From 95fd206382741ae0c5d1a4d5131bc272fcdaa8a5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 13 Sep 2014 21:17:57 -0700 Subject: [PATCH 001/617] Initial commit --- .gitignore | 6 ++++++ AUTHORS | 1 + COPYING | 19 +++++++++++++++++++ README | 2 ++ 4 files changed, 28 insertions(+) create mode 100644 .gitignore create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 README diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..964df4d4a --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*~ +*.lxt +*.pyc +*.vvp +*.kate-swp + diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..7dab2b3a5 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Alex Forencich diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..c36b1255b --- /dev/null +++ b/COPYING @@ -0,0 +1,19 @@ +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. diff --git a/README b/README new file mode 100644 index 000000000..45dbb8ac1 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +Verilog ethernet components + From 35f39a6f4b9b69d8518fc326fc5b79a9661c2719 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 13 Sep 2014 21:21:39 -0700 Subject: [PATCH 002/617] Add AXI stream FIFO --- rtl/axis_fifo.v | 128 +++++++++++++ rtl/axis_fifo_64.v | 131 +++++++++++++ tb/axis_ep.py | 259 +++++++++++++++++++++++++ tb/test_axis_fifo.py | 396 +++++++++++++++++++++++++++++++++++++++ tb/test_axis_fifo.v | 91 +++++++++ tb/test_axis_fifo_64.py | 406 ++++++++++++++++++++++++++++++++++++++++ tb/test_axis_fifo_64.v | 97 ++++++++++ 7 files changed, 1508 insertions(+) create mode 100644 rtl/axis_fifo.v create mode 100644 rtl/axis_fifo_64.v create mode 100644 tb/axis_ep.py create mode 100755 tb/test_axis_fifo.py create mode 100644 tb/test_axis_fifo.v create mode 100755 tb/test_axis_fifo_64.py create mode 100644 tb/test_axis_fifo_64.v diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v new file mode 100644 index 000000000..8004a8311 --- /dev/null +++ b/rtl/axis_fifo.v @@ -0,0 +1,128 @@ +/* + +Copyright (c) 2013 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream FIFO + */ +module axis_fifo # +( + parameter ADDR_WIDTH = 12, + parameter DATA_WIDTH = 8 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] input_axis_tdata, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser +); + +reg [ADDR_WIDTH-1:0] wr_ptr = {ADDR_WIDTH{1'b0}}; +reg [ADDR_WIDTH-1:0] rd_ptr = {ADDR_WIDTH{1'b0}}; +reg [ADDR_WIDTH-1:0] counter = {ADDR_WIDTH{1'b0}}; + +reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}}; + +//(* RAM_STYLE="BLOCK" *) +reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; + +reg output_read = 1'b0; + +reg output_axis_tvalid_reg = 1'b0; + +wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; + +wire full = (counter == (2**ADDR_WIDTH)-1); +wire empty = (counter == 0); + +wire write = input_axis_tvalid & ~full; +wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; + +assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = data_out_reg; + +assign input_axis_tready = ~full; +assign output_axis_tvalid = output_axis_tvalid_reg; + +// write +always @(posedge clk or posedge rst) begin + if (rst) begin + wr_ptr <= 0; + end else if (write) begin + mem[wr_ptr] <= data_in; + wr_ptr <= wr_ptr + 1; + end +end + +// read +always @(posedge clk or posedge rst) begin + if (rst) begin + rd_ptr <= 0; + end else if (read) begin + data_out_reg <= mem[rd_ptr]; + rd_ptr <= rd_ptr + 1; + end +end + +// counter +always @(posedge clk or posedge rst) begin + if (rst) begin + counter <= 0; + end else if (~read & write) begin + counter <= counter + 1; + end else if (read & ~write) begin + counter <= counter - 1; + end +end + +// source ready output +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + end else if (output_axis_tready | ~output_axis_tvalid_reg) begin + output_axis_tvalid_reg <= ~empty; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_reg; + end +end + +endmodule diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v new file mode 100644 index 000000000..8d02f5c0d --- /dev/null +++ b/rtl/axis_fifo_64.v @@ -0,0 +1,131 @@ +/* + +Copyright (c) 2013 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream FIFO (64 bit datapath) + */ +module axis_fifo_64 # +( + parameter ADDR_WIDTH = 12, + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] input_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_axis_tkeep, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser +); + +reg [ADDR_WIDTH-1:0] wr_ptr = {ADDR_WIDTH{1'b0}}; +reg [ADDR_WIDTH-1:0] rd_ptr = {ADDR_WIDTH{1'b0}}; +reg [ADDR_WIDTH-1:0] counter = {ADDR_WIDTH{1'b0}}; + +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; + +//(* RAM_STYLE="BLOCK" *) +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; + +reg output_read = 1'b0; + +reg output_axis_tvalid_reg = 1'b0; + +wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; + +wire full = (counter == (2**ADDR_WIDTH)-1); +wire empty = (counter == 0); + +wire write = input_axis_tvalid & ~full; +wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; + +assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = data_out_reg; + +assign input_axis_tready = ~full; +assign output_axis_tvalid = output_axis_tvalid_reg; + +// write +always @(posedge clk or posedge rst) begin + if (rst) begin + wr_ptr <= 0; + end else if (write) begin + mem[wr_ptr] <= data_in; + wr_ptr <= wr_ptr + 1; + end +end + +// read +always @(posedge clk or posedge rst) begin + if (rst) begin + rd_ptr <= 0; + end else if (read) begin + data_out_reg <= mem[rd_ptr]; + rd_ptr <= rd_ptr + 1; + end +end + +// counter +always @(posedge clk or posedge rst) begin + if (rst) begin + counter <= 0; + end else if (~read & write) begin + counter <= counter + 1; + end else if (read & ~write) begin + counter <= counter - 1; + end +end + +// source ready output +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + end else if (output_axis_tready | ~output_axis_tvalid_reg) begin + output_axis_tvalid_reg <= ~empty; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_reg; + end +end + +endmodule diff --git a/tb/axis_ep.py b/tb/axis_ep.py new file mode 100644 index 000000000..34ff5b35c --- /dev/null +++ b/tb/axis_ep.py @@ -0,0 +1,259 @@ +""" + +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 * + +class AXIStreamFrame(object): + def __init__(self, data=b'', keep=None, user=None): + self.N = 8 + self.M = 1 + self.WL = 8 + self.data = b'' + self.keep = None + self.user = None + + if type(data) is bytes: + data = bytearray(data) + if type(data) is bytearray: + self.data = data + if type(data) is AXIStreamFrame: + self.N = data.N + self.WL = data.WL + self.data = data.data + if data.keep is not None: + self.keep = list(data.keep) + if data.user is not None: + if type(data.user) is int or type(data.user) is bool: + self.user = data.user + else: + self.user = list(data.user) + + def build(self): + if self.data is None: + return + + f = list(self.data) + tdata = [] + tkeep = [] + tuser = [] + i = 0 + + assert_tuser = False + if (type(self.user) is int or type(self.user) is bool) and self.user: + assert_tuser = True + self.user = None + + while len(f) > 0: + data = 0 + keep = 0 + for j in range(self.M): + data = data | (f.pop(0) << (j*self.WL)) + keep = keep | (1 << j) + if len(f) == 0: break + tdata.append(data) + if self.keep is None: + tkeep.append(keep) + else: + tkeep.append(self.keep[i]) + if self.user is None: + tuser.append(0) + else: + tuser.append(self.user[i]) + i += 1 + + if assert_tuser: + tuser[-1] = 1 + self.user = 1 + + return tdata, tkeep, tuser + + def parse(self, tdata, tkeep, tuser): + if tdata is None or tkeep is None or tuser is None: + return + if len(tdata) != len(tkeep) or len(tdata) != len(tuser): + raise Exception("Invalid data") + + self.data = [] + self.keep = [] + self.user = [] + mask = 2**self.WL-1 + + for i in range(len(tdata)): + for j in range(self.M): + if tkeep[i] & (1 << j): + self.data.append((tdata[i] >> (j*self.WL)) & mask) + self.keep.append(tkeep[i]) + self.user.append(tuser[i]) + + if self.WL == 8: + self.data = bytearray(self.data) + + def __eq__(self, other): + if type(other) is AXIStreamFrame: + return self.data == other.data + + def __repr__(self): + return 'AXIStreamFrame(data=%s, keep=%s, user=%s)' % (repr(self.data), repr(self.keep), repr(self.user)) + + def __iter__(self): + return self.data.__iter__() + +def AXIStreamSource(clk, rst, + tdata=None, + tkeep=Signal(bool(True)), + tvalid=Signal(bool(False)), + tready=Signal(bool(True)), + tlast=Signal(bool(False)), + tuser=Signal(bool(False)), + fifo=None, + pause=0, + name=None): + + tready_int = Signal(bool(False)) + tvalid_int = Signal(bool(False)) + + @always_comb + def pause_logic(): + tready_int.next = tready and not pause + tvalid.next = tvalid_int and not pause + + @instance + def logic(): + frame = AXIStreamFrame() + data = [] + keep = [] + user = [] + N = len(tdata) + M = 1 + b = False + if tkeep is not None: + M = len(tkeep) + WL = (len(tdata)+M-1)/M + if WL == 8: + b = True + + while True: + yield clk.posedge, rst.posedge + + if rst: + tdata.next = 0 + tkeep.next = 0 + tvalid_int.next = False + tlast.next = False + else: + if tready_int and tvalid: + if len(data) > 0: + tdata.next = data.pop(0) + tkeep.next = keep.pop(0) + tuser.next = user.pop(0) + tvalid_int.next = True + tlast.next = len(data) == 0 + else: + tvalid_int.next = False + tlast.next = False + if (tlast and tready_int and tvalid) or not tvalid_int: + if not fifo.empty(): + frame = fifo.get() + frame = AXIStreamFrame(frame) + frame.N = N + frame.M = M + frame.WL = WL + frame.build() + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + data, keep, user = frame.build() + tdata.next = data.pop(0) + tkeep.next = keep.pop(0) + tuser.next = user.pop(0) + tvalid_int.next = True + tlast.next = len(data) == 0 + + return logic, pause_logic + + +def AXIStreamSink(clk, rst, + tdata=None, + tkeep=Signal(bool(True)), + tvalid=Signal(bool(True)), + tready=Signal(bool(True)), + tlast=Signal(bool(True)), + tuser=Signal(bool(False)), + fifo=None, + pause=0, + name=None): + + tready_int = Signal(bool(False)) + tvalid_int = Signal(bool(False)) + + @always_comb + def pause_logic(): + tready.next = tready_int and not pause + tvalid_int.next = tvalid and not pause + + @instance + def logic(): + frame = AXIStreamFrame() + data = [] + keep = [] + user = [] + N = len(tdata) + M = 1 + b = False + M = len(tkeep) + WL = (len(tdata)+M-1)/M + if WL == 8: + b = True + + while True: + yield clk.posedge, rst.posedge + + if rst: + tready_int.next = False + frame = AXIStreamFrame() + data = [] + keep = [] + user = [] + else: + tready_int.next = True + + if tvalid_int: + data.append(int(tdata)) + keep.append(int(tkeep)) + user.append(int(tuser)) + if tlast: + frame.N = N + frame.M = M + frame.WL = WL + frame.parse(data, keep, user) + if fifo is not None: + fifo.put(frame) + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + frame = AXIStreamFrame() + data = [] + keep = [] + user = [] + + return logic, pause_logic + diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py new file mode 100755 index 000000000..fe65d118a --- /dev/null +++ b/tb/test_axis_fifo.py @@ -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_fifo' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_fifo(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_fifo(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_fifo.v b/tb/test_axis_fifo.v new file mode 100644 index 000000000..896274765 --- /dev/null +++ b/tb/test_axis_fifo.v @@ -0,0 +1,91 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_fifo; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_axis_tdata = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_fifo.lxt"); + $dumpvars(0, test_axis_fifo); +end + +axis_fifo #( + .ADDR_WIDTH(2), + .DATA_WIDTH(8) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_axis_tdata), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser) +); + +endmodule diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py new file mode 100755 index 000000000..b39ad8282 --- /dev/null +++ b/tb/test_axis_fifo_64.py @@ -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_fifo_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_fifo_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tkeep=input_axis_tkeep, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[64:]) + input_axis_tkeep = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[64:]) + output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tkeep=input_axis_tkeep, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_fifo_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_fifo_64.v b/tb/test_axis_fifo_64.v new file mode 100644 index 000000000..e95a6ed80 --- /dev/null +++ b/tb/test_axis_fifo_64.v @@ -0,0 +1,97 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_fifo_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] input_axis_tdata = 0; +reg [7:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [63:0] output_axis_tdata; +wire [7:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_fifo_64.lxt"); + $dumpvars(0, test_axis_fifo_64); +end + +axis_fifo_64 #( + .ADDR_WIDTH(2), + .DATA_WIDTH(64) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser) +); + +endmodule From 74fa9670712d2252493872681a653403689e8fc5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 13 Sep 2014 21:22:06 -0700 Subject: [PATCH 003/617] Add AXI stream register --- rtl/axis_register.v | 189 +++++++++++++++++ rtl/axis_register_64.v | 200 ++++++++++++++++++ tb/test_axis_register.py | 396 +++++++++++++++++++++++++++++++++++ tb/test_axis_register.v | 90 ++++++++ tb/test_axis_register_64.py | 406 ++++++++++++++++++++++++++++++++++++ tb/test_axis_register_64.v | 96 +++++++++ 6 files changed, 1377 insertions(+) create mode 100644 rtl/axis_register.v create mode 100644 rtl/axis_register_64.v create mode 100755 tb/test_axis_register.py create mode 100644 tb/test_axis_register.v create mode 100755 tb/test_axis_register_64.py create mode 100644 tb/test_axis_register_64.v diff --git a/rtl/axis_register.v b/rtl/axis_register.v new file mode 100644 index 000000000..42fa50104 --- /dev/null +++ b/rtl/axis_register.v @@ -0,0 +1,189 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream register + */ +module axis_register # +( + parameter DATA_WIDTH = 8 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] input_axis_tdata, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser +); + +// state register +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_TRANSFER = 2'd1, + STATE_TRANSFER_WAIT = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +// datapath registers +reg input_axis_tready_reg = 0; + +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign input_axis_tready = input_axis_tready_reg; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @* begin + state_next = 2'bz; + + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - no data in registers + if (input_axis_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + state_next = STATE_TRANSFER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_TRANSFER: begin + // transfer state - data in output register + if (input_axis_tvalid & output_axis_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + state_next = STATE_TRANSFER; + end else if (~input_axis_tvalid & output_axis_tready) begin + // word transfer out - go back to idle + state_next = STATE_IDLE; + end else if (input_axis_tvalid & ~output_axis_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + state_next = STATE_TRANSFER_WAIT; + end else begin + state_next = STATE_TRANSFER; + end + end + STATE_TRANSFER_WAIT: begin + // transfer wait state - data in both output and temp registers + if (output_axis_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + state_next = STATE_TRANSFER; + end else begin + state_next = STATE_TRANSFER_WAIT; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + input_axis_tready_reg <= 0; + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + state_reg <= state_next; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle state - no data in registers; accept new data + input_axis_tready_reg <= 1; + output_axis_tvalid_reg <= 0; + end + STATE_TRANSFER: begin + // transfer state - data in output register; accept new data + input_axis_tready_reg <= 1; + output_axis_tvalid_reg <= 1; + end + STATE_TRANSFER_WAIT: begin + // transfer wait state - data in output and temp registers; do not accept new data + input_axis_tready_reg <= 0; + output_axis_tvalid_reg <= 1; + end + endcase + + // datapath + if (transfer_in_out) begin + output_axis_tdata_reg <= input_axis_tdata; + output_axis_tlast_reg <= input_axis_tlast; + output_axis_tuser_reg <= input_axis_tuser; + end else if (transfer_in_temp) begin + temp_axis_tdata_reg <= input_axis_tdata; + temp_axis_tlast_reg <= input_axis_tlast; + temp_axis_tuser_reg <= input_axis_tuser; + end else if (transfer_temp_out) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v new file mode 100644 index 000000000..3b494e95a --- /dev/null +++ b/rtl/axis_register_64.v @@ -0,0 +1,200 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream register (64 bit datapath) + */ +module axis_register_64 # +( + parameter DATA_WIDTH = 8, + 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 +); + +// state register +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_TRANSFER = 2'd1, + STATE_TRANSFER_WAIT = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +// datapath registers +reg input_axis_tready_reg = 0; + +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign input_axis_tready = input_axis_tready_reg; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @* begin + state_next = 2'bz; + + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - no data in registers + if (input_axis_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + state_next = STATE_TRANSFER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_TRANSFER: begin + // transfer state - data in output register + if (input_axis_tvalid & output_axis_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + state_next = STATE_TRANSFER; + end else if (~input_axis_tvalid & output_axis_tready) begin + // word transfer out - go back to idle + state_next = STATE_IDLE; + end else if (input_axis_tvalid & ~output_axis_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + state_next = STATE_TRANSFER_WAIT; + end else begin + state_next = STATE_TRANSFER; + end + end + STATE_TRANSFER_WAIT: begin + // transfer wait state - data in both output and temp registers + if (output_axis_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + state_next = STATE_TRANSFER; + end else begin + state_next = STATE_TRANSFER_WAIT; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + input_axis_tready_reg <= 0; + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + state_reg <= state_next; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle state - no data in registers; accept new data + input_axis_tready_reg <= 1; + output_axis_tvalid_reg <= 0; + end + STATE_TRANSFER: begin + // transfer state - data in output register; accept new data + input_axis_tready_reg <= 1; + output_axis_tvalid_reg <= 1; + end + STATE_TRANSFER_WAIT: begin + // transfer wait state - data in output and temp registers; do not accept new data + input_axis_tready_reg <= 0; + output_axis_tvalid_reg <= 1; + end + endcase + + // datapath + if (transfer_in_out) begin + output_axis_tdata_reg <= input_axis_tdata; + output_axis_tkeep_reg <= input_axis_tkeep; + output_axis_tlast_reg <= input_axis_tlast; + output_axis_tuser_reg <= input_axis_tuser; + end else if (transfer_in_temp) begin + temp_axis_tdata_reg <= input_axis_tdata; + temp_axis_tkeep_reg <= input_axis_tkeep; + temp_axis_tlast_reg <= input_axis_tlast; + temp_axis_tuser_reg <= input_axis_tuser; + end else if (transfer_temp_out) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py new file mode 100755 index 000000000..13d2897fc --- /dev/null +++ b/tb/test_axis_register.py @@ -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_register' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_register(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_register(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_register.v b/tb/test_axis_register.v new file mode 100644 index 000000000..b442a3604 --- /dev/null +++ b/tb/test_axis_register.v @@ -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_register; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_axis_tdata = 8'd0; +reg input_axis_tvalid = 1'b0; +reg input_axis_tlast = 1'b0; +reg input_axis_tuser = 1'b0; +reg output_axis_tready = 1'b0; + +// Outputs +wire input_axis_tready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_register.lxt"); + $dumpvars(0, test_axis_register); +end + +axis_register #( + .DATA_WIDTH(8) +) +UUT ( + .clk(clk), + .rst(rst), + // axi input + .input_axis_tdata(input_axis_tdata), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // axi output + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser) +); + +endmodule diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py new file mode 100755 index 000000000..4509a6fd0 --- /dev/null +++ b/tb/test_axis_register_64.py @@ -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_register_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_register_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tkeep=input_axis_tkeep, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[64:]) + input_axis_tkeep = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[64:]) + output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tkeep=input_axis_tkeep, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_register_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_register_64.v b/tb/test_axis_register_64.v new file mode 100644 index 000000000..6b2b0e700 --- /dev/null +++ b/tb/test_axis_register_64.v @@ -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_register_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] input_axis_tdata = 8'd0; +reg [7:0] input_axis_tkeep = 8'd0; +reg input_axis_tvalid = 1'b0; +reg input_axis_tlast = 1'b0; +reg input_axis_tuser = 1'b0; +reg output_axis_tready = 1'b0; + +// Outputs +wire input_axis_tready; +wire [63:0] output_axis_tdata; +wire [7:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_register_64.lxt"); + $dumpvars(0, test_axis_register_64); +end + +axis_register_64 #( + .DATA_WIDTH(64) +) +UUT ( + .clk(clk), + .rst(rst), + // axi input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // axi output + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser) +); + +endmodule From e1955a29da4a2865606a04ec6409dff0f1cf1503 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 13 Sep 2014 21:23:11 -0700 Subject: [PATCH 004/617] Add LocalLink to AXI stream bridge --- rtl/axis_ll_bridge.v | 79 +++++++++++++ rtl/ll_axis_bridge.v | 64 +++++++++++ tb/ll_ep.py | 123 ++++++++++++++++++++ tb/test_axis_ll_bridge.py | 232 ++++++++++++++++++++++++++++++++++++++ tb/test_axis_ll_bridge.v | 85 ++++++++++++++ tb/test_ll_axis_bridge.py | 231 +++++++++++++++++++++++++++++++++++++ tb/test_ll_axis_bridge.v | 85 ++++++++++++++ 7 files changed, 899 insertions(+) create mode 100644 rtl/axis_ll_bridge.v create mode 100644 rtl/ll_axis_bridge.v create mode 100644 tb/ll_ep.py create mode 100755 tb/test_axis_ll_bridge.py create mode 100644 tb/test_axis_ll_bridge.v create mode 100755 tb/test_ll_axis_bridge.py create mode 100644 tb/test_ll_axis_bridge.v diff --git a/rtl/axis_ll_bridge.v b/rtl/axis_ll_bridge.v new file mode 100644 index 000000000..06186aef7 --- /dev/null +++ b/rtl/axis_ll_bridge.v @@ -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 diff --git a/rtl/ll_axis_bridge.v b/rtl/ll_axis_bridge.v new file mode 100644 index 000000000..99733536c --- /dev/null +++ b/rtl/ll_axis_bridge.v @@ -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 diff --git a/tb/ll_ep.py b/tb/ll_ep.py new file mode 100644 index 000000000..d69346be6 --- /dev/null +++ b/tb/ll_ep.py @@ -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 + diff --git a/tb/test_axis_ll_bridge.py b/tb/test_axis_ll_bridge.py new file mode 100755 index 000000000..21e6d7a43 --- /dev/null +++ b/tb/test_axis_ll_bridge.py @@ -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() + diff --git a/tb/test_axis_ll_bridge.v b/tb/test_axis_ll_bridge.v new file mode 100644 index 000000000..680b570b9 --- /dev/null +++ b/tb/test_axis_ll_bridge.v @@ -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 diff --git a/tb/test_ll_axis_bridge.py b/tb/test_ll_axis_bridge.py new file mode 100755 index 000000000..7c6ca681d --- /dev/null +++ b/tb/test_ll_axis_bridge.py @@ -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() + diff --git a/tb/test_ll_axis_bridge.v b/tb/test_ll_axis_bridge.v new file mode 100644 index 000000000..573fec7c5 --- /dev/null +++ b/tb/test_ll_axis_bridge.v @@ -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 From 8e4d162667f68039bd65ade3257ad8921f885165 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 14 Sep 2014 01:06:48 -0700 Subject: [PATCH 005/617] Add ethernet frame to AXI stream modules --- rtl/eth_axis_rx.v | 377 +++++++++++++++++++++++++ rtl/eth_axis_rx_64.v | 387 ++++++++++++++++++++++++++ rtl/eth_axis_tx.v | 342 +++++++++++++++++++++++ rtl/eth_axis_tx_64.v | 448 ++++++++++++++++++++++++++++++ tb/eth_ep.py | 228 +++++++++++++++ tb/test_eth_axis_rx.py | 550 ++++++++++++++++++++++++++++++++++++ tb/test_eth_axis_rx.v | 110 ++++++++ tb/test_eth_axis_rx_64.py | 560 +++++++++++++++++++++++++++++++++++++ tb/test_eth_axis_rx_64.v | 116 ++++++++ tb/test_eth_axis_tx.py | 561 +++++++++++++++++++++++++++++++++++++ tb/test_eth_axis_tx.v | 107 +++++++ tb/test_eth_axis_tx_64.py | 571 ++++++++++++++++++++++++++++++++++++++ tb/test_eth_axis_tx_64.v | 113 ++++++++ 13 files changed, 4470 insertions(+) create mode 100644 rtl/eth_axis_rx.v create mode 100644 rtl/eth_axis_rx_64.v create mode 100644 rtl/eth_axis_tx.v create mode 100644 rtl/eth_axis_tx_64.v create mode 100644 tb/eth_ep.py create mode 100755 tb/test_eth_axis_rx.py create mode 100644 tb/test_eth_axis_rx.v create mode 100755 tb/test_eth_axis_rx_64.py create mode 100644 tb/test_eth_axis_rx_64.v create mode 100755 tb/test_eth_axis_tx.py create mode 100644 tb/test_eth_axis_tx.v create mode 100755 tb/test_eth_axis_tx_64.py create mode 100644 tb/test_eth_axis_tx_64.v diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v new file mode 100644 index 000000000..259eae7ec --- /dev/null +++ b/rtl/eth_axis_rx.v @@ -0,0 +1,377 @@ +/* + +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 ethernet frame receiver (AXI in, Ethernet frame out) + */ +module eth_axis_rx +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [7:0] input_axis_tdata, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Status signals + */ + output wire busy, + output wire frame_error +); + +/* + +Ethernet frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype 2 octets + +This module receives an Ethernet frame on an 8 bit wide AXI interface, +separates the dest MAC, source MAC, and eth type into separate parallel +outputs, and forwards the payload data out through a separate AXI interface. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_READ_HEADER = 3'd1, + STATE_READ_PAYLOAD_IDLE = 3'd2, + STATE_READ_PAYLOAD_TRANSFER = 3'd3, + STATE_READ_PAYLOAD_TRANSFER_WAIT = 3'd4, + STATE_READ_PAYLOAD_TRANSFER_LAST = 3'd5; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_eth_dest_mac_0; +reg store_eth_dest_mac_1; +reg store_eth_dest_mac_2; +reg store_eth_dest_mac_3; +reg store_eth_dest_mac_4; +reg store_eth_dest_mac_5; +reg store_eth_src_mac_0; +reg store_eth_src_mac_1; +reg store_eth_src_mac_2; +reg store_eth_src_mac_3; +reg store_eth_src_mac_4; +reg store_eth_src_mac_5; +reg store_eth_type_0; +reg store_eth_type_1; + +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg input_axis_tready_reg = 0; + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [7:0] output_eth_payload_tdata_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg busy_reg = 0, busy_next; +reg frame_error_reg = 0, frame_error_next; + +reg [7:0] temp_eth_payload_tdata_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +assign input_axis_tready = input_axis_tready_reg; + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign busy = busy_reg; +assign frame_error = frame_error_reg; + +always @* begin + state_next = 2'bz; + + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + store_eth_dest_mac_0 = 0; + store_eth_dest_mac_1 = 0; + store_eth_dest_mac_2 = 0; + store_eth_dest_mac_3 = 0; + store_eth_dest_mac_4 = 0; + store_eth_dest_mac_5 = 0; + store_eth_src_mac_0 = 0; + store_eth_src_mac_1 = 0; + store_eth_src_mac_2 = 0; + store_eth_src_mac_3 = 0; + store_eth_src_mac_4 = 0; + store_eth_src_mac_5 = 0; + store_eth_type_0 = 0; + store_eth_type_1 = 0; + + frame_ptr_next = frame_ptr_reg; + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + + frame_error_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_axis_tready & input_axis_tvalid) begin + frame_ptr_next = 1; + store_eth_dest_mac_5 = 1; + state_next = STATE_READ_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_READ_HEADER: begin + // read header state + if (input_axis_tvalid) begin + // word transfer in - store it + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_READ_HEADER; + case (frame_ptr_reg) + 8'h00: store_eth_dest_mac_5 = 1; + 8'h01: store_eth_dest_mac_4 = 1; + 8'h02: store_eth_dest_mac_3 = 1; + 8'h03: store_eth_dest_mac_2 = 1; + 8'h04: store_eth_dest_mac_1 = 1; + 8'h05: store_eth_dest_mac_0 = 1; + 8'h06: store_eth_src_mac_5 = 1; + 8'h07: store_eth_src_mac_4 = 1; + 8'h08: store_eth_src_mac_3 = 1; + 8'h09: store_eth_src_mac_2 = 1; + 8'h0A: store_eth_src_mac_1 = 1; + 8'h0B: store_eth_src_mac_0 = 1; + 8'h0C: store_eth_type_1 = 1; + 8'h0D: begin + store_eth_type_0 = 1; + output_eth_hdr_valid_next = 1; + state_next = STATE_READ_PAYLOAD_IDLE; + end + endcase + if (input_axis_tlast) begin + state_next = STATE_IDLE; + frame_error_next = 1; + end + end else begin + state_next = STATE_READ_HEADER; + end + end + STATE_READ_PAYLOAD_IDLE: begin + // idle; no data in registers + if (input_axis_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + if (input_axis_tlast) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end else begin + state_next = STATE_READ_PAYLOAD_IDLE; + end + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register + if (input_axis_tvalid & output_eth_payload_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + if (input_axis_tlast) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end else if (~input_axis_tvalid & output_eth_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_READ_PAYLOAD_IDLE; + end else if (input_axis_tvalid & ~output_eth_payload_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in both output and temp registers + if (output_eth_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_eth_payload_tlast_reg) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + if (output_eth_payload_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_axis_tready_reg <= 0; + output_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + busy_reg <= 0; + frame_error_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + + frame_error_reg <= frame_error_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_axis_tready_reg <= ~output_eth_hdr_valid; + output_eth_payload_tvalid_reg <= 0; + end + STATE_READ_HEADER: begin + // read header; accept new data + input_axis_tready_reg <= 1; + output_eth_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_IDLE: begin + // read payload; no data in registers; accept new data + input_axis_tready_reg <= 1; + output_eth_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register; accept new data + input_axis_tready_reg <= 1; + output_eth_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in output and temp registers; do not accept new data + input_axis_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + input_axis_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + endcase + + // datapath + if (store_eth_dest_mac_0) output_eth_dest_mac_reg[ 7: 0] <= input_axis_tdata; + if (store_eth_dest_mac_1) output_eth_dest_mac_reg[15: 8] <= input_axis_tdata; + if (store_eth_dest_mac_2) output_eth_dest_mac_reg[23:16] <= input_axis_tdata; + if (store_eth_dest_mac_3) output_eth_dest_mac_reg[31:24] <= input_axis_tdata; + if (store_eth_dest_mac_4) output_eth_dest_mac_reg[39:32] <= input_axis_tdata; + if (store_eth_dest_mac_5) output_eth_dest_mac_reg[47:40] <= input_axis_tdata; + if (store_eth_src_mac_0) output_eth_src_mac_reg[ 7: 0] <= input_axis_tdata; + if (store_eth_src_mac_1) output_eth_src_mac_reg[15: 8] <= input_axis_tdata; + if (store_eth_src_mac_2) output_eth_src_mac_reg[23:16] <= input_axis_tdata; + if (store_eth_src_mac_3) output_eth_src_mac_reg[31:24] <= input_axis_tdata; + if (store_eth_src_mac_4) output_eth_src_mac_reg[39:32] <= input_axis_tdata; + if (store_eth_src_mac_5) output_eth_src_mac_reg[47:40] <= input_axis_tdata; + if (store_eth_type_0) output_eth_type_reg[ 7: 0] <= input_axis_tdata; + if (store_eth_type_1) output_eth_type_reg[15: 8] <= input_axis_tdata; + + if (transfer_in_out) begin + output_eth_payload_tdata_reg <= input_axis_tdata; + output_eth_payload_tlast_reg <= input_axis_tlast; + output_eth_payload_tuser_reg <= input_axis_tuser; + end else if (transfer_in_temp) begin + temp_eth_payload_tdata_reg <= input_axis_tdata; + temp_eth_payload_tlast_reg <= input_axis_tlast; + temp_eth_payload_tuser_reg <= input_axis_tuser; + end else if (transfer_temp_out) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + end +end + +endmodule diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v new file mode 100644 index 000000000..464d9e65b --- /dev/null +++ b/rtl/eth_axis_rx_64.v @@ -0,0 +1,387 @@ +/* + +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 ethernet frame receiver (AXI in, Ethernet frame out, 64 bit datapath) + */ +module eth_axis_rx_64 +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [63:0] input_axis_tdata, + input wire [7:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Status signals + */ + output wire busy, + output wire frame_error +); + +/* + +Ethernet frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype 2 octets + +This module receives an Ethernet frame on an 8 bit wide AXI interface, +separates the dest MAC, source MAC, and eth type into separate parallel +outputs, and forwards the payload data out through a separate AXI interface. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_READ_HEADER = 3'd1, + STATE_READ_PAYLOAD_IDLE = 3'd2, + STATE_READ_PAYLOAD_TRANSFER = 3'd3, + STATE_READ_PAYLOAD_TRANSFER_WAIT = 3'd4, + STATE_READ_PAYLOAD_TRANSFER_LAST = 3'd5; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_hdr_word_0; +reg store_hdr_word_1; + +reg transfer_in_save; +reg transfer_save_out; +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg input_axis_tready_reg = 0; + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg busy_reg = 0, busy_next; +reg frame_error_reg = 0, frame_error_next; + +reg [63:0] temp_eth_payload_tdata_reg = 0; +reg [7:0] temp_eth_payload_tkeep_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +reg [63:0] save_axis_tdata_reg = 0; +reg [7:0] save_axis_tkeep_reg = 0; +reg save_axis_tlast_reg = 0; +reg save_axis_tuser_reg = 0; + +assign input_axis_tready = input_axis_tready_reg; + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign busy = busy_reg; +assign frame_error = frame_error_reg; + +always @* begin + state_next = 2'bz; + + transfer_in_save = 0; + transfer_save_out = 0; + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + store_hdr_word_0 = 0; + store_hdr_word_1 = 0; + + frame_ptr_next = frame_ptr_reg; + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + + frame_error_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_axis_tready & input_axis_tvalid) begin + frame_ptr_next = 8; + store_hdr_word_0 = 1; + transfer_in_save = 1; + state_next = STATE_READ_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_READ_HEADER: begin + // read header state + if (input_axis_tvalid) begin + // word transfer in - store it + frame_ptr_next = frame_ptr_reg+8; + transfer_in_save = 1; + state_next = STATE_READ_HEADER; + case (frame_ptr_reg) + 8'h00: store_hdr_word_0 = 1; + 8'h08: begin + store_hdr_word_1 = 1; + output_eth_hdr_valid_next = 1; + state_next = STATE_READ_PAYLOAD_IDLE; + end + endcase + if (input_axis_tlast) begin + state_next = STATE_IDLE; + frame_error_next = 1; + end + end else begin + state_next = STATE_READ_HEADER; + end + end + STATE_READ_PAYLOAD_IDLE: begin + // idle; no data in registers + if (input_axis_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + transfer_in_save = 1; + if (input_axis_tlast) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end else begin + state_next = STATE_READ_PAYLOAD_IDLE; + end + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register + if (input_axis_tvalid & output_eth_payload_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + transfer_in_save = 1; + if (input_axis_tlast) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end else if (~input_axis_tvalid & output_eth_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_READ_PAYLOAD_IDLE; + end else if (input_axis_tvalid & ~output_eth_payload_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + transfer_in_save = 1; + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in both output and temp registers + if (output_eth_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_eth_payload_tlast_reg | (save_axis_tlast_reg & save_axis_tkeep_reg[7:6] != 0)) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + if (output_eth_payload_tready) begin + // word transfer out + if (save_axis_tkeep_reg[7:6]) begin + // part of word in save register + transfer_save_out = 1; + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + // nothing in save register; done + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_axis_tready_reg <= 0; + output_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + busy_reg <= 0; + frame_error_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + + frame_error_reg <= frame_error_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_axis_tready_reg <= ~output_eth_hdr_valid; + output_eth_payload_tvalid_reg <= 0; + end + STATE_READ_HEADER: begin + // read header; accept new data + input_axis_tready_reg <= 1; + output_eth_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_IDLE: begin + // read payload; no data in registers; accept new data + input_axis_tready_reg <= 1; + output_eth_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register; accept new data + input_axis_tready_reg <= 1; + output_eth_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in output and temp registers; do not accept new data + input_axis_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + input_axis_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + endcase + + // datapath + if (store_hdr_word_0) begin + output_eth_dest_mac_reg[47:40] <= input_axis_tdata[ 7: 0]; + output_eth_dest_mac_reg[39:32] <= input_axis_tdata[15: 8]; + output_eth_dest_mac_reg[31:24] <= input_axis_tdata[23:16]; + output_eth_dest_mac_reg[23:16] <= input_axis_tdata[31:24]; + output_eth_dest_mac_reg[15: 8] <= input_axis_tdata[39:32]; + output_eth_dest_mac_reg[ 7: 0] <= input_axis_tdata[47:40]; + output_eth_src_mac_reg[47:40] <= input_axis_tdata[55:48]; + output_eth_src_mac_reg[39:32] <= input_axis_tdata[63:56]; + end + if (store_hdr_word_1) begin + output_eth_src_mac_reg[31:24] <= input_axis_tdata[ 7: 0]; + output_eth_src_mac_reg[23:16] <= input_axis_tdata[15: 8]; + output_eth_src_mac_reg[15: 8] <= input_axis_tdata[23:16]; + output_eth_src_mac_reg[ 7: 0] <= input_axis_tdata[31:24]; + output_eth_type_reg[15:8] <= input_axis_tdata[39:32]; + output_eth_type_reg[ 7:0] <= input_axis_tdata[47:40]; + end + + if (transfer_in_save) begin + save_axis_tdata_reg <= input_axis_tdata; + save_axis_tkeep_reg <= input_axis_tkeep; + save_axis_tlast_reg <= input_axis_tlast; + save_axis_tuser_reg <= input_axis_tuser; + end else if (transfer_save_out) begin + output_eth_payload_tdata_reg <= {48'd0, save_axis_tdata_reg[63:48]}; + output_eth_payload_tkeep_reg <= {6'd0, save_axis_tkeep_reg[7:6]}; + output_eth_payload_tlast_reg <= save_axis_tlast_reg; + output_eth_payload_tuser_reg <= save_axis_tuser_reg; + save_axis_tkeep_reg <= 0; + end + + if (transfer_in_out) begin + output_eth_payload_tdata_reg <= {input_axis_tdata[47:0], save_axis_tdata_reg[63:48]}; + output_eth_payload_tkeep_reg <= {input_axis_tkeep[5:0], save_axis_tkeep_reg[7:6]}; + output_eth_payload_tlast_reg <= input_axis_tlast & (input_axis_tkeep[7:6] == 0); + output_eth_payload_tuser_reg <= input_axis_tuser & (input_axis_tkeep[7:6] == 0); + end else if (transfer_in_temp) begin + temp_eth_payload_tdata_reg <= {input_axis_tdata[47:0], save_axis_tdata_reg[63:48]}; + temp_eth_payload_tkeep_reg <= {input_axis_tkeep[5:0], save_axis_tkeep_reg[7:6]}; + temp_eth_payload_tlast_reg <= input_axis_tlast & (input_axis_tkeep[7:6] == 0); + temp_eth_payload_tuser_reg <= input_axis_tuser & (input_axis_tkeep[7:6] == 0); + end else if (transfer_temp_out) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + end +end + +endmodule diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v new file mode 100644 index 000000000..4783cfaef --- /dev/null +++ b/rtl/eth_axis_tx.v @@ -0,0 +1,342 @@ +/* + +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 ethernet frame transmitter (Ethernet frame in, AXI out) + */ +module eth_axis_tx +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [7:0] input_eth_payload_tdata, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * AXI output + */ + output wire [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Status signals + */ + output wire busy +); + +/* + +Ethernet frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype 2 octets + +This module receives an Ethernet frame with parallel field input +and an AXI interface for the payload data and produces an AXI +output stream. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_WRITE_HEADER = 3'd1, + STATE_WRITE_PAYLOAD_IDLE = 3'd2, + STATE_WRITE_PAYLOAD_TRANSFER = 3'd3, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 3'd4, + STATE_WRITE_PAYLOAD_TRANSFER_LAST = 3'd5; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_eth_hdr; + +reg [7:0] write_hdr_data; +reg write_hdr_out; + +reg transfer_in_save; +reg transfer_save_out; +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [47:0] eth_dest_mac_reg = 0; +reg [47:0] eth_src_mac_reg = 0; +reg [15:0] eth_type_reg = 0; + +reg input_eth_hdr_ready_reg = 0; +reg input_eth_payload_tready_reg = 0; + +reg [7:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg busy_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign input_eth_hdr_ready = input_eth_hdr_ready_reg; +assign input_eth_payload_tready = input_eth_payload_tready_reg; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +assign busy = busy_reg; + +always @* begin + state_next = 2'bz; + + store_eth_hdr = 0; + + write_hdr_data = 0; + write_hdr_out = 0; + + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + frame_ptr_next = frame_ptr_reg; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_eth_payload_tvalid) begin + store_eth_hdr = 1; + write_hdr_out = 1; + write_hdr_data = input_eth_dest_mac[47:40]; + frame_ptr_next = 1; + state_next = STATE_WRITE_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_HEADER: begin + // read header state + if (output_axis_tready) begin + // word transfer out + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_WRITE_HEADER; + write_hdr_out = 1; + case (frame_ptr_reg) + 8'h01: write_hdr_data = eth_dest_mac_reg[39:32]; + 8'h02: write_hdr_data = eth_dest_mac_reg[31:24]; + 8'h03: write_hdr_data = eth_dest_mac_reg[23:16]; + 8'h04: write_hdr_data = eth_dest_mac_reg[15: 8]; + 8'h05: write_hdr_data = eth_dest_mac_reg[ 7: 0]; + 8'h06: write_hdr_data = eth_src_mac_reg[47:40]; + 8'h07: write_hdr_data = eth_src_mac_reg[39:32]; + 8'h08: write_hdr_data = eth_src_mac_reg[31:24]; + 8'h09: write_hdr_data = eth_src_mac_reg[23:16]; + 8'h0A: write_hdr_data = eth_src_mac_reg[15: 8]; + 8'h0B: write_hdr_data = eth_src_mac_reg[ 7: 0]; + 8'h0C: write_hdr_data = eth_type_reg[15: 8]; + 8'h0D: begin + write_hdr_data = eth_type_reg[ 7: 0]; + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + endcase + end else begin + state_next = STATE_WRITE_HEADER; + end + end + STATE_WRITE_PAYLOAD_IDLE: begin + // idle; no data in registers + if (input_eth_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + if (input_eth_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end else begin + state_next = STATE_WRITE_PAYLOAD_IDLE; + end + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // read payload; data in output register + if (input_eth_payload_tvalid & output_axis_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + if (input_eth_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end else if (~input_eth_payload_tvalid & output_axis_tready) begin + // word transfer out - go back to idle + state_next = STATE_WRITE_PAYLOAD_IDLE; + end else if (input_eth_payload_tvalid & ~output_axis_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in both output and temp registers + if (output_axis_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_axis_tlast_reg) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + if (output_axis_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + eth_dest_mac_reg <= 0; + eth_src_mac_reg <= 0; + eth_type_reg <= 0; + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + busy_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_eth_hdr_ready_reg <= 1; + input_eth_payload_tready_reg <= 0; + output_axis_tvalid_reg <= 0; + end + STATE_WRITE_HEADER: begin + // read header; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_axis_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_IDLE: begin + // read payload; no data in registers; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_axis_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // read payload; data in output register; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_axis_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in output and temp registers; do not accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_axis_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_axis_tvalid_reg <= 1; + end + endcase + + if (store_eth_hdr) begin + eth_dest_mac_reg <= input_eth_dest_mac; + eth_src_mac_reg <= input_eth_src_mac; + eth_type_reg <= input_eth_type; + end + + if (write_hdr_out) begin + output_axis_tdata_reg <= write_hdr_data; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + end else if (transfer_in_out) begin + output_axis_tdata_reg <= input_eth_payload_tdata; + output_axis_tlast_reg <= input_eth_payload_tlast; + output_axis_tuser_reg <= input_eth_payload_tuser; + end else if (transfer_in_temp) begin + temp_axis_tdata_reg <= input_eth_payload_tdata; + temp_axis_tlast_reg <= input_eth_payload_tlast; + temp_axis_tuser_reg <= input_eth_payload_tuser; + end else if (transfer_temp_out) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v new file mode 100644 index 000000000..0b24fadc5 --- /dev/null +++ b/rtl/eth_axis_tx_64.v @@ -0,0 +1,448 @@ +/* + +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 ethernet frame transmitter (Ethernet frame in, AXI out, 64 bit datapath) + */ +module eth_axis_tx_64 +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [63:0] input_eth_payload_tdata, + input wire [7:0] input_eth_payload_tkeep, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * AXI output + */ + output wire [63:0] output_axis_tdata, + output wire [7: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 signals + */ + output wire busy +); + +/* + +Ethernet frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype 2 octets + +This module receives an Ethernet frame with parallel field input +and an AXI interface for the payload data and produces an AXI +output stream. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_WRITE_HEADER = 3'd1, + STATE_WRITE_HEADER_LAST = 3'd2, + STATE_WRITE_HEADER_LAST_WAIT = 3'd3, + STATE_WRITE_PAYLOAD_IDLE = 3'd4, + STATE_WRITE_PAYLOAD_TRANSFER = 3'd5, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 3'd6, + STATE_WRITE_PAYLOAD_TRANSFER_LAST = 3'd7; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_eth_hdr; + +reg [63:0] write_hdr_data; +reg [7:0] write_hdr_keep; +reg write_hdr_out; +reg write_hdr_temp; + +reg transfer_in_save; +reg transfer_save_out; +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [47:0] eth_dest_mac_reg = 0; +reg [47:0] eth_src_mac_reg = 0; +reg [15:0] eth_type_reg = 0; + +reg input_eth_hdr_ready_reg = 0; +reg input_eth_payload_tready_reg = 0; + +reg [63:0] output_axis_tdata_reg = 0; +reg [7:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg busy_reg = 0; + +reg [63:0] temp_axis_tdata_reg = 0; +reg [7:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +reg [63:0] save_eth_payload_tdata_reg = 0; +reg [7:0] save_eth_payload_tkeep_reg = 0; +reg save_eth_payload_tlast_reg = 0; +reg save_eth_payload_tuser_reg = 0; + +assign input_eth_hdr_ready = input_eth_hdr_ready_reg; +assign input_eth_payload_tready = input_eth_payload_tready_reg; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +assign busy = busy_reg; + +always @* begin + state_next = 2'bz; + + store_eth_hdr = 0; + + write_hdr_data = 0; + write_hdr_keep = 0; + write_hdr_out = 0; + write_hdr_temp = 0; + + transfer_in_save = 0; + transfer_save_out = 0; + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + frame_ptr_next = frame_ptr_reg; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_eth_payload_tvalid) begin + store_eth_hdr = 1; + write_hdr_out = 1; + write_hdr_data[ 7: 0] = input_eth_dest_mac[47:40]; + write_hdr_data[15: 8] = input_eth_dest_mac[39:32]; + write_hdr_data[23:16] = input_eth_dest_mac[31:24]; + write_hdr_data[31:24] = input_eth_dest_mac[23:16]; + write_hdr_data[39:32] = input_eth_dest_mac[15: 8]; + write_hdr_data[47:40] = input_eth_dest_mac[ 7: 0]; + write_hdr_data[55:48] = input_eth_src_mac[47:40]; + write_hdr_data[63:56] = input_eth_src_mac[39:32]; + write_hdr_keep = 8'hff; + frame_ptr_next = 8; + state_next = STATE_WRITE_HEADER_LAST; + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_HEADER_LAST: begin + // last header word requires first payload word; process accordingly + if (input_eth_payload_tvalid & output_axis_tready) begin + // word transfer through - update output register + transfer_in_save = 1; + write_hdr_out = 1; + write_hdr_data[ 7: 0] = eth_src_mac_reg[31:24]; + write_hdr_data[15: 8] = eth_src_mac_reg[23:16]; + write_hdr_data[23:16] = eth_src_mac_reg[15: 8]; + write_hdr_data[31:24] = eth_src_mac_reg[ 7: 0]; + write_hdr_data[39:32] = eth_type_reg[15: 8]; + write_hdr_data[47:40] = eth_type_reg[ 7: 0]; + write_hdr_data[55:48] = input_eth_payload_tdata[ 7: 0]; + write_hdr_data[63:56] = input_eth_payload_tdata[15: 8]; + write_hdr_keep = {input_eth_payload_tkeep[1:0], 6'h3F}; + if (input_eth_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end else if (~input_eth_payload_tvalid & output_axis_tready) begin + // word transfer out - go back to idle + state_next = STATE_WRITE_HEADER_LAST_WAIT; + end else if (input_eth_payload_tvalid & ~output_axis_tready) begin + // word transfer in - store in temp + transfer_in_save = 1; + write_hdr_temp = 1; + write_hdr_data[ 7: 0] = eth_src_mac_reg[31:24]; + write_hdr_data[15: 8] = eth_src_mac_reg[23:16]; + write_hdr_data[23:16] = eth_src_mac_reg[15: 8]; + write_hdr_data[31:24] = eth_src_mac_reg[ 7: 0]; + write_hdr_data[39:32] = eth_type_reg[15: 8]; + write_hdr_data[47:40] = eth_type_reg[ 7: 0]; + write_hdr_data[55:48] = input_eth_payload_tdata[ 7: 0]; + write_hdr_data[63:56] = input_eth_payload_tdata[15: 8]; + write_hdr_keep = {input_eth_payload_tkeep[1:0], 6'h3F}; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + STATE_WRITE_HEADER_LAST_WAIT: begin + // last header word requires first payload word; no data in registers + if (input_eth_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_save = 1; + write_hdr_out = 1; + write_hdr_data[ 7: 0] = eth_src_mac_reg[31:24]; + write_hdr_data[15: 8] = eth_src_mac_reg[23:16]; + write_hdr_data[23:16] = eth_src_mac_reg[15: 8]; + write_hdr_data[31:24] = eth_src_mac_reg[ 7: 0]; + write_hdr_data[39:32] = eth_type_reg[15: 8]; + write_hdr_data[47:40] = eth_type_reg[ 7: 0]; + write_hdr_data[55:48] = input_eth_payload_tdata[ 7: 0]; + write_hdr_data[63:56] = input_eth_payload_tdata[15: 8]; + write_hdr_keep = {input_eth_payload_tkeep[1:0], 6'h3F}; + if (input_eth_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end else begin + state_next = STATE_WRITE_HEADER_LAST_WAIT; + end + end + STATE_WRITE_PAYLOAD_IDLE: begin + // idle; no data in registers + if (input_eth_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_save = 1; + transfer_in_out = 1; + if (input_eth_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end else begin + state_next = STATE_WRITE_PAYLOAD_IDLE; + end + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // read payload; data in output register + if (input_eth_payload_tvalid & output_axis_tready) begin + // word transfer through - update output register + transfer_in_save = 1; + transfer_in_out = 1; + if (input_eth_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end else if (~input_eth_payload_tvalid & output_axis_tready) begin + // word transfer out - go back to idle + state_next = STATE_WRITE_PAYLOAD_IDLE; + end else if (input_eth_payload_tvalid & ~output_axis_tready) begin + // word transfer in - store in temp + transfer_in_save = 1; + transfer_in_temp = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in both output and temp registers + if (output_axis_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_axis_tlast_reg | (save_eth_payload_tlast_reg & save_eth_payload_tkeep_reg[7:6] != 0)) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + if (output_axis_tready) begin + // word transfer out - done + if (save_eth_payload_tkeep_reg[7:2]) begin + // part of word in save register + transfer_save_out = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + // nothing in save register; done + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + eth_dest_mac_reg <= 0; + eth_src_mac_reg <= 0; + eth_type_reg <= 0; + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + busy_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_eth_hdr_ready_reg <= 1; + input_eth_payload_tready_reg <= 0; + output_axis_tvalid_reg <= 0; + end + STATE_WRITE_HEADER: begin + // read header; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_axis_tvalid_reg <= 1; + end + STATE_WRITE_HEADER_LAST: begin + // write last header word; need first data word + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_axis_tvalid_reg <= 1; + end + STATE_WRITE_HEADER_LAST_WAIT: begin + // last header word requires first payload word; no data in registers + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_axis_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_IDLE: begin + // read payload; no data in registers; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_axis_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // read payload; data in output register; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_axis_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in output and temp registers; do not accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_axis_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_axis_tvalid_reg <= 1; + end + endcase + + if (store_eth_hdr) begin + eth_dest_mac_reg <= input_eth_dest_mac; + eth_src_mac_reg <= input_eth_src_mac; + eth_type_reg <= input_eth_type; + end + + if (transfer_in_save) begin + save_eth_payload_tdata_reg <= input_eth_payload_tdata; + save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; + save_eth_payload_tlast_reg <= input_eth_payload_tlast; + save_eth_payload_tuser_reg <= input_eth_payload_tuser; + end else if (transfer_save_out) begin + output_axis_tdata_reg <= {16'd0, save_eth_payload_tdata_reg[63:16]}; + output_axis_tkeep_reg <= {2'd0, save_eth_payload_tkeep_reg[7:2]}; + output_axis_tlast_reg <= save_eth_payload_tlast_reg; + output_axis_tuser_reg <= save_eth_payload_tuser_reg; + save_eth_payload_tkeep_reg <= 0; + end + + if (write_hdr_out) begin + output_axis_tdata_reg <= write_hdr_data; + output_axis_tkeep_reg <= write_hdr_keep; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + end else if (write_hdr_temp) begin + temp_axis_tdata_reg <= write_hdr_data; + temp_axis_tkeep_reg <= write_hdr_keep; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else if (transfer_in_out) begin + output_axis_tdata_reg <= {input_eth_payload_tdata[15:0], save_eth_payload_tdata_reg[63:16]}; + output_axis_tkeep_reg <= {input_eth_payload_tkeep[1:0], save_eth_payload_tkeep_reg[7:2]}; + output_axis_tlast_reg <= input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0); + output_axis_tuser_reg <= input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0); + end else if (transfer_in_temp) begin + temp_axis_tdata_reg <= {input_eth_payload_tdata[15:0], save_eth_payload_tdata_reg[63:16]}; + temp_axis_tkeep_reg <= {input_eth_payload_tkeep[1:0], save_eth_payload_tkeep_reg[7:2]}; + temp_axis_tlast_reg <= input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0); + temp_axis_tuser_reg <= input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0); + end else if (transfer_temp_out) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/tb/eth_ep.py b/tb/eth_ep.py new file mode 100644 index 000000000..a71086f4f --- /dev/null +++ b/tb/eth_ep.py @@ -0,0 +1,228 @@ +""" + +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 axis_ep +from Queue import Queue +import struct + +class EthFrame(object): + def __init__(self, payload=b'', eth_dest_mac=0, eth_src_mac=0, eth_type=0): + self._payload = axis_ep.AXIStreamFrame() + self.eth_dest_mac = eth_dest_mac + self.eth_src_mac = eth_src_mac + self.eth_type = eth_type + + if type(payload) is dict: + self.payload = axis_ep.AXIStreamFrame(payload['eth_payload']) + self.eth_dest_mac = payload['eth_dest_mac'] + self.eth_src_mac = payload['eth_src_mac'] + self.eth_type = payload['eth_type'] + if type(payload) is bytes: + payload = bytearray(payload) + if type(payload) is bytearray or type(payload) is axis_ep.AXIStreamFrame: + self.payload = axis_ep.AXIStreamFrame(payload) + if type(payload) is EthFrame: + self.payload = axis_ep.AXIStreamFrame(payload.payload) + self.eth_dest_mac = payload.eth_dest_mac + self.eth_src_mac = payload.eth_src_mac + self.eth_type = payload.eth_type + + @property + def payload(self): + return self._payload + + @payload.setter + def payload(self, value): + self._payload = axis_ep.AXIStreamFrame(value) + + def build_axis(self): + data = b'' + + data += struct.pack('>Q', self.eth_dest_mac)[2:] + data += struct.pack('>Q', self.eth_src_mac)[2:] + data += struct.pack('>H', self.eth_type) + + data += self.payload.data + + return axis_ep.AXIStreamFrame(data) + + def parse_axis(self, data): + data = axis_ep.AXIStreamFrame(data).data + self.eth_dest_mac = struct.unpack('>Q', '\x00\x00'+data[0:6])[0] + self.eth_src_mac = struct.unpack('>Q', '\x00\x00'+data[6:12])[0] + self.eth_type = struct.unpack('>H', data[12:14])[0] + data = data[14:] + self.payload = axis_ep.AXIStreamFrame(data) + + def __eq__(self, other): + if type(other) is EthFrame: + return (self.eth_src_mac == other.eth_src_mac and + self.eth_dest_mac == other.eth_dest_mac and + self.eth_type == other.eth_type and + self.payload == other.payload) + + def __repr__(self): + return 'EthFrame(payload=%s, eth_dest_mac=0x%012x, eth_src_mac=0x%012x, eth_type=0x%04x)' % (repr(self.payload), self.eth_dest_mac, self.eth_src_mac, self.eth_type) + +def EthFrameSource(clk, rst, + eth_hdr_valid=None, + eth_hdr_ready=None, + eth_dest_mac=None, + eth_src_mac=None, + eth_type=None, + eth_payload_tdata=None, + eth_payload_tkeep=Signal(bool(True)), + eth_payload_tvalid=Signal(bool(False)), + eth_payload_tready=Signal(bool(True)), + eth_payload_tlast=Signal(bool(False)), + eth_payload_tuser=Signal(bool(False)), + fifo=None, + pause=0, + name=None): + + eth_hdr_ready_int = Signal(bool(False)) + eth_hdr_valid_int = Signal(bool(False)) + eth_payload_pause = Signal(bool(False)) + + eth_payload_fifo = Queue() + + eth_payload_source = axis_ep.AXIStreamSource(clk, + rst, + tdata=eth_payload_tdata, + tkeep=eth_payload_tkeep, + tvalid=eth_payload_tvalid, + tready=eth_payload_tready, + tlast=eth_payload_tlast, + tuser=eth_payload_tuser, + fifo=eth_payload_fifo, + pause=eth_payload_pause) + + @always_comb + def pause_logic(): + eth_hdr_ready_int.next = eth_hdr_ready and not pause + eth_hdr_valid.next = eth_hdr_valid_int and not pause + eth_payload_pause.next = pause # or eth_hdr_valid_int + + @instance + def logic(): + frame = dict() + + while True: + yield clk.posedge, rst.posedge + + if rst: + eth_hdr_valid_int.next = False + else: + if eth_hdr_ready_int: + eth_hdr_valid_int.next = False + if (eth_payload_tlast and eth_hdr_ready_int and eth_hdr_valid) or not eth_hdr_valid_int: + if not fifo.empty(): + frame = fifo.get() + frame = EthFrame(frame) + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + eth_payload_fifo.put(frame.payload) + + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + + eth_hdr_valid_int.next = True + + return logic, pause_logic, eth_payload_source + + +def EthFrameSink(clk, rst, + eth_hdr_valid=None, + eth_hdr_ready=None, + eth_dest_mac=None, + eth_src_mac=None, + eth_type=None, + eth_payload_tdata=None, + eth_payload_tkeep=Signal(bool(True)), + eth_payload_tvalid=Signal(bool(True)), + eth_payload_tready=Signal(bool(True)), + eth_payload_tlast=Signal(bool(True)), + eth_payload_tuser=Signal(bool(False)), + fifo=None, + pause=0, + name=None): + + eth_hdr_ready_int = Signal(bool(False)) + eth_hdr_valid_int = Signal(bool(False)) + eth_payload_pause = Signal(bool(False)) + + eth_payload_fifo = Queue() + eth_header_fifo = Queue() + + eth_payload_sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=eth_payload_tdata, + tkeep=eth_payload_tkeep, + tvalid=eth_payload_tvalid, + tready=eth_payload_tready, + tlast=eth_payload_tlast, + tuser=eth_payload_tuser, + fifo=eth_payload_fifo, + pause=eth_payload_pause) + + @always_comb + def pause_logic(): + eth_hdr_ready.next = eth_hdr_ready_int and not pause + eth_hdr_valid_int.next = eth_hdr_valid and not pause + eth_payload_pause.next = pause # or eth_hdr_valid_int + + @instance + def logic(): + frame = EthFrame() + + while True: + yield clk.posedge, rst.posedge + + if rst: + eth_hdr_ready_int.next = False + frame = EthFrame() + else: + eth_hdr_ready_int.next = True + + if eth_hdr_ready_int and eth_hdr_valid_int: + frame = EthFrame() + frame.eth_dest_mac = int(eth_dest_mac) + frame.eth_src_mac = int(eth_src_mac) + frame.eth_type = int(eth_type) + eth_header_fifo.put(frame) + + if not eth_payload_fifo.empty() and not eth_header_fifo.empty(): + frame = eth_header_fifo.get() + frame.payload = eth_payload_fifo.get() + fifo.put(frame) + + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + + frame = dict() + + return logic, pause_logic, eth_payload_sink + diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py new file mode 100755 index 000000000..7f92ec9e3 --- /dev/null +++ b/tb/test_eth_axis_rx.py @@ -0,0 +1,550 @@ +#!/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 eth_ep + +module = 'eth_axis_rx' + +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_eth_axis_rx(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy, + frame_error): + + 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_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + busy=busy, + frame_error=frame_error) + +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_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + frame_error = 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 = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_eth_axis_rx(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy, + frame_error) + + @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 + + output_eth_hdr_ready.next = True + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + source_queue.put(test_frame.build_axis()) + yield clk.posedge + + yield output_eth_payload_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 = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.payload = bytearray(range(256)) + source_queue.put(test_frame.build_axis()) + yield clk.posedge + + yield output_eth_payload_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 3: test packet with pauses") + current_test.next = 3 + + 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(range(256)) + source_queue.put(test_frame.build_axis()) + 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_eth_payload_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 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + 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 = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + source_queue.put(test_frame1.build_axis()) + source_queue.put(test_frame2.build_axis()) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield output_eth_payload_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 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + 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(range(32)) + source_queue.put(test_frame1.build_axis()) + source_queue.put(test_frame2.build_axis()) + yield clk.posedge + + while input_axis_tvalid or output_eth_payload_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 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + 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(range(32)) + source_queue.put(test_frame1.build_axis()) + source_queue.put(test_frame2.build_axis()) + yield clk.posedge + + while input_axis_tvalid or output_eth_payload_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: alternate pause source 2") + current_test.next = 7 + + 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(range(33)) + 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(range(33)) + source_queue.put(test_frame1.build_axis()) + source_queue.put(test_frame2.build_axis()) + yield clk.posedge + + while input_axis_tvalid or output_eth_payload_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 8: alternate pause sink 2") + current_test.next = 8 + + 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(range(33)) + 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(range(33)) + source_queue.put(test_frame1.build_axis()) + source_queue.put(test_frame2.build_axis()) + yield clk.posedge + + while input_axis_tvalid or output_eth_payload_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 9: tuser assert") + current_test.next = 9 + + 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + axi_frame = test_frame.build_axis() + axi_frame.user = 1 + + source_queue.put(axi_frame) + yield clk.posedge + + yield output_eth_payload_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.payload.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 10: truncated packet") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame() + test_frame.data = bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09') + source_queue.put(test_frame) + yield clk.posedge + + yield input_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + assert frame_error + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_eth_axis_rx.v b/tb/test_eth_axis_rx.v new file mode 100644 index 000000000..6a7e98b92 --- /dev/null +++ b/tb/test_eth_axis_rx.v @@ -0,0 +1,110 @@ +/* + +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_eth_axis_rx; + +// 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_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +// Outputs +wire input_axis_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [7:0] output_eth_payload_tdata; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire busy; +wire frame_error; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_eth_hdr_ready, + output_eth_payload_tready); + $to_myhdl(input_axis_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + busy, + frame_error); + + // dump file + $dumpfile("test_eth_axis_rx.lxt"); + $dumpvars(0, test_eth_axis_rx); +end + +eth_axis_rx +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), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Status signals + .busy(busy), + .frame_error(frame_error) +); + +endmodule diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py new file mode 100755 index 000000000..ae7512c4d --- /dev/null +++ b/tb/test_eth_axis_rx_64.py @@ -0,0 +1,560 @@ +#!/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 eth_ep + +module = 'eth_axis_rx_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_eth_axis_rx_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy, + frame_error): + + 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_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + busy=busy, + frame_error=frame_error) + +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_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[64:]) + output_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + frame_error = 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 = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_eth_axis_rx_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy, + frame_error) + + @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 + + output_eth_hdr_ready.next = True + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + source_queue.put(test_frame.build_axis()) + yield clk.posedge + + yield output_eth_payload_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 = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.payload = bytearray(range(256)) + source_queue.put(test_frame.build_axis()) + yield clk.posedge + + yield output_eth_payload_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 3: test packet with pauses") + current_test.next = 3 + + 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(range(256)) + source_queue.put(test_frame.build_axis()) + 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_eth_payload_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 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + 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 = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + source_queue.put(test_frame1.build_axis()) + source_queue.put(test_frame2.build_axis()) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield output_eth_payload_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 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + 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(range(32)) + source_queue.put(test_frame1.build_axis()) + source_queue.put(test_frame2.build_axis()) + yield clk.posedge + + while input_axis_tvalid or output_eth_payload_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 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + 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(range(32)) + source_queue.put(test_frame1.build_axis()) + source_queue.put(test_frame2.build_axis()) + yield clk.posedge + + while input_axis_tvalid or output_eth_payload_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: alternate pause source 2") + current_test.next = 7 + + 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(range(33)) + 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(range(33)) + source_queue.put(test_frame1.build_axis()) + source_queue.put(test_frame2.build_axis()) + yield clk.posedge + + while input_axis_tvalid or output_eth_payload_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 8: alternate pause sink 2") + current_test.next = 8 + + 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(range(33)) + 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(range(33)) + source_queue.put(test_frame1.build_axis()) + source_queue.put(test_frame2.build_axis()) + yield clk.posedge + + while input_axis_tvalid or output_eth_payload_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 9: tuser assert") + current_test.next = 9 + + 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + axi_frame = test_frame.build_axis() + axi_frame.user = 1 + + source_queue.put(axi_frame) + yield clk.posedge + + yield output_eth_payload_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.payload.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 10: truncated packet") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame() + test_frame.data = bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09') + source_queue.put(test_frame) + yield clk.posedge + + yield input_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + assert frame_error + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_eth_axis_rx_64.v b/tb/test_eth_axis_rx_64.v new file mode 100644 index 000000000..4dc523c2c --- /dev/null +++ b/tb/test_eth_axis_rx_64.v @@ -0,0 +1,116 @@ +/* + +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_eth_axis_rx_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_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +// Outputs +wire input_axis_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [63:0] output_eth_payload_tdata; +wire [7:0] output_eth_payload_tkeep; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire busy; +wire frame_error; + +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_eth_hdr_ready, + output_eth_payload_tready); + $to_myhdl(input_axis_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + busy, + frame_error); + + // dump file + $dumpfile("test_eth_axis_rx_64.lxt"); + $dumpvars(0, test_eth_axis_rx_64); +end + +eth_axis_rx_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), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Status signals + .busy(busy), + .frame_error(frame_error) +); + +endmodule diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py new file mode 100755 index 000000000..8b8a41fcb --- /dev/null +++ b/tb/test_eth_axis_tx.py @@ -0,0 +1,561 @@ +#!/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 eth_ep + +module = 'eth_axis_tx' + +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_eth_axis_tx(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + busy): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_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, + + busy=busy) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:0]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + busy = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_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_eth_axis_tx(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + busy) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + source_queue.put(test_frame) + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + 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(range(256)) + source_queue.put(test_frame) + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + 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(range(256)) + source_queue.put(test_frame) + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + 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 = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + 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 = b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + source_queue.put(test_frame1) + source_queue.put(test_frame2) + + yield output_axis_tlast.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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + 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(range(32)) + 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(range(32)) + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + + 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(range(32)) + 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(range(32)) + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: alternate pause source 2") + current_test.next = 7 + + 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(range(33)) + 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(range(33)) + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 8: alternate pause sink 2") + current_test.next = 8 + + 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(range(33)) + 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(range(33)) + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 9: tuser assert") + current_test.next = 9 + + 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + test_frame.payload.user = 1 + source_queue.put(test_frame) + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_eth_axis_tx.v b/tb/test_eth_axis_tx.v new file mode 100644 index 000000000..28debdb57 --- /dev/null +++ b/tb/test_eth_axis_tx.v @@ -0,0 +1,107 @@ +/* + +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_eth_axis_tx; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [7:0] input_eth_payload_tdata = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_eth_payload_tready; +wire input_eth_hdr_ready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; +wire busy; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_axis_tready); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + busy); + + // dump file + $dumpfile("test_eth_axis_tx.lxt"); + $dumpvars(0, test_eth_axis_tx); +end + +eth_axis_tx +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_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 signals + .busy(busy) +); + +endmodule diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py new file mode 100755 index 000000000..d5f8fb58b --- /dev/null +++ b/tb/test_eth_axis_tx_64.py @@ -0,0 +1,571 @@ +#!/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 eth_ep + +module = 'eth_axis_tx_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_eth_axis_tx_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + busy): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_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, + + busy=busy) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:0]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[64:]) + input_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + 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)) + input_eth_hdr_ready = Signal(bool(1)) + input_eth_payload_tready = Signal(bool(0)) + busy = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_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_eth_axis_tx_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + busy) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + source_queue.put(test_frame) + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + 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(range(256)) + source_queue.put(test_frame) + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + 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(range(256)) + source_queue.put(test_frame) + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + 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 = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + 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 = b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + source_queue.put(test_frame1) + source_queue.put(test_frame2) + + yield output_axis_tlast.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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + 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(range(32)) + 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(range(32)) + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + + 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(range(32)) + 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(range(32)) + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: alternate pause source 2") + current_test.next = 7 + + 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(range(33)) + 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(range(33)) + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 8: alternate pause sink 2") + current_test.next = 8 + + 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(range(33)) + 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(range(33)) + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 9: tuser assert") + current_test.next = 9 + + 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + test_frame.payload.user = 1 + source_queue.put(test_frame) + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_eth_axis_tx_64.v b/tb/test_eth_axis_tx_64.v new file mode 100644 index 000000000..a08fa101e --- /dev/null +++ b/tb/test_eth_axis_tx_64.v @@ -0,0 +1,113 @@ +/* + +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_eth_axis_tx_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [63:0] input_eth_payload_tdata = 0; +reg [7:0] input_eth_payload_tkeep = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_eth_payload_tready; +wire input_eth_hdr_ready; +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 busy; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_axis_tready); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + busy); + + // dump file + $dumpfile("test_eth_axis_tx_64.lxt"); + $dumpvars(0, test_eth_axis_tx_64); +end + +eth_axis_tx_64 +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_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 signals + .busy(busy) +); + +endmodule From 96f1e432f479403d66d69be3f270872469e83139 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 15 Sep 2014 19:02:41 -0700 Subject: [PATCH 006/617] Remove old code --- tb/test_eth_axis_rx.py | 3 --- tb/test_eth_axis_rx_64.py | 3 --- 2 files changed, 6 deletions(-) diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index 7f92ec9e3..e7d4e0dfe 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -192,9 +192,6 @@ def bench(): yield delay(100) yield clk.posedge - output_eth_hdr_ready.next = True - yield clk.posedge - yield clk.posedge print("test 1: test packet") current_test.next = 1 diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index ae7512c4d..ea5818084 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -202,9 +202,6 @@ def bench(): yield delay(100) yield clk.posedge - output_eth_hdr_ready.next = True - yield clk.posedge - yield clk.posedge print("test 1: test packet") current_test.next = 1 From 46c29160ffee438cb66e08254ee9630fc2e49f11 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 15 Sep 2014 19:03:31 -0700 Subject: [PATCH 007/617] Wait for header instead of payload --- rtl/eth_axis_tx.v | 2 +- rtl/eth_axis_tx_64.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index 4783cfaef..cf92f3412 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -149,7 +149,7 @@ always @* begin // idle state - wait for data frame_ptr_next = 0; - if (input_eth_payload_tvalid) begin + if (input_eth_hdr_valid) begin store_eth_hdr = 1; write_hdr_out = 1; write_hdr_data = input_eth_dest_mac[47:40]; diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index 0b24fadc5..211f9840b 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -167,7 +167,7 @@ always @* begin // idle state - wait for data frame_ptr_next = 0; - if (input_eth_payload_tvalid) begin + if (input_eth_hdr_valid) begin store_eth_hdr = 1; write_hdr_out = 1; write_hdr_data[ 7: 0] = input_eth_dest_mac[47:40]; From a8958f4b23667cd678d7f592743454bf3e477c28 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 15 Sep 2014 19:04:49 -0700 Subject: [PATCH 008/617] Remove unnecessary registers --- rtl/eth_axis_tx.v | 2 -- 1 file changed, 2 deletions(-) diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index cf92f3412..7ab8a6dd8 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -94,8 +94,6 @@ reg store_eth_hdr; reg [7:0] write_hdr_data; reg write_hdr_out; -reg transfer_in_save; -reg transfer_save_out; reg transfer_in_out; reg transfer_in_temp; reg transfer_temp_out; From d7f30a777bdf4d9f94beefeeb6907144e3434472 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 15 Sep 2014 19:05:18 -0700 Subject: [PATCH 009/617] Update comments --- rtl/eth_axis_tx.v | 16 ++++++++-------- rtl/eth_axis_tx_64.v | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index 7ab8a6dd8..949e46c6d 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -201,7 +201,7 @@ always @* begin end end STATE_WRITE_PAYLOAD_TRANSFER: begin - // read payload; data in output register + // write payload; data in output register if (input_eth_payload_tvalid & output_axis_tready) begin // word transfer through - update output register transfer_in_out = 1; @@ -222,7 +222,7 @@ always @* begin end end STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in both output and temp registers + // write payload; data in both output and temp registers if (output_axis_tready) begin // transfer out - move temp to output transfer_temp_out = 1; @@ -236,7 +236,7 @@ always @* begin end end STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data + // write last payload word; data in output register; do not accept new data if (output_axis_tready) begin // word transfer out - done state_next = STATE_IDLE; @@ -280,31 +280,31 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= 0; end STATE_WRITE_HEADER: begin - // read header; accept new data + // write header input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 0; output_axis_tvalid_reg <= 1; end STATE_WRITE_PAYLOAD_IDLE: begin - // read payload; no data in registers; accept new data + // write payload; no data in registers; accept new data input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 1; output_axis_tvalid_reg <= 0; end STATE_WRITE_PAYLOAD_TRANSFER: begin - // read payload; data in output register; accept new data + // write payload; data in output register; accept new data input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 1; output_axis_tvalid_reg <= 1; end STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in output and temp registers; do not accept new data + // write payload; data in output and temp registers; do not accept new data input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 0; output_axis_tvalid_reg <= 1; end STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data + // write last payload word; data in output register; do not accept new data input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 0; output_axis_tvalid_reg <= 1; diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index 211f9840b..9ac013b39 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -266,7 +266,7 @@ always @* begin end end STATE_WRITE_PAYLOAD_TRANSFER: begin - // read payload; data in output register + // write payload; data in output register if (input_eth_payload_tvalid & output_axis_tready) begin // word transfer through - update output register transfer_in_save = 1; @@ -289,7 +289,7 @@ always @* begin end end STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in both output and temp registers + // write payload; data in both output and temp registers if (output_axis_tready) begin // transfer out - move temp to output transfer_temp_out = 1; @@ -303,7 +303,7 @@ always @* begin end end STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data + // write last payload word; data in output register; do not accept new data if (output_axis_tready) begin // word transfer out - done if (save_eth_payload_tkeep_reg[7:2]) begin @@ -366,31 +366,31 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= 1; end STATE_WRITE_HEADER_LAST_WAIT: begin - // last header word requires first payload word; no data in registers + // last header word requires first payload word; no data in registers input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 1; output_axis_tvalid_reg <= 0; end STATE_WRITE_PAYLOAD_IDLE: begin - // read payload; no data in registers; accept new data + // write payload; no data in registers; accept new data input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 1; output_axis_tvalid_reg <= 0; end STATE_WRITE_PAYLOAD_TRANSFER: begin - // read payload; data in output register; accept new data + // write payload; data in output register; accept new data input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 1; output_axis_tvalid_reg <= 1; end STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in output and temp registers; do not accept new data + // write payload; data in output and temp registers; do not accept new data input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 0; output_axis_tvalid_reg <= 1; end STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data + // write last payload word; data in output register; do not accept new data input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 0; output_axis_tvalid_reg <= 1; From ea2b1b99d05c0373f209eb2c1da6451dff4b7ee6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 15 Sep 2014 19:06:02 -0700 Subject: [PATCH 010/617] Add ARP frame to Ethernet frame modules --- rtl/arp_eth_rx.v | 378 ++++++++++++++++++++++++ rtl/arp_eth_rx_64.v | 315 ++++++++++++++++++++ rtl/arp_eth_tx.v | 309 ++++++++++++++++++++ rtl/arp_eth_tx_64.v | 328 +++++++++++++++++++++ tb/arp_ep.py | 279 ++++++++++++++++++ tb/test_arp_eth_rx.py | 595 ++++++++++++++++++++++++++++++++++++++ tb/test_arp_eth_rx.v | 137 +++++++++ tb/test_arp_eth_rx_64.py | 600 +++++++++++++++++++++++++++++++++++++++ tb/test_arp_eth_rx_64.v | 140 +++++++++ tb/test_arp_eth_tx.py | 472 ++++++++++++++++++++++++++++++ tb/test_arp_eth_tx.v | 134 +++++++++ tb/test_arp_eth_tx_64.py | 477 +++++++++++++++++++++++++++++++ tb/test_arp_eth_tx_64.v | 137 +++++++++ 13 files changed, 4301 insertions(+) create mode 100644 rtl/arp_eth_rx.v create mode 100644 rtl/arp_eth_rx_64.v create mode 100644 rtl/arp_eth_tx.v create mode 100644 rtl/arp_eth_tx_64.v create mode 100644 tb/arp_ep.py create mode 100755 tb/test_arp_eth_rx.py create mode 100644 tb/test_arp_eth_rx.v create mode 100755 tb/test_arp_eth_rx_64.py create mode 100644 tb/test_arp_eth_rx_64.v create mode 100755 tb/test_arp_eth_tx.py create mode 100644 tb/test_arp_eth_tx.v create mode 100755 tb/test_arp_eth_tx_64.py create mode 100644 tb/test_arp_eth_tx_64.v diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v new file mode 100644 index 000000000..38724e6f5 --- /dev/null +++ b/rtl/arp_eth_rx.v @@ -0,0 +1,378 @@ +/* + +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 + +/* + * ARP ethernet frame receiver (Ethernet frame in, ARP frame out) + */ +module arp_eth_rx +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [7:0] input_eth_payload_tdata, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * ARP frame output + */ + output wire output_frame_valid, + input wire output_frame_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [15:0] output_arp_htype, + output wire [15:0] output_arp_ptype, + output wire [7:0] output_arp_hlen, + output wire [7:0] output_arp_plen, + output wire [15:0] output_arp_oper, + output wire [47:0] output_arp_sha, + output wire [31:0] output_arp_spa, + output wire [47:0] output_arp_tha, + output wire [31:0] output_arp_tpa, + + /* + * Status signals + */ + output wire busy, + output wire frame_error +); + +/* + +ARP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0806) 2 octets + HTYPE (1) 2 octets + PTYPE (0x0800) 2 octets + HLEN (6) 1 octets + PLEN (4) 1 octets + OPER 2 octets + SHA Sender MAC 6 octets + SPA Sender IP 4 octets + THA Target MAC 6 octets + TPA Target IP 4 octets + +This module receives an Ethernet frame with decoded fields and decodes +the ARP packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_READ_HEADER = 3'd1, + STATE_WAIT_LAST = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_eth_hdr; +reg store_arp_htype_0; +reg store_arp_htype_1; +reg store_arp_ptype_0; +reg store_arp_ptype_1; +reg store_arp_hlen; +reg store_arp_plen; +reg store_arp_oper_0; +reg store_arp_oper_1; +reg store_arp_sha_0; +reg store_arp_sha_1; +reg store_arp_sha_2; +reg store_arp_sha_3; +reg store_arp_sha_4; +reg store_arp_sha_5; +reg store_arp_spa_0; +reg store_arp_spa_1; +reg store_arp_spa_2; +reg store_arp_spa_3; +reg store_arp_tha_0; +reg store_arp_tha_1; +reg store_arp_tha_2; +reg store_arp_tha_3; +reg store_arp_tha_4; +reg store_arp_tha_5; +reg store_arp_tpa_0; +reg store_arp_tpa_1; +reg store_arp_tpa_2; +reg store_arp_tpa_3; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg input_eth_hdr_ready_reg = 0; +reg input_eth_payload_tready_reg = 0; + +reg output_frame_valid_reg = 0, output_frame_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [15:0] output_arp_htype_reg = 0; +reg [15:0] output_arp_ptype_reg = 0; +reg [7:0] output_arp_hlen_reg = 0; +reg [7:0] output_arp_plen_reg = 0; +reg [15:0] output_arp_oper_reg = 0; +reg [47:0] output_arp_sha_reg = 0; +reg [31:0] output_arp_spa_reg = 0; +reg [47:0] output_arp_tha_reg = 0; +reg [31:0] output_arp_tpa_reg = 0; + +reg busy_reg = 0; +reg frame_error_reg = 0, frame_error_next; + +assign input_eth_hdr_ready = input_eth_hdr_ready_reg; +assign input_eth_payload_tready = input_eth_payload_tready_reg; + +assign output_frame_valid = output_frame_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_arp_htype = output_arp_htype_reg; +assign output_arp_ptype = output_arp_ptype_reg; +assign output_arp_hlen = output_arp_hlen_reg; +assign output_arp_plen = output_arp_plen_reg; +assign output_arp_oper = output_arp_oper_reg; +assign output_arp_sha = output_arp_sha_reg; +assign output_arp_spa = output_arp_spa_reg; +assign output_arp_tha = output_arp_tha_reg; +assign output_arp_tpa = output_arp_tpa_reg; + +assign busy = busy_reg; +assign frame_error = frame_error_reg; + +always @* begin + state_next = 2'bz; + + store_eth_hdr = 0; + store_arp_htype_0 = 0; + store_arp_htype_1 = 0; + store_arp_ptype_0 = 0; + store_arp_ptype_1 = 0; + store_arp_hlen = 0; + store_arp_plen = 0; + store_arp_oper_0 = 0; + store_arp_oper_1 = 0; + store_arp_sha_0 = 0; + store_arp_sha_1 = 0; + store_arp_sha_2 = 0; + store_arp_sha_3 = 0; + store_arp_sha_4 = 0; + store_arp_sha_5 = 0; + store_arp_spa_0 = 0; + store_arp_spa_1 = 0; + store_arp_spa_2 = 0; + store_arp_spa_3 = 0; + store_arp_tha_0 = 0; + store_arp_tha_1 = 0; + store_arp_tha_2 = 0; + store_arp_tha_3 = 0; + store_arp_tha_4 = 0; + store_arp_tha_5 = 0; + store_arp_tpa_0 = 0; + store_arp_tpa_1 = 0; + store_arp_tpa_2 = 0; + store_arp_tpa_3 = 0; + + frame_ptr_next = frame_ptr_reg; + + output_frame_valid_next = output_frame_valid_reg & ~output_frame_ready; + + frame_error_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_eth_hdr_ready & input_eth_hdr_valid) begin + frame_ptr_next = 0; + store_eth_hdr = 1; + state_next = STATE_READ_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_READ_HEADER: begin + // read header state + if (input_eth_payload_tvalid) begin + // word transfer in - store it + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_READ_HEADER; + case (frame_ptr_reg) + 8'h00: store_arp_htype_1 = 1; + 8'h01: store_arp_htype_0 = 1; + 8'h02: store_arp_ptype_1 = 1; + 8'h03: store_arp_ptype_0 = 1; + 8'h04: store_arp_hlen = 1; + 8'h05: store_arp_plen = 1; + 8'h06: store_arp_oper_1 = 1; + 8'h07: store_arp_oper_0 = 1; + 8'h08: store_arp_sha_5 = 1; + 8'h09: store_arp_sha_4 = 1; + 8'h0A: store_arp_sha_3 = 1; + 8'h0B: store_arp_sha_2 = 1; + 8'h0C: store_arp_sha_1 = 1; + 8'h0D: store_arp_sha_0 = 1; + 8'h0E: store_arp_spa_3 = 1; + 8'h0F: store_arp_spa_2 = 1; + 8'h10: store_arp_spa_1 = 1; + 8'h11: store_arp_spa_0 = 1; + 8'h12: store_arp_tha_5 = 1; + 8'h13: store_arp_tha_4 = 1; + 8'h14: store_arp_tha_3 = 1; + 8'h15: store_arp_tha_2 = 1; + 8'h16: store_arp_tha_1 = 1; + 8'h17: store_arp_tha_0 = 1; + 8'h18: store_arp_tpa_3 = 1; + 8'h19: store_arp_tpa_2 = 1; + 8'h1A: store_arp_tpa_1 = 1; + 8'h1B: begin + store_arp_tpa_0 = 1; + output_frame_valid_next = 1; + state_next = STATE_WAIT_LAST; + end + endcase + if (input_eth_payload_tlast) begin + state_next = STATE_IDLE; + if (frame_ptr_reg != 8'h1B) begin + frame_error_next = 1; + end + end + end else begin + state_next = STATE_READ_HEADER; + end + end + STATE_WAIT_LAST: begin + // read last payload word; data in output register; do not accept new data + if (input_eth_payload_tvalid) begin + // word transfer out - done + if (input_eth_payload_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end else begin + // wait for end of frame; read and discard + state_next = STATE_WAIT_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_frame_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + busy_reg <= 0; + frame_error_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + output_frame_valid_reg <= output_frame_valid_next; + + frame_error_reg <= frame_error_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_eth_hdr_ready_reg <= ~output_frame_valid; + input_eth_payload_tready_reg <= 0; + end + STATE_READ_HEADER: begin + // read header; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + end + endcase + + // datapath + if (store_eth_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + end + + if (store_arp_htype_0) output_arp_htype_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_htype_1) output_arp_htype_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_ptype_0) output_arp_ptype_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_ptype_1) output_arp_ptype_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_hlen) output_arp_hlen_reg <= input_eth_payload_tdata; + if (store_arp_plen) output_arp_plen_reg <= input_eth_payload_tdata; + if (store_arp_oper_0) output_arp_oper_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_oper_1) output_arp_oper_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_sha_0) output_arp_sha_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_sha_1) output_arp_sha_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_sha_2) output_arp_sha_reg[23:16] <= input_eth_payload_tdata; + if (store_arp_sha_3) output_arp_sha_reg[31:24] <= input_eth_payload_tdata; + if (store_arp_sha_4) output_arp_sha_reg[39:32] <= input_eth_payload_tdata; + if (store_arp_sha_5) output_arp_sha_reg[47:40] <= input_eth_payload_tdata; + if (store_arp_spa_0) output_arp_spa_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_spa_1) output_arp_spa_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_spa_2) output_arp_spa_reg[23:16] <= input_eth_payload_tdata; + if (store_arp_spa_3) output_arp_spa_reg[31:24] <= input_eth_payload_tdata; + if (store_arp_tha_0) output_arp_tha_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_tha_1) output_arp_tha_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_tha_2) output_arp_tha_reg[23:16] <= input_eth_payload_tdata; + if (store_arp_tha_3) output_arp_tha_reg[31:24] <= input_eth_payload_tdata; + if (store_arp_tha_4) output_arp_tha_reg[39:32] <= input_eth_payload_tdata; + if (store_arp_tha_5) output_arp_tha_reg[47:40] <= input_eth_payload_tdata; + if (store_arp_tpa_0) output_arp_tpa_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_tpa_1) output_arp_tpa_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_tpa_2) output_arp_tpa_reg[23:16] <= input_eth_payload_tdata; + if (store_arp_tpa_3) output_arp_tpa_reg[31:24] <= input_eth_payload_tdata; + end +end + +endmodule diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v new file mode 100644 index 000000000..cfb1730c9 --- /dev/null +++ b/rtl/arp_eth_rx_64.v @@ -0,0 +1,315 @@ +/* + +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 + +/* + * ARP ethernet frame receiver (Ethernet frame in, ARP frame out, 64 bit datapath) + */ +module arp_eth_rx_64 +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [63:0] input_eth_payload_tdata, + input wire [7:0] input_eth_payload_tkeep, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * ARP frame output + */ + output wire output_frame_valid, + input wire output_frame_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [15:0] output_arp_htype, + output wire [15:0] output_arp_ptype, + output wire [7:0] output_arp_hlen, + output wire [7:0] output_arp_plen, + output wire [15:0] output_arp_oper, + output wire [47:0] output_arp_sha, + output wire [31:0] output_arp_spa, + output wire [47:0] output_arp_tha, + output wire [31:0] output_arp_tpa, + + /* + * Status signals + */ + output wire busy, + output wire frame_error +); + +/* + +ARP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0806) 2 octets + HTYPE (1) 2 octets + PTYPE (0x0800) 2 octets + HLEN (6) 1 octets + PLEN (4) 1 octets + OPER 2 octets + SHA Sender MAC 6 octets + SPA Sender IP 4 octets + THA Target MAC 6 octets + TPA Target IP 4 octets + +This module receives an Ethernet frame with decoded fields and decodes +the ARP packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_READ_HEADER = 3'd1, + STATE_WAIT_LAST = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_eth_hdr; +reg store_arp_hdr_word_0; +reg store_arp_hdr_word_1; +reg store_arp_hdr_word_2; +reg store_arp_hdr_word_3; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg input_eth_hdr_ready_reg = 0; +reg input_eth_payload_tready_reg = 0; + +reg output_frame_valid_reg = 0, output_frame_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [15:0] output_arp_htype_reg = 0; +reg [15:0] output_arp_ptype_reg = 0; +reg [7:0] output_arp_hlen_reg = 0; +reg [7:0] output_arp_plen_reg = 0; +reg [15:0] output_arp_oper_reg = 0; +reg [47:0] output_arp_sha_reg = 0; +reg [31:0] output_arp_spa_reg = 0; +reg [47:0] output_arp_tha_reg = 0; +reg [31:0] output_arp_tpa_reg = 0; + +reg busy_reg = 0; +reg frame_error_reg = 0, frame_error_next; + +assign input_eth_hdr_ready = input_eth_hdr_ready_reg; +assign input_eth_payload_tready = input_eth_payload_tready_reg; + +assign output_frame_valid = output_frame_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_arp_htype = output_arp_htype_reg; +assign output_arp_ptype = output_arp_ptype_reg; +assign output_arp_hlen = output_arp_hlen_reg; +assign output_arp_plen = output_arp_plen_reg; +assign output_arp_oper = output_arp_oper_reg; +assign output_arp_sha = output_arp_sha_reg; +assign output_arp_spa = output_arp_spa_reg; +assign output_arp_tha = output_arp_tha_reg; +assign output_arp_tpa = output_arp_tpa_reg; + +assign busy = busy_reg; +assign frame_error = frame_error_reg; + +always @* begin + state_next = 2'bz; + + store_eth_hdr = 0; + store_arp_hdr_word_0 = 0; + store_arp_hdr_word_1 = 0; + store_arp_hdr_word_2 = 0; + store_arp_hdr_word_3 = 0; + + frame_ptr_next = frame_ptr_reg; + + output_frame_valid_next = output_frame_valid_reg & ~output_frame_ready; + + frame_error_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_eth_hdr_ready & input_eth_hdr_valid) begin + frame_ptr_next = 0; + store_eth_hdr = 1; + state_next = STATE_READ_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_READ_HEADER: begin + // read header state + if (input_eth_payload_tvalid) begin + // word transfer in - store it + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_READ_HEADER; + case (frame_ptr_reg) + 8'h00: store_arp_hdr_word_0 = 1; + 8'h01: store_arp_hdr_word_1 = 1; + 8'h02: store_arp_hdr_word_2 = 1; + 8'h03: begin + store_arp_hdr_word_3 = 1; + output_frame_valid_next = 1; + state_next = STATE_WAIT_LAST; + end + endcase + if (input_eth_payload_tlast) begin + state_next = STATE_IDLE; + if (frame_ptr_reg != 8'h03 | (input_eth_payload_tkeep & 8'h0F) != 8'h0F) begin + frame_error_next = 1; + end + end + end else begin + state_next = STATE_READ_HEADER; + end + end + STATE_WAIT_LAST: begin + // read last payload word; data in output register; do not accept new data + if (input_eth_payload_tvalid) begin + // word transfer out - done + if (input_eth_payload_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end else begin + // wait for end of frame; read and discard + state_next = STATE_WAIT_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_frame_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + busy_reg <= 0; + frame_error_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + output_frame_valid_reg <= output_frame_valid_next; + + frame_error_reg <= frame_error_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_eth_hdr_ready_reg <= ~output_frame_valid; + input_eth_payload_tready_reg <= 0; + end + STATE_READ_HEADER: begin + // read header; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + end + endcase + + // datapath + if (store_eth_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + end + + if (store_arp_hdr_word_0) begin + output_arp_htype_reg[15: 8] <= input_eth_payload_tdata[ 7: 0]; + output_arp_htype_reg[ 7: 0] <= input_eth_payload_tdata[15: 8]; + output_arp_ptype_reg[15: 8] <= input_eth_payload_tdata[23:16]; + output_arp_ptype_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + output_arp_hlen_reg <= input_eth_payload_tdata[39:32]; + output_arp_plen_reg <= input_eth_payload_tdata[47:40]; + output_arp_oper_reg[15: 8] <= input_eth_payload_tdata[55:48]; + output_arp_oper_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; + end + if (store_arp_hdr_word_1) begin + output_arp_sha_reg[47:40] <= input_eth_payload_tdata[ 7: 0]; + output_arp_sha_reg[39:32] <= input_eth_payload_tdata[15: 8]; + output_arp_sha_reg[31:24] <= input_eth_payload_tdata[23:16]; + output_arp_sha_reg[23:16] <= input_eth_payload_tdata[31:24]; + output_arp_sha_reg[15: 8] <= input_eth_payload_tdata[39:32]; + output_arp_sha_reg[ 7: 0] <= input_eth_payload_tdata[47:40]; + output_arp_spa_reg[31:24] <= input_eth_payload_tdata[55:48]; + output_arp_spa_reg[23:16] <= input_eth_payload_tdata[63:56]; + end + if (store_arp_hdr_word_2) begin + output_arp_spa_reg[15: 8] <= input_eth_payload_tdata[ 7: 0]; + output_arp_spa_reg[ 7: 0] <= input_eth_payload_tdata[15: 8]; + output_arp_tha_reg[47:40] <= input_eth_payload_tdata[23:16]; + output_arp_tha_reg[39:32] <= input_eth_payload_tdata[31:24]; + output_arp_tha_reg[31:24] <= input_eth_payload_tdata[39:32]; + output_arp_tha_reg[23:16] <= input_eth_payload_tdata[47:40]; + output_arp_tha_reg[15: 8] <= input_eth_payload_tdata[55:48]; + output_arp_tha_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; + end + if (store_arp_hdr_word_3) begin + output_arp_tpa_reg[31:24] <= input_eth_payload_tdata[ 7: 0]; + output_arp_tpa_reg[23:16] <= input_eth_payload_tdata[15: 8]; + output_arp_tpa_reg[15: 8] <= input_eth_payload_tdata[23:16]; + output_arp_tpa_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + end + end +end + +endmodule diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v new file mode 100644 index 000000000..fbac1e3f9 --- /dev/null +++ b/rtl/arp_eth_tx.v @@ -0,0 +1,309 @@ +/* + +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 + +/* + * ARP ethernet frame transmitter (ARP frame in, Ethernet frame out) + */ +module arp_eth_tx +( + input wire clk, + input wire rst, + + /* + * ARP frame input + */ + input wire input_frame_valid, + output wire input_frame_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [15:0] input_arp_htype, + input wire [15:0] input_arp_ptype, + input wire [7:0] input_arp_hlen, + input wire [7:0] input_arp_plen, + input wire [15:0] input_arp_oper, + input wire [47:0] input_arp_sha, + input wire [31:0] input_arp_spa, + input wire [47:0] input_arp_tha, + input wire [31:0] input_arp_tpa, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Status signals + */ + output wire busy +); + +/* + +ARP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0806) 2 octets + HTYPE (1) 2 octets + PTYPE (0x0800) 2 octets + HLEN (6) 1 octets + PLEN (4) 1 octets + OPER 2 octets + SHA Sender MAC 6 octets + SPA Sender IP 4 octets + THA Target MAC 6 octets + TPA Target IP 4 octets + +This module receives an Ethernet frame with decoded fields and decodes +the ARP packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_WRITE_HEADER = 3'd1, + STATE_WRITE_HEADER_LAST = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_frame; + +reg [7:0] write_hdr_data; +reg write_hdr_last; +reg write_hdr_out; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [15:0] arp_htype_reg = 0; +reg [15:0] arp_ptype_reg = 0; +reg [7:0] arp_hlen_reg = 0; +reg [7:0] arp_plen_reg = 0; +reg [15:0] arp_oper_reg = 0; +reg [47:0] arp_sha_reg = 0; +reg [31:0] arp_spa_reg = 0; +reg [47:0] arp_tha_reg = 0; +reg [31:0] arp_tpa_reg = 0; + +reg input_frame_ready_reg = 0; + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [7:0] output_eth_payload_tdata_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg busy_reg = 0; + +assign input_frame_ready = input_frame_ready_reg; + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign busy = busy_reg; + +always @* begin + state_next = 2'bz; + + store_frame = 0; + + write_hdr_data = 0; + write_hdr_last = 0; + write_hdr_out = 0; + + frame_ptr_next = frame_ptr_reg; + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_frame_valid) begin + store_frame = 1; + write_hdr_out = 1; + write_hdr_data = input_arp_htype[15: 8]; + output_eth_hdr_valid_next = 1; + frame_ptr_next = 1; + state_next = STATE_WRITE_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_HEADER: begin + // read header state + if (output_eth_payload_tready) begin + // word transfer out + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_WRITE_HEADER; + write_hdr_out = 1; + case (frame_ptr_reg) + 8'h01: write_hdr_data = arp_htype_reg[ 7: 0]; + 8'h02: write_hdr_data = arp_ptype_reg[15: 8]; + 8'h03: write_hdr_data = arp_ptype_reg[ 7: 0]; + 8'h04: write_hdr_data = arp_hlen_reg; + 8'h05: write_hdr_data = arp_plen_reg; + 8'h06: write_hdr_data = arp_oper_reg[15: 8]; + 8'h07: write_hdr_data = arp_oper_reg[ 7: 0]; + 8'h08: write_hdr_data = arp_sha_reg[47:40]; + 8'h09: write_hdr_data = arp_sha_reg[39:32]; + 8'h0A: write_hdr_data = arp_sha_reg[31:24]; + 8'h0B: write_hdr_data = arp_sha_reg[23:16]; + 8'h0C: write_hdr_data = arp_sha_reg[15: 8]; + 8'h0D: write_hdr_data = arp_sha_reg[ 7: 0]; + 8'h0E: write_hdr_data = arp_spa_reg[31:24]; + 8'h0F: write_hdr_data = arp_spa_reg[23:16]; + 8'h10: write_hdr_data = arp_spa_reg[15: 8]; + 8'h11: write_hdr_data = arp_spa_reg[ 7: 0]; + 8'h12: write_hdr_data = arp_tha_reg[47:40]; + 8'h13: write_hdr_data = arp_tha_reg[39:32]; + 8'h14: write_hdr_data = arp_tha_reg[31:24]; + 8'h15: write_hdr_data = arp_tha_reg[23:16]; + 8'h16: write_hdr_data = arp_tha_reg[15: 8]; + 8'h17: write_hdr_data = arp_tha_reg[ 7: 0]; + 8'h18: write_hdr_data = arp_tpa_reg[31:24]; + 8'h19: write_hdr_data = arp_tpa_reg[23:16]; + 8'h1A: write_hdr_data = arp_tpa_reg[15: 8]; + 8'h1B: begin + write_hdr_data = arp_tpa_reg[ 7: 0]; + write_hdr_last = 1; + state_next = STATE_WRITE_HEADER_LAST; + end + endcase + end else begin + state_next = STATE_WRITE_HEADER; + end + end + STATE_WRITE_HEADER_LAST: begin + // write last header word; data in output register + if (output_eth_payload_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_WRITE_HEADER_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_frame_ready_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + arp_htype_reg <= 0; + arp_ptype_reg <= 0; + arp_hlen_reg <= 0; + arp_plen_reg <= 0; + arp_oper_reg <= 0; + arp_sha_reg <= 0; + arp_spa_reg <= 0; + arp_tha_reg <= 0; + arp_tpa_reg <= 0; + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + busy_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_frame_ready_reg <= ~output_eth_hdr_valid; + output_eth_payload_tvalid_reg <= 0; + end + STATE_WRITE_HEADER: begin + // write header + input_frame_ready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_HEADER_LAST: begin + // write last header word; data in output register + input_frame_ready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + endcase + + if (store_frame) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + arp_htype_reg <= input_arp_htype; + arp_ptype_reg <= input_arp_ptype; + arp_hlen_reg <= input_arp_hlen; + arp_plen_reg <= input_arp_plen; + arp_oper_reg <= input_arp_oper; + arp_sha_reg <= input_arp_sha; + arp_spa_reg <= input_arp_spa; + arp_tha_reg <= input_arp_tha; + arp_tpa_reg <= input_arp_tpa; + end + + if (write_hdr_out) begin + output_eth_payload_tdata_reg <= write_hdr_data; + output_eth_payload_tlast_reg <= write_hdr_last; + output_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v new file mode 100644 index 000000000..8729c2ca4 --- /dev/null +++ b/rtl/arp_eth_tx_64.v @@ -0,0 +1,328 @@ +/* + +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 + +/* + * ARP ethernet frame transmitter (ARP frame in, Ethernet frame out, 64 bit datapath) + */ +module arp_eth_tx_64 +( + input wire clk, + input wire rst, + + /* + * ARP frame input + */ + input wire input_frame_valid, + output wire input_frame_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [15:0] input_arp_htype, + input wire [15:0] input_arp_ptype, + input wire [7:0] input_arp_hlen, + input wire [7:0] input_arp_plen, + input wire [15:0] input_arp_oper, + input wire [47:0] input_arp_sha, + input wire [31:0] input_arp_spa, + input wire [47:0] input_arp_tha, + input wire [31:0] input_arp_tpa, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Status signals + */ + output wire busy +); + +/* + +ARP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0806) 2 octets + HTYPE (1) 2 octets + PTYPE (0x0800) 2 octets + HLEN (6) 1 octets + PLEN (4) 1 octets + OPER 2 octets + SHA Sender MAC 6 octets + SPA Sender IP 4 octets + THA Target MAC 6 octets + TPA Target IP 4 octets + +This module receives an Ethernet frame with decoded fields and decodes +the ARP packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_WRITE_HEADER = 3'd1, + STATE_WRITE_HEADER_LAST = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_frame; + +reg [63:0] write_hdr_data; +reg [7:0] write_hdr_keep; +reg write_hdr_last; +reg write_hdr_out; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [15:0] arp_htype_reg = 0; +reg [15:0] arp_ptype_reg = 0; +reg [7:0] arp_hlen_reg = 0; +reg [7:0] arp_plen_reg = 0; +reg [15:0] arp_oper_reg = 0; +reg [47:0] arp_sha_reg = 0; +reg [31:0] arp_spa_reg = 0; +reg [47:0] arp_tha_reg = 0; +reg [31:0] arp_tpa_reg = 0; + +reg input_frame_ready_reg = 0; + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg busy_reg = 0; + +assign input_frame_ready = input_frame_ready_reg; + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign busy = busy_reg; + +always @* begin + state_next = 2'bz; + + store_frame = 0; + + write_hdr_data = 0; + write_hdr_keep = 0; + write_hdr_last = 0; + write_hdr_out = 0; + + frame_ptr_next = frame_ptr_reg; + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_frame_valid) begin + store_frame = 1; + write_hdr_out = 1; + write_hdr_data[ 7: 0] = input_arp_htype[15: 8]; + write_hdr_data[15: 8] = input_arp_htype[ 7: 0]; + write_hdr_data[23:16] = input_arp_ptype[15: 8]; + write_hdr_data[31:24] = input_arp_ptype[ 7: 0]; + write_hdr_data[39:32] = input_arp_hlen; + write_hdr_data[47:40] = input_arp_plen; + write_hdr_data[55:48] = input_arp_oper[15: 8]; + write_hdr_data[63:56] = input_arp_oper[ 7: 0]; + write_hdr_keep = 8'hff; + frame_ptr_next = 8; + output_eth_hdr_valid_next = 1; + state_next = STATE_WRITE_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_HEADER: begin + // read header state + if (output_eth_payload_tready) begin + // word transfer out + frame_ptr_next = frame_ptr_reg+8; + state_next = STATE_WRITE_HEADER; + write_hdr_out = 1; + case (frame_ptr_reg) + 8'h08: begin + write_hdr_data[ 7: 0] = arp_sha_reg[47:40]; + write_hdr_data[15: 8] = arp_sha_reg[39:32]; + write_hdr_data[23:16] = arp_sha_reg[31:24]; + write_hdr_data[31:24] = arp_sha_reg[23:16]; + write_hdr_data[39:32] = arp_sha_reg[15: 8]; + write_hdr_data[47:40] = arp_sha_reg[ 7: 0]; + write_hdr_data[55:48] = arp_spa_reg[31:24]; + write_hdr_data[63:56] = arp_spa_reg[23:16]; + write_hdr_keep = 8'hff; + end + 8'h10: begin + write_hdr_data[ 7: 0] = arp_spa_reg[15: 8]; + write_hdr_data[15: 8] = arp_spa_reg[ 7: 0]; + write_hdr_data[23:16] = arp_tha_reg[47:40]; + write_hdr_data[31:24] = arp_tha_reg[39:32]; + write_hdr_data[39:32] = arp_tha_reg[31:24]; + write_hdr_data[47:40] = arp_tha_reg[23:16]; + write_hdr_data[55:48] = arp_tha_reg[15: 8]; + write_hdr_data[63:56] = arp_tha_reg[ 7: 0]; + write_hdr_keep = 8'hff; + end + 8'h18: begin + write_hdr_data[ 7: 0] = arp_tpa_reg[31:24]; + write_hdr_data[15: 8] = arp_tpa_reg[23:16]; + write_hdr_data[23:16] = arp_tpa_reg[15: 8]; + write_hdr_data[31:24] = arp_tpa_reg[ 7: 0]; + write_hdr_data[39:32] = 0; + write_hdr_data[47:40] = 0; + write_hdr_data[55:48] = 0; + write_hdr_data[63:56] = 0; + write_hdr_keep = 8'h0f; + write_hdr_last = 1; + state_next = STATE_WRITE_HEADER_LAST; + end + endcase + end else begin + state_next = STATE_WRITE_HEADER; + end + end + STATE_WRITE_HEADER_LAST: begin + // write last header word; data in output register + if (output_eth_payload_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_WRITE_HEADER_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_frame_ready_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + arp_htype_reg <= 0; + arp_ptype_reg <= 0; + arp_hlen_reg <= 0; + arp_plen_reg <= 0; + arp_oper_reg <= 0; + arp_sha_reg <= 0; + arp_spa_reg <= 0; + arp_tha_reg <= 0; + arp_tpa_reg <= 0; + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tkeep_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + busy_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_frame_ready_reg <= ~output_eth_hdr_valid; + output_eth_payload_tvalid_reg <= 0; + end + STATE_WRITE_HEADER: begin + // write header + input_frame_ready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_HEADER_LAST: begin + // write last header word; data in output register + input_frame_ready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + endcase + + if (store_frame) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + arp_htype_reg <= input_arp_htype; + arp_ptype_reg <= input_arp_ptype; + arp_hlen_reg <= input_arp_hlen; + arp_plen_reg <= input_arp_plen; + arp_oper_reg <= input_arp_oper; + arp_sha_reg <= input_arp_sha; + arp_spa_reg <= input_arp_spa; + arp_tha_reg <= input_arp_tha; + arp_tpa_reg <= input_arp_tpa; + end + + if (write_hdr_out) begin + output_eth_payload_tdata_reg <= write_hdr_data; + output_eth_payload_tkeep_reg <= write_hdr_keep; + output_eth_payload_tlast_reg <= write_hdr_last; + output_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/arp_ep.py b/tb/arp_ep.py new file mode 100644 index 000000000..adf63c1c3 --- /dev/null +++ b/tb/arp_ep.py @@ -0,0 +1,279 @@ +""" + +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 axis_ep +import eth_ep +from Queue import Queue +import struct + +class ARPFrame(object): + def __init__(self, + eth_dest_mac=0, + eth_src_mac=0, + eth_type=0, + arp_htype=1, + arp_ptype=0x0800, + arp_hlen=6, + arp_plen=4, + arp_oper=2, + arp_sha=0x5A5152535455, + arp_spa=0xc0a80164, + arp_tha=0xDAD1D2D3D4D5, + arp_tpa=0xc0a80164): + + self.eth_dest_mac = eth_dest_mac + self.eth_src_mac = eth_src_mac + self.eth_type = eth_type + self.arp_htype = arp_htype + self.arp_ptype = arp_ptype + self.arp_hlen = arp_hlen + self.arp_plen = arp_plen + self.arp_oper = arp_oper + self.arp_sha = arp_sha + self.arp_spa = arp_spa + self.arp_tha = arp_tha + self.arp_tpa = arp_tpa + + if type(eth_dest_mac) is dict: + self.eth_dest_mac = eth_dest_mac['eth_dest_mac'] + self.eth_src_mac = eth_dest_mac['eth_src_mac'] + self.eth_type = eth_dest_mac['eth_type'] + self.arp_htype = eth_dest_mac['arp_htype'] + self.arp_ptype = eth_dest_mac['arp_ptype'] + self.arp_hlen = eth_dest_mac['arp_hlen'] + self.arp_plen = eth_dest_mac['arp_plen'] + self.arp_oper = eth_dest_mac['arp_oper'] + self.arp_sha = eth_dest_mac['arp_sha'] + self.arp_spa = eth_dest_mac['arp_spa'] + self.arp_tha = eth_dest_mac['arp_tha'] + self.arp_tpa = eth_dest_mac['arp_tpa'] + if type(eth_dest_mac) is ARPFrame: + self.eth_dest_mac = eth_dest_mac.eth_dest_mac + self.eth_src_mac = eth_dest_mac.eth_src_mac + self.eth_type = eth_dest_mac.eth_type + self.arp_htype = eth_dest_mac.arp_htype + self.arp_ptype = eth_dest_mac.arp_ptype + self.arp_hlen = eth_dest_mac.arp_hlen + self.arp_plen = eth_dest_mac.arp_plen + self.arp_oper = eth_dest_mac.arp_oper + self.arp_sha = eth_dest_mac.arp_sha + self.arp_spa = eth_dest_mac.arp_spa + self.arp_tha = eth_dest_mac.arp_tha + self.arp_tpa = eth_dest_mac.arp_tpa + + def build_axis(self): + return self.build_eth().build_axis() + + def build_eth(self): + data = b'' + + data += struct.pack('>H', self.arp_htype) + data += struct.pack('>H', self.arp_ptype) + data += struct.pack('B', self.arp_hlen) + data += struct.pack('B', self.arp_plen) + data += struct.pack('>H', self.arp_oper) + data += struct.pack('>Q', self.arp_sha)[2:] + data += struct.pack('>L', self.arp_spa) + data += struct.pack('>Q', self.arp_tha)[2:] + data += struct.pack('>L', self.arp_tpa) + + return eth_ep.EthFrame(data, self.eth_dest_mac, self.eth_src_mac, self.eth_type) + + def parse_axis(self, data): + frame = eth_ep.EthFrame() + frame.parse_axis(data) + self.parse_eth(frame) + + def parse_eth(self, data): + self.eth_src_mac = data.eth_src_mac + self.eth_dest_mac = data.eth_dest_mac + self.eth_type = data.eth_type + + self.arp_htype = struct.unpack('>H', data.payload.data[0:2])[0] + self.arp_ptype = struct.unpack('>H', data.payload.data[2:4])[0] + self.arp_hlen = struct.unpack('B', data.payload.data[4:5])[0] + self.arp_plen = struct.unpack('B', data.payload.data[5:6])[0] + self.arp_oper = struct.unpack('>H', data.payload.data[6:8])[0] + self.arp_sha = struct.unpack('>Q', '\x00\x00'+data.payload.data[8:14])[0] + self.arp_spa = struct.unpack('>L', data.payload.data[14:18])[0] + self.arp_tha = struct.unpack('>Q', '\x00\x00'+data.payload.data[18:24])[0] + self.arp_tpa = struct.unpack('>L', data.payload.data[24:28])[0] + + def __eq__(self, other): + if type(other) is ARPFrame: + return (self.eth_src_mac == other.eth_src_mac and + self.eth_dest_mac == other.eth_dest_mac and + self.eth_type == other.eth_type and + self.arp_htype == other.arp_htype and + self.arp_ptype == other.arp_ptype and + self.arp_hlen == other.arp_hlen and + self.arp_plen == other.arp_plen and + self.arp_oper == other.arp_oper and + self.arp_sha == other.arp_sha and + self.arp_spa == other.arp_spa and + self.arp_tha == other.arp_tha and + self.arp_tpa == other.arp_tpa) + + def __repr__(self): + return (('ArpFrame(eth_dest_mac=0x%012x, ' % self.eth_dest_mac) + + ('eth_src_mac=0x%012x, ' % self.eth_src_mac) + + ('eth_type=0x%04x, ' % self.eth_type) + + ('arp_htype=0x%04x, ' % self.arp_htype) + + ('arp_ptype=0x%04x, ' % self.arp_ptype) + + ('arp_hlen=%d, ' % self.arp_hlen) + + ('arp_plen=%d, ' % self.arp_plen) + + ('arp_oper=0x%04x, ' % self.arp_oper) + + ('arp_sha=0x%012x, ' % self.arp_sha) + + ('arp_spa=0x%08x, ' % self.arp_spa) + + ('arp_tha=0x%012x, ' % self.arp_tha) + + ('arp_tpa=0x%08x)' % self.arp_tpa)) + +def ARPFrameSource(clk, rst, + frame_valid=None, + frame_ready=None, + eth_dest_mac=None, + eth_src_mac=None, + eth_type=None, + arp_htype=None, + arp_ptype=None, + arp_hlen=None, + arp_plen=None, + arp_oper=None, + arp_sha=None, + arp_spa=None, + arp_tha=None, + arp_tpa=None, + fifo=None, + pause=0, + name=None): + + frame_ready_int = Signal(bool(False)) + frame_valid_int = Signal(bool(False)) + + @always_comb + def pause_logic(): + frame_ready_int.next = frame_ready and not pause + frame_valid.next = frame_valid_int and not pause + + @instance + def logic(): + frame = dict() + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame_valid_int.next = False + else: + if frame_ready_int: + frame_valid_int.next = False + if (frame_ready_int and frame_valid) or not frame_valid_int: + if not fifo.empty(): + frame = fifo.get() + frame = ARPFrame(frame) + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + arp_htype.next = frame.arp_htype + arp_ptype.next = frame.arp_ptype + arp_hlen.next = frame.arp_hlen + arp_plen.next = frame.arp_plen + arp_oper.next = frame.arp_oper + arp_sha.next = frame.arp_sha + arp_spa.next = frame.arp_spa + arp_tha.next = frame.arp_tha + arp_tpa.next = frame.arp_tpa + + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + + frame_valid_int.next = True + + return logic, pause_logic + + +def ARPFrameSink(clk, rst, + frame_valid=None, + frame_ready=None, + eth_dest_mac=None, + eth_src_mac=None, + eth_type=None, + arp_htype=None, + arp_ptype=None, + arp_hlen=None, + arp_plen=None, + arp_oper=None, + arp_sha=None, + arp_spa=None, + arp_tha=None, + arp_tpa=None, + fifo=None, + pause=0, + name=None): + + frame_ready_int = Signal(bool(False)) + frame_valid_int = Signal(bool(False)) + + @always_comb + def pause_logic(): + frame_ready.next = frame_ready_int and not pause + frame_valid_int.next = frame_valid and not pause + + @instance + def logic(): + frame = ARPFrame() + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame_ready_int.next = False + frame = ARPFrame() + else: + frame_ready_int.next = True + + if frame_ready_int and frame_valid_int: + frame = ARPFrame() + frame.eth_dest_mac = int(eth_dest_mac) + frame.eth_src_mac = int(eth_src_mac) + frame.eth_type = int(eth_type) + frame.arp_htype = int(arp_htype) + frame.arp_ptype = int(arp_ptype) + frame.arp_hlen = int(arp_hlen) + frame.arp_plen = int(arp_plen) + frame.arp_oper = int(arp_oper) + frame.arp_sha = int(arp_sha) + frame.arp_spa = int(arp_spa) + frame.arp_tha = int(arp_tha) + frame.arp_tpa = int(arp_tpa) + fifo.put(frame) + + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + + frame = dict() + + return logic, pause_logic + diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py new file mode 100755 index 000000000..bbe36d579 --- /dev/null +++ b/tb/test_arp_eth_rx.py @@ -0,0 +1,595 @@ +#!/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 arp_ep +import eth_ep + +module = 'arp_eth_rx' + +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_arp_eth_rx(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_frame_valid, + output_frame_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_arp_htype, + output_arp_ptype, + output_arp_hlen, + output_arp_plen, + output_arp_oper, + output_arp_sha, + output_arp_spa, + output_arp_tha, + output_arp_tpa, + + busy, + frame_error): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_frame_valid=output_frame_valid, + output_frame_ready=output_frame_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_arp_htype=output_arp_htype, + output_arp_ptype=output_arp_ptype, + output_arp_hlen=output_arp_hlen, + output_arp_plen=output_arp_plen, + output_arp_oper=output_arp_oper, + output_arp_sha=output_arp_sha, + output_arp_spa=output_arp_spa, + output_arp_tha=output_arp_tha, + output_arp_tpa=output_arp_tpa, + + busy=busy, + frame_error=frame_error) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + output_frame_ready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + output_frame_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_arp_htype = Signal(intbv(0)[16:]) + output_arp_ptype = Signal(intbv(0)[16:]) + output_arp_hlen = Signal(intbv(0)[8:]) + output_arp_plen = Signal(intbv(0)[8:]) + output_arp_oper = Signal(intbv(0)[16:]) + output_arp_sha = Signal(intbv(0)[48:]) + output_arp_spa = Signal(intbv(0)[32:]) + output_arp_tha = Signal(intbv(0)[48:]) + output_arp_tpa = Signal(intbv(0)[32:]) + busy = Signal(bool(0)) + frame_error = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = arp_ep.ARPFrameSink(clk, + rst, + frame_ready=output_frame_ready, + frame_valid=output_frame_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + arp_htype=output_arp_htype, + arp_ptype=output_arp_ptype, + arp_hlen=output_arp_hlen, + arp_plen=output_arp_plen, + arp_oper=output_arp_oper, + arp_sha=output_arp_sha, + arp_spa=output_arp_spa, + arp_tha=output_arp_tha, + arp_tpa=output_arp_tpa, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_arp_eth_rx(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_frame_valid, + output_frame_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_arp_htype, + output_arp_ptype, + output_arp_hlen, + output_arp_plen, + output_arp_oper, + output_arp_sha, + output_arp_spa, + output_arp_tha, + output_arp_tpa, + + busy, + frame_error) + + @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 = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield output_frame_valid.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: packet with trailing bytes") + current_test.next = 2 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + eth_frame = test_frame.build_eth() + eth_frame.payload.data += bytearray(range(10)) + source_queue.put(eth_frame) + yield clk.posedge + + yield output_frame_valid.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 3: test packet with pauses") + current_test.next = 3 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + 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_frame_valid.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 = arp_ep.ARPFrame() + test_frame1.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0806 + test_frame1.arp_htype = 0x0001 + test_frame1.arp_ptype = 0x0800 + test_frame1.arp_hlen = 6 + test_frame1.arp_plen = 4 + test_frame1.arp_oper = 1 + test_frame1.arp_sha = 0x5A5152535455 + test_frame1.arp_spa = 0xc0a80164 + test_frame1.arp_tha = 0xDAD1D2D3D4D5 + test_frame1.arp_tpa = 0xc0a80165 + test_frame2 = arp_ep.ARPFrame() + test_frame2.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0806 + test_frame2.arp_htype = 0x0001 + test_frame2.arp_ptype = 0x0800 + test_frame2.arp_hlen = 6 + test_frame2.arp_plen = 4 + test_frame2.arp_oper = 1 + test_frame2.arp_sha = 0x5A5152535455 + test_frame2.arp_spa = 0xc0a80164 + test_frame2.arp_tha = 0xDAD1D2D3D4D5 + test_frame2.arp_tpa = 0xc0a80165 + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + + yield output_frame_valid.posedge + yield clk.posedge + yield output_frame_valid.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 = arp_ep.ARPFrame() + test_frame1.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0806 + test_frame1.arp_htype = 0x0001 + test_frame1.arp_ptype = 0x0800 + test_frame1.arp_hlen = 6 + test_frame1.arp_plen = 4 + test_frame1.arp_oper = 1 + test_frame1.arp_sha = 0x5A5152535455 + test_frame1.arp_spa = 0xc0a80164 + test_frame1.arp_tha = 0xDAD1D2D3D4D5 + test_frame1.arp_tpa = 0xc0a80165 + test_frame2 = arp_ep.ARPFrame() + test_frame2.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0806 + test_frame2.arp_htype = 0x0001 + test_frame2.arp_ptype = 0x0800 + test_frame2.arp_hlen = 6 + test_frame2.arp_plen = 4 + test_frame2.arp_oper = 1 + test_frame2.arp_sha = 0x5A5152535455 + test_frame2.arp_spa = 0xc0a80164 + test_frame2.arp_tha = 0xDAD1D2D3D4D5 + test_frame2.arp_tpa = 0xc0a80165 + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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 = arp_ep.ARPFrame() + test_frame1.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0806 + test_frame1.arp_htype = 0x0001 + test_frame1.arp_ptype = 0x0800 + test_frame1.arp_hlen = 6 + test_frame1.arp_plen = 4 + test_frame1.arp_oper = 1 + test_frame1.arp_sha = 0x5A5152535455 + test_frame1.arp_spa = 0xc0a80164 + test_frame1.arp_tha = 0xDAD1D2D3D4D5 + test_frame1.arp_tpa = 0xc0a80165 + test_frame2 = arp_ep.ARPFrame() + test_frame2.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0806 + test_frame2.arp_htype = 0x0001 + test_frame2.arp_ptype = 0x0800 + test_frame2.arp_hlen = 6 + test_frame2.arp_plen = 4 + test_frame2.arp_oper = 1 + test_frame2.arp_sha = 0x5A5152535455 + test_frame2.arp_spa = 0xc0a80164 + test_frame2.arp_tha = 0xDAD1D2D3D4D5 + test_frame2.arp_tpa = 0xc0a80165 + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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: truncated packet") + current_test.next = 7 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + eth_frame = test_frame.build_eth() + eth_frame.payload.data = eth_frame.payload.data[:-2] + source_queue.put(eth_frame) + yield clk.posedge + + yield input_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + assert frame_error + + yield delay(100) + + yield clk.posedge + print("test 7: bad header") + current_test.next = 7 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield input_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + #assert frame_error + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_arp_eth_rx.v b/tb/test_arp_eth_rx.v new file mode 100644 index 000000000..52c77cba2 --- /dev/null +++ b/tb/test_arp_eth_rx.v @@ -0,0 +1,137 @@ +/* + +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_arp_eth_rx; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [7:0] input_eth_payload_tdata = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg output_frame_ready = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire output_frame_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [15:0] output_arp_htype; +wire [15:0] output_arp_ptype; +wire [7:0] output_arp_hlen; +wire [7:0] output_arp_plen; +wire [15:0] output_arp_oper; +wire [47:0] output_arp_sha; +wire [31:0] output_arp_spa; +wire [47:0] output_arp_tha; +wire [31:0] output_arp_tpa; +wire busy; +wire frame_error; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_frame_ready); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + output_frame_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_arp_htype, + output_arp_ptype, + output_arp_hlen, + output_arp_plen, + output_arp_oper, + output_arp_sha, + output_arp_spa, + output_arp_tha, + output_arp_tpa, + busy, + frame_error); + + // dump file + $dumpfile("test_arp_eth_rx.lxt"); + $dumpvars(0, test_arp_eth_rx); +end + +arp_eth_rx +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // ARP frame output + .output_frame_valid(output_frame_valid), + .output_frame_ready(output_frame_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_arp_htype(output_arp_htype), + .output_arp_ptype(output_arp_ptype), + .output_arp_hlen(output_arp_hlen), + .output_arp_plen(output_arp_plen), + .output_arp_oper(output_arp_oper), + .output_arp_sha(output_arp_sha), + .output_arp_spa(output_arp_spa), + .output_arp_tha(output_arp_tha), + .output_arp_tpa(output_arp_tpa), + // Status signals + .busy(busy), + .frame_error(frame_error) +); + +endmodule diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py new file mode 100755 index 000000000..899bbcf47 --- /dev/null +++ b/tb/test_arp_eth_rx_64.py @@ -0,0 +1,600 @@ +#!/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 arp_ep +import eth_ep + +module = 'arp_eth_rx_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_arp_eth_rx_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_frame_valid, + output_frame_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_arp_htype, + output_arp_ptype, + output_arp_hlen, + output_arp_plen, + output_arp_oper, + output_arp_sha, + output_arp_spa, + output_arp_tha, + output_arp_tpa, + + busy, + frame_error): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_frame_valid=output_frame_valid, + output_frame_ready=output_frame_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_arp_htype=output_arp_htype, + output_arp_ptype=output_arp_ptype, + output_arp_hlen=output_arp_hlen, + output_arp_plen=output_arp_plen, + output_arp_oper=output_arp_oper, + output_arp_sha=output_arp_sha, + output_arp_spa=output_arp_spa, + output_arp_tha=output_arp_tha, + output_arp_tpa=output_arp_tpa, + + busy=busy, + frame_error=frame_error) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[64:]) + input_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + output_frame_ready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + output_frame_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_arp_htype = Signal(intbv(0)[16:]) + output_arp_ptype = Signal(intbv(0)[16:]) + output_arp_hlen = Signal(intbv(0)[8:]) + output_arp_plen = Signal(intbv(0)[8:]) + output_arp_oper = Signal(intbv(0)[16:]) + output_arp_sha = Signal(intbv(0)[48:]) + output_arp_spa = Signal(intbv(0)[32:]) + output_arp_tha = Signal(intbv(0)[48:]) + output_arp_tpa = Signal(intbv(0)[32:]) + busy = Signal(bool(0)) + frame_error = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = arp_ep.ARPFrameSink(clk, + rst, + frame_ready=output_frame_ready, + frame_valid=output_frame_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + arp_htype=output_arp_htype, + arp_ptype=output_arp_ptype, + arp_hlen=output_arp_hlen, + arp_plen=output_arp_plen, + arp_oper=output_arp_oper, + arp_sha=output_arp_sha, + arp_spa=output_arp_spa, + arp_tha=output_arp_tha, + arp_tpa=output_arp_tpa, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_arp_eth_rx_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_frame_valid, + output_frame_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_arp_htype, + output_arp_ptype, + output_arp_hlen, + output_arp_plen, + output_arp_oper, + output_arp_sha, + output_arp_spa, + output_arp_tha, + output_arp_tpa, + + busy, + frame_error) + + @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 = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield output_frame_valid.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: packet with trailing bytes") + current_test.next = 2 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + eth_frame = test_frame.build_eth() + eth_frame.payload.data += bytearray(range(10)) + source_queue.put(eth_frame) + yield clk.posedge + + yield output_frame_valid.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 3: test packet with pauses") + current_test.next = 3 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield delay(16) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(16) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + #yield output_frame_valid.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 = arp_ep.ARPFrame() + test_frame1.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0806 + test_frame1.arp_htype = 0x0001 + test_frame1.arp_ptype = 0x0800 + test_frame1.arp_hlen = 6 + test_frame1.arp_plen = 4 + test_frame1.arp_oper = 1 + test_frame1.arp_sha = 0x5A5152535455 + test_frame1.arp_spa = 0xc0a80164 + test_frame1.arp_tha = 0xDAD1D2D3D4D5 + test_frame1.arp_tpa = 0xc0a80165 + test_frame2 = arp_ep.ARPFrame() + test_frame2.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0806 + test_frame2.arp_htype = 0x0001 + test_frame2.arp_ptype = 0x0800 + test_frame2.arp_hlen = 6 + test_frame2.arp_plen = 4 + test_frame2.arp_oper = 1 + test_frame2.arp_sha = 0x5A5152535455 + test_frame2.arp_spa = 0xc0a80164 + test_frame2.arp_tha = 0xDAD1D2D3D4D5 + test_frame2.arp_tpa = 0xc0a80165 + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + + yield output_frame_valid.posedge + yield clk.posedge + yield output_frame_valid.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 = arp_ep.ARPFrame() + test_frame1.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0806 + test_frame1.arp_htype = 0x0001 + test_frame1.arp_ptype = 0x0800 + test_frame1.arp_hlen = 6 + test_frame1.arp_plen = 4 + test_frame1.arp_oper = 1 + test_frame1.arp_sha = 0x5A5152535455 + test_frame1.arp_spa = 0xc0a80164 + test_frame1.arp_tha = 0xDAD1D2D3D4D5 + test_frame1.arp_tpa = 0xc0a80165 + test_frame2 = arp_ep.ARPFrame() + test_frame2.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0806 + test_frame2.arp_htype = 0x0001 + test_frame2.arp_ptype = 0x0800 + test_frame2.arp_hlen = 6 + test_frame2.arp_plen = 4 + test_frame2.arp_oper = 1 + test_frame2.arp_sha = 0x5A5152535455 + test_frame2.arp_spa = 0xc0a80164 + test_frame2.arp_tha = 0xDAD1D2D3D4D5 + test_frame2.arp_tpa = 0xc0a80165 + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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 = arp_ep.ARPFrame() + test_frame1.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0806 + test_frame1.arp_htype = 0x0001 + test_frame1.arp_ptype = 0x0800 + test_frame1.arp_hlen = 6 + test_frame1.arp_plen = 4 + test_frame1.arp_oper = 1 + test_frame1.arp_sha = 0x5A5152535455 + test_frame1.arp_spa = 0xc0a80164 + test_frame1.arp_tha = 0xDAD1D2D3D4D5 + test_frame1.arp_tpa = 0xc0a80165 + test_frame2 = arp_ep.ARPFrame() + test_frame2.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0806 + test_frame2.arp_htype = 0x0001 + test_frame2.arp_ptype = 0x0800 + test_frame2.arp_hlen = 6 + test_frame2.arp_plen = 4 + test_frame2.arp_oper = 1 + test_frame2.arp_sha = 0x5A5152535455 + test_frame2.arp_spa = 0xc0a80164 + test_frame2.arp_tha = 0xDAD1D2D3D4D5 + test_frame2.arp_tpa = 0xc0a80165 + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + yield clk.posedge + + while input_eth_payload_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: truncated packet") + current_test.next = 7 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + eth_frame = test_frame.build_eth() + eth_frame.payload.data = eth_frame.payload.data[:-2] + source_queue.put(eth_frame) + yield clk.posedge + + yield input_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + assert frame_error + + yield delay(100) + + yield clk.posedge + print("test 7: bad header") + current_test.next = 7 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield input_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + #assert frame_error + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_arp_eth_rx_64.v b/tb/test_arp_eth_rx_64.v new file mode 100644 index 000000000..9f9e42dba --- /dev/null +++ b/tb/test_arp_eth_rx_64.v @@ -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 1 ns / 1 ps + +module test_arp_eth_rx_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [63:0] input_eth_payload_tdata = 0; +reg [7:0] input_eth_payload_tkeep = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg output_frame_ready = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire output_frame_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [15:0] output_arp_htype; +wire [15:0] output_arp_ptype; +wire [7:0] output_arp_hlen; +wire [7:0] output_arp_plen; +wire [15:0] output_arp_oper; +wire [47:0] output_arp_sha; +wire [31:0] output_arp_spa; +wire [47:0] output_arp_tha; +wire [31:0] output_arp_tpa; +wire busy; +wire frame_error; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_frame_ready); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + output_frame_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_arp_htype, + output_arp_ptype, + output_arp_hlen, + output_arp_plen, + output_arp_oper, + output_arp_sha, + output_arp_spa, + output_arp_tha, + output_arp_tpa, + busy, + frame_error); + + // dump file + $dumpfile("test_arp_eth_rx_64.lxt"); + $dumpvars(0, test_arp_eth_rx_64); +end + +arp_eth_rx_64 +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // ARP frame output + .output_frame_valid(output_frame_valid), + .output_frame_ready(output_frame_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_arp_htype(output_arp_htype), + .output_arp_ptype(output_arp_ptype), + .output_arp_hlen(output_arp_hlen), + .output_arp_plen(output_arp_plen), + .output_arp_oper(output_arp_oper), + .output_arp_sha(output_arp_sha), + .output_arp_spa(output_arp_spa), + .output_arp_tha(output_arp_tha), + .output_arp_tpa(output_arp_tpa), + // Status signals + .busy(busy), + .frame_error(frame_error) +); + +endmodule diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py new file mode 100755 index 000000000..30b9ba118 --- /dev/null +++ b/tb/test_arp_eth_tx.py @@ -0,0 +1,472 @@ +#!/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 eth_ep +import arp_ep + +module = 'arp_eth_tx' + +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_arp_eth_tx(clk, + rst, + current_test, + + input_frame_valid, + input_frame_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_arp_htype, + input_arp_ptype, + input_arp_hlen, + input_arp_plen, + input_arp_oper, + input_arp_sha, + input_arp_spa, + input_arp_tha, + input_arp_tpa, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_frame_valid=input_frame_valid, + input_frame_ready=input_frame_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_arp_htype=input_arp_htype, + input_arp_ptype=input_arp_ptype, + input_arp_hlen=input_arp_hlen, + input_arp_plen=input_arp_plen, + input_arp_oper=input_arp_oper, + input_arp_sha=input_arp_sha, + input_arp_spa=input_arp_spa, + input_arp_tha=input_arp_tha, + input_arp_tpa=input_arp_tpa, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + busy=busy) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_frame_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_arp_htype = Signal(intbv(0)[16:]) + input_arp_ptype = Signal(intbv(0)[16:]) + input_arp_hlen = Signal(intbv(0)[8:]) + input_arp_plen = Signal(intbv(0)[8:]) + input_arp_oper = Signal(intbv(0)[16:]) + input_arp_sha = Signal(intbv(0)[48:]) + input_arp_spa = Signal(intbv(0)[32:]) + input_arp_tha = Signal(intbv(0)[48:]) + input_arp_tpa = Signal(intbv(0)[32:]) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + # Outputs + input_frame_ready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = arp_ep.ARPFrameSource(clk, + rst, + frame_ready=input_frame_ready, + frame_valid=input_frame_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + arp_htype=input_arp_htype, + arp_ptype=input_arp_ptype, + arp_hlen=input_arp_hlen, + arp_plen=input_arp_plen, + arp_oper=input_arp_oper, + arp_sha=input_arp_sha, + arp_spa=input_arp_spa, + arp_tha=input_arp_tha, + arp_tpa=input_arp_tpa, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_arp_eth_tx(clk, + rst, + current_test, + + input_frame_valid, + input_frame_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_arp_htype, + input_arp_ptype, + input_arp_hlen, + input_arp_plen, + input_arp_oper, + input_arp_sha, + input_arp_spa, + input_arp_tha, + input_arp_tpa, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test packet with pauses") + current_test.next = 2 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets") + current_test.next = 3 + + test_frame1 = arp_ep.ARPFrame() + test_frame1.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0806 + test_frame1.arp_htype = 0x0001 + test_frame1.arp_ptype = 0x0800 + test_frame1.arp_hlen = 6 + test_frame1.arp_plen = 4 + test_frame1.arp_oper = 1 + test_frame1.arp_sha = 0x5A5152535455 + test_frame1.arp_spa = 0xc0a80164 + test_frame1.arp_tha = 0xDAD1D2D3D4D5 + test_frame1.arp_tpa = 0xc0a80165 + test_frame2 = arp_ep.ARPFrame() + test_frame2.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0806 + test_frame2.arp_htype = 0x0001 + test_frame2.arp_ptype = 0x0800 + test_frame2.arp_hlen = 6 + test_frame2.arp_plen = 4 + test_frame2.arp_oper = 1 + test_frame2.arp_sha = 0x5A5152535455 + test_frame2.arp_spa = 0xc0a80164 + test_frame2.arp_tha = 0xDAD1D2D3D4D5 + test_frame2.arp_tpa = 0xc0a80165 + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 4: alternate pause sink") + current_test.next = 4 + + test_frame1 = arp_ep.ARPFrame() + test_frame1.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0806 + test_frame1.arp_htype = 0x0001 + test_frame1.arp_ptype = 0x0800 + test_frame1.arp_hlen = 6 + test_frame1.arp_plen = 4 + test_frame1.arp_oper = 1 + test_frame1.arp_sha = 0x5A5152535455 + test_frame1.arp_spa = 0xc0a80164 + test_frame1.arp_tha = 0xDAD1D2D3D4D5 + test_frame1.arp_tpa = 0xc0a80165 + test_frame2 = arp_ep.ARPFrame() + test_frame2.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0806 + test_frame2.arp_htype = 0x0001 + test_frame2.arp_ptype = 0x0800 + test_frame2.arp_hlen = 6 + test_frame2.arp_plen = 4 + test_frame2.arp_oper = 1 + test_frame2.arp_sha = 0x5A5152535455 + test_frame2.arp_spa = 0xc0a80164 + test_frame2.arp_tha = 0xDAD1D2D3D4D5 + test_frame2.arp_tpa = 0xc0a80165 + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while output_eth_payload_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() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: bad header") + current_test.next = 7 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + #assert frame_error + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_arp_eth_tx.v b/tb/test_arp_eth_tx.v new file mode 100644 index 000000000..fdae80a01 --- /dev/null +++ b/tb/test_arp_eth_tx.v @@ -0,0 +1,134 @@ +/* + +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_arp_eth_tx; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_frame_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [15:0] input_arp_htype = 0; +reg [15:0] input_arp_ptype = 0; +reg [7:0] input_arp_hlen = 0; +reg [7:0] input_arp_plen = 0; +reg [15:0] input_arp_oper = 0; +reg [47:0] input_arp_sha = 0; +reg [31:0] input_arp_spa = 0; +reg [47:0] input_arp_tha = 0; +reg [31:0] input_arp_tpa = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +// Outputs +wire input_frame_ready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [7:0] output_eth_payload_tdata; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire busy; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_frame_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_arp_htype, + input_arp_ptype, + input_arp_hlen, + input_arp_plen, + input_arp_oper, + input_arp_sha, + input_arp_spa, + input_arp_tha, + input_arp_tpa, + output_eth_hdr_ready, + output_eth_payload_tready); + $to_myhdl(input_frame_ready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + busy); + + // dump file + $dumpfile("test_arp_eth_tx.lxt"); + $dumpvars(0, test_arp_eth_tx); +end + +arp_eth_tx +UUT ( + .clk(clk), + .rst(rst), + // ARP frame input + .input_frame_valid(input_frame_valid), + .input_frame_ready(input_frame_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_arp_htype(input_arp_htype), + .input_arp_ptype(input_arp_ptype), + .input_arp_hlen(input_arp_hlen), + .input_arp_plen(input_arp_plen), + .input_arp_oper(input_arp_oper), + .input_arp_sha(input_arp_sha), + .input_arp_spa(input_arp_spa), + .input_arp_tha(input_arp_tha), + .input_arp_tpa(input_arp_tpa), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Status signals + .busy(busy) +); + +endmodule diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py new file mode 100755 index 000000000..67649480b --- /dev/null +++ b/tb/test_arp_eth_tx_64.py @@ -0,0 +1,477 @@ +#!/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 eth_ep +import arp_ep + +module = 'arp_eth_tx_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_arp_eth_tx_64(clk, + rst, + current_test, + + input_frame_valid, + input_frame_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_arp_htype, + input_arp_ptype, + input_arp_hlen, + input_arp_plen, + input_arp_oper, + input_arp_sha, + input_arp_spa, + input_arp_tha, + input_arp_tpa, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_frame_valid=input_frame_valid, + input_frame_ready=input_frame_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_arp_htype=input_arp_htype, + input_arp_ptype=input_arp_ptype, + input_arp_hlen=input_arp_hlen, + input_arp_plen=input_arp_plen, + input_arp_oper=input_arp_oper, + input_arp_sha=input_arp_sha, + input_arp_spa=input_arp_spa, + input_arp_tha=input_arp_tha, + input_arp_tpa=input_arp_tpa, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + busy=busy) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_frame_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_arp_htype = Signal(intbv(0)[16:]) + input_arp_ptype = Signal(intbv(0)[16:]) + input_arp_hlen = Signal(intbv(0)[8:]) + input_arp_plen = Signal(intbv(0)[8:]) + input_arp_oper = Signal(intbv(0)[16:]) + input_arp_sha = Signal(intbv(0)[48:]) + input_arp_spa = Signal(intbv(0)[32:]) + input_arp_tha = Signal(intbv(0)[48:]) + input_arp_tpa = Signal(intbv(0)[32:]) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + # Outputs + input_frame_ready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[64:]) + output_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = arp_ep.ARPFrameSource(clk, + rst, + frame_ready=input_frame_ready, + frame_valid=input_frame_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + arp_htype=input_arp_htype, + arp_ptype=input_arp_ptype, + arp_hlen=input_arp_hlen, + arp_plen=input_arp_plen, + arp_oper=input_arp_oper, + arp_sha=input_arp_sha, + arp_spa=input_arp_spa, + arp_tha=input_arp_tha, + arp_tpa=input_arp_tpa, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_arp_eth_tx_64(clk, + rst, + current_test, + + input_frame_valid, + input_frame_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_arp_htype, + input_arp_ptype, + input_arp_hlen, + input_arp_plen, + input_arp_oper, + input_arp_sha, + input_arp_spa, + input_arp_tha, + input_arp_tpa, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test packet with pauses") + current_test.next = 2 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame) + yield clk.posedge + + yield delay(16) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets") + current_test.next = 3 + + test_frame1 = arp_ep.ARPFrame() + test_frame1.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0806 + test_frame1.arp_htype = 0x0001 + test_frame1.arp_ptype = 0x0800 + test_frame1.arp_hlen = 6 + test_frame1.arp_plen = 4 + test_frame1.arp_oper = 1 + test_frame1.arp_sha = 0x5A5152535455 + test_frame1.arp_spa = 0xc0a80164 + test_frame1.arp_tha = 0xDAD1D2D3D4D5 + test_frame1.arp_tpa = 0xc0a80165 + test_frame2 = arp_ep.ARPFrame() + test_frame2.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0806 + test_frame2.arp_htype = 0x0001 + test_frame2.arp_ptype = 0x0800 + test_frame2.arp_hlen = 6 + test_frame2.arp_plen = 4 + test_frame2.arp_oper = 1 + test_frame2.arp_sha = 0x5A5152535455 + test_frame2.arp_spa = 0xc0a80164 + test_frame2.arp_tha = 0xDAD1D2D3D4D5 + test_frame2.arp_tpa = 0xc0a80165 + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 4: alternate pause sink") + current_test.next = 4 + + test_frame1 = arp_ep.ARPFrame() + test_frame1.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0806 + test_frame1.arp_htype = 0x0001 + test_frame1.arp_ptype = 0x0800 + test_frame1.arp_hlen = 6 + test_frame1.arp_plen = 4 + test_frame1.arp_oper = 1 + test_frame1.arp_sha = 0x5A5152535455 + test_frame1.arp_spa = 0xc0a80164 + test_frame1.arp_tha = 0xDAD1D2D3D4D5 + test_frame1.arp_tpa = 0xc0a80165 + test_frame2 = arp_ep.ARPFrame() + test_frame2.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0806 + test_frame2.arp_htype = 0x0001 + test_frame2.arp_ptype = 0x0800 + test_frame2.arp_hlen = 6 + test_frame2.arp_plen = 4 + test_frame2.arp_oper = 1 + test_frame2.arp_sha = 0x5A5152535455 + test_frame2.arp_spa = 0xc0a80164 + test_frame2.arp_tha = 0xDAD1D2D3D4D5 + test_frame2.arp_tpa = 0xc0a80165 + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while output_eth_payload_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() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: bad header") + current_test.next = 7 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + #assert frame_error + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_arp_eth_tx_64.v b/tb/test_arp_eth_tx_64.v new file mode 100644 index 000000000..a9aed7821 --- /dev/null +++ b/tb/test_arp_eth_tx_64.v @@ -0,0 +1,137 @@ +/* + +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_arp_eth_tx_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_frame_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [15:0] input_arp_htype = 0; +reg [15:0] input_arp_ptype = 0; +reg [7:0] input_arp_hlen = 0; +reg [7:0] input_arp_plen = 0; +reg [15:0] input_arp_oper = 0; +reg [47:0] input_arp_sha = 0; +reg [31:0] input_arp_spa = 0; +reg [47:0] input_arp_tha = 0; +reg [31:0] input_arp_tpa = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +// Outputs +wire input_frame_ready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [63:0] output_eth_payload_tdata; +wire [7:0] output_eth_payload_tkeep; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire busy; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_frame_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_arp_htype, + input_arp_ptype, + input_arp_hlen, + input_arp_plen, + input_arp_oper, + input_arp_sha, + input_arp_spa, + input_arp_tha, + input_arp_tpa, + output_eth_hdr_ready, + output_eth_payload_tready); + $to_myhdl(input_frame_ready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + busy); + + // dump file + $dumpfile("test_arp_eth_tx_64.lxt"); + $dumpvars(0, test_arp_eth_tx_64); +end + +arp_eth_tx_64 +UUT ( + .clk(clk), + .rst(rst), + // ARP frame input + .input_frame_valid(input_frame_valid), + .input_frame_ready(input_frame_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_arp_htype(input_arp_htype), + .input_arp_ptype(input_arp_ptype), + .input_arp_hlen(input_arp_hlen), + .input_arp_plen(input_arp_plen), + .input_arp_oper(input_arp_oper), + .input_arp_sha(input_arp_sha), + .input_arp_spa(input_arp_spa), + .input_arp_tha(input_arp_tha), + .input_arp_tpa(input_arp_tpa), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Status signals + .busy(busy) +); + +endmodule From 85d11645eb5af7f9dcba37417b121315ca18e4d7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 15 Sep 2014 19:08:01 -0700 Subject: [PATCH 011/617] Rename frame_error to error_header_early_termination --- rtl/arp_eth_rx.v | 14 +++++++------- rtl/arp_eth_rx_64.v | 14 +++++++------- rtl/eth_axis_rx.v | 14 +++++++------- rtl/eth_axis_rx_64.v | 14 +++++++------- tb/test_arp_eth_rx.py | 12 ++++++------ tb/test_arp_eth_rx.v | 6 +++--- tb/test_arp_eth_rx_64.py | 12 ++++++------ tb/test_arp_eth_rx_64.v | 6 +++--- tb/test_eth_axis_rx.py | 10 +++++----- tb/test_eth_axis_rx.v | 6 +++--- tb/test_eth_axis_rx_64.py | 10 +++++----- tb/test_eth_axis_rx_64.v | 6 +++--- 12 files changed, 62 insertions(+), 62 deletions(-) diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index 38724e6f5..054e13990 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -70,7 +70,7 @@ module arp_eth_rx * Status signals */ output wire busy, - output wire frame_error + output wire error_header_early_termination ); /* @@ -155,7 +155,7 @@ reg [47:0] output_arp_tha_reg = 0; reg [31:0] output_arp_tpa_reg = 0; reg busy_reg = 0; -reg frame_error_reg = 0, frame_error_next; +reg error_header_early_termination_reg = 0, error_header_early_termination_next; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; @@ -175,7 +175,7 @@ assign output_arp_tha = output_arp_tha_reg; assign output_arp_tpa = output_arp_tpa_reg; assign busy = busy_reg; -assign frame_error = frame_error_reg; +assign error_header_early_termination = error_header_early_termination_reg; always @* begin state_next = 2'bz; @@ -214,7 +214,7 @@ always @* begin output_frame_valid_next = output_frame_valid_reg & ~output_frame_ready; - frame_error_next = 0; + error_header_early_termination_next = 0; case (state_reg) STATE_IDLE: begin @@ -272,7 +272,7 @@ always @* begin if (input_eth_payload_tlast) begin state_next = STATE_IDLE; if (frame_ptr_reg != 8'h1B) begin - frame_error_next = 1; + error_header_early_termination_next = 1; end end end else begin @@ -306,7 +306,7 @@ always @(posedge clk or posedge rst) begin output_eth_src_mac_reg <= 0; output_eth_type_reg <= 0; busy_reg <= 0; - frame_error_reg <= 0; + error_header_early_termination_reg <= 0; end else begin state_reg <= state_next; @@ -314,7 +314,7 @@ always @(posedge clk or posedge rst) begin output_frame_valid_reg <= output_frame_valid_next; - frame_error_reg <= frame_error_next; + error_header_early_termination_reg <= error_header_early_termination_next; busy_reg <= state_next != STATE_IDLE; diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index cfb1730c9..0a923c4eb 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -71,7 +71,7 @@ module arp_eth_rx_64 * Status signals */ output wire busy, - output wire frame_error + output wire error_header_early_termination ); /* @@ -132,7 +132,7 @@ reg [47:0] output_arp_tha_reg = 0; reg [31:0] output_arp_tpa_reg = 0; reg busy_reg = 0; -reg frame_error_reg = 0, frame_error_next; +reg error_header_early_termination_reg = 0, error_header_early_termination_next; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; @@ -152,7 +152,7 @@ assign output_arp_tha = output_arp_tha_reg; assign output_arp_tpa = output_arp_tpa_reg; assign busy = busy_reg; -assign frame_error = frame_error_reg; +assign error_header_early_termination = error_header_early_termination_reg; always @* begin state_next = 2'bz; @@ -167,7 +167,7 @@ always @* begin output_frame_valid_next = output_frame_valid_reg & ~output_frame_ready; - frame_error_next = 0; + error_header_early_termination_next = 0; case (state_reg) STATE_IDLE: begin @@ -201,7 +201,7 @@ always @* begin if (input_eth_payload_tlast) begin state_next = STATE_IDLE; if (frame_ptr_reg != 8'h03 | (input_eth_payload_tkeep & 8'h0F) != 8'h0F) begin - frame_error_next = 1; + error_header_early_termination_next = 1; end end end else begin @@ -235,7 +235,7 @@ always @(posedge clk or posedge rst) begin output_eth_src_mac_reg <= 0; output_eth_type_reg <= 0; busy_reg <= 0; - frame_error_reg <= 0; + error_header_early_termination_reg <= 0; end else begin state_reg <= state_next; @@ -243,7 +243,7 @@ always @(posedge clk or posedge rst) begin output_frame_valid_reg <= output_frame_valid_next; - frame_error_reg <= frame_error_next; + error_header_early_termination_reg <= error_header_early_termination_next; busy_reg <= state_next != STATE_IDLE; diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index 259eae7ec..30617a865 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -61,7 +61,7 @@ module eth_axis_rx * Status signals */ output wire busy, - output wire frame_error + output wire error_header_early_termination ); /* @@ -123,7 +123,7 @@ reg output_eth_payload_tlast_reg = 0; reg output_eth_payload_tuser_reg = 0; reg busy_reg = 0, busy_next; -reg frame_error_reg = 0, frame_error_next; +reg error_header_early_termination_reg = 0, error_header_early_termination_next; reg [7:0] temp_eth_payload_tdata_reg = 0; reg temp_eth_payload_tlast_reg = 0; @@ -141,7 +141,7 @@ assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; assign busy = busy_reg; -assign frame_error = frame_error_reg; +assign error_header_early_termination = error_header_early_termination_reg; always @* begin state_next = 2'bz; @@ -169,7 +169,7 @@ always @* begin output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - frame_error_next = 0; + error_header_early_termination_next = 0; case (state_reg) STATE_IDLE: begin @@ -212,7 +212,7 @@ always @* begin endcase if (input_axis_tlast) begin state_next = STATE_IDLE; - frame_error_next = 1; + error_header_early_termination_next = 1; end end else begin state_next = STATE_READ_HEADER; @@ -296,7 +296,7 @@ always @(posedge clk or posedge rst) begin temp_eth_payload_tlast_reg <= 0; temp_eth_payload_tuser_reg <= 0; busy_reg <= 0; - frame_error_reg <= 0; + error_header_early_termination_reg <= 0; end else begin state_reg <= state_next; @@ -304,7 +304,7 @@ always @(posedge clk or posedge rst) begin output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - frame_error_reg <= frame_error_next; + error_header_early_termination_reg <= error_header_early_termination_next; busy_reg <= state_next != STATE_IDLE; diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index 464d9e65b..fbaecd882 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -63,7 +63,7 @@ module eth_axis_rx_64 * Status signals */ output wire busy, - output wire frame_error + output wire error_header_early_termination ); /* @@ -116,7 +116,7 @@ reg output_eth_payload_tlast_reg = 0; reg output_eth_payload_tuser_reg = 0; reg busy_reg = 0, busy_next; -reg frame_error_reg = 0, frame_error_next; +reg error_header_early_termination_reg = 0, error_header_early_termination_next; reg [63:0] temp_eth_payload_tdata_reg = 0; reg [7:0] temp_eth_payload_tkeep_reg = 0; @@ -141,7 +141,7 @@ assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; assign busy = busy_reg; -assign frame_error = frame_error_reg; +assign error_header_early_termination = error_header_early_termination_reg; always @* begin state_next = 2'bz; @@ -159,7 +159,7 @@ always @* begin output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - frame_error_next = 0; + error_header_early_termination_next = 0; case (state_reg) STATE_IDLE: begin @@ -192,7 +192,7 @@ always @* begin endcase if (input_axis_tlast) begin state_next = STATE_IDLE; - frame_error_next = 1; + error_header_early_termination_next = 1; end end else begin state_next = STATE_READ_HEADER; @@ -286,7 +286,7 @@ always @(posedge clk or posedge rst) begin temp_eth_payload_tlast_reg <= 0; temp_eth_payload_tuser_reg <= 0; busy_reg <= 0; - frame_error_reg <= 0; + error_header_early_termination_reg <= 0; end else begin state_reg <= state_next; @@ -294,7 +294,7 @@ always @(posedge clk or posedge rst) begin output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - frame_error_reg <= frame_error_next; + error_header_early_termination_reg <= error_header_early_termination_next; busy_reg <= state_next != STATE_IDLE; diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index bbe36d579..ae132815f 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -72,7 +72,7 @@ def dut_arp_eth_rx(clk, output_arp_tpa, busy, - frame_error): + error_header_early_termination): if os.system(build_cmd): raise Exception("Error running build command") @@ -108,7 +108,7 @@ def dut_arp_eth_rx(clk, output_arp_tpa=output_arp_tpa, busy=busy, - frame_error=frame_error) + error_header_early_termination=error_header_early_termination) def bench(): @@ -144,7 +144,7 @@ def bench(): output_arp_tha = Signal(intbv(0)[48:]) output_arp_tpa = Signal(intbv(0)[32:]) busy = Signal(bool(0)) - frame_error = Signal(bool(0)) + error_header_early_termination = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -220,7 +220,7 @@ def bench(): output_arp_tpa, busy, - frame_error) + error_header_early_termination) @always(delay(4)) def clkgen(): @@ -550,7 +550,7 @@ def bench(): yield input_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - assert frame_error + assert error_header_early_termination yield delay(100) @@ -577,7 +577,7 @@ def bench(): yield input_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - #assert frame_error + #assert error_header_early_termination yield delay(100) diff --git a/tb/test_arp_eth_rx.v b/tb/test_arp_eth_rx.v index 52c77cba2..0c1cab7a4 100644 --- a/tb/test_arp_eth_rx.v +++ b/tb/test_arp_eth_rx.v @@ -60,7 +60,7 @@ wire [31:0] output_arp_spa; wire [47:0] output_arp_tha; wire [31:0] output_arp_tpa; wire busy; -wire frame_error; +wire error_header_early_termination; initial begin // myhdl integration @@ -92,7 +92,7 @@ initial begin output_arp_tha, output_arp_tpa, busy, - frame_error); + error_header_early_termination); // dump file $dumpfile("test_arp_eth_rx.lxt"); @@ -131,7 +131,7 @@ UUT ( .output_arp_tpa(output_arp_tpa), // Status signals .busy(busy), - .frame_error(frame_error) + .error_header_early_termination(error_header_early_termination) ); endmodule diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index 899bbcf47..e3109318d 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -73,7 +73,7 @@ def dut_arp_eth_rx_64(clk, output_arp_tpa, busy, - frame_error): + error_header_early_termination): if os.system(build_cmd): raise Exception("Error running build command") @@ -110,7 +110,7 @@ def dut_arp_eth_rx_64(clk, output_arp_tpa=output_arp_tpa, busy=busy, - frame_error=frame_error) + error_header_early_termination=error_header_early_termination) def bench(): @@ -147,7 +147,7 @@ def bench(): output_arp_tha = Signal(intbv(0)[48:]) output_arp_tpa = Signal(intbv(0)[32:]) busy = Signal(bool(0)) - frame_error = Signal(bool(0)) + error_header_early_termination = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -225,7 +225,7 @@ def bench(): output_arp_tpa, busy, - frame_error) + error_header_early_termination) @always(delay(4)) def clkgen(): @@ -555,7 +555,7 @@ def bench(): yield input_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - assert frame_error + assert error_header_early_termination yield delay(100) @@ -582,7 +582,7 @@ def bench(): yield input_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - #assert frame_error + #assert error_header_early_termination yield delay(100) diff --git a/tb/test_arp_eth_rx_64.v b/tb/test_arp_eth_rx_64.v index 9f9e42dba..567a6903b 100644 --- a/tb/test_arp_eth_rx_64.v +++ b/tb/test_arp_eth_rx_64.v @@ -61,7 +61,7 @@ wire [31:0] output_arp_spa; wire [47:0] output_arp_tha; wire [31:0] output_arp_tpa; wire busy; -wire frame_error; +wire error_header_early_termination; initial begin // myhdl integration @@ -94,7 +94,7 @@ initial begin output_arp_tha, output_arp_tpa, busy, - frame_error); + error_header_early_termination); // dump file $dumpfile("test_arp_eth_rx_64.lxt"); @@ -134,7 +134,7 @@ UUT ( .output_arp_tpa(output_arp_tpa), // Status signals .busy(busy), - .frame_error(frame_error) + .error_header_early_termination(error_header_early_termination) ); endmodule diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index e7d4e0dfe..9bfbb298e 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -63,7 +63,7 @@ def dut_eth_axis_rx(clk, output_eth_payload_tuser, busy, - frame_error): + error_header_early_termination): if os.system(build_cmd): raise Exception("Error running build command") @@ -90,7 +90,7 @@ def dut_eth_axis_rx(clk, output_eth_payload_tuser=output_eth_payload_tuser, busy=busy, - frame_error=frame_error) + error_header_early_termination=error_header_early_termination) def bench(): @@ -117,7 +117,7 @@ def bench(): output_eth_payload_tlast = Signal(bool(0)) output_eth_payload_tuser = Signal(bool(0)) busy = Signal(bool(0)) - frame_error = Signal(bool(0)) + error_header_early_termination = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -175,7 +175,7 @@ def bench(): output_eth_payload_tuser, busy, - frame_error) + error_header_early_termination) @always(delay(4)) def clkgen(): @@ -529,7 +529,7 @@ def bench(): yield clk.posedge yield clk.posedge - assert frame_error + assert error_header_early_termination yield delay(100) diff --git a/tb/test_eth_axis_rx.v b/tb/test_eth_axis_rx.v index 6a7e98b92..9ad88025f 100644 --- a/tb/test_eth_axis_rx.v +++ b/tb/test_eth_axis_rx.v @@ -51,7 +51,7 @@ wire output_eth_payload_tvalid; wire output_eth_payload_tlast; wire output_eth_payload_tuser; wire busy; -wire frame_error; +wire error_header_early_termination; initial begin // myhdl integration @@ -74,7 +74,7 @@ initial begin output_eth_payload_tlast, output_eth_payload_tuser, busy, - frame_error); + error_header_early_termination); // dump file $dumpfile("test_eth_axis_rx.lxt"); @@ -104,7 +104,7 @@ UUT ( .output_eth_payload_tuser(output_eth_payload_tuser), // Status signals .busy(busy), - .frame_error(frame_error) + .error_header_early_termination(error_header_early_termination) ); endmodule diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index ea5818084..4e4c4f875 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -65,7 +65,7 @@ def dut_eth_axis_rx_64(clk, output_eth_payload_tuser, busy, - frame_error): + error_header_early_termination): if os.system(build_cmd): raise Exception("Error running build command") @@ -94,7 +94,7 @@ def dut_eth_axis_rx_64(clk, output_eth_payload_tuser=output_eth_payload_tuser, busy=busy, - frame_error=frame_error) + error_header_early_termination=error_header_early_termination) def bench(): @@ -123,7 +123,7 @@ def bench(): output_eth_payload_tlast = Signal(bool(0)) output_eth_payload_tuser = Signal(bool(0)) busy = Signal(bool(0)) - frame_error = Signal(bool(0)) + error_header_early_termination = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -185,7 +185,7 @@ def bench(): output_eth_payload_tuser, busy, - frame_error) + error_header_early_termination) @always(delay(4)) def clkgen(): @@ -539,7 +539,7 @@ def bench(): yield clk.posedge yield clk.posedge - assert frame_error + assert error_header_early_termination yield delay(100) diff --git a/tb/test_eth_axis_rx_64.v b/tb/test_eth_axis_rx_64.v index 4dc523c2c..ae3b4c7bd 100644 --- a/tb/test_eth_axis_rx_64.v +++ b/tb/test_eth_axis_rx_64.v @@ -53,7 +53,7 @@ wire output_eth_payload_tvalid; wire output_eth_payload_tlast; wire output_eth_payload_tuser; wire busy; -wire frame_error; +wire error_header_early_termination; initial begin // myhdl integration @@ -78,7 +78,7 @@ initial begin output_eth_payload_tlast, output_eth_payload_tuser, busy, - frame_error); + error_header_early_termination); // dump file $dumpfile("test_eth_axis_rx_64.lxt"); @@ -110,7 +110,7 @@ UUT ( .output_eth_payload_tuser(output_eth_payload_tuser), // Status signals .busy(busy), - .frame_error(frame_error) + .error_header_early_termination(error_header_early_termination) ); endmodule From 33c044e03514f9adeb82924629ff08e234c8ac2e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 15 Sep 2014 19:31:10 -0700 Subject: [PATCH 012/617] Add invalid header and tuser assert checks and tests --- rtl/arp_eth_rx.v | 18 +++++++++++++-- rtl/arp_eth_rx_64.v | 18 +++++++++++++-- tb/test_arp_eth_rx.py | 47 ++++++++++++++++++++++++++++++++++------ tb/test_arp_eth_rx.v | 7 ++++-- tb/test_arp_eth_rx_64.py | 47 ++++++++++++++++++++++++++++++++++------ tb/test_arp_eth_rx_64.v | 7 ++++-- tb/test_arp_eth_tx.py | 27 ----------------------- tb/test_arp_eth_tx_64.py | 27 ----------------------- 8 files changed, 122 insertions(+), 76 deletions(-) diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index 054e13990..a42f61aa4 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -70,7 +70,8 @@ module arp_eth_rx * Status signals */ output wire busy, - output wire error_header_early_termination + output wire error_header_early_termination, + output wire error_invalid_header ); /* @@ -156,6 +157,7 @@ reg [31:0] output_arp_tpa_reg = 0; reg busy_reg = 0; reg error_header_early_termination_reg = 0, error_header_early_termination_next; +reg error_invalid_header_reg = 0, error_invalid_header_next; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; @@ -176,6 +178,7 @@ assign output_arp_tpa = output_arp_tpa_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; +assign error_invalid_header = error_invalid_header_reg; always @* begin state_next = 2'bz; @@ -215,6 +218,7 @@ always @* begin output_frame_valid_next = output_frame_valid_reg & ~output_frame_ready; error_header_early_termination_next = 0; + error_invalid_header_next = 0; case (state_reg) STATE_IDLE: begin @@ -265,7 +269,6 @@ always @* begin 8'h1A: store_arp_tpa_1 = 1; 8'h1B: begin store_arp_tpa_0 = 1; - output_frame_valid_next = 1; state_next = STATE_WAIT_LAST; end endcase @@ -273,6 +276,10 @@ always @* begin state_next = STATE_IDLE; if (frame_ptr_reg != 8'h1B) begin error_header_early_termination_next = 1; + end else if (output_arp_hlen != 6 || output_arp_plen != 4) begin + error_invalid_header_next = 1; + end else begin + output_frame_valid_next = ~input_eth_payload_tuser; end end end else begin @@ -284,6 +291,11 @@ always @* begin if (input_eth_payload_tvalid) begin // word transfer out - done if (input_eth_payload_tlast) begin + if (output_arp_hlen != 6 || output_arp_plen != 4) begin + error_invalid_header_next = 1; + end else begin + output_frame_valid_next = ~input_eth_payload_tuser; + end state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -307,6 +319,7 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg <= 0; busy_reg <= 0; error_header_early_termination_reg <= 0; + error_invalid_header_reg <= 0; end else begin state_reg <= state_next; @@ -315,6 +328,7 @@ always @(posedge clk or posedge rst) begin output_frame_valid_reg <= output_frame_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; + error_invalid_header_reg <= error_invalid_header_next; busy_reg <= state_next != STATE_IDLE; diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index 0a923c4eb..387ebec62 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -71,7 +71,8 @@ module arp_eth_rx_64 * Status signals */ output wire busy, - output wire error_header_early_termination + output wire error_header_early_termination, + output wire error_invalid_header ); /* @@ -133,6 +134,7 @@ reg [31:0] output_arp_tpa_reg = 0; reg busy_reg = 0; reg error_header_early_termination_reg = 0, error_header_early_termination_next; +reg error_invalid_header_reg = 0, error_invalid_header_next; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; @@ -153,6 +155,7 @@ assign output_arp_tpa = output_arp_tpa_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; +assign error_invalid_header = error_invalid_header_reg; always @* begin state_next = 2'bz; @@ -168,6 +171,7 @@ always @* begin output_frame_valid_next = output_frame_valid_reg & ~output_frame_ready; error_header_early_termination_next = 0; + error_invalid_header_next = 0; case (state_reg) STATE_IDLE: begin @@ -194,7 +198,6 @@ always @* begin 8'h02: store_arp_hdr_word_2 = 1; 8'h03: begin store_arp_hdr_word_3 = 1; - output_frame_valid_next = 1; state_next = STATE_WAIT_LAST; end endcase @@ -202,6 +205,10 @@ always @* begin state_next = STATE_IDLE; if (frame_ptr_reg != 8'h03 | (input_eth_payload_tkeep & 8'h0F) != 8'h0F) begin error_header_early_termination_next = 1; + end else if (output_arp_hlen != 6 || output_arp_plen != 4) begin + error_invalid_header_next = 1; + end else begin + output_frame_valid_next = ~input_eth_payload_tuser; end end end else begin @@ -213,6 +220,11 @@ always @* begin if (input_eth_payload_tvalid) begin // word transfer out - done if (input_eth_payload_tlast) begin + if (output_arp_hlen != 6 || output_arp_plen != 4) begin + error_invalid_header_next = 1; + end else begin + output_frame_valid_next = ~input_eth_payload_tuser; + end state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -236,6 +248,7 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg <= 0; busy_reg <= 0; error_header_early_termination_reg <= 0; + error_invalid_header_reg <= 0; end else begin state_reg <= state_next; @@ -244,6 +257,7 @@ always @(posedge clk or posedge rst) begin output_frame_valid_reg <= output_frame_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; + error_invalid_header_reg <= error_invalid_header_next; busy_reg <= state_next != STATE_IDLE; diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index ae132815f..ff7483098 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -72,7 +72,8 @@ def dut_arp_eth_rx(clk, output_arp_tpa, busy, - error_header_early_termination): + error_header_early_termination, + error_invalid_header): if os.system(build_cmd): raise Exception("Error running build command") @@ -108,7 +109,8 @@ def dut_arp_eth_rx(clk, output_arp_tpa=output_arp_tpa, busy=busy, - error_header_early_termination=error_header_early_termination) + error_header_early_termination=error_header_early_termination, + error_invalid_header=error_invalid_header) def bench(): @@ -145,6 +147,7 @@ def bench(): output_arp_tpa = Signal(intbv(0)[32:]) busy = Signal(bool(0)) error_header_early_termination = Signal(bool(0)) + error_invalid_header = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -220,7 +223,8 @@ def bench(): output_arp_tpa, busy, - error_header_early_termination) + error_header_early_termination, + error_invalid_header) @always(delay(4)) def clkgen(): @@ -555,8 +559,35 @@ def bench(): yield delay(100) yield clk.posedge - print("test 7: bad header") - current_test.next = 7 + print("test 8: bad header") + current_test.next = 8 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 0 + test_frame.arp_plen = 0 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield input_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + assert error_invalid_header + + yield delay(100) + + yield clk.posedge + print("test 9: assert tuser") + current_test.next = 9 test_frame = arp_ep.ARPFrame() test_frame.eth_dest_mac = 0xFFFFFFFFFFFF @@ -571,13 +602,15 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + eth_frame = test_frame.build_eth() + eth_frame.payload.user = 1 + source_queue.put(eth_frame) yield clk.posedge yield input_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - #assert error_header_early_termination + assert sink_queue.empty() yield delay(100) diff --git a/tb/test_arp_eth_rx.v b/tb/test_arp_eth_rx.v index 0c1cab7a4..1b6f2b6fb 100644 --- a/tb/test_arp_eth_rx.v +++ b/tb/test_arp_eth_rx.v @@ -61,6 +61,7 @@ wire [47:0] output_arp_tha; wire [31:0] output_arp_tpa; wire busy; wire error_header_early_termination; +wire error_invalid_header; initial begin // myhdl integration @@ -92,7 +93,8 @@ initial begin output_arp_tha, output_arp_tpa, busy, - error_header_early_termination); + error_header_early_termination, + error_invalid_header); // dump file $dumpfile("test_arp_eth_rx.lxt"); @@ -131,7 +133,8 @@ UUT ( .output_arp_tpa(output_arp_tpa), // Status signals .busy(busy), - .error_header_early_termination(error_header_early_termination) + .error_header_early_termination(error_header_early_termination), + .error_invalid_header(error_invalid_header) ); endmodule diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index e3109318d..23b01cbad 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -73,7 +73,8 @@ def dut_arp_eth_rx_64(clk, output_arp_tpa, busy, - error_header_early_termination): + error_header_early_termination, + error_invalid_header): if os.system(build_cmd): raise Exception("Error running build command") @@ -110,7 +111,8 @@ def dut_arp_eth_rx_64(clk, output_arp_tpa=output_arp_tpa, busy=busy, - error_header_early_termination=error_header_early_termination) + error_header_early_termination=error_header_early_termination, + error_invalid_header=error_invalid_header) def bench(): @@ -148,6 +150,7 @@ def bench(): output_arp_tpa = Signal(intbv(0)[32:]) busy = Signal(bool(0)) error_header_early_termination = Signal(bool(0)) + error_invalid_header = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -225,7 +228,8 @@ def bench(): output_arp_tpa, busy, - error_header_early_termination) + error_header_early_termination, + error_invalid_header) @always(delay(4)) def clkgen(): @@ -560,8 +564,35 @@ def bench(): yield delay(100) yield clk.posedge - print("test 7: bad header") - current_test.next = 7 + print("test 8: bad header") + current_test.next = 8 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 0 + test_frame.arp_plen = 0 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield input_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + assert error_invalid_header + + yield delay(100) + + yield clk.posedge + print("test 9: assert tuser") + current_test.next = 9 test_frame = arp_ep.ARPFrame() test_frame.eth_dest_mac = 0xFFFFFFFFFFFF @@ -576,13 +607,15 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + eth_frame = test_frame.build_eth() + eth_frame.payload.user = 1 + source_queue.put(eth_frame) yield clk.posedge yield input_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - #assert error_header_early_termination + assert sink_queue.empty() yield delay(100) diff --git a/tb/test_arp_eth_rx_64.v b/tb/test_arp_eth_rx_64.v index 567a6903b..8373bec66 100644 --- a/tb/test_arp_eth_rx_64.v +++ b/tb/test_arp_eth_rx_64.v @@ -62,6 +62,7 @@ wire [47:0] output_arp_tha; wire [31:0] output_arp_tpa; wire busy; wire error_header_early_termination; +wire error_invalid_header; initial begin // myhdl integration @@ -94,7 +95,8 @@ initial begin output_arp_tha, output_arp_tpa, busy, - error_header_early_termination); + error_header_early_termination, + error_invalid_header); // dump file $dumpfile("test_arp_eth_rx_64.lxt"); @@ -134,7 +136,8 @@ UUT ( .output_arp_tpa(output_arp_tpa), // Status signals .busy(busy), - .error_header_early_termination(error_header_early_termination) + .error_header_early_termination(error_header_early_termination), + .error_invalid_header(error_invalid_header) ); endmodule diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py index 30b9ba118..6fea2a81a 100755 --- a/tb/test_arp_eth_tx.py +++ b/tb/test_arp_eth_tx.py @@ -431,33 +431,6 @@ def bench(): yield delay(100) - yield clk.posedge - print("test 7: bad header") - current_test.next = 7 - - test_frame = arp_ep.ARPFrame() - test_frame.eth_dest_mac = 0xFFFFFFFFFFFF - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0806 - test_frame.arp_htype = 0x0001 - test_frame.arp_ptype = 0x0800 - test_frame.arp_hlen = 6 - test_frame.arp_plen = 4 - test_frame.arp_oper = 1 - test_frame.arp_sha = 0x5A5152535455 - test_frame.arp_spa = 0xc0a80164 - test_frame.arp_tha = 0xDAD1D2D3D4D5 - test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - #assert frame_error - - yield delay(100) - raise StopSimulation return dut, source, sink, clkgen, check diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py index 67649480b..1e5b4c466 100755 --- a/tb/test_arp_eth_tx_64.py +++ b/tb/test_arp_eth_tx_64.py @@ -436,33 +436,6 @@ def bench(): yield delay(100) - yield clk.posedge - print("test 7: bad header") - current_test.next = 7 - - test_frame = arp_ep.ARPFrame() - test_frame.eth_dest_mac = 0xFFFFFFFFFFFF - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0806 - test_frame.arp_htype = 0x0001 - test_frame.arp_ptype = 0x0800 - test_frame.arp_hlen = 6 - test_frame.arp_plen = 4 - test_frame.arp_oper = 1 - test_frame.arp_sha = 0x5A5152535455 - test_frame.arp_spa = 0xc0a80164 - test_frame.arp_tha = 0xDAD1D2D3D4D5 - test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - #assert frame_error - - yield delay(100) - raise StopSimulation return dut, source, sink, clkgen, check From fdb31878e9c0addd34106dcd0aad11d5b6d96b66 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 17 Sep 2014 12:36:56 -0700 Subject: [PATCH 013/617] Remove length fields from ARP transmit module --- rtl/arp_eth_tx.v | 12 ++---------- rtl/arp_eth_tx_64.v | 12 ++---------- tb/arp_ep.py | 4 ++-- tb/test_arp_eth_tx.py | 10 ---------- tb/test_arp_eth_tx.v | 6 ------ tb/test_arp_eth_tx_64.py | 10 ---------- tb/test_arp_eth_tx_64.v | 6 ------ 7 files changed, 6 insertions(+), 54 deletions(-) diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index fbac1e3f9..de97cc231 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -44,8 +44,6 @@ module arp_eth_tx input wire [15:0] input_eth_type, input wire [15:0] input_arp_htype, input wire [15:0] input_arp_ptype, - input wire [7:0] input_arp_hlen, - input wire [7:0] input_arp_plen, input wire [15:0] input_arp_oper, input wire [47:0] input_arp_sha, input wire [31:0] input_arp_spa, @@ -117,8 +115,6 @@ reg [47:0] output_eth_src_mac_reg = 0; reg [15:0] output_eth_type_reg = 0; reg [15:0] arp_htype_reg = 0; reg [15:0] arp_ptype_reg = 0; -reg [7:0] arp_hlen_reg = 0; -reg [7:0] arp_plen_reg = 0; reg [15:0] arp_oper_reg = 0; reg [47:0] arp_sha_reg = 0; reg [31:0] arp_spa_reg = 0; @@ -188,8 +184,8 @@ always @* begin 8'h01: write_hdr_data = arp_htype_reg[ 7: 0]; 8'h02: write_hdr_data = arp_ptype_reg[15: 8]; 8'h03: write_hdr_data = arp_ptype_reg[ 7: 0]; - 8'h04: write_hdr_data = arp_hlen_reg; - 8'h05: write_hdr_data = arp_plen_reg; + 8'h04: write_hdr_data = 6; // hlen + 8'h05: write_hdr_data = 4; // plen 8'h06: write_hdr_data = arp_oper_reg[15: 8]; 8'h07: write_hdr_data = arp_oper_reg[ 7: 0]; 8'h08: write_hdr_data = arp_sha_reg[47:40]; @@ -243,8 +239,6 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg <= 0; arp_htype_reg <= 0; arp_ptype_reg <= 0; - arp_hlen_reg <= 0; - arp_plen_reg <= 0; arp_oper_reg <= 0; arp_sha_reg <= 0; arp_spa_reg <= 0; @@ -289,8 +283,6 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg <= input_eth_type; arp_htype_reg <= input_arp_htype; arp_ptype_reg <= input_arp_ptype; - arp_hlen_reg <= input_arp_hlen; - arp_plen_reg <= input_arp_plen; arp_oper_reg <= input_arp_oper; arp_sha_reg <= input_arp_sha; arp_spa_reg <= input_arp_spa; diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index 8729c2ca4..61743b789 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -44,8 +44,6 @@ module arp_eth_tx_64 input wire [15:0] input_eth_type, input wire [15:0] input_arp_htype, input wire [15:0] input_arp_ptype, - input wire [7:0] input_arp_hlen, - input wire [7:0] input_arp_plen, input wire [15:0] input_arp_oper, input wire [47:0] input_arp_sha, input wire [31:0] input_arp_spa, @@ -119,8 +117,6 @@ reg [47:0] output_eth_src_mac_reg = 0; reg [15:0] output_eth_type_reg = 0; reg [15:0] arp_htype_reg = 0; reg [15:0] arp_ptype_reg = 0; -reg [7:0] arp_hlen_reg = 0; -reg [7:0] arp_plen_reg = 0; reg [15:0] arp_oper_reg = 0; reg [47:0] arp_sha_reg = 0; reg [31:0] arp_spa_reg = 0; @@ -178,8 +174,8 @@ always @* begin write_hdr_data[15: 8] = input_arp_htype[ 7: 0]; write_hdr_data[23:16] = input_arp_ptype[15: 8]; write_hdr_data[31:24] = input_arp_ptype[ 7: 0]; - write_hdr_data[39:32] = input_arp_hlen; - write_hdr_data[47:40] = input_arp_plen; + write_hdr_data[39:32] = 6; // hlen + write_hdr_data[47:40] = 4; // plen write_hdr_data[55:48] = input_arp_oper[15: 8]; write_hdr_data[63:56] = input_arp_oper[ 7: 0]; write_hdr_keep = 8'hff; @@ -260,8 +256,6 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg <= 0; arp_htype_reg <= 0; arp_ptype_reg <= 0; - arp_hlen_reg <= 0; - arp_plen_reg <= 0; arp_oper_reg <= 0; arp_sha_reg <= 0; arp_spa_reg <= 0; @@ -307,8 +301,6 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg <= input_eth_type; arp_htype_reg <= input_arp_htype; arp_ptype_reg <= input_arp_ptype; - arp_hlen_reg <= input_arp_hlen; - arp_plen_reg <= input_arp_plen; arp_oper_reg <= input_arp_oper; arp_sha_reg <= input_arp_sha; arp_spa_reg <= input_arp_spa; diff --git a/tb/arp_ep.py b/tb/arp_ep.py index adf63c1c3..d6b29fbff 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -158,8 +158,8 @@ def ARPFrameSource(clk, rst, eth_type=None, arp_htype=None, arp_ptype=None, - arp_hlen=None, - arp_plen=None, + arp_hlen=Signal(intbv(0)[8:]), + arp_plen=Signal(intbv(0)[8:]), arp_oper=None, arp_sha=None, arp_spa=None, diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py index 6fea2a81a..1d1c39e3e 100755 --- a/tb/test_arp_eth_tx.py +++ b/tb/test_arp_eth_tx.py @@ -53,8 +53,6 @@ def dut_arp_eth_tx(clk, input_eth_type, input_arp_htype, input_arp_ptype, - input_arp_hlen, - input_arp_plen, input_arp_oper, input_arp_sha, input_arp_spa, @@ -88,8 +86,6 @@ def dut_arp_eth_tx(clk, input_eth_type=input_eth_type, input_arp_htype=input_arp_htype, input_arp_ptype=input_arp_ptype, - input_arp_hlen=input_arp_hlen, - input_arp_plen=input_arp_plen, input_arp_oper=input_arp_oper, input_arp_sha=input_arp_sha, input_arp_spa=input_arp_spa, @@ -122,8 +118,6 @@ def bench(): input_eth_type = Signal(intbv(0)[16:]) input_arp_htype = Signal(intbv(0)[16:]) input_arp_ptype = Signal(intbv(0)[16:]) - input_arp_hlen = Signal(intbv(0)[8:]) - input_arp_plen = Signal(intbv(0)[8:]) input_arp_oper = Signal(intbv(0)[16:]) input_arp_sha = Signal(intbv(0)[48:]) input_arp_spa = Signal(intbv(0)[32:]) @@ -159,8 +153,6 @@ def bench(): eth_type=input_eth_type, arp_htype=input_arp_htype, arp_ptype=input_arp_ptype, - arp_hlen=input_arp_hlen, - arp_plen=input_arp_plen, arp_oper=input_arp_oper, arp_sha=input_arp_sha, arp_spa=input_arp_spa, @@ -198,8 +190,6 @@ def bench(): input_eth_type, input_arp_htype, input_arp_ptype, - input_arp_hlen, - input_arp_plen, input_arp_oper, input_arp_sha, input_arp_spa, diff --git a/tb/test_arp_eth_tx.v b/tb/test_arp_eth_tx.v index fdae80a01..4bff7700b 100644 --- a/tb/test_arp_eth_tx.v +++ b/tb/test_arp_eth_tx.v @@ -39,8 +39,6 @@ reg [47:0] input_eth_src_mac = 0; reg [15:0] input_eth_type = 0; reg [15:0] input_arp_htype = 0; reg [15:0] input_arp_ptype = 0; -reg [7:0] input_arp_hlen = 0; -reg [7:0] input_arp_plen = 0; reg [15:0] input_arp_oper = 0; reg [47:0] input_arp_sha = 0; reg [31:0] input_arp_spa = 0; @@ -72,8 +70,6 @@ initial begin input_eth_type, input_arp_htype, input_arp_ptype, - input_arp_hlen, - input_arp_plen, input_arp_oper, input_arp_sha, input_arp_spa, @@ -109,8 +105,6 @@ UUT ( .input_eth_type(input_eth_type), .input_arp_htype(input_arp_htype), .input_arp_ptype(input_arp_ptype), - .input_arp_hlen(input_arp_hlen), - .input_arp_plen(input_arp_plen), .input_arp_oper(input_arp_oper), .input_arp_sha(input_arp_sha), .input_arp_spa(input_arp_spa), diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py index 1e5b4c466..b4571d53d 100755 --- a/tb/test_arp_eth_tx_64.py +++ b/tb/test_arp_eth_tx_64.py @@ -53,8 +53,6 @@ def dut_arp_eth_tx_64(clk, input_eth_type, input_arp_htype, input_arp_ptype, - input_arp_hlen, - input_arp_plen, input_arp_oper, input_arp_sha, input_arp_spa, @@ -89,8 +87,6 @@ def dut_arp_eth_tx_64(clk, input_eth_type=input_eth_type, input_arp_htype=input_arp_htype, input_arp_ptype=input_arp_ptype, - input_arp_hlen=input_arp_hlen, - input_arp_plen=input_arp_plen, input_arp_oper=input_arp_oper, input_arp_sha=input_arp_sha, input_arp_spa=input_arp_spa, @@ -124,8 +120,6 @@ def bench(): input_eth_type = Signal(intbv(0)[16:]) input_arp_htype = Signal(intbv(0)[16:]) input_arp_ptype = Signal(intbv(0)[16:]) - input_arp_hlen = Signal(intbv(0)[8:]) - input_arp_plen = Signal(intbv(0)[8:]) input_arp_oper = Signal(intbv(0)[16:]) input_arp_sha = Signal(intbv(0)[48:]) input_arp_spa = Signal(intbv(0)[32:]) @@ -162,8 +156,6 @@ def bench(): eth_type=input_eth_type, arp_htype=input_arp_htype, arp_ptype=input_arp_ptype, - arp_hlen=input_arp_hlen, - arp_plen=input_arp_plen, arp_oper=input_arp_oper, arp_sha=input_arp_sha, arp_spa=input_arp_spa, @@ -202,8 +194,6 @@ def bench(): input_eth_type, input_arp_htype, input_arp_ptype, - input_arp_hlen, - input_arp_plen, input_arp_oper, input_arp_sha, input_arp_spa, diff --git a/tb/test_arp_eth_tx_64.v b/tb/test_arp_eth_tx_64.v index a9aed7821..8b8c39d5d 100644 --- a/tb/test_arp_eth_tx_64.v +++ b/tb/test_arp_eth_tx_64.v @@ -39,8 +39,6 @@ reg [47:0] input_eth_src_mac = 0; reg [15:0] input_eth_type = 0; reg [15:0] input_arp_htype = 0; reg [15:0] input_arp_ptype = 0; -reg [7:0] input_arp_hlen = 0; -reg [7:0] input_arp_plen = 0; reg [15:0] input_arp_oper = 0; reg [47:0] input_arp_sha = 0; reg [31:0] input_arp_spa = 0; @@ -73,8 +71,6 @@ initial begin input_eth_type, input_arp_htype, input_arp_ptype, - input_arp_hlen, - input_arp_plen, input_arp_oper, input_arp_sha, input_arp_spa, @@ -111,8 +107,6 @@ UUT ( .input_eth_type(input_eth_type), .input_arp_htype(input_arp_htype), .input_arp_ptype(input_arp_ptype), - .input_arp_hlen(input_arp_hlen), - .input_arp_plen(input_arp_plen), .input_arp_oper(input_arp_oper), .input_arp_sha(input_arp_sha), .input_arp_spa(input_arp_spa), From 2fd2663eeecf077ea80912261ff0e589e64f4512 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 19 Sep 2014 17:31:34 -0700 Subject: [PATCH 014/617] Update comments --- rtl/arp_eth_rx.v | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index a42f61aa4..33ab19cec 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -273,12 +273,16 @@ always @* begin end endcase if (input_eth_payload_tlast) begin + // end of frame state_next = STATE_IDLE; if (frame_ptr_reg != 8'h1B) begin + // don't have the whole header error_header_early_termination_next = 1; end else if (output_arp_hlen != 6 || output_arp_plen != 4) begin + // lengths not valid error_invalid_header_next = 1; end else begin + // otherwise, transfer tuser output_frame_valid_next = ~input_eth_payload_tuser; end end @@ -287,13 +291,14 @@ always @* begin end end STATE_WAIT_LAST: begin - // read last payload word; data in output register; do not accept new data + // wait for end of frame; read and discard if (input_eth_payload_tvalid) begin - // word transfer out - done if (input_eth_payload_tlast) begin if (output_arp_hlen != 6 || output_arp_plen != 4) begin + // lengths not valid error_invalid_header_next = 1; end else begin + // otherwise, transfer tuser output_frame_valid_next = ~input_eth_payload_tuser; end state_next = STATE_IDLE; @@ -301,7 +306,6 @@ always @* begin state_next = STATE_WAIT_LAST; end end else begin - // wait for end of frame; read and discard state_next = STATE_WAIT_LAST; end end From fa72cc2035a6de9601b53adf799c4cd8ab9a72d6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 19 Sep 2014 17:32:27 -0700 Subject: [PATCH 015/617] Always make a copy of the data array --- tb/axis_ep.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 34ff5b35c..f55e08a10 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -33,14 +33,12 @@ class AXIStreamFrame(object): self.keep = None self.user = None - if type(data) is bytes: - data = bytearray(data) - if type(data) is bytearray: - self.data = data + if type(data) is bytes or type(data) is bytearray: + self.data = bytearray(data) if type(data) is AXIStreamFrame: self.N = data.N self.WL = data.WL - self.data = data.data + self.data = bytearray(data.data) if data.keep is not None: self.keep = list(data.keep) if data.user is not None: From 54bc201f5208860f8b8821cb7c3bee4d22819adc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 19 Sep 2014 17:32:27 -0700 Subject: [PATCH 016/617] Always make a copy of the data array --- tb/axis_ep.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 34ff5b35c..f55e08a10 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -33,14 +33,12 @@ class AXIStreamFrame(object): self.keep = None self.user = None - if type(data) is bytes: - data = bytearray(data) - if type(data) is bytearray: - self.data = data + if type(data) is bytes or type(data) is bytearray: + self.data = bytearray(data) if type(data) is AXIStreamFrame: self.N = data.N self.WL = data.WL - self.data = data.data + self.data = bytearray(data.data) if data.keep is not None: self.keep = list(data.keep) if data.user is not None: From 4ad302949f8f682c24be72700948306b83106d0a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 19 Sep 2014 17:33:23 -0700 Subject: [PATCH 017/617] Add defaults --- tb/arp_ep.py | 48 ++++++++++++++++++++++++------------------------ tb/eth_ep.py | 12 ++++++------ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/tb/arp_ep.py b/tb/arp_ep.py index d6b29fbff..8c296bf14 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -153,18 +153,18 @@ class ARPFrame(object): def ARPFrameSource(clk, rst, frame_valid=None, frame_ready=None, - eth_dest_mac=None, - eth_src_mac=None, - eth_type=None, - arp_htype=None, - arp_ptype=None, - arp_hlen=Signal(intbv(0)[8:]), - arp_plen=Signal(intbv(0)[8:]), - arp_oper=None, - arp_sha=None, - arp_spa=None, - arp_tha=None, - arp_tpa=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + arp_htype=Signal(intbv(0)[16:]), + arp_ptype=Signal(intbv(0)[16:]), + arp_hlen=Signal(intbv(6)[8:]), + arp_plen=Signal(intbv(4)[8:]), + arp_oper=Signal(intbv(0)[16:]), + arp_sha=Signal(intbv(0)[48:]), + arp_spa=Signal(intbv(0)[32:]), + arp_tha=Signal(intbv(0)[48:]), + arp_tpa=Signal(intbv(0)[32:]), fifo=None, pause=0, name=None): @@ -217,18 +217,18 @@ def ARPFrameSource(clk, rst, def ARPFrameSink(clk, rst, frame_valid=None, frame_ready=None, - eth_dest_mac=None, - eth_src_mac=None, - eth_type=None, - arp_htype=None, - arp_ptype=None, - arp_hlen=None, - arp_plen=None, - arp_oper=None, - arp_sha=None, - arp_spa=None, - arp_tha=None, - arp_tpa=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + arp_htype=Signal(intbv(0)[16:]), + arp_ptype=Signal(intbv(0)[16:]), + arp_hlen=Signal(intbv(6)[8:]), + arp_plen=Signal(intbv(4)[8:]), + arp_oper=Signal(intbv(0)[16:]), + arp_sha=Signal(intbv(0)[48:]), + arp_spa=Signal(intbv(0)[32:]), + arp_tha=Signal(intbv(0)[48:]), + arp_tpa=Signal(intbv(0)[32:]), fifo=None, pause=0, name=None): diff --git a/tb/eth_ep.py b/tb/eth_ep.py index a71086f4f..4fd9fcdba 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -89,9 +89,9 @@ class EthFrame(object): def EthFrameSource(clk, rst, eth_hdr_valid=None, eth_hdr_ready=None, - eth_dest_mac=None, - eth_src_mac=None, - eth_type=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), eth_payload_tdata=None, eth_payload_tkeep=Signal(bool(True)), eth_payload_tvalid=Signal(bool(False)), @@ -157,9 +157,9 @@ def EthFrameSource(clk, rst, def EthFrameSink(clk, rst, eth_hdr_valid=None, eth_hdr_ready=None, - eth_dest_mac=None, - eth_src_mac=None, - eth_type=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), eth_payload_tdata=None, eth_payload_tkeep=Signal(bool(True)), eth_payload_tvalid=Signal(bool(True)), From 4bee0542b72fca5bf331c4e204490ceb52fbee59 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 19 Sep 2014 17:35:51 -0700 Subject: [PATCH 018/617] Add IP modules (8 bit datapath) --- rtl/ip_eth_rx.v | 626 +++++++++++++++++++++++++++ rtl/ip_eth_tx.v | 556 ++++++++++++++++++++++++ tb/ip_ep.py | 425 ++++++++++++++++++ tb/test_ip_eth_rx.py | 996 +++++++++++++++++++++++++++++++++++++++++++ tb/test_ip_eth_rx.v | 173 ++++++++ tb/test_ip_eth_tx.py | 945 ++++++++++++++++++++++++++++++++++++++++ tb/test_ip_eth_tx.v | 155 +++++++ 7 files changed, 3876 insertions(+) create mode 100644 rtl/ip_eth_rx.v create mode 100644 rtl/ip_eth_tx.v create mode 100644 tb/ip_ep.py create mode 100755 tb/test_ip_eth_rx.py create mode 100644 tb/test_ip_eth_rx.v create mode 100755 tb/test_ip_eth_tx.py create mode 100644 tb/test_ip_eth_tx.v diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v new file mode 100644 index 000000000..0a5619bcd --- /dev/null +++ b/rtl/ip_eth_rx.v @@ -0,0 +1,626 @@ +/* + +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 + +/* + * IP ethernet frame receiver (Ethernet frame in, IP frame out) + */ +module ip_eth_rx +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [7:0] input_eth_payload_tdata, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Status signals + */ + output wire busy, + output wire error_header_early_termination, + output wire error_payload_early_termination, + output wire error_invalid_header, + output wire error_invalid_checksum +); + +/* + +IP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + payload length octets + +This module receives an Ethernet frame with decoded fields and decodes +the AXI packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_READ_HEADER = 3'd1, + STATE_READ_PAYLOAD_IDLE = 3'd2, + STATE_READ_PAYLOAD_TRANSFER = 3'd3, + STATE_READ_PAYLOAD_TRANSFER_WAIT = 3'd4, + STATE_READ_PAYLOAD_TRANSFER_LAST = 3'd5, + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST = 3'd6, + STATE_WAIT_LAST = 3'd7; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_eth_hdr; +reg store_ip_version_ihl; +reg store_ip_dscp_ecn; +reg store_ip_length_0; +reg store_ip_length_1; +reg store_ip_identification_0; +reg store_ip_identification_1; +reg store_ip_flags_fragment_offset_0; +reg store_ip_flags_fragment_offset_1; +reg store_ip_ttl; +reg store_ip_protocol; +reg store_ip_header_checksum_0; +reg store_ip_header_checksum_1; +reg store_ip_source_ip_0; +reg store_ip_source_ip_1; +reg store_ip_source_ip_2; +reg store_ip_source_ip_3; +reg store_ip_dest_ip_0; +reg store_ip_dest_ip_1; +reg store_ip_dest_ip_2; +reg store_ip_dest_ip_3; + +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg assert_tlast; +reg assert_tuser; + +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [15:0] hdr_sum_reg = 0, hdr_sum_next; + +reg input_eth_hdr_ready_reg = 0; +reg input_eth_payload_tready_reg = 0; + +reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [3:0] output_ip_version_reg = 0; +reg [3:0] output_ip_ihl_reg = 0; +reg [5:0] output_ip_dscp_reg = 0; +reg [1:0] output_ip_ecn_reg = 0; +reg [15:0] output_ip_length_reg = 0; +reg [15:0] output_ip_identification_reg = 0; +reg [2:0] output_ip_flags_reg = 0; +reg [12:0] output_ip_fragment_offset_reg = 0; +reg [7:0] output_ip_ttl_reg = 0; +reg [7:0] output_ip_protocol_reg = 0; +reg [15:0] output_ip_header_checksum_reg = 0; +reg [31:0] output_ip_source_ip_reg = 0; +reg [31:0] output_ip_dest_ip_reg = 0; +reg [7:0] output_ip_payload_tdata_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg busy_reg = 0; +reg error_header_early_termination_reg = 0, error_header_early_termination_next; +reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; +reg error_invalid_header_reg = 0, error_invalid_header_next; +reg error_invalid_checksum_reg = 0, error_invalid_checksum_next; + +reg [7:0] temp_ip_payload_tdata_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign input_eth_hdr_ready = input_eth_hdr_ready_reg; +assign input_eth_payload_tready = input_eth_payload_tready_reg; + +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +assign busy = busy_reg; +assign error_header_early_termination = error_header_early_termination_reg; +assign error_payload_early_termination = error_payload_early_termination_reg; +assign error_invalid_header = error_invalid_header_reg; +assign error_invalid_checksum = error_invalid_checksum_reg; + +function [15:0] add1c16b; + parameter WIDTH = 16; + input [15:0] a, b; + reg [16:0] t; + begin + t = a+b; + add1c16b = t[15:0] + t[16]; + end +endfunction + +always @* begin + state_next = 2'bz; + + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + assert_tlast = 0; + assert_tuser = 0; + + store_eth_hdr = 0; + store_ip_version_ihl = 0; + store_ip_dscp_ecn = 0; + store_ip_length_0 = 0; + store_ip_length_1 = 0; + store_ip_identification_0 = 0; + store_ip_identification_1 = 0; + store_ip_flags_fragment_offset_0 = 0; + store_ip_flags_fragment_offset_1 = 0; + store_ip_ttl = 0; + store_ip_protocol = 0; + store_ip_header_checksum_0 = 0; + store_ip_header_checksum_1 = 0; + store_ip_source_ip_0 = 0; + store_ip_source_ip_1 = 0; + store_ip_source_ip_2 = 0; + store_ip_source_ip_3 = 0; + store_ip_dest_ip_0 = 0; + store_ip_dest_ip_1 = 0; + store_ip_dest_ip_2 = 0; + store_ip_dest_ip_3 = 0; + + frame_ptr_next = frame_ptr_reg; + + hdr_sum_next = hdr_sum_reg; + + output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + + error_header_early_termination_next = 0; + error_payload_early_termination_next = 0; + error_invalid_header_next = 0; + error_invalid_checksum_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for header + frame_ptr_next = 0; + hdr_sum_next = 0; + + if (input_eth_hdr_ready & input_eth_hdr_valid) begin + frame_ptr_next = 0; + store_eth_hdr = 1; + state_next = STATE_READ_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_READ_HEADER: begin + // read header state + if (input_eth_payload_tvalid) begin + // word transfer in - store it + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_READ_HEADER; + + if (frame_ptr_reg[0]) begin + hdr_sum_next = add1c16b(hdr_sum_reg, {8'd0, input_eth_payload_tdata}); + end else begin + hdr_sum_next = add1c16b(hdr_sum_reg, {input_eth_payload_tdata, 8'd0}); + end + + case (frame_ptr_reg) + 8'h00: store_ip_version_ihl = 1; + 8'h01: store_ip_dscp_ecn = 1; + 8'h02: store_ip_length_1 = 1; + 8'h03: store_ip_length_0 = 1; + 8'h04: store_ip_identification_1 = 1; + 8'h05: store_ip_identification_0 = 1; + 8'h06: store_ip_flags_fragment_offset_1 = 1; + 8'h07: store_ip_flags_fragment_offset_0 = 1; + 8'h08: store_ip_ttl = 1; + 8'h09: store_ip_protocol = 1; + 8'h0A: store_ip_header_checksum_1 = 1; + 8'h0B: store_ip_header_checksum_0 = 1; + 8'h0C: store_ip_source_ip_3 = 1; + 8'h0D: store_ip_source_ip_2 = 1; + 8'h0E: store_ip_source_ip_1 = 1; + 8'h0F: store_ip_source_ip_0 = 1; + 8'h10: store_ip_dest_ip_3 = 1; + 8'h11: store_ip_dest_ip_2 = 1; + 8'h12: store_ip_dest_ip_1 = 1; + 8'h13: begin + store_ip_dest_ip_0 = 1; + if (output_ip_version_reg != 4 || output_ip_ihl_reg != 5) begin + error_invalid_header_next = 1; + state_next = STATE_WAIT_LAST; + end else if (hdr_sum_next != 16'hffff) begin + error_invalid_checksum_next = 1; + state_next = STATE_WAIT_LAST; + end else begin + output_ip_hdr_valid_next = 1; + state_next = STATE_READ_PAYLOAD_IDLE; + end + end + endcase + + if (input_eth_payload_tlast) begin + state_next = STATE_IDLE; + error_header_early_termination_next = 1; + end + + end else begin + state_next = STATE_READ_HEADER; + end + end + STATE_READ_PAYLOAD_IDLE: begin + // idle; no data in registers + if (input_eth_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+1; + if (input_eth_payload_tlast) begin + if (frame_ptr_next != output_ip_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == output_ip_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_READ_PAYLOAD_IDLE; + end + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register + if (input_eth_payload_tvalid & output_ip_payload_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+1; + if (input_eth_payload_tlast) begin + if (frame_ptr_next != output_ip_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == output_ip_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else if (~input_eth_payload_tvalid & output_ip_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_READ_PAYLOAD_IDLE; + end else if (input_eth_payload_tvalid & ~output_ip_payload_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in both output and temp registers + if (output_ip_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_ip_payload_tlast_reg) begin + if (frame_ptr_next != output_ip_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == output_ip_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + if (output_ip_payload_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + if (input_eth_payload_tvalid) begin + if (input_eth_payload_tlast) begin + // assert tlast and transfer tuser + assert_tlast = 1; + assert_tuser = input_eth_payload_tuser; + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + if (input_eth_payload_tvalid) begin + if (input_eth_payload_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end else begin + state_next = STATE_WAIT_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + hdr_sum_reg <= 0; + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + busy_reg <= 0; + error_header_early_termination_reg <= 0; + error_payload_early_termination_reg <= 0; + error_invalid_header_reg <= 0; + error_invalid_checksum_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + hdr_sum_reg <= hdr_sum_next; + + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + + error_header_early_termination_reg <= error_header_early_termination_next; + error_payload_early_termination_reg <= error_payload_early_termination_next; + error_invalid_header_reg <= error_invalid_header_next; + error_invalid_checksum_reg <= error_invalid_checksum_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_eth_hdr_ready_reg <= ~output_ip_hdr_valid; + input_eth_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + end + STATE_READ_HEADER: begin + // read header; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_IDLE: begin + // read payload; no data in registers; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in output and temp registers; do not accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 0; + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 0; + end + endcase + + // datapath + if (store_eth_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + end + + if (store_ip_version_ihl) {output_ip_version_reg, output_ip_ihl_reg} <= input_eth_payload_tdata; + if (store_ip_dscp_ecn) {output_ip_dscp_reg, output_ip_ecn_reg} <= input_eth_payload_tdata; + if (store_ip_length_0) output_ip_length_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_ip_length_1) output_ip_length_reg[15: 8] <= input_eth_payload_tdata; + if (store_ip_identification_0) output_ip_identification_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_ip_identification_1) output_ip_identification_reg[15: 8] <= input_eth_payload_tdata; + if (store_ip_flags_fragment_offset_0) output_ip_fragment_offset_reg[ 7:0] <= input_eth_payload_tdata; + if (store_ip_flags_fragment_offset_1) {output_ip_flags_reg, output_ip_fragment_offset_reg[12:8]} <= input_eth_payload_tdata; + if (store_ip_ttl) output_ip_ttl_reg <= input_eth_payload_tdata; + if (store_ip_protocol) output_ip_protocol_reg <= input_eth_payload_tdata; + if (store_ip_header_checksum_0) output_ip_header_checksum_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_ip_header_checksum_1) output_ip_header_checksum_reg[15: 8] <= input_eth_payload_tdata; + if (store_ip_source_ip_0) output_ip_source_ip_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_ip_source_ip_1) output_ip_source_ip_reg[15: 8] <= input_eth_payload_tdata; + if (store_ip_source_ip_2) output_ip_source_ip_reg[23:16] <= input_eth_payload_tdata; + if (store_ip_source_ip_3) output_ip_source_ip_reg[31:24] <= input_eth_payload_tdata; + if (store_ip_dest_ip_0) output_ip_dest_ip_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_ip_dest_ip_1) output_ip_dest_ip_reg[15: 8] <= input_eth_payload_tdata; + if (store_ip_dest_ip_2) output_ip_dest_ip_reg[23:16] <= input_eth_payload_tdata; + if (store_ip_dest_ip_3) output_ip_dest_ip_reg[31:24] <= input_eth_payload_tdata; + + if (transfer_in_out) begin + output_ip_payload_tdata_reg <= input_eth_payload_tdata; + output_ip_payload_tlast_reg <= input_eth_payload_tlast; + output_ip_payload_tuser_reg <= input_eth_payload_tuser; + end else if (transfer_in_temp) begin + temp_ip_payload_tdata_reg <= input_eth_payload_tdata; + temp_ip_payload_tlast_reg <= input_eth_payload_tlast; + temp_ip_payload_tuser_reg <= input_eth_payload_tuser; + end else if (transfer_temp_out) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (assert_tlast) output_ip_payload_tlast_reg <= 1; + if (assert_tuser) output_ip_payload_tuser_reg <= 1; + end +end + +endmodule diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v new file mode 100644 index 000000000..76c87a472 --- /dev/null +++ b/rtl/ip_eth_tx.v @@ -0,0 +1,556 @@ +/* + +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 + +/* + * IP ethernet frame transmitter (IP frame in, Ethernet frame out) + */ +module ip_eth_tx +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [7:0] input_ip_payload_tdata, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Status signals + */ + output wire busy, + output wire error_payload_early_termination +); + +/* + +IP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + payload length octets + +This module receives an Ethernet frame with decoded fields and decodes +the AXI packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_WRITE_HEADER = 3'd1, + STATE_WRITE_PAYLOAD_IDLE = 3'd2, + STATE_WRITE_PAYLOAD_TRANSFER = 3'd3, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 3'd4, + STATE_WRITE_PAYLOAD_TRANSFER_LAST = 3'd5, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST = 3'd6, + STATE_WAIT_LAST = 3'd7; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_ip_hdr; + +reg [7:0] write_hdr_data; +reg write_hdr_out; + +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg assert_tlast; +reg assert_tuser; + +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [15:0] hdr_sum_reg = 0, hdr_sum_next; +reg [15:0] payload_len_reg = 0, payload_len_next; + +reg [5:0] ip_dscp_reg = 0; +reg [1:0] ip_ecn_reg = 0; +reg [15:0] ip_length_reg = 0; +reg [15:0] ip_identification_reg = 0; +reg [2:0] ip_flags_reg = 0; +reg [12:0] ip_fragment_offset_reg = 0; +reg [7:0] ip_ttl_reg = 0; +reg [7:0] ip_protocol_reg = 0; +reg [31:0] ip_source_ip_reg = 0; +reg [31:0] ip_dest_ip_reg = 0; + +reg input_ip_hdr_ready_reg = 0; +reg input_ip_payload_tready_reg = 0; + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [7:0] output_eth_payload_tdata_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg busy_reg = 0; +reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; + +reg [7:0] temp_eth_payload_tdata_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +assign input_ip_hdr_ready = input_ip_hdr_ready_reg; +assign input_ip_payload_tready = input_ip_payload_tready_reg; + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign busy = busy_reg; +assign error_payload_early_termination = error_payload_early_termination_reg; + +function [15:0] add1c16b; + parameter WIDTH = 16; + input [15:0] a, b; + reg [16:0] t; + begin + t = a+b; + add1c16b = t[15:0] + t[16]; + end +endfunction + +always @* begin + state_next = 2'bz; + + store_ip_hdr = 0; + + write_hdr_data = 0; + write_hdr_out = 0; + + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + assert_tlast = 0; + assert_tuser = 0; + + frame_ptr_next = frame_ptr_reg; + + hdr_sum_next = hdr_sum_reg; + payload_len_next = payload_len_reg; + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + + error_payload_early_termination_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_ip_hdr_valid & input_ip_hdr_ready) begin + store_ip_hdr = 1; + write_hdr_out = 1; + write_hdr_data = {4'd4, 4'd5}; // ip_version, ip_ihl + output_eth_hdr_valid_next = 1; + frame_ptr_next = 1; + state_next = STATE_WRITE_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_HEADER: begin + // read header state + if (output_eth_payload_tready) begin + // word transfer out + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_WRITE_HEADER; + write_hdr_out = 1; + case (frame_ptr_reg) + 8'h01: begin + write_hdr_data = {ip_dscp_reg, ip_ecn_reg}; + hdr_sum_next = {4'd4, 4'd5, ip_dscp_reg, ip_ecn_reg}; + end + 8'h02: begin + write_hdr_data = ip_length_reg[15: 8]; + hdr_sum_next = add1c16b(hdr_sum_reg, ip_length_reg); + end + 8'h03: begin + write_hdr_data = ip_length_reg[ 7: 0]; + hdr_sum_next = add1c16b(hdr_sum_reg, ip_identification_reg); + end + 8'h04: begin + write_hdr_data = ip_identification_reg[15: 8]; + hdr_sum_next = add1c16b(hdr_sum_reg, {ip_flags_reg, ip_fragment_offset_reg}); + end + 8'h05: begin + write_hdr_data = ip_identification_reg[ 7: 0]; + hdr_sum_next = add1c16b(hdr_sum_reg, {ip_ttl_reg, ip_protocol_reg}); + end + 8'h06: begin + write_hdr_data = {ip_flags_reg, ip_fragment_offset_reg[12:8]}; + hdr_sum_next = add1c16b(hdr_sum_reg, ip_source_ip_reg[31:16]); + end + 8'h07: begin + write_hdr_data = ip_fragment_offset_reg[ 7: 0]; + hdr_sum_next = add1c16b(hdr_sum_reg, ip_source_ip_reg[15:0]); + end + 8'h08: begin + write_hdr_data = ip_ttl_reg; + hdr_sum_next = add1c16b(hdr_sum_reg, ip_dest_ip_reg[31:16]); + end + 8'h09: begin + write_hdr_data = ip_protocol_reg; + hdr_sum_next = add1c16b(hdr_sum_reg, ip_dest_ip_reg[15:0]); + end + 8'h0A: write_hdr_data = ~hdr_sum_reg[15: 8]; + 8'h0B: write_hdr_data = ~hdr_sum_reg[ 7: 0]; + 8'h0C: write_hdr_data = ip_source_ip_reg[31:24]; + 8'h0D: write_hdr_data = ip_source_ip_reg[23:16]; + 8'h0E: write_hdr_data = ip_source_ip_reg[15: 8]; + 8'h0F: write_hdr_data = ip_source_ip_reg[ 7: 0]; + 8'h10: write_hdr_data = ip_dest_ip_reg[31:24]; + 8'h11: write_hdr_data = ip_dest_ip_reg[23:16]; + 8'h12: write_hdr_data = ip_dest_ip_reg[15: 8]; + 8'h13: begin + write_hdr_data = ip_dest_ip_reg[ 7: 0]; + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + endcase + end else begin + state_next = STATE_WRITE_HEADER; + end + end + STATE_WRITE_PAYLOAD_IDLE: begin + // idle; no data in registers + if (input_ip_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+1; + if (input_ip_payload_tlast) begin + if (frame_ptr_next != ip_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == ip_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_WRITE_PAYLOAD_IDLE; + end + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // write payload; data in output register + if (input_ip_payload_tvalid & output_eth_payload_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+1; + if (input_ip_payload_tlast) begin + if (frame_ptr_next != ip_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == ip_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else if (~input_ip_payload_tvalid & output_eth_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_WRITE_PAYLOAD_IDLE; + end else if (input_ip_payload_tvalid & ~output_eth_payload_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // write payload; data in both output and temp registers + if (output_eth_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_eth_payload_tlast_reg) begin + if (frame_ptr_next != ip_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == ip_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // write last payload word; data in output register; do not accept new data + if (output_eth_payload_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + if (input_ip_payload_tvalid) begin + if (input_ip_payload_tlast) begin + // assert tlast and transfer tuser + assert_tlast = 1; + assert_tuser = input_ip_payload_tuser; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + if (input_ip_payload_tvalid) begin + if (input_ip_payload_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end else begin + state_next = STATE_WAIT_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + hdr_sum_reg <= 0; + payload_len_reg <= 0; + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + ip_dscp_reg <= 0; + ip_ecn_reg <= 0; + ip_length_reg <= 0; + ip_identification_reg <= 0; + ip_flags_reg <= 0; + ip_fragment_offset_reg <= 0; + ip_ttl_reg <= 0; + ip_protocol_reg <= 0; + ip_source_ip_reg <= 0; + ip_dest_ip_reg <= 0; + output_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + busy_reg <= 0; + error_payload_early_termination_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + hdr_sum_reg <= hdr_sum_next; + payload_len_reg <= payload_len_next; + + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + + busy_reg <= state_next != STATE_IDLE; + + error_payload_early_termination_reg <= error_payload_early_termination_next; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_ip_hdr_ready_reg <= 1; + input_ip_payload_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + end + STATE_WRITE_HEADER: begin + // write header + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_IDLE: begin + // write payload; no data in registers; accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_eth_payload_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // write payload; data in output register; accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // write payload; data in output and temp registers; do not accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // write last payload word; data in output register; do not accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_eth_payload_tvalid_reg <= 0; + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_eth_payload_tvalid_reg <= 0; + end + endcase + + if (store_ip_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + ip_dscp_reg <= input_ip_dscp; + ip_ecn_reg <= input_ip_ecn; + ip_length_reg <= input_ip_length; + ip_identification_reg <= input_ip_identification; + ip_flags_reg <= input_ip_flags; + ip_fragment_offset_reg <= input_ip_fragment_offset; + ip_ttl_reg <= input_ip_ttl; + ip_protocol_reg <= input_ip_protocol; + ip_source_ip_reg <= input_ip_source_ip; + ip_dest_ip_reg <= input_ip_dest_ip; + end + + if (write_hdr_out) begin + output_eth_payload_tdata_reg <= write_hdr_data; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + end else if (transfer_in_out) begin + output_eth_payload_tdata_reg <= input_ip_payload_tdata; + output_eth_payload_tlast_reg <= input_ip_payload_tlast; + output_eth_payload_tuser_reg <= input_ip_payload_tuser; + end else if (transfer_in_temp) begin + temp_eth_payload_tdata_reg <= input_ip_payload_tdata; + temp_eth_payload_tlast_reg <= input_ip_payload_tlast; + temp_eth_payload_tuser_reg <= input_ip_payload_tuser; + end else if (transfer_temp_out) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (assert_tlast) output_eth_payload_tlast_reg <= 1; + if (assert_tuser) output_eth_payload_tuser_reg <= 1; + end +end + +endmodule diff --git a/tb/ip_ep.py b/tb/ip_ep.py new file mode 100644 index 000000000..482429014 --- /dev/null +++ b/tb/ip_ep.py @@ -0,0 +1,425 @@ +""" + +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 axis_ep +import eth_ep +from Queue import Queue +import struct + +class IPFrame(object): + def __init__(self, payload='', + eth_dest_mac=0, + eth_src_mac=0, + eth_type=0, + ip_version=4, + ip_ihl=5, + ip_dscp=0, + ip_ecn=0, + ip_length=None, + ip_identification=0, + ip_flags=2, + ip_fragment_offset=0, + ip_ttl=64, + ip_protocol=0x11, + ip_header_checksum=None, + ip_source_ip=0xc0a80164, + ip_dest_ip=0xc0a80165): + + self._payload = axis_ep.AXIStreamFrame() + self.eth_dest_mac = eth_dest_mac + self.eth_src_mac = eth_src_mac + self.eth_type = eth_type + self.ip_version = ip_version + self.ip_ihl = ip_ihl + self.ip_dscp = ip_dscp + self.ip_ecn = ip_ecn + self.ip_length = ip_length + self.ip_identification = ip_identification + self.ip_flags = ip_flags + self.ip_fragment_offset = ip_fragment_offset + self.ip_ttl = ip_ttl + self.ip_protocol = ip_protocol + self.ip_header_checksum = ip_header_checksum + self.ip_source_ip = ip_source_ip + self.ip_dest_ip = ip_dest_ip + + if type(payload) is dict: + self.payload = axis_ep.AXIStreamFrame(payload['ip_payload']) + self.eth_dest_mac = payload['eth_dest_mac'] + self.eth_src_mac = payload['eth_src_mac'] + self.eth_type = payload['eth_type'] + self.ip_version = payload['ip_version'] + self.ip_ihl = payload['ip_ihl'] + self.ip_dscp = payload['ip_dscp'] + self.ip_ecn = payload['ip_ecn'] + self.ip_length = payload['ip_length'] + self.ip_identification = payload['ip_identification'] + self.ip_flags = payload['ip_flags'] + self.ip_fragment_offset = payload['ip_fragment_offset'] + self.ip_ttl = payload['ip_ttl'] + self.ip_protocol = payload['ip_protocol'] + self.ip_header_checksum = payload['ip_header_checksum'] + self.ip_source_ip = payload['ip_source_ip'] + self.ip_dest_ip = payload['ip_dest_ip'] + if type(payload) is bytes: + payload = bytearray(payload) + if type(payload) is bytearray or type(payload) is axis_ep.AXIStreamFrame: + self.payload = axis_ep.AXIStreamFrame(payload) + if type(payload) is IPFrame: + self.payload = axis_ep.AXIStreamFrame(payload.payload) + self.eth_dest_mac = payload.eth_dest_mac + self.eth_src_mac = payload.eth_src_mac + self.eth_type = payload.eth_type + self.ip_version = payload.ip_version + self.ip_ihl = payload.ip_ihl + self.ip_dscp = payload.ip_dscp + self.ip_ecn = payload.ip_ecn + self.ip_length = payload.ip_length + self.ip_identification = payload.ip_identification + self.ip_flags = payload.ip_flags + self.ip_fragment_offset = payload.ip_fragment_offset + self.ip_ttl = payload.ip_ttl + self.ip_protocol = payload.ip_protocol + self.ip_header_checksum = payload.ip_header_checksum + self.ip_source_ip = payload.ip_source_ip + self.ip_dest_ip = payload.ip_dest_ip + + @property + def payload(self): + return self._payload + + @payload.setter + def payload(self, value): + self._payload = axis_ep.AXIStreamFrame(value) + + def update_length(self): + self.ip_length = len(self.payload.data) + 20 + + def checksum(self): + cksum = self.ip_version << 12 | self.ip_ihl << 8 | self.ip_dscp << 2 | self.ip_ecn + cksum += self.ip_length + cksum += self.ip_identification + cksum += self.ip_flags << 13 | self.ip_fragment_offset + cksum += self.ip_ttl << 8 | self.ip_protocol + cksum += self.ip_source_ip & 0xffff + cksum += (self.ip_source_ip >> 16) & 0xffff + cksum += self.ip_dest_ip & 0xffff + cksum += (self.ip_dest_ip >> 16) & 0xffff + cksum = (cksum & 0xffff) + (cksum >> 16) + cksum = (cksum & 0xffff) + (cksum >> 16) + return ~cksum & 0xffff + + def update_checksum(self): + self.ip_header_checksum = self.checksum() + + def build(self): + if self.ip_length is None: + self.update_length() + if self.ip_header_checksum is None: + self.update_checksum() + + def build_axis(self): + return self.build_eth().build_axis() + + def build_eth(self): + self.build() + data = '' + + data += struct.pack('B', self.ip_version << 4 | self.ip_ihl) + data += struct.pack('B', self.ip_dscp << 2 | self.ip_ecn) + data += struct.pack('>H', self.ip_length) + data += struct.pack('>H', self.ip_identification) + data += struct.pack('>H', self.ip_flags << 13 | self.ip_fragment_offset) + data += struct.pack('B', self.ip_ttl) + data += struct.pack('B', self.ip_protocol) + data += struct.pack('>H', self.ip_header_checksum) + data += struct.pack('>L', self.ip_source_ip) + data += struct.pack('>L', self.ip_dest_ip) + + data += self.payload.data + + return eth_ep.EthFrame(data, self.eth_dest_mac, self.eth_src_mac, self.eth_type) + + def parse_axis(self, data): + frame = eth_ep.EthFrame() + frame.parse_axis(data) + self.parse_eth(frame) + + def parse_eth(self, data): + self.eth_src_mac = data.eth_src_mac + self.eth_dest_mac = data.eth_dest_mac + self.eth_type = data.eth_type + + v = struct.unpack('B', data.payload.data[0:1])[0] + self.ip_version = (v >> 4) & 0xF + self.ip_ihl = v & 0xF + v = struct.unpack('B', data.payload.data[1:2])[0] + self.ip_dscp = (v >> 2) & 0x3F + self.ip_ecn = v & 0x3 + self.ip_length = struct.unpack('>H', data.payload.data[2:4])[0] + self.ip_identification = struct.unpack('>H', data.payload.data[4:6])[0] + v = struct.unpack('>H', data.payload.data[6:8])[0] + self.ip_flags = (v >> 13) & 0x7 + self.ip_fragment_offset = v & 0x1FFF + self.ip_ttl = struct.unpack('B', data.payload.data[8:9])[0] + self.ip_protocol = struct.unpack('B', data.payload.data[9:10])[0] + self.ip_header_checksum = struct.unpack('>H', data.payload.data[10:12])[0] + self.ip_source_ip = struct.unpack('>L', data.payload.data[12:16])[0] + self.ip_dest_ip = struct.unpack('>L', data.payload.data[16:20])[0] + + self.payload = axis_ep.AXIStreamFrame(data.payload.data[20:]) + + def __eq__(self, other): + if type(other) is IPFrame: + return (self.eth_src_mac == other.eth_src_mac and + self.eth_dest_mac == other.eth_dest_mac and + self.eth_type == other.eth_type and + self.ip_version == other.ip_version and + self.ip_ihl == other.ip_ihl and + self.ip_dscp == other.ip_dscp and + self.ip_ecn == other.ip_ecn and + self.ip_length == other.ip_length and + self.ip_identification == other.ip_identification and + self.ip_flags == other.ip_flags and + self.ip_fragment_offset == other.ip_fragment_offset and + self.ip_ttl == other.ip_ttl and + self.ip_protocol == other.ip_protocol and + self.ip_header_checksum == other.ip_header_checksum and + self.ip_source_ip == other.ip_source_ip and + self.ip_dest_ip == other.ip_dest_ip and + self.payload == other.payload) + + def __repr__(self): + return (('IPFrame(payload=%s, ' % repr(self.payload)) + + ('eth_dest_mac=0x%012x, ' % self.eth_dest_mac) + + ('eth_src_mac=0x%012x, ' % self.eth_src_mac) + + ('eth_type=0x%04x, ' % self.eth_type) + + ('ip_version=%d, ' % self.ip_version) + + ('ip_ihl=%d, ' % self.ip_ihl) + + ('ip_dscp=%d, ' % self.ip_dscp) + + ('ip_ecn=%d, ' % self.ip_ecn) + + ('ip_length=%d, ' % self.ip_length) + + ('ip_identification=%d, ' % self.ip_identification) + + ('ip_flags=%d, ' % self.ip_flags) + + ('ip_fragment_offset=%d, ' % self.ip_fragment_offset) + + ('ip_ttl=%d, ' % self.ip_ttl) + + ('ip_protocol=0x%02x, ' % self.ip_protocol) + + ('ip_header_checksum=%x, ' % self.ip_header_checksum) + + ('ip_source_ip=0x%08x, ' % self.ip_source_ip) + + ('ip_dest_ip=0x%08x)' % self.ip_dest_ip)) + +def IPFrameSource(clk, rst, + ip_hdr_valid=None, + ip_hdr_ready=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + ip_version=Signal(intbv(4)[4:]), + ip_ihl=Signal(intbv(5)[4:]), + ip_dscp=Signal(intbv(0)[6:]), + ip_ecn=Signal(intbv(0)[2:]), + ip_length=Signal(intbv(0)[16:]), + ip_identification=Signal(intbv(0)[16:]), + ip_flags=Signal(intbv(0)[3:]), + ip_fragment_offset=Signal(intbv(0)[13:]), + ip_ttl=Signal(intbv(0)[8:]), + ip_protocol=Signal(intbv(0)[8:]), + ip_header_checksum=Signal(intbv(0)[16:]), + ip_source_ip=Signal(intbv(0)[32:]), + ip_dest_ip=Signal(intbv(0)[32:]), + ip_payload_tdata=None, + ip_payload_tkeep=Signal(bool(True)), + ip_payload_tvalid=Signal(bool(False)), + ip_payload_tready=Signal(bool(True)), + ip_payload_tlast=Signal(bool(False)), + ip_payload_tuser=Signal(bool(False)), + fifo=None, + pause=0, + name=None): + + ip_hdr_ready_int = Signal(bool(False)) + ip_hdr_valid_int = Signal(bool(False)) + ip_payload_pause = Signal(bool(False)) + + ip_payload_fifo = Queue() + + ip_payload_source = axis_ep.AXIStreamSource(clk, + rst, + tdata=ip_payload_tdata, + tkeep=ip_payload_tkeep, + tvalid=ip_payload_tvalid, + tready=ip_payload_tready, + tlast=ip_payload_tlast, + tuser=ip_payload_tuser, + fifo=ip_payload_fifo, + pause=ip_payload_pause) + + @always_comb + def pause_logic(): + ip_hdr_ready_int.next = ip_hdr_ready and not pause + ip_hdr_valid.next = ip_hdr_valid_int and not pause + ip_payload_pause.next = pause # or ip_hdr_valid_int + + @instance + def logic(): + frame = dict() + + while True: + yield clk.posedge, rst.posedge + + if rst: + ip_hdr_valid_int.next = False + else: + if ip_hdr_ready_int: + ip_hdr_valid_int.next = False + if (ip_payload_tlast and ip_hdr_ready_int and ip_hdr_valid) or not ip_hdr_valid_int: + if not fifo.empty(): + frame = fifo.get() + frame = IPFrame(frame) + frame.build() + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + ip_version.next = frame.ip_version + ip_ihl.next = frame.ip_ihl + ip_dscp.next = frame.ip_dscp + ip_ecn.next = frame.ip_ecn + ip_length.next = frame.ip_length + ip_identification.next = frame.ip_identification + ip_flags.next = frame.ip_flags + ip_fragment_offset.next = frame.ip_fragment_offset + ip_ttl.next = frame.ip_ttl + ip_protocol.next = frame.ip_protocol + ip_header_checksum.next = frame.ip_header_checksum + ip_source_ip.next = frame.ip_source_ip + ip_dest_ip.next = frame.ip_dest_ip + ip_payload_fifo.put(frame.payload) + + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + + ip_hdr_valid_int.next = True + + return logic, pause_logic, ip_payload_source + + +def IPFrameSink(clk, rst, + ip_hdr_valid=None, + ip_hdr_ready=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + ip_version=Signal(intbv(4)[4:]), + ip_ihl=Signal(intbv(5)[4:]), + ip_dscp=Signal(intbv(0)[6:]), + ip_ecn=Signal(intbv(0)[2:]), + ip_length=Signal(intbv(0)[16:]), + ip_identification=Signal(intbv(0)[16:]), + ip_flags=Signal(intbv(0)[3:]), + ip_fragment_offset=Signal(intbv(0)[13:]), + ip_ttl=Signal(intbv(0)[8:]), + ip_protocol=Signal(intbv(0)[8:]), + ip_header_checksum=Signal(intbv(0)[16:]), + ip_source_ip=Signal(intbv(0)[32:]), + ip_dest_ip=Signal(intbv(0)[32:]), + ip_payload_tdata=None, + ip_payload_tkeep=Signal(bool(True)), + ip_payload_tvalid=Signal(bool(True)), + ip_payload_tready=Signal(bool(True)), + ip_payload_tlast=Signal(bool(True)), + ip_payload_tuser=Signal(bool(False)), + fifo=None, + pause=0, + name=None): + + ip_hdr_ready_int = Signal(bool(False)) + ip_hdr_valid_int = Signal(bool(False)) + ip_payload_pause = Signal(bool(False)) + + ip_payload_fifo = Queue() + ip_header_fifo = Queue() + + ip_payload_sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=ip_payload_tdata, + tkeep=ip_payload_tkeep, + tvalid=ip_payload_tvalid, + tready=ip_payload_tready, + tlast=ip_payload_tlast, + tuser=ip_payload_tuser, + fifo=ip_payload_fifo, + pause=ip_payload_pause) + + @always_comb + def pause_logic(): + ip_hdr_ready.next = ip_hdr_ready_int and not pause + ip_hdr_valid_int.next = ip_hdr_valid and not pause + ip_payload_pause.next = pause # or ip_hdr_valid_int + + @instance + def logic(): + frame = IPFrame() + + while True: + yield clk.posedge, rst.posedge + + if rst: + ip_hdr_ready_int.next = False + frame = IPFrame() + else: + ip_hdr_ready_int.next = True + + if ip_hdr_ready_int and ip_hdr_valid_int: + frame = IPFrame() + frame.eth_dest_mac = int(eth_dest_mac) + frame.eth_src_mac = int(eth_src_mac) + frame.eth_type = int(eth_type) + frame.ip_version = int(ip_version) + frame.ip_ihl = int(ip_ihl) + frame.ip_dscp = int(ip_dscp) + frame.ip_ecn = int(ip_ecn) + frame.ip_length = int(ip_length) + frame.ip_identification = int(ip_identification) + frame.ip_flags = int(ip_flags) + frame.ip_fragment_offset = int(ip_fragment_offset) + frame.ip_ttl = int(ip_ttl) + frame.ip_protocol = int(ip_protocol) + frame.ip_header_checksum = int(ip_header_checksum) + frame.ip_source_ip = int(ip_source_ip) + frame.ip_dest_ip = int(ip_dest_ip) + ip_header_fifo.put(frame) + + if not ip_payload_fifo.empty() and not ip_header_fifo.empty(): + frame = ip_header_fifo.get() + frame.payload = ip_payload_fifo.get() + fifo.put(frame) + + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + + frame = dict() + + return logic, pause_logic, ip_payload_sink + diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py new file mode 100755 index 000000000..ce904acbe --- /dev/null +++ b/tb/test_ip_eth_rx.py @@ -0,0 +1,996 @@ +#!/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 eth_ep +import ip_ep + +module = 'ip_eth_rx' + +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_ip_eth_rx(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + busy, + error_header_early_termination, + error_payload_early_termination, + error_invalid_header, + error_invalid_checksum): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + busy=busy, + error_header_early_termination=error_header_early_termination, + error_payload_early_termination=error_payload_early_termination, + error_invalid_header=error_invalid_header, + error_invalid_checksum=error_invalid_checksum) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + error_header_early_termination = Signal(bool(0)) + error_payload_early_termination = Signal(bool(0)) + error_invalid_header = Signal(bool(0)) + error_invalid_checksum = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_ip_eth_rx(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + busy, + error_header_early_termination, + error_payload_early_termination, + error_invalid_header, + error_invalid_checksum) + + @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 + print("test 1: test packet") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame.build() + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield output_ip_payload_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 = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = bytearray(range(256)) + test_frame.build() + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield output_ip_payload_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 3: test packet with pauses") + current_test.next = 3 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = bytearray(range(256)) + test_frame.build() + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield delay(128) + 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_ip_payload_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 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80165 + test_frame2.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame2.build() + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + + yield output_ip_payload_tlast.posedge + yield clk.posedge + yield output_ip_payload_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 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80165 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + + while input_eth_payload_tvalid or output_ip_payload_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + 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 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80165 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + + while input_eth_payload_tvalid or output_ip_payload_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + 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: alternate pause source 2") + current_test.next = 7 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80165 + test_frame2.payload = bytearray(range(33)) + test_frame2.build() + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + + while input_eth_payload_tvalid or output_ip_payload_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + 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 8: alternate pause sink 2") + current_test.next = 8 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(33)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80165 + test_frame2.payload = bytearray(range(33)) + test_frame2.build() + source_queue.put(test_frame1.build_eth()) + source_queue.put(test_frame2.build_eth()) + yield clk.posedge + + while input_eth_payload_tvalid or output_ip_payload_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + 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 9: tuser assert") + current_test.next = 9 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame.build() + eth_frame = test_frame.build_eth() + eth_frame.payload.user = 1 + + source_queue.put(eth_frame) + yield clk.posedge + + yield output_ip_payload_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.payload.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 10: truncated packet") + current_test.next = 10 + + eth_frame = eth_ep.EthFrame() + eth_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + eth_frame.eth_src_mac = 0x5A5152535455 + eth_frame.eth_type = 0x0800 + eth_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + + source_queue.put(eth_frame) + yield clk.posedge + + yield input_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + assert error_header_early_termination + + yield delay(100) + + yield clk.posedge + print("test 11: trailing bytes") + current_test.next = 11 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame.build() + eth_frame = test_frame.build_eth() + eth_frame.payload.data += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + + source_queue.put(eth_frame) + yield clk.posedge + + yield output_ip_payload_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 12: trailing bytes with tuser assert") + current_test.next = 12 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame.build() + eth_frame = test_frame.build_eth() + eth_frame.payload.data += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + eth_frame.payload.user = 1 + + source_queue.put(eth_frame) + yield clk.posedge + + yield output_ip_payload_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.payload.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 13: truncated payload") + current_test.next = 13 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = 32 + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02' + test_frame.build() + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield output_ip_payload_tlast.posedge + yield clk.posedge + assert error_payload_early_termination + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + #assert rx_frame == test_frame + assert rx_frame.payload.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 14: bad IHL") + current_test.next = 14 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 6 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame.build() + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield delay(160) + yield clk.posedge + yield clk.posedge + + assert error_invalid_header + + yield input_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + yield delay(100) + + yield clk.posedge + print("test 15: bad checksum") + current_test.next = 15 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = 0x1234 + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame.build() + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield delay(160) + yield clk.posedge + yield clk.posedge + + assert error_invalid_checksum + + yield input_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_eth_rx.v b/tb/test_ip_eth_rx.v new file mode 100644 index 000000000..1f61d1d30 --- /dev/null +++ b/tb/test_ip_eth_rx.v @@ -0,0 +1,173 @@ +/* + +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_ip_eth_rx; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [7:0] input_eth_payload_tdata = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire output_ip_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [7:0] output_ip_payload_tdata; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire busy; +wire error_header_early_termination; +wire error_payload_early_termination; +wire error_invalid_header; +wire error_invalid_checksum; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_ip_hdr_ready, + output_ip_payload_tready); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + output_ip_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + busy, + error_header_early_termination, + error_payload_early_termination, + error_invalid_header, + error_invalid_checksum); + + // dump file + $dumpfile("test_ip_eth_rx.lxt"); + $dumpvars(0, test_ip_eth_rx); +end + +ip_eth_rx +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .busy(busy), + .error_header_early_termination(error_header_early_termination), + .error_payload_early_termination(error_payload_early_termination), + .error_invalid_header(error_invalid_header), + .error_invalid_checksum(error_invalid_checksum) +); + +endmodule diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py new file mode 100755 index 000000000..9cd2db1af --- /dev/null +++ b/tb/test_ip_eth_tx.py @@ -0,0 +1,945 @@ +#!/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 eth_ep +import ip_ep + +module = 'ip_eth_tx' + +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_ip_eth_tx(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy, + error_payload_early_termination): + + 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_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + busy=busy, + error_payload_early_termination=error_payload_early_termination) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_ip_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + # Outputs + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + error_payload_early_termination = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_ip_eth_tx(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy, + error_payload_early_termination) + + @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 + + output_eth_hdr_ready.next = True + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame.build() + source_queue.put(test_frame) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = bytearray(range(256)) + test_frame.build() + source_queue.put(test_frame) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = bytearray(range(256)) + test_frame.build() + 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_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80165 + test_frame2.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame2.build() + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80165 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_ip_payload_tvalid or output_eth_payload_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() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80165 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_ip_payload_tvalid or output_eth_payload_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() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: alternate pause source 2") + current_test.next = 7 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(33)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80165 + test_frame2.payload = bytearray(range(33)) + test_frame2.build() + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_ip_payload_tvalid or output_eth_payload_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() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 8: alternate pause sink 2") + current_test.next = 8 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(33)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80165 + test_frame2.payload = bytearray(range(33)) + test_frame2.build() + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_ip_payload_tvalid or output_eth_payload_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() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 9: tuser assert") + current_test.next = 9 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame.payload.user = 1 + test_frame.build() + source_queue.put(test_frame) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + assert rx_frame.payload.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 10: trailing bytes") + current_test.next = 10 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame.build() + test_frame2 = ip_ep.IPFrame(test_frame) + test_frame2.payload.data += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + + source_queue.put(test_frame2) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + yield clk.posedge + print("test 11: trailing bytes with tuser assert") + current_test.next = 11 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' + test_frame.build() + test_frame2 = ip_ep.IPFrame(test_frame) + test_frame2.payload.data += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + test_frame2.payload.user = 1 + + source_queue.put(test_frame2) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + assert rx_frame.payload.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 13: truncated payload") + current_test.next = 13 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = 32 + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = '\x01\x02' + test_frame.build() + source_queue.put(test_frame) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + assert error_payload_early_termination + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + #assert check_frame == test_frame + assert rx_frame.payload.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_eth_tx.v b/tb/test_ip_eth_tx.v new file mode 100644 index 000000000..ab14a4efc --- /dev/null +++ b/tb/test_ip_eth_tx.v @@ -0,0 +1,155 @@ +/* + +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_ip_eth_tx; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_ip_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [7:0] input_ip_payload_tdata = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +// Outputs +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [7:0] output_eth_payload_tdata; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire busy; +wire error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_ip_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready); + $to_myhdl(input_ip_hdr_ready, + input_ip_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + busy, + error_payload_early_termination); + + // dump file + $dumpfile("test_ip_eth_tx.lxt"); + $dumpvars(0, test_ip_eth_tx); +end + +ip_eth_tx +UUT ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Status signals + .busy(busy), + .error_payload_early_termination(error_payload_early_termination) +); + +endmodule From 4d012b4f52f6cd447ad03fcb523ec93f406ca634 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 21 Sep 2014 15:53:59 -0700 Subject: [PATCH 019/617] Properly reset everything --- rtl/eth_axis_rx_64.v | 6 ++++++ rtl/eth_axis_tx_64.v | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index fbaecd882..d637772d0 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -279,12 +279,18 @@ always @(posedge clk or posedge rst) begin output_eth_src_mac_reg <= 0; output_eth_type_reg <= 0; output_eth_payload_tdata_reg <= 0; + output_eth_payload_tkeep_reg <= 0; output_eth_payload_tvalid_reg <= 0; output_eth_payload_tlast_reg <= 0; output_eth_payload_tuser_reg <= 0; temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; temp_eth_payload_tlast_reg <= 0; temp_eth_payload_tuser_reg <= 0; + save_axis_tdata_reg <= 0; + save_axis_tkeep_reg <= 0; + save_axis_tlast_reg <= 0; + save_axis_tuser_reg <= 0; busy_reg <= 0; error_header_early_termination_reg <= 0; end else begin diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index 9ac013b39..9aedb94db 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -331,12 +331,18 @@ always @(posedge clk or posedge rst) begin eth_src_mac_reg <= 0; eth_type_reg <= 0; output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; output_axis_tvalid_reg <= 0; output_axis_tlast_reg <= 0; output_axis_tuser_reg <= 0; temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; temp_axis_tlast_reg <= 0; temp_axis_tuser_reg <= 0; + save_eth_payload_tdata_reg <= 0; + save_eth_payload_tkeep_reg <= 0; + save_eth_payload_tlast_reg <= 0; + save_eth_payload_tuser_reg <= 0; busy_reg <= 0; end else begin state_reg <= state_next; From 119958cccb3ea484c8bc613337f55e6b28b8374f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 21 Sep 2014 15:54:54 -0700 Subject: [PATCH 020/617] Remove unused parameter --- rtl/ip_eth_rx.v | 1 - rtl/ip_eth_tx.v | 1 - 2 files changed, 2 deletions(-) diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index 0a5619bcd..bbe80f1cc 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -228,7 +228,6 @@ assign error_invalid_header = error_invalid_header_reg; assign error_invalid_checksum = error_invalid_checksum_reg; function [15:0] add1c16b; - parameter WIDTH = 16; input [15:0] a, b; reg [16:0] t; begin diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 76c87a472..8d301e3fe 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -185,7 +185,6 @@ assign busy = busy_reg; assign error_payload_early_termination = error_payload_early_termination_reg; function [15:0] add1c16b; - parameter WIDTH = 16; input [15:0] a, b; reg [16:0] t; begin From c74d2d11279d844e2aa074325f6f64f4641ecd3e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 21 Sep 2014 15:55:02 -0700 Subject: [PATCH 021/617] Update comment --- rtl/ip_eth_tx.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 8d301e3fe..697dea4ee 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -234,7 +234,7 @@ always @* begin end end STATE_WRITE_HEADER: begin - // read header state + // write header state if (output_eth_payload_tready) begin // word transfer out frame_ptr_next = frame_ptr_reg+1; From 3fdd453e0f896df4d52aef94926d67ca46111620 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 21 Sep 2014 15:56:12 -0700 Subject: [PATCH 022/617] Rework IP module testbenches --- tb/test_ip_eth_rx.py | 1471 +++++++++++++++++++++++------------------- tb/test_ip_eth_tx.py | 1252 +++++++++++++++++------------------ 2 files changed, 1455 insertions(+), 1268 deletions(-) diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index ce904acbe..08fc0f497 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -283,6 +283,44 @@ def bench(): def clkgen(): clk.next = not clk + error_header_early_termination_asserted = Signal(bool(0)) + error_payload_early_termination_asserted = Signal(bool(0)) + error_invalid_header_asserted = Signal(bool(0)) + error_invalid_checksum_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_header_early_termination): + error_header_early_termination_asserted.next = 1 + if (error_payload_early_termination): + error_payload_early_termination_asserted.next = 1 + if (error_invalid_header): + error_invalid_header_asserted.next = 1 + if (error_invalid_checksum): + error_invalid_checksum_asserted.next = 1 + + def wait_normal(): + while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + yield clk.posedge + + def wait_pause_source(): + while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + @instance def check(): yield delay(100) @@ -294,697 +332,834 @@ def bench(): yield delay(100) yield clk.posedge - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame.build() - source_queue.put(test_frame.build_eth()) - yield clk.posedge - - yield output_ip_payload_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 = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = bytearray(range(256)) - test_frame.build() - source_queue.put(test_frame.build_eth()) - yield clk.posedge - - yield output_ip_payload_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 3: test packet with pauses") - current_test.next = 3 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = bytearray(range(256)) - test_frame.build() - source_queue.put(test_frame.build_eth()) - yield clk.posedge - - yield delay(128) - 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_ip_payload_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 = ip_ep.IPFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x0800 - test_frame1.ip_version = 4 - test_frame1.ip_ihl = 5 - test_frame1.ip_length = None - test_frame1.ip_identification = 0 - test_frame1.ip_flags = 2 - test_frame1.ip_fragment_offset = 0 - test_frame1.ip_ttl = 64 - test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = None - test_frame1.ip_source_ip = 0xc0a80164 - test_frame1.ip_dest_ip = 0xc0a80165 - test_frame1.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame1.build() - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x11 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame2.build() - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) - yield clk.posedge - - yield output_ip_payload_tlast.posedge - yield clk.posedge - yield output_ip_payload_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 = ip_ep.IPFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x0800 - test_frame1.ip_version = 4 - test_frame1.ip_ihl = 5 - test_frame1.ip_length = None - test_frame1.ip_identification = 0 - test_frame1.ip_flags = 2 - test_frame1.ip_fragment_offset = 0 - test_frame1.ip_ttl = 64 - test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = None - test_frame1.ip_source_ip = 0xc0a80164 - test_frame1.ip_dest_ip = 0xc0a80165 - test_frame1.payload = bytearray(range(32)) - test_frame1.build() - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x11 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = bytearray(range(32)) - test_frame2.build() - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) - yield clk.posedge - - while input_eth_payload_tvalid or output_ip_payload_tvalid: - source_pause.next = True + for payload_len in range(1,18): yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = bytearray(range(payload_len)) + test_frame.build() + eth_frame = test_frame.build_eth() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge - source_pause.next = False + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 4: trailing bytes (1), length %d" % payload_len) + current_test.next = 4 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() - assert rx_frame == test_frame1 + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + eth_frame1.payload.data += bytearray(b'\x00') - assert rx_frame == test_frame2 + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge - yield delay(100) + yield wait() - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 + yield clk.posedge + yield clk.posedge - test_frame1 = ip_ep.IPFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x0800 - test_frame1.ip_version = 4 - test_frame1.ip_ihl = 5 - test_frame1.ip_length = None - test_frame1.ip_identification = 0 - test_frame1.ip_flags = 2 - test_frame1.ip_fragment_offset = 0 - test_frame1.ip_ttl = 64 - test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = None - test_frame1.ip_source_ip = 0xc0a80164 - test_frame1.ip_dest_ip = 0xc0a80165 - test_frame1.payload = bytearray(range(32)) - test_frame1.build() - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x11 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = bytearray(range(32)) - test_frame2.build() - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) - while input_eth_payload_tvalid or output_ip_payload_tvalid: - sink_pause.next = True yield clk.posedge + print("test 5: trailing bytes (10), length %d" % payload_len) + current_test.next = 5 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data += bytearray(b'\x00'*10) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 6: trailing bytes with tuser assert (1), length %d" % payload_len) + current_test.next = 6 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data += bytearray(b'\x00') + eth_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge - sink_pause.next = False + print("test 7: trailing bytes with tuser assert (10), length %d" % payload_len) + current_test.next = 7 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data += bytearray(b'\x00'*10) + eth_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 8: truncated payload (1), length %d" % payload_len) + current_test.next = 8 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len+1)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() - assert rx_frame == test_frame1 + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + eth_frame1.payload.data = eth_frame1.payload.data[:-1] - assert rx_frame == test_frame2 + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 - yield delay(100) + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge - yield clk.posedge - print("test 7: alternate pause source 2") - current_test.next = 7 + yield wait() - test_frame1 = ip_ep.IPFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x0800 - test_frame1.ip_version = 4 - test_frame1.ip_ihl = 5 - test_frame1.ip_length = None - test_frame1.ip_identification = 0 - test_frame1.ip_flags = 2 - test_frame1.ip_fragment_offset = 0 - test_frame1.ip_ttl = 64 - test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = None - test_frame1.ip_source_ip = 0xc0a80164 - test_frame1.ip_dest_ip = 0xc0a80165 - test_frame1.payload = bytearray(range(32)) - test_frame1.build() - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x11 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = bytearray(range(33)) - test_frame2.build() - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) - 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.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) - while input_eth_payload_tvalid or output_ip_payload_tvalid: - source_pause.next = True yield clk.posedge + print("test 9: truncated payload (10), length %d" % payload_len) + current_test.next = 9 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len+10)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data = eth_frame1.payload.data[:-10] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 10: bad IHL, length %d" % payload_len) + current_test.next = 10 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 6 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_invalid_header_asserted.next = 0 + + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + assert error_invalid_header_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge - source_pause.next = False + print("test 11: bad checksum, length %d" % payload_len) + current_test.next = 11 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = 0x1234 + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_invalid_checksum_asserted.next = 0 + + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + assert error_invalid_checksum_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + for length in range(1,20): yield clk.posedge + print("test 12: truncated header, length %d" % length) + current_test.next = 12 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = 0x1234 + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(16)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(16)) + test_frame2.build() - assert rx_frame == test_frame1 + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + eth_frame1.payload.data = eth_frame1.payload.data[:length] - assert rx_frame == test_frame2 + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_header_early_termination_asserted.next = 0 - yield delay(100) + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge - yield clk.posedge - print("test 8: alternate pause sink 2") - current_test.next = 8 + yield wait() - test_frame1 = ip_ep.IPFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x0800 - test_frame1.ip_version = 4 - test_frame1.ip_ihl = 5 - test_frame1.ip_length = None - test_frame1.ip_identification = 0 - test_frame1.ip_flags = 2 - test_frame1.ip_fragment_offset = 0 - test_frame1.ip_ttl = 64 - test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = None - test_frame1.ip_source_ip = 0xc0a80164 - test_frame1.ip_dest_ip = 0xc0a80165 - test_frame1.payload = bytearray(range(33)) - test_frame1.build() - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x11 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = bytearray(range(33)) - test_frame2.build() - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) - yield clk.posedge + yield clk.posedge + yield clk.posedge - while input_eth_payload_tvalid or output_ip_payload_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge + assert error_header_early_termination_asserted - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert sink_queue.empty() - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 9: tuser assert") - current_test.next = 9 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame.build() - eth_frame = test_frame.build_eth() - eth_frame.payload.user = 1 - - source_queue.put(eth_frame) - yield clk.posedge - - yield output_ip_payload_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.payload.user[-1] - - yield delay(100) - - yield clk.posedge - print("test 10: truncated packet") - current_test.next = 10 - - eth_frame = eth_ep.EthFrame() - eth_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - eth_frame.eth_src_mac = 0x5A5152535455 - eth_frame.eth_type = 0x0800 - eth_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - - source_queue.put(eth_frame) - yield clk.posedge - - yield input_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - assert error_header_early_termination - - yield delay(100) - - yield clk.posedge - print("test 11: trailing bytes") - current_test.next = 11 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame.build() - eth_frame = test_frame.build_eth() - eth_frame.payload.data += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' - - source_queue.put(eth_frame) - yield clk.posedge - - yield output_ip_payload_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 12: trailing bytes with tuser assert") - current_test.next = 12 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame.build() - eth_frame = test_frame.build_eth() - eth_frame.payload.data += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' - eth_frame.payload.user = 1 - - source_queue.put(eth_frame) - yield clk.posedge - - yield output_ip_payload_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.payload.user[-1] - - yield delay(100) - - yield clk.posedge - print("test 13: truncated payload") - current_test.next = 13 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = 32 - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02' - test_frame.build() - source_queue.put(test_frame.build_eth()) - yield clk.posedge - - yield output_ip_payload_tlast.posedge - yield clk.posedge - assert error_payload_early_termination - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - #assert rx_frame == test_frame - assert rx_frame.payload.user[-1] - - yield delay(100) - - yield clk.posedge - print("test 14: bad IHL") - current_test.next = 14 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 6 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame.build() - source_queue.put(test_frame.build_eth()) - yield clk.posedge - - yield delay(160) - yield clk.posedge - yield clk.posedge - - assert error_invalid_header - - yield input_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - - yield delay(100) - - yield clk.posedge - print("test 15: bad checksum") - current_test.next = 15 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = 0x1234 - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame.build() - source_queue.put(test_frame.build_eth()) - yield clk.posedge - - yield delay(160) - yield clk.posedge - yield clk.posedge - - assert error_invalid_checksum - - yield input_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - - yield delay(100) + yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source, sink, clkgen, monitor, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py index 9cd2db1af..9ae3f7453 100755 --- a/tb/test_ip_eth_tx.py +++ b/tb/test_ip_eth_tx.py @@ -256,6 +256,35 @@ def bench(): def clkgen(): clk.next = not clk + error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_payload_early_termination): + error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + + def wait_pause_source(): + while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + @instance def check(): yield delay(100) @@ -267,673 +296,656 @@ def bench(): yield delay(100) yield clk.posedge - output_eth_hdr_ready.next = True - yield clk.posedge - - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame.build() - source_queue.put(test_frame) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - assert check_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = bytearray(range(256)) - test_frame.build() - source_queue.put(test_frame) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - assert check_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = bytearray(range(256)) - test_frame.build() - 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_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - assert check_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = ip_ep.IPFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x0800 - test_frame1.ip_version = 4 - test_frame1.ip_ihl = 5 - test_frame1.ip_length = None - test_frame1.ip_identification = 0 - test_frame1.ip_flags = 2 - test_frame1.ip_fragment_offset = 0 - test_frame1.ip_ttl = 64 - test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = None - test_frame1.ip_source_ip = 0xc0a80164 - test_frame1.ip_dest_ip = 0xc0a80165 - test_frame1.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame1.build() - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x11 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame2.build() - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - assert check_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - assert check_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = ip_ep.IPFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x0800 - test_frame1.ip_version = 4 - test_frame1.ip_ihl = 5 - test_frame1.ip_length = None - test_frame1.ip_identification = 0 - test_frame1.ip_flags = 2 - test_frame1.ip_fragment_offset = 0 - test_frame1.ip_ttl = 64 - test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = None - test_frame1.ip_source_ip = 0xc0a80164 - test_frame1.ip_dest_ip = 0xc0a80165 - test_frame1.payload = bytearray(range(32)) - test_frame1.build() - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x11 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = bytearray(range(32)) - test_frame2.build() - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_ip_payload_tvalid or output_eth_payload_tvalid: - source_pause.next = True + for payload_len in range(1,18): yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = bytearray(range(payload_len)) + test_frame.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge - source_pause.next = False + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 4: trailing bytes (1), length %d" % payload_len) + current_test.next = 4 - yield clk.posedge - yield clk.posedge + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00') - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge - assert check_frame == test_frame1 + yield wait() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + yield clk.posedge + yield clk.posedge - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - assert check_frame == test_frame2 + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) - yield delay(100) + assert check_frame == test_frame1 - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame1 = ip_ep.IPFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x0800 - test_frame1.ip_version = 4 - test_frame1.ip_ihl = 5 - test_frame1.ip_length = None - test_frame1.ip_identification = 0 - test_frame1.ip_flags = 2 - test_frame1.ip_fragment_offset = 0 - test_frame1.ip_ttl = 64 - test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = None - test_frame1.ip_source_ip = 0xc0a80164 - test_frame1.ip_dest_ip = 0xc0a80165 - test_frame1.payload = bytearray(range(32)) - test_frame1.build() - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x11 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = bytearray(range(32)) - test_frame2.build() - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) - while input_ip_payload_tvalid or output_eth_payload_tvalid: - sink_pause.next = True yield clk.posedge + print("test 5: trailing bytes (10), length %d" % payload_len) + current_test.next = 5 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00'*10) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 6: trailing bytes with tuser assert (1), length %d" % payload_len) + current_test.next = 6 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00') + test_frame1a.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge - sink_pause.next = False + print("test 7: trailing bytes with tuser assert (10), length %d" % payload_len) + current_test.next = 7 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00'*10) + test_frame1a.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 8: truncated payload (1), length %d" % payload_len) + current_test.next = 8 - yield clk.posedge - yield clk.posedge + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len+1)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data = test_frame1a.payload.data[:-1] - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 - assert check_frame == test_frame1 + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + yield wait() - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) + yield clk.posedge + yield clk.posedge - assert check_frame == test_frame2 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - yield delay(100) + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted - yield clk.posedge - print("test 7: alternate pause source 2") - current_test.next = 7 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame1 = ip_ep.IPFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x0800 - test_frame1.ip_version = 4 - test_frame1.ip_ihl = 5 - test_frame1.ip_length = None - test_frame1.ip_identification = 0 - test_frame1.ip_flags = 2 - test_frame1.ip_fragment_offset = 0 - test_frame1.ip_ttl = 64 - test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = None - test_frame1.ip_source_ip = 0xc0a80164 - test_frame1.ip_dest_ip = 0xc0a80165 - test_frame1.payload = bytearray(range(33)) - test_frame1.build() - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x11 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = bytearray(range(33)) - test_frame2.build() - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) - while input_ip_payload_tvalid or output_eth_payload_tvalid: - source_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - source_pause.next = False yield clk.posedge + print("test 9: truncated payload (10), length %d" % payload_len) + current_test.next = 9 - yield clk.posedge - yield clk.posedge + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len+10)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data = test_frame1a.payload.data[:-10] - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 - assert check_frame == test_frame1 + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + yield wait() - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) + yield clk.posedge + yield clk.posedge - assert check_frame == test_frame2 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - yield delay(100) + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted - yield clk.posedge - print("test 8: alternate pause sink 2") - current_test.next = 8 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame1 = ip_ep.IPFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x0800 - test_frame1.ip_version = 4 - test_frame1.ip_ihl = 5 - test_frame1.ip_length = None - test_frame1.ip_identification = 0 - test_frame1.ip_flags = 2 - test_frame1.ip_fragment_offset = 0 - test_frame1.ip_ttl = 64 - test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = None - test_frame1.ip_source_ip = 0xc0a80164 - test_frame1.ip_dest_ip = 0xc0a80165 - test_frame1.payload = bytearray(range(33)) - test_frame1.build() - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x11 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = bytearray(range(33)) - test_frame2.build() - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) - while input_ip_payload_tvalid or output_eth_payload_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge + assert check_frame == test_frame2 - yield clk.posedge - yield clk.posedge + assert sink_queue.empty() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - assert check_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - assert check_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 9: tuser assert") - current_test.next = 9 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame.payload.user = 1 - test_frame.build() - source_queue.put(test_frame) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - assert check_frame == test_frame - assert rx_frame.payload.user[-1] - - yield delay(100) - - yield clk.posedge - print("test 10: trailing bytes") - current_test.next = 10 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame.build() - test_frame2 = ip_ep.IPFrame(test_frame) - test_frame2.payload.data += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' - - source_queue.put(test_frame2) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - assert check_frame == test_frame - - yield clk.posedge - print("test 11: trailing bytes with tuser assert") - current_test.next = 11 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C' - test_frame.build() - test_frame2 = ip_ep.IPFrame(test_frame) - test_frame2.payload.data += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' - test_frame2.payload.user = 1 - - source_queue.put(test_frame2) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - assert check_frame == test_frame - assert rx_frame.payload.user[-1] - - yield delay(100) - - yield clk.posedge - print("test 13: truncated payload") - current_test.next = 13 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = 32 - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = '\x01\x02' - test_frame.build() - source_queue.put(test_frame) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - assert error_payload_early_termination - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = ip_ep.IPFrame() - check_frame.parse_eth(rx_frame) - - #assert check_frame == test_frame - assert rx_frame.payload.user[-1] - - yield delay(100) + yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source, sink, clkgen, monitor, check def test_bench(): sim = Simulation(bench()) From c9a2b89717a1302836eb1547f3952f30be6c9c7c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Sep 2014 01:12:48 -0700 Subject: [PATCH 023/617] Remove unused register --- rtl/ip_eth_tx.v | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 697dea4ee..9c58d53a6 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -137,7 +137,6 @@ reg assert_tuser; reg [15:0] frame_ptr_reg = 0, frame_ptr_next; reg [15:0] hdr_sum_reg = 0, hdr_sum_next; -reg [15:0] payload_len_reg = 0, payload_len_next; reg [5:0] ip_dscp_reg = 0; reg [1:0] ip_ecn_reg = 0; @@ -211,7 +210,6 @@ always @* begin frame_ptr_next = frame_ptr_reg; hdr_sum_next = hdr_sum_reg; - payload_len_next = payload_len_reg; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; @@ -421,7 +419,6 @@ always @(posedge clk or posedge rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; hdr_sum_reg <= 0; - payload_len_reg <= 0; input_ip_hdr_ready_reg <= 0; input_ip_payload_tready_reg <= 0; ip_dscp_reg <= 0; @@ -453,7 +450,6 @@ always @(posedge clk or posedge rst) begin frame_ptr_reg <= frame_ptr_next; hdr_sum_reg <= hdr_sum_next; - payload_len_reg <= payload_len_next; output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; From 5eaba1c3b32da77cf46f01782e7cb7993b59c327 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Sep 2014 23:52:41 -0700 Subject: [PATCH 024/617] Do not clock out a header if the last signal falls on the last word --- rtl/ip_eth_rx.v | 1 + 1 file changed, 1 insertion(+) diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index bbe80f1cc..35a1da1b8 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -343,6 +343,7 @@ always @* begin if (input_eth_payload_tlast) begin state_next = STATE_IDLE; + output_ip_hdr_valid_next = 0; error_header_early_termination_next = 1; end From 33a61d8d893e13086b7dc6749a0ddc4c5eb11a87 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Sep 2014 00:36:08 -0700 Subject: [PATCH 025/617] Rework Ethernet module testbenches --- tb/test_eth_axis_rx.py | 514 ++++++++++++++------------------------ tb/test_eth_axis_rx_64.py | 514 ++++++++++++++------------------------ tb/test_eth_axis_tx.py | 483 +++++++++++------------------------ tb/test_eth_axis_tx_64.py | 483 +++++++++++------------------------ 4 files changed, 660 insertions(+), 1334 deletions(-) diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index 9bfbb298e..2f539f4fc 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -181,6 +181,35 @@ def bench(): def clkgen(): clk.next = not clk + error_header_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_header_early_termination): + error_header_early_termination_asserted.next = 1 + + def wait_normal(): + while input_axis_tvalid or output_eth_payload_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_eth_payload_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_eth_payload_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + @instance def check(): yield delay(100) @@ -192,350 +221,185 @@ def bench(): yield delay(100) yield clk.posedge - yield clk.posedge - print("test 1: test packet") - 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - source_queue.put(test_frame.build_axis()) - yield clk.posedge - - yield output_eth_payload_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 = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray(range(256)) - source_queue.put(test_frame.build_axis()) - yield clk.posedge - - yield output_eth_payload_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 3: test packet with pauses") - current_test.next = 3 - - 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(range(256)) - source_queue.put(test_frame.build_axis()) - 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_eth_payload_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 = eth_ep.EthFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x8000 - test_frame1.payload = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - 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 = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - source_queue.put(test_frame1.build_axis()) - source_queue.put(test_frame2.build_axis()) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield output_eth_payload_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 = eth_ep.EthFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x8000 - test_frame1.payload = bytearray(range(32)) - 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(range(32)) - source_queue.put(test_frame1.build_axis()) - source_queue.put(test_frame2.build_axis()) - yield clk.posedge - - while input_axis_tvalid or output_eth_payload_tvalid: - source_pause.next = True + for payload_len in range(1,18): yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.payload = bytearray(range(payload_len)) + + axis_frame = test_frame.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(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(range(payload_len)) + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge - source_pause.next = False + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + 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(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(range(payload_len)) + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + for length in range(1,15): yield clk.posedge + print("test 4: truncated packet, length %d" % length) + current_test.next = 4 - yield clk.posedge - yield clk.posedge + 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(range(16)) + 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(range(16)) - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() - assert rx_frame == test_frame1 + axis_frame1.data = axis_frame1.data[:length] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_header_early_termination_asserted.next = 0 - assert rx_frame == test_frame2 + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge - yield delay(100) + yield wait() - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 + yield clk.posedge + yield clk.posedge + yield clk.posedge - 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(range(32)) - 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(range(32)) - source_queue.put(test_frame1.build_axis()) - source_queue.put(test_frame2.build_axis()) - yield clk.posedge + assert error_header_early_termination_asserted - while input_axis_tvalid or output_eth_payload_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - yield clk.posedge - yield clk.posedge + assert rx_frame == test_frame2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert sink_queue.empty() - 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: alternate pause source 2") - current_test.next = 7 - - 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(range(33)) - 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(range(33)) - source_queue.put(test_frame1.build_axis()) - source_queue.put(test_frame2.build_axis()) - yield clk.posedge - - while input_axis_tvalid or output_eth_payload_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 8: alternate pause sink 2") - current_test.next = 8 - - 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(range(33)) - 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(range(33)) - source_queue.put(test_frame1.build_axis()) - source_queue.put(test_frame2.build_axis()) - yield clk.posedge - - while input_axis_tvalid or output_eth_payload_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 9: tuser assert") - current_test.next = 9 - - 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - axi_frame = test_frame.build_axis() - axi_frame.user = 1 - - source_queue.put(axi_frame) - yield clk.posedge - - yield output_eth_payload_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.payload.user[-1] - - yield delay(100) - - yield clk.posedge - print("test 10: truncated packet") - current_test.next = 10 - - test_frame = axis_ep.AXIStreamFrame() - test_frame.data = bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09') - source_queue.put(test_frame) - yield clk.posedge - - yield input_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - assert error_header_early_termination - - yield delay(100) + yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source, sink, clkgen, monitor, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index 4e4c4f875..f8cb1e9d5 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -191,6 +191,35 @@ def bench(): def clkgen(): clk.next = not clk + error_header_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_header_early_termination): + error_header_early_termination_asserted.next = 1 + + def wait_normal(): + while input_axis_tvalid or output_eth_payload_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_eth_payload_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_eth_payload_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + @instance def check(): yield delay(100) @@ -202,350 +231,185 @@ def bench(): yield delay(100) yield clk.posedge - yield clk.posedge - print("test 1: test packet") - 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - source_queue.put(test_frame.build_axis()) - yield clk.posedge - - yield output_eth_payload_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 = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray(range(256)) - source_queue.put(test_frame.build_axis()) - yield clk.posedge - - yield output_eth_payload_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 3: test packet with pauses") - current_test.next = 3 - - 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(range(256)) - source_queue.put(test_frame.build_axis()) - 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_eth_payload_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 = eth_ep.EthFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x8000 - test_frame1.payload = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - 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 = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - source_queue.put(test_frame1.build_axis()) - source_queue.put(test_frame2.build_axis()) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield output_eth_payload_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 = eth_ep.EthFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x8000 - test_frame1.payload = bytearray(range(32)) - 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(range(32)) - source_queue.put(test_frame1.build_axis()) - source_queue.put(test_frame2.build_axis()) - yield clk.posedge - - while input_axis_tvalid or output_eth_payload_tvalid: - source_pause.next = True + for payload_len in range(1,18): yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.payload = bytearray(range(payload_len)) + + axis_frame = test_frame.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(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(range(payload_len)) + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge - source_pause.next = False + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + 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(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(range(payload_len)) + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + for length in range(1,15): yield clk.posedge + print("test 4: truncated packet, length %d" % length) + current_test.next = 4 - yield clk.posedge - yield clk.posedge + 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(range(16)) + 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(range(16)) - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() - assert rx_frame == test_frame1 + axis_frame1.data = axis_frame1.data[:length] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_header_early_termination_asserted.next = 0 - assert rx_frame == test_frame2 + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge - yield delay(100) + yield wait() - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 + yield clk.posedge + yield clk.posedge + yield clk.posedge - 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(range(32)) - 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(range(32)) - source_queue.put(test_frame1.build_axis()) - source_queue.put(test_frame2.build_axis()) - yield clk.posedge + assert error_header_early_termination_asserted - while input_axis_tvalid or output_eth_payload_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - yield clk.posedge - yield clk.posedge + assert rx_frame == test_frame2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert sink_queue.empty() - 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: alternate pause source 2") - current_test.next = 7 - - 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(range(33)) - 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(range(33)) - source_queue.put(test_frame1.build_axis()) - source_queue.put(test_frame2.build_axis()) - yield clk.posedge - - while input_axis_tvalid or output_eth_payload_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 8: alternate pause sink 2") - current_test.next = 8 - - 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(range(33)) - 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(range(33)) - source_queue.put(test_frame1.build_axis()) - source_queue.put(test_frame2.build_axis()) - yield clk.posedge - - while input_axis_tvalid or output_eth_payload_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 9: tuser assert") - current_test.next = 9 - - 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - axi_frame = test_frame.build_axis() - axi_frame.user = 1 - - source_queue.put(axi_frame) - yield clk.posedge - - yield output_eth_payload_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.payload.user[-1] - - yield delay(100) - - yield clk.posedge - print("test 10: truncated packet") - current_test.next = 10 - - test_frame = axis_ep.AXIStreamFrame() - test_frame.data = bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09') - source_queue.put(test_frame) - yield clk.posedge - - yield input_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - assert error_header_early_termination - - yield delay(100) + yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source, sink, clkgen, monitor, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py index 8b8a41fcb..d33a649af 100755 --- a/tb/test_eth_axis_tx.py +++ b/tb/test_eth_axis_tx.py @@ -177,6 +177,28 @@ def bench(): def clkgen(): clk.next = not clk + def wait_normal(): + while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + yield clk.posedge + + def wait_pause_source(): + while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + @instance def check(): yield delay(100) @@ -188,364 +210,141 @@ def bench(): yield delay(100) yield clk.posedge - yield clk.posedge - print("test 1: test packet") - 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - source_queue.put(test_frame) - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 - - 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(range(256)) - source_queue.put(test_frame) - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 - - 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(range(256)) - source_queue.put(test_frame) - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_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() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - 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 = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - 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 = b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - source_queue.put(test_frame1) - source_queue.put(test_frame2) - - yield output_axis_tlast.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() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - 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(range(32)) - 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(range(32)) - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_eth_payload_tvalid: - source_pause.next = True + for payload_len in range(1,18): yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.payload = bytearray(range(payload_len)) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(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(range(payload_len)) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge - source_pause.next = False - yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 - yield clk.posedge - yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + 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(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(range(payload_len)) - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) + test_frame1.payload.user = 1 - assert check_frame == test_frame1 + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + yield wait() - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge - assert check_frame == test_frame2 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - yield delay(100) + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 + assert check_frame == test_frame1 + assert rx_frame.user[-1] + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - 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(range(32)) - 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(range(32)) - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) - while input_eth_payload_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 + assert check_frame == test_frame2 - yield clk.posedge - yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert sink_queue.empty() - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 7: alternate pause source 2") - current_test.next = 7 - - 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(range(33)) - 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(range(33)) - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_eth_payload_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() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 8: alternate pause sink 2") - current_test.next = 8 - - 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(range(33)) - 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(range(33)) - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_eth_payload_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() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 9: tuser assert") - current_test.next = 9 - - 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - test_frame.payload.user = 1 - source_queue.put(test_frame) - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - assert rx_frame.user[-1] - - yield delay(100) + yield delay(100) raise StopSimulation diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py index d5f8fb58b..c877a68a7 100755 --- a/tb/test_eth_axis_tx_64.py +++ b/tb/test_eth_axis_tx_64.py @@ -187,6 +187,28 @@ def bench(): def clkgen(): clk.next = not clk + def wait_normal(): + while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + yield clk.posedge + + def wait_pause_source(): + while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + @instance def check(): yield delay(100) @@ -198,364 +220,141 @@ def bench(): yield delay(100) yield clk.posedge - yield clk.posedge - print("test 1: test packet") - 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - source_queue.put(test_frame) - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 - - 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(range(256)) - source_queue.put(test_frame) - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 - - 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(range(256)) - source_queue.put(test_frame) - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_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() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - 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 = b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - 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 = b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - source_queue.put(test_frame1) - source_queue.put(test_frame2) - - yield output_axis_tlast.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() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - 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(range(32)) - 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(range(32)) - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_eth_payload_tvalid: - source_pause.next = True + for payload_len in range(1,18): yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.payload = bytearray(range(payload_len)) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(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(range(payload_len)) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + yield clk.posedge - source_pause.next = False - yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 - yield clk.posedge - yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + 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(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(range(payload_len)) - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) + test_frame1.payload.user = 1 - assert check_frame == test_frame1 + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + yield wait() - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge - assert check_frame == test_frame2 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - yield delay(100) + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 + assert check_frame == test_frame1 + assert rx_frame.user[-1] + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - 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(range(32)) - 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(range(32)) - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge + check_frame = eth_ep.EthFrame() + check_frame.parse_axis(rx_frame) - while input_eth_payload_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 + assert check_frame == test_frame2 - yield clk.posedge - yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert sink_queue.empty() - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 7: alternate pause source 2") - current_test.next = 7 - - 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(range(33)) - 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(range(33)) - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_eth_payload_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() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 8: alternate pause sink 2") - current_test.next = 8 - - 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(range(33)) - 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(range(33)) - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_eth_payload_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() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 9: tuser assert") - current_test.next = 9 - - 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 = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' - test_frame.payload.user = 1 - source_queue.put(test_frame) - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - assert rx_frame.user[-1] - - yield delay(100) + yield delay(100) raise StopSimulation From ac57a22050804f139cd75ef88995e35104c71f5d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Sep 2014 00:37:14 -0700 Subject: [PATCH 026/617] Abort with early termination error on last assert on first header word --- rtl/eth_axis_rx.v | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index 30617a865..ebc3c6d1c 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -180,6 +180,10 @@ always @* begin frame_ptr_next = 1; store_eth_dest_mac_5 = 1; state_next = STATE_READ_HEADER; + if (input_axis_tlast) begin + state_next = STATE_IDLE; + error_header_early_termination_next = 1; + end end else begin state_next = STATE_IDLE; end From d052bbb2bf89285702c3da5a8a9ea8e07eacb521 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Sep 2014 00:38:36 -0700 Subject: [PATCH 027/617] Update 64-bit ethernet modules with lane shifting logic --- rtl/eth_axis_rx_64.v | 112 +++++++++++++++++++------------ rtl/eth_axis_tx_64.v | 155 ++++++++++++++++++++++++++----------------- 2 files changed, 165 insertions(+), 102 deletions(-) diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index d637772d0..97c17210b 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -95,6 +95,7 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_hdr_word_0; reg store_hdr_word_1; +reg flush_save; reg transfer_in_save; reg transfer_save_out; reg transfer_in_out; @@ -109,7 +110,7 @@ reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; reg [47:0] output_eth_src_mac_reg = 0; reg [15:0] output_eth_type_reg = 0; -reg [63:0] output_eth_payload_tdata_reg = 0; +reg [63:0] output_eth_payload_tdata_reg = 0; reg [7:0] output_eth_payload_tkeep_reg = 0; reg output_eth_payload_tvalid_reg = 0; reg output_eth_payload_tlast_reg = 0; @@ -128,6 +129,14 @@ reg [7:0] save_axis_tkeep_reg = 0; reg save_axis_tlast_reg = 0; reg save_axis_tuser_reg = 0; +reg [63:0] shift_axis_tdata; +reg [7:0] shift_axis_tkeep; +reg shift_axis_tvalid; +reg shift_axis_tlast; +reg shift_axis_tuser; +reg shift_axis_input_tready; +reg shift_axis_extra_cycle; + assign input_axis_tready = input_axis_tready_reg; assign output_eth_hdr_valid = output_eth_hdr_valid_reg; @@ -143,9 +152,32 @@ assign output_eth_payload_tuser = output_eth_payload_tuser_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; +always @* begin + shift_axis_tdata[15:0] = save_axis_tdata_reg[63:48]; + shift_axis_tkeep[1:0] = save_axis_tkeep_reg[7:6]; + shift_axis_extra_cycle = save_axis_tlast_reg & (save_axis_tkeep_reg[7:6] != 0); + + if (shift_axis_extra_cycle) begin + shift_axis_tdata[63:16] = 0; + shift_axis_tkeep[7:2] = 0; + shift_axis_tvalid = 1; + shift_axis_tlast = save_axis_tlast_reg; + shift_axis_tuser = save_axis_tuser_reg; + shift_axis_input_tready = flush_save; + end else begin + shift_axis_tdata[63:16] = input_axis_tdata[47:0]; + shift_axis_tkeep[7:2] = input_axis_tkeep[5:0]; + shift_axis_tvalid = input_axis_tvalid; + shift_axis_tlast = (input_axis_tlast & (input_axis_tkeep[7:6] == 0)); + shift_axis_tuser = (input_axis_tuser & (input_axis_tkeep[7:6] == 0)); + shift_axis_input_tready = ~(input_axis_tlast & input_axis_tvalid & transfer_in_save); + end +end + always @* begin state_next = 2'bz; + flush_save = 0; transfer_in_save = 0; transfer_save_out = 0; transfer_in_out = 0; @@ -165,12 +197,17 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + flush_save = 1; if (input_axis_tready & input_axis_tvalid) begin frame_ptr_next = 8; store_hdr_word_0 = 1; transfer_in_save = 1; state_next = STATE_READ_HEADER; + if (input_axis_tlast) begin + state_next = STATE_IDLE; + error_header_early_termination_next = 1; + end end else begin state_next = STATE_IDLE; end @@ -190,8 +227,9 @@ always @* begin state_next = STATE_READ_PAYLOAD_IDLE; end endcase - if (input_axis_tlast) begin + if (shift_axis_tlast) begin state_next = STATE_IDLE; + output_eth_hdr_valid_next = 0; error_header_early_termination_next = 1; end end else begin @@ -200,11 +238,11 @@ always @* begin end STATE_READ_PAYLOAD_IDLE: begin // idle; no data in registers - if (input_axis_tvalid) begin + if (shift_axis_tvalid) begin // word transfer in - store it in output register transfer_in_out = 1; transfer_in_save = 1; - if (input_axis_tlast) begin + if (shift_axis_tlast) begin state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; end else begin state_next = STATE_READ_PAYLOAD_TRANSFER; @@ -215,19 +253,19 @@ always @* begin end STATE_READ_PAYLOAD_TRANSFER: begin // read payload; data in output register - if (input_axis_tvalid & output_eth_payload_tready) begin + if (shift_axis_tvalid & output_eth_payload_tready) begin // word transfer through - update output register transfer_in_out = 1; transfer_in_save = 1; - if (input_axis_tlast) begin + if (shift_axis_tlast) begin state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; end else begin state_next = STATE_READ_PAYLOAD_TRANSFER; end - end else if (~input_axis_tvalid & output_eth_payload_tready) begin + end else if (~shift_axis_tvalid & output_eth_payload_tready) begin // word transfer out - go back to idle state_next = STATE_READ_PAYLOAD_IDLE; - end else if (input_axis_tvalid & ~output_eth_payload_tready) begin + end else if (shift_axis_tvalid & ~output_eth_payload_tready) begin // word transfer in - store in temp transfer_in_temp = 1; transfer_in_save = 1; @@ -241,7 +279,7 @@ always @* begin if (output_eth_payload_tready) begin // transfer out - move temp to output transfer_temp_out = 1; - if (temp_eth_payload_tlast_reg | (save_axis_tlast_reg & save_axis_tkeep_reg[7:6] != 0)) begin + if (temp_eth_payload_tlast_reg) begin state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; end else begin state_next = STATE_READ_PAYLOAD_TRANSFER; @@ -254,14 +292,7 @@ always @* begin // read last payload word; data in output register; do not accept new data if (output_eth_payload_tready) begin // word transfer out - if (save_axis_tkeep_reg[7:6]) begin - // part of word in save register - transfer_save_out = 1; - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - // nothing in save register; done - state_next = STATE_IDLE; - end + state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; end @@ -313,17 +344,17 @@ always @(posedge clk or posedge rst) begin end STATE_READ_HEADER: begin // read header; accept new data - input_axis_tready_reg <= 1; + input_axis_tready_reg <= shift_axis_input_tready; output_eth_payload_tvalid_reg <= 0; end STATE_READ_PAYLOAD_IDLE: begin // read payload; no data in registers; accept new data - input_axis_tready_reg <= 1; + input_axis_tready_reg <= shift_axis_input_tready; output_eth_payload_tvalid_reg <= 0; end STATE_READ_PAYLOAD_TRANSFER: begin // read payload; data in output register; accept new data - input_axis_tready_reg <= 1; + input_axis_tready_reg <= shift_axis_input_tready; output_eth_payload_tvalid_reg <= 1; end STATE_READ_PAYLOAD_TRANSFER_WAIT: begin @@ -358,35 +389,34 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg[ 7:0] <= input_axis_tdata[47:40]; end - if (transfer_in_save) begin - save_axis_tdata_reg <= input_axis_tdata; - save_axis_tkeep_reg <= input_axis_tkeep; - save_axis_tlast_reg <= input_axis_tlast; - save_axis_tuser_reg <= input_axis_tuser; - end else if (transfer_save_out) begin - output_eth_payload_tdata_reg <= {48'd0, save_axis_tdata_reg[63:48]}; - output_eth_payload_tkeep_reg <= {6'd0, save_axis_tkeep_reg[7:6]}; - output_eth_payload_tlast_reg <= save_axis_tlast_reg; - output_eth_payload_tuser_reg <= save_axis_tuser_reg; - save_axis_tkeep_reg <= 0; - end - if (transfer_in_out) begin - output_eth_payload_tdata_reg <= {input_axis_tdata[47:0], save_axis_tdata_reg[63:48]}; - output_eth_payload_tkeep_reg <= {input_axis_tkeep[5:0], save_axis_tkeep_reg[7:6]}; - output_eth_payload_tlast_reg <= input_axis_tlast & (input_axis_tkeep[7:6] == 0); - output_eth_payload_tuser_reg <= input_axis_tuser & (input_axis_tkeep[7:6] == 0); + output_eth_payload_tdata_reg <= shift_axis_tdata; + output_eth_payload_tkeep_reg <= shift_axis_tkeep; + output_eth_payload_tlast_reg <= shift_axis_tlast; + output_eth_payload_tuser_reg <= shift_axis_tuser; end else if (transfer_in_temp) begin - temp_eth_payload_tdata_reg <= {input_axis_tdata[47:0], save_axis_tdata_reg[63:48]}; - temp_eth_payload_tkeep_reg <= {input_axis_tkeep[5:0], save_axis_tkeep_reg[7:6]}; - temp_eth_payload_tlast_reg <= input_axis_tlast & (input_axis_tkeep[7:6] == 0); - temp_eth_payload_tuser_reg <= input_axis_tuser & (input_axis_tkeep[7:6] == 0); + temp_eth_payload_tdata_reg <= shift_axis_tdata; + temp_eth_payload_tkeep_reg <= shift_axis_tkeep; + temp_eth_payload_tlast_reg <= shift_axis_tlast; + temp_eth_payload_tuser_reg <= shift_axis_tuser; end else if (transfer_temp_out) begin output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; end + + if (flush_save) begin + save_axis_tdata_reg <= 0; + save_axis_tkeep_reg <= 0; + save_axis_tlast_reg <= 0; + save_axis_tuser_reg <= 0; + end else if (transfer_in_save & ~shift_axis_extra_cycle) begin + save_axis_tdata_reg <= input_axis_tdata; + save_axis_tkeep_reg <= input_axis_tkeep; + save_axis_tlast_reg <= input_axis_tlast; + save_axis_tuser_reg <= input_axis_tuser; + end end end diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index 9aedb94db..ac8170a79 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -97,11 +97,13 @@ reg store_eth_hdr; reg [63:0] write_hdr_data; reg [7:0] write_hdr_keep; +reg write_hdr_last; +reg write_hdr_user; reg write_hdr_out; reg write_hdr_temp; +reg flush_save; reg transfer_in_save; -reg transfer_save_out; reg transfer_in_out; reg transfer_in_temp; reg transfer_temp_out; @@ -133,6 +135,14 @@ reg [7:0] save_eth_payload_tkeep_reg = 0; reg save_eth_payload_tlast_reg = 0; reg save_eth_payload_tuser_reg = 0; +reg [63:0] shift_eth_payload_tdata; +reg [7:0] shift_eth_payload_tkeep; +reg shift_eth_payload_tvalid; +reg shift_eth_payload_tlast; +reg shift_eth_payload_tuser; +reg shift_eth_payload_input_tready; +reg shift_eth_payload_extra_cycle; + assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; @@ -144,6 +154,28 @@ assign output_axis_tuser = output_axis_tuser_reg; assign busy = busy_reg; +always @* begin + shift_eth_payload_tdata[47:0] = save_eth_payload_tdata_reg[63:16]; + shift_eth_payload_tkeep[5:0] = save_eth_payload_tkeep_reg[7:2]; + shift_eth_payload_extra_cycle = save_eth_payload_tlast_reg & (save_eth_payload_tkeep_reg[7:2] != 0); + + if (shift_eth_payload_extra_cycle) begin + shift_eth_payload_tdata[63:48] = 0; + shift_eth_payload_tkeep[7:6] = 0; + shift_eth_payload_tvalid = 1; + shift_eth_payload_tlast = save_eth_payload_tlast_reg; + shift_eth_payload_tuser = save_eth_payload_tuser_reg; + shift_eth_payload_input_tready = flush_save; + end else begin + shift_eth_payload_tdata[63:48] = input_eth_payload_tdata[15:0]; + shift_eth_payload_tkeep[7:6] = input_eth_payload_tkeep[1:0]; + shift_eth_payload_tvalid = input_eth_payload_tvalid; + shift_eth_payload_tlast = (input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0)); + shift_eth_payload_tuser = (input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0)); + shift_eth_payload_input_tready = ~(input_eth_payload_tlast & input_eth_payload_tvalid & transfer_in_save); + end +end + always @* begin state_next = 2'bz; @@ -151,11 +183,13 @@ always @* begin write_hdr_data = 0; write_hdr_keep = 0; + write_hdr_last = 0; + write_hdr_user = 0; write_hdr_out = 0; write_hdr_temp = 0; + flush_save = 0; transfer_in_save = 0; - transfer_save_out = 0; transfer_in_out = 0; transfer_in_temp = 0; transfer_temp_out = 0; @@ -166,6 +200,7 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + flush_save = 1; if (input_eth_hdr_valid) begin store_eth_hdr = 1; @@ -187,7 +222,7 @@ always @* begin end STATE_WRITE_HEADER_LAST: begin // last header word requires first payload word; process accordingly - if (input_eth_payload_tvalid & output_axis_tready) begin + if (shift_eth_payload_tvalid & output_axis_tready) begin // word transfer through - update output register transfer_in_save = 1; write_hdr_out = 1; @@ -197,18 +232,20 @@ always @* begin write_hdr_data[31:24] = eth_src_mac_reg[ 7: 0]; write_hdr_data[39:32] = eth_type_reg[15: 8]; write_hdr_data[47:40] = eth_type_reg[ 7: 0]; - write_hdr_data[55:48] = input_eth_payload_tdata[ 7: 0]; - write_hdr_data[63:56] = input_eth_payload_tdata[15: 8]; - write_hdr_keep = {input_eth_payload_tkeep[1:0], 6'h3F}; - if (input_eth_payload_tlast) begin + write_hdr_data[55:48] = shift_eth_payload_tdata[55:48]; + write_hdr_data[63:56] = shift_eth_payload_tdata[63:56]; + write_hdr_keep = {shift_eth_payload_tkeep[7:6], 6'h3F}; + write_hdr_last = shift_eth_payload_tlast; + write_hdr_user = shift_eth_payload_tuser; + if (shift_eth_payload_tlast) begin state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; end else begin state_next = STATE_WRITE_PAYLOAD_TRANSFER; end - end else if (~input_eth_payload_tvalid & output_axis_tready) begin + end else if (~shift_eth_payload_tvalid & output_axis_tready) begin // word transfer out - go back to idle state_next = STATE_WRITE_HEADER_LAST_WAIT; - end else if (input_eth_payload_tvalid & ~output_axis_tready) begin + end else if (shift_eth_payload_tvalid & ~output_axis_tready) begin // word transfer in - store in temp transfer_in_save = 1; write_hdr_temp = 1; @@ -218,9 +255,11 @@ always @* begin write_hdr_data[31:24] = eth_src_mac_reg[ 7: 0]; write_hdr_data[39:32] = eth_type_reg[15: 8]; write_hdr_data[47:40] = eth_type_reg[ 7: 0]; - write_hdr_data[55:48] = input_eth_payload_tdata[ 7: 0]; - write_hdr_data[63:56] = input_eth_payload_tdata[15: 8]; - write_hdr_keep = {input_eth_payload_tkeep[1:0], 6'h3F}; + write_hdr_data[55:48] = shift_eth_payload_tdata[55:48]; + write_hdr_data[63:56] = shift_eth_payload_tdata[63:56]; + write_hdr_keep = {shift_eth_payload_tkeep[7:6], 6'h3F}; + write_hdr_last = shift_eth_payload_tlast; + write_hdr_user = shift_eth_payload_tuser; state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; end else begin state_next = STATE_WRITE_PAYLOAD_TRANSFER; @@ -228,7 +267,7 @@ always @* begin end STATE_WRITE_HEADER_LAST_WAIT: begin // last header word requires first payload word; no data in registers - if (input_eth_payload_tvalid) begin + if (shift_eth_payload_tvalid) begin // word transfer in - store it in output register transfer_in_save = 1; write_hdr_out = 1; @@ -238,10 +277,12 @@ always @* begin write_hdr_data[31:24] = eth_src_mac_reg[ 7: 0]; write_hdr_data[39:32] = eth_type_reg[15: 8]; write_hdr_data[47:40] = eth_type_reg[ 7: 0]; - write_hdr_data[55:48] = input_eth_payload_tdata[ 7: 0]; - write_hdr_data[63:56] = input_eth_payload_tdata[15: 8]; - write_hdr_keep = {input_eth_payload_tkeep[1:0], 6'h3F}; - if (input_eth_payload_tlast) begin + write_hdr_data[55:48] = shift_eth_payload_tdata[55:48]; + write_hdr_data[63:56] = shift_eth_payload_tdata[63:56]; + write_hdr_keep = {shift_eth_payload_tkeep[7:6], 6'h3F}; + write_hdr_last = shift_eth_payload_tlast; + write_hdr_user = shift_eth_payload_tuser; + if (shift_eth_payload_tlast) begin state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; end else begin state_next = STATE_WRITE_PAYLOAD_TRANSFER; @@ -252,11 +293,11 @@ always @* begin end STATE_WRITE_PAYLOAD_IDLE: begin // idle; no data in registers - if (input_eth_payload_tvalid) begin + if (shift_eth_payload_tvalid) begin // word transfer in - store it in output register transfer_in_save = 1; transfer_in_out = 1; - if (input_eth_payload_tlast) begin + if (shift_eth_payload_tlast) begin state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; end else begin state_next = STATE_WRITE_PAYLOAD_TRANSFER; @@ -267,19 +308,19 @@ always @* begin end STATE_WRITE_PAYLOAD_TRANSFER: begin // write payload; data in output register - if (input_eth_payload_tvalid & output_axis_tready) begin + if (shift_eth_payload_tvalid & output_axis_tready) begin // word transfer through - update output register transfer_in_save = 1; transfer_in_out = 1; - if (input_eth_payload_tlast) begin + if (shift_eth_payload_tlast) begin state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; end else begin state_next = STATE_WRITE_PAYLOAD_TRANSFER; end - end else if (~input_eth_payload_tvalid & output_axis_tready) begin + end else if (~shift_eth_payload_tvalid & output_axis_tready) begin // word transfer out - go back to idle state_next = STATE_WRITE_PAYLOAD_IDLE; - end else if (input_eth_payload_tvalid & ~output_axis_tready) begin + end else if (shift_eth_payload_tvalid & ~output_axis_tready) begin // word transfer in - store in temp transfer_in_save = 1; transfer_in_temp = 1; @@ -293,7 +334,7 @@ always @* begin if (output_axis_tready) begin // transfer out - move temp to output transfer_temp_out = 1; - if (temp_axis_tlast_reg | (save_eth_payload_tlast_reg & save_eth_payload_tkeep_reg[7:6] != 0)) begin + if (temp_axis_tlast_reg) begin state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; end else begin state_next = STATE_WRITE_PAYLOAD_TRANSFER; @@ -306,14 +347,7 @@ always @* begin // write last payload word; data in output register; do not accept new data if (output_axis_tready) begin // word transfer out - done - if (save_eth_payload_tkeep_reg[7:2]) begin - // part of word in save register - transfer_save_out = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - // nothing in save register; done - state_next = STATE_IDLE; - end + state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; end @@ -368,25 +402,25 @@ always @(posedge clk or posedge rst) begin STATE_WRITE_HEADER_LAST: begin // write last header word; need first data word input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; + input_eth_payload_tready_reg <= shift_eth_payload_input_tready; output_axis_tvalid_reg <= 1; end STATE_WRITE_HEADER_LAST_WAIT: begin // last header word requires first payload word; no data in registers input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; + input_eth_payload_tready_reg <= shift_eth_payload_input_tready; output_axis_tvalid_reg <= 0; end STATE_WRITE_PAYLOAD_IDLE: begin // write payload; no data in registers; accept new data input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; + input_eth_payload_tready_reg <= shift_eth_payload_input_tready; output_axis_tvalid_reg <= 0; end STATE_WRITE_PAYLOAD_TRANSFER: begin // write payload; data in output register; accept new data input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; + input_eth_payload_tready_reg <= shift_eth_payload_input_tready; output_axis_tvalid_reg <= 1; end STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin @@ -409,45 +443,44 @@ always @(posedge clk or posedge rst) begin eth_type_reg <= input_eth_type; end - if (transfer_in_save) begin - save_eth_payload_tdata_reg <= input_eth_payload_tdata; - save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; - save_eth_payload_tlast_reg <= input_eth_payload_tlast; - save_eth_payload_tuser_reg <= input_eth_payload_tuser; - end else if (transfer_save_out) begin - output_axis_tdata_reg <= {16'd0, save_eth_payload_tdata_reg[63:16]}; - output_axis_tkeep_reg <= {2'd0, save_eth_payload_tkeep_reg[7:2]}; - output_axis_tlast_reg <= save_eth_payload_tlast_reg; - output_axis_tuser_reg <= save_eth_payload_tuser_reg; - save_eth_payload_tkeep_reg <= 0; - end - if (write_hdr_out) begin output_axis_tdata_reg <= write_hdr_data; output_axis_tkeep_reg <= write_hdr_keep; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; + output_axis_tlast_reg <= write_hdr_last; + output_axis_tuser_reg <= write_hdr_user; end else if (write_hdr_temp) begin temp_axis_tdata_reg <= write_hdr_data; temp_axis_tkeep_reg <= write_hdr_keep; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + temp_axis_tlast_reg <= write_hdr_last; + temp_axis_tuser_reg <= write_hdr_user; end else if (transfer_in_out) begin - output_axis_tdata_reg <= {input_eth_payload_tdata[15:0], save_eth_payload_tdata_reg[63:16]}; - output_axis_tkeep_reg <= {input_eth_payload_tkeep[1:0], save_eth_payload_tkeep_reg[7:2]}; - output_axis_tlast_reg <= input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0); - output_axis_tuser_reg <= input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0); + output_axis_tdata_reg <= shift_eth_payload_tdata; + output_axis_tkeep_reg <= shift_eth_payload_tkeep; + output_axis_tlast_reg <= shift_eth_payload_tlast; + output_axis_tuser_reg <= shift_eth_payload_tuser; end else if (transfer_in_temp) begin - temp_axis_tdata_reg <= {input_eth_payload_tdata[15:0], save_eth_payload_tdata_reg[63:16]}; - temp_axis_tkeep_reg <= {input_eth_payload_tkeep[1:0], save_eth_payload_tkeep_reg[7:2]}; - temp_axis_tlast_reg <= input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0); - temp_axis_tuser_reg <= input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0); + temp_axis_tdata_reg <= shift_eth_payload_tdata; + temp_axis_tkeep_reg <= shift_eth_payload_tkeep; + temp_axis_tlast_reg <= shift_eth_payload_tlast; + temp_axis_tuser_reg <= shift_eth_payload_tuser; end else if (transfer_temp_out) begin output_axis_tdata_reg <= temp_axis_tdata_reg; output_axis_tkeep_reg <= temp_axis_tkeep_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end + + if (flush_save) begin + save_eth_payload_tdata_reg <= 0; + save_eth_payload_tkeep_reg <= 0; + save_eth_payload_tlast_reg <= 0; + save_eth_payload_tuser_reg <= 0; + end else if (transfer_in_save & ~shift_eth_payload_extra_cycle) begin + save_eth_payload_tdata_reg <= input_eth_payload_tdata; + save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; + save_eth_payload_tlast_reg <= input_eth_payload_tlast; + save_eth_payload_tuser_reg <= input_eth_payload_tuser; + end end end From 3bee612dfddb88fa5ac854f5372052cf8a0631a9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Sep 2014 00:39:22 -0700 Subject: [PATCH 028/617] Add extra delays to IP testbenches --- tb/test_ip_eth_rx.py | 14 +++++++++++++- tb/test_ip_eth_tx.py | 9 +++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index 08fc0f497..168fc63ea 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -363,6 +363,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -426,6 +427,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -497,6 +499,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -569,6 +572,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -640,6 +644,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -712,6 +717,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -785,6 +791,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -859,6 +866,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -933,6 +941,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -1005,6 +1014,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -1072,6 +1082,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -1087,7 +1098,7 @@ def bench(): yield delay(100) - for length in range(1,20): + for length in range(1,21): yield clk.posedge print("test 12: truncated header, length %d" % length) current_test.next = 12 @@ -1142,6 +1153,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py index 9ae3f7453..2ef007d4c 100755 --- a/tb/test_ip_eth_tx.py +++ b/tb/test_ip_eth_tx.py @@ -326,6 +326,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -389,6 +390,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -463,6 +465,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -539,6 +542,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -614,6 +618,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -690,6 +695,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -767,6 +773,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -845,6 +852,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge @@ -920,6 +928,7 @@ def bench(): yield wait() + yield clk.posedge yield clk.posedge yield clk.posedge From c6236bc647b3dc4f7e6e0879c3d50eec483a8745 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Sep 2014 00:40:48 -0700 Subject: [PATCH 029/617] Add 64-bit datapath version of IP modules --- rtl/ip_eth_rx_64.v | 739 ++++++++++++++++++++++++ rtl/ip_eth_tx_64.v | 821 +++++++++++++++++++++++++++ tb/test_ip_eth_rx_64.py | 1193 +++++++++++++++++++++++++++++++++++++++ tb/test_ip_eth_rx_64.v | 179 ++++++ tb/test_ip_eth_tx_64.py | 976 ++++++++++++++++++++++++++++++++ tb/test_ip_eth_tx_64.v | 161 ++++++ 6 files changed, 4069 insertions(+) create mode 100644 rtl/ip_eth_rx_64.v create mode 100644 rtl/ip_eth_tx_64.v create mode 100755 tb/test_ip_eth_rx_64.py create mode 100644 tb/test_ip_eth_rx_64.v create mode 100755 tb/test_ip_eth_tx_64.py create mode 100644 tb/test_ip_eth_tx_64.v diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v new file mode 100644 index 000000000..510748e2b --- /dev/null +++ b/rtl/ip_eth_rx_64.v @@ -0,0 +1,739 @@ +/* + +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 + +/* + * IP ethernet frame receiver (Ethernet frame in, IP frame out, 64 bit datapath) + */ +module ip_eth_rx_64 +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [63:0] input_eth_payload_tdata, + input wire [7:0] input_eth_payload_tkeep, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Status signals + */ + output wire busy, + output wire error_header_early_termination, + output wire error_payload_early_termination, + output wire error_invalid_header, + output wire error_invalid_checksum +); + +/* + +IP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + payload length octets + +This module receives an Ethernet frame with decoded fields and decodes +the AXI packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [3:0] + STATE_IDLE = 4'd0, + STATE_READ_HEADER = 4'd1, + STATE_READ_PAYLOAD_IDLE = 4'd2, + STATE_READ_PAYLOAD_TRANSFER = 4'd3, + STATE_READ_PAYLOAD_TRANSFER_WAIT = 4'd4, + STATE_READ_PAYLOAD_TRANSFER_LAST = 4'd5, + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST = 4'd6, + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT = 4'd7, + STATE_WAIT_LAST = 4'd8; + +reg [3:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_eth_hdr; +reg store_hdr_word_0; +reg store_hdr_word_1; +reg store_hdr_word_2; + +reg flush_save; +reg transfer_in_save; +reg transfer_save_out; +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg assert_tlast; +reg assert_tuser; +reg [7:0] tkeep_mask; + +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [31:0] hdr_sum_temp; +reg [15:0] hdr_sum_reg = 0, hdr_sum_next; +reg [15:0] hdr_sum_temp_a_reg = 0, hdr_sum_temp_a_next; +reg [15:0] hdr_sum_temp_b_reg = 0, hdr_sum_temp_b_next; + +reg input_eth_hdr_ready_reg = 0; +reg input_eth_payload_tready_reg = 0; + +reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [3:0] output_ip_version_reg = 0; +reg [3:0] output_ip_ihl_reg = 0; +reg [5:0] output_ip_dscp_reg = 0; +reg [1:0] output_ip_ecn_reg = 0; +reg [15:0] output_ip_length_reg = 0; +reg [15:0] output_ip_identification_reg = 0; +reg [2:0] output_ip_flags_reg = 0; +reg [12:0] output_ip_fragment_offset_reg = 0; +reg [7:0] output_ip_ttl_reg = 0; +reg [7:0] output_ip_protocol_reg = 0; +reg [15:0] output_ip_header_checksum_reg = 0; +reg [31:0] output_ip_source_ip_reg = 0; +reg [31:0] output_ip_dest_ip_reg = 0; +reg [63:0] output_ip_payload_tdata_reg = 0; +reg [7:0] output_ip_payload_tkeep_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg busy_reg = 0; +reg error_header_early_termination_reg = 0, error_header_early_termination_next; +reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; +reg error_invalid_header_reg = 0, error_invalid_header_next; +reg error_invalid_checksum_reg = 0, error_invalid_checksum_next; + +reg [63:0] temp_ip_payload_tdata_reg = 0; +reg [7:0] temp_ip_payload_tkeep_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +reg [63:0] save_eth_payload_tdata_reg = 0; +reg [7:0] save_eth_payload_tkeep_reg = 0; +reg save_eth_payload_tlast_reg = 0; +reg save_eth_payload_tuser_reg = 0; + +reg [63:0] shift_eth_payload_tdata; +reg [7:0] shift_eth_payload_tkeep; +reg shift_eth_payload_tvalid; +reg shift_eth_payload_tlast; +reg shift_eth_payload_tuser; +reg shift_eth_payload_input_tready; +reg shift_eth_payload_extra_cycle; + +assign input_eth_hdr_ready = input_eth_hdr_ready_reg; +assign input_eth_payload_tready = input_eth_payload_tready_reg; + +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +assign busy = busy_reg; +assign error_header_early_termination = error_header_early_termination_reg; +assign error_payload_early_termination = error_payload_early_termination_reg; +assign error_invalid_header = error_invalid_header_reg; +assign error_invalid_checksum = error_invalid_checksum_reg; + +function [3:0] keep2count; + input [7:0] k; + case (k) + 8'b00000000: keep2count = 0; + 8'b00000001: keep2count = 1; + 8'b00000011: keep2count = 2; + 8'b00000111: keep2count = 3; + 8'b00001111: keep2count = 4; + 8'b00011111: keep2count = 5; + 8'b00111111: keep2count = 6; + 8'b01111111: keep2count = 7; + 8'b11111111: keep2count = 8; + endcase +endfunction + +function [7:0] count2keep; + input [3:0] k; + case (k) + 4'd0: count2keep = 8'b00000000; + 4'd1: count2keep = 8'b00000001; + 4'd2: count2keep = 8'b00000011; + 4'd3: count2keep = 8'b00000111; + 4'd4: count2keep = 8'b00001111; + 4'd5: count2keep = 8'b00011111; + 4'd6: count2keep = 8'b00111111; + 4'd7: count2keep = 8'b01111111; + 4'd8: count2keep = 8'b11111111; + endcase +endfunction + +always @* begin + shift_eth_payload_tdata[31:0] = save_eth_payload_tdata_reg[63:32]; + shift_eth_payload_tkeep[3:0] = save_eth_payload_tkeep_reg[7:4]; + shift_eth_payload_extra_cycle = save_eth_payload_tlast_reg & (save_eth_payload_tkeep_reg[7:4] != 0); + + if (shift_eth_payload_extra_cycle) begin + shift_eth_payload_tdata[63:32] = 0; + shift_eth_payload_tkeep[7:4] = 0; + shift_eth_payload_tvalid = 1; + shift_eth_payload_tlast = save_eth_payload_tlast_reg; + shift_eth_payload_tuser = save_eth_payload_tuser_reg; + shift_eth_payload_input_tready = flush_save; + end else begin + shift_eth_payload_tdata[63:32] = input_eth_payload_tdata[31:0]; + shift_eth_payload_tkeep[7:4] = input_eth_payload_tkeep[3:0]; + shift_eth_payload_tvalid = input_eth_payload_tvalid; + shift_eth_payload_tlast = (input_eth_payload_tlast & (input_eth_payload_tkeep[7:4] == 0)); + shift_eth_payload_tuser = (input_eth_payload_tuser & (input_eth_payload_tkeep[7:4] == 0)); + shift_eth_payload_input_tready = ~(input_eth_payload_tlast & input_eth_payload_tvalid & transfer_in_save); + end +end + +always @* begin + state_next = 2'bz; + + flush_save = 0; + transfer_in_save = 0; + transfer_save_out = 0; + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + assert_tlast = 0; + assert_tuser = 0; + tkeep_mask = 8'hff; + + store_eth_hdr = 0; + store_hdr_word_0 = 0; + store_hdr_word_1 = 0; + store_hdr_word_2 = 0; + + frame_ptr_next = frame_ptr_reg; + + hdr_sum_temp = 0; + hdr_sum_next = hdr_sum_reg; + hdr_sum_temp_a_next = hdr_sum_temp_a_reg; + hdr_sum_temp_b_next = hdr_sum_temp_b_reg; + + output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + + error_header_early_termination_next = 0; + error_payload_early_termination_next = 0; + error_invalid_header_next = 0; + error_invalid_checksum_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for header + frame_ptr_next = 0; + hdr_sum_next = 0; + flush_save = 1; + + if (input_eth_hdr_ready & input_eth_hdr_valid) begin + frame_ptr_next = 0; + store_eth_hdr = 1; + state_next = STATE_READ_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_READ_HEADER: begin + // read header state + if (input_eth_payload_tvalid) begin + // word transfer in - store it + frame_ptr_next = frame_ptr_reg+8; + transfer_in_save = 1; + state_next = STATE_READ_HEADER; + + case (frame_ptr_reg) + 8'h00: begin + store_hdr_word_0 = 1; + hdr_sum_temp = input_eth_payload_tdata[15:0] + + input_eth_payload_tdata[31:16] + + input_eth_payload_tdata[47:32] + + input_eth_payload_tdata[63:48]; + hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; + hdr_sum_temp_a_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; + end + 8'h08: begin + store_hdr_word_1 = 1; + hdr_sum_temp = input_eth_payload_tdata[15:0] + + input_eth_payload_tdata[31:16] + + input_eth_payload_tdata[47:32] + + input_eth_payload_tdata[63:48]; + hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; + hdr_sum_temp_b_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; + end + 8'h10: begin + store_hdr_word_2 = 1; + hdr_sum_temp = input_eth_payload_tdata[15:0] + + input_eth_payload_tdata[31:16] + + hdr_sum_temp_a_reg + + hdr_sum_temp_b_reg; + hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; + hdr_sum_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; + frame_ptr_next = frame_ptr_reg+4; + if (output_ip_version_reg != 4 || output_ip_ihl_reg != 5) begin + error_invalid_header_next = 1; + state_next = STATE_WAIT_LAST; + end else if (hdr_sum_next != 16'hffff) begin + error_invalid_checksum_next = 1; + state_next = STATE_WAIT_LAST; + end else begin + output_ip_hdr_valid_next = 1; + state_next = STATE_READ_PAYLOAD_IDLE; + end + end + endcase + + if (shift_eth_payload_tlast) begin + state_next = STATE_IDLE; + output_ip_hdr_valid_next = 0; + error_header_early_termination_next = 1; + error_invalid_header_next = 0; + error_invalid_checksum_next = 0; + end + + end else begin + state_next = STATE_READ_HEADER; + end + end + STATE_READ_PAYLOAD_IDLE: begin + // idle; no data in registers + if (shift_eth_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_save = 1; + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_tkeep); + if (frame_ptr_next >= output_ip_length_reg) begin + // have entire payload + frame_ptr_next = output_ip_length_reg; + tkeep_mask = count2keep(output_ip_length_reg - frame_ptr_reg); + if (shift_eth_payload_tlast) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + if (shift_eth_payload_tlast) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_READ_PAYLOAD_IDLE; + end + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register + if (shift_eth_payload_tvalid & output_ip_payload_tready) begin + // word transfer through - update output register + transfer_in_save = 1; + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_tkeep); + if (frame_ptr_next >= output_ip_length_reg) begin + // have entire payload + frame_ptr_next = output_ip_length_reg; + tkeep_mask = count2keep(output_ip_length_reg - frame_ptr_reg); + if (shift_eth_payload_tlast) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + if (shift_eth_payload_tlast) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else if (~shift_eth_payload_tvalid & output_ip_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_READ_PAYLOAD_IDLE; + end else if (shift_eth_payload_tvalid & ~output_ip_payload_tready) begin + // word transfer in - store in temp + transfer_in_save = 1; + transfer_in_temp = 1; + frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_tkeep); + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + if (frame_ptr_next >= output_ip_length_reg) begin + // have entire payload + frame_ptr_next = output_ip_length_reg; + tkeep_mask = count2keep(output_ip_length_reg - frame_ptr_reg); + if (~shift_eth_payload_tlast) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + end + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in both output and temp registers + if (output_ip_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_ip_payload_tlast_reg) begin + if (frame_ptr_next < output_ip_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next >= output_ip_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + if (output_ip_payload_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + if (shift_eth_payload_tvalid) begin + transfer_in_save = 1; + if (shift_eth_payload_tlast) begin + // assert tlast and transfer tuser + assert_tlast = 1; + assert_tuser = shift_eth_payload_tuser; + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin + // wait for end of frame; data in both output and temp registers; read and discard + if (output_ip_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + end + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + if (shift_eth_payload_tvalid) begin + transfer_in_save = 1; + if (shift_eth_payload_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end else begin + state_next = STATE_WAIT_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + hdr_sum_reg <= 0; + hdr_sum_temp_a_reg <= 0; + hdr_sum_temp_b_reg <= 0; + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + busy_reg <= 0; + error_header_early_termination_reg <= 0; + error_payload_early_termination_reg <= 0; + error_invalid_header_reg <= 0; + error_invalid_checksum_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + hdr_sum_reg <= hdr_sum_next; + hdr_sum_temp_a_reg <= hdr_sum_temp_a_next; + hdr_sum_temp_b_reg <= hdr_sum_temp_b_next; + + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + + error_header_early_termination_reg <= error_header_early_termination_next; + error_payload_early_termination_reg <= error_payload_early_termination_next; + error_invalid_header_reg <= error_invalid_header_next; + error_invalid_checksum_reg <= error_invalid_checksum_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_eth_hdr_ready_reg <= ~output_ip_hdr_valid; + input_eth_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + end + STATE_READ_HEADER: begin + // read header; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= shift_eth_payload_input_tready; + output_ip_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_IDLE: begin + // read payload; no data in registers; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= shift_eth_payload_input_tready; + output_ip_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register; accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= shift_eth_payload_input_tready; + output_ip_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in output and temp registers; do not accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= shift_eth_payload_input_tready; + output_ip_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin + // wait for end of frame; data in output and temp registers; do not accept new data + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= shift_eth_payload_input_tready; + output_ip_payload_tvalid_reg <= 0; + end + endcase + + // datapath + if (store_eth_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + end + + if (store_hdr_word_0) begin + {output_ip_version_reg, output_ip_ihl_reg} <= input_eth_payload_tdata[ 7: 0]; + {output_ip_dscp_reg, output_ip_ecn_reg} <= input_eth_payload_tdata[15: 8]; + output_ip_length_reg[15: 8] <= input_eth_payload_tdata[23:16]; + output_ip_length_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + output_ip_identification_reg[15: 8] <= input_eth_payload_tdata[39:32]; + output_ip_identification_reg[ 7: 0] <= input_eth_payload_tdata[47:40]; + {output_ip_flags_reg, output_ip_fragment_offset_reg[12:8]} <= input_eth_payload_tdata[55:48]; + output_ip_fragment_offset_reg[ 7:0] <= input_eth_payload_tdata[63:56]; + end + + if (store_hdr_word_1) begin + output_ip_ttl_reg <= input_eth_payload_tdata[ 7: 0]; + output_ip_protocol_reg <= input_eth_payload_tdata[15: 8]; + output_ip_header_checksum_reg[15: 8] <= input_eth_payload_tdata[23:16]; + output_ip_header_checksum_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + output_ip_source_ip_reg[31:24] <= input_eth_payload_tdata[39:32]; + output_ip_source_ip_reg[23:16] <= input_eth_payload_tdata[47:40]; + output_ip_source_ip_reg[15: 8] <= input_eth_payload_tdata[55:48]; + output_ip_source_ip_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; + end + + if (store_hdr_word_2) begin + output_ip_dest_ip_reg[31:24] <= input_eth_payload_tdata[ 7: 0]; + output_ip_dest_ip_reg[23:16] <= input_eth_payload_tdata[15: 8]; + output_ip_dest_ip_reg[15: 8] <= input_eth_payload_tdata[23:16]; + output_ip_dest_ip_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + end + + if (transfer_in_out) begin + output_ip_payload_tdata_reg <= shift_eth_payload_tdata; + output_ip_payload_tkeep_reg <= shift_eth_payload_tkeep & tkeep_mask; + output_ip_payload_tlast_reg <= shift_eth_payload_tlast; + output_ip_payload_tuser_reg <= shift_eth_payload_tuser; + end else if (transfer_in_temp) begin + temp_ip_payload_tdata_reg <= shift_eth_payload_tdata; + temp_ip_payload_tkeep_reg <= shift_eth_payload_tkeep & tkeep_mask; + temp_ip_payload_tlast_reg <= shift_eth_payload_tlast; + temp_ip_payload_tuser_reg <= shift_eth_payload_tuser; + end else if (transfer_temp_out) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (flush_save) begin + save_eth_payload_tdata_reg <= 0; + save_eth_payload_tkeep_reg <= 0; + save_eth_payload_tlast_reg <= 0; + save_eth_payload_tuser_reg <= 0; + end else if (transfer_in_save & ~shift_eth_payload_extra_cycle) begin + save_eth_payload_tdata_reg <= input_eth_payload_tdata; + save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; + save_eth_payload_tlast_reg <= input_eth_payload_tlast; + save_eth_payload_tuser_reg <= input_eth_payload_tuser; + end + + if (assert_tlast) output_ip_payload_tlast_reg <= 1; + if (assert_tuser) output_ip_payload_tuser_reg <= 1; + end +end + +endmodule diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v new file mode 100644 index 000000000..1a59a61e0 --- /dev/null +++ b/rtl/ip_eth_tx_64.v @@ -0,0 +1,821 @@ +/* + +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 + +/* + * IP ethernet frame transmitter (IP frame in, Ethernet frame out, 64 bit datapath) + */ +module ip_eth_tx_64 +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [63:0] input_ip_payload_tdata, + input wire [7:0] input_ip_payload_tkeep, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Status signals + */ + output wire busy, + output wire error_payload_early_termination +); + +/* + +IP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + payload length octets + +This module receives an Ethernet frame with decoded fields and decodes +the AXI packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [3:0] + STATE_IDLE = 4'd0, + STATE_WRITE_HEADER = 4'd1, + STATE_WRITE_HEADER_LAST = 4'd2, + STATE_WRITE_HEADER_LAST_WAIT = 4'd3, + STATE_WRITE_PAYLOAD_IDLE = 4'd4, + STATE_WRITE_PAYLOAD_TRANSFER = 4'd5, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 4'd6, + STATE_WRITE_PAYLOAD_TRANSFER_LAST = 4'd7, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST = 4'd8, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT = 4'd9, + STATE_WAIT_LAST = 4'd10; + +reg [3:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_ip_hdr; + +reg [63:0] write_hdr_data; +reg [7:0] write_hdr_keep; +reg write_hdr_last; +reg write_hdr_user; +reg write_hdr_out; +reg write_hdr_temp; + +reg flush_save; +reg transfer_in_save; +reg transfer_save_out; +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg assert_tlast; +reg assert_tuser; +reg [7:0] tkeep_mask; + +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [31:0] hdr_sum_temp; +reg [15:0] hdr_sum_reg = 0, hdr_sum_next; + +reg [5:0] ip_dscp_reg = 0; +reg [1:0] ip_ecn_reg = 0; +reg [15:0] ip_length_reg = 0; +reg [15:0] ip_identification_reg = 0; +reg [2:0] ip_flags_reg = 0; +reg [12:0] ip_fragment_offset_reg = 0; +reg [7:0] ip_ttl_reg = 0; +reg [7:0] ip_protocol_reg = 0; +reg [31:0] ip_source_ip_reg = 0; +reg [31:0] ip_dest_ip_reg = 0; + +reg input_ip_hdr_ready_reg = 0; +reg input_ip_payload_tready_reg = 0; + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg busy_reg = 0; +reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; + +reg [63:0] temp_eth_payload_tdata_reg = 0; +reg [7:0] temp_eth_payload_tkeep_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +reg [63:0] save_ip_payload_tdata_reg = 0; +reg [7:0] save_ip_payload_tkeep_reg = 0; +reg save_ip_payload_tlast_reg = 0; +reg save_ip_payload_tuser_reg = 0; + +reg [63:0] shift_ip_payload_tdata; +reg [7:0] shift_ip_payload_tkeep; +reg shift_ip_payload_tvalid; +reg shift_ip_payload_tlast; +reg shift_ip_payload_tuser; +reg shift_ip_payload_input_tready; +reg shift_ip_payload_extra_cycle; + +assign input_ip_hdr_ready = input_ip_hdr_ready_reg; +assign input_ip_payload_tready = input_ip_payload_tready_reg; + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign busy = busy_reg; +assign error_payload_early_termination = error_payload_early_termination_reg; + +function [3:0] keep2count; + input [7:0] k; + case (k) + 8'b00000000: keep2count = 0; + 8'b00000001: keep2count = 1; + 8'b00000011: keep2count = 2; + 8'b00000111: keep2count = 3; + 8'b00001111: keep2count = 4; + 8'b00011111: keep2count = 5; + 8'b00111111: keep2count = 6; + 8'b01111111: keep2count = 7; + 8'b11111111: keep2count = 8; + endcase +endfunction + +function [7:0] count2keep; + input [3:0] k; + case (k) + 4'd0: count2keep = 8'b00000000; + 4'd1: count2keep = 8'b00000001; + 4'd2: count2keep = 8'b00000011; + 4'd3: count2keep = 8'b00000111; + 4'd4: count2keep = 8'b00001111; + 4'd5: count2keep = 8'b00011111; + 4'd6: count2keep = 8'b00111111; + 4'd7: count2keep = 8'b01111111; + 4'd8: count2keep = 8'b11111111; + endcase +endfunction + +always @* begin + shift_ip_payload_tdata[31:0] = save_ip_payload_tdata_reg[63:32]; + shift_ip_payload_tkeep[3:0] = save_ip_payload_tkeep_reg[7:4]; + shift_ip_payload_extra_cycle = save_ip_payload_tlast_reg & (save_ip_payload_tkeep_reg[7:4] != 0); + + if (shift_ip_payload_extra_cycle) begin + shift_ip_payload_tdata[63:32] = 0; + shift_ip_payload_tkeep[7:4] = 0; + shift_ip_payload_tvalid = 1; + shift_ip_payload_tlast = save_ip_payload_tlast_reg; + shift_ip_payload_tuser = save_ip_payload_tuser_reg; + shift_ip_payload_input_tready = flush_save; + end else begin + shift_ip_payload_tdata[63:32] = input_ip_payload_tdata[31:0]; + shift_ip_payload_tkeep[7:4] = input_ip_payload_tkeep[3:0]; + shift_ip_payload_tvalid = input_ip_payload_tvalid; + shift_ip_payload_tlast = (input_ip_payload_tlast & (input_ip_payload_tkeep[7:4] == 0)); + shift_ip_payload_tuser = (input_ip_payload_tuser & (input_ip_payload_tkeep[7:4] == 0)); + shift_ip_payload_input_tready = ~(input_ip_payload_tlast & input_ip_payload_tvalid & transfer_in_save); + end +end + +always @* begin + state_next = 2'bz; + + store_ip_hdr = 0; + + write_hdr_data = 0; + write_hdr_keep = 0; + write_hdr_last = 0; + write_hdr_user = 0; + write_hdr_out = 0; + write_hdr_temp = 0; + + flush_save = 0; + transfer_in_save = 0; + transfer_save_out = 0; + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + assert_tlast = 0; + assert_tuser = 0; + tkeep_mask = 8'hff; + + frame_ptr_next = frame_ptr_reg; + + hdr_sum_temp = 0; + hdr_sum_next = hdr_sum_reg; + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + + error_payload_early_termination_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + flush_save = 1; + + if (input_ip_hdr_valid & input_ip_hdr_ready) begin + store_ip_hdr = 1; + hdr_sum_temp = {4'd4, 4'd5, input_ip_dscp, input_ip_ecn} + + input_ip_length + + input_ip_identification + + {input_ip_flags, input_ip_fragment_offset} + + {input_ip_ttl, input_ip_protocol}; + hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; + hdr_sum_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; + write_hdr_out = 1; + write_hdr_data[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl + write_hdr_data[15: 8] = {input_ip_dscp, input_ip_ecn}; + write_hdr_data[23:16] = input_ip_length[15: 8]; + write_hdr_data[31:24] = input_ip_length[ 7: 0]; + write_hdr_data[39:32] = input_ip_identification[15: 8]; + write_hdr_data[47:40] = input_ip_identification[ 7: 0]; + write_hdr_data[55:48] = {input_ip_flags, input_ip_fragment_offset[12: 8]}; + write_hdr_data[63:56] = input_ip_fragment_offset[ 7: 0]; + write_hdr_keep = 8'hff; + output_eth_hdr_valid_next = 1; + frame_ptr_next = 8; + state_next = STATE_WRITE_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_HEADER: begin + // write header state + if (output_eth_payload_tready) begin + // word transfer out + frame_ptr_next = frame_ptr_reg+8; + state_next = STATE_WRITE_HEADER; + write_hdr_out = 1; + case (frame_ptr_reg) + 8'h08: begin + hdr_sum_temp = hdr_sum_reg + + ip_source_ip_reg[31:16] + + ip_source_ip_reg[15: 0] + + ip_dest_ip_reg[31:16] + + ip_dest_ip_reg[15: 0]; + hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; + hdr_sum_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; + write_hdr_data[ 7: 0] = ip_ttl_reg; + write_hdr_data[15: 8] = ip_protocol_reg; + write_hdr_data[23:16] = ~hdr_sum_next[15: 8]; + write_hdr_data[31:24] = ~hdr_sum_next[ 7: 0]; + write_hdr_data[39:32] = ip_source_ip_reg[31:24]; + write_hdr_data[47:40] = ip_source_ip_reg[23:16]; + write_hdr_data[55:48] = ip_source_ip_reg[15: 8]; + write_hdr_data[63:56] = ip_source_ip_reg[ 7: 0]; + write_hdr_keep = 8'hff; + state_next = STATE_WRITE_HEADER_LAST; + end + endcase + end else begin + state_next = STATE_WRITE_HEADER; + end + end + STATE_WRITE_HEADER_LAST: begin + // last header word requires first payload word; process accordingly + if (shift_ip_payload_tvalid & output_eth_payload_tready) begin + // word transfer through - update output register + transfer_in_save = 1; + write_hdr_out = 1; + write_hdr_data[ 7: 0] = ip_dest_ip_reg[31:24]; + write_hdr_data[15: 8] = ip_dest_ip_reg[23:16]; + write_hdr_data[23:16] = ip_dest_ip_reg[15: 8]; + write_hdr_data[31:24] = ip_dest_ip_reg[ 7: 0]; + write_hdr_data[39:32] = shift_ip_payload_tdata[39:32]; + write_hdr_data[47:40] = shift_ip_payload_tdata[47:40]; + write_hdr_data[55:48] = shift_ip_payload_tdata[55:48]; + write_hdr_data[63:56] = shift_ip_payload_tdata[63:56]; + write_hdr_keep = {shift_ip_payload_tkeep[7:4], 4'hF}; + frame_ptr_next = frame_ptr_reg+keep2count(write_hdr_keep); + if (frame_ptr_next >= ip_length_reg) begin + // have entire payload + frame_ptr_next = ip_length_reg; + tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); + write_hdr_keep = tkeep_mask; + assert_tlast = 1; + assert_tuser = input_ip_payload_tuser; + if (shift_ip_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + if (shift_ip_payload_tlast) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else if (~shift_ip_payload_tvalid & output_eth_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_WRITE_HEADER_LAST_WAIT; + end else if (shift_ip_payload_tvalid & ~output_eth_payload_tready) begin + // word transfer in - store in temp + transfer_in_save = 1; + write_hdr_temp = 1; + write_hdr_data[ 7: 0] = ip_dest_ip_reg[31:24]; + write_hdr_data[15: 8] = ip_dest_ip_reg[23:16]; + write_hdr_data[23:16] = ip_dest_ip_reg[15: 8]; + write_hdr_data[31:24] = ip_dest_ip_reg[ 7: 0]; + write_hdr_data[39:32] = shift_ip_payload_tdata[39:32]; + write_hdr_data[47:40] = shift_ip_payload_tdata[47:40]; + write_hdr_data[55:48] = shift_ip_payload_tdata[55:48]; + write_hdr_data[63:56] = shift_ip_payload_tdata[63:56]; + write_hdr_keep = {shift_ip_payload_tkeep[7:4], 4'hF}; + frame_ptr_next = frame_ptr_reg+keep2count(write_hdr_keep); + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + if (frame_ptr_next >= ip_length_reg) begin + // have entire payload + frame_ptr_next = ip_length_reg; + tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); + write_hdr_keep = tkeep_mask; + write_hdr_last = 1; + write_hdr_user = shift_ip_payload_tuser; + if (shift_ip_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + end + end else begin + if (shift_ip_payload_tlast) begin + // end of frame, but length does not match + write_hdr_last = 1; + write_hdr_user = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + STATE_WRITE_HEADER_LAST_WAIT: begin + // last header word requires first payload word; no data in registers + if (shift_ip_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_save = 1; + write_hdr_out = 1; + write_hdr_data[ 7: 0] = ip_dest_ip_reg[31:24]; + write_hdr_data[15: 8] = ip_dest_ip_reg[23:16]; + write_hdr_data[23:16] = ip_dest_ip_reg[15: 8]; + write_hdr_data[31:24] = ip_dest_ip_reg[ 7: 0]; + write_hdr_data[39:32] = shift_ip_payload_tdata[39:32]; + write_hdr_data[47:40] = shift_ip_payload_tdata[47:40]; + write_hdr_data[55:48] = shift_ip_payload_tdata[55:48]; + write_hdr_data[63:56] = shift_ip_payload_tdata[63:56]; + write_hdr_keep = {shift_ip_payload_tkeep[7:4], 4'hF}; + frame_ptr_next = frame_ptr_reg+keep2count(write_hdr_keep); + if (frame_ptr_next >= ip_length_reg) begin + // have entire payload + frame_ptr_next = ip_length_reg; + tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); + write_hdr_keep = tkeep_mask; + assert_tlast = 1; + assert_tuser = shift_ip_payload_tuser; + if (shift_ip_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + if (shift_ip_payload_tlast) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_WRITE_HEADER_LAST_WAIT; + end + end + STATE_WRITE_PAYLOAD_IDLE: begin + // idle; no data in registers + if (shift_ip_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_save = 1; + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_tkeep); + if (frame_ptr_next >= ip_length_reg) begin + // have entire payload + frame_ptr_next = ip_length_reg; + tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); + if (shift_ip_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + if (shift_ip_payload_tlast) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_WRITE_PAYLOAD_IDLE; + end + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // write payload; data in output register + if (shift_ip_payload_tvalid & output_eth_payload_tready) begin + // word transfer through - update output register + transfer_in_save = 1; + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_tkeep); + if (frame_ptr_next >= ip_length_reg) begin + // have entire payload + frame_ptr_next = ip_length_reg; + tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); + if (shift_ip_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + if (shift_ip_payload_tlast) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else if (~shift_ip_payload_tvalid & output_eth_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_WRITE_PAYLOAD_IDLE; + end else if (shift_ip_payload_tvalid & ~output_eth_payload_tready) begin + // word transfer in - store in temp + transfer_in_save = 1; + transfer_in_temp = 1; + frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_tkeep); + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + if (frame_ptr_next >= ip_length_reg) begin + // have entire payload + frame_ptr_next = ip_length_reg; + tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); + if (~shift_ip_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + end + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // write payload; data in both output and temp registers + if (output_eth_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_eth_payload_tlast_reg) begin + if (frame_ptr_next < ip_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next >= ip_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // write last payload word; data in output register; do not accept new data + if (output_eth_payload_tready) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + if (shift_ip_payload_tvalid) begin + transfer_in_save = 1; + if (shift_ip_payload_tlast) begin + // assert tlast and transfer tuser + assert_tlast = 1; + assert_tuser = shift_ip_payload_tuser; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin + // wait for end of frame; data in both output and temp registers; read and discard + if (output_eth_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + end + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + if (shift_ip_payload_tvalid) begin + transfer_in_save = 1; + if (shift_ip_payload_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end else begin + state_next = STATE_WAIT_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + hdr_sum_reg <= 0; + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + ip_dscp_reg <= 0; + ip_ecn_reg <= 0; + ip_length_reg <= 0; + ip_identification_reg <= 0; + ip_flags_reg <= 0; + ip_fragment_offset_reg <= 0; + ip_ttl_reg <= 0; + ip_protocol_reg <= 0; + ip_source_ip_reg <= 0; + ip_dest_ip_reg <= 0; + output_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + save_ip_payload_tdata_reg <= 0; + save_ip_payload_tkeep_reg <= 0; + save_ip_payload_tlast_reg <= 0; + save_ip_payload_tuser_reg <= 0; + busy_reg <= 0; + error_payload_early_termination_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + hdr_sum_reg <= hdr_sum_next; + + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + + busy_reg <= state_next != STATE_IDLE; + + error_payload_early_termination_reg <= error_payload_early_termination_next; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_ip_hdr_ready_reg <= 1; + input_ip_payload_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + end + STATE_WRITE_HEADER: begin + // write header + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_HEADER_LAST: begin + // write last header word; need first data word + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= shift_ip_payload_input_tready; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_HEADER_LAST_WAIT: begin + // last header word requires first payload word; no data in registers + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= shift_ip_payload_input_tready; + output_eth_payload_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_IDLE: begin + // write payload; no data in registers; accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= shift_ip_payload_input_tready; + output_eth_payload_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // write payload; data in output register; accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= shift_ip_payload_input_tready; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // write payload; data in output and temp registers; do not accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // write last payload word; data in output register; do not accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= shift_ip_payload_input_tready; + output_eth_payload_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin + // wait for end of frame; data in output and temp registers; do not accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_eth_payload_tvalid_reg <= 1; + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= shift_ip_payload_input_tready; + output_eth_payload_tvalid_reg <= 0; + end + endcase + + if (store_ip_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + ip_dscp_reg <= input_ip_dscp; + ip_ecn_reg <= input_ip_ecn; + ip_length_reg <= input_ip_length; + ip_identification_reg <= input_ip_identification; + ip_flags_reg <= input_ip_flags; + ip_fragment_offset_reg <= input_ip_fragment_offset; + ip_ttl_reg <= input_ip_ttl; + ip_protocol_reg <= input_ip_protocol; + ip_source_ip_reg <= input_ip_source_ip; + ip_dest_ip_reg <= input_ip_dest_ip; + end + + if (write_hdr_out) begin + output_eth_payload_tdata_reg <= write_hdr_data; + output_eth_payload_tkeep_reg <= write_hdr_keep & tkeep_mask; + output_eth_payload_tlast_reg <= write_hdr_last; + output_eth_payload_tuser_reg <= write_hdr_user; + end else if (write_hdr_temp) begin + temp_eth_payload_tdata_reg <= write_hdr_data; + temp_eth_payload_tkeep_reg <= write_hdr_keep & tkeep_mask; + temp_eth_payload_tlast_reg <= write_hdr_last; + temp_eth_payload_tuser_reg <= write_hdr_user; + end else if (transfer_in_out) begin + output_eth_payload_tdata_reg <= shift_ip_payload_tdata; + output_eth_payload_tkeep_reg <= shift_ip_payload_tkeep & tkeep_mask; + output_eth_payload_tlast_reg <= shift_ip_payload_tlast; + output_eth_payload_tuser_reg <= shift_ip_payload_tuser; + end else if (transfer_in_temp) begin + temp_eth_payload_tdata_reg <= shift_ip_payload_tdata; + temp_eth_payload_tkeep_reg <= shift_ip_payload_tkeep & tkeep_mask; + temp_eth_payload_tlast_reg <= shift_ip_payload_tlast; + temp_eth_payload_tuser_reg <= shift_ip_payload_tuser; + end else if (transfer_temp_out) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (flush_save) begin + save_ip_payload_tdata_reg <= 0; + save_ip_payload_tkeep_reg <= 0; + save_ip_payload_tlast_reg <= 0; + save_ip_payload_tuser_reg <= 0; + end else if (transfer_in_save & ~shift_ip_payload_extra_cycle) begin + save_ip_payload_tdata_reg <= input_ip_payload_tdata; + save_ip_payload_tkeep_reg <= input_ip_payload_tkeep; + save_ip_payload_tlast_reg <= input_ip_payload_tlast; + save_ip_payload_tuser_reg <= input_ip_payload_tuser; + end + + if (assert_tlast) output_eth_payload_tlast_reg <= 1; + if (assert_tuser) output_eth_payload_tuser_reg <= 1; + end +end + +endmodule diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py new file mode 100755 index 000000000..16cc58158 --- /dev/null +++ b/tb/test_ip_eth_rx_64.py @@ -0,0 +1,1193 @@ +#!/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 eth_ep +import ip_ep + +module = 'ip_eth_rx_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_ip_eth_rx_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + busy, + error_header_early_termination, + error_payload_early_termination, + error_invalid_header, + error_invalid_checksum): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tkeep=output_ip_payload_tkeep, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + busy=busy, + error_header_early_termination=error_header_early_termination, + error_payload_early_termination=error_payload_early_termination, + error_invalid_header=error_invalid_header, + error_invalid_checksum=error_invalid_checksum) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[64:]) + input_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[64:]) + output_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + error_header_early_termination = Signal(bool(0)) + error_payload_early_termination = Signal(bool(0)) + error_invalid_header = Signal(bool(0)) + error_invalid_checksum = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tkeep=output_ip_payload_tkeep, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_ip_eth_rx_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + busy, + error_header_early_termination, + error_payload_early_termination, + error_invalid_header, + error_invalid_checksum) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_header_early_termination_asserted = Signal(bool(0)) + error_payload_early_termination_asserted = Signal(bool(0)) + error_invalid_header_asserted = Signal(bool(0)) + error_invalid_checksum_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_header_early_termination): + error_header_early_termination_asserted.next = 1 + if (error_payload_early_termination): + error_payload_early_termination_asserted.next = 1 + if (error_invalid_header): + error_invalid_header_asserted.next = 1 + if (error_invalid_checksum): + error_invalid_checksum_asserted.next = 1 + + def wait_normal(): + while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + yield clk.posedge + + def wait_pause_source(): + while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = bytearray(range(payload_len)) + test_frame.build() + eth_frame = test_frame.build_eth() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: trailing bytes (1), length %d" % payload_len) + current_test.next = 4 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data += bytearray(b'\x00') + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: trailing bytes (10), length %d" % payload_len) + current_test.next = 5 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data += bytearray(b'\x00'*10) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 6: trailing bytes with tuser assert (1), length %d" % payload_len) + current_test.next = 6 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data += bytearray(b'\x00') + eth_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 7: trailing bytes with tuser assert (10), length %d" % payload_len) + current_test.next = 7 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data += bytearray(b'\x00'*10) + eth_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 8: truncated payload (1), length %d" % payload_len) + current_test.next = 8 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len+1)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data = eth_frame1.payload.data[:-1] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 9: truncated payload (10), length %d" % payload_len) + current_test.next = 9 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len+10)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data = eth_frame1.payload.data[:-10] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 10: bad IHL, length %d" % payload_len) + current_test.next = 10 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 6 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_invalid_header_asserted.next = 0 + + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_invalid_header_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 11: bad checksum, length %d" % payload_len) + current_test.next = 11 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = 0x1234 + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_invalid_checksum_asserted.next = 0 + + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_invalid_checksum_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + for length in range(1,21): + yield clk.posedge + print("test 12: truncated header, length %d" % length) + current_test.next = 12 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = 0x1234 + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(16)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(16)) + test_frame2.build() + + eth_frame1 = test_frame1.build_eth() + eth_frame2 = test_frame2.build_eth() + + eth_frame1.payload.data = eth_frame1.payload.data[:length] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_header_early_termination_asserted.next = 0 + + source_queue.put(eth_frame1) + source_queue.put(eth_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_header_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_eth_rx_64.v b/tb/test_ip_eth_rx_64.v new file mode 100644 index 000000000..70d8a02f4 --- /dev/null +++ b/tb/test_ip_eth_rx_64.v @@ -0,0 +1,179 @@ +/* + +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_ip_eth_rx_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [63:0] input_eth_payload_tdata = 0; +reg [7:0] input_eth_payload_tkeep = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire output_ip_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [63:0] output_ip_payload_tdata; +wire [7:0] output_ip_payload_tkeep; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire busy; +wire error_header_early_termination; +wire error_payload_early_termination; +wire error_invalid_header; +wire error_invalid_checksum; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_ip_hdr_ready, + output_ip_payload_tready); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + output_ip_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + busy, + error_header_early_termination, + error_payload_early_termination, + error_invalid_header, + error_invalid_checksum); + + // dump file + $dumpfile("test_ip_eth_rx_64.lxt"); + $dumpvars(0, test_ip_eth_rx_64); +end + +ip_eth_rx_64 +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .busy(busy), + .error_header_early_termination(error_header_early_termination), + .error_payload_early_termination(error_payload_early_termination), + .error_invalid_header(error_invalid_header), + .error_invalid_checksum(error_invalid_checksum) +); + +endmodule diff --git a/tb/test_ip_eth_tx_64.py b/tb/test_ip_eth_tx_64.py new file mode 100755 index 000000000..976098c8f --- /dev/null +++ b/tb/test_ip_eth_tx_64.py @@ -0,0 +1,976 @@ +#!/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 eth_ep +import ip_ep + +module = 'ip_eth_tx_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_ip_eth_tx_64(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy, + error_payload_early_termination): + + 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_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tkeep=input_ip_payload_tkeep, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + busy=busy, + error_payload_early_termination=error_payload_early_termination) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_ip_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[64:]) + input_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + # Outputs + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[64:]) + output_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + error_payload_early_termination = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tkeep=input_ip_payload_tkeep, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_ip_eth_tx_64(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + busy, + error_payload_early_termination) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_payload_early_termination): + error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + + def wait_pause_source(): + while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = bytearray(range(payload_len)) + test_frame.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: trailing bytes (1), length %d" % payload_len) + current_test.next = 4 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00') + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: trailing bytes (10), length %d" % payload_len) + current_test.next = 5 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00'*10) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 6: trailing bytes with tuser assert (1), length %d" % payload_len) + current_test.next = 6 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00') + test_frame1a.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 7: trailing bytes with tuser assert (10), length %d" % payload_len) + current_test.next = 7 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00'*10) + test_frame1a.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 8: truncated payload (1), length %d" % payload_len) + current_test.next = 8 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len+1)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data = test_frame1a.payload.data[:-1] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 9: truncated payload (10), length %d" % payload_len) + current_test.next = 9 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.payload = bytearray(range(payload_len+10)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = ip_ep.IPFrame(test_frame1) + test_frame1a.payload.data = test_frame1a.payload.data[:-10] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_eth_tx_64.v b/tb/test_ip_eth_tx_64.v new file mode 100644 index 000000000..fea39c3e5 --- /dev/null +++ b/tb/test_ip_eth_tx_64.v @@ -0,0 +1,161 @@ +/* + +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_ip_eth_tx_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_ip_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [63:0] input_ip_payload_tdata = 0; +reg [7:0] input_ip_payload_tkeep = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +// Outputs +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [63:0] output_eth_payload_tdata; +wire [7:0] output_eth_payload_tkeep; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire busy; +wire error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_ip_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready); + $to_myhdl(input_ip_hdr_ready, + input_ip_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + busy, + error_payload_early_termination); + + // dump file + $dumpfile("test_ip_eth_tx_64.lxt"); + $dumpvars(0, test_ip_eth_tx_64); +end + +ip_eth_tx_64 +UUT ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Status signals + .busy(busy), + .error_payload_early_termination(error_payload_early_termination) +); + +endmodule From 8191b38e7a428d4a09aa77ac2f8944127a9e22af Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Sep 2014 16:25:37 -0700 Subject: [PATCH 030/617] Move header valid assign to top --- rtl/ip_eth_rx.v | 2 +- rtl/ip_eth_rx_64.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index 35a1da1b8..61ebed589 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -199,10 +199,10 @@ reg temp_ip_payload_tuser_reg = 0; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; assign output_eth_dest_mac = output_eth_dest_mac_reg; assign output_eth_src_mac = output_eth_src_mac_reg; assign output_eth_type = output_eth_type_reg; -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; assign output_ip_version = output_ip_version_reg; assign output_ip_ihl = output_ip_ihl_reg; assign output_ip_dscp = output_ip_dscp_reg; diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 510748e2b..9696b2e71 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -207,10 +207,10 @@ reg shift_eth_payload_extra_cycle; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; assign output_eth_dest_mac = output_eth_dest_mac_reg; assign output_eth_src_mac = output_eth_src_mac_reg; assign output_eth_type = output_eth_type_reg; -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; assign output_ip_version = output_ip_version_reg; assign output_ip_ihl = output_ip_ihl_reg; assign output_ip_dscp = output_ip_dscp_reg; From ebc1c7ccc6a561e6dae8084c19c1de3a7b7dbbb4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Sep 2014 16:26:23 -0700 Subject: [PATCH 031/617] Rename checksum to calc_checksum in ip_ep --- tb/ip_ep.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tb/ip_ep.py b/tb/ip_ep.py index 482429014..dbabe9a3b 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -117,7 +117,7 @@ class IPFrame(object): def update_length(self): self.ip_length = len(self.payload.data) + 20 - def checksum(self): + def calc_checksum(self): cksum = self.ip_version << 12 | self.ip_ihl << 8 | self.ip_dscp << 2 | self.ip_ecn cksum += self.ip_length cksum += self.ip_identification @@ -132,7 +132,7 @@ class IPFrame(object): return ~cksum & 0xffff def update_checksum(self): - self.ip_header_checksum = self.checksum() + self.ip_header_checksum = self.calc_checksum() def build(self): if self.ip_length is None: From 0f1eb94148e3eff624336916352052c6c64049f2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Sep 2014 16:26:59 -0700 Subject: [PATCH 032/617] Calculate header checksum for truncated packets --- tb/test_ip_eth_rx.py | 2 +- tb/test_ip_eth_rx_64.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index 168fc63ea..afd64ceb3 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -1115,7 +1115,7 @@ def bench(): test_frame1.ip_fragment_offset = 0 test_frame1.ip_ttl = 64 test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = 0x1234 + test_frame1.ip_header_checksum = None test_frame1.ip_source_ip = 0xc0a80164 test_frame1.ip_dest_ip = 0xc0a80165 test_frame1.payload = bytearray(range(16)) diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py index 16cc58158..30412987c 100755 --- a/tb/test_ip_eth_rx_64.py +++ b/tb/test_ip_eth_rx_64.py @@ -1125,7 +1125,7 @@ def bench(): test_frame1.ip_fragment_offset = 0 test_frame1.ip_ttl = 64 test_frame1.ip_protocol = 0x11 - test_frame1.ip_header_checksum = 0x1234 + test_frame1.ip_header_checksum = None test_frame1.ip_source_ip = 0xc0a80164 test_frame1.ip_dest_ip = 0xc0a80165 test_frame1.payload = bytearray(range(16)) From 20da100db61be5fd4c205dd679aa42a6c4b4dd46 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Sep 2014 16:52:42 -0700 Subject: [PATCH 033/617] Add UDP transmit and receive modules --- rtl/udp_ip_rx.v | 583 +++++++++++++++++++++ rtl/udp_ip_tx.v | 562 ++++++++++++++++++++ tb/test_udp_ip_rx.py | 1195 ++++++++++++++++++++++++++++++++++++++++++ tb/test_udp_ip_rx.v | 218 ++++++++ tb/test_udp_ip_tx.py | 1136 +++++++++++++++++++++++++++++++++++++++ tb/test_udp_ip_tx.v | 212 ++++++++ tb/udp_ep.py | 524 ++++++++++++++++++ 7 files changed, 4430 insertions(+) create mode 100644 rtl/udp_ip_rx.v create mode 100644 rtl/udp_ip_tx.v create mode 100755 tb/test_udp_ip_rx.py create mode 100644 tb/test_udp_ip_rx.v create mode 100755 tb/test_udp_ip_tx.py create mode 100644 tb/test_udp_ip_tx.v create mode 100644 tb/udp_ep.py diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v new file mode 100644 index 000000000..3184a1428 --- /dev/null +++ b/rtl/udp_ip_rx.v @@ -0,0 +1,583 @@ +/* + +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 + +/* + * UDP ethernet frame receiver (IP frame in, UDP frame out) + */ +module udp_ip_rx +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [7:0] input_ip_payload_tdata, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [7:0] output_udp_payload_tdata, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Status signals + */ + output wire busy, + output wire error_header_early_termination, + output wire error_payload_early_termination +); + +/* + +UDP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + + source port 2 octets + desination port 2 octets + length 2 octets + checksum 2 octets + + payload length octets + +This module receives an IP frame with decoded fields and decodes +the AXI packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_READ_HEADER = 3'd1, + STATE_READ_PAYLOAD_IDLE = 3'd2, + STATE_READ_PAYLOAD_TRANSFER = 3'd3, + STATE_READ_PAYLOAD_TRANSFER_WAIT = 3'd4, + STATE_READ_PAYLOAD_TRANSFER_LAST = 3'd5, + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST = 3'd6, + STATE_WAIT_LAST = 3'd7; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_ip_hdr; +reg store_udp_source_port_0; +reg store_udp_source_port_1; +reg store_udp_dest_port_0; +reg store_udp_dest_port_1; +reg store_udp_length_0; +reg store_udp_length_1; +reg store_udp_checksum_0; +reg store_udp_checksum_1; + +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg assert_tlast; +reg assert_tuser; + +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; + +reg input_ip_hdr_ready_reg = 0; +reg input_ip_payload_tready_reg = 0; + +reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [3:0] output_ip_version_reg = 0; +reg [3:0] output_ip_ihl_reg = 0; +reg [5:0] output_ip_dscp_reg = 0; +reg [1:0] output_ip_ecn_reg = 0; +reg [15:0] output_ip_length_reg = 0; +reg [15:0] output_ip_identification_reg = 0; +reg [2:0] output_ip_flags_reg = 0; +reg [12:0] output_ip_fragment_offset_reg = 0; +reg [7:0] output_ip_ttl_reg = 0; +reg [7:0] output_ip_protocol_reg = 0; +reg [15:0] output_ip_header_checksum_reg = 0; +reg [31:0] output_ip_source_ip_reg = 0; +reg [31:0] output_ip_dest_ip_reg = 0; +reg [15:0] output_udp_source_port_reg = 0; +reg [15:0] output_udp_dest_port_reg = 0; +reg [15:0] output_udp_length_reg = 0; +reg [15:0] output_udp_checksum_reg = 0; +reg [7:0] output_udp_payload_tdata_reg = 0; +reg output_udp_payload_tvalid_reg = 0; +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg busy_reg = 0; +reg error_header_early_termination_reg = 0, error_header_early_termination_next; +reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; + +reg [7:0] temp_udp_payload_tdata_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; + +assign input_ip_hdr_ready = input_ip_hdr_ready_reg; +assign input_ip_payload_tready = input_ip_payload_tready_reg; + +assign output_udp_hdr_valid = output_udp_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_udp_source_port = output_udp_source_port_reg; +assign output_udp_dest_port = output_udp_dest_port_reg; +assign output_udp_length = output_udp_length_reg; +assign output_udp_checksum = output_udp_checksum_reg; +assign output_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; +assign output_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_udp_payload_tuser = output_udp_payload_tuser_reg; + +assign busy = busy_reg; +assign error_header_early_termination = error_header_early_termination_reg; +assign error_payload_early_termination = error_payload_early_termination_reg; + +always @* begin + state_next = 2'bz; + + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + assert_tlast = 0; + assert_tuser = 0; + + store_ip_hdr = 0; + store_udp_source_port_0 = 0; + store_udp_source_port_1 = 0; + store_udp_dest_port_0 = 0; + store_udp_dest_port_1 = 0; + store_udp_length_0 = 0; + store_udp_length_1 = 0; + store_udp_checksum_0 = 0; + store_udp_checksum_1 = 0; + + frame_ptr_next = frame_ptr_reg; + + output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; + + error_header_early_termination_next = 0; + error_payload_early_termination_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for header + frame_ptr_next = 0; + + if (input_ip_hdr_ready & input_ip_hdr_valid) begin + frame_ptr_next = 0; + store_ip_hdr = 1; + state_next = STATE_READ_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_READ_HEADER: begin + // read header state + if (input_ip_payload_tvalid) begin + // word transfer in - store it + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_READ_HEADER; + + case (frame_ptr_reg) + 8'h00: store_udp_source_port_1 = 1; + 8'h01: store_udp_source_port_0 = 1; + 8'h02: store_udp_dest_port_1 = 1; + 8'h03: store_udp_dest_port_0 = 1; + 8'h04: store_udp_length_1 = 1; + 8'h05: store_udp_length_0 = 1; + 8'h06: store_udp_checksum_1 = 1; + 8'h07: begin + store_udp_checksum_0 = 1; + output_udp_hdr_valid_next = 1; + state_next = STATE_READ_PAYLOAD_IDLE; + end + endcase + + if (input_ip_payload_tlast) begin + state_next = STATE_IDLE; + output_udp_hdr_valid_next = 0; + error_header_early_termination_next = 1; + end + + end else begin + state_next = STATE_READ_HEADER; + end + end + STATE_READ_PAYLOAD_IDLE: begin + // idle; no data in registers + if (input_ip_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+1; + if (input_ip_payload_tlast) begin + if (frame_ptr_next != output_udp_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == output_udp_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_READ_PAYLOAD_IDLE; + end + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register + if (input_ip_payload_tvalid & output_udp_payload_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+1; + if (input_ip_payload_tlast) begin + if (frame_ptr_next != output_udp_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == output_udp_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else if (~input_ip_payload_tvalid & output_udp_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_READ_PAYLOAD_IDLE; + end else if (input_ip_payload_tvalid & ~output_udp_payload_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in both output and temp registers + if (output_udp_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_udp_payload_tlast_reg) begin + if (frame_ptr_next != output_udp_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == output_udp_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + if (output_udp_payload_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + if (input_ip_payload_tvalid) begin + if (input_ip_payload_tlast) begin + // assert tlast and transfer tuser + assert_tlast = 1; + assert_tuser = input_ip_payload_tuser; + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + if (input_ip_payload_tvalid) begin + if (input_ip_payload_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end else begin + state_next = STATE_WAIT_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_udp_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_udp_source_port_reg <= 0; + output_udp_dest_port_reg <= 0; + output_udp_length_reg <= 0; + output_udp_checksum_reg <= 0; + output_udp_payload_tdata_reg <= 0; + output_udp_payload_tvalid_reg <= 0; + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + busy_reg <= 0; + error_header_early_termination_reg <= 0; + error_payload_early_termination_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + + error_header_early_termination_reg <= error_header_early_termination_next; + error_payload_early_termination_reg <= error_payload_early_termination_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_ip_hdr_ready_reg <= ~output_udp_hdr_valid; + input_ip_payload_tready_reg <= 0; + output_udp_payload_tvalid_reg <= 0; + end + STATE_READ_HEADER: begin + // read header; accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_udp_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_IDLE: begin + // read payload; no data in registers; accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_udp_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register; accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_udp_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in output and temp registers; do not accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_udp_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_udp_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_udp_payload_tvalid_reg <= 0; + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_udp_payload_tvalid_reg <= 0; + end + endcase + + // datapath + if (store_ip_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + output_ip_version_reg <= input_ip_version; + output_ip_ihl_reg <= input_ip_ihl; + output_ip_dscp_reg <= input_ip_dscp; + output_ip_ecn_reg <= input_ip_ecn; + output_ip_length_reg <= input_ip_length; + output_ip_identification_reg <= input_ip_identification; + output_ip_flags_reg <= input_ip_flags; + output_ip_fragment_offset_reg <= input_ip_fragment_offset; + output_ip_ttl_reg <= input_ip_ttl; + output_ip_protocol_reg <= input_ip_protocol; + output_ip_header_checksum_reg <= input_ip_header_checksum; + output_ip_source_ip_reg <= input_ip_source_ip; + output_ip_dest_ip_reg <= input_ip_dest_ip; + end + + if (store_udp_source_port_0) output_udp_source_port_reg[ 7: 0] <= input_ip_payload_tdata; + if (store_udp_source_port_1) output_udp_source_port_reg[15: 8] <= input_ip_payload_tdata; + if (store_udp_dest_port_0) output_udp_dest_port_reg[ 7: 0] <= input_ip_payload_tdata; + if (store_udp_dest_port_1) output_udp_dest_port_reg[15: 8] <= input_ip_payload_tdata; + if (store_udp_length_0) output_udp_length_reg[ 7: 0] <= input_ip_payload_tdata; + if (store_udp_length_1) output_udp_length_reg[15: 8] <= input_ip_payload_tdata; + if (store_udp_checksum_0) output_udp_checksum_reg[ 7: 0] <= input_ip_payload_tdata; + if (store_udp_checksum_1) output_udp_checksum_reg[15: 8] <= input_ip_payload_tdata; + + if (transfer_in_out) begin + output_udp_payload_tdata_reg <= input_ip_payload_tdata; + output_udp_payload_tlast_reg <= input_ip_payload_tlast; + output_udp_payload_tuser_reg <= input_ip_payload_tuser; + end else if (transfer_in_temp) begin + temp_udp_payload_tdata_reg <= input_ip_payload_tdata; + temp_udp_payload_tlast_reg <= input_ip_payload_tlast; + temp_udp_payload_tuser_reg <= input_ip_payload_tuser; + end else if (transfer_temp_out) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (assert_tlast) output_udp_payload_tlast_reg <= 1; + if (assert_tuser) output_udp_payload_tuser_reg <= 1; + end +end + +endmodule diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v new file mode 100644 index 000000000..208a76d15 --- /dev/null +++ b/rtl/udp_ip_tx.v @@ -0,0 +1,562 @@ +/* + +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 + +/* + * UDP ethernet frame transmitter (UDP frame in, IP frame out) + */ +module udp_ip_tx +( + input wire clk, + input wire rst, + + /* + * UDP frame input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [7:0] input_udp_payload_tdata, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Status signals + */ + output wire busy, + output wire error_payload_early_termination +); + +/* + +UDP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + + source port 2 octets + desination port 2 octets + length 2 octets + checksum 2 octets + + payload length octets + +This module receives an IP frame with decoded fields and decodes +the AXI packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_WRITE_HEADER = 3'd1, + STATE_WRITE_PAYLOAD_IDLE = 3'd2, + STATE_WRITE_PAYLOAD_TRANSFER = 3'd3, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 3'd4, + STATE_WRITE_PAYLOAD_TRANSFER_LAST = 3'd5, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST = 3'd6, + STATE_WAIT_LAST = 3'd7; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_udp_hdr; + +reg [7:0] write_hdr_data; +reg write_hdr_out; + +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg assert_tlast; +reg assert_tuser; + +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [15:0] hdr_sum_reg = 0, hdr_sum_next; + +reg [15:0] udp_source_port_reg = 0; +reg [15:0] udp_dest_port_reg = 0; +reg [15:0] udp_length_reg = 0; +reg [15:0] udp_checksum_reg = 0; + +reg input_udp_hdr_ready_reg = 0; +reg input_udp_payload_tready_reg = 0; + +reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [3:0] output_ip_version_reg = 0; +reg [3:0] output_ip_ihl_reg = 0; +reg [5:0] output_ip_dscp_reg = 0; +reg [1:0] output_ip_ecn_reg = 0; +reg [15:0] output_ip_length_reg = 0; +reg [15:0] output_ip_identification_reg = 0; +reg [2:0] output_ip_flags_reg = 0; +reg [12:0] output_ip_fragment_offset_reg = 0; +reg [7:0] output_ip_ttl_reg = 0; +reg [7:0] output_ip_protocol_reg = 0; +reg [15:0] output_ip_header_checksum_reg = 0; +reg [31:0] output_ip_source_ip_reg = 0; +reg [31:0] output_ip_dest_ip_reg = 0; +reg [7:0] output_ip_payload_tdata_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg busy_reg = 0; +reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; + +reg [7:0] temp_ip_payload_tdata_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign input_udp_hdr_ready = input_udp_hdr_ready_reg; +assign input_udp_payload_tready = input_udp_payload_tready_reg; + +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +assign busy = busy_reg; +assign error_payload_early_termination = error_payload_early_termination_reg; + +always @* begin + state_next = 2'bz; + + store_udp_hdr = 0; + + write_hdr_data = 0; + write_hdr_out = 0; + + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + assert_tlast = 0; + assert_tuser = 0; + + frame_ptr_next = frame_ptr_reg; + + hdr_sum_next = hdr_sum_reg; + + output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + + error_payload_early_termination_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_udp_hdr_valid & input_udp_hdr_ready) begin + store_udp_hdr = 1; + write_hdr_out = 1; + write_hdr_data = input_udp_source_port[15: 8]; + output_ip_hdr_valid_next = 1; + frame_ptr_next = 1; + state_next = STATE_WRITE_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_HEADER: begin + // write header state + if (output_ip_payload_tready) begin + // word transfer out + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_WRITE_HEADER; + write_hdr_out = 1; + case (frame_ptr_reg) + 8'h01: write_hdr_data = udp_source_port_reg[ 7: 0]; + 8'h02: write_hdr_data = udp_dest_port_reg[15: 8]; + 8'h03: write_hdr_data = udp_dest_port_reg[ 7: 0]; + 8'h04: write_hdr_data = udp_length_reg[15: 8]; + 8'h05: write_hdr_data = udp_length_reg[ 7: 0]; + 8'h06: write_hdr_data = udp_checksum_reg[15: 8]; + 8'h07: begin + write_hdr_data = udp_checksum_reg[ 7: 0]; + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + endcase + end else begin + state_next = STATE_WRITE_HEADER; + end + end + STATE_WRITE_PAYLOAD_IDLE: begin + // idle; no data in registers + if (input_udp_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+1; + if (input_udp_payload_tlast) begin + if (frame_ptr_next != udp_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == udp_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_WRITE_PAYLOAD_IDLE; + end + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // write payload; data in output register + if (input_udp_payload_tvalid & output_ip_payload_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+1; + if (input_udp_payload_tlast) begin + if (frame_ptr_next != udp_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == udp_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else if (~input_udp_payload_tvalid & output_ip_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_WRITE_PAYLOAD_IDLE; + end else if (input_udp_payload_tvalid & ~output_ip_payload_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + frame_ptr_next = frame_ptr_reg+1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // write payload; data in both output and temp registers + if (output_ip_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_ip_payload_tlast_reg) begin + if (frame_ptr_next != udp_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next == udp_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // write last payload word; data in output register; do not accept new data + if (output_ip_payload_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + if (input_udp_payload_tvalid) begin + if (input_udp_payload_tlast) begin + // assert tlast and transfer tuser + assert_tlast = 1; + assert_tuser = input_udp_payload_tuser; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + if (input_udp_payload_tvalid) begin + if (input_udp_payload_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end else begin + state_next = STATE_WAIT_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + hdr_sum_reg <= 0; + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; + udp_source_port_reg <= 0; + udp_dest_port_reg <= 0; + udp_length_reg <= 0; + udp_checksum_reg <= 0; + output_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + busy_reg <= 0; + error_payload_early_termination_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + hdr_sum_reg <= hdr_sum_next; + + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + + busy_reg <= state_next != STATE_IDLE; + + error_payload_early_termination_reg <= error_payload_early_termination_next; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_udp_hdr_ready_reg <= 1; + input_udp_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + end + STATE_WRITE_HEADER: begin + // write header + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_IDLE: begin + // write payload; no data in registers; accept new data + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // write payload; data in output register; accept new data + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // write payload; data in output and temp registers; do not accept new data + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // write last payload word; data in output register; do not accept new data + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 0; + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 0; + end + endcase + + if (store_udp_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + output_ip_version_reg <= input_ip_version; + output_ip_ihl_reg <= input_ip_ihl; + output_ip_dscp_reg <= input_ip_dscp; + output_ip_ecn_reg <= input_ip_ecn; + output_ip_length_reg <= input_udp_length + 20; + output_ip_identification_reg <= input_ip_identification; + output_ip_flags_reg <= input_ip_flags; + output_ip_fragment_offset_reg <= input_ip_fragment_offset; + output_ip_ttl_reg <= input_ip_ttl; + output_ip_protocol_reg <= input_ip_protocol; + output_ip_header_checksum_reg <= input_ip_header_checksum; + output_ip_source_ip_reg <= input_ip_source_ip; + output_ip_dest_ip_reg <= input_ip_dest_ip; + udp_source_port_reg <= input_udp_source_port; + udp_dest_port_reg <= input_udp_dest_port; + udp_length_reg <= input_udp_length; + udp_checksum_reg <= input_udp_checksum; + end + + if (write_hdr_out) begin + output_ip_payload_tdata_reg <= write_hdr_data; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + end else if (transfer_in_out) begin + output_ip_payload_tdata_reg <= input_udp_payload_tdata; + output_ip_payload_tlast_reg <= input_udp_payload_tlast; + output_ip_payload_tuser_reg <= input_udp_payload_tuser; + end else if (transfer_in_temp) begin + temp_ip_payload_tdata_reg <= input_udp_payload_tdata; + temp_ip_payload_tlast_reg <= input_udp_payload_tlast; + temp_ip_payload_tuser_reg <= input_udp_payload_tuser; + end else if (transfer_temp_out) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (assert_tlast) output_ip_payload_tlast_reg <= 1; + if (assert_tuser) output_ip_payload_tuser_reg <= 1; + end +end + +endmodule diff --git a/tb/test_udp_ip_rx.py b/tb/test_udp_ip_rx.py new file mode 100755 index 000000000..6b7047651 --- /dev/null +++ b/tb/test_udp_ip_rx.py @@ -0,0 +1,1195 @@ +#!/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 eth_ep +import ip_ep +import udp_ep + +module = 'udp_ip_rx' + +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_udp_ip_rx(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + busy, + error_header_early_termination, + error_payload_early_termination): + + 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_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + busy=busy, + error_header_early_termination=error_header_early_termination, + error_payload_early_termination=error_payload_early_termination) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_ip_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + output_udp_payload_tready = Signal(bool(0)) + + # Outputs + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + output_udp_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + error_header_early_termination = Signal(bool(0)) + error_payload_early_termination = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_udp_ip_rx(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + busy, + error_header_early_termination, + error_payload_early_termination) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_header_early_termination_asserted = Signal(bool(0)) + error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_header_early_termination): + error_header_early_termination_asserted.next = 1 + if (error_payload_early_termination): + error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + + def wait_pause_source(): + while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(payload_len)) + test_frame.build() + ip_frame = test_frame.build_ip() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: trailing bytes (1), length %d" % payload_len) + current_test.next = 4 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data += bytearray(b'\x00') + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: trailing bytes (10), length %d" % payload_len) + current_test.next = 5 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data += bytearray(b'\x00'*10) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 6: trailing bytes with tuser assert (1), length %d" % payload_len) + current_test.next = 6 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data += bytearray(b'\x00') + ip_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 7: trailing bytes with tuser assert (10), length %d" % payload_len) + current_test.next = 7 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data += bytearray(b'\x00'*10) + ip_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 8: truncated payload (1), length %d" % payload_len) + current_test.next = 8 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len+1)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data = ip_frame1.payload.data[:-1] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 9: truncated payload (10), length %d" % payload_len) + current_test.next = 9 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len+10)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data = ip_frame1.payload.data[:-10] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + for length in range(1,9): + yield clk.posedge + print("test 10: truncated header, length %d" % length) + current_test.next = 10 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(16)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(16)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data = ip_frame1.payload.data[:length] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_header_early_termination_asserted.next = 0 + + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_header_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_ip_rx.v b/tb/test_udp_ip_rx.v new file mode 100644 index 000000000..a750e65f9 --- /dev/null +++ b/tb/test_udp_ip_rx.v @@ -0,0 +1,218 @@ +/* + +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_udp_ip_rx; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_ip_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [7:0] input_ip_payload_tdata = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; + +// Outputs +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire output_udp_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [7:0] output_udp_payload_tdata; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; +wire busy; +wire error_header_early_termination; +wire error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_ip_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + output_udp_hdr_ready, + output_udp_payload_tready); + $to_myhdl(input_ip_hdr_ready, + input_ip_payload_tready, + output_udp_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser, + busy, + error_header_early_termination, + error_payload_early_termination); + + // dump file + $dumpfile("test_udp_ip_rx.lxt"); + $dumpvars(0, test_udp_ip_rx); +end + +udp_ip_rx +UUT ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status signals + .busy(busy), + .error_header_early_termination(error_header_early_termination), + .error_payload_early_termination(error_payload_early_termination) +); + +endmodule diff --git a/tb/test_udp_ip_tx.py b/tb/test_udp_ip_tx.py new file mode 100755 index 000000000..be2f69062 --- /dev/null +++ b/tb/test_udp_ip_tx.py @@ -0,0 +1,1136 @@ +#!/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 eth_ep +import ip_ep +import udp_ep + +module = 'udp_ip_tx' + +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_udp_ip_tx(clk, + rst, + current_test, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + busy, + error_payload_early_termination): + + 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_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_length=input_udp_length, + input_udp_checksum=input_udp_checksum, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + busy=busy, + error_payload_early_termination=error_payload_early_termination) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_udp_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_length = Signal(intbv(0)[16:]) + input_udp_checksum = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + + # Outputs + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + error_payload_early_termination = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_valid=input_udp_hdr_valid, + udp_hdr_ready=input_udp_hdr_ready, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_length=input_udp_length, + udp_checksum=input_udp_checksum, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_udp_ip_tx(clk, + rst, + current_test, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + busy, + error_payload_early_termination) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_payload_early_termination): + error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + yield clk.posedge + + def wait_pause_source(): + while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(payload_len)) + test_frame.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: trailing bytes (1), length %d" % payload_len) + current_test.next = 4 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00') + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: trailing bytes (10), length %d" % payload_len) + current_test.next = 5 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00'*10) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 6: trailing bytes with tuser assert (1), length %d" % payload_len) + current_test.next = 6 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00') + test_frame1a.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 7: trailing bytes with tuser assert (10), length %d" % payload_len) + current_test.next = 7 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00'*10) + test_frame1a.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 8: truncated payload (1), length %d" % payload_len) + current_test.next = 8 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len+1)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data = test_frame1a.payload.data[:-1] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 9: truncated payload (10), length %d" % payload_len) + current_test.next = 9 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len+10)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data = test_frame1.payload.data[:-10] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_ip_tx.v b/tb/test_udp_ip_tx.v new file mode 100644 index 000000000..fb4e3b4c4 --- /dev/null +++ b/tb/test_udp_ip_tx.v @@ -0,0 +1,212 @@ +/* + +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_udp_ip_tx; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_udp_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [15:0] input_udp_length = 0; +reg [15:0] input_udp_checksum = 0; +reg [7:0] input_udp_payload_tdata = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; + +// Outputs +wire input_udp_hdr_ready; +wire input_udp_payload_tready; +wire output_ip_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [7:0] output_ip_payload_tdata; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire busy; +wire error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_udp_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_ip_hdr_ready, + output_ip_payload_tready); + $to_myhdl(input_udp_hdr_ready, + input_udp_payload_tready, + output_ip_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + busy, + error_payload_early_termination); + + // dump file + $dumpfile("test_udp_ip_tx.lxt"); + $dumpvars(0, test_udp_ip_tx); +end + +udp_ip_tx +UUT ( + .clk(clk), + .rst(rst), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .busy(busy), + .error_payload_early_termination(error_payload_early_termination) +); + +endmodule diff --git a/tb/udp_ep.py b/tb/udp_ep.py new file mode 100644 index 000000000..d0f6d2050 --- /dev/null +++ b/tb/udp_ep.py @@ -0,0 +1,524 @@ +""" + +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 axis_ep +import eth_ep +import ip_ep +from Queue import Queue +import struct + +class UDPFrame(object): + def __init__(self, payload='', + eth_dest_mac=0, + eth_src_mac=0, + eth_type=0, + ip_version=4, + ip_ihl=5, + ip_dscp=0, + ip_ecn=0, + ip_length=None, + ip_identification=0, + ip_flags=2, + ip_fragment_offset=0, + ip_ttl=64, + ip_protocol=0x11, + ip_header_checksum=None, + ip_source_ip=0xc0a80164, + ip_dest_ip=0xc0a80165, + udp_source_port=1, + udp_dest_port=2, + udp_length=None, + udp_checksum=None): + + self._payload = axis_ep.AXIStreamFrame() + self.eth_dest_mac = eth_dest_mac + self.eth_src_mac = eth_src_mac + self.eth_type = eth_type + self.ip_version = ip_version + self.ip_ihl = ip_ihl + self.ip_dscp = ip_dscp + self.ip_ecn = ip_ecn + self.ip_length = ip_length + self.ip_identification = ip_identification + self.ip_flags = ip_flags + self.ip_fragment_offset = ip_fragment_offset + self.ip_ttl = ip_ttl + self.ip_protocol = ip_protocol + self.ip_header_checksum = ip_header_checksum + self.ip_source_ip = ip_source_ip + self.ip_dest_ip = ip_dest_ip + self.udp_source_port = udp_source_port + self.udp_dest_port = udp_dest_port + self.udp_length = udp_length + self.udp_checksum = udp_checksum + + if type(payload) is dict: + self.payload = axis_ep.AXIStreamFrame(payload['udp_payload']) + self.eth_dest_mac = payload['eth_dest_mac'] + self.eth_src_mac = payload['eth_src_mac'] + self.eth_type = payload['eth_type'] + self.ip_version = payload['ip_version'] + self.ip_ihl = payload['ip_ihl'] + self.ip_dscp = payload['ip_dscp'] + self.ip_ecn = payload['ip_ecn'] + self.ip_length = payload['ip_length'] + self.ip_identification = payload['ip_identification'] + self.ip_flags = payload['ip_flags'] + self.ip_fragment_offset = payload['ip_fragment_offset'] + self.ip_ttl = payload['ip_ttl'] + self.ip_protocol = payload['ip_protocol'] + self.ip_header_checksum = payload['ip_header_checksum'] + self.ip_source_ip = payload['ip_source_ip'] + self.ip_dest_ip = payload['ip_dest_ip'] + self.udp_source_port = payload['udp_source_port'] + self.udp_dest_port = payload['udp_dest_port'] + self.udp_length = payload['udp_length'] + self.udp_checksum = payload['udp_checksum'] + if type(payload) is bytes: + payload = bytearray(payload) + if type(payload) is bytearray or type(payload) is axis_ep.AXIStreamFrame: + self.payload = axis_ep.AXIStreamFrame(payload) + if type(payload) is UDPFrame: + self.payload = axis_ep.AXIStreamFrame(payload.payload) + self.eth_dest_mac = payload.eth_dest_mac + self.eth_src_mac = payload.eth_src_mac + self.eth_type = payload.eth_type + self.ip_version = payload.ip_version + self.ip_ihl = payload.ip_ihl + self.ip_dscp = payload.ip_dscp + self.ip_ecn = payload.ip_ecn + self.ip_length = payload.ip_length + self.ip_identification = payload.ip_identification + self.ip_flags = payload.ip_flags + self.ip_fragment_offset = payload.ip_fragment_offset + self.ip_ttl = payload.ip_ttl + self.ip_protocol = payload.ip_protocol + self.ip_header_checksum = payload.ip_header_checksum + self.ip_source_ip = payload.ip_source_ip + self.ip_dest_ip = payload.ip_dest_ip + self.udp_source_port = payload.udp_source_port + self.udp_dest_port = payload.udp_dest_port + self.udp_length = payload.udp_length + self.udp_checksum = payload.udp_checksum + + @property + def payload(self): + return self._payload + + @payload.setter + def payload(self, value): + self._payload = axis_ep.AXIStreamFrame(value) + + def update_ip_length(self): + self.ip_length = self.udp_length + 20 + + def update_udp_length(self): + self.udp_length = len(self.payload.data) + 8 + + def update_length(self): + self.update_udp_length() + self.update_ip_length() + + def calc_ip_checksum(self): + cksum = self.ip_version << 12 | self.ip_ihl << 8 | self.ip_dscp << 2 | self.ip_ecn + cksum += self.ip_length + cksum += self.ip_identification + cksum += self.ip_flags << 13 | self.ip_fragment_offset + cksum += self.ip_ttl << 8 | self.ip_protocol + cksum += self.ip_source_ip & 0xffff + cksum += (self.ip_source_ip >> 16) & 0xffff + cksum += self.ip_dest_ip & 0xffff + cksum += (self.ip_dest_ip >> 16) & 0xffff + cksum = (cksum & 0xffff) + (cksum >> 16) + cksum = (cksum & 0xffff) + (cksum >> 16) + return ~cksum & 0xffff + + def calc_udp_checksum(self): + cksum = self.ip_source_ip & 0xffff + cksum += (self.ip_source_ip >> 16) & 0xffff + cksum += self.ip_dest_ip & 0xffff + cksum += (self.ip_dest_ip >> 16) & 0xffff + cksum += self.ip_protocol + cksum += self.udp_length + cksum += self.udp_source_port + cksum += self.udp_dest_port + cksum += self.udp_length + odd = False + for d in self.payload.data: + if odd: + cksum += d + else: + cksum += d << 8 + odd = not odd + cksum = (cksum & 0xffff) + (cksum >> 16) + cksum = (cksum & 0xffff) + (cksum >> 16) + return ~cksum & 0xffff + + def update_ip_checksum(self): + self.ip_header_checksum = self.calc_ip_checksum() + + def update_udp_checksum(self): + self.udp_checksum = self.calc_udp_checksum() + + def update_checksum(self): + self.update_udp_checksum() + self.update_ip_checksum() + + def build(self): + if self.udp_length is None: + self.update_udp_length() + if self.udp_checksum is None: + self.update_udp_checksum() + if self.ip_length is None: + self.update_ip_length() + if self.ip_header_checksum is None: + self.update_ip_checksum() + + def build_axis(self): + return self.build_eth().build_axis() + + def build_eth(self): + return self.build_ip().build_eth() + + def build_ip(self): + self.build() + data = '' + + data += struct.pack('>H', self.udp_source_port) + data += struct.pack('>H', self.udp_dest_port) + data += struct.pack('>H', self.udp_length) + data += struct.pack('>H', self.udp_checksum) + + data += self.payload.data + + return ip_ep.IPFrame(data, + self.eth_dest_mac, + self.eth_src_mac, + self.eth_type, + self.ip_version, + self.ip_ihl, + self.ip_dscp, + self.ip_ecn, + self.ip_length, + self.ip_identification, + self.ip_flags, + self.ip_fragment_offset, + self.ip_ttl, + self.ip_protocol, + self.ip_header_checksum, + self.ip_source_ip, + self.ip_dest_ip) + + def parse_axis(self, data): + frame = eth_ep.EthFrame() + frame.parse_axis(data) + self.parse_eth(frame) + + def parse_eth(self, data): + frame = ip_ep.IPFrame() + frame.parse_eth(data) + self.parse_ip(data) + + def parse_ip(self, data): + self.eth_src_mac = data.eth_src_mac + self.eth_dest_mac = data.eth_dest_mac + self.eth_type = data.eth_type + self.ip_version = data.ip_version + self.ip_ihl = data.ip_ihl + self.ip_dscp = data.ip_dscp + self.ip_ecn = data.ip_ecn + self.ip_length = data.ip_length + self.ip_identification = data.ip_identification + self.ip_flags = data.ip_flags + self.ip_fragment_offset = data.ip_fragment_offset + self.ip_ttl = data.ip_ttl + self.ip_protocol = data.ip_protocol + self.ip_header_checksum = data.ip_header_checksum + self.ip_source_ip = data.ip_source_ip + self.ip_dest_ip = data.ip_dest_ip + + self.udp_source_port = struct.unpack('>H', data.payload.data[0:2])[0] + self.udp_dest_port = struct.unpack('>H', data.payload.data[2:4])[0] + self.udp_length = struct.unpack('>H', data.payload.data[4:6])[0] + self.udp_checksum = struct.unpack('>H', data.payload.data[6:8])[0] + + self.payload = axis_ep.AXIStreamFrame(data.payload.data[8:]) + + def __eq__(self, other): + if type(other) is UDPFrame: + return (self.eth_src_mac == other.eth_src_mac and + self.eth_dest_mac == other.eth_dest_mac and + self.eth_type == other.eth_type and + self.ip_version == other.ip_version and + self.ip_ihl == other.ip_ihl and + self.ip_dscp == other.ip_dscp and + self.ip_ecn == other.ip_ecn and + self.ip_length == other.ip_length and + self.ip_identification == other.ip_identification and + self.ip_flags == other.ip_flags and + self.ip_fragment_offset == other.ip_fragment_offset and + self.ip_ttl == other.ip_ttl and + self.ip_protocol == other.ip_protocol and + self.ip_header_checksum == other.ip_header_checksum and + self.ip_source_ip == other.ip_source_ip and + self.ip_dest_ip == other.ip_dest_ip and + self.udp_source_port == other.udp_source_port and + self.udp_dest_port == other.udp_dest_port and + self.udp_length == other.udp_length and + self.udp_checksum == other.udp_checksum and + self.payload == other.payload) + + def __repr__(self): + return (('UDPFrame(payload=%s, ' % repr(self.payload)) + + ('eth_dest_mac=0x%012x, ' % self.eth_dest_mac) + + ('eth_src_mac=0x%012x, ' % self.eth_src_mac) + + ('eth_type=0x%04x, ' % self.eth_type) + + ('ip_version=%d, ' % self.ip_version) + + ('ip_ihl=%d, ' % self.ip_ihl) + + ('ip_dscp=%d, ' % self.ip_dscp) + + ('ip_ecn=%d, ' % self.ip_ecn) + + ('ip_length=%d, ' % self.ip_length) + + ('ip_identification=%d, ' % self.ip_identification) + + ('ip_flags=%d, ' % self.ip_flags) + + ('ip_fragment_offset=%d, ' % self.ip_fragment_offset) + + ('ip_ttl=%d, ' % self.ip_ttl) + + ('ip_protocol=0x%02x, ' % self.ip_protocol) + + ('ip_header_checksum=%x, ' % self.ip_header_checksum) + + ('ip_source_ip=0x%08x, ' % self.ip_source_ip) + + ('ip_dest_ip=0x%08x, ' % self.ip_dest_ip) + + ('udp_source_port=%d, ' % self.udp_source_port) + + ('udp_dest_port=%d, ' % self.udp_dest_port) + + ('udp_length=%d, ' % self.udp_length) + + ('udp_checksum=%04x)' % self.udp_checksum)) + +def UDPFrameSource(clk, rst, + udp_hdr_valid=None, + udp_hdr_ready=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + ip_version=Signal(intbv(4)[4:]), + ip_ihl=Signal(intbv(5)[4:]), + ip_dscp=Signal(intbv(0)[6:]), + ip_ecn=Signal(intbv(0)[2:]), + ip_length=Signal(intbv(0)[16:]), + ip_identification=Signal(intbv(0)[16:]), + ip_flags=Signal(intbv(0)[3:]), + ip_fragment_offset=Signal(intbv(0)[13:]), + ip_ttl=Signal(intbv(0)[8:]), + ip_protocol=Signal(intbv(0)[8:]), + ip_header_checksum=Signal(intbv(0)[16:]), + ip_source_ip=Signal(intbv(0)[32:]), + ip_dest_ip=Signal(intbv(0)[32:]), + udp_source_port=(intbv(0)[16:]), + udp_dest_port=(intbv(0)[16:]), + udp_length=(intbv(0)[16:]), + udp_checksum=(intbv(0)[16:]), + udp_payload_tdata=None, + udp_payload_tkeep=Signal(bool(True)), + udp_payload_tvalid=Signal(bool(False)), + udp_payload_tready=Signal(bool(True)), + udp_payload_tlast=Signal(bool(False)), + udp_payload_tuser=Signal(bool(False)), + fifo=None, + pause=0, + name=None): + + udp_hdr_ready_int = Signal(bool(False)) + udp_hdr_valid_int = Signal(bool(False)) + udp_payload_pause = Signal(bool(False)) + + udp_payload_fifo = Queue() + + udp_payload_source = axis_ep.AXIStreamSource(clk, + rst, + tdata=udp_payload_tdata, + tkeep=udp_payload_tkeep, + tvalid=udp_payload_tvalid, + tready=udp_payload_tready, + tlast=udp_payload_tlast, + tuser=udp_payload_tuser, + fifo=udp_payload_fifo, + pause=udp_payload_pause) + + @always_comb + def pause_logic(): + udp_hdr_ready_int.next = udp_hdr_ready and not pause + udp_hdr_valid.next = udp_hdr_valid_int and not pause + udp_payload_pause.next = pause # or udp_hdr_valid_int + + @instance + def logic(): + frame = dict() + + while True: + yield clk.posedge, rst.posedge + + if rst: + udp_hdr_valid_int.next = False + else: + if udp_hdr_ready_int: + udp_hdr_valid_int.next = False + if (udp_payload_tlast and udp_hdr_ready_int and udp_hdr_valid) or not udp_hdr_valid_int: + if not fifo.empty(): + frame = fifo.get() + frame = UDPFrame(frame) + frame.build() + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + ip_version.next = frame.ip_version + ip_ihl.next = frame.ip_ihl + ip_dscp.next = frame.ip_dscp + ip_ecn.next = frame.ip_ecn + ip_length.next = frame.ip_length + ip_identification.next = frame.ip_identification + ip_flags.next = frame.ip_flags + ip_fragment_offset.next = frame.ip_fragment_offset + ip_ttl.next = frame.ip_ttl + ip_protocol.next = frame.ip_protocol + ip_header_checksum.next = frame.ip_header_checksum + ip_source_ip.next = frame.ip_source_ip + ip_dest_ip.next = frame.ip_dest_ip + udp_source_port.next = frame.udp_source_port + udp_dest_port.next = frame.udp_dest_port + udp_length.next = frame.udp_length + udp_checksum.next = frame.udp_checksum + udp_payload_fifo.put(frame.payload) + + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + + udp_hdr_valid_int.next = True + + return logic, pause_logic, udp_payload_source + + +def UDPFrameSink(clk, rst, + udp_hdr_valid=None, + udp_hdr_ready=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + ip_version=Signal(intbv(4)[4:]), + ip_ihl=Signal(intbv(5)[4:]), + ip_dscp=Signal(intbv(0)[6:]), + ip_ecn=Signal(intbv(0)[2:]), + ip_length=Signal(intbv(0)[16:]), + ip_identification=Signal(intbv(0)[16:]), + ip_flags=Signal(intbv(0)[3:]), + ip_fragment_offset=Signal(intbv(0)[13:]), + ip_ttl=Signal(intbv(0)[8:]), + ip_protocol=Signal(intbv(0)[8:]), + ip_header_checksum=Signal(intbv(0)[16:]), + ip_source_ip=Signal(intbv(0)[32:]), + ip_dest_ip=Signal(intbv(0)[32:]), + udp_source_port=(intbv(0)[16:]), + udp_dest_port=(intbv(0)[16:]), + udp_length=(intbv(0)[16:]), + udp_checksum=(intbv(0)[16:]), + udp_payload_tdata=None, + udp_payload_tkeep=Signal(bool(True)), + udp_payload_tvalid=Signal(bool(True)), + udp_payload_tready=Signal(bool(True)), + udp_payload_tlast=Signal(bool(True)), + udp_payload_tuser=Signal(bool(False)), + fifo=None, + pause=0, + name=None): + + udp_hdr_ready_int = Signal(bool(False)) + udp_hdr_valid_int = Signal(bool(False)) + udp_payload_pause = Signal(bool(False)) + + udp_payload_fifo = Queue() + udp_header_fifo = Queue() + + udp_payload_sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=udp_payload_tdata, + tkeep=udp_payload_tkeep, + tvalid=udp_payload_tvalid, + tready=udp_payload_tready, + tlast=udp_payload_tlast, + tuser=udp_payload_tuser, + fifo=udp_payload_fifo, + pause=udp_payload_pause) + + @always_comb + def pause_logic(): + udp_hdr_ready.next = udp_hdr_ready_int and not pause + udp_hdr_valid_int.next = udp_hdr_valid and not pause + udp_payload_pause.next = pause # or udp_hdr_valid_int + + @instance + def logic(): + frame = UDPFrame() + + while True: + yield clk.posedge, rst.posedge + + if rst: + udp_hdr_ready_int.next = False + frame = UDPFrame() + else: + udp_hdr_ready_int.next = True + + if udp_hdr_ready_int and udp_hdr_valid_int: + frame = UDPFrame() + frame.eth_dest_mac = int(eth_dest_mac) + frame.eth_src_mac = int(eth_src_mac) + frame.eth_type = int(eth_type) + frame.ip_version = int(ip_version) + frame.ip_ihl = int(ip_ihl) + frame.ip_dscp = int(ip_dscp) + frame.ip_ecn = int(ip_ecn) + frame.ip_length = int(ip_length) + frame.ip_identification = int(ip_identification) + frame.ip_flags = int(ip_flags) + frame.ip_fragment_offset = int(ip_fragment_offset) + frame.ip_ttl = int(ip_ttl) + frame.ip_protocol = int(ip_protocol) + frame.ip_header_checksum = int(ip_header_checksum) + frame.ip_source_ip = int(ip_source_ip) + frame.ip_dest_ip = int(ip_dest_ip) + frame.udp_source_port = int(udp_source_port) + frame.udp_dest_port = int(udp_dest_port) + frame.udp_length = int(udp_length) + frame.udp_checksum = int(udp_checksum) + udp_header_fifo.put(frame) + + if not udp_payload_fifo.empty() and not udp_header_fifo.empty(): + frame = udp_header_fifo.get() + frame.payload = udp_payload_fifo.get() + fifo.put(frame) + + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + + frame = dict() + + return logic, pause_logic, udp_payload_sink + From 1acf493e9d5b701f617eb22021fc79151f913432 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Sep 2014 17:28:05 -0700 Subject: [PATCH 034/617] Add 64 bit UDP transmit and receive modules --- rtl/udp_ip_rx_64.v | 642 +++++++++++++++++++++ rtl/udp_ip_tx_64.v | 623 ++++++++++++++++++++ tb/test_udp_ip_rx_64.py | 1205 +++++++++++++++++++++++++++++++++++++++ tb/test_udp_ip_rx_64.v | 224 ++++++++ tb/test_udp_ip_tx_64.py | 1146 +++++++++++++++++++++++++++++++++++++ tb/test_udp_ip_tx_64.v | 218 +++++++ 6 files changed, 4058 insertions(+) create mode 100644 rtl/udp_ip_rx_64.v create mode 100644 rtl/udp_ip_tx_64.v create mode 100755 tb/test_udp_ip_rx_64.py create mode 100644 tb/test_udp_ip_rx_64.v create mode 100755 tb/test_udp_ip_tx_64.py create mode 100644 tb/test_udp_ip_tx_64.v diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v new file mode 100644 index 000000000..93d9333d9 --- /dev/null +++ b/rtl/udp_ip_rx_64.v @@ -0,0 +1,642 @@ +/* + +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 + +/* + * UDP ethernet frame receiver (IP frame in, UDP frame out, 64 bit datapath) + */ +module udp_ip_rx_64 +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [63:0] input_ip_payload_tdata, + input wire [7:0] input_ip_payload_tkeep, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [63:0] output_udp_payload_tdata, + output wire [7:0] output_udp_payload_tkeep, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Status signals + */ + output wire busy, + output wire error_header_early_termination, + output wire error_payload_early_termination +); + +/* + +UDP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + + source port 2 octets + desination port 2 octets + length 2 octets + checksum 2 octets + + payload length octets + +This module receives an IP frame with decoded fields and decodes +the AXI packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [3:0] + STATE_IDLE = 4'd0, + STATE_READ_HEADER = 4'd1, + STATE_READ_PAYLOAD_IDLE = 4'd2, + STATE_READ_PAYLOAD_TRANSFER = 4'd3, + STATE_READ_PAYLOAD_TRANSFER_WAIT = 4'd4, + STATE_READ_PAYLOAD_TRANSFER_LAST = 4'd5, + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST = 4'd6, + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT = 4'd7, + STATE_WAIT_LAST = 4'd8; + +reg [3:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_ip_hdr; +reg store_hdr_word_0; + +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg assert_tlast; +reg assert_tuser; +reg [7:0] tkeep_mask; + +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; + +reg input_ip_hdr_ready_reg = 0; +reg input_ip_payload_tready_reg = 0; + +reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [3:0] output_ip_version_reg = 0; +reg [3:0] output_ip_ihl_reg = 0; +reg [5:0] output_ip_dscp_reg = 0; +reg [1:0] output_ip_ecn_reg = 0; +reg [15:0] output_ip_length_reg = 0; +reg [15:0] output_ip_identification_reg = 0; +reg [2:0] output_ip_flags_reg = 0; +reg [12:0] output_ip_fragment_offset_reg = 0; +reg [7:0] output_ip_ttl_reg = 0; +reg [7:0] output_ip_protocol_reg = 0; +reg [15:0] output_ip_header_checksum_reg = 0; +reg [31:0] output_ip_source_ip_reg = 0; +reg [31:0] output_ip_dest_ip_reg = 0; +reg [15:0] output_udp_source_port_reg = 0; +reg [15:0] output_udp_dest_port_reg = 0; +reg [15:0] output_udp_length_reg = 0; +reg [15:0] output_udp_checksum_reg = 0; +reg [63:0] output_udp_payload_tdata_reg = 0; +reg [7:0] output_udp_payload_tkeep_reg = 0; +reg output_udp_payload_tvalid_reg = 0; +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg busy_reg = 0; +reg error_header_early_termination_reg = 0, error_header_early_termination_next; +reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; + +reg [63:0] temp_udp_payload_tdata_reg = 0; +reg [7:0] temp_udp_payload_tkeep_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; + +assign input_ip_hdr_ready = input_ip_hdr_ready_reg; +assign input_ip_payload_tready = input_ip_payload_tready_reg; + +assign output_udp_hdr_valid = output_udp_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_udp_source_port = output_udp_source_port_reg; +assign output_udp_dest_port = output_udp_dest_port_reg; +assign output_udp_length = output_udp_length_reg; +assign output_udp_checksum = output_udp_checksum_reg; +assign output_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; +assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; +assign output_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_udp_payload_tuser = output_udp_payload_tuser_reg; + +assign busy = busy_reg; +assign error_header_early_termination = error_header_early_termination_reg; +assign error_payload_early_termination = error_payload_early_termination_reg; + +function [3:0] keep2count; + input [7:0] k; + case (k) + 8'b00000000: keep2count = 0; + 8'b00000001: keep2count = 1; + 8'b00000011: keep2count = 2; + 8'b00000111: keep2count = 3; + 8'b00001111: keep2count = 4; + 8'b00011111: keep2count = 5; + 8'b00111111: keep2count = 6; + 8'b01111111: keep2count = 7; + 8'b11111111: keep2count = 8; + endcase +endfunction + +function [7:0] count2keep; + input [3:0] k; + case (k) + 4'd0: count2keep = 8'b00000000; + 4'd1: count2keep = 8'b00000001; + 4'd2: count2keep = 8'b00000011; + 4'd3: count2keep = 8'b00000111; + 4'd4: count2keep = 8'b00001111; + 4'd5: count2keep = 8'b00011111; + 4'd6: count2keep = 8'b00111111; + 4'd7: count2keep = 8'b01111111; + 4'd8: count2keep = 8'b11111111; + endcase +endfunction + +always @* begin + state_next = 2'bz; + + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + assert_tlast = 0; + assert_tuser = 0; + tkeep_mask = 8'hff; + + store_ip_hdr = 0; + store_hdr_word_0 = 0; + + frame_ptr_next = frame_ptr_reg; + + output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; + + error_header_early_termination_next = 0; + error_payload_early_termination_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for header + frame_ptr_next = 0; + + if (input_ip_hdr_ready & input_ip_hdr_valid) begin + frame_ptr_next = 0; + store_ip_hdr = 1; + state_next = STATE_READ_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_READ_HEADER: begin + // read header state + if (input_ip_payload_tvalid) begin + // word transfer in - store it + frame_ptr_next = frame_ptr_reg+8; + state_next = STATE_READ_HEADER; + + case (frame_ptr_reg) + 8'h00: begin + store_hdr_word_0 = 1; + output_udp_hdr_valid_next = 1; + state_next = STATE_READ_PAYLOAD_IDLE; + end + endcase + + if (input_ip_payload_tlast) begin + state_next = STATE_IDLE; + output_udp_hdr_valid_next = 0; + error_header_early_termination_next = 1; + end + + end else begin + state_next = STATE_READ_HEADER; + end + end + STATE_READ_PAYLOAD_IDLE: begin + // idle; no data in registers + if (input_ip_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+keep2count(input_ip_payload_tkeep); + if (frame_ptr_next >= output_udp_length_reg) begin + // have entire payload + frame_ptr_next = output_udp_length_reg; + tkeep_mask = count2keep(output_udp_length_reg - frame_ptr_reg); + if (input_ip_payload_tlast) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + if (input_ip_payload_tlast) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_READ_PAYLOAD_IDLE; + end + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register + if (input_ip_payload_tvalid & output_udp_payload_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+keep2count(input_ip_payload_tkeep); + if (frame_ptr_next >= output_udp_length_reg) begin + // have entire payload + frame_ptr_next = output_udp_length_reg; + tkeep_mask = count2keep(output_udp_length_reg - frame_ptr_reg); + if (input_ip_payload_tlast) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + if (input_ip_payload_tlast) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else if (~input_ip_payload_tvalid & output_udp_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_READ_PAYLOAD_IDLE; + end else if (input_ip_payload_tvalid & ~output_udp_payload_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + frame_ptr_next = frame_ptr_reg+keep2count(input_ip_payload_tkeep); + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + if (frame_ptr_next >= output_udp_length_reg) begin + // have entire payload + frame_ptr_next = output_udp_length_reg; + tkeep_mask = count2keep(output_udp_length_reg - frame_ptr_reg); + if (~input_ip_payload_tlast) begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + end + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in both output and temp registers + if (output_udp_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_udp_payload_tlast_reg) begin + if (frame_ptr_next <= output_udp_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next >= output_udp_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + if (output_udp_payload_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + if (input_ip_payload_tvalid) begin + if (input_ip_payload_tlast) begin + // assert tlast and transfer tuser + assert_tlast = 1; + assert_tuser = input_ip_payload_tuser; + state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin + // wait for end of frame; data in both output and temp registers; read and discard + if (output_udp_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + end + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + if (input_ip_payload_tvalid) begin + if (input_ip_payload_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end else begin + state_next = STATE_WAIT_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_udp_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_udp_source_port_reg <= 0; + output_udp_dest_port_reg <= 0; + output_udp_length_reg <= 0; + output_udp_checksum_reg <= 0; + output_udp_payload_tdata_reg <= 0; + output_udp_payload_tkeep_reg <= 0; + output_udp_payload_tvalid_reg <= 0; + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + busy_reg <= 0; + error_header_early_termination_reg <= 0; + error_payload_early_termination_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + + error_header_early_termination_reg <= error_header_early_termination_next; + error_payload_early_termination_reg <= error_payload_early_termination_next; + + busy_reg <= state_next != STATE_IDLE; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_ip_hdr_ready_reg <= ~output_udp_hdr_valid; + input_ip_payload_tready_reg <= 0; + output_udp_payload_tvalid_reg <= 0; + end + STATE_READ_HEADER: begin + // read header; accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_udp_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_IDLE: begin + // read payload; no data in registers; accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_udp_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_TRANSFER: begin + // read payload; data in output register; accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_udp_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT: begin + // read payload; data in output and temp registers; do not accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_udp_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_LAST: begin + // read last payload word; data in output register; do not accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_udp_payload_tvalid_reg <= 1; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_udp_payload_tvalid_reg <= 0; + end + STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin + // wait for end of frame; data in output and temp registers; do not accept new data + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_udp_payload_tvalid_reg <= 1; + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 1; + output_udp_payload_tvalid_reg <= 0; + end + endcase + + // datapath + if (store_ip_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + output_ip_version_reg <= input_ip_version; + output_ip_ihl_reg <= input_ip_ihl; + output_ip_dscp_reg <= input_ip_dscp; + output_ip_ecn_reg <= input_ip_ecn; + output_ip_length_reg <= input_ip_length; + output_ip_identification_reg <= input_ip_identification; + output_ip_flags_reg <= input_ip_flags; + output_ip_fragment_offset_reg <= input_ip_fragment_offset; + output_ip_ttl_reg <= input_ip_ttl; + output_ip_protocol_reg <= input_ip_protocol; + output_ip_header_checksum_reg <= input_ip_header_checksum; + output_ip_source_ip_reg <= input_ip_source_ip; + output_ip_dest_ip_reg <= input_ip_dest_ip; + end + + if (store_hdr_word_0) begin + output_udp_source_port_reg[15: 8] <= input_ip_payload_tdata[ 7: 0]; + output_udp_source_port_reg[ 7: 0] <= input_ip_payload_tdata[15: 8]; + output_udp_dest_port_reg[15: 8] <= input_ip_payload_tdata[23:16]; + output_udp_dest_port_reg[ 7: 0] <= input_ip_payload_tdata[31:24]; + output_udp_length_reg[15: 8] <= input_ip_payload_tdata[39:32]; + output_udp_length_reg[ 7: 0] <= input_ip_payload_tdata[47:40]; + output_udp_checksum_reg[15: 8] <= input_ip_payload_tdata[55:48]; + output_udp_checksum_reg[ 7: 0] <= input_ip_payload_tdata[63:56]; + end + + if (transfer_in_out) begin + output_udp_payload_tdata_reg <= input_ip_payload_tdata; + output_udp_payload_tkeep_reg <= input_ip_payload_tkeep & tkeep_mask; + output_udp_payload_tlast_reg <= input_ip_payload_tlast; + output_udp_payload_tuser_reg <= input_ip_payload_tuser; + end else if (transfer_in_temp) begin + temp_udp_payload_tdata_reg <= input_ip_payload_tdata; + temp_udp_payload_tkeep_reg <= input_ip_payload_tkeep & tkeep_mask; + temp_udp_payload_tlast_reg <= input_ip_payload_tlast; + temp_udp_payload_tuser_reg <= input_ip_payload_tuser; + end else if (transfer_temp_out) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (assert_tlast) output_udp_payload_tlast_reg <= 1; + if (assert_tuser) output_udp_payload_tuser_reg <= 1; + end +end + +endmodule diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v new file mode 100644 index 000000000..89e378617 --- /dev/null +++ b/rtl/udp_ip_tx_64.v @@ -0,0 +1,623 @@ +/* + +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 + +/* + * UDP ethernet frame transmitter (UDP frame in, IP frame out, 64-bit datapath) + */ +module udp_ip_tx_64 +( + input wire clk, + input wire rst, + + /* + * UDP frame input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [63:0] input_udp_payload_tdata, + input wire [7:0] input_udp_payload_tkeep, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Status signals + */ + output wire busy, + output wire error_payload_early_termination +); + +/* + +UDP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + + source port 2 octets + desination port 2 octets + length 2 octets + checksum 2 octets + + payload length octets + +This module receives an IP frame with decoded fields and decodes +the AXI packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_WRITE_PAYLOAD_IDLE = 3'd1, + STATE_WRITE_PAYLOAD_TRANSFER = 3'd2, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 3'd3, + STATE_WRITE_PAYLOAD_TRANSFER_LAST = 3'd4, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST = 3'd5, + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT = 3'd6, + STATE_WAIT_LAST = 3'd7; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_udp_hdr; + +reg [63:0] write_hdr_data; +reg [7:0] write_hdr_keep; +reg write_hdr_last; +reg write_hdr_user; +reg write_hdr_out; + +reg transfer_in_out; +reg transfer_in_temp; +reg transfer_temp_out; + +reg assert_tlast; +reg assert_tuser; +reg [7:0] tkeep_mask; + +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [15:0] hdr_sum_reg = 0, hdr_sum_next; + +reg [15:0] udp_source_port_reg = 0; +reg [15:0] udp_dest_port_reg = 0; +reg [15:0] udp_length_reg = 0; +reg [15:0] udp_checksum_reg = 0; + +reg input_udp_hdr_ready_reg = 0; +reg input_udp_payload_tready_reg = 0; + +reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; +reg [3:0] output_ip_version_reg = 0; +reg [3:0] output_ip_ihl_reg = 0; +reg [5:0] output_ip_dscp_reg = 0; +reg [1:0] output_ip_ecn_reg = 0; +reg [15:0] output_ip_length_reg = 0; +reg [15:0] output_ip_identification_reg = 0; +reg [2:0] output_ip_flags_reg = 0; +reg [12:0] output_ip_fragment_offset_reg = 0; +reg [7:0] output_ip_ttl_reg = 0; +reg [7:0] output_ip_protocol_reg = 0; +reg [15:0] output_ip_header_checksum_reg = 0; +reg [31:0] output_ip_source_ip_reg = 0; +reg [31:0] output_ip_dest_ip_reg = 0; +reg [63:0] output_ip_payload_tdata_reg = 0; +reg [7:0] output_ip_payload_tkeep_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg busy_reg = 0; +reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; + +reg [63:0] temp_ip_payload_tdata_reg = 0; +reg [7:0] temp_ip_payload_tkeep_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign input_udp_hdr_ready = input_udp_hdr_ready_reg; +assign input_udp_payload_tready = input_udp_payload_tready_reg; + +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +assign busy = busy_reg; +assign error_payload_early_termination = error_payload_early_termination_reg; + +function [3:0] keep2count; + input [7:0] k; + case (k) + 8'b00000000: keep2count = 0; + 8'b00000001: keep2count = 1; + 8'b00000011: keep2count = 2; + 8'b00000111: keep2count = 3; + 8'b00001111: keep2count = 4; + 8'b00011111: keep2count = 5; + 8'b00111111: keep2count = 6; + 8'b01111111: keep2count = 7; + 8'b11111111: keep2count = 8; + endcase +endfunction + +function [7:0] count2keep; + input [3:0] k; + case (k) + 4'd0: count2keep = 8'b00000000; + 4'd1: count2keep = 8'b00000001; + 4'd2: count2keep = 8'b00000011; + 4'd3: count2keep = 8'b00000111; + 4'd4: count2keep = 8'b00001111; + 4'd5: count2keep = 8'b00011111; + 4'd6: count2keep = 8'b00111111; + 4'd7: count2keep = 8'b01111111; + 4'd8: count2keep = 8'b11111111; + endcase +endfunction + +always @* begin + state_next = 2'bz; + + store_udp_hdr = 0; + + write_hdr_data = 0; + write_hdr_keep = 0; + write_hdr_last = 0; + write_hdr_user = 0; + write_hdr_out = 0; + + transfer_in_out = 0; + transfer_in_temp = 0; + transfer_temp_out = 0; + + assert_tlast = 0; + assert_tuser = 0; + tkeep_mask = 8'hff; + + frame_ptr_next = frame_ptr_reg; + + hdr_sum_next = hdr_sum_reg; + + output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + + error_payload_early_termination_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + + if (input_udp_hdr_valid & input_udp_hdr_ready) begin + store_udp_hdr = 1; + write_hdr_out = 1; + write_hdr_data[ 7: 0] = input_udp_source_port[15: 8]; + write_hdr_data[15: 8] = input_udp_source_port[ 7: 0]; + write_hdr_data[23:16] = input_udp_dest_port[15: 8]; + write_hdr_data[31:24] = input_udp_dest_port[ 7: 0]; + write_hdr_data[39:32] = input_udp_length[15: 8]; + write_hdr_data[47:40] = input_udp_length[ 7: 0]; + write_hdr_data[55:48] = input_udp_checksum[15: 8]; + write_hdr_data[63:56] = input_udp_checksum[ 7: 0]; + write_hdr_keep = 8'hff; + output_ip_hdr_valid_next = 1; + frame_ptr_next = 8; + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_PAYLOAD_IDLE: begin + // idle; no data in registers + if (input_udp_payload_tvalid) begin + // word transfer in - store it in output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+keep2count(input_udp_payload_tkeep); + if (frame_ptr_next >= udp_length_reg) begin + // have entire payload + frame_ptr_next = udp_length_reg; + tkeep_mask = count2keep(udp_length_reg - frame_ptr_reg); + if (input_udp_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + if (input_udp_payload_tlast) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_WRITE_PAYLOAD_IDLE; + end + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // write payload; data in output register + if (input_udp_payload_tvalid & output_ip_payload_tready) begin + // word transfer through - update output register + transfer_in_out = 1; + frame_ptr_next = frame_ptr_reg+keep2count(input_udp_payload_tkeep); + if (frame_ptr_next >= udp_length_reg) begin + // have entire payload + frame_ptr_next = udp_length_reg; + tkeep_mask = count2keep(udp_length_reg - frame_ptr_reg); + if (input_udp_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + if (input_udp_payload_tlast) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else if (~input_udp_payload_tvalid & output_ip_payload_tready) begin + // word transfer out - go back to idle + state_next = STATE_WRITE_PAYLOAD_IDLE; + end else if (input_udp_payload_tvalid & ~output_ip_payload_tready) begin + // word transfer in - store in temp + transfer_in_temp = 1; + frame_ptr_next = frame_ptr_reg+keep2count(input_udp_payload_tkeep); + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + if (frame_ptr_next >= udp_length_reg) begin + // have entire payload + frame_ptr_next = udp_length_reg; + tkeep_mask = count2keep(udp_length_reg - frame_ptr_reg); + if (~input_udp_payload_tlast) begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + end + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // write payload; data in both output and temp registers + if (output_ip_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + if (temp_ip_payload_tlast_reg) begin + if (frame_ptr_next < udp_length_reg) begin + // end of frame, but length does not match + assert_tuser = 1; + assert_tlast = 1; + error_payload_early_termination_next = 1; + end + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + if (frame_ptr_next >= udp_length_reg) begin + // not end of frame, but we have the entire payload + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER; + end + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // write last payload word; data in output register; do not accept new data + if (output_ip_payload_tready) begin + // word transfer out - done + state_next = STATE_IDLE; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + if (input_udp_payload_tvalid) begin + if (input_udp_payload_tlast) begin + // assert tlast and transfer tuser + assert_tlast = 1; + assert_tuser = input_udp_payload_tuser; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin + // wait for end of frame; data in both output and temp registers; read and discard + if (output_ip_payload_tready) begin + // transfer out - move temp to output + transfer_temp_out = 1; + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + end else begin + state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + end + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + if (input_udp_payload_tvalid) begin + if (input_udp_payload_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end else begin + state_next = STATE_WAIT_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + hdr_sum_reg <= 0; + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; + udp_source_port_reg <= 0; + udp_dest_port_reg <= 0; + udp_length_reg <= 0; + udp_checksum_reg <= 0; + output_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + busy_reg <= 0; + error_payload_early_termination_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + hdr_sum_reg <= hdr_sum_next; + + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + + busy_reg <= state_next != STATE_IDLE; + + error_payload_early_termination_reg <= error_payload_early_termination_next; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; accept new data + input_udp_hdr_ready_reg <= 1; + input_udp_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_IDLE: begin + // write payload; no data in registers; accept new data + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_TRANSFER: begin + // write payload; data in output register; accept new data + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin + // write payload; data in output and temp registers; do not accept new data + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin + // write last payload word; data in output register; do not accept new data + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin + // wait for end of frame; data in output register; read and discard + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 0; + end + STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin + // wait for end of frame; data in output and temp registers; do not accept new data + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; + output_ip_payload_tvalid_reg <= 1; + end + STATE_WAIT_LAST: begin + // wait for end of frame; read and discard + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 1; + output_ip_payload_tvalid_reg <= 0; + end + endcase + + if (store_udp_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + output_ip_version_reg <= input_ip_version; + output_ip_ihl_reg <= input_ip_ihl; + output_ip_dscp_reg <= input_ip_dscp; + output_ip_ecn_reg <= input_ip_ecn; + output_ip_length_reg <= input_udp_length + 20; + output_ip_identification_reg <= input_ip_identification; + output_ip_flags_reg <= input_ip_flags; + output_ip_fragment_offset_reg <= input_ip_fragment_offset; + output_ip_ttl_reg <= input_ip_ttl; + output_ip_protocol_reg <= input_ip_protocol; + output_ip_header_checksum_reg <= input_ip_header_checksum; + output_ip_source_ip_reg <= input_ip_source_ip; + output_ip_dest_ip_reg <= input_ip_dest_ip; + udp_source_port_reg <= input_udp_source_port; + udp_dest_port_reg <= input_udp_dest_port; + udp_length_reg <= input_udp_length; + udp_checksum_reg <= input_udp_checksum; + end + + if (write_hdr_out) begin + output_ip_payload_tdata_reg <= write_hdr_data; + output_ip_payload_tkeep_reg <= write_hdr_keep & tkeep_mask; + output_ip_payload_tlast_reg <= write_hdr_last; + output_ip_payload_tuser_reg <= write_hdr_user; + end else if (transfer_in_out) begin + output_ip_payload_tdata_reg <= input_udp_payload_tdata; + output_ip_payload_tkeep_reg <= input_udp_payload_tkeep & tkeep_mask; + output_ip_payload_tlast_reg <= input_udp_payload_tlast; + output_ip_payload_tuser_reg <= input_udp_payload_tuser; + end else if (transfer_in_temp) begin + temp_ip_payload_tdata_reg <= input_udp_payload_tdata; + temp_ip_payload_tkeep_reg <= input_udp_payload_tkeep & tkeep_mask; + temp_ip_payload_tlast_reg <= input_udp_payload_tlast; + temp_ip_payload_tuser_reg <= input_udp_payload_tuser; + end else if (transfer_temp_out) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (assert_tlast) output_ip_payload_tlast_reg <= 1; + if (assert_tuser) output_ip_payload_tuser_reg <= 1; + end +end + +endmodule diff --git a/tb/test_udp_ip_rx_64.py b/tb/test_udp_ip_rx_64.py new file mode 100755 index 000000000..ab24c73c6 --- /dev/null +++ b/tb/test_udp_ip_rx_64.py @@ -0,0 +1,1205 @@ +#!/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 eth_ep +import ip_ep +import udp_ep + +module = 'udp_ip_rx_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_udp_ip_rx_64(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + busy, + error_header_early_termination, + error_payload_early_termination): + + 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_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tkeep=input_ip_payload_tkeep, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tkeep=output_udp_payload_tkeep, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + busy=busy, + error_header_early_termination=error_header_early_termination, + error_payload_early_termination=error_payload_early_termination) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_ip_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[64:]) + input_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + output_udp_payload_tready = Signal(bool(0)) + + # Outputs + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + output_udp_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[64:]) + output_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + error_header_early_termination = Signal(bool(0)) + error_payload_early_termination = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tkeep=input_ip_payload_tkeep, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tkeep=output_udp_payload_tkeep, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_udp_ip_rx_64(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + busy, + error_header_early_termination, + error_payload_early_termination) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_header_early_termination_asserted = Signal(bool(0)) + error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_header_early_termination): + error_header_early_termination_asserted.next = 1 + if (error_payload_early_termination): + error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + + def wait_pause_source(): + while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(payload_len)) + test_frame.build() + ip_frame = test_frame.build_ip() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: trailing bytes (1), length %d" % payload_len) + current_test.next = 4 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data += bytearray(b'\x00') + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: trailing bytes (10), length %d" % payload_len) + current_test.next = 5 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data += bytearray(b'\x00'*10) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 6: trailing bytes with tuser assert (1), length %d" % payload_len) + current_test.next = 6 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data += bytearray(b'\x00') + ip_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 7: trailing bytes with tuser assert (10), length %d" % payload_len) + current_test.next = 7 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data += bytearray(b'\x00'*10) + ip_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 8: truncated payload (1), length %d" % payload_len) + current_test.next = 8 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len+1)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data = ip_frame1.payload.data[:-1] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 9: truncated payload (10), length %d" % payload_len) + current_test.next = 9 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len+10)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data = ip_frame1.payload.data[:-10] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + for length in range(1,9): + yield clk.posedge + print("test 10: truncated header, length %d" % length) + current_test.next = 10 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(16)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(16)) + test_frame2.build() + + ip_frame1 = test_frame1.build_ip() + ip_frame2 = test_frame2.build_ip() + + ip_frame1.payload.data = ip_frame1.payload.data[:length] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_header_early_termination_asserted.next = 0 + + source_queue.put(ip_frame1) + source_queue.put(ip_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_header_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_ip_rx_64.v b/tb/test_udp_ip_rx_64.v new file mode 100644 index 000000000..b311d7ccf --- /dev/null +++ b/tb/test_udp_ip_rx_64.v @@ -0,0 +1,224 @@ +/* + +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_udp_ip_rx_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_ip_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [63:0] input_ip_payload_tdata = 0; +reg [7:0] input_ip_payload_tkeep = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; + +// Outputs +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire output_udp_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [63:0] output_udp_payload_tdata; +wire [7:0] output_udp_payload_tkeep; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; +wire busy; +wire error_header_early_termination; +wire error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_ip_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + output_udp_hdr_ready, + output_udp_payload_tready); + $to_myhdl(input_ip_hdr_ready, + input_ip_payload_tready, + output_udp_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser, + busy, + error_header_early_termination, + error_payload_early_termination); + + // dump file + $dumpfile("test_udp_ip_rx_64.lxt"); + $dumpvars(0, test_udp_ip_rx_64); +end + +udp_ip_rx_64 +UUT ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status signals + .busy(busy), + .error_header_early_termination(error_header_early_termination), + .error_payload_early_termination(error_payload_early_termination) +); + +endmodule diff --git a/tb/test_udp_ip_tx_64.py b/tb/test_udp_ip_tx_64.py new file mode 100755 index 000000000..043fe8926 --- /dev/null +++ b/tb/test_udp_ip_tx_64.py @@ -0,0 +1,1146 @@ +#!/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 eth_ep +import ip_ep +import udp_ep + +module = 'udp_ip_tx_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_udp_ip_tx_64(clk, + rst, + current_test, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + busy, + error_payload_early_termination): + + 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_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_length=input_udp_length, + input_udp_checksum=input_udp_checksum, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tkeep=input_udp_payload_tkeep, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tkeep=output_ip_payload_tkeep, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + busy=busy, + error_payload_early_termination=error_payload_early_termination) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_udp_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_length = Signal(intbv(0)[16:]) + input_udp_checksum = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[64:]) + input_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + + # Outputs + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[64:]) + output_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + error_payload_early_termination = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_valid=input_udp_hdr_valid, + udp_hdr_ready=input_udp_hdr_ready, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_length=input_udp_length, + udp_checksum=input_udp_checksum, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tkeep=input_udp_payload_tkeep, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tkeep=output_ip_payload_tkeep, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_udp_ip_tx_64(clk, + rst, + current_test, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + busy, + error_payload_early_termination) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_payload_early_termination): + error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + yield clk.posedge + + def wait_pause_source(): + while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(payload_len)) + test_frame.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: trailing bytes (1), length %d" % payload_len) + current_test.next = 4 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00') + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: trailing bytes (10), length %d" % payload_len) + current_test.next = 5 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00'*10) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 6: trailing bytes with tuser assert (1), length %d" % payload_len) + current_test.next = 6 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00') + test_frame1a.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 7: trailing bytes with tuser assert (10), length %d" % payload_len) + current_test.next = 7 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data += bytearray(b'\x00'*10) + test_frame1a.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 8: truncated payload (1), length %d" % payload_len) + current_test.next = 8 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len+1)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data = test_frame1a.payload.data[:-1] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 9: truncated payload (10), length %d" % payload_len) + current_test.next = 9 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len+10)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1a = udp_ep.UDPFrame(test_frame1) + test_frame1a.payload.data = test_frame1.payload.data[:-10] + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_payload_early_termination_asserted.next = 0 + + source_queue.put(test_frame1a) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert rx_frame.payload.user[-1] + assert error_payload_early_termination_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_ip_tx_64.v b/tb/test_udp_ip_tx_64.v new file mode 100644 index 000000000..cfc60bf5f --- /dev/null +++ b/tb/test_udp_ip_tx_64.v @@ -0,0 +1,218 @@ +/* + +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_udp_ip_tx_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_udp_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [15:0] input_udp_length = 0; +reg [15:0] input_udp_checksum = 0; +reg [63:0] input_udp_payload_tdata = 0; +reg [7:0] input_udp_payload_tkeep = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; + +// Outputs +wire input_udp_hdr_ready; +wire input_udp_payload_tready; +wire output_ip_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [63:0] output_ip_payload_tdata; +wire [7:0] output_ip_payload_tkeep; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire busy; +wire error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_udp_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_ip_hdr_ready, + output_ip_payload_tready); + $to_myhdl(input_udp_hdr_ready, + input_udp_payload_tready, + output_ip_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + busy, + error_payload_early_termination); + + // dump file + $dumpfile("test_udp_ip_tx_64.lxt"); + $dumpvars(0, test_udp_ip_tx_64); +end + +udp_ip_tx_64 +UUT ( + .clk(clk), + .rst(rst), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tkeep(input_udp_payload_tkeep), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .busy(busy), + .error_payload_early_termination(error_payload_early_termination) +); + +endmodule From e14a79dee46fc8efe3b60a078b3df01a3182de07 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 29 Sep 2014 22:26:55 -0700 Subject: [PATCH 035/617] Add IP module and testbench --- rtl/ip.v | 385 ++++++++++++++++++++++++++++ tb/test_ip.py | 695 ++++++++++++++++++++++++++++++++++++++++++++++++++ tb/test_ip.v | 279 ++++++++++++++++++++ 3 files changed, 1359 insertions(+) create mode 100644 rtl/ip.v create mode 100755 tb/test_ip.py create mode 100644 tb/test_ip.v diff --git a/rtl/ip.v b/rtl/ip.v new file mode 100644 index 000000000..f785b5c74 --- /dev/null +++ b/rtl/ip.v @@ -0,0 +1,385 @@ +/* + +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 + +/* + * IPv4 block, ethernet frame interface + */ +module ip +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [7:0] input_eth_payload_tdata, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * ARP requests + */ + output wire arp_request_valid, + output wire [31:0] arp_request_ip, + input wire arp_response_valid, + input wire arp_response_error, + input wire [47:0] arp_response_mac, + + /* + * IP input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [7:0] input_ip_payload_tdata, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_ip_eth_dest_mac, + output wire [47:0] output_ip_eth_src_mac, + output wire [15:0] output_ip_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Status + */ + output wire rx_busy, + output wire tx_busy, + output wire rx_error_header_early_termination, + output wire rx_error_payload_early_termination, + output wire rx_error_invalid_header, + output wire rx_error_invalid_checksum, + output wire tx_error_payload_early_termination, + output wire tx_error_arp_failed, + + /* + * Configuration + */ + input wire [47:0] local_mac, + input wire [31:0] local_ip +); + +/* + +IP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + payload length octets + +This module receives an Ethernet frame with decoded fields and decodes +the AXI packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_ARP_QUERY = 2'd1, + STATE_SEND_PACKET = 2'd2, + STATE_DROP_PACKET = 2'd3; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg outgoing_ip_hdr_valid_reg = 1'b0, outgoing_ip_hdr_valid_next; +wire outgoing_ip_hdr_ready; +reg [47:0] outgoing_eth_dest_mac_reg = 48'h000000000000, outgoing_eth_dest_mac_next; +wire outgoing_ip_payload_tready; + +/* + * IP frame processing + */ +ip_eth_rx +ip_eth_rx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_ip_eth_dest_mac), + .output_eth_src_mac(output_ip_eth_src_mac), + .output_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .busy(rx_busy), + .error_header_early_termination(rx_error_header_early_termination), + .error_payload_early_termination(rx_error_payload_early_termination), + .error_invalid_header(rx_error_invalid_header), + .error_invalid_checksum(rx_error_invalid_checksum) +); + +ip_eth_tx +ip_eth_tx_inst ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(outgoing_ip_hdr_valid_reg), + .input_ip_hdr_ready(outgoing_ip_hdr_ready), + .input_eth_dest_mac(outgoing_eth_dest_mac_reg), + .input_eth_src_mac(local_mac), + .input_eth_type(16'h0800), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(16'd0), + .input_ip_flags(3'b010), + .input_ip_fragment_offset(13'd0), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(outgoing_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Status signals + .busy(tx_busy), + .error_payload_early_termination(tx_error_payload_early_termination) +); + +reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; + +reg arp_request_valid_reg = 0; + +reg drop_packet_reg = 0; + +assign input_ip_hdr_ready = input_ip_hdr_ready_reg; +assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; + +assign arp_request_valid = arp_request_valid_reg | input_ip_hdr_valid; +assign arp_request_ip = input_ip_dest_ip; + +assign tx_error_arp_failed = arp_response_error; + +always @* begin + state_next = 8'bz; + + input_ip_hdr_ready_next = 0; + + outgoing_ip_hdr_valid_next = outgoing_ip_hdr_valid_reg & ~outgoing_ip_hdr_ready; + outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; + + case (state_reg) + STATE_IDLE: begin + // wait for outgoing packet + if (input_ip_hdr_valid) begin + // initiate ARP request + state_next = STATE_ARP_QUERY; + end else begin + state_next = STATE_IDLE; + end + end + STATE_ARP_QUERY: begin + if (arp_response_valid) begin + // wait for ARP reponse + if (arp_response_error) begin + // did not get MAC address; drop packet + input_ip_hdr_ready_next = 1; + state_next = STATE_DROP_PACKET; + end else begin + // got MAC address; send packet + input_ip_hdr_ready_next = 1; + outgoing_ip_hdr_valid_next = 1; + outgoing_eth_dest_mac_next = arp_response_mac; + state_next = STATE_SEND_PACKET; + end + end else begin + state_next = STATE_ARP_QUERY; + end + end + STATE_SEND_PACKET: begin + // wait for packet transfer to complete + if (input_ip_payload_tlast & input_ip_payload_tvalid) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_SEND_PACKET; + end + end + STATE_DROP_PACKET: begin + // wait for packet transfer to complete + if (input_ip_payload_tlast & input_ip_payload_tvalid) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_DROP_PACKET; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + arp_request_valid_reg <= 0; + input_ip_hdr_ready_reg <= 0; + outgoing_ip_hdr_valid_reg <= 1'b0; + outgoing_eth_dest_mac_reg <= 48'h000000000000; + drop_packet_reg <= 0; + + end else begin + state_reg <= state_next; + + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + + outgoing_ip_hdr_valid_reg <= outgoing_ip_hdr_valid_next; + outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; wait for IP packet + arp_request_valid_reg <= 0; + drop_packet_reg <= 0; + end + STATE_ARP_QUERY: begin + // wait for ARP reponse + arp_request_valid_reg <= 1; + drop_packet_reg <= 0; + end + STATE_SEND_PACKET: begin + // wait for packet transfer to complete + arp_request_valid_reg <= 0; + drop_packet_reg <= 0; + end + STATE_DROP_PACKET: begin + // wait for packet transfer to complete + arp_request_valid_reg <= 0; + drop_packet_reg <= 1; + end + endcase + + end +end + +endmodule diff --git a/tb/test_ip.py b/tb/test_ip.py new file mode 100755 index 000000000..40f30d9e2 --- /dev/null +++ b/tb/test_ip.py @@ -0,0 +1,695 @@ +#!/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 eth_ep +import ip_ep + +module = 'ip' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) +srcs.append("../rtl/ip_eth_rx.v") +srcs.append("../rtl/ip_eth_tx.v") + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_ip(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + arp_request_valid, + arp_request_ip, + arp_response_valid, + arp_response_error, + arp_response_mac, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed, + + local_mac, + local_ip): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + arp_request_valid=arp_request_valid, + arp_request_ip=arp_request_ip, + arp_response_valid=arp_response_valid, + arp_response_error=arp_response_error, + arp_response_mac=arp_response_mac, + + input_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_ip_eth_dest_mac=output_ip_eth_dest_mac, + output_ip_eth_src_mac=output_ip_eth_src_mac, + output_ip_eth_type=output_ip_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + rx_busy=rx_busy, + tx_busy=tx_busy, + rx_error_header_early_termination=rx_error_header_early_termination, + rx_error_payload_early_termination=rx_error_payload_early_termination, + rx_error_invalid_header=rx_error_invalid_header, + rx_error_invalid_checksum=rx_error_invalid_checksum, + tx_error_payload_early_termination=tx_error_payload_early_termination, + tx_error_arp_failed=tx_error_arp_failed, + + local_mac=local_mac, + local_ip=local_ip) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + arp_response_valid = Signal(bool(0)) + arp_response_error = Signal(bool(0)) + arp_response_mac = Signal(intbv(0)[48:]) + input_ip_hdr_valid = Signal(bool(0)) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + arp_request_valid = Signal(bool(0)) + arp_request_ip = Signal(intbv(0)[32:]) + output_ip_hdr_valid = Signal(bool(0)) + output_ip_eth_dest_mac = Signal(intbv(0)[48:]) + output_ip_eth_src_mac = Signal(intbv(0)[48:]) + output_ip_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + rx_busy = Signal(bool(0)) + tx_busy = Signal(bool(0)) + rx_error_header_early_termination = Signal(bool(0)) + rx_error_payload_early_termination = Signal(bool(0)) + rx_error_invalid_header = Signal(bool(0)) + rx_error_invalid_checksum = Signal(bool(0)) + tx_error_payload_early_termination = Signal(bool(0)) + tx_error_arp_failed = Signal(bool(0)) + local_mac = Signal(intbv(0)[48:]) + local_ip = Signal(intbv(0)[32:]) + + # sources and sinks + eth_source_queue = Queue() + eth_source_pause = Signal(bool(0)) + eth_sink_queue = Queue() + eth_sink_pause = Signal(bool(0)) + ip_source_queue = Queue() + ip_source_pause = Signal(bool(0)) + ip_sink_queue = Queue() + ip_sink_pause = Signal(bool(0)) + + eth_source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=eth_source_queue, + pause=eth_source_pause, + name='eth_source') + + eth_sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=eth_sink_queue, + pause=eth_sink_pause, + name='eth_sink') + + ip_source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=ip_source_queue, + pause=ip_source_pause, + name='ip_source') + + ip_sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_ip_eth_dest_mac, + eth_src_mac=output_ip_eth_src_mac, + eth_type=output_ip_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=ip_sink_queue, + pause=ip_sink_pause, + name='ip_sink') + + # DUT + dut = dut_ip(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + arp_request_valid, + arp_request_ip, + arp_response_valid, + arp_response_error, + arp_response_mac, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed, + + local_mac, + local_ip) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + arp_table = {} + + @instance + def arp_emu(): + while True: + yield clk.posedge + + arp_response_valid.next = 0 + arp_response_error.next = 0 + arp_response_mac.next = 0 + + if arp_request_valid: + if int(arp_request_ip) in arp_table: + arp_response_valid.next = 1 + arp_response_mac.next = arp_table[int(arp_request_ip)] + else: + arp_response_valid.next = 1 + arp_response_error.next = 1 + + rx_error_header_early_termination_asserted = Signal(bool(0)) + rx_error_payload_early_termination_asserted = Signal(bool(0)) + rx_error_invalid_header_asserted = Signal(bool(0)) + rx_error_invalid_checksum_asserted = Signal(bool(0)) + tx_error_payload_early_termination_asserted = Signal(bool(0)) + tx_error_arp_failed_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_header_early_termination): + rx_error_header_early_termination_asserted.next = 1 + if (rx_error_payload_early_termination): + rx_error_payload_early_termination_asserted.next = 1 + if (rx_error_invalid_header): + rx_error_invalid_header_asserted.next = 1 + if (rx_error_invalid_checksum): + rx_error_invalid_checksum_asserted.next = 1 + if (tx_error_payload_early_termination): + tx_error_payload_early_termination_asserted.next = 1 + if (tx_error_arp_failed): + tx_error_arp_failed_asserted.next = 1 + + def wait_normal(): + while (input_eth_payload_tvalid or input_ip_payload_tvalid or + output_eth_payload_tvalid or output_ip_payload_tvalid or + input_eth_hdr_valid or input_ip_hdr_valid): + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # set MAC and IP address + local_mac.next = 0x5A5152535455 + local_ip.next = 0xc0a80164 + + # put an entry in the ARP table + arp_table[0xc0a80165] = 0xDAD1D2D3D4D5 + + yield clk.posedge + print("test 1: test IP RX packet") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not ip_sink_queue.empty(): + rx_frame = ip_sink_queue.get() + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test IP TX packet") + current_test.next = 2 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: test IP TX arp fail packet") + current_test.next = 2 + + tx_error_arp_failed_asserted.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + assert tx_error_arp_failed_asserted + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, eth_source, eth_sink, ip_source, ip_sink, clkgen, arp_emu, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip.v b/tb/test_ip.v new file mode 100644 index 000000000..cf63c637d --- /dev/null +++ b/tb/test_ip.v @@ -0,0 +1,279 @@ +/* + +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_ip; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [7:0] input_eth_payload_tdata = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg arp_response_valid = 0; +reg arp_response_error = 0; +reg [47:0] arp_response_mac = 0; +reg input_ip_hdr_valid = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [7:0] input_ip_payload_tdata = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; +reg [47:0] local_mac = 0; +reg [31:0] local_ip = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [7:0] output_eth_payload_tdata; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire arp_request_valid; +wire [31:0] arp_request_ip; +wire output_ip_hdr_valid; +wire [47:0] output_ip_eth_dest_mac; +wire [47:0] output_ip_eth_src_mac; +wire [15:0] output_ip_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [7:0] output_ip_payload_tdata; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire rx_busy; +wire tx_busy; +wire rx_error_header_early_termination; +wire rx_error_payload_early_termination; +wire rx_error_invalid_header; +wire rx_error_invalid_checksum; +wire tx_error_payload_early_termination; +wire tx_error_arp_failed; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + arp_response_valid, + arp_response_error, + arp_response_mac, + input_ip_hdr_valid, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + output_ip_hdr_ready, + output_ip_payload_tready, + local_mac, + local_ip); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + input_ip_hdr_ready, + input_ip_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + arp_request_valid, + arp_request_ip, + output_ip_hdr_valid, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed); + + // dump file + $dumpfile("test_ip.lxt"); + $dumpvars(0, test_ip); +end + +ip +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // ARP requests + .arp_request_valid(arp_request_valid), + .arp_request_ip(arp_request_ip), + .arp_response_valid(arp_response_valid), + .arp_response_error(arp_response_error), + .arp_response_mac(arp_response_mac), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .rx_busy(rx_busy), + .tx_busy(tx_busy), + .rx_error_header_early_termination(rx_error_header_early_termination), + .rx_error_payload_early_termination(rx_error_payload_early_termination), + .rx_error_invalid_header(rx_error_invalid_header), + .rx_error_invalid_checksum(rx_error_invalid_checksum), + .tx_error_payload_early_termination(tx_error_payload_early_termination), + .tx_error_arp_failed(tx_error_arp_failed), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip) +); + +endmodule From fc304ed1ba30fbdc6c2216140d7b79b188b6e07c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 30 Sep 2014 17:41:38 -0700 Subject: [PATCH 036/617] Add 64 bit IP module and testbench --- rtl/ip_64.v | 393 ++++++++++++++++++++++++++ tb/test_ip_64.py | 715 +++++++++++++++++++++++++++++++++++++++++++++++ tb/test_ip_64.v | 291 +++++++++++++++++++ 3 files changed, 1399 insertions(+) create mode 100644 rtl/ip_64.v create mode 100755 tb/test_ip_64.py create mode 100644 tb/test_ip_64.v diff --git a/rtl/ip_64.v b/rtl/ip_64.v new file mode 100644 index 000000000..b1d1ee99b --- /dev/null +++ b/rtl/ip_64.v @@ -0,0 +1,393 @@ +/* + +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 + +/* + * IPv4 block, ethernet frame interface (64 bit datapath) + */ +module ip_64 +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [63:0] input_eth_payload_tdata, + input wire [7:0] input_eth_payload_tkeep, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * ARP requests + */ + output wire arp_request_valid, + output wire [31:0] arp_request_ip, + input wire arp_response_valid, + input wire arp_response_error, + input wire [47:0] arp_response_mac, + + /* + * IP input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [63:0] input_ip_payload_tdata, + input wire [7:0] input_ip_payload_tkeep, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_ip_eth_dest_mac, + output wire [47:0] output_ip_eth_src_mac, + output wire [15:0] output_ip_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Status + */ + output wire rx_busy, + output wire tx_busy, + output wire rx_error_header_early_termination, + output wire rx_error_payload_early_termination, + output wire rx_error_invalid_header, + output wire rx_error_invalid_checksum, + output wire tx_error_payload_early_termination, + output wire tx_error_arp_failed, + + /* + * Configuration + */ + input wire [47:0] local_mac, + input wire [31:0] local_ip +); + +/* + +IP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + payload length octets + +This module receives an Ethernet frame with decoded fields and decodes +the AXI packet format. If the Ethertype does not match, the packet is +discarded. + +*/ + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_ARP_QUERY = 2'd1, + STATE_SEND_PACKET = 2'd2, + STATE_DROP_PACKET = 2'd3; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg outgoing_ip_hdr_valid_reg = 1'b0, outgoing_ip_hdr_valid_next; +wire outgoing_ip_hdr_ready; +reg [47:0] outgoing_eth_dest_mac_reg = 48'h000000000000, outgoing_eth_dest_mac_next; +wire outgoing_ip_payload_tready; + +/* + * IP frame processing + */ +ip_eth_rx_64 +ip_eth_rx_64_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_ip_eth_dest_mac), + .output_eth_src_mac(output_ip_eth_src_mac), + .output_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .busy(rx_busy), + .error_header_early_termination(rx_error_header_early_termination), + .error_payload_early_termination(rx_error_payload_early_termination), + .error_invalid_header(rx_error_invalid_header), + .error_invalid_checksum(rx_error_invalid_checksum) +); + +ip_eth_tx_64 +ip_eth_tx_64_inst ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(outgoing_ip_hdr_valid_reg), + .input_ip_hdr_ready(outgoing_ip_hdr_ready), + .input_eth_dest_mac(outgoing_eth_dest_mac_reg), + .input_eth_src_mac(local_mac), + .input_eth_type(16'h0800), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(16'd0), + .input_ip_flags(3'b010), + .input_ip_fragment_offset(13'd0), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(outgoing_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Status signals + .busy(tx_busy), + .error_payload_early_termination(tx_error_payload_early_termination) +); + +reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; + +reg arp_request_valid_reg = 0; + +reg drop_packet_reg = 0; + +assign input_ip_hdr_ready = input_ip_hdr_ready_reg; +assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; + +assign arp_request_valid = arp_request_valid_reg | input_ip_hdr_valid; +assign arp_request_ip = input_ip_dest_ip; + +assign tx_error_arp_failed = arp_response_error; + +always @* begin + state_next = 8'bz; + + input_ip_hdr_ready_next = 0; + + outgoing_ip_hdr_valid_next = outgoing_ip_hdr_valid_reg & ~outgoing_ip_hdr_ready; + outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; + + case (state_reg) + STATE_IDLE: begin + // wait for outgoing packet + if (input_ip_hdr_valid) begin + // initiate ARP request + state_next = STATE_ARP_QUERY; + end else begin + state_next = STATE_IDLE; + end + end + STATE_ARP_QUERY: begin + if (arp_response_valid) begin + // wait for ARP reponse + if (arp_response_error) begin + // did not get MAC address; drop packet + input_ip_hdr_ready_next = 1; + state_next = STATE_DROP_PACKET; + end else begin + // got MAC address; send packet + input_ip_hdr_ready_next = 1; + outgoing_ip_hdr_valid_next = 1; + outgoing_eth_dest_mac_next = arp_response_mac; + state_next = STATE_SEND_PACKET; + end + end else begin + state_next = STATE_ARP_QUERY; + end + end + STATE_SEND_PACKET: begin + // wait for packet transfer to complete + if (input_ip_payload_tlast & input_ip_payload_tvalid) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_SEND_PACKET; + end + end + STATE_DROP_PACKET: begin + // wait for packet transfer to complete + if (input_ip_payload_tlast & input_ip_payload_tvalid) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_DROP_PACKET; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + arp_request_valid_reg <= 0; + input_ip_hdr_ready_reg <= 0; + outgoing_ip_hdr_valid_reg <= 1'b0; + outgoing_eth_dest_mac_reg <= 48'h000000000000; + drop_packet_reg <= 0; + + end else begin + state_reg <= state_next; + + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + + outgoing_ip_hdr_valid_reg <= outgoing_ip_hdr_valid_next; + outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; + + // generate valid outputs + case (state_next) + STATE_IDLE: begin + // idle; wait for IP packet + arp_request_valid_reg <= 0; + drop_packet_reg <= 0; + end + STATE_ARP_QUERY: begin + // wait for ARP reponse + arp_request_valid_reg <= 1; + drop_packet_reg <= 0; + end + STATE_SEND_PACKET: begin + // wait for packet transfer to complete + arp_request_valid_reg <= 0; + drop_packet_reg <= 0; + end + STATE_DROP_PACKET: begin + // wait for packet transfer to complete + arp_request_valid_reg <= 0; + drop_packet_reg <= 1; + end + endcase + + end +end + +endmodule diff --git a/tb/test_ip_64.py b/tb/test_ip_64.py new file mode 100755 index 000000000..788184f18 --- /dev/null +++ b/tb/test_ip_64.py @@ -0,0 +1,715 @@ +#!/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 eth_ep +import ip_ep + +module = 'ip_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) +srcs.append("../rtl/ip_eth_rx_64.v") +srcs.append("../rtl/ip_eth_tx_64.v") + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_ip_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + arp_request_valid, + arp_request_ip, + arp_response_valid, + arp_response_error, + arp_response_mac, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed, + + local_mac, + local_ip): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + arp_request_valid=arp_request_valid, + arp_request_ip=arp_request_ip, + arp_response_valid=arp_response_valid, + arp_response_error=arp_response_error, + arp_response_mac=arp_response_mac, + + input_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tkeep=input_ip_payload_tkeep, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_ip_eth_dest_mac=output_ip_eth_dest_mac, + output_ip_eth_src_mac=output_ip_eth_src_mac, + output_ip_eth_type=output_ip_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tkeep=output_ip_payload_tkeep, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + rx_busy=rx_busy, + tx_busy=tx_busy, + rx_error_header_early_termination=rx_error_header_early_termination, + rx_error_payload_early_termination=rx_error_payload_early_termination, + rx_error_invalid_header=rx_error_invalid_header, + rx_error_invalid_checksum=rx_error_invalid_checksum, + tx_error_payload_early_termination=tx_error_payload_early_termination, + tx_error_arp_failed=tx_error_arp_failed, + + local_mac=local_mac, + local_ip=local_ip) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[64:]) + input_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + arp_response_valid = Signal(bool(0)) + arp_response_error = Signal(bool(0)) + arp_response_mac = Signal(intbv(0)[48:]) + input_ip_hdr_valid = Signal(bool(0)) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[64:]) + input_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[64:]) + output_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + arp_request_valid = Signal(bool(0)) + arp_request_ip = Signal(intbv(0)[32:]) + output_ip_hdr_valid = Signal(bool(0)) + output_ip_eth_dest_mac = Signal(intbv(0)[48:]) + output_ip_eth_src_mac = Signal(intbv(0)[48:]) + output_ip_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[64:]) + output_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + rx_busy = Signal(bool(0)) + tx_busy = Signal(bool(0)) + rx_error_header_early_termination = Signal(bool(0)) + rx_error_payload_early_termination = Signal(bool(0)) + rx_error_invalid_header = Signal(bool(0)) + rx_error_invalid_checksum = Signal(bool(0)) + tx_error_payload_early_termination = Signal(bool(0)) + tx_error_arp_failed = Signal(bool(0)) + local_mac = Signal(intbv(0)[48:]) + local_ip = Signal(intbv(0)[32:]) + + # sources and sinks + eth_source_queue = Queue() + eth_source_pause = Signal(bool(0)) + eth_sink_queue = Queue() + eth_sink_pause = Signal(bool(0)) + ip_source_queue = Queue() + ip_source_pause = Signal(bool(0)) + ip_sink_queue = Queue() + ip_sink_pause = Signal(bool(0)) + + eth_source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=eth_source_queue, + pause=eth_source_pause, + name='eth_source') + + eth_sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=eth_sink_queue, + pause=eth_sink_pause, + name='eth_sink') + + ip_source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tkeep=input_ip_payload_tkeep, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=ip_source_queue, + pause=ip_source_pause, + name='ip_source') + + ip_sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_ip_eth_dest_mac, + eth_src_mac=output_ip_eth_src_mac, + eth_type=output_ip_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tkeep=output_ip_payload_tkeep, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=ip_sink_queue, + pause=ip_sink_pause, + name='ip_sink') + + # DUT + dut = dut_ip_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + arp_request_valid, + arp_request_ip, + arp_response_valid, + arp_response_error, + arp_response_mac, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed, + + local_mac, + local_ip) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + arp_table = {} + + @instance + def arp_emu(): + while True: + yield clk.posedge + + arp_response_valid.next = 0 + arp_response_error.next = 0 + arp_response_mac.next = 0 + + if arp_request_valid: + if int(arp_request_ip) in arp_table: + arp_response_valid.next = 1 + arp_response_mac.next = arp_table[int(arp_request_ip)] + else: + arp_response_valid.next = 1 + arp_response_error.next = 1 + + rx_error_header_early_termination_asserted = Signal(bool(0)) + rx_error_payload_early_termination_asserted = Signal(bool(0)) + rx_error_invalid_header_asserted = Signal(bool(0)) + rx_error_invalid_checksum_asserted = Signal(bool(0)) + tx_error_payload_early_termination_asserted = Signal(bool(0)) + tx_error_arp_failed_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_header_early_termination): + rx_error_header_early_termination_asserted.next = 1 + if (rx_error_payload_early_termination): + rx_error_payload_early_termination_asserted.next = 1 + if (rx_error_invalid_header): + rx_error_invalid_header_asserted.next = 1 + if (rx_error_invalid_checksum): + rx_error_invalid_checksum_asserted.next = 1 + if (tx_error_payload_early_termination): + tx_error_payload_early_termination_asserted.next = 1 + if (tx_error_arp_failed): + tx_error_arp_failed_asserted.next = 1 + + def wait_normal(): + while (input_eth_payload_tvalid or input_ip_payload_tvalid or + output_eth_payload_tvalid or output_ip_payload_tvalid or + input_eth_hdr_valid or input_ip_hdr_valid): + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # set MAC and IP address + local_mac.next = 0x5A5152535455 + local_ip.next = 0xc0a80164 + + # put an entry in the ARP table + arp_table[0xc0a80165] = 0xDAD1D2D3D4D5 + + yield clk.posedge + print("test 1: test IP RX packet") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not ip_sink_queue.empty(): + rx_frame = ip_sink_queue.get() + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test IP TX packet") + current_test.next = 2 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get() + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: test IP TX arp fail packet") + current_test.next = 2 + + tx_error_arp_failed_asserted.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + assert tx_error_arp_failed_asserted + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, eth_source, eth_sink, ip_source, ip_sink, clkgen, arp_emu, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_64.v b/tb/test_ip_64.v new file mode 100644 index 000000000..2228501ab --- /dev/null +++ b/tb/test_ip_64.v @@ -0,0 +1,291 @@ +/* + +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_ip_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [63:0] input_eth_payload_tdata = 0; +reg [7:0] input_eth_payload_tkeep = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg arp_response_valid = 0; +reg arp_response_error = 0; +reg [47:0] arp_response_mac = 0; +reg input_ip_hdr_valid = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [63:0] input_ip_payload_tdata = 0; +reg [7:0] input_ip_payload_tkeep = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; +reg [47:0] local_mac = 0; +reg [31:0] local_ip = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [63:0] output_eth_payload_tdata; +wire [7:0] output_eth_payload_tkeep; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire arp_request_valid; +wire [31:0] arp_request_ip; +wire output_ip_hdr_valid; +wire [47:0] output_ip_eth_dest_mac; +wire [47:0] output_ip_eth_src_mac; +wire [15:0] output_ip_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [63:0] output_ip_payload_tdata; +wire [7:0] output_ip_payload_tkeep; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire rx_busy; +wire tx_busy; +wire rx_error_header_early_termination; +wire rx_error_payload_early_termination; +wire rx_error_invalid_header; +wire rx_error_invalid_checksum; +wire tx_error_payload_early_termination; +wire tx_error_arp_failed; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + arp_response_valid, + arp_response_error, + arp_response_mac, + input_ip_hdr_valid, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + output_ip_hdr_ready, + output_ip_payload_tready, + local_mac, + local_ip); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + input_ip_hdr_ready, + input_ip_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + arp_request_valid, + arp_request_ip, + output_ip_hdr_valid, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed); + + // dump file + $dumpfile("test_ip_64.lxt"); + $dumpvars(0, test_ip_64); +end + +ip_64 +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // ARP requests + .arp_request_valid(arp_request_valid), + .arp_request_ip(arp_request_ip), + .arp_response_valid(arp_response_valid), + .arp_response_error(arp_response_error), + .arp_response_mac(arp_response_mac), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .rx_busy(rx_busy), + .tx_busy(tx_busy), + .rx_error_header_early_termination(rx_error_header_early_termination), + .rx_error_payload_early_termination(rx_error_payload_early_termination), + .rx_error_invalid_header(rx_error_invalid_header), + .rx_error_invalid_checksum(rx_error_invalid_checksum), + .tx_error_payload_early_termination(tx_error_payload_early_termination), + .tx_error_arp_failed(tx_error_arp_failed), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip) +); + +endmodule From 6ab2a86e13279003877e0ba6557fb1c950a4e201 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 30 Sep 2014 17:51:24 -0700 Subject: [PATCH 037/617] Change default data width --- rtl/axis_register_64.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v index 3b494e95a..b041ef427 100644 --- a/rtl/axis_register_64.v +++ b/rtl/axis_register_64.v @@ -31,7 +31,7 @@ THE SOFTWARE. */ module axis_register_64 # ( - parameter DATA_WIDTH = 8, + parameter DATA_WIDTH = 64, parameter KEEP_WIDTH = (DATA_WIDTH/8) ) ( From ca504230360bc04bd532e4d5fbffe61fc13f8f7a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 30 Sep 2014 17:51:24 -0700 Subject: [PATCH 038/617] Change default data width --- rtl/axis_register_64.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v index 3b494e95a..b041ef427 100644 --- a/rtl/axis_register_64.v +++ b/rtl/axis_register_64.v @@ -31,7 +31,7 @@ THE SOFTWARE. */ module axis_register_64 # ( - parameter DATA_WIDTH = 8, + parameter DATA_WIDTH = 64, parameter KEEP_WIDTH = (DATA_WIDTH/8) ) ( From f53f4aa5047a9b68ae1bbd6fa336a285d3a7ff76 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Oct 2014 15:02:54 -0700 Subject: [PATCH 039/617] Rework AXI stream register --- rtl/axis_register.v | 113 ++++++++------------------------------- rtl/axis_register_64.v | 117 +++++++++-------------------------------- 2 files changed, 46 insertions(+), 184 deletions(-) diff --git a/rtl/axis_register.v b/rtl/axis_register.v index 42fa50104..f7ede82bf 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -56,19 +56,6 @@ module axis_register # output wire output_axis_tuser ); -// state register -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_TRANSFER = 2'd1, - STATE_TRANSFER_WAIT = 2'd2; - -reg [1:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - // datapath registers reg input_axis_tready_reg = 0; @@ -78,6 +65,7 @@ reg output_axis_tlast_reg = 0; reg output_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; reg temp_axis_tlast_reg = 0; reg temp_axis_tuser_reg = 0; @@ -88,98 +76,41 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -always @* begin - state_next = 2'bz; - - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - case (state_reg) - STATE_IDLE: begin - // idle state - no data in registers - if (input_axis_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; - state_next = STATE_TRANSFER; - end else begin - state_next = STATE_IDLE; - end - end - STATE_TRANSFER: begin - // transfer state - data in output register - if (input_axis_tvalid & output_axis_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - state_next = STATE_TRANSFER; - end else if (~input_axis_tvalid & output_axis_tready) begin - // word transfer out - go back to idle - state_next = STATE_IDLE; - end else if (input_axis_tvalid & ~output_axis_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - state_next = STATE_TRANSFER_WAIT; - end else begin - state_next = STATE_TRANSFER; - end - end - STATE_TRANSFER_WAIT: begin - // transfer wait state - data in both output and temp registers - if (output_axis_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - state_next = STATE_TRANSFER; - end else begin - state_next = STATE_TRANSFER_WAIT; - end - end - endcase -end - always @(posedge clk or posedge rst) begin if (rst) begin - state_reg <= STATE_IDLE; input_axis_tready_reg <= 0; output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; output_axis_tlast_reg <= 0; output_axis_tuser_reg <= 0; temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; temp_axis_tlast_reg <= 0; temp_axis_tuser_reg <= 0; end else begin - state_reg <= state_next; + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + input_axis_tready_reg <= output_axis_tready | (~output_axis_tvalid_reg & ~input_axis_tvalid); - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle state - no data in registers; accept new data - input_axis_tready_reg <= 1; - output_axis_tvalid_reg <= 0; + if (input_axis_tready_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= input_axis_tdata; + output_axis_tvalid_reg <= input_axis_tvalid; + output_axis_tlast_reg <= input_axis_tlast; + output_axis_tuser_reg <= input_axis_tuser; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= input_axis_tdata; + temp_axis_tvalid_reg <= input_axis_tvalid; + temp_axis_tlast_reg <= input_axis_tlast; + temp_axis_tuser_reg <= input_axis_tuser; end - STATE_TRANSFER: begin - // transfer state - data in output register; accept new data - input_axis_tready_reg <= 1; - output_axis_tvalid_reg <= 1; - end - STATE_TRANSFER_WAIT: begin - // transfer wait state - data in output and temp registers; do not accept new data - input_axis_tready_reg <= 0; - output_axis_tvalid_reg <= 1; - end - endcase - - // datapath - if (transfer_in_out) begin - output_axis_tdata_reg <= input_axis_tdata; - output_axis_tlast_reg <= input_axis_tlast; - output_axis_tuser_reg <= input_axis_tuser; - end else if (transfer_in_temp) begin - temp_axis_tdata_reg <= input_axis_tdata; - temp_axis_tlast_reg <= input_axis_tlast; - temp_axis_tuser_reg <= input_axis_tuser; - end else if (transfer_temp_out) begin + end else if (output_axis_tready) begin + // input is not ready, but output is ready output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v index b041ef427..ea0fc658b 100644 --- a/rtl/axis_register_64.v +++ b/rtl/axis_register_64.v @@ -59,19 +59,6 @@ module axis_register_64 # output wire output_axis_tuser ); -// state register -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_TRANSFER = 2'd1, - STATE_TRANSFER_WAIT = 2'd2; - -reg [1:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - // datapath registers reg input_axis_tready_reg = 0; @@ -83,6 +70,7 @@ reg output_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; reg temp_axis_tlast_reg = 0; reg temp_axis_tuser_reg = 0; @@ -94,57 +82,8 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -always @* begin - state_next = 2'bz; - - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - case (state_reg) - STATE_IDLE: begin - // idle state - no data in registers - if (input_axis_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; - state_next = STATE_TRANSFER; - end else begin - state_next = STATE_IDLE; - end - end - STATE_TRANSFER: begin - // transfer state - data in output register - if (input_axis_tvalid & output_axis_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - state_next = STATE_TRANSFER; - end else if (~input_axis_tvalid & output_axis_tready) begin - // word transfer out - go back to idle - state_next = STATE_IDLE; - end else if (input_axis_tvalid & ~output_axis_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - state_next = STATE_TRANSFER_WAIT; - end else begin - state_next = STATE_TRANSFER; - end - end - STATE_TRANSFER_WAIT: begin - // transfer wait state - data in both output and temp registers - if (output_axis_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - state_next = STATE_TRANSFER; - end else begin - state_next = STATE_TRANSFER_WAIT; - end - end - endcase -end - always @(posedge clk or posedge rst) begin if (rst) begin - state_reg <= STATE_IDLE; input_axis_tready_reg <= 0; output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; @@ -153,44 +92,36 @@ always @(posedge clk or posedge rst) begin output_axis_tuser_reg <= 0; temp_axis_tdata_reg <= 0; temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; temp_axis_tlast_reg <= 0; temp_axis_tuser_reg <= 0; end else begin - state_reg <= state_next; + // transfer sink ready state to source + // also enable ready input next cycle even if output is not ready if output is currently not valid and will not become valid next cycle + input_axis_tready_reg <= output_axis_tready | (~output_axis_tvalid_reg & ~input_axis_tvalid); - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle state - no data in registers; accept new data - input_axis_tready_reg <= 1; - output_axis_tvalid_reg <= 0; + if (input_axis_tready_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= input_axis_tdata; + output_axis_tkeep_reg <= input_axis_tkeep; + output_axis_tvalid_reg <= input_axis_tvalid; + output_axis_tlast_reg <= input_axis_tlast; + output_axis_tuser_reg <= input_axis_tuser; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= input_axis_tdata; + temp_axis_tkeep_reg <= input_axis_tkeep; + temp_axis_tvalid_reg <= input_axis_tvalid; + temp_axis_tlast_reg <= input_axis_tlast; + temp_axis_tuser_reg <= input_axis_tuser; end - STATE_TRANSFER: begin - // transfer state - data in output register; accept new data - input_axis_tready_reg <= 1; - output_axis_tvalid_reg <= 1; - end - STATE_TRANSFER_WAIT: begin - // transfer wait state - data in output and temp registers; do not accept new data - input_axis_tready_reg <= 0; - output_axis_tvalid_reg <= 1; - end - endcase - - // datapath - if (transfer_in_out) begin - output_axis_tdata_reg <= input_axis_tdata; - output_axis_tkeep_reg <= input_axis_tkeep; - output_axis_tlast_reg <= input_axis_tlast; - output_axis_tuser_reg <= input_axis_tuser; - end else if (transfer_in_temp) begin - temp_axis_tdata_reg <= input_axis_tdata; - temp_axis_tkeep_reg <= input_axis_tkeep; - temp_axis_tlast_reg <= input_axis_tlast; - temp_axis_tuser_reg <= input_axis_tuser; - end else if (transfer_temp_out) begin + end else if (output_axis_tready) begin + // input is not ready, but output is ready output_axis_tdata_reg <= temp_axis_tdata_reg; output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end From 2ec83046f6fed7927210145a304abe00e1d2738d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Oct 2014 15:02:54 -0700 Subject: [PATCH 040/617] Rework AXI stream register --- rtl/axis_register.v | 113 ++++++++------------------------------- rtl/axis_register_64.v | 117 +++++++++-------------------------------- 2 files changed, 46 insertions(+), 184 deletions(-) diff --git a/rtl/axis_register.v b/rtl/axis_register.v index 42fa50104..f7ede82bf 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -56,19 +56,6 @@ module axis_register # output wire output_axis_tuser ); -// state register -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_TRANSFER = 2'd1, - STATE_TRANSFER_WAIT = 2'd2; - -reg [1:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - // datapath registers reg input_axis_tready_reg = 0; @@ -78,6 +65,7 @@ reg output_axis_tlast_reg = 0; reg output_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; reg temp_axis_tlast_reg = 0; reg temp_axis_tuser_reg = 0; @@ -88,98 +76,41 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -always @* begin - state_next = 2'bz; - - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - case (state_reg) - STATE_IDLE: begin - // idle state - no data in registers - if (input_axis_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; - state_next = STATE_TRANSFER; - end else begin - state_next = STATE_IDLE; - end - end - STATE_TRANSFER: begin - // transfer state - data in output register - if (input_axis_tvalid & output_axis_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - state_next = STATE_TRANSFER; - end else if (~input_axis_tvalid & output_axis_tready) begin - // word transfer out - go back to idle - state_next = STATE_IDLE; - end else if (input_axis_tvalid & ~output_axis_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - state_next = STATE_TRANSFER_WAIT; - end else begin - state_next = STATE_TRANSFER; - end - end - STATE_TRANSFER_WAIT: begin - // transfer wait state - data in both output and temp registers - if (output_axis_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - state_next = STATE_TRANSFER; - end else begin - state_next = STATE_TRANSFER_WAIT; - end - end - endcase -end - always @(posedge clk or posedge rst) begin if (rst) begin - state_reg <= STATE_IDLE; input_axis_tready_reg <= 0; output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; output_axis_tlast_reg <= 0; output_axis_tuser_reg <= 0; temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; temp_axis_tlast_reg <= 0; temp_axis_tuser_reg <= 0; end else begin - state_reg <= state_next; + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + input_axis_tready_reg <= output_axis_tready | (~output_axis_tvalid_reg & ~input_axis_tvalid); - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle state - no data in registers; accept new data - input_axis_tready_reg <= 1; - output_axis_tvalid_reg <= 0; + if (input_axis_tready_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= input_axis_tdata; + output_axis_tvalid_reg <= input_axis_tvalid; + output_axis_tlast_reg <= input_axis_tlast; + output_axis_tuser_reg <= input_axis_tuser; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= input_axis_tdata; + temp_axis_tvalid_reg <= input_axis_tvalid; + temp_axis_tlast_reg <= input_axis_tlast; + temp_axis_tuser_reg <= input_axis_tuser; end - STATE_TRANSFER: begin - // transfer state - data in output register; accept new data - input_axis_tready_reg <= 1; - output_axis_tvalid_reg <= 1; - end - STATE_TRANSFER_WAIT: begin - // transfer wait state - data in output and temp registers; do not accept new data - input_axis_tready_reg <= 0; - output_axis_tvalid_reg <= 1; - end - endcase - - // datapath - if (transfer_in_out) begin - output_axis_tdata_reg <= input_axis_tdata; - output_axis_tlast_reg <= input_axis_tlast; - output_axis_tuser_reg <= input_axis_tuser; - end else if (transfer_in_temp) begin - temp_axis_tdata_reg <= input_axis_tdata; - temp_axis_tlast_reg <= input_axis_tlast; - temp_axis_tuser_reg <= input_axis_tuser; - end else if (transfer_temp_out) begin + end else if (output_axis_tready) begin + // input is not ready, but output is ready output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v index b041ef427..ea0fc658b 100644 --- a/rtl/axis_register_64.v +++ b/rtl/axis_register_64.v @@ -59,19 +59,6 @@ module axis_register_64 # output wire output_axis_tuser ); -// state register -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_TRANSFER = 2'd1, - STATE_TRANSFER_WAIT = 2'd2; - -reg [1:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - // datapath registers reg input_axis_tready_reg = 0; @@ -83,6 +70,7 @@ reg output_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; reg temp_axis_tlast_reg = 0; reg temp_axis_tuser_reg = 0; @@ -94,57 +82,8 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -always @* begin - state_next = 2'bz; - - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - case (state_reg) - STATE_IDLE: begin - // idle state - no data in registers - if (input_axis_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; - state_next = STATE_TRANSFER; - end else begin - state_next = STATE_IDLE; - end - end - STATE_TRANSFER: begin - // transfer state - data in output register - if (input_axis_tvalid & output_axis_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - state_next = STATE_TRANSFER; - end else if (~input_axis_tvalid & output_axis_tready) begin - // word transfer out - go back to idle - state_next = STATE_IDLE; - end else if (input_axis_tvalid & ~output_axis_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - state_next = STATE_TRANSFER_WAIT; - end else begin - state_next = STATE_TRANSFER; - end - end - STATE_TRANSFER_WAIT: begin - // transfer wait state - data in both output and temp registers - if (output_axis_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - state_next = STATE_TRANSFER; - end else begin - state_next = STATE_TRANSFER_WAIT; - end - end - endcase -end - always @(posedge clk or posedge rst) begin if (rst) begin - state_reg <= STATE_IDLE; input_axis_tready_reg <= 0; output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; @@ -153,44 +92,36 @@ always @(posedge clk or posedge rst) begin output_axis_tuser_reg <= 0; temp_axis_tdata_reg <= 0; temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; temp_axis_tlast_reg <= 0; temp_axis_tuser_reg <= 0; end else begin - state_reg <= state_next; + // transfer sink ready state to source + // also enable ready input next cycle even if output is not ready if output is currently not valid and will not become valid next cycle + input_axis_tready_reg <= output_axis_tready | (~output_axis_tvalid_reg & ~input_axis_tvalid); - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle state - no data in registers; accept new data - input_axis_tready_reg <= 1; - output_axis_tvalid_reg <= 0; + if (input_axis_tready_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= input_axis_tdata; + output_axis_tkeep_reg <= input_axis_tkeep; + output_axis_tvalid_reg <= input_axis_tvalid; + output_axis_tlast_reg <= input_axis_tlast; + output_axis_tuser_reg <= input_axis_tuser; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= input_axis_tdata; + temp_axis_tkeep_reg <= input_axis_tkeep; + temp_axis_tvalid_reg <= input_axis_tvalid; + temp_axis_tlast_reg <= input_axis_tlast; + temp_axis_tuser_reg <= input_axis_tuser; end - STATE_TRANSFER: begin - // transfer state - data in output register; accept new data - input_axis_tready_reg <= 1; - output_axis_tvalid_reg <= 1; - end - STATE_TRANSFER_WAIT: begin - // transfer wait state - data in output and temp registers; do not accept new data - input_axis_tready_reg <= 0; - output_axis_tvalid_reg <= 1; - end - endcase - - // datapath - if (transfer_in_out) begin - output_axis_tdata_reg <= input_axis_tdata; - output_axis_tkeep_reg <= input_axis_tkeep; - output_axis_tlast_reg <= input_axis_tlast; - output_axis_tuser_reg <= input_axis_tuser; - end else if (transfer_in_temp) begin - temp_axis_tdata_reg <= input_axis_tdata; - temp_axis_tkeep_reg <= input_axis_tkeep; - temp_axis_tlast_reg <= input_axis_tlast; - temp_axis_tuser_reg <= input_axis_tuser; - end else if (transfer_temp_out) begin + end else if (output_axis_tready) begin + // input is not ready, but output is ready output_axis_tdata_reg <= temp_axis_tdata_reg; output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end From 2495dd2bac4275d6b70ce2a411a3498262a81939 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Oct 2014 15:04:36 -0700 Subject: [PATCH 041/617] Initial commit of AXI stream width adapter --- rtl/axis_adapter.v | 425 +++++++++++++++++++++++++++++++++++ tb/test_axis_adapter_64_8.py | 318 ++++++++++++++++++++++++++ tb/test_axis_adapter_64_8.v | 105 +++++++++ tb/test_axis_adapter_8_64.py | 318 ++++++++++++++++++++++++++ tb/test_axis_adapter_8_64.v | 105 +++++++++ 5 files changed, 1271 insertions(+) create mode 100644 rtl/axis_adapter.v create mode 100755 tb/test_axis_adapter_64_8.py create mode 100644 tb/test_axis_adapter_64_8.v create mode 100755 tb/test_axis_adapter_8_64.py create mode 100644 tb/test_axis_adapter_8_64.v diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v new file mode 100644 index 000000000..9fe64e502 --- /dev/null +++ b/rtl/axis_adapter.v @@ -0,0 +1,425 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream bus width adapter + */ +module axis_adapter # +( + parameter INPUT_DATA_WIDTH = 8, + parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8), + parameter OUTPUT_DATA_WIDTH = 8, + parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [INPUT_DATA_WIDTH-1:0] input_axis_tdata, + input wire [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata, + output wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser +); + +// bus word widths (must be identical) +localparam INPUT_DATA_WORD_WIDTH = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH; +localparam OUTPUT_DATA_WORD_WIDTH = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH; +// output bus is wider +localparam EXPAND_BUS = OUTPUT_KEEP_WIDTH > INPUT_KEEP_WIDTH; +// total data and keep widths +localparam DATA_WIDTH = EXPAND_BUS ? OUTPUT_DATA_WIDTH : INPUT_DATA_WIDTH; +localparam KEEP_WIDTH = EXPAND_BUS ? OUTPUT_KEEP_WIDTH : INPUT_KEEP_WIDTH; +// required number of cycles to match widths +localparam CYCLE_COUNT = EXPAND_BUS ? (OUTPUT_KEEP_WIDTH / INPUT_KEEP_WIDTH) : (INPUT_KEEP_WIDTH / OUTPUT_KEEP_WIDTH); +// data width and keep width per cycle +localparam CYCLE_DATA_WIDTH = DATA_WIDTH / CYCLE_COUNT; +localparam CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT; + +// bus width assertions +initial begin + if (INPUT_DATA_WORD_WIDTH * INPUT_KEEP_WIDTH != INPUT_DATA_WIDTH) begin + $error("Error: input data width not evenly divisble"); + $finish; + end + + if (OUTPUT_DATA_WORD_WIDTH * OUTPUT_KEEP_WIDTH != OUTPUT_DATA_WIDTH) begin + $error("Error: output data width not evenly divisble"); + $finish; + end + + if (INPUT_DATA_WORD_WIDTH != OUTPUT_DATA_WORD_WIDTH) begin + $error("Error: word width mismatch"); + $finish; + end +end + +// state register +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_TRANSFER_IN = 3'd1, + STATE_TRANSFER_OUT = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +reg [7:0] cycle_count_reg = 0, cycle_count_next; + +reg [DATA_WIDTH-1:0] temp_tdata_reg = 0, temp_tdata_next; +reg [KEEP_WIDTH-1:0] temp_tkeep_reg = 0, temp_tkeep_next; +reg temp_tlast_reg = 0, temp_tlast_next; +reg temp_tuser_reg = 0, temp_tuser_next; + +// internal datapath +reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_int; +reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +always @* begin + state_next = 3'bz; + + cycle_count_next = cycle_count_reg; + + temp_tdata_next = temp_tdata_reg; + temp_tkeep_next = temp_tkeep_reg; + temp_tlast_next = temp_tlast_reg; + temp_tuser_next = temp_tuser_reg; + + output_axis_tdata_int = 0; + output_axis_tkeep_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + input_axis_tready_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - no data in registers + if (CYCLE_COUNT == 1) begin + // output and input same width - just act like a register + + // accept data next cycle if output register ready next cycle + input_axis_tready_next = output_axis_tready_int_early; + + // transfer through + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = input_axis_tvalid; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; + + state_next = STATE_IDLE; + end else if (EXPAND_BUS) begin + // output bus is wider + + // accept new data + input_axis_tready_next = 1; + + if (input_axis_tvalid) begin + // word transfer in - store it in data register + + // pass complete input word, zero-extended to temp register + temp_tdata_next = input_axis_tdata; + temp_tkeep_next = input_axis_tkeep; + temp_tlast_next = input_axis_tlast; + temp_tuser_next = input_axis_tuser; + + // first input cycle complete + cycle_count_next = 1; + + if (input_axis_tlast) begin + // got last signal on first cycle, so output it + input_axis_tready_next = 0; + state_next = STATE_TRANSFER_OUT; + end else begin + // otherwise, transfer in the rest of the words + input_axis_tready_next = 1; + state_next = STATE_TRANSFER_IN; + end + end else begin + state_next = STATE_IDLE; + end + end else begin + // output bus is narrower + + // accept new data + input_axis_tready_next = 1; + + if (input_axis_tvalid) begin + // word transfer in - store it in data register + cycle_count_next = 0; + + // pass complete input word, zero-extended to temp register + temp_tdata_next = input_axis_tdata; + temp_tkeep_next = input_axis_tkeep; + temp_tlast_next = input_axis_tlast; + temp_tuser_next = input_axis_tuser; + + // short-circuit and get first word out the door + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = 1; + output_axis_tlast_int = input_axis_tlast & ((CYCLE_COUNT == 1) | (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}})); + output_axis_tuser_int = input_axis_tuser & ((CYCLE_COUNT == 1) | (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}})); + + if (output_axis_tready_int) begin + // if output register is ready for first word, then move on to the next one + cycle_count_next = 1; + end + + // continue outputting words + input_axis_tready_next = 0; + state_next = STATE_TRANSFER_OUT; + end else begin + state_next = STATE_IDLE; + end + end + end + STATE_TRANSFER_IN: begin + // transfer word to temp registers + // only used when output is wider + + // accept new data + input_axis_tready_next = 1; + + if (input_axis_tvalid) begin + // word transfer in - store in data register + + temp_tdata_next[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH] = input_axis_tdata; + temp_tkeep_next[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] = input_axis_tkeep; + temp_tlast_next = input_axis_tlast; + temp_tuser_next = input_axis_tuser; + + cycle_count_next = cycle_count_reg + 1; + + if ((cycle_count_reg == CYCLE_COUNT-1) | input_axis_tlast) begin + // terminated by counter or tlast signal, output complete word + // read input word next cycle if output will be ready + input_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_TRANSFER_OUT; + end else begin + // more words to read + input_axis_tready_next = 1; + state_next = STATE_TRANSFER_IN; + end + end else begin + state_next = STATE_TRANSFER_IN; + end + end + STATE_TRANSFER_OUT: begin + // transfer word to output registers + + if (EXPAND_BUS) begin + // output bus is wider + + // do not accept new data + input_axis_tready_next = 0; + + // single-cycle output of entire stored word (output wider) + output_axis_tdata_int = temp_tdata_reg; + output_axis_tkeep_int = temp_tkeep_reg; + output_axis_tvalid_int = 1; + output_axis_tlast_int = temp_tlast_reg; + output_axis_tuser_int = temp_tuser_reg; + + if (output_axis_tready_int) begin + // word transfer out + + if (input_axis_tready & input_axis_tvalid) begin + // word transfer in + + // pass complete input word, zero-extended to temp register + temp_tdata_next = input_axis_tdata; + temp_tkeep_next = input_axis_tkeep; + temp_tlast_next = input_axis_tlast; + temp_tuser_next = input_axis_tuser; + + // first input cycle complete + cycle_count_next = 1; + + if (input_axis_tlast) begin + // got last signal on first cycle, so output it + input_axis_tready_next = 0; + state_next = STATE_TRANSFER_OUT; + end else begin + // otherwise, transfer in the rest of the words + input_axis_tready_next = 1; + state_next = STATE_TRANSFER_IN; + end + end else begin + input_axis_tready_next = 1; + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_TRANSFER_OUT; + end + end else begin + // output bus is narrower + + // do not accept new data + input_axis_tready_next = 0; + + // output current part of stored word (output narrower) + output_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH]; + output_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH]; + output_axis_tvalid_int = 1; + output_axis_tlast_int = temp_tlast_reg & ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})); + output_axis_tuser_int = temp_tuser_reg & ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})); + + if (output_axis_tready_int) begin + // word transfer out + + cycle_count_next = cycle_count_reg + 1; + + if ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})) begin + // terminated by counter or tlast signal + + input_axis_tready_next = 1; + state_next = STATE_IDLE; + end else begin + // more words to write + state_next = STATE_TRANSFER_OUT; + end + end else begin + state_next = STATE_TRANSFER_OUT; + end + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + cycle_count_reg <= 0; + temp_tdata_reg <= 0; + temp_tkeep_reg <= 0; + temp_tlast_reg <= 0; + temp_tuser_reg <= 0; + input_axis_tready_reg <= 0; + end else begin + state_reg <= state_next; + + input_axis_tready_reg <= input_axis_tready_next; + + temp_tdata_reg <= temp_tdata_next; + temp_tkeep_reg <= temp_tkeep_next; + temp_tlast_reg <= temp_tlast_next; + temp_tuser_reg <= temp_tuser_next; + + cycle_count_reg <= cycle_count_next; + end +end + +// output datapath logic +reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py new file mode 100755 index 000000000..a5333dad2 --- /dev/null +++ b/tb/test_axis_adapter_64_8.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue + +import axis_ep + +module = 'axis_adapter' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s_64_8.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_adapter_64_8(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tkeep=input_axis_tkeep, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[64:]) + input_axis_tkeep = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tkeep = Signal(intbv(0)[1:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tkeep=input_axis_tkeep, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_adapter_64_8(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + test_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_adapter_64_8.v b/tb/test_axis_adapter_64_8.v new file mode 100644 index 000000000..be74bbbe5 --- /dev/null +++ b/tb/test_axis_adapter_64_8.v @@ -0,0 +1,105 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_adapter_64_8; + +// parameters +localparam INPUT_DATA_WIDTH = 64; +localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); +localparam OUTPUT_DATA_WIDTH = 8; +localparam OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata; +wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_adapter_64_8.lxt"); + $dumpvars(0, test_axis_adapter_64_8); +end + +axis_adapter #( + .INPUT_DATA_WIDTH(INPUT_DATA_WIDTH), + .INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH), + .OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH), + .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser) +); + +endmodule diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py new file mode 100755 index 000000000..7819e8106 --- /dev/null +++ b/tb/test_axis_adapter_8_64.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue + +import axis_ep + +module = 'axis_adapter' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s_8_64.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_adapter_8_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tkeep=input_axis_tkeep, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tkeep = Signal(intbv(0)[1:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[64:]) + output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tkeep=input_axis_tkeep, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_adapter_8_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + test_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_adapter_8_64.v b/tb/test_axis_adapter_8_64.v new file mode 100644 index 000000000..e27187a4d --- /dev/null +++ b/tb/test_axis_adapter_8_64.v @@ -0,0 +1,105 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_adapter_8_64; + +// parameters +localparam INPUT_DATA_WIDTH = 8; +localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); +localparam OUTPUT_DATA_WIDTH = 64; +localparam OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata; +wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_adapter_8_64.lxt"); + $dumpvars(0, test_axis_adapter_8_64); +end + +axis_adapter #( + .INPUT_DATA_WIDTH(INPUT_DATA_WIDTH), + .INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH), + .OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH), + .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser) +); + +endmodule From e0c2f44dc27cae996810ef8f51f93dc7240fe551 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Oct 2014 15:04:36 -0700 Subject: [PATCH 042/617] Initial commit of AXI stream width adapter --- rtl/axis_adapter.v | 425 +++++++++++++++++++++++++++++++++++ tb/test_axis_adapter_64_8.py | 318 ++++++++++++++++++++++++++ tb/test_axis_adapter_64_8.v | 105 +++++++++ tb/test_axis_adapter_8_64.py | 318 ++++++++++++++++++++++++++ tb/test_axis_adapter_8_64.v | 105 +++++++++ 5 files changed, 1271 insertions(+) create mode 100644 rtl/axis_adapter.v create mode 100755 tb/test_axis_adapter_64_8.py create mode 100644 tb/test_axis_adapter_64_8.v create mode 100755 tb/test_axis_adapter_8_64.py create mode 100644 tb/test_axis_adapter_8_64.v diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v new file mode 100644 index 000000000..9fe64e502 --- /dev/null +++ b/rtl/axis_adapter.v @@ -0,0 +1,425 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream bus width adapter + */ +module axis_adapter # +( + parameter INPUT_DATA_WIDTH = 8, + parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8), + parameter OUTPUT_DATA_WIDTH = 8, + parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [INPUT_DATA_WIDTH-1:0] input_axis_tdata, + input wire [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata, + output wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser +); + +// bus word widths (must be identical) +localparam INPUT_DATA_WORD_WIDTH = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH; +localparam OUTPUT_DATA_WORD_WIDTH = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH; +// output bus is wider +localparam EXPAND_BUS = OUTPUT_KEEP_WIDTH > INPUT_KEEP_WIDTH; +// total data and keep widths +localparam DATA_WIDTH = EXPAND_BUS ? OUTPUT_DATA_WIDTH : INPUT_DATA_WIDTH; +localparam KEEP_WIDTH = EXPAND_BUS ? OUTPUT_KEEP_WIDTH : INPUT_KEEP_WIDTH; +// required number of cycles to match widths +localparam CYCLE_COUNT = EXPAND_BUS ? (OUTPUT_KEEP_WIDTH / INPUT_KEEP_WIDTH) : (INPUT_KEEP_WIDTH / OUTPUT_KEEP_WIDTH); +// data width and keep width per cycle +localparam CYCLE_DATA_WIDTH = DATA_WIDTH / CYCLE_COUNT; +localparam CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT; + +// bus width assertions +initial begin + if (INPUT_DATA_WORD_WIDTH * INPUT_KEEP_WIDTH != INPUT_DATA_WIDTH) begin + $error("Error: input data width not evenly divisble"); + $finish; + end + + if (OUTPUT_DATA_WORD_WIDTH * OUTPUT_KEEP_WIDTH != OUTPUT_DATA_WIDTH) begin + $error("Error: output data width not evenly divisble"); + $finish; + end + + if (INPUT_DATA_WORD_WIDTH != OUTPUT_DATA_WORD_WIDTH) begin + $error("Error: word width mismatch"); + $finish; + end +end + +// state register +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_TRANSFER_IN = 3'd1, + STATE_TRANSFER_OUT = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +reg [7:0] cycle_count_reg = 0, cycle_count_next; + +reg [DATA_WIDTH-1:0] temp_tdata_reg = 0, temp_tdata_next; +reg [KEEP_WIDTH-1:0] temp_tkeep_reg = 0, temp_tkeep_next; +reg temp_tlast_reg = 0, temp_tlast_next; +reg temp_tuser_reg = 0, temp_tuser_next; + +// internal datapath +reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_int; +reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +always @* begin + state_next = 3'bz; + + cycle_count_next = cycle_count_reg; + + temp_tdata_next = temp_tdata_reg; + temp_tkeep_next = temp_tkeep_reg; + temp_tlast_next = temp_tlast_reg; + temp_tuser_next = temp_tuser_reg; + + output_axis_tdata_int = 0; + output_axis_tkeep_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + input_axis_tready_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - no data in registers + if (CYCLE_COUNT == 1) begin + // output and input same width - just act like a register + + // accept data next cycle if output register ready next cycle + input_axis_tready_next = output_axis_tready_int_early; + + // transfer through + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = input_axis_tvalid; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; + + state_next = STATE_IDLE; + end else if (EXPAND_BUS) begin + // output bus is wider + + // accept new data + input_axis_tready_next = 1; + + if (input_axis_tvalid) begin + // word transfer in - store it in data register + + // pass complete input word, zero-extended to temp register + temp_tdata_next = input_axis_tdata; + temp_tkeep_next = input_axis_tkeep; + temp_tlast_next = input_axis_tlast; + temp_tuser_next = input_axis_tuser; + + // first input cycle complete + cycle_count_next = 1; + + if (input_axis_tlast) begin + // got last signal on first cycle, so output it + input_axis_tready_next = 0; + state_next = STATE_TRANSFER_OUT; + end else begin + // otherwise, transfer in the rest of the words + input_axis_tready_next = 1; + state_next = STATE_TRANSFER_IN; + end + end else begin + state_next = STATE_IDLE; + end + end else begin + // output bus is narrower + + // accept new data + input_axis_tready_next = 1; + + if (input_axis_tvalid) begin + // word transfer in - store it in data register + cycle_count_next = 0; + + // pass complete input word, zero-extended to temp register + temp_tdata_next = input_axis_tdata; + temp_tkeep_next = input_axis_tkeep; + temp_tlast_next = input_axis_tlast; + temp_tuser_next = input_axis_tuser; + + // short-circuit and get first word out the door + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = 1; + output_axis_tlast_int = input_axis_tlast & ((CYCLE_COUNT == 1) | (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}})); + output_axis_tuser_int = input_axis_tuser & ((CYCLE_COUNT == 1) | (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}})); + + if (output_axis_tready_int) begin + // if output register is ready for first word, then move on to the next one + cycle_count_next = 1; + end + + // continue outputting words + input_axis_tready_next = 0; + state_next = STATE_TRANSFER_OUT; + end else begin + state_next = STATE_IDLE; + end + end + end + STATE_TRANSFER_IN: begin + // transfer word to temp registers + // only used when output is wider + + // accept new data + input_axis_tready_next = 1; + + if (input_axis_tvalid) begin + // word transfer in - store in data register + + temp_tdata_next[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH] = input_axis_tdata; + temp_tkeep_next[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] = input_axis_tkeep; + temp_tlast_next = input_axis_tlast; + temp_tuser_next = input_axis_tuser; + + cycle_count_next = cycle_count_reg + 1; + + if ((cycle_count_reg == CYCLE_COUNT-1) | input_axis_tlast) begin + // terminated by counter or tlast signal, output complete word + // read input word next cycle if output will be ready + input_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_TRANSFER_OUT; + end else begin + // more words to read + input_axis_tready_next = 1; + state_next = STATE_TRANSFER_IN; + end + end else begin + state_next = STATE_TRANSFER_IN; + end + end + STATE_TRANSFER_OUT: begin + // transfer word to output registers + + if (EXPAND_BUS) begin + // output bus is wider + + // do not accept new data + input_axis_tready_next = 0; + + // single-cycle output of entire stored word (output wider) + output_axis_tdata_int = temp_tdata_reg; + output_axis_tkeep_int = temp_tkeep_reg; + output_axis_tvalid_int = 1; + output_axis_tlast_int = temp_tlast_reg; + output_axis_tuser_int = temp_tuser_reg; + + if (output_axis_tready_int) begin + // word transfer out + + if (input_axis_tready & input_axis_tvalid) begin + // word transfer in + + // pass complete input word, zero-extended to temp register + temp_tdata_next = input_axis_tdata; + temp_tkeep_next = input_axis_tkeep; + temp_tlast_next = input_axis_tlast; + temp_tuser_next = input_axis_tuser; + + // first input cycle complete + cycle_count_next = 1; + + if (input_axis_tlast) begin + // got last signal on first cycle, so output it + input_axis_tready_next = 0; + state_next = STATE_TRANSFER_OUT; + end else begin + // otherwise, transfer in the rest of the words + input_axis_tready_next = 1; + state_next = STATE_TRANSFER_IN; + end + end else begin + input_axis_tready_next = 1; + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_TRANSFER_OUT; + end + end else begin + // output bus is narrower + + // do not accept new data + input_axis_tready_next = 0; + + // output current part of stored word (output narrower) + output_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH]; + output_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH]; + output_axis_tvalid_int = 1; + output_axis_tlast_int = temp_tlast_reg & ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})); + output_axis_tuser_int = temp_tuser_reg & ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})); + + if (output_axis_tready_int) begin + // word transfer out + + cycle_count_next = cycle_count_reg + 1; + + if ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})) begin + // terminated by counter or tlast signal + + input_axis_tready_next = 1; + state_next = STATE_IDLE; + end else begin + // more words to write + state_next = STATE_TRANSFER_OUT; + end + end else begin + state_next = STATE_TRANSFER_OUT; + end + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + cycle_count_reg <= 0; + temp_tdata_reg <= 0; + temp_tkeep_reg <= 0; + temp_tlast_reg <= 0; + temp_tuser_reg <= 0; + input_axis_tready_reg <= 0; + end else begin + state_reg <= state_next; + + input_axis_tready_reg <= input_axis_tready_next; + + temp_tdata_reg <= temp_tdata_next; + temp_tkeep_reg <= temp_tkeep_next; + temp_tlast_reg <= temp_tlast_next; + temp_tuser_reg <= temp_tuser_next; + + cycle_count_reg <= cycle_count_next; + end +end + +// output datapath logic +reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py new file mode 100755 index 000000000..a5333dad2 --- /dev/null +++ b/tb/test_axis_adapter_64_8.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue + +import axis_ep + +module = 'axis_adapter' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s_64_8.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_adapter_64_8(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tkeep=input_axis_tkeep, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[64:]) + input_axis_tkeep = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tkeep = Signal(intbv(0)[1:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tkeep=input_axis_tkeep, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_adapter_64_8(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + test_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_adapter_64_8.v b/tb/test_axis_adapter_64_8.v new file mode 100644 index 000000000..be74bbbe5 --- /dev/null +++ b/tb/test_axis_adapter_64_8.v @@ -0,0 +1,105 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_adapter_64_8; + +// parameters +localparam INPUT_DATA_WIDTH = 64; +localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); +localparam OUTPUT_DATA_WIDTH = 8; +localparam OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata; +wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_adapter_64_8.lxt"); + $dumpvars(0, test_axis_adapter_64_8); +end + +axis_adapter #( + .INPUT_DATA_WIDTH(INPUT_DATA_WIDTH), + .INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH), + .OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH), + .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser) +); + +endmodule diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py new file mode 100755 index 000000000..7819e8106 --- /dev/null +++ b/tb/test_axis_adapter_8_64.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue + +import axis_ep + +module = 'axis_adapter' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s_8_64.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_adapter_8_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tkeep=input_axis_tkeep, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tkeep = Signal(intbv(0)[1:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[64:]) + output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tkeep=input_axis_tkeep, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_adapter_8_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len))) + + test_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_adapter_8_64.v b/tb/test_axis_adapter_8_64.v new file mode 100644 index 000000000..e27187a4d --- /dev/null +++ b/tb/test_axis_adapter_8_64.v @@ -0,0 +1,105 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_adapter_8_64; + +// parameters +localparam INPUT_DATA_WIDTH = 8; +localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); +localparam OUTPUT_DATA_WIDTH = 64; +localparam OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata; +wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_adapter_8_64.lxt"); + $dumpvars(0, test_axis_adapter_8_64); +end + +axis_adapter #( + .INPUT_DATA_WIDTH(INPUT_DATA_WIDTH), + .INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH), + .OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH), + .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser) +); + +endmodule From 8bce338bc05ac425fb3919493ced258ad76c01c2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Oct 2014 15:09:07 -0700 Subject: [PATCH 043/617] Initial commit of AXI stream rate limiter --- rtl/axis_rate_limit.v | 182 +++++++++++++++ rtl/axis_rate_limit_64.v | 194 ++++++++++++++++ tb/test_axis_rate_limit.py | 415 +++++++++++++++++++++++++++++++++ tb/test_axis_rate_limit.v | 100 ++++++++ tb/test_axis_rate_limit_64.py | 425 ++++++++++++++++++++++++++++++++++ tb/test_axis_rate_limit_64.v | 106 +++++++++ 6 files changed, 1422 insertions(+) create mode 100644 rtl/axis_rate_limit.v create mode 100644 rtl/axis_rate_limit_64.v create mode 100755 tb/test_axis_rate_limit.py create mode 100644 tb/test_axis_rate_limit.v create mode 100755 tb/test_axis_rate_limit_64.py create mode 100644 tb/test_axis_rate_limit_64.v diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v new file mode 100644 index 000000000..7c7fd9a4b --- /dev/null +++ b/rtl/axis_rate_limit.v @@ -0,0 +1,182 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream rate limiter + */ +module axis_rate_limit # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] input_axis_tdata, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [7:0] rate_num, + input wire [7:0] rate_denom, + input wire rate_by_frame +); + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; + +reg [23:0] acc_reg = 0, acc_next; +reg pause; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +always @* begin + acc_next = acc_reg; + pause = 0; + frame_next = frame_reg & ~input_axis_tlast; + + if (acc_reg >= rate_num) begin + acc_next = acc_reg - rate_num; + end + + if (input_axis_tready & input_axis_tvalid) begin + // read input + frame_next = ~input_axis_tlast; + acc_next = acc_reg + (rate_denom - rate_num); + end + + if (acc_next >= rate_num) begin + if (rate_by_frame) begin + pause = ~frame_next; + end else begin + pause = 1; + end + end + + input_axis_tready_next = output_axis_tready_int_early & ~pause; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + acc_reg <= 0; + frame_reg <= 0; + input_axis_tready_reg <= 0; + end else begin + acc_reg <= acc_next; + frame_reg <= frame_next; + input_axis_tready_reg <= input_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v new file mode 100644 index 000000000..e1918d3b6 --- /dev/null +++ b/rtl/axis_rate_limit_64.v @@ -0,0 +1,194 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream rate limiter (64 bit datapath) + */ +module axis_rate_limit_64 # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] input_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_axis_tkeep, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [7:0] rate_num, + input wire [7:0] rate_denom, + input wire rate_by_frame +); + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; + +reg [23:0] acc_reg = 0, acc_next; +reg pause; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +always @* begin + acc_next = acc_reg; + pause = 0; + frame_next = frame_reg & ~input_axis_tlast; + + if (acc_reg >= rate_num) begin + acc_next = acc_reg - rate_num; + end + + if (input_axis_tready & input_axis_tvalid) begin + // read input + frame_next = ~input_axis_tlast; + acc_next = acc_reg + (rate_denom - rate_num); + end + + if (acc_next >= rate_num) begin + if (rate_by_frame) begin + pause = ~frame_next; + end else begin + pause = 1; + end + end + + input_axis_tready_next = output_axis_tready_int_early & ~pause; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + acc_reg <= 0; + frame_reg <= 0; + input_axis_tready_reg <= 0; + end else begin + acc_reg <= acc_next; + frame_reg <= frame_next; + input_axis_tready_reg <= input_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py new file mode 100755 index 000000000..1f3f38c0a --- /dev/null +++ b/tb/test_axis_rate_limit.py @@ -0,0 +1,415 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue + +import axis_ep + +module = 'axis_rate_limit' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_rate_limit(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + rate_num, + rate_denom, + rate_by_frame): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + rate_num=rate_num, + rate_denom=rate_denom, + rate_by_frame=rate_by_frame) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + rate_num = Signal(intbv(0)[8:]) + rate_denom = Signal(intbv(0)[8:]) + rate_by_frame = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_rate_limit(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + rate_num, + rate_denom, + rate_by_frame) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + rate_num.next = 1 + rate_denom.next = 10 + rate_by_frame.next = 1 + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_rate_limit.v b/tb/test_axis_rate_limit.v new file mode 100644 index 000000000..a03f8f83a --- /dev/null +++ b/tb/test_axis_rate_limit.v @@ -0,0 +1,100 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_rate_limit; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_axis_tdata = 8'd0; +reg input_axis_tvalid = 1'b0; +reg input_axis_tlast = 1'b0; +reg input_axis_tuser = 1'b0; +reg output_axis_tready = 1'b0; +reg [7:0] rate_num = 0; +reg [7:0] rate_denom = 0; +reg rate_by_frame = 0; + +// Outputs +wire input_axis_tready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready, + rate_num, + rate_denom, + rate_by_frame); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_rate_limit.lxt"); + $dumpvars(0, test_axis_rate_limit); +end + +axis_rate_limit #( + .DATA_WIDTH(8) +) +UUT ( + .clk(clk), + .rst(rst), + // axi input + .input_axis_tdata(input_axis_tdata), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // axi output + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // configuration + .rate_num(rate_num), + .rate_denom(rate_denom), + .rate_by_frame(rate_by_frame) +); + +endmodule diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py new file mode 100755 index 000000000..6531032c8 --- /dev/null +++ b/tb/test_axis_rate_limit_64.py @@ -0,0 +1,425 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue + +import axis_ep + +module = 'axis_rate_limit_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_rate_limit_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + rate_num, + rate_denom, + rate_by_frame): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tkeep=input_axis_tkeep, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + rate_num=rate_num, + rate_denom=rate_denom, + rate_by_frame=rate_by_frame) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[64:]) + input_axis_tkeep = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + rate_num = Signal(intbv(0)[8:]) + rate_denom = Signal(intbv(0)[8:]) + rate_by_frame = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[64:]) + output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tkeep=input_axis_tkeep, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_rate_limit_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + rate_num, + rate_denom, + rate_by_frame) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + rate_num.next = 1 + rate_denom.next = 10 + rate_by_frame.next = 1 + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_rate_limit_64.v b/tb/test_axis_rate_limit_64.v new file mode 100644 index 000000000..71644a0da --- /dev/null +++ b/tb/test_axis_rate_limit_64.v @@ -0,0 +1,106 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_rate_limit_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] input_axis_tdata = 8'd0; +reg [7:0] input_axis_tkeep = 8'd0; +reg input_axis_tvalid = 1'b0; +reg input_axis_tlast = 1'b0; +reg input_axis_tuser = 1'b0; +reg output_axis_tready = 1'b0; +reg [7:0] rate_num = 0; +reg [7:0] rate_denom = 0; +reg rate_by_frame = 0; + +// Outputs +wire input_axis_tready; +wire [63:0] output_axis_tdata; +wire [7:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready, + rate_num, + rate_denom, + rate_by_frame); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_rate_limit_64.lxt"); + $dumpvars(0, test_axis_rate_limit_64); +end + +axis_rate_limit_64 #( + .DATA_WIDTH(64) +) +UUT ( + .clk(clk), + .rst(rst), + // axi input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // axi output + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // configuration + .rate_num(rate_num), + .rate_denom(rate_denom), + .rate_by_frame(rate_by_frame) +); + +endmodule From 377ef5accb320eefb1d54673e1566ce8ce3c5fde Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Oct 2014 15:09:07 -0700 Subject: [PATCH 044/617] Initial commit of AXI stream rate limiter --- rtl/axis_rate_limit.v | 182 +++++++++++++++ rtl/axis_rate_limit_64.v | 194 ++++++++++++++++ tb/test_axis_rate_limit.py | 415 +++++++++++++++++++++++++++++++++ tb/test_axis_rate_limit.v | 100 ++++++++ tb/test_axis_rate_limit_64.py | 425 ++++++++++++++++++++++++++++++++++ tb/test_axis_rate_limit_64.v | 106 +++++++++ 6 files changed, 1422 insertions(+) create mode 100644 rtl/axis_rate_limit.v create mode 100644 rtl/axis_rate_limit_64.v create mode 100755 tb/test_axis_rate_limit.py create mode 100644 tb/test_axis_rate_limit.v create mode 100755 tb/test_axis_rate_limit_64.py create mode 100644 tb/test_axis_rate_limit_64.v diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v new file mode 100644 index 000000000..7c7fd9a4b --- /dev/null +++ b/rtl/axis_rate_limit.v @@ -0,0 +1,182 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream rate limiter + */ +module axis_rate_limit # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] input_axis_tdata, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [7:0] rate_num, + input wire [7:0] rate_denom, + input wire rate_by_frame +); + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; + +reg [23:0] acc_reg = 0, acc_next; +reg pause; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +always @* begin + acc_next = acc_reg; + pause = 0; + frame_next = frame_reg & ~input_axis_tlast; + + if (acc_reg >= rate_num) begin + acc_next = acc_reg - rate_num; + end + + if (input_axis_tready & input_axis_tvalid) begin + // read input + frame_next = ~input_axis_tlast; + acc_next = acc_reg + (rate_denom - rate_num); + end + + if (acc_next >= rate_num) begin + if (rate_by_frame) begin + pause = ~frame_next; + end else begin + pause = 1; + end + end + + input_axis_tready_next = output_axis_tready_int_early & ~pause; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + acc_reg <= 0; + frame_reg <= 0; + input_axis_tready_reg <= 0; + end else begin + acc_reg <= acc_next; + frame_reg <= frame_next; + input_axis_tready_reg <= input_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v new file mode 100644 index 000000000..e1918d3b6 --- /dev/null +++ b/rtl/axis_rate_limit_64.v @@ -0,0 +1,194 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream rate limiter (64 bit datapath) + */ +module axis_rate_limit_64 # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] input_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_axis_tkeep, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [7:0] rate_num, + input wire [7:0] rate_denom, + input wire rate_by_frame +); + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; + +reg [23:0] acc_reg = 0, acc_next; +reg pause; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +always @* begin + acc_next = acc_reg; + pause = 0; + frame_next = frame_reg & ~input_axis_tlast; + + if (acc_reg >= rate_num) begin + acc_next = acc_reg - rate_num; + end + + if (input_axis_tready & input_axis_tvalid) begin + // read input + frame_next = ~input_axis_tlast; + acc_next = acc_reg + (rate_denom - rate_num); + end + + if (acc_next >= rate_num) begin + if (rate_by_frame) begin + pause = ~frame_next; + end else begin + pause = 1; + end + end + + input_axis_tready_next = output_axis_tready_int_early & ~pause; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + acc_reg <= 0; + frame_reg <= 0; + input_axis_tready_reg <= 0; + end else begin + acc_reg <= acc_next; + frame_reg <= frame_next; + input_axis_tready_reg <= input_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py new file mode 100755 index 000000000..1f3f38c0a --- /dev/null +++ b/tb/test_axis_rate_limit.py @@ -0,0 +1,415 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue + +import axis_ep + +module = 'axis_rate_limit' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_rate_limit(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + rate_num, + rate_denom, + rate_by_frame): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + rate_num=rate_num, + rate_denom=rate_denom, + rate_by_frame=rate_by_frame) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + rate_num = Signal(intbv(0)[8:]) + rate_denom = Signal(intbv(0)[8:]) + rate_by_frame = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_rate_limit(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + rate_num, + rate_denom, + rate_by_frame) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + rate_num.next = 1 + rate_denom.next = 10 + rate_by_frame.next = 1 + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_rate_limit.v b/tb/test_axis_rate_limit.v new file mode 100644 index 000000000..a03f8f83a --- /dev/null +++ b/tb/test_axis_rate_limit.v @@ -0,0 +1,100 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_rate_limit; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_axis_tdata = 8'd0; +reg input_axis_tvalid = 1'b0; +reg input_axis_tlast = 1'b0; +reg input_axis_tuser = 1'b0; +reg output_axis_tready = 1'b0; +reg [7:0] rate_num = 0; +reg [7:0] rate_denom = 0; +reg rate_by_frame = 0; + +// Outputs +wire input_axis_tready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready, + rate_num, + rate_denom, + rate_by_frame); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_rate_limit.lxt"); + $dumpvars(0, test_axis_rate_limit); +end + +axis_rate_limit #( + .DATA_WIDTH(8) +) +UUT ( + .clk(clk), + .rst(rst), + // axi input + .input_axis_tdata(input_axis_tdata), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // axi output + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // configuration + .rate_num(rate_num), + .rate_denom(rate_denom), + .rate_by_frame(rate_by_frame) +); + +endmodule diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py new file mode 100755 index 000000000..6531032c8 --- /dev/null +++ b/tb/test_axis_rate_limit_64.py @@ -0,0 +1,425 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue + +import axis_ep + +module = 'axis_rate_limit_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_rate_limit_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + rate_num, + rate_denom, + rate_by_frame): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tkeep=input_axis_tkeep, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + rate_num=rate_num, + rate_denom=rate_denom, + rate_by_frame=rate_by_frame) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[64:]) + input_axis_tkeep = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + rate_num = Signal(intbv(0)[8:]) + rate_denom = Signal(intbv(0)[8:]) + rate_by_frame = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[64:]) + output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tkeep=input_axis_tkeep, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_rate_limit_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + rate_num, + rate_denom, + rate_by_frame) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + rate_num.next = 1 + rate_denom.next = 10 + rate_by_frame.next = 1 + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_rate_limit_64.v b/tb/test_axis_rate_limit_64.v new file mode 100644 index 000000000..71644a0da --- /dev/null +++ b/tb/test_axis_rate_limit_64.v @@ -0,0 +1,106 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_rate_limit_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] input_axis_tdata = 8'd0; +reg [7:0] input_axis_tkeep = 8'd0; +reg input_axis_tvalid = 1'b0; +reg input_axis_tlast = 1'b0; +reg input_axis_tuser = 1'b0; +reg output_axis_tready = 1'b0; +reg [7:0] rate_num = 0; +reg [7:0] rate_denom = 0; +reg rate_by_frame = 0; + +// Outputs +wire input_axis_tready; +wire [63:0] output_axis_tdata; +wire [7:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready, + rate_num, + rate_denom, + rate_by_frame); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_rate_limit_64.lxt"); + $dumpvars(0, test_axis_rate_limit_64); +end + +axis_rate_limit_64 #( + .DATA_WIDTH(64) +) +UUT ( + .clk(clk), + .rst(rst), + // axi input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // axi output + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // configuration + .rate_num(rate_num), + .rate_denom(rate_denom), + .rate_by_frame(rate_by_frame) +); + +endmodule From 8e9b38cde019300715e10cc3bc8f718c6ea44180 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Oct 2014 13:20:37 -0700 Subject: [PATCH 045/617] Initial commit of basic statistics collection module --- rtl/axis_stat_counter.v | 299 +++++++++++++ tb/test_axis_stat_counter.py | 788 +++++++++++++++++++++++++++++++++++ tb/test_axis_stat_counter.v | 98 +++++ 3 files changed, 1185 insertions(+) create mode 100644 rtl/axis_stat_counter.v create mode 100755 tb/test_axis_stat_counter.py create mode 100644 tb/test_axis_stat_counter.v diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v new file mode 100644 index 000000000..083b912c9 --- /dev/null +++ b/rtl/axis_stat_counter.v @@ -0,0 +1,299 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream statistics counter + */ +module axis_stat_counter # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI monitor + */ + input wire [KEEP_WIDTH-1:0] monitor_axis_tkeep, + input wire monitor_axis_tvalid, + input wire monitor_axis_tready, + input wire monitor_axis_tlast, + + /* + * AXI status data output + */ + output wire [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [15:0] tag, + input wire trigger +); + +// state register +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_OUTPUT_DATA = 2'd1; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [31:0] tick_count_reg = 0, tick_count_next; +reg [31:0] byte_count_reg = 0, byte_count_next; +reg [31:0] frame_count_reg = 0, frame_count_next; +reg frame_reg = 0, frame_next; + +reg store_output; +reg [5:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [31:0] tick_count_output_reg = 0; +reg [31:0] byte_count_output_reg = 0; +reg [31:0] frame_count_output_reg = 0; + +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; + +function [3:0] keep2count; + input [7:0] k; + case (k) + 8'b00000000: keep2count = 0; + 8'b00000001: keep2count = 1; + 8'b00000011: keep2count = 2; + 8'b00000111: keep2count = 3; + 8'b00001111: keep2count = 4; + 8'b00011111: keep2count = 5; + 8'b00111111: keep2count = 6; + 8'b01111111: keep2count = 7; + 8'b11111111: keep2count = 8; + endcase +endfunction + +function [7:0] count2keep; + input [3:0] k; + case (k) + 4'd0: count2keep = 8'b00000000; + 4'd1: count2keep = 8'b00000001; + 4'd2: count2keep = 8'b00000011; + 4'd3: count2keep = 8'b00000111; + 4'd4: count2keep = 8'b00001111; + 4'd5: count2keep = 8'b00011111; + 4'd6: count2keep = 8'b00111111; + 4'd7: count2keep = 8'b01111111; + 4'd8: count2keep = 8'b11111111; + endcase +endfunction + +always @* begin + state_next = 2'bz; + + tick_count_next = tick_count_reg; + byte_count_next = byte_count_reg; + frame_count_next = frame_count_reg; + frame_next = frame_reg; + + output_axis_tdata_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + store_output = 0; + + frame_ptr_next = frame_ptr_reg; + + // data readout + + case (state_reg) + STATE_IDLE: begin + if (trigger) begin + store_output = 1; + tick_count_next = 0; + byte_count_next = 0; + frame_count_next = 0; + frame_ptr_next = 0; + + if (output_axis_tready_int) begin + frame_ptr_next = 1; + output_axis_tdata_int = tag[15:8]; + output_axis_tvalid_int = 1; + end + + state_next = STATE_OUTPUT_DATA; + end else begin + state_next = STATE_IDLE; + end + end + STATE_OUTPUT_DATA: begin + if (output_axis_tready_int) begin + state_next = STATE_OUTPUT_DATA; + frame_ptr_next = frame_ptr_reg + 1; + output_axis_tvalid_int = 1; + case (frame_ptr_reg) + 5'd00: output_axis_tdata_int = tag[15:8]; + 5'd01: output_axis_tdata_int = tag[7:0]; + 5'd02: output_axis_tdata_int = tick_count_output_reg[31:24]; + 5'd03: output_axis_tdata_int = tick_count_output_reg[23:16]; + 5'd04: output_axis_tdata_int = tick_count_output_reg[15: 8]; + 5'd05: output_axis_tdata_int = tick_count_output_reg[ 7: 0]; + 5'd06: output_axis_tdata_int = byte_count_output_reg[31:24]; + 5'd07: output_axis_tdata_int = byte_count_output_reg[23:16]; + 5'd08: output_axis_tdata_int = byte_count_output_reg[15: 8]; + 5'd09: output_axis_tdata_int = byte_count_output_reg[ 7: 0]; + 5'd10: output_axis_tdata_int = frame_count_output_reg[31:24]; + 5'd11: output_axis_tdata_int = frame_count_output_reg[23:16]; + 5'd12: output_axis_tdata_int = frame_count_output_reg[15: 8]; + 5'd13: begin + output_axis_tdata_int = frame_count_output_reg[ 7: 0]; + output_axis_tlast_int = 1; + state_next = STATE_IDLE; + end + endcase + end else begin + state_next = STATE_OUTPUT_DATA; + end + end + endcase + + // stats collection + + // increment tick count by number of words that can be transferred per cycle + tick_count_next = tick_count_next + KEEP_WIDTH; + + if (monitor_axis_tready & monitor_axis_tvalid) begin + // valid transfer cycle + + // increment byte count by number of words transferred + byte_count_next = byte_count_next + keep2count(monitor_axis_tkeep); + + // count frames + if (monitor_axis_tlast) begin + // end of frame + frame_next = 0; + end else if (~frame_reg) begin + // first word after end of frame + frame_count_next = frame_count_next + 1; + frame_next = 1; + end + end +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + tick_count_reg <= 0; + byte_count_reg <= 0; + frame_count_reg <= 0; + frame_reg <= 0; + frame_ptr_reg <= 0; + tick_count_output_reg <= 0; + byte_count_output_reg <= 0; + frame_count_output_reg <= 0; + end else begin + state_reg <= state_next; + tick_count_reg <= tick_count_next; + byte_count_reg <= byte_count_next; + frame_count_reg <= frame_count_next; + frame_reg <= frame_next; + frame_ptr_reg <= frame_ptr_next; + + if (store_output) begin + tick_count_output_reg <= tick_count_reg; + byte_count_output_reg <= byte_count_reg; + frame_count_output_reg <= frame_count_reg; + end + end +end + +// output datapath logic +reg [7:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py new file mode 100755 index 000000000..a5d83387e --- /dev/null +++ b/tb/test_axis_stat_counter.py @@ -0,0 +1,788 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue +import struct + +import axis_ep + +module = 'axis_stat_counter' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_stat_counter(clk, + rst, + current_test, + + monitor_axis_tdata, + monitor_axis_tkeep, + monitor_axis_tvalid, + monitor_axis_tready, + monitor_axis_tlast, + monitor_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + tag, + trigger): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + monitor_axis_tdata=monitor_axis_tdata, + monitor_axis_tkeep=monitor_axis_tkeep, + monitor_axis_tvalid=monitor_axis_tvalid, + monitor_axis_tready=monitor_axis_tready, + monitor_axis_tlast=monitor_axis_tlast, + monitor_axis_tuser=monitor_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + tag=tag, + trigger=trigger) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + monitor_axis_tdata = Signal(intbv(0)[64:]) + monitor_axis_tkeep = Signal(intbv(0)[8:]) + monitor_axis_tvalid = Signal(bool(0)) + monitor_axis_tready = Signal(bool(0)) + monitor_axis_tlast = Signal(bool(0)) + monitor_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + tag = Signal(intbv(16)[16:]) + trigger = Signal(bool(0)) + + # Outputs + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + monitor_sink_queue = Queue() + monitor_sink_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=monitor_axis_tdata, + tkeep=monitor_axis_tkeep, + tvalid=monitor_axis_tvalid, + tready=monitor_axis_tready, + tlast=monitor_axis_tlast, + tuser=monitor_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + monitor_sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=monitor_axis_tdata, + tkeep=monitor_axis_tkeep, + tvalid=monitor_axis_tvalid, + tready=monitor_axis_tready, + tlast=monitor_axis_tlast, + tuser=monitor_axis_tuser, + fifo=monitor_sink_queue, + pause=monitor_sink_pause, + name='monitor_sink') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_stat_counter(clk, + rst, + current_test, + + monitor_axis_tdata, + monitor_axis_tkeep, + monitor_axis_tvalid, + monitor_axis_tready, + monitor_axis_tlast, + monitor_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + tag, + trigger) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + tag.next = 1 + + yield clk.posedge + print("test 1: test tick timer") + current_test.next = 1 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + for i in range(100-1): + yield clk.posedge + + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[1] == 100*8 + + yield delay(100) + + yield clk.posedge + print("test 2: pause sink") + current_test.next = 2 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + for i in range(100-1): + yield clk.posedge + + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + while trigger or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[1] == 100*8 + + yield delay(100) + + yield clk.posedge + print("test 3: test packet") + current_test.next = 3 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame.data) + assert rx_frame_values[3] == 1 + + yield delay(100) + + yield clk.posedge + print("test 4: longer packet") + current_test.next = 4 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame.data) + assert rx_frame_values[3] == 1 + + yield delay(100) + + yield clk.posedge + print("test 5: test packet with pauses") + current_test.next = 5 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + monitor_sink_pause.next = True + yield delay(32) + yield clk.posedge + monitor_sink_pause.next = False + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame.data) + assert rx_frame_values[3] == 1 + + yield delay(100) + + yield clk.posedge + print("test 6: back-to-back packets") + current_test.next = 6 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data) + assert rx_frame_values[3] == 2 + + yield delay(100) + + yield clk.posedge + print("test 7: alternate pause source") + current_test.next = 7 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data) + assert rx_frame_values[3] == 2 + + yield delay(100) + + yield clk.posedge + print("test 8: alternate pause sink") + current_test.next = 8 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data) + assert rx_frame_values[3] == 2 + + yield delay(100) + + yield clk.posedge + print("test 9: various length packets") + current_test.next = 9 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + lens = [32, 48, 96, 128, 256] + test_frame = [] + + for i in range(len(lens)): + test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i])))) + + for f in test_frame: + source_queue.put(f) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == sum(len(f.data) for f in test_frame) + assert rx_frame_values[3] == len(test_frame) + + yield delay(100) + + yield clk.posedge + print("test 10: various length packets with intermediate trigger") + current_test.next = 10 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + lens = [32, 48, 96, 128, 256] + test_frame = [] + + for i in range(len(lens)): + test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i])))) + + for f in test_frame: + source_queue.put(f) + yield clk.posedge + + yield delay(200) + + yield clk.posedge + trigger_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame2 = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + cycles1 = (trigger_time - start_time) / 8 + print(rx_frame_values) + + rx_frame2_values = struct.unpack(">HLLL", rx_frame2.data) + cycles2 = (stop_time - trigger_time) / 8 + print(rx_frame2_values) + + assert rx_frame_values[0] == 1 + assert rx_frame2_values[0] == 1 + assert rx_frame_values[1] == cycles1*8 + assert rx_frame2_values[1] == cycles2*8 + assert rx_frame_values[1] + rx_frame2_values[1] == cycles*8 + assert rx_frame_values[2] + rx_frame2_values[2] == sum(len(f.data) for f in test_frame) + assert rx_frame_values[3] + rx_frame2_values[3] == len(test_frame) + + yield delay(100) + + raise StopSimulation + + return dut, source, monitor_sink, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v new file mode 100644 index 000000000..11eac0328 --- /dev/null +++ b/tb/test_axis_stat_counter.v @@ -0,0 +1,98 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_stat_counter; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] monitor_axis_tdata = 8'd0; +reg [7:0] monitor_axis_tkeep = 8'd0; +reg monitor_axis_tvalid = 1'b0; +reg monitor_axis_tready = 1'b0; +reg monitor_axis_tlast = 1'b0; +reg monitor_axis_tuser = 1'b0; +reg output_axis_tready = 1'b0; +reg [15:0] tag = 0; +reg trigger = 0; + +// Outputs +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + monitor_axis_tdata, + monitor_axis_tkeep, + monitor_axis_tvalid, + monitor_axis_tready, + monitor_axis_tlast, + monitor_axis_tuser, + output_axis_tready, + tag, + trigger); + $to_myhdl(output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_stat_counter.lxt"); + $dumpvars(0, test_axis_stat_counter); +end + +axis_stat_counter #( + .DATA_WIDTH(64) +) +UUT ( + .clk(clk), + .rst(rst), + // axi monitor input + .monitor_axis_tkeep(monitor_axis_tkeep), + .monitor_axis_tvalid(monitor_axis_tvalid), + .monitor_axis_tready(monitor_axis_tready), + .monitor_axis_tlast(monitor_axis_tlast), + // axi output + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // configuration + .tag(tag), + .trigger(trigger) +); + +endmodule From f22381baa2c5183a2948431e5dd347b69148d39c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Oct 2014 13:20:37 -0700 Subject: [PATCH 046/617] Initial commit of basic statistics collection module --- rtl/axis_stat_counter.v | 299 +++++++++++++ tb/test_axis_stat_counter.py | 788 +++++++++++++++++++++++++++++++++++ tb/test_axis_stat_counter.v | 98 +++++ 3 files changed, 1185 insertions(+) create mode 100644 rtl/axis_stat_counter.v create mode 100755 tb/test_axis_stat_counter.py create mode 100644 tb/test_axis_stat_counter.v diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v new file mode 100644 index 000000000..083b912c9 --- /dev/null +++ b/rtl/axis_stat_counter.v @@ -0,0 +1,299 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream statistics counter + */ +module axis_stat_counter # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI monitor + */ + input wire [KEEP_WIDTH-1:0] monitor_axis_tkeep, + input wire monitor_axis_tvalid, + input wire monitor_axis_tready, + input wire monitor_axis_tlast, + + /* + * AXI status data output + */ + output wire [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [15:0] tag, + input wire trigger +); + +// state register +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_OUTPUT_DATA = 2'd1; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [31:0] tick_count_reg = 0, tick_count_next; +reg [31:0] byte_count_reg = 0, byte_count_next; +reg [31:0] frame_count_reg = 0, frame_count_next; +reg frame_reg = 0, frame_next; + +reg store_output; +reg [5:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [31:0] tick_count_output_reg = 0; +reg [31:0] byte_count_output_reg = 0; +reg [31:0] frame_count_output_reg = 0; + +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; + +function [3:0] keep2count; + input [7:0] k; + case (k) + 8'b00000000: keep2count = 0; + 8'b00000001: keep2count = 1; + 8'b00000011: keep2count = 2; + 8'b00000111: keep2count = 3; + 8'b00001111: keep2count = 4; + 8'b00011111: keep2count = 5; + 8'b00111111: keep2count = 6; + 8'b01111111: keep2count = 7; + 8'b11111111: keep2count = 8; + endcase +endfunction + +function [7:0] count2keep; + input [3:0] k; + case (k) + 4'd0: count2keep = 8'b00000000; + 4'd1: count2keep = 8'b00000001; + 4'd2: count2keep = 8'b00000011; + 4'd3: count2keep = 8'b00000111; + 4'd4: count2keep = 8'b00001111; + 4'd5: count2keep = 8'b00011111; + 4'd6: count2keep = 8'b00111111; + 4'd7: count2keep = 8'b01111111; + 4'd8: count2keep = 8'b11111111; + endcase +endfunction + +always @* begin + state_next = 2'bz; + + tick_count_next = tick_count_reg; + byte_count_next = byte_count_reg; + frame_count_next = frame_count_reg; + frame_next = frame_reg; + + output_axis_tdata_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + store_output = 0; + + frame_ptr_next = frame_ptr_reg; + + // data readout + + case (state_reg) + STATE_IDLE: begin + if (trigger) begin + store_output = 1; + tick_count_next = 0; + byte_count_next = 0; + frame_count_next = 0; + frame_ptr_next = 0; + + if (output_axis_tready_int) begin + frame_ptr_next = 1; + output_axis_tdata_int = tag[15:8]; + output_axis_tvalid_int = 1; + end + + state_next = STATE_OUTPUT_DATA; + end else begin + state_next = STATE_IDLE; + end + end + STATE_OUTPUT_DATA: begin + if (output_axis_tready_int) begin + state_next = STATE_OUTPUT_DATA; + frame_ptr_next = frame_ptr_reg + 1; + output_axis_tvalid_int = 1; + case (frame_ptr_reg) + 5'd00: output_axis_tdata_int = tag[15:8]; + 5'd01: output_axis_tdata_int = tag[7:0]; + 5'd02: output_axis_tdata_int = tick_count_output_reg[31:24]; + 5'd03: output_axis_tdata_int = tick_count_output_reg[23:16]; + 5'd04: output_axis_tdata_int = tick_count_output_reg[15: 8]; + 5'd05: output_axis_tdata_int = tick_count_output_reg[ 7: 0]; + 5'd06: output_axis_tdata_int = byte_count_output_reg[31:24]; + 5'd07: output_axis_tdata_int = byte_count_output_reg[23:16]; + 5'd08: output_axis_tdata_int = byte_count_output_reg[15: 8]; + 5'd09: output_axis_tdata_int = byte_count_output_reg[ 7: 0]; + 5'd10: output_axis_tdata_int = frame_count_output_reg[31:24]; + 5'd11: output_axis_tdata_int = frame_count_output_reg[23:16]; + 5'd12: output_axis_tdata_int = frame_count_output_reg[15: 8]; + 5'd13: begin + output_axis_tdata_int = frame_count_output_reg[ 7: 0]; + output_axis_tlast_int = 1; + state_next = STATE_IDLE; + end + endcase + end else begin + state_next = STATE_OUTPUT_DATA; + end + end + endcase + + // stats collection + + // increment tick count by number of words that can be transferred per cycle + tick_count_next = tick_count_next + KEEP_WIDTH; + + if (monitor_axis_tready & monitor_axis_tvalid) begin + // valid transfer cycle + + // increment byte count by number of words transferred + byte_count_next = byte_count_next + keep2count(monitor_axis_tkeep); + + // count frames + if (monitor_axis_tlast) begin + // end of frame + frame_next = 0; + end else if (~frame_reg) begin + // first word after end of frame + frame_count_next = frame_count_next + 1; + frame_next = 1; + end + end +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + tick_count_reg <= 0; + byte_count_reg <= 0; + frame_count_reg <= 0; + frame_reg <= 0; + frame_ptr_reg <= 0; + tick_count_output_reg <= 0; + byte_count_output_reg <= 0; + frame_count_output_reg <= 0; + end else begin + state_reg <= state_next; + tick_count_reg <= tick_count_next; + byte_count_reg <= byte_count_next; + frame_count_reg <= frame_count_next; + frame_reg <= frame_next; + frame_ptr_reg <= frame_ptr_next; + + if (store_output) begin + tick_count_output_reg <= tick_count_reg; + byte_count_output_reg <= byte_count_reg; + frame_count_output_reg <= frame_count_reg; + end + end +end + +// output datapath logic +reg [7:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py new file mode 100755 index 000000000..a5d83387e --- /dev/null +++ b/tb/test_axis_stat_counter.py @@ -0,0 +1,788 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue +import struct + +import axis_ep + +module = 'axis_stat_counter' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_stat_counter(clk, + rst, + current_test, + + monitor_axis_tdata, + monitor_axis_tkeep, + monitor_axis_tvalid, + monitor_axis_tready, + monitor_axis_tlast, + monitor_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + tag, + trigger): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + monitor_axis_tdata=monitor_axis_tdata, + monitor_axis_tkeep=monitor_axis_tkeep, + monitor_axis_tvalid=monitor_axis_tvalid, + monitor_axis_tready=monitor_axis_tready, + monitor_axis_tlast=monitor_axis_tlast, + monitor_axis_tuser=monitor_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + tag=tag, + trigger=trigger) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + monitor_axis_tdata = Signal(intbv(0)[64:]) + monitor_axis_tkeep = Signal(intbv(0)[8:]) + monitor_axis_tvalid = Signal(bool(0)) + monitor_axis_tready = Signal(bool(0)) + monitor_axis_tlast = Signal(bool(0)) + monitor_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + tag = Signal(intbv(16)[16:]) + trigger = Signal(bool(0)) + + # Outputs + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + monitor_sink_queue = Queue() + monitor_sink_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=monitor_axis_tdata, + tkeep=monitor_axis_tkeep, + tvalid=monitor_axis_tvalid, + tready=monitor_axis_tready, + tlast=monitor_axis_tlast, + tuser=monitor_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + monitor_sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=monitor_axis_tdata, + tkeep=monitor_axis_tkeep, + tvalid=monitor_axis_tvalid, + tready=monitor_axis_tready, + tlast=monitor_axis_tlast, + tuser=monitor_axis_tuser, + fifo=monitor_sink_queue, + pause=monitor_sink_pause, + name='monitor_sink') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_stat_counter(clk, + rst, + current_test, + + monitor_axis_tdata, + monitor_axis_tkeep, + monitor_axis_tvalid, + monitor_axis_tready, + monitor_axis_tlast, + monitor_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + tag, + trigger) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + tag.next = 1 + + yield clk.posedge + print("test 1: test tick timer") + current_test.next = 1 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + for i in range(100-1): + yield clk.posedge + + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[1] == 100*8 + + yield delay(100) + + yield clk.posedge + print("test 2: pause sink") + current_test.next = 2 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + for i in range(100-1): + yield clk.posedge + + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + while trigger or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[1] == 100*8 + + yield delay(100) + + yield clk.posedge + print("test 3: test packet") + current_test.next = 3 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame.data) + assert rx_frame_values[3] == 1 + + yield delay(100) + + yield clk.posedge + print("test 4: longer packet") + current_test.next = 4 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame.data) + assert rx_frame_values[3] == 1 + + yield delay(100) + + yield clk.posedge + print("test 5: test packet with pauses") + current_test.next = 5 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + monitor_sink_pause.next = True + yield delay(32) + yield clk.posedge + monitor_sink_pause.next = False + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame.data) + assert rx_frame_values[3] == 1 + + yield delay(100) + + yield clk.posedge + print("test 6: back-to-back packets") + current_test.next = 6 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data) + assert rx_frame_values[3] == 2 + + yield delay(100) + + yield clk.posedge + print("test 7: alternate pause source") + current_test.next = 7 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data) + assert rx_frame_values[3] == 2 + + yield delay(100) + + yield clk.posedge + print("test 8: alternate pause sink") + current_test.next = 8 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data) + assert rx_frame_values[3] == 2 + + yield delay(100) + + yield clk.posedge + print("test 9: various length packets") + current_test.next = 9 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + lens = [32, 48, 96, 128, 256] + test_frame = [] + + for i in range(len(lens)): + test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i])))) + + for f in test_frame: + source_queue.put(f) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + print(rx_frame_values) + + assert rx_frame_values[0] == 1 + assert rx_frame_values[1] == cycles*8 + assert rx_frame_values[2] == sum(len(f.data) for f in test_frame) + assert rx_frame_values[3] == len(test_frame) + + yield delay(100) + + yield clk.posedge + print("test 10: various length packets with intermediate trigger") + current_test.next = 10 + + yield clk.posedge + start_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + + lens = [32, 48, 96, 128, 256] + test_frame = [] + + for i in range(len(lens)): + test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i])))) + + for f in test_frame: + source_queue.put(f) + yield clk.posedge + + yield delay(200) + + yield clk.posedge + trigger_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + stop_time = now() + trigger.next = 1 + yield clk.posedge + trigger.next = 0 + yield clk.posedge + + while output_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + # discard first trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # check second trigger output + if not sink_queue.empty(): + rx_frame2 = sink_queue.get() + + rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + cycles = (stop_time - start_time) / 8 + cycles1 = (trigger_time - start_time) / 8 + print(rx_frame_values) + + rx_frame2_values = struct.unpack(">HLLL", rx_frame2.data) + cycles2 = (stop_time - trigger_time) / 8 + print(rx_frame2_values) + + assert rx_frame_values[0] == 1 + assert rx_frame2_values[0] == 1 + assert rx_frame_values[1] == cycles1*8 + assert rx_frame2_values[1] == cycles2*8 + assert rx_frame_values[1] + rx_frame2_values[1] == cycles*8 + assert rx_frame_values[2] + rx_frame2_values[2] == sum(len(f.data) for f in test_frame) + assert rx_frame_values[3] + rx_frame2_values[3] == len(test_frame) + + yield delay(100) + + raise StopSimulation + + return dut, source, monitor_sink, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v new file mode 100644 index 000000000..11eac0328 --- /dev/null +++ b/tb/test_axis_stat_counter.v @@ -0,0 +1,98 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_stat_counter; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] monitor_axis_tdata = 8'd0; +reg [7:0] monitor_axis_tkeep = 8'd0; +reg monitor_axis_tvalid = 1'b0; +reg monitor_axis_tready = 1'b0; +reg monitor_axis_tlast = 1'b0; +reg monitor_axis_tuser = 1'b0; +reg output_axis_tready = 1'b0; +reg [15:0] tag = 0; +reg trigger = 0; + +// Outputs +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + monitor_axis_tdata, + monitor_axis_tkeep, + monitor_axis_tvalid, + monitor_axis_tready, + monitor_axis_tlast, + monitor_axis_tuser, + output_axis_tready, + tag, + trigger); + $to_myhdl(output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_stat_counter.lxt"); + $dumpvars(0, test_axis_stat_counter); +end + +axis_stat_counter #( + .DATA_WIDTH(64) +) +UUT ( + .clk(clk), + .rst(rst), + // axi monitor input + .monitor_axis_tkeep(monitor_axis_tkeep), + .monitor_axis_tvalid(monitor_axis_tvalid), + .monitor_axis_tready(monitor_axis_tready), + .monitor_axis_tlast(monitor_axis_tlast), + // axi output + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // configuration + .tag(tag), + .trigger(trigger) +); + +endmodule From 09d0d879394c444733d95ae47b000483d01aea63 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Oct 2014 16:09:55 -0700 Subject: [PATCH 047/617] Add busy output to statistics collection module --- rtl/axis_stat_counter.v | 14 +++++++++++++- tb/test_axis_stat_counter.py | 10 +++++++--- tb/test_axis_stat_counter.v | 8 ++++++-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index 083b912c9..0baf74527 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -59,7 +59,12 @@ module axis_stat_counter # * Configuration */ input wire [15:0] tag, - input wire trigger + input wire trigger, + + /* + * Status + */ + output wire busy ); // state register @@ -81,6 +86,8 @@ reg [31:0] tick_count_output_reg = 0; reg [31:0] byte_count_output_reg = 0; reg [31:0] frame_count_output_reg = 0; +reg busy_reg = 0; + // internal datapath reg [7:0] output_axis_tdata_int; reg output_axis_tvalid_int; @@ -89,6 +96,8 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early = output_axis_tready; +assign busy = busy_reg; + function [3:0] keep2count; input [7:0] k; case (k) @@ -220,6 +229,7 @@ always @(posedge clk or posedge rst) begin frame_count_reg <= 0; frame_reg <= 0; frame_ptr_reg <= 0; + busy_reg <= 0; tick_count_output_reg <= 0; byte_count_output_reg <= 0; frame_count_output_reg <= 0; @@ -231,6 +241,8 @@ always @(posedge clk or posedge rst) begin frame_reg <= frame_next; frame_ptr_reg <= frame_ptr_next; + busy_reg <= state_next != STATE_IDLE; + if (store_output) begin tick_count_output_reg <= tick_count_reg; byte_count_output_reg <= byte_count_reg; diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index a5d83387e..04cc90c89 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -59,7 +59,8 @@ def dut_axis_stat_counter(clk, output_axis_tuser, tag, - trigger): + trigger, + busy): if os.system(build_cmd): raise Exception("Error running build command") @@ -82,7 +83,8 @@ def dut_axis_stat_counter(clk, output_axis_tuser=output_axis_tuser, tag=tag, - trigger=trigger) + trigger=trigger, + busy=busy) def bench(): @@ -107,6 +109,7 @@ def bench(): output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) + busy = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -170,7 +173,8 @@ def bench(): output_axis_tuser, tag, - trigger) + trigger, + busy) @always(delay(4)) def clkgen(): diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v index 11eac0328..529495195 100644 --- a/tb/test_axis_stat_counter.v +++ b/tb/test_axis_stat_counter.v @@ -48,6 +48,7 @@ wire [7:0] output_axis_tdata; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; +wire busy; initial begin // myhdl integration @@ -66,7 +67,8 @@ initial begin $to_myhdl(output_axis_tdata, output_axis_tvalid, output_axis_tlast, - output_axis_tuser); + output_axis_tuser, + busy); // dump file $dumpfile("test_axis_stat_counter.lxt"); @@ -92,7 +94,9 @@ UUT ( .output_axis_tuser(output_axis_tuser), // configuration .tag(tag), - .trigger(trigger) + .trigger(trigger), + // status + .busy(busy) ); endmodule From 67bb09ba42ba55e8f0ae51b922f5026c63163412 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Oct 2014 16:09:55 -0700 Subject: [PATCH 048/617] Add busy output to statistics collection module --- rtl/axis_stat_counter.v | 14 +++++++++++++- tb/test_axis_stat_counter.py | 10 +++++++--- tb/test_axis_stat_counter.v | 8 ++++++-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index 083b912c9..0baf74527 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -59,7 +59,12 @@ module axis_stat_counter # * Configuration */ input wire [15:0] tag, - input wire trigger + input wire trigger, + + /* + * Status + */ + output wire busy ); // state register @@ -81,6 +86,8 @@ reg [31:0] tick_count_output_reg = 0; reg [31:0] byte_count_output_reg = 0; reg [31:0] frame_count_output_reg = 0; +reg busy_reg = 0; + // internal datapath reg [7:0] output_axis_tdata_int; reg output_axis_tvalid_int; @@ -89,6 +96,8 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early = output_axis_tready; +assign busy = busy_reg; + function [3:0] keep2count; input [7:0] k; case (k) @@ -220,6 +229,7 @@ always @(posedge clk or posedge rst) begin frame_count_reg <= 0; frame_reg <= 0; frame_ptr_reg <= 0; + busy_reg <= 0; tick_count_output_reg <= 0; byte_count_output_reg <= 0; frame_count_output_reg <= 0; @@ -231,6 +241,8 @@ always @(posedge clk or posedge rst) begin frame_reg <= frame_next; frame_ptr_reg <= frame_ptr_next; + busy_reg <= state_next != STATE_IDLE; + if (store_output) begin tick_count_output_reg <= tick_count_reg; byte_count_output_reg <= byte_count_reg; diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index a5d83387e..04cc90c89 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -59,7 +59,8 @@ def dut_axis_stat_counter(clk, output_axis_tuser, tag, - trigger): + trigger, + busy): if os.system(build_cmd): raise Exception("Error running build command") @@ -82,7 +83,8 @@ def dut_axis_stat_counter(clk, output_axis_tuser=output_axis_tuser, tag=tag, - trigger=trigger) + trigger=trigger, + busy=busy) def bench(): @@ -107,6 +109,7 @@ def bench(): output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) + busy = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -170,7 +173,8 @@ def bench(): output_axis_tuser, tag, - trigger) + trigger, + busy) @always(delay(4)) def clkgen(): diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v index 11eac0328..529495195 100644 --- a/tb/test_axis_stat_counter.v +++ b/tb/test_axis_stat_counter.v @@ -48,6 +48,7 @@ wire [7:0] output_axis_tdata; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; +wire busy; initial begin // myhdl integration @@ -66,7 +67,8 @@ initial begin $to_myhdl(output_axis_tdata, output_axis_tvalid, output_axis_tlast, - output_axis_tuser); + output_axis_tuser, + busy); // dump file $dumpfile("test_axis_stat_counter.lxt"); @@ -92,7 +94,9 @@ UUT ( .output_axis_tuser(output_axis_tuser), // configuration .tag(tag), - .trigger(trigger) + .trigger(trigger), + // status + .busy(busy) ); endmodule From 63843e9d5d5f038df78a54a2371e6fd5c9289c89 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Oct 2014 23:25:28 -0700 Subject: [PATCH 049/617] Update rate limit test bench to check more settings and verify rate --- tb/test_axis_rate_limit.py | 497 +++++++++++++++++++++------------- tb/test_axis_rate_limit_64.py | 497 +++++++++++++++++++++------------- 2 files changed, 614 insertions(+), 380 deletions(-) diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index 1f3f38c0a..fc51e35e6 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -160,6 +160,34 @@ def bench(): def clkgen(): clk.next = not clk + reset_stats = Signal(bool(False)) + cur_frame = Signal(bool(False)) + tick_count = Signal(intbv(0)) + byte_count = Signal(intbv(0)) + frame_count = Signal(intbv(0)) + + @always(clk.posedge) + def monitor(): + ctc = int(tick_count) + cbc = int(byte_count) + cfc = int(frame_count) + if reset_stats: + ctc = 0 + cbc = 0 + cfc = 0 + reset_stats.next = 0 + ctc += 1 + if output_axis_tready and output_axis_tvalid: + cbc += 1 + if output_axis_tlast: + cur_frame.next = False + elif not cur_frame: + cfc += 1 + cur_frame.next = True + tick_count.next = ctc + byte_count.next = cbc + frame_count.next = cfc + @instance def check(): yield delay(100) @@ -173,236 +201,325 @@ def bench(): yield clk.posedge rate_num.next = 1 - rate_denom.next = 10 + rate_denom.next = 4 rate_by_frame.next = 1 - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 + for frame_mode in (True, False): + print("test frame mode %s" % frame_mode) + rate_by_frame.next = frame_mode - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge + rate_num.next = 1 + rate_denom.next = 4 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge - assert rx_frame == test_frame + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield delay(100) + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 + assert rx_frame == test_frame - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge + yield delay(100) - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge - assert rx_frame == test_frame + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge + assert rx_frame == test_frame - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: + yield delay(64) + yield clk.posedge source_pause.next = True - yield clk.posedge - yield clk.posedge + yield delay(32) yield clk.posedge source_pause.next = False + + yield delay(64) yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: sink_pause.next = True - yield clk.posedge - yield clk.posedge + yield delay(32) yield clk.posedge sink_pause.next = False + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge yield clk.posedge - yield clk.posedge - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert rx_frame == test_frame - assert rx_frame == test_frame1 + yield delay(100) - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 - assert rx_frame == test_frame2 + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge - yield delay(100) + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 - source_queue.put(test_frame) - yield clk.posedge + assert rx_frame == test_frame1 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert rx_frame == test_frame2 - assert rx_frame == test_frame - assert rx_frame.user[-1] + yield delay(100) - yield delay(100) + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 8: various lengths and delays") + current_test.next = 8 + + for rate in ((1,1), (1,2), (1,10), (2,3)): + print("test 8 rate %d / %d" % rate) + rate_num.next = rate[0] + rate_denom.next = rate[1] + + reset_stats.next = 1 + yield clk.posedge + start_time = now() + + lens = [32, 48, 64, 96, 128, 256] + test_frame = [] + + for i in range(len(lens)): + test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i])))) + + for f in test_frame: + source_queue.put(f) + yield clk.posedge + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + + stop_time = now() + + rx_frame = [] + + for i in range(len(lens)): + if not sink_queue.empty(): + rx_frame.append(sink_queue.get()) + + assert len(rx_frame) == len(test_frame) + + for i in range(len(lens)): + assert rx_frame[i] == test_frame[i] + + cycle = (stop_time - start_time) / 8 + + print("cycles %d" % cycle) + print("tick count %d" % tick_count) + print("byte count %d" % byte_count) + print("frame count %d" % frame_count) + + assert tick_count == cycle + assert byte_count == sum(len(f.data) for f in test_frame) + assert frame_count == len(test_frame) + + test_rate = 1.0 * rate_num / rate_denom + meas_rate = 1.0 * byte_count / tick_count + error = (test_rate - meas_rate) / test_rate + + print("test rate %f" % test_rate) + print("meas rate %f" % meas_rate) + print("error %f%%" % (error*100)) + + assert abs(error) < 0.1 + + yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source, sink, clkgen, monitor, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index 6531032c8..66548e9ca 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -170,6 +170,34 @@ def bench(): def clkgen(): clk.next = not clk + reset_stats = Signal(bool(False)) + cur_frame = Signal(bool(False)) + tick_count = Signal(intbv(0)) + byte_count = Signal(intbv(0)) + frame_count = Signal(intbv(0)) + + @always(clk.posedge) + def monitor(): + ctc = int(tick_count) + cbc = int(byte_count) + cfc = int(frame_count) + if reset_stats: + ctc = 0 + cbc = 0 + cfc = 0 + reset_stats.next = 0 + ctc += len(output_axis_tkeep) + if output_axis_tready and output_axis_tvalid: + cbc += bin(output_axis_tkeep).count('1') + if output_axis_tlast: + cur_frame.next = False + elif not cur_frame: + cfc += 1 + cur_frame.next = True + tick_count.next = ctc + byte_count.next = cbc + frame_count.next = cfc + @instance def check(): yield delay(100) @@ -183,236 +211,325 @@ def bench(): yield clk.posedge rate_num.next = 1 - rate_denom.next = 10 + rate_denom.next = 4 rate_by_frame.next = 1 - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 + for frame_mode in (True, False): + print("test frame mode %s" % frame_mode) + rate_by_frame.next = frame_mode - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge + rate_num.next = 1 + rate_denom.next = 4 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge - assert rx_frame == test_frame + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield delay(100) + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 + assert rx_frame == test_frame - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge + yield delay(100) - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge - assert rx_frame == test_frame + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge + assert rx_frame == test_frame - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: + yield delay(64) + yield clk.posedge source_pause.next = True - yield clk.posedge - yield clk.posedge + yield delay(32) yield clk.posedge source_pause.next = False + + yield delay(64) yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: sink_pause.next = True - yield clk.posedge - yield clk.posedge + yield delay(32) yield clk.posedge sink_pause.next = False + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge yield clk.posedge - yield clk.posedge - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert rx_frame == test_frame - assert rx_frame == test_frame1 + yield delay(100) - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 - assert rx_frame == test_frame2 + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge - yield delay(100) + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 - source_queue.put(test_frame) - yield clk.posedge + assert rx_frame == test_frame1 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert rx_frame == test_frame2 - assert rx_frame == test_frame - assert rx_frame.user[-1] + yield delay(100) - yield delay(100) + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 8: various lengths and delays") + current_test.next = 8 + + for rate in ((1,1), (1,2), (1,10), (2,3)): + print("test 8 rate %d / %d" % rate) + rate_num.next = rate[0] + rate_denom.next = rate[1] + + reset_stats.next = 1 + yield clk.posedge + start_time = now() + + lens = [32, 48, 64, 96, 128, 256] + test_frame = [] + + for i in range(len(lens)): + test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i])))) + + for f in test_frame: + source_queue.put(f) + yield clk.posedge + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + + stop_time = now() + + rx_frame = [] + + for i in range(len(lens)): + if not sink_queue.empty(): + rx_frame.append(sink_queue.get()) + + assert len(rx_frame) == len(test_frame) + + for i in range(len(lens)): + assert rx_frame[i] == test_frame[i] + + cycle = (stop_time - start_time) / 8 + + print("cycles %d" % cycle) + print("tick count %d" % tick_count) + print("byte count %d" % byte_count) + print("frame count %d" % frame_count) + + assert tick_count == cycle*8 + assert byte_count == sum(len(f.data) for f in test_frame) + assert frame_count == len(test_frame) + + test_rate = 1.0 * rate_num / rate_denom + meas_rate = 1.0 * byte_count / tick_count + error = (test_rate - meas_rate) / test_rate + + print("test rate %f" % test_rate) + print("meas rate %f" % meas_rate) + print("error %f%%" % (error*100)) + + assert abs(error) < 0.1 + + yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source, sink, clkgen, monitor, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) From 3b1655f81f0a2bd40376e4aceec3dc8713e61561 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Oct 2014 23:25:28 -0700 Subject: [PATCH 050/617] Update rate limit test bench to check more settings and verify rate --- tb/test_axis_rate_limit.py | 497 +++++++++++++++++++++------------- tb/test_axis_rate_limit_64.py | 497 +++++++++++++++++++++------------- 2 files changed, 614 insertions(+), 380 deletions(-) diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index 1f3f38c0a..fc51e35e6 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -160,6 +160,34 @@ def bench(): def clkgen(): clk.next = not clk + reset_stats = Signal(bool(False)) + cur_frame = Signal(bool(False)) + tick_count = Signal(intbv(0)) + byte_count = Signal(intbv(0)) + frame_count = Signal(intbv(0)) + + @always(clk.posedge) + def monitor(): + ctc = int(tick_count) + cbc = int(byte_count) + cfc = int(frame_count) + if reset_stats: + ctc = 0 + cbc = 0 + cfc = 0 + reset_stats.next = 0 + ctc += 1 + if output_axis_tready and output_axis_tvalid: + cbc += 1 + if output_axis_tlast: + cur_frame.next = False + elif not cur_frame: + cfc += 1 + cur_frame.next = True + tick_count.next = ctc + byte_count.next = cbc + frame_count.next = cfc + @instance def check(): yield delay(100) @@ -173,236 +201,325 @@ def bench(): yield clk.posedge rate_num.next = 1 - rate_denom.next = 10 + rate_denom.next = 4 rate_by_frame.next = 1 - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 + for frame_mode in (True, False): + print("test frame mode %s" % frame_mode) + rate_by_frame.next = frame_mode - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge + rate_num.next = 1 + rate_denom.next = 4 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge - assert rx_frame == test_frame + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield delay(100) + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 + assert rx_frame == test_frame - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge + yield delay(100) - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge - assert rx_frame == test_frame + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge + assert rx_frame == test_frame - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: + yield delay(64) + yield clk.posedge source_pause.next = True - yield clk.posedge - yield clk.posedge + yield delay(32) yield clk.posedge source_pause.next = False + + yield delay(64) yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: sink_pause.next = True - yield clk.posedge - yield clk.posedge + yield delay(32) yield clk.posedge sink_pause.next = False + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge yield clk.posedge - yield clk.posedge - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert rx_frame == test_frame - assert rx_frame == test_frame1 + yield delay(100) - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 - assert rx_frame == test_frame2 + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge - yield delay(100) + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 - source_queue.put(test_frame) - yield clk.posedge + assert rx_frame == test_frame1 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert rx_frame == test_frame2 - assert rx_frame == test_frame - assert rx_frame.user[-1] + yield delay(100) - yield delay(100) + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 8: various lengths and delays") + current_test.next = 8 + + for rate in ((1,1), (1,2), (1,10), (2,3)): + print("test 8 rate %d / %d" % rate) + rate_num.next = rate[0] + rate_denom.next = rate[1] + + reset_stats.next = 1 + yield clk.posedge + start_time = now() + + lens = [32, 48, 64, 96, 128, 256] + test_frame = [] + + for i in range(len(lens)): + test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i])))) + + for f in test_frame: + source_queue.put(f) + yield clk.posedge + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + + stop_time = now() + + rx_frame = [] + + for i in range(len(lens)): + if not sink_queue.empty(): + rx_frame.append(sink_queue.get()) + + assert len(rx_frame) == len(test_frame) + + for i in range(len(lens)): + assert rx_frame[i] == test_frame[i] + + cycle = (stop_time - start_time) / 8 + + print("cycles %d" % cycle) + print("tick count %d" % tick_count) + print("byte count %d" % byte_count) + print("frame count %d" % frame_count) + + assert tick_count == cycle + assert byte_count == sum(len(f.data) for f in test_frame) + assert frame_count == len(test_frame) + + test_rate = 1.0 * rate_num / rate_denom + meas_rate = 1.0 * byte_count / tick_count + error = (test_rate - meas_rate) / test_rate + + print("test rate %f" % test_rate) + print("meas rate %f" % meas_rate) + print("error %f%%" % (error*100)) + + assert abs(error) < 0.1 + + yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source, sink, clkgen, monitor, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index 6531032c8..66548e9ca 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -170,6 +170,34 @@ def bench(): def clkgen(): clk.next = not clk + reset_stats = Signal(bool(False)) + cur_frame = Signal(bool(False)) + tick_count = Signal(intbv(0)) + byte_count = Signal(intbv(0)) + frame_count = Signal(intbv(0)) + + @always(clk.posedge) + def monitor(): + ctc = int(tick_count) + cbc = int(byte_count) + cfc = int(frame_count) + if reset_stats: + ctc = 0 + cbc = 0 + cfc = 0 + reset_stats.next = 0 + ctc += len(output_axis_tkeep) + if output_axis_tready and output_axis_tvalid: + cbc += bin(output_axis_tkeep).count('1') + if output_axis_tlast: + cur_frame.next = False + elif not cur_frame: + cfc += 1 + cur_frame.next = True + tick_count.next = ctc + byte_count.next = cbc + frame_count.next = cfc + @instance def check(): yield delay(100) @@ -183,236 +211,325 @@ def bench(): yield clk.posedge rate_num.next = 1 - rate_denom.next = 10 + rate_denom.next = 4 rate_by_frame.next = 1 - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 + for frame_mode in (True, False): + print("test frame mode %s" % frame_mode) + rate_by_frame.next = frame_mode - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge + rate_num.next = 1 + rate_denom.next = 4 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge - assert rx_frame == test_frame + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield delay(100) + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 + assert rx_frame == test_frame - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge + yield delay(100) - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge - assert rx_frame == test_frame + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge + assert rx_frame == test_frame - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: + yield delay(64) + yield clk.posedge source_pause.next = True - yield clk.posedge - yield clk.posedge + yield delay(32) yield clk.posedge source_pause.next = False + + yield delay(64) yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: sink_pause.next = True - yield clk.posedge - yield clk.posedge + yield delay(32) yield clk.posedge sink_pause.next = False + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge yield clk.posedge - yield clk.posedge - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert rx_frame == test_frame - assert rx_frame == test_frame1 + yield delay(100) - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 - assert rx_frame == test_frame2 + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge - yield delay(100) + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 - source_queue.put(test_frame) - yield clk.posedge + assert rx_frame == test_frame1 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + assert rx_frame == test_frame2 - assert rx_frame == test_frame - assert rx_frame.user[-1] + yield delay(100) - yield delay(100) + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 8: various lengths and delays") + current_test.next = 8 + + for rate in ((1,1), (1,2), (1,10), (2,3)): + print("test 8 rate %d / %d" % rate) + rate_num.next = rate[0] + rate_denom.next = rate[1] + + reset_stats.next = 1 + yield clk.posedge + start_time = now() + + lens = [32, 48, 64, 96, 128, 256] + test_frame = [] + + for i in range(len(lens)): + test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i])))) + + for f in test_frame: + source_queue.put(f) + yield clk.posedge + yield clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + while not input_axis_tready: + yield clk.posedge + + stop_time = now() + + rx_frame = [] + + for i in range(len(lens)): + if not sink_queue.empty(): + rx_frame.append(sink_queue.get()) + + assert len(rx_frame) == len(test_frame) + + for i in range(len(lens)): + assert rx_frame[i] == test_frame[i] + + cycle = (stop_time - start_time) / 8 + + print("cycles %d" % cycle) + print("tick count %d" % tick_count) + print("byte count %d" % byte_count) + print("frame count %d" % frame_count) + + assert tick_count == cycle*8 + assert byte_count == sum(len(f.data) for f in test_frame) + assert frame_count == len(test_frame) + + test_rate = 1.0 * rate_num / rate_denom + meas_rate = 1.0 * byte_count / tick_count + error = (test_rate - meas_rate) / test_rate + + print("test rate %f" % test_rate) + print("meas rate %f" % meas_rate) + print("error %f%%" % (error*100)) + + assert abs(error) < 0.1 + + yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source, sink, clkgen, monitor, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) From 7e01c6c14ca1170a50805aaa82c57daa84f2f659 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 10:47:03 -0700 Subject: [PATCH 051/617] Add AXI stream frame joiner, generator, and testbench --- rtl/axis_frame_join.py | 403 +++++++++++++++++++++++++ rtl/axis_frame_join_4.v | 365 +++++++++++++++++++++++ tb/test_axis_frame_join_4.py | 555 +++++++++++++++++++++++++++++++++++ tb/test_axis_frame_join_4.v | 143 +++++++++ 4 files changed, 1466 insertions(+) create mode 100755 rtl/axis_frame_join.py create mode 100644 rtl/axis_frame_join_4.v create mode 100755 tb/test_axis_frame_join_4.py create mode 100644 tb/test_axis_frame_join_4.v diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py new file mode 100755 index 000000000..50c44de2c --- /dev/null +++ b/rtl/axis_frame_join.py @@ -0,0 +1,403 @@ +#!/usr/bin/env python +"""axis_frame_join + +Generates an AXI Stream frame join module with a specific number of input ports + +Usage: axis_frame_join [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--outputs'): + out_name = a + + if name is None: + name = "axis_frame_join_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream frame joiner {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port frame joiner + */ +module {{name}} # +( + parameter ENABLE_TAG = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ +{%- for p in ports %} + input wire [7:0] input_{{p}}_axis_tdata, + input wire input_{{p}}_axis_tvalid, + output wire input_{{p}}_axis_tready, + input wire input_{{p}}_axis_tlast, + input wire input_{{p}}_axis_tuser, +{% endfor %} + /* + * AXI output + */ + output wire [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [15:0] tag, + + /* + * Status signals + */ + output wire busy +); + +// state register +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_WRITE_TAG = 2'd1, + STATE_TRANSFER = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [2:0] frame_ptr_reg = 0, frame_ptr_next; +reg [{{w-1}}:0] port_sel_reg = 0, port_sel_next; + +reg busy_reg = 0, busy_next; + +reg [7:0] input_tdata; +reg input_tvalid; +reg input_tlast; +reg input_tuser; + +reg output_tuser_reg = 0, output_tuser_next; + +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; +{% for p in ports %} +reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +{%- endfor %} +{% for p in ports %} +assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; +{%- endfor %} + +assign busy = busy_reg; + +always @* begin + state_next = 2'bz; + + frame_ptr_next = frame_ptr_reg; + port_sel_next = port_sel_reg; +{% for p in ports %} + input_{{p}}_axis_tready_next = 0; +{%- endfor %} + + output_axis_tdata_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + output_tuser_next = output_tuser_reg; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + port_sel_next = 0; + output_tuser_next = 0; + + if (ENABLE_TAG) begin + // next cycle if started will send tag, so do not enable input + input_0_axis_tready_next = 0; + end else begin + // next cycle if started will send data, so enable input + input_0_axis_tready_next = output_axis_tready_int_early; + end + + if (input_0_axis_tvalid) begin + // input 0 valid; start transferring data + if (ENABLE_TAG) begin + // tag enabled, so transmit it + if (output_axis_tready_int) begin + // output is ready, so short-circuit first tag byte + frame_ptr_next = 1; + output_axis_tdata_int = tag[15:8]; + output_axis_tvalid_int = 1; + end + + state_next = STATE_WRITE_TAG; + end else begin + // tag disabled, so transmit data + if (output_axis_tready_int) begin + // output is ready, so short-circuit first data byte + output_axis_tdata_int = input_0_axis_tdata; + output_axis_tvalid_int = 1; + end + state_next = STATE_TRANSFER; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_TAG: begin + // write tag data + if (output_axis_tready_int) begin + // output ready, so send tag byte + state_next = STATE_WRITE_TAG; + frame_ptr_next = frame_ptr_reg + 1; + output_axis_tvalid_int = 1; + case (frame_ptr_reg) + 2'd0: output_axis_tdata_int = tag[15:8]; + 2'd1: begin + // last tag byte - get ready to send data, enable input if ready + output_axis_tdata_int = tag[7:0]; + input_0_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_TRANSFER; + end + endcase + end else begin + state_next = STATE_WRITE_TAG; + end + end + STATE_TRANSFER: begin + // transfer input data + + // grab correct input lines, set ready line correctly + case (port_sel_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + input_tdata = input_{{p}}_axis_tdata; + input_tvalid = input_{{p}}_axis_tvalid; + input_tlast = input_{{p}}_axis_tlast; + input_tuser = input_{{p}}_axis_tuser; + input_{{p}}_axis_tready_next = output_axis_tready_int_early; + end +{%- endfor %} + endcase + + if (input_tvalid & output_axis_tready_int) begin + // output ready, transfer byte + state_next = STATE_TRANSFER; + output_axis_tdata_int = input_tdata; + output_axis_tvalid_int = input_tvalid; + + if (input_tlast) begin + // last flag received, switch to next port + port_sel_next = port_sel_reg + 1; + // save tuser - assert tuser out if ANY tuser asserts received + output_tuser_next = output_tuser_next | input_tuser; + // disable input +{%- for p in ports %} + input_{{p}}_axis_tready_next = 0; +{%- endfor %} + + if (port_sel_reg == {{n-1}}) begin + // last port - send tlast and tuser and revert to idle + output_axis_tlast_int = 1; + output_axis_tuser_int = output_tuser_next; + state_next = STATE_IDLE; + end else begin + // otherwise, disable enable next port + case (port_sel_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early; +{%- endfor %} + endcase + end + end + end else begin + state_next = STATE_TRANSFER; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + port_sel_reg <= 0; +{%- for p in ports %} + input_{{p}}_axis_tready_reg <= 0; +{%- endfor %} + output_tuser_reg <= 0; + busy_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + port_sel_reg <= port_sel_next; +{% for p in ports %} + input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; +{%- endfor %} + + output_tuser_reg <= output_tuser_next; + + busy_reg <= state_next != STATE_IDLE; + end +end + +// output datapath logic +reg [7:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v new file mode 100644 index 000000000..e3cc89e49 --- /dev/null +++ b/rtl/axis_frame_join_4.v @@ -0,0 +1,365 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream 4 port frame joiner + */ +module axis_frame_join_4 # +( + parameter ENABLE_TAG = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ + input wire [7:0] input_0_axis_tdata, + input wire input_0_axis_tvalid, + output wire input_0_axis_tready, + input wire input_0_axis_tlast, + input wire input_0_axis_tuser, + + input wire [7:0] input_1_axis_tdata, + input wire input_1_axis_tvalid, + output wire input_1_axis_tready, + input wire input_1_axis_tlast, + input wire input_1_axis_tuser, + + input wire [7:0] input_2_axis_tdata, + input wire input_2_axis_tvalid, + output wire input_2_axis_tready, + input wire input_2_axis_tlast, + input wire input_2_axis_tuser, + + input wire [7:0] input_3_axis_tdata, + input wire input_3_axis_tvalid, + output wire input_3_axis_tready, + input wire input_3_axis_tlast, + input wire input_3_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [15:0] tag, + + /* + * Status signals + */ + output wire busy +); + +// state register +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_WRITE_TAG = 2'd1, + STATE_TRANSFER = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [2:0] frame_ptr_reg = 0, frame_ptr_next; +reg [1:0] port_sel_reg = 0, port_sel_next; + +reg busy_reg = 0, busy_next; + +reg [7:0] input_tdata; +reg input_tvalid; +reg input_tlast; +reg input_tuser; + +reg output_tuser_reg = 0, output_tuser_next; + +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; + +reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; + +assign input_0_axis_tready = input_0_axis_tready_reg; +assign input_1_axis_tready = input_1_axis_tready_reg; +assign input_2_axis_tready = input_2_axis_tready_reg; +assign input_3_axis_tready = input_3_axis_tready_reg; + +assign busy = busy_reg; + +always @* begin + state_next = 2'bz; + + frame_ptr_next = frame_ptr_reg; + port_sel_next = port_sel_reg; + + input_0_axis_tready_next = 0; + input_1_axis_tready_next = 0; + input_2_axis_tready_next = 0; + input_3_axis_tready_next = 0; + + output_axis_tdata_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + output_tuser_next = output_tuser_reg; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + port_sel_next = 0; + output_tuser_next = 0; + + if (ENABLE_TAG) begin + // next cycle if started will send tag, so do not enable input + input_0_axis_tready_next = 0; + end else begin + // next cycle if started will send data, so enable input + input_0_axis_tready_next = output_axis_tready_int_early; + end + + if (input_0_axis_tvalid) begin + // input 0 valid; start transferring data + if (ENABLE_TAG) begin + // tag enabled, so transmit it + if (output_axis_tready_int) begin + // output is ready, so short-circuit first tag byte + frame_ptr_next = 1; + output_axis_tdata_int = tag[15:8]; + output_axis_tvalid_int = 1; + end + + state_next = STATE_WRITE_TAG; + end else begin + // tag disabled, so transmit data + if (output_axis_tready_int) begin + // output is ready, so short-circuit first data byte + output_axis_tdata_int = input_0_axis_tdata; + output_axis_tvalid_int = 1; + end + state_next = STATE_TRANSFER; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_TAG: begin + // write tag data + if (output_axis_tready_int) begin + // output ready, so send tag byte + state_next = STATE_WRITE_TAG; + frame_ptr_next = frame_ptr_reg + 1; + output_axis_tvalid_int = 1; + case (frame_ptr_reg) + 2'd0: output_axis_tdata_int = tag[15:8]; + 2'd1: begin + // last tag byte - get ready to send data, enable input if ready + output_axis_tdata_int = tag[7:0]; + input_0_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_TRANSFER; + end + endcase + end else begin + state_next = STATE_WRITE_TAG; + end + end + STATE_TRANSFER: begin + // transfer input data + + // grab correct input lines, set ready line correctly + case (port_sel_reg) + 2'd0: begin + input_tdata = input_0_axis_tdata; + input_tvalid = input_0_axis_tvalid; + input_tlast = input_0_axis_tlast; + input_tuser = input_0_axis_tuser; + input_0_axis_tready_next = output_axis_tready_int_early; + end + 2'd1: begin + input_tdata = input_1_axis_tdata; + input_tvalid = input_1_axis_tvalid; + input_tlast = input_1_axis_tlast; + input_tuser = input_1_axis_tuser; + input_1_axis_tready_next = output_axis_tready_int_early; + end + 2'd2: begin + input_tdata = input_2_axis_tdata; + input_tvalid = input_2_axis_tvalid; + input_tlast = input_2_axis_tlast; + input_tuser = input_2_axis_tuser; + input_2_axis_tready_next = output_axis_tready_int_early; + end + 2'd3: begin + input_tdata = input_3_axis_tdata; + input_tvalid = input_3_axis_tvalid; + input_tlast = input_3_axis_tlast; + input_tuser = input_3_axis_tuser; + input_3_axis_tready_next = output_axis_tready_int_early; + end + endcase + + if (input_tvalid & output_axis_tready_int) begin + // output ready, transfer byte + state_next = STATE_TRANSFER; + output_axis_tdata_int = input_tdata; + output_axis_tvalid_int = input_tvalid; + + if (input_tlast) begin + // last flag received, switch to next port + port_sel_next = port_sel_reg + 1; + // save tuser - assert tuser out if ANY tuser asserts received + output_tuser_next = output_tuser_next | input_tuser; + // disable input + input_0_axis_tready_next = 0; + input_1_axis_tready_next = 0; + input_2_axis_tready_next = 0; + input_3_axis_tready_next = 0; + + if (port_sel_reg == 3) begin + // last port - send tlast and tuser and revert to idle + output_axis_tlast_int = 1; + output_axis_tuser_int = output_tuser_next; + state_next = STATE_IDLE; + end else begin + // otherwise, disable enable next port + case (port_sel_next) + 2'd0: input_0_axis_tready_next = output_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_axis_tready_int_early; + endcase + end + end + end else begin + state_next = STATE_TRANSFER; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + port_sel_reg <= 0; + input_0_axis_tready_reg <= 0; + input_1_axis_tready_reg <= 0; + input_2_axis_tready_reg <= 0; + input_3_axis_tready_reg <= 0; + output_tuser_reg <= 0; + busy_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + port_sel_reg <= port_sel_next; + + input_0_axis_tready_reg <= input_0_axis_tready_next; + input_1_axis_tready_reg <= input_1_axis_tready_next; + input_2_axis_tready_reg <= input_2_axis_tready_next; + input_3_axis_tready_reg <= input_3_axis_tready_next; + + output_tuser_reg <= output_tuser_next; + + busy_reg <= state_next != STATE_IDLE; + end +end + +// output datapath logic +reg [7:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py new file mode 100755 index 000000000..bdd5ba98e --- /dev/null +++ b/tb/test_axis_frame_join_4.py @@ -0,0 +1,555 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue +import struct + +import axis_ep + +module = 'axis_frame_join_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_frame_join_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + tag, + busy): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + tag=tag, + busy=busy) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_axis_tdata = Signal(intbv(0)[8:]) + input_0_axis_tvalid = Signal(bool(0)) + input_0_axis_tlast = Signal(bool(0)) + input_0_axis_tuser = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[8:]) + input_1_axis_tvalid = Signal(bool(0)) + input_1_axis_tlast = Signal(bool(0)) + input_1_axis_tuser = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[8:]) + input_2_axis_tvalid = Signal(bool(0)) + input_2_axis_tlast = Signal(bool(0)) + input_2_axis_tuser = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[8:]) + input_3_axis_tvalid = Signal(bool(0)) + input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + tag = Signal(intbv(0)[15:]) + + # Outputs + input_0_axis_tready = Signal(bool(0)) + input_1_axis_tready = Signal(bool(0)) + input_2_axis_tready = Signal(bool(0)) + input_3_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source_0') + + source_1 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source_1') + + source_2 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source_2') + + source_3 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source_3') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_frame_join_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + tag, + busy) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + tag.next = 1 + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0) + source_1_queue.put(test_frame_1) + source_2_queue.put(test_frame_2) + source_3_queue.put(test_frame_3) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame_0 = axis_ep.AXIStreamFrame(b'\x00' + bytearray(range(256)) + b'\x00') + test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0) + source_1_queue.put(test_frame_1) + source_2_queue.put(test_frame_2) + source_3_queue.put(test_frame_3) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + + yield delay(100) + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0) + source_1_queue.put(test_frame_1) + source_2_queue.put(test_frame_2) + source_3_queue.put(test_frame_3) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_1_pause.next = True + yield delay(32) + yield clk.posedge + source_1_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0a) + source_0_queue.put(test_frame_0b) + source_1_queue.put(test_frame_1a) + source_1_queue.put(test_frame_1b) + source_2_queue.put(test_frame_2a) + source_2_queue.put(test_frame_2b) + source_3_queue.put(test_frame_3a) + source_3_queue.put(test_frame_3b) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0a) + source_0_queue.put(test_frame_0b) + source_1_queue.put(test_frame_1a) + source_1_queue.put(test_frame_1b) + source_2_queue.put(test_frame_2a) + source_2_queue.put(test_frame_2b) + source_3_queue.put(test_frame_3a) + source_3_queue.put(test_frame_3b) + yield clk.posedge + + while input_3_axis_tvalid or output_axis_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0a) + source_0_queue.put(test_frame_0b) + source_1_queue.put(test_frame_1a) + source_1_queue.put(test_frame_1b) + source_2_queue.put(test_frame_2a) + source_2_queue.put(test_frame_2b) + source_3_queue.put(test_frame_3a) + source_3_queue.put(test_frame_3b) + yield clk.posedge + + while input_3_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_0.user = 1 + source_0_queue.put(test_frame_0) + source_1_queue.put(test_frame_1) + source_2_queue.put(test_frame_2) + source_3_queue.put(test_frame_3) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_frame_join_4.v b/tb/test_axis_frame_join_4.v new file mode 100644 index 000000000..21e005b32 --- /dev/null +++ b/tb/test_axis_frame_join_4.v @@ -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 1 ns / 1 ps + +module test_axis_frame_join_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_0_axis_tdata = 8'd0; +reg input_0_axis_tvalid = 1'b0; +reg input_0_axis_tlast = 1'b0; +reg input_0_axis_tuser = 1'b0; +reg [7:0] input_1_axis_tdata = 8'd0; +reg input_1_axis_tvalid = 1'b0; +reg input_1_axis_tlast = 1'b0; +reg input_1_axis_tuser = 1'b0; +reg [7:0] input_2_axis_tdata = 8'd0; +reg input_2_axis_tvalid = 1'b0; +reg input_2_axis_tlast = 1'b0; +reg input_2_axis_tuser = 1'b0; +reg [7:0] input_3_axis_tdata = 8'd0; +reg input_3_axis_tvalid = 1'b0; +reg input_3_axis_tlast = 1'b0; +reg input_3_axis_tuser = 1'b0; +reg output_axis_tready = 1'b0; +reg [15:0] tag = 0; + +// Outputs +wire input_0_axis_tready; +wire input_1_axis_tready; +wire input_2_axis_tready; +wire input_3_axis_tready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; +wire busy; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready, + tag); + $to_myhdl(input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + busy); + + // dump file + $dumpfile("test_axis_frame_join_4.lxt"); + $dumpvars(0, test_axis_frame_join_4); +end + +axis_frame_join_4 #( + .ENABLE_TAG(1) +) +UUT ( + .clk(clk), + .rst(rst), + // axi input + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tvalid(input_0_axis_tvalid), + .input_0_axis_tready(input_0_axis_tready), + .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tuser(input_0_axis_tuser), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tvalid(input_1_axis_tvalid), + .input_1_axis_tready(input_1_axis_tready), + .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tuser(input_1_axis_tuser), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tvalid(input_2_axis_tvalid), + .input_2_axis_tready(input_2_axis_tready), + .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tuser(input_2_axis_tuser), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tvalid(input_3_axis_tvalid), + .input_3_axis_tready(input_3_axis_tready), + .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tuser(input_3_axis_tuser), + // axi output + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // config + .tag(tag), + // status + .busy(busy) +); + +endmodule From 7c3adb6c2be95946ab8d16bff5b1a14a5aad4a7b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 10:47:03 -0700 Subject: [PATCH 052/617] Add AXI stream frame joiner, generator, and testbench --- rtl/axis_frame_join.py | 403 +++++++++++++++++++++++++ rtl/axis_frame_join_4.v | 365 +++++++++++++++++++++++ tb/test_axis_frame_join_4.py | 555 +++++++++++++++++++++++++++++++++++ tb/test_axis_frame_join_4.v | 143 +++++++++ 4 files changed, 1466 insertions(+) create mode 100755 rtl/axis_frame_join.py create mode 100644 rtl/axis_frame_join_4.v create mode 100755 tb/test_axis_frame_join_4.py create mode 100644 tb/test_axis_frame_join_4.v diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py new file mode 100755 index 000000000..50c44de2c --- /dev/null +++ b/rtl/axis_frame_join.py @@ -0,0 +1,403 @@ +#!/usr/bin/env python +"""axis_frame_join + +Generates an AXI Stream frame join module with a specific number of input ports + +Usage: axis_frame_join [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--outputs'): + out_name = a + + if name is None: + name = "axis_frame_join_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream frame joiner {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port frame joiner + */ +module {{name}} # +( + parameter ENABLE_TAG = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ +{%- for p in ports %} + input wire [7:0] input_{{p}}_axis_tdata, + input wire input_{{p}}_axis_tvalid, + output wire input_{{p}}_axis_tready, + input wire input_{{p}}_axis_tlast, + input wire input_{{p}}_axis_tuser, +{% endfor %} + /* + * AXI output + */ + output wire [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [15:0] tag, + + /* + * Status signals + */ + output wire busy +); + +// state register +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_WRITE_TAG = 2'd1, + STATE_TRANSFER = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [2:0] frame_ptr_reg = 0, frame_ptr_next; +reg [{{w-1}}:0] port_sel_reg = 0, port_sel_next; + +reg busy_reg = 0, busy_next; + +reg [7:0] input_tdata; +reg input_tvalid; +reg input_tlast; +reg input_tuser; + +reg output_tuser_reg = 0, output_tuser_next; + +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; +{% for p in ports %} +reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +{%- endfor %} +{% for p in ports %} +assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; +{%- endfor %} + +assign busy = busy_reg; + +always @* begin + state_next = 2'bz; + + frame_ptr_next = frame_ptr_reg; + port_sel_next = port_sel_reg; +{% for p in ports %} + input_{{p}}_axis_tready_next = 0; +{%- endfor %} + + output_axis_tdata_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + output_tuser_next = output_tuser_reg; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + port_sel_next = 0; + output_tuser_next = 0; + + if (ENABLE_TAG) begin + // next cycle if started will send tag, so do not enable input + input_0_axis_tready_next = 0; + end else begin + // next cycle if started will send data, so enable input + input_0_axis_tready_next = output_axis_tready_int_early; + end + + if (input_0_axis_tvalid) begin + // input 0 valid; start transferring data + if (ENABLE_TAG) begin + // tag enabled, so transmit it + if (output_axis_tready_int) begin + // output is ready, so short-circuit first tag byte + frame_ptr_next = 1; + output_axis_tdata_int = tag[15:8]; + output_axis_tvalid_int = 1; + end + + state_next = STATE_WRITE_TAG; + end else begin + // tag disabled, so transmit data + if (output_axis_tready_int) begin + // output is ready, so short-circuit first data byte + output_axis_tdata_int = input_0_axis_tdata; + output_axis_tvalid_int = 1; + end + state_next = STATE_TRANSFER; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_TAG: begin + // write tag data + if (output_axis_tready_int) begin + // output ready, so send tag byte + state_next = STATE_WRITE_TAG; + frame_ptr_next = frame_ptr_reg + 1; + output_axis_tvalid_int = 1; + case (frame_ptr_reg) + 2'd0: output_axis_tdata_int = tag[15:8]; + 2'd1: begin + // last tag byte - get ready to send data, enable input if ready + output_axis_tdata_int = tag[7:0]; + input_0_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_TRANSFER; + end + endcase + end else begin + state_next = STATE_WRITE_TAG; + end + end + STATE_TRANSFER: begin + // transfer input data + + // grab correct input lines, set ready line correctly + case (port_sel_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + input_tdata = input_{{p}}_axis_tdata; + input_tvalid = input_{{p}}_axis_tvalid; + input_tlast = input_{{p}}_axis_tlast; + input_tuser = input_{{p}}_axis_tuser; + input_{{p}}_axis_tready_next = output_axis_tready_int_early; + end +{%- endfor %} + endcase + + if (input_tvalid & output_axis_tready_int) begin + // output ready, transfer byte + state_next = STATE_TRANSFER; + output_axis_tdata_int = input_tdata; + output_axis_tvalid_int = input_tvalid; + + if (input_tlast) begin + // last flag received, switch to next port + port_sel_next = port_sel_reg + 1; + // save tuser - assert tuser out if ANY tuser asserts received + output_tuser_next = output_tuser_next | input_tuser; + // disable input +{%- for p in ports %} + input_{{p}}_axis_tready_next = 0; +{%- endfor %} + + if (port_sel_reg == {{n-1}}) begin + // last port - send tlast and tuser and revert to idle + output_axis_tlast_int = 1; + output_axis_tuser_int = output_tuser_next; + state_next = STATE_IDLE; + end else begin + // otherwise, disable enable next port + case (port_sel_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early; +{%- endfor %} + endcase + end + end + end else begin + state_next = STATE_TRANSFER; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + port_sel_reg <= 0; +{%- for p in ports %} + input_{{p}}_axis_tready_reg <= 0; +{%- endfor %} + output_tuser_reg <= 0; + busy_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + port_sel_reg <= port_sel_next; +{% for p in ports %} + input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; +{%- endfor %} + + output_tuser_reg <= output_tuser_next; + + busy_reg <= state_next != STATE_IDLE; + end +end + +// output datapath logic +reg [7:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v new file mode 100644 index 000000000..e3cc89e49 --- /dev/null +++ b/rtl/axis_frame_join_4.v @@ -0,0 +1,365 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream 4 port frame joiner + */ +module axis_frame_join_4 # +( + parameter ENABLE_TAG = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ + input wire [7:0] input_0_axis_tdata, + input wire input_0_axis_tvalid, + output wire input_0_axis_tready, + input wire input_0_axis_tlast, + input wire input_0_axis_tuser, + + input wire [7:0] input_1_axis_tdata, + input wire input_1_axis_tvalid, + output wire input_1_axis_tready, + input wire input_1_axis_tlast, + input wire input_1_axis_tuser, + + input wire [7:0] input_2_axis_tdata, + input wire input_2_axis_tvalid, + output wire input_2_axis_tready, + input wire input_2_axis_tlast, + input wire input_2_axis_tuser, + + input wire [7:0] input_3_axis_tdata, + input wire input_3_axis_tvalid, + output wire input_3_axis_tready, + input wire input_3_axis_tlast, + input wire input_3_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [15:0] tag, + + /* + * Status signals + */ + output wire busy +); + +// state register +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_WRITE_TAG = 2'd1, + STATE_TRANSFER = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [2:0] frame_ptr_reg = 0, frame_ptr_next; +reg [1:0] port_sel_reg = 0, port_sel_next; + +reg busy_reg = 0, busy_next; + +reg [7:0] input_tdata; +reg input_tvalid; +reg input_tlast; +reg input_tuser; + +reg output_tuser_reg = 0, output_tuser_next; + +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early = output_axis_tready; + +reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; + +assign input_0_axis_tready = input_0_axis_tready_reg; +assign input_1_axis_tready = input_1_axis_tready_reg; +assign input_2_axis_tready = input_2_axis_tready_reg; +assign input_3_axis_tready = input_3_axis_tready_reg; + +assign busy = busy_reg; + +always @* begin + state_next = 2'bz; + + frame_ptr_next = frame_ptr_reg; + port_sel_next = port_sel_reg; + + input_0_axis_tready_next = 0; + input_1_axis_tready_next = 0; + input_2_axis_tready_next = 0; + input_3_axis_tready_next = 0; + + output_axis_tdata_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + output_tuser_next = output_tuser_reg; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + port_sel_next = 0; + output_tuser_next = 0; + + if (ENABLE_TAG) begin + // next cycle if started will send tag, so do not enable input + input_0_axis_tready_next = 0; + end else begin + // next cycle if started will send data, so enable input + input_0_axis_tready_next = output_axis_tready_int_early; + end + + if (input_0_axis_tvalid) begin + // input 0 valid; start transferring data + if (ENABLE_TAG) begin + // tag enabled, so transmit it + if (output_axis_tready_int) begin + // output is ready, so short-circuit first tag byte + frame_ptr_next = 1; + output_axis_tdata_int = tag[15:8]; + output_axis_tvalid_int = 1; + end + + state_next = STATE_WRITE_TAG; + end else begin + // tag disabled, so transmit data + if (output_axis_tready_int) begin + // output is ready, so short-circuit first data byte + output_axis_tdata_int = input_0_axis_tdata; + output_axis_tvalid_int = 1; + end + state_next = STATE_TRANSFER; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_TAG: begin + // write tag data + if (output_axis_tready_int) begin + // output ready, so send tag byte + state_next = STATE_WRITE_TAG; + frame_ptr_next = frame_ptr_reg + 1; + output_axis_tvalid_int = 1; + case (frame_ptr_reg) + 2'd0: output_axis_tdata_int = tag[15:8]; + 2'd1: begin + // last tag byte - get ready to send data, enable input if ready + output_axis_tdata_int = tag[7:0]; + input_0_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_TRANSFER; + end + endcase + end else begin + state_next = STATE_WRITE_TAG; + end + end + STATE_TRANSFER: begin + // transfer input data + + // grab correct input lines, set ready line correctly + case (port_sel_reg) + 2'd0: begin + input_tdata = input_0_axis_tdata; + input_tvalid = input_0_axis_tvalid; + input_tlast = input_0_axis_tlast; + input_tuser = input_0_axis_tuser; + input_0_axis_tready_next = output_axis_tready_int_early; + end + 2'd1: begin + input_tdata = input_1_axis_tdata; + input_tvalid = input_1_axis_tvalid; + input_tlast = input_1_axis_tlast; + input_tuser = input_1_axis_tuser; + input_1_axis_tready_next = output_axis_tready_int_early; + end + 2'd2: begin + input_tdata = input_2_axis_tdata; + input_tvalid = input_2_axis_tvalid; + input_tlast = input_2_axis_tlast; + input_tuser = input_2_axis_tuser; + input_2_axis_tready_next = output_axis_tready_int_early; + end + 2'd3: begin + input_tdata = input_3_axis_tdata; + input_tvalid = input_3_axis_tvalid; + input_tlast = input_3_axis_tlast; + input_tuser = input_3_axis_tuser; + input_3_axis_tready_next = output_axis_tready_int_early; + end + endcase + + if (input_tvalid & output_axis_tready_int) begin + // output ready, transfer byte + state_next = STATE_TRANSFER; + output_axis_tdata_int = input_tdata; + output_axis_tvalid_int = input_tvalid; + + if (input_tlast) begin + // last flag received, switch to next port + port_sel_next = port_sel_reg + 1; + // save tuser - assert tuser out if ANY tuser asserts received + output_tuser_next = output_tuser_next | input_tuser; + // disable input + input_0_axis_tready_next = 0; + input_1_axis_tready_next = 0; + input_2_axis_tready_next = 0; + input_3_axis_tready_next = 0; + + if (port_sel_reg == 3) begin + // last port - send tlast and tuser and revert to idle + output_axis_tlast_int = 1; + output_axis_tuser_int = output_tuser_next; + state_next = STATE_IDLE; + end else begin + // otherwise, disable enable next port + case (port_sel_next) + 2'd0: input_0_axis_tready_next = output_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_axis_tready_int_early; + endcase + end + end + end else begin + state_next = STATE_TRANSFER; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + port_sel_reg <= 0; + input_0_axis_tready_reg <= 0; + input_1_axis_tready_reg <= 0; + input_2_axis_tready_reg <= 0; + input_3_axis_tready_reg <= 0; + output_tuser_reg <= 0; + busy_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + port_sel_reg <= port_sel_next; + + input_0_axis_tready_reg <= input_0_axis_tready_next; + input_1_axis_tready_reg <= input_1_axis_tready_next; + input_2_axis_tready_reg <= input_2_axis_tready_next; + input_3_axis_tready_reg <= input_3_axis_tready_next; + + output_tuser_reg <= output_tuser_next; + + busy_reg <= state_next != STATE_IDLE; + end +end + +// output datapath logic +reg [7:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + // also enable ready input next cycle if output is currently not valid and will not become valid next cycle + output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + end +end + +endmodule diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py new file mode 100755 index 000000000..bdd5ba98e --- /dev/null +++ b/tb/test_axis_frame_join_4.py @@ -0,0 +1,555 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue +import struct + +import axis_ep + +module = 'axis_frame_join_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_frame_join_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + tag, + busy): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + tag=tag, + busy=busy) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_axis_tdata = Signal(intbv(0)[8:]) + input_0_axis_tvalid = Signal(bool(0)) + input_0_axis_tlast = Signal(bool(0)) + input_0_axis_tuser = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[8:]) + input_1_axis_tvalid = Signal(bool(0)) + input_1_axis_tlast = Signal(bool(0)) + input_1_axis_tuser = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[8:]) + input_2_axis_tvalid = Signal(bool(0)) + input_2_axis_tlast = Signal(bool(0)) + input_2_axis_tuser = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[8:]) + input_3_axis_tvalid = Signal(bool(0)) + input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + tag = Signal(intbv(0)[15:]) + + # Outputs + input_0_axis_tready = Signal(bool(0)) + input_1_axis_tready = Signal(bool(0)) + input_2_axis_tready = Signal(bool(0)) + input_3_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + busy = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source_0') + + source_1 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source_1') + + source_2 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source_2') + + source_3 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source_3') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_frame_join_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + tag, + busy) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + tag.next = 1 + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0) + source_1_queue.put(test_frame_1) + source_2_queue.put(test_frame_2) + source_3_queue.put(test_frame_3) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame_0 = axis_ep.AXIStreamFrame(b'\x00' + bytearray(range(256)) + b'\x00') + test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0) + source_1_queue.put(test_frame_1) + source_2_queue.put(test_frame_2) + source_3_queue.put(test_frame_3) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + + yield delay(100) + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0) + source_1_queue.put(test_frame_1) + source_2_queue.put(test_frame_2) + source_3_queue.put(test_frame_3) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_1_pause.next = True + yield delay(32) + yield clk.posedge + source_1_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0a) + source_0_queue.put(test_frame_0b) + source_1_queue.put(test_frame_1a) + source_1_queue.put(test_frame_1b) + source_2_queue.put(test_frame_2a) + source_2_queue.put(test_frame_2b) + source_3_queue.put(test_frame_3a) + source_3_queue.put(test_frame_3b) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0a) + source_0_queue.put(test_frame_0b) + source_1_queue.put(test_frame_1a) + source_1_queue.put(test_frame_1b) + source_2_queue.put(test_frame_2a) + source_2_queue.put(test_frame_2b) + source_3_queue.put(test_frame_3a) + source_3_queue.put(test_frame_3b) + yield clk.posedge + + while input_3_axis_tvalid or output_axis_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + source_0_queue.put(test_frame_0a) + source_0_queue.put(test_frame_0b) + source_1_queue.put(test_frame_1a) + source_1_queue.put(test_frame_1b) + source_2_queue.put(test_frame_2a) + source_2_queue.put(test_frame_2b) + source_3_queue.put(test_frame_3a) + source_3_queue.put(test_frame_3b) + yield clk.posedge + + while input_3_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data + + yield delay(100) + + yield clk.posedge + print("test 7: tuser assert") + current_test.next = 7 + + test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_0.user = 1 + source_0_queue.put(test_frame_0) + source_1_queue.put(test_frame_1) + source_2_queue.put(test_frame_2) + source_3_queue.put(test_frame_3) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_frame_join_4.v b/tb/test_axis_frame_join_4.v new file mode 100644 index 000000000..21e005b32 --- /dev/null +++ b/tb/test_axis_frame_join_4.v @@ -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 1 ns / 1 ps + +module test_axis_frame_join_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_0_axis_tdata = 8'd0; +reg input_0_axis_tvalid = 1'b0; +reg input_0_axis_tlast = 1'b0; +reg input_0_axis_tuser = 1'b0; +reg [7:0] input_1_axis_tdata = 8'd0; +reg input_1_axis_tvalid = 1'b0; +reg input_1_axis_tlast = 1'b0; +reg input_1_axis_tuser = 1'b0; +reg [7:0] input_2_axis_tdata = 8'd0; +reg input_2_axis_tvalid = 1'b0; +reg input_2_axis_tlast = 1'b0; +reg input_2_axis_tuser = 1'b0; +reg [7:0] input_3_axis_tdata = 8'd0; +reg input_3_axis_tvalid = 1'b0; +reg input_3_axis_tlast = 1'b0; +reg input_3_axis_tuser = 1'b0; +reg output_axis_tready = 1'b0; +reg [15:0] tag = 0; + +// Outputs +wire input_0_axis_tready; +wire input_1_axis_tready; +wire input_2_axis_tready; +wire input_3_axis_tready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; +wire busy; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready, + tag); + $to_myhdl(input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + busy); + + // dump file + $dumpfile("test_axis_frame_join_4.lxt"); + $dumpvars(0, test_axis_frame_join_4); +end + +axis_frame_join_4 #( + .ENABLE_TAG(1) +) +UUT ( + .clk(clk), + .rst(rst), + // axi input + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tvalid(input_0_axis_tvalid), + .input_0_axis_tready(input_0_axis_tready), + .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tuser(input_0_axis_tuser), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tvalid(input_1_axis_tvalid), + .input_1_axis_tready(input_1_axis_tready), + .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tuser(input_1_axis_tuser), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tvalid(input_2_axis_tvalid), + .input_2_axis_tready(input_2_axis_tready), + .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tuser(input_2_axis_tuser), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tvalid(input_3_axis_tvalid), + .input_3_axis_tready(input_3_axis_tready), + .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tuser(input_3_axis_tuser), + // axi output + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // config + .tag(tag), + // status + .busy(busy) +); + +endmodule From 2cf95840eeb249189f84b0fba059b1caca8e3f3f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 15:09:48 -0700 Subject: [PATCH 053/617] Improve output register filling --- rtl/axis_register.v | 8 ++++++-- rtl/axis_register_64.v | 9 +++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/rtl/axis_register.v b/rtl/axis_register.v index f7ede82bf..1032a2ae6 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -89,8 +89,8 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - input_axis_tready_reg <= output_axis_tready | (~output_axis_tvalid_reg & ~input_axis_tvalid); + // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle + input_axis_tready_reg <= output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~input_axis_tvalid); if (input_axis_tready_reg) begin // input is ready @@ -113,6 +113,10 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v index ea0fc658b..c8ab746a6 100644 --- a/rtl/axis_register_64.v +++ b/rtl/axis_register_64.v @@ -97,8 +97,8 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle even if output is not ready if output is currently not valid and will not become valid next cycle - input_axis_tready_reg <= output_axis_tready | (~output_axis_tvalid_reg & ~input_axis_tvalid); + // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle + input_axis_tready_reg <= output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~input_axis_tvalid); if (input_axis_tready_reg) begin // input is ready @@ -124,6 +124,11 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end From a92eb4e57fca975ac485533e3cf655179bb5f2fa Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 15:09:48 -0700 Subject: [PATCH 054/617] Improve output register filling --- rtl/axis_register.v | 8 ++++++-- rtl/axis_register_64.v | 9 +++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/rtl/axis_register.v b/rtl/axis_register.v index f7ede82bf..1032a2ae6 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -89,8 +89,8 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - input_axis_tready_reg <= output_axis_tready | (~output_axis_tvalid_reg & ~input_axis_tvalid); + // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle + input_axis_tready_reg <= output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~input_axis_tvalid); if (input_axis_tready_reg) begin // input is ready @@ -113,6 +113,10 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v index ea0fc658b..c8ab746a6 100644 --- a/rtl/axis_register_64.v +++ b/rtl/axis_register_64.v @@ -97,8 +97,8 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle even if output is not ready if output is currently not valid and will not become valid next cycle - input_axis_tready_reg <= output_axis_tready | (~output_axis_tvalid_reg & ~input_axis_tvalid); + // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle + input_axis_tready_reg <= output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~input_axis_tvalid); if (input_axis_tready_reg) begin // input is ready @@ -124,6 +124,11 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end From a9bbdae908c5510677534fe98f30bf7654434cf6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 15:10:07 -0700 Subject: [PATCH 055/617] Improve output register filling --- rtl/axis_stat_counter.v | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index 0baf74527..7dfdb14fa 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -94,7 +94,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; assign busy = busy_reg; @@ -267,6 +267,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -280,8 +283,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -304,6 +306,10 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end From 47a8c35d5dfb68edb130910bb20a803fe6e1b91f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 15:10:07 -0700 Subject: [PATCH 056/617] Improve output register filling --- rtl/axis_stat_counter.v | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index 0baf74527..7dfdb14fa 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -94,7 +94,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; assign busy = busy_reg; @@ -267,6 +267,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -280,8 +283,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -304,6 +306,10 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end From c86ffa12020ac78028346f1b4cbf74a8ad6b10b4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 15:10:21 -0700 Subject: [PATCH 057/617] Improve output register filling --- rtl/axis_frame_join.py | 12 +++++++++--- rtl/axis_frame_join_4.v | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index 50c44de2c..19c9e9fe4 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -163,7 +163,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; {% for p in ports %} reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; {%- endfor %} @@ -344,6 +344,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -357,8 +360,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -381,6 +383,10 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index e3cc89e49..92270a1cc 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -110,7 +110,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; @@ -321,6 +321,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -334,8 +337,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -358,6 +360,10 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end From a2a509884e85bff8ae38efd17b0d94da914a9d52 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 15:10:21 -0700 Subject: [PATCH 058/617] Improve output register filling --- rtl/axis_frame_join.py | 12 +++++++++--- rtl/axis_frame_join_4.v | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index 50c44de2c..19c9e9fe4 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -163,7 +163,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; {% for p in ports %} reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; {%- endfor %} @@ -344,6 +344,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -357,8 +360,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -381,6 +383,10 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index e3cc89e49..92270a1cc 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -110,7 +110,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; @@ -321,6 +321,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -334,8 +337,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -358,6 +360,10 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end From d82ebcce1799576270d4c5b1a228bf93a50815a1 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 15:11:41 -0700 Subject: [PATCH 059/617] Improve output register filling --- rtl/axis_rate_limit.v | 12 +++++++++--- rtl/axis_rate_limit_64.v | 13 ++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index 7c7fd9a4b..f1ebb70e5 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -70,7 +70,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; reg [23:0] acc_reg = 0, acc_next; reg pause; @@ -138,6 +138,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -151,8 +154,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -175,6 +177,10 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v index e1918d3b6..e5b31ca9c 100644 --- a/rtl/axis_rate_limit_64.v +++ b/rtl/axis_rate_limit_64.v @@ -73,7 +73,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; reg [23:0] acc_reg = 0, acc_next; reg pause; @@ -145,6 +145,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -160,8 +163,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -187,6 +189,11 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end From 5f14df216aef460ec9417484ea56d77f6307eac4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 15:11:41 -0700 Subject: [PATCH 060/617] Improve output register filling --- rtl/axis_rate_limit.v | 12 +++++++++--- rtl/axis_rate_limit_64.v | 13 ++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index 7c7fd9a4b..f1ebb70e5 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -70,7 +70,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; reg [23:0] acc_reg = 0, acc_next; reg pause; @@ -138,6 +138,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -151,8 +154,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -175,6 +177,10 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v index e1918d3b6..e5b31ca9c 100644 --- a/rtl/axis_rate_limit_64.v +++ b/rtl/axis_rate_limit_64.v @@ -73,7 +73,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; reg [23:0] acc_reg = 0, acc_next; reg pause; @@ -145,6 +145,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -160,8 +163,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -187,6 +189,11 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end From 0b8a36d5e7264bf1d9c7873b61e0d570f1cee9a7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 15:13:42 -0700 Subject: [PATCH 061/617] Improve output register filling --- rtl/axis_adapter.v | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index 9fe64e502..dc8da2f42 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -115,7 +115,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; reg input_axis_tready_reg = 0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; @@ -376,6 +376,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -391,8 +394,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -418,6 +420,11 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end From f827b5eafb81c0b326b17cb2bceb5ffa6f2305d0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 22 Oct 2014 15:13:42 -0700 Subject: [PATCH 062/617] Improve output register filling --- rtl/axis_adapter.v | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index 9fe64e502..dc8da2f42 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -115,7 +115,7 @@ reg output_axis_tvalid_int; reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; -wire output_axis_tready_int_early = output_axis_tready; +wire output_axis_tready_int_early; reg input_axis_tready_reg = 0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; @@ -376,6 +376,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + always @(posedge clk or posedge rst) begin if (rst) begin output_axis_tdata_reg <= 0; @@ -391,8 +394,7 @@ always @(posedge clk or posedge rst) begin temp_axis_tuser_reg <= 0; end else begin // transfer sink ready state to source - // also enable ready input next cycle if output is currently not valid and will not become valid next cycle - output_axis_tready_int <= output_axis_tready | (~output_axis_tvalid_reg & ~output_axis_tvalid_int); + output_axis_tready_int <= output_axis_tready_int_early; if (output_axis_tready_int) begin // input is ready @@ -418,6 +420,11 @@ always @(posedge clk or posedge rst) begin output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end From 205be7ed2784f2d898eaf676c19603dc3f598eb6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 23 Oct 2014 00:05:06 -0700 Subject: [PATCH 063/617] Rework AXI ethernet modules to separate output register --- rtl/eth_axis_rx.v | 258 ++++++++++----------- rtl/eth_axis_rx_64.v | 357 ++++++++++++++--------------- rtl/eth_axis_tx.v | 305 +++++++++++-------------- rtl/eth_axis_tx_64.v | 518 +++++++++++++++++++------------------------ 4 files changed, 646 insertions(+), 792 deletions(-) diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index ebc3c6d1c..40fa80265 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -73,21 +73,18 @@ Ethernet frame Source MAC address 6 octets Ethertype 2 octets -This module receives an Ethernet frame on an 8 bit wide AXI interface, -separates the dest MAC, source MAC, and eth type into separate parallel -outputs, and forwards the payload data out through a separate AXI interface. +This module receives an Ethernet frame on an AXI stream interface, decodes +and strips the headers, then produces the header fields in parallel along +with the payload in a separate AXI stream. */ -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_READ_HEADER = 3'd1, - STATE_READ_PAYLOAD_IDLE = 3'd2, - STATE_READ_PAYLOAD_TRANSFER = 3'd3, - STATE_READ_PAYLOAD_TRANSFER_WAIT = 3'd4, - STATE_READ_PAYLOAD_TRANSFER_LAST = 3'd5; +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_READ_HEADER = 2'd1, + STATE_READ_PAYLOAD = 2'd2; -reg [2:0] state_reg = STATE_IDLE, state_next; +reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_eth_dest_mac_0; @@ -105,29 +102,25 @@ reg store_eth_src_mac_5; reg store_eth_type_0; reg store_eth_type_1; -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - reg [7:0] frame_ptr_reg = 0, frame_ptr_next; -reg input_axis_tready_reg = 0; - reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; reg [47:0] output_eth_src_mac_reg = 0; reg [15:0] output_eth_type_reg = 0; -reg [7:0] output_eth_payload_tdata_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; -reg busy_reg = 0, busy_next; +reg input_axis_tready_reg = 0, input_axis_tready_next; + +reg busy_reg = 0; reg error_header_early_termination_reg = 0, error_header_early_termination_next; -reg [7:0] temp_eth_payload_tdata_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +// internal datapath +reg [7:0] output_eth_payload_tdata_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; assign input_axis_tready = input_axis_tready_reg; @@ -135,10 +128,6 @@ assign output_eth_hdr_valid = output_eth_hdr_valid_reg; assign output_eth_dest_mac = output_eth_dest_mac_reg; assign output_eth_src_mac = output_eth_src_mac_reg; assign output_eth_type = output_eth_type_reg; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -146,9 +135,7 @@ assign error_header_early_termination = error_header_early_termination_reg; always @* begin state_next = 2'bz; - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; + input_axis_tready_next = 0; store_eth_dest_mac_0 = 0; store_eth_dest_mac_1 = 0; @@ -171,26 +158,38 @@ always @* begin error_header_early_termination_next = 0; + output_eth_payload_tdata_int = 0; + output_eth_payload_tvalid_int = 0; + output_eth_payload_tlast_int = 0; + output_eth_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + input_axis_tready_next = ~output_eth_hdr_valid_reg; if (input_axis_tready & input_axis_tvalid) begin - frame_ptr_next = 1; - store_eth_dest_mac_5 = 1; - state_next = STATE_READ_HEADER; + // got first word of packet if (input_axis_tlast) begin - state_next = STATE_IDLE; + // tlast asserted on first word error_header_early_termination_next = 1; + state_next = STATE_IDLE; + end else begin + // move to read header state + frame_ptr_next = 1; + store_eth_dest_mac_5 = 1; + state_next = STATE_READ_HEADER; end end else begin state_next = STATE_IDLE; end end STATE_READ_HEADER: begin - // read header state - if (input_axis_tvalid) begin + // read header + input_axis_tready_next = 1; + + if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg+1; state_next = STATE_READ_HEADER; @@ -211,73 +210,38 @@ always @* begin 8'h0D: begin store_eth_type_0 = 1; output_eth_hdr_valid_next = 1; - state_next = STATE_READ_PAYLOAD_IDLE; + input_axis_tready_next = output_eth_payload_tready_int_early; + state_next = STATE_READ_PAYLOAD; end endcase if (input_axis_tlast) begin - state_next = STATE_IDLE; error_header_early_termination_next = 1; + input_axis_tready_next = ~output_eth_hdr_valid_reg; + state_next = STATE_IDLE; end end else begin state_next = STATE_READ_HEADER; end end - STATE_READ_PAYLOAD_IDLE: begin - // idle; no data in registers - if (input_axis_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; + STATE_READ_PAYLOAD: begin + // read payload + input_axis_tready_next = output_eth_payload_tready_int_early; + + output_eth_payload_tdata_int = input_axis_tdata; + output_eth_payload_tvalid_int = input_axis_tvalid & input_axis_tready; + output_eth_payload_tlast_int = input_axis_tlast; + output_eth_payload_tuser_int = input_axis_tuser; + + if (input_axis_tready & input_axis_tvalid) begin + // word transfer through if (input_axis_tlast) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + input_axis_tready_next = ~output_eth_hdr_valid_reg; + state_next = STATE_IDLE; end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; + state_next = STATE_READ_PAYLOAD; end end else begin - state_next = STATE_READ_PAYLOAD_IDLE; - end - end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register - if (input_axis_tvalid & output_eth_payload_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - if (input_axis_tlast) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end else if (~input_axis_tvalid & output_eth_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_READ_PAYLOAD_IDLE; - end else if (input_axis_tvalid & ~output_eth_payload_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in both output and temp registers - if (output_eth_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_eth_payload_tlast_reg) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - if (output_eth_payload_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + state_next = STATE_READ_PAYLOAD; end end endcase @@ -292,13 +256,6 @@ always @(posedge clk or posedge rst) begin output_eth_dest_mac_reg <= 0; output_eth_src_mac_reg <= 0; output_eth_type_reg <= 0; - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; busy_reg <= 0; error_header_early_termination_reg <= 0; end else begin @@ -306,46 +263,14 @@ always @(posedge clk or posedge rst) begin frame_ptr_reg <= frame_ptr_next; + input_axis_tready_reg <= input_axis_tready_next; + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_axis_tready_reg <= ~output_eth_hdr_valid; - output_eth_payload_tvalid_reg <= 0; - end - STATE_READ_HEADER: begin - // read header; accept new data - input_axis_tready_reg <= 1; - output_eth_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_IDLE: begin - // read payload; no data in registers; accept new data - input_axis_tready_reg <= 1; - output_eth_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register; accept new data - input_axis_tready_reg <= 1; - output_eth_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in output and temp registers; do not accept new data - input_axis_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - input_axis_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - endcase - // datapath if (store_eth_dest_mac_0) output_eth_dest_mac_reg[ 7: 0] <= input_axis_tdata; if (store_eth_dest_mac_1) output_eth_dest_mac_reg[15: 8] <= input_axis_tdata; @@ -361,19 +286,68 @@ always @(posedge clk or posedge rst) begin if (store_eth_src_mac_5) output_eth_src_mac_reg[47:40] <= input_axis_tdata; if (store_eth_type_0) output_eth_type_reg[ 7: 0] <= input_axis_tdata; if (store_eth_type_1) output_eth_type_reg[15: 8] <= input_axis_tdata; + end +end - if (transfer_in_out) begin - output_eth_payload_tdata_reg <= input_axis_tdata; - output_eth_payload_tlast_reg <= input_axis_tlast; - output_eth_payload_tuser_reg <= input_axis_tuser; - end else if (transfer_in_temp) begin - temp_eth_payload_tdata_reg <= input_axis_tdata; - temp_eth_payload_tlast_reg <= input_axis_tlast; - temp_eth_payload_tuser_reg <= input_axis_tuser; - end else if (transfer_temp_out) begin +// output datapath logic +reg [7:0] output_eth_payload_tdata_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [7:0] temp_eth_payload_tdata_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; end end end diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index 97c17210b..c0661202e 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -75,19 +75,17 @@ Ethernet frame Source MAC address 6 octets Ethertype 2 octets -This module receives an Ethernet frame on an 8 bit wide AXI interface, -separates the dest MAC, source MAC, and eth type into separate parallel -outputs, and forwards the payload data out through a separate AXI interface. +This module receives an Ethernet frame on an AXI stream interface, decodes +and strips the headers, then produces the header fields in parallel along +with the payload in a separate AXI stream. */ localparam [2:0] STATE_IDLE = 3'd0, STATE_READ_HEADER = 3'd1, - STATE_READ_PAYLOAD_IDLE = 3'd2, - STATE_READ_PAYLOAD_TRANSFER = 3'd3, - STATE_READ_PAYLOAD_TRANSFER_WAIT = 3'd4, - STATE_READ_PAYLOAD_TRANSFER_LAST = 3'd5; + STATE_READ_PAYLOAD = 3'd2, + STATE_READ_PAYLOAD_LAST = 3'd3; reg [2:0] state_reg = STATE_IDLE, state_next; @@ -97,45 +95,33 @@ reg store_hdr_word_1; reg flush_save; reg transfer_in_save; -reg transfer_save_out; -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; reg [7:0] frame_ptr_reg = 0, frame_ptr_next; -reg input_axis_tready_reg = 0; - reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; reg [47:0] output_eth_src_mac_reg = 0; reg [15:0] output_eth_type_reg = 0; -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; -reg busy_reg = 0, busy_next; +reg input_axis_tready_reg = 0, input_axis_tready_next; + +reg busy_reg = 0; reg error_header_early_termination_reg = 0, error_header_early_termination_next; -reg [63:0] temp_eth_payload_tdata_reg = 0; -reg [7:0] temp_eth_payload_tkeep_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; - reg [63:0] save_axis_tdata_reg = 0; reg [7:0] save_axis_tkeep_reg = 0; +reg save_axis_tvalid_reg = 0; reg save_axis_tlast_reg = 0; reg save_axis_tuser_reg = 0; -reg [63:0] shift_axis_tdata; -reg [7:0] shift_axis_tkeep; -reg shift_axis_tvalid; -reg shift_axis_tlast; -reg shift_axis_tuser; -reg shift_axis_input_tready; -reg shift_axis_extra_cycle; +// internal datapath +reg [63:0] output_eth_payload_tdata_int; +reg [7:0] output_eth_payload_tkeep_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; assign input_axis_tready = input_axis_tready_reg; @@ -143,46 +129,17 @@ assign output_eth_hdr_valid = output_eth_hdr_valid_reg; assign output_eth_dest_mac = output_eth_dest_mac_reg; assign output_eth_src_mac = output_eth_src_mac_reg; assign output_eth_type = output_eth_type_reg; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; -always @* begin - shift_axis_tdata[15:0] = save_axis_tdata_reg[63:48]; - shift_axis_tkeep[1:0] = save_axis_tkeep_reg[7:6]; - shift_axis_extra_cycle = save_axis_tlast_reg & (save_axis_tkeep_reg[7:6] != 0); - - if (shift_axis_extra_cycle) begin - shift_axis_tdata[63:16] = 0; - shift_axis_tkeep[7:2] = 0; - shift_axis_tvalid = 1; - shift_axis_tlast = save_axis_tlast_reg; - shift_axis_tuser = save_axis_tuser_reg; - shift_axis_input_tready = flush_save; - end else begin - shift_axis_tdata[63:16] = input_axis_tdata[47:0]; - shift_axis_tkeep[7:2] = input_axis_tkeep[5:0]; - shift_axis_tvalid = input_axis_tvalid; - shift_axis_tlast = (input_axis_tlast & (input_axis_tkeep[7:6] == 0)); - shift_axis_tuser = (input_axis_tuser & (input_axis_tkeep[7:6] == 0)); - shift_axis_input_tready = ~(input_axis_tlast & input_axis_tvalid & transfer_in_save); - end -end - always @* begin state_next = 2'bz; + input_axis_tready_next = 0; + flush_save = 0; transfer_in_save = 0; - transfer_save_out = 0; - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; store_hdr_word_0 = 0; store_hdr_word_1 = 0; @@ -193,20 +150,31 @@ always @* begin error_header_early_termination_next = 0; + output_eth_payload_tdata_int = 0; + output_eth_payload_tkeep_int = 0; + output_eth_payload_tvalid_int = 0; + output_eth_payload_tlast_int = 0; + output_eth_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; flush_save = 1; + input_axis_tready_next = ~output_eth_hdr_valid_reg; if (input_axis_tready & input_axis_tvalid) begin - frame_ptr_next = 8; - store_hdr_word_0 = 1; - transfer_in_save = 1; - state_next = STATE_READ_HEADER; + // got first word of packet if (input_axis_tlast) begin - state_next = STATE_IDLE; + // tlast asserted on first word error_header_early_termination_next = 1; + state_next = STATE_IDLE; + end else begin + // move to read header state + frame_ptr_next = 8; + store_hdr_word_0 = 1; + transfer_in_save = 1; + state_next = STATE_READ_HEADER; end end else begin state_next = STATE_IDLE; @@ -214,7 +182,9 @@ always @* begin end STATE_READ_HEADER: begin // read header state - if (input_axis_tvalid) begin + input_axis_tready_next = 1; + + if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg+8; transfer_in_save = 1; @@ -224,77 +194,77 @@ always @* begin 8'h08: begin store_hdr_word_1 = 1; output_eth_hdr_valid_next = 1; - state_next = STATE_READ_PAYLOAD_IDLE; + input_axis_tready_next = output_eth_payload_tready_int_early; + state_next = STATE_READ_PAYLOAD; end endcase - if (shift_axis_tlast) begin - state_next = STATE_IDLE; - output_eth_hdr_valid_next = 0; - error_header_early_termination_next = 1; + if (input_axis_tlast) begin + if (input_axis_tkeep[7:6] != 0) begin + input_axis_tready_next = 0; + state_next = STATE_READ_PAYLOAD_LAST; + end else begin + flush_save = 1; + output_eth_hdr_valid_next = 0; + error_header_early_termination_next = 1; + input_axis_tready_next = ~output_eth_hdr_valid_reg; + state_next = STATE_IDLE; + end end end else begin state_next = STATE_READ_HEADER; end end - STATE_READ_PAYLOAD_IDLE: begin - // idle; no data in registers - if (shift_axis_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; + STATE_READ_PAYLOAD: begin + // read payload + input_axis_tready_next = output_eth_payload_tready_int_early; + + output_eth_payload_tdata_int[15:0] = save_axis_tdata_reg[63:48]; + output_eth_payload_tkeep_int[1:0] = save_axis_tkeep_reg[7:6]; + + output_eth_payload_tdata_int[63:16] = input_axis_tdata[47:0]; + output_eth_payload_tkeep_int[7:2] = input_axis_tkeep[5:0]; + output_eth_payload_tvalid_int = save_axis_tvalid_reg & input_axis_tvalid & input_axis_tready; + output_eth_payload_tlast_int = (input_axis_tlast & (input_axis_tkeep[7:6] == 0)); + output_eth_payload_tuser_int = (input_axis_tuser & (input_axis_tkeep[7:6] == 0)); + + if (input_axis_tready & input_axis_tvalid) begin + // word transfer through transfer_in_save = 1; - if (shift_axis_tlast) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + if (input_axis_tlast) begin + if (input_axis_tkeep[7:6] != 0) begin + input_axis_tready_next = 0; + state_next = STATE_READ_PAYLOAD_LAST; + end else begin + flush_save = 1; + input_axis_tready_next = ~output_eth_hdr_valid_reg; + state_next = STATE_IDLE; + end end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; + state_next = STATE_READ_PAYLOAD; end end else begin - state_next = STATE_READ_PAYLOAD_IDLE; + state_next = STATE_READ_PAYLOAD; end end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register - if (shift_axis_tvalid & output_eth_payload_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - transfer_in_save = 1; - if (shift_axis_tlast) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end else if (~shift_axis_tvalid & output_eth_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_READ_PAYLOAD_IDLE; - end else if (shift_axis_tvalid & ~output_eth_payload_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - transfer_in_save = 1; - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in both output and temp registers - if (output_eth_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_eth_payload_tlast_reg) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - if (output_eth_payload_tready) begin - // word transfer out + STATE_READ_PAYLOAD_LAST: begin + // read last payload word from save reg + input_axis_tready_next = 0; + + output_eth_payload_tdata_int[15:0] = save_axis_tdata_reg[63:48]; + output_eth_payload_tkeep_int[1:0] = save_axis_tkeep_reg[7:6]; + + output_eth_payload_tdata_int[63:16] = 0; + output_eth_payload_tkeep_int[7:2] = 0; + output_eth_payload_tvalid_int = 1; + output_eth_payload_tlast_int = 1; + output_eth_payload_tuser_int = save_axis_tuser_reg; + + if (output_eth_payload_tready_int) begin + flush_save = 1; + input_axis_tready_next = ~output_eth_hdr_valid_reg; state_next = STATE_IDLE; end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + state_next = STATE_READ_PAYLOAD_LAST; end end endcase @@ -309,17 +279,9 @@ always @(posedge clk or posedge rst) begin output_eth_dest_mac_reg <= 0; output_eth_src_mac_reg <= 0; output_eth_type_reg <= 0; - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tkeep_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; save_axis_tdata_reg <= 0; save_axis_tkeep_reg <= 0; + save_axis_tvalid_reg <= 0; save_axis_tlast_reg <= 0; save_axis_tuser_reg <= 0; busy_reg <= 0; @@ -329,46 +291,14 @@ always @(posedge clk or posedge rst) begin frame_ptr_reg <= frame_ptr_next; + input_axis_tready_reg <= input_axis_tready_next; + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_axis_tready_reg <= ~output_eth_hdr_valid; - output_eth_payload_tvalid_reg <= 0; - end - STATE_READ_HEADER: begin - // read header; accept new data - input_axis_tready_reg <= shift_axis_input_tready; - output_eth_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_IDLE: begin - // read payload; no data in registers; accept new data - input_axis_tready_reg <= shift_axis_input_tready; - output_eth_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register; accept new data - input_axis_tready_reg <= shift_axis_input_tready; - output_eth_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in output and temp registers; do not accept new data - input_axis_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - input_axis_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - endcase - // datapath if (store_hdr_word_0) begin output_eth_dest_mac_reg[47:40] <= input_axis_tdata[ 7: 0]; @@ -389,35 +319,92 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg[ 7:0] <= input_axis_tdata[47:40]; end - if (transfer_in_out) begin - output_eth_payload_tdata_reg <= shift_axis_tdata; - output_eth_payload_tkeep_reg <= shift_axis_tkeep; - output_eth_payload_tlast_reg <= shift_axis_tlast; - output_eth_payload_tuser_reg <= shift_axis_tuser; - end else if (transfer_in_temp) begin - temp_eth_payload_tdata_reg <= shift_axis_tdata; - temp_eth_payload_tkeep_reg <= shift_axis_tkeep; - temp_eth_payload_tlast_reg <= shift_axis_tlast; - temp_eth_payload_tuser_reg <= shift_axis_tuser; - end else if (transfer_temp_out) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - if (flush_save) begin save_axis_tdata_reg <= 0; save_axis_tkeep_reg <= 0; + save_axis_tvalid_reg <= 0; save_axis_tlast_reg <= 0; save_axis_tuser_reg <= 0; - end else if (transfer_in_save & ~shift_axis_extra_cycle) begin + end else if (transfer_in_save) begin save_axis_tdata_reg <= input_axis_tdata; save_axis_tkeep_reg <= input_axis_tkeep; + save_axis_tvalid_reg <= input_axis_tvalid; save_axis_tlast_reg <= input_axis_tlast; save_axis_tuser_reg <= input_axis_tuser; end end end +// output datapath logic +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [63:0] temp_eth_payload_tdata_reg = 0; +reg [7:0] temp_eth_payload_tkeep_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tkeep_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + endmodule diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index 949e46c6d..0dc5426da 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -72,176 +72,132 @@ Ethernet frame Source MAC address 6 octets Ethertype 2 octets -This module receives an Ethernet frame with parallel field input -and an AXI interface for the payload data and produces an AXI -output stream. +This module receives an Ethernet frame with header fields in parallel along +with the payload in an AXI stream, combines the header with the payload, and +transmits the complete Ethernet frame on the output AXI stream interface. */ -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_WRITE_HEADER = 3'd1, - STATE_WRITE_PAYLOAD_IDLE = 3'd2, - STATE_WRITE_PAYLOAD_TRANSFER = 3'd3, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 3'd4, - STATE_WRITE_PAYLOAD_TRANSFER_LAST = 3'd5; +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_WRITE_HEADER = 2'd1, + STATE_WRITE_PAYLOAD = 2'd2; -reg [2:0] state_reg = STATE_IDLE, state_next; +reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_eth_hdr; -reg [7:0] write_hdr_data; -reg write_hdr_out; - -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - reg [7:0] frame_ptr_reg = 0, frame_ptr_next; reg [47:0] eth_dest_mac_reg = 0; reg [47:0] eth_src_mac_reg = 0; reg [15:0] eth_type_reg = 0; -reg input_eth_hdr_ready_reg = 0; -reg input_eth_payload_tready_reg = 0; - -reg [7:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; reg busy_reg = 0; -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - assign busy = busy_reg; always @* begin state_next = 2'bz; + input_eth_hdr_ready_next = 0; + input_eth_payload_tready_next = 0; + store_eth_hdr = 0; - write_hdr_data = 0; - write_hdr_out = 0; - - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - frame_ptr_next = frame_ptr_reg; + output_axis_tdata_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + input_eth_hdr_ready_next = 1; if (input_eth_hdr_valid) begin store_eth_hdr = 1; - write_hdr_out = 1; - write_hdr_data = input_eth_dest_mac[47:40]; - frame_ptr_next = 1; + input_eth_hdr_ready_next = 0; + if (output_axis_tready_int) begin + output_axis_tvalid_int = 1; + output_axis_tdata_int = input_eth_dest_mac[47:40]; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + frame_ptr_next = 1; + end state_next = STATE_WRITE_HEADER; end else begin state_next = STATE_IDLE; end end STATE_WRITE_HEADER: begin - // read header state - if (output_axis_tready) begin - // word transfer out + // write header + if (output_axis_tready_int) begin frame_ptr_next = frame_ptr_reg+1; + output_axis_tvalid_int = 1; state_next = STATE_WRITE_HEADER; - write_hdr_out = 1; case (frame_ptr_reg) - 8'h01: write_hdr_data = eth_dest_mac_reg[39:32]; - 8'h02: write_hdr_data = eth_dest_mac_reg[31:24]; - 8'h03: write_hdr_data = eth_dest_mac_reg[23:16]; - 8'h04: write_hdr_data = eth_dest_mac_reg[15: 8]; - 8'h05: write_hdr_data = eth_dest_mac_reg[ 7: 0]; - 8'h06: write_hdr_data = eth_src_mac_reg[47:40]; - 8'h07: write_hdr_data = eth_src_mac_reg[39:32]; - 8'h08: write_hdr_data = eth_src_mac_reg[31:24]; - 8'h09: write_hdr_data = eth_src_mac_reg[23:16]; - 8'h0A: write_hdr_data = eth_src_mac_reg[15: 8]; - 8'h0B: write_hdr_data = eth_src_mac_reg[ 7: 0]; - 8'h0C: write_hdr_data = eth_type_reg[15: 8]; + 8'h00: output_axis_tdata_int = eth_dest_mac_reg[47:40]; + 8'h01: output_axis_tdata_int = eth_dest_mac_reg[39:32]; + 8'h02: output_axis_tdata_int = eth_dest_mac_reg[31:24]; + 8'h03: output_axis_tdata_int = eth_dest_mac_reg[23:16]; + 8'h04: output_axis_tdata_int = eth_dest_mac_reg[15: 8]; + 8'h05: output_axis_tdata_int = eth_dest_mac_reg[ 7: 0]; + 8'h06: output_axis_tdata_int = eth_src_mac_reg[47:40]; + 8'h07: output_axis_tdata_int = eth_src_mac_reg[39:32]; + 8'h08: output_axis_tdata_int = eth_src_mac_reg[31:24]; + 8'h09: output_axis_tdata_int = eth_src_mac_reg[23:16]; + 8'h0A: output_axis_tdata_int = eth_src_mac_reg[15: 8]; + 8'h0B: output_axis_tdata_int = eth_src_mac_reg[ 7: 0]; + 8'h0C: output_axis_tdata_int = eth_type_reg[15: 8]; 8'h0D: begin - write_hdr_data = eth_type_reg[ 7: 0]; - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + output_axis_tdata_int = eth_type_reg[ 7: 0]; + input_eth_payload_tready_next = output_axis_tready_int_early; + state_next = STATE_WRITE_PAYLOAD; end endcase end else begin state_next = STATE_WRITE_HEADER; end end - STATE_WRITE_PAYLOAD_IDLE: begin - // idle; no data in registers - if (input_eth_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; + STATE_WRITE_PAYLOAD: begin + // write payload + input_eth_payload_tready_next = output_axis_tready_int_early; + + output_axis_tdata_int = input_eth_payload_tdata; + output_axis_tvalid_int = input_eth_payload_tvalid; + output_axis_tlast_int = input_eth_payload_tlast; + output_axis_tuser_int = input_eth_payload_tuser; + + if (input_eth_payload_tready & input_eth_payload_tvalid) begin + // word transfer through if (input_eth_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_eth_payload_tready_next = 0; + input_eth_hdr_ready_next = 1; + state_next = STATE_IDLE; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + state_next = STATE_WRITE_PAYLOAD; end end else begin - state_next = STATE_WRITE_PAYLOAD_IDLE; - end - end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register - if (input_eth_payload_tvalid & output_axis_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - if (input_eth_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end else if (~input_eth_payload_tvalid & output_axis_tready) begin - // word transfer out - go back to idle - state_next = STATE_WRITE_PAYLOAD_IDLE; - end else if (input_eth_payload_tvalid & ~output_axis_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in both output and temp registers - if (output_axis_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_axis_tlast_reg) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - if (output_axis_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + state_next = STATE_WRITE_PAYLOAD; end end endcase @@ -256,83 +212,86 @@ always @(posedge clk or posedge rst) begin eth_dest_mac_reg <= 0; eth_src_mac_reg <= 0; eth_type_reg <= 0; - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; busy_reg <= 0; end else begin state_reg <= state_next; frame_ptr_reg <= frame_ptr_next; + input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + + input_eth_payload_tready_reg <= input_eth_payload_tready_next; + busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_eth_hdr_ready_reg <= 1; - input_eth_payload_tready_reg <= 0; - output_axis_tvalid_reg <= 0; - end - STATE_WRITE_HEADER: begin - // write header - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_axis_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_IDLE: begin - // write payload; no data in registers; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - output_axis_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - output_axis_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in output and temp registers; do not accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_axis_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_axis_tvalid_reg <= 1; - end - endcase - + // datapath if (store_eth_hdr) begin eth_dest_mac_reg <= input_eth_dest_mac; eth_src_mac_reg <= input_eth_src_mac; eth_type_reg <= input_eth_type; end + end +end - if (write_hdr_out) begin - output_axis_tdata_reg <= write_hdr_data; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - end else if (transfer_in_out) begin - output_axis_tdata_reg <= input_eth_payload_tdata; - output_axis_tlast_reg <= input_eth_payload_tlast; - output_axis_tuser_reg <= input_eth_payload_tuser; - end else if (transfer_in_temp) begin - temp_axis_tdata_reg <= input_eth_payload_tdata; - temp_axis_tlast_reg <= input_eth_payload_tlast; - temp_axis_tuser_reg <= input_eth_payload_tuser; - end else if (transfer_temp_out) begin +// output datapath logic +reg [7:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index ac8170a79..194f900ab 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -74,9 +74,9 @@ Ethernet frame Source MAC address 6 octets Ethertype 2 octets -This module receives an Ethernet frame with parallel field input -and an AXI interface for the payload data and produces an AXI -output stream. +This module receives an Ethernet frame with header fields in parallel along +with the payload in an AXI stream, combines the header with the payload, and +transmits the complete Ethernet frame on the output AXI stream interface. */ @@ -84,29 +84,16 @@ localparam [2:0] STATE_IDLE = 3'd0, STATE_WRITE_HEADER = 3'd1, STATE_WRITE_HEADER_LAST = 3'd2, - STATE_WRITE_HEADER_LAST_WAIT = 3'd3, - STATE_WRITE_PAYLOAD_IDLE = 3'd4, - STATE_WRITE_PAYLOAD_TRANSFER = 3'd5, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 3'd6, - STATE_WRITE_PAYLOAD_TRANSFER_LAST = 3'd7; + STATE_WRITE_PAYLOAD = 3'd3, + STATE_WRITE_PAYLOAD_LAST = 3'd4; reg [2:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_eth_hdr; -reg [63:0] write_hdr_data; -reg [7:0] write_hdr_keep; -reg write_hdr_last; -reg write_hdr_user; -reg write_hdr_out; -reg write_hdr_temp; - reg flush_save; reg transfer_in_save; -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; reg [7:0] frame_ptr_reg = 0, frame_ptr_next; @@ -114,242 +101,197 @@ reg [47:0] eth_dest_mac_reg = 0; reg [47:0] eth_src_mac_reg = 0; reg [15:0] eth_type_reg = 0; -reg input_eth_hdr_ready_reg = 0; -reg input_eth_payload_tready_reg = 0; - -reg [63:0] output_axis_tdata_reg = 0; -reg [7:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; reg busy_reg = 0; -reg [63:0] temp_axis_tdata_reg = 0; -reg [7:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; - reg [63:0] save_eth_payload_tdata_reg = 0; reg [7:0] save_eth_payload_tkeep_reg = 0; +reg save_eth_payload_tvalid_reg = 0; reg save_eth_payload_tlast_reg = 0; reg save_eth_payload_tuser_reg = 0; -reg [63:0] shift_eth_payload_tdata; -reg [7:0] shift_eth_payload_tkeep; -reg shift_eth_payload_tvalid; -reg shift_eth_payload_tlast; -reg shift_eth_payload_tuser; -reg shift_eth_payload_input_tready; -reg shift_eth_payload_extra_cycle; +// internal datapath +reg [63:0] output_axis_tdata_int; +reg [7:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - assign busy = busy_reg; -always @* begin - shift_eth_payload_tdata[47:0] = save_eth_payload_tdata_reg[63:16]; - shift_eth_payload_tkeep[5:0] = save_eth_payload_tkeep_reg[7:2]; - shift_eth_payload_extra_cycle = save_eth_payload_tlast_reg & (save_eth_payload_tkeep_reg[7:2] != 0); - - if (shift_eth_payload_extra_cycle) begin - shift_eth_payload_tdata[63:48] = 0; - shift_eth_payload_tkeep[7:6] = 0; - shift_eth_payload_tvalid = 1; - shift_eth_payload_tlast = save_eth_payload_tlast_reg; - shift_eth_payload_tuser = save_eth_payload_tuser_reg; - shift_eth_payload_input_tready = flush_save; - end else begin - shift_eth_payload_tdata[63:48] = input_eth_payload_tdata[15:0]; - shift_eth_payload_tkeep[7:6] = input_eth_payload_tkeep[1:0]; - shift_eth_payload_tvalid = input_eth_payload_tvalid; - shift_eth_payload_tlast = (input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0)); - shift_eth_payload_tuser = (input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0)); - shift_eth_payload_input_tready = ~(input_eth_payload_tlast & input_eth_payload_tvalid & transfer_in_save); - end -end - always @* begin state_next = 2'bz; - store_eth_hdr = 0; + input_eth_hdr_ready_next = 0; + input_eth_payload_tready_next = 0; - write_hdr_data = 0; - write_hdr_keep = 0; - write_hdr_last = 0; - write_hdr_user = 0; - write_hdr_out = 0; - write_hdr_temp = 0; + store_eth_hdr = 0; flush_save = 0; transfer_in_save = 0; - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; frame_ptr_next = frame_ptr_reg; + output_axis_tdata_int = 0; + output_axis_tkeep_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; flush_save = 1; + input_eth_hdr_ready_next = 1; if (input_eth_hdr_valid) begin store_eth_hdr = 1; - write_hdr_out = 1; - write_hdr_data[ 7: 0] = input_eth_dest_mac[47:40]; - write_hdr_data[15: 8] = input_eth_dest_mac[39:32]; - write_hdr_data[23:16] = input_eth_dest_mac[31:24]; - write_hdr_data[31:24] = input_eth_dest_mac[23:16]; - write_hdr_data[39:32] = input_eth_dest_mac[15: 8]; - write_hdr_data[47:40] = input_eth_dest_mac[ 7: 0]; - write_hdr_data[55:48] = input_eth_src_mac[47:40]; - write_hdr_data[63:56] = input_eth_src_mac[39:32]; - write_hdr_keep = 8'hff; - frame_ptr_next = 8; - state_next = STATE_WRITE_HEADER_LAST; + input_eth_hdr_ready_next = 0; + state_next = STATE_WRITE_HEADER; + if (output_axis_tready_int) begin + output_axis_tvalid_int = 1; + output_axis_tdata_int[ 7: 0] = input_eth_dest_mac[47:40]; + output_axis_tdata_int[15: 8] = input_eth_dest_mac[39:32]; + output_axis_tdata_int[23:16] = input_eth_dest_mac[31:24]; + output_axis_tdata_int[31:24] = input_eth_dest_mac[23:16]; + output_axis_tdata_int[39:32] = input_eth_dest_mac[15: 8]; + output_axis_tdata_int[47:40] = input_eth_dest_mac[ 7: 0]; + output_axis_tdata_int[55:48] = input_eth_src_mac[47:40]; + output_axis_tdata_int[63:56] = input_eth_src_mac[39:32]; + output_axis_tkeep_int = 8'hff; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + frame_ptr_next = 8; + input_eth_payload_tready_next = output_axis_tready_int_early; + state_next = STATE_WRITE_HEADER_LAST; + end end else begin state_next = STATE_IDLE; end end + STATE_WRITE_HEADER: begin + // write header + if (output_axis_tready_int) begin + frame_ptr_next = frame_ptr_reg + 8; + output_axis_tvalid_int = 1; + state_next = STATE_WRITE_HEADER; + case (frame_ptr_reg) + 5'd00: begin + output_axis_tdata_int[ 7: 0] = input_eth_dest_mac[47:40]; + output_axis_tdata_int[15: 8] = input_eth_dest_mac[39:32]; + output_axis_tdata_int[23:16] = input_eth_dest_mac[31:24]; + output_axis_tdata_int[31:24] = input_eth_dest_mac[23:16]; + output_axis_tdata_int[39:32] = input_eth_dest_mac[15: 8]; + output_axis_tdata_int[47:40] = input_eth_dest_mac[ 7: 0]; + output_axis_tdata_int[55:48] = input_eth_src_mac[47:40]; + output_axis_tdata_int[63:56] = input_eth_src_mac[39:32]; + output_axis_tkeep_int = 8'hff; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + input_eth_payload_tready_next = output_axis_tready_int_early; + state_next = STATE_WRITE_HEADER_LAST; + end + endcase + end else begin + state_next = STATE_WRITE_HEADER; + end + end STATE_WRITE_HEADER_LAST: begin // last header word requires first payload word; process accordingly - if (shift_eth_payload_tvalid & output_axis_tready) begin - // word transfer through - update output register - transfer_in_save = 1; - write_hdr_out = 1; - write_hdr_data[ 7: 0] = eth_src_mac_reg[31:24]; - write_hdr_data[15: 8] = eth_src_mac_reg[23:16]; - write_hdr_data[23:16] = eth_src_mac_reg[15: 8]; - write_hdr_data[31:24] = eth_src_mac_reg[ 7: 0]; - write_hdr_data[39:32] = eth_type_reg[15: 8]; - write_hdr_data[47:40] = eth_type_reg[ 7: 0]; - write_hdr_data[55:48] = shift_eth_payload_tdata[55:48]; - write_hdr_data[63:56] = shift_eth_payload_tdata[63:56]; - write_hdr_keep = {shift_eth_payload_tkeep[7:6], 6'h3F}; - write_hdr_last = shift_eth_payload_tlast; - write_hdr_user = shift_eth_payload_tuser; - if (shift_eth_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_eth_payload_tready_next = output_axis_tready_int_early; + + if (input_eth_payload_tready & input_eth_payload_tvalid) begin + frame_ptr_next = frame_ptr_reg + 8; + output_axis_tvalid_int = 1; + transfer_in_save = 1; + + output_axis_tdata_int[ 7: 0] = eth_src_mac_reg[31:24]; + output_axis_tdata_int[15: 8] = eth_src_mac_reg[23:16]; + output_axis_tdata_int[23:16] = eth_src_mac_reg[15: 8]; + output_axis_tdata_int[31:24] = eth_src_mac_reg[ 7: 0]; + output_axis_tdata_int[39:32] = eth_type_reg[15: 8]; + output_axis_tdata_int[47:40] = eth_type_reg[ 7: 0]; + output_axis_tdata_int[55:48] = input_eth_payload_tdata[ 7: 0]; + output_axis_tdata_int[63:56] = input_eth_payload_tdata[15: 8]; + output_axis_tkeep_int = {input_eth_payload_tkeep[1:0], 6'h3F}; + output_axis_tlast_int = (input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0)); + output_axis_tuser_int = (input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0)); + + if (input_eth_payload_tlast) begin + input_eth_payload_tready_next = 0; + if (input_eth_payload_tkeep[7:2] != 0) begin + state_next = STATE_WRITE_PAYLOAD_LAST; + end else begin + flush_save = 1; + input_eth_hdr_ready_next = 1; + state_next = STATE_IDLE; + end end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end else if (~shift_eth_payload_tvalid & output_axis_tready) begin - // word transfer out - go back to idle - state_next = STATE_WRITE_HEADER_LAST_WAIT; - end else if (shift_eth_payload_tvalid & ~output_axis_tready) begin - // word transfer in - store in temp - transfer_in_save = 1; - write_hdr_temp = 1; - write_hdr_data[ 7: 0] = eth_src_mac_reg[31:24]; - write_hdr_data[15: 8] = eth_src_mac_reg[23:16]; - write_hdr_data[23:16] = eth_src_mac_reg[15: 8]; - write_hdr_data[31:24] = eth_src_mac_reg[ 7: 0]; - write_hdr_data[39:32] = eth_type_reg[15: 8]; - write_hdr_data[47:40] = eth_type_reg[ 7: 0]; - write_hdr_data[55:48] = shift_eth_payload_tdata[55:48]; - write_hdr_data[63:56] = shift_eth_payload_tdata[63:56]; - write_hdr_keep = {shift_eth_payload_tkeep[7:6], 6'h3F}; - write_hdr_last = shift_eth_payload_tlast; - write_hdr_user = shift_eth_payload_tuser; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - STATE_WRITE_HEADER_LAST_WAIT: begin - // last header word requires first payload word; no data in registers - if (shift_eth_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_save = 1; - write_hdr_out = 1; - write_hdr_data[ 7: 0] = eth_src_mac_reg[31:24]; - write_hdr_data[15: 8] = eth_src_mac_reg[23:16]; - write_hdr_data[23:16] = eth_src_mac_reg[15: 8]; - write_hdr_data[31:24] = eth_src_mac_reg[ 7: 0]; - write_hdr_data[39:32] = eth_type_reg[15: 8]; - write_hdr_data[47:40] = eth_type_reg[ 7: 0]; - write_hdr_data[55:48] = shift_eth_payload_tdata[55:48]; - write_hdr_data[63:56] = shift_eth_payload_tdata[63:56]; - write_hdr_keep = {shift_eth_payload_tkeep[7:6], 6'h3F}; - write_hdr_last = shift_eth_payload_tlast; - write_hdr_user = shift_eth_payload_tuser; - if (shift_eth_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + state_next = STATE_WRITE_PAYLOAD; end end else begin - state_next = STATE_WRITE_HEADER_LAST_WAIT; + state_next = STATE_WRITE_HEADER_LAST; end end - STATE_WRITE_PAYLOAD_IDLE: begin - // idle; no data in registers - if (shift_eth_payload_tvalid) begin - // word transfer in - store it in output register + STATE_WRITE_PAYLOAD: begin + // write payload + input_eth_payload_tready_next = output_axis_tready_int_early; + + output_axis_tdata_int[47:0] = save_eth_payload_tdata_reg[63:16]; + output_axis_tkeep_int[5:0] = save_eth_payload_tkeep_reg[7:2]; + + output_axis_tdata_int[63:48] = input_eth_payload_tdata[15:0]; + output_axis_tkeep_int[7:6] = input_eth_payload_tkeep[1:0]; + output_axis_tvalid_int = input_eth_payload_tvalid; + output_axis_tlast_int = (input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0)); + output_axis_tuser_int = (input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0)); + + if (input_eth_payload_tready & input_eth_payload_tvalid) begin + // word transfer through transfer_in_save = 1; - transfer_in_out = 1; - if (shift_eth_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + if (input_eth_payload_tlast) begin + input_eth_payload_tready_next = 0; + if (input_eth_payload_tkeep[7:2] != 0) begin + state_next = STATE_WRITE_PAYLOAD_LAST; + end else begin + flush_save = 1; + input_eth_hdr_ready_next = 1; + state_next = STATE_IDLE; + end end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + state_next = STATE_WRITE_PAYLOAD; end end else begin - state_next = STATE_WRITE_PAYLOAD_IDLE; + state_next = STATE_WRITE_PAYLOAD; end end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register - if (shift_eth_payload_tvalid & output_axis_tready) begin - // word transfer through - update output register - transfer_in_save = 1; - transfer_in_out = 1; - if (shift_eth_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end else if (~shift_eth_payload_tvalid & output_axis_tready) begin - // word transfer out - go back to idle - state_next = STATE_WRITE_PAYLOAD_IDLE; - end else if (shift_eth_payload_tvalid & ~output_axis_tready) begin - // word transfer in - store in temp - transfer_in_save = 1; - transfer_in_temp = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in both output and temp registers - if (output_axis_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_axis_tlast_reg) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - if (output_axis_tready) begin - // word transfer out - done + STATE_WRITE_PAYLOAD_LAST: begin + // read last payload word from save reg + input_eth_payload_tready_next = 0; + + output_axis_tdata_int[47:0] = save_eth_payload_tdata_reg[63:16]; + output_axis_tkeep_int[5:0] = save_eth_payload_tkeep_reg[7:2]; + + output_axis_tdata_int[63:48] = 0; + output_axis_tkeep_int[7:6] = 0; + output_axis_tvalid_int = 1; + output_axis_tlast_int = 1; + output_axis_tuser_int = save_eth_payload_tuser_reg; + + if (output_axis_tready_int) begin + flush_save = 1; + input_eth_hdr_ready_next = 1; state_next = STATE_IDLE; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + state_next = STATE_WRITE_PAYLOAD_LAST; end end endcase @@ -364,17 +306,9 @@ always @(posedge clk or posedge rst) begin eth_dest_mac_reg <= 0; eth_src_mac_reg <= 0; eth_type_reg <= 0; - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; save_eth_payload_tdata_reg <= 0; save_eth_payload_tkeep_reg <= 0; + save_eth_payload_tvalid_reg <= 0; save_eth_payload_tlast_reg <= 0; save_eth_payload_tuser_reg <= 0; busy_reg <= 0; @@ -383,105 +317,105 @@ always @(posedge clk or posedge rst) begin frame_ptr_reg <= frame_ptr_next; + input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + + input_eth_payload_tready_reg <= input_eth_payload_tready_next; + busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_eth_hdr_ready_reg <= 1; - input_eth_payload_tready_reg <= 0; - output_axis_tvalid_reg <= 0; - end - STATE_WRITE_HEADER: begin - // read header; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_axis_tvalid_reg <= 1; - end - STATE_WRITE_HEADER_LAST: begin - // write last header word; need first data word - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= shift_eth_payload_input_tready; - output_axis_tvalid_reg <= 1; - end - STATE_WRITE_HEADER_LAST_WAIT: begin - // last header word requires first payload word; no data in registers - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= shift_eth_payload_input_tready; - output_axis_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_IDLE: begin - // write payload; no data in registers; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= shift_eth_payload_input_tready; - output_axis_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= shift_eth_payload_input_tready; - output_axis_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in output and temp registers; do not accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_axis_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_axis_tvalid_reg <= 1; - end - endcase - + // datapath if (store_eth_hdr) begin eth_dest_mac_reg <= input_eth_dest_mac; eth_src_mac_reg <= input_eth_src_mac; eth_type_reg <= input_eth_type; end - if (write_hdr_out) begin - output_axis_tdata_reg <= write_hdr_data; - output_axis_tkeep_reg <= write_hdr_keep; - output_axis_tlast_reg <= write_hdr_last; - output_axis_tuser_reg <= write_hdr_user; - end else if (write_hdr_temp) begin - temp_axis_tdata_reg <= write_hdr_data; - temp_axis_tkeep_reg <= write_hdr_keep; - temp_axis_tlast_reg <= write_hdr_last; - temp_axis_tuser_reg <= write_hdr_user; - end else if (transfer_in_out) begin - output_axis_tdata_reg <= shift_eth_payload_tdata; - output_axis_tkeep_reg <= shift_eth_payload_tkeep; - output_axis_tlast_reg <= shift_eth_payload_tlast; - output_axis_tuser_reg <= shift_eth_payload_tuser; - end else if (transfer_in_temp) begin - temp_axis_tdata_reg <= shift_eth_payload_tdata; - temp_axis_tkeep_reg <= shift_eth_payload_tkeep; - temp_axis_tlast_reg <= shift_eth_payload_tlast; - temp_axis_tuser_reg <= shift_eth_payload_tuser; - end else if (transfer_temp_out) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - if (flush_save) begin save_eth_payload_tdata_reg <= 0; save_eth_payload_tkeep_reg <= 0; + save_eth_payload_tvalid_reg <= 0; save_eth_payload_tlast_reg <= 0; save_eth_payload_tuser_reg <= 0; - end else if (transfer_in_save & ~shift_eth_payload_extra_cycle) begin + end else if (transfer_in_save) begin save_eth_payload_tdata_reg <= input_eth_payload_tdata; save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; + save_eth_payload_tvalid_reg <= input_eth_payload_tvalid; save_eth_payload_tlast_reg <= input_eth_payload_tlast; save_eth_payload_tuser_reg <= input_eth_payload_tuser; end end end +// output datapath logic +reg [63:0] output_axis_tdata_reg = 0; +reg [7:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [63:0] temp_axis_tdata_reg = 0; +reg [7:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + endmodule From 0e26b3a8a41ede80d4ee6fd384dc69a7800635e9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Oct 2014 00:54:15 -0700 Subject: [PATCH 064/617] Put back lane shifting logic --- rtl/eth_axis_rx.v | 6 +-- rtl/eth_axis_rx_64.v | 94 ++++++++++++++++----------------- rtl/eth_axis_tx.v | 4 +- rtl/eth_axis_tx_64.v | 121 ++++++++++++++++++++----------------------- 4 files changed, 104 insertions(+), 121 deletions(-) diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index 40fa80265..5a795e141 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -104,13 +104,13 @@ reg store_eth_type_1; reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg input_axis_tready_reg = 0, input_axis_tready_next; + reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; reg [47:0] output_eth_src_mac_reg = 0; reg [15:0] output_eth_type_reg = 0; -reg input_axis_tready_reg = 0, input_axis_tready_next; - reg busy_reg = 0; reg error_header_early_termination_reg = 0, error_header_early_termination_next; @@ -228,7 +228,7 @@ always @* begin input_axis_tready_next = output_eth_payload_tready_int_early; output_eth_payload_tdata_int = input_axis_tdata; - output_eth_payload_tvalid_int = input_axis_tvalid & input_axis_tready; + output_eth_payload_tvalid_int = input_axis_tvalid; output_eth_payload_tlast_int = input_axis_tlast; output_eth_payload_tuser_int = input_axis_tuser; diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index c0661202e..3fb2d3b66 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -84,8 +84,7 @@ with the payload in a separate AXI stream. localparam [2:0] STATE_IDLE = 3'd0, STATE_READ_HEADER = 3'd1, - STATE_READ_PAYLOAD = 3'd2, - STATE_READ_PAYLOAD_LAST = 3'd3; + STATE_READ_PAYLOAD = 3'd2; reg [2:0] state_reg = STATE_IDLE, state_next; @@ -98,22 +97,29 @@ reg transfer_in_save; reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg input_axis_tready_reg = 0, input_axis_tready_next; + reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; reg [47:0] output_eth_src_mac_reg = 0; reg [15:0] output_eth_type_reg = 0; -reg input_axis_tready_reg = 0, input_axis_tready_next; - reg busy_reg = 0; reg error_header_early_termination_reg = 0, error_header_early_termination_next; reg [63:0] save_axis_tdata_reg = 0; reg [7:0] save_axis_tkeep_reg = 0; -reg save_axis_tvalid_reg = 0; reg save_axis_tlast_reg = 0; reg save_axis_tuser_reg = 0; +reg [63:0] shift_axis_tdata; +reg [7:0] shift_axis_tkeep; +reg shift_axis_tvalid; +reg shift_axis_tlast; +reg shift_axis_tuser; +reg shift_axis_input_tready; +reg shift_axis_extra_cycle; + // internal datapath reg [63:0] output_eth_payload_tdata_int; reg [7:0] output_eth_payload_tkeep_int; @@ -133,6 +139,28 @@ assign output_eth_type = output_eth_type_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; +always @* begin + shift_axis_tdata[15:0] = save_axis_tdata_reg[63:48]; + shift_axis_tkeep[1:0] = save_axis_tkeep_reg[7:6]; + shift_axis_extra_cycle = save_axis_tlast_reg & (save_axis_tkeep_reg[7:6] != 0); + + if (shift_axis_extra_cycle) begin + shift_axis_tdata[63:16] = 0; + shift_axis_tkeep[7:2] = 0; + shift_axis_tvalid = 1; + shift_axis_tlast = save_axis_tlast_reg; + shift_axis_tuser = save_axis_tuser_reg; + shift_axis_input_tready = flush_save; + end else begin + shift_axis_tdata[63:16] = input_axis_tdata[47:0]; + shift_axis_tkeep[7:2] = input_axis_tkeep[5:0]; + shift_axis_tvalid = input_axis_tvalid; + shift_axis_tlast = (input_axis_tlast & (input_axis_tkeep[7:6] == 0)); + shift_axis_tuser = (input_axis_tuser & (input_axis_tkeep[7:6] == 0)); + shift_axis_input_tready = ~(input_axis_tlast & input_axis_tvalid & transfer_in_save); + end +end + always @* begin state_next = 2'bz; @@ -201,7 +229,7 @@ always @* begin if (input_axis_tlast) begin if (input_axis_tkeep[7:6] != 0) begin input_axis_tready_next = 0; - state_next = STATE_READ_PAYLOAD_LAST; + state_next = STATE_READ_PAYLOAD; end else begin flush_save = 1; output_eth_hdr_valid_next = 0; @@ -216,29 +244,21 @@ always @* begin end STATE_READ_PAYLOAD: begin // read payload - input_axis_tready_next = output_eth_payload_tready_int_early; + input_axis_tready_next = output_eth_payload_tready_int_early & shift_axis_input_tready; - output_eth_payload_tdata_int[15:0] = save_axis_tdata_reg[63:48]; - output_eth_payload_tkeep_int[1:0] = save_axis_tkeep_reg[7:6]; + output_eth_payload_tdata_int = shift_axis_tdata; + output_eth_payload_tkeep_int = shift_axis_tkeep; + output_eth_payload_tvalid_int = shift_axis_tvalid; + output_eth_payload_tlast_int = shift_axis_tlast; + output_eth_payload_tuser_int = shift_axis_tuser; - output_eth_payload_tdata_int[63:16] = input_axis_tdata[47:0]; - output_eth_payload_tkeep_int[7:2] = input_axis_tkeep[5:0]; - output_eth_payload_tvalid_int = save_axis_tvalid_reg & input_axis_tvalid & input_axis_tready; - output_eth_payload_tlast_int = (input_axis_tlast & (input_axis_tkeep[7:6] == 0)); - output_eth_payload_tuser_int = (input_axis_tuser & (input_axis_tkeep[7:6] == 0)); - - if (input_axis_tready & input_axis_tvalid) begin + if (output_eth_payload_tready_int & shift_axis_tvalid) begin // word transfer through transfer_in_save = 1; - if (input_axis_tlast) begin - if (input_axis_tkeep[7:6] != 0) begin - input_axis_tready_next = 0; - state_next = STATE_READ_PAYLOAD_LAST; - end else begin - flush_save = 1; - input_axis_tready_next = ~output_eth_hdr_valid_reg; - state_next = STATE_IDLE; - end + if (shift_axis_tlast) begin + flush_save = 1; + input_axis_tready_next = ~output_eth_hdr_valid_reg; + state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD; end @@ -246,27 +266,6 @@ always @* begin state_next = STATE_READ_PAYLOAD; end end - STATE_READ_PAYLOAD_LAST: begin - // read last payload word from save reg - input_axis_tready_next = 0; - - output_eth_payload_tdata_int[15:0] = save_axis_tdata_reg[63:48]; - output_eth_payload_tkeep_int[1:0] = save_axis_tkeep_reg[7:6]; - - output_eth_payload_tdata_int[63:16] = 0; - output_eth_payload_tkeep_int[7:2] = 0; - output_eth_payload_tvalid_int = 1; - output_eth_payload_tlast_int = 1; - output_eth_payload_tuser_int = save_axis_tuser_reg; - - if (output_eth_payload_tready_int) begin - flush_save = 1; - input_axis_tready_next = ~output_eth_hdr_valid_reg; - state_next = STATE_IDLE; - end else begin - state_next = STATE_READ_PAYLOAD_LAST; - end - end endcase end @@ -281,7 +280,6 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg <= 0; save_axis_tdata_reg <= 0; save_axis_tkeep_reg <= 0; - save_axis_tvalid_reg <= 0; save_axis_tlast_reg <= 0; save_axis_tuser_reg <= 0; busy_reg <= 0; @@ -322,13 +320,11 @@ always @(posedge clk or posedge rst) begin if (flush_save) begin save_axis_tdata_reg <= 0; save_axis_tkeep_reg <= 0; - save_axis_tvalid_reg <= 0; save_axis_tlast_reg <= 0; save_axis_tuser_reg <= 0; end else if (transfer_in_save) begin save_axis_tdata_reg <= input_axis_tdata; save_axis_tkeep_reg <= input_axis_tkeep; - save_axis_tvalid_reg <= input_axis_tvalid; save_axis_tlast_reg <= input_axis_tlast; save_axis_tuser_reg <= input_axis_tuser; end diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index 0dc5426da..c420d2029 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -133,14 +133,12 @@ always @* begin frame_ptr_next = 0; input_eth_hdr_ready_next = 1; - if (input_eth_hdr_valid) begin + if (input_eth_hdr_ready & input_eth_hdr_valid) begin store_eth_hdr = 1; input_eth_hdr_ready_next = 0; if (output_axis_tready_int) begin output_axis_tvalid_int = 1; output_axis_tdata_int = input_eth_dest_mac[47:40]; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; frame_ptr_next = 1; end state_next = STATE_WRITE_HEADER; diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index 194f900ab..5b351f027 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -84,8 +84,7 @@ localparam [2:0] STATE_IDLE = 3'd0, STATE_WRITE_HEADER = 3'd1, STATE_WRITE_HEADER_LAST = 3'd2, - STATE_WRITE_PAYLOAD = 3'd3, - STATE_WRITE_PAYLOAD_LAST = 3'd4; + STATE_WRITE_PAYLOAD = 3'd3; reg [2:0] state_reg = STATE_IDLE, state_next; @@ -108,10 +107,17 @@ reg busy_reg = 0; reg [63:0] save_eth_payload_tdata_reg = 0; reg [7:0] save_eth_payload_tkeep_reg = 0; -reg save_eth_payload_tvalid_reg = 0; reg save_eth_payload_tlast_reg = 0; reg save_eth_payload_tuser_reg = 0; +reg [63:0] shift_eth_payload_tdata; +reg [7:0] shift_eth_payload_tkeep; +reg shift_eth_payload_tvalid; +reg shift_eth_payload_tlast; +reg shift_eth_payload_tuser; +reg shift_eth_payload_input_tready; +reg shift_eth_payload_extra_cycle; + // internal datapath reg [63:0] output_axis_tdata_int; reg [7:0] output_axis_tkeep_int; @@ -126,6 +132,28 @@ assign input_eth_payload_tready = input_eth_payload_tready_reg; assign busy = busy_reg; +always @* begin + shift_eth_payload_tdata[47:0] = save_eth_payload_tdata_reg[63:16]; + shift_eth_payload_tkeep[5:0] = save_eth_payload_tkeep_reg[7:2]; + shift_eth_payload_extra_cycle = save_eth_payload_tlast_reg & (save_eth_payload_tkeep_reg[7:2] != 0); + + if (shift_eth_payload_extra_cycle) begin + shift_eth_payload_tdata[63:48] = 0; + shift_eth_payload_tkeep[7:6] = 0; + shift_eth_payload_tvalid = 1; + shift_eth_payload_tlast = save_eth_payload_tlast_reg; + shift_eth_payload_tuser = save_eth_payload_tuser_reg; + shift_eth_payload_input_tready = flush_save; + end else begin + shift_eth_payload_tdata[63:48] = input_eth_payload_tdata[15:0]; + shift_eth_payload_tkeep[7:6] = input_eth_payload_tkeep[1:0]; + shift_eth_payload_tvalid = input_eth_payload_tvalid; + shift_eth_payload_tlast = (input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0)); + shift_eth_payload_tuser = (input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0)); + shift_eth_payload_input_tready = ~(input_eth_payload_tlast & input_eth_payload_tvalid & transfer_in_save); + end +end + always @* begin state_next = 2'bz; @@ -152,7 +180,7 @@ always @* begin flush_save = 1; input_eth_hdr_ready_next = 1; - if (input_eth_hdr_valid) begin + if (input_eth_hdr_ready & input_eth_hdr_valid) begin store_eth_hdr = 1; input_eth_hdr_ready_next = 0; state_next = STATE_WRITE_HEADER; @@ -167,8 +195,6 @@ always @* begin output_axis_tdata_int[55:48] = input_eth_src_mac[47:40]; output_axis_tdata_int[63:56] = input_eth_src_mac[39:32]; output_axis_tkeep_int = 8'hff; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; frame_ptr_next = 8; input_eth_payload_tready_next = output_axis_tready_int_early; state_next = STATE_WRITE_HEADER_LAST; @@ -194,9 +220,7 @@ always @* begin output_axis_tdata_int[55:48] = input_eth_src_mac[47:40]; output_axis_tdata_int[63:56] = input_eth_src_mac[39:32]; output_axis_tkeep_int = 8'hff; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; - input_eth_payload_tready_next = output_axis_tready_int_early; + input_eth_payload_tready_next = output_axis_tready_int_early & shift_eth_payload_input_tready; state_next = STATE_WRITE_HEADER_LAST; end endcase @@ -206,9 +230,9 @@ always @* begin end STATE_WRITE_HEADER_LAST: begin // last header word requires first payload word; process accordingly - input_eth_payload_tready_next = output_axis_tready_int_early; + input_eth_payload_tready_next = output_axis_tready_int_early & shift_eth_payload_input_tready; - if (input_eth_payload_tready & input_eth_payload_tvalid) begin + if (input_eth_payload_tready & shift_eth_payload_tvalid) begin frame_ptr_next = frame_ptr_reg + 8; output_axis_tvalid_int = 1; transfer_in_save = 1; @@ -219,21 +243,17 @@ always @* begin output_axis_tdata_int[31:24] = eth_src_mac_reg[ 7: 0]; output_axis_tdata_int[39:32] = eth_type_reg[15: 8]; output_axis_tdata_int[47:40] = eth_type_reg[ 7: 0]; - output_axis_tdata_int[55:48] = input_eth_payload_tdata[ 7: 0]; - output_axis_tdata_int[63:56] = input_eth_payload_tdata[15: 8]; - output_axis_tkeep_int = {input_eth_payload_tkeep[1:0], 6'h3F}; - output_axis_tlast_int = (input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0)); - output_axis_tuser_int = (input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0)); + output_axis_tdata_int[55:48] = shift_eth_payload_tdata[55:48]; + output_axis_tdata_int[63:56] = shift_eth_payload_tdata[63:56]; + output_axis_tkeep_int = {shift_eth_payload_tkeep[7:6], 6'h3F}; + output_axis_tlast_int = shift_eth_payload_tlast; + output_axis_tuser_int = shift_eth_payload_tuser; - if (input_eth_payload_tlast) begin + if (shift_eth_payload_tlast) begin input_eth_payload_tready_next = 0; - if (input_eth_payload_tkeep[7:2] != 0) begin - state_next = STATE_WRITE_PAYLOAD_LAST; - end else begin - flush_save = 1; - input_eth_hdr_ready_next = 1; - state_next = STATE_IDLE; - end + flush_save = 1; + input_eth_hdr_ready_next = 1; + state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; end @@ -243,29 +263,22 @@ always @* begin end STATE_WRITE_PAYLOAD: begin // write payload - input_eth_payload_tready_next = output_axis_tready_int_early; + input_eth_payload_tready_next = output_axis_tready_int_early & shift_eth_payload_input_tready; - output_axis_tdata_int[47:0] = save_eth_payload_tdata_reg[63:16]; - output_axis_tkeep_int[5:0] = save_eth_payload_tkeep_reg[7:2]; + output_axis_tdata_int = shift_eth_payload_tdata; + output_axis_tkeep_int = shift_eth_payload_tkeep; + output_axis_tvalid_int = shift_eth_payload_tvalid; + output_axis_tlast_int = shift_eth_payload_tlast; + output_axis_tuser_int = shift_eth_payload_tuser; - output_axis_tdata_int[63:48] = input_eth_payload_tdata[15:0]; - output_axis_tkeep_int[7:6] = input_eth_payload_tkeep[1:0]; - output_axis_tvalid_int = input_eth_payload_tvalid; - output_axis_tlast_int = (input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0)); - output_axis_tuser_int = (input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0)); - - if (input_eth_payload_tready & input_eth_payload_tvalid) begin + if (output_axis_tready_int & shift_eth_payload_tvalid) begin // word transfer through transfer_in_save = 1; - if (input_eth_payload_tlast) begin + if (shift_eth_payload_tlast) begin input_eth_payload_tready_next = 0; - if (input_eth_payload_tkeep[7:2] != 0) begin - state_next = STATE_WRITE_PAYLOAD_LAST; - end else begin - flush_save = 1; - input_eth_hdr_ready_next = 1; - state_next = STATE_IDLE; - end + flush_save = 1; + input_eth_hdr_ready_next = 1; + state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; end @@ -273,27 +286,6 @@ always @* begin state_next = STATE_WRITE_PAYLOAD; end end - STATE_WRITE_PAYLOAD_LAST: begin - // read last payload word from save reg - input_eth_payload_tready_next = 0; - - output_axis_tdata_int[47:0] = save_eth_payload_tdata_reg[63:16]; - output_axis_tkeep_int[5:0] = save_eth_payload_tkeep_reg[7:2]; - - output_axis_tdata_int[63:48] = 0; - output_axis_tkeep_int[7:6] = 0; - output_axis_tvalid_int = 1; - output_axis_tlast_int = 1; - output_axis_tuser_int = save_eth_payload_tuser_reg; - - if (output_axis_tready_int) begin - flush_save = 1; - input_eth_hdr_ready_next = 1; - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_PAYLOAD_LAST; - end - end endcase end @@ -308,7 +300,6 @@ always @(posedge clk or posedge rst) begin eth_type_reg <= 0; save_eth_payload_tdata_reg <= 0; save_eth_payload_tkeep_reg <= 0; - save_eth_payload_tvalid_reg <= 0; save_eth_payload_tlast_reg <= 0; save_eth_payload_tuser_reg <= 0; busy_reg <= 0; @@ -333,13 +324,11 @@ always @(posedge clk or posedge rst) begin if (flush_save) begin save_eth_payload_tdata_reg <= 0; save_eth_payload_tkeep_reg <= 0; - save_eth_payload_tvalid_reg <= 0; save_eth_payload_tlast_reg <= 0; save_eth_payload_tuser_reg <= 0; end else if (transfer_in_save) begin save_eth_payload_tdata_reg <= input_eth_payload_tdata; save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; - save_eth_payload_tvalid_reg <= input_eth_payload_tvalid; save_eth_payload_tlast_reg <= input_eth_payload_tlast; save_eth_payload_tuser_reg <= input_eth_payload_tuser; end From 867b799ecde98d51544cb1a328e638aecceb7f1d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Oct 2014 01:00:52 -0700 Subject: [PATCH 065/617] Rework IP datapath modules to separate output register --- rtl/ip_eth_rx.v | 344 ++++++++++-------------- rtl/ip_eth_rx_64.v | 435 +++++++++++++----------------- rtl/ip_eth_tx.v | 409 ++++++++++++---------------- rtl/ip_eth_tx_64.v | 658 ++++++++++++++++----------------------------- 4 files changed, 748 insertions(+), 1098 deletions(-) diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index 61ebed589..a1955ed25 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -109,21 +109,19 @@ IP Frame options (IHL-5)*4 octets payload length octets -This module receives an Ethernet frame with decoded fields and decodes -the AXI packet format. If the Ethertype does not match, the packet is -discarded. +This module receives an Ethernet frame with header fields in parallel and +payload on an AXI stream interface, decodes and strips the IP header fields, +then produces the header fields in parallel along with the IP payload in a +separate AXI stream. */ localparam [2:0] STATE_IDLE = 3'd0, STATE_READ_HEADER = 3'd1, - STATE_READ_PAYLOAD_IDLE = 3'd2, - STATE_READ_PAYLOAD_TRANSFER = 3'd3, - STATE_READ_PAYLOAD_TRANSFER_WAIT = 3'd4, - STATE_READ_PAYLOAD_TRANSFER_LAST = 3'd5, - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST = 3'd6, - STATE_WAIT_LAST = 3'd7; + STATE_READ_PAYLOAD = 3'd2, + STATE_READ_PAYLOAD_LAST = 3'd3, + STATE_WAIT_LAST = 3'd4; reg [2:0] state_reg = STATE_IDLE, state_next; @@ -149,20 +147,16 @@ reg store_ip_dest_ip_0; reg store_ip_dest_ip_1; reg store_ip_dest_ip_2; reg store_ip_dest_ip_3; - -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - -reg assert_tlast; -reg assert_tuser; +reg store_last_word; reg [15:0] frame_ptr_reg = 0, frame_ptr_next; reg [15:0] hdr_sum_reg = 0, hdr_sum_next; -reg input_eth_hdr_ready_reg = 0; -reg input_eth_payload_tready_reg = 0; +reg [7:0] last_word_data_reg = 0; + +reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; @@ -181,10 +175,6 @@ reg [7:0] output_ip_protocol_reg = 0; reg [15:0] output_ip_header_checksum_reg = 0; reg [31:0] output_ip_source_ip_reg = 0; reg [31:0] output_ip_dest_ip_reg = 0; -reg [7:0] output_ip_payload_tdata_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; reg busy_reg = 0; reg error_header_early_termination_reg = 0, error_header_early_termination_next; @@ -192,9 +182,13 @@ reg error_payload_early_termination_reg = 0, error_payload_early_termination_nex reg error_invalid_header_reg = 0, error_invalid_header_next; reg error_invalid_checksum_reg = 0, error_invalid_checksum_next; -reg [7:0] temp_ip_payload_tdata_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +// internal datapath +reg [7:0] output_ip_payload_tdata_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; @@ -216,10 +210,6 @@ assign output_ip_protocol = output_ip_protocol_reg; assign output_ip_header_checksum = output_ip_header_checksum_reg; assign output_ip_source_ip = output_ip_source_ip_reg; assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -239,12 +229,8 @@ endfunction always @* begin state_next = 2'bz; - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - assert_tlast = 0; - assert_tuser = 0; + input_eth_hdr_ready_next = 0; + input_eth_payload_tready_next = 0; store_eth_hdr = 0; store_ip_version_ihl = 0; @@ -268,6 +254,8 @@ always @* begin store_ip_dest_ip_2 = 0; store_ip_dest_ip_3 = 0; + store_last_word = 0; + frame_ptr_next = frame_ptr_reg; hdr_sum_next = hdr_sum_reg; @@ -279,14 +267,21 @@ always @* begin error_invalid_header_next = 0; error_invalid_checksum_next = 0; + output_ip_payload_tdata_int = 0; + output_ip_payload_tvalid_int = 0; + output_ip_payload_tlast_int = 0; + output_ip_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for header frame_ptr_next = 0; hdr_sum_next = 0; + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; if (input_eth_hdr_ready & input_eth_hdr_valid) begin - frame_ptr_next = 0; + input_eth_hdr_ready_next = 0; + input_eth_payload_tready_next = 1; store_eth_hdr = 1; state_next = STATE_READ_HEADER; end else begin @@ -294,8 +289,10 @@ always @* begin end end STATE_READ_HEADER: begin - // read header state - if (input_eth_payload_tvalid) begin + // read header + input_eth_payload_tready_next = 1; + + if (input_eth_payload_tready & input_eth_payload_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg+1; state_next = STATE_READ_HEADER; @@ -336,131 +333,87 @@ always @* begin state_next = STATE_WAIT_LAST; end else begin output_ip_hdr_valid_next = 1; - state_next = STATE_READ_PAYLOAD_IDLE; + input_eth_payload_tready_next = output_ip_payload_tready_int_early; + state_next = STATE_READ_PAYLOAD; end end endcase if (input_eth_payload_tlast) begin - state_next = STATE_IDLE; - output_ip_hdr_valid_next = 0; error_header_early_termination_next = 1; + output_ip_hdr_valid_next = 0; + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_eth_payload_tready_next = 0; + state_next = STATE_IDLE; end end else begin state_next = STATE_READ_HEADER; end end - STATE_READ_PAYLOAD_IDLE: begin - // idle; no data in registers - if (input_eth_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; + STATE_READ_PAYLOAD: begin + // read payload + input_eth_payload_tready_next = output_ip_payload_tready_int_early; + + output_ip_payload_tdata_int = input_eth_payload_tdata; + output_ip_payload_tvalid_int = input_eth_payload_tvalid; + output_ip_payload_tlast_int = input_eth_payload_tlast; + output_ip_payload_tuser_int = input_eth_payload_tuser; + + if (input_eth_payload_tready & input_eth_payload_tvalid) begin + // word transfer through frame_ptr_next = frame_ptr_reg+1; if (input_eth_payload_tlast) begin if (frame_ptr_next != output_ip_length_reg) begin // end of frame, but length does not match - assert_tuser = 1; + output_ip_payload_tuser_int = 1; error_payload_early_termination_next = 1; end - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_eth_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin if (frame_ptr_next == output_ip_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + store_last_word = 1; + output_ip_payload_tvalid_int = 0; + state_next = STATE_READ_PAYLOAD_LAST; end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; + state_next = STATE_READ_PAYLOAD; end end end else begin - state_next = STATE_READ_PAYLOAD_IDLE; + state_next = STATE_READ_PAYLOAD; end end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register - if (input_eth_payload_tvalid & output_ip_payload_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - frame_ptr_next = frame_ptr_reg+1; + STATE_READ_PAYLOAD_LAST: begin + // read and discard until end of frame + input_eth_payload_tready_next = output_ip_payload_tready_int_early; + + output_ip_payload_tdata_int = last_word_data_reg; + output_ip_payload_tvalid_int = input_eth_payload_tvalid & input_eth_payload_tlast; + output_ip_payload_tlast_int = input_eth_payload_tlast; + output_ip_payload_tuser_int = input_eth_payload_tuser; + + if (input_eth_payload_tready & input_eth_payload_tvalid) begin if (input_eth_payload_tlast) begin - if (frame_ptr_next != output_ip_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_eth_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin - if (frame_ptr_next == output_ip_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - end else if (~input_eth_payload_tvalid & output_ip_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_READ_PAYLOAD_IDLE; - end else if (input_eth_payload_tvalid & ~output_ip_payload_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - frame_ptr_next = frame_ptr_reg+1; - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in both output and temp registers - if (output_ip_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_ip_payload_tlast_reg) begin - if (frame_ptr_next != output_ip_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - if (frame_ptr_next == output_ip_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end + state_next = STATE_READ_PAYLOAD_LAST; end end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - if (output_ip_payload_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - if (input_eth_payload_tvalid) begin - if (input_eth_payload_tlast) begin - // assert tlast and transfer tuser - assert_tlast = 1; - assert_tuser = input_eth_payload_tuser; - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + state_next = STATE_READ_PAYLOAD_LAST; end end STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - if (input_eth_payload_tvalid) begin + // read and discard until end of frame + input_eth_payload_tready_next = 1; + + if (input_eth_payload_tready & input_eth_payload_tvalid) begin if (input_eth_payload_tlast) begin + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_eth_payload_tready_next = 0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -477,6 +430,7 @@ always @(posedge clk or posedge rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; hdr_sum_reg <= 0; + last_word_data_reg <= 0; input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 0; output_ip_hdr_valid_reg <= 0; @@ -500,9 +454,6 @@ always @(posedge clk or posedge rst) begin output_ip_payload_tvalid_reg <= 0; output_ip_payload_tlast_reg <= 0; output_ip_payload_tuser_reg <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; busy_reg <= 0; error_header_early_termination_reg <= 0; error_payload_early_termination_reg <= 0; @@ -515,6 +466,9 @@ always @(posedge clk or posedge rst) begin hdr_sum_reg <= hdr_sum_next; + input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + input_eth_payload_tready_reg <= input_eth_payload_tready_next; + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; @@ -524,58 +478,6 @@ always @(posedge clk or posedge rst) begin busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_eth_hdr_ready_reg <= ~output_ip_hdr_valid; - input_eth_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - end - STATE_READ_HEADER: begin - // read header; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_IDLE: begin - // read payload; no data in registers; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in output and temp registers; do not accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 0; - end - STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 0; - end - endcase - // datapath if (store_eth_hdr) begin output_eth_dest_mac_reg <= input_eth_dest_mac; @@ -583,6 +485,10 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg <= input_eth_type; end + if (store_last_word) begin + last_word_data_reg <= output_ip_payload_tdata_int; + end + if (store_ip_version_ihl) {output_ip_version_reg, output_ip_ihl_reg} <= input_eth_payload_tdata; if (store_ip_dscp_ecn) {output_ip_dscp_reg, output_ip_ecn_reg} <= input_eth_payload_tdata; if (store_ip_length_0) output_ip_length_reg[ 7: 0] <= input_eth_payload_tdata; @@ -603,23 +509,69 @@ always @(posedge clk or posedge rst) begin if (store_ip_dest_ip_1) output_ip_dest_ip_reg[15: 8] <= input_eth_payload_tdata; if (store_ip_dest_ip_2) output_ip_dest_ip_reg[23:16] <= input_eth_payload_tdata; if (store_ip_dest_ip_3) output_ip_dest_ip_reg[31:24] <= input_eth_payload_tdata; + end +end - if (transfer_in_out) begin - output_ip_payload_tdata_reg <= input_eth_payload_tdata; - output_ip_payload_tlast_reg <= input_eth_payload_tlast; - output_ip_payload_tuser_reg <= input_eth_payload_tuser; - end else if (transfer_in_temp) begin - temp_ip_payload_tdata_reg <= input_eth_payload_tdata; - temp_ip_payload_tlast_reg <= input_eth_payload_tlast; - temp_ip_payload_tuser_reg <= input_eth_payload_tuser; - end else if (transfer_temp_out) begin +// output datapath logic +reg [7:0] output_ip_payload_tdata_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [7:0] temp_ip_payload_tdata_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; end - - if (assert_tlast) output_ip_payload_tlast_reg <= 1; - if (assert_tuser) output_ip_payload_tuser_reg <= 1; end end diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 9696b2e71..3c32b78f1 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -111,41 +111,31 @@ IP Frame options (IHL-5)*4 octets payload length octets -This module receives an Ethernet frame with decoded fields and decodes -the AXI packet format. If the Ethertype does not match, the packet is -discarded. +This module receives an Ethernet frame with header fields in parallel and +payload on an AXI stream interface, decodes and strips the IP header fields, +then produces the header fields in parallel along with the IP payload in a +separate AXI stream. */ -localparam [3:0] - STATE_IDLE = 4'd0, - STATE_READ_HEADER = 4'd1, - STATE_READ_PAYLOAD_IDLE = 4'd2, - STATE_READ_PAYLOAD_TRANSFER = 4'd3, - STATE_READ_PAYLOAD_TRANSFER_WAIT = 4'd4, - STATE_READ_PAYLOAD_TRANSFER_LAST = 4'd5, - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST = 4'd6, - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT = 4'd7, - STATE_WAIT_LAST = 4'd8; +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_READ_HEADER = 3'd1, + STATE_READ_PAYLOAD = 3'd2, + STATE_READ_PAYLOAD_LAST = 3'd3, + STATE_WAIT_LAST = 3'd4; -reg [3:0] state_reg = STATE_IDLE, state_next; +reg [2:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_eth_hdr; reg store_hdr_word_0; reg store_hdr_word_1; reg store_hdr_word_2; +reg store_last_word; reg flush_save; reg transfer_in_save; -reg transfer_save_out; -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - -reg assert_tlast; -reg assert_tuser; -reg [7:0] tkeep_mask; reg [15:0] frame_ptr_reg = 0, frame_ptr_next; @@ -154,8 +144,11 @@ reg [15:0] hdr_sum_reg = 0, hdr_sum_next; reg [15:0] hdr_sum_temp_a_reg = 0, hdr_sum_temp_a_next; reg [15:0] hdr_sum_temp_b_reg = 0, hdr_sum_temp_b_next; -reg input_eth_hdr_ready_reg = 0; -reg input_eth_payload_tready_reg = 0; +reg [63:0] last_word_data_reg = 0; +reg [7:0] last_word_keep_reg = 0; + +reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; @@ -174,11 +167,6 @@ reg [7:0] output_ip_protocol_reg = 0; reg [15:0] output_ip_header_checksum_reg = 0; reg [31:0] output_ip_source_ip_reg = 0; reg [31:0] output_ip_dest_ip_reg = 0; -reg [63:0] output_ip_payload_tdata_reg = 0; -reg [7:0] output_ip_payload_tkeep_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; reg busy_reg = 0; reg error_header_early_termination_reg = 0, error_header_early_termination_next; @@ -186,11 +174,6 @@ reg error_payload_early_termination_reg = 0, error_payload_early_termination_nex reg error_invalid_header_reg = 0, error_invalid_header_next; reg error_invalid_checksum_reg = 0, error_invalid_checksum_next; -reg [63:0] temp_ip_payload_tdata_reg = 0; -reg [7:0] temp_ip_payload_tkeep_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; - reg [63:0] save_eth_payload_tdata_reg = 0; reg [7:0] save_eth_payload_tkeep_reg = 0; reg save_eth_payload_tlast_reg = 0; @@ -204,6 +187,15 @@ reg shift_eth_payload_tuser; reg shift_eth_payload_input_tready; reg shift_eth_payload_extra_cycle; +// internal datapath +reg [63:0] output_ip_payload_tdata_int; +reg [7:0] output_ip_payload_tkeep_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; + assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; @@ -224,11 +216,6 @@ assign output_ip_protocol = output_ip_protocol_reg; assign output_ip_header_checksum = output_ip_header_checksum_reg; assign output_ip_source_ip = output_ip_source_ip_reg; assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -293,20 +280,17 @@ always @* begin flush_save = 0; transfer_in_save = 0; - transfer_save_out = 0; - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - assert_tlast = 0; - assert_tuser = 0; - tkeep_mask = 8'hff; + input_eth_hdr_ready_next = 0; + input_eth_payload_tready_next = 0; store_eth_hdr = 0; store_hdr_word_0 = 0; store_hdr_word_1 = 0; store_hdr_word_2 = 0; + store_last_word = 0; + frame_ptr_next = frame_ptr_reg; hdr_sum_temp = 0; @@ -321,15 +305,23 @@ always @* begin error_invalid_header_next = 0; error_invalid_checksum_next = 0; + output_ip_payload_tdata_int = 0; + output_ip_payload_tkeep_int = 0; + output_ip_payload_tvalid_int = 0; + output_ip_payload_tlast_int = 0; + output_ip_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for header frame_ptr_next = 0; hdr_sum_next = 0; flush_save = 1; + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; if (input_eth_hdr_ready & input_eth_hdr_valid) begin - frame_ptr_next = 0; + input_eth_hdr_ready_next = 0; + input_eth_payload_tready_next = 1; store_eth_hdr = 1; state_next = STATE_READ_HEADER; end else begin @@ -337,7 +329,9 @@ always @* begin end end STATE_READ_HEADER: begin - // read header state + // read header + input_eth_payload_tready_next = shift_eth_payload_input_tready; + if (input_eth_payload_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg+8; @@ -374,173 +368,113 @@ always @* begin frame_ptr_next = frame_ptr_reg+4; if (output_ip_version_reg != 4 || output_ip_ihl_reg != 5) begin error_invalid_header_next = 1; + input_eth_payload_tready_next = shift_eth_payload_input_tready; state_next = STATE_WAIT_LAST; end else if (hdr_sum_next != 16'hffff) begin error_invalid_checksum_next = 1; + input_eth_payload_tready_next = shift_eth_payload_input_tready; state_next = STATE_WAIT_LAST; end else begin output_ip_hdr_valid_next = 1; - state_next = STATE_READ_PAYLOAD_IDLE; + input_eth_payload_tready_next = output_ip_payload_tready_int_early & shift_eth_payload_input_tready; + state_next = STATE_READ_PAYLOAD; end end endcase if (shift_eth_payload_tlast) begin - state_next = STATE_IDLE; - output_ip_hdr_valid_next = 0; error_header_early_termination_next = 1; error_invalid_header_next = 0; error_invalid_checksum_next = 0; + output_ip_hdr_valid_next = 0; + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_eth_payload_tready_next = 0; + state_next = STATE_IDLE; end end else begin state_next = STATE_READ_HEADER; end end - STATE_READ_PAYLOAD_IDLE: begin - // idle; no data in registers - if (shift_eth_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_save = 1; - transfer_in_out = 1; + STATE_READ_PAYLOAD: begin + // read payload + input_eth_payload_tready_next = output_ip_payload_tready_int_early & shift_eth_payload_input_tready; + + output_ip_payload_tdata_int = shift_eth_payload_tdata; + output_ip_payload_tkeep_int = shift_eth_payload_tkeep; + output_ip_payload_tvalid_int = shift_eth_payload_tvalid; + output_ip_payload_tlast_int = shift_eth_payload_tlast; + output_ip_payload_tuser_int = shift_eth_payload_tuser; + + if (output_ip_payload_tready_int & shift_eth_payload_tvalid) begin + // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_tkeep); + transfer_in_save = 1; if (frame_ptr_next >= output_ip_length_reg) begin // have entire payload frame_ptr_next = output_ip_length_reg; - tkeep_mask = count2keep(output_ip_length_reg - frame_ptr_reg); + output_ip_payload_tkeep_int = shift_eth_payload_tkeep & count2keep(output_ip_length_reg - frame_ptr_reg); if (shift_eth_payload_tlast) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + input_eth_payload_tready_next = 0; + flush_save = 1; + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + state_next = STATE_IDLE; end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + store_last_word = 1; + output_ip_payload_tvalid_int = 0; + state_next = STATE_READ_PAYLOAD_LAST; end end else begin if (shift_eth_payload_tlast) begin // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; error_payload_early_termination_next = 1; - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + output_ip_payload_tuser_int = 1; + input_eth_payload_tready_next = 0; + flush_save = 1; + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + state_next = STATE_IDLE; end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; + state_next = STATE_READ_PAYLOAD; end end end else begin - state_next = STATE_READ_PAYLOAD_IDLE; + state_next = STATE_READ_PAYLOAD; end end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register - if (shift_eth_payload_tvalid & output_ip_payload_tready) begin - // word transfer through - update output register - transfer_in_save = 1; - transfer_in_out = 1; - frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_tkeep); - if (frame_ptr_next >= output_ip_length_reg) begin - // have entire payload - frame_ptr_next = output_ip_length_reg; - tkeep_mask = count2keep(output_ip_length_reg - frame_ptr_reg); - if (shift_eth_payload_tlast) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end - end else begin - if (shift_eth_payload_tlast) begin - // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; - error_payload_early_termination_next = 1; - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - end else if (~shift_eth_payload_tvalid & output_ip_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_READ_PAYLOAD_IDLE; - end else if (shift_eth_payload_tvalid & ~output_ip_payload_tready) begin - // word transfer in - store in temp - transfer_in_save = 1; - transfer_in_temp = 1; - frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_tkeep); - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - if (frame_ptr_next >= output_ip_length_reg) begin - // have entire payload - frame_ptr_next = output_ip_length_reg; - tkeep_mask = count2keep(output_ip_length_reg - frame_ptr_reg); - if (~shift_eth_payload_tlast) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; - end - end - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in both output and temp registers - if (output_ip_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_ip_payload_tlast_reg) begin - if (frame_ptr_next < output_ip_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - if (frame_ptr_next >= output_ip_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - if (output_ip_payload_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - if (shift_eth_payload_tvalid) begin + STATE_READ_PAYLOAD_LAST: begin + // read and discard until end of frame + input_eth_payload_tready_next = output_ip_payload_tready_int_early & shift_eth_payload_input_tready; + + output_ip_payload_tdata_int = last_word_data_reg; + output_ip_payload_tkeep_int = last_word_keep_reg; + output_ip_payload_tvalid_int = shift_eth_payload_tvalid & shift_eth_payload_tlast; + output_ip_payload_tlast_int = shift_eth_payload_tlast; + output_ip_payload_tuser_int = shift_eth_payload_tuser; + + if (output_ip_payload_tready_int & shift_eth_payload_tvalid) begin transfer_in_save = 1; if (shift_eth_payload_tlast) begin - // assert tlast and transfer tuser - assert_tlast = 1; - assert_tuser = shift_eth_payload_tuser; - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + input_eth_payload_tready_next = 0; + flush_save = 1; + input_eth_hdr_ready_next = 1; + state_next = STATE_IDLE; end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + state_next = STATE_READ_PAYLOAD_LAST; end end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin - // wait for end of frame; data in both output and temp registers; read and discard - if (output_ip_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + state_next = STATE_READ_PAYLOAD_LAST; end end STATE_WAIT_LAST: begin - // wait for end of frame; read and discard + // read and discard until end of frame + input_eth_payload_tready_next = shift_eth_payload_input_tready; + if (shift_eth_payload_tvalid) begin transfer_in_save = 1; if (shift_eth_payload_tlast) begin + input_eth_payload_tready_next = 0; + flush_save = 1; + input_eth_hdr_ready_next = 1; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -559,6 +493,8 @@ always @(posedge clk or posedge rst) begin hdr_sum_reg <= 0; hdr_sum_temp_a_reg <= 0; hdr_sum_temp_b_reg <= 0; + last_word_data_reg <= 0; + last_word_keep_reg <= 0; input_eth_hdr_ready_reg <= 0; input_eth_payload_tready_reg <= 0; output_ip_hdr_valid_reg <= 0; @@ -582,9 +518,10 @@ always @(posedge clk or posedge rst) begin output_ip_payload_tvalid_reg <= 0; output_ip_payload_tlast_reg <= 0; output_ip_payload_tuser_reg <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + save_eth_payload_tdata_reg <= 0; + save_eth_payload_tkeep_reg <= 0; + save_eth_payload_tlast_reg <= 0; + save_eth_payload_tuser_reg <= 0; busy_reg <= 0; error_header_early_termination_reg <= 0; error_payload_early_termination_reg <= 0; @@ -599,6 +536,9 @@ always @(posedge clk or posedge rst) begin hdr_sum_temp_a_reg <= hdr_sum_temp_a_next; hdr_sum_temp_b_reg <= hdr_sum_temp_b_next; + input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + input_eth_payload_tready_reg <= input_eth_payload_tready_next; + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; @@ -608,64 +548,6 @@ always @(posedge clk or posedge rst) begin busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_eth_hdr_ready_reg <= ~output_ip_hdr_valid; - input_eth_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - end - STATE_READ_HEADER: begin - // read header; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= shift_eth_payload_input_tready; - output_ip_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_IDLE: begin - // read payload; no data in registers; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= shift_eth_payload_input_tready; - output_ip_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= shift_eth_payload_input_tready; - output_ip_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in output and temp registers; do not accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= shift_eth_payload_input_tready; - output_ip_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin - // wait for end of frame; data in output and temp registers; do not accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= shift_eth_payload_input_tready; - output_ip_payload_tvalid_reg <= 0; - end - endcase - // datapath if (store_eth_hdr) begin output_eth_dest_mac_reg <= input_eth_dest_mac; @@ -673,6 +555,11 @@ always @(posedge clk or posedge rst) begin output_eth_type_reg <= input_eth_type; end + if (store_last_word) begin + last_word_data_reg <= output_ip_payload_tdata_int; + last_word_keep_reg <= output_ip_payload_tkeep_int; + end + if (store_hdr_word_0) begin {output_ip_version_reg, output_ip_ihl_reg} <= input_eth_payload_tdata[ 7: 0]; {output_ip_dscp_reg, output_ip_ecn_reg} <= input_eth_payload_tdata[15: 8]; @@ -702,37 +589,89 @@ always @(posedge clk or posedge rst) begin output_ip_dest_ip_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; end - if (transfer_in_out) begin - output_ip_payload_tdata_reg <= shift_eth_payload_tdata; - output_ip_payload_tkeep_reg <= shift_eth_payload_tkeep & tkeep_mask; - output_ip_payload_tlast_reg <= shift_eth_payload_tlast; - output_ip_payload_tuser_reg <= shift_eth_payload_tuser; - end else if (transfer_in_temp) begin - temp_ip_payload_tdata_reg <= shift_eth_payload_tdata; - temp_ip_payload_tkeep_reg <= shift_eth_payload_tkeep & tkeep_mask; - temp_ip_payload_tlast_reg <= shift_eth_payload_tlast; - temp_ip_payload_tuser_reg <= shift_eth_payload_tuser; - end else if (transfer_temp_out) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - if (flush_save) begin save_eth_payload_tdata_reg <= 0; save_eth_payload_tkeep_reg <= 0; save_eth_payload_tlast_reg <= 0; save_eth_payload_tuser_reg <= 0; - end else if (transfer_in_save & ~shift_eth_payload_extra_cycle) begin + end else if (transfer_in_save) begin save_eth_payload_tdata_reg <= input_eth_payload_tdata; save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; save_eth_payload_tlast_reg <= input_eth_payload_tlast; save_eth_payload_tuser_reg <= input_eth_payload_tuser; end + end +end - if (assert_tlast) output_ip_payload_tlast_reg <= 1; - if (assert_tuser) output_ip_payload_tuser_reg <= 1; +// output datapath logic +reg [63:0] output_ip_payload_tdata_reg = 0; +reg [7:0] output_ip_payload_tkeep_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [63:0] temp_ip_payload_tdata_reg = 0; +reg [7:0] temp_ip_payload_tkeep_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tkeep_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end end end diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 9c58d53a6..73bf5ca59 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -103,41 +103,32 @@ IP Frame options (IHL-5)*4 octets payload length octets -This module receives an Ethernet frame with decoded fields and decodes -the AXI packet format. If the Ethertype does not match, the packet is -discarded. +This module receives an IP frame with header fields in parallel along with the +payload in an AXI stream, combines the header with the payload, passes through +the Ethernet headers, and transmits the complete Ethernet payload on an AXI +interface. */ localparam [2:0] STATE_IDLE = 3'd0, STATE_WRITE_HEADER = 3'd1, - STATE_WRITE_PAYLOAD_IDLE = 3'd2, - STATE_WRITE_PAYLOAD_TRANSFER = 3'd3, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 3'd4, - STATE_WRITE_PAYLOAD_TRANSFER_LAST = 3'd5, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST = 3'd6, - STATE_WAIT_LAST = 3'd7; + STATE_WRITE_PAYLOAD = 3'd2, + STATE_WRITE_PAYLOAD_LAST = 3'd3, + STATE_WAIT_LAST = 3'd4; reg [2:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_ip_hdr; +reg store_last_word; -reg [7:0] write_hdr_data; -reg write_hdr_out; - -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - -reg assert_tlast; -reg assert_tuser; - -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; reg [15:0] hdr_sum_reg = 0, hdr_sum_next; +reg [7:0] last_word_data_reg = 0; + reg [5:0] ip_dscp_reg = 0; reg [1:0] ip_ecn_reg = 0; reg [15:0] ip_length_reg = 0; @@ -149,24 +140,24 @@ reg [7:0] ip_protocol_reg = 0; reg [31:0] ip_source_ip_reg = 0; reg [31:0] ip_dest_ip_reg = 0; -reg input_ip_hdr_ready_reg = 0; -reg input_ip_payload_tready_reg = 0; +reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; reg [47:0] output_eth_src_mac_reg = 0; reg [15:0] output_eth_type_reg = 0; -reg [7:0] output_eth_payload_tdata_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; reg busy_reg = 0; reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; -reg [7:0] temp_eth_payload_tdata_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +// internal datapath +reg [7:0] output_eth_payload_tdata_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = input_ip_payload_tready_reg; @@ -175,10 +166,6 @@ assign output_eth_hdr_valid = output_eth_hdr_valid_reg; assign output_eth_dest_mac = output_eth_dest_mac_reg; assign output_eth_src_mac = output_eth_src_mac_reg; assign output_eth_type = output_eth_type_reg; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; assign busy = busy_reg; assign error_payload_early_termination = error_payload_early_termination_reg; @@ -195,17 +182,12 @@ endfunction always @* begin state_next = 2'bz; + input_ip_hdr_ready_next = 0; + input_ip_payload_tready_next = 0; + store_ip_hdr = 0; - write_hdr_data = 0; - write_hdr_out = 0; - - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - assert_tlast = 0; - assert_tuser = 0; + store_last_word = 0; frame_ptr_next = frame_ptr_reg; @@ -215,194 +197,159 @@ always @* begin error_payload_early_termination_next = 0; + output_eth_payload_tdata_int = 0; + output_eth_payload_tvalid_int = 0; + output_eth_payload_tlast_int = 0; + output_eth_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - if (input_ip_hdr_valid & input_ip_hdr_ready) begin + if (input_ip_hdr_ready & input_ip_hdr_valid) begin store_ip_hdr = 1; - write_hdr_out = 1; - write_hdr_data = {4'd4, 4'd5}; // ip_version, ip_ihl + input_ip_hdr_ready_next = 0; output_eth_hdr_valid_next = 1; - frame_ptr_next = 1; + if (output_eth_payload_tready_int) begin + output_eth_payload_tvalid_int = 1; + output_eth_payload_tdata_int = {4'd4, 4'd5}; // ip_version, ip_ihl + frame_ptr_next = 1; + end state_next = STATE_WRITE_HEADER; end else begin state_next = STATE_IDLE; end end STATE_WRITE_HEADER: begin - // write header state - if (output_eth_payload_tready) begin - // word transfer out + // write header + if (output_eth_payload_tready_int) begin frame_ptr_next = frame_ptr_reg+1; + output_eth_payload_tvalid_int = 1; state_next = STATE_WRITE_HEADER; - write_hdr_out = 1; case (frame_ptr_reg) + 8'h00: begin + output_eth_payload_tdata_int = {4'd4, 4'd5}; // ip_version, ip_ihl + end 8'h01: begin - write_hdr_data = {ip_dscp_reg, ip_ecn_reg}; + output_eth_payload_tdata_int = {ip_dscp_reg, ip_ecn_reg}; hdr_sum_next = {4'd4, 4'd5, ip_dscp_reg, ip_ecn_reg}; end 8'h02: begin - write_hdr_data = ip_length_reg[15: 8]; + output_eth_payload_tdata_int = ip_length_reg[15: 8]; hdr_sum_next = add1c16b(hdr_sum_reg, ip_length_reg); end 8'h03: begin - write_hdr_data = ip_length_reg[ 7: 0]; + output_eth_payload_tdata_int = ip_length_reg[ 7: 0]; hdr_sum_next = add1c16b(hdr_sum_reg, ip_identification_reg); end 8'h04: begin - write_hdr_data = ip_identification_reg[15: 8]; + output_eth_payload_tdata_int = ip_identification_reg[15: 8]; hdr_sum_next = add1c16b(hdr_sum_reg, {ip_flags_reg, ip_fragment_offset_reg}); end 8'h05: begin - write_hdr_data = ip_identification_reg[ 7: 0]; + output_eth_payload_tdata_int = ip_identification_reg[ 7: 0]; hdr_sum_next = add1c16b(hdr_sum_reg, {ip_ttl_reg, ip_protocol_reg}); end 8'h06: begin - write_hdr_data = {ip_flags_reg, ip_fragment_offset_reg[12:8]}; + output_eth_payload_tdata_int = {ip_flags_reg, ip_fragment_offset_reg[12:8]}; hdr_sum_next = add1c16b(hdr_sum_reg, ip_source_ip_reg[31:16]); end 8'h07: begin - write_hdr_data = ip_fragment_offset_reg[ 7: 0]; + output_eth_payload_tdata_int = ip_fragment_offset_reg[ 7: 0]; hdr_sum_next = add1c16b(hdr_sum_reg, ip_source_ip_reg[15:0]); end 8'h08: begin - write_hdr_data = ip_ttl_reg; + output_eth_payload_tdata_int = ip_ttl_reg; hdr_sum_next = add1c16b(hdr_sum_reg, ip_dest_ip_reg[31:16]); end 8'h09: begin - write_hdr_data = ip_protocol_reg; + output_eth_payload_tdata_int = ip_protocol_reg; hdr_sum_next = add1c16b(hdr_sum_reg, ip_dest_ip_reg[15:0]); end - 8'h0A: write_hdr_data = ~hdr_sum_reg[15: 8]; - 8'h0B: write_hdr_data = ~hdr_sum_reg[ 7: 0]; - 8'h0C: write_hdr_data = ip_source_ip_reg[31:24]; - 8'h0D: write_hdr_data = ip_source_ip_reg[23:16]; - 8'h0E: write_hdr_data = ip_source_ip_reg[15: 8]; - 8'h0F: write_hdr_data = ip_source_ip_reg[ 7: 0]; - 8'h10: write_hdr_data = ip_dest_ip_reg[31:24]; - 8'h11: write_hdr_data = ip_dest_ip_reg[23:16]; - 8'h12: write_hdr_data = ip_dest_ip_reg[15: 8]; + 8'h0A: output_eth_payload_tdata_int = ~hdr_sum_reg[15: 8]; + 8'h0B: output_eth_payload_tdata_int = ~hdr_sum_reg[ 7: 0]; + 8'h0C: output_eth_payload_tdata_int = ip_source_ip_reg[31:24]; + 8'h0D: output_eth_payload_tdata_int = ip_source_ip_reg[23:16]; + 8'h0E: output_eth_payload_tdata_int = ip_source_ip_reg[15: 8]; + 8'h0F: output_eth_payload_tdata_int = ip_source_ip_reg[ 7: 0]; + 8'h10: output_eth_payload_tdata_int = ip_dest_ip_reg[31:24]; + 8'h11: output_eth_payload_tdata_int = ip_dest_ip_reg[23:16]; + 8'h12: output_eth_payload_tdata_int = ip_dest_ip_reg[15: 8]; 8'h13: begin - write_hdr_data = ip_dest_ip_reg[ 7: 0]; - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + output_eth_payload_tdata_int = ip_dest_ip_reg[ 7: 0]; + input_ip_payload_tready_next = output_eth_payload_tready_int_early; + state_next = STATE_WRITE_PAYLOAD; end endcase end else begin state_next = STATE_WRITE_HEADER; end end - STATE_WRITE_PAYLOAD_IDLE: begin - // idle; no data in registers - if (input_ip_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; + STATE_WRITE_PAYLOAD: begin + // write payload + input_ip_payload_tready_next = output_eth_payload_tready_int_early; + + output_eth_payload_tdata_int = input_ip_payload_tdata; + output_eth_payload_tvalid_int = input_ip_payload_tvalid; + output_eth_payload_tlast_int = input_ip_payload_tlast; + output_eth_payload_tuser_int = input_ip_payload_tuser; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin + // word transfer through frame_ptr_next = frame_ptr_reg+1; if (input_ip_payload_tlast) begin if (frame_ptr_next != ip_length_reg) begin // end of frame, but length does not match - assert_tuser = 1; + output_eth_payload_tuser_int = 1; error_payload_early_termination_next = 1; end - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + input_ip_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin if (frame_ptr_next == ip_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + store_last_word = 1; + output_eth_payload_tvalid_int = 0; + state_next = STATE_WRITE_PAYLOAD_LAST; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + state_next = STATE_WRITE_PAYLOAD; end end end else begin - state_next = STATE_WRITE_PAYLOAD_IDLE; + state_next = STATE_WRITE_PAYLOAD; end end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register - if (input_ip_payload_tvalid & output_eth_payload_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - frame_ptr_next = frame_ptr_reg+1; + STATE_WRITE_PAYLOAD_LAST: begin + // read and discard until end of frame + input_ip_payload_tready_next = output_eth_payload_tready_int_early; + + output_eth_payload_tdata_int = last_word_data_reg; + output_eth_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tlast; + output_eth_payload_tlast_int = input_ip_payload_tlast; + output_eth_payload_tuser_int = input_ip_payload_tuser; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin - if (frame_ptr_next != ip_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + input_ip_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin - if (frame_ptr_next == ip_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - end else if (~input_ip_payload_tvalid & output_eth_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_WRITE_PAYLOAD_IDLE; - end else if (input_ip_payload_tvalid & ~output_eth_payload_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - frame_ptr_next = frame_ptr_reg+1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in both output and temp registers - if (output_eth_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_eth_payload_tlast_reg) begin - if (frame_ptr_next != ip_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - if (frame_ptr_next == ip_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end + state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - if (output_eth_payload_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - if (input_ip_payload_tvalid) begin - if (input_ip_payload_tlast) begin - // assert tlast and transfer tuser - assert_tlast = 1; - assert_tuser = input_ip_payload_tuser; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + state_next = STATE_WRITE_PAYLOAD_LAST; end end STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - if (input_ip_payload_tvalid) begin + // read and discard until end of frame + input_ip_payload_tready_next = 1; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin + input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + input_ip_payload_tready_next = 0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -419,6 +366,7 @@ always @(posedge clk or posedge rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; hdr_sum_reg <= 0; + last_word_data_reg <= 0; input_ip_hdr_ready_reg <= 0; input_ip_payload_tready_reg <= 0; ip_dscp_reg <= 0; @@ -435,13 +383,6 @@ always @(posedge clk or posedge rst) begin output_eth_dest_mac_reg <= 0; output_eth_src_mac_reg <= 0; output_eth_type_reg <= 0; - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; busy_reg <= 0; error_payload_early_termination_reg <= 0; end else begin @@ -451,64 +392,16 @@ always @(posedge clk or posedge rst) begin hdr_sum_reg <= hdr_sum_next; + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + input_ip_payload_tready_reg <= input_ip_payload_tready_next; + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; error_payload_early_termination_reg <= error_payload_early_termination_next; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_ip_hdr_ready_reg <= 1; - input_ip_payload_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - end - STATE_WRITE_HEADER: begin - // write header - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_IDLE: begin - // write payload; no data in registers; accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_eth_payload_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register; accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in output and temp registers; do not accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_eth_payload_tvalid_reg <= 0; - end - STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_eth_payload_tvalid_reg <= 0; - end - endcase - + // datapath if (store_ip_hdr) begin output_eth_dest_mac_reg <= input_eth_dest_mac; output_eth_src_mac_reg <= input_eth_src_mac; @@ -525,26 +418,72 @@ always @(posedge clk or posedge rst) begin ip_dest_ip_reg <= input_ip_dest_ip; end - if (write_hdr_out) begin - output_eth_payload_tdata_reg <= write_hdr_data; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - end else if (transfer_in_out) begin - output_eth_payload_tdata_reg <= input_ip_payload_tdata; - output_eth_payload_tlast_reg <= input_ip_payload_tlast; - output_eth_payload_tuser_reg <= input_ip_payload_tuser; - end else if (transfer_in_temp) begin - temp_eth_payload_tdata_reg <= input_ip_payload_tdata; - temp_eth_payload_tlast_reg <= input_ip_payload_tlast; - temp_eth_payload_tuser_reg <= input_ip_payload_tuser; - end else if (transfer_temp_out) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + if (store_last_word) begin + last_word_data_reg <= output_eth_payload_tdata_int; end + end +end - if (assert_tlast) output_eth_payload_tlast_reg <= 1; - if (assert_tuser) output_eth_payload_tuser_reg <= 1; +// output datapath logic +reg [7:0] output_eth_payload_tdata_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_eth_payload_tdata_int; + temp_axis_tvalid_reg <= output_eth_payload_tvalid_int; + temp_axis_tlast_reg <= output_eth_payload_tlast_int; + temp_axis_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_axis_tdata_reg; + output_eth_payload_tvalid_reg <= temp_axis_tvalid_reg; + output_eth_payload_tlast_reg <= temp_axis_tlast_reg; + output_eth_payload_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end end end diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 1a59a61e0..2d72eb599 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -105,53 +105,38 @@ IP Frame options (IHL-5)*4 octets payload length octets -This module receives an Ethernet frame with decoded fields and decodes -the AXI packet format. If the Ethertype does not match, the packet is -discarded. +This module receives an IP frame with header fields in parallel along with the +payload in an AXI stream, combines the header with the payload, passes through +the Ethernet headers, and transmits the complete Ethernet payload on an AXI +interface. */ -localparam [3:0] - STATE_IDLE = 4'd0, - STATE_WRITE_HEADER = 4'd1, - STATE_WRITE_HEADER_LAST = 4'd2, - STATE_WRITE_HEADER_LAST_WAIT = 4'd3, - STATE_WRITE_PAYLOAD_IDLE = 4'd4, - STATE_WRITE_PAYLOAD_TRANSFER = 4'd5, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 4'd6, - STATE_WRITE_PAYLOAD_TRANSFER_LAST = 4'd7, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST = 4'd8, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT = 4'd9, - STATE_WAIT_LAST = 4'd10; +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_WRITE_HEADER = 3'd1, + STATE_WRITE_HEADER_LAST = 3'd2, + STATE_WRITE_PAYLOAD = 3'd3, + STATE_WRITE_PAYLOAD_LAST = 3'd4, + STATE_WAIT_LAST = 3'd5; -reg [3:0] state_reg = STATE_IDLE, state_next; +reg [2:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_ip_hdr; +reg store_last_word; -reg [63:0] write_hdr_data; -reg [7:0] write_hdr_keep; -reg write_hdr_last; -reg write_hdr_user; -reg write_hdr_out; -reg write_hdr_temp; +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; reg flush_save; reg transfer_in_save; -reg transfer_save_out; -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - -reg assert_tlast; -reg assert_tuser; -reg [7:0] tkeep_mask; - -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; reg [31:0] hdr_sum_temp; reg [15:0] hdr_sum_reg = 0, hdr_sum_next; +reg [63:0] last_word_data_reg = 0; +reg [7:0] last_word_keep_reg = 0; + reg [5:0] ip_dscp_reg = 0; reg [1:0] ip_ecn_reg = 0; reg [15:0] ip_length_reg = 0; @@ -163,27 +148,17 @@ reg [7:0] ip_protocol_reg = 0; reg [31:0] ip_source_ip_reg = 0; reg [31:0] ip_dest_ip_reg = 0; -reg input_ip_hdr_ready_reg = 0; -reg input_ip_payload_tready_reg = 0; +reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; reg [47:0] output_eth_src_mac_reg = 0; reg [15:0] output_eth_type_reg = 0; -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; reg busy_reg = 0; reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; -reg [63:0] temp_eth_payload_tdata_reg = 0; -reg [7:0] temp_eth_payload_tkeep_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; - reg [63:0] save_ip_payload_tdata_reg = 0; reg [7:0] save_ip_payload_tkeep_reg = 0; reg save_ip_payload_tlast_reg = 0; @@ -197,6 +172,15 @@ reg shift_ip_payload_tuser; reg shift_ip_payload_input_tready; reg shift_ip_payload_extra_cycle; +// internal datapath +reg [63:0] output_eth_payload_tdata_int; +reg [7:0] output_eth_payload_tkeep_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = input_ip_payload_tready_reg; @@ -204,11 +188,6 @@ assign output_eth_hdr_valid = output_eth_hdr_valid_reg; assign output_eth_dest_mac = output_eth_dest_mac_reg; assign output_eth_src_mac = output_eth_src_mac_reg; assign output_eth_type = output_eth_type_reg; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; assign busy = busy_reg; assign error_payload_early_termination = error_payload_early_termination_reg; @@ -261,32 +240,22 @@ always @* begin shift_ip_payload_tvalid = input_ip_payload_tvalid; shift_ip_payload_tlast = (input_ip_payload_tlast & (input_ip_payload_tkeep[7:4] == 0)); shift_ip_payload_tuser = (input_ip_payload_tuser & (input_ip_payload_tkeep[7:4] == 0)); - shift_ip_payload_input_tready = ~(input_ip_payload_tlast & input_ip_payload_tvalid & transfer_in_save); + shift_ip_payload_input_tready = ~(input_ip_payload_tlast & input_ip_payload_tvalid & transfer_in_save) & ~save_ip_payload_tlast_reg; end end always @* begin state_next = 2'bz; + input_ip_hdr_ready_next = 0; + input_ip_payload_tready_next = 0; + store_ip_hdr = 0; - write_hdr_data = 0; - write_hdr_keep = 0; - write_hdr_last = 0; - write_hdr_user = 0; - write_hdr_out = 0; - write_hdr_temp = 0; + store_last_word = 0; flush_save = 0; transfer_in_save = 0; - transfer_save_out = 0; - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - assert_tlast = 0; - assert_tuser = 0; - tkeep_mask = 8'hff; frame_ptr_next = frame_ptr_reg; @@ -297,13 +266,20 @@ always @* begin error_payload_early_termination_next = 0; + output_eth_payload_tdata_int = 0; + output_eth_payload_tkeep_int = 0; + output_eth_payload_tvalid_int = 0; + output_eth_payload_tlast_int = 0; + output_eth_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; flush_save = 1; + input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - if (input_ip_hdr_valid & input_ip_hdr_ready) begin + if (input_ip_hdr_ready & input_ip_hdr_valid) begin store_ip_hdr = 1; hdr_sum_temp = {4'd4, 4'd5, input_ip_dscp, input_ip_ecn} + input_ip_length + @@ -312,31 +288,44 @@ always @* begin {input_ip_ttl, input_ip_protocol}; hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; hdr_sum_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; - write_hdr_out = 1; - write_hdr_data[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl - write_hdr_data[15: 8] = {input_ip_dscp, input_ip_ecn}; - write_hdr_data[23:16] = input_ip_length[15: 8]; - write_hdr_data[31:24] = input_ip_length[ 7: 0]; - write_hdr_data[39:32] = input_ip_identification[15: 8]; - write_hdr_data[47:40] = input_ip_identification[ 7: 0]; - write_hdr_data[55:48] = {input_ip_flags, input_ip_fragment_offset[12: 8]}; - write_hdr_data[63:56] = input_ip_fragment_offset[ 7: 0]; - write_hdr_keep = 8'hff; + input_ip_hdr_ready_next = 0; output_eth_hdr_valid_next = 1; - frame_ptr_next = 8; + if (output_eth_payload_tready_int) begin + output_eth_payload_tvalid_int = 1; + output_eth_payload_tdata_int[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl + output_eth_payload_tdata_int[15: 8] = {input_ip_dscp, input_ip_ecn}; + output_eth_payload_tdata_int[23:16] = input_ip_length[15: 8]; + output_eth_payload_tdata_int[31:24] = input_ip_length[ 7: 0]; + output_eth_payload_tdata_int[39:32] = input_ip_identification[15: 8]; + output_eth_payload_tdata_int[47:40] = input_ip_identification[ 7: 0]; + output_eth_payload_tdata_int[55:48] = {input_ip_flags, input_ip_fragment_offset[12: 8]}; + output_eth_payload_tdata_int[63:56] = input_ip_fragment_offset[ 7: 0]; + output_eth_payload_tkeep_int = 8'hff; + frame_ptr_next = 8; + end state_next = STATE_WRITE_HEADER; end else begin state_next = STATE_IDLE; end end STATE_WRITE_HEADER: begin - // write header state - if (output_eth_payload_tready) begin - // word transfer out + // write header + if (output_eth_payload_tready_int) begin frame_ptr_next = frame_ptr_reg+8; + output_eth_payload_tvalid_int = 1; state_next = STATE_WRITE_HEADER; - write_hdr_out = 1; case (frame_ptr_reg) + 8'h00: begin + output_eth_payload_tdata_int[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl + output_eth_payload_tdata_int[15: 8] = {input_ip_dscp, input_ip_ecn}; + output_eth_payload_tdata_int[23:16] = input_ip_length[15: 8]; + output_eth_payload_tdata_int[31:24] = input_ip_length[ 7: 0]; + output_eth_payload_tdata_int[39:32] = input_ip_identification[15: 8]; + output_eth_payload_tdata_int[47:40] = input_ip_identification[ 7: 0]; + output_eth_payload_tdata_int[55:48] = {input_ip_flags, input_ip_fragment_offset[12: 8]}; + output_eth_payload_tdata_int[63:56] = input_ip_fragment_offset[ 7: 0]; + output_eth_payload_tkeep_int = 8'hff; + end 8'h08: begin hdr_sum_temp = hdr_sum_reg + ip_source_ip_reg[31:16] + @@ -345,15 +334,16 @@ always @* begin ip_dest_ip_reg[15: 0]; hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; hdr_sum_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; - write_hdr_data[ 7: 0] = ip_ttl_reg; - write_hdr_data[15: 8] = ip_protocol_reg; - write_hdr_data[23:16] = ~hdr_sum_next[15: 8]; - write_hdr_data[31:24] = ~hdr_sum_next[ 7: 0]; - write_hdr_data[39:32] = ip_source_ip_reg[31:24]; - write_hdr_data[47:40] = ip_source_ip_reg[23:16]; - write_hdr_data[55:48] = ip_source_ip_reg[15: 8]; - write_hdr_data[63:56] = ip_source_ip_reg[ 7: 0]; - write_hdr_keep = 8'hff; + output_eth_payload_tdata_int[ 7: 0] = ip_ttl_reg; + output_eth_payload_tdata_int[15: 8] = ip_protocol_reg; + output_eth_payload_tdata_int[23:16] = ~hdr_sum_next[15: 8]; + output_eth_payload_tdata_int[31:24] = ~hdr_sum_next[ 7: 0]; + output_eth_payload_tdata_int[39:32] = ip_source_ip_reg[31:24]; + output_eth_payload_tdata_int[47:40] = ip_source_ip_reg[23:16]; + output_eth_payload_tdata_int[55:48] = ip_source_ip_reg[15: 8]; + output_eth_payload_tdata_int[63:56] = ip_source_ip_reg[ 7: 0]; + output_eth_payload_tkeep_int = 8'hff; + input_ip_payload_tready_next = output_eth_payload_tready_int_early; state_next = STATE_WRITE_HEADER_LAST; end endcase @@ -363,272 +353,131 @@ always @* begin end STATE_WRITE_HEADER_LAST: begin // last header word requires first payload word; process accordingly - if (shift_ip_payload_tvalid & output_eth_payload_tready) begin - // word transfer through - update output register + input_ip_payload_tready_next = output_eth_payload_tready_int_early & shift_ip_payload_input_tready; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin + output_eth_payload_tvalid_int = 1; transfer_in_save = 1; - write_hdr_out = 1; - write_hdr_data[ 7: 0] = ip_dest_ip_reg[31:24]; - write_hdr_data[15: 8] = ip_dest_ip_reg[23:16]; - write_hdr_data[23:16] = ip_dest_ip_reg[15: 8]; - write_hdr_data[31:24] = ip_dest_ip_reg[ 7: 0]; - write_hdr_data[39:32] = shift_ip_payload_tdata[39:32]; - write_hdr_data[47:40] = shift_ip_payload_tdata[47:40]; - write_hdr_data[55:48] = shift_ip_payload_tdata[55:48]; - write_hdr_data[63:56] = shift_ip_payload_tdata[63:56]; - write_hdr_keep = {shift_ip_payload_tkeep[7:4], 4'hF}; - frame_ptr_next = frame_ptr_reg+keep2count(write_hdr_keep); + + output_eth_payload_tdata_int[ 7: 0] = ip_dest_ip_reg[31:24]; + output_eth_payload_tdata_int[15: 8] = ip_dest_ip_reg[23:16]; + output_eth_payload_tdata_int[23:16] = ip_dest_ip_reg[15: 8]; + output_eth_payload_tdata_int[31:24] = ip_dest_ip_reg[ 7: 0]; + output_eth_payload_tdata_int[39:32] = shift_ip_payload_tdata[39:32]; + output_eth_payload_tdata_int[47:40] = shift_ip_payload_tdata[47:40]; + output_eth_payload_tdata_int[55:48] = shift_ip_payload_tdata[55:48]; + output_eth_payload_tdata_int[63:56] = shift_ip_payload_tdata[63:56]; + output_eth_payload_tkeep_int = {shift_ip_payload_tkeep[7:4], 4'hF}; + output_eth_payload_tlast_int = shift_ip_payload_tlast; + output_eth_payload_tuser_int = shift_ip_payload_tuser; + frame_ptr_next = frame_ptr_reg+keep2count(output_eth_payload_tkeep_int); + if (frame_ptr_next >= ip_length_reg) begin // have entire payload frame_ptr_next = ip_length_reg; - tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); - write_hdr_keep = tkeep_mask; - assert_tlast = 1; - assert_tuser = input_ip_payload_tuser; + output_eth_payload_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); if (shift_ip_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + input_ip_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + store_last_word = 1; + input_ip_payload_tready_next = shift_ip_payload_input_tready; + output_eth_payload_tvalid_int = 0; + state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin if (shift_ip_payload_tlast) begin // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; error_payload_early_termination_next = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_ip_payload_tready_next = shift_ip_payload_input_tready; + output_eth_payload_tuser_int = 1; + state_next = STATE_WAIT_LAST; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - end else if (~shift_ip_payload_tvalid & output_eth_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_WRITE_HEADER_LAST_WAIT; - end else if (shift_ip_payload_tvalid & ~output_eth_payload_tready) begin - // word transfer in - store in temp - transfer_in_save = 1; - write_hdr_temp = 1; - write_hdr_data[ 7: 0] = ip_dest_ip_reg[31:24]; - write_hdr_data[15: 8] = ip_dest_ip_reg[23:16]; - write_hdr_data[23:16] = ip_dest_ip_reg[15: 8]; - write_hdr_data[31:24] = ip_dest_ip_reg[ 7: 0]; - write_hdr_data[39:32] = shift_ip_payload_tdata[39:32]; - write_hdr_data[47:40] = shift_ip_payload_tdata[47:40]; - write_hdr_data[55:48] = shift_ip_payload_tdata[55:48]; - write_hdr_data[63:56] = shift_ip_payload_tdata[63:56]; - write_hdr_keep = {shift_ip_payload_tkeep[7:4], 4'hF}; - frame_ptr_next = frame_ptr_reg+keep2count(write_hdr_keep); - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - if (frame_ptr_next >= ip_length_reg) begin - // have entire payload - frame_ptr_next = ip_length_reg; - tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); - write_hdr_keep = tkeep_mask; - write_hdr_last = 1; - write_hdr_user = shift_ip_payload_tuser; - if (shift_ip_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; - end - end else begin - if (shift_ip_payload_tlast) begin - // end of frame, but length does not match - write_hdr_last = 1; - write_hdr_user = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - STATE_WRITE_HEADER_LAST_WAIT: begin - // last header word requires first payload word; no data in registers - if (shift_ip_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_save = 1; - write_hdr_out = 1; - write_hdr_data[ 7: 0] = ip_dest_ip_reg[31:24]; - write_hdr_data[15: 8] = ip_dest_ip_reg[23:16]; - write_hdr_data[23:16] = ip_dest_ip_reg[15: 8]; - write_hdr_data[31:24] = ip_dest_ip_reg[ 7: 0]; - write_hdr_data[39:32] = shift_ip_payload_tdata[39:32]; - write_hdr_data[47:40] = shift_ip_payload_tdata[47:40]; - write_hdr_data[55:48] = shift_ip_payload_tdata[55:48]; - write_hdr_data[63:56] = shift_ip_payload_tdata[63:56]; - write_hdr_keep = {shift_ip_payload_tkeep[7:4], 4'hF}; - frame_ptr_next = frame_ptr_reg+keep2count(write_hdr_keep); - if (frame_ptr_next >= ip_length_reg) begin - // have entire payload - frame_ptr_next = ip_length_reg; - tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); - write_hdr_keep = tkeep_mask; - assert_tlast = 1; - assert_tuser = shift_ip_payload_tuser; - if (shift_ip_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end - end else begin - if (shift_ip_payload_tlast) begin - // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; - error_payload_early_termination_next = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + state_next = STATE_WRITE_PAYLOAD; end end end else begin - state_next = STATE_WRITE_HEADER_LAST_WAIT; + state_next = STATE_WRITE_HEADER_LAST; end end - STATE_WRITE_PAYLOAD_IDLE: begin - // idle; no data in registers - if (shift_ip_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_save = 1; - transfer_in_out = 1; + STATE_WRITE_PAYLOAD: begin + // write payload + input_ip_payload_tready_next = output_eth_payload_tready_int_early & shift_ip_payload_input_tready; + + output_eth_payload_tdata_int = shift_ip_payload_tdata; + output_eth_payload_tkeep_int = shift_ip_payload_tkeep; + output_eth_payload_tvalid_int = shift_ip_payload_tvalid; + output_eth_payload_tlast_int = shift_ip_payload_tlast; + output_eth_payload_tuser_int = shift_ip_payload_tuser; + + if (output_eth_payload_tready_int & shift_ip_payload_tvalid) begin + // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_tkeep); - if (frame_ptr_next >= ip_length_reg) begin - // have entire payload - frame_ptr_next = ip_length_reg; - tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); - if (shift_ip_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end - end else begin - if (shift_ip_payload_tlast) begin - // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; - error_payload_early_termination_next = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - end else begin - state_next = STATE_WRITE_PAYLOAD_IDLE; - end - end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register - if (shift_ip_payload_tvalid & output_eth_payload_tready) begin - // word transfer through - update output register transfer_in_save = 1; - transfer_in_out = 1; - frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_tkeep); if (frame_ptr_next >= ip_length_reg) begin // have entire payload frame_ptr_next = ip_length_reg; - tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); + output_eth_payload_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); if (shift_ip_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_ip_payload_tready_next = 0; + flush_save = 1; + input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + state_next = STATE_IDLE; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + store_last_word = 1; + output_eth_payload_tvalid_int = 0; + state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin if (shift_ip_payload_tlast) begin // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; error_payload_early_termination_next = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + output_eth_payload_tuser_int = 1; + input_ip_payload_tready_next = 0; + flush_save = 1; + input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + state_next = STATE_IDLE; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - end else if (~shift_ip_payload_tvalid & output_eth_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_WRITE_PAYLOAD_IDLE; - end else if (shift_ip_payload_tvalid & ~output_eth_payload_tready) begin - // word transfer in - store in temp - transfer_in_save = 1; - transfer_in_temp = 1; - frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_tkeep); - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - if (frame_ptr_next >= ip_length_reg) begin - // have entire payload - frame_ptr_next = ip_length_reg; - tkeep_mask = count2keep(ip_length_reg - frame_ptr_reg); - if (~shift_ip_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + state_next = STATE_WRITE_PAYLOAD; end end end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + state_next = STATE_WRITE_PAYLOAD; end end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in both output and temp registers - if (output_eth_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_eth_payload_tlast_reg) begin - if (frame_ptr_next < ip_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - if (frame_ptr_next >= ip_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - if (output_eth_payload_tready) begin - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - if (shift_ip_payload_tvalid) begin + STATE_WRITE_PAYLOAD_LAST: begin + // read and discard until end of frame + input_ip_payload_tready_next = output_eth_payload_tready_int_early & shift_ip_payload_input_tready; + + output_eth_payload_tdata_int = last_word_data_reg; + output_eth_payload_tkeep_int = last_word_keep_reg; + output_eth_payload_tvalid_int = shift_ip_payload_tvalid & shift_ip_payload_tlast; + output_eth_payload_tlast_int = shift_ip_payload_tlast; + output_eth_payload_tuser_int = shift_ip_payload_tuser; + + if (output_eth_payload_tready_int & shift_ip_payload_tvalid) begin transfer_in_save = 1; if (shift_ip_payload_tlast) begin - // assert tlast and transfer tuser - assert_tlast = 1; - assert_tuser = shift_ip_payload_tuser; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + input_ip_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin - // wait for end of frame; data in both output and temp registers; read and discard - if (output_eth_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + state_next = STATE_WRITE_PAYLOAD_LAST; end end STATE_WAIT_LAST: begin - // wait for end of frame; read and discard + // read and discard until end of frame + input_ip_payload_tready_next = shift_ip_payload_input_tready; + if (shift_ip_payload_tvalid) begin transfer_in_save = 1; if (shift_ip_payload_tlast) begin + input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + input_ip_payload_tready_next = 0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -645,6 +494,8 @@ always @(posedge clk or posedge rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; hdr_sum_reg <= 0; + last_word_data_reg <= 0; + last_word_keep_reg <= 0; input_ip_hdr_ready_reg <= 0; input_ip_payload_tready_reg <= 0; ip_dscp_reg <= 0; @@ -661,18 +512,6 @@ always @(posedge clk or posedge rst) begin output_eth_dest_mac_reg <= 0; output_eth_src_mac_reg <= 0; output_eth_type_reg <= 0; - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - save_ip_payload_tdata_reg <= 0; - save_ip_payload_tkeep_reg <= 0; - save_ip_payload_tlast_reg <= 0; - save_ip_payload_tuser_reg <= 0; busy_reg <= 0; error_payload_early_termination_reg <= 0; end else begin @@ -682,82 +521,16 @@ always @(posedge clk or posedge rst) begin hdr_sum_reg <= hdr_sum_next; + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + input_ip_payload_tready_reg <= input_ip_payload_tready_next; + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; error_payload_early_termination_reg <= error_payload_early_termination_next; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_ip_hdr_ready_reg <= 1; - input_ip_payload_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - end - STATE_WRITE_HEADER: begin - // write header - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_HEADER_LAST: begin - // write last header word; need first data word - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= shift_ip_payload_input_tready; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_HEADER_LAST_WAIT: begin - // last header word requires first payload word; no data in registers - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= shift_ip_payload_input_tready; - output_eth_payload_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_IDLE: begin - // write payload; no data in registers; accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= shift_ip_payload_input_tready; - output_eth_payload_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register; accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= shift_ip_payload_input_tready; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in output and temp registers; do not accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= shift_ip_payload_input_tready; - output_eth_payload_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin - // wait for end of frame; data in output and temp registers; do not accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= shift_ip_payload_input_tready; - output_eth_payload_tvalid_reg <= 0; - end - endcase - + // datapath if (store_ip_hdr) begin output_eth_dest_mac_reg <= input_eth_dest_mac; output_eth_src_mac_reg <= input_eth_src_mac; @@ -774,31 +547,9 @@ always @(posedge clk or posedge rst) begin ip_dest_ip_reg <= input_ip_dest_ip; end - if (write_hdr_out) begin - output_eth_payload_tdata_reg <= write_hdr_data; - output_eth_payload_tkeep_reg <= write_hdr_keep & tkeep_mask; - output_eth_payload_tlast_reg <= write_hdr_last; - output_eth_payload_tuser_reg <= write_hdr_user; - end else if (write_hdr_temp) begin - temp_eth_payload_tdata_reg <= write_hdr_data; - temp_eth_payload_tkeep_reg <= write_hdr_keep & tkeep_mask; - temp_eth_payload_tlast_reg <= write_hdr_last; - temp_eth_payload_tuser_reg <= write_hdr_user; - end else if (transfer_in_out) begin - output_eth_payload_tdata_reg <= shift_ip_payload_tdata; - output_eth_payload_tkeep_reg <= shift_ip_payload_tkeep & tkeep_mask; - output_eth_payload_tlast_reg <= shift_ip_payload_tlast; - output_eth_payload_tuser_reg <= shift_ip_payload_tuser; - end else if (transfer_in_temp) begin - temp_eth_payload_tdata_reg <= shift_ip_payload_tdata; - temp_eth_payload_tkeep_reg <= shift_ip_payload_tkeep & tkeep_mask; - temp_eth_payload_tlast_reg <= shift_ip_payload_tlast; - temp_eth_payload_tuser_reg <= shift_ip_payload_tuser; - end else if (transfer_temp_out) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + if (store_last_word) begin + last_word_data_reg <= output_eth_payload_tdata_int; + last_word_keep_reg <= output_eth_payload_tkeep_int; end if (flush_save) begin @@ -806,15 +557,84 @@ always @(posedge clk or posedge rst) begin save_ip_payload_tkeep_reg <= 0; save_ip_payload_tlast_reg <= 0; save_ip_payload_tuser_reg <= 0; - end else if (transfer_in_save & ~shift_ip_payload_extra_cycle) begin + end else if (transfer_in_save) begin save_ip_payload_tdata_reg <= input_ip_payload_tdata; save_ip_payload_tkeep_reg <= input_ip_payload_tkeep; save_ip_payload_tlast_reg <= input_ip_payload_tlast; save_ip_payload_tuser_reg <= input_ip_payload_tuser; end + end +end - if (assert_tlast) output_eth_payload_tlast_reg <= 1; - if (assert_tuser) output_eth_payload_tuser_reg <= 1; +// output datapath logic +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [63:0] temp_eth_payload_tdata_reg = 0; +reg [7:0] temp_eth_payload_tkeep_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tkeep_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end end end From 44741815494aa215616085889b65db208416693d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Oct 2014 01:55:29 -0700 Subject: [PATCH 066/617] Rework UDP datapath modules to separate output register --- rtl/udp_ip_rx.v | 344 +++++++++++++++------------------- rtl/udp_ip_rx_64.v | 412 +++++++++++++++++------------------------ rtl/udp_ip_tx.v | 368 +++++++++++++++--------------------- rtl/udp_ip_tx_64.v | 453 ++++++++++++++++++++------------------------- 4 files changed, 661 insertions(+), 916 deletions(-) diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v index 3184a1428..b03b05ed6 100644 --- a/rtl/udp_ip_rx.v +++ b/rtl/udp_ip_rx.v @@ -130,21 +130,19 @@ UDP Frame payload length octets -This module receives an IP frame with decoded fields and decodes -the AXI packet format. If the Ethertype does not match, the packet is -discarded. +This module receives an IP frame with header fields in parallel and payload on +an AXI stream interface, decodes and strips the UDP header fields, then +produces the header fields in parallel along with the UDP payload in a +separate AXI stream. */ localparam [2:0] STATE_IDLE = 3'd0, STATE_READ_HEADER = 3'd1, - STATE_READ_PAYLOAD_IDLE = 3'd2, - STATE_READ_PAYLOAD_TRANSFER = 3'd3, - STATE_READ_PAYLOAD_TRANSFER_WAIT = 3'd4, - STATE_READ_PAYLOAD_TRANSFER_LAST = 3'd5, - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST = 3'd6, - STATE_WAIT_LAST = 3'd7; + STATE_READ_PAYLOAD = 3'd2, + STATE_READ_PAYLOAD_LAST = 3'd3, + STATE_WAIT_LAST = 3'd4; reg [2:0] state_reg = STATE_IDLE, state_next; @@ -158,18 +156,11 @@ reg store_udp_length_0; reg store_udp_length_1; reg store_udp_checksum_0; reg store_udp_checksum_1; - -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - -reg assert_tlast; -reg assert_tuser; +reg store_last_word; reg [15:0] frame_ptr_reg = 0, frame_ptr_next; -reg input_ip_hdr_ready_reg = 0; -reg input_ip_payload_tready_reg = 0; +reg [7:0] last_word_data_reg = 0; reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; @@ -192,18 +183,21 @@ reg [15:0] output_udp_source_port_reg = 0; reg [15:0] output_udp_dest_port_reg = 0; reg [15:0] output_udp_length_reg = 0; reg [15:0] output_udp_checksum_reg = 0; -reg [7:0] output_udp_payload_tdata_reg = 0; -reg output_udp_payload_tvalid_reg = 0; -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; + +reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; reg busy_reg = 0; reg error_header_early_termination_reg = 0, error_header_early_termination_next; reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; -reg [7:0] temp_udp_payload_tdata_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +// internal datapath +reg [7:0] output_udp_payload_tdata_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = input_ip_payload_tready_reg; @@ -229,10 +223,6 @@ assign output_udp_source_port = output_udp_source_port_reg; assign output_udp_dest_port = output_udp_dest_port_reg; assign output_udp_length = output_udp_length_reg; assign output_udp_checksum = output_udp_checksum_reg; -assign output_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; -assign output_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_udp_payload_tuser = output_udp_payload_tuser_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -241,12 +231,8 @@ assign error_payload_early_termination = error_payload_early_termination_reg; always @* begin state_next = 2'bz; - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - assert_tlast = 0; - assert_tuser = 0; + input_ip_hdr_ready_next = 0; + input_ip_payload_tready_next = 0; store_ip_hdr = 0; store_udp_source_port_0 = 0; @@ -258,6 +244,8 @@ always @* begin store_udp_checksum_0 = 0; store_udp_checksum_1 = 0; + store_last_word = 0; + frame_ptr_next = frame_ptr_reg; output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; @@ -265,13 +253,20 @@ always @* begin error_header_early_termination_next = 0; error_payload_early_termination_next = 0; + output_udp_payload_tdata_int = 0; + output_udp_payload_tvalid_int = 0; + output_udp_payload_tlast_int = 0; + output_udp_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for header frame_ptr_next = 0; + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; if (input_ip_hdr_ready & input_ip_hdr_valid) begin - frame_ptr_next = 0; + input_ip_hdr_ready_next = 0; + input_ip_payload_tready_next = 1; store_ip_hdr = 1; state_next = STATE_READ_HEADER; end else begin @@ -280,7 +275,9 @@ always @* begin end STATE_READ_HEADER: begin // read header state - if (input_ip_payload_tvalid) begin + input_ip_payload_tready_next = 1; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg+1; state_next = STATE_READ_HEADER; @@ -296,130 +293,86 @@ always @* begin 8'h07: begin store_udp_checksum_0 = 1; output_udp_hdr_valid_next = 1; - state_next = STATE_READ_PAYLOAD_IDLE; + input_ip_payload_tready_next = output_udp_payload_tready_int_early; + state_next = STATE_READ_PAYLOAD; end endcase if (input_ip_payload_tlast) begin - state_next = STATE_IDLE; - output_udp_hdr_valid_next = 0; error_header_early_termination_next = 1; + output_udp_hdr_valid_next = 0; + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + input_ip_payload_tready_next = 0; + state_next = STATE_IDLE; end end else begin state_next = STATE_READ_HEADER; end end - STATE_READ_PAYLOAD_IDLE: begin - // idle; no data in registers - if (input_ip_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; + STATE_READ_PAYLOAD: begin + // read payload + input_ip_payload_tready_next = output_udp_payload_tready_int_early; + + output_udp_payload_tdata_int = input_ip_payload_tdata; + output_udp_payload_tvalid_int = input_ip_payload_tvalid; + output_udp_payload_tlast_int = input_ip_payload_tlast; + output_udp_payload_tuser_int = input_ip_payload_tuser; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin + // word transfer through frame_ptr_next = frame_ptr_reg+1; if (input_ip_payload_tlast) begin if (frame_ptr_next != output_udp_length_reg) begin // end of frame, but length does not match - assert_tuser = 1; + output_udp_payload_tuser_int = 1; error_payload_early_termination_next = 1; end - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + input_ip_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin if (frame_ptr_next == output_udp_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + store_last_word = 1; + output_udp_payload_tvalid_int = 0; + state_next = STATE_READ_PAYLOAD_LAST; end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; + state_next = STATE_READ_PAYLOAD; end end end else begin - state_next = STATE_READ_PAYLOAD_IDLE; + state_next = STATE_READ_PAYLOAD; end end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register - if (input_ip_payload_tvalid & output_udp_payload_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - frame_ptr_next = frame_ptr_reg+1; + STATE_READ_PAYLOAD_LAST: begin + // read and discard until end of frame + input_ip_payload_tready_next = output_udp_payload_tready_int_early; + + output_udp_payload_tdata_int = last_word_data_reg; + output_udp_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tlast; + output_udp_payload_tlast_int = input_ip_payload_tlast; + output_udp_payload_tuser_int = input_ip_payload_tuser; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin - if (frame_ptr_next != output_udp_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + input_ip_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin - if (frame_ptr_next == output_udp_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - end else if (~input_ip_payload_tvalid & output_udp_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_READ_PAYLOAD_IDLE; - end else if (input_ip_payload_tvalid & ~output_udp_payload_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - frame_ptr_next = frame_ptr_reg+1; - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in both output and temp registers - if (output_udp_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_udp_payload_tlast_reg) begin - if (frame_ptr_next != output_udp_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - if (frame_ptr_next == output_udp_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end + state_next = STATE_READ_PAYLOAD_LAST; end end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - if (output_udp_payload_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - if (input_ip_payload_tvalid) begin - if (input_ip_payload_tlast) begin - // assert tlast and transfer tuser - assert_tlast = 1; - assert_tuser = input_ip_payload_tuser; - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + state_next = STATE_READ_PAYLOAD_LAST; end end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - if (input_ip_payload_tvalid) begin + input_ip_payload_tready_next = 1; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + input_ip_payload_tready_next = 0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -435,6 +388,7 @@ always @(posedge clk or posedge rst) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; + last_word_data_reg <= 0; input_ip_hdr_ready_reg <= 0; input_ip_payload_tready_reg <= 0; output_udp_hdr_valid_reg <= 0; @@ -458,13 +412,6 @@ always @(posedge clk or posedge rst) begin output_udp_dest_port_reg <= 0; output_udp_length_reg <= 0; output_udp_checksum_reg <= 0; - output_udp_payload_tdata_reg <= 0; - output_udp_payload_tvalid_reg <= 0; - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; busy_reg <= 0; error_header_early_termination_reg <= 0; error_payload_early_termination_reg <= 0; @@ -473,6 +420,9 @@ always @(posedge clk or posedge rst) begin frame_ptr_reg <= frame_ptr_next; + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + input_ip_payload_tready_reg <= input_ip_payload_tready_next; + output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; @@ -480,58 +430,6 @@ always @(posedge clk or posedge rst) begin busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_ip_hdr_ready_reg <= ~output_udp_hdr_valid; - input_ip_payload_tready_reg <= 0; - output_udp_payload_tvalid_reg <= 0; - end - STATE_READ_HEADER: begin - // read header; accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_udp_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_IDLE: begin - // read payload; no data in registers; accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_udp_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register; accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_udp_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in output and temp registers; do not accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_udp_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_udp_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_udp_payload_tvalid_reg <= 0; - end - STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_udp_payload_tvalid_reg <= 0; - end - endcase - // datapath if (store_ip_hdr) begin output_eth_dest_mac_reg <= input_eth_dest_mac; @@ -552,6 +450,10 @@ always @(posedge clk or posedge rst) begin output_ip_dest_ip_reg <= input_ip_dest_ip; end + if (store_last_word) begin + last_word_data_reg <= output_udp_payload_tdata_int; + end + if (store_udp_source_port_0) output_udp_source_port_reg[ 7: 0] <= input_ip_payload_tdata; if (store_udp_source_port_1) output_udp_source_port_reg[15: 8] <= input_ip_payload_tdata; if (store_udp_dest_port_0) output_udp_dest_port_reg[ 7: 0] <= input_ip_payload_tdata; @@ -560,23 +462,69 @@ always @(posedge clk or posedge rst) begin if (store_udp_length_1) output_udp_length_reg[15: 8] <= input_ip_payload_tdata; if (store_udp_checksum_0) output_udp_checksum_reg[ 7: 0] <= input_ip_payload_tdata; if (store_udp_checksum_1) output_udp_checksum_reg[15: 8] <= input_ip_payload_tdata; + end +end - if (transfer_in_out) begin - output_udp_payload_tdata_reg <= input_ip_payload_tdata; - output_udp_payload_tlast_reg <= input_ip_payload_tlast; - output_udp_payload_tuser_reg <= input_ip_payload_tuser; - end else if (transfer_in_temp) begin - temp_udp_payload_tdata_reg <= input_ip_payload_tdata; - temp_udp_payload_tlast_reg <= input_ip_payload_tlast; - temp_udp_payload_tuser_reg <= input_ip_payload_tuser; - end else if (transfer_temp_out) begin +// output datapath logic +reg [7:0] output_udp_payload_tdata_reg = 0; +reg output_udp_payload_tvalid_reg = 0; +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg [7:0] temp_udp_payload_tdata_reg = 0; +reg temp_udp_payload_tvalid_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); + +assign output_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; +assign output_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_udp_payload_tuser = output_udp_payload_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_udp_payload_tdata_reg <= 0; + output_udp_payload_tvalid_reg <= 0; + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + + if (output_udp_payload_tready_int) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; end - - if (assert_tlast) output_udp_payload_tlast_reg <= 1; - if (assert_tuser) output_udp_payload_tuser_reg <= 1; end end diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index 93d9333d9..63dda8413 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -132,41 +132,31 @@ UDP Frame payload length octets -This module receives an IP frame with decoded fields and decodes -the AXI packet format. If the Ethertype does not match, the packet is -discarded. +This module receives an IP frame with header fields in parallel and payload on +an AXI stream interface, decodes and strips the UDP header fields, then +produces the header fields in parallel along with the UDP payload in a +separate AXI stream. */ -localparam [3:0] - STATE_IDLE = 4'd0, - STATE_READ_HEADER = 4'd1, - STATE_READ_PAYLOAD_IDLE = 4'd2, - STATE_READ_PAYLOAD_TRANSFER = 4'd3, - STATE_READ_PAYLOAD_TRANSFER_WAIT = 4'd4, - STATE_READ_PAYLOAD_TRANSFER_LAST = 4'd5, - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST = 4'd6, - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT = 4'd7, - STATE_WAIT_LAST = 4'd8; +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_READ_HEADER = 3'd1, + STATE_READ_PAYLOAD = 3'd2, + STATE_READ_PAYLOAD_LAST = 3'd3, + STATE_WAIT_LAST = 3'd4; -reg [3:0] state_reg = STATE_IDLE, state_next; +reg [2:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_ip_hdr; reg store_hdr_word_0; - -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - -reg assert_tlast; -reg assert_tuser; -reg [7:0] tkeep_mask; +reg store_last_word; reg [15:0] frame_ptr_reg = 0, frame_ptr_next; -reg input_ip_hdr_ready_reg = 0; -reg input_ip_payload_tready_reg = 0; +reg [63:0] last_word_data_reg = 0; +reg [7:0] last_word_keep_reg = 0; reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; @@ -189,20 +179,22 @@ reg [15:0] output_udp_source_port_reg = 0; reg [15:0] output_udp_dest_port_reg = 0; reg [15:0] output_udp_length_reg = 0; reg [15:0] output_udp_checksum_reg = 0; -reg [63:0] output_udp_payload_tdata_reg = 0; -reg [7:0] output_udp_payload_tkeep_reg = 0; -reg output_udp_payload_tvalid_reg = 0; -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; + +reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; reg busy_reg = 0; reg error_header_early_termination_reg = 0, error_header_early_termination_next; reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; -reg [63:0] temp_udp_payload_tdata_reg = 0; -reg [7:0] temp_udp_payload_tkeep_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +// internal datapath +reg [63:0] output_udp_payload_tdata_int; +reg [7:0] output_udp_payload_tkeep_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = input_ip_payload_tready_reg; @@ -228,11 +220,6 @@ assign output_udp_source_port = output_udp_source_port_reg; assign output_udp_dest_port = output_udp_dest_port_reg; assign output_udp_length = output_udp_length_reg; assign output_udp_checksum = output_udp_checksum_reg; -assign output_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; -assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; -assign output_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_udp_payload_tuser = output_udp_payload_tuser_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -271,17 +258,14 @@ endfunction always @* begin state_next = 2'bz; - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - assert_tlast = 0; - assert_tuser = 0; - tkeep_mask = 8'hff; + input_ip_hdr_ready_next = 0; + input_ip_payload_tready_next = 0; store_ip_hdr = 0; store_hdr_word_0 = 0; + store_last_word = 0; + frame_ptr_next = frame_ptr_reg; output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; @@ -289,13 +273,21 @@ always @* begin error_header_early_termination_next = 0; error_payload_early_termination_next = 0; + output_udp_payload_tdata_int = 0; + output_udp_payload_tkeep_int = 0; + output_udp_payload_tvalid_int = 0; + output_udp_payload_tlast_int = 0; + output_udp_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for header frame_ptr_next = 0; + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; if (input_ip_hdr_ready & input_ip_hdr_valid) begin - frame_ptr_next = 0; + input_ip_hdr_ready_next = 0; + input_ip_payload_tready_next = 1; store_ip_hdr = 1; state_next = STATE_READ_HEADER; end else begin @@ -304,7 +296,9 @@ always @* begin end STATE_READ_HEADER: begin // read header state - if (input_ip_payload_tvalid) begin + input_ip_payload_tready_next = 1; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg+8; state_next = STATE_READ_HEADER; @@ -313,159 +307,95 @@ always @* begin 8'h00: begin store_hdr_word_0 = 1; output_udp_hdr_valid_next = 1; - state_next = STATE_READ_PAYLOAD_IDLE; + input_ip_payload_tready_next = output_udp_payload_tready_int_early; + state_next = STATE_READ_PAYLOAD; end endcase if (input_ip_payload_tlast) begin - state_next = STATE_IDLE; - output_udp_hdr_valid_next = 0; error_header_early_termination_next = 1; + output_udp_hdr_valid_next = 0; + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + input_ip_payload_tready_next = 0; + state_next = STATE_IDLE; end end else begin state_next = STATE_READ_HEADER; end end - STATE_READ_PAYLOAD_IDLE: begin - // idle; no data in registers - if (input_ip_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; + STATE_READ_PAYLOAD: begin + // read payload + input_ip_payload_tready_next = output_udp_payload_tready_int_early; + + output_udp_payload_tdata_int = input_ip_payload_tdata; + output_udp_payload_tkeep_int = input_ip_payload_tkeep; + output_udp_payload_tvalid_int = input_ip_payload_tvalid; + output_udp_payload_tlast_int = input_ip_payload_tlast; + output_udp_payload_tuser_int = input_ip_payload_tuser; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin + // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(input_ip_payload_tkeep); if (frame_ptr_next >= output_udp_length_reg) begin // have entire payload frame_ptr_next = output_udp_length_reg; - tkeep_mask = count2keep(output_udp_length_reg - frame_ptr_reg); + output_udp_payload_tkeep_int = input_ip_payload_tkeep & count2keep(output_udp_length_reg - frame_ptr_reg); if (input_ip_payload_tlast) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + input_ip_payload_tready_next = 0; + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + state_next = STATE_IDLE; end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + store_last_word = 1; + output_udp_payload_tvalid_int = 0; + state_next = STATE_READ_PAYLOAD_LAST; end end else begin if (input_ip_payload_tlast) begin // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; error_payload_early_termination_next = 1; - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + output_udp_payload_tuser_int = 1; + input_ip_payload_tready_next = 0; + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + state_next = STATE_IDLE; end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; + state_next = STATE_READ_PAYLOAD; end end end else begin - state_next = STATE_READ_PAYLOAD_IDLE; + state_next = STATE_READ_PAYLOAD; end end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register - if (input_ip_payload_tvalid & output_udp_payload_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - frame_ptr_next = frame_ptr_reg+keep2count(input_ip_payload_tkeep); - if (frame_ptr_next >= output_udp_length_reg) begin - // have entire payload - frame_ptr_next = output_udp_length_reg; - tkeep_mask = count2keep(output_udp_length_reg - frame_ptr_reg); - if (input_ip_payload_tlast) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end - end else begin - if (input_ip_payload_tlast) begin - // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; - error_payload_early_termination_next = 1; - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - end else if (~input_ip_payload_tvalid & output_udp_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_READ_PAYLOAD_IDLE; - end else if (input_ip_payload_tvalid & ~output_udp_payload_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - frame_ptr_next = frame_ptr_reg+keep2count(input_ip_payload_tkeep); - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - if (frame_ptr_next >= output_udp_length_reg) begin - // have entire payload - frame_ptr_next = output_udp_length_reg; - tkeep_mask = count2keep(output_udp_length_reg - frame_ptr_reg); - if (~input_ip_payload_tlast) begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; - end - end - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in both output and temp registers - if (output_udp_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_udp_payload_tlast_reg) begin - if (frame_ptr_next <= output_udp_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end else begin - if (frame_ptr_next >= output_udp_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER; - end - end - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - if (output_udp_payload_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - if (input_ip_payload_tvalid) begin + STATE_READ_PAYLOAD_LAST: begin + // read and discard until end of frame + input_ip_payload_tready_next = output_udp_payload_tready_int_early; + + output_udp_payload_tdata_int = last_word_data_reg; + output_udp_payload_tkeep_int = last_word_keep_reg; + output_udp_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tlast; + output_udp_payload_tlast_int = input_ip_payload_tlast; + output_udp_payload_tuser_int = input_ip_payload_tuser; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin - // assert tlast and transfer tuser - assert_tlast = 1; - assert_tuser = input_ip_payload_tuser; - state_next = STATE_READ_PAYLOAD_TRANSFER_LAST; + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + input_ip_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; + state_next = STATE_READ_PAYLOAD_LAST; end end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin - // wait for end of frame; data in both output and temp registers; read and discard - if (output_udp_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + state_next = STATE_READ_PAYLOAD_LAST; end end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - if (input_ip_payload_tvalid) begin + input_ip_payload_tready_next = 1; + + if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin + input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + input_ip_payload_tready_next = 0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -481,6 +411,7 @@ always @(posedge clk or posedge rst) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; + last_word_data_reg <= 0; input_ip_hdr_ready_reg <= 0; input_ip_payload_tready_reg <= 0; output_udp_hdr_valid_reg <= 0; @@ -504,15 +435,6 @@ always @(posedge clk or posedge rst) begin output_udp_dest_port_reg <= 0; output_udp_length_reg <= 0; output_udp_checksum_reg <= 0; - output_udp_payload_tdata_reg <= 0; - output_udp_payload_tkeep_reg <= 0; - output_udp_payload_tvalid_reg <= 0; - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; busy_reg <= 0; error_header_early_termination_reg <= 0; error_payload_early_termination_reg <= 0; @@ -521,6 +443,9 @@ always @(posedge clk or posedge rst) begin frame_ptr_reg <= frame_ptr_next; + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + input_ip_payload_tready_reg <= input_ip_payload_tready_next; + output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; @@ -528,64 +453,6 @@ always @(posedge clk or posedge rst) begin busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_ip_hdr_ready_reg <= ~output_udp_hdr_valid; - input_ip_payload_tready_reg <= 0; - output_udp_payload_tvalid_reg <= 0; - end - STATE_READ_HEADER: begin - // read header; accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_udp_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_IDLE: begin - // read payload; no data in registers; accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_udp_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_TRANSFER: begin - // read payload; data in output register; accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_udp_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT: begin - // read payload; data in output and temp registers; do not accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_udp_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_LAST: begin - // read last payload word; data in output register; do not accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_udp_payload_tvalid_reg <= 1; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_udp_payload_tvalid_reg <= 0; - end - STATE_READ_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin - // wait for end of frame; data in output and temp registers; do not accept new data - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_udp_payload_tvalid_reg <= 1; - end - STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 1; - output_udp_payload_tvalid_reg <= 0; - end - endcase - // datapath if (store_ip_hdr) begin output_eth_dest_mac_reg <= input_eth_dest_mac; @@ -606,6 +473,11 @@ always @(posedge clk or posedge rst) begin output_ip_dest_ip_reg <= input_ip_dest_ip; end + if (store_last_word) begin + last_word_data_reg <= output_udp_payload_tdata_int; + last_word_keep_reg <= output_udp_payload_tkeep_int; + end + if (store_hdr_word_0) begin output_udp_source_port_reg[15: 8] <= input_ip_payload_tdata[ 7: 0]; output_udp_source_port_reg[ 7: 0] <= input_ip_payload_tdata[15: 8]; @@ -616,26 +488,78 @@ always @(posedge clk or posedge rst) begin output_udp_checksum_reg[15: 8] <= input_ip_payload_tdata[55:48]; output_udp_checksum_reg[ 7: 0] <= input_ip_payload_tdata[63:56]; end + end +end - if (transfer_in_out) begin - output_udp_payload_tdata_reg <= input_ip_payload_tdata; - output_udp_payload_tkeep_reg <= input_ip_payload_tkeep & tkeep_mask; - output_udp_payload_tlast_reg <= input_ip_payload_tlast; - output_udp_payload_tuser_reg <= input_ip_payload_tuser; - end else if (transfer_in_temp) begin - temp_udp_payload_tdata_reg <= input_ip_payload_tdata; - temp_udp_payload_tkeep_reg <= input_ip_payload_tkeep & tkeep_mask; - temp_udp_payload_tlast_reg <= input_ip_payload_tlast; - temp_udp_payload_tuser_reg <= input_ip_payload_tuser; - end else if (transfer_temp_out) begin +// output datapath logic +reg [63:0] output_udp_payload_tdata_reg = 0; +reg [7:0] output_udp_payload_tkeep_reg = 0; +reg output_udp_payload_tvalid_reg = 0; +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg [63:0] temp_udp_payload_tdata_reg = 0; +reg [7:0] temp_udp_payload_tkeep_reg = 0; +reg temp_udp_payload_tvalid_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); + +assign output_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; +assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; +assign output_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_udp_payload_tuser = output_udp_payload_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_udp_payload_tdata_reg <= 0; + output_udp_payload_tkeep_reg <= 0; + output_udp_payload_tvalid_reg <= 0; + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + + if (output_udp_payload_tready_int) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; end - - if (assert_tlast) output_udp_payload_tlast_reg <= 1; - if (assert_tuser) output_udp_payload_tuser_reg <= 1; end end diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index 208a76d15..88140172d 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -128,48 +128,36 @@ UDP Frame payload length octets -This module receives an IP frame with decoded fields and decodes -the AXI packet format. If the Ethertype does not match, the packet is -discarded. +This module receives a UDP frame with header fields in parallel along with the +payload in an AXI stream, combines the header with the payload, passes through +the IP headers, and transmits the complete IP payload on an AXI interface. */ localparam [2:0] STATE_IDLE = 3'd0, STATE_WRITE_HEADER = 3'd1, - STATE_WRITE_PAYLOAD_IDLE = 3'd2, - STATE_WRITE_PAYLOAD_TRANSFER = 3'd3, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 3'd4, - STATE_WRITE_PAYLOAD_TRANSFER_LAST = 3'd5, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST = 3'd6, - STATE_WAIT_LAST = 3'd7; + STATE_WRITE_PAYLOAD = 3'd2, + STATE_WRITE_PAYLOAD_LAST = 3'd3, + STATE_WAIT_LAST = 3'd4; reg [2:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_udp_hdr; - -reg [7:0] write_hdr_data; -reg write_hdr_out; - -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - -reg assert_tlast; -reg assert_tuser; +reg store_last_word; reg [15:0] frame_ptr_reg = 0, frame_ptr_next; -reg [15:0] hdr_sum_reg = 0, hdr_sum_next; +reg [7:0] last_word_data_reg = 0; reg [15:0] udp_source_port_reg = 0; reg [15:0] udp_dest_port_reg = 0; reg [15:0] udp_length_reg = 0; reg [15:0] udp_checksum_reg = 0; -reg input_udp_hdr_ready_reg = 0; -reg input_udp_payload_tready_reg = 0; +reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; @@ -188,17 +176,17 @@ reg [7:0] output_ip_protocol_reg = 0; reg [15:0] output_ip_header_checksum_reg = 0; reg [31:0] output_ip_source_ip_reg = 0; reg [31:0] output_ip_dest_ip_reg = 0; -reg [7:0] output_ip_payload_tdata_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; reg busy_reg = 0; reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; -reg [7:0] temp_ip_payload_tdata_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +// internal datapath +reg [7:0] output_ip_payload_tdata_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; assign input_udp_hdr_ready = input_udp_hdr_ready_reg; assign input_udp_payload_tready = input_udp_payload_tready_reg; @@ -220,10 +208,6 @@ assign output_ip_protocol = output_ip_protocol_reg; assign output_ip_header_checksum = output_ip_header_checksum_reg; assign output_ip_source_ip = output_ip_source_ip_reg; assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; assign busy = busy_reg; assign error_payload_early_termination = error_payload_early_termination_reg; @@ -231,37 +215,39 @@ assign error_payload_early_termination = error_payload_early_termination_reg; always @* begin state_next = 2'bz; + input_udp_hdr_ready_next = 0; + input_udp_payload_tready_next = 0; + store_udp_hdr = 0; - write_hdr_data = 0; - write_hdr_out = 0; - - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - assert_tlast = 0; - assert_tuser = 0; + store_last_word = 0; frame_ptr_next = frame_ptr_reg; - hdr_sum_next = hdr_sum_reg; - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; error_payload_early_termination_next = 0; + output_ip_payload_tdata_int = 0; + output_ip_payload_tvalid_int = 0; + output_ip_payload_tlast_int = 0; + output_ip_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - if (input_udp_hdr_valid & input_udp_hdr_ready) begin + if (input_udp_hdr_ready & input_udp_hdr_valid) begin store_udp_hdr = 1; - write_hdr_out = 1; - write_hdr_data = input_udp_source_port[15: 8]; + input_udp_hdr_ready_next = 0; output_ip_hdr_valid_next = 1; - frame_ptr_next = 1; + if (output_ip_payload_tready_int) begin + output_ip_payload_tvalid_int = 1; + output_ip_payload_tdata_int = input_udp_source_port[15: 8]; + frame_ptr_next = 1; + end state_next = STATE_WRITE_HEADER; end else begin state_next = STATE_IDLE; @@ -269,137 +255,92 @@ always @* begin end STATE_WRITE_HEADER: begin // write header state - if (output_ip_payload_tready) begin + if (output_ip_payload_tready_int) begin // word transfer out frame_ptr_next = frame_ptr_reg+1; + output_ip_payload_tvalid_int = 1; state_next = STATE_WRITE_HEADER; - write_hdr_out = 1; case (frame_ptr_reg) - 8'h01: write_hdr_data = udp_source_port_reg[ 7: 0]; - 8'h02: write_hdr_data = udp_dest_port_reg[15: 8]; - 8'h03: write_hdr_data = udp_dest_port_reg[ 7: 0]; - 8'h04: write_hdr_data = udp_length_reg[15: 8]; - 8'h05: write_hdr_data = udp_length_reg[ 7: 0]; - 8'h06: write_hdr_data = udp_checksum_reg[15: 8]; + 8'h00: output_ip_payload_tdata_int = input_udp_source_port[15: 8]; + 8'h01: output_ip_payload_tdata_int = udp_source_port_reg[ 7: 0]; + 8'h02: output_ip_payload_tdata_int = udp_dest_port_reg[15: 8]; + 8'h03: output_ip_payload_tdata_int = udp_dest_port_reg[ 7: 0]; + 8'h04: output_ip_payload_tdata_int = udp_length_reg[15: 8]; + 8'h05: output_ip_payload_tdata_int = udp_length_reg[ 7: 0]; + 8'h06: output_ip_payload_tdata_int = udp_checksum_reg[15: 8]; 8'h07: begin - write_hdr_data = udp_checksum_reg[ 7: 0]; - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + output_ip_payload_tdata_int = udp_checksum_reg[ 7: 0]; + input_udp_payload_tready_next = output_ip_payload_tready_int_early; + state_next = STATE_WRITE_PAYLOAD; end endcase end else begin state_next = STATE_WRITE_HEADER; end end - STATE_WRITE_PAYLOAD_IDLE: begin - // idle; no data in registers - if (input_udp_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; + STATE_WRITE_PAYLOAD: begin + // write payload + input_udp_payload_tready_next = output_ip_payload_tready_int_early; + + output_ip_payload_tdata_int = input_udp_payload_tdata; + output_ip_payload_tvalid_int = input_udp_payload_tvalid; + output_ip_payload_tlast_int = input_udp_payload_tlast; + output_ip_payload_tuser_int = input_udp_payload_tuser; + + if (input_udp_payload_tready & input_udp_payload_tvalid) begin + // word transfer through frame_ptr_next = frame_ptr_reg+1; if (input_udp_payload_tlast) begin if (frame_ptr_next != udp_length_reg) begin // end of frame, but length does not match - assert_tuser = 1; + output_ip_payload_tuser_int = 1; error_payload_early_termination_next = 1; end - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_udp_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin if (frame_ptr_next == udp_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + store_last_word = 1; + output_ip_payload_tvalid_int = 0; + state_next = STATE_WRITE_PAYLOAD_LAST; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + state_next = STATE_WRITE_PAYLOAD; end end end else begin - state_next = STATE_WRITE_PAYLOAD_IDLE; + state_next = STATE_WRITE_PAYLOAD; end end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register - if (input_udp_payload_tvalid & output_ip_payload_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - frame_ptr_next = frame_ptr_reg+1; + STATE_WRITE_PAYLOAD_LAST: begin + // read and discard until end of frame + input_udp_payload_tready_next = output_ip_payload_tready_int_early; + + output_ip_payload_tdata_int = last_word_data_reg; + output_ip_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tlast; + output_ip_payload_tlast_int = input_udp_payload_tlast; + output_ip_payload_tuser_int = input_udp_payload_tuser; + + if (input_udp_payload_tready & input_udp_payload_tvalid) begin if (input_udp_payload_tlast) begin - if (frame_ptr_next != udp_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_udp_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin - if (frame_ptr_next == udp_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - end else if (~input_udp_payload_tvalid & output_ip_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_WRITE_PAYLOAD_IDLE; - end else if (input_udp_payload_tvalid & ~output_ip_payload_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - frame_ptr_next = frame_ptr_reg+1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in both output and temp registers - if (output_ip_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_ip_payload_tlast_reg) begin - if (frame_ptr_next != udp_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - if (frame_ptr_next == udp_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end + state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - if (output_ip_payload_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - if (input_udp_payload_tvalid) begin - if (input_udp_payload_tlast) begin - // assert tlast and transfer tuser - assert_tlast = 1; - assert_tuser = input_udp_payload_tuser; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + state_next = STATE_WRITE_PAYLOAD_LAST; end end STATE_WAIT_LAST: begin // wait for end of frame; read and discard + input_udp_payload_tready_next = 1; + if (input_udp_payload_tvalid) begin if (input_udp_payload_tlast) begin + input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_udp_payload_tready_next = 0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -415,7 +356,7 @@ always @(posedge clk or posedge rst) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; - hdr_sum_reg <= 0; + last_word_data_reg <= 0; input_udp_hdr_ready_reg <= 0; input_udp_payload_tready_reg <= 0; udp_source_port_reg <= 0; @@ -443,9 +384,6 @@ always @(posedge clk or posedge rst) begin output_ip_payload_tvalid_reg <= 0; output_ip_payload_tlast_reg <= 0; output_ip_payload_tuser_reg <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; busy_reg <= 0; error_payload_early_termination_reg <= 0; end else begin @@ -453,7 +391,8 @@ always @(posedge clk or posedge rst) begin frame_ptr_reg <= frame_ptr_next; - hdr_sum_reg <= hdr_sum_next; + input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; + input_udp_payload_tready_reg <= input_udp_payload_tready_next; output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; @@ -461,58 +400,7 @@ always @(posedge clk or posedge rst) begin error_payload_early_termination_reg <= error_payload_early_termination_next; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_udp_hdr_ready_reg <= 1; - input_udp_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - end - STATE_WRITE_HEADER: begin - // write header - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_IDLE: begin - // write payload; no data in registers; accept new data - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register; accept new data - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in output and temp registers; do not accept new data - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 0; - end - STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 0; - end - endcase - + // datapath if (store_udp_hdr) begin output_eth_dest_mac_reg <= input_eth_dest_mac; output_eth_src_mac_reg <= input_eth_src_mac; @@ -536,26 +424,72 @@ always @(posedge clk or posedge rst) begin udp_checksum_reg <= input_udp_checksum; end - if (write_hdr_out) begin - output_ip_payload_tdata_reg <= write_hdr_data; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - end else if (transfer_in_out) begin - output_ip_payload_tdata_reg <= input_udp_payload_tdata; - output_ip_payload_tlast_reg <= input_udp_payload_tlast; - output_ip_payload_tuser_reg <= input_udp_payload_tuser; - end else if (transfer_in_temp) begin - temp_ip_payload_tdata_reg <= input_udp_payload_tdata; - temp_ip_payload_tlast_reg <= input_udp_payload_tlast; - temp_ip_payload_tuser_reg <= input_udp_payload_tuser; - end else if (transfer_temp_out) begin + if (store_last_word) begin + last_word_data_reg <= output_ip_payload_tdata_int; + end + end +end + +// output datapath logic +reg [7:0] output_ip_payload_tdata_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [7:0] temp_ip_payload_tdata_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; end - - if (assert_tlast) output_ip_payload_tlast_reg <= 1; - if (assert_tuser) output_ip_payload_tuser_reg <= 1; end end diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index 89e378617..1b4e11a02 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -130,52 +130,37 @@ UDP Frame payload length octets -This module receives an IP frame with decoded fields and decodes -the AXI packet format. If the Ethertype does not match, the packet is -discarded. +This module receives a UDP frame with header fields in parallel along with the +payload in an AXI stream, combines the header with the payload, passes through +the IP headers, and transmits the complete IP payload on an AXI interface. */ localparam [2:0] STATE_IDLE = 3'd0, - STATE_WRITE_PAYLOAD_IDLE = 3'd1, - STATE_WRITE_PAYLOAD_TRANSFER = 3'd2, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT = 3'd3, - STATE_WRITE_PAYLOAD_TRANSFER_LAST = 3'd4, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST = 3'd5, - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT = 3'd6, - STATE_WAIT_LAST = 3'd7; + STATE_WRITE_HEADER = 3'd1, + STATE_WRITE_PAYLOAD = 3'd2, + STATE_WRITE_PAYLOAD_LAST = 3'd3, + STATE_WAIT_LAST = 3'd4; reg [2:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_udp_hdr; - -reg [63:0] write_hdr_data; -reg [7:0] write_hdr_keep; -reg write_hdr_last; -reg write_hdr_user; -reg write_hdr_out; - -reg transfer_in_out; -reg transfer_in_temp; -reg transfer_temp_out; - -reg assert_tlast; -reg assert_tuser; -reg [7:0] tkeep_mask; +reg store_last_word; reg [15:0] frame_ptr_reg = 0, frame_ptr_next; -reg [15:0] hdr_sum_reg = 0, hdr_sum_next; +reg [63:0] last_word_data_reg = 0; +reg [7:0] last_word_keep_reg = 0; reg [15:0] udp_source_port_reg = 0; reg [15:0] udp_dest_port_reg = 0; reg [15:0] udp_length_reg = 0; reg [15:0] udp_checksum_reg = 0; -reg input_udp_hdr_ready_reg = 0; -reg input_udp_payload_tready_reg = 0; +reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; @@ -194,19 +179,18 @@ reg [7:0] output_ip_protocol_reg = 0; reg [15:0] output_ip_header_checksum_reg = 0; reg [31:0] output_ip_source_ip_reg = 0; reg [31:0] output_ip_dest_ip_reg = 0; -reg [63:0] output_ip_payload_tdata_reg = 0; -reg [7:0] output_ip_payload_tkeep_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; reg busy_reg = 0; reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; -reg [63:0] temp_ip_payload_tdata_reg = 0; -reg [7:0] temp_ip_payload_tkeep_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +// internal datapath +reg [63:0] output_ip_payload_tdata_int; +reg [7:0] output_ip_payload_tkeep_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; assign input_udp_hdr_ready = input_udp_hdr_ready_reg; assign input_udp_payload_tready = input_udp_payload_tready_reg; @@ -228,11 +212,6 @@ assign output_ip_protocol = output_ip_protocol_reg; assign output_ip_header_checksum = output_ip_header_checksum_reg; assign output_ip_source_ip = output_ip_source_ip_reg; assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; assign busy = busy_reg; assign error_payload_early_termination = error_payload_early_termination_reg; @@ -270,193 +249,153 @@ endfunction always @* begin state_next = 2'bz; + input_udp_hdr_ready_next = 0; + input_udp_payload_tready_next = 0; + store_udp_hdr = 0; - write_hdr_data = 0; - write_hdr_keep = 0; - write_hdr_last = 0; - write_hdr_user = 0; - write_hdr_out = 0; - - transfer_in_out = 0; - transfer_in_temp = 0; - transfer_temp_out = 0; - - assert_tlast = 0; - assert_tuser = 0; - tkeep_mask = 8'hff; + store_last_word = 0; frame_ptr_next = frame_ptr_reg; - hdr_sum_next = hdr_sum_reg; - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; error_payload_early_termination_next = 0; + output_ip_payload_tdata_int = 0; + output_ip_payload_tkeep_int = 0; + output_ip_payload_tvalid_int = 0; + output_ip_payload_tlast_int = 0; + output_ip_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - if (input_udp_hdr_valid & input_udp_hdr_ready) begin + if (input_udp_hdr_ready & input_udp_hdr_valid) begin store_udp_hdr = 1; - write_hdr_out = 1; - write_hdr_data[ 7: 0] = input_udp_source_port[15: 8]; - write_hdr_data[15: 8] = input_udp_source_port[ 7: 0]; - write_hdr_data[23:16] = input_udp_dest_port[15: 8]; - write_hdr_data[31:24] = input_udp_dest_port[ 7: 0]; - write_hdr_data[39:32] = input_udp_length[15: 8]; - write_hdr_data[47:40] = input_udp_length[ 7: 0]; - write_hdr_data[55:48] = input_udp_checksum[15: 8]; - write_hdr_data[63:56] = input_udp_checksum[ 7: 0]; - write_hdr_keep = 8'hff; + input_udp_hdr_ready_next = 0; output_ip_hdr_valid_next = 1; - frame_ptr_next = 8; - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + state_next = STATE_WRITE_HEADER; + if (output_ip_payload_tready_int) begin + output_ip_payload_tvalid_int = 1; + output_ip_payload_tdata_int[ 7: 0] = input_udp_source_port[15: 8]; + output_ip_payload_tdata_int[15: 8] = input_udp_source_port[ 7: 0]; + output_ip_payload_tdata_int[23:16] = input_udp_dest_port[15: 8]; + output_ip_payload_tdata_int[31:24] = input_udp_dest_port[ 7: 0]; + output_ip_payload_tdata_int[39:32] = input_udp_length[15: 8]; + output_ip_payload_tdata_int[47:40] = input_udp_length[ 7: 0]; + output_ip_payload_tdata_int[55:48] = input_udp_checksum[15: 8]; + output_ip_payload_tdata_int[63:56] = input_udp_checksum[ 7: 0]; + output_ip_payload_tkeep_int = 8'hff; + frame_ptr_next = 8; + input_udp_payload_tready_next = output_ip_payload_tready_int_early; + state_next = STATE_WRITE_PAYLOAD; + end end else begin state_next = STATE_IDLE; end end - STATE_WRITE_PAYLOAD_IDLE: begin - // idle; no data in registers - if (input_udp_payload_tvalid) begin - // word transfer in - store it in output register - transfer_in_out = 1; + STATE_WRITE_HEADER: begin + // write header state + if (output_ip_payload_tready_int) begin + // word transfer out + frame_ptr_next = frame_ptr_reg+8; + output_ip_payload_tvalid_int = 1; + state_next = STATE_WRITE_HEADER; + case (frame_ptr_reg) + 8'h00: begin + output_ip_payload_tdata_int[ 7: 0] = input_udp_source_port[15: 8]; + output_ip_payload_tdata_int[15: 8] = input_udp_source_port[ 7: 0]; + output_ip_payload_tdata_int[23:16] = input_udp_dest_port[15: 8]; + output_ip_payload_tdata_int[31:24] = input_udp_dest_port[ 7: 0]; + output_ip_payload_tdata_int[39:32] = input_udp_length[15: 8]; + output_ip_payload_tdata_int[47:40] = input_udp_length[ 7: 0]; + output_ip_payload_tdata_int[55:48] = input_udp_checksum[15: 8]; + output_ip_payload_tdata_int[63:56] = input_udp_checksum[ 7: 0]; + output_ip_payload_tkeep_int = 8'hff; + input_udp_payload_tready_next = output_ip_payload_tready_int_early; + state_next = STATE_WRITE_PAYLOAD; + end + endcase + end else begin + state_next = STATE_WRITE_HEADER; + end + end + STATE_WRITE_PAYLOAD: begin + // write payload + input_udp_payload_tready_next = output_ip_payload_tready_int_early; + + output_ip_payload_tdata_int = input_udp_payload_tdata; + output_ip_payload_tkeep_int = input_udp_payload_tkeep; + output_ip_payload_tvalid_int = input_udp_payload_tvalid; + output_ip_payload_tlast_int = input_udp_payload_tlast; + output_ip_payload_tuser_int = input_udp_payload_tuser; + + if (output_ip_payload_tready_int & input_udp_payload_tvalid) begin + // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(input_udp_payload_tkeep); if (frame_ptr_next >= udp_length_reg) begin // have entire payload frame_ptr_next = udp_length_reg; - tkeep_mask = count2keep(udp_length_reg - frame_ptr_reg); + output_ip_payload_tkeep_int = count2keep(udp_length_reg - frame_ptr_reg); if (input_udp_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_udp_payload_tready_next = 0; + input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + state_next = STATE_IDLE; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + store_last_word = 1; + output_ip_payload_tvalid_int = 0; + state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin if (input_udp_payload_tlast) begin // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; error_payload_early_termination_next = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + output_ip_payload_tuser_int = 1; + input_udp_payload_tready_next = 0; + input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + state_next = STATE_IDLE; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; + state_next = STATE_WRITE_PAYLOAD; end end end else begin - state_next = STATE_WRITE_PAYLOAD_IDLE; + state_next = STATE_WRITE_PAYLOAD; end end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register - if (input_udp_payload_tvalid & output_ip_payload_tready) begin - // word transfer through - update output register - transfer_in_out = 1; - frame_ptr_next = frame_ptr_reg+keep2count(input_udp_payload_tkeep); - if (frame_ptr_next >= udp_length_reg) begin - // have entire payload - frame_ptr_next = udp_length_reg; - tkeep_mask = count2keep(udp_length_reg - frame_ptr_reg); - if (input_udp_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end - end else begin - if (input_udp_payload_tlast) begin - // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; - error_payload_early_termination_next = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - end else if (~input_udp_payload_tvalid & output_ip_payload_tready) begin - // word transfer out - go back to idle - state_next = STATE_WRITE_PAYLOAD_IDLE; - end else if (input_udp_payload_tvalid & ~output_ip_payload_tready) begin - // word transfer in - store in temp - transfer_in_temp = 1; - frame_ptr_next = frame_ptr_reg+keep2count(input_udp_payload_tkeep); - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - if (frame_ptr_next >= udp_length_reg) begin - // have entire payload - frame_ptr_next = udp_length_reg; - tkeep_mask = count2keep(udp_length_reg - frame_ptr_reg); - if (~input_udp_payload_tlast) begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; - end - end - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in both output and temp registers - if (output_ip_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - if (temp_ip_payload_tlast_reg) begin - if (frame_ptr_next < udp_length_reg) begin - // end of frame, but length does not match - assert_tuser = 1; - assert_tlast = 1; - error_payload_early_termination_next = 1; - end - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end else begin - if (frame_ptr_next >= udp_length_reg) begin - // not end of frame, but we have the entire payload - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER; - end - end - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - if (output_ip_payload_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - if (input_udp_payload_tvalid) begin + STATE_WRITE_PAYLOAD_LAST: begin + // read and discard until end of frame + input_udp_payload_tready_next = output_ip_payload_tready_int_early; + + output_ip_payload_tdata_int = last_word_data_reg; + output_ip_payload_tkeep_int = last_word_keep_reg; + output_ip_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tlast; + output_ip_payload_tlast_int = input_udp_payload_tlast; + output_ip_payload_tuser_int = input_udp_payload_tuser; + + if (input_udp_payload_tready & input_udp_payload_tvalid) begin if (input_udp_payload_tlast) begin - // assert tlast and transfer tuser - assert_tlast = 1; - assert_tuser = input_udp_payload_tuser; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_LAST; + input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_udp_payload_tready_next = 0; + state_next = STATE_IDLE; end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; + state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin - // wait for end of frame; data in both output and temp registers; read and discard - if (output_ip_payload_tready) begin - // transfer out - move temp to output - transfer_temp_out = 1; - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST; - end else begin - state_next = STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT; + state_next = STATE_WRITE_PAYLOAD_LAST; end end STATE_WAIT_LAST: begin // wait for end of frame; read and discard + input_udp_payload_tready_next = 1; + if (input_udp_payload_tvalid) begin if (input_udp_payload_tlast) begin + input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_udp_payload_tready_next = 0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -472,7 +411,8 @@ always @(posedge clk or posedge rst) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; - hdr_sum_reg <= 0; + last_word_data_reg <= 0; + last_word_keep_reg <= 0; input_udp_hdr_ready_reg <= 0; input_udp_payload_tready_reg <= 0; udp_source_port_reg <= 0; @@ -500,9 +440,6 @@ always @(posedge clk or posedge rst) begin output_ip_payload_tvalid_reg <= 0; output_ip_payload_tlast_reg <= 0; output_ip_payload_tuser_reg <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; busy_reg <= 0; error_payload_early_termination_reg <= 0; end else begin @@ -510,7 +447,8 @@ always @(posedge clk or posedge rst) begin frame_ptr_reg <= frame_ptr_next; - hdr_sum_reg <= hdr_sum_next; + input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; + input_udp_payload_tready_reg <= input_udp_payload_tready_next; output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; @@ -518,58 +456,7 @@ always @(posedge clk or posedge rst) begin error_payload_early_termination_reg <= error_payload_early_termination_next; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_udp_hdr_ready_reg <= 1; - input_udp_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_IDLE: begin - // write payload; no data in registers; accept new data - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_TRANSFER: begin - // write payload; data in output register; accept new data - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT: begin - // write payload; data in output and temp registers; do not accept new data - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_LAST: begin - // write last payload word; data in output register; do not accept new data - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST: begin - // wait for end of frame; data in output register; read and discard - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 0; - end - STATE_WRITE_PAYLOAD_TRANSFER_WAIT_LAST_WAIT: begin - // wait for end of frame; data in output and temp registers; do not accept new data - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; - output_ip_payload_tvalid_reg <= 1; - end - STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 1; - output_ip_payload_tvalid_reg <= 0; - end - endcase - + // datapath if (store_udp_hdr) begin output_eth_dest_mac_reg <= input_eth_dest_mac; output_eth_src_mac_reg <= input_eth_src_mac; @@ -593,30 +480,82 @@ always @(posedge clk or posedge rst) begin udp_checksum_reg <= input_udp_checksum; end - if (write_hdr_out) begin - output_ip_payload_tdata_reg <= write_hdr_data; - output_ip_payload_tkeep_reg <= write_hdr_keep & tkeep_mask; - output_ip_payload_tlast_reg <= write_hdr_last; - output_ip_payload_tuser_reg <= write_hdr_user; - end else if (transfer_in_out) begin - output_ip_payload_tdata_reg <= input_udp_payload_tdata; - output_ip_payload_tkeep_reg <= input_udp_payload_tkeep & tkeep_mask; - output_ip_payload_tlast_reg <= input_udp_payload_tlast; - output_ip_payload_tuser_reg <= input_udp_payload_tuser; - end else if (transfer_in_temp) begin - temp_ip_payload_tdata_reg <= input_udp_payload_tdata; - temp_ip_payload_tkeep_reg <= input_udp_payload_tkeep & tkeep_mask; - temp_ip_payload_tlast_reg <= input_udp_payload_tlast; - temp_ip_payload_tuser_reg <= input_udp_payload_tuser; - end else if (transfer_temp_out) begin + if (store_last_word) begin + last_word_data_reg <= output_ip_payload_tdata_int; + last_word_keep_reg <= output_ip_payload_tkeep_int; + end + end +end + +// output datapath logic +reg [63:0] output_ip_payload_tdata_reg = 0; +reg [7:0] output_ip_payload_tkeep_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [63:0] temp_ip_payload_tdata_reg = 0; +reg [7:0] temp_ip_payload_tkeep_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tkeep_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; end - - if (assert_tlast) output_ip_payload_tlast_reg <= 1; - if (assert_tuser) output_ip_payload_tuser_reg <= 1; end end From 0f62d31fefe477bb40dd5ec62e7bd8ae2b43cd5f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Oct 2014 01:55:36 -0700 Subject: [PATCH 067/617] Rework ARP datapath modules to separate output register --- rtl/arp_eth_rx.v | 50 ++++---- rtl/arp_eth_rx_64.v | 54 +++++---- rtl/arp_eth_tx.v | 227 +++++++++++++++++++++---------------- rtl/arp_eth_tx_64.v | 270 ++++++++++++++++++++++++++------------------ 4 files changed, 335 insertions(+), 266 deletions(-) diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index 33ab19cec..75961cbe4 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -92,9 +92,9 @@ ARP Frame THA Target MAC 6 octets TPA Target IP 4 octets -This module receives an Ethernet frame with decoded fields and decodes -the ARP packet format. If the Ethertype does not match, the packet is -discarded. +This module receives an Ethernet frame with header fields in parallel and +payload on an AXI stream interface, decodes the ARP packet fields, and +produces the frame fields in parallel. */ @@ -138,8 +138,8 @@ reg store_arp_tpa_3; reg [7:0] frame_ptr_reg = 0, frame_ptr_next; -reg input_eth_hdr_ready_reg = 0; -reg input_eth_payload_tready_reg = 0; +reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; reg output_frame_valid_reg = 0, output_frame_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; @@ -183,6 +183,9 @@ assign error_invalid_header = error_invalid_header_reg; always @* begin state_next = 2'bz; + input_eth_hdr_ready_next = 0; + input_eth_payload_tready_next = 0; + store_eth_hdr = 0; store_arp_htype_0 = 0; store_arp_htype_1 = 0; @@ -224,9 +227,11 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + input_eth_hdr_ready_next = ~output_frame_valid_reg; if (input_eth_hdr_ready & input_eth_hdr_valid) begin - frame_ptr_next = 0; + input_eth_hdr_ready_next = 0; + input_eth_payload_tready_next = 1; store_eth_hdr = 1; state_next = STATE_READ_HEADER; end else begin @@ -235,6 +240,8 @@ always @* begin end STATE_READ_HEADER: begin // read header state + input_eth_payload_tready_next = 1; + if (input_eth_payload_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg+1; @@ -274,7 +281,6 @@ always @* begin endcase if (input_eth_payload_tlast) begin // end of frame - state_next = STATE_IDLE; if (frame_ptr_reg != 8'h1B) begin // don't have the whole header error_header_early_termination_next = 1; @@ -285,6 +291,9 @@ always @* begin // otherwise, transfer tuser output_frame_valid_next = ~input_eth_payload_tuser; end + input_eth_hdr_ready_next = ~output_frame_valid_reg; + input_eth_payload_tready_next = 0; + state_next = STATE_IDLE; end end else begin state_next = STATE_READ_HEADER; @@ -292,6 +301,8 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard + input_eth_payload_tready_next = 1; + if (input_eth_payload_tvalid) begin if (input_eth_payload_tlast) begin if (output_arp_hlen != 6 || output_arp_plen != 4) begin @@ -301,11 +312,14 @@ always @* begin // otherwise, transfer tuser output_frame_valid_next = ~input_eth_payload_tuser; end + input_eth_hdr_ready_next = ~output_frame_valid_reg; + input_eth_payload_tready_next = 0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; end end else begin + // wait for end of frame; read and discard state_next = STATE_WAIT_LAST; end end @@ -327,6 +341,9 @@ always @(posedge clk or posedge rst) begin end else begin state_reg <= state_next; + input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + input_eth_payload_tready_reg <= input_eth_payload_tready_next; + frame_ptr_reg <= frame_ptr_next; output_frame_valid_reg <= output_frame_valid_next; @@ -336,25 +353,6 @@ always @(posedge clk or posedge rst) begin busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_eth_hdr_ready_reg <= ~output_frame_valid; - input_eth_payload_tready_reg <= 0; - end - STATE_READ_HEADER: begin - // read header; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - end - STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - end - endcase - // datapath if (store_eth_hdr) begin output_eth_dest_mac_reg <= input_eth_dest_mac; diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index 387ebec62..7a56c52c9 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -93,9 +93,9 @@ ARP Frame THA Target MAC 6 octets TPA Target IP 4 octets -This module receives an Ethernet frame with decoded fields and decodes -the ARP packet format. If the Ethertype does not match, the packet is -discarded. +This module receives an Ethernet frame with header fields in parallel and +payload on an AXI stream interface, decodes the ARP packet fields, and +produces the frame fields in parallel. */ @@ -115,8 +115,8 @@ reg store_arp_hdr_word_3; reg [7:0] frame_ptr_reg = 0, frame_ptr_next; -reg input_eth_hdr_ready_reg = 0; -reg input_eth_payload_tready_reg = 0; +reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; reg output_frame_valid_reg = 0, output_frame_valid_next; reg [47:0] output_eth_dest_mac_reg = 0; @@ -160,6 +160,9 @@ assign error_invalid_header = error_invalid_header_reg; always @* begin state_next = 2'bz; + input_eth_hdr_ready_next = 0; + input_eth_payload_tready_next = 0; + store_eth_hdr = 0; store_arp_hdr_word_0 = 0; store_arp_hdr_word_1 = 0; @@ -177,9 +180,11 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + input_eth_hdr_ready_next = ~output_frame_valid_reg; if (input_eth_hdr_ready & input_eth_hdr_valid) begin - frame_ptr_next = 0; + input_eth_hdr_ready_next = 0; + input_eth_payload_tready_next = 1; store_eth_hdr = 1; state_next = STATE_READ_HEADER; end else begin @@ -188,6 +193,8 @@ always @* begin end STATE_READ_HEADER: begin // read header state + input_eth_payload_tready_next = 1; + if (input_eth_payload_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg+1; @@ -202,7 +209,6 @@ always @* begin end endcase if (input_eth_payload_tlast) begin - state_next = STATE_IDLE; if (frame_ptr_reg != 8'h03 | (input_eth_payload_tkeep & 8'h0F) != 8'h0F) begin error_header_early_termination_next = 1; end else if (output_arp_hlen != 6 || output_arp_plen != 4) begin @@ -210,21 +216,29 @@ always @* begin end else begin output_frame_valid_next = ~input_eth_payload_tuser; end + input_eth_hdr_ready_next = ~output_frame_valid_reg; + input_eth_payload_tready_next = 0; + state_next = STATE_IDLE; end end else begin state_next = STATE_READ_HEADER; end end STATE_WAIT_LAST: begin - // read last payload word; data in output register; do not accept new data + // wait for end of frame; read and discard + input_eth_payload_tready_next = 1; + if (input_eth_payload_tvalid) begin - // word transfer out - done if (input_eth_payload_tlast) begin if (output_arp_hlen != 6 || output_arp_plen != 4) begin + // lengths not valid error_invalid_header_next = 1; end else begin + // otherwise, transfer tuser output_frame_valid_next = ~input_eth_payload_tuser; end + input_eth_hdr_ready_next = ~output_frame_valid_reg; + input_eth_payload_tready_next = 0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -252,6 +266,9 @@ always @(posedge clk or posedge rst) begin end else begin state_reg <= state_next; + input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + input_eth_payload_tready_reg <= input_eth_payload_tready_next; + frame_ptr_reg <= frame_ptr_next; output_frame_valid_reg <= output_frame_valid_next; @@ -261,25 +278,6 @@ always @(posedge clk or posedge rst) begin busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_eth_hdr_ready_reg <= ~output_frame_valid; - input_eth_payload_tready_reg <= 0; - end - STATE_READ_HEADER: begin - // read header; accept new data - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - end - STATE_WAIT_LAST: begin - // wait for end of frame; read and discard - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 1; - end - endcase - // datapath if (store_eth_hdr) begin output_eth_dest_mac_reg <= input_eth_dest_mac; diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index de97cc231..f12475bc1 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -88,31 +88,22 @@ ARP Frame THA Target MAC 6 octets TPA Target IP 4 octets -This module receives an Ethernet frame with decoded fields and decodes -the ARP packet format. If the Ethertype does not match, the packet is -discarded. +This module receives an ARP frame with header fields in parallel and +transmits the complete Ethernet payload on an AXI interface. */ -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_WRITE_HEADER = 3'd1, - STATE_WRITE_HEADER_LAST = 3'd2; +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_WRITE_HEADER = 2'd1; -reg [2:0] state_reg = STATE_IDLE, state_next; +reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_frame; -reg [7:0] write_hdr_data; -reg write_hdr_last; -reg write_hdr_out; - reg [7:0] frame_ptr_reg = 0, frame_ptr_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; reg [15:0] arp_htype_reg = 0; reg [15:0] arp_ptype_reg = 0; reg [15:0] arp_oper_reg = 0; @@ -121,53 +112,63 @@ reg [31:0] arp_spa_reg = 0; reg [47:0] arp_tha_reg = 0; reg [31:0] arp_tpa_reg = 0; -reg input_frame_ready_reg = 0; +reg input_frame_ready_reg = 0, input_frame_ready_next; reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [7:0] output_eth_payload_tdata_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; reg busy_reg = 0; +// internal datapath +reg [7:0] output_eth_payload_tdata_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + assign input_frame_ready = input_frame_ready_reg; assign output_eth_hdr_valid = output_eth_hdr_valid_reg; assign output_eth_dest_mac = output_eth_dest_mac_reg; assign output_eth_src_mac = output_eth_src_mac_reg; assign output_eth_type = output_eth_type_reg; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; assign busy = busy_reg; always @* begin state_next = 2'bz; - store_frame = 0; + input_frame_ready_next = 0; - write_hdr_data = 0; - write_hdr_last = 0; - write_hdr_out = 0; + store_frame = 0; frame_ptr_next = frame_ptr_reg; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + output_eth_payload_tdata_int = 0; + output_eth_payload_tvalid_int = 0; + output_eth_payload_tlast_int = 0; + output_eth_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + input_frame_ready_next = ~output_eth_hdr_valid_reg; - if (input_frame_valid) begin + if (input_frame_ready & input_frame_valid) begin store_frame = 1; - write_hdr_out = 1; - write_hdr_data = input_arp_htype[15: 8]; + input_frame_ready_next = 0; output_eth_hdr_valid_next = 1; - frame_ptr_next = 1; + if (output_eth_payload_tready_int) begin + output_eth_payload_tvalid_int = 1; + output_eth_payload_tdata_int = input_arp_htype[15: 8]; + frame_ptr_next = 1; + end state_next = STATE_WRITE_HEADER; end else begin state_next = STATE_IDLE; @@ -175,57 +176,49 @@ always @* begin end STATE_WRITE_HEADER: begin // read header state - if (output_eth_payload_tready) begin + if (output_eth_payload_tready_int) begin // word transfer out frame_ptr_next = frame_ptr_reg+1; + output_eth_payload_tvalid_int = 1; state_next = STATE_WRITE_HEADER; - write_hdr_out = 1; case (frame_ptr_reg) - 8'h01: write_hdr_data = arp_htype_reg[ 7: 0]; - 8'h02: write_hdr_data = arp_ptype_reg[15: 8]; - 8'h03: write_hdr_data = arp_ptype_reg[ 7: 0]; - 8'h04: write_hdr_data = 6; // hlen - 8'h05: write_hdr_data = 4; // plen - 8'h06: write_hdr_data = arp_oper_reg[15: 8]; - 8'h07: write_hdr_data = arp_oper_reg[ 7: 0]; - 8'h08: write_hdr_data = arp_sha_reg[47:40]; - 8'h09: write_hdr_data = arp_sha_reg[39:32]; - 8'h0A: write_hdr_data = arp_sha_reg[31:24]; - 8'h0B: write_hdr_data = arp_sha_reg[23:16]; - 8'h0C: write_hdr_data = arp_sha_reg[15: 8]; - 8'h0D: write_hdr_data = arp_sha_reg[ 7: 0]; - 8'h0E: write_hdr_data = arp_spa_reg[31:24]; - 8'h0F: write_hdr_data = arp_spa_reg[23:16]; - 8'h10: write_hdr_data = arp_spa_reg[15: 8]; - 8'h11: write_hdr_data = arp_spa_reg[ 7: 0]; - 8'h12: write_hdr_data = arp_tha_reg[47:40]; - 8'h13: write_hdr_data = arp_tha_reg[39:32]; - 8'h14: write_hdr_data = arp_tha_reg[31:24]; - 8'h15: write_hdr_data = arp_tha_reg[23:16]; - 8'h16: write_hdr_data = arp_tha_reg[15: 8]; - 8'h17: write_hdr_data = arp_tha_reg[ 7: 0]; - 8'h18: write_hdr_data = arp_tpa_reg[31:24]; - 8'h19: write_hdr_data = arp_tpa_reg[23:16]; - 8'h1A: write_hdr_data = arp_tpa_reg[15: 8]; + 8'h01: output_eth_payload_tdata_int = arp_htype_reg[ 7: 0]; + 8'h02: output_eth_payload_tdata_int = arp_ptype_reg[15: 8]; + 8'h03: output_eth_payload_tdata_int = arp_ptype_reg[ 7: 0]; + 8'h04: output_eth_payload_tdata_int = 6; // hlen + 8'h05: output_eth_payload_tdata_int = 4; // plen + 8'h06: output_eth_payload_tdata_int = arp_oper_reg[15: 8]; + 8'h07: output_eth_payload_tdata_int = arp_oper_reg[ 7: 0]; + 8'h08: output_eth_payload_tdata_int = arp_sha_reg[47:40]; + 8'h09: output_eth_payload_tdata_int = arp_sha_reg[39:32]; + 8'h0A: output_eth_payload_tdata_int = arp_sha_reg[31:24]; + 8'h0B: output_eth_payload_tdata_int = arp_sha_reg[23:16]; + 8'h0C: output_eth_payload_tdata_int = arp_sha_reg[15: 8]; + 8'h0D: output_eth_payload_tdata_int = arp_sha_reg[ 7: 0]; + 8'h0E: output_eth_payload_tdata_int = arp_spa_reg[31:24]; + 8'h0F: output_eth_payload_tdata_int = arp_spa_reg[23:16]; + 8'h10: output_eth_payload_tdata_int = arp_spa_reg[15: 8]; + 8'h11: output_eth_payload_tdata_int = arp_spa_reg[ 7: 0]; + 8'h12: output_eth_payload_tdata_int = arp_tha_reg[47:40]; + 8'h13: output_eth_payload_tdata_int = arp_tha_reg[39:32]; + 8'h14: output_eth_payload_tdata_int = arp_tha_reg[31:24]; + 8'h15: output_eth_payload_tdata_int = arp_tha_reg[23:16]; + 8'h16: output_eth_payload_tdata_int = arp_tha_reg[15: 8]; + 8'h17: output_eth_payload_tdata_int = arp_tha_reg[ 7: 0]; + 8'h18: output_eth_payload_tdata_int = arp_tpa_reg[31:24]; + 8'h19: output_eth_payload_tdata_int = arp_tpa_reg[23:16]; + 8'h1A: output_eth_payload_tdata_int = arp_tpa_reg[15: 8]; 8'h1B: begin - write_hdr_data = arp_tpa_reg[ 7: 0]; - write_hdr_last = 1; - state_next = STATE_WRITE_HEADER_LAST; + output_eth_payload_tdata_int = arp_tpa_reg[ 7: 0]; + output_eth_payload_tlast_int = 1; + input_frame_ready_next = ~output_eth_hdr_valid_reg; + state_next = STATE_IDLE; end endcase end else begin state_next = STATE_WRITE_HEADER; end end - STATE_WRITE_HEADER_LAST: begin - // write last header word; data in output register - if (output_eth_payload_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_HEADER_LAST; - end - end endcase end @@ -244,39 +237,18 @@ always @(posedge clk or posedge rst) begin arp_spa_reg <= 0; arp_tha_reg <= 0; arp_tpa_reg <= 0; - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; busy_reg <= 0; end else begin state_reg <= state_next; frame_ptr_reg <= frame_ptr_next; + input_frame_ready_reg <= input_frame_ready_next; + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_frame_ready_reg <= ~output_eth_hdr_valid; - output_eth_payload_tvalid_reg <= 0; - end - STATE_WRITE_HEADER: begin - // write header - input_frame_ready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_HEADER_LAST: begin - // write last header word; data in output register - input_frame_ready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - endcase - if (store_frame) begin output_eth_dest_mac_reg <= input_eth_dest_mac; output_eth_src_mac_reg <= input_eth_src_mac; @@ -289,11 +261,68 @@ always @(posedge clk or posedge rst) begin arp_tha_reg <= input_arp_tha; arp_tpa_reg <= input_arp_tpa; end + end +end - if (write_hdr_out) begin - output_eth_payload_tdata_reg <= write_hdr_data; - output_eth_payload_tlast_reg <= write_hdr_last; - output_eth_payload_tuser_reg <= 0; +// output datapath logic +reg [7:0] output_eth_payload_tdata_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_eth_payload_tdata_int; + temp_axis_tvalid_reg <= output_eth_payload_tvalid_int; + temp_axis_tlast_reg <= output_eth_payload_tlast_int; + temp_axis_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_axis_tdata_reg; + output_eth_payload_tvalid_reg <= temp_axis_tvalid_reg; + output_eth_payload_tlast_reg <= temp_axis_tlast_reg; + output_eth_payload_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; end end end diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index 61743b789..ee12b501e 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -89,32 +89,22 @@ ARP Frame THA Target MAC 6 octets TPA Target IP 4 octets -This module receives an Ethernet frame with decoded fields and decodes -the ARP packet format. If the Ethertype does not match, the packet is -discarded. +This module receives an ARP frame with header fields in parallel and +transmits the complete Ethernet payload on an AXI interface. */ -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_WRITE_HEADER = 3'd1, - STATE_WRITE_HEADER_LAST = 3'd2; +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_WRITE_HEADER = 2'd1; -reg [2:0] state_reg = STATE_IDLE, state_next; +reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_frame; -reg [63:0] write_hdr_data; -reg [7:0] write_hdr_keep; -reg write_hdr_last; -reg write_hdr_out; - reg [7:0] frame_ptr_reg = 0, frame_ptr_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; reg [15:0] arp_htype_reg = 0; reg [15:0] arp_ptype_reg = 0; reg [15:0] arp_oper_reg = 0; @@ -123,64 +113,72 @@ reg [31:0] arp_spa_reg = 0; reg [47:0] arp_tha_reg = 0; reg [31:0] arp_tpa_reg = 0; -reg input_frame_ready_reg = 0; +reg input_frame_ready_reg = 0, input_frame_ready_next; reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [47:0] output_eth_dest_mac_reg = 0; +reg [47:0] output_eth_src_mac_reg = 0; +reg [15:0] output_eth_type_reg = 0; reg busy_reg = 0; +// internal datapath +reg [63:0] output_eth_payload_tdata_int; +reg [7:0] output_eth_payload_tkeep_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + assign input_frame_ready = input_frame_ready_reg; assign output_eth_hdr_valid = output_eth_hdr_valid_reg; assign output_eth_dest_mac = output_eth_dest_mac_reg; assign output_eth_src_mac = output_eth_src_mac_reg; assign output_eth_type = output_eth_type_reg; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; assign busy = busy_reg; always @* begin state_next = 2'bz; - store_frame = 0; + input_frame_ready_next = 0; - write_hdr_data = 0; - write_hdr_keep = 0; - write_hdr_last = 0; - write_hdr_out = 0; + store_frame = 0; frame_ptr_next = frame_ptr_reg; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + output_eth_payload_tdata_int = 0; + output_eth_payload_tvalid_int = 0; + output_eth_payload_tlast_int = 0; + output_eth_payload_tuser_int = 0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 0; + input_frame_ready_next = ~output_eth_hdr_valid_reg; - if (input_frame_valid) begin + if (input_frame_ready & input_frame_valid) begin store_frame = 1; - write_hdr_out = 1; - write_hdr_data[ 7: 0] = input_arp_htype[15: 8]; - write_hdr_data[15: 8] = input_arp_htype[ 7: 0]; - write_hdr_data[23:16] = input_arp_ptype[15: 8]; - write_hdr_data[31:24] = input_arp_ptype[ 7: 0]; - write_hdr_data[39:32] = 6; // hlen - write_hdr_data[47:40] = 4; // plen - write_hdr_data[55:48] = input_arp_oper[15: 8]; - write_hdr_data[63:56] = input_arp_oper[ 7: 0]; - write_hdr_keep = 8'hff; - frame_ptr_next = 8; + input_frame_ready_next = 0; output_eth_hdr_valid_next = 1; + if (output_eth_payload_tready_int) begin + output_eth_payload_tvalid_int = 1; + output_eth_payload_tdata_int[ 7: 0] = input_arp_htype[15: 8]; + output_eth_payload_tdata_int[15: 8] = input_arp_htype[ 7: 0]; + output_eth_payload_tdata_int[23:16] = input_arp_ptype[15: 8]; + output_eth_payload_tdata_int[31:24] = input_arp_ptype[ 7: 0]; + output_eth_payload_tdata_int[39:32] = 6; // hlen + output_eth_payload_tdata_int[47:40] = 4; // plen + output_eth_payload_tdata_int[55:48] = input_arp_oper[15: 8]; + output_eth_payload_tdata_int[63:56] = input_arp_oper[ 7: 0]; + output_eth_payload_tkeep_int = 8'hff; + frame_ptr_next = 8; + end state_next = STATE_WRITE_HEADER; end else begin state_next = STATE_IDLE; @@ -188,61 +186,64 @@ always @* begin end STATE_WRITE_HEADER: begin // read header state - if (output_eth_payload_tready) begin + if (output_eth_payload_tready_int) begin // word transfer out frame_ptr_next = frame_ptr_reg+8; + output_eth_payload_tvalid_int = 1; state_next = STATE_WRITE_HEADER; - write_hdr_out = 1; case (frame_ptr_reg) + 8'h00: begin + output_eth_payload_tdata_int[ 7: 0] = input_arp_htype[15: 8]; + output_eth_payload_tdata_int[15: 8] = input_arp_htype[ 7: 0]; + output_eth_payload_tdata_int[23:16] = input_arp_ptype[15: 8]; + output_eth_payload_tdata_int[31:24] = input_arp_ptype[ 7: 0]; + output_eth_payload_tdata_int[39:32] = 6; // hlen + output_eth_payload_tdata_int[47:40] = 4; // plen + output_eth_payload_tdata_int[55:48] = input_arp_oper[15: 8]; + output_eth_payload_tdata_int[63:56] = input_arp_oper[ 7: 0]; + output_eth_payload_tkeep_int = 8'hff; + end 8'h08: begin - write_hdr_data[ 7: 0] = arp_sha_reg[47:40]; - write_hdr_data[15: 8] = arp_sha_reg[39:32]; - write_hdr_data[23:16] = arp_sha_reg[31:24]; - write_hdr_data[31:24] = arp_sha_reg[23:16]; - write_hdr_data[39:32] = arp_sha_reg[15: 8]; - write_hdr_data[47:40] = arp_sha_reg[ 7: 0]; - write_hdr_data[55:48] = arp_spa_reg[31:24]; - write_hdr_data[63:56] = arp_spa_reg[23:16]; - write_hdr_keep = 8'hff; + output_eth_payload_tdata_int[ 7: 0] = arp_sha_reg[47:40]; + output_eth_payload_tdata_int[15: 8] = arp_sha_reg[39:32]; + output_eth_payload_tdata_int[23:16] = arp_sha_reg[31:24]; + output_eth_payload_tdata_int[31:24] = arp_sha_reg[23:16]; + output_eth_payload_tdata_int[39:32] = arp_sha_reg[15: 8]; + output_eth_payload_tdata_int[47:40] = arp_sha_reg[ 7: 0]; + output_eth_payload_tdata_int[55:48] = arp_spa_reg[31:24]; + output_eth_payload_tdata_int[63:56] = arp_spa_reg[23:16]; + output_eth_payload_tkeep_int = 8'hff; end 8'h10: begin - write_hdr_data[ 7: 0] = arp_spa_reg[15: 8]; - write_hdr_data[15: 8] = arp_spa_reg[ 7: 0]; - write_hdr_data[23:16] = arp_tha_reg[47:40]; - write_hdr_data[31:24] = arp_tha_reg[39:32]; - write_hdr_data[39:32] = arp_tha_reg[31:24]; - write_hdr_data[47:40] = arp_tha_reg[23:16]; - write_hdr_data[55:48] = arp_tha_reg[15: 8]; - write_hdr_data[63:56] = arp_tha_reg[ 7: 0]; - write_hdr_keep = 8'hff; + output_eth_payload_tdata_int[ 7: 0] = arp_spa_reg[15: 8]; + output_eth_payload_tdata_int[15: 8] = arp_spa_reg[ 7: 0]; + output_eth_payload_tdata_int[23:16] = arp_tha_reg[47:40]; + output_eth_payload_tdata_int[31:24] = arp_tha_reg[39:32]; + output_eth_payload_tdata_int[39:32] = arp_tha_reg[31:24]; + output_eth_payload_tdata_int[47:40] = arp_tha_reg[23:16]; + output_eth_payload_tdata_int[55:48] = arp_tha_reg[15: 8]; + output_eth_payload_tdata_int[63:56] = arp_tha_reg[ 7: 0]; + output_eth_payload_tkeep_int = 8'hff; end 8'h18: begin - write_hdr_data[ 7: 0] = arp_tpa_reg[31:24]; - write_hdr_data[15: 8] = arp_tpa_reg[23:16]; - write_hdr_data[23:16] = arp_tpa_reg[15: 8]; - write_hdr_data[31:24] = arp_tpa_reg[ 7: 0]; - write_hdr_data[39:32] = 0; - write_hdr_data[47:40] = 0; - write_hdr_data[55:48] = 0; - write_hdr_data[63:56] = 0; - write_hdr_keep = 8'h0f; - write_hdr_last = 1; - state_next = STATE_WRITE_HEADER_LAST; + output_eth_payload_tdata_int[ 7: 0] = arp_tpa_reg[31:24]; + output_eth_payload_tdata_int[15: 8] = arp_tpa_reg[23:16]; + output_eth_payload_tdata_int[23:16] = arp_tpa_reg[15: 8]; + output_eth_payload_tdata_int[31:24] = arp_tpa_reg[ 7: 0]; + output_eth_payload_tdata_int[39:32] = 0; + output_eth_payload_tdata_int[47:40] = 0; + output_eth_payload_tdata_int[55:48] = 0; + output_eth_payload_tdata_int[63:56] = 0; + output_eth_payload_tkeep_int = 8'h0f; + output_eth_payload_tlast_int = 1; + input_frame_ready_next = ~output_eth_hdr_valid_reg; + state_next = STATE_IDLE; end endcase end else begin state_next = STATE_WRITE_HEADER; end end - STATE_WRITE_HEADER_LAST: begin - // write last header word; data in output register - if (output_eth_payload_tready) begin - // word transfer out - done - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_HEADER_LAST; - end - end endcase end @@ -261,40 +262,18 @@ always @(posedge clk or posedge rst) begin arp_spa_reg <= 0; arp_tha_reg <= 0; arp_tpa_reg <= 0; - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tkeep_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; busy_reg <= 0; end else begin state_reg <= state_next; frame_ptr_reg <= frame_ptr_next; + input_frame_ready_reg <= input_frame_ready_next; + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; accept new data - input_frame_ready_reg <= ~output_eth_hdr_valid; - output_eth_payload_tvalid_reg <= 0; - end - STATE_WRITE_HEADER: begin - // write header - input_frame_ready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - STATE_WRITE_HEADER_LAST: begin - // write last header word; data in output register - input_frame_ready_reg <= 0; - output_eth_payload_tvalid_reg <= 1; - end - endcase - if (store_frame) begin output_eth_dest_mac_reg <= input_eth_dest_mac; output_eth_src_mac_reg <= input_eth_src_mac; @@ -307,12 +286,77 @@ always @(posedge clk or posedge rst) begin arp_tha_reg <= input_arp_tha; arp_tpa_reg <= input_arp_tpa; end + end +end - if (write_hdr_out) begin - output_eth_payload_tdata_reg <= write_hdr_data; - output_eth_payload_tkeep_reg <= write_hdr_keep; - output_eth_payload_tlast_reg <= write_hdr_last; - output_eth_payload_tuser_reg <= 0; +// output datapath logic +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [63:0] temp_eth_payload_tdata_reg = 0; +reg [7:0] temp_eth_payload_tkeep_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tkeep_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; end end end From af0dce33b1ddf9840ce931787dbe2b870050d054 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Oct 2014 01:55:42 -0700 Subject: [PATCH 068/617] Separate out input mux in AXI frame joiner --- rtl/axis_frame_join.py | 30 +++++++++++------ rtl/axis_frame_join_4.v | 74 ++++++++++++++++++++++------------------- 2 files changed, 59 insertions(+), 45 deletions(-) diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index 19c9e9fe4..aa69ee4b6 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -156,6 +156,9 @@ reg input_tlast; reg input_tuser; reg output_tuser_reg = 0, output_tuser_next; +{% for p in ports %} +reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +{%- endfor %} // internal datapath reg [7:0] output_axis_tdata_int; @@ -165,14 +168,25 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; {% for p in ports %} -reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; -{%- endfor %} -{% for p in ports %} assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; {%- endfor %} assign busy = busy_reg; +always @* begin + // input port mux + case (port_sel_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + input_tdata = input_{{p}}_axis_tdata; + input_tvalid = input_{{p}}_axis_tvalid; + input_tlast = input_{{p}}_axis_tlast; + input_tuser = input_{{p}}_axis_tuser; + end +{%- endfor %} + endcase +end + always @* begin state_next = 2'bz; @@ -252,16 +266,10 @@ always @* begin STATE_TRANSFER: begin // transfer input data - // grab correct input lines, set ready line correctly + // set ready for current input case (port_sel_reg) {%- for p in ports %} - {{w}}'d{{p}}: begin - input_tdata = input_{{p}}_axis_tdata; - input_tvalid = input_{{p}}_axis_tvalid; - input_tlast = input_{{p}}_axis_tlast; - input_tuser = input_{{p}}_axis_tuser; - input_{{p}}_axis_tready_next = output_axis_tready_int_early; - end + {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early; {%- endfor %} endcase diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index 92270a1cc..c1430465d 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -104,6 +104,11 @@ reg input_tuser; reg output_tuser_reg = 0, output_tuser_next; +reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; + // internal datapath reg [7:0] output_axis_tdata_int; reg output_axis_tvalid_int; @@ -112,11 +117,6 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; - assign input_0_axis_tready = input_0_axis_tready_reg; assign input_1_axis_tready = input_1_axis_tready_reg; assign input_2_axis_tready = input_2_axis_tready_reg; @@ -124,6 +124,36 @@ assign input_3_axis_tready = input_3_axis_tready_reg; assign busy = busy_reg; +always @* begin + // input port mux + case (port_sel_reg) + 2'd0: begin + input_tdata = input_0_axis_tdata; + input_tvalid = input_0_axis_tvalid; + input_tlast = input_0_axis_tlast; + input_tuser = input_0_axis_tuser; + end + 2'd1: begin + input_tdata = input_1_axis_tdata; + input_tvalid = input_1_axis_tvalid; + input_tlast = input_1_axis_tlast; + input_tuser = input_1_axis_tuser; + end + 2'd2: begin + input_tdata = input_2_axis_tdata; + input_tvalid = input_2_axis_tvalid; + input_tlast = input_2_axis_tlast; + input_tuser = input_2_axis_tuser; + end + 2'd3: begin + input_tdata = input_3_axis_tdata; + input_tvalid = input_3_axis_tvalid; + input_tlast = input_3_axis_tlast; + input_tuser = input_3_axis_tuser; + end + endcase +end + always @* begin state_next = 2'bz; @@ -205,36 +235,12 @@ always @* begin STATE_TRANSFER: begin // transfer input data - // grab correct input lines, set ready line correctly + // set ready for current input case (port_sel_reg) - 2'd0: begin - input_tdata = input_0_axis_tdata; - input_tvalid = input_0_axis_tvalid; - input_tlast = input_0_axis_tlast; - input_tuser = input_0_axis_tuser; - input_0_axis_tready_next = output_axis_tready_int_early; - end - 2'd1: begin - input_tdata = input_1_axis_tdata; - input_tvalid = input_1_axis_tvalid; - input_tlast = input_1_axis_tlast; - input_tuser = input_1_axis_tuser; - input_1_axis_tready_next = output_axis_tready_int_early; - end - 2'd2: begin - input_tdata = input_2_axis_tdata; - input_tvalid = input_2_axis_tvalid; - input_tlast = input_2_axis_tlast; - input_tuser = input_2_axis_tuser; - input_2_axis_tready_next = output_axis_tready_int_early; - end - 2'd3: begin - input_tdata = input_3_axis_tdata; - input_tvalid = input_3_axis_tvalid; - input_tlast = input_3_axis_tlast; - input_tuser = input_3_axis_tuser; - input_3_axis_tready_next = output_axis_tready_int_early; - end + 2'd0: input_0_axis_tready_next = output_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_axis_tready_int_early; endcase if (input_tvalid & output_axis_tready_int) begin From 588c2742e8b7c1ce8a138743c9308a42db9b9bf1 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Oct 2014 01:55:42 -0700 Subject: [PATCH 069/617] Separate out input mux in AXI frame joiner --- rtl/axis_frame_join.py | 30 +++++++++++------ rtl/axis_frame_join_4.v | 74 ++++++++++++++++++++++------------------- 2 files changed, 59 insertions(+), 45 deletions(-) diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index 19c9e9fe4..aa69ee4b6 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -156,6 +156,9 @@ reg input_tlast; reg input_tuser; reg output_tuser_reg = 0, output_tuser_next; +{% for p in ports %} +reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +{%- endfor %} // internal datapath reg [7:0] output_axis_tdata_int; @@ -165,14 +168,25 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; {% for p in ports %} -reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; -{%- endfor %} -{% for p in ports %} assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; {%- endfor %} assign busy = busy_reg; +always @* begin + // input port mux + case (port_sel_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + input_tdata = input_{{p}}_axis_tdata; + input_tvalid = input_{{p}}_axis_tvalid; + input_tlast = input_{{p}}_axis_tlast; + input_tuser = input_{{p}}_axis_tuser; + end +{%- endfor %} + endcase +end + always @* begin state_next = 2'bz; @@ -252,16 +266,10 @@ always @* begin STATE_TRANSFER: begin // transfer input data - // grab correct input lines, set ready line correctly + // set ready for current input case (port_sel_reg) {%- for p in ports %} - {{w}}'d{{p}}: begin - input_tdata = input_{{p}}_axis_tdata; - input_tvalid = input_{{p}}_axis_tvalid; - input_tlast = input_{{p}}_axis_tlast; - input_tuser = input_{{p}}_axis_tuser; - input_{{p}}_axis_tready_next = output_axis_tready_int_early; - end + {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early; {%- endfor %} endcase diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index 92270a1cc..c1430465d 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -104,6 +104,11 @@ reg input_tuser; reg output_tuser_reg = 0, output_tuser_next; +reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; + // internal datapath reg [7:0] output_axis_tdata_int; reg output_axis_tvalid_int; @@ -112,11 +117,6 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; - assign input_0_axis_tready = input_0_axis_tready_reg; assign input_1_axis_tready = input_1_axis_tready_reg; assign input_2_axis_tready = input_2_axis_tready_reg; @@ -124,6 +124,36 @@ assign input_3_axis_tready = input_3_axis_tready_reg; assign busy = busy_reg; +always @* begin + // input port mux + case (port_sel_reg) + 2'd0: begin + input_tdata = input_0_axis_tdata; + input_tvalid = input_0_axis_tvalid; + input_tlast = input_0_axis_tlast; + input_tuser = input_0_axis_tuser; + end + 2'd1: begin + input_tdata = input_1_axis_tdata; + input_tvalid = input_1_axis_tvalid; + input_tlast = input_1_axis_tlast; + input_tuser = input_1_axis_tuser; + end + 2'd2: begin + input_tdata = input_2_axis_tdata; + input_tvalid = input_2_axis_tvalid; + input_tlast = input_2_axis_tlast; + input_tuser = input_2_axis_tuser; + end + 2'd3: begin + input_tdata = input_3_axis_tdata; + input_tvalid = input_3_axis_tvalid; + input_tlast = input_3_axis_tlast; + input_tuser = input_3_axis_tuser; + end + endcase +end + always @* begin state_next = 2'bz; @@ -205,36 +235,12 @@ always @* begin STATE_TRANSFER: begin // transfer input data - // grab correct input lines, set ready line correctly + // set ready for current input case (port_sel_reg) - 2'd0: begin - input_tdata = input_0_axis_tdata; - input_tvalid = input_0_axis_tvalid; - input_tlast = input_0_axis_tlast; - input_tuser = input_0_axis_tuser; - input_0_axis_tready_next = output_axis_tready_int_early; - end - 2'd1: begin - input_tdata = input_1_axis_tdata; - input_tvalid = input_1_axis_tvalid; - input_tlast = input_1_axis_tlast; - input_tuser = input_1_axis_tuser; - input_1_axis_tready_next = output_axis_tready_int_early; - end - 2'd2: begin - input_tdata = input_2_axis_tdata; - input_tvalid = input_2_axis_tvalid; - input_tlast = input_2_axis_tlast; - input_tuser = input_2_axis_tuser; - input_2_axis_tready_next = output_axis_tready_int_early; - end - 2'd3: begin - input_tdata = input_3_axis_tdata; - input_tvalid = input_3_axis_tvalid; - input_tlast = input_3_axis_tlast; - input_tuser = input_3_axis_tuser; - input_3_axis_tready_next = output_axis_tready_int_early; - end + 2'd0: input_0_axis_tready_next = output_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_axis_tready_int_early; endcase if (input_tvalid & output_axis_tready_int) begin From 0507fd4ca940417e0e41a4e95866e3240705bbe5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 5 Nov 2014 16:19:00 -0800 Subject: [PATCH 070/617] Update readme --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 45dbb8ac1..34d1f782c 100644 --- a/README +++ b/README @@ -1,2 +1,2 @@ -Verilog ethernet components +Verilog AXI Stream components From 849f3c174a9a2f213491bfc0bb56c2c42cbdc36c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 5 Nov 2014 16:22:09 -0800 Subject: [PATCH 071/617] Add .travis.yml --- .travis.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..b6a9c62c8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: python +python: + - "2.7" +virtualenv: + system_site_packages: true +before_install: + - export d=`pwd` + - sudo apt-get update -qq + - sudo apt-get install -y iverilog + - hg clone https://bitbucket.org/jandecaluwe/myhdl + - 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 +script: + - cd tb && py.test + From e8c43653e364ffedf716be920197ce8b8e8e5d28 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 5 Nov 2014 16:33:33 -0800 Subject: [PATCH 072/617] Adjust syntax for old Python 2 --- tb/test_axis_adapter_64_8.py | 30 ++++++------- tb/test_axis_adapter_8_64.py | 30 ++++++------- tb/test_axis_fifo.py | 78 ++++++++++++++++----------------- tb/test_axis_fifo_64.py | 76 ++++++++++++++++---------------- tb/test_axis_frame_join_4.py | 80 +++++++++++++++++----------------- tb/test_axis_ll_bridge.py | 32 +++++++------- tb/test_axis_rate_limit.py | 82 +++++++++++++++++------------------ tb/test_axis_rate_limit_64.py | 82 +++++++++++++++++------------------ tb/test_axis_register.py | 78 ++++++++++++++++----------------- tb/test_axis_register_64.py | 76 ++++++++++++++++---------------- tb/test_axis_stat_counter.py | 80 +++++++++++++++++----------------- tb/test_ll_axis_bridge.py | 32 +++++++------- 12 files changed, 378 insertions(+), 378 deletions(-) diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index a5333dad2..a76c084ff 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -192,9 +192,9 @@ def bench(): print("test 1: test packet, length %d" % payload_len) current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: @@ -222,13 +222,13 @@ def bench(): print("test 2: back-to-back packets, length %d" % payload_len) current_test.next = 2 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: @@ -263,13 +263,13 @@ def bench(): print("test 3: tuser assert, length %d" % payload_len) current_test.next = 3 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(payload_len))) test_frame1.user = 1 diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index 7819e8106..1d14bf2c7 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -192,9 +192,9 @@ def bench(): print("test 1: test packet, length %d" % payload_len) current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: @@ -222,13 +222,13 @@ def bench(): print("test 2: back-to-back packets, length %d" % payload_len) current_test.next = 2 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: @@ -263,13 +263,13 @@ def bench(): print("test 3: tuser assert, length %d" % payload_len) current_test.next = 3 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(payload_len))) test_frame1.user = 1 diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index fe65d118a..9e7313cd1 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -161,10 +161,10 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -184,9 +184,9 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -205,10 +205,10 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -242,14 +242,14 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -278,14 +278,14 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -319,14 +319,14 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -360,10 +360,10 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = 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 diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index b39ad8282..7f879b40f 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -171,10 +171,10 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -194,9 +194,9 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -215,9 +215,9 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -252,14 +252,14 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -288,14 +288,14 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -329,14 +329,14 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -370,10 +370,10 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = 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 diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index bdd5ba98e..4cdc3c95c 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -282,10 +282,10 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_0 = axis_ep.AXIStreamFrame('\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1 = axis_ep.AXIStreamFrame('\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame('\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame('\x03\xAA\xBB\xCC\xDD\x03') source_0_queue.put(test_frame_0) source_1_queue.put(test_frame_1) source_2_queue.put(test_frame_2) @@ -308,10 +308,10 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame_0 = axis_ep.AXIStreamFrame(b'\x00' + bytearray(range(256)) + b'\x00') - test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_0 = axis_ep.AXIStreamFrame('\x00' + bytearray(range(256)) + '\x00') + test_frame_1 = axis_ep.AXIStreamFrame('\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame('\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame('\x03\xAA\xBB\xCC\xDD\x03') source_0_queue.put(test_frame_0) source_1_queue.put(test_frame_1) source_2_queue.put(test_frame_2) @@ -334,10 +334,10 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_0 = axis_ep.AXIStreamFrame('\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1 = axis_ep.AXIStreamFrame('\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame('\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame('\x03\xAA\xBB\xCC\xDD\x03') source_0_queue.put(test_frame_0) source_1_queue.put(test_frame_1) source_2_queue.put(test_frame_2) @@ -374,14 +374,14 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_0a = axis_ep.AXIStreamFrame('\x00\xAA\xBB\xCC\xDD\x00') + test_frame_0b = axis_ep.AXIStreamFrame('\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1a = axis_ep.AXIStreamFrame('\x01\xAA\xBB\xCC\xDD\x01') + test_frame_1b = axis_ep.AXIStreamFrame('\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2a = axis_ep.AXIStreamFrame('\x02\xAA\xBB\xCC\xDD\x02') + test_frame_2b = axis_ep.AXIStreamFrame('\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3a = axis_ep.AXIStreamFrame('\x03\xAA\xBB\xCC\xDD\x03') + test_frame_3b = axis_ep.AXIStreamFrame('\x03\xAA\xBB\xCC\xDD\x03') source_0_queue.put(test_frame_0a) source_0_queue.put(test_frame_0b) source_1_queue.put(test_frame_1a) @@ -416,14 +416,14 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_0a = axis_ep.AXIStreamFrame('\x00\xAA\xBB\xCC\xDD\x00') + test_frame_0b = axis_ep.AXIStreamFrame('\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1a = axis_ep.AXIStreamFrame('\x01\xAA\xBB\xCC\xDD\x01') + test_frame_1b = axis_ep.AXIStreamFrame('\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2a = axis_ep.AXIStreamFrame('\x02\xAA\xBB\xCC\xDD\x02') + test_frame_2b = axis_ep.AXIStreamFrame('\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3a = axis_ep.AXIStreamFrame('\x03\xAA\xBB\xCC\xDD\x03') + test_frame_3b = axis_ep.AXIStreamFrame('\x03\xAA\xBB\xCC\xDD\x03') source_0_queue.put(test_frame_0a) source_0_queue.put(test_frame_0b) source_1_queue.put(test_frame_1a) @@ -469,14 +469,14 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_0a = axis_ep.AXIStreamFrame('\x00\xAA\xBB\xCC\xDD\x00') + test_frame_0b = axis_ep.AXIStreamFrame('\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1a = axis_ep.AXIStreamFrame('\x01\xAA\xBB\xCC\xDD\x01') + test_frame_1b = axis_ep.AXIStreamFrame('\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2a = axis_ep.AXIStreamFrame('\x02\xAA\xBB\xCC\xDD\x02') + test_frame_2b = axis_ep.AXIStreamFrame('\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3a = axis_ep.AXIStreamFrame('\x03\xAA\xBB\xCC\xDD\x03') + test_frame_3b = axis_ep.AXIStreamFrame('\x03\xAA\xBB\xCC\xDD\x03') source_0_queue.put(test_frame_0a) source_0_queue.put(test_frame_0b) source_1_queue.put(test_frame_1a) @@ -516,10 +516,10 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') + test_frame_0 = axis_ep.AXIStreamFrame('\x00\xAA\xBB\xCC\xDD\x00') + test_frame_1 = axis_ep.AXIStreamFrame('\x01\xAA\xBB\xCC\xDD\x01') + test_frame_2 = axis_ep.AXIStreamFrame('\x02\xAA\xBB\xCC\xDD\x02') + test_frame_3 = axis_ep.AXIStreamFrame('\x03\xAA\xBB\xCC\xDD\x03') test_frame_0.user = 1 source_0_queue.put(test_frame_0) source_1_queue.put(test_frame_1) diff --git a/tb/test_axis_ll_bridge.py b/tb/test_axis_ll_bridge.py index 21e6d7a43..45d8295b9 100755 --- a/tb/test_axis_ll_bridge.py +++ b/tb/test_axis_ll_bridge.py @@ -157,10 +157,10 @@ def bench(): 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')) + source_queue.put(bytearray('\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')) yield clk.posedge yield ll_eof_out_n.negedge @@ -171,10 +171,10 @@ def bench(): 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') + assert bytearray(rx_frame) == ('\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') yield delay(100) @@ -182,10 +182,10 @@ def bench(): 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')) + source_queue.put(bytearray('\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')) yield clk.posedge yield delay(64) @@ -210,10 +210,10 @@ def bench(): 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') + assert bytearray(rx_frame) == ('\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') yield delay(100) diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index fc51e35e6..b9f0ff420 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -215,10 +215,10 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -240,9 +240,9 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -263,9 +263,9 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -302,14 +302,14 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -338,14 +338,14 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -382,14 +382,14 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -426,10 +426,10 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = 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 @@ -466,9 +466,9 @@ def bench(): test_frame = [] for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame.append(axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(lens[i])))) for f in test_frame: diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index 66548e9ca..acfc3c7a1 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -225,10 +225,10 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -250,9 +250,9 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -273,9 +273,9 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -312,14 +312,14 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -348,14 +348,14 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -392,14 +392,14 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -436,10 +436,10 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = 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 @@ -476,9 +476,9 @@ def bench(): test_frame = [] for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame.append(axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(lens[i])))) for f in test_frame: diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py index 13d2897fc..84759ea1d 100755 --- a/tb/test_axis_register.py +++ b/tb/test_axis_register.py @@ -161,10 +161,10 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -184,9 +184,9 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -205,10 +205,10 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -242,14 +242,14 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -278,14 +278,14 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -319,14 +319,14 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -360,10 +360,10 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = 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 diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py index 4509a6fd0..52dad6a42 100755 --- a/tb/test_axis_register_64.py +++ b/tb/test_axis_register_64.py @@ -171,10 +171,10 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -194,9 +194,9 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -215,9 +215,9 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -252,14 +252,14 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -288,14 +288,14 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -329,14 +329,14 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -370,10 +370,10 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = 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 diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index 04cc90c89..670f2145a 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -293,10 +293,10 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -347,9 +347,9 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -401,9 +401,9 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + 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 @@ -469,14 +469,14 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -528,14 +528,14 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -587,14 +587,14 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + 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 @@ -650,9 +650,9 @@ def bench(): test_frame = [] for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame.append(axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(lens[i])))) for f in test_frame: @@ -710,9 +710,9 @@ def bench(): test_frame = [] for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + + test_frame.append(axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + bytearray(range(lens[i])))) for f in test_frame: diff --git a/tb/test_ll_axis_bridge.py b/tb/test_ll_axis_bridge.py index 7c6ca681d..f24b25915 100755 --- a/tb/test_ll_axis_bridge.py +++ b/tb/test_ll_axis_bridge.py @@ -156,10 +156,10 @@ def bench(): 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')) + source_queue.put(bytearray('\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')) yield clk.posedge yield axis_tlast.negedge @@ -170,10 +170,10 @@ def bench(): 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') + assert bytearray(rx_frame) == ('\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') yield delay(100) @@ -181,10 +181,10 @@ def bench(): 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')) + source_queue.put(bytearray('\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')) yield clk.posedge yield delay(64) @@ -209,10 +209,10 @@ def bench(): 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') + assert bytearray(rx_frame) == ('\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') yield delay(100) From ac2f7e546df3b7f4a936cdb4d558adc517c5ddb4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 5 Nov 2014 16:40:27 -0800 Subject: [PATCH 073/617] Adjust syntax for old Python 2 --- tb/test_axis_stat_counter.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index 670f2145a..c455b7990 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -226,7 +226,7 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 print(rx_frame_values) @@ -273,7 +273,7 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 print(rx_frame_values) @@ -326,7 +326,7 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 print(rx_frame_values) @@ -380,7 +380,7 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 print(rx_frame_values) @@ -448,7 +448,7 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 print(rx_frame_values) @@ -507,7 +507,7 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 print(rx_frame_values) @@ -566,7 +566,7 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 print(rx_frame_values) @@ -625,7 +625,7 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 print(rx_frame_values) @@ -685,7 +685,7 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 print(rx_frame_values) @@ -758,12 +758,12 @@ def bench(): if not sink_queue.empty(): rx_frame2 = sink_queue.get() - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) + rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 cycles1 = (trigger_time - start_time) / 8 print(rx_frame_values) - rx_frame2_values = struct.unpack(">HLLL", rx_frame2.data) + rx_frame2_values = struct.unpack(">HLLL", bytes(rx_frame2.data)) cycles2 = (stop_time - trigger_time) / 8 print(rx_frame2_values) From 96c6fcd144c9e106beeeca883e7d199836658fee Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 5 Nov 2014 16:59:59 -0800 Subject: [PATCH 074/617] Remove AXI stream components --- rtl/axis_adapter.v | 432 ------------------- rtl/axis_fifo.v | 128 ------ rtl/axis_fifo_64.v | 131 ------ rtl/axis_frame_join.py | 417 ------------------ rtl/axis_frame_join_4.v | 377 ---------------- rtl/axis_ll_bridge.v | 79 ---- rtl/axis_rate_limit.v | 188 -------- rtl/axis_rate_limit_64.v | 201 --------- rtl/axis_register.v | 124 ------ rtl/axis_register_64.v | 136 ------ rtl/axis_stat_counter.v | 317 -------------- rtl/ll_axis_bridge.v | 64 --- tb/test_axis_adapter_64_8.py | 318 -------------- tb/test_axis_adapter_64_8.v | 105 ----- tb/test_axis_adapter_8_64.py | 318 -------------- tb/test_axis_adapter_8_64.v | 105 ----- tb/test_axis_fifo.py | 396 ----------------- tb/test_axis_fifo.v | 91 ---- tb/test_axis_fifo_64.py | 406 ----------------- tb/test_axis_fifo_64.v | 97 ----- tb/test_axis_frame_join_4.py | 555 ------------------------ tb/test_axis_frame_join_4.v | 143 ------ tb/test_axis_ll_bridge.py | 232 ---------- tb/test_axis_ll_bridge.v | 85 ---- tb/test_axis_rate_limit.py | 532 ----------------------- tb/test_axis_rate_limit.v | 100 ----- tb/test_axis_rate_limit_64.py | 542 ----------------------- tb/test_axis_rate_limit_64.v | 106 ----- tb/test_axis_register.py | 396 ----------------- tb/test_axis_register.v | 90 ---- tb/test_axis_register_64.py | 406 ----------------- tb/test_axis_register_64.v | 96 ----- tb/test_axis_stat_counter.py | 792 ---------------------------------- tb/test_axis_stat_counter.v | 102 ----- tb/test_ll_axis_bridge.py | 231 ---------- tb/test_ll_axis_bridge.v | 85 ---- 36 files changed, 8923 deletions(-) delete mode 100644 rtl/axis_adapter.v delete mode 100644 rtl/axis_fifo.v delete mode 100644 rtl/axis_fifo_64.v delete mode 100755 rtl/axis_frame_join.py delete mode 100644 rtl/axis_frame_join_4.v delete mode 100644 rtl/axis_ll_bridge.v delete mode 100644 rtl/axis_rate_limit.v delete mode 100644 rtl/axis_rate_limit_64.v delete mode 100644 rtl/axis_register.v delete mode 100644 rtl/axis_register_64.v delete mode 100644 rtl/axis_stat_counter.v delete mode 100644 rtl/ll_axis_bridge.v delete mode 100755 tb/test_axis_adapter_64_8.py delete mode 100644 tb/test_axis_adapter_64_8.v delete mode 100755 tb/test_axis_adapter_8_64.py delete mode 100644 tb/test_axis_adapter_8_64.v delete mode 100755 tb/test_axis_fifo.py delete mode 100644 tb/test_axis_fifo.v delete mode 100755 tb/test_axis_fifo_64.py delete mode 100644 tb/test_axis_fifo_64.v delete mode 100755 tb/test_axis_frame_join_4.py delete mode 100644 tb/test_axis_frame_join_4.v delete mode 100755 tb/test_axis_ll_bridge.py delete mode 100644 tb/test_axis_ll_bridge.v delete mode 100755 tb/test_axis_rate_limit.py delete mode 100644 tb/test_axis_rate_limit.v delete mode 100755 tb/test_axis_rate_limit_64.py delete mode 100644 tb/test_axis_rate_limit_64.v delete mode 100755 tb/test_axis_register.py delete mode 100644 tb/test_axis_register.v delete mode 100755 tb/test_axis_register_64.py delete mode 100644 tb/test_axis_register_64.v delete mode 100755 tb/test_axis_stat_counter.py delete mode 100644 tb/test_axis_stat_counter.v delete mode 100755 tb/test_ll_axis_bridge.py delete mode 100644 tb/test_ll_axis_bridge.v diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v deleted file mode 100644 index dc8da2f42..000000000 --- a/rtl/axis_adapter.v +++ /dev/null @@ -1,432 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream bus width adapter - */ -module axis_adapter # -( - parameter INPUT_DATA_WIDTH = 8, - parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8), - parameter OUTPUT_DATA_WIDTH = 8, - parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [INPUT_DATA_WIDTH-1:0] input_axis_tdata, - input wire [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * AXI output - */ - output wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata, - output wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser -); - -// bus word widths (must be identical) -localparam INPUT_DATA_WORD_WIDTH = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH; -localparam OUTPUT_DATA_WORD_WIDTH = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH; -// output bus is wider -localparam EXPAND_BUS = OUTPUT_KEEP_WIDTH > INPUT_KEEP_WIDTH; -// total data and keep widths -localparam DATA_WIDTH = EXPAND_BUS ? OUTPUT_DATA_WIDTH : INPUT_DATA_WIDTH; -localparam KEEP_WIDTH = EXPAND_BUS ? OUTPUT_KEEP_WIDTH : INPUT_KEEP_WIDTH; -// required number of cycles to match widths -localparam CYCLE_COUNT = EXPAND_BUS ? (OUTPUT_KEEP_WIDTH / INPUT_KEEP_WIDTH) : (INPUT_KEEP_WIDTH / OUTPUT_KEEP_WIDTH); -// data width and keep width per cycle -localparam CYCLE_DATA_WIDTH = DATA_WIDTH / CYCLE_COUNT; -localparam CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT; - -// bus width assertions -initial begin - if (INPUT_DATA_WORD_WIDTH * INPUT_KEEP_WIDTH != INPUT_DATA_WIDTH) begin - $error("Error: input data width not evenly divisble"); - $finish; - end - - if (OUTPUT_DATA_WORD_WIDTH * OUTPUT_KEEP_WIDTH != OUTPUT_DATA_WIDTH) begin - $error("Error: output data width not evenly divisble"); - $finish; - end - - if (INPUT_DATA_WORD_WIDTH != OUTPUT_DATA_WORD_WIDTH) begin - $error("Error: word width mismatch"); - $finish; - end -end - -// state register -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_TRANSFER_IN = 3'd1, - STATE_TRANSFER_OUT = 3'd2; - -reg [2:0] state_reg = STATE_IDLE, state_next; - -reg [7:0] cycle_count_reg = 0, cycle_count_next; - -reg [DATA_WIDTH-1:0] temp_tdata_reg = 0, temp_tdata_next; -reg [KEEP_WIDTH-1:0] temp_tkeep_reg = 0, temp_tkeep_next; -reg temp_tlast_reg = 0, temp_tlast_next; -reg temp_tuser_reg = 0, temp_tuser_next; - -// internal datapath -reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_int; -reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -reg input_axis_tready_reg = 0, input_axis_tready_next; -assign input_axis_tready = input_axis_tready_reg; - -always @* begin - state_next = 3'bz; - - cycle_count_next = cycle_count_reg; - - temp_tdata_next = temp_tdata_reg; - temp_tkeep_next = temp_tkeep_reg; - temp_tlast_next = temp_tlast_reg; - temp_tuser_next = temp_tuser_reg; - - output_axis_tdata_int = 0; - output_axis_tkeep_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; - - input_axis_tready_next = 0; - - case (state_reg) - STATE_IDLE: begin - // idle state - no data in registers - if (CYCLE_COUNT == 1) begin - // output and input same width - just act like a register - - // accept data next cycle if output register ready next cycle - input_axis_tready_next = output_axis_tready_int_early; - - // transfer through - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = input_axis_tlast; - output_axis_tuser_int = input_axis_tuser; - - state_next = STATE_IDLE; - end else if (EXPAND_BUS) begin - // output bus is wider - - // accept new data - input_axis_tready_next = 1; - - if (input_axis_tvalid) begin - // word transfer in - store it in data register - - // pass complete input word, zero-extended to temp register - temp_tdata_next = input_axis_tdata; - temp_tkeep_next = input_axis_tkeep; - temp_tlast_next = input_axis_tlast; - temp_tuser_next = input_axis_tuser; - - // first input cycle complete - cycle_count_next = 1; - - if (input_axis_tlast) begin - // got last signal on first cycle, so output it - input_axis_tready_next = 0; - state_next = STATE_TRANSFER_OUT; - end else begin - // otherwise, transfer in the rest of the words - input_axis_tready_next = 1; - state_next = STATE_TRANSFER_IN; - end - end else begin - state_next = STATE_IDLE; - end - end else begin - // output bus is narrower - - // accept new data - input_axis_tready_next = 1; - - if (input_axis_tvalid) begin - // word transfer in - store it in data register - cycle_count_next = 0; - - // pass complete input word, zero-extended to temp register - temp_tdata_next = input_axis_tdata; - temp_tkeep_next = input_axis_tkeep; - temp_tlast_next = input_axis_tlast; - temp_tuser_next = input_axis_tuser; - - // short-circuit and get first word out the door - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = 1; - output_axis_tlast_int = input_axis_tlast & ((CYCLE_COUNT == 1) | (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}})); - output_axis_tuser_int = input_axis_tuser & ((CYCLE_COUNT == 1) | (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}})); - - if (output_axis_tready_int) begin - // if output register is ready for first word, then move on to the next one - cycle_count_next = 1; - end - - // continue outputting words - input_axis_tready_next = 0; - state_next = STATE_TRANSFER_OUT; - end else begin - state_next = STATE_IDLE; - end - end - end - STATE_TRANSFER_IN: begin - // transfer word to temp registers - // only used when output is wider - - // accept new data - input_axis_tready_next = 1; - - if (input_axis_tvalid) begin - // word transfer in - store in data register - - temp_tdata_next[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH] = input_axis_tdata; - temp_tkeep_next[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] = input_axis_tkeep; - temp_tlast_next = input_axis_tlast; - temp_tuser_next = input_axis_tuser; - - cycle_count_next = cycle_count_reg + 1; - - if ((cycle_count_reg == CYCLE_COUNT-1) | input_axis_tlast) begin - // terminated by counter or tlast signal, output complete word - // read input word next cycle if output will be ready - input_axis_tready_next = output_axis_tready_int_early; - state_next = STATE_TRANSFER_OUT; - end else begin - // more words to read - input_axis_tready_next = 1; - state_next = STATE_TRANSFER_IN; - end - end else begin - state_next = STATE_TRANSFER_IN; - end - end - STATE_TRANSFER_OUT: begin - // transfer word to output registers - - if (EXPAND_BUS) begin - // output bus is wider - - // do not accept new data - input_axis_tready_next = 0; - - // single-cycle output of entire stored word (output wider) - output_axis_tdata_int = temp_tdata_reg; - output_axis_tkeep_int = temp_tkeep_reg; - output_axis_tvalid_int = 1; - output_axis_tlast_int = temp_tlast_reg; - output_axis_tuser_int = temp_tuser_reg; - - if (output_axis_tready_int) begin - // word transfer out - - if (input_axis_tready & input_axis_tvalid) begin - // word transfer in - - // pass complete input word, zero-extended to temp register - temp_tdata_next = input_axis_tdata; - temp_tkeep_next = input_axis_tkeep; - temp_tlast_next = input_axis_tlast; - temp_tuser_next = input_axis_tuser; - - // first input cycle complete - cycle_count_next = 1; - - if (input_axis_tlast) begin - // got last signal on first cycle, so output it - input_axis_tready_next = 0; - state_next = STATE_TRANSFER_OUT; - end else begin - // otherwise, transfer in the rest of the words - input_axis_tready_next = 1; - state_next = STATE_TRANSFER_IN; - end - end else begin - input_axis_tready_next = 1; - state_next = STATE_IDLE; - end - end else begin - state_next = STATE_TRANSFER_OUT; - end - end else begin - // output bus is narrower - - // do not accept new data - input_axis_tready_next = 0; - - // output current part of stored word (output narrower) - output_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH]; - output_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH]; - output_axis_tvalid_int = 1; - output_axis_tlast_int = temp_tlast_reg & ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})); - output_axis_tuser_int = temp_tuser_reg & ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})); - - if (output_axis_tready_int) begin - // word transfer out - - cycle_count_next = cycle_count_reg + 1; - - if ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})) begin - // terminated by counter or tlast signal - - input_axis_tready_next = 1; - state_next = STATE_IDLE; - end else begin - // more words to write - state_next = STATE_TRANSFER_OUT; - end - end else begin - state_next = STATE_TRANSFER_OUT; - end - end - end - endcase -end - -always @(posedge clk or posedge rst) begin - if (rst) begin - state_reg <= STATE_IDLE; - cycle_count_reg <= 0; - temp_tdata_reg <= 0; - temp_tkeep_reg <= 0; - temp_tlast_reg <= 0; - temp_tuser_reg <= 0; - input_axis_tready_reg <= 0; - end else begin - state_reg <= state_next; - - input_axis_tready_reg <= input_axis_tready_next; - - temp_tdata_reg <= temp_tdata_next; - temp_tkeep_reg <= temp_tkeep_next; - temp_tlast_reg <= temp_tlast_next; - temp_tuser_reg <= temp_tuser_next; - - cycle_count_reg <= cycle_count_next; - end -end - -// output datapath logic -reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; - -reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); - -always @(posedge clk or posedge rst) begin - if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; - - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end - end -end - -endmodule diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v deleted file mode 100644 index 8004a8311..000000000 --- a/rtl/axis_fifo.v +++ /dev/null @@ -1,128 +0,0 @@ -/* - -Copyright (c) 2013 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream FIFO - */ -module axis_fifo # -( - parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 8 -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser -); - -reg [ADDR_WIDTH-1:0] wr_ptr = {ADDR_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] rd_ptr = {ADDR_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] counter = {ADDR_WIDTH{1'b0}}; - -reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}}; - -//(* RAM_STYLE="BLOCK" *) -reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; - -reg output_read = 1'b0; - -reg output_axis_tvalid_reg = 1'b0; - -wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; - -wire full = (counter == (2**ADDR_WIDTH)-1); -wire empty = (counter == 0); - -wire write = input_axis_tvalid & ~full; -wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; - -assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = data_out_reg; - -assign input_axis_tready = ~full; -assign output_axis_tvalid = output_axis_tvalid_reg; - -// write -always @(posedge clk or posedge rst) begin - if (rst) begin - wr_ptr <= 0; - end else if (write) begin - mem[wr_ptr] <= data_in; - wr_ptr <= wr_ptr + 1; - end -end - -// read -always @(posedge clk or posedge rst) begin - if (rst) begin - rd_ptr <= 0; - end else if (read) begin - data_out_reg <= mem[rd_ptr]; - rd_ptr <= rd_ptr + 1; - end -end - -// counter -always @(posedge clk or posedge rst) begin - if (rst) begin - counter <= 0; - end else if (~read & write) begin - counter <= counter + 1; - end else if (read & ~write) begin - counter <= counter - 1; - end -end - -// source ready output -always @(posedge clk or posedge rst) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - end else if (output_axis_tready | ~output_axis_tvalid_reg) begin - output_axis_tvalid_reg <= ~empty; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_reg; - end -end - -endmodule diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v deleted file mode 100644 index 8d02f5c0d..000000000 --- a/rtl/axis_fifo_64.v +++ /dev/null @@ -1,131 +0,0 @@ -/* - -Copyright (c) 2013 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream FIFO (64 bit datapath) - */ -module axis_fifo_64 # -( - parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] input_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser -); - -reg [ADDR_WIDTH-1:0] wr_ptr = {ADDR_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] rd_ptr = {ADDR_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] counter = {ADDR_WIDTH{1'b0}}; - -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; - -//(* RAM_STYLE="BLOCK" *) -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; - -reg output_read = 1'b0; - -reg output_axis_tvalid_reg = 1'b0; - -wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; - -wire full = (counter == (2**ADDR_WIDTH)-1); -wire empty = (counter == 0); - -wire write = input_axis_tvalid & ~full; -wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; - -assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = data_out_reg; - -assign input_axis_tready = ~full; -assign output_axis_tvalid = output_axis_tvalid_reg; - -// write -always @(posedge clk or posedge rst) begin - if (rst) begin - wr_ptr <= 0; - end else if (write) begin - mem[wr_ptr] <= data_in; - wr_ptr <= wr_ptr + 1; - end -end - -// read -always @(posedge clk or posedge rst) begin - if (rst) begin - rd_ptr <= 0; - end else if (read) begin - data_out_reg <= mem[rd_ptr]; - rd_ptr <= rd_ptr + 1; - end -end - -// counter -always @(posedge clk or posedge rst) begin - if (rst) begin - counter <= 0; - end else if (~read & write) begin - counter <= counter + 1; - end else if (read & ~write) begin - counter <= counter - 1; - end -end - -// source ready output -always @(posedge clk or posedge rst) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - end else if (output_axis_tready | ~output_axis_tvalid_reg) begin - output_axis_tvalid_reg <= ~empty; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_reg; - end -end - -endmodule diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py deleted file mode 100755 index aa69ee4b6..000000000 --- a/rtl/axis_frame_join.py +++ /dev/null @@ -1,417 +0,0 @@ -#!/usr/bin/env python -"""axis_frame_join - -Generates an AXI Stream frame join module with a specific number of input ports - -Usage: axis_frame_join [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name -""" - -import io -import sys -import getopt -from math import * -from jinja2 import Template - -class Usage(Exception): - def __init__(self, msg): - self.msg = msg - -def main(argv=None): - if argv is None: - argv = sys.argv - try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--outputs'): - out_name = a - - if name is None: - name = "axis_frame_join_{0}".format(ports) - - if out_name is None: - out_name = name + ".v" - - print("Opening file '%s'..." % out_name) - - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) - - print("Generating {0} port AXI Stream frame joiner {1}...".format(ports, name)) - - select_width = ceil(log2(ports)) - - t = Template(u"""/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream {{n}} port frame joiner - */ -module {{name}} # -( - parameter ENABLE_TAG = 1 -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ -{%- for p in ports %} - input wire [7:0] input_{{p}}_axis_tdata, - input wire input_{{p}}_axis_tvalid, - output wire input_{{p}}_axis_tready, - input wire input_{{p}}_axis_tlast, - input wire input_{{p}}_axis_tuser, -{% endfor %} - /* - * AXI output - */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Configuration - */ - input wire [15:0] tag, - - /* - * Status signals - */ - output wire busy -); - -// state register -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_WRITE_TAG = 2'd1, - STATE_TRANSFER = 2'd2; - -reg [1:0] state_reg = STATE_IDLE, state_next; - -reg [2:0] frame_ptr_reg = 0, frame_ptr_next; -reg [{{w-1}}:0] port_sel_reg = 0, port_sel_next; - -reg busy_reg = 0, busy_next; - -reg [7:0] input_tdata; -reg input_tvalid; -reg input_tlast; -reg input_tuser; - -reg output_tuser_reg = 0, output_tuser_next; -{% for p in ports %} -reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; -{%- endfor %} - -// internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; -{% for p in ports %} -assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; -{%- endfor %} - -assign busy = busy_reg; - -always @* begin - // input port mux - case (port_sel_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - input_tdata = input_{{p}}_axis_tdata; - input_tvalid = input_{{p}}_axis_tvalid; - input_tlast = input_{{p}}_axis_tlast; - input_tuser = input_{{p}}_axis_tuser; - end -{%- endfor %} - endcase -end - -always @* begin - state_next = 2'bz; - - frame_ptr_next = frame_ptr_reg; - port_sel_next = port_sel_reg; -{% for p in ports %} - input_{{p}}_axis_tready_next = 0; -{%- endfor %} - - output_axis_tdata_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; - - output_tuser_next = output_tuser_reg; - - case (state_reg) - STATE_IDLE: begin - // idle state - wait for data - frame_ptr_next = 0; - port_sel_next = 0; - output_tuser_next = 0; - - if (ENABLE_TAG) begin - // next cycle if started will send tag, so do not enable input - input_0_axis_tready_next = 0; - end else begin - // next cycle if started will send data, so enable input - input_0_axis_tready_next = output_axis_tready_int_early; - end - - if (input_0_axis_tvalid) begin - // input 0 valid; start transferring data - if (ENABLE_TAG) begin - // tag enabled, so transmit it - if (output_axis_tready_int) begin - // output is ready, so short-circuit first tag byte - frame_ptr_next = 1; - output_axis_tdata_int = tag[15:8]; - output_axis_tvalid_int = 1; - end - - state_next = STATE_WRITE_TAG; - end else begin - // tag disabled, so transmit data - if (output_axis_tready_int) begin - // output is ready, so short-circuit first data byte - output_axis_tdata_int = input_0_axis_tdata; - output_axis_tvalid_int = 1; - end - state_next = STATE_TRANSFER; - end - end else begin - state_next = STATE_IDLE; - end - end - STATE_WRITE_TAG: begin - // write tag data - if (output_axis_tready_int) begin - // output ready, so send tag byte - state_next = STATE_WRITE_TAG; - frame_ptr_next = frame_ptr_reg + 1; - output_axis_tvalid_int = 1; - case (frame_ptr_reg) - 2'd0: output_axis_tdata_int = tag[15:8]; - 2'd1: begin - // last tag byte - get ready to send data, enable input if ready - output_axis_tdata_int = tag[7:0]; - input_0_axis_tready_next = output_axis_tready_int_early; - state_next = STATE_TRANSFER; - end - endcase - end else begin - state_next = STATE_WRITE_TAG; - end - end - STATE_TRANSFER: begin - // transfer input data - - // set ready for current input - case (port_sel_reg) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early; -{%- endfor %} - endcase - - if (input_tvalid & output_axis_tready_int) begin - // output ready, transfer byte - state_next = STATE_TRANSFER; - output_axis_tdata_int = input_tdata; - output_axis_tvalid_int = input_tvalid; - - if (input_tlast) begin - // last flag received, switch to next port - port_sel_next = port_sel_reg + 1; - // save tuser - assert tuser out if ANY tuser asserts received - output_tuser_next = output_tuser_next | input_tuser; - // disable input -{%- for p in ports %} - input_{{p}}_axis_tready_next = 0; -{%- endfor %} - - if (port_sel_reg == {{n-1}}) begin - // last port - send tlast and tuser and revert to idle - output_axis_tlast_int = 1; - output_axis_tuser_int = output_tuser_next; - state_next = STATE_IDLE; - end else begin - // otherwise, disable enable next port - case (port_sel_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early; -{%- endfor %} - endcase - end - end - end else begin - state_next = STATE_TRANSFER; - end - end - endcase -end - -always @(posedge clk or posedge rst) begin - if (rst) begin - state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - port_sel_reg <= 0; -{%- for p in ports %} - input_{{p}}_axis_tready_reg <= 0; -{%- endfor %} - output_tuser_reg <= 0; - busy_reg <= 0; - end else begin - state_reg <= state_next; - - frame_ptr_reg <= frame_ptr_next; - - port_sel_reg <= port_sel_next; -{% for p in ports %} - input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; -{%- endfor %} - - output_tuser_reg <= output_tuser_next; - - busy_reg <= state_next != STATE_IDLE; - end -end - -// output datapath logic -reg [7:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; - -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); - -always @(posedge clk or posedge rst) begin - if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; - - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end - end -end - -endmodule - -""") - - out_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - sys.exit(main()) - diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v deleted file mode 100644 index c1430465d..000000000 --- a/rtl/axis_frame_join_4.v +++ /dev/null @@ -1,377 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream 4 port frame joiner - */ -module axis_frame_join_4 # -( - parameter ENABLE_TAG = 1 -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ - input wire [7:0] input_0_axis_tdata, - input wire input_0_axis_tvalid, - output wire input_0_axis_tready, - input wire input_0_axis_tlast, - input wire input_0_axis_tuser, - - input wire [7:0] input_1_axis_tdata, - input wire input_1_axis_tvalid, - output wire input_1_axis_tready, - input wire input_1_axis_tlast, - input wire input_1_axis_tuser, - - input wire [7:0] input_2_axis_tdata, - input wire input_2_axis_tvalid, - output wire input_2_axis_tready, - input wire input_2_axis_tlast, - input wire input_2_axis_tuser, - - input wire [7:0] input_3_axis_tdata, - input wire input_3_axis_tvalid, - output wire input_3_axis_tready, - input wire input_3_axis_tlast, - input wire input_3_axis_tuser, - - /* - * AXI output - */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Configuration - */ - input wire [15:0] tag, - - /* - * Status signals - */ - output wire busy -); - -// state register -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_WRITE_TAG = 2'd1, - STATE_TRANSFER = 2'd2; - -reg [1:0] state_reg = STATE_IDLE, state_next; - -reg [2:0] frame_ptr_reg = 0, frame_ptr_next; -reg [1:0] port_sel_reg = 0, port_sel_next; - -reg busy_reg = 0, busy_next; - -reg [7:0] input_tdata; -reg input_tvalid; -reg input_tlast; -reg input_tuser; - -reg output_tuser_reg = 0, output_tuser_next; - -reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; - -// internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -assign input_0_axis_tready = input_0_axis_tready_reg; -assign input_1_axis_tready = input_1_axis_tready_reg; -assign input_2_axis_tready = input_2_axis_tready_reg; -assign input_3_axis_tready = input_3_axis_tready_reg; - -assign busy = busy_reg; - -always @* begin - // input port mux - case (port_sel_reg) - 2'd0: begin - input_tdata = input_0_axis_tdata; - input_tvalid = input_0_axis_tvalid; - input_tlast = input_0_axis_tlast; - input_tuser = input_0_axis_tuser; - end - 2'd1: begin - input_tdata = input_1_axis_tdata; - input_tvalid = input_1_axis_tvalid; - input_tlast = input_1_axis_tlast; - input_tuser = input_1_axis_tuser; - end - 2'd2: begin - input_tdata = input_2_axis_tdata; - input_tvalid = input_2_axis_tvalid; - input_tlast = input_2_axis_tlast; - input_tuser = input_2_axis_tuser; - end - 2'd3: begin - input_tdata = input_3_axis_tdata; - input_tvalid = input_3_axis_tvalid; - input_tlast = input_3_axis_tlast; - input_tuser = input_3_axis_tuser; - end - endcase -end - -always @* begin - state_next = 2'bz; - - frame_ptr_next = frame_ptr_reg; - port_sel_next = port_sel_reg; - - input_0_axis_tready_next = 0; - input_1_axis_tready_next = 0; - input_2_axis_tready_next = 0; - input_3_axis_tready_next = 0; - - output_axis_tdata_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; - - output_tuser_next = output_tuser_reg; - - case (state_reg) - STATE_IDLE: begin - // idle state - wait for data - frame_ptr_next = 0; - port_sel_next = 0; - output_tuser_next = 0; - - if (ENABLE_TAG) begin - // next cycle if started will send tag, so do not enable input - input_0_axis_tready_next = 0; - end else begin - // next cycle if started will send data, so enable input - input_0_axis_tready_next = output_axis_tready_int_early; - end - - if (input_0_axis_tvalid) begin - // input 0 valid; start transferring data - if (ENABLE_TAG) begin - // tag enabled, so transmit it - if (output_axis_tready_int) begin - // output is ready, so short-circuit first tag byte - frame_ptr_next = 1; - output_axis_tdata_int = tag[15:8]; - output_axis_tvalid_int = 1; - end - - state_next = STATE_WRITE_TAG; - end else begin - // tag disabled, so transmit data - if (output_axis_tready_int) begin - // output is ready, so short-circuit first data byte - output_axis_tdata_int = input_0_axis_tdata; - output_axis_tvalid_int = 1; - end - state_next = STATE_TRANSFER; - end - end else begin - state_next = STATE_IDLE; - end - end - STATE_WRITE_TAG: begin - // write tag data - if (output_axis_tready_int) begin - // output ready, so send tag byte - state_next = STATE_WRITE_TAG; - frame_ptr_next = frame_ptr_reg + 1; - output_axis_tvalid_int = 1; - case (frame_ptr_reg) - 2'd0: output_axis_tdata_int = tag[15:8]; - 2'd1: begin - // last tag byte - get ready to send data, enable input if ready - output_axis_tdata_int = tag[7:0]; - input_0_axis_tready_next = output_axis_tready_int_early; - state_next = STATE_TRANSFER; - end - endcase - end else begin - state_next = STATE_WRITE_TAG; - end - end - STATE_TRANSFER: begin - // transfer input data - - // set ready for current input - case (port_sel_reg) - 2'd0: input_0_axis_tready_next = output_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_axis_tready_int_early; - endcase - - if (input_tvalid & output_axis_tready_int) begin - // output ready, transfer byte - state_next = STATE_TRANSFER; - output_axis_tdata_int = input_tdata; - output_axis_tvalid_int = input_tvalid; - - if (input_tlast) begin - // last flag received, switch to next port - port_sel_next = port_sel_reg + 1; - // save tuser - assert tuser out if ANY tuser asserts received - output_tuser_next = output_tuser_next | input_tuser; - // disable input - input_0_axis_tready_next = 0; - input_1_axis_tready_next = 0; - input_2_axis_tready_next = 0; - input_3_axis_tready_next = 0; - - if (port_sel_reg == 3) begin - // last port - send tlast and tuser and revert to idle - output_axis_tlast_int = 1; - output_axis_tuser_int = output_tuser_next; - state_next = STATE_IDLE; - end else begin - // otherwise, disable enable next port - case (port_sel_next) - 2'd0: input_0_axis_tready_next = output_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_axis_tready_int_early; - endcase - end - end - end else begin - state_next = STATE_TRANSFER; - end - end - endcase -end - -always @(posedge clk or posedge rst) begin - if (rst) begin - state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - port_sel_reg <= 0; - input_0_axis_tready_reg <= 0; - input_1_axis_tready_reg <= 0; - input_2_axis_tready_reg <= 0; - input_3_axis_tready_reg <= 0; - output_tuser_reg <= 0; - busy_reg <= 0; - end else begin - state_reg <= state_next; - - frame_ptr_reg <= frame_ptr_next; - - port_sel_reg <= port_sel_next; - - input_0_axis_tready_reg <= input_0_axis_tready_next; - input_1_axis_tready_reg <= input_1_axis_tready_next; - input_2_axis_tready_reg <= input_2_axis_tready_next; - input_3_axis_tready_reg <= input_3_axis_tready_next; - - output_tuser_reg <= output_tuser_next; - - busy_reg <= state_next != STATE_IDLE; - end -end - -// output datapath logic -reg [7:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; - -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); - -always @(posedge clk or posedge rst) begin - if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; - - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end - end -end - -endmodule diff --git a/rtl/axis_ll_bridge.v b/rtl/axis_ll_bridge.v deleted file mode 100644 index 06186aef7..000000000 --- a/rtl/axis_ll_bridge.v +++ /dev/null @@ -1,79 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream to LocalLink bridge - */ -module axis_ll_bridge # -( - parameter DATA_WIDTH = 8 -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] axis_tdata, - input wire axis_tvalid, - output wire axis_tready, - input wire axis_tlast, - - /* - * LocalLink output - */ - output wire [DATA_WIDTH-1:0] ll_data_out, - output wire ll_sof_out_n, - output wire ll_eof_out_n, - output wire ll_src_rdy_out_n, - input wire ll_dst_rdy_in_n -); - -reg last_tlast = 1'b1; - -always @(posedge clk or posedge rst) begin - if (rst) begin - last_tlast = 1'b1; - end else begin - if (axis_tvalid & axis_tready) last_tlast = axis_tlast; - end -end - -// high for packet length 1 -> cannot set SOF and EOF in same cycle -// invalid packets are discarded -wire invalid = axis_tvalid & axis_tlast & last_tlast; - -assign axis_tready = ~ll_dst_rdy_in_n; - -assign ll_data_out = axis_tdata; -assign ll_sof_out_n = ~(last_tlast & axis_tvalid & ~invalid); -assign ll_eof_out_n = ~(axis_tlast & ~invalid); -assign ll_src_rdy_out_n = ~(axis_tvalid & ~invalid); - -endmodule diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v deleted file mode 100644 index f1ebb70e5..000000000 --- a/rtl/axis_rate_limit.v +++ /dev/null @@ -1,188 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream rate limiter - */ -module axis_rate_limit # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Configuration - */ - input wire [7:0] rate_num, - input wire [7:0] rate_denom, - input wire rate_by_frame -); - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -reg [23:0] acc_reg = 0, acc_next; -reg pause; -reg frame_reg = 0, frame_next; - -reg input_axis_tready_reg = 0, input_axis_tready_next; -assign input_axis_tready = input_axis_tready_reg; - -always @* begin - acc_next = acc_reg; - pause = 0; - frame_next = frame_reg & ~input_axis_tlast; - - if (acc_reg >= rate_num) begin - acc_next = acc_reg - rate_num; - end - - if (input_axis_tready & input_axis_tvalid) begin - // read input - frame_next = ~input_axis_tlast; - acc_next = acc_reg + (rate_denom - rate_num); - end - - if (acc_next >= rate_num) begin - if (rate_by_frame) begin - pause = ~frame_next; - end else begin - pause = 1; - end - end - - input_axis_tready_next = output_axis_tready_int_early & ~pause; - - output_axis_tdata_int = input_axis_tdata; - output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tuser_int = input_axis_tuser; -end - -always @(posedge clk or posedge rst) begin - if (rst) begin - acc_reg <= 0; - frame_reg <= 0; - input_axis_tready_reg <= 0; - end else begin - acc_reg <= acc_next; - frame_reg <= frame_next; - input_axis_tready_reg <= input_axis_tready_next; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); - -always @(posedge clk or posedge rst) begin - if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; - - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end - end -end - -endmodule diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v deleted file mode 100644 index e5b31ca9c..000000000 --- a/rtl/axis_rate_limit_64.v +++ /dev/null @@ -1,201 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream rate limiter (64 bit datapath) - */ -module axis_rate_limit_64 # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] input_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Configuration - */ - input wire [7:0] rate_num, - input wire [7:0] rate_denom, - input wire rate_by_frame -); - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -reg [23:0] acc_reg = 0, acc_next; -reg pause; -reg frame_reg = 0, frame_next; - -reg input_axis_tready_reg = 0, input_axis_tready_next; -assign input_axis_tready = input_axis_tready_reg; - -always @* begin - acc_next = acc_reg; - pause = 0; - frame_next = frame_reg & ~input_axis_tlast; - - if (acc_reg >= rate_num) begin - acc_next = acc_reg - rate_num; - end - - if (input_axis_tready & input_axis_tvalid) begin - // read input - frame_next = ~input_axis_tlast; - acc_next = acc_reg + (rate_denom - rate_num); - end - - if (acc_next >= rate_num) begin - if (rate_by_frame) begin - pause = ~frame_next; - end else begin - pause = 1; - end - end - - input_axis_tready_next = output_axis_tready_int_early & ~pause; - - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tuser_int = input_axis_tuser; -end - -always @(posedge clk or posedge rst) begin - if (rst) begin - acc_reg <= 0; - frame_reg <= 0; - input_axis_tready_reg <= 0; - end else begin - acc_reg <= acc_next; - frame_reg <= frame_next; - input_axis_tready_reg <= input_axis_tready_next; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); - -always @(posedge clk or posedge rst) begin - if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; - - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end - end -end - -endmodule diff --git a/rtl/axis_register.v b/rtl/axis_register.v deleted file mode 100644 index 1032a2ae6..000000000 --- a/rtl/axis_register.v +++ /dev/null @@ -1,124 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream register - */ -module axis_register # -( - parameter DATA_WIDTH = 8 -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser -); - -// datapath registers -reg input_axis_tready_reg = 0; - -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; - -assign input_axis_tready = input_axis_tready_reg; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -always @(posedge clk or posedge rst) begin - if (rst) begin - input_axis_tready_reg <= 0; - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end else begin - // transfer sink ready state to source - // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle - input_axis_tready_reg <= output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~input_axis_tvalid); - - if (input_axis_tready_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= input_axis_tdata; - output_axis_tvalid_reg <= input_axis_tvalid; - output_axis_tlast_reg <= input_axis_tlast; - output_axis_tuser_reg <= input_axis_tuser; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= input_axis_tdata; - temp_axis_tvalid_reg <= input_axis_tvalid; - temp_axis_tlast_reg <= input_axis_tlast; - temp_axis_tuser_reg <= input_axis_tuser; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end - end -end - -endmodule diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v deleted file mode 100644 index c8ab746a6..000000000 --- a/rtl/axis_register_64.v +++ /dev/null @@ -1,136 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream register (64 bit datapath) - */ -module axis_register_64 # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] input_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser -); - -// datapath registers -reg input_axis_tready_reg = 0; - -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; - -assign input_axis_tready = input_axis_tready_reg; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -always @(posedge clk or posedge rst) begin - if (rst) begin - input_axis_tready_reg <= 0; - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end else begin - // transfer sink ready state to source - // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle - input_axis_tready_reg <= output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~input_axis_tvalid); - - if (input_axis_tready_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= input_axis_tdata; - output_axis_tkeep_reg <= input_axis_tkeep; - output_axis_tvalid_reg <= input_axis_tvalid; - output_axis_tlast_reg <= input_axis_tlast; - output_axis_tuser_reg <= input_axis_tuser; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= input_axis_tdata; - temp_axis_tkeep_reg <= input_axis_tkeep; - temp_axis_tvalid_reg <= input_axis_tvalid; - temp_axis_tlast_reg <= input_axis_tlast; - temp_axis_tuser_reg <= input_axis_tuser; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end - end -end - -endmodule diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v deleted file mode 100644 index 7dfdb14fa..000000000 --- a/rtl/axis_stat_counter.v +++ /dev/null @@ -1,317 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream statistics counter - */ -module axis_stat_counter # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI monitor - */ - input wire [KEEP_WIDTH-1:0] monitor_axis_tkeep, - input wire monitor_axis_tvalid, - input wire monitor_axis_tready, - input wire monitor_axis_tlast, - - /* - * AXI status data output - */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Configuration - */ - input wire [15:0] tag, - input wire trigger, - - /* - * Status - */ - output wire busy -); - -// state register -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_OUTPUT_DATA = 2'd1; - -reg [1:0] state_reg = STATE_IDLE, state_next; - -reg [31:0] tick_count_reg = 0, tick_count_next; -reg [31:0] byte_count_reg = 0, byte_count_next; -reg [31:0] frame_count_reg = 0, frame_count_next; -reg frame_reg = 0, frame_next; - -reg store_output; -reg [5:0] frame_ptr_reg = 0, frame_ptr_next; - -reg [31:0] tick_count_output_reg = 0; -reg [31:0] byte_count_output_reg = 0; -reg [31:0] frame_count_output_reg = 0; - -reg busy_reg = 0; - -// internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -assign busy = busy_reg; - -function [3:0] keep2count; - input [7:0] k; - case (k) - 8'b00000000: keep2count = 0; - 8'b00000001: keep2count = 1; - 8'b00000011: keep2count = 2; - 8'b00000111: keep2count = 3; - 8'b00001111: keep2count = 4; - 8'b00011111: keep2count = 5; - 8'b00111111: keep2count = 6; - 8'b01111111: keep2count = 7; - 8'b11111111: keep2count = 8; - endcase -endfunction - -function [7:0] count2keep; - input [3:0] k; - case (k) - 4'd0: count2keep = 8'b00000000; - 4'd1: count2keep = 8'b00000001; - 4'd2: count2keep = 8'b00000011; - 4'd3: count2keep = 8'b00000111; - 4'd4: count2keep = 8'b00001111; - 4'd5: count2keep = 8'b00011111; - 4'd6: count2keep = 8'b00111111; - 4'd7: count2keep = 8'b01111111; - 4'd8: count2keep = 8'b11111111; - endcase -endfunction - -always @* begin - state_next = 2'bz; - - tick_count_next = tick_count_reg; - byte_count_next = byte_count_reg; - frame_count_next = frame_count_reg; - frame_next = frame_reg; - - output_axis_tdata_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; - - store_output = 0; - - frame_ptr_next = frame_ptr_reg; - - // data readout - - case (state_reg) - STATE_IDLE: begin - if (trigger) begin - store_output = 1; - tick_count_next = 0; - byte_count_next = 0; - frame_count_next = 0; - frame_ptr_next = 0; - - if (output_axis_tready_int) begin - frame_ptr_next = 1; - output_axis_tdata_int = tag[15:8]; - output_axis_tvalid_int = 1; - end - - state_next = STATE_OUTPUT_DATA; - end else begin - state_next = STATE_IDLE; - end - end - STATE_OUTPUT_DATA: begin - if (output_axis_tready_int) begin - state_next = STATE_OUTPUT_DATA; - frame_ptr_next = frame_ptr_reg + 1; - output_axis_tvalid_int = 1; - case (frame_ptr_reg) - 5'd00: output_axis_tdata_int = tag[15:8]; - 5'd01: output_axis_tdata_int = tag[7:0]; - 5'd02: output_axis_tdata_int = tick_count_output_reg[31:24]; - 5'd03: output_axis_tdata_int = tick_count_output_reg[23:16]; - 5'd04: output_axis_tdata_int = tick_count_output_reg[15: 8]; - 5'd05: output_axis_tdata_int = tick_count_output_reg[ 7: 0]; - 5'd06: output_axis_tdata_int = byte_count_output_reg[31:24]; - 5'd07: output_axis_tdata_int = byte_count_output_reg[23:16]; - 5'd08: output_axis_tdata_int = byte_count_output_reg[15: 8]; - 5'd09: output_axis_tdata_int = byte_count_output_reg[ 7: 0]; - 5'd10: output_axis_tdata_int = frame_count_output_reg[31:24]; - 5'd11: output_axis_tdata_int = frame_count_output_reg[23:16]; - 5'd12: output_axis_tdata_int = frame_count_output_reg[15: 8]; - 5'd13: begin - output_axis_tdata_int = frame_count_output_reg[ 7: 0]; - output_axis_tlast_int = 1; - state_next = STATE_IDLE; - end - endcase - end else begin - state_next = STATE_OUTPUT_DATA; - end - end - endcase - - // stats collection - - // increment tick count by number of words that can be transferred per cycle - tick_count_next = tick_count_next + KEEP_WIDTH; - - if (monitor_axis_tready & monitor_axis_tvalid) begin - // valid transfer cycle - - // increment byte count by number of words transferred - byte_count_next = byte_count_next + keep2count(monitor_axis_tkeep); - - // count frames - if (monitor_axis_tlast) begin - // end of frame - frame_next = 0; - end else if (~frame_reg) begin - // first word after end of frame - frame_count_next = frame_count_next + 1; - frame_next = 1; - end - end -end - -always @(posedge clk or posedge rst) begin - if (rst) begin - state_reg <= STATE_IDLE; - tick_count_reg <= 0; - byte_count_reg <= 0; - frame_count_reg <= 0; - frame_reg <= 0; - frame_ptr_reg <= 0; - busy_reg <= 0; - tick_count_output_reg <= 0; - byte_count_output_reg <= 0; - frame_count_output_reg <= 0; - end else begin - state_reg <= state_next; - tick_count_reg <= tick_count_next; - byte_count_reg <= byte_count_next; - frame_count_reg <= frame_count_next; - frame_reg <= frame_next; - frame_ptr_reg <= frame_ptr_next; - - busy_reg <= state_next != STATE_IDLE; - - if (store_output) begin - tick_count_output_reg <= tick_count_reg; - byte_count_output_reg <= byte_count_reg; - frame_count_output_reg <= frame_count_reg; - end - end -end - -// output datapath logic -reg [7:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; - -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); - -always @(posedge clk or posedge rst) begin - if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; - - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end - end -end - -endmodule diff --git a/rtl/ll_axis_bridge.v b/rtl/ll_axis_bridge.v deleted file mode 100644 index 99733536c..000000000 --- a/rtl/ll_axis_bridge.v +++ /dev/null @@ -1,64 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * LocalLink to AXI4-Stream bridge - */ -module ll_axis_bridge # -( - parameter DATA_WIDTH = 8 -) -( - input wire clk, - input wire rst, - - /* - * LocalLink input - */ - input wire [DATA_WIDTH-1:0] ll_data_in, - input wire ll_sof_in_n, - input wire ll_eof_in_n, - input wire ll_src_rdy_in_n, - output wire ll_dst_rdy_out_n, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] axis_tdata, - output wire axis_tvalid, - input wire axis_tready, - output wire axis_tlast -); - -assign axis_tdata = ll_data_in; -assign axis_tvalid = ~ll_src_rdy_in_n; -assign axis_tlast = ~ll_eof_in_n; - -assign ll_dst_rdy_out_n = ~axis_tready; - -endmodule diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py deleted file mode 100755 index a5333dad2..000000000 --- a/tb/test_axis_adapter_64_8.py +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue - -import axis_ep - -module = 'axis_adapter' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s_64_8.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_adapter_64_8(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - input_axis_tdata = Signal(intbv(0)[64:]) - input_axis_tkeep = Signal(intbv(0)[8:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) - - # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tkeep = Signal(intbv(0)[1:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_adapter_64_8(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - - def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: - source_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - - def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - for payload_len in range(1,18): - yield clk.posedge - print("test 1: test packet, length %d" % payload_len) - current_test.next = 1 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield clk.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - assert sink_queue.empty() - - yield delay(100) - - yield clk.posedge - print("test 2: back-to-back packets, length %d" % payload_len) - current_test.next = 2 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield clk.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - assert sink_queue.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: tuser assert, length %d" % payload_len) - current_test.next = 3 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - - test_frame1.user = 1 - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield clk.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - assert rx_frame.user[-1] - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - assert sink_queue.empty() - - yield delay(100) - - raise StopSimulation - - return dut, source, sink, clkgen, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_adapter_64_8.v b/tb/test_axis_adapter_64_8.v deleted file mode 100644 index be74bbbe5..000000000 --- a/tb/test_axis_adapter_64_8.v +++ /dev/null @@ -1,105 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_adapter_64_8; - -// parameters -localparam INPUT_DATA_WIDTH = 64; -localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); -localparam OUTPUT_DATA_WIDTH = 8; -localparam OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg input_axis_tuser = 0; -reg output_axis_tready = 0; - -// Outputs -wire input_axis_tready; -wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata; -wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); - - // dump file - $dumpfile("test_axis_adapter_64_8.lxt"); - $dumpvars(0, test_axis_adapter_64_8); -end - -axis_adapter #( - .INPUT_DATA_WIDTH(INPUT_DATA_WIDTH), - .INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH), - .OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH), - .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH) -) -UUT ( - .clk(clk), - .rst(rst), - // AXI input - .input_axis_tdata(input_axis_tdata), - .input_axis_tkeep(input_axis_tkeep), - .input_axis_tvalid(input_axis_tvalid), - .input_axis_tready(input_axis_tready), - .input_axis_tlast(input_axis_tlast), - .input_axis_tuser(input_axis_tuser), - // AXI output - .output_axis_tdata(output_axis_tdata), - .output_axis_tkeep(output_axis_tkeep), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser) -); - -endmodule diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py deleted file mode 100755 index 7819e8106..000000000 --- a/tb/test_axis_adapter_8_64.py +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue - -import axis_ep - -module = 'axis_adapter' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s_8_64.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_adapter_8_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - input_axis_tdata = Signal(intbv(0)[8:]) - input_axis_tkeep = Signal(intbv(0)[1:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) - - # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_adapter_8_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - - def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: - source_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - - def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - for payload_len in range(1,18): - yield clk.posedge - print("test 1: test packet, length %d" % payload_len) - current_test.next = 1 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield clk.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - assert sink_queue.empty() - - yield delay(100) - - yield clk.posedge - print("test 2: back-to-back packets, length %d" % payload_len) - current_test.next = 2 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield clk.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - assert sink_queue.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: tuser assert, length %d" % payload_len) - current_test.next = 3 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - - test_frame1.user = 1 - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield clk.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - assert rx_frame.user[-1] - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - assert sink_queue.empty() - - yield delay(100) - - raise StopSimulation - - return dut, source, sink, clkgen, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_adapter_8_64.v b/tb/test_axis_adapter_8_64.v deleted file mode 100644 index e27187a4d..000000000 --- a/tb/test_axis_adapter_8_64.v +++ /dev/null @@ -1,105 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_adapter_8_64; - -// parameters -localparam INPUT_DATA_WIDTH = 8; -localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); -localparam OUTPUT_DATA_WIDTH = 64; -localparam OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg input_axis_tuser = 0; -reg output_axis_tready = 0; - -// Outputs -wire input_axis_tready; -wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata; -wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); - - // dump file - $dumpfile("test_axis_adapter_8_64.lxt"); - $dumpvars(0, test_axis_adapter_8_64); -end - -axis_adapter #( - .INPUT_DATA_WIDTH(INPUT_DATA_WIDTH), - .INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH), - .OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH), - .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH) -) -UUT ( - .clk(clk), - .rst(rst), - // AXI input - .input_axis_tdata(input_axis_tdata), - .input_axis_tkeep(input_axis_tkeep), - .input_axis_tvalid(input_axis_tvalid), - .input_axis_tready(input_axis_tready), - .input_axis_tlast(input_axis_tlast), - .input_axis_tuser(input_axis_tuser), - // AXI output - .output_axis_tdata(output_axis_tdata), - .output_axis_tkeep(output_axis_tkeep), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser) -); - -endmodule diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py deleted file mode 100755 index fe65d118a..000000000 --- a/tb/test_axis_fifo.py +++ /dev/null @@ -1,396 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue - -import axis_ep - -module = 'axis_fifo' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_fifo(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - input_axis_tdata = Signal(intbv(0)[8:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) - - # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_fifo(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - yield clk.posedge - - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - source_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - assert rx_frame.user[-1] - - yield delay(100) - - raise StopSimulation - - return dut, source, sink, clkgen, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_fifo.v b/tb/test_axis_fifo.v deleted file mode 100644 index 896274765..000000000 --- a/tb/test_axis_fifo.v +++ /dev/null @@ -1,91 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_fifo; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [7:0] input_axis_tdata = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg input_axis_tuser = 0; -reg output_axis_tready = 0; - -// Outputs -wire input_axis_tready; -wire [7:0] output_axis_tdata; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); - - // dump file - $dumpfile("test_axis_fifo.lxt"); - $dumpvars(0, test_axis_fifo); -end - -axis_fifo #( - .ADDR_WIDTH(2), - .DATA_WIDTH(8) -) -UUT ( - .clk(clk), - .rst(rst), - // AXI input - .input_axis_tdata(input_axis_tdata), - .input_axis_tvalid(input_axis_tvalid), - .input_axis_tready(input_axis_tready), - .input_axis_tlast(input_axis_tlast), - .input_axis_tuser(input_axis_tuser), - // AXI output - .output_axis_tdata(output_axis_tdata), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser) -); - -endmodule diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py deleted file mode 100755 index b39ad8282..000000000 --- a/tb/test_axis_fifo_64.py +++ /dev/null @@ -1,406 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue - -import axis_ep - -module = 'axis_fifo_64' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_fifo_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - input_axis_tdata = Signal(intbv(0)[64:]) - input_axis_tkeep = Signal(intbv(0)[8:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) - - # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_fifo_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - yield clk.posedge - - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - source_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - assert rx_frame.user[-1] - - yield delay(100) - - raise StopSimulation - - return dut, source, sink, clkgen, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_fifo_64.v b/tb/test_axis_fifo_64.v deleted file mode 100644 index e95a6ed80..000000000 --- a/tb/test_axis_fifo_64.v +++ /dev/null @@ -1,97 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_fifo_64; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [63:0] input_axis_tdata = 0; -reg [7:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg input_axis_tuser = 0; -reg output_axis_tready = 0; - -// Outputs -wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); - - // dump file - $dumpfile("test_axis_fifo_64.lxt"); - $dumpvars(0, test_axis_fifo_64); -end - -axis_fifo_64 #( - .ADDR_WIDTH(2), - .DATA_WIDTH(64) -) -UUT ( - .clk(clk), - .rst(rst), - // AXI input - .input_axis_tdata(input_axis_tdata), - .input_axis_tkeep(input_axis_tkeep), - .input_axis_tvalid(input_axis_tvalid), - .input_axis_tready(input_axis_tready), - .input_axis_tlast(input_axis_tlast), - .input_axis_tuser(input_axis_tuser), - // AXI output - .output_axis_tdata(output_axis_tdata), - .output_axis_tkeep(output_axis_tkeep), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser) -); - -endmodule diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py deleted file mode 100755 index bdd5ba98e..000000000 --- a/tb/test_axis_frame_join_4.py +++ /dev/null @@ -1,555 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue -import struct - -import axis_ep - -module = 'axis_frame_join_4' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_frame_join_4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - tag, - busy): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tuser=input_0_axis_tuser, - - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tuser=input_1_axis_tuser, - - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tuser=input_2_axis_tuser, - - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tuser=input_3_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - tag=tag, - busy=busy) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - input_0_axis_tdata = Signal(intbv(0)[8:]) - input_0_axis_tvalid = Signal(bool(0)) - input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tuser = Signal(bool(0)) - input_1_axis_tdata = Signal(intbv(0)[8:]) - input_1_axis_tvalid = Signal(bool(0)) - input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tuser = Signal(bool(0)) - input_2_axis_tdata = Signal(intbv(0)[8:]) - input_2_axis_tvalid = Signal(bool(0)) - input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tuser = Signal(bool(0)) - input_3_axis_tdata = Signal(intbv(0)[8:]) - input_3_axis_tvalid = Signal(bool(0)) - input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) - tag = Signal(intbv(0)[15:]) - - # Outputs - input_0_axis_tready = Signal(bool(0)) - input_1_axis_tready = Signal(bool(0)) - input_2_axis_tready = Signal(bool(0)) - input_3_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - busy = Signal(bool(0)) - - # sources and sinks - source_0_queue = Queue() - source_0_pause = Signal(bool(0)) - source_1_queue = Queue() - source_1_pause = Signal(bool(0)) - source_2_queue = Queue() - source_2_pause = Signal(bool(0)) - source_3_queue = Queue() - source_3_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source_0 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_0_axis_tdata, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tuser=input_0_axis_tuser, - fifo=source_0_queue, - pause=source_0_pause, - name='source_0') - - source_1 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_1_axis_tdata, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tuser=input_1_axis_tuser, - fifo=source_1_queue, - pause=source_1_pause, - name='source_1') - - source_2 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_2_axis_tdata, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tuser=input_2_axis_tuser, - fifo=source_2_queue, - pause=source_2_pause, - name='source_2') - - source_3 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_3_axis_tdata, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tuser=input_3_axis_tuser, - fifo=source_3_queue, - pause=source_3_pause, - name='source_3') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_frame_join_4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - tag, - busy) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - yield clk.posedge - tag.next = 1 - - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0) - source_1_queue.put(test_frame_1) - source_2_queue.put(test_frame_2) - source_3_queue.put(test_frame_3) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data - - yield delay(100) - - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 - - test_frame_0 = axis_ep.AXIStreamFrame(b'\x00' + bytearray(range(256)) + b'\x00') - test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0) - source_1_queue.put(test_frame_1) - source_2_queue.put(test_frame_2) - source_3_queue.put(test_frame_3) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data - - yield delay(100) - - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 - - test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0) - source_1_queue.put(test_frame_1) - source_2_queue.put(test_frame_2) - source_3_queue.put(test_frame_3) - yield clk.posedge - - yield delay(64) - yield clk.posedge - source_1_pause.next = True - yield delay(32) - yield clk.posedge - source_1_pause.next = False - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0a) - source_0_queue.put(test_frame_0b) - source_1_queue.put(test_frame_1a) - source_1_queue.put(test_frame_1b) - source_2_queue.put(test_frame_2a) - source_2_queue.put(test_frame_2b) - source_3_queue.put(test_frame_3a) - source_3_queue.put(test_frame_3b) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0a) - source_0_queue.put(test_frame_0b) - source_1_queue.put(test_frame_1a) - source_1_queue.put(test_frame_1b) - source_2_queue.put(test_frame_2a) - source_2_queue.put(test_frame_2b) - source_3_queue.put(test_frame_3a) - source_3_queue.put(test_frame_3b) - yield clk.posedge - - while input_3_axis_tvalid or output_axis_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0a) - source_0_queue.put(test_frame_0b) - source_1_queue.put(test_frame_1a) - source_1_queue.put(test_frame_1b) - source_2_queue.put(test_frame_2a) - source_2_queue.put(test_frame_2b) - source_3_queue.put(test_frame_3a) - source_3_queue.put(test_frame_3b) - yield clk.posedge - - while input_3_axis_tvalid or output_axis_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data - - yield delay(100) - - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 - - test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00') - test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') - test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') - test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - test_frame_0.user = 1 - source_0_queue.put(test_frame_0) - source_1_queue.put(test_frame_1) - source_2_queue.put(test_frame_2) - source_3_queue.put(test_frame_3) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data - assert rx_frame.user[-1] - - yield delay(100) - - raise StopSimulation - - return dut, source_0, source_1, source_2, source_3, sink, clkgen, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_frame_join_4.v b/tb/test_axis_frame_join_4.v deleted file mode 100644 index 21e005b32..000000000 --- a/tb/test_axis_frame_join_4.v +++ /dev/null @@ -1,143 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_frame_join_4; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [7:0] input_0_axis_tdata = 8'd0; -reg input_0_axis_tvalid = 1'b0; -reg input_0_axis_tlast = 1'b0; -reg input_0_axis_tuser = 1'b0; -reg [7:0] input_1_axis_tdata = 8'd0; -reg input_1_axis_tvalid = 1'b0; -reg input_1_axis_tlast = 1'b0; -reg input_1_axis_tuser = 1'b0; -reg [7:0] input_2_axis_tdata = 8'd0; -reg input_2_axis_tvalid = 1'b0; -reg input_2_axis_tlast = 1'b0; -reg input_2_axis_tuser = 1'b0; -reg [7:0] input_3_axis_tdata = 8'd0; -reg input_3_axis_tvalid = 1'b0; -reg input_3_axis_tlast = 1'b0; -reg input_3_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; -reg [15:0] tag = 0; - -// Outputs -wire input_0_axis_tready; -wire input_1_axis_tready; -wire input_2_axis_tready; -wire input_3_axis_tready; -wire [7:0] output_axis_tdata; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; -wire busy; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tuser, - output_axis_tready, - tag); - $to_myhdl(input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, - busy); - - // dump file - $dumpfile("test_axis_frame_join_4.lxt"); - $dumpvars(0, test_axis_frame_join_4); -end - -axis_frame_join_4 #( - .ENABLE_TAG(1) -) -UUT ( - .clk(clk), - .rst(rst), - // axi input - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tvalid(input_0_axis_tvalid), - .input_0_axis_tready(input_0_axis_tready), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tvalid(input_1_axis_tvalid), - .input_1_axis_tready(input_1_axis_tready), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tvalid(input_2_axis_tvalid), - .input_2_axis_tready(input_2_axis_tready), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tvalid(input_3_axis_tvalid), - .input_3_axis_tready(input_3_axis_tready), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tuser(input_3_axis_tuser), - // axi output - .output_axis_tdata(output_axis_tdata), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser), - // config - .tag(tag), - // status - .busy(busy) -); - -endmodule diff --git a/tb/test_axis_ll_bridge.py b/tb/test_axis_ll_bridge.py deleted file mode 100755 index 21e6d7a43..000000000 --- a/tb/test_axis_ll_bridge.py +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue - -import axis_ep -import ll_ep - -module = 'axis_ll_bridge' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_ll_bridge(clk, - rst, - current_test, - - axis_tdata, - axis_tvalid, - axis_tready, - axis_tlast, - - ll_data_out, - ll_sof_out_n, - ll_eof_out_n, - ll_src_rdy_out_n, - ll_dst_rdy_in_n): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - axis_tdata=axis_tdata, - axis_tvalid=axis_tvalid, - axis_tready=axis_tready, - axis_tlast=axis_tlast, - - ll_data_out=ll_data_out, - ll_sof_out_n=ll_sof_out_n, - ll_eof_out_n=ll_eof_out_n, - ll_src_rdy_out_n=ll_src_rdy_out_n, - ll_dst_rdy_in_n=ll_dst_rdy_in_n) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - axis_tdata = Signal(intbv(0)[8:]) - axis_tvalid = Signal(bool(0)) - axis_tlast = Signal(bool(0)) - ll_dst_rdy_in_n = Signal(bool(1)) - - # Outputs - ll_data_out = Signal(intbv(0)[8:]) - ll_sof_out_n = Signal(bool(1)) - ll_eof_out_n = Signal(bool(1)) - ll_src_rdy_out_n = Signal(bool(1)) - axis_tready = Signal(bool(0)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=axis_tdata, - tvalid=axis_tvalid, - tready=axis_tready, - tlast=axis_tlast, - fifo=source_queue, - pause=source_pause, - name='source') - - sink = ll_ep.LocalLinkSink(clk, - rst, - data_in=ll_data_out, - sof_in_n=ll_sof_out_n, - eof_in_n=ll_eof_out_n, - src_rdy_in_n=ll_src_rdy_out_n, - dst_rdy_out_n=ll_dst_rdy_in_n, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_ll_bridge(clk, - rst, - current_test, - - axis_tdata, - axis_tvalid, - axis_tready, - axis_tlast, - - ll_data_out, - ll_sof_out_n, - ll_eof_out_n, - ll_src_rdy_out_n, - ll_dst_rdy_in_n) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - yield clk.posedge - - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - source_queue.put(bytearray(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')) - yield clk.posedge - - yield ll_eof_out_n.negedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert bytearray(rx_frame) == (b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - - yield delay(100) - - yield clk.posedge - print("test 2: test packet with pauses") - current_test.next = 2 - - source_queue.put(bytearray(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')) - yield clk.posedge - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - yield ll_eof_out_n.negedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert bytearray(rx_frame) == (b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - - yield delay(100) - - raise StopSimulation - - return dut, source, sink, clkgen, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_ll_bridge.v b/tb/test_axis_ll_bridge.v deleted file mode 100644 index 680b570b9..000000000 --- a/tb/test_axis_ll_bridge.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_ll_bridge; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [7:0] axis_tdata = 8'd0; -reg axis_tvalid = 1'b0; -reg axis_tlast = 1'b0; -reg ll_dst_rdy_in_n = 1'b1; - -// Outputs -wire [7:0] ll_data_out; -wire ll_sof_out_n; -wire ll_eof_out_n; -wire ll_src_rdy_out_n; -wire axis_tready; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - axis_tdata, - axis_tvalid, - axis_tlast, - ll_dst_rdy_in_n); - $to_myhdl(ll_data_out, - ll_sof_out_n, - ll_eof_out_n, - ll_src_rdy_out_n, - axis_tready); - - // dump file - $dumpfile("test_axis_ll_bridge.lxt"); - $dumpvars(0, test_axis_ll_bridge); -end - -axis_ll_bridge -UUT ( - .clk(clk), - .rst(rst), - // axi input - .axis_tdata(axis_tdata), - .axis_tvalid(axis_tvalid), - .axis_tready(axis_tready), - .axis_tlast(axis_tlast), - // locallink output - .ll_data_out(ll_data_out), - .ll_sof_out_n(ll_sof_out_n), - .ll_eof_out_n(ll_eof_out_n), - .ll_src_rdy_out_n(ll_src_rdy_out_n), - .ll_dst_rdy_in_n(ll_dst_rdy_in_n) -); - -endmodule diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py deleted file mode 100755 index fc51e35e6..000000000 --- a/tb/test_axis_rate_limit.py +++ /dev/null @@ -1,532 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue - -import axis_ep - -module = 'axis_rate_limit' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_rate_limit(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - rate_num, - rate_denom, - rate_by_frame): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - rate_num=rate_num, - rate_denom=rate_denom, - rate_by_frame=rate_by_frame) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - input_axis_tdata = Signal(intbv(0)[8:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) - - rate_num = Signal(intbv(0)[8:]) - rate_denom = Signal(intbv(0)[8:]) - rate_by_frame = Signal(bool(0)) - - # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_rate_limit(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - rate_num, - rate_denom, - rate_by_frame) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - reset_stats = Signal(bool(False)) - cur_frame = Signal(bool(False)) - tick_count = Signal(intbv(0)) - byte_count = Signal(intbv(0)) - frame_count = Signal(intbv(0)) - - @always(clk.posedge) - def monitor(): - ctc = int(tick_count) - cbc = int(byte_count) - cfc = int(frame_count) - if reset_stats: - ctc = 0 - cbc = 0 - cfc = 0 - reset_stats.next = 0 - ctc += 1 - if output_axis_tready and output_axis_tvalid: - cbc += 1 - if output_axis_tlast: - cur_frame.next = False - elif not cur_frame: - cfc += 1 - cur_frame.next = True - tick_count.next = ctc - byte_count.next = cbc - frame_count.next = cfc - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - yield clk.posedge - rate_num.next = 1 - rate_denom.next = 4 - rate_by_frame.next = 1 - - for frame_mode in (True, False): - print("test frame mode %s" % frame_mode) - rate_by_frame.next = frame_mode - - rate_num.next = 1 - rate_denom.next = 4 - - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - source_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 - source_queue.put(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - assert rx_frame.user[-1] - - yield delay(100) - - yield clk.posedge - print("test 8: various lengths and delays") - current_test.next = 8 - - for rate in ((1,1), (1,2), (1,10), (2,3)): - print("test 8 rate %d / %d" % rate) - rate_num.next = rate[0] - rate_denom.next = rate[1] - - reset_stats.next = 1 - yield clk.posedge - start_time = now() - - lens = [32, 48, 64, 96, 128, 256] - test_frame = [] - - for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(lens[i])))) - - for f in test_frame: - source_queue.put(f) - yield clk.posedge - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - - stop_time = now() - - rx_frame = [] - - for i in range(len(lens)): - if not sink_queue.empty(): - rx_frame.append(sink_queue.get()) - - assert len(rx_frame) == len(test_frame) - - for i in range(len(lens)): - assert rx_frame[i] == test_frame[i] - - cycle = (stop_time - start_time) / 8 - - print("cycles %d" % cycle) - print("tick count %d" % tick_count) - print("byte count %d" % byte_count) - print("frame count %d" % frame_count) - - assert tick_count == cycle - assert byte_count == sum(len(f.data) for f in test_frame) - assert frame_count == len(test_frame) - - test_rate = 1.0 * rate_num / rate_denom - meas_rate = 1.0 * byte_count / tick_count - error = (test_rate - meas_rate) / test_rate - - print("test rate %f" % test_rate) - print("meas rate %f" % meas_rate) - print("error %f%%" % (error*100)) - - assert abs(error) < 0.1 - - yield delay(100) - - raise StopSimulation - - return dut, source, sink, clkgen, monitor, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_rate_limit.v b/tb/test_axis_rate_limit.v deleted file mode 100644 index a03f8f83a..000000000 --- a/tb/test_axis_rate_limit.v +++ /dev/null @@ -1,100 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_rate_limit; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [7:0] input_axis_tdata = 8'd0; -reg input_axis_tvalid = 1'b0; -reg input_axis_tlast = 1'b0; -reg input_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; -reg [7:0] rate_num = 0; -reg [7:0] rate_denom = 0; -reg rate_by_frame = 0; - -// Outputs -wire input_axis_tready; -wire [7:0] output_axis_tdata; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready, - rate_num, - rate_denom, - rate_by_frame); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); - - // dump file - $dumpfile("test_axis_rate_limit.lxt"); - $dumpvars(0, test_axis_rate_limit); -end - -axis_rate_limit #( - .DATA_WIDTH(8) -) -UUT ( - .clk(clk), - .rst(rst), - // axi input - .input_axis_tdata(input_axis_tdata), - .input_axis_tvalid(input_axis_tvalid), - .input_axis_tready(input_axis_tready), - .input_axis_tlast(input_axis_tlast), - .input_axis_tuser(input_axis_tuser), - // axi output - .output_axis_tdata(output_axis_tdata), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser), - // configuration - .rate_num(rate_num), - .rate_denom(rate_denom), - .rate_by_frame(rate_by_frame) -); - -endmodule diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py deleted file mode 100755 index 66548e9ca..000000000 --- a/tb/test_axis_rate_limit_64.py +++ /dev/null @@ -1,542 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue - -import axis_ep - -module = 'axis_rate_limit_64' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_rate_limit_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - rate_num, - rate_denom, - rate_by_frame): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - rate_num=rate_num, - rate_denom=rate_denom, - rate_by_frame=rate_by_frame) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - input_axis_tdata = Signal(intbv(0)[64:]) - input_axis_tkeep = Signal(intbv(0)[8:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) - - rate_num = Signal(intbv(0)[8:]) - rate_denom = Signal(intbv(0)[8:]) - rate_by_frame = Signal(bool(0)) - - # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_rate_limit_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - rate_num, - rate_denom, - rate_by_frame) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - reset_stats = Signal(bool(False)) - cur_frame = Signal(bool(False)) - tick_count = Signal(intbv(0)) - byte_count = Signal(intbv(0)) - frame_count = Signal(intbv(0)) - - @always(clk.posedge) - def monitor(): - ctc = int(tick_count) - cbc = int(byte_count) - cfc = int(frame_count) - if reset_stats: - ctc = 0 - cbc = 0 - cfc = 0 - reset_stats.next = 0 - ctc += len(output_axis_tkeep) - if output_axis_tready and output_axis_tvalid: - cbc += bin(output_axis_tkeep).count('1') - if output_axis_tlast: - cur_frame.next = False - elif not cur_frame: - cfc += 1 - cur_frame.next = True - tick_count.next = ctc - byte_count.next = cbc - frame_count.next = cfc - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - yield clk.posedge - rate_num.next = 1 - rate_denom.next = 4 - rate_by_frame.next = 1 - - for frame_mode in (True, False): - print("test frame mode %s" % frame_mode) - rate_by_frame.next = frame_mode - - rate_num.next = 1 - rate_denom.next = 4 - - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - source_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 - source_queue.put(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - assert rx_frame.user[-1] - - yield delay(100) - - yield clk.posedge - print("test 8: various lengths and delays") - current_test.next = 8 - - for rate in ((1,1), (1,2), (1,10), (2,3)): - print("test 8 rate %d / %d" % rate) - rate_num.next = rate[0] - rate_denom.next = rate[1] - - reset_stats.next = 1 - yield clk.posedge - start_time = now() - - lens = [32, 48, 64, 96, 128, 256] - test_frame = [] - - for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(lens[i])))) - - for f in test_frame: - source_queue.put(f) - yield clk.posedge - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - - stop_time = now() - - rx_frame = [] - - for i in range(len(lens)): - if not sink_queue.empty(): - rx_frame.append(sink_queue.get()) - - assert len(rx_frame) == len(test_frame) - - for i in range(len(lens)): - assert rx_frame[i] == test_frame[i] - - cycle = (stop_time - start_time) / 8 - - print("cycles %d" % cycle) - print("tick count %d" % tick_count) - print("byte count %d" % byte_count) - print("frame count %d" % frame_count) - - assert tick_count == cycle*8 - assert byte_count == sum(len(f.data) for f in test_frame) - assert frame_count == len(test_frame) - - test_rate = 1.0 * rate_num / rate_denom - meas_rate = 1.0 * byte_count / tick_count - error = (test_rate - meas_rate) / test_rate - - print("test rate %f" % test_rate) - print("meas rate %f" % meas_rate) - print("error %f%%" % (error*100)) - - assert abs(error) < 0.1 - - yield delay(100) - - raise StopSimulation - - return dut, source, sink, clkgen, monitor, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_rate_limit_64.v b/tb/test_axis_rate_limit_64.v deleted file mode 100644 index 71644a0da..000000000 --- a/tb/test_axis_rate_limit_64.v +++ /dev/null @@ -1,106 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_rate_limit_64; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [63:0] input_axis_tdata = 8'd0; -reg [7:0] input_axis_tkeep = 8'd0; -reg input_axis_tvalid = 1'b0; -reg input_axis_tlast = 1'b0; -reg input_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; -reg [7:0] rate_num = 0; -reg [7:0] rate_denom = 0; -reg rate_by_frame = 0; - -// Outputs -wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready, - rate_num, - rate_denom, - rate_by_frame); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); - - // dump file - $dumpfile("test_axis_rate_limit_64.lxt"); - $dumpvars(0, test_axis_rate_limit_64); -end - -axis_rate_limit_64 #( - .DATA_WIDTH(64) -) -UUT ( - .clk(clk), - .rst(rst), - // axi input - .input_axis_tdata(input_axis_tdata), - .input_axis_tkeep(input_axis_tkeep), - .input_axis_tvalid(input_axis_tvalid), - .input_axis_tready(input_axis_tready), - .input_axis_tlast(input_axis_tlast), - .input_axis_tuser(input_axis_tuser), - // axi output - .output_axis_tdata(output_axis_tdata), - .output_axis_tkeep(output_axis_tkeep), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser), - // configuration - .rate_num(rate_num), - .rate_denom(rate_denom), - .rate_by_frame(rate_by_frame) -); - -endmodule diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py deleted file mode 100755 index 13d2897fc..000000000 --- a/tb/test_axis_register.py +++ /dev/null @@ -1,396 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue - -import axis_ep - -module = 'axis_register' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_register(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - input_axis_tdata = Signal(intbv(0)[8:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) - - # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_register(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - yield clk.posedge - - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - source_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - assert rx_frame.user[-1] - - yield delay(100) - - raise StopSimulation - - return dut, source, sink, clkgen, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_register.v b/tb/test_axis_register.v deleted file mode 100644 index b442a3604..000000000 --- a/tb/test_axis_register.v +++ /dev/null @@ -1,90 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_register; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [7:0] input_axis_tdata = 8'd0; -reg input_axis_tvalid = 1'b0; -reg input_axis_tlast = 1'b0; -reg input_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; - -// Outputs -wire input_axis_tready; -wire [7:0] output_axis_tdata; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); - - // dump file - $dumpfile("test_axis_register.lxt"); - $dumpvars(0, test_axis_register); -end - -axis_register #( - .DATA_WIDTH(8) -) -UUT ( - .clk(clk), - .rst(rst), - // axi input - .input_axis_tdata(input_axis_tdata), - .input_axis_tvalid(input_axis_tvalid), - .input_axis_tready(input_axis_tready), - .input_axis_tlast(input_axis_tlast), - .input_axis_tuser(input_axis_tuser), - // axi output - .output_axis_tdata(output_axis_tdata), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser) -); - -endmodule diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py deleted file mode 100755 index 4509a6fd0..000000000 --- a/tb/test_axis_register_64.py +++ /dev/null @@ -1,406 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue - -import axis_ep - -module = 'axis_register_64' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_register_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - input_axis_tdata = Signal(intbv(0)[64:]) - input_axis_tkeep = Signal(intbv(0)[8:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) - - # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_register_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - yield clk.posedge - - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: longer packet") - current_test.next = 2 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield clk.posedge - print("test 3: test packet with pauses") - current_test.next = 3 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 4: back-to-back packets") - current_test.next = 4 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 5: alternate pause source") - current_test.next = 5 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - source_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 6: alternate pause sink") - current_test.next = 6 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame1 - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame2 - - yield delay(100) - - yield clk.posedge - print("test 7: tuser assert") - current_test.next = 7 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 - source_queue.put(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert rx_frame == test_frame - assert rx_frame.user[-1] - - yield delay(100) - - raise StopSimulation - - return dut, source, sink, clkgen, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_register_64.v b/tb/test_axis_register_64.v deleted file mode 100644 index 6b2b0e700..000000000 --- a/tb/test_axis_register_64.v +++ /dev/null @@ -1,96 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_register_64; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [63:0] input_axis_tdata = 8'd0; -reg [7:0] input_axis_tkeep = 8'd0; -reg input_axis_tvalid = 1'b0; -reg input_axis_tlast = 1'b0; -reg input_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; - -// Outputs -wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); - - // dump file - $dumpfile("test_axis_register_64.lxt"); - $dumpvars(0, test_axis_register_64); -end - -axis_register_64 #( - .DATA_WIDTH(64) -) -UUT ( - .clk(clk), - .rst(rst), - // axi input - .input_axis_tdata(input_axis_tdata), - .input_axis_tkeep(input_axis_tkeep), - .input_axis_tvalid(input_axis_tvalid), - .input_axis_tready(input_axis_tready), - .input_axis_tlast(input_axis_tlast), - .input_axis_tuser(input_axis_tuser), - // axi output - .output_axis_tdata(output_axis_tdata), - .output_axis_tkeep(output_axis_tkeep), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser) -); - -endmodule diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py deleted file mode 100755 index 04cc90c89..000000000 --- a/tb/test_axis_stat_counter.py +++ /dev/null @@ -1,792 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue -import struct - -import axis_ep - -module = 'axis_stat_counter' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_stat_counter(clk, - rst, - current_test, - - monitor_axis_tdata, - monitor_axis_tkeep, - monitor_axis_tvalid, - monitor_axis_tready, - monitor_axis_tlast, - monitor_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - tag, - trigger, - busy): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - monitor_axis_tdata=monitor_axis_tdata, - monitor_axis_tkeep=monitor_axis_tkeep, - monitor_axis_tvalid=monitor_axis_tvalid, - monitor_axis_tready=monitor_axis_tready, - monitor_axis_tlast=monitor_axis_tlast, - monitor_axis_tuser=monitor_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - tag=tag, - trigger=trigger, - busy=busy) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - monitor_axis_tdata = Signal(intbv(0)[64:]) - monitor_axis_tkeep = Signal(intbv(0)[8:]) - monitor_axis_tvalid = Signal(bool(0)) - monitor_axis_tready = Signal(bool(0)) - monitor_axis_tlast = Signal(bool(0)) - monitor_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) - - tag = Signal(intbv(16)[16:]) - trigger = Signal(bool(0)) - - # Outputs - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - busy = Signal(bool(0)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - monitor_sink_queue = Queue() - monitor_sink_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=monitor_axis_tdata, - tkeep=monitor_axis_tkeep, - tvalid=monitor_axis_tvalid, - tready=monitor_axis_tready, - tlast=monitor_axis_tlast, - tuser=monitor_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') - - monitor_sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=monitor_axis_tdata, - tkeep=monitor_axis_tkeep, - tvalid=monitor_axis_tvalid, - tready=monitor_axis_tready, - tlast=monitor_axis_tlast, - tuser=monitor_axis_tuser, - fifo=monitor_sink_queue, - pause=monitor_sink_pause, - name='monitor_sink') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_axis_stat_counter(clk, - rst, - current_test, - - monitor_axis_tdata, - monitor_axis_tkeep, - monitor_axis_tvalid, - monitor_axis_tready, - monitor_axis_tlast, - monitor_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - tag, - trigger, - busy) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - yield clk.posedge - tag.next = 1 - - yield clk.posedge - print("test 1: test tick timer") - current_test.next = 1 - - yield clk.posedge - start_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - for i in range(100-1): - yield clk.posedge - - stop_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - - # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) - cycles = (stop_time - start_time) / 8 - print(rx_frame_values) - - assert rx_frame_values[0] == 1 - assert rx_frame_values[1] == cycles*8 - assert rx_frame_values[1] == 100*8 - - yield delay(100) - - yield clk.posedge - print("test 2: pause sink") - current_test.next = 2 - - yield clk.posedge - start_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - for i in range(100-1): - yield clk.posedge - - stop_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - while trigger or output_axis_tvalid: - sink_pause.next = True - yield clk.posedge - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - - yield clk.posedge - yield clk.posedge - - # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) - cycles = (stop_time - start_time) / 8 - print(rx_frame_values) - - assert rx_frame_values[0] == 1 - assert rx_frame_values[1] == cycles*8 - assert rx_frame_values[1] == 100*8 - - yield delay(100) - - yield clk.posedge - print("test 3: test packet") - current_test.next = 3 - - yield clk.posedge - start_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) - yield clk.posedge - - while monitor_axis_tvalid: - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - stop_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - - # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) - cycles = (stop_time - start_time) / 8 - print(rx_frame_values) - - assert rx_frame_values[0] == 1 - assert rx_frame_values[1] == cycles*8 - assert rx_frame_values[2] == len(test_frame.data) - assert rx_frame_values[3] == 1 - - yield delay(100) - - yield clk.posedge - print("test 4: longer packet") - current_test.next = 4 - - yield clk.posedge - start_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - while monitor_axis_tvalid: - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - stop_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - - # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) - cycles = (stop_time - start_time) / 8 - print(rx_frame_values) - - assert rx_frame_values[0] == 1 - assert rx_frame_values[1] == cycles*8 - assert rx_frame_values[2] == len(test_frame.data) - assert rx_frame_values[3] == 1 - - yield delay(100) - - yield clk.posedge - print("test 5: test packet with pauses") - current_test.next = 5 - - yield clk.posedge - start_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - source_queue.put(test_frame) - yield clk.posedge - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False - - yield delay(64) - yield clk.posedge - monitor_sink_pause.next = True - yield delay(32) - yield clk.posedge - monitor_sink_pause.next = False - - while monitor_axis_tvalid: - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - stop_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - - # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) - cycles = (stop_time - start_time) / 8 - print(rx_frame_values) - - assert rx_frame_values[0] == 1 - assert rx_frame_values[1] == cycles*8 - assert rx_frame_values[2] == len(test_frame.data) - assert rx_frame_values[3] == 1 - - yield delay(100) - - yield clk.posedge - print("test 6: back-to-back packets") - current_test.next = 6 - - yield clk.posedge - start_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while monitor_axis_tvalid: - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - stop_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - - # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) - cycles = (stop_time - start_time) / 8 - print(rx_frame_values) - - assert rx_frame_values[0] == 1 - assert rx_frame_values[1] == cycles*8 - assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data) - assert rx_frame_values[3] == 2 - - yield delay(100) - - yield clk.posedge - print("test 7: alternate pause source") - current_test.next = 7 - - yield clk.posedge - start_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while monitor_axis_tvalid: - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - stop_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - - # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) - cycles = (stop_time - start_time) / 8 - print(rx_frame_values) - - assert rx_frame_values[0] == 1 - assert rx_frame_values[1] == cycles*8 - assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data) - assert rx_frame_values[3] == 2 - - yield delay(100) - - yield clk.posedge - print("test 8: alternate pause sink") - current_test.next = 8 - - yield clk.posedge - start_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) - yield clk.posedge - - while monitor_axis_tvalid: - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - stop_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - - # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) - cycles = (stop_time - start_time) / 8 - print(rx_frame_values) - - assert rx_frame_values[0] == 1 - assert rx_frame_values[1] == cycles*8 - assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data) - assert rx_frame_values[3] == 2 - - yield delay(100) - - yield clk.posedge - print("test 9: various length packets") - current_test.next = 9 - - yield clk.posedge - start_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - lens = [32, 48, 96, 128, 256] - test_frame = [] - - for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(lens[i])))) - - for f in test_frame: - source_queue.put(f) - yield clk.posedge - - while monitor_axis_tvalid: - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - stop_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - - # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) - cycles = (stop_time - start_time) / 8 - print(rx_frame_values) - - assert rx_frame_values[0] == 1 - assert rx_frame_values[1] == cycles*8 - assert rx_frame_values[2] == sum(len(f.data) for f in test_frame) - assert rx_frame_values[3] == len(test_frame) - - yield delay(100) - - yield clk.posedge - print("test 10: various length packets with intermediate trigger") - current_test.next = 10 - - yield clk.posedge - start_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - - lens = [32, 48, 96, 128, 256] - test_frame = [] - - for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(lens[i])))) - - for f in test_frame: - source_queue.put(f) - yield clk.posedge - - yield delay(200) - - yield clk.posedge - trigger_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - yield clk.posedge - - while monitor_axis_tvalid: - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - stop_time = now() - trigger.next = 1 - yield clk.posedge - trigger.next = 0 - yield clk.posedge - - while output_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - - # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - # check second trigger output - if not sink_queue.empty(): - rx_frame2 = sink_queue.get() - - rx_frame_values = struct.unpack(">HLLL", rx_frame.data) - cycles = (stop_time - start_time) / 8 - cycles1 = (trigger_time - start_time) / 8 - print(rx_frame_values) - - rx_frame2_values = struct.unpack(">HLLL", rx_frame2.data) - cycles2 = (stop_time - trigger_time) / 8 - print(rx_frame2_values) - - assert rx_frame_values[0] == 1 - assert rx_frame2_values[0] == 1 - assert rx_frame_values[1] == cycles1*8 - assert rx_frame2_values[1] == cycles2*8 - assert rx_frame_values[1] + rx_frame2_values[1] == cycles*8 - assert rx_frame_values[2] + rx_frame2_values[2] == sum(len(f.data) for f in test_frame) - assert rx_frame_values[3] + rx_frame2_values[3] == len(test_frame) - - yield delay(100) - - raise StopSimulation - - return dut, source, monitor_sink, sink, clkgen, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v deleted file mode 100644 index 529495195..000000000 --- a/tb/test_axis_stat_counter.v +++ /dev/null @@ -1,102 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_axis_stat_counter; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [63:0] monitor_axis_tdata = 8'd0; -reg [7:0] monitor_axis_tkeep = 8'd0; -reg monitor_axis_tvalid = 1'b0; -reg monitor_axis_tready = 1'b0; -reg monitor_axis_tlast = 1'b0; -reg monitor_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; -reg [15:0] tag = 0; -reg trigger = 0; - -// Outputs -wire [7:0] output_axis_tdata; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; -wire busy; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - monitor_axis_tdata, - monitor_axis_tkeep, - monitor_axis_tvalid, - monitor_axis_tready, - monitor_axis_tlast, - monitor_axis_tuser, - output_axis_tready, - tag, - trigger); - $to_myhdl(output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, - busy); - - // dump file - $dumpfile("test_axis_stat_counter.lxt"); - $dumpvars(0, test_axis_stat_counter); -end - -axis_stat_counter #( - .DATA_WIDTH(64) -) -UUT ( - .clk(clk), - .rst(rst), - // axi monitor input - .monitor_axis_tkeep(monitor_axis_tkeep), - .monitor_axis_tvalid(monitor_axis_tvalid), - .monitor_axis_tready(monitor_axis_tready), - .monitor_axis_tlast(monitor_axis_tlast), - // axi output - .output_axis_tdata(output_axis_tdata), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser), - // configuration - .tag(tag), - .trigger(trigger), - // status - .busy(busy) -); - -endmodule diff --git a/tb/test_ll_axis_bridge.py b/tb/test_ll_axis_bridge.py deleted file mode 100755 index 7c6ca681d..000000000 --- a/tb/test_ll_axis_bridge.py +++ /dev/null @@ -1,231 +0,0 @@ -#!/usr/bin/env python2 -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -from Queue import Queue - -import axis_ep -import ll_ep - -module = 'll_axis_bridge' - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_ll_axis_bridge(clk, - rst, - current_test, - - ll_data_in, - ll_sof_in_n, - ll_eof_in_n, - ll_src_rdy_in_n, - ll_dst_rdy_out_n, - - axis_tdata, - axis_tvalid, - axis_tready, - axis_tlast): - - os.system(build_cmd) - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - ll_data_in=ll_data_in, - ll_sof_in_n=ll_sof_in_n, - ll_eof_in_n=ll_eof_in_n, - ll_src_rdy_in_n=ll_src_rdy_in_n, - ll_dst_rdy_out_n=ll_dst_rdy_out_n, - - axis_tdata=axis_tdata, - axis_tvalid=axis_tvalid, - axis_tready=axis_tready, - axis_tlast=axis_tlast) - -def bench(): - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - ll_data_in = Signal(intbv(0)[8:]) - ll_sof_in_n = Signal(bool(1)) - ll_eof_in_n = Signal(bool(1)) - ll_src_rdy_in_n = Signal(bool(1)) - axis_tready = Signal(bool(0)) - - # Outputs - axis_tdata = Signal(intbv(0)[8:]) - axis_tvalid = Signal(bool(0)) - axis_tlast = Signal(bool(0)) - ll_dst_rdy_out_n = Signal(bool(1)) - - # sources and sinks - source_queue = Queue() - source_pause = Signal(bool(0)) - sink_queue = Queue() - sink_pause = Signal(bool(0)) - - source = ll_ep.LocalLinkSource(clk, - rst, - data_out=ll_data_in, - sof_out_n=ll_sof_in_n, - eof_out_n=ll_eof_in_n, - src_rdy_out_n=ll_src_rdy_in_n, - dst_rdy_in_n=ll_dst_rdy_out_n, - fifo=source_queue, - pause=source_pause, - name='source') - - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=axis_tdata, - tvalid=axis_tvalid, - tready=axis_tready, - tlast=axis_tlast, - fifo=sink_queue, - pause=sink_pause, - name='sink') - - # DUT - dut = dut_ll_axis_bridge(clk, - rst, - current_test, - - ll_data_in, - ll_sof_in_n, - ll_eof_in_n, - ll_src_rdy_in_n, - ll_dst_rdy_out_n, - - axis_tdata, - axis_tvalid, - axis_tready, - axis_tlast) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - yield clk.posedge - - yield clk.posedge - print("test 1: test packet") - current_test.next = 1 - - source_queue.put(bytearray(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')) - yield clk.posedge - - yield axis_tlast.negedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert bytearray(rx_frame) == (b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - - yield delay(100) - - yield clk.posedge - print("test 2: test packet with pauses") - current_test.next = 2 - - source_queue.put(bytearray(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')) - yield clk.posedge - - yield delay(64) - yield clk.posedge - source_pause.next = True - yield delay(32) - yield clk.posedge - source_pause.next = False - - yield delay(64) - yield clk.posedge - sink_pause.next = True - yield delay(32) - yield clk.posedge - sink_pause.next = False - - yield axis_tlast.negedge - yield clk.posedge - yield clk.posedge - - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() - - assert bytearray(rx_frame) == (b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - - yield delay(100) - - raise StopSimulation - - return dut, source, sink, clkgen, check - -def test_bench(): - os.chdir(os.path.dirname(os.path.abspath(__file__))) - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() - diff --git a/tb/test_ll_axis_bridge.v b/tb/test_ll_axis_bridge.v deleted file mode 100644 index 573fec7c5..000000000 --- a/tb/test_ll_axis_bridge.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module test_ll_axis_bridge; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [7:0] ll_data_in = 0; -reg ll_sof_in_n = 1; -reg ll_eof_in_n = 1; -reg ll_src_rdy_in_n = 1; -reg axis_tready = 0; - -// Outputs -wire ll_dst_rdy_out_n; -wire [7:0] axis_tdata; -wire axis_tvalid; -wire axis_tlast; - -initial begin - // myhdl integration - $from_myhdl(clk, - rst, - current_test, - ll_data_in, - ll_sof_in_n, - ll_eof_in_n, - ll_src_rdy_in_n, - axis_tready); - $to_myhdl(axis_tdata, - axis_tvalid, - axis_tlast, - ll_dst_rdy_out_n); - - // dump file - $dumpfile("test_ll_axis_bridge.lxt"); - $dumpvars(0, test_ll_axis_bridge); -end - -ll_axis_bridge -UUT ( - .clk(clk), - .rst(rst), - // locallink input - .ll_data_in(ll_data_in), - .ll_sof_in_n(ll_sof_in_n), - .ll_eof_in_n(ll_eof_in_n), - .ll_src_rdy_in_n(ll_src_rdy_in_n), - .ll_dst_rdy_out_n(ll_dst_rdy_out_n), - // axi output - .axis_tdata(axis_tdata), - .axis_tvalid(axis_tvalid), - .axis_tready(axis_tready), - .axis_tlast(axis_tlast) -); - -endmodule From d64445b9e057cf97ae8fd57fbe83c5505c6ba45c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 5 Nov 2014 17:24:48 -0800 Subject: [PATCH 075/617] Add git subdir script for axis lib --- lib/update-axis.sh | 118 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100755 lib/update-axis.sh diff --git a/lib/update-axis.sh b/lib/update-axis.sh new file mode 100755 index 000000000..ccc2eaa81 --- /dev/null +++ b/lib/update-axis.sh @@ -0,0 +1,118 @@ +#!/bin/bash + +# Git subtree manager +# Alex Forencich +# This script facilitates easy management of subtrees +# included in larger repositories as this script can +# be included in the repository itself. + +# Settings +# uncomment to use --squash +#squash="yes" +# Remote repository +repo="git@github.com:alexforencich/verilog-axis.git" +# Remote name +remote="axis" +# Subdirectory to store code in +# (relative to repo root or to script location) +#subdir="axis" +rel_subdir="axis" +# Remote branch +branch="master" +# Backport branch name (only used for pushing) +backportbranch="${remote}backport" +# Add commit message +addmsg="added ${remote} as a subproject" +# Merge commit message +mergemsg="merged changes in ${remote}" + +# Usage +# add - adds subtree +# pull - default, pulls from remote +# push - pushes to remote + +# determine repo absolute path +if [ -n "$rel_subdir" ]; then + # cd to script dir + SOURCE="${BASH_SOURCE[0]}" + while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located + done + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + + cd "$DIR" + + # relative path to script dir + git-absolute-path () { + fullpath=$(readlink -f "$1") + gitroot="$(git rev-parse --show-toplevel)" || return 1 + [[ "$fullpath" =~ "$gitroot" ]] && echo "${fullpath/$gitroot\//}" + } + + subdir="$(git-absolute-path .)/$rel_subdir" +fi + +squashflag="" + +cd $(git rev-parse --show-toplevel) + +if [ $squash ]; then + squashflag="--squash" +fi + +action="pull" + +if [ ! -d "$subdir" ]; then + action="add" +fi + +if [ -n "$1" ]; then + action="$1" +fi + +# array contains value +# usage: contains array value +function contains() { + local n=$# + local value=${!n} + for ((i=1;i < $n;i++)) { + if [ "${!i}" == "${value}" ]; then + echo "y" + return 0 + fi + } + echo "n" + return 1 +} + +case "$action" in + add) + if [ $(contains $(git remote) "$remote") != "y" ]; then + git remote add "$remote" "$repo" + fi + git fetch "$remote" + git subtree add -P "$subdir" $squashflag -m "$addmsg" "$remote/$branch" + ;; + pull) + if [ $(contains $(git remote) "$remote") != "y" ]; then + git remote add "$remote" "$repo" + fi + git fetch "$remote" + git subtree merge -P "$subdir" $squashflag -m "$mergemsg" "$remote/$branch" + ;; + push) + if [ $(contains $(git remote) "$remote") != "y" ]; then + git remote add "$remote" "$repo" + fi + git subtree split -P "$subdir" -b "$backportbranch" + git push "$remote" "$backportbranch:$branch" + ;; + *) + echo "Error: unknown action!" + exit 1 +esac + +exit 0 + From 918ef8f76caa46b60cc5d92e5eca5ab553e625d5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 8 Nov 2014 00:23:23 -0800 Subject: [PATCH 076/617] Add AXI async FIFO and testbench --- rtl/axis_async_fifo.v | 149 ++++++++++++ rtl/axis_async_fifo_64.v | 152 ++++++++++++ tb/test_axis_async_fifo.py | 412 +++++++++++++++++++++++++++++++++ tb/test_axis_async_fifo.v | 97 ++++++++ tb/test_axis_async_fifo_64.py | 422 ++++++++++++++++++++++++++++++++++ tb/test_axis_async_fifo_64.v | 103 +++++++++ 6 files changed, 1335 insertions(+) create mode 100644 rtl/axis_async_fifo.v create mode 100644 rtl/axis_async_fifo_64.v create mode 100755 tb/test_axis_async_fifo.py create mode 100644 tb/test_axis_async_fifo.v create mode 100755 tb/test_axis_async_fifo_64.py create mode 100644 tb/test_axis_async_fifo_64.v diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v new file mode 100644 index 000000000..f52e04121 --- /dev/null +++ b/rtl/axis_async_fifo.v @@ -0,0 +1,149 @@ +/* + +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 asynchronous FIFO + */ +module axis_async_fifo # +( + parameter ADDR_WIDTH = 12, + parameter DATA_WIDTH = 8 +) +( + /* + * AXI input + */ + input wire input_clk, + input wire input_rst, + 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 + */ + input wire output_clk, + input wire output_rst, + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser +); + +reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_gray = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; + +reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; + +reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}}; + +//(* RAM_STYLE="BLOCK" *) +reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; + +reg output_read = 1'b0; + +reg output_axis_tvalid_reg = 1'b0; + +wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; + +// full when first TWO MSBs do NOT match, but rest matches +// (gray code equivalent of first MSB different but rest same) +wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync3[ADDR_WIDTH]) && + (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync3[ADDR_WIDTH-1]) && + (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync3[ADDR_WIDTH-2:0])); +// empty when pointers match exactly +wire empty = rd_ptr_gray == wr_ptr_gray_sync3; + +wire write = input_axis_tvalid & ~full; +wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; + +assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = data_out_reg; + +assign input_axis_tready = ~full; +assign output_axis_tvalid = output_axis_tvalid_reg; + +// write +always @(posedge input_clk or posedge input_rst) begin + if (input_rst) begin + wr_ptr <= 0; + end else if (write) begin + mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; + wr_ptr_next = wr_ptr + 1; + wr_ptr <= wr_ptr_next; + wr_ptr_gray <= wr_ptr_next ^ (wr_ptr_next >> 1); + end +end + +// pointer synchronization in SRL16 +always @(posedge input_clk) begin + rd_ptr_gray_sync1 <= rd_ptr_gray; + rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + rd_ptr_gray_sync3 <= rd_ptr_gray_sync2; +end + +// read +always @(posedge output_clk or posedge output_rst) begin + if (output_rst) begin + rd_ptr <= 0; + end else if (read) begin + data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; + rd_ptr_next = rd_ptr + 1; + rd_ptr <= rd_ptr_next; + rd_ptr_gray <= rd_ptr_next ^ (rd_ptr_next >> 1); + end +end + +// pointer synchronization in SRL16 +always @(posedge output_clk) begin + wr_ptr_gray_sync1 <= wr_ptr_gray; + wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; + wr_ptr_gray_sync3 <= wr_ptr_gray_sync2; +end + +// source ready output +always @(posedge output_clk or posedge output_rst) begin + if (output_rst) begin + output_axis_tvalid_reg <= 1'b0; + end else if (output_axis_tready | ~output_axis_tvalid_reg) begin + output_axis_tvalid_reg <= ~empty; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_reg; + end +end + +endmodule diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v new file mode 100644 index 000000000..baf3bf406 --- /dev/null +++ b/rtl/axis_async_fifo_64.v @@ -0,0 +1,152 @@ +/* + +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 asynchronous FIFO (64 bit datapath) + */ +module axis_async_fifo_64 # +( + parameter ADDR_WIDTH = 12, + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + /* + * AXI input + */ + input wire input_clk, + input wire input_rst, + 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 + */ + input wire output_clk, + input wire output_rst, + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_axis_tkeep, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser +); + +reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_gray = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; + +reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; + +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; + +//(* RAM_STYLE="BLOCK" *) +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; + +reg output_read = 1'b0; + +reg output_axis_tvalid_reg = 1'b0; + +wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; + +// full when first TWO MSBs do NOT match, but rest matches +// (gray code equivalent of first MSB different but rest same) +wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync3[ADDR_WIDTH]) && + (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync3[ADDR_WIDTH-1]) && + (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync3[ADDR_WIDTH-2:0])); +// empty when pointers match exactly +wire empty = rd_ptr_gray == wr_ptr_gray_sync3; + +wire write = input_axis_tvalid & ~full; +wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; + +assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = data_out_reg; + +assign input_axis_tready = ~full; +assign output_axis_tvalid = output_axis_tvalid_reg; + +// write +always @(posedge input_clk or posedge input_rst) begin + if (input_rst) begin + wr_ptr <= 0; + end else if (write) begin + mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; + wr_ptr_next = wr_ptr + 1; + wr_ptr <= wr_ptr_next; + wr_ptr_gray <= wr_ptr_next ^ (wr_ptr_next >> 1); + end +end + +// pointer synchronization in SRL16 +always @(posedge input_clk) begin + rd_ptr_gray_sync1 <= rd_ptr_gray; + rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + rd_ptr_gray_sync3 <= rd_ptr_gray_sync2; +end + +// read +always @(posedge output_clk or posedge output_rst) begin + if (output_rst) begin + rd_ptr <= 0; + end else if (read) begin + data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; + rd_ptr_next = rd_ptr + 1; + rd_ptr <= rd_ptr_next; + rd_ptr_gray <= rd_ptr_next ^ (rd_ptr_next >> 1); + end +end + +// pointer synchronization in SRL16 +always @(posedge output_clk) begin + wr_ptr_gray_sync1 <= wr_ptr_gray; + wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; + wr_ptr_gray_sync3 <= wr_ptr_gray_sync2; +end + +// source ready output +always @(posedge output_clk or posedge output_rst) begin + if (output_rst) begin + output_axis_tvalid_reg <= 1'b0; + end else if (output_axis_tready | ~output_axis_tvalid_reg) begin + output_axis_tvalid_reg <= ~empty; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_reg; + end +end + +endmodule diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py new file mode 100755 index 000000000..e6eb8a3c5 --- /dev/null +++ b/tb/test_axis_async_fifo.py @@ -0,0 +1,412 @@ +#!/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_async_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_async_fifo(input_clk, + input_rst, + output_clk, + output_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, + input_clk=input_clk, + input_rst=input_rst, + output_clk=output_clk, + output_rst=output_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 + input_clk = Signal(bool(0)) + input_rst = Signal(bool(0)) + output_clk = Signal(bool(0)) + output_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(input_clk, + input_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(output_clk, + output_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_async_fifo(input_clk, + input_rst, + output_clk, + output_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 input_clkgen(): + input_clk.next = not input_clk + + @always(delay(5)) + def output_clkgen(): + output_clk.next = not output_clk + + @instance + def check(): + yield delay(100) + yield input_clk.posedge + input_rst.next = 1 + output_rst.next = 1 + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + input_rst.next = 0 + output_rst.next = 0 + yield input_clk.posedge + yield delay(100) + yield input_clk.posedge + + yield input_clk.posedge + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield input_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 input_clk.posedge + + yield delay(64) + yield input_clk.posedge + source_pause.next = True + yield delay(32) + yield input_clk.posedge + source_pause.next = False + + yield delay(64) + yield output_clk.posedge + sink_pause.next = True + yield delay(32) + yield output_clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + source_pause.next = False + yield input_clk.posedge + + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + sink_pause.next = False + yield output_clk.posedge + + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_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, input_clkgen, output_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() + diff --git a/tb/test_axis_async_fifo.v b/tb/test_axis_async_fifo.v new file mode 100644 index 000000000..dbfbdd494 --- /dev/null +++ b/tb/test_axis_async_fifo.v @@ -0,0 +1,97 @@ +/* + +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_async_fifo; + +// Inputs +reg input_clk = 0; +reg input_rst = 0; +reg output_clk = 0; +reg output_rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_axis_tdata = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(input_clk, + input_rst, + output_clk, + output_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_async_fifo.lxt"); + $dumpvars(0, test_axis_async_fifo); +end + +axis_async_fifo #( + .ADDR_WIDTH(2), + .DATA_WIDTH(8) +) +UUT ( + // AXI input + .input_clk(input_clk), + .input_rst(input_rst), + .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_clk(output_clk), + .output_rst(output_rst), + .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 diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py new file mode 100755 index 000000000..6b9eabeef --- /dev/null +++ b/tb/test_axis_async_fifo_64.py @@ -0,0 +1,422 @@ +#!/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_async_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_async_fifo_64(input_clk, + input_rst, + output_clk, + output_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, + input_clk=input_clk, + input_rst=input_rst, + output_clk=output_clk, + output_rst=output_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 + input_clk = Signal(bool(0)) + input_rst = Signal(bool(0)) + output_clk = Signal(bool(0)) + output_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(input_clk, + input_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(output_clk, + output_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_async_fifo_64(input_clk, + input_rst, + output_clk, + output_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 input_clkgen(): + input_clk.next = not input_clk + + @always(delay(5)) + def output_clkgen(): + output_clk.next = not output_clk + + @instance + def check(): + yield delay(100) + yield input_clk.posedge + input_rst.next = 1 + output_rst.next = 1 + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + input_rst.next = 0 + output_rst.next = 0 + yield input_clk.posedge + yield delay(100) + yield input_clk.posedge + + yield input_clk.posedge + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield input_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 input_clk.posedge + + yield delay(64) + yield input_clk.posedge + source_pause.next = True + yield delay(32) + yield input_clk.posedge + source_pause.next = False + + yield delay(64) + yield output_clk.posedge + sink_pause.next = True + yield delay(32) + yield output_clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + source_pause.next = False + yield input_clk.posedge + + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + sink_pause.next = False + yield output_clk.posedge + + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_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, input_clkgen, output_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() + diff --git a/tb/test_axis_async_fifo_64.v b/tb/test_axis_async_fifo_64.v new file mode 100644 index 000000000..6741debeb --- /dev/null +++ b/tb/test_axis_async_fifo_64.v @@ -0,0 +1,103 @@ +/* + +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_async_fifo_64; + +// Inputs +reg input_clk = 0; +reg input_rst = 0; +reg output_clk = 0; +reg output_rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] input_axis_tdata = 0; +reg [7:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [63:0] output_axis_tdata; +wire [7:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(input_clk, + input_rst, + output_clk, + output_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_async_fifo_64.lxt"); + $dumpvars(0, test_axis_async_fifo_64); +end + +axis_async_fifo_64 #( + .ADDR_WIDTH(2), + .DATA_WIDTH(64) +) +UUT ( + // AXI input + .input_clk(input_clk), + .input_rst(input_rst), + .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_clk(output_clk), + .output_rst(output_rst), + .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 From b232a6459d082dcba624fce6b442c87fce150c73 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 8 Nov 2014 12:45:36 -0800 Subject: [PATCH 077/617] Remove counter from AXI fifo modules --- rtl/axis_fifo.v | 27 +++++++++------------------ rtl/axis_fifo_64.v | 27 +++++++++------------------ 2 files changed, 18 insertions(+), 36 deletions(-) diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index 8004a8311..6a291ff99 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -57,9 +57,8 @@ module axis_fifo # output wire output_axis_tuser ); -reg [ADDR_WIDTH-1:0] wr_ptr = {ADDR_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] rd_ptr = {ADDR_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] counter = {ADDR_WIDTH{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}}; @@ -72,8 +71,11 @@ reg output_axis_tvalid_reg = 1'b0; wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; -wire full = (counter == (2**ADDR_WIDTH)-1); -wire empty = (counter == 0); +// full when first MSB different but rest same +wire full = ((wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && + (wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0])); +// empty when pointers match exactly +wire empty = wr_ptr == rd_ptr; wire write = input_axis_tvalid & ~full; wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; @@ -88,7 +90,7 @@ always @(posedge clk or posedge rst) begin if (rst) begin wr_ptr <= 0; end else if (write) begin - mem[wr_ptr] <= data_in; + mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; wr_ptr <= wr_ptr + 1; end end @@ -98,22 +100,11 @@ always @(posedge clk or posedge rst) begin if (rst) begin rd_ptr <= 0; end else if (read) begin - data_out_reg <= mem[rd_ptr]; + data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; rd_ptr <= rd_ptr + 1; end end -// counter -always @(posedge clk or posedge rst) begin - if (rst) begin - counter <= 0; - end else if (~read & write) begin - counter <= counter + 1; - end else if (read & ~write) begin - counter <= counter - 1; - end -end - // source ready output always @(posedge clk or posedge rst) begin if (rst) begin diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v index 8d02f5c0d..0accac316 100644 --- a/rtl/axis_fifo_64.v +++ b/rtl/axis_fifo_64.v @@ -60,9 +60,8 @@ module axis_fifo_64 # output wire output_axis_tuser ); -reg [ADDR_WIDTH-1:0] wr_ptr = {ADDR_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] rd_ptr = {ADDR_WIDTH{1'b0}}; -reg [ADDR_WIDTH-1:0] counter = {ADDR_WIDTH{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; @@ -75,8 +74,11 @@ reg output_axis_tvalid_reg = 1'b0; wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; -wire full = (counter == (2**ADDR_WIDTH)-1); -wire empty = (counter == 0); +// full when first MSB different but rest same +wire full = ((wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && + (wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0])); +// empty when pointers match exactly +wire empty = wr_ptr == rd_ptr; wire write = input_axis_tvalid & ~full; wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; @@ -91,7 +93,7 @@ always @(posedge clk or posedge rst) begin if (rst) begin wr_ptr <= 0; end else if (write) begin - mem[wr_ptr] <= data_in; + mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; wr_ptr <= wr_ptr + 1; end end @@ -101,22 +103,11 @@ always @(posedge clk or posedge rst) begin if (rst) begin rd_ptr <= 0; end else if (read) begin - data_out_reg <= mem[rd_ptr]; + data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; rd_ptr <= rd_ptr + 1; end end -// counter -always @(posedge clk or posedge rst) begin - if (rst) begin - counter <= 0; - end else if (~read & write) begin - counter <= counter + 1; - end else if (read & ~write) begin - counter <= counter - 1; - end -end - // source ready output always @(posedge clk or posedge rst) begin if (rst) begin From 6fa46b6c57f19dacf5e856d5e147b816a7aebcd0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 8 Nov 2014 21:07:47 -0800 Subject: [PATCH 078/617] Add AXI frame fifo and testbench --- rtl/axis_frame_fifo.v | 138 ++++++++++++ rtl/axis_frame_fifo_64.v | 141 ++++++++++++ tb/test_axis_frame_fifo.py | 401 ++++++++++++++++++++++++++++++++ tb/test_axis_frame_fifo.v | 88 ++++++++ tb/test_axis_frame_fifo_64.py | 414 ++++++++++++++++++++++++++++++++++ tb/test_axis_frame_fifo_64.v | 94 ++++++++ 6 files changed, 1276 insertions(+) create mode 100644 rtl/axis_frame_fifo.v create mode 100644 rtl/axis_frame_fifo_64.v create mode 100755 tb/test_axis_frame_fifo.py create mode 100644 tb/test_axis_frame_fifo.v create mode 100755 tb/test_axis_frame_fifo_64.py create mode 100644 tb/test_axis_frame_fifo_64.v diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v new file mode 100644 index 000000000..d037adfe4 --- /dev/null +++ b/rtl/axis_frame_fifo.v @@ -0,0 +1,138 @@ +/* + +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 frame FIFO + */ +module axis_frame_fifo # +( + parameter ADDR_WIDTH = 12, + parameter DATA_WIDTH = 8 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] input_axis_tdata, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast +); + +reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; + +reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; + +//(* RAM_STYLE="BLOCK" *) +reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; + +reg output_read = 1'b0; + +reg output_axis_tvalid_reg = 1'b0; + +wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tdata}; + +// full when first MSB different but rest same +wire full = ((wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && + (wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0])); +// empty when pointers match exactly +wire empty = wr_ptr == rd_ptr; +// overflow in single packet +wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && + (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); + +wire write = input_axis_tvalid & ~full; +wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; + +assign {output_axis_tlast, output_axis_tdata} = data_out_reg; + +assign input_axis_tready = ~full; +assign output_axis_tvalid = output_axis_tvalid_reg; + +// write +always @(posedge clk or posedge rst) begin + if (rst) begin + wr_ptr <= 0; + end else if (write) begin + if (full_cur) begin + // buffer full, hold current pointer, drop packet at end + if (input_axis_tlast) begin + wr_ptr_cur <= wr_ptr; + end + end else begin + mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; + wr_ptr_cur <= wr_ptr_cur + 1; + if (input_axis_tlast) begin + if (input_axis_tuser) begin + // bad packet, reset write pointer + wr_ptr_cur <= wr_ptr; + end else begin + // good packet, push new write pointer + wr_ptr <= wr_ptr_cur + 1; + end + end + end + end +end + +// read +always @(posedge clk or posedge rst) begin + if (rst) begin + rd_ptr <= 0; + end else if (read) begin + data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; + rd_ptr <= rd_ptr + 1; + end +end + +// source ready output +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + end else if (output_axis_tready | ~output_axis_tvalid_reg) begin + output_axis_tvalid_reg <= ~empty; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_reg; + end +end + +endmodule diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v new file mode 100644 index 000000000..f55dcf01a --- /dev/null +++ b/rtl/axis_frame_fifo_64.v @@ -0,0 +1,141 @@ +/* + +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 frame FIFO (64 bit datapath) + */ +module axis_frame_fifo_64 # +( + parameter ADDR_WIDTH = 12, + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] input_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_axis_tkeep, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast +); + +reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; + +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; + +//(* RAM_STYLE="BLOCK" *) +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; + +reg output_read = 1'b0; + +reg output_axis_tvalid_reg = 1'b0; + +wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; + +// full when first MSB different but rest same +wire full = ((wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && + (wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0])); +// empty when pointers match exactly +wire empty = wr_ptr == rd_ptr; +// overflow in single packet +wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && + (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); + +wire write = input_axis_tvalid & ~full; +wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; + +assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; + +assign input_axis_tready = ~full; +assign output_axis_tvalid = output_axis_tvalid_reg; + +// write +always @(posedge clk or posedge rst) begin + if (rst) begin + wr_ptr <= 0; + end else if (write) begin + if (full_cur) begin + // buffer full, hold current pointer, drop packet at end + if (input_axis_tlast) begin + wr_ptr_cur <= wr_ptr; + end + end else begin + mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; + wr_ptr_cur <= wr_ptr_cur + 1; + if (input_axis_tlast) begin + if (input_axis_tuser) begin + // bad packet, reset write pointer + wr_ptr_cur <= wr_ptr; + end else begin + // good packet, push new write pointer + wr_ptr <= wr_ptr_cur + 1; + end + end + end + end +end + +// read +always @(posedge clk or posedge rst) begin + if (rst) begin + rd_ptr <= 0; + end else if (read) begin + data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; + rd_ptr <= rd_ptr + 1; + end +end + +// source ready output +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + end else if (output_axis_tready | ~output_axis_tvalid_reg) begin + output_axis_tvalid_reg <= ~empty; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_reg; + end +end + +endmodule diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py new file mode 100755 index 000000000..76a28dd08 --- /dev/null +++ b/tb/test_axis_frame_fifo.py @@ -0,0 +1,401 @@ +#!/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_frame_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_frame_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): + + 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) + +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)) + + # 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, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_frame_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) + + @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 delay(1000) + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 8: single packet overflow") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + + bytearray(range(256))*2) + source_queue.put(test_frame) + yield clk.posedge + + yield delay(10000) + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v new file mode 100644 index 000000000..69ae48514 --- /dev/null +++ b/tb/test_axis_frame_fifo.v @@ -0,0 +1,88 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_frame_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; + +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); + + // dump file + $dumpfile("test_axis_frame_fifo.lxt"); + $dumpvars(0, test_axis_frame_fifo); +end + +axis_frame_fifo #( + .ADDR_WIDTH(9), + .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) +); + +endmodule diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py new file mode 100755 index 000000000..ce6f47cda --- /dev/null +++ b/tb/test_axis_frame_fifo_64.py @@ -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_frame_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_frame_fifo_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_axis_tdata=input_axis_tdata, + input_axis_tkeep=input_axis_tkeep, + input_axis_tvalid=input_axis_tvalid, + input_axis_tready=input_axis_tready, + input_axis_tlast=input_axis_tlast, + input_axis_tuser=input_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[64:]) + input_axis_tkeep = Signal(intbv(0)[8:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[64:]) + output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_axis_tdata, + tkeep=input_axis_tkeep, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_frame_fifo_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame('\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 delay(1000) + + assert sink_queue.empty() + + yield clk.posedge + print("test 8: single packet overflow") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + + bytearray(range(256))*2) + source_queue.put(test_frame) + yield clk.posedge + + yield delay(10000) + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v new file mode 100644 index 000000000..c7048e3fd --- /dev/null +++ b/tb/test_axis_frame_fifo_64.v @@ -0,0 +1,94 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_frame_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; + +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); + + // dump file + $dumpfile("test_axis_frame_fifo_64.lxt"); + $dumpvars(0, test_axis_frame_fifo_64); +end + +axis_frame_fifo_64 #( + .ADDR_WIDTH(6), + .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) +); + +endmodule From 10e0d7d1bb0d6d8bc631f3817b7934b7cfa61fb9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 8 Nov 2014 21:29:39 -0800 Subject: [PATCH 079/617] Add AXI async frame fifo and testbench --- rtl/axis_async_frame_fifo.v | 168 +++++++++++ rtl/axis_async_frame_fifo_64.v | 171 +++++++++++ tb/test_axis_async_frame_fifo.py | 421 +++++++++++++++++++++++++++ tb/test_axis_async_frame_fifo.v | 94 ++++++ tb/test_axis_async_frame_fifo_64.py | 431 ++++++++++++++++++++++++++++ tb/test_axis_async_frame_fifo_64.v | 100 +++++++ 6 files changed, 1385 insertions(+) create mode 100644 rtl/axis_async_frame_fifo.v create mode 100644 rtl/axis_async_frame_fifo_64.v create mode 100755 tb/test_axis_async_frame_fifo.py create mode 100644 tb/test_axis_async_frame_fifo.v create mode 100755 tb/test_axis_async_frame_fifo_64.py create mode 100644 tb/test_axis_async_frame_fifo_64.v diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v new file mode 100644 index 000000000..16f2e17bc --- /dev/null +++ b/rtl/axis_async_frame_fifo.v @@ -0,0 +1,168 @@ +/* + +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 asynchronous FIFO + */ +module axis_async_frame_fifo # +( + parameter ADDR_WIDTH = 12, + parameter DATA_WIDTH = 8 +) +( + /* + * AXI input + */ + input wire input_clk, + input wire input_rst, + 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 + */ + input wire output_clk, + input wire output_rst, + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast +); + +reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; + +reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; + +reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; + +//(* RAM_STYLE="BLOCK" *) +reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; + +reg output_read = 1'b0; + +reg output_axis_tvalid_reg = 1'b0; + +wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tdata}; + +// full when first TWO MSBs do NOT match, but rest matches +// (gray code equivalent of first MSB different but rest same) +wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync3[ADDR_WIDTH]) && + (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync3[ADDR_WIDTH-1]) && + (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync3[ADDR_WIDTH-2:0])); +// empty when pointers match exactly +wire empty = rd_ptr_gray == wr_ptr_gray_sync3; +// overflow in single packet +wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && + (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); + +wire write = input_axis_tvalid & ~full; +wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; + +assign {output_axis_tlast, output_axis_tdata} = data_out_reg; + +assign input_axis_tready = ~full; +assign output_axis_tvalid = output_axis_tvalid_reg; + +// write +always @(posedge input_clk or posedge input_rst) begin + if (input_rst) begin + wr_ptr <= 0; + end else if (write) begin + if (full_cur) begin + // buffer full, hold current pointer, drop packet at end + if (input_axis_tlast) begin + wr_ptr_cur <= wr_ptr; + end + end else begin + mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; + wr_ptr_cur <= wr_ptr_cur + 1; + if (input_axis_tlast) begin + if (input_axis_tuser) begin + // bad packet, reset write pointer + wr_ptr_cur <= wr_ptr; + end else begin + // good packet, push new write pointer + wr_ptr_next = wr_ptr_cur + 1; + wr_ptr <= wr_ptr_next; + wr_ptr_gray <= wr_ptr_next ^ (wr_ptr_next >> 1); + end + end + end + end +end + +// pointer synchronization in SRL16 +always @(posedge input_clk) begin + rd_ptr_gray_sync1 <= rd_ptr_gray; + rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + rd_ptr_gray_sync3 <= rd_ptr_gray_sync2; +end + +// read +always @(posedge output_clk or posedge output_rst) begin + if (output_rst) begin + rd_ptr <= 0; + end else if (read) begin + data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; + rd_ptr_next = rd_ptr + 1; + rd_ptr <= rd_ptr_next; + rd_ptr_gray <= rd_ptr_next ^ (rd_ptr_next >> 1); + end +end + +// pointer synchronization in SRL16 +always @(posedge output_clk) begin + wr_ptr_gray_sync1 <= wr_ptr_gray; + wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; + wr_ptr_gray_sync3 <= wr_ptr_gray_sync2; +end + +// source ready output +always @(posedge output_clk or posedge output_rst) begin + if (output_rst) begin + output_axis_tvalid_reg <= 1'b0; + end else if (output_axis_tready | ~output_axis_tvalid_reg) begin + output_axis_tvalid_reg <= ~empty; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_reg; + end +end + +endmodule diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v new file mode 100644 index 000000000..3da51f5ef --- /dev/null +++ b/rtl/axis_async_frame_fifo_64.v @@ -0,0 +1,171 @@ +/* + +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 asynchronous FIFO (64 bit datapath) + */ +module axis_async_frame_fifo_64 # +( + parameter ADDR_WIDTH = 12, + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + /* + * AXI input + */ + input wire input_clk, + input wire input_rst, + 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 + */ + input wire output_clk, + input wire output_rst, + 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 +); + +reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; + +reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; + +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; + +//(* RAM_STYLE="BLOCK" *) +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; + +reg output_read = 1'b0; + +reg output_axis_tvalid_reg = 1'b0; + +wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; + +// full when first TWO MSBs do NOT match, but rest matches +// (gray code equivalent of first MSB different but rest same) +wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync3[ADDR_WIDTH]) && + (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync3[ADDR_WIDTH-1]) && + (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync3[ADDR_WIDTH-2:0])); +// empty when pointers match exactly +wire empty = rd_ptr_gray == wr_ptr_gray_sync3; +// overflow in single packet +wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && + (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); + +wire write = input_axis_tvalid & ~full; +wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; + +assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; + +assign input_axis_tready = ~full; +assign output_axis_tvalid = output_axis_tvalid_reg; + +// write +always @(posedge input_clk or posedge input_rst) begin + if (input_rst) begin + wr_ptr <= 0; + end else if (write) begin + if (full_cur) begin + // buffer full, hold current pointer, drop packet at end + if (input_axis_tlast) begin + wr_ptr_cur <= wr_ptr; + end + end else begin + mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; + wr_ptr_cur <= wr_ptr_cur + 1; + if (input_axis_tlast) begin + if (input_axis_tuser) begin + // bad packet, reset write pointer + wr_ptr_cur <= wr_ptr; + end else begin + // good packet, push new write pointer + wr_ptr_next = wr_ptr_cur + 1; + wr_ptr <= wr_ptr_next; + wr_ptr_gray <= wr_ptr_next ^ (wr_ptr_next >> 1); + end + end + end + end +end + +// pointer synchronization in SRL16 +always @(posedge input_clk) begin + rd_ptr_gray_sync1 <= rd_ptr_gray; + rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + rd_ptr_gray_sync3 <= rd_ptr_gray_sync2; +end + +// read +always @(posedge output_clk or posedge output_rst) begin + if (output_rst) begin + rd_ptr <= 0; + end else if (read) begin + data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; + rd_ptr_next = rd_ptr + 1; + rd_ptr <= rd_ptr_next; + rd_ptr_gray <= rd_ptr_next ^ (rd_ptr_next >> 1); + end +end + +// pointer synchronization in SRL16 +always @(posedge output_clk) begin + wr_ptr_gray_sync1 <= wr_ptr_gray; + wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; + wr_ptr_gray_sync3 <= wr_ptr_gray_sync2; +end + +// source ready output +always @(posedge output_clk or posedge output_rst) begin + if (output_rst) begin + output_axis_tvalid_reg <= 1'b0; + end else if (output_axis_tready | ~output_axis_tvalid_reg) begin + output_axis_tvalid_reg <= ~empty; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_reg; + end +end + +endmodule diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py new file mode 100755 index 000000000..e7bd55da5 --- /dev/null +++ b/tb/test_axis_async_frame_fifo.py @@ -0,0 +1,421 @@ +#!/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_async_frame_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_async_frame_fifo(input_clk, + input_rst, + output_clk, + output_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): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + input_clk=input_clk, + input_rst=input_rst, + output_clk=output_clk, + output_rst=output_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) + +def bench(): + + # Inputs + input_clk = Signal(bool(0)) + input_rst = Signal(bool(0)) + output_clk = Signal(bool(0)) + output_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)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(input_clk, + input_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(output_clk, + output_rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_async_frame_fifo(input_clk, + input_rst, + output_clk, + output_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) + + @always(delay(4)) + def input_clkgen(): + input_clk.next = not input_clk + + @always(delay(5)) + def output_clkgen(): + output_clk.next = not output_clk + + @instance + def check(): + yield delay(100) + yield input_clk.posedge + input_rst.next = 1 + output_rst.next = 1 + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + input_rst.next = 0 + output_rst.next = 0 + yield input_clk.posedge + yield delay(100) + yield input_clk.posedge + + yield input_clk.posedge + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield input_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 input_clk.posedge + + yield delay(64) + yield input_clk.posedge + source_pause.next = True + yield delay(32) + yield input_clk.posedge + source_pause.next = False + + yield delay(64) + yield output_clk.posedge + sink_pause.next = True + yield delay(32) + yield output_clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + source_pause.next = False + yield input_clk.posedge + + yield output_clk.posedge + yield output_clk.posedge + if output_axis_tvalid: + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + sink_pause.next = False + yield output_clk.posedge + + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + yield delay(1000) + + assert sink_queue.empty() + + yield delay(100) + + yield input_clk.posedge + print("test 8: single packet overflow") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + + bytearray(range(256))*2) + source_queue.put(test_frame) + yield input_clk.posedge + + yield delay(10000) + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, input_clkgen, output_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() + diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v new file mode 100644 index 000000000..916b87354 --- /dev/null +++ b/tb/test_axis_async_frame_fifo.v @@ -0,0 +1,94 @@ +/* + +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_async_frame_fifo; + +// Inputs +reg input_clk = 0; +reg input_rst = 0; +reg output_clk = 0; +reg output_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; + +initial begin + // myhdl integration + $from_myhdl(input_clk, + input_rst, + output_clk, + output_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); + + // dump file + $dumpfile("test_axis_async_frame_fifo.lxt"); + $dumpvars(0, test_axis_async_frame_fifo); +end + +axis_async_frame_fifo #( + .ADDR_WIDTH(9), + .DATA_WIDTH(8) +) +UUT ( + // AXI input + .input_clk(input_clk), + .input_rst(input_rst), + .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_clk(output_clk), + .output_rst(output_rst), + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast) +); + +endmodule diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py new file mode 100755 index 000000000..f12906653 --- /dev/null +++ b/tb/test_axis_async_frame_fifo_64.py @@ -0,0 +1,431 @@ +#!/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_async_frame_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_async_frame_fifo_64(input_clk, + input_rst, + output_clk, + output_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): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + input_clk=input_clk, + input_rst=input_rst, + output_clk=output_clk, + output_rst=output_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) + +def bench(): + + # Inputs + input_clk = Signal(bool(0)) + input_rst = Signal(bool(0)) + output_clk = Signal(bool(0)) + output_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)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource(input_clk, + input_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(output_clk, + output_rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_axis_async_frame_fifo_64(input_clk, + input_rst, + output_clk, + output_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) + + @always(delay(4)) + def input_clkgen(): + input_clk.next = not input_clk + + @always(delay(5)) + def output_clkgen(): + output_clk.next = not output_clk + + @instance + def check(): + yield delay(100) + yield input_clk.posedge + input_rst.next = 1 + output_rst.next = 1 + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + input_rst.next = 0 + output_rst.next = 0 + yield input_clk.posedge + yield delay(100) + yield input_clk.posedge + + yield input_clk.posedge + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield input_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 input_clk.posedge + + yield delay(64) + yield input_clk.posedge + source_pause.next = True + yield delay(32) + yield input_clk.posedge + source_pause.next = False + + yield delay(64) + yield output_clk.posedge + sink_pause.next = True + yield delay(32) + yield output_clk.posedge + sink_pause.next = False + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_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 input_clk.posedge + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + source_pause.next = False + yield input_clk.posedge + + yield output_clk.posedge + yield output_clk.posedge + if output_axis_tvalid: + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + sink_pause.next = False + yield output_clk.posedge + + yield output_clk.posedge + yield output_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 input_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 input_clk.posedge + + yield delay(1000) + + assert sink_queue.empty() + + yield delay(100) + + yield input_clk.posedge + print("test 8: single packet overflow") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x51\x52\x53\x54\x55' + + '\x80\x00' + + bytearray(range(256))*2) + source_queue.put(test_frame) + yield input_clk.posedge + + yield delay(10000) + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, input_clkgen, output_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() + diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v new file mode 100644 index 000000000..62e3ad7aa --- /dev/null +++ b/tb/test_axis_async_frame_fifo_64.v @@ -0,0 +1,100 @@ +/* + +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_async_frame_fifo_64; + +// Inputs +reg input_clk = 0; +reg input_rst = 0; +reg output_clk = 0; +reg output_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; + +initial begin + // myhdl integration + $from_myhdl(input_clk, + input_rst, + output_clk, + output_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); + + // dump file + $dumpfile("test_axis_async_frame_fifo_64.lxt"); + $dumpvars(0, test_axis_async_frame_fifo_64); +end + +axis_async_frame_fifo_64 #( + .ADDR_WIDTH(6), + .DATA_WIDTH(64) +) +UUT ( + // AXI input + .input_clk(input_clk), + .input_rst(input_rst), + .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_clk(output_clk), + .output_rst(output_rst), + .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) +); + +endmodule From 7804272b2e36a07a9ef31dd6adfa23a5435fdf2b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 9 Nov 2014 02:13:20 -0800 Subject: [PATCH 080/617] Updated readme --- README | 3 +- README.md | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+), 2 deletions(-) mode change 100644 => 120000 README create mode 100644 README.md diff --git a/README b/README deleted file mode 100644 index 34d1f782c..000000000 --- a/README +++ /dev/null @@ -1,2 +0,0 @@ -Verilog AXI Stream components - diff --git a/README b/README new file mode 120000 index 000000000..42061c01a --- /dev/null +++ b/README @@ -0,0 +1 @@ +README.md \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..60300ac79 --- /dev/null +++ b/README.md @@ -0,0 +1,205 @@ +# Verilog AXI Stream Components Readme + +For more information and updates: http://alexforencich.com/wiki/en/verilog/axis/start + +GitHub repository: https://github.com/alexforencich/verilog-axis + +## Introduction + +Collection of AXI Stream bus components. Most components are fully +parametrizable in interface widths. Includes full MyHDL testbench with +intelligent bus cosimulation endpoints. + +## Documentation + +### axis_adapter module + +The axis_adapter module bridges AXI stream busses of differing widths. The +module is parametrizable, but there are certain restrictions. First, the bus +word widths must be identical (e.g. one 8-bit lane and eight 8-bit lanes, but +not one 16-bit lane and one 32-bit lane). Second, the bus widths must be +related by an integer multiple (e.g. 2 words and 6 words, but not 4 words +and 6 words). Wait states will be inserted on the wider bus side when +necessary. + +### axis_async_fifo module + +Basic word-based asynchronous FIFO with parametrizable data width and depth. +Supports power of two depths only. + +### axis_async_fifo_64 module + +Basic word-based asynchronous FIFO with tkeep signal and parametrizable data +width and depth. Supports power of two depths only. + +### axis_async_frame_fifo module + +Basic frame-based asynchronous FIFO with parametrizable data width and depth. +Supports power of two depths only. + +### axis_async_fifo_64 module + +Basic frame-based asynchronous FIFO with tkeep signal and parametrizable data +width and depth. Supports power of two depths only. + +### axis_fifo module + +Basic word-based synchronous FIFO with parametrizable data width and depth. +Supports power of two depths only. + +### axis_fifo_64 module + +Basic word-based synchronous FIFO with tkeep signal and parametrizable data +width and depth. Supports power of two depths only. + +### axis_frame_fifo module + +Basic frame-based synchronous FIFO with parametrizable data width and depth. +Supports power of two depths only. + +### axis_fifo_64 module + +Basic frame-based synchronous FIFO with tkeep signal and parametrizable data +width and depth. Supports power of two depths only. + +### axis_frame_join_N module + +Frame joiner with optional tag. 8 bit data path only. + +Can be generated with arbitrary port counts with axis_frame_join.py. + +### axis_ll_bringe module + +AXI stream to LocalLink bridge. + +### axis_rate_limit module + +Fractional rate limiter, supports word and frame modes. Inserts wait states +to limit data rate to specified ratio. Frame mode inserts wait states at end +of frames, word mode ignores frames and inserts wait states at any point. +Parametrizable data width. Rate and mode are configurable at run time. + +### axis_rate_limit_64 module + +Fractional rate limiter with tkeep signal, supports word and frame modes. +Inserts wait states to limit data rate to specified ratio. Frame mode inserts +wait states at end of frames, word mode ignores frames and inserts wait states +at any point. Parametrizable data width. Rate and mode are configurable at +run time. + +### axis_register module + +Datapath register. Use to improve timing for long routes. + +### axis_register_64 module + +Datapath register with tkeep signal. Use to improve timing for long routes. + +### axis_stat_counter module + +Statistics counter module. Counts bytes and frames passing through monitored +AXI stream interface. Trigger signal used to reset and dump counts out of AXI +interface, along with tag value. Use with axis_frame_join_N to form a single +monolithic frame from multiple monitored points with the same trigger. + +### ll_axis_bridge module + +LocalLink to AXI stream bridge. + +### Common signals + + tdata : Data (width generally DATA_WIDTH) + tkeep : Data word valid (width generally KEEP_WIDTH, present on _64 modules) + tvalid : Data valid + tready : Sink ready + tlast : End-of-frame + tuser : Bad frame (valid with tlast & tvalid) + +### Source Files + + rtl/axis_adapter.v : Parametrizable bus width adapter + rtl/axis_async_fifo.v : Asynchronous FIFO + rtl/axis_async_fifo_64.v : Asynchronous FIFO (64 bit) + rtl/axis_async_frame_fifo.v : Asynchronous frame FIFO + rtl/axis_async_frame_fifo_64.v : Asynchronous frame FIFO (64 bit) + rtl/axis_fifo.v : Synchronous FIFO + rtl/axis_fifo_64.v : Synchronous FIFO (64 bit) + rtl/axis_frame_fifo.v : Synchronous frame FIFO + rtl/axis_frame_fifo_64.v : Synchronous frame FIFO (64 bit) + rtl/axis_frame_join.py : Frame joiner generator + rtl/axis_frame_join_4.v : 4 port frame joiner + rtl/axis_ll_bridge.v : AXI stream to LocalLink bridge + rtl/axis_rate_limit.v : Fractional rate limiter + rtl/axis_rate_limit_64.v : Fractional rate limiter (64 bit) + rtl/axis_register.v : AXI Stream register + rtl/axis_register_64.v : AXI Stream register (64 bit) + rtl/axis_stat_counter.v : Statistics counter + rtl/ll_axis_bridge.v : LocalLink to AXI stream bridge + +### AXI Stream Interface Example + +two byte transfer with sink pause after each byte + + __ __ __ __ __ __ __ __ __ + clk __/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__ + _____ _________________ + tdata XXXXXXXXX_D0__X_D1______________XXXXXXXXXXXXXXXXXXXXXXXX + _____ _________________ + tkeep XXXXXXXXX_K0__X_K1______________XXXXXXXXXXXXXXXXXXXXXXXX + _______________________ + tvalid ________/ \_______________________ + ______________ _____ ___________ + tready \___________/ \___________/ + _________________ + tlast ______________/ \_______________________ + + tuser ________________________________________________________ + + +two back-to-back packets, no pauses + + __ __ __ __ __ __ __ __ __ + clk __/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__ + _____ _____ _____ _____ _____ _____ + tdata XXXXXXXXX_A0__X_A1__X_A2__X_B0__X_B1__X_B2__XXXXXXXXXXXX + _____ _____ _____ _____ _____ _____ + tkeep XXXXXXXXX_K0__X_K1__X_K2__X_K0__X_K1__X_K2__XXXXXXXXXXXX + ___________________________________ + tvalid ________/ \___________ + ________________________________________________________ + tready + _____ _____ + tlast ____________________/ \___________/ \___________ + + tuser ________________________________________________________ + + +bad frame + + __ __ __ __ __ __ + clk __/ \__/ \__/ \__/ \__/ \__/ \__ + _____ _____ _____ + tdata XXXXXXXXX_A0__X_A1__X_A2__XXXXXXXXXXXX + _____ _____ _____ + tkeep XXXXXXXXX_K0__X_K1__X_K2__XXXXXXXXXXXX + _________________ + tvalid ________/ \___________ + ______________________________________ + tready + _____ + tlast ____________________/ \___________ + _____ + tuser ____________________/ \___________ + + +## Testing + +Running the included testbenches requires MyHDL and Icarus Verilog. Make sure +that myhdl.vpi is installed properly for cosimulation to work correctly. The +testbenches can be run with a Python test runner like nose or py.test, or the +individual test scripts can be run with python directly. + +### Testbench Files + + tb/axis_ep.py : MyHDL AXI Stream endpoints + tb/ll_ep.py : MyHDL LocalLink endpoints From a28a534bff820037db4fd09d3be001072f18a5e2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 12 Nov 2014 01:54:31 -0800 Subject: [PATCH 081/617] Add AXI stream crosspoint module and testbench --- rtl/axis_crosspoint.py | 206 +++++++++++++ rtl/axis_crosspoint_4x4.v | 281 +++++++++++++++++ rtl/axis_crosspoint_64.py | 214 +++++++++++++ rtl/axis_crosspoint_64_4x4.v | 322 ++++++++++++++++++++ tb/test_axis_crosspoint_4x4.py | 448 +++++++++++++++++++++++++++ tb/test_axis_crosspoint_4x4.v | 146 +++++++++ tb/test_axis_crosspoint_64_4x4.py | 488 ++++++++++++++++++++++++++++++ tb/test_axis_crosspoint_64_4x4.v | 170 +++++++++++ 8 files changed, 2275 insertions(+) create mode 100755 rtl/axis_crosspoint.py create mode 100644 rtl/axis_crosspoint_4x4.v create mode 100755 rtl/axis_crosspoint_64.py create mode 100644 rtl/axis_crosspoint_64_4x4.v create mode 100755 tb/test_axis_crosspoint_4x4.py create mode 100644 tb/test_axis_crosspoint_4x4.v create mode 100755 tb/test_axis_crosspoint_64_4x4.py create mode 100644 tb/test_axis_crosspoint_64_4x4.v diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py new file mode 100755 index 000000000..dc8f24149 --- /dev/null +++ b/rtl/axis_crosspoint.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +"""axis_crosspoint + +Generates an AXI Stream crosspoint switch with a specific number of ports + +Usage: axis_crosspoint [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "axis_crosspoint_{0}x{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream crosspoint {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}}x{{n}} crosspoint + */ +module {{name}} # +( + parameter DATA_WIDTH = 8 +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ + {%- for p in ports %} + input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire input_{{p}}_axis_tvalid, + input wire input_{{p}}_axis_tlast, + {% endfor %} + /* + * AXI Stream outputs + */ + {%- for p in ports %} + output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, + output wire output_{{p}}_axis_tvalid, + output wire output_{{p}}_axis_tlast, + {% endfor %} + /* + * Control + */ + {%- for p in ports %} + input wire [{{w-1}}:0] output_{{p}}_select{% if not loop.last %},{% endif %} + {%- endfor %} +); +{% for p in ports %} +reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = 0; +reg input_{{p}}_axis_tvalid_reg = 0; +reg input_{{p}}_axis_tlast_reg = 0; +{% endfor %} + +{%- for p in ports %} +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = 0; +reg output_{{p}}_axis_tvalid_reg = 0; +reg output_{{p}}_axis_tlast_reg = 0; +{% endfor %} + +{%- for p in ports %} +reg [{{w-1}}:0] output_{{p}}_select_reg = 0; +{%- endfor %} +{% for p in ports %} +assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; +assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; +assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; +{% endfor %} + +always @(posedge clk or posedge rst) begin + if (rst) begin + {%- for p in ports %} + output_{{p}}_select_reg <= 0; + {%- endfor %} + {% for p in ports %} + input_{{p}}_axis_tvalid_reg <= 0; + input_{{p}}_axis_tlast_reg <= 0; + {%- endfor %} + {% for p in ports %} + output_{{p}}_axis_tvalid_reg <= 0; + output_{{p}}_axis_tlast_reg <= 0; + {%- endfor %} + end else begin + {%- for p in ports %} + input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; + input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; + input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; + {% endfor %} + {%- for p in ports %} + output_{{p}}_select_reg <= output_{{p}}_select; + {%- endfor %} + {%- for p in ports %} + + case (output_{{p}}_select_reg) + {%- for q in ports %} + {{w}}'d{{q}}: begin + output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; + output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; + output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; + end + {%- endfor %} + endcase + {%- endfor %} + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/axis_crosspoint_4x4.v b/rtl/axis_crosspoint_4x4.v new file mode 100644 index 000000000..1734f49f3 --- /dev/null +++ b/rtl/axis_crosspoint_4x4.v @@ -0,0 +1,281 @@ +/* + +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 4x4 crosspoint + */ +module axis_crosspoint_4x4 # +( + parameter DATA_WIDTH = 8 +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ + input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire input_0_axis_tvalid, + input wire input_0_axis_tlast, + + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire input_1_axis_tvalid, + input wire input_1_axis_tlast, + + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire input_2_axis_tvalid, + input wire input_2_axis_tlast, + + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire input_3_axis_tvalid, + input wire input_3_axis_tlast, + + /* + * AXI Stream outputs + */ + output wire [DATA_WIDTH-1:0] output_0_axis_tdata, + output wire output_0_axis_tvalid, + output wire output_0_axis_tlast, + + output wire [DATA_WIDTH-1:0] output_1_axis_tdata, + output wire output_1_axis_tvalid, + output wire output_1_axis_tlast, + + output wire [DATA_WIDTH-1:0] output_2_axis_tdata, + output wire output_2_axis_tvalid, + output wire output_2_axis_tlast, + + output wire [DATA_WIDTH-1:0] output_3_axis_tdata, + output wire output_3_axis_tvalid, + output wire output_3_axis_tlast, + + /* + * Control + */ + input wire [1:0] output_0_select, + input wire [1:0] output_1_select, + input wire [1:0] output_2_select, + input wire [1:0] output_3_select +); + +reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = 0; +reg input_0_axis_tvalid_reg = 0; +reg input_0_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = 0; +reg input_1_axis_tvalid_reg = 0; +reg input_1_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = 0; +reg input_2_axis_tvalid_reg = 0; +reg input_2_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = 0; +reg input_3_axis_tvalid_reg = 0; +reg input_3_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = 0; +reg output_0_axis_tvalid_reg = 0; +reg output_0_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = 0; +reg output_1_axis_tvalid_reg = 0; +reg output_1_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = 0; +reg output_2_axis_tvalid_reg = 0; +reg output_2_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = 0; +reg output_3_axis_tvalid_reg = 0; +reg output_3_axis_tlast_reg = 0; + +reg [1:0] output_0_select_reg = 0; +reg [1:0] output_1_select_reg = 0; +reg [1:0] output_2_select_reg = 0; +reg [1:0] output_3_select_reg = 0; + +assign output_0_axis_tdata = output_0_axis_tdata_reg; +assign output_0_axis_tvalid = output_0_axis_tvalid_reg; +assign output_0_axis_tlast = output_0_axis_tlast_reg; + +assign output_1_axis_tdata = output_1_axis_tdata_reg; +assign output_1_axis_tvalid = output_1_axis_tvalid_reg; +assign output_1_axis_tlast = output_1_axis_tlast_reg; + +assign output_2_axis_tdata = output_2_axis_tdata_reg; +assign output_2_axis_tvalid = output_2_axis_tvalid_reg; +assign output_2_axis_tlast = output_2_axis_tlast_reg; + +assign output_3_axis_tdata = output_3_axis_tdata_reg; +assign output_3_axis_tvalid = output_3_axis_tvalid_reg; +assign output_3_axis_tlast = output_3_axis_tlast_reg; + + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_0_select_reg <= 0; + output_1_select_reg <= 0; + output_2_select_reg <= 0; + output_3_select_reg <= 0; + + input_0_axis_tvalid_reg <= 0; + input_0_axis_tlast_reg <= 0; + input_1_axis_tvalid_reg <= 0; + input_1_axis_tlast_reg <= 0; + input_2_axis_tvalid_reg <= 0; + input_2_axis_tlast_reg <= 0; + input_3_axis_tvalid_reg <= 0; + input_3_axis_tlast_reg <= 0; + + output_0_axis_tvalid_reg <= 0; + output_0_axis_tlast_reg <= 0; + output_1_axis_tvalid_reg <= 0; + output_1_axis_tlast_reg <= 0; + output_2_axis_tvalid_reg <= 0; + output_2_axis_tlast_reg <= 0; + output_3_axis_tvalid_reg <= 0; + output_3_axis_tlast_reg <= 0; + end else begin + input_0_axis_tdata_reg <= input_0_axis_tdata; + input_0_axis_tvalid_reg <= input_0_axis_tvalid; + input_0_axis_tlast_reg <= input_0_axis_tlast; + + input_1_axis_tdata_reg <= input_1_axis_tdata; + input_1_axis_tvalid_reg <= input_1_axis_tvalid; + input_1_axis_tlast_reg <= input_1_axis_tlast; + + input_2_axis_tdata_reg <= input_2_axis_tdata; + input_2_axis_tvalid_reg <= input_2_axis_tvalid; + input_2_axis_tlast_reg <= input_2_axis_tlast; + + input_3_axis_tdata_reg <= input_3_axis_tdata; + input_3_axis_tvalid_reg <= input_3_axis_tvalid; + input_3_axis_tlast_reg <= input_3_axis_tlast; + + output_0_select_reg <= output_0_select; + output_1_select_reg <= output_1_select; + output_2_select_reg <= output_2_select; + output_3_select_reg <= output_3_select; + + case (output_0_select_reg) + 2'd0: begin + output_0_axis_tdata_reg <= input_0_axis_tdata_reg; + output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; + output_0_axis_tlast_reg <= input_0_axis_tlast_reg; + end + 2'd1: begin + output_0_axis_tdata_reg <= input_1_axis_tdata_reg; + output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; + output_0_axis_tlast_reg <= input_1_axis_tlast_reg; + end + 2'd2: begin + output_0_axis_tdata_reg <= input_2_axis_tdata_reg; + output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; + output_0_axis_tlast_reg <= input_2_axis_tlast_reg; + end + 2'd3: begin + output_0_axis_tdata_reg <= input_3_axis_tdata_reg; + output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; + output_0_axis_tlast_reg <= input_3_axis_tlast_reg; + end + endcase + + case (output_1_select_reg) + 2'd0: begin + output_1_axis_tdata_reg <= input_0_axis_tdata_reg; + output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; + output_1_axis_tlast_reg <= input_0_axis_tlast_reg; + end + 2'd1: begin + output_1_axis_tdata_reg <= input_1_axis_tdata_reg; + output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; + output_1_axis_tlast_reg <= input_1_axis_tlast_reg; + end + 2'd2: begin + output_1_axis_tdata_reg <= input_2_axis_tdata_reg; + output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; + output_1_axis_tlast_reg <= input_2_axis_tlast_reg; + end + 2'd3: begin + output_1_axis_tdata_reg <= input_3_axis_tdata_reg; + output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; + output_1_axis_tlast_reg <= input_3_axis_tlast_reg; + end + endcase + + case (output_2_select_reg) + 2'd0: begin + output_2_axis_tdata_reg <= input_0_axis_tdata_reg; + output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; + output_2_axis_tlast_reg <= input_0_axis_tlast_reg; + end + 2'd1: begin + output_2_axis_tdata_reg <= input_1_axis_tdata_reg; + output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; + output_2_axis_tlast_reg <= input_1_axis_tlast_reg; + end + 2'd2: begin + output_2_axis_tdata_reg <= input_2_axis_tdata_reg; + output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; + output_2_axis_tlast_reg <= input_2_axis_tlast_reg; + end + 2'd3: begin + output_2_axis_tdata_reg <= input_3_axis_tdata_reg; + output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; + output_2_axis_tlast_reg <= input_3_axis_tlast_reg; + end + endcase + + case (output_3_select_reg) + 2'd0: begin + output_3_axis_tdata_reg <= input_0_axis_tdata_reg; + output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; + output_3_axis_tlast_reg <= input_0_axis_tlast_reg; + end + 2'd1: begin + output_3_axis_tdata_reg <= input_1_axis_tdata_reg; + output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; + output_3_axis_tlast_reg <= input_1_axis_tlast_reg; + end + 2'd2: begin + output_3_axis_tdata_reg <= input_2_axis_tdata_reg; + output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; + output_3_axis_tlast_reg <= input_2_axis_tlast_reg; + end + 2'd3: begin + output_3_axis_tdata_reg <= input_3_axis_tdata_reg; + output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; + output_3_axis_tlast_reg <= input_3_axis_tlast_reg; + end + endcase + end +end + +endmodule diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py new file mode 100755 index 000000000..dea44e2ea --- /dev/null +++ b/rtl/axis_crosspoint_64.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +"""axis_crosspoint_64_64 + +Generates an AXI Stream crosspoint switch with a specific number of ports + +Usage: axis_crosspoint_64 [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "axis_crosspoint_64_{0}x{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream crosspoint {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}}x{{n}} crosspoint (64 bit datapath) + */ +module {{name}} # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ + {%- for p in ports %} + input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, + input wire input_{{p}}_axis_tvalid, + input wire input_{{p}}_axis_tlast, + {% endfor %} + /* + * AXI Stream outputs + */ + {%- for p in ports %} + output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, + output wire output_{{p}}_axis_tvalid, + output wire output_{{p}}_axis_tlast, + {% endfor %} + /* + * Control + */ + {%- for p in ports %} + input wire [{{w-1}}:0] output_{{p}}_select{% if not loop.last %},{% endif %} + {%- endfor %} +); +{% for p in ports %} +reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep_reg = 0; +reg input_{{p}}_axis_tvalid_reg = 0; +reg input_{{p}}_axis_tlast_reg = 0; +{% endfor %} + +{%- for p in ports %} +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = 0; +reg output_{{p}}_axis_tvalid_reg = 0; +reg output_{{p}}_axis_tlast_reg = 0; +{% endfor %} + +{%- for p in ports %} +reg [{{w-1}}:0] output_{{p}}_select_reg = 0; +{%- endfor %} +{% for p in ports %} +assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; +assign output_{{p}}_axis_tkeep = output_{{p}}_axis_tkeep_reg; +assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; +assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; +{% endfor %} + +always @(posedge clk or posedge rst) begin + if (rst) begin + {%- for p in ports %} + output_{{p}}_select_reg <= 0; + {%- endfor %} + {% for p in ports %} + input_{{p}}_axis_tvalid_reg <= 0; + input_{{p}}_axis_tlast_reg <= 0; + {%- endfor %} + {% for p in ports %} + output_{{p}}_axis_tvalid_reg <= 0; + output_{{p}}_axis_tlast_reg <= 0; + {%- endfor %} + end else begin + {%- for p in ports %} + input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; + input_{{p}}_axis_tkeep_reg <= input_{{p}}_axis_tkeep; + input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; + input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; + {% endfor %} + {%- for p in ports %} + output_{{p}}_select_reg <= output_{{p}}_select; + {%- endfor %} + {%- for p in ports %} + + case (output_{{p}}_select_reg) + {%- for q in ports %} + {{w}}'d{{q}}: begin + output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; + output_{{p}}_axis_tkeep_reg <= input_{{q}}_axis_tkeep_reg; + output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; + output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; + end + {%- endfor %} + endcase + {%- endfor %} + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/axis_crosspoint_64_4x4.v b/rtl/axis_crosspoint_64_4x4.v new file mode 100644 index 000000000..25345c15d --- /dev/null +++ b/rtl/axis_crosspoint_64_4x4.v @@ -0,0 +1,322 @@ +/* + +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 4x4 crosspoint (64 bit datapath) + */ +module axis_crosspoint_64_4x4 # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ + input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, + input wire input_0_axis_tvalid, + input wire input_0_axis_tlast, + + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, + input wire input_1_axis_tvalid, + input wire input_1_axis_tlast, + + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, + input wire input_2_axis_tvalid, + input wire input_2_axis_tlast, + + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, + input wire input_3_axis_tvalid, + input wire input_3_axis_tlast, + + /* + * AXI Stream outputs + */ + output wire [DATA_WIDTH-1:0] output_0_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, + output wire output_0_axis_tvalid, + output wire output_0_axis_tlast, + + output wire [DATA_WIDTH-1:0] output_1_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, + output wire output_1_axis_tvalid, + output wire output_1_axis_tlast, + + output wire [DATA_WIDTH-1:0] output_2_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, + output wire output_2_axis_tvalid, + output wire output_2_axis_tlast, + + output wire [DATA_WIDTH-1:0] output_3_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, + output wire output_3_axis_tvalid, + output wire output_3_axis_tlast, + + /* + * Control + */ + input wire [1:0] output_0_select, + input wire [1:0] output_1_select, + input wire [1:0] output_2_select, + input wire [1:0] output_3_select +); + +reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep_reg = 0; +reg input_0_axis_tvalid_reg = 0; +reg input_0_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep_reg = 0; +reg input_1_axis_tvalid_reg = 0; +reg input_1_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep_reg = 0; +reg input_2_axis_tvalid_reg = 0; +reg input_2_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep_reg = 0; +reg input_3_axis_tvalid_reg = 0; +reg input_3_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = 0; +reg output_0_axis_tvalid_reg = 0; +reg output_0_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = 0; +reg output_1_axis_tvalid_reg = 0; +reg output_1_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = 0; +reg output_2_axis_tvalid_reg = 0; +reg output_2_axis_tlast_reg = 0; + +reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = 0; +reg output_3_axis_tvalid_reg = 0; +reg output_3_axis_tlast_reg = 0; + +reg [1:0] output_0_select_reg = 0; +reg [1:0] output_1_select_reg = 0; +reg [1:0] output_2_select_reg = 0; +reg [1:0] output_3_select_reg = 0; + +assign output_0_axis_tdata = output_0_axis_tdata_reg; +assign output_0_axis_tkeep = output_0_axis_tkeep_reg; +assign output_0_axis_tvalid = output_0_axis_tvalid_reg; +assign output_0_axis_tlast = output_0_axis_tlast_reg; + +assign output_1_axis_tdata = output_1_axis_tdata_reg; +assign output_1_axis_tkeep = output_1_axis_tkeep_reg; +assign output_1_axis_tvalid = output_1_axis_tvalid_reg; +assign output_1_axis_tlast = output_1_axis_tlast_reg; + +assign output_2_axis_tdata = output_2_axis_tdata_reg; +assign output_2_axis_tkeep = output_2_axis_tkeep_reg; +assign output_2_axis_tvalid = output_2_axis_tvalid_reg; +assign output_2_axis_tlast = output_2_axis_tlast_reg; + +assign output_3_axis_tdata = output_3_axis_tdata_reg; +assign output_3_axis_tkeep = output_3_axis_tkeep_reg; +assign output_3_axis_tvalid = output_3_axis_tvalid_reg; +assign output_3_axis_tlast = output_3_axis_tlast_reg; + + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_0_select_reg <= 0; + output_1_select_reg <= 0; + output_2_select_reg <= 0; + output_3_select_reg <= 0; + + input_0_axis_tvalid_reg <= 0; + input_0_axis_tlast_reg <= 0; + input_1_axis_tvalid_reg <= 0; + input_1_axis_tlast_reg <= 0; + input_2_axis_tvalid_reg <= 0; + input_2_axis_tlast_reg <= 0; + input_3_axis_tvalid_reg <= 0; + input_3_axis_tlast_reg <= 0; + + output_0_axis_tvalid_reg <= 0; + output_0_axis_tlast_reg <= 0; + output_1_axis_tvalid_reg <= 0; + output_1_axis_tlast_reg <= 0; + output_2_axis_tvalid_reg <= 0; + output_2_axis_tlast_reg <= 0; + output_3_axis_tvalid_reg <= 0; + output_3_axis_tlast_reg <= 0; + end else begin + input_0_axis_tdata_reg <= input_0_axis_tdata; + input_0_axis_tkeep_reg <= input_0_axis_tkeep; + input_0_axis_tvalid_reg <= input_0_axis_tvalid; + input_0_axis_tlast_reg <= input_0_axis_tlast; + + input_1_axis_tdata_reg <= input_1_axis_tdata; + input_1_axis_tkeep_reg <= input_1_axis_tkeep; + input_1_axis_tvalid_reg <= input_1_axis_tvalid; + input_1_axis_tlast_reg <= input_1_axis_tlast; + + input_2_axis_tdata_reg <= input_2_axis_tdata; + input_2_axis_tkeep_reg <= input_2_axis_tkeep; + input_2_axis_tvalid_reg <= input_2_axis_tvalid; + input_2_axis_tlast_reg <= input_2_axis_tlast; + + input_3_axis_tdata_reg <= input_3_axis_tdata; + input_3_axis_tkeep_reg <= input_3_axis_tkeep; + input_3_axis_tvalid_reg <= input_3_axis_tvalid; + input_3_axis_tlast_reg <= input_3_axis_tlast; + + output_0_select_reg <= output_0_select; + output_1_select_reg <= output_1_select; + output_2_select_reg <= output_2_select; + output_3_select_reg <= output_3_select; + + case (output_0_select_reg) + 2'd0: begin + output_0_axis_tdata_reg <= input_0_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; + output_0_axis_tlast_reg <= input_0_axis_tlast_reg; + end + 2'd1: begin + output_0_axis_tdata_reg <= input_1_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; + output_0_axis_tlast_reg <= input_1_axis_tlast_reg; + end + 2'd2: begin + output_0_axis_tdata_reg <= input_2_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; + output_0_axis_tlast_reg <= input_2_axis_tlast_reg; + end + 2'd3: begin + output_0_axis_tdata_reg <= input_3_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; + output_0_axis_tlast_reg <= input_3_axis_tlast_reg; + end + endcase + + case (output_1_select_reg) + 2'd0: begin + output_1_axis_tdata_reg <= input_0_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; + output_1_axis_tlast_reg <= input_0_axis_tlast_reg; + end + 2'd1: begin + output_1_axis_tdata_reg <= input_1_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; + output_1_axis_tlast_reg <= input_1_axis_tlast_reg; + end + 2'd2: begin + output_1_axis_tdata_reg <= input_2_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; + output_1_axis_tlast_reg <= input_2_axis_tlast_reg; + end + 2'd3: begin + output_1_axis_tdata_reg <= input_3_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; + output_1_axis_tlast_reg <= input_3_axis_tlast_reg; + end + endcase + + case (output_2_select_reg) + 2'd0: begin + output_2_axis_tdata_reg <= input_0_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; + output_2_axis_tlast_reg <= input_0_axis_tlast_reg; + end + 2'd1: begin + output_2_axis_tdata_reg <= input_1_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; + output_2_axis_tlast_reg <= input_1_axis_tlast_reg; + end + 2'd2: begin + output_2_axis_tdata_reg <= input_2_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; + output_2_axis_tlast_reg <= input_2_axis_tlast_reg; + end + 2'd3: begin + output_2_axis_tdata_reg <= input_3_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; + output_2_axis_tlast_reg <= input_3_axis_tlast_reg; + end + endcase + + case (output_3_select_reg) + 2'd0: begin + output_3_axis_tdata_reg <= input_0_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; + output_3_axis_tlast_reg <= input_0_axis_tlast_reg; + end + 2'd1: begin + output_3_axis_tdata_reg <= input_1_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; + output_3_axis_tlast_reg <= input_1_axis_tlast_reg; + end + 2'd2: begin + output_3_axis_tdata_reg <= input_2_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; + output_3_axis_tlast_reg <= input_2_axis_tlast_reg; + end + 2'd3: begin + output_3_axis_tdata_reg <= input_3_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; + output_3_axis_tlast_reg <= input_3_axis_tlast_reg; + end + endcase + end +end + +endmodule diff --git a/tb/test_axis_crosspoint_4x4.py b/tb/test_axis_crosspoint_4x4.py new file mode 100755 index 000000000..44803183e --- /dev/null +++ b/tb/test_axis_crosspoint_4x4.py @@ -0,0 +1,448 @@ +#!/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_crosspoint_4x4' + +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_crosspoint_4x4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tlast, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tlast, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tlast, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tlast, + + output_0_select, + output_1_select, + output_2_select, + output_3_select): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tlast=input_0_axis_tlast, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tlast=input_1_axis_tlast, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tlast=input_2_axis_tlast, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tlast=input_3_axis_tlast, + + output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tlast=output_0_axis_tlast, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tlast=output_1_axis_tlast, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tlast=output_2_axis_tlast, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tlast=output_3_axis_tlast, + + output_0_select=output_0_select, + output_1_select=output_1_select, + output_2_select=output_2_select, + output_3_select=output_3_select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_axis_tdata = Signal(intbv(0)[8:]) + input_0_axis_tvalid = Signal(bool(0)) + input_0_axis_tlast = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[8:]) + input_1_axis_tvalid = Signal(bool(0)) + input_1_axis_tlast = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[8:]) + input_2_axis_tvalid = Signal(bool(0)) + input_2_axis_tlast = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[8:]) + input_3_axis_tvalid = Signal(bool(0)) + input_3_axis_tlast = Signal(bool(0)) + + output_0_select = Signal(intbv(0)[2:]) + output_1_select = Signal(intbv(0)[2:]) + output_2_select = Signal(intbv(0)[2:]) + output_3_select = Signal(intbv(0)[2:]) + + # Outputs + output_0_axis_tdata = Signal(intbv(0)[8:]) + output_0_axis_tvalid = Signal(bool(0)) + output_0_axis_tlast = Signal(bool(0)) + output_1_axis_tdata = Signal(intbv(0)[8:]) + output_1_axis_tvalid = Signal(bool(0)) + output_1_axis_tlast = Signal(bool(0)) + output_2_axis_tdata = Signal(intbv(0)[8:]) + output_2_axis_tvalid = Signal(bool(0)) + output_2_axis_tlast = Signal(bool(0)) + output_3_axis_tdata = Signal(intbv(0)[8:]) + output_3_axis_tvalid = Signal(bool(0)) + output_3_axis_tlast = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_pause = Signal(bool(0)) + + source_0 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tlast=input_0_axis_tlast, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + source_1 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tlast=input_1_axis_tlast, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + source_2 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tlast=input_2_axis_tlast, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + source_3 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tlast=input_3_axis_tlast, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink_0 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_0_axis_tdata, + tvalid=output_0_axis_tvalid, + tlast=output_0_axis_tlast, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + sink_1 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_1_axis_tdata, + tvalid=output_1_axis_tvalid, + tlast=output_1_axis_tlast, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + sink_2 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_2_axis_tdata, + tvalid=output_2_axis_tvalid, + tlast=output_2_axis_tlast, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + sink_3 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_3_axis_tdata, + tvalid=output_3_axis_tvalid, + tlast=output_3_axis_tlast, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_axis_crosspoint_4x4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tlast, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tlast, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tlast, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tlast, + + output_0_select, + output_1_select, + output_2_select, + output_3_select) + + @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: 0123 -> 0123") + current_test.next = 1 + + output_0_select.next = 0 + output_1_select.next = 1 + output_2_select.next = 2 + output_3_select.next = 3 + + test_frame0 = axis_ep.AXIStreamFrame('\x01\x00\x00\xFF\x01\x02\x03\x04') + test_frame1 = axis_ep.AXIStreamFrame('\x01\x01\x01\xFF\x01\x02\x03\x04') + test_frame2 = axis_ep.AXIStreamFrame('\x01\x02\x02\xFF\x01\x02\x03\x04') + test_frame3 = axis_ep.AXIStreamFrame('\x01\x03\x03\xFF\x01\x02\x03\x04') + source_0_queue.put(test_frame0) + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame1 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame2 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame3 + + yield delay(100) + + yield clk.posedge + print("test 2: 0123 -> 3210") + current_test.next = 2 + + output_0_select.next = 3 + output_1_select.next = 2 + output_2_select.next = 1 + output_3_select.next = 0 + + test_frame0 = axis_ep.AXIStreamFrame('\x02\x00\x03\xFF\x01\x02\x03\x04') + test_frame1 = axis_ep.AXIStreamFrame('\x02\x01\x02\xFF\x01\x02\x03\x04') + test_frame2 = axis_ep.AXIStreamFrame('\x02\x02\x01\xFF\x01\x02\x03\x04') + test_frame3 = axis_ep.AXIStreamFrame('\x02\x03\x00\xFF\x01\x02\x03\x04') + source_0_queue.put(test_frame0) + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame3 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame2 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame1 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame0 + + yield delay(100) + + yield clk.posedge + print("test 3: 0000 -> 0123") + current_test.next = 3 + + output_0_select.next = 0 + output_1_select.next = 0 + output_2_select.next = 0 + output_3_select.next = 0 + + test_frame0 = axis_ep.AXIStreamFrame('\x03\x00\xFF\xFF\x01\x02\x03\x04') + source_0_queue.put(test_frame0) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame0 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame0 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame0 + + yield delay(100) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink_0, sink_1, sink_2, sink_3, 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() + diff --git a/tb/test_axis_crosspoint_4x4.v b/tb/test_axis_crosspoint_4x4.v new file mode 100644 index 000000000..5114ae959 --- /dev/null +++ b/tb/test_axis_crosspoint_4x4.v @@ -0,0 +1,146 @@ +/* + +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_crosspoint_4x4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_0_axis_tdata = 0; +reg input_0_axis_tvalid = 0; +reg input_0_axis_tlast = 0; +reg [7:0] input_1_axis_tdata = 0; +reg input_1_axis_tvalid = 0; +reg input_1_axis_tlast = 0; +reg [7:0] input_2_axis_tdata = 0; +reg input_2_axis_tvalid = 0; +reg input_2_axis_tlast = 0; +reg [7:0] input_3_axis_tdata = 0; +reg input_3_axis_tvalid = 0; +reg input_3_axis_tlast = 0; + +reg [1:0] output_0_select = 0; +reg [1:0] output_1_select = 0; +reg [1:0] output_2_select = 0; +reg [1:0] output_3_select = 0; + +// Outputs +wire [7:0] output_0_axis_tdata; +wire output_0_axis_tvalid; +wire output_0_axis_tlast; +wire [7:0] output_1_axis_tdata; +wire output_1_axis_tvalid; +wire output_1_axis_tlast; +wire [7:0] output_2_axis_tdata; +wire output_2_axis_tvalid; +wire output_2_axis_tlast; +wire [7:0] output_3_axis_tdata; +wire output_3_axis_tvalid; +wire output_3_axis_tlast; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + output_0_select, + output_1_select, + output_2_select, + output_3_select); + $to_myhdl(output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tlast, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tlast, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tlast, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tlast); + + // dump file + $dumpfile("test_axis_crosspoint_4x4.lxt"); + $dumpvars(0, test_axis_crosspoint_4x4); +end + +axis_crosspoint_4x4 #( + .DATA_WIDTH(8) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI inputs + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tvalid(input_0_axis_tvalid), + .input_0_axis_tlast(input_0_axis_tlast), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tvalid(input_1_axis_tvalid), + .input_1_axis_tlast(input_1_axis_tlast), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tvalid(input_2_axis_tvalid), + .input_2_axis_tlast(input_2_axis_tlast), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tvalid(input_3_axis_tvalid), + .input_3_axis_tlast(input_3_axis_tlast), + // AXI outputs + .output_0_axis_tdata(output_0_axis_tdata), + .output_0_axis_tvalid(output_0_axis_tvalid), + .output_0_axis_tlast(output_0_axis_tlast), + .output_1_axis_tdata(output_1_axis_tdata), + .output_1_axis_tvalid(output_1_axis_tvalid), + .output_1_axis_tlast(output_1_axis_tlast), + .output_2_axis_tdata(output_2_axis_tdata), + .output_2_axis_tvalid(output_2_axis_tvalid), + .output_2_axis_tlast(output_2_axis_tlast), + .output_3_axis_tdata(output_3_axis_tdata), + .output_3_axis_tvalid(output_3_axis_tvalid), + .output_3_axis_tlast(output_3_axis_tlast), + // Control + .output_0_select(output_0_select), + .output_1_select(output_1_select), + .output_2_select(output_2_select), + .output_3_select(output_3_select) +); + +endmodule diff --git a/tb/test_axis_crosspoint_64_4x4.py b/tb/test_axis_crosspoint_64_4x4.py new file mode 100755 index 000000000..ba91ecf6b --- /dev/null +++ b/tb/test_axis_crosspoint_64_4x4.py @@ -0,0 +1,488 @@ +#!/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_crosspoint_64_4x4' + +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_crosspoint_64_4x4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tlast, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tlast, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tlast, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tlast, + + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tlast, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tlast, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tlast, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tlast, + + output_0_select, + output_1_select, + output_2_select, + output_3_select): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tlast=input_0_axis_tlast, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tlast=input_1_axis_tlast, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tlast=input_2_axis_tlast, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tlast=input_3_axis_tlast, + + output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tkeep=output_0_axis_tkeep, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tlast=output_0_axis_tlast, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tkeep=output_1_axis_tkeep, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tlast=output_1_axis_tlast, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tkeep=output_2_axis_tkeep, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tlast=output_2_axis_tlast, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tkeep=output_3_axis_tkeep, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tlast=output_3_axis_tlast, + + output_0_select=output_0_select, + output_1_select=output_1_select, + output_2_select=output_2_select, + output_3_select=output_3_select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_axis_tdata = Signal(intbv(0)[64:]) + input_0_axis_tkeep = Signal(intbv(0)[8:]) + input_0_axis_tvalid = Signal(bool(0)) + input_0_axis_tlast = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[64:]) + input_1_axis_tkeep = Signal(intbv(0)[8:]) + input_1_axis_tvalid = Signal(bool(0)) + input_1_axis_tlast = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[64:]) + input_2_axis_tkeep = Signal(intbv(0)[8:]) + input_2_axis_tvalid = Signal(bool(0)) + input_2_axis_tlast = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[64:]) + input_3_axis_tkeep = Signal(intbv(0)[8:]) + input_3_axis_tvalid = Signal(bool(0)) + input_3_axis_tlast = Signal(bool(0)) + + output_0_select = Signal(intbv(0)[2:]) + output_1_select = Signal(intbv(0)[2:]) + output_2_select = Signal(intbv(0)[2:]) + output_3_select = Signal(intbv(0)[2:]) + + # Outputs + output_0_axis_tdata = Signal(intbv(0)[64:]) + output_0_axis_tkeep = Signal(intbv(0)[8:]) + output_0_axis_tvalid = Signal(bool(0)) + output_0_axis_tlast = Signal(bool(0)) + output_1_axis_tdata = Signal(intbv(0)[64:]) + output_1_axis_tkeep = Signal(intbv(0)[8:]) + output_1_axis_tvalid = Signal(bool(0)) + output_1_axis_tlast = Signal(bool(0)) + output_2_axis_tdata = Signal(intbv(0)[64:]) + output_2_axis_tkeep = Signal(intbv(0)[8:]) + output_2_axis_tvalid = Signal(bool(0)) + output_2_axis_tlast = Signal(bool(0)) + output_3_axis_tdata = Signal(intbv(0)[64:]) + output_3_axis_tkeep = Signal(intbv(0)[8:]) + output_3_axis_tvalid = Signal(bool(0)) + output_3_axis_tlast = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_pause = Signal(bool(0)) + + source_0 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, + tvalid=input_0_axis_tvalid, + tlast=input_0_axis_tlast, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + source_1 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, + tvalid=input_1_axis_tvalid, + tlast=input_1_axis_tlast, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + source_2 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, + tvalid=input_2_axis_tvalid, + tlast=input_2_axis_tlast, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + source_3 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, + tvalid=input_3_axis_tvalid, + tlast=input_3_axis_tlast, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink_0 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_0_axis_tdata, + tkeep=output_0_axis_tkeep, + tvalid=output_0_axis_tvalid, + tlast=output_0_axis_tlast, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + sink_1 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_1_axis_tdata, + tkeep=output_1_axis_tkeep, + tvalid=output_1_axis_tvalid, + tlast=output_1_axis_tlast, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + sink_2 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_2_axis_tdata, + tkeep=output_2_axis_tkeep, + tvalid=output_2_axis_tvalid, + tlast=output_2_axis_tlast, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + sink_3 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_3_axis_tdata, + tkeep=output_3_axis_tkeep, + tvalid=output_3_axis_tvalid, + tlast=output_3_axis_tlast, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_axis_crosspoint_64_4x4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tlast, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tlast, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tlast, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tlast, + + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tlast, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tlast, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tlast, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tlast, + + output_0_select, + output_1_select, + output_2_select, + output_3_select) + + @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: 0123 -> 0123") + current_test.next = 1 + + output_0_select.next = 0 + output_1_select.next = 1 + output_2_select.next = 2 + output_3_select.next = 3 + + test_frame0 = axis_ep.AXIStreamFrame('\x01\x00\x00\xFF\x01\x02\x03\x04') + test_frame1 = axis_ep.AXIStreamFrame('\x01\x01\x01\xFF\x01\x02\x03\x04') + test_frame2 = axis_ep.AXIStreamFrame('\x01\x02\x02\xFF\x01\x02\x03\x04') + test_frame3 = axis_ep.AXIStreamFrame('\x01\x03\x03\xFF\x01\x02\x03\x04') + source_0_queue.put(test_frame0) + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame1 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame2 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame3 + + yield delay(100) + + yield clk.posedge + print("test 2: 0123 -> 3210") + current_test.next = 2 + + output_0_select.next = 3 + output_1_select.next = 2 + output_2_select.next = 1 + output_3_select.next = 0 + + test_frame0 = axis_ep.AXIStreamFrame('\x02\x00\x03\xFF\x01\x02\x03\x04') + test_frame1 = axis_ep.AXIStreamFrame('\x02\x01\x02\xFF\x01\x02\x03\x04') + test_frame2 = axis_ep.AXIStreamFrame('\x02\x02\x01\xFF\x01\x02\x03\x04') + test_frame3 = axis_ep.AXIStreamFrame('\x02\x03\x00\xFF\x01\x02\x03\x04') + source_0_queue.put(test_frame0) + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame3 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame2 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame1 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame0 + + yield delay(100) + + yield clk.posedge + print("test 3: 0000 -> 0123") + current_test.next = 3 + + output_0_select.next = 0 + output_1_select.next = 0 + output_2_select.next = 0 + output_3_select.next = 0 + + test_frame0 = axis_ep.AXIStreamFrame('\x03\x00\xFF\xFF\x01\x02\x03\x04') + source_0_queue.put(test_frame0) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame0 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame0 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame0 + + yield delay(100) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink_0, sink_1, sink_2, sink_3, 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() + diff --git a/tb/test_axis_crosspoint_64_4x4.v b/tb/test_axis_crosspoint_64_4x4.v new file mode 100644 index 000000000..a302ceef8 --- /dev/null +++ b/tb/test_axis_crosspoint_64_4x4.v @@ -0,0 +1,170 @@ +/* + +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_crosspoint_64_4x4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] input_0_axis_tdata = 0; +reg [7:0] input_0_axis_tkeep = 0; +reg input_0_axis_tvalid = 0; +reg input_0_axis_tlast = 0; +reg [63:0] input_1_axis_tdata = 0; +reg [7:0] input_1_axis_tkeep = 0; +reg input_1_axis_tvalid = 0; +reg input_1_axis_tlast = 0; +reg [63:0] input_2_axis_tdata = 0; +reg [7:0] input_2_axis_tkeep = 0; +reg input_2_axis_tvalid = 0; +reg input_2_axis_tlast = 0; +reg [63:0] input_3_axis_tdata = 0; +reg [7:0] input_3_axis_tkeep = 0; +reg input_3_axis_tvalid = 0; +reg input_3_axis_tlast = 0; + +reg [1:0] output_0_select = 0; +reg [1:0] output_1_select = 0; +reg [1:0] output_2_select = 0; +reg [1:0] output_3_select = 0; + +// Outputs +wire [63:0] output_0_axis_tdata; +wire [7:0] output_0_axis_tkeep; +wire output_0_axis_tvalid; +wire output_0_axis_tlast; +wire [63:0] output_1_axis_tdata; +wire [7:0] output_1_axis_tkeep; +wire output_1_axis_tvalid; +wire output_1_axis_tlast; +wire [63:0] output_2_axis_tdata; +wire [7:0] output_2_axis_tkeep; +wire output_2_axis_tvalid; +wire output_2_axis_tlast; +wire [63:0] output_3_axis_tdata; +wire [7:0] output_3_axis_tkeep; +wire output_3_axis_tvalid; +wire output_3_axis_tlast; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tlast, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tlast, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tlast, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tlast, + output_0_select, + output_1_select, + output_2_select, + output_3_select); + $to_myhdl(output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tlast, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tlast, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tlast, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tlast); + + // dump file + $dumpfile("test_axis_crosspoint_64_4x4.lxt"); + $dumpvars(0, test_axis_crosspoint_64_4x4); +end + +axis_crosspoint_64_4x4 #( + .DATA_WIDTH(64) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI inputs + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tkeep(input_0_axis_tkeep), + .input_0_axis_tvalid(input_0_axis_tvalid), + .input_0_axis_tlast(input_0_axis_tlast), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tkeep(input_1_axis_tkeep), + .input_1_axis_tvalid(input_1_axis_tvalid), + .input_1_axis_tlast(input_1_axis_tlast), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tkeep(input_2_axis_tkeep), + .input_2_axis_tvalid(input_2_axis_tvalid), + .input_2_axis_tlast(input_2_axis_tlast), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tkeep(input_3_axis_tkeep), + .input_3_axis_tvalid(input_3_axis_tvalid), + .input_3_axis_tlast(input_3_axis_tlast), + // AXI outputs + .output_0_axis_tdata(output_0_axis_tdata), + .output_0_axis_tkeep(output_0_axis_tkeep), + .output_0_axis_tvalid(output_0_axis_tvalid), + .output_0_axis_tlast(output_0_axis_tlast), + .output_1_axis_tdata(output_1_axis_tdata), + .output_1_axis_tkeep(output_1_axis_tkeep), + .output_1_axis_tvalid(output_1_axis_tvalid), + .output_1_axis_tlast(output_1_axis_tlast), + .output_2_axis_tdata(output_2_axis_tdata), + .output_2_axis_tkeep(output_2_axis_tkeep), + .output_2_axis_tvalid(output_2_axis_tvalid), + .output_2_axis_tlast(output_2_axis_tlast), + .output_3_axis_tdata(output_3_axis_tdata), + .output_3_axis_tkeep(output_3_axis_tkeep), + .output_3_axis_tvalid(output_3_axis_tvalid), + .output_3_axis_tlast(output_3_axis_tlast), + // Control + .output_0_select(output_0_select), + .output_1_select(output_1_select), + .output_2_select(output_2_select), + .output_3_select(output_3_select) +); + +endmodule From d6784d189d9b4bdd4eb74afe34da85298a538568 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 12 Nov 2014 02:03:59 -0800 Subject: [PATCH 082/617] Update readme --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 60300ac79..9fafda454 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,20 @@ Supports power of two depths only. Basic frame-based asynchronous FIFO with tkeep signal and parametrizable data width and depth. Supports power of two depths only. +### axis_crosspoint module + +Basic crosspoint switch. tready signal not supported. Parametrizable data +width. + +Can be generated with arbitrary port counts with axis_crosspoint.py. + +### axis_crosspoint_64 module + +Basic crosspoint switch with tkeep. tready signal not supported. +Parametrizable data width. + +Can be generated with arbitrary port counts with axis_crosspoint_64.py. + ### axis_fifo module Basic word-based synchronous FIFO with parametrizable data width and depth. @@ -122,6 +136,10 @@ LocalLink to AXI stream bridge. rtl/axis_async_fifo_64.v : Asynchronous FIFO (64 bit) rtl/axis_async_frame_fifo.v : Asynchronous frame FIFO rtl/axis_async_frame_fifo_64.v : Asynchronous frame FIFO (64 bit) + rtl/axis_crosspoint.py : Crosspoint switch generator + rtl/axis_crosspoint_4x4.v : 4x4 crosspoint switch + rtl/axis_crosspoint_64.py : Crosspoint switch generator (64 bit) + rtl/axis_crosspoint_64_4x4.v : 4x4 crosspoint switch (64 bit) rtl/axis_fifo.v : Synchronous FIFO rtl/axis_fifo_64.v : Synchronous FIFO (64 bit) rtl/axis_frame_fifo.v : Synchronous frame FIFO From 3816eb3c20f40b72d2d23cb6964a8bd8126985c2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 12 Nov 2014 02:06:18 -0800 Subject: [PATCH 083/617] Fix parameters --- rtl/axis_rate_limit.v | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index f1ebb70e5..a7f113e58 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -31,8 +31,7 @@ THE SOFTWARE. */ module axis_rate_limit # ( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) + parameter DATA_WIDTH = 8 ) ( input wire clk, From aafacb372edb8cbd485d9100194c9d2ad10cee54 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 12 Nov 2014 15:32:05 -0800 Subject: [PATCH 084/617] Trim trailing spaces --- rtl/axis_crosspoint.py | 46 ++++++++++++++++++------------------ rtl/axis_crosspoint_4x4.v | 38 ++++++++++++++--------------- rtl/axis_crosspoint_64.py | 46 ++++++++++++++++++------------------ rtl/axis_crosspoint_64_4x4.v | 38 ++++++++++++++--------------- 4 files changed, 84 insertions(+), 84 deletions(-) diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index dc8f24149..e779ad086 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """axis_crosspoint -Generates an AXI Stream crosspoint switch with a specific number of ports +Generates an AXI Stream crosspoint switch with the specified number of ports Usage: axis_crosspoint [OPTION]... -?, --help display this help and exit @@ -106,29 +106,29 @@ module {{name}} # ( input wire clk, input wire rst, - + /* * AXI Stream inputs */ - {%- for p in ports %} +{%- for p in ports %} input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, input wire input_{{p}}_axis_tvalid, input wire input_{{p}}_axis_tlast, - {% endfor %} +{% endfor %} /* * AXI Stream outputs */ - {%- for p in ports %} +{%- for p in ports %} output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, output wire output_{{p}}_axis_tvalid, output wire output_{{p}}_axis_tlast, - {% endfor %} +{% endfor %} /* * Control */ - {%- for p in ports %} +{%- for p in ports %} input wire [{{w-1}}:0] output_{{p}}_select{% if not loop.last %},{% endif %} - {%- endfor %} +{%- endfor %} ); {% for p in ports %} reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = 0; @@ -153,38 +153,38 @@ assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; always @(posedge clk or posedge rst) begin if (rst) begin - {%- for p in ports %} +{%- for p in ports %} output_{{p}}_select_reg <= 0; - {%- endfor %} - {% for p in ports %} +{%- endfor %} +{% for p in ports %} input_{{p}}_axis_tvalid_reg <= 0; input_{{p}}_axis_tlast_reg <= 0; - {%- endfor %} - {% for p in ports %} +{%- endfor %} +{% for p in ports %} output_{{p}}_axis_tvalid_reg <= 0; output_{{p}}_axis_tlast_reg <= 0; - {%- endfor %} +{%- endfor %} end else begin - {%- for p in ports %} +{%- for p in ports %} input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; - {% endfor %} - {%- for p in ports %} +{% endfor %} +{%- for p in ports %} output_{{p}}_select_reg <= output_{{p}}_select; - {%- endfor %} - {%- for p in ports %} - +{%- endfor %} +{%- for p in ports %} + case (output_{{p}}_select_reg) - {%- for q in ports %} +{%- for q in ports %} {{w}}'d{{q}}: begin output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; end - {%- endfor %} +{%- endfor %} endcase - {%- endfor %} +{%- endfor %} end end diff --git a/rtl/axis_crosspoint_4x4.v b/rtl/axis_crosspoint_4x4.v index 1734f49f3..859f4309c 100644 --- a/rtl/axis_crosspoint_4x4.v +++ b/rtl/axis_crosspoint_4x4.v @@ -36,45 +36,45 @@ module axis_crosspoint_4x4 # ( input wire clk, input wire rst, - + /* * AXI Stream inputs */ input wire [DATA_WIDTH-1:0] input_0_axis_tdata, input wire input_0_axis_tvalid, input wire input_0_axis_tlast, - + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, input wire input_1_axis_tvalid, input wire input_1_axis_tlast, - + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, input wire input_2_axis_tvalid, input wire input_2_axis_tlast, - + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, input wire input_3_axis_tvalid, input wire input_3_axis_tlast, - + /* * AXI Stream outputs */ output wire [DATA_WIDTH-1:0] output_0_axis_tdata, output wire output_0_axis_tvalid, output wire output_0_axis_tlast, - + output wire [DATA_WIDTH-1:0] output_1_axis_tdata, output wire output_1_axis_tvalid, output wire output_1_axis_tlast, - + output wire [DATA_WIDTH-1:0] output_2_axis_tdata, output wire output_2_axis_tvalid, output wire output_2_axis_tlast, - + output wire [DATA_WIDTH-1:0] output_3_axis_tdata, output wire output_3_axis_tvalid, output wire output_3_axis_tlast, - + /* * Control */ @@ -144,7 +144,7 @@ always @(posedge clk or posedge rst) begin output_1_select_reg <= 0; output_2_select_reg <= 0; output_3_select_reg <= 0; - + input_0_axis_tvalid_reg <= 0; input_0_axis_tlast_reg <= 0; input_1_axis_tvalid_reg <= 0; @@ -153,7 +153,7 @@ always @(posedge clk or posedge rst) begin input_2_axis_tlast_reg <= 0; input_3_axis_tvalid_reg <= 0; input_3_axis_tlast_reg <= 0; - + output_0_axis_tvalid_reg <= 0; output_0_axis_tlast_reg <= 0; output_1_axis_tvalid_reg <= 0; @@ -166,24 +166,24 @@ always @(posedge clk or posedge rst) begin input_0_axis_tdata_reg <= input_0_axis_tdata; input_0_axis_tvalid_reg <= input_0_axis_tvalid; input_0_axis_tlast_reg <= input_0_axis_tlast; - + input_1_axis_tdata_reg <= input_1_axis_tdata; input_1_axis_tvalid_reg <= input_1_axis_tvalid; input_1_axis_tlast_reg <= input_1_axis_tlast; - + input_2_axis_tdata_reg <= input_2_axis_tdata; input_2_axis_tvalid_reg <= input_2_axis_tvalid; input_2_axis_tlast_reg <= input_2_axis_tlast; - + input_3_axis_tdata_reg <= input_3_axis_tdata; input_3_axis_tvalid_reg <= input_3_axis_tvalid; input_3_axis_tlast_reg <= input_3_axis_tlast; - + output_0_select_reg <= output_0_select; output_1_select_reg <= output_1_select; output_2_select_reg <= output_2_select; output_3_select_reg <= output_3_select; - + case (output_0_select_reg) 2'd0: begin output_0_axis_tdata_reg <= input_0_axis_tdata_reg; @@ -206,7 +206,7 @@ always @(posedge clk or posedge rst) begin output_0_axis_tlast_reg <= input_3_axis_tlast_reg; end endcase - + case (output_1_select_reg) 2'd0: begin output_1_axis_tdata_reg <= input_0_axis_tdata_reg; @@ -229,7 +229,7 @@ always @(posedge clk or posedge rst) begin output_1_axis_tlast_reg <= input_3_axis_tlast_reg; end endcase - + case (output_2_select_reg) 2'd0: begin output_2_axis_tdata_reg <= input_0_axis_tdata_reg; @@ -252,7 +252,7 @@ always @(posedge clk or posedge rst) begin output_2_axis_tlast_reg <= input_3_axis_tlast_reg; end endcase - + case (output_3_select_reg) 2'd0: begin output_3_axis_tdata_reg <= input_0_axis_tdata_reg; diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index dea44e2ea..fa674ffab 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """axis_crosspoint_64_64 -Generates an AXI Stream crosspoint switch with a specific number of ports +Generates an AXI Stream crosspoint switch with the specified number of ports Usage: axis_crosspoint_64 [OPTION]... -?, --help display this help and exit @@ -107,31 +107,31 @@ module {{name}} # ( input wire clk, input wire rst, - + /* * AXI Stream inputs */ - {%- for p in ports %} +{%- for p in ports %} input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, input wire input_{{p}}_axis_tvalid, input wire input_{{p}}_axis_tlast, - {% endfor %} +{% endfor %} /* * AXI Stream outputs */ - {%- for p in ports %} +{%- for p in ports %} output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, output wire output_{{p}}_axis_tvalid, output wire output_{{p}}_axis_tlast, - {% endfor %} +{% endfor %} /* * Control */ - {%- for p in ports %} +{%- for p in ports %} input wire [{{w-1}}:0] output_{{p}}_select{% if not loop.last %},{% endif %} - {%- endfor %} +{%- endfor %} ); {% for p in ports %} reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = 0; @@ -159,40 +159,40 @@ assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; always @(posedge clk or posedge rst) begin if (rst) begin - {%- for p in ports %} +{%- for p in ports %} output_{{p}}_select_reg <= 0; - {%- endfor %} - {% for p in ports %} +{%- endfor %} +{% for p in ports %} input_{{p}}_axis_tvalid_reg <= 0; input_{{p}}_axis_tlast_reg <= 0; - {%- endfor %} - {% for p in ports %} +{%- endfor %} +{% for p in ports %} output_{{p}}_axis_tvalid_reg <= 0; output_{{p}}_axis_tlast_reg <= 0; - {%- endfor %} +{%- endfor %} end else begin - {%- for p in ports %} +{%- for p in ports %} input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; input_{{p}}_axis_tkeep_reg <= input_{{p}}_axis_tkeep; input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; - {% endfor %} - {%- for p in ports %} +{% endfor %} +{%- for p in ports %} output_{{p}}_select_reg <= output_{{p}}_select; - {%- endfor %} - {%- for p in ports %} - +{%- endfor %} +{%- for p in ports %} + case (output_{{p}}_select_reg) - {%- for q in ports %} +{%- for q in ports %} {{w}}'d{{q}}: begin output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; output_{{p}}_axis_tkeep_reg <= input_{{q}}_axis_tkeep_reg; output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; end - {%- endfor %} +{%- endfor %} endcase - {%- endfor %} +{%- endfor %} end end diff --git a/rtl/axis_crosspoint_64_4x4.v b/rtl/axis_crosspoint_64_4x4.v index 25345c15d..08c41ad54 100644 --- a/rtl/axis_crosspoint_64_4x4.v +++ b/rtl/axis_crosspoint_64_4x4.v @@ -37,7 +37,7 @@ module axis_crosspoint_64_4x4 # ( input wire clk, input wire rst, - + /* * AXI Stream inputs */ @@ -45,22 +45,22 @@ module axis_crosspoint_64_4x4 # input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, input wire input_0_axis_tvalid, input wire input_0_axis_tlast, - + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, input wire input_1_axis_tvalid, input wire input_1_axis_tlast, - + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, input wire input_2_axis_tvalid, input wire input_2_axis_tlast, - + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, input wire input_3_axis_tvalid, input wire input_3_axis_tlast, - + /* * AXI Stream outputs */ @@ -68,22 +68,22 @@ module axis_crosspoint_64_4x4 # output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, output wire output_0_axis_tvalid, output wire output_0_axis_tlast, - + output wire [DATA_WIDTH-1:0] output_1_axis_tdata, output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, output wire output_1_axis_tvalid, output wire output_1_axis_tlast, - + output wire [DATA_WIDTH-1:0] output_2_axis_tdata, output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, output wire output_2_axis_tvalid, output wire output_2_axis_tlast, - + output wire [DATA_WIDTH-1:0] output_3_axis_tdata, output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, output wire output_3_axis_tvalid, output wire output_3_axis_tlast, - + /* * Control */ @@ -165,7 +165,7 @@ always @(posedge clk or posedge rst) begin output_1_select_reg <= 0; output_2_select_reg <= 0; output_3_select_reg <= 0; - + input_0_axis_tvalid_reg <= 0; input_0_axis_tlast_reg <= 0; input_1_axis_tvalid_reg <= 0; @@ -174,7 +174,7 @@ always @(posedge clk or posedge rst) begin input_2_axis_tlast_reg <= 0; input_3_axis_tvalid_reg <= 0; input_3_axis_tlast_reg <= 0; - + output_0_axis_tvalid_reg <= 0; output_0_axis_tlast_reg <= 0; output_1_axis_tvalid_reg <= 0; @@ -188,27 +188,27 @@ always @(posedge clk or posedge rst) begin input_0_axis_tkeep_reg <= input_0_axis_tkeep; input_0_axis_tvalid_reg <= input_0_axis_tvalid; input_0_axis_tlast_reg <= input_0_axis_tlast; - + input_1_axis_tdata_reg <= input_1_axis_tdata; input_1_axis_tkeep_reg <= input_1_axis_tkeep; input_1_axis_tvalid_reg <= input_1_axis_tvalid; input_1_axis_tlast_reg <= input_1_axis_tlast; - + input_2_axis_tdata_reg <= input_2_axis_tdata; input_2_axis_tkeep_reg <= input_2_axis_tkeep; input_2_axis_tvalid_reg <= input_2_axis_tvalid; input_2_axis_tlast_reg <= input_2_axis_tlast; - + input_3_axis_tdata_reg <= input_3_axis_tdata; input_3_axis_tkeep_reg <= input_3_axis_tkeep; input_3_axis_tvalid_reg <= input_3_axis_tvalid; input_3_axis_tlast_reg <= input_3_axis_tlast; - + output_0_select_reg <= output_0_select; output_1_select_reg <= output_1_select; output_2_select_reg <= output_2_select; output_3_select_reg <= output_3_select; - + case (output_0_select_reg) 2'd0: begin output_0_axis_tdata_reg <= input_0_axis_tdata_reg; @@ -235,7 +235,7 @@ always @(posedge clk or posedge rst) begin output_0_axis_tlast_reg <= input_3_axis_tlast_reg; end endcase - + case (output_1_select_reg) 2'd0: begin output_1_axis_tdata_reg <= input_0_axis_tdata_reg; @@ -262,7 +262,7 @@ always @(posedge clk or posedge rst) begin output_1_axis_tlast_reg <= input_3_axis_tlast_reg; end endcase - + case (output_2_select_reg) 2'd0: begin output_2_axis_tdata_reg <= input_0_axis_tdata_reg; @@ -289,7 +289,7 @@ always @(posedge clk or posedge rst) begin output_2_axis_tlast_reg <= input_3_axis_tlast_reg; end endcase - + case (output_3_select_reg) 2'd0: begin output_3_axis_tdata_reg <= input_0_axis_tdata_reg; From 5af6dc3501ed77cab3d4ca570584ca60990c4a29 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 12 Nov 2014 15:49:07 -0800 Subject: [PATCH 085/617] Add AXI stream mux and testbench --- rtl/axis_mux.py | 308 +++++++++++++++++++++++ rtl/axis_mux_4.v | 269 ++++++++++++++++++++ rtl/axis_mux_64.py | 324 ++++++++++++++++++++++++ rtl/axis_mux_64_4.v | 291 ++++++++++++++++++++++ tb/test_axis_mux_4.py | 497 +++++++++++++++++++++++++++++++++++++ tb/test_axis_mux_4.v | 142 +++++++++++ tb/test_axis_mux_64_4.py | 522 +++++++++++++++++++++++++++++++++++++++ tb/test_axis_mux_64_4.v | 157 ++++++++++++ 8 files changed, 2510 insertions(+) create mode 100755 rtl/axis_mux.py create mode 100644 rtl/axis_mux_4.v create mode 100755 rtl/axis_mux_64.py create mode 100644 rtl/axis_mux_64_4.v create mode 100755 tb/test_axis_mux_4.py create mode 100644 tb/test_axis_mux_4.v create mode 100755 tb/test_axis_mux_64_4.py create mode 100644 tb/test_axis_mux_64_4.v diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py new file mode 100755 index 000000000..6286e3c19 --- /dev/null +++ b/rtl/axis_mux.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python +"""axis_mux + +Generates an AXI Stream mux with the specified number of ports + +Usage: axis_crosspoint [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "axis_mux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port multiplexer + */ +module {{name}} # +( + parameter DATA_WIDTH = 8 +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ +{%- for p in ports %} + input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire input_{{p}}_axis_tvalid, + output wire input_{{p}}_axis_tready, + input wire input_{{p}}_axis_tlast, + input wire input_{{p}}_axis_tuser, +{% endfor %} + /* + * AXI output + */ + output wire [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, + + /* + * Control + */ + input wire [{{w-1}}:0] select +); + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; +{% for p in ports %} +reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +{%- endfor %} +{% for p in ports %} +assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; +{%- endfor %} + +// mux for start of packet detection +reg selected_input_tvalid; +always @* begin + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: selected_input_tvalid = input_{{p}}_axis_tvalid; +{%- endfor %} + endcase +end + +// mux for incoming packet +reg [DATA_WIDTH-1:0] current_input_tdata; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_input_tdata = input_{{p}}_axis_tdata; + current_input_tvalid = input_{{p}}_axis_tvalid; + current_input_tready = input_{{p}}_axis_tready; + current_input_tlast = input_{{p}}_axis_tlast; + current_input_tuser = input_{{p}}_axis_tuser; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; +{% for p in ports %} + input_{{p}}_axis_tready_next = 0; +{%- endfor %} + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (selected_input_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + end + + // generate ready signal on selected port + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early & frame_next; +{%- endfor %} + endcase + + // pass through selected packet data + output_axis_tdata_int = current_input_tdata; + output_axis_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_axis_tlast_int = current_input_tlast; + output_axis_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; +{%- for p in ports %} + input_{{p}}_axis_tready_reg <= 0; +{%- endfor %} + end else begin + select_reg <= select_next; + frame_reg <= frame_next; +{%- for p in ports %} + input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; +{%- endfor %} + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v new file mode 100644 index 000000000..b1e04fb63 --- /dev/null +++ b/rtl/axis_mux_4.v @@ -0,0 +1,269 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream 4 port multiplexer + */ +module axis_mux_4 # +( + parameter DATA_WIDTH = 8 +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ + input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire input_0_axis_tvalid, + output wire input_0_axis_tready, + input wire input_0_axis_tlast, + input wire input_0_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire input_1_axis_tvalid, + output wire input_1_axis_tready, + input wire input_1_axis_tlast, + input wire input_1_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire input_2_axis_tvalid, + output wire input_2_axis_tready, + input wire input_2_axis_tlast, + input wire input_2_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire input_3_axis_tvalid, + output wire input_3_axis_tready, + input wire input_3_axis_tlast, + input wire input_3_axis_tuser, + + /* + * AXI output + */ + output wire [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, + + /* + * Control + */ + input wire [1:0] select +); + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; + +assign input_0_axis_tready = input_0_axis_tready_reg; +assign input_1_axis_tready = input_1_axis_tready_reg; +assign input_2_axis_tready = input_2_axis_tready_reg; +assign input_3_axis_tready = input_3_axis_tready_reg; + +// mux for start of packet detection +reg selected_input_tvalid; +always @* begin + case (select) + 2'd0: selected_input_tvalid = input_0_axis_tvalid; + 2'd1: selected_input_tvalid = input_1_axis_tvalid; + 2'd2: selected_input_tvalid = input_2_axis_tvalid; + 2'd3: selected_input_tvalid = input_3_axis_tvalid; + endcase +end + +// mux for incoming packet +reg [DATA_WIDTH-1:0] current_input_tdata; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 2'd0: begin + current_input_tdata = input_0_axis_tdata; + current_input_tvalid = input_0_axis_tvalid; + current_input_tready = input_0_axis_tready; + current_input_tlast = input_0_axis_tlast; + current_input_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_tdata = input_1_axis_tdata; + current_input_tvalid = input_1_axis_tvalid; + current_input_tready = input_1_axis_tready; + current_input_tlast = input_1_axis_tlast; + current_input_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_tdata = input_2_axis_tdata; + current_input_tvalid = input_2_axis_tvalid; + current_input_tready = input_2_axis_tready; + current_input_tlast = input_2_axis_tlast; + current_input_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_tdata = input_3_axis_tdata; + current_input_tvalid = input_3_axis_tvalid; + current_input_tready = input_3_axis_tready; + current_input_tlast = input_3_axis_tlast; + current_input_tuser = input_3_axis_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_axis_tready_next = 0; + input_1_axis_tready_next = 0; + input_2_axis_tready_next = 0; + input_3_axis_tready_next = 0; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (selected_input_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + end + + // generate ready signal on selected port + case (select_next) + 2'd0: input_0_axis_tready_next = output_axis_tready_int_early & frame_next; + 2'd1: input_1_axis_tready_next = output_axis_tready_int_early & frame_next; + 2'd2: input_2_axis_tready_next = output_axis_tready_int_early & frame_next; + 2'd3: input_3_axis_tready_next = output_axis_tready_int_early & frame_next; + endcase + + // pass through selected packet data + output_axis_tdata_int = current_input_tdata; + output_axis_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_axis_tlast_int = current_input_tlast; + output_axis_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_axis_tready_reg <= 0; + input_1_axis_tready_reg <= 0; + input_2_axis_tready_reg <= 0; + input_3_axis_tready_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_axis_tready_reg <= input_0_axis_tready_next; + input_1_axis_tready_reg <= input_1_axis_tready_next; + input_2_axis_tready_reg <= input_2_axis_tready_next; + input_3_axis_tready_reg <= input_3_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py new file mode 100755 index 000000000..53acfe832 --- /dev/null +++ b/rtl/axis_mux_64.py @@ -0,0 +1,324 @@ +#!/usr/bin/env python +"""axis_mux + +Generates an AXI Stream mux with the specified number of ports + +Usage: axis_crosspoint [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "axis_mux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port multiplexer (64 bit datapath) + */ +module {{name}} # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ +{%- for p in ports %} + input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, + input wire input_{{p}}_axis_tvalid, + output wire input_{{p}}_axis_tready, + input wire input_{{p}}_axis_tlast, + input wire input_{{p}}_axis_tuser, +{% endfor %} + /* + * AXI output + */ + output wire [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, + + /* + * Control + */ + input wire [{{w-1}}:0] select +); + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; +{% for p in ports %} +reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +{%- endfor %} +{% for p in ports %} +assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; +{%- endfor %} + +// mux for start of packet detection +reg selected_input_tvalid; +always @* begin + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: selected_input_tvalid = input_{{p}}_axis_tvalid; +{%- endfor %} + endcase +end + +// mux for incoming packet +reg [DATA_WIDTH-1:0] current_input_tdata; +reg [KEEP_WIDTH-1:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_input_tdata = input_{{p}}_axis_tdata; + current_input_tkeep = input_{{p}}_axis_tkeep; + current_input_tvalid = input_{{p}}_axis_tvalid; + current_input_tready = input_{{p}}_axis_tready; + current_input_tlast = input_{{p}}_axis_tlast; + current_input_tuser = input_{{p}}_axis_tuser; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; +{% for p in ports %} + input_{{p}}_axis_tready_next = 0; +{%- endfor %} + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (selected_input_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + end + + // generate ready signal on selected port + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early & frame_next; +{%- endfor %} + endcase + + // pass through selected packet data + output_axis_tdata_int = current_input_tdata; + output_axis_tkeep_int = current_input_tkeep; + output_axis_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_axis_tlast_int = current_input_tlast; + output_axis_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; +{%- for p in ports %} + input_{{p}}_axis_tready_reg <= 0; +{%- endfor %} + end else begin + select_reg <= select_next; + frame_reg <= frame_next; +{%- for p in ports %} + input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; +{%- endfor %} + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/axis_mux_64_4.v b/rtl/axis_mux_64_4.v new file mode 100644 index 000000000..038e377f5 --- /dev/null +++ b/rtl/axis_mux_64_4.v @@ -0,0 +1,291 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream 4 port multiplexer (64 bit datapath) + */ +module axis_mux_64_4 # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ + input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, + input wire input_0_axis_tvalid, + output wire input_0_axis_tready, + input wire input_0_axis_tlast, + input wire input_0_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, + input wire input_1_axis_tvalid, + output wire input_1_axis_tready, + input wire input_1_axis_tlast, + input wire input_1_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, + input wire input_2_axis_tvalid, + output wire input_2_axis_tready, + input wire input_2_axis_tlast, + input wire input_2_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, + input wire input_3_axis_tvalid, + output wire input_3_axis_tready, + input wire input_3_axis_tlast, + input wire input_3_axis_tuser, + + /* + * AXI output + */ + output wire [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, + + /* + * Control + */ + input wire [1:0] select +); + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; + +assign input_0_axis_tready = input_0_axis_tready_reg; +assign input_1_axis_tready = input_1_axis_tready_reg; +assign input_2_axis_tready = input_2_axis_tready_reg; +assign input_3_axis_tready = input_3_axis_tready_reg; + +// mux for start of packet detection +reg selected_input_tvalid; +always @* begin + case (select) + 2'd0: selected_input_tvalid = input_0_axis_tvalid; + 2'd1: selected_input_tvalid = input_1_axis_tvalid; + 2'd2: selected_input_tvalid = input_2_axis_tvalid; + 2'd3: selected_input_tvalid = input_3_axis_tvalid; + endcase +end + +// mux for incoming packet +reg [DATA_WIDTH-1:0] current_input_tdata; +reg [KEEP_WIDTH-1:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 2'd0: begin + current_input_tdata = input_0_axis_tdata; + current_input_tkeep = input_0_axis_tkeep; + current_input_tvalid = input_0_axis_tvalid; + current_input_tready = input_0_axis_tready; + current_input_tlast = input_0_axis_tlast; + current_input_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_tdata = input_1_axis_tdata; + current_input_tkeep = input_1_axis_tkeep; + current_input_tvalid = input_1_axis_tvalid; + current_input_tready = input_1_axis_tready; + current_input_tlast = input_1_axis_tlast; + current_input_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_tdata = input_2_axis_tdata; + current_input_tkeep = input_2_axis_tkeep; + current_input_tvalid = input_2_axis_tvalid; + current_input_tready = input_2_axis_tready; + current_input_tlast = input_2_axis_tlast; + current_input_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_tdata = input_3_axis_tdata; + current_input_tkeep = input_3_axis_tkeep; + current_input_tvalid = input_3_axis_tvalid; + current_input_tready = input_3_axis_tready; + current_input_tlast = input_3_axis_tlast; + current_input_tuser = input_3_axis_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_axis_tready_next = 0; + input_1_axis_tready_next = 0; + input_2_axis_tready_next = 0; + input_3_axis_tready_next = 0; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (selected_input_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + end + + // generate ready signal on selected port + case (select_next) + 2'd0: input_0_axis_tready_next = output_axis_tready_int_early & frame_next; + 2'd1: input_1_axis_tready_next = output_axis_tready_int_early & frame_next; + 2'd2: input_2_axis_tready_next = output_axis_tready_int_early & frame_next; + 2'd3: input_3_axis_tready_next = output_axis_tready_int_early & frame_next; + endcase + + // pass through selected packet data + output_axis_tdata_int = current_input_tdata; + output_axis_tkeep_int = current_input_tkeep; + output_axis_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_axis_tlast_int = current_input_tlast; + output_axis_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_axis_tready_reg <= 0; + input_1_axis_tready_reg <= 0; + input_2_axis_tready_reg <= 0; + input_3_axis_tready_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_axis_tready_reg <= input_0_axis_tready_next; + input_1_axis_tready_reg <= input_1_axis_tready_next; + input_2_axis_tready_reg <= input_2_axis_tready_next; + input_3_axis_tready_reg <= input_3_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py new file mode 100755 index 000000000..08fd69232 --- /dev/null +++ b/tb/test_axis_mux_4.py @@ -0,0 +1,497 @@ +#!/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_mux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_mux_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + select): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_axis_tdata = Signal(intbv(0)[8:]) + input_0_axis_tvalid = Signal(bool(0)) + input_0_axis_tlast = Signal(bool(0)) + input_0_axis_tuser = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[8:]) + input_1_axis_tvalid = Signal(bool(0)) + input_1_axis_tlast = Signal(bool(0)) + input_1_axis_tuser = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[8:]) + input_2_axis_tvalid = Signal(bool(0)) + input_2_axis_tlast = Signal(bool(0)) + input_2_axis_tuser = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[8:]) + input_3_axis_tvalid = Signal(bool(0)) + input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tuser = Signal(bool(0)) + + output_axis_tready = Signal(bool(0)) + + select = Signal(intbv(0)[2:]) + + # Outputs + input_0_axis_tready = Signal(bool(0)) + input_1_axis_tready = Signal(bool(0)) + input_2_axis_tready = Signal(bool(0)) + input_3_axis_tready = Signal(bool(0)) + + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + source_1 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + source_2 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + source_3 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + 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_mux_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + select) + + @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: select port 0") + current_test.next = 1 + + select.next = 0 + + 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_0_queue.put(test_frame) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.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_1_queue.put(test_frame) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = 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_frame2 = 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_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + select.next = 2 + 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: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + select.next = 2 + 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: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + select.next = 2 + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_mux_4.v b/tb/test_axis_mux_4.v new file mode 100644 index 000000000..d31c8429d --- /dev/null +++ b/tb/test_axis_mux_4.v @@ -0,0 +1,142 @@ +/* + +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_mux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_0_axis_tdata = 0; +reg input_0_axis_tvalid = 0; +reg input_0_axis_tlast = 0; +reg input_0_axis_tuser = 0; +reg [7:0] input_1_axis_tdata = 0; +reg input_1_axis_tvalid = 0; +reg input_1_axis_tlast = 0; +reg input_1_axis_tuser = 0; +reg [7:0] input_2_axis_tdata = 0; +reg input_2_axis_tvalid = 0; +reg input_2_axis_tlast = 0; +reg input_2_axis_tuser = 0; +reg [7:0] input_3_axis_tdata = 0; +reg input_3_axis_tvalid = 0; +reg input_3_axis_tlast = 0; +reg input_3_axis_tuser = 0; + +reg output_axis_tready = 0; + +reg [1:0] select = 0; + +// Outputs +wire input_0_axis_tready; +wire input_1_axis_tready; +wire input_2_axis_tready; +wire input_3_axis_tready; + +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready, + select); + $to_myhdl(input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_mux_4.lxt"); + $dumpvars(0, test_axis_mux_4); +end + +axis_mux_4 #( + .DATA_WIDTH(8) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI inputs + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tvalid(input_0_axis_tvalid), + .input_0_axis_tready(input_0_axis_tready), + .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tuser(input_0_axis_tuser), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tvalid(input_1_axis_tvalid), + .input_1_axis_tready(input_1_axis_tready), + .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tuser(input_1_axis_tuser), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tvalid(input_2_axis_tvalid), + .input_2_axis_tready(input_2_axis_tready), + .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tuser(input_2_axis_tuser), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tvalid(input_3_axis_tvalid), + .input_3_axis_tready(input_3_axis_tready), + .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tuser(input_3_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // Control + .select(select) +); + +endmodule diff --git a/tb/test_axis_mux_64_4.py b/tb/test_axis_mux_64_4.py new file mode 100755 index 000000000..b866c680b --- /dev/null +++ b/tb/test_axis_mux_64_4.py @@ -0,0 +1,522 @@ +#!/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_mux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_mux_64_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + select): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_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, + + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_axis_tdata = Signal(intbv(0)[64:]) + input_0_axis_tkeep = Signal(intbv(0)[8:]) + input_0_axis_tvalid = Signal(bool(0)) + input_0_axis_tlast = Signal(bool(0)) + input_0_axis_tuser = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[64:]) + input_1_axis_tkeep = Signal(intbv(0)[8:]) + input_1_axis_tvalid = Signal(bool(0)) + input_1_axis_tlast = Signal(bool(0)) + input_1_axis_tuser = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[64:]) + input_2_axis_tkeep = Signal(intbv(0)[8:]) + input_2_axis_tvalid = Signal(bool(0)) + input_2_axis_tlast = Signal(bool(0)) + input_2_axis_tuser = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[64:]) + input_3_axis_tkeep = Signal(intbv(0)[8:]) + input_3_axis_tvalid = Signal(bool(0)) + input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tuser = Signal(bool(0)) + + output_axis_tready = Signal(bool(0)) + + select = Signal(intbv(0)[2:]) + + # Outputs + input_0_axis_tready = Signal(bool(0)) + input_1_axis_tready = Signal(bool(0)) + input_2_axis_tready = Signal(bool(0)) + input_3_axis_tready = Signal(bool(0)) + + output_axis_tdata = Signal(intbv(0)[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_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + source_1 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + source_2 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + source_3 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + 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_mux_64_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + select) + + @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: select port 0") + current_test.next = 1 + + select.next = 0 + + 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_0_queue.put(test_frame) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.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_1_queue.put(test_frame) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = 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_frame2 = 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_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + select.next = 2 + 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: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + select.next = 2 + 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: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + select.next = 2 + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_mux_64_4.v b/tb/test_axis_mux_64_4.v new file mode 100644 index 000000000..31c4f0b19 --- /dev/null +++ b/tb/test_axis_mux_64_4.v @@ -0,0 +1,157 @@ +/* + +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_mux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] input_0_axis_tdata = 0; +reg [7:0] input_0_axis_tkeep = 0; +reg input_0_axis_tvalid = 0; +reg input_0_axis_tlast = 0; +reg input_0_axis_tuser = 0; +reg [63:0] input_1_axis_tdata = 0; +reg [7:0] input_1_axis_tkeep = 0; +reg input_1_axis_tvalid = 0; +reg input_1_axis_tlast = 0; +reg input_1_axis_tuser = 0; +reg [63:0] input_2_axis_tdata = 0; +reg [7:0] input_2_axis_tkeep = 0; +reg input_2_axis_tvalid = 0; +reg input_2_axis_tlast = 0; +reg input_2_axis_tuser = 0; +reg [63:0] input_3_axis_tdata = 0; +reg [7:0] input_3_axis_tkeep = 0; +reg input_3_axis_tvalid = 0; +reg input_3_axis_tlast = 0; +reg input_3_axis_tuser = 0; + +reg output_axis_tready = 0; + +reg [1:0] select = 0; + +// Outputs +wire input_0_axis_tready; +wire input_1_axis_tready; +wire input_2_axis_tready; +wire input_3_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_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready, + select); + $to_myhdl(input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_mux_64_4.lxt"); + $dumpvars(0, test_axis_mux_64_4); +end + +axis_mux_64_4 #( + .DATA_WIDTH(64) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI inputs + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tkeep(input_0_axis_tkeep), + .input_0_axis_tvalid(input_0_axis_tvalid), + .input_0_axis_tready(input_0_axis_tready), + .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tuser(input_0_axis_tuser), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tkeep(input_1_axis_tkeep), + .input_1_axis_tvalid(input_1_axis_tvalid), + .input_1_axis_tready(input_1_axis_tready), + .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tuser(input_1_axis_tuser), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tkeep(input_2_axis_tkeep), + .input_2_axis_tvalid(input_2_axis_tvalid), + .input_2_axis_tready(input_2_axis_tready), + .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tuser(input_2_axis_tuser), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tkeep(input_3_axis_tkeep), + .input_3_axis_tvalid(input_3_axis_tvalid), + .input_3_axis_tready(input_3_axis_tready), + .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tuser(input_3_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_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), + // Control + .select(select) +); + +endmodule From 73a580df95c9cf357006c92b0dfc970b1ab3dba7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 12 Nov 2014 15:53:47 -0800 Subject: [PATCH 086/617] Update readme --- README.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9fafda454..a06e43690 100644 --- a/README.md +++ b/README.md @@ -82,10 +82,23 @@ Frame joiner with optional tag. 8 bit data path only. Can be generated with arbitrary port counts with axis_frame_join.py. -### axis_ll_bringe module +### axis_ll_bridge module AXI stream to LocalLink bridge. +### axis_mux_N module + +Frame-aware AXI stream muliplexer with parametrizable data width. + +Can be generated with arbitrary port counts with axis_mux.py. + +### axis_mux_64_N module + +Frame-aware AXI stream muliplexer with tkeep signal and parametrizable data +width. + +Can be generated with arbitrary port counts with axis_mux_64.py. + ### axis_rate_limit module Fractional rate limiter, supports word and frame modes. Inserts wait states @@ -147,6 +160,10 @@ LocalLink to AXI stream bridge. rtl/axis_frame_join.py : Frame joiner generator rtl/axis_frame_join_4.v : 4 port frame joiner rtl/axis_ll_bridge.v : AXI stream to LocalLink bridge + rtl/axis_mux.py : Multiplexer generator + rtl/axis_mux_4.v : 4 port multiplexer + rtl/axis_mux_64.py : Multiplexer generator (64 bit) + rtl/axis_mux_64_4.v : 4 port multiplexer (64 bit) rtl/axis_rate_limit.v : Fractional rate limiter rtl/axis_rate_limit_64.v : Fractional rate limiter (64 bit) rtl/axis_register.v : AXI Stream register From 5c49ed61916bffb44f6a430d4e58367b5201b134 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 12 Nov 2014 19:21:28 -0800 Subject: [PATCH 087/617] Add AXI stream demux and testbench --- rtl/axis_demux.py | 290 ++++++++++++++++++++ rtl/axis_demux_4.v | 251 ++++++++++++++++++ rtl/axis_demux_64.py | 304 +++++++++++++++++++++ rtl/axis_demux_64_4.v | 271 +++++++++++++++++++ tb/test_axis_demux_4.py | 500 +++++++++++++++++++++++++++++++++++ tb/test_axis_demux_4.v | 142 ++++++++++ tb/test_axis_demux_64_4.py | 525 +++++++++++++++++++++++++++++++++++++ tb/test_axis_demux_64_4.v | 157 +++++++++++ 8 files changed, 2440 insertions(+) create mode 100755 rtl/axis_demux.py create mode 100644 rtl/axis_demux_4.v create mode 100755 rtl/axis_demux_64.py create mode 100644 rtl/axis_demux_64_4.v create mode 100755 tb/test_axis_demux_4.py create mode 100644 tb/test_axis_demux_4.v create mode 100755 tb/test_axis_demux_64_4.py create mode 100644 tb/test_axis_demux_64_4.v diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py new file mode 100755 index 000000000..4fb494ef2 --- /dev/null +++ b/rtl/axis_demux.py @@ -0,0 +1,290 @@ +#!/usr/bin/env python +"""axis_mux + +Generates an AXI Stream demux with the specified number of ports + +Usage: axis_crosspoint [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "axis_demux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream demux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port demultiplexer + */ +module {{name}} # +( + 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 outputs + */ +{%- for p in ports %} + output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, + output wire output_{{p}}_axis_tvalid, + input wire output_{{p}}_axis_tready, + output wire output_{{p}}_axis_tlast, + output wire output_{{p}}_axis_tuser, +{% endfor %} + /* + * Control + */ + input wire [{{w-1}}:0] select +); + +// // internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +// mux for output control signals +reg current_output_tready; +reg current_output_tvalid; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_output_tvalid = output_{{p}}_axis_tvalid; + current_output_tready = output_{{p}}_axis_tready; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_axis_tready_next = 0; + + if (frame_reg) begin + if (input_axis_tvalid & input_axis_tready) begin + // end of frame detection + frame_next = ~input_axis_tlast; + end + end else if (input_axis_tvalid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + end + + input_axis_tready_next = output_axis_tready_int_early & frame_next; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_axis_tready_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_axis_tready_reg <= input_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +{%- for p in ports %} +reg output_{{p}}_axis_tvalid_reg = 0; +{%- endfor %} +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; +{% for p in ports %} +assign output_{{p}}_axis_tdata = output_axis_tdata_reg; +assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; +assign output_{{p}}_axis_tlast = output_axis_tlast_reg; +assign output_{{p}}_axis_tuser = output_axis_tuser_reg; +{% endfor %} +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; +{%- for p in ports %} + output_{{p}}_axis_tvalid_reg <= 0; +{%- endfor %} + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_axis_tvalid_reg <= output_axis_tvalid_int; +{%- endfor %} + endcase + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_axis_tvalid_reg <= temp_axis_tvalid_reg; +{%- endfor %} + endcase + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v new file mode 100644 index 000000000..f045c1558 --- /dev/null +++ b/rtl/axis_demux_4.v @@ -0,0 +1,251 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream 4 port demultiplexer + */ +module axis_demux_4 # +( + 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 outputs + */ + output wire [DATA_WIDTH-1:0] output_0_axis_tdata, + output wire output_0_axis_tvalid, + input wire output_0_axis_tready, + output wire output_0_axis_tlast, + output wire output_0_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_1_axis_tdata, + output wire output_1_axis_tvalid, + input wire output_1_axis_tready, + output wire output_1_axis_tlast, + output wire output_1_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_2_axis_tdata, + output wire output_2_axis_tvalid, + input wire output_2_axis_tready, + output wire output_2_axis_tlast, + output wire output_2_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_3_axis_tdata, + output wire output_3_axis_tvalid, + input wire output_3_axis_tready, + output wire output_3_axis_tlast, + output wire output_3_axis_tuser, + + /* + * Control + */ + input wire [1:0] select +); + +// // internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +// mux for output control signals +reg current_output_tready; +reg current_output_tvalid; +always @* begin + case (select_reg) + 2'd0: begin + current_output_tvalid = output_0_axis_tvalid; + current_output_tready = output_0_axis_tready; + end + 2'd1: begin + current_output_tvalid = output_1_axis_tvalid; + current_output_tready = output_1_axis_tready; + end + 2'd2: begin + current_output_tvalid = output_2_axis_tvalid; + current_output_tready = output_2_axis_tready; + end + 2'd3: begin + current_output_tvalid = output_3_axis_tvalid; + current_output_tready = output_3_axis_tready; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_axis_tready_next = 0; + + if (frame_reg) begin + if (input_axis_tvalid & input_axis_tready) begin + // end of frame detection + frame_next = ~input_axis_tlast; + end + end else if (input_axis_tvalid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + end + + input_axis_tready_next = output_axis_tready_int_early & frame_next; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_axis_tready_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_axis_tready_reg <= input_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg output_0_axis_tvalid_reg = 0; +reg output_1_axis_tvalid_reg = 0; +reg output_2_axis_tvalid_reg = 0; +reg output_3_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_0_axis_tdata = output_axis_tdata_reg; +assign output_0_axis_tvalid = output_0_axis_tvalid_reg; +assign output_0_axis_tlast = output_axis_tlast_reg; +assign output_0_axis_tuser = output_axis_tuser_reg; + +assign output_1_axis_tdata = output_axis_tdata_reg; +assign output_1_axis_tvalid = output_1_axis_tvalid_reg; +assign output_1_axis_tlast = output_axis_tlast_reg; +assign output_1_axis_tuser = output_axis_tuser_reg; + +assign output_2_axis_tdata = output_axis_tdata_reg; +assign output_2_axis_tvalid = output_2_axis_tvalid_reg; +assign output_2_axis_tlast = output_axis_tlast_reg; +assign output_2_axis_tuser = output_axis_tuser_reg; + +assign output_3_axis_tdata = output_axis_tdata_reg; +assign output_3_axis_tvalid = output_3_axis_tvalid_reg; +assign output_3_axis_tlast = output_axis_tlast_reg; +assign output_3_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_0_axis_tvalid_reg <= 0; + output_1_axis_tvalid_reg <= 0; + output_2_axis_tvalid_reg <= 0; + output_3_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + case (select_reg) + 2'd0: output_0_axis_tvalid_reg <= output_axis_tvalid_int; + 2'd1: output_1_axis_tvalid_reg <= output_axis_tvalid_int; + 2'd2: output_2_axis_tvalid_reg <= output_axis_tvalid_int; + 2'd3: output_3_axis_tvalid_reg <= output_axis_tvalid_int; + endcase + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + case (select_reg) + 2'd0: output_0_axis_tvalid_reg <= temp_axis_tvalid_reg; + 2'd1: output_1_axis_tvalid_reg <= temp_axis_tvalid_reg; + 2'd2: output_2_axis_tvalid_reg <= temp_axis_tvalid_reg; + 2'd3: output_3_axis_tvalid_reg <= temp_axis_tvalid_reg; + endcase + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py new file mode 100755 index 000000000..e28e5d3ac --- /dev/null +++ b/rtl/axis_demux_64.py @@ -0,0 +1,304 @@ +#!/usr/bin/env python +"""axis_mux + +Generates an AXI Stream demux with the specified number of ports + +Usage: axis_crosspoint [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "axis_demux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream demux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port demultiplexer (64 bit datapath) + */ +module {{name}} # +( + 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 outputs + */ +{%- for p in ports %} + output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, + output wire output_{{p}}_axis_tvalid, + input wire output_{{p}}_axis_tready, + output wire output_{{p}}_axis_tlast, + output wire output_{{p}}_axis_tuser, +{% endfor %} + /* + * Control + */ + input wire [{{w-1}}:0] select +); + +// // internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +// mux for output control signals +reg current_output_tready; +reg current_output_tvalid; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_output_tvalid = output_{{p}}_axis_tvalid; + current_output_tready = output_{{p}}_axis_tready; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_axis_tready_next = 0; + + if (frame_reg) begin + if (input_axis_tvalid & input_axis_tready) begin + // end of frame detection + frame_next = ~input_axis_tlast; + end + end else if (input_axis_tvalid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + end + + input_axis_tready_next = output_axis_tready_int_early & frame_next; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_axis_tready_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_axis_tready_reg <= input_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +{%- for p in ports %} +reg output_{{p}}_axis_tvalid_reg = 0; +{%- endfor %} +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; +{% for p in ports %} +assign output_{{p}}_axis_tdata = output_axis_tdata_reg; +assign output_{{p}}_axis_tkeep = output_axis_tkeep_reg; +assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; +assign output_{{p}}_axis_tlast = output_axis_tlast_reg; +assign output_{{p}}_axis_tuser = output_axis_tuser_reg; +{% endfor %} +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; +{%- for p in ports %} + output_{{p}}_axis_tvalid_reg <= 0; +{%- endfor %} + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_axis_tvalid_reg <= output_axis_tvalid_int; +{%- endfor %} + endcase + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_axis_tvalid_reg <= temp_axis_tvalid_reg; +{%- endfor %} + endcase + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/axis_demux_64_4.v b/rtl/axis_demux_64_4.v new file mode 100644 index 000000000..3605ff394 --- /dev/null +++ b/rtl/axis_demux_64_4.v @@ -0,0 +1,271 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream 4 port demultiplexer (64 bit datapath) + */ +module axis_demux_64_4 # +( + 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 outputs + */ + output wire [DATA_WIDTH-1:0] output_0_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, + output wire output_0_axis_tvalid, + input wire output_0_axis_tready, + output wire output_0_axis_tlast, + output wire output_0_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_1_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, + output wire output_1_axis_tvalid, + input wire output_1_axis_tready, + output wire output_1_axis_tlast, + output wire output_1_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_2_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, + output wire output_2_axis_tvalid, + input wire output_2_axis_tready, + output wire output_2_axis_tlast, + output wire output_2_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_3_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, + output wire output_3_axis_tvalid, + input wire output_3_axis_tready, + output wire output_3_axis_tlast, + output wire output_3_axis_tuser, + + /* + * Control + */ + input wire [1:0] select +); + +// // internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +// mux for output control signals +reg current_output_tready; +reg current_output_tvalid; +always @* begin + case (select_reg) + 2'd0: begin + current_output_tvalid = output_0_axis_tvalid; + current_output_tready = output_0_axis_tready; + end + 2'd1: begin + current_output_tvalid = output_1_axis_tvalid; + current_output_tready = output_1_axis_tready; + end + 2'd2: begin + current_output_tvalid = output_2_axis_tvalid; + current_output_tready = output_2_axis_tready; + end + 2'd3: begin + current_output_tvalid = output_3_axis_tvalid; + current_output_tready = output_3_axis_tready; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_axis_tready_next = 0; + + if (frame_reg) begin + if (input_axis_tvalid & input_axis_tready) begin + // end of frame detection + frame_next = ~input_axis_tlast; + end + end else if (input_axis_tvalid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + end + + input_axis_tready_next = output_axis_tready_int_early & frame_next; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_axis_tready_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_axis_tready_reg <= input_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg output_0_axis_tvalid_reg = 0; +reg output_1_axis_tvalid_reg = 0; +reg output_2_axis_tvalid_reg = 0; +reg output_3_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_0_axis_tdata = output_axis_tdata_reg; +assign output_0_axis_tkeep = output_axis_tkeep_reg; +assign output_0_axis_tvalid = output_0_axis_tvalid_reg; +assign output_0_axis_tlast = output_axis_tlast_reg; +assign output_0_axis_tuser = output_axis_tuser_reg; + +assign output_1_axis_tdata = output_axis_tdata_reg; +assign output_1_axis_tkeep = output_axis_tkeep_reg; +assign output_1_axis_tvalid = output_1_axis_tvalid_reg; +assign output_1_axis_tlast = output_axis_tlast_reg; +assign output_1_axis_tuser = output_axis_tuser_reg; + +assign output_2_axis_tdata = output_axis_tdata_reg; +assign output_2_axis_tkeep = output_axis_tkeep_reg; +assign output_2_axis_tvalid = output_2_axis_tvalid_reg; +assign output_2_axis_tlast = output_axis_tlast_reg; +assign output_2_axis_tuser = output_axis_tuser_reg; + +assign output_3_axis_tdata = output_axis_tdata_reg; +assign output_3_axis_tkeep = output_axis_tkeep_reg; +assign output_3_axis_tvalid = output_3_axis_tvalid_reg; +assign output_3_axis_tlast = output_axis_tlast_reg; +assign output_3_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_0_axis_tvalid_reg <= 0; + output_1_axis_tvalid_reg <= 0; + output_2_axis_tvalid_reg <= 0; + output_3_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + case (select_reg) + 2'd0: output_0_axis_tvalid_reg <= output_axis_tvalid_int; + 2'd1: output_1_axis_tvalid_reg <= output_axis_tvalid_int; + 2'd2: output_2_axis_tvalid_reg <= output_axis_tvalid_int; + 2'd3: output_3_axis_tvalid_reg <= output_axis_tvalid_int; + endcase + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + case (select_reg) + 2'd0: output_0_axis_tvalid_reg <= temp_axis_tvalid_reg; + 2'd1: output_1_axis_tvalid_reg <= temp_axis_tvalid_reg; + 2'd2: output_2_axis_tvalid_reg <= temp_axis_tvalid_reg; + 2'd3: output_3_axis_tvalid_reg <= temp_axis_tvalid_reg; + endcase + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py new file mode 100755 index 000000000..d6a56083c --- /dev/null +++ b/tb/test_axis_demux_4.py @@ -0,0 +1,500 @@ +#!/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_demux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_demux_4(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tready, + output_0_axis_tlast, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tready, + output_1_axis_tlast, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tready, + output_2_axis_tlast, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tready, + output_3_axis_tlast, + output_3_axis_tuser, + + select): + + 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_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tready=output_0_axis_tready, + output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tuser=output_0_axis_tuser, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tready=output_1_axis_tready, + output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tuser=output_1_axis_tuser, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tready=output_2_axis_tready, + output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tuser=output_2_axis_tuser, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tready=output_3_axis_tready, + output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tuser=output_3_axis_tuser, + + select=select) + +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_0_axis_tready = Signal(bool(0)) + output_1_axis_tready = Signal(bool(0)) + output_2_axis_tready = Signal(bool(0)) + output_3_axis_tready = Signal(bool(0)) + + select = Signal(intbv(0)[2:]) + + # Outputs + input_axis_tready = Signal(bool(0)) + + output_0_axis_tdata = Signal(intbv(0)[8:]) + output_0_axis_tvalid = Signal(bool(0)) + output_0_axis_tlast = Signal(bool(0)) + output_0_axis_tuser = Signal(bool(0)) + output_1_axis_tdata = Signal(intbv(0)[8:]) + output_1_axis_tvalid = Signal(bool(0)) + output_1_axis_tlast = Signal(bool(0)) + output_1_axis_tuser = Signal(bool(0)) + output_2_axis_tdata = Signal(intbv(0)[8:]) + output_2_axis_tvalid = Signal(bool(0)) + output_2_axis_tlast = Signal(bool(0)) + output_2_axis_tuser = Signal(bool(0)) + output_3_axis_tdata = Signal(intbv(0)[8:]) + output_3_axis_tvalid = Signal(bool(0)) + output_3_axis_tlast = Signal(bool(0)) + output_3_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_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_0 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_0_axis_tdata, + tvalid=output_0_axis_tvalid, + tready=output_0_axis_tready, + tlast=output_0_axis_tlast, + tuser=output_0_axis_tuser, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + + sink_1 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_1_axis_tdata, + tvalid=output_1_axis_tvalid, + tready=output_1_axis_tready, + tlast=output_1_axis_tlast, + tuser=output_1_axis_tuser, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + + sink_2 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_2_axis_tdata, + tvalid=output_2_axis_tvalid, + tready=output_2_axis_tready, + tlast=output_2_axis_tlast, + tuser=output_2_axis_tuser, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + + sink_3 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_3_axis_tdata, + tvalid=output_3_axis_tvalid, + tready=output_3_axis_tready, + tlast=output_3_axis_tlast, + tuser=output_3_axis_tuser, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_axis_demux_4(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tready, + output_0_axis_tlast, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tready, + output_1_axis_tlast, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tready, + output_2_axis_tlast, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tready, + output_3_axis_tlast, + output_3_axis_tuser, + + select) + + @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: select port 0") + current_test.next = 1 + + select.next = 0 + + 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 + + while input_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.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 + + while input_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = 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_frame2 = 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_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid: + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid: + sink_0_pause.next = True + sink_1_pause.next = True + sink_2_pause.next = True + sink_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_0_pause.next = False + sink_1_pause.next = False + sink_2_pause.next = False + sink_3_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + raise StopSimulation + + return dut, source, sink_0, sink_1, sink_2, sink_3, 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() + diff --git a/tb/test_axis_demux_4.v b/tb/test_axis_demux_4.v new file mode 100644 index 000000000..056b23ff4 --- /dev/null +++ b/tb/test_axis_demux_4.v @@ -0,0 +1,142 @@ +/* + +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_demux_4; + +// 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_0_axis_tready = 0; +reg output_1_axis_tready = 0; +reg output_2_axis_tready = 0; +reg output_3_axis_tready = 0; + +reg [1:0] select = 0; + +// Outputs +wire input_axis_tready; + +wire [7:0] output_0_axis_tdata; +wire output_0_axis_tvalid; +wire output_0_axis_tlast; +wire output_0_axis_tuser; +wire [7:0] output_1_axis_tdata; +wire output_1_axis_tvalid; +wire output_1_axis_tlast; +wire output_1_axis_tuser; +wire [7:0] output_2_axis_tdata; +wire output_2_axis_tvalid; +wire output_2_axis_tlast; +wire output_2_axis_tuser; +wire [7:0] output_3_axis_tdata; +wire output_3_axis_tvalid; +wire output_3_axis_tlast; +wire output_3_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_0_axis_tready, + output_1_axis_tready, + output_2_axis_tready, + output_3_axis_tready, + select); + $to_myhdl(input_axis_tready, + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tlast, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tlast, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tlast, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tlast, + output_3_axis_tuser); + + // dump file + $dumpfile("test_axis_demux_4.lxt"); + $dumpvars(0, test_axis_demux_4); +end + +axis_demux_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 outputs + .output_0_axis_tdata(output_0_axis_tdata), + .output_0_axis_tvalid(output_0_axis_tvalid), + .output_0_axis_tready(output_0_axis_tready), + .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tuser(output_0_axis_tuser), + .output_1_axis_tdata(output_1_axis_tdata), + .output_1_axis_tvalid(output_1_axis_tvalid), + .output_1_axis_tready(output_1_axis_tready), + .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tuser(output_1_axis_tuser), + .output_2_axis_tdata(output_2_axis_tdata), + .output_2_axis_tvalid(output_2_axis_tvalid), + .output_2_axis_tready(output_2_axis_tready), + .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tuser(output_2_axis_tuser), + .output_3_axis_tdata(output_3_axis_tdata), + .output_3_axis_tvalid(output_3_axis_tvalid), + .output_3_axis_tready(output_3_axis_tready), + .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tuser(output_3_axis_tuser), + // Control + .select(select) +); + +endmodule diff --git a/tb/test_axis_demux_64_4.py b/tb/test_axis_demux_64_4.py new file mode 100755 index 000000000..05e3fb06d --- /dev/null +++ b/tb/test_axis_demux_64_4.py @@ -0,0 +1,525 @@ +#!/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_demux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_demux_64_4(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tready, + output_0_axis_tlast, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tready, + output_1_axis_tlast, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tready, + output_2_axis_tlast, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tready, + output_3_axis_tlast, + output_3_axis_tuser, + + select): + + 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_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tkeep=output_0_axis_tkeep, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tready=output_0_axis_tready, + output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tuser=output_0_axis_tuser, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tkeep=output_1_axis_tkeep, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tready=output_1_axis_tready, + output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tuser=output_1_axis_tuser, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tkeep=output_2_axis_tkeep, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tready=output_2_axis_tready, + output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tuser=output_2_axis_tuser, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tkeep=output_3_axis_tkeep, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tready=output_3_axis_tready, + output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tuser=output_3_axis_tuser, + + select=select) + +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_0_axis_tready = Signal(bool(0)) + output_1_axis_tready = Signal(bool(0)) + output_2_axis_tready = Signal(bool(0)) + output_3_axis_tready = Signal(bool(0)) + + select = Signal(intbv(0)[2:]) + + # Outputs + input_axis_tready = Signal(bool(0)) + + output_0_axis_tdata = Signal(intbv(0)[64:]) + output_0_axis_tkeep = Signal(intbv(0)[8:]) + output_0_axis_tvalid = Signal(bool(0)) + output_0_axis_tlast = Signal(bool(0)) + output_0_axis_tuser = Signal(bool(0)) + output_1_axis_tdata = Signal(intbv(0)[64:]) + output_1_axis_tkeep = Signal(intbv(0)[8:]) + output_1_axis_tvalid = Signal(bool(0)) + output_1_axis_tlast = Signal(bool(0)) + output_1_axis_tuser = Signal(bool(0)) + output_2_axis_tdata = Signal(intbv(0)[64:]) + output_2_axis_tkeep = Signal(intbv(0)[8:]) + output_2_axis_tvalid = Signal(bool(0)) + output_2_axis_tlast = Signal(bool(0)) + output_2_axis_tuser = Signal(bool(0)) + output_3_axis_tdata = Signal(intbv(0)[64:]) + output_3_axis_tkeep = Signal(intbv(0)[8:]) + output_3_axis_tvalid = Signal(bool(0)) + output_3_axis_tlast = Signal(bool(0)) + output_3_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_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_0 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_0_axis_tdata, + tkeep=output_0_axis_tkeep, + tvalid=output_0_axis_tvalid, + tready=output_0_axis_tready, + tlast=output_0_axis_tlast, + tuser=output_0_axis_tuser, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + + sink_1 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_1_axis_tdata, + tkeep=output_1_axis_tkeep, + tvalid=output_1_axis_tvalid, + tready=output_1_axis_tready, + tlast=output_1_axis_tlast, + tuser=output_1_axis_tuser, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + + sink_2 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_2_axis_tdata, + tkeep=output_2_axis_tkeep, + tvalid=output_2_axis_tvalid, + tready=output_2_axis_tready, + tlast=output_2_axis_tlast, + tuser=output_2_axis_tuser, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + + sink_3 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_3_axis_tdata, + tkeep=output_3_axis_tkeep, + tvalid=output_3_axis_tvalid, + tready=output_3_axis_tready, + tlast=output_3_axis_tlast, + tuser=output_3_axis_tuser, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_axis_demux_64_4(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tready, + output_0_axis_tlast, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tready, + output_1_axis_tlast, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tready, + output_2_axis_tlast, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tready, + output_3_axis_tlast, + output_3_axis_tuser, + + select) + + @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: select port 0") + current_test.next = 1 + + select.next = 0 + + 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 + + while input_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.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 + + while input_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = 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_frame2 = 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_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid: + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = 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_frame2 = 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_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_axis_tvalid: + sink_0_pause.next = True + sink_1_pause.next = True + sink_2_pause.next = True + sink_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_0_pause.next = False + sink_1_pause.next = False + sink_2_pause.next = False + sink_3_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + raise StopSimulation + + return dut, source, sink_0, sink_1, sink_2, sink_3, 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() + diff --git a/tb/test_axis_demux_64_4.v b/tb/test_axis_demux_64_4.v new file mode 100644 index 000000000..70528466f --- /dev/null +++ b/tb/test_axis_demux_64_4.v @@ -0,0 +1,157 @@ +/* + +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_demux_64_4; + +// 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_0_axis_tready = 0; +reg output_1_axis_tready = 0; +reg output_2_axis_tready = 0; +reg output_3_axis_tready = 0; + +reg [1:0] select = 0; + +// Outputs +wire input_axis_tready; + +wire [63:0] output_0_axis_tdata; +wire [7:0] output_0_axis_tkeep; +wire output_0_axis_tvalid; +wire output_0_axis_tlast; +wire output_0_axis_tuser; +wire [63:0] output_1_axis_tdata; +wire [7:0] output_1_axis_tkeep; +wire output_1_axis_tvalid; +wire output_1_axis_tlast; +wire output_1_axis_tuser; +wire [63:0] output_2_axis_tdata; +wire [7:0] output_2_axis_tkeep; +wire output_2_axis_tvalid; +wire output_2_axis_tlast; +wire output_2_axis_tuser; +wire [63:0] output_3_axis_tdata; +wire [7:0] output_3_axis_tkeep; +wire output_3_axis_tvalid; +wire output_3_axis_tlast; +wire output_3_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_0_axis_tready, + output_1_axis_tready, + output_2_axis_tready, + output_3_axis_tready, + select); + $to_myhdl(input_axis_tready, + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tlast, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tlast, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tlast, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tlast, + output_3_axis_tuser); + + // dump file + $dumpfile("test_axis_demux_64_4.lxt"); + $dumpvars(0, test_axis_demux_64_4); +end + +axis_demux_64_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 outputs + .output_0_axis_tdata(output_0_axis_tdata), + .output_0_axis_tkeep(output_0_axis_tkeep), + .output_0_axis_tvalid(output_0_axis_tvalid), + .output_0_axis_tready(output_0_axis_tready), + .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tuser(output_0_axis_tuser), + .output_1_axis_tdata(output_1_axis_tdata), + .output_1_axis_tkeep(output_1_axis_tkeep), + .output_1_axis_tvalid(output_1_axis_tvalid), + .output_1_axis_tready(output_1_axis_tready), + .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tuser(output_1_axis_tuser), + .output_2_axis_tdata(output_2_axis_tdata), + .output_2_axis_tkeep(output_2_axis_tkeep), + .output_2_axis_tvalid(output_2_axis_tvalid), + .output_2_axis_tready(output_2_axis_tready), + .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tuser(output_2_axis_tuser), + .output_3_axis_tdata(output_3_axis_tdata), + .output_3_axis_tkeep(output_3_axis_tkeep), + .output_3_axis_tvalid(output_3_axis_tvalid), + .output_3_axis_tready(output_3_axis_tready), + .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tuser(output_3_axis_tuser), + // Control + .select(select) +); + +endmodule From 3399f284b2f70036408f094926f0ca823bbad5b1 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 12 Nov 2014 23:59:02 -0800 Subject: [PATCH 088/617] Add priority encoder --- rtl/priority_encoder.v | 82 ++++++++++++++++++++ tb/test_priority_encoder.py | 147 ++++++++++++++++++++++++++++++++++++ tb/test_priority_encoder.v | 71 +++++++++++++++++ 3 files changed, 300 insertions(+) create mode 100644 rtl/priority_encoder.v create mode 100755 tb/test_priority_encoder.py create mode 100644 tb/test_priority_encoder.v diff --git a/rtl/priority_encoder.v b/rtl/priority_encoder.v new file mode 100644 index 000000000..03af53fe9 --- /dev/null +++ b/rtl/priority_encoder.v @@ -0,0 +1,82 @@ +/* + +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 + +/* + * Priority encoder module + */ +module priority_encoder # +( + parameter WIDTH = 4 +) +( + input wire [WIDTH-1:0] input_unencoded, + output wire output_valid, + output wire [$clog2(WIDTH)-1:0] output_encoded, + output wire [WIDTH-1:0] output_unencoded +); + +// power-of-two width +localparam W1 = 2**$clog2(WIDTH); +localparam W2 = W1/2; + +generate + if (WIDTH == 2) begin + // two inputs - just an OR gate + assign output_valid = |input_unencoded; + assign output_encoded = input_unencoded[1]; + end else begin + // more than two inputs - split into two parts and recurse + // also pad input to correct power-of-two width + wire [$clog2(W2)-1:0] out1, out2; + wire valid1, valid2; + priority_encoder #( + .WIDTH(W2) + ) + priority_encoder_inst1 ( + .input_unencoded(input_unencoded[W2-1:0]), + .output_valid(valid1), + .output_encoded(out1) + ); + priority_encoder #( + .WIDTH(W2) + ) + priority_encoder_inst2 ( + .input_unencoded({{W1-WIDTH{1'b0}}, input_unencoded[WIDTH-1:W2]}), + .output_valid(valid2), + .output_encoded(out2) + ); + // multiplexer to select part + assign output_valid = valid1 | valid2; + assign output_encoded = valid2 ? {1'b1, out2} : {1'b0, out1}; + end +endgenerate + +// unencoded output +assign output_unencoded = 1 << output_encoded; + +endmodule diff --git a/tb/test_priority_encoder.py b/tb/test_priority_encoder.py new file mode 100755 index 000000000..143aa9bb6 --- /dev/null +++ b/tb/test_priority_encoder.py @@ -0,0 +1,147 @@ +#!/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 + +module = 'priority_encoder' + +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_priority_encoder(clk, + rst, + current_test, + + input_unencoded, + + output_valid, + output_encoded, + output_unencoded): + + 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_unencoded=input_unencoded, + + output_valid=output_valid, + output_encoded=output_encoded, + output_unencoded=output_unencoded) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_unencoded = Signal(intbv(0)[32:]) + + # Outputs + output_valid = Signal(bool(0)) + output_encoded = Signal(intbv(0)[5:]) + output_unencoded = Signal(intbv(0)[32:]) + + # DUT + dut = dut_priority_encoder(clk, + rst, + current_test, + + input_unencoded, + + output_valid, + output_encoded, + output_unencoded) + + @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 + + print("test 1: one bit") + current_test.next = 1 + + for i in range(32): + input_unencoded.next = 1 << i + + yield clk.posedge + + assert output_encoded == i + assert output_unencoded == 1 << i + + yield delay(100) + + yield clk.posedge + + print("test 2: two bits") + current_test.next = 2 + + for i in range(32): + for j in range(32): + + input_unencoded.next = (1 << i) | (1 << j) + + yield clk.posedge + + assert output_encoded == max(i,j) + assert output_unencoded == 1 << max(i,j) + + yield delay(100) + + raise StopSimulation + + return dut, 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() + diff --git a/tb/test_priority_encoder.v b/tb/test_priority_encoder.v new file mode 100644 index 000000000..af7f07882 --- /dev/null +++ b/tb/test_priority_encoder.v @@ -0,0 +1,71 @@ +/* + +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_priority_encoder; + +// parameters +localparam WIDTH = 32; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [WIDTH-1:0] input_unencoded = 0; + +// Outputs +wire output_valid; +wire [$clog2(WIDTH)-1:0] output_encoded; +wire [WIDTH-1:0] output_unencoded; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_unencoded); + $to_myhdl(output_valid, + output_encoded, + output_unencoded); + + // dump file + $dumpfile("test_priority_encoder.lxt"); + $dumpvars(0, test_priority_encoder); +end + +priority_encoder #( + .WIDTH(WIDTH) +) +UUT ( + .input_unencoded(input_unencoded), + .output_valid(output_valid), + .output_encoded(output_encoded), + .output_unencoded(output_unencoded) +); + +endmodule From a1633f27d8d4628ca70441f065f4a085c0525864 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 13 Nov 2014 01:22:59 -0800 Subject: [PATCH 089/617] Add arbiter module --- rtl/arbiter.v | 135 ++++++++++++++++++++++++ tb/test_arbiter.py | 176 +++++++++++++++++++++++++++++++ tb/test_arbiter.v | 77 ++++++++++++++ tb/test_arbiter_rr.py | 233 ++++++++++++++++++++++++++++++++++++++++++ tb/test_arbiter_rr.v | 77 ++++++++++++++ 5 files changed, 698 insertions(+) create mode 100644 rtl/arbiter.v create mode 100755 tb/test_arbiter.py create mode 100644 tb/test_arbiter.v create mode 100755 tb/test_arbiter_rr.py create mode 100644 tb/test_arbiter_rr.v diff --git a/rtl/arbiter.v b/rtl/arbiter.v new file mode 100644 index 000000000..17261352b --- /dev/null +++ b/rtl/arbiter.v @@ -0,0 +1,135 @@ +/* + +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 + +/* + * Arbiter module + */ +module arbiter # +( + parameter PORTS = 4, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter TYPE = "PRIORITY", + // block until request deassert: "TRUE" or "FALSE" + parameter BLOCK = "TRUE" +) +( + input wire clk, + input wire rst, + + input wire [PORTS-1:0] request, + + output wire [PORTS-1:0] grant, + output wire grant_valid, + output wire [$clog2(PORTS)-1:0] grant_encoded +); + +reg [PORTS-1:0] grant_reg = 0, grant_next; +reg grant_valid_reg = 0, grant_valid_next; +reg [$clog2(PORTS)-1:0] grant_encoded_reg = 0, grant_encoded_next; + +assign grant_valid = grant_valid_reg; +assign grant = grant_reg; +assign grant_encoded = grant_encoded_reg; + +wire request_valid; +wire [$clog2(PORTS)-1:0] request_index; +wire [PORTS-1:0] request_mask; + +priority_encoder #( + .WIDTH(PORTS) +) +priority_encoder_inst ( + .input_unencoded(request), + .output_valid(request_valid), + .output_encoded(request_index), + .output_unencoded(request_mask) +); + +reg [PORTS-1:0] mask_reg = 0, mask_next; + +wire masked_request_valid; +wire [$clog2(PORTS)-1:0] masked_request_index; +wire [PORTS-1:0] masked_request_mask; + +priority_encoder #( + .WIDTH(PORTS) +) +priority_encoder_masked ( + .input_unencoded(request & mask_reg), + .output_valid(masked_request_valid), + .output_encoded(masked_request_index), + .output_unencoded(masked_request_mask) +); + +always @* begin + grant_next = 0; + grant_valid_next = 0; + grant_encoded_next = 0; + mask_next = mask_reg; + + if (BLOCK == "TRUE" && grant_reg & request) begin + // granted request still asserted; hold it + grant_valid_next = grant_valid_reg; + grant_next = grant_reg; + grant_encoded_next = grant_encoded_reg; + end else if (request_valid) begin + if (TYPE == "PRIORITY") begin + grant_valid_next = 1; + grant_next = request_mask; + grant_encoded_next = request_index; + end else if (TYPE == "ROUND_ROBIN") begin + if (masked_request_valid) begin + grant_valid_next = 1; + grant_next = masked_request_mask; + grant_encoded_next = masked_request_index; + mask_next = {PORTS{1'b1}} >> (PORTS - masked_request_index); + end else begin + grant_valid_next = 1; + grant_next = request_mask; + grant_encoded_next = request_index; + mask_next = {PORTS{1'b1}} >> (PORTS - request_index); + end + end + end +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + grant_reg <= 0; + grant_valid_reg <= 0; + grant_encoded_reg <= 0; + mask_reg <= 0; + end else begin + grant_reg <= grant_next; + grant_valid_reg <= grant_valid_next; + grant_encoded_reg <= grant_encoded_next; + mask_reg <= mask_next; + end +end + +endmodule diff --git a/tb/test_arbiter.py b/tb/test_arbiter.py new file mode 100755 index 000000000..872adb5d2 --- /dev/null +++ b/tb/test_arbiter.py @@ -0,0 +1,176 @@ +#!/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 + +module = 'arbiter' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_arbiter(clk, + rst, + current_test, + + request, + + grant, + grant_valid, + grant_encoded): + + 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, + + request=request, + + grant=grant, + grant_valid=grant_valid, + grant_encoded=grant_encoded) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + request = Signal(intbv(0)[32:]) + + # Outputs + grant = Signal(intbv(0)[32:]) + grant_valid = Signal(bool(0)) + grant_encoded = Signal(intbv(0)[5:]) + + # DUT + dut = dut_arbiter(clk, + rst, + current_test, + + request, + + grant, + grant_valid, + grant_encoded) + + @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 + + print("test 1: one bit") + current_test.next = 1 + + yield clk.posedge + + for i in range(32): + l = [i] + request.next = reduce(lambda x, y: x|y, [1< Date: Thu, 13 Nov 2014 02:01:07 -0800 Subject: [PATCH 090/617] Change block parameter --- rtl/arbiter.v | 10 ++++++++-- tb/test_arbiter.py | 4 ++++ tb/test_arbiter.v | 7 +++++-- tb/test_arbiter_rr.py | 4 ++++ tb/test_arbiter_rr.v | 7 +++++-- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/rtl/arbiter.v b/rtl/arbiter.v index 17261352b..71ca40107 100644 --- a/rtl/arbiter.v +++ b/rtl/arbiter.v @@ -34,7 +34,7 @@ module arbiter # parameter PORTS = 4, // arbitration type: "PRIORITY" or "ROUND_ROBIN" parameter TYPE = "PRIORITY", - // block until request deassert: "TRUE" or "FALSE" + // block type: "NONE", "REQUEST", "ACKNOWLEDGE" parameter BLOCK = "TRUE" ) ( @@ -42,6 +42,7 @@ module arbiter # input wire rst, input wire [PORTS-1:0] request, + input wire [PORTS-1:0] acknowledge, output wire [PORTS-1:0] grant, output wire grant_valid, @@ -92,11 +93,16 @@ always @* begin grant_encoded_next = 0; mask_next = mask_reg; - if (BLOCK == "TRUE" && grant_reg & request) begin + if (BLOCK == "REQUEST" && grant_reg & request) begin // granted request still asserted; hold it grant_valid_next = grant_valid_reg; grant_next = grant_reg; grant_encoded_next = grant_encoded_reg; + end else if (BLOCK == "ACKNOWLEDGE" && grant_valid && !(grant_reg & acknowledge)) begin + // granted request not yet acknowledged; hold it + grant_valid_next = grant_valid_reg; + grant_next = grant_reg; + grant_encoded_next = grant_encoded_reg; end else if (request_valid) begin if (TYPE == "PRIORITY") begin grant_valid_next = 1; diff --git a/tb/test_arbiter.py b/tb/test_arbiter.py index 872adb5d2..6d85b1a93 100755 --- a/tb/test_arbiter.py +++ b/tb/test_arbiter.py @@ -43,6 +43,7 @@ def dut_arbiter(clk, current_test, request, + acknowledge, grant, grant_valid, @@ -56,6 +57,7 @@ def dut_arbiter(clk, current_test=current_test, request=request, + acknowledge=acknowledge, grant=grant, grant_valid=grant_valid, @@ -69,6 +71,7 @@ def bench(): current_test = Signal(intbv(0)[8:]) request = Signal(intbv(0)[32:]) + acknowledge = Signal(intbv(0)[32:]) # Outputs grant = Signal(intbv(0)[32:]) @@ -81,6 +84,7 @@ def bench(): current_test, request, + acknowledge, grant, grant_valid, diff --git a/tb/test_arbiter.v b/tb/test_arbiter.v index 28038ba56..5f206a52d 100644 --- a/tb/test_arbiter.v +++ b/tb/test_arbiter.v @@ -31,7 +31,7 @@ module test_arbiter; // parameters localparam PORTS = 32; localparam TYPE = "PRIORITY"; -localparam BLOCK = "TRUE"; +localparam BLOCK = "REQUEST"; // Inputs reg clk = 0; @@ -39,6 +39,7 @@ reg rst = 0; reg [7:0] current_test = 0; reg [PORTS-1:0] request = 0; +reg [PORTS-1:0] acknowledge = 0; // Outputs wire [PORTS-1:0] grant; @@ -50,7 +51,8 @@ initial begin $from_myhdl(clk, rst, current_test, - request); + request, + acknowledge); $to_myhdl(grant, grant_valid, grant_encoded); @@ -69,6 +71,7 @@ UUT ( .clk(clk), .rst(rst), .request(request), + .acknowledge(acknowledge), .grant(grant), .grant_valid(grant_valid), .grant_encoded(grant_encoded) diff --git a/tb/test_arbiter_rr.py b/tb/test_arbiter_rr.py index f2802189f..02c032eda 100755 --- a/tb/test_arbiter_rr.py +++ b/tb/test_arbiter_rr.py @@ -43,6 +43,7 @@ def dut_arbiter_rr(clk, current_test, request, + acknowledge, grant, grant_valid, @@ -56,6 +57,7 @@ def dut_arbiter_rr(clk, current_test=current_test, request=request, + acknowledge=acknowledge, grant=grant, grant_valid=grant_valid, @@ -69,6 +71,7 @@ def bench(): current_test = Signal(intbv(0)[8:]) request = Signal(intbv(0)[32:]) + acknowledge = Signal(intbv(0)[32:]) # Outputs grant = Signal(intbv(0)[32:]) @@ -81,6 +84,7 @@ def bench(): current_test, request, + acknowledge, grant, grant_valid, diff --git a/tb/test_arbiter_rr.v b/tb/test_arbiter_rr.v index 1e2ec7515..93a4cce70 100644 --- a/tb/test_arbiter_rr.v +++ b/tb/test_arbiter_rr.v @@ -31,7 +31,7 @@ module test_arbiter_rr; // parameters localparam PORTS = 32; localparam TYPE = "ROUND_ROBIN"; -localparam BLOCK = "TRUE"; +localparam BLOCK = "REQUEST"; // Inputs reg clk = 0; @@ -39,6 +39,7 @@ reg rst = 0; reg [7:0] current_test = 0; reg [PORTS-1:0] request = 0; +reg [PORTS-1:0] acknowledge = 0; // Outputs wire [PORTS-1:0] grant; @@ -50,7 +51,8 @@ initial begin $from_myhdl(clk, rst, current_test, - request); + request, + acknowledge); $to_myhdl(grant, grant_valid, grant_encoded); @@ -69,6 +71,7 @@ UUT ( .clk(clk), .rst(rst), .request(request), + .acknowledge(acknowledge), .grant(grant), .grant_valid(grant_valid), .grant_encoded(grant_encoded) From 5f0d23a3ad68b64c8cc883d86c0fa7cec16f79ec Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 13 Nov 2014 02:01:45 -0800 Subject: [PATCH 091/617] Add AXI arbitrated mux module and testbench --- rtl/axis_arb_mux.py | 193 ++++++++++++ rtl/axis_arb_mux_4.v | 143 +++++++++ rtl/axis_arb_mux_64.py | 198 ++++++++++++ rtl/axis_arb_mux_64_4.v | 154 ++++++++++ tb/test_axis_arb_mux_4.py | 544 +++++++++++++++++++++++++++++++++ tb/test_axis_arb_mux_4.v | 137 +++++++++ tb/test_axis_arb_mux_64_4.py | 569 +++++++++++++++++++++++++++++++++++ tb/test_axis_arb_mux_64_4.v | 152 ++++++++++ 8 files changed, 2090 insertions(+) create mode 100755 rtl/axis_arb_mux.py create mode 100644 rtl/axis_arb_mux_4.v create mode 100755 rtl/axis_arb_mux_64.py create mode 100644 rtl/axis_arb_mux_64_4.v create mode 100755 tb/test_axis_arb_mux_4.py create mode 100644 tb/test_axis_arb_mux_4.v create mode 100755 tb/test_axis_arb_mux_64_4.py create mode 100644 tb/test_axis_arb_mux_64_4.v diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py new file mode 100755 index 000000000..b1223060c --- /dev/null +++ b/rtl/axis_arb_mux.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python +"""axis_mux + +Generates an arbitrated AXI Stream mux with the specified number of ports + +Usage: axis_crosspoint [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "axis_arb_mux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port arbitrated multiplexer + */ +module {{name}} # +( + parameter DATA_WIDTH = 8, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY" +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ +{%- for p in ports %} + input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire input_{{p}}_axis_tvalid, + output wire input_{{p}}_axis_tready, + input wire input_{{p}}_axis_tlast, + input wire input_{{p}}_axis_tuser, +{% endfor %} + /* + * AXI output + */ + output wire [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 +); + +wire [{{n-1}}:0] request; +wire [{{n-1}}:0] acknowledge; +wire [{{n-1}}:0] grant; +wire [{{w-1}}:0] grant_encoded; +{% for p in ports %} +assign acknowledge[{{p}}] = input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast; +assign request[{{p}}] = input_{{p}}_axis_tvalid & ~acknowledge[{{p}}]; +{%- endfor %} + +// mux instance +axis_mux_{{n}} #( + .DATA_WIDTH(DATA_WIDTH) +) +mux_inst ( + .clk(clk), + .rst(rst), +{%- for p in ports %} + .input_{{p}}_axis_tdata(input_{{p}}_axis_tdata), + .input_{{p}}_axis_tvalid(input_{{p}}_axis_tvalid & grant[{{p}}]), + .input_{{p}}_axis_tready(input_{{p}}_axis_tready), + .input_{{p}}_axis_tlast(input_{{p}}_axis_tlast), + .input_{{p}}_axis_tuser(input_{{p}}_axis_tuser), +{%- endfor %} + .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), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS({{n}}), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE") +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_encoded(grant_encoded) +); + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/axis_arb_mux_4.v b/rtl/axis_arb_mux_4.v new file mode 100644 index 000000000..ac24f9193 --- /dev/null +++ b/rtl/axis_arb_mux_4.v @@ -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 4 port arbitrated multiplexer + */ +module axis_arb_mux_4 # +( + parameter DATA_WIDTH = 8, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY" +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ + input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire input_0_axis_tvalid, + output wire input_0_axis_tready, + input wire input_0_axis_tlast, + input wire input_0_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire input_1_axis_tvalid, + output wire input_1_axis_tready, + input wire input_1_axis_tlast, + input wire input_1_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire input_2_axis_tvalid, + output wire input_2_axis_tready, + input wire input_2_axis_tlast, + input wire input_2_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire input_3_axis_tvalid, + output wire input_3_axis_tready, + input wire input_3_axis_tlast, + input wire input_3_axis_tuser, + + /* + * AXI output + */ + output wire [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 +); + +wire [3:0] request; +wire [3:0] acknowledge; +wire [3:0] grant; +wire [1:0] grant_encoded; + +assign acknowledge[0] = input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign request[0] = input_0_axis_tvalid & ~acknowledge[0]; +assign acknowledge[1] = input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign request[1] = input_1_axis_tvalid & ~acknowledge[1]; +assign acknowledge[2] = input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign request[2] = input_2_axis_tvalid & ~acknowledge[2]; +assign acknowledge[3] = input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; +assign request[3] = input_3_axis_tvalid & ~acknowledge[3]; + +// mux instance +axis_mux_4 #( + .DATA_WIDTH(DATA_WIDTH) +) +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tvalid(input_0_axis_tvalid & grant[0]), + .input_0_axis_tready(input_0_axis_tready), + .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tuser(input_0_axis_tuser), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tvalid(input_1_axis_tvalid & grant[1]), + .input_1_axis_tready(input_1_axis_tready), + .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tuser(input_1_axis_tuser), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tvalid(input_2_axis_tvalid & grant[2]), + .input_2_axis_tready(input_2_axis_tready), + .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tuser(input_2_axis_tuser), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tvalid(input_3_axis_tvalid & grant[3]), + .input_3_axis_tready(input_3_axis_tready), + .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tuser(input_3_axis_tuser), + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE") +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/rtl/axis_arb_mux_64.py b/rtl/axis_arb_mux_64.py new file mode 100755 index 000000000..6b05df0cb --- /dev/null +++ b/rtl/axis_arb_mux_64.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python +"""axis_mux + +Generates an arbitrated AXI Stream mux with the specified number of ports + +Usage: axis_crosspoint [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "axis_arb_mux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port arbitrated multiplexer (64 bit datapath) + */ +module {{name}} # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY" +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ +{%- for p in ports %} + input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, + input wire input_{{p}}_axis_tvalid, + output wire input_{{p}}_axis_tready, + input wire input_{{p}}_axis_tlast, + input wire input_{{p}}_axis_tuser, +{% endfor %} + /* + * AXI output + */ + output wire [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 +); + +wire [{{n-1}}:0] request; +wire [{{n-1}}:0] acknowledge; +wire [{{n-1}}:0] grant; +wire [{{w-1}}:0] grant_encoded; +{% for p in ports %} +assign acknowledge[{{p}}] = input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast; +assign request[{{p}}] = input_{{p}}_axis_tvalid & ~acknowledge[{{p}}]; +{%- endfor %} + +// mux instance +axis_mux_64_{{n}} #( + .DATA_WIDTH(DATA_WIDTH) +) +mux_inst ( + .clk(clk), + .rst(rst), +{%- for p in ports %} + .input_{{p}}_axis_tdata(input_{{p}}_axis_tdata), + .input_{{p}}_axis_tkeep(input_{{p}}_axis_tkeep), + .input_{{p}}_axis_tvalid(input_{{p}}_axis_tvalid & grant[{{p}}]), + .input_{{p}}_axis_tready(input_{{p}}_axis_tready), + .input_{{p}}_axis_tlast(input_{{p}}_axis_tlast), + .input_{{p}}_axis_tuser(input_{{p}}_axis_tuser), +{%- endfor %} + .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), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS({{n}}), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE") +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_encoded(grant_encoded) +); + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/axis_arb_mux_64_4.v b/rtl/axis_arb_mux_64_4.v new file mode 100644 index 000000000..d44ecc5ca --- /dev/null +++ b/rtl/axis_arb_mux_64_4.v @@ -0,0 +1,154 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream 4 port arbitrated multiplexer (64 bit datapath) + */ +module axis_arb_mux_64_4 # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY" +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ + input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, + input wire input_0_axis_tvalid, + output wire input_0_axis_tready, + input wire input_0_axis_tlast, + input wire input_0_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, + input wire input_1_axis_tvalid, + output wire input_1_axis_tready, + input wire input_1_axis_tlast, + input wire input_1_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, + input wire input_2_axis_tvalid, + output wire input_2_axis_tready, + input wire input_2_axis_tlast, + input wire input_2_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, + input wire input_3_axis_tvalid, + output wire input_3_axis_tready, + input wire input_3_axis_tlast, + input wire input_3_axis_tuser, + + /* + * AXI output + */ + output wire [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 +); + +wire [3:0] request; +wire [3:0] acknowledge; +wire [3:0] grant; +wire [1:0] grant_encoded; + +assign acknowledge[0] = input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign request[0] = input_0_axis_tvalid & ~acknowledge[0]; +assign acknowledge[1] = input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign request[1] = input_1_axis_tvalid & ~acknowledge[1]; +assign acknowledge[2] = input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign request[2] = input_2_axis_tvalid & ~acknowledge[2]; +assign acknowledge[3] = input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; +assign request[3] = input_3_axis_tvalid & ~acknowledge[3]; + +// mux instance +axis_mux_64_4 #( + .DATA_WIDTH(DATA_WIDTH) +) +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tkeep(input_0_axis_tkeep), + .input_0_axis_tvalid(input_0_axis_tvalid & grant[0]), + .input_0_axis_tready(input_0_axis_tready), + .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tuser(input_0_axis_tuser), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tkeep(input_1_axis_tkeep), + .input_1_axis_tvalid(input_1_axis_tvalid & grant[1]), + .input_1_axis_tready(input_1_axis_tready), + .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tuser(input_1_axis_tuser), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tkeep(input_2_axis_tkeep), + .input_2_axis_tvalid(input_2_axis_tvalid & grant[2]), + .input_2_axis_tready(input_2_axis_tready), + .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tuser(input_2_axis_tuser), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tkeep(input_3_axis_tkeep), + .input_3_axis_tvalid(input_3_axis_tvalid & grant[3]), + .input_3_axis_tready(input_3_axis_tready), + .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tuser(input_3_axis_tuser), + .output_axis_tdata(output_axis_tdata), + .output_axis_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), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE") +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py new file mode 100755 index 000000000..8cd01f7fe --- /dev/null +++ b/tb/test_axis_arb_mux_4.py @@ -0,0 +1,544 @@ +#!/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_arb_mux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_mux_4.v") +srcs.append("../rtl/arbiter.v") +srcs.append("../rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_arb_mux_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_axis_tdata = Signal(intbv(0)[8:]) + input_0_axis_tvalid = Signal(bool(0)) + input_0_axis_tlast = Signal(bool(0)) + input_0_axis_tuser = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[8:]) + input_1_axis_tvalid = Signal(bool(0)) + input_1_axis_tlast = Signal(bool(0)) + input_1_axis_tuser = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[8:]) + input_2_axis_tvalid = Signal(bool(0)) + input_2_axis_tlast = Signal(bool(0)) + input_2_axis_tuser = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[8:]) + input_3_axis_tvalid = Signal(bool(0)) + input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tuser = Signal(bool(0)) + + output_axis_tready = Signal(bool(0)) + + # Outputs + input_0_axis_tready = Signal(bool(0)) + input_1_axis_tready = Signal(bool(0)) + input_2_axis_tready = Signal(bool(0)) + input_3_axis_tready = Signal(bool(0)) + + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + source_1 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + source_2 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + source_3 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + 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_arb_mux_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @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: port 0") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x00\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_0_queue.put(test_frame) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: port 1") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x01\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_1_queue.put(test_frame) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x00\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\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\x00\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x01\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\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\x02\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + 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_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x01\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\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\x02\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x01\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\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\x02\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_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_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, different ports, arbitration test") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x01\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\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\x02\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + yield clk.posedge + + yield delay(800) + yield clk.posedge + source_2_queue.put(test_frame2) + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + 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_frame2 + + 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_frame1 + + 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 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_arb_mux_4.v b/tb/test_axis_arb_mux_4.v new file mode 100644 index 000000000..a9a89daf2 --- /dev/null +++ b/tb/test_axis_arb_mux_4.v @@ -0,0 +1,137 @@ +/* + +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_arb_mux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_0_axis_tdata = 0; +reg input_0_axis_tvalid = 0; +reg input_0_axis_tlast = 0; +reg input_0_axis_tuser = 0; +reg [7:0] input_1_axis_tdata = 0; +reg input_1_axis_tvalid = 0; +reg input_1_axis_tlast = 0; +reg input_1_axis_tuser = 0; +reg [7:0] input_2_axis_tdata = 0; +reg input_2_axis_tvalid = 0; +reg input_2_axis_tlast = 0; +reg input_2_axis_tuser = 0; +reg [7:0] input_3_axis_tdata = 0; +reg input_3_axis_tvalid = 0; +reg input_3_axis_tlast = 0; +reg input_3_axis_tuser = 0; + +reg output_axis_tready = 0; + +// Outputs +wire input_0_axis_tready; +wire input_1_axis_tready; +wire input_2_axis_tready; +wire input_3_axis_tready; + +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready); + $to_myhdl(input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_arb_mux_4.lxt"); + $dumpvars(0, test_axis_arb_mux_4); +end + +axis_arb_mux_4 #( + .DATA_WIDTH(8) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI inputs + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tvalid(input_0_axis_tvalid), + .input_0_axis_tready(input_0_axis_tready), + .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tuser(input_0_axis_tuser), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tvalid(input_1_axis_tvalid), + .input_1_axis_tready(input_1_axis_tready), + .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tuser(input_1_axis_tuser), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tvalid(input_2_axis_tvalid), + .input_2_axis_tready(input_2_axis_tready), + .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tuser(input_2_axis_tuser), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tvalid(input_3_axis_tvalid), + .input_3_axis_tready(input_3_axis_tready), + .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tuser(input_3_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser) +); + +endmodule diff --git a/tb/test_axis_arb_mux_64_4.py b/tb/test_axis_arb_mux_64_4.py new file mode 100755 index 000000000..15a0e4504 --- /dev/null +++ b/tb/test_axis_arb_mux_64_4.py @@ -0,0 +1,569 @@ +#!/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_arb_mux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_mux_64_4.v") +srcs.append("../rtl/arbiter.v") +srcs.append("../rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_arb_mux_64_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_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_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_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_0_axis_tdata = Signal(intbv(0)[64:]) + input_0_axis_tkeep = Signal(intbv(0)[8:]) + input_0_axis_tvalid = Signal(bool(0)) + input_0_axis_tlast = Signal(bool(0)) + input_0_axis_tuser = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[64:]) + input_1_axis_tkeep = Signal(intbv(0)[8:]) + input_1_axis_tvalid = Signal(bool(0)) + input_1_axis_tlast = Signal(bool(0)) + input_1_axis_tuser = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[64:]) + input_2_axis_tkeep = Signal(intbv(0)[8:]) + input_2_axis_tvalid = Signal(bool(0)) + input_2_axis_tlast = Signal(bool(0)) + input_2_axis_tuser = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[64:]) + input_3_axis_tkeep = Signal(intbv(0)[8:]) + input_3_axis_tvalid = Signal(bool(0)) + input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tuser = Signal(bool(0)) + + output_axis_tready = Signal(bool(0)) + + # Outputs + input_0_axis_tready = Signal(bool(0)) + input_1_axis_tready = Signal(bool(0)) + input_2_axis_tready = Signal(bool(0)) + input_3_axis_tready = Signal(bool(0)) + + output_axis_tdata = Signal(intbv(0)[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_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + source_1 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + source_2 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + source_3 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + 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_arb_mux_64_4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_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: port 0") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x00\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_0_queue.put(test_frame) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: port 1") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x01\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_1_queue.put(test_frame) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x00\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\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\x00\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x01\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\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\x02\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + 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_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x01\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\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\x02\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x01\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\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\x02\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_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_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, different ports, arbitration test") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' + + '\x5A\x01\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\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\x02\x52\x53\x54\x55' + + '\x80\x00' + + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + yield clk.posedge + + yield delay(150) + yield clk.posedge + source_2_queue.put(test_frame2) + + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + 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_frame2 + + 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_frame1 + + 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 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_arb_mux_64_4.v b/tb/test_axis_arb_mux_64_4.v new file mode 100644 index 000000000..e4f5db801 --- /dev/null +++ b/tb/test_axis_arb_mux_64_4.v @@ -0,0 +1,152 @@ +/* + +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_arb_mux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] input_0_axis_tdata = 0; +reg [7:0] input_0_axis_tkeep = 0; +reg input_0_axis_tvalid = 0; +reg input_0_axis_tlast = 0; +reg input_0_axis_tuser = 0; +reg [63:0] input_1_axis_tdata = 0; +reg [7:0] input_1_axis_tkeep = 0; +reg input_1_axis_tvalid = 0; +reg input_1_axis_tlast = 0; +reg input_1_axis_tuser = 0; +reg [63:0] input_2_axis_tdata = 0; +reg [7:0] input_2_axis_tkeep = 0; +reg input_2_axis_tvalid = 0; +reg input_2_axis_tlast = 0; +reg input_2_axis_tuser = 0; +reg [63:0] input_3_axis_tdata = 0; +reg [7:0] input_3_axis_tkeep = 0; +reg input_3_axis_tvalid = 0; +reg input_3_axis_tlast = 0; +reg input_3_axis_tuser = 0; + +reg output_axis_tready = 0; + +// Outputs +wire input_0_axis_tready; +wire input_1_axis_tready; +wire input_2_axis_tready; +wire input_3_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_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready); + $to_myhdl(input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_arb_mux_64_4.lxt"); + $dumpvars(0, test_axis_arb_mux_64_4); +end + +axis_arb_mux_64_4 #( + .DATA_WIDTH(64) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI inputs + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tkeep(input_0_axis_tkeep), + .input_0_axis_tvalid(input_0_axis_tvalid), + .input_0_axis_tready(input_0_axis_tready), + .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tuser(input_0_axis_tuser), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tkeep(input_1_axis_tkeep), + .input_1_axis_tvalid(input_1_axis_tvalid), + .input_1_axis_tready(input_1_axis_tready), + .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tuser(input_1_axis_tuser), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tkeep(input_2_axis_tkeep), + .input_2_axis_tvalid(input_2_axis_tvalid), + .input_2_axis_tready(input_2_axis_tready), + .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tuser(input_2_axis_tuser), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tkeep(input_3_axis_tkeep), + .input_3_axis_tvalid(input_3_axis_tvalid), + .input_3_axis_tready(input_3_axis_tready), + .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tuser(input_3_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_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 From 851aeb9309a9fd473f787112e012e5b7be13ae01 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 13 Nov 2014 10:06:28 -0800 Subject: [PATCH 092/617] Fix block parameter --- rtl/arbiter.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/arbiter.v b/rtl/arbiter.v index 71ca40107..219b4661c 100644 --- a/rtl/arbiter.v +++ b/rtl/arbiter.v @@ -35,7 +35,7 @@ module arbiter # // arbitration type: "PRIORITY" or "ROUND_ROBIN" parameter TYPE = "PRIORITY", // block type: "NONE", "REQUEST", "ACKNOWLEDGE" - parameter BLOCK = "TRUE" + parameter BLOCK = "NONE" ) ( input wire clk, From bd902081539278cb41ca16d4f09216bbcf8ec79b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 13 Nov 2014 10:19:46 -0800 Subject: [PATCH 093/617] Update readme --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/README.md b/README.md index a06e43690..99a985c56 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,11 @@ intelligent bus cosimulation endpoints. ## Documentation +### arbiter module + +General-purpose parametrizable arbiter. Supports priority and round-robin +arbitration. Supports blocking until request release or acknowledge. + ### axis_adapter module The axis_adapter module bridges AXI stream busses of differing widths. The @@ -22,6 +27,20 @@ related by an integer multiple (e.g. 2 words and 6 words, but not 4 words and 6 words). Wait states will be inserted on the wider bus side when necessary. +### axis_arb_mux_N module + +Frame-aware AXI stream arbitrated muliplexer with parametrizable data width. +Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with axis_arb_mux.py. + +### axis_arb_mux_64_N module + +Frame-aware AXI stream arbitrated muliplexer with tkeep signal and +parametrizable data width. Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with axis_arb_mux_64.py. + ### axis_async_fifo module Basic word-based asynchronous FIFO with parametrizable data width and depth. @@ -56,6 +75,19 @@ Parametrizable data width. Can be generated with arbitrary port counts with axis_crosspoint_64.py. +### axis_demux_N module + +Frame-aware AXI stream demuliplexer with parametrizable data width. + +Can be generated with arbitrary port counts with axis_demux.py. + +### axis_demux_64_N module + +Frame-aware AXI stream demuliplexer with tkeep signal and parametrizable data +width. + +Can be generated with arbitrary port counts with axis_demux_64.py. + ### axis_fifo module Basic word-based synchronous FIFO with parametrizable data width and depth. @@ -133,6 +165,10 @@ monolithic frame from multiple monitored points with the same trigger. LocalLink to AXI stream bridge. +### priority_encoder module + +Parametrizable priority encoder. + ### Common signals tdata : Data (width generally DATA_WIDTH) @@ -144,7 +180,12 @@ LocalLink to AXI stream bridge. ### Source Files + rtl/arbiter.v : General-purpose parametrizable arbiter rtl/axis_adapter.v : Parametrizable bus width adapter + rtl/axis_arb_mux.py : Arbitrated multiplexer generator + rtl/axis_arb_mux_4.v : 4 port arbitrated multiplexer + rtl/axis_arb_mux_64.py : Arbitrated multiplexer generator (64 bit) + rtl/axis_arb_mux_64_4.v : 4 port arbitrated multiplexer (64 bit) rtl/axis_async_fifo.v : Asynchronous FIFO rtl/axis_async_fifo_64.v : Asynchronous FIFO (64 bit) rtl/axis_async_frame_fifo.v : Asynchronous frame FIFO @@ -153,6 +194,10 @@ LocalLink to AXI stream bridge. rtl/axis_crosspoint_4x4.v : 4x4 crosspoint switch rtl/axis_crosspoint_64.py : Crosspoint switch generator (64 bit) rtl/axis_crosspoint_64_4x4.v : 4x4 crosspoint switch (64 bit) + rtl/axis_demux.py : Demultiplexer generator + rtl/axis_demux_4.v : 4 port demultiplexer + rtl/axis_demux_64.py : Demultiplexer generator (64 bit) + rtl/axis_demux_64_4.v : 4 port demultiplexer (64 bit) rtl/axis_fifo.v : Synchronous FIFO rtl/axis_fifo_64.v : Synchronous FIFO (64 bit) rtl/axis_frame_fifo.v : Synchronous frame FIFO @@ -170,6 +215,7 @@ LocalLink to AXI stream bridge. rtl/axis_register_64.v : AXI Stream register (64 bit) rtl/axis_stat_counter.v : Statistics counter rtl/ll_axis_bridge.v : LocalLink to AXI stream bridge + rtl/priority_encoder.v : Parametrizable priority encoder ### AXI Stream Interface Example From 8a46e6900c0ee06b06de81319ed7deeb505dabf3 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 13 Nov 2014 10:21:54 -0800 Subject: [PATCH 094/617] Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99a985c56..182e346da 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ width and depth. Supports power of two depths only. Basic frame-based synchronous FIFO with parametrizable data width and depth. Supports power of two depths only. -### axis_fifo_64 module +### axis_frame_fifo_64 module Basic frame-based synchronous FIFO with tkeep signal and parametrizable data width and depth. Supports power of two depths only. From 698234c2979c962b731b3a87db38af8ce5369cde Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 13 Nov 2014 10:39:27 -0800 Subject: [PATCH 095/617] Update comments --- rtl/axis_arb_mux.py | 4 ++-- rtl/axis_arb_mux_64.py | 4 ++-- rtl/axis_async_frame_fifo.v | 2 +- rtl/axis_async_frame_fifo_64.v | 2 +- rtl/axis_crosspoint_64.py | 2 +- rtl/axis_demux.py | 4 ++-- rtl/axis_demux_64.py | 4 ++-- rtl/axis_mux.py | 2 +- rtl/axis_mux_64.py | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index b1223060c..9b40e7fca 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -1,9 +1,9 @@ #!/usr/bin/env python -"""axis_mux +"""axis_arb_mux Generates an arbitrated AXI Stream mux with the specified number of ports -Usage: axis_crosspoint [OPTION]... +Usage: axis_arb_mux [OPTION]... -?, --help display this help and exit -p, --ports specify number of ports -n, --name specify module name diff --git a/rtl/axis_arb_mux_64.py b/rtl/axis_arb_mux_64.py index 6b05df0cb..75571c11e 100755 --- a/rtl/axis_arb_mux_64.py +++ b/rtl/axis_arb_mux_64.py @@ -1,9 +1,9 @@ #!/usr/bin/env python -"""axis_mux +"""axis_arb_mux_64 Generates an arbitrated AXI Stream mux with the specified number of ports -Usage: axis_crosspoint [OPTION]... +Usage: axis_arb_mux_64 [OPTION]... -?, --help display this help and exit -p, --ports specify number of ports -n, --name specify module name diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 16f2e17bc..be2374241 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -27,7 +27,7 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * AXI4-Stream asynchronous FIFO + * AXI4-Stream asynchronous frame FIFO */ module axis_async_frame_fifo # ( diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 3da51f5ef..2a200f691 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -27,7 +27,7 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * AXI4-Stream asynchronous FIFO (64 bit datapath) + * AXI4-Stream asynchronous frame FIFO (64 bit datapath) */ module axis_async_frame_fifo_64 # ( diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index fa674ffab..c666299a4 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -"""axis_crosspoint_64_64 +"""axis_crosspoint_64 Generates an AXI Stream crosspoint switch with the specified number of ports diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index 4fb494ef2..419d09f35 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -1,9 +1,9 @@ #!/usr/bin/env python -"""axis_mux +"""axis_demux Generates an AXI Stream demux with the specified number of ports -Usage: axis_crosspoint [OPTION]... +Usage: axis_demux [OPTION]... -?, --help display this help and exit -p, --ports specify number of ports -n, --name specify module name diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index e28e5d3ac..b1ad161be 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -1,9 +1,9 @@ #!/usr/bin/env python -"""axis_mux +"""axis_demux_64 Generates an AXI Stream demux with the specified number of ports -Usage: axis_crosspoint [OPTION]... +Usage: axis_demux_64 [OPTION]... -?, --help display this help and exit -p, --ports specify number of ports -n, --name specify module name diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 6286e3c19..711e80970 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -3,7 +3,7 @@ Generates an AXI Stream mux with the specified number of ports -Usage: axis_crosspoint [OPTION]... +Usage: axis_mux [OPTION]... -?, --help display this help and exit -p, --ports specify number of ports -n, --name specify module name diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index 53acfe832..7ef021d78 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -1,9 +1,9 @@ #!/usr/bin/env python -"""axis_mux +"""axis_mux_64 Generates an AXI Stream mux with the specified number of ports -Usage: axis_crosspoint [OPTION]... +Usage: axis_mux_64 [OPTION]... -?, --help display this help and exit -p, --ports specify number of ports -n, --name specify module name From 789c7da6d65c413370da9e261dfe5eb6b9e6ff53 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 13 Nov 2014 10:39:41 -0800 Subject: [PATCH 096/617] Fix parameter --- rtl/axis_frame_join.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index aa69ee4b6..ec866ed84 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -47,7 +47,7 @@ def main(argv=None): ports = int(a) if o in ('-n', '--name'): name = a - if o in ('-o', '--outputs'): + if o in ('-o', '--output'): out_name = a if name is None: From 7c8699939983f37ff47a56849aa8e72eac68c46c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 13 Nov 2014 16:26:07 -0800 Subject: [PATCH 097/617] Minor reorganization --- rtl/axis_demux.py | 11 ++++++----- rtl/axis_demux_4.v | 11 ++++++----- rtl/axis_demux_64.py | 11 ++++++----- rtl/axis_demux_64_4.v | 11 ++++++----- rtl/axis_mux.py | 12 ++++++------ rtl/axis_mux_4.v | 16 ++++++++-------- rtl/axis_mux_64.py | 12 ++++++------ rtl/axis_mux_64_4.v | 16 ++++++++-------- 8 files changed, 52 insertions(+), 48 deletions(-) diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index 419d09f35..601e87d29 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -132,7 +132,12 @@ module {{name}} # input wire [{{w-1}}:0] select ); -// // internal datapath +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; + +// internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg output_axis_tvalid_int; reg output_axis_tready_int = 0; @@ -140,10 +145,6 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; - -reg input_axis_tready_reg = 0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; // mux for output control signals diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v index f045c1558..1209f07c0 100644 --- a/rtl/axis_demux_4.v +++ b/rtl/axis_demux_4.v @@ -79,7 +79,12 @@ module axis_demux_4 # input wire [1:0] select ); -// // internal datapath +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; + +// internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg output_axis_tvalid_int; reg output_axis_tready_int = 0; @@ -87,10 +92,6 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; - -reg input_axis_tready_reg = 0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; // mux for output control signals diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index b1ad161be..7f485bb14 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -135,7 +135,12 @@ module {{name}} # input wire [{{w-1}}:0] select ); -// // internal datapath +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; + +// internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; reg output_axis_tvalid_int; @@ -144,10 +149,6 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; - -reg input_axis_tready_reg = 0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; // mux for output control signals diff --git a/rtl/axis_demux_64_4.v b/rtl/axis_demux_64_4.v index 3605ff394..47940c670 100644 --- a/rtl/axis_demux_64_4.v +++ b/rtl/axis_demux_64_4.v @@ -85,7 +85,12 @@ module axis_demux_64_4 # input wire [1:0] select ); -// // internal datapath +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; + +// internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; reg output_axis_tvalid_int; @@ -94,10 +99,6 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; - -reg input_axis_tready_reg = 0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; // mux for output control signals diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 711e80970..37c2f8a3a 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -132,6 +132,12 @@ module {{name}} # input wire [{{w-1}}:0] select ); +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; +{% for p in ports %} +reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +{%- endfor %} + // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg output_axis_tvalid_int; @@ -139,12 +145,6 @@ reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; - -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; -{% for p in ports %} -reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; -{%- endfor %} {% for p in ports %} assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; {%- endfor %} diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v index b1e04fb63..12ad752a6 100644 --- a/rtl/axis_mux_4.v +++ b/rtl/axis_mux_4.v @@ -79,14 +79,6 @@ module axis_mux_4 # input wire [1:0] select ); -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - reg [1:0] select_reg = 0, select_next; reg frame_reg = 0, frame_next; @@ -95,6 +87,14 @@ reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + assign input_0_axis_tready = input_0_axis_tready_reg; assign input_1_axis_tready = input_1_axis_tready_reg; assign input_2_axis_tready = input_2_axis_tready_reg; diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index 7ef021d78..9b9165612 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -135,6 +135,12 @@ module {{name}} # input wire [{{w-1}}:0] select ); +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; +{% for p in ports %} +reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +{%- endfor %} + // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; @@ -143,12 +149,6 @@ reg output_axis_tready_int = 0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; - -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; -{% for p in ports %} -reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; -{%- endfor %} {% for p in ports %} assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; {%- endfor %} diff --git a/rtl/axis_mux_64_4.v b/rtl/axis_mux_64_4.v index 038e377f5..bbf945e09 100644 --- a/rtl/axis_mux_64_4.v +++ b/rtl/axis_mux_64_4.v @@ -85,6 +85,14 @@ module axis_mux_64_4 # input wire [1:0] select ); +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; + // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; @@ -94,14 +102,6 @@ reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; - -reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; - assign input_0_axis_tready = input_0_axis_tready_reg; assign input_1_axis_tready = input_1_axis_tready_reg; assign input_2_axis_tready = input_2_axis_tready_reg; From 9bee01e74cade52ad9dec5b0d3d9893619d2449c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 14 Nov 2014 17:48:51 -0800 Subject: [PATCH 098/617] Add ethernet mux and testbench --- rtl/eth_mux.py | 368 ++++++++++++++++++++++ rtl/eth_mux_4.v | 376 ++++++++++++++++++++++ rtl/eth_mux_64.py | 383 +++++++++++++++++++++++ rtl/eth_mux_64_4.v | 397 ++++++++++++++++++++++++ tb/test_eth_mux_4.py | 648 ++++++++++++++++++++++++++++++++++++++ tb/test_eth_mux_4.v | 215 +++++++++++++ tb/test_eth_mux_64_4.py | 673 ++++++++++++++++++++++++++++++++++++++++ tb/test_eth_mux_64_4.v | 230 ++++++++++++++ 8 files changed, 3290 insertions(+) create mode 100755 rtl/eth_mux.py create mode 100644 rtl/eth_mux_4.v create mode 100755 rtl/eth_mux_64.py create mode 100644 rtl/eth_mux_64_4.v create mode 100755 tb/test_eth_mux_4.py create mode 100644 tb/test_eth_mux_4.v create mode 100755 tb/test_eth_mux_64_4.py create mode 100644 tb/test_eth_mux_64_4.v diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py new file mode 100755 index 000000000..6d030f1a1 --- /dev/null +++ b/rtl/eth_mux.py @@ -0,0 +1,368 @@ +#!/usr/bin/env python +"""eth_mux + +Generates an Ethernet mux with the specified number of ports + +Usage: eth_mux [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "eth_mux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port Ethernet mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * Ethernet {{n}} port multiplexer + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_eth_hdr_valid, + output wire input_{{p}}_eth_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [7:0] input_{{p}}_eth_payload_tdata, + input wire input_{{p}}_eth_payload_tvalid, + output wire input_{{p}}_eth_payload_tready, + input wire input_{{p}}_eth_payload_tlast, + input wire input_{{p}}_eth_payload_tuser, +{% endfor %} + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Control + */ + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; +{% for p in ports %} +reg input_{{p}}_eth_hdr_ready_reg = 0, input_{{p}}_eth_hdr_ready_next; +{%- endfor %} +{% for p in ports %} +reg input_{{p}}_eth_payload_tready_reg = 0, input_{{p}}_eth_payload_tready_next; +{%- endfor %} + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; + +// internal datapath +reg [7:0] output_eth_payload_tdata_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; +{% for p in ports %} +assign input_{{p}}_eth_hdr_ready = input_{{p}}_eth_hdr_ready_reg; +{%- endfor %} +{% for p in ports %} +assign input_{{p}}_eth_payload_tready = input_{{p}}_eth_payload_tready_reg; +{%- endfor %} + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; + +// mux for start of packet detection +reg selected_input_eth_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +always @* begin + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: begin + selected_input_eth_hdr_valid = input_{{p}}_eth_hdr_valid; + selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; + selected_input_eth_src_mac = input_{{p}}_eth_src_mac; + selected_input_eth_type = input_{{p}}_eth_type; + end +{%- endfor %} + endcase +end + +// mux for incoming packet +reg [7:0] current_input_tdata; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_input_tdata = input_{{p}}_eth_payload_tdata; + current_input_tvalid = input_{{p}}_eth_payload_tvalid; + current_input_tready = input_{{p}}_eth_payload_tready; + current_input_tlast = input_{{p}}_eth_payload_tlast; + current_input_tuser = input_{{p}}_eth_payload_tuser; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; +{% for p in ports %} + input_{{p}}_eth_hdr_ready_next = input_{{p}}_eth_hdr_ready_reg & ~input_{{p}}_eth_hdr_valid; +{%- endfor %} +{% for p in ports %} + input_{{p}}_eth_payload_tready_next = 0; +{%- endfor %} + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (selected_input_eth_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + output_eth_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + end + + // generate ready signal on selected port + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: begin + input_{{p}}_eth_hdr_ready_next = input_{{p}}_eth_hdr_ready_next | (frame_next & ~frame_reg); + input_{{p}}_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + end +{%- endfor %} + endcase + + // pass through selected packet data + output_eth_payload_tdata_int = current_input_tdata; + output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_eth_payload_tlast_int = current_input_tlast; + output_eth_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; +{%- for p in ports %} + input_{{p}}_eth_hdr_ready_reg <= 0; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_eth_payload_tready_reg <= 0; +{%- endfor %} + output_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; +{%- for p in ports %} + input_{{p}}_eth_hdr_ready_reg <= input_{{p}}_eth_hdr_ready_next; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_eth_payload_tready_reg <= input_{{p}}_eth_payload_tready_next; +{%- endfor %} + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + end +end + +// output datapath logic +reg [7:0] output_eth_payload_tdata_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [7:0] temp_eth_payload_tdata_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v new file mode 100644 index 000000000..77e7b710c --- /dev/null +++ b/rtl/eth_mux_4.v @@ -0,0 +1,376 @@ +/* + +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 + +/* + * Ethernet 4 port multiplexer + */ +module eth_mux_4 +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ + input wire input_0_eth_hdr_valid, + output wire input_0_eth_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [7:0] input_0_eth_payload_tdata, + input wire input_0_eth_payload_tvalid, + output wire input_0_eth_payload_tready, + input wire input_0_eth_payload_tlast, + input wire input_0_eth_payload_tuser, + + input wire input_1_eth_hdr_valid, + output wire input_1_eth_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [7:0] input_1_eth_payload_tdata, + input wire input_1_eth_payload_tvalid, + output wire input_1_eth_payload_tready, + input wire input_1_eth_payload_tlast, + input wire input_1_eth_payload_tuser, + + input wire input_2_eth_hdr_valid, + output wire input_2_eth_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [7:0] input_2_eth_payload_tdata, + input wire input_2_eth_payload_tvalid, + output wire input_2_eth_payload_tready, + input wire input_2_eth_payload_tlast, + input wire input_2_eth_payload_tuser, + + input wire input_3_eth_hdr_valid, + output wire input_3_eth_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [7:0] input_3_eth_payload_tdata, + input wire input_3_eth_payload_tvalid, + output wire input_3_eth_payload_tready, + input wire input_3_eth_payload_tlast, + input wire input_3_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Control + */ + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_eth_hdr_ready_reg = 0, input_0_eth_hdr_ready_next; +reg input_1_eth_hdr_ready_reg = 0, input_1_eth_hdr_ready_next; +reg input_2_eth_hdr_ready_reg = 0, input_2_eth_hdr_ready_next; +reg input_3_eth_hdr_ready_reg = 0, input_3_eth_hdr_ready_next; + +reg input_0_eth_payload_tready_reg = 0, input_0_eth_payload_tready_next; +reg input_1_eth_payload_tready_reg = 0, input_1_eth_payload_tready_next; +reg input_2_eth_payload_tready_reg = 0, input_2_eth_payload_tready_next; +reg input_3_eth_payload_tready_reg = 0, input_3_eth_payload_tready_next; + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; + +// internal datapath +reg [7:0] output_eth_payload_tdata_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + +assign input_0_eth_hdr_ready = input_0_eth_hdr_ready_reg; +assign input_1_eth_hdr_ready = input_1_eth_hdr_ready_reg; +assign input_2_eth_hdr_ready = input_2_eth_hdr_ready_reg; +assign input_3_eth_hdr_ready = input_3_eth_hdr_ready_reg; + +assign input_0_eth_payload_tready = input_0_eth_payload_tready_reg; +assign input_1_eth_payload_tready = input_1_eth_payload_tready_reg; +assign input_2_eth_payload_tready = input_2_eth_payload_tready_reg; +assign input_3_eth_payload_tready = input_3_eth_payload_tready_reg; + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; + +// mux for start of packet detection +reg selected_input_eth_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +always @* begin + case (select) + 2'd0: begin + selected_input_eth_hdr_valid = input_0_eth_hdr_valid; + selected_input_eth_dest_mac = input_0_eth_dest_mac; + selected_input_eth_src_mac = input_0_eth_src_mac; + selected_input_eth_type = input_0_eth_type; + end + 2'd1: begin + selected_input_eth_hdr_valid = input_1_eth_hdr_valid; + selected_input_eth_dest_mac = input_1_eth_dest_mac; + selected_input_eth_src_mac = input_1_eth_src_mac; + selected_input_eth_type = input_1_eth_type; + end + 2'd2: begin + selected_input_eth_hdr_valid = input_2_eth_hdr_valid; + selected_input_eth_dest_mac = input_2_eth_dest_mac; + selected_input_eth_src_mac = input_2_eth_src_mac; + selected_input_eth_type = input_2_eth_type; + end + 2'd3: begin + selected_input_eth_hdr_valid = input_3_eth_hdr_valid; + selected_input_eth_dest_mac = input_3_eth_dest_mac; + selected_input_eth_src_mac = input_3_eth_src_mac; + selected_input_eth_type = input_3_eth_type; + end + endcase +end + +// mux for incoming packet +reg [7:0] current_input_tdata; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 2'd0: begin + current_input_tdata = input_0_eth_payload_tdata; + current_input_tvalid = input_0_eth_payload_tvalid; + current_input_tready = input_0_eth_payload_tready; + current_input_tlast = input_0_eth_payload_tlast; + current_input_tuser = input_0_eth_payload_tuser; + end + 2'd1: begin + current_input_tdata = input_1_eth_payload_tdata; + current_input_tvalid = input_1_eth_payload_tvalid; + current_input_tready = input_1_eth_payload_tready; + current_input_tlast = input_1_eth_payload_tlast; + current_input_tuser = input_1_eth_payload_tuser; + end + 2'd2: begin + current_input_tdata = input_2_eth_payload_tdata; + current_input_tvalid = input_2_eth_payload_tvalid; + current_input_tready = input_2_eth_payload_tready; + current_input_tlast = input_2_eth_payload_tlast; + current_input_tuser = input_2_eth_payload_tuser; + end + 2'd3: begin + current_input_tdata = input_3_eth_payload_tdata; + current_input_tvalid = input_3_eth_payload_tvalid; + current_input_tready = input_3_eth_payload_tready; + current_input_tlast = input_3_eth_payload_tlast; + current_input_tuser = input_3_eth_payload_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_reg & ~input_0_eth_hdr_valid; + input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_reg & ~input_1_eth_hdr_valid; + input_2_eth_hdr_ready_next = input_2_eth_hdr_ready_reg & ~input_2_eth_hdr_valid; + input_3_eth_hdr_ready_next = input_3_eth_hdr_ready_reg & ~input_3_eth_hdr_valid; + + input_0_eth_payload_tready_next = 0; + input_1_eth_payload_tready_next = 0; + input_2_eth_payload_tready_next = 0; + input_3_eth_payload_tready_next = 0; + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (selected_input_eth_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + output_eth_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + end + + // generate ready signal on selected port + case (select_next) + 2'd0: begin + input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_next | (frame_next & ~frame_reg); + input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + end + 2'd1: begin + input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_next | (frame_next & ~frame_reg); + input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + end + 2'd2: begin + input_2_eth_hdr_ready_next = input_2_eth_hdr_ready_next | (frame_next & ~frame_reg); + input_2_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + end + 2'd3: begin + input_3_eth_hdr_ready_next = input_3_eth_hdr_ready_next | (frame_next & ~frame_reg); + input_3_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + end + endcase + + // pass through selected packet data + output_eth_payload_tdata_int = current_input_tdata; + output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_eth_payload_tlast_int = current_input_tlast; + output_eth_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_eth_hdr_ready_reg <= 0; + input_1_eth_hdr_ready_reg <= 0; + input_2_eth_hdr_ready_reg <= 0; + input_3_eth_hdr_ready_reg <= 0; + input_0_eth_payload_tready_reg <= 0; + input_1_eth_payload_tready_reg <= 0; + input_2_eth_payload_tready_reg <= 0; + input_3_eth_payload_tready_reg <= 0; + output_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_eth_hdr_ready_reg <= input_0_eth_hdr_ready_next; + input_1_eth_hdr_ready_reg <= input_1_eth_hdr_ready_next; + input_2_eth_hdr_ready_reg <= input_2_eth_hdr_ready_next; + input_3_eth_hdr_ready_reg <= input_3_eth_hdr_ready_next; + input_0_eth_payload_tready_reg <= input_0_eth_payload_tready_next; + input_1_eth_payload_tready_reg <= input_1_eth_payload_tready_next; + input_2_eth_payload_tready_reg <= input_2_eth_payload_tready_next; + input_3_eth_payload_tready_reg <= input_3_eth_payload_tready_next; + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + end +end + +// output datapath logic +reg [7:0] output_eth_payload_tdata_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [7:0] temp_eth_payload_tdata_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py new file mode 100755 index 000000000..d5a3a8f66 --- /dev/null +++ b/rtl/eth_mux_64.py @@ -0,0 +1,383 @@ +#!/usr/bin/env python +"""eth_mux_64 + +Generates an Ethernet mux with the specified number of ports + +Usage: eth_mux_64 [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "eth_mux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port Ethernet mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * Ethernet {{n}} port multiplexer (64 bit datapath) + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_eth_hdr_valid, + output wire input_{{p}}_eth_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [63:0] input_{{p}}_eth_payload_tdata, + input wire [7:0] input_{{p}}_eth_payload_tkeep, + input wire input_{{p}}_eth_payload_tvalid, + output wire input_{{p}}_eth_payload_tready, + input wire input_{{p}}_eth_payload_tlast, + input wire input_{{p}}_eth_payload_tuser, +{% endfor %} + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Control + */ + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; +{% for p in ports %} +reg input_{{p}}_eth_hdr_ready_reg = 0, input_{{p}}_eth_hdr_ready_next; +{%- endfor %} +{% for p in ports %} +reg input_{{p}}_eth_payload_tready_reg = 0, input_{{p}}_eth_payload_tready_next; +{%- endfor %} + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; + +// internal datapath +reg [63:0] output_eth_payload_tdata_int; +reg [7:0] output_eth_payload_tkeep_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; +{% for p in ports %} +assign input_{{p}}_eth_hdr_ready = input_{{p}}_eth_hdr_ready_reg; +{%- endfor %} +{% for p in ports %} +assign input_{{p}}_eth_payload_tready = input_{{p}}_eth_payload_tready_reg; +{%- endfor %} + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; + +// mux for start of packet detection +reg selected_input_eth_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +always @* begin + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: begin + selected_input_eth_hdr_valid = input_{{p}}_eth_hdr_valid; + selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; + selected_input_eth_src_mac = input_{{p}}_eth_src_mac; + selected_input_eth_type = input_{{p}}_eth_type; + end +{%- endfor %} + endcase +end + +// mux for incoming packet +reg [63:0] current_input_tdata; +reg [7:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_input_tdata = input_{{p}}_eth_payload_tdata; + current_input_tkeep = input_{{p}}_eth_payload_tkeep; + current_input_tvalid = input_{{p}}_eth_payload_tvalid; + current_input_tready = input_{{p}}_eth_payload_tready; + current_input_tlast = input_{{p}}_eth_payload_tlast; + current_input_tuser = input_{{p}}_eth_payload_tuser; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; +{% for p in ports %} + input_{{p}}_eth_hdr_ready_next = input_{{p}}_eth_hdr_ready_reg & ~input_{{p}}_eth_hdr_valid; +{%- endfor %} +{% for p in ports %} + input_{{p}}_eth_payload_tready_next = 0; +{%- endfor %} + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (selected_input_eth_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + output_eth_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + end + + // generate ready signal on selected port + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: begin + input_{{p}}_eth_hdr_ready_next = input_{{p}}_eth_hdr_ready_next | (frame_next & ~frame_reg); + input_{{p}}_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + end +{%- endfor %} + endcase + + // pass through selected packet data + output_eth_payload_tdata_int = current_input_tdata; + output_eth_payload_tkeep_int = current_input_tkeep; + output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_eth_payload_tlast_int = current_input_tlast; + output_eth_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; +{%- for p in ports %} + input_{{p}}_eth_hdr_ready_reg <= 0; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_eth_payload_tready_reg <= 0; +{%- endfor %} + output_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; +{%- for p in ports %} + input_{{p}}_eth_hdr_ready_reg <= input_{{p}}_eth_hdr_ready_next; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_eth_payload_tready_reg <= input_{{p}}_eth_payload_tready_next; +{%- endfor %} + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + end +end + +// output datapath logic +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [63:0] temp_eth_payload_tdata_reg = 0; +reg [7:0] temp_eth_payload_tkeep_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tkeep_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v new file mode 100644 index 000000000..7f849c350 --- /dev/null +++ b/rtl/eth_mux_64_4.v @@ -0,0 +1,397 @@ +/* + +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 + +/* + * Ethernet 4 port multiplexer (64 bit datapath) + */ +module eth_mux_64_4 +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ + input wire input_0_eth_hdr_valid, + output wire input_0_eth_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [63:0] input_0_eth_payload_tdata, + input wire [7:0] input_0_eth_payload_tkeep, + input wire input_0_eth_payload_tvalid, + output wire input_0_eth_payload_tready, + input wire input_0_eth_payload_tlast, + input wire input_0_eth_payload_tuser, + + input wire input_1_eth_hdr_valid, + output wire input_1_eth_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [63:0] input_1_eth_payload_tdata, + input wire [7:0] input_1_eth_payload_tkeep, + input wire input_1_eth_payload_tvalid, + output wire input_1_eth_payload_tready, + input wire input_1_eth_payload_tlast, + input wire input_1_eth_payload_tuser, + + input wire input_2_eth_hdr_valid, + output wire input_2_eth_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [63:0] input_2_eth_payload_tdata, + input wire [7:0] input_2_eth_payload_tkeep, + input wire input_2_eth_payload_tvalid, + output wire input_2_eth_payload_tready, + input wire input_2_eth_payload_tlast, + input wire input_2_eth_payload_tuser, + + input wire input_3_eth_hdr_valid, + output wire input_3_eth_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [63:0] input_3_eth_payload_tdata, + input wire [7:0] input_3_eth_payload_tkeep, + input wire input_3_eth_payload_tvalid, + output wire input_3_eth_payload_tready, + input wire input_3_eth_payload_tlast, + input wire input_3_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Control + */ + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_eth_hdr_ready_reg = 0, input_0_eth_hdr_ready_next; +reg input_1_eth_hdr_ready_reg = 0, input_1_eth_hdr_ready_next; +reg input_2_eth_hdr_ready_reg = 0, input_2_eth_hdr_ready_next; +reg input_3_eth_hdr_ready_reg = 0, input_3_eth_hdr_ready_next; + +reg input_0_eth_payload_tready_reg = 0, input_0_eth_payload_tready_next; +reg input_1_eth_payload_tready_reg = 0, input_1_eth_payload_tready_next; +reg input_2_eth_payload_tready_reg = 0, input_2_eth_payload_tready_next; +reg input_3_eth_payload_tready_reg = 0, input_3_eth_payload_tready_next; + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; + +// internal datapath +reg [63:0] output_eth_payload_tdata_int; +reg [7:0] output_eth_payload_tkeep_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + +assign input_0_eth_hdr_ready = input_0_eth_hdr_ready_reg; +assign input_1_eth_hdr_ready = input_1_eth_hdr_ready_reg; +assign input_2_eth_hdr_ready = input_2_eth_hdr_ready_reg; +assign input_3_eth_hdr_ready = input_3_eth_hdr_ready_reg; + +assign input_0_eth_payload_tready = input_0_eth_payload_tready_reg; +assign input_1_eth_payload_tready = input_1_eth_payload_tready_reg; +assign input_2_eth_payload_tready = input_2_eth_payload_tready_reg; +assign input_3_eth_payload_tready = input_3_eth_payload_tready_reg; + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; + +// mux for start of packet detection +reg selected_input_eth_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +always @* begin + case (select) + 2'd0: begin + selected_input_eth_hdr_valid = input_0_eth_hdr_valid; + selected_input_eth_dest_mac = input_0_eth_dest_mac; + selected_input_eth_src_mac = input_0_eth_src_mac; + selected_input_eth_type = input_0_eth_type; + end + 2'd1: begin + selected_input_eth_hdr_valid = input_1_eth_hdr_valid; + selected_input_eth_dest_mac = input_1_eth_dest_mac; + selected_input_eth_src_mac = input_1_eth_src_mac; + selected_input_eth_type = input_1_eth_type; + end + 2'd2: begin + selected_input_eth_hdr_valid = input_2_eth_hdr_valid; + selected_input_eth_dest_mac = input_2_eth_dest_mac; + selected_input_eth_src_mac = input_2_eth_src_mac; + selected_input_eth_type = input_2_eth_type; + end + 2'd3: begin + selected_input_eth_hdr_valid = input_3_eth_hdr_valid; + selected_input_eth_dest_mac = input_3_eth_dest_mac; + selected_input_eth_src_mac = input_3_eth_src_mac; + selected_input_eth_type = input_3_eth_type; + end + endcase +end + +// mux for incoming packet +reg [63:0] current_input_tdata; +reg [7:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 2'd0: begin + current_input_tdata = input_0_eth_payload_tdata; + current_input_tkeep = input_0_eth_payload_tkeep; + current_input_tvalid = input_0_eth_payload_tvalid; + current_input_tready = input_0_eth_payload_tready; + current_input_tlast = input_0_eth_payload_tlast; + current_input_tuser = input_0_eth_payload_tuser; + end + 2'd1: begin + current_input_tdata = input_1_eth_payload_tdata; + current_input_tkeep = input_1_eth_payload_tkeep; + current_input_tvalid = input_1_eth_payload_tvalid; + current_input_tready = input_1_eth_payload_tready; + current_input_tlast = input_1_eth_payload_tlast; + current_input_tuser = input_1_eth_payload_tuser; + end + 2'd2: begin + current_input_tdata = input_2_eth_payload_tdata; + current_input_tkeep = input_2_eth_payload_tkeep; + current_input_tvalid = input_2_eth_payload_tvalid; + current_input_tready = input_2_eth_payload_tready; + current_input_tlast = input_2_eth_payload_tlast; + current_input_tuser = input_2_eth_payload_tuser; + end + 2'd3: begin + current_input_tdata = input_3_eth_payload_tdata; + current_input_tkeep = input_3_eth_payload_tkeep; + current_input_tvalid = input_3_eth_payload_tvalid; + current_input_tready = input_3_eth_payload_tready; + current_input_tlast = input_3_eth_payload_tlast; + current_input_tuser = input_3_eth_payload_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_reg & ~input_0_eth_hdr_valid; + input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_reg & ~input_1_eth_hdr_valid; + input_2_eth_hdr_ready_next = input_2_eth_hdr_ready_reg & ~input_2_eth_hdr_valid; + input_3_eth_hdr_ready_next = input_3_eth_hdr_ready_reg & ~input_3_eth_hdr_valid; + + input_0_eth_payload_tready_next = 0; + input_1_eth_payload_tready_next = 0; + input_2_eth_payload_tready_next = 0; + input_3_eth_payload_tready_next = 0; + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (selected_input_eth_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + output_eth_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + end + + // generate ready signal on selected port + case (select_next) + 2'd0: begin + input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_next | (frame_next & ~frame_reg); + input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + end + 2'd1: begin + input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_next | (frame_next & ~frame_reg); + input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + end + 2'd2: begin + input_2_eth_hdr_ready_next = input_2_eth_hdr_ready_next | (frame_next & ~frame_reg); + input_2_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + end + 2'd3: begin + input_3_eth_hdr_ready_next = input_3_eth_hdr_ready_next | (frame_next & ~frame_reg); + input_3_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + end + endcase + + // pass through selected packet data + output_eth_payload_tdata_int = current_input_tdata; + output_eth_payload_tkeep_int = current_input_tkeep; + output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_eth_payload_tlast_int = current_input_tlast; + output_eth_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_eth_hdr_ready_reg <= 0; + input_1_eth_hdr_ready_reg <= 0; + input_2_eth_hdr_ready_reg <= 0; + input_3_eth_hdr_ready_reg <= 0; + input_0_eth_payload_tready_reg <= 0; + input_1_eth_payload_tready_reg <= 0; + input_2_eth_payload_tready_reg <= 0; + input_3_eth_payload_tready_reg <= 0; + output_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_eth_hdr_ready_reg <= input_0_eth_hdr_ready_next; + input_1_eth_hdr_ready_reg <= input_1_eth_hdr_ready_next; + input_2_eth_hdr_ready_reg <= input_2_eth_hdr_ready_next; + input_3_eth_hdr_ready_reg <= input_3_eth_hdr_ready_next; + input_0_eth_payload_tready_reg <= input_0_eth_payload_tready_next; + input_1_eth_payload_tready_reg <= input_1_eth_payload_tready_next; + input_2_eth_payload_tready_reg <= input_2_eth_payload_tready_next; + input_3_eth_payload_tready_reg <= input_3_eth_payload_tready_next; + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + end +end + +// output datapath logic +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [63:0] temp_eth_payload_tdata_reg = 0; +reg [7:0] temp_eth_payload_tkeep_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tkeep_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_eth_mux_4.py b/tb/test_eth_mux_4.py new file mode 100755 index 000000000..9e468ace6 --- /dev/null +++ b/tb/test_eth_mux_4.py @@ -0,0 +1,648 @@ +#!/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 eth_ep + +module = 'eth_mux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_mux_4(clk, + rst, + current_test, + + input_0_eth_hdr_valid, + input_0_eth_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tvalid, + input_0_eth_payload_tready, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tvalid, + input_1_eth_payload_tready, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tvalid, + input_2_eth_payload_tready, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tvalid, + input_3_eth_payload_tready, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + select): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_eth_hdr_valid=input_0_eth_hdr_valid, + input_0_eth_hdr_ready=input_0_eth_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_eth_payload_tdata=input_0_eth_payload_tdata, + input_0_eth_payload_tvalid=input_0_eth_payload_tvalid, + input_0_eth_payload_tready=input_0_eth_payload_tready, + input_0_eth_payload_tlast=input_0_eth_payload_tlast, + input_0_eth_payload_tuser=input_0_eth_payload_tuser, + input_1_eth_hdr_valid=input_1_eth_hdr_valid, + input_1_eth_hdr_ready=input_1_eth_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_eth_payload_tdata=input_1_eth_payload_tdata, + input_1_eth_payload_tvalid=input_1_eth_payload_tvalid, + input_1_eth_payload_tready=input_1_eth_payload_tready, + input_1_eth_payload_tlast=input_1_eth_payload_tlast, + input_1_eth_payload_tuser=input_1_eth_payload_tuser, + input_2_eth_hdr_valid=input_2_eth_hdr_valid, + input_2_eth_hdr_ready=input_2_eth_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_eth_payload_tdata=input_2_eth_payload_tdata, + input_2_eth_payload_tvalid=input_2_eth_payload_tvalid, + input_2_eth_payload_tready=input_2_eth_payload_tready, + input_2_eth_payload_tlast=input_2_eth_payload_tlast, + input_2_eth_payload_tuser=input_2_eth_payload_tuser, + input_3_eth_hdr_valid=input_3_eth_hdr_valid, + input_3_eth_hdr_ready=input_3_eth_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_eth_payload_tdata=input_3_eth_payload_tdata, + input_3_eth_payload_tvalid=input_3_eth_payload_tvalid, + input_3_eth_payload_tready=input_3_eth_payload_tready, + input_3_eth_payload_tlast=input_3_eth_payload_tlast, + input_3_eth_payload_tuser=input_3_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_eth_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_eth_payload_tdata = Signal(intbv(0)[8:]) + input_0_eth_payload_tvalid = Signal(bool(0)) + input_0_eth_payload_tlast = Signal(bool(0)) + input_0_eth_payload_tuser = Signal(bool(0)) + input_1_eth_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_eth_payload_tdata = Signal(intbv(0)[8:]) + input_1_eth_payload_tvalid = Signal(bool(0)) + input_1_eth_payload_tlast = Signal(bool(0)) + input_1_eth_payload_tuser = Signal(bool(0)) + input_2_eth_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_eth_payload_tdata = Signal(intbv(0)[8:]) + input_2_eth_payload_tvalid = Signal(bool(0)) + input_2_eth_payload_tlast = Signal(bool(0)) + input_2_eth_payload_tuser = Signal(bool(0)) + input_3_eth_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_eth_payload_tdata = Signal(intbv(0)[8:]) + input_3_eth_payload_tvalid = Signal(bool(0)) + input_3_eth_payload_tlast = Signal(bool(0)) + input_3_eth_payload_tuser = Signal(bool(0)) + + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + select = Signal(intbv(0)[2:]) + + # Outputs + input_0_eth_hdr_ready = Signal(bool(0)) + input_0_eth_payload_tready = Signal(bool(0)) + input_1_eth_hdr_ready = Signal(bool(0)) + input_1_eth_payload_tready = Signal(bool(0)) + input_2_eth_hdr_ready = Signal(bool(0)) + input_2_eth_payload_tready = Signal(bool(0)) + input_3_eth_hdr_ready = Signal(bool(0)) + input_3_eth_payload_tready = Signal(bool(0)) + + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_0_eth_hdr_ready, + eth_hdr_valid=input_0_eth_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + eth_payload_tdata=input_0_eth_payload_tdata, + eth_payload_tvalid=input_0_eth_payload_tvalid, + eth_payload_tready=input_0_eth_payload_tready, + eth_payload_tlast=input_0_eth_payload_tlast, + eth_payload_tuser=input_0_eth_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_1_eth_hdr_ready, + eth_hdr_valid=input_1_eth_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + eth_payload_tdata=input_1_eth_payload_tdata, + eth_payload_tvalid=input_1_eth_payload_tvalid, + eth_payload_tready=input_1_eth_payload_tready, + eth_payload_tlast=input_1_eth_payload_tlast, + eth_payload_tuser=input_1_eth_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_2_eth_hdr_ready, + eth_hdr_valid=input_2_eth_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + eth_payload_tdata=input_2_eth_payload_tdata, + eth_payload_tvalid=input_2_eth_payload_tvalid, + eth_payload_tready=input_2_eth_payload_tready, + eth_payload_tlast=input_2_eth_payload_tlast, + eth_payload_tuser=input_2_eth_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_3_eth_hdr_ready, + eth_hdr_valid=input_3_eth_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + eth_payload_tdata=input_3_eth_payload_tdata, + eth_payload_tvalid=input_3_eth_payload_tvalid, + eth_payload_tready=input_3_eth_payload_tready, + eth_payload_tlast=input_3_eth_payload_tlast, + eth_payload_tuser=input_3_eth_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_eth_mux_4(clk, + rst, + current_test, + + input_0_eth_hdr_valid, + input_0_eth_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tvalid, + input_0_eth_payload_tready, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tvalid, + input_1_eth_payload_tready, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tvalid, + input_2_eth_payload_tready, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tvalid, + input_3_eth_payload_tready, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + select) + + @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: select port 0") + current_test.next = 1 + + select.next = 0 + + 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(range(32)) + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.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(range(32)) + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + 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(range(32)) + 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(range(32)) + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + yield clk.posedge + select.next = 2 + 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: alterate pause source") + current_test.next = 5 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + select.next = 2 + 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: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + select.next = 2 + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_eth_mux_4.v b/tb/test_eth_mux_4.v new file mode 100644 index 000000000..7db7bdc39 --- /dev/null +++ b/tb/test_eth_mux_4.v @@ -0,0 +1,215 @@ +/* + +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_eth_mux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_eth_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [7:0] input_0_eth_payload_tdata = 0; +reg input_0_eth_payload_tvalid = 0; +reg input_0_eth_payload_tlast = 0; +reg input_0_eth_payload_tuser = 0; +reg input_1_eth_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [7:0] input_1_eth_payload_tdata = 0; +reg input_1_eth_payload_tvalid = 0; +reg input_1_eth_payload_tlast = 0; +reg input_1_eth_payload_tuser = 0; +reg input_2_eth_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [7:0] input_2_eth_payload_tdata = 0; +reg input_2_eth_payload_tvalid = 0; +reg input_2_eth_payload_tlast = 0; +reg input_2_eth_payload_tuser = 0; +reg input_3_eth_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [7:0] input_3_eth_payload_tdata = 0; +reg input_3_eth_payload_tvalid = 0; +reg input_3_eth_payload_tlast = 0; +reg input_3_eth_payload_tuser = 0; + +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +reg [1:0] select = 0; + +// Outputs +wire input_0_eth_payload_tready; +wire input_0_eth_hdr_ready; +wire input_1_eth_payload_tready; +wire input_1_eth_hdr_ready; +wire input_2_eth_payload_tready; +wire input_2_eth_hdr_ready; +wire input_3_eth_payload_tready; +wire input_3_eth_hdr_ready; + +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [7:0] output_eth_payload_tdata; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_eth_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tvalid, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tvalid, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tvalid, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tvalid, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + select); + $to_myhdl(input_0_eth_hdr_ready, + input_0_eth_payload_tready, + input_1_eth_hdr_ready, + input_1_eth_payload_tready, + input_2_eth_hdr_ready, + input_2_eth_payload_tready, + input_3_eth_hdr_ready, + input_3_eth_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser); + + // dump file + $dumpfile("test_eth_mux_4.lxt"); + $dumpvars(0, test_eth_mux_4); +end + +eth_mux_4 +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame inputs + .input_0_eth_hdr_valid(input_0_eth_hdr_valid), + .input_0_eth_hdr_ready(input_0_eth_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_eth_payload_tdata(input_0_eth_payload_tdata), + .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid), + .input_0_eth_payload_tready(input_0_eth_payload_tready), + .input_0_eth_payload_tlast(input_0_eth_payload_tlast), + .input_0_eth_payload_tuser(input_0_eth_payload_tuser), + .input_1_eth_hdr_valid(input_1_eth_hdr_valid), + .input_1_eth_hdr_ready(input_1_eth_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_eth_payload_tdata(input_1_eth_payload_tdata), + .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid), + .input_1_eth_payload_tready(input_1_eth_payload_tready), + .input_1_eth_payload_tlast(input_1_eth_payload_tlast), + .input_1_eth_payload_tuser(input_1_eth_payload_tuser), + .input_2_eth_hdr_valid(input_2_eth_hdr_valid), + .input_2_eth_hdr_ready(input_2_eth_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_eth_payload_tdata(input_2_eth_payload_tdata), + .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid), + .input_2_eth_payload_tready(input_2_eth_payload_tready), + .input_2_eth_payload_tlast(input_2_eth_payload_tlast), + .input_2_eth_payload_tuser(input_2_eth_payload_tuser), + .input_3_eth_hdr_valid(input_3_eth_hdr_valid), + .input_3_eth_hdr_ready(input_3_eth_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_eth_payload_tdata(input_3_eth_payload_tdata), + .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid), + .input_3_eth_payload_tready(input_3_eth_payload_tready), + .input_3_eth_payload_tlast(input_3_eth_payload_tlast), + .input_3_eth_payload_tuser(input_3_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Control + .select(select) +); + +endmodule diff --git a/tb/test_eth_mux_64_4.py b/tb/test_eth_mux_64_4.py new file mode 100755 index 000000000..e044429b2 --- /dev/null +++ b/tb/test_eth_mux_64_4.py @@ -0,0 +1,673 @@ +#!/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 eth_ep + +module = 'eth_mux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_mux_64_4(clk, + rst, + current_test, + + input_0_eth_hdr_valid, + input_0_eth_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tkeep, + input_0_eth_payload_tvalid, + input_0_eth_payload_tready, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tkeep, + input_1_eth_payload_tvalid, + input_1_eth_payload_tready, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tkeep, + input_2_eth_payload_tvalid, + input_2_eth_payload_tready, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tkeep, + input_3_eth_payload_tvalid, + input_3_eth_payload_tready, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + select): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_eth_hdr_valid=input_0_eth_hdr_valid, + input_0_eth_hdr_ready=input_0_eth_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_eth_payload_tdata=input_0_eth_payload_tdata, + input_0_eth_payload_tkeep=input_0_eth_payload_tkeep, + input_0_eth_payload_tvalid=input_0_eth_payload_tvalid, + input_0_eth_payload_tready=input_0_eth_payload_tready, + input_0_eth_payload_tlast=input_0_eth_payload_tlast, + input_0_eth_payload_tuser=input_0_eth_payload_tuser, + input_1_eth_hdr_valid=input_1_eth_hdr_valid, + input_1_eth_hdr_ready=input_1_eth_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_eth_payload_tdata=input_1_eth_payload_tdata, + input_1_eth_payload_tkeep=input_1_eth_payload_tkeep, + input_1_eth_payload_tvalid=input_1_eth_payload_tvalid, + input_1_eth_payload_tready=input_1_eth_payload_tready, + input_1_eth_payload_tlast=input_1_eth_payload_tlast, + input_1_eth_payload_tuser=input_1_eth_payload_tuser, + input_2_eth_hdr_valid=input_2_eth_hdr_valid, + input_2_eth_hdr_ready=input_2_eth_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_eth_payload_tdata=input_2_eth_payload_tdata, + input_2_eth_payload_tkeep=input_2_eth_payload_tkeep, + input_2_eth_payload_tvalid=input_2_eth_payload_tvalid, + input_2_eth_payload_tready=input_2_eth_payload_tready, + input_2_eth_payload_tlast=input_2_eth_payload_tlast, + input_2_eth_payload_tuser=input_2_eth_payload_tuser, + input_3_eth_hdr_valid=input_3_eth_hdr_valid, + input_3_eth_hdr_ready=input_3_eth_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_eth_payload_tdata=input_3_eth_payload_tdata, + input_3_eth_payload_tkeep=input_3_eth_payload_tkeep, + input_3_eth_payload_tvalid=input_3_eth_payload_tvalid, + input_3_eth_payload_tready=input_3_eth_payload_tready, + input_3_eth_payload_tlast=input_3_eth_payload_tlast, + input_3_eth_payload_tuser=input_3_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_eth_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_eth_payload_tdata = Signal(intbv(0)[64:]) + input_0_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_0_eth_payload_tvalid = Signal(bool(0)) + input_0_eth_payload_tlast = Signal(bool(0)) + input_0_eth_payload_tuser = Signal(bool(0)) + input_1_eth_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_eth_payload_tdata = Signal(intbv(0)[64:]) + input_1_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_1_eth_payload_tvalid = Signal(bool(0)) + input_1_eth_payload_tlast = Signal(bool(0)) + input_1_eth_payload_tuser = Signal(bool(0)) + input_2_eth_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_eth_payload_tdata = Signal(intbv(0)[64:]) + input_2_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_2_eth_payload_tvalid = Signal(bool(0)) + input_2_eth_payload_tlast = Signal(bool(0)) + input_2_eth_payload_tuser = Signal(bool(0)) + input_3_eth_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_eth_payload_tdata = Signal(intbv(0)[64:]) + input_3_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_3_eth_payload_tvalid = Signal(bool(0)) + input_3_eth_payload_tlast = Signal(bool(0)) + input_3_eth_payload_tuser = Signal(bool(0)) + + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + select = Signal(intbv(0)[2:]) + + # Outputs + input_0_eth_hdr_ready = Signal(bool(0)) + input_0_eth_payload_tready = Signal(bool(0)) + input_1_eth_hdr_ready = Signal(bool(0)) + input_1_eth_payload_tready = Signal(bool(0)) + input_2_eth_hdr_ready = Signal(bool(0)) + input_2_eth_payload_tready = Signal(bool(0)) + input_3_eth_hdr_ready = Signal(bool(0)) + input_3_eth_payload_tready = Signal(bool(0)) + + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[64:]) + output_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_0_eth_hdr_ready, + eth_hdr_valid=input_0_eth_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + eth_payload_tdata=input_0_eth_payload_tdata, + eth_payload_tkeep=input_0_eth_payload_tkeep, + eth_payload_tvalid=input_0_eth_payload_tvalid, + eth_payload_tready=input_0_eth_payload_tready, + eth_payload_tlast=input_0_eth_payload_tlast, + eth_payload_tuser=input_0_eth_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_1_eth_hdr_ready, + eth_hdr_valid=input_1_eth_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + eth_payload_tdata=input_1_eth_payload_tdata, + eth_payload_tkeep=input_1_eth_payload_tkeep, + eth_payload_tvalid=input_1_eth_payload_tvalid, + eth_payload_tready=input_1_eth_payload_tready, + eth_payload_tlast=input_1_eth_payload_tlast, + eth_payload_tuser=input_1_eth_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_2_eth_hdr_ready, + eth_hdr_valid=input_2_eth_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + eth_payload_tdata=input_2_eth_payload_tdata, + eth_payload_tkeep=input_2_eth_payload_tkeep, + eth_payload_tvalid=input_2_eth_payload_tvalid, + eth_payload_tready=input_2_eth_payload_tready, + eth_payload_tlast=input_2_eth_payload_tlast, + eth_payload_tuser=input_2_eth_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_3_eth_hdr_ready, + eth_hdr_valid=input_3_eth_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + eth_payload_tdata=input_3_eth_payload_tdata, + eth_payload_tkeep=input_3_eth_payload_tkeep, + eth_payload_tvalid=input_3_eth_payload_tvalid, + eth_payload_tready=input_3_eth_payload_tready, + eth_payload_tlast=input_3_eth_payload_tlast, + eth_payload_tuser=input_3_eth_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_eth_mux_64_4(clk, + rst, + current_test, + + input_0_eth_hdr_valid, + input_0_eth_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tkeep, + input_0_eth_payload_tvalid, + input_0_eth_payload_tready, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tkeep, + input_1_eth_payload_tvalid, + input_1_eth_payload_tready, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tkeep, + input_2_eth_payload_tvalid, + input_2_eth_payload_tready, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tkeep, + input_3_eth_payload_tvalid, + input_3_eth_payload_tready, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + select) + + @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: select port 0") + current_test.next = 1 + + select.next = 0 + + 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(range(32)) + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.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(range(32)) + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + 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(range(32)) + 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(range(32)) + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + yield clk.posedge + select.next = 2 + 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: alterate pause source") + current_test.next = 5 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + select.next = 2 + 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: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + select.next = 2 + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_eth_mux_64_4.v b/tb/test_eth_mux_64_4.v new file mode 100644 index 000000000..e979f0a61 --- /dev/null +++ b/tb/test_eth_mux_64_4.v @@ -0,0 +1,230 @@ +/* + +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_eth_mux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_eth_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [63:0] input_0_eth_payload_tdata = 0; +reg [7:0] input_0_eth_payload_tkeep = 0; +reg input_0_eth_payload_tvalid = 0; +reg input_0_eth_payload_tlast = 0; +reg input_0_eth_payload_tuser = 0; +reg input_1_eth_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [63:0] input_1_eth_payload_tdata = 0; +reg [7:0] input_1_eth_payload_tkeep = 0; +reg input_1_eth_payload_tvalid = 0; +reg input_1_eth_payload_tlast = 0; +reg input_1_eth_payload_tuser = 0; +reg input_2_eth_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [63:0] input_2_eth_payload_tdata = 0; +reg [7:0] input_2_eth_payload_tkeep = 0; +reg input_2_eth_payload_tvalid = 0; +reg input_2_eth_payload_tlast = 0; +reg input_2_eth_payload_tuser = 0; +reg input_3_eth_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [63:0] input_3_eth_payload_tdata = 0; +reg [7:0] input_3_eth_payload_tkeep = 0; +reg input_3_eth_payload_tvalid = 0; +reg input_3_eth_payload_tlast = 0; +reg input_3_eth_payload_tuser = 0; + +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +reg [1:0] select = 0; + +// Outputs +wire input_0_eth_payload_tready; +wire input_0_eth_hdr_ready; +wire input_1_eth_payload_tready; +wire input_1_eth_hdr_ready; +wire input_2_eth_payload_tready; +wire input_2_eth_hdr_ready; +wire input_3_eth_payload_tready; +wire input_3_eth_hdr_ready; + +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [63:0] output_eth_payload_tdata; +wire [7:0] output_eth_payload_tkeep; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_eth_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tkeep, + input_0_eth_payload_tvalid, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tkeep, + input_1_eth_payload_tvalid, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tkeep, + input_2_eth_payload_tvalid, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tkeep, + input_3_eth_payload_tvalid, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + select); + $to_myhdl(input_0_eth_hdr_ready, + input_0_eth_payload_tready, + input_1_eth_hdr_ready, + input_1_eth_payload_tready, + input_2_eth_hdr_ready, + input_2_eth_payload_tready, + input_3_eth_hdr_ready, + input_3_eth_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser); + + // dump file + $dumpfile("test_eth_mux_64_4.lxt"); + $dumpvars(0, test_eth_mux_64_4); +end + +eth_mux_64_4 +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame inputs + .input_0_eth_hdr_valid(input_0_eth_hdr_valid), + .input_0_eth_hdr_ready(input_0_eth_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_eth_payload_tdata(input_0_eth_payload_tdata), + .input_0_eth_payload_tkeep(input_0_eth_payload_tkeep), + .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid), + .input_0_eth_payload_tready(input_0_eth_payload_tready), + .input_0_eth_payload_tlast(input_0_eth_payload_tlast), + .input_0_eth_payload_tuser(input_0_eth_payload_tuser), + .input_1_eth_hdr_valid(input_1_eth_hdr_valid), + .input_1_eth_hdr_ready(input_1_eth_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_eth_payload_tdata(input_1_eth_payload_tdata), + .input_1_eth_payload_tkeep(input_1_eth_payload_tkeep), + .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid), + .input_1_eth_payload_tready(input_1_eth_payload_tready), + .input_1_eth_payload_tlast(input_1_eth_payload_tlast), + .input_1_eth_payload_tuser(input_1_eth_payload_tuser), + .input_2_eth_hdr_valid(input_2_eth_hdr_valid), + .input_2_eth_hdr_ready(input_2_eth_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_eth_payload_tdata(input_2_eth_payload_tdata), + .input_2_eth_payload_tkeep(input_2_eth_payload_tkeep), + .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid), + .input_2_eth_payload_tready(input_2_eth_payload_tready), + .input_2_eth_payload_tlast(input_2_eth_payload_tlast), + .input_2_eth_payload_tuser(input_2_eth_payload_tuser), + .input_3_eth_hdr_valid(input_3_eth_hdr_valid), + .input_3_eth_hdr_ready(input_3_eth_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_eth_payload_tdata(input_3_eth_payload_tdata), + .input_3_eth_payload_tkeep(input_3_eth_payload_tkeep), + .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid), + .input_3_eth_payload_tready(input_3_eth_payload_tready), + .input_3_eth_payload_tlast(input_3_eth_payload_tlast), + .input_3_eth_payload_tuser(input_3_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Control + .select(select) +); + +endmodule From c90d5141acd9a6cbe16b46b61647da4349eb5c77 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 14 Nov 2014 22:11:49 -0800 Subject: [PATCH 099/617] Add ethernet arbitrated mux module and testbench --- rtl/eth_arb_mux.py | 210 +++++++++++ rtl/eth_arb_mux_4.v | 190 ++++++++++ rtl/eth_arb_mux_64.py | 214 +++++++++++ rtl/eth_arb_mux_64_4.v | 200 ++++++++++ tb/test_eth_arb_mux_4.py | 698 ++++++++++++++++++++++++++++++++++ tb/test_eth_arb_mux_4.v | 210 +++++++++++ tb/test_eth_arb_mux_64_4.py | 723 ++++++++++++++++++++++++++++++++++++ tb/test_eth_arb_mux_64_4.v | 225 +++++++++++ 8 files changed, 2670 insertions(+) create mode 100755 rtl/eth_arb_mux.py create mode 100644 rtl/eth_arb_mux_4.v create mode 100755 rtl/eth_arb_mux_64.py create mode 100644 rtl/eth_arb_mux_64_4.v create mode 100755 tb/test_eth_arb_mux_4.py create mode 100644 tb/test_eth_arb_mux_4.v create mode 100755 tb/test_eth_arb_mux_64_4.py create mode 100644 tb/test_eth_arb_mux_64_4.v diff --git a/rtl/eth_arb_mux.py b/rtl/eth_arb_mux.py new file mode 100755 index 000000000..e3ac794ec --- /dev/null +++ b/rtl/eth_arb_mux.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python +"""eth_arb_mux + +Generates an arbitrated Ethernet mux with the specified number of ports + +Usage: eth_arb_mux [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "eth_arb_mux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * Ethernet {{n}} port arbitrated multiplexer + */ +module {{name}} # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY" +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_eth_hdr_valid, + output wire input_{{p}}_eth_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [7:0] input_{{p}}_eth_payload_tdata, + input wire input_{{p}}_eth_payload_tvalid, + output wire input_{{p}}_eth_payload_tready, + input wire input_{{p}}_eth_payload_tlast, + input wire input_{{p}}_eth_payload_tuser, +{% endfor %} + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser +); + +wire [{{n-1}}:0] request; +wire [{{n-1}}:0] acknowledge; +wire [{{n-1}}:0] grant; +wire [{{w-1}}:0] grant_encoded; +{% for p in ports %} +assign acknowledge[{{p}}] = input_{{p}}_eth_payload_tvalid & input_{{p}}_eth_payload_tready & input_{{p}}_eth_payload_tlast; +assign request[{{p}}] = input_{{p}}_eth_hdr_valid; +{%- endfor %} + +// mux instance +eth_mux_{{n}} +mux_inst ( + .clk(clk), + .rst(rst), +{%- for p in ports %} + .input_{{p}}_eth_hdr_valid(input_{{p}}_eth_hdr_valid & grant[{{p}}]), + .input_{{p}}_eth_hdr_ready(input_{{p}}_eth_hdr_ready), + .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), + .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), + .input_{{p}}_eth_type(input_{{p}}_eth_type), + .input_{{p}}_eth_payload_tdata(input_{{p}}_eth_payload_tdata), + .input_{{p}}_eth_payload_tvalid(input_{{p}}_eth_payload_tvalid & grant[{{p}}]), + .input_{{p}}_eth_payload_tready(input_{{p}}_eth_payload_tready), + .input_{{p}}_eth_payload_tlast(input_{{p}}_eth_payload_tlast), + .input_{{p}}_eth_payload_tuser(input_{{p}}_eth_payload_tuser), +{%- endfor %} + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS({{n}}), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE") +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_encoded(grant_encoded) +); + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/eth_arb_mux_4.v b/rtl/eth_arb_mux_4.v new file mode 100644 index 000000000..93c877d5e --- /dev/null +++ b/rtl/eth_arb_mux_4.v @@ -0,0 +1,190 @@ +/* + +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 + +/* + * Ethernet 4 port arbitrated multiplexer + */ +module eth_arb_mux_4 # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY" +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ + input wire input_0_eth_hdr_valid, + output wire input_0_eth_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [7:0] input_0_eth_payload_tdata, + input wire input_0_eth_payload_tvalid, + output wire input_0_eth_payload_tready, + input wire input_0_eth_payload_tlast, + input wire input_0_eth_payload_tuser, + + input wire input_1_eth_hdr_valid, + output wire input_1_eth_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [7:0] input_1_eth_payload_tdata, + input wire input_1_eth_payload_tvalid, + output wire input_1_eth_payload_tready, + input wire input_1_eth_payload_tlast, + input wire input_1_eth_payload_tuser, + + input wire input_2_eth_hdr_valid, + output wire input_2_eth_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [7:0] input_2_eth_payload_tdata, + input wire input_2_eth_payload_tvalid, + output wire input_2_eth_payload_tready, + input wire input_2_eth_payload_tlast, + input wire input_2_eth_payload_tuser, + + input wire input_3_eth_hdr_valid, + output wire input_3_eth_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [7:0] input_3_eth_payload_tdata, + input wire input_3_eth_payload_tvalid, + output wire input_3_eth_payload_tready, + input wire input_3_eth_payload_tlast, + input wire input_3_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser +); + +wire [3:0] request; +wire [3:0] acknowledge; +wire [3:0] grant; +wire [1:0] grant_encoded; + +assign acknowledge[0] = input_0_eth_payload_tvalid & input_0_eth_payload_tready & input_0_eth_payload_tlast; +assign request[0] = input_0_eth_hdr_valid; +assign acknowledge[1] = input_1_eth_payload_tvalid & input_1_eth_payload_tready & input_1_eth_payload_tlast; +assign request[1] = input_1_eth_hdr_valid; +assign acknowledge[2] = input_2_eth_payload_tvalid & input_2_eth_payload_tready & input_2_eth_payload_tlast; +assign request[2] = input_2_eth_hdr_valid; +assign acknowledge[3] = input_3_eth_payload_tvalid & input_3_eth_payload_tready & input_3_eth_payload_tlast; +assign request[3] = input_3_eth_hdr_valid; + +// mux instance +eth_mux_4 +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_eth_hdr_valid(input_0_eth_hdr_valid & grant[0]), + .input_0_eth_hdr_ready(input_0_eth_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_eth_payload_tdata(input_0_eth_payload_tdata), + .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid & grant[0]), + .input_0_eth_payload_tready(input_0_eth_payload_tready), + .input_0_eth_payload_tlast(input_0_eth_payload_tlast), + .input_0_eth_payload_tuser(input_0_eth_payload_tuser), + .input_1_eth_hdr_valid(input_1_eth_hdr_valid & grant[1]), + .input_1_eth_hdr_ready(input_1_eth_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_eth_payload_tdata(input_1_eth_payload_tdata), + .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid & grant[1]), + .input_1_eth_payload_tready(input_1_eth_payload_tready), + .input_1_eth_payload_tlast(input_1_eth_payload_tlast), + .input_1_eth_payload_tuser(input_1_eth_payload_tuser), + .input_2_eth_hdr_valid(input_2_eth_hdr_valid & grant[2]), + .input_2_eth_hdr_ready(input_2_eth_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_eth_payload_tdata(input_2_eth_payload_tdata), + .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid & grant[2]), + .input_2_eth_payload_tready(input_2_eth_payload_tready), + .input_2_eth_payload_tlast(input_2_eth_payload_tlast), + .input_2_eth_payload_tuser(input_2_eth_payload_tuser), + .input_3_eth_hdr_valid(input_3_eth_hdr_valid & grant[3]), + .input_3_eth_hdr_ready(input_3_eth_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_eth_payload_tdata(input_3_eth_payload_tdata), + .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid & grant[3]), + .input_3_eth_payload_tready(input_3_eth_payload_tready), + .input_3_eth_payload_tlast(input_3_eth_payload_tlast), + .input_3_eth_payload_tuser(input_3_eth_payload_tuser), + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE") +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/rtl/eth_arb_mux_64.py b/rtl/eth_arb_mux_64.py new file mode 100755 index 000000000..49e2ed822 --- /dev/null +++ b/rtl/eth_arb_mux_64.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +"""eth_arb_mux_64 + +Generates an arbitrated Ethernet mux with the specified number of ports + +Usage: eth_arb_mux_64 [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "eth_arb_mux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * Ethernet {{n}} port arbitrated multiplexer (64 bit datapath) + */ +module {{name}} # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY" +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_eth_hdr_valid, + output wire input_{{p}}_eth_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [63:0] input_{{p}}_eth_payload_tdata, + input wire [7:0] input_{{p}}_eth_payload_tkeep, + input wire input_{{p}}_eth_payload_tvalid, + output wire input_{{p}}_eth_payload_tready, + input wire input_{{p}}_eth_payload_tlast, + input wire input_{{p}}_eth_payload_tuser, +{% endfor %} + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser +); + +wire [{{n-1}}:0] request; +wire [{{n-1}}:0] acknowledge; +wire [{{n-1}}:0] grant; +wire [{{w-1}}:0] grant_encoded; +{% for p in ports %} +assign acknowledge[{{p}}] = input_{{p}}_eth_payload_tvalid & input_{{p}}_eth_payload_tready & input_{{p}}_eth_payload_tlast; +assign request[{{p}}] = input_{{p}}_eth_hdr_valid; +{%- endfor %} + +// mux instance +eth_mux_64_{{n}} +mux_inst ( + .clk(clk), + .rst(rst), +{%- for p in ports %} + .input_{{p}}_eth_hdr_valid(input_{{p}}_eth_hdr_valid & grant[{{p}}]), + .input_{{p}}_eth_hdr_ready(input_{{p}}_eth_hdr_ready), + .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), + .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), + .input_{{p}}_eth_type(input_{{p}}_eth_type), + .input_{{p}}_eth_payload_tdata(input_{{p}}_eth_payload_tdata), + .input_{{p}}_eth_payload_tkeep(input_{{p}}_eth_payload_tkeep), + .input_{{p}}_eth_payload_tvalid(input_{{p}}_eth_payload_tvalid & grant[{{p}}]), + .input_{{p}}_eth_payload_tready(input_{{p}}_eth_payload_tready), + .input_{{p}}_eth_payload_tlast(input_{{p}}_eth_payload_tlast), + .input_{{p}}_eth_payload_tuser(input_{{p}}_eth_payload_tuser), +{%- endfor %} + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS({{n}}), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE") +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_encoded(grant_encoded) +); + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/eth_arb_mux_64_4.v b/rtl/eth_arb_mux_64_4.v new file mode 100644 index 000000000..64f48aed0 --- /dev/null +++ b/rtl/eth_arb_mux_64_4.v @@ -0,0 +1,200 @@ +/* + +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 + +/* + * Ethernet 4 port arbitrated multiplexer (64 bit datapath) + */ +module eth_arb_mux_64_4 # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY" +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ + input wire input_0_eth_hdr_valid, + output wire input_0_eth_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [63:0] input_0_eth_payload_tdata, + input wire [7:0] input_0_eth_payload_tkeep, + input wire input_0_eth_payload_tvalid, + output wire input_0_eth_payload_tready, + input wire input_0_eth_payload_tlast, + input wire input_0_eth_payload_tuser, + + input wire input_1_eth_hdr_valid, + output wire input_1_eth_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [63:0] input_1_eth_payload_tdata, + input wire [7:0] input_1_eth_payload_tkeep, + input wire input_1_eth_payload_tvalid, + output wire input_1_eth_payload_tready, + input wire input_1_eth_payload_tlast, + input wire input_1_eth_payload_tuser, + + input wire input_2_eth_hdr_valid, + output wire input_2_eth_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [63:0] input_2_eth_payload_tdata, + input wire [7:0] input_2_eth_payload_tkeep, + input wire input_2_eth_payload_tvalid, + output wire input_2_eth_payload_tready, + input wire input_2_eth_payload_tlast, + input wire input_2_eth_payload_tuser, + + input wire input_3_eth_hdr_valid, + output wire input_3_eth_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [63:0] input_3_eth_payload_tdata, + input wire [7:0] input_3_eth_payload_tkeep, + input wire input_3_eth_payload_tvalid, + output wire input_3_eth_payload_tready, + input wire input_3_eth_payload_tlast, + input wire input_3_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser +); + +wire [3:0] request; +wire [3:0] acknowledge; +wire [3:0] grant; +wire [1:0] grant_encoded; + +assign acknowledge[0] = input_0_eth_payload_tvalid & input_0_eth_payload_tready & input_0_eth_payload_tlast; +assign request[0] = input_0_eth_hdr_valid; +assign acknowledge[1] = input_1_eth_payload_tvalid & input_1_eth_payload_tready & input_1_eth_payload_tlast; +assign request[1] = input_1_eth_hdr_valid; +assign acknowledge[2] = input_2_eth_payload_tvalid & input_2_eth_payload_tready & input_2_eth_payload_tlast; +assign request[2] = input_2_eth_hdr_valid; +assign acknowledge[3] = input_3_eth_payload_tvalid & input_3_eth_payload_tready & input_3_eth_payload_tlast; +assign request[3] = input_3_eth_hdr_valid; + +// mux instance +eth_mux_64_4 +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_eth_hdr_valid(input_0_eth_hdr_valid & grant[0]), + .input_0_eth_hdr_ready(input_0_eth_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_eth_payload_tdata(input_0_eth_payload_tdata), + .input_0_eth_payload_tkeep(input_0_eth_payload_tkeep), + .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid & grant[0]), + .input_0_eth_payload_tready(input_0_eth_payload_tready), + .input_0_eth_payload_tlast(input_0_eth_payload_tlast), + .input_0_eth_payload_tuser(input_0_eth_payload_tuser), + .input_1_eth_hdr_valid(input_1_eth_hdr_valid & grant[1]), + .input_1_eth_hdr_ready(input_1_eth_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_eth_payload_tdata(input_1_eth_payload_tdata), + .input_1_eth_payload_tkeep(input_1_eth_payload_tkeep), + .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid & grant[1]), + .input_1_eth_payload_tready(input_1_eth_payload_tready), + .input_1_eth_payload_tlast(input_1_eth_payload_tlast), + .input_1_eth_payload_tuser(input_1_eth_payload_tuser), + .input_2_eth_hdr_valid(input_2_eth_hdr_valid & grant[2]), + .input_2_eth_hdr_ready(input_2_eth_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_eth_payload_tdata(input_2_eth_payload_tdata), + .input_2_eth_payload_tkeep(input_2_eth_payload_tkeep), + .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid & grant[2]), + .input_2_eth_payload_tready(input_2_eth_payload_tready), + .input_2_eth_payload_tlast(input_2_eth_payload_tlast), + .input_2_eth_payload_tuser(input_2_eth_payload_tuser), + .input_3_eth_hdr_valid(input_3_eth_hdr_valid & grant[3]), + .input_3_eth_hdr_ready(input_3_eth_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_eth_payload_tdata(input_3_eth_payload_tdata), + .input_3_eth_payload_tkeep(input_3_eth_payload_tkeep), + .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid & grant[3]), + .input_3_eth_payload_tready(input_3_eth_payload_tready), + .input_3_eth_payload_tlast(input_3_eth_payload_tlast), + .input_3_eth_payload_tuser(input_3_eth_payload_tuser), + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE") +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/tb/test_eth_arb_mux_4.py b/tb/test_eth_arb_mux_4.py new file mode 100755 index 000000000..84347fac0 --- /dev/null +++ b/tb/test_eth_arb_mux_4.py @@ -0,0 +1,698 @@ +#!/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 eth_ep + +module = 'eth_arb_mux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_mux_4.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_arb_mux_4(clk, + rst, + current_test, + + input_0_eth_hdr_valid, + input_0_eth_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tvalid, + input_0_eth_payload_tready, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tvalid, + input_1_eth_payload_tready, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tvalid, + input_2_eth_payload_tready, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tvalid, + input_3_eth_payload_tready, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_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_0_eth_hdr_valid=input_0_eth_hdr_valid, + input_0_eth_hdr_ready=input_0_eth_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_eth_payload_tdata=input_0_eth_payload_tdata, + input_0_eth_payload_tvalid=input_0_eth_payload_tvalid, + input_0_eth_payload_tready=input_0_eth_payload_tready, + input_0_eth_payload_tlast=input_0_eth_payload_tlast, + input_0_eth_payload_tuser=input_0_eth_payload_tuser, + input_1_eth_hdr_valid=input_1_eth_hdr_valid, + input_1_eth_hdr_ready=input_1_eth_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_eth_payload_tdata=input_1_eth_payload_tdata, + input_1_eth_payload_tvalid=input_1_eth_payload_tvalid, + input_1_eth_payload_tready=input_1_eth_payload_tready, + input_1_eth_payload_tlast=input_1_eth_payload_tlast, + input_1_eth_payload_tuser=input_1_eth_payload_tuser, + input_2_eth_hdr_valid=input_2_eth_hdr_valid, + input_2_eth_hdr_ready=input_2_eth_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_eth_payload_tdata=input_2_eth_payload_tdata, + input_2_eth_payload_tvalid=input_2_eth_payload_tvalid, + input_2_eth_payload_tready=input_2_eth_payload_tready, + input_2_eth_payload_tlast=input_2_eth_payload_tlast, + input_2_eth_payload_tuser=input_2_eth_payload_tuser, + input_3_eth_hdr_valid=input_3_eth_hdr_valid, + input_3_eth_hdr_ready=input_3_eth_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_eth_payload_tdata=input_3_eth_payload_tdata, + input_3_eth_payload_tvalid=input_3_eth_payload_tvalid, + input_3_eth_payload_tready=input_3_eth_payload_tready, + input_3_eth_payload_tlast=input_3_eth_payload_tlast, + input_3_eth_payload_tuser=input_3_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_eth_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_eth_payload_tdata = Signal(intbv(0)[8:]) + input_0_eth_payload_tvalid = Signal(bool(0)) + input_0_eth_payload_tlast = Signal(bool(0)) + input_0_eth_payload_tuser = Signal(bool(0)) + input_1_eth_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_eth_payload_tdata = Signal(intbv(0)[8:]) + input_1_eth_payload_tvalid = Signal(bool(0)) + input_1_eth_payload_tlast = Signal(bool(0)) + input_1_eth_payload_tuser = Signal(bool(0)) + input_2_eth_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_eth_payload_tdata = Signal(intbv(0)[8:]) + input_2_eth_payload_tvalid = Signal(bool(0)) + input_2_eth_payload_tlast = Signal(bool(0)) + input_2_eth_payload_tuser = Signal(bool(0)) + input_3_eth_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_eth_payload_tdata = Signal(intbv(0)[8:]) + input_3_eth_payload_tvalid = Signal(bool(0)) + input_3_eth_payload_tlast = Signal(bool(0)) + input_3_eth_payload_tuser = Signal(bool(0)) + + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + # Outputs + input_0_eth_hdr_ready = Signal(bool(0)) + input_0_eth_payload_tready = Signal(bool(0)) + input_1_eth_hdr_ready = Signal(bool(0)) + input_1_eth_payload_tready = Signal(bool(0)) + input_2_eth_hdr_ready = Signal(bool(0)) + input_2_eth_payload_tready = Signal(bool(0)) + input_3_eth_hdr_ready = Signal(bool(0)) + input_3_eth_payload_tready = Signal(bool(0)) + + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_0_eth_hdr_ready, + eth_hdr_valid=input_0_eth_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + eth_payload_tdata=input_0_eth_payload_tdata, + eth_payload_tvalid=input_0_eth_payload_tvalid, + eth_payload_tready=input_0_eth_payload_tready, + eth_payload_tlast=input_0_eth_payload_tlast, + eth_payload_tuser=input_0_eth_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_1_eth_hdr_ready, + eth_hdr_valid=input_1_eth_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + eth_payload_tdata=input_1_eth_payload_tdata, + eth_payload_tvalid=input_1_eth_payload_tvalid, + eth_payload_tready=input_1_eth_payload_tready, + eth_payload_tlast=input_1_eth_payload_tlast, + eth_payload_tuser=input_1_eth_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_2_eth_hdr_ready, + eth_hdr_valid=input_2_eth_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + eth_payload_tdata=input_2_eth_payload_tdata, + eth_payload_tvalid=input_2_eth_payload_tvalid, + eth_payload_tready=input_2_eth_payload_tready, + eth_payload_tlast=input_2_eth_payload_tlast, + eth_payload_tuser=input_2_eth_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_3_eth_hdr_ready, + eth_hdr_valid=input_3_eth_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + eth_payload_tdata=input_3_eth_payload_tdata, + eth_payload_tvalid=input_3_eth_payload_tvalid, + eth_payload_tready=input_3_eth_payload_tready, + eth_payload_tlast=input_3_eth_payload_tlast, + eth_payload_tuser=input_3_eth_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_eth_arb_mux_4(clk, + rst, + current_test, + + input_0_eth_hdr_valid, + input_0_eth_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tvalid, + input_0_eth_payload_tready, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tvalid, + input_1_eth_payload_tready, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tvalid, + input_2_eth_payload_tready, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tvalid, + input_3_eth_payload_tready, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_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: port 0") + current_test.next = 1 + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A0052535455 + test_frame.eth_type = 0x8000 + test_frame.payload = bytearray(range(32)) + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: port 1") + current_test.next = 2 + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A0152535455 + test_frame.eth_type = 0x8000 + test_frame.payload = bytearray(range(32)) + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0052535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + test_frame2 = eth_ep.EthFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0052535455 + test_frame2.eth_type = 0x8000 + test_frame2.payload = bytearray(range(32)) + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + test_frame2 = eth_ep.EthFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.payload = bytearray(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + 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_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + test_frame2 = eth_ep.EthFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.payload = bytearray(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + test_frame2 = eth_ep.EthFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.payload = bytearray(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_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 + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 7: back-to-back packets, different ports, arbitration test") + current_test.next = 7 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + test_frame2 = eth_ep.EthFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.payload = bytearray(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + yield clk.posedge + + yield delay(800) + yield clk.posedge + source_2_queue.put(test_frame2) + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + 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_frame2 + + 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_frame1 + + 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 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_eth_arb_mux_4.v b/tb/test_eth_arb_mux_4.v new file mode 100644 index 000000000..9b7130ea7 --- /dev/null +++ b/tb/test_eth_arb_mux_4.v @@ -0,0 +1,210 @@ +/* + +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_eth_arb_mux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_eth_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [7:0] input_0_eth_payload_tdata = 0; +reg input_0_eth_payload_tvalid = 0; +reg input_0_eth_payload_tlast = 0; +reg input_0_eth_payload_tuser = 0; +reg input_1_eth_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [7:0] input_1_eth_payload_tdata = 0; +reg input_1_eth_payload_tvalid = 0; +reg input_1_eth_payload_tlast = 0; +reg input_1_eth_payload_tuser = 0; +reg input_2_eth_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [7:0] input_2_eth_payload_tdata = 0; +reg input_2_eth_payload_tvalid = 0; +reg input_2_eth_payload_tlast = 0; +reg input_2_eth_payload_tuser = 0; +reg input_3_eth_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [7:0] input_3_eth_payload_tdata = 0; +reg input_3_eth_payload_tvalid = 0; +reg input_3_eth_payload_tlast = 0; +reg input_3_eth_payload_tuser = 0; + +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +// Outputs +wire input_0_eth_payload_tready; +wire input_0_eth_hdr_ready; +wire input_1_eth_payload_tready; +wire input_1_eth_hdr_ready; +wire input_2_eth_payload_tready; +wire input_2_eth_hdr_ready; +wire input_3_eth_payload_tready; +wire input_3_eth_hdr_ready; + +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [7:0] output_eth_payload_tdata; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_eth_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tvalid, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tvalid, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tvalid, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tvalid, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready); + $to_myhdl(input_0_eth_hdr_ready, + input_0_eth_payload_tready, + input_1_eth_hdr_ready, + input_1_eth_payload_tready, + input_2_eth_hdr_ready, + input_2_eth_payload_tready, + input_3_eth_hdr_ready, + input_3_eth_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser); + + // dump file + $dumpfile("test_eth_arb_mux_4.lxt"); + $dumpvars(0, test_eth_arb_mux_4); +end + +eth_arb_mux_4 +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame inputs + .input_0_eth_hdr_valid(input_0_eth_hdr_valid), + .input_0_eth_hdr_ready(input_0_eth_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_eth_payload_tdata(input_0_eth_payload_tdata), + .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid), + .input_0_eth_payload_tready(input_0_eth_payload_tready), + .input_0_eth_payload_tlast(input_0_eth_payload_tlast), + .input_0_eth_payload_tuser(input_0_eth_payload_tuser), + .input_1_eth_hdr_valid(input_1_eth_hdr_valid), + .input_1_eth_hdr_ready(input_1_eth_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_eth_payload_tdata(input_1_eth_payload_tdata), + .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid), + .input_1_eth_payload_tready(input_1_eth_payload_tready), + .input_1_eth_payload_tlast(input_1_eth_payload_tlast), + .input_1_eth_payload_tuser(input_1_eth_payload_tuser), + .input_2_eth_hdr_valid(input_2_eth_hdr_valid), + .input_2_eth_hdr_ready(input_2_eth_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_eth_payload_tdata(input_2_eth_payload_tdata), + .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid), + .input_2_eth_payload_tready(input_2_eth_payload_tready), + .input_2_eth_payload_tlast(input_2_eth_payload_tlast), + .input_2_eth_payload_tuser(input_2_eth_payload_tuser), + .input_3_eth_hdr_valid(input_3_eth_hdr_valid), + .input_3_eth_hdr_ready(input_3_eth_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_eth_payload_tdata(input_3_eth_payload_tdata), + .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid), + .input_3_eth_payload_tready(input_3_eth_payload_tready), + .input_3_eth_payload_tlast(input_3_eth_payload_tlast), + .input_3_eth_payload_tuser(input_3_eth_payload_tuser), + // Eth frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser) +); + +endmodule diff --git a/tb/test_eth_arb_mux_64_4.py b/tb/test_eth_arb_mux_64_4.py new file mode 100755 index 000000000..edf0ee619 --- /dev/null +++ b/tb/test_eth_arb_mux_64_4.py @@ -0,0 +1,723 @@ +#!/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 eth_ep + +module = 'eth_arb_mux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_mux_64_4.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_arb_mux_64_4(clk, + rst, + current_test, + + input_0_eth_hdr_valid, + input_0_eth_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tkeep, + input_0_eth_payload_tvalid, + input_0_eth_payload_tready, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tkeep, + input_1_eth_payload_tvalid, + input_1_eth_payload_tready, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tkeep, + input_2_eth_payload_tvalid, + input_2_eth_payload_tready, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tkeep, + input_3_eth_payload_tvalid, + input_3_eth_payload_tready, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_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_0_eth_hdr_valid=input_0_eth_hdr_valid, + input_0_eth_hdr_ready=input_0_eth_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_eth_payload_tdata=input_0_eth_payload_tdata, + input_0_eth_payload_tkeep=input_0_eth_payload_tkeep, + input_0_eth_payload_tvalid=input_0_eth_payload_tvalid, + input_0_eth_payload_tready=input_0_eth_payload_tready, + input_0_eth_payload_tlast=input_0_eth_payload_tlast, + input_0_eth_payload_tuser=input_0_eth_payload_tuser, + input_1_eth_hdr_valid=input_1_eth_hdr_valid, + input_1_eth_hdr_ready=input_1_eth_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_eth_payload_tdata=input_1_eth_payload_tdata, + input_1_eth_payload_tkeep=input_1_eth_payload_tkeep, + input_1_eth_payload_tvalid=input_1_eth_payload_tvalid, + input_1_eth_payload_tready=input_1_eth_payload_tready, + input_1_eth_payload_tlast=input_1_eth_payload_tlast, + input_1_eth_payload_tuser=input_1_eth_payload_tuser, + input_2_eth_hdr_valid=input_2_eth_hdr_valid, + input_2_eth_hdr_ready=input_2_eth_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_eth_payload_tdata=input_2_eth_payload_tdata, + input_2_eth_payload_tkeep=input_2_eth_payload_tkeep, + input_2_eth_payload_tvalid=input_2_eth_payload_tvalid, + input_2_eth_payload_tready=input_2_eth_payload_tready, + input_2_eth_payload_tlast=input_2_eth_payload_tlast, + input_2_eth_payload_tuser=input_2_eth_payload_tuser, + input_3_eth_hdr_valid=input_3_eth_hdr_valid, + input_3_eth_hdr_ready=input_3_eth_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_eth_payload_tdata=input_3_eth_payload_tdata, + input_3_eth_payload_tkeep=input_3_eth_payload_tkeep, + input_3_eth_payload_tvalid=input_3_eth_payload_tvalid, + input_3_eth_payload_tready=input_3_eth_payload_tready, + input_3_eth_payload_tlast=input_3_eth_payload_tlast, + input_3_eth_payload_tuser=input_3_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_eth_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_eth_payload_tdata = Signal(intbv(0)[64:]) + input_0_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_0_eth_payload_tvalid = Signal(bool(0)) + input_0_eth_payload_tlast = Signal(bool(0)) + input_0_eth_payload_tuser = Signal(bool(0)) + input_1_eth_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_eth_payload_tdata = Signal(intbv(0)[64:]) + input_1_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_1_eth_payload_tvalid = Signal(bool(0)) + input_1_eth_payload_tlast = Signal(bool(0)) + input_1_eth_payload_tuser = Signal(bool(0)) + input_2_eth_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_eth_payload_tdata = Signal(intbv(0)[64:]) + input_2_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_2_eth_payload_tvalid = Signal(bool(0)) + input_2_eth_payload_tlast = Signal(bool(0)) + input_2_eth_payload_tuser = Signal(bool(0)) + input_3_eth_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_eth_payload_tdata = Signal(intbv(0)[64:]) + input_3_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_3_eth_payload_tvalid = Signal(bool(0)) + input_3_eth_payload_tlast = Signal(bool(0)) + input_3_eth_payload_tuser = Signal(bool(0)) + + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + # Outputs + input_0_eth_hdr_ready = Signal(bool(0)) + input_0_eth_payload_tready = Signal(bool(0)) + input_1_eth_hdr_ready = Signal(bool(0)) + input_1_eth_payload_tready = Signal(bool(0)) + input_2_eth_hdr_ready = Signal(bool(0)) + input_2_eth_payload_tready = Signal(bool(0)) + input_3_eth_hdr_ready = Signal(bool(0)) + input_3_eth_payload_tready = Signal(bool(0)) + + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[64:]) + output_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_0_eth_hdr_ready, + eth_hdr_valid=input_0_eth_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + eth_payload_tdata=input_0_eth_payload_tdata, + eth_payload_tkeep=input_0_eth_payload_tkeep, + eth_payload_tvalid=input_0_eth_payload_tvalid, + eth_payload_tready=input_0_eth_payload_tready, + eth_payload_tlast=input_0_eth_payload_tlast, + eth_payload_tuser=input_0_eth_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_1_eth_hdr_ready, + eth_hdr_valid=input_1_eth_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + eth_payload_tdata=input_1_eth_payload_tdata, + eth_payload_tkeep=input_1_eth_payload_tkeep, + eth_payload_tvalid=input_1_eth_payload_tvalid, + eth_payload_tready=input_1_eth_payload_tready, + eth_payload_tlast=input_1_eth_payload_tlast, + eth_payload_tuser=input_1_eth_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_2_eth_hdr_ready, + eth_hdr_valid=input_2_eth_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + eth_payload_tdata=input_2_eth_payload_tdata, + eth_payload_tkeep=input_2_eth_payload_tkeep, + eth_payload_tvalid=input_2_eth_payload_tvalid, + eth_payload_tready=input_2_eth_payload_tready, + eth_payload_tlast=input_2_eth_payload_tlast, + eth_payload_tuser=input_2_eth_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_3_eth_hdr_ready, + eth_hdr_valid=input_3_eth_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + eth_payload_tdata=input_3_eth_payload_tdata, + eth_payload_tkeep=input_3_eth_payload_tkeep, + eth_payload_tvalid=input_3_eth_payload_tvalid, + eth_payload_tready=input_3_eth_payload_tready, + eth_payload_tlast=input_3_eth_payload_tlast, + eth_payload_tuser=input_3_eth_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_eth_arb_mux_64_4(clk, + rst, + current_test, + + input_0_eth_hdr_valid, + input_0_eth_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tkeep, + input_0_eth_payload_tvalid, + input_0_eth_payload_tready, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tkeep, + input_1_eth_payload_tvalid, + input_1_eth_payload_tready, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tkeep, + input_2_eth_payload_tvalid, + input_2_eth_payload_tready, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tkeep, + input_3_eth_payload_tvalid, + input_3_eth_payload_tready, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_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: port 0") + current_test.next = 1 + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A0052535455 + test_frame.eth_type = 0x8000 + test_frame.payload = bytearray(range(32)) + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: port 1") + current_test.next = 2 + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A0152535455 + test_frame.eth_type = 0x8000 + test_frame.payload = bytearray(range(32)) + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0052535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + test_frame2 = eth_ep.EthFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0052535455 + test_frame2.eth_type = 0x8000 + test_frame2.payload = bytearray(range(32)) + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + test_frame2 = eth_ep.EthFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.payload = bytearray(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + 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_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + test_frame2 = eth_ep.EthFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.payload = bytearray(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + test_frame2 = eth_ep.EthFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.payload = bytearray(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_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 + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + yield clk.posedge + print("test 7: back-to-back packets, different ports, arbitration test") + current_test.next = 7 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(32)) + test_frame2 = eth_ep.EthFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.payload = bytearray(range(32)) + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + source_1_queue.put(test_frame1) + yield clk.posedge + + yield delay(150) + yield clk.posedge + source_2_queue.put(test_frame2) + + while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + 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_frame2 + + 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_frame1 + + 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 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame1 + + yield delay(100) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_eth_arb_mux_64_4.v b/tb/test_eth_arb_mux_64_4.v new file mode 100644 index 000000000..d7a1b6f57 --- /dev/null +++ b/tb/test_eth_arb_mux_64_4.v @@ -0,0 +1,225 @@ +/* + +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_eth_arb_mux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_eth_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [63:0] input_0_eth_payload_tdata = 0; +reg [7:0] input_0_eth_payload_tkeep = 0; +reg input_0_eth_payload_tvalid = 0; +reg input_0_eth_payload_tlast = 0; +reg input_0_eth_payload_tuser = 0; +reg input_1_eth_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [63:0] input_1_eth_payload_tdata = 0; +reg [7:0] input_1_eth_payload_tkeep = 0; +reg input_1_eth_payload_tvalid = 0; +reg input_1_eth_payload_tlast = 0; +reg input_1_eth_payload_tuser = 0; +reg input_2_eth_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [63:0] input_2_eth_payload_tdata = 0; +reg [7:0] input_2_eth_payload_tkeep = 0; +reg input_2_eth_payload_tvalid = 0; +reg input_2_eth_payload_tlast = 0; +reg input_2_eth_payload_tuser = 0; +reg input_3_eth_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [63:0] input_3_eth_payload_tdata = 0; +reg [7:0] input_3_eth_payload_tkeep = 0; +reg input_3_eth_payload_tvalid = 0; +reg input_3_eth_payload_tlast = 0; +reg input_3_eth_payload_tuser = 0; + +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +// Outputs +wire input_0_eth_payload_tready; +wire input_0_eth_hdr_ready; +wire input_1_eth_payload_tready; +wire input_1_eth_hdr_ready; +wire input_2_eth_payload_tready; +wire input_2_eth_hdr_ready; +wire input_3_eth_payload_tready; +wire input_3_eth_hdr_ready; + +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [63:0] output_eth_payload_tdata; +wire [7:0] output_eth_payload_tkeep; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_eth_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_eth_payload_tdata, + input_0_eth_payload_tkeep, + input_0_eth_payload_tvalid, + input_0_eth_payload_tlast, + input_0_eth_payload_tuser, + input_1_eth_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_eth_payload_tdata, + input_1_eth_payload_tkeep, + input_1_eth_payload_tvalid, + input_1_eth_payload_tlast, + input_1_eth_payload_tuser, + input_2_eth_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_eth_payload_tdata, + input_2_eth_payload_tkeep, + input_2_eth_payload_tvalid, + input_2_eth_payload_tlast, + input_2_eth_payload_tuser, + input_3_eth_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_eth_payload_tdata, + input_3_eth_payload_tkeep, + input_3_eth_payload_tvalid, + input_3_eth_payload_tlast, + input_3_eth_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready); + $to_myhdl(input_0_eth_hdr_ready, + input_0_eth_payload_tready, + input_1_eth_hdr_ready, + input_1_eth_payload_tready, + input_2_eth_hdr_ready, + input_2_eth_payload_tready, + input_3_eth_hdr_ready, + input_3_eth_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser); + + // dump file + $dumpfile("test_eth_arb_mux_64_4.lxt"); + $dumpvars(0, test_eth_arb_mux_64_4); +end + +eth_arb_mux_64_4 +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame inputs + .input_0_eth_hdr_valid(input_0_eth_hdr_valid), + .input_0_eth_hdr_ready(input_0_eth_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_eth_payload_tdata(input_0_eth_payload_tdata), + .input_0_eth_payload_tkeep(input_0_eth_payload_tkeep), + .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid), + .input_0_eth_payload_tready(input_0_eth_payload_tready), + .input_0_eth_payload_tlast(input_0_eth_payload_tlast), + .input_0_eth_payload_tuser(input_0_eth_payload_tuser), + .input_1_eth_hdr_valid(input_1_eth_hdr_valid), + .input_1_eth_hdr_ready(input_1_eth_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_eth_payload_tdata(input_1_eth_payload_tdata), + .input_1_eth_payload_tkeep(input_1_eth_payload_tkeep), + .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid), + .input_1_eth_payload_tready(input_1_eth_payload_tready), + .input_1_eth_payload_tlast(input_1_eth_payload_tlast), + .input_1_eth_payload_tuser(input_1_eth_payload_tuser), + .input_2_eth_hdr_valid(input_2_eth_hdr_valid), + .input_2_eth_hdr_ready(input_2_eth_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_eth_payload_tdata(input_2_eth_payload_tdata), + .input_2_eth_payload_tkeep(input_2_eth_payload_tkeep), + .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid), + .input_2_eth_payload_tready(input_2_eth_payload_tready), + .input_2_eth_payload_tlast(input_2_eth_payload_tlast), + .input_2_eth_payload_tuser(input_2_eth_payload_tuser), + .input_3_eth_hdr_valid(input_3_eth_hdr_valid), + .input_3_eth_hdr_ready(input_3_eth_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_eth_payload_tdata(input_3_eth_payload_tdata), + .input_3_eth_payload_tkeep(input_3_eth_payload_tkeep), + .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid), + .input_3_eth_payload_tready(input_3_eth_payload_tready), + .input_3_eth_payload_tlast(input_3_eth_payload_tlast), + .input_3_eth_payload_tuser(input_3_eth_payload_tuser), + // Eth frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser) +); + +endmodule From b123525597237792fed0eef17df5985b2f5fab01 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Nov 2014 01:38:20 -0800 Subject: [PATCH 100/617] Add enable signal --- rtl/axis_arb_mux.py | 3 +++ rtl/axis_arb_mux_4.v | 3 +++ rtl/axis_arb_mux_64.py | 3 +++ rtl/axis_arb_mux_64_4.v | 3 +++ rtl/axis_demux.py | 3 ++- rtl/axis_demux_4.v | 3 ++- rtl/axis_demux_64.py | 3 ++- rtl/axis_demux_64_4.v | 3 ++- rtl/axis_mux.py | 3 ++- rtl/axis_mux_4.v | 3 ++- rtl/axis_mux_64.py | 3 ++- rtl/axis_mux_64_4.v | 3 ++- tb/test_axis_demux_4.py | 5 +++++ tb/test_axis_demux_4.v | 3 +++ tb/test_axis_demux_64_4.py | 5 +++++ tb/test_axis_demux_64_4.v | 3 +++ tb/test_axis_mux_4.py | 5 +++++ tb/test_axis_mux_4.v | 3 +++ tb/test_axis_mux_64_4.py | 5 +++++ tb/test_axis_mux_64_4.v | 3 +++ 20 files changed, 60 insertions(+), 8 deletions(-) diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index 9b40e7fca..f6c689541 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -132,6 +132,7 @@ module {{name}} # wire [{{n-1}}:0] request; wire [{{n-1}}:0] acknowledge; wire [{{n-1}}:0] grant; +wire grant_valid; wire [{{w-1}}:0] grant_encoded; {% for p in ports %} assign acknowledge[{{p}}] = input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast; @@ -157,6 +158,7 @@ mux_inst ( .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), .output_axis_tuser(output_axis_tuser), + .enable(grant_valid), .select(grant_encoded) ); @@ -172,6 +174,7 @@ arb_inst ( .request(request), .acknowledge(acknowledge), .grant(grant), + .grant_valid(grant_valid), .grant_encoded(grant_encoded) ); diff --git a/rtl/axis_arb_mux_4.v b/rtl/axis_arb_mux_4.v index ac24f9193..ce700a0c7 100644 --- a/rtl/axis_arb_mux_4.v +++ b/rtl/axis_arb_mux_4.v @@ -79,6 +79,7 @@ module axis_arb_mux_4 # wire [3:0] request; wire [3:0] acknowledge; wire [3:0] grant; +wire grant_valid; wire [1:0] grant_encoded; assign acknowledge[0] = input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; @@ -122,6 +123,7 @@ mux_inst ( .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), .output_axis_tuser(output_axis_tuser), + .enable(grant_valid), .select(grant_encoded) ); @@ -137,6 +139,7 @@ arb_inst ( .request(request), .acknowledge(acknowledge), .grant(grant), + .grant_valid(grant_valid), .grant_encoded(grant_encoded) ); diff --git a/rtl/axis_arb_mux_64.py b/rtl/axis_arb_mux_64.py index 75571c11e..f2f7ee514 100755 --- a/rtl/axis_arb_mux_64.py +++ b/rtl/axis_arb_mux_64.py @@ -135,6 +135,7 @@ module {{name}} # wire [{{n-1}}:0] request; wire [{{n-1}}:0] acknowledge; wire [{{n-1}}:0] grant; +wire grant_valid; wire [{{w-1}}:0] grant_encoded; {% for p in ports %} assign acknowledge[{{p}}] = input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast; @@ -162,6 +163,7 @@ mux_inst ( .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), .output_axis_tuser(output_axis_tuser), + .enable(grant_valid), .select(grant_encoded) ); @@ -177,6 +179,7 @@ arb_inst ( .request(request), .acknowledge(acknowledge), .grant(grant), + .grant_valid(grant_valid), .grant_encoded(grant_encoded) ); diff --git a/rtl/axis_arb_mux_64_4.v b/rtl/axis_arb_mux_64_4.v index d44ecc5ca..42c566f6b 100644 --- a/rtl/axis_arb_mux_64_4.v +++ b/rtl/axis_arb_mux_64_4.v @@ -85,6 +85,7 @@ module axis_arb_mux_64_4 # wire [3:0] request; wire [3:0] acknowledge; wire [3:0] grant; +wire grant_valid; wire [1:0] grant_encoded; assign acknowledge[0] = input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; @@ -133,6 +134,7 @@ mux_inst ( .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), .output_axis_tuser(output_axis_tuser), + .enable(grant_valid), .select(grant_encoded) ); @@ -148,6 +150,7 @@ arb_inst ( .request(request), .acknowledge(acknowledge), .grant(grant), + .grant_valid(grant_valid), .grant_encoded(grant_encoded) ); diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index 601e87d29..d7ce6ceaa 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -129,6 +129,7 @@ module {{name}} # /* * Control */ + input wire enable, input wire [{{w-1}}:0] select ); @@ -172,7 +173,7 @@ always @* begin // end of frame detection frame_next = ~input_axis_tlast; end - end else if (input_axis_tvalid & ~current_output_tvalid) begin + end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v index 1209f07c0..e796b8347 100644 --- a/rtl/axis_demux_4.v +++ b/rtl/axis_demux_4.v @@ -76,6 +76,7 @@ module axis_demux_4 # /* * Control */ + input wire enable, input wire [1:0] select ); @@ -129,7 +130,7 @@ always @* begin // end of frame detection frame_next = ~input_axis_tlast; end - end else if (input_axis_tvalid & ~current_output_tvalid) begin + end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index 7f485bb14..cf927c1fb 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -132,6 +132,7 @@ module {{name}} # /* * Control */ + input wire enable, input wire [{{w-1}}:0] select ); @@ -176,7 +177,7 @@ always @* begin // end of frame detection frame_next = ~input_axis_tlast; end - end else if (input_axis_tvalid & ~current_output_tvalid) begin + end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/axis_demux_64_4.v b/rtl/axis_demux_64_4.v index 47940c670..d64f0b13a 100644 --- a/rtl/axis_demux_64_4.v +++ b/rtl/axis_demux_64_4.v @@ -82,6 +82,7 @@ module axis_demux_64_4 # /* * Control */ + input wire enable, input wire [1:0] select ); @@ -136,7 +137,7 @@ always @* begin // end of frame detection frame_next = ~input_axis_tlast; end - end else if (input_axis_tvalid & ~current_output_tvalid) begin + end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 37c2f8a3a..122c96026 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -129,6 +129,7 @@ module {{name}} # /* * Control */ + input wire enable, input wire [{{w-1}}:0] select ); @@ -191,7 +192,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (selected_input_tvalid) begin + end else if (enable & selected_input_tvalid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v index 12ad752a6..63f58ae9f 100644 --- a/rtl/axis_mux_4.v +++ b/rtl/axis_mux_4.v @@ -76,6 +76,7 @@ module axis_mux_4 # /* * Control */ + input wire enable, input wire [1:0] select ); @@ -164,7 +165,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (selected_input_tvalid) begin + end else if (enable & selected_input_tvalid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index 9b9165612..29b3f7aa9 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -132,6 +132,7 @@ module {{name}} # /* * Control */ + input wire enable, input wire [{{w-1}}:0] select ); @@ -197,7 +198,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (selected_input_tvalid) begin + end else if (enable & selected_input_tvalid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/axis_mux_64_4.v b/rtl/axis_mux_64_4.v index bbf945e09..06d0d6749 100644 --- a/rtl/axis_mux_64_4.v +++ b/rtl/axis_mux_64_4.v @@ -82,6 +82,7 @@ module axis_mux_64_4 # /* * Control */ + input wire enable, input wire [1:0] select ); @@ -176,7 +177,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (selected_input_tvalid) begin + end else if (enable & selected_input_tvalid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py index d6a56083c..c39a347c6 100755 --- a/tb/test_axis_demux_4.py +++ b/tb/test_axis_demux_4.py @@ -71,6 +71,7 @@ def dut_axis_demux_4(clk, output_3_axis_tlast, output_3_axis_tuser, + enable, select): if os.system(build_cmd): @@ -107,6 +108,7 @@ def dut_axis_demux_4(clk, output_3_axis_tlast=output_3_axis_tlast, output_3_axis_tuser=output_3_axis_tuser, + enable=enable, select=select) def bench(): @@ -126,6 +128,7 @@ def bench(): output_2_axis_tready = Signal(bool(0)) output_3_axis_tready = Signal(bool(0)) + enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs @@ -247,6 +250,7 @@ def bench(): output_3_axis_tlast, output_3_axis_tuser, + enable, select) @always(delay(4)) @@ -265,6 +269,7 @@ def bench(): yield clk.posedge yield clk.posedge + enable.next = True yield clk.posedge print("test 1: select port 0") diff --git a/tb/test_axis_demux_4.v b/tb/test_axis_demux_4.v index 056b23ff4..5f58f8627 100644 --- a/tb/test_axis_demux_4.v +++ b/tb/test_axis_demux_4.v @@ -43,6 +43,7 @@ reg output_1_axis_tready = 0; reg output_2_axis_tready = 0; reg output_3_axis_tready = 0; +reg enable = 0; reg [1:0] select = 0; // Outputs @@ -78,6 +79,7 @@ initial begin output_1_axis_tready, output_2_axis_tready, output_3_axis_tready, + enable, select); $to_myhdl(input_axis_tready, output_0_axis_tdata, @@ -136,6 +138,7 @@ UUT ( .output_3_axis_tlast(output_3_axis_tlast), .output_3_axis_tuser(output_3_axis_tuser), // Control + .enable(enable), .select(select) ); diff --git a/tb/test_axis_demux_64_4.py b/tb/test_axis_demux_64_4.py index 05e3fb06d..08aeb3a74 100755 --- a/tb/test_axis_demux_64_4.py +++ b/tb/test_axis_demux_64_4.py @@ -76,6 +76,7 @@ def dut_axis_demux_64_4(clk, output_3_axis_tlast, output_3_axis_tuser, + enable, select): if os.system(build_cmd): @@ -117,6 +118,7 @@ def dut_axis_demux_64_4(clk, output_3_axis_tlast=output_3_axis_tlast, output_3_axis_tuser=output_3_axis_tuser, + enable=enable, select=select) def bench(): @@ -137,6 +139,7 @@ def bench(): output_2_axis_tready = Signal(bool(0)) output_3_axis_tready = Signal(bool(0)) + enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs @@ -272,6 +275,7 @@ def bench(): output_3_axis_tlast, output_3_axis_tuser, + enable, select) @always(delay(4)) @@ -290,6 +294,7 @@ def bench(): yield clk.posedge yield clk.posedge + enable.next = True yield clk.posedge print("test 1: select port 0") diff --git a/tb/test_axis_demux_64_4.v b/tb/test_axis_demux_64_4.v index 70528466f..6233ac295 100644 --- a/tb/test_axis_demux_64_4.v +++ b/tb/test_axis_demux_64_4.v @@ -44,6 +44,7 @@ reg output_1_axis_tready = 0; reg output_2_axis_tready = 0; reg output_3_axis_tready = 0; +reg enable = 0; reg [1:0] select = 0; // Outputs @@ -84,6 +85,7 @@ initial begin output_1_axis_tready, output_2_axis_tready, output_3_axis_tready, + enable, select); $to_myhdl(input_axis_tready, output_0_axis_tdata, @@ -151,6 +153,7 @@ UUT ( .output_3_axis_tlast(output_3_axis_tlast), .output_3_axis_tuser(output_3_axis_tuser), // Control + .enable(enable), .select(select) ); diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py index 08fd69232..97cccfdf4 100755 --- a/tb/test_axis_mux_4.py +++ b/tb/test_axis_mux_4.py @@ -71,6 +71,7 @@ def dut_axis_mux_4(clk, output_axis_tlast, output_axis_tuser, + enable, select): if os.system(build_cmd): @@ -107,6 +108,7 @@ def dut_axis_mux_4(clk, output_axis_tlast=output_axis_tlast, output_axis_tuser=output_axis_tuser, + enable=enable, select=select) def bench(): @@ -135,6 +137,7 @@ def bench(): output_axis_tready = Signal(bool(0)) + enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs @@ -244,6 +247,7 @@ def bench(): output_axis_tlast, output_axis_tuser, + enable, select) @always(delay(4)) @@ -262,6 +266,7 @@ def bench(): yield clk.posedge yield clk.posedge + enable.next = True yield clk.posedge print("test 1: select port 0") diff --git a/tb/test_axis_mux_4.v b/tb/test_axis_mux_4.v index d31c8429d..6fcbc7e6b 100644 --- a/tb/test_axis_mux_4.v +++ b/tb/test_axis_mux_4.v @@ -52,6 +52,7 @@ reg input_3_axis_tuser = 0; reg output_axis_tready = 0; +reg enable = 0; reg [1:0] select = 0; // Outputs @@ -87,6 +88,7 @@ initial begin input_3_axis_tlast, input_3_axis_tuser, output_axis_tready, + enable, select); $to_myhdl(input_0_axis_tready, input_1_axis_tready, @@ -136,6 +138,7 @@ UUT ( .output_axis_tlast(output_axis_tlast), .output_axis_tuser(output_axis_tuser), // Control + .enable(enable), .select(select) ); diff --git a/tb/test_axis_mux_64_4.py b/tb/test_axis_mux_64_4.py index b866c680b..f8349d26c 100755 --- a/tb/test_axis_mux_64_4.py +++ b/tb/test_axis_mux_64_4.py @@ -76,6 +76,7 @@ def dut_axis_mux_64_4(clk, output_axis_tlast, output_axis_tuser, + enable, select): if os.system(build_cmd): @@ -117,6 +118,7 @@ def dut_axis_mux_64_4(clk, output_axis_tlast=output_axis_tlast, output_axis_tuser=output_axis_tuser, + enable=enable, select=select) def bench(): @@ -149,6 +151,7 @@ def bench(): output_axis_tready = Signal(bool(0)) + enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs @@ -269,6 +272,7 @@ def bench(): output_axis_tlast, output_axis_tuser, + enable, select) @always(delay(4)) @@ -287,6 +291,7 @@ def bench(): yield clk.posedge yield clk.posedge + enable.next = True yield clk.posedge print("test 1: select port 0") diff --git a/tb/test_axis_mux_64_4.v b/tb/test_axis_mux_64_4.v index 31c4f0b19..3209d64ac 100644 --- a/tb/test_axis_mux_64_4.v +++ b/tb/test_axis_mux_64_4.v @@ -56,6 +56,7 @@ reg input_3_axis_tuser = 0; reg output_axis_tready = 0; +reg enable = 0; reg [1:0] select = 0; // Outputs @@ -96,6 +97,7 @@ initial begin input_3_axis_tlast, input_3_axis_tuser, output_axis_tready, + enable, select); $to_myhdl(input_0_axis_tready, input_1_axis_tready, @@ -151,6 +153,7 @@ UUT ( .output_axis_tlast(output_axis_tlast), .output_axis_tuser(output_axis_tuser), // Control + .enable(enable), .select(select) ); From d193ca5905c1293d3b8be3a1014dacc634ffef75 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Nov 2014 01:58:17 -0800 Subject: [PATCH 101/617] Add LSB_PRIORITY parameter --- rtl/arbiter.v | 22 +++++++++++++++++----- rtl/priority_encoder.v | 22 +++++++++++++++++----- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/rtl/arbiter.v b/rtl/arbiter.v index 219b4661c..d6e06303d 100644 --- a/rtl/arbiter.v +++ b/rtl/arbiter.v @@ -35,7 +35,9 @@ module arbiter # // arbitration type: "PRIORITY" or "ROUND_ROBIN" parameter TYPE = "PRIORITY", // block type: "NONE", "REQUEST", "ACKNOWLEDGE" - parameter BLOCK = "NONE" + parameter BLOCK = "NONE", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "LOW" ) ( input wire clk, @@ -62,7 +64,8 @@ wire [$clog2(PORTS)-1:0] request_index; wire [PORTS-1:0] request_mask; priority_encoder #( - .WIDTH(PORTS) + .WIDTH(PORTS), + .LSB_PRIORITY(LSB_PRIORITY) ) priority_encoder_inst ( .input_unencoded(request), @@ -78,7 +81,8 @@ wire [$clog2(PORTS)-1:0] masked_request_index; wire [PORTS-1:0] masked_request_mask; priority_encoder #( - .WIDTH(PORTS) + .WIDTH(PORTS), + .LSB_PRIORITY(LSB_PRIORITY) ) priority_encoder_masked ( .input_unencoded(request & mask_reg), @@ -113,12 +117,20 @@ always @* begin grant_valid_next = 1; grant_next = masked_request_mask; grant_encoded_next = masked_request_index; - mask_next = {PORTS{1'b1}} >> (PORTS - masked_request_index); + if (LSB_PRIORITY == "LOW") begin + mask_next = {PORTS{1'b1}} >> (PORTS - masked_request_index); + end else begin + mask_next = {PORTS{1'b1}} << (masked_request_index + 1); + end end else begin grant_valid_next = 1; grant_next = request_mask; grant_encoded_next = request_index; - mask_next = {PORTS{1'b1}} >> (PORTS - request_index); + if (LSB_PRIORITY == "LOW") begin + mask_next = {PORTS{1'b1}} >> (PORTS - request_index); + end else begin + mask_next = {PORTS{1'b1}} << (request_index + 1); + end end end end diff --git a/rtl/priority_encoder.v b/rtl/priority_encoder.v index 03af53fe9..cb380c760 100644 --- a/rtl/priority_encoder.v +++ b/rtl/priority_encoder.v @@ -31,7 +31,9 @@ THE SOFTWARE. */ module priority_encoder # ( - parameter WIDTH = 4 + parameter WIDTH = 4, + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "LOW" ) ( input wire [WIDTH-1:0] input_unencoded, @@ -48,14 +50,19 @@ generate if (WIDTH == 2) begin // two inputs - just an OR gate assign output_valid = |input_unencoded; - assign output_encoded = input_unencoded[1]; + if (LSB_PRIORITY == "LOW") begin + assign output_encoded = input_unencoded[1]; + end else begin + assign output_encoded = ~input_unencoded[0]; + end end else begin // more than two inputs - split into two parts and recurse // also pad input to correct power-of-two width wire [$clog2(W2)-1:0] out1, out2; wire valid1, valid2; priority_encoder #( - .WIDTH(W2) + .WIDTH(W2), + .LSB_PRIORITY(LSB_PRIORITY) ) priority_encoder_inst1 ( .input_unencoded(input_unencoded[W2-1:0]), @@ -63,7 +70,8 @@ generate .output_encoded(out1) ); priority_encoder #( - .WIDTH(W2) + .WIDTH(W2), + .LSB_PRIORITY(LSB_PRIORITY) ) priority_encoder_inst2 ( .input_unencoded({{W1-WIDTH{1'b0}}, input_unencoded[WIDTH-1:W2]}), @@ -72,7 +80,11 @@ generate ); // multiplexer to select part assign output_valid = valid1 | valid2; - assign output_encoded = valid2 ? {1'b1, out2} : {1'b0, out1}; + if (LSB_PRIORITY == "LOW") begin + assign output_encoded = valid2 ? {1'b1, out2} : {1'b0, out1}; + end else begin + assign output_encoded = valid1 ? {1'b0, out1} : {1'b1, out2}; + end end endgenerate From 0c3af7d5bb20d1e0802a1309744a9917fd7aa92a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Nov 2014 02:00:27 -0800 Subject: [PATCH 102/617] Reverse priority in arbitrated mux --- rtl/axis_arb_mux.py | 7 +++-- rtl/axis_arb_mux_4.v | 7 +++-- rtl/axis_arb_mux_64.py | 7 +++-- rtl/axis_arb_mux_64_4.v | 7 +++-- tb/test_axis_arb_mux_4.py | 58 ++++++++++++++++++------------------ tb/test_axis_arb_mux_64_4.py | 58 ++++++++++++++++++------------------ 6 files changed, 78 insertions(+), 66 deletions(-) diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index f6c689541..9d37839d6 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -103,7 +103,9 @@ module {{name}} # ( parameter DATA_WIDTH = 8, // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" ) ( input wire clk, @@ -166,7 +168,8 @@ mux_inst ( arbiter #( .PORTS({{n}}), .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE") + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) ) arb_inst ( .clk(clk), diff --git a/rtl/axis_arb_mux_4.v b/rtl/axis_arb_mux_4.v index ce700a0c7..56d2afe23 100644 --- a/rtl/axis_arb_mux_4.v +++ b/rtl/axis_arb_mux_4.v @@ -33,7 +33,9 @@ module axis_arb_mux_4 # ( parameter DATA_WIDTH = 8, // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" ) ( input wire clk, @@ -131,7 +133,8 @@ mux_inst ( arbiter #( .PORTS(4), .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE") + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) ) arb_inst ( .clk(clk), diff --git a/rtl/axis_arb_mux_64.py b/rtl/axis_arb_mux_64.py index f2f7ee514..873c2e2a9 100755 --- a/rtl/axis_arb_mux_64.py +++ b/rtl/axis_arb_mux_64.py @@ -104,7 +104,9 @@ module {{name}} # parameter DATA_WIDTH = 64, parameter KEEP_WIDTH = (DATA_WIDTH/8), // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" ) ( input wire clk, @@ -171,7 +173,8 @@ mux_inst ( arbiter #( .PORTS({{n}}), .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE") + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) ) arb_inst ( .clk(clk), diff --git a/rtl/axis_arb_mux_64_4.v b/rtl/axis_arb_mux_64_4.v index 42c566f6b..b4947e2ef 100644 --- a/rtl/axis_arb_mux_64_4.v +++ b/rtl/axis_arb_mux_64_4.v @@ -34,7 +34,9 @@ module axis_arb_mux_64_4 # parameter DATA_WIDTH = 64, parameter KEEP_WIDTH = (DATA_WIDTH/8), // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" ) ( input wire clk, @@ -142,7 +144,8 @@ mux_inst ( arbiter #( .PORTS(4), .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE") + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) ) arb_inst ( .clk(clk), diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index 8cd01f7fe..e406ef368 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -366,13 +366,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -412,13 +412,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -452,13 +452,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -476,39 +476,21 @@ def bench(): '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') source_1_queue.put(test_frame1) source_2_queue.put(test_frame2) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) yield clk.posedge yield delay(800) yield clk.posedge - source_2_queue.put(test_frame2) + source_1_queue.put(test_frame1) while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: 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_frame2 - - 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_frame1 - rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() @@ -521,12 +503,30 @@ def bench(): assert rx_frame == test_frame2 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + 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) raise StopSimulation diff --git a/tb/test_axis_arb_mux_64_4.py b/tb/test_axis_arb_mux_64_4.py index 15a0e4504..4698f5f2d 100755 --- a/tb/test_axis_arb_mux_64_4.py +++ b/tb/test_axis_arb_mux_64_4.py @@ -391,13 +391,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -437,13 +437,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -477,13 +477,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -501,39 +501,21 @@ def bench(): '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') source_1_queue.put(test_frame1) source_2_queue.put(test_frame2) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) yield clk.posedge yield delay(150) yield clk.posedge - source_2_queue.put(test_frame2) + source_1_queue.put(test_frame1) while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: 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_frame2 - - 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_frame1 - rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() @@ -546,12 +528,30 @@ def bench(): assert rx_frame == test_frame2 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + 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) raise StopSimulation From f1d075d9748571d79d6fa99567b81829f8482624 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Nov 2014 02:13:43 -0800 Subject: [PATCH 103/617] Add enable signal --- rtl/eth_arb_mux.py | 3 +++ rtl/eth_arb_mux_4.v | 3 +++ rtl/eth_arb_mux_64.py | 3 +++ rtl/eth_arb_mux_64_4.v | 3 +++ rtl/eth_mux.py | 3 ++- rtl/eth_mux_4.v | 3 ++- rtl/eth_mux_64.py | 3 ++- rtl/eth_mux_64_4.v | 3 ++- tb/test_eth_mux_4.py | 5 +++++ tb/test_eth_mux_4.v | 3 +++ tb/test_eth_mux_64_4.py | 5 +++++ tb/test_eth_mux_64_4.v | 3 +++ 12 files changed, 36 insertions(+), 4 deletions(-) diff --git a/rtl/eth_arb_mux.py b/rtl/eth_arb_mux.py index e3ac794ec..918787607 100755 --- a/rtl/eth_arb_mux.py +++ b/rtl/eth_arb_mux.py @@ -141,6 +141,7 @@ module {{name}} # wire [{{n-1}}:0] request; wire [{{n-1}}:0] acknowledge; wire [{{n-1}}:0] grant; +wire grant_valid; wire [{{w-1}}:0] grant_encoded; {% for p in ports %} assign acknowledge[{{p}}] = input_{{p}}_eth_payload_tvalid & input_{{p}}_eth_payload_tready & input_{{p}}_eth_payload_tlast; @@ -174,6 +175,7 @@ mux_inst ( .output_eth_payload_tready(output_eth_payload_tready), .output_eth_payload_tlast(output_eth_payload_tlast), .output_eth_payload_tuser(output_eth_payload_tuser), + .enable(grant_valid), .select(grant_encoded) ); @@ -189,6 +191,7 @@ arb_inst ( .request(request), .acknowledge(acknowledge), .grant(grant), + .grant_valid(grant_valid), .grant_encoded(grant_encoded) ); diff --git a/rtl/eth_arb_mux_4.v b/rtl/eth_arb_mux_4.v index 93c877d5e..166f05f58 100644 --- a/rtl/eth_arb_mux_4.v +++ b/rtl/eth_arb_mux_4.v @@ -103,6 +103,7 @@ module eth_arb_mux_4 # wire [3:0] request; wire [3:0] acknowledge; wire [3:0] grant; +wire grant_valid; wire [1:0] grant_encoded; assign acknowledge[0] = input_0_eth_payload_tvalid & input_0_eth_payload_tready & input_0_eth_payload_tlast; @@ -169,6 +170,7 @@ mux_inst ( .output_eth_payload_tready(output_eth_payload_tready), .output_eth_payload_tlast(output_eth_payload_tlast), .output_eth_payload_tuser(output_eth_payload_tuser), + .enable(grant_valid), .select(grant_encoded) ); @@ -184,6 +186,7 @@ arb_inst ( .request(request), .acknowledge(acknowledge), .grant(grant), + .grant_valid(grant_valid), .grant_encoded(grant_encoded) ); diff --git a/rtl/eth_arb_mux_64.py b/rtl/eth_arb_mux_64.py index 49e2ed822..cbc839fab 100755 --- a/rtl/eth_arb_mux_64.py +++ b/rtl/eth_arb_mux_64.py @@ -143,6 +143,7 @@ module {{name}} # wire [{{n-1}}:0] request; wire [{{n-1}}:0] acknowledge; wire [{{n-1}}:0] grant; +wire grant_valid; wire [{{w-1}}:0] grant_encoded; {% for p in ports %} assign acknowledge[{{p}}] = input_{{p}}_eth_payload_tvalid & input_{{p}}_eth_payload_tready & input_{{p}}_eth_payload_tlast; @@ -178,6 +179,7 @@ mux_inst ( .output_eth_payload_tready(output_eth_payload_tready), .output_eth_payload_tlast(output_eth_payload_tlast), .output_eth_payload_tuser(output_eth_payload_tuser), + .enable(grant_valid), .select(grant_encoded) ); @@ -193,6 +195,7 @@ arb_inst ( .request(request), .acknowledge(acknowledge), .grant(grant), + .grant_valid(grant_valid), .grant_encoded(grant_encoded) ); diff --git a/rtl/eth_arb_mux_64_4.v b/rtl/eth_arb_mux_64_4.v index 64f48aed0..4c2aa57fe 100644 --- a/rtl/eth_arb_mux_64_4.v +++ b/rtl/eth_arb_mux_64_4.v @@ -108,6 +108,7 @@ module eth_arb_mux_64_4 # wire [3:0] request; wire [3:0] acknowledge; wire [3:0] grant; +wire grant_valid; wire [1:0] grant_encoded; assign acknowledge[0] = input_0_eth_payload_tvalid & input_0_eth_payload_tready & input_0_eth_payload_tlast; @@ -179,6 +180,7 @@ mux_inst ( .output_eth_payload_tready(output_eth_payload_tready), .output_eth_payload_tlast(output_eth_payload_tlast), .output_eth_payload_tuser(output_eth_payload_tuser), + .enable(grant_valid), .select(grant_encoded) ); @@ -194,6 +196,7 @@ arb_inst ( .request(request), .acknowledge(acknowledge), .grant(grant), + .grant_valid(grant_valid), .grant_encoded(grant_encoded) ); diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index 6d030f1a1..6bd2421f7 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -136,6 +136,7 @@ module {{name}} /* * Control */ + input wire enable, input wire [{{w-1}}:0] select ); @@ -230,7 +231,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (selected_input_eth_hdr_valid) begin + end else if (enable & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v index 77e7b710c..343411381 100644 --- a/rtl/eth_mux_4.v +++ b/rtl/eth_mux_4.v @@ -98,6 +98,7 @@ module eth_mux_4 /* * Control */ + input wire enable, input wire [1:0] select ); @@ -239,7 +240,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (selected_input_eth_hdr_valid) begin + end else if (enable & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index d5a3a8f66..6630ad9df 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -138,6 +138,7 @@ module {{name}} /* * Control */ + input wire enable, input wire [{{w-1}}:0] select ); @@ -235,7 +236,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (selected_input_eth_hdr_valid) begin + end else if (enable & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v index 7f849c350..f8c904e28 100644 --- a/rtl/eth_mux_64_4.v +++ b/rtl/eth_mux_64_4.v @@ -103,6 +103,7 @@ module eth_mux_64_4 /* * Control */ + input wire enable, input wire [1:0] select ); @@ -250,7 +251,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (selected_input_eth_hdr_valid) begin + end else if (enable & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/tb/test_eth_mux_4.py b/tb/test_eth_mux_4.py index 9e468ace6..add42f539 100755 --- a/tb/test_eth_mux_4.py +++ b/tb/test_eth_mux_4.py @@ -96,6 +96,7 @@ def dut_eth_mux_4(clk, output_eth_payload_tlast, output_eth_payload_tuser, + enable, select): if os.system(build_cmd): @@ -157,6 +158,7 @@ def dut_eth_mux_4(clk, output_eth_payload_tlast=output_eth_payload_tlast, output_eth_payload_tuser=output_eth_payload_tuser, + enable=enable, select=select) def bench(): @@ -202,6 +204,7 @@ def bench(): output_eth_payload_tready = Signal(bool(0)) output_eth_hdr_ready = Signal(bool(0)) + enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs @@ -372,6 +375,7 @@ def bench(): output_eth_payload_tlast, output_eth_payload_tuser, + enable, select) @always(delay(4)) @@ -390,6 +394,7 @@ def bench(): yield clk.posedge yield clk.posedge + enable.next = True yield clk.posedge print("test 1: select port 0") diff --git a/tb/test_eth_mux_4.v b/tb/test_eth_mux_4.v index 7db7bdc39..1826aa743 100644 --- a/tb/test_eth_mux_4.v +++ b/tb/test_eth_mux_4.v @@ -69,6 +69,7 @@ reg input_3_eth_payload_tuser = 0; reg output_eth_hdr_ready = 0; reg output_eth_payload_tready = 0; +reg enable = 0; reg [1:0] select = 0; // Outputs @@ -129,6 +130,7 @@ initial begin input_3_eth_payload_tuser, output_eth_hdr_ready, output_eth_payload_tready, + enable, select); $to_myhdl(input_0_eth_hdr_ready, input_0_eth_payload_tready, @@ -209,6 +211,7 @@ UUT ( .output_eth_payload_tlast(output_eth_payload_tlast), .output_eth_payload_tuser(output_eth_payload_tuser), // Control + .enable(enable), .select(select) ); diff --git a/tb/test_eth_mux_64_4.py b/tb/test_eth_mux_64_4.py index e044429b2..e9a89bb5b 100755 --- a/tb/test_eth_mux_64_4.py +++ b/tb/test_eth_mux_64_4.py @@ -101,6 +101,7 @@ def dut_eth_mux_64_4(clk, output_eth_payload_tlast, output_eth_payload_tuser, + enable, select): if os.system(build_cmd): @@ -167,6 +168,7 @@ def dut_eth_mux_64_4(clk, output_eth_payload_tlast=output_eth_payload_tlast, output_eth_payload_tuser=output_eth_payload_tuser, + enable=enable, select=select) def bench(): @@ -216,6 +218,7 @@ def bench(): output_eth_payload_tready = Signal(bool(0)) output_eth_hdr_ready = Signal(bool(0)) + enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs @@ -397,6 +400,7 @@ def bench(): output_eth_payload_tlast, output_eth_payload_tuser, + enable, select) @always(delay(4)) @@ -415,6 +419,7 @@ def bench(): yield clk.posedge yield clk.posedge + enable.next = True yield clk.posedge print("test 1: select port 0") diff --git a/tb/test_eth_mux_64_4.v b/tb/test_eth_mux_64_4.v index e979f0a61..58d4f2118 100644 --- a/tb/test_eth_mux_64_4.v +++ b/tb/test_eth_mux_64_4.v @@ -73,6 +73,7 @@ reg input_3_eth_payload_tuser = 0; reg output_eth_hdr_ready = 0; reg output_eth_payload_tready = 0; +reg enable = 0; reg [1:0] select = 0; // Outputs @@ -138,6 +139,7 @@ initial begin input_3_eth_payload_tuser, output_eth_hdr_ready, output_eth_payload_tready, + enable, select); $to_myhdl(input_0_eth_hdr_ready, input_0_eth_payload_tready, @@ -224,6 +226,7 @@ UUT ( .output_eth_payload_tlast(output_eth_payload_tlast), .output_eth_payload_tuser(output_eth_payload_tuser), // Control + .enable(enable), .select(select) ); From 4d1180d74c902897ba2666b0308c2472fc21f40d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Nov 2014 02:20:44 -0800 Subject: [PATCH 104/617] Reverse priority in arbitrated mux --- rtl/eth_arb_mux.py | 7 +++-- rtl/eth_arb_mux_4.v | 7 +++-- rtl/eth_arb_mux_64.py | 7 +++-- rtl/eth_arb_mux_64_4.v | 7 +++-- tb/test_eth_arb_mux_4.py | 58 ++++++++++++++++++------------------- tb/test_eth_arb_mux_64_4.py | 58 ++++++++++++++++++------------------- 6 files changed, 78 insertions(+), 66 deletions(-) diff --git a/rtl/eth_arb_mux.py b/rtl/eth_arb_mux.py index 918787607..998ff328b 100755 --- a/rtl/eth_arb_mux.py +++ b/rtl/eth_arb_mux.py @@ -102,7 +102,9 @@ THE SOFTWARE. module {{name}} # ( // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" ) ( input wire clk, @@ -183,7 +185,8 @@ mux_inst ( arbiter #( .PORTS({{n}}), .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE") + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) ) arb_inst ( .clk(clk), diff --git a/rtl/eth_arb_mux_4.v b/rtl/eth_arb_mux_4.v index 166f05f58..71e75e091 100644 --- a/rtl/eth_arb_mux_4.v +++ b/rtl/eth_arb_mux_4.v @@ -32,7 +32,9 @@ THE SOFTWARE. module eth_arb_mux_4 # ( // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" ) ( input wire clk, @@ -178,7 +180,8 @@ mux_inst ( arbiter #( .PORTS(4), .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE") + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) ) arb_inst ( .clk(clk), diff --git a/rtl/eth_arb_mux_64.py b/rtl/eth_arb_mux_64.py index cbc839fab..9c7b642f5 100755 --- a/rtl/eth_arb_mux_64.py +++ b/rtl/eth_arb_mux_64.py @@ -102,7 +102,9 @@ THE SOFTWARE. module {{name}} # ( // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" ) ( input wire clk, @@ -187,7 +189,8 @@ mux_inst ( arbiter #( .PORTS({{n}}), .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE") + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) ) arb_inst ( .clk(clk), diff --git a/rtl/eth_arb_mux_64_4.v b/rtl/eth_arb_mux_64_4.v index 4c2aa57fe..84a7ab1ff 100644 --- a/rtl/eth_arb_mux_64_4.v +++ b/rtl/eth_arb_mux_64_4.v @@ -32,7 +32,9 @@ THE SOFTWARE. module eth_arb_mux_64_4 # ( // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" ) ( input wire clk, @@ -188,7 +190,8 @@ mux_inst ( arbiter #( .PORTS(4), .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE") + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) ) arb_inst ( .clk(clk), diff --git a/tb/test_eth_arb_mux_4.py b/tb/test_eth_arb_mux_4.py index 84347fac0..d3c086ef0 100755 --- a/tb/test_eth_arb_mux_4.py +++ b/tb/test_eth_arb_mux_4.py @@ -508,13 +508,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -558,13 +558,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -603,13 +603,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -630,39 +630,21 @@ def bench(): source_1_queue.put(test_frame1) source_2_queue.put(test_frame2) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) yield clk.posedge yield delay(800) yield clk.posedge - source_2_queue.put(test_frame2) + source_1_queue.put(test_frame1) while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: 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_frame2 - - 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_frame1 - rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() @@ -675,12 +657,30 @@ def bench(): assert rx_frame == test_frame2 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + 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) raise StopSimulation diff --git a/tb/test_eth_arb_mux_64_4.py b/tb/test_eth_arb_mux_64_4.py index edf0ee619..699276ce1 100755 --- a/tb/test_eth_arb_mux_64_4.py +++ b/tb/test_eth_arb_mux_64_4.py @@ -533,13 +533,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -583,13 +583,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -628,13 +628,13 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield delay(100) @@ -655,39 +655,21 @@ def bench(): source_1_queue.put(test_frame1) source_2_queue.put(test_frame2) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) - source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) yield clk.posedge yield delay(150) yield clk.posedge - source_2_queue.put(test_frame2) + source_1_queue.put(test_frame1) while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: 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_frame2 - - 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_frame1 - rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() @@ -700,12 +682,30 @@ def bench(): assert rx_frame == test_frame2 + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + 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) raise StopSimulation From 59952bd8cf10d55f39c829204e309de44a867933 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 17 Nov 2014 18:10:35 -0800 Subject: [PATCH 105/617] Do not accept new frame until header is read --- rtl/eth_mux.py | 2 +- rtl/eth_mux_4.v | 2 +- rtl/eth_mux_64.py | 2 +- rtl/eth_mux_64_4.v | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index 6bd2421f7..d0d5cd22c 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -231,7 +231,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (enable & selected_input_eth_hdr_valid) begin + end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v index 343411381..b7071462b 100644 --- a/rtl/eth_mux_4.v +++ b/rtl/eth_mux_4.v @@ -240,7 +240,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (enable & selected_input_eth_hdr_valid) begin + end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index 6630ad9df..4a3250d6a 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -236,7 +236,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (enable & selected_input_eth_hdr_valid) begin + end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v index f8c904e28..cd80138e3 100644 --- a/rtl/eth_mux_64_4.v +++ b/rtl/eth_mux_64_4.v @@ -251,7 +251,7 @@ always @* begin // end of frame detection frame_next = ~current_input_tlast; end - end else if (enable & selected_input_eth_hdr_valid) begin + end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1; select_next = select; From 885d847514f4a8b8138d934e41ed4450628a433a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 17 Nov 2014 19:27:45 -0800 Subject: [PATCH 106/617] Rework header ready set --- rtl/eth_mux.py | 12 ++++++++---- rtl/eth_mux_4.v | 28 ++++++++++++---------------- rtl/eth_mux_64.py | 12 ++++++++---- rtl/eth_mux_64_4.v | 28 ++++++++++++---------------- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index d0d5cd22c..088e821d5 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -235,6 +235,13 @@ always @* begin // start of frame, grab select value frame_next = 1; select_next = select; + + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_eth_hdr_ready_next = 1; +{%- endfor %} + endcase + output_eth_hdr_valid_next = 1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; @@ -244,10 +251,7 @@ always @* begin // generate ready signal on selected port case (select_next) {%- for p in ports %} - {{w}}'d{{p}}: begin - input_{{p}}_eth_hdr_ready_next = input_{{p}}_eth_hdr_ready_next | (frame_next & ~frame_reg); - input_{{p}}_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - end + {{w}}'d{{p}}: input_{{p}}_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; {%- endfor %} endcase diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v index b7071462b..7d5633bf3 100644 --- a/rtl/eth_mux_4.v +++ b/rtl/eth_mux_4.v @@ -244,6 +244,14 @@ always @* begin // start of frame, grab select value frame_next = 1; select_next = select; + + case (select_next) + 2'd0: input_0_eth_hdr_ready_next = 1; + 2'd1: input_1_eth_hdr_ready_next = 1; + 2'd2: input_2_eth_hdr_ready_next = 1; + 2'd3: input_3_eth_hdr_ready_next = 1; + endcase + output_eth_hdr_valid_next = 1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; @@ -252,22 +260,10 @@ always @* begin // generate ready signal on selected port case (select_next) - 2'd0: begin - input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_next | (frame_next & ~frame_reg); - input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - end - 2'd1: begin - input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_next | (frame_next & ~frame_reg); - input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - end - 2'd2: begin - input_2_eth_hdr_ready_next = input_2_eth_hdr_ready_next | (frame_next & ~frame_reg); - input_2_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - end - 2'd3: begin - input_3_eth_hdr_ready_next = input_3_eth_hdr_ready_next | (frame_next & ~frame_reg); - input_3_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - end + 2'd0: input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + 2'd1: input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + 2'd2: input_2_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + 2'd3: input_3_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; endcase // pass through selected packet data diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index 4a3250d6a..8e7fadda4 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -240,6 +240,13 @@ always @* begin // start of frame, grab select value frame_next = 1; select_next = select; + + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_eth_hdr_ready_next = 1; +{%- endfor %} + endcase + output_eth_hdr_valid_next = 1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; @@ -249,10 +256,7 @@ always @* begin // generate ready signal on selected port case (select_next) {%- for p in ports %} - {{w}}'d{{p}}: begin - input_{{p}}_eth_hdr_ready_next = input_{{p}}_eth_hdr_ready_next | (frame_next & ~frame_reg); - input_{{p}}_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - end + {{w}}'d{{p}}: input_{{p}}_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; {%- endfor %} endcase diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v index cd80138e3..085eb5db3 100644 --- a/rtl/eth_mux_64_4.v +++ b/rtl/eth_mux_64_4.v @@ -255,6 +255,14 @@ always @* begin // start of frame, grab select value frame_next = 1; select_next = select; + + case (select_next) + 2'd0: input_0_eth_hdr_ready_next = 1; + 2'd1: input_1_eth_hdr_ready_next = 1; + 2'd2: input_2_eth_hdr_ready_next = 1; + 2'd3: input_3_eth_hdr_ready_next = 1; + endcase + output_eth_hdr_valid_next = 1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; @@ -263,22 +271,10 @@ always @* begin // generate ready signal on selected port case (select_next) - 2'd0: begin - input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_next | (frame_next & ~frame_reg); - input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - end - 2'd1: begin - input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_next | (frame_next & ~frame_reg); - input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - end - 2'd2: begin - input_2_eth_hdr_ready_next = input_2_eth_hdr_ready_next | (frame_next & ~frame_reg); - input_2_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - end - 2'd3: begin - input_3_eth_hdr_ready_next = input_3_eth_hdr_ready_next | (frame_next & ~frame_reg); - input_3_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - end + 2'd0: input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + 2'd1: input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + 2'd2: input_2_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + 2'd3: input_3_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; endcase // pass through selected packet data From 4db581ae3c45bf5fbf57117c9e76cc203fbacc23 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 17 Nov 2014 21:52:49 -0800 Subject: [PATCH 107/617] Add ethernet demux module and testbench --- rtl/eth_demux.py | 349 ++++++++++++++++++++ rtl/eth_demux_4.v | 351 ++++++++++++++++++++ rtl/eth_demux_64.py | 362 ++++++++++++++++++++ rtl/eth_demux_64_4.v | 370 +++++++++++++++++++++ tb/test_eth_demux_4.py | 646 ++++++++++++++++++++++++++++++++++++ tb/test_eth_demux_4.v | 218 +++++++++++++ tb/test_eth_demux_64_4.py | 671 ++++++++++++++++++++++++++++++++++++++ tb/test_eth_demux_64_4.v | 233 +++++++++++++ 8 files changed, 3200 insertions(+) create mode 100755 rtl/eth_demux.py create mode 100644 rtl/eth_demux_4.v create mode 100755 rtl/eth_demux_64.py create mode 100644 rtl/eth_demux_64_4.v create mode 100755 tb/test_eth_demux_4.py create mode 100644 tb/test_eth_demux_4.v create mode 100755 tb/test_eth_demux_64_4.py create mode 100644 tb/test_eth_demux_64_4.v diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py new file mode 100755 index 000000000..302f75790 --- /dev/null +++ b/rtl/eth_demux.py @@ -0,0 +1,349 @@ +#!/usr/bin/env python +"""eth_demux + +Generates an Ethernet demux with the specified number of ports + +Usage: eth_demux [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "eth_demux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port Ethernet demux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * Ethernet {{n}} port demultiplexer + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [7:0] input_eth_payload_tdata, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame outputs + */ +{%- for p in ports %} + output wire output_{{p}}_eth_hdr_valid, + input wire output_{{p}}_eth_hdr_ready, + output wire [47:0] output_{{p}}_eth_dest_mac, + output wire [47:0] output_{{p}}_eth_src_mac, + output wire [15:0] output_{{p}}_eth_type, + output wire [7:0] output_{{p}}_eth_payload_tdata, + output wire output_{{p}}_eth_payload_tvalid, + input wire output_{{p}}_eth_payload_tready, + output wire output_{{p}}_eth_payload_tlast, + output wire output_{{p}}_eth_payload_tuser, +{% endfor %} + /* + * Control + */ + input wire enable, + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +{% for p in ports %} +reg output_{{p}}_eth_hdr_valid_reg = 0, output_{{p}}_eth_hdr_valid_next; +{%- endfor %} +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; + +// internal datapath +reg [7:0] output_eth_payload_tdata_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + +assign input_eth_hdr_ready = input_eth_hdr_ready_reg; +assign input_eth_payload_tready = input_eth_payload_tready_reg; +{% for p in ports %} +assign output_{{p}}_eth_hdr_valid = output_{{p}}_eth_hdr_valid_reg; +assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; +assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; +assign output_{{p}}_eth_type = output_eth_type_reg; +{% endfor %} +// mux for output control signals +reg current_output_eth_hdr_valid; +reg current_output_eth_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_output_eth_hdr_valid = output_{{p}}_eth_hdr_valid; + current_output_eth_hdr_ready = output_{{p}}_eth_hdr_ready; + current_output_tvalid = output_{{p}}_eth_payload_tvalid; + current_output_tready = output_{{p}}_eth_payload_tready; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; + input_eth_payload_tready_next = 0; + +{%- for p in ports %} + output_{{p}}_eth_hdr_valid_next = output_{{p}}_eth_hdr_valid_reg & ~output_{{p}}_eth_hdr_ready; +{%- endfor %} + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + + if (frame_reg) begin + if (input_eth_payload_tvalid & input_eth_payload_tready) begin + // end of frame detection + frame_next = ~input_eth_payload_tlast; + end + end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_eth_hdr_ready_next = 1; + + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_eth_hdr_valid_next = 1; +{%- endfor %} + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + end + + input_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + + output_eth_payload_tdata_int = input_eth_payload_tdata; + output_eth_payload_tvalid_int = input_eth_payload_tvalid & input_eth_payload_tready; + output_eth_payload_tlast_int = input_eth_payload_tlast; + output_eth_payload_tuser_int = input_eth_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; +{%- for p in ports %} + output_{{p}}_eth_hdr_valid_reg <= 0; +{%- endfor %} + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + input_eth_payload_tready_reg <= input_eth_payload_tready_next; +{%- for p in ports %} + output_{{p}}_eth_hdr_valid_reg <= output_{{p}}_eth_hdr_valid_next; +{%- endfor %} + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + end +end + +// output datapath logic +reg [7:0] output_eth_payload_tdata_reg = 0; +{%- for p in ports %} +reg output_{{p}}_eth_payload_tvalid_reg = 0; +{%- endfor %} +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [7:0] temp_eth_payload_tdata_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; +{% for p in ports %} +assign output_{{p}}_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_{{p}}_eth_payload_tvalid = output_{{p}}_eth_payload_tvalid_reg; +assign output_{{p}}_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_{{p}}_eth_payload_tuser = output_eth_payload_tuser_reg; +{% endfor %} +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; +{%- for p in ports %} + output_{{p}}_eth_payload_tvalid_reg <= 0; +{%- endfor %} + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; +{%- endfor %} + endcase + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; +{%- endfor %} + endcase + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/eth_demux_4.v b/rtl/eth_demux_4.v new file mode 100644 index 000000000..3ca93c52a --- /dev/null +++ b/rtl/eth_demux_4.v @@ -0,0 +1,351 @@ +/* + +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 + +/* + * Ethernet 4 port demultiplexer + */ +module eth_demux_4 +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [7:0] input_eth_payload_tdata, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame outputs + */ + output wire output_0_eth_hdr_valid, + input wire output_0_eth_hdr_ready, + output wire [47:0] output_0_eth_dest_mac, + output wire [47:0] output_0_eth_src_mac, + output wire [15:0] output_0_eth_type, + output wire [7:0] output_0_eth_payload_tdata, + output wire output_0_eth_payload_tvalid, + input wire output_0_eth_payload_tready, + output wire output_0_eth_payload_tlast, + output wire output_0_eth_payload_tuser, + + output wire output_1_eth_hdr_valid, + input wire output_1_eth_hdr_ready, + output wire [47:0] output_1_eth_dest_mac, + output wire [47:0] output_1_eth_src_mac, + output wire [15:0] output_1_eth_type, + output wire [7:0] output_1_eth_payload_tdata, + output wire output_1_eth_payload_tvalid, + input wire output_1_eth_payload_tready, + output wire output_1_eth_payload_tlast, + output wire output_1_eth_payload_tuser, + + output wire output_2_eth_hdr_valid, + input wire output_2_eth_hdr_ready, + output wire [47:0] output_2_eth_dest_mac, + output wire [47:0] output_2_eth_src_mac, + output wire [15:0] output_2_eth_type, + output wire [7:0] output_2_eth_payload_tdata, + output wire output_2_eth_payload_tvalid, + input wire output_2_eth_payload_tready, + output wire output_2_eth_payload_tlast, + output wire output_2_eth_payload_tuser, + + output wire output_3_eth_hdr_valid, + input wire output_3_eth_hdr_ready, + output wire [47:0] output_3_eth_dest_mac, + output wire [47:0] output_3_eth_src_mac, + output wire [15:0] output_3_eth_type, + output wire [7:0] output_3_eth_payload_tdata, + output wire output_3_eth_payload_tvalid, + input wire output_3_eth_payload_tready, + output wire output_3_eth_payload_tlast, + output wire output_3_eth_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; + +reg output_0_eth_hdr_valid_reg = 0, output_0_eth_hdr_valid_next; +reg output_1_eth_hdr_valid_reg = 0, output_1_eth_hdr_valid_next; +reg output_2_eth_hdr_valid_reg = 0, output_2_eth_hdr_valid_next; +reg output_3_eth_hdr_valid_reg = 0, output_3_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; + +// internal datapath +reg [7:0] output_eth_payload_tdata_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + +assign input_eth_hdr_ready = input_eth_hdr_ready_reg; +assign input_eth_payload_tready = input_eth_payload_tready_reg; + +assign output_0_eth_hdr_valid = output_0_eth_hdr_valid_reg; +assign output_0_eth_dest_mac = output_eth_dest_mac_reg; +assign output_0_eth_src_mac = output_eth_src_mac_reg; +assign output_0_eth_type = output_eth_type_reg; + +assign output_1_eth_hdr_valid = output_1_eth_hdr_valid_reg; +assign output_1_eth_dest_mac = output_eth_dest_mac_reg; +assign output_1_eth_src_mac = output_eth_src_mac_reg; +assign output_1_eth_type = output_eth_type_reg; + +assign output_2_eth_hdr_valid = output_2_eth_hdr_valid_reg; +assign output_2_eth_dest_mac = output_eth_dest_mac_reg; +assign output_2_eth_src_mac = output_eth_src_mac_reg; +assign output_2_eth_type = output_eth_type_reg; + +assign output_3_eth_hdr_valid = output_3_eth_hdr_valid_reg; +assign output_3_eth_dest_mac = output_eth_dest_mac_reg; +assign output_3_eth_src_mac = output_eth_src_mac_reg; +assign output_3_eth_type = output_eth_type_reg; + +// mux for output control signals +reg current_output_eth_hdr_valid; +reg current_output_eth_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) + 2'd0: begin + current_output_eth_hdr_valid = output_0_eth_hdr_valid; + current_output_eth_hdr_ready = output_0_eth_hdr_ready; + current_output_tvalid = output_0_eth_payload_tvalid; + current_output_tready = output_0_eth_payload_tready; + end + 2'd1: begin + current_output_eth_hdr_valid = output_1_eth_hdr_valid; + current_output_eth_hdr_ready = output_1_eth_hdr_ready; + current_output_tvalid = output_1_eth_payload_tvalid; + current_output_tready = output_1_eth_payload_tready; + end + 2'd2: begin + current_output_eth_hdr_valid = output_2_eth_hdr_valid; + current_output_eth_hdr_ready = output_2_eth_hdr_ready; + current_output_tvalid = output_2_eth_payload_tvalid; + current_output_tready = output_2_eth_payload_tready; + end + 2'd3: begin + current_output_eth_hdr_valid = output_3_eth_hdr_valid; + current_output_eth_hdr_ready = output_3_eth_hdr_ready; + current_output_tvalid = output_3_eth_payload_tvalid; + current_output_tready = output_3_eth_payload_tready; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; + input_eth_payload_tready_next = 0; + output_0_eth_hdr_valid_next = output_0_eth_hdr_valid_reg & ~output_0_eth_hdr_ready; + output_1_eth_hdr_valid_next = output_1_eth_hdr_valid_reg & ~output_1_eth_hdr_ready; + output_2_eth_hdr_valid_next = output_2_eth_hdr_valid_reg & ~output_2_eth_hdr_ready; + output_3_eth_hdr_valid_next = output_3_eth_hdr_valid_reg & ~output_3_eth_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + + if (frame_reg) begin + if (input_eth_payload_tvalid & input_eth_payload_tready) begin + // end of frame detection + frame_next = ~input_eth_payload_tlast; + end + end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_eth_hdr_ready_next = 1; + + case (select) + 2'd0: output_0_eth_hdr_valid_next = 1; + 2'd1: output_1_eth_hdr_valid_next = 1; + 2'd2: output_2_eth_hdr_valid_next = 1; + 2'd3: output_3_eth_hdr_valid_next = 1; + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + end + + input_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + + output_eth_payload_tdata_int = input_eth_payload_tdata; + output_eth_payload_tvalid_int = input_eth_payload_tvalid & input_eth_payload_tready; + output_eth_payload_tlast_int = input_eth_payload_tlast; + output_eth_payload_tuser_int = input_eth_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_0_eth_hdr_valid_reg <= 0; + output_1_eth_hdr_valid_reg <= 0; + output_2_eth_hdr_valid_reg <= 0; + output_3_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + input_eth_payload_tready_reg <= input_eth_payload_tready_next; + output_0_eth_hdr_valid_reg <= output_0_eth_hdr_valid_next; + output_1_eth_hdr_valid_reg <= output_1_eth_hdr_valid_next; + output_2_eth_hdr_valid_reg <= output_2_eth_hdr_valid_next; + output_3_eth_hdr_valid_reg <= output_3_eth_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + end +end + +// output datapath logic +reg [7:0] output_eth_payload_tdata_reg = 0; +reg output_0_eth_payload_tvalid_reg = 0; +reg output_1_eth_payload_tvalid_reg = 0; +reg output_2_eth_payload_tvalid_reg = 0; +reg output_3_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [7:0] temp_eth_payload_tdata_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +assign output_0_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_0_eth_payload_tvalid = output_0_eth_payload_tvalid_reg; +assign output_0_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_0_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign output_1_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_1_eth_payload_tvalid = output_1_eth_payload_tvalid_reg; +assign output_1_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_1_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign output_2_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_2_eth_payload_tvalid = output_2_eth_payload_tvalid_reg; +assign output_2_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_2_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign output_3_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_3_eth_payload_tvalid = output_3_eth_payload_tvalid_reg; +assign output_3_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_3_eth_payload_tuser = output_eth_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_0_eth_payload_tvalid_reg <= 0; + output_1_eth_payload_tvalid_reg <= 0; + output_2_eth_payload_tvalid_reg <= 0; + output_3_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + case (select_reg) + 2'd0: output_0_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + 2'd1: output_1_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + 2'd2: output_2_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + 2'd3: output_3_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + endcase + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + case (select_reg) + 2'd0: output_0_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + 2'd1: output_1_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + 2'd2: output_2_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + 2'd3: output_3_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + endcase + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py new file mode 100755 index 000000000..2950af1dd --- /dev/null +++ b/rtl/eth_demux_64.py @@ -0,0 +1,362 @@ +#!/usr/bin/env python +"""eth_demux_64 + +Generates an Ethernet demux with the specified number of ports + +Usage: eth_demux_64 [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "eth_demux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port Ethernet demux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * Ethernet {{n}} port demultiplexer (64 bit datapath) + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [63:0] input_eth_payload_tdata, + input wire [7:0] input_eth_payload_tkeep, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame outputs + */ +{%- for p in ports %} + output wire output_{{p}}_eth_hdr_valid, + input wire output_{{p}}_eth_hdr_ready, + output wire [47:0] output_{{p}}_eth_dest_mac, + output wire [47:0] output_{{p}}_eth_src_mac, + output wire [15:0] output_{{p}}_eth_type, + output wire [63:0] output_{{p}}_eth_payload_tdata, + output wire [7:0] output_{{p}}_eth_payload_tkeep, + output wire output_{{p}}_eth_payload_tvalid, + input wire output_{{p}}_eth_payload_tready, + output wire output_{{p}}_eth_payload_tlast, + output wire output_{{p}}_eth_payload_tuser, +{% endfor %} + /* + * Control + */ + input wire enable, + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +{% for p in ports %} +reg output_{{p}}_eth_hdr_valid_reg = 0, output_{{p}}_eth_hdr_valid_next; +{%- endfor %} +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; + +// internal datapath +reg [63:0] output_eth_payload_tdata_int; +reg [7:0] output_eth_payload_tkeep_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + +assign input_eth_hdr_ready = input_eth_hdr_ready_reg; +assign input_eth_payload_tready = input_eth_payload_tready_reg; +{% for p in ports %} +assign output_{{p}}_eth_hdr_valid = output_{{p}}_eth_hdr_valid_reg; +assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; +assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; +assign output_{{p}}_eth_type = output_eth_type_reg; +{% endfor %} +// mux for output control signals +reg current_output_eth_hdr_valid; +reg current_output_eth_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_output_eth_hdr_valid = output_{{p}}_eth_hdr_valid; + current_output_eth_hdr_ready = output_{{p}}_eth_hdr_ready; + current_output_tvalid = output_{{p}}_eth_payload_tvalid; + current_output_tready = output_{{p}}_eth_payload_tready; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; + input_eth_payload_tready_next = 0; + +{%- for p in ports %} + output_{{p}}_eth_hdr_valid_next = output_{{p}}_eth_hdr_valid_reg & ~output_{{p}}_eth_hdr_ready; +{%- endfor %} + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + + if (frame_reg) begin + if (input_eth_payload_tvalid & input_eth_payload_tready) begin + // end of frame detection + frame_next = ~input_eth_payload_tlast; + end + end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_eth_hdr_ready_next = 1; + + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_eth_hdr_valid_next = 1; +{%- endfor %} + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + end + + input_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + + output_eth_payload_tdata_int = input_eth_payload_tdata; + output_eth_payload_tkeep_int = input_eth_payload_tkeep; + output_eth_payload_tvalid_int = input_eth_payload_tvalid & input_eth_payload_tready; + output_eth_payload_tlast_int = input_eth_payload_tlast; + output_eth_payload_tuser_int = input_eth_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; +{%- for p in ports %} + output_{{p}}_eth_hdr_valid_reg <= 0; +{%- endfor %} + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + input_eth_payload_tready_reg <= input_eth_payload_tready_next; +{%- for p in ports %} + output_{{p}}_eth_hdr_valid_reg <= output_{{p}}_eth_hdr_valid_next; +{%- endfor %} + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + end +end + +// output datapath logic +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +{%- for p in ports %} +reg output_{{p}}_eth_payload_tvalid_reg = 0; +{%- endfor %} +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [63:0] temp_eth_payload_tdata_reg = 0; +reg [7:0] temp_eth_payload_tkeep_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; +{% for p in ports %} +assign output_{{p}}_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_{{p}}_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_{{p}}_eth_payload_tvalid = output_{{p}}_eth_payload_tvalid_reg; +assign output_{{p}}_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_{{p}}_eth_payload_tuser = output_eth_payload_tuser_reg; +{% endfor %} +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tkeep_reg <= 0; +{%- for p in ports %} + output_{{p}}_eth_payload_tvalid_reg <= 0; +{%- endfor %} + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; +{%- endfor %} + endcase + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; +{%- endfor %} + endcase + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/eth_demux_64_4.v b/rtl/eth_demux_64_4.v new file mode 100644 index 000000000..5294656a0 --- /dev/null +++ b/rtl/eth_demux_64_4.v @@ -0,0 +1,370 @@ +/* + +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 + +/* + * Ethernet 4 port demultiplexer (64 bit datapath) + */ +module eth_demux_64_4 +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [63:0] input_eth_payload_tdata, + input wire [7:0] input_eth_payload_tkeep, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame outputs + */ + output wire output_0_eth_hdr_valid, + input wire output_0_eth_hdr_ready, + output wire [47:0] output_0_eth_dest_mac, + output wire [47:0] output_0_eth_src_mac, + output wire [15:0] output_0_eth_type, + output wire [63:0] output_0_eth_payload_tdata, + output wire [7:0] output_0_eth_payload_tkeep, + output wire output_0_eth_payload_tvalid, + input wire output_0_eth_payload_tready, + output wire output_0_eth_payload_tlast, + output wire output_0_eth_payload_tuser, + + output wire output_1_eth_hdr_valid, + input wire output_1_eth_hdr_ready, + output wire [47:0] output_1_eth_dest_mac, + output wire [47:0] output_1_eth_src_mac, + output wire [15:0] output_1_eth_type, + output wire [63:0] output_1_eth_payload_tdata, + output wire [7:0] output_1_eth_payload_tkeep, + output wire output_1_eth_payload_tvalid, + input wire output_1_eth_payload_tready, + output wire output_1_eth_payload_tlast, + output wire output_1_eth_payload_tuser, + + output wire output_2_eth_hdr_valid, + input wire output_2_eth_hdr_ready, + output wire [47:0] output_2_eth_dest_mac, + output wire [47:0] output_2_eth_src_mac, + output wire [15:0] output_2_eth_type, + output wire [63:0] output_2_eth_payload_tdata, + output wire [7:0] output_2_eth_payload_tkeep, + output wire output_2_eth_payload_tvalid, + input wire output_2_eth_payload_tready, + output wire output_2_eth_payload_tlast, + output wire output_2_eth_payload_tuser, + + output wire output_3_eth_hdr_valid, + input wire output_3_eth_hdr_ready, + output wire [47:0] output_3_eth_dest_mac, + output wire [47:0] output_3_eth_src_mac, + output wire [15:0] output_3_eth_type, + output wire [63:0] output_3_eth_payload_tdata, + output wire [7:0] output_3_eth_payload_tkeep, + output wire output_3_eth_payload_tvalid, + input wire output_3_eth_payload_tready, + output wire output_3_eth_payload_tlast, + output wire output_3_eth_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; + +reg output_0_eth_hdr_valid_reg = 0, output_0_eth_hdr_valid_next; +reg output_1_eth_hdr_valid_reg = 0, output_1_eth_hdr_valid_next; +reg output_2_eth_hdr_valid_reg = 0, output_2_eth_hdr_valid_next; +reg output_3_eth_hdr_valid_reg = 0, output_3_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; + +// internal datapath +reg [63:0] output_eth_payload_tdata_int; +reg [7:0] output_eth_payload_tkeep_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + +assign input_eth_hdr_ready = input_eth_hdr_ready_reg; +assign input_eth_payload_tready = input_eth_payload_tready_reg; + +assign output_0_eth_hdr_valid = output_0_eth_hdr_valid_reg; +assign output_0_eth_dest_mac = output_eth_dest_mac_reg; +assign output_0_eth_src_mac = output_eth_src_mac_reg; +assign output_0_eth_type = output_eth_type_reg; + +assign output_1_eth_hdr_valid = output_1_eth_hdr_valid_reg; +assign output_1_eth_dest_mac = output_eth_dest_mac_reg; +assign output_1_eth_src_mac = output_eth_src_mac_reg; +assign output_1_eth_type = output_eth_type_reg; + +assign output_2_eth_hdr_valid = output_2_eth_hdr_valid_reg; +assign output_2_eth_dest_mac = output_eth_dest_mac_reg; +assign output_2_eth_src_mac = output_eth_src_mac_reg; +assign output_2_eth_type = output_eth_type_reg; + +assign output_3_eth_hdr_valid = output_3_eth_hdr_valid_reg; +assign output_3_eth_dest_mac = output_eth_dest_mac_reg; +assign output_3_eth_src_mac = output_eth_src_mac_reg; +assign output_3_eth_type = output_eth_type_reg; + +// mux for output control signals +reg current_output_eth_hdr_valid; +reg current_output_eth_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) + 2'd0: begin + current_output_eth_hdr_valid = output_0_eth_hdr_valid; + current_output_eth_hdr_ready = output_0_eth_hdr_ready; + current_output_tvalid = output_0_eth_payload_tvalid; + current_output_tready = output_0_eth_payload_tready; + end + 2'd1: begin + current_output_eth_hdr_valid = output_1_eth_hdr_valid; + current_output_eth_hdr_ready = output_1_eth_hdr_ready; + current_output_tvalid = output_1_eth_payload_tvalid; + current_output_tready = output_1_eth_payload_tready; + end + 2'd2: begin + current_output_eth_hdr_valid = output_2_eth_hdr_valid; + current_output_eth_hdr_ready = output_2_eth_hdr_ready; + current_output_tvalid = output_2_eth_payload_tvalid; + current_output_tready = output_2_eth_payload_tready; + end + 2'd3: begin + current_output_eth_hdr_valid = output_3_eth_hdr_valid; + current_output_eth_hdr_ready = output_3_eth_hdr_ready; + current_output_tvalid = output_3_eth_payload_tvalid; + current_output_tready = output_3_eth_payload_tready; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; + input_eth_payload_tready_next = 0; + output_0_eth_hdr_valid_next = output_0_eth_hdr_valid_reg & ~output_0_eth_hdr_ready; + output_1_eth_hdr_valid_next = output_1_eth_hdr_valid_reg & ~output_1_eth_hdr_ready; + output_2_eth_hdr_valid_next = output_2_eth_hdr_valid_reg & ~output_2_eth_hdr_ready; + output_3_eth_hdr_valid_next = output_3_eth_hdr_valid_reg & ~output_3_eth_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + + if (frame_reg) begin + if (input_eth_payload_tvalid & input_eth_payload_tready) begin + // end of frame detection + frame_next = ~input_eth_payload_tlast; + end + end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_eth_hdr_ready_next = 1; + + case (select) + 2'd0: output_0_eth_hdr_valid_next = 1; + 2'd1: output_1_eth_hdr_valid_next = 1; + 2'd2: output_2_eth_hdr_valid_next = 1; + 2'd3: output_3_eth_hdr_valid_next = 1; + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + end + + input_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + + output_eth_payload_tdata_int = input_eth_payload_tdata; + output_eth_payload_tkeep_int = input_eth_payload_tkeep; + output_eth_payload_tvalid_int = input_eth_payload_tvalid & input_eth_payload_tready; + output_eth_payload_tlast_int = input_eth_payload_tlast; + output_eth_payload_tuser_int = input_eth_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_eth_hdr_ready_reg <= 0; + input_eth_payload_tready_reg <= 0; + output_0_eth_hdr_valid_reg <= 0; + output_1_eth_hdr_valid_reg <= 0; + output_2_eth_hdr_valid_reg <= 0; + output_3_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + input_eth_payload_tready_reg <= input_eth_payload_tready_next; + output_0_eth_hdr_valid_reg <= output_0_eth_hdr_valid_next; + output_1_eth_hdr_valid_reg <= output_1_eth_hdr_valid_next; + output_2_eth_hdr_valid_reg <= output_2_eth_hdr_valid_next; + output_3_eth_hdr_valid_reg <= output_3_eth_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + end +end + +// output datapath logic +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +reg output_0_eth_payload_tvalid_reg = 0; +reg output_1_eth_payload_tvalid_reg = 0; +reg output_2_eth_payload_tvalid_reg = 0; +reg output_3_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [63:0] temp_eth_payload_tdata_reg = 0; +reg [7:0] temp_eth_payload_tkeep_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +assign output_0_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_0_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_0_eth_payload_tvalid = output_0_eth_payload_tvalid_reg; +assign output_0_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_0_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign output_1_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_1_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_1_eth_payload_tvalid = output_1_eth_payload_tvalid_reg; +assign output_1_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_1_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign output_2_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_2_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_2_eth_payload_tvalid = output_2_eth_payload_tvalid_reg; +assign output_2_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_2_eth_payload_tuser = output_eth_payload_tuser_reg; + +assign output_3_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_3_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_3_eth_payload_tvalid = output_3_eth_payload_tvalid_reg; +assign output_3_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_3_eth_payload_tuser = output_eth_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tkeep_reg <= 0; + output_0_eth_payload_tvalid_reg <= 0; + output_1_eth_payload_tvalid_reg <= 0; + output_2_eth_payload_tvalid_reg <= 0; + output_3_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + case (select_reg) + 2'd0: output_0_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + 2'd1: output_1_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + 2'd2: output_2_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + 2'd3: output_3_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + endcase + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + case (select_reg) + 2'd0: output_0_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + 2'd1: output_1_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + 2'd2: output_2_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + 2'd3: output_3_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + endcase + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_eth_demux_4.py b/tb/test_eth_demux_4.py new file mode 100755 index 000000000..b57963fac --- /dev/null +++ b/tb/test_eth_demux_4.py @@ -0,0 +1,646 @@ +#!/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 eth_ep + +module = 'eth_demux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_demux_4(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_0_eth_hdr_valid, + output_0_eth_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_eth_payload_tdata, + output_0_eth_payload_tvalid, + output_0_eth_payload_tready, + output_0_eth_payload_tlast, + output_0_eth_payload_tuser, + output_1_eth_hdr_valid, + output_1_eth_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_eth_payload_tdata, + output_1_eth_payload_tvalid, + output_1_eth_payload_tready, + output_1_eth_payload_tlast, + output_1_eth_payload_tuser, + output_2_eth_hdr_valid, + output_2_eth_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_eth_payload_tdata, + output_2_eth_payload_tvalid, + output_2_eth_payload_tready, + output_2_eth_payload_tlast, + output_2_eth_payload_tuser, + output_3_eth_hdr_valid, + output_3_eth_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_eth_payload_tdata, + output_3_eth_payload_tvalid, + output_3_eth_payload_tready, + output_3_eth_payload_tlast, + output_3_eth_payload_tuser, + + enable, + select): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_0_eth_hdr_valid=output_0_eth_hdr_valid, + output_0_eth_hdr_ready=output_0_eth_hdr_ready, + output_0_eth_dest_mac=output_0_eth_dest_mac, + output_0_eth_src_mac=output_0_eth_src_mac, + output_0_eth_type=output_0_eth_type, + output_0_eth_payload_tdata=output_0_eth_payload_tdata, + output_0_eth_payload_tvalid=output_0_eth_payload_tvalid, + output_0_eth_payload_tready=output_0_eth_payload_tready, + output_0_eth_payload_tlast=output_0_eth_payload_tlast, + output_0_eth_payload_tuser=output_0_eth_payload_tuser, + output_1_eth_hdr_valid=output_1_eth_hdr_valid, + output_1_eth_hdr_ready=output_1_eth_hdr_ready, + output_1_eth_dest_mac=output_1_eth_dest_mac, + output_1_eth_src_mac=output_1_eth_src_mac, + output_1_eth_type=output_1_eth_type, + output_1_eth_payload_tdata=output_1_eth_payload_tdata, + output_1_eth_payload_tvalid=output_1_eth_payload_tvalid, + output_1_eth_payload_tready=output_1_eth_payload_tready, + output_1_eth_payload_tlast=output_1_eth_payload_tlast, + output_1_eth_payload_tuser=output_1_eth_payload_tuser, + output_2_eth_hdr_valid=output_2_eth_hdr_valid, + output_2_eth_hdr_ready=output_2_eth_hdr_ready, + output_2_eth_dest_mac=output_2_eth_dest_mac, + output_2_eth_src_mac=output_2_eth_src_mac, + output_2_eth_type=output_2_eth_type, + output_2_eth_payload_tdata=output_2_eth_payload_tdata, + output_2_eth_payload_tvalid=output_2_eth_payload_tvalid, + output_2_eth_payload_tready=output_2_eth_payload_tready, + output_2_eth_payload_tlast=output_2_eth_payload_tlast, + output_2_eth_payload_tuser=output_2_eth_payload_tuser, + output_3_eth_hdr_valid=output_3_eth_hdr_valid, + output_3_eth_hdr_ready=output_3_eth_hdr_ready, + output_3_eth_dest_mac=output_3_eth_dest_mac, + output_3_eth_src_mac=output_3_eth_src_mac, + output_3_eth_type=output_3_eth_type, + output_3_eth_payload_tdata=output_3_eth_payload_tdata, + output_3_eth_payload_tvalid=output_3_eth_payload_tvalid, + output_3_eth_payload_tready=output_3_eth_payload_tready, + output_3_eth_payload_tlast=output_3_eth_payload_tlast, + output_3_eth_payload_tuser=output_3_eth_payload_tuser, + + enable=enable, + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + + output_0_eth_hdr_ready = Signal(bool(0)) + output_0_eth_payload_tready = Signal(bool(0)) + output_1_eth_hdr_ready = Signal(bool(0)) + output_1_eth_payload_tready = Signal(bool(0)) + output_2_eth_hdr_ready = Signal(bool(0)) + output_2_eth_payload_tready = Signal(bool(0)) + output_3_eth_hdr_ready = Signal(bool(0)) + output_3_eth_payload_tready = Signal(bool(0)) + + enable = Signal(bool(0)) + select = Signal(intbv(0)[2:]) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + + output_0_eth_hdr_valid = Signal(bool(0)) + output_0_eth_dest_mac = Signal(intbv(0)[48:]) + output_0_eth_src_mac = Signal(intbv(0)[48:]) + output_0_eth_type = Signal(intbv(0)[16:]) + output_0_eth_payload_tdata = Signal(intbv(0)[8:]) + output_0_eth_payload_tvalid = Signal(bool(0)) + output_0_eth_payload_tlast = Signal(bool(0)) + output_0_eth_payload_tuser = Signal(bool(0)) + output_1_eth_hdr_valid = Signal(bool(0)) + output_1_eth_dest_mac = Signal(intbv(0)[48:]) + output_1_eth_src_mac = Signal(intbv(0)[48:]) + output_1_eth_type = Signal(intbv(0)[16:]) + output_1_eth_payload_tdata = Signal(intbv(0)[8:]) + output_1_eth_payload_tvalid = Signal(bool(0)) + output_1_eth_payload_tlast = Signal(bool(0)) + output_1_eth_payload_tuser = Signal(bool(0)) + output_2_eth_hdr_valid = Signal(bool(0)) + output_2_eth_dest_mac = Signal(intbv(0)[48:]) + output_2_eth_src_mac = Signal(intbv(0)[48:]) + output_2_eth_type = Signal(intbv(0)[16:]) + output_2_eth_payload_tdata = Signal(intbv(0)[8:]) + output_2_eth_payload_tvalid = Signal(bool(0)) + output_2_eth_payload_tlast = Signal(bool(0)) + output_2_eth_payload_tuser = Signal(bool(0)) + output_3_eth_hdr_valid = Signal(bool(0)) + output_3_eth_dest_mac = Signal(intbv(0)[48:]) + output_3_eth_src_mac = Signal(intbv(0)[48:]) + output_3_eth_type = Signal(intbv(0)[16:]) + output_3_eth_payload_tdata = Signal(intbv(0)[8:]) + output_3_eth_payload_tvalid = Signal(bool(0)) + output_3_eth_payload_tlast = Signal(bool(0)) + output_3_eth_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_pause = Signal(bool(0)) + + source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink_0 = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_0_eth_hdr_ready, + eth_hdr_valid=output_0_eth_hdr_valid, + eth_dest_mac=output_0_eth_dest_mac, + eth_src_mac=output_0_eth_src_mac, + eth_type=output_0_eth_type, + eth_payload_tdata=output_0_eth_payload_tdata, + eth_payload_tvalid=output_0_eth_payload_tvalid, + eth_payload_tready=output_0_eth_payload_tready, + eth_payload_tlast=output_0_eth_payload_tlast, + eth_payload_tuser=output_0_eth_payload_tuser, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + + sink_1 = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_1_eth_hdr_ready, + eth_hdr_valid=output_1_eth_hdr_valid, + eth_dest_mac=output_1_eth_dest_mac, + eth_src_mac=output_1_eth_src_mac, + eth_type=output_1_eth_type, + eth_payload_tdata=output_1_eth_payload_tdata, + eth_payload_tvalid=output_1_eth_payload_tvalid, + eth_payload_tready=output_1_eth_payload_tready, + eth_payload_tlast=output_1_eth_payload_tlast, + eth_payload_tuser=output_1_eth_payload_tuser, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + + sink_2 = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_2_eth_hdr_ready, + eth_hdr_valid=output_2_eth_hdr_valid, + eth_dest_mac=output_2_eth_dest_mac, + eth_src_mac=output_2_eth_src_mac, + eth_type=output_2_eth_type, + eth_payload_tdata=output_2_eth_payload_tdata, + eth_payload_tvalid=output_2_eth_payload_tvalid, + eth_payload_tready=output_2_eth_payload_tready, + eth_payload_tlast=output_2_eth_payload_tlast, + eth_payload_tuser=output_2_eth_payload_tuser, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + + sink_3 = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_3_eth_hdr_ready, + eth_hdr_valid=output_3_eth_hdr_valid, + eth_dest_mac=output_3_eth_dest_mac, + eth_src_mac=output_3_eth_src_mac, + eth_type=output_3_eth_type, + eth_payload_tdata=output_3_eth_payload_tdata, + eth_payload_tvalid=output_3_eth_payload_tvalid, + eth_payload_tready=output_3_eth_payload_tready, + eth_payload_tlast=output_3_eth_payload_tlast, + eth_payload_tuser=output_3_eth_payload_tuser, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_eth_demux_4(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_0_eth_hdr_valid, + output_0_eth_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_eth_payload_tdata, + output_0_eth_payload_tvalid, + output_0_eth_payload_tready, + output_0_eth_payload_tlast, + output_0_eth_payload_tuser, + output_1_eth_hdr_valid, + output_1_eth_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_eth_payload_tdata, + output_1_eth_payload_tvalid, + output_1_eth_payload_tready, + output_1_eth_payload_tlast, + output_1_eth_payload_tuser, + output_2_eth_hdr_valid, + output_2_eth_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_eth_payload_tdata, + output_2_eth_payload_tvalid, + output_2_eth_payload_tready, + output_2_eth_payload_tlast, + output_2_eth_payload_tuser, + output_3_eth_hdr_valid, + output_3_eth_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_eth_payload_tdata, + output_3_eth_payload_tvalid, + output_3_eth_payload_tready, + output_3_eth_payload_tlast, + output_3_eth_payload_tuser, + + enable, + select) + + @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 + enable.next = True + + yield clk.posedge + print("test 1: select port 0") + current_test.next = 1 + + select.next = 0 + + 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(range(32)) + + source_queue.put(test_frame) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.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(range(32)) + + source_queue.put(test_frame) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + 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(range(32)) + 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(range(32)) + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + sink_0_pause.next = True + sink_1_pause.next = True + sink_2_pause.next = True + sink_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_0_pause.next = False + sink_1_pause.next = False + sink_2_pause.next = False + sink_3_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + raise StopSimulation + + return dut, source, sink_0, sink_1, sink_2, sink_3, 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() + diff --git a/tb/test_eth_demux_4.v b/tb/test_eth_demux_4.v new file mode 100644 index 000000000..8bc5d87e6 --- /dev/null +++ b/tb/test_eth_demux_4.v @@ -0,0 +1,218 @@ +/* + +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_eth_demux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [7:0] input_eth_payload_tdata = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; + +reg output_0_eth_hdr_ready = 0; +reg output_0_eth_payload_tready = 0; +reg output_1_eth_hdr_ready = 0; +reg output_1_eth_payload_tready = 0; +reg output_2_eth_hdr_ready = 0; +reg output_2_eth_payload_tready = 0; +reg output_3_eth_hdr_ready = 0; +reg output_3_eth_payload_tready = 0; + +reg enable = 0; +reg [1:0] select = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; + +wire output_0_eth_hdr_valid; +wire [47:0] output_0_eth_dest_mac; +wire [47:0] output_0_eth_src_mac; +wire [15:0] output_0_eth_type; +wire [7:0] output_0_eth_payload_tdata; +wire output_0_eth_payload_tvalid; +wire output_0_eth_payload_tlast; +wire output_0_eth_payload_tuser; +wire output_1_eth_hdr_valid; +wire [47:0] output_1_eth_dest_mac; +wire [47:0] output_1_eth_src_mac; +wire [15:0] output_1_eth_type; +wire [7:0] output_1_eth_payload_tdata; +wire output_1_eth_payload_tvalid; +wire output_1_eth_payload_tlast; +wire output_1_eth_payload_tuser; +wire output_2_eth_hdr_valid; +wire [47:0] output_2_eth_dest_mac; +wire [47:0] output_2_eth_src_mac; +wire [15:0] output_2_eth_type; +wire [7:0] output_2_eth_payload_tdata; +wire output_2_eth_payload_tvalid; +wire output_2_eth_payload_tlast; +wire output_2_eth_payload_tuser; +wire output_3_eth_hdr_valid; +wire [47:0] output_3_eth_dest_mac; +wire [47:0] output_3_eth_src_mac; +wire [15:0] output_3_eth_type; +wire [7:0] output_3_eth_payload_tdata; +wire output_3_eth_payload_tvalid; +wire output_3_eth_payload_tlast; +wire output_3_eth_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_0_eth_hdr_ready, + output_0_eth_payload_tready, + output_1_eth_hdr_ready, + output_1_eth_payload_tready, + output_2_eth_hdr_ready, + output_2_eth_payload_tready, + output_3_eth_hdr_ready, + output_3_eth_payload_tready, + enable, + select); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + output_0_eth_hdr_valid, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_eth_payload_tdata, + output_0_eth_payload_tvalid, + output_0_eth_payload_tlast, + output_0_eth_payload_tuser, + output_1_eth_hdr_valid, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_eth_payload_tdata, + output_1_eth_payload_tvalid, + output_1_eth_payload_tlast, + output_1_eth_payload_tuser, + output_2_eth_hdr_valid, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_eth_payload_tdata, + output_2_eth_payload_tvalid, + output_2_eth_payload_tlast, + output_2_eth_payload_tuser, + output_3_eth_hdr_valid, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_eth_payload_tdata, + output_3_eth_payload_tvalid, + output_3_eth_payload_tlast, + output_3_eth_payload_tuser); + + // dump file + $dumpfile("test_eth_demux_4.lxt"); + $dumpvars(0, test_eth_demux_4); +end + +eth_demux_4 +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame outputs + .output_0_eth_hdr_valid(output_0_eth_hdr_valid), + .output_0_eth_hdr_ready(output_0_eth_hdr_ready), + .output_0_eth_dest_mac(output_0_eth_dest_mac), + .output_0_eth_src_mac(output_0_eth_src_mac), + .output_0_eth_type(output_0_eth_type), + .output_0_eth_payload_tdata(output_0_eth_payload_tdata), + .output_0_eth_payload_tvalid(output_0_eth_payload_tvalid), + .output_0_eth_payload_tready(output_0_eth_payload_tready), + .output_0_eth_payload_tlast(output_0_eth_payload_tlast), + .output_0_eth_payload_tuser(output_0_eth_payload_tuser), + .output_1_eth_hdr_valid(output_1_eth_hdr_valid), + .output_1_eth_hdr_ready(output_1_eth_hdr_ready), + .output_1_eth_dest_mac(output_1_eth_dest_mac), + .output_1_eth_src_mac(output_1_eth_src_mac), + .output_1_eth_type(output_1_eth_type), + .output_1_eth_payload_tdata(output_1_eth_payload_tdata), + .output_1_eth_payload_tvalid(output_1_eth_payload_tvalid), + .output_1_eth_payload_tready(output_1_eth_payload_tready), + .output_1_eth_payload_tlast(output_1_eth_payload_tlast), + .output_1_eth_payload_tuser(output_1_eth_payload_tuser), + .output_2_eth_hdr_valid(output_2_eth_hdr_valid), + .output_2_eth_hdr_ready(output_2_eth_hdr_ready), + .output_2_eth_dest_mac(output_2_eth_dest_mac), + .output_2_eth_src_mac(output_2_eth_src_mac), + .output_2_eth_type(output_2_eth_type), + .output_2_eth_payload_tdata(output_2_eth_payload_tdata), + .output_2_eth_payload_tvalid(output_2_eth_payload_tvalid), + .output_2_eth_payload_tready(output_2_eth_payload_tready), + .output_2_eth_payload_tlast(output_2_eth_payload_tlast), + .output_2_eth_payload_tuser(output_2_eth_payload_tuser), + .output_3_eth_hdr_valid(output_3_eth_hdr_valid), + .output_3_eth_hdr_ready(output_3_eth_hdr_ready), + .output_3_eth_dest_mac(output_3_eth_dest_mac), + .output_3_eth_src_mac(output_3_eth_src_mac), + .output_3_eth_type(output_3_eth_type), + .output_3_eth_payload_tdata(output_3_eth_payload_tdata), + .output_3_eth_payload_tvalid(output_3_eth_payload_tvalid), + .output_3_eth_payload_tready(output_3_eth_payload_tready), + .output_3_eth_payload_tlast(output_3_eth_payload_tlast), + .output_3_eth_payload_tuser(output_3_eth_payload_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule diff --git a/tb/test_eth_demux_64_4.py b/tb/test_eth_demux_64_4.py new file mode 100755 index 000000000..199fb08a6 --- /dev/null +++ b/tb/test_eth_demux_64_4.py @@ -0,0 +1,671 @@ +#!/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 eth_ep + +module = 'eth_demux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_demux_64_4(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_0_eth_hdr_valid, + output_0_eth_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_eth_payload_tdata, + output_0_eth_payload_tkeep, + output_0_eth_payload_tvalid, + output_0_eth_payload_tready, + output_0_eth_payload_tlast, + output_0_eth_payload_tuser, + output_1_eth_hdr_valid, + output_1_eth_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_eth_payload_tdata, + output_1_eth_payload_tkeep, + output_1_eth_payload_tvalid, + output_1_eth_payload_tready, + output_1_eth_payload_tlast, + output_1_eth_payload_tuser, + output_2_eth_hdr_valid, + output_2_eth_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_eth_payload_tdata, + output_2_eth_payload_tkeep, + output_2_eth_payload_tvalid, + output_2_eth_payload_tready, + output_2_eth_payload_tlast, + output_2_eth_payload_tuser, + output_3_eth_hdr_valid, + output_3_eth_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_eth_payload_tdata, + output_3_eth_payload_tkeep, + output_3_eth_payload_tvalid, + output_3_eth_payload_tready, + output_3_eth_payload_tlast, + output_3_eth_payload_tuser, + + enable, + select): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_0_eth_hdr_valid=output_0_eth_hdr_valid, + output_0_eth_hdr_ready=output_0_eth_hdr_ready, + output_0_eth_dest_mac=output_0_eth_dest_mac, + output_0_eth_src_mac=output_0_eth_src_mac, + output_0_eth_type=output_0_eth_type, + output_0_eth_payload_tdata=output_0_eth_payload_tdata, + output_0_eth_payload_tkeep=output_0_eth_payload_tkeep, + output_0_eth_payload_tvalid=output_0_eth_payload_tvalid, + output_0_eth_payload_tready=output_0_eth_payload_tready, + output_0_eth_payload_tlast=output_0_eth_payload_tlast, + output_0_eth_payload_tuser=output_0_eth_payload_tuser, + output_1_eth_hdr_valid=output_1_eth_hdr_valid, + output_1_eth_hdr_ready=output_1_eth_hdr_ready, + output_1_eth_dest_mac=output_1_eth_dest_mac, + output_1_eth_src_mac=output_1_eth_src_mac, + output_1_eth_type=output_1_eth_type, + output_1_eth_payload_tdata=output_1_eth_payload_tdata, + output_1_eth_payload_tkeep=output_1_eth_payload_tkeep, + output_1_eth_payload_tvalid=output_1_eth_payload_tvalid, + output_1_eth_payload_tready=output_1_eth_payload_tready, + output_1_eth_payload_tlast=output_1_eth_payload_tlast, + output_1_eth_payload_tuser=output_1_eth_payload_tuser, + output_2_eth_hdr_valid=output_2_eth_hdr_valid, + output_2_eth_hdr_ready=output_2_eth_hdr_ready, + output_2_eth_dest_mac=output_2_eth_dest_mac, + output_2_eth_src_mac=output_2_eth_src_mac, + output_2_eth_type=output_2_eth_type, + output_2_eth_payload_tdata=output_2_eth_payload_tdata, + output_2_eth_payload_tkeep=output_2_eth_payload_tkeep, + output_2_eth_payload_tvalid=output_2_eth_payload_tvalid, + output_2_eth_payload_tready=output_2_eth_payload_tready, + output_2_eth_payload_tlast=output_2_eth_payload_tlast, + output_2_eth_payload_tuser=output_2_eth_payload_tuser, + output_3_eth_hdr_valid=output_3_eth_hdr_valid, + output_3_eth_hdr_ready=output_3_eth_hdr_ready, + output_3_eth_dest_mac=output_3_eth_dest_mac, + output_3_eth_src_mac=output_3_eth_src_mac, + output_3_eth_type=output_3_eth_type, + output_3_eth_payload_tdata=output_3_eth_payload_tdata, + output_3_eth_payload_tkeep=output_3_eth_payload_tkeep, + output_3_eth_payload_tvalid=output_3_eth_payload_tvalid, + output_3_eth_payload_tready=output_3_eth_payload_tready, + output_3_eth_payload_tlast=output_3_eth_payload_tlast, + output_3_eth_payload_tuser=output_3_eth_payload_tuser, + + enable=enable, + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[64:]) + input_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + + output_0_eth_hdr_ready = Signal(bool(0)) + output_0_eth_payload_tready = Signal(bool(0)) + output_1_eth_hdr_ready = Signal(bool(0)) + output_1_eth_payload_tready = Signal(bool(0)) + output_2_eth_hdr_ready = Signal(bool(0)) + output_2_eth_payload_tready = Signal(bool(0)) + output_3_eth_hdr_ready = Signal(bool(0)) + output_3_eth_payload_tready = Signal(bool(0)) + + enable = Signal(bool(0)) + select = Signal(intbv(0)[2:]) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + + output_0_eth_hdr_valid = Signal(bool(0)) + output_0_eth_dest_mac = Signal(intbv(0)[48:]) + output_0_eth_src_mac = Signal(intbv(0)[48:]) + output_0_eth_type = Signal(intbv(0)[16:]) + output_0_eth_payload_tdata = Signal(intbv(0)[64:]) + output_0_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_0_eth_payload_tvalid = Signal(bool(0)) + output_0_eth_payload_tlast = Signal(bool(0)) + output_0_eth_payload_tuser = Signal(bool(0)) + output_1_eth_hdr_valid = Signal(bool(0)) + output_1_eth_dest_mac = Signal(intbv(0)[48:]) + output_1_eth_src_mac = Signal(intbv(0)[48:]) + output_1_eth_type = Signal(intbv(0)[16:]) + output_1_eth_payload_tdata = Signal(intbv(0)[64:]) + output_1_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_1_eth_payload_tvalid = Signal(bool(0)) + output_1_eth_payload_tlast = Signal(bool(0)) + output_1_eth_payload_tuser = Signal(bool(0)) + output_2_eth_hdr_valid = Signal(bool(0)) + output_2_eth_dest_mac = Signal(intbv(0)[48:]) + output_2_eth_src_mac = Signal(intbv(0)[48:]) + output_2_eth_type = Signal(intbv(0)[16:]) + output_2_eth_payload_tdata = Signal(intbv(0)[64:]) + output_2_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_2_eth_payload_tvalid = Signal(bool(0)) + output_2_eth_payload_tlast = Signal(bool(0)) + output_2_eth_payload_tuser = Signal(bool(0)) + output_3_eth_hdr_valid = Signal(bool(0)) + output_3_eth_dest_mac = Signal(intbv(0)[48:]) + output_3_eth_src_mac = Signal(intbv(0)[48:]) + output_3_eth_type = Signal(intbv(0)[16:]) + output_3_eth_payload_tdata = Signal(intbv(0)[64:]) + output_3_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_3_eth_payload_tvalid = Signal(bool(0)) + output_3_eth_payload_tlast = Signal(bool(0)) + output_3_eth_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_pause = Signal(bool(0)) + + source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink_0 = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_0_eth_hdr_ready, + eth_hdr_valid=output_0_eth_hdr_valid, + eth_dest_mac=output_0_eth_dest_mac, + eth_src_mac=output_0_eth_src_mac, + eth_type=output_0_eth_type, + eth_payload_tdata=output_0_eth_payload_tdata, + eth_payload_tkeep=output_0_eth_payload_tkeep, + eth_payload_tvalid=output_0_eth_payload_tvalid, + eth_payload_tready=output_0_eth_payload_tready, + eth_payload_tlast=output_0_eth_payload_tlast, + eth_payload_tuser=output_0_eth_payload_tuser, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + + sink_1 = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_1_eth_hdr_ready, + eth_hdr_valid=output_1_eth_hdr_valid, + eth_dest_mac=output_1_eth_dest_mac, + eth_src_mac=output_1_eth_src_mac, + eth_type=output_1_eth_type, + eth_payload_tdata=output_1_eth_payload_tdata, + eth_payload_tkeep=output_1_eth_payload_tkeep, + eth_payload_tvalid=output_1_eth_payload_tvalid, + eth_payload_tready=output_1_eth_payload_tready, + eth_payload_tlast=output_1_eth_payload_tlast, + eth_payload_tuser=output_1_eth_payload_tuser, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + + sink_2 = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_2_eth_hdr_ready, + eth_hdr_valid=output_2_eth_hdr_valid, + eth_dest_mac=output_2_eth_dest_mac, + eth_src_mac=output_2_eth_src_mac, + eth_type=output_2_eth_type, + eth_payload_tdata=output_2_eth_payload_tdata, + eth_payload_tkeep=output_2_eth_payload_tkeep, + eth_payload_tvalid=output_2_eth_payload_tvalid, + eth_payload_tready=output_2_eth_payload_tready, + eth_payload_tlast=output_2_eth_payload_tlast, + eth_payload_tuser=output_2_eth_payload_tuser, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + + sink_3 = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_3_eth_hdr_ready, + eth_hdr_valid=output_3_eth_hdr_valid, + eth_dest_mac=output_3_eth_dest_mac, + eth_src_mac=output_3_eth_src_mac, + eth_type=output_3_eth_type, + eth_payload_tdata=output_3_eth_payload_tdata, + eth_payload_tkeep=output_3_eth_payload_tkeep, + eth_payload_tvalid=output_3_eth_payload_tvalid, + eth_payload_tready=output_3_eth_payload_tready, + eth_payload_tlast=output_3_eth_payload_tlast, + eth_payload_tuser=output_3_eth_payload_tuser, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_eth_demux_64_4(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_0_eth_hdr_valid, + output_0_eth_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_eth_payload_tdata, + output_0_eth_payload_tkeep, + output_0_eth_payload_tvalid, + output_0_eth_payload_tready, + output_0_eth_payload_tlast, + output_0_eth_payload_tuser, + output_1_eth_hdr_valid, + output_1_eth_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_eth_payload_tdata, + output_1_eth_payload_tkeep, + output_1_eth_payload_tvalid, + output_1_eth_payload_tready, + output_1_eth_payload_tlast, + output_1_eth_payload_tuser, + output_2_eth_hdr_valid, + output_2_eth_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_eth_payload_tdata, + output_2_eth_payload_tkeep, + output_2_eth_payload_tvalid, + output_2_eth_payload_tready, + output_2_eth_payload_tlast, + output_2_eth_payload_tuser, + output_3_eth_hdr_valid, + output_3_eth_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_eth_payload_tdata, + output_3_eth_payload_tkeep, + output_3_eth_payload_tvalid, + output_3_eth_payload_tready, + output_3_eth_payload_tlast, + output_3_eth_payload_tuser, + + enable, + select) + + @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 + enable.next = True + + yield clk.posedge + print("test 1: select port 0") + current_test.next = 1 + + select.next = 0 + + 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(range(32)) + + source_queue.put(test_frame) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.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(range(32)) + + source_queue.put(test_frame) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + 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(range(32)) + 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(range(32)) + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + 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(range(32)) + 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(range(32)) + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_eth_payload_tvalid or input_eth_hdr_valid: + sink_0_pause.next = True + sink_1_pause.next = True + sink_2_pause.next = True + sink_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_0_pause.next = False + sink_1_pause.next = False + sink_2_pause.next = False + sink_3_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + raise StopSimulation + + return dut, source, sink_0, sink_1, sink_2, sink_3, 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() + diff --git a/tb/test_eth_demux_64_4.v b/tb/test_eth_demux_64_4.v new file mode 100644 index 000000000..692f68fef --- /dev/null +++ b/tb/test_eth_demux_64_4.v @@ -0,0 +1,233 @@ +/* + +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_eth_demux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [63:0] input_eth_payload_tdata = 0; +reg [7:0] input_eth_payload_tkeep = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; + +reg output_0_eth_hdr_ready = 0; +reg output_0_eth_payload_tready = 0; +reg output_1_eth_hdr_ready = 0; +reg output_1_eth_payload_tready = 0; +reg output_2_eth_hdr_ready = 0; +reg output_2_eth_payload_tready = 0; +reg output_3_eth_hdr_ready = 0; +reg output_3_eth_payload_tready = 0; + +reg enable = 0; +reg [1:0] select = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; + +wire output_0_eth_hdr_valid; +wire [47:0] output_0_eth_dest_mac; +wire [47:0] output_0_eth_src_mac; +wire [15:0] output_0_eth_type; +wire [63:0] output_0_eth_payload_tdata; +wire [7:0] output_0_eth_payload_tkeep; +wire output_0_eth_payload_tvalid; +wire output_0_eth_payload_tlast; +wire output_0_eth_payload_tuser; +wire output_1_eth_hdr_valid; +wire [47:0] output_1_eth_dest_mac; +wire [47:0] output_1_eth_src_mac; +wire [15:0] output_1_eth_type; +wire [63:0] output_1_eth_payload_tdata; +wire [7:0] output_1_eth_payload_tkeep; +wire output_1_eth_payload_tvalid; +wire output_1_eth_payload_tlast; +wire output_1_eth_payload_tuser; +wire output_2_eth_hdr_valid; +wire [47:0] output_2_eth_dest_mac; +wire [47:0] output_2_eth_src_mac; +wire [15:0] output_2_eth_type; +wire [63:0] output_2_eth_payload_tdata; +wire [7:0] output_2_eth_payload_tkeep; +wire output_2_eth_payload_tvalid; +wire output_2_eth_payload_tlast; +wire output_2_eth_payload_tuser; +wire output_3_eth_hdr_valid; +wire [47:0] output_3_eth_dest_mac; +wire [47:0] output_3_eth_src_mac; +wire [15:0] output_3_eth_type; +wire [63:0] output_3_eth_payload_tdata; +wire [7:0] output_3_eth_payload_tkeep; +wire output_3_eth_payload_tvalid; +wire output_3_eth_payload_tlast; +wire output_3_eth_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_0_eth_hdr_ready, + output_0_eth_payload_tready, + output_1_eth_hdr_ready, + output_1_eth_payload_tready, + output_2_eth_hdr_ready, + output_2_eth_payload_tready, + output_3_eth_hdr_ready, + output_3_eth_payload_tready, + enable, + select); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + output_0_eth_hdr_valid, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_eth_payload_tdata, + output_0_eth_payload_tkeep, + output_0_eth_payload_tvalid, + output_0_eth_payload_tlast, + output_0_eth_payload_tuser, + output_1_eth_hdr_valid, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_eth_payload_tdata, + output_1_eth_payload_tkeep, + output_1_eth_payload_tvalid, + output_1_eth_payload_tlast, + output_1_eth_payload_tuser, + output_2_eth_hdr_valid, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_eth_payload_tdata, + output_2_eth_payload_tkeep, + output_2_eth_payload_tvalid, + output_2_eth_payload_tlast, + output_2_eth_payload_tuser, + output_3_eth_hdr_valid, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_eth_payload_tdata, + output_3_eth_payload_tkeep, + output_3_eth_payload_tvalid, + output_3_eth_payload_tlast, + output_3_eth_payload_tuser); + + // dump file + $dumpfile("test_eth_demux_64_4.lxt"); + $dumpvars(0, test_eth_demux_64_4); +end + +eth_demux_64_4 +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame outputs + .output_0_eth_hdr_valid(output_0_eth_hdr_valid), + .output_0_eth_hdr_ready(output_0_eth_hdr_ready), + .output_0_eth_dest_mac(output_0_eth_dest_mac), + .output_0_eth_src_mac(output_0_eth_src_mac), + .output_0_eth_type(output_0_eth_type), + .output_0_eth_payload_tdata(output_0_eth_payload_tdata), + .output_0_eth_payload_tkeep(output_0_eth_payload_tkeep), + .output_0_eth_payload_tvalid(output_0_eth_payload_tvalid), + .output_0_eth_payload_tready(output_0_eth_payload_tready), + .output_0_eth_payload_tlast(output_0_eth_payload_tlast), + .output_0_eth_payload_tuser(output_0_eth_payload_tuser), + .output_1_eth_hdr_valid(output_1_eth_hdr_valid), + .output_1_eth_hdr_ready(output_1_eth_hdr_ready), + .output_1_eth_dest_mac(output_1_eth_dest_mac), + .output_1_eth_src_mac(output_1_eth_src_mac), + .output_1_eth_type(output_1_eth_type), + .output_1_eth_payload_tdata(output_1_eth_payload_tdata), + .output_1_eth_payload_tkeep(output_1_eth_payload_tkeep), + .output_1_eth_payload_tvalid(output_1_eth_payload_tvalid), + .output_1_eth_payload_tready(output_1_eth_payload_tready), + .output_1_eth_payload_tlast(output_1_eth_payload_tlast), + .output_1_eth_payload_tuser(output_1_eth_payload_tuser), + .output_2_eth_hdr_valid(output_2_eth_hdr_valid), + .output_2_eth_hdr_ready(output_2_eth_hdr_ready), + .output_2_eth_dest_mac(output_2_eth_dest_mac), + .output_2_eth_src_mac(output_2_eth_src_mac), + .output_2_eth_type(output_2_eth_type), + .output_2_eth_payload_tdata(output_2_eth_payload_tdata), + .output_2_eth_payload_tkeep(output_2_eth_payload_tkeep), + .output_2_eth_payload_tvalid(output_2_eth_payload_tvalid), + .output_2_eth_payload_tready(output_2_eth_payload_tready), + .output_2_eth_payload_tlast(output_2_eth_payload_tlast), + .output_2_eth_payload_tuser(output_2_eth_payload_tuser), + .output_3_eth_hdr_valid(output_3_eth_hdr_valid), + .output_3_eth_hdr_ready(output_3_eth_hdr_ready), + .output_3_eth_dest_mac(output_3_eth_dest_mac), + .output_3_eth_src_mac(output_3_eth_src_mac), + .output_3_eth_type(output_3_eth_type), + .output_3_eth_payload_tdata(output_3_eth_payload_tdata), + .output_3_eth_payload_tkeep(output_3_eth_payload_tkeep), + .output_3_eth_payload_tvalid(output_3_eth_payload_tvalid), + .output_3_eth_payload_tready(output_3_eth_payload_tready), + .output_3_eth_payload_tlast(output_3_eth_payload_tlast), + .output_3_eth_payload_tuser(output_3_eth_payload_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule From f6fcec08f3fd4dcdb5a04e28997d7e0f8dbb380d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 18 Nov 2014 11:27:34 -0800 Subject: [PATCH 108/617] Add IP mux module and testbench --- rtl/ip_mux.py | 503 ++++++++++++++++++ rtl/ip_mux_4.v | 581 ++++++++++++++++++++ rtl/ip_mux_64.py | 518 ++++++++++++++++++ rtl/ip_mux_64_4.v | 602 +++++++++++++++++++++ tb/test_ip_mux_4.py | 1118 +++++++++++++++++++++++++++++++++++++++ tb/test_ip_mux_4.v | 413 +++++++++++++++ tb/test_ip_mux_64_4.py | 1143 ++++++++++++++++++++++++++++++++++++++++ tb/test_ip_mux_64_4.v | 428 +++++++++++++++ 8 files changed, 5306 insertions(+) create mode 100755 rtl/ip_mux.py create mode 100644 rtl/ip_mux_4.v create mode 100755 rtl/ip_mux_64.py create mode 100644 rtl/ip_mux_64_4.v create mode 100755 tb/test_ip_mux_4.py create mode 100644 tb/test_ip_mux_4.v create mode 100755 tb/test_ip_mux_64_4.py create mode 100644 tb/test_ip_mux_64_4.v diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py new file mode 100755 index 000000000..c5f3e833e --- /dev/null +++ b/rtl/ip_mux.py @@ -0,0 +1,503 @@ +#!/usr/bin/env python +"""ip_mux + +Generates an IP mux with the specified number of ports + +Usage: ip_mux [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "ip_mux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port IP mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * IP {{n}} port multiplexer + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_ip_hdr_valid, + output wire input_{{p}}_ip_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [3:0] input_{{p}}_ip_version, + input wire [3:0] input_{{p}}_ip_ihl, + input wire [5:0] input_{{p}}_ip_dscp, + input wire [1:0] input_{{p}}_ip_ecn, + input wire [15:0] input_{{p}}_ip_length, + input wire [15:0] input_{{p}}_ip_identification, + input wire [2:0] input_{{p}}_ip_flags, + input wire [12:0] input_{{p}}_ip_fragment_offset, + input wire [7:0] input_{{p}}_ip_ttl, + input wire [7:0] input_{{p}}_ip_protocol, + input wire [15:0] input_{{p}}_ip_header_checksum, + input wire [31:0] input_{{p}}_ip_source_ip, + input wire [31:0] input_{{p}}_ip_dest_ip, + input wire [7:0] input_{{p}}_ip_payload_tdata, + input wire input_{{p}}_ip_payload_tvalid, + output wire input_{{p}}_ip_payload_tready, + input wire input_{{p}}_ip_payload_tlast, + input wire input_{{p}}_ip_payload_tuser, +{% endfor %} + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; +{% for p in ports %} +reg input_{{p}}_ip_hdr_ready_reg = 0, input_{{p}}_ip_hdr_ready_next; +{%- endfor %} +{% for p in ports %} +reg input_{{p}}_ip_payload_tready_reg = 0, input_{{p}}_ip_payload_tready_next; +{%- endfor %} + +reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; + +// internal datapath +reg [7:0] output_ip_payload_tdata_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; +{% for p in ports %} +assign input_{{p}}_ip_hdr_ready = input_{{p}}_ip_hdr_ready_reg; +{%- endfor %} +{% for p in ports %} +assign input_{{p}}_ip_payload_tready = input_{{p}}_ip_payload_tready_reg; +{%- endfor %} + +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; + +// mux for start of packet detection +reg selected_input_ip_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +reg [3:0] selected_input_ip_version; +reg [3:0] selected_input_ip_ihl; +reg [5:0] selected_input_ip_dscp; +reg [1:0] selected_input_ip_ecn; +reg [15:0] selected_input_ip_length; +reg [15:0] selected_input_ip_identification; +reg [2:0] selected_input_ip_flags; +reg [12:0] selected_input_ip_fragment_offset; +reg [7:0] selected_input_ip_ttl; +reg [7:0] selected_input_ip_protocol; +reg [15:0] selected_input_ip_header_checksum; +reg [31:0] selected_input_ip_source_ip; +reg [31:0] selected_input_ip_dest_ip; +always @* begin + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: begin + selected_input_ip_hdr_valid = input_{{p}}_ip_hdr_valid; + selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; + selected_input_eth_src_mac = input_{{p}}_eth_src_mac; + selected_input_eth_type = input_{{p}}_eth_type; + selected_input_ip_version = input_{{p}}_ip_version; + selected_input_ip_ihl = input_{{p}}_ip_ihl; + selected_input_ip_dscp = input_{{p}}_ip_dscp; + selected_input_ip_ecn = input_{{p}}_ip_ecn; + selected_input_ip_length = input_{{p}}_ip_length; + selected_input_ip_identification = input_{{p}}_ip_identification; + selected_input_ip_flags = input_{{p}}_ip_flags; + selected_input_ip_fragment_offset = input_{{p}}_ip_fragment_offset; + selected_input_ip_ttl = input_{{p}}_ip_ttl; + selected_input_ip_protocol = input_{{p}}_ip_protocol; + selected_input_ip_header_checksum = input_{{p}}_ip_header_checksum; + selected_input_ip_source_ip = input_{{p}}_ip_source_ip; + selected_input_ip_dest_ip = input_{{p}}_ip_dest_ip; + end +{%- endfor %} + endcase +end + +// mux for incoming packet +reg [7:0] current_input_tdata; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_input_tdata = input_{{p}}_ip_payload_tdata; + current_input_tvalid = input_{{p}}_ip_payload_tvalid; + current_input_tready = input_{{p}}_ip_payload_tready; + current_input_tlast = input_{{p}}_ip_payload_tlast; + current_input_tuser = input_{{p}}_ip_payload_tuser; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; +{% for p in ports %} + input_{{p}}_ip_hdr_ready_next = input_{{p}}_ip_hdr_ready_reg & ~input_{{p}}_ip_hdr_valid; +{%- endfor %} +{% for p in ports %} + input_{{p}}_ip_payload_tready_next = 0; +{%- endfor %} + + output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_ip_hdr_ready_next = 1; +{%- endfor %} + endcase + + output_ip_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + output_ip_version_next = selected_input_ip_version; + output_ip_ihl_next = selected_input_ip_ihl; + output_ip_dscp_next = selected_input_ip_dscp; + output_ip_ecn_next = selected_input_ip_ecn; + output_ip_length_next = selected_input_ip_length; + output_ip_identification_next = selected_input_ip_identification; + output_ip_flags_next = selected_input_ip_flags; + output_ip_fragment_offset_next = selected_input_ip_fragment_offset; + output_ip_ttl_next = selected_input_ip_ttl; + output_ip_protocol_next = selected_input_ip_protocol; + output_ip_header_checksum_next = selected_input_ip_header_checksum; + output_ip_source_ip_next = selected_input_ip_source_ip; + output_ip_dest_ip_next = selected_input_ip_dest_ip; + end + + // generate ready signal on selected port + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; +{%- endfor %} + endcase + + // pass through selected packet data + output_ip_payload_tdata_int = current_input_tdata; + output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_ip_payload_tlast_int = current_input_tlast; + output_ip_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; +{%- for p in ports %} + input_{{p}}_ip_hdr_ready_reg <= 0; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_ip_payload_tready_reg <= 0; +{%- endfor %} + output_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; +{%- for p in ports %} + input_{{p}}_ip_hdr_ready_reg <= input_{{p}}_ip_hdr_ready_next; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_ip_payload_tready_reg <= input_{{p}}_ip_payload_tready_next; +{%- endfor %} + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + end +end + +// output datapath logic +reg [7:0] output_ip_payload_tdata_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [7:0] temp_ip_payload_tdata_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/ip_mux_4.v b/rtl/ip_mux_4.v new file mode 100644 index 000000000..ed25252da --- /dev/null +++ b/rtl/ip_mux_4.v @@ -0,0 +1,581 @@ +/* + +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 + +/* + * IP 4 port multiplexer + */ +module ip_mux_4 +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ + input wire input_0_ip_hdr_valid, + output wire input_0_ip_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [7:0] input_0_ip_payload_tdata, + input wire input_0_ip_payload_tvalid, + output wire input_0_ip_payload_tready, + input wire input_0_ip_payload_tlast, + input wire input_0_ip_payload_tuser, + + input wire input_1_ip_hdr_valid, + output wire input_1_ip_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [7:0] input_1_ip_payload_tdata, + input wire input_1_ip_payload_tvalid, + output wire input_1_ip_payload_tready, + input wire input_1_ip_payload_tlast, + input wire input_1_ip_payload_tuser, + + input wire input_2_ip_hdr_valid, + output wire input_2_ip_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [3:0] input_2_ip_version, + input wire [3:0] input_2_ip_ihl, + input wire [5:0] input_2_ip_dscp, + input wire [1:0] input_2_ip_ecn, + input wire [15:0] input_2_ip_length, + input wire [15:0] input_2_ip_identification, + input wire [2:0] input_2_ip_flags, + input wire [12:0] input_2_ip_fragment_offset, + input wire [7:0] input_2_ip_ttl, + input wire [7:0] input_2_ip_protocol, + input wire [15:0] input_2_ip_header_checksum, + input wire [31:0] input_2_ip_source_ip, + input wire [31:0] input_2_ip_dest_ip, + input wire [7:0] input_2_ip_payload_tdata, + input wire input_2_ip_payload_tvalid, + output wire input_2_ip_payload_tready, + input wire input_2_ip_payload_tlast, + input wire input_2_ip_payload_tuser, + + input wire input_3_ip_hdr_valid, + output wire input_3_ip_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [3:0] input_3_ip_version, + input wire [3:0] input_3_ip_ihl, + input wire [5:0] input_3_ip_dscp, + input wire [1:0] input_3_ip_ecn, + input wire [15:0] input_3_ip_length, + input wire [15:0] input_3_ip_identification, + input wire [2:0] input_3_ip_flags, + input wire [12:0] input_3_ip_fragment_offset, + input wire [7:0] input_3_ip_ttl, + input wire [7:0] input_3_ip_protocol, + input wire [15:0] input_3_ip_header_checksum, + input wire [31:0] input_3_ip_source_ip, + input wire [31:0] input_3_ip_dest_ip, + input wire [7:0] input_3_ip_payload_tdata, + input wire input_3_ip_payload_tvalid, + output wire input_3_ip_payload_tready, + input wire input_3_ip_payload_tlast, + input wire input_3_ip_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_ip_hdr_ready_reg = 0, input_0_ip_hdr_ready_next; +reg input_1_ip_hdr_ready_reg = 0, input_1_ip_hdr_ready_next; +reg input_2_ip_hdr_ready_reg = 0, input_2_ip_hdr_ready_next; +reg input_3_ip_hdr_ready_reg = 0, input_3_ip_hdr_ready_next; + +reg input_0_ip_payload_tready_reg = 0, input_0_ip_payload_tready_next; +reg input_1_ip_payload_tready_reg = 0, input_1_ip_payload_tready_next; +reg input_2_ip_payload_tready_reg = 0, input_2_ip_payload_tready_next; +reg input_3_ip_payload_tready_reg = 0, input_3_ip_payload_tready_next; + +reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; + +// internal datapath +reg [7:0] output_ip_payload_tdata_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; + +assign input_0_ip_hdr_ready = input_0_ip_hdr_ready_reg; +assign input_1_ip_hdr_ready = input_1_ip_hdr_ready_reg; +assign input_2_ip_hdr_ready = input_2_ip_hdr_ready_reg; +assign input_3_ip_hdr_ready = input_3_ip_hdr_ready_reg; + +assign input_0_ip_payload_tready = input_0_ip_payload_tready_reg; +assign input_1_ip_payload_tready = input_1_ip_payload_tready_reg; +assign input_2_ip_payload_tready = input_2_ip_payload_tready_reg; +assign input_3_ip_payload_tready = input_3_ip_payload_tready_reg; + +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; + +// mux for start of packet detection +reg selected_input_ip_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +reg [3:0] selected_input_ip_version; +reg [3:0] selected_input_ip_ihl; +reg [5:0] selected_input_ip_dscp; +reg [1:0] selected_input_ip_ecn; +reg [15:0] selected_input_ip_length; +reg [15:0] selected_input_ip_identification; +reg [2:0] selected_input_ip_flags; +reg [12:0] selected_input_ip_fragment_offset; +reg [7:0] selected_input_ip_ttl; +reg [7:0] selected_input_ip_protocol; +reg [15:0] selected_input_ip_header_checksum; +reg [31:0] selected_input_ip_source_ip; +reg [31:0] selected_input_ip_dest_ip; +always @* begin + case (select) + 2'd0: begin + selected_input_ip_hdr_valid = input_0_ip_hdr_valid; + selected_input_eth_dest_mac = input_0_eth_dest_mac; + selected_input_eth_src_mac = input_0_eth_src_mac; + selected_input_eth_type = input_0_eth_type; + selected_input_ip_version = input_0_ip_version; + selected_input_ip_ihl = input_0_ip_ihl; + selected_input_ip_dscp = input_0_ip_dscp; + selected_input_ip_ecn = input_0_ip_ecn; + selected_input_ip_length = input_0_ip_length; + selected_input_ip_identification = input_0_ip_identification; + selected_input_ip_flags = input_0_ip_flags; + selected_input_ip_fragment_offset = input_0_ip_fragment_offset; + selected_input_ip_ttl = input_0_ip_ttl; + selected_input_ip_protocol = input_0_ip_protocol; + selected_input_ip_header_checksum = input_0_ip_header_checksum; + selected_input_ip_source_ip = input_0_ip_source_ip; + selected_input_ip_dest_ip = input_0_ip_dest_ip; + end + 2'd1: begin + selected_input_ip_hdr_valid = input_1_ip_hdr_valid; + selected_input_eth_dest_mac = input_1_eth_dest_mac; + selected_input_eth_src_mac = input_1_eth_src_mac; + selected_input_eth_type = input_1_eth_type; + selected_input_ip_version = input_1_ip_version; + selected_input_ip_ihl = input_1_ip_ihl; + selected_input_ip_dscp = input_1_ip_dscp; + selected_input_ip_ecn = input_1_ip_ecn; + selected_input_ip_length = input_1_ip_length; + selected_input_ip_identification = input_1_ip_identification; + selected_input_ip_flags = input_1_ip_flags; + selected_input_ip_fragment_offset = input_1_ip_fragment_offset; + selected_input_ip_ttl = input_1_ip_ttl; + selected_input_ip_protocol = input_1_ip_protocol; + selected_input_ip_header_checksum = input_1_ip_header_checksum; + selected_input_ip_source_ip = input_1_ip_source_ip; + selected_input_ip_dest_ip = input_1_ip_dest_ip; + end + 2'd2: begin + selected_input_ip_hdr_valid = input_2_ip_hdr_valid; + selected_input_eth_dest_mac = input_2_eth_dest_mac; + selected_input_eth_src_mac = input_2_eth_src_mac; + selected_input_eth_type = input_2_eth_type; + selected_input_ip_version = input_2_ip_version; + selected_input_ip_ihl = input_2_ip_ihl; + selected_input_ip_dscp = input_2_ip_dscp; + selected_input_ip_ecn = input_2_ip_ecn; + selected_input_ip_length = input_2_ip_length; + selected_input_ip_identification = input_2_ip_identification; + selected_input_ip_flags = input_2_ip_flags; + selected_input_ip_fragment_offset = input_2_ip_fragment_offset; + selected_input_ip_ttl = input_2_ip_ttl; + selected_input_ip_protocol = input_2_ip_protocol; + selected_input_ip_header_checksum = input_2_ip_header_checksum; + selected_input_ip_source_ip = input_2_ip_source_ip; + selected_input_ip_dest_ip = input_2_ip_dest_ip; + end + 2'd3: begin + selected_input_ip_hdr_valid = input_3_ip_hdr_valid; + selected_input_eth_dest_mac = input_3_eth_dest_mac; + selected_input_eth_src_mac = input_3_eth_src_mac; + selected_input_eth_type = input_3_eth_type; + selected_input_ip_version = input_3_ip_version; + selected_input_ip_ihl = input_3_ip_ihl; + selected_input_ip_dscp = input_3_ip_dscp; + selected_input_ip_ecn = input_3_ip_ecn; + selected_input_ip_length = input_3_ip_length; + selected_input_ip_identification = input_3_ip_identification; + selected_input_ip_flags = input_3_ip_flags; + selected_input_ip_fragment_offset = input_3_ip_fragment_offset; + selected_input_ip_ttl = input_3_ip_ttl; + selected_input_ip_protocol = input_3_ip_protocol; + selected_input_ip_header_checksum = input_3_ip_header_checksum; + selected_input_ip_source_ip = input_3_ip_source_ip; + selected_input_ip_dest_ip = input_3_ip_dest_ip; + end + endcase +end + +// mux for incoming packet +reg [7:0] current_input_tdata; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 2'd0: begin + current_input_tdata = input_0_ip_payload_tdata; + current_input_tvalid = input_0_ip_payload_tvalid; + current_input_tready = input_0_ip_payload_tready; + current_input_tlast = input_0_ip_payload_tlast; + current_input_tuser = input_0_ip_payload_tuser; + end + 2'd1: begin + current_input_tdata = input_1_ip_payload_tdata; + current_input_tvalid = input_1_ip_payload_tvalid; + current_input_tready = input_1_ip_payload_tready; + current_input_tlast = input_1_ip_payload_tlast; + current_input_tuser = input_1_ip_payload_tuser; + end + 2'd2: begin + current_input_tdata = input_2_ip_payload_tdata; + current_input_tvalid = input_2_ip_payload_tvalid; + current_input_tready = input_2_ip_payload_tready; + current_input_tlast = input_2_ip_payload_tlast; + current_input_tuser = input_2_ip_payload_tuser; + end + 2'd3: begin + current_input_tdata = input_3_ip_payload_tdata; + current_input_tvalid = input_3_ip_payload_tvalid; + current_input_tready = input_3_ip_payload_tready; + current_input_tlast = input_3_ip_payload_tlast; + current_input_tuser = input_3_ip_payload_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_ip_hdr_ready_next = input_0_ip_hdr_ready_reg & ~input_0_ip_hdr_valid; + input_1_ip_hdr_ready_next = input_1_ip_hdr_ready_reg & ~input_1_ip_hdr_valid; + input_2_ip_hdr_ready_next = input_2_ip_hdr_ready_reg & ~input_2_ip_hdr_valid; + input_3_ip_hdr_ready_next = input_3_ip_hdr_ready_reg & ~input_3_ip_hdr_valid; + + input_0_ip_payload_tready_next = 0; + input_1_ip_payload_tready_next = 0; + input_2_ip_payload_tready_next = 0; + input_3_ip_payload_tready_next = 0; + + output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) + 2'd0: input_0_ip_hdr_ready_next = 1; + 2'd1: input_1_ip_hdr_ready_next = 1; + 2'd2: input_2_ip_hdr_ready_next = 1; + 2'd3: input_3_ip_hdr_ready_next = 1; + endcase + + output_ip_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + output_ip_version_next = selected_input_ip_version; + output_ip_ihl_next = selected_input_ip_ihl; + output_ip_dscp_next = selected_input_ip_dscp; + output_ip_ecn_next = selected_input_ip_ecn; + output_ip_length_next = selected_input_ip_length; + output_ip_identification_next = selected_input_ip_identification; + output_ip_flags_next = selected_input_ip_flags; + output_ip_fragment_offset_next = selected_input_ip_fragment_offset; + output_ip_ttl_next = selected_input_ip_ttl; + output_ip_protocol_next = selected_input_ip_protocol; + output_ip_header_checksum_next = selected_input_ip_header_checksum; + output_ip_source_ip_next = selected_input_ip_source_ip; + output_ip_dest_ip_next = selected_input_ip_dest_ip; + end + + // generate ready signal on selected port + case (select_next) + 2'd0: input_0_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + 2'd1: input_1_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + 2'd2: input_2_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + 2'd3: input_3_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + endcase + + // pass through selected packet data + output_ip_payload_tdata_int = current_input_tdata; + output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_ip_payload_tlast_int = current_input_tlast; + output_ip_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_ip_hdr_ready_reg <= 0; + input_1_ip_hdr_ready_reg <= 0; + input_2_ip_hdr_ready_reg <= 0; + input_3_ip_hdr_ready_reg <= 0; + input_0_ip_payload_tready_reg <= 0; + input_1_ip_payload_tready_reg <= 0; + input_2_ip_payload_tready_reg <= 0; + input_3_ip_payload_tready_reg <= 0; + output_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_ip_hdr_ready_reg <= input_0_ip_hdr_ready_next; + input_1_ip_hdr_ready_reg <= input_1_ip_hdr_ready_next; + input_2_ip_hdr_ready_reg <= input_2_ip_hdr_ready_next; + input_3_ip_hdr_ready_reg <= input_3_ip_hdr_ready_next; + input_0_ip_payload_tready_reg <= input_0_ip_payload_tready_next; + input_1_ip_payload_tready_reg <= input_1_ip_payload_tready_next; + input_2_ip_payload_tready_reg <= input_2_ip_payload_tready_next; + input_3_ip_payload_tready_reg <= input_3_ip_payload_tready_next; + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + end +end + +// output datapath logic +reg [7:0] output_ip_payload_tdata_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [7:0] temp_ip_payload_tdata_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py new file mode 100755 index 000000000..4b45b71c1 --- /dev/null +++ b/rtl/ip_mux_64.py @@ -0,0 +1,518 @@ +#!/usr/bin/env python +"""ip_mux_64 + +Generates an IP mux with the specified number of ports + +Usage: ip_mux_64 [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "ip_mux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port IP mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * IP {{n}} port multiplexer (64 bit datapath) + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_ip_hdr_valid, + output wire input_{{p}}_ip_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [3:0] input_{{p}}_ip_version, + input wire [3:0] input_{{p}}_ip_ihl, + input wire [5:0] input_{{p}}_ip_dscp, + input wire [1:0] input_{{p}}_ip_ecn, + input wire [15:0] input_{{p}}_ip_length, + input wire [15:0] input_{{p}}_ip_identification, + input wire [2:0] input_{{p}}_ip_flags, + input wire [12:0] input_{{p}}_ip_fragment_offset, + input wire [7:0] input_{{p}}_ip_ttl, + input wire [7:0] input_{{p}}_ip_protocol, + input wire [15:0] input_{{p}}_ip_header_checksum, + input wire [31:0] input_{{p}}_ip_source_ip, + input wire [31:0] input_{{p}}_ip_dest_ip, + input wire [63:0] input_{{p}}_ip_payload_tdata, + input wire [7:0] input_{{p}}_ip_payload_tkeep, + input wire input_{{p}}_ip_payload_tvalid, + output wire input_{{p}}_ip_payload_tready, + input wire input_{{p}}_ip_payload_tlast, + input wire input_{{p}}_ip_payload_tuser, +{% endfor %} + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; +{% for p in ports %} +reg input_{{p}}_ip_hdr_ready_reg = 0, input_{{p}}_ip_hdr_ready_next; +{%- endfor %} +{% for p in ports %} +reg input_{{p}}_ip_payload_tready_reg = 0, input_{{p}}_ip_payload_tready_next; +{%- endfor %} + +reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; + +// internal datapath +reg [63:0] output_ip_payload_tdata_int; +reg [7:0] output_ip_payload_tkeep_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; +{% for p in ports %} +assign input_{{p}}_ip_hdr_ready = input_{{p}}_ip_hdr_ready_reg; +{%- endfor %} +{% for p in ports %} +assign input_{{p}}_ip_payload_tready = input_{{p}}_ip_payload_tready_reg; +{%- endfor %} + +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; + +// mux for start of packet detection +reg selected_input_ip_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +reg [3:0] selected_input_ip_version; +reg [3:0] selected_input_ip_ihl; +reg [5:0] selected_input_ip_dscp; +reg [1:0] selected_input_ip_ecn; +reg [15:0] selected_input_ip_length; +reg [15:0] selected_input_ip_identification; +reg [2:0] selected_input_ip_flags; +reg [12:0] selected_input_ip_fragment_offset; +reg [7:0] selected_input_ip_ttl; +reg [7:0] selected_input_ip_protocol; +reg [15:0] selected_input_ip_header_checksum; +reg [31:0] selected_input_ip_source_ip; +reg [31:0] selected_input_ip_dest_ip; +always @* begin + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: begin + selected_input_ip_hdr_valid = input_{{p}}_ip_hdr_valid; + selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; + selected_input_eth_src_mac = input_{{p}}_eth_src_mac; + selected_input_eth_type = input_{{p}}_eth_type; + selected_input_ip_version = input_{{p}}_ip_version; + selected_input_ip_ihl = input_{{p}}_ip_ihl; + selected_input_ip_dscp = input_{{p}}_ip_dscp; + selected_input_ip_ecn = input_{{p}}_ip_ecn; + selected_input_ip_length = input_{{p}}_ip_length; + selected_input_ip_identification = input_{{p}}_ip_identification; + selected_input_ip_flags = input_{{p}}_ip_flags; + selected_input_ip_fragment_offset = input_{{p}}_ip_fragment_offset; + selected_input_ip_ttl = input_{{p}}_ip_ttl; + selected_input_ip_protocol = input_{{p}}_ip_protocol; + selected_input_ip_header_checksum = input_{{p}}_ip_header_checksum; + selected_input_ip_source_ip = input_{{p}}_ip_source_ip; + selected_input_ip_dest_ip = input_{{p}}_ip_dest_ip; + end +{%- endfor %} + endcase +end + +// mux for incoming packet +reg [63:0] current_input_tdata; +reg [7:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_input_tdata = input_{{p}}_ip_payload_tdata; + current_input_tkeep = input_{{p}}_ip_payload_tkeep; + current_input_tvalid = input_{{p}}_ip_payload_tvalid; + current_input_tready = input_{{p}}_ip_payload_tready; + current_input_tlast = input_{{p}}_ip_payload_tlast; + current_input_tuser = input_{{p}}_ip_payload_tuser; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; +{% for p in ports %} + input_{{p}}_ip_hdr_ready_next = input_{{p}}_ip_hdr_ready_reg & ~input_{{p}}_ip_hdr_valid; +{%- endfor %} +{% for p in ports %} + input_{{p}}_ip_payload_tready_next = 0; +{%- endfor %} + + output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_ip_hdr_ready_next = 1; +{%- endfor %} + endcase + + output_ip_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + output_ip_version_next = selected_input_ip_version; + output_ip_ihl_next = selected_input_ip_ihl; + output_ip_dscp_next = selected_input_ip_dscp; + output_ip_ecn_next = selected_input_ip_ecn; + output_ip_length_next = selected_input_ip_length; + output_ip_identification_next = selected_input_ip_identification; + output_ip_flags_next = selected_input_ip_flags; + output_ip_fragment_offset_next = selected_input_ip_fragment_offset; + output_ip_ttl_next = selected_input_ip_ttl; + output_ip_protocol_next = selected_input_ip_protocol; + output_ip_header_checksum_next = selected_input_ip_header_checksum; + output_ip_source_ip_next = selected_input_ip_source_ip; + output_ip_dest_ip_next = selected_input_ip_dest_ip; + end + + // generate ready signal on selected port + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; +{%- endfor %} + endcase + + // pass through selected packet data + output_ip_payload_tdata_int = current_input_tdata; + output_ip_payload_tkeep_int = current_input_tkeep; + output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_ip_payload_tlast_int = current_input_tlast; + output_ip_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; +{%- for p in ports %} + input_{{p}}_ip_hdr_ready_reg <= 0; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_ip_payload_tready_reg <= 0; +{%- endfor %} + output_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; +{%- for p in ports %} + input_{{p}}_ip_hdr_ready_reg <= input_{{p}}_ip_hdr_ready_next; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_ip_payload_tready_reg <= input_{{p}}_ip_payload_tready_next; +{%- endfor %} + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + end +end + +// output datapath logic +reg [63:0] output_ip_payload_tdata_reg = 0; +reg [7:0] output_ip_payload_tkeep_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [63:0] temp_ip_payload_tdata_reg = 0; +reg [7:0] temp_ip_payload_tkeep_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tkeep_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/ip_mux_64_4.v b/rtl/ip_mux_64_4.v new file mode 100644 index 000000000..d5b2dda77 --- /dev/null +++ b/rtl/ip_mux_64_4.v @@ -0,0 +1,602 @@ +/* + +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 + +/* + * IP 4 port multiplexer (64 bit datapath) + */ +module ip_mux_64_4 +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ + input wire input_0_ip_hdr_valid, + output wire input_0_ip_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [63:0] input_0_ip_payload_tdata, + input wire [7:0] input_0_ip_payload_tkeep, + input wire input_0_ip_payload_tvalid, + output wire input_0_ip_payload_tready, + input wire input_0_ip_payload_tlast, + input wire input_0_ip_payload_tuser, + + input wire input_1_ip_hdr_valid, + output wire input_1_ip_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [63:0] input_1_ip_payload_tdata, + input wire [7:0] input_1_ip_payload_tkeep, + input wire input_1_ip_payload_tvalid, + output wire input_1_ip_payload_tready, + input wire input_1_ip_payload_tlast, + input wire input_1_ip_payload_tuser, + + input wire input_2_ip_hdr_valid, + output wire input_2_ip_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [3:0] input_2_ip_version, + input wire [3:0] input_2_ip_ihl, + input wire [5:0] input_2_ip_dscp, + input wire [1:0] input_2_ip_ecn, + input wire [15:0] input_2_ip_length, + input wire [15:0] input_2_ip_identification, + input wire [2:0] input_2_ip_flags, + input wire [12:0] input_2_ip_fragment_offset, + input wire [7:0] input_2_ip_ttl, + input wire [7:0] input_2_ip_protocol, + input wire [15:0] input_2_ip_header_checksum, + input wire [31:0] input_2_ip_source_ip, + input wire [31:0] input_2_ip_dest_ip, + input wire [63:0] input_2_ip_payload_tdata, + input wire [7:0] input_2_ip_payload_tkeep, + input wire input_2_ip_payload_tvalid, + output wire input_2_ip_payload_tready, + input wire input_2_ip_payload_tlast, + input wire input_2_ip_payload_tuser, + + input wire input_3_ip_hdr_valid, + output wire input_3_ip_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [3:0] input_3_ip_version, + input wire [3:0] input_3_ip_ihl, + input wire [5:0] input_3_ip_dscp, + input wire [1:0] input_3_ip_ecn, + input wire [15:0] input_3_ip_length, + input wire [15:0] input_3_ip_identification, + input wire [2:0] input_3_ip_flags, + input wire [12:0] input_3_ip_fragment_offset, + input wire [7:0] input_3_ip_ttl, + input wire [7:0] input_3_ip_protocol, + input wire [15:0] input_3_ip_header_checksum, + input wire [31:0] input_3_ip_source_ip, + input wire [31:0] input_3_ip_dest_ip, + input wire [63:0] input_3_ip_payload_tdata, + input wire [7:0] input_3_ip_payload_tkeep, + input wire input_3_ip_payload_tvalid, + output wire input_3_ip_payload_tready, + input wire input_3_ip_payload_tlast, + input wire input_3_ip_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_ip_hdr_ready_reg = 0, input_0_ip_hdr_ready_next; +reg input_1_ip_hdr_ready_reg = 0, input_1_ip_hdr_ready_next; +reg input_2_ip_hdr_ready_reg = 0, input_2_ip_hdr_ready_next; +reg input_3_ip_hdr_ready_reg = 0, input_3_ip_hdr_ready_next; + +reg input_0_ip_payload_tready_reg = 0, input_0_ip_payload_tready_next; +reg input_1_ip_payload_tready_reg = 0, input_1_ip_payload_tready_next; +reg input_2_ip_payload_tready_reg = 0, input_2_ip_payload_tready_next; +reg input_3_ip_payload_tready_reg = 0, input_3_ip_payload_tready_next; + +reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; + +// internal datapath +reg [63:0] output_ip_payload_tdata_int; +reg [7:0] output_ip_payload_tkeep_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; + +assign input_0_ip_hdr_ready = input_0_ip_hdr_ready_reg; +assign input_1_ip_hdr_ready = input_1_ip_hdr_ready_reg; +assign input_2_ip_hdr_ready = input_2_ip_hdr_ready_reg; +assign input_3_ip_hdr_ready = input_3_ip_hdr_ready_reg; + +assign input_0_ip_payload_tready = input_0_ip_payload_tready_reg; +assign input_1_ip_payload_tready = input_1_ip_payload_tready_reg; +assign input_2_ip_payload_tready = input_2_ip_payload_tready_reg; +assign input_3_ip_payload_tready = input_3_ip_payload_tready_reg; + +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; + +// mux for start of packet detection +reg selected_input_ip_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +reg [3:0] selected_input_ip_version; +reg [3:0] selected_input_ip_ihl; +reg [5:0] selected_input_ip_dscp; +reg [1:0] selected_input_ip_ecn; +reg [15:0] selected_input_ip_length; +reg [15:0] selected_input_ip_identification; +reg [2:0] selected_input_ip_flags; +reg [12:0] selected_input_ip_fragment_offset; +reg [7:0] selected_input_ip_ttl; +reg [7:0] selected_input_ip_protocol; +reg [15:0] selected_input_ip_header_checksum; +reg [31:0] selected_input_ip_source_ip; +reg [31:0] selected_input_ip_dest_ip; +always @* begin + case (select) + 2'd0: begin + selected_input_ip_hdr_valid = input_0_ip_hdr_valid; + selected_input_eth_dest_mac = input_0_eth_dest_mac; + selected_input_eth_src_mac = input_0_eth_src_mac; + selected_input_eth_type = input_0_eth_type; + selected_input_ip_version = input_0_ip_version; + selected_input_ip_ihl = input_0_ip_ihl; + selected_input_ip_dscp = input_0_ip_dscp; + selected_input_ip_ecn = input_0_ip_ecn; + selected_input_ip_length = input_0_ip_length; + selected_input_ip_identification = input_0_ip_identification; + selected_input_ip_flags = input_0_ip_flags; + selected_input_ip_fragment_offset = input_0_ip_fragment_offset; + selected_input_ip_ttl = input_0_ip_ttl; + selected_input_ip_protocol = input_0_ip_protocol; + selected_input_ip_header_checksum = input_0_ip_header_checksum; + selected_input_ip_source_ip = input_0_ip_source_ip; + selected_input_ip_dest_ip = input_0_ip_dest_ip; + end + 2'd1: begin + selected_input_ip_hdr_valid = input_1_ip_hdr_valid; + selected_input_eth_dest_mac = input_1_eth_dest_mac; + selected_input_eth_src_mac = input_1_eth_src_mac; + selected_input_eth_type = input_1_eth_type; + selected_input_ip_version = input_1_ip_version; + selected_input_ip_ihl = input_1_ip_ihl; + selected_input_ip_dscp = input_1_ip_dscp; + selected_input_ip_ecn = input_1_ip_ecn; + selected_input_ip_length = input_1_ip_length; + selected_input_ip_identification = input_1_ip_identification; + selected_input_ip_flags = input_1_ip_flags; + selected_input_ip_fragment_offset = input_1_ip_fragment_offset; + selected_input_ip_ttl = input_1_ip_ttl; + selected_input_ip_protocol = input_1_ip_protocol; + selected_input_ip_header_checksum = input_1_ip_header_checksum; + selected_input_ip_source_ip = input_1_ip_source_ip; + selected_input_ip_dest_ip = input_1_ip_dest_ip; + end + 2'd2: begin + selected_input_ip_hdr_valid = input_2_ip_hdr_valid; + selected_input_eth_dest_mac = input_2_eth_dest_mac; + selected_input_eth_src_mac = input_2_eth_src_mac; + selected_input_eth_type = input_2_eth_type; + selected_input_ip_version = input_2_ip_version; + selected_input_ip_ihl = input_2_ip_ihl; + selected_input_ip_dscp = input_2_ip_dscp; + selected_input_ip_ecn = input_2_ip_ecn; + selected_input_ip_length = input_2_ip_length; + selected_input_ip_identification = input_2_ip_identification; + selected_input_ip_flags = input_2_ip_flags; + selected_input_ip_fragment_offset = input_2_ip_fragment_offset; + selected_input_ip_ttl = input_2_ip_ttl; + selected_input_ip_protocol = input_2_ip_protocol; + selected_input_ip_header_checksum = input_2_ip_header_checksum; + selected_input_ip_source_ip = input_2_ip_source_ip; + selected_input_ip_dest_ip = input_2_ip_dest_ip; + end + 2'd3: begin + selected_input_ip_hdr_valid = input_3_ip_hdr_valid; + selected_input_eth_dest_mac = input_3_eth_dest_mac; + selected_input_eth_src_mac = input_3_eth_src_mac; + selected_input_eth_type = input_3_eth_type; + selected_input_ip_version = input_3_ip_version; + selected_input_ip_ihl = input_3_ip_ihl; + selected_input_ip_dscp = input_3_ip_dscp; + selected_input_ip_ecn = input_3_ip_ecn; + selected_input_ip_length = input_3_ip_length; + selected_input_ip_identification = input_3_ip_identification; + selected_input_ip_flags = input_3_ip_flags; + selected_input_ip_fragment_offset = input_3_ip_fragment_offset; + selected_input_ip_ttl = input_3_ip_ttl; + selected_input_ip_protocol = input_3_ip_protocol; + selected_input_ip_header_checksum = input_3_ip_header_checksum; + selected_input_ip_source_ip = input_3_ip_source_ip; + selected_input_ip_dest_ip = input_3_ip_dest_ip; + end + endcase +end + +// mux for incoming packet +reg [63:0] current_input_tdata; +reg [7:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 2'd0: begin + current_input_tdata = input_0_ip_payload_tdata; + current_input_tkeep = input_0_ip_payload_tkeep; + current_input_tvalid = input_0_ip_payload_tvalid; + current_input_tready = input_0_ip_payload_tready; + current_input_tlast = input_0_ip_payload_tlast; + current_input_tuser = input_0_ip_payload_tuser; + end + 2'd1: begin + current_input_tdata = input_1_ip_payload_tdata; + current_input_tkeep = input_1_ip_payload_tkeep; + current_input_tvalid = input_1_ip_payload_tvalid; + current_input_tready = input_1_ip_payload_tready; + current_input_tlast = input_1_ip_payload_tlast; + current_input_tuser = input_1_ip_payload_tuser; + end + 2'd2: begin + current_input_tdata = input_2_ip_payload_tdata; + current_input_tkeep = input_2_ip_payload_tkeep; + current_input_tvalid = input_2_ip_payload_tvalid; + current_input_tready = input_2_ip_payload_tready; + current_input_tlast = input_2_ip_payload_tlast; + current_input_tuser = input_2_ip_payload_tuser; + end + 2'd3: begin + current_input_tdata = input_3_ip_payload_tdata; + current_input_tkeep = input_3_ip_payload_tkeep; + current_input_tvalid = input_3_ip_payload_tvalid; + current_input_tready = input_3_ip_payload_tready; + current_input_tlast = input_3_ip_payload_tlast; + current_input_tuser = input_3_ip_payload_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_ip_hdr_ready_next = input_0_ip_hdr_ready_reg & ~input_0_ip_hdr_valid; + input_1_ip_hdr_ready_next = input_1_ip_hdr_ready_reg & ~input_1_ip_hdr_valid; + input_2_ip_hdr_ready_next = input_2_ip_hdr_ready_reg & ~input_2_ip_hdr_valid; + input_3_ip_hdr_ready_next = input_3_ip_hdr_ready_reg & ~input_3_ip_hdr_valid; + + input_0_ip_payload_tready_next = 0; + input_1_ip_payload_tready_next = 0; + input_2_ip_payload_tready_next = 0; + input_3_ip_payload_tready_next = 0; + + output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) + 2'd0: input_0_ip_hdr_ready_next = 1; + 2'd1: input_1_ip_hdr_ready_next = 1; + 2'd2: input_2_ip_hdr_ready_next = 1; + 2'd3: input_3_ip_hdr_ready_next = 1; + endcase + + output_ip_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + output_ip_version_next = selected_input_ip_version; + output_ip_ihl_next = selected_input_ip_ihl; + output_ip_dscp_next = selected_input_ip_dscp; + output_ip_ecn_next = selected_input_ip_ecn; + output_ip_length_next = selected_input_ip_length; + output_ip_identification_next = selected_input_ip_identification; + output_ip_flags_next = selected_input_ip_flags; + output_ip_fragment_offset_next = selected_input_ip_fragment_offset; + output_ip_ttl_next = selected_input_ip_ttl; + output_ip_protocol_next = selected_input_ip_protocol; + output_ip_header_checksum_next = selected_input_ip_header_checksum; + output_ip_source_ip_next = selected_input_ip_source_ip; + output_ip_dest_ip_next = selected_input_ip_dest_ip; + end + + // generate ready signal on selected port + case (select_next) + 2'd0: input_0_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + 2'd1: input_1_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + 2'd2: input_2_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + 2'd3: input_3_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + endcase + + // pass through selected packet data + output_ip_payload_tdata_int = current_input_tdata; + output_ip_payload_tkeep_int = current_input_tkeep; + output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_ip_payload_tlast_int = current_input_tlast; + output_ip_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_ip_hdr_ready_reg <= 0; + input_1_ip_hdr_ready_reg <= 0; + input_2_ip_hdr_ready_reg <= 0; + input_3_ip_hdr_ready_reg <= 0; + input_0_ip_payload_tready_reg <= 0; + input_1_ip_payload_tready_reg <= 0; + input_2_ip_payload_tready_reg <= 0; + input_3_ip_payload_tready_reg <= 0; + output_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_ip_hdr_ready_reg <= input_0_ip_hdr_ready_next; + input_1_ip_hdr_ready_reg <= input_1_ip_hdr_ready_next; + input_2_ip_hdr_ready_reg <= input_2_ip_hdr_ready_next; + input_3_ip_hdr_ready_reg <= input_3_ip_hdr_ready_next; + input_0_ip_payload_tready_reg <= input_0_ip_payload_tready_next; + input_1_ip_payload_tready_reg <= input_1_ip_payload_tready_next; + input_2_ip_payload_tready_reg <= input_2_ip_payload_tready_next; + input_3_ip_payload_tready_reg <= input_3_ip_payload_tready_next; + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + end +end + +// output datapath logic +reg [63:0] output_ip_payload_tdata_reg = 0; +reg [7:0] output_ip_payload_tkeep_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [63:0] temp_ip_payload_tdata_reg = 0; +reg [7:0] temp_ip_payload_tkeep_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tkeep_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_ip_mux_4.py b/tb/test_ip_mux_4.py new file mode 100755 index 000000000..aae612801 --- /dev/null +++ b/tb/test_ip_mux_4.py @@ -0,0 +1,1118 @@ +#!/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 ip_ep + +module = 'ip_mux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_ip_mux_4(clk, + rst, + current_test, + + input_0_ip_hdr_valid, + input_0_ip_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tvalid, + input_0_ip_payload_tready, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_ip_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tvalid, + input_1_ip_payload_tready, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_ip_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tvalid, + input_2_ip_payload_tready, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_ip_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tvalid, + input_3_ip_payload_tready, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + enable, + select): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_ip_hdr_valid=input_0_ip_hdr_valid, + input_0_ip_hdr_ready=input_0_ip_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_ip_version=input_0_ip_version, + input_0_ip_ihl=input_0_ip_ihl, + input_0_ip_dscp=input_0_ip_dscp, + input_0_ip_ecn=input_0_ip_ecn, + input_0_ip_length=input_0_ip_length, + input_0_ip_identification=input_0_ip_identification, + input_0_ip_flags=input_0_ip_flags, + input_0_ip_fragment_offset=input_0_ip_fragment_offset, + input_0_ip_ttl=input_0_ip_ttl, + input_0_ip_protocol=input_0_ip_protocol, + input_0_ip_header_checksum=input_0_ip_header_checksum, + input_0_ip_source_ip=input_0_ip_source_ip, + input_0_ip_dest_ip=input_0_ip_dest_ip, + input_0_ip_payload_tdata=input_0_ip_payload_tdata, + input_0_ip_payload_tvalid=input_0_ip_payload_tvalid, + input_0_ip_payload_tready=input_0_ip_payload_tready, + input_0_ip_payload_tlast=input_0_ip_payload_tlast, + input_0_ip_payload_tuser=input_0_ip_payload_tuser, + input_1_ip_hdr_valid=input_1_ip_hdr_valid, + input_1_ip_hdr_ready=input_1_ip_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_ip_version=input_1_ip_version, + input_1_ip_ihl=input_1_ip_ihl, + input_1_ip_dscp=input_1_ip_dscp, + input_1_ip_ecn=input_1_ip_ecn, + input_1_ip_length=input_1_ip_length, + input_1_ip_identification=input_1_ip_identification, + input_1_ip_flags=input_1_ip_flags, + input_1_ip_fragment_offset=input_1_ip_fragment_offset, + input_1_ip_ttl=input_1_ip_ttl, + input_1_ip_protocol=input_1_ip_protocol, + input_1_ip_header_checksum=input_1_ip_header_checksum, + input_1_ip_source_ip=input_1_ip_source_ip, + input_1_ip_dest_ip=input_1_ip_dest_ip, + input_1_ip_payload_tdata=input_1_ip_payload_tdata, + input_1_ip_payload_tvalid=input_1_ip_payload_tvalid, + input_1_ip_payload_tready=input_1_ip_payload_tready, + input_1_ip_payload_tlast=input_1_ip_payload_tlast, + input_1_ip_payload_tuser=input_1_ip_payload_tuser, + input_2_ip_hdr_valid=input_2_ip_hdr_valid, + input_2_ip_hdr_ready=input_2_ip_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_ip_version=input_2_ip_version, + input_2_ip_ihl=input_2_ip_ihl, + input_2_ip_dscp=input_2_ip_dscp, + input_2_ip_ecn=input_2_ip_ecn, + input_2_ip_length=input_2_ip_length, + input_2_ip_identification=input_2_ip_identification, + input_2_ip_flags=input_2_ip_flags, + input_2_ip_fragment_offset=input_2_ip_fragment_offset, + input_2_ip_ttl=input_2_ip_ttl, + input_2_ip_protocol=input_2_ip_protocol, + input_2_ip_header_checksum=input_2_ip_header_checksum, + input_2_ip_source_ip=input_2_ip_source_ip, + input_2_ip_dest_ip=input_2_ip_dest_ip, + input_2_ip_payload_tdata=input_2_ip_payload_tdata, + input_2_ip_payload_tvalid=input_2_ip_payload_tvalid, + input_2_ip_payload_tready=input_2_ip_payload_tready, + input_2_ip_payload_tlast=input_2_ip_payload_tlast, + input_2_ip_payload_tuser=input_2_ip_payload_tuser, + input_3_ip_hdr_valid=input_3_ip_hdr_valid, + input_3_ip_hdr_ready=input_3_ip_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_ip_version=input_3_ip_version, + input_3_ip_ihl=input_3_ip_ihl, + input_3_ip_dscp=input_3_ip_dscp, + input_3_ip_ecn=input_3_ip_ecn, + input_3_ip_length=input_3_ip_length, + input_3_ip_identification=input_3_ip_identification, + input_3_ip_flags=input_3_ip_flags, + input_3_ip_fragment_offset=input_3_ip_fragment_offset, + input_3_ip_ttl=input_3_ip_ttl, + input_3_ip_protocol=input_3_ip_protocol, + input_3_ip_header_checksum=input_3_ip_header_checksum, + input_3_ip_source_ip=input_3_ip_source_ip, + input_3_ip_dest_ip=input_3_ip_dest_ip, + input_3_ip_payload_tdata=input_3_ip_payload_tdata, + input_3_ip_payload_tvalid=input_3_ip_payload_tvalid, + input_3_ip_payload_tready=input_3_ip_payload_tready, + input_3_ip_payload_tlast=input_3_ip_payload_tlast, + input_3_ip_payload_tuser=input_3_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + enable=enable, + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_ip_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_ip_version = Signal(intbv(0)[4:]) + input_0_ip_ihl = Signal(intbv(0)[4:]) + input_0_ip_dscp = Signal(intbv(0)[6:]) + input_0_ip_ecn = Signal(intbv(0)[2:]) + input_0_ip_length = Signal(intbv(0)[16:]) + input_0_ip_identification = Signal(intbv(0)[16:]) + input_0_ip_flags = Signal(intbv(0)[3:]) + input_0_ip_fragment_offset = Signal(intbv(0)[13:]) + input_0_ip_ttl = Signal(intbv(0)[8:]) + input_0_ip_protocol = Signal(intbv(0)[8:]) + input_0_ip_header_checksum = Signal(intbv(0)[16:]) + input_0_ip_source_ip = Signal(intbv(0)[32:]) + input_0_ip_dest_ip = Signal(intbv(0)[32:]) + input_0_ip_payload_tdata = Signal(intbv(0)[8:]) + input_0_ip_payload_tvalid = Signal(bool(0)) + input_0_ip_payload_tlast = Signal(bool(0)) + input_0_ip_payload_tuser = Signal(bool(0)) + input_1_ip_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_ip_version = Signal(intbv(0)[4:]) + input_1_ip_ihl = Signal(intbv(0)[4:]) + input_1_ip_dscp = Signal(intbv(0)[6:]) + input_1_ip_ecn = Signal(intbv(0)[2:]) + input_1_ip_length = Signal(intbv(0)[16:]) + input_1_ip_identification = Signal(intbv(0)[16:]) + input_1_ip_flags = Signal(intbv(0)[3:]) + input_1_ip_fragment_offset = Signal(intbv(0)[13:]) + input_1_ip_ttl = Signal(intbv(0)[8:]) + input_1_ip_protocol = Signal(intbv(0)[8:]) + input_1_ip_header_checksum = Signal(intbv(0)[16:]) + input_1_ip_source_ip = Signal(intbv(0)[32:]) + input_1_ip_dest_ip = Signal(intbv(0)[32:]) + input_1_ip_payload_tdata = Signal(intbv(0)[8:]) + input_1_ip_payload_tvalid = Signal(bool(0)) + input_1_ip_payload_tlast = Signal(bool(0)) + input_1_ip_payload_tuser = Signal(bool(0)) + input_2_ip_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_ip_version = Signal(intbv(0)[4:]) + input_2_ip_ihl = Signal(intbv(0)[4:]) + input_2_ip_dscp = Signal(intbv(0)[6:]) + input_2_ip_ecn = Signal(intbv(0)[2:]) + input_2_ip_length = Signal(intbv(0)[16:]) + input_2_ip_identification = Signal(intbv(0)[16:]) + input_2_ip_flags = Signal(intbv(0)[3:]) + input_2_ip_fragment_offset = Signal(intbv(0)[13:]) + input_2_ip_ttl = Signal(intbv(0)[8:]) + input_2_ip_protocol = Signal(intbv(0)[8:]) + input_2_ip_header_checksum = Signal(intbv(0)[16:]) + input_2_ip_source_ip = Signal(intbv(0)[32:]) + input_2_ip_dest_ip = Signal(intbv(0)[32:]) + input_2_ip_payload_tdata = Signal(intbv(0)[8:]) + input_2_ip_payload_tvalid = Signal(bool(0)) + input_2_ip_payload_tlast = Signal(bool(0)) + input_2_ip_payload_tuser = Signal(bool(0)) + input_3_ip_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_ip_version = Signal(intbv(0)[4:]) + input_3_ip_ihl = Signal(intbv(0)[4:]) + input_3_ip_dscp = Signal(intbv(0)[6:]) + input_3_ip_ecn = Signal(intbv(0)[2:]) + input_3_ip_length = Signal(intbv(0)[16:]) + input_3_ip_identification = Signal(intbv(0)[16:]) + input_3_ip_flags = Signal(intbv(0)[3:]) + input_3_ip_fragment_offset = Signal(intbv(0)[13:]) + input_3_ip_ttl = Signal(intbv(0)[8:]) + input_3_ip_protocol = Signal(intbv(0)[8:]) + input_3_ip_header_checksum = Signal(intbv(0)[16:]) + input_3_ip_source_ip = Signal(intbv(0)[32:]) + input_3_ip_dest_ip = Signal(intbv(0)[32:]) + input_3_ip_payload_tdata = Signal(intbv(0)[8:]) + input_3_ip_payload_tvalid = Signal(bool(0)) + input_3_ip_payload_tlast = Signal(bool(0)) + input_3_ip_payload_tuser = Signal(bool(0)) + + output_ip_payload_tready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + + enable = Signal(bool(0)) + select = Signal(intbv(0)[2:]) + + # Outputs + input_0_ip_hdr_ready = Signal(bool(0)) + input_0_ip_payload_tready = Signal(bool(0)) + input_1_ip_hdr_ready = Signal(bool(0)) + input_1_ip_payload_tready = Signal(bool(0)) + input_2_ip_hdr_ready = Signal(bool(0)) + input_2_ip_payload_tready = Signal(bool(0)) + input_3_ip_hdr_ready = Signal(bool(0)) + input_3_ip_payload_tready = Signal(bool(0)) + + output_ip_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_0_ip_hdr_ready, + ip_hdr_valid=input_0_ip_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + ip_version=input_0_ip_version, + ip_ihl=input_0_ip_ihl, + ip_dscp=input_0_ip_dscp, + ip_ecn=input_0_ip_ecn, + ip_length=input_0_ip_length, + ip_identification=input_0_ip_identification, + ip_flags=input_0_ip_flags, + ip_fragment_offset=input_0_ip_fragment_offset, + ip_ttl=input_0_ip_ttl, + ip_protocol=input_0_ip_protocol, + ip_header_checksum=input_0_ip_header_checksum, + ip_source_ip=input_0_ip_source_ip, + ip_dest_ip=input_0_ip_dest_ip, + ip_payload_tdata=input_0_ip_payload_tdata, + ip_payload_tvalid=input_0_ip_payload_tvalid, + ip_payload_tready=input_0_ip_payload_tready, + ip_payload_tlast=input_0_ip_payload_tlast, + ip_payload_tuser=input_0_ip_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_1_ip_hdr_ready, + ip_hdr_valid=input_1_ip_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + ip_version=input_1_ip_version, + ip_ihl=input_1_ip_ihl, + ip_dscp=input_1_ip_dscp, + ip_ecn=input_1_ip_ecn, + ip_length=input_1_ip_length, + ip_identification=input_1_ip_identification, + ip_flags=input_1_ip_flags, + ip_fragment_offset=input_1_ip_fragment_offset, + ip_ttl=input_1_ip_ttl, + ip_protocol=input_1_ip_protocol, + ip_header_checksum=input_1_ip_header_checksum, + ip_source_ip=input_1_ip_source_ip, + ip_dest_ip=input_1_ip_dest_ip, + ip_payload_tdata=input_1_ip_payload_tdata, + ip_payload_tvalid=input_1_ip_payload_tvalid, + ip_payload_tready=input_1_ip_payload_tready, + ip_payload_tlast=input_1_ip_payload_tlast, + ip_payload_tuser=input_1_ip_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_2_ip_hdr_ready, + ip_hdr_valid=input_2_ip_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + ip_version=input_2_ip_version, + ip_ihl=input_2_ip_ihl, + ip_dscp=input_2_ip_dscp, + ip_ecn=input_2_ip_ecn, + ip_length=input_2_ip_length, + ip_identification=input_2_ip_identification, + ip_flags=input_2_ip_flags, + ip_fragment_offset=input_2_ip_fragment_offset, + ip_ttl=input_2_ip_ttl, + ip_protocol=input_2_ip_protocol, + ip_header_checksum=input_2_ip_header_checksum, + ip_source_ip=input_2_ip_source_ip, + ip_dest_ip=input_2_ip_dest_ip, + ip_payload_tdata=input_2_ip_payload_tdata, + ip_payload_tvalid=input_2_ip_payload_tvalid, + ip_payload_tready=input_2_ip_payload_tready, + ip_payload_tlast=input_2_ip_payload_tlast, + ip_payload_tuser=input_2_ip_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_3_ip_hdr_ready, + ip_hdr_valid=input_3_ip_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + ip_version=input_3_ip_version, + ip_ihl=input_3_ip_ihl, + ip_dscp=input_3_ip_dscp, + ip_ecn=input_3_ip_ecn, + ip_length=input_3_ip_length, + ip_identification=input_3_ip_identification, + ip_flags=input_3_ip_flags, + ip_fragment_offset=input_3_ip_fragment_offset, + ip_ttl=input_3_ip_ttl, + ip_protocol=input_3_ip_protocol, + ip_header_checksum=input_3_ip_header_checksum, + ip_source_ip=input_3_ip_source_ip, + ip_dest_ip=input_3_ip_dest_ip, + ip_payload_tdata=input_3_ip_payload_tdata, + ip_payload_tvalid=input_3_ip_payload_tvalid, + ip_payload_tready=input_3_ip_payload_tready, + ip_payload_tlast=input_3_ip_payload_tlast, + ip_payload_tuser=input_3_ip_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_ip_mux_4(clk, + rst, + current_test, + + input_0_ip_hdr_valid, + input_0_ip_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tvalid, + input_0_ip_payload_tready, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_ip_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tvalid, + input_1_ip_payload_tready, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_ip_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tvalid, + input_2_ip_payload_tready, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_ip_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tvalid, + input_3_ip_payload_tready, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + enable, + select) + + @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 + enable.next = True + + yield clk.posedge + print("test 1: select port 0") + current_test.next = 1 + + select.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + yield clk.posedge + select.next = 2 + 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: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + select.next = 2 + 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: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + select.next = 2 + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_mux_4.v b/tb/test_ip_mux_4.v new file mode 100644 index 000000000..a5af9d391 --- /dev/null +++ b/tb/test_ip_mux_4.v @@ -0,0 +1,413 @@ +/* + +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_ip_mux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_ip_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [3:0] input_0_ip_version = 0; +reg [3:0] input_0_ip_ihl = 0; +reg [5:0] input_0_ip_dscp = 0; +reg [1:0] input_0_ip_ecn = 0; +reg [15:0] input_0_ip_length = 0; +reg [15:0] input_0_ip_identification = 0; +reg [2:0] input_0_ip_flags = 0; +reg [12:0] input_0_ip_fragment_offset = 0; +reg [7:0] input_0_ip_ttl = 0; +reg [7:0] input_0_ip_protocol = 0; +reg [15:0] input_0_ip_header_checksum = 0; +reg [31:0] input_0_ip_source_ip = 0; +reg [31:0] input_0_ip_dest_ip = 0; +reg [7:0] input_0_ip_payload_tdata = 0; +reg input_0_ip_payload_tvalid = 0; +reg input_0_ip_payload_tlast = 0; +reg input_0_ip_payload_tuser = 0; +reg input_1_ip_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [3:0] input_1_ip_version = 0; +reg [3:0] input_1_ip_ihl = 0; +reg [5:0] input_1_ip_dscp = 0; +reg [1:0] input_1_ip_ecn = 0; +reg [15:0] input_1_ip_length = 0; +reg [15:0] input_1_ip_identification = 0; +reg [2:0] input_1_ip_flags = 0; +reg [12:0] input_1_ip_fragment_offset = 0; +reg [7:0] input_1_ip_ttl = 0; +reg [7:0] input_1_ip_protocol = 0; +reg [15:0] input_1_ip_header_checksum = 0; +reg [31:0] input_1_ip_source_ip = 0; +reg [31:0] input_1_ip_dest_ip = 0; +reg [7:0] input_1_ip_payload_tdata = 0; +reg input_1_ip_payload_tvalid = 0; +reg input_1_ip_payload_tlast = 0; +reg input_1_ip_payload_tuser = 0; +reg input_2_ip_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [3:0] input_2_ip_version = 0; +reg [3:0] input_2_ip_ihl = 0; +reg [5:0] input_2_ip_dscp = 0; +reg [1:0] input_2_ip_ecn = 0; +reg [15:0] input_2_ip_length = 0; +reg [15:0] input_2_ip_identification = 0; +reg [2:0] input_2_ip_flags = 0; +reg [12:0] input_2_ip_fragment_offset = 0; +reg [7:0] input_2_ip_ttl = 0; +reg [7:0] input_2_ip_protocol = 0; +reg [15:0] input_2_ip_header_checksum = 0; +reg [31:0] input_2_ip_source_ip = 0; +reg [31:0] input_2_ip_dest_ip = 0; +reg [7:0] input_2_ip_payload_tdata = 0; +reg input_2_ip_payload_tvalid = 0; +reg input_2_ip_payload_tlast = 0; +reg input_2_ip_payload_tuser = 0; +reg input_3_ip_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [3:0] input_3_ip_version = 0; +reg [3:0] input_3_ip_ihl = 0; +reg [5:0] input_3_ip_dscp = 0; +reg [1:0] input_3_ip_ecn = 0; +reg [15:0] input_3_ip_length = 0; +reg [15:0] input_3_ip_identification = 0; +reg [2:0] input_3_ip_flags = 0; +reg [12:0] input_3_ip_fragment_offset = 0; +reg [7:0] input_3_ip_ttl = 0; +reg [7:0] input_3_ip_protocol = 0; +reg [15:0] input_3_ip_header_checksum = 0; +reg [31:0] input_3_ip_source_ip = 0; +reg [31:0] input_3_ip_dest_ip = 0; +reg [7:0] input_3_ip_payload_tdata = 0; +reg input_3_ip_payload_tvalid = 0; +reg input_3_ip_payload_tlast = 0; +reg input_3_ip_payload_tuser = 0; + +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; + +reg enable = 0; +reg [1:0] select = 0; + +// Outputs +wire input_0_ip_payload_tready; +wire input_0_ip_hdr_ready; +wire input_1_ip_payload_tready; +wire input_1_ip_hdr_ready; +wire input_2_ip_payload_tready; +wire input_2_ip_hdr_ready; +wire input_3_ip_payload_tready; +wire input_3_ip_hdr_ready; + +wire output_ip_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [7:0] output_ip_payload_tdata; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_ip_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tvalid, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tvalid, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tvalid, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tvalid, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + output_ip_hdr_ready, + output_ip_payload_tready, + enable, + select); + $to_myhdl(input_0_ip_hdr_ready, + input_0_ip_payload_tready, + input_1_ip_hdr_ready, + input_1_ip_payload_tready, + input_2_ip_hdr_ready, + input_2_ip_payload_tready, + input_3_ip_hdr_ready, + input_3_ip_payload_tready, + output_ip_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser); + + // dump file + $dumpfile("test_ip_mux_4.lxt"); + $dumpvars(0, test_ip_mux_4); +end + +ip_mux_4 +UUT ( + .clk(clk), + .rst(rst), + // IP frame inputs + .input_0_ip_hdr_valid(input_0_ip_hdr_valid), + .input_0_ip_hdr_ready(input_0_ip_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_ip_payload_tdata(input_0_ip_payload_tdata), + .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid), + .input_0_ip_payload_tready(input_0_ip_payload_tready), + .input_0_ip_payload_tlast(input_0_ip_payload_tlast), + .input_0_ip_payload_tuser(input_0_ip_payload_tuser), + .input_1_ip_hdr_valid(input_1_ip_hdr_valid), + .input_1_ip_hdr_ready(input_1_ip_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_ip_payload_tdata(input_1_ip_payload_tdata), + .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid), + .input_1_ip_payload_tready(input_1_ip_payload_tready), + .input_1_ip_payload_tlast(input_1_ip_payload_tlast), + .input_1_ip_payload_tuser(input_1_ip_payload_tuser), + .input_2_ip_hdr_valid(input_2_ip_hdr_valid), + .input_2_ip_hdr_ready(input_2_ip_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_ip_payload_tdata(input_2_ip_payload_tdata), + .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid), + .input_2_ip_payload_tready(input_2_ip_payload_tready), + .input_2_ip_payload_tlast(input_2_ip_payload_tlast), + .input_2_ip_payload_tuser(input_2_ip_payload_tuser), + .input_3_ip_hdr_valid(input_3_ip_hdr_valid), + .input_3_ip_hdr_ready(input_3_ip_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_ip_payload_tdata(input_3_ip_payload_tdata), + .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid), + .input_3_ip_payload_tready(input_3_ip_payload_tready), + .input_3_ip_payload_tlast(input_3_ip_payload_tlast), + .input_3_ip_payload_tuser(input_3_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule diff --git a/tb/test_ip_mux_64_4.py b/tb/test_ip_mux_64_4.py new file mode 100755 index 000000000..7656167d0 --- /dev/null +++ b/tb/test_ip_mux_64_4.py @@ -0,0 +1,1143 @@ +#!/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 ip_ep + +module = 'ip_mux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_ip_mux_64_4(clk, + rst, + current_test, + + input_0_ip_hdr_valid, + input_0_ip_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tkeep, + input_0_ip_payload_tvalid, + input_0_ip_payload_tready, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_ip_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tkeep, + input_1_ip_payload_tvalid, + input_1_ip_payload_tready, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_ip_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tkeep, + input_2_ip_payload_tvalid, + input_2_ip_payload_tready, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_ip_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tkeep, + input_3_ip_payload_tvalid, + input_3_ip_payload_tready, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + enable, + select): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_ip_hdr_valid=input_0_ip_hdr_valid, + input_0_ip_hdr_ready=input_0_ip_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_ip_version=input_0_ip_version, + input_0_ip_ihl=input_0_ip_ihl, + input_0_ip_dscp=input_0_ip_dscp, + input_0_ip_ecn=input_0_ip_ecn, + input_0_ip_length=input_0_ip_length, + input_0_ip_identification=input_0_ip_identification, + input_0_ip_flags=input_0_ip_flags, + input_0_ip_fragment_offset=input_0_ip_fragment_offset, + input_0_ip_ttl=input_0_ip_ttl, + input_0_ip_protocol=input_0_ip_protocol, + input_0_ip_header_checksum=input_0_ip_header_checksum, + input_0_ip_source_ip=input_0_ip_source_ip, + input_0_ip_dest_ip=input_0_ip_dest_ip, + input_0_ip_payload_tdata=input_0_ip_payload_tdata, + input_0_ip_payload_tkeep=input_0_ip_payload_tkeep, + input_0_ip_payload_tvalid=input_0_ip_payload_tvalid, + input_0_ip_payload_tready=input_0_ip_payload_tready, + input_0_ip_payload_tlast=input_0_ip_payload_tlast, + input_0_ip_payload_tuser=input_0_ip_payload_tuser, + input_1_ip_hdr_valid=input_1_ip_hdr_valid, + input_1_ip_hdr_ready=input_1_ip_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_ip_version=input_1_ip_version, + input_1_ip_ihl=input_1_ip_ihl, + input_1_ip_dscp=input_1_ip_dscp, + input_1_ip_ecn=input_1_ip_ecn, + input_1_ip_length=input_1_ip_length, + input_1_ip_identification=input_1_ip_identification, + input_1_ip_flags=input_1_ip_flags, + input_1_ip_fragment_offset=input_1_ip_fragment_offset, + input_1_ip_ttl=input_1_ip_ttl, + input_1_ip_protocol=input_1_ip_protocol, + input_1_ip_header_checksum=input_1_ip_header_checksum, + input_1_ip_source_ip=input_1_ip_source_ip, + input_1_ip_dest_ip=input_1_ip_dest_ip, + input_1_ip_payload_tdata=input_1_ip_payload_tdata, + input_1_ip_payload_tkeep=input_1_ip_payload_tkeep, + input_1_ip_payload_tvalid=input_1_ip_payload_tvalid, + input_1_ip_payload_tready=input_1_ip_payload_tready, + input_1_ip_payload_tlast=input_1_ip_payload_tlast, + input_1_ip_payload_tuser=input_1_ip_payload_tuser, + input_2_ip_hdr_valid=input_2_ip_hdr_valid, + input_2_ip_hdr_ready=input_2_ip_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_ip_version=input_2_ip_version, + input_2_ip_ihl=input_2_ip_ihl, + input_2_ip_dscp=input_2_ip_dscp, + input_2_ip_ecn=input_2_ip_ecn, + input_2_ip_length=input_2_ip_length, + input_2_ip_identification=input_2_ip_identification, + input_2_ip_flags=input_2_ip_flags, + input_2_ip_fragment_offset=input_2_ip_fragment_offset, + input_2_ip_ttl=input_2_ip_ttl, + input_2_ip_protocol=input_2_ip_protocol, + input_2_ip_header_checksum=input_2_ip_header_checksum, + input_2_ip_source_ip=input_2_ip_source_ip, + input_2_ip_dest_ip=input_2_ip_dest_ip, + input_2_ip_payload_tdata=input_2_ip_payload_tdata, + input_2_ip_payload_tkeep=input_2_ip_payload_tkeep, + input_2_ip_payload_tvalid=input_2_ip_payload_tvalid, + input_2_ip_payload_tready=input_2_ip_payload_tready, + input_2_ip_payload_tlast=input_2_ip_payload_tlast, + input_2_ip_payload_tuser=input_2_ip_payload_tuser, + input_3_ip_hdr_valid=input_3_ip_hdr_valid, + input_3_ip_hdr_ready=input_3_ip_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_ip_version=input_3_ip_version, + input_3_ip_ihl=input_3_ip_ihl, + input_3_ip_dscp=input_3_ip_dscp, + input_3_ip_ecn=input_3_ip_ecn, + input_3_ip_length=input_3_ip_length, + input_3_ip_identification=input_3_ip_identification, + input_3_ip_flags=input_3_ip_flags, + input_3_ip_fragment_offset=input_3_ip_fragment_offset, + input_3_ip_ttl=input_3_ip_ttl, + input_3_ip_protocol=input_3_ip_protocol, + input_3_ip_header_checksum=input_3_ip_header_checksum, + input_3_ip_source_ip=input_3_ip_source_ip, + input_3_ip_dest_ip=input_3_ip_dest_ip, + input_3_ip_payload_tdata=input_3_ip_payload_tdata, + input_3_ip_payload_tkeep=input_3_ip_payload_tkeep, + input_3_ip_payload_tvalid=input_3_ip_payload_tvalid, + input_3_ip_payload_tready=input_3_ip_payload_tready, + input_3_ip_payload_tlast=input_3_ip_payload_tlast, + input_3_ip_payload_tuser=input_3_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tkeep=output_ip_payload_tkeep, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + enable=enable, + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_ip_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_ip_version = Signal(intbv(0)[4:]) + input_0_ip_ihl = Signal(intbv(0)[4:]) + input_0_ip_dscp = Signal(intbv(0)[6:]) + input_0_ip_ecn = Signal(intbv(0)[2:]) + input_0_ip_length = Signal(intbv(0)[16:]) + input_0_ip_identification = Signal(intbv(0)[16:]) + input_0_ip_flags = Signal(intbv(0)[3:]) + input_0_ip_fragment_offset = Signal(intbv(0)[13:]) + input_0_ip_ttl = Signal(intbv(0)[8:]) + input_0_ip_protocol = Signal(intbv(0)[8:]) + input_0_ip_header_checksum = Signal(intbv(0)[16:]) + input_0_ip_source_ip = Signal(intbv(0)[32:]) + input_0_ip_dest_ip = Signal(intbv(0)[32:]) + input_0_ip_payload_tdata = Signal(intbv(0)[64:]) + input_0_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_0_ip_payload_tvalid = Signal(bool(0)) + input_0_ip_payload_tlast = Signal(bool(0)) + input_0_ip_payload_tuser = Signal(bool(0)) + input_1_ip_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_ip_version = Signal(intbv(0)[4:]) + input_1_ip_ihl = Signal(intbv(0)[4:]) + input_1_ip_dscp = Signal(intbv(0)[6:]) + input_1_ip_ecn = Signal(intbv(0)[2:]) + input_1_ip_length = Signal(intbv(0)[16:]) + input_1_ip_identification = Signal(intbv(0)[16:]) + input_1_ip_flags = Signal(intbv(0)[3:]) + input_1_ip_fragment_offset = Signal(intbv(0)[13:]) + input_1_ip_ttl = Signal(intbv(0)[8:]) + input_1_ip_protocol = Signal(intbv(0)[8:]) + input_1_ip_header_checksum = Signal(intbv(0)[16:]) + input_1_ip_source_ip = Signal(intbv(0)[32:]) + input_1_ip_dest_ip = Signal(intbv(0)[32:]) + input_1_ip_payload_tdata = Signal(intbv(0)[64:]) + input_1_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_1_ip_payload_tvalid = Signal(bool(0)) + input_1_ip_payload_tlast = Signal(bool(0)) + input_1_ip_payload_tuser = Signal(bool(0)) + input_2_ip_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_ip_version = Signal(intbv(0)[4:]) + input_2_ip_ihl = Signal(intbv(0)[4:]) + input_2_ip_dscp = Signal(intbv(0)[6:]) + input_2_ip_ecn = Signal(intbv(0)[2:]) + input_2_ip_length = Signal(intbv(0)[16:]) + input_2_ip_identification = Signal(intbv(0)[16:]) + input_2_ip_flags = Signal(intbv(0)[3:]) + input_2_ip_fragment_offset = Signal(intbv(0)[13:]) + input_2_ip_ttl = Signal(intbv(0)[8:]) + input_2_ip_protocol = Signal(intbv(0)[8:]) + input_2_ip_header_checksum = Signal(intbv(0)[16:]) + input_2_ip_source_ip = Signal(intbv(0)[32:]) + input_2_ip_dest_ip = Signal(intbv(0)[32:]) + input_2_ip_payload_tdata = Signal(intbv(0)[64:]) + input_2_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_2_ip_payload_tvalid = Signal(bool(0)) + input_2_ip_payload_tlast = Signal(bool(0)) + input_2_ip_payload_tuser = Signal(bool(0)) + input_3_ip_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_ip_version = Signal(intbv(0)[4:]) + input_3_ip_ihl = Signal(intbv(0)[4:]) + input_3_ip_dscp = Signal(intbv(0)[6:]) + input_3_ip_ecn = Signal(intbv(0)[2:]) + input_3_ip_length = Signal(intbv(0)[16:]) + input_3_ip_identification = Signal(intbv(0)[16:]) + input_3_ip_flags = Signal(intbv(0)[3:]) + input_3_ip_fragment_offset = Signal(intbv(0)[13:]) + input_3_ip_ttl = Signal(intbv(0)[8:]) + input_3_ip_protocol = Signal(intbv(0)[8:]) + input_3_ip_header_checksum = Signal(intbv(0)[16:]) + input_3_ip_source_ip = Signal(intbv(0)[32:]) + input_3_ip_dest_ip = Signal(intbv(0)[32:]) + input_3_ip_payload_tdata = Signal(intbv(0)[64:]) + input_3_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_3_ip_payload_tvalid = Signal(bool(0)) + input_3_ip_payload_tlast = Signal(bool(0)) + input_3_ip_payload_tuser = Signal(bool(0)) + + output_ip_payload_tready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + + enable = Signal(bool(0)) + select = Signal(intbv(0)[2:]) + + # Outputs + input_0_ip_hdr_ready = Signal(bool(0)) + input_0_ip_payload_tready = Signal(bool(0)) + input_1_ip_hdr_ready = Signal(bool(0)) + input_1_ip_payload_tready = Signal(bool(0)) + input_2_ip_hdr_ready = Signal(bool(0)) + input_2_ip_payload_tready = Signal(bool(0)) + input_3_ip_hdr_ready = Signal(bool(0)) + input_3_ip_payload_tready = Signal(bool(0)) + + output_ip_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[64:]) + output_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_0_ip_hdr_ready, + ip_hdr_valid=input_0_ip_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + ip_version=input_0_ip_version, + ip_ihl=input_0_ip_ihl, + ip_dscp=input_0_ip_dscp, + ip_ecn=input_0_ip_ecn, + ip_length=input_0_ip_length, + ip_identification=input_0_ip_identification, + ip_flags=input_0_ip_flags, + ip_fragment_offset=input_0_ip_fragment_offset, + ip_ttl=input_0_ip_ttl, + ip_protocol=input_0_ip_protocol, + ip_header_checksum=input_0_ip_header_checksum, + ip_source_ip=input_0_ip_source_ip, + ip_dest_ip=input_0_ip_dest_ip, + ip_payload_tdata=input_0_ip_payload_tdata, + ip_payload_tkeep=input_0_ip_payload_tkeep, + ip_payload_tvalid=input_0_ip_payload_tvalid, + ip_payload_tready=input_0_ip_payload_tready, + ip_payload_tlast=input_0_ip_payload_tlast, + ip_payload_tuser=input_0_ip_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_1_ip_hdr_ready, + ip_hdr_valid=input_1_ip_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + ip_version=input_1_ip_version, + ip_ihl=input_1_ip_ihl, + ip_dscp=input_1_ip_dscp, + ip_ecn=input_1_ip_ecn, + ip_length=input_1_ip_length, + ip_identification=input_1_ip_identification, + ip_flags=input_1_ip_flags, + ip_fragment_offset=input_1_ip_fragment_offset, + ip_ttl=input_1_ip_ttl, + ip_protocol=input_1_ip_protocol, + ip_header_checksum=input_1_ip_header_checksum, + ip_source_ip=input_1_ip_source_ip, + ip_dest_ip=input_1_ip_dest_ip, + ip_payload_tdata=input_1_ip_payload_tdata, + ip_payload_tkeep=input_1_ip_payload_tkeep, + ip_payload_tvalid=input_1_ip_payload_tvalid, + ip_payload_tready=input_1_ip_payload_tready, + ip_payload_tlast=input_1_ip_payload_tlast, + ip_payload_tuser=input_1_ip_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_2_ip_hdr_ready, + ip_hdr_valid=input_2_ip_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + ip_version=input_2_ip_version, + ip_ihl=input_2_ip_ihl, + ip_dscp=input_2_ip_dscp, + ip_ecn=input_2_ip_ecn, + ip_length=input_2_ip_length, + ip_identification=input_2_ip_identification, + ip_flags=input_2_ip_flags, + ip_fragment_offset=input_2_ip_fragment_offset, + ip_ttl=input_2_ip_ttl, + ip_protocol=input_2_ip_protocol, + ip_header_checksum=input_2_ip_header_checksum, + ip_source_ip=input_2_ip_source_ip, + ip_dest_ip=input_2_ip_dest_ip, + ip_payload_tdata=input_2_ip_payload_tdata, + ip_payload_tkeep=input_2_ip_payload_tkeep, + ip_payload_tvalid=input_2_ip_payload_tvalid, + ip_payload_tready=input_2_ip_payload_tready, + ip_payload_tlast=input_2_ip_payload_tlast, + ip_payload_tuser=input_2_ip_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_3_ip_hdr_ready, + ip_hdr_valid=input_3_ip_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + ip_version=input_3_ip_version, + ip_ihl=input_3_ip_ihl, + ip_dscp=input_3_ip_dscp, + ip_ecn=input_3_ip_ecn, + ip_length=input_3_ip_length, + ip_identification=input_3_ip_identification, + ip_flags=input_3_ip_flags, + ip_fragment_offset=input_3_ip_fragment_offset, + ip_ttl=input_3_ip_ttl, + ip_protocol=input_3_ip_protocol, + ip_header_checksum=input_3_ip_header_checksum, + ip_source_ip=input_3_ip_source_ip, + ip_dest_ip=input_3_ip_dest_ip, + ip_payload_tdata=input_3_ip_payload_tdata, + ip_payload_tkeep=input_3_ip_payload_tkeep, + ip_payload_tvalid=input_3_ip_payload_tvalid, + ip_payload_tready=input_3_ip_payload_tready, + ip_payload_tlast=input_3_ip_payload_tlast, + ip_payload_tuser=input_3_ip_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tkeep=output_ip_payload_tkeep, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_ip_mux_64_4(clk, + rst, + current_test, + + input_0_ip_hdr_valid, + input_0_ip_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tkeep, + input_0_ip_payload_tvalid, + input_0_ip_payload_tready, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_ip_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tkeep, + input_1_ip_payload_tvalid, + input_1_ip_payload_tready, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_ip_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tkeep, + input_2_ip_payload_tvalid, + input_2_ip_payload_tready, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_ip_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tkeep, + input_3_ip_payload_tvalid, + input_3_ip_payload_tready, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + enable, + select) + + @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 + enable.next = True + + yield clk.posedge + print("test 1: select port 0") + current_test.next = 1 + + select.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + yield clk.posedge + select.next = 2 + 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: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + select.next = 2 + 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: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + select.next = 2 + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_mux_64_4.v b/tb/test_ip_mux_64_4.v new file mode 100644 index 000000000..ab796d85b --- /dev/null +++ b/tb/test_ip_mux_64_4.v @@ -0,0 +1,428 @@ +/* + +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_ip_mux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_ip_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [3:0] input_0_ip_version = 0; +reg [3:0] input_0_ip_ihl = 0; +reg [5:0] input_0_ip_dscp = 0; +reg [1:0] input_0_ip_ecn = 0; +reg [15:0] input_0_ip_length = 0; +reg [15:0] input_0_ip_identification = 0; +reg [2:0] input_0_ip_flags = 0; +reg [12:0] input_0_ip_fragment_offset = 0; +reg [7:0] input_0_ip_ttl = 0; +reg [7:0] input_0_ip_protocol = 0; +reg [15:0] input_0_ip_header_checksum = 0; +reg [31:0] input_0_ip_source_ip = 0; +reg [31:0] input_0_ip_dest_ip = 0; +reg [63:0] input_0_ip_payload_tdata = 0; +reg [7:0] input_0_ip_payload_tkeep = 0; +reg input_0_ip_payload_tvalid = 0; +reg input_0_ip_payload_tlast = 0; +reg input_0_ip_payload_tuser = 0; +reg input_1_ip_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [3:0] input_1_ip_version = 0; +reg [3:0] input_1_ip_ihl = 0; +reg [5:0] input_1_ip_dscp = 0; +reg [1:0] input_1_ip_ecn = 0; +reg [15:0] input_1_ip_length = 0; +reg [15:0] input_1_ip_identification = 0; +reg [2:0] input_1_ip_flags = 0; +reg [12:0] input_1_ip_fragment_offset = 0; +reg [7:0] input_1_ip_ttl = 0; +reg [7:0] input_1_ip_protocol = 0; +reg [15:0] input_1_ip_header_checksum = 0; +reg [31:0] input_1_ip_source_ip = 0; +reg [31:0] input_1_ip_dest_ip = 0; +reg [63:0] input_1_ip_payload_tdata = 0; +reg [7:0] input_1_ip_payload_tkeep = 0; +reg input_1_ip_payload_tvalid = 0; +reg input_1_ip_payload_tlast = 0; +reg input_1_ip_payload_tuser = 0; +reg input_2_ip_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [3:0] input_2_ip_version = 0; +reg [3:0] input_2_ip_ihl = 0; +reg [5:0] input_2_ip_dscp = 0; +reg [1:0] input_2_ip_ecn = 0; +reg [15:0] input_2_ip_length = 0; +reg [15:0] input_2_ip_identification = 0; +reg [2:0] input_2_ip_flags = 0; +reg [12:0] input_2_ip_fragment_offset = 0; +reg [7:0] input_2_ip_ttl = 0; +reg [7:0] input_2_ip_protocol = 0; +reg [15:0] input_2_ip_header_checksum = 0; +reg [31:0] input_2_ip_source_ip = 0; +reg [31:0] input_2_ip_dest_ip = 0; +reg [63:0] input_2_ip_payload_tdata = 0; +reg [7:0] input_2_ip_payload_tkeep = 0; +reg input_2_ip_payload_tvalid = 0; +reg input_2_ip_payload_tlast = 0; +reg input_2_ip_payload_tuser = 0; +reg input_3_ip_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [3:0] input_3_ip_version = 0; +reg [3:0] input_3_ip_ihl = 0; +reg [5:0] input_3_ip_dscp = 0; +reg [1:0] input_3_ip_ecn = 0; +reg [15:0] input_3_ip_length = 0; +reg [15:0] input_3_ip_identification = 0; +reg [2:0] input_3_ip_flags = 0; +reg [12:0] input_3_ip_fragment_offset = 0; +reg [7:0] input_3_ip_ttl = 0; +reg [7:0] input_3_ip_protocol = 0; +reg [15:0] input_3_ip_header_checksum = 0; +reg [31:0] input_3_ip_source_ip = 0; +reg [31:0] input_3_ip_dest_ip = 0; +reg [63:0] input_3_ip_payload_tdata = 0; +reg [7:0] input_3_ip_payload_tkeep = 0; +reg input_3_ip_payload_tvalid = 0; +reg input_3_ip_payload_tlast = 0; +reg input_3_ip_payload_tuser = 0; + +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; + +reg enable = 0; +reg [1:0] select = 0; + +// Outputs +wire input_0_ip_payload_tready; +wire input_0_ip_hdr_ready; +wire input_1_ip_payload_tready; +wire input_1_ip_hdr_ready; +wire input_2_ip_payload_tready; +wire input_2_ip_hdr_ready; +wire input_3_ip_payload_tready; +wire input_3_ip_hdr_ready; + +wire output_ip_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [63:0] output_ip_payload_tdata; +wire [7:0] output_ip_payload_tkeep; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_ip_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tkeep, + input_0_ip_payload_tvalid, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tkeep, + input_1_ip_payload_tvalid, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tkeep, + input_2_ip_payload_tvalid, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tkeep, + input_3_ip_payload_tvalid, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + output_ip_hdr_ready, + output_ip_payload_tready, + enable, + select); + $to_myhdl(input_0_ip_hdr_ready, + input_0_ip_payload_tready, + input_1_ip_hdr_ready, + input_1_ip_payload_tready, + input_2_ip_hdr_ready, + input_2_ip_payload_tready, + input_3_ip_hdr_ready, + input_3_ip_payload_tready, + output_ip_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser); + + // dump file + $dumpfile("test_ip_mux_64_4.lxt"); + $dumpvars(0, test_ip_mux_64_4); +end + +ip_mux_64_4 +UUT ( + .clk(clk), + .rst(rst), + // IP frame inputs + .input_0_ip_hdr_valid(input_0_ip_hdr_valid), + .input_0_ip_hdr_ready(input_0_ip_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_ip_payload_tdata(input_0_ip_payload_tdata), + .input_0_ip_payload_tkeep(input_0_ip_payload_tkeep), + .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid), + .input_0_ip_payload_tready(input_0_ip_payload_tready), + .input_0_ip_payload_tlast(input_0_ip_payload_tlast), + .input_0_ip_payload_tuser(input_0_ip_payload_tuser), + .input_1_ip_hdr_valid(input_1_ip_hdr_valid), + .input_1_ip_hdr_ready(input_1_ip_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_ip_payload_tdata(input_1_ip_payload_tdata), + .input_1_ip_payload_tkeep(input_1_ip_payload_tkeep), + .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid), + .input_1_ip_payload_tready(input_1_ip_payload_tready), + .input_1_ip_payload_tlast(input_1_ip_payload_tlast), + .input_1_ip_payload_tuser(input_1_ip_payload_tuser), + .input_2_ip_hdr_valid(input_2_ip_hdr_valid), + .input_2_ip_hdr_ready(input_2_ip_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_ip_payload_tdata(input_2_ip_payload_tdata), + .input_2_ip_payload_tkeep(input_2_ip_payload_tkeep), + .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid), + .input_2_ip_payload_tready(input_2_ip_payload_tready), + .input_2_ip_payload_tlast(input_2_ip_payload_tlast), + .input_2_ip_payload_tuser(input_2_ip_payload_tuser), + .input_3_ip_hdr_valid(input_3_ip_hdr_valid), + .input_3_ip_hdr_ready(input_3_ip_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_ip_payload_tdata(input_3_ip_payload_tdata), + .input_3_ip_payload_tkeep(input_3_ip_payload_tkeep), + .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid), + .input_3_ip_payload_tready(input_3_ip_payload_tready), + .input_3_ip_payload_tlast(input_3_ip_payload_tlast), + .input_3_ip_payload_tuser(input_3_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule From fbca60e65e807a814f220b25438c27a96b2447a7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 18 Nov 2014 11:48:11 -0800 Subject: [PATCH 109/617] Add IP arbitrated mux and testbench --- rtl/ip_arb_mux.py | 268 ++++++++ rtl/ip_arb_mux_4.v | 326 ++++++++++ rtl/ip_arb_mux_64.py | 272 ++++++++ rtl/ip_arb_mux_64_4.v | 336 ++++++++++ tb/test_ip_arb_mux_4.py | 1191 +++++++++++++++++++++++++++++++++++ tb/test_ip_arb_mux_4.v | 405 ++++++++++++ tb/test_ip_arb_mux_64_4.py | 1216 ++++++++++++++++++++++++++++++++++++ tb/test_ip_arb_mux_64_4.v | 420 +++++++++++++ 8 files changed, 4434 insertions(+) create mode 100755 rtl/ip_arb_mux.py create mode 100644 rtl/ip_arb_mux_4.v create mode 100755 rtl/ip_arb_mux_64.py create mode 100644 rtl/ip_arb_mux_64_4.v create mode 100755 tb/test_ip_arb_mux_4.py create mode 100644 tb/test_ip_arb_mux_4.v create mode 100755 tb/test_ip_arb_mux_64_4.py create mode 100644 tb/test_ip_arb_mux_64_4.v diff --git a/rtl/ip_arb_mux.py b/rtl/ip_arb_mux.py new file mode 100755 index 000000000..40de019f2 --- /dev/null +++ b/rtl/ip_arb_mux.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python +"""ip_arb_mux + +Generates an arbitrated IP mux with the specified number of ports + +Usage: ip_arb_mux [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "ip_arb_mux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * IP {{n}} port arbitrated multiplexer + */ +module {{name}} # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_ip_hdr_valid, + output wire input_{{p}}_ip_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [3:0] input_{{p}}_ip_version, + input wire [3:0] input_{{p}}_ip_ihl, + input wire [5:0] input_{{p}}_ip_dscp, + input wire [1:0] input_{{p}}_ip_ecn, + input wire [15:0] input_{{p}}_ip_length, + input wire [15:0] input_{{p}}_ip_identification, + input wire [2:0] input_{{p}}_ip_flags, + input wire [12:0] input_{{p}}_ip_fragment_offset, + input wire [7:0] input_{{p}}_ip_ttl, + input wire [7:0] input_{{p}}_ip_protocol, + input wire [15:0] input_{{p}}_ip_header_checksum, + input wire [31:0] input_{{p}}_ip_source_ip, + input wire [31:0] input_{{p}}_ip_dest_ip, + input wire [7:0] input_{{p}}_ip_payload_tdata, + input wire input_{{p}}_ip_payload_tvalid, + output wire input_{{p}}_ip_payload_tready, + input wire input_{{p}}_ip_payload_tlast, + input wire input_{{p}}_ip_payload_tuser, +{% endfor %} + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser +); + +wire [{{n-1}}:0] request; +wire [{{n-1}}:0] acknowledge; +wire [{{n-1}}:0] grant; +wire grant_valid; +wire [{{w-1}}:0] grant_encoded; +{% for p in ports %} +assign acknowledge[{{p}}] = input_{{p}}_ip_payload_tvalid & input_{{p}}_ip_payload_tready & input_{{p}}_ip_payload_tlast; +assign request[{{p}}] = input_{{p}}_ip_hdr_valid; +{%- endfor %} + +// mux instance +ip_mux_{{n}} +mux_inst ( + .clk(clk), + .rst(rst), +{%- for p in ports %} + .input_{{p}}_ip_hdr_valid(input_{{p}}_ip_hdr_valid & grant[{{p}}]), + .input_{{p}}_ip_hdr_ready(input_{{p}}_ip_hdr_ready), + .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), + .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), + .input_{{p}}_eth_type(input_{{p}}_eth_type), + .input_{{p}}_ip_version(input_{{p}}_ip_version), + .input_{{p}}_ip_ihl(input_{{p}}_ip_ihl), + .input_{{p}}_ip_dscp(input_{{p}}_ip_dscp), + .input_{{p}}_ip_ecn(input_{{p}}_ip_ecn), + .input_{{p}}_ip_length(input_{{p}}_ip_length), + .input_{{p}}_ip_identification(input_{{p}}_ip_identification), + .input_{{p}}_ip_flags(input_{{p}}_ip_flags), + .input_{{p}}_ip_fragment_offset(input_{{p}}_ip_fragment_offset), + .input_{{p}}_ip_ttl(input_{{p}}_ip_ttl), + .input_{{p}}_ip_protocol(input_{{p}}_ip_protocol), + .input_{{p}}_ip_header_checksum(input_{{p}}_ip_header_checksum), + .input_{{p}}_ip_source_ip(input_{{p}}_ip_source_ip), + .input_{{p}}_ip_dest_ip(input_{{p}}_ip_dest_ip), + .input_{{p}}_ip_payload_tdata(input_{{p}}_ip_payload_tdata), + .input_{{p}}_ip_payload_tvalid(input_{{p}}_ip_payload_tvalid & grant[{{p}}]), + .input_{{p}}_ip_payload_tready(input_{{p}}_ip_payload_tready), + .input_{{p}}_ip_payload_tlast(input_{{p}}_ip_payload_tlast), + .input_{{p}}_ip_payload_tuser(input_{{p}}_ip_payload_tuser), +{%- endfor %} + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS({{n}}), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/ip_arb_mux_4.v b/rtl/ip_arb_mux_4.v new file mode 100644 index 000000000..d181064ef --- /dev/null +++ b/rtl/ip_arb_mux_4.v @@ -0,0 +1,326 @@ +/* + +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 + +/* + * IP 4 port arbitrated multiplexer + */ +module ip_arb_mux_4 # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ + input wire input_0_ip_hdr_valid, + output wire input_0_ip_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [7:0] input_0_ip_payload_tdata, + input wire input_0_ip_payload_tvalid, + output wire input_0_ip_payload_tready, + input wire input_0_ip_payload_tlast, + input wire input_0_ip_payload_tuser, + + input wire input_1_ip_hdr_valid, + output wire input_1_ip_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [7:0] input_1_ip_payload_tdata, + input wire input_1_ip_payload_tvalid, + output wire input_1_ip_payload_tready, + input wire input_1_ip_payload_tlast, + input wire input_1_ip_payload_tuser, + + input wire input_2_ip_hdr_valid, + output wire input_2_ip_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [3:0] input_2_ip_version, + input wire [3:0] input_2_ip_ihl, + input wire [5:0] input_2_ip_dscp, + input wire [1:0] input_2_ip_ecn, + input wire [15:0] input_2_ip_length, + input wire [15:0] input_2_ip_identification, + input wire [2:0] input_2_ip_flags, + input wire [12:0] input_2_ip_fragment_offset, + input wire [7:0] input_2_ip_ttl, + input wire [7:0] input_2_ip_protocol, + input wire [15:0] input_2_ip_header_checksum, + input wire [31:0] input_2_ip_source_ip, + input wire [31:0] input_2_ip_dest_ip, + input wire [7:0] input_2_ip_payload_tdata, + input wire input_2_ip_payload_tvalid, + output wire input_2_ip_payload_tready, + input wire input_2_ip_payload_tlast, + input wire input_2_ip_payload_tuser, + + input wire input_3_ip_hdr_valid, + output wire input_3_ip_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [3:0] input_3_ip_version, + input wire [3:0] input_3_ip_ihl, + input wire [5:0] input_3_ip_dscp, + input wire [1:0] input_3_ip_ecn, + input wire [15:0] input_3_ip_length, + input wire [15:0] input_3_ip_identification, + input wire [2:0] input_3_ip_flags, + input wire [12:0] input_3_ip_fragment_offset, + input wire [7:0] input_3_ip_ttl, + input wire [7:0] input_3_ip_protocol, + input wire [15:0] input_3_ip_header_checksum, + input wire [31:0] input_3_ip_source_ip, + input wire [31:0] input_3_ip_dest_ip, + input wire [7:0] input_3_ip_payload_tdata, + input wire input_3_ip_payload_tvalid, + output wire input_3_ip_payload_tready, + input wire input_3_ip_payload_tlast, + input wire input_3_ip_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser +); + +wire [3:0] request; +wire [3:0] acknowledge; +wire [3:0] grant; +wire grant_valid; +wire [1:0] grant_encoded; + +assign acknowledge[0] = input_0_ip_payload_tvalid & input_0_ip_payload_tready & input_0_ip_payload_tlast; +assign request[0] = input_0_ip_hdr_valid; +assign acknowledge[1] = input_1_ip_payload_tvalid & input_1_ip_payload_tready & input_1_ip_payload_tlast; +assign request[1] = input_1_ip_hdr_valid; +assign acknowledge[2] = input_2_ip_payload_tvalid & input_2_ip_payload_tready & input_2_ip_payload_tlast; +assign request[2] = input_2_ip_hdr_valid; +assign acknowledge[3] = input_3_ip_payload_tvalid & input_3_ip_payload_tready & input_3_ip_payload_tlast; +assign request[3] = input_3_ip_hdr_valid; + +// mux instance +ip_mux_4 +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_ip_hdr_valid(input_0_ip_hdr_valid & grant[0]), + .input_0_ip_hdr_ready(input_0_ip_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_ip_payload_tdata(input_0_ip_payload_tdata), + .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid & grant[0]), + .input_0_ip_payload_tready(input_0_ip_payload_tready), + .input_0_ip_payload_tlast(input_0_ip_payload_tlast), + .input_0_ip_payload_tuser(input_0_ip_payload_tuser), + .input_1_ip_hdr_valid(input_1_ip_hdr_valid & grant[1]), + .input_1_ip_hdr_ready(input_1_ip_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_ip_payload_tdata(input_1_ip_payload_tdata), + .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid & grant[1]), + .input_1_ip_payload_tready(input_1_ip_payload_tready), + .input_1_ip_payload_tlast(input_1_ip_payload_tlast), + .input_1_ip_payload_tuser(input_1_ip_payload_tuser), + .input_2_ip_hdr_valid(input_2_ip_hdr_valid & grant[2]), + .input_2_ip_hdr_ready(input_2_ip_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_ip_payload_tdata(input_2_ip_payload_tdata), + .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid & grant[2]), + .input_2_ip_payload_tready(input_2_ip_payload_tready), + .input_2_ip_payload_tlast(input_2_ip_payload_tlast), + .input_2_ip_payload_tuser(input_2_ip_payload_tuser), + .input_3_ip_hdr_valid(input_3_ip_hdr_valid & grant[3]), + .input_3_ip_hdr_ready(input_3_ip_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_ip_payload_tdata(input_3_ip_payload_tdata), + .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid & grant[3]), + .input_3_ip_payload_tready(input_3_ip_payload_tready), + .input_3_ip_payload_tlast(input_3_ip_payload_tlast), + .input_3_ip_payload_tuser(input_3_ip_payload_tuser), + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/rtl/ip_arb_mux_64.py b/rtl/ip_arb_mux_64.py new file mode 100755 index 000000000..17e10a910 --- /dev/null +++ b/rtl/ip_arb_mux_64.py @@ -0,0 +1,272 @@ +#!/usr/bin/env python +"""ip_arb_mux_64 + +Generates an arbitrated IP mux with the specified number of ports + +Usage: ip_arb_mux_64 [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "ip_arb_mux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * IP {{n}} port arbitrated multiplexer (64 bit datapath) + */ +module {{name}} # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_ip_hdr_valid, + output wire input_{{p}}_ip_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [3:0] input_{{p}}_ip_version, + input wire [3:0] input_{{p}}_ip_ihl, + input wire [5:0] input_{{p}}_ip_dscp, + input wire [1:0] input_{{p}}_ip_ecn, + input wire [15:0] input_{{p}}_ip_length, + input wire [15:0] input_{{p}}_ip_identification, + input wire [2:0] input_{{p}}_ip_flags, + input wire [12:0] input_{{p}}_ip_fragment_offset, + input wire [7:0] input_{{p}}_ip_ttl, + input wire [7:0] input_{{p}}_ip_protocol, + input wire [15:0] input_{{p}}_ip_header_checksum, + input wire [31:0] input_{{p}}_ip_source_ip, + input wire [31:0] input_{{p}}_ip_dest_ip, + input wire [63:0] input_{{p}}_ip_payload_tdata, + input wire [7:0] input_{{p}}_ip_payload_tkeep, + input wire input_{{p}}_ip_payload_tvalid, + output wire input_{{p}}_ip_payload_tready, + input wire input_{{p}}_ip_payload_tlast, + input wire input_{{p}}_ip_payload_tuser, +{% endfor %} + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser +); + +wire [{{n-1}}:0] request; +wire [{{n-1}}:0] acknowledge; +wire [{{n-1}}:0] grant; +wire grant_valid; +wire [{{w-1}}:0] grant_encoded; +{% for p in ports %} +assign acknowledge[{{p}}] = input_{{p}}_ip_payload_tvalid & input_{{p}}_ip_payload_tready & input_{{p}}_ip_payload_tlast; +assign request[{{p}}] = input_{{p}}_ip_hdr_valid; +{%- endfor %} + +// mux instance +ip_mux_64_{{n}} +mux_inst ( + .clk(clk), + .rst(rst), +{%- for p in ports %} + .input_{{p}}_ip_hdr_valid(input_{{p}}_ip_hdr_valid & grant[{{p}}]), + .input_{{p}}_ip_hdr_ready(input_{{p}}_ip_hdr_ready), + .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), + .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), + .input_{{p}}_eth_type(input_{{p}}_eth_type), + .input_{{p}}_ip_version(input_{{p}}_ip_version), + .input_{{p}}_ip_ihl(input_{{p}}_ip_ihl), + .input_{{p}}_ip_dscp(input_{{p}}_ip_dscp), + .input_{{p}}_ip_ecn(input_{{p}}_ip_ecn), + .input_{{p}}_ip_length(input_{{p}}_ip_length), + .input_{{p}}_ip_identification(input_{{p}}_ip_identification), + .input_{{p}}_ip_flags(input_{{p}}_ip_flags), + .input_{{p}}_ip_fragment_offset(input_{{p}}_ip_fragment_offset), + .input_{{p}}_ip_ttl(input_{{p}}_ip_ttl), + .input_{{p}}_ip_protocol(input_{{p}}_ip_protocol), + .input_{{p}}_ip_header_checksum(input_{{p}}_ip_header_checksum), + .input_{{p}}_ip_source_ip(input_{{p}}_ip_source_ip), + .input_{{p}}_ip_dest_ip(input_{{p}}_ip_dest_ip), + .input_{{p}}_ip_payload_tdata(input_{{p}}_ip_payload_tdata), + .input_{{p}}_ip_payload_tkeep(input_{{p}}_ip_payload_tkeep), + .input_{{p}}_ip_payload_tvalid(input_{{p}}_ip_payload_tvalid & grant[{{p}}]), + .input_{{p}}_ip_payload_tready(input_{{p}}_ip_payload_tready), + .input_{{p}}_ip_payload_tlast(input_{{p}}_ip_payload_tlast), + .input_{{p}}_ip_payload_tuser(input_{{p}}_ip_payload_tuser), +{%- endfor %} + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS({{n}}), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/ip_arb_mux_64_4.v b/rtl/ip_arb_mux_64_4.v new file mode 100644 index 000000000..0803be0c0 --- /dev/null +++ b/rtl/ip_arb_mux_64_4.v @@ -0,0 +1,336 @@ +/* + +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 + +/* + * IP 4 port arbitrated multiplexer (64 bit datapath) + */ +module ip_arb_mux_64_4 # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ + input wire input_0_ip_hdr_valid, + output wire input_0_ip_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [63:0] input_0_ip_payload_tdata, + input wire [7:0] input_0_ip_payload_tkeep, + input wire input_0_ip_payload_tvalid, + output wire input_0_ip_payload_tready, + input wire input_0_ip_payload_tlast, + input wire input_0_ip_payload_tuser, + + input wire input_1_ip_hdr_valid, + output wire input_1_ip_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [63:0] input_1_ip_payload_tdata, + input wire [7:0] input_1_ip_payload_tkeep, + input wire input_1_ip_payload_tvalid, + output wire input_1_ip_payload_tready, + input wire input_1_ip_payload_tlast, + input wire input_1_ip_payload_tuser, + + input wire input_2_ip_hdr_valid, + output wire input_2_ip_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [3:0] input_2_ip_version, + input wire [3:0] input_2_ip_ihl, + input wire [5:0] input_2_ip_dscp, + input wire [1:0] input_2_ip_ecn, + input wire [15:0] input_2_ip_length, + input wire [15:0] input_2_ip_identification, + input wire [2:0] input_2_ip_flags, + input wire [12:0] input_2_ip_fragment_offset, + input wire [7:0] input_2_ip_ttl, + input wire [7:0] input_2_ip_protocol, + input wire [15:0] input_2_ip_header_checksum, + input wire [31:0] input_2_ip_source_ip, + input wire [31:0] input_2_ip_dest_ip, + input wire [63:0] input_2_ip_payload_tdata, + input wire [7:0] input_2_ip_payload_tkeep, + input wire input_2_ip_payload_tvalid, + output wire input_2_ip_payload_tready, + input wire input_2_ip_payload_tlast, + input wire input_2_ip_payload_tuser, + + input wire input_3_ip_hdr_valid, + output wire input_3_ip_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [3:0] input_3_ip_version, + input wire [3:0] input_3_ip_ihl, + input wire [5:0] input_3_ip_dscp, + input wire [1:0] input_3_ip_ecn, + input wire [15:0] input_3_ip_length, + input wire [15:0] input_3_ip_identification, + input wire [2:0] input_3_ip_flags, + input wire [12:0] input_3_ip_fragment_offset, + input wire [7:0] input_3_ip_ttl, + input wire [7:0] input_3_ip_protocol, + input wire [15:0] input_3_ip_header_checksum, + input wire [31:0] input_3_ip_source_ip, + input wire [31:0] input_3_ip_dest_ip, + input wire [63:0] input_3_ip_payload_tdata, + input wire [7:0] input_3_ip_payload_tkeep, + input wire input_3_ip_payload_tvalid, + output wire input_3_ip_payload_tready, + input wire input_3_ip_payload_tlast, + input wire input_3_ip_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser +); + +wire [3:0] request; +wire [3:0] acknowledge; +wire [3:0] grant; +wire grant_valid; +wire [1:0] grant_encoded; + +assign acknowledge[0] = input_0_ip_payload_tvalid & input_0_ip_payload_tready & input_0_ip_payload_tlast; +assign request[0] = input_0_ip_hdr_valid; +assign acknowledge[1] = input_1_ip_payload_tvalid & input_1_ip_payload_tready & input_1_ip_payload_tlast; +assign request[1] = input_1_ip_hdr_valid; +assign acknowledge[2] = input_2_ip_payload_tvalid & input_2_ip_payload_tready & input_2_ip_payload_tlast; +assign request[2] = input_2_ip_hdr_valid; +assign acknowledge[3] = input_3_ip_payload_tvalid & input_3_ip_payload_tready & input_3_ip_payload_tlast; +assign request[3] = input_3_ip_hdr_valid; + +// mux instance +ip_mux_64_4 +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_ip_hdr_valid(input_0_ip_hdr_valid & grant[0]), + .input_0_ip_hdr_ready(input_0_ip_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_ip_payload_tdata(input_0_ip_payload_tdata), + .input_0_ip_payload_tkeep(input_0_ip_payload_tkeep), + .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid & grant[0]), + .input_0_ip_payload_tready(input_0_ip_payload_tready), + .input_0_ip_payload_tlast(input_0_ip_payload_tlast), + .input_0_ip_payload_tuser(input_0_ip_payload_tuser), + .input_1_ip_hdr_valid(input_1_ip_hdr_valid & grant[1]), + .input_1_ip_hdr_ready(input_1_ip_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_ip_payload_tdata(input_1_ip_payload_tdata), + .input_1_ip_payload_tkeep(input_1_ip_payload_tkeep), + .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid & grant[1]), + .input_1_ip_payload_tready(input_1_ip_payload_tready), + .input_1_ip_payload_tlast(input_1_ip_payload_tlast), + .input_1_ip_payload_tuser(input_1_ip_payload_tuser), + .input_2_ip_hdr_valid(input_2_ip_hdr_valid & grant[2]), + .input_2_ip_hdr_ready(input_2_ip_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_ip_payload_tdata(input_2_ip_payload_tdata), + .input_2_ip_payload_tkeep(input_2_ip_payload_tkeep), + .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid & grant[2]), + .input_2_ip_payload_tready(input_2_ip_payload_tready), + .input_2_ip_payload_tlast(input_2_ip_payload_tlast), + .input_2_ip_payload_tuser(input_2_ip_payload_tuser), + .input_3_ip_hdr_valid(input_3_ip_hdr_valid & grant[3]), + .input_3_ip_hdr_ready(input_3_ip_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_ip_payload_tdata(input_3_ip_payload_tdata), + .input_3_ip_payload_tkeep(input_3_ip_payload_tkeep), + .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid & grant[3]), + .input_3_ip_payload_tready(input_3_ip_payload_tready), + .input_3_ip_payload_tlast(input_3_ip_payload_tlast), + .input_3_ip_payload_tuser(input_3_ip_payload_tuser), + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/tb/test_ip_arb_mux_4.py b/tb/test_ip_arb_mux_4.py new file mode 100755 index 000000000..c68bb1a70 --- /dev/null +++ b/tb/test_ip_arb_mux_4.py @@ -0,0 +1,1191 @@ +#!/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 ip_ep + +module = 'ip_arb_mux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/ip_mux_4.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_ip_arb_mux_4(clk, + rst, + current_test, + + input_0_ip_hdr_valid, + input_0_ip_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tvalid, + input_0_ip_payload_tready, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_ip_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tvalid, + input_1_ip_payload_tready, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_ip_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tvalid, + input_2_ip_payload_tready, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_ip_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tvalid, + input_3_ip_payload_tready, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_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_0_ip_hdr_valid=input_0_ip_hdr_valid, + input_0_ip_hdr_ready=input_0_ip_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_ip_version=input_0_ip_version, + input_0_ip_ihl=input_0_ip_ihl, + input_0_ip_dscp=input_0_ip_dscp, + input_0_ip_ecn=input_0_ip_ecn, + input_0_ip_length=input_0_ip_length, + input_0_ip_identification=input_0_ip_identification, + input_0_ip_flags=input_0_ip_flags, + input_0_ip_fragment_offset=input_0_ip_fragment_offset, + input_0_ip_ttl=input_0_ip_ttl, + input_0_ip_protocol=input_0_ip_protocol, + input_0_ip_header_checksum=input_0_ip_header_checksum, + input_0_ip_source_ip=input_0_ip_source_ip, + input_0_ip_dest_ip=input_0_ip_dest_ip, + input_0_ip_payload_tdata=input_0_ip_payload_tdata, + input_0_ip_payload_tvalid=input_0_ip_payload_tvalid, + input_0_ip_payload_tready=input_0_ip_payload_tready, + input_0_ip_payload_tlast=input_0_ip_payload_tlast, + input_0_ip_payload_tuser=input_0_ip_payload_tuser, + input_1_ip_hdr_valid=input_1_ip_hdr_valid, + input_1_ip_hdr_ready=input_1_ip_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_ip_version=input_1_ip_version, + input_1_ip_ihl=input_1_ip_ihl, + input_1_ip_dscp=input_1_ip_dscp, + input_1_ip_ecn=input_1_ip_ecn, + input_1_ip_length=input_1_ip_length, + input_1_ip_identification=input_1_ip_identification, + input_1_ip_flags=input_1_ip_flags, + input_1_ip_fragment_offset=input_1_ip_fragment_offset, + input_1_ip_ttl=input_1_ip_ttl, + input_1_ip_protocol=input_1_ip_protocol, + input_1_ip_header_checksum=input_1_ip_header_checksum, + input_1_ip_source_ip=input_1_ip_source_ip, + input_1_ip_dest_ip=input_1_ip_dest_ip, + input_1_ip_payload_tdata=input_1_ip_payload_tdata, + input_1_ip_payload_tvalid=input_1_ip_payload_tvalid, + input_1_ip_payload_tready=input_1_ip_payload_tready, + input_1_ip_payload_tlast=input_1_ip_payload_tlast, + input_1_ip_payload_tuser=input_1_ip_payload_tuser, + input_2_ip_hdr_valid=input_2_ip_hdr_valid, + input_2_ip_hdr_ready=input_2_ip_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_ip_version=input_2_ip_version, + input_2_ip_ihl=input_2_ip_ihl, + input_2_ip_dscp=input_2_ip_dscp, + input_2_ip_ecn=input_2_ip_ecn, + input_2_ip_length=input_2_ip_length, + input_2_ip_identification=input_2_ip_identification, + input_2_ip_flags=input_2_ip_flags, + input_2_ip_fragment_offset=input_2_ip_fragment_offset, + input_2_ip_ttl=input_2_ip_ttl, + input_2_ip_protocol=input_2_ip_protocol, + input_2_ip_header_checksum=input_2_ip_header_checksum, + input_2_ip_source_ip=input_2_ip_source_ip, + input_2_ip_dest_ip=input_2_ip_dest_ip, + input_2_ip_payload_tdata=input_2_ip_payload_tdata, + input_2_ip_payload_tvalid=input_2_ip_payload_tvalid, + input_2_ip_payload_tready=input_2_ip_payload_tready, + input_2_ip_payload_tlast=input_2_ip_payload_tlast, + input_2_ip_payload_tuser=input_2_ip_payload_tuser, + input_3_ip_hdr_valid=input_3_ip_hdr_valid, + input_3_ip_hdr_ready=input_3_ip_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_ip_version=input_3_ip_version, + input_3_ip_ihl=input_3_ip_ihl, + input_3_ip_dscp=input_3_ip_dscp, + input_3_ip_ecn=input_3_ip_ecn, + input_3_ip_length=input_3_ip_length, + input_3_ip_identification=input_3_ip_identification, + input_3_ip_flags=input_3_ip_flags, + input_3_ip_fragment_offset=input_3_ip_fragment_offset, + input_3_ip_ttl=input_3_ip_ttl, + input_3_ip_protocol=input_3_ip_protocol, + input_3_ip_header_checksum=input_3_ip_header_checksum, + input_3_ip_source_ip=input_3_ip_source_ip, + input_3_ip_dest_ip=input_3_ip_dest_ip, + input_3_ip_payload_tdata=input_3_ip_payload_tdata, + input_3_ip_payload_tvalid=input_3_ip_payload_tvalid, + input_3_ip_payload_tready=input_3_ip_payload_tready, + input_3_ip_payload_tlast=input_3_ip_payload_tlast, + input_3_ip_payload_tuser=input_3_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_ip_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_ip_version = Signal(intbv(0)[4:]) + input_0_ip_ihl = Signal(intbv(0)[4:]) + input_0_ip_dscp = Signal(intbv(0)[6:]) + input_0_ip_ecn = Signal(intbv(0)[2:]) + input_0_ip_length = Signal(intbv(0)[16:]) + input_0_ip_identification = Signal(intbv(0)[16:]) + input_0_ip_flags = Signal(intbv(0)[3:]) + input_0_ip_fragment_offset = Signal(intbv(0)[13:]) + input_0_ip_ttl = Signal(intbv(0)[8:]) + input_0_ip_protocol = Signal(intbv(0)[8:]) + input_0_ip_header_checksum = Signal(intbv(0)[16:]) + input_0_ip_source_ip = Signal(intbv(0)[32:]) + input_0_ip_dest_ip = Signal(intbv(0)[32:]) + input_0_ip_payload_tdata = Signal(intbv(0)[8:]) + input_0_ip_payload_tvalid = Signal(bool(0)) + input_0_ip_payload_tlast = Signal(bool(0)) + input_0_ip_payload_tuser = Signal(bool(0)) + input_1_ip_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_ip_version = Signal(intbv(0)[4:]) + input_1_ip_ihl = Signal(intbv(0)[4:]) + input_1_ip_dscp = Signal(intbv(0)[6:]) + input_1_ip_ecn = Signal(intbv(0)[2:]) + input_1_ip_length = Signal(intbv(0)[16:]) + input_1_ip_identification = Signal(intbv(0)[16:]) + input_1_ip_flags = Signal(intbv(0)[3:]) + input_1_ip_fragment_offset = Signal(intbv(0)[13:]) + input_1_ip_ttl = Signal(intbv(0)[8:]) + input_1_ip_protocol = Signal(intbv(0)[8:]) + input_1_ip_header_checksum = Signal(intbv(0)[16:]) + input_1_ip_source_ip = Signal(intbv(0)[32:]) + input_1_ip_dest_ip = Signal(intbv(0)[32:]) + input_1_ip_payload_tdata = Signal(intbv(0)[8:]) + input_1_ip_payload_tvalid = Signal(bool(0)) + input_1_ip_payload_tlast = Signal(bool(0)) + input_1_ip_payload_tuser = Signal(bool(0)) + input_2_ip_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_ip_version = Signal(intbv(0)[4:]) + input_2_ip_ihl = Signal(intbv(0)[4:]) + input_2_ip_dscp = Signal(intbv(0)[6:]) + input_2_ip_ecn = Signal(intbv(0)[2:]) + input_2_ip_length = Signal(intbv(0)[16:]) + input_2_ip_identification = Signal(intbv(0)[16:]) + input_2_ip_flags = Signal(intbv(0)[3:]) + input_2_ip_fragment_offset = Signal(intbv(0)[13:]) + input_2_ip_ttl = Signal(intbv(0)[8:]) + input_2_ip_protocol = Signal(intbv(0)[8:]) + input_2_ip_header_checksum = Signal(intbv(0)[16:]) + input_2_ip_source_ip = Signal(intbv(0)[32:]) + input_2_ip_dest_ip = Signal(intbv(0)[32:]) + input_2_ip_payload_tdata = Signal(intbv(0)[8:]) + input_2_ip_payload_tvalid = Signal(bool(0)) + input_2_ip_payload_tlast = Signal(bool(0)) + input_2_ip_payload_tuser = Signal(bool(0)) + input_3_ip_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_ip_version = Signal(intbv(0)[4:]) + input_3_ip_ihl = Signal(intbv(0)[4:]) + input_3_ip_dscp = Signal(intbv(0)[6:]) + input_3_ip_ecn = Signal(intbv(0)[2:]) + input_3_ip_length = Signal(intbv(0)[16:]) + input_3_ip_identification = Signal(intbv(0)[16:]) + input_3_ip_flags = Signal(intbv(0)[3:]) + input_3_ip_fragment_offset = Signal(intbv(0)[13:]) + input_3_ip_ttl = Signal(intbv(0)[8:]) + input_3_ip_protocol = Signal(intbv(0)[8:]) + input_3_ip_header_checksum = Signal(intbv(0)[16:]) + input_3_ip_source_ip = Signal(intbv(0)[32:]) + input_3_ip_dest_ip = Signal(intbv(0)[32:]) + input_3_ip_payload_tdata = Signal(intbv(0)[8:]) + input_3_ip_payload_tvalid = Signal(bool(0)) + input_3_ip_payload_tlast = Signal(bool(0)) + input_3_ip_payload_tuser = Signal(bool(0)) + + output_ip_payload_tready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + + # Outputs + input_0_ip_hdr_ready = Signal(bool(0)) + input_0_ip_payload_tready = Signal(bool(0)) + input_1_ip_hdr_ready = Signal(bool(0)) + input_1_ip_payload_tready = Signal(bool(0)) + input_2_ip_hdr_ready = Signal(bool(0)) + input_2_ip_payload_tready = Signal(bool(0)) + input_3_ip_hdr_ready = Signal(bool(0)) + input_3_ip_payload_tready = Signal(bool(0)) + + output_ip_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_0_ip_hdr_ready, + ip_hdr_valid=input_0_ip_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + ip_version=input_0_ip_version, + ip_ihl=input_0_ip_ihl, + ip_dscp=input_0_ip_dscp, + ip_ecn=input_0_ip_ecn, + ip_length=input_0_ip_length, + ip_identification=input_0_ip_identification, + ip_flags=input_0_ip_flags, + ip_fragment_offset=input_0_ip_fragment_offset, + ip_ttl=input_0_ip_ttl, + ip_protocol=input_0_ip_protocol, + ip_header_checksum=input_0_ip_header_checksum, + ip_source_ip=input_0_ip_source_ip, + ip_dest_ip=input_0_ip_dest_ip, + ip_payload_tdata=input_0_ip_payload_tdata, + ip_payload_tvalid=input_0_ip_payload_tvalid, + ip_payload_tready=input_0_ip_payload_tready, + ip_payload_tlast=input_0_ip_payload_tlast, + ip_payload_tuser=input_0_ip_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_1_ip_hdr_ready, + ip_hdr_valid=input_1_ip_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + ip_version=input_1_ip_version, + ip_ihl=input_1_ip_ihl, + ip_dscp=input_1_ip_dscp, + ip_ecn=input_1_ip_ecn, + ip_length=input_1_ip_length, + ip_identification=input_1_ip_identification, + ip_flags=input_1_ip_flags, + ip_fragment_offset=input_1_ip_fragment_offset, + ip_ttl=input_1_ip_ttl, + ip_protocol=input_1_ip_protocol, + ip_header_checksum=input_1_ip_header_checksum, + ip_source_ip=input_1_ip_source_ip, + ip_dest_ip=input_1_ip_dest_ip, + ip_payload_tdata=input_1_ip_payload_tdata, + ip_payload_tvalid=input_1_ip_payload_tvalid, + ip_payload_tready=input_1_ip_payload_tready, + ip_payload_tlast=input_1_ip_payload_tlast, + ip_payload_tuser=input_1_ip_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_2_ip_hdr_ready, + ip_hdr_valid=input_2_ip_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + ip_version=input_2_ip_version, + ip_ihl=input_2_ip_ihl, + ip_dscp=input_2_ip_dscp, + ip_ecn=input_2_ip_ecn, + ip_length=input_2_ip_length, + ip_identification=input_2_ip_identification, + ip_flags=input_2_ip_flags, + ip_fragment_offset=input_2_ip_fragment_offset, + ip_ttl=input_2_ip_ttl, + ip_protocol=input_2_ip_protocol, + ip_header_checksum=input_2_ip_header_checksum, + ip_source_ip=input_2_ip_source_ip, + ip_dest_ip=input_2_ip_dest_ip, + ip_payload_tdata=input_2_ip_payload_tdata, + ip_payload_tvalid=input_2_ip_payload_tvalid, + ip_payload_tready=input_2_ip_payload_tready, + ip_payload_tlast=input_2_ip_payload_tlast, + ip_payload_tuser=input_2_ip_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_3_ip_hdr_ready, + ip_hdr_valid=input_3_ip_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + ip_version=input_3_ip_version, + ip_ihl=input_3_ip_ihl, + ip_dscp=input_3_ip_dscp, + ip_ecn=input_3_ip_ecn, + ip_length=input_3_ip_length, + ip_identification=input_3_ip_identification, + ip_flags=input_3_ip_flags, + ip_fragment_offset=input_3_ip_fragment_offset, + ip_ttl=input_3_ip_ttl, + ip_protocol=input_3_ip_protocol, + ip_header_checksum=input_3_ip_header_checksum, + ip_source_ip=input_3_ip_source_ip, + ip_dest_ip=input_3_ip_dest_ip, + ip_payload_tdata=input_3_ip_payload_tdata, + ip_payload_tvalid=input_3_ip_payload_tvalid, + ip_payload_tready=input_3_ip_payload_tready, + ip_payload_tlast=input_3_ip_payload_tlast, + ip_payload_tuser=input_3_ip_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_ip_arb_mux_4(clk, + rst, + current_test, + + input_0_ip_hdr_valid, + input_0_ip_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tvalid, + input_0_ip_payload_tready, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_ip_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tvalid, + input_1_ip_payload_tready, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_ip_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tvalid, + input_2_ip_payload_tready, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_ip_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tvalid, + input_3_ip_payload_tready, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_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: port 0") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: port 1") + current_test.next = 2 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + 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 5: alterate pause source") + current_test.next = 5 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == 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: alterate pause sink") + current_test.next = 6 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_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 + 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: back-to-back packets, different ports, arbitration test") + current_test.next = 7 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + yield clk.posedge + + yield delay(800) + yield clk.posedge + source_1_queue.put(test_frame1) + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + 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 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_arb_mux_4.v b/tb/test_ip_arb_mux_4.v new file mode 100644 index 000000000..5270e0643 --- /dev/null +++ b/tb/test_ip_arb_mux_4.v @@ -0,0 +1,405 @@ +/* + +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_ip_arb_mux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_ip_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [3:0] input_0_ip_version = 0; +reg [3:0] input_0_ip_ihl = 0; +reg [5:0] input_0_ip_dscp = 0; +reg [1:0] input_0_ip_ecn = 0; +reg [15:0] input_0_ip_length = 0; +reg [15:0] input_0_ip_identification = 0; +reg [2:0] input_0_ip_flags = 0; +reg [12:0] input_0_ip_fragment_offset = 0; +reg [7:0] input_0_ip_ttl = 0; +reg [7:0] input_0_ip_protocol = 0; +reg [15:0] input_0_ip_header_checksum = 0; +reg [31:0] input_0_ip_source_ip = 0; +reg [31:0] input_0_ip_dest_ip = 0; +reg [7:0] input_0_ip_payload_tdata = 0; +reg input_0_ip_payload_tvalid = 0; +reg input_0_ip_payload_tlast = 0; +reg input_0_ip_payload_tuser = 0; +reg input_1_ip_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [3:0] input_1_ip_version = 0; +reg [3:0] input_1_ip_ihl = 0; +reg [5:0] input_1_ip_dscp = 0; +reg [1:0] input_1_ip_ecn = 0; +reg [15:0] input_1_ip_length = 0; +reg [15:0] input_1_ip_identification = 0; +reg [2:0] input_1_ip_flags = 0; +reg [12:0] input_1_ip_fragment_offset = 0; +reg [7:0] input_1_ip_ttl = 0; +reg [7:0] input_1_ip_protocol = 0; +reg [15:0] input_1_ip_header_checksum = 0; +reg [31:0] input_1_ip_source_ip = 0; +reg [31:0] input_1_ip_dest_ip = 0; +reg [7:0] input_1_ip_payload_tdata = 0; +reg input_1_ip_payload_tvalid = 0; +reg input_1_ip_payload_tlast = 0; +reg input_1_ip_payload_tuser = 0; +reg input_2_ip_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [3:0] input_2_ip_version = 0; +reg [3:0] input_2_ip_ihl = 0; +reg [5:0] input_2_ip_dscp = 0; +reg [1:0] input_2_ip_ecn = 0; +reg [15:0] input_2_ip_length = 0; +reg [15:0] input_2_ip_identification = 0; +reg [2:0] input_2_ip_flags = 0; +reg [12:0] input_2_ip_fragment_offset = 0; +reg [7:0] input_2_ip_ttl = 0; +reg [7:0] input_2_ip_protocol = 0; +reg [15:0] input_2_ip_header_checksum = 0; +reg [31:0] input_2_ip_source_ip = 0; +reg [31:0] input_2_ip_dest_ip = 0; +reg [7:0] input_2_ip_payload_tdata = 0; +reg input_2_ip_payload_tvalid = 0; +reg input_2_ip_payload_tlast = 0; +reg input_2_ip_payload_tuser = 0; +reg input_3_ip_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [3:0] input_3_ip_version = 0; +reg [3:0] input_3_ip_ihl = 0; +reg [5:0] input_3_ip_dscp = 0; +reg [1:0] input_3_ip_ecn = 0; +reg [15:0] input_3_ip_length = 0; +reg [15:0] input_3_ip_identification = 0; +reg [2:0] input_3_ip_flags = 0; +reg [12:0] input_3_ip_fragment_offset = 0; +reg [7:0] input_3_ip_ttl = 0; +reg [7:0] input_3_ip_protocol = 0; +reg [15:0] input_3_ip_header_checksum = 0; +reg [31:0] input_3_ip_source_ip = 0; +reg [31:0] input_3_ip_dest_ip = 0; +reg [7:0] input_3_ip_payload_tdata = 0; +reg input_3_ip_payload_tvalid = 0; +reg input_3_ip_payload_tlast = 0; +reg input_3_ip_payload_tuser = 0; + +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; + +// Outputs +wire input_0_ip_payload_tready; +wire input_0_ip_hdr_ready; +wire input_1_ip_payload_tready; +wire input_1_ip_hdr_ready; +wire input_2_ip_payload_tready; +wire input_2_ip_hdr_ready; +wire input_3_ip_payload_tready; +wire input_3_ip_hdr_ready; + +wire output_ip_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [7:0] output_ip_payload_tdata; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_ip_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tvalid, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tvalid, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tvalid, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tvalid, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + output_ip_hdr_ready, + output_ip_payload_tready); + $to_myhdl(input_0_ip_hdr_ready, + input_0_ip_payload_tready, + input_1_ip_hdr_ready, + input_1_ip_payload_tready, + input_2_ip_hdr_ready, + input_2_ip_payload_tready, + input_3_ip_hdr_ready, + input_3_ip_payload_tready, + output_ip_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser); + + // dump file + $dumpfile("test_ip_arb_mux_4.lxt"); + $dumpvars(0, test_ip_arb_mux_4); +end + +ip_arb_mux_4 +UUT ( + .clk(clk), + .rst(rst), + // IP frame inputs + .input_0_ip_hdr_valid(input_0_ip_hdr_valid), + .input_0_ip_hdr_ready(input_0_ip_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_ip_payload_tdata(input_0_ip_payload_tdata), + .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid), + .input_0_ip_payload_tready(input_0_ip_payload_tready), + .input_0_ip_payload_tlast(input_0_ip_payload_tlast), + .input_0_ip_payload_tuser(input_0_ip_payload_tuser), + .input_1_ip_hdr_valid(input_1_ip_hdr_valid), + .input_1_ip_hdr_ready(input_1_ip_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_ip_payload_tdata(input_1_ip_payload_tdata), + .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid), + .input_1_ip_payload_tready(input_1_ip_payload_tready), + .input_1_ip_payload_tlast(input_1_ip_payload_tlast), + .input_1_ip_payload_tuser(input_1_ip_payload_tuser), + .input_2_ip_hdr_valid(input_2_ip_hdr_valid), + .input_2_ip_hdr_ready(input_2_ip_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_ip_payload_tdata(input_2_ip_payload_tdata), + .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid), + .input_2_ip_payload_tready(input_2_ip_payload_tready), + .input_2_ip_payload_tlast(input_2_ip_payload_tlast), + .input_2_ip_payload_tuser(input_2_ip_payload_tuser), + .input_3_ip_hdr_valid(input_3_ip_hdr_valid), + .input_3_ip_hdr_ready(input_3_ip_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_ip_payload_tdata(input_3_ip_payload_tdata), + .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid), + .input_3_ip_payload_tready(input_3_ip_payload_tready), + .input_3_ip_payload_tlast(input_3_ip_payload_tlast), + .input_3_ip_payload_tuser(input_3_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser) +); + +endmodule diff --git a/tb/test_ip_arb_mux_64_4.py b/tb/test_ip_arb_mux_64_4.py new file mode 100755 index 000000000..f9b2f9666 --- /dev/null +++ b/tb/test_ip_arb_mux_64_4.py @@ -0,0 +1,1216 @@ +#!/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 ip_ep + +module = 'ip_arb_mux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/ip_mux_64_4.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_ip_arb_mux_64_4(clk, + rst, + current_test, + + input_0_ip_hdr_valid, + input_0_ip_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tkeep, + input_0_ip_payload_tvalid, + input_0_ip_payload_tready, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_ip_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tkeep, + input_1_ip_payload_tvalid, + input_1_ip_payload_tready, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_ip_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tkeep, + input_2_ip_payload_tvalid, + input_2_ip_payload_tready, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_ip_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tkeep, + input_3_ip_payload_tvalid, + input_3_ip_payload_tready, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_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_0_ip_hdr_valid=input_0_ip_hdr_valid, + input_0_ip_hdr_ready=input_0_ip_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_ip_version=input_0_ip_version, + input_0_ip_ihl=input_0_ip_ihl, + input_0_ip_dscp=input_0_ip_dscp, + input_0_ip_ecn=input_0_ip_ecn, + input_0_ip_length=input_0_ip_length, + input_0_ip_identification=input_0_ip_identification, + input_0_ip_flags=input_0_ip_flags, + input_0_ip_fragment_offset=input_0_ip_fragment_offset, + input_0_ip_ttl=input_0_ip_ttl, + input_0_ip_protocol=input_0_ip_protocol, + input_0_ip_header_checksum=input_0_ip_header_checksum, + input_0_ip_source_ip=input_0_ip_source_ip, + input_0_ip_dest_ip=input_0_ip_dest_ip, + input_0_ip_payload_tdata=input_0_ip_payload_tdata, + input_0_ip_payload_tkeep=input_0_ip_payload_tkeep, + input_0_ip_payload_tvalid=input_0_ip_payload_tvalid, + input_0_ip_payload_tready=input_0_ip_payload_tready, + input_0_ip_payload_tlast=input_0_ip_payload_tlast, + input_0_ip_payload_tuser=input_0_ip_payload_tuser, + input_1_ip_hdr_valid=input_1_ip_hdr_valid, + input_1_ip_hdr_ready=input_1_ip_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_ip_version=input_1_ip_version, + input_1_ip_ihl=input_1_ip_ihl, + input_1_ip_dscp=input_1_ip_dscp, + input_1_ip_ecn=input_1_ip_ecn, + input_1_ip_length=input_1_ip_length, + input_1_ip_identification=input_1_ip_identification, + input_1_ip_flags=input_1_ip_flags, + input_1_ip_fragment_offset=input_1_ip_fragment_offset, + input_1_ip_ttl=input_1_ip_ttl, + input_1_ip_protocol=input_1_ip_protocol, + input_1_ip_header_checksum=input_1_ip_header_checksum, + input_1_ip_source_ip=input_1_ip_source_ip, + input_1_ip_dest_ip=input_1_ip_dest_ip, + input_1_ip_payload_tdata=input_1_ip_payload_tdata, + input_1_ip_payload_tkeep=input_1_ip_payload_tkeep, + input_1_ip_payload_tvalid=input_1_ip_payload_tvalid, + input_1_ip_payload_tready=input_1_ip_payload_tready, + input_1_ip_payload_tlast=input_1_ip_payload_tlast, + input_1_ip_payload_tuser=input_1_ip_payload_tuser, + input_2_ip_hdr_valid=input_2_ip_hdr_valid, + input_2_ip_hdr_ready=input_2_ip_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_ip_version=input_2_ip_version, + input_2_ip_ihl=input_2_ip_ihl, + input_2_ip_dscp=input_2_ip_dscp, + input_2_ip_ecn=input_2_ip_ecn, + input_2_ip_length=input_2_ip_length, + input_2_ip_identification=input_2_ip_identification, + input_2_ip_flags=input_2_ip_flags, + input_2_ip_fragment_offset=input_2_ip_fragment_offset, + input_2_ip_ttl=input_2_ip_ttl, + input_2_ip_protocol=input_2_ip_protocol, + input_2_ip_header_checksum=input_2_ip_header_checksum, + input_2_ip_source_ip=input_2_ip_source_ip, + input_2_ip_dest_ip=input_2_ip_dest_ip, + input_2_ip_payload_tdata=input_2_ip_payload_tdata, + input_2_ip_payload_tkeep=input_2_ip_payload_tkeep, + input_2_ip_payload_tvalid=input_2_ip_payload_tvalid, + input_2_ip_payload_tready=input_2_ip_payload_tready, + input_2_ip_payload_tlast=input_2_ip_payload_tlast, + input_2_ip_payload_tuser=input_2_ip_payload_tuser, + input_3_ip_hdr_valid=input_3_ip_hdr_valid, + input_3_ip_hdr_ready=input_3_ip_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_ip_version=input_3_ip_version, + input_3_ip_ihl=input_3_ip_ihl, + input_3_ip_dscp=input_3_ip_dscp, + input_3_ip_ecn=input_3_ip_ecn, + input_3_ip_length=input_3_ip_length, + input_3_ip_identification=input_3_ip_identification, + input_3_ip_flags=input_3_ip_flags, + input_3_ip_fragment_offset=input_3_ip_fragment_offset, + input_3_ip_ttl=input_3_ip_ttl, + input_3_ip_protocol=input_3_ip_protocol, + input_3_ip_header_checksum=input_3_ip_header_checksum, + input_3_ip_source_ip=input_3_ip_source_ip, + input_3_ip_dest_ip=input_3_ip_dest_ip, + input_3_ip_payload_tdata=input_3_ip_payload_tdata, + input_3_ip_payload_tkeep=input_3_ip_payload_tkeep, + input_3_ip_payload_tvalid=input_3_ip_payload_tvalid, + input_3_ip_payload_tready=input_3_ip_payload_tready, + input_3_ip_payload_tlast=input_3_ip_payload_tlast, + input_3_ip_payload_tuser=input_3_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tkeep=output_ip_payload_tkeep, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_ip_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_ip_version = Signal(intbv(0)[4:]) + input_0_ip_ihl = Signal(intbv(0)[4:]) + input_0_ip_dscp = Signal(intbv(0)[6:]) + input_0_ip_ecn = Signal(intbv(0)[2:]) + input_0_ip_length = Signal(intbv(0)[16:]) + input_0_ip_identification = Signal(intbv(0)[16:]) + input_0_ip_flags = Signal(intbv(0)[3:]) + input_0_ip_fragment_offset = Signal(intbv(0)[13:]) + input_0_ip_ttl = Signal(intbv(0)[8:]) + input_0_ip_protocol = Signal(intbv(0)[8:]) + input_0_ip_header_checksum = Signal(intbv(0)[16:]) + input_0_ip_source_ip = Signal(intbv(0)[32:]) + input_0_ip_dest_ip = Signal(intbv(0)[32:]) + input_0_ip_payload_tdata = Signal(intbv(0)[64:]) + input_0_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_0_ip_payload_tvalid = Signal(bool(0)) + input_0_ip_payload_tlast = Signal(bool(0)) + input_0_ip_payload_tuser = Signal(bool(0)) + input_1_ip_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_ip_version = Signal(intbv(0)[4:]) + input_1_ip_ihl = Signal(intbv(0)[4:]) + input_1_ip_dscp = Signal(intbv(0)[6:]) + input_1_ip_ecn = Signal(intbv(0)[2:]) + input_1_ip_length = Signal(intbv(0)[16:]) + input_1_ip_identification = Signal(intbv(0)[16:]) + input_1_ip_flags = Signal(intbv(0)[3:]) + input_1_ip_fragment_offset = Signal(intbv(0)[13:]) + input_1_ip_ttl = Signal(intbv(0)[8:]) + input_1_ip_protocol = Signal(intbv(0)[8:]) + input_1_ip_header_checksum = Signal(intbv(0)[16:]) + input_1_ip_source_ip = Signal(intbv(0)[32:]) + input_1_ip_dest_ip = Signal(intbv(0)[32:]) + input_1_ip_payload_tdata = Signal(intbv(0)[64:]) + input_1_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_1_ip_payload_tvalid = Signal(bool(0)) + input_1_ip_payload_tlast = Signal(bool(0)) + input_1_ip_payload_tuser = Signal(bool(0)) + input_2_ip_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_ip_version = Signal(intbv(0)[4:]) + input_2_ip_ihl = Signal(intbv(0)[4:]) + input_2_ip_dscp = Signal(intbv(0)[6:]) + input_2_ip_ecn = Signal(intbv(0)[2:]) + input_2_ip_length = Signal(intbv(0)[16:]) + input_2_ip_identification = Signal(intbv(0)[16:]) + input_2_ip_flags = Signal(intbv(0)[3:]) + input_2_ip_fragment_offset = Signal(intbv(0)[13:]) + input_2_ip_ttl = Signal(intbv(0)[8:]) + input_2_ip_protocol = Signal(intbv(0)[8:]) + input_2_ip_header_checksum = Signal(intbv(0)[16:]) + input_2_ip_source_ip = Signal(intbv(0)[32:]) + input_2_ip_dest_ip = Signal(intbv(0)[32:]) + input_2_ip_payload_tdata = Signal(intbv(0)[64:]) + input_2_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_2_ip_payload_tvalid = Signal(bool(0)) + input_2_ip_payload_tlast = Signal(bool(0)) + input_2_ip_payload_tuser = Signal(bool(0)) + input_3_ip_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_ip_version = Signal(intbv(0)[4:]) + input_3_ip_ihl = Signal(intbv(0)[4:]) + input_3_ip_dscp = Signal(intbv(0)[6:]) + input_3_ip_ecn = Signal(intbv(0)[2:]) + input_3_ip_length = Signal(intbv(0)[16:]) + input_3_ip_identification = Signal(intbv(0)[16:]) + input_3_ip_flags = Signal(intbv(0)[3:]) + input_3_ip_fragment_offset = Signal(intbv(0)[13:]) + input_3_ip_ttl = Signal(intbv(0)[8:]) + input_3_ip_protocol = Signal(intbv(0)[8:]) + input_3_ip_header_checksum = Signal(intbv(0)[16:]) + input_3_ip_source_ip = Signal(intbv(0)[32:]) + input_3_ip_dest_ip = Signal(intbv(0)[32:]) + input_3_ip_payload_tdata = Signal(intbv(0)[64:]) + input_3_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_3_ip_payload_tvalid = Signal(bool(0)) + input_3_ip_payload_tlast = Signal(bool(0)) + input_3_ip_payload_tuser = Signal(bool(0)) + + output_ip_payload_tready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + + # Outputs + input_0_ip_hdr_ready = Signal(bool(0)) + input_0_ip_payload_tready = Signal(bool(0)) + input_1_ip_hdr_ready = Signal(bool(0)) + input_1_ip_payload_tready = Signal(bool(0)) + input_2_ip_hdr_ready = Signal(bool(0)) + input_2_ip_payload_tready = Signal(bool(0)) + input_3_ip_hdr_ready = Signal(bool(0)) + input_3_ip_payload_tready = Signal(bool(0)) + + output_ip_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[64:]) + output_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_0_ip_hdr_ready, + ip_hdr_valid=input_0_ip_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + ip_version=input_0_ip_version, + ip_ihl=input_0_ip_ihl, + ip_dscp=input_0_ip_dscp, + ip_ecn=input_0_ip_ecn, + ip_length=input_0_ip_length, + ip_identification=input_0_ip_identification, + ip_flags=input_0_ip_flags, + ip_fragment_offset=input_0_ip_fragment_offset, + ip_ttl=input_0_ip_ttl, + ip_protocol=input_0_ip_protocol, + ip_header_checksum=input_0_ip_header_checksum, + ip_source_ip=input_0_ip_source_ip, + ip_dest_ip=input_0_ip_dest_ip, + ip_payload_tdata=input_0_ip_payload_tdata, + ip_payload_tkeep=input_0_ip_payload_tkeep, + ip_payload_tvalid=input_0_ip_payload_tvalid, + ip_payload_tready=input_0_ip_payload_tready, + ip_payload_tlast=input_0_ip_payload_tlast, + ip_payload_tuser=input_0_ip_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_1_ip_hdr_ready, + ip_hdr_valid=input_1_ip_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + ip_version=input_1_ip_version, + ip_ihl=input_1_ip_ihl, + ip_dscp=input_1_ip_dscp, + ip_ecn=input_1_ip_ecn, + ip_length=input_1_ip_length, + ip_identification=input_1_ip_identification, + ip_flags=input_1_ip_flags, + ip_fragment_offset=input_1_ip_fragment_offset, + ip_ttl=input_1_ip_ttl, + ip_protocol=input_1_ip_protocol, + ip_header_checksum=input_1_ip_header_checksum, + ip_source_ip=input_1_ip_source_ip, + ip_dest_ip=input_1_ip_dest_ip, + ip_payload_tdata=input_1_ip_payload_tdata, + ip_payload_tkeep=input_1_ip_payload_tkeep, + ip_payload_tvalid=input_1_ip_payload_tvalid, + ip_payload_tready=input_1_ip_payload_tready, + ip_payload_tlast=input_1_ip_payload_tlast, + ip_payload_tuser=input_1_ip_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_2_ip_hdr_ready, + ip_hdr_valid=input_2_ip_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + ip_version=input_2_ip_version, + ip_ihl=input_2_ip_ihl, + ip_dscp=input_2_ip_dscp, + ip_ecn=input_2_ip_ecn, + ip_length=input_2_ip_length, + ip_identification=input_2_ip_identification, + ip_flags=input_2_ip_flags, + ip_fragment_offset=input_2_ip_fragment_offset, + ip_ttl=input_2_ip_ttl, + ip_protocol=input_2_ip_protocol, + ip_header_checksum=input_2_ip_header_checksum, + ip_source_ip=input_2_ip_source_ip, + ip_dest_ip=input_2_ip_dest_ip, + ip_payload_tdata=input_2_ip_payload_tdata, + ip_payload_tkeep=input_2_ip_payload_tkeep, + ip_payload_tvalid=input_2_ip_payload_tvalid, + ip_payload_tready=input_2_ip_payload_tready, + ip_payload_tlast=input_2_ip_payload_tlast, + ip_payload_tuser=input_2_ip_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_3_ip_hdr_ready, + ip_hdr_valid=input_3_ip_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + ip_version=input_3_ip_version, + ip_ihl=input_3_ip_ihl, + ip_dscp=input_3_ip_dscp, + ip_ecn=input_3_ip_ecn, + ip_length=input_3_ip_length, + ip_identification=input_3_ip_identification, + ip_flags=input_3_ip_flags, + ip_fragment_offset=input_3_ip_fragment_offset, + ip_ttl=input_3_ip_ttl, + ip_protocol=input_3_ip_protocol, + ip_header_checksum=input_3_ip_header_checksum, + ip_source_ip=input_3_ip_source_ip, + ip_dest_ip=input_3_ip_dest_ip, + ip_payload_tdata=input_3_ip_payload_tdata, + ip_payload_tkeep=input_3_ip_payload_tkeep, + ip_payload_tvalid=input_3_ip_payload_tvalid, + ip_payload_tready=input_3_ip_payload_tready, + ip_payload_tlast=input_3_ip_payload_tlast, + ip_payload_tuser=input_3_ip_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tkeep=output_ip_payload_tkeep, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_ip_arb_mux_64_4(clk, + rst, + current_test, + + input_0_ip_hdr_valid, + input_0_ip_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tkeep, + input_0_ip_payload_tvalid, + input_0_ip_payload_tready, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_ip_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tkeep, + input_1_ip_payload_tvalid, + input_1_ip_payload_tready, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_ip_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tkeep, + input_2_ip_payload_tvalid, + input_2_ip_payload_tready, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_ip_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tkeep, + input_3_ip_payload_tvalid, + input_3_ip_payload_tready, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_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: port 0") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: port 1") + current_test.next = 2 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + 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 5: alterate pause source") + current_test.next = 5 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == 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: alterate pause sink") + current_test.next = 6 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_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 + 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: back-to-back packets, different ports, arbitration test") + current_test.next = 7 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + yield clk.posedge + + yield delay(150) + yield clk.posedge + source_1_queue.put(test_frame1) + + while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + 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 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_arb_mux_64_4.v b/tb/test_ip_arb_mux_64_4.v new file mode 100644 index 000000000..930311284 --- /dev/null +++ b/tb/test_ip_arb_mux_64_4.v @@ -0,0 +1,420 @@ +/* + +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_ip_arb_mux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_ip_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [3:0] input_0_ip_version = 0; +reg [3:0] input_0_ip_ihl = 0; +reg [5:0] input_0_ip_dscp = 0; +reg [1:0] input_0_ip_ecn = 0; +reg [15:0] input_0_ip_length = 0; +reg [15:0] input_0_ip_identification = 0; +reg [2:0] input_0_ip_flags = 0; +reg [12:0] input_0_ip_fragment_offset = 0; +reg [7:0] input_0_ip_ttl = 0; +reg [7:0] input_0_ip_protocol = 0; +reg [15:0] input_0_ip_header_checksum = 0; +reg [31:0] input_0_ip_source_ip = 0; +reg [31:0] input_0_ip_dest_ip = 0; +reg [63:0] input_0_ip_payload_tdata = 0; +reg [7:0] input_0_ip_payload_tkeep = 0; +reg input_0_ip_payload_tvalid = 0; +reg input_0_ip_payload_tlast = 0; +reg input_0_ip_payload_tuser = 0; +reg input_1_ip_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [3:0] input_1_ip_version = 0; +reg [3:0] input_1_ip_ihl = 0; +reg [5:0] input_1_ip_dscp = 0; +reg [1:0] input_1_ip_ecn = 0; +reg [15:0] input_1_ip_length = 0; +reg [15:0] input_1_ip_identification = 0; +reg [2:0] input_1_ip_flags = 0; +reg [12:0] input_1_ip_fragment_offset = 0; +reg [7:0] input_1_ip_ttl = 0; +reg [7:0] input_1_ip_protocol = 0; +reg [15:0] input_1_ip_header_checksum = 0; +reg [31:0] input_1_ip_source_ip = 0; +reg [31:0] input_1_ip_dest_ip = 0; +reg [63:0] input_1_ip_payload_tdata = 0; +reg [7:0] input_1_ip_payload_tkeep = 0; +reg input_1_ip_payload_tvalid = 0; +reg input_1_ip_payload_tlast = 0; +reg input_1_ip_payload_tuser = 0; +reg input_2_ip_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [3:0] input_2_ip_version = 0; +reg [3:0] input_2_ip_ihl = 0; +reg [5:0] input_2_ip_dscp = 0; +reg [1:0] input_2_ip_ecn = 0; +reg [15:0] input_2_ip_length = 0; +reg [15:0] input_2_ip_identification = 0; +reg [2:0] input_2_ip_flags = 0; +reg [12:0] input_2_ip_fragment_offset = 0; +reg [7:0] input_2_ip_ttl = 0; +reg [7:0] input_2_ip_protocol = 0; +reg [15:0] input_2_ip_header_checksum = 0; +reg [31:0] input_2_ip_source_ip = 0; +reg [31:0] input_2_ip_dest_ip = 0; +reg [63:0] input_2_ip_payload_tdata = 0; +reg [7:0] input_2_ip_payload_tkeep = 0; +reg input_2_ip_payload_tvalid = 0; +reg input_2_ip_payload_tlast = 0; +reg input_2_ip_payload_tuser = 0; +reg input_3_ip_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [3:0] input_3_ip_version = 0; +reg [3:0] input_3_ip_ihl = 0; +reg [5:0] input_3_ip_dscp = 0; +reg [1:0] input_3_ip_ecn = 0; +reg [15:0] input_3_ip_length = 0; +reg [15:0] input_3_ip_identification = 0; +reg [2:0] input_3_ip_flags = 0; +reg [12:0] input_3_ip_fragment_offset = 0; +reg [7:0] input_3_ip_ttl = 0; +reg [7:0] input_3_ip_protocol = 0; +reg [15:0] input_3_ip_header_checksum = 0; +reg [31:0] input_3_ip_source_ip = 0; +reg [31:0] input_3_ip_dest_ip = 0; +reg [63:0] input_3_ip_payload_tdata = 0; +reg [7:0] input_3_ip_payload_tkeep = 0; +reg input_3_ip_payload_tvalid = 0; +reg input_3_ip_payload_tlast = 0; +reg input_3_ip_payload_tuser = 0; + +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; + +// Outputs +wire input_0_ip_payload_tready; +wire input_0_ip_hdr_ready; +wire input_1_ip_payload_tready; +wire input_1_ip_hdr_ready; +wire input_2_ip_payload_tready; +wire input_2_ip_hdr_ready; +wire input_3_ip_payload_tready; +wire input_3_ip_hdr_ready; + +wire output_ip_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [63:0] output_ip_payload_tdata; +wire [7:0] output_ip_payload_tkeep; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_ip_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_ip_payload_tdata, + input_0_ip_payload_tkeep, + input_0_ip_payload_tvalid, + input_0_ip_payload_tlast, + input_0_ip_payload_tuser, + input_1_ip_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_ip_payload_tdata, + input_1_ip_payload_tkeep, + input_1_ip_payload_tvalid, + input_1_ip_payload_tlast, + input_1_ip_payload_tuser, + input_2_ip_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_ip_payload_tdata, + input_2_ip_payload_tkeep, + input_2_ip_payload_tvalid, + input_2_ip_payload_tlast, + input_2_ip_payload_tuser, + input_3_ip_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_ip_payload_tdata, + input_3_ip_payload_tkeep, + input_3_ip_payload_tvalid, + input_3_ip_payload_tlast, + input_3_ip_payload_tuser, + output_ip_hdr_ready, + output_ip_payload_tready); + $to_myhdl(input_0_ip_hdr_ready, + input_0_ip_payload_tready, + input_1_ip_hdr_ready, + input_1_ip_payload_tready, + input_2_ip_hdr_ready, + input_2_ip_payload_tready, + input_3_ip_hdr_ready, + input_3_ip_payload_tready, + output_ip_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser); + + // dump file + $dumpfile("test_ip_arb_mux_64_4.lxt"); + $dumpvars(0, test_ip_arb_mux_64_4); +end + +ip_arb_mux_64_4 +UUT ( + .clk(clk), + .rst(rst), + // IP frame inputs + .input_0_ip_hdr_valid(input_0_ip_hdr_valid), + .input_0_ip_hdr_ready(input_0_ip_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_ip_payload_tdata(input_0_ip_payload_tdata), + .input_0_ip_payload_tkeep(input_0_ip_payload_tkeep), + .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid), + .input_0_ip_payload_tready(input_0_ip_payload_tready), + .input_0_ip_payload_tlast(input_0_ip_payload_tlast), + .input_0_ip_payload_tuser(input_0_ip_payload_tuser), + .input_1_ip_hdr_valid(input_1_ip_hdr_valid), + .input_1_ip_hdr_ready(input_1_ip_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_ip_payload_tdata(input_1_ip_payload_tdata), + .input_1_ip_payload_tkeep(input_1_ip_payload_tkeep), + .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid), + .input_1_ip_payload_tready(input_1_ip_payload_tready), + .input_1_ip_payload_tlast(input_1_ip_payload_tlast), + .input_1_ip_payload_tuser(input_1_ip_payload_tuser), + .input_2_ip_hdr_valid(input_2_ip_hdr_valid), + .input_2_ip_hdr_ready(input_2_ip_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_ip_payload_tdata(input_2_ip_payload_tdata), + .input_2_ip_payload_tkeep(input_2_ip_payload_tkeep), + .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid), + .input_2_ip_payload_tready(input_2_ip_payload_tready), + .input_2_ip_payload_tlast(input_2_ip_payload_tlast), + .input_2_ip_payload_tuser(input_2_ip_payload_tuser), + .input_3_ip_hdr_valid(input_3_ip_hdr_valid), + .input_3_ip_hdr_ready(input_3_ip_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_ip_payload_tdata(input_3_ip_payload_tdata), + .input_3_ip_payload_tkeep(input_3_ip_payload_tkeep), + .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid), + .input_3_ip_payload_tready(input_3_ip_payload_tready), + .input_3_ip_payload_tlast(input_3_ip_payload_tlast), + .input_3_ip_payload_tuser(input_3_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser) +); + +endmodule From 348a3476168c96336610d67166d99d9eadce87bc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 18 Nov 2014 12:36:12 -0800 Subject: [PATCH 110/617] Add IP demux and testbench --- rtl/ip_demux.py | 453 +++++++++++++++ rtl/ip_demux_4.v | 533 ++++++++++++++++++ rtl/ip_demux_64.py | 466 ++++++++++++++++ rtl/ip_demux_64_4.v | 552 ++++++++++++++++++ tb/test_ip_demux_4.py | 1111 +++++++++++++++++++++++++++++++++++++ tb/test_ip_demux_4.v | 413 ++++++++++++++ tb/test_ip_demux_64_4.py | 1136 ++++++++++++++++++++++++++++++++++++++ tb/test_ip_demux_64_4.v | 428 ++++++++++++++ 8 files changed, 5092 insertions(+) create mode 100755 rtl/ip_demux.py create mode 100644 rtl/ip_demux_4.v create mode 100755 rtl/ip_demux_64.py create mode 100644 rtl/ip_demux_64_4.v create mode 100755 tb/test_ip_demux_4.py create mode 100644 tb/test_ip_demux_4.v create mode 100755 tb/test_ip_demux_64_4.py create mode 100644 tb/test_ip_demux_64_4.v diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py new file mode 100755 index 000000000..0af4ed028 --- /dev/null +++ b/rtl/ip_demux.py @@ -0,0 +1,453 @@ +#!/usr/bin/env python +"""ip_demux + +Generates an IP demux with the specified number of ports + +Usage: ip_demux [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "ip_demux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port IP demux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * IP {{n}} port demultiplexer + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [7:0] input_ip_payload_tdata, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP frame outputs + */ +{%- for p in ports %} + output wire output_{{p}}_ip_hdr_valid, + input wire output_{{p}}_ip_hdr_ready, + output wire [47:0] output_{{p}}_eth_dest_mac, + output wire [47:0] output_{{p}}_eth_src_mac, + output wire [15:0] output_{{p}}_eth_type, + output wire [3:0] output_{{p}}_ip_version, + output wire [3:0] output_{{p}}_ip_ihl, + output wire [5:0] output_{{p}}_ip_dscp, + output wire [1:0] output_{{p}}_ip_ecn, + output wire [15:0] output_{{p}}_ip_length, + output wire [15:0] output_{{p}}_ip_identification, + output wire [2:0] output_{{p}}_ip_flags, + output wire [12:0] output_{{p}}_ip_fragment_offset, + output wire [7:0] output_{{p}}_ip_ttl, + output wire [7:0] output_{{p}}_ip_protocol, + output wire [15:0] output_{{p}}_ip_header_checksum, + output wire [31:0] output_{{p}}_ip_source_ip, + output wire [31:0] output_{{p}}_ip_dest_ip, + output wire [7:0] output_{{p}}_ip_payload_tdata, + output wire output_{{p}}_ip_payload_tvalid, + input wire output_{{p}}_ip_payload_tready, + output wire output_{{p}}_ip_payload_tlast, + output wire output_{{p}}_ip_payload_tuser, +{% endfor %} + /* + * Control + */ + input wire enable, + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; +{% for p in ports %} +reg output_{{p}}_ip_hdr_valid_reg = 0, output_{{p}}_ip_hdr_valid_next; +{%- endfor %} +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; + +// internal datapath +reg [7:0] output_ip_payload_tdata_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; + +assign input_ip_hdr_ready = input_ip_hdr_ready_reg; +assign input_ip_payload_tready = input_ip_payload_tready_reg; +{% for p in ports %} +assign output_{{p}}_ip_hdr_valid = output_{{p}}_ip_hdr_valid_reg; +assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; +assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; +assign output_{{p}}_eth_type = output_eth_type_reg; +assign output_{{p}}_ip_version = output_ip_version_reg; +assign output_{{p}}_ip_ihl = output_ip_ihl_reg; +assign output_{{p}}_ip_dscp = output_ip_dscp_reg; +assign output_{{p}}_ip_ecn = output_ip_ecn_reg; +assign output_{{p}}_ip_length = output_ip_length_reg; +assign output_{{p}}_ip_identification = output_ip_identification_reg; +assign output_{{p}}_ip_flags = output_ip_flags_reg; +assign output_{{p}}_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_{{p}}_ip_ttl = output_ip_ttl_reg; +assign output_{{p}}_ip_protocol = output_ip_protocol_reg; +assign output_{{p}}_ip_header_checksum = output_ip_header_checksum_reg; +assign output_{{p}}_ip_source_ip = output_ip_source_ip_reg; +assign output_{{p}}_ip_dest_ip = output_ip_dest_ip_reg; +{% endfor %} +// mux for output control signals +reg current_output_ip_hdr_valid; +reg current_output_ip_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_output_ip_hdr_valid = output_{{p}}_ip_hdr_valid; + current_output_ip_hdr_ready = output_{{p}}_ip_hdr_ready; + current_output_tvalid = output_{{p}}_ip_payload_tvalid; + current_output_tready = output_{{p}}_ip_payload_tready; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; + input_ip_payload_tready_next = 0; + +{%- for p in ports %} + output_{{p}}_ip_hdr_valid_next = output_{{p}}_ip_hdr_valid_reg & ~output_{{p}}_ip_hdr_ready; +{%- endfor %} + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + + if (frame_reg) begin + if (input_ip_payload_tvalid & input_ip_payload_tready) begin + // end of frame detection + frame_next = ~input_ip_payload_tlast; + end + end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_ip_hdr_ready_next = 1; + + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_ip_hdr_valid_next = 1; +{%- endfor %} + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + output_ip_version_next = input_ip_version; + output_ip_ihl_next = input_ip_ihl; + output_ip_dscp_next = input_ip_dscp; + output_ip_ecn_next = input_ip_ecn; + output_ip_length_next = input_ip_length; + output_ip_identification_next = input_ip_identification; + output_ip_flags_next = input_ip_flags; + output_ip_fragment_offset_next = input_ip_fragment_offset; + output_ip_ttl_next = input_ip_ttl; + output_ip_protocol_next = input_ip_protocol; + output_ip_header_checksum_next = input_ip_header_checksum; + output_ip_source_ip_next = input_ip_source_ip; + output_ip_dest_ip_next = input_ip_dest_ip; + end + + input_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + + output_ip_payload_tdata_int = input_ip_payload_tdata; + output_ip_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tready; + output_ip_payload_tlast_int = input_ip_payload_tlast; + output_ip_payload_tuser_int = input_ip_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; +{%- for p in ports %} + output_{{p}}_ip_hdr_valid_reg <= 0; +{%- endfor %} + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + input_ip_payload_tready_reg <= input_ip_payload_tready_next; +{%- for p in ports %} + output_{{p}}_ip_hdr_valid_reg <= output_{{p}}_ip_hdr_valid_next; +{%- endfor %} + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + end +end + +// output datapath logic +reg [7:0] output_ip_payload_tdata_reg = 0; +{%- for p in ports %} +reg output_{{p}}_ip_payload_tvalid_reg = 0; +{%- endfor %} +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [7:0] temp_ip_payload_tdata_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; +{% for p in ports %} +assign output_{{p}}_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_{{p}}_ip_payload_tvalid = output_{{p}}_ip_payload_tvalid_reg; +assign output_{{p}}_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_{{p}}_ip_payload_tuser = output_ip_payload_tuser_reg; +{% endfor %} +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; +{%- for p in ports %} + output_{{p}}_ip_payload_tvalid_reg <= 0; +{%- endfor %} + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; +{%- endfor %} + endcase + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; +{%- endfor %} + endcase + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/ip_demux_4.v b/rtl/ip_demux_4.v new file mode 100644 index 000000000..fc5eb0093 --- /dev/null +++ b/rtl/ip_demux_4.v @@ -0,0 +1,533 @@ +/* + +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 + +/* + * IP 4 port demultiplexer + */ +module ip_demux_4 +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [7:0] input_ip_payload_tdata, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP frame outputs + */ + output wire output_0_ip_hdr_valid, + input wire output_0_ip_hdr_ready, + output wire [47:0] output_0_eth_dest_mac, + output wire [47:0] output_0_eth_src_mac, + output wire [15:0] output_0_eth_type, + output wire [3:0] output_0_ip_version, + output wire [3:0] output_0_ip_ihl, + output wire [5:0] output_0_ip_dscp, + output wire [1:0] output_0_ip_ecn, + output wire [15:0] output_0_ip_length, + output wire [15:0] output_0_ip_identification, + output wire [2:0] output_0_ip_flags, + output wire [12:0] output_0_ip_fragment_offset, + output wire [7:0] output_0_ip_ttl, + output wire [7:0] output_0_ip_protocol, + output wire [15:0] output_0_ip_header_checksum, + output wire [31:0] output_0_ip_source_ip, + output wire [31:0] output_0_ip_dest_ip, + output wire [7:0] output_0_ip_payload_tdata, + output wire output_0_ip_payload_tvalid, + input wire output_0_ip_payload_tready, + output wire output_0_ip_payload_tlast, + output wire output_0_ip_payload_tuser, + + output wire output_1_ip_hdr_valid, + input wire output_1_ip_hdr_ready, + output wire [47:0] output_1_eth_dest_mac, + output wire [47:0] output_1_eth_src_mac, + output wire [15:0] output_1_eth_type, + output wire [3:0] output_1_ip_version, + output wire [3:0] output_1_ip_ihl, + output wire [5:0] output_1_ip_dscp, + output wire [1:0] output_1_ip_ecn, + output wire [15:0] output_1_ip_length, + output wire [15:0] output_1_ip_identification, + output wire [2:0] output_1_ip_flags, + output wire [12:0] output_1_ip_fragment_offset, + output wire [7:0] output_1_ip_ttl, + output wire [7:0] output_1_ip_protocol, + output wire [15:0] output_1_ip_header_checksum, + output wire [31:0] output_1_ip_source_ip, + output wire [31:0] output_1_ip_dest_ip, + output wire [7:0] output_1_ip_payload_tdata, + output wire output_1_ip_payload_tvalid, + input wire output_1_ip_payload_tready, + output wire output_1_ip_payload_tlast, + output wire output_1_ip_payload_tuser, + + output wire output_2_ip_hdr_valid, + input wire output_2_ip_hdr_ready, + output wire [47:0] output_2_eth_dest_mac, + output wire [47:0] output_2_eth_src_mac, + output wire [15:0] output_2_eth_type, + output wire [3:0] output_2_ip_version, + output wire [3:0] output_2_ip_ihl, + output wire [5:0] output_2_ip_dscp, + output wire [1:0] output_2_ip_ecn, + output wire [15:0] output_2_ip_length, + output wire [15:0] output_2_ip_identification, + output wire [2:0] output_2_ip_flags, + output wire [12:0] output_2_ip_fragment_offset, + output wire [7:0] output_2_ip_ttl, + output wire [7:0] output_2_ip_protocol, + output wire [15:0] output_2_ip_header_checksum, + output wire [31:0] output_2_ip_source_ip, + output wire [31:0] output_2_ip_dest_ip, + output wire [7:0] output_2_ip_payload_tdata, + output wire output_2_ip_payload_tvalid, + input wire output_2_ip_payload_tready, + output wire output_2_ip_payload_tlast, + output wire output_2_ip_payload_tuser, + + output wire output_3_ip_hdr_valid, + input wire output_3_ip_hdr_ready, + output wire [47:0] output_3_eth_dest_mac, + output wire [47:0] output_3_eth_src_mac, + output wire [15:0] output_3_eth_type, + output wire [3:0] output_3_ip_version, + output wire [3:0] output_3_ip_ihl, + output wire [5:0] output_3_ip_dscp, + output wire [1:0] output_3_ip_ecn, + output wire [15:0] output_3_ip_length, + output wire [15:0] output_3_ip_identification, + output wire [2:0] output_3_ip_flags, + output wire [12:0] output_3_ip_fragment_offset, + output wire [7:0] output_3_ip_ttl, + output wire [7:0] output_3_ip_protocol, + output wire [15:0] output_3_ip_header_checksum, + output wire [31:0] output_3_ip_source_ip, + output wire [31:0] output_3_ip_dest_ip, + output wire [7:0] output_3_ip_payload_tdata, + output wire output_3_ip_payload_tvalid, + input wire output_3_ip_payload_tready, + output wire output_3_ip_payload_tlast, + output wire output_3_ip_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; + +reg output_0_ip_hdr_valid_reg = 0, output_0_ip_hdr_valid_next; +reg output_1_ip_hdr_valid_reg = 0, output_1_ip_hdr_valid_next; +reg output_2_ip_hdr_valid_reg = 0, output_2_ip_hdr_valid_next; +reg output_3_ip_hdr_valid_reg = 0, output_3_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; + +// internal datapath +reg [7:0] output_ip_payload_tdata_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; + +assign input_ip_hdr_ready = input_ip_hdr_ready_reg; +assign input_ip_payload_tready = input_ip_payload_tready_reg; + +assign output_0_ip_hdr_valid = output_0_ip_hdr_valid_reg; +assign output_0_eth_dest_mac = output_eth_dest_mac_reg; +assign output_0_eth_src_mac = output_eth_src_mac_reg; +assign output_0_eth_type = output_eth_type_reg; +assign output_0_ip_version = output_ip_version_reg; +assign output_0_ip_ihl = output_ip_ihl_reg; +assign output_0_ip_dscp = output_ip_dscp_reg; +assign output_0_ip_ecn = output_ip_ecn_reg; +assign output_0_ip_length = output_ip_length_reg; +assign output_0_ip_identification = output_ip_identification_reg; +assign output_0_ip_flags = output_ip_flags_reg; +assign output_0_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_0_ip_ttl = output_ip_ttl_reg; +assign output_0_ip_protocol = output_ip_protocol_reg; +assign output_0_ip_header_checksum = output_ip_header_checksum_reg; +assign output_0_ip_source_ip = output_ip_source_ip_reg; +assign output_0_ip_dest_ip = output_ip_dest_ip_reg; + +assign output_1_ip_hdr_valid = output_1_ip_hdr_valid_reg; +assign output_1_eth_dest_mac = output_eth_dest_mac_reg; +assign output_1_eth_src_mac = output_eth_src_mac_reg; +assign output_1_eth_type = output_eth_type_reg; +assign output_1_ip_version = output_ip_version_reg; +assign output_1_ip_ihl = output_ip_ihl_reg; +assign output_1_ip_dscp = output_ip_dscp_reg; +assign output_1_ip_ecn = output_ip_ecn_reg; +assign output_1_ip_length = output_ip_length_reg; +assign output_1_ip_identification = output_ip_identification_reg; +assign output_1_ip_flags = output_ip_flags_reg; +assign output_1_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_1_ip_ttl = output_ip_ttl_reg; +assign output_1_ip_protocol = output_ip_protocol_reg; +assign output_1_ip_header_checksum = output_ip_header_checksum_reg; +assign output_1_ip_source_ip = output_ip_source_ip_reg; +assign output_1_ip_dest_ip = output_ip_dest_ip_reg; + +assign output_2_ip_hdr_valid = output_2_ip_hdr_valid_reg; +assign output_2_eth_dest_mac = output_eth_dest_mac_reg; +assign output_2_eth_src_mac = output_eth_src_mac_reg; +assign output_2_eth_type = output_eth_type_reg; +assign output_2_ip_version = output_ip_version_reg; +assign output_2_ip_ihl = output_ip_ihl_reg; +assign output_2_ip_dscp = output_ip_dscp_reg; +assign output_2_ip_ecn = output_ip_ecn_reg; +assign output_2_ip_length = output_ip_length_reg; +assign output_2_ip_identification = output_ip_identification_reg; +assign output_2_ip_flags = output_ip_flags_reg; +assign output_2_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_2_ip_ttl = output_ip_ttl_reg; +assign output_2_ip_protocol = output_ip_protocol_reg; +assign output_2_ip_header_checksum = output_ip_header_checksum_reg; +assign output_2_ip_source_ip = output_ip_source_ip_reg; +assign output_2_ip_dest_ip = output_ip_dest_ip_reg; + +assign output_3_ip_hdr_valid = output_3_ip_hdr_valid_reg; +assign output_3_eth_dest_mac = output_eth_dest_mac_reg; +assign output_3_eth_src_mac = output_eth_src_mac_reg; +assign output_3_eth_type = output_eth_type_reg; +assign output_3_ip_version = output_ip_version_reg; +assign output_3_ip_ihl = output_ip_ihl_reg; +assign output_3_ip_dscp = output_ip_dscp_reg; +assign output_3_ip_ecn = output_ip_ecn_reg; +assign output_3_ip_length = output_ip_length_reg; +assign output_3_ip_identification = output_ip_identification_reg; +assign output_3_ip_flags = output_ip_flags_reg; +assign output_3_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_3_ip_ttl = output_ip_ttl_reg; +assign output_3_ip_protocol = output_ip_protocol_reg; +assign output_3_ip_header_checksum = output_ip_header_checksum_reg; +assign output_3_ip_source_ip = output_ip_source_ip_reg; +assign output_3_ip_dest_ip = output_ip_dest_ip_reg; + +// mux for output control signals +reg current_output_ip_hdr_valid; +reg current_output_ip_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) + 2'd0: begin + current_output_ip_hdr_valid = output_0_ip_hdr_valid; + current_output_ip_hdr_ready = output_0_ip_hdr_ready; + current_output_tvalid = output_0_ip_payload_tvalid; + current_output_tready = output_0_ip_payload_tready; + end + 2'd1: begin + current_output_ip_hdr_valid = output_1_ip_hdr_valid; + current_output_ip_hdr_ready = output_1_ip_hdr_ready; + current_output_tvalid = output_1_ip_payload_tvalid; + current_output_tready = output_1_ip_payload_tready; + end + 2'd2: begin + current_output_ip_hdr_valid = output_2_ip_hdr_valid; + current_output_ip_hdr_ready = output_2_ip_hdr_ready; + current_output_tvalid = output_2_ip_payload_tvalid; + current_output_tready = output_2_ip_payload_tready; + end + 2'd3: begin + current_output_ip_hdr_valid = output_3_ip_hdr_valid; + current_output_ip_hdr_ready = output_3_ip_hdr_ready; + current_output_tvalid = output_3_ip_payload_tvalid; + current_output_tready = output_3_ip_payload_tready; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; + input_ip_payload_tready_next = 0; + output_0_ip_hdr_valid_next = output_0_ip_hdr_valid_reg & ~output_0_ip_hdr_ready; + output_1_ip_hdr_valid_next = output_1_ip_hdr_valid_reg & ~output_1_ip_hdr_ready; + output_2_ip_hdr_valid_next = output_2_ip_hdr_valid_reg & ~output_2_ip_hdr_ready; + output_3_ip_hdr_valid_next = output_3_ip_hdr_valid_reg & ~output_3_ip_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + + if (frame_reg) begin + if (input_ip_payload_tvalid & input_ip_payload_tready) begin + // end of frame detection + frame_next = ~input_ip_payload_tlast; + end + end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_ip_hdr_ready_next = 1; + + case (select) + 2'd0: output_0_ip_hdr_valid_next = 1; + 2'd1: output_1_ip_hdr_valid_next = 1; + 2'd2: output_2_ip_hdr_valid_next = 1; + 2'd3: output_3_ip_hdr_valid_next = 1; + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + output_ip_version_next = input_ip_version; + output_ip_ihl_next = input_ip_ihl; + output_ip_dscp_next = input_ip_dscp; + output_ip_ecn_next = input_ip_ecn; + output_ip_length_next = input_ip_length; + output_ip_identification_next = input_ip_identification; + output_ip_flags_next = input_ip_flags; + output_ip_fragment_offset_next = input_ip_fragment_offset; + output_ip_ttl_next = input_ip_ttl; + output_ip_protocol_next = input_ip_protocol; + output_ip_header_checksum_next = input_ip_header_checksum; + output_ip_source_ip_next = input_ip_source_ip; + output_ip_dest_ip_next = input_ip_dest_ip; + end + + input_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + + output_ip_payload_tdata_int = input_ip_payload_tdata; + output_ip_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tready; + output_ip_payload_tlast_int = input_ip_payload_tlast; + output_ip_payload_tuser_int = input_ip_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_0_ip_hdr_valid_reg <= 0; + output_1_ip_hdr_valid_reg <= 0; + output_2_ip_hdr_valid_reg <= 0; + output_3_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + input_ip_payload_tready_reg <= input_ip_payload_tready_next; + output_0_ip_hdr_valid_reg <= output_0_ip_hdr_valid_next; + output_1_ip_hdr_valid_reg <= output_1_ip_hdr_valid_next; + output_2_ip_hdr_valid_reg <= output_2_ip_hdr_valid_next; + output_3_ip_hdr_valid_reg <= output_3_ip_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + end +end + +// output datapath logic +reg [7:0] output_ip_payload_tdata_reg = 0; +reg output_0_ip_payload_tvalid_reg = 0; +reg output_1_ip_payload_tvalid_reg = 0; +reg output_2_ip_payload_tvalid_reg = 0; +reg output_3_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [7:0] temp_ip_payload_tdata_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign output_0_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_0_ip_payload_tvalid = output_0_ip_payload_tvalid_reg; +assign output_0_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_0_ip_payload_tuser = output_ip_payload_tuser_reg; + +assign output_1_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_1_ip_payload_tvalid = output_1_ip_payload_tvalid_reg; +assign output_1_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_1_ip_payload_tuser = output_ip_payload_tuser_reg; + +assign output_2_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_2_ip_payload_tvalid = output_2_ip_payload_tvalid_reg; +assign output_2_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_2_ip_payload_tuser = output_ip_payload_tuser_reg; + +assign output_3_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_3_ip_payload_tvalid = output_3_ip_payload_tvalid_reg; +assign output_3_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_3_ip_payload_tuser = output_ip_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_0_ip_payload_tvalid_reg <= 0; + output_1_ip_payload_tvalid_reg <= 0; + output_2_ip_payload_tvalid_reg <= 0; + output_3_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + case (select_reg) + 2'd0: output_0_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + 2'd1: output_1_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + 2'd2: output_2_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + 2'd3: output_3_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + endcase + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + case (select_reg) + 2'd0: output_0_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + 2'd1: output_1_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + 2'd2: output_2_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + 2'd3: output_3_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + endcase + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py new file mode 100755 index 000000000..441e0a328 --- /dev/null +++ b/rtl/ip_demux_64.py @@ -0,0 +1,466 @@ +#!/usr/bin/env python +"""ip_demux_64 + +Generates an IP demux with the specified number of ports + +Usage: ip_demux_64 [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "ip_demux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port IP demux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * IP {{n}} port demultiplexer (64 bit datapath) + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [63:0] input_ip_payload_tdata, + input wire [7:0] input_ip_payload_tkeep, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP frame outputs + */ +{%- for p in ports %} + output wire output_{{p}}_ip_hdr_valid, + input wire output_{{p}}_ip_hdr_ready, + output wire [47:0] output_{{p}}_eth_dest_mac, + output wire [47:0] output_{{p}}_eth_src_mac, + output wire [15:0] output_{{p}}_eth_type, + output wire [3:0] output_{{p}}_ip_version, + output wire [3:0] output_{{p}}_ip_ihl, + output wire [5:0] output_{{p}}_ip_dscp, + output wire [1:0] output_{{p}}_ip_ecn, + output wire [15:0] output_{{p}}_ip_length, + output wire [15:0] output_{{p}}_ip_identification, + output wire [2:0] output_{{p}}_ip_flags, + output wire [12:0] output_{{p}}_ip_fragment_offset, + output wire [7:0] output_{{p}}_ip_ttl, + output wire [7:0] output_{{p}}_ip_protocol, + output wire [15:0] output_{{p}}_ip_header_checksum, + output wire [31:0] output_{{p}}_ip_source_ip, + output wire [31:0] output_{{p}}_ip_dest_ip, + output wire [63:0] output_{{p}}_ip_payload_tdata, + output wire [7:0] output_{{p}}_ip_payload_tkeep, + output wire output_{{p}}_ip_payload_tvalid, + input wire output_{{p}}_ip_payload_tready, + output wire output_{{p}}_ip_payload_tlast, + output wire output_{{p}}_ip_payload_tuser, +{% endfor %} + /* + * Control + */ + input wire enable, + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; +{% for p in ports %} +reg output_{{p}}_ip_hdr_valid_reg = 0, output_{{p}}_ip_hdr_valid_next; +{%- endfor %} +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; + +// internal datapath +reg [63:0] output_ip_payload_tdata_int; +reg [7:0] output_ip_payload_tkeep_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; + +assign input_ip_hdr_ready = input_ip_hdr_ready_reg; +assign input_ip_payload_tready = input_ip_payload_tready_reg; +{% for p in ports %} +assign output_{{p}}_ip_hdr_valid = output_{{p}}_ip_hdr_valid_reg; +assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; +assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; +assign output_{{p}}_eth_type = output_eth_type_reg; +assign output_{{p}}_ip_version = output_ip_version_reg; +assign output_{{p}}_ip_ihl = output_ip_ihl_reg; +assign output_{{p}}_ip_dscp = output_ip_dscp_reg; +assign output_{{p}}_ip_ecn = output_ip_ecn_reg; +assign output_{{p}}_ip_length = output_ip_length_reg; +assign output_{{p}}_ip_identification = output_ip_identification_reg; +assign output_{{p}}_ip_flags = output_ip_flags_reg; +assign output_{{p}}_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_{{p}}_ip_ttl = output_ip_ttl_reg; +assign output_{{p}}_ip_protocol = output_ip_protocol_reg; +assign output_{{p}}_ip_header_checksum = output_ip_header_checksum_reg; +assign output_{{p}}_ip_source_ip = output_ip_source_ip_reg; +assign output_{{p}}_ip_dest_ip = output_ip_dest_ip_reg; +{% endfor %} +// mux for output control signals +reg current_output_ip_hdr_valid; +reg current_output_ip_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_output_ip_hdr_valid = output_{{p}}_ip_hdr_valid; + current_output_ip_hdr_ready = output_{{p}}_ip_hdr_ready; + current_output_tvalid = output_{{p}}_ip_payload_tvalid; + current_output_tready = output_{{p}}_ip_payload_tready; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; + input_ip_payload_tready_next = 0; + +{%- for p in ports %} + output_{{p}}_ip_hdr_valid_next = output_{{p}}_ip_hdr_valid_reg & ~output_{{p}}_ip_hdr_ready; +{%- endfor %} + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + + if (frame_reg) begin + if (input_ip_payload_tvalid & input_ip_payload_tready) begin + // end of frame detection + frame_next = ~input_ip_payload_tlast; + end + end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_ip_hdr_ready_next = 1; + + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_ip_hdr_valid_next = 1; +{%- endfor %} + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + output_ip_version_next = input_ip_version; + output_ip_ihl_next = input_ip_ihl; + output_ip_dscp_next = input_ip_dscp; + output_ip_ecn_next = input_ip_ecn; + output_ip_length_next = input_ip_length; + output_ip_identification_next = input_ip_identification; + output_ip_flags_next = input_ip_flags; + output_ip_fragment_offset_next = input_ip_fragment_offset; + output_ip_ttl_next = input_ip_ttl; + output_ip_protocol_next = input_ip_protocol; + output_ip_header_checksum_next = input_ip_header_checksum; + output_ip_source_ip_next = input_ip_source_ip; + output_ip_dest_ip_next = input_ip_dest_ip; + end + + input_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + + output_ip_payload_tdata_int = input_ip_payload_tdata; + output_ip_payload_tkeep_int = input_ip_payload_tkeep; + output_ip_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tready; + output_ip_payload_tlast_int = input_ip_payload_tlast; + output_ip_payload_tuser_int = input_ip_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; +{%- for p in ports %} + output_{{p}}_ip_hdr_valid_reg <= 0; +{%- endfor %} + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + input_ip_payload_tready_reg <= input_ip_payload_tready_next; +{%- for p in ports %} + output_{{p}}_ip_hdr_valid_reg <= output_{{p}}_ip_hdr_valid_next; +{%- endfor %} + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + end +end + +// output datapath logic +reg [63:0] output_ip_payload_tdata_reg = 0; +reg [7:0] output_ip_payload_tkeep_reg = 0; +{%- for p in ports %} +reg output_{{p}}_ip_payload_tvalid_reg = 0; +{%- endfor %} +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [63:0] temp_ip_payload_tdata_reg = 0; +reg [7:0] temp_ip_payload_tkeep_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; +{% for p in ports %} +assign output_{{p}}_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_{{p}}_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_{{p}}_ip_payload_tvalid = output_{{p}}_ip_payload_tvalid_reg; +assign output_{{p}}_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_{{p}}_ip_payload_tuser = output_ip_payload_tuser_reg; +{% endfor %} +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tkeep_reg <= 0; +{%- for p in ports %} + output_{{p}}_ip_payload_tvalid_reg <= 0; +{%- endfor %} + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; +{%- endfor %} + endcase + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; +{%- endfor %} + endcase + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/ip_demux_64_4.v b/rtl/ip_demux_64_4.v new file mode 100644 index 000000000..957c20028 --- /dev/null +++ b/rtl/ip_demux_64_4.v @@ -0,0 +1,552 @@ +/* + +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 + +/* + * IP 4 port demultiplexer (64 bit datapath) + */ +module ip_demux_64_4 +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [63:0] input_ip_payload_tdata, + input wire [7:0] input_ip_payload_tkeep, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP frame outputs + */ + output wire output_0_ip_hdr_valid, + input wire output_0_ip_hdr_ready, + output wire [47:0] output_0_eth_dest_mac, + output wire [47:0] output_0_eth_src_mac, + output wire [15:0] output_0_eth_type, + output wire [3:0] output_0_ip_version, + output wire [3:0] output_0_ip_ihl, + output wire [5:0] output_0_ip_dscp, + output wire [1:0] output_0_ip_ecn, + output wire [15:0] output_0_ip_length, + output wire [15:0] output_0_ip_identification, + output wire [2:0] output_0_ip_flags, + output wire [12:0] output_0_ip_fragment_offset, + output wire [7:0] output_0_ip_ttl, + output wire [7:0] output_0_ip_protocol, + output wire [15:0] output_0_ip_header_checksum, + output wire [31:0] output_0_ip_source_ip, + output wire [31:0] output_0_ip_dest_ip, + output wire [63:0] output_0_ip_payload_tdata, + output wire [7:0] output_0_ip_payload_tkeep, + output wire output_0_ip_payload_tvalid, + input wire output_0_ip_payload_tready, + output wire output_0_ip_payload_tlast, + output wire output_0_ip_payload_tuser, + + output wire output_1_ip_hdr_valid, + input wire output_1_ip_hdr_ready, + output wire [47:0] output_1_eth_dest_mac, + output wire [47:0] output_1_eth_src_mac, + output wire [15:0] output_1_eth_type, + output wire [3:0] output_1_ip_version, + output wire [3:0] output_1_ip_ihl, + output wire [5:0] output_1_ip_dscp, + output wire [1:0] output_1_ip_ecn, + output wire [15:0] output_1_ip_length, + output wire [15:0] output_1_ip_identification, + output wire [2:0] output_1_ip_flags, + output wire [12:0] output_1_ip_fragment_offset, + output wire [7:0] output_1_ip_ttl, + output wire [7:0] output_1_ip_protocol, + output wire [15:0] output_1_ip_header_checksum, + output wire [31:0] output_1_ip_source_ip, + output wire [31:0] output_1_ip_dest_ip, + output wire [63:0] output_1_ip_payload_tdata, + output wire [7:0] output_1_ip_payload_tkeep, + output wire output_1_ip_payload_tvalid, + input wire output_1_ip_payload_tready, + output wire output_1_ip_payload_tlast, + output wire output_1_ip_payload_tuser, + + output wire output_2_ip_hdr_valid, + input wire output_2_ip_hdr_ready, + output wire [47:0] output_2_eth_dest_mac, + output wire [47:0] output_2_eth_src_mac, + output wire [15:0] output_2_eth_type, + output wire [3:0] output_2_ip_version, + output wire [3:0] output_2_ip_ihl, + output wire [5:0] output_2_ip_dscp, + output wire [1:0] output_2_ip_ecn, + output wire [15:0] output_2_ip_length, + output wire [15:0] output_2_ip_identification, + output wire [2:0] output_2_ip_flags, + output wire [12:0] output_2_ip_fragment_offset, + output wire [7:0] output_2_ip_ttl, + output wire [7:0] output_2_ip_protocol, + output wire [15:0] output_2_ip_header_checksum, + output wire [31:0] output_2_ip_source_ip, + output wire [31:0] output_2_ip_dest_ip, + output wire [63:0] output_2_ip_payload_tdata, + output wire [7:0] output_2_ip_payload_tkeep, + output wire output_2_ip_payload_tvalid, + input wire output_2_ip_payload_tready, + output wire output_2_ip_payload_tlast, + output wire output_2_ip_payload_tuser, + + output wire output_3_ip_hdr_valid, + input wire output_3_ip_hdr_ready, + output wire [47:0] output_3_eth_dest_mac, + output wire [47:0] output_3_eth_src_mac, + output wire [15:0] output_3_eth_type, + output wire [3:0] output_3_ip_version, + output wire [3:0] output_3_ip_ihl, + output wire [5:0] output_3_ip_dscp, + output wire [1:0] output_3_ip_ecn, + output wire [15:0] output_3_ip_length, + output wire [15:0] output_3_ip_identification, + output wire [2:0] output_3_ip_flags, + output wire [12:0] output_3_ip_fragment_offset, + output wire [7:0] output_3_ip_ttl, + output wire [7:0] output_3_ip_protocol, + output wire [15:0] output_3_ip_header_checksum, + output wire [31:0] output_3_ip_source_ip, + output wire [31:0] output_3_ip_dest_ip, + output wire [63:0] output_3_ip_payload_tdata, + output wire [7:0] output_3_ip_payload_tkeep, + output wire output_3_ip_payload_tvalid, + input wire output_3_ip_payload_tready, + output wire output_3_ip_payload_tlast, + output wire output_3_ip_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; + +reg output_0_ip_hdr_valid_reg = 0, output_0_ip_hdr_valid_next; +reg output_1_ip_hdr_valid_reg = 0, output_1_ip_hdr_valid_next; +reg output_2_ip_hdr_valid_reg = 0, output_2_ip_hdr_valid_next; +reg output_3_ip_hdr_valid_reg = 0, output_3_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; + +// internal datapath +reg [63:0] output_ip_payload_tdata_int; +reg [7:0] output_ip_payload_tkeep_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; + +assign input_ip_hdr_ready = input_ip_hdr_ready_reg; +assign input_ip_payload_tready = input_ip_payload_tready_reg; + +assign output_0_ip_hdr_valid = output_0_ip_hdr_valid_reg; +assign output_0_eth_dest_mac = output_eth_dest_mac_reg; +assign output_0_eth_src_mac = output_eth_src_mac_reg; +assign output_0_eth_type = output_eth_type_reg; +assign output_0_ip_version = output_ip_version_reg; +assign output_0_ip_ihl = output_ip_ihl_reg; +assign output_0_ip_dscp = output_ip_dscp_reg; +assign output_0_ip_ecn = output_ip_ecn_reg; +assign output_0_ip_length = output_ip_length_reg; +assign output_0_ip_identification = output_ip_identification_reg; +assign output_0_ip_flags = output_ip_flags_reg; +assign output_0_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_0_ip_ttl = output_ip_ttl_reg; +assign output_0_ip_protocol = output_ip_protocol_reg; +assign output_0_ip_header_checksum = output_ip_header_checksum_reg; +assign output_0_ip_source_ip = output_ip_source_ip_reg; +assign output_0_ip_dest_ip = output_ip_dest_ip_reg; + +assign output_1_ip_hdr_valid = output_1_ip_hdr_valid_reg; +assign output_1_eth_dest_mac = output_eth_dest_mac_reg; +assign output_1_eth_src_mac = output_eth_src_mac_reg; +assign output_1_eth_type = output_eth_type_reg; +assign output_1_ip_version = output_ip_version_reg; +assign output_1_ip_ihl = output_ip_ihl_reg; +assign output_1_ip_dscp = output_ip_dscp_reg; +assign output_1_ip_ecn = output_ip_ecn_reg; +assign output_1_ip_length = output_ip_length_reg; +assign output_1_ip_identification = output_ip_identification_reg; +assign output_1_ip_flags = output_ip_flags_reg; +assign output_1_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_1_ip_ttl = output_ip_ttl_reg; +assign output_1_ip_protocol = output_ip_protocol_reg; +assign output_1_ip_header_checksum = output_ip_header_checksum_reg; +assign output_1_ip_source_ip = output_ip_source_ip_reg; +assign output_1_ip_dest_ip = output_ip_dest_ip_reg; + +assign output_2_ip_hdr_valid = output_2_ip_hdr_valid_reg; +assign output_2_eth_dest_mac = output_eth_dest_mac_reg; +assign output_2_eth_src_mac = output_eth_src_mac_reg; +assign output_2_eth_type = output_eth_type_reg; +assign output_2_ip_version = output_ip_version_reg; +assign output_2_ip_ihl = output_ip_ihl_reg; +assign output_2_ip_dscp = output_ip_dscp_reg; +assign output_2_ip_ecn = output_ip_ecn_reg; +assign output_2_ip_length = output_ip_length_reg; +assign output_2_ip_identification = output_ip_identification_reg; +assign output_2_ip_flags = output_ip_flags_reg; +assign output_2_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_2_ip_ttl = output_ip_ttl_reg; +assign output_2_ip_protocol = output_ip_protocol_reg; +assign output_2_ip_header_checksum = output_ip_header_checksum_reg; +assign output_2_ip_source_ip = output_ip_source_ip_reg; +assign output_2_ip_dest_ip = output_ip_dest_ip_reg; + +assign output_3_ip_hdr_valid = output_3_ip_hdr_valid_reg; +assign output_3_eth_dest_mac = output_eth_dest_mac_reg; +assign output_3_eth_src_mac = output_eth_src_mac_reg; +assign output_3_eth_type = output_eth_type_reg; +assign output_3_ip_version = output_ip_version_reg; +assign output_3_ip_ihl = output_ip_ihl_reg; +assign output_3_ip_dscp = output_ip_dscp_reg; +assign output_3_ip_ecn = output_ip_ecn_reg; +assign output_3_ip_length = output_ip_length_reg; +assign output_3_ip_identification = output_ip_identification_reg; +assign output_3_ip_flags = output_ip_flags_reg; +assign output_3_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_3_ip_ttl = output_ip_ttl_reg; +assign output_3_ip_protocol = output_ip_protocol_reg; +assign output_3_ip_header_checksum = output_ip_header_checksum_reg; +assign output_3_ip_source_ip = output_ip_source_ip_reg; +assign output_3_ip_dest_ip = output_ip_dest_ip_reg; + +// mux for output control signals +reg current_output_ip_hdr_valid; +reg current_output_ip_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) + 2'd0: begin + current_output_ip_hdr_valid = output_0_ip_hdr_valid; + current_output_ip_hdr_ready = output_0_ip_hdr_ready; + current_output_tvalid = output_0_ip_payload_tvalid; + current_output_tready = output_0_ip_payload_tready; + end + 2'd1: begin + current_output_ip_hdr_valid = output_1_ip_hdr_valid; + current_output_ip_hdr_ready = output_1_ip_hdr_ready; + current_output_tvalid = output_1_ip_payload_tvalid; + current_output_tready = output_1_ip_payload_tready; + end + 2'd2: begin + current_output_ip_hdr_valid = output_2_ip_hdr_valid; + current_output_ip_hdr_ready = output_2_ip_hdr_ready; + current_output_tvalid = output_2_ip_payload_tvalid; + current_output_tready = output_2_ip_payload_tready; + end + 2'd3: begin + current_output_ip_hdr_valid = output_3_ip_hdr_valid; + current_output_ip_hdr_ready = output_3_ip_hdr_ready; + current_output_tvalid = output_3_ip_payload_tvalid; + current_output_tready = output_3_ip_payload_tready; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; + input_ip_payload_tready_next = 0; + output_0_ip_hdr_valid_next = output_0_ip_hdr_valid_reg & ~output_0_ip_hdr_ready; + output_1_ip_hdr_valid_next = output_1_ip_hdr_valid_reg & ~output_1_ip_hdr_ready; + output_2_ip_hdr_valid_next = output_2_ip_hdr_valid_reg & ~output_2_ip_hdr_ready; + output_3_ip_hdr_valid_next = output_3_ip_hdr_valid_reg & ~output_3_ip_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + + if (frame_reg) begin + if (input_ip_payload_tvalid & input_ip_payload_tready) begin + // end of frame detection + frame_next = ~input_ip_payload_tlast; + end + end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_ip_hdr_ready_next = 1; + + case (select) + 2'd0: output_0_ip_hdr_valid_next = 1; + 2'd1: output_1_ip_hdr_valid_next = 1; + 2'd2: output_2_ip_hdr_valid_next = 1; + 2'd3: output_3_ip_hdr_valid_next = 1; + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + output_ip_version_next = input_ip_version; + output_ip_ihl_next = input_ip_ihl; + output_ip_dscp_next = input_ip_dscp; + output_ip_ecn_next = input_ip_ecn; + output_ip_length_next = input_ip_length; + output_ip_identification_next = input_ip_identification; + output_ip_flags_next = input_ip_flags; + output_ip_fragment_offset_next = input_ip_fragment_offset; + output_ip_ttl_next = input_ip_ttl; + output_ip_protocol_next = input_ip_protocol; + output_ip_header_checksum_next = input_ip_header_checksum; + output_ip_source_ip_next = input_ip_source_ip; + output_ip_dest_ip_next = input_ip_dest_ip; + end + + input_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + + output_ip_payload_tdata_int = input_ip_payload_tdata; + output_ip_payload_tkeep_int = input_ip_payload_tkeep; + output_ip_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tready; + output_ip_payload_tlast_int = input_ip_payload_tlast; + output_ip_payload_tuser_int = input_ip_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_ip_hdr_ready_reg <= 0; + input_ip_payload_tready_reg <= 0; + output_0_ip_hdr_valid_reg <= 0; + output_1_ip_hdr_valid_reg <= 0; + output_2_ip_hdr_valid_reg <= 0; + output_3_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + input_ip_payload_tready_reg <= input_ip_payload_tready_next; + output_0_ip_hdr_valid_reg <= output_0_ip_hdr_valid_next; + output_1_ip_hdr_valid_reg <= output_1_ip_hdr_valid_next; + output_2_ip_hdr_valid_reg <= output_2_ip_hdr_valid_next; + output_3_ip_hdr_valid_reg <= output_3_ip_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + end +end + +// output datapath logic +reg [63:0] output_ip_payload_tdata_reg = 0; +reg [7:0] output_ip_payload_tkeep_reg = 0; +reg output_0_ip_payload_tvalid_reg = 0; +reg output_1_ip_payload_tvalid_reg = 0; +reg output_2_ip_payload_tvalid_reg = 0; +reg output_3_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [63:0] temp_ip_payload_tdata_reg = 0; +reg [7:0] temp_ip_payload_tkeep_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign output_0_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_0_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_0_ip_payload_tvalid = output_0_ip_payload_tvalid_reg; +assign output_0_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_0_ip_payload_tuser = output_ip_payload_tuser_reg; + +assign output_1_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_1_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_1_ip_payload_tvalid = output_1_ip_payload_tvalid_reg; +assign output_1_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_1_ip_payload_tuser = output_ip_payload_tuser_reg; + +assign output_2_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_2_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_2_ip_payload_tvalid = output_2_ip_payload_tvalid_reg; +assign output_2_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_2_ip_payload_tuser = output_ip_payload_tuser_reg; + +assign output_3_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_3_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_3_ip_payload_tvalid = output_3_ip_payload_tvalid_reg; +assign output_3_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_3_ip_payload_tuser = output_ip_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tkeep_reg <= 0; + output_0_ip_payload_tvalid_reg <= 0; + output_1_ip_payload_tvalid_reg <= 0; + output_2_ip_payload_tvalid_reg <= 0; + output_3_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + case (select_reg) + 2'd0: output_0_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + 2'd1: output_1_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + 2'd2: output_2_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + 2'd3: output_3_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + endcase + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + case (select_reg) + 2'd0: output_0_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + 2'd1: output_1_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + 2'd2: output_2_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + 2'd3: output_3_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + endcase + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_ip_demux_4.py b/tb/test_ip_demux_4.py new file mode 100755 index 000000000..f0ba7e88f --- /dev/null +++ b/tb/test_ip_demux_4.py @@ -0,0 +1,1111 @@ +#!/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 ip_ep + +module = 'ip_demux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_ip_demux_4(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_0_ip_hdr_valid, + output_0_ip_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_ip_payload_tdata, + output_0_ip_payload_tvalid, + output_0_ip_payload_tready, + output_0_ip_payload_tlast, + output_0_ip_payload_tuser, + output_1_ip_hdr_valid, + output_1_ip_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_ip_payload_tdata, + output_1_ip_payload_tvalid, + output_1_ip_payload_tready, + output_1_ip_payload_tlast, + output_1_ip_payload_tuser, + output_2_ip_hdr_valid, + output_2_ip_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_ip_payload_tdata, + output_2_ip_payload_tvalid, + output_2_ip_payload_tready, + output_2_ip_payload_tlast, + output_2_ip_payload_tuser, + output_3_ip_hdr_valid, + output_3_ip_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_ip_payload_tdata, + output_3_ip_payload_tvalid, + output_3_ip_payload_tready, + output_3_ip_payload_tlast, + output_3_ip_payload_tuser, + + enable, + select): + + 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_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_0_ip_hdr_valid=output_0_ip_hdr_valid, + output_0_ip_hdr_ready=output_0_ip_hdr_ready, + output_0_eth_dest_mac=output_0_eth_dest_mac, + output_0_eth_src_mac=output_0_eth_src_mac, + output_0_eth_type=output_0_eth_type, + output_0_ip_version=output_0_ip_version, + output_0_ip_ihl=output_0_ip_ihl, + output_0_ip_dscp=output_0_ip_dscp, + output_0_ip_ecn=output_0_ip_ecn, + output_0_ip_length=output_0_ip_length, + output_0_ip_identification=output_0_ip_identification, + output_0_ip_flags=output_0_ip_flags, + output_0_ip_fragment_offset=output_0_ip_fragment_offset, + output_0_ip_ttl=output_0_ip_ttl, + output_0_ip_protocol=output_0_ip_protocol, + output_0_ip_header_checksum=output_0_ip_header_checksum, + output_0_ip_source_ip=output_0_ip_source_ip, + output_0_ip_dest_ip=output_0_ip_dest_ip, + output_0_ip_payload_tdata=output_0_ip_payload_tdata, + output_0_ip_payload_tvalid=output_0_ip_payload_tvalid, + output_0_ip_payload_tready=output_0_ip_payload_tready, + output_0_ip_payload_tlast=output_0_ip_payload_tlast, + output_0_ip_payload_tuser=output_0_ip_payload_tuser, + output_1_ip_hdr_valid=output_1_ip_hdr_valid, + output_1_ip_hdr_ready=output_1_ip_hdr_ready, + output_1_eth_dest_mac=output_1_eth_dest_mac, + output_1_eth_src_mac=output_1_eth_src_mac, + output_1_eth_type=output_1_eth_type, + output_1_ip_version=output_1_ip_version, + output_1_ip_ihl=output_1_ip_ihl, + output_1_ip_dscp=output_1_ip_dscp, + output_1_ip_ecn=output_1_ip_ecn, + output_1_ip_length=output_1_ip_length, + output_1_ip_identification=output_1_ip_identification, + output_1_ip_flags=output_1_ip_flags, + output_1_ip_fragment_offset=output_1_ip_fragment_offset, + output_1_ip_ttl=output_1_ip_ttl, + output_1_ip_protocol=output_1_ip_protocol, + output_1_ip_header_checksum=output_1_ip_header_checksum, + output_1_ip_source_ip=output_1_ip_source_ip, + output_1_ip_dest_ip=output_1_ip_dest_ip, + output_1_ip_payload_tdata=output_1_ip_payload_tdata, + output_1_ip_payload_tvalid=output_1_ip_payload_tvalid, + output_1_ip_payload_tready=output_1_ip_payload_tready, + output_1_ip_payload_tlast=output_1_ip_payload_tlast, + output_1_ip_payload_tuser=output_1_ip_payload_tuser, + output_2_ip_hdr_valid=output_2_ip_hdr_valid, + output_2_ip_hdr_ready=output_2_ip_hdr_ready, + output_2_eth_dest_mac=output_2_eth_dest_mac, + output_2_eth_src_mac=output_2_eth_src_mac, + output_2_eth_type=output_2_eth_type, + output_2_ip_version=output_2_ip_version, + output_2_ip_ihl=output_2_ip_ihl, + output_2_ip_dscp=output_2_ip_dscp, + output_2_ip_ecn=output_2_ip_ecn, + output_2_ip_length=output_2_ip_length, + output_2_ip_identification=output_2_ip_identification, + output_2_ip_flags=output_2_ip_flags, + output_2_ip_fragment_offset=output_2_ip_fragment_offset, + output_2_ip_ttl=output_2_ip_ttl, + output_2_ip_protocol=output_2_ip_protocol, + output_2_ip_header_checksum=output_2_ip_header_checksum, + output_2_ip_source_ip=output_2_ip_source_ip, + output_2_ip_dest_ip=output_2_ip_dest_ip, + output_2_ip_payload_tdata=output_2_ip_payload_tdata, + output_2_ip_payload_tvalid=output_2_ip_payload_tvalid, + output_2_ip_payload_tready=output_2_ip_payload_tready, + output_2_ip_payload_tlast=output_2_ip_payload_tlast, + output_2_ip_payload_tuser=output_2_ip_payload_tuser, + output_3_ip_hdr_valid=output_3_ip_hdr_valid, + output_3_ip_hdr_ready=output_3_ip_hdr_ready, + output_3_eth_dest_mac=output_3_eth_dest_mac, + output_3_eth_src_mac=output_3_eth_src_mac, + output_3_eth_type=output_3_eth_type, + output_3_ip_version=output_3_ip_version, + output_3_ip_ihl=output_3_ip_ihl, + output_3_ip_dscp=output_3_ip_dscp, + output_3_ip_ecn=output_3_ip_ecn, + output_3_ip_length=output_3_ip_length, + output_3_ip_identification=output_3_ip_identification, + output_3_ip_flags=output_3_ip_flags, + output_3_ip_fragment_offset=output_3_ip_fragment_offset, + output_3_ip_ttl=output_3_ip_ttl, + output_3_ip_protocol=output_3_ip_protocol, + output_3_ip_header_checksum=output_3_ip_header_checksum, + output_3_ip_source_ip=output_3_ip_source_ip, + output_3_ip_dest_ip=output_3_ip_dest_ip, + output_3_ip_payload_tdata=output_3_ip_payload_tdata, + output_3_ip_payload_tvalid=output_3_ip_payload_tvalid, + output_3_ip_payload_tready=output_3_ip_payload_tready, + output_3_ip_payload_tlast=output_3_ip_payload_tlast, + output_3_ip_payload_tuser=output_3_ip_payload_tuser, + + enable=enable, + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_ip_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + + output_0_ip_hdr_ready = Signal(bool(0)) + output_0_ip_payload_tready = Signal(bool(0)) + output_1_ip_hdr_ready = Signal(bool(0)) + output_1_ip_payload_tready = Signal(bool(0)) + output_2_ip_hdr_ready = Signal(bool(0)) + output_2_ip_payload_tready = Signal(bool(0)) + output_3_ip_hdr_ready = Signal(bool(0)) + output_3_ip_payload_tready = Signal(bool(0)) + + enable = Signal(bool(0)) + select = Signal(intbv(0)[2:]) + + # Outputs + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + + output_0_ip_hdr_valid = Signal(bool(0)) + output_0_eth_dest_mac = Signal(intbv(0)[48:]) + output_0_eth_src_mac = Signal(intbv(0)[48:]) + output_0_eth_type = Signal(intbv(0)[16:]) + output_0_ip_version = Signal(intbv(0)[4:]) + output_0_ip_ihl = Signal(intbv(0)[4:]) + output_0_ip_dscp = Signal(intbv(0)[6:]) + output_0_ip_ecn = Signal(intbv(0)[2:]) + output_0_ip_length = Signal(intbv(0)[16:]) + output_0_ip_identification = Signal(intbv(0)[16:]) + output_0_ip_flags = Signal(intbv(0)[3:]) + output_0_ip_fragment_offset = Signal(intbv(0)[13:]) + output_0_ip_ttl = Signal(intbv(0)[8:]) + output_0_ip_protocol = Signal(intbv(0)[8:]) + output_0_ip_header_checksum = Signal(intbv(0)[16:]) + output_0_ip_source_ip = Signal(intbv(0)[32:]) + output_0_ip_dest_ip = Signal(intbv(0)[32:]) + output_0_ip_payload_tdata = Signal(intbv(0)[8:]) + output_0_ip_payload_tvalid = Signal(bool(0)) + output_0_ip_payload_tlast = Signal(bool(0)) + output_0_ip_payload_tuser = Signal(bool(0)) + output_1_ip_hdr_valid = Signal(bool(0)) + output_1_eth_dest_mac = Signal(intbv(0)[48:]) + output_1_eth_src_mac = Signal(intbv(0)[48:]) + output_1_eth_type = Signal(intbv(0)[16:]) + output_1_ip_version = Signal(intbv(0)[4:]) + output_1_ip_ihl = Signal(intbv(0)[4:]) + output_1_ip_dscp = Signal(intbv(0)[6:]) + output_1_ip_ecn = Signal(intbv(0)[2:]) + output_1_ip_length = Signal(intbv(0)[16:]) + output_1_ip_identification = Signal(intbv(0)[16:]) + output_1_ip_flags = Signal(intbv(0)[3:]) + output_1_ip_fragment_offset = Signal(intbv(0)[13:]) + output_1_ip_ttl = Signal(intbv(0)[8:]) + output_1_ip_protocol = Signal(intbv(0)[8:]) + output_1_ip_header_checksum = Signal(intbv(0)[16:]) + output_1_ip_source_ip = Signal(intbv(0)[32:]) + output_1_ip_dest_ip = Signal(intbv(0)[32:]) + output_1_ip_payload_tdata = Signal(intbv(0)[8:]) + output_1_ip_payload_tvalid = Signal(bool(0)) + output_1_ip_payload_tlast = Signal(bool(0)) + output_1_ip_payload_tuser = Signal(bool(0)) + output_2_ip_hdr_valid = Signal(bool(0)) + output_2_eth_dest_mac = Signal(intbv(0)[48:]) + output_2_eth_src_mac = Signal(intbv(0)[48:]) + output_2_eth_type = Signal(intbv(0)[16:]) + output_2_ip_version = Signal(intbv(0)[4:]) + output_2_ip_ihl = Signal(intbv(0)[4:]) + output_2_ip_dscp = Signal(intbv(0)[6:]) + output_2_ip_ecn = Signal(intbv(0)[2:]) + output_2_ip_length = Signal(intbv(0)[16:]) + output_2_ip_identification = Signal(intbv(0)[16:]) + output_2_ip_flags = Signal(intbv(0)[3:]) + output_2_ip_fragment_offset = Signal(intbv(0)[13:]) + output_2_ip_ttl = Signal(intbv(0)[8:]) + output_2_ip_protocol = Signal(intbv(0)[8:]) + output_2_ip_header_checksum = Signal(intbv(0)[16:]) + output_2_ip_source_ip = Signal(intbv(0)[32:]) + output_2_ip_dest_ip = Signal(intbv(0)[32:]) + output_2_ip_payload_tdata = Signal(intbv(0)[8:]) + output_2_ip_payload_tvalid = Signal(bool(0)) + output_2_ip_payload_tlast = Signal(bool(0)) + output_2_ip_payload_tuser = Signal(bool(0)) + output_3_ip_hdr_valid = Signal(bool(0)) + output_3_eth_dest_mac = Signal(intbv(0)[48:]) + output_3_eth_src_mac = Signal(intbv(0)[48:]) + output_3_eth_type = Signal(intbv(0)[16:]) + output_3_ip_version = Signal(intbv(0)[4:]) + output_3_ip_ihl = Signal(intbv(0)[4:]) + output_3_ip_dscp = Signal(intbv(0)[6:]) + output_3_ip_ecn = Signal(intbv(0)[2:]) + output_3_ip_length = Signal(intbv(0)[16:]) + output_3_ip_identification = Signal(intbv(0)[16:]) + output_3_ip_flags = Signal(intbv(0)[3:]) + output_3_ip_fragment_offset = Signal(intbv(0)[13:]) + output_3_ip_ttl = Signal(intbv(0)[8:]) + output_3_ip_protocol = Signal(intbv(0)[8:]) + output_3_ip_header_checksum = Signal(intbv(0)[16:]) + output_3_ip_source_ip = Signal(intbv(0)[32:]) + output_3_ip_dest_ip = Signal(intbv(0)[32:]) + output_3_ip_payload_tdata = Signal(intbv(0)[8:]) + output_3_ip_payload_tvalid = Signal(bool(0)) + output_3_ip_payload_tlast = Signal(bool(0)) + output_3_ip_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_pause = Signal(bool(0)) + + source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_ip_hdr_ready, + ip_hdr_valid=input_ip_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink_0 = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_0_ip_hdr_ready, + ip_hdr_valid=output_0_ip_hdr_valid, + eth_dest_mac=output_0_eth_dest_mac, + eth_src_mac=output_0_eth_src_mac, + eth_type=output_0_eth_type, + ip_version=output_0_ip_version, + ip_ihl=output_0_ip_ihl, + ip_dscp=output_0_ip_dscp, + ip_ecn=output_0_ip_ecn, + ip_length=output_0_ip_length, + ip_identification=output_0_ip_identification, + ip_flags=output_0_ip_flags, + ip_fragment_offset=output_0_ip_fragment_offset, + ip_ttl=output_0_ip_ttl, + ip_protocol=output_0_ip_protocol, + ip_header_checksum=output_0_ip_header_checksum, + ip_source_ip=output_0_ip_source_ip, + ip_dest_ip=output_0_ip_dest_ip, + ip_payload_tdata=output_0_ip_payload_tdata, + ip_payload_tvalid=output_0_ip_payload_tvalid, + ip_payload_tready=output_0_ip_payload_tready, + ip_payload_tlast=output_0_ip_payload_tlast, + ip_payload_tuser=output_0_ip_payload_tuser, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + + sink_1 = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_1_ip_hdr_ready, + ip_hdr_valid=output_1_ip_hdr_valid, + eth_dest_mac=output_1_eth_dest_mac, + eth_src_mac=output_1_eth_src_mac, + eth_type=output_1_eth_type, + ip_version=output_1_ip_version, + ip_ihl=output_1_ip_ihl, + ip_dscp=output_1_ip_dscp, + ip_ecn=output_1_ip_ecn, + ip_length=output_1_ip_length, + ip_identification=output_1_ip_identification, + ip_flags=output_1_ip_flags, + ip_fragment_offset=output_1_ip_fragment_offset, + ip_ttl=output_1_ip_ttl, + ip_protocol=output_1_ip_protocol, + ip_header_checksum=output_1_ip_header_checksum, + ip_source_ip=output_1_ip_source_ip, + ip_dest_ip=output_1_ip_dest_ip, + ip_payload_tdata=output_1_ip_payload_tdata, + ip_payload_tvalid=output_1_ip_payload_tvalid, + ip_payload_tready=output_1_ip_payload_tready, + ip_payload_tlast=output_1_ip_payload_tlast, + ip_payload_tuser=output_1_ip_payload_tuser, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + + sink_2 = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_2_ip_hdr_ready, + ip_hdr_valid=output_2_ip_hdr_valid, + eth_dest_mac=output_2_eth_dest_mac, + eth_src_mac=output_2_eth_src_mac, + eth_type=output_2_eth_type, + ip_version=output_2_ip_version, + ip_ihl=output_2_ip_ihl, + ip_dscp=output_2_ip_dscp, + ip_ecn=output_2_ip_ecn, + ip_length=output_2_ip_length, + ip_identification=output_2_ip_identification, + ip_flags=output_2_ip_flags, + ip_fragment_offset=output_2_ip_fragment_offset, + ip_ttl=output_2_ip_ttl, + ip_protocol=output_2_ip_protocol, + ip_header_checksum=output_2_ip_header_checksum, + ip_source_ip=output_2_ip_source_ip, + ip_dest_ip=output_2_ip_dest_ip, + ip_payload_tdata=output_2_ip_payload_tdata, + ip_payload_tvalid=output_2_ip_payload_tvalid, + ip_payload_tready=output_2_ip_payload_tready, + ip_payload_tlast=output_2_ip_payload_tlast, + ip_payload_tuser=output_2_ip_payload_tuser, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + + sink_3 = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_3_ip_hdr_ready, + ip_hdr_valid=output_3_ip_hdr_valid, + eth_dest_mac=output_3_eth_dest_mac, + eth_src_mac=output_3_eth_src_mac, + eth_type=output_3_eth_type, + ip_version=output_3_ip_version, + ip_ihl=output_3_ip_ihl, + ip_dscp=output_3_ip_dscp, + ip_ecn=output_3_ip_ecn, + ip_length=output_3_ip_length, + ip_identification=output_3_ip_identification, + ip_flags=output_3_ip_flags, + ip_fragment_offset=output_3_ip_fragment_offset, + ip_ttl=output_3_ip_ttl, + ip_protocol=output_3_ip_protocol, + ip_header_checksum=output_3_ip_header_checksum, + ip_source_ip=output_3_ip_source_ip, + ip_dest_ip=output_3_ip_dest_ip, + ip_payload_tdata=output_3_ip_payload_tdata, + ip_payload_tvalid=output_3_ip_payload_tvalid, + ip_payload_tready=output_3_ip_payload_tready, + ip_payload_tlast=output_3_ip_payload_tlast, + ip_payload_tuser=output_3_ip_payload_tuser, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_ip_demux_4(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_0_ip_hdr_valid, + output_0_ip_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_ip_payload_tdata, + output_0_ip_payload_tvalid, + output_0_ip_payload_tready, + output_0_ip_payload_tlast, + output_0_ip_payload_tuser, + output_1_ip_hdr_valid, + output_1_ip_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_ip_payload_tdata, + output_1_ip_payload_tvalid, + output_1_ip_payload_tready, + output_1_ip_payload_tlast, + output_1_ip_payload_tuser, + output_2_ip_hdr_valid, + output_2_ip_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_ip_payload_tdata, + output_2_ip_payload_tvalid, + output_2_ip_payload_tready, + output_2_ip_payload_tlast, + output_2_ip_payload_tuser, + output_3_ip_hdr_valid, + output_3_ip_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_ip_payload_tdata, + output_3_ip_payload_tvalid, + output_3_ip_payload_tready, + output_3_ip_payload_tlast, + output_3_ip_payload_tuser, + + enable, + select) + + @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 + enable.next = True + + yield clk.posedge + print("test 1: select port 0") + current_test.next = 1 + + select.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_queue.put(test_frame) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_queue.put(test_frame) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + sink_0_pause.next = True + sink_1_pause.next = True + sink_2_pause.next = True + sink_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_0_pause.next = False + sink_1_pause.next = False + sink_2_pause.next = False + sink_3_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + raise StopSimulation + + return dut, source, sink_0, sink_1, sink_2, sink_3, 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() + diff --git a/tb/test_ip_demux_4.v b/tb/test_ip_demux_4.v new file mode 100644 index 000000000..32beaabe1 --- /dev/null +++ b/tb/test_ip_demux_4.v @@ -0,0 +1,413 @@ +/* + +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_ip_demux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_ip_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [7:0] input_ip_payload_tdata = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; + +reg output_0_ip_hdr_ready = 0; +reg output_0_ip_payload_tready = 0; +reg output_1_ip_hdr_ready = 0; +reg output_1_ip_payload_tready = 0; +reg output_2_ip_hdr_ready = 0; +reg output_2_ip_payload_tready = 0; +reg output_3_ip_hdr_ready = 0; +reg output_3_ip_payload_tready = 0; + +reg enable = 0; +reg [1:0] select = 0; + +// Outputs +wire input_ip_hdr_ready; +wire input_ip_payload_tready; + +wire output_0_ip_hdr_valid; +wire [47:0] output_0_eth_dest_mac; +wire [47:0] output_0_eth_src_mac; +wire [15:0] output_0_eth_type; +wire [3:0] output_0_ip_version; +wire [3:0] output_0_ip_ihl; +wire [5:0] output_0_ip_dscp; +wire [1:0] output_0_ip_ecn; +wire [15:0] output_0_ip_length; +wire [15:0] output_0_ip_identification; +wire [2:0] output_0_ip_flags; +wire [12:0] output_0_ip_fragment_offset; +wire [7:0] output_0_ip_ttl; +wire [7:0] output_0_ip_protocol; +wire [15:0] output_0_ip_header_checksum; +wire [31:0] output_0_ip_source_ip; +wire [31:0] output_0_ip_dest_ip; +wire [7:0] output_0_ip_payload_tdata; +wire output_0_ip_payload_tvalid; +wire output_0_ip_payload_tlast; +wire output_0_ip_payload_tuser; +wire output_1_ip_hdr_valid; +wire [47:0] output_1_eth_dest_mac; +wire [47:0] output_1_eth_src_mac; +wire [15:0] output_1_eth_type; +wire [3:0] output_1_ip_version; +wire [3:0] output_1_ip_ihl; +wire [5:0] output_1_ip_dscp; +wire [1:0] output_1_ip_ecn; +wire [15:0] output_1_ip_length; +wire [15:0] output_1_ip_identification; +wire [2:0] output_1_ip_flags; +wire [12:0] output_1_ip_fragment_offset; +wire [7:0] output_1_ip_ttl; +wire [7:0] output_1_ip_protocol; +wire [15:0] output_1_ip_header_checksum; +wire [31:0] output_1_ip_source_ip; +wire [31:0] output_1_ip_dest_ip; +wire [7:0] output_1_ip_payload_tdata; +wire output_1_ip_payload_tvalid; +wire output_1_ip_payload_tlast; +wire output_1_ip_payload_tuser; +wire output_2_ip_hdr_valid; +wire [47:0] output_2_eth_dest_mac; +wire [47:0] output_2_eth_src_mac; +wire [15:0] output_2_eth_type; +wire [3:0] output_2_ip_version; +wire [3:0] output_2_ip_ihl; +wire [5:0] output_2_ip_dscp; +wire [1:0] output_2_ip_ecn; +wire [15:0] output_2_ip_length; +wire [15:0] output_2_ip_identification; +wire [2:0] output_2_ip_flags; +wire [12:0] output_2_ip_fragment_offset; +wire [7:0] output_2_ip_ttl; +wire [7:0] output_2_ip_protocol; +wire [15:0] output_2_ip_header_checksum; +wire [31:0] output_2_ip_source_ip; +wire [31:0] output_2_ip_dest_ip; +wire [7:0] output_2_ip_payload_tdata; +wire output_2_ip_payload_tvalid; +wire output_2_ip_payload_tlast; +wire output_2_ip_payload_tuser; +wire output_3_ip_hdr_valid; +wire [47:0] output_3_eth_dest_mac; +wire [47:0] output_3_eth_src_mac; +wire [15:0] output_3_eth_type; +wire [3:0] output_3_ip_version; +wire [3:0] output_3_ip_ihl; +wire [5:0] output_3_ip_dscp; +wire [1:0] output_3_ip_ecn; +wire [15:0] output_3_ip_length; +wire [15:0] output_3_ip_identification; +wire [2:0] output_3_ip_flags; +wire [12:0] output_3_ip_fragment_offset; +wire [7:0] output_3_ip_ttl; +wire [7:0] output_3_ip_protocol; +wire [15:0] output_3_ip_header_checksum; +wire [31:0] output_3_ip_source_ip; +wire [31:0] output_3_ip_dest_ip; +wire [7:0] output_3_ip_payload_tdata; +wire output_3_ip_payload_tvalid; +wire output_3_ip_payload_tlast; +wire output_3_ip_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_ip_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + output_0_ip_hdr_ready, + output_0_ip_payload_tready, + output_1_ip_hdr_ready, + output_1_ip_payload_tready, + output_2_ip_hdr_ready, + output_2_ip_payload_tready, + output_3_ip_hdr_ready, + output_3_ip_payload_tready, + enable, + select); + $to_myhdl(input_ip_hdr_ready, + input_ip_payload_tready, + output_0_ip_hdr_valid, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_ip_payload_tdata, + output_0_ip_payload_tvalid, + output_0_ip_payload_tlast, + output_0_ip_payload_tuser, + output_1_ip_hdr_valid, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_ip_payload_tdata, + output_1_ip_payload_tvalid, + output_1_ip_payload_tlast, + output_1_ip_payload_tuser, + output_2_ip_hdr_valid, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_ip_payload_tdata, + output_2_ip_payload_tvalid, + output_2_ip_payload_tlast, + output_2_ip_payload_tuser, + output_3_ip_hdr_valid, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_ip_payload_tdata, + output_3_ip_payload_tvalid, + output_3_ip_payload_tlast, + output_3_ip_payload_tuser); + + // dump file + $dumpfile("test_ip_demux_4.lxt"); + $dumpvars(0, test_ip_demux_4); +end + +ip_demux_4 +UUT ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame outputs + .output_0_ip_hdr_valid(output_0_ip_hdr_valid), + .output_0_ip_hdr_ready(output_0_ip_hdr_ready), + .output_0_eth_dest_mac(output_0_eth_dest_mac), + .output_0_eth_src_mac(output_0_eth_src_mac), + .output_0_eth_type(output_0_eth_type), + .output_0_ip_version(output_0_ip_version), + .output_0_ip_ihl(output_0_ip_ihl), + .output_0_ip_dscp(output_0_ip_dscp), + .output_0_ip_ecn(output_0_ip_ecn), + .output_0_ip_length(output_0_ip_length), + .output_0_ip_identification(output_0_ip_identification), + .output_0_ip_flags(output_0_ip_flags), + .output_0_ip_fragment_offset(output_0_ip_fragment_offset), + .output_0_ip_ttl(output_0_ip_ttl), + .output_0_ip_protocol(output_0_ip_protocol), + .output_0_ip_header_checksum(output_0_ip_header_checksum), + .output_0_ip_source_ip(output_0_ip_source_ip), + .output_0_ip_dest_ip(output_0_ip_dest_ip), + .output_0_ip_payload_tdata(output_0_ip_payload_tdata), + .output_0_ip_payload_tvalid(output_0_ip_payload_tvalid), + .output_0_ip_payload_tready(output_0_ip_payload_tready), + .output_0_ip_payload_tlast(output_0_ip_payload_tlast), + .output_0_ip_payload_tuser(output_0_ip_payload_tuser), + .output_1_ip_hdr_valid(output_1_ip_hdr_valid), + .output_1_ip_hdr_ready(output_1_ip_hdr_ready), + .output_1_eth_dest_mac(output_1_eth_dest_mac), + .output_1_eth_src_mac(output_1_eth_src_mac), + .output_1_eth_type(output_1_eth_type), + .output_1_ip_version(output_1_ip_version), + .output_1_ip_ihl(output_1_ip_ihl), + .output_1_ip_dscp(output_1_ip_dscp), + .output_1_ip_ecn(output_1_ip_ecn), + .output_1_ip_length(output_1_ip_length), + .output_1_ip_identification(output_1_ip_identification), + .output_1_ip_flags(output_1_ip_flags), + .output_1_ip_fragment_offset(output_1_ip_fragment_offset), + .output_1_ip_ttl(output_1_ip_ttl), + .output_1_ip_protocol(output_1_ip_protocol), + .output_1_ip_header_checksum(output_1_ip_header_checksum), + .output_1_ip_source_ip(output_1_ip_source_ip), + .output_1_ip_dest_ip(output_1_ip_dest_ip), + .output_1_ip_payload_tdata(output_1_ip_payload_tdata), + .output_1_ip_payload_tvalid(output_1_ip_payload_tvalid), + .output_1_ip_payload_tready(output_1_ip_payload_tready), + .output_1_ip_payload_tlast(output_1_ip_payload_tlast), + .output_1_ip_payload_tuser(output_1_ip_payload_tuser), + .output_2_ip_hdr_valid(output_2_ip_hdr_valid), + .output_2_ip_hdr_ready(output_2_ip_hdr_ready), + .output_2_eth_dest_mac(output_2_eth_dest_mac), + .output_2_eth_src_mac(output_2_eth_src_mac), + .output_2_eth_type(output_2_eth_type), + .output_2_ip_version(output_2_ip_version), + .output_2_ip_ihl(output_2_ip_ihl), + .output_2_ip_dscp(output_2_ip_dscp), + .output_2_ip_ecn(output_2_ip_ecn), + .output_2_ip_length(output_2_ip_length), + .output_2_ip_identification(output_2_ip_identification), + .output_2_ip_flags(output_2_ip_flags), + .output_2_ip_fragment_offset(output_2_ip_fragment_offset), + .output_2_ip_ttl(output_2_ip_ttl), + .output_2_ip_protocol(output_2_ip_protocol), + .output_2_ip_header_checksum(output_2_ip_header_checksum), + .output_2_ip_source_ip(output_2_ip_source_ip), + .output_2_ip_dest_ip(output_2_ip_dest_ip), + .output_2_ip_payload_tdata(output_2_ip_payload_tdata), + .output_2_ip_payload_tvalid(output_2_ip_payload_tvalid), + .output_2_ip_payload_tready(output_2_ip_payload_tready), + .output_2_ip_payload_tlast(output_2_ip_payload_tlast), + .output_2_ip_payload_tuser(output_2_ip_payload_tuser), + .output_3_ip_hdr_valid(output_3_ip_hdr_valid), + .output_3_ip_hdr_ready(output_3_ip_hdr_ready), + .output_3_eth_dest_mac(output_3_eth_dest_mac), + .output_3_eth_src_mac(output_3_eth_src_mac), + .output_3_eth_type(output_3_eth_type), + .output_3_ip_version(output_3_ip_version), + .output_3_ip_ihl(output_3_ip_ihl), + .output_3_ip_dscp(output_3_ip_dscp), + .output_3_ip_ecn(output_3_ip_ecn), + .output_3_ip_length(output_3_ip_length), + .output_3_ip_identification(output_3_ip_identification), + .output_3_ip_flags(output_3_ip_flags), + .output_3_ip_fragment_offset(output_3_ip_fragment_offset), + .output_3_ip_ttl(output_3_ip_ttl), + .output_3_ip_protocol(output_3_ip_protocol), + .output_3_ip_header_checksum(output_3_ip_header_checksum), + .output_3_ip_source_ip(output_3_ip_source_ip), + .output_3_ip_dest_ip(output_3_ip_dest_ip), + .output_3_ip_payload_tdata(output_3_ip_payload_tdata), + .output_3_ip_payload_tvalid(output_3_ip_payload_tvalid), + .output_3_ip_payload_tready(output_3_ip_payload_tready), + .output_3_ip_payload_tlast(output_3_ip_payload_tlast), + .output_3_ip_payload_tuser(output_3_ip_payload_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule diff --git a/tb/test_ip_demux_64_4.py b/tb/test_ip_demux_64_4.py new file mode 100755 index 000000000..d7f87954d --- /dev/null +++ b/tb/test_ip_demux_64_4.py @@ -0,0 +1,1136 @@ +#!/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 ip_ep + +module = 'ip_demux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_ip_demux_64_4(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_0_ip_hdr_valid, + output_0_ip_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_ip_payload_tdata, + output_0_ip_payload_tkeep, + output_0_ip_payload_tvalid, + output_0_ip_payload_tready, + output_0_ip_payload_tlast, + output_0_ip_payload_tuser, + output_1_ip_hdr_valid, + output_1_ip_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_ip_payload_tdata, + output_1_ip_payload_tkeep, + output_1_ip_payload_tvalid, + output_1_ip_payload_tready, + output_1_ip_payload_tlast, + output_1_ip_payload_tuser, + output_2_ip_hdr_valid, + output_2_ip_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_ip_payload_tdata, + output_2_ip_payload_tkeep, + output_2_ip_payload_tvalid, + output_2_ip_payload_tready, + output_2_ip_payload_tlast, + output_2_ip_payload_tuser, + output_3_ip_hdr_valid, + output_3_ip_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_ip_payload_tdata, + output_3_ip_payload_tkeep, + output_3_ip_payload_tvalid, + output_3_ip_payload_tready, + output_3_ip_payload_tlast, + output_3_ip_payload_tuser, + + enable, + select): + + 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_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tkeep=input_ip_payload_tkeep, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_0_ip_hdr_valid=output_0_ip_hdr_valid, + output_0_ip_hdr_ready=output_0_ip_hdr_ready, + output_0_eth_dest_mac=output_0_eth_dest_mac, + output_0_eth_src_mac=output_0_eth_src_mac, + output_0_eth_type=output_0_eth_type, + output_0_ip_version=output_0_ip_version, + output_0_ip_ihl=output_0_ip_ihl, + output_0_ip_dscp=output_0_ip_dscp, + output_0_ip_ecn=output_0_ip_ecn, + output_0_ip_length=output_0_ip_length, + output_0_ip_identification=output_0_ip_identification, + output_0_ip_flags=output_0_ip_flags, + output_0_ip_fragment_offset=output_0_ip_fragment_offset, + output_0_ip_ttl=output_0_ip_ttl, + output_0_ip_protocol=output_0_ip_protocol, + output_0_ip_header_checksum=output_0_ip_header_checksum, + output_0_ip_source_ip=output_0_ip_source_ip, + output_0_ip_dest_ip=output_0_ip_dest_ip, + output_0_ip_payload_tdata=output_0_ip_payload_tdata, + output_0_ip_payload_tkeep=output_0_ip_payload_tkeep, + output_0_ip_payload_tvalid=output_0_ip_payload_tvalid, + output_0_ip_payload_tready=output_0_ip_payload_tready, + output_0_ip_payload_tlast=output_0_ip_payload_tlast, + output_0_ip_payload_tuser=output_0_ip_payload_tuser, + output_1_ip_hdr_valid=output_1_ip_hdr_valid, + output_1_ip_hdr_ready=output_1_ip_hdr_ready, + output_1_eth_dest_mac=output_1_eth_dest_mac, + output_1_eth_src_mac=output_1_eth_src_mac, + output_1_eth_type=output_1_eth_type, + output_1_ip_version=output_1_ip_version, + output_1_ip_ihl=output_1_ip_ihl, + output_1_ip_dscp=output_1_ip_dscp, + output_1_ip_ecn=output_1_ip_ecn, + output_1_ip_length=output_1_ip_length, + output_1_ip_identification=output_1_ip_identification, + output_1_ip_flags=output_1_ip_flags, + output_1_ip_fragment_offset=output_1_ip_fragment_offset, + output_1_ip_ttl=output_1_ip_ttl, + output_1_ip_protocol=output_1_ip_protocol, + output_1_ip_header_checksum=output_1_ip_header_checksum, + output_1_ip_source_ip=output_1_ip_source_ip, + output_1_ip_dest_ip=output_1_ip_dest_ip, + output_1_ip_payload_tdata=output_1_ip_payload_tdata, + output_1_ip_payload_tkeep=output_1_ip_payload_tkeep, + output_1_ip_payload_tvalid=output_1_ip_payload_tvalid, + output_1_ip_payload_tready=output_1_ip_payload_tready, + output_1_ip_payload_tlast=output_1_ip_payload_tlast, + output_1_ip_payload_tuser=output_1_ip_payload_tuser, + output_2_ip_hdr_valid=output_2_ip_hdr_valid, + output_2_ip_hdr_ready=output_2_ip_hdr_ready, + output_2_eth_dest_mac=output_2_eth_dest_mac, + output_2_eth_src_mac=output_2_eth_src_mac, + output_2_eth_type=output_2_eth_type, + output_2_ip_version=output_2_ip_version, + output_2_ip_ihl=output_2_ip_ihl, + output_2_ip_dscp=output_2_ip_dscp, + output_2_ip_ecn=output_2_ip_ecn, + output_2_ip_length=output_2_ip_length, + output_2_ip_identification=output_2_ip_identification, + output_2_ip_flags=output_2_ip_flags, + output_2_ip_fragment_offset=output_2_ip_fragment_offset, + output_2_ip_ttl=output_2_ip_ttl, + output_2_ip_protocol=output_2_ip_protocol, + output_2_ip_header_checksum=output_2_ip_header_checksum, + output_2_ip_source_ip=output_2_ip_source_ip, + output_2_ip_dest_ip=output_2_ip_dest_ip, + output_2_ip_payload_tdata=output_2_ip_payload_tdata, + output_2_ip_payload_tkeep=output_2_ip_payload_tkeep, + output_2_ip_payload_tvalid=output_2_ip_payload_tvalid, + output_2_ip_payload_tready=output_2_ip_payload_tready, + output_2_ip_payload_tlast=output_2_ip_payload_tlast, + output_2_ip_payload_tuser=output_2_ip_payload_tuser, + output_3_ip_hdr_valid=output_3_ip_hdr_valid, + output_3_ip_hdr_ready=output_3_ip_hdr_ready, + output_3_eth_dest_mac=output_3_eth_dest_mac, + output_3_eth_src_mac=output_3_eth_src_mac, + output_3_eth_type=output_3_eth_type, + output_3_ip_version=output_3_ip_version, + output_3_ip_ihl=output_3_ip_ihl, + output_3_ip_dscp=output_3_ip_dscp, + output_3_ip_ecn=output_3_ip_ecn, + output_3_ip_length=output_3_ip_length, + output_3_ip_identification=output_3_ip_identification, + output_3_ip_flags=output_3_ip_flags, + output_3_ip_fragment_offset=output_3_ip_fragment_offset, + output_3_ip_ttl=output_3_ip_ttl, + output_3_ip_protocol=output_3_ip_protocol, + output_3_ip_header_checksum=output_3_ip_header_checksum, + output_3_ip_source_ip=output_3_ip_source_ip, + output_3_ip_dest_ip=output_3_ip_dest_ip, + output_3_ip_payload_tdata=output_3_ip_payload_tdata, + output_3_ip_payload_tkeep=output_3_ip_payload_tkeep, + output_3_ip_payload_tvalid=output_3_ip_payload_tvalid, + output_3_ip_payload_tready=output_3_ip_payload_tready, + output_3_ip_payload_tlast=output_3_ip_payload_tlast, + output_3_ip_payload_tuser=output_3_ip_payload_tuser, + + enable=enable, + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_ip_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[64:]) + input_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + + output_0_ip_hdr_ready = Signal(bool(0)) + output_0_ip_payload_tready = Signal(bool(0)) + output_1_ip_hdr_ready = Signal(bool(0)) + output_1_ip_payload_tready = Signal(bool(0)) + output_2_ip_hdr_ready = Signal(bool(0)) + output_2_ip_payload_tready = Signal(bool(0)) + output_3_ip_hdr_ready = Signal(bool(0)) + output_3_ip_payload_tready = Signal(bool(0)) + + enable = Signal(bool(0)) + select = Signal(intbv(0)[2:]) + + # Outputs + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + + output_0_ip_hdr_valid = Signal(bool(0)) + output_0_eth_dest_mac = Signal(intbv(0)[48:]) + output_0_eth_src_mac = Signal(intbv(0)[48:]) + output_0_eth_type = Signal(intbv(0)[16:]) + output_0_ip_version = Signal(intbv(0)[4:]) + output_0_ip_ihl = Signal(intbv(0)[4:]) + output_0_ip_dscp = Signal(intbv(0)[6:]) + output_0_ip_ecn = Signal(intbv(0)[2:]) + output_0_ip_length = Signal(intbv(0)[16:]) + output_0_ip_identification = Signal(intbv(0)[16:]) + output_0_ip_flags = Signal(intbv(0)[3:]) + output_0_ip_fragment_offset = Signal(intbv(0)[13:]) + output_0_ip_ttl = Signal(intbv(0)[8:]) + output_0_ip_protocol = Signal(intbv(0)[8:]) + output_0_ip_header_checksum = Signal(intbv(0)[16:]) + output_0_ip_source_ip = Signal(intbv(0)[32:]) + output_0_ip_dest_ip = Signal(intbv(0)[32:]) + output_0_ip_payload_tdata = Signal(intbv(0)[64:]) + output_0_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_0_ip_payload_tvalid = Signal(bool(0)) + output_0_ip_payload_tlast = Signal(bool(0)) + output_0_ip_payload_tuser = Signal(bool(0)) + output_1_ip_hdr_valid = Signal(bool(0)) + output_1_eth_dest_mac = Signal(intbv(0)[48:]) + output_1_eth_src_mac = Signal(intbv(0)[48:]) + output_1_eth_type = Signal(intbv(0)[16:]) + output_1_ip_version = Signal(intbv(0)[4:]) + output_1_ip_ihl = Signal(intbv(0)[4:]) + output_1_ip_dscp = Signal(intbv(0)[6:]) + output_1_ip_ecn = Signal(intbv(0)[2:]) + output_1_ip_length = Signal(intbv(0)[16:]) + output_1_ip_identification = Signal(intbv(0)[16:]) + output_1_ip_flags = Signal(intbv(0)[3:]) + output_1_ip_fragment_offset = Signal(intbv(0)[13:]) + output_1_ip_ttl = Signal(intbv(0)[8:]) + output_1_ip_protocol = Signal(intbv(0)[8:]) + output_1_ip_header_checksum = Signal(intbv(0)[16:]) + output_1_ip_source_ip = Signal(intbv(0)[32:]) + output_1_ip_dest_ip = Signal(intbv(0)[32:]) + output_1_ip_payload_tdata = Signal(intbv(0)[64:]) + output_1_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_1_ip_payload_tvalid = Signal(bool(0)) + output_1_ip_payload_tlast = Signal(bool(0)) + output_1_ip_payload_tuser = Signal(bool(0)) + output_2_ip_hdr_valid = Signal(bool(0)) + output_2_eth_dest_mac = Signal(intbv(0)[48:]) + output_2_eth_src_mac = Signal(intbv(0)[48:]) + output_2_eth_type = Signal(intbv(0)[16:]) + output_2_ip_version = Signal(intbv(0)[4:]) + output_2_ip_ihl = Signal(intbv(0)[4:]) + output_2_ip_dscp = Signal(intbv(0)[6:]) + output_2_ip_ecn = Signal(intbv(0)[2:]) + output_2_ip_length = Signal(intbv(0)[16:]) + output_2_ip_identification = Signal(intbv(0)[16:]) + output_2_ip_flags = Signal(intbv(0)[3:]) + output_2_ip_fragment_offset = Signal(intbv(0)[13:]) + output_2_ip_ttl = Signal(intbv(0)[8:]) + output_2_ip_protocol = Signal(intbv(0)[8:]) + output_2_ip_header_checksum = Signal(intbv(0)[16:]) + output_2_ip_source_ip = Signal(intbv(0)[32:]) + output_2_ip_dest_ip = Signal(intbv(0)[32:]) + output_2_ip_payload_tdata = Signal(intbv(0)[64:]) + output_2_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_2_ip_payload_tvalid = Signal(bool(0)) + output_2_ip_payload_tlast = Signal(bool(0)) + output_2_ip_payload_tuser = Signal(bool(0)) + output_3_ip_hdr_valid = Signal(bool(0)) + output_3_eth_dest_mac = Signal(intbv(0)[48:]) + output_3_eth_src_mac = Signal(intbv(0)[48:]) + output_3_eth_type = Signal(intbv(0)[16:]) + output_3_ip_version = Signal(intbv(0)[4:]) + output_3_ip_ihl = Signal(intbv(0)[4:]) + output_3_ip_dscp = Signal(intbv(0)[6:]) + output_3_ip_ecn = Signal(intbv(0)[2:]) + output_3_ip_length = Signal(intbv(0)[16:]) + output_3_ip_identification = Signal(intbv(0)[16:]) + output_3_ip_flags = Signal(intbv(0)[3:]) + output_3_ip_fragment_offset = Signal(intbv(0)[13:]) + output_3_ip_ttl = Signal(intbv(0)[8:]) + output_3_ip_protocol = Signal(intbv(0)[8:]) + output_3_ip_header_checksum = Signal(intbv(0)[16:]) + output_3_ip_source_ip = Signal(intbv(0)[32:]) + output_3_ip_dest_ip = Signal(intbv(0)[32:]) + output_3_ip_payload_tdata = Signal(intbv(0)[64:]) + output_3_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_3_ip_payload_tvalid = Signal(bool(0)) + output_3_ip_payload_tlast = Signal(bool(0)) + output_3_ip_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_pause = Signal(bool(0)) + + source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_ready=input_ip_hdr_ready, + ip_hdr_valid=input_ip_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tkeep=input_ip_payload_tkeep, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink_0 = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_0_ip_hdr_ready, + ip_hdr_valid=output_0_ip_hdr_valid, + eth_dest_mac=output_0_eth_dest_mac, + eth_src_mac=output_0_eth_src_mac, + eth_type=output_0_eth_type, + ip_version=output_0_ip_version, + ip_ihl=output_0_ip_ihl, + ip_dscp=output_0_ip_dscp, + ip_ecn=output_0_ip_ecn, + ip_length=output_0_ip_length, + ip_identification=output_0_ip_identification, + ip_flags=output_0_ip_flags, + ip_fragment_offset=output_0_ip_fragment_offset, + ip_ttl=output_0_ip_ttl, + ip_protocol=output_0_ip_protocol, + ip_header_checksum=output_0_ip_header_checksum, + ip_source_ip=output_0_ip_source_ip, + ip_dest_ip=output_0_ip_dest_ip, + ip_payload_tdata=output_0_ip_payload_tdata, + ip_payload_tkeep=output_0_ip_payload_tkeep, + ip_payload_tvalid=output_0_ip_payload_tvalid, + ip_payload_tready=output_0_ip_payload_tready, + ip_payload_tlast=output_0_ip_payload_tlast, + ip_payload_tuser=output_0_ip_payload_tuser, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + + sink_1 = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_1_ip_hdr_ready, + ip_hdr_valid=output_1_ip_hdr_valid, + eth_dest_mac=output_1_eth_dest_mac, + eth_src_mac=output_1_eth_src_mac, + eth_type=output_1_eth_type, + ip_version=output_1_ip_version, + ip_ihl=output_1_ip_ihl, + ip_dscp=output_1_ip_dscp, + ip_ecn=output_1_ip_ecn, + ip_length=output_1_ip_length, + ip_identification=output_1_ip_identification, + ip_flags=output_1_ip_flags, + ip_fragment_offset=output_1_ip_fragment_offset, + ip_ttl=output_1_ip_ttl, + ip_protocol=output_1_ip_protocol, + ip_header_checksum=output_1_ip_header_checksum, + ip_source_ip=output_1_ip_source_ip, + ip_dest_ip=output_1_ip_dest_ip, + ip_payload_tdata=output_1_ip_payload_tdata, + ip_payload_tkeep=output_1_ip_payload_tkeep, + ip_payload_tvalid=output_1_ip_payload_tvalid, + ip_payload_tready=output_1_ip_payload_tready, + ip_payload_tlast=output_1_ip_payload_tlast, + ip_payload_tuser=output_1_ip_payload_tuser, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + + sink_2 = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_2_ip_hdr_ready, + ip_hdr_valid=output_2_ip_hdr_valid, + eth_dest_mac=output_2_eth_dest_mac, + eth_src_mac=output_2_eth_src_mac, + eth_type=output_2_eth_type, + ip_version=output_2_ip_version, + ip_ihl=output_2_ip_ihl, + ip_dscp=output_2_ip_dscp, + ip_ecn=output_2_ip_ecn, + ip_length=output_2_ip_length, + ip_identification=output_2_ip_identification, + ip_flags=output_2_ip_flags, + ip_fragment_offset=output_2_ip_fragment_offset, + ip_ttl=output_2_ip_ttl, + ip_protocol=output_2_ip_protocol, + ip_header_checksum=output_2_ip_header_checksum, + ip_source_ip=output_2_ip_source_ip, + ip_dest_ip=output_2_ip_dest_ip, + ip_payload_tdata=output_2_ip_payload_tdata, + ip_payload_tkeep=output_2_ip_payload_tkeep, + ip_payload_tvalid=output_2_ip_payload_tvalid, + ip_payload_tready=output_2_ip_payload_tready, + ip_payload_tlast=output_2_ip_payload_tlast, + ip_payload_tuser=output_2_ip_payload_tuser, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + + sink_3 = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_3_ip_hdr_ready, + ip_hdr_valid=output_3_ip_hdr_valid, + eth_dest_mac=output_3_eth_dest_mac, + eth_src_mac=output_3_eth_src_mac, + eth_type=output_3_eth_type, + ip_version=output_3_ip_version, + ip_ihl=output_3_ip_ihl, + ip_dscp=output_3_ip_dscp, + ip_ecn=output_3_ip_ecn, + ip_length=output_3_ip_length, + ip_identification=output_3_ip_identification, + ip_flags=output_3_ip_flags, + ip_fragment_offset=output_3_ip_fragment_offset, + ip_ttl=output_3_ip_ttl, + ip_protocol=output_3_ip_protocol, + ip_header_checksum=output_3_ip_header_checksum, + ip_source_ip=output_3_ip_source_ip, + ip_dest_ip=output_3_ip_dest_ip, + ip_payload_tdata=output_3_ip_payload_tdata, + ip_payload_tkeep=output_3_ip_payload_tkeep, + ip_payload_tvalid=output_3_ip_payload_tvalid, + ip_payload_tready=output_3_ip_payload_tready, + ip_payload_tlast=output_3_ip_payload_tlast, + ip_payload_tuser=output_3_ip_payload_tuser, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_ip_demux_64_4(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_0_ip_hdr_valid, + output_0_ip_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_ip_payload_tdata, + output_0_ip_payload_tkeep, + output_0_ip_payload_tvalid, + output_0_ip_payload_tready, + output_0_ip_payload_tlast, + output_0_ip_payload_tuser, + output_1_ip_hdr_valid, + output_1_ip_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_ip_payload_tdata, + output_1_ip_payload_tkeep, + output_1_ip_payload_tvalid, + output_1_ip_payload_tready, + output_1_ip_payload_tlast, + output_1_ip_payload_tuser, + output_2_ip_hdr_valid, + output_2_ip_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_ip_payload_tdata, + output_2_ip_payload_tkeep, + output_2_ip_payload_tvalid, + output_2_ip_payload_tready, + output_2_ip_payload_tlast, + output_2_ip_payload_tuser, + output_3_ip_hdr_valid, + output_3_ip_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_ip_payload_tdata, + output_3_ip_payload_tkeep, + output_3_ip_payload_tvalid, + output_3_ip_payload_tready, + output_3_ip_payload_tlast, + output_3_ip_payload_tuser, + + enable, + select) + + @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 + enable.next = True + + yield clk.posedge + print("test 1: select port 0") + current_test.next = 1 + + select.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_queue.put(test_frame) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_queue.put(test_frame) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = ip_ep.IPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = ip_ep.IPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_ip_payload_tvalid or input_ip_hdr_valid: + sink_0_pause.next = True + sink_1_pause.next = True + sink_2_pause.next = True + sink_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_0_pause.next = False + sink_1_pause.next = False + sink_2_pause.next = False + sink_3_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + raise StopSimulation + + return dut, source, sink_0, sink_1, sink_2, sink_3, 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() + diff --git a/tb/test_ip_demux_64_4.v b/tb/test_ip_demux_64_4.v new file mode 100644 index 000000000..60fb08282 --- /dev/null +++ b/tb/test_ip_demux_64_4.v @@ -0,0 +1,428 @@ +/* + +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_ip_demux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_ip_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [63:0] input_ip_payload_tdata = 0; +reg [7:0] input_ip_payload_tkeep = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; + +reg output_0_ip_hdr_ready = 0; +reg output_0_ip_payload_tready = 0; +reg output_1_ip_hdr_ready = 0; +reg output_1_ip_payload_tready = 0; +reg output_2_ip_hdr_ready = 0; +reg output_2_ip_payload_tready = 0; +reg output_3_ip_hdr_ready = 0; +reg output_3_ip_payload_tready = 0; + +reg enable = 0; +reg [1:0] select = 0; + +// Outputs +wire input_ip_hdr_ready; +wire input_ip_payload_tready; + +wire output_0_ip_hdr_valid; +wire [47:0] output_0_eth_dest_mac; +wire [47:0] output_0_eth_src_mac; +wire [15:0] output_0_eth_type; +wire [3:0] output_0_ip_version; +wire [3:0] output_0_ip_ihl; +wire [5:0] output_0_ip_dscp; +wire [1:0] output_0_ip_ecn; +wire [15:0] output_0_ip_length; +wire [15:0] output_0_ip_identification; +wire [2:0] output_0_ip_flags; +wire [12:0] output_0_ip_fragment_offset; +wire [7:0] output_0_ip_ttl; +wire [7:0] output_0_ip_protocol; +wire [15:0] output_0_ip_header_checksum; +wire [31:0] output_0_ip_source_ip; +wire [31:0] output_0_ip_dest_ip; +wire [63:0] output_0_ip_payload_tdata; +wire [7:0] output_0_ip_payload_tkeep; +wire output_0_ip_payload_tvalid; +wire output_0_ip_payload_tlast; +wire output_0_ip_payload_tuser; +wire output_1_ip_hdr_valid; +wire [47:0] output_1_eth_dest_mac; +wire [47:0] output_1_eth_src_mac; +wire [15:0] output_1_eth_type; +wire [3:0] output_1_ip_version; +wire [3:0] output_1_ip_ihl; +wire [5:0] output_1_ip_dscp; +wire [1:0] output_1_ip_ecn; +wire [15:0] output_1_ip_length; +wire [15:0] output_1_ip_identification; +wire [2:0] output_1_ip_flags; +wire [12:0] output_1_ip_fragment_offset; +wire [7:0] output_1_ip_ttl; +wire [7:0] output_1_ip_protocol; +wire [15:0] output_1_ip_header_checksum; +wire [31:0] output_1_ip_source_ip; +wire [31:0] output_1_ip_dest_ip; +wire [63:0] output_1_ip_payload_tdata; +wire [7:0] output_1_ip_payload_tkeep; +wire output_1_ip_payload_tvalid; +wire output_1_ip_payload_tlast; +wire output_1_ip_payload_tuser; +wire output_2_ip_hdr_valid; +wire [47:0] output_2_eth_dest_mac; +wire [47:0] output_2_eth_src_mac; +wire [15:0] output_2_eth_type; +wire [3:0] output_2_ip_version; +wire [3:0] output_2_ip_ihl; +wire [5:0] output_2_ip_dscp; +wire [1:0] output_2_ip_ecn; +wire [15:0] output_2_ip_length; +wire [15:0] output_2_ip_identification; +wire [2:0] output_2_ip_flags; +wire [12:0] output_2_ip_fragment_offset; +wire [7:0] output_2_ip_ttl; +wire [7:0] output_2_ip_protocol; +wire [15:0] output_2_ip_header_checksum; +wire [31:0] output_2_ip_source_ip; +wire [31:0] output_2_ip_dest_ip; +wire [63:0] output_2_ip_payload_tdata; +wire [7:0] output_2_ip_payload_tkeep; +wire output_2_ip_payload_tvalid; +wire output_2_ip_payload_tlast; +wire output_2_ip_payload_tuser; +wire output_3_ip_hdr_valid; +wire [47:0] output_3_eth_dest_mac; +wire [47:0] output_3_eth_src_mac; +wire [15:0] output_3_eth_type; +wire [3:0] output_3_ip_version; +wire [3:0] output_3_ip_ihl; +wire [5:0] output_3_ip_dscp; +wire [1:0] output_3_ip_ecn; +wire [15:0] output_3_ip_length; +wire [15:0] output_3_ip_identification; +wire [2:0] output_3_ip_flags; +wire [12:0] output_3_ip_fragment_offset; +wire [7:0] output_3_ip_ttl; +wire [7:0] output_3_ip_protocol; +wire [15:0] output_3_ip_header_checksum; +wire [31:0] output_3_ip_source_ip; +wire [31:0] output_3_ip_dest_ip; +wire [63:0] output_3_ip_payload_tdata; +wire [7:0] output_3_ip_payload_tkeep; +wire output_3_ip_payload_tvalid; +wire output_3_ip_payload_tlast; +wire output_3_ip_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_ip_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + output_0_ip_hdr_ready, + output_0_ip_payload_tready, + output_1_ip_hdr_ready, + output_1_ip_payload_tready, + output_2_ip_hdr_ready, + output_2_ip_payload_tready, + output_3_ip_hdr_ready, + output_3_ip_payload_tready, + enable, + select); + $to_myhdl(input_ip_hdr_ready, + input_ip_payload_tready, + output_0_ip_hdr_valid, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_ip_payload_tdata, + output_0_ip_payload_tkeep, + output_0_ip_payload_tvalid, + output_0_ip_payload_tlast, + output_0_ip_payload_tuser, + output_1_ip_hdr_valid, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_ip_payload_tdata, + output_1_ip_payload_tkeep, + output_1_ip_payload_tvalid, + output_1_ip_payload_tlast, + output_1_ip_payload_tuser, + output_2_ip_hdr_valid, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_ip_payload_tdata, + output_2_ip_payload_tkeep, + output_2_ip_payload_tvalid, + output_2_ip_payload_tlast, + output_2_ip_payload_tuser, + output_3_ip_hdr_valid, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_ip_payload_tdata, + output_3_ip_payload_tkeep, + output_3_ip_payload_tvalid, + output_3_ip_payload_tlast, + output_3_ip_payload_tuser); + + // dump file + $dumpfile("test_ip_demux_64_4.lxt"); + $dumpvars(0, test_ip_demux_64_4); +end + +ip_demux_64_4 +UUT ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame outputs + .output_0_ip_hdr_valid(output_0_ip_hdr_valid), + .output_0_ip_hdr_ready(output_0_ip_hdr_ready), + .output_0_eth_dest_mac(output_0_eth_dest_mac), + .output_0_eth_src_mac(output_0_eth_src_mac), + .output_0_eth_type(output_0_eth_type), + .output_0_ip_version(output_0_ip_version), + .output_0_ip_ihl(output_0_ip_ihl), + .output_0_ip_dscp(output_0_ip_dscp), + .output_0_ip_ecn(output_0_ip_ecn), + .output_0_ip_length(output_0_ip_length), + .output_0_ip_identification(output_0_ip_identification), + .output_0_ip_flags(output_0_ip_flags), + .output_0_ip_fragment_offset(output_0_ip_fragment_offset), + .output_0_ip_ttl(output_0_ip_ttl), + .output_0_ip_protocol(output_0_ip_protocol), + .output_0_ip_header_checksum(output_0_ip_header_checksum), + .output_0_ip_source_ip(output_0_ip_source_ip), + .output_0_ip_dest_ip(output_0_ip_dest_ip), + .output_0_ip_payload_tdata(output_0_ip_payload_tdata), + .output_0_ip_payload_tkeep(output_0_ip_payload_tkeep), + .output_0_ip_payload_tvalid(output_0_ip_payload_tvalid), + .output_0_ip_payload_tready(output_0_ip_payload_tready), + .output_0_ip_payload_tlast(output_0_ip_payload_tlast), + .output_0_ip_payload_tuser(output_0_ip_payload_tuser), + .output_1_ip_hdr_valid(output_1_ip_hdr_valid), + .output_1_ip_hdr_ready(output_1_ip_hdr_ready), + .output_1_eth_dest_mac(output_1_eth_dest_mac), + .output_1_eth_src_mac(output_1_eth_src_mac), + .output_1_eth_type(output_1_eth_type), + .output_1_ip_version(output_1_ip_version), + .output_1_ip_ihl(output_1_ip_ihl), + .output_1_ip_dscp(output_1_ip_dscp), + .output_1_ip_ecn(output_1_ip_ecn), + .output_1_ip_length(output_1_ip_length), + .output_1_ip_identification(output_1_ip_identification), + .output_1_ip_flags(output_1_ip_flags), + .output_1_ip_fragment_offset(output_1_ip_fragment_offset), + .output_1_ip_ttl(output_1_ip_ttl), + .output_1_ip_protocol(output_1_ip_protocol), + .output_1_ip_header_checksum(output_1_ip_header_checksum), + .output_1_ip_source_ip(output_1_ip_source_ip), + .output_1_ip_dest_ip(output_1_ip_dest_ip), + .output_1_ip_payload_tdata(output_1_ip_payload_tdata), + .output_1_ip_payload_tkeep(output_1_ip_payload_tkeep), + .output_1_ip_payload_tvalid(output_1_ip_payload_tvalid), + .output_1_ip_payload_tready(output_1_ip_payload_tready), + .output_1_ip_payload_tlast(output_1_ip_payload_tlast), + .output_1_ip_payload_tuser(output_1_ip_payload_tuser), + .output_2_ip_hdr_valid(output_2_ip_hdr_valid), + .output_2_ip_hdr_ready(output_2_ip_hdr_ready), + .output_2_eth_dest_mac(output_2_eth_dest_mac), + .output_2_eth_src_mac(output_2_eth_src_mac), + .output_2_eth_type(output_2_eth_type), + .output_2_ip_version(output_2_ip_version), + .output_2_ip_ihl(output_2_ip_ihl), + .output_2_ip_dscp(output_2_ip_dscp), + .output_2_ip_ecn(output_2_ip_ecn), + .output_2_ip_length(output_2_ip_length), + .output_2_ip_identification(output_2_ip_identification), + .output_2_ip_flags(output_2_ip_flags), + .output_2_ip_fragment_offset(output_2_ip_fragment_offset), + .output_2_ip_ttl(output_2_ip_ttl), + .output_2_ip_protocol(output_2_ip_protocol), + .output_2_ip_header_checksum(output_2_ip_header_checksum), + .output_2_ip_source_ip(output_2_ip_source_ip), + .output_2_ip_dest_ip(output_2_ip_dest_ip), + .output_2_ip_payload_tdata(output_2_ip_payload_tdata), + .output_2_ip_payload_tkeep(output_2_ip_payload_tkeep), + .output_2_ip_payload_tvalid(output_2_ip_payload_tvalid), + .output_2_ip_payload_tready(output_2_ip_payload_tready), + .output_2_ip_payload_tlast(output_2_ip_payload_tlast), + .output_2_ip_payload_tuser(output_2_ip_payload_tuser), + .output_3_ip_hdr_valid(output_3_ip_hdr_valid), + .output_3_ip_hdr_ready(output_3_ip_hdr_ready), + .output_3_eth_dest_mac(output_3_eth_dest_mac), + .output_3_eth_src_mac(output_3_eth_src_mac), + .output_3_eth_type(output_3_eth_type), + .output_3_ip_version(output_3_ip_version), + .output_3_ip_ihl(output_3_ip_ihl), + .output_3_ip_dscp(output_3_ip_dscp), + .output_3_ip_ecn(output_3_ip_ecn), + .output_3_ip_length(output_3_ip_length), + .output_3_ip_identification(output_3_ip_identification), + .output_3_ip_flags(output_3_ip_flags), + .output_3_ip_fragment_offset(output_3_ip_fragment_offset), + .output_3_ip_ttl(output_3_ip_ttl), + .output_3_ip_protocol(output_3_ip_protocol), + .output_3_ip_header_checksum(output_3_ip_header_checksum), + .output_3_ip_source_ip(output_3_ip_source_ip), + .output_3_ip_dest_ip(output_3_ip_dest_ip), + .output_3_ip_payload_tdata(output_3_ip_payload_tdata), + .output_3_ip_payload_tkeep(output_3_ip_payload_tkeep), + .output_3_ip_payload_tvalid(output_3_ip_payload_tvalid), + .output_3_ip_payload_tready(output_3_ip_payload_tready), + .output_3_ip_payload_tlast(output_3_ip_payload_tlast), + .output_3_ip_payload_tuser(output_3_ip_payload_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule From a5d68fcff912dc71d93c1c8369df17f2ffe42386 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 18 Nov 2014 14:41:48 -0800 Subject: [PATCH 111/617] Add UDP mux module and testbench --- rtl/udp_mux.py | 543 +++++++++++++++++ rtl/udp_mux_4.v | 645 ++++++++++++++++++++ rtl/udp_mux_64.py | 558 +++++++++++++++++ rtl/udp_mux_64_4.v | 666 ++++++++++++++++++++ tb/test_udp_mux_4.py | 1258 ++++++++++++++++++++++++++++++++++++++ tb/test_udp_mux_4.v | 473 +++++++++++++++ tb/test_udp_mux_64_4.py | 1283 +++++++++++++++++++++++++++++++++++++++ tb/test_udp_mux_64_4.v | 488 +++++++++++++++ 8 files changed, 5914 insertions(+) create mode 100755 rtl/udp_mux.py create mode 100644 rtl/udp_mux_4.v create mode 100755 rtl/udp_mux_64.py create mode 100644 rtl/udp_mux_64_4.v create mode 100755 tb/test_udp_mux_4.py create mode 100644 tb/test_udp_mux_4.v create mode 100755 tb/test_udp_mux_64_4.py create mode 100644 tb/test_udp_mux_64_4.v diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py new file mode 100755 index 000000000..c56b24bd7 --- /dev/null +++ b/rtl/udp_mux.py @@ -0,0 +1,543 @@ +#!/usr/bin/env python +"""udp_mux + +Generates an UDP mux with the specified number of ports + +Usage: udp_mux [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "udp_mux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port UDP mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * UDP {{n}} port multiplexer + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * UDP frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_udp_hdr_valid, + output wire input_{{p}}_udp_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [3:0] input_{{p}}_ip_version, + input wire [3:0] input_{{p}}_ip_ihl, + input wire [5:0] input_{{p}}_ip_dscp, + input wire [1:0] input_{{p}}_ip_ecn, + input wire [15:0] input_{{p}}_ip_length, + input wire [15:0] input_{{p}}_ip_identification, + input wire [2:0] input_{{p}}_ip_flags, + input wire [12:0] input_{{p}}_ip_fragment_offset, + input wire [7:0] input_{{p}}_ip_ttl, + input wire [7:0] input_{{p}}_ip_protocol, + input wire [15:0] input_{{p}}_ip_header_checksum, + input wire [31:0] input_{{p}}_ip_source_ip, + input wire [31:0] input_{{p}}_ip_dest_ip, + input wire [15:0] input_{{p}}_udp_source_port, + input wire [15:0] input_{{p}}_udp_dest_port, + input wire [15:0] input_{{p}}_udp_length, + input wire [15:0] input_{{p}}_udp_checksum, + input wire [7:0] input_{{p}}_udp_payload_tdata, + input wire input_{{p}}_udp_payload_tvalid, + output wire input_{{p}}_udp_payload_tready, + input wire input_{{p}}_udp_payload_tlast, + input wire input_{{p}}_udp_payload_tuser, +{% endfor %} + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [7:0] output_udp_payload_tdata, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; +{% for p in ports %} +reg input_{{p}}_udp_hdr_ready_reg = 0, input_{{p}}_udp_hdr_ready_next; +{%- endfor %} +{% for p in ports %} +reg input_{{p}}_udp_payload_tready_reg = 0, input_{{p}}_udp_payload_tready_next; +{%- endfor %} + +reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; + +// internal datapath +reg [7:0] output_udp_payload_tdata_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; +{% for p in ports %} +assign input_{{p}}_udp_hdr_ready = input_{{p}}_udp_hdr_ready_reg; +{%- endfor %} +{% for p in ports %} +assign input_{{p}}_udp_payload_tready = input_{{p}}_udp_payload_tready_reg; +{%- endfor %} + +assign output_udp_hdr_valid = output_udp_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_udp_source_port = output_udp_source_port_reg; +assign output_udp_dest_port = output_udp_dest_port_reg; +assign output_udp_length = output_udp_length_reg; +assign output_udp_checksum = output_udp_checksum_reg; + +// mux for start of packet detection +reg selected_input_udp_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +reg [3:0] selected_input_ip_version; +reg [3:0] selected_input_ip_ihl; +reg [5:0] selected_input_ip_dscp; +reg [1:0] selected_input_ip_ecn; +reg [15:0] selected_input_ip_length; +reg [15:0] selected_input_ip_identification; +reg [2:0] selected_input_ip_flags; +reg [12:0] selected_input_ip_fragment_offset; +reg [7:0] selected_input_ip_ttl; +reg [7:0] selected_input_ip_protocol; +reg [15:0] selected_input_ip_header_checksum; +reg [31:0] selected_input_ip_source_ip; +reg [31:0] selected_input_ip_dest_ip; +reg [15:0] selected_input_udp_source_port; +reg [15:0] selected_input_udp_dest_port; +reg [15:0] selected_input_udp_length; +reg [15:0] selected_input_udp_checksum; +always @* begin + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: begin + selected_input_udp_hdr_valid = input_{{p}}_udp_hdr_valid; + selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; + selected_input_eth_src_mac = input_{{p}}_eth_src_mac; + selected_input_eth_type = input_{{p}}_eth_type; + selected_input_ip_version = input_{{p}}_ip_version; + selected_input_ip_ihl = input_{{p}}_ip_ihl; + selected_input_ip_dscp = input_{{p}}_ip_dscp; + selected_input_ip_ecn = input_{{p}}_ip_ecn; + selected_input_ip_length = input_{{p}}_ip_length; + selected_input_ip_identification = input_{{p}}_ip_identification; + selected_input_ip_flags = input_{{p}}_ip_flags; + selected_input_ip_fragment_offset = input_{{p}}_ip_fragment_offset; + selected_input_ip_ttl = input_{{p}}_ip_ttl; + selected_input_ip_protocol = input_{{p}}_ip_protocol; + selected_input_ip_header_checksum = input_{{p}}_ip_header_checksum; + selected_input_ip_source_ip = input_{{p}}_ip_source_ip; + selected_input_ip_dest_ip = input_{{p}}_ip_dest_ip; + selected_input_udp_source_port = input_{{p}}_udp_source_port; + selected_input_udp_dest_port = input_{{p}}_udp_dest_port; + selected_input_udp_length = input_{{p}}_udp_length; + selected_input_udp_checksum = input_{{p}}_udp_checksum; + end +{%- endfor %} + endcase +end + +// mux for incoming packet +reg [7:0] current_input_tdata; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_input_tdata = input_{{p}}_udp_payload_tdata; + current_input_tvalid = input_{{p}}_udp_payload_tvalid; + current_input_tready = input_{{p}}_udp_payload_tready; + current_input_tlast = input_{{p}}_udp_payload_tlast; + current_input_tuser = input_{{p}}_udp_payload_tuser; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; +{% for p in ports %} + input_{{p}}_udp_hdr_ready_next = input_{{p}}_udp_hdr_ready_reg & ~input_{{p}}_udp_hdr_valid; +{%- endfor %} +{% for p in ports %} + input_{{p}}_udp_payload_tready_next = 0; +{%- endfor %} + + output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + output_udp_source_port_next = output_udp_source_port_reg; + output_udp_dest_port_next = output_udp_dest_port_reg; + output_udp_length_next = output_udp_length_reg; + output_udp_checksum_next = output_udp_checksum_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_udp_hdr_ready_next = 1; +{%- endfor %} + endcase + + output_udp_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + output_ip_version_next = selected_input_ip_version; + output_ip_ihl_next = selected_input_ip_ihl; + output_ip_dscp_next = selected_input_ip_dscp; + output_ip_ecn_next = selected_input_ip_ecn; + output_ip_length_next = selected_input_ip_length; + output_ip_identification_next = selected_input_ip_identification; + output_ip_flags_next = selected_input_ip_flags; + output_ip_fragment_offset_next = selected_input_ip_fragment_offset; + output_ip_ttl_next = selected_input_ip_ttl; + output_ip_protocol_next = selected_input_ip_protocol; + output_ip_header_checksum_next = selected_input_ip_header_checksum; + output_ip_source_ip_next = selected_input_ip_source_ip; + output_ip_dest_ip_next = selected_input_ip_dest_ip; + output_udp_source_port_next = selected_input_udp_source_port; + output_udp_dest_port_next = selected_input_udp_dest_port; + output_udp_length_next = selected_input_udp_length; + output_udp_checksum_next = selected_input_udp_checksum; + end + + // generate ready signal on selected port + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; +{%- endfor %} + endcase + + // pass through selected packet data + output_udp_payload_tdata_int = current_input_tdata; + output_udp_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_udp_payload_tlast_int = current_input_tlast; + output_udp_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; +{%- for p in ports %} + input_{{p}}_udp_hdr_ready_reg <= 0; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_udp_payload_tready_reg <= 0; +{%- endfor %} + output_udp_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_udp_source_port_reg <= 0; + output_udp_dest_port_reg <= 0; + output_udp_length_reg <= 0; + output_udp_checksum_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; +{%- for p in ports %} + input_{{p}}_udp_hdr_ready_reg <= input_{{p}}_udp_hdr_ready_next; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_udp_payload_tready_reg <= input_{{p}}_udp_payload_tready_next; +{%- endfor %} + output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; + end +end + +// output datapath logic +reg [7:0] output_udp_payload_tdata_reg = 0; +reg output_udp_payload_tvalid_reg = 0; +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg [7:0] temp_udp_payload_tdata_reg = 0; +reg temp_udp_payload_tvalid_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; + +assign output_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; +assign output_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_udp_payload_tuser = output_udp_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_udp_payload_tdata_reg <= 0; + output_udp_payload_tvalid_reg <= 0; + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + + if (output_udp_payload_tready_int) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/udp_mux_4.v b/rtl/udp_mux_4.v new file mode 100644 index 000000000..4bbaede2e --- /dev/null +++ b/rtl/udp_mux_4.v @@ -0,0 +1,645 @@ +/* + +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 + +/* + * UDP 4 port multiplexer + */ +module udp_mux_4 +( + input wire clk, + input wire rst, + + /* + * UDP frame inputs + */ + input wire input_0_udp_hdr_valid, + output wire input_0_udp_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [15:0] input_0_udp_source_port, + input wire [15:0] input_0_udp_dest_port, + input wire [15:0] input_0_udp_length, + input wire [15:0] input_0_udp_checksum, + input wire [7:0] input_0_udp_payload_tdata, + input wire input_0_udp_payload_tvalid, + output wire input_0_udp_payload_tready, + input wire input_0_udp_payload_tlast, + input wire input_0_udp_payload_tuser, + + input wire input_1_udp_hdr_valid, + output wire input_1_udp_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [15:0] input_1_udp_source_port, + input wire [15:0] input_1_udp_dest_port, + input wire [15:0] input_1_udp_length, + input wire [15:0] input_1_udp_checksum, + input wire [7:0] input_1_udp_payload_tdata, + input wire input_1_udp_payload_tvalid, + output wire input_1_udp_payload_tready, + input wire input_1_udp_payload_tlast, + input wire input_1_udp_payload_tuser, + + input wire input_2_udp_hdr_valid, + output wire input_2_udp_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [3:0] input_2_ip_version, + input wire [3:0] input_2_ip_ihl, + input wire [5:0] input_2_ip_dscp, + input wire [1:0] input_2_ip_ecn, + input wire [15:0] input_2_ip_length, + input wire [15:0] input_2_ip_identification, + input wire [2:0] input_2_ip_flags, + input wire [12:0] input_2_ip_fragment_offset, + input wire [7:0] input_2_ip_ttl, + input wire [7:0] input_2_ip_protocol, + input wire [15:0] input_2_ip_header_checksum, + input wire [31:0] input_2_ip_source_ip, + input wire [31:0] input_2_ip_dest_ip, + input wire [15:0] input_2_udp_source_port, + input wire [15:0] input_2_udp_dest_port, + input wire [15:0] input_2_udp_length, + input wire [15:0] input_2_udp_checksum, + input wire [7:0] input_2_udp_payload_tdata, + input wire input_2_udp_payload_tvalid, + output wire input_2_udp_payload_tready, + input wire input_2_udp_payload_tlast, + input wire input_2_udp_payload_tuser, + + input wire input_3_udp_hdr_valid, + output wire input_3_udp_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [3:0] input_3_ip_version, + input wire [3:0] input_3_ip_ihl, + input wire [5:0] input_3_ip_dscp, + input wire [1:0] input_3_ip_ecn, + input wire [15:0] input_3_ip_length, + input wire [15:0] input_3_ip_identification, + input wire [2:0] input_3_ip_flags, + input wire [12:0] input_3_ip_fragment_offset, + input wire [7:0] input_3_ip_ttl, + input wire [7:0] input_3_ip_protocol, + input wire [15:0] input_3_ip_header_checksum, + input wire [31:0] input_3_ip_source_ip, + input wire [31:0] input_3_ip_dest_ip, + input wire [15:0] input_3_udp_source_port, + input wire [15:0] input_3_udp_dest_port, + input wire [15:0] input_3_udp_length, + input wire [15:0] input_3_udp_checksum, + input wire [7:0] input_3_udp_payload_tdata, + input wire input_3_udp_payload_tvalid, + output wire input_3_udp_payload_tready, + input wire input_3_udp_payload_tlast, + input wire input_3_udp_payload_tuser, + + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [7:0] output_udp_payload_tdata, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_udp_hdr_ready_reg = 0, input_0_udp_hdr_ready_next; +reg input_1_udp_hdr_ready_reg = 0, input_1_udp_hdr_ready_next; +reg input_2_udp_hdr_ready_reg = 0, input_2_udp_hdr_ready_next; +reg input_3_udp_hdr_ready_reg = 0, input_3_udp_hdr_ready_next; + +reg input_0_udp_payload_tready_reg = 0, input_0_udp_payload_tready_next; +reg input_1_udp_payload_tready_reg = 0, input_1_udp_payload_tready_next; +reg input_2_udp_payload_tready_reg = 0, input_2_udp_payload_tready_next; +reg input_3_udp_payload_tready_reg = 0, input_3_udp_payload_tready_next; + +reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; + +// internal datapath +reg [7:0] output_udp_payload_tdata_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; + +assign input_0_udp_hdr_ready = input_0_udp_hdr_ready_reg; +assign input_1_udp_hdr_ready = input_1_udp_hdr_ready_reg; +assign input_2_udp_hdr_ready = input_2_udp_hdr_ready_reg; +assign input_3_udp_hdr_ready = input_3_udp_hdr_ready_reg; + +assign input_0_udp_payload_tready = input_0_udp_payload_tready_reg; +assign input_1_udp_payload_tready = input_1_udp_payload_tready_reg; +assign input_2_udp_payload_tready = input_2_udp_payload_tready_reg; +assign input_3_udp_payload_tready = input_3_udp_payload_tready_reg; + +assign output_udp_hdr_valid = output_udp_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_udp_source_port = output_udp_source_port_reg; +assign output_udp_dest_port = output_udp_dest_port_reg; +assign output_udp_length = output_udp_length_reg; +assign output_udp_checksum = output_udp_checksum_reg; + +// mux for start of packet detection +reg selected_input_udp_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +reg [3:0] selected_input_ip_version; +reg [3:0] selected_input_ip_ihl; +reg [5:0] selected_input_ip_dscp; +reg [1:0] selected_input_ip_ecn; +reg [15:0] selected_input_ip_length; +reg [15:0] selected_input_ip_identification; +reg [2:0] selected_input_ip_flags; +reg [12:0] selected_input_ip_fragment_offset; +reg [7:0] selected_input_ip_ttl; +reg [7:0] selected_input_ip_protocol; +reg [15:0] selected_input_ip_header_checksum; +reg [31:0] selected_input_ip_source_ip; +reg [31:0] selected_input_ip_dest_ip; +reg [15:0] selected_input_udp_source_port; +reg [15:0] selected_input_udp_dest_port; +reg [15:0] selected_input_udp_length; +reg [15:0] selected_input_udp_checksum; +always @* begin + case (select) + 2'd0: begin + selected_input_udp_hdr_valid = input_0_udp_hdr_valid; + selected_input_eth_dest_mac = input_0_eth_dest_mac; + selected_input_eth_src_mac = input_0_eth_src_mac; + selected_input_eth_type = input_0_eth_type; + selected_input_ip_version = input_0_ip_version; + selected_input_ip_ihl = input_0_ip_ihl; + selected_input_ip_dscp = input_0_ip_dscp; + selected_input_ip_ecn = input_0_ip_ecn; + selected_input_ip_length = input_0_ip_length; + selected_input_ip_identification = input_0_ip_identification; + selected_input_ip_flags = input_0_ip_flags; + selected_input_ip_fragment_offset = input_0_ip_fragment_offset; + selected_input_ip_ttl = input_0_ip_ttl; + selected_input_ip_protocol = input_0_ip_protocol; + selected_input_ip_header_checksum = input_0_ip_header_checksum; + selected_input_ip_source_ip = input_0_ip_source_ip; + selected_input_ip_dest_ip = input_0_ip_dest_ip; + selected_input_udp_source_port = input_0_udp_source_port; + selected_input_udp_dest_port = input_0_udp_dest_port; + selected_input_udp_length = input_0_udp_length; + selected_input_udp_checksum = input_0_udp_checksum; + end + 2'd1: begin + selected_input_udp_hdr_valid = input_1_udp_hdr_valid; + selected_input_eth_dest_mac = input_1_eth_dest_mac; + selected_input_eth_src_mac = input_1_eth_src_mac; + selected_input_eth_type = input_1_eth_type; + selected_input_ip_version = input_1_ip_version; + selected_input_ip_ihl = input_1_ip_ihl; + selected_input_ip_dscp = input_1_ip_dscp; + selected_input_ip_ecn = input_1_ip_ecn; + selected_input_ip_length = input_1_ip_length; + selected_input_ip_identification = input_1_ip_identification; + selected_input_ip_flags = input_1_ip_flags; + selected_input_ip_fragment_offset = input_1_ip_fragment_offset; + selected_input_ip_ttl = input_1_ip_ttl; + selected_input_ip_protocol = input_1_ip_protocol; + selected_input_ip_header_checksum = input_1_ip_header_checksum; + selected_input_ip_source_ip = input_1_ip_source_ip; + selected_input_ip_dest_ip = input_1_ip_dest_ip; + selected_input_udp_source_port = input_1_udp_source_port; + selected_input_udp_dest_port = input_1_udp_dest_port; + selected_input_udp_length = input_1_udp_length; + selected_input_udp_checksum = input_1_udp_checksum; + end + 2'd2: begin + selected_input_udp_hdr_valid = input_2_udp_hdr_valid; + selected_input_eth_dest_mac = input_2_eth_dest_mac; + selected_input_eth_src_mac = input_2_eth_src_mac; + selected_input_eth_type = input_2_eth_type; + selected_input_ip_version = input_2_ip_version; + selected_input_ip_ihl = input_2_ip_ihl; + selected_input_ip_dscp = input_2_ip_dscp; + selected_input_ip_ecn = input_2_ip_ecn; + selected_input_ip_length = input_2_ip_length; + selected_input_ip_identification = input_2_ip_identification; + selected_input_ip_flags = input_2_ip_flags; + selected_input_ip_fragment_offset = input_2_ip_fragment_offset; + selected_input_ip_ttl = input_2_ip_ttl; + selected_input_ip_protocol = input_2_ip_protocol; + selected_input_ip_header_checksum = input_2_ip_header_checksum; + selected_input_ip_source_ip = input_2_ip_source_ip; + selected_input_ip_dest_ip = input_2_ip_dest_ip; + selected_input_udp_source_port = input_2_udp_source_port; + selected_input_udp_dest_port = input_2_udp_dest_port; + selected_input_udp_length = input_2_udp_length; + selected_input_udp_checksum = input_2_udp_checksum; + end + 2'd3: begin + selected_input_udp_hdr_valid = input_3_udp_hdr_valid; + selected_input_eth_dest_mac = input_3_eth_dest_mac; + selected_input_eth_src_mac = input_3_eth_src_mac; + selected_input_eth_type = input_3_eth_type; + selected_input_ip_version = input_3_ip_version; + selected_input_ip_ihl = input_3_ip_ihl; + selected_input_ip_dscp = input_3_ip_dscp; + selected_input_ip_ecn = input_3_ip_ecn; + selected_input_ip_length = input_3_ip_length; + selected_input_ip_identification = input_3_ip_identification; + selected_input_ip_flags = input_3_ip_flags; + selected_input_ip_fragment_offset = input_3_ip_fragment_offset; + selected_input_ip_ttl = input_3_ip_ttl; + selected_input_ip_protocol = input_3_ip_protocol; + selected_input_ip_header_checksum = input_3_ip_header_checksum; + selected_input_ip_source_ip = input_3_ip_source_ip; + selected_input_ip_dest_ip = input_3_ip_dest_ip; + selected_input_udp_source_port = input_3_udp_source_port; + selected_input_udp_dest_port = input_3_udp_dest_port; + selected_input_udp_length = input_3_udp_length; + selected_input_udp_checksum = input_3_udp_checksum; + end + endcase +end + +// mux for incoming packet +reg [7:0] current_input_tdata; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 2'd0: begin + current_input_tdata = input_0_udp_payload_tdata; + current_input_tvalid = input_0_udp_payload_tvalid; + current_input_tready = input_0_udp_payload_tready; + current_input_tlast = input_0_udp_payload_tlast; + current_input_tuser = input_0_udp_payload_tuser; + end + 2'd1: begin + current_input_tdata = input_1_udp_payload_tdata; + current_input_tvalid = input_1_udp_payload_tvalid; + current_input_tready = input_1_udp_payload_tready; + current_input_tlast = input_1_udp_payload_tlast; + current_input_tuser = input_1_udp_payload_tuser; + end + 2'd2: begin + current_input_tdata = input_2_udp_payload_tdata; + current_input_tvalid = input_2_udp_payload_tvalid; + current_input_tready = input_2_udp_payload_tready; + current_input_tlast = input_2_udp_payload_tlast; + current_input_tuser = input_2_udp_payload_tuser; + end + 2'd3: begin + current_input_tdata = input_3_udp_payload_tdata; + current_input_tvalid = input_3_udp_payload_tvalid; + current_input_tready = input_3_udp_payload_tready; + current_input_tlast = input_3_udp_payload_tlast; + current_input_tuser = input_3_udp_payload_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_udp_hdr_ready_next = input_0_udp_hdr_ready_reg & ~input_0_udp_hdr_valid; + input_1_udp_hdr_ready_next = input_1_udp_hdr_ready_reg & ~input_1_udp_hdr_valid; + input_2_udp_hdr_ready_next = input_2_udp_hdr_ready_reg & ~input_2_udp_hdr_valid; + input_3_udp_hdr_ready_next = input_3_udp_hdr_ready_reg & ~input_3_udp_hdr_valid; + + input_0_udp_payload_tready_next = 0; + input_1_udp_payload_tready_next = 0; + input_2_udp_payload_tready_next = 0; + input_3_udp_payload_tready_next = 0; + + output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + output_udp_source_port_next = output_udp_source_port_reg; + output_udp_dest_port_next = output_udp_dest_port_reg; + output_udp_length_next = output_udp_length_reg; + output_udp_checksum_next = output_udp_checksum_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) + 2'd0: input_0_udp_hdr_ready_next = 1; + 2'd1: input_1_udp_hdr_ready_next = 1; + 2'd2: input_2_udp_hdr_ready_next = 1; + 2'd3: input_3_udp_hdr_ready_next = 1; + endcase + + output_udp_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + output_ip_version_next = selected_input_ip_version; + output_ip_ihl_next = selected_input_ip_ihl; + output_ip_dscp_next = selected_input_ip_dscp; + output_ip_ecn_next = selected_input_ip_ecn; + output_ip_length_next = selected_input_ip_length; + output_ip_identification_next = selected_input_ip_identification; + output_ip_flags_next = selected_input_ip_flags; + output_ip_fragment_offset_next = selected_input_ip_fragment_offset; + output_ip_ttl_next = selected_input_ip_ttl; + output_ip_protocol_next = selected_input_ip_protocol; + output_ip_header_checksum_next = selected_input_ip_header_checksum; + output_ip_source_ip_next = selected_input_ip_source_ip; + output_ip_dest_ip_next = selected_input_ip_dest_ip; + output_udp_source_port_next = selected_input_udp_source_port; + output_udp_dest_port_next = selected_input_udp_dest_port; + output_udp_length_next = selected_input_udp_length; + output_udp_checksum_next = selected_input_udp_checksum; + end + + // generate ready signal on selected port + case (select_next) + 2'd0: input_0_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + 2'd1: input_1_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + 2'd2: input_2_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + 2'd3: input_3_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + endcase + + // pass through selected packet data + output_udp_payload_tdata_int = current_input_tdata; + output_udp_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_udp_payload_tlast_int = current_input_tlast; + output_udp_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_udp_hdr_ready_reg <= 0; + input_1_udp_hdr_ready_reg <= 0; + input_2_udp_hdr_ready_reg <= 0; + input_3_udp_hdr_ready_reg <= 0; + input_0_udp_payload_tready_reg <= 0; + input_1_udp_payload_tready_reg <= 0; + input_2_udp_payload_tready_reg <= 0; + input_3_udp_payload_tready_reg <= 0; + output_udp_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_udp_source_port_reg <= 0; + output_udp_dest_port_reg <= 0; + output_udp_length_reg <= 0; + output_udp_checksum_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_udp_hdr_ready_reg <= input_0_udp_hdr_ready_next; + input_1_udp_hdr_ready_reg <= input_1_udp_hdr_ready_next; + input_2_udp_hdr_ready_reg <= input_2_udp_hdr_ready_next; + input_3_udp_hdr_ready_reg <= input_3_udp_hdr_ready_next; + input_0_udp_payload_tready_reg <= input_0_udp_payload_tready_next; + input_1_udp_payload_tready_reg <= input_1_udp_payload_tready_next; + input_2_udp_payload_tready_reg <= input_2_udp_payload_tready_next; + input_3_udp_payload_tready_reg <= input_3_udp_payload_tready_next; + output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; + end +end + +// output datapath logic +reg [7:0] output_udp_payload_tdata_reg = 0; +reg output_udp_payload_tvalid_reg = 0; +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg [7:0] temp_udp_payload_tdata_reg = 0; +reg temp_udp_payload_tvalid_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; + +assign output_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; +assign output_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_udp_payload_tuser = output_udp_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_udp_payload_tdata_reg <= 0; + output_udp_payload_tvalid_reg <= 0; + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + + if (output_udp_payload_tready_int) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py new file mode 100755 index 000000000..1e3b79db2 --- /dev/null +++ b/rtl/udp_mux_64.py @@ -0,0 +1,558 @@ +#!/usr/bin/env python +"""udp_mux_64 + +Generates an UDP mux with the specified number of ports + +Usage: udp_mux_64 [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "udp_mux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port UDP mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * UDP {{n}} port multiplexer (64 bit datapath) + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * UDP frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_udp_hdr_valid, + output wire input_{{p}}_udp_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [3:0] input_{{p}}_ip_version, + input wire [3:0] input_{{p}}_ip_ihl, + input wire [5:0] input_{{p}}_ip_dscp, + input wire [1:0] input_{{p}}_ip_ecn, + input wire [15:0] input_{{p}}_ip_length, + input wire [15:0] input_{{p}}_ip_identification, + input wire [2:0] input_{{p}}_ip_flags, + input wire [12:0] input_{{p}}_ip_fragment_offset, + input wire [7:0] input_{{p}}_ip_ttl, + input wire [7:0] input_{{p}}_ip_protocol, + input wire [15:0] input_{{p}}_ip_header_checksum, + input wire [31:0] input_{{p}}_ip_source_ip, + input wire [31:0] input_{{p}}_ip_dest_ip, + input wire [15:0] input_{{p}}_udp_source_port, + input wire [15:0] input_{{p}}_udp_dest_port, + input wire [15:0] input_{{p}}_udp_length, + input wire [15:0] input_{{p}}_udp_checksum, + input wire [63:0] input_{{p}}_udp_payload_tdata, + input wire [7:0] input_{{p}}_udp_payload_tkeep, + input wire input_{{p}}_udp_payload_tvalid, + output wire input_{{p}}_udp_payload_tready, + input wire input_{{p}}_udp_payload_tlast, + input wire input_{{p}}_udp_payload_tuser, +{% endfor %} + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [63:0] output_udp_payload_tdata, + output wire [7:0] output_udp_payload_tkeep, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; +{% for p in ports %} +reg input_{{p}}_udp_hdr_ready_reg = 0, input_{{p}}_udp_hdr_ready_next; +{%- endfor %} +{% for p in ports %} +reg input_{{p}}_udp_payload_tready_reg = 0, input_{{p}}_udp_payload_tready_next; +{%- endfor %} + +reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; + +// internal datapath +reg [63:0] output_udp_payload_tdata_int; +reg [7:0] output_udp_payload_tkeep_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; +{% for p in ports %} +assign input_{{p}}_udp_hdr_ready = input_{{p}}_udp_hdr_ready_reg; +{%- endfor %} +{% for p in ports %} +assign input_{{p}}_udp_payload_tready = input_{{p}}_udp_payload_tready_reg; +{%- endfor %} + +assign output_udp_hdr_valid = output_udp_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_udp_source_port = output_udp_source_port_reg; +assign output_udp_dest_port = output_udp_dest_port_reg; +assign output_udp_length = output_udp_length_reg; +assign output_udp_checksum = output_udp_checksum_reg; + +// mux for start of packet detection +reg selected_input_udp_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +reg [3:0] selected_input_ip_version; +reg [3:0] selected_input_ip_ihl; +reg [5:0] selected_input_ip_dscp; +reg [1:0] selected_input_ip_ecn; +reg [15:0] selected_input_ip_length; +reg [15:0] selected_input_ip_identification; +reg [2:0] selected_input_ip_flags; +reg [12:0] selected_input_ip_fragment_offset; +reg [7:0] selected_input_ip_ttl; +reg [7:0] selected_input_ip_protocol; +reg [15:0] selected_input_ip_header_checksum; +reg [31:0] selected_input_ip_source_ip; +reg [31:0] selected_input_ip_dest_ip; +reg [15:0] selected_input_udp_source_port; +reg [15:0] selected_input_udp_dest_port; +reg [15:0] selected_input_udp_length; +reg [15:0] selected_input_udp_checksum; +always @* begin + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: begin + selected_input_udp_hdr_valid = input_{{p}}_udp_hdr_valid; + selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; + selected_input_eth_src_mac = input_{{p}}_eth_src_mac; + selected_input_eth_type = input_{{p}}_eth_type; + selected_input_ip_version = input_{{p}}_ip_version; + selected_input_ip_ihl = input_{{p}}_ip_ihl; + selected_input_ip_dscp = input_{{p}}_ip_dscp; + selected_input_ip_ecn = input_{{p}}_ip_ecn; + selected_input_ip_length = input_{{p}}_ip_length; + selected_input_ip_identification = input_{{p}}_ip_identification; + selected_input_ip_flags = input_{{p}}_ip_flags; + selected_input_ip_fragment_offset = input_{{p}}_ip_fragment_offset; + selected_input_ip_ttl = input_{{p}}_ip_ttl; + selected_input_ip_protocol = input_{{p}}_ip_protocol; + selected_input_ip_header_checksum = input_{{p}}_ip_header_checksum; + selected_input_ip_source_ip = input_{{p}}_ip_source_ip; + selected_input_ip_dest_ip = input_{{p}}_ip_dest_ip; + selected_input_udp_source_port = input_{{p}}_udp_source_port; + selected_input_udp_dest_port = input_{{p}}_udp_dest_port; + selected_input_udp_length = input_{{p}}_udp_length; + selected_input_udp_checksum = input_{{p}}_udp_checksum; + end +{%- endfor %} + endcase +end + +// mux for incoming packet +reg [63:0] current_input_tdata; +reg [7:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_input_tdata = input_{{p}}_udp_payload_tdata; + current_input_tkeep = input_{{p}}_udp_payload_tkeep; + current_input_tvalid = input_{{p}}_udp_payload_tvalid; + current_input_tready = input_{{p}}_udp_payload_tready; + current_input_tlast = input_{{p}}_udp_payload_tlast; + current_input_tuser = input_{{p}}_udp_payload_tuser; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; +{% for p in ports %} + input_{{p}}_udp_hdr_ready_next = input_{{p}}_udp_hdr_ready_reg & ~input_{{p}}_udp_hdr_valid; +{%- endfor %} +{% for p in ports %} + input_{{p}}_udp_payload_tready_next = 0; +{%- endfor %} + + output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + output_udp_source_port_next = output_udp_source_port_reg; + output_udp_dest_port_next = output_udp_dest_port_reg; + output_udp_length_next = output_udp_length_reg; + output_udp_checksum_next = output_udp_checksum_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_udp_hdr_ready_next = 1; +{%- endfor %} + endcase + + output_udp_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + output_ip_version_next = selected_input_ip_version; + output_ip_ihl_next = selected_input_ip_ihl; + output_ip_dscp_next = selected_input_ip_dscp; + output_ip_ecn_next = selected_input_ip_ecn; + output_ip_length_next = selected_input_ip_length; + output_ip_identification_next = selected_input_ip_identification; + output_ip_flags_next = selected_input_ip_flags; + output_ip_fragment_offset_next = selected_input_ip_fragment_offset; + output_ip_ttl_next = selected_input_ip_ttl; + output_ip_protocol_next = selected_input_ip_protocol; + output_ip_header_checksum_next = selected_input_ip_header_checksum; + output_ip_source_ip_next = selected_input_ip_source_ip; + output_ip_dest_ip_next = selected_input_ip_dest_ip; + output_udp_source_port_next = selected_input_udp_source_port; + output_udp_dest_port_next = selected_input_udp_dest_port; + output_udp_length_next = selected_input_udp_length; + output_udp_checksum_next = selected_input_udp_checksum; + end + + // generate ready signal on selected port + case (select_next) +{%- for p in ports %} + {{w}}'d{{p}}: input_{{p}}_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; +{%- endfor %} + endcase + + // pass through selected packet data + output_udp_payload_tdata_int = current_input_tdata; + output_udp_payload_tkeep_int = current_input_tkeep; + output_udp_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_udp_payload_tlast_int = current_input_tlast; + output_udp_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; +{%- for p in ports %} + input_{{p}}_udp_hdr_ready_reg <= 0; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_udp_payload_tready_reg <= 0; +{%- endfor %} + output_udp_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_udp_source_port_reg <= 0; + output_udp_dest_port_reg <= 0; + output_udp_length_reg <= 0; + output_udp_checksum_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; +{%- for p in ports %} + input_{{p}}_udp_hdr_ready_reg <= input_{{p}}_udp_hdr_ready_next; +{%- endfor %} +{%- for p in ports %} + input_{{p}}_udp_payload_tready_reg <= input_{{p}}_udp_payload_tready_next; +{%- endfor %} + output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; + end +end + +// output datapath logic +reg [63:0] output_udp_payload_tdata_reg = 0; +reg [7:0] output_udp_payload_tkeep_reg = 0; +reg output_udp_payload_tvalid_reg = 0; +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg [63:0] temp_udp_payload_tdata_reg = 0; +reg [7:0] temp_udp_payload_tkeep_reg = 0; +reg temp_udp_payload_tvalid_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; + +assign output_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; +assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; +assign output_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_udp_payload_tuser = output_udp_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_udp_payload_tdata_reg <= 0; + output_udp_payload_tkeep_reg <= 0; + output_udp_payload_tvalid_reg <= 0; + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + + if (output_udp_payload_tready_int) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/udp_mux_64_4.v b/rtl/udp_mux_64_4.v new file mode 100644 index 000000000..f363402b0 --- /dev/null +++ b/rtl/udp_mux_64_4.v @@ -0,0 +1,666 @@ +/* + +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 + +/* + * UDP 4 port multiplexer (64 bit datapath) + */ +module udp_mux_64_4 +( + input wire clk, + input wire rst, + + /* + * UDP frame inputs + */ + input wire input_0_udp_hdr_valid, + output wire input_0_udp_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [15:0] input_0_udp_source_port, + input wire [15:0] input_0_udp_dest_port, + input wire [15:0] input_0_udp_length, + input wire [15:0] input_0_udp_checksum, + input wire [63:0] input_0_udp_payload_tdata, + input wire [7:0] input_0_udp_payload_tkeep, + input wire input_0_udp_payload_tvalid, + output wire input_0_udp_payload_tready, + input wire input_0_udp_payload_tlast, + input wire input_0_udp_payload_tuser, + + input wire input_1_udp_hdr_valid, + output wire input_1_udp_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [15:0] input_1_udp_source_port, + input wire [15:0] input_1_udp_dest_port, + input wire [15:0] input_1_udp_length, + input wire [15:0] input_1_udp_checksum, + input wire [63:0] input_1_udp_payload_tdata, + input wire [7:0] input_1_udp_payload_tkeep, + input wire input_1_udp_payload_tvalid, + output wire input_1_udp_payload_tready, + input wire input_1_udp_payload_tlast, + input wire input_1_udp_payload_tuser, + + input wire input_2_udp_hdr_valid, + output wire input_2_udp_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [3:0] input_2_ip_version, + input wire [3:0] input_2_ip_ihl, + input wire [5:0] input_2_ip_dscp, + input wire [1:0] input_2_ip_ecn, + input wire [15:0] input_2_ip_length, + input wire [15:0] input_2_ip_identification, + input wire [2:0] input_2_ip_flags, + input wire [12:0] input_2_ip_fragment_offset, + input wire [7:0] input_2_ip_ttl, + input wire [7:0] input_2_ip_protocol, + input wire [15:0] input_2_ip_header_checksum, + input wire [31:0] input_2_ip_source_ip, + input wire [31:0] input_2_ip_dest_ip, + input wire [15:0] input_2_udp_source_port, + input wire [15:0] input_2_udp_dest_port, + input wire [15:0] input_2_udp_length, + input wire [15:0] input_2_udp_checksum, + input wire [63:0] input_2_udp_payload_tdata, + input wire [7:0] input_2_udp_payload_tkeep, + input wire input_2_udp_payload_tvalid, + output wire input_2_udp_payload_tready, + input wire input_2_udp_payload_tlast, + input wire input_2_udp_payload_tuser, + + input wire input_3_udp_hdr_valid, + output wire input_3_udp_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [3:0] input_3_ip_version, + input wire [3:0] input_3_ip_ihl, + input wire [5:0] input_3_ip_dscp, + input wire [1:0] input_3_ip_ecn, + input wire [15:0] input_3_ip_length, + input wire [15:0] input_3_ip_identification, + input wire [2:0] input_3_ip_flags, + input wire [12:0] input_3_ip_fragment_offset, + input wire [7:0] input_3_ip_ttl, + input wire [7:0] input_3_ip_protocol, + input wire [15:0] input_3_ip_header_checksum, + input wire [31:0] input_3_ip_source_ip, + input wire [31:0] input_3_ip_dest_ip, + input wire [15:0] input_3_udp_source_port, + input wire [15:0] input_3_udp_dest_port, + input wire [15:0] input_3_udp_length, + input wire [15:0] input_3_udp_checksum, + input wire [63:0] input_3_udp_payload_tdata, + input wire [7:0] input_3_udp_payload_tkeep, + input wire input_3_udp_payload_tvalid, + output wire input_3_udp_payload_tready, + input wire input_3_udp_payload_tlast, + input wire input_3_udp_payload_tuser, + + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [63:0] output_udp_payload_tdata, + output wire [7:0] output_udp_payload_tkeep, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_udp_hdr_ready_reg = 0, input_0_udp_hdr_ready_next; +reg input_1_udp_hdr_ready_reg = 0, input_1_udp_hdr_ready_next; +reg input_2_udp_hdr_ready_reg = 0, input_2_udp_hdr_ready_next; +reg input_3_udp_hdr_ready_reg = 0, input_3_udp_hdr_ready_next; + +reg input_0_udp_payload_tready_reg = 0, input_0_udp_payload_tready_next; +reg input_1_udp_payload_tready_reg = 0, input_1_udp_payload_tready_next; +reg input_2_udp_payload_tready_reg = 0, input_2_udp_payload_tready_next; +reg input_3_udp_payload_tready_reg = 0, input_3_udp_payload_tready_next; + +reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; + +// internal datapath +reg [63:0] output_udp_payload_tdata_int; +reg [7:0] output_udp_payload_tkeep_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; + +assign input_0_udp_hdr_ready = input_0_udp_hdr_ready_reg; +assign input_1_udp_hdr_ready = input_1_udp_hdr_ready_reg; +assign input_2_udp_hdr_ready = input_2_udp_hdr_ready_reg; +assign input_3_udp_hdr_ready = input_3_udp_hdr_ready_reg; + +assign input_0_udp_payload_tready = input_0_udp_payload_tready_reg; +assign input_1_udp_payload_tready = input_1_udp_payload_tready_reg; +assign input_2_udp_payload_tready = input_2_udp_payload_tready_reg; +assign input_3_udp_payload_tready = input_3_udp_payload_tready_reg; + +assign output_udp_hdr_valid = output_udp_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_udp_source_port = output_udp_source_port_reg; +assign output_udp_dest_port = output_udp_dest_port_reg; +assign output_udp_length = output_udp_length_reg; +assign output_udp_checksum = output_udp_checksum_reg; + +// mux for start of packet detection +reg selected_input_udp_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +reg [3:0] selected_input_ip_version; +reg [3:0] selected_input_ip_ihl; +reg [5:0] selected_input_ip_dscp; +reg [1:0] selected_input_ip_ecn; +reg [15:0] selected_input_ip_length; +reg [15:0] selected_input_ip_identification; +reg [2:0] selected_input_ip_flags; +reg [12:0] selected_input_ip_fragment_offset; +reg [7:0] selected_input_ip_ttl; +reg [7:0] selected_input_ip_protocol; +reg [15:0] selected_input_ip_header_checksum; +reg [31:0] selected_input_ip_source_ip; +reg [31:0] selected_input_ip_dest_ip; +reg [15:0] selected_input_udp_source_port; +reg [15:0] selected_input_udp_dest_port; +reg [15:0] selected_input_udp_length; +reg [15:0] selected_input_udp_checksum; +always @* begin + case (select) + 2'd0: begin + selected_input_udp_hdr_valid = input_0_udp_hdr_valid; + selected_input_eth_dest_mac = input_0_eth_dest_mac; + selected_input_eth_src_mac = input_0_eth_src_mac; + selected_input_eth_type = input_0_eth_type; + selected_input_ip_version = input_0_ip_version; + selected_input_ip_ihl = input_0_ip_ihl; + selected_input_ip_dscp = input_0_ip_dscp; + selected_input_ip_ecn = input_0_ip_ecn; + selected_input_ip_length = input_0_ip_length; + selected_input_ip_identification = input_0_ip_identification; + selected_input_ip_flags = input_0_ip_flags; + selected_input_ip_fragment_offset = input_0_ip_fragment_offset; + selected_input_ip_ttl = input_0_ip_ttl; + selected_input_ip_protocol = input_0_ip_protocol; + selected_input_ip_header_checksum = input_0_ip_header_checksum; + selected_input_ip_source_ip = input_0_ip_source_ip; + selected_input_ip_dest_ip = input_0_ip_dest_ip; + selected_input_udp_source_port = input_0_udp_source_port; + selected_input_udp_dest_port = input_0_udp_dest_port; + selected_input_udp_length = input_0_udp_length; + selected_input_udp_checksum = input_0_udp_checksum; + end + 2'd1: begin + selected_input_udp_hdr_valid = input_1_udp_hdr_valid; + selected_input_eth_dest_mac = input_1_eth_dest_mac; + selected_input_eth_src_mac = input_1_eth_src_mac; + selected_input_eth_type = input_1_eth_type; + selected_input_ip_version = input_1_ip_version; + selected_input_ip_ihl = input_1_ip_ihl; + selected_input_ip_dscp = input_1_ip_dscp; + selected_input_ip_ecn = input_1_ip_ecn; + selected_input_ip_length = input_1_ip_length; + selected_input_ip_identification = input_1_ip_identification; + selected_input_ip_flags = input_1_ip_flags; + selected_input_ip_fragment_offset = input_1_ip_fragment_offset; + selected_input_ip_ttl = input_1_ip_ttl; + selected_input_ip_protocol = input_1_ip_protocol; + selected_input_ip_header_checksum = input_1_ip_header_checksum; + selected_input_ip_source_ip = input_1_ip_source_ip; + selected_input_ip_dest_ip = input_1_ip_dest_ip; + selected_input_udp_source_port = input_1_udp_source_port; + selected_input_udp_dest_port = input_1_udp_dest_port; + selected_input_udp_length = input_1_udp_length; + selected_input_udp_checksum = input_1_udp_checksum; + end + 2'd2: begin + selected_input_udp_hdr_valid = input_2_udp_hdr_valid; + selected_input_eth_dest_mac = input_2_eth_dest_mac; + selected_input_eth_src_mac = input_2_eth_src_mac; + selected_input_eth_type = input_2_eth_type; + selected_input_ip_version = input_2_ip_version; + selected_input_ip_ihl = input_2_ip_ihl; + selected_input_ip_dscp = input_2_ip_dscp; + selected_input_ip_ecn = input_2_ip_ecn; + selected_input_ip_length = input_2_ip_length; + selected_input_ip_identification = input_2_ip_identification; + selected_input_ip_flags = input_2_ip_flags; + selected_input_ip_fragment_offset = input_2_ip_fragment_offset; + selected_input_ip_ttl = input_2_ip_ttl; + selected_input_ip_protocol = input_2_ip_protocol; + selected_input_ip_header_checksum = input_2_ip_header_checksum; + selected_input_ip_source_ip = input_2_ip_source_ip; + selected_input_ip_dest_ip = input_2_ip_dest_ip; + selected_input_udp_source_port = input_2_udp_source_port; + selected_input_udp_dest_port = input_2_udp_dest_port; + selected_input_udp_length = input_2_udp_length; + selected_input_udp_checksum = input_2_udp_checksum; + end + 2'd3: begin + selected_input_udp_hdr_valid = input_3_udp_hdr_valid; + selected_input_eth_dest_mac = input_3_eth_dest_mac; + selected_input_eth_src_mac = input_3_eth_src_mac; + selected_input_eth_type = input_3_eth_type; + selected_input_ip_version = input_3_ip_version; + selected_input_ip_ihl = input_3_ip_ihl; + selected_input_ip_dscp = input_3_ip_dscp; + selected_input_ip_ecn = input_3_ip_ecn; + selected_input_ip_length = input_3_ip_length; + selected_input_ip_identification = input_3_ip_identification; + selected_input_ip_flags = input_3_ip_flags; + selected_input_ip_fragment_offset = input_3_ip_fragment_offset; + selected_input_ip_ttl = input_3_ip_ttl; + selected_input_ip_protocol = input_3_ip_protocol; + selected_input_ip_header_checksum = input_3_ip_header_checksum; + selected_input_ip_source_ip = input_3_ip_source_ip; + selected_input_ip_dest_ip = input_3_ip_dest_ip; + selected_input_udp_source_port = input_3_udp_source_port; + selected_input_udp_dest_port = input_3_udp_dest_port; + selected_input_udp_length = input_3_udp_length; + selected_input_udp_checksum = input_3_udp_checksum; + end + endcase +end + +// mux for incoming packet +reg [63:0] current_input_tdata; +reg [7:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 2'd0: begin + current_input_tdata = input_0_udp_payload_tdata; + current_input_tkeep = input_0_udp_payload_tkeep; + current_input_tvalid = input_0_udp_payload_tvalid; + current_input_tready = input_0_udp_payload_tready; + current_input_tlast = input_0_udp_payload_tlast; + current_input_tuser = input_0_udp_payload_tuser; + end + 2'd1: begin + current_input_tdata = input_1_udp_payload_tdata; + current_input_tkeep = input_1_udp_payload_tkeep; + current_input_tvalid = input_1_udp_payload_tvalid; + current_input_tready = input_1_udp_payload_tready; + current_input_tlast = input_1_udp_payload_tlast; + current_input_tuser = input_1_udp_payload_tuser; + end + 2'd2: begin + current_input_tdata = input_2_udp_payload_tdata; + current_input_tkeep = input_2_udp_payload_tkeep; + current_input_tvalid = input_2_udp_payload_tvalid; + current_input_tready = input_2_udp_payload_tready; + current_input_tlast = input_2_udp_payload_tlast; + current_input_tuser = input_2_udp_payload_tuser; + end + 2'd3: begin + current_input_tdata = input_3_udp_payload_tdata; + current_input_tkeep = input_3_udp_payload_tkeep; + current_input_tvalid = input_3_udp_payload_tvalid; + current_input_tready = input_3_udp_payload_tready; + current_input_tlast = input_3_udp_payload_tlast; + current_input_tuser = input_3_udp_payload_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_udp_hdr_ready_next = input_0_udp_hdr_ready_reg & ~input_0_udp_hdr_valid; + input_1_udp_hdr_ready_next = input_1_udp_hdr_ready_reg & ~input_1_udp_hdr_valid; + input_2_udp_hdr_ready_next = input_2_udp_hdr_ready_reg & ~input_2_udp_hdr_valid; + input_3_udp_hdr_ready_next = input_3_udp_hdr_ready_reg & ~input_3_udp_hdr_valid; + + input_0_udp_payload_tready_next = 0; + input_1_udp_payload_tready_next = 0; + input_2_udp_payload_tready_next = 0; + input_3_udp_payload_tready_next = 0; + + output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + output_udp_source_port_next = output_udp_source_port_reg; + output_udp_dest_port_next = output_udp_dest_port_reg; + output_udp_length_next = output_udp_length_reg; + output_udp_checksum_next = output_udp_checksum_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) + 2'd0: input_0_udp_hdr_ready_next = 1; + 2'd1: input_1_udp_hdr_ready_next = 1; + 2'd2: input_2_udp_hdr_ready_next = 1; + 2'd3: input_3_udp_hdr_ready_next = 1; + endcase + + output_udp_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + output_ip_version_next = selected_input_ip_version; + output_ip_ihl_next = selected_input_ip_ihl; + output_ip_dscp_next = selected_input_ip_dscp; + output_ip_ecn_next = selected_input_ip_ecn; + output_ip_length_next = selected_input_ip_length; + output_ip_identification_next = selected_input_ip_identification; + output_ip_flags_next = selected_input_ip_flags; + output_ip_fragment_offset_next = selected_input_ip_fragment_offset; + output_ip_ttl_next = selected_input_ip_ttl; + output_ip_protocol_next = selected_input_ip_protocol; + output_ip_header_checksum_next = selected_input_ip_header_checksum; + output_ip_source_ip_next = selected_input_ip_source_ip; + output_ip_dest_ip_next = selected_input_ip_dest_ip; + output_udp_source_port_next = selected_input_udp_source_port; + output_udp_dest_port_next = selected_input_udp_dest_port; + output_udp_length_next = selected_input_udp_length; + output_udp_checksum_next = selected_input_udp_checksum; + end + + // generate ready signal on selected port + case (select_next) + 2'd0: input_0_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + 2'd1: input_1_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + 2'd2: input_2_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + 2'd3: input_3_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + endcase + + // pass through selected packet data + output_udp_payload_tdata_int = current_input_tdata; + output_udp_payload_tkeep_int = current_input_tkeep; + output_udp_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_udp_payload_tlast_int = current_input_tlast; + output_udp_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_udp_hdr_ready_reg <= 0; + input_1_udp_hdr_ready_reg <= 0; + input_2_udp_hdr_ready_reg <= 0; + input_3_udp_hdr_ready_reg <= 0; + input_0_udp_payload_tready_reg <= 0; + input_1_udp_payload_tready_reg <= 0; + input_2_udp_payload_tready_reg <= 0; + input_3_udp_payload_tready_reg <= 0; + output_udp_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_udp_source_port_reg <= 0; + output_udp_dest_port_reg <= 0; + output_udp_length_reg <= 0; + output_udp_checksum_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_udp_hdr_ready_reg <= input_0_udp_hdr_ready_next; + input_1_udp_hdr_ready_reg <= input_1_udp_hdr_ready_next; + input_2_udp_hdr_ready_reg <= input_2_udp_hdr_ready_next; + input_3_udp_hdr_ready_reg <= input_3_udp_hdr_ready_next; + input_0_udp_payload_tready_reg <= input_0_udp_payload_tready_next; + input_1_udp_payload_tready_reg <= input_1_udp_payload_tready_next; + input_2_udp_payload_tready_reg <= input_2_udp_payload_tready_next; + input_3_udp_payload_tready_reg <= input_3_udp_payload_tready_next; + output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; + end +end + +// output datapath logic +reg [63:0] output_udp_payload_tdata_reg = 0; +reg [7:0] output_udp_payload_tkeep_reg = 0; +reg output_udp_payload_tvalid_reg = 0; +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg [63:0] temp_udp_payload_tdata_reg = 0; +reg [7:0] temp_udp_payload_tkeep_reg = 0; +reg temp_udp_payload_tvalid_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; + +assign output_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; +assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; +assign output_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_udp_payload_tuser = output_udp_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_udp_payload_tdata_reg <= 0; + output_udp_payload_tkeep_reg <= 0; + output_udp_payload_tvalid_reg <= 0; + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + + if (output_udp_payload_tready_int) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_udp_mux_4.py b/tb/test_udp_mux_4.py new file mode 100755 index 000000000..6a9d00382 --- /dev/null +++ b/tb/test_udp_mux_4.py @@ -0,0 +1,1258 @@ +#!/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 udp_ep + +module = 'udp_mux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp_mux_4(clk, + rst, + current_test, + + input_0_udp_hdr_valid, + input_0_udp_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tvalid, + input_0_udp_payload_tready, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_udp_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tvalid, + input_1_udp_payload_tready, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_udp_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tvalid, + input_2_udp_payload_tready, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_udp_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tvalid, + input_3_udp_payload_tready, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + enable, + select): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_udp_hdr_valid=input_0_udp_hdr_valid, + input_0_udp_hdr_ready=input_0_udp_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_ip_version=input_0_ip_version, + input_0_ip_ihl=input_0_ip_ihl, + input_0_ip_dscp=input_0_ip_dscp, + input_0_ip_ecn=input_0_ip_ecn, + input_0_ip_length=input_0_ip_length, + input_0_ip_identification=input_0_ip_identification, + input_0_ip_flags=input_0_ip_flags, + input_0_ip_fragment_offset=input_0_ip_fragment_offset, + input_0_ip_ttl=input_0_ip_ttl, + input_0_ip_protocol=input_0_ip_protocol, + input_0_ip_header_checksum=input_0_ip_header_checksum, + input_0_ip_source_ip=input_0_ip_source_ip, + input_0_ip_dest_ip=input_0_ip_dest_ip, + input_0_udp_source_port=input_0_udp_source_port, + input_0_udp_dest_port=input_0_udp_dest_port, + input_0_udp_length=input_0_udp_length, + input_0_udp_checksum=input_0_udp_checksum, + input_0_udp_payload_tdata=input_0_udp_payload_tdata, + input_0_udp_payload_tvalid=input_0_udp_payload_tvalid, + input_0_udp_payload_tready=input_0_udp_payload_tready, + input_0_udp_payload_tlast=input_0_udp_payload_tlast, + input_0_udp_payload_tuser=input_0_udp_payload_tuser, + input_1_udp_hdr_valid=input_1_udp_hdr_valid, + input_1_udp_hdr_ready=input_1_udp_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_ip_version=input_1_ip_version, + input_1_ip_ihl=input_1_ip_ihl, + input_1_ip_dscp=input_1_ip_dscp, + input_1_ip_ecn=input_1_ip_ecn, + input_1_ip_length=input_1_ip_length, + input_1_ip_identification=input_1_ip_identification, + input_1_ip_flags=input_1_ip_flags, + input_1_ip_fragment_offset=input_1_ip_fragment_offset, + input_1_ip_ttl=input_1_ip_ttl, + input_1_ip_protocol=input_1_ip_protocol, + input_1_ip_header_checksum=input_1_ip_header_checksum, + input_1_ip_source_ip=input_1_ip_source_ip, + input_1_ip_dest_ip=input_1_ip_dest_ip, + input_1_udp_source_port=input_1_udp_source_port, + input_1_udp_dest_port=input_1_udp_dest_port, + input_1_udp_length=input_1_udp_length, + input_1_udp_checksum=input_1_udp_checksum, + input_1_udp_payload_tdata=input_1_udp_payload_tdata, + input_1_udp_payload_tvalid=input_1_udp_payload_tvalid, + input_1_udp_payload_tready=input_1_udp_payload_tready, + input_1_udp_payload_tlast=input_1_udp_payload_tlast, + input_1_udp_payload_tuser=input_1_udp_payload_tuser, + input_2_udp_hdr_valid=input_2_udp_hdr_valid, + input_2_udp_hdr_ready=input_2_udp_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_ip_version=input_2_ip_version, + input_2_ip_ihl=input_2_ip_ihl, + input_2_ip_dscp=input_2_ip_dscp, + input_2_ip_ecn=input_2_ip_ecn, + input_2_ip_length=input_2_ip_length, + input_2_ip_identification=input_2_ip_identification, + input_2_ip_flags=input_2_ip_flags, + input_2_ip_fragment_offset=input_2_ip_fragment_offset, + input_2_ip_ttl=input_2_ip_ttl, + input_2_ip_protocol=input_2_ip_protocol, + input_2_ip_header_checksum=input_2_ip_header_checksum, + input_2_ip_source_ip=input_2_ip_source_ip, + input_2_ip_dest_ip=input_2_ip_dest_ip, + input_2_udp_source_port=input_2_udp_source_port, + input_2_udp_dest_port=input_2_udp_dest_port, + input_2_udp_length=input_2_udp_length, + input_2_udp_checksum=input_2_udp_checksum, + input_2_udp_payload_tdata=input_2_udp_payload_tdata, + input_2_udp_payload_tvalid=input_2_udp_payload_tvalid, + input_2_udp_payload_tready=input_2_udp_payload_tready, + input_2_udp_payload_tlast=input_2_udp_payload_tlast, + input_2_udp_payload_tuser=input_2_udp_payload_tuser, + input_3_udp_hdr_valid=input_3_udp_hdr_valid, + input_3_udp_hdr_ready=input_3_udp_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_ip_version=input_3_ip_version, + input_3_ip_ihl=input_3_ip_ihl, + input_3_ip_dscp=input_3_ip_dscp, + input_3_ip_ecn=input_3_ip_ecn, + input_3_ip_length=input_3_ip_length, + input_3_ip_identification=input_3_ip_identification, + input_3_ip_flags=input_3_ip_flags, + input_3_ip_fragment_offset=input_3_ip_fragment_offset, + input_3_ip_ttl=input_3_ip_ttl, + input_3_ip_protocol=input_3_ip_protocol, + input_3_ip_header_checksum=input_3_ip_header_checksum, + input_3_ip_source_ip=input_3_ip_source_ip, + input_3_ip_dest_ip=input_3_ip_dest_ip, + input_3_udp_source_port=input_3_udp_source_port, + input_3_udp_dest_port=input_3_udp_dest_port, + input_3_udp_length=input_3_udp_length, + input_3_udp_checksum=input_3_udp_checksum, + input_3_udp_payload_tdata=input_3_udp_payload_tdata, + input_3_udp_payload_tvalid=input_3_udp_payload_tvalid, + input_3_udp_payload_tready=input_3_udp_payload_tready, + input_3_udp_payload_tlast=input_3_udp_payload_tlast, + input_3_udp_payload_tuser=input_3_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + enable=enable, + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_udp_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_ip_version = Signal(intbv(0)[4:]) + input_0_ip_ihl = Signal(intbv(0)[4:]) + input_0_ip_dscp = Signal(intbv(0)[6:]) + input_0_ip_ecn = Signal(intbv(0)[2:]) + input_0_ip_length = Signal(intbv(0)[16:]) + input_0_ip_identification = Signal(intbv(0)[16:]) + input_0_ip_flags = Signal(intbv(0)[3:]) + input_0_ip_fragment_offset = Signal(intbv(0)[13:]) + input_0_ip_ttl = Signal(intbv(0)[8:]) + input_0_ip_protocol = Signal(intbv(0)[8:]) + input_0_ip_header_checksum = Signal(intbv(0)[16:]) + input_0_ip_source_ip = Signal(intbv(0)[32:]) + input_0_ip_dest_ip = Signal(intbv(0)[32:]) + input_0_udp_source_port = Signal(intbv(0)[16:]) + input_0_udp_dest_port = Signal(intbv(0)[16:]) + input_0_udp_length = Signal(intbv(0)[16:]) + input_0_udp_checksum = Signal(intbv(0)[16:]) + input_0_udp_payload_tdata = Signal(intbv(0)[8:]) + input_0_udp_payload_tvalid = Signal(bool(0)) + input_0_udp_payload_tlast = Signal(bool(0)) + input_0_udp_payload_tuser = Signal(bool(0)) + input_1_udp_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_ip_version = Signal(intbv(0)[4:]) + input_1_ip_ihl = Signal(intbv(0)[4:]) + input_1_ip_dscp = Signal(intbv(0)[6:]) + input_1_ip_ecn = Signal(intbv(0)[2:]) + input_1_ip_length = Signal(intbv(0)[16:]) + input_1_ip_identification = Signal(intbv(0)[16:]) + input_1_ip_flags = Signal(intbv(0)[3:]) + input_1_ip_fragment_offset = Signal(intbv(0)[13:]) + input_1_ip_ttl = Signal(intbv(0)[8:]) + input_1_ip_protocol = Signal(intbv(0)[8:]) + input_1_ip_header_checksum = Signal(intbv(0)[16:]) + input_1_ip_source_ip = Signal(intbv(0)[32:]) + input_1_ip_dest_ip = Signal(intbv(0)[32:]) + input_1_udp_source_port = Signal(intbv(0)[16:]) + input_1_udp_dest_port = Signal(intbv(0)[16:]) + input_1_udp_length = Signal(intbv(0)[16:]) + input_1_udp_checksum = Signal(intbv(0)[16:]) + input_1_udp_payload_tdata = Signal(intbv(0)[8:]) + input_1_udp_payload_tvalid = Signal(bool(0)) + input_1_udp_payload_tlast = Signal(bool(0)) + input_1_udp_payload_tuser = Signal(bool(0)) + input_2_udp_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_ip_version = Signal(intbv(0)[4:]) + input_2_ip_ihl = Signal(intbv(0)[4:]) + input_2_ip_dscp = Signal(intbv(0)[6:]) + input_2_ip_ecn = Signal(intbv(0)[2:]) + input_2_ip_length = Signal(intbv(0)[16:]) + input_2_ip_identification = Signal(intbv(0)[16:]) + input_2_ip_flags = Signal(intbv(0)[3:]) + input_2_ip_fragment_offset = Signal(intbv(0)[13:]) + input_2_ip_ttl = Signal(intbv(0)[8:]) + input_2_ip_protocol = Signal(intbv(0)[8:]) + input_2_ip_header_checksum = Signal(intbv(0)[16:]) + input_2_ip_source_ip = Signal(intbv(0)[32:]) + input_2_ip_dest_ip = Signal(intbv(0)[32:]) + input_2_udp_source_port = Signal(intbv(0)[16:]) + input_2_udp_dest_port = Signal(intbv(0)[16:]) + input_2_udp_length = Signal(intbv(0)[16:]) + input_2_udp_checksum = Signal(intbv(0)[16:]) + input_2_udp_payload_tdata = Signal(intbv(0)[8:]) + input_2_udp_payload_tvalid = Signal(bool(0)) + input_2_udp_payload_tlast = Signal(bool(0)) + input_2_udp_payload_tuser = Signal(bool(0)) + input_3_udp_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_ip_version = Signal(intbv(0)[4:]) + input_3_ip_ihl = Signal(intbv(0)[4:]) + input_3_ip_dscp = Signal(intbv(0)[6:]) + input_3_ip_ecn = Signal(intbv(0)[2:]) + input_3_ip_length = Signal(intbv(0)[16:]) + input_3_ip_identification = Signal(intbv(0)[16:]) + input_3_ip_flags = Signal(intbv(0)[3:]) + input_3_ip_fragment_offset = Signal(intbv(0)[13:]) + input_3_ip_ttl = Signal(intbv(0)[8:]) + input_3_ip_protocol = Signal(intbv(0)[8:]) + input_3_ip_header_checksum = Signal(intbv(0)[16:]) + input_3_ip_source_ip = Signal(intbv(0)[32:]) + input_3_ip_dest_ip = Signal(intbv(0)[32:]) + input_3_udp_source_port = Signal(intbv(0)[16:]) + input_3_udp_dest_port = Signal(intbv(0)[16:]) + input_3_udp_length = Signal(intbv(0)[16:]) + input_3_udp_checksum = Signal(intbv(0)[16:]) + input_3_udp_payload_tdata = Signal(intbv(0)[8:]) + input_3_udp_payload_tvalid = Signal(bool(0)) + input_3_udp_payload_tlast = Signal(bool(0)) + input_3_udp_payload_tuser = Signal(bool(0)) + + output_udp_payload_tready = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + + enable = Signal(bool(0)) + select = Signal(intbv(0)[2:]) + + # Outputs + input_0_udp_hdr_ready = Signal(bool(0)) + input_0_udp_payload_tready = Signal(bool(0)) + input_1_udp_hdr_ready = Signal(bool(0)) + input_1_udp_payload_tready = Signal(bool(0)) + input_2_udp_hdr_ready = Signal(bool(0)) + input_2_udp_payload_tready = Signal(bool(0)) + input_3_udp_hdr_ready = Signal(bool(0)) + input_3_udp_payload_tready = Signal(bool(0)) + + output_udp_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_0_udp_hdr_ready, + udp_hdr_valid=input_0_udp_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + ip_version=input_0_ip_version, + ip_ihl=input_0_ip_ihl, + ip_dscp=input_0_ip_dscp, + ip_ecn=input_0_ip_ecn, + ip_length=input_0_ip_length, + ip_identification=input_0_ip_identification, + ip_flags=input_0_ip_flags, + ip_fragment_offset=input_0_ip_fragment_offset, + ip_ttl=input_0_ip_ttl, + ip_protocol=input_0_ip_protocol, + ip_header_checksum=input_0_ip_header_checksum, + ip_source_ip=input_0_ip_source_ip, + ip_dest_ip=input_0_ip_dest_ip, + udp_source_port=input_0_udp_source_port, + udp_dest_port=input_0_udp_dest_port, + udp_length=input_0_udp_length, + udp_checksum=input_0_udp_checksum, + udp_payload_tdata=input_0_udp_payload_tdata, + udp_payload_tvalid=input_0_udp_payload_tvalid, + udp_payload_tready=input_0_udp_payload_tready, + udp_payload_tlast=input_0_udp_payload_tlast, + udp_payload_tuser=input_0_udp_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_1_udp_hdr_ready, + udp_hdr_valid=input_1_udp_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + ip_version=input_1_ip_version, + ip_ihl=input_1_ip_ihl, + ip_dscp=input_1_ip_dscp, + ip_ecn=input_1_ip_ecn, + ip_length=input_1_ip_length, + ip_identification=input_1_ip_identification, + ip_flags=input_1_ip_flags, + ip_fragment_offset=input_1_ip_fragment_offset, + ip_ttl=input_1_ip_ttl, + ip_protocol=input_1_ip_protocol, + ip_header_checksum=input_1_ip_header_checksum, + ip_source_ip=input_1_ip_source_ip, + ip_dest_ip=input_1_ip_dest_ip, + udp_source_port=input_1_udp_source_port, + udp_dest_port=input_1_udp_dest_port, + udp_length=input_1_udp_length, + udp_checksum=input_1_udp_checksum, + udp_payload_tdata=input_1_udp_payload_tdata, + udp_payload_tvalid=input_1_udp_payload_tvalid, + udp_payload_tready=input_1_udp_payload_tready, + udp_payload_tlast=input_1_udp_payload_tlast, + udp_payload_tuser=input_1_udp_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_2_udp_hdr_ready, + udp_hdr_valid=input_2_udp_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + ip_version=input_2_ip_version, + ip_ihl=input_2_ip_ihl, + ip_dscp=input_2_ip_dscp, + ip_ecn=input_2_ip_ecn, + ip_length=input_2_ip_length, + ip_identification=input_2_ip_identification, + ip_flags=input_2_ip_flags, + ip_fragment_offset=input_2_ip_fragment_offset, + ip_ttl=input_2_ip_ttl, + ip_protocol=input_2_ip_protocol, + ip_header_checksum=input_2_ip_header_checksum, + ip_source_ip=input_2_ip_source_ip, + ip_dest_ip=input_2_ip_dest_ip, + udp_source_port=input_2_udp_source_port, + udp_dest_port=input_2_udp_dest_port, + udp_length=input_2_udp_length, + udp_checksum=input_2_udp_checksum, + udp_payload_tdata=input_2_udp_payload_tdata, + udp_payload_tvalid=input_2_udp_payload_tvalid, + udp_payload_tready=input_2_udp_payload_tready, + udp_payload_tlast=input_2_udp_payload_tlast, + udp_payload_tuser=input_2_udp_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_3_udp_hdr_ready, + udp_hdr_valid=input_3_udp_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + ip_version=input_3_ip_version, + ip_ihl=input_3_ip_ihl, + ip_dscp=input_3_ip_dscp, + ip_ecn=input_3_ip_ecn, + ip_length=input_3_ip_length, + ip_identification=input_3_ip_identification, + ip_flags=input_3_ip_flags, + ip_fragment_offset=input_3_ip_fragment_offset, + ip_ttl=input_3_ip_ttl, + ip_protocol=input_3_ip_protocol, + ip_header_checksum=input_3_ip_header_checksum, + ip_source_ip=input_3_ip_source_ip, + ip_dest_ip=input_3_ip_dest_ip, + udp_source_port=input_3_udp_source_port, + udp_dest_port=input_3_udp_dest_port, + udp_length=input_3_udp_length, + udp_checksum=input_3_udp_checksum, + udp_payload_tdata=input_3_udp_payload_tdata, + udp_payload_tvalid=input_3_udp_payload_tvalid, + udp_payload_tready=input_3_udp_payload_tready, + udp_payload_tlast=input_3_udp_payload_tlast, + udp_payload_tuser=input_3_udp_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_udp_mux_4(clk, + rst, + current_test, + + input_0_udp_hdr_valid, + input_0_udp_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tvalid, + input_0_udp_payload_tready, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_udp_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tvalid, + input_1_udp_payload_tready, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_udp_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tvalid, + input_2_udp_payload_tready, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_udp_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tvalid, + input_3_udp_payload_tready, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + enable, + select) + + @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 + enable.next = True + + yield clk.posedge + print("test 1: select port 0") + current_test.next = 1 + + select.next = 0 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + yield clk.posedge + select.next = 2 + 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: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + select.next = 2 + 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: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + select.next = 2 + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_mux_4.v b/tb/test_udp_mux_4.v new file mode 100644 index 000000000..120825e01 --- /dev/null +++ b/tb/test_udp_mux_4.v @@ -0,0 +1,473 @@ +/* + +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_udp_mux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_udp_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [3:0] input_0_ip_version = 0; +reg [3:0] input_0_ip_ihl = 0; +reg [5:0] input_0_ip_dscp = 0; +reg [1:0] input_0_ip_ecn = 0; +reg [15:0] input_0_ip_length = 0; +reg [15:0] input_0_ip_identification = 0; +reg [2:0] input_0_ip_flags = 0; +reg [12:0] input_0_ip_fragment_offset = 0; +reg [7:0] input_0_ip_ttl = 0; +reg [7:0] input_0_ip_protocol = 0; +reg [15:0] input_0_ip_header_checksum = 0; +reg [31:0] input_0_ip_source_ip = 0; +reg [31:0] input_0_ip_dest_ip = 0; +reg [15:0] input_0_udp_source_port = 0; +reg [15:0] input_0_udp_dest_port = 0; +reg [15:0] input_0_udp_length = 0; +reg [15:0] input_0_udp_checksum = 0; +reg [7:0] input_0_udp_payload_tdata = 0; +reg input_0_udp_payload_tvalid = 0; +reg input_0_udp_payload_tlast = 0; +reg input_0_udp_payload_tuser = 0; +reg input_1_udp_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [3:0] input_1_ip_version = 0; +reg [3:0] input_1_ip_ihl = 0; +reg [5:0] input_1_ip_dscp = 0; +reg [1:0] input_1_ip_ecn = 0; +reg [15:0] input_1_ip_length = 0; +reg [15:0] input_1_ip_identification = 0; +reg [2:0] input_1_ip_flags = 0; +reg [12:0] input_1_ip_fragment_offset = 0; +reg [7:0] input_1_ip_ttl = 0; +reg [7:0] input_1_ip_protocol = 0; +reg [15:0] input_1_ip_header_checksum = 0; +reg [31:0] input_1_ip_source_ip = 0; +reg [31:0] input_1_ip_dest_ip = 0; +reg [15:0] input_1_udp_source_port = 0; +reg [15:0] input_1_udp_dest_port = 0; +reg [15:0] input_1_udp_length = 0; +reg [15:0] input_1_udp_checksum = 0; +reg [7:0] input_1_udp_payload_tdata = 0; +reg input_1_udp_payload_tvalid = 0; +reg input_1_udp_payload_tlast = 0; +reg input_1_udp_payload_tuser = 0; +reg input_2_udp_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [3:0] input_2_ip_version = 0; +reg [3:0] input_2_ip_ihl = 0; +reg [5:0] input_2_ip_dscp = 0; +reg [1:0] input_2_ip_ecn = 0; +reg [15:0] input_2_ip_length = 0; +reg [15:0] input_2_ip_identification = 0; +reg [2:0] input_2_ip_flags = 0; +reg [12:0] input_2_ip_fragment_offset = 0; +reg [7:0] input_2_ip_ttl = 0; +reg [7:0] input_2_ip_protocol = 0; +reg [15:0] input_2_ip_header_checksum = 0; +reg [31:0] input_2_ip_source_ip = 0; +reg [31:0] input_2_ip_dest_ip = 0; +reg [15:0] input_2_udp_source_port = 0; +reg [15:0] input_2_udp_dest_port = 0; +reg [15:0] input_2_udp_length = 0; +reg [15:0] input_2_udp_checksum = 0; +reg [7:0] input_2_udp_payload_tdata = 0; +reg input_2_udp_payload_tvalid = 0; +reg input_2_udp_payload_tlast = 0; +reg input_2_udp_payload_tuser = 0; +reg input_3_udp_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [3:0] input_3_ip_version = 0; +reg [3:0] input_3_ip_ihl = 0; +reg [5:0] input_3_ip_dscp = 0; +reg [1:0] input_3_ip_ecn = 0; +reg [15:0] input_3_ip_length = 0; +reg [15:0] input_3_ip_identification = 0; +reg [2:0] input_3_ip_flags = 0; +reg [12:0] input_3_ip_fragment_offset = 0; +reg [7:0] input_3_ip_ttl = 0; +reg [7:0] input_3_ip_protocol = 0; +reg [15:0] input_3_ip_header_checksum = 0; +reg [31:0] input_3_ip_source_ip = 0; +reg [31:0] input_3_ip_dest_ip = 0; +reg [15:0] input_3_udp_source_port = 0; +reg [15:0] input_3_udp_dest_port = 0; +reg [15:0] input_3_udp_length = 0; +reg [15:0] input_3_udp_checksum = 0; +reg [7:0] input_3_udp_payload_tdata = 0; +reg input_3_udp_payload_tvalid = 0; +reg input_3_udp_payload_tlast = 0; +reg input_3_udp_payload_tuser = 0; + +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; + +reg enable = 0; +reg [1:0] select = 0; + +// Outputs +wire input_0_udp_payload_tready; +wire input_0_udp_hdr_ready; +wire input_1_udp_payload_tready; +wire input_1_udp_hdr_ready; +wire input_2_udp_payload_tready; +wire input_2_udp_hdr_ready; +wire input_3_udp_payload_tready; +wire input_3_udp_hdr_ready; + +wire output_udp_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [7:0] output_udp_payload_tdata; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_udp_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tvalid, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tvalid, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tvalid, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tvalid, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + output_udp_hdr_ready, + output_udp_payload_tready, + enable, + select); + $to_myhdl(input_0_udp_hdr_ready, + input_0_udp_payload_tready, + input_1_udp_hdr_ready, + input_1_udp_payload_tready, + input_2_udp_hdr_ready, + input_2_udp_payload_tready, + input_3_udp_hdr_ready, + input_3_udp_payload_tready, + output_udp_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser); + + // dump file + $dumpfile("test_udp_mux_4.lxt"); + $dumpvars(0, test_udp_mux_4); +end + +udp_mux_4 +UUT ( + .clk(clk), + .rst(rst), + // UDP frame inputs + .input_0_udp_hdr_valid(input_0_udp_hdr_valid), + .input_0_udp_hdr_ready(input_0_udp_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_udp_source_port(input_0_udp_source_port), + .input_0_udp_dest_port(input_0_udp_dest_port), + .input_0_udp_length(input_0_udp_length), + .input_0_udp_checksum(input_0_udp_checksum), + .input_0_udp_payload_tdata(input_0_udp_payload_tdata), + .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid), + .input_0_udp_payload_tready(input_0_udp_payload_tready), + .input_0_udp_payload_tlast(input_0_udp_payload_tlast), + .input_0_udp_payload_tuser(input_0_udp_payload_tuser), + .input_1_udp_hdr_valid(input_1_udp_hdr_valid), + .input_1_udp_hdr_ready(input_1_udp_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_udp_source_port(input_1_udp_source_port), + .input_1_udp_dest_port(input_1_udp_dest_port), + .input_1_udp_length(input_1_udp_length), + .input_1_udp_checksum(input_1_udp_checksum), + .input_1_udp_payload_tdata(input_1_udp_payload_tdata), + .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid), + .input_1_udp_payload_tready(input_1_udp_payload_tready), + .input_1_udp_payload_tlast(input_1_udp_payload_tlast), + .input_1_udp_payload_tuser(input_1_udp_payload_tuser), + .input_2_udp_hdr_valid(input_2_udp_hdr_valid), + .input_2_udp_hdr_ready(input_2_udp_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_udp_source_port(input_2_udp_source_port), + .input_2_udp_dest_port(input_2_udp_dest_port), + .input_2_udp_length(input_2_udp_length), + .input_2_udp_checksum(input_2_udp_checksum), + .input_2_udp_payload_tdata(input_2_udp_payload_tdata), + .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid), + .input_2_udp_payload_tready(input_2_udp_payload_tready), + .input_2_udp_payload_tlast(input_2_udp_payload_tlast), + .input_2_udp_payload_tuser(input_2_udp_payload_tuser), + .input_3_udp_hdr_valid(input_3_udp_hdr_valid), + .input_3_udp_hdr_ready(input_3_udp_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_udp_source_port(input_3_udp_source_port), + .input_3_udp_dest_port(input_3_udp_dest_port), + .input_3_udp_length(input_3_udp_length), + .input_3_udp_checksum(input_3_udp_checksum), + .input_3_udp_payload_tdata(input_3_udp_payload_tdata), + .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid), + .input_3_udp_payload_tready(input_3_udp_payload_tready), + .input_3_udp_payload_tlast(input_3_udp_payload_tlast), + .input_3_udp_payload_tuser(input_3_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule diff --git a/tb/test_udp_mux_64_4.py b/tb/test_udp_mux_64_4.py new file mode 100755 index 000000000..177ef1896 --- /dev/null +++ b/tb/test_udp_mux_64_4.py @@ -0,0 +1,1283 @@ +#!/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 udp_ep + +module = 'udp_mux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp_mux_64_4(clk, + rst, + current_test, + + input_0_udp_hdr_valid, + input_0_udp_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tkeep, + input_0_udp_payload_tvalid, + input_0_udp_payload_tready, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_udp_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tkeep, + input_1_udp_payload_tvalid, + input_1_udp_payload_tready, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_udp_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tkeep, + input_2_udp_payload_tvalid, + input_2_udp_payload_tready, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_udp_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tkeep, + input_3_udp_payload_tvalid, + input_3_udp_payload_tready, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + enable, + select): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_udp_hdr_valid=input_0_udp_hdr_valid, + input_0_udp_hdr_ready=input_0_udp_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_ip_version=input_0_ip_version, + input_0_ip_ihl=input_0_ip_ihl, + input_0_ip_dscp=input_0_ip_dscp, + input_0_ip_ecn=input_0_ip_ecn, + input_0_ip_length=input_0_ip_length, + input_0_ip_identification=input_0_ip_identification, + input_0_ip_flags=input_0_ip_flags, + input_0_ip_fragment_offset=input_0_ip_fragment_offset, + input_0_ip_ttl=input_0_ip_ttl, + input_0_ip_protocol=input_0_ip_protocol, + input_0_ip_header_checksum=input_0_ip_header_checksum, + input_0_ip_source_ip=input_0_ip_source_ip, + input_0_ip_dest_ip=input_0_ip_dest_ip, + input_0_udp_source_port=input_0_udp_source_port, + input_0_udp_dest_port=input_0_udp_dest_port, + input_0_udp_length=input_0_udp_length, + input_0_udp_checksum=input_0_udp_checksum, + input_0_udp_payload_tdata=input_0_udp_payload_tdata, + input_0_udp_payload_tkeep=input_0_udp_payload_tkeep, + input_0_udp_payload_tvalid=input_0_udp_payload_tvalid, + input_0_udp_payload_tready=input_0_udp_payload_tready, + input_0_udp_payload_tlast=input_0_udp_payload_tlast, + input_0_udp_payload_tuser=input_0_udp_payload_tuser, + input_1_udp_hdr_valid=input_1_udp_hdr_valid, + input_1_udp_hdr_ready=input_1_udp_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_ip_version=input_1_ip_version, + input_1_ip_ihl=input_1_ip_ihl, + input_1_ip_dscp=input_1_ip_dscp, + input_1_ip_ecn=input_1_ip_ecn, + input_1_ip_length=input_1_ip_length, + input_1_ip_identification=input_1_ip_identification, + input_1_ip_flags=input_1_ip_flags, + input_1_ip_fragment_offset=input_1_ip_fragment_offset, + input_1_ip_ttl=input_1_ip_ttl, + input_1_ip_protocol=input_1_ip_protocol, + input_1_ip_header_checksum=input_1_ip_header_checksum, + input_1_ip_source_ip=input_1_ip_source_ip, + input_1_ip_dest_ip=input_1_ip_dest_ip, + input_1_udp_source_port=input_1_udp_source_port, + input_1_udp_dest_port=input_1_udp_dest_port, + input_1_udp_length=input_1_udp_length, + input_1_udp_checksum=input_1_udp_checksum, + input_1_udp_payload_tdata=input_1_udp_payload_tdata, + input_1_udp_payload_tkeep=input_1_udp_payload_tkeep, + input_1_udp_payload_tvalid=input_1_udp_payload_tvalid, + input_1_udp_payload_tready=input_1_udp_payload_tready, + input_1_udp_payload_tlast=input_1_udp_payload_tlast, + input_1_udp_payload_tuser=input_1_udp_payload_tuser, + input_2_udp_hdr_valid=input_2_udp_hdr_valid, + input_2_udp_hdr_ready=input_2_udp_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_ip_version=input_2_ip_version, + input_2_ip_ihl=input_2_ip_ihl, + input_2_ip_dscp=input_2_ip_dscp, + input_2_ip_ecn=input_2_ip_ecn, + input_2_ip_length=input_2_ip_length, + input_2_ip_identification=input_2_ip_identification, + input_2_ip_flags=input_2_ip_flags, + input_2_ip_fragment_offset=input_2_ip_fragment_offset, + input_2_ip_ttl=input_2_ip_ttl, + input_2_ip_protocol=input_2_ip_protocol, + input_2_ip_header_checksum=input_2_ip_header_checksum, + input_2_ip_source_ip=input_2_ip_source_ip, + input_2_ip_dest_ip=input_2_ip_dest_ip, + input_2_udp_source_port=input_2_udp_source_port, + input_2_udp_dest_port=input_2_udp_dest_port, + input_2_udp_length=input_2_udp_length, + input_2_udp_checksum=input_2_udp_checksum, + input_2_udp_payload_tdata=input_2_udp_payload_tdata, + input_2_udp_payload_tkeep=input_2_udp_payload_tkeep, + input_2_udp_payload_tvalid=input_2_udp_payload_tvalid, + input_2_udp_payload_tready=input_2_udp_payload_tready, + input_2_udp_payload_tlast=input_2_udp_payload_tlast, + input_2_udp_payload_tuser=input_2_udp_payload_tuser, + input_3_udp_hdr_valid=input_3_udp_hdr_valid, + input_3_udp_hdr_ready=input_3_udp_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_ip_version=input_3_ip_version, + input_3_ip_ihl=input_3_ip_ihl, + input_3_ip_dscp=input_3_ip_dscp, + input_3_ip_ecn=input_3_ip_ecn, + input_3_ip_length=input_3_ip_length, + input_3_ip_identification=input_3_ip_identification, + input_3_ip_flags=input_3_ip_flags, + input_3_ip_fragment_offset=input_3_ip_fragment_offset, + input_3_ip_ttl=input_3_ip_ttl, + input_3_ip_protocol=input_3_ip_protocol, + input_3_ip_header_checksum=input_3_ip_header_checksum, + input_3_ip_source_ip=input_3_ip_source_ip, + input_3_ip_dest_ip=input_3_ip_dest_ip, + input_3_udp_source_port=input_3_udp_source_port, + input_3_udp_dest_port=input_3_udp_dest_port, + input_3_udp_length=input_3_udp_length, + input_3_udp_checksum=input_3_udp_checksum, + input_3_udp_payload_tdata=input_3_udp_payload_tdata, + input_3_udp_payload_tkeep=input_3_udp_payload_tkeep, + input_3_udp_payload_tvalid=input_3_udp_payload_tvalid, + input_3_udp_payload_tready=input_3_udp_payload_tready, + input_3_udp_payload_tlast=input_3_udp_payload_tlast, + input_3_udp_payload_tuser=input_3_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tkeep=output_udp_payload_tkeep, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + enable=enable, + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_udp_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_ip_version = Signal(intbv(0)[4:]) + input_0_ip_ihl = Signal(intbv(0)[4:]) + input_0_ip_dscp = Signal(intbv(0)[6:]) + input_0_ip_ecn = Signal(intbv(0)[2:]) + input_0_ip_length = Signal(intbv(0)[16:]) + input_0_ip_identification = Signal(intbv(0)[16:]) + input_0_ip_flags = Signal(intbv(0)[3:]) + input_0_ip_fragment_offset = Signal(intbv(0)[13:]) + input_0_ip_ttl = Signal(intbv(0)[8:]) + input_0_ip_protocol = Signal(intbv(0)[8:]) + input_0_ip_header_checksum = Signal(intbv(0)[16:]) + input_0_ip_source_ip = Signal(intbv(0)[32:]) + input_0_ip_dest_ip = Signal(intbv(0)[32:]) + input_0_udp_source_port = Signal(intbv(0)[16:]) + input_0_udp_dest_port = Signal(intbv(0)[16:]) + input_0_udp_length = Signal(intbv(0)[16:]) + input_0_udp_checksum = Signal(intbv(0)[16:]) + input_0_udp_payload_tdata = Signal(intbv(0)[64:]) + input_0_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_0_udp_payload_tvalid = Signal(bool(0)) + input_0_udp_payload_tlast = Signal(bool(0)) + input_0_udp_payload_tuser = Signal(bool(0)) + input_1_udp_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_ip_version = Signal(intbv(0)[4:]) + input_1_ip_ihl = Signal(intbv(0)[4:]) + input_1_ip_dscp = Signal(intbv(0)[6:]) + input_1_ip_ecn = Signal(intbv(0)[2:]) + input_1_ip_length = Signal(intbv(0)[16:]) + input_1_ip_identification = Signal(intbv(0)[16:]) + input_1_ip_flags = Signal(intbv(0)[3:]) + input_1_ip_fragment_offset = Signal(intbv(0)[13:]) + input_1_ip_ttl = Signal(intbv(0)[8:]) + input_1_ip_protocol = Signal(intbv(0)[8:]) + input_1_ip_header_checksum = Signal(intbv(0)[16:]) + input_1_ip_source_ip = Signal(intbv(0)[32:]) + input_1_ip_dest_ip = Signal(intbv(0)[32:]) + input_1_udp_source_port = Signal(intbv(0)[16:]) + input_1_udp_dest_port = Signal(intbv(0)[16:]) + input_1_udp_length = Signal(intbv(0)[16:]) + input_1_udp_checksum = Signal(intbv(0)[16:]) + input_1_udp_payload_tdata = Signal(intbv(0)[64:]) + input_1_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_1_udp_payload_tvalid = Signal(bool(0)) + input_1_udp_payload_tlast = Signal(bool(0)) + input_1_udp_payload_tuser = Signal(bool(0)) + input_2_udp_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_ip_version = Signal(intbv(0)[4:]) + input_2_ip_ihl = Signal(intbv(0)[4:]) + input_2_ip_dscp = Signal(intbv(0)[6:]) + input_2_ip_ecn = Signal(intbv(0)[2:]) + input_2_ip_length = Signal(intbv(0)[16:]) + input_2_ip_identification = Signal(intbv(0)[16:]) + input_2_ip_flags = Signal(intbv(0)[3:]) + input_2_ip_fragment_offset = Signal(intbv(0)[13:]) + input_2_ip_ttl = Signal(intbv(0)[8:]) + input_2_ip_protocol = Signal(intbv(0)[8:]) + input_2_ip_header_checksum = Signal(intbv(0)[16:]) + input_2_ip_source_ip = Signal(intbv(0)[32:]) + input_2_ip_dest_ip = Signal(intbv(0)[32:]) + input_2_udp_source_port = Signal(intbv(0)[16:]) + input_2_udp_dest_port = Signal(intbv(0)[16:]) + input_2_udp_length = Signal(intbv(0)[16:]) + input_2_udp_checksum = Signal(intbv(0)[16:]) + input_2_udp_payload_tdata = Signal(intbv(0)[64:]) + input_2_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_2_udp_payload_tvalid = Signal(bool(0)) + input_2_udp_payload_tlast = Signal(bool(0)) + input_2_udp_payload_tuser = Signal(bool(0)) + input_3_udp_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_ip_version = Signal(intbv(0)[4:]) + input_3_ip_ihl = Signal(intbv(0)[4:]) + input_3_ip_dscp = Signal(intbv(0)[6:]) + input_3_ip_ecn = Signal(intbv(0)[2:]) + input_3_ip_length = Signal(intbv(0)[16:]) + input_3_ip_identification = Signal(intbv(0)[16:]) + input_3_ip_flags = Signal(intbv(0)[3:]) + input_3_ip_fragment_offset = Signal(intbv(0)[13:]) + input_3_ip_ttl = Signal(intbv(0)[8:]) + input_3_ip_protocol = Signal(intbv(0)[8:]) + input_3_ip_header_checksum = Signal(intbv(0)[16:]) + input_3_ip_source_ip = Signal(intbv(0)[32:]) + input_3_ip_dest_ip = Signal(intbv(0)[32:]) + input_3_udp_source_port = Signal(intbv(0)[16:]) + input_3_udp_dest_port = Signal(intbv(0)[16:]) + input_3_udp_length = Signal(intbv(0)[16:]) + input_3_udp_checksum = Signal(intbv(0)[16:]) + input_3_udp_payload_tdata = Signal(intbv(0)[64:]) + input_3_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_3_udp_payload_tvalid = Signal(bool(0)) + input_3_udp_payload_tlast = Signal(bool(0)) + input_3_udp_payload_tuser = Signal(bool(0)) + + output_udp_payload_tready = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + + enable = Signal(bool(0)) + select = Signal(intbv(0)[2:]) + + # Outputs + input_0_udp_hdr_ready = Signal(bool(0)) + input_0_udp_payload_tready = Signal(bool(0)) + input_1_udp_hdr_ready = Signal(bool(0)) + input_1_udp_payload_tready = Signal(bool(0)) + input_2_udp_hdr_ready = Signal(bool(0)) + input_2_udp_payload_tready = Signal(bool(0)) + input_3_udp_hdr_ready = Signal(bool(0)) + input_3_udp_payload_tready = Signal(bool(0)) + + output_udp_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[64:]) + output_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_0_udp_hdr_ready, + udp_hdr_valid=input_0_udp_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + ip_version=input_0_ip_version, + ip_ihl=input_0_ip_ihl, + ip_dscp=input_0_ip_dscp, + ip_ecn=input_0_ip_ecn, + ip_length=input_0_ip_length, + ip_identification=input_0_ip_identification, + ip_flags=input_0_ip_flags, + ip_fragment_offset=input_0_ip_fragment_offset, + ip_ttl=input_0_ip_ttl, + ip_protocol=input_0_ip_protocol, + ip_header_checksum=input_0_ip_header_checksum, + ip_source_ip=input_0_ip_source_ip, + ip_dest_ip=input_0_ip_dest_ip, + udp_source_port=input_0_udp_source_port, + udp_dest_port=input_0_udp_dest_port, + udp_length=input_0_udp_length, + udp_checksum=input_0_udp_checksum, + udp_payload_tdata=input_0_udp_payload_tdata, + udp_payload_tkeep=input_0_udp_payload_tkeep, + udp_payload_tvalid=input_0_udp_payload_tvalid, + udp_payload_tready=input_0_udp_payload_tready, + udp_payload_tlast=input_0_udp_payload_tlast, + udp_payload_tuser=input_0_udp_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_1_udp_hdr_ready, + udp_hdr_valid=input_1_udp_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + ip_version=input_1_ip_version, + ip_ihl=input_1_ip_ihl, + ip_dscp=input_1_ip_dscp, + ip_ecn=input_1_ip_ecn, + ip_length=input_1_ip_length, + ip_identification=input_1_ip_identification, + ip_flags=input_1_ip_flags, + ip_fragment_offset=input_1_ip_fragment_offset, + ip_ttl=input_1_ip_ttl, + ip_protocol=input_1_ip_protocol, + ip_header_checksum=input_1_ip_header_checksum, + ip_source_ip=input_1_ip_source_ip, + ip_dest_ip=input_1_ip_dest_ip, + udp_source_port=input_1_udp_source_port, + udp_dest_port=input_1_udp_dest_port, + udp_length=input_1_udp_length, + udp_checksum=input_1_udp_checksum, + udp_payload_tdata=input_1_udp_payload_tdata, + udp_payload_tkeep=input_1_udp_payload_tkeep, + udp_payload_tvalid=input_1_udp_payload_tvalid, + udp_payload_tready=input_1_udp_payload_tready, + udp_payload_tlast=input_1_udp_payload_tlast, + udp_payload_tuser=input_1_udp_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_2_udp_hdr_ready, + udp_hdr_valid=input_2_udp_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + ip_version=input_2_ip_version, + ip_ihl=input_2_ip_ihl, + ip_dscp=input_2_ip_dscp, + ip_ecn=input_2_ip_ecn, + ip_length=input_2_ip_length, + ip_identification=input_2_ip_identification, + ip_flags=input_2_ip_flags, + ip_fragment_offset=input_2_ip_fragment_offset, + ip_ttl=input_2_ip_ttl, + ip_protocol=input_2_ip_protocol, + ip_header_checksum=input_2_ip_header_checksum, + ip_source_ip=input_2_ip_source_ip, + ip_dest_ip=input_2_ip_dest_ip, + udp_source_port=input_2_udp_source_port, + udp_dest_port=input_2_udp_dest_port, + udp_length=input_2_udp_length, + udp_checksum=input_2_udp_checksum, + udp_payload_tdata=input_2_udp_payload_tdata, + udp_payload_tkeep=input_2_udp_payload_tkeep, + udp_payload_tvalid=input_2_udp_payload_tvalid, + udp_payload_tready=input_2_udp_payload_tready, + udp_payload_tlast=input_2_udp_payload_tlast, + udp_payload_tuser=input_2_udp_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_3_udp_hdr_ready, + udp_hdr_valid=input_3_udp_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + ip_version=input_3_ip_version, + ip_ihl=input_3_ip_ihl, + ip_dscp=input_3_ip_dscp, + ip_ecn=input_3_ip_ecn, + ip_length=input_3_ip_length, + ip_identification=input_3_ip_identification, + ip_flags=input_3_ip_flags, + ip_fragment_offset=input_3_ip_fragment_offset, + ip_ttl=input_3_ip_ttl, + ip_protocol=input_3_ip_protocol, + ip_header_checksum=input_3_ip_header_checksum, + ip_source_ip=input_3_ip_source_ip, + ip_dest_ip=input_3_ip_dest_ip, + udp_source_port=input_3_udp_source_port, + udp_dest_port=input_3_udp_dest_port, + udp_length=input_3_udp_length, + udp_checksum=input_3_udp_checksum, + udp_payload_tdata=input_3_udp_payload_tdata, + udp_payload_tkeep=input_3_udp_payload_tkeep, + udp_payload_tvalid=input_3_udp_payload_tvalid, + udp_payload_tready=input_3_udp_payload_tready, + udp_payload_tlast=input_3_udp_payload_tlast, + udp_payload_tuser=input_3_udp_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tkeep=output_udp_payload_tkeep, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_udp_mux_64_4(clk, + rst, + current_test, + + input_0_udp_hdr_valid, + input_0_udp_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tkeep, + input_0_udp_payload_tvalid, + input_0_udp_payload_tready, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_udp_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tkeep, + input_1_udp_payload_tvalid, + input_1_udp_payload_tready, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_udp_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tkeep, + input_2_udp_payload_tvalid, + input_2_udp_payload_tready, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_udp_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tkeep, + input_3_udp_payload_tvalid, + input_3_udp_payload_tready, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + enable, + select) + + @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 + enable.next = True + + yield clk.posedge + print("test 1: select port 0") + current_test.next = 1 + + select.next = 0 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + yield clk.posedge + select.next = 2 + 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: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + select.next = 2 + 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: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + select.next = 2 + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_mux_64_4.v b/tb/test_udp_mux_64_4.v new file mode 100644 index 000000000..4e781d363 --- /dev/null +++ b/tb/test_udp_mux_64_4.v @@ -0,0 +1,488 @@ +/* + +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_udp_mux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_udp_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [3:0] input_0_ip_version = 0; +reg [3:0] input_0_ip_ihl = 0; +reg [5:0] input_0_ip_dscp = 0; +reg [1:0] input_0_ip_ecn = 0; +reg [15:0] input_0_ip_length = 0; +reg [15:0] input_0_ip_identification = 0; +reg [2:0] input_0_ip_flags = 0; +reg [12:0] input_0_ip_fragment_offset = 0; +reg [7:0] input_0_ip_ttl = 0; +reg [7:0] input_0_ip_protocol = 0; +reg [15:0] input_0_ip_header_checksum = 0; +reg [31:0] input_0_ip_source_ip = 0; +reg [31:0] input_0_ip_dest_ip = 0; +reg [15:0] input_0_udp_source_port = 0; +reg [15:0] input_0_udp_dest_port = 0; +reg [15:0] input_0_udp_length = 0; +reg [15:0] input_0_udp_checksum = 0; +reg [63:0] input_0_udp_payload_tdata = 0; +reg [7:0] input_0_udp_payload_tkeep = 0; +reg input_0_udp_payload_tvalid = 0; +reg input_0_udp_payload_tlast = 0; +reg input_0_udp_payload_tuser = 0; +reg input_1_udp_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [3:0] input_1_ip_version = 0; +reg [3:0] input_1_ip_ihl = 0; +reg [5:0] input_1_ip_dscp = 0; +reg [1:0] input_1_ip_ecn = 0; +reg [15:0] input_1_ip_length = 0; +reg [15:0] input_1_ip_identification = 0; +reg [2:0] input_1_ip_flags = 0; +reg [12:0] input_1_ip_fragment_offset = 0; +reg [7:0] input_1_ip_ttl = 0; +reg [7:0] input_1_ip_protocol = 0; +reg [15:0] input_1_ip_header_checksum = 0; +reg [31:0] input_1_ip_source_ip = 0; +reg [31:0] input_1_ip_dest_ip = 0; +reg [15:0] input_1_udp_source_port = 0; +reg [15:0] input_1_udp_dest_port = 0; +reg [15:0] input_1_udp_length = 0; +reg [15:0] input_1_udp_checksum = 0; +reg [63:0] input_1_udp_payload_tdata = 0; +reg [7:0] input_1_udp_payload_tkeep = 0; +reg input_1_udp_payload_tvalid = 0; +reg input_1_udp_payload_tlast = 0; +reg input_1_udp_payload_tuser = 0; +reg input_2_udp_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [3:0] input_2_ip_version = 0; +reg [3:0] input_2_ip_ihl = 0; +reg [5:0] input_2_ip_dscp = 0; +reg [1:0] input_2_ip_ecn = 0; +reg [15:0] input_2_ip_length = 0; +reg [15:0] input_2_ip_identification = 0; +reg [2:0] input_2_ip_flags = 0; +reg [12:0] input_2_ip_fragment_offset = 0; +reg [7:0] input_2_ip_ttl = 0; +reg [7:0] input_2_ip_protocol = 0; +reg [15:0] input_2_ip_header_checksum = 0; +reg [31:0] input_2_ip_source_ip = 0; +reg [31:0] input_2_ip_dest_ip = 0; +reg [15:0] input_2_udp_source_port = 0; +reg [15:0] input_2_udp_dest_port = 0; +reg [15:0] input_2_udp_length = 0; +reg [15:0] input_2_udp_checksum = 0; +reg [63:0] input_2_udp_payload_tdata = 0; +reg [7:0] input_2_udp_payload_tkeep = 0; +reg input_2_udp_payload_tvalid = 0; +reg input_2_udp_payload_tlast = 0; +reg input_2_udp_payload_tuser = 0; +reg input_3_udp_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [3:0] input_3_ip_version = 0; +reg [3:0] input_3_ip_ihl = 0; +reg [5:0] input_3_ip_dscp = 0; +reg [1:0] input_3_ip_ecn = 0; +reg [15:0] input_3_ip_length = 0; +reg [15:0] input_3_ip_identification = 0; +reg [2:0] input_3_ip_flags = 0; +reg [12:0] input_3_ip_fragment_offset = 0; +reg [7:0] input_3_ip_ttl = 0; +reg [7:0] input_3_ip_protocol = 0; +reg [15:0] input_3_ip_header_checksum = 0; +reg [31:0] input_3_ip_source_ip = 0; +reg [31:0] input_3_ip_dest_ip = 0; +reg [15:0] input_3_udp_source_port = 0; +reg [15:0] input_3_udp_dest_port = 0; +reg [15:0] input_3_udp_length = 0; +reg [15:0] input_3_udp_checksum = 0; +reg [63:0] input_3_udp_payload_tdata = 0; +reg [7:0] input_3_udp_payload_tkeep = 0; +reg input_3_udp_payload_tvalid = 0; +reg input_3_udp_payload_tlast = 0; +reg input_3_udp_payload_tuser = 0; + +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; + +reg enable = 0; +reg [1:0] select = 0; + +// Outputs +wire input_0_udp_payload_tready; +wire input_0_udp_hdr_ready; +wire input_1_udp_payload_tready; +wire input_1_udp_hdr_ready; +wire input_2_udp_payload_tready; +wire input_2_udp_hdr_ready; +wire input_3_udp_payload_tready; +wire input_3_udp_hdr_ready; + +wire output_udp_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [63:0] output_udp_payload_tdata; +wire [7:0] output_udp_payload_tkeep; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_udp_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tkeep, + input_0_udp_payload_tvalid, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tkeep, + input_1_udp_payload_tvalid, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tkeep, + input_2_udp_payload_tvalid, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tkeep, + input_3_udp_payload_tvalid, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + output_udp_hdr_ready, + output_udp_payload_tready, + enable, + select); + $to_myhdl(input_0_udp_hdr_ready, + input_0_udp_payload_tready, + input_1_udp_hdr_ready, + input_1_udp_payload_tready, + input_2_udp_hdr_ready, + input_2_udp_payload_tready, + input_3_udp_hdr_ready, + input_3_udp_payload_tready, + output_udp_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser); + + // dump file + $dumpfile("test_udp_mux_64_4.lxt"); + $dumpvars(0, test_udp_mux_64_4); +end + +udp_mux_64_4 +UUT ( + .clk(clk), + .rst(rst), + // UDP frame inputs + .input_0_udp_hdr_valid(input_0_udp_hdr_valid), + .input_0_udp_hdr_ready(input_0_udp_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_udp_source_port(input_0_udp_source_port), + .input_0_udp_dest_port(input_0_udp_dest_port), + .input_0_udp_length(input_0_udp_length), + .input_0_udp_checksum(input_0_udp_checksum), + .input_0_udp_payload_tdata(input_0_udp_payload_tdata), + .input_0_udp_payload_tkeep(input_0_udp_payload_tkeep), + .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid), + .input_0_udp_payload_tready(input_0_udp_payload_tready), + .input_0_udp_payload_tlast(input_0_udp_payload_tlast), + .input_0_udp_payload_tuser(input_0_udp_payload_tuser), + .input_1_udp_hdr_valid(input_1_udp_hdr_valid), + .input_1_udp_hdr_ready(input_1_udp_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_udp_source_port(input_1_udp_source_port), + .input_1_udp_dest_port(input_1_udp_dest_port), + .input_1_udp_length(input_1_udp_length), + .input_1_udp_checksum(input_1_udp_checksum), + .input_1_udp_payload_tdata(input_1_udp_payload_tdata), + .input_1_udp_payload_tkeep(input_1_udp_payload_tkeep), + .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid), + .input_1_udp_payload_tready(input_1_udp_payload_tready), + .input_1_udp_payload_tlast(input_1_udp_payload_tlast), + .input_1_udp_payload_tuser(input_1_udp_payload_tuser), + .input_2_udp_hdr_valid(input_2_udp_hdr_valid), + .input_2_udp_hdr_ready(input_2_udp_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_udp_source_port(input_2_udp_source_port), + .input_2_udp_dest_port(input_2_udp_dest_port), + .input_2_udp_length(input_2_udp_length), + .input_2_udp_checksum(input_2_udp_checksum), + .input_2_udp_payload_tdata(input_2_udp_payload_tdata), + .input_2_udp_payload_tkeep(input_2_udp_payload_tkeep), + .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid), + .input_2_udp_payload_tready(input_2_udp_payload_tready), + .input_2_udp_payload_tlast(input_2_udp_payload_tlast), + .input_2_udp_payload_tuser(input_2_udp_payload_tuser), + .input_3_udp_hdr_valid(input_3_udp_hdr_valid), + .input_3_udp_hdr_ready(input_3_udp_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_udp_source_port(input_3_udp_source_port), + .input_3_udp_dest_port(input_3_udp_dest_port), + .input_3_udp_length(input_3_udp_length), + .input_3_udp_checksum(input_3_udp_checksum), + .input_3_udp_payload_tdata(input_3_udp_payload_tdata), + .input_3_udp_payload_tkeep(input_3_udp_payload_tkeep), + .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid), + .input_3_udp_payload_tready(input_3_udp_payload_tready), + .input_3_udp_payload_tlast(input_3_udp_payload_tlast), + .input_3_udp_payload_tuser(input_3_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule From 1b69fc5eed7140da47d58a4035bae75b58caa61b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 18 Nov 2014 14:53:31 -0800 Subject: [PATCH 112/617] Add UDP arbitrated mux and testbench --- rtl/udp_arb_mux.py | 284 ++++++++ rtl/udp_arb_mux_4.v | 366 ++++++++++ rtl/udp_arb_mux_64.py | 288 ++++++++ rtl/udp_arb_mux_64_4.v | 376 ++++++++++ tb/test_udp_arb_mux_4.py | 1339 ++++++++++++++++++++++++++++++++++ tb/test_udp_arb_mux_4.v | 465 ++++++++++++ tb/test_udp_arb_mux_64_4.py | 1364 +++++++++++++++++++++++++++++++++++ tb/test_udp_arb_mux_64_4.v | 480 ++++++++++++ 8 files changed, 4962 insertions(+) create mode 100755 rtl/udp_arb_mux.py create mode 100644 rtl/udp_arb_mux_4.v create mode 100755 rtl/udp_arb_mux_64.py create mode 100644 rtl/udp_arb_mux_64_4.v create mode 100755 tb/test_udp_arb_mux_4.py create mode 100644 tb/test_udp_arb_mux_4.v create mode 100755 tb/test_udp_arb_mux_64_4.py create mode 100644 tb/test_udp_arb_mux_64_4.v diff --git a/rtl/udp_arb_mux.py b/rtl/udp_arb_mux.py new file mode 100755 index 000000000..0a8f53c7c --- /dev/null +++ b/rtl/udp_arb_mux.py @@ -0,0 +1,284 @@ +#!/usr/bin/env python +"""udp_arb_mux + +Generates an arbitrated UDP mux with the specified number of ports + +Usage: udp_arb_mux [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "udp_arb_mux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * UDP {{n}} port arbitrated multiplexer + */ +module {{name}} # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * UDP frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_udp_hdr_valid, + output wire input_{{p}}_udp_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [3:0] input_{{p}}_ip_version, + input wire [3:0] input_{{p}}_ip_ihl, + input wire [5:0] input_{{p}}_ip_dscp, + input wire [1:0] input_{{p}}_ip_ecn, + input wire [15:0] input_{{p}}_ip_length, + input wire [15:0] input_{{p}}_ip_identification, + input wire [2:0] input_{{p}}_ip_flags, + input wire [12:0] input_{{p}}_ip_fragment_offset, + input wire [7:0] input_{{p}}_ip_ttl, + input wire [7:0] input_{{p}}_ip_protocol, + input wire [15:0] input_{{p}}_ip_header_checksum, + input wire [31:0] input_{{p}}_ip_source_ip, + input wire [31:0] input_{{p}}_ip_dest_ip, + input wire [15:0] input_{{p}}_udp_source_port, + input wire [15:0] input_{{p}}_udp_dest_port, + input wire [15:0] input_{{p}}_udp_length, + input wire [15:0] input_{{p}}_udp_checksum, + input wire [7:0] input_{{p}}_udp_payload_tdata, + input wire input_{{p}}_udp_payload_tvalid, + output wire input_{{p}}_udp_payload_tready, + input wire input_{{p}}_udp_payload_tlast, + input wire input_{{p}}_udp_payload_tuser, +{% endfor %} + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [7:0] output_udp_payload_tdata, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser +); + +wire [{{n-1}}:0] request; +wire [{{n-1}}:0] acknowledge; +wire [{{n-1}}:0] grant; +wire grant_valid; +wire [{{w-1}}:0] grant_encoded; +{% for p in ports %} +assign acknowledge[{{p}}] = input_{{p}}_udp_payload_tvalid & input_{{p}}_udp_payload_tready & input_{{p}}_udp_payload_tlast; +assign request[{{p}}] = input_{{p}}_udp_hdr_valid; +{%- endfor %} + +// mux instance +udp_mux_{{n}} +mux_inst ( + .clk(clk), + .rst(rst), +{%- for p in ports %} + .input_{{p}}_udp_hdr_valid(input_{{p}}_udp_hdr_valid & grant[{{p}}]), + .input_{{p}}_udp_hdr_ready(input_{{p}}_udp_hdr_ready), + .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), + .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), + .input_{{p}}_eth_type(input_{{p}}_eth_type), + .input_{{p}}_ip_version(input_{{p}}_ip_version), + .input_{{p}}_ip_ihl(input_{{p}}_ip_ihl), + .input_{{p}}_ip_dscp(input_{{p}}_ip_dscp), + .input_{{p}}_ip_ecn(input_{{p}}_ip_ecn), + .input_{{p}}_ip_length(input_{{p}}_ip_length), + .input_{{p}}_ip_identification(input_{{p}}_ip_identification), + .input_{{p}}_ip_flags(input_{{p}}_ip_flags), + .input_{{p}}_ip_fragment_offset(input_{{p}}_ip_fragment_offset), + .input_{{p}}_ip_ttl(input_{{p}}_ip_ttl), + .input_{{p}}_ip_protocol(input_{{p}}_ip_protocol), + .input_{{p}}_ip_header_checksum(input_{{p}}_ip_header_checksum), + .input_{{p}}_ip_source_ip(input_{{p}}_ip_source_ip), + .input_{{p}}_ip_dest_ip(input_{{p}}_ip_dest_ip), + .input_{{p}}_udp_source_port(input_{{p}}_udp_source_port), + .input_{{p}}_udp_dest_port(input_{{p}}_udp_dest_port), + .input_{{p}}_udp_length(input_{{p}}_udp_length), + .input_{{p}}_udp_checksum(input_{{p}}_udp_checksum), + .input_{{p}}_udp_payload_tdata(input_{{p}}_udp_payload_tdata), + .input_{{p}}_udp_payload_tvalid(input_{{p}}_udp_payload_tvalid & grant[{{p}}]), + .input_{{p}}_udp_payload_tready(input_{{p}}_udp_payload_tready), + .input_{{p}}_udp_payload_tlast(input_{{p}}_udp_payload_tlast), + .input_{{p}}_udp_payload_tuser(input_{{p}}_udp_payload_tuser), +{%- endfor %} + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS({{n}}), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/udp_arb_mux_4.v b/rtl/udp_arb_mux_4.v new file mode 100644 index 000000000..9d926e99f --- /dev/null +++ b/rtl/udp_arb_mux_4.v @@ -0,0 +1,366 @@ +/* + +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 + +/* + * UDP 4 port arbitrated multiplexer + */ +module udp_arb_mux_4 # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * UDP frame inputs + */ + input wire input_0_udp_hdr_valid, + output wire input_0_udp_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [15:0] input_0_udp_source_port, + input wire [15:0] input_0_udp_dest_port, + input wire [15:0] input_0_udp_length, + input wire [15:0] input_0_udp_checksum, + input wire [7:0] input_0_udp_payload_tdata, + input wire input_0_udp_payload_tvalid, + output wire input_0_udp_payload_tready, + input wire input_0_udp_payload_tlast, + input wire input_0_udp_payload_tuser, + + input wire input_1_udp_hdr_valid, + output wire input_1_udp_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [15:0] input_1_udp_source_port, + input wire [15:0] input_1_udp_dest_port, + input wire [15:0] input_1_udp_length, + input wire [15:0] input_1_udp_checksum, + input wire [7:0] input_1_udp_payload_tdata, + input wire input_1_udp_payload_tvalid, + output wire input_1_udp_payload_tready, + input wire input_1_udp_payload_tlast, + input wire input_1_udp_payload_tuser, + + input wire input_2_udp_hdr_valid, + output wire input_2_udp_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [3:0] input_2_ip_version, + input wire [3:0] input_2_ip_ihl, + input wire [5:0] input_2_ip_dscp, + input wire [1:0] input_2_ip_ecn, + input wire [15:0] input_2_ip_length, + input wire [15:0] input_2_ip_identification, + input wire [2:0] input_2_ip_flags, + input wire [12:0] input_2_ip_fragment_offset, + input wire [7:0] input_2_ip_ttl, + input wire [7:0] input_2_ip_protocol, + input wire [15:0] input_2_ip_header_checksum, + input wire [31:0] input_2_ip_source_ip, + input wire [31:0] input_2_ip_dest_ip, + input wire [15:0] input_2_udp_source_port, + input wire [15:0] input_2_udp_dest_port, + input wire [15:0] input_2_udp_length, + input wire [15:0] input_2_udp_checksum, + input wire [7:0] input_2_udp_payload_tdata, + input wire input_2_udp_payload_tvalid, + output wire input_2_udp_payload_tready, + input wire input_2_udp_payload_tlast, + input wire input_2_udp_payload_tuser, + + input wire input_3_udp_hdr_valid, + output wire input_3_udp_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [3:0] input_3_ip_version, + input wire [3:0] input_3_ip_ihl, + input wire [5:0] input_3_ip_dscp, + input wire [1:0] input_3_ip_ecn, + input wire [15:0] input_3_ip_length, + input wire [15:0] input_3_ip_identification, + input wire [2:0] input_3_ip_flags, + input wire [12:0] input_3_ip_fragment_offset, + input wire [7:0] input_3_ip_ttl, + input wire [7:0] input_3_ip_protocol, + input wire [15:0] input_3_ip_header_checksum, + input wire [31:0] input_3_ip_source_ip, + input wire [31:0] input_3_ip_dest_ip, + input wire [15:0] input_3_udp_source_port, + input wire [15:0] input_3_udp_dest_port, + input wire [15:0] input_3_udp_length, + input wire [15:0] input_3_udp_checksum, + input wire [7:0] input_3_udp_payload_tdata, + input wire input_3_udp_payload_tvalid, + output wire input_3_udp_payload_tready, + input wire input_3_udp_payload_tlast, + input wire input_3_udp_payload_tuser, + + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [7:0] output_udp_payload_tdata, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser +); + +wire [3:0] request; +wire [3:0] acknowledge; +wire [3:0] grant; +wire grant_valid; +wire [1:0] grant_encoded; + +assign acknowledge[0] = input_0_udp_payload_tvalid & input_0_udp_payload_tready & input_0_udp_payload_tlast; +assign request[0] = input_0_udp_hdr_valid; +assign acknowledge[1] = input_1_udp_payload_tvalid & input_1_udp_payload_tready & input_1_udp_payload_tlast; +assign request[1] = input_1_udp_hdr_valid; +assign acknowledge[2] = input_2_udp_payload_tvalid & input_2_udp_payload_tready & input_2_udp_payload_tlast; +assign request[2] = input_2_udp_hdr_valid; +assign acknowledge[3] = input_3_udp_payload_tvalid & input_3_udp_payload_tready & input_3_udp_payload_tlast; +assign request[3] = input_3_udp_hdr_valid; + +// mux instance +udp_mux_4 +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_udp_hdr_valid(input_0_udp_hdr_valid & grant[0]), + .input_0_udp_hdr_ready(input_0_udp_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_udp_source_port(input_0_udp_source_port), + .input_0_udp_dest_port(input_0_udp_dest_port), + .input_0_udp_length(input_0_udp_length), + .input_0_udp_checksum(input_0_udp_checksum), + .input_0_udp_payload_tdata(input_0_udp_payload_tdata), + .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid & grant[0]), + .input_0_udp_payload_tready(input_0_udp_payload_tready), + .input_0_udp_payload_tlast(input_0_udp_payload_tlast), + .input_0_udp_payload_tuser(input_0_udp_payload_tuser), + .input_1_udp_hdr_valid(input_1_udp_hdr_valid & grant[1]), + .input_1_udp_hdr_ready(input_1_udp_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_udp_source_port(input_1_udp_source_port), + .input_1_udp_dest_port(input_1_udp_dest_port), + .input_1_udp_length(input_1_udp_length), + .input_1_udp_checksum(input_1_udp_checksum), + .input_1_udp_payload_tdata(input_1_udp_payload_tdata), + .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid & grant[1]), + .input_1_udp_payload_tready(input_1_udp_payload_tready), + .input_1_udp_payload_tlast(input_1_udp_payload_tlast), + .input_1_udp_payload_tuser(input_1_udp_payload_tuser), + .input_2_udp_hdr_valid(input_2_udp_hdr_valid & grant[2]), + .input_2_udp_hdr_ready(input_2_udp_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_udp_source_port(input_2_udp_source_port), + .input_2_udp_dest_port(input_2_udp_dest_port), + .input_2_udp_length(input_2_udp_length), + .input_2_udp_checksum(input_2_udp_checksum), + .input_2_udp_payload_tdata(input_2_udp_payload_tdata), + .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid & grant[2]), + .input_2_udp_payload_tready(input_2_udp_payload_tready), + .input_2_udp_payload_tlast(input_2_udp_payload_tlast), + .input_2_udp_payload_tuser(input_2_udp_payload_tuser), + .input_3_udp_hdr_valid(input_3_udp_hdr_valid & grant[3]), + .input_3_udp_hdr_ready(input_3_udp_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_udp_source_port(input_3_udp_source_port), + .input_3_udp_dest_port(input_3_udp_dest_port), + .input_3_udp_length(input_3_udp_length), + .input_3_udp_checksum(input_3_udp_checksum), + .input_3_udp_payload_tdata(input_3_udp_payload_tdata), + .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid & grant[3]), + .input_3_udp_payload_tready(input_3_udp_payload_tready), + .input_3_udp_payload_tlast(input_3_udp_payload_tlast), + .input_3_udp_payload_tuser(input_3_udp_payload_tuser), + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/rtl/udp_arb_mux_64.py b/rtl/udp_arb_mux_64.py new file mode 100755 index 000000000..8151998ab --- /dev/null +++ b/rtl/udp_arb_mux_64.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python +"""udp_arb_mux_64 + +Generates an arbitrated UDP mux with the specified number of ports + +Usage: udp_arb_mux_64 [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "udp_arb_mux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * UDP {{n}} port arbitrated multiplexer (64 bit datapath) + */ +module {{name}} # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * UDP frame inputs + */ +{%- for p in ports %} + input wire input_{{p}}_udp_hdr_valid, + output wire input_{{p}}_udp_hdr_ready, + input wire [47:0] input_{{p}}_eth_dest_mac, + input wire [47:0] input_{{p}}_eth_src_mac, + input wire [15:0] input_{{p}}_eth_type, + input wire [3:0] input_{{p}}_ip_version, + input wire [3:0] input_{{p}}_ip_ihl, + input wire [5:0] input_{{p}}_ip_dscp, + input wire [1:0] input_{{p}}_ip_ecn, + input wire [15:0] input_{{p}}_ip_length, + input wire [15:0] input_{{p}}_ip_identification, + input wire [2:0] input_{{p}}_ip_flags, + input wire [12:0] input_{{p}}_ip_fragment_offset, + input wire [7:0] input_{{p}}_ip_ttl, + input wire [7:0] input_{{p}}_ip_protocol, + input wire [15:0] input_{{p}}_ip_header_checksum, + input wire [31:0] input_{{p}}_ip_source_ip, + input wire [31:0] input_{{p}}_ip_dest_ip, + input wire [15:0] input_{{p}}_udp_source_port, + input wire [15:0] input_{{p}}_udp_dest_port, + input wire [15:0] input_{{p}}_udp_length, + input wire [15:0] input_{{p}}_udp_checksum, + input wire [63:0] input_{{p}}_udp_payload_tdata, + input wire [7:0] input_{{p}}_udp_payload_tkeep, + input wire input_{{p}}_udp_payload_tvalid, + output wire input_{{p}}_udp_payload_tready, + input wire input_{{p}}_udp_payload_tlast, + input wire input_{{p}}_udp_payload_tuser, +{% endfor %} + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [63:0] output_udp_payload_tdata, + output wire [7:0] output_udp_payload_tkeep, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser +); + +wire [{{n-1}}:0] request; +wire [{{n-1}}:0] acknowledge; +wire [{{n-1}}:0] grant; +wire grant_valid; +wire [{{w-1}}:0] grant_encoded; +{% for p in ports %} +assign acknowledge[{{p}}] = input_{{p}}_udp_payload_tvalid & input_{{p}}_udp_payload_tready & input_{{p}}_udp_payload_tlast; +assign request[{{p}}] = input_{{p}}_udp_hdr_valid; +{%- endfor %} + +// mux instance +udp_mux_64_{{n}} +mux_inst ( + .clk(clk), + .rst(rst), +{%- for p in ports %} + .input_{{p}}_udp_hdr_valid(input_{{p}}_udp_hdr_valid & grant[{{p}}]), + .input_{{p}}_udp_hdr_ready(input_{{p}}_udp_hdr_ready), + .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), + .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), + .input_{{p}}_eth_type(input_{{p}}_eth_type), + .input_{{p}}_ip_version(input_{{p}}_ip_version), + .input_{{p}}_ip_ihl(input_{{p}}_ip_ihl), + .input_{{p}}_ip_dscp(input_{{p}}_ip_dscp), + .input_{{p}}_ip_ecn(input_{{p}}_ip_ecn), + .input_{{p}}_ip_length(input_{{p}}_ip_length), + .input_{{p}}_ip_identification(input_{{p}}_ip_identification), + .input_{{p}}_ip_flags(input_{{p}}_ip_flags), + .input_{{p}}_ip_fragment_offset(input_{{p}}_ip_fragment_offset), + .input_{{p}}_ip_ttl(input_{{p}}_ip_ttl), + .input_{{p}}_ip_protocol(input_{{p}}_ip_protocol), + .input_{{p}}_ip_header_checksum(input_{{p}}_ip_header_checksum), + .input_{{p}}_ip_source_ip(input_{{p}}_ip_source_ip), + .input_{{p}}_ip_dest_ip(input_{{p}}_ip_dest_ip), + .input_{{p}}_udp_source_port(input_{{p}}_udp_source_port), + .input_{{p}}_udp_dest_port(input_{{p}}_udp_dest_port), + .input_{{p}}_udp_length(input_{{p}}_udp_length), + .input_{{p}}_udp_checksum(input_{{p}}_udp_checksum), + .input_{{p}}_udp_payload_tdata(input_{{p}}_udp_payload_tdata), + .input_{{p}}_udp_payload_tkeep(input_{{p}}_udp_payload_tkeep), + .input_{{p}}_udp_payload_tvalid(input_{{p}}_udp_payload_tvalid & grant[{{p}}]), + .input_{{p}}_udp_payload_tready(input_{{p}}_udp_payload_tready), + .input_{{p}}_udp_payload_tlast(input_{{p}}_udp_payload_tlast), + .input_{{p}}_udp_payload_tuser(input_{{p}}_udp_payload_tuser), +{%- endfor %} + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS({{n}}), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/udp_arb_mux_64_4.v b/rtl/udp_arb_mux_64_4.v new file mode 100644 index 000000000..60bb9c5be --- /dev/null +++ b/rtl/udp_arb_mux_64_4.v @@ -0,0 +1,376 @@ +/* + +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 + +/* + * UDP 4 port arbitrated multiplexer (64 bit datapath) + */ +module udp_arb_mux_64_4 # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * UDP frame inputs + */ + input wire input_0_udp_hdr_valid, + output wire input_0_udp_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [15:0] input_0_udp_source_port, + input wire [15:0] input_0_udp_dest_port, + input wire [15:0] input_0_udp_length, + input wire [15:0] input_0_udp_checksum, + input wire [63:0] input_0_udp_payload_tdata, + input wire [7:0] input_0_udp_payload_tkeep, + input wire input_0_udp_payload_tvalid, + output wire input_0_udp_payload_tready, + input wire input_0_udp_payload_tlast, + input wire input_0_udp_payload_tuser, + + input wire input_1_udp_hdr_valid, + output wire input_1_udp_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [15:0] input_1_udp_source_port, + input wire [15:0] input_1_udp_dest_port, + input wire [15:0] input_1_udp_length, + input wire [15:0] input_1_udp_checksum, + input wire [63:0] input_1_udp_payload_tdata, + input wire [7:0] input_1_udp_payload_tkeep, + input wire input_1_udp_payload_tvalid, + output wire input_1_udp_payload_tready, + input wire input_1_udp_payload_tlast, + input wire input_1_udp_payload_tuser, + + input wire input_2_udp_hdr_valid, + output wire input_2_udp_hdr_ready, + input wire [47:0] input_2_eth_dest_mac, + input wire [47:0] input_2_eth_src_mac, + input wire [15:0] input_2_eth_type, + input wire [3:0] input_2_ip_version, + input wire [3:0] input_2_ip_ihl, + input wire [5:0] input_2_ip_dscp, + input wire [1:0] input_2_ip_ecn, + input wire [15:0] input_2_ip_length, + input wire [15:0] input_2_ip_identification, + input wire [2:0] input_2_ip_flags, + input wire [12:0] input_2_ip_fragment_offset, + input wire [7:0] input_2_ip_ttl, + input wire [7:0] input_2_ip_protocol, + input wire [15:0] input_2_ip_header_checksum, + input wire [31:0] input_2_ip_source_ip, + input wire [31:0] input_2_ip_dest_ip, + input wire [15:0] input_2_udp_source_port, + input wire [15:0] input_2_udp_dest_port, + input wire [15:0] input_2_udp_length, + input wire [15:0] input_2_udp_checksum, + input wire [63:0] input_2_udp_payload_tdata, + input wire [7:0] input_2_udp_payload_tkeep, + input wire input_2_udp_payload_tvalid, + output wire input_2_udp_payload_tready, + input wire input_2_udp_payload_tlast, + input wire input_2_udp_payload_tuser, + + input wire input_3_udp_hdr_valid, + output wire input_3_udp_hdr_ready, + input wire [47:0] input_3_eth_dest_mac, + input wire [47:0] input_3_eth_src_mac, + input wire [15:0] input_3_eth_type, + input wire [3:0] input_3_ip_version, + input wire [3:0] input_3_ip_ihl, + input wire [5:0] input_3_ip_dscp, + input wire [1:0] input_3_ip_ecn, + input wire [15:0] input_3_ip_length, + input wire [15:0] input_3_ip_identification, + input wire [2:0] input_3_ip_flags, + input wire [12:0] input_3_ip_fragment_offset, + input wire [7:0] input_3_ip_ttl, + input wire [7:0] input_3_ip_protocol, + input wire [15:0] input_3_ip_header_checksum, + input wire [31:0] input_3_ip_source_ip, + input wire [31:0] input_3_ip_dest_ip, + input wire [15:0] input_3_udp_source_port, + input wire [15:0] input_3_udp_dest_port, + input wire [15:0] input_3_udp_length, + input wire [15:0] input_3_udp_checksum, + input wire [63:0] input_3_udp_payload_tdata, + input wire [7:0] input_3_udp_payload_tkeep, + input wire input_3_udp_payload_tvalid, + output wire input_3_udp_payload_tready, + input wire input_3_udp_payload_tlast, + input wire input_3_udp_payload_tuser, + + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [63:0] output_udp_payload_tdata, + output wire [7:0] output_udp_payload_tkeep, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser +); + +wire [3:0] request; +wire [3:0] acknowledge; +wire [3:0] grant; +wire grant_valid; +wire [1:0] grant_encoded; + +assign acknowledge[0] = input_0_udp_payload_tvalid & input_0_udp_payload_tready & input_0_udp_payload_tlast; +assign request[0] = input_0_udp_hdr_valid; +assign acknowledge[1] = input_1_udp_payload_tvalid & input_1_udp_payload_tready & input_1_udp_payload_tlast; +assign request[1] = input_1_udp_hdr_valid; +assign acknowledge[2] = input_2_udp_payload_tvalid & input_2_udp_payload_tready & input_2_udp_payload_tlast; +assign request[2] = input_2_udp_hdr_valid; +assign acknowledge[3] = input_3_udp_payload_tvalid & input_3_udp_payload_tready & input_3_udp_payload_tlast; +assign request[3] = input_3_udp_hdr_valid; + +// mux instance +udp_mux_64_4 +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_udp_hdr_valid(input_0_udp_hdr_valid & grant[0]), + .input_0_udp_hdr_ready(input_0_udp_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_udp_source_port(input_0_udp_source_port), + .input_0_udp_dest_port(input_0_udp_dest_port), + .input_0_udp_length(input_0_udp_length), + .input_0_udp_checksum(input_0_udp_checksum), + .input_0_udp_payload_tdata(input_0_udp_payload_tdata), + .input_0_udp_payload_tkeep(input_0_udp_payload_tkeep), + .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid & grant[0]), + .input_0_udp_payload_tready(input_0_udp_payload_tready), + .input_0_udp_payload_tlast(input_0_udp_payload_tlast), + .input_0_udp_payload_tuser(input_0_udp_payload_tuser), + .input_1_udp_hdr_valid(input_1_udp_hdr_valid & grant[1]), + .input_1_udp_hdr_ready(input_1_udp_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_udp_source_port(input_1_udp_source_port), + .input_1_udp_dest_port(input_1_udp_dest_port), + .input_1_udp_length(input_1_udp_length), + .input_1_udp_checksum(input_1_udp_checksum), + .input_1_udp_payload_tdata(input_1_udp_payload_tdata), + .input_1_udp_payload_tkeep(input_1_udp_payload_tkeep), + .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid & grant[1]), + .input_1_udp_payload_tready(input_1_udp_payload_tready), + .input_1_udp_payload_tlast(input_1_udp_payload_tlast), + .input_1_udp_payload_tuser(input_1_udp_payload_tuser), + .input_2_udp_hdr_valid(input_2_udp_hdr_valid & grant[2]), + .input_2_udp_hdr_ready(input_2_udp_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_udp_source_port(input_2_udp_source_port), + .input_2_udp_dest_port(input_2_udp_dest_port), + .input_2_udp_length(input_2_udp_length), + .input_2_udp_checksum(input_2_udp_checksum), + .input_2_udp_payload_tdata(input_2_udp_payload_tdata), + .input_2_udp_payload_tkeep(input_2_udp_payload_tkeep), + .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid & grant[2]), + .input_2_udp_payload_tready(input_2_udp_payload_tready), + .input_2_udp_payload_tlast(input_2_udp_payload_tlast), + .input_2_udp_payload_tuser(input_2_udp_payload_tuser), + .input_3_udp_hdr_valid(input_3_udp_hdr_valid & grant[3]), + .input_3_udp_hdr_ready(input_3_udp_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_udp_source_port(input_3_udp_source_port), + .input_3_udp_dest_port(input_3_udp_dest_port), + .input_3_udp_length(input_3_udp_length), + .input_3_udp_checksum(input_3_udp_checksum), + .input_3_udp_payload_tdata(input_3_udp_payload_tdata), + .input_3_udp_payload_tkeep(input_3_udp_payload_tkeep), + .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid & grant[3]), + .input_3_udp_payload_tready(input_3_udp_payload_tready), + .input_3_udp_payload_tlast(input_3_udp_payload_tlast), + .input_3_udp_payload_tuser(input_3_udp_payload_tuser), + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/tb/test_udp_arb_mux_4.py b/tb/test_udp_arb_mux_4.py new file mode 100755 index 000000000..e16978825 --- /dev/null +++ b/tb/test_udp_arb_mux_4.py @@ -0,0 +1,1339 @@ +#!/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 udp_ep + +module = 'udp_arb_mux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/udp_mux_4.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp_arb_mux_4(clk, + rst, + current_test, + + input_0_udp_hdr_valid, + input_0_udp_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tvalid, + input_0_udp_payload_tready, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_udp_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tvalid, + input_1_udp_payload_tready, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_udp_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tvalid, + input_2_udp_payload_tready, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_udp_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tvalid, + input_3_udp_payload_tready, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_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_0_udp_hdr_valid=input_0_udp_hdr_valid, + input_0_udp_hdr_ready=input_0_udp_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_ip_version=input_0_ip_version, + input_0_ip_ihl=input_0_ip_ihl, + input_0_ip_dscp=input_0_ip_dscp, + input_0_ip_ecn=input_0_ip_ecn, + input_0_ip_length=input_0_ip_length, + input_0_ip_identification=input_0_ip_identification, + input_0_ip_flags=input_0_ip_flags, + input_0_ip_fragment_offset=input_0_ip_fragment_offset, + input_0_ip_ttl=input_0_ip_ttl, + input_0_ip_protocol=input_0_ip_protocol, + input_0_ip_header_checksum=input_0_ip_header_checksum, + input_0_ip_source_ip=input_0_ip_source_ip, + input_0_ip_dest_ip=input_0_ip_dest_ip, + input_0_udp_source_port=input_0_udp_source_port, + input_0_udp_dest_port=input_0_udp_dest_port, + input_0_udp_length=input_0_udp_length, + input_0_udp_checksum=input_0_udp_checksum, + input_0_udp_payload_tdata=input_0_udp_payload_tdata, + input_0_udp_payload_tvalid=input_0_udp_payload_tvalid, + input_0_udp_payload_tready=input_0_udp_payload_tready, + input_0_udp_payload_tlast=input_0_udp_payload_tlast, + input_0_udp_payload_tuser=input_0_udp_payload_tuser, + input_1_udp_hdr_valid=input_1_udp_hdr_valid, + input_1_udp_hdr_ready=input_1_udp_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_ip_version=input_1_ip_version, + input_1_ip_ihl=input_1_ip_ihl, + input_1_ip_dscp=input_1_ip_dscp, + input_1_ip_ecn=input_1_ip_ecn, + input_1_ip_length=input_1_ip_length, + input_1_ip_identification=input_1_ip_identification, + input_1_ip_flags=input_1_ip_flags, + input_1_ip_fragment_offset=input_1_ip_fragment_offset, + input_1_ip_ttl=input_1_ip_ttl, + input_1_ip_protocol=input_1_ip_protocol, + input_1_ip_header_checksum=input_1_ip_header_checksum, + input_1_ip_source_ip=input_1_ip_source_ip, + input_1_ip_dest_ip=input_1_ip_dest_ip, + input_1_udp_source_port=input_1_udp_source_port, + input_1_udp_dest_port=input_1_udp_dest_port, + input_1_udp_length=input_1_udp_length, + input_1_udp_checksum=input_1_udp_checksum, + input_1_udp_payload_tdata=input_1_udp_payload_tdata, + input_1_udp_payload_tvalid=input_1_udp_payload_tvalid, + input_1_udp_payload_tready=input_1_udp_payload_tready, + input_1_udp_payload_tlast=input_1_udp_payload_tlast, + input_1_udp_payload_tuser=input_1_udp_payload_tuser, + input_2_udp_hdr_valid=input_2_udp_hdr_valid, + input_2_udp_hdr_ready=input_2_udp_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_ip_version=input_2_ip_version, + input_2_ip_ihl=input_2_ip_ihl, + input_2_ip_dscp=input_2_ip_dscp, + input_2_ip_ecn=input_2_ip_ecn, + input_2_ip_length=input_2_ip_length, + input_2_ip_identification=input_2_ip_identification, + input_2_ip_flags=input_2_ip_flags, + input_2_ip_fragment_offset=input_2_ip_fragment_offset, + input_2_ip_ttl=input_2_ip_ttl, + input_2_ip_protocol=input_2_ip_protocol, + input_2_ip_header_checksum=input_2_ip_header_checksum, + input_2_ip_source_ip=input_2_ip_source_ip, + input_2_ip_dest_ip=input_2_ip_dest_ip, + input_2_udp_source_port=input_2_udp_source_port, + input_2_udp_dest_port=input_2_udp_dest_port, + input_2_udp_length=input_2_udp_length, + input_2_udp_checksum=input_2_udp_checksum, + input_2_udp_payload_tdata=input_2_udp_payload_tdata, + input_2_udp_payload_tvalid=input_2_udp_payload_tvalid, + input_2_udp_payload_tready=input_2_udp_payload_tready, + input_2_udp_payload_tlast=input_2_udp_payload_tlast, + input_2_udp_payload_tuser=input_2_udp_payload_tuser, + input_3_udp_hdr_valid=input_3_udp_hdr_valid, + input_3_udp_hdr_ready=input_3_udp_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_ip_version=input_3_ip_version, + input_3_ip_ihl=input_3_ip_ihl, + input_3_ip_dscp=input_3_ip_dscp, + input_3_ip_ecn=input_3_ip_ecn, + input_3_ip_length=input_3_ip_length, + input_3_ip_identification=input_3_ip_identification, + input_3_ip_flags=input_3_ip_flags, + input_3_ip_fragment_offset=input_3_ip_fragment_offset, + input_3_ip_ttl=input_3_ip_ttl, + input_3_ip_protocol=input_3_ip_protocol, + input_3_ip_header_checksum=input_3_ip_header_checksum, + input_3_ip_source_ip=input_3_ip_source_ip, + input_3_ip_dest_ip=input_3_ip_dest_ip, + input_3_udp_source_port=input_3_udp_source_port, + input_3_udp_dest_port=input_3_udp_dest_port, + input_3_udp_length=input_3_udp_length, + input_3_udp_checksum=input_3_udp_checksum, + input_3_udp_payload_tdata=input_3_udp_payload_tdata, + input_3_udp_payload_tvalid=input_3_udp_payload_tvalid, + input_3_udp_payload_tready=input_3_udp_payload_tready, + input_3_udp_payload_tlast=input_3_udp_payload_tlast, + input_3_udp_payload_tuser=input_3_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_udp_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_ip_version = Signal(intbv(0)[4:]) + input_0_ip_ihl = Signal(intbv(0)[4:]) + input_0_ip_dscp = Signal(intbv(0)[6:]) + input_0_ip_ecn = Signal(intbv(0)[2:]) + input_0_ip_length = Signal(intbv(0)[16:]) + input_0_ip_identification = Signal(intbv(0)[16:]) + input_0_ip_flags = Signal(intbv(0)[3:]) + input_0_ip_fragment_offset = Signal(intbv(0)[13:]) + input_0_ip_ttl = Signal(intbv(0)[8:]) + input_0_ip_protocol = Signal(intbv(0)[8:]) + input_0_ip_header_checksum = Signal(intbv(0)[16:]) + input_0_ip_source_ip = Signal(intbv(0)[32:]) + input_0_ip_dest_ip = Signal(intbv(0)[32:]) + input_0_udp_source_port = Signal(intbv(0)[16:]) + input_0_udp_dest_port = Signal(intbv(0)[16:]) + input_0_udp_length = Signal(intbv(0)[16:]) + input_0_udp_checksum = Signal(intbv(0)[16:]) + input_0_udp_payload_tdata = Signal(intbv(0)[8:]) + input_0_udp_payload_tvalid = Signal(bool(0)) + input_0_udp_payload_tlast = Signal(bool(0)) + input_0_udp_payload_tuser = Signal(bool(0)) + input_1_udp_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_ip_version = Signal(intbv(0)[4:]) + input_1_ip_ihl = Signal(intbv(0)[4:]) + input_1_ip_dscp = Signal(intbv(0)[6:]) + input_1_ip_ecn = Signal(intbv(0)[2:]) + input_1_ip_length = Signal(intbv(0)[16:]) + input_1_ip_identification = Signal(intbv(0)[16:]) + input_1_ip_flags = Signal(intbv(0)[3:]) + input_1_ip_fragment_offset = Signal(intbv(0)[13:]) + input_1_ip_ttl = Signal(intbv(0)[8:]) + input_1_ip_protocol = Signal(intbv(0)[8:]) + input_1_ip_header_checksum = Signal(intbv(0)[16:]) + input_1_ip_source_ip = Signal(intbv(0)[32:]) + input_1_ip_dest_ip = Signal(intbv(0)[32:]) + input_1_udp_source_port = Signal(intbv(0)[16:]) + input_1_udp_dest_port = Signal(intbv(0)[16:]) + input_1_udp_length = Signal(intbv(0)[16:]) + input_1_udp_checksum = Signal(intbv(0)[16:]) + input_1_udp_payload_tdata = Signal(intbv(0)[8:]) + input_1_udp_payload_tvalid = Signal(bool(0)) + input_1_udp_payload_tlast = Signal(bool(0)) + input_1_udp_payload_tuser = Signal(bool(0)) + input_2_udp_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_ip_version = Signal(intbv(0)[4:]) + input_2_ip_ihl = Signal(intbv(0)[4:]) + input_2_ip_dscp = Signal(intbv(0)[6:]) + input_2_ip_ecn = Signal(intbv(0)[2:]) + input_2_ip_length = Signal(intbv(0)[16:]) + input_2_ip_identification = Signal(intbv(0)[16:]) + input_2_ip_flags = Signal(intbv(0)[3:]) + input_2_ip_fragment_offset = Signal(intbv(0)[13:]) + input_2_ip_ttl = Signal(intbv(0)[8:]) + input_2_ip_protocol = Signal(intbv(0)[8:]) + input_2_ip_header_checksum = Signal(intbv(0)[16:]) + input_2_ip_source_ip = Signal(intbv(0)[32:]) + input_2_ip_dest_ip = Signal(intbv(0)[32:]) + input_2_udp_source_port = Signal(intbv(0)[16:]) + input_2_udp_dest_port = Signal(intbv(0)[16:]) + input_2_udp_length = Signal(intbv(0)[16:]) + input_2_udp_checksum = Signal(intbv(0)[16:]) + input_2_udp_payload_tdata = Signal(intbv(0)[8:]) + input_2_udp_payload_tvalid = Signal(bool(0)) + input_2_udp_payload_tlast = Signal(bool(0)) + input_2_udp_payload_tuser = Signal(bool(0)) + input_3_udp_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_ip_version = Signal(intbv(0)[4:]) + input_3_ip_ihl = Signal(intbv(0)[4:]) + input_3_ip_dscp = Signal(intbv(0)[6:]) + input_3_ip_ecn = Signal(intbv(0)[2:]) + input_3_ip_length = Signal(intbv(0)[16:]) + input_3_ip_identification = Signal(intbv(0)[16:]) + input_3_ip_flags = Signal(intbv(0)[3:]) + input_3_ip_fragment_offset = Signal(intbv(0)[13:]) + input_3_ip_ttl = Signal(intbv(0)[8:]) + input_3_ip_protocol = Signal(intbv(0)[8:]) + input_3_ip_header_checksum = Signal(intbv(0)[16:]) + input_3_ip_source_ip = Signal(intbv(0)[32:]) + input_3_ip_dest_ip = Signal(intbv(0)[32:]) + input_3_udp_source_port = Signal(intbv(0)[16:]) + input_3_udp_dest_port = Signal(intbv(0)[16:]) + input_3_udp_length = Signal(intbv(0)[16:]) + input_3_udp_checksum = Signal(intbv(0)[16:]) + input_3_udp_payload_tdata = Signal(intbv(0)[8:]) + input_3_udp_payload_tvalid = Signal(bool(0)) + input_3_udp_payload_tlast = Signal(bool(0)) + input_3_udp_payload_tuser = Signal(bool(0)) + + output_udp_payload_tready = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + + # Outputs + input_0_udp_hdr_ready = Signal(bool(0)) + input_0_udp_payload_tready = Signal(bool(0)) + input_1_udp_hdr_ready = Signal(bool(0)) + input_1_udp_payload_tready = Signal(bool(0)) + input_2_udp_hdr_ready = Signal(bool(0)) + input_2_udp_payload_tready = Signal(bool(0)) + input_3_udp_hdr_ready = Signal(bool(0)) + input_3_udp_payload_tready = Signal(bool(0)) + + output_udp_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_0_udp_hdr_ready, + udp_hdr_valid=input_0_udp_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + ip_version=input_0_ip_version, + ip_ihl=input_0_ip_ihl, + ip_dscp=input_0_ip_dscp, + ip_ecn=input_0_ip_ecn, + ip_length=input_0_ip_length, + ip_identification=input_0_ip_identification, + ip_flags=input_0_ip_flags, + ip_fragment_offset=input_0_ip_fragment_offset, + ip_ttl=input_0_ip_ttl, + ip_protocol=input_0_ip_protocol, + ip_header_checksum=input_0_ip_header_checksum, + ip_source_ip=input_0_ip_source_ip, + ip_dest_ip=input_0_ip_dest_ip, + udp_source_port=input_0_udp_source_port, + udp_dest_port=input_0_udp_dest_port, + udp_length=input_0_udp_length, + udp_checksum=input_0_udp_checksum, + udp_payload_tdata=input_0_udp_payload_tdata, + udp_payload_tvalid=input_0_udp_payload_tvalid, + udp_payload_tready=input_0_udp_payload_tready, + udp_payload_tlast=input_0_udp_payload_tlast, + udp_payload_tuser=input_0_udp_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_1_udp_hdr_ready, + udp_hdr_valid=input_1_udp_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + ip_version=input_1_ip_version, + ip_ihl=input_1_ip_ihl, + ip_dscp=input_1_ip_dscp, + ip_ecn=input_1_ip_ecn, + ip_length=input_1_ip_length, + ip_identification=input_1_ip_identification, + ip_flags=input_1_ip_flags, + ip_fragment_offset=input_1_ip_fragment_offset, + ip_ttl=input_1_ip_ttl, + ip_protocol=input_1_ip_protocol, + ip_header_checksum=input_1_ip_header_checksum, + ip_source_ip=input_1_ip_source_ip, + ip_dest_ip=input_1_ip_dest_ip, + udp_source_port=input_1_udp_source_port, + udp_dest_port=input_1_udp_dest_port, + udp_length=input_1_udp_length, + udp_checksum=input_1_udp_checksum, + udp_payload_tdata=input_1_udp_payload_tdata, + udp_payload_tvalid=input_1_udp_payload_tvalid, + udp_payload_tready=input_1_udp_payload_tready, + udp_payload_tlast=input_1_udp_payload_tlast, + udp_payload_tuser=input_1_udp_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_2_udp_hdr_ready, + udp_hdr_valid=input_2_udp_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + ip_version=input_2_ip_version, + ip_ihl=input_2_ip_ihl, + ip_dscp=input_2_ip_dscp, + ip_ecn=input_2_ip_ecn, + ip_length=input_2_ip_length, + ip_identification=input_2_ip_identification, + ip_flags=input_2_ip_flags, + ip_fragment_offset=input_2_ip_fragment_offset, + ip_ttl=input_2_ip_ttl, + ip_protocol=input_2_ip_protocol, + ip_header_checksum=input_2_ip_header_checksum, + ip_source_ip=input_2_ip_source_ip, + ip_dest_ip=input_2_ip_dest_ip, + udp_source_port=input_2_udp_source_port, + udp_dest_port=input_2_udp_dest_port, + udp_length=input_2_udp_length, + udp_checksum=input_2_udp_checksum, + udp_payload_tdata=input_2_udp_payload_tdata, + udp_payload_tvalid=input_2_udp_payload_tvalid, + udp_payload_tready=input_2_udp_payload_tready, + udp_payload_tlast=input_2_udp_payload_tlast, + udp_payload_tuser=input_2_udp_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_3_udp_hdr_ready, + udp_hdr_valid=input_3_udp_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + ip_version=input_3_ip_version, + ip_ihl=input_3_ip_ihl, + ip_dscp=input_3_ip_dscp, + ip_ecn=input_3_ip_ecn, + ip_length=input_3_ip_length, + ip_identification=input_3_ip_identification, + ip_flags=input_3_ip_flags, + ip_fragment_offset=input_3_ip_fragment_offset, + ip_ttl=input_3_ip_ttl, + ip_protocol=input_3_ip_protocol, + ip_header_checksum=input_3_ip_header_checksum, + ip_source_ip=input_3_ip_source_ip, + ip_dest_ip=input_3_ip_dest_ip, + udp_source_port=input_3_udp_source_port, + udp_dest_port=input_3_udp_dest_port, + udp_length=input_3_udp_length, + udp_checksum=input_3_udp_checksum, + udp_payload_tdata=input_3_udp_payload_tdata, + udp_payload_tvalid=input_3_udp_payload_tvalid, + udp_payload_tready=input_3_udp_payload_tready, + udp_payload_tlast=input_3_udp_payload_tlast, + udp_payload_tuser=input_3_udp_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_udp_arb_mux_4(clk, + rst, + current_test, + + input_0_udp_hdr_valid, + input_0_udp_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tvalid, + input_0_udp_payload_tready, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_udp_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tvalid, + input_1_udp_payload_tready, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_udp_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tvalid, + input_2_udp_payload_tready, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_udp_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tvalid, + input_3_udp_payload_tready, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_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: port 0") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: port 1") + current_test.next = 2 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + 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 5: alterate pause source") + current_test.next = 5 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == 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: alterate pause sink") + current_test.next = 6 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_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 + 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: back-to-back packets, different ports, arbitration test") + current_test.next = 7 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + yield clk.posedge + + yield delay(800) + yield clk.posedge + source_1_queue.put(test_frame1) + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + 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 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_arb_mux_4.v b/tb/test_udp_arb_mux_4.v new file mode 100644 index 000000000..f38d96a2c --- /dev/null +++ b/tb/test_udp_arb_mux_4.v @@ -0,0 +1,465 @@ +/* + +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_udp_arb_mux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_udp_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [3:0] input_0_ip_version = 0; +reg [3:0] input_0_ip_ihl = 0; +reg [5:0] input_0_ip_dscp = 0; +reg [1:0] input_0_ip_ecn = 0; +reg [15:0] input_0_ip_length = 0; +reg [15:0] input_0_ip_identification = 0; +reg [2:0] input_0_ip_flags = 0; +reg [12:0] input_0_ip_fragment_offset = 0; +reg [7:0] input_0_ip_ttl = 0; +reg [7:0] input_0_ip_protocol = 0; +reg [15:0] input_0_ip_header_checksum = 0; +reg [31:0] input_0_ip_source_ip = 0; +reg [31:0] input_0_ip_dest_ip = 0; +reg [15:0] input_0_udp_source_port = 0; +reg [15:0] input_0_udp_dest_port = 0; +reg [15:0] input_0_udp_length = 0; +reg [15:0] input_0_udp_checksum = 0; +reg [7:0] input_0_udp_payload_tdata = 0; +reg input_0_udp_payload_tvalid = 0; +reg input_0_udp_payload_tlast = 0; +reg input_0_udp_payload_tuser = 0; +reg input_1_udp_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [3:0] input_1_ip_version = 0; +reg [3:0] input_1_ip_ihl = 0; +reg [5:0] input_1_ip_dscp = 0; +reg [1:0] input_1_ip_ecn = 0; +reg [15:0] input_1_ip_length = 0; +reg [15:0] input_1_ip_identification = 0; +reg [2:0] input_1_ip_flags = 0; +reg [12:0] input_1_ip_fragment_offset = 0; +reg [7:0] input_1_ip_ttl = 0; +reg [7:0] input_1_ip_protocol = 0; +reg [15:0] input_1_ip_header_checksum = 0; +reg [31:0] input_1_ip_source_ip = 0; +reg [31:0] input_1_ip_dest_ip = 0; +reg [15:0] input_1_udp_source_port = 0; +reg [15:0] input_1_udp_dest_port = 0; +reg [15:0] input_1_udp_length = 0; +reg [15:0] input_1_udp_checksum = 0; +reg [7:0] input_1_udp_payload_tdata = 0; +reg input_1_udp_payload_tvalid = 0; +reg input_1_udp_payload_tlast = 0; +reg input_1_udp_payload_tuser = 0; +reg input_2_udp_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [3:0] input_2_ip_version = 0; +reg [3:0] input_2_ip_ihl = 0; +reg [5:0] input_2_ip_dscp = 0; +reg [1:0] input_2_ip_ecn = 0; +reg [15:0] input_2_ip_length = 0; +reg [15:0] input_2_ip_identification = 0; +reg [2:0] input_2_ip_flags = 0; +reg [12:0] input_2_ip_fragment_offset = 0; +reg [7:0] input_2_ip_ttl = 0; +reg [7:0] input_2_ip_protocol = 0; +reg [15:0] input_2_ip_header_checksum = 0; +reg [31:0] input_2_ip_source_ip = 0; +reg [31:0] input_2_ip_dest_ip = 0; +reg [15:0] input_2_udp_source_port = 0; +reg [15:0] input_2_udp_dest_port = 0; +reg [15:0] input_2_udp_length = 0; +reg [15:0] input_2_udp_checksum = 0; +reg [7:0] input_2_udp_payload_tdata = 0; +reg input_2_udp_payload_tvalid = 0; +reg input_2_udp_payload_tlast = 0; +reg input_2_udp_payload_tuser = 0; +reg input_3_udp_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [3:0] input_3_ip_version = 0; +reg [3:0] input_3_ip_ihl = 0; +reg [5:0] input_3_ip_dscp = 0; +reg [1:0] input_3_ip_ecn = 0; +reg [15:0] input_3_ip_length = 0; +reg [15:0] input_3_ip_identification = 0; +reg [2:0] input_3_ip_flags = 0; +reg [12:0] input_3_ip_fragment_offset = 0; +reg [7:0] input_3_ip_ttl = 0; +reg [7:0] input_3_ip_protocol = 0; +reg [15:0] input_3_ip_header_checksum = 0; +reg [31:0] input_3_ip_source_ip = 0; +reg [31:0] input_3_ip_dest_ip = 0; +reg [15:0] input_3_udp_source_port = 0; +reg [15:0] input_3_udp_dest_port = 0; +reg [15:0] input_3_udp_length = 0; +reg [15:0] input_3_udp_checksum = 0; +reg [7:0] input_3_udp_payload_tdata = 0; +reg input_3_udp_payload_tvalid = 0; +reg input_3_udp_payload_tlast = 0; +reg input_3_udp_payload_tuser = 0; + +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; + +// Outputs +wire input_0_udp_payload_tready; +wire input_0_udp_hdr_ready; +wire input_1_udp_payload_tready; +wire input_1_udp_hdr_ready; +wire input_2_udp_payload_tready; +wire input_2_udp_hdr_ready; +wire input_3_udp_payload_tready; +wire input_3_udp_hdr_ready; + +wire output_udp_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [7:0] output_udp_payload_tdata; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_udp_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tvalid, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tvalid, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tvalid, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tvalid, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + output_udp_hdr_ready, + output_udp_payload_tready); + $to_myhdl(input_0_udp_hdr_ready, + input_0_udp_payload_tready, + input_1_udp_hdr_ready, + input_1_udp_payload_tready, + input_2_udp_hdr_ready, + input_2_udp_payload_tready, + input_3_udp_hdr_ready, + input_3_udp_payload_tready, + output_udp_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser); + + // dump file + $dumpfile("test_udp_arb_mux_4.lxt"); + $dumpvars(0, test_udp_arb_mux_4); +end + +udp_arb_mux_4 +UUT ( + .clk(clk), + .rst(rst), + // UDP frame inputs + .input_0_udp_hdr_valid(input_0_udp_hdr_valid), + .input_0_udp_hdr_ready(input_0_udp_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_udp_source_port(input_0_udp_source_port), + .input_0_udp_dest_port(input_0_udp_dest_port), + .input_0_udp_length(input_0_udp_length), + .input_0_udp_checksum(input_0_udp_checksum), + .input_0_udp_payload_tdata(input_0_udp_payload_tdata), + .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid), + .input_0_udp_payload_tready(input_0_udp_payload_tready), + .input_0_udp_payload_tlast(input_0_udp_payload_tlast), + .input_0_udp_payload_tuser(input_0_udp_payload_tuser), + .input_1_udp_hdr_valid(input_1_udp_hdr_valid), + .input_1_udp_hdr_ready(input_1_udp_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_udp_source_port(input_1_udp_source_port), + .input_1_udp_dest_port(input_1_udp_dest_port), + .input_1_udp_length(input_1_udp_length), + .input_1_udp_checksum(input_1_udp_checksum), + .input_1_udp_payload_tdata(input_1_udp_payload_tdata), + .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid), + .input_1_udp_payload_tready(input_1_udp_payload_tready), + .input_1_udp_payload_tlast(input_1_udp_payload_tlast), + .input_1_udp_payload_tuser(input_1_udp_payload_tuser), + .input_2_udp_hdr_valid(input_2_udp_hdr_valid), + .input_2_udp_hdr_ready(input_2_udp_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_udp_source_port(input_2_udp_source_port), + .input_2_udp_dest_port(input_2_udp_dest_port), + .input_2_udp_length(input_2_udp_length), + .input_2_udp_checksum(input_2_udp_checksum), + .input_2_udp_payload_tdata(input_2_udp_payload_tdata), + .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid), + .input_2_udp_payload_tready(input_2_udp_payload_tready), + .input_2_udp_payload_tlast(input_2_udp_payload_tlast), + .input_2_udp_payload_tuser(input_2_udp_payload_tuser), + .input_3_udp_hdr_valid(input_3_udp_hdr_valid), + .input_3_udp_hdr_ready(input_3_udp_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_udp_source_port(input_3_udp_source_port), + .input_3_udp_dest_port(input_3_udp_dest_port), + .input_3_udp_length(input_3_udp_length), + .input_3_udp_checksum(input_3_udp_checksum), + .input_3_udp_payload_tdata(input_3_udp_payload_tdata), + .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid), + .input_3_udp_payload_tready(input_3_udp_payload_tready), + .input_3_udp_payload_tlast(input_3_udp_payload_tlast), + .input_3_udp_payload_tuser(input_3_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser) +); + +endmodule diff --git a/tb/test_udp_arb_mux_64_4.py b/tb/test_udp_arb_mux_64_4.py new file mode 100755 index 000000000..08c670950 --- /dev/null +++ b/tb/test_udp_arb_mux_64_4.py @@ -0,0 +1,1364 @@ +#!/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 udp_ep + +module = 'udp_arb_mux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/udp_mux_64_4.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp_arb_mux_64_4(clk, + rst, + current_test, + + input_0_udp_hdr_valid, + input_0_udp_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tkeep, + input_0_udp_payload_tvalid, + input_0_udp_payload_tready, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_udp_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tkeep, + input_1_udp_payload_tvalid, + input_1_udp_payload_tready, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_udp_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tkeep, + input_2_udp_payload_tvalid, + input_2_udp_payload_tready, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_udp_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tkeep, + input_3_udp_payload_tvalid, + input_3_udp_payload_tready, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_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_0_udp_hdr_valid=input_0_udp_hdr_valid, + input_0_udp_hdr_ready=input_0_udp_hdr_ready, + input_0_eth_dest_mac=input_0_eth_dest_mac, + input_0_eth_src_mac=input_0_eth_src_mac, + input_0_eth_type=input_0_eth_type, + input_0_ip_version=input_0_ip_version, + input_0_ip_ihl=input_0_ip_ihl, + input_0_ip_dscp=input_0_ip_dscp, + input_0_ip_ecn=input_0_ip_ecn, + input_0_ip_length=input_0_ip_length, + input_0_ip_identification=input_0_ip_identification, + input_0_ip_flags=input_0_ip_flags, + input_0_ip_fragment_offset=input_0_ip_fragment_offset, + input_0_ip_ttl=input_0_ip_ttl, + input_0_ip_protocol=input_0_ip_protocol, + input_0_ip_header_checksum=input_0_ip_header_checksum, + input_0_ip_source_ip=input_0_ip_source_ip, + input_0_ip_dest_ip=input_0_ip_dest_ip, + input_0_udp_source_port=input_0_udp_source_port, + input_0_udp_dest_port=input_0_udp_dest_port, + input_0_udp_length=input_0_udp_length, + input_0_udp_checksum=input_0_udp_checksum, + input_0_udp_payload_tdata=input_0_udp_payload_tdata, + input_0_udp_payload_tkeep=input_0_udp_payload_tkeep, + input_0_udp_payload_tvalid=input_0_udp_payload_tvalid, + input_0_udp_payload_tready=input_0_udp_payload_tready, + input_0_udp_payload_tlast=input_0_udp_payload_tlast, + input_0_udp_payload_tuser=input_0_udp_payload_tuser, + input_1_udp_hdr_valid=input_1_udp_hdr_valid, + input_1_udp_hdr_ready=input_1_udp_hdr_ready, + input_1_eth_dest_mac=input_1_eth_dest_mac, + input_1_eth_src_mac=input_1_eth_src_mac, + input_1_eth_type=input_1_eth_type, + input_1_ip_version=input_1_ip_version, + input_1_ip_ihl=input_1_ip_ihl, + input_1_ip_dscp=input_1_ip_dscp, + input_1_ip_ecn=input_1_ip_ecn, + input_1_ip_length=input_1_ip_length, + input_1_ip_identification=input_1_ip_identification, + input_1_ip_flags=input_1_ip_flags, + input_1_ip_fragment_offset=input_1_ip_fragment_offset, + input_1_ip_ttl=input_1_ip_ttl, + input_1_ip_protocol=input_1_ip_protocol, + input_1_ip_header_checksum=input_1_ip_header_checksum, + input_1_ip_source_ip=input_1_ip_source_ip, + input_1_ip_dest_ip=input_1_ip_dest_ip, + input_1_udp_source_port=input_1_udp_source_port, + input_1_udp_dest_port=input_1_udp_dest_port, + input_1_udp_length=input_1_udp_length, + input_1_udp_checksum=input_1_udp_checksum, + input_1_udp_payload_tdata=input_1_udp_payload_tdata, + input_1_udp_payload_tkeep=input_1_udp_payload_tkeep, + input_1_udp_payload_tvalid=input_1_udp_payload_tvalid, + input_1_udp_payload_tready=input_1_udp_payload_tready, + input_1_udp_payload_tlast=input_1_udp_payload_tlast, + input_1_udp_payload_tuser=input_1_udp_payload_tuser, + input_2_udp_hdr_valid=input_2_udp_hdr_valid, + input_2_udp_hdr_ready=input_2_udp_hdr_ready, + input_2_eth_dest_mac=input_2_eth_dest_mac, + input_2_eth_src_mac=input_2_eth_src_mac, + input_2_eth_type=input_2_eth_type, + input_2_ip_version=input_2_ip_version, + input_2_ip_ihl=input_2_ip_ihl, + input_2_ip_dscp=input_2_ip_dscp, + input_2_ip_ecn=input_2_ip_ecn, + input_2_ip_length=input_2_ip_length, + input_2_ip_identification=input_2_ip_identification, + input_2_ip_flags=input_2_ip_flags, + input_2_ip_fragment_offset=input_2_ip_fragment_offset, + input_2_ip_ttl=input_2_ip_ttl, + input_2_ip_protocol=input_2_ip_protocol, + input_2_ip_header_checksum=input_2_ip_header_checksum, + input_2_ip_source_ip=input_2_ip_source_ip, + input_2_ip_dest_ip=input_2_ip_dest_ip, + input_2_udp_source_port=input_2_udp_source_port, + input_2_udp_dest_port=input_2_udp_dest_port, + input_2_udp_length=input_2_udp_length, + input_2_udp_checksum=input_2_udp_checksum, + input_2_udp_payload_tdata=input_2_udp_payload_tdata, + input_2_udp_payload_tkeep=input_2_udp_payload_tkeep, + input_2_udp_payload_tvalid=input_2_udp_payload_tvalid, + input_2_udp_payload_tready=input_2_udp_payload_tready, + input_2_udp_payload_tlast=input_2_udp_payload_tlast, + input_2_udp_payload_tuser=input_2_udp_payload_tuser, + input_3_udp_hdr_valid=input_3_udp_hdr_valid, + input_3_udp_hdr_ready=input_3_udp_hdr_ready, + input_3_eth_dest_mac=input_3_eth_dest_mac, + input_3_eth_src_mac=input_3_eth_src_mac, + input_3_eth_type=input_3_eth_type, + input_3_ip_version=input_3_ip_version, + input_3_ip_ihl=input_3_ip_ihl, + input_3_ip_dscp=input_3_ip_dscp, + input_3_ip_ecn=input_3_ip_ecn, + input_3_ip_length=input_3_ip_length, + input_3_ip_identification=input_3_ip_identification, + input_3_ip_flags=input_3_ip_flags, + input_3_ip_fragment_offset=input_3_ip_fragment_offset, + input_3_ip_ttl=input_3_ip_ttl, + input_3_ip_protocol=input_3_ip_protocol, + input_3_ip_header_checksum=input_3_ip_header_checksum, + input_3_ip_source_ip=input_3_ip_source_ip, + input_3_ip_dest_ip=input_3_ip_dest_ip, + input_3_udp_source_port=input_3_udp_source_port, + input_3_udp_dest_port=input_3_udp_dest_port, + input_3_udp_length=input_3_udp_length, + input_3_udp_checksum=input_3_udp_checksum, + input_3_udp_payload_tdata=input_3_udp_payload_tdata, + input_3_udp_payload_tkeep=input_3_udp_payload_tkeep, + input_3_udp_payload_tvalid=input_3_udp_payload_tvalid, + input_3_udp_payload_tready=input_3_udp_payload_tready, + input_3_udp_payload_tlast=input_3_udp_payload_tlast, + input_3_udp_payload_tuser=input_3_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tkeep=output_udp_payload_tkeep, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_udp_hdr_valid = Signal(bool(0)) + input_0_eth_dest_mac = Signal(intbv(0)[48:]) + input_0_eth_src_mac = Signal(intbv(0)[48:]) + input_0_eth_type = Signal(intbv(0)[16:]) + input_0_ip_version = Signal(intbv(0)[4:]) + input_0_ip_ihl = Signal(intbv(0)[4:]) + input_0_ip_dscp = Signal(intbv(0)[6:]) + input_0_ip_ecn = Signal(intbv(0)[2:]) + input_0_ip_length = Signal(intbv(0)[16:]) + input_0_ip_identification = Signal(intbv(0)[16:]) + input_0_ip_flags = Signal(intbv(0)[3:]) + input_0_ip_fragment_offset = Signal(intbv(0)[13:]) + input_0_ip_ttl = Signal(intbv(0)[8:]) + input_0_ip_protocol = Signal(intbv(0)[8:]) + input_0_ip_header_checksum = Signal(intbv(0)[16:]) + input_0_ip_source_ip = Signal(intbv(0)[32:]) + input_0_ip_dest_ip = Signal(intbv(0)[32:]) + input_0_udp_source_port = Signal(intbv(0)[16:]) + input_0_udp_dest_port = Signal(intbv(0)[16:]) + input_0_udp_length = Signal(intbv(0)[16:]) + input_0_udp_checksum = Signal(intbv(0)[16:]) + input_0_udp_payload_tdata = Signal(intbv(0)[64:]) + input_0_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_0_udp_payload_tvalid = Signal(bool(0)) + input_0_udp_payload_tlast = Signal(bool(0)) + input_0_udp_payload_tuser = Signal(bool(0)) + input_1_udp_hdr_valid = Signal(bool(0)) + input_1_eth_dest_mac = Signal(intbv(0)[48:]) + input_1_eth_src_mac = Signal(intbv(0)[48:]) + input_1_eth_type = Signal(intbv(0)[16:]) + input_1_ip_version = Signal(intbv(0)[4:]) + input_1_ip_ihl = Signal(intbv(0)[4:]) + input_1_ip_dscp = Signal(intbv(0)[6:]) + input_1_ip_ecn = Signal(intbv(0)[2:]) + input_1_ip_length = Signal(intbv(0)[16:]) + input_1_ip_identification = Signal(intbv(0)[16:]) + input_1_ip_flags = Signal(intbv(0)[3:]) + input_1_ip_fragment_offset = Signal(intbv(0)[13:]) + input_1_ip_ttl = Signal(intbv(0)[8:]) + input_1_ip_protocol = Signal(intbv(0)[8:]) + input_1_ip_header_checksum = Signal(intbv(0)[16:]) + input_1_ip_source_ip = Signal(intbv(0)[32:]) + input_1_ip_dest_ip = Signal(intbv(0)[32:]) + input_1_udp_source_port = Signal(intbv(0)[16:]) + input_1_udp_dest_port = Signal(intbv(0)[16:]) + input_1_udp_length = Signal(intbv(0)[16:]) + input_1_udp_checksum = Signal(intbv(0)[16:]) + input_1_udp_payload_tdata = Signal(intbv(0)[64:]) + input_1_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_1_udp_payload_tvalid = Signal(bool(0)) + input_1_udp_payload_tlast = Signal(bool(0)) + input_1_udp_payload_tuser = Signal(bool(0)) + input_2_udp_hdr_valid = Signal(bool(0)) + input_2_eth_dest_mac = Signal(intbv(0)[48:]) + input_2_eth_src_mac = Signal(intbv(0)[48:]) + input_2_eth_type = Signal(intbv(0)[16:]) + input_2_ip_version = Signal(intbv(0)[4:]) + input_2_ip_ihl = Signal(intbv(0)[4:]) + input_2_ip_dscp = Signal(intbv(0)[6:]) + input_2_ip_ecn = Signal(intbv(0)[2:]) + input_2_ip_length = Signal(intbv(0)[16:]) + input_2_ip_identification = Signal(intbv(0)[16:]) + input_2_ip_flags = Signal(intbv(0)[3:]) + input_2_ip_fragment_offset = Signal(intbv(0)[13:]) + input_2_ip_ttl = Signal(intbv(0)[8:]) + input_2_ip_protocol = Signal(intbv(0)[8:]) + input_2_ip_header_checksum = Signal(intbv(0)[16:]) + input_2_ip_source_ip = Signal(intbv(0)[32:]) + input_2_ip_dest_ip = Signal(intbv(0)[32:]) + input_2_udp_source_port = Signal(intbv(0)[16:]) + input_2_udp_dest_port = Signal(intbv(0)[16:]) + input_2_udp_length = Signal(intbv(0)[16:]) + input_2_udp_checksum = Signal(intbv(0)[16:]) + input_2_udp_payload_tdata = Signal(intbv(0)[64:]) + input_2_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_2_udp_payload_tvalid = Signal(bool(0)) + input_2_udp_payload_tlast = Signal(bool(0)) + input_2_udp_payload_tuser = Signal(bool(0)) + input_3_udp_hdr_valid = Signal(bool(0)) + input_3_eth_dest_mac = Signal(intbv(0)[48:]) + input_3_eth_src_mac = Signal(intbv(0)[48:]) + input_3_eth_type = Signal(intbv(0)[16:]) + input_3_ip_version = Signal(intbv(0)[4:]) + input_3_ip_ihl = Signal(intbv(0)[4:]) + input_3_ip_dscp = Signal(intbv(0)[6:]) + input_3_ip_ecn = Signal(intbv(0)[2:]) + input_3_ip_length = Signal(intbv(0)[16:]) + input_3_ip_identification = Signal(intbv(0)[16:]) + input_3_ip_flags = Signal(intbv(0)[3:]) + input_3_ip_fragment_offset = Signal(intbv(0)[13:]) + input_3_ip_ttl = Signal(intbv(0)[8:]) + input_3_ip_protocol = Signal(intbv(0)[8:]) + input_3_ip_header_checksum = Signal(intbv(0)[16:]) + input_3_ip_source_ip = Signal(intbv(0)[32:]) + input_3_ip_dest_ip = Signal(intbv(0)[32:]) + input_3_udp_source_port = Signal(intbv(0)[16:]) + input_3_udp_dest_port = Signal(intbv(0)[16:]) + input_3_udp_length = Signal(intbv(0)[16:]) + input_3_udp_checksum = Signal(intbv(0)[16:]) + input_3_udp_payload_tdata = Signal(intbv(0)[64:]) + input_3_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_3_udp_payload_tvalid = Signal(bool(0)) + input_3_udp_payload_tlast = Signal(bool(0)) + input_3_udp_payload_tuser = Signal(bool(0)) + + output_udp_payload_tready = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + + # Outputs + input_0_udp_hdr_ready = Signal(bool(0)) + input_0_udp_payload_tready = Signal(bool(0)) + input_1_udp_hdr_ready = Signal(bool(0)) + input_1_udp_payload_tready = Signal(bool(0)) + input_2_udp_hdr_ready = Signal(bool(0)) + input_2_udp_payload_tready = Signal(bool(0)) + input_3_udp_hdr_ready = Signal(bool(0)) + input_3_udp_payload_tready = Signal(bool(0)) + + output_udp_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[64:]) + output_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source_0 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_0_udp_hdr_ready, + udp_hdr_valid=input_0_udp_hdr_valid, + eth_dest_mac=input_0_eth_dest_mac, + eth_src_mac=input_0_eth_src_mac, + eth_type=input_0_eth_type, + ip_version=input_0_ip_version, + ip_ihl=input_0_ip_ihl, + ip_dscp=input_0_ip_dscp, + ip_ecn=input_0_ip_ecn, + ip_length=input_0_ip_length, + ip_identification=input_0_ip_identification, + ip_flags=input_0_ip_flags, + ip_fragment_offset=input_0_ip_fragment_offset, + ip_ttl=input_0_ip_ttl, + ip_protocol=input_0_ip_protocol, + ip_header_checksum=input_0_ip_header_checksum, + ip_source_ip=input_0_ip_source_ip, + ip_dest_ip=input_0_ip_dest_ip, + udp_source_port=input_0_udp_source_port, + udp_dest_port=input_0_udp_dest_port, + udp_length=input_0_udp_length, + udp_checksum=input_0_udp_checksum, + udp_payload_tdata=input_0_udp_payload_tdata, + udp_payload_tkeep=input_0_udp_payload_tkeep, + udp_payload_tvalid=input_0_udp_payload_tvalid, + udp_payload_tready=input_0_udp_payload_tready, + udp_payload_tlast=input_0_udp_payload_tlast, + udp_payload_tuser=input_0_udp_payload_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + + source_1 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_1_udp_hdr_ready, + udp_hdr_valid=input_1_udp_hdr_valid, + eth_dest_mac=input_1_eth_dest_mac, + eth_src_mac=input_1_eth_src_mac, + eth_type=input_1_eth_type, + ip_version=input_1_ip_version, + ip_ihl=input_1_ip_ihl, + ip_dscp=input_1_ip_dscp, + ip_ecn=input_1_ip_ecn, + ip_length=input_1_ip_length, + ip_identification=input_1_ip_identification, + ip_flags=input_1_ip_flags, + ip_fragment_offset=input_1_ip_fragment_offset, + ip_ttl=input_1_ip_ttl, + ip_protocol=input_1_ip_protocol, + ip_header_checksum=input_1_ip_header_checksum, + ip_source_ip=input_1_ip_source_ip, + ip_dest_ip=input_1_ip_dest_ip, + udp_source_port=input_1_udp_source_port, + udp_dest_port=input_1_udp_dest_port, + udp_length=input_1_udp_length, + udp_checksum=input_1_udp_checksum, + udp_payload_tdata=input_1_udp_payload_tdata, + udp_payload_tkeep=input_1_udp_payload_tkeep, + udp_payload_tvalid=input_1_udp_payload_tvalid, + udp_payload_tready=input_1_udp_payload_tready, + udp_payload_tlast=input_1_udp_payload_tlast, + udp_payload_tuser=input_1_udp_payload_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + + source_2 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_2_udp_hdr_ready, + udp_hdr_valid=input_2_udp_hdr_valid, + eth_dest_mac=input_2_eth_dest_mac, + eth_src_mac=input_2_eth_src_mac, + eth_type=input_2_eth_type, + ip_version=input_2_ip_version, + ip_ihl=input_2_ip_ihl, + ip_dscp=input_2_ip_dscp, + ip_ecn=input_2_ip_ecn, + ip_length=input_2_ip_length, + ip_identification=input_2_ip_identification, + ip_flags=input_2_ip_flags, + ip_fragment_offset=input_2_ip_fragment_offset, + ip_ttl=input_2_ip_ttl, + ip_protocol=input_2_ip_protocol, + ip_header_checksum=input_2_ip_header_checksum, + ip_source_ip=input_2_ip_source_ip, + ip_dest_ip=input_2_ip_dest_ip, + udp_source_port=input_2_udp_source_port, + udp_dest_port=input_2_udp_dest_port, + udp_length=input_2_udp_length, + udp_checksum=input_2_udp_checksum, + udp_payload_tdata=input_2_udp_payload_tdata, + udp_payload_tkeep=input_2_udp_payload_tkeep, + udp_payload_tvalid=input_2_udp_payload_tvalid, + udp_payload_tready=input_2_udp_payload_tready, + udp_payload_tlast=input_2_udp_payload_tlast, + udp_payload_tuser=input_2_udp_payload_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + + source_3 = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_3_udp_hdr_ready, + udp_hdr_valid=input_3_udp_hdr_valid, + eth_dest_mac=input_3_eth_dest_mac, + eth_src_mac=input_3_eth_src_mac, + eth_type=input_3_eth_type, + ip_version=input_3_ip_version, + ip_ihl=input_3_ip_ihl, + ip_dscp=input_3_ip_dscp, + ip_ecn=input_3_ip_ecn, + ip_length=input_3_ip_length, + ip_identification=input_3_ip_identification, + ip_flags=input_3_ip_flags, + ip_fragment_offset=input_3_ip_fragment_offset, + ip_ttl=input_3_ip_ttl, + ip_protocol=input_3_ip_protocol, + ip_header_checksum=input_3_ip_header_checksum, + ip_source_ip=input_3_ip_source_ip, + ip_dest_ip=input_3_ip_dest_ip, + udp_source_port=input_3_udp_source_port, + udp_dest_port=input_3_udp_dest_port, + udp_length=input_3_udp_length, + udp_checksum=input_3_udp_checksum, + udp_payload_tdata=input_3_udp_payload_tdata, + udp_payload_tkeep=input_3_udp_payload_tkeep, + udp_payload_tvalid=input_3_udp_payload_tvalid, + udp_payload_tready=input_3_udp_payload_tready, + udp_payload_tlast=input_3_udp_payload_tlast, + udp_payload_tuser=input_3_udp_payload_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tkeep=output_udp_payload_tkeep, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_udp_arb_mux_64_4(clk, + rst, + current_test, + + input_0_udp_hdr_valid, + input_0_udp_hdr_ready, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tkeep, + input_0_udp_payload_tvalid, + input_0_udp_payload_tready, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_udp_hdr_ready, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tkeep, + input_1_udp_payload_tvalid, + input_1_udp_payload_tready, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_udp_hdr_ready, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tkeep, + input_2_udp_payload_tvalid, + input_2_udp_payload_tready, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_udp_hdr_ready, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tkeep, + input_3_udp_payload_tvalid, + input_3_udp_payload_tready, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_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: port 0") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_0_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: port 1") + current_test.next = 2 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_1_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + 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 4: back-to-back packets, different ports") + current_test.next = 4 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + 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 5: alterate pause source") + current_test.next = 5 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == 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: alterate pause sink") + current_test.next = 6 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_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 + 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: back-to-back packets, different ports, arbitration test") + current_test.next = 7 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A0152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A0252535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + source_2_queue.put(test_frame2) + yield clk.posedge + + yield delay(150) + yield clk.posedge + source_1_queue.put(test_frame1) + + while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + 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 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame2 + + 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) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_arb_mux_64_4.v b/tb/test_udp_arb_mux_64_4.v new file mode 100644 index 000000000..11f7e7ed2 --- /dev/null +++ b/tb/test_udp_arb_mux_64_4.v @@ -0,0 +1,480 @@ +/* + +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_udp_arb_mux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_0_udp_hdr_valid = 0; +reg [47:0] input_0_eth_dest_mac = 0; +reg [47:0] input_0_eth_src_mac = 0; +reg [15:0] input_0_eth_type = 0; +reg [3:0] input_0_ip_version = 0; +reg [3:0] input_0_ip_ihl = 0; +reg [5:0] input_0_ip_dscp = 0; +reg [1:0] input_0_ip_ecn = 0; +reg [15:0] input_0_ip_length = 0; +reg [15:0] input_0_ip_identification = 0; +reg [2:0] input_0_ip_flags = 0; +reg [12:0] input_0_ip_fragment_offset = 0; +reg [7:0] input_0_ip_ttl = 0; +reg [7:0] input_0_ip_protocol = 0; +reg [15:0] input_0_ip_header_checksum = 0; +reg [31:0] input_0_ip_source_ip = 0; +reg [31:0] input_0_ip_dest_ip = 0; +reg [15:0] input_0_udp_source_port = 0; +reg [15:0] input_0_udp_dest_port = 0; +reg [15:0] input_0_udp_length = 0; +reg [15:0] input_0_udp_checksum = 0; +reg [63:0] input_0_udp_payload_tdata = 0; +reg [7:0] input_0_udp_payload_tkeep = 0; +reg input_0_udp_payload_tvalid = 0; +reg input_0_udp_payload_tlast = 0; +reg input_0_udp_payload_tuser = 0; +reg input_1_udp_hdr_valid = 0; +reg [47:0] input_1_eth_dest_mac = 0; +reg [47:0] input_1_eth_src_mac = 0; +reg [15:0] input_1_eth_type = 0; +reg [3:0] input_1_ip_version = 0; +reg [3:0] input_1_ip_ihl = 0; +reg [5:0] input_1_ip_dscp = 0; +reg [1:0] input_1_ip_ecn = 0; +reg [15:0] input_1_ip_length = 0; +reg [15:0] input_1_ip_identification = 0; +reg [2:0] input_1_ip_flags = 0; +reg [12:0] input_1_ip_fragment_offset = 0; +reg [7:0] input_1_ip_ttl = 0; +reg [7:0] input_1_ip_protocol = 0; +reg [15:0] input_1_ip_header_checksum = 0; +reg [31:0] input_1_ip_source_ip = 0; +reg [31:0] input_1_ip_dest_ip = 0; +reg [15:0] input_1_udp_source_port = 0; +reg [15:0] input_1_udp_dest_port = 0; +reg [15:0] input_1_udp_length = 0; +reg [15:0] input_1_udp_checksum = 0; +reg [63:0] input_1_udp_payload_tdata = 0; +reg [7:0] input_1_udp_payload_tkeep = 0; +reg input_1_udp_payload_tvalid = 0; +reg input_1_udp_payload_tlast = 0; +reg input_1_udp_payload_tuser = 0; +reg input_2_udp_hdr_valid = 0; +reg [47:0] input_2_eth_dest_mac = 0; +reg [47:0] input_2_eth_src_mac = 0; +reg [15:0] input_2_eth_type = 0; +reg [3:0] input_2_ip_version = 0; +reg [3:0] input_2_ip_ihl = 0; +reg [5:0] input_2_ip_dscp = 0; +reg [1:0] input_2_ip_ecn = 0; +reg [15:0] input_2_ip_length = 0; +reg [15:0] input_2_ip_identification = 0; +reg [2:0] input_2_ip_flags = 0; +reg [12:0] input_2_ip_fragment_offset = 0; +reg [7:0] input_2_ip_ttl = 0; +reg [7:0] input_2_ip_protocol = 0; +reg [15:0] input_2_ip_header_checksum = 0; +reg [31:0] input_2_ip_source_ip = 0; +reg [31:0] input_2_ip_dest_ip = 0; +reg [15:0] input_2_udp_source_port = 0; +reg [15:0] input_2_udp_dest_port = 0; +reg [15:0] input_2_udp_length = 0; +reg [15:0] input_2_udp_checksum = 0; +reg [63:0] input_2_udp_payload_tdata = 0; +reg [7:0] input_2_udp_payload_tkeep = 0; +reg input_2_udp_payload_tvalid = 0; +reg input_2_udp_payload_tlast = 0; +reg input_2_udp_payload_tuser = 0; +reg input_3_udp_hdr_valid = 0; +reg [47:0] input_3_eth_dest_mac = 0; +reg [47:0] input_3_eth_src_mac = 0; +reg [15:0] input_3_eth_type = 0; +reg [3:0] input_3_ip_version = 0; +reg [3:0] input_3_ip_ihl = 0; +reg [5:0] input_3_ip_dscp = 0; +reg [1:0] input_3_ip_ecn = 0; +reg [15:0] input_3_ip_length = 0; +reg [15:0] input_3_ip_identification = 0; +reg [2:0] input_3_ip_flags = 0; +reg [12:0] input_3_ip_fragment_offset = 0; +reg [7:0] input_3_ip_ttl = 0; +reg [7:0] input_3_ip_protocol = 0; +reg [15:0] input_3_ip_header_checksum = 0; +reg [31:0] input_3_ip_source_ip = 0; +reg [31:0] input_3_ip_dest_ip = 0; +reg [15:0] input_3_udp_source_port = 0; +reg [15:0] input_3_udp_dest_port = 0; +reg [15:0] input_3_udp_length = 0; +reg [15:0] input_3_udp_checksum = 0; +reg [63:0] input_3_udp_payload_tdata = 0; +reg [7:0] input_3_udp_payload_tkeep = 0; +reg input_3_udp_payload_tvalid = 0; +reg input_3_udp_payload_tlast = 0; +reg input_3_udp_payload_tuser = 0; + +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; + +// Outputs +wire input_0_udp_payload_tready; +wire input_0_udp_hdr_ready; +wire input_1_udp_payload_tready; +wire input_1_udp_hdr_ready; +wire input_2_udp_payload_tready; +wire input_2_udp_hdr_ready; +wire input_3_udp_payload_tready; +wire input_3_udp_hdr_ready; + +wire output_udp_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [63:0] output_udp_payload_tdata; +wire [7:0] output_udp_payload_tkeep; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_udp_hdr_valid, + input_0_eth_dest_mac, + input_0_eth_src_mac, + input_0_eth_type, + input_0_ip_version, + input_0_ip_ihl, + input_0_ip_dscp, + input_0_ip_ecn, + input_0_ip_length, + input_0_ip_identification, + input_0_ip_flags, + input_0_ip_fragment_offset, + input_0_ip_ttl, + input_0_ip_protocol, + input_0_ip_header_checksum, + input_0_ip_source_ip, + input_0_ip_dest_ip, + input_0_udp_source_port, + input_0_udp_dest_port, + input_0_udp_length, + input_0_udp_checksum, + input_0_udp_payload_tdata, + input_0_udp_payload_tkeep, + input_0_udp_payload_tvalid, + input_0_udp_payload_tlast, + input_0_udp_payload_tuser, + input_1_udp_hdr_valid, + input_1_eth_dest_mac, + input_1_eth_src_mac, + input_1_eth_type, + input_1_ip_version, + input_1_ip_ihl, + input_1_ip_dscp, + input_1_ip_ecn, + input_1_ip_length, + input_1_ip_identification, + input_1_ip_flags, + input_1_ip_fragment_offset, + input_1_ip_ttl, + input_1_ip_protocol, + input_1_ip_header_checksum, + input_1_ip_source_ip, + input_1_ip_dest_ip, + input_1_udp_source_port, + input_1_udp_dest_port, + input_1_udp_length, + input_1_udp_checksum, + input_1_udp_payload_tdata, + input_1_udp_payload_tkeep, + input_1_udp_payload_tvalid, + input_1_udp_payload_tlast, + input_1_udp_payload_tuser, + input_2_udp_hdr_valid, + input_2_eth_dest_mac, + input_2_eth_src_mac, + input_2_eth_type, + input_2_ip_version, + input_2_ip_ihl, + input_2_ip_dscp, + input_2_ip_ecn, + input_2_ip_length, + input_2_ip_identification, + input_2_ip_flags, + input_2_ip_fragment_offset, + input_2_ip_ttl, + input_2_ip_protocol, + input_2_ip_header_checksum, + input_2_ip_source_ip, + input_2_ip_dest_ip, + input_2_udp_source_port, + input_2_udp_dest_port, + input_2_udp_length, + input_2_udp_checksum, + input_2_udp_payload_tdata, + input_2_udp_payload_tkeep, + input_2_udp_payload_tvalid, + input_2_udp_payload_tlast, + input_2_udp_payload_tuser, + input_3_udp_hdr_valid, + input_3_eth_dest_mac, + input_3_eth_src_mac, + input_3_eth_type, + input_3_ip_version, + input_3_ip_ihl, + input_3_ip_dscp, + input_3_ip_ecn, + input_3_ip_length, + input_3_ip_identification, + input_3_ip_flags, + input_3_ip_fragment_offset, + input_3_ip_ttl, + input_3_ip_protocol, + input_3_ip_header_checksum, + input_3_ip_source_ip, + input_3_ip_dest_ip, + input_3_udp_source_port, + input_3_udp_dest_port, + input_3_udp_length, + input_3_udp_checksum, + input_3_udp_payload_tdata, + input_3_udp_payload_tkeep, + input_3_udp_payload_tvalid, + input_3_udp_payload_tlast, + input_3_udp_payload_tuser, + output_udp_hdr_ready, + output_udp_payload_tready); + $to_myhdl(input_0_udp_hdr_ready, + input_0_udp_payload_tready, + input_1_udp_hdr_ready, + input_1_udp_payload_tready, + input_2_udp_hdr_ready, + input_2_udp_payload_tready, + input_3_udp_hdr_ready, + input_3_udp_payload_tready, + output_udp_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser); + + // dump file + $dumpfile("test_udp_arb_mux_64_4.lxt"); + $dumpvars(0, test_udp_arb_mux_64_4); +end + +udp_arb_mux_64_4 +UUT ( + .clk(clk), + .rst(rst), + // UDP frame inputs + .input_0_udp_hdr_valid(input_0_udp_hdr_valid), + .input_0_udp_hdr_ready(input_0_udp_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_udp_source_port(input_0_udp_source_port), + .input_0_udp_dest_port(input_0_udp_dest_port), + .input_0_udp_length(input_0_udp_length), + .input_0_udp_checksum(input_0_udp_checksum), + .input_0_udp_payload_tdata(input_0_udp_payload_tdata), + .input_0_udp_payload_tkeep(input_0_udp_payload_tkeep), + .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid), + .input_0_udp_payload_tready(input_0_udp_payload_tready), + .input_0_udp_payload_tlast(input_0_udp_payload_tlast), + .input_0_udp_payload_tuser(input_0_udp_payload_tuser), + .input_1_udp_hdr_valid(input_1_udp_hdr_valid), + .input_1_udp_hdr_ready(input_1_udp_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_udp_source_port(input_1_udp_source_port), + .input_1_udp_dest_port(input_1_udp_dest_port), + .input_1_udp_length(input_1_udp_length), + .input_1_udp_checksum(input_1_udp_checksum), + .input_1_udp_payload_tdata(input_1_udp_payload_tdata), + .input_1_udp_payload_tkeep(input_1_udp_payload_tkeep), + .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid), + .input_1_udp_payload_tready(input_1_udp_payload_tready), + .input_1_udp_payload_tlast(input_1_udp_payload_tlast), + .input_1_udp_payload_tuser(input_1_udp_payload_tuser), + .input_2_udp_hdr_valid(input_2_udp_hdr_valid), + .input_2_udp_hdr_ready(input_2_udp_hdr_ready), + .input_2_eth_dest_mac(input_2_eth_dest_mac), + .input_2_eth_src_mac(input_2_eth_src_mac), + .input_2_eth_type(input_2_eth_type), + .input_2_ip_version(input_2_ip_version), + .input_2_ip_ihl(input_2_ip_ihl), + .input_2_ip_dscp(input_2_ip_dscp), + .input_2_ip_ecn(input_2_ip_ecn), + .input_2_ip_length(input_2_ip_length), + .input_2_ip_identification(input_2_ip_identification), + .input_2_ip_flags(input_2_ip_flags), + .input_2_ip_fragment_offset(input_2_ip_fragment_offset), + .input_2_ip_ttl(input_2_ip_ttl), + .input_2_ip_protocol(input_2_ip_protocol), + .input_2_ip_header_checksum(input_2_ip_header_checksum), + .input_2_ip_source_ip(input_2_ip_source_ip), + .input_2_ip_dest_ip(input_2_ip_dest_ip), + .input_2_udp_source_port(input_2_udp_source_port), + .input_2_udp_dest_port(input_2_udp_dest_port), + .input_2_udp_length(input_2_udp_length), + .input_2_udp_checksum(input_2_udp_checksum), + .input_2_udp_payload_tdata(input_2_udp_payload_tdata), + .input_2_udp_payload_tkeep(input_2_udp_payload_tkeep), + .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid), + .input_2_udp_payload_tready(input_2_udp_payload_tready), + .input_2_udp_payload_tlast(input_2_udp_payload_tlast), + .input_2_udp_payload_tuser(input_2_udp_payload_tuser), + .input_3_udp_hdr_valid(input_3_udp_hdr_valid), + .input_3_udp_hdr_ready(input_3_udp_hdr_ready), + .input_3_eth_dest_mac(input_3_eth_dest_mac), + .input_3_eth_src_mac(input_3_eth_src_mac), + .input_3_eth_type(input_3_eth_type), + .input_3_ip_version(input_3_ip_version), + .input_3_ip_ihl(input_3_ip_ihl), + .input_3_ip_dscp(input_3_ip_dscp), + .input_3_ip_ecn(input_3_ip_ecn), + .input_3_ip_length(input_3_ip_length), + .input_3_ip_identification(input_3_ip_identification), + .input_3_ip_flags(input_3_ip_flags), + .input_3_ip_fragment_offset(input_3_ip_fragment_offset), + .input_3_ip_ttl(input_3_ip_ttl), + .input_3_ip_protocol(input_3_ip_protocol), + .input_3_ip_header_checksum(input_3_ip_header_checksum), + .input_3_ip_source_ip(input_3_ip_source_ip), + .input_3_ip_dest_ip(input_3_ip_dest_ip), + .input_3_udp_source_port(input_3_udp_source_port), + .input_3_udp_dest_port(input_3_udp_dest_port), + .input_3_udp_length(input_3_udp_length), + .input_3_udp_checksum(input_3_udp_checksum), + .input_3_udp_payload_tdata(input_3_udp_payload_tdata), + .input_3_udp_payload_tkeep(input_3_udp_payload_tkeep), + .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid), + .input_3_udp_payload_tready(input_3_udp_payload_tready), + .input_3_udp_payload_tlast(input_3_udp_payload_tlast), + .input_3_udp_payload_tuser(input_3_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser) +); + +endmodule From 64f6488bf114ab2659e086413c21245963493c8b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 18 Nov 2014 15:17:50 -0800 Subject: [PATCH 113/617] Add UDP demux module and testbench --- rtl/udp_demux.py | 485 ++++++++++++++ rtl/udp_demux_4.v | 589 +++++++++++++++++ rtl/udp_demux_64.py | 498 +++++++++++++++ rtl/udp_demux_64_4.v | 608 ++++++++++++++++++ tb/test_udp_demux_4.py | 1251 ++++++++++++++++++++++++++++++++++++ tb/test_udp_demux_4.v | 473 ++++++++++++++ tb/test_udp_demux_64_4.py | 1276 +++++++++++++++++++++++++++++++++++++ tb/test_udp_demux_64_4.v | 488 ++++++++++++++ 8 files changed, 5668 insertions(+) create mode 100755 rtl/udp_demux.py create mode 100644 rtl/udp_demux_4.v create mode 100755 rtl/udp_demux_64.py create mode 100644 rtl/udp_demux_64_4.v create mode 100755 tb/test_udp_demux_4.py create mode 100644 tb/test_udp_demux_4.v create mode 100755 tb/test_udp_demux_64_4.py create mode 100644 tb/test_udp_demux_64_4.v diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py new file mode 100755 index 000000000..7ddeadefd --- /dev/null +++ b/rtl/udp_demux.py @@ -0,0 +1,485 @@ +#!/usr/bin/env python +"""udp_demux + +Generates an UDP demux with the specified number of ports + +Usage: udp_demux [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "udp_demux_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port UDP demux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * UDP {{n}} port demultiplexer + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * UDP frame input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [7:0] input_udp_payload_tdata, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP frame outputs + */ +{%- for p in ports %} + output wire output_{{p}}_udp_hdr_valid, + input wire output_{{p}}_udp_hdr_ready, + output wire [47:0] output_{{p}}_eth_dest_mac, + output wire [47:0] output_{{p}}_eth_src_mac, + output wire [15:0] output_{{p}}_eth_type, + output wire [3:0] output_{{p}}_ip_version, + output wire [3:0] output_{{p}}_ip_ihl, + output wire [5:0] output_{{p}}_ip_dscp, + output wire [1:0] output_{{p}}_ip_ecn, + output wire [15:0] output_{{p}}_ip_length, + output wire [15:0] output_{{p}}_ip_identification, + output wire [2:0] output_{{p}}_ip_flags, + output wire [12:0] output_{{p}}_ip_fragment_offset, + output wire [7:0] output_{{p}}_ip_ttl, + output wire [7:0] output_{{p}}_ip_protocol, + output wire [15:0] output_{{p}}_ip_header_checksum, + output wire [31:0] output_{{p}}_ip_source_ip, + output wire [31:0] output_{{p}}_ip_dest_ip, + output wire [15:0] output_{{p}}_udp_source_port, + output wire [15:0] output_{{p}}_udp_dest_port, + output wire [15:0] output_{{p}}_udp_length, + output wire [15:0] output_{{p}}_udp_checksum, + output wire [7:0] output_{{p}}_udp_payload_tdata, + output wire output_{{p}}_udp_payload_tvalid, + input wire output_{{p}}_udp_payload_tready, + output wire output_{{p}}_udp_payload_tlast, + output wire output_{{p}}_udp_payload_tuser, +{% endfor %} + /* + * Control + */ + input wire enable, + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; +{% for p in ports %} +reg output_{{p}}_udp_hdr_valid_reg = 0, output_{{p}}_udp_hdr_valid_next; +{%- endfor %} +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; + +// internal datapath +reg [7:0] output_udp_payload_tdata_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; + +assign input_udp_hdr_ready = input_udp_hdr_ready_reg; +assign input_udp_payload_tready = input_udp_payload_tready_reg; +{% for p in ports %} +assign output_{{p}}_udp_hdr_valid = output_{{p}}_udp_hdr_valid_reg; +assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; +assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; +assign output_{{p}}_eth_type = output_eth_type_reg; +assign output_{{p}}_ip_version = output_ip_version_reg; +assign output_{{p}}_ip_ihl = output_ip_ihl_reg; +assign output_{{p}}_ip_dscp = output_ip_dscp_reg; +assign output_{{p}}_ip_ecn = output_ip_ecn_reg; +assign output_{{p}}_ip_length = output_ip_length_reg; +assign output_{{p}}_ip_identification = output_ip_identification_reg; +assign output_{{p}}_ip_flags = output_ip_flags_reg; +assign output_{{p}}_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_{{p}}_ip_ttl = output_ip_ttl_reg; +assign output_{{p}}_ip_protocol = output_ip_protocol_reg; +assign output_{{p}}_ip_header_checksum = output_ip_header_checksum_reg; +assign output_{{p}}_ip_source_ip = output_ip_source_ip_reg; +assign output_{{p}}_ip_dest_ip = output_ip_dest_ip_reg; +assign output_{{p}}_udp_source_port = output_udp_source_port_reg; +assign output_{{p}}_udp_dest_port = output_udp_dest_port_reg; +assign output_{{p}}_udp_length = output_udp_length_reg; +assign output_{{p}}_udp_checksum = output_udp_checksum_reg; +{% endfor %} +// mux for output control signals +reg current_output_udp_hdr_valid; +reg current_output_udp_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_output_udp_hdr_valid = output_{{p}}_udp_hdr_valid; + current_output_udp_hdr_ready = output_{{p}}_udp_hdr_ready; + current_output_tvalid = output_{{p}}_udp_payload_tvalid; + current_output_tready = output_{{p}}_udp_payload_tready; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; + input_udp_payload_tready_next = 0; + +{%- for p in ports %} + output_{{p}}_udp_hdr_valid_next = output_{{p}}_udp_hdr_valid_reg & ~output_{{p}}_udp_hdr_ready; +{%- endfor %} + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + output_udp_source_port_next = output_udp_source_port_reg; + output_udp_dest_port_next = output_udp_dest_port_reg; + output_udp_length_next = output_udp_length_reg; + output_udp_checksum_next = output_udp_checksum_reg; + + if (frame_reg) begin + if (input_udp_payload_tvalid & input_udp_payload_tready) begin + // end of frame detection + frame_next = ~input_udp_payload_tlast; + end + end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_udp_hdr_ready_next = 1; + + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_udp_hdr_valid_next = 1; +{%- endfor %} + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + output_ip_version_next = input_ip_version; + output_ip_ihl_next = input_ip_ihl; + output_ip_dscp_next = input_ip_dscp; + output_ip_ecn_next = input_ip_ecn; + output_ip_length_next = input_ip_length; + output_ip_identification_next = input_ip_identification; + output_ip_flags_next = input_ip_flags; + output_ip_fragment_offset_next = input_ip_fragment_offset; + output_ip_ttl_next = input_ip_ttl; + output_ip_protocol_next = input_ip_protocol; + output_ip_header_checksum_next = input_ip_header_checksum; + output_ip_source_ip_next = input_ip_source_ip; + output_ip_dest_ip_next = input_ip_dest_ip; + output_udp_source_port_next = input_udp_source_port; + output_udp_dest_port_next = input_udp_dest_port; + output_udp_length_next = input_udp_length; + output_udp_checksum_next = input_udp_checksum; + end + + input_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + + output_udp_payload_tdata_int = input_udp_payload_tdata; + output_udp_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tready; + output_udp_payload_tlast_int = input_udp_payload_tlast; + output_udp_payload_tuser_int = input_udp_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; +{%- for p in ports %} + output_{{p}}_udp_hdr_valid_reg <= 0; +{%- endfor %} + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_udp_source_port_reg <= 0; + output_udp_dest_port_reg <= 0; + output_udp_length_reg <= 0; + output_udp_checksum_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; + input_udp_payload_tready_reg <= input_udp_payload_tready_next; +{%- for p in ports %} + output_{{p}}_udp_hdr_valid_reg <= output_{{p}}_udp_hdr_valid_next; +{%- endfor %} + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; + end +end + +// output datapath logic +reg [7:0] output_udp_payload_tdata_reg = 0; +{%- for p in ports %} +reg output_{{p}}_udp_payload_tvalid_reg = 0; +{%- endfor %} +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg [7:0] temp_udp_payload_tdata_reg = 0; +reg temp_udp_payload_tvalid_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; +{% for p in ports %} +assign output_{{p}}_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_{{p}}_udp_payload_tvalid = output_{{p}}_udp_payload_tvalid_reg; +assign output_{{p}}_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_{{p}}_udp_payload_tuser = output_udp_payload_tuser_reg; +{% endfor %} +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_udp_payload_tdata_reg <= 0; +{%- for p in ports %} + output_{{p}}_udp_payload_tvalid_reg <= 0; +{%- endfor %} + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + + if (output_udp_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; +{%- endfor %} + endcase + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; +{%- endfor %} + endcase + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/udp_demux_4.v b/rtl/udp_demux_4.v new file mode 100644 index 000000000..06de23f03 --- /dev/null +++ b/rtl/udp_demux_4.v @@ -0,0 +1,589 @@ +/* + +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 + +/* + * UDP 4 port demultiplexer + */ +module udp_demux_4 +( + input wire clk, + input wire rst, + + /* + * UDP frame input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [7:0] input_udp_payload_tdata, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP frame outputs + */ + output wire output_0_udp_hdr_valid, + input wire output_0_udp_hdr_ready, + output wire [47:0] output_0_eth_dest_mac, + output wire [47:0] output_0_eth_src_mac, + output wire [15:0] output_0_eth_type, + output wire [3:0] output_0_ip_version, + output wire [3:0] output_0_ip_ihl, + output wire [5:0] output_0_ip_dscp, + output wire [1:0] output_0_ip_ecn, + output wire [15:0] output_0_ip_length, + output wire [15:0] output_0_ip_identification, + output wire [2:0] output_0_ip_flags, + output wire [12:0] output_0_ip_fragment_offset, + output wire [7:0] output_0_ip_ttl, + output wire [7:0] output_0_ip_protocol, + output wire [15:0] output_0_ip_header_checksum, + output wire [31:0] output_0_ip_source_ip, + output wire [31:0] output_0_ip_dest_ip, + output wire [15:0] output_0_udp_source_port, + output wire [15:0] output_0_udp_dest_port, + output wire [15:0] output_0_udp_length, + output wire [15:0] output_0_udp_checksum, + output wire [7:0] output_0_udp_payload_tdata, + output wire output_0_udp_payload_tvalid, + input wire output_0_udp_payload_tready, + output wire output_0_udp_payload_tlast, + output wire output_0_udp_payload_tuser, + + output wire output_1_udp_hdr_valid, + input wire output_1_udp_hdr_ready, + output wire [47:0] output_1_eth_dest_mac, + output wire [47:0] output_1_eth_src_mac, + output wire [15:0] output_1_eth_type, + output wire [3:0] output_1_ip_version, + output wire [3:0] output_1_ip_ihl, + output wire [5:0] output_1_ip_dscp, + output wire [1:0] output_1_ip_ecn, + output wire [15:0] output_1_ip_length, + output wire [15:0] output_1_ip_identification, + output wire [2:0] output_1_ip_flags, + output wire [12:0] output_1_ip_fragment_offset, + output wire [7:0] output_1_ip_ttl, + output wire [7:0] output_1_ip_protocol, + output wire [15:0] output_1_ip_header_checksum, + output wire [31:0] output_1_ip_source_ip, + output wire [31:0] output_1_ip_dest_ip, + output wire [15:0] output_1_udp_source_port, + output wire [15:0] output_1_udp_dest_port, + output wire [15:0] output_1_udp_length, + output wire [15:0] output_1_udp_checksum, + output wire [7:0] output_1_udp_payload_tdata, + output wire output_1_udp_payload_tvalid, + input wire output_1_udp_payload_tready, + output wire output_1_udp_payload_tlast, + output wire output_1_udp_payload_tuser, + + output wire output_2_udp_hdr_valid, + input wire output_2_udp_hdr_ready, + output wire [47:0] output_2_eth_dest_mac, + output wire [47:0] output_2_eth_src_mac, + output wire [15:0] output_2_eth_type, + output wire [3:0] output_2_ip_version, + output wire [3:0] output_2_ip_ihl, + output wire [5:0] output_2_ip_dscp, + output wire [1:0] output_2_ip_ecn, + output wire [15:0] output_2_ip_length, + output wire [15:0] output_2_ip_identification, + output wire [2:0] output_2_ip_flags, + output wire [12:0] output_2_ip_fragment_offset, + output wire [7:0] output_2_ip_ttl, + output wire [7:0] output_2_ip_protocol, + output wire [15:0] output_2_ip_header_checksum, + output wire [31:0] output_2_ip_source_ip, + output wire [31:0] output_2_ip_dest_ip, + output wire [15:0] output_2_udp_source_port, + output wire [15:0] output_2_udp_dest_port, + output wire [15:0] output_2_udp_length, + output wire [15:0] output_2_udp_checksum, + output wire [7:0] output_2_udp_payload_tdata, + output wire output_2_udp_payload_tvalid, + input wire output_2_udp_payload_tready, + output wire output_2_udp_payload_tlast, + output wire output_2_udp_payload_tuser, + + output wire output_3_udp_hdr_valid, + input wire output_3_udp_hdr_ready, + output wire [47:0] output_3_eth_dest_mac, + output wire [47:0] output_3_eth_src_mac, + output wire [15:0] output_3_eth_type, + output wire [3:0] output_3_ip_version, + output wire [3:0] output_3_ip_ihl, + output wire [5:0] output_3_ip_dscp, + output wire [1:0] output_3_ip_ecn, + output wire [15:0] output_3_ip_length, + output wire [15:0] output_3_ip_identification, + output wire [2:0] output_3_ip_flags, + output wire [12:0] output_3_ip_fragment_offset, + output wire [7:0] output_3_ip_ttl, + output wire [7:0] output_3_ip_protocol, + output wire [15:0] output_3_ip_header_checksum, + output wire [31:0] output_3_ip_source_ip, + output wire [31:0] output_3_ip_dest_ip, + output wire [15:0] output_3_udp_source_port, + output wire [15:0] output_3_udp_dest_port, + output wire [15:0] output_3_udp_length, + output wire [15:0] output_3_udp_checksum, + output wire [7:0] output_3_udp_payload_tdata, + output wire output_3_udp_payload_tvalid, + input wire output_3_udp_payload_tready, + output wire output_3_udp_payload_tlast, + output wire output_3_udp_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; + +reg output_0_udp_hdr_valid_reg = 0, output_0_udp_hdr_valid_next; +reg output_1_udp_hdr_valid_reg = 0, output_1_udp_hdr_valid_next; +reg output_2_udp_hdr_valid_reg = 0, output_2_udp_hdr_valid_next; +reg output_3_udp_hdr_valid_reg = 0, output_3_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; + +// internal datapath +reg [7:0] output_udp_payload_tdata_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; + +assign input_udp_hdr_ready = input_udp_hdr_ready_reg; +assign input_udp_payload_tready = input_udp_payload_tready_reg; + +assign output_0_udp_hdr_valid = output_0_udp_hdr_valid_reg; +assign output_0_eth_dest_mac = output_eth_dest_mac_reg; +assign output_0_eth_src_mac = output_eth_src_mac_reg; +assign output_0_eth_type = output_eth_type_reg; +assign output_0_ip_version = output_ip_version_reg; +assign output_0_ip_ihl = output_ip_ihl_reg; +assign output_0_ip_dscp = output_ip_dscp_reg; +assign output_0_ip_ecn = output_ip_ecn_reg; +assign output_0_ip_length = output_ip_length_reg; +assign output_0_ip_identification = output_ip_identification_reg; +assign output_0_ip_flags = output_ip_flags_reg; +assign output_0_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_0_ip_ttl = output_ip_ttl_reg; +assign output_0_ip_protocol = output_ip_protocol_reg; +assign output_0_ip_header_checksum = output_ip_header_checksum_reg; +assign output_0_ip_source_ip = output_ip_source_ip_reg; +assign output_0_ip_dest_ip = output_ip_dest_ip_reg; +assign output_0_udp_source_port = output_udp_source_port_reg; +assign output_0_udp_dest_port = output_udp_dest_port_reg; +assign output_0_udp_length = output_udp_length_reg; +assign output_0_udp_checksum = output_udp_checksum_reg; + +assign output_1_udp_hdr_valid = output_1_udp_hdr_valid_reg; +assign output_1_eth_dest_mac = output_eth_dest_mac_reg; +assign output_1_eth_src_mac = output_eth_src_mac_reg; +assign output_1_eth_type = output_eth_type_reg; +assign output_1_ip_version = output_ip_version_reg; +assign output_1_ip_ihl = output_ip_ihl_reg; +assign output_1_ip_dscp = output_ip_dscp_reg; +assign output_1_ip_ecn = output_ip_ecn_reg; +assign output_1_ip_length = output_ip_length_reg; +assign output_1_ip_identification = output_ip_identification_reg; +assign output_1_ip_flags = output_ip_flags_reg; +assign output_1_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_1_ip_ttl = output_ip_ttl_reg; +assign output_1_ip_protocol = output_ip_protocol_reg; +assign output_1_ip_header_checksum = output_ip_header_checksum_reg; +assign output_1_ip_source_ip = output_ip_source_ip_reg; +assign output_1_ip_dest_ip = output_ip_dest_ip_reg; +assign output_1_udp_source_port = output_udp_source_port_reg; +assign output_1_udp_dest_port = output_udp_dest_port_reg; +assign output_1_udp_length = output_udp_length_reg; +assign output_1_udp_checksum = output_udp_checksum_reg; + +assign output_2_udp_hdr_valid = output_2_udp_hdr_valid_reg; +assign output_2_eth_dest_mac = output_eth_dest_mac_reg; +assign output_2_eth_src_mac = output_eth_src_mac_reg; +assign output_2_eth_type = output_eth_type_reg; +assign output_2_ip_version = output_ip_version_reg; +assign output_2_ip_ihl = output_ip_ihl_reg; +assign output_2_ip_dscp = output_ip_dscp_reg; +assign output_2_ip_ecn = output_ip_ecn_reg; +assign output_2_ip_length = output_ip_length_reg; +assign output_2_ip_identification = output_ip_identification_reg; +assign output_2_ip_flags = output_ip_flags_reg; +assign output_2_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_2_ip_ttl = output_ip_ttl_reg; +assign output_2_ip_protocol = output_ip_protocol_reg; +assign output_2_ip_header_checksum = output_ip_header_checksum_reg; +assign output_2_ip_source_ip = output_ip_source_ip_reg; +assign output_2_ip_dest_ip = output_ip_dest_ip_reg; +assign output_2_udp_source_port = output_udp_source_port_reg; +assign output_2_udp_dest_port = output_udp_dest_port_reg; +assign output_2_udp_length = output_udp_length_reg; +assign output_2_udp_checksum = output_udp_checksum_reg; + +assign output_3_udp_hdr_valid = output_3_udp_hdr_valid_reg; +assign output_3_eth_dest_mac = output_eth_dest_mac_reg; +assign output_3_eth_src_mac = output_eth_src_mac_reg; +assign output_3_eth_type = output_eth_type_reg; +assign output_3_ip_version = output_ip_version_reg; +assign output_3_ip_ihl = output_ip_ihl_reg; +assign output_3_ip_dscp = output_ip_dscp_reg; +assign output_3_ip_ecn = output_ip_ecn_reg; +assign output_3_ip_length = output_ip_length_reg; +assign output_3_ip_identification = output_ip_identification_reg; +assign output_3_ip_flags = output_ip_flags_reg; +assign output_3_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_3_ip_ttl = output_ip_ttl_reg; +assign output_3_ip_protocol = output_ip_protocol_reg; +assign output_3_ip_header_checksum = output_ip_header_checksum_reg; +assign output_3_ip_source_ip = output_ip_source_ip_reg; +assign output_3_ip_dest_ip = output_ip_dest_ip_reg; +assign output_3_udp_source_port = output_udp_source_port_reg; +assign output_3_udp_dest_port = output_udp_dest_port_reg; +assign output_3_udp_length = output_udp_length_reg; +assign output_3_udp_checksum = output_udp_checksum_reg; + +// mux for output control signals +reg current_output_udp_hdr_valid; +reg current_output_udp_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) + 2'd0: begin + current_output_udp_hdr_valid = output_0_udp_hdr_valid; + current_output_udp_hdr_ready = output_0_udp_hdr_ready; + current_output_tvalid = output_0_udp_payload_tvalid; + current_output_tready = output_0_udp_payload_tready; + end + 2'd1: begin + current_output_udp_hdr_valid = output_1_udp_hdr_valid; + current_output_udp_hdr_ready = output_1_udp_hdr_ready; + current_output_tvalid = output_1_udp_payload_tvalid; + current_output_tready = output_1_udp_payload_tready; + end + 2'd2: begin + current_output_udp_hdr_valid = output_2_udp_hdr_valid; + current_output_udp_hdr_ready = output_2_udp_hdr_ready; + current_output_tvalid = output_2_udp_payload_tvalid; + current_output_tready = output_2_udp_payload_tready; + end + 2'd3: begin + current_output_udp_hdr_valid = output_3_udp_hdr_valid; + current_output_udp_hdr_ready = output_3_udp_hdr_ready; + current_output_tvalid = output_3_udp_payload_tvalid; + current_output_tready = output_3_udp_payload_tready; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; + input_udp_payload_tready_next = 0; + output_0_udp_hdr_valid_next = output_0_udp_hdr_valid_reg & ~output_0_udp_hdr_ready; + output_1_udp_hdr_valid_next = output_1_udp_hdr_valid_reg & ~output_1_udp_hdr_ready; + output_2_udp_hdr_valid_next = output_2_udp_hdr_valid_reg & ~output_2_udp_hdr_ready; + output_3_udp_hdr_valid_next = output_3_udp_hdr_valid_reg & ~output_3_udp_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + output_udp_source_port_next = output_udp_source_port_reg; + output_udp_dest_port_next = output_udp_dest_port_reg; + output_udp_length_next = output_udp_length_reg; + output_udp_checksum_next = output_udp_checksum_reg; + + if (frame_reg) begin + if (input_udp_payload_tvalid & input_udp_payload_tready) begin + // end of frame detection + frame_next = ~input_udp_payload_tlast; + end + end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_udp_hdr_ready_next = 1; + + case (select) + 2'd0: output_0_udp_hdr_valid_next = 1; + 2'd1: output_1_udp_hdr_valid_next = 1; + 2'd2: output_2_udp_hdr_valid_next = 1; + 2'd3: output_3_udp_hdr_valid_next = 1; + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + output_ip_version_next = input_ip_version; + output_ip_ihl_next = input_ip_ihl; + output_ip_dscp_next = input_ip_dscp; + output_ip_ecn_next = input_ip_ecn; + output_ip_length_next = input_ip_length; + output_ip_identification_next = input_ip_identification; + output_ip_flags_next = input_ip_flags; + output_ip_fragment_offset_next = input_ip_fragment_offset; + output_ip_ttl_next = input_ip_ttl; + output_ip_protocol_next = input_ip_protocol; + output_ip_header_checksum_next = input_ip_header_checksum; + output_ip_source_ip_next = input_ip_source_ip; + output_ip_dest_ip_next = input_ip_dest_ip; + output_udp_source_port_next = input_udp_source_port; + output_udp_dest_port_next = input_udp_dest_port; + output_udp_length_next = input_udp_length; + output_udp_checksum_next = input_udp_checksum; + end + + input_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + + output_udp_payload_tdata_int = input_udp_payload_tdata; + output_udp_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tready; + output_udp_payload_tlast_int = input_udp_payload_tlast; + output_udp_payload_tuser_int = input_udp_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; + output_0_udp_hdr_valid_reg <= 0; + output_1_udp_hdr_valid_reg <= 0; + output_2_udp_hdr_valid_reg <= 0; + output_3_udp_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_udp_source_port_reg <= 0; + output_udp_dest_port_reg <= 0; + output_udp_length_reg <= 0; + output_udp_checksum_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; + input_udp_payload_tready_reg <= input_udp_payload_tready_next; + output_0_udp_hdr_valid_reg <= output_0_udp_hdr_valid_next; + output_1_udp_hdr_valid_reg <= output_1_udp_hdr_valid_next; + output_2_udp_hdr_valid_reg <= output_2_udp_hdr_valid_next; + output_3_udp_hdr_valid_reg <= output_3_udp_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; + end +end + +// output datapath logic +reg [7:0] output_udp_payload_tdata_reg = 0; +reg output_0_udp_payload_tvalid_reg = 0; +reg output_1_udp_payload_tvalid_reg = 0; +reg output_2_udp_payload_tvalid_reg = 0; +reg output_3_udp_payload_tvalid_reg = 0; +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg [7:0] temp_udp_payload_tdata_reg = 0; +reg temp_udp_payload_tvalid_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; + +assign output_0_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_0_udp_payload_tvalid = output_0_udp_payload_tvalid_reg; +assign output_0_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_0_udp_payload_tuser = output_udp_payload_tuser_reg; + +assign output_1_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_1_udp_payload_tvalid = output_1_udp_payload_tvalid_reg; +assign output_1_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_1_udp_payload_tuser = output_udp_payload_tuser_reg; + +assign output_2_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_2_udp_payload_tvalid = output_2_udp_payload_tvalid_reg; +assign output_2_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_2_udp_payload_tuser = output_udp_payload_tuser_reg; + +assign output_3_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_3_udp_payload_tvalid = output_3_udp_payload_tvalid_reg; +assign output_3_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_3_udp_payload_tuser = output_udp_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_udp_payload_tdata_reg <= 0; + output_0_udp_payload_tvalid_reg <= 0; + output_1_udp_payload_tvalid_reg <= 0; + output_2_udp_payload_tvalid_reg <= 0; + output_3_udp_payload_tvalid_reg <= 0; + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + + if (output_udp_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + case (select_reg) + 2'd0: output_0_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + 2'd1: output_1_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + 2'd2: output_2_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + 2'd3: output_3_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + endcase + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + case (select_reg) + 2'd0: output_0_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + 2'd1: output_1_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + 2'd2: output_2_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + 2'd3: output_3_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + endcase + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py new file mode 100755 index 000000000..1ab008f38 --- /dev/null +++ b/rtl/udp_demux_64.py @@ -0,0 +1,498 @@ +#!/usr/bin/env python +"""udp_demux_64 + +Generates an UDP demux with the specified number of ports + +Usage: udp_demux_64 [OPTION]... + -?, --help display this help and exit + -p, --ports specify number of ports + -n, --name specify module name + -o, --output specify output file name +""" + +import io +import sys +import getopt +from math import * +from jinja2 import Template + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + +def main(argv=None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) + except getopt.error as msg: + raise Usage(msg) + # more code, unchanged + except Usage as err: + print(err.msg, file=sys.stderr) + print("for help use --help", file=sys.stderr) + return 2 + + ports = 4 + name = None + out_name = None + + # process options + for o, a in opts: + if o in ('-?', '--help'): + print(__doc__) + sys.exit(0) + if o in ('-p', '--ports'): + ports = int(a) + if o in ('-n', '--name'): + name = a + if o in ('-o', '--output'): + out_name = a + + if name is None: + name = "udp_demux_64_{0}".format(ports) + + if out_name is None: + out_name = name + ".v" + + print("Opening file '%s'..." % out_name) + + try: + out_file = open(out_name, 'w') + except Exception as ex: + print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) + exit(1) + + print("Generating {0} port UDP demux {1}...".format(ports, name)) + + select_width = ceil(log2(ports)) + + t = Template(u"""/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * UDP {{n}} port demultiplexer (64 bit datapath) + */ +module {{name}} +( + input wire clk, + input wire rst, + + /* + * UDP frame input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [63:0] input_udp_payload_tdata, + input wire [7:0] input_udp_payload_tkeep, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP frame outputs + */ +{%- for p in ports %} + output wire output_{{p}}_udp_hdr_valid, + input wire output_{{p}}_udp_hdr_ready, + output wire [47:0] output_{{p}}_eth_dest_mac, + output wire [47:0] output_{{p}}_eth_src_mac, + output wire [15:0] output_{{p}}_eth_type, + output wire [3:0] output_{{p}}_ip_version, + output wire [3:0] output_{{p}}_ip_ihl, + output wire [5:0] output_{{p}}_ip_dscp, + output wire [1:0] output_{{p}}_ip_ecn, + output wire [15:0] output_{{p}}_ip_length, + output wire [15:0] output_{{p}}_ip_identification, + output wire [2:0] output_{{p}}_ip_flags, + output wire [12:0] output_{{p}}_ip_fragment_offset, + output wire [7:0] output_{{p}}_ip_ttl, + output wire [7:0] output_{{p}}_ip_protocol, + output wire [15:0] output_{{p}}_ip_header_checksum, + output wire [31:0] output_{{p}}_ip_source_ip, + output wire [31:0] output_{{p}}_ip_dest_ip, + output wire [15:0] output_{{p}}_udp_source_port, + output wire [15:0] output_{{p}}_udp_dest_port, + output wire [15:0] output_{{p}}_udp_length, + output wire [15:0] output_{{p}}_udp_checksum, + output wire [63:0] output_{{p}}_udp_payload_tdata, + output wire [7:0] output_{{p}}_udp_payload_tkeep, + output wire output_{{p}}_udp_payload_tvalid, + input wire output_{{p}}_udp_payload_tready, + output wire output_{{p}}_udp_payload_tlast, + output wire output_{{p}}_udp_payload_tuser, +{% endfor %} + /* + * Control + */ + input wire enable, + input wire [{{w-1}}:0] select +); + +reg [{{w-1}}:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; +{% for p in ports %} +reg output_{{p}}_udp_hdr_valid_reg = 0, output_{{p}}_udp_hdr_valid_next; +{%- endfor %} +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; + +// internal datapath +reg [63:0] output_udp_payload_tdata_int; +reg [7:0] output_udp_payload_tkeep_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; + +assign input_udp_hdr_ready = input_udp_hdr_ready_reg; +assign input_udp_payload_tready = input_udp_payload_tready_reg; +{% for p in ports %} +assign output_{{p}}_udp_hdr_valid = output_{{p}}_udp_hdr_valid_reg; +assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; +assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; +assign output_{{p}}_eth_type = output_eth_type_reg; +assign output_{{p}}_ip_version = output_ip_version_reg; +assign output_{{p}}_ip_ihl = output_ip_ihl_reg; +assign output_{{p}}_ip_dscp = output_ip_dscp_reg; +assign output_{{p}}_ip_ecn = output_ip_ecn_reg; +assign output_{{p}}_ip_length = output_ip_length_reg; +assign output_{{p}}_ip_identification = output_ip_identification_reg; +assign output_{{p}}_ip_flags = output_ip_flags_reg; +assign output_{{p}}_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_{{p}}_ip_ttl = output_ip_ttl_reg; +assign output_{{p}}_ip_protocol = output_ip_protocol_reg; +assign output_{{p}}_ip_header_checksum = output_ip_header_checksum_reg; +assign output_{{p}}_ip_source_ip = output_ip_source_ip_reg; +assign output_{{p}}_ip_dest_ip = output_ip_dest_ip_reg; +assign output_{{p}}_udp_source_port = output_udp_source_port_reg; +assign output_{{p}}_udp_dest_port = output_udp_dest_port_reg; +assign output_{{p}}_udp_length = output_udp_length_reg; +assign output_{{p}}_udp_checksum = output_udp_checksum_reg; +{% endfor %} +// mux for output control signals +reg current_output_udp_hdr_valid; +reg current_output_udp_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: begin + current_output_udp_hdr_valid = output_{{p}}_udp_hdr_valid; + current_output_udp_hdr_ready = output_{{p}}_udp_hdr_ready; + current_output_tvalid = output_{{p}}_udp_payload_tvalid; + current_output_tready = output_{{p}}_udp_payload_tready; + end +{%- endfor %} + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; + input_udp_payload_tready_next = 0; + +{%- for p in ports %} + output_{{p}}_udp_hdr_valid_next = output_{{p}}_udp_hdr_valid_reg & ~output_{{p}}_udp_hdr_ready; +{%- endfor %} + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + output_udp_source_port_next = output_udp_source_port_reg; + output_udp_dest_port_next = output_udp_dest_port_reg; + output_udp_length_next = output_udp_length_reg; + output_udp_checksum_next = output_udp_checksum_reg; + + if (frame_reg) begin + if (input_udp_payload_tvalid & input_udp_payload_tready) begin + // end of frame detection + frame_next = ~input_udp_payload_tlast; + end + end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_udp_hdr_ready_next = 1; + + case (select) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_udp_hdr_valid_next = 1; +{%- endfor %} + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + output_ip_version_next = input_ip_version; + output_ip_ihl_next = input_ip_ihl; + output_ip_dscp_next = input_ip_dscp; + output_ip_ecn_next = input_ip_ecn; + output_ip_length_next = input_ip_length; + output_ip_identification_next = input_ip_identification; + output_ip_flags_next = input_ip_flags; + output_ip_fragment_offset_next = input_ip_fragment_offset; + output_ip_ttl_next = input_ip_ttl; + output_ip_protocol_next = input_ip_protocol; + output_ip_header_checksum_next = input_ip_header_checksum; + output_ip_source_ip_next = input_ip_source_ip; + output_ip_dest_ip_next = input_ip_dest_ip; + output_udp_source_port_next = input_udp_source_port; + output_udp_dest_port_next = input_udp_dest_port; + output_udp_length_next = input_udp_length; + output_udp_checksum_next = input_udp_checksum; + end + + input_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + + output_udp_payload_tdata_int = input_udp_payload_tdata; + output_udp_payload_tkeep_int = input_udp_payload_tkeep; + output_udp_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tready; + output_udp_payload_tlast_int = input_udp_payload_tlast; + output_udp_payload_tuser_int = input_udp_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; +{%- for p in ports %} + output_{{p}}_udp_hdr_valid_reg <= 0; +{%- endfor %} + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_udp_source_port_reg <= 0; + output_udp_dest_port_reg <= 0; + output_udp_length_reg <= 0; + output_udp_checksum_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; + input_udp_payload_tready_reg <= input_udp_payload_tready_next; +{%- for p in ports %} + output_{{p}}_udp_hdr_valid_reg <= output_{{p}}_udp_hdr_valid_next; +{%- endfor %} + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; + end +end + +// output datapath logic +reg [63:0] output_udp_payload_tdata_reg = 0; +reg [7:0] output_udp_payload_tkeep_reg = 0; +{%- for p in ports %} +reg output_{{p}}_udp_payload_tvalid_reg = 0; +{%- endfor %} +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg [63:0] temp_udp_payload_tdata_reg = 0; +reg [7:0] temp_udp_payload_tkeep_reg = 0; +reg temp_udp_payload_tvalid_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; +{% for p in ports %} +assign output_{{p}}_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_{{p}}_udp_payload_tkeep = output_udp_payload_tkeep_reg; +assign output_{{p}}_udp_payload_tvalid = output_{{p}}_udp_payload_tvalid_reg; +assign output_{{p}}_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_{{p}}_udp_payload_tuser = output_udp_payload_tuser_reg; +{% endfor %} +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_udp_payload_tdata_reg <= 0; + output_udp_payload_tkeep_reg <= 0; +{%- for p in ports %} + output_{{p}}_udp_payload_tvalid_reg <= 0; +{%- endfor %} + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + + if (output_udp_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; +{%- endfor %} + endcase + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + case (select_reg) +{%- for p in ports %} + {{w}}'d{{p}}: output_{{p}}_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; +{%- endfor %} + endcase + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end + end +end + +endmodule + +""") + + out_file.write(t.render( + n=ports, + w=select_width, + name=name, + ports=range(ports) + )) + + print("Done") + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/rtl/udp_demux_64_4.v b/rtl/udp_demux_64_4.v new file mode 100644 index 000000000..bd28b6d7f --- /dev/null +++ b/rtl/udp_demux_64_4.v @@ -0,0 +1,608 @@ +/* + +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 + +/* + * UDP 4 port demultiplexer (64 bit datapath) + */ +module udp_demux_64_4 +( + input wire clk, + input wire rst, + + /* + * UDP frame input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [63:0] input_udp_payload_tdata, + input wire [7:0] input_udp_payload_tkeep, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP frame outputs + */ + output wire output_0_udp_hdr_valid, + input wire output_0_udp_hdr_ready, + output wire [47:0] output_0_eth_dest_mac, + output wire [47:0] output_0_eth_src_mac, + output wire [15:0] output_0_eth_type, + output wire [3:0] output_0_ip_version, + output wire [3:0] output_0_ip_ihl, + output wire [5:0] output_0_ip_dscp, + output wire [1:0] output_0_ip_ecn, + output wire [15:0] output_0_ip_length, + output wire [15:0] output_0_ip_identification, + output wire [2:0] output_0_ip_flags, + output wire [12:0] output_0_ip_fragment_offset, + output wire [7:0] output_0_ip_ttl, + output wire [7:0] output_0_ip_protocol, + output wire [15:0] output_0_ip_header_checksum, + output wire [31:0] output_0_ip_source_ip, + output wire [31:0] output_0_ip_dest_ip, + output wire [15:0] output_0_udp_source_port, + output wire [15:0] output_0_udp_dest_port, + output wire [15:0] output_0_udp_length, + output wire [15:0] output_0_udp_checksum, + output wire [63:0] output_0_udp_payload_tdata, + output wire [7:0] output_0_udp_payload_tkeep, + output wire output_0_udp_payload_tvalid, + input wire output_0_udp_payload_tready, + output wire output_0_udp_payload_tlast, + output wire output_0_udp_payload_tuser, + + output wire output_1_udp_hdr_valid, + input wire output_1_udp_hdr_ready, + output wire [47:0] output_1_eth_dest_mac, + output wire [47:0] output_1_eth_src_mac, + output wire [15:0] output_1_eth_type, + output wire [3:0] output_1_ip_version, + output wire [3:0] output_1_ip_ihl, + output wire [5:0] output_1_ip_dscp, + output wire [1:0] output_1_ip_ecn, + output wire [15:0] output_1_ip_length, + output wire [15:0] output_1_ip_identification, + output wire [2:0] output_1_ip_flags, + output wire [12:0] output_1_ip_fragment_offset, + output wire [7:0] output_1_ip_ttl, + output wire [7:0] output_1_ip_protocol, + output wire [15:0] output_1_ip_header_checksum, + output wire [31:0] output_1_ip_source_ip, + output wire [31:0] output_1_ip_dest_ip, + output wire [15:0] output_1_udp_source_port, + output wire [15:0] output_1_udp_dest_port, + output wire [15:0] output_1_udp_length, + output wire [15:0] output_1_udp_checksum, + output wire [63:0] output_1_udp_payload_tdata, + output wire [7:0] output_1_udp_payload_tkeep, + output wire output_1_udp_payload_tvalid, + input wire output_1_udp_payload_tready, + output wire output_1_udp_payload_tlast, + output wire output_1_udp_payload_tuser, + + output wire output_2_udp_hdr_valid, + input wire output_2_udp_hdr_ready, + output wire [47:0] output_2_eth_dest_mac, + output wire [47:0] output_2_eth_src_mac, + output wire [15:0] output_2_eth_type, + output wire [3:0] output_2_ip_version, + output wire [3:0] output_2_ip_ihl, + output wire [5:0] output_2_ip_dscp, + output wire [1:0] output_2_ip_ecn, + output wire [15:0] output_2_ip_length, + output wire [15:0] output_2_ip_identification, + output wire [2:0] output_2_ip_flags, + output wire [12:0] output_2_ip_fragment_offset, + output wire [7:0] output_2_ip_ttl, + output wire [7:0] output_2_ip_protocol, + output wire [15:0] output_2_ip_header_checksum, + output wire [31:0] output_2_ip_source_ip, + output wire [31:0] output_2_ip_dest_ip, + output wire [15:0] output_2_udp_source_port, + output wire [15:0] output_2_udp_dest_port, + output wire [15:0] output_2_udp_length, + output wire [15:0] output_2_udp_checksum, + output wire [63:0] output_2_udp_payload_tdata, + output wire [7:0] output_2_udp_payload_tkeep, + output wire output_2_udp_payload_tvalid, + input wire output_2_udp_payload_tready, + output wire output_2_udp_payload_tlast, + output wire output_2_udp_payload_tuser, + + output wire output_3_udp_hdr_valid, + input wire output_3_udp_hdr_ready, + output wire [47:0] output_3_eth_dest_mac, + output wire [47:0] output_3_eth_src_mac, + output wire [15:0] output_3_eth_type, + output wire [3:0] output_3_ip_version, + output wire [3:0] output_3_ip_ihl, + output wire [5:0] output_3_ip_dscp, + output wire [1:0] output_3_ip_ecn, + output wire [15:0] output_3_ip_length, + output wire [15:0] output_3_ip_identification, + output wire [2:0] output_3_ip_flags, + output wire [12:0] output_3_ip_fragment_offset, + output wire [7:0] output_3_ip_ttl, + output wire [7:0] output_3_ip_protocol, + output wire [15:0] output_3_ip_header_checksum, + output wire [31:0] output_3_ip_source_ip, + output wire [31:0] output_3_ip_dest_ip, + output wire [15:0] output_3_udp_source_port, + output wire [15:0] output_3_udp_dest_port, + output wire [15:0] output_3_udp_length, + output wire [15:0] output_3_udp_checksum, + output wire [63:0] output_3_udp_payload_tdata, + output wire [7:0] output_3_udp_payload_tkeep, + output wire output_3_udp_payload_tvalid, + input wire output_3_udp_payload_tready, + output wire output_3_udp_payload_tlast, + output wire output_3_udp_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [1:0] select +); + +reg [1:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; + +reg output_0_udp_hdr_valid_reg = 0, output_0_udp_hdr_valid_next; +reg output_1_udp_hdr_valid_reg = 0, output_1_udp_hdr_valid_next; +reg output_2_udp_hdr_valid_reg = 0, output_2_udp_hdr_valid_next; +reg output_3_udp_hdr_valid_reg = 0, output_3_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; + +// internal datapath +reg [63:0] output_udp_payload_tdata_int; +reg [7:0] output_udp_payload_tkeep_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; + +assign input_udp_hdr_ready = input_udp_hdr_ready_reg; +assign input_udp_payload_tready = input_udp_payload_tready_reg; + +assign output_0_udp_hdr_valid = output_0_udp_hdr_valid_reg; +assign output_0_eth_dest_mac = output_eth_dest_mac_reg; +assign output_0_eth_src_mac = output_eth_src_mac_reg; +assign output_0_eth_type = output_eth_type_reg; +assign output_0_ip_version = output_ip_version_reg; +assign output_0_ip_ihl = output_ip_ihl_reg; +assign output_0_ip_dscp = output_ip_dscp_reg; +assign output_0_ip_ecn = output_ip_ecn_reg; +assign output_0_ip_length = output_ip_length_reg; +assign output_0_ip_identification = output_ip_identification_reg; +assign output_0_ip_flags = output_ip_flags_reg; +assign output_0_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_0_ip_ttl = output_ip_ttl_reg; +assign output_0_ip_protocol = output_ip_protocol_reg; +assign output_0_ip_header_checksum = output_ip_header_checksum_reg; +assign output_0_ip_source_ip = output_ip_source_ip_reg; +assign output_0_ip_dest_ip = output_ip_dest_ip_reg; +assign output_0_udp_source_port = output_udp_source_port_reg; +assign output_0_udp_dest_port = output_udp_dest_port_reg; +assign output_0_udp_length = output_udp_length_reg; +assign output_0_udp_checksum = output_udp_checksum_reg; + +assign output_1_udp_hdr_valid = output_1_udp_hdr_valid_reg; +assign output_1_eth_dest_mac = output_eth_dest_mac_reg; +assign output_1_eth_src_mac = output_eth_src_mac_reg; +assign output_1_eth_type = output_eth_type_reg; +assign output_1_ip_version = output_ip_version_reg; +assign output_1_ip_ihl = output_ip_ihl_reg; +assign output_1_ip_dscp = output_ip_dscp_reg; +assign output_1_ip_ecn = output_ip_ecn_reg; +assign output_1_ip_length = output_ip_length_reg; +assign output_1_ip_identification = output_ip_identification_reg; +assign output_1_ip_flags = output_ip_flags_reg; +assign output_1_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_1_ip_ttl = output_ip_ttl_reg; +assign output_1_ip_protocol = output_ip_protocol_reg; +assign output_1_ip_header_checksum = output_ip_header_checksum_reg; +assign output_1_ip_source_ip = output_ip_source_ip_reg; +assign output_1_ip_dest_ip = output_ip_dest_ip_reg; +assign output_1_udp_source_port = output_udp_source_port_reg; +assign output_1_udp_dest_port = output_udp_dest_port_reg; +assign output_1_udp_length = output_udp_length_reg; +assign output_1_udp_checksum = output_udp_checksum_reg; + +assign output_2_udp_hdr_valid = output_2_udp_hdr_valid_reg; +assign output_2_eth_dest_mac = output_eth_dest_mac_reg; +assign output_2_eth_src_mac = output_eth_src_mac_reg; +assign output_2_eth_type = output_eth_type_reg; +assign output_2_ip_version = output_ip_version_reg; +assign output_2_ip_ihl = output_ip_ihl_reg; +assign output_2_ip_dscp = output_ip_dscp_reg; +assign output_2_ip_ecn = output_ip_ecn_reg; +assign output_2_ip_length = output_ip_length_reg; +assign output_2_ip_identification = output_ip_identification_reg; +assign output_2_ip_flags = output_ip_flags_reg; +assign output_2_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_2_ip_ttl = output_ip_ttl_reg; +assign output_2_ip_protocol = output_ip_protocol_reg; +assign output_2_ip_header_checksum = output_ip_header_checksum_reg; +assign output_2_ip_source_ip = output_ip_source_ip_reg; +assign output_2_ip_dest_ip = output_ip_dest_ip_reg; +assign output_2_udp_source_port = output_udp_source_port_reg; +assign output_2_udp_dest_port = output_udp_dest_port_reg; +assign output_2_udp_length = output_udp_length_reg; +assign output_2_udp_checksum = output_udp_checksum_reg; + +assign output_3_udp_hdr_valid = output_3_udp_hdr_valid_reg; +assign output_3_eth_dest_mac = output_eth_dest_mac_reg; +assign output_3_eth_src_mac = output_eth_src_mac_reg; +assign output_3_eth_type = output_eth_type_reg; +assign output_3_ip_version = output_ip_version_reg; +assign output_3_ip_ihl = output_ip_ihl_reg; +assign output_3_ip_dscp = output_ip_dscp_reg; +assign output_3_ip_ecn = output_ip_ecn_reg; +assign output_3_ip_length = output_ip_length_reg; +assign output_3_ip_identification = output_ip_identification_reg; +assign output_3_ip_flags = output_ip_flags_reg; +assign output_3_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_3_ip_ttl = output_ip_ttl_reg; +assign output_3_ip_protocol = output_ip_protocol_reg; +assign output_3_ip_header_checksum = output_ip_header_checksum_reg; +assign output_3_ip_source_ip = output_ip_source_ip_reg; +assign output_3_ip_dest_ip = output_ip_dest_ip_reg; +assign output_3_udp_source_port = output_udp_source_port_reg; +assign output_3_udp_dest_port = output_udp_dest_port_reg; +assign output_3_udp_length = output_udp_length_reg; +assign output_3_udp_checksum = output_udp_checksum_reg; + +// mux for output control signals +reg current_output_udp_hdr_valid; +reg current_output_udp_hdr_ready; +reg current_output_tvalid; +reg current_output_tready; +always @* begin + case (select_reg) + 2'd0: begin + current_output_udp_hdr_valid = output_0_udp_hdr_valid; + current_output_udp_hdr_ready = output_0_udp_hdr_ready; + current_output_tvalid = output_0_udp_payload_tvalid; + current_output_tready = output_0_udp_payload_tready; + end + 2'd1: begin + current_output_udp_hdr_valid = output_1_udp_hdr_valid; + current_output_udp_hdr_ready = output_1_udp_hdr_ready; + current_output_tvalid = output_1_udp_payload_tvalid; + current_output_tready = output_1_udp_payload_tready; + end + 2'd2: begin + current_output_udp_hdr_valid = output_2_udp_hdr_valid; + current_output_udp_hdr_ready = output_2_udp_hdr_ready; + current_output_tvalid = output_2_udp_payload_tvalid; + current_output_tready = output_2_udp_payload_tready; + end + 2'd3: begin + current_output_udp_hdr_valid = output_3_udp_hdr_valid; + current_output_udp_hdr_ready = output_3_udp_hdr_ready; + current_output_tvalid = output_3_udp_payload_tvalid; + current_output_tready = output_3_udp_payload_tready; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; + input_udp_payload_tready_next = 0; + output_0_udp_hdr_valid_next = output_0_udp_hdr_valid_reg & ~output_0_udp_hdr_ready; + output_1_udp_hdr_valid_next = output_1_udp_hdr_valid_reg & ~output_1_udp_hdr_ready; + output_2_udp_hdr_valid_next = output_2_udp_hdr_valid_reg & ~output_2_udp_hdr_ready; + output_3_udp_hdr_valid_next = output_3_udp_hdr_valid_reg & ~output_3_udp_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + output_udp_source_port_next = output_udp_source_port_reg; + output_udp_dest_port_next = output_udp_dest_port_reg; + output_udp_length_next = output_udp_length_reg; + output_udp_checksum_next = output_udp_checksum_reg; + + if (frame_reg) begin + if (input_udp_payload_tvalid & input_udp_payload_tready) begin + // end of frame detection + frame_next = ~input_udp_payload_tlast; + end + end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + input_udp_hdr_ready_next = 1; + + case (select) + 2'd0: output_0_udp_hdr_valid_next = 1; + 2'd1: output_1_udp_hdr_valid_next = 1; + 2'd2: output_2_udp_hdr_valid_next = 1; + 2'd3: output_3_udp_hdr_valid_next = 1; + endcase + output_eth_dest_mac_next = input_eth_dest_mac; + output_eth_src_mac_next = input_eth_src_mac; + output_eth_type_next = input_eth_type; + output_ip_version_next = input_ip_version; + output_ip_ihl_next = input_ip_ihl; + output_ip_dscp_next = input_ip_dscp; + output_ip_ecn_next = input_ip_ecn; + output_ip_length_next = input_ip_length; + output_ip_identification_next = input_ip_identification; + output_ip_flags_next = input_ip_flags; + output_ip_fragment_offset_next = input_ip_fragment_offset; + output_ip_ttl_next = input_ip_ttl; + output_ip_protocol_next = input_ip_protocol; + output_ip_header_checksum_next = input_ip_header_checksum; + output_ip_source_ip_next = input_ip_source_ip; + output_ip_dest_ip_next = input_ip_dest_ip; + output_udp_source_port_next = input_udp_source_port; + output_udp_dest_port_next = input_udp_dest_port; + output_udp_length_next = input_udp_length; + output_udp_checksum_next = input_udp_checksum; + end + + input_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; + + output_udp_payload_tdata_int = input_udp_payload_tdata; + output_udp_payload_tkeep_int = input_udp_payload_tkeep; + output_udp_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tready; + output_udp_payload_tlast_int = input_udp_payload_tlast; + output_udp_payload_tuser_int = input_udp_payload_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_udp_hdr_ready_reg <= 0; + input_udp_payload_tready_reg <= 0; + output_0_udp_hdr_valid_reg <= 0; + output_1_udp_hdr_valid_reg <= 0; + output_2_udp_hdr_valid_reg <= 0; + output_3_udp_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + output_udp_source_port_reg <= 0; + output_udp_dest_port_reg <= 0; + output_udp_length_reg <= 0; + output_udp_checksum_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; + input_udp_payload_tready_reg <= input_udp_payload_tready_next; + output_0_udp_hdr_valid_reg <= output_0_udp_hdr_valid_next; + output_1_udp_hdr_valid_reg <= output_1_udp_hdr_valid_next; + output_2_udp_hdr_valid_reg <= output_2_udp_hdr_valid_next; + output_3_udp_hdr_valid_reg <= output_3_udp_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; + end +end + +// output datapath logic +reg [63:0] output_udp_payload_tdata_reg = 0; +reg [7:0] output_udp_payload_tkeep_reg = 0; +reg output_0_udp_payload_tvalid_reg = 0; +reg output_1_udp_payload_tvalid_reg = 0; +reg output_2_udp_payload_tvalid_reg = 0; +reg output_3_udp_payload_tvalid_reg = 0; +reg output_udp_payload_tlast_reg = 0; +reg output_udp_payload_tuser_reg = 0; + +reg [63:0] temp_udp_payload_tdata_reg = 0; +reg [7:0] temp_udp_payload_tkeep_reg = 0; +reg temp_udp_payload_tvalid_reg = 0; +reg temp_udp_payload_tlast_reg = 0; +reg temp_udp_payload_tuser_reg = 0; + +assign output_0_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_0_udp_payload_tkeep = output_udp_payload_tkeep_reg; +assign output_0_udp_payload_tvalid = output_0_udp_payload_tvalid_reg; +assign output_0_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_0_udp_payload_tuser = output_udp_payload_tuser_reg; + +assign output_1_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_1_udp_payload_tkeep = output_udp_payload_tkeep_reg; +assign output_1_udp_payload_tvalid = output_1_udp_payload_tvalid_reg; +assign output_1_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_1_udp_payload_tuser = output_udp_payload_tuser_reg; + +assign output_2_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_2_udp_payload_tkeep = output_udp_payload_tkeep_reg; +assign output_2_udp_payload_tvalid = output_2_udp_payload_tvalid_reg; +assign output_2_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_2_udp_payload_tuser = output_udp_payload_tuser_reg; + +assign output_3_udp_payload_tdata = output_udp_payload_tdata_reg; +assign output_3_udp_payload_tkeep = output_udp_payload_tkeep_reg; +assign output_3_udp_payload_tvalid = output_3_udp_payload_tvalid_reg; +assign output_3_udp_payload_tlast = output_udp_payload_tlast_reg; +assign output_3_udp_payload_tuser = output_udp_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_udp_payload_tdata_reg <= 0; + output_udp_payload_tkeep_reg <= 0; + output_0_udp_payload_tvalid_reg <= 0; + output_1_udp_payload_tvalid_reg <= 0; + output_2_udp_payload_tvalid_reg <= 0; + output_3_udp_payload_tvalid_reg <= 0; + output_udp_payload_tlast_reg <= 0; + output_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int <= 0; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + + if (output_udp_payload_tready_int) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + case (select_reg) + 2'd0: output_0_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + 2'd1: output_1_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + 2'd2: output_2_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + 2'd3: output_3_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + endcase + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + case (select_reg) + 2'd0: output_0_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + 2'd1: output_1_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + 2'd2: output_2_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + 2'd3: output_3_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; + endcase + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + temp_udp_payload_tdata_reg <= 0; + temp_udp_payload_tkeep_reg <= 0; + temp_udp_payload_tvalid_reg <= 0; + temp_udp_payload_tlast_reg <= 0; + temp_udp_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_udp_demux_4.py b/tb/test_udp_demux_4.py new file mode 100755 index 000000000..6c3ff3411 --- /dev/null +++ b/tb/test_udp_demux_4.py @@ -0,0 +1,1251 @@ +#!/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 udp_ep + +module = 'udp_demux_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp_demux_4(clk, + rst, + current_test, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_0_udp_hdr_valid, + output_0_udp_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_udp_source_port, + output_0_udp_dest_port, + output_0_udp_length, + output_0_udp_checksum, + output_0_udp_payload_tdata, + output_0_udp_payload_tvalid, + output_0_udp_payload_tready, + output_0_udp_payload_tlast, + output_0_udp_payload_tuser, + output_1_udp_hdr_valid, + output_1_udp_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_udp_source_port, + output_1_udp_dest_port, + output_1_udp_length, + output_1_udp_checksum, + output_1_udp_payload_tdata, + output_1_udp_payload_tvalid, + output_1_udp_payload_tready, + output_1_udp_payload_tlast, + output_1_udp_payload_tuser, + output_2_udp_hdr_valid, + output_2_udp_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_udp_source_port, + output_2_udp_dest_port, + output_2_udp_length, + output_2_udp_checksum, + output_2_udp_payload_tdata, + output_2_udp_payload_tvalid, + output_2_udp_payload_tready, + output_2_udp_payload_tlast, + output_2_udp_payload_tuser, + output_3_udp_hdr_valid, + output_3_udp_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_udp_source_port, + output_3_udp_dest_port, + output_3_udp_length, + output_3_udp_checksum, + output_3_udp_payload_tdata, + output_3_udp_payload_tvalid, + output_3_udp_payload_tready, + output_3_udp_payload_tlast, + output_3_udp_payload_tuser, + + enable, + select): + + 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_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_length=input_udp_length, + input_udp_checksum=input_udp_checksum, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_0_udp_hdr_valid=output_0_udp_hdr_valid, + output_0_udp_hdr_ready=output_0_udp_hdr_ready, + output_0_eth_dest_mac=output_0_eth_dest_mac, + output_0_eth_src_mac=output_0_eth_src_mac, + output_0_eth_type=output_0_eth_type, + output_0_ip_version=output_0_ip_version, + output_0_ip_ihl=output_0_ip_ihl, + output_0_ip_dscp=output_0_ip_dscp, + output_0_ip_ecn=output_0_ip_ecn, + output_0_ip_length=output_0_ip_length, + output_0_ip_identification=output_0_ip_identification, + output_0_ip_flags=output_0_ip_flags, + output_0_ip_fragment_offset=output_0_ip_fragment_offset, + output_0_ip_ttl=output_0_ip_ttl, + output_0_ip_protocol=output_0_ip_protocol, + output_0_ip_header_checksum=output_0_ip_header_checksum, + output_0_ip_source_ip=output_0_ip_source_ip, + output_0_ip_dest_ip=output_0_ip_dest_ip, + output_0_udp_source_port=output_0_udp_source_port, + output_0_udp_dest_port=output_0_udp_dest_port, + output_0_udp_length=output_0_udp_length, + output_0_udp_checksum=output_0_udp_checksum, + output_0_udp_payload_tdata=output_0_udp_payload_tdata, + output_0_udp_payload_tvalid=output_0_udp_payload_tvalid, + output_0_udp_payload_tready=output_0_udp_payload_tready, + output_0_udp_payload_tlast=output_0_udp_payload_tlast, + output_0_udp_payload_tuser=output_0_udp_payload_tuser, + output_1_udp_hdr_valid=output_1_udp_hdr_valid, + output_1_udp_hdr_ready=output_1_udp_hdr_ready, + output_1_eth_dest_mac=output_1_eth_dest_mac, + output_1_eth_src_mac=output_1_eth_src_mac, + output_1_eth_type=output_1_eth_type, + output_1_ip_version=output_1_ip_version, + output_1_ip_ihl=output_1_ip_ihl, + output_1_ip_dscp=output_1_ip_dscp, + output_1_ip_ecn=output_1_ip_ecn, + output_1_ip_length=output_1_ip_length, + output_1_ip_identification=output_1_ip_identification, + output_1_ip_flags=output_1_ip_flags, + output_1_ip_fragment_offset=output_1_ip_fragment_offset, + output_1_ip_ttl=output_1_ip_ttl, + output_1_ip_protocol=output_1_ip_protocol, + output_1_ip_header_checksum=output_1_ip_header_checksum, + output_1_ip_source_ip=output_1_ip_source_ip, + output_1_ip_dest_ip=output_1_ip_dest_ip, + output_1_udp_source_port=output_1_udp_source_port, + output_1_udp_dest_port=output_1_udp_dest_port, + output_1_udp_length=output_1_udp_length, + output_1_udp_checksum=output_1_udp_checksum, + output_1_udp_payload_tdata=output_1_udp_payload_tdata, + output_1_udp_payload_tvalid=output_1_udp_payload_tvalid, + output_1_udp_payload_tready=output_1_udp_payload_tready, + output_1_udp_payload_tlast=output_1_udp_payload_tlast, + output_1_udp_payload_tuser=output_1_udp_payload_tuser, + output_2_udp_hdr_valid=output_2_udp_hdr_valid, + output_2_udp_hdr_ready=output_2_udp_hdr_ready, + output_2_eth_dest_mac=output_2_eth_dest_mac, + output_2_eth_src_mac=output_2_eth_src_mac, + output_2_eth_type=output_2_eth_type, + output_2_ip_version=output_2_ip_version, + output_2_ip_ihl=output_2_ip_ihl, + output_2_ip_dscp=output_2_ip_dscp, + output_2_ip_ecn=output_2_ip_ecn, + output_2_ip_length=output_2_ip_length, + output_2_ip_identification=output_2_ip_identification, + output_2_ip_flags=output_2_ip_flags, + output_2_ip_fragment_offset=output_2_ip_fragment_offset, + output_2_ip_ttl=output_2_ip_ttl, + output_2_ip_protocol=output_2_ip_protocol, + output_2_ip_header_checksum=output_2_ip_header_checksum, + output_2_ip_source_ip=output_2_ip_source_ip, + output_2_ip_dest_ip=output_2_ip_dest_ip, + output_2_udp_source_port=output_2_udp_source_port, + output_2_udp_dest_port=output_2_udp_dest_port, + output_2_udp_length=output_2_udp_length, + output_2_udp_checksum=output_2_udp_checksum, + output_2_udp_payload_tdata=output_2_udp_payload_tdata, + output_2_udp_payload_tvalid=output_2_udp_payload_tvalid, + output_2_udp_payload_tready=output_2_udp_payload_tready, + output_2_udp_payload_tlast=output_2_udp_payload_tlast, + output_2_udp_payload_tuser=output_2_udp_payload_tuser, + output_3_udp_hdr_valid=output_3_udp_hdr_valid, + output_3_udp_hdr_ready=output_3_udp_hdr_ready, + output_3_eth_dest_mac=output_3_eth_dest_mac, + output_3_eth_src_mac=output_3_eth_src_mac, + output_3_eth_type=output_3_eth_type, + output_3_ip_version=output_3_ip_version, + output_3_ip_ihl=output_3_ip_ihl, + output_3_ip_dscp=output_3_ip_dscp, + output_3_ip_ecn=output_3_ip_ecn, + output_3_ip_length=output_3_ip_length, + output_3_ip_identification=output_3_ip_identification, + output_3_ip_flags=output_3_ip_flags, + output_3_ip_fragment_offset=output_3_ip_fragment_offset, + output_3_ip_ttl=output_3_ip_ttl, + output_3_ip_protocol=output_3_ip_protocol, + output_3_ip_header_checksum=output_3_ip_header_checksum, + output_3_ip_source_ip=output_3_ip_source_ip, + output_3_ip_dest_ip=output_3_ip_dest_ip, + output_3_udp_source_port=output_3_udp_source_port, + output_3_udp_dest_port=output_3_udp_dest_port, + output_3_udp_length=output_3_udp_length, + output_3_udp_checksum=output_3_udp_checksum, + output_3_udp_payload_tdata=output_3_udp_payload_tdata, + output_3_udp_payload_tvalid=output_3_udp_payload_tvalid, + output_3_udp_payload_tready=output_3_udp_payload_tready, + output_3_udp_payload_tlast=output_3_udp_payload_tlast, + output_3_udp_payload_tuser=output_3_udp_payload_tuser, + + enable=enable, + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_udp_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_length = Signal(intbv(0)[16:]) + input_udp_checksum = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + + output_0_udp_hdr_ready = Signal(bool(0)) + output_0_udp_payload_tready = Signal(bool(0)) + output_1_udp_hdr_ready = Signal(bool(0)) + output_1_udp_payload_tready = Signal(bool(0)) + output_2_udp_hdr_ready = Signal(bool(0)) + output_2_udp_payload_tready = Signal(bool(0)) + output_3_udp_hdr_ready = Signal(bool(0)) + output_3_udp_payload_tready = Signal(bool(0)) + + enable = Signal(bool(0)) + select = Signal(intbv(0)[2:]) + + # Outputs + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + + output_0_udp_hdr_valid = Signal(bool(0)) + output_0_eth_dest_mac = Signal(intbv(0)[48:]) + output_0_eth_src_mac = Signal(intbv(0)[48:]) + output_0_eth_type = Signal(intbv(0)[16:]) + output_0_ip_version = Signal(intbv(0)[4:]) + output_0_ip_ihl = Signal(intbv(0)[4:]) + output_0_ip_dscp = Signal(intbv(0)[6:]) + output_0_ip_ecn = Signal(intbv(0)[2:]) + output_0_ip_length = Signal(intbv(0)[16:]) + output_0_ip_identification = Signal(intbv(0)[16:]) + output_0_ip_flags = Signal(intbv(0)[3:]) + output_0_ip_fragment_offset = Signal(intbv(0)[13:]) + output_0_ip_ttl = Signal(intbv(0)[8:]) + output_0_ip_protocol = Signal(intbv(0)[8:]) + output_0_ip_header_checksum = Signal(intbv(0)[16:]) + output_0_ip_source_ip = Signal(intbv(0)[32:]) + output_0_ip_dest_ip = Signal(intbv(0)[32:]) + output_0_udp_source_port = Signal(intbv(0)[16:]) + output_0_udp_dest_port = Signal(intbv(0)[16:]) + output_0_udp_length = Signal(intbv(0)[16:]) + output_0_udp_checksum = Signal(intbv(0)[16:]) + output_0_udp_payload_tdata = Signal(intbv(0)[8:]) + output_0_udp_payload_tvalid = Signal(bool(0)) + output_0_udp_payload_tlast = Signal(bool(0)) + output_0_udp_payload_tuser = Signal(bool(0)) + output_1_udp_hdr_valid = Signal(bool(0)) + output_1_eth_dest_mac = Signal(intbv(0)[48:]) + output_1_eth_src_mac = Signal(intbv(0)[48:]) + output_1_eth_type = Signal(intbv(0)[16:]) + output_1_ip_version = Signal(intbv(0)[4:]) + output_1_ip_ihl = Signal(intbv(0)[4:]) + output_1_ip_dscp = Signal(intbv(0)[6:]) + output_1_ip_ecn = Signal(intbv(0)[2:]) + output_1_ip_length = Signal(intbv(0)[16:]) + output_1_ip_identification = Signal(intbv(0)[16:]) + output_1_ip_flags = Signal(intbv(0)[3:]) + output_1_ip_fragment_offset = Signal(intbv(0)[13:]) + output_1_ip_ttl = Signal(intbv(0)[8:]) + output_1_ip_protocol = Signal(intbv(0)[8:]) + output_1_ip_header_checksum = Signal(intbv(0)[16:]) + output_1_ip_source_ip = Signal(intbv(0)[32:]) + output_1_ip_dest_ip = Signal(intbv(0)[32:]) + output_1_udp_source_port = Signal(intbv(0)[16:]) + output_1_udp_dest_port = Signal(intbv(0)[16:]) + output_1_udp_length = Signal(intbv(0)[16:]) + output_1_udp_checksum = Signal(intbv(0)[16:]) + output_1_udp_payload_tdata = Signal(intbv(0)[8:]) + output_1_udp_payload_tvalid = Signal(bool(0)) + output_1_udp_payload_tlast = Signal(bool(0)) + output_1_udp_payload_tuser = Signal(bool(0)) + output_2_udp_hdr_valid = Signal(bool(0)) + output_2_eth_dest_mac = Signal(intbv(0)[48:]) + output_2_eth_src_mac = Signal(intbv(0)[48:]) + output_2_eth_type = Signal(intbv(0)[16:]) + output_2_ip_version = Signal(intbv(0)[4:]) + output_2_ip_ihl = Signal(intbv(0)[4:]) + output_2_ip_dscp = Signal(intbv(0)[6:]) + output_2_ip_ecn = Signal(intbv(0)[2:]) + output_2_ip_length = Signal(intbv(0)[16:]) + output_2_ip_identification = Signal(intbv(0)[16:]) + output_2_ip_flags = Signal(intbv(0)[3:]) + output_2_ip_fragment_offset = Signal(intbv(0)[13:]) + output_2_ip_ttl = Signal(intbv(0)[8:]) + output_2_ip_protocol = Signal(intbv(0)[8:]) + output_2_ip_header_checksum = Signal(intbv(0)[16:]) + output_2_ip_source_ip = Signal(intbv(0)[32:]) + output_2_ip_dest_ip = Signal(intbv(0)[32:]) + output_2_udp_source_port = Signal(intbv(0)[16:]) + output_2_udp_dest_port = Signal(intbv(0)[16:]) + output_2_udp_length = Signal(intbv(0)[16:]) + output_2_udp_checksum = Signal(intbv(0)[16:]) + output_2_udp_payload_tdata = Signal(intbv(0)[8:]) + output_2_udp_payload_tvalid = Signal(bool(0)) + output_2_udp_payload_tlast = Signal(bool(0)) + output_2_udp_payload_tuser = Signal(bool(0)) + output_3_udp_hdr_valid = Signal(bool(0)) + output_3_eth_dest_mac = Signal(intbv(0)[48:]) + output_3_eth_src_mac = Signal(intbv(0)[48:]) + output_3_eth_type = Signal(intbv(0)[16:]) + output_3_ip_version = Signal(intbv(0)[4:]) + output_3_ip_ihl = Signal(intbv(0)[4:]) + output_3_ip_dscp = Signal(intbv(0)[6:]) + output_3_ip_ecn = Signal(intbv(0)[2:]) + output_3_ip_length = Signal(intbv(0)[16:]) + output_3_ip_identification = Signal(intbv(0)[16:]) + output_3_ip_flags = Signal(intbv(0)[3:]) + output_3_ip_fragment_offset = Signal(intbv(0)[13:]) + output_3_ip_ttl = Signal(intbv(0)[8:]) + output_3_ip_protocol = Signal(intbv(0)[8:]) + output_3_ip_header_checksum = Signal(intbv(0)[16:]) + output_3_ip_source_ip = Signal(intbv(0)[32:]) + output_3_ip_dest_ip = Signal(intbv(0)[32:]) + output_3_udp_source_port = Signal(intbv(0)[16:]) + output_3_udp_dest_port = Signal(intbv(0)[16:]) + output_3_udp_length = Signal(intbv(0)[16:]) + output_3_udp_checksum = Signal(intbv(0)[16:]) + output_3_udp_payload_tdata = Signal(intbv(0)[8:]) + output_3_udp_payload_tvalid = Signal(bool(0)) + output_3_udp_payload_tlast = Signal(bool(0)) + output_3_udp_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_pause = Signal(bool(0)) + + source = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_udp_hdr_ready, + udp_hdr_valid=input_udp_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_length=input_udp_length, + udp_checksum=input_udp_checksum, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink_0 = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_0_udp_hdr_ready, + udp_hdr_valid=output_0_udp_hdr_valid, + eth_dest_mac=output_0_eth_dest_mac, + eth_src_mac=output_0_eth_src_mac, + eth_type=output_0_eth_type, + ip_version=output_0_ip_version, + ip_ihl=output_0_ip_ihl, + ip_dscp=output_0_ip_dscp, + ip_ecn=output_0_ip_ecn, + ip_length=output_0_ip_length, + ip_identification=output_0_ip_identification, + ip_flags=output_0_ip_flags, + ip_fragment_offset=output_0_ip_fragment_offset, + ip_ttl=output_0_ip_ttl, + ip_protocol=output_0_ip_protocol, + ip_header_checksum=output_0_ip_header_checksum, + ip_source_ip=output_0_ip_source_ip, + ip_dest_ip=output_0_ip_dest_ip, + udp_source_port=output_0_udp_source_port, + udp_dest_port=output_0_udp_dest_port, + udp_length=output_0_udp_length, + udp_checksum=output_0_udp_checksum, + udp_payload_tdata=output_0_udp_payload_tdata, + udp_payload_tvalid=output_0_udp_payload_tvalid, + udp_payload_tready=output_0_udp_payload_tready, + udp_payload_tlast=output_0_udp_payload_tlast, + udp_payload_tuser=output_0_udp_payload_tuser, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + + sink_1 = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_1_udp_hdr_ready, + udp_hdr_valid=output_1_udp_hdr_valid, + eth_dest_mac=output_1_eth_dest_mac, + eth_src_mac=output_1_eth_src_mac, + eth_type=output_1_eth_type, + ip_version=output_1_ip_version, + ip_ihl=output_1_ip_ihl, + ip_dscp=output_1_ip_dscp, + ip_ecn=output_1_ip_ecn, + ip_length=output_1_ip_length, + ip_identification=output_1_ip_identification, + ip_flags=output_1_ip_flags, + ip_fragment_offset=output_1_ip_fragment_offset, + ip_ttl=output_1_ip_ttl, + ip_protocol=output_1_ip_protocol, + ip_header_checksum=output_1_ip_header_checksum, + ip_source_ip=output_1_ip_source_ip, + ip_dest_ip=output_1_ip_dest_ip, + udp_source_port=output_1_udp_source_port, + udp_dest_port=output_1_udp_dest_port, + udp_length=output_1_udp_length, + udp_checksum=output_1_udp_checksum, + udp_payload_tdata=output_1_udp_payload_tdata, + udp_payload_tvalid=output_1_udp_payload_tvalid, + udp_payload_tready=output_1_udp_payload_tready, + udp_payload_tlast=output_1_udp_payload_tlast, + udp_payload_tuser=output_1_udp_payload_tuser, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + + sink_2 = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_2_udp_hdr_ready, + udp_hdr_valid=output_2_udp_hdr_valid, + eth_dest_mac=output_2_eth_dest_mac, + eth_src_mac=output_2_eth_src_mac, + eth_type=output_2_eth_type, + ip_version=output_2_ip_version, + ip_ihl=output_2_ip_ihl, + ip_dscp=output_2_ip_dscp, + ip_ecn=output_2_ip_ecn, + ip_length=output_2_ip_length, + ip_identification=output_2_ip_identification, + ip_flags=output_2_ip_flags, + ip_fragment_offset=output_2_ip_fragment_offset, + ip_ttl=output_2_ip_ttl, + ip_protocol=output_2_ip_protocol, + ip_header_checksum=output_2_ip_header_checksum, + ip_source_ip=output_2_ip_source_ip, + ip_dest_ip=output_2_ip_dest_ip, + udp_source_port=output_2_udp_source_port, + udp_dest_port=output_2_udp_dest_port, + udp_length=output_2_udp_length, + udp_checksum=output_2_udp_checksum, + udp_payload_tdata=output_2_udp_payload_tdata, + udp_payload_tvalid=output_2_udp_payload_tvalid, + udp_payload_tready=output_2_udp_payload_tready, + udp_payload_tlast=output_2_udp_payload_tlast, + udp_payload_tuser=output_2_udp_payload_tuser, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + + sink_3 = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_3_udp_hdr_ready, + udp_hdr_valid=output_3_udp_hdr_valid, + eth_dest_mac=output_3_eth_dest_mac, + eth_src_mac=output_3_eth_src_mac, + eth_type=output_3_eth_type, + ip_version=output_3_ip_version, + ip_ihl=output_3_ip_ihl, + ip_dscp=output_3_ip_dscp, + ip_ecn=output_3_ip_ecn, + ip_length=output_3_ip_length, + ip_identification=output_3_ip_identification, + ip_flags=output_3_ip_flags, + ip_fragment_offset=output_3_ip_fragment_offset, + ip_ttl=output_3_ip_ttl, + ip_protocol=output_3_ip_protocol, + ip_header_checksum=output_3_ip_header_checksum, + ip_source_ip=output_3_ip_source_ip, + ip_dest_ip=output_3_ip_dest_ip, + udp_source_port=output_3_udp_source_port, + udp_dest_port=output_3_udp_dest_port, + udp_length=output_3_udp_length, + udp_checksum=output_3_udp_checksum, + udp_payload_tdata=output_3_udp_payload_tdata, + udp_payload_tvalid=output_3_udp_payload_tvalid, + udp_payload_tready=output_3_udp_payload_tready, + udp_payload_tlast=output_3_udp_payload_tlast, + udp_payload_tuser=output_3_udp_payload_tuser, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_udp_demux_4(clk, + rst, + current_test, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_0_udp_hdr_valid, + output_0_udp_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_udp_source_port, + output_0_udp_dest_port, + output_0_udp_length, + output_0_udp_checksum, + output_0_udp_payload_tdata, + output_0_udp_payload_tvalid, + output_0_udp_payload_tready, + output_0_udp_payload_tlast, + output_0_udp_payload_tuser, + output_1_udp_hdr_valid, + output_1_udp_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_udp_source_port, + output_1_udp_dest_port, + output_1_udp_length, + output_1_udp_checksum, + output_1_udp_payload_tdata, + output_1_udp_payload_tvalid, + output_1_udp_payload_tready, + output_1_udp_payload_tlast, + output_1_udp_payload_tuser, + output_2_udp_hdr_valid, + output_2_udp_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_udp_source_port, + output_2_udp_dest_port, + output_2_udp_length, + output_2_udp_checksum, + output_2_udp_payload_tdata, + output_2_udp_payload_tvalid, + output_2_udp_payload_tready, + output_2_udp_payload_tlast, + output_2_udp_payload_tuser, + output_3_udp_hdr_valid, + output_3_udp_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_udp_source_port, + output_3_udp_dest_port, + output_3_udp_length, + output_3_udp_checksum, + output_3_udp_payload_tdata, + output_3_udp_payload_tvalid, + output_3_udp_payload_tready, + output_3_udp_payload_tlast, + output_3_udp_payload_tuser, + + enable, + select) + + @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 + enable.next = True + + yield clk.posedge + print("test 1: select port 0") + current_test.next = 1 + + select.next = 0 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_queue.put(test_frame) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_queue.put(test_frame) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + sink_0_pause.next = True + sink_1_pause.next = True + sink_2_pause.next = True + sink_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_0_pause.next = False + sink_1_pause.next = False + sink_2_pause.next = False + sink_3_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + raise StopSimulation + + return dut, source, sink_0, sink_1, sink_2, sink_3, 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() + diff --git a/tb/test_udp_demux_4.v b/tb/test_udp_demux_4.v new file mode 100644 index 000000000..1c4865b96 --- /dev/null +++ b/tb/test_udp_demux_4.v @@ -0,0 +1,473 @@ +/* + +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_udp_demux_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_udp_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [15:0] input_udp_length = 0; +reg [15:0] input_udp_checksum = 0; +reg [7:0] input_udp_payload_tdata = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; + +reg output_0_udp_hdr_ready = 0; +reg output_0_udp_payload_tready = 0; +reg output_1_udp_hdr_ready = 0; +reg output_1_udp_payload_tready = 0; +reg output_2_udp_hdr_ready = 0; +reg output_2_udp_payload_tready = 0; +reg output_3_udp_hdr_ready = 0; +reg output_3_udp_payload_tready = 0; + +reg enable = 0; +reg [1:0] select = 0; + +// Outputs +wire input_udp_hdr_ready; +wire input_udp_payload_tready; + +wire output_0_udp_hdr_valid; +wire [47:0] output_0_eth_dest_mac; +wire [47:0] output_0_eth_src_mac; +wire [15:0] output_0_eth_type; +wire [3:0] output_0_ip_version; +wire [3:0] output_0_ip_ihl; +wire [5:0] output_0_ip_dscp; +wire [1:0] output_0_ip_ecn; +wire [15:0] output_0_ip_length; +wire [15:0] output_0_ip_identification; +wire [2:0] output_0_ip_flags; +wire [12:0] output_0_ip_fragment_offset; +wire [7:0] output_0_ip_ttl; +wire [7:0] output_0_ip_protocol; +wire [15:0] output_0_ip_header_checksum; +wire [31:0] output_0_ip_source_ip; +wire [31:0] output_0_ip_dest_ip; +wire [15:0] output_0_udp_source_port; +wire [15:0] output_0_udp_dest_port; +wire [15:0] output_0_udp_length; +wire [15:0] output_0_udp_checksum; +wire [7:0] output_0_udp_payload_tdata; +wire output_0_udp_payload_tvalid; +wire output_0_udp_payload_tlast; +wire output_0_udp_payload_tuser; +wire output_1_udp_hdr_valid; +wire [47:0] output_1_eth_dest_mac; +wire [47:0] output_1_eth_src_mac; +wire [15:0] output_1_eth_type; +wire [3:0] output_1_ip_version; +wire [3:0] output_1_ip_ihl; +wire [5:0] output_1_ip_dscp; +wire [1:0] output_1_ip_ecn; +wire [15:0] output_1_ip_length; +wire [15:0] output_1_ip_identification; +wire [2:0] output_1_ip_flags; +wire [12:0] output_1_ip_fragment_offset; +wire [7:0] output_1_ip_ttl; +wire [7:0] output_1_ip_protocol; +wire [15:0] output_1_ip_header_checksum; +wire [31:0] output_1_ip_source_ip; +wire [31:0] output_1_ip_dest_ip; +wire [15:0] output_1_udp_source_port; +wire [15:0] output_1_udp_dest_port; +wire [15:0] output_1_udp_length; +wire [15:0] output_1_udp_checksum; +wire [7:0] output_1_udp_payload_tdata; +wire output_1_udp_payload_tvalid; +wire output_1_udp_payload_tlast; +wire output_1_udp_payload_tuser; +wire output_2_udp_hdr_valid; +wire [47:0] output_2_eth_dest_mac; +wire [47:0] output_2_eth_src_mac; +wire [15:0] output_2_eth_type; +wire [3:0] output_2_ip_version; +wire [3:0] output_2_ip_ihl; +wire [5:0] output_2_ip_dscp; +wire [1:0] output_2_ip_ecn; +wire [15:0] output_2_ip_length; +wire [15:0] output_2_ip_identification; +wire [2:0] output_2_ip_flags; +wire [12:0] output_2_ip_fragment_offset; +wire [7:0] output_2_ip_ttl; +wire [7:0] output_2_ip_protocol; +wire [15:0] output_2_ip_header_checksum; +wire [31:0] output_2_ip_source_ip; +wire [31:0] output_2_ip_dest_ip; +wire [15:0] output_2_udp_source_port; +wire [15:0] output_2_udp_dest_port; +wire [15:0] output_2_udp_length; +wire [15:0] output_2_udp_checksum; +wire [7:0] output_2_udp_payload_tdata; +wire output_2_udp_payload_tvalid; +wire output_2_udp_payload_tlast; +wire output_2_udp_payload_tuser; +wire output_3_udp_hdr_valid; +wire [47:0] output_3_eth_dest_mac; +wire [47:0] output_3_eth_src_mac; +wire [15:0] output_3_eth_type; +wire [3:0] output_3_ip_version; +wire [3:0] output_3_ip_ihl; +wire [5:0] output_3_ip_dscp; +wire [1:0] output_3_ip_ecn; +wire [15:0] output_3_ip_length; +wire [15:0] output_3_ip_identification; +wire [2:0] output_3_ip_flags; +wire [12:0] output_3_ip_fragment_offset; +wire [7:0] output_3_ip_ttl; +wire [7:0] output_3_ip_protocol; +wire [15:0] output_3_ip_header_checksum; +wire [31:0] output_3_ip_source_ip; +wire [31:0] output_3_ip_dest_ip; +wire [15:0] output_3_udp_source_port; +wire [15:0] output_3_udp_dest_port; +wire [15:0] output_3_udp_length; +wire [15:0] output_3_udp_checksum; +wire [7:0] output_3_udp_payload_tdata; +wire output_3_udp_payload_tvalid; +wire output_3_udp_payload_tlast; +wire output_3_udp_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_udp_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_0_udp_hdr_ready, + output_0_udp_payload_tready, + output_1_udp_hdr_ready, + output_1_udp_payload_tready, + output_2_udp_hdr_ready, + output_2_udp_payload_tready, + output_3_udp_hdr_ready, + output_3_udp_payload_tready, + enable, + select); + $to_myhdl(input_udp_hdr_ready, + input_udp_payload_tready, + output_0_udp_hdr_valid, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_udp_source_port, + output_0_udp_dest_port, + output_0_udp_length, + output_0_udp_checksum, + output_0_udp_payload_tdata, + output_0_udp_payload_tvalid, + output_0_udp_payload_tlast, + output_0_udp_payload_tuser, + output_1_udp_hdr_valid, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_udp_source_port, + output_1_udp_dest_port, + output_1_udp_length, + output_1_udp_checksum, + output_1_udp_payload_tdata, + output_1_udp_payload_tvalid, + output_1_udp_payload_tlast, + output_1_udp_payload_tuser, + output_2_udp_hdr_valid, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_udp_source_port, + output_2_udp_dest_port, + output_2_udp_length, + output_2_udp_checksum, + output_2_udp_payload_tdata, + output_2_udp_payload_tvalid, + output_2_udp_payload_tlast, + output_2_udp_payload_tuser, + output_3_udp_hdr_valid, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_udp_source_port, + output_3_udp_dest_port, + output_3_udp_length, + output_3_udp_checksum, + output_3_udp_payload_tdata, + output_3_udp_payload_tvalid, + output_3_udp_payload_tlast, + output_3_udp_payload_tuser); + + // dump file + $dumpfile("test_udp_demux_4.lxt"); + $dumpvars(0, test_udp_demux_4); +end + +udp_demux_4 +UUT ( + .clk(clk), + .rst(rst), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame outputs + .output_0_udp_hdr_valid(output_0_udp_hdr_valid), + .output_0_udp_hdr_ready(output_0_udp_hdr_ready), + .output_0_eth_dest_mac(output_0_eth_dest_mac), + .output_0_eth_src_mac(output_0_eth_src_mac), + .output_0_eth_type(output_0_eth_type), + .output_0_ip_version(output_0_ip_version), + .output_0_ip_ihl(output_0_ip_ihl), + .output_0_ip_dscp(output_0_ip_dscp), + .output_0_ip_ecn(output_0_ip_ecn), + .output_0_ip_length(output_0_ip_length), + .output_0_ip_identification(output_0_ip_identification), + .output_0_ip_flags(output_0_ip_flags), + .output_0_ip_fragment_offset(output_0_ip_fragment_offset), + .output_0_ip_ttl(output_0_ip_ttl), + .output_0_ip_protocol(output_0_ip_protocol), + .output_0_ip_header_checksum(output_0_ip_header_checksum), + .output_0_ip_source_ip(output_0_ip_source_ip), + .output_0_ip_dest_ip(output_0_ip_dest_ip), + .output_0_udp_source_port(output_0_udp_source_port), + .output_0_udp_dest_port(output_0_udp_dest_port), + .output_0_udp_length(output_0_udp_length), + .output_0_udp_checksum(output_0_udp_checksum), + .output_0_udp_payload_tdata(output_0_udp_payload_tdata), + .output_0_udp_payload_tvalid(output_0_udp_payload_tvalid), + .output_0_udp_payload_tready(output_0_udp_payload_tready), + .output_0_udp_payload_tlast(output_0_udp_payload_tlast), + .output_0_udp_payload_tuser(output_0_udp_payload_tuser), + .output_1_udp_hdr_valid(output_1_udp_hdr_valid), + .output_1_udp_hdr_ready(output_1_udp_hdr_ready), + .output_1_eth_dest_mac(output_1_eth_dest_mac), + .output_1_eth_src_mac(output_1_eth_src_mac), + .output_1_eth_type(output_1_eth_type), + .output_1_ip_version(output_1_ip_version), + .output_1_ip_ihl(output_1_ip_ihl), + .output_1_ip_dscp(output_1_ip_dscp), + .output_1_ip_ecn(output_1_ip_ecn), + .output_1_ip_length(output_1_ip_length), + .output_1_ip_identification(output_1_ip_identification), + .output_1_ip_flags(output_1_ip_flags), + .output_1_ip_fragment_offset(output_1_ip_fragment_offset), + .output_1_ip_ttl(output_1_ip_ttl), + .output_1_ip_protocol(output_1_ip_protocol), + .output_1_ip_header_checksum(output_1_ip_header_checksum), + .output_1_ip_source_ip(output_1_ip_source_ip), + .output_1_ip_dest_ip(output_1_ip_dest_ip), + .output_1_udp_source_port(output_1_udp_source_port), + .output_1_udp_dest_port(output_1_udp_dest_port), + .output_1_udp_length(output_1_udp_length), + .output_1_udp_checksum(output_1_udp_checksum), + .output_1_udp_payload_tdata(output_1_udp_payload_tdata), + .output_1_udp_payload_tvalid(output_1_udp_payload_tvalid), + .output_1_udp_payload_tready(output_1_udp_payload_tready), + .output_1_udp_payload_tlast(output_1_udp_payload_tlast), + .output_1_udp_payload_tuser(output_1_udp_payload_tuser), + .output_2_udp_hdr_valid(output_2_udp_hdr_valid), + .output_2_udp_hdr_ready(output_2_udp_hdr_ready), + .output_2_eth_dest_mac(output_2_eth_dest_mac), + .output_2_eth_src_mac(output_2_eth_src_mac), + .output_2_eth_type(output_2_eth_type), + .output_2_ip_version(output_2_ip_version), + .output_2_ip_ihl(output_2_ip_ihl), + .output_2_ip_dscp(output_2_ip_dscp), + .output_2_ip_ecn(output_2_ip_ecn), + .output_2_ip_length(output_2_ip_length), + .output_2_ip_identification(output_2_ip_identification), + .output_2_ip_flags(output_2_ip_flags), + .output_2_ip_fragment_offset(output_2_ip_fragment_offset), + .output_2_ip_ttl(output_2_ip_ttl), + .output_2_ip_protocol(output_2_ip_protocol), + .output_2_ip_header_checksum(output_2_ip_header_checksum), + .output_2_ip_source_ip(output_2_ip_source_ip), + .output_2_ip_dest_ip(output_2_ip_dest_ip), + .output_2_udp_source_port(output_2_udp_source_port), + .output_2_udp_dest_port(output_2_udp_dest_port), + .output_2_udp_length(output_2_udp_length), + .output_2_udp_checksum(output_2_udp_checksum), + .output_2_udp_payload_tdata(output_2_udp_payload_tdata), + .output_2_udp_payload_tvalid(output_2_udp_payload_tvalid), + .output_2_udp_payload_tready(output_2_udp_payload_tready), + .output_2_udp_payload_tlast(output_2_udp_payload_tlast), + .output_2_udp_payload_tuser(output_2_udp_payload_tuser), + .output_3_udp_hdr_valid(output_3_udp_hdr_valid), + .output_3_udp_hdr_ready(output_3_udp_hdr_ready), + .output_3_eth_dest_mac(output_3_eth_dest_mac), + .output_3_eth_src_mac(output_3_eth_src_mac), + .output_3_eth_type(output_3_eth_type), + .output_3_ip_version(output_3_ip_version), + .output_3_ip_ihl(output_3_ip_ihl), + .output_3_ip_dscp(output_3_ip_dscp), + .output_3_ip_ecn(output_3_ip_ecn), + .output_3_ip_length(output_3_ip_length), + .output_3_ip_identification(output_3_ip_identification), + .output_3_ip_flags(output_3_ip_flags), + .output_3_ip_fragment_offset(output_3_ip_fragment_offset), + .output_3_ip_ttl(output_3_ip_ttl), + .output_3_ip_protocol(output_3_ip_protocol), + .output_3_ip_header_checksum(output_3_ip_header_checksum), + .output_3_ip_source_ip(output_3_ip_source_ip), + .output_3_ip_dest_ip(output_3_ip_dest_ip), + .output_3_udp_source_port(output_3_udp_source_port), + .output_3_udp_dest_port(output_3_udp_dest_port), + .output_3_udp_length(output_3_udp_length), + .output_3_udp_checksum(output_3_udp_checksum), + .output_3_udp_payload_tdata(output_3_udp_payload_tdata), + .output_3_udp_payload_tvalid(output_3_udp_payload_tvalid), + .output_3_udp_payload_tready(output_3_udp_payload_tready), + .output_3_udp_payload_tlast(output_3_udp_payload_tlast), + .output_3_udp_payload_tuser(output_3_udp_payload_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule diff --git a/tb/test_udp_demux_64_4.py b/tb/test_udp_demux_64_4.py new file mode 100755 index 000000000..8cf0c9a1a --- /dev/null +++ b/tb/test_udp_demux_64_4.py @@ -0,0 +1,1276 @@ +#!/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 udp_ep + +module = 'udp_demux_64_4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp_demux_64_4(clk, + rst, + current_test, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_0_udp_hdr_valid, + output_0_udp_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_udp_source_port, + output_0_udp_dest_port, + output_0_udp_length, + output_0_udp_checksum, + output_0_udp_payload_tdata, + output_0_udp_payload_tkeep, + output_0_udp_payload_tvalid, + output_0_udp_payload_tready, + output_0_udp_payload_tlast, + output_0_udp_payload_tuser, + output_1_udp_hdr_valid, + output_1_udp_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_udp_source_port, + output_1_udp_dest_port, + output_1_udp_length, + output_1_udp_checksum, + output_1_udp_payload_tdata, + output_1_udp_payload_tkeep, + output_1_udp_payload_tvalid, + output_1_udp_payload_tready, + output_1_udp_payload_tlast, + output_1_udp_payload_tuser, + output_2_udp_hdr_valid, + output_2_udp_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_udp_source_port, + output_2_udp_dest_port, + output_2_udp_length, + output_2_udp_checksum, + output_2_udp_payload_tdata, + output_2_udp_payload_tkeep, + output_2_udp_payload_tvalid, + output_2_udp_payload_tready, + output_2_udp_payload_tlast, + output_2_udp_payload_tuser, + output_3_udp_hdr_valid, + output_3_udp_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_udp_source_port, + output_3_udp_dest_port, + output_3_udp_length, + output_3_udp_checksum, + output_3_udp_payload_tdata, + output_3_udp_payload_tkeep, + output_3_udp_payload_tvalid, + output_3_udp_payload_tready, + output_3_udp_payload_tlast, + output_3_udp_payload_tuser, + + enable, + select): + + 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_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_length=input_udp_length, + input_udp_checksum=input_udp_checksum, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tkeep=input_udp_payload_tkeep, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_0_udp_hdr_valid=output_0_udp_hdr_valid, + output_0_udp_hdr_ready=output_0_udp_hdr_ready, + output_0_eth_dest_mac=output_0_eth_dest_mac, + output_0_eth_src_mac=output_0_eth_src_mac, + output_0_eth_type=output_0_eth_type, + output_0_ip_version=output_0_ip_version, + output_0_ip_ihl=output_0_ip_ihl, + output_0_ip_dscp=output_0_ip_dscp, + output_0_ip_ecn=output_0_ip_ecn, + output_0_ip_length=output_0_ip_length, + output_0_ip_identification=output_0_ip_identification, + output_0_ip_flags=output_0_ip_flags, + output_0_ip_fragment_offset=output_0_ip_fragment_offset, + output_0_ip_ttl=output_0_ip_ttl, + output_0_ip_protocol=output_0_ip_protocol, + output_0_ip_header_checksum=output_0_ip_header_checksum, + output_0_ip_source_ip=output_0_ip_source_ip, + output_0_ip_dest_ip=output_0_ip_dest_ip, + output_0_udp_source_port=output_0_udp_source_port, + output_0_udp_dest_port=output_0_udp_dest_port, + output_0_udp_length=output_0_udp_length, + output_0_udp_checksum=output_0_udp_checksum, + output_0_udp_payload_tdata=output_0_udp_payload_tdata, + output_0_udp_payload_tkeep=output_0_udp_payload_tkeep, + output_0_udp_payload_tvalid=output_0_udp_payload_tvalid, + output_0_udp_payload_tready=output_0_udp_payload_tready, + output_0_udp_payload_tlast=output_0_udp_payload_tlast, + output_0_udp_payload_tuser=output_0_udp_payload_tuser, + output_1_udp_hdr_valid=output_1_udp_hdr_valid, + output_1_udp_hdr_ready=output_1_udp_hdr_ready, + output_1_eth_dest_mac=output_1_eth_dest_mac, + output_1_eth_src_mac=output_1_eth_src_mac, + output_1_eth_type=output_1_eth_type, + output_1_ip_version=output_1_ip_version, + output_1_ip_ihl=output_1_ip_ihl, + output_1_ip_dscp=output_1_ip_dscp, + output_1_ip_ecn=output_1_ip_ecn, + output_1_ip_length=output_1_ip_length, + output_1_ip_identification=output_1_ip_identification, + output_1_ip_flags=output_1_ip_flags, + output_1_ip_fragment_offset=output_1_ip_fragment_offset, + output_1_ip_ttl=output_1_ip_ttl, + output_1_ip_protocol=output_1_ip_protocol, + output_1_ip_header_checksum=output_1_ip_header_checksum, + output_1_ip_source_ip=output_1_ip_source_ip, + output_1_ip_dest_ip=output_1_ip_dest_ip, + output_1_udp_source_port=output_1_udp_source_port, + output_1_udp_dest_port=output_1_udp_dest_port, + output_1_udp_length=output_1_udp_length, + output_1_udp_checksum=output_1_udp_checksum, + output_1_udp_payload_tdata=output_1_udp_payload_tdata, + output_1_udp_payload_tkeep=output_1_udp_payload_tkeep, + output_1_udp_payload_tvalid=output_1_udp_payload_tvalid, + output_1_udp_payload_tready=output_1_udp_payload_tready, + output_1_udp_payload_tlast=output_1_udp_payload_tlast, + output_1_udp_payload_tuser=output_1_udp_payload_tuser, + output_2_udp_hdr_valid=output_2_udp_hdr_valid, + output_2_udp_hdr_ready=output_2_udp_hdr_ready, + output_2_eth_dest_mac=output_2_eth_dest_mac, + output_2_eth_src_mac=output_2_eth_src_mac, + output_2_eth_type=output_2_eth_type, + output_2_ip_version=output_2_ip_version, + output_2_ip_ihl=output_2_ip_ihl, + output_2_ip_dscp=output_2_ip_dscp, + output_2_ip_ecn=output_2_ip_ecn, + output_2_ip_length=output_2_ip_length, + output_2_ip_identification=output_2_ip_identification, + output_2_ip_flags=output_2_ip_flags, + output_2_ip_fragment_offset=output_2_ip_fragment_offset, + output_2_ip_ttl=output_2_ip_ttl, + output_2_ip_protocol=output_2_ip_protocol, + output_2_ip_header_checksum=output_2_ip_header_checksum, + output_2_ip_source_ip=output_2_ip_source_ip, + output_2_ip_dest_ip=output_2_ip_dest_ip, + output_2_udp_source_port=output_2_udp_source_port, + output_2_udp_dest_port=output_2_udp_dest_port, + output_2_udp_length=output_2_udp_length, + output_2_udp_checksum=output_2_udp_checksum, + output_2_udp_payload_tdata=output_2_udp_payload_tdata, + output_2_udp_payload_tkeep=output_2_udp_payload_tkeep, + output_2_udp_payload_tvalid=output_2_udp_payload_tvalid, + output_2_udp_payload_tready=output_2_udp_payload_tready, + output_2_udp_payload_tlast=output_2_udp_payload_tlast, + output_2_udp_payload_tuser=output_2_udp_payload_tuser, + output_3_udp_hdr_valid=output_3_udp_hdr_valid, + output_3_udp_hdr_ready=output_3_udp_hdr_ready, + output_3_eth_dest_mac=output_3_eth_dest_mac, + output_3_eth_src_mac=output_3_eth_src_mac, + output_3_eth_type=output_3_eth_type, + output_3_ip_version=output_3_ip_version, + output_3_ip_ihl=output_3_ip_ihl, + output_3_ip_dscp=output_3_ip_dscp, + output_3_ip_ecn=output_3_ip_ecn, + output_3_ip_length=output_3_ip_length, + output_3_ip_identification=output_3_ip_identification, + output_3_ip_flags=output_3_ip_flags, + output_3_ip_fragment_offset=output_3_ip_fragment_offset, + output_3_ip_ttl=output_3_ip_ttl, + output_3_ip_protocol=output_3_ip_protocol, + output_3_ip_header_checksum=output_3_ip_header_checksum, + output_3_ip_source_ip=output_3_ip_source_ip, + output_3_ip_dest_ip=output_3_ip_dest_ip, + output_3_udp_source_port=output_3_udp_source_port, + output_3_udp_dest_port=output_3_udp_dest_port, + output_3_udp_length=output_3_udp_length, + output_3_udp_checksum=output_3_udp_checksum, + output_3_udp_payload_tdata=output_3_udp_payload_tdata, + output_3_udp_payload_tkeep=output_3_udp_payload_tkeep, + output_3_udp_payload_tvalid=output_3_udp_payload_tvalid, + output_3_udp_payload_tready=output_3_udp_payload_tready, + output_3_udp_payload_tlast=output_3_udp_payload_tlast, + output_3_udp_payload_tuser=output_3_udp_payload_tuser, + + enable=enable, + select=select) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_udp_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_length = Signal(intbv(0)[16:]) + input_udp_checksum = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[64:]) + input_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + + output_0_udp_hdr_ready = Signal(bool(0)) + output_0_udp_payload_tready = Signal(bool(0)) + output_1_udp_hdr_ready = Signal(bool(0)) + output_1_udp_payload_tready = Signal(bool(0)) + output_2_udp_hdr_ready = Signal(bool(0)) + output_2_udp_payload_tready = Signal(bool(0)) + output_3_udp_hdr_ready = Signal(bool(0)) + output_3_udp_payload_tready = Signal(bool(0)) + + enable = Signal(bool(0)) + select = Signal(intbv(0)[2:]) + + # Outputs + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + + output_0_udp_hdr_valid = Signal(bool(0)) + output_0_eth_dest_mac = Signal(intbv(0)[48:]) + output_0_eth_src_mac = Signal(intbv(0)[48:]) + output_0_eth_type = Signal(intbv(0)[16:]) + output_0_ip_version = Signal(intbv(0)[4:]) + output_0_ip_ihl = Signal(intbv(0)[4:]) + output_0_ip_dscp = Signal(intbv(0)[6:]) + output_0_ip_ecn = Signal(intbv(0)[2:]) + output_0_ip_length = Signal(intbv(0)[16:]) + output_0_ip_identification = Signal(intbv(0)[16:]) + output_0_ip_flags = Signal(intbv(0)[3:]) + output_0_ip_fragment_offset = Signal(intbv(0)[13:]) + output_0_ip_ttl = Signal(intbv(0)[8:]) + output_0_ip_protocol = Signal(intbv(0)[8:]) + output_0_ip_header_checksum = Signal(intbv(0)[16:]) + output_0_ip_source_ip = Signal(intbv(0)[32:]) + output_0_ip_dest_ip = Signal(intbv(0)[32:]) + output_0_udp_source_port = Signal(intbv(0)[16:]) + output_0_udp_dest_port = Signal(intbv(0)[16:]) + output_0_udp_length = Signal(intbv(0)[16:]) + output_0_udp_checksum = Signal(intbv(0)[16:]) + output_0_udp_payload_tdata = Signal(intbv(0)[64:]) + output_0_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_0_udp_payload_tvalid = Signal(bool(0)) + output_0_udp_payload_tlast = Signal(bool(0)) + output_0_udp_payload_tuser = Signal(bool(0)) + output_1_udp_hdr_valid = Signal(bool(0)) + output_1_eth_dest_mac = Signal(intbv(0)[48:]) + output_1_eth_src_mac = Signal(intbv(0)[48:]) + output_1_eth_type = Signal(intbv(0)[16:]) + output_1_ip_version = Signal(intbv(0)[4:]) + output_1_ip_ihl = Signal(intbv(0)[4:]) + output_1_ip_dscp = Signal(intbv(0)[6:]) + output_1_ip_ecn = Signal(intbv(0)[2:]) + output_1_ip_length = Signal(intbv(0)[16:]) + output_1_ip_identification = Signal(intbv(0)[16:]) + output_1_ip_flags = Signal(intbv(0)[3:]) + output_1_ip_fragment_offset = Signal(intbv(0)[13:]) + output_1_ip_ttl = Signal(intbv(0)[8:]) + output_1_ip_protocol = Signal(intbv(0)[8:]) + output_1_ip_header_checksum = Signal(intbv(0)[16:]) + output_1_ip_source_ip = Signal(intbv(0)[32:]) + output_1_ip_dest_ip = Signal(intbv(0)[32:]) + output_1_udp_source_port = Signal(intbv(0)[16:]) + output_1_udp_dest_port = Signal(intbv(0)[16:]) + output_1_udp_length = Signal(intbv(0)[16:]) + output_1_udp_checksum = Signal(intbv(0)[16:]) + output_1_udp_payload_tdata = Signal(intbv(0)[64:]) + output_1_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_1_udp_payload_tvalid = Signal(bool(0)) + output_1_udp_payload_tlast = Signal(bool(0)) + output_1_udp_payload_tuser = Signal(bool(0)) + output_2_udp_hdr_valid = Signal(bool(0)) + output_2_eth_dest_mac = Signal(intbv(0)[48:]) + output_2_eth_src_mac = Signal(intbv(0)[48:]) + output_2_eth_type = Signal(intbv(0)[16:]) + output_2_ip_version = Signal(intbv(0)[4:]) + output_2_ip_ihl = Signal(intbv(0)[4:]) + output_2_ip_dscp = Signal(intbv(0)[6:]) + output_2_ip_ecn = Signal(intbv(0)[2:]) + output_2_ip_length = Signal(intbv(0)[16:]) + output_2_ip_identification = Signal(intbv(0)[16:]) + output_2_ip_flags = Signal(intbv(0)[3:]) + output_2_ip_fragment_offset = Signal(intbv(0)[13:]) + output_2_ip_ttl = Signal(intbv(0)[8:]) + output_2_ip_protocol = Signal(intbv(0)[8:]) + output_2_ip_header_checksum = Signal(intbv(0)[16:]) + output_2_ip_source_ip = Signal(intbv(0)[32:]) + output_2_ip_dest_ip = Signal(intbv(0)[32:]) + output_2_udp_source_port = Signal(intbv(0)[16:]) + output_2_udp_dest_port = Signal(intbv(0)[16:]) + output_2_udp_length = Signal(intbv(0)[16:]) + output_2_udp_checksum = Signal(intbv(0)[16:]) + output_2_udp_payload_tdata = Signal(intbv(0)[64:]) + output_2_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_2_udp_payload_tvalid = Signal(bool(0)) + output_2_udp_payload_tlast = Signal(bool(0)) + output_2_udp_payload_tuser = Signal(bool(0)) + output_3_udp_hdr_valid = Signal(bool(0)) + output_3_eth_dest_mac = Signal(intbv(0)[48:]) + output_3_eth_src_mac = Signal(intbv(0)[48:]) + output_3_eth_type = Signal(intbv(0)[16:]) + output_3_ip_version = Signal(intbv(0)[4:]) + output_3_ip_ihl = Signal(intbv(0)[4:]) + output_3_ip_dscp = Signal(intbv(0)[6:]) + output_3_ip_ecn = Signal(intbv(0)[2:]) + output_3_ip_length = Signal(intbv(0)[16:]) + output_3_ip_identification = Signal(intbv(0)[16:]) + output_3_ip_flags = Signal(intbv(0)[3:]) + output_3_ip_fragment_offset = Signal(intbv(0)[13:]) + output_3_ip_ttl = Signal(intbv(0)[8:]) + output_3_ip_protocol = Signal(intbv(0)[8:]) + output_3_ip_header_checksum = Signal(intbv(0)[16:]) + output_3_ip_source_ip = Signal(intbv(0)[32:]) + output_3_ip_dest_ip = Signal(intbv(0)[32:]) + output_3_udp_source_port = Signal(intbv(0)[16:]) + output_3_udp_dest_port = Signal(intbv(0)[16:]) + output_3_udp_length = Signal(intbv(0)[16:]) + output_3_udp_checksum = Signal(intbv(0)[16:]) + output_3_udp_payload_tdata = Signal(intbv(0)[64:]) + output_3_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_3_udp_payload_tvalid = Signal(bool(0)) + output_3_udp_payload_tlast = Signal(bool(0)) + output_3_udp_payload_tuser = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_pause = Signal(bool(0)) + + source = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_ready=input_udp_hdr_ready, + udp_hdr_valid=input_udp_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_length=input_udp_length, + udp_checksum=input_udp_checksum, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tkeep=input_udp_payload_tkeep, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink_0 = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_0_udp_hdr_ready, + udp_hdr_valid=output_0_udp_hdr_valid, + eth_dest_mac=output_0_eth_dest_mac, + eth_src_mac=output_0_eth_src_mac, + eth_type=output_0_eth_type, + ip_version=output_0_ip_version, + ip_ihl=output_0_ip_ihl, + ip_dscp=output_0_ip_dscp, + ip_ecn=output_0_ip_ecn, + ip_length=output_0_ip_length, + ip_identification=output_0_ip_identification, + ip_flags=output_0_ip_flags, + ip_fragment_offset=output_0_ip_fragment_offset, + ip_ttl=output_0_ip_ttl, + ip_protocol=output_0_ip_protocol, + ip_header_checksum=output_0_ip_header_checksum, + ip_source_ip=output_0_ip_source_ip, + ip_dest_ip=output_0_ip_dest_ip, + udp_source_port=output_0_udp_source_port, + udp_dest_port=output_0_udp_dest_port, + udp_length=output_0_udp_length, + udp_checksum=output_0_udp_checksum, + udp_payload_tdata=output_0_udp_payload_tdata, + udp_payload_tkeep=output_0_udp_payload_tkeep, + udp_payload_tvalid=output_0_udp_payload_tvalid, + udp_payload_tready=output_0_udp_payload_tready, + udp_payload_tlast=output_0_udp_payload_tlast, + udp_payload_tuser=output_0_udp_payload_tuser, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + + sink_1 = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_1_udp_hdr_ready, + udp_hdr_valid=output_1_udp_hdr_valid, + eth_dest_mac=output_1_eth_dest_mac, + eth_src_mac=output_1_eth_src_mac, + eth_type=output_1_eth_type, + ip_version=output_1_ip_version, + ip_ihl=output_1_ip_ihl, + ip_dscp=output_1_ip_dscp, + ip_ecn=output_1_ip_ecn, + ip_length=output_1_ip_length, + ip_identification=output_1_ip_identification, + ip_flags=output_1_ip_flags, + ip_fragment_offset=output_1_ip_fragment_offset, + ip_ttl=output_1_ip_ttl, + ip_protocol=output_1_ip_protocol, + ip_header_checksum=output_1_ip_header_checksum, + ip_source_ip=output_1_ip_source_ip, + ip_dest_ip=output_1_ip_dest_ip, + udp_source_port=output_1_udp_source_port, + udp_dest_port=output_1_udp_dest_port, + udp_length=output_1_udp_length, + udp_checksum=output_1_udp_checksum, + udp_payload_tdata=output_1_udp_payload_tdata, + udp_payload_tkeep=output_1_udp_payload_tkeep, + udp_payload_tvalid=output_1_udp_payload_tvalid, + udp_payload_tready=output_1_udp_payload_tready, + udp_payload_tlast=output_1_udp_payload_tlast, + udp_payload_tuser=output_1_udp_payload_tuser, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + + sink_2 = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_2_udp_hdr_ready, + udp_hdr_valid=output_2_udp_hdr_valid, + eth_dest_mac=output_2_eth_dest_mac, + eth_src_mac=output_2_eth_src_mac, + eth_type=output_2_eth_type, + ip_version=output_2_ip_version, + ip_ihl=output_2_ip_ihl, + ip_dscp=output_2_ip_dscp, + ip_ecn=output_2_ip_ecn, + ip_length=output_2_ip_length, + ip_identification=output_2_ip_identification, + ip_flags=output_2_ip_flags, + ip_fragment_offset=output_2_ip_fragment_offset, + ip_ttl=output_2_ip_ttl, + ip_protocol=output_2_ip_protocol, + ip_header_checksum=output_2_ip_header_checksum, + ip_source_ip=output_2_ip_source_ip, + ip_dest_ip=output_2_ip_dest_ip, + udp_source_port=output_2_udp_source_port, + udp_dest_port=output_2_udp_dest_port, + udp_length=output_2_udp_length, + udp_checksum=output_2_udp_checksum, + udp_payload_tdata=output_2_udp_payload_tdata, + udp_payload_tkeep=output_2_udp_payload_tkeep, + udp_payload_tvalid=output_2_udp_payload_tvalid, + udp_payload_tready=output_2_udp_payload_tready, + udp_payload_tlast=output_2_udp_payload_tlast, + udp_payload_tuser=output_2_udp_payload_tuser, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + + sink_3 = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_3_udp_hdr_ready, + udp_hdr_valid=output_3_udp_hdr_valid, + eth_dest_mac=output_3_eth_dest_mac, + eth_src_mac=output_3_eth_src_mac, + eth_type=output_3_eth_type, + ip_version=output_3_ip_version, + ip_ihl=output_3_ip_ihl, + ip_dscp=output_3_ip_dscp, + ip_ecn=output_3_ip_ecn, + ip_length=output_3_ip_length, + ip_identification=output_3_ip_identification, + ip_flags=output_3_ip_flags, + ip_fragment_offset=output_3_ip_fragment_offset, + ip_ttl=output_3_ip_ttl, + ip_protocol=output_3_ip_protocol, + ip_header_checksum=output_3_ip_header_checksum, + ip_source_ip=output_3_ip_source_ip, + ip_dest_ip=output_3_ip_dest_ip, + udp_source_port=output_3_udp_source_port, + udp_dest_port=output_3_udp_dest_port, + udp_length=output_3_udp_length, + udp_checksum=output_3_udp_checksum, + udp_payload_tdata=output_3_udp_payload_tdata, + udp_payload_tkeep=output_3_udp_payload_tkeep, + udp_payload_tvalid=output_3_udp_payload_tvalid, + udp_payload_tready=output_3_udp_payload_tready, + udp_payload_tlast=output_3_udp_payload_tlast, + udp_payload_tuser=output_3_udp_payload_tuser, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_udp_demux_64_4(clk, + rst, + current_test, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_0_udp_hdr_valid, + output_0_udp_hdr_ready, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_udp_source_port, + output_0_udp_dest_port, + output_0_udp_length, + output_0_udp_checksum, + output_0_udp_payload_tdata, + output_0_udp_payload_tkeep, + output_0_udp_payload_tvalid, + output_0_udp_payload_tready, + output_0_udp_payload_tlast, + output_0_udp_payload_tuser, + output_1_udp_hdr_valid, + output_1_udp_hdr_ready, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_udp_source_port, + output_1_udp_dest_port, + output_1_udp_length, + output_1_udp_checksum, + output_1_udp_payload_tdata, + output_1_udp_payload_tkeep, + output_1_udp_payload_tvalid, + output_1_udp_payload_tready, + output_1_udp_payload_tlast, + output_1_udp_payload_tuser, + output_2_udp_hdr_valid, + output_2_udp_hdr_ready, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_udp_source_port, + output_2_udp_dest_port, + output_2_udp_length, + output_2_udp_checksum, + output_2_udp_payload_tdata, + output_2_udp_payload_tkeep, + output_2_udp_payload_tvalid, + output_2_udp_payload_tready, + output_2_udp_payload_tlast, + output_2_udp_payload_tuser, + output_3_udp_hdr_valid, + output_3_udp_hdr_ready, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_udp_source_port, + output_3_udp_dest_port, + output_3_udp_length, + output_3_udp_checksum, + output_3_udp_payload_tdata, + output_3_udp_payload_tkeep, + output_3_udp_payload_tvalid, + output_3_udp_payload_tready, + output_3_udp_payload_tlast, + output_3_udp_payload_tuser, + + enable, + select) + + @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 + enable.next = True + + yield clk.posedge + print("test 1: select port 0") + current_test.next = 1 + + select.next = 0 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_queue.put(test_frame) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: select port 1") + current_test.next = 2 + + select.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source_queue.put(test_frame) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, same port") + current_test.next = 3 + + select.next = 0 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_0_queue.empty(): + rx_frame = sink_0_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, different ports") + current_test.next = 4 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alterate pause source") + current_test.next = 5 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alterate pause sink") + current_test.next = 6 + + select.next = 1 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_dscp = 0 + test_frame1.ip_ecn = 0 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80165 + test_frame1.ip_dest_ip = 0xc0a80164 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(32)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x8000 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_dscp = 0 + test_frame2.ip_ecn = 0 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80165 + test_frame2.ip_dest_ip = 0xc0a80164 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(32)) + test_frame2.build() + + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while input_udp_payload_tvalid or input_udp_hdr_valid: + sink_0_pause.next = True + sink_1_pause.next = True + sink_2_pause.next = True + sink_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_0_pause.next = False + sink_1_pause.next = False + sink_2_pause.next = False + sink_3_pause.next = False + yield clk.posedge + select.next = 2 + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_1_queue.empty(): + rx_frame = sink_1_queue.get() + + assert rx_frame == test_frame1 + + rx_frame = None + if not sink_2_queue.empty(): + rx_frame = sink_2_queue.get() + + assert rx_frame == test_frame2 + + yield delay(100) + + raise StopSimulation + + return dut, source, sink_0, sink_1, sink_2, sink_3, 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() + diff --git a/tb/test_udp_demux_64_4.v b/tb/test_udp_demux_64_4.v new file mode 100644 index 000000000..d0853d713 --- /dev/null +++ b/tb/test_udp_demux_64_4.v @@ -0,0 +1,488 @@ +/* + +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_udp_demux_64_4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_udp_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [15:0] input_udp_length = 0; +reg [15:0] input_udp_checksum = 0; +reg [63:0] input_udp_payload_tdata = 0; +reg [7:0] input_udp_payload_tkeep = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; + +reg output_0_udp_hdr_ready = 0; +reg output_0_udp_payload_tready = 0; +reg output_1_udp_hdr_ready = 0; +reg output_1_udp_payload_tready = 0; +reg output_2_udp_hdr_ready = 0; +reg output_2_udp_payload_tready = 0; +reg output_3_udp_hdr_ready = 0; +reg output_3_udp_payload_tready = 0; + +reg enable = 0; +reg [1:0] select = 0; + +// Outputs +wire input_udp_hdr_ready; +wire input_udp_payload_tready; + +wire output_0_udp_hdr_valid; +wire [47:0] output_0_eth_dest_mac; +wire [47:0] output_0_eth_src_mac; +wire [15:0] output_0_eth_type; +wire [3:0] output_0_ip_version; +wire [3:0] output_0_ip_ihl; +wire [5:0] output_0_ip_dscp; +wire [1:0] output_0_ip_ecn; +wire [15:0] output_0_ip_length; +wire [15:0] output_0_ip_identification; +wire [2:0] output_0_ip_flags; +wire [12:0] output_0_ip_fragment_offset; +wire [7:0] output_0_ip_ttl; +wire [7:0] output_0_ip_protocol; +wire [15:0] output_0_ip_header_checksum; +wire [31:0] output_0_ip_source_ip; +wire [31:0] output_0_ip_dest_ip; +wire [15:0] output_0_udp_source_port; +wire [15:0] output_0_udp_dest_port; +wire [15:0] output_0_udp_length; +wire [15:0] output_0_udp_checksum; +wire [63:0] output_0_udp_payload_tdata; +wire [7:0] output_0_udp_payload_tkeep; +wire output_0_udp_payload_tvalid; +wire output_0_udp_payload_tlast; +wire output_0_udp_payload_tuser; +wire output_1_udp_hdr_valid; +wire [47:0] output_1_eth_dest_mac; +wire [47:0] output_1_eth_src_mac; +wire [15:0] output_1_eth_type; +wire [3:0] output_1_ip_version; +wire [3:0] output_1_ip_ihl; +wire [5:0] output_1_ip_dscp; +wire [1:0] output_1_ip_ecn; +wire [15:0] output_1_ip_length; +wire [15:0] output_1_ip_identification; +wire [2:0] output_1_ip_flags; +wire [12:0] output_1_ip_fragment_offset; +wire [7:0] output_1_ip_ttl; +wire [7:0] output_1_ip_protocol; +wire [15:0] output_1_ip_header_checksum; +wire [31:0] output_1_ip_source_ip; +wire [31:0] output_1_ip_dest_ip; +wire [15:0] output_1_udp_source_port; +wire [15:0] output_1_udp_dest_port; +wire [15:0] output_1_udp_length; +wire [15:0] output_1_udp_checksum; +wire [63:0] output_1_udp_payload_tdata; +wire [7:0] output_1_udp_payload_tkeep; +wire output_1_udp_payload_tvalid; +wire output_1_udp_payload_tlast; +wire output_1_udp_payload_tuser; +wire output_2_udp_hdr_valid; +wire [47:0] output_2_eth_dest_mac; +wire [47:0] output_2_eth_src_mac; +wire [15:0] output_2_eth_type; +wire [3:0] output_2_ip_version; +wire [3:0] output_2_ip_ihl; +wire [5:0] output_2_ip_dscp; +wire [1:0] output_2_ip_ecn; +wire [15:0] output_2_ip_length; +wire [15:0] output_2_ip_identification; +wire [2:0] output_2_ip_flags; +wire [12:0] output_2_ip_fragment_offset; +wire [7:0] output_2_ip_ttl; +wire [7:0] output_2_ip_protocol; +wire [15:0] output_2_ip_header_checksum; +wire [31:0] output_2_ip_source_ip; +wire [31:0] output_2_ip_dest_ip; +wire [15:0] output_2_udp_source_port; +wire [15:0] output_2_udp_dest_port; +wire [15:0] output_2_udp_length; +wire [15:0] output_2_udp_checksum; +wire [63:0] output_2_udp_payload_tdata; +wire [7:0] output_2_udp_payload_tkeep; +wire output_2_udp_payload_tvalid; +wire output_2_udp_payload_tlast; +wire output_2_udp_payload_tuser; +wire output_3_udp_hdr_valid; +wire [47:0] output_3_eth_dest_mac; +wire [47:0] output_3_eth_src_mac; +wire [15:0] output_3_eth_type; +wire [3:0] output_3_ip_version; +wire [3:0] output_3_ip_ihl; +wire [5:0] output_3_ip_dscp; +wire [1:0] output_3_ip_ecn; +wire [15:0] output_3_ip_length; +wire [15:0] output_3_ip_identification; +wire [2:0] output_3_ip_flags; +wire [12:0] output_3_ip_fragment_offset; +wire [7:0] output_3_ip_ttl; +wire [7:0] output_3_ip_protocol; +wire [15:0] output_3_ip_header_checksum; +wire [31:0] output_3_ip_source_ip; +wire [31:0] output_3_ip_dest_ip; +wire [15:0] output_3_udp_source_port; +wire [15:0] output_3_udp_dest_port; +wire [15:0] output_3_udp_length; +wire [15:0] output_3_udp_checksum; +wire [63:0] output_3_udp_payload_tdata; +wire [7:0] output_3_udp_payload_tkeep; +wire output_3_udp_payload_tvalid; +wire output_3_udp_payload_tlast; +wire output_3_udp_payload_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_udp_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_0_udp_hdr_ready, + output_0_udp_payload_tready, + output_1_udp_hdr_ready, + output_1_udp_payload_tready, + output_2_udp_hdr_ready, + output_2_udp_payload_tready, + output_3_udp_hdr_ready, + output_3_udp_payload_tready, + enable, + select); + $to_myhdl(input_udp_hdr_ready, + input_udp_payload_tready, + output_0_udp_hdr_valid, + output_0_eth_dest_mac, + output_0_eth_src_mac, + output_0_eth_type, + output_0_ip_version, + output_0_ip_ihl, + output_0_ip_dscp, + output_0_ip_ecn, + output_0_ip_length, + output_0_ip_identification, + output_0_ip_flags, + output_0_ip_fragment_offset, + output_0_ip_ttl, + output_0_ip_protocol, + output_0_ip_header_checksum, + output_0_ip_source_ip, + output_0_ip_dest_ip, + output_0_udp_source_port, + output_0_udp_dest_port, + output_0_udp_length, + output_0_udp_checksum, + output_0_udp_payload_tdata, + output_0_udp_payload_tkeep, + output_0_udp_payload_tvalid, + output_0_udp_payload_tlast, + output_0_udp_payload_tuser, + output_1_udp_hdr_valid, + output_1_eth_dest_mac, + output_1_eth_src_mac, + output_1_eth_type, + output_1_ip_version, + output_1_ip_ihl, + output_1_ip_dscp, + output_1_ip_ecn, + output_1_ip_length, + output_1_ip_identification, + output_1_ip_flags, + output_1_ip_fragment_offset, + output_1_ip_ttl, + output_1_ip_protocol, + output_1_ip_header_checksum, + output_1_ip_source_ip, + output_1_ip_dest_ip, + output_1_udp_source_port, + output_1_udp_dest_port, + output_1_udp_length, + output_1_udp_checksum, + output_1_udp_payload_tdata, + output_1_udp_payload_tkeep, + output_1_udp_payload_tvalid, + output_1_udp_payload_tlast, + output_1_udp_payload_tuser, + output_2_udp_hdr_valid, + output_2_eth_dest_mac, + output_2_eth_src_mac, + output_2_eth_type, + output_2_ip_version, + output_2_ip_ihl, + output_2_ip_dscp, + output_2_ip_ecn, + output_2_ip_length, + output_2_ip_identification, + output_2_ip_flags, + output_2_ip_fragment_offset, + output_2_ip_ttl, + output_2_ip_protocol, + output_2_ip_header_checksum, + output_2_ip_source_ip, + output_2_ip_dest_ip, + output_2_udp_source_port, + output_2_udp_dest_port, + output_2_udp_length, + output_2_udp_checksum, + output_2_udp_payload_tdata, + output_2_udp_payload_tkeep, + output_2_udp_payload_tvalid, + output_2_udp_payload_tlast, + output_2_udp_payload_tuser, + output_3_udp_hdr_valid, + output_3_eth_dest_mac, + output_3_eth_src_mac, + output_3_eth_type, + output_3_ip_version, + output_3_ip_ihl, + output_3_ip_dscp, + output_3_ip_ecn, + output_3_ip_length, + output_3_ip_identification, + output_3_ip_flags, + output_3_ip_fragment_offset, + output_3_ip_ttl, + output_3_ip_protocol, + output_3_ip_header_checksum, + output_3_ip_source_ip, + output_3_ip_dest_ip, + output_3_udp_source_port, + output_3_udp_dest_port, + output_3_udp_length, + output_3_udp_checksum, + output_3_udp_payload_tdata, + output_3_udp_payload_tkeep, + output_3_udp_payload_tvalid, + output_3_udp_payload_tlast, + output_3_udp_payload_tuser); + + // dump file + $dumpfile("test_udp_demux_64_4.lxt"); + $dumpvars(0, test_udp_demux_64_4); +end + +udp_demux_64_4 +UUT ( + .clk(clk), + .rst(rst), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tkeep(input_udp_payload_tkeep), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame outputs + .output_0_udp_hdr_valid(output_0_udp_hdr_valid), + .output_0_udp_hdr_ready(output_0_udp_hdr_ready), + .output_0_eth_dest_mac(output_0_eth_dest_mac), + .output_0_eth_src_mac(output_0_eth_src_mac), + .output_0_eth_type(output_0_eth_type), + .output_0_ip_version(output_0_ip_version), + .output_0_ip_ihl(output_0_ip_ihl), + .output_0_ip_dscp(output_0_ip_dscp), + .output_0_ip_ecn(output_0_ip_ecn), + .output_0_ip_length(output_0_ip_length), + .output_0_ip_identification(output_0_ip_identification), + .output_0_ip_flags(output_0_ip_flags), + .output_0_ip_fragment_offset(output_0_ip_fragment_offset), + .output_0_ip_ttl(output_0_ip_ttl), + .output_0_ip_protocol(output_0_ip_protocol), + .output_0_ip_header_checksum(output_0_ip_header_checksum), + .output_0_ip_source_ip(output_0_ip_source_ip), + .output_0_ip_dest_ip(output_0_ip_dest_ip), + .output_0_udp_source_port(output_0_udp_source_port), + .output_0_udp_dest_port(output_0_udp_dest_port), + .output_0_udp_length(output_0_udp_length), + .output_0_udp_checksum(output_0_udp_checksum), + .output_0_udp_payload_tdata(output_0_udp_payload_tdata), + .output_0_udp_payload_tkeep(output_0_udp_payload_tkeep), + .output_0_udp_payload_tvalid(output_0_udp_payload_tvalid), + .output_0_udp_payload_tready(output_0_udp_payload_tready), + .output_0_udp_payload_tlast(output_0_udp_payload_tlast), + .output_0_udp_payload_tuser(output_0_udp_payload_tuser), + .output_1_udp_hdr_valid(output_1_udp_hdr_valid), + .output_1_udp_hdr_ready(output_1_udp_hdr_ready), + .output_1_eth_dest_mac(output_1_eth_dest_mac), + .output_1_eth_src_mac(output_1_eth_src_mac), + .output_1_eth_type(output_1_eth_type), + .output_1_ip_version(output_1_ip_version), + .output_1_ip_ihl(output_1_ip_ihl), + .output_1_ip_dscp(output_1_ip_dscp), + .output_1_ip_ecn(output_1_ip_ecn), + .output_1_ip_length(output_1_ip_length), + .output_1_ip_identification(output_1_ip_identification), + .output_1_ip_flags(output_1_ip_flags), + .output_1_ip_fragment_offset(output_1_ip_fragment_offset), + .output_1_ip_ttl(output_1_ip_ttl), + .output_1_ip_protocol(output_1_ip_protocol), + .output_1_ip_header_checksum(output_1_ip_header_checksum), + .output_1_ip_source_ip(output_1_ip_source_ip), + .output_1_ip_dest_ip(output_1_ip_dest_ip), + .output_1_udp_source_port(output_1_udp_source_port), + .output_1_udp_dest_port(output_1_udp_dest_port), + .output_1_udp_length(output_1_udp_length), + .output_1_udp_checksum(output_1_udp_checksum), + .output_1_udp_payload_tdata(output_1_udp_payload_tdata), + .output_1_udp_payload_tkeep(output_1_udp_payload_tkeep), + .output_1_udp_payload_tvalid(output_1_udp_payload_tvalid), + .output_1_udp_payload_tready(output_1_udp_payload_tready), + .output_1_udp_payload_tlast(output_1_udp_payload_tlast), + .output_1_udp_payload_tuser(output_1_udp_payload_tuser), + .output_2_udp_hdr_valid(output_2_udp_hdr_valid), + .output_2_udp_hdr_ready(output_2_udp_hdr_ready), + .output_2_eth_dest_mac(output_2_eth_dest_mac), + .output_2_eth_src_mac(output_2_eth_src_mac), + .output_2_eth_type(output_2_eth_type), + .output_2_ip_version(output_2_ip_version), + .output_2_ip_ihl(output_2_ip_ihl), + .output_2_ip_dscp(output_2_ip_dscp), + .output_2_ip_ecn(output_2_ip_ecn), + .output_2_ip_length(output_2_ip_length), + .output_2_ip_identification(output_2_ip_identification), + .output_2_ip_flags(output_2_ip_flags), + .output_2_ip_fragment_offset(output_2_ip_fragment_offset), + .output_2_ip_ttl(output_2_ip_ttl), + .output_2_ip_protocol(output_2_ip_protocol), + .output_2_ip_header_checksum(output_2_ip_header_checksum), + .output_2_ip_source_ip(output_2_ip_source_ip), + .output_2_ip_dest_ip(output_2_ip_dest_ip), + .output_2_udp_source_port(output_2_udp_source_port), + .output_2_udp_dest_port(output_2_udp_dest_port), + .output_2_udp_length(output_2_udp_length), + .output_2_udp_checksum(output_2_udp_checksum), + .output_2_udp_payload_tdata(output_2_udp_payload_tdata), + .output_2_udp_payload_tkeep(output_2_udp_payload_tkeep), + .output_2_udp_payload_tvalid(output_2_udp_payload_tvalid), + .output_2_udp_payload_tready(output_2_udp_payload_tready), + .output_2_udp_payload_tlast(output_2_udp_payload_tlast), + .output_2_udp_payload_tuser(output_2_udp_payload_tuser), + .output_3_udp_hdr_valid(output_3_udp_hdr_valid), + .output_3_udp_hdr_ready(output_3_udp_hdr_ready), + .output_3_eth_dest_mac(output_3_eth_dest_mac), + .output_3_eth_src_mac(output_3_eth_src_mac), + .output_3_eth_type(output_3_eth_type), + .output_3_ip_version(output_3_ip_version), + .output_3_ip_ihl(output_3_ip_ihl), + .output_3_ip_dscp(output_3_ip_dscp), + .output_3_ip_ecn(output_3_ip_ecn), + .output_3_ip_length(output_3_ip_length), + .output_3_ip_identification(output_3_ip_identification), + .output_3_ip_flags(output_3_ip_flags), + .output_3_ip_fragment_offset(output_3_ip_fragment_offset), + .output_3_ip_ttl(output_3_ip_ttl), + .output_3_ip_protocol(output_3_ip_protocol), + .output_3_ip_header_checksum(output_3_ip_header_checksum), + .output_3_ip_source_ip(output_3_ip_source_ip), + .output_3_ip_dest_ip(output_3_ip_dest_ip), + .output_3_udp_source_port(output_3_udp_source_port), + .output_3_udp_dest_port(output_3_udp_dest_port), + .output_3_udp_length(output_3_udp_length), + .output_3_udp_checksum(output_3_udp_checksum), + .output_3_udp_payload_tdata(output_3_udp_payload_tdata), + .output_3_udp_payload_tkeep(output_3_udp_payload_tkeep), + .output_3_udp_payload_tvalid(output_3_udp_payload_tvalid), + .output_3_udp_payload_tready(output_3_udp_payload_tready), + .output_3_udp_payload_tlast(output_3_udp_payload_tlast), + .output_3_udp_payload_tuser(output_3_udp_payload_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule From 495bb2714f4ba0ec3848ec33d6eb8ba05a2e6436 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Nov 2014 16:21:02 -0800 Subject: [PATCH 114/617] Update readme --- README | 3 +- README.md | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 2 deletions(-) mode change 100644 => 120000 README create mode 100644 README.md diff --git a/README b/README deleted file mode 100644 index 45dbb8ac1..000000000 --- a/README +++ /dev/null @@ -1,2 +0,0 @@ -Verilog ethernet components - diff --git a/README b/README new file mode 120000 index 000000000..42061c01a --- /dev/null +++ b/README @@ -0,0 +1 @@ +README.md \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..44772b1b2 --- /dev/null +++ b/README.md @@ -0,0 +1,119 @@ +# Verilog Ethernet Components Readme + +For more information and updates: http://alexforencich.com/wiki/en/verilog/ethernet/start + +GitHub repository: https://github.com/alexforencich/verilog-ethernet + +## Introduction + +Collection of Ethernet-related components for both gigabit and 10G packet +processing (8 bit and 64 bit datapaths). Includes modules for handling +Ethernet frames as well as IP, UDP, and ARP and the components for +constructing a complete UDP/IP stack. Includes full MyHDL testbench with +intelligent bus cosimulation endpoints. + +## Documentation + +## eth_axis_rx module + +Ethernet frame receiver. + +## eth_axis_rx_64 module + +Ethernet frame receiver with 64 bit datapath for 10G Ethernet. + +## eth_axis_tx module + +Ethernet frame transmitter. + +## eth_axis_tx_64 module + +Ethernet frame transmitter with 64 bit datapath for 10G Ethernet. + +### Common signals + + tdata : Data (width generally DATA_WIDTH) + tkeep : Data word valid (width generally KEEP_WIDTH, present on _64 modules) + tvalid : Data valid + tready : Sink ready + tlast : End-of-frame + tuser : Bad frame (valid with tlast & tvalid) + +### Source Files + + rtl/arbiter.v : General-purpose parametrizable arbiter + rtl/eth_axis_rx.v : Ethernet frame receiver + rtl/eth_axis_rx_64.v : Ethernet frame receiver (64 bit) + rtl/eth_axis_tx.v : Ethernet frame transmitter + rtl/eth_axis_tx_64.v : Ethernet frame transmitter (64 bit) + +### AXI Stream Interface Example + +two byte transfer with sink pause after each byte + + __ __ __ __ __ __ __ __ __ + clk __/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__ + _____ _________________ + tdata XXXXXXXXX_D0__X_D1______________XXXXXXXXXXXXXXXXXXXXXXXX + _____ _________________ + tkeep XXXXXXXXX_K0__X_K1______________XXXXXXXXXXXXXXXXXXXXXXXX + _______________________ + tvalid ________/ \_______________________ + ______________ _____ ___________ + tready \___________/ \___________/ + _________________ + tlast ______________/ \_______________________ + + tuser ________________________________________________________ + + +two back-to-back packets, no pauses + + __ __ __ __ __ __ __ __ __ + clk __/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__ + _____ _____ _____ _____ _____ _____ + tdata XXXXXXXXX_A0__X_A1__X_A2__X_B0__X_B1__X_B2__XXXXXXXXXXXX + _____ _____ _____ _____ _____ _____ + tkeep XXXXXXXXX_K0__X_K1__X_K2__X_K0__X_K1__X_K2__XXXXXXXXXXXX + ___________________________________ + tvalid ________/ \___________ + ________________________________________________________ + tready + _____ _____ + tlast ____________________/ \___________/ \___________ + + tuser ________________________________________________________ + + +bad frame + + __ __ __ __ __ __ + clk __/ \__/ \__/ \__/ \__/ \__/ \__ + _____ _____ _____ + tdata XXXXXXXXX_A0__X_A1__X_A2__XXXXXXXXXXXX + _____ _____ _____ + tkeep XXXXXXXXX_K0__X_K1__X_K2__XXXXXXXXXXXX + _________________ + tvalid ________/ \___________ + ______________________________________ + tready + _____ + tlast ____________________/ \___________ + _____ + tuser ____________________/ \___________ + + +## Testing + +Running the included testbenches requires MyHDL and Icarus Verilog. Make sure +that myhdl.vpi is installed properly for cosimulation to work correctly. The +testbenches can be run with a Python test runner like nose or py.test, or the +individual test scripts can be run with python directly. + +### Testbench Files + + tb/arp_ep.py : MyHDL ARP frame endpoints + tb/axis_ep.py : MyHDL AXI Stream endpoints + tb/eth_ep.py : MyHDL Ethernet frame endpoints + tb/ip_ep.py : MyHDL IP frame endpoints + tb/udp_ep.py : MyHDL UDP frame endpoints From 3dfcac97ce598e591dfde66e87478f3fabf31938 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Nov 2014 17:07:01 -0800 Subject: [PATCH 115/617] Update readme --- README.md | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 265 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 44772b1b2..6914809dd 100644 --- a/README.md +++ b/README.md @@ -14,22 +14,206 @@ intelligent bus cosimulation endpoints. ## Documentation -## eth_axis_rx module +### arp_eth_rx module -Ethernet frame receiver. +ARP frame receiver. -## eth_axis_rx_64 module +### arp_eth_rx_64 module + +ARP frame receiver with 64 bit datapath for 10G Ethernet. + +### arp_eth_tx module + +ARP frame transmitter. + +### arp_eth_tx_64 module + +ARP frame transmitter with 64 bit datapath for 10G Ethernet. + +### eth_arb_mux_N module + +Ethernet frame arbitrated muliplexer with 8 bit data width for gigabit +Ethernet. Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with eth_arb_mux.py. + +### eth_arb_mux_64_N module + +Ethernet frame arbitrated muliplexer with 8 bit data width for 10G Ethernet. +Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with eth_arb_mux_64.py. + +### eth_axis_rx module + +Ethernet frame receiver. + +### eth_axis_rx_64 module Ethernet frame receiver with 64 bit datapath for 10G Ethernet. -## eth_axis_tx module +### eth_axis_tx module Ethernet frame transmitter. -## eth_axis_tx_64 module +### eth_axis_tx_64 module Ethernet frame transmitter with 64 bit datapath for 10G Ethernet. +### eth_demux_N module + +Ethernet frame demuliplexer with 8 bit data width for gigabit Ethernet. +Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with eth_demux.py. + +### eth_demux_64_N module + +Ethernet frame demuliplexer with 64 bit data width for 10G Ethernet. Supports +priority and round-robin arbitration. + +Can be generated with arbitrary port counts with eth_demux_64.py. + +### eth_mux_N module + +Ethernet frame muliplexer with 8 bit data width for gigabit Ethernet. +Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with eth_mux.py. + +### eth_mux_64_N module + +Ethernet frame muliplexer with 64 bit data width for 10G Ethernet. Supports +priority and round-robin arbitration. + +Can be generated with arbitrary port counts with eth_mux_64.py. + +### ip module + +IPv4 block with 8 bit data width for gigabit Ethernet. Manages IPv4 packet +transmssion and reception. Interfaces with ARP module for MAC address lookup. + +### ip_64 module + +IPv4 block with 64 bit data width for 10G Ethernet. Manages IPv4 packet +transmssion and reception. Interfaces with ARP module for MAC address lookup. + +### ip_arb_mux_N module + +IP frame arbitrated muliplexer with 8 bit data width for gigabit +Ethernet. Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with ip_arb_mux.py. + +### ip_arb_mux_64_N module + +IP frame arbitrated muliplexer with 8 bit data width for 10G Ethernet. +Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with ip_arb_mux_64.py. + +### ip_eth_rx module + +IP frame receiver. + +### ip_eth_rx_64 module + +IP frame receiver with 64 bit datapath for 10G Ethernet. + +### ip_eth_tx module + +IP frame transmitter. + +### ip_eth_tx_64 module + +IP frame transmitter with 64 bit datapath for 10G Ethernet. + +### ip_demux_N module + +IP frame demuliplexer with 8 bit data width for gigabit Ethernet. +Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with ip_demux.py. + +### ip_demux_64_N module + +IP frame demuliplexer with 64 bit data width for 10G Ethernet. Supports +priority and round-robin arbitration. + +Can be generated with arbitrary port counts with ip_demux_64.py. + +### ip_mux_N module + +IP frame muliplexer with 8 bit data width for gigabit Ethernet. +Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with ip_mux.py. + +### ip_mux_64_N module + +IP frame muliplexer with 64 bit data width for 10G Ethernet. Supports +priority and round-robin arbitration. + +Can be generated with arbitrary port counts with ip_mux_64.py. + +### udp_arb_mux_N module + +UDP frame arbitrated muliplexer with 8 bit data width for gigabit +Ethernet. Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with udp_arb_mux.py. + +### udp_arb_mux_64_N module + +UDP frame arbitrated muliplexer with 8 bit data width for 10G Ethernet. +Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with udp_arb_mux_64.py. + +### udp_ip_rx module + +UDP frame receiver. + +### udp_ip_rx_64 module + +UDP frame receiver with 64 bit datapath for 10G Ethernet. + +### udp_ip_tx module + +UDP frame transmitter. + +### udp_ip_tx_64 module + +UDP frame transmitter with 64 bit datapath for 10G Ethernet. + +### udp_demux_N module + +UDP frame demuliplexer with 8 bit data width for gigabit Ethernet. +Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with udp_demux.py. + +### udp_demux_64_N module + +UDP frame demuliplexer with 64 bit data width for 10G Ethernet. Supports +priority and round-robin arbitration. + +Can be generated with arbitrary port counts with udp_demux_64.py. + +### udp_mux_N module + +UDP frame muliplexer with 8 bit data width for gigabit Ethernet. +Supports priority and round-robin arbitration. + +Can be generated with arbitrary port counts with udp_mux.py. + +### udp_mux_64_N module + +UDP frame muliplexer with 64 bit data width for 10G Ethernet. Supports +priority and round-robin arbitration. + +Can be generated with arbitrary port counts with udp_mux_64.py. + ### Common signals tdata : Data (width generally DATA_WIDTH) @@ -41,14 +225,89 @@ Ethernet frame transmitter with 64 bit datapath for 10G Ethernet. ### Source Files - rtl/arbiter.v : General-purpose parametrizable arbiter + rtl/arp_eth_rx.v : ARP frame receiver + rtl/arp_eth_rx_64.v : ARP frame receiver (64 bit) + rtl/arp_eth_tx.v : ARP frame transmitter + rtl/arp_eth_tx_64.v : ARP frame transmitter (64 bit) + rtl/eth_arb_mux.py : Ethernet frame arbitrated multiplexer generator + rtl/eth_arb_mux_4.v : 4 port Ethernet frame arbitrated multiplexer + rtl/eth_arb_mux_64.py : Ethernet frame arbitrated multiplexer generator (64 bit) + rtl/eth_arb_mux_64_4.v : 4 port Ethernet frame arbitrated multiplexer (64 bit) rtl/eth_axis_rx.v : Ethernet frame receiver rtl/eth_axis_rx_64.v : Ethernet frame receiver (64 bit) rtl/eth_axis_tx.v : Ethernet frame transmitter rtl/eth_axis_tx_64.v : Ethernet frame transmitter (64 bit) + rtl/eth_demux.py : Ethernet frame demultiplexer generator + rtl/eth_demux_4.v : 4 port Ethernet frame demultiplexer + rtl/eth_demux_64.py : Ethernet frame demultiplexer generator (64 bit) + rtl/eth_demux_64_4.v : 4 port Ethernet frame demultiplexer (64 bit) + rtl/eth_mux.py : Ethernet frame multiplexer generator + rtl/eth_mux_4.v : 4 port Ethernet frame multiplexer + rtl/eth_mux_64.py : Ethernet frame multiplexer generator (64 bit) + rtl/eth_mux_64_4.v : 4 port Ethernet frame multiplexer (64 bit) + rtl/ip.v : IPv4 block + rtl/ip_64.v : IPv4 block (64 bit) + rtl/ip_arb_mux.py : IP frame arbitrated multiplexer generator + rtl/ip_arb_mux_4.v : 4 port IP frame arbitrated multiplexer + rtl/ip_arb_mux_64.py : IP frame arbitrated multiplexer generator (64 bit) + rtl/ip_arb_mux_64_4.v : 4 port IP frame arbitrated multiplexer (64 bit) + rtl/ip_eth_rx.v : IPv4 frame receiver + rtl/ip_eth_rx_64.v : IPv4 frame receiver (64 bit) + rtl/ip_eth_tx.v : IPv4 frame transmitter + rtl/ip_eth_tx_64.v : IPv4 frame transmitter (64 bit) + rtl/ip_demux.py : IP frame demultiplexer generator + rtl/ip_demux_4.v : 4 port IP frame demultiplexer + rtl/ip_demux_64.py : IP frame demultiplexer generator (64 bit) + rtl/ip_demux_64_4.v : 4 port IP frame demultiplexer (64 bit) + rtl/ip_mux.py : IP frame multiplexer generator + rtl/ip_mux_4.v : 4 port IP frame multiplexer + rtl/ip_mux_64.py : IP frame multiplexer generator (64 bit) + rtl/ip_mux_64_4.v : 4 port IP frame multiplexer (64 bit) + rtl/udp_arb_mux.py : UDP frame arbitrated multiplexer generator + rtl/udp_arb_mux_4.v : 4 port UDP frame arbitrated multiplexer + rtl/udp_arb_mux_64.py : UDP frame arbitrated multiplexer generator (64 bit) + rtl/udp_arb_mux_64_4.v : 4 port UDP frame arbitrated multiplexer (64 bit) + rtl/udp_ip_rx.v : UDP frame receiver + rtl/udp_ip_rx_64.v : UDP frame receiver (64 bit) + rtl/udp_ip_tx.v : UDP frame transmitter + rtl/udp_ip_tx_64.v : UDP frame transmitter (64 bit) + rtl/udp_demux.py : UDP frame demultiplexer generator + rtl/udp_demux_4.v : 4 port UDP frame demultiplexer + rtl/udp_demux_64.py : UDP frame demultiplexer generator (64 bit) + rtl/udp_demux_64_4.v : 4 port UDP frame demultiplexer (64 bit) + rtl/udp_mux.py : UDP frame multiplexer generator + rtl/udp_mux_4.v : 4 port UDP frame multiplexer + rtl/udp_mux_64.py : UDP frame multiplexer generator (64 bit) + rtl/udp_mux_64_4.v : 4 port UDP frame multiplexer (64 bit) ### AXI Stream Interface Example +transfer with header data + + __ __ __ __ __ __ __ + clk __/ \__/ \__/ \__/ \__/ \__/ \__/ \__ + ______________ ___________ + hdr_ready \_________________/ + _____ + hdr_valid ________/ \_____________________________ + _____ + hdr_data XXXXXXXXX_HDR_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + ___________ _____ _____ + tdata XXXXXXXXX_A0________X_A1__X_A2__XXXXXXXXXXXX + ___________ _____ _____ + tdata XXXXXXXXX_A0________X_A1__X_A2__XXXXXXXXXXXX + ___________ _____ _____ + tkeep XXXXXXXXX_K0________X_K1__X_K2__XXXXXXXXXXXX + _______________________ + tvalid ________/ \___________ + _________________ + tready ______________/ \___________ + _____ + tlast __________________________/ \___________ + + tuser ____________________________________________ + + two byte transfer with sink pause after each byte __ __ __ __ __ __ __ __ __ From b07c2d63b008a341a3a859bcbb2fc32b24597a03 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Nov 2014 23:06:43 -0800 Subject: [PATCH 116/617] Parametrize tag and counter widths --- rtl/axis_frame_join.py | 37 ++++++---- rtl/axis_frame_join_4.v | 37 ++++++---- rtl/axis_stat_counter.v | 134 ++++++++++++++++++++---------------- tb/test_axis_frame_join_4.v | 2 +- 4 files changed, 122 insertions(+), 88 deletions(-) diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index ec866ed84..c01ed0ff0 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -101,7 +101,8 @@ THE SOFTWARE. */ module {{name}} # ( - parameter ENABLE_TAG = 1 + parameter TAG_ENABLE = 1, + parameter TAG_WIDTH = 16 ) ( input wire clk, @@ -129,7 +130,7 @@ module {{name}} # /* * Configuration */ - input wire [15:0] tag, + input wire [TAG_WIDTH-1:0] tag, /* * Status signals @@ -137,6 +138,8 @@ module {{name}} # output wire busy ); +localparam TAG_BYTE_WIDTH = (TAG_WIDTH + 7) / 8; + // state register localparam [1:0] STATE_IDLE = 2'd0, @@ -187,6 +190,8 @@ always @* begin endcase end +integer offset, i; + always @* begin state_next = 2'bz; @@ -210,7 +215,7 @@ always @* begin port_sel_next = 0; output_tuser_next = 0; - if (ENABLE_TAG) begin + if (TAG_ENABLE) begin // next cycle if started will send tag, so do not enable input input_0_axis_tready_next = 0; end else begin @@ -220,15 +225,14 @@ always @* begin if (input_0_axis_tvalid) begin // input 0 valid; start transferring data - if (ENABLE_TAG) begin + if (TAG_ENABLE) begin // tag enabled, so transmit it if (output_axis_tready_int) begin // output is ready, so short-circuit first tag byte frame_ptr_next = 1; - output_axis_tdata_int = tag[15:8]; + output_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; output_axis_tvalid_int = 1; end - state_next = STATE_WRITE_TAG; end else begin // tag disabled, so transmit data @@ -250,15 +254,20 @@ always @* begin state_next = STATE_WRITE_TAG; frame_ptr_next = frame_ptr_reg + 1; output_axis_tvalid_int = 1; - case (frame_ptr_reg) - 2'd0: output_axis_tdata_int = tag[15:8]; - 2'd1: begin - // last tag byte - get ready to send data, enable input if ready - output_axis_tdata_int = tag[7:0]; - input_0_axis_tready_next = output_axis_tready_int_early; - state_next = STATE_TRANSFER; + + offset = 0; + if (TAG_ENABLE) begin + for (i = TAG_BYTE_WIDTH-1; i >= 0; i = i - 1) begin + if (frame_ptr_reg == offset) begin + output_axis_tdata_int = tag[i*8 +: 8]; + end + offset = offset + 1; end - endcase + end + if (frame_ptr_reg == offset-1) begin + input_0_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_TRANSFER; + end end else begin state_next = STATE_WRITE_TAG; end diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index c1430465d..b6411207d 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -31,7 +31,8 @@ THE SOFTWARE. */ module axis_frame_join_4 # ( - parameter ENABLE_TAG = 1 + parameter TAG_ENABLE = 1, + parameter TAG_WIDTH = 16 ) ( input wire clk, @@ -76,7 +77,7 @@ module axis_frame_join_4 # /* * Configuration */ - input wire [15:0] tag, + input wire [TAG_WIDTH-1:0] tag, /* * Status signals @@ -84,6 +85,8 @@ module axis_frame_join_4 # output wire busy ); +localparam TAG_BYTE_WIDTH = (TAG_WIDTH + 7) / 8; + // state register localparam [1:0] STATE_IDLE = 2'd0, @@ -154,6 +157,8 @@ always @* begin endcase end +integer offset, i; + always @* begin state_next = 2'bz; @@ -179,7 +184,7 @@ always @* begin port_sel_next = 0; output_tuser_next = 0; - if (ENABLE_TAG) begin + if (TAG_ENABLE) begin // next cycle if started will send tag, so do not enable input input_0_axis_tready_next = 0; end else begin @@ -189,15 +194,14 @@ always @* begin if (input_0_axis_tvalid) begin // input 0 valid; start transferring data - if (ENABLE_TAG) begin + if (TAG_ENABLE) begin // tag enabled, so transmit it if (output_axis_tready_int) begin // output is ready, so short-circuit first tag byte frame_ptr_next = 1; - output_axis_tdata_int = tag[15:8]; + output_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; output_axis_tvalid_int = 1; end - state_next = STATE_WRITE_TAG; end else begin // tag disabled, so transmit data @@ -219,15 +223,20 @@ always @* begin state_next = STATE_WRITE_TAG; frame_ptr_next = frame_ptr_reg + 1; output_axis_tvalid_int = 1; - case (frame_ptr_reg) - 2'd0: output_axis_tdata_int = tag[15:8]; - 2'd1: begin - // last tag byte - get ready to send data, enable input if ready - output_axis_tdata_int = tag[7:0]; - input_0_axis_tready_next = output_axis_tready_int_early; - state_next = STATE_TRANSFER; + + offset = 0; + if (TAG_ENABLE) begin + for (i = TAG_BYTE_WIDTH-1; i >= 0; i = i - 1) begin + if (frame_ptr_reg == offset) begin + output_axis_tdata_int = tag[i*8 +: 8]; + end + offset = offset + 1; end - endcase + end + if (frame_ptr_reg == offset-1) begin + input_0_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_TRANSFER; + end end else begin state_next = STATE_WRITE_TAG; end diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index 7dfdb14fa..64a10d279 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -32,7 +32,15 @@ THE SOFTWARE. module axis_stat_counter # ( parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter TAG_ENABLE = 1, + parameter TAG_WIDTH = 16, + parameter TICK_COUNT_ENABLE = 1, + parameter TICK_COUNT_WIDTH = 32, + parameter BYTE_COUNT_ENABLE = 1, + parameter BYTE_COUNT_WIDTH = 32, + parameter FRAME_COUNT_ENABLE = 1, + parameter FRAME_COUNT_WIDTH = 32 ) ( input wire clk, @@ -58,7 +66,7 @@ module axis_stat_counter # /* * Configuration */ - input wire [15:0] tag, + input wire [TAG_WIDTH-1:0] tag, input wire trigger, /* @@ -67,6 +75,12 @@ module axis_stat_counter # output wire busy ); +localparam TAG_BYTE_WIDTH = (TAG_WIDTH + 7) / 8; +localparam TICK_COUNT_BYTE_WIDTH = (TICK_COUNT_WIDTH + 7) / 8; +localparam BYTE_COUNT_BYTE_WIDTH = (BYTE_COUNT_WIDTH + 7) / 8; +localparam FRAME_COUNT_BYTE_WIDTH = (FRAME_COUNT_WIDTH + 7) / 8; +localparam TOTAL_LENGTH = TAG_BYTE_WIDTH + TICK_COUNT_BYTE_WIDTH + BYTE_COUNT_BYTE_WIDTH + FRAME_COUNT_BYTE_WIDTH; + // state register localparam [1:0] STATE_IDLE = 2'd0, @@ -74,17 +88,17 @@ localparam [1:0] reg [1:0] state_reg = STATE_IDLE, state_next; -reg [31:0] tick_count_reg = 0, tick_count_next; -reg [31:0] byte_count_reg = 0, byte_count_next; -reg [31:0] frame_count_reg = 0, frame_count_next; +reg [TICK_COUNT_WIDTH-1:0] tick_count_reg = 0, tick_count_next; +reg [BYTE_COUNT_WIDTH-1:0] byte_count_reg = 0, byte_count_next; +reg [FRAME_COUNT_WIDTH-1:0] frame_count_reg = 0, frame_count_next; reg frame_reg = 0, frame_next; reg store_output; -reg [5:0] frame_ptr_reg = 0, frame_ptr_next; +reg [$clog2(TOTAL_LENGTH)-1:0] frame_ptr_reg = 0, frame_ptr_next; -reg [31:0] tick_count_output_reg = 0; -reg [31:0] byte_count_output_reg = 0; -reg [31:0] frame_count_output_reg = 0; +reg [TICK_COUNT_WIDTH-1:0] tick_count_output_reg = 0; +reg [BYTE_COUNT_WIDTH-1:0] byte_count_output_reg = 0; +reg [FRAME_COUNT_WIDTH-1:0] frame_count_output_reg = 0; reg busy_reg = 0; @@ -98,35 +112,7 @@ wire output_axis_tready_int_early; assign busy = busy_reg; -function [3:0] keep2count; - input [7:0] k; - case (k) - 8'b00000000: keep2count = 0; - 8'b00000001: keep2count = 1; - 8'b00000011: keep2count = 2; - 8'b00000111: keep2count = 3; - 8'b00001111: keep2count = 4; - 8'b00011111: keep2count = 5; - 8'b00111111: keep2count = 6; - 8'b01111111: keep2count = 7; - 8'b11111111: keep2count = 8; - endcase -endfunction - -function [7:0] count2keep; - input [3:0] k; - case (k) - 4'd0: count2keep = 8'b00000000; - 4'd1: count2keep = 8'b00000001; - 4'd2: count2keep = 8'b00000011; - 4'd3: count2keep = 8'b00000111; - 4'd4: count2keep = 8'b00001111; - 4'd5: count2keep = 8'b00011111; - 4'd6: count2keep = 8'b00111111; - 4'd7: count2keep = 8'b01111111; - 4'd8: count2keep = 8'b11111111; - endcase -endfunction +integer offset, i, bit_cnt; always @* begin state_next = 2'bz; @@ -158,7 +144,15 @@ always @* begin if (output_axis_tready_int) begin frame_ptr_next = 1; - output_axis_tdata_int = tag[15:8]; + if (TAG_ENABLE) begin + output_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; + end else if (TICK_COUNT_ENABLE) begin + output_axis_tdata_int = tag[(TICK_COUNT_BYTE_WIDTH-1)*8 +: 8]; + end else if (BYTE_COUNT_ENABLE) begin + output_axis_tdata_int = tag[(BYTE_COUNT_BYTE_WIDTH-1)*8 +: 8]; + end else if (FRAME_COUNT_ENABLE) begin + output_axis_tdata_int = tag[(FRAME_COUNT_BYTE_WIDTH-1)*8 +: 8]; + end output_axis_tvalid_int = 1; end @@ -172,26 +166,44 @@ always @* begin state_next = STATE_OUTPUT_DATA; frame_ptr_next = frame_ptr_reg + 1; output_axis_tvalid_int = 1; - case (frame_ptr_reg) - 5'd00: output_axis_tdata_int = tag[15:8]; - 5'd01: output_axis_tdata_int = tag[7:0]; - 5'd02: output_axis_tdata_int = tick_count_output_reg[31:24]; - 5'd03: output_axis_tdata_int = tick_count_output_reg[23:16]; - 5'd04: output_axis_tdata_int = tick_count_output_reg[15: 8]; - 5'd05: output_axis_tdata_int = tick_count_output_reg[ 7: 0]; - 5'd06: output_axis_tdata_int = byte_count_output_reg[31:24]; - 5'd07: output_axis_tdata_int = byte_count_output_reg[23:16]; - 5'd08: output_axis_tdata_int = byte_count_output_reg[15: 8]; - 5'd09: output_axis_tdata_int = byte_count_output_reg[ 7: 0]; - 5'd10: output_axis_tdata_int = frame_count_output_reg[31:24]; - 5'd11: output_axis_tdata_int = frame_count_output_reg[23:16]; - 5'd12: output_axis_tdata_int = frame_count_output_reg[15: 8]; - 5'd13: begin - output_axis_tdata_int = frame_count_output_reg[ 7: 0]; - output_axis_tlast_int = 1; - state_next = STATE_IDLE; + + offset = 0; + if (TAG_ENABLE) begin + for (i = TAG_BYTE_WIDTH-1; i >= 0; i = i - 1) begin + if (frame_ptr_reg == offset) begin + output_axis_tdata_int = tag[i*8 +: 8]; + end + offset = offset + 1; end - endcase + end + if (TICK_COUNT_ENABLE) begin + for (i = TICK_COUNT_BYTE_WIDTH-1; i >= 0; i = i - 1) begin + if (frame_ptr_reg == offset) begin + output_axis_tdata_int = tick_count_output_reg[i*8 +: 8]; + end + offset = offset + 1; + end + end + if (BYTE_COUNT_ENABLE) begin + for (i = BYTE_COUNT_BYTE_WIDTH-1; i >= 0; i = i - 1) begin + if (frame_ptr_reg == offset) begin + output_axis_tdata_int = byte_count_output_reg[i*8 +: 8]; + end + offset = offset + 1; + end + end + if (FRAME_COUNT_ENABLE) begin + for (i = FRAME_COUNT_BYTE_WIDTH-1; i >= 0; i = i - 1) begin + if (frame_ptr_reg == offset) begin + output_axis_tdata_int = frame_count_output_reg[i*8 +: 8]; + end + offset = offset + 1; + end + end + if (frame_ptr_reg == offset-1) begin + output_axis_tlast_int = 1; + state_next = STATE_IDLE; + end end else begin state_next = STATE_OUTPUT_DATA; end @@ -207,7 +219,11 @@ always @* begin // valid transfer cycle // increment byte count by number of words transferred - byte_count_next = byte_count_next + keep2count(monitor_axis_tkeep); + bit_cnt = 0; + for (i = 0; i < KEEP_WIDTH; i = i + 1) begin + bit_cnt = bit_cnt + monitor_axis_tkeep[i]; + end + byte_count_next = byte_count_next + bit_cnt; // count frames if (monitor_axis_tlast) begin diff --git a/tb/test_axis_frame_join_4.v b/tb/test_axis_frame_join_4.v index 21e005b32..ea280c3d6 100644 --- a/tb/test_axis_frame_join_4.v +++ b/tb/test_axis_frame_join_4.v @@ -102,7 +102,7 @@ initial begin end axis_frame_join_4 #( - .ENABLE_TAG(1) + .TAG_ENABLE(1) ) UUT ( .clk(clk), From fc6ccd97fb0c5e023e3cefbc13d6301a8110aaca Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 20 Nov 2014 12:11:11 -0800 Subject: [PATCH 117/617] Rework IP modules --- rtl/ip.v | 97 +++++++++++++--------------------------------------- rtl/ip_64.v | 98 +++++++++++++---------------------------------------- 2 files changed, 47 insertions(+), 148 deletions(-) diff --git a/rtl/ip.v b/rtl/ip.v index f785b5c74..3d888d5b5 100644 --- a/rtl/ip.v +++ b/rtl/ip.v @@ -135,41 +135,10 @@ module ip input wire [31:0] local_ip ); -/* - -IP Frame - - Field Length - Destination MAC address 6 octets - Source MAC address 6 octets - Ethertype (0x0800) 2 octets - Version (4) 4 bits - IHL (5-15) 4 bits - DSCP (0) 6 bits - ECN (0) 2 bits - length 2 octets - identification (0?) 2 octets - flags (010) 3 bits - fragment offset (0) 13 bits - time to live (64?) 1 octet - protocol 1 octet - header checksum 2 octets - source IP 4 octets - destination IP 4 octets - options (IHL-5)*4 octets - payload length octets - -This module receives an Ethernet frame with decoded fields and decodes -the AXI packet format. If the Ethertype does not match, the packet is -discarded. - -*/ - localparam [1:0] STATE_IDLE = 2'd0, STATE_ARP_QUERY = 2'd1, - STATE_SEND_PACKET = 2'd2, - STATE_DROP_PACKET = 2'd3; + STATE_WAIT_PACKET = 2'd2; reg [1:0] state_reg = STATE_IDLE, state_next; @@ -271,9 +240,9 @@ ip_eth_tx_inst ( reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; -reg arp_request_valid_reg = 0; +reg arp_request_valid_reg = 0, arp_request_valid_next; -reg drop_packet_reg = 0; +reg drop_packet_reg = 0, drop_packet_next; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; @@ -286,6 +255,9 @@ assign tx_error_arp_failed = arp_response_error; always @* begin state_next = 8'bz; + arp_request_valid_next = 0; + drop_packet_next = 0; + input_ip_hdr_ready_next = 0; outgoing_ip_hdr_valid_next = outgoing_ip_hdr_valid_reg & ~outgoing_ip_hdr_ready; @@ -296,43 +268,43 @@ always @* begin // wait for outgoing packet if (input_ip_hdr_valid) begin // initiate ARP request + arp_request_valid_next = 1; state_next = STATE_ARP_QUERY; end else begin state_next = STATE_IDLE; end end STATE_ARP_QUERY: begin + arp_request_valid_next = 1; + if (arp_response_valid) begin // wait for ARP reponse if (arp_response_error) begin // did not get MAC address; drop packet input_ip_hdr_ready_next = 1; - state_next = STATE_DROP_PACKET; + arp_request_valid_next = 0; + drop_packet_next = 1; + state_next = STATE_WAIT_PACKET; end else begin // got MAC address; send packet input_ip_hdr_ready_next = 1; + arp_request_valid_next = 0; outgoing_ip_hdr_valid_next = 1; outgoing_eth_dest_mac_next = arp_response_mac; - state_next = STATE_SEND_PACKET; + state_next = STATE_WAIT_PACKET; end end else begin state_next = STATE_ARP_QUERY; end end - STATE_SEND_PACKET: begin + STATE_WAIT_PACKET: begin + drop_packet_next = drop_packet_reg; + // wait for packet transfer to complete - if (input_ip_payload_tlast & input_ip_payload_tvalid) begin + if (input_ip_payload_tlast & input_ip_payload_tready & input_ip_payload_tvalid) begin state_next = STATE_IDLE; end else begin - state_next = STATE_SEND_PACKET; - end - end - STATE_DROP_PACKET: begin - // wait for packet transfer to complete - if (input_ip_payload_tlast & input_ip_payload_tvalid) begin - state_next = STATE_IDLE; - end else begin - state_next = STATE_DROP_PACKET; + state_next = STATE_WAIT_PACKET; end end endcase @@ -342,43 +314,20 @@ always @(posedge clk or posedge rst) begin if (rst) begin state_reg <= STATE_IDLE; arp_request_valid_reg <= 0; + drop_packet_reg <= 0; input_ip_hdr_ready_reg <= 0; outgoing_ip_hdr_valid_reg <= 1'b0; outgoing_eth_dest_mac_reg <= 48'h000000000000; - drop_packet_reg <= 0; - end else begin state_reg <= state_next; + arp_request_valid_reg <= arp_request_valid_next; + drop_packet_reg <= drop_packet_next; + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; outgoing_ip_hdr_valid_reg <= outgoing_ip_hdr_valid_next; outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; - - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; wait for IP packet - arp_request_valid_reg <= 0; - drop_packet_reg <= 0; - end - STATE_ARP_QUERY: begin - // wait for ARP reponse - arp_request_valid_reg <= 1; - drop_packet_reg <= 0; - end - STATE_SEND_PACKET: begin - // wait for packet transfer to complete - arp_request_valid_reg <= 0; - drop_packet_reg <= 0; - end - STATE_DROP_PACKET: begin - // wait for packet transfer to complete - arp_request_valid_reg <= 0; - drop_packet_reg <= 1; - end - endcase - end end diff --git a/rtl/ip_64.v b/rtl/ip_64.v index b1d1ee99b..9eae37d9a 100644 --- a/rtl/ip_64.v +++ b/rtl/ip_64.v @@ -139,41 +139,10 @@ module ip_64 input wire [31:0] local_ip ); -/* - -IP Frame - - Field Length - Destination MAC address 6 octets - Source MAC address 6 octets - Ethertype (0x0800) 2 octets - Version (4) 4 bits - IHL (5-15) 4 bits - DSCP (0) 6 bits - ECN (0) 2 bits - length 2 octets - identification (0?) 2 octets - flags (010) 3 bits - fragment offset (0) 13 bits - time to live (64?) 1 octet - protocol 1 octet - header checksum 2 octets - source IP 4 octets - destination IP 4 octets - options (IHL-5)*4 octets - payload length octets - -This module receives an Ethernet frame with decoded fields and decodes -the AXI packet format. If the Ethertype does not match, the packet is -discarded. - -*/ - localparam [1:0] STATE_IDLE = 2'd0, STATE_ARP_QUERY = 2'd1, - STATE_SEND_PACKET = 2'd2, - STATE_DROP_PACKET = 2'd3; + STATE_WAIT_PACKET = 2'd2; reg [1:0] state_reg = STATE_IDLE, state_next; @@ -277,11 +246,12 @@ ip_eth_tx_64_inst ( .error_payload_early_termination(tx_error_payload_early_termination) ); + reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; -reg arp_request_valid_reg = 0; +reg arp_request_valid_reg = 0, arp_request_valid_next; -reg drop_packet_reg = 0; +reg drop_packet_reg = 0, drop_packet_next; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; @@ -294,6 +264,9 @@ assign tx_error_arp_failed = arp_response_error; always @* begin state_next = 8'bz; + arp_request_valid_next = 0; + drop_packet_next = 0; + input_ip_hdr_ready_next = 0; outgoing_ip_hdr_valid_next = outgoing_ip_hdr_valid_reg & ~outgoing_ip_hdr_ready; @@ -304,43 +277,43 @@ always @* begin // wait for outgoing packet if (input_ip_hdr_valid) begin // initiate ARP request + arp_request_valid_next = 1; state_next = STATE_ARP_QUERY; end else begin state_next = STATE_IDLE; end end STATE_ARP_QUERY: begin + arp_request_valid_next = 1; + if (arp_response_valid) begin // wait for ARP reponse if (arp_response_error) begin // did not get MAC address; drop packet input_ip_hdr_ready_next = 1; - state_next = STATE_DROP_PACKET; + arp_request_valid_next = 0; + drop_packet_next = 1; + state_next = STATE_WAIT_PACKET; end else begin // got MAC address; send packet input_ip_hdr_ready_next = 1; + arp_request_valid_next = 0; outgoing_ip_hdr_valid_next = 1; outgoing_eth_dest_mac_next = arp_response_mac; - state_next = STATE_SEND_PACKET; + state_next = STATE_WAIT_PACKET; end end else begin state_next = STATE_ARP_QUERY; end end - STATE_SEND_PACKET: begin + STATE_WAIT_PACKET: begin + drop_packet_next = drop_packet_reg; + // wait for packet transfer to complete - if (input_ip_payload_tlast & input_ip_payload_tvalid) begin + if (input_ip_payload_tlast & input_ip_payload_tready & input_ip_payload_tvalid) begin state_next = STATE_IDLE; end else begin - state_next = STATE_SEND_PACKET; - end - end - STATE_DROP_PACKET: begin - // wait for packet transfer to complete - if (input_ip_payload_tlast & input_ip_payload_tvalid) begin - state_next = STATE_IDLE; - end else begin - state_next = STATE_DROP_PACKET; + state_next = STATE_WAIT_PACKET; end end endcase @@ -350,43 +323,20 @@ always @(posedge clk or posedge rst) begin if (rst) begin state_reg <= STATE_IDLE; arp_request_valid_reg <= 0; + drop_packet_reg <= 0; input_ip_hdr_ready_reg <= 0; outgoing_ip_hdr_valid_reg <= 1'b0; outgoing_eth_dest_mac_reg <= 48'h000000000000; - drop_packet_reg <= 0; - end else begin state_reg <= state_next; + arp_request_valid_reg <= arp_request_valid_next; + drop_packet_reg <= drop_packet_next; + input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; outgoing_ip_hdr_valid_reg <= outgoing_ip_hdr_valid_next; outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; - - // generate valid outputs - case (state_next) - STATE_IDLE: begin - // idle; wait for IP packet - arp_request_valid_reg <= 0; - drop_packet_reg <= 0; - end - STATE_ARP_QUERY: begin - // wait for ARP reponse - arp_request_valid_reg <= 1; - drop_packet_reg <= 0; - end - STATE_SEND_PACKET: begin - // wait for packet transfer to complete - arp_request_valid_reg <= 0; - drop_packet_reg <= 0; - end - STATE_DROP_PACKET: begin - // wait for packet transfer to complete - arp_request_valid_reg <= 0; - drop_packet_reg <= 1; - end - endcase - end end From f35ecece83607aafd21cd8a5a5848e4de7bb37f4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 20 Nov 2014 22:52:52 -0800 Subject: [PATCH 118/617] Initialize tkeep properly --- rtl/arp_eth_tx_64.v | 1 + 1 file changed, 1 insertion(+) diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index ee12b501e..5b49ea1e9 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -152,6 +152,7 @@ always @* begin output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; output_eth_payload_tdata_int = 0; + output_eth_payload_tkeep_int = 0; output_eth_payload_tvalid_int = 0; output_eth_payload_tlast_int = 0; output_eth_payload_tuser_int = 0; From 7fdb7b4f356b4942afbb113242bf3e229dd4d3e4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 20 Nov 2014 22:54:08 -0800 Subject: [PATCH 119/617] Add ARP cache module --- rtl/arp_cache.v | 178 ++++++++++++++ tb/test_arp_cache.py | 549 +++++++++++++++++++++++++++++++++++++++++++ tb/test_arp_cache.v | 97 ++++++++ 3 files changed, 824 insertions(+) create mode 100644 rtl/arp_cache.v create mode 100755 tb/test_arp_cache.py create mode 100755 tb/test_arp_cache.v diff --git a/rtl/arp_cache.v b/rtl/arp_cache.v new file mode 100644 index 000000000..0f2835bb3 --- /dev/null +++ b/rtl/arp_cache.v @@ -0,0 +1,178 @@ +/* + +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 + +/* + * ARP cache block + */ +module arp_cache #( + parameter CACHE_ADDR_WIDTH = 2 +) +( + input wire clk, + input wire rst, + + /* + * Query cache + */ + input wire query_request_valid, + input wire [31:0] query_request_ip, + output wire query_response_valid, + output wire query_response_error, + output wire [47:0] query_response_mac, + + /* + * Write cache + */ + input wire write_request_valid, + input wire [31:0] write_request_ip, + input wire [47:0] write_request_mac, + output wire write_in_progress, + output wire write_complete, + + /* + * Configuration + */ + input wire clear_cache +); + +// bit LRU cache + +reg [31:0] ip_addr_mem[(2**CACHE_ADDR_WIDTH)-1:0]; +reg [47:0] mac_addr_mem[(2**CACHE_ADDR_WIDTH)-1:0]; +reg [(2**CACHE_ADDR_WIDTH)-1:0] lru_bit = 0; + +reg query_response_valid_reg = 0; +reg query_response_error_reg = 0; +reg [47:0] query_response_mac_reg = 0; + +reg write_complete_reg = 0; + +localparam [2:0] + WRITE_STATE_IDLE = 0, + WRITE_STATE_SEARCH = 1, + WRITE_STATE_NOTFOUND = 2; + +reg [2:0] write_state = WRITE_STATE_IDLE; +reg [31:0] write_ip_reg = 0; +reg [47:0] write_mac_reg = 0; +reg [CACHE_ADDR_WIDTH-1:0] write_addr = 0; +reg [CACHE_ADDR_WIDTH-1:0] write_ptr = 0; + +wire write_state_idle = (write_state == WRITE_STATE_IDLE); +wire write_state_search = (write_state == WRITE_STATE_SEARCH); +wire write_state_notfound = (write_state == WRITE_STATE_NOTFOUND); + +reg clear_cache_operation = 0; + +assign query_response_valid = query_response_valid_reg; +assign query_response_error = query_response_error_reg; +assign query_response_mac = query_response_mac_reg; + +assign write_in_progress = ~write_state_idle; +assign write_complete = write_complete_reg; + +wire lru_full = &lru_bit; + +integer i; + +always @(posedge clk or posedge rst) begin + if (rst) begin + query_response_valid_reg <= 0; + query_response_error_reg <= 0; + write_complete_reg <= 0; + write_state <= WRITE_STATE_IDLE; + write_addr <= 0; + write_ptr <= 0; + clear_cache_operation <= 1; + lru_bit <= 0; + end else begin + write_complete_reg <= 0; + query_response_valid_reg <= 0; + query_response_error_reg <= 0; + + // clear LRU bits when full + if (lru_full) begin + lru_bit <= 0; + end + + // fast IP match and readout + if (query_request_valid) begin + query_response_valid_reg <= 1; + query_response_error_reg <= 1; + for (i = 0; i < 2**CACHE_ADDR_WIDTH; i = i + 1) begin + if (ip_addr_mem[i] == query_request_ip) begin + query_response_error_reg <= 0; + query_response_mac_reg <= mac_addr_mem[i]; + lru_bit[i] <= 1'b1; + end + end + end + + // manage writes + if (write_state_idle) begin + if (write_request_valid) begin + write_state <= WRITE_STATE_SEARCH; + write_ip_reg <= write_request_ip; + write_mac_reg <= write_request_mac; + end + write_addr <= 0; + end else if (write_state_search) begin + write_addr <= write_addr + 1; + if (&write_addr) begin + write_state <= WRITE_STATE_NOTFOUND; + end + if (ip_addr_mem[write_addr] == write_ip_reg) begin + write_state <= WRITE_STATE_IDLE; + mac_addr_mem[write_addr] <= write_mac_reg; + write_complete_reg <= 1; + end + end else if (write_state_notfound) begin + write_ptr <= write_ptr + 1; + if (~lru_bit[write_ptr]) begin + ip_addr_mem[write_ptr] <= write_ip_reg; + mac_addr_mem[write_ptr] <= write_mac_reg; + write_state <= WRITE_STATE_IDLE; + write_complete_reg <= 1; + end + end + + // clear cache + if (clear_cache & ~clear_cache_operation) begin + clear_cache_operation <= 1; + write_addr <= 0; + end + if (clear_cache_operation) begin + write_addr <= write_addr + 1; + ip_addr_mem[write_addr] <= 0; + mac_addr_mem[write_addr] <= 0; + clear_cache_operation <= ~&write_addr; + end + end +end + +endmodule diff --git a/tb/test_arp_cache.py b/tb/test_arp_cache.py new file mode 100755 index 000000000..a31451d44 --- /dev/null +++ b/tb/test_arp_cache.py @@ -0,0 +1,549 @@ +#!/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 + +module = 'arp_cache' + +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_arp_cache(clk, + rst, + current_test, + + query_request_valid, + query_request_ip, + query_response_valid, + query_response_error, + query_response_mac, + + write_request_valid, + write_request_ip, + write_request_mac, + write_in_progress, + write_complete, + + clear_cache): + + 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, + + query_request_valid=query_request_valid, + query_request_ip=query_request_ip, + query_response_valid=query_response_valid, + query_response_error=query_response_error, + query_response_mac=query_response_mac, + + write_request_valid=write_request_valid, + write_request_ip=write_request_ip, + write_request_mac=write_request_mac, + write_in_progress=write_in_progress, + write_complete=write_complete, + + clear_cache=clear_cache) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + query_request_valid = Signal(bool(0)) + query_request_ip = Signal(intbv(0)[32:]) + + write_request_valid = Signal(bool(0)) + write_request_ip = Signal(intbv(0)[32:]) + write_request_mac = Signal(intbv(0)[48:]) + + clear_cache = Signal(bool(0)) + + # Outputs + query_response_valid = Signal(bool(0)) + query_response_error = Signal(bool(0)) + query_response_mac = Signal(intbv(0)[48:]) + + write_in_progress = Signal(bool(0)) + write_complete = Signal(bool(0)) + + # DUT + dut = dut_arp_cache(clk, + rst, + current_test, + + query_request_valid, + query_request_ip, + query_response_valid, + query_response_error, + query_response_mac, + + write_request_valid, + write_request_ip, + write_request_mac, + write_in_progress, + write_complete, + + clear_cache) + + @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 + print("test 1: write") + current_test.next = 1 + + yield clk.posedge + write_request_valid.next = True + write_request_ip.next = 0xc0a80111 + write_request_mac.next = 0x0000c0a80111 + yield clk.posedge + write_request_valid.next = False + + yield write_complete.posedge + yield clk.posedge + + yield clk.posedge + write_request_valid.next = True + write_request_ip.next = 0xc0a80112 + write_request_mac.next = 0x0000c0a80112 + yield clk.posedge + write_request_valid.next = False + + yield write_complete.posedge + yield clk.posedge + + yield delay(100) + + yield clk.posedge + print("test 2: read") + current_test.next = 2 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80111 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80111 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80112 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80112 + + # not in cache; was not written + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80113 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield delay(100) + + yield clk.posedge + print("test 3: write more") + current_test.next = 3 + + yield clk.posedge + write_request_valid.next = True + write_request_ip.next = 0xc0a80121 + write_request_mac.next = 0x0000c0a80121 + yield clk.posedge + write_request_valid.next = False + + yield write_complete.posedge + yield clk.posedge + + yield clk.posedge + write_request_valid.next = True + write_request_ip.next = 0xc0a80122 + write_request_mac.next = 0x0000c0a80122 + yield clk.posedge + write_request_valid.next = False + + yield write_complete.posedge + yield clk.posedge + + # overwrites 0xc0a80121 due to LRU + yield clk.posedge + write_request_valid.next = True + write_request_ip.next = 0xc0a80123 + write_request_mac.next = 0x0000c0a80123 + yield clk.posedge + write_request_valid.next = False + + yield write_complete.posedge + yield clk.posedge + + yield delay(100) + + yield clk.posedge + print("test 4: read more") + current_test.next = 4 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80111 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80111 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80112 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80112 + + # not in cache; was overwritten + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80121 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80122 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80122 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80123 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80123 + + # LRU reset by previous operation + + yield delay(100) + + yield clk.posedge + print("test 5: LRU test") + current_test.next = 5 + + # read to set LRU bit + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80111 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80111 + + yield clk.posedge + write_request_valid.next = True + write_request_ip.next = 0xc0a80131 + write_request_mac.next = 0x0000c0a80131 + yield clk.posedge + write_request_valid.next = False + + yield write_complete.posedge + yield clk.posedge + + yield clk.posedge + write_request_valid.next = True + write_request_ip.next = 0xc0a80132 + write_request_mac.next = 0x0000c0a80132 + yield clk.posedge + write_request_valid.next = False + + yield write_complete.posedge + yield clk.posedge + + yield clk.posedge + write_request_valid.next = True + write_request_ip.next = 0xc0a80133 + write_request_mac.next = 0x0000c0a80133 + yield clk.posedge + write_request_valid.next = False + + yield write_complete.posedge + yield clk.posedge + + # read values + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80111 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80111 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80112 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80121 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80122 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80123 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80131 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80131 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80132 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80132 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80133 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80133 + + # LRU reset by previous operation + + yield delay(100) + + yield clk.posedge + print("test 6: Test overwrite") + current_test.next = 6 + + yield clk.posedge + write_request_valid.next = True + write_request_ip.next = 0xc0a80133 + write_request_mac.next = 0x0000c0a80164 + yield clk.posedge + write_request_valid.next = False + + yield write_complete.posedge + yield clk.posedge + + # read values + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80111 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80111 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80112 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80121 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80122 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80123 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80131 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80131 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80132 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80132 + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80133 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert not bool(query_response_error) + assert int(query_response_mac) == 0x0000c0a80164 + + # LRU reset by previous operation + + yield delay(100) + + yield clk.posedge + print("test 7: clear cache") + current_test.next = 7 + + yield clk.posedge + clear_cache.next = True + yield clk.posedge + clear_cache.next = False + + yield delay(100) + + yield clk.posedge + query_request_valid.next = True + query_request_ip.next = 0xc0a80111 + yield clk.posedge + query_request_valid.next = False + + yield query_response_valid.posedge + assert bool(query_response_error) + + yield delay(100) + + raise StopSimulation + + return dut, 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() + diff --git a/tb/test_arp_cache.v b/tb/test_arp_cache.v new file mode 100755 index 000000000..ff6c81f73 --- /dev/null +++ b/tb/test_arp_cache.v @@ -0,0 +1,97 @@ +/* + +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_arp_cache; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg query_request_valid = 0; +reg [31:0] query_request_ip = 0; + +reg write_request_valid = 0; +reg [31:0] write_request_ip = 0; +reg [47:0] write_request_mac = 0; + +reg clear_cache = 0; + +// Outputs +wire query_response_valid; +wire query_response_error; +wire [47:0] query_response_mac; + +wire write_in_progress; +wire write_complete; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + query_request_valid, + query_request_ip, + write_request_valid, + write_request_ip, + write_request_mac, + clear_cache); + $to_myhdl(query_response_valid, + query_response_error, + query_response_mac, + write_in_progress, + write_complete); + + // dump file + $dumpfile("test_arp_cache.lxt"); + $dumpvars(0, test_arp_cache); +end + +arp_cache #( + .CACHE_ADDR_WIDTH(2) +) +UUT ( + .clk(clk), + .rst(rst), + // Query cache + .query_request_valid(query_request_valid), + .query_request_ip(query_request_ip), + .query_response_valid(query_response_valid), + .query_response_error(query_response_error), + .query_response_mac(query_response_mac), + // Write cache + .write_request_valid(write_request_valid), + .write_request_ip(write_request_ip), + .write_request_mac(write_request_mac), + .write_in_progress(write_in_progress), + .write_complete(write_complete), + // Configuration + .clear_cache(clear_cache) +); + +endmodule From 2ae3581144f1acb3411ae39399cc3de757ad8e9c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 20 Nov 2014 22:55:28 -0800 Subject: [PATCH 120/617] Add ARP module and testbench --- rtl/arp.v | 427 +++++++++++++++++++++++++++++++++++++ rtl/arp_64.v | 431 +++++++++++++++++++++++++++++++++++++ tb/test_arp.py | 516 +++++++++++++++++++++++++++++++++++++++++++++ tb/test_arp.v | 160 ++++++++++++++ tb/test_arp_64.py | 526 ++++++++++++++++++++++++++++++++++++++++++++++ tb/test_arp_64.v | 166 +++++++++++++++ 6 files changed, 2226 insertions(+) create mode 100644 rtl/arp.v create mode 100644 rtl/arp_64.v create mode 100755 tb/test_arp.py create mode 100644 tb/test_arp.v create mode 100755 tb/test_arp_64.py create mode 100644 tb/test_arp_64.v diff --git a/rtl/arp.v b/rtl/arp.v new file mode 100644 index 000000000..000fa85ec --- /dev/null +++ b/rtl/arp.v @@ -0,0 +1,427 @@ +/* + +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 + +/* + * ARP block for IPv4, ethernet frame interface + */ +module arp #( + parameter CACHE_ADDR_WIDTH = 2, + parameter REQUEST_RETRY_COUNT = 4, + parameter REQUEST_RETRY_INTERVAL = 125000000*2, + parameter REQUEST_TIMEOUT = 125000000*30 +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [7:0] input_eth_payload_tdata, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * ARP requests + */ + input wire arp_request_valid, + input wire [31:0] arp_request_ip, + output wire arp_response_valid, + output wire arp_response_error, + output wire [47:0] arp_response_mac, + + /* + * Configuration + */ + input wire [47:0] local_mac, + input wire [31:0] local_ip, + input wire [31:0] gateway_ip, + input wire [31:0] subnet_mask, + input wire clear_cache +); + +localparam [15:0] + ARP_OPER_ARP_REQUEST = 16'h0001, + ARP_OPER_ARP_REPLY = 16'h0002, + ARP_OPER_INARP_REQUEST = 16'h0008, + ARP_OPER_INARP_REPLY = 16'h0009; + +wire incoming_frame_valid; +wire incoming_frame_ready; +wire [47:0] incoming_eth_dest_mac; +wire [47:0] incoming_eth_src_mac; +wire [15:0] incoming_eth_type; +wire [15:0] incoming_arp_htype; +wire [15:0] incoming_arp_ptype; +wire [7:0] incoming_arp_hlen; +wire [7:0] incoming_arp_plen; +wire [15:0] incoming_arp_oper; +wire [47:0] incoming_arp_sha; +wire [31:0] incoming_arp_spa; +wire [47:0] incoming_arp_tha; +wire [31:0] incoming_arp_tpa; + +reg outgoing_frame_valid_reg = 0, outgoing_frame_valid_next; +wire outgoing_frame_ready; +reg [47:0] outgoing_eth_dest_mac_reg = 0, outgoing_eth_dest_mac_next; +reg [15:0] outgoing_arp_oper_reg = 0, outgoing_arp_oper_next; +reg [47:0] outgoing_arp_tha_reg = 0, outgoing_arp_tha_next; +reg [31:0] outgoing_arp_tpa_reg = 0, outgoing_arp_tpa_next; + +// drop frame +reg drop_incoming_frame_reg = 0, drop_incoming_frame_next; + +// wait on incoming frames until we can reply +assign incoming_frame_ready = outgoing_frame_ready | drop_incoming_frame_reg; + +/* + * ARP frame processing + */ +arp_eth_rx +arp_eth_rx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // ARP frame output + .output_frame_valid(incoming_frame_valid), + .output_frame_ready(incoming_frame_ready), + .output_eth_dest_mac(incoming_eth_dest_mac), + .output_eth_src_mac(incoming_eth_src_mac), + .output_eth_type(incoming_eth_type), + .output_arp_htype(incoming_arp_htype), + .output_arp_ptype(incoming_arp_ptype), + .output_arp_hlen(incoming_arp_hlen), + .output_arp_plen(incoming_arp_plen), + .output_arp_oper(incoming_arp_oper), + .output_arp_sha(incoming_arp_sha), + .output_arp_spa(incoming_arp_spa), + .output_arp_tha(incoming_arp_tha), + .output_arp_tpa(incoming_arp_tpa), + // Status signals + .busy(), + .error_header_early_termination(), + .error_invalid_header() +); + +arp_eth_tx +arp_eth_tx_inst ( + .clk(clk), + .rst(rst), + // ARP frame input + .input_frame_valid(outgoing_frame_valid_reg), + .input_frame_ready(outgoing_frame_ready), + .input_eth_dest_mac(outgoing_eth_dest_mac_reg), + .input_eth_src_mac(local_mac), + .input_eth_type(16'h0806), + .input_arp_htype(16'h0001), + .input_arp_ptype(16'h0800), + .input_arp_oper(outgoing_arp_oper_reg), + .input_arp_sha(local_mac), + .input_arp_spa(local_ip), + .input_arp_tha(outgoing_arp_tha_reg), + .input_arp_tpa(outgoing_arp_tpa_reg), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Status signals + .busy() +); + +wire incoming_eth_type_valid = (incoming_eth_type == 16'h0806); +wire incoming_arp_htype_valid = (incoming_arp_htype == 16'h0001); +wire incoming_arp_ptype_valid = (incoming_arp_ptype == 16'h0800); + +wire incoming_arp_oper_arp_request = (incoming_arp_oper == ARP_OPER_ARP_REQUEST); +wire incoming_arp_oper_arp_reply = (incoming_arp_oper == ARP_OPER_ARP_REPLY); +wire incoming_arp_oper_inarp_request = (incoming_arp_oper == ARP_OPER_INARP_REQUEST); +wire incoming_arp_oper_inarp_reply = (incoming_arp_oper == ARP_OPER_INARP_REPLY); + +wire filtered_incoming_frame_valid = incoming_frame_valid & + incoming_eth_type_valid & + incoming_arp_htype_valid & + incoming_arp_ptype_valid; + +wire filtered_incoming_arp_oper_arp_request = filtered_incoming_frame_valid & incoming_arp_oper_arp_request; +wire filtered_incoming_arp_oper_arp_reply = filtered_incoming_frame_valid & incoming_arp_oper_arp_reply; +wire filtered_incoming_arp_oper_inarp_request = filtered_incoming_frame_valid & incoming_arp_oper_inarp_request; +wire filtered_incoming_arp_oper_inarp_reply = filtered_incoming_frame_valid & incoming_arp_oper_inarp_reply; + +wire cache_query_request_valid; +wire [31:0] cache_query_request_ip; +wire cache_query_response_valid; +wire cache_query_response_error; +wire [47:0] cache_query_response_mac; + +reg cache_write_request_valid_reg = 0, cache_write_request_valid_next; +reg [31:0] cache_write_request_ip_reg = 0, cache_write_request_ip_next; +reg [47:0] cache_write_request_mac_reg = 0, cache_write_request_mac_next; +wire cache_write_in_progress; +wire cache_write_complete; + +/* + * ARP cache + */ +arp_cache #( + .CACHE_ADDR_WIDTH(CACHE_ADDR_WIDTH) +) +arp_cache_inst ( + .clk(clk), + .rst(rst), + // Query cache + .query_request_valid(cache_query_request_valid), + .query_request_ip(cache_query_request_ip), + .query_response_valid(cache_query_response_valid), + .query_response_error(cache_query_response_error), + .query_response_mac(cache_query_response_mac), + // Write cache + .write_request_valid(cache_write_request_valid_reg), + .write_request_ip(cache_write_request_ip_reg), + .write_request_mac(cache_write_request_mac_reg), + .write_in_progress(cache_write_in_progress), + .write_complete(cache_write_complete), + // Configuration + .clear_cache(clear_cache) +); + +reg arp_request_operation_reg = 0, arp_request_operation_next; + +reg arp_request_valid_reg = 0, arp_request_valid_next; +reg [31:0] arp_request_ip_reg = 0, arp_request_ip_next; + +reg arp_response_error_reg = 0, arp_response_error_next; +reg arp_response_broadcast_reg = 0, arp_response_broadcast_next; + +reg [5:0] arp_request_retry_cnt_reg = 0, arp_request_retry_cnt_next; +reg [35:0] arp_request_timer_reg = 0, arp_request_timer_next; + +assign cache_query_request_valid = ~arp_request_operation_reg ? arp_request_valid_reg : 1'b1; +assign cache_query_request_ip = arp_request_ip_reg; + +assign arp_response_valid = arp_response_error_reg | (cache_query_response_valid & ~cache_query_response_error & ~arp_request_operation_reg) | arp_response_broadcast_reg; +assign arp_response_error = arp_response_error_reg; +assign arp_response_mac = arp_response_broadcast_reg ? 48'hffffffffffff : cache_query_response_mac; + +always @* begin + outgoing_frame_valid_next = outgoing_frame_valid_reg & ~outgoing_frame_ready; + outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; + outgoing_arp_oper_next = outgoing_arp_oper_reg; + outgoing_arp_tha_next = outgoing_arp_tha_reg; + outgoing_arp_tpa_next = outgoing_arp_tpa_reg; + + cache_write_request_valid_next = 0; + cache_write_request_mac_next = 0; + cache_write_request_ip_next = 0; + + arp_request_valid_next = 0; + arp_request_ip_next = arp_request_ip_reg; + arp_request_operation_next = arp_request_operation_reg; + arp_request_retry_cnt_next = arp_request_retry_cnt_reg; + arp_request_timer_next = arp_request_timer_reg; + arp_response_error_next = 0; + arp_response_broadcast_next = 0; + + drop_incoming_frame_next = 0; + + // manage incoming frames + if (filtered_incoming_frame_valid & ~(outgoing_frame_valid_reg & ~outgoing_frame_ready)) begin + // store sender addresses in cache + cache_write_request_valid_next = 1; + cache_write_request_ip_next = incoming_arp_spa; + cache_write_request_mac_next = incoming_arp_sha; + if (incoming_arp_oper_arp_request) begin + if (incoming_arp_tpa == local_ip) begin + // send reply frame to valid incoming request + outgoing_frame_valid_next = 1; + outgoing_eth_dest_mac_next = incoming_eth_src_mac; + outgoing_arp_oper_next = ARP_OPER_ARP_REPLY; + outgoing_arp_tha_next = incoming_arp_sha; + outgoing_arp_tpa_next = incoming_arp_spa; + end else begin + // does not match -> drop it + drop_incoming_frame_next = 1; + end + end else if (incoming_arp_oper_inarp_request) begin + if (incoming_arp_tha == local_mac) begin + // send reply frame to valid incoming request + outgoing_frame_valid_next = 1; + outgoing_eth_dest_mac_next = incoming_eth_src_mac; + outgoing_arp_oper_next = ARP_OPER_INARP_REPLY; + outgoing_arp_tha_next = incoming_arp_sha; + outgoing_arp_tpa_next = incoming_arp_spa; + end else begin + // does not match -> drop it + drop_incoming_frame_next = 1; + end + end else begin + // does not match -> drop it + drop_incoming_frame_next = 1; + end + end else if (incoming_frame_valid & ~filtered_incoming_frame_valid) begin + // incoming invalid frame -> drop it + drop_incoming_frame_next = 1; + end + + // manage ARP lookup requests + if (~arp_request_operation_reg) begin + if (arp_request_valid) begin + if (~(arp_request_ip | subnet_mask) == 0) begin + // broadcast address + // (all bits in request IP set where subnet mask is clear) + arp_request_valid_next = 0; + arp_response_broadcast_next = 1; + end else if (((arp_request_ip ^ gateway_ip) & subnet_mask) == 0) begin + // within subnet, look up IP directly + // (no bits differ between request IP and gateway IP where subnet mask is set) + arp_request_valid_next = 1; + arp_request_ip_next = arp_request_ip; + end else begin + // outside of subnet, so look up gateway address + arp_request_valid_next = 1; + arp_request_ip_next = gateway_ip; + end + end + if (cache_query_response_error & ~arp_response_error) begin + arp_request_operation_next = 1; + // send ARP request frame + outgoing_frame_valid_next = 1; + outgoing_eth_dest_mac_next = 48'hFF_FF_FF_FF_FF_FF; + outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; + outgoing_arp_tha_next = 48'h00_00_00_00_00_00; + outgoing_arp_tpa_next = arp_request_ip_reg; + arp_request_retry_cnt_next = REQUEST_RETRY_COUNT-1; + arp_request_timer_next = REQUEST_RETRY_INTERVAL; + end + end else begin + arp_request_timer_next = arp_request_timer_reg - 1; + // if we got a response, it will go in the cache, so when the query succeds, we're done + if (cache_query_response_valid & ~cache_query_response_error) begin + arp_request_operation_next = 0; + end + // timer timeout + if (arp_request_timer_reg == 0) begin + if (arp_request_retry_cnt_reg > 0) begin + // have more retries + // send ARP request frame + outgoing_frame_valid_next = 1'b1; + outgoing_eth_dest_mac_next = 48'hFF_FF_FF_FF_FF_FF; + outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; + outgoing_arp_tha_next = 48'h00_00_00_00_00_00; + outgoing_arp_tpa_next = arp_request_ip_reg; + arp_request_retry_cnt_next = arp_request_retry_cnt_reg - 1; + if (arp_request_retry_cnt_reg > 1) begin + arp_request_timer_next = REQUEST_RETRY_INTERVAL; + end else begin + arp_request_timer_next = REQUEST_TIMEOUT; + end + end else begin + // out of retries + arp_request_operation_next = 0; + arp_response_error_next = 1; + end + end + end +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + outgoing_frame_valid_reg <= 0; + outgoing_eth_dest_mac_reg <= 0; + outgoing_arp_oper_reg <= 0; + outgoing_arp_tha_reg <= 0; + outgoing_arp_tpa_reg <= 0; + cache_write_request_valid_reg <= 0; + cache_write_request_mac_reg <= 0; + cache_write_request_ip_reg <= 0; + arp_request_valid_reg <= 0; + arp_request_ip_reg <= 0; + arp_request_operation_reg <= 0; + arp_request_retry_cnt_reg <= 0; + arp_request_timer_reg <= 0; + arp_response_error_reg <= 0; + arp_response_broadcast_reg <= 0; + drop_incoming_frame_reg <= 0; + end else begin + outgoing_frame_valid_reg <= outgoing_frame_valid_next; + outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; + outgoing_arp_oper_reg <= outgoing_arp_oper_next; + outgoing_arp_tha_reg <= outgoing_arp_tha_next; + outgoing_arp_tpa_reg <= outgoing_arp_tpa_next; + cache_write_request_valid_reg <= cache_write_request_valid_next; + cache_write_request_mac_reg <= cache_write_request_mac_next; + cache_write_request_ip_reg <= cache_write_request_ip_next; + arp_request_valid_reg <= arp_request_valid_next; + arp_request_ip_reg <= arp_request_ip_next; + arp_request_operation_reg <= arp_request_operation_next; + arp_request_retry_cnt_reg <= arp_request_retry_cnt_next; + arp_request_timer_reg <= arp_request_timer_next; + arp_response_error_reg <= arp_response_error_next; + arp_response_broadcast_reg <= arp_response_broadcast_next; + drop_incoming_frame_reg <= drop_incoming_frame_next; + end +end + +endmodule diff --git a/rtl/arp_64.v b/rtl/arp_64.v new file mode 100644 index 000000000..490e3c101 --- /dev/null +++ b/rtl/arp_64.v @@ -0,0 +1,431 @@ +/* + +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 + +/* + * ARP block for IPv4, ethernet frame interface (64 bit datapath) + */ +module arp_64 #( + parameter CACHE_ADDR_WIDTH = 2, + parameter REQUEST_RETRY_COUNT = 4, + parameter REQUEST_RETRY_INTERVAL = 125000000*2, + parameter REQUEST_TIMEOUT = 125000000*30 +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [63:0] input_eth_payload_tdata, + input wire [7:0] input_eth_payload_tkeep, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * ARP requests + */ + input wire arp_request_valid, + input wire [31:0] arp_request_ip, + output wire arp_response_valid, + output wire arp_response_error, + output wire [47:0] arp_response_mac, + + /* + * Configuration + */ + input wire [47:0] local_mac, + input wire [31:0] local_ip, + input wire [31:0] gateway_ip, + input wire [31:0] subnet_mask, + input wire clear_cache +); + +localparam [15:0] + ARP_OPER_ARP_REQUEST = 16'h0001, + ARP_OPER_ARP_REPLY = 16'h0002, + ARP_OPER_INARP_REQUEST = 16'h0008, + ARP_OPER_INARP_REPLY = 16'h0009; + +wire incoming_frame_valid; +wire incoming_frame_ready; +wire [47:0] incoming_eth_dest_mac; +wire [47:0] incoming_eth_src_mac; +wire [15:0] incoming_eth_type; +wire [15:0] incoming_arp_htype; +wire [15:0] incoming_arp_ptype; +wire [7:0] incoming_arp_hlen; +wire [7:0] incoming_arp_plen; +wire [15:0] incoming_arp_oper; +wire [47:0] incoming_arp_sha; +wire [31:0] incoming_arp_spa; +wire [47:0] incoming_arp_tha; +wire [31:0] incoming_arp_tpa; + +reg outgoing_frame_valid_reg = 0, outgoing_frame_valid_next; +wire outgoing_frame_ready; +reg [47:0] outgoing_eth_dest_mac_reg = 0, outgoing_eth_dest_mac_next; +reg [15:0] outgoing_arp_oper_reg = 0, outgoing_arp_oper_next; +reg [47:0] outgoing_arp_tha_reg = 0, outgoing_arp_tha_next; +reg [31:0] outgoing_arp_tpa_reg = 0, outgoing_arp_tpa_next; + +// drop frame +reg drop_incoming_frame_reg = 0, drop_incoming_frame_next; + +// wait on incoming frames until we can reply +assign incoming_frame_ready = outgoing_frame_ready | drop_incoming_frame_reg; + +/* + * ARP frame processing + */ +arp_eth_rx_64 +arp_eth_rx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // ARP frame output + .output_frame_valid(incoming_frame_valid), + .output_frame_ready(incoming_frame_ready), + .output_eth_dest_mac(incoming_eth_dest_mac), + .output_eth_src_mac(incoming_eth_src_mac), + .output_eth_type(incoming_eth_type), + .output_arp_htype(incoming_arp_htype), + .output_arp_ptype(incoming_arp_ptype), + .output_arp_hlen(incoming_arp_hlen), + .output_arp_plen(incoming_arp_plen), + .output_arp_oper(incoming_arp_oper), + .output_arp_sha(incoming_arp_sha), + .output_arp_spa(incoming_arp_spa), + .output_arp_tha(incoming_arp_tha), + .output_arp_tpa(incoming_arp_tpa), + // Status signals + .busy(), + .error_header_early_termination(), + .error_invalid_header() +); + +arp_eth_tx_64 +arp_eth_tx_inst ( + .clk(clk), + .rst(rst), + // ARP frame input + .input_frame_valid(outgoing_frame_valid_reg), + .input_frame_ready(outgoing_frame_ready), + .input_eth_dest_mac(outgoing_eth_dest_mac_reg), + .input_eth_src_mac(local_mac), + .input_eth_type(16'h0806), + .input_arp_htype(16'h0001), + .input_arp_ptype(16'h0800), + .input_arp_oper(outgoing_arp_oper_reg), + .input_arp_sha(local_mac), + .input_arp_spa(local_ip), + .input_arp_tha(outgoing_arp_tha_reg), + .input_arp_tpa(outgoing_arp_tpa_reg), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // Status signals + .busy() +); + +wire incoming_eth_type_valid = (incoming_eth_type == 16'h0806); +wire incoming_arp_htype_valid = (incoming_arp_htype == 16'h0001); +wire incoming_arp_ptype_valid = (incoming_arp_ptype == 16'h0800); + +wire incoming_arp_oper_arp_request = (incoming_arp_oper == ARP_OPER_ARP_REQUEST); +wire incoming_arp_oper_arp_reply = (incoming_arp_oper == ARP_OPER_ARP_REPLY); +wire incoming_arp_oper_inarp_request = (incoming_arp_oper == ARP_OPER_INARP_REQUEST); +wire incoming_arp_oper_inarp_reply = (incoming_arp_oper == ARP_OPER_INARP_REPLY); + +wire filtered_incoming_frame_valid = incoming_frame_valid & + incoming_eth_type_valid & + incoming_arp_htype_valid & + incoming_arp_ptype_valid; + +wire filtered_incoming_arp_oper_arp_request = filtered_incoming_frame_valid & incoming_arp_oper_arp_request; +wire filtered_incoming_arp_oper_arp_reply = filtered_incoming_frame_valid & incoming_arp_oper_arp_reply; +wire filtered_incoming_arp_oper_inarp_request = filtered_incoming_frame_valid & incoming_arp_oper_inarp_request; +wire filtered_incoming_arp_oper_inarp_reply = filtered_incoming_frame_valid & incoming_arp_oper_inarp_reply; + +wire cache_query_request_valid; +wire [31:0] cache_query_request_ip; +wire cache_query_response_valid; +wire cache_query_response_error; +wire [47:0] cache_query_response_mac; + +reg cache_write_request_valid_reg = 0, cache_write_request_valid_next; +reg [31:0] cache_write_request_ip_reg = 0, cache_write_request_ip_next; +reg [47:0] cache_write_request_mac_reg = 0, cache_write_request_mac_next; +wire cache_write_in_progress; +wire cache_write_complete; + +/* + * ARP cache + */ +arp_cache #( + .CACHE_ADDR_WIDTH(CACHE_ADDR_WIDTH) +) +arp_cache_inst ( + .clk(clk), + .rst(rst), + // Query cache + .query_request_valid(cache_query_request_valid), + .query_request_ip(cache_query_request_ip), + .query_response_valid(cache_query_response_valid), + .query_response_error(cache_query_response_error), + .query_response_mac(cache_query_response_mac), + // Write cache + .write_request_valid(cache_write_request_valid_reg), + .write_request_ip(cache_write_request_ip_reg), + .write_request_mac(cache_write_request_mac_reg), + .write_in_progress(cache_write_in_progress), + .write_complete(cache_write_complete), + // Configuration + .clear_cache(clear_cache) +); + +reg arp_request_operation_reg = 0, arp_request_operation_next; + +reg arp_request_valid_reg = 0, arp_request_valid_next; +reg [31:0] arp_request_ip_reg = 0, arp_request_ip_next; + +reg arp_response_error_reg = 0, arp_response_error_next; +reg arp_response_broadcast_reg = 0, arp_response_broadcast_next; + +reg [5:0] arp_request_retry_cnt_reg = 0, arp_request_retry_cnt_next; +reg [35:0] arp_request_timer_reg = 0, arp_request_timer_next; + +assign cache_query_request_valid = ~arp_request_operation_reg ? arp_request_valid_reg : 1'b1; +assign cache_query_request_ip = arp_request_ip_reg; + +assign arp_response_valid = arp_response_error_reg | (cache_query_response_valid & ~cache_query_response_error & ~arp_request_operation_reg) | arp_response_broadcast_reg; +assign arp_response_error = arp_response_error_reg; +assign arp_response_mac = arp_response_broadcast_reg ? 48'hffffffffffff : cache_query_response_mac; + +always @* begin + outgoing_frame_valid_next = outgoing_frame_valid_reg & ~outgoing_frame_ready; + outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; + outgoing_arp_oper_next = outgoing_arp_oper_reg; + outgoing_arp_tha_next = outgoing_arp_tha_reg; + outgoing_arp_tpa_next = outgoing_arp_tpa_reg; + + cache_write_request_valid_next = 0; + cache_write_request_mac_next = 0; + cache_write_request_ip_next = 0; + + arp_request_valid_next = 0; + arp_request_ip_next = arp_request_ip_reg; + arp_request_operation_next = arp_request_operation_reg; + arp_request_retry_cnt_next = arp_request_retry_cnt_reg; + arp_request_timer_next = arp_request_timer_reg; + arp_response_error_next = 0; + arp_response_broadcast_next = 0; + + drop_incoming_frame_next = 0; + + // manage incoming frames + if (filtered_incoming_frame_valid & ~(outgoing_frame_valid_reg & ~outgoing_frame_ready)) begin + // store sender addresses in cache + cache_write_request_valid_next = 1; + cache_write_request_ip_next = incoming_arp_spa; + cache_write_request_mac_next = incoming_arp_sha; + if (incoming_arp_oper_arp_request) begin + if (incoming_arp_tpa == local_ip) begin + // send reply frame to valid incoming request + outgoing_frame_valid_next = 1; + outgoing_eth_dest_mac_next = incoming_eth_src_mac; + outgoing_arp_oper_next = ARP_OPER_ARP_REPLY; + outgoing_arp_tha_next = incoming_arp_sha; + outgoing_arp_tpa_next = incoming_arp_spa; + end else begin + // does not match -> drop it + drop_incoming_frame_next = 1; + end + end else if (incoming_arp_oper_inarp_request) begin + if (incoming_arp_tha == local_mac) begin + // send reply frame to valid incoming request + outgoing_frame_valid_next = 1; + outgoing_eth_dest_mac_next = incoming_eth_src_mac; + outgoing_arp_oper_next = ARP_OPER_INARP_REPLY; + outgoing_arp_tha_next = incoming_arp_sha; + outgoing_arp_tpa_next = incoming_arp_spa; + end else begin + // does not match -> drop it + drop_incoming_frame_next = 1; + end + end else begin + // does not match -> drop it + drop_incoming_frame_next = 1; + end + end else if (incoming_frame_valid & ~filtered_incoming_frame_valid) begin + // incoming invalid frame -> drop it + drop_incoming_frame_next = 1; + end + + // manage ARP lookup requests + if (~arp_request_operation_reg) begin + if (arp_request_valid) begin + if (~(arp_request_ip | subnet_mask) == 0) begin + // broadcast address + // (all bits in request IP set where subnet mask is clear) + arp_request_valid_next = 0; + arp_response_broadcast_next = 1; + end else if (((arp_request_ip ^ gateway_ip) & subnet_mask) == 0) begin + // within subnet, look up IP directly + // (no bits differ between request IP and gateway IP where subnet mask is set) + arp_request_valid_next = 1; + arp_request_ip_next = arp_request_ip; + end else begin + // outside of subnet, so look up gateway address + arp_request_valid_next = 1; + arp_request_ip_next = gateway_ip; + end + end + if (cache_query_response_error & ~arp_response_error) begin + arp_request_operation_next = 1; + // send ARP request frame + outgoing_frame_valid_next = 1; + outgoing_eth_dest_mac_next = 48'hFF_FF_FF_FF_FF_FF; + outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; + outgoing_arp_tha_next = 48'h00_00_00_00_00_00; + outgoing_arp_tpa_next = arp_request_ip_reg; + arp_request_retry_cnt_next = REQUEST_RETRY_COUNT-1; + arp_request_timer_next = REQUEST_RETRY_INTERVAL; + end + end else begin + arp_request_timer_next = arp_request_timer_reg - 1; + // if we got a response, it will go in the cache, so when the query succeds, we're done + if (cache_query_response_valid & ~cache_query_response_error) begin + arp_request_operation_next = 0; + end + // timer timeout + if (arp_request_timer_reg == 0) begin + if (arp_request_retry_cnt_reg > 0) begin + // have more retries + // send ARP request frame + outgoing_frame_valid_next = 1'b1; + outgoing_eth_dest_mac_next = 48'hFF_FF_FF_FF_FF_FF; + outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; + outgoing_arp_tha_next = 48'h00_00_00_00_00_00; + outgoing_arp_tpa_next = arp_request_ip_reg; + arp_request_retry_cnt_next = arp_request_retry_cnt_reg - 1; + if (arp_request_retry_cnt_reg > 1) begin + arp_request_timer_next = REQUEST_RETRY_INTERVAL; + end else begin + arp_request_timer_next = REQUEST_TIMEOUT; + end + end else begin + // out of retries + arp_request_operation_next = 0; + arp_response_error_next = 1; + end + end + end +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + outgoing_frame_valid_reg <= 0; + outgoing_eth_dest_mac_reg <= 0; + outgoing_arp_oper_reg <= 0; + outgoing_arp_tha_reg <= 0; + outgoing_arp_tpa_reg <= 0; + cache_write_request_valid_reg <= 0; + cache_write_request_mac_reg <= 0; + cache_write_request_ip_reg <= 0; + arp_request_valid_reg <= 0; + arp_request_ip_reg <= 0; + arp_request_operation_reg <= 0; + arp_request_retry_cnt_reg <= 0; + arp_request_timer_reg <= 0; + arp_response_error_reg <= 0; + arp_response_broadcast_reg <= 0; + drop_incoming_frame_reg <= 0; + end else begin + outgoing_frame_valid_reg <= outgoing_frame_valid_next; + outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; + outgoing_arp_oper_reg <= outgoing_arp_oper_next; + outgoing_arp_tha_reg <= outgoing_arp_tha_next; + outgoing_arp_tpa_reg <= outgoing_arp_tpa_next; + cache_write_request_valid_reg <= cache_write_request_valid_next; + cache_write_request_mac_reg <= cache_write_request_mac_next; + cache_write_request_ip_reg <= cache_write_request_ip_next; + arp_request_valid_reg <= arp_request_valid_next; + arp_request_ip_reg <= arp_request_ip_next; + arp_request_operation_reg <= arp_request_operation_next; + arp_request_retry_cnt_reg <= arp_request_retry_cnt_next; + arp_request_timer_reg <= arp_request_timer_next; + arp_response_error_reg <= arp_response_error_next; + arp_response_broadcast_reg <= arp_response_broadcast_next; + drop_incoming_frame_reg <= drop_incoming_frame_next; + end +end + +endmodule diff --git a/tb/test_arp.py b/tb/test_arp.py new file mode 100755 index 000000000..4a9e2f2d9 --- /dev/null +++ b/tb/test_arp.py @@ -0,0 +1,516 @@ +#!/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 eth_ep +import arp_ep + +module = 'arp' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/arp_cache.v") +srcs.append("../rtl/arp_eth_rx.v") +srcs.append("../rtl/arp_eth_tx.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_arp(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + arp_request_valid, + arp_request_ip, + arp_response_valid, + arp_response_error, + arp_response_mac, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_cache): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + arp_request_valid=arp_request_valid, + arp_request_ip=arp_request_ip, + arp_response_valid=arp_response_valid, + arp_response_error=arp_response_error, + arp_response_mac=arp_response_mac, + + local_mac=local_mac, + local_ip=local_ip, + gateway_ip=gateway_ip, + subnet_mask=subnet_mask, + clear_cache=clear_cache) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + arp_request_valid = Signal(bool(0)) + arp_request_ip = Signal(intbv(0)[32:]) + + local_mac = Signal(intbv(0)[48:]) + local_ip = Signal(intbv(0)[32:]) + gateway_ip = Signal(intbv(0)[32:]) + subnet_mask = Signal(intbv(0)[32:]) + clear_cache = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + + arp_response_valid = Signal(bool(0)) + arp_response_error = Signal(bool(0)) + arp_response_mac = Signal(intbv(0)[48:]) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_arp(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + arp_request_valid, + arp_request_ip, + arp_response_valid, + arp_response_error, + arp_response_mac, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_cache) + + @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 + local_mac.next = 0xDAD1D2D3D4D5 + local_ip.next = 0xc0a80165 + gateway_ip.next = 0xc0a80101 + subnet_mask.next = 0xFFFFFF00 + + yield clk.posedge + print("test 1: ARP request") + current_test.next = 1 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0x000000000000 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0x5A5152535455 + assert check_frame.eth_src_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 2 + assert check_frame.arp_sha == 0xDAD1D2D3D4D5 + assert check_frame.arp_spa == 0xc0a80165 + assert check_frame.arp_tha == 0x5A5152535455 + assert check_frame.arp_tpa == 0xc0a80164 + + yield delay(100) + + yield clk.posedge + print("test 2: Cached read") + current_test.next = 2 + + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0xc0a80164 + yield clk.posedge + arp_request_valid.next = False + + yield arp_response_valid.posedge + assert not bool(arp_response_error) + assert int(arp_response_mac) == 0x5A5152535455 + + yield delay(100) + + yield clk.posedge + print("test 3: Unached read") + current_test.next = 3 + + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0xc0a80166 + yield clk.posedge + arp_request_valid.next = False + + # wait for ARP request packet + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0xDAD1D2D3D4D5 + assert check_frame.arp_spa == 0xc0a80165 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80166 + + # generate response + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x6A6162636465 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 2 + test_frame.arp_sha = 0x6A6162636465 + test_frame.arp_spa = 0xc0a80166 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + # wait for lookup + yield arp_response_valid.posedge + assert not bool(arp_response_error) + assert int(arp_response_mac) == 0x6A6162636465 + + yield delay(100) + + yield clk.posedge + print("test 4: Unached read, outside of subnet") + current_test.next = 4 + + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0x08080808 + yield clk.posedge + arp_request_valid.next = False + + # wait for ARP request packet + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0xDAD1D2D3D4D5 + assert check_frame.arp_spa == 0xc0a80165 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80101 + + # generate response + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0xAABBCCDDEEFF + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 2 + test_frame.arp_sha = 0xAABBCCDDEEFF + test_frame.arp_spa = 0xc0a80101 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + # wait for lookup + yield arp_response_valid.posedge + assert not bool(arp_response_error) + assert int(arp_response_mac) == 0xAABBCCDDEEFF + + yield delay(100) + + yield clk.posedge + print("test 5: Unached read, timeout") + current_test.next = 5 + + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0xc0a80167 + yield clk.posedge + arp_request_valid.next = False + + yield arp_response_valid.posedge + assert bool(arp_response_error) + + # check for 4 ARP requests + assert sink_queue.qsize() == 4 + + while not sink_queue.empty(): + rx_frame = sink_queue.get(False) + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0xDAD1D2D3D4D5 + assert check_frame.arp_spa == 0xc0a80165 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80167 + + yield delay(100) + + yield clk.posedge + print("test 6: Broadcast") + current_test.next = 6 + + # subnet broadcast + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0xc0a801FF + yield clk.posedge + arp_request_valid.next = False + + yield arp_response_valid.posedge + assert not bool(arp_response_error) + assert int(arp_response_mac) == 0xFFFFFFFFFFFF + + # general broadcast + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0xFFFFFFFF + yield clk.posedge + arp_request_valid.next = False + + yield arp_response_valid.posedge + assert not bool(arp_response_error) + assert int(arp_response_mac) == 0xFFFFFFFFFFFF + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_arp.v b/tb/test_arp.v new file mode 100644 index 000000000..2e64a6b41 --- /dev/null +++ b/tb/test_arp.v @@ -0,0 +1,160 @@ +/* + +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_arp; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [7:0] input_eth_payload_tdata = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; + +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +reg arp_request_valid = 0; +reg [31:0] arp_request_ip = 0; + +reg [47:0] local_mac = 0; +reg [31:0] local_ip = 0; +reg [31:0] gateway_ip = 0; +reg [31:0] subnet_mask = 0; +reg clear_cache = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; + +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [7:0] output_eth_payload_tdata; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; + +wire arp_response_valid; +wire arp_response_error; +wire [47:0] arp_response_mac; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + arp_request_valid, + arp_request_ip, + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_cache); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + arp_response_valid, + arp_response_error, + arp_response_mac); + + // dump file + $dumpfile("test_arp.lxt"); + $dumpvars(0, test_arp); +end + +arp #( + .CACHE_ADDR_WIDTH(2), + .REQUEST_RETRY_COUNT(4), + .REQUEST_RETRY_INTERVAL(150), + .REQUEST_TIMEOUT(400) +) +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // ARP requests + .arp_request_valid(arp_request_valid), + .arp_request_ip(arp_request_ip), + .arp_response_valid(arp_response_valid), + .arp_response_error(arp_response_error), + .arp_response_mac(arp_response_mac), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_cache(clear_cache) +); + +endmodule diff --git a/tb/test_arp_64.py b/tb/test_arp_64.py new file mode 100755 index 000000000..8e93c2993 --- /dev/null +++ b/tb/test_arp_64.py @@ -0,0 +1,526 @@ +#!/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 eth_ep +import arp_ep + +module = 'arp_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/arp_cache.v") +srcs.append("../rtl/arp_eth_rx_64.v") +srcs.append("../rtl/arp_eth_tx_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_arp_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + arp_request_valid, + arp_request_ip, + arp_response_valid, + arp_response_error, + arp_response_mac, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_cache): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + arp_request_valid=arp_request_valid, + arp_request_ip=arp_request_ip, + arp_response_valid=arp_response_valid, + arp_response_error=arp_response_error, + arp_response_mac=arp_response_mac, + + local_mac=local_mac, + local_ip=local_ip, + gateway_ip=gateway_ip, + subnet_mask=subnet_mask, + clear_cache=clear_cache) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[64:]) + input_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + + arp_request_valid = Signal(bool(0)) + arp_request_ip = Signal(intbv(0)[32:]) + + local_mac = Signal(intbv(0)[48:]) + local_ip = Signal(intbv(0)[32:]) + gateway_ip = Signal(intbv(0)[32:]) + subnet_mask = Signal(intbv(0)[32:]) + clear_cache = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[64:]) + output_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + + arp_response_valid = Signal(bool(0)) + arp_response_error = Signal(bool(0)) + arp_response_mac = Signal(intbv(0)[48:]) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + + source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=source_queue, + pause=source_pause, + name='source') + + sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=sink_queue, + pause=sink_pause, + name='sink') + + # DUT + dut = dut_arp_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + arp_request_valid, + arp_request_ip, + arp_response_valid, + arp_response_error, + arp_response_mac, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_cache) + + @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 + local_mac.next = 0xDAD1D2D3D4D5 + local_ip.next = 0xc0a80165 + gateway_ip.next = 0xc0a80101 + subnet_mask.next = 0xFFFFFF00 + + yield clk.posedge + print("test 1: ARP request") + current_test.next = 1 + + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xFFFFFFFFFFFF + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 1 + test_frame.arp_sha = 0x5A5152535455 + test_frame.arp_spa = 0xc0a80164 + test_frame.arp_tha = 0x000000000000 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0x5A5152535455 + assert check_frame.eth_src_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 2 + assert check_frame.arp_sha == 0xDAD1D2D3D4D5 + assert check_frame.arp_spa == 0xc0a80165 + assert check_frame.arp_tha == 0x5A5152535455 + assert check_frame.arp_tpa == 0xc0a80164 + + yield delay(100) + + yield clk.posedge + print("test 2: Cached read") + current_test.next = 2 + + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0xc0a80164 + yield clk.posedge + arp_request_valid.next = False + + yield arp_response_valid.posedge + assert not bool(arp_response_error) + assert int(arp_response_mac) == 0x5A5152535455 + + yield delay(100) + + yield clk.posedge + print("test 3: Unached read") + current_test.next = 3 + + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0xc0a80166 + yield clk.posedge + arp_request_valid.next = False + + # wait for ARP request packet + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0xDAD1D2D3D4D5 + assert check_frame.arp_spa == 0xc0a80165 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80166 + + # generate response + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x6A6162636465 + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 2 + test_frame.arp_sha = 0x6A6162636465 + test_frame.arp_spa = 0xc0a80166 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + # wait for lookup + yield arp_response_valid.posedge + assert not bool(arp_response_error) + assert int(arp_response_mac) == 0x6A6162636465 + + yield delay(100) + + yield clk.posedge + print("test 4: Unached read, outside of subnet") + current_test.next = 4 + + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0x08080808 + yield clk.posedge + arp_request_valid.next = False + + # wait for ARP request packet + yield output_eth_payload_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0xDAD1D2D3D4D5 + assert check_frame.arp_spa == 0xc0a80165 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80101 + + # generate response + test_frame = arp_ep.ARPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0xAABBCCDDEEFF + test_frame.eth_type = 0x0806 + test_frame.arp_htype = 0x0001 + test_frame.arp_ptype = 0x0800 + test_frame.arp_hlen = 6 + test_frame.arp_plen = 4 + test_frame.arp_oper = 2 + test_frame.arp_sha = 0xAABBCCDDEEFF + test_frame.arp_spa = 0xc0a80101 + test_frame.arp_tha = 0xDAD1D2D3D4D5 + test_frame.arp_tpa = 0xc0a80165 + source_queue.put(test_frame.build_eth()) + yield clk.posedge + + # wait for lookup + yield arp_response_valid.posedge + assert not bool(arp_response_error) + assert int(arp_response_mac) == 0xAABBCCDDEEFF + + yield delay(100) + + yield clk.posedge + print("test 5: Unached read, timeout") + current_test.next = 5 + + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0xc0a80167 + yield clk.posedge + arp_request_valid.next = False + + yield arp_response_valid.posedge + assert bool(arp_response_error) + + # check for 4 ARP requests + assert sink_queue.qsize() == 4 + + while not sink_queue.empty(): + rx_frame = sink_queue.get(False) + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0xDAD1D2D3D4D5 + assert check_frame.arp_spa == 0xc0a80165 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80167 + + yield delay(100) + + yield clk.posedge + print("test 6: Broadcast") + current_test.next = 6 + + # subnet broadcast + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0xc0a801FF + yield clk.posedge + arp_request_valid.next = False + + yield arp_response_valid.posedge + assert not bool(arp_response_error) + assert int(arp_response_mac) == 0xFFFFFFFFFFFF + + # general broadcast + yield clk.posedge + arp_request_valid.next = True + arp_request_ip.next = 0xFFFFFFFF + yield clk.posedge + arp_request_valid.next = False + + yield arp_response_valid.posedge + assert not bool(arp_response_error) + assert int(arp_response_mac) == 0xFFFFFFFFFFFF + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_arp_64.v b/tb/test_arp_64.v new file mode 100644 index 000000000..dd4113205 --- /dev/null +++ b/tb/test_arp_64.v @@ -0,0 +1,166 @@ +/* + +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_arp_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [63:0] input_eth_payload_tdata = 0; +reg [7:0] input_eth_payload_tkeep = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; + +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; + +reg arp_request_valid = 0; +reg [31:0] arp_request_ip = 0; + +reg [47:0] local_mac = 0; +reg [31:0] local_ip = 0; +reg [31:0] gateway_ip = 0; +reg [31:0] subnet_mask = 0; +reg clear_cache = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; + +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [63:0] output_eth_payload_tdata; +wire [7:0] output_eth_payload_tkeep; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; + +wire arp_response_valid; +wire arp_response_error; +wire [47:0] arp_response_mac; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + arp_request_valid, + arp_request_ip, + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_cache); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + arp_response_valid, + arp_response_error, + arp_response_mac); + + // dump file + $dumpfile("test_arp_64.lxt"); + $dumpvars(0, test_arp_64); +end + +arp_64 #( + .CACHE_ADDR_WIDTH(2), + .REQUEST_RETRY_COUNT(4), + .REQUEST_RETRY_INTERVAL(150), + .REQUEST_TIMEOUT(400) +) +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // ARP requests + .arp_request_valid(arp_request_valid), + .arp_request_ip(arp_request_ip), + .arp_response_valid(arp_response_valid), + .arp_response_error(arp_response_error), + .arp_response_mac(arp_response_mac), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_cache(clear_cache) +); + +endmodule From a8bb020839c071bc16c4efb581cab18b1dcc0e72 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 20 Nov 2014 23:51:24 -0800 Subject: [PATCH 121/617] Reorder includes --- tb/test_ip.py | 2 +- tb/test_ip_64.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tb/test_ip.py b/tb/test_ip.py index 40f30d9e2..ff0f131a7 100755 --- a/tb/test_ip.py +++ b/tb/test_ip.py @@ -35,9 +35,9 @@ module = 'ip' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) srcs.append("../rtl/ip_eth_rx.v") srcs.append("../rtl/ip_eth_tx.v") +srcs.append("test_%s.v" % module) src = ' '.join(srcs) diff --git a/tb/test_ip_64.py b/tb/test_ip_64.py index 788184f18..e05227351 100755 --- a/tb/test_ip_64.py +++ b/tb/test_ip_64.py @@ -35,9 +35,9 @@ module = 'ip_64' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) srcs.append("../rtl/ip_eth_rx_64.v") srcs.append("../rtl/ip_eth_tx_64.v") +srcs.append("test_%s.v" % module) src = ' '.join(srcs) From d483ebb8da6392ca33a011047de35daf1dfeffcf Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 20 Nov 2014 23:59:54 -0800 Subject: [PATCH 122/617] Drop arp request earlier --- rtl/ip.v | 2 +- rtl/ip_64.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/ip.v b/rtl/ip.v index 3d888d5b5..67328486d 100644 --- a/rtl/ip.v +++ b/rtl/ip.v @@ -247,7 +247,7 @@ reg drop_packet_reg = 0, drop_packet_next; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; -assign arp_request_valid = arp_request_valid_reg | input_ip_hdr_valid; +assign arp_request_valid = arp_request_valid_reg | (input_ip_hdr_valid & ~input_ip_hdr_ready_reg); assign arp_request_ip = input_ip_dest_ip; assign tx_error_arp_failed = arp_response_error; diff --git a/rtl/ip_64.v b/rtl/ip_64.v index 9eae37d9a..b7ed26b80 100644 --- a/rtl/ip_64.v +++ b/rtl/ip_64.v @@ -256,7 +256,7 @@ reg drop_packet_reg = 0, drop_packet_next; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; -assign arp_request_valid = arp_request_valid_reg | input_ip_hdr_valid; +assign arp_request_valid = arp_request_valid_reg | (input_ip_hdr_valid & ~input_ip_hdr_ready_reg); assign arp_request_ip = input_ip_dest_ip; assign tx_error_arp_failed = arp_response_error; From 96b6e7ca9603e6ba8b8f9ad22747bec0431763fd Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 21 Nov 2014 00:00:27 -0800 Subject: [PATCH 123/617] Ignore transient requests --- rtl/arp.v | 4 ++-- rtl/arp_64.v | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtl/arp.v b/rtl/arp.v index 000fa85ec..a88928a9d 100644 --- a/rtl/arp.v +++ b/rtl/arp.v @@ -326,7 +326,7 @@ always @* begin end // manage ARP lookup requests - if (~arp_request_operation_reg) begin + if (~arp_request_operation_reg & ~arp_response_valid) begin if (arp_request_valid) begin if (~(arp_request_ip | subnet_mask) == 0) begin // broadcast address @@ -355,7 +355,7 @@ always @* begin arp_request_retry_cnt_next = REQUEST_RETRY_COUNT-1; arp_request_timer_next = REQUEST_RETRY_INTERVAL; end - end else begin + end else if (arp_request_operation_reg) begin arp_request_timer_next = arp_request_timer_reg - 1; // if we got a response, it will go in the cache, so when the query succeds, we're done if (cache_query_response_valid & ~cache_query_response_error) begin diff --git a/rtl/arp_64.v b/rtl/arp_64.v index 490e3c101..8e9f84151 100644 --- a/rtl/arp_64.v +++ b/rtl/arp_64.v @@ -330,7 +330,7 @@ always @* begin end // manage ARP lookup requests - if (~arp_request_operation_reg) begin + if (~arp_request_operation_reg & ~arp_response_valid) begin if (arp_request_valid) begin if (~(arp_request_ip | subnet_mask) == 0) begin // broadcast address @@ -359,7 +359,7 @@ always @* begin arp_request_retry_cnt_next = REQUEST_RETRY_COUNT-1; arp_request_timer_next = REQUEST_RETRY_INTERVAL; end - end else begin + end else if (arp_request_operation_reg) begin arp_request_timer_next = arp_request_timer_reg - 1; // if we got a response, it will go in the cache, so when the query succeds, we're done if (cache_query_response_valid & ~cache_query_response_error) begin From 9bf6f01649fa8c7bcd063ab76029b58b04c1aa0a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 21 Nov 2014 00:02:20 -0800 Subject: [PATCH 124/617] Add 2 port Ethernet mux components --- rtl/eth_arb_mux_2.v | 150 +++++++++++++++++++ rtl/eth_arb_mux_64_2.v | 156 ++++++++++++++++++++ rtl/eth_mux_2.v | 301 ++++++++++++++++++++++++++++++++++++++ rtl/eth_mux_64_2.v | 318 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 925 insertions(+) create mode 100644 rtl/eth_arb_mux_2.v create mode 100644 rtl/eth_arb_mux_64_2.v create mode 100644 rtl/eth_mux_2.v create mode 100644 rtl/eth_mux_64_2.v diff --git a/rtl/eth_arb_mux_2.v b/rtl/eth_arb_mux_2.v new file mode 100644 index 000000000..80137efde --- /dev/null +++ b/rtl/eth_arb_mux_2.v @@ -0,0 +1,150 @@ +/* + +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 + +/* + * Ethernet 2 port arbitrated multiplexer + */ +module eth_arb_mux_2 # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ + input wire input_0_eth_hdr_valid, + output wire input_0_eth_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [7:0] input_0_eth_payload_tdata, + input wire input_0_eth_payload_tvalid, + output wire input_0_eth_payload_tready, + input wire input_0_eth_payload_tlast, + input wire input_0_eth_payload_tuser, + + input wire input_1_eth_hdr_valid, + output wire input_1_eth_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [7:0] input_1_eth_payload_tdata, + input wire input_1_eth_payload_tvalid, + output wire input_1_eth_payload_tready, + input wire input_1_eth_payload_tlast, + input wire input_1_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser +); + +wire [1:0] request; +wire [1:0] acknowledge; +wire [1:0] grant; +wire grant_valid; +wire [0:0] grant_encoded; + +assign acknowledge[0] = input_0_eth_payload_tvalid & input_0_eth_payload_tready & input_0_eth_payload_tlast; +assign request[0] = input_0_eth_hdr_valid; +assign acknowledge[1] = input_1_eth_payload_tvalid & input_1_eth_payload_tready & input_1_eth_payload_tlast; +assign request[1] = input_1_eth_hdr_valid; + +// mux instance +eth_mux_2 +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_eth_hdr_valid(input_0_eth_hdr_valid & grant[0]), + .input_0_eth_hdr_ready(input_0_eth_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_eth_payload_tdata(input_0_eth_payload_tdata), + .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid & grant[0]), + .input_0_eth_payload_tready(input_0_eth_payload_tready), + .input_0_eth_payload_tlast(input_0_eth_payload_tlast), + .input_0_eth_payload_tuser(input_0_eth_payload_tuser), + .input_1_eth_hdr_valid(input_1_eth_hdr_valid & grant[1]), + .input_1_eth_hdr_ready(input_1_eth_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_eth_payload_tdata(input_1_eth_payload_tdata), + .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid & grant[1]), + .input_1_eth_payload_tready(input_1_eth_payload_tready), + .input_1_eth_payload_tlast(input_1_eth_payload_tlast), + .input_1_eth_payload_tuser(input_1_eth_payload_tuser), + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(2), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/rtl/eth_arb_mux_64_2.v b/rtl/eth_arb_mux_64_2.v new file mode 100644 index 000000000..bcdb04c58 --- /dev/null +++ b/rtl/eth_arb_mux_64_2.v @@ -0,0 +1,156 @@ +/* + +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 + +/* + * Ethernet 2 port arbitrated multiplexer (64 bit datapath) + */ +module eth_arb_mux_64_2 # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ + input wire input_0_eth_hdr_valid, + output wire input_0_eth_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [63:0] input_0_eth_payload_tdata, + input wire [7:0] input_0_eth_payload_tkeep, + input wire input_0_eth_payload_tvalid, + output wire input_0_eth_payload_tready, + input wire input_0_eth_payload_tlast, + input wire input_0_eth_payload_tuser, + + input wire input_1_eth_hdr_valid, + output wire input_1_eth_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [63:0] input_1_eth_payload_tdata, + input wire [7:0] input_1_eth_payload_tkeep, + input wire input_1_eth_payload_tvalid, + output wire input_1_eth_payload_tready, + input wire input_1_eth_payload_tlast, + input wire input_1_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser +); + +wire [1:0] request; +wire [1:0] acknowledge; +wire [1:0] grant; +wire grant_valid; +wire [0:0] grant_encoded; + +assign acknowledge[0] = input_0_eth_payload_tvalid & input_0_eth_payload_tready & input_0_eth_payload_tlast; +assign request[0] = input_0_eth_hdr_valid; +assign acknowledge[1] = input_1_eth_payload_tvalid & input_1_eth_payload_tready & input_1_eth_payload_tlast; +assign request[1] = input_1_eth_hdr_valid; + +// mux instance +eth_mux_64_2 +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_eth_hdr_valid(input_0_eth_hdr_valid & grant[0]), + .input_0_eth_hdr_ready(input_0_eth_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_eth_payload_tdata(input_0_eth_payload_tdata), + .input_0_eth_payload_tkeep(input_0_eth_payload_tkeep), + .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid & grant[0]), + .input_0_eth_payload_tready(input_0_eth_payload_tready), + .input_0_eth_payload_tlast(input_0_eth_payload_tlast), + .input_0_eth_payload_tuser(input_0_eth_payload_tuser), + .input_1_eth_hdr_valid(input_1_eth_hdr_valid & grant[1]), + .input_1_eth_hdr_ready(input_1_eth_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_eth_payload_tdata(input_1_eth_payload_tdata), + .input_1_eth_payload_tkeep(input_1_eth_payload_tkeep), + .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid & grant[1]), + .input_1_eth_payload_tready(input_1_eth_payload_tready), + .input_1_eth_payload_tlast(input_1_eth_payload_tlast), + .input_1_eth_payload_tuser(input_1_eth_payload_tuser), + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(2), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/rtl/eth_mux_2.v b/rtl/eth_mux_2.v new file mode 100644 index 000000000..540589064 --- /dev/null +++ b/rtl/eth_mux_2.v @@ -0,0 +1,301 @@ +/* + +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 + +/* + * Ethernet 2 port multiplexer + */ +module eth_mux_2 +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ + input wire input_0_eth_hdr_valid, + output wire input_0_eth_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [7:0] input_0_eth_payload_tdata, + input wire input_0_eth_payload_tvalid, + output wire input_0_eth_payload_tready, + input wire input_0_eth_payload_tlast, + input wire input_0_eth_payload_tuser, + + input wire input_1_eth_hdr_valid, + output wire input_1_eth_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [7:0] input_1_eth_payload_tdata, + input wire input_1_eth_payload_tvalid, + output wire input_1_eth_payload_tready, + input wire input_1_eth_payload_tlast, + input wire input_1_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [0:0] select +); + +reg [0:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_eth_hdr_ready_reg = 0, input_0_eth_hdr_ready_next; +reg input_1_eth_hdr_ready_reg = 0, input_1_eth_hdr_ready_next; + +reg input_0_eth_payload_tready_reg = 0, input_0_eth_payload_tready_next; +reg input_1_eth_payload_tready_reg = 0, input_1_eth_payload_tready_next; + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; + +// internal datapath +reg [7:0] output_eth_payload_tdata_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + +assign input_0_eth_hdr_ready = input_0_eth_hdr_ready_reg; +assign input_1_eth_hdr_ready = input_1_eth_hdr_ready_reg; + +assign input_0_eth_payload_tready = input_0_eth_payload_tready_reg; +assign input_1_eth_payload_tready = input_1_eth_payload_tready_reg; + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; + +// mux for start of packet detection +reg selected_input_eth_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +always @* begin + case (select) + 1'd0: begin + selected_input_eth_hdr_valid = input_0_eth_hdr_valid; + selected_input_eth_dest_mac = input_0_eth_dest_mac; + selected_input_eth_src_mac = input_0_eth_src_mac; + selected_input_eth_type = input_0_eth_type; + end + 1'd1: begin + selected_input_eth_hdr_valid = input_1_eth_hdr_valid; + selected_input_eth_dest_mac = input_1_eth_dest_mac; + selected_input_eth_src_mac = input_1_eth_src_mac; + selected_input_eth_type = input_1_eth_type; + end + endcase +end + +// mux for incoming packet +reg [7:0] current_input_tdata; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 1'd0: begin + current_input_tdata = input_0_eth_payload_tdata; + current_input_tvalid = input_0_eth_payload_tvalid; + current_input_tready = input_0_eth_payload_tready; + current_input_tlast = input_0_eth_payload_tlast; + current_input_tuser = input_0_eth_payload_tuser; + end + 1'd1: begin + current_input_tdata = input_1_eth_payload_tdata; + current_input_tvalid = input_1_eth_payload_tvalid; + current_input_tready = input_1_eth_payload_tready; + current_input_tlast = input_1_eth_payload_tlast; + current_input_tuser = input_1_eth_payload_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_reg & ~input_0_eth_hdr_valid; + input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_reg & ~input_1_eth_hdr_valid; + + input_0_eth_payload_tready_next = 0; + input_1_eth_payload_tready_next = 0; + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) + 1'd0: input_0_eth_hdr_ready_next = 1; + 1'd1: input_1_eth_hdr_ready_next = 1; + endcase + + output_eth_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + end + + // generate ready signal on selected port + case (select_next) + 1'd0: input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + 1'd1: input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + endcase + + // pass through selected packet data + output_eth_payload_tdata_int = current_input_tdata; + output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_eth_payload_tlast_int = current_input_tlast; + output_eth_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_eth_hdr_ready_reg <= 0; + input_1_eth_hdr_ready_reg <= 0; + input_0_eth_payload_tready_reg <= 0; + input_1_eth_payload_tready_reg <= 0; + output_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_eth_hdr_ready_reg <= input_0_eth_hdr_ready_next; + input_1_eth_hdr_ready_reg <= input_1_eth_hdr_ready_next; + input_0_eth_payload_tready_reg <= input_0_eth_payload_tready_next; + input_1_eth_payload_tready_reg <= input_1_eth_payload_tready_next; + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + end +end + +// output datapath logic +reg [7:0] output_eth_payload_tdata_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [7:0] temp_eth_payload_tdata_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/eth_mux_64_2.v b/rtl/eth_mux_64_2.v new file mode 100644 index 000000000..61ff2215e --- /dev/null +++ b/rtl/eth_mux_64_2.v @@ -0,0 +1,318 @@ +/* + +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 + +/* + * Ethernet 2 port multiplexer (64 bit datapath) + */ +module eth_mux_64_2 +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ + input wire input_0_eth_hdr_valid, + output wire input_0_eth_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [63:0] input_0_eth_payload_tdata, + input wire [7:0] input_0_eth_payload_tkeep, + input wire input_0_eth_payload_tvalid, + output wire input_0_eth_payload_tready, + input wire input_0_eth_payload_tlast, + input wire input_0_eth_payload_tuser, + + input wire input_1_eth_hdr_valid, + output wire input_1_eth_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [63:0] input_1_eth_payload_tdata, + input wire [7:0] input_1_eth_payload_tkeep, + input wire input_1_eth_payload_tvalid, + output wire input_1_eth_payload_tready, + input wire input_1_eth_payload_tlast, + input wire input_1_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [0:0] select +); + +reg [0:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_eth_hdr_ready_reg = 0, input_0_eth_hdr_ready_next; +reg input_1_eth_hdr_ready_reg = 0, input_1_eth_hdr_ready_next; + +reg input_0_eth_payload_tready_reg = 0, input_0_eth_payload_tready_next; +reg input_1_eth_payload_tready_reg = 0, input_1_eth_payload_tready_next; + +reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; + +// internal datapath +reg [63:0] output_eth_payload_tdata_int; +reg [7:0] output_eth_payload_tkeep_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; + +assign input_0_eth_hdr_ready = input_0_eth_hdr_ready_reg; +assign input_1_eth_hdr_ready = input_1_eth_hdr_ready_reg; + +assign input_0_eth_payload_tready = input_0_eth_payload_tready_reg; +assign input_1_eth_payload_tready = input_1_eth_payload_tready_reg; + +assign output_eth_hdr_valid = output_eth_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; + +// mux for start of packet detection +reg selected_input_eth_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +always @* begin + case (select) + 1'd0: begin + selected_input_eth_hdr_valid = input_0_eth_hdr_valid; + selected_input_eth_dest_mac = input_0_eth_dest_mac; + selected_input_eth_src_mac = input_0_eth_src_mac; + selected_input_eth_type = input_0_eth_type; + end + 1'd1: begin + selected_input_eth_hdr_valid = input_1_eth_hdr_valid; + selected_input_eth_dest_mac = input_1_eth_dest_mac; + selected_input_eth_src_mac = input_1_eth_src_mac; + selected_input_eth_type = input_1_eth_type; + end + endcase +end + +// mux for incoming packet +reg [63:0] current_input_tdata; +reg [7:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 1'd0: begin + current_input_tdata = input_0_eth_payload_tdata; + current_input_tkeep = input_0_eth_payload_tkeep; + current_input_tvalid = input_0_eth_payload_tvalid; + current_input_tready = input_0_eth_payload_tready; + current_input_tlast = input_0_eth_payload_tlast; + current_input_tuser = input_0_eth_payload_tuser; + end + 1'd1: begin + current_input_tdata = input_1_eth_payload_tdata; + current_input_tkeep = input_1_eth_payload_tkeep; + current_input_tvalid = input_1_eth_payload_tvalid; + current_input_tready = input_1_eth_payload_tready; + current_input_tlast = input_1_eth_payload_tlast; + current_input_tuser = input_1_eth_payload_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_reg & ~input_0_eth_hdr_valid; + input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_reg & ~input_1_eth_hdr_valid; + + input_0_eth_payload_tready_next = 0; + input_1_eth_payload_tready_next = 0; + + output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) + 1'd0: input_0_eth_hdr_ready_next = 1; + 1'd1: input_1_eth_hdr_ready_next = 1; + endcase + + output_eth_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + end + + // generate ready signal on selected port + case (select_next) + 1'd0: input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + 1'd1: input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; + endcase + + // pass through selected packet data + output_eth_payload_tdata_int = current_input_tdata; + output_eth_payload_tkeep_int = current_input_tkeep; + output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_eth_payload_tlast_int = current_input_tlast; + output_eth_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_eth_hdr_ready_reg <= 0; + input_1_eth_hdr_ready_reg <= 0; + input_0_eth_payload_tready_reg <= 0; + input_1_eth_payload_tready_reg <= 0; + output_eth_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_eth_hdr_ready_reg <= input_0_eth_hdr_ready_next; + input_1_eth_hdr_ready_reg <= input_1_eth_hdr_ready_next; + input_0_eth_payload_tready_reg <= input_0_eth_payload_tready_next; + input_1_eth_payload_tready_reg <= input_1_eth_payload_tready_next; + output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + end +end + +// output datapath logic +reg [63:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tkeep_reg = 0; +reg output_eth_payload_tvalid_reg = 0; +reg output_eth_payload_tlast_reg = 0; +reg output_eth_payload_tuser_reg = 0; + +reg [63:0] temp_eth_payload_tdata_reg = 0; +reg [7:0] temp_eth_payload_tkeep_reg = 0; +reg temp_eth_payload_tvalid_reg = 0; +reg temp_eth_payload_tlast_reg = 0; +reg temp_eth_payload_tuser_reg = 0; + +assign output_eth_payload_tdata = output_eth_payload_tdata_reg; +assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; +assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; +assign output_eth_payload_tlast = output_eth_payload_tlast_reg; +assign output_eth_payload_tuser = output_eth_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_eth_payload_tdata_reg <= 0; + output_eth_payload_tkeep_reg <= 0; + output_eth_payload_tvalid_reg <= 0; + output_eth_payload_tlast_reg <= 0; + output_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int <= 0; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + + if (output_eth_payload_tready_int) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + temp_eth_payload_tdata_reg <= 0; + temp_eth_payload_tkeep_reg <= 0; + temp_eth_payload_tvalid_reg <= 0; + temp_eth_payload_tlast_reg <= 0; + temp_eth_payload_tuser_reg <= 0; + end + end +end + +endmodule From 4a228f06c57d8205a04967b98fd1b3d18f24b05a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 21 Nov 2014 00:03:08 -0800 Subject: [PATCH 125/617] Add IP complete module and testbench --- rtl/ip_complete.v | 403 ++++++++++++++++++++ rtl/ip_complete_64.v | 422 +++++++++++++++++++++ tb/test_ip_complete.py | 733 +++++++++++++++++++++++++++++++++++++ tb/test_ip_complete.v | 282 ++++++++++++++ tb/test_ip_complete_64.py | 753 ++++++++++++++++++++++++++++++++++++++ tb/test_ip_complete_64.v | 294 +++++++++++++++ 6 files changed, 2887 insertions(+) create mode 100644 rtl/ip_complete.v create mode 100644 rtl/ip_complete_64.v create mode 100755 tb/test_ip_complete.py create mode 100644 tb/test_ip_complete.v create mode 100755 tb/test_ip_complete_64.py create mode 100644 tb/test_ip_complete_64.v diff --git a/rtl/ip_complete.v b/rtl/ip_complete.v new file mode 100644 index 000000000..d0f366eb2 --- /dev/null +++ b/rtl/ip_complete.v @@ -0,0 +1,403 @@ +/* + +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 + +/* + * IPv4 and ARP block, ethernet frame interface + */ +module ip_complete #( + parameter ARP_CACHE_ADDR_WIDTH = 2, + parameter ARP_REQUEST_RETRY_COUNT = 4, + parameter ARP_REQUEST_RETRY_INTERVAL = 125000000*2, + parameter ARP_REQUEST_TIMEOUT = 125000000*30 +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [7:0] input_eth_payload_tdata, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * IP input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [7:0] input_ip_payload_tdata, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_ip_eth_dest_mac, + output wire [47:0] output_ip_eth_src_mac, + output wire [15:0] output_ip_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Status + */ + output wire rx_busy, + output wire tx_busy, + output wire rx_error_header_early_termination, + output wire rx_error_payload_early_termination, + output wire rx_error_invalid_header, + output wire rx_error_invalid_checksum, + output wire tx_error_payload_early_termination, + output wire tx_error_arp_failed, + + /* + * Configuration + */ + input wire [47:0] local_mac, + input wire [31:0] local_ip, + input wire [31:0] gateway_ip, + input wire [31:0] subnet_mask, + input wire clear_arp_cache +); + +/* + +This module integrates the IP and ARP modules for a complete IP stack + +*/ + +wire arp_request_valid; +wire [31:0] arp_request_ip; +wire arp_response_valid; +wire arp_response_error; +wire [47:0] arp_response_mac; + +wire ip_rx_eth_hdr_valid; +wire ip_rx_eth_hdr_ready; +wire [47:0] ip_rx_eth_dest_mac; +wire [47:0] ip_rx_eth_src_mac; +wire [15:0] ip_rx_eth_type; +wire [7:0] ip_rx_eth_payload_tdata; +wire ip_rx_eth_payload_tvalid; +wire ip_rx_eth_payload_tready; +wire ip_rx_eth_payload_tlast; +wire ip_rx_eth_payload_tuser; + +wire ip_tx_eth_hdr_valid; +wire ip_tx_eth_hdr_ready; +wire [47:0] ip_tx_eth_dest_mac; +wire [47:0] ip_tx_eth_src_mac; +wire [15:0] ip_tx_eth_type; +wire [7:0] ip_tx_eth_payload_tdata; +wire ip_tx_eth_payload_tvalid; +wire ip_tx_eth_payload_tready; +wire ip_tx_eth_payload_tlast; +wire ip_tx_eth_payload_tuser; + +wire arp_rx_eth_hdr_valid; +wire arp_rx_eth_hdr_ready; +wire [47:0] arp_rx_eth_dest_mac; +wire [47:0] arp_rx_eth_src_mac; +wire [15:0] arp_rx_eth_type; +wire [7:0] arp_rx_eth_payload_tdata; +wire arp_rx_eth_payload_tvalid; +wire arp_rx_eth_payload_tready; +wire arp_rx_eth_payload_tlast; +wire arp_rx_eth_payload_tuser; + +wire arp_tx_eth_hdr_valid; +wire arp_tx_eth_hdr_ready; +wire [47:0] arp_tx_eth_dest_mac; +wire [47:0] arp_tx_eth_src_mac; +wire [15:0] arp_tx_eth_type; +wire [7:0] arp_tx_eth_payload_tdata; +wire arp_tx_eth_payload_tvalid; +wire arp_tx_eth_payload_tready; +wire arp_tx_eth_payload_tlast; +wire arp_tx_eth_payload_tuser; + +/* + * Input classifier (eth_type) + */ +wire input_select_ip = (input_eth_type == 16'h0800); +wire input_select_arp = (input_eth_type == 16'h0806); +wire input_select_none = ~(input_select_ip | input_select_arp); + +assign ip_rx_eth_hdr_valid = input_select_ip & input_eth_hdr_valid; +assign ip_rx_eth_dest_mac = input_eth_dest_mac; +assign ip_rx_eth_src_mac = input_eth_src_mac; +assign ip_rx_eth_type = 16'h0800; +assign ip_rx_eth_payload_tdata = input_eth_payload_tdata; +assign ip_rx_eth_payload_tvalid = input_select_ip & input_eth_payload_tvalid; +assign ip_rx_eth_payload_tlast = input_eth_payload_tlast; +assign ip_rx_eth_payload_tuser = input_eth_payload_tuser; + +assign arp_rx_eth_hdr_valid = input_select_arp & input_eth_hdr_valid; +assign arp_rx_eth_dest_mac = input_eth_dest_mac; +assign arp_rx_eth_src_mac = input_eth_src_mac; +assign arp_rx_eth_type = 16'h0806; +assign arp_rx_eth_payload_tdata = input_eth_payload_tdata; +assign arp_rx_eth_payload_tvalid = input_select_arp & input_eth_payload_tvalid; +assign arp_rx_eth_payload_tlast = input_eth_payload_tlast; +assign arp_rx_eth_payload_tuser = input_eth_payload_tuser; + +assign input_eth_hdr_ready = arp_rx_eth_hdr_ready & ip_rx_eth_hdr_ready; + +assign input_eth_payload_tready = (input_select_ip & ip_rx_eth_payload_tready) | + (input_select_arp & arp_rx_eth_payload_tready) | + input_select_none; + +/* + * Output arbiter + */ +eth_arb_mux_2 +eth_arb_mux_2_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame inputs + // ARP input (highest priority) + .input_0_eth_hdr_valid(arp_tx_eth_hdr_valid), + .input_0_eth_hdr_ready(arp_tx_eth_hdr_ready), + .input_0_eth_dest_mac(arp_tx_eth_dest_mac), + .input_0_eth_src_mac(arp_tx_eth_src_mac), + .input_0_eth_type(arp_tx_eth_type), + .input_0_eth_payload_tdata(arp_tx_eth_payload_tdata), + .input_0_eth_payload_tvalid(arp_tx_eth_payload_tvalid), + .input_0_eth_payload_tready(arp_tx_eth_payload_tready), + .input_0_eth_payload_tlast(arp_tx_eth_payload_tlast), + .input_0_eth_payload_tuser(arp_tx_eth_payload_tuser), + // IP input (lowest priority) + .input_1_eth_hdr_valid(ip_tx_eth_hdr_valid), + .input_1_eth_hdr_ready(ip_tx_eth_hdr_ready), + .input_1_eth_dest_mac(ip_tx_eth_dest_mac), + .input_1_eth_src_mac(ip_tx_eth_src_mac), + .input_1_eth_type(ip_tx_eth_type), + .input_1_eth_payload_tdata(ip_tx_eth_payload_tdata), + .input_1_eth_payload_tvalid(ip_tx_eth_payload_tvalid), + .input_1_eth_payload_tready(ip_tx_eth_payload_tready), + .input_1_eth_payload_tlast(ip_tx_eth_payload_tlast), + .input_1_eth_payload_tuser(ip_tx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser) +); + +/* + * IP module + */ +ip +ip_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(ip_rx_eth_hdr_valid), + .input_eth_hdr_ready(ip_rx_eth_hdr_ready), + .input_eth_dest_mac(ip_rx_eth_dest_mac), + .input_eth_src_mac(ip_rx_eth_src_mac), + .input_eth_type(ip_rx_eth_type), + .input_eth_payload_tdata(ip_rx_eth_payload_tdata), + .input_eth_payload_tvalid(ip_rx_eth_payload_tvalid), + .input_eth_payload_tready(ip_rx_eth_payload_tready), + .input_eth_payload_tlast(ip_rx_eth_payload_tlast), + .input_eth_payload_tuser(ip_rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(ip_tx_eth_hdr_valid), + .output_eth_hdr_ready(ip_tx_eth_hdr_ready), + .output_eth_dest_mac(ip_tx_eth_dest_mac), + .output_eth_src_mac(ip_tx_eth_src_mac), + .output_eth_type(ip_tx_eth_type), + .output_eth_payload_tdata(ip_tx_eth_payload_tdata), + .output_eth_payload_tvalid(ip_tx_eth_payload_tvalid), + .output_eth_payload_tready(ip_tx_eth_payload_tready), + .output_eth_payload_tlast(ip_tx_eth_payload_tlast), + .output_eth_payload_tuser(ip_tx_eth_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // ARP requests + .arp_request_valid(arp_request_valid), + .arp_request_ip(arp_request_ip), + .arp_response_valid(arp_response_valid), + .arp_response_error(arp_response_error), + .arp_response_mac(arp_response_mac), + // Status + .rx_busy(rx_busy), + .tx_busy(tx_busy), + .rx_error_header_early_termination(rx_error_header_early_termination), + .rx_error_payload_early_termination(rx_error_payload_early_termination), + .rx_error_invalid_header(rx_error_invalid_header), + .rx_error_invalid_checksum(rx_error_invalid_checksum), + .tx_error_payload_early_termination(tx_error_payload_early_termination), + .tx_error_arp_failed(tx_error_arp_failed), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip) +); + +/* + * ARP module + */ +arp #( + .CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT) +) +arp_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(arp_rx_eth_hdr_valid), + .input_eth_hdr_ready(arp_rx_eth_hdr_ready), + .input_eth_dest_mac(arp_rx_eth_dest_mac), + .input_eth_src_mac(arp_rx_eth_src_mac), + .input_eth_type(arp_rx_eth_type), + .input_eth_payload_tdata(arp_rx_eth_payload_tdata), + .input_eth_payload_tvalid(arp_rx_eth_payload_tvalid), + .input_eth_payload_tready(arp_rx_eth_payload_tready), + .input_eth_payload_tlast(arp_rx_eth_payload_tlast), + .input_eth_payload_tuser(arp_rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(arp_tx_eth_hdr_valid), + .output_eth_hdr_ready(arp_tx_eth_hdr_ready), + .output_eth_dest_mac(arp_tx_eth_dest_mac), + .output_eth_src_mac(arp_tx_eth_src_mac), + .output_eth_type(arp_tx_eth_type), + .output_eth_payload_tdata(arp_tx_eth_payload_tdata), + .output_eth_payload_tvalid(arp_tx_eth_payload_tvalid), + .output_eth_payload_tready(arp_tx_eth_payload_tready), + .output_eth_payload_tlast(arp_tx_eth_payload_tlast), + .output_eth_payload_tuser(arp_tx_eth_payload_tuser), + // ARP requests + .arp_request_valid(arp_request_valid), + .arp_request_ip(arp_request_ip), + .arp_response_valid(arp_response_valid), + .arp_response_error(arp_response_error), + .arp_response_mac(arp_response_mac), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_cache(clear_arp_cache) +); + +endmodule diff --git a/rtl/ip_complete_64.v b/rtl/ip_complete_64.v new file mode 100644 index 000000000..5147d143e --- /dev/null +++ b/rtl/ip_complete_64.v @@ -0,0 +1,422 @@ +/* + +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 + +/* + * IPv4 and ARP block, ethernet frame interface (64 bit datapath) + */ +module ip_complete_64 #( + parameter ARP_CACHE_ADDR_WIDTH = 2, + parameter ARP_REQUEST_RETRY_COUNT = 4, + parameter ARP_REQUEST_RETRY_INTERVAL = 156250000*2, + parameter ARP_REQUEST_TIMEOUT = 156250000*30 +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [63:0] input_eth_payload_tdata, + input wire [7:0] input_eth_payload_tkeep, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * IP input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [63:0] input_ip_payload_tdata, + input wire [7:0] input_ip_payload_tkeep, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_ip_eth_dest_mac, + output wire [47:0] output_ip_eth_src_mac, + output wire [15:0] output_ip_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Status + */ + output wire rx_busy, + output wire tx_busy, + output wire rx_error_header_early_termination, + output wire rx_error_payload_early_termination, + output wire rx_error_invalid_header, + output wire rx_error_invalid_checksum, + output wire tx_error_payload_early_termination, + output wire tx_error_arp_failed, + + /* + * Configuration + */ + input wire [47:0] local_mac, + input wire [31:0] local_ip, + input wire [31:0] gateway_ip, + input wire [31:0] subnet_mask, + input wire clear_arp_cache +); + +/* + +This module integrates the IP and ARP modules for a complete IP stack + +*/ + +wire arp_request_valid; +wire [31:0] arp_request_ip; +wire arp_response_valid; +wire arp_response_error; +wire [47:0] arp_response_mac; + +wire ip_rx_eth_hdr_valid; +wire ip_rx_eth_hdr_ready; +wire [47:0] ip_rx_eth_dest_mac; +wire [47:0] ip_rx_eth_src_mac; +wire [15:0] ip_rx_eth_type; +wire [63:0] ip_rx_eth_payload_tdata; +wire [7:0] ip_rx_eth_payload_tkeep; +wire ip_rx_eth_payload_tvalid; +wire ip_rx_eth_payload_tready; +wire ip_rx_eth_payload_tlast; +wire ip_rx_eth_payload_tuser; + +wire ip_tx_eth_hdr_valid; +wire ip_tx_eth_hdr_ready; +wire [47:0] ip_tx_eth_dest_mac; +wire [47:0] ip_tx_eth_src_mac; +wire [15:0] ip_tx_eth_type; +wire [63:0] ip_tx_eth_payload_tdata; +wire [7:0] ip_tx_eth_payload_tkeep; +wire ip_tx_eth_payload_tvalid; +wire ip_tx_eth_payload_tready; +wire ip_tx_eth_payload_tlast; +wire ip_tx_eth_payload_tuser; + +wire arp_rx_eth_hdr_valid; +wire arp_rx_eth_hdr_ready; +wire [47:0] arp_rx_eth_dest_mac; +wire [47:0] arp_rx_eth_src_mac; +wire [15:0] arp_rx_eth_type; +wire [63:0] arp_rx_eth_payload_tdata; +wire [7:0] arp_rx_eth_payload_tkeep; +wire arp_rx_eth_payload_tvalid; +wire arp_rx_eth_payload_tready; +wire arp_rx_eth_payload_tlast; +wire arp_rx_eth_payload_tuser; + +wire arp_tx_eth_hdr_valid; +wire arp_tx_eth_hdr_ready; +wire [47:0] arp_tx_eth_dest_mac; +wire [47:0] arp_tx_eth_src_mac; +wire [15:0] arp_tx_eth_type; +wire [63:0] arp_tx_eth_payload_tdata; +wire [7:0] arp_tx_eth_payload_tkeep; +wire arp_tx_eth_payload_tvalid; +wire arp_tx_eth_payload_tready; +wire arp_tx_eth_payload_tlast; +wire arp_tx_eth_payload_tuser; + +/* + * Input classifier (eth_type) + */ +wire input_select_ip = (input_eth_type == 16'h0800); +wire input_select_arp = (input_eth_type == 16'h0806); +wire input_select_none = ~(input_select_ip | input_select_arp); + +assign ip_rx_eth_hdr_valid = input_select_ip & input_eth_hdr_valid; +assign ip_rx_eth_dest_mac = input_eth_dest_mac; +assign ip_rx_eth_src_mac = input_eth_src_mac; +assign ip_rx_eth_type = 16'h0800; +assign ip_rx_eth_payload_tdata = input_eth_payload_tdata; +assign ip_rx_eth_payload_tkeep = input_eth_payload_tkeep; +assign ip_rx_eth_payload_tvalid = input_select_ip & input_eth_payload_tvalid; +assign ip_rx_eth_payload_tlast = input_eth_payload_tlast; +assign ip_rx_eth_payload_tuser = input_eth_payload_tuser; + +assign arp_rx_eth_hdr_valid = input_select_arp & input_eth_hdr_valid; +assign arp_rx_eth_dest_mac = input_eth_dest_mac; +assign arp_rx_eth_src_mac = input_eth_src_mac; +assign arp_rx_eth_type = 16'h0806; +assign arp_rx_eth_payload_tdata = input_eth_payload_tdata; +assign arp_rx_eth_payload_tkeep = input_eth_payload_tkeep; +assign arp_rx_eth_payload_tvalid = input_select_arp & input_eth_payload_tvalid; +assign arp_rx_eth_payload_tlast = input_eth_payload_tlast; +assign arp_rx_eth_payload_tuser = input_eth_payload_tuser; + +assign input_eth_hdr_ready = arp_rx_eth_hdr_ready & ip_rx_eth_hdr_ready; + +assign input_eth_payload_tready = (input_select_ip & ip_rx_eth_payload_tready) | + (input_select_arp & arp_rx_eth_payload_tready) | + input_select_none; + +/* + * Output arbiter + */ +eth_arb_mux_64_2 +eth_arb_mux_2_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame inputs + // ARP input (highest priority) + .input_0_eth_hdr_valid(arp_tx_eth_hdr_valid), + .input_0_eth_hdr_ready(arp_tx_eth_hdr_ready), + .input_0_eth_dest_mac(arp_tx_eth_dest_mac), + .input_0_eth_src_mac(arp_tx_eth_src_mac), + .input_0_eth_type(arp_tx_eth_type), + .input_0_eth_payload_tdata(arp_tx_eth_payload_tdata), + .input_0_eth_payload_tkeep(arp_tx_eth_payload_tkeep), + .input_0_eth_payload_tvalid(arp_tx_eth_payload_tvalid), + .input_0_eth_payload_tready(arp_tx_eth_payload_tready), + .input_0_eth_payload_tlast(arp_tx_eth_payload_tlast), + .input_0_eth_payload_tuser(arp_tx_eth_payload_tuser), + // IP input (lowest priority) + .input_1_eth_hdr_valid(ip_tx_eth_hdr_valid), + .input_1_eth_hdr_ready(ip_tx_eth_hdr_ready), + .input_1_eth_dest_mac(ip_tx_eth_dest_mac), + .input_1_eth_src_mac(ip_tx_eth_src_mac), + .input_1_eth_type(ip_tx_eth_type), + .input_1_eth_payload_tdata(ip_tx_eth_payload_tdata), + .input_1_eth_payload_tkeep(ip_tx_eth_payload_tkeep), + .input_1_eth_payload_tvalid(ip_tx_eth_payload_tvalid), + .input_1_eth_payload_tready(ip_tx_eth_payload_tready), + .input_1_eth_payload_tlast(ip_tx_eth_payload_tlast), + .input_1_eth_payload_tuser(ip_tx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser) +); + +/* + * IP module + */ +ip_64 +ip_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(ip_rx_eth_hdr_valid), + .input_eth_hdr_ready(ip_rx_eth_hdr_ready), + .input_eth_dest_mac(ip_rx_eth_dest_mac), + .input_eth_src_mac(ip_rx_eth_src_mac), + .input_eth_type(ip_rx_eth_type), + .input_eth_payload_tdata(ip_rx_eth_payload_tdata), + .input_eth_payload_tkeep(ip_rx_eth_payload_tkeep), + .input_eth_payload_tvalid(ip_rx_eth_payload_tvalid), + .input_eth_payload_tready(ip_rx_eth_payload_tready), + .input_eth_payload_tlast(ip_rx_eth_payload_tlast), + .input_eth_payload_tuser(ip_rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(ip_tx_eth_hdr_valid), + .output_eth_hdr_ready(ip_tx_eth_hdr_ready), + .output_eth_dest_mac(ip_tx_eth_dest_mac), + .output_eth_src_mac(ip_tx_eth_src_mac), + .output_eth_type(ip_tx_eth_type), + .output_eth_payload_tdata(ip_tx_eth_payload_tdata), + .output_eth_payload_tkeep(ip_tx_eth_payload_tkeep), + .output_eth_payload_tvalid(ip_tx_eth_payload_tvalid), + .output_eth_payload_tready(ip_tx_eth_payload_tready), + .output_eth_payload_tlast(ip_tx_eth_payload_tlast), + .output_eth_payload_tuser(ip_tx_eth_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // ARP requests + .arp_request_valid(arp_request_valid), + .arp_request_ip(arp_request_ip), + .arp_response_valid(arp_response_valid), + .arp_response_error(arp_response_error), + .arp_response_mac(arp_response_mac), + // Status + .rx_busy(rx_busy), + .tx_busy(tx_busy), + .rx_error_header_early_termination(rx_error_header_early_termination), + .rx_error_payload_early_termination(rx_error_payload_early_termination), + .rx_error_invalid_header(rx_error_invalid_header), + .rx_error_invalid_checksum(rx_error_invalid_checksum), + .tx_error_payload_early_termination(tx_error_payload_early_termination), + .tx_error_arp_failed(tx_error_arp_failed), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip) +); + +/* + * ARP module + */ +arp_64 #( + .CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT) +) +arp_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(arp_rx_eth_hdr_valid), + .input_eth_hdr_ready(arp_rx_eth_hdr_ready), + .input_eth_dest_mac(arp_rx_eth_dest_mac), + .input_eth_src_mac(arp_rx_eth_src_mac), + .input_eth_type(arp_rx_eth_type), + .input_eth_payload_tdata(arp_rx_eth_payload_tdata), + .input_eth_payload_tkeep(arp_rx_eth_payload_tkeep), + .input_eth_payload_tvalid(arp_rx_eth_payload_tvalid), + .input_eth_payload_tready(arp_rx_eth_payload_tready), + .input_eth_payload_tlast(arp_rx_eth_payload_tlast), + .input_eth_payload_tuser(arp_rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(arp_tx_eth_hdr_valid), + .output_eth_hdr_ready(arp_tx_eth_hdr_ready), + .output_eth_dest_mac(arp_tx_eth_dest_mac), + .output_eth_src_mac(arp_tx_eth_src_mac), + .output_eth_type(arp_tx_eth_type), + .output_eth_payload_tdata(arp_tx_eth_payload_tdata), + .output_eth_payload_tkeep(arp_tx_eth_payload_tkeep), + .output_eth_payload_tvalid(arp_tx_eth_payload_tvalid), + .output_eth_payload_tready(arp_tx_eth_payload_tready), + .output_eth_payload_tlast(arp_tx_eth_payload_tlast), + .output_eth_payload_tuser(arp_tx_eth_payload_tuser), + // ARP requests + .arp_request_valid(arp_request_valid), + .arp_request_ip(arp_request_ip), + .arp_response_valid(arp_response_valid), + .arp_response_error(arp_response_error), + .arp_response_mac(arp_response_mac), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_cache(clear_arp_cache) +); + +endmodule diff --git a/tb/test_ip_complete.py b/tb/test_ip_complete.py new file mode 100755 index 000000000..f73631254 --- /dev/null +++ b/tb/test_ip_complete.py @@ -0,0 +1,733 @@ +#!/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 eth_ep +import arp_ep +import ip_ep + +module = 'ip_complete' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/ip.v") +srcs.append("../rtl/ip_eth_rx.v") +srcs.append("../rtl/ip_eth_tx.v") +srcs.append("../rtl/arp.v") +srcs.append("../rtl/arp_cache.v") +srcs.append("../rtl/arp_eth_rx.v") +srcs.append("../rtl/arp_eth_tx.v") +srcs.append("../rtl/eth_arb_mux_2.v") +srcs.append("../rtl/eth_mux_2.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_ip_complete(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + input_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_ip_eth_dest_mac=output_ip_eth_dest_mac, + output_ip_eth_src_mac=output_ip_eth_src_mac, + output_ip_eth_type=output_ip_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + rx_busy=rx_busy, + tx_busy=tx_busy, + rx_error_header_early_termination=rx_error_header_early_termination, + rx_error_payload_early_termination=rx_error_payload_early_termination, + rx_error_invalid_header=rx_error_invalid_header, + rx_error_invalid_checksum=rx_error_invalid_checksum, + tx_error_payload_early_termination=tx_error_payload_early_termination, + tx_error_arp_failed=tx_error_arp_failed, + + local_mac=local_mac, + local_ip=local_ip, + gateway_ip=gateway_ip, + subnet_mask=subnet_mask, + clear_arp_cache=clear_arp_cache) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + input_ip_hdr_valid = Signal(bool(0)) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_ip_eth_dest_mac = Signal(intbv(0)[48:]) + output_ip_eth_src_mac = Signal(intbv(0)[48:]) + output_ip_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + rx_busy = Signal(bool(0)) + tx_busy = Signal(bool(0)) + rx_error_header_early_termination = Signal(bool(0)) + rx_error_payload_early_termination = Signal(bool(0)) + rx_error_invalid_header = Signal(bool(0)) + rx_error_invalid_checksum = Signal(bool(0)) + tx_error_payload_early_termination = Signal(bool(0)) + tx_error_arp_failed = Signal(bool(0)) + local_mac = Signal(intbv(0)[48:]) + local_ip = Signal(intbv(0)[32:]) + gateway_ip = Signal(intbv(0)[32:]) + subnet_mask = Signal(intbv(0)[32:]) + clear_arp_cache = Signal(bool(0)) + + # sources and sinks + eth_source_queue = Queue() + eth_source_pause = Signal(bool(0)) + eth_sink_queue = Queue() + eth_sink_pause = Signal(bool(0)) + ip_source_queue = Queue() + ip_source_pause = Signal(bool(0)) + ip_sink_queue = Queue() + ip_sink_pause = Signal(bool(0)) + + eth_source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=eth_source_queue, + pause=eth_source_pause, + name='eth_source') + + eth_sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=eth_sink_queue, + pause=eth_sink_pause, + name='eth_sink') + + ip_source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=ip_source_queue, + pause=ip_source_pause, + name='ip_source') + + ip_sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_ip_eth_dest_mac, + eth_src_mac=output_ip_eth_src_mac, + eth_type=output_ip_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=ip_sink_queue, + pause=ip_sink_pause, + name='ip_sink') + + # DUT + dut = dut_ip_complete(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + rx_error_header_early_termination_asserted = Signal(bool(0)) + rx_error_payload_early_termination_asserted = Signal(bool(0)) + rx_error_invalid_header_asserted = Signal(bool(0)) + rx_error_invalid_checksum_asserted = Signal(bool(0)) + tx_error_payload_early_termination_asserted = Signal(bool(0)) + tx_error_arp_failed_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_header_early_termination): + rx_error_header_early_termination_asserted.next = 1 + if (rx_error_payload_early_termination): + rx_error_payload_early_termination_asserted.next = 1 + if (rx_error_invalid_header): + rx_error_invalid_header_asserted.next = 1 + if (rx_error_invalid_checksum): + rx_error_invalid_checksum_asserted.next = 1 + if (tx_error_payload_early_termination): + tx_error_payload_early_termination_asserted.next = 1 + if (tx_error_arp_failed): + tx_error_arp_failed_asserted.next = 1 + + def wait_normal(): + while (input_eth_payload_tvalid or input_ip_payload_tvalid or + output_eth_payload_tvalid or output_ip_payload_tvalid or + input_eth_hdr_valid or input_ip_hdr_valid): + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # set MAC and IP address + local_mac.next = 0x5A5152535455 + local_ip.next = 0xc0a80164 + gateway_ip.next = 0xc0a80101 + subnet_mask.next = 0xffffff00 + + yield clk.posedge + print("test 1: test IP RX packet") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = ip_sink_queue.get(False) + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test IP TX packet") + current_test.next = 2 + + # send IP packet + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + # wait for ARP request packet + while eth_sink_queue.empty(): + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80166 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x5A5152535455 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80166 + arp_frame.arp_tha = 0x5A5152535455 + arp_frame.arp_tpa = 0xc0a80164 + eth_source_queue.put(arp_frame.build_eth()) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + print(test_frame) + print(check_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: test IP TX arp fail packet") + current_test.next = 2 + + tx_error_arp_failed_asserted.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80167 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + assert tx_error_arp_failed_asserted + + # check for 4 ARP requests + assert eth_sink_queue.qsize() == 4 + + while not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get(False) + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80167 + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, eth_source, eth_sink, ip_source, ip_sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_complete.v b/tb/test_ip_complete.v new file mode 100644 index 000000000..dbbf40d20 --- /dev/null +++ b/tb/test_ip_complete.v @@ -0,0 +1,282 @@ +/* + +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_ip_complete; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [7:0] input_eth_payload_tdata = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg arp_response_valid = 0; +reg arp_response_error = 0; +reg [47:0] arp_response_mac = 0; +reg input_ip_hdr_valid = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [7:0] input_ip_payload_tdata = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; +reg [47:0] local_mac = 0; +reg [31:0] local_ip = 0; +reg [31:0] gateway_ip = 0; +reg [31:0] subnet_mask = 0; +reg clear_arp_cache = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [7:0] output_eth_payload_tdata; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire arp_request_valid; +wire [31:0] arp_request_ip; +wire output_ip_hdr_valid; +wire [47:0] output_ip_eth_dest_mac; +wire [47:0] output_ip_eth_src_mac; +wire [15:0] output_ip_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [7:0] output_ip_payload_tdata; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire rx_busy; +wire tx_busy; +wire rx_error_header_early_termination; +wire rx_error_payload_early_termination; +wire rx_error_invalid_header; +wire rx_error_invalid_checksum; +wire tx_error_payload_early_termination; +wire tx_error_arp_failed; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + input_ip_hdr_valid, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + output_ip_hdr_ready, + output_ip_payload_tready, + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + input_ip_hdr_ready, + input_ip_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + output_ip_hdr_valid, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed); + + // dump file + $dumpfile("test_ip_complete.lxt"); + $dumpvars(0, test_ip_complete); +end + +ip_complete #( + .ARP_CACHE_ADDR_WIDTH(2), + .ARP_REQUEST_RETRY_COUNT(4), + .ARP_REQUEST_RETRY_INTERVAL(150), + .ARP_REQUEST_TIMEOUT(400) +) +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .rx_busy(rx_busy), + .tx_busy(tx_busy), + .rx_error_header_early_termination(rx_error_header_early_termination), + .rx_error_payload_early_termination(rx_error_payload_early_termination), + .rx_error_invalid_header(rx_error_invalid_header), + .rx_error_invalid_checksum(rx_error_invalid_checksum), + .tx_error_payload_early_termination(tx_error_payload_early_termination), + .tx_error_arp_failed(tx_error_arp_failed), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(clear_arp_cache) +); + +endmodule diff --git a/tb/test_ip_complete_64.py b/tb/test_ip_complete_64.py new file mode 100755 index 000000000..a1311ae37 --- /dev/null +++ b/tb/test_ip_complete_64.py @@ -0,0 +1,753 @@ +#!/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 eth_ep +import arp_ep +import ip_ep + +module = 'ip_complete_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/ip_64.v") +srcs.append("../rtl/ip_eth_rx_64.v") +srcs.append("../rtl/ip_eth_tx_64.v") +srcs.append("../rtl/arp_64.v") +srcs.append("../rtl/arp_cache.v") +srcs.append("../rtl/arp_eth_rx_64.v") +srcs.append("../rtl/arp_eth_tx_64.v") +srcs.append("../rtl/eth_arb_mux_64_2.v") +srcs.append("../rtl/eth_mux_64_2.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_ip_complete_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + input_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tkeep=input_ip_payload_tkeep, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_ip_eth_dest_mac=output_ip_eth_dest_mac, + output_ip_eth_src_mac=output_ip_eth_src_mac, + output_ip_eth_type=output_ip_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tkeep=output_ip_payload_tkeep, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + rx_busy=rx_busy, + tx_busy=tx_busy, + rx_error_header_early_termination=rx_error_header_early_termination, + rx_error_payload_early_termination=rx_error_payload_early_termination, + rx_error_invalid_header=rx_error_invalid_header, + rx_error_invalid_checksum=rx_error_invalid_checksum, + tx_error_payload_early_termination=tx_error_payload_early_termination, + tx_error_arp_failed=tx_error_arp_failed, + + local_mac=local_mac, + local_ip=local_ip, + gateway_ip=gateway_ip, + subnet_mask=subnet_mask, + clear_arp_cache=clear_arp_cache) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[64:]) + input_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + input_ip_hdr_valid = Signal(bool(0)) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[64:]) + input_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[64:]) + output_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_ip_eth_dest_mac = Signal(intbv(0)[48:]) + output_ip_eth_src_mac = Signal(intbv(0)[48:]) + output_ip_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[64:]) + output_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + rx_busy = Signal(bool(0)) + tx_busy = Signal(bool(0)) + rx_error_header_early_termination = Signal(bool(0)) + rx_error_payload_early_termination = Signal(bool(0)) + rx_error_invalid_header = Signal(bool(0)) + rx_error_invalid_checksum = Signal(bool(0)) + tx_error_payload_early_termination = Signal(bool(0)) + tx_error_arp_failed = Signal(bool(0)) + local_mac = Signal(intbv(0)[48:]) + local_ip = Signal(intbv(0)[32:]) + gateway_ip = Signal(intbv(0)[32:]) + subnet_mask = Signal(intbv(0)[32:]) + clear_arp_cache = Signal(bool(0)) + + # sources and sinks + eth_source_queue = Queue() + eth_source_pause = Signal(bool(0)) + eth_sink_queue = Queue() + eth_sink_pause = Signal(bool(0)) + ip_source_queue = Queue() + ip_source_pause = Signal(bool(0)) + ip_sink_queue = Queue() + ip_sink_pause = Signal(bool(0)) + + eth_source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=eth_source_queue, + pause=eth_source_pause, + name='eth_source') + + eth_sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=eth_sink_queue, + pause=eth_sink_pause, + name='eth_sink') + + ip_source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tkeep=input_ip_payload_tkeep, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=ip_source_queue, + pause=ip_source_pause, + name='ip_source') + + ip_sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_ip_eth_dest_mac, + eth_src_mac=output_ip_eth_src_mac, + eth_type=output_ip_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tkeep=output_ip_payload_tkeep, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=ip_sink_queue, + pause=ip_sink_pause, + name='ip_sink') + + # DUT + dut = dut_ip_complete_64(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + rx_error_header_early_termination_asserted = Signal(bool(0)) + rx_error_payload_early_termination_asserted = Signal(bool(0)) + rx_error_invalid_header_asserted = Signal(bool(0)) + rx_error_invalid_checksum_asserted = Signal(bool(0)) + tx_error_payload_early_termination_asserted = Signal(bool(0)) + tx_error_arp_failed_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_header_early_termination): + rx_error_header_early_termination_asserted.next = 1 + if (rx_error_payload_early_termination): + rx_error_payload_early_termination_asserted.next = 1 + if (rx_error_invalid_header): + rx_error_invalid_header_asserted.next = 1 + if (rx_error_invalid_checksum): + rx_error_invalid_checksum_asserted.next = 1 + if (tx_error_payload_early_termination): + tx_error_payload_early_termination_asserted.next = 1 + if (tx_error_arp_failed): + tx_error_arp_failed_asserted.next = 1 + + def wait_normal(): + while (input_eth_payload_tvalid or input_ip_payload_tvalid or + output_eth_payload_tvalid or output_ip_payload_tvalid or + input_eth_hdr_valid or input_ip_hdr_valid): + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # set MAC and IP address + local_mac.next = 0x5A5152535455 + local_ip.next = 0xc0a80164 + gateway_ip.next = 0xc0a80101 + subnet_mask.next = 0xffffff00 + + yield clk.posedge + print("test 1: test IP RX packet") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = ip_sink_queue.get(False) + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test IP TX packet") + current_test.next = 2 + + # send IP packet + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + # wait for ARP request packet + while eth_sink_queue.empty(): + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80166 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x5A5152535455 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80166 + arp_frame.arp_tha = 0x5A5152535455 + arp_frame.arp_tpa = 0xc0a80164 + eth_source_queue.put(arp_frame.build_eth()) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + print(test_frame) + print(check_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: test IP TX arp fail packet") + current_test.next = 2 + + tx_error_arp_failed_asserted.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80167 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + assert tx_error_arp_failed_asserted + + # check for 4 ARP requests + assert eth_sink_queue.qsize() == 4 + + while not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get(False) + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80167 + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, eth_source, eth_sink, ip_source, ip_sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_ip_complete_64.v b/tb/test_ip_complete_64.v new file mode 100644 index 000000000..790c90cf3 --- /dev/null +++ b/tb/test_ip_complete_64.v @@ -0,0 +1,294 @@ +/* + +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_ip_complete_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [63:0] input_eth_payload_tdata = 0; +reg [7:0] input_eth_payload_tkeep = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg arp_response_valid = 0; +reg arp_response_error = 0; +reg [47:0] arp_response_mac = 0; +reg input_ip_hdr_valid = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [63:0] input_ip_payload_tdata = 0; +reg [7:0] input_ip_payload_tkeep = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; +reg [47:0] local_mac = 0; +reg [31:0] local_ip = 0; +reg [31:0] gateway_ip = 0; +reg [31:0] subnet_mask = 0; +reg clear_arp_cache = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [63:0] output_eth_payload_tdata; +wire [7:0] output_eth_payload_tkeep; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire arp_request_valid; +wire [31:0] arp_request_ip; +wire output_ip_hdr_valid; +wire [47:0] output_ip_eth_dest_mac; +wire [47:0] output_ip_eth_src_mac; +wire [15:0] output_ip_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [63:0] output_ip_payload_tdata; +wire [7:0] output_ip_payload_tkeep; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire rx_busy; +wire tx_busy; +wire rx_error_header_early_termination; +wire rx_error_payload_early_termination; +wire rx_error_invalid_header; +wire rx_error_invalid_checksum; +wire tx_error_payload_early_termination; +wire tx_error_arp_failed; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + input_ip_hdr_valid, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + output_ip_hdr_ready, + output_ip_payload_tready, + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + input_ip_hdr_ready, + input_ip_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + output_ip_hdr_valid, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + rx_error_invalid_header, + rx_error_invalid_checksum, + tx_error_payload_early_termination, + tx_error_arp_failed); + + // dump file + $dumpfile("test_ip_complete_64.lxt"); + $dumpvars(0, test_ip_complete_64); +end + +ip_complete_64 #( + .ARP_CACHE_ADDR_WIDTH(2), + .ARP_REQUEST_RETRY_COUNT(4), + .ARP_REQUEST_RETRY_INTERVAL(150), + .ARP_REQUEST_TIMEOUT(400) +) +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .rx_busy(rx_busy), + .tx_busy(tx_busy), + .rx_error_header_early_termination(rx_error_header_early_termination), + .rx_error_payload_early_termination(rx_error_payload_early_termination), + .rx_error_invalid_header(rx_error_invalid_header), + .rx_error_invalid_checksum(rx_error_invalid_checksum), + .tx_error_payload_early_termination(tx_error_payload_early_termination), + .tx_error_arp_failed(tx_error_arp_failed), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(clear_arp_cache) +); + +endmodule From 32a66ed014662284bbf810ddd4b222893fbbf07d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 21 Nov 2014 00:15:30 -0800 Subject: [PATCH 126/617] Update readme --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 6914809dd..f976d72d5 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,19 @@ intelligent bus cosimulation endpoints. ## Documentation +### arp module + +ARP handling logic with parametrizable retry timeout parameters. + +### arp_64 module + +ARP handling logic with parametrizable retry timeout parameters and 64 bit +datapath for 10G Ethernet. + +### arp_cache module + +Basic LRU cache for ARP entries. Parametrizable depth. + ### arp_eth_rx module ARP frame receiver. @@ -112,6 +125,18 @@ Supports priority and round-robin arbitration. Can be generated with arbitrary port counts with ip_arb_mux_64.py. +### ip_complete module + +IPv4 module with ARP integration. + +Top level for gigabit IP stack. + +### ip_complete_64 module + +IPv4 module with ARP integration and 64 bit data width for 10G Ethernet. + +Top level for 10G IP stack. + ### ip_eth_rx module IP frame receiver. From d60844a399f4fe2bc6aa65e97b5b0cda3ef012b8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 21 Nov 2014 00:20:54 -0800 Subject: [PATCH 127/617] Update readme --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index f976d72d5..2c7196262 100644 --- a/README.md +++ b/README.md @@ -250,13 +250,18 @@ Can be generated with arbitrary port counts with udp_mux_64.py. ### Source Files + rtl/arp.v : ARP handling logic + rtl/arp_64.v : ARP handling logic (64 bit) + rtl/arp_cache.v : ARP LRU cache rtl/arp_eth_rx.v : ARP frame receiver rtl/arp_eth_rx_64.v : ARP frame receiver (64 bit) rtl/arp_eth_tx.v : ARP frame transmitter rtl/arp_eth_tx_64.v : ARP frame transmitter (64 bit) rtl/eth_arb_mux.py : Ethernet frame arbitrated multiplexer generator + rtl/eth_arb_mux_2.v : 2 port Ethernet frame arbitrated multiplexer rtl/eth_arb_mux_4.v : 4 port Ethernet frame arbitrated multiplexer rtl/eth_arb_mux_64.py : Ethernet frame arbitrated multiplexer generator (64 bit) + rtl/eth_arb_mux_64_2.v : 2 port Ethernet frame arbitrated multiplexer (64 bit) rtl/eth_arb_mux_64_4.v : 4 port Ethernet frame arbitrated multiplexer (64 bit) rtl/eth_axis_rx.v : Ethernet frame receiver rtl/eth_axis_rx_64.v : Ethernet frame receiver (64 bit) @@ -267,8 +272,10 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/eth_demux_64.py : Ethernet frame demultiplexer generator (64 bit) rtl/eth_demux_64_4.v : 4 port Ethernet frame demultiplexer (64 bit) rtl/eth_mux.py : Ethernet frame multiplexer generator + rtl/eth_mux_2.v : 4 port Ethernet frame multiplexer rtl/eth_mux_4.v : 4 port Ethernet frame multiplexer rtl/eth_mux_64.py : Ethernet frame multiplexer generator (64 bit) + rtl/eth_mux_64_2.v : 4 port Ethernet frame multiplexer (64 bit) rtl/eth_mux_64_4.v : 4 port Ethernet frame multiplexer (64 bit) rtl/ip.v : IPv4 block rtl/ip_64.v : IPv4 block (64 bit) @@ -276,6 +283,8 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/ip_arb_mux_4.v : 4 port IP frame arbitrated multiplexer rtl/ip_arb_mux_64.py : IP frame arbitrated multiplexer generator (64 bit) rtl/ip_arb_mux_64_4.v : 4 port IP frame arbitrated multiplexer (64 bit) + rtl/ip_complete.v : IPv4 stack (IP-ARP integration) + rtl/ip_complete_64.v : IPv4 stack (IP-ARP integration) (64 bit) rtl/ip_eth_rx.v : IPv4 frame receiver rtl/ip_eth_rx_64.v : IPv4 frame receiver (64 bit) rtl/ip_eth_tx.v : IPv4 frame transmitter From 27cb9609f1e9a87e4b35fab6c3317e3406eaaabf Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 21 Nov 2014 01:06:24 -0800 Subject: [PATCH 128/617] clog2 does not work in localparam in XST --- rtl/priority_encoder.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/priority_encoder.v b/rtl/priority_encoder.v index cb380c760..e0d3c1a41 100644 --- a/rtl/priority_encoder.v +++ b/rtl/priority_encoder.v @@ -43,8 +43,8 @@ module priority_encoder # ); // power-of-two width -localparam W1 = 2**$clog2(WIDTH); -localparam W2 = W1/2; +parameter W1 = 2**$clog2(WIDTH); +parameter W2 = W1/2; generate if (WIDTH == 2) begin From 63f6e96492eb9899e2f740a2555f74279157cd07 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 21 Nov 2014 01:07:02 -0800 Subject: [PATCH 129/617] Add tuser signal to crosspoint module --- rtl/axis_crosspoint.py | 11 +++++++ rtl/axis_crosspoint_4x4.v | 56 +++++++++++++++++++++++++++++++ rtl/axis_crosspoint_64.py | 13 ++++++++ rtl/axis_crosspoint_64_4x4.v | 64 ++++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+) diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index e779ad086..e37707bb3 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -114,6 +114,7 @@ module {{name}} # input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, input wire input_{{p}}_axis_tvalid, input wire input_{{p}}_axis_tlast, + input wire input_{{p}}_axis_tuser, {% endfor %} /* * AXI Stream outputs @@ -122,6 +123,7 @@ module {{name}} # output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, output wire output_{{p}}_axis_tvalid, output wire output_{{p}}_axis_tlast, + output wire output_{{p}}_axis_tuser, {% endfor %} /* * Control @@ -134,12 +136,14 @@ module {{name}} # reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = 0; reg input_{{p}}_axis_tvalid_reg = 0; reg input_{{p}}_axis_tlast_reg = 0; +reg input_{{p}}_axis_tuser_reg = 0; {% endfor %} {%- for p in ports %} reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = 0; reg output_{{p}}_axis_tvalid_reg = 0; reg output_{{p}}_axis_tlast_reg = 0; +reg output_{{p}}_axis_tuser_reg = 0; {% endfor %} {%- for p in ports %} @@ -149,6 +153,7 @@ reg [{{w-1}}:0] output_{{p}}_select_reg = 0; assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; +assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; {% endfor %} always @(posedge clk or posedge rst) begin @@ -157,18 +162,23 @@ always @(posedge clk or posedge rst) begin output_{{p}}_select_reg <= 0; {%- endfor %} {% for p in ports %} + input_{{p}}_axis_tdata_reg <= 0; input_{{p}}_axis_tvalid_reg <= 0; input_{{p}}_axis_tlast_reg <= 0; + input_{{p}}_axis_tuser_reg <= 0; {%- endfor %} {% for p in ports %} + output_{{p}}_axis_tdata_reg <= 0; output_{{p}}_axis_tvalid_reg <= 0; output_{{p}}_axis_tlast_reg <= 0; + output_{{p}}_axis_tuser_reg <= 0; {%- endfor %} end else begin {%- for p in ports %} input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; + input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; {% endfor %} {%- for p in ports %} output_{{p}}_select_reg <= output_{{p}}_select; @@ -181,6 +191,7 @@ always @(posedge clk or posedge rst) begin output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; + output_{{p}}_axis_tuser_reg <= input_{{q}}_axis_tuser_reg; end {%- endfor %} endcase diff --git a/rtl/axis_crosspoint_4x4.v b/rtl/axis_crosspoint_4x4.v index 859f4309c..581fdf016 100644 --- a/rtl/axis_crosspoint_4x4.v +++ b/rtl/axis_crosspoint_4x4.v @@ -43,18 +43,22 @@ module axis_crosspoint_4x4 # input wire [DATA_WIDTH-1:0] input_0_axis_tdata, input wire input_0_axis_tvalid, input wire input_0_axis_tlast, + input wire input_0_axis_tuser, input wire [DATA_WIDTH-1:0] input_1_axis_tdata, input wire input_1_axis_tvalid, input wire input_1_axis_tlast, + input wire input_1_axis_tuser, input wire [DATA_WIDTH-1:0] input_2_axis_tdata, input wire input_2_axis_tvalid, input wire input_2_axis_tlast, + input wire input_2_axis_tuser, input wire [DATA_WIDTH-1:0] input_3_axis_tdata, input wire input_3_axis_tvalid, input wire input_3_axis_tlast, + input wire input_3_axis_tuser, /* * AXI Stream outputs @@ -62,18 +66,22 @@ module axis_crosspoint_4x4 # output wire [DATA_WIDTH-1:0] output_0_axis_tdata, output wire output_0_axis_tvalid, output wire output_0_axis_tlast, + output wire output_0_axis_tuser, output wire [DATA_WIDTH-1:0] output_1_axis_tdata, output wire output_1_axis_tvalid, output wire output_1_axis_tlast, + output wire output_1_axis_tuser, output wire [DATA_WIDTH-1:0] output_2_axis_tdata, output wire output_2_axis_tvalid, output wire output_2_axis_tlast, + output wire output_2_axis_tuser, output wire [DATA_WIDTH-1:0] output_3_axis_tdata, output wire output_3_axis_tvalid, output wire output_3_axis_tlast, + output wire output_3_axis_tuser, /* * Control @@ -87,34 +95,42 @@ module axis_crosspoint_4x4 # reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = 0; reg input_0_axis_tvalid_reg = 0; reg input_0_axis_tlast_reg = 0; +reg input_0_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = 0; reg input_1_axis_tvalid_reg = 0; reg input_1_axis_tlast_reg = 0; +reg input_1_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = 0; reg input_2_axis_tvalid_reg = 0; reg input_2_axis_tlast_reg = 0; +reg input_2_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = 0; reg input_3_axis_tvalid_reg = 0; reg input_3_axis_tlast_reg = 0; +reg input_3_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = 0; reg output_0_axis_tvalid_reg = 0; reg output_0_axis_tlast_reg = 0; +reg output_0_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = 0; reg output_1_axis_tvalid_reg = 0; reg output_1_axis_tlast_reg = 0; +reg output_1_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = 0; reg output_2_axis_tvalid_reg = 0; reg output_2_axis_tlast_reg = 0; +reg output_2_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = 0; reg output_3_axis_tvalid_reg = 0; reg output_3_axis_tlast_reg = 0; +reg output_3_axis_tuser_reg = 0; reg [1:0] output_0_select_reg = 0; reg [1:0] output_1_select_reg = 0; @@ -124,18 +140,22 @@ reg [1:0] output_3_select_reg = 0; assign output_0_axis_tdata = output_0_axis_tdata_reg; assign output_0_axis_tvalid = output_0_axis_tvalid_reg; assign output_0_axis_tlast = output_0_axis_tlast_reg; +assign output_0_axis_tuser = output_0_axis_tuser_reg; assign output_1_axis_tdata = output_1_axis_tdata_reg; assign output_1_axis_tvalid = output_1_axis_tvalid_reg; assign output_1_axis_tlast = output_1_axis_tlast_reg; +assign output_1_axis_tuser = output_1_axis_tuser_reg; assign output_2_axis_tdata = output_2_axis_tdata_reg; assign output_2_axis_tvalid = output_2_axis_tvalid_reg; assign output_2_axis_tlast = output_2_axis_tlast_reg; +assign output_2_axis_tuser = output_2_axis_tuser_reg; assign output_3_axis_tdata = output_3_axis_tdata_reg; assign output_3_axis_tvalid = output_3_axis_tvalid_reg; assign output_3_axis_tlast = output_3_axis_tlast_reg; +assign output_3_axis_tuser = output_3_axis_tuser_reg; always @(posedge clk or posedge rst) begin @@ -145,39 +165,59 @@ always @(posedge clk or posedge rst) begin output_2_select_reg <= 0; output_3_select_reg <= 0; + input_0_axis_tdata_reg <= 0; input_0_axis_tvalid_reg <= 0; input_0_axis_tlast_reg <= 0; + input_0_axis_tuser_reg <= 0; + input_1_axis_tdata_reg <= 0; input_1_axis_tvalid_reg <= 0; input_1_axis_tlast_reg <= 0; + input_1_axis_tuser_reg <= 0; + input_2_axis_tdata_reg <= 0; input_2_axis_tvalid_reg <= 0; input_2_axis_tlast_reg <= 0; + input_2_axis_tuser_reg <= 0; + input_3_axis_tdata_reg <= 0; input_3_axis_tvalid_reg <= 0; input_3_axis_tlast_reg <= 0; + input_3_axis_tuser_reg <= 0; + output_0_axis_tdata_reg <= 0; output_0_axis_tvalid_reg <= 0; output_0_axis_tlast_reg <= 0; + output_0_axis_tuser_reg <= 0; + output_1_axis_tdata_reg <= 0; output_1_axis_tvalid_reg <= 0; output_1_axis_tlast_reg <= 0; + output_1_axis_tuser_reg <= 0; + output_2_axis_tdata_reg <= 0; output_2_axis_tvalid_reg <= 0; output_2_axis_tlast_reg <= 0; + output_2_axis_tuser_reg <= 0; + output_3_axis_tdata_reg <= 0; output_3_axis_tvalid_reg <= 0; output_3_axis_tlast_reg <= 0; + output_3_axis_tuser_reg <= 0; end else begin input_0_axis_tdata_reg <= input_0_axis_tdata; input_0_axis_tvalid_reg <= input_0_axis_tvalid; input_0_axis_tlast_reg <= input_0_axis_tlast; + input_0_axis_tuser_reg <= input_0_axis_tuser; input_1_axis_tdata_reg <= input_1_axis_tdata; input_1_axis_tvalid_reg <= input_1_axis_tvalid; input_1_axis_tlast_reg <= input_1_axis_tlast; + input_1_axis_tuser_reg <= input_1_axis_tuser; input_2_axis_tdata_reg <= input_2_axis_tdata; input_2_axis_tvalid_reg <= input_2_axis_tvalid; input_2_axis_tlast_reg <= input_2_axis_tlast; + input_2_axis_tuser_reg <= input_2_axis_tuser; input_3_axis_tdata_reg <= input_3_axis_tdata; input_3_axis_tvalid_reg <= input_3_axis_tvalid; input_3_axis_tlast_reg <= input_3_axis_tlast; + input_3_axis_tuser_reg <= input_3_axis_tuser; output_0_select_reg <= output_0_select; output_1_select_reg <= output_1_select; @@ -189,21 +229,25 @@ always @(posedge clk or posedge rst) begin output_0_axis_tdata_reg <= input_0_axis_tdata_reg; output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; output_0_axis_tlast_reg <= input_0_axis_tlast_reg; + output_0_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_0_axis_tdata_reg <= input_1_axis_tdata_reg; output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; output_0_axis_tlast_reg <= input_1_axis_tlast_reg; + output_0_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_0_axis_tdata_reg <= input_2_axis_tdata_reg; output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; output_0_axis_tlast_reg <= input_2_axis_tlast_reg; + output_0_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_0_axis_tdata_reg <= input_3_axis_tdata_reg; output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; output_0_axis_tlast_reg <= input_3_axis_tlast_reg; + output_0_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase @@ -212,21 +256,25 @@ always @(posedge clk or posedge rst) begin output_1_axis_tdata_reg <= input_0_axis_tdata_reg; output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; output_1_axis_tlast_reg <= input_0_axis_tlast_reg; + output_1_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_1_axis_tdata_reg <= input_1_axis_tdata_reg; output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; output_1_axis_tlast_reg <= input_1_axis_tlast_reg; + output_1_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_1_axis_tdata_reg <= input_2_axis_tdata_reg; output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; output_1_axis_tlast_reg <= input_2_axis_tlast_reg; + output_1_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_1_axis_tdata_reg <= input_3_axis_tdata_reg; output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; output_1_axis_tlast_reg <= input_3_axis_tlast_reg; + output_1_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase @@ -235,21 +283,25 @@ always @(posedge clk or posedge rst) begin output_2_axis_tdata_reg <= input_0_axis_tdata_reg; output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; output_2_axis_tlast_reg <= input_0_axis_tlast_reg; + output_2_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_2_axis_tdata_reg <= input_1_axis_tdata_reg; output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; output_2_axis_tlast_reg <= input_1_axis_tlast_reg; + output_2_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_2_axis_tdata_reg <= input_2_axis_tdata_reg; output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; output_2_axis_tlast_reg <= input_2_axis_tlast_reg; + output_2_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_2_axis_tdata_reg <= input_3_axis_tdata_reg; output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; output_2_axis_tlast_reg <= input_3_axis_tlast_reg; + output_2_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase @@ -258,21 +310,25 @@ always @(posedge clk or posedge rst) begin output_3_axis_tdata_reg <= input_0_axis_tdata_reg; output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; output_3_axis_tlast_reg <= input_0_axis_tlast_reg; + output_3_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_3_axis_tdata_reg <= input_1_axis_tdata_reg; output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; output_3_axis_tlast_reg <= input_1_axis_tlast_reg; + output_3_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_3_axis_tdata_reg <= input_2_axis_tdata_reg; output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; output_3_axis_tlast_reg <= input_2_axis_tlast_reg; + output_3_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_3_axis_tdata_reg <= input_3_axis_tdata_reg; output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; output_3_axis_tlast_reg <= input_3_axis_tlast_reg; + output_3_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase end diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index c666299a4..12dbe8ae5 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -116,6 +116,7 @@ module {{name}} # input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, input wire input_{{p}}_axis_tvalid, input wire input_{{p}}_axis_tlast, + input wire input_{{p}}_axis_tuser, {% endfor %} /* * AXI Stream outputs @@ -125,6 +126,7 @@ module {{name}} # output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, output wire output_{{p}}_axis_tvalid, output wire output_{{p}}_axis_tlast, + output wire output_{{p}}_axis_tuser, {% endfor %} /* * Control @@ -138,6 +140,7 @@ reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep_reg = 0; reg input_{{p}}_axis_tvalid_reg = 0; reg input_{{p}}_axis_tlast_reg = 0; +reg input_{{p}}_axis_tuser_reg = 0; {% endfor %} {%- for p in ports %} @@ -145,6 +148,7 @@ reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = 0; reg output_{{p}}_axis_tvalid_reg = 0; reg output_{{p}}_axis_tlast_reg = 0; +reg output_{{p}}_axis_tuser_reg = 0; {% endfor %} {%- for p in ports %} @@ -155,6 +159,7 @@ assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; assign output_{{p}}_axis_tkeep = output_{{p}}_axis_tkeep_reg; assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; +assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; {% endfor %} always @(posedge clk or posedge rst) begin @@ -163,12 +168,18 @@ always @(posedge clk or posedge rst) begin output_{{p}}_select_reg <= 0; {%- endfor %} {% for p in ports %} + input_{{p}}_axis_tdata_reg <= 0; + input_{{p}}_axis_tkeep_reg <= 0; input_{{p}}_axis_tvalid_reg <= 0; input_{{p}}_axis_tlast_reg <= 0; + input_{{p}}_axis_tuser_reg <= 0; {%- endfor %} {% for p in ports %} + output_{{p}}_axis_tdata_reg <= 0; + output_{{p}}_axis_tkeep_reg <= 0; output_{{p}}_axis_tvalid_reg <= 0; output_{{p}}_axis_tlast_reg <= 0; + output_{{p}}_axis_tuser_reg <= 0; {%- endfor %} end else begin {%- for p in ports %} @@ -176,6 +187,7 @@ always @(posedge clk or posedge rst) begin input_{{p}}_axis_tkeep_reg <= input_{{p}}_axis_tkeep; input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; + input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; {% endfor %} {%- for p in ports %} output_{{p}}_select_reg <= output_{{p}}_select; @@ -189,6 +201,7 @@ always @(posedge clk or posedge rst) begin output_{{p}}_axis_tkeep_reg <= input_{{q}}_axis_tkeep_reg; output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; + output_{{p}}_axis_tuser_reg <= input_{{q}}_axis_tuser_reg; end {%- endfor %} endcase diff --git a/rtl/axis_crosspoint_64_4x4.v b/rtl/axis_crosspoint_64_4x4.v index 08c41ad54..edf12f892 100644 --- a/rtl/axis_crosspoint_64_4x4.v +++ b/rtl/axis_crosspoint_64_4x4.v @@ -45,21 +45,25 @@ module axis_crosspoint_64_4x4 # input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, input wire input_0_axis_tvalid, input wire input_0_axis_tlast, + input wire input_0_axis_tuser, input wire [DATA_WIDTH-1:0] input_1_axis_tdata, input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, input wire input_1_axis_tvalid, input wire input_1_axis_tlast, + input wire input_1_axis_tuser, input wire [DATA_WIDTH-1:0] input_2_axis_tdata, input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, input wire input_2_axis_tvalid, input wire input_2_axis_tlast, + input wire input_2_axis_tuser, input wire [DATA_WIDTH-1:0] input_3_axis_tdata, input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, input wire input_3_axis_tvalid, input wire input_3_axis_tlast, + input wire input_3_axis_tuser, /* * AXI Stream outputs @@ -68,21 +72,25 @@ module axis_crosspoint_64_4x4 # output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, output wire output_0_axis_tvalid, output wire output_0_axis_tlast, + output wire output_0_axis_tuser, output wire [DATA_WIDTH-1:0] output_1_axis_tdata, output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, output wire output_1_axis_tvalid, output wire output_1_axis_tlast, + output wire output_1_axis_tuser, output wire [DATA_WIDTH-1:0] output_2_axis_tdata, output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, output wire output_2_axis_tvalid, output wire output_2_axis_tlast, + output wire output_2_axis_tuser, output wire [DATA_WIDTH-1:0] output_3_axis_tdata, output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, output wire output_3_axis_tvalid, output wire output_3_axis_tlast, + output wire output_3_axis_tuser, /* * Control @@ -97,41 +105,49 @@ reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] input_0_axis_tkeep_reg = 0; reg input_0_axis_tvalid_reg = 0; reg input_0_axis_tlast_reg = 0; +reg input_0_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] input_1_axis_tkeep_reg = 0; reg input_1_axis_tvalid_reg = 0; reg input_1_axis_tlast_reg = 0; +reg input_1_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] input_2_axis_tkeep_reg = 0; reg input_2_axis_tvalid_reg = 0; reg input_2_axis_tlast_reg = 0; +reg input_2_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] input_3_axis_tkeep_reg = 0; reg input_3_axis_tvalid_reg = 0; reg input_3_axis_tlast_reg = 0; +reg input_3_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = 0; reg output_0_axis_tvalid_reg = 0; reg output_0_axis_tlast_reg = 0; +reg output_0_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = 0; reg output_1_axis_tvalid_reg = 0; reg output_1_axis_tlast_reg = 0; +reg output_1_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = 0; reg output_2_axis_tvalid_reg = 0; reg output_2_axis_tlast_reg = 0; +reg output_2_axis_tuser_reg = 0; reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = 0; reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = 0; reg output_3_axis_tvalid_reg = 0; reg output_3_axis_tlast_reg = 0; +reg output_3_axis_tuser_reg = 0; reg [1:0] output_0_select_reg = 0; reg [1:0] output_1_select_reg = 0; @@ -142,21 +158,25 @@ assign output_0_axis_tdata = output_0_axis_tdata_reg; assign output_0_axis_tkeep = output_0_axis_tkeep_reg; assign output_0_axis_tvalid = output_0_axis_tvalid_reg; assign output_0_axis_tlast = output_0_axis_tlast_reg; +assign output_0_axis_tuser = output_0_axis_tuser_reg; assign output_1_axis_tdata = output_1_axis_tdata_reg; assign output_1_axis_tkeep = output_1_axis_tkeep_reg; assign output_1_axis_tvalid = output_1_axis_tvalid_reg; assign output_1_axis_tlast = output_1_axis_tlast_reg; +assign output_1_axis_tuser = output_1_axis_tuser_reg; assign output_2_axis_tdata = output_2_axis_tdata_reg; assign output_2_axis_tkeep = output_2_axis_tkeep_reg; assign output_2_axis_tvalid = output_2_axis_tvalid_reg; assign output_2_axis_tlast = output_2_axis_tlast_reg; +assign output_2_axis_tuser = output_2_axis_tuser_reg; assign output_3_axis_tdata = output_3_axis_tdata_reg; assign output_3_axis_tkeep = output_3_axis_tkeep_reg; assign output_3_axis_tvalid = output_3_axis_tvalid_reg; assign output_3_axis_tlast = output_3_axis_tlast_reg; +assign output_3_axis_tuser = output_3_axis_tuser_reg; always @(posedge clk or posedge rst) begin @@ -166,43 +186,71 @@ always @(posedge clk or posedge rst) begin output_2_select_reg <= 0; output_3_select_reg <= 0; + input_0_axis_tdata_reg <= 0; + input_0_axis_tkeep_reg <= 0; input_0_axis_tvalid_reg <= 0; input_0_axis_tlast_reg <= 0; + input_0_axis_tuser_reg <= 0; + input_1_axis_tdata_reg <= 0; + input_1_axis_tkeep_reg <= 0; input_1_axis_tvalid_reg <= 0; input_1_axis_tlast_reg <= 0; + input_1_axis_tuser_reg <= 0; + input_2_axis_tdata_reg <= 0; + input_2_axis_tkeep_reg <= 0; input_2_axis_tvalid_reg <= 0; input_2_axis_tlast_reg <= 0; + input_2_axis_tuser_reg <= 0; + input_3_axis_tdata_reg <= 0; + input_3_axis_tkeep_reg <= 0; input_3_axis_tvalid_reg <= 0; input_3_axis_tlast_reg <= 0; + input_3_axis_tuser_reg <= 0; + output_0_axis_tdata_reg <= 0; + output_0_axis_tkeep_reg <= 0; output_0_axis_tvalid_reg <= 0; output_0_axis_tlast_reg <= 0; + output_0_axis_tuser_reg <= 0; + output_1_axis_tdata_reg <= 0; + output_1_axis_tkeep_reg <= 0; output_1_axis_tvalid_reg <= 0; output_1_axis_tlast_reg <= 0; + output_1_axis_tuser_reg <= 0; + output_2_axis_tdata_reg <= 0; + output_2_axis_tkeep_reg <= 0; output_2_axis_tvalid_reg <= 0; output_2_axis_tlast_reg <= 0; + output_2_axis_tuser_reg <= 0; + output_3_axis_tdata_reg <= 0; + output_3_axis_tkeep_reg <= 0; output_3_axis_tvalid_reg <= 0; output_3_axis_tlast_reg <= 0; + output_3_axis_tuser_reg <= 0; end else begin input_0_axis_tdata_reg <= input_0_axis_tdata; input_0_axis_tkeep_reg <= input_0_axis_tkeep; input_0_axis_tvalid_reg <= input_0_axis_tvalid; input_0_axis_tlast_reg <= input_0_axis_tlast; + input_0_axis_tuser_reg <= input_0_axis_tuser; input_1_axis_tdata_reg <= input_1_axis_tdata; input_1_axis_tkeep_reg <= input_1_axis_tkeep; input_1_axis_tvalid_reg <= input_1_axis_tvalid; input_1_axis_tlast_reg <= input_1_axis_tlast; + input_1_axis_tuser_reg <= input_1_axis_tuser; input_2_axis_tdata_reg <= input_2_axis_tdata; input_2_axis_tkeep_reg <= input_2_axis_tkeep; input_2_axis_tvalid_reg <= input_2_axis_tvalid; input_2_axis_tlast_reg <= input_2_axis_tlast; + input_2_axis_tuser_reg <= input_2_axis_tuser; input_3_axis_tdata_reg <= input_3_axis_tdata; input_3_axis_tkeep_reg <= input_3_axis_tkeep; input_3_axis_tvalid_reg <= input_3_axis_tvalid; input_3_axis_tlast_reg <= input_3_axis_tlast; + input_3_axis_tuser_reg <= input_3_axis_tuser; output_0_select_reg <= output_0_select; output_1_select_reg <= output_1_select; @@ -215,24 +263,28 @@ always @(posedge clk or posedge rst) begin output_0_axis_tkeep_reg <= input_0_axis_tkeep_reg; output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; output_0_axis_tlast_reg <= input_0_axis_tlast_reg; + output_0_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_0_axis_tdata_reg <= input_1_axis_tdata_reg; output_0_axis_tkeep_reg <= input_1_axis_tkeep_reg; output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; output_0_axis_tlast_reg <= input_1_axis_tlast_reg; + output_0_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_0_axis_tdata_reg <= input_2_axis_tdata_reg; output_0_axis_tkeep_reg <= input_2_axis_tkeep_reg; output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; output_0_axis_tlast_reg <= input_2_axis_tlast_reg; + output_0_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_0_axis_tdata_reg <= input_3_axis_tdata_reg; output_0_axis_tkeep_reg <= input_3_axis_tkeep_reg; output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; output_0_axis_tlast_reg <= input_3_axis_tlast_reg; + output_0_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase @@ -242,24 +294,28 @@ always @(posedge clk or posedge rst) begin output_1_axis_tkeep_reg <= input_0_axis_tkeep_reg; output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; output_1_axis_tlast_reg <= input_0_axis_tlast_reg; + output_1_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_1_axis_tdata_reg <= input_1_axis_tdata_reg; output_1_axis_tkeep_reg <= input_1_axis_tkeep_reg; output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; output_1_axis_tlast_reg <= input_1_axis_tlast_reg; + output_1_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_1_axis_tdata_reg <= input_2_axis_tdata_reg; output_1_axis_tkeep_reg <= input_2_axis_tkeep_reg; output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; output_1_axis_tlast_reg <= input_2_axis_tlast_reg; + output_1_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_1_axis_tdata_reg <= input_3_axis_tdata_reg; output_1_axis_tkeep_reg <= input_3_axis_tkeep_reg; output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; output_1_axis_tlast_reg <= input_3_axis_tlast_reg; + output_1_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase @@ -269,24 +325,28 @@ always @(posedge clk or posedge rst) begin output_2_axis_tkeep_reg <= input_0_axis_tkeep_reg; output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; output_2_axis_tlast_reg <= input_0_axis_tlast_reg; + output_2_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_2_axis_tdata_reg <= input_1_axis_tdata_reg; output_2_axis_tkeep_reg <= input_1_axis_tkeep_reg; output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; output_2_axis_tlast_reg <= input_1_axis_tlast_reg; + output_2_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_2_axis_tdata_reg <= input_2_axis_tdata_reg; output_2_axis_tkeep_reg <= input_2_axis_tkeep_reg; output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; output_2_axis_tlast_reg <= input_2_axis_tlast_reg; + output_2_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_2_axis_tdata_reg <= input_3_axis_tdata_reg; output_2_axis_tkeep_reg <= input_3_axis_tkeep_reg; output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; output_2_axis_tlast_reg <= input_3_axis_tlast_reg; + output_2_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase @@ -296,24 +356,28 @@ always @(posedge clk or posedge rst) begin output_3_axis_tkeep_reg <= input_0_axis_tkeep_reg; output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; output_3_axis_tlast_reg <= input_0_axis_tlast_reg; + output_3_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_3_axis_tdata_reg <= input_1_axis_tdata_reg; output_3_axis_tkeep_reg <= input_1_axis_tkeep_reg; output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; output_3_axis_tlast_reg <= input_1_axis_tlast_reg; + output_3_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_3_axis_tdata_reg <= input_2_axis_tdata_reg; output_3_axis_tkeep_reg <= input_2_axis_tkeep_reg; output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; output_3_axis_tlast_reg <= input_2_axis_tlast_reg; + output_3_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_3_axis_tdata_reg <= input_3_axis_tdata_reg; output_3_axis_tkeep_reg <= input_3_axis_tkeep_reg; output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; output_3_axis_tlast_reg <= input_3_axis_tlast_reg; + output_3_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase end From fbcbbe3a69f899c18a8c4fd95b8f8f6d8fea5e4b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 21 Nov 2014 10:43:20 -0800 Subject: [PATCH 130/617] Remove adder tree --- rtl/axis_stat_counter.v | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index 64a10d279..a99834262 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -220,8 +220,9 @@ always @* begin // increment byte count by number of words transferred bit_cnt = 0; - for (i = 0; i < KEEP_WIDTH; i = i + 1) begin - bit_cnt = bit_cnt + monitor_axis_tkeep[i]; + for (i = 0; i <= KEEP_WIDTH; i = i + 1) begin + //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; + if (monitor_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) bit_cnt = i; end byte_count_next = byte_count_next + bit_cnt; From b83dd341850c9e803f0d39fbd9e77bb3cfe245cc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 3 Dec 2014 13:15:13 -0800 Subject: [PATCH 131/617] Fix register names --- rtl/axis_stat_counter.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index a99834262..94fd8e06f 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -147,11 +147,11 @@ always @* begin if (TAG_ENABLE) begin output_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; end else if (TICK_COUNT_ENABLE) begin - output_axis_tdata_int = tag[(TICK_COUNT_BYTE_WIDTH-1)*8 +: 8]; + output_axis_tdata_int = tick_count_reg[(TICK_COUNT_BYTE_WIDTH-1)*8 +: 8]; end else if (BYTE_COUNT_ENABLE) begin - output_axis_tdata_int = tag[(BYTE_COUNT_BYTE_WIDTH-1)*8 +: 8]; + output_axis_tdata_int = byte_count_reg[(BYTE_COUNT_BYTE_WIDTH-1)*8 +: 8]; end else if (FRAME_COUNT_ENABLE) begin - output_axis_tdata_int = tag[(FRAME_COUNT_BYTE_WIDTH-1)*8 +: 8]; + output_axis_tdata_int = frame_count_reg[(FRAME_COUNT_BYTE_WIDTH-1)*8 +: 8]; end output_axis_tvalid_int = 1; end From 385e358c08dbca00b91794127480c60fc47c960e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 3 Dec 2014 18:02:53 -0800 Subject: [PATCH 132/617] Use non-broken myhdl --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b6a9c62c8..4dcbbcf7b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ before_install: - export d=`pwd` - sudo apt-get update -qq - 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/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/ivl/myhdl.vpi - cd $d From 10fd51f19267aee4d5102e443c8c967e305105be Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 3 Dec 2014 18:49:33 -0800 Subject: [PATCH 133/617] Add SRL FIFO module and testbench --- rtl/axis_srl_fifo.v | 140 ++++++++++++ rtl/axis_srl_fifo_64.v | 143 +++++++++++++ tb/test_axis_srl_fifo.py | 404 +++++++++++++++++++++++++++++++++++ tb/test_axis_srl_fifo.v | 96 +++++++++ tb/test_axis_srl_fifo_64.py | 414 ++++++++++++++++++++++++++++++++++++ tb/test_axis_srl_fifo_64.v | 102 +++++++++ 6 files changed, 1299 insertions(+) create mode 100644 rtl/axis_srl_fifo.v create mode 100644 rtl/axis_srl_fifo_64.v create mode 100755 tb/test_axis_srl_fifo.py create mode 100644 tb/test_axis_srl_fifo.v create mode 100755 tb/test_axis_srl_fifo_64.py create mode 100644 tb/test_axis_srl_fifo_64.v diff --git a/rtl/axis_srl_fifo.v b/rtl/axis_srl_fifo.v new file mode 100644 index 000000000..2e8075238 --- /dev/null +++ b/rtl/axis_srl_fifo.v @@ -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 diff --git a/rtl/axis_srl_fifo_64.v b/rtl/axis_srl_fifo_64.v new file mode 100644 index 000000000..3f176f54a --- /dev/null +++ b/rtl/axis_srl_fifo_64.v @@ -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 diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py new file mode 100755 index 000000000..d47d7c930 --- /dev/null +++ b/tb/test_axis_srl_fifo.py @@ -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() + diff --git a/tb/test_axis_srl_fifo.v b/tb/test_axis_srl_fifo.v new file mode 100644 index 000000000..596ba10b5 --- /dev/null +++ b/tb/test_axis_srl_fifo.v @@ -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 diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py new file mode 100755 index 000000000..a83befed4 --- /dev/null +++ b/tb/test_axis_srl_fifo_64.py @@ -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() + diff --git a/tb/test_axis_srl_fifo_64.v b/tb/test_axis_srl_fifo_64.v new file mode 100644 index 000000000..e435176e8 --- /dev/null +++ b/tb/test_axis_srl_fifo_64.v @@ -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 From 3c7e3b04245a309310b09e1664f94c6cd26070b4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 3 Dec 2014 18:51:46 -0800 Subject: [PATCH 134/617] Add SRL register module and testbench --- rtl/axis_srl_register.v | 101 ++++++++ rtl/axis_srl_register_64.v | 104 ++++++++ tb/test_axis_srl_register.py | 396 +++++++++++++++++++++++++++++++ tb/test_axis_srl_register.v | 90 +++++++ tb/test_axis_srl_register_64.py | 406 ++++++++++++++++++++++++++++++++ tb/test_axis_srl_register_64.v | 96 ++++++++ 6 files changed, 1193 insertions(+) create mode 100644 rtl/axis_srl_register.v create mode 100644 rtl/axis_srl_register_64.v create mode 100755 tb/test_axis_srl_register.py create mode 100644 tb/test_axis_srl_register.v create mode 100755 tb/test_axis_srl_register_64.py create mode 100644 tb/test_axis_srl_register_64.v diff --git a/rtl/axis_srl_register.v b/rtl/axis_srl_register.v new file mode 100644 index 000000000..52666e5c3 --- /dev/null +++ b/rtl/axis_srl_register.v @@ -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 diff --git a/rtl/axis_srl_register_64.v b/rtl/axis_srl_register_64.v new file mode 100644 index 000000000..28ff084d8 --- /dev/null +++ b/rtl/axis_srl_register_64.v @@ -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 diff --git a/tb/test_axis_srl_register.py b/tb/test_axis_srl_register.py new file mode 100755 index 000000000..342f34ed1 --- /dev/null +++ b/tb/test_axis_srl_register.py @@ -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() + diff --git a/tb/test_axis_srl_register.v b/tb/test_axis_srl_register.v new file mode 100644 index 000000000..dccb5ff43 --- /dev/null +++ b/tb/test_axis_srl_register.v @@ -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 diff --git a/tb/test_axis_srl_register_64.py b/tb/test_axis_srl_register_64.py new file mode 100755 index 000000000..cee95378e --- /dev/null +++ b/tb/test_axis_srl_register_64.py @@ -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() + diff --git a/tb/test_axis_srl_register_64.v b/tb/test_axis_srl_register_64.v new file mode 100644 index 000000000..1df9036da --- /dev/null +++ b/tb/test_axis_srl_register_64.v @@ -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 From 8582ab07497312858b865ee8b414e9aaa72d9919 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 3 Dec 2014 19:00:12 -0800 Subject: [PATCH 135/617] Update readme --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 182e346da..fac23527b 100644 --- a/README.md +++ b/README.md @@ -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. +### 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 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_register.v : AXI Stream register 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/ll_axis_bridge.v : LocalLink to AXI stream bridge rtl/priority_encoder.v : Parametrizable priority encoder From f3ea7cd8acb093f017aa16ee12a25574becf0f35 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 24 Feb 2015 20:26:24 -0800 Subject: [PATCH 136/617] Add FCS field to eth_ep --- tb/eth_ep.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/tb/eth_ep.py b/tb/eth_ep.py index 4fd9fcdba..0a50edc22 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -26,19 +26,22 @@ from myhdl import * import axis_ep from Queue import Queue import struct +import zlib class EthFrame(object): - def __init__(self, payload=b'', eth_dest_mac=0, eth_src_mac=0, eth_type=0): + def __init__(self, payload=b'', eth_dest_mac=0, eth_src_mac=0, eth_type=0, eth_fcs=None): self._payload = axis_ep.AXIStreamFrame() self.eth_dest_mac = eth_dest_mac self.eth_src_mac = eth_src_mac self.eth_type = eth_type + self.eth_fcs = eth_fcs if type(payload) is dict: self.payload = axis_ep.AXIStreamFrame(payload['eth_payload']) self.eth_dest_mac = payload['eth_dest_mac'] self.eth_src_mac = payload['eth_src_mac'] self.eth_type = payload['eth_type'] + self.eth_fcs = payload['eth_fcs'] if type(payload) is bytes: payload = bytearray(payload) if type(payload) is bytearray or type(payload) is axis_ep.AXIStreamFrame: @@ -48,6 +51,7 @@ class EthFrame(object): self.eth_dest_mac = payload.eth_dest_mac self.eth_src_mac = payload.eth_src_mac self.eth_type = payload.eth_type + self.eth_fcs = payload.eth_fcs @property def payload(self): @@ -57,6 +61,14 @@ class EthFrame(object): def payload(self, value): self._payload = axis_ep.AXIStreamFrame(value) + def calc_fcs(self): + frame = self.build_axis().data + + return zlib.crc32(bytes(frame)) & 0xffffffff + + def update_fcs(self): + self.eth_fcs = self.calc_fcs() + def build_axis(self): data = b'' @@ -68,6 +80,16 @@ class EthFrame(object): return axis_ep.AXIStreamFrame(data) + def build_axis_fcs(self): + if self.eth_fcs is None: + self.update_fcs() + + data = self.build_axis().data + + data += struct.pack('Q', '\x00\x00'+data[0:6])[0] @@ -76,6 +98,12 @@ class EthFrame(object): data = data[14:] self.payload = axis_ep.AXIStreamFrame(data) + def parse_axis_fcs(self, data): + self.parse_axis(data) + data = self.payload.data + self.payload = axis_ep.AXIStreamFrame(data[:-4]) + self.eth_fcs = struct.unpack(' Date: Wed, 25 Feb 2015 14:40:26 -0800 Subject: [PATCH 137/617] Add Ethernet CRC modules --- rtl/eth_crc_16.v | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ rtl/eth_crc_24.v | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ rtl/eth_crc_32.v | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ rtl/eth_crc_40.v | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ rtl/eth_crc_48.v | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ rtl/eth_crc_56.v | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ rtl/eth_crc_64.v | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ rtl/eth_crc_8.v | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 680 insertions(+) create mode 100644 rtl/eth_crc_16.v create mode 100644 rtl/eth_crc_24.v create mode 100644 rtl/eth_crc_32.v create mode 100644 rtl/eth_crc_40.v create mode 100644 rtl/eth_crc_48.v create mode 100644 rtl/eth_crc_56.v create mode 100644 rtl/eth_crc_64.v create mode 100644 rtl/eth_crc_8.v diff --git a/rtl/eth_crc_16.v b/rtl/eth_crc_16.v new file mode 100644 index 000000000..a06b69c3d --- /dev/null +++ b/rtl/eth_crc_16.v @@ -0,0 +1,85 @@ +/* + +Copyright (c) 2014-2015 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 + +/* + * CRC module eth_crc_16 + * + * CRC width: 32 + * Data width: 16 + * CRC polynomial: 32'h4c11db7 + * Configuration: galois + * Bit-reverse: input and output + * + * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + * + * Generated by crcgen.py + * + * crcgen.py -b -r -d 16 -n eth_crc_16 + * + */ +module eth_crc_16 +( + input wire [15:0] data_in, + input wire [31:0] crc_state, + output wire [31:0] crc_next +); + +assign crc_next[0] = crc_state[0] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[16] ^ data_in[0] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[10]; +assign crc_next[1] = crc_state[1] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[17] ^ data_in[1] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[11]; +assign crc_next[2] = crc_state[2] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[12] ^ crc_state[18] ^ data_in[2] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[12]; +assign crc_next[3] = crc_state[3] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[13] ^ crc_state[19] ^ data_in[3] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[13]; +assign crc_next[4] = crc_state[4] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[20] ^ data_in[4] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[14]; +assign crc_next[5] = crc_state[5] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[21] ^ data_in[5] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[15]; +assign crc_next[6] = crc_state[0] ^ crc_state[4] ^ crc_state[7] ^ crc_state[12] ^ crc_state[13] ^ crc_state[22] ^ data_in[0] ^ data_in[4] ^ data_in[7] ^ data_in[12] ^ data_in[13]; +assign crc_next[7] = crc_state[1] ^ crc_state[5] ^ crc_state[8] ^ crc_state[13] ^ crc_state[14] ^ crc_state[23] ^ data_in[1] ^ data_in[5] ^ data_in[8] ^ data_in[13] ^ data_in[14]; +assign crc_next[8] = crc_state[0] ^ crc_state[2] ^ crc_state[6] ^ crc_state[9] ^ crc_state[14] ^ crc_state[15] ^ crc_state[24] ^ data_in[0] ^ data_in[2] ^ data_in[6] ^ data_in[9] ^ data_in[14] ^ data_in[15]; +assign crc_next[9] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[15] ^ crc_state[25] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[15]; +assign crc_next[10] = crc_state[2] ^ crc_state[5] ^ crc_state[6] ^ crc_state[10] ^ crc_state[26] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[10]; +assign crc_next[11] = crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[27] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[11]; +assign crc_next[12] = crc_state[0] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[28] ^ data_in[0] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[12]; +assign crc_next[13] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[13]; +assign crc_next[14] = crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[14]; +assign crc_next[15] = crc_state[2] ^ crc_state[3] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[15] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[15]; +assign crc_next[16] = crc_state[0] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ data_in[0] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12]; +assign crc_next[17] = crc_state[0] ^ crc_state[1] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ data_in[0] ^ data_in[1] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13]; +assign crc_next[18] = crc_state[1] ^ crc_state[2] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ data_in[1] ^ data_in[2] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14]; +assign crc_next[19] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[15]; +assign crc_next[20] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[6] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[6] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15]; +assign crc_next[21] = crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15]; +assign crc_next[22] = crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14]; +assign crc_next[23] = crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15]; +assign crc_next[24] = crc_state[0] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ data_in[0] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15]; +assign crc_next[25] = crc_state[1] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ data_in[1] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14]; +assign crc_next[26] = crc_state[2] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ data_in[2] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15]; +assign crc_next[27] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15]; +assign crc_next[28] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[13] ^ data_in[14]; +assign crc_next[29] = crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[14] ^ data_in[15]; +assign crc_next[30] = crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[14] ^ crc_state[15] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[14] ^ data_in[15]; +assign crc_next[31] = crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[9] ^ crc_state[15] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[15]; + +endmodule diff --git a/rtl/eth_crc_24.v b/rtl/eth_crc_24.v new file mode 100644 index 000000000..0b75df7bc --- /dev/null +++ b/rtl/eth_crc_24.v @@ -0,0 +1,85 @@ +/* + +Copyright (c) 2014-2015 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 + +/* + * CRC module eth_crc_24 + * + * CRC width: 32 + * Data width: 24 + * CRC polynomial: 32'h4c11db7 + * Configuration: galois + * Bit-reverse: input and output + * + * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + * + * Generated by crcgen.py + * + * crcgen.py -b -r -d 24 -n eth_crc_24 + * + */ +module eth_crc_24 +( + input wire [23:0] data_in, + input wire [31:0] crc_state, + output wire [31:0] crc_next +); + +assign crc_next[0] = crc_state[0] ^ crc_state[8] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[24] ^ data_in[0] ^ data_in[8] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[18]; +assign crc_next[1] = crc_state[0] ^ crc_state[1] ^ crc_state[9] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[25] ^ data_in[0] ^ data_in[1] ^ data_in[9] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[19]; +assign crc_next[2] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[10] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[20] ^ crc_state[26] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[10] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[20]; +assign crc_next[3] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[11] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[21] ^ crc_state[27] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[11] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[21]; +assign crc_next[4] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[12] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[28] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[12] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[22]; +assign crc_next[5] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[13] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[23] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[13] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[23]; +assign crc_next[6] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[12] ^ crc_state[15] ^ crc_state[20] ^ crc_state[21] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[12] ^ data_in[15] ^ data_in[20] ^ data_in[21]; +assign crc_next[7] = crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[13] ^ crc_state[16] ^ crc_state[21] ^ crc_state[22] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[13] ^ data_in[16] ^ data_in[21] ^ data_in[22]; +assign crc_next[8] = crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[14] ^ crc_state[17] ^ crc_state[22] ^ crc_state[23] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[14] ^ data_in[17] ^ data_in[22] ^ data_in[23]; +assign crc_next[9] = crc_state[0] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[23] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[23]; +assign crc_next[10] = crc_state[1] ^ crc_state[5] ^ crc_state[6] ^ crc_state[10] ^ crc_state[13] ^ crc_state[14] ^ crc_state[18] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[10] ^ data_in[13] ^ data_in[14] ^ data_in[18]; +assign crc_next[11] = crc_state[0] ^ crc_state[2] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ data_in[0] ^ data_in[2] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[19]; +assign crc_next[12] = crc_state[1] ^ crc_state[3] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ data_in[1] ^ data_in[3] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[20]; +assign crc_next[13] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[21]; +assign crc_next[14] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[5] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[17] ^ data_in[18] ^ data_in[22]; +assign crc_next[15] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[6] ^ crc_state[10] ^ crc_state[11] ^ crc_state[15] ^ crc_state[18] ^ crc_state[19] ^ crc_state[23] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[6] ^ data_in[10] ^ data_in[11] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[23]; +assign crc_next[16] = crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20]; +assign crc_next[17] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21]; +assign crc_next[18] = crc_state[1] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[13] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22]; +assign crc_next[19] = crc_state[2] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[23]; +assign crc_next[20] = crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[14] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[14] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23]; +assign crc_next[21] = crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23]; +assign crc_next[22] = crc_state[0] ^ crc_state[5] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ data_in[0] ^ data_in[5] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22]; +assign crc_next[23] = crc_state[0] ^ crc_state[1] ^ crc_state[6] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ data_in[0] ^ data_in[1] ^ data_in[6] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23]; +assign crc_next[24] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[7] ^ crc_state[8] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[7] ^ data_in[8] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23]; +assign crc_next[25] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[9] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[9] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22]; +assign crc_next[26] = crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[10] ^ crc_state[13] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[10] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23]; +assign crc_next[27] = crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[23]; +assign crc_next[28] = crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[21] ^ data_in[22]; +assign crc_next[29] = crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[22] ^ data_in[23]; +assign crc_next[30] = crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[22] ^ crc_state[23] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[22] ^ data_in[23]; +assign crc_next[31] = crc_state[7] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[17] ^ crc_state[23] ^ data_in[7] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[17] ^ data_in[23]; + +endmodule diff --git a/rtl/eth_crc_32.v b/rtl/eth_crc_32.v new file mode 100644 index 000000000..690560c73 --- /dev/null +++ b/rtl/eth_crc_32.v @@ -0,0 +1,85 @@ +/* + +Copyright (c) 2014-2015 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 + +/* + * CRC module eth_crc_32 + * + * CRC width: 32 + * Data width: 32 + * CRC polynomial: 32'h4c11db7 + * Configuration: galois + * Bit-reverse: input and output + * + * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + * + * Generated by crcgen.py + * + * crcgen.py -b -r -d 32 -n eth_crc_32 + * + */ +module eth_crc_32 +( + input wire [31:0] data_in, + input wire [31:0] crc_state, + output wire [31:0] crc_next +); + +assign crc_next[0] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[16] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[26] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[16] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[26]; +assign crc_next[1] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[17] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[17] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[27]; +assign crc_next[2] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[18] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[28] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[18] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[28]; +assign crc_next[3] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[19] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[29] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[19] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[29]; +assign crc_next[4] = crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[20] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[30] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[20] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[30]; +assign crc_next[5] = crc_state[0] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[21] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[21] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[31]; +assign crc_next[6] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[20] ^ crc_state[23] ^ crc_state[28] ^ crc_state[29] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[20] ^ data_in[23] ^ data_in[28] ^ data_in[29]; +assign crc_next[7] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[21] ^ crc_state[24] ^ crc_state[29] ^ crc_state[30] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[21] ^ data_in[24] ^ data_in[29] ^ data_in[30]; +assign crc_next[8] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[22] ^ crc_state[25] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[22] ^ data_in[25] ^ data_in[30] ^ data_in[31]; +assign crc_next[9] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[31]; +assign crc_next[10] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[13] ^ crc_state[14] ^ crc_state[18] ^ crc_state[21] ^ crc_state[22] ^ crc_state[26] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[13] ^ data_in[14] ^ data_in[18] ^ data_in[21] ^ data_in[22] ^ data_in[26]; +assign crc_next[11] = crc_state[1] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[10] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[27] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[27]; +assign crc_next[12] = crc_state[2] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[11] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[23] ^ crc_state[24] ^ crc_state[28] ^ data_in[2] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[11] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[28]; +assign crc_next[13] = crc_state[0] ^ crc_state[3] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[24] ^ crc_state[25] ^ crc_state[29] ^ data_in[0] ^ data_in[3] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[24] ^ data_in[25] ^ data_in[29]; +assign crc_next[14] = crc_state[0] ^ crc_state[1] ^ crc_state[4] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[13] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[4] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[13] ^ data_in[17] ^ data_in[18] ^ data_in[22] ^ data_in[25] ^ data_in[26] ^ data_in[30]; +assign crc_next[15] = crc_state[1] ^ crc_state[2] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[14] ^ crc_state[18] ^ crc_state[19] ^ crc_state[23] ^ crc_state[26] ^ crc_state[27] ^ crc_state[31] ^ data_in[1] ^ data_in[2] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[14] ^ data_in[18] ^ data_in[19] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[31]; +assign crc_next[16] = crc_state[1] ^ crc_state[4] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ data_in[1] ^ data_in[4] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[28]; +assign crc_next[17] = crc_state[2] ^ crc_state[5] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[20] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ data_in[2] ^ data_in[5] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29]; +assign crc_next[18] = crc_state[0] ^ crc_state[3] ^ crc_state[6] ^ crc_state[9] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[21] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[3] ^ data_in[6] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[21] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[30]; +assign crc_next[19] = crc_state[0] ^ crc_state[1] ^ crc_state[4] ^ crc_state[7] ^ crc_state[10] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[4] ^ data_in[7] ^ data_in[10] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[31]; +assign crc_next[20] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[22] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[22] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31]; +assign crc_next[21] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[22] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[31]; +assign crc_next[22] = crc_state[2] ^ crc_state[7] ^ crc_state[8] ^ crc_state[13] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ data_in[2] ^ data_in[7] ^ data_in[8] ^ data_in[13] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30]; +assign crc_next[23] = crc_state[0] ^ crc_state[3] ^ crc_state[8] ^ crc_state[9] ^ crc_state[14] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[8] ^ data_in[9] ^ data_in[14] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31]; +assign crc_next[24] = crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[15] ^ crc_state[16] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[15] ^ data_in[16] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[31]; +assign crc_next[25] = crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[17] ^ crc_state[20] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[17] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30]; +assign crc_next[26] = crc_state[2] ^ crc_state[3] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[18] ^ crc_state[21] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[18] ^ data_in[21] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31]; +assign crc_next[27] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[19] ^ crc_state[20] ^ crc_state[23] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[19] ^ data_in[20] ^ data_in[23] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[31]; +assign crc_next[28] = crc_state[0] ^ crc_state[4] ^ crc_state[6] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[4] ^ data_in[6] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[28] ^ data_in[29] ^ data_in[30]; +assign crc_next[29] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[7] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[7] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[29] ^ data_in[30] ^ data_in[31]; +assign crc_next[30] = crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[30] ^ crc_state[31] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[14] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[30] ^ data_in[31]; +assign crc_next[31] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[15] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[25] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[15] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[25] ^ data_in[31]; + +endmodule diff --git a/rtl/eth_crc_40.v b/rtl/eth_crc_40.v new file mode 100644 index 000000000..56145cfa6 --- /dev/null +++ b/rtl/eth_crc_40.v @@ -0,0 +1,85 @@ +/* + +Copyright (c) 2014-2015 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 + +/* + * CRC module eth_crc_40 + * + * CRC width: 32 + * Data width: 40 + * CRC polynomial: 32'h4c11db7 + * Configuration: galois + * Bit-reverse: input and output + * + * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + * + * Generated by crcgen.py + * + * crcgen.py -b -r -d 40 -n eth_crc_40 + * + */ +module eth_crc_40 +( + input wire [39:0] data_in, + input wire [31:0] crc_state, + output wire [31:0] crc_next +); + +assign crc_next[0] = crc_state[3] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[24] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[3] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[24] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[34]; +assign crc_next[1] = crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[25] ^ crc_state[29] ^ crc_state[31] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[25] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[35]; +assign crc_next[2] = crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[26] ^ crc_state[30] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[26] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[36]; +assign crc_next[3] = crc_state[6] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[27] ^ crc_state[31] ^ data_in[6] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[27] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[37]; +assign crc_next[4] = crc_state[0] ^ crc_state[7] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[28] ^ data_in[0] ^ data_in[7] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[28] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[38]; +assign crc_next[5] = crc_state[0] ^ crc_state[1] ^ crc_state[8] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[8] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[29] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[39]; +assign crc_next[6] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[28] ^ crc_state[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[28] ^ data_in[31] ^ data_in[36] ^ data_in[37]; +assign crc_next[7] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ crc_state[29] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[29] ^ data_in[32] ^ data_in[37] ^ data_in[38]; +assign crc_next[8] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[30] ^ data_in[33] ^ data_in[38] ^ data_in[39]; +assign crc_next[9] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[39]; +assign crc_next[10] = crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[17] ^ crc_state[21] ^ crc_state[22] ^ crc_state[26] ^ crc_state[29] ^ crc_state[30] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[21] ^ data_in[22] ^ data_in[26] ^ data_in[29] ^ data_in[30] ^ data_in[34]; +assign crc_next[11] = crc_state[0] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[9] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[18] ^ crc_state[22] ^ crc_state[23] ^ crc_state[27] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[18] ^ data_in[22] ^ data_in[23] ^ data_in[27] ^ data_in[30] ^ data_in[31] ^ data_in[35]; +assign crc_next[12] = crc_state[1] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[19] ^ crc_state[23] ^ crc_state[24] ^ crc_state[28] ^ crc_state[31] ^ data_in[1] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[19] ^ data_in[23] ^ data_in[24] ^ data_in[28] ^ data_in[31] ^ data_in[32] ^ data_in[36]; +assign crc_next[13] = crc_state[0] ^ crc_state[2] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[24] ^ crc_state[25] ^ crc_state[29] ^ data_in[0] ^ data_in[2] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[24] ^ data_in[25] ^ data_in[29] ^ data_in[32] ^ data_in[33] ^ data_in[37]; +assign crc_next[14] = crc_state[1] ^ crc_state[3] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[12] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[21] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ data_in[1] ^ data_in[3] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[12] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[21] ^ data_in[25] ^ data_in[26] ^ data_in[30] ^ data_in[33] ^ data_in[34] ^ data_in[38]; +assign crc_next[15] = crc_state[2] ^ crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[13] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[22] ^ crc_state[26] ^ crc_state[27] ^ crc_state[31] ^ data_in[2] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[22] ^ data_in[26] ^ data_in[27] ^ data_in[31] ^ data_in[34] ^ data_in[35] ^ data_in[39]; +assign crc_next[16] = crc_state[5] ^ crc_state[6] ^ crc_state[9] ^ crc_state[12] ^ crc_state[15] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ crc_state[30] ^ crc_state[31] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[12] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[36]; +assign crc_next[17] = crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[13] ^ crc_state[16] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[28] ^ crc_state[31] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[13] ^ data_in[16] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[28] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[37]; +assign crc_next[18] = crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[14] ^ crc_state[17] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[29] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[14] ^ data_in[17] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[29] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[38]; +assign crc_next[19] = crc_state[8] ^ crc_state[9] ^ crc_state[12] ^ crc_state[15] ^ crc_state[18] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[30] ^ data_in[8] ^ data_in[9] ^ data_in[12] ^ data_in[15] ^ data_in[18] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[30] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[39]; +assign crc_next[20] = crc_state[3] ^ crc_state[6] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[30] ^ data_in[3] ^ data_in[6] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[30] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[39]; +assign crc_next[21] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[20] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[20] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[30] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[39]; +assign crc_next[22] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[15] ^ crc_state[16] ^ crc_state[21] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[15] ^ data_in[16] ^ data_in[21] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[38]; +assign crc_next[23] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[16] ^ crc_state[17] ^ crc_state[22] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[16] ^ data_in[17] ^ data_in[22] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[39]; +assign crc_next[24] = crc_state[0] ^ crc_state[2] ^ crc_state[5] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[23] ^ crc_state[24] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[5] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[23] ^ data_in[24] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[39]; +assign crc_next[25] = crc_state[1] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[25] ^ crc_state[28] ^ crc_state[31] ^ data_in[1] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[25] ^ data_in[28] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[38]; +assign crc_next[26] = crc_state[0] ^ crc_state[2] ^ crc_state[10] ^ crc_state[11] ^ crc_state[15] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[26] ^ crc_state[29] ^ data_in[0] ^ data_in[2] ^ data_in[10] ^ data_in[11] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[26] ^ data_in[29] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[39]; +assign crc_next[27] = crc_state[0] ^ crc_state[1] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[24] ^ crc_state[27] ^ crc_state[28] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[24] ^ data_in[27] ^ data_in[28] ^ data_in[31] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[39]; +assign crc_next[28] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[14] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[14] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[36] ^ data_in[37] ^ data_in[38]; +assign crc_next[29] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[15] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[15] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[37] ^ data_in[38] ^ data_in[39]; +assign crc_next[30] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[22] ^ crc_state[23] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[22] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[38] ^ data_in[39]; +assign crc_next[31] = crc_state[2] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[23] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ data_in[2] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[23] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[33] ^ data_in[39]; + +endmodule diff --git a/rtl/eth_crc_48.v b/rtl/eth_crc_48.v new file mode 100644 index 000000000..e1ddbfe3d --- /dev/null +++ b/rtl/eth_crc_48.v @@ -0,0 +1,85 @@ +/* + +Copyright (c) 2014-2015 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 + +/* + * CRC module eth_crc_48 + * + * CRC width: 32 + * Data width: 48 + * CRC polynomial: 32'h4c11db7 + * Configuration: galois + * Bit-reverse: input and output + * + * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + * + * Generated by crcgen.py + * + * crcgen.py -b -r -d 48 -n eth_crc_48 + * + */ +module eth_crc_48 +( + input wire [47:0] data_in, + input wire [31:0] crc_state, + output wire [31:0] crc_next +); + +assign crc_next[0] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[11] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[11] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[32] ^ data_in[36] ^ data_in[38] ^ data_in[39] ^ data_in[42]; +assign crc_next[1] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[33] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[43]; +assign crc_next[2] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[34] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[44]; +assign crc_next[3] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[14] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[14] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[35] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[45]; +assign crc_next[4] = crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[15] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[15] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[36] ^ data_in[40] ^ data_in[42] ^ data_in[43] ^ data_in[46]; +assign crc_next[5] = crc_state[0] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[16] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ data_in[0] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[16] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[37] ^ data_in[41] ^ data_in[43] ^ data_in[44] ^ data_in[47]; +assign crc_next[6] = crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[25] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[32] ^ data_in[36] ^ data_in[39] ^ data_in[44] ^ data_in[45]; +assign crc_next[7] = crc_state[0] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[33] ^ data_in[37] ^ data_in[40] ^ data_in[45] ^ data_in[46]; +assign crc_next[8] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[38] ^ data_in[41] ^ data_in[46] ^ data_in[47]; +assign crc_next[9] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[47]; +assign crc_next[10] = crc_state[5] ^ crc_state[7] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[25] ^ crc_state[29] ^ crc_state[30] ^ data_in[5] ^ data_in[7] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^ data_in[29] ^ data_in[30] ^ data_in[34] ^ data_in[37] ^ data_in[38] ^ data_in[42]; +assign crc_next[11] = crc_state[6] ^ crc_state[8] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[17] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[26] ^ crc_state[30] ^ crc_state[31] ^ data_in[6] ^ data_in[8] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[17] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[26] ^ data_in[30] ^ data_in[31] ^ data_in[35] ^ data_in[38] ^ data_in[39] ^ data_in[43]; +assign crc_next[12] = crc_state[0] ^ crc_state[7] ^ crc_state[9] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ crc_state[27] ^ crc_state[31] ^ data_in[0] ^ data_in[7] ^ data_in[9] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[18] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[27] ^ data_in[31] ^ data_in[32] ^ data_in[36] ^ data_in[39] ^ data_in[40] ^ data_in[44]; +assign crc_next[13] = crc_state[1] ^ crc_state[8] ^ crc_state[10] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[28] ^ data_in[1] ^ data_in[8] ^ data_in[10] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[28] ^ data_in[32] ^ data_in[33] ^ data_in[37] ^ data_in[40] ^ data_in[41] ^ data_in[45]; +assign crc_next[14] = crc_state[0] ^ crc_state[2] ^ crc_state[9] ^ crc_state[11] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[20] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[29] ^ data_in[0] ^ data_in[2] ^ data_in[9] ^ data_in[11] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[20] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[29] ^ data_in[33] ^ data_in[34] ^ data_in[38] ^ data_in[41] ^ data_in[42] ^ data_in[46]; +assign crc_next[15] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[10] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[21] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[28] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[10] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[30] ^ data_in[34] ^ data_in[35] ^ data_in[39] ^ data_in[42] ^ data_in[43] ^ data_in[47]; +assign crc_next[16] = crc_state[2] ^ crc_state[3] ^ crc_state[13] ^ crc_state[14] ^ crc_state[17] ^ crc_state[20] ^ crc_state[23] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[13] ^ data_in[14] ^ data_in[17] ^ data_in[20] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[35] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[42] ^ data_in[43] ^ data_in[44]; +assign crc_next[17] = crc_state[3] ^ crc_state[4] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[21] ^ crc_state[24] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ data_in[3] ^ data_in[4] ^ data_in[14] ^ data_in[15] ^ data_in[18] ^ data_in[21] ^ data_in[24] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[36] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[43] ^ data_in[44] ^ data_in[45]; +assign crc_next[18] = crc_state[0] ^ crc_state[4] ^ crc_state[5] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[22] ^ crc_state[25] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[22] ^ data_in[25] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[37] ^ data_in[40] ^ data_in[41] ^ data_in[42] ^ data_in[44] ^ data_in[45] ^ data_in[46]; +assign crc_next[19] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[6] ^ crc_state[16] ^ crc_state[17] ^ crc_state[20] ^ crc_state[23] ^ crc_state[26] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[16] ^ data_in[17] ^ data_in[20] ^ data_in[23] ^ data_in[26] ^ data_in[29] ^ data_in[30] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[38] ^ data_in[41] ^ data_in[42] ^ data_in[43] ^ data_in[45] ^ data_in[46] ^ data_in[47]; +assign crc_next[20] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[14] ^ crc_state[16] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[27] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[14] ^ data_in[16] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[27] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[35] ^ data_in[38] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[47]; +assign crc_next[21] = crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[28] ^ crc_state[31] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[28] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[38] ^ data_in[42] ^ data_in[44] ^ data_in[45] ^ data_in[47]; +assign crc_next[22] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[23] ^ crc_state[24] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[18] ^ data_in[23] ^ data_in[24] ^ data_in[29] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[42] ^ data_in[43] ^ data_in[45] ^ data_in[46]; +assign crc_next[23] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[24] ^ crc_state[25] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[24] ^ data_in[25] ^ data_in[30] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[47]; +assign crc_next[24] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[10] ^ crc_state[13] ^ crc_state[15] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[13] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[31] ^ data_in[32] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[42] ^ data_in[44] ^ data_in[45] ^ data_in[47]; +assign crc_next[25] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[17] ^ data_in[18] ^ data_in[22] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[33] ^ data_in[36] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[42] ^ data_in[43] ^ data_in[45] ^ data_in[46]; +assign crc_next[26] = crc_state[1] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[18] ^ crc_state[19] ^ crc_state[23] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[18] ^ data_in[19] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[34] ^ data_in[37] ^ data_in[40] ^ data_in[41] ^ data_in[42] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[47]; +assign crc_next[27] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ crc_state[23] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[22] ^ data_in[23] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[32] ^ data_in[35] ^ data_in[36] ^ data_in[39] ^ data_in[41] ^ data_in[43] ^ data_in[44] ^ data_in[45] ^ data_in[47]; +assign crc_next[28] = crc_state[2] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[22] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[2] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[22] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[44] ^ data_in[45] ^ data_in[46]; +assign crc_next[29] = crc_state[3] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[23] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[3] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[23] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[45] ^ data_in[46] ^ data_in[47]; +assign crc_next[30] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[19] ^ crc_state[20] ^ crc_state[23] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[19] ^ data_in[20] ^ data_in[23] ^ data_in[30] ^ data_in[31] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[46] ^ data_in[47]; +assign crc_next[31] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[10] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[10] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[31] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[41] ^ data_in[47]; + +endmodule diff --git a/rtl/eth_crc_56.v b/rtl/eth_crc_56.v new file mode 100644 index 000000000..51871564b --- /dev/null +++ b/rtl/eth_crc_56.v @@ -0,0 +1,85 @@ +/* + +Copyright (c) 2014-2015 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 + +/* + * CRC module eth_crc_56 + * + * CRC width: 32 + * Data width: 56 + * CRC polynomial: 32'h4c11db7 + * Configuration: galois + * Bit-reverse: input and output + * + * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + * + * Generated by crcgen.py + * + * crcgen.py -b -r -d 56 -n eth_crc_56 + * + */ +module eth_crc_56 +( + input wire [55:0] data_in, + input wire [31:0] crc_state, + output wire [31:0] crc_next +); + +assign crc_next[0] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[19] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[19] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[40] ^ data_in[44] ^ data_in[46] ^ data_in[47] ^ data_in[50]; +assign crc_next[1] = crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[20] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[20] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[41] ^ data_in[45] ^ data_in[47] ^ data_in[48] ^ data_in[51]; +assign crc_next[2] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[21] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[21] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[42] ^ data_in[46] ^ data_in[48] ^ data_in[49] ^ data_in[52]; +assign crc_next[3] = crc_state[1] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[22] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[22] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[43] ^ data_in[47] ^ data_in[49] ^ data_in[50] ^ data_in[53]; +assign crc_next[4] = crc_state[0] ^ crc_state[2] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[23] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[23] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[44] ^ data_in[48] ^ data_in[50] ^ data_in[51] ^ data_in[54]; +assign crc_next[5] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[24] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[24] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[45] ^ data_in[49] ^ data_in[51] ^ data_in[52] ^ data_in[55]; +assign crc_next[6] = crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[33] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[40] ^ data_in[44] ^ data_in[47] ^ data_in[52] ^ data_in[53]; +assign crc_next[7] = crc_state[0] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[23] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[23] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[41] ^ data_in[45] ^ data_in[48] ^ data_in[53] ^ data_in[54]; +assign crc_next[8] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[24] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[24] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[42] ^ data_in[46] ^ data_in[49] ^ data_in[54] ^ data_in[55]; +assign crc_next[9] = crc_state[0] ^ crc_state[3] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[24] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[24] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[41] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[55]; +assign crc_next[10] = crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[13] ^ crc_state[15] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[24] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[13] ^ data_in[15] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[24] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[33] ^ data_in[37] ^ data_in[38] ^ data_in[42] ^ data_in[45] ^ data_in[46] ^ data_in[50]; +assign crc_next[11] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[14] ^ crc_state[16] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[25] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[14] ^ data_in[16] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[25] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[32] ^ data_in[34] ^ data_in[38] ^ data_in[39] ^ data_in[43] ^ data_in[46] ^ data_in[47] ^ data_in[51]; +assign crc_next[12] = crc_state[1] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[15] ^ crc_state[17] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[26] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[15] ^ data_in[17] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[26] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[33] ^ data_in[35] ^ data_in[39] ^ data_in[40] ^ data_in[44] ^ data_in[47] ^ data_in[48] ^ data_in[52]; +assign crc_next[13] = crc_state[2] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[16] ^ crc_state[18] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ crc_state[29] ^ crc_state[31] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[16] ^ data_in[18] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[36] ^ data_in[40] ^ data_in[41] ^ data_in[45] ^ data_in[48] ^ data_in[49] ^ data_in[53]; +assign crc_next[14] = crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[17] ^ crc_state[19] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[28] ^ crc_state[30] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[17] ^ data_in[19] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[28] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[35] ^ data_in[37] ^ data_in[41] ^ data_in[42] ^ data_in[46] ^ data_in[49] ^ data_in[50] ^ data_in[54]; +assign crc_next[15] = crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[18] ^ crc_state[20] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[29] ^ crc_state[31] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[18] ^ data_in[20] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[29] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[36] ^ data_in[38] ^ data_in[42] ^ data_in[43] ^ data_in[47] ^ data_in[50] ^ data_in[51] ^ data_in[55]; +assign crc_next[16] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[10] ^ crc_state[11] ^ crc_state[21] ^ crc_state[22] ^ crc_state[25] ^ crc_state[28] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[10] ^ data_in[11] ^ data_in[21] ^ data_in[22] ^ data_in[25] ^ data_in[28] ^ data_in[31] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[43] ^ data_in[46] ^ data_in[47] ^ data_in[48] ^ data_in[50] ^ data_in[51] ^ data_in[52]; +assign crc_next[17] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[12] ^ crc_state[22] ^ crc_state[23] ^ crc_state[26] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[12] ^ data_in[22] ^ data_in[23] ^ data_in[26] ^ data_in[29] ^ data_in[32] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[44] ^ data_in[47] ^ data_in[48] ^ data_in[49] ^ data_in[51] ^ data_in[52] ^ data_in[53]; +assign crc_next[18] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[13] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[13] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[30] ^ data_in[33] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[45] ^ data_in[48] ^ data_in[49] ^ data_in[50] ^ data_in[52] ^ data_in[53] ^ data_in[54]; +assign crc_next[19] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[14] ^ crc_state[24] ^ crc_state[25] ^ crc_state[28] ^ crc_state[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[14] ^ data_in[24] ^ data_in[25] ^ data_in[28] ^ data_in[31] ^ data_in[34] ^ data_in[37] ^ data_in[38] ^ data_in[40] ^ data_in[42] ^ data_in[43] ^ data_in[46] ^ data_in[49] ^ data_in[50] ^ data_in[51] ^ data_in[53] ^ data_in[54] ^ data_in[55]; +assign crc_next[20] = crc_state[0] ^ crc_state[1] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[22] ^ crc_state[24] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[22] ^ data_in[24] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[35] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[43] ^ data_in[46] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[55]; +assign crc_next[21] = crc_state[0] ^ crc_state[3] ^ crc_state[5] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ data_in[0] ^ data_in[3] ^ data_in[5] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[36] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[46] ^ data_in[50] ^ data_in[52] ^ data_in[53] ^ data_in[55]; +assign crc_next[22] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[26] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[26] ^ data_in[31] ^ data_in[32] ^ data_in[37] ^ data_in[42] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[50] ^ data_in[51] ^ data_in[53] ^ data_in[54]; +assign crc_next[23] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[32] ^ data_in[33] ^ data_in[38] ^ data_in[43] ^ data_in[44] ^ data_in[45] ^ data_in[47] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[55]; +assign crc_next[24] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[18] ^ crc_state[21] ^ crc_state[23] ^ crc_state[26] ^ crc_state[27] ^ crc_state[30] ^ crc_state[31] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[18] ^ data_in[21] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[39] ^ data_in[40] ^ data_in[45] ^ data_in[47] ^ data_in[48] ^ data_in[50] ^ data_in[52] ^ data_in[53] ^ data_in[55]; +assign crc_next[25] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[25] ^ data_in[26] ^ data_in[30] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[41] ^ data_in[44] ^ data_in[47] ^ data_in[48] ^ data_in[49] ^ data_in[50] ^ data_in[51] ^ data_in[53] ^ data_in[54]; +assign crc_next[26] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[9] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[26] ^ crc_state[27] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[26] ^ data_in[27] ^ data_in[31] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[42] ^ data_in[45] ^ data_in[48] ^ data_in[49] ^ data_in[50] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[55]; +assign crc_next[27] = crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ crc_state[31] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[30] ^ data_in[31] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[40] ^ data_in[43] ^ data_in[44] ^ data_in[47] ^ data_in[49] ^ data_in[51] ^ data_in[52] ^ data_in[53] ^ data_in[55]; +assign crc_next[28] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[10] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[28] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[10] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[28] ^ data_in[30] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[45] ^ data_in[46] ^ data_in[47] ^ data_in[48] ^ data_in[52] ^ data_in[53] ^ data_in[54]; +assign crc_next[29] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[11] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[11] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[29] ^ data_in[31] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[46] ^ data_in[47] ^ data_in[48] ^ data_in[49] ^ data_in[53] ^ data_in[54] ^ data_in[55]; +assign crc_next[30] = crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[27] ^ crc_state[28] ^ crc_state[31] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[27] ^ data_in[28] ^ data_in[31] ^ data_in[38] ^ data_in[39] ^ data_in[42] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[48] ^ data_in[49] ^ data_in[54] ^ data_in[55]; +assign crc_next[31] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[18] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[18] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[39] ^ data_in[43] ^ data_in[45] ^ data_in[46] ^ data_in[49] ^ data_in[55]; + +endmodule diff --git a/rtl/eth_crc_64.v b/rtl/eth_crc_64.v new file mode 100644 index 000000000..2979381ad --- /dev/null +++ b/rtl/eth_crc_64.v @@ -0,0 +1,85 @@ +/* + +Copyright (c) 2014-2015 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 + +/* + * CRC module eth_crc_64 + * + * CRC width: 32 + * Data width: 64 + * CRC polynomial: 32'h4c11db7 + * Configuration: galois + * Bit-reverse: input and output + * + * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + * + * Generated by crcgen.py + * + * crcgen.py -b -r -d 64 -n eth_crc_64 + * + */ +module eth_crc_64 +( + input wire [63:0] data_in, + input wire [31:0] crc_state, + output wire [31:0] crc_next +); + +assign crc_next[0] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[27] ^ crc_state[30] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[27] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[48] ^ data_in[52] ^ data_in[54] ^ data_in[55] ^ data_in[58]; +assign crc_next[1] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[28] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[28] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[49] ^ data_in[53] ^ data_in[55] ^ data_in[56] ^ data_in[59]; +assign crc_next[2] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[29] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[42] ^ data_in[50] ^ data_in[54] ^ data_in[56] ^ data_in[57] ^ data_in[60]; +assign crc_next[3] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[30] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[43] ^ data_in[51] ^ data_in[55] ^ data_in[57] ^ data_in[58] ^ data_in[61]; +assign crc_next[4] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[31] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[42] ^ data_in[43] ^ data_in[44] ^ data_in[52] ^ data_in[56] ^ data_in[58] ^ data_in[59] ^ data_in[62]; +assign crc_next[5] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[32] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[43] ^ data_in[44] ^ data_in[45] ^ data_in[53] ^ data_in[57] ^ data_in[59] ^ data_in[60] ^ data_in[63]; +assign crc_next[6] = crc_state[1] ^ crc_state[2] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[30] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[41] ^ data_in[42] ^ data_in[44] ^ data_in[45] ^ data_in[46] ^ data_in[48] ^ data_in[52] ^ data_in[55] ^ data_in[60] ^ data_in[61]; +assign crc_next[7] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[31] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[42] ^ data_in[43] ^ data_in[45] ^ data_in[46] ^ data_in[47] ^ data_in[49] ^ data_in[53] ^ data_in[56] ^ data_in[61] ^ data_in[62]; +assign crc_next[8] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[32] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[47] ^ data_in[48] ^ data_in[50] ^ data_in[54] ^ data_in[57] ^ data_in[62] ^ data_in[63]; +assign crc_next[9] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[11] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[11] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[32] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[44] ^ data_in[45] ^ data_in[47] ^ data_in[49] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[63]; +assign crc_next[10] = crc_state[1] ^ crc_state[2] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[21] ^ crc_state[23] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ data_in[1] ^ data_in[2] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[21] ^ data_in[23] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[32] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[41] ^ data_in[45] ^ data_in[46] ^ data_in[50] ^ data_in[53] ^ data_in[54] ^ data_in[58]; +assign crc_next[11] = crc_state[2] ^ crc_state[3] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[22] ^ crc_state[24] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ data_in[2] ^ data_in[3] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[22] ^ data_in[24] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[33] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[40] ^ data_in[42] ^ data_in[46] ^ data_in[47] ^ data_in[51] ^ data_in[54] ^ data_in[55] ^ data_in[59]; +assign crc_next[12] = crc_state[3] ^ crc_state[4] ^ crc_state[9] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[23] ^ crc_state[25] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[3] ^ data_in[4] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[23] ^ data_in[25] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[34] ^ data_in[36] ^ data_in[38] ^ data_in[39] ^ data_in[41] ^ data_in[43] ^ data_in[47] ^ data_in[48] ^ data_in[52] ^ data_in[55] ^ data_in[56] ^ data_in[60]; +assign crc_next[13] = crc_state[4] ^ crc_state[5] ^ crc_state[10] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[24] ^ crc_state[26] ^ crc_state[29] ^ crc_state[31] ^ data_in[4] ^ data_in[5] ^ data_in[10] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[24] ^ data_in[26] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[35] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[42] ^ data_in[44] ^ data_in[48] ^ data_in[49] ^ data_in[53] ^ data_in[56] ^ data_in[57] ^ data_in[61]; +assign crc_next[14] = crc_state[5] ^ crc_state[6] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[25] ^ crc_state[27] ^ crc_state[30] ^ data_in[5] ^ data_in[6] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[25] ^ data_in[27] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[36] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[43] ^ data_in[45] ^ data_in[49] ^ data_in[50] ^ data_in[54] ^ data_in[57] ^ data_in[58] ^ data_in[62]; +assign crc_next[15] = crc_state[6] ^ crc_state[7] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[26] ^ crc_state[28] ^ crc_state[31] ^ data_in[6] ^ data_in[7] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[26] ^ data_in[28] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[37] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[44] ^ data_in[46] ^ data_in[50] ^ data_in[51] ^ data_in[55] ^ data_in[58] ^ data_in[59] ^ data_in[63]; +assign crc_next[16] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[18] ^ crc_state[19] ^ crc_state[29] ^ crc_state[30] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[18] ^ data_in[19] ^ data_in[29] ^ data_in[30] ^ data_in[33] ^ data_in[36] ^ data_in[39] ^ data_in[42] ^ data_in[43] ^ data_in[45] ^ data_in[47] ^ data_in[48] ^ data_in[51] ^ data_in[54] ^ data_in[55] ^ data_in[56] ^ data_in[58] ^ data_in[59] ^ data_in[60]; +assign crc_next[17] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[20] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[20] ^ data_in[30] ^ data_in[31] ^ data_in[34] ^ data_in[37] ^ data_in[40] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[48] ^ data_in[49] ^ data_in[52] ^ data_in[55] ^ data_in[56] ^ data_in[57] ^ data_in[59] ^ data_in[60] ^ data_in[61]; +assign crc_next[18] = crc_state[1] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[21] ^ crc_state[31] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[21] ^ data_in[31] ^ data_in[32] ^ data_in[35] ^ data_in[38] ^ data_in[41] ^ data_in[44] ^ data_in[45] ^ data_in[47] ^ data_in[49] ^ data_in[50] ^ data_in[53] ^ data_in[56] ^ data_in[57] ^ data_in[58] ^ data_in[60] ^ data_in[61] ^ data_in[62]; +assign crc_next[19] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[22] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[22] ^ data_in[32] ^ data_in[33] ^ data_in[36] ^ data_in[39] ^ data_in[42] ^ data_in[45] ^ data_in[46] ^ data_in[48] ^ data_in[50] ^ data_in[51] ^ data_in[54] ^ data_in[57] ^ data_in[58] ^ data_in[59] ^ data_in[61] ^ data_in[62] ^ data_in[63]; +assign crc_next[20] = crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[27] ^ crc_state[30] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[27] ^ data_in[30] ^ data_in[32] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[43] ^ data_in[46] ^ data_in[47] ^ data_in[48] ^ data_in[49] ^ data_in[51] ^ data_in[54] ^ data_in[59] ^ data_in[60] ^ data_in[62] ^ data_in[63]; +assign crc_next[21] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[13] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[13] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[44] ^ data_in[47] ^ data_in[49] ^ data_in[50] ^ data_in[54] ^ data_in[58] ^ data_in[60] ^ data_in[61] ^ data_in[63]; +assign crc_next[22] = crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[34] ^ data_in[39] ^ data_in[40] ^ data_in[45] ^ data_in[50] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[58] ^ data_in[59] ^ data_in[61] ^ data_in[62]; +assign crc_next[23] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[35] ^ data_in[40] ^ data_in[41] ^ data_in[46] ^ data_in[51] ^ data_in[52] ^ data_in[53] ^ data_in[55] ^ data_in[59] ^ data_in[60] ^ data_in[62] ^ data_in[63]; +assign crc_next[24] = crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[26] ^ crc_state[29] ^ crc_state[31] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[26] ^ data_in[29] ^ data_in[31] ^ data_in[34] ^ data_in[35] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[42] ^ data_in[47] ^ data_in[48] ^ data_in[53] ^ data_in[55] ^ data_in[56] ^ data_in[58] ^ data_in[60] ^ data_in[61] ^ data_in[63]; +assign crc_next[25] = crc_state[1] ^ crc_state[3] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ data_in[1] ^ data_in[3] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[33] ^ data_in[34] ^ data_in[38] ^ data_in[41] ^ data_in[42] ^ data_in[43] ^ data_in[49] ^ data_in[52] ^ data_in[55] ^ data_in[56] ^ data_in[57] ^ data_in[58] ^ data_in[59] ^ data_in[61] ^ data_in[62]; +assign crc_next[26] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[17] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[17] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[34] ^ data_in[35] ^ data_in[39] ^ data_in[42] ^ data_in[43] ^ data_in[44] ^ data_in[50] ^ data_in[53] ^ data_in[56] ^ data_in[57] ^ data_in[58] ^ data_in[59] ^ data_in[60] ^ data_in[62] ^ data_in[63]; +assign crc_next[27] = crc_state[0] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[30] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[38] ^ data_in[39] ^ data_in[43] ^ data_in[44] ^ data_in[45] ^ data_in[48] ^ data_in[51] ^ data_in[52] ^ data_in[55] ^ data_in[57] ^ data_in[59] ^ data_in[60] ^ data_in[61] ^ data_in[63]; +assign crc_next[28] = crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[18] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[30] ^ crc_state[31] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[18] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[36] ^ data_in[38] ^ data_in[44] ^ data_in[45] ^ data_in[46] ^ data_in[48] ^ data_in[49] ^ data_in[53] ^ data_in[54] ^ data_in[55] ^ data_in[56] ^ data_in[60] ^ data_in[61] ^ data_in[62]; +assign crc_next[29] = crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[19] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[31] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[19] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[37] ^ data_in[39] ^ data_in[45] ^ data_in[46] ^ data_in[47] ^ data_in[49] ^ data_in[50] ^ data_in[54] ^ data_in[55] ^ data_in[56] ^ data_in[57] ^ data_in[61] ^ data_in[62] ^ data_in[63]; +assign crc_next[30] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[25] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[35] ^ data_in[36] ^ data_in[39] ^ data_in[46] ^ data_in[47] ^ data_in[50] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[56] ^ data_in[57] ^ data_in[62] ^ data_in[63]; +assign crc_next[31] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[26] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[26] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[47] ^ data_in[51] ^ data_in[53] ^ data_in[54] ^ data_in[57] ^ data_in[63]; + +endmodule diff --git a/rtl/eth_crc_8.v b/rtl/eth_crc_8.v new file mode 100644 index 000000000..320f55781 --- /dev/null +++ b/rtl/eth_crc_8.v @@ -0,0 +1,85 @@ +/* + +Copyright (c) 2014-2015 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 + +/* + * CRC module eth_crc_8 + * + * CRC width: 32 + * Data width: 8 + * CRC polynomial: 32'h4c11db7 + * Configuration: galois + * Bit-reverse: input and output + * + * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + * + * Generated by crcgen.py + * + * crcgen.py -b -r -d 8 -n eth_crc_8 + * + */ +module eth_crc_8 +( + input wire [7:0] data_in, + input wire [31:0] crc_state, + output wire [31:0] crc_next +); + +assign crc_next[0] = crc_state[2] ^ crc_state[8] ^ data_in[2]; +assign crc_next[1] = crc_state[0] ^ crc_state[3] ^ crc_state[9] ^ data_in[0] ^ data_in[3]; +assign crc_next[2] = crc_state[0] ^ crc_state[1] ^ crc_state[4] ^ crc_state[10] ^ data_in[0] ^ data_in[1] ^ data_in[4]; +assign crc_next[3] = crc_state[1] ^ crc_state[2] ^ crc_state[5] ^ crc_state[11] ^ data_in[1] ^ data_in[2] ^ data_in[5]; +assign crc_next[4] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[12] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[6]; +assign crc_next[5] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[13] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[7]; +assign crc_next[6] = crc_state[4] ^ crc_state[5] ^ crc_state[14] ^ data_in[4] ^ data_in[5]; +assign crc_next[7] = crc_state[0] ^ crc_state[5] ^ crc_state[6] ^ crc_state[15] ^ data_in[0] ^ data_in[5] ^ data_in[6]; +assign crc_next[8] = crc_state[1] ^ crc_state[6] ^ crc_state[7] ^ crc_state[16] ^ data_in[1] ^ data_in[6] ^ data_in[7]; +assign crc_next[9] = crc_state[7] ^ crc_state[17] ^ data_in[7]; +assign crc_next[10] = crc_state[2] ^ crc_state[18] ^ data_in[2]; +assign crc_next[11] = crc_state[3] ^ crc_state[19] ^ data_in[3]; +assign crc_next[12] = crc_state[0] ^ crc_state[4] ^ crc_state[20] ^ data_in[0] ^ data_in[4]; +assign crc_next[13] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[21] ^ data_in[0] ^ data_in[1] ^ data_in[5]; +assign crc_next[14] = crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[22] ^ data_in[1] ^ data_in[2] ^ data_in[6]; +assign crc_next[15] = crc_state[2] ^ crc_state[3] ^ crc_state[7] ^ crc_state[23] ^ data_in[2] ^ data_in[3] ^ data_in[7]; +assign crc_next[16] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[24] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4]; +assign crc_next[17] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[25] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5]; +assign crc_next[18] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[26] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6]; +assign crc_next[19] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[27] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7]; +assign crc_next[20] = crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[28] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7]; +assign crc_next[21] = crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[29] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7]; +assign crc_next[22] = crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[30] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6]; +assign crc_next[23] = crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[31] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7]; +assign crc_next[24] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7]; +assign crc_next[25] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6]; +assign crc_next[26] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7]; +assign crc_next[27] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7]; +assign crc_next[28] = crc_state[0] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[6]; +assign crc_next[29] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[7]; +assign crc_next[30] = crc_state[0] ^ crc_state[1] ^ crc_state[6] ^ crc_state[7] ^ data_in[0] ^ data_in[1] ^ data_in[6] ^ data_in[7]; +assign crc_next[31] = crc_state[1] ^ crc_state[7] ^ data_in[1] ^ data_in[7]; + +endmodule From 9265ab0946a09307b4aade96918a188a1fcddf28 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 15:58:20 -0800 Subject: [PATCH 138/617] Properly handle eth_fcs of None --- tb/eth_ep.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tb/eth_ep.py b/tb/eth_ep.py index 0a50edc22..260e765f3 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -112,7 +112,10 @@ class EthFrame(object): self.payload == other.payload) def __repr__(self): - return 'EthFrame(payload=%s, eth_dest_mac=0x%012x, eth_src_mac=0x%012x, eth_type=0x%04x, eth_fcs=0x%08x)' % (repr(self.payload), self.eth_dest_mac, self.eth_src_mac, self.eth_type, self.eth_fcs) + fcs = 'None' + if self.eth_fcs is not None: + fcs = '0x%08x' % self.eth_fcs + return 'EthFrame(payload=%s, eth_dest_mac=0x%012x, eth_src_mac=0x%012x, eth_type=0x%04x, eth_fcs=%s)' % (repr(self.payload), self.eth_dest_mac, self.eth_src_mac, self.eth_type, fcs) def EthFrameSource(clk, rst, eth_hdr_valid=None, From 43fe36087c88da84e3aadbf3a05531877a15644e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 16:04:57 -0800 Subject: [PATCH 139/617] Update readme --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 2c7196262..c853c8444 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,10 @@ Ethernet frame transmitter. Ethernet frame transmitter with 64 bit datapath for 10G Ethernet. +### eth_crc_N module + +CRC logic for Ethernet frame check sequence, N input data bits. + ### eth_demux_N module Ethernet frame demuliplexer with 8 bit data width for gigabit Ethernet. @@ -267,6 +271,14 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/eth_axis_rx_64.v : Ethernet frame receiver (64 bit) rtl/eth_axis_tx.v : Ethernet frame transmitter rtl/eth_axis_tx_64.v : Ethernet frame transmitter (64 bit) + rtl/eth_crc_8.v : Ethernet CRC logic, 8 bits + rtl/eth_crc_16.v : Ethernet CRC logic, 16 bits + rtl/eth_crc_24.v : Ethernet CRC logic, 24 bits + rtl/eth_crc_32.v : Ethernet CRC logic, 32 bits + rtl/eth_crc_40.v : Ethernet CRC logic, 40 bits + rtl/eth_crc_48.v : Ethernet CRC logic, 48 bits + rtl/eth_crc_56.v : Ethernet CRC logic, 56 bits + rtl/eth_crc_64.v : Ethernet CRC logic, 64 bits rtl/eth_demux.py : Ethernet frame demultiplexer generator rtl/eth_demux_4.v : 4 port Ethernet frame demultiplexer rtl/eth_demux_64.py : Ethernet frame demultiplexer generator (64 bit) From da04654196e88c4617d45ccf15030dd2dd06a595 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 16:11:04 -0800 Subject: [PATCH 140/617] Add Ethernet FCS calculator modules --- rtl/axis_eth_fcs.v | 89 +++++++++++++++++ rtl/axis_eth_fcs_64.v | 155 ++++++++++++++++++++++++++++++ tb/test_axis_eth_fcs.py | 177 ++++++++++++++++++++++++++++++++++ tb/test_axis_eth_fcs.v | 82 ++++++++++++++++ tb/test_axis_eth_fcs_64.py | 189 +++++++++++++++++++++++++++++++++++++ tb/test_axis_eth_fcs_64.v | 85 +++++++++++++++++ 6 files changed, 777 insertions(+) create mode 100644 rtl/axis_eth_fcs.v create mode 100644 rtl/axis_eth_fcs_64.v create mode 100755 tb/test_axis_eth_fcs.py create mode 100644 tb/test_axis_eth_fcs.v create mode 100755 tb/test_axis_eth_fcs_64.py create mode 100644 tb/test_axis_eth_fcs_64.v diff --git a/rtl/axis_eth_fcs.v b/rtl/axis_eth_fcs.v new file mode 100644 index 000000000..60a17520f --- /dev/null +++ b/rtl/axis_eth_fcs.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2015 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 Ethernet FCS Generator + */ +module axis_eth_fcs +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [7:0] input_axis_tdata, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * FCS output + */ + output wire [31:0] output_fcs, + output wire output_fcs_valid +); + +reg [31:0] crc_state = 32'hFFFFFFFF; +reg [31:0] fcs_reg = 0; +reg fcs_valid_reg = 0; + +wire [31:0] crc_next; + +assign input_axis_tready = 1; +assign output_fcs = fcs_reg; +assign output_fcs_valid = fcs_valid_reg; + +eth_crc_8 +eth_crc_8_inst ( + .data_in(input_axis_tdata), + .crc_state(crc_state), + .crc_next(crc_next) +); + +always @(posedge clk or posedge rst) begin + if (rst) begin + crc_state <= 32'hFFFFFFFF; + fcs_reg <= 0; + fcs_valid_reg <= 0; + end else begin + fcs_valid_reg <= 0; + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + crc_state <= 32'hFFFFFFFF; + fcs_reg <= ~crc_next; + fcs_valid_reg <= 1; + end else begin + crc_state <= crc_next; + end + end + end +end + +endmodule diff --git a/rtl/axis_eth_fcs_64.v b/rtl/axis_eth_fcs_64.v new file mode 100644 index 000000000..539f9dc75 --- /dev/null +++ b/rtl/axis_eth_fcs_64.v @@ -0,0 +1,155 @@ +/* + +Copyright (c) 2015 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 Ethernet FCS Generator (64 bit datapath) + */ +module axis_eth_fcs_64 +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [63:0] input_axis_tdata, + input wire [7:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * FCS output + */ + output wire [31:0] output_fcs, + output wire output_fcs_valid +); + +reg [31:0] crc_state = 32'hFFFFFFFF; +reg [31:0] fcs_reg = 0; +reg fcs_valid_reg = 0; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; +wire [31:0] crc_next4; +wire [31:0] crc_next5; +wire [31:0] crc_next6; +wire [31:0] crc_next7; + +assign input_axis_tready = 1; +assign output_fcs = fcs_reg; +assign output_fcs_valid = fcs_valid_reg; + +eth_crc_8 +eth_crc_8_inst ( + .data_in(input_axis_tdata[7:0]), + .crc_state(crc_state), + .crc_next(crc_next0) +); + +eth_crc_16 +eth_crc_16_inst ( + .data_in(input_axis_tdata[15:0]), + .crc_state(crc_state), + .crc_next(crc_next1) +); + +eth_crc_24 +eth_crc_24_inst ( + .data_in(input_axis_tdata[23:0]), + .crc_state(crc_state), + .crc_next(crc_next2) +); + +eth_crc_32 +eth_crc_32_inst ( + .data_in(input_axis_tdata[31:0]), + .crc_state(crc_state), + .crc_next(crc_next3) +); + +eth_crc_40 +eth_crc_40_inst ( + .data_in(input_axis_tdata[39:0]), + .crc_state(crc_state), + .crc_next(crc_next4) +); + +eth_crc_48 +eth_crc_48_inst ( + .data_in(input_axis_tdata[47:0]), + .crc_state(crc_state), + .crc_next(crc_next5) +); + +eth_crc_56 +eth_crc_56_inst ( + .data_in(input_axis_tdata[55:0]), + .crc_state(crc_state), + .crc_next(crc_next6) +); + +eth_crc_64 +eth_crc_64_inst ( + .data_in(input_axis_tdata[63:0]), + .crc_state(crc_state), + .crc_next(crc_next7) +); + +always @(posedge clk or posedge rst) begin + if (rst) begin + crc_state <= 32'hFFFFFFFF; + fcs_reg <= 0; + fcs_valid_reg <= 0; + end else begin + fcs_valid_reg <= 0; + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + crc_state <= 32'hFFFFFFFF; + case (input_axis_tkeep) + 8'b00000001: fcs_reg <= ~crc_next0; + 8'b00000011: fcs_reg <= ~crc_next1; + 8'b00000111: fcs_reg <= ~crc_next2; + 8'b00001111: fcs_reg <= ~crc_next3; + 8'b00011111: fcs_reg <= ~crc_next4; + 8'b00111111: fcs_reg <= ~crc_next5; + 8'b01111111: fcs_reg <= ~crc_next6; + 8'b11111111: fcs_reg <= ~crc_next7; + endcase + fcs_valid_reg <= 1; + end else begin + crc_state <= crc_next7; + end + end + end +end + +endmodule diff --git a/tb/test_axis_eth_fcs.py b/tb/test_axis_eth_fcs.py new file mode 100755 index 000000000..6899a6665 --- /dev/null +++ b/tb/test_axis_eth_fcs.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep + +module = 'axis_eth_fcs' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_eth_fcs(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_fcs, + output_fcs_valid): + + 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_fcs=output_fcs, + output_fcs_valid=output_fcs_valid) + +def bench(): + + # Parameters + + + # 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)) + + # Outputs + input_axis_tready = Signal(bool(1)) + output_fcs = Signal(intbv(0)[32:]) + output_fcs_valid = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_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') + + # DUT + dut = dut_axis_eth_fcs(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_fcs, + output_fcs_valid) + + @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 + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + yield output_fcs_valid.posedge + + print(hex(int(output_fcs))) + print(hex(test_frame.eth_fcs)) + + assert output_fcs == test_frame.eth_fcs + + yield delay(100) + + raise StopSimulation + + return dut, source, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_eth_fcs.v b/tb/test_axis_eth_fcs.v new file mode 100644 index 000000000..e1a10f78b --- /dev/null +++ b/tb/test_axis_eth_fcs.v @@ -0,0 +1,82 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for axis_eth_fcs + */ +module test_axis_eth_fcs; + +// Parameters + +// 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; + +// Outputs +wire input_axis_tready; +wire [31:0] output_fcs; +wire output_fcs_valid; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser); + $to_myhdl(input_axis_tready, + output_fcs, + output_fcs_valid); + + // dump file + $dumpfile("test_axis_eth_fcs.lxt"); + $dumpvars(0, test_axis_eth_fcs); +end + +axis_eth_fcs +UUT ( + .clk(clk), + .rst(rst), + .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_fcs(output_fcs), + .output_fcs_valid(output_fcs_valid) +); + +endmodule diff --git a/tb/test_axis_eth_fcs_64.py b/tb/test_axis_eth_fcs_64.py new file mode 100755 index 000000000..8b4fe0bbf --- /dev/null +++ b/tb/test_axis_eth_fcs_64.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep + +module = 'axis_eth_fcs_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/eth_crc_16.v") +srcs.append("../rtl/eth_crc_24.v") +srcs.append("../rtl/eth_crc_32.v") +srcs.append("../rtl/eth_crc_40.v") +srcs.append("../rtl/eth_crc_48.v") +srcs.append("../rtl/eth_crc_56.v") +srcs.append("../rtl/eth_crc_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_eth_fcs_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_fcs, + output_fcs_valid): + + 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_fcs=output_fcs, + output_fcs_valid=output_fcs_valid) + +def bench(): + + # Parameters + + + # 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)) + + # Outputs + input_axis_tready = Signal(bool(1)) + output_fcs = Signal(intbv(0)[32:]) + output_fcs_valid = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_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') + + # DUT + dut = dut_axis_eth_fcs_64(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_fcs, + output_fcs_valid) + + @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 + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + yield output_fcs_valid.posedge + + print(hex(int(output_fcs))) + print(hex(test_frame.eth_fcs)) + + assert output_fcs == test_frame.eth_fcs + + yield delay(100) + + raise StopSimulation + + return dut, source, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_eth_fcs_64.v b/tb/test_axis_eth_fcs_64.v new file mode 100644 index 000000000..68dd4b0c0 --- /dev/null +++ b/tb/test_axis_eth_fcs_64.v @@ -0,0 +1,85 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for axis_eth_fcs_64 + */ +module test_axis_eth_fcs_64; + +// Parameters + +// 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; + +// Outputs +wire input_axis_tready; +wire [31:0] output_fcs; +wire output_fcs_valid; + +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); + $to_myhdl(input_axis_tready, + output_fcs, + output_fcs_valid); + + // dump file + $dumpfile("test_axis_eth_fcs_64.lxt"); + $dumpvars(0, test_axis_eth_fcs_64); +end + +axis_eth_fcs_64 +UUT ( + .clk(clk), + .rst(rst), + .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_fcs(output_fcs), + .output_fcs_valid(output_fcs_valid) +); + +endmodule From bf847ff5408d064ba83f7559d22ded442915e01c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 16:14:09 -0800 Subject: [PATCH 141/617] Update readme --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index c853c8444..53d2fb915 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,14 @@ ARP frame transmitter. ARP frame transmitter with 64 bit datapath for 10G Ethernet. +### axis_eth_fcs module + +Ethernet frame check sequence calculator. + +### axis_eth_fcs_64 module + +Ethernet frame check sequence calculator with 64 bit datapath for 10G Ethernet. + ### eth_arb_mux_N module Ethernet frame arbitrated muliplexer with 8 bit data width for gigabit @@ -262,6 +270,8 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/arp_eth_tx.v : ARP frame transmitter rtl/arp_eth_tx_64.v : ARP frame transmitter (64 bit) rtl/eth_arb_mux.py : Ethernet frame arbitrated multiplexer generator + rtl/axis_eth_fcs.v : Ethernet FCS calculator + rtl/axis_eth_fcs_64.v : Ethernet FCS calculator (64 bit) rtl/eth_arb_mux_2.v : 2 port Ethernet frame arbitrated multiplexer rtl/eth_arb_mux_4.v : 4 port Ethernet frame arbitrated multiplexer rtl/eth_arb_mux_64.py : Ethernet frame arbitrated multiplexer generator (64 bit) From bfe6c37ca93f856afa4ce32f536a41e3cc4b9c3c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 19:00:33 -0800 Subject: [PATCH 142/617] Add ethernet FCS inserter and checker --- rtl/axis_eth_fcs_check.v | 303 ++++++++++++++++++++++++ rtl/axis_eth_fcs_insert.v | 320 +++++++++++++++++++++++++ tb/test_axis_eth_fcs_check.py | 416 +++++++++++++++++++++++++++++++++ tb/test_axis_eth_fcs_check.v | 97 ++++++++ tb/test_axis_eth_fcs_insert.py | 350 +++++++++++++++++++++++++++ tb/test_axis_eth_fcs_insert.v | 99 ++++++++ 6 files changed, 1585 insertions(+) create mode 100644 rtl/axis_eth_fcs_check.v create mode 100644 rtl/axis_eth_fcs_insert.v create mode 100755 tb/test_axis_eth_fcs_check.py create mode 100644 tb/test_axis_eth_fcs_check.v create mode 100755 tb/test_axis_eth_fcs_insert.py create mode 100644 tb/test_axis_eth_fcs_insert.v diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v new file mode 100644 index 000000000..434e204e0 --- /dev/null +++ b/rtl/axis_eth_fcs_check.v @@ -0,0 +1,303 @@ +/* + +Copyright (c) 2015 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 Ethernet FCS checker + */ +module axis_eth_fcs_check +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [7: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 [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Status + */ + output wire busy, + output wire error_bad_fcs +); + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PAYLOAD = 2'd1; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; +reg shift_in; +reg shift_reset; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [7:0] input_axis_tdata_d0 = 0; +reg [7:0] input_axis_tdata_d1 = 0; +reg [7:0] input_axis_tdata_d2 = 0; +reg [7:0] input_axis_tdata_d3 = 0; + +reg input_axis_tvalid_d0 = 0; +reg input_axis_tvalid_d1 = 0; +reg input_axis_tvalid_d2 = 0; +reg input_axis_tvalid_d3 = 0; + +reg busy_reg = 0; +reg error_bad_fcs_reg = 0, error_bad_fcs_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; +wire [31:0] crc_next; + +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +assign input_axis_tready = input_axis_tready_reg; + +assign busy = busy_reg; +assign error_bad_fcs = error_bad_fcs_reg; + +eth_crc_8 +eth_crc_8_inst ( + .data_in(input_axis_tdata_d3), + .crc_state(crc_state), + .crc_next(crc_next) +); + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 0; + update_crc = 0; + shift_in = 0; + shift_reset = 0; + + frame_ptr_next = frame_ptr_reg; + + input_axis_tready_next = 0; + + output_axis_tdata_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + error_bad_fcs_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + input_axis_tready_next = output_axis_tready_int_early; + frame_ptr_next = 0; + reset_crc = 1; + + output_axis_tdata_int = input_axis_tdata_d3; + output_axis_tvalid_int = input_axis_tvalid_d3 & input_axis_tvalid; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (input_axis_tready & input_axis_tvalid) begin + shift_in = 1; + + if (input_axis_tvalid_d3) begin + frame_ptr_next = 1; + reset_crc = 0; + update_crc = 1; + state_next = STATE_PAYLOAD; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // transfer payload + input_axis_tready_next = output_axis_tready_int_early; + + output_axis_tdata_int = input_axis_tdata_d3; + output_axis_tvalid_int = input_axis_tvalid_d3 & input_axis_tvalid; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (input_axis_tready & input_axis_tvalid) begin + frame_ptr_next = frame_ptr_reg + 1; + shift_in = 1; + update_crc = 1; + if (input_axis_tlast) begin + shift_reset = 1; + reset_crc = 1; + output_axis_tlast_int = 1; + output_axis_tuser_int = input_axis_tuser; + if ({input_axis_tdata, input_axis_tdata_d0, input_axis_tdata_d1, input_axis_tdata_d2} != ~crc_next) begin + output_axis_tuser_int = 1; + error_bad_fcs_next = 1; + end + input_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_IDLE; + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + state_next = STATE_PAYLOAD; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 0; + + input_axis_tready_reg <= 0; + + busy_reg <= 0; + error_bad_fcs_reg <= 0; + + crc_state <= 32'hFFFFFFFF; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + input_axis_tready_reg <= input_axis_tready_next; + + busy_reg <= state_next != STATE_IDLE; + error_bad_fcs_reg <= error_bad_fcs_next; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next; + end + + if (shift_reset) begin + input_axis_tvalid_d0 <= 0; + input_axis_tvalid_d1 <= 0; + input_axis_tvalid_d2 <= 0; + input_axis_tvalid_d3 <= 0; + end else if (shift_in) begin + input_axis_tdata_d0 <= input_axis_tdata; + input_axis_tdata_d1 <= input_axis_tdata_d0; + input_axis_tdata_d2 <= input_axis_tdata_d1; + input_axis_tdata_d3 <= input_axis_tdata_d2; + + input_axis_tvalid_d0 <= input_axis_tvalid; + input_axis_tvalid_d1 <= input_axis_tvalid_d0; + input_axis_tvalid_d2 <= input_axis_tvalid_d1; + input_axis_tvalid_d3 <= input_axis_tvalid_d2; + end + end +end + +// output datapath logic +reg [7:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v new file mode 100644 index 000000000..a95380175 --- /dev/null +++ b/rtl/axis_eth_fcs_insert.v @@ -0,0 +1,320 @@ +/* + +Copyright (c) 2015 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 Ethernet FCS inserter + */ +module axis_eth_fcs_insert # +( + parameter ENABLE_PADDING = 0, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [7: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 [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Status + */ + output wire busy +); + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PAYLOAD = 2'd1, + STATE_PAD = 2'd2, + STATE_FCS = 2'd3; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg busy_reg = 0; + +reg input_axis_tready_reg = 0, input_axis_tready_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; +wire [31:0] crc_next; + +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +assign input_axis_tready = input_axis_tready_reg; + +assign busy = busy_reg; + +eth_crc_8 +eth_crc_8_inst ( + .data_in(output_axis_tdata_int), + .crc_state(crc_state), + .crc_next(crc_next) +); + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 0; + update_crc = 0; + + frame_ptr_next = frame_ptr_reg; + + input_axis_tready_next = 0; + + output_axis_tdata_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + input_axis_tready_next = output_axis_tready_int_early; + frame_ptr_next = 0; + reset_crc = 1; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tvalid_int = input_axis_tvalid; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (input_axis_tready & input_axis_tvalid) begin + frame_ptr_next = 1; + reset_crc = 0; + update_crc = 1; + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // transfer payload + input_axis_tready_next = output_axis_tready_int_early; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tvalid_int = input_axis_tvalid; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (input_axis_tready & input_axis_tvalid) begin + frame_ptr_next = frame_ptr_reg + 1; + update_crc = 1; + if (input_axis_tlast) begin + if (input_axis_tuser) begin + output_axis_tlast_int = 1; + output_axis_tuser_int = 1; + reset_crc = 1; + state_next = STATE_IDLE; + end else begin + input_axis_tready_next = 0; + if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-5) begin + state_next = STATE_PAD; + end else begin + frame_ptr_next = 0; + state_next = STATE_FCS; + end + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + state_next = STATE_PAYLOAD; + end + end + STATE_PAD: begin + // insert padding + input_axis_tready_next = 0; + + output_axis_tdata_int = 0; + output_axis_tvalid_int = 1; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (output_axis_tready_int) begin + frame_ptr_next = frame_ptr_reg + 1; + update_crc = 1; + if (frame_ptr_next < MIN_FRAME_LENGTH-5) begin + state_next = STATE_PAD; + end else begin + frame_ptr_next = 0; + state_next = STATE_FCS; + end + end + end + STATE_FCS: begin + // send FCS + input_axis_tready_next = 0; + + case (frame_ptr_reg) + 2'd0: output_axis_tdata_int = ~crc_state[7:0]; + 2'd1: output_axis_tdata_int = ~crc_state[15:8]; + 2'd2: output_axis_tdata_int = ~crc_state[23:16]; + 2'd3: output_axis_tdata_int = ~crc_state[31:24]; + endcase + output_axis_tvalid_int = 1; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (output_axis_tready_int) begin + frame_ptr_next = frame_ptr_reg + 1; + + if (frame_ptr_reg < 3) begin + state_next = STATE_FCS; + end else begin + reset_crc = 1; + frame_ptr_next = 0; + output_axis_tlast_int = 1; + input_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_FCS; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 0; + + input_axis_tready_reg <= 0; + + busy_reg <= 0; + + crc_state <= 32'hFFFFFFFF; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + input_axis_tready_reg <= input_axis_tready_next; + + busy_reg <= state_next != STATE_IDLE; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next; + end + end +end + +// output datapath logic +reg [7:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [7:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py new file mode 100755 index 000000000..a51919e5e --- /dev/null +++ b/tb/test_axis_eth_fcs_check.py @@ -0,0 +1,416 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep + +module = 'axis_eth_fcs_check' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_eth_fcs_check(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, + + busy, + error_bad_fcs): + + 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, + + busy=busy, + error_bad_fcs=error_bad_fcs) + +def bench(): + + # Parameters + + + # 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)) + busy = Signal(bool(0)) + error_bad_fcs = 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_eth_fcs_check(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, + + busy, + error_bad_fcs) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame1 + assert not rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + axis_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: bad FCS, length %d" % payload_len) + current_test.next = 4 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + axis_frame1.data[-1] ^= 0xff + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_eth_fcs_check.v b/tb/test_axis_eth_fcs_check.v new file mode 100644 index 000000000..bfb00d425 --- /dev/null +++ b/tb/test_axis_eth_fcs_check.v @@ -0,0 +1,97 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for axis_eth_fcs_check + */ +module test_axis_eth_fcs_check; + +// Parameters + +// 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 busy; +wire error_bad_fcs; + +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, + busy, + error_bad_fcs); + + // dump file + $dumpfile("test_axis_eth_fcs_check.lxt"); + $dumpvars(0, test_axis_eth_fcs_check); +end + +axis_eth_fcs_check +UUT ( + .clk(clk), + .rst(rst), + .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), + .busy(busy), + .error_bad_fcs(error_bad_fcs) +); + +endmodule diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py new file mode 100755 index 000000000..ccf395879 --- /dev/null +++ b/tb/test_axis_eth_fcs_insert.py @@ -0,0 +1,350 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep + +module = 'axis_eth_fcs_insert' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_eth_fcs_insert(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, + + busy): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_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, + + busy=busy) + +def bench(): + + # Parameters + ENABLE_PADDING = 0 + MIN_FRAME_LENGTH = 64 + + # 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)) + busy = 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_eth_fcs_insert(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, + + busy) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + assert eth_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + assert eth_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + assert eth_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + assert eth_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_eth_fcs_insert.v b/tb/test_axis_eth_fcs_insert.v new file mode 100644 index 000000000..39f966fd3 --- /dev/null +++ b/tb/test_axis_eth_fcs_insert.v @@ -0,0 +1,99 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for axis_eth_fcs_insert + */ +module test_axis_eth_fcs_insert; + +// Parameters +parameter ENABLE_PADDING = 0; +parameter MIN_FRAME_LENGTH = 64; + +// 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 busy; + +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, + busy); + + // dump file + $dumpfile("test_axis_eth_fcs_insert.lxt"); + $dumpvars(0, test_axis_eth_fcs_insert); +end + +axis_eth_fcs_insert #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .clk(clk), + .rst(rst), + .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), + .busy(busy) +); + +endmodule From 218d3f1b0f6a406eed0d6a6abf574545c95f36cb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 19:05:56 -0800 Subject: [PATCH 143/617] Add assert for error_bad_fcs signal --- tb/test_axis_eth_fcs_check.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index a51919e5e..89d623f5e 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -160,6 +160,13 @@ def bench(): def clkgen(): clk.next = not clk + error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_bad_fcs): + error_bad_fcs_asserted.next = 1 + def wait_normal(): while input_axis_tvalid or output_axis_tvalid: yield clk.posedge @@ -371,6 +378,8 @@ def bench(): axis_frame1.data[-1] ^= 0xff for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_bad_fcs_asserted.next = 0 + source_queue.put(axis_frame1) source_queue.put(axis_frame2) yield clk.posedge @@ -382,6 +391,8 @@ def bench(): yield clk.posedge yield clk.posedge + assert error_bad_fcs_asserted + rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() @@ -405,7 +416,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, monitor, source, sink, clkgen, check def test_bench(): sim = Simulation(bench()) From bb31d5792157fdc53a800ed18802cdbf2174998f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 19:15:31 -0800 Subject: [PATCH 144/617] Add GMII endpoint module --- tb/gmii_ep.py | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 tb/gmii_ep.py diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py new file mode 100644 index 000000000..c4b13d3b7 --- /dev/null +++ b/tb/gmii_ep.py @@ -0,0 +1,100 @@ +""" + +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 GMIISource(clk, rst, + txd, + tx_en, + tx_er, + fifo=None, + name=None): + + @instance + def logic(): + frame = [] + ifg_cnt = 0 + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame = [] + txd.next = 0 + tx_en.next = 0 + tx_er.next = 0 + ifg_cnt = 0 + else: + if ifg_cnt > 0: + ifg_cnt -= 1 + tx_en.next = 0 + elif len(frame) > 0: + txd.next = frame.pop(0) + tx_en.next = 1 + if len(frame) == 0: + ifg_cnt = 12 + elif not fifo.empty(): + frame = fifo.get() + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + frame = '\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(frame) + txd.next = frame.pop(0) + tx_en.next = 1 + else: + tx_en.next = 0 + + return logic + + +def GMIISink(clk, rst, + rxd, + rx_dv, + rx_er, + fifo=None, + name=None): + + @instance + def logic(): + frame = None + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame = None + else: + if rx_dv: + if frame is None and rxd == 0xD5: + frame = [] + elif frame is not None: + frame.append(int(rxd)) + elif frame is not None: + if len(frame) > 0: + if fifo is not None: + fifo.put(frame) + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + frame = None + + return logic From 6dee616834d4bf3590b0f04dee7aa583b1d57d89 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 19:16:08 -0800 Subject: [PATCH 145/617] Add gigabit MAC module --- rtl/eth_mac_1g.v | 115 +++++++++++++ rtl/eth_mac_1g_rx.v | 231 ++++++++++++++++++++++++++ rtl/eth_mac_1g_tx.v | 262 +++++++++++++++++++++++++++++ tb/test_eth_mac_1g.py | 341 ++++++++++++++++++++++++++++++++++++++ tb/test_eth_mac_1g.v | 130 +++++++++++++++ tb/test_eth_mac_1g_rx.py | 343 ++++++++++++++++++++++++++++++++++++++ tb/test_eth_mac_1g_rx.v | 88 ++++++++++ tb/test_eth_mac_1g_tx.py | 347 +++++++++++++++++++++++++++++++++++++++ tb/test_eth_mac_1g_tx.v | 93 +++++++++++ 9 files changed, 1950 insertions(+) create mode 100644 rtl/eth_mac_1g.v create mode 100644 rtl/eth_mac_1g_rx.v create mode 100644 rtl/eth_mac_1g_tx.v create mode 100755 tb/test_eth_mac_1g.py create mode 100644 tb/test_eth_mac_1g.v create mode 100755 tb/test_eth_mac_1g_rx.py create mode 100644 tb/test_eth_mac_1g_rx.v create mode 100755 tb/test_eth_mac_1g_tx.py create mode 100644 tb/test_eth_mac_1g_tx.v diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v new file mode 100644 index 000000000..848630e5b --- /dev/null +++ b/rtl/eth_mac_1g.v @@ -0,0 +1,115 @@ +/* + +Copyright (c) 2015 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 + +/* + * 1G Ethernet MAC + */ +module eth_mac_1g # +( + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, + + /* + * AXI input + */ + input wire [7:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] rx_axis_tdata, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * GMII interface + */ + input wire [7:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, + output wire [7:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * Status + */ + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +eth_mac_1g_rx +eth_mac_1g_rx_inst ( + .clk(rx_clk), + .rst(rx_rst), + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .output_axis_tdata(rx_axis_tdata), + .output_axis_tvalid(rx_axis_tvalid), + .output_axis_tlast(rx_axis_tlast), + .output_axis_tuser(rx_axis_tuser), + .error_bad_frame(rx_error_bad_frame), + .error_bad_fcs(rx_error_bad_fcs) +); + +eth_mac_1g_tx #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_tx_inst ( + .clk(tx_clk), + .rst(tx_rst), + .input_axis_tdata(tx_axis_tdata), + .input_axis_tvalid(tx_axis_tvalid), + .input_axis_tready(tx_axis_tready), + .input_axis_tlast(tx_axis_tlast), + .input_axis_tuser(tx_axis_tuser), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v new file mode 100644 index 000000000..b07e88492 --- /dev/null +++ b/rtl/eth_mac_1g_rx.v @@ -0,0 +1,231 @@ +/* + +Copyright (c) 2015 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 + +/* + * 1G Ethernet MAC + */ +module eth_mac_1g_rx +( + input wire clk, + input wire rst, + + /* + * GMII input + */ + input wire [7:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, + + /* + * AXI output + */ + output wire [7:0] output_axis_tdata, + output wire output_axis_tvalid, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Status + */ + output wire error_bad_frame, + output wire error_bad_fcs +); + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PAYLOAD = 3'd1; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [7:0] gmii_rxd_d0 = 0; +reg [7:0] gmii_rxd_d1 = 0; +reg [7:0] gmii_rxd_d2 = 0; +reg [7:0] gmii_rxd_d3 = 0; +reg [7:0] gmii_rxd_d4 = 0; + +reg gmii_rx_dv_d0 = 0; +reg gmii_rx_dv_d1 = 0; +reg gmii_rx_dv_d2 = 0; +reg gmii_rx_dv_d3 = 0; +reg gmii_rx_dv_d4 = 0; + +reg gmii_rx_er_d0 = 0; +reg gmii_rx_er_d1 = 0; +reg gmii_rx_er_d2 = 0; +reg gmii_rx_er_d3 = 0; +reg gmii_rx_er_d4 = 0; + +reg [7:0] output_axis_tdata_reg = 0, output_axis_tdata_next; +reg output_axis_tvalid_reg = 0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 0, output_axis_tlast_next; +reg output_axis_tuser_reg = 0, output_axis_tuser_next; + +reg error_bad_frame_reg = 0, error_bad_frame_next; +reg error_bad_fcs_reg = 0, error_bad_fcs_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; +wire [31:0] crc_next; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +assign error_bad_frame = error_bad_frame_reg; +assign error_bad_fcs = error_bad_fcs_reg; + +eth_crc_8 +eth_crc_8_inst ( + .data_in(gmii_rxd_d4), + .crc_state(crc_state), + .crc_next(crc_next) +); + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 0; + update_crc = 0; + + frame_ptr_next = frame_ptr_reg; + + output_axis_tdata_next = 0; + output_axis_tvalid_next = 0; + output_axis_tlast_next = 0; + output_axis_tuser_next = 0; + + error_bad_frame_next = 0; + error_bad_fcs_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for packet + reset_crc = 1; + + if (gmii_rx_dv_d4 && ~gmii_rx_er_d4 && gmii_rxd_d4 == 8'hD5) begin + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // read payload + update_crc = 1; + + output_axis_tdata_next = gmii_rxd_d4; + output_axis_tvalid_next = 1; + + if (gmii_rx_er) begin + // error + output_axis_tlast_next = 1; + output_axis_tuser_next = 1; + error_bad_frame_next = 1; + state_next = STATE_IDLE; + end if (~gmii_rx_dv) begin + // end of packet + output_axis_tlast_next = 1; + if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin + // FCS good + output_axis_tuser_next = 0; + end else begin + // FCS bad + output_axis_tuser_next = 1; + error_bad_frame_next = 1; + error_bad_fcs_next = 1; + end + state_next = STATE_IDLE; + end else begin + state_next = STATE_PAYLOAD; + end + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 0; + + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + + error_bad_frame_reg <= 0; + error_bad_fcs_reg <= 0; + + crc_state <= 32'hFFFFFFFF; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + output_axis_tdata_reg <= output_axis_tdata_next; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tlast_reg <= output_axis_tlast_next; + output_axis_tuser_reg <= output_axis_tuser_next; + + error_bad_frame_reg <= error_bad_frame_next; + error_bad_fcs_reg <= error_bad_fcs_next; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next; + end + end + + // delay input + gmii_rxd_d0 <= gmii_rxd; + gmii_rxd_d1 <= gmii_rxd_d0; + gmii_rxd_d2 <= gmii_rxd_d1; + gmii_rxd_d3 <= gmii_rxd_d2; + gmii_rxd_d4 <= gmii_rxd_d3; + + gmii_rx_dv_d0 <= gmii_rx_dv; + gmii_rx_dv_d1 <= gmii_rx_dv_d0; + gmii_rx_dv_d2 <= gmii_rx_dv_d1; + gmii_rx_dv_d3 <= gmii_rx_dv_d2; + gmii_rx_dv_d4 <= gmii_rx_dv_d3; + + gmii_rx_er_d0 <= gmii_rx_er; + gmii_rx_er_d1 <= gmii_rx_er_d0; + gmii_rx_er_d2 <= gmii_rx_er_d1; + gmii_rx_er_d3 <= gmii_rx_er_d2; + gmii_rx_er_d4 <= gmii_rx_er_d3; +end + +endmodule diff --git a/rtl/eth_mac_1g_tx.v b/rtl/eth_mac_1g_tx.v new file mode 100644 index 000000000..79f159dec --- /dev/null +++ b/rtl/eth_mac_1g_tx.v @@ -0,0 +1,262 @@ +/* + +Copyright (c) 2015 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 + +/* + * 1G Ethernet MAC + */ +module eth_mac_1g_tx # +( + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [7:0] input_axis_tdata, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * GMII output + */ + output wire [7:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PREAMBLE = 3'd1, + STATE_PAYLOAD = 3'd2, + STATE_PAD = 3'd3, + STATE_FCS = 3'd4, + STATE_IFG = 3'd5; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [7:0] gmii_txd_reg = 0, gmii_txd_next; +reg gmii_tx_en_reg = 0, gmii_tx_en_next; +reg gmii_tx_er_reg = 0, gmii_tx_er_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; +wire [31:0] crc_next; + +assign input_axis_tready = input_axis_tready_reg; + +assign gmii_txd = gmii_txd_reg; +assign gmii_tx_en = gmii_tx_en_reg; +assign gmii_tx_er = gmii_tx_er_reg; + +eth_crc_8 +eth_crc_8_inst ( + .data_in(gmii_txd_next), + .crc_state(crc_state), + .crc_next(crc_next) +); + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 0; + update_crc = 0; + + frame_ptr_next = frame_ptr_reg; + + input_axis_tready_next = 0; + + gmii_txd_next = 0; + gmii_tx_en_next = 0; + gmii_tx_er_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for packet + reset_crc = 1; + + if (input_axis_tvalid) begin + frame_ptr_next = 1; + gmii_txd_next = 8'h55; // Preamble + gmii_tx_en_next = 1; + state_next = STATE_PREAMBLE; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PREAMBLE: begin + // send preamble + reset_crc = 1; + frame_ptr_next = frame_ptr_reg + 1; + + gmii_txd_next = 8'h55; // Preamble + gmii_tx_en_next = 1; + + if (frame_ptr_reg == 7) begin + // end of preamble; start payload + frame_ptr_next = 0; + input_axis_tready_next = 1; + gmii_txd_next = 8'hD5; // SFD + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_PREAMBLE; + end + end + STATE_PAYLOAD: begin + // send payload + update_crc = 1; + input_axis_tready_next = 1; + + frame_ptr_next = frame_ptr_reg + 1; + + gmii_txd_next = input_axis_tdata; + gmii_tx_en_next = 1; + + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + input_axis_tready_next = 0; + if (input_axis_tuser) begin + gmii_tx_er_next = 1; + frame_ptr_next = 0; + state_next = STATE_IFG; + end else begin + if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin + state_next = STATE_PAD; + end else begin + frame_ptr_next = 0; + state_next = STATE_FCS; + end + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + gmii_tx_er_next = 1; + frame_ptr_next = 0; + state_next = STATE_IFG; + end + end + STATE_PAD: begin + // send padding + update_crc = 1; + frame_ptr_next = frame_ptr_reg + 1; + + gmii_txd_next = 0; + gmii_tx_en_next = 1; + + if (frame_ptr_reg < MIN_FRAME_LENGTH-5) begin + state_next = STATE_PAD; + end else begin + frame_ptr_next = 0; + state_next = STATE_FCS; + end + end + STATE_FCS: begin + // send FCS + frame_ptr_next = frame_ptr_reg + 1; + + case (frame_ptr_reg) + 2'd0: gmii_txd_next = ~crc_state[7:0]; + 2'd1: gmii_txd_next = ~crc_state[15:8]; + 2'd2: gmii_txd_next = ~crc_state[23:16]; + 2'd3: gmii_txd_next = ~crc_state[31:24]; + endcase + gmii_tx_en_next = 1; + + if (frame_ptr_reg < 3) begin + state_next = STATE_FCS; + end else begin + frame_ptr_next = 0; + state_next = STATE_IFG; + end + end + STATE_IFG: begin + // send IFG + frame_ptr_next = frame_ptr_reg + 1; + reset_crc = 1; + + if (frame_ptr_reg < ifg_delay-1) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 0; + + input_axis_tready_reg <= 0; + + gmii_txd_reg <= 0; + gmii_tx_en_reg <= 0; + gmii_tx_er_reg <= 0; + + crc_state <= 32'hFFFFFFFF; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + input_axis_tready_reg <= input_axis_tready_next; + + gmii_txd_reg <= gmii_txd_next; + gmii_tx_en_reg <= gmii_tx_en_next; + gmii_tx_er_reg <= gmii_tx_er_next; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next; + end + end +end + +endmodule diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py new file mode 100755 index 000000000..8b53ee4b6 --- /dev/null +++ b/tb/test_eth_mac_1g.py @@ -0,0 +1,341 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep +import gmii_ep + +module = 'eth_mac_1g' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/eth_mac_1g_rx.v") +srcs.append("../rtl/eth_mac_1g_tx.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_mac_1g(clk, + rst, + current_test, + + rx_clk, + rx_rst, + tx_clk, + tx_rst, + + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tready, + tx_axis_tlast, + tx_axis_tuser, + + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + + gmii_txd, + gmii_tx_en, + gmii_tx_er, + + rx_error_bad_frame, + rx_error_bad_fcs, + + ifg_delay): + + 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, + + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + gmii_rxd=gmii_rxd, + gmii_rx_dv=gmii_rx_dv, + gmii_rx_er=gmii_rx_er, + + gmii_txd=gmii_txd, + gmii_tx_en=gmii_tx_en, + gmii_tx_er=gmii_tx_er, + + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + + ifg_delay=ifg_delay) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[8:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + gmii_rxd = Signal(intbv(0)[8:]) + gmii_rx_dv = Signal(bool(0)) + gmii_rx_er = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[8:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + gmii_txd = Signal(intbv(0)[8:]) + gmii_tx_en = Signal(bool(0)) + gmii_tx_er = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + + # sources and sinks + gmii_source_queue = Queue() + gmii_sink_queue = Queue() + axis_source_queue = Queue() + axis_source_pause = Signal(bool(0)) + axis_sink_queue = Queue() + + gmii_source = gmii_ep.GMIISource(rx_clk, + rx_rst, + txd=gmii_rxd, + tx_en=gmii_rx_dv, + tx_er=gmii_rx_er, + fifo=gmii_source_queue, + name='gmii_source') + + gmii_sink = gmii_ep.GMIISink(tx_clk, + tx_rst, + rxd=gmii_txd, + rx_dv=gmii_tx_en, + rx_er=gmii_tx_er, + fifo=gmii_sink_queue, + name='gmii_sink') + + axis_source = axis_ep.AXIStreamSource(tx_clk, + tx_rst, + tdata=tx_axis_tdata, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + fifo=axis_source_queue, + pause=axis_source_pause, + name='axis_source') + + axis_sink = axis_ep.AXIStreamSink(rx_clk, + rx_rst, + tdata=rx_axis_tdata, + tvalid=rx_axis_tvalid, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + fifo=axis_sink_queue, + name='axis_sink') + + # DUT + dut = dut_eth_mac_1g(clk, + rst, + current_test, + + rx_clk, + rx_rst, + tx_clk, + tx_rst, + + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tready, + tx_axis_tlast, + tx_axis_tuser, + + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + + gmii_txd, + gmii_tx_en, + gmii_tx_er, + + rx_error_bad_frame, + rx_error_bad_fcs, + + ifg_delay) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + tx_clk.next = not tx_clk + rx_clk.next = not rx_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + tx_rst.next = 1 + rx_rst.next = 1 + yield clk.posedge + rst.next = 0 + tx_rst.next = 0 + rx_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + gmii_source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + while gmii_rx_dv or rx_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not axis_sink_queue.empty(): + rx_frame = axis_sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + while gmii_tx_en or tx_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not gmii_sink_queue.empty(): + rx_frame = gmii_sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(bytearray(rx_frame)) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return dut, axis_source, axis_sink, gmii_source, gmii_sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_1g.v b/tb/test_eth_mac_1g.v new file mode 100644 index 000000000..a56553a10 --- /dev/null +++ b/tb/test_eth_mac_1g.v @@ -0,0 +1,130 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for eth_mac_1g + */ +module test_eth_mac_1g; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg rx_clk = 0; +reg rx_rst = 0; +reg tx_clk = 0; +reg tx_rst = 0; +reg [7:0] tx_axis_tdata = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg [7:0] gmii_rxd = 0; +reg gmii_rx_dv = 0; +reg gmii_rx_er = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire [7:0] gmii_txd; +wire gmii_tx_en; +wire gmii_tx_er; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + rx_clk, + rx_rst, + tx_clk, + tx_rst, + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + ifg_delay); + $to_myhdl(tx_axis_tready, + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + gmii_txd, + gmii_tx_en, + gmii_tx_er, + rx_error_bad_frame, + rx_error_bad_fcs); + + // dump file + $dumpfile("test_eth_mac_1g.lxt"); + $dumpvars(0, test_eth_mac_1g); +end + +eth_mac_1g #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py new file mode 100755 index 000000000..1f05e43c3 --- /dev/null +++ b/tb/test_eth_mac_1g_rx.py @@ -0,0 +1,343 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep +import gmii_ep + +module = 'eth_mac_1g_rx' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_mac_1g_rx(clk, + rst, + current_test, + + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + + error_bad_frame, + error_bad_fcs): + + 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, + + gmii_rxd=gmii_rxd, + gmii_rx_dv=gmii_rx_dv, + gmii_rx_er=gmii_rx_er, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + error_bad_frame=error_bad_frame, + error_bad_fcs=error_bad_fcs) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + gmii_rxd = Signal(intbv(0)[8:]) + gmii_rx_dv = Signal(bool(0)) + gmii_rx_er = Signal(bool(0)) + + # Outputs + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + error_bad_frame = Signal(bool(0)) + error_bad_fcs = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + sink_queue = Queue() + + source = gmii_ep.GMIISource(clk, + rst, + txd=gmii_rxd, + tx_en=gmii_rx_dv, + tx_er=gmii_rx_er, + fifo=source_queue, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + name='sink') + + # DUT + dut = dut_eth_mac_1g_rx(clk, + rst, + current_test, + + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + + error_bad_frame, + error_bad_fcs) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_bad_frame_asserted = Signal(bool(0)) + error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_bad_frame): + error_bad_frame_asserted.next = 1 + if (error_bad_fcs): + error_bad_fcs_asserted.next = 1 + + @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,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + while gmii_rx_dv or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + while gmii_rx_dv or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + + while gmii_rx_dv or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: truncated frame, length %d" % payload_len) + current_test.next = 3 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + axis_frame1.data = axis_frame1.data[:-1] + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + while gmii_rx_dv or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + + while gmii_rx_dv or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_bad_frame_asserted + assert error_bad_fcs_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, monitor, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_1g_rx.v b/tb/test_eth_mac_1g_rx.v new file mode 100644 index 000000000..95a30881e --- /dev/null +++ b/tb/test_eth_mac_1g_rx.v @@ -0,0 +1,88 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for eth_mac_1g_rx + */ +module test_eth_mac_1g_rx; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] gmii_rxd = 0; +reg gmii_rx_dv = 0; +reg gmii_rx_er = 0; + +// Outputs +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; +wire error_bad_frame; +wire error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + gmii_rxd, + gmii_rx_dv, + gmii_rx_er); + $to_myhdl(output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + error_bad_frame, + error_bad_fcs); + + // dump file + $dumpfile("test_eth_mac_1g_rx.lxt"); + $dumpvars(0, test_eth_mac_1g_rx); +end + +eth_mac_1g_rx +UUT ( + .clk(clk), + .rst(rst), + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + .error_bad_frame(error_bad_frame), + .error_bad_fcs(error_bad_fcs) +); + +endmodule diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py new file mode 100755 index 000000000..3d0531104 --- /dev/null +++ b/tb/test_eth_mac_1g_tx.py @@ -0,0 +1,347 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep +import gmii_ep + +module = 'eth_mac_1g_tx' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_mac_1g_tx(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + gmii_txd, + gmii_tx_en, + gmii_tx_er, + + ifg_delay): + + 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, + + gmii_txd=gmii_txd, + gmii_tx_en=gmii_tx_en, + gmii_tx_er=gmii_tx_er, + + ifg_delay=ifg_delay) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # 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)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + input_axis_tready = Signal(bool(0)) + gmii_txd = Signal(intbv(0)[8:]) + gmii_tx_en = Signal(bool(0)) + gmii_tx_er = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + + 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 = gmii_ep.GMIISink(clk, + rst, + rxd=gmii_txd, + rx_dv=gmii_tx_en, + rx_er=gmii_tx_er, + fifo=sink_queue, + name='sink') + + # DUT + dut = dut_eth_mac_1g_tx(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + gmii_txd, + gmii_tx_en, + gmii_tx_er, + + ifg_delay) + + @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 + + ifg_delay.next = 12 + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + while gmii_tx_en or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(bytearray(rx_frame)) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + while gmii_tx_en or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(bytearray(rx_frame)) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame1.eth_src_mac + assert eth_frame.eth_type == test_frame1.eth_type + assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(bytearray(rx_frame)) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.user = 1 + + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + while gmii_tx_en or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + # bad packet + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(bytearray(rx_frame)) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_1g_tx.v b/tb/test_eth_mac_1g_tx.v new file mode 100644 index 000000000..60a4a7bd0 --- /dev/null +++ b/tb/test_eth_mac_1g_tx.v @@ -0,0 +1,93 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for eth_mac_1g_tx + */ +module test_eth_mac_1g_tx; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; + +// 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 [7:0] ifg_delay = 0; + +// Outputs +wire input_axis_tready; +wire [7:0] gmii_txd; +wire gmii_tx_en; +wire gmii_tx_er; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + ifg_delay); + $to_myhdl(input_axis_tready, + gmii_txd, + gmii_tx_en, + gmii_tx_er); + + // dump file + $dumpfile("test_eth_mac_1g_tx.lxt"); + $dumpvars(0, test_eth_mac_1g_tx); +end + +eth_mac_1g_tx #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .clk(clk), + .rst(rst), + .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), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + .ifg_delay(ifg_delay) +); + +endmodule From b10beab08f7b85a12250b681bdde52a9bb5b13a7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 19:16:17 -0800 Subject: [PATCH 146/617] Update readme --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 53d2fb915..01bf5f8a9 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,14 @@ Ethernet frame check sequence calculator. Ethernet frame check sequence calculator with 64 bit datapath for 10G Ethernet. +### axis_eth_fcs_check module + +Ethernet frame check sequence checker. + +### axis_eth_fcs_insert module + +Ethernet frame check sequence inserter. + ### eth_arb_mux_N module Ethernet frame arbitrated muliplexer with 8 bit data width for gigabit @@ -99,6 +107,18 @@ priority and round-robin arbitration. Can be generated with arbitrary port counts with eth_demux_64.py. +### eth_mac_1g module + +Gigabit Ethernet MAC with GMII interface. + +### eth_mac_1g_rx module + +Gigabit Ethernet MAC RX with GMII interface. + +### eth_mac_1g_tx module + +Gigabit Ethernet MAC TX with GMII interface. + ### eth_mux_N module Ethernet frame muliplexer with 8 bit data width for gigabit Ethernet. @@ -272,6 +292,8 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/eth_arb_mux.py : Ethernet frame arbitrated multiplexer generator rtl/axis_eth_fcs.v : Ethernet FCS calculator rtl/axis_eth_fcs_64.v : Ethernet FCS calculator (64 bit) + rtl/axis_eth_fcs_insert.v : Ethernet FCS inserter + rtl/axis_eth_fcs_check.v : Ethernet FCS checker rtl/eth_arb_mux_2.v : 2 port Ethernet frame arbitrated multiplexer rtl/eth_arb_mux_4.v : 4 port Ethernet frame arbitrated multiplexer rtl/eth_arb_mux_64.py : Ethernet frame arbitrated multiplexer generator (64 bit) @@ -293,6 +315,9 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/eth_demux_4.v : 4 port Ethernet frame demultiplexer rtl/eth_demux_64.py : Ethernet frame demultiplexer generator (64 bit) rtl/eth_demux_64_4.v : 4 port Ethernet frame demultiplexer (64 bit) + rtl/eth_mac_1g.v : Gigabit Etherent MAC + rtl/eth_mac_1g_rx.v : Gigabit Etherent MAC RX + rtl/eth_mac_1g_tx.v : Gigabit Etherent MAC TX rtl/eth_mux.py : Ethernet frame multiplexer generator rtl/eth_mux_2.v : 4 port Ethernet frame multiplexer rtl/eth_mux_4.v : 4 port Ethernet frame multiplexer From ca94f1ded9c39627084013fa0e1e11c08d17f7e5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 19:17:34 -0800 Subject: [PATCH 147/617] Update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 01bf5f8a9..05aec6d63 100644 --- a/README.md +++ b/README.md @@ -455,5 +455,6 @@ individual test scripts can be run with python directly. tb/arp_ep.py : MyHDL ARP frame endpoints tb/axis_ep.py : MyHDL AXI Stream endpoints tb/eth_ep.py : MyHDL Ethernet frame endpoints + tb/gmii_ep.py : MyHDL GMII endpoints tb/ip_ep.py : MyHDL IP frame endpoints tb/udp_ep.py : MyHDL UDP frame endpoints From d34aaf784dc1696e02c711ea944e874853bcc49b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 21:19:26 -0800 Subject: [PATCH 148/617] Add UDP modules --- rtl/udp.v | 417 ++++++++++++++++++++++++ rtl/udp_64.v | 429 +++++++++++++++++++++++++ tb/test_udp.py | 784 ++++++++++++++++++++++++++++++++++++++++++++ tb/test_udp.v | 382 ++++++++++++++++++++++ tb/test_udp_64.py | 804 ++++++++++++++++++++++++++++++++++++++++++++++ tb/test_udp_64.v | 394 +++++++++++++++++++++++ 6 files changed, 3210 insertions(+) create mode 100644 rtl/udp.v create mode 100644 rtl/udp_64.v create mode 100755 tb/test_udp.py create mode 100644 tb/test_udp.v create mode 100755 tb/test_udp_64.py create mode 100644 tb/test_udp_64.v diff --git a/rtl/udp.v b/rtl/udp.v new file mode 100644 index 000000000..22b0a0a28 --- /dev/null +++ b/rtl/udp.v @@ -0,0 +1,417 @@ +/* + +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 + +/* + * UDP block, IP interface + */ +module udp # +( + parameter CHECKSUM_ENABLE = 1, + parameter CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11, + parameter CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3 +) +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [47:0] input_ip_eth_dest_mac, + input wire [47:0] input_ip_eth_src_mac, + input wire [15:0] input_ip_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [7:0] input_ip_payload_tdata, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_ip_eth_dest_mac, + output wire [47:0] output_ip_eth_src_mac, + output wire [15:0] output_ip_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * UDP frame input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [47:0] input_udp_eth_dest_mac, + input wire [47:0] input_udp_eth_src_mac, + input wire [15:0] input_udp_eth_type, + input wire [3:0] input_udp_ip_version, + input wire [3:0] input_udp_ip_ihl, + input wire [5:0] input_udp_ip_dscp, + input wire [1:0] input_udp_ip_ecn, + input wire [15:0] input_udp_ip_identification, + input wire [2:0] input_udp_ip_flags, + input wire [12:0] input_udp_ip_fragment_offset, + input wire [7:0] input_udp_ip_ttl, + input wire [7:0] input_udp_ip_protocol, + input wire [15:0] input_udp_ip_header_checksum, + input wire [31:0] input_udp_ip_source_ip, + input wire [31:0] input_udp_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [7:0] input_udp_payload_tdata, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_udp_eth_dest_mac, + output wire [47:0] output_udp_eth_src_mac, + output wire [15:0] output_udp_eth_type, + output wire [3:0] output_udp_ip_version, + output wire [3:0] output_udp_ip_ihl, + output wire [5:0] output_udp_ip_dscp, + output wire [1:0] output_udp_ip_ecn, + output wire [15:0] output_udp_ip_length, + output wire [15:0] output_udp_ip_identification, + output wire [2:0] output_udp_ip_flags, + output wire [12:0] output_udp_ip_fragment_offset, + output wire [7:0] output_udp_ip_ttl, + output wire [7:0] output_udp_ip_protocol, + output wire [15:0] output_udp_ip_header_checksum, + output wire [31:0] output_udp_ip_source_ip, + output wire [31:0] output_udp_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [7:0] output_udp_payload_tdata, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Status signals + */ + output wire rx_busy, + output wire tx_busy, + output wire rx_error_header_early_termination, + output wire rx_error_payload_early_termination, + output wire tx_error_payload_early_termination +); + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [47:0] tx_udp_eth_dest_mac; +wire [47:0] tx_udp_eth_src_mac; +wire [15:0] tx_udp_eth_type; +wire [3:0] tx_udp_ip_version; +wire [3:0] tx_udp_ip_ihl; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [15:0] tx_udp_ip_identification; +wire [2:0] tx_udp_ip_flags; +wire [12:0] tx_udp_ip_fragment_offset; +wire [7:0] tx_udp_ip_ttl; +wire [7:0] tx_udp_ip_protocol; +wire [15:0] tx_udp_ip_header_checksum; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_tdata; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +udp_ip_rx +udp_ip_rx_inst ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_eth_dest_mac(input_ip_eth_dest_mac), + .input_eth_src_mac(input_ip_eth_src_mac), + .input_eth_type(input_ip_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_udp_eth_dest_mac), + .output_eth_src_mac(output_udp_eth_src_mac), + .output_eth_type(output_udp_eth_type), + .output_ip_version(output_udp_ip_version), + .output_ip_ihl(output_udp_ip_ihl), + .output_ip_dscp(output_udp_ip_dscp), + .output_ip_ecn(output_udp_ip_ecn), + .output_ip_length(output_udp_ip_length), + .output_ip_identification(output_udp_ip_identification), + .output_ip_flags(output_udp_ip_flags), + .output_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_ip_ttl(output_udp_ip_ttl), + .output_ip_protocol(output_udp_ip_protocol), + .output_ip_header_checksum(output_udp_ip_header_checksum), + .output_ip_source_ip(output_udp_ip_source_ip), + .output_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status signals + .busy(rx_busy), + .error_header_early_termination(rx_error_header_early_termination), + .error_payload_early_termination(rx_error_payload_early_termination) +); + +generate + +if (CHECKSUM_ENABLE) begin + + udp_checksum #( + .PAYLOAD_FIFO_ADDR_WIDTH(CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .HEADER_FIFO_ADDR_WIDTH(CHECKSUM_HEADER_FIFO_ADDR_WIDTH) + ) + udp_checksum_inst ( + .clk(clk), + .rst(rst), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_eth_dest_mac(input_udp_eth_dest_mac), + .input_eth_src_mac(input_udp_eth_src_mac), + .input_eth_type(input_udp_eth_type), + .input_ip_version(input_udp_ip_version), + .input_ip_ihl(input_udp_ip_ihl), + .input_ip_dscp(input_udp_ip_dscp), + .input_ip_ecn(input_udp_ip_ecn), + .input_ip_identification(input_udp_ip_identification), + .input_ip_flags(input_udp_ip_flags), + .input_ip_fragment_offset(input_udp_ip_fragment_offset), + .input_ip_ttl(input_udp_ip_ttl), + .input_ip_protocol(input_udp_ip_protocol), + .input_ip_header_checksum(input_udp_ip_header_checksum), + .input_ip_source_ip(input_udp_ip_source_ip), + .input_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(tx_udp_hdr_valid), + .output_udp_hdr_ready(tx_udp_hdr_ready), + .output_eth_dest_mac(tx_udp_eth_dest_mac), + .output_eth_src_mac(tx_udp_eth_src_mac), + .output_eth_type(tx_udp_eth_type), + .output_ip_version(tx_udp_ip_version), + .output_ip_ihl(tx_udp_ip_ihl), + .output_ip_dscp(tx_udp_ip_dscp), + .output_ip_ecn(tx_udp_ip_ecn), + .output_ip_length(), + .output_ip_identification(tx_udp_ip_identification), + .output_ip_flags(tx_udp_ip_flags), + .output_ip_fragment_offset(tx_udp_ip_fragment_offset), + .output_ip_ttl(tx_udp_ip_ttl), + .output_ip_protocol(tx_udp_ip_protocol), + .output_ip_header_checksum(tx_udp_ip_header_checksum), + .output_ip_source_ip(tx_udp_ip_source_ip), + .output_ip_dest_ip(tx_udp_ip_dest_ip), + .output_udp_source_port(tx_udp_source_port), + .output_udp_dest_port(tx_udp_dest_port), + .output_udp_length(tx_udp_length), + .output_udp_checksum(tx_udp_checksum), + .output_udp_payload_tdata(tx_udp_payload_tdata), + .output_udp_payload_tvalid(tx_udp_payload_tvalid), + .output_udp_payload_tready(tx_udp_payload_tready), + .output_udp_payload_tlast(tx_udp_payload_tlast), + .output_udp_payload_tuser(tx_udp_payload_tuser) + ); + +end else begin + + assign tx_udp_hdr_valid = input_udp_hdr_valid; + assign input_udp_hdr_ready = tx_udp_hdr_ready; + assign tx_udp_eth_dest_mac = input_udp_eth_dest_mac; + assign tx_udp_eth_src_mac = input_udp_eth_src_mac; + assign tx_udp_eth_type = input_udp_eth_type; + assign tx_udp_ip_version = input_udp_ip_version; + assign tx_udp_ip_ihl = input_udp_ip_ihl; + assign tx_udp_ip_dscp = input_udp_ip_dscp; + assign tx_udp_ip_ecn = input_udp_ip_ecn; + assign tx_udp_ip_identification = input_udp_ip_identification; + assign tx_udp_ip_flags = input_udp_ip_flags; + assign tx_udp_ip_fragment_offset = input_udp_ip_fragment_offset; + assign tx_udp_ip_ttl = input_udp_ip_ttl; + assign tx_udp_ip_protocol = input_udp_ip_protocol; + assign tx_udp_ip_header_checksum = input_udp_ip_header_checksum; + assign tx_udp_ip_source_ip = input_udp_ip_source_ip; + assign tx_udp_ip_dest_ip = input_udp_ip_dest_ip; + assign tx_udp_source_port = input_udp_source_port; + assign tx_udp_dest_port = input_udp_dest_port; + assign tx_udp_length = input_udp_length; + assign tx_udp_checksum = input_udp_checksum; + assign tx_udp_payload_tdata = input_udp_payload_tdata; + assign tx_udp_payload_tvalid = input_udp_payload_tvalid; + assign input_udp_payload_tready = tx_udp_payload_tready; + assign tx_udp_payload_tlast = input_udp_payload_tlast; + assign tx_udp_payload_tuser = input_udp_payload_tuser; + +end + +endgenerate + +udp_ip_tx +udp_ip_tx_inst ( + .clk(clk), + .rst(rst), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_eth_dest_mac(tx_udp_eth_dest_mac), + .input_eth_src_mac(tx_udp_eth_src_mac), + .input_eth_type(tx_udp_eth_type), + .input_ip_version(tx_udp_ip_version), + .input_ip_ihl(tx_udp_ip_ihl), + .input_ip_dscp(tx_udp_ip_dscp), + .input_ip_ecn(tx_udp_ip_ecn), + .input_ip_identification(tx_udp_ip_identification), + .input_ip_flags(tx_udp_ip_flags), + .input_ip_fragment_offset(tx_udp_ip_fragment_offset), + .input_ip_ttl(tx_udp_ip_ttl), + .input_ip_protocol(tx_udp_ip_protocol), + .input_ip_header_checksum(tx_udp_ip_header_checksum), + .input_ip_source_ip(tx_udp_ip_source_ip), + .input_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_ip_eth_dest_mac), + .output_eth_src_mac(output_ip_eth_src_mac), + .output_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .busy(tx_busy), + .error_payload_early_termination(tx_error_payload_early_termination) +); + +endmodule diff --git a/rtl/udp_64.v b/rtl/udp_64.v new file mode 100644 index 000000000..f90d53347 --- /dev/null +++ b/rtl/udp_64.v @@ -0,0 +1,429 @@ +/* + +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 + +/* + * UDP block, IP interface (64 bit datapath) + */ +module udp_64 # +( + parameter CHECKSUM_ENABLE = 1, + parameter CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11, + parameter CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3 +) +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [47:0] input_ip_eth_dest_mac, + input wire [47:0] input_ip_eth_src_mac, + input wire [15:0] input_ip_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [63:0] input_ip_payload_tdata, + input wire [7:0] input_ip_payload_tkeep, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_ip_eth_dest_mac, + output wire [47:0] output_ip_eth_src_mac, + output wire [15:0] output_ip_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * UDP frame input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [47:0] input_udp_eth_dest_mac, + input wire [47:0] input_udp_eth_src_mac, + input wire [15:0] input_udp_eth_type, + input wire [3:0] input_udp_ip_version, + input wire [3:0] input_udp_ip_ihl, + input wire [5:0] input_udp_ip_dscp, + input wire [1:0] input_udp_ip_ecn, + input wire [15:0] input_udp_ip_identification, + input wire [2:0] input_udp_ip_flags, + input wire [12:0] input_udp_ip_fragment_offset, + input wire [7:0] input_udp_ip_ttl, + input wire [7:0] input_udp_ip_protocol, + input wire [15:0] input_udp_ip_header_checksum, + input wire [31:0] input_udp_ip_source_ip, + input wire [31:0] input_udp_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [63:0] input_udp_payload_tdata, + input wire [7:0] input_udp_payload_tkeep, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_udp_eth_dest_mac, + output wire [47:0] output_udp_eth_src_mac, + output wire [15:0] output_udp_eth_type, + output wire [3:0] output_udp_ip_version, + output wire [3:0] output_udp_ip_ihl, + output wire [5:0] output_udp_ip_dscp, + output wire [1:0] output_udp_ip_ecn, + output wire [15:0] output_udp_ip_length, + output wire [15:0] output_udp_ip_identification, + output wire [2:0] output_udp_ip_flags, + output wire [12:0] output_udp_ip_fragment_offset, + output wire [7:0] output_udp_ip_ttl, + output wire [7:0] output_udp_ip_protocol, + output wire [15:0] output_udp_ip_header_checksum, + output wire [31:0] output_udp_ip_source_ip, + output wire [31:0] output_udp_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [63:0] output_udp_payload_tdata, + output wire [7:0] output_udp_payload_tkeep, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Status signals + */ + output wire rx_busy, + output wire tx_busy, + output wire rx_error_header_early_termination, + output wire rx_error_payload_early_termination, + output wire tx_error_payload_early_termination +); + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [47:0] tx_udp_eth_dest_mac; +wire [47:0] tx_udp_eth_src_mac; +wire [15:0] tx_udp_eth_type; +wire [3:0] tx_udp_ip_version; +wire [3:0] tx_udp_ip_ihl; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [15:0] tx_udp_ip_identification; +wire [2:0] tx_udp_ip_flags; +wire [12:0] tx_udp_ip_fragment_offset; +wire [7:0] tx_udp_ip_ttl; +wire [7:0] tx_udp_ip_protocol; +wire [15:0] tx_udp_ip_header_checksum; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [63:0] tx_udp_payload_tdata; +wire [7:0] tx_udp_payload_tkeep; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +udp_ip_rx_64 +udp_ip_rx_64_inst ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_eth_dest_mac(input_ip_eth_dest_mac), + .input_eth_src_mac(input_ip_eth_src_mac), + .input_eth_type(input_ip_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_udp_eth_dest_mac), + .output_eth_src_mac(output_udp_eth_src_mac), + .output_eth_type(output_udp_eth_type), + .output_ip_version(output_udp_ip_version), + .output_ip_ihl(output_udp_ip_ihl), + .output_ip_dscp(output_udp_ip_dscp), + .output_ip_ecn(output_udp_ip_ecn), + .output_ip_length(output_udp_ip_length), + .output_ip_identification(output_udp_ip_identification), + .output_ip_flags(output_udp_ip_flags), + .output_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_ip_ttl(output_udp_ip_ttl), + .output_ip_protocol(output_udp_ip_protocol), + .output_ip_header_checksum(output_udp_ip_header_checksum), + .output_ip_source_ip(output_udp_ip_source_ip), + .output_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status signals + .busy(rx_busy), + .error_header_early_termination(rx_error_header_early_termination), + .error_payload_early_termination(rx_error_payload_early_termination) +); + +generate + +if (CHECKSUM_ENABLE) begin + + udp_checksum_64 #( + .PAYLOAD_FIFO_ADDR_WIDTH(CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .HEADER_FIFO_ADDR_WIDTH(CHECKSUM_HEADER_FIFO_ADDR_WIDTH) + ) + udp_checksum_64_inst ( + .clk(clk), + .rst(rst), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_eth_dest_mac(input_udp_eth_dest_mac), + .input_eth_src_mac(input_udp_eth_src_mac), + .input_eth_type(input_udp_eth_type), + .input_ip_version(input_udp_ip_version), + .input_ip_ihl(input_udp_ip_ihl), + .input_ip_dscp(input_udp_ip_dscp), + .input_ip_ecn(input_udp_ip_ecn), + .input_ip_identification(input_udp_ip_identification), + .input_ip_flags(input_udp_ip_flags), + .input_ip_fragment_offset(input_udp_ip_fragment_offset), + .input_ip_ttl(input_udp_ip_ttl), + .input_ip_protocol(input_udp_ip_protocol), + .input_ip_header_checksum(input_udp_ip_header_checksum), + .input_ip_source_ip(input_udp_ip_source_ip), + .input_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tkeep(input_udp_payload_tkeep), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(tx_udp_hdr_valid), + .output_udp_hdr_ready(tx_udp_hdr_ready), + .output_eth_dest_mac(tx_udp_eth_dest_mac), + .output_eth_src_mac(tx_udp_eth_src_mac), + .output_eth_type(tx_udp_eth_type), + .output_ip_version(tx_udp_ip_version), + .output_ip_ihl(tx_udp_ip_ihl), + .output_ip_dscp(tx_udp_ip_dscp), + .output_ip_ecn(tx_udp_ip_ecn), + .output_ip_length(), + .output_ip_identification(tx_udp_ip_identification), + .output_ip_flags(tx_udp_ip_flags), + .output_ip_fragment_offset(tx_udp_ip_fragment_offset), + .output_ip_ttl(tx_udp_ip_ttl), + .output_ip_protocol(tx_udp_ip_protocol), + .output_ip_header_checksum(tx_udp_ip_header_checksum), + .output_ip_source_ip(tx_udp_ip_source_ip), + .output_ip_dest_ip(tx_udp_ip_dest_ip), + .output_udp_source_port(tx_udp_source_port), + .output_udp_dest_port(tx_udp_dest_port), + .output_udp_length(tx_udp_length), + .output_udp_checksum(tx_udp_checksum), + .output_udp_payload_tdata(tx_udp_payload_tdata), + .output_udp_payload_tkeep(tx_udp_payload_tkeep), + .output_udp_payload_tvalid(tx_udp_payload_tvalid), + .output_udp_payload_tready(tx_udp_payload_tready), + .output_udp_payload_tlast(tx_udp_payload_tlast), + .output_udp_payload_tuser(tx_udp_payload_tuser) + ); + +end else begin + + assign tx_udp_hdr_valid = input_udp_hdr_valid; + assign input_udp_hdr_ready = tx_udp_hdr_ready; + assign tx_udp_eth_dest_mac = input_udp_eth_dest_mac; + assign tx_udp_eth_src_mac = input_udp_eth_src_mac; + assign tx_udp_eth_type = input_udp_eth_type; + assign tx_udp_ip_version = input_udp_ip_version; + assign tx_udp_ip_ihl = input_udp_ip_ihl; + assign tx_udp_ip_dscp = input_udp_ip_dscp; + assign tx_udp_ip_ecn = input_udp_ip_ecn; + assign tx_udp_ip_identification = input_udp_ip_identification; + assign tx_udp_ip_flags = input_udp_ip_flags; + assign tx_udp_ip_fragment_offset = input_udp_ip_fragment_offset; + assign tx_udp_ip_ttl = input_udp_ip_ttl; + assign tx_udp_ip_protocol = input_udp_ip_protocol; + assign tx_udp_ip_header_checksum = input_udp_ip_header_checksum; + assign tx_udp_ip_source_ip = input_udp_ip_source_ip; + assign tx_udp_ip_dest_ip = input_udp_ip_dest_ip; + assign tx_udp_source_port = input_udp_source_port; + assign tx_udp_dest_port = input_udp_dest_port; + assign tx_udp_length = input_udp_length; + assign tx_udp_checksum = input_udp_checksum; + assign tx_udp_payload_tdata = input_udp_payload_tdata; + assign tx_udp_payload_tkeep = input_udp_payload_tkeep; + assign tx_udp_payload_tvalid = input_udp_payload_tvalid; + assign input_udp_payload_tready = tx_udp_payload_tready; + assign tx_udp_payload_tlast = input_udp_payload_tlast; + assign tx_udp_payload_tuser = input_udp_payload_tuser; + +end + +endgenerate + +udp_ip_tx_64 +udp_ip_tx_64_inst ( + .clk(clk), + .rst(rst), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_eth_dest_mac(tx_udp_eth_dest_mac), + .input_eth_src_mac(tx_udp_eth_src_mac), + .input_eth_type(tx_udp_eth_type), + .input_ip_version(tx_udp_ip_version), + .input_ip_ihl(tx_udp_ip_ihl), + .input_ip_dscp(tx_udp_ip_dscp), + .input_ip_ecn(tx_udp_ip_ecn), + .input_ip_identification(tx_udp_ip_identification), + .input_ip_flags(tx_udp_ip_flags), + .input_ip_fragment_offset(tx_udp_ip_fragment_offset), + .input_ip_ttl(tx_udp_ip_ttl), + .input_ip_protocol(tx_udp_ip_protocol), + .input_ip_header_checksum(tx_udp_ip_header_checksum), + .input_ip_source_ip(tx_udp_ip_source_ip), + .input_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tkeep(tx_udp_payload_tkeep), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_ip_eth_dest_mac), + .output_eth_src_mac(output_ip_eth_src_mac), + .output_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // Status signals + .busy(tx_busy), + .error_payload_early_termination(tx_error_payload_early_termination) +); + +endmodule diff --git a/tb/test_udp.py b/tb/test_udp.py new file mode 100755 index 000000000..5f1760b07 --- /dev/null +++ b/tb/test_udp.py @@ -0,0 +1,784 @@ +#!/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 eth_ep +import ip_ep +import udp_ep + +module = 'udp' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/udp_ip_rx.v") +srcs.append("../rtl/udp_ip_tx.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_eth_dest_mac, + input_ip_eth_src_mac, + input_ip_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_eth_dest_mac, + input_udp_eth_src_mac, + input_udp_eth_type, + input_udp_ip_version, + input_udp_ip_ihl, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_identification, + input_udp_ip_flags, + input_udp_ip_fragment_offset, + input_udp_ip_ttl, + input_udp_ip_protocol, + input_udp_ip_header_checksum, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + tx_error_payload_early_termination): + + 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_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_ip_eth_dest_mac=input_ip_eth_dest_mac, + input_ip_eth_src_mac=input_ip_eth_src_mac, + input_ip_eth_type=input_ip_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_ip_eth_dest_mac=output_ip_eth_dest_mac, + output_ip_eth_src_mac=output_ip_eth_src_mac, + output_ip_eth_type=output_ip_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + input_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_udp_eth_dest_mac=input_udp_eth_dest_mac, + input_udp_eth_src_mac=input_udp_eth_src_mac, + input_udp_eth_type=input_udp_eth_type, + input_udp_ip_version=input_udp_ip_version, + input_udp_ip_ihl=input_udp_ip_ihl, + input_udp_ip_dscp=input_udp_ip_dscp, + input_udp_ip_ecn=input_udp_ip_ecn, + input_udp_ip_identification=input_udp_ip_identification, + input_udp_ip_flags=input_udp_ip_flags, + input_udp_ip_fragment_offset=input_udp_ip_fragment_offset, + input_udp_ip_ttl=input_udp_ip_ttl, + input_udp_ip_protocol=input_udp_ip_protocol, + input_udp_ip_header_checksum=input_udp_ip_header_checksum, + input_udp_ip_source_ip=input_udp_ip_source_ip, + input_udp_ip_dest_ip=input_udp_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_length=input_udp_length, + input_udp_checksum=input_udp_checksum, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_udp_eth_dest_mac=output_udp_eth_dest_mac, + output_udp_eth_src_mac=output_udp_eth_src_mac, + output_udp_eth_type=output_udp_eth_type, + output_udp_ip_version=output_udp_ip_version, + output_udp_ip_ihl=output_udp_ip_ihl, + output_udp_ip_dscp=output_udp_ip_dscp, + output_udp_ip_ecn=output_udp_ip_ecn, + output_udp_ip_length=output_udp_ip_length, + output_udp_ip_identification=output_udp_ip_identification, + output_udp_ip_flags=output_udp_ip_flags, + output_udp_ip_fragment_offset=output_udp_ip_fragment_offset, + output_udp_ip_ttl=output_udp_ip_ttl, + output_udp_ip_protocol=output_udp_ip_protocol, + output_udp_ip_header_checksum=output_udp_ip_header_checksum, + output_udp_ip_source_ip=output_udp_ip_source_ip, + output_udp_ip_dest_ip=output_udp_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + rx_busy=rx_busy, + tx_busy=tx_busy, + rx_error_header_early_termination=rx_error_header_early_termination, + rx_error_payload_early_termination=rx_error_payload_early_termination, + tx_error_payload_early_termination=tx_error_payload_early_termination) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_ip_hdr_valid = Signal(bool(0)) + input_ip_eth_dest_mac = Signal(intbv(0)[48:]) + input_ip_eth_src_mac = Signal(intbv(0)[48:]) + input_ip_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + input_udp_hdr_valid = Signal(bool(0)) + input_udp_eth_dest_mac = Signal(intbv(0)[48:]) + input_udp_eth_src_mac = Signal(intbv(0)[48:]) + input_udp_eth_type = Signal(intbv(0)[16:]) + input_udp_ip_version = Signal(intbv(0)[4:]) + input_udp_ip_ihl = Signal(intbv(0)[4:]) + input_udp_ip_dscp = Signal(intbv(0)[6:]) + input_udp_ip_ecn = Signal(intbv(0)[2:]) + input_udp_ip_identification = Signal(intbv(0)[16:]) + input_udp_ip_flags = Signal(intbv(0)[3:]) + input_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + input_udp_ip_ttl = Signal(intbv(0)[8:]) + input_udp_ip_protocol = Signal(intbv(0)[8:]) + input_udp_ip_header_checksum = Signal(intbv(0)[16:]) + input_udp_ip_source_ip = Signal(intbv(0)[32:]) + input_udp_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_length = Signal(intbv(0)[16:]) + input_udp_checksum = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + output_udp_payload_tready = Signal(bool(0)) + + # Outputs + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_ip_eth_dest_mac = Signal(intbv(0)[48:]) + output_ip_eth_src_mac = Signal(intbv(0)[48:]) + output_ip_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + output_udp_hdr_valid = Signal(bool(0)) + output_udp_eth_dest_mac = Signal(intbv(0)[48:]) + output_udp_eth_src_mac = Signal(intbv(0)[48:]) + output_udp_eth_type = Signal(intbv(0)[16:]) + output_udp_ip_version = Signal(intbv(0)[4:]) + output_udp_ip_ihl = Signal(intbv(0)[4:]) + output_udp_ip_dscp = Signal(intbv(0)[6:]) + output_udp_ip_ecn = Signal(intbv(0)[2:]) + output_udp_ip_length = Signal(intbv(0)[16:]) + output_udp_ip_identification = Signal(intbv(0)[16:]) + output_udp_ip_flags = Signal(intbv(0)[3:]) + output_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + output_udp_ip_ttl = Signal(intbv(0)[8:]) + output_udp_ip_protocol = Signal(intbv(0)[8:]) + output_udp_ip_header_checksum = Signal(intbv(0)[16:]) + output_udp_ip_source_ip = Signal(intbv(0)[32:]) + output_udp_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + rx_busy = Signal(bool(0)) + tx_busy = Signal(bool(0)) + rx_error_header_early_termination = Signal(bool(0)) + rx_error_payload_early_termination = Signal(bool(0)) + tx_error_payload_early_termination = Signal(bool(0)) + + # sources and sinks + ip_source_queue = Queue() + ip_source_pause = Signal(bool(0)) + ip_sink_queue = Queue() + ip_sink_pause = Signal(bool(0)) + udp_source_queue = Queue() + udp_source_pause = Signal(bool(0)) + udp_sink_queue = Queue() + udp_sink_pause = Signal(bool(0)) + + ip_source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + eth_dest_mac=input_ip_eth_dest_mac, + eth_src_mac=input_ip_eth_src_mac, + eth_type=input_ip_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=ip_source_queue, + pause=ip_source_pause, + name='ip_source') + + ip_sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_ip_eth_dest_mac, + eth_src_mac=output_ip_eth_src_mac, + eth_type=output_ip_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=ip_sink_queue, + pause=ip_sink_pause, + name='ip_sink') + + udp_source = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_valid=input_udp_hdr_valid, + udp_hdr_ready=input_udp_hdr_ready, + eth_dest_mac=input_udp_eth_dest_mac, + eth_src_mac=input_udp_eth_src_mac, + eth_type=input_udp_eth_type, + ip_version=input_udp_ip_version, + ip_ihl=input_udp_ip_ihl, + ip_dscp=input_udp_ip_dscp, + ip_ecn=input_udp_ip_ecn, + ip_identification=input_udp_ip_identification, + ip_flags=input_udp_ip_flags, + ip_fragment_offset=input_udp_ip_fragment_offset, + ip_ttl=input_udp_ip_ttl, + ip_protocol=input_udp_ip_protocol, + ip_header_checksum=input_udp_ip_header_checksum, + ip_source_ip=input_udp_ip_source_ip, + ip_dest_ip=input_udp_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_length=input_udp_length, + udp_checksum=input_udp_checksum, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + fifo=udp_source_queue, + pause=udp_source_pause, + name='udp_source') + + udp_sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_udp_eth_dest_mac, + eth_src_mac=output_udp_eth_src_mac, + eth_type=output_udp_eth_type, + ip_version=output_udp_ip_version, + ip_ihl=output_udp_ip_ihl, + ip_dscp=output_udp_ip_dscp, + ip_ecn=output_udp_ip_ecn, + ip_length=output_udp_ip_length, + ip_identification=output_udp_ip_identification, + ip_flags=output_udp_ip_flags, + ip_fragment_offset=output_udp_ip_fragment_offset, + ip_ttl=output_udp_ip_ttl, + ip_protocol=output_udp_ip_protocol, + ip_header_checksum=output_udp_ip_header_checksum, + ip_source_ip=output_udp_ip_source_ip, + ip_dest_ip=output_udp_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=udp_sink_queue, + pause=udp_sink_pause, + name='udp_sink') + + # DUT + dut = dut_udp(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_eth_dest_mac, + input_ip_eth_src_mac, + input_ip_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_eth_dest_mac, + input_udp_eth_src_mac, + input_udp_eth_type, + input_udp_ip_version, + input_udp_ip_ihl, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_identification, + input_udp_ip_flags, + input_udp_ip_fragment_offset, + input_udp_ip_ttl, + input_udp_ip_protocol, + input_udp_ip_header_checksum, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + tx_error_payload_early_termination) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + rx_error_header_early_termination_asserted = Signal(bool(0)) + rx_error_payload_early_termination_asserted = Signal(bool(0)) + tx_error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_header_early_termination): + rx_error_header_early_termination_asserted.next = 1 + if (rx_error_payload_early_termination): + rx_error_payload_early_termination_asserted.next = 1 + if (tx_error_payload_early_termination): + tx_error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while (input_ip_payload_tvalid or input_udp_payload_tvalid or + output_ip_payload_tvalid or output_udp_payload_tvalid or + input_ip_hdr_valid or input_udp_hdr_valid): + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + ip_frame = test_frame.build_ip() + + ip_source_queue.put(ip_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not udp_sink_queue.empty(): + rx_frame = udp_sink_queue.get() + + assert rx_frame == test_frame + + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test UDP TX packet") + current_test.next = 2 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + udp_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not ip_sink_queue.empty(): + rx_frame = ip_sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame + + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, ip_source, ip_sink, udp_source, udp_sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp.v b/tb/test_udp.v new file mode 100644 index 000000000..278552e2f --- /dev/null +++ b/tb/test_udp.v @@ -0,0 +1,382 @@ +/* + +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_udp; + +// Parameters +parameter CHECKSUM_ENABLE = 0; +parameter CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11; +parameter CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_ip_hdr_valid = 0; +reg [47:0] input_ip_eth_dest_mac = 0; +reg [47:0] input_ip_eth_src_mac = 0; +reg [15:0] input_ip_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [7:0] input_ip_payload_tdata = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg input_udp_hdr_valid = 0; +reg [47:0] input_udp_eth_dest_mac = 0; +reg [47:0] input_udp_eth_src_mac = 0; +reg [15:0] input_udp_eth_type = 0; +reg [3:0] input_udp_ip_version = 0; +reg [3:0] input_udp_ip_ihl = 0; +reg [5:0] input_udp_ip_dscp = 0; +reg [1:0] input_udp_ip_ecn = 0; +reg [15:0] input_udp_ip_identification = 0; +reg [2:0] input_udp_ip_flags = 0; +reg [12:0] input_udp_ip_fragment_offset = 0; +reg [7:0] input_udp_ip_ttl = 0; +reg [7:0] input_udp_ip_protocol = 0; +reg [15:0] input_udp_ip_header_checksum = 0; +reg [31:0] input_udp_ip_source_ip = 0; +reg [31:0] input_udp_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [15:0] input_udp_length = 0; +reg [15:0] input_udp_checksum = 0; +reg [7:0] input_udp_payload_tdata = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; + +// Outputs +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire input_udp_hdr_ready; +wire input_udp_payload_tready; +wire output_ip_hdr_valid; +wire [47:0] output_ip_eth_dest_mac; +wire [47:0] output_ip_eth_src_mac; +wire [15:0] output_ip_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [7:0] output_ip_payload_tdata; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire output_udp_hdr_valid; +wire [47:0] output_udp_eth_dest_mac; +wire [47:0] output_udp_eth_src_mac; +wire [15:0] output_udp_eth_type; +wire [3:0] output_udp_ip_version; +wire [3:0] output_udp_ip_ihl; +wire [5:0] output_udp_ip_dscp; +wire [1:0] output_udp_ip_ecn; +wire [15:0] output_udp_ip_length; +wire [15:0] output_udp_ip_identification; +wire [2:0] output_udp_ip_flags; +wire [12:0] output_udp_ip_fragment_offset; +wire [7:0] output_udp_ip_ttl; +wire [7:0] output_udp_ip_protocol; +wire [15:0] output_udp_ip_header_checksum; +wire [31:0] output_udp_ip_source_ip; +wire [31:0] output_udp_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [7:0] output_udp_payload_tdata; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; +wire rx_busy; +wire tx_busy; +wire rx_error_header_early_termination; +wire rx_error_payload_early_termination; +wire tx_error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_ip_hdr_valid, + input_ip_eth_dest_mac, + input_ip_eth_src_mac, + input_ip_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + input_udp_hdr_valid, + input_udp_eth_dest_mac, + input_udp_eth_src_mac, + input_udp_eth_type, + input_udp_ip_version, + input_udp_ip_ihl, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_identification, + input_udp_ip_flags, + input_udp_ip_fragment_offset, + input_udp_ip_ttl, + input_udp_ip_protocol, + input_udp_ip_header_checksum, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_ip_hdr_ready, + output_ip_payload_tready, + output_udp_hdr_ready, + output_udp_payload_tready); + $to_myhdl(input_ip_hdr_ready, + input_ip_payload_tready, + input_udp_hdr_ready, + input_udp_payload_tready, + output_ip_hdr_valid, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + output_udp_hdr_valid, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser, + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + tx_error_payload_early_termination); + + // dump file + $dumpfile("test_udp.lxt"); + $dumpvars(0, test_udp); +end + +udp #( + .CHECKSUM_ENABLE(CHECKSUM_ENABLE), + .CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .CHECKSUM_HEADER_FIFO_ADDR_WIDTH(CHECKSUM_HEADER_FIFO_ADDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_eth_dest_mac(input_ip_eth_dest_mac), + .input_ip_eth_src_mac(input_ip_eth_src_mac), + .input_ip_eth_type(input_ip_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_udp_eth_dest_mac(input_udp_eth_dest_mac), + .input_udp_eth_src_mac(input_udp_eth_src_mac), + .input_udp_eth_type(input_udp_eth_type), + .input_udp_ip_version(input_udp_ip_version), + .input_udp_ip_ihl(input_udp_ip_ihl), + .input_udp_ip_dscp(input_udp_ip_dscp), + .input_udp_ip_ecn(input_udp_ip_ecn), + .input_udp_ip_identification(input_udp_ip_identification), + .input_udp_ip_flags(input_udp_ip_flags), + .input_udp_ip_fragment_offset(input_udp_ip_fragment_offset), + .input_udp_ip_ttl(input_udp_ip_ttl), + .input_udp_ip_protocol(input_udp_ip_protocol), + .input_udp_ip_header_checksum(input_udp_ip_header_checksum), + .input_udp_ip_source_ip(input_udp_ip_source_ip), + .input_udp_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_udp_eth_dest_mac(output_udp_eth_dest_mac), + .output_udp_eth_src_mac(output_udp_eth_src_mac), + .output_udp_eth_type(output_udp_eth_type), + .output_udp_ip_version(output_udp_ip_version), + .output_udp_ip_ihl(output_udp_ip_ihl), + .output_udp_ip_dscp(output_udp_ip_dscp), + .output_udp_ip_ecn(output_udp_ip_ecn), + .output_udp_ip_length(output_udp_ip_length), + .output_udp_ip_identification(output_udp_ip_identification), + .output_udp_ip_flags(output_udp_ip_flags), + .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_udp_ip_ttl(output_udp_ip_ttl), + .output_udp_ip_protocol(output_udp_ip_protocol), + .output_udp_ip_header_checksum(output_udp_ip_header_checksum), + .output_udp_ip_source_ip(output_udp_ip_source_ip), + .output_udp_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status signals + .rx_busy(rx_busy), + .tx_busy(tx_busy), + .rx_error_header_early_termination(rx_error_header_early_termination), + .rx_error_payload_early_termination(rx_error_payload_early_termination), + .tx_error_payload_early_termination(tx_error_payload_early_termination) +); + +endmodule diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py new file mode 100755 index 000000000..3b4e6d1c2 --- /dev/null +++ b/tb/test_udp_64.py @@ -0,0 +1,804 @@ +#!/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 eth_ep +import ip_ep +import udp_ep + +module = 'udp_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/udp_ip_rx_64.v") +srcs.append("../rtl/udp_ip_tx_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_eth_dest_mac, + input_ip_eth_src_mac, + input_ip_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_eth_dest_mac, + input_udp_eth_src_mac, + input_udp_eth_type, + input_udp_ip_version, + input_udp_ip_ihl, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_identification, + input_udp_ip_flags, + input_udp_ip_fragment_offset, + input_udp_ip_ttl, + input_udp_ip_protocol, + input_udp_ip_header_checksum, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + tx_error_payload_early_termination): + + 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_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_ip_eth_dest_mac=input_ip_eth_dest_mac, + input_ip_eth_src_mac=input_ip_eth_src_mac, + input_ip_eth_type=input_ip_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tkeep=input_ip_payload_tkeep, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_ip_eth_dest_mac=output_ip_eth_dest_mac, + output_ip_eth_src_mac=output_ip_eth_src_mac, + output_ip_eth_type=output_ip_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tkeep=output_ip_payload_tkeep, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + input_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_udp_eth_dest_mac=input_udp_eth_dest_mac, + input_udp_eth_src_mac=input_udp_eth_src_mac, + input_udp_eth_type=input_udp_eth_type, + input_udp_ip_version=input_udp_ip_version, + input_udp_ip_ihl=input_udp_ip_ihl, + input_udp_ip_dscp=input_udp_ip_dscp, + input_udp_ip_ecn=input_udp_ip_ecn, + input_udp_ip_identification=input_udp_ip_identification, + input_udp_ip_flags=input_udp_ip_flags, + input_udp_ip_fragment_offset=input_udp_ip_fragment_offset, + input_udp_ip_ttl=input_udp_ip_ttl, + input_udp_ip_protocol=input_udp_ip_protocol, + input_udp_ip_header_checksum=input_udp_ip_header_checksum, + input_udp_ip_source_ip=input_udp_ip_source_ip, + input_udp_ip_dest_ip=input_udp_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_length=input_udp_length, + input_udp_checksum=input_udp_checksum, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tkeep=input_udp_payload_tkeep, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_udp_eth_dest_mac=output_udp_eth_dest_mac, + output_udp_eth_src_mac=output_udp_eth_src_mac, + output_udp_eth_type=output_udp_eth_type, + output_udp_ip_version=output_udp_ip_version, + output_udp_ip_ihl=output_udp_ip_ihl, + output_udp_ip_dscp=output_udp_ip_dscp, + output_udp_ip_ecn=output_udp_ip_ecn, + output_udp_ip_length=output_udp_ip_length, + output_udp_ip_identification=output_udp_ip_identification, + output_udp_ip_flags=output_udp_ip_flags, + output_udp_ip_fragment_offset=output_udp_ip_fragment_offset, + output_udp_ip_ttl=output_udp_ip_ttl, + output_udp_ip_protocol=output_udp_ip_protocol, + output_udp_ip_header_checksum=output_udp_ip_header_checksum, + output_udp_ip_source_ip=output_udp_ip_source_ip, + output_udp_ip_dest_ip=output_udp_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tkeep=output_udp_payload_tkeep, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + rx_busy=rx_busy, + tx_busy=tx_busy, + rx_error_header_early_termination=rx_error_header_early_termination, + rx_error_payload_early_termination=rx_error_payload_early_termination, + tx_error_payload_early_termination=tx_error_payload_early_termination) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_ip_hdr_valid = Signal(bool(0)) + input_ip_eth_dest_mac = Signal(intbv(0)[48:]) + input_ip_eth_src_mac = Signal(intbv(0)[48:]) + input_ip_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[64:]) + input_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + input_udp_hdr_valid = Signal(bool(0)) + input_udp_eth_dest_mac = Signal(intbv(0)[48:]) + input_udp_eth_src_mac = Signal(intbv(0)[48:]) + input_udp_eth_type = Signal(intbv(0)[16:]) + input_udp_ip_version = Signal(intbv(0)[4:]) + input_udp_ip_ihl = Signal(intbv(0)[4:]) + input_udp_ip_dscp = Signal(intbv(0)[6:]) + input_udp_ip_ecn = Signal(intbv(0)[2:]) + input_udp_ip_identification = Signal(intbv(0)[16:]) + input_udp_ip_flags = Signal(intbv(0)[3:]) + input_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + input_udp_ip_ttl = Signal(intbv(0)[8:]) + input_udp_ip_protocol = Signal(intbv(0)[8:]) + input_udp_ip_header_checksum = Signal(intbv(0)[16:]) + input_udp_ip_source_ip = Signal(intbv(0)[32:]) + input_udp_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_length = Signal(intbv(0)[16:]) + input_udp_checksum = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[64:]) + input_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + output_udp_payload_tready = Signal(bool(0)) + + # Outputs + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_ip_eth_dest_mac = Signal(intbv(0)[48:]) + output_ip_eth_src_mac = Signal(intbv(0)[48:]) + output_ip_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[64:]) + output_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + output_udp_hdr_valid = Signal(bool(0)) + output_udp_eth_dest_mac = Signal(intbv(0)[48:]) + output_udp_eth_src_mac = Signal(intbv(0)[48:]) + output_udp_eth_type = Signal(intbv(0)[16:]) + output_udp_ip_version = Signal(intbv(0)[4:]) + output_udp_ip_ihl = Signal(intbv(0)[4:]) + output_udp_ip_dscp = Signal(intbv(0)[6:]) + output_udp_ip_ecn = Signal(intbv(0)[2:]) + output_udp_ip_length = Signal(intbv(0)[16:]) + output_udp_ip_identification = Signal(intbv(0)[16:]) + output_udp_ip_flags = Signal(intbv(0)[3:]) + output_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + output_udp_ip_ttl = Signal(intbv(0)[8:]) + output_udp_ip_protocol = Signal(intbv(0)[8:]) + output_udp_ip_header_checksum = Signal(intbv(0)[16:]) + output_udp_ip_source_ip = Signal(intbv(0)[32:]) + output_udp_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[64:]) + output_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + rx_busy = Signal(bool(0)) + tx_busy = Signal(bool(0)) + rx_error_header_early_termination = Signal(bool(0)) + rx_error_payload_early_termination = Signal(bool(0)) + tx_error_payload_early_termination = Signal(bool(0)) + + # sources and sinks + ip_source_queue = Queue() + ip_source_pause = Signal(bool(0)) + ip_sink_queue = Queue() + ip_sink_pause = Signal(bool(0)) + udp_source_queue = Queue() + udp_source_pause = Signal(bool(0)) + udp_sink_queue = Queue() + udp_sink_pause = Signal(bool(0)) + + ip_source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + eth_dest_mac=input_ip_eth_dest_mac, + eth_src_mac=input_ip_eth_src_mac, + eth_type=input_ip_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tkeep=input_ip_payload_tkeep, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=ip_source_queue, + pause=ip_source_pause, + name='ip_source') + + ip_sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_ip_eth_dest_mac, + eth_src_mac=output_ip_eth_src_mac, + eth_type=output_ip_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tkeep=output_ip_payload_tkeep, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=ip_sink_queue, + pause=ip_sink_pause, + name='ip_sink') + + udp_source = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_valid=input_udp_hdr_valid, + udp_hdr_ready=input_udp_hdr_ready, + eth_dest_mac=input_udp_eth_dest_mac, + eth_src_mac=input_udp_eth_src_mac, + eth_type=input_udp_eth_type, + ip_version=input_udp_ip_version, + ip_ihl=input_udp_ip_ihl, + ip_dscp=input_udp_ip_dscp, + ip_ecn=input_udp_ip_ecn, + ip_identification=input_udp_ip_identification, + ip_flags=input_udp_ip_flags, + ip_fragment_offset=input_udp_ip_fragment_offset, + ip_ttl=input_udp_ip_ttl, + ip_protocol=input_udp_ip_protocol, + ip_header_checksum=input_udp_ip_header_checksum, + ip_source_ip=input_udp_ip_source_ip, + ip_dest_ip=input_udp_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_length=input_udp_length, + udp_checksum=input_udp_checksum, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tkeep=input_udp_payload_tkeep, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + fifo=udp_source_queue, + pause=udp_source_pause, + name='udp_source') + + udp_sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_udp_eth_dest_mac, + eth_src_mac=output_udp_eth_src_mac, + eth_type=output_udp_eth_type, + ip_version=output_udp_ip_version, + ip_ihl=output_udp_ip_ihl, + ip_dscp=output_udp_ip_dscp, + ip_ecn=output_udp_ip_ecn, + ip_length=output_udp_ip_length, + ip_identification=output_udp_ip_identification, + ip_flags=output_udp_ip_flags, + ip_fragment_offset=output_udp_ip_fragment_offset, + ip_ttl=output_udp_ip_ttl, + ip_protocol=output_udp_ip_protocol, + ip_header_checksum=output_udp_ip_header_checksum, + ip_source_ip=output_udp_ip_source_ip, + ip_dest_ip=output_udp_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tkeep=output_udp_payload_tkeep, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=udp_sink_queue, + pause=udp_sink_pause, + name='udp_sink') + + # DUT + dut = dut_udp(clk, + rst, + current_test, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_eth_dest_mac, + input_ip_eth_src_mac, + input_ip_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_eth_dest_mac, + input_udp_eth_src_mac, + input_udp_eth_type, + input_udp_ip_version, + input_udp_ip_ihl, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_identification, + input_udp_ip_flags, + input_udp_ip_fragment_offset, + input_udp_ip_ttl, + input_udp_ip_protocol, + input_udp_ip_header_checksum, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + tx_error_payload_early_termination) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + rx_error_header_early_termination_asserted = Signal(bool(0)) + rx_error_payload_early_termination_asserted = Signal(bool(0)) + tx_error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_header_early_termination): + rx_error_header_early_termination_asserted.next = 1 + if (rx_error_payload_early_termination): + rx_error_payload_early_termination_asserted.next = 1 + if (tx_error_payload_early_termination): + tx_error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while (input_ip_payload_tvalid or input_udp_payload_tvalid or + output_ip_payload_tvalid or output_udp_payload_tvalid or + input_ip_hdr_valid or input_udp_hdr_valid): + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + ip_frame = test_frame.build_ip() + + ip_source_queue.put(ip_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not udp_sink_queue.empty(): + rx_frame = udp_sink_queue.get() + + assert rx_frame == test_frame + + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test UDP TX packet") + current_test.next = 2 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + udp_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not ip_sink_queue.empty(): + rx_frame = ip_sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_ip(rx_frame) + + assert check_frame == test_frame + + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, ip_source, ip_sink, udp_source, udp_sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_64.v b/tb/test_udp_64.v new file mode 100644 index 000000000..dbce9b8ce --- /dev/null +++ b/tb/test_udp_64.v @@ -0,0 +1,394 @@ +/* + +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_udp_64; + +// Parameters +parameter CHECKSUM_ENABLE = 0; +parameter CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11; +parameter CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_ip_hdr_valid = 0; +reg [47:0] input_ip_eth_dest_mac = 0; +reg [47:0] input_ip_eth_src_mac = 0; +reg [15:0] input_ip_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [63:0] input_ip_payload_tdata = 0; +reg [7:0] input_ip_payload_tkeep = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg input_udp_hdr_valid = 0; +reg [47:0] input_udp_eth_dest_mac = 0; +reg [47:0] input_udp_eth_src_mac = 0; +reg [15:0] input_udp_eth_type = 0; +reg [3:0] input_udp_ip_version = 0; +reg [3:0] input_udp_ip_ihl = 0; +reg [5:0] input_udp_ip_dscp = 0; +reg [1:0] input_udp_ip_ecn = 0; +reg [15:0] input_udp_ip_identification = 0; +reg [2:0] input_udp_ip_flags = 0; +reg [12:0] input_udp_ip_fragment_offset = 0; +reg [7:0] input_udp_ip_ttl = 0; +reg [7:0] input_udp_ip_protocol = 0; +reg [15:0] input_udp_ip_header_checksum = 0; +reg [31:0] input_udp_ip_source_ip = 0; +reg [31:0] input_udp_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [15:0] input_udp_length = 0; +reg [15:0] input_udp_checksum = 0; +reg [63:0] input_udp_payload_tdata = 0; +reg [7:0] input_udp_payload_tkeep = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; + +// Outputs +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire input_udp_hdr_ready; +wire input_udp_payload_tready; +wire output_ip_hdr_valid; +wire [47:0] output_ip_eth_dest_mac; +wire [47:0] output_ip_eth_src_mac; +wire [15:0] output_ip_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [63:0] output_ip_payload_tdata; +wire [7:0] output_ip_payload_tkeep; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire output_udp_hdr_valid; +wire [47:0] output_udp_eth_dest_mac; +wire [47:0] output_udp_eth_src_mac; +wire [15:0] output_udp_eth_type; +wire [3:0] output_udp_ip_version; +wire [3:0] output_udp_ip_ihl; +wire [5:0] output_udp_ip_dscp; +wire [1:0] output_udp_ip_ecn; +wire [15:0] output_udp_ip_length; +wire [15:0] output_udp_ip_identification; +wire [2:0] output_udp_ip_flags; +wire [12:0] output_udp_ip_fragment_offset; +wire [7:0] output_udp_ip_ttl; +wire [7:0] output_udp_ip_protocol; +wire [15:0] output_udp_ip_header_checksum; +wire [31:0] output_udp_ip_source_ip; +wire [31:0] output_udp_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [63:0] output_udp_payload_tdata; +wire [7:0] output_udp_payload_tkeep; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; +wire rx_busy; +wire tx_busy; +wire rx_error_header_early_termination; +wire rx_error_payload_early_termination; +wire tx_error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_ip_hdr_valid, + input_ip_eth_dest_mac, + input_ip_eth_src_mac, + input_ip_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_protocol, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + input_udp_hdr_valid, + input_udp_eth_dest_mac, + input_udp_eth_src_mac, + input_udp_eth_type, + input_udp_ip_version, + input_udp_ip_ihl, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_identification, + input_udp_ip_flags, + input_udp_ip_fragment_offset, + input_udp_ip_ttl, + input_udp_ip_protocol, + input_udp_ip_header_checksum, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_ip_hdr_ready, + output_ip_payload_tready, + output_udp_hdr_ready, + output_udp_payload_tready); + $to_myhdl(input_ip_hdr_ready, + input_ip_payload_tready, + input_udp_hdr_ready, + input_udp_payload_tready, + output_ip_hdr_valid, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + output_udp_hdr_valid, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser, + rx_busy, + tx_busy, + rx_error_header_early_termination, + rx_error_payload_early_termination, + tx_error_payload_early_termination); + + // dump file + $dumpfile("test_udp_64.lxt"); + $dumpvars(0, test_udp_64); +end + +udp_64 #( + .CHECKSUM_ENABLE(CHECKSUM_ENABLE), + .CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .CHECKSUM_HEADER_FIFO_ADDR_WIDTH(CHECKSUM_HEADER_FIFO_ADDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_eth_dest_mac(input_ip_eth_dest_mac), + .input_ip_eth_src_mac(input_ip_eth_src_mac), + .input_ip_eth_type(input_ip_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_udp_eth_dest_mac(input_udp_eth_dest_mac), + .input_udp_eth_src_mac(input_udp_eth_src_mac), + .input_udp_eth_type(input_udp_eth_type), + .input_udp_ip_version(input_udp_ip_version), + .input_udp_ip_ihl(input_udp_ip_ihl), + .input_udp_ip_dscp(input_udp_ip_dscp), + .input_udp_ip_ecn(input_udp_ip_ecn), + .input_udp_ip_identification(input_udp_ip_identification), + .input_udp_ip_flags(input_udp_ip_flags), + .input_udp_ip_fragment_offset(input_udp_ip_fragment_offset), + .input_udp_ip_ttl(input_udp_ip_ttl), + .input_udp_ip_protocol(input_udp_ip_protocol), + .input_udp_ip_header_checksum(input_udp_ip_header_checksum), + .input_udp_ip_source_ip(input_udp_ip_source_ip), + .input_udp_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tkeep(input_udp_payload_tkeep), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_udp_eth_dest_mac(output_udp_eth_dest_mac), + .output_udp_eth_src_mac(output_udp_eth_src_mac), + .output_udp_eth_type(output_udp_eth_type), + .output_udp_ip_version(output_udp_ip_version), + .output_udp_ip_ihl(output_udp_ip_ihl), + .output_udp_ip_dscp(output_udp_ip_dscp), + .output_udp_ip_ecn(output_udp_ip_ecn), + .output_udp_ip_length(output_udp_ip_length), + .output_udp_ip_identification(output_udp_ip_identification), + .output_udp_ip_flags(output_udp_ip_flags), + .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_udp_ip_ttl(output_udp_ip_ttl), + .output_udp_ip_protocol(output_udp_ip_protocol), + .output_udp_ip_header_checksum(output_udp_ip_header_checksum), + .output_udp_ip_source_ip(output_udp_ip_source_ip), + .output_udp_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status signals + .rx_busy(rx_busy), + .tx_busy(tx_busy), + .rx_error_header_early_termination(rx_error_header_early_termination), + .rx_error_payload_early_termination(rx_error_payload_early_termination), + .tx_error_payload_early_termination(tx_error_payload_early_termination) +); + +endmodule From b2ea1c8568b8f9e6293b7f261e21eb0cf12f9a16 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 21:41:51 -0800 Subject: [PATCH 149/617] Add parameters to ip_complete testbenches --- tb/test_ip_complete.v | 14 ++++++++++---- tb/test_ip_complete_64.v | 14 ++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/tb/test_ip_complete.v b/tb/test_ip_complete.v index dbbf40d20..ed1670ff6 100644 --- a/tb/test_ip_complete.v +++ b/tb/test_ip_complete.v @@ -28,6 +28,12 @@ THE SOFTWARE. module test_ip_complete; +// Parameters +parameter ARP_CACHE_ADDR_WIDTH = 2; +parameter ARP_REQUEST_RETRY_COUNT = 4; +parameter ARP_REQUEST_RETRY_INTERVAL = 150; +parameter ARP_REQUEST_TIMEOUT = 400; + // Inputs reg clk = 0; reg rst = 0; @@ -193,10 +199,10 @@ initial begin end ip_complete #( - .ARP_CACHE_ADDR_WIDTH(2), - .ARP_REQUEST_RETRY_COUNT(4), - .ARP_REQUEST_RETRY_INTERVAL(150), - .ARP_REQUEST_TIMEOUT(400) + .ARP_CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT) ) UUT ( .clk(clk), diff --git a/tb/test_ip_complete_64.v b/tb/test_ip_complete_64.v index 790c90cf3..d835efe45 100644 --- a/tb/test_ip_complete_64.v +++ b/tb/test_ip_complete_64.v @@ -28,6 +28,12 @@ THE SOFTWARE. module test_ip_complete_64; +// Parameters +parameter ARP_CACHE_ADDR_WIDTH = 2; +parameter ARP_REQUEST_RETRY_COUNT = 4; +parameter ARP_REQUEST_RETRY_INTERVAL = 150; +parameter ARP_REQUEST_TIMEOUT = 400; + // Inputs reg clk = 0; reg rst = 0; @@ -201,10 +207,10 @@ initial begin end ip_complete_64 #( - .ARP_CACHE_ADDR_WIDTH(2), - .ARP_REQUEST_RETRY_COUNT(4), - .ARP_REQUEST_RETRY_INTERVAL(150), - .ARP_REQUEST_TIMEOUT(400) + .ARP_CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT) ) UUT ( .clk(clk), From 10108d5d1a61682d196e47e6319885f5f1f187f1 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 22:05:07 -0800 Subject: [PATCH 150/617] Add 2 port IP mux components --- rtl/ip_arb_mux_2.v | 228 ++++++++++++++++++++ rtl/ip_arb_mux_64_2.v | 234 +++++++++++++++++++++ rtl/ip_mux_2.v | 457 ++++++++++++++++++++++++++++++++++++++++ rtl/ip_mux_64_2.v | 474 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1393 insertions(+) create mode 100644 rtl/ip_arb_mux_2.v create mode 100644 rtl/ip_arb_mux_64_2.v create mode 100644 rtl/ip_mux_2.v create mode 100644 rtl/ip_mux_64_2.v diff --git a/rtl/ip_arb_mux_2.v b/rtl/ip_arb_mux_2.v new file mode 100644 index 000000000..e1e980642 --- /dev/null +++ b/rtl/ip_arb_mux_2.v @@ -0,0 +1,228 @@ +/* + +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 + +/* + * IP 2 port arbitrated multiplexer + */ +module ip_arb_mux_2 # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ + input wire input_0_ip_hdr_valid, + output wire input_0_ip_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [7:0] input_0_ip_payload_tdata, + input wire input_0_ip_payload_tvalid, + output wire input_0_ip_payload_tready, + input wire input_0_ip_payload_tlast, + input wire input_0_ip_payload_tuser, + + input wire input_1_ip_hdr_valid, + output wire input_1_ip_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [7:0] input_1_ip_payload_tdata, + input wire input_1_ip_payload_tvalid, + output wire input_1_ip_payload_tready, + input wire input_1_ip_payload_tlast, + input wire input_1_ip_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser +); + +wire [1:0] request; +wire [1:0] acknowledge; +wire [1:0] grant; +wire grant_valid; +wire [0:0] grant_encoded; + +assign acknowledge[0] = input_0_ip_payload_tvalid & input_0_ip_payload_tready & input_0_ip_payload_tlast; +assign request[0] = input_0_ip_hdr_valid; +assign acknowledge[1] = input_1_ip_payload_tvalid & input_1_ip_payload_tready & input_1_ip_payload_tlast; +assign request[1] = input_1_ip_hdr_valid; + +// mux instance +ip_mux_2 +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_ip_hdr_valid(input_0_ip_hdr_valid & grant[0]), + .input_0_ip_hdr_ready(input_0_ip_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_ip_payload_tdata(input_0_ip_payload_tdata), + .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid & grant[0]), + .input_0_ip_payload_tready(input_0_ip_payload_tready), + .input_0_ip_payload_tlast(input_0_ip_payload_tlast), + .input_0_ip_payload_tuser(input_0_ip_payload_tuser), + .input_1_ip_hdr_valid(input_1_ip_hdr_valid & grant[1]), + .input_1_ip_hdr_ready(input_1_ip_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_ip_payload_tdata(input_1_ip_payload_tdata), + .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid & grant[1]), + .input_1_ip_payload_tready(input_1_ip_payload_tready), + .input_1_ip_payload_tlast(input_1_ip_payload_tlast), + .input_1_ip_payload_tuser(input_1_ip_payload_tuser), + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(2), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/rtl/ip_arb_mux_64_2.v b/rtl/ip_arb_mux_64_2.v new file mode 100644 index 000000000..f210eaba4 --- /dev/null +++ b/rtl/ip_arb_mux_64_2.v @@ -0,0 +1,234 @@ +/* + +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 + +/* + * IP 2 port arbitrated multiplexer (64 bit datapath) + */ +module ip_arb_mux_64_2 # +( + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ + input wire input_0_ip_hdr_valid, + output wire input_0_ip_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [63:0] input_0_ip_payload_tdata, + input wire [7:0] input_0_ip_payload_tkeep, + input wire input_0_ip_payload_tvalid, + output wire input_0_ip_payload_tready, + input wire input_0_ip_payload_tlast, + input wire input_0_ip_payload_tuser, + + input wire input_1_ip_hdr_valid, + output wire input_1_ip_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [63:0] input_1_ip_payload_tdata, + input wire [7:0] input_1_ip_payload_tkeep, + input wire input_1_ip_payload_tvalid, + output wire input_1_ip_payload_tready, + input wire input_1_ip_payload_tlast, + input wire input_1_ip_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser +); + +wire [1:0] request; +wire [1:0] acknowledge; +wire [1:0] grant; +wire grant_valid; +wire [0:0] grant_encoded; + +assign acknowledge[0] = input_0_ip_payload_tvalid & input_0_ip_payload_tready & input_0_ip_payload_tlast; +assign request[0] = input_0_ip_hdr_valid; +assign acknowledge[1] = input_1_ip_payload_tvalid & input_1_ip_payload_tready & input_1_ip_payload_tlast; +assign request[1] = input_1_ip_hdr_valid; + +// mux instance +ip_mux_64_2 +mux_inst ( + .clk(clk), + .rst(rst), + .input_0_ip_hdr_valid(input_0_ip_hdr_valid & grant[0]), + .input_0_ip_hdr_ready(input_0_ip_hdr_ready), + .input_0_eth_dest_mac(input_0_eth_dest_mac), + .input_0_eth_src_mac(input_0_eth_src_mac), + .input_0_eth_type(input_0_eth_type), + .input_0_ip_version(input_0_ip_version), + .input_0_ip_ihl(input_0_ip_ihl), + .input_0_ip_dscp(input_0_ip_dscp), + .input_0_ip_ecn(input_0_ip_ecn), + .input_0_ip_length(input_0_ip_length), + .input_0_ip_identification(input_0_ip_identification), + .input_0_ip_flags(input_0_ip_flags), + .input_0_ip_fragment_offset(input_0_ip_fragment_offset), + .input_0_ip_ttl(input_0_ip_ttl), + .input_0_ip_protocol(input_0_ip_protocol), + .input_0_ip_header_checksum(input_0_ip_header_checksum), + .input_0_ip_source_ip(input_0_ip_source_ip), + .input_0_ip_dest_ip(input_0_ip_dest_ip), + .input_0_ip_payload_tdata(input_0_ip_payload_tdata), + .input_0_ip_payload_tkeep(input_0_ip_payload_tkeep), + .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid & grant[0]), + .input_0_ip_payload_tready(input_0_ip_payload_tready), + .input_0_ip_payload_tlast(input_0_ip_payload_tlast), + .input_0_ip_payload_tuser(input_0_ip_payload_tuser), + .input_1_ip_hdr_valid(input_1_ip_hdr_valid & grant[1]), + .input_1_ip_hdr_ready(input_1_ip_hdr_ready), + .input_1_eth_dest_mac(input_1_eth_dest_mac), + .input_1_eth_src_mac(input_1_eth_src_mac), + .input_1_eth_type(input_1_eth_type), + .input_1_ip_version(input_1_ip_version), + .input_1_ip_ihl(input_1_ip_ihl), + .input_1_ip_dscp(input_1_ip_dscp), + .input_1_ip_ecn(input_1_ip_ecn), + .input_1_ip_length(input_1_ip_length), + .input_1_ip_identification(input_1_ip_identification), + .input_1_ip_flags(input_1_ip_flags), + .input_1_ip_fragment_offset(input_1_ip_fragment_offset), + .input_1_ip_ttl(input_1_ip_ttl), + .input_1_ip_protocol(input_1_ip_protocol), + .input_1_ip_header_checksum(input_1_ip_header_checksum), + .input_1_ip_source_ip(input_1_ip_source_ip), + .input_1_ip_dest_ip(input_1_ip_dest_ip), + .input_1_ip_payload_tdata(input_1_ip_payload_tdata), + .input_1_ip_payload_tkeep(input_1_ip_payload_tkeep), + .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid & grant[1]), + .input_1_ip_payload_tready(input_1_ip_payload_tready), + .input_1_ip_payload_tlast(input_1_ip_payload_tlast), + .input_1_ip_payload_tuser(input_1_ip_payload_tuser), + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + .enable(grant_valid), + .select(grant_encoded) +); + +// arbiter instance +arbiter #( + .PORTS(2), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +endmodule diff --git a/rtl/ip_mux_2.v b/rtl/ip_mux_2.v new file mode 100644 index 000000000..5ad0fa6fa --- /dev/null +++ b/rtl/ip_mux_2.v @@ -0,0 +1,457 @@ +/* + +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 + +/* + * IP 2 port multiplexer + */ +module ip_mux_2 +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ + input wire input_0_ip_hdr_valid, + output wire input_0_ip_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [7:0] input_0_ip_payload_tdata, + input wire input_0_ip_payload_tvalid, + output wire input_0_ip_payload_tready, + input wire input_0_ip_payload_tlast, + input wire input_0_ip_payload_tuser, + + input wire input_1_ip_hdr_valid, + output wire input_1_ip_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [7:0] input_1_ip_payload_tdata, + input wire input_1_ip_payload_tvalid, + output wire input_1_ip_payload_tready, + input wire input_1_ip_payload_tlast, + input wire input_1_ip_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [0:0] select +); + +reg [0:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_ip_hdr_ready_reg = 0, input_0_ip_hdr_ready_next; +reg input_1_ip_hdr_ready_reg = 0, input_1_ip_hdr_ready_next; + +reg input_0_ip_payload_tready_reg = 0, input_0_ip_payload_tready_next; +reg input_1_ip_payload_tready_reg = 0, input_1_ip_payload_tready_next; + +reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; + +// internal datapath +reg [7:0] output_ip_payload_tdata_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; + +assign input_0_ip_hdr_ready = input_0_ip_hdr_ready_reg; +assign input_1_ip_hdr_ready = input_1_ip_hdr_ready_reg; + +assign input_0_ip_payload_tready = input_0_ip_payload_tready_reg; +assign input_1_ip_payload_tready = input_1_ip_payload_tready_reg; + +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; + +// mux for start of packet detection +reg selected_input_ip_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +reg [3:0] selected_input_ip_version; +reg [3:0] selected_input_ip_ihl; +reg [5:0] selected_input_ip_dscp; +reg [1:0] selected_input_ip_ecn; +reg [15:0] selected_input_ip_length; +reg [15:0] selected_input_ip_identification; +reg [2:0] selected_input_ip_flags; +reg [12:0] selected_input_ip_fragment_offset; +reg [7:0] selected_input_ip_ttl; +reg [7:0] selected_input_ip_protocol; +reg [15:0] selected_input_ip_header_checksum; +reg [31:0] selected_input_ip_source_ip; +reg [31:0] selected_input_ip_dest_ip; +always @* begin + case (select) + 1'd0: begin + selected_input_ip_hdr_valid = input_0_ip_hdr_valid; + selected_input_eth_dest_mac = input_0_eth_dest_mac; + selected_input_eth_src_mac = input_0_eth_src_mac; + selected_input_eth_type = input_0_eth_type; + selected_input_ip_version = input_0_ip_version; + selected_input_ip_ihl = input_0_ip_ihl; + selected_input_ip_dscp = input_0_ip_dscp; + selected_input_ip_ecn = input_0_ip_ecn; + selected_input_ip_length = input_0_ip_length; + selected_input_ip_identification = input_0_ip_identification; + selected_input_ip_flags = input_0_ip_flags; + selected_input_ip_fragment_offset = input_0_ip_fragment_offset; + selected_input_ip_ttl = input_0_ip_ttl; + selected_input_ip_protocol = input_0_ip_protocol; + selected_input_ip_header_checksum = input_0_ip_header_checksum; + selected_input_ip_source_ip = input_0_ip_source_ip; + selected_input_ip_dest_ip = input_0_ip_dest_ip; + end + 1'd1: begin + selected_input_ip_hdr_valid = input_1_ip_hdr_valid; + selected_input_eth_dest_mac = input_1_eth_dest_mac; + selected_input_eth_src_mac = input_1_eth_src_mac; + selected_input_eth_type = input_1_eth_type; + selected_input_ip_version = input_1_ip_version; + selected_input_ip_ihl = input_1_ip_ihl; + selected_input_ip_dscp = input_1_ip_dscp; + selected_input_ip_ecn = input_1_ip_ecn; + selected_input_ip_length = input_1_ip_length; + selected_input_ip_identification = input_1_ip_identification; + selected_input_ip_flags = input_1_ip_flags; + selected_input_ip_fragment_offset = input_1_ip_fragment_offset; + selected_input_ip_ttl = input_1_ip_ttl; + selected_input_ip_protocol = input_1_ip_protocol; + selected_input_ip_header_checksum = input_1_ip_header_checksum; + selected_input_ip_source_ip = input_1_ip_source_ip; + selected_input_ip_dest_ip = input_1_ip_dest_ip; + end + endcase +end + +// mux for incoming packet +reg [7:0] current_input_tdata; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 1'd0: begin + current_input_tdata = input_0_ip_payload_tdata; + current_input_tvalid = input_0_ip_payload_tvalid; + current_input_tready = input_0_ip_payload_tready; + current_input_tlast = input_0_ip_payload_tlast; + current_input_tuser = input_0_ip_payload_tuser; + end + 1'd1: begin + current_input_tdata = input_1_ip_payload_tdata; + current_input_tvalid = input_1_ip_payload_tvalid; + current_input_tready = input_1_ip_payload_tready; + current_input_tlast = input_1_ip_payload_tlast; + current_input_tuser = input_1_ip_payload_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_ip_hdr_ready_next = input_0_ip_hdr_ready_reg & ~input_0_ip_hdr_valid; + input_1_ip_hdr_ready_next = input_1_ip_hdr_ready_reg & ~input_1_ip_hdr_valid; + + input_0_ip_payload_tready_next = 0; + input_1_ip_payload_tready_next = 0; + + output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) + 1'd0: input_0_ip_hdr_ready_next = 1; + 1'd1: input_1_ip_hdr_ready_next = 1; + endcase + + output_ip_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + output_ip_version_next = selected_input_ip_version; + output_ip_ihl_next = selected_input_ip_ihl; + output_ip_dscp_next = selected_input_ip_dscp; + output_ip_ecn_next = selected_input_ip_ecn; + output_ip_length_next = selected_input_ip_length; + output_ip_identification_next = selected_input_ip_identification; + output_ip_flags_next = selected_input_ip_flags; + output_ip_fragment_offset_next = selected_input_ip_fragment_offset; + output_ip_ttl_next = selected_input_ip_ttl; + output_ip_protocol_next = selected_input_ip_protocol; + output_ip_header_checksum_next = selected_input_ip_header_checksum; + output_ip_source_ip_next = selected_input_ip_source_ip; + output_ip_dest_ip_next = selected_input_ip_dest_ip; + end + + // generate ready signal on selected port + case (select_next) + 1'd0: input_0_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + 1'd1: input_1_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + endcase + + // pass through selected packet data + output_ip_payload_tdata_int = current_input_tdata; + output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_ip_payload_tlast_int = current_input_tlast; + output_ip_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_ip_hdr_ready_reg <= 0; + input_1_ip_hdr_ready_reg <= 0; + input_0_ip_payload_tready_reg <= 0; + input_1_ip_payload_tready_reg <= 0; + output_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_ip_hdr_ready_reg <= input_0_ip_hdr_ready_next; + input_1_ip_hdr_ready_reg <= input_1_ip_hdr_ready_next; + input_0_ip_payload_tready_reg <= input_0_ip_payload_tready_next; + input_1_ip_payload_tready_reg <= input_1_ip_payload_tready_next; + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + end +end + +// output datapath logic +reg [7:0] output_ip_payload_tdata_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [7:0] temp_ip_payload_tdata_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/ip_mux_64_2.v b/rtl/ip_mux_64_2.v new file mode 100644 index 000000000..f5f479702 --- /dev/null +++ b/rtl/ip_mux_64_2.v @@ -0,0 +1,474 @@ +/* + +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 + +/* + * IP 2 port multiplexer (64 bit datapath) + */ +module ip_mux_64_2 +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ + input wire input_0_ip_hdr_valid, + output wire input_0_ip_hdr_ready, + input wire [47:0] input_0_eth_dest_mac, + input wire [47:0] input_0_eth_src_mac, + input wire [15:0] input_0_eth_type, + input wire [3:0] input_0_ip_version, + input wire [3:0] input_0_ip_ihl, + input wire [5:0] input_0_ip_dscp, + input wire [1:0] input_0_ip_ecn, + input wire [15:0] input_0_ip_length, + input wire [15:0] input_0_ip_identification, + input wire [2:0] input_0_ip_flags, + input wire [12:0] input_0_ip_fragment_offset, + input wire [7:0] input_0_ip_ttl, + input wire [7:0] input_0_ip_protocol, + input wire [15:0] input_0_ip_header_checksum, + input wire [31:0] input_0_ip_source_ip, + input wire [31:0] input_0_ip_dest_ip, + input wire [63:0] input_0_ip_payload_tdata, + input wire [7:0] input_0_ip_payload_tkeep, + input wire input_0_ip_payload_tvalid, + output wire input_0_ip_payload_tready, + input wire input_0_ip_payload_tlast, + input wire input_0_ip_payload_tuser, + + input wire input_1_ip_hdr_valid, + output wire input_1_ip_hdr_ready, + input wire [47:0] input_1_eth_dest_mac, + input wire [47:0] input_1_eth_src_mac, + input wire [15:0] input_1_eth_type, + input wire [3:0] input_1_ip_version, + input wire [3:0] input_1_ip_ihl, + input wire [5:0] input_1_ip_dscp, + input wire [1:0] input_1_ip_ecn, + input wire [15:0] input_1_ip_length, + input wire [15:0] input_1_ip_identification, + input wire [2:0] input_1_ip_flags, + input wire [12:0] input_1_ip_fragment_offset, + input wire [7:0] input_1_ip_ttl, + input wire [7:0] input_1_ip_protocol, + input wire [15:0] input_1_ip_header_checksum, + input wire [31:0] input_1_ip_source_ip, + input wire [31:0] input_1_ip_dest_ip, + input wire [63:0] input_1_ip_payload_tdata, + input wire [7:0] input_1_ip_payload_tkeep, + input wire input_1_ip_payload_tvalid, + output wire input_1_ip_payload_tready, + input wire input_1_ip_payload_tlast, + input wire input_1_ip_payload_tuser, + + /* + * IP frame output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * Control + */ + input wire enable, + input wire [0:0] select +); + +reg [0:0] select_reg = 0, select_next; +reg frame_reg = 0, frame_next; + +reg input_0_ip_hdr_ready_reg = 0, input_0_ip_hdr_ready_next; +reg input_1_ip_hdr_ready_reg = 0, input_1_ip_hdr_ready_next; + +reg input_0_ip_payload_tready_reg = 0, input_0_ip_payload_tready_next; +reg input_1_ip_payload_tready_reg = 0, input_1_ip_payload_tready_next; + +reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; + +// internal datapath +reg [63:0] output_ip_payload_tdata_int; +reg [7:0] output_ip_payload_tkeep_int; +reg output_ip_payload_tvalid_int; +reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tlast_int; +reg output_ip_payload_tuser_int; +wire output_ip_payload_tready_int_early; + +assign input_0_ip_hdr_ready = input_0_ip_hdr_ready_reg; +assign input_1_ip_hdr_ready = input_1_ip_hdr_ready_reg; + +assign input_0_ip_payload_tready = input_0_ip_payload_tready_reg; +assign input_1_ip_payload_tready = input_1_ip_payload_tready_reg; + +assign output_ip_hdr_valid = output_ip_hdr_valid_reg; +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_ip_length_reg; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = output_ip_protocol_reg; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; + +// mux for start of packet detection +reg selected_input_ip_hdr_valid; +reg [47:0] selected_input_eth_dest_mac; +reg [47:0] selected_input_eth_src_mac; +reg [15:0] selected_input_eth_type; +reg [3:0] selected_input_ip_version; +reg [3:0] selected_input_ip_ihl; +reg [5:0] selected_input_ip_dscp; +reg [1:0] selected_input_ip_ecn; +reg [15:0] selected_input_ip_length; +reg [15:0] selected_input_ip_identification; +reg [2:0] selected_input_ip_flags; +reg [12:0] selected_input_ip_fragment_offset; +reg [7:0] selected_input_ip_ttl; +reg [7:0] selected_input_ip_protocol; +reg [15:0] selected_input_ip_header_checksum; +reg [31:0] selected_input_ip_source_ip; +reg [31:0] selected_input_ip_dest_ip; +always @* begin + case (select) + 1'd0: begin + selected_input_ip_hdr_valid = input_0_ip_hdr_valid; + selected_input_eth_dest_mac = input_0_eth_dest_mac; + selected_input_eth_src_mac = input_0_eth_src_mac; + selected_input_eth_type = input_0_eth_type; + selected_input_ip_version = input_0_ip_version; + selected_input_ip_ihl = input_0_ip_ihl; + selected_input_ip_dscp = input_0_ip_dscp; + selected_input_ip_ecn = input_0_ip_ecn; + selected_input_ip_length = input_0_ip_length; + selected_input_ip_identification = input_0_ip_identification; + selected_input_ip_flags = input_0_ip_flags; + selected_input_ip_fragment_offset = input_0_ip_fragment_offset; + selected_input_ip_ttl = input_0_ip_ttl; + selected_input_ip_protocol = input_0_ip_protocol; + selected_input_ip_header_checksum = input_0_ip_header_checksum; + selected_input_ip_source_ip = input_0_ip_source_ip; + selected_input_ip_dest_ip = input_0_ip_dest_ip; + end + 1'd1: begin + selected_input_ip_hdr_valid = input_1_ip_hdr_valid; + selected_input_eth_dest_mac = input_1_eth_dest_mac; + selected_input_eth_src_mac = input_1_eth_src_mac; + selected_input_eth_type = input_1_eth_type; + selected_input_ip_version = input_1_ip_version; + selected_input_ip_ihl = input_1_ip_ihl; + selected_input_ip_dscp = input_1_ip_dscp; + selected_input_ip_ecn = input_1_ip_ecn; + selected_input_ip_length = input_1_ip_length; + selected_input_ip_identification = input_1_ip_identification; + selected_input_ip_flags = input_1_ip_flags; + selected_input_ip_fragment_offset = input_1_ip_fragment_offset; + selected_input_ip_ttl = input_1_ip_ttl; + selected_input_ip_protocol = input_1_ip_protocol; + selected_input_ip_header_checksum = input_1_ip_header_checksum; + selected_input_ip_source_ip = input_1_ip_source_ip; + selected_input_ip_dest_ip = input_1_ip_dest_ip; + end + endcase +end + +// mux for incoming packet +reg [63:0] current_input_tdata; +reg [7:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg current_input_tuser; +always @* begin + case (select_reg) + 1'd0: begin + current_input_tdata = input_0_ip_payload_tdata; + current_input_tkeep = input_0_ip_payload_tkeep; + current_input_tvalid = input_0_ip_payload_tvalid; + current_input_tready = input_0_ip_payload_tready; + current_input_tlast = input_0_ip_payload_tlast; + current_input_tuser = input_0_ip_payload_tuser; + end + 1'd1: begin + current_input_tdata = input_1_ip_payload_tdata; + current_input_tkeep = input_1_ip_payload_tkeep; + current_input_tvalid = input_1_ip_payload_tvalid; + current_input_tready = input_1_ip_payload_tready; + current_input_tlast = input_1_ip_payload_tlast; + current_input_tuser = input_1_ip_payload_tuser; + end + endcase +end + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + input_0_ip_hdr_ready_next = input_0_ip_hdr_ready_reg & ~input_0_ip_hdr_valid; + input_1_ip_hdr_ready_next = input_1_ip_hdr_ready_reg & ~input_1_ip_hdr_valid; + + input_0_ip_payload_tready_next = 0; + input_1_ip_payload_tready_next = 0; + + output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + output_eth_dest_mac_next = output_eth_dest_mac_reg; + output_eth_src_mac_next = output_eth_src_mac_reg; + output_eth_type_next = output_eth_type_reg; + output_ip_version_next = output_ip_version_reg; + output_ip_ihl_next = output_ip_ihl_reg; + output_ip_dscp_next = output_ip_dscp_reg; + output_ip_ecn_next = output_ip_ecn_reg; + output_ip_length_next = output_ip_length_reg; + output_ip_identification_next = output_ip_identification_reg; + output_ip_flags_next = output_ip_flags_reg; + output_ip_fragment_offset_next = output_ip_fragment_offset_reg; + output_ip_ttl_next = output_ip_ttl_reg; + output_ip_protocol_next = output_ip_protocol_reg; + output_ip_header_checksum_next = output_ip_header_checksum_reg; + output_ip_source_ip_next = output_ip_source_ip_reg; + output_ip_dest_ip_next = output_ip_dest_ip_reg; + + if (frame_reg) begin + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + frame_next = ~current_input_tlast; + end + end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + // start of frame, grab select value + frame_next = 1; + select_next = select; + + case (select_next) + 1'd0: input_0_ip_hdr_ready_next = 1; + 1'd1: input_1_ip_hdr_ready_next = 1; + endcase + + output_ip_hdr_valid_next = 1; + output_eth_dest_mac_next = selected_input_eth_dest_mac; + output_eth_src_mac_next = selected_input_eth_src_mac; + output_eth_type_next = selected_input_eth_type; + output_ip_version_next = selected_input_ip_version; + output_ip_ihl_next = selected_input_ip_ihl; + output_ip_dscp_next = selected_input_ip_dscp; + output_ip_ecn_next = selected_input_ip_ecn; + output_ip_length_next = selected_input_ip_length; + output_ip_identification_next = selected_input_ip_identification; + output_ip_flags_next = selected_input_ip_flags; + output_ip_fragment_offset_next = selected_input_ip_fragment_offset; + output_ip_ttl_next = selected_input_ip_ttl; + output_ip_protocol_next = selected_input_ip_protocol; + output_ip_header_checksum_next = selected_input_ip_header_checksum; + output_ip_source_ip_next = selected_input_ip_source_ip; + output_ip_dest_ip_next = selected_input_ip_dest_ip; + end + + // generate ready signal on selected port + case (select_next) + 1'd0: input_0_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + 1'd1: input_1_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; + endcase + + // pass through selected packet data + output_ip_payload_tdata_int = current_input_tdata; + output_ip_payload_tkeep_int = current_input_tkeep; + output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; + output_ip_payload_tlast_int = current_input_tlast; + output_ip_payload_tuser_int = current_input_tuser; +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 0; + input_0_ip_hdr_ready_reg <= 0; + input_1_ip_hdr_ready_reg <= 0; + input_0_ip_payload_tready_reg <= 0; + input_1_ip_payload_tready_reg <= 0; + output_ip_hdr_valid_reg <= 0; + output_eth_dest_mac_reg <= 0; + output_eth_src_mac_reg <= 0; + output_eth_type_reg <= 0; + output_ip_version_reg <= 0; + output_ip_ihl_reg <= 0; + output_ip_dscp_reg <= 0; + output_ip_ecn_reg <= 0; + output_ip_length_reg <= 0; + output_ip_identification_reg <= 0; + output_ip_flags_reg <= 0; + output_ip_fragment_offset_reg <= 0; + output_ip_ttl_reg <= 0; + output_ip_protocol_reg <= 0; + output_ip_header_checksum_reg <= 0; + output_ip_source_ip_reg <= 0; + output_ip_dest_ip_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + input_0_ip_hdr_ready_reg <= input_0_ip_hdr_ready_next; + input_1_ip_hdr_ready_reg <= input_1_ip_hdr_ready_next; + input_0_ip_payload_tready_reg <= input_0_ip_payload_tready_next; + input_1_ip_payload_tready_reg <= input_1_ip_payload_tready_next; + output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + end +end + +// output datapath logic +reg [63:0] output_ip_payload_tdata_reg = 0; +reg [7:0] output_ip_payload_tkeep_reg = 0; +reg output_ip_payload_tvalid_reg = 0; +reg output_ip_payload_tlast_reg = 0; +reg output_ip_payload_tuser_reg = 0; + +reg [63:0] temp_ip_payload_tdata_reg = 0; +reg [7:0] temp_ip_payload_tkeep_reg = 0; +reg temp_ip_payload_tvalid_reg = 0; +reg temp_ip_payload_tlast_reg = 0; +reg temp_ip_payload_tuser_reg = 0; + +assign output_ip_payload_tdata = output_ip_payload_tdata_reg; +assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; +assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; +assign output_ip_payload_tlast = output_ip_payload_tlast_reg; +assign output_ip_payload_tuser = output_ip_payload_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_ip_payload_tdata_reg <= 0; + output_ip_payload_tkeep_reg <= 0; + output_ip_payload_tvalid_reg <= 0; + output_ip_payload_tlast_reg <= 0; + output_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int <= 0; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + + if (output_ip_payload_tready_int) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + temp_ip_payload_tdata_reg <= 0; + temp_ip_payload_tkeep_reg <= 0; + temp_ip_payload_tvalid_reg <= 0; + temp_ip_payload_tlast_reg <= 0; + temp_ip_payload_tuser_reg <= 0; + end + end +end + +endmodule From 27f319b91ebe5794935bbebdd2771ead29ab74a2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 22:36:05 -0800 Subject: [PATCH 151/617] Fix UDP EP parse_eth --- tb/udp_ep.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tb/udp_ep.py b/tb/udp_ep.py index d0f6d2050..95412139f 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -239,7 +239,7 @@ class UDPFrame(object): def parse_eth(self, data): frame = ip_ep.IPFrame() frame.parse_eth(data) - self.parse_ip(data) + self.parse_ip(frame) def parse_ip(self, data): self.eth_src_mac = data.eth_src_mac From 635f05e9c6050d5ac2162bf92bb1acffc1310abe Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 22:37:40 -0800 Subject: [PATCH 152/617] Remove udp_ip_protocol input --- rtl/udp.v | 10 +++------- rtl/udp_64.v | 9 ++------- tb/test_udp.py | 5 ----- tb/test_udp.v | 3 --- tb/test_udp_64.py | 5 ----- tb/test_udp_64.v | 3 --- 6 files changed, 5 insertions(+), 30 deletions(-) diff --git a/rtl/udp.v b/rtl/udp.v index 22b0a0a28..24ed0ab22 100644 --- a/rtl/udp.v +++ b/rtl/udp.v @@ -109,7 +109,6 @@ module udp # input wire [2:0] input_udp_ip_flags, input wire [12:0] input_udp_ip_fragment_offset, input wire [7:0] input_udp_ip_ttl, - input wire [7:0] input_udp_ip_protocol, input wire [15:0] input_udp_ip_header_checksum, input wire [31:0] input_udp_ip_source_ip, input wire [31:0] input_udp_ip_dest_ip, @@ -177,7 +176,6 @@ wire [15:0] tx_udp_ip_identification; wire [2:0] tx_udp_ip_flags; wire [12:0] tx_udp_ip_fragment_offset; wire [7:0] tx_udp_ip_ttl; -wire [7:0] tx_udp_ip_protocol; wire [15:0] tx_udp_ip_header_checksum; wire [31:0] tx_udp_ip_source_ip; wire [31:0] tx_udp_ip_dest_ip; @@ -278,13 +276,12 @@ if (CHECKSUM_ENABLE) begin .input_ip_flags(input_udp_ip_flags), .input_ip_fragment_offset(input_udp_ip_fragment_offset), .input_ip_ttl(input_udp_ip_ttl), - .input_ip_protocol(input_udp_ip_protocol), + .input_ip_protocol(0), .input_ip_header_checksum(input_udp_ip_header_checksum), .input_ip_source_ip(input_udp_ip_source_ip), .input_ip_dest_ip(input_udp_ip_dest_ip), .input_udp_source_port(input_udp_source_port), .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), .input_udp_checksum(input_udp_checksum), .input_udp_payload_tdata(input_udp_payload_tdata), .input_udp_payload_tvalid(input_udp_payload_tvalid), @@ -306,7 +303,7 @@ if (CHECKSUM_ENABLE) begin .output_ip_flags(tx_udp_ip_flags), .output_ip_fragment_offset(tx_udp_ip_fragment_offset), .output_ip_ttl(tx_udp_ip_ttl), - .output_ip_protocol(tx_udp_ip_protocol), + .output_ip_protocol(), .output_ip_header_checksum(tx_udp_ip_header_checksum), .output_ip_source_ip(tx_udp_ip_source_ip), .output_ip_dest_ip(tx_udp_ip_dest_ip), @@ -336,7 +333,6 @@ end else begin assign tx_udp_ip_flags = input_udp_ip_flags; assign tx_udp_ip_fragment_offset = input_udp_ip_fragment_offset; assign tx_udp_ip_ttl = input_udp_ip_ttl; - assign tx_udp_ip_protocol = input_udp_ip_protocol; assign tx_udp_ip_header_checksum = input_udp_ip_header_checksum; assign tx_udp_ip_source_ip = input_udp_ip_source_ip; assign tx_udp_ip_dest_ip = input_udp_ip_dest_ip; @@ -372,7 +368,7 @@ udp_ip_tx_inst ( .input_ip_flags(tx_udp_ip_flags), .input_ip_fragment_offset(tx_udp_ip_fragment_offset), .input_ip_ttl(tx_udp_ip_ttl), - .input_ip_protocol(tx_udp_ip_protocol), + .input_ip_protocol(8'h11), .input_ip_header_checksum(tx_udp_ip_header_checksum), .input_ip_source_ip(tx_udp_ip_source_ip), .input_ip_dest_ip(tx_udp_ip_dest_ip), diff --git a/rtl/udp_64.v b/rtl/udp_64.v index f90d53347..c0c90ea4b 100644 --- a/rtl/udp_64.v +++ b/rtl/udp_64.v @@ -111,7 +111,6 @@ module udp_64 # input wire [2:0] input_udp_ip_flags, input wire [12:0] input_udp_ip_fragment_offset, input wire [7:0] input_udp_ip_ttl, - input wire [7:0] input_udp_ip_protocol, input wire [15:0] input_udp_ip_header_checksum, input wire [31:0] input_udp_ip_source_ip, input wire [31:0] input_udp_ip_dest_ip, @@ -181,7 +180,6 @@ wire [15:0] tx_udp_ip_identification; wire [2:0] tx_udp_ip_flags; wire [12:0] tx_udp_ip_fragment_offset; wire [7:0] tx_udp_ip_ttl; -wire [7:0] tx_udp_ip_protocol; wire [15:0] tx_udp_ip_header_checksum; wire [31:0] tx_udp_ip_source_ip; wire [31:0] tx_udp_ip_dest_ip; @@ -285,13 +283,12 @@ if (CHECKSUM_ENABLE) begin .input_ip_flags(input_udp_ip_flags), .input_ip_fragment_offset(input_udp_ip_fragment_offset), .input_ip_ttl(input_udp_ip_ttl), - .input_ip_protocol(input_udp_ip_protocol), + .input_ip_protocol(0), .input_ip_header_checksum(input_udp_ip_header_checksum), .input_ip_source_ip(input_udp_ip_source_ip), .input_ip_dest_ip(input_udp_ip_dest_ip), .input_udp_source_port(input_udp_source_port), .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), .input_udp_checksum(input_udp_checksum), .input_udp_payload_tdata(input_udp_payload_tdata), .input_udp_payload_tkeep(input_udp_payload_tkeep), @@ -314,7 +311,6 @@ if (CHECKSUM_ENABLE) begin .output_ip_flags(tx_udp_ip_flags), .output_ip_fragment_offset(tx_udp_ip_fragment_offset), .output_ip_ttl(tx_udp_ip_ttl), - .output_ip_protocol(tx_udp_ip_protocol), .output_ip_header_checksum(tx_udp_ip_header_checksum), .output_ip_source_ip(tx_udp_ip_source_ip), .output_ip_dest_ip(tx_udp_ip_dest_ip), @@ -345,7 +341,6 @@ end else begin assign tx_udp_ip_flags = input_udp_ip_flags; assign tx_udp_ip_fragment_offset = input_udp_ip_fragment_offset; assign tx_udp_ip_ttl = input_udp_ip_ttl; - assign tx_udp_ip_protocol = input_udp_ip_protocol; assign tx_udp_ip_header_checksum = input_udp_ip_header_checksum; assign tx_udp_ip_source_ip = input_udp_ip_source_ip; assign tx_udp_ip_dest_ip = input_udp_ip_dest_ip; @@ -382,7 +377,7 @@ udp_ip_tx_64_inst ( .input_ip_flags(tx_udp_ip_flags), .input_ip_fragment_offset(tx_udp_ip_fragment_offset), .input_ip_ttl(tx_udp_ip_ttl), - .input_ip_protocol(tx_udp_ip_protocol), + .input_ip_protocol(8'h11), .input_ip_header_checksum(tx_udp_ip_header_checksum), .input_ip_source_ip(tx_udp_ip_source_ip), .input_ip_dest_ip(tx_udp_ip_dest_ip), diff --git a/tb/test_udp.py b/tb/test_udp.py index 5f1760b07..9f56e2bd0 100755 --- a/tb/test_udp.py +++ b/tb/test_udp.py @@ -109,7 +109,6 @@ def dut_udp(clk, input_udp_ip_flags, input_udp_ip_fragment_offset, input_udp_ip_ttl, - input_udp_ip_protocol, input_udp_ip_header_checksum, input_udp_ip_source_ip, input_udp_ip_dest_ip, @@ -225,7 +224,6 @@ def dut_udp(clk, input_udp_ip_flags=input_udp_ip_flags, input_udp_ip_fragment_offset=input_udp_ip_fragment_offset, input_udp_ip_ttl=input_udp_ip_ttl, - input_udp_ip_protocol=input_udp_ip_protocol, input_udp_ip_header_checksum=input_udp_ip_header_checksum, input_udp_ip_source_ip=input_udp_ip_source_ip, input_udp_ip_dest_ip=input_udp_ip_dest_ip, @@ -313,7 +311,6 @@ def bench(): input_udp_ip_flags = Signal(intbv(0)[3:]) input_udp_ip_fragment_offset = Signal(intbv(0)[13:]) input_udp_ip_ttl = Signal(intbv(0)[8:]) - input_udp_ip_protocol = Signal(intbv(0)[8:]) input_udp_ip_header_checksum = Signal(intbv(0)[16:]) input_udp_ip_source_ip = Signal(intbv(0)[32:]) input_udp_ip_dest_ip = Signal(intbv(0)[32:]) @@ -470,7 +467,6 @@ def bench(): ip_flags=input_udp_ip_flags, ip_fragment_offset=input_udp_ip_fragment_offset, ip_ttl=input_udp_ip_ttl, - ip_protocol=input_udp_ip_protocol, ip_header_checksum=input_udp_ip_header_checksum, ip_source_ip=input_udp_ip_source_ip, ip_dest_ip=input_udp_ip_dest_ip, @@ -586,7 +582,6 @@ def bench(): input_udp_ip_flags, input_udp_ip_fragment_offset, input_udp_ip_ttl, - input_udp_ip_protocol, input_udp_ip_header_checksum, input_udp_ip_source_ip, input_udp_ip_dest_ip, diff --git a/tb/test_udp.v b/tb/test_udp.v index 278552e2f..e6ba1c716 100644 --- a/tb/test_udp.v +++ b/tb/test_udp.v @@ -71,7 +71,6 @@ reg [15:0] input_udp_ip_identification = 0; reg [2:0] input_udp_ip_flags = 0; reg [12:0] input_udp_ip_fragment_offset = 0; reg [7:0] input_udp_ip_ttl = 0; -reg [7:0] input_udp_ip_protocol = 0; reg [15:0] input_udp_ip_header_checksum = 0; reg [31:0] input_udp_ip_source_ip = 0; reg [31:0] input_udp_ip_dest_ip = 0; @@ -183,7 +182,6 @@ initial begin input_udp_ip_flags, input_udp_ip_fragment_offset, input_udp_ip_ttl, - input_udp_ip_protocol, input_udp_ip_header_checksum, input_udp_ip_source_ip, input_udp_ip_dest_ip, @@ -330,7 +328,6 @@ UUT ( .input_udp_ip_flags(input_udp_ip_flags), .input_udp_ip_fragment_offset(input_udp_ip_fragment_offset), .input_udp_ip_ttl(input_udp_ip_ttl), - .input_udp_ip_protocol(input_udp_ip_protocol), .input_udp_ip_header_checksum(input_udp_ip_header_checksum), .input_udp_ip_source_ip(input_udp_ip_source_ip), .input_udp_ip_dest_ip(input_udp_ip_dest_ip), diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py index 3b4e6d1c2..dd1c54d10 100755 --- a/tb/test_udp_64.py +++ b/tb/test_udp_64.py @@ -111,7 +111,6 @@ def dut_udp(clk, input_udp_ip_flags, input_udp_ip_fragment_offset, input_udp_ip_ttl, - input_udp_ip_protocol, input_udp_ip_header_checksum, input_udp_ip_source_ip, input_udp_ip_dest_ip, @@ -231,7 +230,6 @@ def dut_udp(clk, input_udp_ip_flags=input_udp_ip_flags, input_udp_ip_fragment_offset=input_udp_ip_fragment_offset, input_udp_ip_ttl=input_udp_ip_ttl, - input_udp_ip_protocol=input_udp_ip_protocol, input_udp_ip_header_checksum=input_udp_ip_header_checksum, input_udp_ip_source_ip=input_udp_ip_source_ip, input_udp_ip_dest_ip=input_udp_ip_dest_ip, @@ -322,7 +320,6 @@ def bench(): input_udp_ip_flags = Signal(intbv(0)[3:]) input_udp_ip_fragment_offset = Signal(intbv(0)[13:]) input_udp_ip_ttl = Signal(intbv(0)[8:]) - input_udp_ip_protocol = Signal(intbv(0)[8:]) input_udp_ip_header_checksum = Signal(intbv(0)[16:]) input_udp_ip_source_ip = Signal(intbv(0)[32:]) input_udp_ip_dest_ip = Signal(intbv(0)[32:]) @@ -484,7 +481,6 @@ def bench(): ip_flags=input_udp_ip_flags, ip_fragment_offset=input_udp_ip_fragment_offset, ip_ttl=input_udp_ip_ttl, - ip_protocol=input_udp_ip_protocol, ip_header_checksum=input_udp_ip_header_checksum, ip_source_ip=input_udp_ip_source_ip, ip_dest_ip=input_udp_ip_dest_ip, @@ -604,7 +600,6 @@ def bench(): input_udp_ip_flags, input_udp_ip_fragment_offset, input_udp_ip_ttl, - input_udp_ip_protocol, input_udp_ip_header_checksum, input_udp_ip_source_ip, input_udp_ip_dest_ip, diff --git a/tb/test_udp_64.v b/tb/test_udp_64.v index dbce9b8ce..556324b4c 100644 --- a/tb/test_udp_64.v +++ b/tb/test_udp_64.v @@ -72,7 +72,6 @@ reg [15:0] input_udp_ip_identification = 0; reg [2:0] input_udp_ip_flags = 0; reg [12:0] input_udp_ip_fragment_offset = 0; reg [7:0] input_udp_ip_ttl = 0; -reg [7:0] input_udp_ip_protocol = 0; reg [15:0] input_udp_ip_header_checksum = 0; reg [31:0] input_udp_ip_source_ip = 0; reg [31:0] input_udp_ip_dest_ip = 0; @@ -188,7 +187,6 @@ initial begin input_udp_ip_flags, input_udp_ip_fragment_offset, input_udp_ip_ttl, - input_udp_ip_protocol, input_udp_ip_header_checksum, input_udp_ip_source_ip, input_udp_ip_dest_ip, @@ -340,7 +338,6 @@ UUT ( .input_udp_ip_flags(input_udp_ip_flags), .input_udp_ip_fragment_offset(input_udp_ip_fragment_offset), .input_udp_ip_ttl(input_udp_ip_ttl), - .input_udp_ip_protocol(input_udp_ip_protocol), .input_udp_ip_header_checksum(input_udp_ip_header_checksum), .input_udp_ip_source_ip(input_udp_ip_source_ip), .input_udp_ip_dest_ip(input_udp_ip_dest_ip), From b892fd11727c8b586f845a3cda0c49740141f3f2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 22:57:24 -0800 Subject: [PATCH 153/617] Add UDP complete module and testbench --- rtl/udp_complete.v | 623 ++++++++++++++++++++ rtl/udp_complete_64.v | 646 ++++++++++++++++++++ tb/test_udp_complete.py | 1108 +++++++++++++++++++++++++++++++++++ tb/test_udp_complete.v | 440 ++++++++++++++ tb/test_udp_complete_64.py | 1138 ++++++++++++++++++++++++++++++++++++ tb/test_udp_complete_64.v | 458 +++++++++++++++ 6 files changed, 4413 insertions(+) create mode 100644 rtl/udp_complete.v create mode 100644 rtl/udp_complete_64.v create mode 100755 tb/test_udp_complete.py create mode 100644 tb/test_udp_complete.v create mode 100755 tb/test_udp_complete_64.py create mode 100644 tb/test_udp_complete_64.v diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v new file mode 100644 index 000000000..d32bba109 --- /dev/null +++ b/rtl/udp_complete.v @@ -0,0 +1,623 @@ +/* + +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 + +/* + * IPv4 and ARP block with UDP support, ethernet frame interface + */ +module udp_complete #( + parameter ARP_CACHE_ADDR_WIDTH = 2, + parameter ARP_REQUEST_RETRY_COUNT = 4, + parameter ARP_REQUEST_RETRY_INTERVAL = 125000000*2, + parameter ARP_REQUEST_TIMEOUT = 125000000*30, + parameter UDP_CHECKSUM_ENABLE = 1, + parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11, + parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3 +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [7:0] input_eth_payload_tdata, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * IP input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [7:0] input_ip_payload_tdata, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_ip_eth_dest_mac, + output wire [47:0] output_ip_eth_src_mac, + output wire [15:0] output_ip_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * UDP input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [5:0] input_udp_ip_dscp, + input wire [1:0] input_udp_ip_ecn, + input wire [7:0] input_udp_ip_ttl, + input wire [31:0] input_udp_ip_source_ip, + input wire [31:0] input_udp_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [7:0] input_udp_payload_tdata, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_udp_eth_dest_mac, + output wire [47:0] output_udp_eth_src_mac, + output wire [15:0] output_udp_eth_type, + output wire [3:0] output_udp_ip_version, + output wire [3:0] output_udp_ip_ihl, + output wire [5:0] output_udp_ip_dscp, + output wire [1:0] output_udp_ip_ecn, + output wire [15:0] output_udp_ip_length, + output wire [15:0] output_udp_ip_identification, + output wire [2:0] output_udp_ip_flags, + output wire [12:0] output_udp_ip_fragment_offset, + output wire [7:0] output_udp_ip_ttl, + output wire [7:0] output_udp_ip_protocol, + output wire [15:0] output_udp_ip_header_checksum, + output wire [31:0] output_udp_ip_source_ip, + output wire [31:0] output_udp_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [7:0] output_udp_payload_tdata, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Status + */ + output wire ip_rx_busy, + output wire ip_tx_busy, + output wire udp_rx_busy, + output wire udp_tx_busy, + output wire ip_rx_error_header_early_termination, + output wire ip_rx_error_payload_early_termination, + output wire ip_rx_error_invalid_header, + output wire ip_rx_error_invalid_checksum, + output wire ip_tx_error_payload_early_termination, + output wire ip_tx_error_arp_failed, + output wire udp_rx_error_header_early_termination, + output wire udp_rx_error_payload_early_termination, + output wire udp_tx_error_payload_early_termination, + + /* + * Configuration + */ + input wire [47:0] local_mac, + input wire [31:0] local_ip, + input wire [31:0] gateway_ip, + input wire [31:0] subnet_mask, + input wire clear_arp_cache +); + +wire ip_rx_ip_hdr_valid; +wire ip_rx_ip_hdr_ready; +wire [47:0] ip_rx_ip_eth_dest_mac; +wire [47:0] ip_rx_ip_eth_src_mac; +wire [15:0] ip_rx_ip_eth_type; +wire [3:0] ip_rx_ip_version; +wire [3:0] ip_rx_ip_ihl; +wire [5:0] ip_rx_ip_dscp; +wire [1:0] ip_rx_ip_ecn; +wire [15:0] ip_rx_ip_length; +wire [15:0] ip_rx_ip_identification; +wire [2:0] ip_rx_ip_flags; +wire [12:0] ip_rx_ip_fragment_offset; +wire [7:0] ip_rx_ip_ttl; +wire [7:0] ip_rx_ip_protocol; +wire [15:0] ip_rx_ip_header_checksum; +wire [31:0] ip_rx_ip_source_ip; +wire [31:0] ip_rx_ip_dest_ip; +wire [7:0] ip_rx_ip_payload_tdata; +wire ip_rx_ip_payload_tvalid; +wire ip_rx_ip_payload_tlast; +wire ip_rx_ip_payload_tuser; +wire ip_rx_ip_payload_tready; + +wire ip_tx_ip_hdr_valid; +wire ip_tx_ip_hdr_ready; +wire [5:0] ip_tx_ip_dscp; +wire [1:0] ip_tx_ip_ecn; +wire [15:0] ip_tx_ip_length; +wire [7:0] ip_tx_ip_ttl; +wire [7:0] ip_tx_ip_protocol; +wire [31:0] ip_tx_ip_source_ip; +wire [31:0] ip_tx_ip_dest_ip; +wire [7:0] ip_tx_ip_payload_tdata; +wire ip_tx_ip_payload_tvalid; +wire ip_tx_ip_payload_tlast; +wire ip_tx_ip_payload_tuser; +wire ip_tx_ip_payload_tready; + +wire udp_rx_ip_hdr_valid; +wire udp_rx_ip_hdr_ready; +wire [47:0] udp_rx_ip_eth_dest_mac; +wire [47:0] udp_rx_ip_eth_src_mac; +wire [15:0] udp_rx_ip_eth_type; +wire [3:0] udp_rx_ip_version; +wire [3:0] udp_rx_ip_ihl; +wire [5:0] udp_rx_ip_dscp; +wire [1:0] udp_rx_ip_ecn; +wire [15:0] udp_rx_ip_length; +wire [15:0] udp_rx_ip_identification; +wire [2:0] udp_rx_ip_flags; +wire [12:0] udp_rx_ip_fragment_offset; +wire [7:0] udp_rx_ip_ttl; +wire [7:0] udp_rx_ip_protocol; +wire [15:0] udp_rx_ip_header_checksum; +wire [31:0] udp_rx_ip_source_ip; +wire [31:0] udp_rx_ip_dest_ip; +wire [7:0] udp_rx_ip_payload_tdata; +wire udp_rx_ip_payload_tvalid; +wire udp_rx_ip_payload_tlast; +wire udp_rx_ip_payload_tuser; +wire udp_rx_ip_payload_tready; + +wire udp_tx_ip_hdr_valid; +wire udp_tx_ip_hdr_ready; +wire [5:0] udp_tx_ip_dscp; +wire [1:0] udp_tx_ip_ecn; +wire [15:0] udp_tx_ip_length; +wire [7:0] udp_tx_ip_ttl; +wire [7:0] udp_tx_ip_protocol; +wire [31:0] udp_tx_ip_source_ip; +wire [31:0] udp_tx_ip_dest_ip; +wire [7:0] udp_tx_ip_payload_tdata; +wire udp_tx_ip_payload_tvalid; +wire udp_tx_ip_payload_tlast; +wire udp_tx_ip_payload_tuser; +wire udp_tx_ip_payload_tready; + +/* + * Input classifier (ip_protocol) + */ +wire input_select_udp = (ip_rx_ip_protocol == 8'h11); +wire input_select_ip = ~input_select_udp; + +// IP frame to UDP module +assign udp_rx_ip_hdr_valid = input_select_udp & ip_rx_ip_hdr_valid; +assign udp_rx_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; +assign udp_rx_ip_eth_src_mac = ip_rx_ip_eth_src_mac; +assign udp_rx_ip_eth_type = ip_rx_ip_eth_type; +assign udp_rx_ip_version = ip_rx_ip_version; +assign udp_rx_ip_ihl = ip_rx_ip_ihl; +assign udp_rx_ip_dscp = ip_rx_ip_dscp; +assign udp_rx_ip_ecn = ip_rx_ip_ecn; +assign udp_rx_ip_length = ip_rx_ip_length; +assign udp_rx_ip_identification = ip_rx_ip_identification; +assign udp_rx_ip_flags = ip_rx_ip_flags; +assign udp_rx_ip_fragment_offset = ip_rx_ip_fragment_offset; +assign udp_rx_ip_ttl = ip_rx_ip_ttl; +assign udp_rx_ip_protocol = 8'h11; +assign udp_rx_ip_header_checksum = ip_rx_ip_header_checksum; +assign udp_rx_ip_source_ip = ip_rx_ip_source_ip; +assign udp_rx_ip_dest_ip = ip_rx_ip_dest_ip; +assign udp_rx_ip_payload_tdata = ip_rx_ip_payload_tdata; +assign udp_rx_ip_payload_tvalid = input_select_udp & ip_rx_ip_payload_tvalid; +assign udp_rx_ip_payload_tlast = ip_rx_ip_payload_tlast; +assign udp_rx_ip_payload_tuser = ip_rx_ip_payload_tuser; + +// External IP frame output +assign output_ip_hdr_valid = input_select_ip & ip_rx_ip_hdr_valid; +assign output_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; +assign output_ip_eth_src_mac = ip_rx_ip_eth_src_mac; +assign output_ip_eth_type = ip_rx_ip_eth_type; +assign output_ip_version = ip_rx_ip_version; +assign output_ip_ihl = ip_rx_ip_ihl; +assign output_ip_dscp = ip_rx_ip_dscp; +assign output_ip_ecn = ip_rx_ip_ecn; +assign output_ip_length = ip_rx_ip_length; +assign output_ip_identification = ip_rx_ip_identification; +assign output_ip_flags = ip_rx_ip_flags; +assign output_ip_fragment_offset = ip_rx_ip_fragment_offset; +assign output_ip_ttl = ip_rx_ip_ttl; +assign output_ip_protocol = ip_rx_ip_protocol; +assign output_ip_header_checksum = ip_rx_ip_header_checksum; +assign output_ip_source_ip = ip_rx_ip_source_ip; +assign output_ip_dest_ip = ip_rx_ip_dest_ip; +assign output_ip_payload_tdata = ip_rx_ip_payload_tdata; +assign output_ip_payload_tvalid = input_select_ip & ip_rx_ip_payload_tvalid; +assign output_ip_payload_tlast = ip_rx_ip_payload_tlast; +assign output_ip_payload_tuser = ip_rx_ip_payload_tuser; + +assign ip_rx_ip_hdr_ready = udp_rx_ip_hdr_ready & output_ip_hdr_ready; + +assign ip_rx_ip_payload_tready = (input_select_udp & udp_rx_ip_payload_tready) | + (input_select_ip & output_ip_payload_tready); + +/* + * Output arbiter + */ +ip_arb_mux_2 +ip_arb_mux_2_inst ( + .clk(clk), + .rst(rst), + // IP frame input from UDP module + .input_0_ip_hdr_valid(udp_tx_ip_hdr_valid), + .input_0_ip_hdr_ready(udp_tx_ip_hdr_ready), + .input_0_eth_dest_mac(0), + .input_0_eth_src_mac(0), + .input_0_eth_type(0), + .input_0_ip_version(0), + .input_0_ip_ihl(0), + .input_0_ip_dscp(udp_tx_ip_dscp), + .input_0_ip_ecn(udp_tx_ip_ecn), + .input_0_ip_length(udp_tx_ip_length), + .input_0_ip_identification(0), + .input_0_ip_flags(0), + .input_0_ip_fragment_offset(0), + .input_0_ip_ttl(udp_tx_ip_ttl), + .input_0_ip_protocol(udp_tx_ip_protocol), + .input_0_ip_header_checksum(0), + .input_0_ip_source_ip(udp_tx_ip_source_ip), + .input_0_ip_dest_ip(udp_tx_ip_dest_ip), + .input_0_ip_payload_tdata(udp_tx_ip_payload_tdata), + .input_0_ip_payload_tvalid(udp_tx_ip_payload_tvalid), + .input_0_ip_payload_tready(udp_tx_ip_payload_tready), + .input_0_ip_payload_tlast(udp_tx_ip_payload_tlast), + .input_0_ip_payload_tuser(udp_tx_ip_payload_tuser), + // External IP frame input + .input_1_ip_hdr_valid(input_ip_hdr_valid), + .input_1_ip_hdr_ready(input_ip_hdr_ready), + .input_1_eth_dest_mac(0), + .input_1_eth_src_mac(0), + .input_1_eth_type(0), + .input_1_ip_version(0), + .input_1_ip_ihl(0), + .input_1_ip_dscp(input_ip_dscp), + .input_1_ip_ecn(input_ip_ecn), + .input_1_ip_length(input_ip_length), + .input_1_ip_identification(0), + .input_1_ip_flags(0), + .input_1_ip_fragment_offset(0), + .input_1_ip_ttl(input_ip_ttl), + .input_1_ip_protocol(input_ip_protocol), + .input_1_ip_header_checksum(0), + .input_1_ip_source_ip(input_ip_source_ip), + .input_1_ip_dest_ip(input_ip_dest_ip), + .input_1_ip_payload_tdata(input_ip_payload_tdata), + .input_1_ip_payload_tvalid(input_ip_payload_tvalid), + .input_1_ip_payload_tready(input_ip_payload_tready), + .input_1_ip_payload_tlast(input_ip_payload_tlast), + .input_1_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output to IP stack + .output_ip_hdr_valid(ip_tx_ip_hdr_valid), + .output_ip_hdr_ready(ip_tx_ip_hdr_ready), + .output_eth_dest_mac(), + .output_eth_src_mac(), + .output_eth_type(), + .output_ip_version(), + .output_ip_ihl(), + .output_ip_dscp(ip_tx_ip_dscp), + .output_ip_ecn(ip_tx_ip_ecn), + .output_ip_length(ip_tx_ip_length), + .output_ip_identification(), + .output_ip_flags(), + .output_ip_fragment_offset(), + .output_ip_ttl(ip_tx_ip_ttl), + .output_ip_protocol(ip_tx_ip_protocol), + .output_ip_header_checksum(), + .output_ip_source_ip(ip_tx_ip_source_ip), + .output_ip_dest_ip(ip_tx_ip_dest_ip), + .output_ip_payload_tdata(ip_tx_ip_payload_tdata), + .output_ip_payload_tvalid(ip_tx_ip_payload_tvalid), + .output_ip_payload_tready(ip_tx_ip_payload_tready), + .output_ip_payload_tlast(ip_tx_ip_payload_tlast), + .output_ip_payload_tuser(ip_tx_ip_payload_tuser) +); + +/* + * IP stack + */ +ip_complete #( + .ARP_CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT) +) +ip_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(ip_tx_ip_hdr_valid), + .input_ip_hdr_ready(ip_tx_ip_hdr_ready), + .input_ip_dscp(ip_tx_ip_dscp), + .input_ip_ecn(ip_tx_ip_ecn), + .input_ip_length(ip_tx_ip_length), + .input_ip_ttl(ip_tx_ip_ttl), + .input_ip_protocol(ip_tx_ip_protocol), + .input_ip_source_ip(ip_tx_ip_source_ip), + .input_ip_dest_ip(ip_tx_ip_dest_ip), + .input_ip_payload_tdata(ip_tx_ip_payload_tdata), + .input_ip_payload_tvalid(ip_tx_ip_payload_tvalid), + .input_ip_payload_tready(ip_tx_ip_payload_tready), + .input_ip_payload_tlast(ip_tx_ip_payload_tlast), + .input_ip_payload_tuser(ip_tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(ip_rx_ip_hdr_valid), + .output_ip_hdr_ready(ip_rx_ip_hdr_ready), + .output_ip_eth_dest_mac(ip_rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(ip_rx_ip_eth_src_mac), + .output_ip_eth_type(ip_rx_ip_eth_type), + .output_ip_version(ip_rx_ip_version), + .output_ip_ihl(ip_rx_ip_ihl), + .output_ip_dscp(ip_rx_ip_dscp), + .output_ip_ecn(ip_rx_ip_ecn), + .output_ip_length(ip_rx_ip_length), + .output_ip_identification(ip_rx_ip_identification), + .output_ip_flags(ip_rx_ip_flags), + .output_ip_fragment_offset(ip_rx_ip_fragment_offset), + .output_ip_ttl(ip_rx_ip_ttl), + .output_ip_protocol(ip_rx_ip_protocol), + .output_ip_header_checksum(ip_rx_ip_header_checksum), + .output_ip_source_ip(ip_rx_ip_source_ip), + .output_ip_dest_ip(ip_rx_ip_dest_ip), + .output_ip_payload_tdata(ip_rx_ip_payload_tdata), + .output_ip_payload_tvalid(ip_rx_ip_payload_tvalid), + .output_ip_payload_tready(ip_rx_ip_payload_tready), + .output_ip_payload_tlast(ip_rx_ip_payload_tlast), + .output_ip_payload_tuser(ip_rx_ip_payload_tuser), + // Status + .rx_busy(ip_rx_busy), + .tx_busy(ip_tx_busy), + .rx_error_header_early_termination(ip_rx_error_header_early_termination), + .rx_error_payload_early_termination(ip_rx_error_payload_early_termination), + .rx_error_invalid_header(ip_rx_error_invalid_header), + .rx_error_invalid_checksum(ip_rx_error_invalid_checksum), + .tx_error_payload_early_termination(ip_tx_error_payload_early_termination), + .tx_error_arp_failed(ip_tx_error_arp_failed), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(clear_arp_cache) +); + +/* + * UDP interface + */ +udp #( + .CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) +) +udp_inst ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(udp_rx_ip_hdr_valid), + .input_ip_hdr_ready(udp_rx_ip_hdr_ready), + .input_ip_eth_dest_mac(udp_rx_ip_eth_dest_mac), + .input_ip_eth_src_mac(udp_rx_ip_eth_src_mac), + .input_ip_eth_type(udp_rx_ip_eth_type), + .input_ip_version(udp_rx_ip_version), + .input_ip_ihl(udp_rx_ip_ihl), + .input_ip_dscp(udp_rx_ip_dscp), + .input_ip_ecn(udp_rx_ip_ecn), + .input_ip_length(udp_rx_ip_length), + .input_ip_identification(udp_rx_ip_identification), + .input_ip_flags(udp_rx_ip_flags), + .input_ip_fragment_offset(udp_rx_ip_fragment_offset), + .input_ip_ttl(udp_rx_ip_ttl), + .input_ip_protocol(udp_rx_ip_protocol), + .input_ip_header_checksum(udp_rx_ip_header_checksum), + .input_ip_source_ip(udp_rx_ip_source_ip), + .input_ip_dest_ip(udp_rx_ip_dest_ip), + .input_ip_payload_tdata(udp_rx_ip_payload_tdata), + .input_ip_payload_tvalid(udp_rx_ip_payload_tvalid), + .input_ip_payload_tready(udp_rx_ip_payload_tready), + .input_ip_payload_tlast(udp_rx_ip_payload_tlast), + .input_ip_payload_tuser(udp_rx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(udp_tx_ip_hdr_valid), + .output_ip_hdr_ready(udp_tx_ip_hdr_ready), + .output_ip_eth_dest_mac(), + .output_ip_eth_src_mac(), + .output_ip_eth_type(), + .output_ip_version(), + .output_ip_ihl(), + .output_ip_dscp(udp_tx_ip_dscp), + .output_ip_ecn(udp_tx_ip_ecn), + .output_ip_length(udp_tx_ip_length), + .output_ip_identification(), + .output_ip_flags(), + .output_ip_fragment_offset(), + .output_ip_ttl(udp_tx_ip_ttl), + .output_ip_protocol(udp_tx_ip_protocol), + .output_ip_header_checksum(), + .output_ip_source_ip(udp_tx_ip_source_ip), + .output_ip_dest_ip(udp_tx_ip_dest_ip), + .output_ip_payload_tdata(udp_tx_ip_payload_tdata), + .output_ip_payload_tvalid(udp_tx_ip_payload_tvalid), + .output_ip_payload_tready(udp_tx_ip_payload_tready), + .output_ip_payload_tlast(udp_tx_ip_payload_tlast), + .output_ip_payload_tuser(udp_tx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_udp_eth_dest_mac(0), + .input_udp_eth_src_mac(0), + .input_udp_eth_type(0), + .input_udp_ip_version(0), + .input_udp_ip_ihl(0), + .input_udp_ip_dscp(input_udp_ip_dscp), + .input_udp_ip_ecn(input_udp_ip_ecn), + .input_udp_ip_identification(0), + .input_udp_ip_flags(0), + .input_udp_ip_fragment_offset(0), + .input_udp_ip_ttl(input_udp_ip_ttl), + .input_udp_ip_header_checksum(0), + .input_udp_ip_source_ip(input_udp_ip_source_ip), + .input_udp_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_udp_eth_dest_mac(output_udp_eth_dest_mac), + .output_udp_eth_src_mac(output_udp_eth_src_mac), + .output_udp_eth_type(output_udp_eth_type), + .output_udp_ip_version(output_udp_ip_version), + .output_udp_ip_ihl(output_udp_ip_ihl), + .output_udp_ip_dscp(output_udp_ip_dscp), + .output_udp_ip_ecn(output_udp_ip_ecn), + .output_udp_ip_length(output_udp_ip_length), + .output_udp_ip_identification(output_udp_ip_identification), + .output_udp_ip_flags(output_udp_ip_flags), + .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_udp_ip_ttl(output_udp_ip_ttl), + .output_udp_ip_protocol(output_udp_ip_protocol), + .output_udp_ip_header_checksum(output_udp_ip_header_checksum), + .output_udp_ip_source_ip(output_udp_ip_source_ip), + .output_udp_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status + .rx_busy(udp_rx_busy), + .tx_busy(udp_tx_busy), + .rx_error_header_early_termination(udp_rx_error_header_early_termination), + .rx_error_payload_early_termination(udp_rx_error_payload_early_termination), + .tx_error_payload_early_termination(udp_tx_error_payload_early_termination) +); + +endmodule diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v new file mode 100644 index 000000000..8eeb2525f --- /dev/null +++ b/rtl/udp_complete_64.v @@ -0,0 +1,646 @@ +/* + +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 + +/* + * IPv4 and ARP block with UDP support, ethernet frame interface (64 bit datapath) + */ +module udp_complete_64 #( + parameter ARP_CACHE_ADDR_WIDTH = 2, + parameter ARP_REQUEST_RETRY_COUNT = 4, + parameter ARP_REQUEST_RETRY_INTERVAL = 125000000*2, + parameter ARP_REQUEST_TIMEOUT = 125000000*30, + parameter UDP_CHECKSUM_ENABLE = 1, + parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11, + parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3 +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [63:0] input_eth_payload_tdata, + input wire [7:0] input_eth_payload_tkeep, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * IP input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [63:0] input_ip_payload_tdata, + input wire [7:0] input_ip_payload_tkeep, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_ip_eth_dest_mac, + output wire [47:0] output_ip_eth_src_mac, + output wire [15:0] output_ip_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * UDP input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [5:0] input_udp_ip_dscp, + input wire [1:0] input_udp_ip_ecn, + input wire [7:0] input_udp_ip_ttl, + input wire [31:0] input_udp_ip_source_ip, + input wire [31:0] input_udp_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [63:0] input_udp_payload_tdata, + input wire [7:0] input_udp_payload_tkeep, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_udp_eth_dest_mac, + output wire [47:0] output_udp_eth_src_mac, + output wire [15:0] output_udp_eth_type, + output wire [3:0] output_udp_ip_version, + output wire [3:0] output_udp_ip_ihl, + output wire [5:0] output_udp_ip_dscp, + output wire [1:0] output_udp_ip_ecn, + output wire [15:0] output_udp_ip_length, + output wire [15:0] output_udp_ip_identification, + output wire [2:0] output_udp_ip_flags, + output wire [12:0] output_udp_ip_fragment_offset, + output wire [7:0] output_udp_ip_ttl, + output wire [7:0] output_udp_ip_protocol, + output wire [15:0] output_udp_ip_header_checksum, + output wire [31:0] output_udp_ip_source_ip, + output wire [31:0] output_udp_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [63:0] output_udp_payload_tdata, + output wire [7:0] output_udp_payload_tkeep, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Status + */ + output wire ip_rx_busy, + output wire ip_tx_busy, + output wire udp_rx_busy, + output wire udp_tx_busy, + output wire ip_rx_error_header_early_termination, + output wire ip_rx_error_payload_early_termination, + output wire ip_rx_error_invalid_header, + output wire ip_rx_error_invalid_checksum, + output wire ip_tx_error_payload_early_termination, + output wire ip_tx_error_arp_failed, + output wire udp_rx_error_header_early_termination, + output wire udp_rx_error_payload_early_termination, + output wire udp_tx_error_payload_early_termination, + + /* + * Configuration + */ + input wire [47:0] local_mac, + input wire [31:0] local_ip, + input wire [31:0] gateway_ip, + input wire [31:0] subnet_mask, + input wire clear_arp_cache +); + +wire ip_rx_ip_hdr_valid; +wire ip_rx_ip_hdr_ready; +wire [47:0] ip_rx_ip_eth_dest_mac; +wire [47:0] ip_rx_ip_eth_src_mac; +wire [15:0] ip_rx_ip_eth_type; +wire [3:0] ip_rx_ip_version; +wire [3:0] ip_rx_ip_ihl; +wire [5:0] ip_rx_ip_dscp; +wire [1:0] ip_rx_ip_ecn; +wire [15:0] ip_rx_ip_length; +wire [15:0] ip_rx_ip_identification; +wire [2:0] ip_rx_ip_flags; +wire [12:0] ip_rx_ip_fragment_offset; +wire [7:0] ip_rx_ip_ttl; +wire [7:0] ip_rx_ip_protocol; +wire [15:0] ip_rx_ip_header_checksum; +wire [31:0] ip_rx_ip_source_ip; +wire [31:0] ip_rx_ip_dest_ip; +wire [63:0] ip_rx_ip_payload_tdata; +wire [7:0] ip_rx_ip_payload_tkeep; +wire ip_rx_ip_payload_tvalid; +wire ip_rx_ip_payload_tlast; +wire ip_rx_ip_payload_tuser; +wire ip_rx_ip_payload_tready; + +wire ip_tx_ip_hdr_valid; +wire ip_tx_ip_hdr_ready; +wire [5:0] ip_tx_ip_dscp; +wire [1:0] ip_tx_ip_ecn; +wire [15:0] ip_tx_ip_length; +wire [7:0] ip_tx_ip_ttl; +wire [7:0] ip_tx_ip_protocol; +wire [31:0] ip_tx_ip_source_ip; +wire [31:0] ip_tx_ip_dest_ip; +wire [63:0] ip_tx_ip_payload_tdata; +wire [7:0] ip_tx_ip_payload_tkeep; +wire ip_tx_ip_payload_tvalid; +wire ip_tx_ip_payload_tlast; +wire ip_tx_ip_payload_tuser; +wire ip_tx_ip_payload_tready; + +wire udp_rx_ip_hdr_valid; +wire udp_rx_ip_hdr_ready; +wire [47:0] udp_rx_ip_eth_dest_mac; +wire [47:0] udp_rx_ip_eth_src_mac; +wire [15:0] udp_rx_ip_eth_type; +wire [3:0] udp_rx_ip_version; +wire [3:0] udp_rx_ip_ihl; +wire [5:0] udp_rx_ip_dscp; +wire [1:0] udp_rx_ip_ecn; +wire [15:0] udp_rx_ip_length; +wire [15:0] udp_rx_ip_identification; +wire [2:0] udp_rx_ip_flags; +wire [12:0] udp_rx_ip_fragment_offset; +wire [7:0] udp_rx_ip_ttl; +wire [7:0] udp_rx_ip_protocol; +wire [15:0] udp_rx_ip_header_checksum; +wire [31:0] udp_rx_ip_source_ip; +wire [31:0] udp_rx_ip_dest_ip; +wire [63:0] udp_rx_ip_payload_tdata; +wire [7:0] udp_rx_ip_payload_tkeep; +wire udp_rx_ip_payload_tvalid; +wire udp_rx_ip_payload_tlast; +wire udp_rx_ip_payload_tuser; +wire udp_rx_ip_payload_tready; + +wire udp_tx_ip_hdr_valid; +wire udp_tx_ip_hdr_ready; +wire [5:0] udp_tx_ip_dscp; +wire [1:0] udp_tx_ip_ecn; +wire [15:0] udp_tx_ip_length; +wire [7:0] udp_tx_ip_ttl; +wire [7:0] udp_tx_ip_protocol; +wire [31:0] udp_tx_ip_source_ip; +wire [31:0] udp_tx_ip_dest_ip; +wire [63:0] udp_tx_ip_payload_tdata; +wire [7:0] udp_tx_ip_payload_tkeep; +wire udp_tx_ip_payload_tvalid; +wire udp_tx_ip_payload_tlast; +wire udp_tx_ip_payload_tuser; +wire udp_tx_ip_payload_tready; + +/* + * Input classifier (ip_protocol) + */ +wire input_select_udp = (ip_rx_ip_protocol == 8'h11); +wire input_select_ip = ~input_select_udp; + +// IP frame to UDP module +assign udp_rx_ip_hdr_valid = input_select_udp & ip_rx_ip_hdr_valid; +assign udp_rx_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; +assign udp_rx_ip_eth_src_mac = ip_rx_ip_eth_src_mac; +assign udp_rx_ip_eth_type = ip_rx_ip_eth_type; +assign udp_rx_ip_version = ip_rx_ip_version; +assign udp_rx_ip_ihl = ip_rx_ip_ihl; +assign udp_rx_ip_dscp = ip_rx_ip_dscp; +assign udp_rx_ip_ecn = ip_rx_ip_ecn; +assign udp_rx_ip_length = ip_rx_ip_length; +assign udp_rx_ip_identification = ip_rx_ip_identification; +assign udp_rx_ip_flags = ip_rx_ip_flags; +assign udp_rx_ip_fragment_offset = ip_rx_ip_fragment_offset; +assign udp_rx_ip_ttl = ip_rx_ip_ttl; +assign udp_rx_ip_protocol = 8'h11; +assign udp_rx_ip_header_checksum = ip_rx_ip_header_checksum; +assign udp_rx_ip_source_ip = ip_rx_ip_source_ip; +assign udp_rx_ip_dest_ip = ip_rx_ip_dest_ip; +assign udp_rx_ip_payload_tdata = ip_rx_ip_payload_tdata; +assign udp_rx_ip_payload_tkeep = ip_rx_ip_payload_tkeep; +assign udp_rx_ip_payload_tvalid = input_select_udp & ip_rx_ip_payload_tvalid; +assign udp_rx_ip_payload_tlast = ip_rx_ip_payload_tlast; +assign udp_rx_ip_payload_tuser = ip_rx_ip_payload_tuser; + +// External IP frame output +assign output_ip_hdr_valid = input_select_ip & ip_rx_ip_hdr_valid; +assign output_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; +assign output_ip_eth_src_mac = ip_rx_ip_eth_src_mac; +assign output_ip_eth_type = ip_rx_ip_eth_type; +assign output_ip_version = ip_rx_ip_version; +assign output_ip_ihl = ip_rx_ip_ihl; +assign output_ip_dscp = ip_rx_ip_dscp; +assign output_ip_ecn = ip_rx_ip_ecn; +assign output_ip_length = ip_rx_ip_length; +assign output_ip_identification = ip_rx_ip_identification; +assign output_ip_flags = ip_rx_ip_flags; +assign output_ip_fragment_offset = ip_rx_ip_fragment_offset; +assign output_ip_ttl = ip_rx_ip_ttl; +assign output_ip_protocol = ip_rx_ip_protocol; +assign output_ip_header_checksum = ip_rx_ip_header_checksum; +assign output_ip_source_ip = ip_rx_ip_source_ip; +assign output_ip_dest_ip = ip_rx_ip_dest_ip; +assign output_ip_payload_tdata = ip_rx_ip_payload_tdata; +assign output_ip_payload_tkeep = ip_rx_ip_payload_tkeep; +assign output_ip_payload_tvalid = input_select_ip & ip_rx_ip_payload_tvalid; +assign output_ip_payload_tlast = ip_rx_ip_payload_tlast; +assign output_ip_payload_tuser = ip_rx_ip_payload_tuser; + +assign ip_rx_ip_hdr_ready = udp_rx_ip_hdr_ready & output_ip_hdr_ready; + +assign ip_rx_ip_payload_tready = (input_select_udp & udp_rx_ip_payload_tready) | + (input_select_ip & output_ip_payload_tready); + +/* + * Output arbiter + */ +ip_arb_mux_64_2 +ip_arb_mux_64_2_inst ( + .clk(clk), + .rst(rst), + // IP frame input from UDP module + .input_0_ip_hdr_valid(udp_tx_ip_hdr_valid), + .input_0_ip_hdr_ready(udp_tx_ip_hdr_ready), + .input_0_eth_dest_mac(0), + .input_0_eth_src_mac(0), + .input_0_eth_type(0), + .input_0_ip_version(0), + .input_0_ip_ihl(0), + .input_0_ip_dscp(udp_tx_ip_dscp), + .input_0_ip_ecn(udp_tx_ip_ecn), + .input_0_ip_length(udp_tx_ip_length), + .input_0_ip_identification(0), + .input_0_ip_flags(0), + .input_0_ip_fragment_offset(0), + .input_0_ip_ttl(udp_tx_ip_ttl), + .input_0_ip_protocol(udp_tx_ip_protocol), + .input_0_ip_header_checksum(0), + .input_0_ip_source_ip(udp_tx_ip_source_ip), + .input_0_ip_dest_ip(udp_tx_ip_dest_ip), + .input_0_ip_payload_tdata(udp_tx_ip_payload_tdata), + .input_0_ip_payload_tkeep(udp_tx_ip_payload_tkeep), + .input_0_ip_payload_tvalid(udp_tx_ip_payload_tvalid), + .input_0_ip_payload_tready(udp_tx_ip_payload_tready), + .input_0_ip_payload_tlast(udp_tx_ip_payload_tlast), + .input_0_ip_payload_tuser(udp_tx_ip_payload_tuser), + // External IP frame input + .input_1_ip_hdr_valid(input_ip_hdr_valid), + .input_1_ip_hdr_ready(input_ip_hdr_ready), + .input_1_eth_dest_mac(0), + .input_1_eth_src_mac(0), + .input_1_eth_type(0), + .input_1_ip_version(0), + .input_1_ip_ihl(0), + .input_1_ip_dscp(input_ip_dscp), + .input_1_ip_ecn(input_ip_ecn), + .input_1_ip_length(input_ip_length), + .input_1_ip_identification(0), + .input_1_ip_flags(0), + .input_1_ip_fragment_offset(0), + .input_1_ip_ttl(input_ip_ttl), + .input_1_ip_protocol(input_ip_protocol), + .input_1_ip_header_checksum(0), + .input_1_ip_source_ip(input_ip_source_ip), + .input_1_ip_dest_ip(input_ip_dest_ip), + .input_1_ip_payload_tdata(input_ip_payload_tdata), + .input_1_ip_payload_tkeep(input_ip_payload_tkeep), + .input_1_ip_payload_tvalid(input_ip_payload_tvalid), + .input_1_ip_payload_tready(input_ip_payload_tready), + .input_1_ip_payload_tlast(input_ip_payload_tlast), + .input_1_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output to IP stack + .output_ip_hdr_valid(ip_tx_ip_hdr_valid), + .output_ip_hdr_ready(ip_tx_ip_hdr_ready), + .output_eth_dest_mac(), + .output_eth_src_mac(), + .output_eth_type(), + .output_ip_version(), + .output_ip_ihl(), + .output_ip_dscp(ip_tx_ip_dscp), + .output_ip_ecn(ip_tx_ip_ecn), + .output_ip_length(ip_tx_ip_length), + .output_ip_identification(), + .output_ip_flags(), + .output_ip_fragment_offset(), + .output_ip_ttl(ip_tx_ip_ttl), + .output_ip_protocol(ip_tx_ip_protocol), + .output_ip_header_checksum(), + .output_ip_source_ip(ip_tx_ip_source_ip), + .output_ip_dest_ip(ip_tx_ip_dest_ip), + .output_ip_payload_tdata(ip_tx_ip_payload_tdata), + .output_ip_payload_tkeep(ip_tx_ip_payload_tkeep), + .output_ip_payload_tvalid(ip_tx_ip_payload_tvalid), + .output_ip_payload_tready(ip_tx_ip_payload_tready), + .output_ip_payload_tlast(ip_tx_ip_payload_tlast), + .output_ip_payload_tuser(ip_tx_ip_payload_tuser) +); + +/* + * IP stack + */ +ip_complete_64 #( + .ARP_CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT) +) +ip_complete_64_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(ip_tx_ip_hdr_valid), + .input_ip_hdr_ready(ip_tx_ip_hdr_ready), + .input_ip_dscp(ip_tx_ip_dscp), + .input_ip_ecn(ip_tx_ip_ecn), + .input_ip_length(ip_tx_ip_length), + .input_ip_ttl(ip_tx_ip_ttl), + .input_ip_protocol(ip_tx_ip_protocol), + .input_ip_source_ip(ip_tx_ip_source_ip), + .input_ip_dest_ip(ip_tx_ip_dest_ip), + .input_ip_payload_tdata(ip_tx_ip_payload_tdata), + .input_ip_payload_tkeep(ip_tx_ip_payload_tkeep), + .input_ip_payload_tvalid(ip_tx_ip_payload_tvalid), + .input_ip_payload_tready(ip_tx_ip_payload_tready), + .input_ip_payload_tlast(ip_tx_ip_payload_tlast), + .input_ip_payload_tuser(ip_tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(ip_rx_ip_hdr_valid), + .output_ip_hdr_ready(ip_rx_ip_hdr_ready), + .output_ip_eth_dest_mac(ip_rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(ip_rx_ip_eth_src_mac), + .output_ip_eth_type(ip_rx_ip_eth_type), + .output_ip_version(ip_rx_ip_version), + .output_ip_ihl(ip_rx_ip_ihl), + .output_ip_dscp(ip_rx_ip_dscp), + .output_ip_ecn(ip_rx_ip_ecn), + .output_ip_length(ip_rx_ip_length), + .output_ip_identification(ip_rx_ip_identification), + .output_ip_flags(ip_rx_ip_flags), + .output_ip_fragment_offset(ip_rx_ip_fragment_offset), + .output_ip_ttl(ip_rx_ip_ttl), + .output_ip_protocol(ip_rx_ip_protocol), + .output_ip_header_checksum(ip_rx_ip_header_checksum), + .output_ip_source_ip(ip_rx_ip_source_ip), + .output_ip_dest_ip(ip_rx_ip_dest_ip), + .output_ip_payload_tdata(ip_rx_ip_payload_tdata), + .output_ip_payload_tkeep(ip_rx_ip_payload_tkeep), + .output_ip_payload_tvalid(ip_rx_ip_payload_tvalid), + .output_ip_payload_tready(ip_rx_ip_payload_tready), + .output_ip_payload_tlast(ip_rx_ip_payload_tlast), + .output_ip_payload_tuser(ip_rx_ip_payload_tuser), + // Status + .rx_busy(ip_rx_busy), + .tx_busy(ip_tx_busy), + .rx_error_header_early_termination(ip_rx_error_header_early_termination), + .rx_error_payload_early_termination(ip_rx_error_payload_early_termination), + .rx_error_invalid_header(ip_rx_error_invalid_header), + .rx_error_invalid_checksum(ip_rx_error_invalid_checksum), + .tx_error_payload_early_termination(ip_tx_error_payload_early_termination), + .tx_error_arp_failed(ip_tx_error_arp_failed), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(clear_arp_cache) +); + +/* + * UDP interface + */ +udp_64 #( + .CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) +) +udp_64_inst ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(udp_rx_ip_hdr_valid), + .input_ip_hdr_ready(udp_rx_ip_hdr_ready), + .input_ip_eth_dest_mac(udp_rx_ip_eth_dest_mac), + .input_ip_eth_src_mac(udp_rx_ip_eth_src_mac), + .input_ip_eth_type(udp_rx_ip_eth_type), + .input_ip_version(udp_rx_ip_version), + .input_ip_ihl(udp_rx_ip_ihl), + .input_ip_dscp(udp_rx_ip_dscp), + .input_ip_ecn(udp_rx_ip_ecn), + .input_ip_length(udp_rx_ip_length), + .input_ip_identification(udp_rx_ip_identification), + .input_ip_flags(udp_rx_ip_flags), + .input_ip_fragment_offset(udp_rx_ip_fragment_offset), + .input_ip_ttl(udp_rx_ip_ttl), + .input_ip_protocol(udp_rx_ip_protocol), + .input_ip_header_checksum(udp_rx_ip_header_checksum), + .input_ip_source_ip(udp_rx_ip_source_ip), + .input_ip_dest_ip(udp_rx_ip_dest_ip), + .input_ip_payload_tdata(udp_rx_ip_payload_tdata), + .input_ip_payload_tkeep(udp_rx_ip_payload_tkeep), + .input_ip_payload_tvalid(udp_rx_ip_payload_tvalid), + .input_ip_payload_tready(udp_rx_ip_payload_tready), + .input_ip_payload_tlast(udp_rx_ip_payload_tlast), + .input_ip_payload_tuser(udp_rx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(udp_tx_ip_hdr_valid), + .output_ip_hdr_ready(udp_tx_ip_hdr_ready), + .output_ip_eth_dest_mac(), + .output_ip_eth_src_mac(), + .output_ip_eth_type(), + .output_ip_version(), + .output_ip_ihl(), + .output_ip_dscp(udp_tx_ip_dscp), + .output_ip_ecn(udp_tx_ip_ecn), + .output_ip_length(udp_tx_ip_length), + .output_ip_identification(), + .output_ip_flags(), + .output_ip_fragment_offset(), + .output_ip_ttl(udp_tx_ip_ttl), + .output_ip_protocol(udp_tx_ip_protocol), + .output_ip_header_checksum(), + .output_ip_source_ip(udp_tx_ip_source_ip), + .output_ip_dest_ip(udp_tx_ip_dest_ip), + .output_ip_payload_tdata(udp_tx_ip_payload_tdata), + .output_ip_payload_tkeep(udp_tx_ip_payload_tkeep), + .output_ip_payload_tvalid(udp_tx_ip_payload_tvalid), + .output_ip_payload_tready(udp_tx_ip_payload_tready), + .output_ip_payload_tlast(udp_tx_ip_payload_tlast), + .output_ip_payload_tuser(udp_tx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_udp_eth_dest_mac(0), + .input_udp_eth_src_mac(0), + .input_udp_eth_type(0), + .input_udp_ip_version(0), + .input_udp_ip_ihl(0), + .input_udp_ip_dscp(input_udp_ip_dscp), + .input_udp_ip_ecn(input_udp_ip_ecn), + .input_udp_ip_identification(0), + .input_udp_ip_flags(0), + .input_udp_ip_fragment_offset(0), + .input_udp_ip_ttl(input_udp_ip_ttl), + .input_udp_ip_header_checksum(0), + .input_udp_ip_source_ip(input_udp_ip_source_ip), + .input_udp_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tkeep(input_udp_payload_tkeep), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_udp_eth_dest_mac(output_udp_eth_dest_mac), + .output_udp_eth_src_mac(output_udp_eth_src_mac), + .output_udp_eth_type(output_udp_eth_type), + .output_udp_ip_version(output_udp_ip_version), + .output_udp_ip_ihl(output_udp_ip_ihl), + .output_udp_ip_dscp(output_udp_ip_dscp), + .output_udp_ip_ecn(output_udp_ip_ecn), + .output_udp_ip_length(output_udp_ip_length), + .output_udp_ip_identification(output_udp_ip_identification), + .output_udp_ip_flags(output_udp_ip_flags), + .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_udp_ip_ttl(output_udp_ip_ttl), + .output_udp_ip_protocol(output_udp_ip_protocol), + .output_udp_ip_header_checksum(output_udp_ip_header_checksum), + .output_udp_ip_source_ip(output_udp_ip_source_ip), + .output_udp_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status + .rx_busy(udp_rx_busy), + .tx_busy(udp_tx_busy), + .rx_error_header_early_termination(udp_rx_error_header_early_termination), + .rx_error_payload_early_termination(udp_rx_error_payload_early_termination), + .tx_error_payload_early_termination(udp_tx_error_payload_early_termination) +); + +endmodule diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py new file mode 100755 index 000000000..f50818cba --- /dev/null +++ b/tb/test_udp_complete.py @@ -0,0 +1,1108 @@ +#!/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 eth_ep +import arp_ep +import ip_ep +import udp_ep + +module = 'udp_complete' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/udp.v") +srcs.append("../rtl/udp_ip_rx.v") +srcs.append("../rtl/udp_ip_tx.v") +srcs.append("../rtl/ip_complete.v") +srcs.append("../rtl/ip.v") +srcs.append("../rtl/ip_eth_rx.v") +srcs.append("../rtl/ip_eth_tx.v") +srcs.append("../rtl/ip_arb_mux_2.v") +srcs.append("../rtl/ip_mux_2.v") +srcs.append("../rtl/arp.v") +srcs.append("../rtl/arp_cache.v") +srcs.append("../rtl/arp_eth_rx.v") +srcs.append("../rtl/arp_eth_tx.v") +srcs.append("../rtl/eth_arb_mux_2.v") +srcs.append("../rtl/eth_mux_2.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp_complete(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + input_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_ip_eth_dest_mac=output_ip_eth_dest_mac, + output_ip_eth_src_mac=output_ip_eth_src_mac, + output_ip_eth_type=output_ip_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + input_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_udp_ip_dscp=input_udp_ip_dscp, + input_udp_ip_ecn=input_udp_ip_ecn, + input_udp_ip_ttl=input_udp_ip_ttl, + input_udp_ip_source_ip=input_udp_ip_source_ip, + input_udp_ip_dest_ip=input_udp_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_length=input_udp_length, + input_udp_checksum=input_udp_checksum, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_udp_eth_dest_mac=output_udp_eth_dest_mac, + output_udp_eth_src_mac=output_udp_eth_src_mac, + output_udp_eth_type=output_udp_eth_type, + output_udp_ip_version=output_udp_ip_version, + output_udp_ip_ihl=output_udp_ip_ihl, + output_udp_ip_dscp=output_udp_ip_dscp, + output_udp_ip_ecn=output_udp_ip_ecn, + output_udp_ip_length=output_udp_ip_length, + output_udp_ip_identification=output_udp_ip_identification, + output_udp_ip_flags=output_udp_ip_flags, + output_udp_ip_fragment_offset=output_udp_ip_fragment_offset, + output_udp_ip_ttl=output_udp_ip_ttl, + output_udp_ip_protocol=output_udp_ip_protocol, + output_udp_ip_header_checksum=output_udp_ip_header_checksum, + output_udp_ip_source_ip=output_udp_ip_source_ip, + output_udp_ip_dest_ip=output_udp_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + ip_rx_busy=ip_rx_busy, + ip_tx_busy=ip_tx_busy, + udp_rx_busy=udp_rx_busy, + udp_tx_busy=udp_tx_busy, + ip_rx_error_header_early_termination=ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination=ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header=ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum=ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination=ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed=ip_tx_error_arp_failed, + udp_rx_error_header_early_termination=udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination=udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination=udp_tx_error_payload_early_termination, + + local_mac=local_mac, + local_ip=local_ip, + gateway_ip=gateway_ip, + subnet_mask=subnet_mask, + clear_arp_cache=clear_arp_cache) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + input_ip_hdr_valid = Signal(bool(0)) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + input_udp_hdr_valid = Signal(bool(0)) + input_udp_ip_dscp = Signal(intbv(0)[6:]) + input_udp_ip_ecn = Signal(intbv(0)[2:]) + input_udp_ip_ttl = Signal(intbv(0)[8:]) + input_udp_ip_source_ip = Signal(intbv(0)[32:]) + input_udp_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_length = Signal(intbv(0)[16:]) + input_udp_checksum = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + output_udp_payload_tready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_ip_eth_dest_mac = Signal(intbv(0)[48:]) + output_ip_eth_src_mac = Signal(intbv(0)[48:]) + output_ip_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + output_udp_hdr_valid = Signal(bool(0)) + output_udp_eth_dest_mac = Signal(intbv(0)[48:]) + output_udp_eth_src_mac = Signal(intbv(0)[48:]) + output_udp_eth_type = Signal(intbv(0)[16:]) + output_udp_ip_version = Signal(intbv(0)[4:]) + output_udp_ip_ihl = Signal(intbv(0)[4:]) + output_udp_ip_dscp = Signal(intbv(0)[6:]) + output_udp_ip_ecn = Signal(intbv(0)[2:]) + output_udp_ip_length = Signal(intbv(0)[16:]) + output_udp_ip_identification = Signal(intbv(0)[16:]) + output_udp_ip_flags = Signal(intbv(0)[3:]) + output_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + output_udp_ip_ttl = Signal(intbv(0)[8:]) + output_udp_ip_protocol = Signal(intbv(0)[8:]) + output_udp_ip_header_checksum = Signal(intbv(0)[16:]) + output_udp_ip_source_ip = Signal(intbv(0)[32:]) + output_udp_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + ip_rx_busy = Signal(bool(0)) + ip_tx_busy = Signal(bool(0)) + udp_rx_busy = Signal(bool(0)) + udp_tx_busy = Signal(bool(0)) + ip_rx_error_header_early_termination = Signal(bool(0)) + ip_rx_error_payload_early_termination = Signal(bool(0)) + ip_rx_error_invalid_header = Signal(bool(0)) + ip_rx_error_invalid_checksum = Signal(bool(0)) + ip_tx_error_payload_early_termination = Signal(bool(0)) + ip_tx_error_arp_failed = Signal(bool(0)) + udp_rx_error_header_early_termination = Signal(bool(0)) + udp_rx_error_payload_early_termination = Signal(bool(0)) + udp_tx_error_payload_early_termination = Signal(bool(0)) + local_mac = Signal(intbv(0)[48:]) + local_ip = Signal(intbv(0)[32:]) + gateway_ip = Signal(intbv(0)[32:]) + subnet_mask = Signal(intbv(0)[32:]) + clear_arp_cache = Signal(bool(0)) + + # sources and sinks + eth_source_queue = Queue() + eth_source_pause = Signal(bool(0)) + eth_sink_queue = Queue() + eth_sink_pause = Signal(bool(0)) + ip_source_queue = Queue() + ip_source_pause = Signal(bool(0)) + ip_sink_queue = Queue() + ip_sink_pause = Signal(bool(0)) + udp_source_queue = Queue() + udp_source_pause = Signal(bool(0)) + udp_sink_queue = Queue() + udp_sink_pause = Signal(bool(0)) + + eth_source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=eth_source_queue, + pause=eth_source_pause, + name='eth_source') + + eth_sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=eth_sink_queue, + pause=eth_sink_pause, + name='eth_sink') + + ip_source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=ip_source_queue, + pause=ip_source_pause, + name='ip_source') + + ip_sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_ip_eth_dest_mac, + eth_src_mac=output_ip_eth_src_mac, + eth_type=output_ip_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=ip_sink_queue, + pause=ip_sink_pause, + name='ip_sink') + + udp_source = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_valid=input_udp_hdr_valid, + udp_hdr_ready=input_udp_hdr_ready, + ip_dscp=input_udp_ip_dscp, + ip_ecn=input_udp_ip_ecn, + ip_ttl=input_udp_ip_ttl, + ip_source_ip=input_udp_ip_source_ip, + ip_dest_ip=input_udp_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_length=input_udp_length, + udp_checksum=input_udp_checksum, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + fifo=udp_source_queue, + pause=udp_source_pause, + name='udp_source') + + udp_sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_udp_eth_dest_mac, + eth_src_mac=output_udp_eth_src_mac, + eth_type=output_udp_eth_type, + ip_version=output_udp_ip_version, + ip_ihl=output_udp_ip_ihl, + ip_dscp=output_udp_ip_dscp, + ip_ecn=output_udp_ip_ecn, + ip_length=output_udp_ip_length, + ip_identification=output_udp_ip_identification, + ip_flags=output_udp_ip_flags, + ip_fragment_offset=output_udp_ip_fragment_offset, + ip_ttl=output_udp_ip_ttl, + ip_protocol=output_udp_ip_protocol, + ip_header_checksum=output_udp_ip_header_checksum, + ip_source_ip=output_udp_ip_source_ip, + ip_dest_ip=output_udp_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=udp_sink_queue, + pause=udp_sink_pause, + name='udp_sink') + + # DUT + dut = dut_udp_complete(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + ip_rx_error_header_early_termination_asserted = Signal(bool(0)) + ip_rx_error_payload_early_termination_asserted = Signal(bool(0)) + ip_rx_error_invalid_header_asserted = Signal(bool(0)) + ip_rx_error_invalid_checksum_asserted = Signal(bool(0)) + ip_tx_error_payload_early_termination_asserted = Signal(bool(0)) + ip_tx_error_arp_failed_asserted = Signal(bool(0)) + udp_rx_error_header_early_termination_asserted = Signal(bool(0)) + udp_rx_error_payload_early_termination_asserted = Signal(bool(0)) + udp_tx_error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (ip_rx_error_header_early_termination): + ip_rx_error_header_early_termination_asserted.next = 1 + if (ip_rx_error_payload_early_termination): + ip_rx_error_payload_early_termination_asserted.next = 1 + if (ip_rx_error_invalid_header): + ip_rx_error_invalid_header_asserted.next = 1 + if (ip_rx_error_invalid_checksum): + ip_rx_error_invalid_checksum_asserted.next = 1 + if (ip_tx_error_payload_early_termination): + ip_tx_error_payload_early_termination_asserted.next = 1 + if (ip_tx_error_arp_failed): + ip_tx_error_arp_failed_asserted.next = 1 + if (udp_rx_error_header_early_termination): + udp_rx_error_header_early_termination_asserted.next = 1 + if (udp_rx_error_payload_early_termination): + udp_rx_error_payload_early_termination_asserted.next = 1 + if (udp_tx_error_payload_early_termination): + udp_tx_error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or + output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or + input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # set MAC and IP address + local_mac.next = 0x5A5152535455 + local_ip.next = 0xc0a80164 + gateway_ip.next = 0xc0a80101 + subnet_mask.next = 0xffffff00 + + yield clk.posedge + print("test 1: test IP RX packet") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = ip_sink_queue.get(False) + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test IP TX packet") + current_test.next = 2 + + # send IP packet + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + # wait for ARP request packet + while eth_sink_queue.empty(): + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80166 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x5A5152535455 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80166 + arp_frame.arp_tha = 0x5A5152535455 + arp_frame.arp_tpa = 0xc0a80164 + eth_source_queue.put(arp_frame.build_eth()) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + print(test_frame) + print(check_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: test IP TX arp fail packet") + current_test.next = 2 + + ip_tx_error_arp_failed_asserted.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80167 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + assert ip_tx_error_arp_failed_asserted + + # check for 4 ARP requests + assert eth_sink_queue.qsize() == 4 + + while not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get(False) + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80167 + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: test UDP RX packet") + current_test.next = 4 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not udp_sink_queue.empty(): + rx_frame = udp_sink_queue.get() + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: test UDP TX packet") + current_test.next = 5 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + udp_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, eth_source, eth_sink, ip_source, ip_sink, udp_source, udp_sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_complete.v b/tb/test_udp_complete.v new file mode 100644 index 000000000..76e5b1e30 --- /dev/null +++ b/tb/test_udp_complete.v @@ -0,0 +1,440 @@ +/* + +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_udp_complete; + +// Parameters +parameter ARP_CACHE_ADDR_WIDTH = 2; +parameter ARP_REQUEST_RETRY_COUNT = 4; +parameter ARP_REQUEST_RETRY_INTERVAL = 150; +parameter ARP_REQUEST_TIMEOUT = 400; +parameter UDP_CHECKSUM_ENABLE = 0; +parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11; +parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [7:0] input_eth_payload_tdata = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg arp_response_valid = 0; +reg arp_response_error = 0; +reg [47:0] arp_response_mac = 0; +reg input_ip_hdr_valid = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [7:0] input_ip_payload_tdata = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg input_udp_hdr_valid = 0; +reg [5:0] input_udp_ip_dscp = 0; +reg [1:0] input_udp_ip_ecn = 0; +reg [7:0] input_udp_ip_ttl = 0; +reg [31:0] input_udp_ip_source_ip = 0; +reg [31:0] input_udp_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [15:0] input_udp_length = 0; +reg [15:0] input_udp_checksum = 0; +reg [7:0] input_udp_payload_tdata = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; +reg [47:0] local_mac = 0; +reg [31:0] local_ip = 0; +reg [31:0] gateway_ip = 0; +reg [31:0] subnet_mask = 0; +reg clear_arp_cache = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire input_udp_hdr_ready; +wire input_udp_payload_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [7:0] output_eth_payload_tdata; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire arp_request_valid; +wire [31:0] arp_request_ip; +wire output_ip_hdr_valid; +wire [47:0] output_ip_eth_dest_mac; +wire [47:0] output_ip_eth_src_mac; +wire [15:0] output_ip_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [7:0] output_ip_payload_tdata; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire output_udp_hdr_valid; +wire [47:0] output_udp_eth_dest_mac; +wire [47:0] output_udp_eth_src_mac; +wire [15:0] output_udp_eth_type; +wire [3:0] output_udp_ip_version; +wire [3:0] output_udp_ip_ihl; +wire [5:0] output_udp_ip_dscp; +wire [1:0] output_udp_ip_ecn; +wire [15:0] output_udp_ip_length; +wire [15:0] output_udp_ip_identification; +wire [2:0] output_udp_ip_flags; +wire [12:0] output_udp_ip_fragment_offset; +wire [7:0] output_udp_ip_ttl; +wire [7:0] output_udp_ip_protocol; +wire [15:0] output_udp_ip_header_checksum; +wire [31:0] output_udp_ip_source_ip; +wire [31:0] output_udp_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [7:0] output_udp_payload_tdata; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; +wire ip_rx_busy; +wire ip_tx_busy; +wire udp_rx_busy; +wire udp_tx_busy; +wire ip_rx_error_header_early_termination; +wire ip_rx_error_payload_early_termination; +wire ip_rx_error_invalid_header; +wire ip_rx_error_invalid_checksum; +wire ip_tx_error_payload_early_termination; +wire ip_tx_error_arp_failed; +wire udp_rx_error_header_early_termination; +wire udp_rx_error_payload_early_termination; +wire udp_tx_error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + input_ip_hdr_valid, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + input_udp_hdr_valid, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + output_ip_hdr_ready, + output_ip_payload_tready, + output_udp_hdr_ready, + output_udp_payload_tready, + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + input_ip_hdr_ready, + input_ip_payload_tready, + input_udp_hdr_ready, + input_udp_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + output_ip_hdr_valid, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + output_udp_hdr_valid, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser, + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination); + + // dump file + $dumpfile("test_udp_complete.lxt"); + $dumpvars(0, test_udp_complete); +end + +udp_complete #( + .ARP_CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT), + .UDP_CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_udp_ip_dscp(input_udp_ip_dscp), + .input_udp_ip_ecn(input_udp_ip_ecn), + .input_udp_ip_ttl(input_udp_ip_ttl), + .input_udp_ip_source_ip(input_udp_ip_source_ip), + .input_udp_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_udp_eth_dest_mac(output_udp_eth_dest_mac), + .output_udp_eth_src_mac(output_udp_eth_src_mac), + .output_udp_eth_type(output_udp_eth_type), + .output_udp_ip_version(output_udp_ip_version), + .output_udp_ip_ihl(output_udp_ip_ihl), + .output_udp_ip_dscp(output_udp_ip_dscp), + .output_udp_ip_ecn(output_udp_ip_ecn), + .output_udp_ip_length(output_udp_ip_length), + .output_udp_ip_identification(output_udp_ip_identification), + .output_udp_ip_flags(output_udp_ip_flags), + .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_udp_ip_ttl(output_udp_ip_ttl), + .output_udp_ip_protocol(output_udp_ip_protocol), + .output_udp_ip_header_checksum(output_udp_ip_header_checksum), + .output_udp_ip_source_ip(output_udp_ip_source_ip), + .output_udp_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status signals + .ip_rx_busy(ip_rx_busy), + .ip_tx_busy(ip_tx_busy), + .udp_rx_busy(udp_rx_busy), + .udp_tx_busy(udp_tx_busy), + .ip_rx_error_header_early_termination(ip_rx_error_header_early_termination), + .ip_rx_error_payload_early_termination(ip_rx_error_payload_early_termination), + .ip_rx_error_invalid_header(ip_rx_error_invalid_header), + .ip_rx_error_invalid_checksum(ip_rx_error_invalid_checksum), + .ip_tx_error_payload_early_termination(ip_tx_error_payload_early_termination), + .ip_tx_error_arp_failed(ip_tx_error_arp_failed), + .udp_rx_error_header_early_termination(udp_rx_error_header_early_termination), + .udp_rx_error_payload_early_termination(udp_rx_error_payload_early_termination), + .udp_tx_error_payload_early_termination(udp_tx_error_payload_early_termination), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(clear_arp_cache) +); + +endmodule diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py new file mode 100755 index 000000000..98833866c --- /dev/null +++ b/tb/test_udp_complete_64.py @@ -0,0 +1,1138 @@ +#!/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 eth_ep +import arp_ep +import ip_ep +import udp_ep + +module = 'udp_complete_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/udp_64.v") +srcs.append("../rtl/udp_ip_rx_64.v") +srcs.append("../rtl/udp_ip_tx_64.v") +srcs.append("../rtl/ip_complete_64.v") +srcs.append("../rtl/ip_64.v") +srcs.append("../rtl/ip_eth_rx_64.v") +srcs.append("../rtl/ip_eth_tx_64.v") +srcs.append("../rtl/ip_arb_mux_64_2.v") +srcs.append("../rtl/ip_mux_64_2.v") +srcs.append("../rtl/arp_64.v") +srcs.append("../rtl/arp_cache.v") +srcs.append("../rtl/arp_eth_rx_64.v") +srcs.append("../rtl/arp_eth_tx_64.v") +srcs.append("../rtl/eth_arb_mux_64_2.v") +srcs.append("../rtl/eth_mux_64_2.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp_complete(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache): + + 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_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + input_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tkeep=input_ip_payload_tkeep, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_ip_eth_dest_mac=output_ip_eth_dest_mac, + output_ip_eth_src_mac=output_ip_eth_src_mac, + output_ip_eth_type=output_ip_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tkeep=output_ip_payload_tkeep, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + input_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_udp_ip_dscp=input_udp_ip_dscp, + input_udp_ip_ecn=input_udp_ip_ecn, + input_udp_ip_ttl=input_udp_ip_ttl, + input_udp_ip_source_ip=input_udp_ip_source_ip, + input_udp_ip_dest_ip=input_udp_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_length=input_udp_length, + input_udp_checksum=input_udp_checksum, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tkeep=input_udp_payload_tkeep, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_udp_eth_dest_mac=output_udp_eth_dest_mac, + output_udp_eth_src_mac=output_udp_eth_src_mac, + output_udp_eth_type=output_udp_eth_type, + output_udp_ip_version=output_udp_ip_version, + output_udp_ip_ihl=output_udp_ip_ihl, + output_udp_ip_dscp=output_udp_ip_dscp, + output_udp_ip_ecn=output_udp_ip_ecn, + output_udp_ip_length=output_udp_ip_length, + output_udp_ip_identification=output_udp_ip_identification, + output_udp_ip_flags=output_udp_ip_flags, + output_udp_ip_fragment_offset=output_udp_ip_fragment_offset, + output_udp_ip_ttl=output_udp_ip_ttl, + output_udp_ip_protocol=output_udp_ip_protocol, + output_udp_ip_header_checksum=output_udp_ip_header_checksum, + output_udp_ip_source_ip=output_udp_ip_source_ip, + output_udp_ip_dest_ip=output_udp_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tkeep=output_udp_payload_tkeep, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + ip_rx_busy=ip_rx_busy, + ip_tx_busy=ip_tx_busy, + udp_rx_busy=udp_rx_busy, + udp_tx_busy=udp_tx_busy, + ip_rx_error_header_early_termination=ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination=ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header=ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum=ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination=ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed=ip_tx_error_arp_failed, + udp_rx_error_header_early_termination=udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination=udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination=udp_tx_error_payload_early_termination, + + local_mac=local_mac, + local_ip=local_ip, + gateway_ip=gateway_ip, + subnet_mask=subnet_mask, + clear_arp_cache=clear_arp_cache) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[64:]) + input_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + input_ip_hdr_valid = Signal(bool(0)) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[64:]) + input_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + input_udp_hdr_valid = Signal(bool(0)) + input_udp_ip_dscp = Signal(intbv(0)[6:]) + input_udp_ip_ecn = Signal(intbv(0)[2:]) + input_udp_ip_ttl = Signal(intbv(0)[8:]) + input_udp_ip_source_ip = Signal(intbv(0)[32:]) + input_udp_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_length = Signal(intbv(0)[16:]) + input_udp_checksum = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[64:]) + input_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + output_udp_payload_tready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[64:]) + output_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_ip_eth_dest_mac = Signal(intbv(0)[48:]) + output_ip_eth_src_mac = Signal(intbv(0)[48:]) + output_ip_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[64:]) + output_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + output_udp_hdr_valid = Signal(bool(0)) + output_udp_eth_dest_mac = Signal(intbv(0)[48:]) + output_udp_eth_src_mac = Signal(intbv(0)[48:]) + output_udp_eth_type = Signal(intbv(0)[16:]) + output_udp_ip_version = Signal(intbv(0)[4:]) + output_udp_ip_ihl = Signal(intbv(0)[4:]) + output_udp_ip_dscp = Signal(intbv(0)[6:]) + output_udp_ip_ecn = Signal(intbv(0)[2:]) + output_udp_ip_length = Signal(intbv(0)[16:]) + output_udp_ip_identification = Signal(intbv(0)[16:]) + output_udp_ip_flags = Signal(intbv(0)[3:]) + output_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + output_udp_ip_ttl = Signal(intbv(0)[8:]) + output_udp_ip_protocol = Signal(intbv(0)[8:]) + output_udp_ip_header_checksum = Signal(intbv(0)[16:]) + output_udp_ip_source_ip = Signal(intbv(0)[32:]) + output_udp_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[64:]) + output_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + ip_rx_busy = Signal(bool(0)) + ip_tx_busy = Signal(bool(0)) + udp_rx_busy = Signal(bool(0)) + udp_tx_busy = Signal(bool(0)) + ip_rx_error_header_early_termination = Signal(bool(0)) + ip_rx_error_payload_early_termination = Signal(bool(0)) + ip_rx_error_invalid_header = Signal(bool(0)) + ip_rx_error_invalid_checksum = Signal(bool(0)) + ip_tx_error_payload_early_termination = Signal(bool(0)) + ip_tx_error_arp_failed = Signal(bool(0)) + udp_rx_error_header_early_termination = Signal(bool(0)) + udp_rx_error_payload_early_termination = Signal(bool(0)) + udp_tx_error_payload_early_termination = Signal(bool(0)) + local_mac = Signal(intbv(0)[48:]) + local_ip = Signal(intbv(0)[32:]) + gateway_ip = Signal(intbv(0)[32:]) + subnet_mask = Signal(intbv(0)[32:]) + clear_arp_cache = Signal(bool(0)) + + # sources and sinks + eth_source_queue = Queue() + eth_source_pause = Signal(bool(0)) + eth_sink_queue = Queue() + eth_sink_pause = Signal(bool(0)) + ip_source_queue = Queue() + ip_source_pause = Signal(bool(0)) + ip_sink_queue = Queue() + ip_sink_pause = Signal(bool(0)) + udp_source_queue = Queue() + udp_source_pause = Signal(bool(0)) + udp_sink_queue = Queue() + udp_sink_pause = Signal(bool(0)) + + eth_source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=eth_source_queue, + pause=eth_source_pause, + name='eth_source') + + eth_sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=eth_sink_queue, + pause=eth_sink_pause, + name='eth_sink') + + ip_source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tkeep=input_ip_payload_tkeep, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=ip_source_queue, + pause=ip_source_pause, + name='ip_source') + + ip_sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_ip_eth_dest_mac, + eth_src_mac=output_ip_eth_src_mac, + eth_type=output_ip_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tkeep=output_ip_payload_tkeep, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=ip_sink_queue, + pause=ip_sink_pause, + name='ip_sink') + + udp_source = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_valid=input_udp_hdr_valid, + udp_hdr_ready=input_udp_hdr_ready, + ip_dscp=input_udp_ip_dscp, + ip_ecn=input_udp_ip_ecn, + ip_ttl=input_udp_ip_ttl, + ip_source_ip=input_udp_ip_source_ip, + ip_dest_ip=input_udp_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_length=input_udp_length, + udp_checksum=input_udp_checksum, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tkeep=input_udp_payload_tkeep, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + fifo=udp_source_queue, + pause=udp_source_pause, + name='udp_source') + + udp_sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_udp_eth_dest_mac, + eth_src_mac=output_udp_eth_src_mac, + eth_type=output_udp_eth_type, + ip_version=output_udp_ip_version, + ip_ihl=output_udp_ip_ihl, + ip_dscp=output_udp_ip_dscp, + ip_ecn=output_udp_ip_ecn, + ip_length=output_udp_ip_length, + ip_identification=output_udp_ip_identification, + ip_flags=output_udp_ip_flags, + ip_fragment_offset=output_udp_ip_fragment_offset, + ip_ttl=output_udp_ip_ttl, + ip_protocol=output_udp_ip_protocol, + ip_header_checksum=output_udp_ip_header_checksum, + ip_source_ip=output_udp_ip_source_ip, + ip_dest_ip=output_udp_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tkeep=output_udp_payload_tkeep, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=udp_sink_queue, + pause=udp_sink_pause, + name='udp_sink') + + # DUT + dut = dut_udp_complete(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + ip_rx_error_header_early_termination_asserted = Signal(bool(0)) + ip_rx_error_payload_early_termination_asserted = Signal(bool(0)) + ip_rx_error_invalid_header_asserted = Signal(bool(0)) + ip_rx_error_invalid_checksum_asserted = Signal(bool(0)) + ip_tx_error_payload_early_termination_asserted = Signal(bool(0)) + ip_tx_error_arp_failed_asserted = Signal(bool(0)) + udp_rx_error_header_early_termination_asserted = Signal(bool(0)) + udp_rx_error_payload_early_termination_asserted = Signal(bool(0)) + udp_tx_error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (ip_rx_error_header_early_termination): + ip_rx_error_header_early_termination_asserted.next = 1 + if (ip_rx_error_payload_early_termination): + ip_rx_error_payload_early_termination_asserted.next = 1 + if (ip_rx_error_invalid_header): + ip_rx_error_invalid_header_asserted.next = 1 + if (ip_rx_error_invalid_checksum): + ip_rx_error_invalid_checksum_asserted.next = 1 + if (ip_tx_error_payload_early_termination): + ip_tx_error_payload_early_termination_asserted.next = 1 + if (ip_tx_error_arp_failed): + ip_tx_error_arp_failed_asserted.next = 1 + if (udp_rx_error_header_early_termination): + udp_rx_error_header_early_termination_asserted.next = 1 + if (udp_rx_error_payload_early_termination): + udp_rx_error_payload_early_termination_asserted.next = 1 + if (udp_tx_error_payload_early_termination): + udp_tx_error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or + output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or + input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # set MAC and IP address + local_mac.next = 0x5A5152535455 + local_ip.next = 0xc0a80164 + gateway_ip.next = 0xc0a80101 + subnet_mask.next = 0xffffff00 + + yield clk.posedge + print("test 1: test IP RX packet") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = ip_sink_queue.get(False) + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test IP TX packet") + current_test.next = 2 + + # send IP packet + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + # wait for ARP request packet + while eth_sink_queue.empty(): + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80166 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x5A5152535455 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80166 + arp_frame.arp_tha = 0x5A5152535455 + arp_frame.arp_tpa = 0xc0a80164 + eth_source_queue.put(arp_frame.build_eth()) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + print(test_frame) + print(check_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: test IP TX arp fail packet") + current_test.next = 2 + + ip_tx_error_arp_failed_asserted.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80167 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + assert ip_tx_error_arp_failed_asserted + + # check for 4 ARP requests + assert eth_sink_queue.qsize() == 4 + + while not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get(False) + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80167 + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: test UDP RX packet") + current_test.next = 4 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not udp_sink_queue.empty(): + rx_frame = udp_sink_queue.get() + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: test UDP TX packet") + current_test.next = 5 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + udp_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, eth_source, eth_sink, ip_source, ip_sink, udp_source, udp_sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_complete_64.v b/tb/test_udp_complete_64.v new file mode 100644 index 000000000..36e19c609 --- /dev/null +++ b/tb/test_udp_complete_64.v @@ -0,0 +1,458 @@ +/* + +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_udp_complete_64; + +// Parameters +parameter ARP_CACHE_ADDR_WIDTH = 2; +parameter ARP_REQUEST_RETRY_COUNT = 4; +parameter ARP_REQUEST_RETRY_INTERVAL = 150; +parameter ARP_REQUEST_TIMEOUT = 400; +parameter UDP_CHECKSUM_ENABLE = 0; +parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11; +parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [63:0] input_eth_payload_tdata = 0; +reg [7:0] input_eth_payload_tkeep = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg arp_response_valid = 0; +reg arp_response_error = 0; +reg [47:0] arp_response_mac = 0; +reg input_ip_hdr_valid = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [63:0] input_ip_payload_tdata = 0; +reg [7:0] input_ip_payload_tkeep = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg input_udp_hdr_valid = 0; +reg [5:0] input_udp_ip_dscp = 0; +reg [1:0] input_udp_ip_ecn = 0; +reg [7:0] input_udp_ip_ttl = 0; +reg [31:0] input_udp_ip_source_ip = 0; +reg [31:0] input_udp_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [15:0] input_udp_length = 0; +reg [15:0] input_udp_checksum = 0; +reg [63:0] input_udp_payload_tdata = 0; +reg [7:0] input_udp_payload_tkeep = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; +reg [47:0] local_mac = 0; +reg [31:0] local_ip = 0; +reg [31:0] gateway_ip = 0; +reg [31:0] subnet_mask = 0; +reg clear_arp_cache = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire input_udp_hdr_ready; +wire input_udp_payload_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [63:0] output_eth_payload_tdata; +wire [7:0] output_eth_payload_tkeep; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire arp_request_valid; +wire [31:0] arp_request_ip; +wire output_ip_hdr_valid; +wire [47:0] output_ip_eth_dest_mac; +wire [47:0] output_ip_eth_src_mac; +wire [15:0] output_ip_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [63:0] output_ip_payload_tdata; +wire [7:0] output_ip_payload_tkeep; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire output_udp_hdr_valid; +wire [47:0] output_udp_eth_dest_mac; +wire [47:0] output_udp_eth_src_mac; +wire [15:0] output_udp_eth_type; +wire [3:0] output_udp_ip_version; +wire [3:0] output_udp_ip_ihl; +wire [5:0] output_udp_ip_dscp; +wire [1:0] output_udp_ip_ecn; +wire [15:0] output_udp_ip_length; +wire [15:0] output_udp_ip_identification; +wire [2:0] output_udp_ip_flags; +wire [12:0] output_udp_ip_fragment_offset; +wire [7:0] output_udp_ip_ttl; +wire [7:0] output_udp_ip_protocol; +wire [15:0] output_udp_ip_header_checksum; +wire [31:0] output_udp_ip_source_ip; +wire [31:0] output_udp_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [63:0] output_udp_payload_tdata; +wire [7:0] output_udp_payload_tkeep; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; +wire ip_rx_busy; +wire ip_tx_busy; +wire udp_rx_busy; +wire udp_tx_busy; +wire ip_rx_error_header_early_termination; +wire ip_rx_error_payload_early_termination; +wire ip_rx_error_invalid_header; +wire ip_rx_error_invalid_checksum; +wire ip_tx_error_payload_early_termination; +wire ip_tx_error_arp_failed; +wire udp_rx_error_header_early_termination; +wire udp_rx_error_payload_early_termination; +wire udp_tx_error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + input_ip_hdr_valid, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + input_udp_hdr_valid, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + output_ip_hdr_ready, + output_ip_payload_tready, + output_udp_hdr_ready, + output_udp_payload_tready, + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + input_ip_hdr_ready, + input_ip_payload_tready, + input_udp_hdr_ready, + input_udp_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + output_ip_hdr_valid, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + output_udp_hdr_valid, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser, + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination); + + // dump file + $dumpfile("test_udp_complete_64.lxt"); + $dumpvars(0, test_udp_complete_64); +end + +udp_complete_64 #( + .ARP_CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT), + .UDP_CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_udp_ip_dscp(input_udp_ip_dscp), + .input_udp_ip_ecn(input_udp_ip_ecn), + .input_udp_ip_ttl(input_udp_ip_ttl), + .input_udp_ip_source_ip(input_udp_ip_source_ip), + .input_udp_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tkeep(input_udp_payload_tkeep), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_udp_eth_dest_mac(output_udp_eth_dest_mac), + .output_udp_eth_src_mac(output_udp_eth_src_mac), + .output_udp_eth_type(output_udp_eth_type), + .output_udp_ip_version(output_udp_ip_version), + .output_udp_ip_ihl(output_udp_ip_ihl), + .output_udp_ip_dscp(output_udp_ip_dscp), + .output_udp_ip_ecn(output_udp_ip_ecn), + .output_udp_ip_length(output_udp_ip_length), + .output_udp_ip_identification(output_udp_ip_identification), + .output_udp_ip_flags(output_udp_ip_flags), + .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_udp_ip_ttl(output_udp_ip_ttl), + .output_udp_ip_protocol(output_udp_ip_protocol), + .output_udp_ip_header_checksum(output_udp_ip_header_checksum), + .output_udp_ip_source_ip(output_udp_ip_source_ip), + .output_udp_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status signals + .ip_rx_busy(ip_rx_busy), + .ip_tx_busy(ip_tx_busy), + .udp_rx_busy(udp_rx_busy), + .udp_tx_busy(udp_tx_busy), + .ip_rx_error_header_early_termination(ip_rx_error_header_early_termination), + .ip_rx_error_payload_early_termination(ip_rx_error_payload_early_termination), + .ip_rx_error_invalid_header(ip_rx_error_invalid_header), + .ip_rx_error_invalid_checksum(ip_rx_error_invalid_checksum), + .ip_tx_error_payload_early_termination(ip_tx_error_payload_early_termination), + .ip_tx_error_arp_failed(ip_tx_error_arp_failed), + .udp_rx_error_header_early_termination(udp_rx_error_header_early_termination), + .udp_rx_error_payload_early_termination(udp_rx_error_payload_early_termination), + .udp_tx_error_payload_early_termination(udp_tx_error_payload_early_termination), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(clear_arp_cache) +); + +endmodule From 1ec5012cd8f2787053e1ea3534bfb261f5a89732 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 22:57:39 -0800 Subject: [PATCH 154/617] Update readme --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index 05aec6d63..e4b537930 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,16 @@ priority and round-robin arbitration. Can be generated with arbitrary port counts with ip_mux_64.py. +### udp module + +UDP block with 8 bit data width for gigabit Ethernet. Manages UDP packet +transmssion and reception. + +### udp_64 module + +UDP block with 64 bit data width for 10G Ethernet. Manages UDP packet +transmssion and reception. + ### udp_arb_mux_N module UDP frame arbitrated muliplexer with 8 bit data width for gigabit @@ -227,6 +237,19 @@ Supports priority and round-robin arbitration. Can be generated with arbitrary port counts with udp_arb_mux_64.py. +### udp_complete module + +UDP module with IPv4 and ARP integration. + +Top level for gigabit UDP stack. + +### udp_complete_64 module + +UDP module with IPv4 and ARP integration and 64 bit data width for 10G +Ethernet. + +Top level for 10G UDP stack. + ### udp_ip_rx module UDP frame receiver. @@ -344,10 +367,14 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/ip_mux_4.v : 4 port IP frame multiplexer rtl/ip_mux_64.py : IP frame multiplexer generator (64 bit) rtl/ip_mux_64_4.v : 4 port IP frame multiplexer (64 bit) + rtl/udp.v : UDP block + rtl/udp_64.v : UDP block (64 bit) rtl/udp_arb_mux.py : UDP frame arbitrated multiplexer generator rtl/udp_arb_mux_4.v : 4 port UDP frame arbitrated multiplexer rtl/udp_arb_mux_64.py : UDP frame arbitrated multiplexer generator (64 bit) rtl/udp_arb_mux_64_4.v : 4 port UDP frame arbitrated multiplexer (64 bit) + rtl/udp_complete.v : UDP stack (IP-ARP-UDP) + rtl/udp_complete_64.v : UDP stack (IP-ARP-UDP) (64 bit) rtl/udp_ip_rx.v : UDP frame receiver rtl/udp_ip_rx_64.v : UDP frame receiver (64 bit) rtl/udp_ip_tx.v : UDP frame transmitter From 3ef81acbb7664346bf9a0883385ebd251adee09e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 26 Feb 2015 23:09:37 -0800 Subject: [PATCH 155/617] Update readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index e4b537930..7fa37cd4a 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ Ethernet frames as well as IP, UDP, and ARP and the components for constructing a complete UDP/IP stack. Includes full MyHDL testbench with intelligent bus cosimulation endpoints. +For IP and ARP support only, use ip_complete (1G) or ip_complete_64 (10G). + +For UDP, IP, and ARP support, use udp_complete (1G) or udp_complete_64 (10G). + ## Documentation ### arp module From 6b4dd02946a1c911076ca732b7e337882c0087fa Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 28 Feb 2015 00:43:27 -0800 Subject: [PATCH 156/617] Resolve multiple driver issue --- rtl/ip_eth_rx.v | 4 ---- rtl/ip_eth_rx_64.v | 4 ---- rtl/udp_ip_tx.v | 4 ---- rtl/udp_ip_tx_64.v | 4 ---- 4 files changed, 16 deletions(-) diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index a1955ed25..0d95789f9 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -450,10 +450,6 @@ always @(posedge clk or posedge rst) begin output_ip_header_checksum_reg <= 0; output_ip_source_ip_reg <= 0; output_ip_dest_ip_reg <= 0; - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; busy_reg <= 0; error_header_early_termination_reg <= 0; error_payload_early_termination_reg <= 0; diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 3c32b78f1..ca2cfaa10 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -514,10 +514,6 @@ always @(posedge clk or posedge rst) begin output_ip_header_checksum_reg <= 0; output_ip_source_ip_reg <= 0; output_ip_dest_ip_reg <= 0; - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; save_eth_payload_tdata_reg <= 0; save_eth_payload_tkeep_reg <= 0; save_eth_payload_tlast_reg <= 0; diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index 88140172d..059227f3f 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -380,10 +380,6 @@ always @(posedge clk or posedge rst) begin output_ip_header_checksum_reg <= 0; output_ip_source_ip_reg <= 0; output_ip_dest_ip_reg <= 0; - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; busy_reg <= 0; error_payload_early_termination_reg <= 0; end else begin diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index 1b4e11a02..0dc083dab 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -436,10 +436,6 @@ always @(posedge clk or posedge rst) begin output_ip_header_checksum_reg <= 0; output_ip_source_ip_reg <= 0; output_ip_dest_ip_reg <= 0; - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; busy_reg <= 0; error_payload_early_termination_reg <= 0; end else begin From 7532915bb79c9f81baffc03c2bc34761eee9d7a5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 28 Feb 2015 01:11:03 -0800 Subject: [PATCH 157/617] Add GMII PHY interface module --- rtl/gmii_phy_if.v | 187 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 rtl/gmii_phy_if.v diff --git a/rtl/gmii_phy_if.v b/rtl/gmii_phy_if.v new file mode 100644 index 000000000..21bd9c655 --- /dev/null +++ b/rtl/gmii_phy_if.v @@ -0,0 +1,187 @@ +/* + +Copyright (c) 2015 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 + +/* + * GMII PHY interface + */ +module gmii_phy_if # +( + parameter TARGET_XILINX = 0 +) +( + input wire clk, + input wire rst, + + /* + * GMII interface to MAC + */ + output wire mac_gmii_rx_clk, + output wire mac_gmii_rx_rst, + output wire [7:0] mac_gmii_rxd, + output wire mac_gmii_rx_dv, + output wire mac_gmii_rx_er, + output wire mac_gmii_tx_clk, + output wire mac_gmii_tx_rst, + input wire [7:0] mac_gmii_txd, + input wire mac_gmii_tx_en, + input wire mac_gmii_tx_er, + + /* + * GMII interface to PHY + */ + input wire phy_gmii_rx_clk, + input wire [7:0] phy_gmii_rxd, + input wire phy_gmii_rx_dv, + input wire phy_gmii_rx_er, + output wire phy_gmii_tx_clk, + output wire [7:0] phy_gmii_txd, + output wire phy_gmii_tx_en, + output wire phy_gmii_tx_er +); + +wire phy_gmii_rx_clk_int; +wire phy_gmii_rx_clk_io; +wire phy_gmii_tx_clk_int; + +generate + +if (TARGET_XILINX) begin + + // use Xilinx clocking primitives + + // pass through RX clock to input buffers + BUFIO2 + phy_gmii_rx_clk_bufio ( + .I(phy_gmii_rx_clk), + .DIVCLK(phy_gmii_rx_clk_int), + .IOCLK(phy_gmii_rx_clk_io), + .SERDESSTROBE() + ); + + // pass through RX clock to MAC + BUFG + phy_gmii_rx_clk_bufg ( + .I(phy_gmii_rx_clk_int), + .O(mac_gmii_rx_clk) + ); + + // pass through clock to MAC + assign mac_gmii_tx_clk = clk; + + // pass through clock to PHY + assign phy_gmii_tx_clk_int = clk; + + // invert to center clock edge in valid window + ODDR2 + phy_gmii_tx_clk_oddr ( + .Q(phy_gmii_tx_clk), + .C0(phy_gmii_tx_clk_int), + .C1(~phy_gmii_tx_clk_int), + .CE(1), + .D0(0), + .D1(1), + .R(0), + .S(0) + ); + +end else begin + + // pass through RX clock to input buffers + assign phy_gmii_rx_clk_io = phy_gmii_rx_clk; + + // pass through RX clock to MAC + assign phy_gmii_rx_clk_int = phy_gmii_rx_clk; + assign mac_gmii_rx_clk = phy_gmii_rx_clk_int; + + // pass through clock to MAC + assign mac_gmii_tx_clk = clk; + + // pass through clock to PHY + assign phy_gmii_tx_clk_int = clk; + + // invert to center clock edge in valid window + assign phy_gmii_tx_clk = ~phy_gmii_tx_clk_int; + +end + +endgenerate + +// reset sync +reg [3:0] tx_rst_reg = 4'hf; +assign mac_gmii_tx_rst = tx_rst_reg[0]; + +always @(posedge mac_gmii_tx_clk or posedge rst) begin + if (rst) begin + tx_rst_reg <= 4'hf; + end else begin + tx_rst_reg <= {1'b0, tx_rst_reg[3:1]}; + end +end + +reg [3:0] rx_rst_reg = 4'hf; +assign mac_gmii_rx_rst = rx_rst_reg[0]; + +always @(posedge mac_gmii_rx_clk or posedge rst) begin + if (rst) begin + rx_rst_reg <= 4'hf; + end else begin + rx_rst_reg <= {1'b0, rx_rst_reg[3:1]}; + end +end + +// register RX data from PHY to MAC +reg [7:0] gmii_rxd_reg = 0; +reg gmii_rx_dv_reg = 0; +reg gmii_rx_er_reg = 0; + +always @(posedge phy_gmii_rx_clk_io) begin + gmii_rxd_reg <= phy_gmii_rxd; + gmii_rx_dv_reg <= phy_gmii_rx_dv; + gmii_rx_er_reg <= phy_gmii_rx_er; +end + +assign mac_gmii_rxd = gmii_rxd_reg; +assign mac_gmii_rx_dv = gmii_rx_dv_reg; +assign mac_gmii_rx_er = gmii_rx_er_reg; + +// register TX data from MAC to PHY +reg [7:0] gmii_txd_reg = 0; +reg gmii_tx_en_reg = 0; +reg gmii_tx_er_reg = 0; + +always @(posedge phy_gmii_tx_clk_int) begin + gmii_txd_reg <= mac_gmii_txd; + gmii_tx_en_reg <= mac_gmii_tx_en; + gmii_tx_er_reg <= mac_gmii_tx_er; +end + +assign phy_gmii_txd = gmii_txd_reg; +assign phy_gmii_tx_en = gmii_tx_en_reg; +assign phy_gmii_tx_er = gmii_tx_er_reg; + +endmodule From d57c857d88b71a1e9b174e6050686479bf904958 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 28 Feb 2015 18:24:20 -0800 Subject: [PATCH 158/617] Put PHY interface registers into IOBs for timing --- rtl/gmii_phy_if.v | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtl/gmii_phy_if.v b/rtl/gmii_phy_if.v index 21bd9c655..5f9d29eb1 100644 --- a/rtl/gmii_phy_if.v +++ b/rtl/gmii_phy_if.v @@ -155,8 +155,11 @@ always @(posedge mac_gmii_rx_clk or posedge rst) begin end // register RX data from PHY to MAC +(* IOB = "TRUE" *) reg [7:0] gmii_rxd_reg = 0; +(* IOB = "TRUE" *) reg gmii_rx_dv_reg = 0; +(* IOB = "TRUE" *) reg gmii_rx_er_reg = 0; always @(posedge phy_gmii_rx_clk_io) begin @@ -170,8 +173,11 @@ assign mac_gmii_rx_dv = gmii_rx_dv_reg; assign mac_gmii_rx_er = gmii_rx_er_reg; // register TX data from MAC to PHY +(* IOB = "TRUE" *) reg [7:0] gmii_txd_reg = 0; +(* IOB = "TRUE" *) reg gmii_tx_en_reg = 0; +(* IOB = "TRUE" *) reg gmii_tx_er_reg = 0; always @(posedge phy_gmii_tx_clk_int) begin From 14e71d568dc75b99c1dad36913d1a4fd5e37baa2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 28 Feb 2015 19:14:22 -0800 Subject: [PATCH 159/617] Improve classifier logic by registering payload select signals --- rtl/ip_complete.v | 35 ++++++++++++++++++++++++++++++----- rtl/ip_complete_64.v | 35 ++++++++++++++++++++++++++++++----- rtl/udp_complete.v | 29 +++++++++++++++++++++++++---- rtl/udp_complete_64.v | 29 +++++++++++++++++++++++++---- 4 files changed, 110 insertions(+), 18 deletions(-) diff --git a/rtl/ip_complete.v b/rtl/ip_complete.v index d0f366eb2..ac9d440b5 100644 --- a/rtl/ip_complete.v +++ b/rtl/ip_complete.v @@ -197,12 +197,37 @@ wire input_select_ip = (input_eth_type == 16'h0800); wire input_select_arp = (input_eth_type == 16'h0806); wire input_select_none = ~(input_select_ip | input_select_arp); +reg input_select_ip_reg = 0; +reg input_select_arp_reg = 0; +reg input_select_none_reg = 0; + +always @(posedge clk) begin + if (rst) begin + input_select_ip_reg <= 0; + input_select_arp_reg <= 0; + input_select_none_reg <= 0; + end else begin + if (input_eth_payload_tvalid) begin + if ((~input_select_ip_reg & ~input_select_arp_reg & ~input_select_none_reg) | + (input_eth_payload_tvalid & input_eth_payload_tready & input_eth_payload_tlast)) begin + input_select_ip_reg <= input_select_ip; + input_select_arp_reg <= input_select_arp; + input_select_none_reg <= input_select_none; + end + end else begin + input_select_ip_reg <= 0; + input_select_arp_reg <= 0; + input_select_none_reg <= 0; + end + end +end + assign ip_rx_eth_hdr_valid = input_select_ip & input_eth_hdr_valid; assign ip_rx_eth_dest_mac = input_eth_dest_mac; assign ip_rx_eth_src_mac = input_eth_src_mac; assign ip_rx_eth_type = 16'h0800; assign ip_rx_eth_payload_tdata = input_eth_payload_tdata; -assign ip_rx_eth_payload_tvalid = input_select_ip & input_eth_payload_tvalid; +assign ip_rx_eth_payload_tvalid = input_select_ip_reg & input_eth_payload_tvalid; assign ip_rx_eth_payload_tlast = input_eth_payload_tlast; assign ip_rx_eth_payload_tuser = input_eth_payload_tuser; @@ -211,15 +236,15 @@ assign arp_rx_eth_dest_mac = input_eth_dest_mac; assign arp_rx_eth_src_mac = input_eth_src_mac; assign arp_rx_eth_type = 16'h0806; assign arp_rx_eth_payload_tdata = input_eth_payload_tdata; -assign arp_rx_eth_payload_tvalid = input_select_arp & input_eth_payload_tvalid; +assign arp_rx_eth_payload_tvalid = input_select_arp_reg & input_eth_payload_tvalid; assign arp_rx_eth_payload_tlast = input_eth_payload_tlast; assign arp_rx_eth_payload_tuser = input_eth_payload_tuser; assign input_eth_hdr_ready = arp_rx_eth_hdr_ready & ip_rx_eth_hdr_ready; -assign input_eth_payload_tready = (input_select_ip & ip_rx_eth_payload_tready) | - (input_select_arp & arp_rx_eth_payload_tready) | - input_select_none; +assign input_eth_payload_tready = (input_select_ip_reg & ip_rx_eth_payload_tready) | + (input_select_arp_reg & arp_rx_eth_payload_tready) | + input_select_none_reg; /* * Output arbiter diff --git a/rtl/ip_complete_64.v b/rtl/ip_complete_64.v index 5147d143e..4428d6c92 100644 --- a/rtl/ip_complete_64.v +++ b/rtl/ip_complete_64.v @@ -205,13 +205,38 @@ wire input_select_ip = (input_eth_type == 16'h0800); wire input_select_arp = (input_eth_type == 16'h0806); wire input_select_none = ~(input_select_ip | input_select_arp); +reg input_select_ip_reg = 0; +reg input_select_arp_reg = 0; +reg input_select_none_reg = 0; + +always @(posedge clk) begin + if (rst) begin + input_select_ip_reg <= 0; + input_select_arp_reg <= 0; + input_select_none_reg <= 0; + end else begin + if (input_eth_payload_tvalid) begin + if ((~input_select_ip_reg & ~input_select_arp_reg & ~input_select_none_reg) | + (input_eth_payload_tvalid & input_eth_payload_tready & input_eth_payload_tlast)) begin + input_select_ip_reg <= input_select_ip; + input_select_arp_reg <= input_select_arp; + input_select_none_reg <= input_select_none; + end + end else begin + input_select_ip_reg <= 0; + input_select_arp_reg <= 0; + input_select_none_reg <= 0; + end + end +end + assign ip_rx_eth_hdr_valid = input_select_ip & input_eth_hdr_valid; assign ip_rx_eth_dest_mac = input_eth_dest_mac; assign ip_rx_eth_src_mac = input_eth_src_mac; assign ip_rx_eth_type = 16'h0800; assign ip_rx_eth_payload_tdata = input_eth_payload_tdata; assign ip_rx_eth_payload_tkeep = input_eth_payload_tkeep; -assign ip_rx_eth_payload_tvalid = input_select_ip & input_eth_payload_tvalid; +assign ip_rx_eth_payload_tvalid = input_select_ip_reg & input_eth_payload_tvalid; assign ip_rx_eth_payload_tlast = input_eth_payload_tlast; assign ip_rx_eth_payload_tuser = input_eth_payload_tuser; @@ -221,15 +246,15 @@ assign arp_rx_eth_src_mac = input_eth_src_mac; assign arp_rx_eth_type = 16'h0806; assign arp_rx_eth_payload_tdata = input_eth_payload_tdata; assign arp_rx_eth_payload_tkeep = input_eth_payload_tkeep; -assign arp_rx_eth_payload_tvalid = input_select_arp & input_eth_payload_tvalid; +assign arp_rx_eth_payload_tvalid = input_select_arp_reg & input_eth_payload_tvalid; assign arp_rx_eth_payload_tlast = input_eth_payload_tlast; assign arp_rx_eth_payload_tuser = input_eth_payload_tuser; assign input_eth_hdr_ready = arp_rx_eth_hdr_ready & ip_rx_eth_hdr_ready; -assign input_eth_payload_tready = (input_select_ip & ip_rx_eth_payload_tready) | - (input_select_arp & arp_rx_eth_payload_tready) | - input_select_none; +assign input_eth_payload_tready = (input_select_ip_reg & ip_rx_eth_payload_tready) | + (input_select_arp_reg & arp_rx_eth_payload_tready) | + input_select_none_reg; /* * Output arbiter diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v index d32bba109..915dcfe35 100644 --- a/rtl/udp_complete.v +++ b/rtl/udp_complete.v @@ -277,6 +277,27 @@ wire udp_tx_ip_payload_tready; wire input_select_udp = (ip_rx_ip_protocol == 8'h11); wire input_select_ip = ~input_select_udp; +reg input_select_udp_reg = 0; +reg input_select_ip_reg = 0; + +always @(posedge clk) begin + if (rst) begin + input_select_udp_reg <= 0; + input_select_ip_reg <= 0; + end else begin + if (ip_rx_ip_payload_tvalid) begin + if ((~input_select_udp_reg & ~input_select_ip_reg) | + (ip_rx_ip_payload_tvalid & ip_rx_ip_payload_tready & ip_rx_ip_payload_tlast)) begin + input_select_udp_reg <= input_select_udp; + input_select_ip_reg <= input_select_ip; + end + end else begin + input_select_udp_reg <= 0; + input_select_ip_reg <= 0; + end + end +end + // IP frame to UDP module assign udp_rx_ip_hdr_valid = input_select_udp & ip_rx_ip_hdr_valid; assign udp_rx_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; @@ -296,7 +317,7 @@ assign udp_rx_ip_header_checksum = ip_rx_ip_header_checksum; assign udp_rx_ip_source_ip = ip_rx_ip_source_ip; assign udp_rx_ip_dest_ip = ip_rx_ip_dest_ip; assign udp_rx_ip_payload_tdata = ip_rx_ip_payload_tdata; -assign udp_rx_ip_payload_tvalid = input_select_udp & ip_rx_ip_payload_tvalid; +assign udp_rx_ip_payload_tvalid = input_select_udp_reg & ip_rx_ip_payload_tvalid; assign udp_rx_ip_payload_tlast = ip_rx_ip_payload_tlast; assign udp_rx_ip_payload_tuser = ip_rx_ip_payload_tuser; @@ -319,14 +340,14 @@ assign output_ip_header_checksum = ip_rx_ip_header_checksum; assign output_ip_source_ip = ip_rx_ip_source_ip; assign output_ip_dest_ip = ip_rx_ip_dest_ip; assign output_ip_payload_tdata = ip_rx_ip_payload_tdata; -assign output_ip_payload_tvalid = input_select_ip & ip_rx_ip_payload_tvalid; +assign output_ip_payload_tvalid = input_select_ip_reg & ip_rx_ip_payload_tvalid; assign output_ip_payload_tlast = ip_rx_ip_payload_tlast; assign output_ip_payload_tuser = ip_rx_ip_payload_tuser; assign ip_rx_ip_hdr_ready = udp_rx_ip_hdr_ready & output_ip_hdr_ready; -assign ip_rx_ip_payload_tready = (input_select_udp & udp_rx_ip_payload_tready) | - (input_select_ip & output_ip_payload_tready); +assign ip_rx_ip_payload_tready = (input_select_udp_reg & udp_rx_ip_payload_tready) | + (input_select_ip_reg & output_ip_payload_tready); /* * Output arbiter diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v index 8eeb2525f..4389e11ca 100644 --- a/rtl/udp_complete_64.v +++ b/rtl/udp_complete_64.v @@ -287,6 +287,27 @@ wire udp_tx_ip_payload_tready; wire input_select_udp = (ip_rx_ip_protocol == 8'h11); wire input_select_ip = ~input_select_udp; +reg input_select_udp_reg = 0; +reg input_select_ip_reg = 0; + +always @(posedge clk) begin + if (rst) begin + input_select_udp_reg <= 0; + input_select_ip_reg <= 0; + end else begin + if (ip_rx_ip_payload_tvalid) begin + if ((~input_select_udp_reg & ~input_select_ip_reg) | + (ip_rx_ip_payload_tvalid & ip_rx_ip_payload_tready & ip_rx_ip_payload_tlast)) begin + input_select_udp_reg <= input_select_udp; + input_select_ip_reg <= input_select_ip; + end + end else begin + input_select_udp_reg <= 0; + input_select_ip_reg <= 0; + end + end +end + // IP frame to UDP module assign udp_rx_ip_hdr_valid = input_select_udp & ip_rx_ip_hdr_valid; assign udp_rx_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; @@ -307,7 +328,7 @@ assign udp_rx_ip_source_ip = ip_rx_ip_source_ip; assign udp_rx_ip_dest_ip = ip_rx_ip_dest_ip; assign udp_rx_ip_payload_tdata = ip_rx_ip_payload_tdata; assign udp_rx_ip_payload_tkeep = ip_rx_ip_payload_tkeep; -assign udp_rx_ip_payload_tvalid = input_select_udp & ip_rx_ip_payload_tvalid; +assign udp_rx_ip_payload_tvalid = input_select_udp_reg & ip_rx_ip_payload_tvalid; assign udp_rx_ip_payload_tlast = ip_rx_ip_payload_tlast; assign udp_rx_ip_payload_tuser = ip_rx_ip_payload_tuser; @@ -331,14 +352,14 @@ assign output_ip_source_ip = ip_rx_ip_source_ip; assign output_ip_dest_ip = ip_rx_ip_dest_ip; assign output_ip_payload_tdata = ip_rx_ip_payload_tdata; assign output_ip_payload_tkeep = ip_rx_ip_payload_tkeep; -assign output_ip_payload_tvalid = input_select_ip & ip_rx_ip_payload_tvalid; +assign output_ip_payload_tvalid = input_select_ip_reg & ip_rx_ip_payload_tvalid; assign output_ip_payload_tlast = ip_rx_ip_payload_tlast; assign output_ip_payload_tuser = ip_rx_ip_payload_tuser; assign ip_rx_ip_hdr_ready = udp_rx_ip_hdr_ready & output_ip_hdr_ready; -assign ip_rx_ip_payload_tready = (input_select_udp & udp_rx_ip_payload_tready) | - (input_select_ip & output_ip_payload_tready); +assign ip_rx_ip_payload_tready = (input_select_udp_reg & udp_rx_ip_payload_tready) | + (input_select_ip_reg & output_ip_payload_tready); /* * Output arbiter From 6e2eda256dd1f85bcd4f7c0cff099bdaff881786 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 28 Feb 2015 19:32:08 -0800 Subject: [PATCH 160/617] Improve frame drop logic in frame FIFOs, add DROP_WHEN_FULL option to disable input tready signal --- rtl/axis_async_frame_fifo.v | 13 +++++++++---- rtl/axis_async_frame_fifo_64.v | 13 +++++++++---- rtl/axis_frame_fifo.v | 13 +++++++++---- rtl/axis_frame_fifo_64.v | 13 +++++++++---- tb/test_axis_async_frame_fifo.v | 3 ++- tb/test_axis_async_frame_fifo_64.v | 3 ++- tb/test_axis_frame_fifo.v | 3 ++- tb/test_axis_frame_fifo_64.v | 3 ++- 8 files changed, 44 insertions(+), 20 deletions(-) diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index be2374241..1c8aed29d 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -32,7 +32,8 @@ THE SOFTWARE. module axis_async_frame_fifo # ( parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter DROP_WHEN_FULL = 0 ) ( /* @@ -70,6 +71,8 @@ reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; +reg drop_frame = 1'b0; + reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) @@ -92,12 +95,12 @@ wire empty = rd_ptr_gray == wr_ptr_gray_sync3; wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); -wire write = input_axis_tvalid & ~full; +wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL); wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; assign {output_axis_tlast, output_axis_tdata} = data_out_reg; -assign input_axis_tready = ~full; +assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; // write @@ -105,10 +108,12 @@ always @(posedge input_clk or posedge input_rst) begin if (input_rst) begin wr_ptr <= 0; end else if (write) begin - if (full_cur) begin + if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end + drop_frame <= 1; if (input_axis_tlast) begin wr_ptr_cur <= wr_ptr; + drop_frame <= 0; end end else begin mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 2a200f691..4d3fd6f79 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -33,7 +33,8 @@ module axis_async_frame_fifo_64 # ( parameter ADDR_WIDTH = 12, parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter DROP_WHEN_FULL = 0 ) ( /* @@ -73,6 +74,8 @@ reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; +reg drop_frame = 1'b0; + reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) @@ -95,12 +98,12 @@ wire empty = rd_ptr_gray == wr_ptr_gray_sync3; wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); -wire write = input_axis_tvalid & ~full; +wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL); wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; -assign input_axis_tready = ~full; +assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; // write @@ -108,10 +111,12 @@ always @(posedge input_clk or posedge input_rst) begin if (input_rst) begin wr_ptr <= 0; end else if (write) begin - if (full_cur) begin + if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end + drop_frame <= 1; if (input_axis_tlast) begin wr_ptr_cur <= wr_ptr; + drop_frame <= 0; end end else begin mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index d037adfe4..0890c8982 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -32,7 +32,8 @@ THE SOFTWARE. module axis_frame_fifo # ( parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter DROP_WHEN_FULL = 0 ) ( input wire clk, @@ -60,6 +61,8 @@ reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; +reg drop_frame = 1'b0; + reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) @@ -80,12 +83,12 @@ wire empty = wr_ptr == rd_ptr; wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); -wire write = input_axis_tvalid & ~full; +wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL); wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; assign {output_axis_tlast, output_axis_tdata} = data_out_reg; -assign input_axis_tready = ~full; +assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; // write @@ -93,10 +96,12 @@ always @(posedge clk or posedge rst) begin if (rst) begin wr_ptr <= 0; end else if (write) begin - if (full_cur) begin + if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end + drop_frame <= 1; if (input_axis_tlast) begin wr_ptr_cur <= wr_ptr; + drop_frame <= 0; end end else begin mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index f55dcf01a..e42a76932 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -33,7 +33,8 @@ module axis_frame_fifo_64 # ( parameter ADDR_WIDTH = 12, parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter DROP_WHEN_FULL = 0 ) ( input wire clk, @@ -63,6 +64,8 @@ reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; +reg drop_frame = 1'b0; + reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) @@ -83,12 +86,12 @@ wire empty = wr_ptr == rd_ptr; wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); -wire write = input_axis_tvalid & ~full; +wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL); wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; -assign input_axis_tready = ~full; +assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; // write @@ -96,10 +99,12 @@ always @(posedge clk or posedge rst) begin if (rst) begin wr_ptr <= 0; end else if (write) begin - if (full_cur) begin + if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end + drop_frame <= 1; if (input_axis_tlast) begin wr_ptr_cur <= wr_ptr; + drop_frame <= 0; end end else begin mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index 916b87354..c41570cb0 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -71,7 +71,8 @@ end axis_async_frame_fifo #( .ADDR_WIDTH(9), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .DROP_WHEN_FULL(0) ) UUT ( // AXI input diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index 62e3ad7aa..f9249e7dc 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -75,7 +75,8 @@ end axis_async_frame_fifo_64 #( .ADDR_WIDTH(6), - .DATA_WIDTH(64) + .DATA_WIDTH(64), + .DROP_WHEN_FULL(0) ) UUT ( // AXI input diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v index 69ae48514..d0a13fb91 100644 --- a/tb/test_axis_frame_fifo.v +++ b/tb/test_axis_frame_fifo.v @@ -67,7 +67,8 @@ end axis_frame_fifo #( .ADDR_WIDTH(9), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .DROP_WHEN_FULL(0) ) UUT ( .clk(clk), diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v index c7048e3fd..30d872985 100644 --- a/tb/test_axis_frame_fifo_64.v +++ b/tb/test_axis_frame_fifo_64.v @@ -71,7 +71,8 @@ end axis_frame_fifo_64 #( .ADDR_WIDTH(6), - .DATA_WIDTH(64) + .DATA_WIDTH(64), + .DROP_WHEN_FULL(0) ) UUT ( .clk(clk), From d489468776dbbdce60b14232b90572b210a15b59 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 28 Feb 2015 20:05:05 -0800 Subject: [PATCH 161/617] Add example design for Digilent Atlys board --- example/ATLYS/fpga/Makefile | 25 + example/ATLYS/fpga/clock.ucf | 6 + example/ATLYS/fpga/common/xilinx.mk | 191 ++++++ example/ATLYS/fpga/coregen/Makefile | 33 + example/ATLYS/fpga/coregen/coregen.cgp | 20 + example/ATLYS/fpga/coregen/dcm_i100_o125.xco | 269 ++++++++ example/ATLYS/fpga/fpga.ucf | 193 ++++++ example/ATLYS/fpga/fpga/Makefile | 61 ++ example/ATLYS/fpga/lib/eth | 1 + example/ATLYS/fpga/rtl/debounce_switch.v | 89 +++ example/ATLYS/fpga/rtl/fpga.v | 182 ++++++ example/ATLYS/fpga/rtl/fpga_core.v | 646 +++++++++++++++++++ example/ATLYS/fpga/rtl/fpga_pads.v | 170 +++++ example/ATLYS/fpga/rtl/sync_reset.v | 52 ++ example/ATLYS/fpga/rtl/sync_signal.v | 58 ++ example/ATLYS/fpga/tb/arp_ep.py | 1 + example/ATLYS/fpga/tb/axis_ep.py | 1 + example/ATLYS/fpga/tb/eth_ep.py | 1 + example/ATLYS/fpga/tb/gmii_ep.py | 1 + example/ATLYS/fpga/tb/ip_ep.py | 1 + example/ATLYS/fpga/tb/test_fpga_core.py | 335 ++++++++++ example/ATLYS/fpga/tb/test_fpga_core.v | 118 ++++ example/ATLYS/fpga/tb/udp_ep.py | 1 + 23 files changed, 2455 insertions(+) create mode 100644 example/ATLYS/fpga/Makefile create mode 100644 example/ATLYS/fpga/clock.ucf create mode 100644 example/ATLYS/fpga/common/xilinx.mk create mode 100644 example/ATLYS/fpga/coregen/Makefile create mode 100644 example/ATLYS/fpga/coregen/coregen.cgp create mode 100644 example/ATLYS/fpga/coregen/dcm_i100_o125.xco create mode 100644 example/ATLYS/fpga/fpga.ucf create mode 100644 example/ATLYS/fpga/fpga/Makefile create mode 120000 example/ATLYS/fpga/lib/eth create mode 100644 example/ATLYS/fpga/rtl/debounce_switch.v create mode 100644 example/ATLYS/fpga/rtl/fpga.v create mode 100644 example/ATLYS/fpga/rtl/fpga_core.v create mode 100644 example/ATLYS/fpga/rtl/fpga_pads.v create mode 100644 example/ATLYS/fpga/rtl/sync_reset.v create mode 100644 example/ATLYS/fpga/rtl/sync_signal.v create mode 120000 example/ATLYS/fpga/tb/arp_ep.py create mode 120000 example/ATLYS/fpga/tb/axis_ep.py create mode 120000 example/ATLYS/fpga/tb/eth_ep.py create mode 120000 example/ATLYS/fpga/tb/gmii_ep.py create mode 120000 example/ATLYS/fpga/tb/ip_ep.py create mode 100755 example/ATLYS/fpga/tb/test_fpga_core.py create mode 100644 example/ATLYS/fpga/tb/test_fpga_core.v create mode 120000 example/ATLYS/fpga/tb/udp_ep.py diff --git a/example/ATLYS/fpga/Makefile b/example/ATLYS/fpga/Makefile new file mode 100644 index 000000000..9f8bd4048 --- /dev/null +++ b/example/ATLYS/fpga/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = coregen fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/ATLYS/fpga/clock.ucf b/example/ATLYS/fpga/clock.ucf new file mode 100644 index 000000000..d954d3a0d --- /dev/null +++ b/example/ATLYS/fpga/clock.ucf @@ -0,0 +1,6 @@ +# UCF file for clock module domain crossing constraints + +NET "clk_int" TNM = "ffs_clk_int"; +NET "core_inst/gmii_rx_clk" TNM = "ffs_gmii_rx_clk"; +TIMESPEC "TS_clk_int_to_gmii_rx_clk" = FROM "ffs_clk_int" TO "ffs_gmii_rx_clk" 10 ns; +TIMESPEC "TS_gmii_rx_clk_to_clk_int" = FROM "ffs_gmii_rx_clk" TO "ffs_clk_int" 10 ns; diff --git a/example/ATLYS/fpga/common/xilinx.mk b/example/ATLYS/fpga/common/xilinx.mk new file mode 100644 index 000000000..f10a45f8e --- /dev/null +++ b/example/ATLYS/fpga/common/xilinx.mk @@ -0,0 +1,191 @@ +############################################################################# +# Author: Lane Brooks/Keith Fife +# Date: 04/28/2006 +# License: GPL +# Desc: This is a Makefile intended to take a verilog rtl design +# through the Xilinx ISE tools to generate configuration files for +# Xilinx FPGAs. This file is generic and just a template. As such +# all design specific options such as synthesis files, fpga part type, +# prom part type, etc should be set in the top Makefile prior to +# including this file. Alternatively, all parameters can be passed +# in from the command line as well. +# +############################################################################## +# +# Parameter: +# SYN_FILES - Space seperated list of files to be synthesized +# PART - FPGA part (see Xilinx documentation) +# PROM - PROM part +# NGC_PATHS - Space seperated list of any dirs with pre-compiled ngc files. +# UCF_FILES - Space seperated list of user constraint files. Defaults to xilinx/$(FPGA_TOP).ucf +# +# +# Example Calling Makefile: +# +# SYN_FILES = fpga.v fifo.v clks.v +# PART = xc3s1000 +# FPGA_TOP = fpga +# PROM = xc18v04 +# NGC_PATH = ipLib1 ipLib2 +# FPGA_ARCH = spartan6 +# SPI_PROM_SIZE = (in bytes) +# include xilinx.mk +############################################################################# +# +# Command Line Example: +# make -f xilinx.mk PART=xc3s1000-4fg320 SYN_FILES="fpga.v test.v" FPGA_TOP=fpga +# +############################################################################## +# +# Required Setup: +# +# %.ucf - user constraint file. Needed by ngdbuild +# +# Optional Files: +# %.xcf - user constraint file. Needed by xst. +# %.ut - File for pin states needed by bitgen + + +.PHONY: clean bit prom fpga spi + + +# Mark the intermediate files as PRECIOUS to prevent make from +# deleting them (see make manual section 10.4). +.PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.bit %_timesim.v + +# include the local Makefile for project for any project specific targets +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +INC_PATHS_REL = $(patsubst %, ../%, $(INC_PATHS)) +NGC_PATHS_REL = $(patsubst %, ../%, $(NGC_PATHS)) + +ifdef UCF_FILES + UCF_FILES_REL = $(patsubst %, ../%, $(UCF_FILES)) +else + UCF_FILES_REL = $(FPGA_TOP).ucf +endif + + + +fpga: $(FPGA_TOP).bit + +mcs: $(FPGA_TOP).mcs + +prom: $(FPGA_TOP).spi + +spi: $(FPGA_TOP).spi + +fpgasim: $(FPGA_TOP)_sim.v + + +########################### XST TEMPLATES ############################ +# There are 2 files that XST uses for synthesis that we auto generate. +# The first is a project file which is just a list of all the verilog +# files. The second is the src file which passes XST all the options. +# See XST user manual for XST options. +%.ngc: $(SYN_FILES_REL) $(INC_FILES_REL) + rm -rf xst $*.prj $*.xst defines.v + touch defines.v + mkdir -p xst/tmp + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo verilog work defines.v > $*.prj + for x in $(SYN_FILES_REL); do echo verilog work $$x >> $*.prj; done + @echo "set -tmpdir ./xst/tmp" >> $*.xst + @echo "set -xsthdpdir ./xst" >> $*.xst + @echo "run" >> $*.xst + @echo "-ifn $*.prj" >> $*.xst + @echo "-ifmt mixed" >> $*.xst + @echo "-top $*" >> $*.xst + @echo "-ofn $*" >> $*.xst + @echo "-ofmt NGC" >> $*.xst + @echo "-opt_mode Speed" >> $*.xst + @echo "-opt_level 1" >> $*.xst + # @echo "-verilog2001 YES" >> $*.xst + @echo "-keep_hierarchy NO" >> $*.xst + @echo "-p $(FPGA_PART)" >> $*.xst + xst -ifn $*.xst -ofn $*.log + + +########################### ISE TRANSLATE ############################ +# ngdbuild will automatically use a ucf called %.ucf if one is found. +# We setup the dependancy such that %.ucf file is required. If any +# pre-compiled ncd files are needed, set the NGC_PATH variable as a space +# seperated list of directories that include the pre-compiled ngc files. +%.ngd: %.ngc $(UCF_FILES_REL) + ngdbuild -dd ngdbuild $(patsubst %,-sd %, $(NGC_PATHS_REL)) $(patsubst %,-uc %, $(UCF_FILES_REL)) -p $(FPGA_PART) $< $@ + + +########################### ISE MAP ################################### +ifeq ($(FPGA_ARCH),spartan6) + MAP_OPTS= -register_duplication on -timing -xe n +else + MAP_OPTS= -cm speed -register_duplication on -timing -xe n -pr b +endif + +%_map.ncd: %.ngd + map -p $(FPGA_PART) $(MAP_OPTS) -w -o $@ $< $*.pcf + +# map -p $(FPGA_PART) -cm area -pr b -k 4 -c 100 -o $@ $< $*.pcf + + +########################### ISE PnR ################################### +%.ncd: %_map.ncd + par -w -ol high $< $@ $*.pcf + +# par -w -ol std -t 1 $< $@ $*.pcf + + +##################### ISE Static Timing Analysis ##################### +%.twr: %.ncd + -trce -e 3 -l 3 -u -xml $* $< -o $@ $*.pcf + +%_sim.v: %.ncd + netgen -s 4 -pcf $*.pcf -sdf_anno true -ism -sdf_path netgen -w -dir . -ofmt verilog -sim $< $@ + +# netgen -ise "/home/lane/Second/xilinx/Second/Second" -intstyle ise -s 4 -pcf Second.pcf -sdf_anno true -sdf_path netgen/par -w -dir netgen/par -ofmt verilog -sim Second.ncd Second_timesim.v + + +########################### ISE Bitgen ############################# +%.bit: %.twr + bitgen $(BITGEN_OPTIONS) -w $*.ncd $*.bit + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +########################### ISE Promgen ############################# +%.mcs: %.bit + promgen -spi -w -p mcs -s $(SPI_PROM_SIZE) -o $@ -u 0 $< + # promgen -w -p mcs -c FF -o $@ -u 0 $< -x $(PROM) + mkdir -p rev + EXT=mcs; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +%.spi: %.mcs + objcopy -I ihex -O binary $< $@ + EXT=spi; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + + +tmpclean: + -rm -rf xst ngdbuild *_map.* *.ncd *.ngc *.log *.xst *.prj *.lso *~ *.pcf *.bld *.ngd *.xpi *_pad.* *.unroutes *.twx *.par *.twr *.pad *.drc *.bgn *.prm *.sig netgen *.v *.nlf *.xml + +clean: tmpclean + -rm -rf *.bit *.mcs + +# clean everything +distclean: clean + -rm -rf rev + diff --git a/example/ATLYS/fpga/coregen/Makefile b/example/ATLYS/fpga/coregen/Makefile new file mode 100644 index 000000000..714069069 --- /dev/null +++ b/example/ATLYS/fpga/coregen/Makefile @@ -0,0 +1,33 @@ +# Tools +COREGEN:=coregen +XAW2VERILOG:=xaw2verilog + +# Source +XCO:=dcm_i100_o125.xco +XAW:= + +# Targets +TARGETS += $(XCO:.xco=) +TARGETS += $(XAW:.xaw=) + +# Rules +.PHONY: all +all: $(TARGETS) + +.PHONY: clean +clean: + -rm -rf $(TARGETS) + +%: %.xco + $(eval $@_TMP := $(shell mktemp -d)) + cp -a coregen.cgp $($@_TMP) + cp -a $< $($@_TMP) + cd $($@_TMP) && $(COREGEN) -p coregen.cgp -b $(notdir $<) + mv $($@_TMP) $@ + +%: %.xaw + $(eval $@_TMP := $(shell mktemp -d)) + cp -a coregen.cgp $($@_TMP) + cp -a $< $($@_TMP) + cd $($@_TMP) && $(XAW2VERILOG) -st $(notdir $<) $(notdir $*) + mv $($@_TMP) $@ diff --git a/example/ATLYS/fpga/coregen/coregen.cgp b/example/ATLYS/fpga/coregen/coregen.cgp new file mode 100644 index 000000000..773be0a87 --- /dev/null +++ b/example/ATLYS/fpga/coregen/coregen.cgp @@ -0,0 +1,20 @@ +# Date: Sat Jan 07 00:34:24 2012 +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6slx45 +SET devicefamily = spartan6 +SET flowvendor = Foundation_ISE +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = csg324 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +SET workingdirectory = .\tmp\ +# CRC: 90246c5 diff --git a/example/ATLYS/fpga/coregen/dcm_i100_o125.xco b/example/ATLYS/fpga/coregen/dcm_i100_o125.xco new file mode 100644 index 000000000..18ce93185 --- /dev/null +++ b/example/ATLYS/fpga/coregen/dcm_i100_o125.xco @@ -0,0 +1,269 @@ +############################################################## +# +# Xilinx Core Generator version 14.7 +# Date: Sun Mar 1 03:45:12 2015 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:clk_wiz:3.6 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6slx45 +SET devicefamily = spartan6 +SET flowvendor = Foundation_ISE +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = csg324 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Clocking_Wizard xilinx.com:ip:clk_wiz:3.6 +# END Select +# BEGIN Parameters +CSET calc_done=DONE +CSET clk_in_sel_port=CLK_IN_SEL +CSET clk_out1_port=CLK_OUT1 +CSET clk_out1_use_fine_ps_gui=false +CSET clk_out2_port=CLK_OUT2 +CSET clk_out2_use_fine_ps_gui=false +CSET clk_out3_port=CLK_OUT3 +CSET clk_out3_use_fine_ps_gui=false +CSET clk_out4_port=CLK_OUT4 +CSET clk_out4_use_fine_ps_gui=false +CSET clk_out5_port=CLK_OUT5 +CSET clk_out5_use_fine_ps_gui=false +CSET clk_out6_port=CLK_OUT6 +CSET clk_out6_use_fine_ps_gui=false +CSET clk_out7_port=CLK_OUT7 +CSET clk_out7_use_fine_ps_gui=false +CSET clk_valid_port=CLK_VALID +CSET clkfb_in_n_port=CLKFB_IN_N +CSET clkfb_in_p_port=CLKFB_IN_P +CSET clkfb_in_port=CLKFB_IN +CSET clkfb_in_signaling=SINGLE +CSET clkfb_out_n_port=CLKFB_OUT_N +CSET clkfb_out_p_port=CLKFB_OUT_P +CSET clkfb_out_port=CLKFB_OUT +CSET clkfb_stopped_port=CLKFB_STOPPED +CSET clkin1_jitter_ps=100.0 +CSET clkin1_ui_jitter=0.010 +CSET clkin2_jitter_ps=100.0 +CSET clkin2_ui_jitter=0.010 +CSET clkout1_drives=BUFG +CSET clkout1_requested_duty_cycle=50.000 +CSET clkout1_requested_out_freq=125.000 +CSET clkout1_requested_phase=0.000 +CSET clkout2_drives=BUFG +CSET clkout2_requested_duty_cycle=50.000 +CSET clkout2_requested_out_freq=100.000 +CSET clkout2_requested_phase=0.000 +CSET clkout2_used=false +CSET clkout3_drives=BUFG +CSET clkout3_requested_duty_cycle=50.000 +CSET clkout3_requested_out_freq=100.000 +CSET clkout3_requested_phase=0.000 +CSET clkout3_used=false +CSET clkout4_drives=BUFG +CSET clkout4_requested_duty_cycle=50.000 +CSET clkout4_requested_out_freq=100.000 +CSET clkout4_requested_phase=0.000 +CSET clkout4_used=false +CSET clkout5_drives=BUFG +CSET clkout5_requested_duty_cycle=50.000 +CSET clkout5_requested_out_freq=100.000 +CSET clkout5_requested_phase=0.000 +CSET clkout5_used=false +CSET clkout6_drives=BUFG +CSET clkout6_requested_duty_cycle=50.000 +CSET clkout6_requested_out_freq=100.000 +CSET clkout6_requested_phase=0.000 +CSET clkout6_used=false +CSET clkout7_drives=BUFG +CSET clkout7_requested_duty_cycle=50.000 +CSET clkout7_requested_out_freq=100.000 +CSET clkout7_requested_phase=0.000 +CSET clkout7_used=false +CSET clock_mgr_type=AUTO +CSET component_name=dcm_i100_o125 +CSET daddr_port=DADDR +CSET dclk_port=DCLK +CSET dcm_clk_feedback=1X +CSET dcm_clk_out1_port=CLKFX +CSET dcm_clk_out2_port=CLK0 +CSET dcm_clk_out3_port=CLK0 +CSET dcm_clk_out4_port=CLK0 +CSET dcm_clk_out5_port=CLK0 +CSET dcm_clk_out6_port=CLK0 +CSET dcm_clkdv_divide=2.0 +CSET dcm_clkfx_divide=4 +CSET dcm_clkfx_multiply=5 +CSET dcm_clkgen_clk_out1_port=CLKFX +CSET dcm_clkgen_clk_out2_port=CLKFX +CSET dcm_clkgen_clk_out3_port=CLKFX +CSET dcm_clkgen_clkfx_divide=1 +CSET dcm_clkgen_clkfx_md_max=0.000 +CSET dcm_clkgen_clkfx_multiply=4 +CSET dcm_clkgen_clkfxdv_divide=2 +CSET dcm_clkgen_clkin_period=10.000 +CSET dcm_clkgen_notes=None +CSET dcm_clkgen_spread_spectrum=NONE +CSET dcm_clkgen_startup_wait=false +CSET dcm_clkin_divide_by_2=false +CSET dcm_clkin_period=10.000 +CSET dcm_clkout_phase_shift=NONE +CSET dcm_deskew_adjust=SYSTEM_SYNCHRONOUS +CSET dcm_notes=None +CSET dcm_phase_shift=0 +CSET dcm_pll_cascade=NONE +CSET dcm_startup_wait=false +CSET den_port=DEN +CSET din_port=DIN +CSET dout_port=DOUT +CSET drdy_port=DRDY +CSET dwe_port=DWE +CSET feedback_source=FDBK_AUTO +CSET in_freq_units=Units_MHz +CSET in_jitter_units=Units_UI +CSET input_clk_stopped_port=INPUT_CLK_STOPPED +CSET jitter_options=UI +CSET jitter_sel=No_Jitter +CSET locked_port=LOCKED +CSET mmcm_bandwidth=OPTIMIZED +CSET mmcm_clkfbout_mult_f=4.000 +CSET mmcm_clkfbout_phase=0.000 +CSET mmcm_clkfbout_use_fine_ps=false +CSET mmcm_clkin1_period=10.000 +CSET mmcm_clkin2_period=10.000 +CSET mmcm_clkout0_divide_f=4.000 +CSET mmcm_clkout0_duty_cycle=0.500 +CSET mmcm_clkout0_phase=0.000 +CSET mmcm_clkout0_use_fine_ps=false +CSET mmcm_clkout1_divide=1 +CSET mmcm_clkout1_duty_cycle=0.500 +CSET mmcm_clkout1_phase=0.000 +CSET mmcm_clkout1_use_fine_ps=false +CSET mmcm_clkout2_divide=1 +CSET mmcm_clkout2_duty_cycle=0.500 +CSET mmcm_clkout2_phase=0.000 +CSET mmcm_clkout2_use_fine_ps=false +CSET mmcm_clkout3_divide=1 +CSET mmcm_clkout3_duty_cycle=0.500 +CSET mmcm_clkout3_phase=0.000 +CSET mmcm_clkout3_use_fine_ps=false +CSET mmcm_clkout4_cascade=false +CSET mmcm_clkout4_divide=1 +CSET mmcm_clkout4_duty_cycle=0.500 +CSET mmcm_clkout4_phase=0.000 +CSET mmcm_clkout4_use_fine_ps=false +CSET mmcm_clkout5_divide=1 +CSET mmcm_clkout5_duty_cycle=0.500 +CSET mmcm_clkout5_phase=0.000 +CSET mmcm_clkout5_use_fine_ps=false +CSET mmcm_clkout6_divide=1 +CSET mmcm_clkout6_duty_cycle=0.500 +CSET mmcm_clkout6_phase=0.000 +CSET mmcm_clkout6_use_fine_ps=false +CSET mmcm_clock_hold=false +CSET mmcm_compensation=ZHOLD +CSET mmcm_divclk_divide=1 +CSET mmcm_notes=None +CSET mmcm_ref_jitter1=0.010 +CSET mmcm_ref_jitter2=0.010 +CSET mmcm_startup_wait=false +CSET num_out_clks=1 +CSET override_dcm=false +CSET override_dcm_clkgen=false +CSET override_mmcm=false +CSET override_pll=false +CSET platform=lin64 +CSET pll_bandwidth=OPTIMIZED +CSET pll_clk_feedback=CLKFBOUT +CSET pll_clkfbout_mult=4 +CSET pll_clkfbout_phase=0.000 +CSET pll_clkin_period=10.000 +CSET pll_clkout0_divide=1 +CSET pll_clkout0_duty_cycle=0.500 +CSET pll_clkout0_phase=0.000 +CSET pll_clkout1_divide=1 +CSET pll_clkout1_duty_cycle=0.500 +CSET pll_clkout1_phase=0.000 +CSET pll_clkout2_divide=1 +CSET pll_clkout2_duty_cycle=0.500 +CSET pll_clkout2_phase=0.000 +CSET pll_clkout3_divide=1 +CSET pll_clkout3_duty_cycle=0.500 +CSET pll_clkout3_phase=0.000 +CSET pll_clkout4_divide=1 +CSET pll_clkout4_duty_cycle=0.500 +CSET pll_clkout4_phase=0.000 +CSET pll_clkout5_divide=1 +CSET pll_clkout5_duty_cycle=0.500 +CSET pll_clkout5_phase=0.000 +CSET pll_compensation=SYSTEM_SYNCHRONOUS +CSET pll_divclk_divide=1 +CSET pll_notes=None +CSET pll_ref_jitter=0.010 +CSET power_down_port=POWER_DOWN +CSET prim_in_freq=100.000 +CSET prim_in_jitter=0.010 +CSET prim_source=Single_ended_clock_capable_pin +CSET primary_port=CLK_IN1 +CSET primitive=MMCM +CSET primtype_sel=PLL_BASE +CSET psclk_port=PSCLK +CSET psdone_port=PSDONE +CSET psen_port=PSEN +CSET psincdec_port=PSINCDEC +CSET relative_inclk=REL_PRIMARY +CSET reset_port=RESET +CSET secondary_in_freq=100.000 +CSET secondary_in_jitter=0.010 +CSET secondary_port=CLK_IN2 +CSET secondary_source=Single_ended_clock_capable_pin +CSET ss_mod_freq=250 +CSET ss_mode=CENTER_HIGH +CSET status_port=STATUS +CSET summary_strings=empty +CSET use_clk_valid=false +CSET use_clkfb_stopped=false +CSET use_dyn_phase_shift=false +CSET use_dyn_reconfig=false +CSET use_freeze=false +CSET use_freq_synth=true +CSET use_inclk_stopped=false +CSET use_inclk_switchover=false +CSET use_locked=true +CSET use_max_i_jitter=false +CSET use_min_o_jitter=false +CSET use_min_power=false +CSET use_phase_alignment=true +CSET use_power_down=false +CSET use_reset=true +CSET use_spread_spectrum=false +CSET use_spread_spectrum_1=false +CSET use_status=false +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2012-05-10T12:44:55Z +# END Extra information +GENERATE +# CRC: fe0bbd35 diff --git a/example/ATLYS/fpga/fpga.ucf b/example/ATLYS/fpga/fpga.ucf new file mode 100644 index 000000000..5dd47d228 --- /dev/null +++ b/example/ATLYS/fpga/fpga.ucf @@ -0,0 +1,193 @@ +# User Constraints File for the Digilent Atlys board, rev C + +CONFIG PART = xc6slx45-2csg324; + +# 100MHz Clock: I/O Bank 1 +NET "clk" LOC = "L15" | IOSTANDARD=LVCMOS33; # IO_L42P_GCLK7_M1UDM (GCLK) +NET "clk" TNM_NET = "sys_clk_pin"; +TIMESPEC "TS_sys_clk_pin" = PERIOD "sys_clk_pin" 100000 kHz; + +# Light Emitting Diodes (not used) +NET "led<0>" LOC = "U18" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (LD0) +NET "led<1>" LOC = "M14" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L53P (LD1) +NET "led<2>" LOC = "N14" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L53N_VREF (LD2) +NET "led<3>" LOC = "L14" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L61P (LD3) +NET "led<4>" LOC = "M13" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L61N (LD4) +NET "led<5>" LOC = "D4" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; # Bank = 0, IO_L1P_HSWAPEN_0 (HSWAP/LD5) +NET "led<6>" LOC = "P16" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L74N_DOUT_BUSY_1 (LD6) +NET "led<7>" LOC = "N12" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; # Bank = 2, IO_L13P_M1_2 (M1/LD7) + +# Reset Button: I/O Bank 2 (not used) +NET "reset_n" LOC = "T15" | IOSTANDARD=LVCMOS33; # IO_L1N_M0_CMPMISO_2 (M0/RESET) + +# Push Buttons: I/O Bank 3 (not used) +NET "btnu" LOC = "N4"; # IO_L1P (BTNU) +NET "btnl" LOC = "P4"; # IO_L2P (BTNL) +NET "btnd" LOC = "P3"; # IO_L2N (BTND) +NET "btnr" LOC = "F6"; # IO_L55P_M3A13 (BTNR) +NET "btnc" LOC = "F5"; # IO_L55N_M3A14 (BTNC) + +# Toggle Switches (not used) +NET "sw<0>" LOC = "A10"; # Bank = 0, IO_L37N_GCLK12 (SW0) +NET "sw<1>" LOC = "D14"; # Bank = 0, IO_L65P_SCP3 (SW1) +NET "sw<2>" LOC = "C14"; # Bank = 0, IO_L65N_SCP2 (SW2) +NET "sw<3>" LOC = "P15"; # Bank = 1, IO_L74P_AWAKE_1 (SW3) +NET "sw<4>" LOC = "P12"; # Bank = 2, IO_L13N_D10 (SW4) +NET "sw<5>" LOC = "R5"; # Bank = 2, IO_L48P_D7 (SW5) +NET "sw<6>" LOC = "T5"; # Bank = 2, IO_L48N_RDWR_B_VREF_2 (SW6) +NET "sw<7>" LOC = "E4"; # Bank = 3, IO_L54P_M3RESET (SW7) + +# Marvell M88E1111 Tri-Mode Ethernet PHY (1000BASE-T): I/O Bank 1 +# Interrupt, Reset, MDIO +#NET "phy_int_n" LOC = "L16" | IOSTANDARD=LVCMOS25; # IO_L42N_GCLK6_TRDY1_M1LDM (E-INT) +NET "phy_reset_n" LOC = "G13" | IOSTANDARD=LVCMOS25; # IO_L32N_A16_M1A9 (E-RESET) +#NET "phy_mdc" LOC = "F16" | IOSTANDARD=LVCMOS25; # IO_L1N_A24_VREF (E-MDC) +#NET "phy_mdio" LOC = "N17" | IOSTANDARD=LVCMOS25; # IO_L48P_HDC_M1DQ8 (E-MDIO) +# GMII Transmit +NET "phy_gtx_clk" LOC = "L12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L40P_GCLK11_M1A5 (E-GTXCLK) +NET "phy_txd<0>" LOC = "H16" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L37N_A6_M1A1 (E-TXD0) +NET "phy_txd<1>" LOC = "H13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L36P_A9_M1BA0 (E-TXD1) +NET "phy_txd<2>" LOC = "K14" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L39N_M1ODT (E-TXD2) +NET "phy_txd<3>" LOC = "K13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L34N_A12_M1BA2 (E-TXD3) +NET "phy_txd<4>" LOC = "J13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L39P_M1A3 (E-TXD4) +NET "phy_txd<5>" LOC = "G14" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L30N_A20_M1A11 (E-TXD5) +NET "phy_txd<6>" LOC = "H12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L32P_A17_M1A8 (E-TXD6) +NET "phy_txd<7>" LOC = "K12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L34P_A13_M1WE (E-TXD7) +NET "phy_tx_en" LOC = "H15" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L37P_A7_M1A0 (E-TXEN) +NET "phy_tx_er" LOC = "G18" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L38N_A4_M1CLKN (E-TXER) +# GMII Receive (not used) +NET "phy_rx_clk" LOC = "K15" | IOSTANDARD=LVCMOS25 | TNM_NET = "clk_rx_local"; # IO_L41P_GCLK9_IRDY1_M1RASN (E-RXCLK) +NET "phy_rxd<0>" LOC = "G16" | IOSTANDARD=LVCMOS25; # IO_L38P_A5_M1CLK (E-RXD0) +NET "phy_rxd<1>" LOC = "H14" | IOSTANDARD=LVCMOS25; # IO_L36N_A8_M1BA1 (E-RXD1) +NET "phy_rxd<2>" LOC = "E16" | IOSTANDARD=LVCMOS25; # IO_L33P_A15_M1A10 (E-RXD2) +NET "phy_rxd<3>" LOC = "F15" | IOSTANDARD=LVCMOS25; # IO_L1P_A25 (E-RXD3) +NET "phy_rxd<4>" LOC = "F14" | IOSTANDARD=LVCMOS25; # IO_L30P_A21_M1RESET (E-RXD4) +NET "phy_rxd<5>" LOC = "E18" | IOSTANDARD=LVCMOS25; # IO_L33N_A14_M1A4 (E-RXD5) +NET "phy_rxd<6>" LOC = "D18" | IOSTANDARD=LVCMOS25; # IO_L31N_A18_M1A12 (E-RXD6) +NET "phy_rxd<7>" LOC = "D17" | IOSTANDARD=LVCMOS25; # IO_L31P_A19_M1CKE (E-RXD7) +NET "phy_rx_dv" LOC = "F17" | IOSTANDARD=LVCMOS25; # IO_L35P_A11_M1A7 (E-RXDV) +NET "phy_rx_er" LOC = "F18" | IOSTANDARD=LVCMOS25; # IO_L35N_A10_M1A2 (E-RXER) + +# Timing constraints for Ethernet PHY +TIMESPEC "TS_rx_clk_root" = PERIOD "clk_rx_local" 8000 ps HIGH 50 %; +# WARNING: Receiving Ethernet frames will not work without these constraints. +# WARNING: Meeting these constraints will require instantiating an IODELAY2 primitive. +#INST "phy_rxd" TNM = IN_GMII; +#INST "phy_rx_er" TNM = IN_GMII; +#INST "phy_rx_dv" TNM = IN_GMII; +#TIMEGRP "IN_GMII" OFFSET = IN 2.4 ns VALID 2.8 ns BEFORE "phy_rx_clk125"; + +# PMOD Connector (FPGA Bank 2) +# +# FPGA | Atlys +# ------------------------------------ +# T3 | IO_L62N_D6 | JA1 (TOP) +# R3 | IO_L62P_D5 | JA2 (TOP) +# P6 | IO_L64N_D9 | JA3 (TOP) +# N5 | IO_L64P_D8 | JA4 (TOP) +# | GND | JA5 (TOP) +# | Vcc | JA6 (TOP) +# V9 | IO_L32N_GCLK28 | JA7 (BOTTOM) +# T9 | IO_L32P_GCLK29 | JA8 (BOTTOM) +# V4 | IO_L63N | JA9 (BOTTOM) +# T4 | IO_L63P | JA10 (BOTTOM) +# | GND | JA11 (BOTTOM) +# | Vcc | JA12 (BOTTOM) +# +#NET "ready<1>" LOC = "T3" | IOSTANDARD=LVCMOS33 | PULLDOWN; +#NET "trigger<1>" LOC = "V9" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; +#NET "spi_mosi<1>" LOC = "R3" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; +#NET "spi_cs_n<1>" LOC = "T9" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; +#NET "spi_clk<1>" LOC = "P6" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; +#NET "spi_gnd<1>" LOC = "V4" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; + +# VHDCI Connector (FPGA Bank 2) +# Note: Channnel 1 connects to P signals, Channel 2 to N signals +# +# FPGA | Atlys | VmodMIB +# ----------------------------------------------------------------------------- +# U16 | IO_L2P_CMPCLK | EXP-IO1_P | JC.1 | JC-CLK_P | JC8 (BOTTOM) +# U15 | *IO_L5P | EXP-IO2_P | JC.3 | JC-D0_P | JC2 (TOP) +# U13 | IO_L14P_D11 | EXP-IO3_P | JC.4 | JC-D1_P | JC10 (BOTTOM) +# M11 | *IO_L15P | EXP-IO4_P | JC.6 | JC-D2_P | JC4 (TOP) +# R11 | IO_L16P | EXP-IO5_P | JC.7 | JA-D0_P | JA2 (TOP) +# T12 | *IO_L19P | EXP-IO6_P | JC.9 | JA-D1_P | JA10 (BOTTOM) +# N10 | *IO_L20P | EXP-IO7_P | JC.10 | JA-D2_P | JA4 (TOP) +# M10 | *IO_L22P | EXP-IO8_P | JC.12 | JB-D0_P | JB2 (TOP) +# U11 | IO_L23P | EXP-IO9_P | JC.13 | JB-D1_P | JB10 (BOTTOM) +# R10 | IO_L29P_GCLK3 | EXP-IO10_P | JC.15 | JA-CLK_P | JA8 (BOTTOM) +# U10 | IO_L30P_GCLK1_D13 | EXP-IO11_P | JC.20 | JB-CLK_P | JB8 (BOTTOM) +# R8 | IO_L31P_GCLK31_D14 | EXP-IO12_P | JC.22 | JB-D2_P | JB4 (TOP) +# M8 | *IO_L40P | EXP-IO13_P | JC.23 | JE8 | JE8 (BOTTOM) +# U8 | IO_L41P | EXP-IO14_P | JC.25 | JE2 | JE2 (TOP) +# U7 | IO_L43P | EXP-IO15_P | JC.26 | JE10 | JE10 (BOTTOM) +# N7 | *IO_L44P | EXP-IO16_P | JC.28 | JE4 | JE4 (TOP) +# T6 | IO_L45P | EXP-IO17_P | JC.29 | JD-CLK_P | JD8 (BOTTOM) +# R7 | IO_L46P | EXP-IO18_P | JC.31 | JD-D0_P | JD2 (TOP) +# N6 | *IO_L47P | EXP-IO19_P | JC.32 | JD-D1_P | JD10 (BOTTOM) +# U5 | IO_49P_D3 | EXP-IO20_P | JC.34 | JD-D2_P | JD4 (TOP) +# V16 | IO_L2N_CMPMOSI | EXP-IO1_N | JC.35 | JC-CLK_N | JC7 (BOTTOM) +# V15 | *IO_L5N | EXP-IO2_N | JC.37 | JC-D0_N | JC1 (TOP) +# V13 | IO_L14N_D12 | EXP-IO3_N | JC.38 | JC-D1_N | JC9 (BOTTOM) +# N11 | *IO_L15N | EXP-IO4_N | JC.40 | JC-D2_N | JC3 (TOP) +# T11 | IO_L16N_VREF | EXP-IO5_N | JC.41 | JA-D0_N | JA1 (TOP) +# V12 | *IO_L19N | EXP-IO6_N | JC.43 | JA-D1_N | JA9 (BOTTOM) +# P11 | *IO_L20N | EXP-IO7_N | JC.44 | JA-D2_N | JA3 (TOP) +# N9 | *IO_L22N | EXP-IO8_N | JC.46 | JB-D0_N | JB1 (TOP) +# V11 | IO_L23N | EXP-IO9_N | JC.47 | JB-D1_N | JB9 (BOTTOM) +# T10 | IO_L29N_GCLK2 | EXP-IO10_N | JC.49 | JA-CLK_N | JA7 (BOTTOM) +# V10 | IO_L30N_GCLK0_USERCCLK | EXP-IO11_N | JC.54 | JB-CLK_N | JB7 (BOTTOM) +# T8 | IO_L31N_GCLK30_D15 | EXP-IO12_N | JC.56 | JB-D2_N | JB3 (TOP) +# N8 | *IO_L40N | EXP-IO13_N | JC.57 | JE7 | JE7 (BOTTOM) +# V8 | IO_L41N_VREF | EXP-IO14_N | JC.59 | JE1 | JE1 (TOP) +# V7 | IO_L43N | EXP-IO15_N | JC.60 | JE9 | JE9 (BOTTOM) +# P8 | *IO_L44N | EXP-IO16_N | JC.62 | JE3 | JE3 (TOP) +# V6 | IO_L45N | EXP-IO17_N | JC.63 | JD-CLK_N | JD7 (BOTTOM) +# T7 | IO_L46N | EXP-IO18_N | JC.65 | JD-D0_N | JD1 (TOP) +# P7 | *IO_L47N | EXP-IO19_N | JC.66 | JD-D1_N | JD9 (BOTTOM) +# V5 | IO_49N_D4 | EXP-IO20_N | JC.68 | JD-D2_N | JD3 (TOP) + +#NET "" LOC = "U16" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO1_P +#NET "" LOC = "U15" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO2_P +#NET "" LOC = "U13" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO3_P +#NET "" LOC = "M11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO4_P +#NET "" LOC = "R11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO5_P +#NET "" LOC = "T12" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO6_P +#NET "" LOC = "N10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO7_P +#NET "" LOC = "M10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO8_P +#NET "" LOC = "U11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO9_P +#NET "" LOC = "R10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO10_P +#NET "" LOC = "U10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO11_P +#NET "" LOC = "R8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO12_P +#NET "" LOC = "M8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO13_P +#NET "" LOC = "U8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO14_P +#NET "" LOC = "U7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO15_P +#NET "" LOC = "N7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO16_P +#NET "" LOC = "T6" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO17_P +#NET "" LOC = "R7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO18_P +#NET "" LOC = "N6" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO19_P +#NET "" LOC = "U5" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO20_P +#NET "" LOC = "V16" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO1_N +#NET "" LOC = "V15" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO2_N +#NET "" LOC = "V13" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO3_N +#NET "" LOC = "N11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO4_N +#NET "" LOC = "T11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO5_N +#NET "" LOC = "V12" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO6_N +#NET "" LOC = "P11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO7_N +#NET "" LOC = "N9" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO8_N +#NET "" LOC = "V11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO9_N +#NET "" LOC = "T10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO10_N +#NET "" LOC = "V10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO11_N +#NET "" LOC = "T8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO12_N +#NET "" LOC = "N8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO13_N +#NET "" LOC = "V8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO14_N +#NET "" LOC = "V7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO15_N +#NET "" LOC = "P8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO16_N +#NET "" LOC = "V6" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO17_N +#NET "" LOC = "T7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO18_N +#NET "" LOC = "P7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO19_N +#NET "" LOC = "V5" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO20_N + +# Exar UART: I/O Bank 0 +NET "uart_rxd" LOC = "A16" | IOSTANDARD=LVCMOS33; # IO_L66N_SCP0 (USBB-RXD) +NET "uart_txd" LOC = "B16" | IOSTANDARD=LVCMOS33; # IO_L66P_SCP1 (USBB-TXD) diff --git a/example/ATLYS/fpga/fpga/Makefile b/example/ATLYS/fpga/fpga/Makefile new file mode 100644 index 000000000..aed16c07f --- /dev/null +++ b/example/ATLYS/fpga/fpga/Makefile @@ -0,0 +1,61 @@ + +# FPGA settings +FPGA_PART = xc6slx45-2csg324 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/fpga_pads.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/gmii_phy_if.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v +SYN_FILES += lib/eth/rtl/eth_crc_8.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v +SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v +SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v + +# UCF files +UCF_FILES = fpga.ucf +UCF_FILES += clock.ucf + +# NGC paths for ngdbuild +NGC_PATHS = coregen/dcm_i100_o125 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + djtgcfg prog -d Atlys --index 0 --file $(FPGA_TOP).bit + diff --git a/example/ATLYS/fpga/lib/eth b/example/ATLYS/fpga/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/ATLYS/fpga/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/ATLYS/fpga/rtl/debounce_switch.v b/example/ATLYS/fpga/rtl/debounce_switch.v new file mode 100644 index 000000000..f3fb77a16 --- /dev/null +++ b/example/ATLYS/fpga/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/ATLYS/fpga/rtl/fpga.v b/example/ATLYS/fpga/rtl/fpga.v new file mode 100644 index 000000000..0aa317e47 --- /dev/null +++ b/example/ATLYS/fpga/rtl/fpga.v @@ -0,0 +1,182 @@ +/* + +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. + +*/ + +module fpga ( + /* + * Clock: 100MHz + * Reset: Push button, active low + */ + input wire clk, + input wire reset_n, + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire [7:0] led, + /* + * Ethernet: 1000BASE-T GMII + */ + input wire phy_rx_clk, + input wire [7:0] phy_rxd, + input wire phy_rx_dv, + input wire phy_rx_er, + output wire phy_gtx_clk, + output wire [7:0] phy_txd, + output wire phy_tx_en, + output wire phy_tx_er, + output wire phy_reset_n, + /* + * UART: 500000 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd +); + +/* + * Clock: 125MHz + * Synchronous reset + */ +wire clk_int; +wire rst_int; +/* + * GPIO + */ +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [7:0] sw_int; +wire [7:0] led_int; +/* + * Ethernet: 1000BASE-T GMII + */ +wire phy_rx_clk_int; +wire [7:0] phy_rxd_int; +wire phy_rx_dv_int; +wire phy_rx_er_int; +wire phy_gtx_clk_int; +wire [7:0] phy_txd_int; +wire phy_tx_en_int; +wire phy_tx_er_int; +wire phy_reset_n_int; +/* + * UART: 115200 bps, 8N1 + */ +wire uart_rxd_int; +wire uart_txd_int; + +fpga_core +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk(clk_int), + .rst(rst_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .led(led_int), + /* + * Ethernet: 1000BASE-T GMII + */ + .phy_rx_clk(phy_rx_clk_int), + .phy_rxd(phy_rxd_int), + .phy_rx_dv(phy_rx_dv_int), + .phy_rx_er(phy_rx_er_int), + .phy_gtx_clk(phy_gtx_clk_int), + .phy_txd(phy_txd_int), + .phy_tx_en(phy_tx_en_int), + .phy_tx_er(phy_tx_er_int), + .phy_reset_n(phy_reset_n_int), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd_int) +); + +fpga_pads +pads_inst ( + /* + * Pads + */ + .clk_pad(clk), + .reset_n_pad(reset_n), + .btnu_pad(btnu), + .btnl_pad(btnl), + .btnd_pad(btnd), + .btnr_pad(btnr), + .btnc_pad(btnc), + .sw_pad(sw), + .led_pad(led), + .phy_rx_clk_pad(phy_rx_clk), + .phy_rxd_pad(phy_rxd), + .phy_rx_dv_pad(phy_rx_dv), + .phy_rx_er_pad(phy_rx_er), + .phy_gtx_clk_pad(phy_gtx_clk), + .phy_txd_pad(phy_txd), + .phy_tx_en_pad(phy_tx_en), + .phy_tx_er_pad(phy_tx_er), + .phy_reset_n_pad(phy_reset_n), + .uart_rxd_pad(uart_rxd), + .uart_txd_pad(uart_txd), + /* + * Internal + */ + .clk_int(clk_int), + .rst_int(rst_int), + .btnu_int(btnu_int), + .btnl_int(btnl_int), + .btnd_int(btnd_int), + .btnr_int(btnr_int), + .btnc_int(btnc_int), + .sw_int(sw_int), + .led_int(led_int), + .phy_rx_clk_int(phy_rx_clk_int), + .phy_rxd_int(phy_rxd_int), + .phy_rx_dv_int(phy_rx_dv_int), + .phy_rx_er_int(phy_rx_er_int), + .phy_gtx_clk_int(phy_gtx_clk_int), + .phy_txd_int(phy_txd_int), + .phy_tx_en_int(phy_tx_en_int), + .phy_tx_er_int(phy_tx_er_int), + .phy_reset_n_int(phy_reset_n_int), + .uart_rxd_int(uart_rxd_int), + .uart_txd_int(uart_txd_int) +); + +endmodule diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..aedb04de3 --- /dev/null +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -0,0 +1,646 @@ +/* + +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 fpga_core # +( + parameter TARGET_XILINX = 1 +) +( + /* + * Clock: 125MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire [7:0] led, + /* + * Ethernet: 1000BASE-T GMII + */ + input wire phy_rx_clk, + input wire [7:0] phy_rxd, + input wire phy_rx_dv, + input wire phy_rx_er, + output wire phy_gtx_clk, + output wire [7:0] phy_txd, + output wire phy_tx_en, + output wire phy_tx_er, + output wire phy_reset_n, + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd +); + +// GMII between MAC and PHY IF +wire gmii_rx_clk; +wire gmii_rx_rst; +wire [7:0] gmii_rxd; +wire gmii_rx_dv; +wire gmii_rx_er; + +wire gmii_tx_clk; +wire gmii_tx_rst; +wire [7:0] gmii_txd; +wire gmii_tx_en; +wire gmii_tx_er; + +// AXI between MAC and FIFO +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [7:0] tx_axis_tdata; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; + +// AXI between FIFO and Ethernet modules +wire [7:0] rx_fifo_axis_tdata; +wire rx_fifo_axis_tvalid; +wire rx_fifo_axis_tready; +wire rx_fifo_axis_tlast; +wire rx_fifo_axis_tuser = 0; + +wire [7:0] tx_fifo_axis_tdata; +wire tx_fifo_axis_tvalid; +wire tx_fifo_axis_tready; +wire tx_fifo_axis_tlast; +wire tx_fifo_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [7:0] rx_eth_payload_tdata; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [7:0] tx_eth_payload_tdata; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [7:0] rx_ip_payload_tdata; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [7:0] tx_ip_payload_tdata; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [7:0] rx_udp_payload_tdata; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_tdata; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [7:0] rx_fifo_udp_payload_tdata; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [7:0] tx_fifo_udp_payload_tdata; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_tvalid; + if (tx_udp_payload_tvalid & ~valid_last) begin + led_reg <= tx_udp_payload_tdata; + end + end +end + +//assign led = sw; +assign led = led_reg; +assign phy_reset_n = ~rst; + +assign uart_txd = 0; + +gmii_phy_if #( + .TARGET_XILINX(TARGET_XILINX) +) +gmii_phy_if_inst ( + .clk(clk), + .rst(rst), + + .mac_gmii_rx_clk(gmii_rx_clk), + .mac_gmii_rx_rst(gmii_rx_rst), + .mac_gmii_rxd(gmii_rxd), + .mac_gmii_rx_dv(gmii_rx_dv), + .mac_gmii_rx_er(gmii_rx_er), + .mac_gmii_tx_clk(gmii_tx_clk), + .mac_gmii_tx_rst(gmii_tx_rst), + .mac_gmii_txd(gmii_txd), + .mac_gmii_tx_en(gmii_tx_en), + .mac_gmii_tx_er(gmii_tx_er), + + .phy_gmii_rx_clk(phy_rx_clk), + .phy_gmii_rxd(phy_rxd), + .phy_gmii_rx_dv(phy_rx_dv), + .phy_gmii_rx_er(phy_rx_er), + .phy_gmii_tx_clk(phy_gtx_clk), + .phy_gmii_txd(phy_txd), + .phy_gmii_tx_en(phy_tx_en), + .phy_gmii_tx_er(phy_tx_er) +); + +eth_mac_1g #( + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64) +) +eth_mac_1g_inst ( + .rx_clk(gmii_rx_clk), + .rx_rst(gmii_rx_rst), + .tx_clk(gmii_tx_clk), + .tx_rst(gmii_tx_rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(0), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + + .ifg_delay(12) +); + +axis_async_frame_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8), + .DROP_WHEN_FULL(1) +) +rx_fifo ( + // AXI input + .input_clk(gmii_rx_clk), + .input_rst(gmii_rx_rst), + + .input_axis_tdata(rx_axis_tdata), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + + // AXI output + .output_clk(clk), + .output_rst(rst), + + .output_axis_tdata(rx_fifo_axis_tdata), + .output_axis_tvalid(rx_fifo_axis_tvalid), + .output_axis_tready(rx_fifo_axis_tready), + .output_axis_tlast(rx_fifo_axis_tlast) +); + +axis_async_frame_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8) +) +tx_fifo ( + // AXI input + .input_clk(clk), + .input_rst(rst), + + .input_axis_tdata(tx_fifo_axis_tdata), + .input_axis_tvalid(tx_fifo_axis_tvalid), + .input_axis_tready(tx_fifo_axis_tready), + .input_axis_tlast(tx_fifo_axis_tlast), + .input_axis_tuser(tx_fifo_axis_tuser), + + // AXI output + .output_clk(gmii_tx_clk), + .output_rst(gmii_tx_rst), + + .output_axis_tdata(tx_axis_tdata), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast) +); + +eth_axis_rx +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(rx_fifo_axis_tdata), + .input_axis_tvalid(rx_fifo_axis_tvalid), + .input_axis_tready(rx_fifo_axis_tready), + .input_axis_tlast(rx_fifo_axis_tlast), + .input_axis_tuser(rx_fifo_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_fifo_axis_tdata), + .output_axis_tvalid(tx_fifo_axis_tvalid), + .output_axis_tready(tx_fifo_axis_tready), + .output_axis_tlast(tx_fifo_axis_tlast), + .output_axis_tuser(tx_fifo_axis_tuser), + // Status signals + .busy() +); + +udp_complete #( + .UDP_CHECKSUM_ENABLE(0) +) +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(0) +); + +axis_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/ATLYS/fpga/rtl/fpga_pads.v b/example/ATLYS/fpga/rtl/fpga_pads.v new file mode 100644 index 000000000..82222816b --- /dev/null +++ b/example/ATLYS/fpga/rtl/fpga_pads.v @@ -0,0 +1,170 @@ +/* + +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 fpga_pads ( + /* + * Pads + */ + input wire clk_pad, + input wire reset_n_pad, + input wire btnu_pad, + input wire btnl_pad, + input wire btnd_pad, + input wire btnr_pad, + input wire btnc_pad, + input wire [7:0] sw_pad, + output wire [7:0] led_pad, + input wire phy_rx_clk_pad, + input wire [7:0] phy_rxd_pad, + input wire phy_rx_dv_pad, + input wire phy_rx_er_pad, + output wire phy_gtx_clk_pad, + output wire [7:0] phy_txd_pad, + output wire phy_tx_en_pad, + output wire phy_tx_er_pad, + output wire phy_reset_n_pad, + input wire uart_rxd_pad, + output wire uart_txd_pad, + /* + * Internal + */ + output wire clk_int, + output wire rst_int, + output wire btnu_int, + output wire btnl_int, + output wire btnd_int, + output wire btnr_int, + output wire btnc_int, + output wire [7:0] sw_int, + input wire [7:0] led_int, + output wire phy_rx_clk_int, + output wire [7:0] phy_rxd_int, + output wire phy_rx_dv_int, + output wire phy_rx_er_int, + input wire phy_gtx_clk_int, + input wire [7:0] phy_txd_int, + input wire phy_tx_en_int, + input wire phy_tx_er_int, + input wire phy_reset_n_int, + output wire uart_rxd_int, + input wire uart_txd_int +); + +wire clk_valid; +/* + * Asynchronous reset created by from the combination of the external + * asyncrhonous reset input and the DCM clk_valid output. + */ +wire reset0 = ~reset_n_pad; +wire reset1 = ~clk_valid; + +/* + * Create a 125MHz clock from a 100MHz clock. + */ +dcm_i100_o125 +dcm_inst ( + .CLK_IN1(clk_pad), // IN(1) + .RESET(reset0), // IN(1) + .CLK_OUT1(clk_int), // OUT(1) + .LOCKED(clk_valid) // OUT(1) +); + +/* + * Create a synchronous reset in the 125MHz domain. + */ +sync_reset #( + .N(6) +) +sync_reset_inst ( + .clk(clk_int), // IN(1) + .rst(reset1), // IN(1) + .sync_reset_out(rst_int) // OUT(1) +); + +/* + * Synchronize the inputs. + */ +sync_signal #( + .WIDTH(1), + .N(2) +) +sync_signal_inst ( + .clk(clk_int), //IN(1) + .in({uart_rxd_pad}), //IN(1) + .out({uart_rxd_int}) // OUT(1) +); + +/* + * Debounce the switches + */ +debounce_switch #( + .WIDTH(13), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_int), // IN(1) + .rst(rst_int), // IN(1) + .in({btnu_pad, + btnl_pad, + btnd_pad, + btnr_pad, + btnc_pad, + sw_pad}), // IN(13) + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) // OUT(13) +); + +/* + * PHY inputs not synchronized here + */ +assign phy_rx_clk_int = phy_rx_clk_pad; +assign phy_rxd_int = phy_rxd_pad; +assign phy_rx_dv_int = phy_rx_dv_pad; +assign phy_rx_er_int = phy_rx_er_pad; + +/* + * PHY outputs not synchronized here + */ +assign phy_gtx_clk_pad = phy_gtx_clk_int; +assign phy_txd_pad = phy_txd_int; +assign phy_tx_en_pad = phy_tx_en_int; +assign phy_tx_er_pad = phy_tx_er_int; +assign phy_reset_n_pad = phy_reset_n_int; + +/* + * Outputs not synchronized here + */ +assign led_pad = led_int; +assign uart_txd_pad = uart_txd_int; + +endmodule diff --git a/example/ATLYS/fpga/rtl/sync_reset.v b/example/ATLYS/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..ffa0530bf --- /dev/null +++ b/example/ATLYS/fpga/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/ATLYS/fpga/rtl/sync_signal.v b/example/ATLYS/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..705d4f8ec --- /dev/null +++ b/example/ATLYS/fpga/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/ATLYS/fpga/tb/arp_ep.py b/example/ATLYS/fpga/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/ATLYS/fpga/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/ATLYS/fpga/tb/axis_ep.py b/example/ATLYS/fpga/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/ATLYS/fpga/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/ATLYS/fpga/tb/eth_ep.py b/example/ATLYS/fpga/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/ATLYS/fpga/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/ATLYS/fpga/tb/gmii_ep.py b/example/ATLYS/fpga/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/ATLYS/fpga/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/ATLYS/fpga/tb/ip_ep.py b/example/ATLYS/fpga/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/ATLYS/fpga/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py new file mode 100755 index 000000000..18d082d6b --- /dev/null +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -0,0 +1,335 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep +import arp_ep +import udp_ep +import gmii_ep + +module = 'fpga_core' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/gmii_phy_if.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") +srcs.append("../lib/eth/rtl/eth_crc_8.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp.v") +srcs.append("../lib/eth/rtl/udp_ip_rx.v") +srcs.append("../lib/eth/rtl/udp_ip_tx.v") +srcs.append("../lib/eth/rtl/ip_complete.v") +srcs.append("../lib/eth/rtl/ip.v") +srcs.append("../lib/eth/rtl/ip_eth_rx.v") +srcs.append("../lib/eth/rtl/ip_eth_tx.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") +srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") +srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_fpga_core(clk, + rst, + + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + led, + + phy_rx_clk, + phy_rxd, + phy_rx_dv, + phy_rx_er, + phy_gtx_clk, + phy_txd, + phy_tx_en, + phy_tx_er, + phy_reset_n, + + uart_rxd, + uart_txd): + + 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, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, + + phy_rx_clk=phy_rx_clk, + phy_rxd=phy_rxd, + phy_rx_dv=phy_rx_dv, + phy_rx_er=phy_rx_er, + phy_gtx_clk=phy_gtx_clk, + phy_txd=phy_txd, + phy_tx_en=phy_tx_en, + phy_tx_er=phy_tx_er, + phy_reset_n=phy_reset_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd) + +def bench(): + + # Parameters + TARGET_XILINX = 1 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[8:]) + phy_rx_clk = Signal(bool(0)) + phy_rxd = Signal(intbv(0)[8:]) + phy_rx_dv = Signal(bool(0)) + phy_rx_er = Signal(bool(0)) + uart_rxd = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[8:]) + phy_gtx_clk = Signal(bool(0)) + phy_txd = Signal(intbv(0)[8:]) + phy_tx_en = Signal(bool(0)) + phy_tx_er = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_txd = Signal(bool(0)) + + # sources and sinks + gmii_source_queue = Queue() + gmii_sink_queue = Queue() + + gmii_source = gmii_ep.GMIISource(phy_rx_clk, + rst, + txd=phy_rxd, + tx_en=phy_rx_dv, + tx_er=phy_rx_er, + fifo=gmii_source_queue, + name='gmii_source') + + gmii_sink = gmii_ep.GMIISink(phy_gtx_clk, + rst, + rxd=phy_txd, + rx_dv=phy_tx_en, + rx_er=phy_tx_er, + fifo=gmii_sink_queue, + name='gmii_sink') + + # DUT + dut = dut_fpga_core(clk, + rst, + current_test, + + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + led, + + phy_rx_clk, + phy_rxd, + phy_rx_dv, + phy_rx_er, + phy_gtx_clk, + phy_txd, + phy_tx_en, + phy_tx_er, + phy_reset_n, + + uart_rxd, + uart_txd) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + phy_rx_clk.next = not phy_rx_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 + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source_queue.put(test_frame.build_eth().build_axis_fcs()) + + # wait for ARP request packet + while gmii_sink_queue.empty(): + yield clk.posedge + + rx_frame = gmii_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(bytearray(rx_frame)) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + gmii_source_queue.put(arp_frame.build_eth().build_axis_fcs()) + + while gmii_sink_queue.empty(): + yield clk.posedge + + rx_frame = gmii_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(bytearray(rx_frame)) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source_queue.empty() + assert gmii_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, gmii_source, gmii_sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/ATLYS/fpga/tb/test_fpga_core.v b/example/ATLYS/fpga/tb/test_fpga_core.v new file mode 100644 index 000000000..cf9bf6426 --- /dev/null +++ b/example/ATLYS/fpga/tb/test_fpga_core.v @@ -0,0 +1,118 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters +parameter TARGET_XILINX = 0; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [7:0] sw = 0; +reg phy_rx_clk = 0; +reg [7:0] phy_rxd = 0; +reg phy_rx_dv = 0; +reg phy_rx_er = 0; +reg uart_rxd = 0; + +// Outputs +wire [7:0] led; +wire phy_gtx_clk; +wire [7:0] phy_txd; +wire phy_tx_en; +wire phy_tx_er; +wire phy_reset_n; +wire uart_txd; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_rx_clk, + phy_rxd, + phy_rx_dv, + phy_rx_er, + uart_rxd); + $to_myhdl(led, + phy_gtx_clk, + phy_txd, + phy_tx_en, + phy_tx_er, + phy_reset_n, + uart_txd); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core #( + .TARGET_XILINX(TARGET_XILINX) +) +UUT ( + .clk(clk), + .rst(rst), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_dv(phy_rx_dv), + .phy_rx_er(phy_rx_er), + .phy_gtx_clk(phy_gtx_clk), + .phy_txd(phy_txd), + .phy_tx_en(phy_tx_en), + .phy_tx_er(phy_tx_er), + .phy_reset_n(phy_reset_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd) +); + +endmodule diff --git a/example/ATLYS/fpga/tb/udp_ep.py b/example/ATLYS/fpga/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/ATLYS/fpga/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file From 08dd43defc169c69ccd6acdfa46d4646b9b9fecb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 28 Feb 2015 23:08:53 -0800 Subject: [PATCH 162/617] Add frame length asserts to gigabit MAC testbench --- tb/test_eth_mac_1g.py | 1 + tb/test_eth_mac_1g_tx.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index 8b53ee4b6..8e07f6cf1 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -320,6 +320,7 @@ def bench(): print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) + assert len(eth_frame.payload.data) == 46 assert eth_frame.eth_fcs == eth_frame.calc_fcs() assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac assert eth_frame.eth_src_mac == test_frame.eth_src_mac diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index 3d0531104..9629c9fab 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -196,6 +196,7 @@ def bench(): print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) + assert len(eth_frame.payload.data) == max(payload_len, 46) assert eth_frame.eth_fcs == eth_frame.calc_fcs() assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac assert eth_frame.eth_src_mac == test_frame.eth_src_mac @@ -248,6 +249,7 @@ def bench(): print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) + assert len(eth_frame.payload.data) == max(payload_len, 46) assert eth_frame.eth_fcs == eth_frame.calc_fcs() assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac assert eth_frame.eth_src_mac == test_frame1.eth_src_mac @@ -264,6 +266,7 @@ def bench(): print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) + assert len(eth_frame.payload.data) == max(payload_len, 46) assert eth_frame.eth_fcs == eth_frame.calc_fcs() assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac assert eth_frame.eth_src_mac == test_frame2.eth_src_mac @@ -324,6 +327,7 @@ def bench(): print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) + assert len(eth_frame.payload.data) == max(payload_len, 46) assert eth_frame.eth_fcs == eth_frame.calc_fcs() assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac assert eth_frame.eth_src_mac == test_frame2.eth_src_mac From d3e30d0a73604e3b873661ceee1877b59021d38c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 28 Feb 2015 23:09:41 -0800 Subject: [PATCH 163/617] Fix padding bug --- rtl/axis_eth_fcs_insert.v | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v index a95380175..dd0a43090 100644 --- a/rtl/axis_eth_fcs_insert.v +++ b/rtl/axis_eth_fcs_insert.v @@ -158,7 +158,7 @@ always @* begin state_next = STATE_IDLE; end else begin input_axis_tready_next = 0; - if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-5) begin + if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin state_next = STATE_PAD; end else begin frame_ptr_next = 0; @@ -184,12 +184,14 @@ always @* begin if (output_axis_tready_int) begin frame_ptr_next = frame_ptr_reg + 1; update_crc = 1; - if (frame_ptr_next < MIN_FRAME_LENGTH-5) begin + if (frame_ptr_reg < MIN_FRAME_LENGTH-5) begin state_next = STATE_PAD; end else begin frame_ptr_next = 0; state_next = STATE_FCS; end + end else begin + state_next = STATE_PAD; end end STATE_FCS: begin From ff14639eea5d9f926e273f7c64dfae8ca4a5cc86 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 28 Feb 2015 23:13:02 -0800 Subject: [PATCH 164/617] Test FCS inserter with padding insertion enabled --- tb/test_axis_eth_fcs_insert.py | 42 ++++++++++++++++++++++++++++++---- tb/test_axis_eth_fcs_insert.v | 2 +- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index ccf395879..df6ef3d8c 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -84,7 +84,7 @@ def dut_axis_eth_fcs_insert(clk, def bench(): # Parameters - ENABLE_PADDING = 0 + ENABLE_PADDING = 1 MIN_FRAME_LENGTH = 64 # Inputs @@ -224,7 +224,15 @@ def bench(): eth_frame = eth_ep.EthFrame() eth_frame.parse_axis_fcs(rx_frame) - assert eth_frame == test_frame + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 assert sink_queue.empty() @@ -269,7 +277,15 @@ def bench(): eth_frame = eth_ep.EthFrame() eth_frame.parse_axis_fcs(rx_frame) - assert eth_frame == test_frame1 + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame1.eth_src_mac + assert eth_frame.eth_type == test_frame1.eth_type + assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 rx_frame = None if not sink_queue.empty(): @@ -278,7 +294,15 @@ def bench(): eth_frame = eth_ep.EthFrame() eth_frame.parse_axis_fcs(rx_frame) - assert eth_frame == test_frame2 + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 assert sink_queue.empty() @@ -331,7 +355,15 @@ def bench(): eth_frame = eth_ep.EthFrame() eth_frame.parse_axis_fcs(rx_frame) - assert eth_frame == test_frame2 + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 assert sink_queue.empty() diff --git a/tb/test_axis_eth_fcs_insert.v b/tb/test_axis_eth_fcs_insert.v index 39f966fd3..8cf67d99c 100644 --- a/tb/test_axis_eth_fcs_insert.v +++ b/tb/test_axis_eth_fcs_insert.v @@ -32,7 +32,7 @@ THE SOFTWARE. module test_axis_eth_fcs_insert; // Parameters -parameter ENABLE_PADDING = 0; +parameter ENABLE_PADDING = 1; parameter MIN_FRAME_LENGTH = 64; // Inputs From 43999fb360b1a9ac644b640cc7091a5bdfcf5f0c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 3 Mar 2015 00:46:53 -0800 Subject: [PATCH 165/617] Add testbench for FCS insert with padding --- tb/test_axis_eth_fcs_insert.py | 8 +- tb/test_axis_eth_fcs_insert.v | 2 +- tb/test_axis_eth_fcs_insert_pad.py | 382 +++++++++++++++++++++++++++++ tb/test_axis_eth_fcs_insert_pad.v | 99 ++++++++ 4 files changed, 486 insertions(+), 5 deletions(-) create mode 100755 tb/test_axis_eth_fcs_insert_pad.py create mode 100644 tb/test_axis_eth_fcs_insert_pad.v diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index df6ef3d8c..be271d576 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -227,7 +227,7 @@ def bench(): print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) - assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.payload.data == test_frame.payload.data assert eth_frame.eth_fcs == eth_frame.calc_fcs() assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac assert eth_frame.eth_src_mac == test_frame.eth_src_mac @@ -280,7 +280,7 @@ def bench(): print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) - assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.payload.data == test_frame1.payload.data assert eth_frame.eth_fcs == eth_frame.calc_fcs() assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac assert eth_frame.eth_src_mac == test_frame1.eth_src_mac @@ -297,7 +297,7 @@ def bench(): print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) - assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.payload.data == test_frame2.payload.data assert eth_frame.eth_fcs == eth_frame.calc_fcs() assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac assert eth_frame.eth_src_mac == test_frame2.eth_src_mac @@ -358,7 +358,7 @@ def bench(): print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) - assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.payload.data == test_frame2.payload.data assert eth_frame.eth_fcs == eth_frame.calc_fcs() assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac assert eth_frame.eth_src_mac == test_frame2.eth_src_mac diff --git a/tb/test_axis_eth_fcs_insert.v b/tb/test_axis_eth_fcs_insert.v index 8cf67d99c..39f966fd3 100644 --- a/tb/test_axis_eth_fcs_insert.v +++ b/tb/test_axis_eth_fcs_insert.v @@ -32,7 +32,7 @@ THE SOFTWARE. module test_axis_eth_fcs_insert; // Parameters -parameter ENABLE_PADDING = 1; +parameter ENABLE_PADDING = 0; parameter MIN_FRAME_LENGTH = 64; // Inputs diff --git a/tb/test_axis_eth_fcs_insert_pad.py b/tb/test_axis_eth_fcs_insert_pad.py new file mode 100755 index 000000000..6c972b43d --- /dev/null +++ b/tb/test_axis_eth_fcs_insert_pad.py @@ -0,0 +1,382 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep + +module = 'axis_eth_fcs_insert' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("test_%s_pad.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_eth_fcs_insert(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, + + busy): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_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, + + busy=busy) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # 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)) + busy = 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_eth_fcs_insert(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, + + busy) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame1.eth_src_mac + assert eth_frame.eth_type == test_frame1.eth_type + assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_eth_fcs_insert_pad.v b/tb/test_axis_eth_fcs_insert_pad.v new file mode 100644 index 000000000..5464d7c99 --- /dev/null +++ b/tb/test_axis_eth_fcs_insert_pad.v @@ -0,0 +1,99 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for axis_eth_fcs_insert + */ +module test_axis_eth_fcs_insert_pad; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; + +// 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 busy; + +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, + busy); + + // dump file + $dumpfile("test_axis_eth_fcs_insert_pad.lxt"); + $dumpvars(0, test_axis_eth_fcs_insert_pad); +end + +axis_eth_fcs_insert #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .clk(clk), + .rst(rst), + .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), + .busy(busy) +); + +endmodule From 23fa1f12076161a0bf6e4b3dd4392479a88e9e92 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 3 Mar 2015 21:46:02 -0800 Subject: [PATCH 166/617] Handle tlast on first cycle --- rtl/axis_eth_fcs_insert.v | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v index dd0a43090..665c93d5c 100644 --- a/rtl/axis_eth_fcs_insert.v +++ b/rtl/axis_eth_fcs_insert.v @@ -133,7 +133,25 @@ always @* begin frame_ptr_next = 1; reset_crc = 0; update_crc = 1; - state_next = STATE_PAYLOAD; + if (input_axis_tlast) begin + if (input_axis_tuser) begin + output_axis_tlast_int = 1; + output_axis_tuser_int = 1; + reset_crc = 1; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + input_axis_tready_next = 0; + if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin + state_next = STATE_PAD; + end else begin + frame_ptr_next = 0; + state_next = STATE_FCS; + end + end + end else begin + state_next = STATE_PAYLOAD; + end end else begin state_next = STATE_IDLE; end @@ -155,6 +173,7 @@ always @* begin output_axis_tlast_int = 1; output_axis_tuser_int = 1; reset_crc = 1; + frame_ptr_next = 0; state_next = STATE_IDLE; end else begin input_axis_tready_next = 0; From 47a3a50b655150300ebc188fc1a714a15cadef16 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 3 Mar 2015 23:47:27 -0800 Subject: [PATCH 167/617] Move preamble out of gmii endpoint --- tb/gmii_ep.py | 7 +++---- tb/test_eth_mac_1g.py | 6 ++++-- tb/test_eth_mac_1g_rx.py | 10 +++++----- tb/test_eth_mac_1g_tx.py | 18 ++++++++++++++---- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index c4b13d3b7..82123c2fe 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -58,7 +58,6 @@ def GMIISource(clk, rst, frame = fifo.get() if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) - frame = '\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(frame) txd.next = frame.pop(0) tx_en.next = 1 else: @@ -85,12 +84,12 @@ def GMIISink(clk, rst, frame = None else: if rx_dv: - if frame is None and rxd == 0xD5: + if frame is None: frame = [] - elif frame is not None: - frame.append(int(rxd)) + frame.append(int(rxd)) elif frame is not None: if len(frame) > 0: + frame = bytearray(frame) if fifo is not None: fifo.put(frame) if name is not None: diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index 8e07f6cf1..9399be2de 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -265,7 +265,7 @@ def bench(): axis_frame = test_frame.build_axis_fcs() - gmii_source_queue.put(axis_frame) + gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) yield clk.posedge yield clk.posedge @@ -314,8 +314,10 @@ def bench(): if not gmii_sink_queue.empty(): rx_frame = gmii_sink_queue.get() + assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(bytearray(rx_frame)) + eth_frame.parse_axis_fcs(rx_frame[8:]) print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py index 1f05e43c3..71089f1d9 100755 --- a/tb/test_eth_mac_1g_rx.py +++ b/tb/test_eth_mac_1g_rx.py @@ -179,7 +179,7 @@ def bench(): axis_frame = test_frame.build_axis_fcs() - source_queue.put(axis_frame) + source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) yield clk.posedge yield clk.posedge @@ -224,8 +224,8 @@ def bench(): axis_frame1 = test_frame1.build_axis_fcs() axis_frame2 = test_frame2.build_axis_fcs() - source_queue.put(axis_frame1) - source_queue.put(axis_frame2) + source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) yield clk.posedge yield clk.posedge @@ -290,8 +290,8 @@ def bench(): error_bad_frame_asserted.next = 0 error_bad_fcs_asserted.next = 0 - source_queue.put(axis_frame1) - source_queue.put(axis_frame2) + source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) yield clk.posedge yield clk.posedge diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index 9629c9fab..124309eff 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -190,8 +190,10 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() + assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(bytearray(rx_frame)) + eth_frame.parse_axis_fcs(rx_frame[8:]) print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) @@ -243,8 +245,10 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() + assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(bytearray(rx_frame)) + eth_frame.parse_axis_fcs(rx_frame[8:]) print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) @@ -260,8 +264,10 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() + assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(bytearray(rx_frame)) + eth_frame.parse_axis_fcs(rx_frame[8:]) print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) @@ -315,14 +321,18 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() + assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + # bad packet rx_frame = None if not sink_queue.empty(): rx_frame = sink_queue.get() + assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(bytearray(rx_frame)) + eth_frame.parse_axis_fcs(rx_frame[8:]) print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) From 263891b3f644e3b714dd1f0a2fd69d47f01108f1 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 4 Mar 2015 00:31:41 -0800 Subject: [PATCH 168/617] Make sure all paths set state_next --- rtl/axis_eth_fcs_check.v | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v index 434e204e0..bc6884047 100644 --- a/rtl/axis_eth_fcs_check.v +++ b/rtl/axis_eth_fcs_check.v @@ -150,6 +150,8 @@ always @* begin reset_crc = 0; update_crc = 1; state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_IDLE; end end else begin state_next = STATE_IDLE; From 17ad08e412aa699410c6f1732ffae45586577303 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 4 Mar 2015 00:33:26 -0800 Subject: [PATCH 169/617] Add 64-bit Ethernet FCS inserter --- rtl/axis_eth_fcs_insert_64.v | 636 ++++++++++++++++++++++++++ tb/test_axis_eth_fcs_insert_64.py | 399 ++++++++++++++++ tb/test_axis_eth_fcs_insert_64.v | 105 +++++ tb/test_axis_eth_fcs_insert_64_pad.py | 399 ++++++++++++++++ tb/test_axis_eth_fcs_insert_64_pad.v | 105 +++++ 5 files changed, 1644 insertions(+) create mode 100644 rtl/axis_eth_fcs_insert_64.v create mode 100755 tb/test_axis_eth_fcs_insert_64.py create mode 100644 tb/test_axis_eth_fcs_insert_64.v create mode 100755 tb/test_axis_eth_fcs_insert_64_pad.py create mode 100644 tb/test_axis_eth_fcs_insert_64_pad.v diff --git a/rtl/axis_eth_fcs_insert_64.v b/rtl/axis_eth_fcs_insert_64.v new file mode 100644 index 000000000..fa6553871 --- /dev/null +++ b/rtl/axis_eth_fcs_insert_64.v @@ -0,0 +1,636 @@ +/* + +Copyright (c) 2015 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 Ethernet FCS inserter (64 bit datapath) + */ +module axis_eth_fcs_insert_64 # +( + parameter ENABLE_PADDING = 0, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [63:0] input_axis_tdata, + input wire [7: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 [63:0] output_axis_tdata, + output wire [7: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 busy +); + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PAYLOAD = 2'd1, + STATE_PAD = 2'd2, + STATE_FCS = 2'd3; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg [63:0] input_axis_tdata_masked; + +reg [63:0] fcs_input_tdata; +reg [7:0] fcs_input_tkeep; + +reg [63:0] fcs_output_tdata_0; +reg [63:0] fcs_output_tdata_1; +reg [7:0] fcs_output_tkeep_0; +reg [7:0] fcs_output_tkeep_1; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [63:0] last_cycle_tdata_reg = 0, last_cycle_tdata_next; +reg [7:0] last_cycle_tkeep_reg = 0, last_cycle_tkeep_next; + +reg busy_reg = 0; + +reg input_axis_tready_reg = 0, input_axis_tready_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; +wire [31:0] crc_next4; +wire [31:0] crc_next5; +wire [31:0] crc_next6; +wire [31:0] crc_next7; + +// internal datapath +reg [63:0] output_axis_tdata_int; +reg [7:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +assign input_axis_tready = input_axis_tready_reg; + +assign busy = busy_reg; + +eth_crc_8 +eth_crc_8_inst ( + .data_in(fcs_input_tdata[7:0]), + .crc_state(crc_state), + .crc_next(crc_next0) +); + +eth_crc_16 +eth_crc_16_inst ( + .data_in(fcs_input_tdata[15:0]), + .crc_state(crc_state), + .crc_next(crc_next1) +); + +eth_crc_24 +eth_crc_24_inst ( + .data_in(fcs_input_tdata[23:0]), + .crc_state(crc_state), + .crc_next(crc_next2) +); + +eth_crc_32 +eth_crc_32_inst ( + .data_in(fcs_input_tdata[31:0]), + .crc_state(crc_state), + .crc_next(crc_next3) +); + +eth_crc_40 +eth_crc_40_inst ( + .data_in(fcs_input_tdata[39:0]), + .crc_state(crc_state), + .crc_next(crc_next4) +); + +eth_crc_48 +eth_crc_48_inst ( + .data_in(fcs_input_tdata[47:0]), + .crc_state(crc_state), + .crc_next(crc_next5) +); + +eth_crc_56 +eth_crc_56_inst ( + .data_in(fcs_input_tdata[55:0]), + .crc_state(crc_state), + .crc_next(crc_next6) +); + +eth_crc_64 +eth_crc_64_inst ( + .data_in(fcs_input_tdata[63:0]), + .crc_state(crc_state), + .crc_next(crc_next7) +); + +function [3:0] keep2count; + input [7:0] k; + case (k) + 8'b00000000: keep2count = 0; + 8'b00000001: keep2count = 1; + 8'b00000011: keep2count = 2; + 8'b00000111: keep2count = 3; + 8'b00001111: keep2count = 4; + 8'b00011111: keep2count = 5; + 8'b00111111: keep2count = 6; + 8'b01111111: keep2count = 7; + 8'b11111111: keep2count = 8; + endcase +endfunction + +function [7:0] count2keep; + input [3:0] k; + case (k) + 4'd0: count2keep = 8'b00000000; + 4'd1: count2keep = 8'b00000001; + 4'd2: count2keep = 8'b00000011; + 4'd3: count2keep = 8'b00000111; + 4'd4: count2keep = 8'b00001111; + 4'd5: count2keep = 8'b00011111; + 4'd6: count2keep = 8'b00111111; + 4'd7: count2keep = 8'b01111111; + 4'd8: count2keep = 8'b11111111; + endcase +endfunction + +// Mask input data +always @* begin + input_axis_tdata_masked[ 7: 0] = input_axis_tkeep[0] ? input_axis_tdata[ 7: 0] : 8'd0; + input_axis_tdata_masked[15: 8] = input_axis_tkeep[1] ? input_axis_tdata[15: 8] : 8'd0; + input_axis_tdata_masked[23:16] = input_axis_tkeep[2] ? input_axis_tdata[23:16] : 8'd0; + input_axis_tdata_masked[31:24] = input_axis_tkeep[3] ? input_axis_tdata[31:24] : 8'd0; + input_axis_tdata_masked[39:32] = input_axis_tkeep[4] ? input_axis_tdata[39:32] : 8'd0; + input_axis_tdata_masked[47:40] = input_axis_tkeep[5] ? input_axis_tdata[47:40] : 8'd0; + input_axis_tdata_masked[55:48] = input_axis_tkeep[6] ? input_axis_tdata[55:48] : 8'd0; + input_axis_tdata_masked[63:56] = input_axis_tkeep[7] ? input_axis_tdata[63:56] : 8'd0; +end + +// FCS cycle calculation +always @* begin + case (fcs_input_tkeep) + 8'b00000001: begin + fcs_output_tdata_0 = {24'd0, ~crc_next0[31:0], fcs_input_tdata[7:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b00011111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b00000011: begin + fcs_output_tdata_0 = {16'd0, ~crc_next1[31:0], fcs_input_tdata[15:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b00111111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b00000111: begin + fcs_output_tdata_0 = {8'd0, ~crc_next2[31:0], fcs_input_tdata[23:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b01111111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b00001111: begin + fcs_output_tdata_0 = {~crc_next3[31:0], fcs_input_tdata[31:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b11111111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b00011111: begin + fcs_output_tdata_0 = {~crc_next4[23:0], fcs_input_tdata[39:0]}; + fcs_output_tdata_1 = {56'd0, ~crc_next4[31:24]}; + fcs_output_tkeep_0 = 8'b11111111; + fcs_output_tkeep_1 = 8'b00000001; + end + 8'b00111111: begin + fcs_output_tdata_0 = {~crc_next5[15:0], fcs_input_tdata[47:0]}; + fcs_output_tdata_1 = {48'd0, ~crc_next5[31:16]}; + fcs_output_tkeep_0 = 8'b11111111; + fcs_output_tkeep_1 = 8'b00000011; + end + 8'b01111111: begin + fcs_output_tdata_0 = {~crc_next6[7:0], fcs_input_tdata[55:0]}; + fcs_output_tdata_1 = {40'd0, ~crc_next6[31:8]}; + fcs_output_tkeep_0 = 8'b11111111; + fcs_output_tkeep_1 = 8'b00000111; + end + 8'b11111111: begin + fcs_output_tdata_0 = fcs_input_tdata; + fcs_output_tdata_1 = {32'd0, ~crc_next7[31:0]}; + fcs_output_tkeep_0 = 8'b11111111; + fcs_output_tkeep_1 = 8'b00001111; + end + default: begin + fcs_output_tdata_0 = 0; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 0; + fcs_output_tkeep_1 = 0; + end + endcase +end + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 0; + update_crc = 0; + + frame_ptr_next = frame_ptr_reg; + + last_cycle_tdata_next = last_cycle_tdata_reg; + last_cycle_tkeep_next = last_cycle_tkeep_reg; + + input_axis_tready_next = 0; + + fcs_input_tdata = 0; + fcs_input_tkeep = 0; + + output_axis_tdata_int = 0; + output_axis_tkeep_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + input_axis_tready_next = output_axis_tready_int_early; + frame_ptr_next = 0; + reset_crc = 1; + + output_axis_tdata_int = input_axis_tdata_masked; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = input_axis_tvalid; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + fcs_input_tdata = input_axis_tdata_masked; + fcs_input_tkeep = input_axis_tkeep; + + if (input_axis_tready & input_axis_tvalid) begin + reset_crc = 0; + update_crc = 1; + frame_ptr_next = keep2count(input_axis_tkeep); + if (input_axis_tlast) begin + if (input_axis_tuser) begin + output_axis_tlast_int = 1; + output_axis_tuser_int = 1; + reset_crc = 1; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-4) begin + output_axis_tkeep_int = 8'hff; + fcs_input_tkeep = 8'hff; + frame_ptr_next = frame_ptr_reg + 8; + + if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin + input_axis_tready_next = 0; + state_next = STATE_PAD; + end else begin + output_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + fcs_input_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + + output_axis_tdata_int = fcs_output_tdata_0; + last_cycle_tdata_next = fcs_output_tdata_1; + output_axis_tkeep_int = fcs_output_tkeep_0; + last_cycle_tkeep_next = fcs_output_tkeep_1; + + reset_crc = 1; + + if (fcs_output_tkeep_1 == 0) begin + output_axis_tlast_int = 1; + input_axis_tready_next = output_axis_tready_int_early; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + input_axis_tready_next = 0; + state_next = STATE_FCS; + end + end + end else begin + output_axis_tdata_int = fcs_output_tdata_0; + last_cycle_tdata_next = fcs_output_tdata_1; + output_axis_tkeep_int = fcs_output_tkeep_0; + last_cycle_tkeep_next = fcs_output_tkeep_1; + + reset_crc = 1; + + if (fcs_output_tkeep_1 == 0) begin + output_axis_tlast_int = 1; + input_axis_tready_next = output_axis_tready_int_early; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + input_axis_tready_next = 0; + state_next = STATE_FCS; + end + end + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // transfer payload + input_axis_tready_next = output_axis_tready_int_early; + + output_axis_tdata_int = input_axis_tdata_masked; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = input_axis_tvalid; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + fcs_input_tdata = input_axis_tdata_masked; + fcs_input_tkeep = input_axis_tkeep; + + if (input_axis_tready & input_axis_tvalid) begin + update_crc = 1; + frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); + if (input_axis_tlast) begin + if (input_axis_tuser) begin + output_axis_tlast_int = 1; + output_axis_tuser_int = 1; + reset_crc = 1; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-4) begin + output_axis_tkeep_int = 8'hff; + fcs_input_tkeep = 8'hff; + frame_ptr_next = frame_ptr_reg + 8; + + if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin + input_axis_tready_next = 0; + state_next = STATE_PAD; + end else begin + output_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + fcs_input_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + + output_axis_tdata_int = fcs_output_tdata_0; + last_cycle_tdata_next = fcs_output_tdata_1; + output_axis_tkeep_int = fcs_output_tkeep_0; + last_cycle_tkeep_next = fcs_output_tkeep_1; + + reset_crc = 1; + + if (fcs_output_tkeep_1 == 0) begin + output_axis_tlast_int = 1; + input_axis_tready_next = output_axis_tready_int_early; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + input_axis_tready_next = 0; + state_next = STATE_FCS; + end + end + end else begin + output_axis_tdata_int = fcs_output_tdata_0; + last_cycle_tdata_next = fcs_output_tdata_1; + output_axis_tkeep_int = fcs_output_tkeep_0; + last_cycle_tkeep_next = fcs_output_tkeep_1; + + reset_crc = 1; + + if (fcs_output_tkeep_1 == 0) begin + output_axis_tlast_int = 1; + input_axis_tready_next = output_axis_tready_int_early; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + input_axis_tready_next = 0; + state_next = STATE_FCS; + end + end + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + state_next = STATE_PAYLOAD; + end + end + STATE_PAD: begin + input_axis_tready_next = 0; + + output_axis_tdata_int = 0; + output_axis_tkeep_int = 8'hff; + output_axis_tvalid_int = 1; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + fcs_input_tdata = 0; + fcs_input_tkeep = 8'hff; + + if (output_axis_tready_int) begin + update_crc = 1; + frame_ptr_next = frame_ptr_reg + 8; + + if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin + state_next = STATE_PAD; + end else begin + output_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + fcs_input_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + + output_axis_tdata_int = fcs_output_tdata_0; + last_cycle_tdata_next = fcs_output_tdata_1; + output_axis_tkeep_int = fcs_output_tkeep_0; + last_cycle_tkeep_next = fcs_output_tkeep_1; + + reset_crc = 1; + + if (fcs_output_tkeep_1 == 0) begin + output_axis_tlast_int = 1; + input_axis_tready_next = output_axis_tready_int_early; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + input_axis_tready_next = 0; + state_next = STATE_FCS; + end + end + end else begin + state_next = STATE_PAD; + end + end + STATE_FCS: begin + // last cycle + input_axis_tready_next = 0; + + output_axis_tdata_int = last_cycle_tdata_reg; + output_axis_tkeep_int = last_cycle_tkeep_reg; + output_axis_tvalid_int = 1; + output_axis_tlast_int = 1; + output_axis_tuser_int = 0; + + if (output_axis_tready_int) begin + reset_crc = 1; + input_axis_tready_next = output_axis_tready_int_early; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + state_next = STATE_FCS; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 0; + + last_cycle_tdata_reg <= 0; + last_cycle_tkeep_reg <= 0; + + input_axis_tready_reg <= 0; + + busy_reg <= 0; + + crc_state <= 32'hFFFFFFFF; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + last_cycle_tdata_reg <= last_cycle_tdata_next; + last_cycle_tkeep_reg <= last_cycle_tkeep_next; + + input_axis_tready_reg <= input_axis_tready_next; + + busy_reg <= state_next != STATE_IDLE; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next7; + end + end +end + +// output datapath logic +reg [63:0] output_axis_tdata_reg = 0; +reg [7:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [63:0] temp_axis_tdata_reg = 0; +reg [7:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_axis_eth_fcs_insert_64.py b/tb/test_axis_eth_fcs_insert_64.py new file mode 100755 index 000000000..b684ac0f9 --- /dev/null +++ b/tb/test_axis_eth_fcs_insert_64.py @@ -0,0 +1,399 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep + +module = 'axis_eth_fcs_insert_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/eth_crc_16.v") +srcs.append("../rtl/eth_crc_24.v") +srcs.append("../rtl/eth_crc_32.v") +srcs.append("../rtl/eth_crc_40.v") +srcs.append("../rtl/eth_crc_48.v") +srcs.append("../rtl/eth_crc_56.v") +srcs.append("../rtl/eth_crc_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_eth_fcs_insert_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, + + busy): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_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, + + busy=busy) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # 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)) + busy = 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_eth_fcs_insert_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, + + busy) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(40,58)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert eth_frame.payload.data == test_frame.payload.data + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert eth_frame.payload.data == test_frame1.payload.data + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame1.eth_src_mac + assert eth_frame.eth_type == test_frame1.eth_type + assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert eth_frame.payload.data == test_frame2.payload.data + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert eth_frame.payload.data == test_frame2.payload.data + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_eth_fcs_insert_64.v b/tb/test_axis_eth_fcs_insert_64.v new file mode 100644 index 000000000..3f7e8d893 --- /dev/null +++ b/tb/test_axis_eth_fcs_insert_64.v @@ -0,0 +1,105 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for axis_eth_fcs_insert_64 + */ +module test_axis_eth_fcs_insert_64; + +// Parameters +parameter ENABLE_PADDING = 0; +parameter MIN_FRAME_LENGTH = 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 busy; + +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, + busy); + + // dump file + $dumpfile("test_axis_eth_fcs_insert_64.lxt"); + $dumpvars(0, test_axis_eth_fcs_insert_64); +end + +axis_eth_fcs_insert_64 #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .clk(clk), + .rst(rst), + .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), + .busy(busy) +); + +endmodule diff --git a/tb/test_axis_eth_fcs_insert_64_pad.py b/tb/test_axis_eth_fcs_insert_64_pad.py new file mode 100755 index 000000000..c4983a42a --- /dev/null +++ b/tb/test_axis_eth_fcs_insert_64_pad.py @@ -0,0 +1,399 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2015 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 eth_ep + +module = 'axis_eth_fcs_insert_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/eth_crc_16.v") +srcs.append("../rtl/eth_crc_24.v") +srcs.append("../rtl/eth_crc_32.v") +srcs.append("../rtl/eth_crc_40.v") +srcs.append("../rtl/eth_crc_48.v") +srcs.append("../rtl/eth_crc_56.v") +srcs.append("../rtl/eth_crc_64.v") +srcs.append("test_%s_pad.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_eth_fcs_insert_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, + + busy): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_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, + + busy=busy) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # 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)) + busy = 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_eth_fcs_insert_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, + + busy) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(40,58)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame1.eth_src_mac + assert eth_frame.eth_type == test_frame1.eth_type + assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_eth_fcs_insert_64_pad.v b/tb/test_axis_eth_fcs_insert_64_pad.v new file mode 100644 index 000000000..2defab0fc --- /dev/null +++ b/tb/test_axis_eth_fcs_insert_64_pad.v @@ -0,0 +1,105 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for axis_eth_fcs_insert_64 + */ +module test_axis_eth_fcs_insert_64_pad; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 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 busy; + +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, + busy); + + // dump file + $dumpfile("test_axis_eth_fcs_insert_64_pad.lxt"); + $dumpvars(0, test_axis_eth_fcs_insert_64_pad); +end + +axis_eth_fcs_insert_64 #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .clk(clk), + .rst(rst), + .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), + .busy(busy) +); + +endmodule From 8ba6cf00d620f11b5b526e5f02d82e154861ddbe Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 4 Mar 2015 12:58:22 -0800 Subject: [PATCH 170/617] Test very short packets --- tb/test_axis_eth_fcs_insert.py | 38 ++++++++++++++++++++++++++ tb/test_axis_eth_fcs_insert_64.py | 38 ++++++++++++++++++++++++++ tb/test_axis_eth_fcs_insert_64_pad.py | 39 +++++++++++++++++++++++++++ tb/test_axis_eth_fcs_insert_pad.py | 39 +++++++++++++++++++++++++++ 4 files changed, 154 insertions(+) diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index be271d576..db4cb1667 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -26,6 +26,8 @@ THE SOFTWARE. from myhdl import * import os from Queue import Queue +import struct +import zlib import axis_ep import eth_ep @@ -369,6 +371,42 @@ def bench(): yield delay(100) + for payload_len in list(range(1,18)): + yield clk.posedge + print("test 4: test short packet, length %d" % payload_len) + current_test.next = 4 + + test_frame = bytearray(range(payload_len)) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + payload = rx_frame.data[:-4] + fcs = struct.unpack(' Date: Wed, 4 Mar 2015 13:06:29 -0800 Subject: [PATCH 171/617] Properly handle short packets --- rtl/axis_eth_fcs_check.v | 15 ++++++++++++++- tb/test_axis_eth_fcs_check.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v index bc6884047..5b5ee4176 100644 --- a/rtl/axis_eth_fcs_check.v +++ b/rtl/axis_eth_fcs_check.v @@ -149,7 +149,20 @@ always @* begin frame_ptr_next = 1; reset_crc = 0; update_crc = 1; - state_next = STATE_PAYLOAD; + if (input_axis_tlast) begin + shift_reset = 1; + reset_crc = 1; + output_axis_tlast_int = 1; + output_axis_tuser_int = input_axis_tuser; + if ({input_axis_tdata, input_axis_tdata_d0, input_axis_tdata_d1, input_axis_tdata_d2} != ~crc_next) begin + output_axis_tuser_int = 1; + error_bad_fcs_next = 1; + end + input_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_IDLE; + end else begin + state_next = STATE_PAYLOAD; + end end else begin state_next = STATE_IDLE; end diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index 89d623f5e..c2e108410 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -26,6 +26,8 @@ THE SOFTWARE. from myhdl import * import os from Queue import Queue +import struct +import zlib import axis_ep import eth_ep @@ -414,6 +416,36 @@ def bench(): yield delay(100) + for payload_len in list(range(1,18)): + yield clk.posedge + print("test 5: test short packet, length %d" % payload_len) + current_test.next = 5 + + test_frame = bytearray(range(payload_len)) + fcs = zlib.crc32(bytes(test_frame)) & 0xffffffff + test_frame_fcs = test_frame + struct.pack(' Date: Mon, 9 Mar 2015 02:38:39 -0700 Subject: [PATCH 172/617] Remove z from default states for FSM inference --- rtl/arp_eth_rx.v | 2 +- rtl/arp_eth_rx_64.v | 2 +- rtl/arp_eth_tx.v | 2 +- rtl/arp_eth_tx_64.v | 2 +- rtl/eth_axis_rx.v | 2 +- rtl/eth_axis_rx_64.v | 2 +- rtl/eth_axis_tx.v | 2 +- rtl/eth_axis_tx_64.v | 2 +- rtl/ip.v | 2 +- rtl/ip_64.v | 2 +- rtl/ip_eth_rx.v | 2 +- rtl/ip_eth_rx_64.v | 2 +- rtl/ip_eth_tx.v | 2 +- rtl/ip_eth_tx_64.v | 2 +- rtl/udp_ip_rx.v | 2 +- rtl/udp_ip_rx_64.v | 2 +- rtl/udp_ip_tx.v | 2 +- rtl/udp_ip_tx_64.v | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index 75961cbe4..2223b40a5 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -181,7 +181,7 @@ assign error_header_early_termination = error_header_early_termination_reg; assign error_invalid_header = error_invalid_header_reg; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_eth_hdr_ready_next = 0; input_eth_payload_tready_next = 0; diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index 7a56c52c9..d02163408 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -158,7 +158,7 @@ assign error_header_early_termination = error_header_early_termination_reg; assign error_invalid_header = error_invalid_header_reg; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_eth_hdr_ready_next = 0; input_eth_payload_tready_next = 0; diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index f12475bc1..30d620a55 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -139,7 +139,7 @@ assign output_eth_type = output_eth_type_reg; assign busy = busy_reg; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_frame_ready_next = 0; diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index 5b49ea1e9..4a6a2d913 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -141,7 +141,7 @@ assign output_eth_type = output_eth_type_reg; assign busy = busy_reg; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_frame_ready_next = 0; diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index 5a795e141..a962b42a4 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -133,7 +133,7 @@ assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_axis_tready_next = 0; diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index 3fb2d3b66..230bd2b28 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -162,7 +162,7 @@ always @* begin end always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_axis_tready_next = 0; diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index c420d2029..f62c07939 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -113,7 +113,7 @@ assign input_eth_payload_tready = input_eth_payload_tready_reg; assign busy = busy_reg; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_eth_hdr_ready_next = 0; input_eth_payload_tready_next = 0; diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index 5b351f027..32906e230 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -155,7 +155,7 @@ always @* begin end always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_eth_hdr_ready_next = 0; input_eth_payload_tready_next = 0; diff --git a/rtl/ip.v b/rtl/ip.v index 67328486d..d0a0d8236 100644 --- a/rtl/ip.v +++ b/rtl/ip.v @@ -253,7 +253,7 @@ assign arp_request_ip = input_ip_dest_ip; assign tx_error_arp_failed = arp_response_error; always @* begin - state_next = 8'bz; + state_next = STATE_IDLE; arp_request_valid_next = 0; drop_packet_next = 0; diff --git a/rtl/ip_64.v b/rtl/ip_64.v index b7ed26b80..126b0e9d3 100644 --- a/rtl/ip_64.v +++ b/rtl/ip_64.v @@ -262,7 +262,7 @@ assign arp_request_ip = input_ip_dest_ip; assign tx_error_arp_failed = arp_response_error; always @* begin - state_next = 8'bz; + state_next = STATE_IDLE; arp_request_valid_next = 0; drop_packet_next = 0; diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index 0d95789f9..237202ce6 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -227,7 +227,7 @@ function [15:0] add1c16b; endfunction always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_eth_hdr_ready_next = 0; input_eth_payload_tready_next = 0; diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index ca2cfaa10..e0e4b9cb2 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -276,7 +276,7 @@ always @* begin end always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; flush_save = 0; transfer_in_save = 0; diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 73bf5ca59..0bbe2d314 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -180,7 +180,7 @@ function [15:0] add1c16b; endfunction always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_ip_hdr_ready_next = 0; input_ip_payload_tready_next = 0; diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 2d72eb599..9f6e0c803 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -245,7 +245,7 @@ always @* begin end always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_ip_hdr_ready_next = 0; input_ip_payload_tready_next = 0; diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v index b03b05ed6..99bd176e9 100644 --- a/rtl/udp_ip_rx.v +++ b/rtl/udp_ip_rx.v @@ -229,7 +229,7 @@ assign error_header_early_termination = error_header_early_termination_reg; assign error_payload_early_termination = error_payload_early_termination_reg; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_ip_hdr_ready_next = 0; input_ip_payload_tready_next = 0; diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index 63dda8413..b0671a635 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -256,7 +256,7 @@ function [7:0] count2keep; endfunction always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_ip_hdr_ready_next = 0; input_ip_payload_tready_next = 0; diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index 059227f3f..d2c83cb01 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -213,7 +213,7 @@ assign busy = busy_reg; assign error_payload_early_termination = error_payload_early_termination_reg; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_udp_hdr_ready_next = 0; input_udp_payload_tready_next = 0; diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index 0dc083dab..ef660eebe 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -247,7 +247,7 @@ function [7:0] count2keep; endfunction always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; input_udp_hdr_ready_next = 0; input_udp_payload_tready_next = 0; From 3138795899fc3eb884fc6f61f77e285ac2f4e82f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 02:55:30 -0700 Subject: [PATCH 173/617] Fix rate limiter testbenches --- tb/test_axis_rate_limit.py | 4 ++-- tb/test_axis_rate_limit_64.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index b9f0ff420..8cdbf84cb 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -505,8 +505,8 @@ def bench(): assert byte_count == sum(len(f.data) for f in test_frame) assert frame_count == len(test_frame) - test_rate = 1.0 * rate_num / rate_denom - meas_rate = 1.0 * byte_count / tick_count + test_rate = float(rate_num) / float(rate_denom) + meas_rate = float(byte_count) / float(tick_count) error = (test_rate - meas_rate) / test_rate print("test rate %f" % test_rate) diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index acfc3c7a1..d2f3e872f 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -515,8 +515,8 @@ def bench(): assert byte_count == sum(len(f.data) for f in test_frame) assert frame_count == len(test_frame) - test_rate = 1.0 * rate_num / rate_denom - meas_rate = 1.0 * byte_count / tick_count + test_rate = float(rate_num) / float(rate_denom) + meas_rate = float(byte_count) / float(tick_count) error = (test_rate - meas_rate) / test_rate print("test rate %f" % test_rate) From 4981d7cacdf80681c0fda348efe0703503282af6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 02:56:17 -0700 Subject: [PATCH 174/617] Update MyHDL repo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4dcbbcf7b..8527dee99 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ before_install: - export d=`pwd` - sudo apt-get update -qq - sudo apt-get install -y iverilog - - hg clone https://bitbucket.org/alexforencich/myhdl + - git clone https://github.com/jandecaluwe/myhdl.git - 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 From 54bfdaa8c09aabd2242d73d00f990d50b8d59eb2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 03:19:43 -0700 Subject: [PATCH 175/617] Cast WL to int --- tb/axis_ep.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index f55e08a10..f1fc25b9b 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -147,7 +147,7 @@ def AXIStreamSource(clk, rst, b = False if tkeep is not None: M = len(tkeep) - WL = (len(tdata)+M-1)/M + WL = int((len(tdata)+M-1)/M) if WL == 8: b = True @@ -219,7 +219,7 @@ def AXIStreamSink(clk, rst, M = 1 b = False M = len(tkeep) - WL = (len(tdata)+M-1)/M + WL = int((len(tdata)+M-1)/M) if WL == 8: b = True From 02a7f4d5ed9dbc021fe49cd29d0aa06d7c34055d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 03:32:19 -0700 Subject: [PATCH 176/617] Update testbenches to python 3 --- tb/test_arbiter.py | 17 +++-- tb/test_arbiter_rr.py | 22 ++++-- tb/test_axis_adapter_64_8.py | 38 +++++----- tb/test_axis_adapter_8_64.py | 38 +++++----- tb/test_axis_arb_mux_4.py | 104 +++++++++++++++------------- tb/test_axis_arb_mux_64_4.py | 104 +++++++++++++++------------- tb/test_axis_async_fifo.py | 86 ++++++++++++----------- tb/test_axis_async_fifo_64.py | 84 +++++++++++----------- tb/test_axis_async_frame_fifo.py | 92 ++++++++++++------------ tb/test_axis_async_frame_fifo_64.py | 90 ++++++++++++------------ tb/test_axis_crosspoint_4x4.py | 26 ++++--- tb/test_axis_crosspoint_64_4x4.py | 26 ++++--- tb/test_axis_demux_4.py | 88 ++++++++++++----------- tb/test_axis_demux_64_4.py | 88 ++++++++++++----------- tb/test_axis_fifo.py | 86 ++++++++++++----------- tb/test_axis_fifo_64.py | 84 +++++++++++----------- tb/test_axis_frame_fifo.py | 92 ++++++++++++------------ tb/test_axis_frame_fifo_64.py | 90 ++++++++++++------------ tb/test_axis_frame_join_4.py | 88 ++++++++++++----------- tb/test_axis_ll_bridge.py | 40 ++++++----- tb/test_axis_mux_4.py | 88 ++++++++++++----------- tb/test_axis_mux_64_4.py | 88 ++++++++++++----------- tb/test_axis_rate_limit.py | 90 ++++++++++++------------ tb/test_axis_rate_limit_64.py | 90 ++++++++++++------------ tb/test_axis_register.py | 86 ++++++++++++----------- tb/test_axis_register_64.py | 84 +++++++++++----------- tb/test_axis_srl_fifo.py | 86 ++++++++++++----------- tb/test_axis_srl_fifo_64.py | 84 +++++++++++----------- tb/test_axis_srl_register.py | 86 ++++++++++++----------- tb/test_axis_srl_register_64.py | 84 +++++++++++----------- tb/test_axis_stat_counter.py | 88 ++++++++++++----------- tb/test_ll_axis_bridge.py | 40 ++++++----- tb/test_priority_encoder.py | 2 +- 33 files changed, 1260 insertions(+), 1119 deletions(-) diff --git a/tb/test_arbiter.py b/tb/test_arbiter.py index 6d85b1a93..3ed18d8e8 100755 --- a/tb/test_arbiter.py +++ b/tb/test_arbiter.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -114,7 +114,10 @@ def bench(): for i in range(32): l = [i] - request.next = reduce(lambda x, y: x|y, [1< Date: Sat, 21 Mar 2015 03:32:42 -0700 Subject: [PATCH 177/617] Test with python 3 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8527dee99..ef2066076 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: python python: - - "2.7" + - "3.3" virtualenv: system_site_packages: true before_install: From 7b991bfe0eadea0a733dff0fc53e0a539e88d2ee Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 03:35:42 -0700 Subject: [PATCH 178/617] Update AXI stream endpoint to support multiple tdata signals --- tb/axis_ep.py | 137 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 42 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index f1fc25b9b..036c47541 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -26,6 +26,7 @@ from myhdl import * class AXIStreamFrame(object): def __init__(self, data=b'', keep=None, user=None): + self.B = 0 self.N = 8 self.M = 1 self.WL = 8 @@ -35,10 +36,13 @@ class AXIStreamFrame(object): if type(data) is bytes or type(data) is bytearray: self.data = bytearray(data) - if type(data) is AXIStreamFrame: + elif type(data) is AXIStreamFrame: self.N = data.N self.WL = data.WL - self.data = bytearray(data.data) + if type(data.data) is bytearray: + self.data = bytearray(data.data) + else: + self.data = list(data.data) if data.keep is not None: self.keep = list(data.keep) if data.user is not None: @@ -46,6 +50,8 @@ class AXIStreamFrame(object): self.user = data.user else: self.user = list(data.user) + else: + self.data = list(data) def build(self): if self.data is None: @@ -62,23 +68,35 @@ class AXIStreamFrame(object): assert_tuser = True self.user = None - while len(f) > 0: - data = 0 - keep = 0 - for j in range(self.M): - data = data | (f.pop(0) << (j*self.WL)) - keep = keep | (1 << j) - if len(f) == 0: break - tdata.append(data) - if self.keep is None: - tkeep.append(keep) - else: - tkeep.append(self.keep[i]) - if self.user is None: - tuser.append(0) - else: - tuser.append(self.user[i]) - i += 1 + if self.B == 0: + while len(f) > 0: + data = 0 + keep = 0 + for j in range(self.M): + data = data | (f.pop(0) << (j*self.WL)) + keep = keep | (1 << j) + if len(f) == 0: break + tdata.append(data) + if self.keep is None: + tkeep.append(keep) + else: + tkeep.append(self.keep[i]) + if self.user is None: + tuser.append(0) + else: + tuser.append(self.user[i]) + i += 1 + else: + # multiple tdata signals + while len(f) > 0: + data = 0 + tdata.append(f.pop(0)) + tkeep.append(0) + if self.user is None: + tuser.append(0) + else: + tuser.append(self.user[i]) + i += 1 if assert_tuser: tuser[-1] = 1 @@ -95,14 +113,21 @@ class AXIStreamFrame(object): self.data = [] self.keep = [] self.user = [] - mask = 2**self.WL-1 - for i in range(len(tdata)): - for j in range(self.M): - if tkeep[i] & (1 << j): - self.data.append((tdata[i] >> (j*self.WL)) & mask) - self.keep.append(tkeep[i]) - self.user.append(tuser[i]) + if self.B == 0: + mask = 2**self.WL-1 + + for i in range(len(tdata)): + for j in range(self.M): + if tkeep[i] & (1 << j): + self.data.append((tdata[i] >> (j*self.WL)) & mask) + self.keep.append(tkeep[i]) + self.user.append(tuser[i]) + else: + for i in range(len(tdata)): + self.data.append(tdata[i]) + self.keep.append(tkeep[i]) + self.user.append(tuser[i]) if self.WL == 8: self.data = bytearray(self.data) @@ -142,27 +167,39 @@ def AXIStreamSource(clk, rst, data = [] keep = [] user = [] + B = 0 N = len(tdata) - M = 1 - b = False - if tkeep is not None: - M = len(tkeep) + M = len(tkeep) WL = int((len(tdata)+M-1)/M) - if WL == 8: - b = True + + if type(tdata) is list or type(tdata) is tuple: + # multiple tdata signals + B = len(tdata) + N = [len(b) for b in tdata] + M = 1 + WL = [1]*B while True: yield clk.posedge, rst.posedge if rst: - tdata.next = 0 + if B > 0: + for s in tdata: + s.next = 0 + else: + tdata.next = 0 tkeep.next = 0 tvalid_int.next = False tlast.next = False else: if tready_int and tvalid: if len(data) > 0: - tdata.next = data.pop(0) + if B > 0: + l = data.pop(0) + for i in range(B): + tdata[i].next = l[i] + else: + tdata.next = data.pop(0) tkeep.next = keep.pop(0) tuser.next = user.pop(0) tvalid_int.next = True @@ -174,14 +211,19 @@ def AXIStreamSource(clk, rst, if not fifo.empty(): frame = fifo.get() frame = AXIStreamFrame(frame) + frame.B = B frame.N = N frame.M = M frame.WL = WL - frame.build() + data, keep, user = frame.build() if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) - data, keep, user = frame.build() - tdata.next = data.pop(0) + if B > 0: + l = data.pop(0) + for i in range(B): + tdata[i].next = l[i] + else: + tdata.next = data.pop(0) tkeep.next = keep.pop(0) tuser.next = user.pop(0) tvalid_int.next = True @@ -215,13 +257,17 @@ def AXIStreamSink(clk, rst, data = [] keep = [] user = [] + B = 0 N = len(tdata) - M = 1 - b = False M = len(tkeep) WL = int((len(tdata)+M-1)/M) - if WL == 8: - b = True + + if type(tdata) is list or type(tdata) is tuple: + # multiple tdata signals + B = len(tdata) + N = [len(b) for b in tdata] + M = 1 + WL = [1]*B while True: yield clk.posedge, rst.posedge @@ -236,10 +282,17 @@ def AXIStreamSink(clk, rst, tready_int.next = True if tvalid_int: - data.append(int(tdata)) + if B > 0: + l = [] + for i in range(B): + l.append(int(tdata[i])) + data.append(l) + else: + data.append(int(tdata)) keep.append(int(tkeep)) user.append(int(tuser)) if tlast: + frame.B = B frame.N = N frame.M = M frame.WL = WL From d00471352f8d3ae01a1fe9ed2abe4c1826a4af33 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 04:24:52 -0700 Subject: [PATCH 179/617] Update .travis.yml --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ef2066076..e746f291b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ language: python python: - "3.3" -virtualenv: - system_site_packages: true before_install: - export d=`pwd` - sudo apt-get update -qq From d9c41d43f000bc2d14535533f24275db99b1b5ff Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 04:28:53 -0700 Subject: [PATCH 180/617] Update .travis.yml --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e746f291b..22c486ffe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ language: python python: - - "3.3" + - "3.2" +virtualenv: + system_site_packages: true before_install: - export d=`pwd` - sudo apt-get update -qq From 6bd28aa128d436f65ad2c8405a3914054b875422 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 04:36:54 -0700 Subject: [PATCH 181/617] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 22c486ffe..e9bc0a451 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ before_install: - sudo apt-get update -qq - sudo apt-get install -y iverilog - git clone https://github.com/jandecaluwe/myhdl.git - - cd $d/myhdl && sudo python setup.py install + - cd $d/myhdl && sudo python3 setup.py install - cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/ivl/myhdl.vpi - cd $d script: From 646ad2a2932f08f5782a3917f36a2c5773af5067 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 04:39:27 -0700 Subject: [PATCH 182/617] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e9bc0a451..653d3ff67 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: python python: - - "3.2" + - "3.4" virtualenv: system_site_packages: true before_install: From 684f6967e57d29aa05a285a69202a71c262ee887 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 04:40:57 -0700 Subject: [PATCH 183/617] Update .travis.yml --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 653d3ff67..42f17a017 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ language: python python: - "3.4" -virtualenv: - system_site_packages: true before_install: - export d=`pwd` - sudo apt-get update -qq From eb9f7c13f1119de469b4319cd2353d97ae5e676d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 04:47:21 -0700 Subject: [PATCH 184/617] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 42f17a017..f410aec44 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ before_install: - sudo apt-get update -qq - sudo apt-get install -y iverilog - git clone https://github.com/jandecaluwe/myhdl.git - - cd $d/myhdl && sudo python3 setup.py install + - cd $d/myhdl && sudo python3.4 setup.py install - cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/ivl/myhdl.vpi - cd $d script: From 8cd0d3ee06ed7a84ec57f166cbad618f44b81589 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 04:49:43 -0700 Subject: [PATCH 185/617] Update .travis.yml --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f410aec44..394066aff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,11 @@ python: - "3.4" before_install: - export d=`pwd` + - export PYTHON_EXE=`which python` - sudo apt-get update -qq - sudo apt-get install -y iverilog - git clone https://github.com/jandecaluwe/myhdl.git - - cd $d/myhdl && sudo python3.4 setup.py install + - cd $d/myhdl && sudo $PYTHON_EXE setup.py install - cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/ivl/myhdl.vpi - cd $d script: From 101d963c0994da57da4b858219da40df31fb912d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 21:44:16 -0700 Subject: [PATCH 186/617] Update AXI stream endpoint --- tb/axis_ep.py | 141 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 44 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index f55e08a10..036c47541 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -26,6 +26,7 @@ from myhdl import * class AXIStreamFrame(object): def __init__(self, data=b'', keep=None, user=None): + self.B = 0 self.N = 8 self.M = 1 self.WL = 8 @@ -35,10 +36,13 @@ class AXIStreamFrame(object): if type(data) is bytes or type(data) is bytearray: self.data = bytearray(data) - if type(data) is AXIStreamFrame: + elif type(data) is AXIStreamFrame: self.N = data.N self.WL = data.WL - self.data = bytearray(data.data) + if type(data.data) is bytearray: + self.data = bytearray(data.data) + else: + self.data = list(data.data) if data.keep is not None: self.keep = list(data.keep) if data.user is not None: @@ -46,6 +50,8 @@ class AXIStreamFrame(object): self.user = data.user else: self.user = list(data.user) + else: + self.data = list(data) def build(self): if self.data is None: @@ -62,23 +68,35 @@ class AXIStreamFrame(object): assert_tuser = True self.user = None - while len(f) > 0: - data = 0 - keep = 0 - for j in range(self.M): - data = data | (f.pop(0) << (j*self.WL)) - keep = keep | (1 << j) - if len(f) == 0: break - tdata.append(data) - if self.keep is None: - tkeep.append(keep) - else: - tkeep.append(self.keep[i]) - if self.user is None: - tuser.append(0) - else: - tuser.append(self.user[i]) - i += 1 + if self.B == 0: + while len(f) > 0: + data = 0 + keep = 0 + for j in range(self.M): + data = data | (f.pop(0) << (j*self.WL)) + keep = keep | (1 << j) + if len(f) == 0: break + tdata.append(data) + if self.keep is None: + tkeep.append(keep) + else: + tkeep.append(self.keep[i]) + if self.user is None: + tuser.append(0) + else: + tuser.append(self.user[i]) + i += 1 + else: + # multiple tdata signals + while len(f) > 0: + data = 0 + tdata.append(f.pop(0)) + tkeep.append(0) + if self.user is None: + tuser.append(0) + else: + tuser.append(self.user[i]) + i += 1 if assert_tuser: tuser[-1] = 1 @@ -95,14 +113,21 @@ class AXIStreamFrame(object): self.data = [] self.keep = [] self.user = [] - mask = 2**self.WL-1 - for i in range(len(tdata)): - for j in range(self.M): - if tkeep[i] & (1 << j): - self.data.append((tdata[i] >> (j*self.WL)) & mask) - self.keep.append(tkeep[i]) - self.user.append(tuser[i]) + if self.B == 0: + mask = 2**self.WL-1 + + for i in range(len(tdata)): + for j in range(self.M): + if tkeep[i] & (1 << j): + self.data.append((tdata[i] >> (j*self.WL)) & mask) + self.keep.append(tkeep[i]) + self.user.append(tuser[i]) + else: + for i in range(len(tdata)): + self.data.append(tdata[i]) + self.keep.append(tkeep[i]) + self.user.append(tuser[i]) if self.WL == 8: self.data = bytearray(self.data) @@ -142,27 +167,39 @@ def AXIStreamSource(clk, rst, data = [] keep = [] user = [] + B = 0 N = len(tdata) - M = 1 - b = False - if tkeep is not None: - M = len(tkeep) - WL = (len(tdata)+M-1)/M - if WL == 8: - b = True + M = len(tkeep) + WL = int((len(tdata)+M-1)/M) + + if type(tdata) is list or type(tdata) is tuple: + # multiple tdata signals + B = len(tdata) + N = [len(b) for b in tdata] + M = 1 + WL = [1]*B while True: yield clk.posedge, rst.posedge if rst: - tdata.next = 0 + if B > 0: + for s in tdata: + s.next = 0 + else: + tdata.next = 0 tkeep.next = 0 tvalid_int.next = False tlast.next = False else: if tready_int and tvalid: if len(data) > 0: - tdata.next = data.pop(0) + if B > 0: + l = data.pop(0) + for i in range(B): + tdata[i].next = l[i] + else: + tdata.next = data.pop(0) tkeep.next = keep.pop(0) tuser.next = user.pop(0) tvalid_int.next = True @@ -174,14 +211,19 @@ def AXIStreamSource(clk, rst, if not fifo.empty(): frame = fifo.get() frame = AXIStreamFrame(frame) + frame.B = B frame.N = N frame.M = M frame.WL = WL - frame.build() + data, keep, user = frame.build() if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) - data, keep, user = frame.build() - tdata.next = data.pop(0) + if B > 0: + l = data.pop(0) + for i in range(B): + tdata[i].next = l[i] + else: + tdata.next = data.pop(0) tkeep.next = keep.pop(0) tuser.next = user.pop(0) tvalid_int.next = True @@ -215,13 +257,17 @@ def AXIStreamSink(clk, rst, data = [] keep = [] user = [] + B = 0 N = len(tdata) - M = 1 - b = False M = len(tkeep) - WL = (len(tdata)+M-1)/M - if WL == 8: - b = True + WL = int((len(tdata)+M-1)/M) + + if type(tdata) is list or type(tdata) is tuple: + # multiple tdata signals + B = len(tdata) + N = [len(b) for b in tdata] + M = 1 + WL = [1]*B while True: yield clk.posedge, rst.posedge @@ -236,10 +282,17 @@ def AXIStreamSink(clk, rst, tready_int.next = True if tvalid_int: - data.append(int(tdata)) + if B > 0: + l = [] + for i in range(B): + l.append(int(tdata[i])) + data.append(l) + else: + data.append(int(tdata)) keep.append(int(tkeep)) user.append(int(tuser)) if tlast: + frame.B = B frame.N = N frame.M = M frame.WL = WL From 5a4b480c7eb240dec7ac79de777120dedc74c757 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 22:31:01 -0700 Subject: [PATCH 187/617] Update testbenches for python 3 --- tb/arp_ep.py | 10 +++++++--- tb/eth_ep.py | 10 +++++++--- tb/gmii_ep.py | 2 +- tb/ip_ep.py | 10 +++++++--- tb/test_arp.py | 8 ++++++-- tb/test_arp_64.py | 8 ++++++-- tb/test_arp_cache.py | 2 +- tb/test_arp_eth_rx.py | 8 ++++++-- tb/test_arp_eth_rx_64.py | 8 ++++++-- tb/test_arp_eth_tx.py | 8 ++++++-- tb/test_arp_eth_tx_64.py | 8 ++++++-- tb/test_axis_eth_fcs.py | 8 ++++++-- tb/test_axis_eth_fcs_64.py | 8 ++++++-- tb/test_axis_eth_fcs_check.py | 8 ++++++-- tb/test_axis_eth_fcs_insert.py | 8 ++++++-- tb/test_axis_eth_fcs_insert_64.py | 8 ++++++-- tb/test_axis_eth_fcs_insert_64_pad.py | 8 ++++++-- tb/test_axis_eth_fcs_insert_pad.py | 8 ++++++-- tb/test_eth_arb_mux_4.py | 8 ++++++-- tb/test_eth_arb_mux_64_4.py | 8 ++++++-- tb/test_eth_axis_rx.py | 8 ++++++-- tb/test_eth_axis_rx_64.py | 8 ++++++-- tb/test_eth_axis_tx.py | 8 ++++++-- tb/test_eth_axis_tx_64.py | 8 ++++++-- tb/test_eth_demux_4.py | 8 ++++++-- tb/test_eth_demux_64_4.py | 8 ++++++-- tb/test_eth_mac_1g.py | 8 ++++++-- tb/test_eth_mac_1g_rx.py | 8 ++++++-- tb/test_eth_mac_1g_tx.py | 8 ++++++-- tb/test_eth_mux_4.py | 8 ++++++-- tb/test_eth_mux_64_4.py | 8 ++++++-- tb/test_ip.py | 8 ++++++-- tb/test_ip_64.py | 8 ++++++-- tb/test_ip_arb_mux_4.py | 8 ++++++-- tb/test_ip_arb_mux_64_4.py | 8 ++++++-- tb/test_ip_complete.py | 8 ++++++-- tb/test_ip_complete_64.py | 8 ++++++-- tb/test_ip_demux_4.py | 8 ++++++-- tb/test_ip_demux_64_4.py | 8 ++++++-- tb/test_ip_eth_rx.py | 8 ++++++-- tb/test_ip_eth_rx_64.py | 8 ++++++-- tb/test_ip_eth_tx.py | 8 ++++++-- tb/test_ip_eth_tx_64.py | 8 ++++++-- tb/test_ip_mux_4.py | 8 ++++++-- tb/test_ip_mux_64_4.py | 8 ++++++-- tb/test_udp.py | 8 ++++++-- tb/test_udp_64.py | 8 ++++++-- tb/test_udp_arb_mux_4.py | 8 ++++++-- tb/test_udp_arb_mux_64_4.py | 8 ++++++-- tb/test_udp_complete.py | 8 ++++++-- tb/test_udp_complete_64.py | 8 ++++++-- tb/test_udp_demux_4.py | 8 ++++++-- tb/test_udp_demux_64_4.py | 8 ++++++-- tb/test_udp_ip_rx.py | 8 ++++++-- tb/test_udp_ip_rx_64.py | 8 ++++++-- tb/test_udp_ip_tx.py | 8 ++++++-- tb/test_udp_ip_tx_64.py | 8 ++++++-- tb/test_udp_mux_4.py | 8 ++++++-- tb/test_udp_mux_64_4.py | 8 ++++++-- tb/udp_ep.py | 10 +++++++--- 60 files changed, 354 insertions(+), 122 deletions(-) diff --git a/tb/arp_ep.py b/tb/arp_ep.py index 8c296bf14..f7909637c 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -25,9 +25,13 @@ THE SOFTWARE. from myhdl import * import axis_ep import eth_ep -from Queue import Queue import struct +try: + from queue import Queue +except ImportError: + from Queue import Queue + class ARPFrame(object): def __init__(self, eth_dest_mac=0, @@ -116,9 +120,9 @@ class ARPFrame(object): self.arp_hlen = struct.unpack('B', data.payload.data[4:5])[0] self.arp_plen = struct.unpack('B', data.payload.data[5:6])[0] self.arp_oper = struct.unpack('>H', data.payload.data[6:8])[0] - self.arp_sha = struct.unpack('>Q', '\x00\x00'+data.payload.data[8:14])[0] + self.arp_sha = struct.unpack('>Q', b'\x00\x00'+data.payload.data[8:14])[0] self.arp_spa = struct.unpack('>L', data.payload.data[14:18])[0] - self.arp_tha = struct.unpack('>Q', '\x00\x00'+data.payload.data[18:24])[0] + self.arp_tha = struct.unpack('>Q', b'\x00\x00'+data.payload.data[18:24])[0] self.arp_tpa = struct.unpack('>L', data.payload.data[24:28])[0] def __eq__(self, other): diff --git a/tb/eth_ep.py b/tb/eth_ep.py index 260e765f3..185b1ac25 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -24,10 +24,14 @@ THE SOFTWARE. from myhdl import * import axis_ep -from Queue import Queue import struct import zlib +try: + from queue import Queue +except ImportError: + from Queue import Queue + class EthFrame(object): def __init__(self, payload=b'', eth_dest_mac=0, eth_src_mac=0, eth_type=0, eth_fcs=None): self._payload = axis_ep.AXIStreamFrame() @@ -92,8 +96,8 @@ class EthFrame(object): def parse_axis(self, data): data = axis_ep.AXIStreamFrame(data).data - self.eth_dest_mac = struct.unpack('>Q', '\x00\x00'+data[0:6])[0] - self.eth_src_mac = struct.unpack('>Q', '\x00\x00'+data[6:12])[0] + self.eth_dest_mac = struct.unpack('>Q', b'\x00\x00'+data[0:6])[0] + self.eth_src_mac = struct.unpack('>Q', b'\x00\x00'+data[6:12])[0] self.eth_type = struct.unpack('>H', data[12:14])[0] data = data[14:] self.payload = axis_ep.AXIStreamFrame(data) diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index 82123c2fe..a578b1500 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -55,7 +55,7 @@ def GMIISource(clk, rst, if len(frame) == 0: ifg_cnt = 12 elif not fifo.empty(): - frame = fifo.get() + frame = list(fifo.get()) if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) txd.next = frame.pop(0) diff --git a/tb/ip_ep.py b/tb/ip_ep.py index dbabe9a3b..46a63f17d 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -25,11 +25,15 @@ THE SOFTWARE. from myhdl import * import axis_ep import eth_ep -from Queue import Queue import struct +try: + from queue import Queue +except ImportError: + from Queue import Queue + class IPFrame(object): - def __init__(self, payload='', + def __init__(self, payload=b'', eth_dest_mac=0, eth_src_mac=0, eth_type=0, @@ -145,7 +149,7 @@ class IPFrame(object): def build_eth(self): self.build() - data = '' + data = b'' data += struct.pack('B', self.ip_version << 4 | self.ip_ihl) data += struct.pack('B', self.ip_dscp << 2 | self.ip_ecn) diff --git a/tb/test_arp.py b/tb/test_arp.py index 4a9e2f2d9..03e633aeb 100755 --- a/tb/test_arp.py +++ b/tb/test_arp.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import arp_ep diff --git a/tb/test_arp_64.py b/tb/test_arp_64.py index 8e93c2993..2a4b3626b 100755 --- a/tb/test_arp_64.py +++ b/tb/test_arp_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import arp_ep diff --git a/tb/test_arp_cache.py b/tb/test_arp_cache.py index a31451d44..537309e84 100755 --- a/tb/test_arp_cache.py +++ b/tb/test_arp_cache.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index ff7483098..01b457187 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import arp_ep import eth_ep diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index 23b01cbad..489ff043b 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import arp_ep import eth_ep diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py index 1d1c39e3e..417dc7100 100755 --- a/tb/test_arp_eth_tx.py +++ b/tb/test_arp_eth_tx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py index b4571d53d..f25965141 100755 --- a/tb/test_arp_eth_tx_64.py +++ b/tb/test_arp_eth_tx_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_axis_eth_fcs.py b/tb/test_axis_eth_fcs.py index 6899a6665..461859e5d 100755 --- a/tb/test_axis_eth_fcs.py +++ b/tb/test_axis_eth_fcs.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_axis_eth_fcs_64.py b/tb/test_axis_eth_fcs_64.py index 8b4fe0bbf..c74132b5c 100755 --- a/tb/test_axis_eth_fcs_64.py +++ b/tb/test_axis_eth_fcs_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index c2e108410..687605efd 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,10 +25,14 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue import struct import zlib +try: + from queue import Queue +except ImportError: + from Queue import Queue + import axis_ep import eth_ep diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index db4cb1667..6cd5ab452 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,10 +25,14 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue import struct import zlib +try: + from queue import Queue +except ImportError: + from Queue import Queue + import axis_ep import eth_ep diff --git a/tb/test_axis_eth_fcs_insert_64.py b/tb/test_axis_eth_fcs_insert_64.py index a80f9251e..7c723518c 100755 --- a/tb/test_axis_eth_fcs_insert_64.py +++ b/tb/test_axis_eth_fcs_insert_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,10 +25,14 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue import struct import zlib +try: + from queue import Queue +except ImportError: + from Queue import Queue + import axis_ep import eth_ep diff --git a/tb/test_axis_eth_fcs_insert_64_pad.py b/tb/test_axis_eth_fcs_insert_64_pad.py index c25275a5d..5215d82c4 100755 --- a/tb/test_axis_eth_fcs_insert_64_pad.py +++ b/tb/test_axis_eth_fcs_insert_64_pad.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,10 +25,14 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue import struct import zlib +try: + from queue import Queue +except ImportError: + from Queue import Queue + import axis_ep import eth_ep diff --git a/tb/test_axis_eth_fcs_insert_pad.py b/tb/test_axis_eth_fcs_insert_pad.py index dc99d0ef3..a6f122649 100755 --- a/tb/test_axis_eth_fcs_insert_pad.py +++ b/tb/test_axis_eth_fcs_insert_pad.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,10 +25,14 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue import struct import zlib +try: + from queue import Queue +except ImportError: + from Queue import Queue + import axis_ep import eth_ep diff --git a/tb/test_eth_arb_mux_4.py b/tb/test_eth_arb_mux_4.py index d3c086ef0..8c3216af8 100755 --- a/tb/test_eth_arb_mux_4.py +++ b/tb/test_eth_arb_mux_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep diff --git a/tb/test_eth_arb_mux_64_4.py b/tb/test_eth_arb_mux_64_4.py index 699276ce1..d9cd5524f 100755 --- a/tb/test_eth_arb_mux_64_4.py +++ b/tb/test_eth_arb_mux_64_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index 2f539f4fc..0914cefe3 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index f8cb1e9d5..1d11f45da 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py index d33a649af..090ce99a6 100755 --- a/tb/test_eth_axis_tx.py +++ b/tb/test_eth_axis_tx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py index c877a68a7..987549ee0 100755 --- a/tb/test_eth_axis_tx_64.py +++ b/tb/test_eth_axis_tx_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_eth_demux_4.py b/tb/test_eth_demux_4.py index b57963fac..8bda3a376 100755 --- a/tb/test_eth_demux_4.py +++ b/tb/test_eth_demux_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep diff --git a/tb/test_eth_demux_64_4.py b/tb/test_eth_demux_64_4.py index 199fb08a6..afe1cbe7d 100755 --- a/tb/test_eth_demux_64_4.py +++ b/tb/test_eth_demux_64_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index 9399be2de..a4b9da14b 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py index 71089f1d9..b15abdaec 100755 --- a/tb/test_eth_mac_1g_rx.py +++ b/tb/test_eth_mac_1g_rx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index 124309eff..e6fa9221e 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import axis_ep import eth_ep diff --git a/tb/test_eth_mux_4.py b/tb/test_eth_mux_4.py index add42f539..854b69992 100755 --- a/tb/test_eth_mux_4.py +++ b/tb/test_eth_mux_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep diff --git a/tb/test_eth_mux_64_4.py b/tb/test_eth_mux_64_4.py index e9a89bb5b..2c2b4757e 100755 --- a/tb/test_eth_mux_64_4.py +++ b/tb/test_eth_mux_64_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep diff --git a/tb/test_ip.py b/tb/test_ip.py index ff0f131a7..cab09c353 100755 --- a/tb/test_ip.py +++ b/tb/test_ip.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_ip_64.py b/tb/test_ip_64.py index e05227351..b42196b9b 100755 --- a/tb/test_ip_64.py +++ b/tb/test_ip_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_ip_arb_mux_4.py b/tb/test_ip_arb_mux_4.py index c68bb1a70..8c3fa6e34 100755 --- a/tb/test_ip_arb_mux_4.py +++ b/tb/test_ip_arb_mux_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import ip_ep diff --git a/tb/test_ip_arb_mux_64_4.py b/tb/test_ip_arb_mux_64_4.py index f9b2f9666..707f7b764 100755 --- a/tb/test_ip_arb_mux_64_4.py +++ b/tb/test_ip_arb_mux_64_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import ip_ep diff --git a/tb/test_ip_complete.py b/tb/test_ip_complete.py index f73631254..70eec26db 100755 --- a/tb/test_ip_complete.py +++ b/tb/test_ip_complete.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import arp_ep diff --git a/tb/test_ip_complete_64.py b/tb/test_ip_complete_64.py index a1311ae37..6d276d06b 100755 --- a/tb/test_ip_complete_64.py +++ b/tb/test_ip_complete_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import arp_ep diff --git a/tb/test_ip_demux_4.py b/tb/test_ip_demux_4.py index f0ba7e88f..4eb1b7bfe 100755 --- a/tb/test_ip_demux_4.py +++ b/tb/test_ip_demux_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import ip_ep diff --git a/tb/test_ip_demux_64_4.py b/tb/test_ip_demux_64_4.py index d7f87954d..5ffb109ed 100755 --- a/tb/test_ip_demux_64_4.py +++ b/tb/test_ip_demux_64_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import ip_ep diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index afd64ceb3..c42f7e749 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py index 30412987c..8db947c56 100755 --- a/tb/test_ip_eth_rx_64.py +++ b/tb/test_ip_eth_rx_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py index 2ef007d4c..8748bccbe 100755 --- a/tb/test_ip_eth_tx.py +++ b/tb/test_ip_eth_tx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_ip_eth_tx_64.py b/tb/test_ip_eth_tx_64.py index 976098c8f..4ac5616c7 100755 --- a/tb/test_ip_eth_tx_64.py +++ b/tb/test_ip_eth_tx_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_ip_mux_4.py b/tb/test_ip_mux_4.py index aae612801..b860a05e7 100755 --- a/tb/test_ip_mux_4.py +++ b/tb/test_ip_mux_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import ip_ep diff --git a/tb/test_ip_mux_64_4.py b/tb/test_ip_mux_64_4.py index 7656167d0..659ffa83e 100755 --- a/tb/test_ip_mux_64_4.py +++ b/tb/test_ip_mux_64_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import ip_ep diff --git a/tb/test_udp.py b/tb/test_udp.py index 9f56e2bd0..755e13a47 100755 --- a/tb/test_udp.py +++ b/tb/test_udp.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py index dd1c54d10..56b6de966 100755 --- a/tb/test_udp_64.py +++ b/tb/test_udp_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_udp_arb_mux_4.py b/tb/test_udp_arb_mux_4.py index e16978825..ef28100ac 100755 --- a/tb/test_udp_arb_mux_4.py +++ b/tb/test_udp_arb_mux_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import udp_ep diff --git a/tb/test_udp_arb_mux_64_4.py b/tb/test_udp_arb_mux_64_4.py index 08c670950..9dac1b9db 100755 --- a/tb/test_udp_arb_mux_64_4.py +++ b/tb/test_udp_arb_mux_64_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import udp_ep diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py index f50818cba..f70122101 100755 --- a/tb/test_udp_complete.py +++ b/tb/test_udp_complete.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import arp_ep diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index 98833866c..d9775d43f 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import arp_ep diff --git a/tb/test_udp_demux_4.py b/tb/test_udp_demux_4.py index 6c3ff3411..705da471d 100755 --- a/tb/test_udp_demux_4.py +++ b/tb/test_udp_demux_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import udp_ep diff --git a/tb/test_udp_demux_64_4.py b/tb/test_udp_demux_64_4.py index 8cf0c9a1a..b4f304660 100755 --- a/tb/test_udp_demux_64_4.py +++ b/tb/test_udp_demux_64_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import udp_ep diff --git a/tb/test_udp_ip_rx.py b/tb/test_udp_ip_rx.py index 6b7047651..5e216ba2c 100755 --- a/tb/test_udp_ip_rx.py +++ b/tb/test_udp_ip_rx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_udp_ip_rx_64.py b/tb/test_udp_ip_rx_64.py index ab24c73c6..df95e52dd 100755 --- a/tb/test_udp_ip_rx_64.py +++ b/tb/test_udp_ip_rx_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_udp_ip_tx.py b/tb/test_udp_ip_tx.py index be2f69062..98db8ce38 100755 --- a/tb/test_udp_ip_tx.py +++ b/tb/test_udp_ip_tx.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_udp_ip_tx_64.py b/tb/test_udp_ip_tx_64.py index 043fe8926..100d4400c 100755 --- a/tb/test_udp_ip_tx_64.py +++ b/tb/test_udp_ip_tx_64.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import ip_ep diff --git a/tb/test_udp_mux_4.py b/tb/test_udp_mux_4.py index 6a9d00382..d5b464b4a 100755 --- a/tb/test_udp_mux_4.py +++ b/tb/test_udp_mux_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import udp_ep diff --git a/tb/test_udp_mux_64_4.py b/tb/test_udp_mux_64_4.py index 177ef1896..197d85d33 100755 --- a/tb/test_udp_mux_64_4.py +++ b/tb/test_udp_mux_64_4.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2014 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import udp_ep diff --git a/tb/udp_ep.py b/tb/udp_ep.py index 95412139f..c814cc4cc 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -26,11 +26,15 @@ from myhdl import * import axis_ep import eth_ep import ip_ep -from Queue import Queue import struct +try: + from queue import Queue +except ImportError: + from Queue import Queue + class UDPFrame(object): - def __init__(self, payload='', + def __init__(self, payload=b'', eth_dest_mac=0, eth_src_mac=0, eth_type=0, @@ -204,7 +208,7 @@ class UDPFrame(object): def build_ip(self): self.build() - data = '' + data = b'' data += struct.pack('>H', self.udp_source_port) data += struct.pack('>H', self.udp_dest_port) From ae7758d83595b0b4a206bad4db7a908b5791aeac Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 21 Mar 2015 22:31:22 -0700 Subject: [PATCH 188/617] Add .travis.yml --- .travis.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..394066aff --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +language: python +python: + - "3.4" +before_install: + - export d=`pwd` + - export PYTHON_EXE=`which python` + - sudo apt-get update -qq + - sudo apt-get install -y iverilog + - git clone https://github.com/jandecaluwe/myhdl.git + - cd $d/myhdl && sudo $PYTHON_EXE setup.py install + - cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/ivl/myhdl.vpi + - cd $d +script: + - cd tb && py.test + From db6a6e23f51be49a12b223d3b1d018e54318b110 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 22 Mar 2015 01:05:57 -0700 Subject: [PATCH 189/617] Add 64 bit Ethernet FCS checker --- rtl/axis_eth_fcs_check_64.v | 563 +++++++++++++++++++++++++++++++ tb/test_axis_eth_fcs_check_64.py | 480 ++++++++++++++++++++++++++ tb/test_axis_eth_fcs_check_64.v | 103 ++++++ 3 files changed, 1146 insertions(+) create mode 100644 rtl/axis_eth_fcs_check_64.v create mode 100755 tb/test_axis_eth_fcs_check_64.py create mode 100644 tb/test_axis_eth_fcs_check_64.v diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v new file mode 100644 index 000000000..6777a5388 --- /dev/null +++ b/rtl/axis_eth_fcs_check_64.v @@ -0,0 +1,563 @@ +/* + +Copyright (c) 2015 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 Ethernet FCS checker (64 bit datapath) + */ +module axis_eth_fcs_check_64 +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [63:0] input_axis_tdata, + input wire [7: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 [63:0] output_axis_tdata, + output wire [7: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 busy, + output wire error_bad_fcs +); + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PAYLOAD = 2'd1, + STATE_LAST = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; +reg shift_in; +reg shift_reset; + +reg [63:0] input_axis_tdata_masked; + +reg [63:0] fcs_output_tdata_0; +reg [63:0] fcs_output_tdata_1; +reg [7:0] fcs_output_tkeep_0; +reg [7:0] fcs_output_tkeep_1; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [7:0] last_cycle_tkeep_reg = 0, last_cycle_tkeep_next; +reg last_cycle_tuser_reg = 0, last_cycle_tuser_next; + +reg [63:0] input_axis_tdata_d0 = 0; + +reg [7:0] input_axis_tkeep_d0 = 0; + +reg input_axis_tvalid_d0 = 0; + +reg input_axis_tuser_d0 = 0; + +reg busy_reg = 0; +reg error_bad_fcs_reg = 0, error_bad_fcs_next; + +reg input_axis_tready_reg = 0, input_axis_tready_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; +wire [31:0] crc_next4; +wire [31:0] crc_next5; +wire [31:0] crc_next6; +wire [31:0] crc_next7; + +reg [31:0] crc_next4_save = 0; +reg [31:0] crc_next5_save = 0; +reg [31:0] crc_next6_save = 0; +reg [31:0] crc_next7_save = 0; + +// internal datapath +reg [63:0] output_axis_tdata_int; +reg [7:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +assign input_axis_tready = input_axis_tready_reg; + +assign busy = busy_reg; +assign error_bad_fcs = error_bad_fcs_reg; + +eth_crc_8 +eth_crc_8_inst ( + .data_in(input_axis_tdata[7:0]), + .crc_state(crc_state), + .crc_next(crc_next0) +); + +eth_crc_16 +eth_crc_16_inst ( + .data_in(input_axis_tdata[15:0]), + .crc_state(crc_state), + .crc_next(crc_next1) +); + +eth_crc_24 +eth_crc_24_inst ( + .data_in(input_axis_tdata[23:0]), + .crc_state(crc_state), + .crc_next(crc_next2) +); + +eth_crc_32 +eth_crc_32_inst ( + .data_in(input_axis_tdata[31:0]), + .crc_state(crc_state), + .crc_next(crc_next3) +); + +eth_crc_40 +eth_crc_40_inst ( + .data_in(input_axis_tdata[39:0]), + .crc_state(crc_state), + .crc_next(crc_next4) +); + +eth_crc_48 +eth_crc_48_inst ( + .data_in(input_axis_tdata[47:0]), + .crc_state(crc_state), + .crc_next(crc_next5) +); + +eth_crc_56 +eth_crc_56_inst ( + .data_in(input_axis_tdata[55:0]), + .crc_state(crc_state), + .crc_next(crc_next6) +); + +eth_crc_64 +eth_crc_64_inst ( + .data_in(input_axis_tdata[63:0]), + .crc_state(crc_state), + .crc_next(crc_next7) +); + +function [3:0] keep2count; + input [7:0] k; + case (k) + 8'b00000000: keep2count = 0; + 8'b00000001: keep2count = 1; + 8'b00000011: keep2count = 2; + 8'b00000111: keep2count = 3; + 8'b00001111: keep2count = 4; + 8'b00011111: keep2count = 5; + 8'b00111111: keep2count = 6; + 8'b01111111: keep2count = 7; + 8'b11111111: keep2count = 8; + endcase +endfunction + +function [7:0] count2keep; + input [3:0] k; + case (k) + 4'd0: count2keep = 8'b00000000; + 4'd1: count2keep = 8'b00000001; + 4'd2: count2keep = 8'b00000011; + 4'd3: count2keep = 8'b00000111; + 4'd4: count2keep = 8'b00001111; + 4'd5: count2keep = 8'b00011111; + 4'd6: count2keep = 8'b00111111; + 4'd7: count2keep = 8'b01111111; + 4'd8: count2keep = 8'b11111111; + endcase +endfunction + +// Mask input data +always @* begin + input_axis_tdata_masked[ 7: 0] = input_axis_tkeep[0] ? input_axis_tdata[ 7: 0] : 8'd0; + input_axis_tdata_masked[15: 8] = input_axis_tkeep[1] ? input_axis_tdata[15: 8] : 8'd0; + input_axis_tdata_masked[23:16] = input_axis_tkeep[2] ? input_axis_tdata[23:16] : 8'd0; + input_axis_tdata_masked[31:24] = input_axis_tkeep[3] ? input_axis_tdata[31:24] : 8'd0; + input_axis_tdata_masked[39:32] = input_axis_tkeep[4] ? input_axis_tdata[39:32] : 8'd0; + input_axis_tdata_masked[47:40] = input_axis_tkeep[5] ? input_axis_tdata[47:40] : 8'd0; + input_axis_tdata_masked[55:48] = input_axis_tkeep[6] ? input_axis_tdata[55:48] : 8'd0; + input_axis_tdata_masked[63:56] = input_axis_tkeep[7] ? input_axis_tdata[63:56] : 8'd0; +end + +// FCS cycle calculation +always @* begin + case (input_axis_tkeep) + 8'b00000001: begin + fcs_output_tdata_0 = {~crc_next4_save[23:0], input_axis_tdata_d0[39:0]}; + fcs_output_tdata_1 = {56'd0, ~crc_next4_save[31:24]}; + fcs_output_tkeep_0 = 8'b00011111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b00000011: begin + fcs_output_tdata_0 = {~crc_next5_save[15:0], input_axis_tdata_d0[47:0]}; + fcs_output_tdata_1 = {48'd0, ~crc_next5_save[31:16]}; + fcs_output_tkeep_0 = 8'b00111111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b00000111: begin + fcs_output_tdata_0 = {~crc_next6_save[7:0], input_axis_tdata_d0[55:0]}; + fcs_output_tdata_1 = {40'd0, ~crc_next6_save[31:8]}; + fcs_output_tkeep_0 = 8'b01111111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b00001111: begin + fcs_output_tdata_0 = input_axis_tdata_d0; + fcs_output_tdata_1 = {32'd0, ~crc_next7_save[31:0]}; + fcs_output_tkeep_0 = 8'b11111111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b00011111: begin + fcs_output_tdata_0 = {24'd0, ~crc_next0[31:0], input_axis_tdata[7:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b00000001; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b00111111: begin + fcs_output_tdata_0 = {16'd0, ~crc_next1[31:0], input_axis_tdata[15:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b00000011; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b01111111: begin + fcs_output_tdata_0 = {8'd0, ~crc_next2[31:0], input_axis_tdata[23:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b00000111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b11111111: begin + fcs_output_tdata_0 = {~crc_next3[31:0], input_axis_tdata[31:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b00001111; + fcs_output_tkeep_1 = 8'b00000000; + end + default: begin + fcs_output_tdata_0 = 0; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 0; + fcs_output_tkeep_1 = 0; + end + endcase +end + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 0; + update_crc = 0; + shift_in = 0; + shift_reset = 0; + + frame_ptr_next = frame_ptr_reg; + + last_cycle_tkeep_next = last_cycle_tkeep_reg; + last_cycle_tuser_next = last_cycle_tuser_reg; + + input_axis_tready_next = 0; + + output_axis_tdata_int = 0; + output_axis_tkeep_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + error_bad_fcs_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + input_axis_tready_next = output_axis_tready_int_early; + frame_ptr_next = 0; + reset_crc = 1; + + output_axis_tdata_int = input_axis_tdata_d0; + output_axis_tkeep_int = input_axis_tkeep_d0; + output_axis_tvalid_int = input_axis_tvalid_d0 & input_axis_tvalid; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (input_axis_tready & input_axis_tvalid) begin + shift_in = 1; + reset_crc = 0; + update_crc = 1; + frame_ptr_next = keep2count(input_axis_tkeep); + if (input_axis_tlast) begin + if (input_axis_tkeep[7:4] == 0) begin + shift_reset = 1; + reset_crc = 1; + output_axis_tlast_int = 1; + output_axis_tuser_int = input_axis_tuser; + output_axis_tkeep_int = fcs_output_tkeep_0; + if (input_axis_tdata_masked != fcs_output_tdata_1 || input_axis_tdata_d0 != fcs_output_tdata_0) begin + output_axis_tuser_int = 1; + error_bad_fcs_next = 1; + end + input_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_IDLE; + end else begin + last_cycle_tkeep_next = fcs_output_tkeep_0; + last_cycle_tuser_next = input_axis_tuser; + if (input_axis_tdata_masked != fcs_output_tdata_0) begin + error_bad_fcs_next = 1; + last_cycle_tuser_next = 1; + end + input_axis_tready_next = 0; + state_next = STATE_LAST; + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // transfer payload + input_axis_tready_next = output_axis_tready_int_early; + + output_axis_tdata_int = input_axis_tdata_d0; + output_axis_tkeep_int = input_axis_tkeep_d0; + output_axis_tvalid_int = input_axis_tvalid_d0 & input_axis_tvalid; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (input_axis_tready & input_axis_tvalid) begin + shift_in = 1; + update_crc = 1; + frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); + if (input_axis_tlast) begin + if (input_axis_tkeep[7:4] == 0) begin + shift_reset = 1; + reset_crc = 1; + output_axis_tlast_int = 1; + output_axis_tuser_int = input_axis_tuser; + output_axis_tkeep_int = fcs_output_tkeep_0; + if (input_axis_tdata_masked != fcs_output_tdata_1 || input_axis_tdata_d0 != fcs_output_tdata_0) begin + output_axis_tuser_int = 1; + error_bad_fcs_next = 1; + end + input_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_IDLE; + end else begin + last_cycle_tkeep_reg = fcs_output_tkeep_0; + last_cycle_tuser_reg = input_axis_tuser; + if (input_axis_tdata_masked != fcs_output_tdata_0) begin + error_bad_fcs_next = 1; + last_cycle_tuser_next = 1; + end + input_axis_tready_next = 0; + state_next = STATE_LAST; + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + state_next = STATE_PAYLOAD; + end + end + STATE_LAST: begin + // last cycle + input_axis_tready_next = 0; + + output_axis_tdata_int = input_axis_tdata_d0; + output_axis_tkeep_int = last_cycle_tkeep_reg; + output_axis_tvalid_int = input_axis_tvalid_d0; + output_axis_tlast_int = 1; + output_axis_tuser_int = last_cycle_tuser_reg; + + if (output_axis_tready_int) begin + shift_reset = 1; + reset_crc = 1; + input_axis_tready_next = output_axis_tready_int_early; + state_next = STATE_IDLE; + end else begin + state_next = STATE_LAST; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 0; + + last_cycle_tkeep_reg <= 0; + last_cycle_tuser_reg <= 0; + + input_axis_tready_reg <= 0; + + busy_reg <= 0; + error_bad_fcs_reg <= 0; + + crc_state <= 32'hFFFFFFFF; + + crc_next4_save <= 0; + crc_next5_save <= 0; + crc_next6_save <= 0; + crc_next7_save <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + last_cycle_tkeep_reg <= last_cycle_tkeep_next; + last_cycle_tuser_reg <= last_cycle_tuser_next; + + input_axis_tready_reg <= input_axis_tready_next; + + busy_reg <= state_next != STATE_IDLE; + error_bad_fcs_reg <= error_bad_fcs_next; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + + crc_next4_save <= 0; + crc_next5_save <= 0; + crc_next6_save <= 0; + crc_next7_save <= 0; + end else if (update_crc) begin + crc_state <= crc_next7; + + crc_next4_save <= crc_next4; + crc_next5_save <= crc_next5; + crc_next6_save <= crc_next6; + crc_next7_save <= crc_next7; + end + + if (shift_reset) begin + input_axis_tvalid_d0 <= 0; + end else if (shift_in) begin + input_axis_tdata_d0 <= input_axis_tdata; + + input_axis_tkeep_d0 <= input_axis_tkeep; + + input_axis_tvalid_d0 <= input_axis_tvalid; + + input_axis_tuser_d0 <= input_axis_tuser; + end + end +end + +// output datapath logic +reg [63:0] output_axis_tdata_reg = 0; +reg [7:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [63:0] temp_axis_tdata_reg = 0; +reg [7:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_axis_eth_fcs_check_64.py b/tb/test_axis_eth_fcs_check_64.py new file mode 100755 index 000000000..9d7135149 --- /dev/null +++ b/tb/test_axis_eth_fcs_check_64.py @@ -0,0 +1,480 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 +import struct +import zlib + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep +import eth_ep + +module = 'axis_eth_fcs_check_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/eth_crc_16.v") +srcs.append("../rtl/eth_crc_24.v") +srcs.append("../rtl/eth_crc_32.v") +srcs.append("../rtl/eth_crc_40.v") +srcs.append("../rtl/eth_crc_48.v") +srcs.append("../rtl/eth_crc_56.v") +srcs.append("../rtl/eth_crc_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_eth_fcs_check_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, + + busy, + error_bad_fcs): + + 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, + + busy=busy, + error_bad_fcs=error_bad_fcs) + +def bench(): + + # Parameters + + + # 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)) + busy = Signal(bool(0)) + error_bad_fcs = 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_eth_fcs_check_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, + + busy, + error_bad_fcs) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_bad_fcs): + error_bad_fcs_asserted.next = 1 + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(40,58)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame1 + assert not rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + axis_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: bad FCS, length %d" % payload_len) + current_test.next = 4 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + axis_frame1.data[-1] ^= 0xff + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + error_bad_fcs_asserted.next = 0 + + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_bad_fcs_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + for payload_len in list(range(1,18)): + yield clk.posedge + print("test 5: test short packet, length %d" % payload_len) + current_test.next = 5 + + test_frame = bytearray(range(payload_len)) + fcs = zlib.crc32(bytes(test_frame)) & 0xffffffff + test_frame_fcs = test_frame + struct.pack(' Date: Wed, 1 Apr 2015 19:43:54 -0700 Subject: [PATCH 190/617] Update for Python 3 --- example/ATLYS/fpga/tb/test_fpga_core.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index 18d082d6b..da172489a 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Copyright (c) 2015 Alex Forencich @@ -25,7 +25,11 @@ THE SOFTWARE. from myhdl import * import os -from Queue import Queue + +try: + from queue import Queue +except ImportError: + from Queue import Queue import eth_ep import arp_ep From 5341987c45cbcce31cfa9e623317e46b67e507d3 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 1 Apr 2015 19:44:25 -0700 Subject: [PATCH 191/617] Manage ethernet preamble properly --- example/ATLYS/fpga/tb/test_fpga_core.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index da172489a..5f99b9845 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -248,7 +248,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - gmii_source_queue.put(test_frame.build_eth().build_axis_fcs()) + gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) # wait for ARP request packet while gmii_sink_queue.empty(): @@ -256,7 +256,7 @@ def bench(): rx_frame = gmii_sink_queue.get(False) check_eth_frame = eth_ep.EthFrame() - check_eth_frame.parse_axis_fcs(bytearray(rx_frame)) + check_eth_frame.parse_axis_fcs(bytearray(rx_frame)[8:]) check_frame = arp_ep.ARPFrame() check_frame.parse_eth(check_eth_frame) @@ -290,14 +290,14 @@ def bench(): arp_frame.arp_tha = 0x020000000000 arp_frame.arp_tpa = 0xc0a80180 - gmii_source_queue.put(arp_frame.build_eth().build_axis_fcs()) + gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) while gmii_sink_queue.empty(): yield clk.posedge rx_frame = gmii_sink_queue.get(False) check_eth_frame = eth_ep.EthFrame() - check_eth_frame.parse_axis_fcs(bytearray(rx_frame)) + check_eth_frame.parse_axis_fcs(bytearray(rx_frame)[8:]) check_frame = udp_ep.UDPFrame() check_frame.parse_eth(check_eth_frame) From 9b7bad92f28c7e80d04c6b7e7af0209ee8061479 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 19 Apr 2015 17:51:27 -0700 Subject: [PATCH 192/617] Reset pointers correctly --- rtl/axis_async_frame_fifo.v | 4 ++++ rtl/axis_async_frame_fifo_64.v | 4 ++++ rtl/axis_frame_fifo.v | 2 ++ rtl/axis_frame_fifo_64.v | 2 ++ 4 files changed, 12 insertions(+) diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 1c8aed29d..8b86c7890 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -107,6 +107,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; always @(posedge input_clk or posedge input_rst) begin if (input_rst) begin wr_ptr <= 0; + wr_ptr_cur <= 0; + wr_ptr_gray <= 0; + drop_frame <= 0; end else if (write) begin if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end @@ -144,6 +147,7 @@ end always @(posedge output_clk or posedge output_rst) begin if (output_rst) begin rd_ptr <= 0; + rd_ptr_gray <= 0; end else if (read) begin data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; rd_ptr_next = rd_ptr + 1; diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 4d3fd6f79..5fb593810 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -110,6 +110,9 @@ assign output_axis_tvalid = output_axis_tvalid_reg; always @(posedge input_clk or posedge input_rst) begin if (input_rst) begin wr_ptr <= 0; + wr_ptr_cur <= 0; + wr_ptr_gray <= 0; + drop_frame <= 0; end else if (write) begin if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end @@ -147,6 +150,7 @@ end always @(posedge output_clk or posedge output_rst) begin if (output_rst) begin rd_ptr <= 0; + rd_ptr_gray <= 0; end else if (read) begin data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; rd_ptr_next = rd_ptr + 1; diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 0890c8982..2acd6cb5c 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -95,6 +95,8 @@ assign output_axis_tvalid = output_axis_tvalid_reg; always @(posedge clk or posedge rst) begin if (rst) begin wr_ptr <= 0; + wr_ptr_cur <= 0; + drop_frame <= 0; end else if (write) begin if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index e42a76932..bde78d80c 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -98,6 +98,8 @@ assign output_axis_tvalid = output_axis_tvalid_reg; always @(posedge clk or posedge rst) begin if (rst) begin wr_ptr <= 0; + wr_ptr_cur <= 0; + drop_frame <= 0; end else if (write) begin if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end From 966e47a8268e7f7d41a641817909b8275339bbb8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 19 Apr 2015 23:06:30 -0700 Subject: [PATCH 193/617] Fix RAM and register widths --- rtl/axis_frame_fifo.v | 6 +++--- rtl/axis_frame_fifo_64.v | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 2acd6cb5c..526901fc1 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -63,16 +63,16 @@ reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; reg drop_frame = 1'b0; -reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; +reg [DATA_WIDTH+1-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) -reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; reg output_read = 1'b0; reg output_axis_tvalid_reg = 1'b0; -wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tdata}; +wire [DATA_WIDTH+1-1:0] data_in = {input_axis_tlast, input_axis_tdata}; // full when first MSB different but rest same wire full = ((wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index bde78d80c..9e9d866db 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -66,16 +66,16 @@ reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; reg drop_frame = 1'b0; -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; +reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; reg output_read = 1'b0; reg output_axis_tvalid_reg = 1'b0; -wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; +wire [DATA_WIDTH+KEEP_WIDTH+1-1:0] data_in = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; // full when first MSB different but rest same wire full = ((wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && From 7795a9182bed538032a200d45b1de1a5cca26657 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 19 Apr 2015 23:08:41 -0700 Subject: [PATCH 194/617] Remove tristate for state machine inference --- rtl/axis_adapter.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index dc8da2f42..b0ed727ba 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -121,7 +121,7 @@ reg input_axis_tready_reg = 0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; always @* begin - state_next = 3'bz; + state_next = STATE_IDLE; cycle_count_next = cycle_count_reg; From 9cca78bc7c082b1bff9dd4168fac4841dd47b03b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 19 Apr 2015 23:33:34 -0700 Subject: [PATCH 195/617] Fix last cycle detect logic --- rtl/axis_adapter.v | 60 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index b0ed727ba..8b621abcd 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -103,6 +103,8 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg [7:0] cycle_count_reg = 0, cycle_count_next; +reg last_cycle; + reg [DATA_WIDTH-1:0] temp_tdata_reg = 0, temp_tdata_next; reg [KEEP_WIDTH-1:0] temp_tkeep_reg = 0, temp_tkeep_next; reg temp_tlast_reg = 0, temp_tlast_next; @@ -161,7 +163,7 @@ always @* begin // accept new data input_axis_tready_next = 1; - if (input_axis_tvalid) begin + if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store it in data register // pass complete input word, zero-extended to temp register @@ -191,10 +193,24 @@ always @* begin // accept new data input_axis_tready_next = 1; - if (input_axis_tvalid) begin + if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store it in data register cycle_count_next = 0; + // is this the last cycle? + if (CYCLE_COUNT == 1) begin + // last cycle by counter value + last_cycle = 1; + end else if (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}) begin + // last cycle by tkeep fall in current cycle + last_cycle = 1; + end else if (input_axis_tkeep[(CYCLE_KEEP_WIDTH*2)-1:CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin + // last cycle by tkeep fall at end of current cycle + last_cycle = 1; + end else begin + last_cycle = 0; + end + // pass complete input word, zero-extended to temp register temp_tdata_next = input_axis_tdata; temp_tkeep_next = input_axis_tkeep; @@ -202,20 +218,24 @@ always @* begin temp_tuser_next = input_axis_tuser; // short-circuit and get first word out the door - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; + output_axis_tdata_int = input_axis_tdata[CYCLE_DATA_WIDTH-1:0]; + output_axis_tkeep_int = input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0]; output_axis_tvalid_int = 1; - output_axis_tlast_int = input_axis_tlast & ((CYCLE_COUNT == 1) | (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}})); - output_axis_tuser_int = input_axis_tuser & ((CYCLE_COUNT == 1) | (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}})); + output_axis_tlast_int = input_axis_tlast & last_cycle; + output_axis_tuser_int = input_axis_tuser & last_cycle; if (output_axis_tready_int) begin // if output register is ready for first word, then move on to the next one cycle_count_next = 1; end - // continue outputting words - input_axis_tready_next = 0; - state_next = STATE_TRANSFER_OUT; + if (!last_cycle || !output_axis_tready_int) begin + // continue outputting words + input_axis_tready_next = 0; + state_next = STATE_TRANSFER_OUT; + end else begin + state_next = STATE_IDLE; + end end else begin state_next = STATE_IDLE; end @@ -228,7 +248,7 @@ always @* begin // accept new data input_axis_tready_next = 1; - if (input_axis_tvalid) begin + if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store in data register temp_tdata_next[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH] = input_axis_tdata; @@ -305,19 +325,33 @@ always @* begin // do not accept new data input_axis_tready_next = 0; + // is this the last cycle? + if (cycle_count_reg == CYCLE_COUNT-1) begin + // last cycle by counter value + last_cycle = 1; + end else if (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}}) begin + // last cycle by tkeep fall in current cycle + last_cycle = 1; + end else if (temp_tkeep_reg[(cycle_count_reg+1)*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin + // last cycle by tkeep fall at end of current cycle + last_cycle = 1; + end else begin + last_cycle = 0; + end + // output current part of stored word (output narrower) output_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH]; output_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH]; output_axis_tvalid_int = 1; - output_axis_tlast_int = temp_tlast_reg & ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})); - output_axis_tuser_int = temp_tuser_reg & ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})); + output_axis_tlast_int = temp_tlast_reg & last_cycle; + output_axis_tuser_int = temp_tuser_reg & last_cycle; if (output_axis_tready_int) begin // word transfer out cycle_count_next = cycle_count_reg + 1; - if ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})) begin + if (last_cycle) begin // terminated by counter or tlast signal input_axis_tready_next = 1; From 71511b367179c6fe23c56f772ef078a571075c06 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Apr 2015 23:37:57 -0700 Subject: [PATCH 196/617] Remove unused register --- rtl/eth_mac_1g_rx.v | 8 -------- 1 file changed, 8 deletions(-) diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v index b07e88492..90d28c901 100644 --- a/rtl/eth_mac_1g_rx.v +++ b/rtl/eth_mac_1g_rx.v @@ -66,8 +66,6 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; - reg [7:0] gmii_rxd_d0 = 0; reg [7:0] gmii_rxd_d1 = 0; reg [7:0] gmii_rxd_d2 = 0; @@ -118,8 +116,6 @@ always @* begin reset_crc = 0; update_crc = 0; - frame_ptr_next = frame_ptr_reg; - output_axis_tdata_next = 0; output_axis_tvalid_next = 0; output_axis_tlast_next = 0; @@ -176,8 +172,6 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; output_axis_tlast_reg <= 0; @@ -190,8 +184,6 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; - output_axis_tdata_reg <= output_axis_tdata_next; output_axis_tvalid_reg <= output_axis_tvalid_next; output_axis_tlast_reg <= output_axis_tlast_next; From 14f2d5e9f7031e205cf3f44d015fa62fd1567608 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 3 May 2015 00:23:58 -0700 Subject: [PATCH 197/617] Add tkeep asserts to AXI stream EP --- tb/axis_ep.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 036c47541..70431ad1a 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -24,6 +24,8 @@ THE SOFTWARE. from myhdl import * +skip_asserts = False + class AXIStreamFrame(object): def __init__(self, data=b'', keep=None, user=None): self.B = 0 @@ -261,6 +263,7 @@ def AXIStreamSink(clk, rst, N = len(tdata) M = len(tkeep) WL = int((len(tdata)+M-1)/M) + first = True if type(tdata) is list or type(tdata) is tuple: # multiple tdata signals @@ -278,10 +281,31 @@ def AXIStreamSink(clk, rst, data = [] keep = [] user = [] + first = True else: tready_int.next = True if tvalid_int: + + if not skip_asserts: + # zero tkeep not allowed + assert int(tkeep) != 0 + # tkeep must be contiguous + # i.e. 0b00011110 allowed, but 0b00011010 not allowed + b = int(tkeep) + while b & 1 == 0: + b = b >> 1 + while b & 1 == 1: + b = b >> 1 + assert b == 0 + # tkeep must not have gaps across cycles + if not first: + # not first cycle; lowest bit must be set + assert int(tkeep) & 1 + if not tlast: + # not last cycle; highest bit must be set + assert int(tkeep) & (1 << len(tkeep)-1) + if B > 0: l = [] for i in range(B): @@ -291,6 +315,7 @@ def AXIStreamSink(clk, rst, data.append(int(tdata)) keep.append(int(tkeep)) user.append(int(tuser)) + first = False if tlast: frame.B = B frame.N = N @@ -305,6 +330,7 @@ def AXIStreamSink(clk, rst, data = [] keep = [] user = [] + first = True return logic, pause_logic From 0be84e3b0344b288d7915a67ae74274e7097f476 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 4 May 2015 01:17:39 -0700 Subject: [PATCH 198/617] Write to _next instead of _reg in async block --- rtl/axis_eth_fcs_check_64.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index 6777a5388..19fb6ae35 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -386,8 +386,8 @@ always @* begin input_axis_tready_next = output_axis_tready_int_early; state_next = STATE_IDLE; end else begin - last_cycle_tkeep_reg = fcs_output_tkeep_0; - last_cycle_tuser_reg = input_axis_tuser; + last_cycle_tkeep_next = fcs_output_tkeep_0; + last_cycle_tuser_next = input_axis_tuser; if (input_axis_tdata_masked != fcs_output_tdata_0) begin error_bad_fcs_next = 1; last_cycle_tuser_next = 1; From 3a180bd24fc97389601a103229c9264f342a100b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 7 May 2015 19:08:16 -0700 Subject: [PATCH 199/617] Improve error signal handling --- rtl/eth_mac_1g_rx.v | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v index 90d28c901..5f4e88ce9 100644 --- a/rtl/eth_mac_1g_rx.v +++ b/rtl/eth_mac_1g_rx.v @@ -58,7 +58,8 @@ module eth_mac_1g_rx localparam [2:0] STATE_IDLE = 3'd0, - STATE_PAYLOAD = 3'd1; + STATE_PAYLOAD = 3'd1, + STATE_WAIT_LAST = 3'd2; reg [2:0] state_reg = STATE_IDLE, state_next; @@ -142,13 +143,13 @@ always @* begin output_axis_tdata_next = gmii_rxd_d4; output_axis_tvalid_next = 1; - if (gmii_rx_er) begin + if (gmii_rx_dv & gmii_rx_er) begin // error output_axis_tlast_next = 1; output_axis_tuser_next = 1; error_bad_frame_next = 1; - state_next = STATE_IDLE; - end if (~gmii_rx_dv) begin + state_next = STATE_WAIT_LAST; + end else if (~gmii_rx_dv) begin // end of packet output_axis_tlast_next = 1; if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin @@ -165,6 +166,15 @@ always @* begin state_next = STATE_PAYLOAD; end end + STATE_WAIT_LAST: begin + // wait for end of packet + + if (~gmii_rx_dv) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end endcase end From f93310b85b9e9a831aa2179df0f694560b322b3e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 7 May 2015 19:10:44 -0700 Subject: [PATCH 200/617] Add GMIIFrame object and add tests and asserts for GMII error signal --- tb/gmii_ep.py | 99 +++++++++++++++++++++++++++++++++++----- tb/test_eth_mac_1g.py | 4 +- tb/test_eth_mac_1g_rx.py | 84 ++++++++++++++++++++++++++++++++-- tb/test_eth_mac_1g_tx.py | 19 ++++---- 4 files changed, 179 insertions(+), 27 deletions(-) diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index a578b1500..379e4a24d 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -24,6 +24,63 @@ THE SOFTWARE. from myhdl import * +class GMIIFrame(object): + def __init__(self, data=b'', error=None): + self.data = b'' + self.error = None + + if type(data) is GMIIFrame: + self.data = data.data + self.error = data.error + else: + self.data = bytearray(data) + + def build(self): + if self.data is None: + return + + f = list(self.data) + d = [] + er = [] + i = 0 + + assert_er = False + if (type(self.error) is int or type(self.error) is bool) and self.error: + assert_er = True + self.error = None + + while len(f) > 0: + d.append(f.pop(0)) + if self.error is None: + er.append(0) + else: + er.append(self.error[i]) + i += 1 + + if assert_er: + er[-1] = 1 + self.error = 1 + + return d, er + + def parse(self, d, er): + if d is None or er is None: + return + + self.data = bytearray(d) + self.error = er + + def __eq__(self, other): + if type(other) is GMIIFrame: + return self.data == other.data + + def __repr__(self): + return 'GMIIFrame(data=%s, error=%s)' % (repr(self.data), repr(self.error)) + + def __iter__(self): + return self.data.__iter__() + + def GMIISource(clk, rst, txd, tx_en, @@ -33,34 +90,45 @@ def GMIISource(clk, rst, @instance def logic(): - frame = [] + frame = None + d = [] + er = [] ifg_cnt = 0 while True: yield clk.posedge, rst.posedge if rst: - frame = [] + frame = None txd.next = 0 tx_en.next = 0 tx_er.next = 0 + d = [] + er = [] ifg_cnt = 0 else: if ifg_cnt > 0: ifg_cnt -= 1 + txd.next = 0 + tx_er.next = 0 tx_en.next = 0 - elif len(frame) > 0: - txd.next = frame.pop(0) + elif len(d) > 0: + txd.next = d.pop(0) + tx_er.next = er.pop(0) tx_en.next = 1 - if len(frame) == 0: + if len(d) == 0: ifg_cnt = 12 elif not fifo.empty(): - frame = list(fifo.get()) + frame = GMIIFrame(fifo.get()) + d, er = frame.build() if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) - txd.next = frame.pop(0) + txd.next = d.pop(0) + tx_er.next = er.pop(0) tx_en.next = 1 else: + txd.next = 0 + tx_er.next = 0 tx_en.next = 0 return logic @@ -76,24 +144,33 @@ def GMIISink(clk, rst, @instance def logic(): frame = None + d = [] + er = [] while True: yield clk.posedge, rst.posedge if rst: frame = None + d = [] + er = [] else: if rx_dv: if frame is None: - frame = [] - frame.append(int(rxd)) + frame = GMIIFrame() + d = [] + er = [] + d.append(int(rxd)) + er.append(int(rx_er)) elif frame is not None: - if len(frame) > 0: - frame = bytearray(frame) + if len(d) > 0: + frame.parse(d, er) if fifo is not None: fifo.put(frame) if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) frame = None + d = [] + er = [] return logic diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index a4b9da14b..b3ace71ac 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -318,10 +318,10 @@ def bench(): if not gmii_sink_queue.empty(): rx_frame = gmii_sink_queue.get() - assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame[8:]) + eth_frame.parse_axis_fcs(rx_frame.data[8:]) print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py index b15abdaec..a3d308414 100755 --- a/tb/test_eth_mac_1g_rx.py +++ b/tb/test_eth_mac_1g_rx.py @@ -182,8 +182,9 @@ def bench(): test_frame.update_fcs() axis_frame = test_frame.build_axis_fcs() + gmii_frame = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + source_queue.put(gmii_frame) yield clk.posedge yield clk.posedge @@ -227,9 +228,11 @@ def bench(): axis_frame1 = test_frame1.build_axis_fcs() axis_frame2 = test_frame2.build_axis_fcs() + gmii_frame1 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + gmii_frame2 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) - source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) - source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + source_queue.put(gmii_frame1) + source_queue.put(gmii_frame2) yield clk.posedge yield clk.posedge @@ -294,8 +297,11 @@ def bench(): error_bad_frame_asserted.next = 0 error_bad_fcs_asserted.next = 0 - source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) - source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + gmii_frame1 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + gmii_frame2 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source_queue.put(gmii_frame1) + source_queue.put(gmii_frame2) yield clk.posedge yield clk.posedge @@ -334,6 +340,74 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 4: errored frame, length %d" % payload_len) + current_test.next = 4 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + gmii_frame1 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + gmii_frame2 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + gmii_frame1.error = 1 + + source_queue.put(gmii_frame1) + source_queue.put(gmii_frame2) + yield clk.posedge + yield clk.posedge + + while gmii_rx_dv or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + + while gmii_rx_dv or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_bad_frame_asserted + assert not error_bad_fcs_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, monitor, source, sink, clkgen, check diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index e6fa9221e..5824815b4 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -194,10 +194,10 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame[8:]) + eth_frame.parse_axis_fcs(rx_frame.data[8:]) print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) @@ -249,10 +249,10 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame[8:]) + eth_frame.parse_axis_fcs(rx_frame.data[8:]) print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) @@ -268,10 +268,10 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame[8:]) + eth_frame.parse_axis_fcs(rx_frame.data[8:]) print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) @@ -325,7 +325,8 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.error[-1] # bad packet @@ -333,10 +334,10 @@ def bench(): if not sink_queue.empty(): rx_frame = sink_queue.get() - assert rx_frame[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame[8:]) + eth_frame.parse_axis_fcs(rx_frame.data[8:]) print(hex(eth_frame.eth_fcs)) print(hex(eth_frame.calc_fcs())) From ccd94dc3ed7158deb3398d15e120b180b8460094 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 7 May 2015 19:11:31 -0700 Subject: [PATCH 201/617] Replace axis_ep.py with symlink --- tb/axis_ep.py | 311 +------------------------------------------------- 1 file changed, 1 insertion(+), 310 deletions(-) mode change 100644 => 120000 tb/axis_ep.py diff --git a/tb/axis_ep.py b/tb/axis_ep.py deleted file mode 100644 index 036c47541..000000000 --- a/tb/axis_ep.py +++ /dev/null @@ -1,310 +0,0 @@ -""" - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * - -class AXIStreamFrame(object): - def __init__(self, data=b'', keep=None, user=None): - self.B = 0 - self.N = 8 - self.M = 1 - self.WL = 8 - self.data = b'' - self.keep = None - self.user = None - - if type(data) is bytes or type(data) is bytearray: - self.data = bytearray(data) - elif type(data) is AXIStreamFrame: - self.N = data.N - self.WL = data.WL - if type(data.data) is bytearray: - self.data = bytearray(data.data) - else: - self.data = list(data.data) - if data.keep is not None: - self.keep = list(data.keep) - if data.user is not None: - if type(data.user) is int or type(data.user) is bool: - self.user = data.user - else: - self.user = list(data.user) - else: - self.data = list(data) - - def build(self): - if self.data is None: - return - - f = list(self.data) - tdata = [] - tkeep = [] - tuser = [] - i = 0 - - assert_tuser = False - if (type(self.user) is int or type(self.user) is bool) and self.user: - assert_tuser = True - self.user = None - - if self.B == 0: - while len(f) > 0: - data = 0 - keep = 0 - for j in range(self.M): - data = data | (f.pop(0) << (j*self.WL)) - keep = keep | (1 << j) - if len(f) == 0: break - tdata.append(data) - if self.keep is None: - tkeep.append(keep) - else: - tkeep.append(self.keep[i]) - if self.user is None: - tuser.append(0) - else: - tuser.append(self.user[i]) - i += 1 - else: - # multiple tdata signals - while len(f) > 0: - data = 0 - tdata.append(f.pop(0)) - tkeep.append(0) - if self.user is None: - tuser.append(0) - else: - tuser.append(self.user[i]) - i += 1 - - if assert_tuser: - tuser[-1] = 1 - self.user = 1 - - return tdata, tkeep, tuser - - def parse(self, tdata, tkeep, tuser): - if tdata is None or tkeep is None or tuser is None: - return - if len(tdata) != len(tkeep) or len(tdata) != len(tuser): - raise Exception("Invalid data") - - self.data = [] - self.keep = [] - self.user = [] - - if self.B == 0: - mask = 2**self.WL-1 - - for i in range(len(tdata)): - for j in range(self.M): - if tkeep[i] & (1 << j): - self.data.append((tdata[i] >> (j*self.WL)) & mask) - self.keep.append(tkeep[i]) - self.user.append(tuser[i]) - else: - for i in range(len(tdata)): - self.data.append(tdata[i]) - self.keep.append(tkeep[i]) - self.user.append(tuser[i]) - - if self.WL == 8: - self.data = bytearray(self.data) - - def __eq__(self, other): - if type(other) is AXIStreamFrame: - return self.data == other.data - - def __repr__(self): - return 'AXIStreamFrame(data=%s, keep=%s, user=%s)' % (repr(self.data), repr(self.keep), repr(self.user)) - - def __iter__(self): - return self.data.__iter__() - -def AXIStreamSource(clk, rst, - tdata=None, - tkeep=Signal(bool(True)), - tvalid=Signal(bool(False)), - tready=Signal(bool(True)), - tlast=Signal(bool(False)), - tuser=Signal(bool(False)), - fifo=None, - pause=0, - name=None): - - tready_int = Signal(bool(False)) - tvalid_int = Signal(bool(False)) - - @always_comb - def pause_logic(): - tready_int.next = tready and not pause - tvalid.next = tvalid_int and not pause - - @instance - def logic(): - frame = AXIStreamFrame() - data = [] - keep = [] - user = [] - B = 0 - N = len(tdata) - M = len(tkeep) - WL = int((len(tdata)+M-1)/M) - - if type(tdata) is list or type(tdata) is tuple: - # multiple tdata signals - B = len(tdata) - N = [len(b) for b in tdata] - M = 1 - WL = [1]*B - - while True: - yield clk.posedge, rst.posedge - - if rst: - if B > 0: - for s in tdata: - s.next = 0 - else: - tdata.next = 0 - tkeep.next = 0 - tvalid_int.next = False - tlast.next = False - else: - if tready_int and tvalid: - if len(data) > 0: - if B > 0: - l = data.pop(0) - for i in range(B): - tdata[i].next = l[i] - else: - tdata.next = data.pop(0) - tkeep.next = keep.pop(0) - tuser.next = user.pop(0) - tvalid_int.next = True - tlast.next = len(data) == 0 - else: - tvalid_int.next = False - tlast.next = False - if (tlast and tready_int and tvalid) or not tvalid_int: - if not fifo.empty(): - frame = fifo.get() - frame = AXIStreamFrame(frame) - frame.B = B - frame.N = N - frame.M = M - frame.WL = WL - data, keep, user = frame.build() - if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) - if B > 0: - l = data.pop(0) - for i in range(B): - tdata[i].next = l[i] - else: - tdata.next = data.pop(0) - tkeep.next = keep.pop(0) - tuser.next = user.pop(0) - tvalid_int.next = True - tlast.next = len(data) == 0 - - return logic, pause_logic - - -def AXIStreamSink(clk, rst, - tdata=None, - tkeep=Signal(bool(True)), - tvalid=Signal(bool(True)), - tready=Signal(bool(True)), - tlast=Signal(bool(True)), - tuser=Signal(bool(False)), - fifo=None, - pause=0, - name=None): - - tready_int = Signal(bool(False)) - tvalid_int = Signal(bool(False)) - - @always_comb - def pause_logic(): - tready.next = tready_int and not pause - tvalid_int.next = tvalid and not pause - - @instance - def logic(): - frame = AXIStreamFrame() - data = [] - keep = [] - user = [] - B = 0 - N = len(tdata) - M = len(tkeep) - WL = int((len(tdata)+M-1)/M) - - if type(tdata) is list or type(tdata) is tuple: - # multiple tdata signals - B = len(tdata) - N = [len(b) for b in tdata] - M = 1 - WL = [1]*B - - while True: - yield clk.posedge, rst.posedge - - if rst: - tready_int.next = False - frame = AXIStreamFrame() - data = [] - keep = [] - user = [] - else: - tready_int.next = True - - if tvalid_int: - if B > 0: - l = [] - for i in range(B): - l.append(int(tdata[i])) - data.append(l) - else: - data.append(int(tdata)) - keep.append(int(tkeep)) - user.append(int(tuser)) - if tlast: - frame.B = B - frame.N = N - frame.M = M - frame.WL = WL - frame.parse(data, keep, user) - if fifo is not None: - fifo.put(frame) - if name is not None: - print("[%s] Got frame %s" % (name, repr(frame))) - frame = AXIStreamFrame() - data = [] - keep = [] - user = [] - - return logic, pause_logic - diff --git a/tb/axis_ep.py b/tb/axis_ep.py new file mode 120000 index 000000000..f4ce98383 --- /dev/null +++ b/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/axis/tb/axis_ep.py \ No newline at end of file From 73bebaba4612c54817c25eb5e48f3731885f3523 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 7 May 2015 23:45:30 -0700 Subject: [PATCH 202/617] Add FIFO wrapper for gigabit MAC module --- rtl/eth_mac_1g_fifo.v | 177 +++++++++++++++++ tb/test_eth_mac_1g_fifo.py | 378 +++++++++++++++++++++++++++++++++++++ tb/test_eth_mac_1g_fifo.v | 143 ++++++++++++++ 3 files changed, 698 insertions(+) create mode 100644 rtl/eth_mac_1g_fifo.v create mode 100755 tb/test_eth_mac_1g_fifo.py create mode 100644 tb/test_eth_mac_1g_fifo.v diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v new file mode 100644 index 000000000..a92eaa7f6 --- /dev/null +++ b/rtl/eth_mac_1g_fifo.v @@ -0,0 +1,177 @@ +/* + +Copyright (c) 2015 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 + +/* + * 1G Ethernet MAC with TX and RX FIFOs + */ +module eth_mac_1g_fifo # +( + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter TX_FIFO_ADDR_WIDTH = 9, + parameter RX_FIFO_ADDR_WIDTH = 9 +) +( + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, + input wire logic_clk, + input wire logic_rst, + + /* + * AXI input + */ + input wire [7:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] rx_axis_tdata, + output wire rx_axis_tvalid, + input wire rx_axis_tready, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * GMII interface + */ + input wire [7:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, + output wire [7:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * Status + */ + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +wire [7:0] tx_fifo_axis_tdata; +wire tx_fifo_axis_tvalid; +wire tx_fifo_axis_tready; +wire tx_fifo_axis_tlast; +wire tx_fifo_axis_tuser; + +wire [7:0] rx_fifo_axis_tdata; +wire rx_fifo_axis_tvalid; +wire rx_fifo_axis_tlast; +wire rx_fifo_axis_tuser; + +eth_mac_1g #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_fifo_axis_tdata), + .tx_axis_tvalid(tx_fifo_axis_tvalid), + .tx_axis_tready(tx_fifo_axis_tready), + .tx_axis_tlast(tx_fifo_axis_tlast), + .tx_axis_tuser(tx_fifo_axis_tuser), + .rx_axis_tdata(rx_fifo_axis_tdata), + .rx_axis_tvalid(rx_fifo_axis_tvalid), + .rx_axis_tlast(rx_fifo_axis_tlast), + .rx_axis_tuser(rx_fifo_axis_tuser), + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +axis_async_frame_fifo #( + .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(8), + .DROP_WHEN_FULL(0) +) +tx_fifo ( + // AXI input + .input_clk(logic_clk), + .input_rst(logic_rst), + .input_axis_tdata(tx_axis_tdata), + .input_axis_tvalid(tx_axis_tvalid), + .input_axis_tready(tx_axis_tready), + .input_axis_tlast(tx_axis_tlast), + .input_axis_tuser(tx_axis_tuser), + // AXI output + .output_clk(tx_clk), + .output_rst(tx_rst), + .output_axis_tdata(tx_fifo_axis_tdata), + .output_axis_tvalid(tx_fifo_axis_tvalid), + .output_axis_tready(tx_fifo_axis_tready), + .output_axis_tlast(tx_fifo_axis_tlast) +); + +assign tx_fifo_axis_tuser = 1'b0; + +axis_async_frame_fifo #( + .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(8), + .DROP_WHEN_FULL(1) +) +rx_fifo ( + // AXI input + .input_clk(rx_clk), + .input_rst(rx_rst), + .input_axis_tdata(rx_fifo_axis_tdata), + .input_axis_tvalid(rx_fifo_axis_tvalid), + .input_axis_tready(), + .input_axis_tlast(rx_fifo_axis_tlast), + .input_axis_tuser(rx_fifo_axis_tuser), + // AXI output + .output_clk(logic_clk), + .output_rst(logic_rst), + .output_axis_tdata(rx_axis_tdata), + .output_axis_tvalid(rx_axis_tvalid), + .output_axis_tready(rx_axis_tready), + .output_axis_tlast(rx_axis_tlast) +); + +assign rx_axis_tuser = 1'b0; + +endmodule diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py new file mode 100755 index 000000000..cd36feddd --- /dev/null +++ b/tb/test_eth_mac_1g_fifo.py @@ -0,0 +1,378 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep +import eth_ep +import gmii_ep + +module = 'eth_mac_1g_fifo' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/eth_mac_1g_rx.v") +srcs.append("../rtl/eth_mac_1g_tx.v") +srcs.append("../rtl/eth_mac_1g.v") +srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_mac_1g(clk, + rst, + current_test, + + rx_clk, + rx_rst, + tx_clk, + tx_rst, + logic_clk, + logic_rst, + + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tready, + tx_axis_tlast, + tx_axis_tuser, + + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tready, + rx_axis_tlast, + rx_axis_tuser, + + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + + gmii_txd, + gmii_tx_en, + gmii_tx_er, + + rx_error_bad_frame, + rx_error_bad_fcs, + + ifg_delay): + + 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, + + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + logic_clk=logic_clk, + logic_rst=logic_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tready=rx_axis_tready, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + gmii_rxd=gmii_rxd, + gmii_rx_dv=gmii_rx_dv, + gmii_rx_er=gmii_rx_er, + + gmii_txd=gmii_txd, + gmii_tx_en=gmii_tx_en, + gmii_tx_er=gmii_tx_er, + + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + + ifg_delay=ifg_delay) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + TX_FIFO_ADDR_WIDTH = 9 + RX_FIFO_ADDR_WIDTH = 9 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + logic_clk = Signal(bool(0)) + logic_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[8:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + rx_axis_tready = Signal(bool(0)) + gmii_rxd = Signal(intbv(0)[8:]) + gmii_rx_dv = Signal(bool(0)) + gmii_rx_er = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[8:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + gmii_txd = Signal(intbv(0)[8:]) + gmii_tx_en = Signal(bool(0)) + gmii_tx_er = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + + # sources and sinks + gmii_source_queue = Queue() + gmii_sink_queue = Queue() + axis_source_queue = Queue() + axis_source_pause = Signal(bool(0)) + axis_sink_queue = Queue() + + gmii_source = gmii_ep.GMIISource(rx_clk, + rx_rst, + txd=gmii_rxd, + tx_en=gmii_rx_dv, + tx_er=gmii_rx_er, + fifo=gmii_source_queue, + name='gmii_source') + + gmii_sink = gmii_ep.GMIISink(tx_clk, + tx_rst, + rxd=gmii_txd, + rx_dv=gmii_tx_en, + rx_er=gmii_tx_er, + fifo=gmii_sink_queue, + name='gmii_sink') + + axis_source = axis_ep.AXIStreamSource(tx_clk, + tx_rst, + tdata=tx_axis_tdata, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + fifo=axis_source_queue, + pause=axis_source_pause, + name='axis_source') + + axis_sink = axis_ep.AXIStreamSink(rx_clk, + rx_rst, + tdata=rx_axis_tdata, + tvalid=rx_axis_tvalid, + tready=rx_axis_tready, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + fifo=axis_sink_queue, + name='axis_sink') + + # DUT + dut = dut_eth_mac_1g(clk, + rst, + current_test, + + rx_clk, + rx_rst, + tx_clk, + tx_rst, + logic_clk, + logic_rst, + + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tready, + tx_axis_tlast, + tx_axis_tuser, + + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tready, + rx_axis_tlast, + rx_axis_tuser, + + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + + gmii_txd, + gmii_tx_en, + gmii_tx_er, + + rx_error_bad_frame, + rx_error_bad_fcs, + + ifg_delay) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + tx_clk.next = not tx_clk + rx_clk.next = not rx_clk + logic_clk.next = not logic_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + tx_rst.next = 1 + rx_rst.next = 1 + logic_rst.next = 1 + yield clk.posedge + rst.next = 0 + tx_rst.next = 0 + rx_rst.next = 0 + logic_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + yield clk.posedge + yield clk.posedge + + while gmii_rx_dv: + yield clk.posedge + + yield delay(100) + + while rx_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not axis_sink_queue.empty(): + rx_frame = axis_sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + while tx_axis_tvalid: + yield clk.posedge + + yield delay(100) + + while gmii_tx_en: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not gmii_sink_queue.empty(): + rx_frame = gmii_sink_queue.get() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return dut, axis_source, axis_sink, gmii_source, gmii_sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_1g_fifo.v b/tb/test_eth_mac_1g_fifo.v new file mode 100644 index 000000000..500094656 --- /dev/null +++ b/tb/test_eth_mac_1g_fifo.v @@ -0,0 +1,143 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for eth_mac_1g_fifo + */ +module test_eth_mac_1g_fifo; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; +parameter TX_FIFO_ADDR_WIDTH = 9; +parameter RX_FIFO_ADDR_WIDTH = 9; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg rx_clk = 0; +reg rx_rst = 0; +reg tx_clk = 0; +reg tx_rst = 0; +reg logic_clk = 0; +reg logic_rst = 0; +reg [7:0] tx_axis_tdata = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg rx_axis_tready = 0; +reg [7:0] gmii_rxd = 0; +reg gmii_rx_dv = 0; +reg gmii_rx_er = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire [7:0] gmii_txd; +wire gmii_tx_en; +wire gmii_tx_er; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + rx_clk, + rx_rst, + tx_clk, + tx_rst, + logic_clk, + logic_rst, + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + rx_axis_tready, + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + ifg_delay); + $to_myhdl(tx_axis_tready, + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + gmii_txd, + gmii_tx_en, + gmii_tx_er, + rx_error_bad_frame, + rx_error_bad_fcs); + + // dump file + $dumpfile("test_eth_mac_1g_fifo.lxt"); + $dumpvars(0, test_eth_mac_1g_fifo); +end + +eth_mac_1g_fifo #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .TX_FIFO_ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .RX_FIFO_ADDR_WIDTH(RX_FIFO_ADDR_WIDTH) +) +UUT ( + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .logic_clk(logic_clk), + .logic_rst(logic_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +endmodule From 17edcfe88e91084525c911d3407368e78d8fb9cd Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 00:04:12 -0700 Subject: [PATCH 203/617] Add XGMII endpoint module --- tb/xgmii_ep.py | 262 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 tb/xgmii_ep.py diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py new file mode 100644 index 000000000..1d8e71924 --- /dev/null +++ b/tb/xgmii_ep.py @@ -0,0 +1,262 @@ +""" + +Copyright (c) 2015 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 * + +class XGMIIFrame(object): + def __init__(self, data=b'', error=None, ctrl=None): + self.data = b'' + self.error = None + self.ctrl = None + + if type(data) is XGMIIFrame: + self.data = data.data + self.error = data.error + self.ctrl = data.ctrl + else: + self.data = bytearray(data) + + def build(self): + if self.data is None: + return + + f = list(self.data) + ctrl = [] + error = [] + d = [] + c = [] + i = 0 + + assert_error = False + if (type(self.error) is int or type(self.error) is bool) and self.error: + assert_error = True + error = [0]*len(self.data) + error[-1] = 1 + elif self.error is None: + error = [0]*len(self.data) + else: + error = list(self.error) + + if self.ctrl is None: + ctrl = [0]*len(self.data) + else: + ctrl = list(self.ctrl) + + assert len(ctrl) == len(f) + assert len(ctrl) == len(f) + + for i in range(len(f)): + if error[i]: + f[i] = 0xfe + ctrl[i] = 1 + + i = 0 + while len(f) > 0: + d.append(f.pop(0)) + c.append(ctrl[i]) + i += 1 + + return d, c + + def parse(self, d, c): + if d is None or c is None: + return + + self.data = bytearray(d) + self.ctrl = c + + self.error = [0]*len(self.data) + + for i in range(len(self.data)): + if c[i] and d[i] == 0xfe: + self.error[i] = 1 + + def __eq__(self, other): + if type(other) is XGMIIFrame: + return self.data == other.data + + def __repr__(self): + return 'XGMIIFrame(data=%s, error=%s, ctrl=%s)' % (repr(self.data), repr(self.error), repr(self.ctrl)) + + def __iter__(self): + return self.data.__iter__() + + +def XGMIISource(clk, rst, + txd, + txc, + fifo=None, + name=None): + + @instance + def logic(): + frame = None + dl = [] + cl = [] + ifg_cnt = 0 + deficit_idle_cnt = 0 + nt = False + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame = None + txd.next = 0x0707070707070707 + txc.next = 0xff + dl = [] + cl = [] + ifg_cnt = 0 + deficit_idle_cnt = 0 + nt = False + else: + if ifg_cnt > 7: + ifg_cnt -= 8 + txd.next = 0x0707070707070707 + txc.next = 0xff + elif len(dl) > 0 or nt: + d = 0 + c = 0 + + for i in range(8): + if len(dl) > 0: + d |= dl.pop(0) << (8*i) + c |= cl.pop(0) << i + nt = True + else: + if nt: + d |= 0xfd << (8*i) + nt = False + ifg_cnt = 12 - (8-i) + deficit_idle_cnt + else: + d |= 0x07 << (8*i) + c |= 1 << i + + txd.next = d + txc.next = c + elif not fifo.empty(): + frame = XGMIIFrame(fifo.get()) + dl, cl = frame.build() + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + + if ifg_cnt >= 4: + deficit_idle_cnt = ifg_cnt - 4 + else: + deficit_idle_cnt = ifg_cnt + ifg_cnt = 0 + + assert len(dl) > 0 + assert dl.pop(0) == 0x55 + cl.pop(0) + + k = 1 + d = 0xfb + c = 1 + + if ifg_cnt > 0: + k = 5 + d = 0xfb07070707 + c = 0x1f + + for i in range(k,8): + if len(dl) > 0: + d |= dl.pop(0) << (8*i) + c |= cl.pop(0) << i + nt = True + else: + if nt: + d |= 0xfd << (8*i) + nt = False + else: + d |= 0x07 << (8*i) + c |= 1 << i + + txd.next = d + txc.next = c + else: + ifg_cnt = 0 + deficit_idle_cnt = 0 + txd.next = 0x0707070707070707 + txc.next = 0xff + + return logic + + +def XGMIISink(clk, rst, + rxd, + rxc, + fifo=None, + name=None): + + @instance + def logic(): + frame = None + d = [] + c = [] + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame = None + d = [] + c = [] + else: + if frame is None: + if rxc & 1 and rxd & 0xff == 0xfb: + # start in lane 0 + frame = XGMIIFrame() + d = [0x55] + c = [0] + for i in range(1,8): + d.append((int(rxd) >> (8*i)) & 0xff) + c.append((int(rxc) >> i) & 1) + elif (rxc >> 4) & 1 and (rxd >> 32) & 0xff == 0xfb: + # start in lane 4 + frame = XGMIIFrame() + d = [0x55] + c = [0] + for i in range(5,8): + d.append((int(rxd) >> (8*i)) & 0xff) + c.append((int(rxc) >> i) & 1) + else: + for i in range(8): + if (rxc >> i) & 1 and (rxd >> (8*i)) & 0xff == 0xfd: + # terminate + frame.parse(d, c) + if fifo is not None: + fifo.put(frame) + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + frame = None + d = [] + c = [] + break + else: + d.append((int(rxd) >> (8*i)) & 0xff) + c.append((int(rxc) >> i) & 1) + + return logic + From bf349b16ba8d89e8195a50efbe1109e1cf5ef6aa Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 00:05:21 -0700 Subject: [PATCH 204/617] Add 10G MAC module --- rtl/eth_mac_10g.v | 117 ++++++++ rtl/eth_mac_10g_rx.v | 488 +++++++++++++++++++++++++++++++ rtl/eth_mac_10g_tx.v | 590 ++++++++++++++++++++++++++++++++++++++ tb/test_eth_mac_10g.py | 356 +++++++++++++++++++++++ tb/test_eth_mac_10g.v | 132 +++++++++ tb/test_eth_mac_10g_rx.py | 461 +++++++++++++++++++++++++++++ tb/test_eth_mac_10g_rx.v | 88 ++++++ tb/test_eth_mac_10g_tx.py | 402 ++++++++++++++++++++++++++ tb/test_eth_mac_10g_tx.v | 93 ++++++ 9 files changed, 2727 insertions(+) create mode 100644 rtl/eth_mac_10g.v create mode 100644 rtl/eth_mac_10g_rx.v create mode 100644 rtl/eth_mac_10g_tx.v create mode 100755 tb/test_eth_mac_10g.py create mode 100644 tb/test_eth_mac_10g.v create mode 100755 tb/test_eth_mac_10g_rx.py create mode 100644 tb/test_eth_mac_10g_rx.v create mode 100755 tb/test_eth_mac_10g_tx.py create mode 100644 tb/test_eth_mac_10g_tx.v diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v new file mode 100644 index 000000000..f09c4da60 --- /dev/null +++ b/rtl/eth_mac_10g.v @@ -0,0 +1,117 @@ +/* + +Copyright (c) 2015 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 + +/* + * 10G Ethernet MAC + */ +module eth_mac_10g # +( + parameter ENABLE_PADDING = 1, + parameter ENABLE_DIC = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, + + /* + * AXI input + */ + input wire [63:0] tx_axis_tdata, + input wire [7:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [63:0] rx_axis_tdata, + output wire [7:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * XGMII interface + */ + input wire [63:0] xgmii_rxd, + input wire [7:0] xgmii_rxc, + output wire [63:0] xgmii_txd, + output wire [7:0] xgmii_txc, + + /* + * Status + */ + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +eth_mac_10g_rx +eth_mac_10g_rx_inst ( + .clk(rx_clk), + .rst(rx_rst), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .output_axis_tdata(rx_axis_tdata), + .output_axis_tkeep(rx_axis_tkeep), + .output_axis_tvalid(rx_axis_tvalid), + .output_axis_tlast(rx_axis_tlast), + .output_axis_tuser(rx_axis_tuser), + .error_bad_frame(rx_error_bad_frame), + .error_bad_fcs(rx_error_bad_fcs) +); + +eth_mac_10g_tx #( + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_10g_tx_inst ( + .clk(tx_clk), + .rst(tx_rst), + .input_axis_tdata(tx_axis_tdata), + .input_axis_tkeep(tx_axis_tkeep), + .input_axis_tvalid(tx_axis_tvalid), + .input_axis_tready(tx_axis_tready), + .input_axis_tlast(tx_axis_tlast), + .input_axis_tuser(tx_axis_tuser), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v new file mode 100644 index 000000000..523907087 --- /dev/null +++ b/rtl/eth_mac_10g_rx.v @@ -0,0 +1,488 @@ +/* + +Copyright (c) 2015 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 + +/* + * 10G Ethernet MAC + */ +module eth_mac_10g_rx +( + input wire clk, + input wire rst, + + /* + * XGMII input + */ + input wire [63:0] xgmii_rxd, + input wire [7:0] xgmii_rxc, + + /* + * AXI output + */ + output wire [63:0] output_axis_tdata, + output wire [7:0] output_axis_tkeep, + output wire output_axis_tvalid, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Status + */ + output wire error_bad_frame, + output wire error_bad_fcs +); + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PAYLOAD = 3'd1, + STATE_LAST = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg [63:0] xgmii_rxd_masked; + +reg [63:0] fcs_output_tdata_0; +reg [63:0] fcs_output_tdata_1; +reg [7:0] fcs_output_tkeep_0; +reg [7:0] fcs_output_tkeep_1; + +reg [7:0] last_cycle_tkeep_reg = 0, last_cycle_tkeep_next; +reg last_cycle_tuser_reg = 0, last_cycle_tuser_next; + +reg lanes_swapped = 0; +reg [31:0] swap_rxd = 0; +reg [3:0] swap_rxc = 0; + +reg [63:0] xgmii_rxd_d0 = 64'h0707070707070707; +reg [63:0] xgmii_rxd_d1 = 64'h0707070707070707; + +reg [7:0] xgmii_rxc_d0 = 8'b11111111; +reg [7:0] xgmii_rxc_d1 = 8'b11111111; + +reg [63:0] output_axis_tdata_reg = 0, output_axis_tdata_next; +reg [7:0] output_axis_tkeep_reg = 0, output_axis_tkeep_next; +reg output_axis_tvalid_reg = 0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 0, output_axis_tlast_next; +reg output_axis_tuser_reg = 0, output_axis_tuser_next; + +reg error_bad_frame_reg = 0, error_bad_frame_next; +reg error_bad_fcs_reg = 0, error_bad_fcs_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; +wire [31:0] crc_next4; +wire [31:0] crc_next5; +wire [31:0] crc_next6; +wire [31:0] crc_next7; + +reg [31:0] crc_next3_save = 0; +reg [31:0] crc_next4_save = 0; +reg [31:0] crc_next5_save = 0; +reg [31:0] crc_next6_save = 0; +reg [31:0] crc_next7_save = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +assign error_bad_frame = error_bad_frame_reg; +assign error_bad_fcs = error_bad_fcs_reg; + +eth_crc_8 +eth_crc_8_inst ( + .data_in(xgmii_rxd_d0[7:0]), + .crc_state(crc_state), + .crc_next(crc_next0) +); + +eth_crc_16 +eth_crc_16_inst ( + .data_in(xgmii_rxd_d0[15:0]), + .crc_state(crc_state), + .crc_next(crc_next1) +); + +eth_crc_24 +eth_crc_24_inst ( + .data_in(xgmii_rxd_d0[23:0]), + .crc_state(crc_state), + .crc_next(crc_next2) +); + +eth_crc_32 +eth_crc_32_inst ( + .data_in(xgmii_rxd_d0[31:0]), + .crc_state(crc_state), + .crc_next(crc_next3) +); + +eth_crc_40 +eth_crc_40_inst ( + .data_in(xgmii_rxd_d0[39:0]), + .crc_state(crc_state), + .crc_next(crc_next4) +); + +eth_crc_48 +eth_crc_48_inst ( + .data_in(xgmii_rxd_d0[47:0]), + .crc_state(crc_state), + .crc_next(crc_next5) +); + +eth_crc_56 +eth_crc_56_inst ( + .data_in(xgmii_rxd_d0[55:0]), + .crc_state(crc_state), + .crc_next(crc_next6) +); + +eth_crc_64 +eth_crc_64_inst ( + .data_in(xgmii_rxd_d0[63:0]), + .crc_state(crc_state), + .crc_next(crc_next7) +); + +// FCS cycle calculation +always @* begin + case (xgmii_rxc_d0) + 8'b11111111: begin + fcs_output_tdata_0 = {~crc_next3_save[31:0], xgmii_rxd_d1[31:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b00001111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b11111110: begin + fcs_output_tdata_0 = {~crc_next4_save[23:0], xgmii_rxd_d1[39:0]}; + fcs_output_tdata_1 = {56'd0, ~crc_next4_save[31:24]}; + fcs_output_tkeep_0 = 8'b00011111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b11111100: begin + fcs_output_tdata_0 = {~crc_next5_save[15:0], xgmii_rxd_d1[47:0]}; + fcs_output_tdata_1 = {48'd0, ~crc_next5_save[31:16]}; + fcs_output_tkeep_0 = 8'b00111111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b11111000: begin + fcs_output_tdata_0 = {~crc_next6_save[7:0], xgmii_rxd_d1[55:0]}; + fcs_output_tdata_1 = {40'd0, ~crc_next6_save[31:8]}; + fcs_output_tkeep_0 = 8'b01111111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b11110000: begin + fcs_output_tdata_0 = xgmii_rxd_d1; + fcs_output_tdata_1 = {32'd0, ~crc_next7_save[31:0]}; + fcs_output_tkeep_0 = 8'b11111111; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b11100000: begin + fcs_output_tdata_0 = {24'd0, ~crc_next0[31:0], xgmii_rxd_d0[7:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b00000001; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b11000000: begin + fcs_output_tdata_0 = {16'd0, ~crc_next1[31:0], xgmii_rxd_d0[15:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b00000011; + fcs_output_tkeep_1 = 8'b00000000; + end + 8'b10000000: begin + fcs_output_tdata_0 = {8'd0, ~crc_next2[31:0], xgmii_rxd_d0[23:0]}; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 8'b00000111; + fcs_output_tkeep_1 = 8'b00000000; + end + default: begin + fcs_output_tdata_0 = 0; + fcs_output_tdata_1 = 0; + fcs_output_tkeep_0 = 0; + fcs_output_tkeep_1 = 0; + end + endcase +end + +// detect control characters +reg [7:0] detect_start; +reg [7:0] detect_term; +reg [7:0] detect_error; + +integer i; + +always @* begin + for (i = 0; i < 8; i = i + 1) begin + detect_start[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfb); + detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfd); + detect_error[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfe); + end +end + +// mask errors to within packet +reg [7:0] detect_error_masked; + +always @* begin + case (detect_term) + 8'b00000000: begin + detect_error_masked = detect_error; + end + 8'b00000001: begin + detect_error_masked = 0; + end + 8'b00000010: begin + detect_error_masked = detect_error[0]; + end + 8'b00000100: begin + detect_error_masked = detect_error[1:0]; + end + 8'b00001000: begin + detect_error_masked = detect_error[2:0]; + end + 8'b00010000: begin + detect_error_masked = detect_error[3:0]; + end + 8'b00100000: begin + detect_error_masked = detect_error[4:0]; + end + 8'b01000000: begin + detect_error_masked = detect_error[5:0]; + end + 8'b10000000: begin + detect_error_masked = detect_error[6:0]; + end + endcase +end + +// Mask input data +integer j; + +always @* begin + for (j = 0; j < 8; j = j + 1) begin + xgmii_rxd_masked[j*8 +: 8] = xgmii_rxc_d0[j] ? 8'd0 : xgmii_rxd_d0[j*8 +: 8]; + end +end + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 0; + update_crc = 0; + + last_cycle_tkeep_next = last_cycle_tkeep_reg; + last_cycle_tuser_next = last_cycle_tuser_reg; + + output_axis_tdata_next = 0; + output_axis_tkeep_next = 0; + output_axis_tvalid_next = 0; + output_axis_tlast_next = 0; + output_axis_tuser_next = 0; + + error_bad_frame_next = 0; + error_bad_fcs_next = 0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for packet + reset_crc = 1; + + if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin + // start condition + reset_crc = 0; + update_crc = 1; + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // read payload + update_crc = 1; + + output_axis_tdata_next = xgmii_rxd_d1; + output_axis_tkeep_next = ~xgmii_rxc_d1; + output_axis_tvalid_next = 1; + output_axis_tlast_next = 0; + output_axis_tuser_next = 0; + + if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin + // start condition in packet - flag as bad and restart + output_axis_tlast_next = 1; + output_axis_tuser_next = 1; + error_bad_frame_next = 1; + reset_crc = 1; + state_next = STATE_PAYLOAD; + end else if (detect_error_masked) begin + // error condition + output_axis_tlast_next = 1; + output_axis_tuser_next = 1; + error_bad_frame_next = 1; + reset_crc = 1; + state_next = STATE_IDLE; + end else if (detect_term) begin + if (detect_term[4:0]) begin + // end this cycle + reset_crc = 1; + output_axis_tkeep_next = fcs_output_tkeep_0; + output_axis_tlast_next = 1; + if (xgmii_rxd_masked != fcs_output_tdata_1 || xgmii_rxd_d1 != fcs_output_tdata_0) begin + output_axis_tuser_next = 1; + error_bad_frame_next = 1; + error_bad_fcs_next = 1; + end + state_next = STATE_IDLE; + end else begin + // need extra cycle + last_cycle_tkeep_next = fcs_output_tkeep_0; + last_cycle_tuser_next = 0; + if (xgmii_rxd_masked != fcs_output_tdata_0) begin + error_bad_frame_next = 1; + error_bad_fcs_next = 1; + last_cycle_tuser_next = 1; + end + state_next = STATE_LAST; + end + end else begin + state_next = STATE_PAYLOAD; + end + end + STATE_LAST: begin + // last cycle of packet + output_axis_tdata_next = xgmii_rxd_d1; + output_axis_tkeep_next = last_cycle_tkeep_reg; + output_axis_tvalid_next = 1; + output_axis_tlast_next = 1; + output_axis_tuser_next = last_cycle_tuser_reg; + + reset_crc = 1; + + if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin + // start condition + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_IDLE; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + + last_cycle_tkeep_reg <= 0; + last_cycle_tuser_reg <= 0; + + error_bad_frame_reg <= 0; + error_bad_fcs_reg <= 0; + + crc_state <= 32'hFFFFFFFF; + + xgmii_rxd_d0 <= 64'h0707070707070707; + xgmii_rxd_d1 <= 64'h0707070707070707; + + xgmii_rxc_d0 <= 8'b11111111; + xgmii_rxc_d1 <= 8'b11111111; + + lanes_swapped <= 0; + swap_rxd <= 0; + swap_rxc <= 0; + end else begin + state_reg <= state_next; + + output_axis_tdata_reg <= output_axis_tdata_next; + output_axis_tkeep_reg <= output_axis_tkeep_next; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tlast_reg <= output_axis_tlast_next; + output_axis_tuser_reg <= output_axis_tuser_next; + + last_cycle_tkeep_reg <= last_cycle_tkeep_next; + last_cycle_tuser_reg <= last_cycle_tuser_next; + + error_bad_frame_reg <= error_bad_frame_next; + error_bad_fcs_reg <= error_bad_fcs_next; + + if (xgmii_rxc[0] && xgmii_rxd[7:0] == 8'hfb) begin + lanes_swapped <= 0; + xgmii_rxd_d0 <= xgmii_rxd; + xgmii_rxc_d0 <= xgmii_rxc; + end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == 8'hfb) begin + lanes_swapped <= 1; + xgmii_rxd_d0 <= 64'h0707070707070707; + xgmii_rxc_d0 <= 8'b11111111; + end else if (lanes_swapped) begin + xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; + xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; + end else begin + xgmii_rxd_d0 <= xgmii_rxd; + xgmii_rxc_d0 <= xgmii_rxc; + end + + swap_rxd <= xgmii_rxd[63:32]; + swap_rxc <= xgmii_rxc[7:4]; + + xgmii_rxd_d1 <= xgmii_rxd_d0; + xgmii_rxc_d1 <= xgmii_rxc_d0; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + + crc_next3_save <= 0; + crc_next4_save <= 0; + crc_next5_save <= 0; + crc_next6_save <= 0; + crc_next7_save <= 0; + end else if (update_crc) begin + crc_state <= crc_next7; + + crc_next3_save <= crc_next3; + crc_next4_save <= crc_next4; + crc_next5_save <= crc_next5; + crc_next6_save <= crc_next6; + crc_next7_save <= crc_next7; + end + end +end + +endmodule diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v new file mode 100644 index 000000000..3d416d05d --- /dev/null +++ b/rtl/eth_mac_10g_tx.v @@ -0,0 +1,590 @@ +/* + +Copyright (c) 2015 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 + +/* + * 10G Ethernet MAC + */ +module eth_mac_10g_tx # +( + parameter ENABLE_PADDING = 1, + parameter ENABLE_DIC = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [63:0] input_axis_tdata, + input wire [7:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * XGMII output + */ + output wire [63:0] xgmii_txd, + output wire [7:0] xgmii_txc, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PAYLOAD = 3'd1, + STATE_PAD = 3'd2, + STATE_FCS = 3'd3, + STATE_IFG = 3'd4; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg swap_lanes; +reg unswap_lanes; + +reg lanes_swapped = 0; +reg [31:0] swap_txd = 0; +reg [3:0] swap_txc = 0; + +reg [63:0] input_axis_tdata_masked; + +reg [63:0] fcs_input_tdata; +reg [7:0] fcs_input_tkeep; + +reg [63:0] fcs_output_txd_0; +reg [63:0] fcs_output_txd_1; +reg [7:0] fcs_output_txc_0; +reg [7:0] fcs_output_txc_1; + +reg [7:0] ifg_offset; + +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [7:0] ifg_count_reg = 0, ifg_count_next; +reg [1:0] deficit_idle_count_reg = 0, deficit_idle_count_next; + +reg [63:0] last_cycle_txd_reg = 0, last_cycle_txd_next; +reg [7:0] last_cycle_txc_reg = 0, last_cycle_txc_next; + +reg busy_reg = 0; + +reg input_axis_tready_reg = 0, input_axis_tready_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; +wire [31:0] crc_next4; +wire [31:0] crc_next5; +wire [31:0] crc_next6; +wire [31:0] crc_next7; + +reg [63:0] xgmii_txd_reg = 64'h0707070707070707, xgmii_txd_next; +reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; + +assign input_axis_tready = input_axis_tready_reg; + +assign xgmii_txd = xgmii_txd_reg; +assign xgmii_txc = xgmii_txc_reg; + +eth_crc_8 +eth_crc_8_inst ( + .data_in(fcs_input_tdata[7:0]), + .crc_state(crc_state), + .crc_next(crc_next0) +); + +eth_crc_16 +eth_crc_16_inst ( + .data_in(fcs_input_tdata[15:0]), + .crc_state(crc_state), + .crc_next(crc_next1) +); + +eth_crc_24 +eth_crc_24_inst ( + .data_in(fcs_input_tdata[23:0]), + .crc_state(crc_state), + .crc_next(crc_next2) +); + +eth_crc_32 +eth_crc_32_inst ( + .data_in(fcs_input_tdata[31:0]), + .crc_state(crc_state), + .crc_next(crc_next3) +); + +eth_crc_40 +eth_crc_40_inst ( + .data_in(fcs_input_tdata[39:0]), + .crc_state(crc_state), + .crc_next(crc_next4) +); + +eth_crc_48 +eth_crc_48_inst ( + .data_in(fcs_input_tdata[47:0]), + .crc_state(crc_state), + .crc_next(crc_next5) +); + +eth_crc_56 +eth_crc_56_inst ( + .data_in(fcs_input_tdata[55:0]), + .crc_state(crc_state), + .crc_next(crc_next6) +); + +eth_crc_64 +eth_crc_64_inst ( + .data_in(fcs_input_tdata[63:0]), + .crc_state(crc_state), + .crc_next(crc_next7) +); + +function [3:0] keep2count; + input [7:0] k; + case (k) + 8'b00000000: keep2count = 0; + 8'b00000001: keep2count = 1; + 8'b00000011: keep2count = 2; + 8'b00000111: keep2count = 3; + 8'b00001111: keep2count = 4; + 8'b00011111: keep2count = 5; + 8'b00111111: keep2count = 6; + 8'b01111111: keep2count = 7; + 8'b11111111: keep2count = 8; + endcase +endfunction + +function [7:0] count2keep; + input [3:0] k; + case (k) + 4'd0: count2keep = 8'b00000000; + 4'd1: count2keep = 8'b00000001; + 4'd2: count2keep = 8'b00000011; + 4'd3: count2keep = 8'b00000111; + 4'd4: count2keep = 8'b00001111; + 4'd5: count2keep = 8'b00011111; + 4'd6: count2keep = 8'b00111111; + 4'd7: count2keep = 8'b01111111; + 4'd8: count2keep = 8'b11111111; + endcase +endfunction + +// Mask input data +always @* begin + input_axis_tdata_masked[ 7: 0] = input_axis_tkeep[0] ? input_axis_tdata[ 7: 0] : 8'd0; + input_axis_tdata_masked[15: 8] = input_axis_tkeep[1] ? input_axis_tdata[15: 8] : 8'd0; + input_axis_tdata_masked[23:16] = input_axis_tkeep[2] ? input_axis_tdata[23:16] : 8'd0; + input_axis_tdata_masked[31:24] = input_axis_tkeep[3] ? input_axis_tdata[31:24] : 8'd0; + input_axis_tdata_masked[39:32] = input_axis_tkeep[4] ? input_axis_tdata[39:32] : 8'd0; + input_axis_tdata_masked[47:40] = input_axis_tkeep[5] ? input_axis_tdata[47:40] : 8'd0; + input_axis_tdata_masked[55:48] = input_axis_tkeep[6] ? input_axis_tdata[55:48] : 8'd0; + input_axis_tdata_masked[63:56] = input_axis_tkeep[7] ? input_axis_tdata[63:56] : 8'd0; +end + +// FCS cycle calculation +always @* begin + case (fcs_input_tkeep) + 8'b00000001: begin + fcs_output_txd_0 = {24'h0707fd, ~crc_next0[31:0], fcs_input_tdata[7:0]}; + fcs_output_txd_1 = {63'h0707070707070707}; + fcs_output_txc_0 = 8'b11100000; + fcs_output_txc_1 = 8'b11111111; + ifg_offset = 3; + end + 8'b00000011: begin + fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], fcs_input_tdata[15:0]}; + fcs_output_txd_1 = {63'h0707070707070707}; + fcs_output_txc_0 = 8'b11000000; + fcs_output_txc_1 = 8'b11111111; + ifg_offset = 2; + end + 8'b00000111: begin + fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], fcs_input_tdata[23:0]}; + fcs_output_txd_1 = {63'h0707070707070707}; + fcs_output_txc_0 = 8'b10000000; + fcs_output_txc_1 = 8'b11111111; + ifg_offset = 1; + end + 8'b00001111: begin + fcs_output_txd_0 = {~crc_next3[31:0], fcs_input_tdata[31:0]}; + fcs_output_txd_1 = {63'h07070707070707fd}; + fcs_output_txc_0 = 8'b00000000; + fcs_output_txc_1 = 8'b11111111; + ifg_offset = 8; + end + 8'b00011111: begin + fcs_output_txd_0 = {~crc_next4[23:0], fcs_input_tdata[39:0]}; + fcs_output_txd_1 = {56'h070707070707fd, ~crc_next4[31:24]}; + fcs_output_txc_0 = 8'b00000000; + fcs_output_txc_1 = 8'b11111110; + ifg_offset = 7; + end + 8'b00111111: begin + fcs_output_txd_0 = {~crc_next5[15:0], fcs_input_tdata[47:0]}; + fcs_output_txd_1 = {48'h0707070707fd, ~crc_next5[31:16]}; + fcs_output_txc_0 = 8'b00000000; + fcs_output_txc_1 = 8'b11111100; + ifg_offset = 6; + end + 8'b01111111: begin + fcs_output_txd_0 = {~crc_next6[7:0], fcs_input_tdata[55:0]}; + fcs_output_txd_1 = {40'h07070707fd, ~crc_next6[31:8]}; + fcs_output_txc_0 = 8'b00000000; + fcs_output_txc_1 = 8'b11111000; + ifg_offset = 5; + end + 8'b11111111: begin + fcs_output_txd_0 = fcs_input_tdata; + fcs_output_txd_1 = {32'h070707fd, ~crc_next7[31:0]}; + fcs_output_txc_0 = 8'b00000000; + fcs_output_txc_1 = 8'b11110000; + ifg_offset = 4; + end + default: begin + fcs_output_txd_0 = 0; + fcs_output_txd_1 = 0; + fcs_output_txc_0 = 0; + fcs_output_txc_1 = 0; + ifg_offset = 0; + end + endcase +end + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 0; + update_crc = 0; + + swap_lanes = 0; + unswap_lanes = 0; + + frame_ptr_next = frame_ptr_reg; + + ifg_count_next = ifg_count_reg; + + last_cycle_txd_next = last_cycle_txd_reg; + last_cycle_txc_next = last_cycle_txc_reg; + + input_axis_tready_next = 0; + + fcs_input_tdata = 0; + fcs_input_tkeep = 0; + + // XGMII idle + xgmii_txd_next = 64'h0707070707070707; + xgmii_txc_next = 8'b11111111; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 0; + reset_crc = 1; + + // XGMII idle + xgmii_txd_next = 64'h0707070707070707; + xgmii_txc_next = 8'b11111111; + + if (input_axis_tvalid) begin + // XGMII start and preamble + if (ifg_count_reg > 0) begin + // need to send more idles - swap lanes + swap_lanes = 1; + end else begin + // no more idles - unswap + unswap_lanes = 1; + end + xgmii_txd_next = 64'hd5555555555555fb; + xgmii_txc_next = 8'b00000001; + input_axis_tready_next = 1; + state_next = STATE_PAYLOAD; + end else begin + ifg_count_next = 0; + deficit_idle_count_next = 0; + unswap_lanes = 1; + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // transfer payload + update_crc = 1; + input_axis_tready_next = 1; + + xgmii_txd_next = input_axis_tdata_masked; + xgmii_txc_next = 8'b00000000; + + fcs_input_tdata = input_axis_tdata_masked; + fcs_input_tkeep = input_axis_tkeep; + + if (input_axis_tvalid) begin + frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); + if (input_axis_tlast) begin + input_axis_tready_next = 0; + if (input_axis_tuser) begin + xgmii_txd_next = 64'h070707fdfefefefe; + xgmii_txc_next = 8'b11111111; + frame_ptr_next = 0; + ifg_count_next = 8; + state_next = STATE_IFG; + end else begin + if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-4) begin + fcs_input_tkeep = 8'hff; + frame_ptr_next = frame_ptr_reg + 8; + + if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin + input_axis_tready_next = 0; + state_next = STATE_PAD; + end else begin + fcs_input_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + + xgmii_txd_next = fcs_output_txd_0; + xgmii_txc_next = fcs_output_txc_0; + last_cycle_txd_next = fcs_output_txd_1; + last_cycle_txc_next = fcs_output_txc_1; + + reset_crc = 1; + frame_ptr_next = 0; + input_axis_tready_next = 0; + + ifg_count_next = (ifg_delay > 12 ? ifg_delay : 12) - ifg_offset + (lanes_swapped ? 4 : 0) + deficit_idle_count_reg; + if (fcs_output_txc_1 != 8'hff || fcs_output_txc_0 == 0) begin + state_next = STATE_FCS; + end else begin + state_next = STATE_IFG; + end + end + end else begin + xgmii_txd_next = fcs_output_txd_0; + xgmii_txc_next = fcs_output_txc_0; + last_cycle_txd_next = fcs_output_txd_1; + last_cycle_txc_next = fcs_output_txc_1; + + reset_crc = 1; + frame_ptr_next = 0; + input_axis_tready_next = 0; + + ifg_count_next = (ifg_delay > 12 ? ifg_delay : 12) - ifg_offset + (lanes_swapped ? 4 : 0) + deficit_idle_count_reg; + if (fcs_output_txc_1 != 8'hff || fcs_output_txc_0 == 0) begin + state_next = STATE_FCS; + end else begin + state_next = STATE_IFG; + end + end + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + xgmii_txd_next = 64'h070707fdfefefefe; + xgmii_txc_next = 8'b11111111; + frame_ptr_next = 0; + ifg_count_next = 8; + state_next = STATE_IFG; + end + end + STATE_PAD: begin + input_axis_tready_next = 0; + + xgmii_txd_next = 0; + xgmii_txc_next = 8'b00000000; + + fcs_input_tdata = 0; + fcs_input_tkeep = 8'hff; + + update_crc = 1; + frame_ptr_next = frame_ptr_reg + 8; + + if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin + state_next = STATE_PAD; + end else begin + fcs_input_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + + xgmii_txd_next = fcs_output_txd_0; + xgmii_txc_next = fcs_output_txc_0; + last_cycle_txd_next = fcs_output_txd_1; + last_cycle_txc_next = fcs_output_txc_1; + + reset_crc = 1; + frame_ptr_next = 0; + input_axis_tready_next = 0; + + ifg_count_next = (ifg_delay > 12 ? ifg_delay : 12) - ifg_offset + (lanes_swapped ? 4 : 0) + deficit_idle_count_reg; + if (fcs_output_txc_1 != 8'hff || fcs_output_txc_0 == 0) begin + state_next = STATE_FCS; + end else begin + state_next = STATE_IFG; + end + end + end + STATE_FCS: begin + // last cycle + input_axis_tready_next = 0; + + xgmii_txd_next = last_cycle_txd_reg; + xgmii_txc_next = last_cycle_txc_reg; + + reset_crc = 1; + frame_ptr_next = 0; + + if (ENABLE_DIC) begin + if (ifg_count_next > 7) begin + state_next = STATE_IFG; + end else begin + if (ifg_count_next >= 4) begin + deficit_idle_count_next = ifg_count_next - 4; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 0; + end + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 4) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end + end + STATE_IFG: begin + // send IFG + if (ifg_count_reg > 8) begin + ifg_count_next = ifg_count_reg - 8; + end else begin + ifg_count_next = 0; + end + + reset_crc = 1; + + if (ENABLE_DIC) begin + if (ifg_count_next > 7) begin + state_next = STATE_IFG; + end else begin + if (ifg_count_next >= 4) begin + deficit_idle_count_next = ifg_count_next - 4; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 0; + end + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 4) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 0; + + ifg_count_reg <= 0; + deficit_idle_count_reg <= 0; + + last_cycle_txd_reg <= 0; + last_cycle_txc_reg <= 0; + + input_axis_tready_reg <= 0; + + xgmii_txd_reg <= 64'h0707070707070707; + xgmii_txc_reg <= 8'b11111111; + + crc_state <= 32'hFFFFFFFF; + + lanes_swapped <= 0; + swap_txd <= 0; + swap_txc <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + ifg_count_reg <= ifg_count_next; + deficit_idle_count_reg <= deficit_idle_count_next; + + last_cycle_txd_reg <= last_cycle_txd_next; + last_cycle_txc_reg <= last_cycle_txc_next; + + input_axis_tready_reg <= input_axis_tready_next; + + if (lanes_swapped) begin + if (unswap_lanes) begin + lanes_swapped <= 0; + xgmii_txd_reg <= xgmii_txd_next; + xgmii_txc_reg <= xgmii_txc_next; + end else begin + xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd}; + xgmii_txc_reg <= {xgmii_txc_next[3:0], swap_txc}; + end + end else begin + if (swap_lanes) begin + lanes_swapped <= 1; + xgmii_txd_reg <= {xgmii_txd_next[31:0], 32'h07070707}; + xgmii_txc_reg <= {xgmii_txc_next[3:0], 4'b1111}; + end else begin + xgmii_txd_reg <= xgmii_txd_next; + xgmii_txc_reg <= xgmii_txc_next; + end + end + + swap_txd <= xgmii_txd_next[63:32]; + swap_txc <= xgmii_txc_next[7:4]; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next7; + end + end +end + +endmodule diff --git a/tb/test_eth_mac_10g.py b/tb/test_eth_mac_10g.py new file mode 100755 index 000000000..a0eaa19db --- /dev/null +++ b/tb/test_eth_mac_10g.py @@ -0,0 +1,356 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep +import eth_ep +import xgmii_ep + +module = 'eth_mac_10g' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/eth_crc_16.v") +srcs.append("../rtl/eth_crc_24.v") +srcs.append("../rtl/eth_crc_32.v") +srcs.append("../rtl/eth_crc_40.v") +srcs.append("../rtl/eth_crc_48.v") +srcs.append("../rtl/eth_crc_56.v") +srcs.append("../rtl/eth_crc_64.v") +srcs.append("../rtl/eth_mac_10g_rx.v") +srcs.append("../rtl/eth_mac_10g_tx.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_mac_1g(clk, + rst, + current_test, + + rx_clk, + rx_rst, + tx_clk, + tx_rst, + + tx_axis_tdata, + tx_axis_tkeep, + tx_axis_tvalid, + tx_axis_tready, + tx_axis_tlast, + tx_axis_tuser, + + rx_axis_tdata, + rx_axis_tkeep, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + + xgmii_rxd, + xgmii_rxc, + + xgmii_txd, + xgmii_txc, + + rx_error_bad_frame, + rx_error_bad_fcs, + + ifg_delay): + + 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, + + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tkeep=tx_axis_tkeep, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tkeep=rx_axis_tkeep, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + xgmii_rxd=xgmii_rxd, + xgmii_rxc=xgmii_rxc, + + xgmii_txd=xgmii_txd, + xgmii_txc=xgmii_txc, + + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + + ifg_delay=ifg_delay) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + ENABLE_DIC = 1 + MIN_FRAME_LENGTH = 64 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[64:]) + tx_axis_tkeep = Signal(intbv(0)[8:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + xgmii_rxd = Signal(intbv(0x0707070707070707)[64:]) + xgmii_rxc = Signal(intbv(0xff)[8:]) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[64:]) + rx_axis_tkeep = Signal(intbv(0)[8:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) + xgmii_txc = Signal(intbv(0xff)[8:]) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + + # sources and sinks + xgmii_source_queue = Queue() + xgmii_sink_queue = Queue() + axis_source_queue = Queue() + axis_source_pause = Signal(bool(0)) + axis_sink_queue = Queue() + + xgmii_source = xgmii_ep.XGMIISource(rx_clk, + rx_rst, + txd=xgmii_rxd, + txc=xgmii_rxc, + fifo=xgmii_source_queue, + name='xgmii_source') + + xgmii_sink = xgmii_ep.XGMIISink(tx_clk, + tx_rst, + rxd=xgmii_txd, + rxc=xgmii_txc, + fifo=xgmii_sink_queue, + name='xgmii_sink') + + axis_source = axis_ep.AXIStreamSource(tx_clk, + tx_rst, + tdata=tx_axis_tdata, + tkeep=tx_axis_tkeep, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + fifo=axis_source_queue, + pause=axis_source_pause, + name='axis_source') + + axis_sink = axis_ep.AXIStreamSink(rx_clk, + rx_rst, + tdata=rx_axis_tdata, + tkeep=rx_axis_tkeep, + tvalid=rx_axis_tvalid, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + fifo=axis_sink_queue, + name='axis_sink') + + # DUT + dut = dut_eth_mac_1g(clk, + rst, + current_test, + + rx_clk, + rx_rst, + tx_clk, + tx_rst, + + tx_axis_tdata, + tx_axis_tkeep, + tx_axis_tvalid, + tx_axis_tready, + tx_axis_tlast, + tx_axis_tuser, + + rx_axis_tdata, + rx_axis_tkeep, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + + xgmii_rxd, + xgmii_rxc, + + xgmii_txd, + xgmii_txc, + + rx_error_bad_frame, + rx_error_bad_fcs, + + ifg_delay) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + tx_clk.next = not tx_clk + rx_clk.next = not rx_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + tx_rst.next = 1 + rx_rst.next = 1 + yield clk.posedge + rst.next = 0 + tx_rst.next = 0 + rx_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + yield clk.posedge + yield clk.posedge + + while xgmii_rxc != 0xff or rx_axis_tvalid or not xgmii_source_queue.empty(): + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not axis_sink_queue.empty(): + rx_frame = axis_sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + while xgmii_txc != 0xff or tx_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not xgmii_sink_queue.empty(): + rx_frame = xgmii_sink_queue.get() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return dut, axis_source, axis_sink, xgmii_source, xgmii_sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_10g.v b/tb/test_eth_mac_10g.v new file mode 100644 index 000000000..c9c63de6d --- /dev/null +++ b/tb/test_eth_mac_10g.v @@ -0,0 +1,132 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for eth_mac_10g + */ +module test_eth_mac_10g; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; +parameter MIN_FRAME_LENGTH = 64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg rx_clk = 0; +reg rx_rst = 0; +reg tx_clk = 0; +reg tx_rst = 0; +reg [63:0] tx_axis_tdata = 0; +reg [7:0] tx_axis_tkeep = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg [63:0] xgmii_rxd = 0; +reg [7:0] xgmii_rxc = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [63:0] rx_axis_tdata; +wire [7:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire [63:0] xgmii_txd; +wire [7:0] xgmii_txc; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + rx_clk, + rx_rst, + tx_clk, + tx_rst, + tx_axis_tdata, + tx_axis_tkeep, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + xgmii_rxd, + xgmii_rxc, + ifg_delay); + $to_myhdl(tx_axis_tready, + rx_axis_tdata, + rx_axis_tkeep, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + xgmii_txd, + xgmii_txc, + rx_error_bad_frame, + rx_error_bad_fcs); + + // dump file + $dumpfile("test_eth_mac_10g.lxt"); + $dumpvars(0, test_eth_mac_10g); +end + +eth_mac_10g #( + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/tb/test_eth_mac_10g_rx.py b/tb/test_eth_mac_10g_rx.py new file mode 100755 index 000000000..eaacb0e8a --- /dev/null +++ b/tb/test_eth_mac_10g_rx.py @@ -0,0 +1,461 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep +import eth_ep +import xgmii_ep + +axis_ep.skip_assert = True + +module = 'eth_mac_10g_rx' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/eth_crc_16.v") +srcs.append("../rtl/eth_crc_24.v") +srcs.append("../rtl/eth_crc_32.v") +srcs.append("../rtl/eth_crc_40.v") +srcs.append("../rtl/eth_crc_48.v") +srcs.append("../rtl/eth_crc_56.v") +srcs.append("../rtl/eth_crc_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_mac_10g_rx(clk, + rst, + current_test, + + xgmii_rxd, + xgmii_rxc, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + + error_bad_frame, + error_bad_fcs): + + 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, + + xgmii_rxd=xgmii_rxd, + xgmii_rxc=xgmii_rxc, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + error_bad_frame=error_bad_frame, + error_bad_fcs=error_bad_fcs) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + xgmii_rxd = Signal(intbv(0x0707070707070707)[64:]) + xgmii_rxc = Signal(intbv(0xff)[8:]) + + # Outputs + 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)) + error_bad_frame = Signal(bool(0)) + error_bad_fcs = Signal(bool(0)) + + # sources and sinks + source_queue = Queue() + sink_queue = Queue() + + source = xgmii_ep.XGMIISource(clk, + rst, + txd=xgmii_rxd, + txc=xgmii_rxc, + fifo=source_queue, + name='source') + + sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + fifo=sink_queue, + name='sink') + + # DUT + dut = dut_eth_mac_10g_rx(clk, + rst, + current_test, + + xgmii_rxd, + xgmii_rxc, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + + error_bad_frame, + error_bad_fcs) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_bad_frame_asserted = Signal(bool(0)) + error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_bad_frame): + error_bad_frame_asserted.next = 1 + if (error_bad_fcs): + error_bad_fcs_asserted.next = 1 + + @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,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + source_queue.put(xgmii_frame) + yield clk.posedge + yield clk.posedge + + while xgmii_rxc != 0xff or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source_queue.put(xgmii_frame1) + source_queue.put(xgmii_frame2) + yield clk.posedge + yield clk.posedge + + while xgmii_rxc != 0xff or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + + while xgmii_rxc != 0xff or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame1 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: truncated frame, length %d" % payload_len) + current_test.next = 3 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + axis_frame1.data = axis_frame1.data[:-1] + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source_queue.put(xgmii_frame1) + source_queue.put(xgmii_frame2) + yield clk.posedge + yield clk.posedge + + while xgmii_rxc != 0xff or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + + while xgmii_rxc != 0xff or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_bad_frame_asserted + assert error_bad_fcs_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: errored frame, length %d" % payload_len) + current_test.next = 4 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + xgmii_frame1.error = 1 + + source_queue.put(xgmii_frame1) + source_queue.put(xgmii_frame2) + yield clk.posedge + yield clk.posedge + + while xgmii_rxc != 0xff or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + + while xgmii_rxc != 0xff or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_bad_frame_asserted + assert not error_bad_fcs_asserted + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink_queue.empty() + + yield delay(100) + + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 5: test stream, length %d" % payload_len) + current_test.next = 5 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + yield clk.posedge + yield clk.posedge + + while xgmii_rxc != 0xff or output_axis_tvalid or not source_queue.empty(): + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + yield delay(100) + + raise StopSimulation + + return dut, monitor, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_10g_rx.v b/tb/test_eth_mac_10g_rx.v new file mode 100644 index 000000000..96713171d --- /dev/null +++ b/tb/test_eth_mac_10g_rx.v @@ -0,0 +1,88 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for eth_mac_10g_rx + */ +module test_eth_mac_10g_rx; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] xgmii_rxd = 64'h0707070707070707; +reg [7:0] xgmii_rxc = 8'hff; + +// Outputs +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 error_bad_frame; +wire error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + xgmii_rxd, + xgmii_rxc); + $to_myhdl(output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + error_bad_frame, + error_bad_fcs); + + // dump file + $dumpfile("test_eth_mac_10g_rx.lxt"); + $dumpvars(0, test_eth_mac_10g_rx); +end + +eth_mac_10g_rx +UUT ( + .clk(clk), + .rst(rst), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + .error_bad_frame(error_bad_frame), + .error_bad_fcs(error_bad_fcs) +); + +endmodule diff --git a/tb/test_eth_mac_10g_tx.py b/tb/test_eth_mac_10g_tx.py new file mode 100755 index 000000000..75c8c6929 --- /dev/null +++ b/tb/test_eth_mac_10g_tx.py @@ -0,0 +1,402 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep +import eth_ep +import xgmii_ep + +module = 'eth_mac_10g_tx' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/eth_crc_16.v") +srcs.append("../rtl/eth_crc_24.v") +srcs.append("../rtl/eth_crc_32.v") +srcs.append("../rtl/eth_crc_40.v") +srcs.append("../rtl/eth_crc_48.v") +srcs.append("../rtl/eth_crc_56.v") +srcs.append("../rtl/eth_crc_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_mac_10g_tx(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + xgmii_txd, + xgmii_txc, + + ifg_delay): + + 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, + + xgmii_txd=xgmii_txd, + xgmii_txc=xgmii_txc, + + ifg_delay=ifg_delay) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # 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)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + input_axis_tready = Signal(bool(0)) + xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) + xgmii_txc = Signal(intbv(0xff)[8:]) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + + 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 = xgmii_ep.XGMIISink(clk, + rst, + rxd=xgmii_txd, + rxc=xgmii_txc, + fifo=sink_queue, + name='sink') + + # DUT + dut = dut_eth_mac_10g_tx(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + xgmii_txd, + xgmii_txc, + + ifg_delay) + + @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 + + ifg_delay.next = 12 + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(40,58)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + while xgmii_txc != 0xff or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + while xgmii_txc != 0xff or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame1.eth_src_mac + assert eth_frame.eth_type == test_frame1.eth_type + assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = eth_ep.EthFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x8000 + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.user = 1 + + source_queue.put(axis_frame1) + source_queue.put(axis_frame2) + yield clk.posedge + yield clk.posedge + + while xgmii_txc != 0xff or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.error[-1] + + # bad packet + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink_queue.empty() + + yield delay(100) + + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 4: test stream, length %d" % payload_len) + current_test.next = 4 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source_queue.put(axis_frame) + + yield clk.posedge + yield clk.posedge + + while xgmii_txc != 0xff or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_10g_tx.v b/tb/test_eth_mac_10g_tx.v new file mode 100644 index 000000000..54efc23b7 --- /dev/null +++ b/tb/test_eth_mac_10g_tx.v @@ -0,0 +1,93 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for eth_mac_10g_tx + */ +module test_eth_mac_10g_tx; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 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 [7:0] ifg_delay = 0; + +// Outputs +wire input_axis_tready; +wire [63:0] xgmii_txd; +wire [7:0] xgmii_txc; + +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, + ifg_delay); + $to_myhdl(input_axis_tready, + xgmii_txd, + xgmii_txc); + + // dump file + $dumpfile("test_eth_mac_10g_tx.lxt"); + $dumpvars(0, test_eth_mac_10g_tx); +end + +eth_mac_10g_tx #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .clk(clk), + .rst(rst), + .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), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .ifg_delay(ifg_delay) +); + +endmodule From 00a87b26b3f3b4f279140af867edf8b2f485b052 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 00:07:09 -0700 Subject: [PATCH 205/617] Add FIFO wrapper for 10G MAC module --- rtl/eth_mac_10g_fifo.v | 185 +++++++++++++++++ tb/test_eth_mac_10g_fifo.py | 386 ++++++++++++++++++++++++++++++++++++ tb/test_eth_mac_10g_fifo.v | 145 ++++++++++++++ 3 files changed, 716 insertions(+) create mode 100644 rtl/eth_mac_10g_fifo.v create mode 100755 tb/test_eth_mac_10g_fifo.py create mode 100644 tb/test_eth_mac_10g_fifo.v diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v new file mode 100644 index 000000000..5d1880738 --- /dev/null +++ b/rtl/eth_mac_10g_fifo.v @@ -0,0 +1,185 @@ +/* + +Copyright (c) 2015 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 + +/* + * 10G Ethernet MAC with TX and RX FIFOs + */ +module eth_mac_10g_fifo # +( + parameter ENABLE_PADDING = 1, + parameter ENABLE_DIC = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter TX_FIFO_ADDR_WIDTH = 9, + parameter RX_FIFO_ADDR_WIDTH = 9 +) +( + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, + input wire logic_clk, + input wire logic_rst, + + /* + * AXI input + */ + input wire [63:0] tx_axis_tdata, + input wire [7:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [63:0] rx_axis_tdata, + output wire [7:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + input wire rx_axis_tready, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * XGMII interface + */ + input wire [63:0] xgmii_rxd, + input wire [7:0] xgmii_rxc, + output wire [63:0] xgmii_txd, + output wire [7:0] xgmii_txc, + + /* + * Status + */ + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +wire [63:0] tx_fifo_axis_tdata; +wire [7:0] tx_fifo_axis_tkeep; +wire tx_fifo_axis_tvalid; +wire tx_fifo_axis_tready; +wire tx_fifo_axis_tlast; +wire tx_fifo_axis_tuser; + +wire [63:0] rx_fifo_axis_tdata; +wire [7:0] rx_fifo_axis_tkeep; +wire rx_fifo_axis_tvalid; +wire rx_fifo_axis_tlast; +wire rx_fifo_axis_tuser; + +eth_mac_10g #( + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_fifo_axis_tdata), + .tx_axis_tkeep(tx_fifo_axis_tkeep), + .tx_axis_tvalid(tx_fifo_axis_tvalid), + .tx_axis_tready(tx_fifo_axis_tready), + .tx_axis_tlast(tx_fifo_axis_tlast), + .tx_axis_tuser(tx_fifo_axis_tuser), + .rx_axis_tdata(rx_fifo_axis_tdata), + .rx_axis_tkeep(rx_fifo_axis_tkeep), + .rx_axis_tvalid(rx_fifo_axis_tvalid), + .rx_axis_tlast(rx_fifo_axis_tlast), + .rx_axis_tuser(rx_fifo_axis_tuser), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +axis_async_frame_fifo_64 #( + .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(64), + .DROP_WHEN_FULL(0) +) +tx_fifo ( + // AXI input + .input_clk(logic_clk), + .input_rst(logic_rst), + .input_axis_tdata(tx_axis_tdata), + .input_axis_tkeep(tx_axis_tkeep), + .input_axis_tvalid(tx_axis_tvalid), + .input_axis_tready(tx_axis_tready), + .input_axis_tlast(tx_axis_tlast), + .input_axis_tuser(tx_axis_tuser), + // AXI output + .output_clk(tx_clk), + .output_rst(tx_rst), + .output_axis_tdata(tx_fifo_axis_tdata), + .output_axis_tkeep(tx_fifo_axis_tkeep), + .output_axis_tvalid(tx_fifo_axis_tvalid), + .output_axis_tready(tx_fifo_axis_tready), + .output_axis_tlast(tx_fifo_axis_tlast) +); + +assign tx_fifo_axis_tuser = 1'b0; + +axis_async_frame_fifo_64 #( + .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(64), + .DROP_WHEN_FULL(1) +) +rx_fifo ( + // AXI input + .input_clk(rx_clk), + .input_rst(rx_rst), + .input_axis_tdata(rx_fifo_axis_tdata), + .input_axis_tkeep(rx_fifo_axis_tkeep), + .input_axis_tvalid(rx_fifo_axis_tvalid), + .input_axis_tready(), + .input_axis_tlast(rx_fifo_axis_tlast), + .input_axis_tuser(rx_fifo_axis_tuser), + // AXI output + .output_clk(logic_clk), + .output_rst(logic_rst), + .output_axis_tdata(rx_axis_tdata), + .output_axis_tkeep(rx_axis_tkeep), + .output_axis_tvalid(rx_axis_tvalid), + .output_axis_tready(rx_axis_tready), + .output_axis_tlast(rx_axis_tlast) +); + +assign rx_axis_tuser = 1'b0; + +endmodule diff --git a/tb/test_eth_mac_10g_fifo.py b/tb/test_eth_mac_10g_fifo.py new file mode 100755 index 000000000..a5f502ac5 --- /dev/null +++ b/tb/test_eth_mac_10g_fifo.py @@ -0,0 +1,386 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep +import eth_ep +import xgmii_ep + +module = 'eth_mac_10g_fifo' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/eth_crc_16.v") +srcs.append("../rtl/eth_crc_24.v") +srcs.append("../rtl/eth_crc_32.v") +srcs.append("../rtl/eth_crc_40.v") +srcs.append("../rtl/eth_crc_48.v") +srcs.append("../rtl/eth_crc_56.v") +srcs.append("../rtl/eth_crc_64.v") +srcs.append("../rtl/eth_mac_10g_rx.v") +srcs.append("../rtl/eth_mac_10g_tx.v") +srcs.append("../rtl/eth_mac_10g.v") +srcs.append("../lib/axis/rtl/axis_async_frame_fifo_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_eth_mac_1g(clk, + rst, + current_test, + + rx_clk, + rx_rst, + tx_clk, + tx_rst, + logic_clk, + logic_rst, + + tx_axis_tdata, + tx_axis_tkeep, + tx_axis_tvalid, + tx_axis_tready, + tx_axis_tlast, + tx_axis_tuser, + + rx_axis_tdata, + rx_axis_tkeep, + rx_axis_tvalid, + rx_axis_tready, + rx_axis_tlast, + rx_axis_tuser, + + xgmii_rxd, + xgmii_rxc, + + xgmii_txd, + xgmii_txc, + + rx_error_bad_frame, + rx_error_bad_fcs, + + ifg_delay): + + 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, + + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + logic_clk=logic_clk, + logic_rst=logic_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tkeep=tx_axis_tkeep, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tkeep=rx_axis_tkeep, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tready=rx_axis_tready, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + xgmii_rxd=xgmii_rxd, + xgmii_rxc=xgmii_rxc, + + xgmii_txd=xgmii_txd, + xgmii_txc=xgmii_txc, + + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + + ifg_delay=ifg_delay) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + ENABLE_DIC = 1 + MIN_FRAME_LENGTH = 64 + TX_FIFO_ADDR_WIDTH = 9 + RX_FIFO_ADDR_WIDTH = 9 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + logic_clk = Signal(bool(0)) + logic_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[64:]) + tx_axis_tkeep = Signal(intbv(0)[8:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + rx_axis_tready = Signal(bool(0)) + xgmii_rxd = Signal(intbv(0x0707070707070707)[64:]) + xgmii_rxc = Signal(intbv(0xff)[8:]) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[64:]) + rx_axis_tkeep = Signal(intbv(0)[8:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) + xgmii_txc = Signal(intbv(0xff)[8:]) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + + # sources and sinks + xgmii_source_queue = Queue() + xgmii_sink_queue = Queue() + axis_source_queue = Queue() + axis_source_pause = Signal(bool(0)) + axis_sink_queue = Queue() + + xgmii_source = xgmii_ep.XGMIISource(rx_clk, + rx_rst, + txd=xgmii_rxd, + txc=xgmii_rxc, + fifo=xgmii_source_queue, + name='xgmii_source') + + xgmii_sink = xgmii_ep.XGMIISink(tx_clk, + tx_rst, + rxd=xgmii_txd, + rxc=xgmii_txc, + fifo=xgmii_sink_queue, + name='xgmii_sink') + + axis_source = axis_ep.AXIStreamSource(tx_clk, + tx_rst, + tdata=tx_axis_tdata, + tkeep=tx_axis_tkeep, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + fifo=axis_source_queue, + pause=axis_source_pause, + name='axis_source') + + axis_sink = axis_ep.AXIStreamSink(rx_clk, + rx_rst, + tdata=rx_axis_tdata, + tkeep=rx_axis_tkeep, + tvalid=rx_axis_tvalid, + tready=rx_axis_tready, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + fifo=axis_sink_queue, + name='axis_sink') + + # DUT + dut = dut_eth_mac_1g(clk, + rst, + current_test, + + rx_clk, + rx_rst, + tx_clk, + tx_rst, + logic_clk, + logic_rst, + + tx_axis_tdata, + tx_axis_tkeep, + tx_axis_tvalid, + tx_axis_tready, + tx_axis_tlast, + tx_axis_tuser, + + rx_axis_tdata, + rx_axis_tkeep, + rx_axis_tvalid, + rx_axis_tready, + rx_axis_tlast, + rx_axis_tuser, + + xgmii_rxd, + xgmii_rxc, + + xgmii_txd, + xgmii_txc, + + rx_error_bad_frame, + rx_error_bad_fcs, + + ifg_delay) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + tx_clk.next = not tx_clk + rx_clk.next = not rx_clk + logic_clk.next = not logic_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + tx_rst.next = 1 + rx_rst.next = 1 + logic_rst.next = 1 + yield clk.posedge + rst.next = 0 + tx_rst.next = 0 + rx_rst.next = 0 + logic_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + yield clk.posedge + yield clk.posedge + + while xgmii_rxc != 0xff: + yield clk.posedge + + yield delay(100) + + while rx_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not axis_sink_queue.empty(): + rx_frame = axis_sink_queue.get() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source_queue.put(axis_frame) + yield clk.posedge + yield clk.posedge + + while tx_axis_tvalid: + yield clk.posedge + + yield delay(100) + + while xgmii_txc != 0xff: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not xgmii_sink_queue.empty(): + rx_frame = xgmii_sink_queue.get() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return dut, axis_source, axis_sink, xgmii_source, xgmii_sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_10g_fifo.v b/tb/test_eth_mac_10g_fifo.v new file mode 100644 index 000000000..41676323a --- /dev/null +++ b/tb/test_eth_mac_10g_fifo.v @@ -0,0 +1,145 @@ +/* + +Copyright (c) 2015 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 + +/* + * Testbench for eth_mac_10g_fifo + */ +module test_eth_mac_10g_fifo; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; +parameter MIN_FRAME_LENGTH = 64; +parameter TX_FIFO_ADDR_WIDTH = 9; +parameter RX_FIFO_ADDR_WIDTH = 9; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg rx_clk = 0; +reg rx_rst = 0; +reg tx_clk = 0; +reg tx_rst = 0; +reg logic_clk = 0; +reg logic_rst = 0; +reg [63:0] tx_axis_tdata = 0; +reg [7:0] tx_axis_tkeep = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg rx_axis_tready = 0; +reg [63:0] xgmii_rxd = 0; +reg [7:0] xgmii_rxc = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [63:0] rx_axis_tdata; +wire [7:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire [63:0] xgmii_txd; +wire [7:0] xgmii_txc; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + rx_clk, + rx_rst, + tx_clk, + tx_rst, + logic_clk, + logic_rst, + tx_axis_tdata, + tx_axis_tkeep, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + rx_axis_tready, + xgmii_rxd, + xgmii_rxc, + ifg_delay); + $to_myhdl(tx_axis_tready, + rx_axis_tdata, + rx_axis_tkeep, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + xgmii_txd, + xgmii_txc, + rx_error_bad_frame, + rx_error_bad_fcs); + + // dump file + $dumpfile("test_eth_mac_10g_fifo.lxt"); + $dumpvars(0, test_eth_mac_10g_fifo); +end + +eth_mac_10g_fifo #( + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .TX_FIFO_ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .RX_FIFO_ADDR_WIDTH(RX_FIFO_ADDR_WIDTH) +) +UUT ( + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .logic_clk(logic_clk), + .logic_rst(logic_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +endmodule From bf0571332db328ecf30a8d01305986d4540707d4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 00:12:09 -0700 Subject: [PATCH 206/617] Update readme --- README.md | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7fa37cd4a..475475a1f 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,10 @@ Can be generated with arbitrary port counts with eth_demux_64.py. Gigabit Ethernet MAC with GMII interface. +### eth_mac_1g_fifo module + +Gigabit Ethernet MAC with GMII interface and FIFOs. + ### eth_mac_1g_rx module Gigabit Ethernet MAC RX with GMII interface. @@ -123,6 +127,22 @@ Gigabit Ethernet MAC RX with GMII interface. Gigabit Ethernet MAC TX with GMII interface. +### eth_mac_10g module + +10G Ethernet MAC with XGMII interface. + +### eth_mac_10g_fifo module + +10G Ethernet MAC with XGMII interface and FIFOs. + +### eth_mac_10g_rx module + +10G Ethernet MAC RX with XGMII interface. + +### eth_mac_10g_tx module + +10G Ethernet MAC TX with XGMII interface. + ### eth_mux_N module Ethernet frame muliplexer with 8 bit data width for gigabit Ethernet. @@ -137,6 +157,10 @@ priority and round-robin arbitration. Can be generated with arbitrary port counts with eth_mux_64.py. +### gmii_phy_if + +GMII PHY interface and clocking logic. + ### ip module IPv4 block with 8 bit data width for gigabit Ethernet. Manages IPv4 packet @@ -342,15 +366,21 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/eth_demux_4.v : 4 port Ethernet frame demultiplexer rtl/eth_demux_64.py : Ethernet frame demultiplexer generator (64 bit) rtl/eth_demux_64_4.v : 4 port Ethernet frame demultiplexer (64 bit) - rtl/eth_mac_1g.v : Gigabit Etherent MAC - rtl/eth_mac_1g_rx.v : Gigabit Etherent MAC RX - rtl/eth_mac_1g_tx.v : Gigabit Etherent MAC TX + rtl/eth_mac_1g.v : Gigabit Etherent GMII MAC + rtl/eth_mac_1g_fifo.v : Gigabit Etherent GMII MAC with FIFO + rtl/eth_mac_1g_rx.v : Gigabit Etherent GMII MAC RX + rtl/eth_mac_1g_tx.v : Gigabit Etherent GMII MAC TX + rtl/eth_mac_10g.v : 10G Etherent XGMII MAC + rtl/eth_mac_10g_fifo.v : 10G Etherent XGMII MAC with FIFO + rtl/eth_mac_10g_rx.v : 10G Etherent XGMII MAC RX + rtl/eth_mac_10g_tx.v : 10G Etherent XGMII MAC TX rtl/eth_mux.py : Ethernet frame multiplexer generator rtl/eth_mux_2.v : 4 port Ethernet frame multiplexer rtl/eth_mux_4.v : 4 port Ethernet frame multiplexer rtl/eth_mux_64.py : Ethernet frame multiplexer generator (64 bit) rtl/eth_mux_64_2.v : 4 port Ethernet frame multiplexer (64 bit) rtl/eth_mux_64_4.v : 4 port Ethernet frame multiplexer (64 bit) + rtl/gmii_phy_if.v : GMII PHY interface rtl/ip.v : IPv4 block rtl/ip_64.v : IPv4 block (64 bit) rtl/ip_arb_mux.py : IP frame arbitrated multiplexer generator @@ -489,3 +519,4 @@ individual test scripts can be run with python directly. tb/gmii_ep.py : MyHDL GMII endpoints tb/ip_ep.py : MyHDL IP frame endpoints tb/udp_ep.py : MyHDL UDP frame endpoints + tb/xgmii_ep.py : MyHDL XGMII endpoints From 6a012c992b60b9bbb581d5f2985d35e52646534e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 00:45:27 -0700 Subject: [PATCH 207/617] Update example design to use FIFO wrapper --- example/ATLYS/fpga/fpga/Makefile | 1 + example/ATLYS/fpga/rtl/fpga_core.v | 105 ++++++------------------ example/ATLYS/fpga/tb/test_fpga_core.py | 5 +- 3 files changed, 27 insertions(+), 84 deletions(-) diff --git a/example/ATLYS/fpga/fpga/Makefile b/example/ATLYS/fpga/fpga/Makefile index aed16c07f..ed7fe28bc 100644 --- a/example/ATLYS/fpga/fpga/Makefile +++ b/example/ATLYS/fpga/fpga/Makefile @@ -16,6 +16,7 @@ SYN_FILES += rtl/debounce_switch.v SYN_FILES += rtl/sync_reset.v SYN_FILES += rtl/sync_signal.v SYN_FILES += lib/eth/rtl/gmii_phy_if.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index aedb04de3..60ee25928 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -79,9 +79,10 @@ wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; -// AXI between MAC and FIFO +// AXI between MAC and Ethernet modules wire [7:0] rx_axis_tdata; wire rx_axis_tvalid; +wire rx_axis_tready; wire rx_axis_tlast; wire rx_axis_tuser; @@ -89,19 +90,7 @@ wire [7:0] tx_axis_tdata; wire tx_axis_tvalid; wire tx_axis_tready; wire tx_axis_tlast; - -// AXI between FIFO and Ethernet modules -wire [7:0] rx_fifo_axis_tdata; -wire rx_fifo_axis_tvalid; -wire rx_fifo_axis_tready; -wire rx_fifo_axis_tlast; -wire rx_fifo_axis_tuser = 0; - -wire [7:0] tx_fifo_axis_tdata; -wire tx_fifo_axis_tvalid; -wire tx_fifo_axis_tready; -wire tx_fifo_axis_tlast; -wire tx_fifo_axis_tuser; +wire tx_axis_tuser; // Ethernet frame between Ethernet modules and UDP stack wire rx_eth_hdr_ready; @@ -350,101 +339,53 @@ gmii_phy_if_inst ( .phy_gmii_tx_er(phy_tx_er) ); -eth_mac_1g #( +eth_mac_1g_fifo #( .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64) ) -eth_mac_1g_inst ( +eth_mac_1g_fifo_inst ( .rx_clk(gmii_rx_clk), .rx_rst(gmii_rx_rst), .tx_clk(gmii_tx_clk), .tx_rst(gmii_tx_rst), + .logic_clk(clk), + .logic_rst(rst), .tx_axis_tdata(tx_axis_tdata), .tx_axis_tvalid(tx_axis_tvalid), .tx_axis_tready(tx_axis_tready), .tx_axis_tlast(tx_axis_tlast), - .tx_axis_tuser(0), - + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), .rx_axis_tlast(rx_axis_tlast), .rx_axis_tuser(rx_axis_tuser), - + .gmii_rxd(gmii_rxd), .gmii_rx_dv(gmii_rx_dv), .gmii_rx_er(gmii_rx_er), .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), - + .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), - + .ifg_delay(12) ); -axis_async_frame_fifo #( - .ADDR_WIDTH(12), - .DATA_WIDTH(8), - .DROP_WHEN_FULL(1) -) -rx_fifo ( - // AXI input - .input_clk(gmii_rx_clk), - .input_rst(gmii_rx_rst), - - .input_axis_tdata(rx_axis_tdata), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), - - // AXI output - .output_clk(clk), - .output_rst(rst), - - .output_axis_tdata(rx_fifo_axis_tdata), - .output_axis_tvalid(rx_fifo_axis_tvalid), - .output_axis_tready(rx_fifo_axis_tready), - .output_axis_tlast(rx_fifo_axis_tlast) -); - -axis_async_frame_fifo #( - .ADDR_WIDTH(12), - .DATA_WIDTH(8) -) -tx_fifo ( - // AXI input - .input_clk(clk), - .input_rst(rst), - - .input_axis_tdata(tx_fifo_axis_tdata), - .input_axis_tvalid(tx_fifo_axis_tvalid), - .input_axis_tready(tx_fifo_axis_tready), - .input_axis_tlast(tx_fifo_axis_tlast), - .input_axis_tuser(tx_fifo_axis_tuser), - - // AXI output - .output_clk(gmii_tx_clk), - .output_rst(gmii_tx_rst), - - .output_axis_tdata(tx_axis_tdata), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast) -); - eth_axis_rx eth_axis_rx_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_fifo_axis_tdata), - .input_axis_tvalid(rx_fifo_axis_tvalid), - .input_axis_tready(rx_fifo_axis_tready), - .input_axis_tlast(rx_fifo_axis_tlast), - .input_axis_tuser(rx_fifo_axis_tuser), + .input_axis_tdata(rx_axis_tdata), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), // Ethernet frame output .output_eth_hdr_valid(rx_eth_hdr_valid), .output_eth_hdr_ready(rx_eth_hdr_ready), @@ -477,11 +418,11 @@ eth_axis_tx_inst ( .input_eth_payload_tlast(tx_eth_payload_tlast), .input_eth_payload_tuser(tx_eth_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_axis_tdata), - .output_axis_tvalid(tx_fifo_axis_tvalid), - .output_axis_tready(tx_fifo_axis_tready), - .output_axis_tlast(tx_fifo_axis_tlast), - .output_axis_tuser(tx_fifo_axis_tuser), + .output_axis_tdata(tx_axis_tdata), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), // Status signals .busy() ); diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index 5f99b9845..ea14d21b0 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -42,6 +42,7 @@ srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../lib/eth/rtl/gmii_phy_if.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_1g.v") srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") @@ -256,7 +257,7 @@ def bench(): rx_frame = gmii_sink_queue.get(False) check_eth_frame = eth_ep.EthFrame() - check_eth_frame.parse_axis_fcs(bytearray(rx_frame)[8:]) + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = arp_ep.ARPFrame() check_frame.parse_eth(check_eth_frame) @@ -297,7 +298,7 @@ def bench(): rx_frame = gmii_sink_queue.get(False) check_eth_frame = eth_ep.EthFrame() - check_eth_frame.parse_axis_fcs(bytearray(rx_frame)[8:]) + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = udp_ep.UDPFrame() check_frame.parse_eth(check_eth_frame) From 51e65f5a22774cf2223145b59d36acb7fb8187e2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 01:41:35 -0700 Subject: [PATCH 208/617] Rework async FIFO resets and synchronization --- rtl/axis_async_fifo.v | 76 ++++++++++++++++++++++++---------- rtl/axis_async_fifo_64.v | 76 ++++++++++++++++++++++++---------- rtl/axis_async_frame_fifo.v | 76 ++++++++++++++++++++++++---------- rtl/axis_async_frame_fifo_64.v | 76 ++++++++++++++++++++++++---------- 4 files changed, 216 insertions(+), 88 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index f52e04121..31a3f9338 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -65,10 +65,13 @@ reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; + +reg input_rst_sync1 = 1; +reg input_rst_sync2 = 1; +reg output_rst_sync1 = 1; +reg output_rst_sync2 = 1; reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}}; @@ -83,11 +86,11 @@ wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axi // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync3[ADDR_WIDTH]) && - (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync3[ADDR_WIDTH-1]) && - (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync3[ADDR_WIDTH-2:0])); +wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync2[ADDR_WIDTH]) && + (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync2[ADDR_WIDTH-1]) && + (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2[ADDR_WIDTH-2:0])); // empty when pointers match exactly -wire empty = rd_ptr_gray == wr_ptr_gray_sync3; +wire empty = rd_ptr_gray == wr_ptr_gray_sync2; wire write = input_axis_tvalid & ~full; wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; @@ -97,9 +100,30 @@ assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = data_out_reg; assign input_axis_tready = ~full; assign output_axis_tvalid = output_axis_tvalid_reg; +// reset synchronization +always @(posedge input_clk or posedge input_rst or posedge output_rst) begin + if (input_rst | output_rst) begin + input_rst_sync1 <= 1; + input_rst_sync2 <= 1; + end else begin + input_rst_sync1 <= 0; + input_rst_sync2 <= input_rst_sync1; + end +end + +always @(posedge output_clk or posedge input_rst or posedge output_rst) begin + if (input_rst | output_rst) begin + output_rst_sync1 <= 1; + output_rst_sync2 <= 1; + end else begin + output_rst_sync1 <= 0; + output_rst_sync2 <= output_rst_sync1; + end +end + // write -always @(posedge input_clk or posedge input_rst) begin - if (input_rst) begin +always @(posedge input_clk or posedge input_rst_sync2) begin + if (input_rst_sync2) begin wr_ptr <= 0; end else if (write) begin mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; @@ -109,16 +133,20 @@ always @(posedge input_clk or posedge input_rst) begin end end -// pointer synchronization in SRL16 -always @(posedge input_clk) begin - rd_ptr_gray_sync1 <= rd_ptr_gray; - rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; - rd_ptr_gray_sync3 <= rd_ptr_gray_sync2; +// pointer synchronization +always @(posedge input_clk or posedge input_rst_sync2) begin + if (input_rst_sync2) begin + rd_ptr_gray_sync1 <= 0; + rd_ptr_gray_sync2 <= 0; + end else begin + rd_ptr_gray_sync1 <= rd_ptr_gray; + rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + end end // read -always @(posedge output_clk or posedge output_rst) begin - if (output_rst) begin +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin rd_ptr <= 0; end else if (read) begin data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; @@ -128,16 +156,20 @@ always @(posedge output_clk or posedge output_rst) begin end end -// pointer synchronization in SRL16 -always @(posedge output_clk) begin - wr_ptr_gray_sync1 <= wr_ptr_gray; - wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; - wr_ptr_gray_sync3 <= wr_ptr_gray_sync2; +// pointer synchronization +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin + wr_ptr_gray_sync1 <= 0; + wr_ptr_gray_sync2 <= 0; + end else begin + wr_ptr_gray_sync1 <= wr_ptr_gray; + wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; + end end // source ready output -always @(posedge output_clk or posedge output_rst) begin - if (output_rst) begin +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin output_axis_tvalid_reg <= ~empty; diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index baf3bf406..da1060b48 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -68,10 +68,13 @@ reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; + +reg input_rst_sync1 = 1; +reg input_rst_sync2 = 1; +reg output_rst_sync1 = 1; +reg output_rst_sync2 = 1; reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; @@ -86,11 +89,11 @@ wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync3[ADDR_WIDTH]) && - (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync3[ADDR_WIDTH-1]) && - (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync3[ADDR_WIDTH-2:0])); +wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync2[ADDR_WIDTH]) && + (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync2[ADDR_WIDTH-1]) && + (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2[ADDR_WIDTH-2:0])); // empty when pointers match exactly -wire empty = rd_ptr_gray == wr_ptr_gray_sync3; +wire empty = rd_ptr_gray == wr_ptr_gray_sync2; wire write = input_axis_tvalid & ~full; wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; @@ -100,9 +103,30 @@ assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tda assign input_axis_tready = ~full; assign output_axis_tvalid = output_axis_tvalid_reg; +// reset synchronization +always @(posedge input_clk or posedge input_rst or posedge output_rst) begin + if (input_rst | output_rst) begin + input_rst_sync1 <= 1; + input_rst_sync2 <= 1; + end else begin + input_rst_sync1 <= 0; + input_rst_sync2 <= input_rst_sync1; + end +end + +always @(posedge output_clk or posedge input_rst or posedge output_rst) begin + if (input_rst | output_rst) begin + output_rst_sync1 <= 1; + output_rst_sync2 <= 1; + end else begin + output_rst_sync1 <= 0; + output_rst_sync2 <= output_rst_sync1; + end +end + // write -always @(posedge input_clk or posedge input_rst) begin - if (input_rst) begin +always @(posedge input_clk or posedge input_rst_sync2) begin + if (input_rst_sync2) begin wr_ptr <= 0; end else if (write) begin mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; @@ -112,16 +136,20 @@ always @(posedge input_clk or posedge input_rst) begin end end -// pointer synchronization in SRL16 -always @(posedge input_clk) begin - rd_ptr_gray_sync1 <= rd_ptr_gray; - rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; - rd_ptr_gray_sync3 <= rd_ptr_gray_sync2; +// pointer synchronization +always @(posedge input_clk or posedge input_rst_sync2) begin + if (input_rst_sync2) begin + rd_ptr_gray_sync1 <= 0; + rd_ptr_gray_sync2 <= 0; + end else begin + rd_ptr_gray_sync1 <= rd_ptr_gray; + rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + end end // read -always @(posedge output_clk or posedge output_rst) begin - if (output_rst) begin +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin rd_ptr <= 0; end else if (read) begin data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; @@ -131,16 +159,20 @@ always @(posedge output_clk or posedge output_rst) begin end end -// pointer synchronization in SRL16 -always @(posedge output_clk) begin - wr_ptr_gray_sync1 <= wr_ptr_gray; - wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; - wr_ptr_gray_sync3 <= wr_ptr_gray_sync2; +// pointer synchronization +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin + wr_ptr_gray_sync1 <= 0; + wr_ptr_gray_sync2 <= 0; + end else begin + wr_ptr_gray_sync1 <= wr_ptr_gray; + wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; + end end // source ready output -always @(posedge output_clk or posedge output_rst) begin - if (output_rst) begin +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin output_axis_tvalid_reg <= ~empty; diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 8b86c7890..46d43ab7f 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -66,10 +66,13 @@ reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; + +reg input_rst_sync1 = 1; +reg input_rst_sync2 = 1; +reg output_rst_sync1 = 1; +reg output_rst_sync2 = 1; reg drop_frame = 1'b0; @@ -86,11 +89,11 @@ wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tdata}; // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync3[ADDR_WIDTH]) && - (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync3[ADDR_WIDTH-1]) && - (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync3[ADDR_WIDTH-2:0])); +wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync2[ADDR_WIDTH]) && + (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync2[ADDR_WIDTH-1]) && + (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2[ADDR_WIDTH-2:0])); // empty when pointers match exactly -wire empty = rd_ptr_gray == wr_ptr_gray_sync3; +wire empty = rd_ptr_gray == wr_ptr_gray_sync2; // overflow in single packet wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); @@ -103,9 +106,30 @@ assign {output_axis_tlast, output_axis_tdata} = data_out_reg; assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; +// reset synchronization +always @(posedge input_clk or posedge input_rst or posedge output_rst) begin + if (input_rst | output_rst) begin + input_rst_sync1 <= 1; + input_rst_sync2 <= 1; + end else begin + input_rst_sync1 <= 0; + input_rst_sync2 <= input_rst_sync1; + end +end + +always @(posedge output_clk or posedge input_rst or posedge output_rst) begin + if (input_rst | output_rst) begin + output_rst_sync1 <= 1; + output_rst_sync2 <= 1; + end else begin + output_rst_sync1 <= 0; + output_rst_sync2 <= output_rst_sync1; + end +end + // write -always @(posedge input_clk or posedge input_rst) begin - if (input_rst) begin +always @(posedge input_clk or posedge input_rst_sync2) begin + if (input_rst_sync2) begin wr_ptr <= 0; wr_ptr_cur <= 0; wr_ptr_gray <= 0; @@ -136,16 +160,20 @@ always @(posedge input_clk or posedge input_rst) begin end end -// pointer synchronization in SRL16 -always @(posedge input_clk) begin - rd_ptr_gray_sync1 <= rd_ptr_gray; - rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; - rd_ptr_gray_sync3 <= rd_ptr_gray_sync2; +// pointer synchronization +always @(posedge input_clk or posedge input_rst_sync2) begin + if (input_rst_sync2) begin + rd_ptr_gray_sync1 <= 0; + rd_ptr_gray_sync2 <= 0; + end else begin + rd_ptr_gray_sync1 <= rd_ptr_gray; + rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + end end // read -always @(posedge output_clk or posedge output_rst) begin - if (output_rst) begin +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin rd_ptr <= 0; rd_ptr_gray <= 0; end else if (read) begin @@ -156,16 +184,20 @@ always @(posedge output_clk or posedge output_rst) begin end end -// pointer synchronization in SRL16 -always @(posedge output_clk) begin - wr_ptr_gray_sync1 <= wr_ptr_gray; - wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; - wr_ptr_gray_sync3 <= wr_ptr_gray_sync2; +// pointer synchronization +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin + wr_ptr_gray_sync1 <= 0; + wr_ptr_gray_sync2 <= 0; + end else begin + wr_ptr_gray_sync1 <= wr_ptr_gray; + wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; + end end // source ready output -always @(posedge output_clk or posedge output_rst) begin - if (output_rst) begin +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin output_axis_tvalid_reg <= ~empty; diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 5fb593810..864360ea0 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -69,10 +69,13 @@ reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync3 = {ADDR_WIDTH+1{1'b0}}; + +reg input_rst_sync1 = 1; +reg input_rst_sync2 = 1; +reg output_rst_sync1 = 1; +reg output_rst_sync2 = 1; reg drop_frame = 1'b0; @@ -89,11 +92,11 @@ wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tkeep // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync3[ADDR_WIDTH]) && - (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync3[ADDR_WIDTH-1]) && - (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync3[ADDR_WIDTH-2:0])); +wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync2[ADDR_WIDTH]) && + (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync2[ADDR_WIDTH-1]) && + (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2[ADDR_WIDTH-2:0])); // empty when pointers match exactly -wire empty = rd_ptr_gray == wr_ptr_gray_sync3; +wire empty = rd_ptr_gray == wr_ptr_gray_sync2; // overflow in single packet wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); @@ -106,9 +109,30 @@ assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; +// reset synchronization +always @(posedge input_clk or posedge input_rst or posedge output_rst) begin + if (input_rst | output_rst) begin + input_rst_sync1 <= 1; + input_rst_sync2 <= 1; + end else begin + input_rst_sync1 <= 0; + input_rst_sync2 <= input_rst_sync1; + end +end + +always @(posedge output_clk or posedge input_rst or posedge output_rst) begin + if (input_rst | output_rst) begin + output_rst_sync1 <= 1; + output_rst_sync2 <= 1; + end else begin + output_rst_sync1 <= 0; + output_rst_sync2 <= output_rst_sync1; + end +end + // write -always @(posedge input_clk or posedge input_rst) begin - if (input_rst) begin +always @(posedge input_clk or posedge input_rst_sync2) begin + if (input_rst_sync2) begin wr_ptr <= 0; wr_ptr_cur <= 0; wr_ptr_gray <= 0; @@ -139,16 +163,20 @@ always @(posedge input_clk or posedge input_rst) begin end end -// pointer synchronization in SRL16 -always @(posedge input_clk) begin - rd_ptr_gray_sync1 <= rd_ptr_gray; - rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; - rd_ptr_gray_sync3 <= rd_ptr_gray_sync2; +// pointer synchronization +always @(posedge input_clk or posedge input_rst_sync2) begin + if (input_rst_sync2) begin + rd_ptr_gray_sync1 <= 0; + rd_ptr_gray_sync2 <= 0; + end else begin + rd_ptr_gray_sync1 <= rd_ptr_gray; + rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + end end // read -always @(posedge output_clk or posedge output_rst) begin - if (output_rst) begin +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin rd_ptr <= 0; rd_ptr_gray <= 0; end else if (read) begin @@ -159,16 +187,20 @@ always @(posedge output_clk or posedge output_rst) begin end end -// pointer synchronization in SRL16 -always @(posedge output_clk) begin - wr_ptr_gray_sync1 <= wr_ptr_gray; - wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; - wr_ptr_gray_sync3 <= wr_ptr_gray_sync2; +// pointer synchronization +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin + wr_ptr_gray_sync1 <= 0; + wr_ptr_gray_sync2 <= 0; + end else begin + wr_ptr_gray_sync1 <= wr_ptr_gray; + wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; + end end // source ready output -always @(posedge output_clk or posedge output_rst) begin - if (output_rst) begin +always @(posedge output_clk or posedge output_rst_sync2) begin + if (output_rst_sync2) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin output_axis_tvalid_reg <= ~empty; From 16fec34ddc2262d6206731e214698d7c3611e95b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 01:44:55 -0700 Subject: [PATCH 209/617] Default FIFO size at least 2 MTU (3000 bytes) --- rtl/eth_mac_1g_fifo.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index a92eaa7f6..f99927b7f 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -33,8 +33,8 @@ module eth_mac_1g_fifo # ( parameter ENABLE_PADDING = 1, parameter MIN_FRAME_LENGTH = 64, - parameter TX_FIFO_ADDR_WIDTH = 9, - parameter RX_FIFO_ADDR_WIDTH = 9 + parameter TX_FIFO_ADDR_WIDTH = 12, + parameter RX_FIFO_ADDR_WIDTH = 12 ) ( input wire rx_clk, From 6b23d83361b102929f520ae93e0c71563aa6044a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 01:45:42 -0700 Subject: [PATCH 210/617] Set FIFO size in example design --- example/ATLYS/fpga/rtl/fpga_core.v | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index 60ee25928..d58aa454b 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -341,7 +341,9 @@ gmii_phy_if_inst ( eth_mac_1g_fifo #( .ENABLE_PADDING(1), - .MIN_FRAME_LENGTH(64) + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .RX_FIFO_ADDR_WIDTH(12) ) eth_mac_1g_fifo_inst ( .rx_clk(gmii_rx_clk), From 5ae8eb9611cbc41844930d111311012575295f14 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 20:37:31 -0700 Subject: [PATCH 211/617] Improve ip_eth_tx_64 module timing performance --- rtl/ip_eth_tx_64.v | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 9f6e0c803..3986bbff7 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -132,7 +132,7 @@ reg flush_save; reg transfer_in_save; reg [31:0] hdr_sum_temp; -reg [15:0] hdr_sum_reg = 0, hdr_sum_next; +reg [31:0] hdr_sum_reg = 0, hdr_sum_next; reg [63:0] last_word_data_reg = 0; reg [7:0] last_word_keep_reg = 0; @@ -281,13 +281,15 @@ always @* begin if (input_ip_hdr_ready & input_ip_hdr_valid) begin store_ip_hdr = 1; - hdr_sum_temp = {4'd4, 4'd5, input_ip_dscp, input_ip_ecn} + + hdr_sum_next = {4'd4, 4'd5, input_ip_dscp, input_ip_ecn} + input_ip_length + input_ip_identification + {input_ip_flags, input_ip_fragment_offset} + - {input_ip_ttl, input_ip_protocol}; - hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; - hdr_sum_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; + {input_ip_ttl, input_ip_protocol} + + input_ip_source_ip[31:16] + + input_ip_source_ip[15: 0] + + input_ip_dest_ip[31:16] + + input_ip_dest_ip[15: 0]; input_ip_hdr_ready_next = 0; output_eth_hdr_valid_next = 1; if (output_eth_payload_tready_int) begin @@ -327,17 +329,12 @@ always @* begin output_eth_payload_tkeep_int = 8'hff; end 8'h08: begin - hdr_sum_temp = hdr_sum_reg + - ip_source_ip_reg[31:16] + - ip_source_ip_reg[15: 0] + - ip_dest_ip_reg[31:16] + - ip_dest_ip_reg[15: 0]; - hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; - hdr_sum_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; + hdr_sum_temp = hdr_sum_reg[15:0] + hdr_sum_reg[31:16]; + hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[16]; output_eth_payload_tdata_int[ 7: 0] = ip_ttl_reg; output_eth_payload_tdata_int[15: 8] = ip_protocol_reg; - output_eth_payload_tdata_int[23:16] = ~hdr_sum_next[15: 8]; - output_eth_payload_tdata_int[31:24] = ~hdr_sum_next[ 7: 0]; + output_eth_payload_tdata_int[23:16] = ~hdr_sum_temp[15: 8]; + output_eth_payload_tdata_int[31:24] = ~hdr_sum_temp[ 7: 0]; output_eth_payload_tdata_int[39:32] = ip_source_ip_reg[31:24]; output_eth_payload_tdata_int[47:40] = ip_source_ip_reg[23:16]; output_eth_payload_tdata_int[55:48] = ip_source_ip_reg[15: 8]; From 8aa5ec5118648a94f11bd61d68ef7ad9fef9fa00 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 21:06:33 -0700 Subject: [PATCH 212/617] Improve ip_eth_rx_64 module timing performance --- rtl/ip_eth_rx_64.v | 70 +++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index e0e4b9cb2..fffa2d324 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -140,9 +140,8 @@ reg transfer_in_save; reg [15:0] frame_ptr_reg = 0, frame_ptr_next; reg [31:0] hdr_sum_temp; -reg [15:0] hdr_sum_reg = 0, hdr_sum_next; -reg [15:0] hdr_sum_temp_a_reg = 0, hdr_sum_temp_a_next; -reg [15:0] hdr_sum_temp_b_reg = 0, hdr_sum_temp_b_next; +reg [31:0] hdr_sum_reg = 0, hdr_sum_next; +reg check_hdr_reg = 0, check_hdr_next; reg [63:0] last_word_data_reg = 0; reg [7:0] last_word_keep_reg = 0; @@ -295,8 +294,7 @@ always @* begin hdr_sum_temp = 0; hdr_sum_next = hdr_sum_reg; - hdr_sum_temp_a_next = hdr_sum_temp_a_reg; - hdr_sum_temp_b_next = hdr_sum_temp_b_reg; + check_hdr_next = check_hdr_reg; output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; @@ -341,41 +339,34 @@ always @* begin case (frame_ptr_reg) 8'h00: begin store_hdr_word_0 = 1; - hdr_sum_temp = input_eth_payload_tdata[15:0] + + hdr_sum_next = input_eth_payload_tdata[15:0] + input_eth_payload_tdata[31:16] + input_eth_payload_tdata[47:32] + input_eth_payload_tdata[63:48]; - hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; - hdr_sum_temp_a_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; end 8'h08: begin store_hdr_word_1 = 1; - hdr_sum_temp = input_eth_payload_tdata[15:0] + + hdr_sum_next = hdr_sum_reg + + input_eth_payload_tdata[15:0] + input_eth_payload_tdata[31:16] + input_eth_payload_tdata[47:32] + input_eth_payload_tdata[63:48]; - hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; - hdr_sum_temp_b_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; end 8'h10: begin store_hdr_word_2 = 1; - hdr_sum_temp = input_eth_payload_tdata[15:0] + - input_eth_payload_tdata[31:16] + - hdr_sum_temp_a_reg + - hdr_sum_temp_b_reg; - hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[31:16]; - hdr_sum_next = hdr_sum_temp[15:0] + hdr_sum_temp[16]; + hdr_sum_next = hdr_sum_reg + + input_eth_payload_tdata[15:0] + + input_eth_payload_tdata[31:16]; frame_ptr_next = frame_ptr_reg+4; + + // check header checksum on next cycle for improved timing + check_hdr_next = 1; + if (output_ip_version_reg != 4 || output_ip_ihl_reg != 5) begin error_invalid_header_next = 1; input_eth_payload_tready_next = shift_eth_payload_input_tready; state_next = STATE_WAIT_LAST; - end else if (hdr_sum_next != 16'hffff) begin - error_invalid_checksum_next = 1; - input_eth_payload_tready_next = shift_eth_payload_input_tready; - state_next = STATE_WAIT_LAST; end else begin - output_ip_hdr_valid_next = 1; input_eth_payload_tready_next = output_ip_payload_tready_int_early & shift_eth_payload_input_tready; state_next = STATE_READ_PAYLOAD; end @@ -417,7 +408,7 @@ always @* begin if (shift_eth_payload_tlast) begin input_eth_payload_tready_next = 0; flush_save = 1; - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg & ~check_hdr_reg; state_next = STATE_IDLE; end else begin store_last_word = 1; @@ -431,7 +422,7 @@ always @* begin output_ip_payload_tuser_int = 1; input_eth_payload_tready_next = 0; flush_save = 1; - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg & ~check_hdr_reg; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD; @@ -440,6 +431,31 @@ always @* begin end else begin state_next = STATE_READ_PAYLOAD; end + + if (check_hdr_reg) begin + check_hdr_next = 0; + + hdr_sum_temp = hdr_sum_reg[15:0] + hdr_sum_reg[31:16]; + hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[16]; + + if (hdr_sum_temp != 16'hffff) begin + // bad checksum + error_invalid_checksum_next = 1; + output_ip_payload_tvalid_int = 0; + if (shift_eth_payload_tlast & shift_eth_payload_tvalid) begin + // only one payload cycle; return to idle now + input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg & ~check_hdr_reg; + state_next = STATE_IDLE; + end else begin + // drop payload + input_eth_payload_tready_next = shift_eth_payload_input_tready; + state_next = STATE_WAIT_LAST; + end + end else begin + // good checksum; transfer header + output_ip_hdr_valid_next = 1; + end + end end STATE_READ_PAYLOAD_LAST: begin // read and discard until end of frame @@ -491,8 +507,7 @@ always @(posedge clk or posedge rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; hdr_sum_reg <= 0; - hdr_sum_temp_a_reg <= 0; - hdr_sum_temp_b_reg <= 0; + check_hdr_reg <= 0; last_word_data_reg <= 0; last_word_keep_reg <= 0; input_eth_hdr_ready_reg <= 0; @@ -529,8 +544,7 @@ always @(posedge clk or posedge rst) begin frame_ptr_reg <= frame_ptr_next; hdr_sum_reg <= hdr_sum_next; - hdr_sum_temp_a_reg <= hdr_sum_temp_a_next; - hdr_sum_temp_b_reg <= hdr_sum_temp_b_next; + check_hdr_reg <= check_hdr_next; input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; input_eth_payload_tready_reg <= input_eth_payload_tready_next; From 8b762a600912ab4108d411e4d7a30de8acd3fe67 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 May 2015 21:25:37 -0700 Subject: [PATCH 213/617] Add asserts to check for orphaned payloads --- tb/ip_ep.py | 4 ++++ tb/udp_ep.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tb/ip_ep.py b/tb/ip_ep.py index 46a63f17d..ab216fe37 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -420,6 +420,10 @@ def IPFrameSink(clk, rst, frame.payload = ip_payload_fifo.get() fifo.put(frame) + # ensure all payloads have been matched to headers + if ip_header_fifo.empty(): + assert ip_payload_fifo.empty() + if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) diff --git a/tb/udp_ep.py b/tb/udp_ep.py index c814cc4cc..aac2f1bc2 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -519,6 +519,10 @@ def UDPFrameSink(clk, rst, frame.payload = udp_payload_fifo.get() fifo.put(frame) + # ensure all payloads have been matched to headers + if udp_header_fifo.empty(): + assert udp_payload_fifo.empty() + if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) From 8fea20ef772f0581cdc6d9842acd9bd83219ec82 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 12 May 2015 16:57:14 -0700 Subject: [PATCH 214/617] Fix frame_ptr_reg width --- rtl/ip_eth_tx.v | 2 +- rtl/ip_eth_tx_64.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 0bbe2d314..911884a5d 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -123,7 +123,7 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_ip_hdr; reg store_last_word; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; reg [15:0] hdr_sum_reg = 0, hdr_sum_next; diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 3986bbff7..4b2778eaa 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -126,7 +126,7 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_ip_hdr; reg store_last_word; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; reg flush_save; reg transfer_in_save; From e65173b7ee9c77b293e9fba67f882ebdac6022be Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 12 May 2015 17:52:41 -0700 Subject: [PATCH 215/617] Add overflow, bad_frame, and good_frame status outputs to frame FIFOs --- rtl/axis_async_frame_fifo.v | 31 +++++++- rtl/axis_async_frame_fifo_64.v | 31 +++++++- rtl/axis_frame_fifo.v | 31 +++++++- rtl/axis_frame_fifo_64.v | 31 +++++++- tb/test_axis_async_frame_fifo.py | 108 ++++++++++++++++++++++++++- tb/test_axis_async_frame_fifo.v | 14 +++- tb/test_axis_async_frame_fifo_64.py | 108 ++++++++++++++++++++++++++- tb/test_axis_async_frame_fifo_64.v | 14 +++- tb/test_axis_frame_fifo.py | 108 ++++++++++++++++++++++++++- tb/test_axis_frame_fifo.v | 14 +++- tb/test_axis_frame_fifo_64.py | 110 +++++++++++++++++++++++++++- tb/test_axis_frame_fifo_64.v | 14 +++- 12 files changed, 578 insertions(+), 36 deletions(-) diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 46d43ab7f..8fdcbff84 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -55,7 +55,14 @@ module axis_async_frame_fifo # 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_tlast, + + /* + * Status + */ + output wire overflow, + output wire bad_frame, + output wire good_frame ); reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; @@ -75,14 +82,15 @@ reg output_rst_sync1 = 1; reg output_rst_sync2 = 1; reg drop_frame = 1'b0; +reg overflow_reg = 1'b0; +reg bad_frame_reg = 1'b0; +reg good_frame_reg = 1'b0; reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_read = 1'b0; - reg output_axis_tvalid_reg = 1'b0; wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tdata}; @@ -106,6 +114,10 @@ assign {output_axis_tlast, output_axis_tdata} = data_out_reg; assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; +assign overflow = overflow_reg; +assign bad_frame = bad_frame_reg; +assign good_frame = good_frame_reg; + // reset synchronization always @(posedge input_clk or posedge input_rst or posedge output_rst) begin if (input_rst | output_rst) begin @@ -134,13 +146,20 @@ always @(posedge input_clk or posedge input_rst_sync2) begin wr_ptr_cur <= 0; wr_ptr_gray <= 0; drop_frame <= 0; + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; end else if (write) begin + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end drop_frame <= 1; if (input_axis_tlast) begin wr_ptr_cur <= wr_ptr; drop_frame <= 0; + overflow_reg <= 1; end end else begin mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; @@ -149,14 +168,20 @@ always @(posedge input_clk or posedge input_rst_sync2) begin if (input_axis_tuser) begin // bad packet, reset write pointer wr_ptr_cur <= wr_ptr; + bad_frame_reg <= 1; end else begin // good packet, push new write pointer wr_ptr_next = wr_ptr_cur + 1; wr_ptr <= wr_ptr_next; wr_ptr_gray <= wr_ptr_next ^ (wr_ptr_next >> 1); + good_frame_reg <= 1; end end end + end else begin + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; end end diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 864360ea0..2a0d88d2f 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -58,7 +58,14 @@ module axis_async_frame_fifo_64 # 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_tlast, + + /* + * Status + */ + output wire overflow, + output wire bad_frame, + output wire good_frame ); reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; @@ -78,14 +85,15 @@ reg output_rst_sync1 = 1; reg output_rst_sync2 = 1; reg drop_frame = 1'b0; +reg overflow_reg = 1'b0; +reg bad_frame_reg = 1'b0; +reg good_frame_reg = 1'b0; reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_read = 1'b0; - reg output_axis_tvalid_reg = 1'b0; wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; @@ -109,6 +117,10 @@ assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; +assign overflow = overflow_reg; +assign bad_frame = bad_frame_reg; +assign good_frame = good_frame_reg; + // reset synchronization always @(posedge input_clk or posedge input_rst or posedge output_rst) begin if (input_rst | output_rst) begin @@ -137,13 +149,20 @@ always @(posedge input_clk or posedge input_rst_sync2) begin wr_ptr_cur <= 0; wr_ptr_gray <= 0; drop_frame <= 0; + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; end else if (write) begin + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end drop_frame <= 1; if (input_axis_tlast) begin wr_ptr_cur <= wr_ptr; drop_frame <= 0; + overflow_reg <= 1; end end else begin mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; @@ -152,14 +171,20 @@ always @(posedge input_clk or posedge input_rst_sync2) begin if (input_axis_tuser) begin // bad packet, reset write pointer wr_ptr_cur <= wr_ptr; + bad_frame_reg <= 1; end else begin // good packet, push new write pointer wr_ptr_next = wr_ptr_cur + 1; wr_ptr <= wr_ptr_next; wr_ptr_gray <= wr_ptr_next ^ (wr_ptr_next >> 1); + good_frame_reg <= 1; end end end + end else begin + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; end end diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 526901fc1..46819e7c7 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -54,7 +54,14 @@ module axis_frame_fifo # 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_tlast, + + /* + * Status + */ + output wire overflow, + output wire bad_frame, + output wire good_frame ); reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; @@ -62,14 +69,15 @@ reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; reg drop_frame = 1'b0; +reg overflow_reg = 1'b0; +reg bad_frame_reg = 1'b0; +reg good_frame_reg = 1'b0; reg [DATA_WIDTH+1-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_read = 1'b0; - reg output_axis_tvalid_reg = 1'b0; wire [DATA_WIDTH+1-1:0] data_in = {input_axis_tlast, input_axis_tdata}; @@ -91,19 +99,30 @@ assign {output_axis_tlast, output_axis_tdata} = data_out_reg; assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; +assign overflow = overflow_reg; +assign bad_frame = bad_frame_reg; +assign good_frame = good_frame_reg; + // write always @(posedge clk or posedge rst) begin if (rst) begin wr_ptr <= 0; wr_ptr_cur <= 0; drop_frame <= 0; + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; end else if (write) begin + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end drop_frame <= 1; if (input_axis_tlast) begin wr_ptr_cur <= wr_ptr; drop_frame <= 0; + overflow_reg <= 1; end end else begin mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; @@ -112,12 +131,18 @@ always @(posedge clk or posedge rst) begin if (input_axis_tuser) begin // bad packet, reset write pointer wr_ptr_cur <= wr_ptr; + bad_frame_reg <= 1; end else begin // good packet, push new write pointer wr_ptr <= wr_ptr_cur + 1; + good_frame_reg <= 1; end end end + end else begin + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; end end diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index 9e9d866db..a99331ad5 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -57,7 +57,14 @@ module axis_frame_fifo_64 # 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_tlast, + + /* + * Status + */ + output wire overflow, + output wire bad_frame, + output wire good_frame ); reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; @@ -65,14 +72,15 @@ reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; reg drop_frame = 1'b0; +reg overflow_reg = 1'b0; +reg bad_frame_reg = 1'b0; +reg good_frame_reg = 1'b0; reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_read = 1'b0; - reg output_axis_tvalid_reg = 1'b0; wire [DATA_WIDTH+KEEP_WIDTH+1-1:0] data_in = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; @@ -94,19 +102,30 @@ assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; +assign overflow = overflow_reg; +assign bad_frame = bad_frame_reg; +assign good_frame = good_frame_reg; + // write always @(posedge clk or posedge rst) begin if (rst) begin wr_ptr <= 0; wr_ptr_cur <= 0; drop_frame <= 0; + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; end else if (write) begin + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; if (full | full_cur | drop_frame) begin // buffer full, hold current pointer, drop packet at end drop_frame <= 1; if (input_axis_tlast) begin wr_ptr_cur <= wr_ptr; drop_frame <= 0; + overflow_reg <= 1; end end else begin mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; @@ -115,12 +134,18 @@ always @(posedge clk or posedge rst) begin if (input_axis_tuser) begin // bad packet, reset write pointer wr_ptr_cur <= wr_ptr; + bad_frame_reg <= 1; end else begin // good packet, push new write pointer wr_ptr <= wr_ptr_cur + 1; + good_frame_reg <= 1; end end end + end else begin + overflow_reg <= 0; + bad_frame_reg <= 0; + good_frame_reg <= 0; end end diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index b06a4ff9a..75c30747e 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -59,7 +59,11 @@ def dut_axis_async_frame_fifo(input_clk, output_axis_tdata, output_axis_tvalid, output_axis_tready, - output_axis_tlast): + output_axis_tlast, + + overflow, + bad_frame, + good_frame): if os.system(build_cmd): raise Exception("Error running build command") @@ -79,7 +83,11 @@ def dut_axis_async_frame_fifo(input_clk, 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_tlast=output_axis_tlast, + + overflow=overflow, + bad_frame=bad_frame, + good_frame=good_frame) def bench(): @@ -101,6 +109,9 @@ def bench(): output_axis_tdata = Signal(intbv(0)[8:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) + overflow = Signal(bool(0)) + bad_frame = Signal(bool(0)) + good_frame = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -145,7 +156,11 @@ def bench(): output_axis_tdata, output_axis_tvalid, output_axis_tready, - output_axis_tlast) + output_axis_tlast, + + overflow, + bad_frame, + good_frame) @always(delay(4)) def input_clkgen(): @@ -155,6 +170,19 @@ def bench(): def output_clkgen(): output_clk.next = not output_clk + overflow_asserted = Signal(bool(0)) + bad_frame_asserted = Signal(bool(0)) + good_frame_asserted = Signal(bool(0)) + + @always(input_clk.posedge) + def monitor(): + if (overflow): + overflow_asserted.next = 1 + if (bad_frame): + bad_frame_asserted.next = 1 + if (good_frame): + good_frame_asserted.next = 1 + @instance def check(): yield delay(100) @@ -180,6 +208,11 @@ def bench(): 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') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield input_clk.posedge @@ -193,6 +226,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -203,6 +240,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield input_clk.posedge @@ -216,6 +258,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield input_clk.posedge print("test 3: test packet with pauses") current_test.next = 3 @@ -224,6 +270,11 @@ def bench(): 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') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield input_clk.posedge @@ -251,6 +302,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -265,6 +320,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield input_clk.posedge @@ -287,6 +347,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -301,6 +365,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield input_clk.posedge @@ -332,6 +401,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -346,6 +419,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield input_clk.posedge @@ -373,6 +451,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -384,6 +466,11 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield input_clk.posedge @@ -391,6 +478,10 @@ def bench(): assert sink_queue.empty() + assert not overflow_asserted + assert bad_frame_asserted + assert not good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -401,6 +492,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))*2) + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield input_clk.posedge @@ -408,11 +504,15 @@ def bench(): assert sink_queue.empty() + assert overflow_asserted + assert not bad_frame_asserted + assert not good_frame_asserted + yield delay(100) raise StopSimulation - return dut, source, sink, input_clkgen, output_clkgen, check + return dut, monitor, source, sink, input_clkgen, output_clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index c41570cb0..2c603d750 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -46,6 +46,9 @@ wire input_axis_tready; wire [7:0] output_axis_tdata; wire output_axis_tvalid; wire output_axis_tlast; +wire overflow; +wire bad_frame; +wire good_frame; initial begin // myhdl integration @@ -62,7 +65,10 @@ initial begin $to_myhdl(input_axis_tready, output_axis_tdata, output_axis_tvalid, - output_axis_tlast); + output_axis_tlast, + overflow, + bad_frame, + good_frame); // dump file $dumpfile("test_axis_async_frame_fifo.lxt"); @@ -89,7 +95,11 @@ UUT ( .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_tlast(output_axis_tlast), + // Status + .overflow(overflow), + .bad_frame(bad_frame), + .good_frame(good_frame) ); endmodule diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index f0f9f6ea5..5f0fb2b2c 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -61,7 +61,11 @@ def dut_axis_async_frame_fifo_64(input_clk, output_axis_tkeep, output_axis_tvalid, output_axis_tready, - output_axis_tlast): + output_axis_tlast, + + overflow, + bad_frame, + good_frame): if os.system(build_cmd): raise Exception("Error running build command") @@ -83,7 +87,11 @@ def dut_axis_async_frame_fifo_64(input_clk, 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_tlast=output_axis_tlast, + + overflow=overflow, + bad_frame=bad_frame, + good_frame=good_frame) def bench(): @@ -107,6 +115,9 @@ def bench(): output_axis_tkeep = Signal(intbv(0)[8:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) + overflow = Signal(bool(0)) + bad_frame = Signal(bool(0)) + good_frame = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -155,7 +166,11 @@ def bench(): output_axis_tkeep, output_axis_tvalid, output_axis_tready, - output_axis_tlast) + output_axis_tlast, + + overflow, + bad_frame, + good_frame) @always(delay(4)) def input_clkgen(): @@ -165,6 +180,19 @@ def bench(): def output_clkgen(): output_clk.next = not output_clk + overflow_asserted = Signal(bool(0)) + bad_frame_asserted = Signal(bool(0)) + good_frame_asserted = Signal(bool(0)) + + @always(input_clk.posedge) + def monitor(): + if (overflow): + overflow_asserted.next = 1 + if (bad_frame): + bad_frame_asserted.next = 1 + if (good_frame): + good_frame_asserted.next = 1 + @instance def check(): yield delay(100) @@ -190,6 +218,11 @@ def bench(): 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') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield input_clk.posedge @@ -203,6 +236,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -213,6 +250,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield input_clk.posedge @@ -226,6 +268,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield input_clk.posedge print("test 3: test packet with pauses") current_test.next = 3 @@ -234,6 +280,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield input_clk.posedge @@ -261,6 +312,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -275,6 +330,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield input_clk.posedge @@ -297,6 +357,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -311,6 +375,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield input_clk.posedge @@ -342,6 +411,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -356,6 +429,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield input_clk.posedge @@ -383,6 +461,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -394,6 +476,11 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield input_clk.posedge @@ -401,6 +488,10 @@ def bench(): assert sink_queue.empty() + assert not overflow_asserted + assert bad_frame_asserted + assert not good_frame_asserted + yield delay(100) yield input_clk.posedge @@ -411,6 +502,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))*2) + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield input_clk.posedge @@ -418,11 +514,15 @@ def bench(): assert sink_queue.empty() + assert overflow_asserted + assert not bad_frame_asserted + assert not good_frame_asserted + yield delay(100) raise StopSimulation - return dut, source, sink, input_clkgen, output_clkgen, check + return dut, monitor, source, sink, input_clkgen, output_clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index f9249e7dc..6ba39b210 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -48,6 +48,9 @@ wire [63:0] output_axis_tdata; wire [7:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; +wire overflow; +wire bad_frame; +wire good_frame; initial begin // myhdl integration @@ -66,7 +69,10 @@ initial begin output_axis_tdata, output_axis_tkeep, output_axis_tvalid, - output_axis_tlast); + output_axis_tlast, + overflow, + bad_frame, + good_frame); // dump file $dumpfile("test_axis_async_frame_fifo_64.lxt"); @@ -95,7 +101,11 @@ UUT ( .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_tlast(output_axis_tlast), + // Status + .overflow(overflow), + .bad_frame(bad_frame), + .good_frame(good_frame) ); endmodule diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index d228e41e1..84868e765 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -57,7 +57,11 @@ def dut_axis_frame_fifo(clk, output_axis_tdata, output_axis_tvalid, output_axis_tready, - output_axis_tlast): + output_axis_tlast, + + overflow, + bad_frame, + good_frame): if os.system(build_cmd): raise Exception("Error running build command") @@ -75,7 +79,11 @@ def dut_axis_frame_fifo(clk, 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_tlast=output_axis_tlast, + + overflow=overflow, + bad_frame=bad_frame, + good_frame=good_frame) def bench(): @@ -95,6 +103,9 @@ def bench(): output_axis_tdata = Signal(intbv(0)[8:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) + overflow = Signal(bool(0)) + bad_frame = Signal(bool(0)) + good_frame = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -137,12 +148,29 @@ def bench(): output_axis_tdata, output_axis_tvalid, output_axis_tready, - output_axis_tlast) + output_axis_tlast, + + overflow, + bad_frame, + good_frame) @always(delay(4)) def clkgen(): clk.next = not clk + overflow_asserted = Signal(bool(0)) + bad_frame_asserted = Signal(bool(0)) + good_frame_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (overflow): + overflow_asserted.next = 1 + if (bad_frame): + bad_frame_asserted.next = 1 + if (good_frame): + good_frame_asserted.next = 1 + @instance def check(): yield delay(100) @@ -164,6 +192,11 @@ def bench(): 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') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield clk.posedge @@ -177,6 +210,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield clk.posedge @@ -187,6 +224,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield clk.posedge @@ -200,6 +242,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield clk.posedge print("test 3: test packet with pauses") current_test.next = 3 @@ -208,6 +254,11 @@ def bench(): 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') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield clk.posedge @@ -235,6 +286,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield clk.posedge @@ -249,6 +304,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield clk.posedge @@ -271,6 +331,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield clk.posedge @@ -285,6 +349,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield clk.posedge @@ -312,6 +381,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield clk.posedge @@ -326,6 +399,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield clk.posedge @@ -353,6 +431,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield clk.posedge @@ -364,6 +446,11 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield clk.posedge @@ -371,6 +458,10 @@ def bench(): assert sink_queue.empty() + assert not overflow_asserted + assert bad_frame_asserted + assert not good_frame_asserted + yield delay(100) yield clk.posedge @@ -381,6 +472,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))*2) + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield clk.posedge @@ -388,11 +484,15 @@ def bench(): assert sink_queue.empty() + assert overflow_asserted + assert not bad_frame_asserted + assert not good_frame_asserted + yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, monitor, source, sink, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v index d0a13fb91..9ecf98432 100644 --- a/tb/test_axis_frame_fifo.v +++ b/tb/test_axis_frame_fifo.v @@ -44,6 +44,9 @@ wire input_axis_tready; wire [7:0] output_axis_tdata; wire output_axis_tvalid; wire output_axis_tlast; +wire overflow; +wire bad_frame; +wire good_frame; initial begin // myhdl integration @@ -58,7 +61,10 @@ initial begin $to_myhdl(input_axis_tready, output_axis_tdata, output_axis_tvalid, - output_axis_tlast); + output_axis_tlast, + overflow, + bad_frame, + good_frame); // dump file $dumpfile("test_axis_frame_fifo.lxt"); @@ -83,7 +89,11 @@ UUT ( .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_tlast(output_axis_tlast), + // Status + .overflow(overflow), + .bad_frame(bad_frame), + .good_frame(good_frame) ); endmodule diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index 404eaef14..ed8524dcf 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -60,7 +60,11 @@ def dut_axis_frame_fifo_64(clk, output_axis_tvalid, output_axis_tready, output_axis_tlast, - output_axis_tuser): + output_axis_tuser, + + overflow, + bad_frame, + good_frame): if os.system(build_cmd): raise Exception("Error running build command") @@ -81,7 +85,11 @@ def dut_axis_frame_fifo_64(clk, output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) + output_axis_tuser=output_axis_tuser, + + overflow=overflow, + bad_frame=bad_frame, + good_frame=good_frame) def bench(): @@ -104,6 +112,9 @@ def bench(): output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) + overflow = Signal(bool(0)) + bad_frame = Signal(bool(0)) + good_frame = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -152,12 +163,29 @@ def bench(): output_axis_tvalid, output_axis_tready, output_axis_tlast, - output_axis_tuser) + output_axis_tuser, + + overflow, + bad_frame, + good_frame) @always(delay(4)) def clkgen(): clk.next = not clk + overflow_asserted = Signal(bool(0)) + bad_frame_asserted = Signal(bool(0)) + good_frame_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (overflow): + overflow_asserted.next = 1 + if (bad_frame): + bad_frame_asserted.next = 1 + if (good_frame): + good_frame_asserted.next = 1 + @instance def check(): yield delay(100) @@ -179,6 +207,11 @@ def bench(): 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') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield clk.posedge @@ -192,6 +225,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield clk.posedge @@ -202,6 +239,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield clk.posedge @@ -215,6 +257,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield clk.posedge print("test 3: test packet with pauses") current_test.next = 3 @@ -223,6 +269,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield clk.posedge @@ -250,6 +301,10 @@ def bench(): assert rx_frame == test_frame + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield clk.posedge @@ -264,6 +319,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield clk.posedge @@ -286,6 +346,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield clk.posedge @@ -300,6 +364,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield clk.posedge @@ -327,6 +396,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield clk.posedge @@ -341,6 +414,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame1) source_queue.put(test_frame2) yield clk.posedge @@ -368,6 +446,10 @@ def bench(): assert rx_frame == test_frame2 + assert not overflow_asserted + assert not bad_frame_asserted + assert good_frame_asserted + yield delay(100) yield clk.posedge @@ -379,6 +461,11 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield clk.posedge @@ -386,6 +473,12 @@ def bench(): assert sink_queue.empty() + assert not overflow_asserted + assert bad_frame_asserted + assert not good_frame_asserted + + yield delay(100) + yield clk.posedge print("test 8: single packet overflow") current_test.next = 8 @@ -394,6 +487,11 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))*2) + + overflow_asserted.next = 0 + bad_frame_asserted.next = 0 + good_frame_asserted.next = 0 + source_queue.put(test_frame) yield clk.posedge @@ -401,11 +499,15 @@ def bench(): assert sink_queue.empty() + assert overflow_asserted + assert not bad_frame_asserted + assert not good_frame_asserted + yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, monitor, source, sink, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v index 30d872985..e840e8538 100644 --- a/tb/test_axis_frame_fifo_64.v +++ b/tb/test_axis_frame_fifo_64.v @@ -46,6 +46,9 @@ wire [63:0] output_axis_tdata; wire [7:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; +wire overflow; +wire bad_frame; +wire good_frame; initial begin // myhdl integration @@ -62,7 +65,10 @@ initial begin output_axis_tdata, output_axis_tkeep, output_axis_tvalid, - output_axis_tlast); + output_axis_tlast, + overflow, + bad_frame, + good_frame); // dump file $dumpfile("test_axis_frame_fifo_64.lxt"); @@ -89,7 +95,11 @@ UUT ( .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_tlast(output_axis_tlast), + // Status + .overflow(overflow), + .bad_frame(bad_frame), + .good_frame(good_frame) ); endmodule From e72b93033dbc1fd5281ac718cd5f84ed55cbf6c4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 12 May 2015 17:54:37 -0700 Subject: [PATCH 216/617] Add parameters to axis_stat_counter testbench --- tb/test_axis_stat_counter.v | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v index 529495195..c8f1bdf87 100644 --- a/tb/test_axis_stat_counter.v +++ b/tb/test_axis_stat_counter.v @@ -28,6 +28,18 @@ THE SOFTWARE. module test_axis_stat_counter; +// parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter TAG_ENABLE = 1; +parameter TAG_WIDTH = 16; +parameter TICK_COUNT_ENABLE = 1; +parameter TICK_COUNT_WIDTH = 32; +parameter BYTE_COUNT_ENABLE = 1; +parameter BYTE_COUNT_WIDTH = 32; +parameter FRAME_COUNT_ENABLE = 1; +parameter FRAME_COUNT_WIDTH = 32; + // Inputs reg clk = 0; reg rst = 0; @@ -76,7 +88,16 @@ initial begin end axis_stat_counter #( - .DATA_WIDTH(64) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .TAG_ENABLE(TAG_ENABLE), + .TAG_WIDTH(TAG_WIDTH), + .TICK_COUNT_ENABLE(TICK_COUNT_ENABLE), + .TICK_COUNT_WIDTH(TICK_COUNT_WIDTH), + .BYTE_COUNT_ENABLE(BYTE_COUNT_ENABLE), + .BYTE_COUNT_WIDTH(BYTE_COUNT_WIDTH), + .FRAME_COUNT_ENABLE(FRAME_COUNT_ENABLE), + .FRAME_COUNT_WIDTH(FRAME_COUNT_WIDTH) ) UUT ( .clk(clk), From 3d17cc1cee3807411bdeca4addfd92314b6121eb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 12 May 2015 17:58:09 -0700 Subject: [PATCH 217/617] Adjust rate limiter framing logic --- rtl/axis_rate_limit.v | 2 +- rtl/axis_rate_limit_64.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index a7f113e58..cb5b733bf 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -81,7 +81,7 @@ assign input_axis_tready = input_axis_tready_reg; always @* begin acc_next = acc_reg; pause = 0; - frame_next = frame_reg & ~input_axis_tlast; + frame_next = frame_reg; if (acc_reg >= rate_num) begin acc_next = acc_reg - rate_num; diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v index e5b31ca9c..a6ce68165 100644 --- a/rtl/axis_rate_limit_64.v +++ b/rtl/axis_rate_limit_64.v @@ -85,7 +85,7 @@ assign input_axis_tready = input_axis_tready_reg; always @* begin acc_next = acc_reg; pause = 0; - frame_next = frame_reg & ~input_axis_tlast; + frame_next = frame_reg; if (acc_reg >= rate_num) begin acc_next = acc_reg - rate_num; From ec95a6055dfdaa76d2de6cbfa571f71f459904bb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 12 May 2015 19:12:23 -0700 Subject: [PATCH 218/617] Feed through and synchronize FIFO status signals --- rtl/eth_mac_10g_fifo.v | 52 +++++++++++++++++++++++++++++++++++-- rtl/eth_mac_1g_fifo.v | 52 +++++++++++++++++++++++++++++++++++-- tb/test_eth_mac_10g_fifo.py | 24 +++++++++++++++++ tb/test_eth_mac_10g_fifo.v | 20 +++++++++++++- tb/test_eth_mac_1g_fifo.py | 24 +++++++++++++++++ tb/test_eth_mac_1g_fifo.v | 20 +++++++++++++- 6 files changed, 186 insertions(+), 6 deletions(-) diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 5d1880738..302971168 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -76,8 +76,14 @@ module eth_mac_10g_fifo # /* * Status */ + output wire tx_fifo_overflow, + output wire tx_fifo_bad_frame, + output wire tx_fifo_good_frame, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, + output wire rx_fifo_overflow, + output wire rx_fifo_bad_frame, + output wire rx_fifo_good_frame, /* * Configuration @@ -98,6 +104,40 @@ wire rx_fifo_axis_tvalid; wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; +// synchronize FIFO status signals into logic clock domain (only required for RX FIFO) +wire rx_fifo_overflow_int; +wire rx_fifo_bad_frame_int; +wire rx_fifo_good_frame_int; + +reg [2:0] rx_sync_reg_1 = 0; +reg [2:0] rx_sync_reg_2 = 0; +reg [2:0] rx_sync_reg_3 = 0; +reg [2:0] rx_sync_reg_4 = 0; + +assign rx_fifo_overflow = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; +assign rx_fifo_bad_frame = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; +assign rx_fifo_good_frame = rx_sync_reg_3[2] ^ rx_sync_reg_4[2]; + +always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + rx_sync_reg_1 <= 0; + end else begin + rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_fifo_good_frame_int, rx_fifo_bad_frame_int, rx_fifo_overflow_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + rx_sync_reg_2 <= 0; + rx_sync_reg_3 <= 0; + rx_sync_reg_4 <= 0; + end else begin + rx_sync_reg_2 <= rx_sync_reg_1; + rx_sync_reg_3 <= rx_sync_reg_2; + rx_sync_reg_4 <= rx_sync_reg_3; + end +end + eth_mac_10g #( .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), @@ -150,7 +190,11 @@ tx_fifo ( .output_axis_tkeep(tx_fifo_axis_tkeep), .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), - .output_axis_tlast(tx_fifo_axis_tlast) + .output_axis_tlast(tx_fifo_axis_tlast), + // Status + .overflow(tx_fifo_overflow), + .bad_frame(tx_fifo_bad_frame), + .good_frame(tx_fifo_good_frame) ); assign tx_fifo_axis_tuser = 1'b0; @@ -177,7 +221,11 @@ rx_fifo ( .output_axis_tkeep(rx_axis_tkeep), .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), - .output_axis_tlast(rx_axis_tlast) + .output_axis_tlast(rx_axis_tlast), + // Status + .overflow(rx_fifo_overflow_int), + .bad_frame(rx_fifo_bad_frame_int), + .good_frame(rx_fifo_good_frame_int) ); assign rx_axis_tuser = 1'b0; diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index f99927b7f..6590c43c4 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -75,8 +75,14 @@ module eth_mac_1g_fifo # /* * Status */ + output wire tx_fifo_overflow, + output wire tx_fifo_bad_frame, + output wire tx_fifo_good_frame, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, + output wire rx_fifo_overflow, + output wire rx_fifo_bad_frame, + output wire rx_fifo_good_frame, /* * Configuration @@ -95,6 +101,40 @@ wire rx_fifo_axis_tvalid; wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; +// synchronize FIFO status signals into logic clock domain (only required for RX FIFO) +wire rx_fifo_overflow_int; +wire rx_fifo_bad_frame_int; +wire rx_fifo_good_frame_int; + +reg [2:0] rx_sync_reg_1 = 0; +reg [2:0] rx_sync_reg_2 = 0; +reg [2:0] rx_sync_reg_3 = 0; +reg [2:0] rx_sync_reg_4 = 0; + +assign rx_fifo_overflow = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; +assign rx_fifo_bad_frame = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; +assign rx_fifo_good_frame = rx_sync_reg_3[2] ^ rx_sync_reg_4[2]; + +always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + rx_sync_reg_1 <= 0; + end else begin + rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_fifo_good_frame_int, rx_fifo_bad_frame_int, rx_fifo_overflow_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + rx_sync_reg_2 <= 0; + rx_sync_reg_3 <= 0; + rx_sync_reg_4 <= 0; + end else begin + rx_sync_reg_2 <= rx_sync_reg_1; + rx_sync_reg_3 <= rx_sync_reg_2; + rx_sync_reg_4 <= rx_sync_reg_3; + end +end + eth_mac_1g #( .ENABLE_PADDING(ENABLE_PADDING), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) @@ -144,7 +184,11 @@ tx_fifo ( .output_axis_tdata(tx_fifo_axis_tdata), .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), - .output_axis_tlast(tx_fifo_axis_tlast) + .output_axis_tlast(tx_fifo_axis_tlast), + // Status + .overflow(tx_fifo_overflow), + .bad_frame(tx_fifo_bad_frame), + .good_frame(tx_fifo_good_frame) ); assign tx_fifo_axis_tuser = 1'b0; @@ -169,7 +213,11 @@ rx_fifo ( .output_axis_tdata(rx_axis_tdata), .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), - .output_axis_tlast(rx_axis_tlast) + .output_axis_tlast(rx_axis_tlast), + // Status + .overflow(rx_fifo_overflow_int), + .bad_frame(rx_fifo_bad_frame_int), + .good_frame(rx_fifo_good_frame_int) ); assign rx_axis_tuser = 1'b0; diff --git a/tb/test_eth_mac_10g_fifo.py b/tb/test_eth_mac_10g_fifo.py index a5f502ac5..d66815fe1 100755 --- a/tb/test_eth_mac_10g_fifo.py +++ b/tb/test_eth_mac_10g_fifo.py @@ -91,6 +91,12 @@ def dut_eth_mac_1g(clk, rx_error_bad_frame, rx_error_bad_fcs, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, ifg_delay): @@ -128,8 +134,14 @@ def dut_eth_mac_1g(clk, xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + tx_fifo_overflow=tx_fifo_overflow, + tx_fifo_bad_frame=tx_fifo_bad_frame, + tx_fifo_good_frame=tx_fifo_good_frame, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, + rx_fifo_overflow=rx_fifo_overflow, + rx_fifo_bad_frame=rx_fifo_bad_frame, + rx_fifo_good_frame=rx_fifo_good_frame, ifg_delay=ifg_delay) @@ -172,8 +184,14 @@ def bench(): rx_axis_tuser = Signal(bool(0)) xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) xgmii_txc = Signal(intbv(0xff)[8:]) + tx_fifo_overflow = Signal(bool(0)) + tx_fifo_bad_frame = Signal(bool(0)) + tx_fifo_good_frame = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) + rx_fifo_overflow = Signal(bool(0)) + rx_fifo_bad_frame = Signal(bool(0)) + rx_fifo_good_frame = Signal(bool(0)) # sources and sinks xgmii_source_queue = Queue() @@ -251,8 +269,14 @@ def bench(): xgmii_txd, xgmii_txc, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, rx_error_bad_frame, rx_error_bad_fcs, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame, ifg_delay) diff --git a/tb/test_eth_mac_10g_fifo.v b/tb/test_eth_mac_10g_fifo.v index 41676323a..2d5ac1036 100644 --- a/tb/test_eth_mac_10g_fifo.v +++ b/tb/test_eth_mac_10g_fifo.v @@ -68,8 +68,14 @@ wire rx_axis_tlast; wire rx_axis_tuser; wire [63:0] xgmii_txd; wire [7:0] xgmii_txc; +wire tx_fifo_overflow; +wire tx_fifo_bad_frame; +wire tx_fifo_good_frame; wire rx_error_bad_frame; wire rx_error_bad_fcs; +wire rx_fifo_overflow; +wire rx_fifo_bad_frame; +wire rx_fifo_good_frame; initial begin // myhdl integration @@ -99,8 +105,14 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, rx_error_bad_frame, - rx_error_bad_fcs); + rx_error_bad_fcs, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame); // dump file $dumpfile("test_eth_mac_10g_fifo.lxt"); @@ -137,8 +149,14 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .tx_fifo_overflow(tx_fifo_overflow), + .tx_fifo_bad_frame(tx_fifo_bad_frame), + .tx_fifo_good_frame(tx_fifo_good_frame), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(rx_fifo_overflow), + .rx_fifo_bad_frame(rx_fifo_bad_frame), + .rx_fifo_good_frame(rx_fifo_good_frame), .ifg_delay(ifg_delay) ); diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py index cd36feddd..32dfa3e97 100755 --- a/tb/test_eth_mac_1g_fifo.py +++ b/tb/test_eth_mac_1g_fifo.py @@ -84,6 +84,12 @@ def dut_eth_mac_1g(clk, rx_error_bad_frame, rx_error_bad_fcs, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame, ifg_delay): @@ -121,8 +127,14 @@ def dut_eth_mac_1g(clk, gmii_tx_en=gmii_tx_en, gmii_tx_er=gmii_tx_er, + tx_fifo_overflow=tx_fifo_overflow, + tx_fifo_bad_frame=tx_fifo_bad_frame, + tx_fifo_good_frame=tx_fifo_good_frame, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, + rx_fifo_overflow=rx_fifo_overflow, + rx_fifo_bad_frame=rx_fifo_bad_frame, + rx_fifo_good_frame=rx_fifo_good_frame, ifg_delay=ifg_delay) @@ -164,8 +176,14 @@ def bench(): gmii_txd = Signal(intbv(0)[8:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) + tx_fifo_overflow = Signal(bool(0)) + tx_fifo_bad_frame = Signal(bool(0)) + tx_fifo_good_frame = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) + rx_fifo_overflow = Signal(bool(0)) + rx_fifo_bad_frame = Signal(bool(0)) + rx_fifo_good_frame = Signal(bool(0)) # sources and sinks gmii_source_queue = Queue() @@ -243,8 +261,14 @@ def bench(): gmii_tx_en, gmii_tx_er, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, rx_error_bad_frame, rx_error_bad_fcs, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame, ifg_delay) diff --git a/tb/test_eth_mac_1g_fifo.v b/tb/test_eth_mac_1g_fifo.v index 500094656..b8cd0d6a8 100644 --- a/tb/test_eth_mac_1g_fifo.v +++ b/tb/test_eth_mac_1g_fifo.v @@ -67,8 +67,14 @@ wire rx_axis_tuser; wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; +wire tx_fifo_overflow; +wire tx_fifo_bad_frame; +wire tx_fifo_good_frame; wire rx_error_bad_frame; wire rx_error_bad_fcs; +wire rx_fifo_overflow; +wire rx_fifo_bad_frame; +wire rx_fifo_good_frame; initial begin // myhdl integration @@ -98,8 +104,14 @@ initial begin gmii_txd, gmii_tx_en, gmii_tx_er, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, rx_error_bad_frame, - rx_error_bad_fcs); + rx_error_bad_fcs, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame); // dump file $dumpfile("test_eth_mac_1g_fifo.lxt"); @@ -135,8 +147,14 @@ UUT ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .tx_fifo_overflow(tx_fifo_overflow), + .tx_fifo_bad_frame(tx_fifo_bad_frame), + .tx_fifo_good_frame(tx_fifo_good_frame), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(rx_fifo_overflow), + .rx_fifo_bad_frame(rx_fifo_bad_frame), + .rx_fifo_good_frame(rx_fifo_good_frame), .ifg_delay(ifg_delay) ); From 15edfa0f85492d491c5bc78c530fbce0b229a06d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 16 May 2015 22:32:02 -0700 Subject: [PATCH 219/617] Add missing initialize --- rtl/eth_mac_10g_tx.v | 1 + 1 file changed, 1 insertion(+) diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 3d416d05d..6abf04fc2 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -303,6 +303,7 @@ always @* begin frame_ptr_next = frame_ptr_reg; ifg_count_next = ifg_count_reg; + deficit_idle_count_next = deficit_idle_count_reg; last_cycle_txd_next = last_cycle_txd_reg; last_cycle_txc_next = last_cycle_txc_reg; From 0352d550843c18c0435af6690e83715740054d8c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 16 May 2015 22:34:29 -0700 Subject: [PATCH 220/617] Add default case --- rtl/eth_mac_10g_rx.v | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index 523907087..d50c3c69c 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -285,6 +285,9 @@ always @* begin 8'b10000000: begin detect_error_masked = detect_error[6:0]; end + default: begin + detect_error_masked = detect_error; + end endcase end From 14a2caa9941ce8e193ab2e1acec68bba3852323e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 17 May 2015 01:39:59 -0700 Subject: [PATCH 221/617] Rework 10G ethernet MAC TX to add input register --- rtl/eth_mac_10g_tx.v | 163 +++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 93 deletions(-) diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 6abf04fc2..32c1b64ac 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -65,8 +65,9 @@ localparam [2:0] STATE_IDLE = 3'd0, STATE_PAYLOAD = 3'd1, STATE_PAD = 3'd2, - STATE_FCS = 3'd3, - STATE_IFG = 3'd4; + STATE_FCS_1 = 3'd3, + STATE_FCS_2 = 3'd4, + STATE_IFG = 3'd5; reg [2:0] state_reg = STATE_IDLE, state_next; @@ -83,8 +84,8 @@ reg [3:0] swap_txc = 0; reg [63:0] input_axis_tdata_masked; -reg [63:0] fcs_input_tdata; -reg [7:0] fcs_input_tkeep; +reg [63:0] input_tdata_reg = 0, input_tdata_next; +reg [7:0] input_tkeep_reg = 0, input_tkeep_next; reg [63:0] fcs_output_txd_0; reg [63:0] fcs_output_txd_1; @@ -98,9 +99,6 @@ reg [7:0] frame_ptr_reg = 0, frame_ptr_next; reg [7:0] ifg_count_reg = 0, ifg_count_next; reg [1:0] deficit_idle_count_reg = 0, deficit_idle_count_next; -reg [63:0] last_cycle_txd_reg = 0, last_cycle_txd_next; -reg [7:0] last_cycle_txc_reg = 0, last_cycle_txc_next; - reg busy_reg = 0; reg input_axis_tready_reg = 0, input_axis_tready_next; @@ -126,56 +124,56 @@ assign xgmii_txc = xgmii_txc_reg; eth_crc_8 eth_crc_8_inst ( - .data_in(fcs_input_tdata[7:0]), + .data_in(input_tdata_reg[7:0]), .crc_state(crc_state), .crc_next(crc_next0) ); eth_crc_16 eth_crc_16_inst ( - .data_in(fcs_input_tdata[15:0]), + .data_in(input_tdata_reg[15:0]), .crc_state(crc_state), .crc_next(crc_next1) ); eth_crc_24 eth_crc_24_inst ( - .data_in(fcs_input_tdata[23:0]), + .data_in(input_tdata_reg[23:0]), .crc_state(crc_state), .crc_next(crc_next2) ); eth_crc_32 eth_crc_32_inst ( - .data_in(fcs_input_tdata[31:0]), + .data_in(input_tdata_reg[31:0]), .crc_state(crc_state), .crc_next(crc_next3) ); eth_crc_40 eth_crc_40_inst ( - .data_in(fcs_input_tdata[39:0]), + .data_in(input_tdata_reg[39:0]), .crc_state(crc_state), .crc_next(crc_next4) ); eth_crc_48 eth_crc_48_inst ( - .data_in(fcs_input_tdata[47:0]), + .data_in(input_tdata_reg[47:0]), .crc_state(crc_state), .crc_next(crc_next5) ); eth_crc_56 eth_crc_56_inst ( - .data_in(fcs_input_tdata[55:0]), + .data_in(input_tdata_reg[55:0]), .crc_state(crc_state), .crc_next(crc_next6) ); eth_crc_64 eth_crc_64_inst ( - .data_in(fcs_input_tdata[63:0]), + .data_in(input_tdata_reg[63:0]), .crc_state(crc_state), .crc_next(crc_next7) ); @@ -224,58 +222,58 @@ end // FCS cycle calculation always @* begin - case (fcs_input_tkeep) + case (input_tkeep_reg) 8'b00000001: begin - fcs_output_txd_0 = {24'h0707fd, ~crc_next0[31:0], fcs_input_tdata[7:0]}; + fcs_output_txd_0 = {24'h0707fd, ~crc_next0[31:0], input_tdata_reg[7:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b11100000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 3; end 8'b00000011: begin - fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], fcs_input_tdata[15:0]}; + fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], input_tdata_reg[15:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b11000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 2; end 8'b00000111: begin - fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], fcs_input_tdata[23:0]}; + fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], input_tdata_reg[23:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b10000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 1; end 8'b00001111: begin - fcs_output_txd_0 = {~crc_next3[31:0], fcs_input_tdata[31:0]}; + fcs_output_txd_0 = {~crc_next3[31:0], input_tdata_reg[31:0]}; fcs_output_txd_1 = {63'h07070707070707fd}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8; end 8'b00011111: begin - fcs_output_txd_0 = {~crc_next4[23:0], fcs_input_tdata[39:0]}; + fcs_output_txd_0 = {~crc_next4[23:0], input_tdata_reg[39:0]}; fcs_output_txd_1 = {56'h070707070707fd, ~crc_next4[31:24]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111110; ifg_offset = 7; end 8'b00111111: begin - fcs_output_txd_0 = {~crc_next5[15:0], fcs_input_tdata[47:0]}; + fcs_output_txd_0 = {~crc_next5[15:0], input_tdata_reg[47:0]}; fcs_output_txd_1 = {48'h0707070707fd, ~crc_next5[31:16]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111100; ifg_offset = 6; end 8'b01111111: begin - fcs_output_txd_0 = {~crc_next6[7:0], fcs_input_tdata[55:0]}; + fcs_output_txd_0 = {~crc_next6[7:0], input_tdata_reg[55:0]}; fcs_output_txd_1 = {40'h07070707fd, ~crc_next6[31:8]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111000; ifg_offset = 5; end 8'b11111111: begin - fcs_output_txd_0 = fcs_input_tdata; + fcs_output_txd_0 = input_tdata_reg; fcs_output_txd_1 = {32'h070707fd, ~crc_next7[31:0]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11110000; @@ -305,13 +303,10 @@ always @* begin ifg_count_next = ifg_count_reg; deficit_idle_count_next = deficit_idle_count_reg; - last_cycle_txd_next = last_cycle_txd_reg; - last_cycle_txc_next = last_cycle_txc_reg; - input_axis_tready_next = 0; - fcs_input_tdata = 0; - fcs_input_tkeep = 0; + input_tdata_next = input_tdata_reg; + input_tkeep_next = input_tkeep_reg; // XGMII idle xgmii_txd_next = 64'h0707070707070707; @@ -320,13 +315,17 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; + frame_ptr_next = keep2count(input_axis_tkeep); reset_crc = 1; + input_axis_tready_next = 1; // XGMII idle xgmii_txd_next = 64'h0707070707070707; xgmii_txc_next = 8'b11111111; + input_tdata_next = input_axis_tdata_masked; + input_tkeep_next = input_axis_tkeep; + if (input_axis_tvalid) begin // XGMII start and preamble if (ifg_count_reg > 0) begin @@ -352,11 +351,11 @@ always @* begin update_crc = 1; input_axis_tready_next = 1; - xgmii_txd_next = input_axis_tdata_masked; + xgmii_txd_next = input_tdata_reg; xgmii_txc_next = 8'b00000000; - fcs_input_tdata = input_axis_tdata_masked; - fcs_input_tkeep = input_axis_tkeep; + input_tdata_next = input_axis_tdata_masked; + input_tkeep_next = input_axis_tkeep; if (input_axis_tvalid) begin frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); @@ -369,48 +368,20 @@ always @* begin ifg_count_next = 8; state_next = STATE_IFG; end else begin + input_axis_tready_next = 0; + if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-4) begin - fcs_input_tkeep = 8'hff; + input_tkeep_next = 8'hff; frame_ptr_next = frame_ptr_reg + 8; if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin - input_axis_tready_next = 0; state_next = STATE_PAD; end else begin - fcs_input_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); - - xgmii_txd_next = fcs_output_txd_0; - xgmii_txc_next = fcs_output_txc_0; - last_cycle_txd_next = fcs_output_txd_1; - last_cycle_txc_next = fcs_output_txc_1; - - reset_crc = 1; - frame_ptr_next = 0; - input_axis_tready_next = 0; - - ifg_count_next = (ifg_delay > 12 ? ifg_delay : 12) - ifg_offset + (lanes_swapped ? 4 : 0) + deficit_idle_count_reg; - if (fcs_output_txc_1 != 8'hff || fcs_output_txc_0 == 0) begin - state_next = STATE_FCS; - end else begin - state_next = STATE_IFG; - end + input_tkeep_next = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + state_next = STATE_FCS_1; end end else begin - xgmii_txd_next = fcs_output_txd_0; - xgmii_txc_next = fcs_output_txc_0; - last_cycle_txd_next = fcs_output_txd_1; - last_cycle_txc_next = fcs_output_txc_1; - - reset_crc = 1; - frame_ptr_next = 0; - input_axis_tready_next = 0; - - ifg_count_next = (ifg_delay > 12 ? ifg_delay : 12) - ifg_offset + (lanes_swapped ? 4 : 0) + deficit_idle_count_reg; - if (fcs_output_txc_1 != 8'hff || fcs_output_txc_0 == 0) begin - state_next = STATE_FCS; - end else begin - state_next = STATE_IFG; - end + state_next = STATE_FCS_1; end end end else begin @@ -427,11 +398,11 @@ always @* begin STATE_PAD: begin input_axis_tready_next = 0; - xgmii_txd_next = 0; + xgmii_txd_next = input_tdata_reg; xgmii_txc_next = 8'b00000000; - fcs_input_tdata = 0; - fcs_input_tkeep = 8'hff; + input_tdata_next = 0; + input_tkeep_next = 8'hff; update_crc = 1; frame_ptr_next = frame_ptr_reg + 8; @@ -439,31 +410,33 @@ always @* begin if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin state_next = STATE_PAD; end else begin - fcs_input_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + input_tkeep_next = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); - xgmii_txd_next = fcs_output_txd_0; - xgmii_txc_next = fcs_output_txc_0; - last_cycle_txd_next = fcs_output_txd_1; - last_cycle_txc_next = fcs_output_txc_1; - - reset_crc = 1; - frame_ptr_next = 0; - input_axis_tready_next = 0; - - ifg_count_next = (ifg_delay > 12 ? ifg_delay : 12) - ifg_offset + (lanes_swapped ? 4 : 0) + deficit_idle_count_reg; - if (fcs_output_txc_1 != 8'hff || fcs_output_txc_0 == 0) begin - state_next = STATE_FCS; - end else begin - state_next = STATE_IFG; - end + state_next = STATE_FCS_1; end end - STATE_FCS: begin + STATE_FCS_1: begin // last cycle input_axis_tready_next = 0; - xgmii_txd_next = last_cycle_txd_reg; - xgmii_txc_next = last_cycle_txc_reg; + xgmii_txd_next = fcs_output_txd_0; + xgmii_txc_next = fcs_output_txc_0; + + frame_ptr_next = 0; + + ifg_count_next = (ifg_delay > 12 ? ifg_delay : 12) - ifg_offset + (lanes_swapped ? 4 : 0) + deficit_idle_count_reg; + if (fcs_output_txc_1 != 8'hff || fcs_output_txc_0 == 0) begin + state_next = STATE_FCS_2; + end else begin + state_next = STATE_IFG; + end + end + STATE_FCS_2: begin + // last cycle + input_axis_tready_next = 0; + + xgmii_txd_next = fcs_output_txd_1; + xgmii_txc_next = fcs_output_txc_1; reset_crc = 1; frame_ptr_next = 0; @@ -478,12 +451,14 @@ always @* begin deficit_idle_count_next = ifg_count_next; ifg_count_next = 0; end + input_axis_tready_next = 1; state_next = STATE_IDLE; end end else begin if (ifg_count_next > 4) begin state_next = STATE_IFG; end else begin + input_axis_tready_next = 1; state_next = STATE_IDLE; end end @@ -508,12 +483,14 @@ always @* begin deficit_idle_count_next = ifg_count_next; ifg_count_next = 0; end + input_axis_tready_next = 1; state_next = STATE_IDLE; end end else begin if (ifg_count_next > 4) begin state_next = STATE_IFG; end else begin + input_axis_tready_next = 1; state_next = STATE_IDLE; end end @@ -530,8 +507,8 @@ always @(posedge clk or posedge rst) begin ifg_count_reg <= 0; deficit_idle_count_reg <= 0; - last_cycle_txd_reg <= 0; - last_cycle_txc_reg <= 0; + input_tdata_reg <= 0; + input_tkeep_reg <= 0; input_axis_tready_reg <= 0; @@ -551,8 +528,8 @@ always @(posedge clk or posedge rst) begin ifg_count_reg <= ifg_count_next; deficit_idle_count_reg <= deficit_idle_count_next; - last_cycle_txd_reg <= last_cycle_txd_next; - last_cycle_txc_reg <= last_cycle_txc_next; + input_tdata_reg <= input_tdata_next; + input_tkeep_reg <= input_tkeep_next; input_axis_tready_reg <= input_axis_tready_next; From c15761068a39450004d4817e77b43ef42cc91d0b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 5 Jun 2015 17:04:10 -0700 Subject: [PATCH 222/617] Add AXI stream frame length adjust modules --- rtl/axis_frame_length_adjust.v | 485 ++++++++++++++++++++ rtl/axis_frame_length_adjust_fifo.v | 162 +++++++ rtl/axis_frame_length_adjust_fifo_64.v | 169 +++++++ tb/test_axis_frame_length_adjust_64.py | 413 +++++++++++++++++ tb/test_axis_frame_length_adjust_64.v | 127 +++++ tb/test_axis_frame_length_adjust_8.py | 413 +++++++++++++++++ tb/test_axis_frame_length_adjust_8.v | 127 +++++ tb/test_axis_frame_length_adjust_fifo.py | 395 ++++++++++++++++ tb/test_axis_frame_length_adjust_fifo.v | 122 +++++ tb/test_axis_frame_length_adjust_fifo_64.py | 406 ++++++++++++++++ tb/test_axis_frame_length_adjust_fifo_64.v | 130 ++++++ 11 files changed, 2949 insertions(+) create mode 100644 rtl/axis_frame_length_adjust.v create mode 100644 rtl/axis_frame_length_adjust_fifo.v create mode 100644 rtl/axis_frame_length_adjust_fifo_64.v create mode 100755 tb/test_axis_frame_length_adjust_64.py create mode 100644 tb/test_axis_frame_length_adjust_64.v create mode 100755 tb/test_axis_frame_length_adjust_8.py create mode 100644 tb/test_axis_frame_length_adjust_8.v create mode 100755 tb/test_axis_frame_length_adjust_fifo.py create mode 100644 tb/test_axis_frame_length_adjust_fifo.v create mode 100755 tb/test_axis_frame_length_adjust_fifo_64.py create mode 100644 tb/test_axis_frame_length_adjust_fifo_64.v diff --git a/rtl/axis_frame_length_adjust.v b/rtl/axis_frame_length_adjust.v new file mode 100644 index 000000000..ba1eb9550 --- /dev/null +++ b/rtl/axis_frame_length_adjust.v @@ -0,0 +1,485 @@ +/* + +Copyright (c) 2015 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 frame length adjuster + */ +module axis_frame_length_adjust # +( + parameter DATA_WIDTH = 1, + 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, + + /* + * Status + */ + output wire status_valid, + input wire status_ready, + output wire status_frame_pad, + output wire status_frame_truncate, + output wire [15:0] status_frame_length, + output wire [15:0] status_frame_original_length, + + /* + * Configuration + */ + input wire [15:0] length_min, + input wire [15:0] length_max +); + +// bus word width +localparam DATA_WORD_WIDTH = DATA_WIDTH / KEEP_WIDTH; + +// bus width assertions +initial begin + if (DATA_WORD_WIDTH * KEEP_WIDTH != DATA_WIDTH) begin + $error("Error: data width not evenly divisble"); + $finish; + end +end + +// state register +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_TRANSFER = 3'd1, + STATE_PAD = 3'd2, + STATE_TRUNCATE = 3'd3; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_last_word; + +reg [15:0] frame_ptr_reg = 0, frame_ptr_next; + +reg [DATA_WIDTH-1:0] last_word_data_reg = 0; +reg [KEEP_WIDTH-1:0] last_word_keep_reg = 0; + +reg last_cycle_tuser_reg = 0, last_cycle_tuser_next; + +reg status_valid_reg = 0, status_valid_next; +reg status_frame_pad_reg = 0, status_frame_pad_next; +reg status_frame_truncate_reg = 0, status_frame_truncate_next; +reg [15:0] status_frame_length_reg = 0, status_frame_length_next; +reg [15:0] status_frame_original_length_reg = 0, status_frame_original_length_next; + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg input_axis_tready_reg = 0, input_axis_tready_next; +assign input_axis_tready = input_axis_tready_reg; + +assign status_valid = status_valid_reg; +assign status_frame_pad = status_frame_pad_reg; +assign status_frame_truncate = status_frame_truncate_reg; +assign status_frame_length = status_frame_length_reg; +assign status_frame_original_length = status_frame_original_length_reg; + +integer i, word_cnt; + +always @* begin + state_next = STATE_IDLE; + + store_last_word = 0; + + frame_ptr_next = frame_ptr_reg; + + output_axis_tdata_int = 0; + output_axis_tkeep_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + input_axis_tready_next = 0; + + last_cycle_tuser_next = last_cycle_tuser_reg; + + status_valid_next = status_valid_reg & ~status_ready; + status_frame_pad_next = status_frame_pad_reg; + status_frame_truncate_next = status_frame_truncate_reg; + status_frame_length_next = status_frame_length_reg; + status_frame_original_length_next = status_frame_original_length_reg; + + case (state_reg) + STATE_IDLE: begin + // idle state + // accept data next cycle if output register ready next cycle + input_axis_tready_next = output_axis_tready_int_early & (~status_valid_reg | status_ready); + + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = input_axis_tvalid; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; + + if (input_axis_tready & input_axis_tvalid) begin + // transfer through + word_cnt = 0; + for (i = 0; i <= KEEP_WIDTH; i = i + 1) begin + //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; + if (input_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; + end + frame_ptr_next = frame_ptr_reg+word_cnt; + + if (frame_ptr_next >= length_max) begin + output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_max - frame_ptr_reg)); + if (input_axis_tlast) begin + status_valid_next = 1; + status_frame_pad_next = 0; + status_frame_truncate_next = frame_ptr_next > length_max; + status_frame_length_next = length_max; + status_frame_original_length_next = frame_ptr_next; + input_axis_tready_next = output_axis_tready_int_early & status_ready; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + output_axis_tvalid_int = 0; + store_last_word = 1; + state_next = STATE_TRUNCATE; + end + end else begin + if (input_axis_tlast) begin + status_frame_original_length_next = frame_ptr_next; + if (frame_ptr_next < length_min) begin + if (frame_ptr_reg + KEEP_WIDTH < length_min) begin + frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; + input_axis_tready_next = 0; + output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + last_cycle_tuser_next = input_axis_tuser; + state_next = STATE_PAD; + end else begin + status_valid_next = 1; + status_frame_pad_next = 1; + status_frame_truncate_next = 0; + status_frame_length_next = length_min; + input_axis_tready_next = output_axis_tready_int_early & status_ready; + output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_min - frame_ptr_reg)); + frame_ptr_next = 0; + state_next = STATE_IDLE; + end + end else begin + status_valid_next = 1; + status_frame_pad_next = 0; + status_frame_truncate_next = 0; + status_frame_length_next = frame_ptr_next; + status_frame_original_length_next = frame_ptr_next; + input_axis_tready_next = output_axis_tready_int_early & status_ready; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_TRANSFER; + end + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_TRANSFER: begin + // transfer data + // accept data next cycle if output register ready next cycle + input_axis_tready_next = output_axis_tready_int_early; + + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; + output_axis_tvalid_int = input_axis_tvalid; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; + + if (input_axis_tready & input_axis_tvalid) begin + // transfer through + word_cnt = 0; + for (i = 0; i <= KEEP_WIDTH; i = i + 1) begin + //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; + if (input_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; + end + frame_ptr_next = frame_ptr_reg+word_cnt; + + if (frame_ptr_next >= length_max) begin + output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_max - frame_ptr_reg)); + if (input_axis_tlast) begin + status_valid_next = 1; + status_frame_pad_next = 0; + status_frame_truncate_next = frame_ptr_next > length_max; + status_frame_length_next = length_max; + status_frame_original_length_next = frame_ptr_next; + input_axis_tready_next = output_axis_tready_int_early & status_ready; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + output_axis_tvalid_int = 0; + store_last_word = 1; + state_next = STATE_TRUNCATE; + end + end else begin + if (input_axis_tlast) begin + status_frame_original_length_next = frame_ptr_next; + if (frame_ptr_next < length_min) begin + if (frame_ptr_reg + KEEP_WIDTH < length_min) begin + frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; + input_axis_tready_next = 0; + output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + last_cycle_tuser_next = input_axis_tuser; + state_next = STATE_PAD; + end else begin + status_valid_next = 1; + status_frame_pad_next = 1; + status_frame_truncate_next = 0; + status_frame_length_next = length_min; + input_axis_tready_next = output_axis_tready_int_early & status_ready; + output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_min - frame_ptr_reg)); + frame_ptr_next = 0; + state_next = STATE_IDLE; + end + end else begin + status_valid_next = 1; + status_frame_pad_next = 0; + status_frame_truncate_next = 0; + status_frame_length_next = frame_ptr_next; + status_frame_original_length_next = frame_ptr_next; + input_axis_tready_next = output_axis_tready_int_early & status_ready; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_TRANSFER; + end + end + end else begin + state_next = STATE_TRANSFER; + end + end + STATE_PAD: begin + // pad to minimum length + input_axis_tready_next = 0; + + output_axis_tdata_int = 0; + output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; + output_axis_tvalid_int = 1; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (output_axis_tready_int) begin + frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; + + if (frame_ptr_next >= length_min) begin + status_valid_next = 1; + status_frame_pad_next = 1; + status_frame_truncate_next = 0; + status_frame_length_next = length_min; + input_axis_tready_next = output_axis_tready_int_early & status_ready; + output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_min - frame_ptr_reg)); + output_axis_tlast_int = 1; + output_axis_tuser_int = last_cycle_tuser_reg; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + state_next = STATE_PAD; + end + end else begin + state_next = STATE_PAD; + end + end + STATE_TRUNCATE: begin + // drop after maximum length + input_axis_tready_next = output_axis_tready_int_early; + + output_axis_tdata_int = last_word_data_reg; + output_axis_tkeep_int = last_word_keep_reg; + output_axis_tvalid_int = input_axis_tvalid & input_axis_tlast; + output_axis_tlast_int = input_axis_tlast; + output_axis_tuser_int = input_axis_tuser; + + if (input_axis_tready & input_axis_tvalid) begin + word_cnt = 0; + for (i = 0; i <= KEEP_WIDTH; i = i + 1) begin + //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; + if (input_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; + end + frame_ptr_next = frame_ptr_reg+word_cnt; + + if (input_axis_tlast) begin + status_valid_next = 1; + status_frame_pad_next = 0; + status_frame_truncate_next = 1; + status_frame_length_next = length_max; + status_frame_original_length_next = frame_ptr_next; + input_axis_tready_next = output_axis_tready_int_early & status_ready; + frame_ptr_next = 0; + state_next = STATE_IDLE; + end else begin + state_next = STATE_TRUNCATE; + end + end else begin + state_next = STATE_TRUNCATE; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= 0; + input_axis_tready_reg <= 0; + last_word_data_reg <= 0; + last_word_keep_reg <= 0; + last_cycle_tuser_reg <= 0; + status_valid_reg <= 0; + status_frame_pad_reg <= 0; + status_frame_truncate_reg <= 0; + status_frame_length_reg <= 0; + status_frame_original_length_reg <= 0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + input_axis_tready_reg <= input_axis_tready_next; + + last_cycle_tuser_reg <= last_cycle_tuser_next; + + status_valid_reg <= status_valid_next; + status_frame_pad_reg <= status_frame_pad_next; + status_frame_truncate_reg <= status_frame_truncate_next; + status_frame_length_reg <= status_frame_length_next; + status_frame_original_length_reg <= status_frame_original_length_next; + + if (store_last_word) begin + last_word_data_reg <= output_axis_tdata_int; + last_word_keep_reg <= output_axis_tkeep_int; + end + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready and currently valid, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/axis_frame_length_adjust_fifo.v b/rtl/axis_frame_length_adjust_fifo.v new file mode 100644 index 000000000..9e827084f --- /dev/null +++ b/rtl/axis_frame_length_adjust_fifo.v @@ -0,0 +1,162 @@ +/* + +Copyright (c) 2015 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 frame length adjuster with FIFO + */ +module axis_frame_length_adjust_fifo # +( + parameter DATA_WIDTH = 8, + parameter FRAME_FIFO_ADDR_WIDTH = 12, + parameter HEADER_FIFO_ADDR_WIDTH = 3 +) +( + 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 output_axis_hdr_valid, + input wire output_axis_hdr_ready, + output wire output_axis_hdr_pad, + output wire output_axis_hdr_truncate, + output wire [15:0] output_axis_hdr_length, + output wire [15:0] output_axis_hdr_original_length, + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [15:0] length_min, + input wire [15:0] length_max +); + +wire [DATA_WIDTH-1:0] fifo_axis_tdata; +wire fifo_axis_tvalid; +wire fifo_axis_tready; +wire fifo_axis_tlast; +wire fifo_axis_tuser; + +wire status_valid; +wire status_ready; +wire status_frame_pad; +wire status_frame_truncate; +wire [15:0] status_frame_length; +wire [15:0] status_frame_original_length; + +axis_frame_length_adjust #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(1) +) +axis_frame_length_adjust_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(1), + .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(fifo_axis_tdata), + .output_axis_tkeep(), + .output_axis_tvalid(fifo_axis_tvalid), + .output_axis_tready(fifo_axis_tready), + .output_axis_tlast(fifo_axis_tlast), + .output_axis_tuser(fifo_axis_tuser), + // Status + .status_valid(status_valid), + .status_ready(status_ready), + .status_frame_pad(status_frame_pad), + .status_frame_truncate(status_frame_truncate), + .status_frame_length(status_frame_length), + .status_frame_original_length(status_frame_original_length), + // Configuration + .length_min(length_min), + .length_max(length_max) +); + +axis_fifo #( + .ADDR_WIDTH(FRAME_FIFO_ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH) +) +frame_fifo_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(fifo_axis_tdata), + .input_axis_tvalid(fifo_axis_tvalid), + .input_axis_tready(fifo_axis_tready), + .input_axis_tlast(fifo_axis_tlast), + .input_axis_tuser(fifo_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) +); + +axis_fifo #( + .ADDR_WIDTH(HEADER_FIFO_ADDR_WIDTH), + .DATA_WIDTH(1+1+16+16) +) +header_fifo_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata({status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length}), + .input_axis_tvalid(status_valid), + .input_axis_tready(status_ready), + .input_axis_tlast(0), + .input_axis_tuser(0), + // AXI output + .output_axis_tdata({output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length}), + .output_axis_tvalid(output_axis_hdr_valid), + .output_axis_tready(output_axis_hdr_ready), + .output_axis_tlast(), + .output_axis_tuser() +); + + +endmodule diff --git a/rtl/axis_frame_length_adjust_fifo_64.v b/rtl/axis_frame_length_adjust_fifo_64.v new file mode 100644 index 000000000..9d75ab4ca --- /dev/null +++ b/rtl/axis_frame_length_adjust_fifo_64.v @@ -0,0 +1,169 @@ +/* + +Copyright (c) 2015 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 frame length adjuster with FIFO (64 bit datapath) + */ +module axis_frame_length_adjust_fifo_64 # +( + parameter DATA_WIDTH = 8, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter FRAME_FIFO_ADDR_WIDTH = 12, + parameter HEADER_FIFO_ADDR_WIDTH = 3 +) +( + 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 output_axis_hdr_valid, + input wire output_axis_hdr_ready, + output wire output_axis_hdr_pad, + output wire output_axis_hdr_truncate, + output wire [15:0] output_axis_hdr_length, + output wire [15:0] output_axis_hdr_original_length, + output wire [DATA_WIDTH-1:0] output_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_axis_tkeep, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Configuration + */ + input wire [15:0] length_min, + input wire [15:0] length_max +); + +wire [DATA_WIDTH-1:0] fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] fifo_axis_tkeep; +wire fifo_axis_tvalid; +wire fifo_axis_tready; +wire fifo_axis_tlast; +wire fifo_axis_tuser; + +wire status_valid; +wire status_ready; +wire status_frame_pad; +wire status_frame_truncate; +wire [15:0] status_frame_length; +wire [15:0] status_frame_original_length; + +axis_frame_length_adjust #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) +) +axis_frame_length_adjust_inst ( + .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(fifo_axis_tdata), + .output_axis_tkeep(fifo_axis_tkeep), + .output_axis_tvalid(fifo_axis_tvalid), + .output_axis_tready(fifo_axis_tready), + .output_axis_tlast(fifo_axis_tlast), + .output_axis_tuser(fifo_axis_tuser), + // Status + .status_valid(status_valid), + .status_ready(status_ready), + .status_frame_pad(status_frame_pad), + .status_frame_truncate(status_frame_truncate), + .status_frame_length(status_frame_length), + .status_frame_original_length(status_frame_original_length), + // Configuration + .length_min(length_min), + .length_max(length_max) +); + +axis_fifo_64 #( + .ADDR_WIDTH(FRAME_FIFO_ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) +) +frame_fifo_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(fifo_axis_tdata), + .input_axis_tkeep(fifo_axis_tkeep), + .input_axis_tvalid(fifo_axis_tvalid), + .input_axis_tready(fifo_axis_tready), + .input_axis_tlast(fifo_axis_tlast), + .input_axis_tuser(fifo_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) +); + +axis_fifo #( + .ADDR_WIDTH(HEADER_FIFO_ADDR_WIDTH), + .DATA_WIDTH(1+1+16+16) +) +header_fifo_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata({status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length}), + .input_axis_tvalid(status_valid), + .input_axis_tready(status_ready), + .input_axis_tlast(0), + .input_axis_tuser(0), + // AXI output + .output_axis_tdata({output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length}), + .output_axis_tvalid(output_axis_hdr_valid), + .output_axis_tready(output_axis_hdr_ready), + .output_axis_tlast(), + .output_axis_tuser() +); + + +endmodule diff --git a/tb/test_axis_frame_length_adjust_64.py b/tb/test_axis_frame_length_adjust_64.py new file mode 100755 index 000000000..96351c3e4 --- /dev/null +++ b/tb/test_axis_frame_length_adjust_64.py @@ -0,0 +1,413 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_frame_length_adjust' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s_64.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s_64.vvp %s" % (module, src) + +def dut_axis_frame_length_adjust_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, + + status_valid, + status_ready, + status_frame_pad, + status_frame_truncate, + status_frame_length, + status_frame_original_length, + + length_min, + length_max): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s_64.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, + + status_valid=status_valid, + status_ready=status_ready, + status_frame_pad=status_frame_pad, + status_frame_truncate=status_frame_truncate, + status_frame_length=status_frame_length, + status_frame_original_length=status_frame_original_length, + + length_min=length_min, + length_max=length_max) + +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)) + status_ready = Signal(bool(0)) + length_min = Signal(intbv(0)[16:]) + length_max = Signal(intbv(0)[16:]) + + # 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)) + status_valid = Signal(bool(0)) + status_frame_pad = Signal(bool(0)) + status_frame_truncate = Signal(bool(0)) + status_frame_length = Signal(intbv(0)[16:]) + status_frame_original_length = Signal(intbv(0)[16:]) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + status_sink_queue = Queue() + status_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') + + status_sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=(status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length), + tvalid=status_valid, + tready=status_ready, + fifo=status_sink_queue, + pause=status_sink_pause, + name='status_sink') + + # DUT + dut = dut_axis_frame_length_adjust_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, + + status_valid, + status_ready, + status_frame_pad, + status_frame_truncate, + status_frame_length, + status_frame_original_length, + + length_min, + length_max) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + length_min.next = 1 + length_max.next = 20 + + for lmax in range(1,18): + for lmin in range(0,lmax+1): + length_min.next = lmin + length_max.next = lmax + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + lrx = len(rx_frame.data) + lt = len(test_frame.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame.data[:lm] + + status = status_sink_queue.get(False) + assert status.data[0][0] == (lt < lmin) + assert status.data[0][1] == (lt > lmax) + assert status.data[0][2] == lrx + assert status.data[0][3] == lt + + assert sink_queue.empty() + assert status_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + lrx = len(rx_frame.data) + lt = len(test_frame1.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame1.data[:lm] + + status = status_sink_queue.get(False) + assert status.data[0][0] == (lt < lmin) + assert status.data[0][1] == (lt > lmax) + assert status.data[0][2] == lrx + assert status.data[0][3] == lt + + rx_frame = sink_queue.get(False) + + lrx = len(rx_frame.data) + lt = len(test_frame2.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame2.data[:lm] + + status = status_sink_queue.get(False) + assert status.data[0][0] == (lt < lmin) + assert status.data[0][1] == (lt > lmax) + assert status.data[0][2] == lrx + assert status.data[0][3] == lt + + assert sink_queue.empty() + assert status_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + test_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + lrx = len(rx_frame.data) + lt = len(test_frame1.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame1.data[:lm] + + assert rx_frame.user[-1] + + status = status_sink_queue.get(False) + assert status.data[0][0] == (lt < lmin) + assert status.data[0][1] == (lt > lmax) + assert status.data[0][2] == lrx + assert status.data[0][3] == lt + + rx_frame = sink_queue.get(False) + + lrx = len(rx_frame.data) + lt = len(test_frame2.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame2.data[:lm] + + status = status_sink_queue.get(False) + assert status.data[0][0] == (lt < lmin) + assert status.data[0][1] == (lt > lmax) + assert status.data[0][2] == lrx + assert status.data[0][3] == lt + + assert sink_queue.empty() + assert status_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, status_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() + diff --git a/tb/test_axis_frame_length_adjust_64.v b/tb/test_axis_frame_length_adjust_64.v new file mode 100644 index 000000000..601df06d1 --- /dev/null +++ b/tb/test_axis_frame_length_adjust_64.v @@ -0,0 +1,127 @@ +/* + +Copyright (c) 2015 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_frame_length_adjust_64; + +// parameters +localparam DATA_WIDTH = 64; +localparam KEEP_WIDTH = (DATA_WIDTH/8); + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; +reg status_ready = 0; +reg [15:0] length_min = 0; +reg [15:0] length_max = 0; + +// Outputs +wire input_axis_tready; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; +wire status_valid; +wire status_frame_pad; +wire status_frame_truncate; +wire [15:0] status_frame_length; +wire [15:0] status_frame_original_length; + +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, + status_ready, + length_min, + length_max); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + status_valid, + status_frame_pad, + status_frame_truncate, + status_frame_length, + status_frame_original_length); + + // dump file + $dumpfile("test_axis_frame_length_adjust_64.lxt"); + $dumpvars(0, test_axis_frame_length_adjust_64); +end + +axis_frame_length_adjust #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // Status + .status_valid(status_valid), + .status_ready(status_ready), + .status_frame_pad(status_frame_pad), + .status_frame_truncate(status_frame_truncate), + .status_frame_length(status_frame_length), + .status_frame_original_length(status_frame_original_length), + // Configuration + .length_min(length_min), + .length_max(length_max) +); + +endmodule diff --git a/tb/test_axis_frame_length_adjust_8.py b/tb/test_axis_frame_length_adjust_8.py new file mode 100755 index 000000000..f077297ce --- /dev/null +++ b/tb/test_axis_frame_length_adjust_8.py @@ -0,0 +1,413 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_frame_length_adjust' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("test_%s_8.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s_8.vvp %s" % (module, src) + +def dut_axis_frame_length_adjust_8(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + status_valid, + status_ready, + status_frame_pad, + status_frame_truncate, + status_frame_length, + status_frame_original_length, + + length_min, + length_max): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s_8.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, + + status_valid=status_valid, + status_ready=status_ready, + status_frame_pad=status_frame_pad, + status_frame_truncate=status_frame_truncate, + status_frame_length=status_frame_length, + status_frame_original_length=status_frame_original_length, + + length_min=length_min, + length_max=length_max) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tkeep = Signal(intbv(0)[1:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + status_ready = Signal(bool(0)) + length_min = Signal(intbv(0)[16:]) + length_max = Signal(intbv(0)[16:]) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tkeep = Signal(intbv(0)[1:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + status_valid = Signal(bool(0)) + status_frame_pad = Signal(bool(0)) + status_frame_truncate = Signal(bool(0)) + status_frame_length = Signal(intbv(0)[16:]) + status_frame_original_length = Signal(intbv(0)[16:]) + + # sources and sinks + source_queue = Queue() + source_pause = Signal(bool(0)) + sink_queue = Queue() + sink_pause = Signal(bool(0)) + status_sink_queue = Queue() + status_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') + + status_sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=(status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length), + tvalid=status_valid, + tready=status_ready, + fifo=status_sink_queue, + pause=status_sink_pause, + name='status_sink') + + # DUT + dut = dut_axis_frame_length_adjust_8(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + status_valid, + status_ready, + status_frame_pad, + status_frame_truncate, + status_frame_length, + status_frame_original_length, + + length_min, + length_max) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_axis_tvalid or output_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_axis_tvalid or output_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + length_min.next = 1 + length_max.next = 20 + + for lmax in range(1,6): + for lmin in range(0,lmax+1): + length_min.next = lmin + length_max.next = lmax + + for payload_len in range(1,6): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + lrx = len(rx_frame.data) + lt = len(test_frame.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame.data[:lm] + + status = status_sink_queue.get(False) + assert status.data[0][0] == (lt < lmin) + assert status.data[0][1] == (lt > lmax) + assert status.data[0][2] == lrx + assert status.data[0][3] == lt + + assert sink_queue.empty() + assert status_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + lrx = len(rx_frame.data) + lt = len(test_frame1.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame1.data[:lm] + + status = status_sink_queue.get(False) + assert status.data[0][0] == (lt < lmin) + assert status.data[0][1] == (lt > lmax) + assert status.data[0][2] == lrx + assert status.data[0][3] == lt + + rx_frame = sink_queue.get(False) + + lrx = len(rx_frame.data) + lt = len(test_frame2.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame2.data[:lm] + + status = status_sink_queue.get(False) + assert status.data[0][0] == (lt < lmin) + assert status.data[0][1] == (lt > lmax) + assert status.data[0][2] == lrx + assert status.data[0][3] == lt + + assert sink_queue.empty() + assert status_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + test_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + lrx = len(rx_frame.data) + lt = len(test_frame1.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame1.data[:lm] + + assert rx_frame.user[-1] + + status = status_sink_queue.get(False) + assert status.data[0][0] == (lt < lmin) + assert status.data[0][1] == (lt > lmax) + assert status.data[0][2] == lrx + assert status.data[0][3] == lt + + rx_frame = sink_queue.get(False) + + lrx = len(rx_frame.data) + lt = len(test_frame2.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame2.data[:lm] + + status = status_sink_queue.get(False) + assert status.data[0][0] == (lt < lmin) + assert status.data[0][1] == (lt > lmax) + assert status.data[0][2] == lrx + assert status.data[0][3] == lt + + assert sink_queue.empty() + assert status_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, status_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() + diff --git a/tb/test_axis_frame_length_adjust_8.v b/tb/test_axis_frame_length_adjust_8.v new file mode 100644 index 000000000..fdfc4c2f6 --- /dev/null +++ b/tb/test_axis_frame_length_adjust_8.v @@ -0,0 +1,127 @@ +/* + +Copyright (c) 2015 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_frame_length_adjust_8; + +// parameters +localparam DATA_WIDTH = 8; +localparam KEEP_WIDTH = (DATA_WIDTH/8); + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; +reg status_ready = 0; +reg [15:0] length_min = 0; +reg [15:0] length_max = 0; + +// Outputs +wire input_axis_tready; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; +wire status_valid; +wire status_frame_pad; +wire status_frame_truncate; +wire [15:0] status_frame_length; +wire [15:0] status_frame_original_length; + +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, + status_ready, + length_min, + length_max); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + status_valid, + status_frame_pad, + status_frame_truncate, + status_frame_length, + status_frame_original_length); + + // dump file + $dumpfile("test_axis_frame_length_adjust_8.lxt"); + $dumpvars(0, test_axis_frame_length_adjust_8); +end + +axis_frame_length_adjust #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // AXI output + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // Status + .status_valid(status_valid), + .status_ready(status_ready), + .status_frame_pad(status_frame_pad), + .status_frame_truncate(status_frame_truncate), + .status_frame_length(status_frame_length), + .status_frame_original_length(status_frame_original_length), + // Configuration + .length_min(length_min), + .length_max(length_max) +); + +endmodule diff --git a/tb/test_axis_frame_length_adjust_fifo.py b/tb/test_axis_frame_length_adjust_fifo.py new file mode 100755 index 000000000..bafea3092 --- /dev/null +++ b/tb/test_axis_frame_length_adjust_fifo.py @@ -0,0 +1,395 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_frame_length_adjust_fifo' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_frame_length_adjust.v") +srcs.append("../rtl/axis_fifo.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_frame_length_adjust_fifo(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_hdr_valid, + output_axis_hdr_ready, + output_axis_hdr_pad, + output_axis_hdr_truncate, + output_axis_hdr_length, + output_axis_hdr_original_length, + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + length_min, + length_max): + + 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_hdr_valid=output_axis_hdr_valid, + output_axis_hdr_ready=output_axis_hdr_ready, + output_axis_hdr_pad=output_axis_hdr_pad, + output_axis_hdr_truncate=output_axis_hdr_truncate, + output_axis_hdr_length=output_axis_hdr_length, + output_axis_hdr_original_length=output_axis_hdr_original_length, + 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, + + length_min=length_min, + length_max=length_max) + +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_hdr_ready = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + length_min = Signal(intbv(0)[16:]) + length_max = Signal(intbv(0)[16:]) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_hdr_valid = Signal(bool(0)) + output_axis_hdr_pad = Signal(bool(0)) + output_axis_hdr_truncate = Signal(bool(0)) + output_axis_hdr_length = Signal(intbv(0)[16:]) + output_axis_hdr_original_length = Signal(intbv(0)[16:]) + 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)) + hdr_sink_queue = Queue() + hdr_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') + + hdr_sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=(output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length), + tvalid=output_axis_hdr_valid, + tready=output_axis_hdr_ready, + fifo=hdr_sink_queue, + pause=hdr_sink_pause, + name='hdr_sink') + + # DUT + dut = dut_axis_frame_length_adjust_fifo(clk, + rst, + current_test, + + input_axis_tdata, + input_axis_tvalid, + input_axis_tready, + input_axis_tlast, + input_axis_tuser, + + output_axis_hdr_valid, + output_axis_hdr_ready, + output_axis_hdr_pad, + output_axis_hdr_truncate, + output_axis_hdr_length, + output_axis_hdr_original_length, + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + length_min, + length_max) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + length_min.next = 1 + length_max.next = 20 + + for lmax in range(1,6): + for lmin in range(0,lmax+1): + length_min.next = lmin + length_max.next = lmax + + for payload_len in range(1,6): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + for wait in wait_normal,: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + lrx = len(rx_frame.data) + lt = len(test_frame.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame.data[:lm] + + hdr = hdr_sink_queue.get(False) + assert hdr.data[0][0] == (lt < lmin) + assert hdr.data[0][1] == (lt > lmax) + assert hdr.data[0][2] == lrx + assert hdr.data[0][3] == lt + + assert sink_queue.empty() + assert hdr_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + for wait in wait_normal,: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + lrx = len(rx_frame.data) + lt = len(test_frame1.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame1.data[:lm] + + hdr = hdr_sink_queue.get(False) + assert hdr.data[0][0] == (lt < lmin) + assert hdr.data[0][1] == (lt > lmax) + assert hdr.data[0][2] == lrx + assert hdr.data[0][3] == lt + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + lrx = len(rx_frame.data) + lt = len(test_frame2.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame2.data[:lm] + + hdr = hdr_sink_queue.get(False) + assert hdr.data[0][0] == (lt < lmin) + assert hdr.data[0][1] == (lt > lmax) + assert hdr.data[0][2] == lrx + assert hdr.data[0][3] == lt + + assert sink_queue.empty() + assert hdr_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + test_frame1.user = 1 + + for wait in wait_normal,: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + lrx = len(rx_frame.data) + lt = len(test_frame1.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame1.data[:lm] + + hdr = hdr_sink_queue.get(False) + assert hdr.data[0][0] == (lt < lmin) + assert hdr.data[0][1] == (lt > lmax) + assert hdr.data[0][2] == lrx + assert hdr.data[0][3] == lt + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + lrx = len(rx_frame.data) + lt = len(test_frame2.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame2.data[:lm] + + hdr = hdr_sink_queue.get(False) + assert hdr.data[0][0] == (lt < lmin) + assert hdr.data[0][1] == (lt > lmax) + assert hdr.data[0][2] == lrx + assert hdr.data[0][3] == lt + + assert sink_queue.empty() + assert hdr_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, hdr_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() + diff --git a/tb/test_axis_frame_length_adjust_fifo.v b/tb/test_axis_frame_length_adjust_fifo.v new file mode 100644 index 000000000..34f604275 --- /dev/null +++ b/tb/test_axis_frame_length_adjust_fifo.v @@ -0,0 +1,122 @@ +/* + +Copyright (c) 2015 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_frame_length_adjust_fifo; + +// parameters +localparam DATA_WIDTH = 8; +localparam FRAME_FIFO_ADDR_WIDTH = 12; +localparam HEADER_FIFO_ADDR_WIDTH = 3; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_hdr_ready = 0; +reg output_axis_tready = 0; +reg [15:0] length_min = 0; +reg [15:0] length_max = 0; + +// Outputs +wire input_axis_tready; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; +wire output_axis_hdr_valid; +wire output_axis_hdr_pad; +wire output_axis_hdr_truncate; +wire [15:0] output_axis_hdr_length; +wire [15:0] output_axis_hdr_original_length; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_hdr_ready, + output_axis_tready, + length_min, + length_max); + $to_myhdl(input_axis_tready, + output_axis_hdr_valid, + output_axis_hdr_pad, + output_axis_hdr_truncate, + output_axis_hdr_length, + output_axis_hdr_original_length, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_frame_length_adjust_fifo.lxt"); + $dumpvars(0, test_axis_frame_length_adjust_fifo); +end + +axis_frame_length_adjust_fifo #( + .DATA_WIDTH(DATA_WIDTH), + .FRAME_FIFO_ADDR_WIDTH(FRAME_FIFO_ADDR_WIDTH), + .HEADER_FIFO_ADDR_WIDTH(HEADER_FIFO_ADDR_WIDTH) +) +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_hdr_valid(output_axis_hdr_valid), + .output_axis_hdr_ready(output_axis_hdr_ready), + .output_axis_hdr_pad(output_axis_hdr_pad), + .output_axis_hdr_truncate(output_axis_hdr_truncate), + .output_axis_hdr_length(output_axis_hdr_length), + .output_axis_hdr_original_length(output_axis_hdr_original_length), + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // Configuration + .length_min(length_min), + .length_max(length_max) +); + +endmodule diff --git a/tb/test_axis_frame_length_adjust_fifo_64.py b/tb/test_axis_frame_length_adjust_fifo_64.py new file mode 100755 index 000000000..caf985e6b --- /dev/null +++ b/tb/test_axis_frame_length_adjust_fifo_64.py @@ -0,0 +1,406 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_frame_length_adjust_fifo_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_frame_length_adjust.v") +srcs.append("../rtl/axis_fifo.v") +srcs.append("../rtl/axis_fifo_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_axis_frame_length_adjust_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_hdr_valid, + output_axis_hdr_ready, + output_axis_hdr_pad, + output_axis_hdr_truncate, + output_axis_hdr_length, + output_axis_hdr_original_length, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + length_min, + length_max): + + 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_hdr_valid=output_axis_hdr_valid, + output_axis_hdr_ready=output_axis_hdr_ready, + output_axis_hdr_pad=output_axis_hdr_pad, + output_axis_hdr_truncate=output_axis_hdr_truncate, + output_axis_hdr_length=output_axis_hdr_length, + output_axis_hdr_original_length=output_axis_hdr_original_length, + 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, + + length_min=length_min, + length_max=length_max) + +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_hdr_ready = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + length_min = Signal(intbv(0)[16:]) + length_max = Signal(intbv(0)[16:]) + + # Outputs + input_axis_tready = Signal(bool(0)) + output_axis_hdr_valid = Signal(bool(0)) + output_axis_hdr_pad = Signal(bool(0)) + output_axis_hdr_truncate = Signal(bool(0)) + output_axis_hdr_length = Signal(intbv(0)[16:]) + output_axis_hdr_original_length = Signal(intbv(0)[16:]) + 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)) + hdr_sink_queue = Queue() + hdr_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') + + hdr_sink = axis_ep.AXIStreamSink(clk, + rst, + tdata=(output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length), + tvalid=output_axis_hdr_valid, + tready=output_axis_hdr_ready, + fifo=hdr_sink_queue, + pause=hdr_sink_pause, + name='hdr_sink') + + # DUT + dut = dut_axis_frame_length_adjust_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_hdr_valid, + output_axis_hdr_ready, + output_axis_hdr_pad, + output_axis_hdr_truncate, + output_axis_hdr_length, + output_axis_hdr_original_length, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser, + + length_min, + length_max) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_axis_tvalid or output_axis_tvalid: + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + length_min.next = 1 + length_max.next = 20 + + for lmax in range(1,18): + for lmin in range(0,lmax+1): + length_min.next = lmin + length_max.next = lmax + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + for wait in wait_normal,: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + lrx = len(rx_frame.data) + lt = len(test_frame.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame.data[:lm] + + hdr = hdr_sink_queue.get(False) + assert hdr.data[0][0] == (lt < lmin) + assert hdr.data[0][1] == (lt > lmax) + assert hdr.data[0][2] == lrx + assert hdr.data[0][3] == lt + + assert sink_queue.empty() + assert hdr_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + for wait in wait_normal,: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + lrx = len(rx_frame.data) + lt = len(test_frame1.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame1.data[:lm] + + hdr = hdr_sink_queue.get(False) + assert hdr.data[0][0] == (lt < lmin) + assert hdr.data[0][1] == (lt > lmax) + assert hdr.data[0][2] == lrx + assert hdr.data[0][3] == lt + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + lrx = len(rx_frame.data) + lt = len(test_frame2.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame2.data[:lm] + + hdr = hdr_sink_queue.get(False) + assert hdr.data[0][0] == (lt < lmin) + assert hdr.data[0][1] == (lt > lmax) + assert hdr.data[0][2] == lrx + assert hdr.data[0][3] == lt + + assert sink_queue.empty() + assert hdr_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + + test_frame1.user = 1 + + for wait in wait_normal,: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + lrx = len(rx_frame.data) + lt = len(test_frame1.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame1.data[:lm] + + hdr = hdr_sink_queue.get(False) + assert hdr.data[0][0] == (lt < lmin) + assert hdr.data[0][1] == (lt > lmax) + assert hdr.data[0][2] == lrx + assert hdr.data[0][3] == lt + assert rx_frame.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + lrx = len(rx_frame.data) + lt = len(test_frame2.data) + lm = min(lrx, lt) + assert lrx >= lmin + assert lrx <= lmax + assert rx_frame.data[:lm] == test_frame2.data[:lm] + + hdr = hdr_sink_queue.get(False) + assert hdr.data[0][0] == (lt < lmin) + assert hdr.data[0][1] == (lt > lmax) + assert hdr.data[0][2] == lrx + assert hdr.data[0][3] == lt + + assert sink_queue.empty() + assert hdr_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, hdr_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() + diff --git a/tb/test_axis_frame_length_adjust_fifo_64.v b/tb/test_axis_frame_length_adjust_fifo_64.v new file mode 100644 index 000000000..80dc558c4 --- /dev/null +++ b/tb/test_axis_frame_length_adjust_fifo_64.v @@ -0,0 +1,130 @@ +/* + +Copyright (c) 2015 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_axis_frame_length_adjust_fifo_64; + +// parameters +localparam DATA_WIDTH = 64; +localparam KEEP_WIDTH = (DATA_WIDTH/8); +localparam FRAME_FIFO_ADDR_WIDTH = 9; +localparam HEADER_FIFO_ADDR_WIDTH = 3; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_hdr_ready = 0; +reg output_axis_tready = 0; +reg [15:0] length_min = 0; +reg [15:0] length_max = 0; + +// Outputs +wire input_axis_tready; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; +wire output_axis_hdr_valid; +wire output_axis_hdr_pad; +wire output_axis_hdr_truncate; +wire [15:0] output_axis_hdr_length; +wire [15:0] output_axis_hdr_original_length; + +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_hdr_ready, + output_axis_tready, + length_min, + length_max); + $to_myhdl(input_axis_tready, + output_axis_hdr_valid, + output_axis_hdr_pad, + output_axis_hdr_truncate, + output_axis_hdr_length, + output_axis_hdr_original_length, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_frame_length_adjust_fifo_64.lxt"); + $dumpvars(0, test_axis_frame_length_adjust_fifo_64); +end + +axis_frame_length_adjust_fifo_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .FRAME_FIFO_ADDR_WIDTH(FRAME_FIFO_ADDR_WIDTH), + .HEADER_FIFO_ADDR_WIDTH(HEADER_FIFO_ADDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_axis_tdata), + .input_axis_tkeep(input_axis_tkeep), + .input_axis_tvalid(input_axis_tvalid), + .input_axis_tready(input_axis_tready), + .input_axis_tlast(input_axis_tlast), + .input_axis_tuser(input_axis_tuser), + // AXI output + .output_axis_hdr_valid(output_axis_hdr_valid), + .output_axis_hdr_ready(output_axis_hdr_ready), + .output_axis_hdr_pad(output_axis_hdr_pad), + .output_axis_hdr_truncate(output_axis_hdr_truncate), + .output_axis_hdr_length(output_axis_hdr_length), + .output_axis_hdr_original_length(output_axis_hdr_original_length), + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tready(output_axis_tready), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + // Configuration + .length_min(length_min), + .length_max(length_max) +); + +endmodule From bfc97ac311c0ffb9e757b319645e507925d85c5e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 5 Jun 2015 23:42:43 -0700 Subject: [PATCH 223/617] Fix error detect in 1G MAC --- rtl/eth_mac_1g_rx.v | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v index 5f4e88ce9..ed4ec30d3 100644 --- a/rtl/eth_mac_1g_rx.v +++ b/rtl/eth_mac_1g_rx.v @@ -143,7 +143,7 @@ always @* begin output_axis_tdata_next = gmii_rxd_d4; output_axis_tvalid_next = 1; - if (gmii_rx_dv & gmii_rx_er) begin + if (gmii_rx_dv_d4 & gmii_rx_er_d4) begin // error output_axis_tlast_next = 1; output_axis_tuser_next = 1; @@ -152,7 +152,11 @@ always @* begin end else if (~gmii_rx_dv) begin // end of packet output_axis_tlast_next = 1; - if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin + if (gmii_rx_er_d0 | gmii_rx_er_d1 | gmii_rx_er_d2 | gmii_rx_er_d3) begin + // error received in FCS bytes + output_axis_tuser_next = 1; + error_bad_frame_next = 1; + end else if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin // FCS good output_axis_tuser_next = 0; end else begin From 455ddf5df21040089e91ba19244cbd8aad37d1b9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 6 Jun 2015 00:49:40 -0700 Subject: [PATCH 224/617] Fix error detect in 10G MAC --- rtl/eth_mac_10g_rx.v | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index d50c3c69c..75ca47fbf 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -325,9 +325,20 @@ always @* begin if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin // start condition - reset_crc = 0; - update_crc = 1; - state_next = STATE_PAYLOAD; + if (detect_error_masked) begin + // error in first data word + output_axis_tdata_next = 0; + output_axis_tkeep_next = 1; + output_axis_tvalid_next = 1; + output_axis_tlast_next = 1; + output_axis_tuser_next = 1; + error_bad_frame_next = 1; + state_next = STATE_IDLE; + end else begin + reset_crc = 0; + update_crc = 1; + state_next = STATE_PAYLOAD; + end end else begin state_next = STATE_IDLE; end From 0ecd354d7ff19c93a865879aa9b2ab4403fa0147 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 7 Jun 2015 22:07:04 -0700 Subject: [PATCH 225/617] Fix instance name --- rtl/eth_mac_10g_fifo.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 302971168..0090daee8 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -143,7 +143,7 @@ eth_mac_10g #( .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) ) -eth_mac_1g_inst ( +eth_mac_10g_inst ( .tx_clk(tx_clk), .tx_rst(tx_rst), .rx_clk(rx_clk), From 87fe1a561f861366f8999a8ab5c1d3357290fc8a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 22 Jun 2015 14:56:56 -0700 Subject: [PATCH 226/617] Add AXI stream tap modules --- rtl/axis_tap.v | 234 ++++++++++++++++++++++ rtl/axis_tap_64.v | 251 ++++++++++++++++++++++++ tb/test_axis_tap.py | 420 ++++++++++++++++++++++++++++++++++++++++ tb/test_axis_tap.v | 90 +++++++++ tb/test_axis_tap_64.py | 430 +++++++++++++++++++++++++++++++++++++++++ tb/test_axis_tap_64.v | 97 ++++++++++ 6 files changed, 1522 insertions(+) create mode 100644 rtl/axis_tap.v create mode 100644 rtl/axis_tap_64.v create mode 100755 tb/test_axis_tap.py create mode 100644 tb/test_axis_tap.v create mode 100755 tb/test_axis_tap_64.py create mode 100644 tb/test_axis_tap_64.v diff --git a/rtl/axis_tap.v b/rtl/axis_tap.v new file mode 100644 index 000000000..a79742653 --- /dev/null +++ b/rtl/axis_tap.v @@ -0,0 +1,234 @@ +/* + +Copyright (c) 2015 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 tap + */ +module axis_tap # +( + parameter DATA_WIDTH = 8 +) +( + input wire clk, + input wire rst, + + /* + * AXI tap + */ + input wire [DATA_WIDTH-1:0] tap_axis_tdata, + input wire tap_axis_tvalid, + input wire tap_axis_tready, + input wire tap_axis_tlast, + input wire tap_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 +); + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_TRANSFER = 2'd1, + STATE_TRUNCATE = 2'd2, + STATE_WAIT = 2'd3; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg frame_reg = 0, frame_next; + +always @* begin + state_next = STATE_IDLE; + + frame_next = frame_reg; + + output_axis_tdata_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (tap_axis_tready & tap_axis_tvalid) begin + frame_next = ~tap_axis_tlast; + end + + case (state_reg) + STATE_IDLE: begin + if (tap_axis_tready & tap_axis_tvalid) begin + // start of frame + if (output_axis_tready_int) begin + output_axis_tdata_int = tap_axis_tdata; + output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; + output_axis_tlast_int = tap_axis_tlast; + output_axis_tuser_int = tap_axis_tuser; + if (tap_axis_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_TRANSFER; + end + end else begin + state_next = STATE_WAIT; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_TRANSFER: begin + if (tap_axis_tready & tap_axis_tvalid) begin + // transfer data + if (output_axis_tready_int) begin + output_axis_tdata_int = tap_axis_tdata; + output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; + output_axis_tlast_int = tap_axis_tlast; + output_axis_tuser_int = tap_axis_tuser; + if (tap_axis_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_TRANSFER; + end + end else begin + state_next = STATE_TRUNCATE; + end + end else begin + state_next = STATE_TRANSFER; + end + end + STATE_TRUNCATE: begin + if (output_axis_tready_int) begin + output_axis_tdata_int = 0; + output_axis_tvalid_int = 1; + output_axis_tlast_int = 1; + output_axis_tuser_int = 1; + if (frame_next) begin + state_next = STATE_WAIT; + end else begin + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_TRUNCATE; + end + end + STATE_WAIT: begin + if (tap_axis_tready & tap_axis_tvalid) begin + if (tap_axis_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT; + end + end else begin + state_next = STATE_WAIT; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_reg <= 0; + end else begin + state_reg <= state_next; + frame_reg <= frame_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/rtl/axis_tap_64.v b/rtl/axis_tap_64.v new file mode 100644 index 000000000..0e73ece6c --- /dev/null +++ b/rtl/axis_tap_64.v @@ -0,0 +1,251 @@ +/* + +Copyright (c) 2015 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 tap (64 bit datapath) + */ +module axis_tap_64 # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * AXI tap + */ + input wire [DATA_WIDTH-1:0] tap_axis_tdata, + input wire [KEEP_WIDTH-1:0] tap_axis_tkeep, + input wire tap_axis_tvalid, + input wire tap_axis_tready, + input wire tap_axis_tlast, + input wire tap_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 +); + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int = 0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_TRANSFER = 2'd1, + STATE_TRUNCATE = 2'd2, + STATE_WAIT = 2'd3; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg frame_reg = 0, frame_next; + +always @* begin + state_next = STATE_IDLE; + + frame_next = frame_reg; + + output_axis_tdata_int = 0; + output_axis_tkeep_int = 0; + output_axis_tvalid_int = 0; + output_axis_tlast_int = 0; + output_axis_tuser_int = 0; + + if (tap_axis_tready & tap_axis_tvalid) begin + frame_next = ~tap_axis_tlast; + end + + case (state_reg) + STATE_IDLE: begin + if (tap_axis_tready & tap_axis_tvalid) begin + // start of frame + if (output_axis_tready_int) begin + output_axis_tdata_int = tap_axis_tdata; + output_axis_tkeep_int = tap_axis_tkeep; + output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; + output_axis_tlast_int = tap_axis_tlast; + output_axis_tuser_int = tap_axis_tuser; + if (tap_axis_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_TRANSFER; + end + end else begin + state_next = STATE_WAIT; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_TRANSFER: begin + if (tap_axis_tready & tap_axis_tvalid) begin + // transfer data + if (output_axis_tready_int) begin + output_axis_tdata_int = tap_axis_tdata; + output_axis_tkeep_int = tap_axis_tkeep; + output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; + output_axis_tlast_int = tap_axis_tlast; + output_axis_tuser_int = tap_axis_tuser; + if (tap_axis_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_TRANSFER; + end + end else begin + state_next = STATE_TRUNCATE; + end + end else begin + state_next = STATE_TRANSFER; + end + end + STATE_TRUNCATE: begin + if (output_axis_tready_int) begin + output_axis_tdata_int = 0; + output_axis_tkeep_int = 1; + output_axis_tvalid_int = 1; + output_axis_tlast_int = 1; + output_axis_tuser_int = 1; + if (frame_next) begin + state_next = STATE_WAIT; + end else begin + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_TRUNCATE; + end + end + STATE_WAIT: begin + if (tap_axis_tready & tap_axis_tvalid) begin + if (tap_axis_tlast) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT; + end + end else begin + state_next = STATE_WAIT; + end + end + endcase +end + +always @(posedge clk or posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_reg <= 0; + end else begin + state_reg <= state_next; + frame_reg <= frame_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg output_axis_tvalid_reg = 0; +reg output_axis_tlast_reg = 0; +reg output_axis_tuser_reg = 0; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; +reg temp_axis_tvalid_reg = 0; +reg temp_axis_tlast_reg = 0; +reg temp_axis_tuser_reg = 0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); + +always @(posedge clk or posedge rst) begin + if (rst) begin + output_axis_tdata_reg <= 0; + output_axis_tkeep_reg <= 0; + output_axis_tvalid_reg <= 0; + output_axis_tlast_reg <= 0; + output_axis_tuser_reg <= 0; + output_axis_tready_int <= 0; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end else begin + // transfer sink ready state to source + output_axis_tready_int <= output_axis_tready_int_early; + + if (output_axis_tready_int) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tvalid_reg <= output_axis_tvalid_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else begin + // output is not ready, store input in temp + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tvalid_reg <= output_axis_tvalid_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tvalid_reg <= temp_axis_tvalid_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + temp_axis_tdata_reg <= 0; + temp_axis_tkeep_reg <= 0; + temp_axis_tvalid_reg <= 0; + temp_axis_tlast_reg <= 0; + temp_axis_tuser_reg <= 0; + end + end +end + +endmodule diff --git a/tb/test_axis_tap.py b/tb/test_axis_tap.py new file mode 100755 index 000000000..621bd822d --- /dev/null +++ b/tb/test_axis_tap.py @@ -0,0 +1,420 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_tap' +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_tap(clk, + rst, + current_test, + + tap_axis_tdata, + tap_axis_tvalid, + tap_axis_tready, + tap_axis_tlast, + tap_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, + + tap_axis_tdata=tap_axis_tdata, + tap_axis_tvalid=tap_axis_tvalid, + tap_axis_tready=tap_axis_tready, + tap_axis_tlast=tap_axis_tlast, + tap_axis_tuser=tap_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:]) + + tap_axis_tdata = Signal(intbv(0)[8:]) + tap_axis_tvalid = Signal(bool(0)) + tap_axis_tready = Signal(bool(1)) + tap_axis_tlast = Signal(bool(0)) + tap_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + + # 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=tap_axis_tdata, + tvalid=tap_axis_tvalid, + tready=tap_axis_tready, + tlast=tap_axis_tlast, + tuser=tap_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_tap(clk, + rst, + current_test, + + tap_axis_tdata, + tap_axis_tvalid, + tap_axis_tready, + tap_axis_tlast, + tap_axis_tuser, + + output_axis_tdata, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: test packet with source pause") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield 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: test packet with sink pause") + current_test.next = 4 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + 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.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 5: back-to-back packets") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + 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 6: alternate pause source") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while tap_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 7: alternate pause sink") + current_test.next = 7 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while tap_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.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 8: tuser assert") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_tap.v b/tb/test_axis_tap.v new file mode 100644 index 000000000..fab77189e --- /dev/null +++ b/tb/test_axis_tap.v @@ -0,0 +1,90 @@ +/* + +Copyright (c) 2015 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_tap; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] tap_axis_tdata = 0; +reg tap_axis_tvalid = 0; +reg tap_axis_tready = 0; +reg tap_axis_tlast = 0; +reg tap_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +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, + tap_axis_tdata, + tap_axis_tvalid, + tap_axis_tready, + tap_axis_tlast, + tap_axis_tuser, + output_axis_tready); + $to_myhdl(output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_tap.lxt"); + $dumpvars(0, test_axis_tap); +end + +axis_tap #( + .DATA_WIDTH(8) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI tap + .tap_axis_tdata(tap_axis_tdata), + .tap_axis_tvalid(tap_axis_tvalid), + .tap_axis_tready(tap_axis_tready), + .tap_axis_tlast(tap_axis_tlast), + .tap_axis_tuser(tap_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 diff --git a/tb/test_axis_tap_64.py b/tb/test_axis_tap_64.py new file mode 100755 index 000000000..f8ef3b01e --- /dev/null +++ b/tb/test_axis_tap_64.py @@ -0,0 +1,430 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_tap_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_tap_64(clk, + rst, + current_test, + + tap_axis_tdata, + tap_axis_tkeep, + tap_axis_tvalid, + tap_axis_tready, + tap_axis_tlast, + tap_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, + + tap_axis_tdata=tap_axis_tdata, + tap_axis_tkeep=tap_axis_tkeep, + tap_axis_tvalid=tap_axis_tvalid, + tap_axis_tready=tap_axis_tready, + tap_axis_tlast=tap_axis_tlast, + tap_axis_tuser=tap_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:]) + + tap_axis_tdata = Signal(intbv(0)[64:]) + tap_axis_tkeep = Signal(intbv(0)[8:]) + tap_axis_tvalid = Signal(bool(0)) + tap_axis_tready = Signal(bool(1)) + tap_axis_tlast = Signal(bool(0)) + tap_axis_tuser = Signal(bool(0)) + output_axis_tready = Signal(bool(0)) + + # Outputs + 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=tap_axis_tdata, + tkeep=tap_axis_tkeep, + tvalid=tap_axis_tvalid, + tready=tap_axis_tready, + tlast=tap_axis_tlast, + tuser=tap_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_tap_64(clk, + rst, + current_test, + + tap_axis_tdata, + tap_axis_tkeep, + tap_axis_tvalid, + tap_axis_tready, + tap_axis_tlast, + tap_axis_tuser, + + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tready, + output_axis_tlast, + output_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: test packet with source pause") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield 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: test packet with sink pause") + current_test.next = 4 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + 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.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 5: back-to-back packets") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + 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 6: alternate pause source") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while tap_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 7: alternate pause sink") + current_test.next = 7 + + test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))) + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + + while tap_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.user[-1] + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame.user[-1] + + yield delay(100) + + yield clk.posedge + print("test 8: tuser assert") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame.user = 1 + source_queue.put(test_frame) + yield clk.posedge + + yield output_axis_tlast.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + assert rx_frame.user[-1] + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_axis_tap_64.v b/tb/test_axis_tap_64.v new file mode 100644 index 000000000..a9a9e4d14 --- /dev/null +++ b/tb/test_axis_tap_64.v @@ -0,0 +1,97 @@ +/* + +Copyright (c) 2015 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_tap_64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] tap_axis_tdata = 0; +reg [7:0] tap_axis_tkeep = 0; +reg tap_axis_tvalid = 0; +reg tap_axis_tready = 0; +reg tap_axis_tlast = 0; +reg tap_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +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, + tap_axis_tdata, + tap_axis_tkeep, + tap_axis_tvalid, + tap_axis_tready, + tap_axis_tlast, + tap_axis_tuser, + output_axis_tready); + $to_myhdl(output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_tap_64.lxt"); + $dumpvars(0, test_axis_tap_64); +end + +axis_tap_64 #( + .DATA_WIDTH(64), + .KEEP_WIDTH(8) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI tap + .tap_axis_tdata(tap_axis_tdata), + .tap_axis_tkeep(tap_axis_tkeep), + .tap_axis_tvalid(tap_axis_tvalid), + .tap_axis_tready(tap_axis_tready), + .tap_axis_tlast(tap_axis_tlast), + .tap_axis_tuser(tap_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 From dbf720ffbe0edd2300b0dd6827ea52fcac6b1d19 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 23 Jun 2015 07:43:06 -0700 Subject: [PATCH 227/617] Improve 10G PHY TX timing performance --- rtl/eth_mac_10g_tx.v | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 32c1b64ac..30be231c9 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -61,6 +61,10 @@ module eth_mac_10g_tx # input wire [7:0] ifg_delay ); +localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; +localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8; +localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007; + localparam [2:0] STATE_IDLE = 3'd0, STATE_PAYLOAD = 3'd1, @@ -315,7 +319,7 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = keep2count(input_axis_tkeep); + frame_ptr_next = 8; reset_crc = 1; input_axis_tready_next = 1; @@ -358,8 +362,9 @@ always @* begin input_tkeep_next = input_axis_tkeep; if (input_axis_tvalid) begin - frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); + frame_ptr_next = frame_ptr_reg + 8; if (input_axis_tlast) begin + frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); input_axis_tready_next = 0; if (input_axis_tuser) begin xgmii_txd_next = 64'h070707fdfefefefe; @@ -370,14 +375,14 @@ always @* begin end else begin input_axis_tready_next = 0; - if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-4) begin + if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(input_axis_tkeep) < MIN_FL_NOCRC_LS))) begin input_tkeep_next = 8'hff; frame_ptr_next = frame_ptr_reg + 8; - if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin + if (frame_ptr_reg < MIN_FL_NOCRC_MS) begin state_next = STATE_PAD; end else begin - input_tkeep_next = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + input_tkeep_next = 8'hff >> (8-MIN_FL_NOCRC_LS); state_next = STATE_FCS_1; end end else begin @@ -407,10 +412,10 @@ always @* begin update_crc = 1; frame_ptr_next = frame_ptr_reg + 8; - if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin + if (frame_ptr_reg < MIN_FL_NOCRC_MS) begin state_next = STATE_PAD; end else begin - input_tkeep_next = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + input_tkeep_next = 8'hff >> (8-MIN_FL_NOCRC_LS); state_next = STATE_FCS_1; end From abe0d926ba92b46ef297c69adddfee2dd12ef55f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 23 Jun 2015 08:55:39 -0700 Subject: [PATCH 228/617] Consider any control characters in packet body as errors --- rtl/eth_mac_10g_rx.v | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index 75ca47fbf..31362af90 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -255,38 +255,49 @@ end // mask errors to within packet reg [7:0] detect_error_masked; +reg [7:0] control_masked; always @* begin case (detect_term) 8'b00000000: begin detect_error_masked = detect_error; + control_masked = xgmii_rxc_d0; end 8'b00000001: begin detect_error_masked = 0; + control_masked = 0; end 8'b00000010: begin detect_error_masked = detect_error[0]; + control_masked = xgmii_rxc_d0[0]; end 8'b00000100: begin detect_error_masked = detect_error[1:0]; + control_masked = xgmii_rxc_d0[1:0]; end 8'b00001000: begin detect_error_masked = detect_error[2:0]; + control_masked = xgmii_rxc_d0[2:0]; end 8'b00010000: begin detect_error_masked = detect_error[3:0]; + control_masked = xgmii_rxc_d0[3:0]; end 8'b00100000: begin detect_error_masked = detect_error[4:0]; + control_masked = xgmii_rxc_d0[4:0]; end 8'b01000000: begin detect_error_masked = detect_error[5:0]; + control_masked = xgmii_rxc_d0[5:0]; end 8'b10000000: begin detect_error_masked = detect_error[6:0]; + control_masked = xgmii_rxc_d0[6:0]; end default: begin detect_error_masked = detect_error; + control_masked = xgmii_rxc_d0; end endcase end @@ -360,8 +371,8 @@ always @* begin error_bad_frame_next = 1; reset_crc = 1; state_next = STATE_PAYLOAD; - end else if (detect_error_masked) begin - // error condition + end else if (control_masked) begin + // control or error characters in packet output_axis_tlast_next = 1; output_axis_tuser_next = 1; error_bad_frame_next = 1; From 6bd7309b9d849b67a59dd6b77e87ae5ef86da0dc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 9 Jul 2015 11:11:32 -0700 Subject: [PATCH 229/617] Properly reset all registers --- rtl/axis_async_fifo.v | 2 ++ rtl/axis_async_fifo_64.v | 2 ++ 2 files changed, 4 insertions(+) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 31a3f9338..1f755cdfb 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -125,6 +125,7 @@ end always @(posedge input_clk or posedge input_rst_sync2) begin if (input_rst_sync2) begin wr_ptr <= 0; + wr_ptr_gray <= 0; end else if (write) begin mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; wr_ptr_next = wr_ptr + 1; @@ -148,6 +149,7 @@ end always @(posedge output_clk or posedge output_rst_sync2) begin if (output_rst_sync2) begin rd_ptr <= 0; + rd_ptr_gray <= 0; end else if (read) begin data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; rd_ptr_next = rd_ptr + 1; diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index da1060b48..ee1d38056 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -128,6 +128,7 @@ end always @(posedge input_clk or posedge input_rst_sync2) begin if (input_rst_sync2) begin wr_ptr <= 0; + wr_ptr_gray <= 0; end else if (write) begin mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; wr_ptr_next = wr_ptr + 1; @@ -151,6 +152,7 @@ end always @(posedge output_clk or posedge output_rst_sync2) begin if (output_rst_sync2) begin rd_ptr <= 0; + rd_ptr_gray <= 0; end else if (read) begin data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; rd_ptr_next = rd_ptr + 1; From f387e4c3001ce9af1f013fae8270b0f5e5e2f861 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 9 Jul 2015 11:13:12 -0700 Subject: [PATCH 230/617] Remove unused register --- rtl/axis_async_fifo.v | 2 -- rtl/axis_async_fifo_64.v | 2 -- rtl/axis_fifo.v | 2 -- rtl/axis_fifo_64.v | 2 -- 4 files changed, 8 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 1f755cdfb..63ae2816a 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -78,8 +78,6 @@ reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_read = 1'b0; - reg output_axis_tvalid_reg = 1'b0; wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index ee1d38056..9e3dc9627 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -81,8 +81,6 @@ reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}} //(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_read = 1'b0; - reg output_axis_tvalid_reg = 1'b0; wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index 6a291ff99..d79836d8c 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -65,8 +65,6 @@ reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_read = 1'b0; - reg output_axis_tvalid_reg = 1'b0; wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v index 0accac316..28abfc411 100644 --- a/rtl/axis_fifo_64.v +++ b/rtl/axis_fifo_64.v @@ -68,8 +68,6 @@ reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}} //(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_read = 1'b0; - reg output_axis_tvalid_reg = 1'b0; wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; From 516c50d7867bac12f21de4d25bdcc6ab00d2bd06 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 9 Jul 2015 11:13:25 -0700 Subject: [PATCH 231/617] Add FIFO reset tests --- tb/test_axis_async_fifo.py | 84 +++++++++++++++++++++++++++++ tb/test_axis_async_fifo_64.py | 84 +++++++++++++++++++++++++++++ tb/test_axis_async_frame_fifo.py | 84 +++++++++++++++++++++++++++++ tb/test_axis_async_frame_fifo_64.py | 84 +++++++++++++++++++++++++++++ tb/test_axis_fifo.py | 55 +++++++++++++++++++ tb/test_axis_fifo_64.py | 55 +++++++++++++++++++ tb/test_axis_frame_fifo.py | 55 +++++++++++++++++++ tb/test_axis_frame_fifo_64.py | 55 +++++++++++++++++++ 8 files changed, 556 insertions(+) diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index 68090aaa3..817887c1f 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -401,6 +401,90 @@ def bench(): yield delay(100) + yield input_clk.posedge + print("test 8: initial sink pause") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + sink_pause.next = 0 + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_clk.posedge + print("test 9: initial sink pause, input reset") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + + input_rst.next = 1 + yield input_clk.posedge + input_rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + + assert sink_queue.empty() + + yield delay(100) + + yield input_clk.posedge + print("test 10: initial sink pause, output reset") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + + output_rst.next = 1 + yield output_clk.posedge + output_rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, source, sink, input_clkgen, output_clkgen, check diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index 94be27207..e72c4ebcc 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -411,6 +411,90 @@ def bench(): yield delay(100) + yield input_clk.posedge + print("test 8: initial sink pause") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + sink_pause.next = 0 + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_clk.posedge + print("test 9: initial sink pause, input reset") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + + input_rst.next = 1 + yield input_clk.posedge + input_rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + + assert sink_queue.empty() + + yield delay(100) + + yield input_clk.posedge + print("test 10: initial sink pause, output reset") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + + output_rst.next = 1 + yield output_clk.posedge + output_rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, source, sink, input_clkgen, output_clkgen, check diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index 75c30747e..77b87f45b 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -510,6 +510,90 @@ def bench(): yield delay(100) + yield input_clk.posedge + print("test 9: initial sink pause") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + sink_pause.next = 0 + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_clk.posedge + print("test 10: initial sink pause, input reset") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + + input_rst.next = 1 + yield input_clk.posedge + input_rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + + assert sink_queue.empty() + + yield delay(100) + + yield input_clk.posedge + print("test 11: initial sink pause, output reset") + current_test.next = 11 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + + output_rst.next = 1 + yield output_clk.posedge + output_rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, monitor, source, sink, input_clkgen, output_clkgen, check diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index 5f0fb2b2c..5c5cb6ade 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -520,6 +520,90 @@ def bench(): yield delay(100) + yield input_clk.posedge + print("test 9: initial sink pause") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + sink_pause.next = 0 + + yield output_axis_tlast.posedge + yield output_clk.posedge + yield output_clk.posedge + + rx_frame = None + if not sink_queue.empty(): + rx_frame = sink_queue.get() + + assert rx_frame == test_frame + + yield delay(100) + + yield input_clk.posedge + print("test 10: initial sink pause, input reset") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + + input_rst.next = 1 + yield input_clk.posedge + input_rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + + assert sink_queue.empty() + + yield delay(100) + + yield input_clk.posedge + print("test 11: initial sink pause, output reset") + current_test.next = 11 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + yield input_clk.posedge + + output_rst.next = 1 + yield output_clk.posedge + output_rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield output_clk.posedge + yield output_clk.posedge + yield output_clk.posedge + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, monitor, source, sink, input_clkgen, output_clkgen, check diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index de7a2ba71..19382b3b5 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -385,6 +385,61 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 8: initial sink pause") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = 0 + + 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 9: initial sink pause, reset") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rst.next = 1 + yield clk.posedge + rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, source, sink, clkgen, check diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index 320dd60a0..9ebbe3e50 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -395,6 +395,61 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 8: initial sink pause") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = 0 + + 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 9: initial sink pause, reset") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rst.next = 1 + yield clk.posedge + rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, source, sink, clkgen, check diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index 84868e765..d01334821 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -490,6 +490,61 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 9: initial sink pause") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = 0 + + 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 10: initial sink pause, reset") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rst.next = 1 + yield clk.posedge + rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, monitor, source, sink, clkgen, check diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index ed8524dcf..b37f483ac 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -505,6 +505,61 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 9: initial sink pause") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = 0 + + 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 10: initial sink pause, reset") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rst.next = 1 + yield clk.posedge + rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, monitor, source, sink, clkgen, check From 04e4ccc5179dd343985db7876043d84de4c18145 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 9 Jul 2015 11:25:49 -0700 Subject: [PATCH 232/617] Update for compatibility with older version of Python --- rtl/axis_arb_mux.py | 4 ++-- rtl/axis_arb_mux_64.py | 4 ++-- rtl/axis_crosspoint.py | 4 ++-- rtl/axis_crosspoint_64.py | 4 ++-- rtl/axis_demux.py | 4 ++-- rtl/axis_demux_64.py | 4 ++-- rtl/axis_frame_join.py | 4 ++-- rtl/axis_mux.py | 4 ++-- rtl/axis_mux_64.py | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index 9d37839d6..e0c128697 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -13,7 +13,7 @@ Usage: axis_arb_mux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/axis_arb_mux_64.py b/rtl/axis_arb_mux_64.py index 873c2e2a9..ecbd81019 100755 --- a/rtl/axis_arb_mux_64.py +++ b/rtl/axis_arb_mux_64.py @@ -13,7 +13,7 @@ Usage: axis_arb_mux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index e37707bb3..985aae771 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -13,7 +13,7 @@ Usage: axis_crosspoint [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream crosspoint {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index 12dbe8ae5..158396e13 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -13,7 +13,7 @@ Usage: axis_crosspoint_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream crosspoint {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index d7ce6ceaa..ac32eca95 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -13,7 +13,7 @@ Usage: axis_demux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream demux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index cf927c1fb..807f19bfd 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -13,7 +13,7 @@ Usage: axis_demux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream demux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index c01ed0ff0..896f50c71 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -13,7 +13,7 @@ Usage: axis_frame_join [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream frame joiner {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 122c96026..8230bfd4b 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -13,7 +13,7 @@ Usage: axis_mux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index 29b3f7aa9..31fd2a663 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -13,7 +13,7 @@ Usage: axis_mux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* From 2667c9c631c509562b8ccb80b6ab2d71d5d27a19 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 9 Jul 2015 11:35:55 -0700 Subject: [PATCH 233/617] Update for compatibility with older version of Python --- rtl/eth_arb_mux.py | 4 ++-- rtl/eth_arb_mux_64.py | 4 ++-- rtl/eth_demux.py | 4 ++-- rtl/eth_demux_64.py | 4 ++-- rtl/eth_mux.py | 4 ++-- rtl/eth_mux_64.py | 4 ++-- rtl/ip_arb_mux.py | 4 ++-- rtl/ip_arb_mux_64.py | 4 ++-- rtl/ip_demux.py | 4 ++-- rtl/ip_demux_64.py | 4 ++-- rtl/ip_mux.py | 4 ++-- rtl/ip_mux_64.py | 4 ++-- rtl/udp_arb_mux.py | 4 ++-- rtl/udp_arb_mux_64.py | 4 ++-- rtl/udp_demux.py | 4 ++-- rtl/udp_demux_64.py | 4 ++-- rtl/udp_mux.py | 4 ++-- rtl/udp_mux_64.py | 4 ++-- 18 files changed, 36 insertions(+), 36 deletions(-) diff --git a/rtl/eth_arb_mux.py b/rtl/eth_arb_mux.py index 998ff328b..f04dcd965 100755 --- a/rtl/eth_arb_mux.py +++ b/rtl/eth_arb_mux.py @@ -13,7 +13,7 @@ Usage: eth_arb_mux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/eth_arb_mux_64.py b/rtl/eth_arb_mux_64.py index 9c7b642f5..4a8c8a38e 100755 --- a/rtl/eth_arb_mux_64.py +++ b/rtl/eth_arb_mux_64.py @@ -13,7 +13,7 @@ Usage: eth_arb_mux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py index 302f75790..8c1d024ea 100755 --- a/rtl/eth_demux.py +++ b/rtl/eth_demux.py @@ -13,7 +13,7 @@ Usage: eth_demux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port Ethernet demux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py index 2950af1dd..7ab156851 100755 --- a/rtl/eth_demux_64.py +++ b/rtl/eth_demux_64.py @@ -13,7 +13,7 @@ Usage: eth_demux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port Ethernet demux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index 088e821d5..954261aaf 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -13,7 +13,7 @@ Usage: eth_mux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port Ethernet mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index 8e7fadda4..17d223d86 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -13,7 +13,7 @@ Usage: eth_mux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port Ethernet mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/ip_arb_mux.py b/rtl/ip_arb_mux.py index 40de019f2..343bb53cb 100755 --- a/rtl/ip_arb_mux.py +++ b/rtl/ip_arb_mux.py @@ -13,7 +13,7 @@ Usage: ip_arb_mux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/ip_arb_mux_64.py b/rtl/ip_arb_mux_64.py index 17e10a910..01d83f1ea 100755 --- a/rtl/ip_arb_mux_64.py +++ b/rtl/ip_arb_mux_64.py @@ -13,7 +13,7 @@ Usage: ip_arb_mux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py index 0af4ed028..13004c01b 100755 --- a/rtl/ip_demux.py +++ b/rtl/ip_demux.py @@ -13,7 +13,7 @@ Usage: ip_demux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port IP demux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py index 441e0a328..471c740bc 100755 --- a/rtl/ip_demux_64.py +++ b/rtl/ip_demux_64.py @@ -13,7 +13,7 @@ Usage: ip_demux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port IP demux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py index c5f3e833e..10235c857 100755 --- a/rtl/ip_mux.py +++ b/rtl/ip_mux.py @@ -13,7 +13,7 @@ Usage: ip_mux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port IP mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py index 4b45b71c1..01094dbc3 100755 --- a/rtl/ip_mux_64.py +++ b/rtl/ip_mux_64.py @@ -13,7 +13,7 @@ Usage: ip_mux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port IP mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/udp_arb_mux.py b/rtl/udp_arb_mux.py index 0a8f53c7c..512edccd2 100755 --- a/rtl/udp_arb_mux.py +++ b/rtl/udp_arb_mux.py @@ -13,7 +13,7 @@ Usage: udp_arb_mux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/udp_arb_mux_64.py b/rtl/udp_arb_mux_64.py index 8151998ab..965d68346 100755 --- a/rtl/udp_arb_mux_64.py +++ b/rtl/udp_arb_mux_64.py @@ -13,7 +13,7 @@ Usage: udp_arb_mux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py index 7ddeadefd..acca63340 100755 --- a/rtl/udp_demux.py +++ b/rtl/udp_demux.py @@ -13,7 +13,7 @@ Usage: udp_demux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port UDP demux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py index 1ab008f38..d89b6f192 100755 --- a/rtl/udp_demux_64.py +++ b/rtl/udp_demux_64.py @@ -13,7 +13,7 @@ Usage: udp_demux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port UDP demux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py index c56b24bd7..dda37ee00 100755 --- a/rtl/udp_mux.py +++ b/rtl/udp_mux.py @@ -13,7 +13,7 @@ Usage: udp_mux [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port UDP mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py index 1e3b79db2..536b4d9eb 100755 --- a/rtl/udp_mux_64.py +++ b/rtl/udp_mux_64.py @@ -13,7 +13,7 @@ Usage: udp_mux_64 [OPTION]... import io import sys import getopt -from math import * +import math from jinja2 import Template class Usage(Exception): @@ -66,7 +66,7 @@ def main(argv=None): print("Generating {0} port UDP mux {1}...".format(ports, name)) - select_width = ceil(log2(ports)) + select_width = int(math.ceil(math.log(ports, 2))) t = Template(u"""/* From 88f3e97badb3fae405c0b9d2c637e2be62b80fca Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 9 Jul 2015 11:52:06 -0700 Subject: [PATCH 234/617] Update readme --- README.md | 120 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index fac23527b..bc5d16d83 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,29 @@ Frame joiner with optional tag. 8 bit data path only. Can be generated with arbitrary port counts with axis_frame_join.py. +### axis_frame_length_adjust module + +Frame length adjuster module. Truncates or pads frames as necessary to meet +the specified minimum and maximum length. Reports the original and current +lengths as well as whether the packet was truncated or padded. Length limits +are configurable at run time. + +### axis_frame_length_adjust_fifo module + +Frame length adjuster module with FIFO. Truncates or pads frames as necessary +to meet the specified minimum and maximum length. Reports the original and +current lengths as well as whether the packet was truncated or padded. FIFOs +are used so that the status information can be read before the packet itself. +Length limits are configurable at run time. + +### axis_frame_length_adjust_fifo_64 module + +Frame length adjuster module with FIFO. Truncates or pads frames as necessary +to meet the specified minimum and maximum length. Reports the original and +current lengths as well as whether the packet was truncated or padded. FIFOs +are used so that the status information can be read before the packet itself. +Length limits are configurable at run time. Packet FIFO has a tkeep signal. + ### axis_ll_bridge module AXI stream to LocalLink bridge. @@ -182,6 +205,18 @@ AXI stream interface. Trigger signal used to reset and dump counts out of AXI interface, along with tag value. Use with axis_frame_join_N to form a single monolithic frame from multiple monitored points with the same trigger. +### axis_tap module + +AXI stream tap module. Used to make a copy of an AXI stream bus without +affecting the bus. Back-pressure on the output results in truncated frames +with tuser set. + +### axis_tap_64 module + +AXI stream tap module with tkeep signal. Used to make a copy of an AXI stream +bus without affecting the bus. Back-pressure on the output results in +truncated frames with tuser set. + ### ll_axis_bridge module LocalLink to AXI stream bridge. @@ -201,46 +236,51 @@ Parametrizable priority encoder. ### Source Files - rtl/arbiter.v : General-purpose parametrizable arbiter - rtl/axis_adapter.v : Parametrizable bus width adapter - rtl/axis_arb_mux.py : Arbitrated multiplexer generator - rtl/axis_arb_mux_4.v : 4 port arbitrated multiplexer - rtl/axis_arb_mux_64.py : Arbitrated multiplexer generator (64 bit) - rtl/axis_arb_mux_64_4.v : 4 port arbitrated multiplexer (64 bit) - rtl/axis_async_fifo.v : Asynchronous FIFO - rtl/axis_async_fifo_64.v : Asynchronous FIFO (64 bit) - rtl/axis_async_frame_fifo.v : Asynchronous frame FIFO - rtl/axis_async_frame_fifo_64.v : Asynchronous frame FIFO (64 bit) - rtl/axis_crosspoint.py : Crosspoint switch generator - rtl/axis_crosspoint_4x4.v : 4x4 crosspoint switch - rtl/axis_crosspoint_64.py : Crosspoint switch generator (64 bit) - rtl/axis_crosspoint_64_4x4.v : 4x4 crosspoint switch (64 bit) - rtl/axis_demux.py : Demultiplexer generator - rtl/axis_demux_4.v : 4 port demultiplexer - rtl/axis_demux_64.py : Demultiplexer generator (64 bit) - rtl/axis_demux_64_4.v : 4 port demultiplexer (64 bit) - rtl/axis_fifo.v : Synchronous FIFO - rtl/axis_fifo_64.v : Synchronous FIFO (64 bit) - rtl/axis_frame_fifo.v : Synchronous frame FIFO - rtl/axis_frame_fifo_64.v : Synchronous frame FIFO (64 bit) - rtl/axis_frame_join.py : Frame joiner generator - rtl/axis_frame_join_4.v : 4 port frame joiner - rtl/axis_ll_bridge.v : AXI stream to LocalLink bridge - rtl/axis_mux.py : Multiplexer generator - rtl/axis_mux_4.v : 4 port multiplexer - rtl/axis_mux_64.py : Multiplexer generator (64 bit) - rtl/axis_mux_64_4.v : 4 port multiplexer (64 bit) - rtl/axis_rate_limit.v : Fractional rate limiter - rtl/axis_rate_limit_64.v : Fractional rate limiter (64 bit) - rtl/axis_register.v : AXI Stream register - 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/ll_axis_bridge.v : LocalLink to AXI stream bridge - rtl/priority_encoder.v : Parametrizable priority encoder + arbiter.v : General-purpose parametrizable arbiter + axis_adapter.v : Parametrizable bus width adapter + axis_arb_mux.py : Arbitrated multiplexer generator + axis_arb_mux_4.v : 4 port arbitrated multiplexer + axis_arb_mux_64.py : Arbitrated multiplexer generator (64 bit) + axis_arb_mux_64_4.v : 4 port arbitrated multiplexer (64 bit) + axis_async_fifo.v : Asynchronous FIFO + axis_async_fifo_64.v : Asynchronous FIFO (64 bit) + axis_async_frame_fifo.v : Asynchronous frame FIFO + axis_async_frame_fifo_64.v : Asynchronous frame FIFO (64 bit) + axis_crosspoint.py : Crosspoint switch generator + axis_crosspoint_4x4.v : 4x4 crosspoint switch + axis_crosspoint_64.py : Crosspoint switch generator (64 bit) + axis_crosspoint_64_4x4.v : 4x4 crosspoint switch (64 bit) + axis_demux.py : Demultiplexer generator + axis_demux_4.v : 4 port demultiplexer + axis_demux_64.py : Demultiplexer generator (64 bit) + axis_demux_64_4.v : 4 port demultiplexer (64 bit) + axis_fifo.v : Synchronous FIFO + axis_fifo_64.v : Synchronous FIFO (64 bit) + axis_frame_fifo.v : Synchronous frame FIFO + axis_frame_fifo_64.v : Synchronous frame FIFO (64 bit) + axis_frame_join.py : Frame joiner generator + axis_frame_join_4.v : 4 port frame joiner + axis_frame_length_adjust.v : Frame length adjuster + axis_frame_length_adjust_fifo.v : Frame length adjuster with FIFO + axis_frame_length_adjust_fifo_64.v : Frame length adjuster with FIFO (64 bit) + axis_ll_bridge.v : AXI stream to LocalLink bridge + axis_mux.py : Multiplexer generator + axis_mux_4.v : 4 port multiplexer + axis_mux_64.py : Multiplexer generator (64 bit) + axis_mux_64_4.v : 4 port multiplexer (64 bit) + axis_rate_limit.v : Fractional rate limiter + axis_rate_limit_64.v : Fractional rate limiter (64 bit) + axis_register.v : AXI Stream register + axis_register_64.v : AXI Stream register (64 bit) + axis_srl_fifo.v : SRL-based FIFO + axis_srl_fifo_64.v : SRL-based FIFO (64 bit) + axis_srl_register.v : SRL-based register + axis_srl_register_64.v : SRL-based register (64 bit) + axis_stat_counter.v : Statistics counter + axis_tap.v : AXI stream tap + axis_tap_64.v : AXI stream tap (64 bit) + ll_axis_bridge.v : LocalLink to AXI stream bridge + priority_encoder.v : Parametrizable priority encoder ### AXI Stream Interface Example From dfab866e9950df51f488a841674ffdec1b96864b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 13 Jul 2015 23:09:02 -0700 Subject: [PATCH 235/617] Remove unused reg --- rtl/axis_srl_fifo.v | 3 +-- rtl/axis_srl_fifo_64.v | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/rtl/axis_srl_fifo.v b/rtl/axis_srl_fifo.v index 2e8075238..6a15d7d4d 100644 --- a/rtl/axis_srl_fifo.v +++ b/rtl/axis_srl_fifo.v @@ -63,7 +63,7 @@ module axis_srl_fifo # ); reg [DATA_WIDTH+2-1:0] data_reg[DEPTH-1:0]; -reg [$clog2(DEPTH+1)-1:0] ptr_reg = 0, ptr_next; +reg [$clog2(DEPTH+1)-1:0] ptr_reg = 0; reg full_reg = 0, full_next; reg empty_reg = 1, empty_next; @@ -93,7 +93,6 @@ always @* begin shift = 0; inc = 0; dec = 0; - ptr_next = ptr_reg; full_next = full_reg; empty_next = empty_reg; diff --git a/rtl/axis_srl_fifo_64.v b/rtl/axis_srl_fifo_64.v index 3f176f54a..fb3480e44 100644 --- a/rtl/axis_srl_fifo_64.v +++ b/rtl/axis_srl_fifo_64.v @@ -66,7 +66,7 @@ module axis_srl_fifo_64 # ); 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 [$clog2(DEPTH+1)-1:0] ptr_reg = 0; reg full_reg = 0, full_next; reg empty_reg = 1, empty_next; @@ -96,7 +96,6 @@ always @* begin shift = 0; inc = 0; dec = 0; - ptr_next = ptr_reg; full_next = full_reg; empty_next = empty_reg; From ac97cffc2b45f4bc9e7fe884c2aea04cf2ca17d2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 13 Jul 2015 23:15:09 -0700 Subject: [PATCH 236/617] Properly reset all registers --- rtl/axis_srl_fifo.v | 2 ++ rtl/axis_srl_fifo_64.v | 2 ++ rtl/axis_srl_register.v | 1 + rtl/axis_srl_register_64.v | 1 + 4 files changed, 6 insertions(+) diff --git a/rtl/axis_srl_fifo.v b/rtl/axis_srl_fifo.v index 6a15d7d4d..b5b887cd0 100644 --- a/rtl/axis_srl_fifo.v +++ b/rtl/axis_srl_fifo.v @@ -115,6 +115,8 @@ end always @(posedge clk) begin if (rst) begin ptr_reg <= 0; + full_reg <= 0; + empty_reg <= 1; end else begin if (shift) begin data_reg[0] <= {input_axis_tlast, input_axis_tuser, input_axis_tdata}; diff --git a/rtl/axis_srl_fifo_64.v b/rtl/axis_srl_fifo_64.v index fb3480e44..8411b94d1 100644 --- a/rtl/axis_srl_fifo_64.v +++ b/rtl/axis_srl_fifo_64.v @@ -118,6 +118,8 @@ end always @(posedge clk) begin if (rst) begin ptr_reg <= 0; + full_reg <= 0; + empty_reg <= 1; end else begin if (shift) begin data_reg[0] <= {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; diff --git a/rtl/axis_srl_register.v b/rtl/axis_srl_register.v index 52666e5c3..2e4ea4731 100644 --- a/rtl/axis_srl_register.v +++ b/rtl/axis_srl_register.v @@ -77,6 +77,7 @@ end always @(posedge clk) begin if (rst) begin ptr_reg <= 0; + full_reg <= 0; end else begin // transfer empty to full full_reg <= ~output_axis_tready & output_axis_tvalid; diff --git a/rtl/axis_srl_register_64.v b/rtl/axis_srl_register_64.v index 28ff084d8..3c569f596 100644 --- a/rtl/axis_srl_register_64.v +++ b/rtl/axis_srl_register_64.v @@ -80,6 +80,7 @@ end always @(posedge clk) begin if (rst) begin ptr_reg <= 0; + full_reg <= 0; end else begin // transfer empty to full full_reg <= ~output_axis_tready & output_axis_tvalid; From 120f86f4cf4562ed33e0a385f1067b551a5fad6d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 13 Jul 2015 23:15:39 -0700 Subject: [PATCH 237/617] Add SRL FIFO reset tests --- tb/test_axis_srl_fifo.py | 55 +++++++++++++++++++++++++++++++++++++ tb/test_axis_srl_fifo_64.py | 55 +++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py index 1e466a7ce..0f4faa28f 100755 --- a/tb/test_axis_srl_fifo.py +++ b/tb/test_axis_srl_fifo.py @@ -393,6 +393,61 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 8: initial sink pause") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = 0 + + 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 9: initial sink pause, reset") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rst.next = 1 + yield clk.posedge + rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, source, sink, clkgen, check diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py index 1b3fe413e..ee7004a5f 100755 --- a/tb/test_axis_srl_fifo_64.py +++ b/tb/test_axis_srl_fifo_64.py @@ -403,6 +403,61 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 8: initial sink pause") + current_test.next = 8 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = 0 + + 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 9: initial sink pause, reset") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + + sink_pause.next = 1 + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rst.next = 1 + yield clk.posedge + rst.next = 0 + + sink_pause.next = 0 + + yield delay(100) + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert sink_queue.empty() + + yield delay(100) + raise StopSimulation return dut, source, sink, clkgen, check From 26b165227c46fb60a7b0b9f4e9343f61df8eb6a5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 14 Jul 2015 08:27:49 -0700 Subject: [PATCH 238/617] Update for compatibility with older versions of Python --- rtl/axis_arb_mux.py | 2 ++ rtl/axis_arb_mux_64.py | 2 ++ rtl/axis_crosspoint.py | 2 ++ rtl/axis_crosspoint_64.py | 2 ++ rtl/axis_demux.py | 2 ++ rtl/axis_demux_64.py | 2 ++ rtl/axis_frame_join.py | 2 ++ rtl/axis_mux.py | 2 ++ rtl/axis_mux_64.py | 2 ++ 9 files changed, 18 insertions(+) diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index e0c128697..51629e20e 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -10,6 +10,8 @@ Usage: axis_arb_mux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/axis_arb_mux_64.py b/rtl/axis_arb_mux_64.py index ecbd81019..ae354538d 100755 --- a/rtl/axis_arb_mux_64.py +++ b/rtl/axis_arb_mux_64.py @@ -10,6 +10,8 @@ Usage: axis_arb_mux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index 985aae771..24eda4211 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -10,6 +10,8 @@ Usage: axis_crosspoint [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index 158396e13..75261be8a 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -10,6 +10,8 @@ Usage: axis_crosspoint_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index ac32eca95..68838dfd0 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -10,6 +10,8 @@ Usage: axis_demux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index 807f19bfd..03931d3ea 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -10,6 +10,8 @@ Usage: axis_demux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index 896f50c71..912b260ba 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -10,6 +10,8 @@ Usage: axis_frame_join [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 8230bfd4b..d7d3b64fd 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -10,6 +10,8 @@ Usage: axis_mux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index 31fd2a663..b1d480d60 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -10,6 +10,8 @@ Usage: axis_mux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt From af8bed8237f63d797acb4d9b6a8b2659e6e855ca Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 14 Jul 2015 08:29:54 -0700 Subject: [PATCH 239/617] Update for compatibility with older versions of Python --- rtl/eth_arb_mux.py | 2 ++ rtl/eth_arb_mux_64.py | 2 ++ rtl/eth_demux.py | 2 ++ rtl/eth_demux_64.py | 2 ++ rtl/eth_mux.py | 2 ++ rtl/eth_mux_64.py | 2 ++ rtl/ip_arb_mux.py | 2 ++ rtl/ip_arb_mux_64.py | 2 ++ rtl/ip_demux.py | 2 ++ rtl/ip_demux_64.py | 2 ++ rtl/ip_mux.py | 2 ++ rtl/ip_mux_64.py | 2 ++ rtl/udp_arb_mux.py | 2 ++ rtl/udp_arb_mux_64.py | 2 ++ rtl/udp_demux.py | 2 ++ rtl/udp_demux_64.py | 2 ++ rtl/udp_mux.py | 2 ++ rtl/udp_mux_64.py | 2 ++ 18 files changed, 36 insertions(+) diff --git a/rtl/eth_arb_mux.py b/rtl/eth_arb_mux.py index f04dcd965..06549b579 100755 --- a/rtl/eth_arb_mux.py +++ b/rtl/eth_arb_mux.py @@ -10,6 +10,8 @@ Usage: eth_arb_mux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/eth_arb_mux_64.py b/rtl/eth_arb_mux_64.py index 4a8c8a38e..f777de8a8 100755 --- a/rtl/eth_arb_mux_64.py +++ b/rtl/eth_arb_mux_64.py @@ -10,6 +10,8 @@ Usage: eth_arb_mux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py index 8c1d024ea..1c14b38f2 100755 --- a/rtl/eth_demux.py +++ b/rtl/eth_demux.py @@ -10,6 +10,8 @@ Usage: eth_demux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py index 7ab156851..55820c698 100755 --- a/rtl/eth_demux_64.py +++ b/rtl/eth_demux_64.py @@ -10,6 +10,8 @@ Usage: eth_demux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index 954261aaf..cb3aaa6fc 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -10,6 +10,8 @@ Usage: eth_mux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index 17d223d86..2713acecb 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -10,6 +10,8 @@ Usage: eth_mux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/ip_arb_mux.py b/rtl/ip_arb_mux.py index 343bb53cb..92f83fc41 100755 --- a/rtl/ip_arb_mux.py +++ b/rtl/ip_arb_mux.py @@ -10,6 +10,8 @@ Usage: ip_arb_mux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/ip_arb_mux_64.py b/rtl/ip_arb_mux_64.py index 01d83f1ea..43d76e1b9 100755 --- a/rtl/ip_arb_mux_64.py +++ b/rtl/ip_arb_mux_64.py @@ -10,6 +10,8 @@ Usage: ip_arb_mux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py index 13004c01b..3b848c34a 100755 --- a/rtl/ip_demux.py +++ b/rtl/ip_demux.py @@ -10,6 +10,8 @@ Usage: ip_demux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py index 471c740bc..754fcbf2c 100755 --- a/rtl/ip_demux_64.py +++ b/rtl/ip_demux_64.py @@ -10,6 +10,8 @@ Usage: ip_demux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py index 10235c857..513168b18 100755 --- a/rtl/ip_mux.py +++ b/rtl/ip_mux.py @@ -10,6 +10,8 @@ Usage: ip_mux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py index 01094dbc3..5f2e37143 100755 --- a/rtl/ip_mux_64.py +++ b/rtl/ip_mux_64.py @@ -10,6 +10,8 @@ Usage: ip_mux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/udp_arb_mux.py b/rtl/udp_arb_mux.py index 512edccd2..99417864d 100755 --- a/rtl/udp_arb_mux.py +++ b/rtl/udp_arb_mux.py @@ -10,6 +10,8 @@ Usage: udp_arb_mux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/udp_arb_mux_64.py b/rtl/udp_arb_mux_64.py index 965d68346..7ebb996c4 100755 --- a/rtl/udp_arb_mux_64.py +++ b/rtl/udp_arb_mux_64.py @@ -10,6 +10,8 @@ Usage: udp_arb_mux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py index acca63340..d18ccb2a9 100755 --- a/rtl/udp_demux.py +++ b/rtl/udp_demux.py @@ -10,6 +10,8 @@ Usage: udp_demux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py index d89b6f192..bf5c69402 100755 --- a/rtl/udp_demux_64.py +++ b/rtl/udp_demux_64.py @@ -10,6 +10,8 @@ Usage: udp_demux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py index dda37ee00..c06658483 100755 --- a/rtl/udp_mux.py +++ b/rtl/udp_mux.py @@ -10,6 +10,8 @@ Usage: udp_mux [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py index 536b4d9eb..3e80863c4 100755 --- a/rtl/udp_mux_64.py +++ b/rtl/udp_mux_64.py @@ -10,6 +10,8 @@ Usage: udp_mux_64 [OPTION]... -o, --output specify output file name """ +from __future__ import print_function + import io import sys import getopt From 4156d8511a26a28d83c86eacb62ccdc5a135857f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 7 Aug 2015 12:13:44 -0700 Subject: [PATCH 240/617] Rework CRC check --- rtl/eth_mac_10g_rx.v | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index 31362af90..cbb6a54d9 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -113,6 +113,8 @@ reg [31:0] crc_next5_save = 0; reg [31:0] crc_next6_save = 0; reg [31:0] crc_next7_save = 0; +reg [31:0] crc_check = 0; + assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; assign output_axis_tvalid = output_axis_tvalid_reg; @@ -186,54 +188,63 @@ always @* begin fcs_output_tdata_1 = 0; fcs_output_tkeep_0 = 8'b00001111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next7_save; end 8'b11111110: begin fcs_output_tdata_0 = {~crc_next4_save[23:0], xgmii_rxd_d1[39:0]}; fcs_output_tdata_1 = {56'd0, ~crc_next4_save[31:24]}; fcs_output_tkeep_0 = 8'b00011111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next0; end 8'b11111100: begin fcs_output_tdata_0 = {~crc_next5_save[15:0], xgmii_rxd_d1[47:0]}; fcs_output_tdata_1 = {48'd0, ~crc_next5_save[31:16]}; fcs_output_tkeep_0 = 8'b00111111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next1; end 8'b11111000: begin fcs_output_tdata_0 = {~crc_next6_save[7:0], xgmii_rxd_d1[55:0]}; fcs_output_tdata_1 = {40'd0, ~crc_next6_save[31:8]}; fcs_output_tkeep_0 = 8'b01111111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next2; end 8'b11110000: begin fcs_output_tdata_0 = xgmii_rxd_d1; fcs_output_tdata_1 = {32'd0, ~crc_next7_save[31:0]}; fcs_output_tkeep_0 = 8'b11111111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next3; end 8'b11100000: begin fcs_output_tdata_0 = {24'd0, ~crc_next0[31:0], xgmii_rxd_d0[7:0]}; fcs_output_tdata_1 = 0; fcs_output_tkeep_0 = 8'b00000001; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next4; end 8'b11000000: begin fcs_output_tdata_0 = {16'd0, ~crc_next1[31:0], xgmii_rxd_d0[15:0]}; fcs_output_tdata_1 = 0; fcs_output_tkeep_0 = 8'b00000011; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next5; end 8'b10000000: begin fcs_output_tdata_0 = {8'd0, ~crc_next2[31:0], xgmii_rxd_d0[23:0]}; fcs_output_tdata_1 = 0; fcs_output_tkeep_0 = 8'b00000111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next6; end default: begin fcs_output_tdata_0 = 0; fcs_output_tdata_1 = 0; fcs_output_tkeep_0 = 0; fcs_output_tkeep_1 = 0; + crc_check = 0; end endcase end @@ -384,7 +395,7 @@ always @* begin reset_crc = 1; output_axis_tkeep_next = fcs_output_tkeep_0; output_axis_tlast_next = 1; - if (xgmii_rxd_masked != fcs_output_tdata_1 || xgmii_rxd_d1 != fcs_output_tdata_0) begin + if (crc_check != 32'h2144df1c) begin output_axis_tuser_next = 1; error_bad_frame_next = 1; error_bad_fcs_next = 1; @@ -394,7 +405,7 @@ always @* begin // need extra cycle last_cycle_tkeep_next = fcs_output_tkeep_0; last_cycle_tuser_next = 0; - if (xgmii_rxd_masked != fcs_output_tdata_0) begin + if (crc_check != 32'h2144df1c) begin error_bad_frame_next = 1; error_bad_fcs_next = 1; last_cycle_tuser_next = 1; @@ -440,9 +451,15 @@ always @(posedge clk or posedge rst) begin error_bad_frame_reg <= 0; error_bad_fcs_reg <= 0; - + crc_state <= 32'hFFFFFFFF; + crc_next3_save <= 0; + crc_next4_save <= 0; + crc_next5_save <= 0; + crc_next6_save <= 0; + crc_next7_save <= 0; + xgmii_rxd_d0 <= 64'h0707070707070707; xgmii_rxd_d1 <= 64'h0707070707070707; From ca11618e6dbd46d9c36ccfd5879992a8b8cbb3e8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 8 Oct 2015 11:26:32 -0700 Subject: [PATCH 241/617] Convert to synchronous resets --- rtl/arbiter.v | 2 +- rtl/axis_adapter.v | 4 ++-- rtl/axis_crosspoint.py | 2 +- rtl/axis_crosspoint_4x4.v | 2 +- rtl/axis_crosspoint_64.py | 2 +- rtl/axis_crosspoint_64_4x4.v | 2 +- rtl/axis_demux.py | 4 ++-- rtl/axis_demux_4.v | 4 ++-- rtl/axis_demux_64.py | 4 ++-- rtl/axis_demux_64_4.v | 4 ++-- rtl/axis_fifo.v | 6 +++--- rtl/axis_fifo_64.v | 6 +++--- rtl/axis_frame_fifo.v | 6 +++--- rtl/axis_frame_fifo_64.v | 6 +++--- rtl/axis_frame_join.py | 4 ++-- rtl/axis_frame_join_4.v | 4 ++-- rtl/axis_frame_length_adjust.v | 4 ++-- rtl/axis_ll_bridge.v | 2 +- rtl/axis_mux.py | 4 ++-- rtl/axis_mux_4.v | 4 ++-- rtl/axis_mux_64.py | 4 ++-- rtl/axis_mux_64_4.v | 4 ++-- rtl/axis_rate_limit.v | 4 ++-- rtl/axis_rate_limit_64.v | 4 ++-- rtl/axis_register.v | 2 +- rtl/axis_register_64.v | 2 +- rtl/axis_stat_counter.v | 4 ++-- rtl/axis_tap.v | 4 ++-- rtl/axis_tap_64.v | 4 ++-- 29 files changed, 54 insertions(+), 54 deletions(-) diff --git a/rtl/arbiter.v b/rtl/arbiter.v index d6e06303d..8932b33de 100644 --- a/rtl/arbiter.v +++ b/rtl/arbiter.v @@ -136,7 +136,7 @@ always @* begin end end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin grant_reg <= 0; grant_valid_reg <= 0; diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index 8b621abcd..1eed1403b 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -368,7 +368,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; cycle_count_reg <= 0; @@ -413,7 +413,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index 24eda4211..c3d28c607 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -158,7 +158,7 @@ assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; {% endfor %} -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin {%- for p in ports %} output_{{p}}_select_reg <= 0; diff --git a/rtl/axis_crosspoint_4x4.v b/rtl/axis_crosspoint_4x4.v index 581fdf016..cb8a26a58 100644 --- a/rtl/axis_crosspoint_4x4.v +++ b/rtl/axis_crosspoint_4x4.v @@ -158,7 +158,7 @@ assign output_3_axis_tlast = output_3_axis_tlast_reg; assign output_3_axis_tuser = output_3_axis_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_0_select_reg <= 0; output_1_select_reg <= 0; diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index 75261be8a..537981541 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -164,7 +164,7 @@ assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; {% endfor %} -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin {%- for p in ports %} output_{{p}}_select_reg <= 0; diff --git a/rtl/axis_crosspoint_64_4x4.v b/rtl/axis_crosspoint_64_4x4.v index edf12f892..4e7688a36 100644 --- a/rtl/axis_crosspoint_64_4x4.v +++ b/rtl/axis_crosspoint_64_4x4.v @@ -179,7 +179,7 @@ assign output_3_axis_tlast = output_3_axis_tlast_reg; assign output_3_axis_tuser = output_3_axis_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_0_select_reg <= 0; output_1_select_reg <= 0; diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index 68838dfd0..e696c4b95 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -189,7 +189,7 @@ always @* begin output_axis_tuser_int = input_axis_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -222,7 +222,7 @@ assign output_{{p}}_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; {%- for p in ports %} diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v index e796b8347..493f5585f 100644 --- a/rtl/axis_demux_4.v +++ b/rtl/axis_demux_4.v @@ -144,7 +144,7 @@ always @* begin output_axis_tuser_int = input_axis_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -193,7 +193,7 @@ assign output_3_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_0_axis_tvalid_reg <= 0; diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index 03931d3ea..984da1372 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -194,7 +194,7 @@ always @* begin output_axis_tuser_int = input_axis_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -230,7 +230,7 @@ assign output_{{p}}_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; diff --git a/rtl/axis_demux_64_4.v b/rtl/axis_demux_64_4.v index d64f0b13a..e4fb0a441 100644 --- a/rtl/axis_demux_64_4.v +++ b/rtl/axis_demux_64_4.v @@ -152,7 +152,7 @@ always @* begin output_axis_tuser_int = input_axis_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -207,7 +207,7 @@ assign output_3_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index d79836d8c..c31f4ef1c 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -84,7 +84,7 @@ assign input_axis_tready = ~full; assign output_axis_tvalid = output_axis_tvalid_reg; // write -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin wr_ptr <= 0; end else if (write) begin @@ -94,7 +94,7 @@ always @(posedge clk or posedge rst) begin end // read -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin rd_ptr <= 0; end else if (read) begin @@ -104,7 +104,7 @@ always @(posedge clk or posedge rst) begin end // source ready output -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v index 28abfc411..7409df3e2 100644 --- a/rtl/axis_fifo_64.v +++ b/rtl/axis_fifo_64.v @@ -87,7 +87,7 @@ assign input_axis_tready = ~full; assign output_axis_tvalid = output_axis_tvalid_reg; // write -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin wr_ptr <= 0; end else if (write) begin @@ -97,7 +97,7 @@ always @(posedge clk or posedge rst) begin end // read -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin rd_ptr <= 0; end else if (read) begin @@ -107,7 +107,7 @@ always @(posedge clk or posedge rst) begin end // source ready output -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 46819e7c7..10e6805a0 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -104,7 +104,7 @@ assign bad_frame = bad_frame_reg; assign good_frame = good_frame_reg; // write -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin wr_ptr <= 0; wr_ptr_cur <= 0; @@ -147,7 +147,7 @@ always @(posedge clk or posedge rst) begin end // read -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin rd_ptr <= 0; end else if (read) begin @@ -157,7 +157,7 @@ always @(posedge clk or posedge rst) begin end // source ready output -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index a99331ad5..085d19725 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -107,7 +107,7 @@ assign bad_frame = bad_frame_reg; assign good_frame = good_frame_reg; // write -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin wr_ptr <= 0; wr_ptr_cur <= 0; @@ -150,7 +150,7 @@ always @(posedge clk or posedge rst) begin end // read -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin rd_ptr <= 0; end else if (read) begin @@ -160,7 +160,7 @@ always @(posedge clk or posedge rst) begin end // source ready output -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index 912b260ba..33252dd59 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -321,7 +321,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -366,7 +366,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index b6411207d..d57acf7cb 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -291,7 +291,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -339,7 +339,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; diff --git a/rtl/axis_frame_length_adjust.v b/rtl/axis_frame_length_adjust.v index ba1eb9550..35b037061 100644 --- a/rtl/axis_frame_length_adjust.v +++ b/rtl/axis_frame_length_adjust.v @@ -375,7 +375,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -432,7 +432,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; diff --git a/rtl/axis_ll_bridge.v b/rtl/axis_ll_bridge.v index 06186aef7..e095a261a 100644 --- a/rtl/axis_ll_bridge.v +++ b/rtl/axis_ll_bridge.v @@ -57,7 +57,7 @@ module axis_ll_bridge # reg last_tlast = 1'b1; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin last_tlast = 1'b1; end else begin diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index d7d3b64fd..8f0881593 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -214,7 +214,7 @@ always @* begin output_axis_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -249,7 +249,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v index 63f58ae9f..bafefba14 100644 --- a/rtl/axis_mux_4.v +++ b/rtl/axis_mux_4.v @@ -186,7 +186,7 @@ always @* begin output_axis_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -223,7 +223,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index b1d480d60..d011b6e03 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -221,7 +221,7 @@ always @* begin output_axis_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -259,7 +259,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; diff --git a/rtl/axis_mux_64_4.v b/rtl/axis_mux_64_4.v index 06d0d6749..624fad750 100644 --- a/rtl/axis_mux_64_4.v +++ b/rtl/axis_mux_64_4.v @@ -199,7 +199,7 @@ always @* begin output_axis_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -239,7 +239,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index cb5b733bf..fb0da33e8 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -109,7 +109,7 @@ always @* begin output_axis_tuser_int = input_axis_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin acc_reg <= 0; frame_reg <= 0; @@ -140,7 +140,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v index a6ce68165..be6cc1c2c 100644 --- a/rtl/axis_rate_limit_64.v +++ b/rtl/axis_rate_limit_64.v @@ -114,7 +114,7 @@ always @* begin output_axis_tuser_int = input_axis_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin acc_reg <= 0; frame_reg <= 0; @@ -148,7 +148,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; diff --git a/rtl/axis_register.v b/rtl/axis_register.v index 1032a2ae6..35ce7555d 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -76,7 +76,7 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin input_axis_tready_reg <= 0; output_axis_tdata_reg <= 0; diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v index c8ab746a6..c635b3f5a 100644 --- a/rtl/axis_register_64.v +++ b/rtl/axis_register_64.v @@ -82,7 +82,7 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin input_axis_tready_reg <= 0; output_axis_tdata_reg <= 0; diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index 94fd8e06f..77b99e735 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -238,7 +238,7 @@ always @* begin end end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; tick_count_reg <= 0; @@ -287,7 +287,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; diff --git a/rtl/axis_tap.v b/rtl/axis_tap.v index a79742653..b4fa25f91 100644 --- a/rtl/axis_tap.v +++ b/rtl/axis_tap.v @@ -158,7 +158,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_reg <= 0; @@ -187,7 +187,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; diff --git a/rtl/axis_tap_64.v b/rtl/axis_tap_64.v index 0e73ece6c..bed8668bc 100644 --- a/rtl/axis_tap_64.v +++ b/rtl/axis_tap_64.v @@ -166,7 +166,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_reg <= 0; @@ -198,7 +198,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; From 30a35c3d732005551e2f3a878e1b070711e182ef Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 8 Oct 2015 12:52:51 -0700 Subject: [PATCH 242/617] Convert async fifo to common reset --- rtl/axis_async_fifo.v | 15 ++++--- rtl/axis_async_fifo_64.v | 15 ++++--- rtl/axis_async_frame_fifo.v | 15 ++++--- rtl/axis_async_frame_fifo_64.v | 15 ++++--- tb/test_axis_async_fifo.py | 61 ++++++----------------------- tb/test_axis_async_fifo.v | 12 +++--- tb/test_axis_async_fifo_64.py | 61 ++++++----------------------- tb/test_axis_async_fifo_64.v | 12 +++--- tb/test_axis_async_frame_fifo.py | 61 ++++++----------------------- tb/test_axis_async_frame_fifo.v | 12 +++--- tb/test_axis_async_frame_fifo_64.py | 61 ++++++----------------------- tb/test_axis_async_frame_fifo_64.v | 12 +++--- 12 files changed, 108 insertions(+), 244 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 63ae2816a..4dcb22695 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -35,11 +35,15 @@ module axis_async_fifo # parameter DATA_WIDTH = 8 ) ( + /* + * Common asynchronous reset + */ + input wire async_rst, + /* * AXI input */ input wire input_clk, - input wire input_rst, input wire [DATA_WIDTH-1:0] input_axis_tdata, input wire input_axis_tvalid, output wire input_axis_tready, @@ -50,7 +54,6 @@ module axis_async_fifo # * AXI output */ input wire output_clk, - input wire output_rst, output wire [DATA_WIDTH-1:0] output_axis_tdata, output wire output_axis_tvalid, input wire output_axis_tready, @@ -99,8 +102,8 @@ assign input_axis_tready = ~full; assign output_axis_tvalid = output_axis_tvalid_reg; // reset synchronization -always @(posedge input_clk or posedge input_rst or posedge output_rst) begin - if (input_rst | output_rst) begin +always @(posedge input_clk or posedge async_rst) begin + if (async_rst) begin input_rst_sync1 <= 1; input_rst_sync2 <= 1; end else begin @@ -109,8 +112,8 @@ always @(posedge input_clk or posedge input_rst or posedge output_rst) begin end end -always @(posedge output_clk or posedge input_rst or posedge output_rst) begin - if (input_rst | output_rst) begin +always @(posedge output_clk or posedge async_rst) begin + if (async_rst) begin output_rst_sync1 <= 1; output_rst_sync2 <= 1; end else begin diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index 9e3dc9627..7303b87fc 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -36,11 +36,15 @@ module axis_async_fifo_64 # parameter KEEP_WIDTH = (DATA_WIDTH/8) ) ( + /* + * Common asynchronous reset + */ + input wire async_rst, + /* * AXI input */ input wire input_clk, - input wire input_rst, input wire [DATA_WIDTH-1:0] input_axis_tdata, input wire [KEEP_WIDTH-1:0] input_axis_tkeep, input wire input_axis_tvalid, @@ -52,7 +56,6 @@ module axis_async_fifo_64 # * AXI output */ input wire output_clk, - input wire output_rst, output wire [DATA_WIDTH-1:0] output_axis_tdata, output wire [KEEP_WIDTH-1:0] output_axis_tkeep, output wire output_axis_tvalid, @@ -102,8 +105,8 @@ assign input_axis_tready = ~full; assign output_axis_tvalid = output_axis_tvalid_reg; // reset synchronization -always @(posedge input_clk or posedge input_rst or posedge output_rst) begin - if (input_rst | output_rst) begin +always @(posedge input_clk or posedge async_rst) begin + if (async_rst) begin input_rst_sync1 <= 1; input_rst_sync2 <= 1; end else begin @@ -112,8 +115,8 @@ always @(posedge input_clk or posedge input_rst or posedge output_rst) begin end end -always @(posedge output_clk or posedge input_rst or posedge output_rst) begin - if (input_rst | output_rst) begin +always @(posedge output_clk or posedge async_rst) begin + if (async_rst) begin output_rst_sync1 <= 1; output_rst_sync2 <= 1; end else begin diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 8fdcbff84..e0e215ecc 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -36,11 +36,15 @@ module axis_async_frame_fifo # parameter DROP_WHEN_FULL = 0 ) ( + /* + * Common asynchronous reset + */ + input wire async_rst, + /* * AXI input */ input wire input_clk, - input wire input_rst, input wire [DATA_WIDTH-1:0] input_axis_tdata, input wire input_axis_tvalid, output wire input_axis_tready, @@ -51,7 +55,6 @@ module axis_async_frame_fifo # * AXI output */ input wire output_clk, - input wire output_rst, output wire [DATA_WIDTH-1:0] output_axis_tdata, output wire output_axis_tvalid, input wire output_axis_tready, @@ -119,8 +122,8 @@ assign bad_frame = bad_frame_reg; assign good_frame = good_frame_reg; // reset synchronization -always @(posedge input_clk or posedge input_rst or posedge output_rst) begin - if (input_rst | output_rst) begin +always @(posedge input_clk or posedge async_rst) begin + if (async_rst) begin input_rst_sync1 <= 1; input_rst_sync2 <= 1; end else begin @@ -129,8 +132,8 @@ always @(posedge input_clk or posedge input_rst or posedge output_rst) begin end end -always @(posedge output_clk or posedge input_rst or posedge output_rst) begin - if (input_rst | output_rst) begin +always @(posedge output_clk or posedge async_rst) begin + if (async_rst) begin output_rst_sync1 <= 1; output_rst_sync2 <= 1; end else begin diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 2a0d88d2f..0847cd235 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -37,11 +37,15 @@ module axis_async_frame_fifo_64 # parameter DROP_WHEN_FULL = 0 ) ( + /* + * Common asynchronous reset + */ + input wire async_rst, + /* * AXI input */ input wire input_clk, - input wire input_rst, input wire [DATA_WIDTH-1:0] input_axis_tdata, input wire [KEEP_WIDTH-1:0] input_axis_tkeep, input wire input_axis_tvalid, @@ -53,7 +57,6 @@ module axis_async_frame_fifo_64 # * AXI output */ input wire output_clk, - input wire output_rst, output wire [DATA_WIDTH-1:0] output_axis_tdata, output wire [KEEP_WIDTH-1:0] output_axis_tkeep, output wire output_axis_tvalid, @@ -122,8 +125,8 @@ assign bad_frame = bad_frame_reg; assign good_frame = good_frame_reg; // reset synchronization -always @(posedge input_clk or posedge input_rst or posedge output_rst) begin - if (input_rst | output_rst) begin +always @(posedge input_clk or posedge async_rst) begin + if (async_rst) begin input_rst_sync1 <= 1; input_rst_sync2 <= 1; end else begin @@ -132,8 +135,8 @@ always @(posedge input_clk or posedge input_rst or posedge output_rst) begin end end -always @(posedge output_clk or posedge input_rst or posedge output_rst) begin - if (input_rst | output_rst) begin +always @(posedge output_clk or posedge async_rst) begin + if (async_rst) begin output_rst_sync1 <= 1; output_rst_sync2 <= 1; end else begin diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index 817887c1f..28f759c5d 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -44,10 +44,9 @@ src = ' '.join(srcs) build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) -def dut_axis_async_fifo(input_clk, - input_rst, +def dut_axis_async_fifo(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, @@ -65,10 +64,9 @@ def dut_axis_async_fifo(input_clk, if os.system(build_cmd): raise Exception("Error running build command") return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + async_rst=async_rst, input_clk=input_clk, - input_rst=input_rst, output_clk=output_clk, - output_rst=output_rst, current_test=current_test, input_axis_tdata=input_axis_tdata, @@ -86,10 +84,9 @@ def dut_axis_async_fifo(input_clk, def bench(): # Inputs + async_rst = Signal(bool(0)) input_clk = Signal(bool(0)) - input_rst = Signal(bool(0)) output_clk = Signal(bool(0)) - output_rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[8:]) @@ -112,7 +109,7 @@ def bench(): sink_pause = Signal(bool(0)) source = axis_ep.AXIStreamSource(input_clk, - input_rst, + async_rst, tdata=input_axis_tdata, tvalid=input_axis_tvalid, tready=input_axis_tready, @@ -123,7 +120,7 @@ def bench(): name='source') sink = axis_ep.AXIStreamSink(output_clk, - output_rst, + async_rst, tdata=output_axis_tdata, tvalid=output_axis_tvalid, tready=output_axis_tready, @@ -134,10 +131,9 @@ def bench(): name='sink') # DUT - dut = dut_axis_async_fifo(input_clk, - input_rst, + dut = dut_axis_async_fifo(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, @@ -164,13 +160,11 @@ def bench(): def check(): yield delay(100) yield input_clk.posedge - input_rst.next = 1 - output_rst.next = 1 + async_rst.next = 1 yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge - input_rst.next = 0 - output_rst.next = 0 + async_rst.next = 0 yield input_clk.posedge yield delay(100) yield input_clk.posedge @@ -428,7 +422,7 @@ def bench(): yield delay(100) yield input_clk.posedge - print("test 9: initial sink pause, input reset") + print("test 9: initial sink pause, assert reset") current_test.next = 9 test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') @@ -440,38 +434,9 @@ def bench(): yield input_clk.posedge yield input_clk.posedge - input_rst.next = 1 + async_rst.next = 1 yield input_clk.posedge - input_rst.next = 0 - - sink_pause.next = 0 - - yield delay(100) - - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - - assert sink_queue.empty() - - yield delay(100) - - yield input_clk.posedge - print("test 10: initial sink pause, output reset") - current_test.next = 10 - - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') - - sink_pause.next = 1 - source_queue.put(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - - output_rst.next = 1 - yield output_clk.posedge - output_rst.next = 0 + async_rst.next = 0 sink_pause.next = 0 diff --git a/tb/test_axis_async_fifo.v b/tb/test_axis_async_fifo.v index dbfbdd494..fe91682a2 100644 --- a/tb/test_axis_async_fifo.v +++ b/tb/test_axis_async_fifo.v @@ -29,10 +29,9 @@ THE SOFTWARE. module test_axis_async_fifo; // Inputs +reg async_rst = 0; reg input_clk = 0; -reg input_rst = 0; reg output_clk = 0; -reg output_rst = 0; reg [7:0] current_test = 0; reg [7:0] input_axis_tdata = 0; @@ -50,10 +49,9 @@ wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(input_clk, - input_rst, + $from_myhdl(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, input_axis_tvalid, @@ -76,9 +74,10 @@ axis_async_fifo #( .DATA_WIDTH(8) ) UUT ( + // Common reset + .async_rst(async_rst), // AXI input .input_clk(input_clk), - .input_rst(input_rst), .input_axis_tdata(input_axis_tdata), .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), @@ -86,7 +85,6 @@ UUT ( .input_axis_tuser(input_axis_tuser), // AXI output .output_clk(output_clk), - .output_rst(output_rst), .output_axis_tdata(output_axis_tdata), .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index e72c4ebcc..a973ecc8c 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -44,10 +44,9 @@ src = ' '.join(srcs) build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) -def dut_axis_async_fifo_64(input_clk, - input_rst, +def dut_axis_async_fifo_64(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, @@ -67,10 +66,9 @@ def dut_axis_async_fifo_64(input_clk, if os.system(build_cmd): raise Exception("Error running build command") return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + async_rst=async_rst, input_clk=input_clk, - input_rst=input_rst, output_clk=output_clk, - output_rst=output_rst, current_test=current_test, input_axis_tdata=input_axis_tdata, @@ -90,10 +88,9 @@ def dut_axis_async_fifo_64(input_clk, def bench(): # Inputs + async_rst = Signal(bool(0)) input_clk = Signal(bool(0)) - input_rst = Signal(bool(0)) output_clk = Signal(bool(0)) - output_rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[64:]) @@ -118,7 +115,7 @@ def bench(): sink_pause = Signal(bool(0)) source = axis_ep.AXIStreamSource(input_clk, - input_rst, + async_rst, tdata=input_axis_tdata, tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, @@ -130,7 +127,7 @@ def bench(): name='source') sink = axis_ep.AXIStreamSink(output_clk, - output_rst, + async_rst, tdata=output_axis_tdata, tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, @@ -142,10 +139,9 @@ def bench(): name='sink') # DUT - dut = dut_axis_async_fifo_64(input_clk, - input_rst, + dut = dut_axis_async_fifo_64(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, @@ -174,13 +170,11 @@ def bench(): def check(): yield delay(100) yield input_clk.posedge - input_rst.next = 1 - output_rst.next = 1 + async_rst.next = 1 yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge - input_rst.next = 0 - output_rst.next = 0 + async_rst.next = 0 yield input_clk.posedge yield delay(100) yield input_clk.posedge @@ -438,7 +432,7 @@ def bench(): yield delay(100) yield input_clk.posedge - print("test 9: initial sink pause, input reset") + print("test 9: initial sink pause, assert reset") current_test.next = 9 test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) @@ -450,38 +444,9 @@ def bench(): yield input_clk.posedge yield input_clk.posedge - input_rst.next = 1 + async_rst.next = 1 yield input_clk.posedge - input_rst.next = 0 - - sink_pause.next = 0 - - yield delay(100) - - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - - assert sink_queue.empty() - - yield delay(100) - - yield input_clk.posedge - print("test 10: initial sink pause, output reset") - current_test.next = 10 - - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) - - sink_pause.next = 1 - source_queue.put(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - - output_rst.next = 1 - yield output_clk.posedge - output_rst.next = 0 + async_rst.next = 0 sink_pause.next = 0 diff --git a/tb/test_axis_async_fifo_64.v b/tb/test_axis_async_fifo_64.v index 6741debeb..bd49f80fd 100644 --- a/tb/test_axis_async_fifo_64.v +++ b/tb/test_axis_async_fifo_64.v @@ -29,10 +29,9 @@ THE SOFTWARE. module test_axis_async_fifo_64; // Inputs +reg async_rst = 0; reg input_clk = 0; -reg input_rst = 0; reg output_clk = 0; -reg output_rst = 0; reg [7:0] current_test = 0; reg [63:0] input_axis_tdata = 0; @@ -52,10 +51,9 @@ wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(input_clk, - input_rst, + $from_myhdl(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, input_axis_tkeep, @@ -80,9 +78,10 @@ axis_async_fifo_64 #( .DATA_WIDTH(64) ) UUT ( + // Common reset + .async_rst(async_rst), // AXI input .input_clk(input_clk), - .input_rst(input_rst), .input_axis_tdata(input_axis_tdata), .input_axis_tkeep(input_axis_tkeep), .input_axis_tvalid(input_axis_tvalid), @@ -91,7 +90,6 @@ UUT ( .input_axis_tuser(input_axis_tuser), // AXI output .output_clk(output_clk), - .output_rst(output_rst), .output_axis_tdata(output_axis_tdata), .output_axis_tkeep(output_axis_tkeep), .output_axis_tvalid(output_axis_tvalid), diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index 77b87f45b..6c9226f5f 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -44,10 +44,9 @@ src = ' '.join(srcs) build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) -def dut_axis_async_frame_fifo(input_clk, - input_rst, +def dut_axis_async_frame_fifo(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, @@ -68,10 +67,9 @@ def dut_axis_async_frame_fifo(input_clk, if os.system(build_cmd): raise Exception("Error running build command") return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + async_rst=async_rst, input_clk=input_clk, - input_rst=input_rst, output_clk=output_clk, - output_rst=output_rst, current_test=current_test, input_axis_tdata=input_axis_tdata, @@ -92,10 +90,9 @@ def dut_axis_async_frame_fifo(input_clk, def bench(): # Inputs + async_rst = Signal(bool(0)) input_clk = Signal(bool(0)) - input_rst = Signal(bool(0)) output_clk = Signal(bool(0)) - output_rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[8:]) @@ -120,7 +117,7 @@ def bench(): sink_pause = Signal(bool(0)) source = axis_ep.AXIStreamSource(input_clk, - input_rst, + async_rst, tdata=input_axis_tdata, tvalid=input_axis_tvalid, tready=input_axis_tready, @@ -131,7 +128,7 @@ def bench(): name='source') sink = axis_ep.AXIStreamSink(output_clk, - output_rst, + async_rst, tdata=output_axis_tdata, tvalid=output_axis_tvalid, tready=output_axis_tready, @@ -141,10 +138,9 @@ def bench(): name='sink') # DUT - dut = dut_axis_async_frame_fifo(input_clk, - input_rst, + dut = dut_axis_async_frame_fifo(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, @@ -187,13 +183,11 @@ def bench(): def check(): yield delay(100) yield input_clk.posedge - input_rst.next = 1 - output_rst.next = 1 + async_rst.next = 1 yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge - input_rst.next = 0 - output_rst.next = 0 + async_rst.next = 0 yield input_clk.posedge yield delay(100) yield input_clk.posedge @@ -537,7 +531,7 @@ def bench(): yield delay(100) yield input_clk.posedge - print("test 10: initial sink pause, input reset") + print("test 10: initial sink pause, assert reset") current_test.next = 10 test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') @@ -549,38 +543,9 @@ def bench(): yield input_clk.posedge yield input_clk.posedge - input_rst.next = 1 + async_rst.next = 1 yield input_clk.posedge - input_rst.next = 0 - - sink_pause.next = 0 - - yield delay(100) - - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - - assert sink_queue.empty() - - yield delay(100) - - yield input_clk.posedge - print("test 11: initial sink pause, output reset") - current_test.next = 11 - - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') - - sink_pause.next = 1 - source_queue.put(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - - output_rst.next = 1 - yield output_clk.posedge - output_rst.next = 0 + async_rst.next = 0 sink_pause.next = 0 diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index 2c603d750..7c57a7bc3 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -29,10 +29,9 @@ THE SOFTWARE. module test_axis_async_frame_fifo; // Inputs +reg async_rst = 0; reg input_clk = 0; -reg input_rst = 0; reg output_clk = 0; -reg output_rst = 0; reg [7:0] current_test = 0; reg [7:0] input_axis_tdata = 0; @@ -52,10 +51,9 @@ wire good_frame; initial begin // myhdl integration - $from_myhdl(input_clk, - input_rst, + $from_myhdl(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, input_axis_tvalid, @@ -81,9 +79,10 @@ axis_async_frame_fifo #( .DROP_WHEN_FULL(0) ) UUT ( + // Common reset + .async_rst(async_rst), // AXI input .input_clk(input_clk), - .input_rst(input_rst), .input_axis_tdata(input_axis_tdata), .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), @@ -91,7 +90,6 @@ UUT ( .input_axis_tuser(input_axis_tuser), // AXI output .output_clk(output_clk), - .output_rst(output_rst), .output_axis_tdata(output_axis_tdata), .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index 5c5cb6ade..c01d651e1 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -44,10 +44,9 @@ src = ' '.join(srcs) build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) -def dut_axis_async_frame_fifo_64(input_clk, - input_rst, +def dut_axis_async_frame_fifo_64(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, @@ -70,10 +69,9 @@ def dut_axis_async_frame_fifo_64(input_clk, if os.system(build_cmd): raise Exception("Error running build command") return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + async_rst=async_rst, input_clk=input_clk, - input_rst=input_rst, output_clk=output_clk, - output_rst=output_rst, current_test=current_test, input_axis_tdata=input_axis_tdata, @@ -96,10 +94,9 @@ def dut_axis_async_frame_fifo_64(input_clk, def bench(): # Inputs + async_rst = Signal(bool(0)) input_clk = Signal(bool(0)) - input_rst = Signal(bool(0)) output_clk = Signal(bool(0)) - output_rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[64:]) @@ -126,7 +123,7 @@ def bench(): sink_pause = Signal(bool(0)) source = axis_ep.AXIStreamSource(input_clk, - input_rst, + async_rst, tdata=input_axis_tdata, tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, @@ -138,7 +135,7 @@ def bench(): name='source') sink = axis_ep.AXIStreamSink(output_clk, - output_rst, + async_rst, tdata=output_axis_tdata, tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, @@ -149,10 +146,9 @@ def bench(): name='sink') # DUT - dut = dut_axis_async_frame_fifo_64(input_clk, - input_rst, + dut = dut_axis_async_frame_fifo_64(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, @@ -197,13 +193,11 @@ def bench(): def check(): yield delay(100) yield input_clk.posedge - input_rst.next = 1 - output_rst.next = 1 + async_rst.next = 1 yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge - input_rst.next = 0 - output_rst.next = 0 + async_rst.next = 0 yield input_clk.posedge yield delay(100) yield input_clk.posedge @@ -547,7 +541,7 @@ def bench(): yield delay(100) yield input_clk.posedge - print("test 10: initial sink pause, input reset") + print("test 10: initial sink pause, assert reset") current_test.next = 10 test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) @@ -559,38 +553,9 @@ def bench(): yield input_clk.posedge yield input_clk.posedge - input_rst.next = 1 + async_rst.next = 1 yield input_clk.posedge - input_rst.next = 0 - - sink_pause.next = 0 - - yield delay(100) - - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - - assert sink_queue.empty() - - yield delay(100) - - yield input_clk.posedge - print("test 11: initial sink pause, output reset") - current_test.next = 11 - - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) - - sink_pause.next = 1 - source_queue.put(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - - output_rst.next = 1 - yield output_clk.posedge - output_rst.next = 0 + async_rst.next = 0 sink_pause.next = 0 diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index 6ba39b210..27759a6c9 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -29,10 +29,9 @@ THE SOFTWARE. module test_axis_async_frame_fifo_64; // Inputs +reg async_rst = 0; reg input_clk = 0; -reg input_rst = 0; reg output_clk = 0; -reg output_rst = 0; reg [7:0] current_test = 0; reg [63:0] input_axis_tdata = 0; @@ -54,10 +53,9 @@ wire good_frame; initial begin // myhdl integration - $from_myhdl(input_clk, - input_rst, + $from_myhdl(async_rst, + input_clk, output_clk, - output_rst, current_test, input_axis_tdata, input_axis_tkeep, @@ -85,9 +83,10 @@ axis_async_frame_fifo_64 #( .DROP_WHEN_FULL(0) ) UUT ( + // Common reset + .async_rst(async_rst), // AXI input .input_clk(input_clk), - .input_rst(input_rst), .input_axis_tdata(input_axis_tdata), .input_axis_tkeep(input_axis_tkeep), .input_axis_tvalid(input_axis_tvalid), @@ -96,7 +95,6 @@ UUT ( .input_axis_tuser(input_axis_tuser), // AXI output .output_clk(output_clk), - .output_rst(output_rst), .output_axis_tdata(output_axis_tdata), .output_axis_tkeep(output_axis_tkeep), .output_axis_tvalid(output_axis_tvalid), From 90ac361df534476de80dcf21864e70b33a83bf38 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 8 Oct 2015 13:03:42 -0700 Subject: [PATCH 243/617] Internal synchronous reset on async FIFOs --- rtl/axis_async_fifo.v | 28 +++++++++++++++++----------- rtl/axis_async_fifo_64.v | 28 +++++++++++++++++----------- rtl/axis_async_frame_fifo.v | 28 +++++++++++++++++----------- rtl/axis_async_frame_fifo_64.v | 28 +++++++++++++++++----------- 4 files changed, 68 insertions(+), 44 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 4dcb22695..6fc52b6e4 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -73,8 +73,10 @@ reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; reg input_rst_sync1 = 1; reg input_rst_sync2 = 1; +reg input_rst_sync3 = 1; reg output_rst_sync1 = 1; reg output_rst_sync2 = 1; +reg output_rst_sync3 = 1; reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}}; @@ -106,9 +108,11 @@ always @(posedge input_clk or posedge async_rst) begin if (async_rst) begin input_rst_sync1 <= 1; input_rst_sync2 <= 1; + input_rst_sync3 <= 1; end else begin input_rst_sync1 <= 0; - input_rst_sync2 <= input_rst_sync1; + input_rst_sync2 <= input_rst_sync1 | output_rst_sync1; + input_rst_sync3 <= input_rst_sync2; end end @@ -116,15 +120,17 @@ always @(posedge output_clk or posedge async_rst) begin if (async_rst) begin output_rst_sync1 <= 1; output_rst_sync2 <= 1; + output_rst_sync3 <= 1; end else begin output_rst_sync1 <= 0; output_rst_sync2 <= output_rst_sync1; + output_rst_sync3 <= output_rst_sync2; end end // write -always @(posedge input_clk or posedge input_rst_sync2) begin - if (input_rst_sync2) begin +always @(posedge input_clk) begin + if (input_rst_sync3) begin wr_ptr <= 0; wr_ptr_gray <= 0; end else if (write) begin @@ -136,8 +142,8 @@ always @(posedge input_clk or posedge input_rst_sync2) begin end // pointer synchronization -always @(posedge input_clk or posedge input_rst_sync2) begin - if (input_rst_sync2) begin +always @(posedge input_clk) begin + if (input_rst_sync3) begin rd_ptr_gray_sync1 <= 0; rd_ptr_gray_sync2 <= 0; end else begin @@ -147,8 +153,8 @@ always @(posedge input_clk or posedge input_rst_sync2) begin end // read -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin rd_ptr <= 0; rd_ptr_gray <= 0; end else if (read) begin @@ -160,8 +166,8 @@ always @(posedge output_clk or posedge output_rst_sync2) begin end // pointer synchronization -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin wr_ptr_gray_sync1 <= 0; wr_ptr_gray_sync2 <= 0; end else begin @@ -171,8 +177,8 @@ always @(posedge output_clk or posedge output_rst_sync2) begin end // source ready output -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin output_axis_tvalid_reg <= ~empty; diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index 7303b87fc..eaddcdd45 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -76,8 +76,10 @@ reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; reg input_rst_sync1 = 1; reg input_rst_sync2 = 1; +reg input_rst_sync3 = 1; reg output_rst_sync1 = 1; reg output_rst_sync2 = 1; +reg output_rst_sync3 = 1; reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; @@ -109,9 +111,11 @@ always @(posedge input_clk or posedge async_rst) begin if (async_rst) begin input_rst_sync1 <= 1; input_rst_sync2 <= 1; + input_rst_sync3 <= 1; end else begin input_rst_sync1 <= 0; - input_rst_sync2 <= input_rst_sync1; + input_rst_sync2 <= input_rst_sync1 | output_rst_sync1; + input_rst_sync3 <= input_rst_sync2; end end @@ -119,15 +123,17 @@ always @(posedge output_clk or posedge async_rst) begin if (async_rst) begin output_rst_sync1 <= 1; output_rst_sync2 <= 1; + output_rst_sync3 <= 1; end else begin output_rst_sync1 <= 0; output_rst_sync2 <= output_rst_sync1; + output_rst_sync3 <= output_rst_sync2; end end // write -always @(posedge input_clk or posedge input_rst_sync2) begin - if (input_rst_sync2) begin +always @(posedge input_clk) begin + if (input_rst_sync3) begin wr_ptr <= 0; wr_ptr_gray <= 0; end else if (write) begin @@ -139,8 +145,8 @@ always @(posedge input_clk or posedge input_rst_sync2) begin end // pointer synchronization -always @(posedge input_clk or posedge input_rst_sync2) begin - if (input_rst_sync2) begin +always @(posedge input_clk) begin + if (input_rst_sync3) begin rd_ptr_gray_sync1 <= 0; rd_ptr_gray_sync2 <= 0; end else begin @@ -150,8 +156,8 @@ always @(posedge input_clk or posedge input_rst_sync2) begin end // read -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin rd_ptr <= 0; rd_ptr_gray <= 0; end else if (read) begin @@ -163,8 +169,8 @@ always @(posedge output_clk or posedge output_rst_sync2) begin end // pointer synchronization -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin wr_ptr_gray_sync1 <= 0; wr_ptr_gray_sync2 <= 0; end else begin @@ -174,8 +180,8 @@ always @(posedge output_clk or posedge output_rst_sync2) begin end // source ready output -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin output_axis_tvalid_reg <= ~empty; diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index e0e215ecc..344cff6d5 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -81,8 +81,10 @@ reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; reg input_rst_sync1 = 1; reg input_rst_sync2 = 1; +reg input_rst_sync3 = 1; reg output_rst_sync1 = 1; reg output_rst_sync2 = 1; +reg output_rst_sync3 = 1; reg drop_frame = 1'b0; reg overflow_reg = 1'b0; @@ -126,9 +128,11 @@ always @(posedge input_clk or posedge async_rst) begin if (async_rst) begin input_rst_sync1 <= 1; input_rst_sync2 <= 1; + input_rst_sync3 <= 1; end else begin input_rst_sync1 <= 0; - input_rst_sync2 <= input_rst_sync1; + input_rst_sync2 <= input_rst_sync1 | output_rst_sync1; + input_rst_sync3 <= input_rst_sync2; end end @@ -136,15 +140,17 @@ always @(posedge output_clk or posedge async_rst) begin if (async_rst) begin output_rst_sync1 <= 1; output_rst_sync2 <= 1; + output_rst_sync3 <= 1; end else begin output_rst_sync1 <= 0; output_rst_sync2 <= output_rst_sync1; + output_rst_sync3 <= output_rst_sync2; end end // write -always @(posedge input_clk or posedge input_rst_sync2) begin - if (input_rst_sync2) begin +always @(posedge input_clk) begin + if (input_rst_sync3) begin wr_ptr <= 0; wr_ptr_cur <= 0; wr_ptr_gray <= 0; @@ -189,8 +195,8 @@ always @(posedge input_clk or posedge input_rst_sync2) begin end // pointer synchronization -always @(posedge input_clk or posedge input_rst_sync2) begin - if (input_rst_sync2) begin +always @(posedge input_clk) begin + if (input_rst_sync3) begin rd_ptr_gray_sync1 <= 0; rd_ptr_gray_sync2 <= 0; end else begin @@ -200,8 +206,8 @@ always @(posedge input_clk or posedge input_rst_sync2) begin end // read -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin rd_ptr <= 0; rd_ptr_gray <= 0; end else if (read) begin @@ -213,8 +219,8 @@ always @(posedge output_clk or posedge output_rst_sync2) begin end // pointer synchronization -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin wr_ptr_gray_sync1 <= 0; wr_ptr_gray_sync2 <= 0; end else begin @@ -224,8 +230,8 @@ always @(posedge output_clk or posedge output_rst_sync2) begin end // source ready output -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin output_axis_tvalid_reg <= ~empty; diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 0847cd235..b82d73db3 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -84,8 +84,10 @@ reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; reg input_rst_sync1 = 1; reg input_rst_sync2 = 1; +reg input_rst_sync3 = 1; reg output_rst_sync1 = 1; reg output_rst_sync2 = 1; +reg output_rst_sync3 = 1; reg drop_frame = 1'b0; reg overflow_reg = 1'b0; @@ -129,9 +131,11 @@ always @(posedge input_clk or posedge async_rst) begin if (async_rst) begin input_rst_sync1 <= 1; input_rst_sync2 <= 1; + input_rst_sync3 <= 1; end else begin input_rst_sync1 <= 0; - input_rst_sync2 <= input_rst_sync1; + input_rst_sync2 <= input_rst_sync1 | output_rst_sync1; + input_rst_sync3 <= input_rst_sync2; end end @@ -139,15 +143,17 @@ always @(posedge output_clk or posedge async_rst) begin if (async_rst) begin output_rst_sync1 <= 1; output_rst_sync2 <= 1; + output_rst_sync3 <= 1; end else begin output_rst_sync1 <= 0; output_rst_sync2 <= output_rst_sync1; + output_rst_sync3 <= output_rst_sync2; end end // write -always @(posedge input_clk or posedge input_rst_sync2) begin - if (input_rst_sync2) begin +always @(posedge input_clk) begin + if (input_rst_sync3) begin wr_ptr <= 0; wr_ptr_cur <= 0; wr_ptr_gray <= 0; @@ -192,8 +198,8 @@ always @(posedge input_clk or posedge input_rst_sync2) begin end // pointer synchronization -always @(posedge input_clk or posedge input_rst_sync2) begin - if (input_rst_sync2) begin +always @(posedge input_clk) begin + if (input_rst_sync3) begin rd_ptr_gray_sync1 <= 0; rd_ptr_gray_sync2 <= 0; end else begin @@ -203,8 +209,8 @@ always @(posedge input_clk or posedge input_rst_sync2) begin end // read -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin rd_ptr <= 0; rd_ptr_gray <= 0; end else if (read) begin @@ -216,8 +222,8 @@ always @(posedge output_clk or posedge output_rst_sync2) begin end // pointer synchronization -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin wr_ptr_gray_sync1 <= 0; wr_ptr_gray_sync2 <= 0; end else begin @@ -227,8 +233,8 @@ always @(posedge output_clk or posedge output_rst_sync2) begin end // source ready output -always @(posedge output_clk or posedge output_rst_sync2) begin - if (output_rst_sync2) begin +always @(posedge output_clk) begin + if (output_rst_sync3) begin output_axis_tvalid_reg <= 1'b0; end else if (output_axis_tready | ~output_axis_tvalid_reg) begin output_axis_tvalid_reg <= ~empty; From 382226ad5966198862fb676c7a5810067c2c6a19 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 8 Oct 2015 23:46:59 -0700 Subject: [PATCH 244/617] Don't accept data until reset is complete --- rtl/axis_async_fifo.v | 2 +- rtl/axis_async_fifo_64.v | 2 +- rtl/axis_async_frame_fifo.v | 2 +- rtl/axis_async_frame_fifo_64.v | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 6fc52b6e4..4edb91551 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -100,7 +100,7 @@ wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = data_out_reg; -assign input_axis_tready = ~full; +assign input_axis_tready = ~full & ~input_rst_sync3; assign output_axis_tvalid = output_axis_tvalid_reg; // reset synchronization diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index eaddcdd45..c7eed0e3e 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -103,7 +103,7 @@ wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = data_out_reg; -assign input_axis_tready = ~full; +assign input_axis_tready = ~full & ~input_rst_sync3; assign output_axis_tvalid = output_axis_tvalid_reg; // reset synchronization diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 344cff6d5..3239633d3 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -116,7 +116,7 @@ wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; assign {output_axis_tlast, output_axis_tdata} = data_out_reg; -assign input_axis_tready = (~full | DROP_WHEN_FULL); +assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3; assign output_axis_tvalid = output_axis_tvalid_reg; assign overflow = overflow_reg; diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index b82d73db3..f613e5757 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -119,7 +119,7 @@ wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; -assign input_axis_tready = (~full | DROP_WHEN_FULL); +assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3; assign output_axis_tvalid = output_axis_tvalid_reg; assign overflow = overflow_reg; From 364b5373127d8d07039cb504adf45d122438e465 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 9 Oct 2015 15:14:54 -0700 Subject: [PATCH 245/617] Synchronize status signals for both clock domains in async frame FIFO --- rtl/axis_async_frame_fifo.v | 66 ++++++++- rtl/axis_async_frame_fifo_64.v | 66 ++++++++- tb/test_axis_async_frame_fifo.py | 214 +++++++++++++++++++--------- tb/test_axis_async_frame_fifo.v | 27 ++-- tb/test_axis_async_frame_fifo_64.py | 214 +++++++++++++++++++--------- tb/test_axis_async_frame_fifo_64.v | 27 ++-- 6 files changed, 442 insertions(+), 172 deletions(-) diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 3239633d3..944b1f48b 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -63,9 +63,12 @@ module axis_async_frame_fifo # /* * Status */ - output wire overflow, - output wire bad_frame, - output wire good_frame + output wire input_status_overflow, + output wire input_status_bad_frame, + output wire input_status_good_frame, + output wire output_status_overflow, + output wire output_status_bad_frame, + output wire output_status_good_frame ); reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; @@ -91,6 +94,19 @@ reg overflow_reg = 1'b0; reg bad_frame_reg = 1'b0; reg good_frame_reg = 1'b0; +reg overflow_sync1 = 1'b0; +reg overflow_sync2 = 1'b0; +reg overflow_sync3 = 1'b0; +reg overflow_sync4 = 1'b0; +reg bad_frame_sync1 = 1'b0; +reg bad_frame_sync2 = 1'b0; +reg bad_frame_sync3 = 1'b0; +reg bad_frame_sync4 = 1'b0; +reg good_frame_sync1 = 1'b0; +reg good_frame_sync2 = 1'b0; +reg good_frame_sync3 = 1'b0; +reg good_frame_sync4 = 1'b0; + reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) @@ -119,9 +135,13 @@ assign {output_axis_tlast, output_axis_tdata} = data_out_reg; assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3; assign output_axis_tvalid = output_axis_tvalid_reg; -assign overflow = overflow_reg; -assign bad_frame = bad_frame_reg; -assign good_frame = good_frame_reg; +assign input_status_overflow = overflow_reg; +assign input_status_bad_frame = bad_frame_reg; +assign input_status_good_frame = good_frame_reg; + +assign output_status_overflow = overflow_sync3 ^ overflow_sync4; +assign output_status_bad_frame = bad_frame_sync3 ^ bad_frame_sync4; +assign output_status_good_frame = good_frame_sync3 ^ good_frame_sync4; // reset synchronization always @(posedge input_clk or posedge async_rst) begin @@ -240,4 +260,38 @@ always @(posedge output_clk) begin end end +// status synchronization +always @(posedge input_clk) begin + if (input_rst_sync3) begin + overflow_sync1 <= 1'b0; + bad_frame_sync1 <= 1'b0; + good_frame_sync1 <= 1'b0; + end else begin + overflow_sync1 <= overflow_sync1 ^ overflow_reg; + bad_frame_sync1 <= bad_frame_sync1 ^ bad_frame_reg; + good_frame_sync1 <= good_frame_sync1 ^ good_frame_reg; + end +end + +always @(posedge output_clk) begin + if (output_rst_sync3) begin + overflow_sync2 <= 1'b0; + overflow_sync3 <= 1'b0; + bad_frame_sync2 <= 1'b0; + bad_frame_sync3 <= 1'b0; + good_frame_sync2 <= 1'b0; + good_frame_sync3 <= 1'b0; + end else begin + overflow_sync2 <= overflow_sync1; + overflow_sync3 <= overflow_sync2; + overflow_sync4 <= overflow_sync3; + bad_frame_sync2 <= bad_frame_sync1; + bad_frame_sync3 <= bad_frame_sync2; + bad_frame_sync4 <= bad_frame_sync3; + good_frame_sync2 <= good_frame_sync1; + good_frame_sync3 <= good_frame_sync2; + good_frame_sync4 <= good_frame_sync3; + end +end + endmodule diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index f613e5757..2183ea039 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -66,9 +66,12 @@ module axis_async_frame_fifo_64 # /* * Status */ - output wire overflow, - output wire bad_frame, - output wire good_frame + output wire input_status_overflow, + output wire input_status_bad_frame, + output wire input_status_good_frame, + output wire output_status_overflow, + output wire output_status_bad_frame, + output wire output_status_good_frame ); reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; @@ -94,6 +97,19 @@ reg overflow_reg = 1'b0; reg bad_frame_reg = 1'b0; reg good_frame_reg = 1'b0; +reg overflow_sync1 = 1'b0; +reg overflow_sync2 = 1'b0; +reg overflow_sync3 = 1'b0; +reg overflow_sync4 = 1'b0; +reg bad_frame_sync1 = 1'b0; +reg bad_frame_sync2 = 1'b0; +reg bad_frame_sync3 = 1'b0; +reg bad_frame_sync4 = 1'b0; +reg good_frame_sync1 = 1'b0; +reg good_frame_sync2 = 1'b0; +reg good_frame_sync3 = 1'b0; +reg good_frame_sync4 = 1'b0; + reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; //(* RAM_STYLE="BLOCK" *) @@ -122,9 +138,13 @@ assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3; assign output_axis_tvalid = output_axis_tvalid_reg; -assign overflow = overflow_reg; -assign bad_frame = bad_frame_reg; -assign good_frame = good_frame_reg; +assign input_status_overflow = overflow_reg; +assign input_status_bad_frame = bad_frame_reg; +assign input_status_good_frame = good_frame_reg; + +assign output_status_overflow = overflow_sync3 ^ overflow_sync4; +assign output_status_bad_frame = bad_frame_sync3 ^ bad_frame_sync4; +assign output_status_good_frame = good_frame_sync3 ^ good_frame_sync4; // reset synchronization always @(posedge input_clk or posedge async_rst) begin @@ -243,4 +263,38 @@ always @(posedge output_clk) begin end end +// status synchronization +always @(posedge input_clk) begin + if (input_rst_sync3) begin + overflow_sync1 <= 1'b0; + bad_frame_sync1 <= 1'b0; + good_frame_sync1 <= 1'b0; + end else begin + overflow_sync1 <= overflow_sync1 ^ overflow_reg; + bad_frame_sync1 <= bad_frame_sync1 ^ bad_frame_reg; + good_frame_sync1 <= good_frame_sync1 ^ good_frame_reg; + end +end + +always @(posedge output_clk) begin + if (output_rst_sync3) begin + overflow_sync2 <= 1'b0; + overflow_sync3 <= 1'b0; + bad_frame_sync2 <= 1'b0; + bad_frame_sync3 <= 1'b0; + good_frame_sync2 <= 1'b0; + good_frame_sync3 <= 1'b0; + end else begin + overflow_sync2 <= overflow_sync1; + overflow_sync3 <= overflow_sync2; + overflow_sync4 <= overflow_sync3; + bad_frame_sync2 <= bad_frame_sync1; + bad_frame_sync3 <= bad_frame_sync2; + bad_frame_sync4 <= bad_frame_sync3; + good_frame_sync2 <= good_frame_sync1; + good_frame_sync3 <= good_frame_sync2; + good_frame_sync4 <= good_frame_sync3; + end +end + endmodule diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index 6c9226f5f..378e1bc6e 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -60,9 +60,12 @@ def dut_axis_async_frame_fifo(async_rst, output_axis_tready, output_axis_tlast, - overflow, - bad_frame, - good_frame): + input_status_overflow, + input_status_bad_frame, + input_status_good_frame, + output_status_overflow, + output_status_bad_frame, + output_status_good_frame): if os.system(build_cmd): raise Exception("Error running build command") @@ -83,9 +86,12 @@ def dut_axis_async_frame_fifo(async_rst, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, - overflow=overflow, - bad_frame=bad_frame, - good_frame=good_frame) + input_status_overflow=input_status_overflow, + input_status_bad_frame=input_status_bad_frame, + input_status_good_frame=input_status_good_frame, + output_status_overflow=output_status_overflow, + output_status_bad_frame=output_status_bad_frame, + output_status_good_frame=output_status_good_frame) def bench(): @@ -106,9 +112,12 @@ def bench(): output_axis_tdata = Signal(intbv(0)[8:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - overflow = Signal(bool(0)) - bad_frame = Signal(bool(0)) - good_frame = Signal(bool(0)) + input_status_overflow = Signal(bool(0)) + input_status_bad_frame = Signal(bool(0)) + input_status_good_frame = Signal(bool(0)) + output_status_overflow = Signal(bool(0)) + output_status_bad_frame = Signal(bool(0)) + output_status_good_frame = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -154,9 +163,12 @@ def bench(): output_axis_tready, output_axis_tlast, - overflow, - bad_frame, - good_frame) + input_status_overflow, + input_status_bad_frame, + input_status_good_frame, + output_status_overflow, + output_status_bad_frame, + output_status_good_frame) @always(delay(4)) def input_clkgen(): @@ -166,18 +178,30 @@ def bench(): def output_clkgen(): output_clk.next = not output_clk - overflow_asserted = Signal(bool(0)) - bad_frame_asserted = Signal(bool(0)) - good_frame_asserted = Signal(bool(0)) + input_status_overflow_asserted = Signal(bool(0)) + input_status_bad_frame_asserted = Signal(bool(0)) + input_status_good_frame_asserted = Signal(bool(0)) + output_status_overflow_asserted = Signal(bool(0)) + output_status_bad_frame_asserted = Signal(bool(0)) + output_status_good_frame_asserted = Signal(bool(0)) @always(input_clk.posedge) - def monitor(): - if (overflow): - overflow_asserted.next = 1 - if (bad_frame): - bad_frame_asserted.next = 1 - if (good_frame): - good_frame_asserted.next = 1 + def monitor_1(): + if (input_status_overflow): + input_status_overflow_asserted.next = 1 + if (input_status_bad_frame): + input_status_bad_frame_asserted.next = 1 + if (input_status_good_frame): + input_status_good_frame_asserted.next = 1 + + @always(output_clk.posedge) + def monitor_2(): + if (output_status_overflow): + output_status_overflow_asserted.next = 1 + if (output_status_bad_frame): + output_status_bad_frame_asserted.next = 1 + if (output_status_good_frame): + output_status_good_frame_asserted.next = 1 @instance def check(): @@ -203,9 +227,12 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame) yield input_clk.posedge @@ -220,9 +247,12 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield delay(100) @@ -235,9 +265,12 @@ def bench(): b'\x80\x00' + bytearray(range(256))) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame) yield input_clk.posedge @@ -252,9 +285,12 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield input_clk.posedge print("test 3: test packet with pauses") @@ -265,9 +301,12 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame) yield input_clk.posedge @@ -296,9 +335,12 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield delay(100) @@ -315,9 +357,12 @@ def bench(): b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame1) source_queue.put(test_frame2) @@ -341,9 +386,12 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield delay(100) @@ -360,9 +408,12 @@ def bench(): b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame1) source_queue.put(test_frame2) @@ -395,9 +446,12 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield delay(100) @@ -414,9 +468,12 @@ def bench(): b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame1) source_queue.put(test_frame2) @@ -445,9 +502,12 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield delay(100) @@ -461,9 +521,12 @@ def bench(): b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame) yield input_clk.posedge @@ -472,9 +535,12 @@ def bench(): assert sink_queue.empty() - assert not overflow_asserted - assert bad_frame_asserted - assert not good_frame_asserted + assert not input_status_overflow_asserted + assert input_status_bad_frame_asserted + assert not input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert output_status_bad_frame_asserted + assert not output_status_good_frame_asserted yield delay(100) @@ -487,9 +553,12 @@ def bench(): b'\x80\x00' + bytearray(range(256))*2) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame) yield input_clk.posedge @@ -498,9 +567,12 @@ def bench(): assert sink_queue.empty() - assert overflow_asserted - assert not bad_frame_asserted - assert not good_frame_asserted + assert input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert not input_status_good_frame_asserted + assert output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert not output_status_good_frame_asserted yield delay(100) @@ -561,7 +633,7 @@ def bench(): raise StopSimulation - return dut, monitor, source, sink, input_clkgen, output_clkgen, check + return dut, monitor_1, monitor_2, source, sink, input_clkgen, output_clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index 7c57a7bc3..9caa8edc3 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -45,9 +45,12 @@ wire input_axis_tready; wire [7:0] output_axis_tdata; wire output_axis_tvalid; wire output_axis_tlast; -wire overflow; -wire bad_frame; -wire good_frame; +wire input_status_overflow; +wire input_status_bad_frame; +wire input_status_good_frame; +wire output_status_overflow; +wire output_status_bad_frame; +wire output_status_good_frame; initial begin // myhdl integration @@ -64,9 +67,12 @@ initial begin output_axis_tdata, output_axis_tvalid, output_axis_tlast, - overflow, - bad_frame, - good_frame); + input_status_overflow, + input_status_bad_frame, + input_status_good_frame, + output_status_overflow, + output_status_bad_frame, + output_status_good_frame); // dump file $dumpfile("test_axis_async_frame_fifo.lxt"); @@ -95,9 +101,12 @@ UUT ( .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), // Status - .overflow(overflow), - .bad_frame(bad_frame), - .good_frame(good_frame) + .input_status_overflow(input_status_overflow), + .input_status_bad_frame(input_status_bad_frame), + .input_status_good_frame(input_status_good_frame), + .output_status_overflow(output_status_overflow), + .output_status_bad_frame(output_status_bad_frame), + .output_status_good_frame(output_status_good_frame) ); endmodule diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index c01d651e1..e12404f02 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -62,9 +62,12 @@ def dut_axis_async_frame_fifo_64(async_rst, output_axis_tready, output_axis_tlast, - overflow, - bad_frame, - good_frame): + input_status_overflow, + input_status_bad_frame, + input_status_good_frame, + output_status_overflow, + output_status_bad_frame, + output_status_good_frame): if os.system(build_cmd): raise Exception("Error running build command") @@ -87,9 +90,12 @@ def dut_axis_async_frame_fifo_64(async_rst, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, - overflow=overflow, - bad_frame=bad_frame, - good_frame=good_frame) + input_status_overflow=input_status_overflow, + input_status_bad_frame=input_status_bad_frame, + input_status_good_frame=input_status_good_frame, + output_status_overflow=output_status_overflow, + output_status_bad_frame=output_status_bad_frame, + output_status_good_frame=output_status_good_frame) def bench(): @@ -112,9 +118,12 @@ def bench(): output_axis_tkeep = Signal(intbv(0)[8:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - overflow = Signal(bool(0)) - bad_frame = Signal(bool(0)) - good_frame = Signal(bool(0)) + input_status_overflow = Signal(bool(0)) + input_status_bad_frame = Signal(bool(0)) + input_status_good_frame = Signal(bool(0)) + output_status_overflow = Signal(bool(0)) + output_status_bad_frame = Signal(bool(0)) + output_status_good_frame = Signal(bool(0)) # sources and sinks source_queue = Queue() @@ -164,9 +173,12 @@ def bench(): output_axis_tready, output_axis_tlast, - overflow, - bad_frame, - good_frame) + input_status_overflow, + input_status_bad_frame, + input_status_good_frame, + output_status_overflow, + output_status_bad_frame, + output_status_good_frame) @always(delay(4)) def input_clkgen(): @@ -176,18 +188,30 @@ def bench(): def output_clkgen(): output_clk.next = not output_clk - overflow_asserted = Signal(bool(0)) - bad_frame_asserted = Signal(bool(0)) - good_frame_asserted = Signal(bool(0)) + input_status_overflow_asserted = Signal(bool(0)) + input_status_bad_frame_asserted = Signal(bool(0)) + input_status_good_frame_asserted = Signal(bool(0)) + output_status_overflow_asserted = Signal(bool(0)) + output_status_bad_frame_asserted = Signal(bool(0)) + output_status_good_frame_asserted = Signal(bool(0)) @always(input_clk.posedge) - def monitor(): - if (overflow): - overflow_asserted.next = 1 - if (bad_frame): - bad_frame_asserted.next = 1 - if (good_frame): - good_frame_asserted.next = 1 + def monitor_1(): + if (input_status_overflow): + input_status_overflow_asserted.next = 1 + if (input_status_bad_frame): + input_status_bad_frame_asserted.next = 1 + if (input_status_good_frame): + input_status_good_frame_asserted.next = 1 + + @always(output_clk.posedge) + def monitor_2(): + if (output_status_overflow): + output_status_overflow_asserted.next = 1 + if (output_status_bad_frame): + output_status_bad_frame_asserted.next = 1 + if (output_status_good_frame): + output_status_good_frame_asserted.next = 1 @instance def check(): @@ -213,9 +237,12 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame) yield input_clk.posedge @@ -230,9 +257,12 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield delay(100) @@ -245,9 +275,12 @@ def bench(): b'\x80\x00' + bytearray(range(256))) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame) yield input_clk.posedge @@ -262,9 +295,12 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield input_clk.posedge print("test 3: test packet with pauses") @@ -275,9 +311,12 @@ def bench(): b'\x80\x00' + bytearray(range(256))) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame) yield input_clk.posedge @@ -306,9 +345,12 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield delay(100) @@ -325,9 +367,12 @@ def bench(): b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame1) source_queue.put(test_frame2) @@ -351,9 +396,12 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield delay(100) @@ -370,9 +418,12 @@ def bench(): b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame1) source_queue.put(test_frame2) @@ -405,9 +456,12 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield delay(100) @@ -424,9 +478,12 @@ def bench(): b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame1) source_queue.put(test_frame2) @@ -455,9 +512,12 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert output_status_good_frame_asserted yield delay(100) @@ -471,9 +531,12 @@ def bench(): b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame) yield input_clk.posedge @@ -482,9 +545,12 @@ def bench(): assert sink_queue.empty() - assert not overflow_asserted - assert bad_frame_asserted - assert not good_frame_asserted + assert not input_status_overflow_asserted + assert input_status_bad_frame_asserted + assert not input_status_good_frame_asserted + assert not output_status_overflow_asserted + assert output_status_bad_frame_asserted + assert not output_status_good_frame_asserted yield delay(100) @@ -497,9 +563,12 @@ def bench(): b'\x80\x00' + bytearray(range(256))*2) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + input_status_overflow_asserted.next = 0 + input_status_bad_frame_asserted.next = 0 + input_status_good_frame_asserted.next = 0 + output_status_overflow_asserted.next = 0 + output_status_bad_frame_asserted.next = 0 + output_status_good_frame_asserted.next = 0 source_queue.put(test_frame) yield input_clk.posedge @@ -508,9 +577,12 @@ def bench(): assert sink_queue.empty() - assert overflow_asserted - assert not bad_frame_asserted - assert not good_frame_asserted + assert input_status_overflow_asserted + assert not input_status_bad_frame_asserted + assert not input_status_good_frame_asserted + assert output_status_overflow_asserted + assert not output_status_bad_frame_asserted + assert not output_status_good_frame_asserted yield delay(100) @@ -571,7 +643,7 @@ def bench(): raise StopSimulation - return dut, monitor, source, sink, input_clkgen, output_clkgen, check + return dut, monitor_1, monitor_2, source, sink, input_clkgen, output_clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index 27759a6c9..e8b9bbcf6 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -47,9 +47,12 @@ wire [63:0] output_axis_tdata; wire [7:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire overflow; -wire bad_frame; -wire good_frame; +wire input_status_overflow; +wire input_status_bad_frame; +wire input_status_good_frame; +wire output_status_overflow; +wire output_status_bad_frame; +wire output_status_good_frame; initial begin // myhdl integration @@ -68,9 +71,12 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, - overflow, - bad_frame, - good_frame); + input_status_overflow, + input_status_bad_frame, + input_status_good_frame, + output_status_overflow, + output_status_bad_frame, + output_status_good_frame); // dump file $dumpfile("test_axis_async_frame_fifo_64.lxt"); @@ -101,9 +107,12 @@ UUT ( .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), // Status - .overflow(overflow), - .bad_frame(bad_frame), - .good_frame(good_frame) + .input_status_overflow(input_status_overflow), + .input_status_bad_frame(input_status_bad_frame), + .input_status_good_frame(input_status_good_frame), + .output_status_overflow(output_status_overflow), + .output_status_bad_frame(output_status_bad_frame), + .output_status_good_frame(output_status_good_frame) ); endmodule From 55071645fd468f97e269160d77a387d1a2ab054d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 9 Oct 2015 22:35:25 -0700 Subject: [PATCH 246/617] Update async FIFO instances --- rtl/eth_mac_10g_fifo.v | 60 +++++++++++------------------------------- rtl/eth_mac_1g_fifo.v | 60 +++++++++++------------------------------- 2 files changed, 32 insertions(+), 88 deletions(-) diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 0090daee8..2232b3a38 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -104,40 +104,6 @@ wire rx_fifo_axis_tvalid; wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; -// synchronize FIFO status signals into logic clock domain (only required for RX FIFO) -wire rx_fifo_overflow_int; -wire rx_fifo_bad_frame_int; -wire rx_fifo_good_frame_int; - -reg [2:0] rx_sync_reg_1 = 0; -reg [2:0] rx_sync_reg_2 = 0; -reg [2:0] rx_sync_reg_3 = 0; -reg [2:0] rx_sync_reg_4 = 0; - -assign rx_fifo_overflow = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; -assign rx_fifo_bad_frame = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; -assign rx_fifo_good_frame = rx_sync_reg_3[2] ^ rx_sync_reg_4[2]; - -always @(posedge rx_clk or posedge rx_rst) begin - if (rx_rst) begin - rx_sync_reg_1 <= 0; - end else begin - rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_fifo_good_frame_int, rx_fifo_bad_frame_int, rx_fifo_overflow_int}; - end -end - -always @(posedge logic_clk or posedge logic_rst) begin - if (logic_rst) begin - rx_sync_reg_2 <= 0; - rx_sync_reg_3 <= 0; - rx_sync_reg_4 <= 0; - end else begin - rx_sync_reg_2 <= rx_sync_reg_1; - rx_sync_reg_3 <= rx_sync_reg_2; - rx_sync_reg_4 <= rx_sync_reg_3; - end -end - eth_mac_10g #( .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), @@ -174,9 +140,10 @@ axis_async_frame_fifo_64 #( .DROP_WHEN_FULL(0) ) tx_fifo ( + // Common reset + .async_rst(logic_rst | tx_rst), // AXI input .input_clk(logic_clk), - .input_rst(logic_rst), .input_axis_tdata(tx_axis_tdata), .input_axis_tkeep(tx_axis_tkeep), .input_axis_tvalid(tx_axis_tvalid), @@ -185,16 +152,18 @@ tx_fifo ( .input_axis_tuser(tx_axis_tuser), // AXI output .output_clk(tx_clk), - .output_rst(tx_rst), .output_axis_tdata(tx_fifo_axis_tdata), .output_axis_tkeep(tx_fifo_axis_tkeep), .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), .output_axis_tlast(tx_fifo_axis_tlast), // Status - .overflow(tx_fifo_overflow), - .bad_frame(tx_fifo_bad_frame), - .good_frame(tx_fifo_good_frame) + .input_status_overflow(tx_fifo_overflow), + .input_status_bad_frame(tx_fifo_bad_frame), + .input_status_good_frame(tx_fifo_good_frame), + .output_status_overflow(), + .output_status_bad_frame(), + .output_status_good_frame() ); assign tx_fifo_axis_tuser = 1'b0; @@ -205,9 +174,10 @@ axis_async_frame_fifo_64 #( .DROP_WHEN_FULL(1) ) rx_fifo ( + // Common reset + .async_rst(rx_rst | logic_rst), // AXI input .input_clk(rx_clk), - .input_rst(rx_rst), .input_axis_tdata(rx_fifo_axis_tdata), .input_axis_tkeep(rx_fifo_axis_tkeep), .input_axis_tvalid(rx_fifo_axis_tvalid), @@ -216,16 +186,18 @@ rx_fifo ( .input_axis_tuser(rx_fifo_axis_tuser), // AXI output .output_clk(logic_clk), - .output_rst(logic_rst), .output_axis_tdata(rx_axis_tdata), .output_axis_tkeep(rx_axis_tkeep), .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), .output_axis_tlast(rx_axis_tlast), // Status - .overflow(rx_fifo_overflow_int), - .bad_frame(rx_fifo_bad_frame_int), - .good_frame(rx_fifo_good_frame_int) + .input_status_overflow(), + .input_status_bad_frame(), + .input_status_good_frame(), + .output_status_overflow(rx_fifo_overflow), + .output_status_bad_frame(rx_fifo_bad_frame), + .output_status_good_frame(rx_fifo_good_frame) ); assign rx_axis_tuser = 1'b0; diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index 6590c43c4..298554a79 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -101,40 +101,6 @@ wire rx_fifo_axis_tvalid; wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; -// synchronize FIFO status signals into logic clock domain (only required for RX FIFO) -wire rx_fifo_overflow_int; -wire rx_fifo_bad_frame_int; -wire rx_fifo_good_frame_int; - -reg [2:0] rx_sync_reg_1 = 0; -reg [2:0] rx_sync_reg_2 = 0; -reg [2:0] rx_sync_reg_3 = 0; -reg [2:0] rx_sync_reg_4 = 0; - -assign rx_fifo_overflow = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; -assign rx_fifo_bad_frame = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; -assign rx_fifo_good_frame = rx_sync_reg_3[2] ^ rx_sync_reg_4[2]; - -always @(posedge rx_clk or posedge rx_rst) begin - if (rx_rst) begin - rx_sync_reg_1 <= 0; - end else begin - rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_fifo_good_frame_int, rx_fifo_bad_frame_int, rx_fifo_overflow_int}; - end -end - -always @(posedge logic_clk or posedge logic_rst) begin - if (logic_rst) begin - rx_sync_reg_2 <= 0; - rx_sync_reg_3 <= 0; - rx_sync_reg_4 <= 0; - end else begin - rx_sync_reg_2 <= rx_sync_reg_1; - rx_sync_reg_3 <= rx_sync_reg_2; - rx_sync_reg_4 <= rx_sync_reg_3; - end -end - eth_mac_1g #( .ENABLE_PADDING(ENABLE_PADDING), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) @@ -170,9 +136,10 @@ axis_async_frame_fifo #( .DROP_WHEN_FULL(0) ) tx_fifo ( + // Common reset + .async_rst(logic_rst | tx_rst), // AXI input .input_clk(logic_clk), - .input_rst(logic_rst), .input_axis_tdata(tx_axis_tdata), .input_axis_tvalid(tx_axis_tvalid), .input_axis_tready(tx_axis_tready), @@ -180,15 +147,17 @@ tx_fifo ( .input_axis_tuser(tx_axis_tuser), // AXI output .output_clk(tx_clk), - .output_rst(tx_rst), .output_axis_tdata(tx_fifo_axis_tdata), .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), .output_axis_tlast(tx_fifo_axis_tlast), // Status - .overflow(tx_fifo_overflow), - .bad_frame(tx_fifo_bad_frame), - .good_frame(tx_fifo_good_frame) + .input_status_overflow(tx_fifo_overflow), + .input_status_bad_frame(tx_fifo_bad_frame), + .input_status_good_frame(tx_fifo_good_frame), + .output_status_overflow(), + .output_status_bad_frame(), + .output_status_good_frame() ); assign tx_fifo_axis_tuser = 1'b0; @@ -199,9 +168,10 @@ axis_async_frame_fifo #( .DROP_WHEN_FULL(1) ) rx_fifo ( + // Common reset + .async_rst(rx_rst | logic_rst), // AXI input .input_clk(rx_clk), - .input_rst(rx_rst), .input_axis_tdata(rx_fifo_axis_tdata), .input_axis_tvalid(rx_fifo_axis_tvalid), .input_axis_tready(), @@ -209,15 +179,17 @@ rx_fifo ( .input_axis_tuser(rx_fifo_axis_tuser), // AXI output .output_clk(logic_clk), - .output_rst(logic_rst), .output_axis_tdata(rx_axis_tdata), .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), .output_axis_tlast(rx_axis_tlast), // Status - .overflow(rx_fifo_overflow_int), - .bad_frame(rx_fifo_bad_frame_int), - .good_frame(rx_fifo_good_frame_int) + .input_status_overflow(), + .input_status_bad_frame(), + .input_status_good_frame(), + .output_status_overflow(rx_fifo_overflow), + .output_status_bad_frame(rx_fifo_bad_frame), + .output_status_good_frame(rx_fifo_good_frame) ); assign rx_axis_tuser = 1'b0; From cc5fead04d896e40378042c149e20cac7b694cb9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 9 Oct 2015 22:36:58 -0700 Subject: [PATCH 247/617] Convert to synchronous resets --- rtl/arp.v | 2 +- rtl/arp_64.v | 2 +- rtl/arp_cache.v | 2 +- rtl/arp_eth_rx.v | 2 +- rtl/arp_eth_rx_64.v | 2 +- rtl/arp_eth_tx.v | 4 ++-- rtl/arp_eth_tx_64.v | 4 ++-- rtl/axis_eth_fcs.v | 2 +- rtl/axis_eth_fcs_64.v | 2 +- rtl/axis_eth_fcs_check.v | 4 ++-- rtl/axis_eth_fcs_check_64.v | 4 ++-- rtl/axis_eth_fcs_insert.v | 4 ++-- rtl/axis_eth_fcs_insert_64.v | 4 ++-- rtl/eth_axis_rx.v | 4 ++-- rtl/eth_axis_rx_64.v | 4 ++-- rtl/eth_axis_tx.v | 4 ++-- rtl/eth_axis_tx_64.v | 4 ++-- rtl/eth_demux.py | 4 ++-- rtl/eth_demux_4.v | 4 ++-- rtl/eth_demux_64.py | 4 ++-- rtl/eth_demux_64_4.v | 4 ++-- rtl/eth_mac_10g_rx.v | 2 +- rtl/eth_mac_10g_tx.v | 2 +- rtl/eth_mux.py | 4 ++-- rtl/eth_mux_2.v | 4 ++-- rtl/eth_mux_4.v | 4 ++-- rtl/eth_mux_64.py | 4 ++-- rtl/eth_mux_64_2.v | 4 ++-- rtl/eth_mux_64_4.v | 4 ++-- rtl/ip.v | 2 +- rtl/ip_64.v | 2 +- rtl/ip_demux.py | 4 ++-- rtl/ip_demux_4.v | 4 ++-- rtl/ip_demux_64.py | 4 ++-- rtl/ip_demux_64_4.v | 4 ++-- rtl/ip_eth_rx.v | 4 ++-- rtl/ip_eth_rx_64.v | 4 ++-- rtl/ip_eth_tx.v | 4 ++-- rtl/ip_eth_tx_64.v | 4 ++-- rtl/ip_mux.py | 4 ++-- rtl/ip_mux_2.v | 4 ++-- rtl/ip_mux_4.v | 4 ++-- rtl/ip_mux_64.py | 4 ++-- rtl/ip_mux_64_2.v | 4 ++-- rtl/ip_mux_64_4.v | 4 ++-- rtl/udp_demux.py | 4 ++-- rtl/udp_demux_4.v | 4 ++-- rtl/udp_demux_64.py | 4 ++-- rtl/udp_demux_64_4.v | 4 ++-- rtl/udp_ip_rx.v | 4 ++-- rtl/udp_ip_rx_64.v | 4 ++-- rtl/udp_ip_tx.v | 4 ++-- rtl/udp_ip_tx_64.v | 4 ++-- rtl/udp_mux.py | 4 ++-- rtl/udp_mux_4.v | 4 ++-- rtl/udp_mux_64.py | 4 ++-- rtl/udp_mux_64_4.v | 4 ++-- 57 files changed, 103 insertions(+), 103 deletions(-) diff --git a/rtl/arp.v b/rtl/arp.v index a88928a9d..62f834999 100644 --- a/rtl/arp.v +++ b/rtl/arp.v @@ -386,7 +386,7 @@ always @* begin end end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin outgoing_frame_valid_reg <= 0; outgoing_eth_dest_mac_reg <= 0; diff --git a/rtl/arp_64.v b/rtl/arp_64.v index 8e9f84151..e8c39424b 100644 --- a/rtl/arp_64.v +++ b/rtl/arp_64.v @@ -390,7 +390,7 @@ always @* begin end end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin outgoing_frame_valid_reg <= 0; outgoing_eth_dest_mac_reg <= 0; diff --git a/rtl/arp_cache.v b/rtl/arp_cache.v index 0f2835bb3..88c844311 100644 --- a/rtl/arp_cache.v +++ b/rtl/arp_cache.v @@ -100,7 +100,7 @@ wire lru_full = &lru_bit; integer i; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin query_response_valid_reg <= 0; query_response_error_reg <= 0; diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index 2223b40a5..54ba2f6a9 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -326,7 +326,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index d02163408..64579d82d 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -251,7 +251,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index 30d620a55..4e42473b8 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -222,7 +222,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -283,7 +283,7 @@ assign output_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tvalid_reg <= 0; diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index 4a6a2d913..197c14c29 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -248,7 +248,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -312,7 +312,7 @@ assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tkeep_reg <= 0; diff --git a/rtl/axis_eth_fcs.v b/rtl/axis_eth_fcs.v index 60a17520f..fb24ae32c 100644 --- a/rtl/axis_eth_fcs.v +++ b/rtl/axis_eth_fcs.v @@ -67,7 +67,7 @@ eth_crc_8_inst ( .crc_next(crc_next) ); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin crc_state <= 32'hFFFFFFFF; fcs_reg <= 0; diff --git a/rtl/axis_eth_fcs_64.v b/rtl/axis_eth_fcs_64.v index 539f9dc75..4dacede72 100644 --- a/rtl/axis_eth_fcs_64.v +++ b/rtl/axis_eth_fcs_64.v @@ -124,7 +124,7 @@ eth_crc_64_inst ( .crc_next(crc_next7) ); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin crc_state <= 32'hFFFFFFFF; fcs_reg <= 0; diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v index 5b5ee4176..b83f7c752 100644 --- a/rtl/axis_eth_fcs_check.v +++ b/rtl/axis_eth_fcs_check.v @@ -204,7 +204,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; @@ -271,7 +271,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index 19fb6ae35..bba112cb6 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -424,7 +424,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; @@ -510,7 +510,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v index 665c93d5c..7cc839fa6 100644 --- a/rtl/axis_eth_fcs_insert.v +++ b/rtl/axis_eth_fcs_insert.v @@ -246,7 +246,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; @@ -294,7 +294,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; diff --git a/rtl/axis_eth_fcs_insert_64.v b/rtl/axis_eth_fcs_insert_64.v index fa6553871..a38453ff5 100644 --- a/rtl/axis_eth_fcs_insert_64.v +++ b/rtl/axis_eth_fcs_insert_64.v @@ -526,7 +526,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; @@ -583,7 +583,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index a962b42a4..f4e1b0822 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -247,7 +247,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -308,7 +308,7 @@ assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tvalid_reg <= 0; diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index 230bd2b28..b947f73b4 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -269,7 +269,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -353,7 +353,7 @@ assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tkeep_reg <= 0; diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index f62c07939..4855c5e02 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -201,7 +201,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -250,7 +250,7 @@ assign output_axis_tuser = output_axis_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tvalid_reg <= 0; diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index 32906e230..66f90d37e 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -289,7 +289,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -357,7 +357,7 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_axis_tdata_reg <= 0; output_axis_tkeep_reg <= 0; diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py index 1c14b38f2..d9097b6da 100755 --- a/rtl/eth_demux.py +++ b/rtl/eth_demux.py @@ -232,7 +232,7 @@ always @* begin output_eth_payload_tuser_int = input_eth_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -279,7 +279,7 @@ assign output_{{p}}_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; {%- for p in ports %} diff --git a/rtl/eth_demux_4.v b/rtl/eth_demux_4.v index 3ca93c52a..5609da33d 100644 --- a/rtl/eth_demux_4.v +++ b/rtl/eth_demux_4.v @@ -226,7 +226,7 @@ always @* begin output_eth_payload_tuser_int = input_eth_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -291,7 +291,7 @@ assign output_3_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_0_eth_payload_tvalid_reg <= 0; diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py index 55820c698..742c4f8da 100755 --- a/rtl/eth_demux_64.py +++ b/rtl/eth_demux_64.py @@ -236,7 +236,7 @@ always @* begin output_eth_payload_tuser_int = input_eth_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -286,7 +286,7 @@ assign output_{{p}}_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tkeep_reg <= 0; diff --git a/rtl/eth_demux_64_4.v b/rtl/eth_demux_64_4.v index 5294656a0..cbba1b3a8 100644 --- a/rtl/eth_demux_64_4.v +++ b/rtl/eth_demux_64_4.v @@ -233,7 +233,7 @@ always @* begin output_eth_payload_tuser_int = input_eth_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -304,7 +304,7 @@ assign output_3_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tkeep_reg <= 0; diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index cbb6a54d9..bd5aefacb 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -436,7 +436,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 30be231c9..f2b82358d 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -503,7 +503,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index cb3aaa6fc..f1407c662 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -264,7 +264,7 @@ always @* begin output_eth_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -313,7 +313,7 @@ assign output_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tvalid_reg <= 0; diff --git a/rtl/eth_mux_2.v b/rtl/eth_mux_2.v index 540589064..c63a6337b 100644 --- a/rtl/eth_mux_2.v +++ b/rtl/eth_mux_2.v @@ -209,7 +209,7 @@ always @* begin output_eth_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -254,7 +254,7 @@ assign output_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tvalid_reg <= 0; diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v index 7d5633bf3..ac2ce44c1 100644 --- a/rtl/eth_mux_4.v +++ b/rtl/eth_mux_4.v @@ -273,7 +273,7 @@ always @* begin output_eth_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -326,7 +326,7 @@ assign output_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tvalid_reg <= 0; diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index 2713acecb..f037dcff3 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -270,7 +270,7 @@ always @* begin output_eth_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -322,7 +322,7 @@ assign output_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tkeep_reg <= 0; diff --git a/rtl/eth_mux_64_2.v b/rtl/eth_mux_64_2.v index 61ff2215e..e9b95d2b5 100644 --- a/rtl/eth_mux_64_2.v +++ b/rtl/eth_mux_64_2.v @@ -217,7 +217,7 @@ always @* begin output_eth_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -265,7 +265,7 @@ assign output_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tkeep_reg <= 0; diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v index 085eb5db3..a8cd75a3e 100644 --- a/rtl/eth_mux_64_4.v +++ b/rtl/eth_mux_64_4.v @@ -285,7 +285,7 @@ always @* begin output_eth_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -341,7 +341,7 @@ assign output_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tkeep_reg <= 0; diff --git a/rtl/ip.v b/rtl/ip.v index d0a0d8236..e4ff38717 100644 --- a/rtl/ip.v +++ b/rtl/ip.v @@ -310,7 +310,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; arp_request_valid_reg <= 0; diff --git a/rtl/ip_64.v b/rtl/ip_64.v index 126b0e9d3..3a0bf5156 100644 --- a/rtl/ip_64.v +++ b/rtl/ip_64.v @@ -319,7 +319,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; arp_request_valid_reg <= 0; diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py index 3b848c34a..fefe1cdb3 100755 --- a/rtl/ip_demux.py +++ b/rtl/ip_demux.py @@ -310,7 +310,7 @@ always @* begin output_ip_payload_tuser_int = input_ip_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -383,7 +383,7 @@ assign output_{{p}}_ip_payload_tuser = output_ip_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; {%- for p in ports %} diff --git a/rtl/ip_demux_4.v b/rtl/ip_demux_4.v index fc5eb0093..2eb72c861 100644 --- a/rtl/ip_demux_4.v +++ b/rtl/ip_demux_4.v @@ -382,7 +382,7 @@ always @* begin output_ip_payload_tuser_int = input_ip_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -473,7 +473,7 @@ assign output_3_ip_payload_tuser = output_ip_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_0_ip_payload_tvalid_reg <= 0; diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py index 754fcbf2c..2ba047cde 100755 --- a/rtl/ip_demux_64.py +++ b/rtl/ip_demux_64.py @@ -314,7 +314,7 @@ always @* begin output_ip_payload_tuser_int = input_ip_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -390,7 +390,7 @@ assign output_{{p}}_ip_payload_tuser = output_ip_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tkeep_reg <= 0; diff --git a/rtl/ip_demux_64_4.v b/rtl/ip_demux_64_4.v index 957c20028..2a06d0dde 100644 --- a/rtl/ip_demux_64_4.v +++ b/rtl/ip_demux_64_4.v @@ -389,7 +389,7 @@ always @* begin output_ip_payload_tuser_int = input_ip_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -486,7 +486,7 @@ assign output_3_ip_payload_tuser = output_ip_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tkeep_reg <= 0; diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index 237202ce6..d25231266 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -425,7 +425,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -527,7 +527,7 @@ assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tvalid_reg <= 0; diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index fffa2d324..99b494d2a 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -502,7 +502,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -635,7 +635,7 @@ assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tkeep_reg <= 0; diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 911884a5d..014e2bdee 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -361,7 +361,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -443,7 +443,7 @@ assign output_eth_payload_tuser = output_eth_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tvalid_reg <= 0; diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 4b2778eaa..cfff84b5f 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -486,7 +486,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -585,7 +585,7 @@ assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_eth_payload_tdata_reg <= 0; output_eth_payload_tkeep_reg <= 0; diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py index 513168b18..4951b1a83 100755 --- a/rtl/ip_mux.py +++ b/rtl/ip_mux.py @@ -368,7 +368,7 @@ always @* begin output_ip_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -443,7 +443,7 @@ assign output_ip_payload_tuser = output_ip_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tvalid_reg <= 0; diff --git a/rtl/ip_mux_2.v b/rtl/ip_mux_2.v index 5ad0fa6fa..704e57cf6 100644 --- a/rtl/ip_mux_2.v +++ b/rtl/ip_mux_2.v @@ -339,7 +339,7 @@ always @* begin output_ip_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -410,7 +410,7 @@ assign output_ip_payload_tuser = output_ip_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tvalid_reg <= 0; diff --git a/rtl/ip_mux_4.v b/rtl/ip_mux_4.v index ed25252da..553349d42 100644 --- a/rtl/ip_mux_4.v +++ b/rtl/ip_mux_4.v @@ -455,7 +455,7 @@ always @* begin output_ip_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -534,7 +534,7 @@ assign output_ip_payload_tuser = output_ip_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tvalid_reg <= 0; diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py index 5f2e37143..4e17865d4 100755 --- a/rtl/ip_mux_64.py +++ b/rtl/ip_mux_64.py @@ -374,7 +374,7 @@ always @* begin output_ip_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -452,7 +452,7 @@ assign output_ip_payload_tuser = output_ip_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tkeep_reg <= 0; diff --git a/rtl/ip_mux_64_2.v b/rtl/ip_mux_64_2.v index f5f479702..c634c0863 100644 --- a/rtl/ip_mux_64_2.v +++ b/rtl/ip_mux_64_2.v @@ -347,7 +347,7 @@ always @* begin output_ip_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -421,7 +421,7 @@ assign output_ip_payload_tuser = output_ip_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tkeep_reg <= 0; diff --git a/rtl/ip_mux_64_4.v b/rtl/ip_mux_64_4.v index d5b2dda77..623449cdb 100644 --- a/rtl/ip_mux_64_4.v +++ b/rtl/ip_mux_64_4.v @@ -467,7 +467,7 @@ always @* begin output_ip_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -549,7 +549,7 @@ assign output_ip_payload_tuser = output_ip_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tkeep_reg <= 0; diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py index d18ccb2a9..cddf69454 100755 --- a/rtl/udp_demux.py +++ b/rtl/udp_demux.py @@ -334,7 +334,7 @@ always @* begin output_udp_payload_tuser_int = input_udp_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -415,7 +415,7 @@ assign output_{{p}}_udp_payload_tuser = output_udp_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_udp_payload_tdata_reg <= 0; {%- for p in ports %} diff --git a/rtl/udp_demux_4.v b/rtl/udp_demux_4.v index 06de23f03..250e98705 100644 --- a/rtl/udp_demux_4.v +++ b/rtl/udp_demux_4.v @@ -430,7 +430,7 @@ always @* begin output_udp_payload_tuser_int = input_udp_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -529,7 +529,7 @@ assign output_3_udp_payload_tuser = output_udp_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_udp_payload_tdata_reg <= 0; output_0_udp_payload_tvalid_reg <= 0; diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py index bf5c69402..18a6315dd 100755 --- a/rtl/udp_demux_64.py +++ b/rtl/udp_demux_64.py @@ -338,7 +338,7 @@ always @* begin output_udp_payload_tuser_int = input_udp_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -422,7 +422,7 @@ assign output_{{p}}_udp_payload_tuser = output_udp_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_udp_payload_tdata_reg <= 0; output_udp_payload_tkeep_reg <= 0; diff --git a/rtl/udp_demux_64_4.v b/rtl/udp_demux_64_4.v index bd28b6d7f..4d3e20f5d 100644 --- a/rtl/udp_demux_64_4.v +++ b/rtl/udp_demux_64_4.v @@ -437,7 +437,7 @@ always @* begin output_udp_payload_tuser_int = input_udp_payload_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -542,7 +542,7 @@ assign output_3_udp_payload_tuser = output_udp_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_udp_payload_tdata_reg <= 0; output_udp_payload_tkeep_reg <= 0; diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v index 99bd176e9..52d7735a8 100644 --- a/rtl/udp_ip_rx.v +++ b/rtl/udp_ip_rx.v @@ -384,7 +384,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -484,7 +484,7 @@ assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; assign output_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_udp_payload_tuser = output_udp_payload_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_udp_payload_tdata_reg <= 0; output_udp_payload_tvalid_reg <= 0; diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index b0671a635..541135ee4 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -407,7 +407,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -513,7 +513,7 @@ assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; assign output_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_udp_payload_tuser = output_udp_payload_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_udp_payload_tdata_reg <= 0; output_udp_payload_tkeep_reg <= 0; diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index d2c83cb01..652f850d9 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -352,7 +352,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -445,7 +445,7 @@ assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tvalid_reg <= 0; diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index ef660eebe..69b5ba4ed 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -407,7 +407,7 @@ always @* begin endcase end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; @@ -505,7 +505,7 @@ assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_ip_payload_tdata_reg <= 0; output_ip_payload_tkeep_reg <= 0; diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py index c06658483..96dad473e 100755 --- a/rtl/udp_mux.py +++ b/rtl/udp_mux.py @@ -400,7 +400,7 @@ always @* begin output_udp_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -483,7 +483,7 @@ assign output_udp_payload_tuser = output_udp_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_udp_payload_tdata_reg <= 0; output_udp_payload_tvalid_reg <= 0; diff --git a/rtl/udp_mux_4.v b/rtl/udp_mux_4.v index 4bbaede2e..360e8f54e 100644 --- a/rtl/udp_mux_4.v +++ b/rtl/udp_mux_4.v @@ -511,7 +511,7 @@ always @* begin output_udp_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -598,7 +598,7 @@ assign output_udp_payload_tuser = output_udp_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_udp_payload_tdata_reg <= 0; output_udp_payload_tvalid_reg <= 0; diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py index 3e80863c4..b6b5ffc4e 100755 --- a/rtl/udp_mux_64.py +++ b/rtl/udp_mux_64.py @@ -406,7 +406,7 @@ always @* begin output_udp_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -492,7 +492,7 @@ assign output_udp_payload_tuser = output_udp_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_udp_payload_tdata_reg <= 0; output_udp_payload_tkeep_reg <= 0; diff --git a/rtl/udp_mux_64_4.v b/rtl/udp_mux_64_4.v index f363402b0..e20425c6d 100644 --- a/rtl/udp_mux_64_4.v +++ b/rtl/udp_mux_64_4.v @@ -523,7 +523,7 @@ always @* begin output_udp_payload_tuser_int = current_input_tuser; end -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin select_reg <= 0; frame_reg <= 0; @@ -613,7 +613,7 @@ assign output_udp_payload_tuser = output_udp_payload_tuser_reg; // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); -always @(posedge clk or posedge rst) begin +always @(posedge clk) begin if (rst) begin output_udp_payload_tdata_reg <= 0; output_udp_payload_tkeep_reg <= 0; From 08afe3a5d285c99b259f7d27df71d8f67b993d0f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 9 Oct 2015 22:51:55 -0700 Subject: [PATCH 248/617] Synchronize MAC status signals --- rtl/eth_mac_10g_fifo.v | 36 ++++++++++++++++++++++++++++++++++-- rtl/eth_mac_1g_fifo.v | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 2232b3a38..3740d7bf2 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -104,6 +104,38 @@ wire rx_fifo_axis_tvalid; wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; +// synchronize MAC status signals into logic clock domain +wire rx_error_bad_frame_int; +wire rx_error_bad_fcs_int; + +reg [1:0] rx_sync_reg_1 = 0; +reg [1:0] rx_sync_reg_2 = 0; +reg [1:0] rx_sync_reg_3 = 0; +reg [1:0] rx_sync_reg_4 = 0; + +assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; +assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; + +always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + rx_sync_reg_1 <= 0; + end else begin + rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_error_bad_frame_int, rx_error_bad_frame_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + rx_sync_reg_2 <= 0; + rx_sync_reg_3 <= 0; + rx_sync_reg_4 <= 0; + end else begin + rx_sync_reg_2 <= rx_sync_reg_1; + rx_sync_reg_3 <= rx_sync_reg_2; + rx_sync_reg_4 <= rx_sync_reg_3; + end +end + eth_mac_10g #( .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), @@ -129,8 +161,8 @@ eth_mac_10g_inst ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_error_bad_frame(rx_error_bad_frame_int), + .rx_error_bad_fcs(rx_error_bad_fcs_int), .ifg_delay(ifg_delay) ); diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index 298554a79..15b249b70 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -101,6 +101,38 @@ wire rx_fifo_axis_tvalid; wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; +// synchronize MAC status signals into logic clock domain +wire rx_error_bad_frame_int; +wire rx_error_bad_fcs_int; + +reg [1:0] rx_sync_reg_1 = 0; +reg [1:0] rx_sync_reg_2 = 0; +reg [1:0] rx_sync_reg_3 = 0; +reg [1:0] rx_sync_reg_4 = 0; + +assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; +assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; + +always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + rx_sync_reg_1 <= 0; + end else begin + rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_error_bad_frame_int, rx_error_bad_frame_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + rx_sync_reg_2 <= 0; + rx_sync_reg_3 <= 0; + rx_sync_reg_4 <= 0; + end else begin + rx_sync_reg_2 <= rx_sync_reg_1; + rx_sync_reg_3 <= rx_sync_reg_2; + rx_sync_reg_4 <= rx_sync_reg_3; + end +end + eth_mac_1g #( .ENABLE_PADDING(ENABLE_PADDING), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) @@ -125,8 +157,8 @@ eth_mac_1g_inst ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_error_bad_frame(rx_error_bad_frame_int), + .rx_error_bad_fcs(rx_error_bad_fcs_int), .ifg_delay(ifg_delay) ); From 9d90f09de51ebe5399a649a13ec18120d35009d0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 9 Oct 2015 22:56:52 -0700 Subject: [PATCH 249/617] Rework CRC check --- rtl/axis_eth_fcs_check_64.v | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index bba112cb6..47fc8ae54 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -115,6 +115,8 @@ reg [31:0] crc_next5_save = 0; reg [31:0] crc_next6_save = 0; reg [31:0] crc_next7_save = 0; +reg [31:0] crc_check = 0; + // internal datapath reg [63:0] output_axis_tdata_int; reg [7:0] output_axis_tkeep_int; @@ -235,48 +237,56 @@ always @* begin fcs_output_tdata_1 = {56'd0, ~crc_next4_save[31:24]}; fcs_output_tkeep_0 = 8'b00011111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next0; end 8'b00000011: begin fcs_output_tdata_0 = {~crc_next5_save[15:0], input_axis_tdata_d0[47:0]}; fcs_output_tdata_1 = {48'd0, ~crc_next5_save[31:16]}; fcs_output_tkeep_0 = 8'b00111111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next1; end 8'b00000111: begin fcs_output_tdata_0 = {~crc_next6_save[7:0], input_axis_tdata_d0[55:0]}; fcs_output_tdata_1 = {40'd0, ~crc_next6_save[31:8]}; fcs_output_tkeep_0 = 8'b01111111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next2; end 8'b00001111: begin fcs_output_tdata_0 = input_axis_tdata_d0; fcs_output_tdata_1 = {32'd0, ~crc_next7_save[31:0]}; fcs_output_tkeep_0 = 8'b11111111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next3; end 8'b00011111: begin fcs_output_tdata_0 = {24'd0, ~crc_next0[31:0], input_axis_tdata[7:0]}; fcs_output_tdata_1 = 0; fcs_output_tkeep_0 = 8'b00000001; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next4; end 8'b00111111: begin fcs_output_tdata_0 = {16'd0, ~crc_next1[31:0], input_axis_tdata[15:0]}; fcs_output_tdata_1 = 0; fcs_output_tkeep_0 = 8'b00000011; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next5; end 8'b01111111: begin fcs_output_tdata_0 = {8'd0, ~crc_next2[31:0], input_axis_tdata[23:0]}; fcs_output_tdata_1 = 0; fcs_output_tkeep_0 = 8'b00000111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next6; end 8'b11111111: begin fcs_output_tdata_0 = {~crc_next3[31:0], input_axis_tdata[31:0]}; fcs_output_tdata_1 = 0; fcs_output_tkeep_0 = 8'b00001111; fcs_output_tkeep_1 = 8'b00000000; + crc_check = ~crc_next7; end default: begin fcs_output_tdata_0 = 0; @@ -379,7 +389,7 @@ always @* begin output_axis_tlast_int = 1; output_axis_tuser_int = input_axis_tuser; output_axis_tkeep_int = fcs_output_tkeep_0; - if (input_axis_tdata_masked != fcs_output_tdata_1 || input_axis_tdata_d0 != fcs_output_tdata_0) begin + if (crc_check != 32'h2144df1c) begin output_axis_tuser_int = 1; error_bad_fcs_next = 1; end @@ -388,7 +398,7 @@ always @* begin end else begin last_cycle_tkeep_next = fcs_output_tkeep_0; last_cycle_tuser_next = input_axis_tuser; - if (input_axis_tdata_masked != fcs_output_tdata_0) begin + if (crc_check != 32'h2144df1c) begin error_bad_fcs_next = 1; last_cycle_tuser_next = 1; end From dcad442e7c785739e06e7f51d4fc990bff1cb032 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 19 Oct 2015 00:30:50 -0700 Subject: [PATCH 250/617] Improve timing performance of frame length adjust module --- rtl/axis_frame_length_adjust.v | 117 ++++++++++++++++++++++++++------- 1 file changed, 92 insertions(+), 25 deletions(-) diff --git a/rtl/axis_frame_length_adjust.v b/rtl/axis_frame_length_adjust.v index 35b037061..6c1c2ae68 100644 --- a/rtl/axis_frame_length_adjust.v +++ b/rtl/axis_frame_length_adjust.v @@ -100,6 +100,10 @@ reg store_last_word; reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +// frame length counters +reg [15:0] short_counter_reg = 0, short_counter_next = 0; +reg [15:0] long_counter_reg = 0, long_counter_next = 0; + reg [DATA_WIDTH-1:0] last_word_data_reg = 0; reg [KEEP_WIDTH-1:0] last_word_keep_reg = 0; @@ -138,6 +142,9 @@ always @* begin frame_ptr_next = frame_ptr_reg; + short_counter_next = short_counter_reg; + long_counter_next = long_counter_reg; + output_axis_tdata_int = 0; output_axis_tkeep_int = 0; output_axis_tvalid_int = 0; @@ -166,6 +173,9 @@ always @* begin output_axis_tlast_int = input_axis_tlast; output_axis_tuser_int = input_axis_tuser; + short_counter_next = length_min; + long_counter_next = length_max; + if (input_axis_tready & input_axis_tvalid) begin // transfer through word_cnt = 0; @@ -173,18 +183,32 @@ always @* begin //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; if (input_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; end - frame_ptr_next = frame_ptr_reg+word_cnt; + frame_ptr_next = frame_ptr_reg+KEEP_WIDTH; - if (frame_ptr_next >= length_max) begin - output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_max - frame_ptr_reg)); + if (short_counter_reg > KEEP_WIDTH) begin + short_counter_next = short_counter_reg - KEEP_WIDTH; + end else begin + short_counter_next = 0; + end + + if (long_counter_reg > KEEP_WIDTH) begin + long_counter_next = long_counter_reg - KEEP_WIDTH; + end else begin + long_counter_next = 0; + end + + if (long_counter_reg <= word_cnt) begin + output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-long_counter_reg); if (input_axis_tlast) begin status_valid_next = 1; status_frame_pad_next = 0; - status_frame_truncate_next = frame_ptr_next > length_max; + status_frame_truncate_next = word_cnt > long_counter_reg; status_frame_length_next = length_max; - status_frame_original_length_next = frame_ptr_next; + status_frame_original_length_next = frame_ptr_reg+word_cnt; input_axis_tready_next = output_axis_tready_int_early & status_ready; frame_ptr_next = 0; + short_counter_next = length_min; + long_counter_next = length_max; state_next = STATE_IDLE; end else begin output_axis_tvalid_int = 0; @@ -193,9 +217,9 @@ always @* begin end end else begin if (input_axis_tlast) begin - status_frame_original_length_next = frame_ptr_next; - if (frame_ptr_next < length_min) begin - if (frame_ptr_reg + KEEP_WIDTH < length_min) begin + status_frame_original_length_next = frame_ptr_reg+word_cnt; + if (short_counter_reg > word_cnt) begin + if (short_counter_reg > KEEP_WIDTH) begin frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; input_axis_tready_next = 0; output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; @@ -211,16 +235,20 @@ always @* begin input_axis_tready_next = output_axis_tready_int_early & status_ready; output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_min - frame_ptr_reg)); frame_ptr_next = 0; + short_counter_next = length_min; + long_counter_next = length_max; state_next = STATE_IDLE; end end else begin status_valid_next = 1; status_frame_pad_next = 0; status_frame_truncate_next = 0; - status_frame_length_next = frame_ptr_next; - status_frame_original_length_next = frame_ptr_next; + status_frame_length_next = frame_ptr_reg+word_cnt; + status_frame_original_length_next = frame_ptr_reg+word_cnt; input_axis_tready_next = output_axis_tready_int_early & status_ready; frame_ptr_next = 0; + short_counter_next = length_min; + long_counter_next = length_max; state_next = STATE_IDLE; end end else begin @@ -249,18 +277,32 @@ always @* begin //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; if (input_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; end - frame_ptr_next = frame_ptr_reg+word_cnt; + frame_ptr_next = frame_ptr_reg+KEEP_WIDTH; - if (frame_ptr_next >= length_max) begin - output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_max - frame_ptr_reg)); + if (short_counter_reg > KEEP_WIDTH) begin + short_counter_next = short_counter_reg - KEEP_WIDTH; + end else begin + short_counter_next = 0; + end + + if (long_counter_reg > KEEP_WIDTH) begin + long_counter_next = long_counter_reg - KEEP_WIDTH; + end else begin + long_counter_next = 0; + end + + if (long_counter_reg <= word_cnt) begin + output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-long_counter_reg); if (input_axis_tlast) begin status_valid_next = 1; status_frame_pad_next = 0; - status_frame_truncate_next = frame_ptr_next > length_max; + status_frame_truncate_next = word_cnt > long_counter_reg; status_frame_length_next = length_max; - status_frame_original_length_next = frame_ptr_next; + status_frame_original_length_next = frame_ptr_reg+word_cnt; input_axis_tready_next = output_axis_tready_int_early & status_ready; frame_ptr_next = 0; + short_counter_next = length_min; + long_counter_next = length_max; state_next = STATE_IDLE; end else begin output_axis_tvalid_int = 0; @@ -269,9 +311,9 @@ always @* begin end end else begin if (input_axis_tlast) begin - status_frame_original_length_next = frame_ptr_next; - if (frame_ptr_next < length_min) begin - if (frame_ptr_reg + KEEP_WIDTH < length_min) begin + status_frame_original_length_next = frame_ptr_reg+word_cnt; + if (short_counter_reg > word_cnt) begin + if (short_counter_reg > KEEP_WIDTH) begin frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; input_axis_tready_next = 0; output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; @@ -285,18 +327,22 @@ always @* begin status_frame_truncate_next = 0; status_frame_length_next = length_min; input_axis_tready_next = output_axis_tready_int_early & status_ready; - output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_min - frame_ptr_reg)); + output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-short_counter_reg); frame_ptr_next = 0; + short_counter_next = length_min; + long_counter_next = length_max; state_next = STATE_IDLE; end end else begin status_valid_next = 1; status_frame_pad_next = 0; status_frame_truncate_next = 0; - status_frame_length_next = frame_ptr_next; - status_frame_original_length_next = frame_ptr_next; + status_frame_length_next = frame_ptr_reg+word_cnt; + status_frame_original_length_next = frame_ptr_reg+word_cnt; input_axis_tready_next = output_axis_tready_int_early & status_ready; frame_ptr_next = 0; + short_counter_next = length_min; + long_counter_next = length_max; state_next = STATE_IDLE; end end else begin @@ -320,16 +366,30 @@ always @* begin if (output_axis_tready_int) begin frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; - if (frame_ptr_next >= length_min) begin + if (short_counter_reg > KEEP_WIDTH) begin + short_counter_next = short_counter_reg - KEEP_WIDTH; + end else begin + short_counter_next = 0; + end + + if (long_counter_reg > KEEP_WIDTH) begin + long_counter_next = long_counter_reg - KEEP_WIDTH; + end else begin + long_counter_next = 0; + end + + if (short_counter_reg <= KEEP_WIDTH) begin status_valid_next = 1; status_frame_pad_next = 1; status_frame_truncate_next = 0; status_frame_length_next = length_min; input_axis_tready_next = output_axis_tready_int_early & status_ready; - output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_min - frame_ptr_reg)); + output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-short_counter_reg); output_axis_tlast_int = 1; output_axis_tuser_int = last_cycle_tuser_reg; frame_ptr_next = 0; + short_counter_next = length_min; + long_counter_next = length_max; state_next = STATE_IDLE; end else begin state_next = STATE_PAD; @@ -354,16 +414,18 @@ always @* begin //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; if (input_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; end - frame_ptr_next = frame_ptr_reg+word_cnt; + frame_ptr_next = frame_ptr_reg+KEEP_WIDTH; if (input_axis_tlast) begin status_valid_next = 1; status_frame_pad_next = 0; status_frame_truncate_next = 1; status_frame_length_next = length_max; - status_frame_original_length_next = frame_ptr_next; + status_frame_original_length_next = frame_ptr_reg+word_cnt; input_axis_tready_next = output_axis_tready_int_early & status_ready; frame_ptr_next = 0; + short_counter_next = length_min; + long_counter_next = length_max; state_next = STATE_IDLE; end else begin state_next = STATE_TRUNCATE; @@ -379,6 +441,8 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 0; + short_counter_reg <= 0; + long_counter_reg <= 0; input_axis_tready_reg <= 0; last_word_data_reg <= 0; last_word_keep_reg <= 0; @@ -393,6 +457,9 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; + short_counter_reg <= short_counter_next; + long_counter_reg <= long_counter_next; + input_axis_tready_reg <= input_axis_tready_next; last_cycle_tuser_reg <= last_cycle_tuser_next; From 7ea566e6d29f66f74430813cb39a456745c2ff31 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 19 Oct 2015 19:15:38 -0700 Subject: [PATCH 251/617] Update generate scripts to use argparse --- rtl/axis_arb_mux.py | 72 ++++++++++------------------------- rtl/axis_arb_mux_64.py | 72 ++++++++++------------------------- rtl/axis_crosspoint.py | 72 ++++++++++------------------------- rtl/axis_crosspoint_64.py | 72 ++++++++++------------------------- rtl/axis_demux.py | 72 ++++++++++------------------------- rtl/axis_demux_64.py | 72 ++++++++++------------------------- rtl/axis_frame_join.py | 80 ++++++++++++--------------------------- rtl/axis_mux.py | 72 ++++++++++------------------------- rtl/axis_mux_64.py | 72 ++++++++++------------------------- 9 files changed, 184 insertions(+), 472 deletions(-) diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index 51629e20e..b138386bc 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""axis_arb_mux - +""" Generates an arbitrated AXI Stream mux with the specified number of ports - -Usage: axis_arb_mux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "axis_arb_mux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) @@ -187,7 +155,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -197,5 +165,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/axis_arb_mux_64.py b/rtl/axis_arb_mux_64.py index ae354538d..6fcb936d7 100755 --- a/rtl/axis_arb_mux_64.py +++ b/rtl/axis_arb_mux_64.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""axis_arb_mux_64 - +""" Generates an arbitrated AXI Stream mux with the specified number of ports - -Usage: axis_arb_mux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "axis_arb_mux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) @@ -192,7 +160,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -202,5 +170,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index c3d28c607..ac193f2d0 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""axis_crosspoint - +""" Generates an AXI Stream crosspoint switch with the specified number of ports - -Usage: axis_crosspoint [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "axis_crosspoint_{0}x{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port AXI Stream crosspoint {1}...".format(ports, name)) @@ -205,7 +173,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -215,5 +183,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index 537981541..bb871037b 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""axis_crosspoint_64 - +""" Generates an AXI Stream crosspoint switch with the specified number of ports - -Usage: axis_crosspoint_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "axis_crosspoint_64_{0}x{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port AXI Stream crosspoint {1}...".format(ports, name)) @@ -215,7 +183,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -225,5 +193,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index e696c4b95..8cd57b75d 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""axis_demux - +""" Generates an AXI Stream demux with the specified number of ports - -Usage: axis_demux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "axis_demux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port AXI Stream demux {1}...".format(ports, name)) @@ -280,7 +248,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -290,5 +258,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index 984da1372..8b3271388 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""axis_demux_64 - +""" Generates an AXI Stream demux with the specified number of ports - -Usage: axis_demux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "axis_demux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port AXI Stream demux {1}...".format(ports, name)) @@ -294,7 +262,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -304,5 +272,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index 33252dd59..91c23bb95 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""axis_frame_join - +""" Generates an AXI Stream frame join module with a specific number of input ports - -Usage: axis_frame_join [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a - + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) + +def generate(ports=4, name=None, output=None): if name is None: name = "axis_frame_join_{0}".format(ports) - - if out_name is None: - out_name = name + ".v" - - print("Opening file '%s'..." % out_name) - - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + + if output is None: + output = name + ".v" + + print("Opening file '{0}'...".format(output)) + + output_file = open(output, 'w') print("Generating {0} port AXI Stream frame joiner {1}...".format(ports, name)) @@ -414,7 +382,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -424,5 +392,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 8f0881593..16fc4c9f9 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""axis_mux - +""" Generates an AXI Stream mux with the specified number of ports - -Usage: axis_mux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "axis_mux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port AXI Stream mux {1}...".format(ports, name)) @@ -297,7 +265,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -307,5 +275,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index d011b6e03..cc5b5ede6 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""axis_mux_64 - +""" Generates an AXI Stream mux with the specified number of ports - -Usage: axis_mux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "axis_mux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port AXI Stream mux {1}...".format(ports, name)) @@ -313,7 +281,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -323,5 +291,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() From 2a59c7db1cd9401b797dc7b81a59bce4c4fa4af5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 19 Oct 2015 19:26:59 -0700 Subject: [PATCH 252/617] Update generate scripts to use argparse --- rtl/eth_arb_mux.py | 74 ++++++++++++------------------------------- rtl/eth_arb_mux_64.py | 74 ++++++++++++------------------------------- rtl/eth_demux.py | 72 ++++++++++++----------------------------- rtl/eth_demux_64.py | 72 ++++++++++++----------------------------- rtl/eth_mux.py | 72 ++++++++++++----------------------------- rtl/eth_mux_64.py | 72 ++++++++++++----------------------------- rtl/ip_arb_mux.py | 74 ++++++++++++------------------------------- rtl/ip_arb_mux_64.py | 74 ++++++++++++------------------------------- rtl/ip_demux.py | 72 ++++++++++++----------------------------- rtl/ip_demux_64.py | 72 ++++++++++++----------------------------- rtl/ip_mux.py | 72 ++++++++++++----------------------------- rtl/ip_mux_64.py | 72 ++++++++++++----------------------------- rtl/udp_arb_mux.py | 74 ++++++++++++------------------------------- rtl/udp_arb_mux_64.py | 74 ++++++++++++------------------------------- rtl/udp_demux.py | 74 ++++++++++++------------------------------- rtl/udp_demux_64.py | 74 ++++++++++++------------------------------- rtl/udp_mux.py | 74 ++++++++++++------------------------------- rtl/udp_mux_64.py | 74 ++++++++++++------------------------------- 18 files changed, 370 insertions(+), 946 deletions(-) diff --git a/rtl/eth_arb_mux.py b/rtl/eth_arb_mux.py index 06549b579..2ceaec636 100755 --- a/rtl/eth_arb_mux.py +++ b/rtl/eth_arb_mux.py @@ -1,72 +1,40 @@ #!/usr/bin/env python -"""eth_arb_mux - +""" Generates an arbitrated Ethernet mux with the specified number of ports - -Usage: eth_arb_mux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "eth_arb_mux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') - print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + print("Generating {0} port Ethernet arbitrated mux {1}...".format(ports, name)) select_width = int(math.ceil(math.log(ports, 2))) @@ -204,7 +172,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -214,5 +182,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/eth_arb_mux_64.py b/rtl/eth_arb_mux_64.py index f777de8a8..a4cc9150f 100755 --- a/rtl/eth_arb_mux_64.py +++ b/rtl/eth_arb_mux_64.py @@ -1,72 +1,40 @@ #!/usr/bin/env python -"""eth_arb_mux_64 - +""" Generates an arbitrated Ethernet mux with the specified number of ports - -Usage: eth_arb_mux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "eth_arb_mux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') - print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + print("Generating {0} port Ethernet arbitrated mux {1}...".format(ports, name)) select_width = int(math.ceil(math.log(ports, 2))) @@ -208,7 +176,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -218,5 +186,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py index d9097b6da..8bc36806b 100755 --- a/rtl/eth_demux.py +++ b/rtl/eth_demux.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""eth_demux - +""" Generates an Ethernet demux with the specified number of ports - -Usage: eth_demux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "eth_demux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port Ethernet demux {1}...".format(ports, name)) @@ -337,7 +305,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -347,5 +315,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py index 742c4f8da..e32d4e2b8 100755 --- a/rtl/eth_demux_64.py +++ b/rtl/eth_demux_64.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""eth_demux_64 - +""" Generates an Ethernet demux with the specified number of ports - -Usage: eth_demux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "eth_demux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port Ethernet demux {1}...".format(ports, name)) @@ -350,7 +318,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -360,5 +328,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index f1407c662..27fb7ab23 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""eth_mux - +""" Generates an Ethernet mux with the specified number of ports - -Usage: eth_mux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "eth_mux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port Ethernet mux {1}...".format(ports, name)) @@ -361,7 +329,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -371,5 +339,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index f037dcff3..36c47b0f9 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""eth_mux_64 - +""" Generates an Ethernet mux with the specified number of ports - -Usage: eth_mux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "eth_mux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port Ethernet mux {1}...".format(ports, name)) @@ -376,7 +344,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -386,5 +354,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/ip_arb_mux.py b/rtl/ip_arb_mux.py index 92f83fc41..26b461e2f 100755 --- a/rtl/ip_arb_mux.py +++ b/rtl/ip_arb_mux.py @@ -1,72 +1,40 @@ #!/usr/bin/env python -"""ip_arb_mux - +""" Generates an arbitrated IP mux with the specified number of ports - -Usage: ip_arb_mux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "ip_arb_mux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') - print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + print("Generating {0} port IP arbitrated mux {1}...".format(ports, name)) select_width = int(math.ceil(math.log(ports, 2))) @@ -256,7 +224,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -266,5 +234,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/ip_arb_mux_64.py b/rtl/ip_arb_mux_64.py index 43d76e1b9..38b03032a 100755 --- a/rtl/ip_arb_mux_64.py +++ b/rtl/ip_arb_mux_64.py @@ -1,72 +1,40 @@ #!/usr/bin/env python -"""ip_arb_mux_64 - +""" Generates an arbitrated IP mux with the specified number of ports - -Usage: ip_arb_mux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "ip_arb_mux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') - print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + print("Generating {0} port IP arbitrated mux {1}...".format(ports, name)) select_width = int(math.ceil(math.log(ports, 2))) @@ -260,7 +228,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -270,5 +238,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py index fefe1cdb3..d25b52508 100755 --- a/rtl/ip_demux.py +++ b/rtl/ip_demux.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""ip_demux - +""" Generates an IP demux with the specified number of ports - -Usage: ip_demux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "ip_demux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port IP demux {1}...".format(ports, name)) @@ -441,7 +409,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -451,5 +419,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py index 2ba047cde..725694a85 100755 --- a/rtl/ip_demux_64.py +++ b/rtl/ip_demux_64.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""ip_demux_64 - +""" Generates an IP demux with the specified number of ports - -Usage: ip_demux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "ip_demux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port IP demux {1}...".format(ports, name)) @@ -454,7 +422,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -464,5 +432,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py index 4951b1a83..875f6e7b0 100755 --- a/rtl/ip_mux.py +++ b/rtl/ip_mux.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""ip_mux - +""" Generates an IP mux with the specified number of ports - -Usage: ip_mux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "ip_mux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port IP mux {1}...".format(ports, name)) @@ -491,7 +459,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -501,5 +469,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py index 4e17865d4..2c3f198b9 100755 --- a/rtl/ip_mux_64.py +++ b/rtl/ip_mux_64.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""ip_mux_64 - +""" Generates an IP mux with the specified number of ports - -Usage: ip_mux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "ip_mux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port IP mux {1}...".format(ports, name)) @@ -506,7 +474,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -516,5 +484,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/udp_arb_mux.py b/rtl/udp_arb_mux.py index 99417864d..08868ec33 100755 --- a/rtl/udp_arb_mux.py +++ b/rtl/udp_arb_mux.py @@ -1,72 +1,40 @@ #!/usr/bin/env python -"""udp_arb_mux - +""" Generates an arbitrated UDP mux with the specified number of ports - -Usage: udp_arb_mux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "udp_arb_mux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') - print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + print("Generating {0} port UDP arbitrated mux {1}...".format(ports, name)) select_width = int(math.ceil(math.log(ports, 2))) @@ -272,7 +240,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -282,5 +250,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/udp_arb_mux_64.py b/rtl/udp_arb_mux_64.py index 7ebb996c4..3ff26816d 100755 --- a/rtl/udp_arb_mux_64.py +++ b/rtl/udp_arb_mux_64.py @@ -1,72 +1,40 @@ #!/usr/bin/env python -"""udp_arb_mux_64 - +""" Generates an arbitrated UDP mux with the specified number of ports - -Usage: udp_arb_mux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "udp_arb_mux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') - print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) + print("Generating {0} port UDP arbitrated mux {1}...".format(ports, name)) select_width = int(math.ceil(math.log(ports, 2))) @@ -276,7 +244,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -286,5 +254,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py index cddf69454..9adb19f02 100755 --- a/rtl/udp_demux.py +++ b/rtl/udp_demux.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""udp_demux - -Generates an UDP demux with the specified number of ports - -Usage: udp_demux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name +""" +Generates a UDP demux with the specified number of ports """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "udp_demux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port UDP demux {1}...".format(ports, name)) @@ -473,7 +441,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -483,5 +451,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py index 18a6315dd..ba54d24c4 100755 --- a/rtl/udp_demux_64.py +++ b/rtl/udp_demux_64.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""udp_demux_64 - -Generates an UDP demux with the specified number of ports - -Usage: udp_demux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name +""" +Generates a UDP demux with the specified number of ports """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "udp_demux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port UDP demux {1}...".format(ports, name)) @@ -486,7 +454,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -496,5 +464,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py index 96dad473e..7fb6b106a 100755 --- a/rtl/udp_mux.py +++ b/rtl/udp_mux.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""udp_mux - -Generates an UDP mux with the specified number of ports - -Usage: udp_mux [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name +""" +Generates a UDP mux with the specified number of ports """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "udp_mux_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port UDP mux {1}...".format(ports, name)) @@ -531,7 +499,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -541,5 +509,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py index b6b5ffc4e..68869d050 100755 --- a/rtl/udp_mux_64.py +++ b/rtl/udp_mux_64.py @@ -1,70 +1,38 @@ #!/usr/bin/env python -"""udp_mux_64 - -Generates an UDP mux with the specified number of ports - -Usage: udp_mux_64 [OPTION]... - -?, --help display this help and exit - -p, --ports specify number of ports - -n, --name specify module name - -o, --output specify output file name +""" +Generates a UDP mux with the specified number of ports """ from __future__ import print_function -import io -import sys -import getopt +import argparse import math from jinja2 import Template -class Usage(Exception): - def __init__(self, msg): - self.msg = msg +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() -def main(argv=None): - if argv is None: - argv = sys.argv try: - try: - opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="]) - except getopt.error as msg: - raise Usage(msg) - # more code, unchanged - except Usage as err: - print(err.msg, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - - ports = 4 - name = None - out_name = None - - # process options - for o, a in opts: - if o in ('-?', '--help'): - print(__doc__) - sys.exit(0) - if o in ('-p', '--ports'): - ports = int(a) - if o in ('-n', '--name'): - name = a - if o in ('-o', '--output'): - out_name = a + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) +def generate(ports=4, name=None, output=None): if name is None: name = "udp_mux_64_{0}".format(ports) - if out_name is None: - out_name = name + ".v" + if output is None: + output = name + ".v" - print("Opening file '%s'..." % out_name) + print("Opening file '{0}'...".format(output)) - try: - out_file = open(out_name, 'w') - except Exception as ex: - print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr) - exit(1) + output_file = open(output, 'w') print("Generating {0} port UDP mux {1}...".format(ports, name)) @@ -546,7 +514,7 @@ endmodule """) - out_file.write(t.render( + output_file.write(t.render( n=ports, w=select_width, name=name, @@ -556,5 +524,5 @@ endmodule print("Done") if __name__ == "__main__": - sys.exit(main()) + main() From 475f897a31ec3a75cf003ffa710bffa439365bd0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 20 Oct 2015 16:04:47 -0700 Subject: [PATCH 253/617] Unconditional increment length --- rtl/eth_mac_10g_tx.v | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index f2b82358d..8581081a4 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -355,6 +355,8 @@ always @* begin update_crc = 1; input_axis_tready_next = 1; + frame_ptr_next = frame_ptr_reg + 8; + xgmii_txd_next = input_tdata_reg; xgmii_txc_next = 8'b00000000; @@ -362,7 +364,6 @@ always @* begin input_tkeep_next = input_axis_tkeep; if (input_axis_tvalid) begin - frame_ptr_next = frame_ptr_reg + 8; if (input_axis_tlast) begin frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); input_axis_tready_next = 0; From 73e0a1cff4435be8c89163df1ca45facc16b1c53 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 20 Oct 2015 16:05:23 -0700 Subject: [PATCH 254/617] Fail outgoing frames on tvalid deassert --- rtl/eth_mac_10g_tx.v | 46 ++++++++++++++++++++++++++++++++++++++++++-- rtl/eth_mac_1g_tx.v | 25 ++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 8581081a4..fbf777874 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -71,7 +71,8 @@ localparam [2:0] STATE_PAD = 3'd2, STATE_FCS_1 = 3'd3, STATE_FCS_2 = 3'd4, - STATE_IFG = 3'd5; + STATE_IFG = 3'd5, + STATE_WAIT_END = 3'd6; reg [2:0] state_reg = STATE_IDLE, state_next; @@ -394,11 +395,12 @@ always @* begin state_next = STATE_PAYLOAD; end end else begin + // tvalid deassert, fail frame xgmii_txd_next = 64'h070707fdfefefefe; xgmii_txc_next = 8'b11111111; frame_ptr_next = 0; ifg_count_next = 8; - state_next = STATE_IFG; + state_next = STATE_WAIT_END; end end STATE_PAD: begin @@ -501,6 +503,46 @@ always @* begin end end end + STATE_WAIT_END: begin + // wait for end of frame + if (ifg_count_reg > 8) begin + ifg_count_next = ifg_count_reg - 8; + end else begin + ifg_count_next = 0; + end + + reset_crc = 1; + + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + if (ENABLE_DIC) begin + if (ifg_count_next > 7) begin + state_next = STATE_IFG; + end else begin + if (ifg_count_next >= 4) begin + deficit_idle_count_next = ifg_count_next - 4; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 0; + end + input_axis_tready_next = 1; + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 4) begin + state_next = STATE_IFG; + end else begin + input_axis_tready_next = 1; + state_next = STATE_IDLE; + end + end + end else begin + state_next = STATE_WAIT_END; + end + end else begin + state_next = STATE_WAIT_END; + end + end endcase end diff --git a/rtl/eth_mac_1g_tx.v b/rtl/eth_mac_1g_tx.v index 79f159dec..a9b2fff47 100644 --- a/rtl/eth_mac_1g_tx.v +++ b/rtl/eth_mac_1g_tx.v @@ -66,7 +66,8 @@ localparam [2:0] STATE_PAYLOAD = 3'd2, STATE_PAD = 3'd3, STATE_FCS = 3'd4, - STATE_IFG = 3'd5; + STATE_IFG = 3'd5, + STATE_WAIT_END = 3'd6; reg [2:0] state_reg = STATE_IDLE, state_next; @@ -173,9 +174,10 @@ always @* begin state_next = STATE_PAYLOAD; end end else begin + // tvalid deassert, fail frame gmii_tx_er_next = 1; frame_ptr_next = 0; - state_next = STATE_IFG; + state_next = STATE_WAIT_END; end end STATE_PAD: begin @@ -223,6 +225,25 @@ always @* begin state_next = STATE_IDLE; end end + STATE_WAIT_END: begin + // wait for end of frame + frame_ptr_next = frame_ptr_reg + 1; + reset_crc = 1; + + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + if (frame_ptr_reg < ifg_delay-1) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_WAIT_END; + end + end else begin + state_next = STATE_WAIT_END; + end + end endcase end From 26aacea6efe835547e803147ed42af1c5eb3748a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 28 Oct 2015 12:40:23 -0700 Subject: [PATCH 255/617] Remove unused code --- rtl/eth_mac_10g_tx.v | 2 -- 1 file changed, 2 deletions(-) diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index fbf777874..94f049c75 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -104,8 +104,6 @@ reg [7:0] frame_ptr_reg = 0, frame_ptr_next; reg [7:0] ifg_count_reg = 0, ifg_count_next; reg [1:0] deficit_idle_count_reg = 0, deficit_idle_count_next; -reg busy_reg = 0; - reg input_axis_tready_reg = 0, input_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; From 17bf03d7a23bfa41b0f64032b1ae106fc4087490 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 3 Nov 2015 15:30:08 -0800 Subject: [PATCH 256/617] 10G MAC RX optimizations --- rtl/eth_mac_10g_rx.v | 222 ++++++++++++------------------------------- 1 file changed, 60 insertions(+), 162 deletions(-) diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index bd5aefacb..f6814a044 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -67,15 +67,7 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [63:0] xgmii_rxd_masked; - -reg [63:0] fcs_output_tdata_0; -reg [63:0] fcs_output_tdata_1; -reg [7:0] fcs_output_tkeep_0; -reg [7:0] fcs_output_tkeep_1; - reg [7:0] last_cycle_tkeep_reg = 0, last_cycle_tkeep_next; -reg last_cycle_tuser_reg = 0, last_cycle_tuser_next; reg lanes_swapped = 0; reg [31:0] swap_rxd = 0; @@ -97,23 +89,21 @@ reg error_bad_frame_reg = 0, error_bad_frame_next; reg error_bad_fcs_reg = 0, error_bad_fcs_next; reg [31:0] crc_state = 32'hFFFFFFFF; +reg [31:0] crc_state3 = 32'hFFFFFFFF; wire [31:0] crc_next0; wire [31:0] crc_next1; wire [31:0] crc_next2; wire [31:0] crc_next3; -wire [31:0] crc_next4; -wire [31:0] crc_next5; -wire [31:0] crc_next6; wire [31:0] crc_next7; -reg [31:0] crc_next3_save = 0; -reg [31:0] crc_next4_save = 0; -reg [31:0] crc_next5_save = 0; -reg [31:0] crc_next6_save = 0; -reg [31:0] crc_next7_save = 0; +wire crc_valid0 = crc_next0 == ~32'h2144df1c; +wire crc_valid1 = crc_next1 == ~32'h2144df1c; +wire crc_valid2 = crc_next2 == ~32'h2144df1c; +wire crc_valid3 = crc_next3 == ~32'h2144df1c; +wire crc_valid7 = crc_next7 == ~32'h2144df1c; -reg [31:0] crc_check = 0; +reg crc_valid7_save = 0; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -124,55 +114,36 @@ assign output_axis_tuser = output_axis_tuser_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; +wire last_cycle = state_reg == STATE_LAST; + eth_crc_8 eth_crc_8_inst ( - .data_in(xgmii_rxd_d0[7:0]), - .crc_state(crc_state), + .data_in(last_cycle ? xgmii_rxd_d1[39:32] : xgmii_rxd_d0[7:0]), + .crc_state(last_cycle ? crc_state3 : crc_state), .crc_next(crc_next0) ); eth_crc_16 eth_crc_16_inst ( - .data_in(xgmii_rxd_d0[15:0]), - .crc_state(crc_state), + .data_in(last_cycle ? xgmii_rxd_d1[47:32] : xgmii_rxd_d0[15:0]), + .crc_state(last_cycle ? crc_state3 : crc_state), .crc_next(crc_next1) ); eth_crc_24 eth_crc_24_inst ( - .data_in(xgmii_rxd_d0[23:0]), - .crc_state(crc_state), + .data_in(last_cycle ? xgmii_rxd_d1[55:32] : xgmii_rxd_d0[23:0]), + .crc_state(last_cycle ? crc_state3 : crc_state), .crc_next(crc_next2) ); eth_crc_32 eth_crc_32_inst ( - .data_in(xgmii_rxd_d0[31:0]), - .crc_state(crc_state), + .data_in(last_cycle ? xgmii_rxd_d1[63:32] : xgmii_rxd_d0[31:0]), + .crc_state(last_cycle ? crc_state3 : crc_state), .crc_next(crc_next3) ); -eth_crc_40 -eth_crc_40_inst ( - .data_in(xgmii_rxd_d0[39:0]), - .crc_state(crc_state), - .crc_next(crc_next4) -); - -eth_crc_48 -eth_crc_48_inst ( - .data_in(xgmii_rxd_d0[47:0]), - .crc_state(crc_state), - .crc_next(crc_next5) -); - -eth_crc_56 -eth_crc_56_inst ( - .data_in(xgmii_rxd_d0[55:0]), - .crc_state(crc_state), - .crc_next(crc_next6) -); - eth_crc_64 eth_crc_64_inst ( .data_in(xgmii_rxd_d0[63:0]), @@ -180,80 +151,13 @@ eth_crc_64_inst ( .crc_next(crc_next7) ); -// FCS cycle calculation -always @* begin - case (xgmii_rxc_d0) - 8'b11111111: begin - fcs_output_tdata_0 = {~crc_next3_save[31:0], xgmii_rxd_d1[31:0]}; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 8'b00001111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next7_save; - end - 8'b11111110: begin - fcs_output_tdata_0 = {~crc_next4_save[23:0], xgmii_rxd_d1[39:0]}; - fcs_output_tdata_1 = {56'd0, ~crc_next4_save[31:24]}; - fcs_output_tkeep_0 = 8'b00011111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next0; - end - 8'b11111100: begin - fcs_output_tdata_0 = {~crc_next5_save[15:0], xgmii_rxd_d1[47:0]}; - fcs_output_tdata_1 = {48'd0, ~crc_next5_save[31:16]}; - fcs_output_tkeep_0 = 8'b00111111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next1; - end - 8'b11111000: begin - fcs_output_tdata_0 = {~crc_next6_save[7:0], xgmii_rxd_d1[55:0]}; - fcs_output_tdata_1 = {40'd0, ~crc_next6_save[31:8]}; - fcs_output_tkeep_0 = 8'b01111111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next2; - end - 8'b11110000: begin - fcs_output_tdata_0 = xgmii_rxd_d1; - fcs_output_tdata_1 = {32'd0, ~crc_next7_save[31:0]}; - fcs_output_tkeep_0 = 8'b11111111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next3; - end - 8'b11100000: begin - fcs_output_tdata_0 = {24'd0, ~crc_next0[31:0], xgmii_rxd_d0[7:0]}; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 8'b00000001; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next4; - end - 8'b11000000: begin - fcs_output_tdata_0 = {16'd0, ~crc_next1[31:0], xgmii_rxd_d0[15:0]}; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 8'b00000011; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next5; - end - 8'b10000000: begin - fcs_output_tdata_0 = {8'd0, ~crc_next2[31:0], xgmii_rxd_d0[23:0]}; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 8'b00000111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next6; - end - default: begin - fcs_output_tdata_0 = 0; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 0; - fcs_output_tkeep_1 = 0; - crc_check = 0; - end - endcase -end - // detect control characters reg [7:0] detect_start; reg [7:0] detect_term; reg [7:0] detect_error; +reg [7:0] detect_term_save; + integer i; always @* begin @@ -267,61 +171,63 @@ end // mask errors to within packet reg [7:0] detect_error_masked; reg [7:0] control_masked; +reg [7:0] tkeep_mask; always @* begin case (detect_term) 8'b00000000: begin detect_error_masked = detect_error; control_masked = xgmii_rxc_d0; + tkeep_mask = 8'b11111111; end 8'b00000001: begin detect_error_masked = 0; control_masked = 0; + tkeep_mask = 8'b00000000; end 8'b00000010: begin detect_error_masked = detect_error[0]; control_masked = xgmii_rxc_d0[0]; + tkeep_mask = 8'b00000001; end 8'b00000100: begin detect_error_masked = detect_error[1:0]; control_masked = xgmii_rxc_d0[1:0]; + tkeep_mask = 8'b00000011; end 8'b00001000: begin detect_error_masked = detect_error[2:0]; control_masked = xgmii_rxc_d0[2:0]; + tkeep_mask = 8'b00000111; end 8'b00010000: begin detect_error_masked = detect_error[3:0]; control_masked = xgmii_rxc_d0[3:0]; + tkeep_mask = 8'b00001111; end 8'b00100000: begin detect_error_masked = detect_error[4:0]; control_masked = xgmii_rxc_d0[4:0]; + tkeep_mask = 8'b00011111; end 8'b01000000: begin detect_error_masked = detect_error[5:0]; control_masked = xgmii_rxc_d0[5:0]; + tkeep_mask = 8'b00111111; end 8'b10000000: begin detect_error_masked = detect_error[6:0]; control_masked = xgmii_rxc_d0[6:0]; + tkeep_mask = 8'b01111111; end default: begin detect_error_masked = detect_error; control_masked = xgmii_rxc_d0; + tkeep_mask = 8'b11111111; end endcase end -// Mask input data -integer j; - -always @* begin - for (j = 0; j < 8; j = j + 1) begin - xgmii_rxd_masked[j*8 +: 8] = xgmii_rxc_d0[j] ? 8'd0 : xgmii_rxd_d0[j*8 +: 8]; - end -end - always @* begin state_next = STATE_IDLE; @@ -329,7 +235,6 @@ always @* begin update_crc = 0; last_cycle_tkeep_next = last_cycle_tkeep_reg; - last_cycle_tuser_next = last_cycle_tuser_reg; output_axis_tdata_next = 0; output_axis_tkeep_next = 0; @@ -375,14 +280,7 @@ always @* begin output_axis_tlast_next = 0; output_axis_tuser_next = 0; - if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin - // start condition in packet - flag as bad and restart - output_axis_tlast_next = 1; - output_axis_tuser_next = 1; - error_bad_frame_next = 1; - reset_crc = 1; - state_next = STATE_PAYLOAD; - end else if (control_masked) begin + if (control_masked) begin // control or error characters in packet output_axis_tlast_next = 1; output_axis_tuser_next = 1; @@ -393,9 +291,15 @@ always @* begin if (detect_term[4:0]) begin // end this cycle reset_crc = 1; - output_axis_tkeep_next = fcs_output_tkeep_0; + output_axis_tkeep_next = {tkeep_mask[3:0], 4'b1111}; output_axis_tlast_next = 1; - if (crc_check != 32'h2144df1c) begin + if ((detect_term[0] & crc_valid7_save) || + (detect_term[1] & crc_valid0) || + (detect_term[2] & crc_valid1) || + (detect_term[3] & crc_valid2) || + (detect_term[4] & crc_valid3)) begin + // CRC valid + end else begin output_axis_tuser_next = 1; error_bad_frame_next = 1; error_bad_fcs_next = 1; @@ -403,13 +307,7 @@ always @* begin state_next = STATE_IDLE; end else begin // need extra cycle - last_cycle_tkeep_next = fcs_output_tkeep_0; - last_cycle_tuser_next = 0; - if (crc_check != 32'h2144df1c) begin - error_bad_frame_next = 1; - error_bad_fcs_next = 1; - last_cycle_tuser_next = 1; - end + last_cycle_tkeep_next = {4'b0000, tkeep_mask[7:4]}; state_next = STATE_LAST; end end else begin @@ -422,10 +320,20 @@ always @* begin output_axis_tkeep_next = last_cycle_tkeep_reg; output_axis_tvalid_next = 1; output_axis_tlast_next = 1; - output_axis_tuser_next = last_cycle_tuser_reg; + output_axis_tuser_next = 0; reset_crc = 1; + if ((detect_term_save[5] & crc_valid0) || + (detect_term_save[6] & crc_valid1) || + (detect_term_save[7] & crc_valid2)) begin + // CRC valid + end else begin + output_axis_tuser_next = 1; + error_bad_frame_next = 1; + error_bad_fcs_next = 1; + end + if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin // start condition state_next = STATE_PAYLOAD; @@ -447,18 +355,15 @@ always @(posedge clk) begin output_axis_tuser_reg <= 0; last_cycle_tkeep_reg <= 0; - last_cycle_tuser_reg <= 0; error_bad_frame_reg <= 0; error_bad_fcs_reg <= 0; crc_state <= 32'hFFFFFFFF; + crc_state3 <= 32'hFFFFFFFF; + crc_valid7_save <= 0; - crc_next3_save <= 0; - crc_next4_save <= 0; - crc_next5_save <= 0; - crc_next6_save <= 0; - crc_next7_save <= 0; + detect_term_save <= 0; xgmii_rxd_d0 <= 64'h0707070707070707; xgmii_rxd_d1 <= 64'h0707070707070707; @@ -479,7 +384,6 @@ always @(posedge clk) begin output_axis_tuser_reg <= output_axis_tuser_next; last_cycle_tkeep_reg <= last_cycle_tkeep_next; - last_cycle_tuser_reg <= last_cycle_tuser_next; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; @@ -506,23 +410,17 @@ always @(posedge clk) begin xgmii_rxd_d1 <= xgmii_rxd_d0; xgmii_rxc_d1 <= xgmii_rxc_d0; + detect_term_save <= detect_term; + // datapath if (reset_crc) begin crc_state <= 32'hFFFFFFFF; - - crc_next3_save <= 0; - crc_next4_save <= 0; - crc_next5_save <= 0; - crc_next6_save <= 0; - crc_next7_save <= 0; + crc_state3 <= 32'hFFFFFFFF; + crc_valid7_save <= 0; end else if (update_crc) begin crc_state <= crc_next7; - - crc_next3_save <= crc_next3; - crc_next4_save <= crc_next4; - crc_next5_save <= crc_next5; - crc_next6_save <= crc_next6; - crc_next7_save <= crc_next7; + crc_state3 <= crc_next3; + crc_valid7_save <= crc_valid7; end end end From 71235c0b928d8a4aa84fccc398d04fc19a6ee195 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 3 Nov 2015 15:32:23 -0800 Subject: [PATCH 257/617] 64 bit Ethernet FCS checker optimizations --- rtl/axis_eth_fcs_check_64.v | 243 +++++++----------------------------- 1 file changed, 44 insertions(+), 199 deletions(-) diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index 47fc8ae54..48d0268b7 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -74,24 +74,12 @@ reg update_crc; reg shift_in; reg shift_reset; -reg [63:0] input_axis_tdata_masked; - -reg [63:0] fcs_output_tdata_0; -reg [63:0] fcs_output_tdata_1; -reg [7:0] fcs_output_tkeep_0; -reg [7:0] fcs_output_tkeep_1; - -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; - reg [7:0] last_cycle_tkeep_reg = 0, last_cycle_tkeep_next; reg last_cycle_tuser_reg = 0, last_cycle_tuser_next; reg [63:0] input_axis_tdata_d0 = 0; - reg [7:0] input_axis_tkeep_d0 = 0; - reg input_axis_tvalid_d0 = 0; - reg input_axis_tuser_d0 = 0; reg busy_reg = 0; @@ -100,20 +88,18 @@ reg error_bad_fcs_reg = 0, error_bad_fcs_next; reg input_axis_tready_reg = 0, input_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; +reg [31:0] crc_state3 = 32'hFFFFFFFF; wire [31:0] crc_next0; wire [31:0] crc_next1; wire [31:0] crc_next2; wire [31:0] crc_next3; -wire [31:0] crc_next4; -wire [31:0] crc_next5; -wire [31:0] crc_next6; wire [31:0] crc_next7; -reg [31:0] crc_next4_save = 0; -reg [31:0] crc_next5_save = 0; -reg [31:0] crc_next6_save = 0; -reg [31:0] crc_next7_save = 0; +wire crc_valid0 = crc_next0 == ~32'h2144df1c; +wire crc_valid1 = crc_next1 == ~32'h2144df1c; +wire crc_valid2 = crc_next2 == ~32'h2144df1c; +wire crc_valid3 = crc_next3 == ~32'h2144df1c; reg [31:0] crc_check = 0; @@ -131,55 +117,36 @@ assign input_axis_tready = input_axis_tready_reg; assign busy = busy_reg; assign error_bad_fcs = error_bad_fcs_reg; +wire last_cycle = state_reg == STATE_LAST; + eth_crc_8 eth_crc_8_inst ( - .data_in(input_axis_tdata[7:0]), - .crc_state(crc_state), + .data_in(last_cycle ? input_axis_tdata_d0[39:32] : input_axis_tdata[7:0]), + .crc_state(last_cycle ? crc_state3 : crc_state), .crc_next(crc_next0) ); eth_crc_16 eth_crc_16_inst ( - .data_in(input_axis_tdata[15:0]), - .crc_state(crc_state), + .data_in(last_cycle ? input_axis_tdata_d0[47:32] : input_axis_tdata[15:0]), + .crc_state(last_cycle ? crc_state3 : crc_state), .crc_next(crc_next1) ); eth_crc_24 eth_crc_24_inst ( - .data_in(input_axis_tdata[23:0]), - .crc_state(crc_state), + .data_in(last_cycle ? input_axis_tdata_d0[55:32] : input_axis_tdata[23:0]), + .crc_state(last_cycle ? crc_state3 : crc_state), .crc_next(crc_next2) ); eth_crc_32 eth_crc_32_inst ( - .data_in(input_axis_tdata[31:0]), - .crc_state(crc_state), + .data_in(last_cycle ? input_axis_tdata_d0[63:32] : input_axis_tdata[31:0]), + .crc_state(last_cycle ? crc_state3 : crc_state), .crc_next(crc_next3) ); -eth_crc_40 -eth_crc_40_inst ( - .data_in(input_axis_tdata[39:0]), - .crc_state(crc_state), - .crc_next(crc_next4) -); - -eth_crc_48 -eth_crc_48_inst ( - .data_in(input_axis_tdata[47:0]), - .crc_state(crc_state), - .crc_next(crc_next5) -); - -eth_crc_56 -eth_crc_56_inst ( - .data_in(input_axis_tdata[55:0]), - .crc_state(crc_state), - .crc_next(crc_next6) -); - eth_crc_64 eth_crc_64_inst ( .data_in(input_axis_tdata[63:0]), @@ -187,116 +154,6 @@ eth_crc_64_inst ( .crc_next(crc_next7) ); -function [3:0] keep2count; - input [7:0] k; - case (k) - 8'b00000000: keep2count = 0; - 8'b00000001: keep2count = 1; - 8'b00000011: keep2count = 2; - 8'b00000111: keep2count = 3; - 8'b00001111: keep2count = 4; - 8'b00011111: keep2count = 5; - 8'b00111111: keep2count = 6; - 8'b01111111: keep2count = 7; - 8'b11111111: keep2count = 8; - endcase -endfunction - -function [7:0] count2keep; - input [3:0] k; - case (k) - 4'd0: count2keep = 8'b00000000; - 4'd1: count2keep = 8'b00000001; - 4'd2: count2keep = 8'b00000011; - 4'd3: count2keep = 8'b00000111; - 4'd4: count2keep = 8'b00001111; - 4'd5: count2keep = 8'b00011111; - 4'd6: count2keep = 8'b00111111; - 4'd7: count2keep = 8'b01111111; - 4'd8: count2keep = 8'b11111111; - endcase -endfunction - -// Mask input data -always @* begin - input_axis_tdata_masked[ 7: 0] = input_axis_tkeep[0] ? input_axis_tdata[ 7: 0] : 8'd0; - input_axis_tdata_masked[15: 8] = input_axis_tkeep[1] ? input_axis_tdata[15: 8] : 8'd0; - input_axis_tdata_masked[23:16] = input_axis_tkeep[2] ? input_axis_tdata[23:16] : 8'd0; - input_axis_tdata_masked[31:24] = input_axis_tkeep[3] ? input_axis_tdata[31:24] : 8'd0; - input_axis_tdata_masked[39:32] = input_axis_tkeep[4] ? input_axis_tdata[39:32] : 8'd0; - input_axis_tdata_masked[47:40] = input_axis_tkeep[5] ? input_axis_tdata[47:40] : 8'd0; - input_axis_tdata_masked[55:48] = input_axis_tkeep[6] ? input_axis_tdata[55:48] : 8'd0; - input_axis_tdata_masked[63:56] = input_axis_tkeep[7] ? input_axis_tdata[63:56] : 8'd0; -end - -// FCS cycle calculation -always @* begin - case (input_axis_tkeep) - 8'b00000001: begin - fcs_output_tdata_0 = {~crc_next4_save[23:0], input_axis_tdata_d0[39:0]}; - fcs_output_tdata_1 = {56'd0, ~crc_next4_save[31:24]}; - fcs_output_tkeep_0 = 8'b00011111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next0; - end - 8'b00000011: begin - fcs_output_tdata_0 = {~crc_next5_save[15:0], input_axis_tdata_d0[47:0]}; - fcs_output_tdata_1 = {48'd0, ~crc_next5_save[31:16]}; - fcs_output_tkeep_0 = 8'b00111111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next1; - end - 8'b00000111: begin - fcs_output_tdata_0 = {~crc_next6_save[7:0], input_axis_tdata_d0[55:0]}; - fcs_output_tdata_1 = {40'd0, ~crc_next6_save[31:8]}; - fcs_output_tkeep_0 = 8'b01111111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next2; - end - 8'b00001111: begin - fcs_output_tdata_0 = input_axis_tdata_d0; - fcs_output_tdata_1 = {32'd0, ~crc_next7_save[31:0]}; - fcs_output_tkeep_0 = 8'b11111111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next3; - end - 8'b00011111: begin - fcs_output_tdata_0 = {24'd0, ~crc_next0[31:0], input_axis_tdata[7:0]}; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 8'b00000001; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next4; - end - 8'b00111111: begin - fcs_output_tdata_0 = {16'd0, ~crc_next1[31:0], input_axis_tdata[15:0]}; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 8'b00000011; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next5; - end - 8'b01111111: begin - fcs_output_tdata_0 = {8'd0, ~crc_next2[31:0], input_axis_tdata[23:0]}; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 8'b00000111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next6; - end - 8'b11111111: begin - fcs_output_tdata_0 = {~crc_next3[31:0], input_axis_tdata[31:0]}; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 8'b00001111; - fcs_output_tkeep_1 = 8'b00000000; - crc_check = ~crc_next7; - end - default: begin - fcs_output_tdata_0 = 0; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 0; - fcs_output_tkeep_1 = 0; - end - endcase -end - always @* begin state_next = STATE_IDLE; @@ -305,8 +162,6 @@ always @* begin shift_in = 0; shift_reset = 0; - frame_ptr_next = frame_ptr_reg; - last_cycle_tkeep_next = last_cycle_tkeep_reg; last_cycle_tuser_next = last_cycle_tuser_reg; @@ -324,7 +179,6 @@ always @* begin STATE_IDLE: begin // idle state - wait for data input_axis_tready_next = output_axis_tready_int_early; - frame_ptr_next = 0; reset_crc = 1; output_axis_tdata_int = input_axis_tdata_d0; @@ -337,27 +191,27 @@ always @* begin shift_in = 1; reset_crc = 0; update_crc = 1; - frame_ptr_next = keep2count(input_axis_tkeep); if (input_axis_tlast) begin if (input_axis_tkeep[7:4] == 0) begin shift_reset = 1; reset_crc = 1; output_axis_tlast_int = 1; output_axis_tuser_int = input_axis_tuser; - output_axis_tkeep_int = fcs_output_tkeep_0; - if (input_axis_tdata_masked != fcs_output_tdata_1 || input_axis_tdata_d0 != fcs_output_tdata_0) begin + output_axis_tkeep_int = {input_axis_tkeep[3:0], 4'b1111}; + if ((input_axis_tkeep[3:0] == 4'b0001 & crc_valid0) || + (input_axis_tkeep[3:0] == 4'b0011 & crc_valid1) || + (input_axis_tkeep[3:0] == 4'b0111 & crc_valid2) || + (input_axis_tkeep[3:0] == 4'b1111 & crc_valid3)) begin + // CRC valid + end else begin output_axis_tuser_int = 1; error_bad_fcs_next = 1; end input_axis_tready_next = output_axis_tready_int_early; state_next = STATE_IDLE; end else begin - last_cycle_tkeep_next = fcs_output_tkeep_0; + last_cycle_tkeep_next = {4'b0000, input_axis_tkeep[7:4]}; last_cycle_tuser_next = input_axis_tuser; - if (input_axis_tdata_masked != fcs_output_tdata_0) begin - error_bad_fcs_next = 1; - last_cycle_tuser_next = 1; - end input_axis_tready_next = 0; state_next = STATE_LAST; end @@ -381,27 +235,27 @@ always @* begin if (input_axis_tready & input_axis_tvalid) begin shift_in = 1; update_crc = 1; - frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); if (input_axis_tlast) begin if (input_axis_tkeep[7:4] == 0) begin shift_reset = 1; reset_crc = 1; output_axis_tlast_int = 1; output_axis_tuser_int = input_axis_tuser; - output_axis_tkeep_int = fcs_output_tkeep_0; - if (crc_check != 32'h2144df1c) begin + output_axis_tkeep_int = {input_axis_tkeep[3:0], 4'b1111}; + if ((input_axis_tkeep[3:0] == 4'b0001 & crc_valid0) || + (input_axis_tkeep[3:0] == 4'b0011 & crc_valid1) || + (input_axis_tkeep[3:0] == 4'b0111 & crc_valid2) || + (input_axis_tkeep[3:0] == 4'b1111 & crc_valid3)) begin + // CRC valid + end else begin output_axis_tuser_int = 1; error_bad_fcs_next = 1; end input_axis_tready_next = output_axis_tready_int_early; state_next = STATE_IDLE; end else begin - last_cycle_tkeep_next = fcs_output_tkeep_0; + last_cycle_tkeep_next = {4'b0000, input_axis_tkeep[7:4]}; last_cycle_tuser_next = input_axis_tuser; - if (crc_check != 32'h2144df1c) begin - error_bad_fcs_next = 1; - last_cycle_tuser_next = 1; - end input_axis_tready_next = 0; state_next = STATE_LAST; end @@ -422,6 +276,16 @@ always @* begin output_axis_tlast_int = 1; output_axis_tuser_int = last_cycle_tuser_reg; + if ((input_axis_tkeep_d0[7:4] == 4'b0001 & crc_valid0) || + (input_axis_tkeep_d0[7:4] == 4'b0011 & crc_valid1) || + (input_axis_tkeep_d0[7:4] == 4'b0111 & crc_valid2) || + (input_axis_tkeep_d0[7:4] == 4'b1111 & crc_valid3)) begin + // CRC valid + end else begin + output_axis_tuser_int = 1; + error_bad_fcs_next = 1; + end + if (output_axis_tready_int) begin shift_reset = 1; reset_crc = 1; @@ -437,8 +301,6 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - - frame_ptr_reg <= 0; last_cycle_tkeep_reg <= 0; last_cycle_tuser_reg <= 0; @@ -449,16 +311,10 @@ always @(posedge clk) begin error_bad_fcs_reg <= 0; crc_state <= 32'hFFFFFFFF; - - crc_next4_save <= 0; - crc_next5_save <= 0; - crc_next6_save <= 0; - crc_next7_save <= 0; + crc_state3 <= 32'hFFFFFFFF; end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; - last_cycle_tkeep_reg <= last_cycle_tkeep_next; last_cycle_tuser_reg <= last_cycle_tuser_next; @@ -470,29 +326,18 @@ always @(posedge clk) begin // datapath if (reset_crc) begin crc_state <= 32'hFFFFFFFF; - - crc_next4_save <= 0; - crc_next5_save <= 0; - crc_next6_save <= 0; - crc_next7_save <= 0; + crc_state3 <= 32'hFFFFFFFF; end else if (update_crc) begin crc_state <= crc_next7; - - crc_next4_save <= crc_next4; - crc_next5_save <= crc_next5; - crc_next6_save <= crc_next6; - crc_next7_save <= crc_next7; + crc_state3 <= crc_next3; end if (shift_reset) begin input_axis_tvalid_d0 <= 0; end else if (shift_in) begin input_axis_tdata_d0 <= input_axis_tdata; - input_axis_tkeep_d0 <= input_axis_tkeep; - input_axis_tvalid_d0 <= input_axis_tvalid; - input_axis_tuser_d0 <= input_axis_tuser; end end From 0f0ebfb87df82875656c64fa6f1651f4b29b6362 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 7 Nov 2015 01:15:11 -0800 Subject: [PATCH 258/617] Reorganize FIFO modules --- rtl/axis_async_fifo.v | 192 ++++++++++------- rtl/axis_async_fifo_64.v | 194 ++++++++++------- rtl/axis_async_frame_fifo.v | 369 +++++++++++++++++--------------- rtl/axis_async_frame_fifo_64.v | 371 ++++++++++++++++++--------------- rtl/axis_fifo.v | 109 ++++++---- rtl/axis_fifo_64.v | 112 ++++++---- rtl/axis_frame_fifo.v | 183 +++++++++------- rtl/axis_frame_fifo_64.v | 184 +++++++++------- 8 files changed, 1010 insertions(+), 704 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 4edb91551..97a572245 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -61,129 +61,163 @@ module axis_async_fifo # output wire output_axis_tuser ); -reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; -reg [ADDR_WIDTH:0] wr_ptr_gray = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; +reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; -reg input_rst_sync1 = 1; -reg input_rst_sync2 = 1; -reg input_rst_sync3 = 1; -reg output_rst_sync1 = 1; -reg output_rst_sync2 = 1; -reg output_rst_sync3 = 1; +reg input_rst_sync1_reg = 1'b1; +reg input_rst_sync2_reg = 1'b1; +reg input_rst_sync3_reg = 1'b1; +reg output_rst_sync1_reg = 1'b1; +reg output_rst_sync2_reg = 1'b1; +reg output_rst_sync3_reg = 1'b1; -reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}}; - -//(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_axis_tvalid_reg = 1'b0; - -wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync2[ADDR_WIDTH]) && - (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync2[ADDR_WIDTH-1]) && - (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2[ADDR_WIDTH-2:0])); +wire full = ((wr_ptr_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) && + (wr_ptr_gray_reg[ADDR_WIDTH-1] != rd_ptr_gray_sync2_reg[ADDR_WIDTH-1]) && + (wr_ptr_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); // empty when pointers match exactly -wire empty = rd_ptr_gray == wr_ptr_gray_sync2; +wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; -wire write = input_axis_tvalid & ~full; -wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; +// control signals +reg write; +reg read; -assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = data_out_reg; +assign input_axis_tready = ~full & ~input_rst_sync3_reg; -assign input_axis_tready = ~full & ~input_rst_sync3; +assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; // reset synchronization always @(posedge input_clk or posedge async_rst) begin if (async_rst) begin - input_rst_sync1 <= 1; - input_rst_sync2 <= 1; - input_rst_sync3 <= 1; + input_rst_sync1_reg <= 1'b1; + input_rst_sync2_reg <= 1'b1; + input_rst_sync3_reg <= 1'b1; end else begin - input_rst_sync1 <= 0; - input_rst_sync2 <= input_rst_sync1 | output_rst_sync1; - input_rst_sync3 <= input_rst_sync2; + input_rst_sync1_reg <= 1'b0; + input_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; + input_rst_sync3_reg <= input_rst_sync2_reg; end end always @(posedge output_clk or posedge async_rst) begin if (async_rst) begin - output_rst_sync1 <= 1; - output_rst_sync2 <= 1; - output_rst_sync3 <= 1; + output_rst_sync1_reg <= 1'b1; + output_rst_sync2_reg <= 1'b1; + output_rst_sync3_reg <= 1'b1; end else begin - output_rst_sync1 <= 0; - output_rst_sync2 <= output_rst_sync1; - output_rst_sync3 <= output_rst_sync2; + output_rst_sync1_reg <= 1'b0; + output_rst_sync2_reg <= output_rst_sync1_reg; + output_rst_sync3_reg <= output_rst_sync2_reg; + end +end + +// Write logic +always @* begin + write = 1'b0; + + wr_ptr_next = wr_ptr_reg; + wr_ptr_gray_next = wr_ptr_gray_reg; + + if (input_axis_tvalid) begin + // input data valid + if (~full) begin + // not full, perform write + write = 1'b1; + wr_ptr_next = wr_ptr_reg + 1; + wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); + end end end -// write always @(posedge input_clk) begin - if (input_rst_sync3) begin - wr_ptr <= 0; - wr_ptr_gray <= 0; - end else if (write) begin - mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; - wr_ptr_next = wr_ptr + 1; - wr_ptr <= wr_ptr_next; - wr_ptr_gray <= wr_ptr_next ^ (wr_ptr_next >> 1); + if (input_rst_sync3_reg) begin + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + end else begin + wr_ptr_reg <= wr_ptr_next; + wr_ptr_gray_reg <= wr_ptr_gray_next; + end + + if (write) begin + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tuser, input_axis_tdata}; end end // pointer synchronization always @(posedge input_clk) begin - if (input_rst_sync3) begin - rd_ptr_gray_sync1 <= 0; - rd_ptr_gray_sync2 <= 0; + if (input_rst_sync3_reg) begin + rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin - rd_ptr_gray_sync1 <= rd_ptr_gray; - rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg; + rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg; end end -// read always @(posedge output_clk) begin - if (output_rst_sync3) begin - rd_ptr <= 0; - rd_ptr_gray <= 0; - end else if (read) begin - data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; - rd_ptr_next = rd_ptr + 1; - rd_ptr <= rd_ptr_next; - rd_ptr_gray <= rd_ptr_next ^ (rd_ptr_next >> 1); - end -end - -// pointer synchronization -always @(posedge output_clk) begin - if (output_rst_sync3) begin - wr_ptr_gray_sync1 <= 0; - wr_ptr_gray_sync2 <= 0; + if (output_rst_sync3_reg) begin + wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin - wr_ptr_gray_sync1 <= wr_ptr_gray; - wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; + wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; + wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg; + end +end + +// Read logic +always @* begin + read = 1'b0; + + rd_ptr_next = rd_ptr_reg; + rd_ptr_gray_next = rd_ptr_gray_reg; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + // output data not valid OR currently being transferred + if (~empty) begin + // not empty, perform read + read = 1'b1; + output_axis_tvalid_next = 1'b1; + rd_ptr_next = rd_ptr_reg + 1; + rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); + end else begin + output_axis_tvalid_next = 1'b0; + end end end -// source ready output always @(posedge output_clk) begin - if (output_rst_sync3) begin + if (output_rst_sync3_reg) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; output_axis_tvalid_reg <= 1'b0; - end else if (output_axis_tready | ~output_axis_tvalid_reg) begin - output_axis_tvalid_reg <= ~empty; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_reg; + rd_ptr_reg <= rd_ptr_next; + rd_ptr_gray_reg <= rd_ptr_gray_next; + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (read) begin + {output_axis_tlast_reg, output_axis_tuser_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index c7eed0e3e..cf5ae7ed3 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -64,129 +64,165 @@ module axis_async_fifo_64 # output wire output_axis_tuser ); -reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; -reg [ADDR_WIDTH:0] wr_ptr_gray = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; +reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; -reg input_rst_sync1 = 1; -reg input_rst_sync2 = 1; -reg input_rst_sync3 = 1; -reg output_rst_sync1 = 1; -reg output_rst_sync2 = 1; -reg output_rst_sync3 = 1; +reg input_rst_sync1_reg = 1'b1; +reg input_rst_sync2_reg = 1'b1; +reg input_rst_sync3_reg = 1'b1; +reg output_rst_sync1_reg = 1'b1; +reg output_rst_sync2_reg = 1'b1; +reg output_rst_sync3_reg = 1'b1; -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; - -//(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_axis_tvalid_reg = 1'b0; - -wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync2[ADDR_WIDTH]) && - (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync2[ADDR_WIDTH-1]) && - (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2[ADDR_WIDTH-2:0])); +wire full = ((wr_ptr_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) && + (wr_ptr_gray_reg[ADDR_WIDTH-1] != rd_ptr_gray_sync2_reg[ADDR_WIDTH-1]) && + (wr_ptr_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); // empty when pointers match exactly -wire empty = rd_ptr_gray == wr_ptr_gray_sync2; +wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; -wire write = input_axis_tvalid & ~full; -wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; +// control signals +reg write; +reg read; -assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = data_out_reg; +assign input_axis_tready = ~full & ~input_rst_sync3_reg; -assign input_axis_tready = ~full & ~input_rst_sync3; +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; // reset synchronization always @(posedge input_clk or posedge async_rst) begin if (async_rst) begin - input_rst_sync1 <= 1; - input_rst_sync2 <= 1; - input_rst_sync3 <= 1; + input_rst_sync1_reg <= 1'b1; + input_rst_sync2_reg <= 1'b1; + input_rst_sync3_reg <= 1'b1; end else begin - input_rst_sync1 <= 0; - input_rst_sync2 <= input_rst_sync1 | output_rst_sync1; - input_rst_sync3 <= input_rst_sync2; + input_rst_sync1_reg <= 1'b0; + input_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; + input_rst_sync3_reg <= input_rst_sync2_reg; end end always @(posedge output_clk or posedge async_rst) begin if (async_rst) begin - output_rst_sync1 <= 1; - output_rst_sync2 <= 1; - output_rst_sync3 <= 1; + output_rst_sync1_reg <= 1'b1; + output_rst_sync2_reg <= 1'b1; + output_rst_sync3_reg <= 1'b1; end else begin - output_rst_sync1 <= 0; - output_rst_sync2 <= output_rst_sync1; - output_rst_sync3 <= output_rst_sync2; + output_rst_sync1_reg <= 1'b0; + output_rst_sync2_reg <= output_rst_sync1_reg; + output_rst_sync3_reg <= output_rst_sync2_reg; + end +end + +// Write logic +always @* begin + write = 1'b0; + + wr_ptr_next = wr_ptr_reg; + wr_ptr_gray_next = wr_ptr_gray_reg; + + if (input_axis_tvalid) begin + // input data valid + if (~full) begin + // not full, perform write + write = 1'b1; + wr_ptr_next = wr_ptr_reg + 1; + wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); + end end end -// write always @(posedge input_clk) begin - if (input_rst_sync3) begin - wr_ptr <= 0; - wr_ptr_gray <= 0; - end else if (write) begin - mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; - wr_ptr_next = wr_ptr + 1; - wr_ptr <= wr_ptr_next; - wr_ptr_gray <= wr_ptr_next ^ (wr_ptr_next >> 1); + if (input_rst_sync3_reg) begin + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + end else begin + wr_ptr_reg <= wr_ptr_next; + wr_ptr_gray_reg <= wr_ptr_gray_next; + end + + if (write) begin + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; end end // pointer synchronization always @(posedge input_clk) begin - if (input_rst_sync3) begin - rd_ptr_gray_sync1 <= 0; - rd_ptr_gray_sync2 <= 0; + if (input_rst_sync3_reg) begin + rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin - rd_ptr_gray_sync1 <= rd_ptr_gray; - rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg; + rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg; end end -// read always @(posedge output_clk) begin - if (output_rst_sync3) begin - rd_ptr <= 0; - rd_ptr_gray <= 0; - end else if (read) begin - data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; - rd_ptr_next = rd_ptr + 1; - rd_ptr <= rd_ptr_next; - rd_ptr_gray <= rd_ptr_next ^ (rd_ptr_next >> 1); - end -end - -// pointer synchronization -always @(posedge output_clk) begin - if (output_rst_sync3) begin - wr_ptr_gray_sync1 <= 0; - wr_ptr_gray_sync2 <= 0; + if (output_rst_sync3_reg) begin + wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin - wr_ptr_gray_sync1 <= wr_ptr_gray; - wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; + wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; + wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg; + end +end + +// Read logic +always @* begin + read = 1'b0; + + rd_ptr_next = rd_ptr_reg; + rd_ptr_gray_next = rd_ptr_gray_reg; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + // output data not valid OR currently being transferred + if (~empty) begin + // not empty, perform read + read = 1'b1; + output_axis_tvalid_next = 1'b1; + rd_ptr_next = rd_ptr_reg + 1; + rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); + end else begin + output_axis_tvalid_next = 1'b0; + end end end -// source ready output always @(posedge output_clk) begin - if (output_rst_sync3) begin + if (output_rst_sync3_reg) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; output_axis_tvalid_reg <= 1'b0; - end else if (output_axis_tready | ~output_axis_tvalid_reg) begin - output_axis_tvalid_reg <= ~empty; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_reg; + rd_ptr_reg <= rd_ptr_next; + rd_ptr_gray_reg <= rd_ptr_gray_next; + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (read) begin + {output_axis_tlast_reg, output_axis_tuser_reg, output_axis_tkeep_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 944b1f48b..e2f9d43e1 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -71,226 +71,267 @@ module axis_async_frame_fifo # output wire output_status_good_frame ); -reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; -reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; +reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; +reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; -reg input_rst_sync1 = 1; -reg input_rst_sync2 = 1; -reg input_rst_sync3 = 1; -reg output_rst_sync1 = 1; -reg output_rst_sync2 = 1; -reg output_rst_sync3 = 1; +reg input_rst_sync1_reg = 1'b1; +reg input_rst_sync2_reg = 1'b1; +reg input_rst_sync3_reg = 1'b1; +reg output_rst_sync1_reg = 1'b1; +reg output_rst_sync2_reg = 1'b1; +reg output_rst_sync3_reg = 1'b1; -reg drop_frame = 1'b0; -reg overflow_reg = 1'b0; -reg bad_frame_reg = 1'b0; -reg good_frame_reg = 1'b0; +reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg overflow_sync1 = 1'b0; -reg overflow_sync2 = 1'b0; -reg overflow_sync3 = 1'b0; -reg overflow_sync4 = 1'b0; -reg bad_frame_sync1 = 1'b0; -reg bad_frame_sync2 = 1'b0; -reg bad_frame_sync3 = 1'b0; -reg bad_frame_sync4 = 1'b0; -reg good_frame_sync1 = 1'b0; -reg good_frame_sync2 = 1'b0; -reg good_frame_sync3 = 1'b0; -reg good_frame_sync4 = 1'b0; - -reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; - -//(* RAM_STYLE="BLOCK" *) -reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; - -reg output_axis_tvalid_reg = 1'b0; - -wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tdata}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync2[ADDR_WIDTH]) && - (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync2[ADDR_WIDTH-1]) && - (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2[ADDR_WIDTH-2:0])); +wire full = ((wr_ptr_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) && + (wr_ptr_gray_reg[ADDR_WIDTH-1] != rd_ptr_gray_sync2_reg[ADDR_WIDTH-1]) && + (wr_ptr_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); // empty when pointers match exactly -wire empty = rd_ptr_gray == wr_ptr_gray_sync2; -// overflow in single packet -wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && - (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); +wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; +// overflow within packet +wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); -wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL); -wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; +// control signals +reg write; +reg read; -assign {output_axis_tlast, output_axis_tdata} = data_out_reg; +reg drop_frame_reg = 1'b0, drop_frame_next; +reg overflow_reg = 1'b0, overflow_next; +reg bad_frame_reg = 1'b0, bad_frame_next; +reg good_frame_reg = 1'b0, good_frame_next; -assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3; +reg overflow_sync1_reg = 1'b0; +reg overflow_sync2_reg = 1'b0; +reg overflow_sync3_reg = 1'b0; +reg overflow_sync4_reg = 1'b0; +reg bad_frame_sync1_reg = 1'b0; +reg bad_frame_sync2_reg = 1'b0; +reg bad_frame_sync3_reg = 1'b0; +reg bad_frame_sync4_reg = 1'b0; +reg good_frame_sync1_reg = 1'b0; +reg good_frame_sync2_reg = 1'b0; +reg good_frame_sync3_reg = 1'b0; +reg good_frame_sync4_reg = 1'b0; + +assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3_reg; + +assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; assign input_status_overflow = overflow_reg; assign input_status_bad_frame = bad_frame_reg; assign input_status_good_frame = good_frame_reg; -assign output_status_overflow = overflow_sync3 ^ overflow_sync4; -assign output_status_bad_frame = bad_frame_sync3 ^ bad_frame_sync4; -assign output_status_good_frame = good_frame_sync3 ^ good_frame_sync4; +assign output_status_overflow = overflow_sync3_reg ^ overflow_sync4_reg; +assign output_status_bad_frame = bad_frame_sync3_reg ^ bad_frame_sync4_reg; +assign output_status_good_frame = good_frame_sync3_reg ^ good_frame_sync4_reg; // reset synchronization always @(posedge input_clk or posedge async_rst) begin if (async_rst) begin - input_rst_sync1 <= 1; - input_rst_sync2 <= 1; - input_rst_sync3 <= 1; + input_rst_sync1_reg <= 1'b1; + input_rst_sync2_reg <= 1'b1; + input_rst_sync3_reg <= 1'b1; end else begin - input_rst_sync1 <= 0; - input_rst_sync2 <= input_rst_sync1 | output_rst_sync1; - input_rst_sync3 <= input_rst_sync2; + input_rst_sync1_reg <= 1'b0; + input_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; + input_rst_sync3_reg <= input_rst_sync2_reg; end end always @(posedge output_clk or posedge async_rst) begin if (async_rst) begin - output_rst_sync1 <= 1; - output_rst_sync2 <= 1; - output_rst_sync3 <= 1; + output_rst_sync1_reg <= 1'b1; + output_rst_sync2_reg <= 1'b1; + output_rst_sync3_reg <= 1'b1; end else begin - output_rst_sync1 <= 0; - output_rst_sync2 <= output_rst_sync1; - output_rst_sync3 <= output_rst_sync2; + output_rst_sync1_reg <= 1'b0; + output_rst_sync2_reg <= output_rst_sync1_reg; + output_rst_sync3_reg <= output_rst_sync2_reg; end end -// write -always @(posedge input_clk) begin - if (input_rst_sync3) begin - wr_ptr <= 0; - wr_ptr_cur <= 0; - wr_ptr_gray <= 0; - drop_frame <= 0; - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; - end else if (write) begin - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; - if (full | full_cur | drop_frame) begin - // buffer full, hold current pointer, drop packet at end - drop_frame <= 1; - if (input_axis_tlast) begin - wr_ptr_cur <= wr_ptr; - drop_frame <= 0; - overflow_reg <= 1; - end - end else begin - mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; - wr_ptr_cur <= wr_ptr_cur + 1; - if (input_axis_tlast) begin - if (input_axis_tuser) begin - // bad packet, reset write pointer - wr_ptr_cur <= wr_ptr; - bad_frame_reg <= 1; - end else begin - // good packet, push new write pointer - wr_ptr_next = wr_ptr_cur + 1; - wr_ptr <= wr_ptr_next; - wr_ptr_gray <= wr_ptr_next ^ (wr_ptr_next >> 1); - good_frame_reg <= 1; +// Write logic +always @* begin + write = 1'b0; + + drop_frame_next = 1'b0; + overflow_next = 1'b0; + bad_frame_next = 1'b0; + good_frame_next = 1'b0; + + wr_ptr_next = wr_ptr_reg; + wr_ptr_cur_next = wr_ptr_cur_reg; + wr_ptr_gray_next = wr_ptr_gray_reg; + + if (input_axis_tvalid) begin + // input data valid + if (~full | DROP_WHEN_FULL) begin + // not full, perform write + if (full | full_cur | drop_frame_reg) begin + // full, packet overflow, or currently dropping frame + // drop frame + drop_frame_next = 1'b1; + if (input_axis_tlast) begin + // end of frame, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + drop_frame_next = 1'b0; + overflow_next = 1'b1; + end + end else begin + write = 1'b1; + wr_ptr_cur_next = wr_ptr_cur_reg + 1; + if (input_axis_tlast) begin + // end of frame + if (input_axis_tuser) begin + // bad packet, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + bad_frame_next = 1'b1; + end else begin + // good packet, update write pointer + wr_ptr_next = wr_ptr_cur_reg + 1; + wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); + good_frame_next = 1'b1; + end end end end + end +end + +always @(posedge input_clk) begin + if (input_rst_sync3_reg) begin + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + + drop_frame_reg <= 1'b0; + overflow_reg <= 1'b0; + bad_frame_reg <= 1'b0; + good_frame_reg <= 1'b0; end else begin - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; + wr_ptr_reg <= wr_ptr_next; + wr_ptr_cur_reg <= wr_ptr_cur_next; + wr_ptr_gray_reg <= wr_ptr_gray_next; + + drop_frame_reg <= drop_frame_next; + overflow_reg <= overflow_next; + bad_frame_reg <= bad_frame_next; + good_frame_reg <= good_frame_next; + end + + if (write) begin + mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tdata}; end end // pointer synchronization always @(posedge input_clk) begin - if (input_rst_sync3) begin - rd_ptr_gray_sync1 <= 0; - rd_ptr_gray_sync2 <= 0; + if (input_rst_sync3_reg) begin + rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin - rd_ptr_gray_sync1 <= rd_ptr_gray; - rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg; + rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg; end end -// read always @(posedge output_clk) begin - if (output_rst_sync3) begin - rd_ptr <= 0; - rd_ptr_gray <= 0; - end else if (read) begin - data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; - rd_ptr_next = rd_ptr + 1; - rd_ptr <= rd_ptr_next; - rd_ptr_gray <= rd_ptr_next ^ (rd_ptr_next >> 1); - end -end - -// pointer synchronization -always @(posedge output_clk) begin - if (output_rst_sync3) begin - wr_ptr_gray_sync1 <= 0; - wr_ptr_gray_sync2 <= 0; + if (output_rst_sync3_reg) begin + wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin - wr_ptr_gray_sync1 <= wr_ptr_gray; - wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; - end -end - -// source ready output -always @(posedge output_clk) begin - if (output_rst_sync3) begin - output_axis_tvalid_reg <= 1'b0; - end else if (output_axis_tready | ~output_axis_tvalid_reg) begin - output_axis_tvalid_reg <= ~empty; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_reg; + wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; + wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg; end end // status synchronization always @(posedge input_clk) begin - if (input_rst_sync3) begin - overflow_sync1 <= 1'b0; - bad_frame_sync1 <= 1'b0; - good_frame_sync1 <= 1'b0; + if (input_rst_sync3_reg) begin + overflow_sync1_reg <= 1'b0; + bad_frame_sync1_reg <= 1'b0; + good_frame_sync1_reg <= 1'b0; end else begin - overflow_sync1 <= overflow_sync1 ^ overflow_reg; - bad_frame_sync1 <= bad_frame_sync1 ^ bad_frame_reg; - good_frame_sync1 <= good_frame_sync1 ^ good_frame_reg; + overflow_sync1_reg <= overflow_sync1_reg ^ overflow_reg; + bad_frame_sync1_reg <= bad_frame_sync1_reg ^ bad_frame_reg; + good_frame_sync1_reg <= good_frame_sync1_reg ^ good_frame_reg; end end always @(posedge output_clk) begin - if (output_rst_sync3) begin - overflow_sync2 <= 1'b0; - overflow_sync3 <= 1'b0; - bad_frame_sync2 <= 1'b0; - bad_frame_sync3 <= 1'b0; - good_frame_sync2 <= 1'b0; - good_frame_sync3 <= 1'b0; + if (output_rst_sync3_reg) begin + overflow_sync2_reg <= 1'b0; + overflow_sync3_reg <= 1'b0; + bad_frame_sync2_reg <= 1'b0; + bad_frame_sync3_reg <= 1'b0; + good_frame_sync2_reg <= 1'b0; + good_frame_sync3_reg <= 1'b0; end else begin - overflow_sync2 <= overflow_sync1; - overflow_sync3 <= overflow_sync2; - overflow_sync4 <= overflow_sync3; - bad_frame_sync2 <= bad_frame_sync1; - bad_frame_sync3 <= bad_frame_sync2; - bad_frame_sync4 <= bad_frame_sync3; - good_frame_sync2 <= good_frame_sync1; - good_frame_sync3 <= good_frame_sync2; - good_frame_sync4 <= good_frame_sync3; + overflow_sync2_reg <= overflow_sync1_reg; + overflow_sync3_reg <= overflow_sync2_reg; + overflow_sync4_reg <= overflow_sync3_reg; + bad_frame_sync2_reg <= bad_frame_sync1_reg; + bad_frame_sync3_reg <= bad_frame_sync2_reg; + bad_frame_sync4_reg <= bad_frame_sync3_reg; + good_frame_sync2_reg <= good_frame_sync1_reg; + good_frame_sync3_reg <= good_frame_sync2_reg; + good_frame_sync4_reg <= good_frame_sync3_reg; + end +end + +// Read logic +always @* begin + read = 1'b0; + + rd_ptr_next = rd_ptr_reg; + rd_ptr_gray_next = rd_ptr_gray_reg; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + // output data not valid OR currently being transferred + if (~empty) begin + // not empty, perform read + read = 1'b1; + output_axis_tvalid_next = 1'b1; + rd_ptr_next = rd_ptr_reg + 1; + rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); + end else begin + output_axis_tvalid_next = 1'b0; + end + end +end + +always @(posedge output_clk) begin + if (output_rst_sync3_reg) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + output_axis_tvalid_reg <= 1'b0; + end else begin + rd_ptr_reg <= rd_ptr_next; + rd_ptr_gray_reg <= rd_ptr_gray_next; + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (read) begin + {output_axis_tlast_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 2183ea039..2a52d9b6e 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -74,226 +74,269 @@ module axis_async_frame_fifo_64 # output wire output_status_good_frame ); -reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; -reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [ADDR_WIDTH:0] rd_ptr_gray = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; +reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; +reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync1 = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync2 = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; -reg input_rst_sync1 = 1; -reg input_rst_sync2 = 1; -reg input_rst_sync3 = 1; -reg output_rst_sync1 = 1; -reg output_rst_sync2 = 1; -reg output_rst_sync3 = 1; +reg input_rst_sync1_reg = 1'b1; +reg input_rst_sync2_reg = 1'b1; +reg input_rst_sync3_reg = 1'b1; +reg output_rst_sync1_reg = 1'b1; +reg output_rst_sync2_reg = 1'b1; +reg output_rst_sync3_reg = 1'b1; -reg drop_frame = 1'b0; -reg overflow_reg = 1'b0; -reg bad_frame_reg = 1'b0; -reg good_frame_reg = 1'b0; +reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg overflow_sync1 = 1'b0; -reg overflow_sync2 = 1'b0; -reg overflow_sync3 = 1'b0; -reg overflow_sync4 = 1'b0; -reg bad_frame_sync1 = 1'b0; -reg bad_frame_sync2 = 1'b0; -reg bad_frame_sync3 = 1'b0; -reg bad_frame_sync4 = 1'b0; -reg good_frame_sync1 = 1'b0; -reg good_frame_sync2 = 1'b0; -reg good_frame_sync3 = 1'b0; -reg good_frame_sync4 = 1'b0; - -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; - -//(* RAM_STYLE="BLOCK" *) -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; - -reg output_axis_tvalid_reg = 1'b0; - -wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray[ADDR_WIDTH] != rd_ptr_gray_sync2[ADDR_WIDTH]) && - (wr_ptr_gray[ADDR_WIDTH-1] != rd_ptr_gray_sync2[ADDR_WIDTH-1]) && - (wr_ptr_gray[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2[ADDR_WIDTH-2:0])); +wire full = ((wr_ptr_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) && + (wr_ptr_gray_reg[ADDR_WIDTH-1] != rd_ptr_gray_sync2_reg[ADDR_WIDTH-1]) && + (wr_ptr_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); // empty when pointers match exactly -wire empty = rd_ptr_gray == wr_ptr_gray_sync2; -// overflow in single packet -wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && - (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); +wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; +// overflow within packet +wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); -wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL); -wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; +// control signals +reg write; +reg read; -assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; +reg drop_frame_reg = 1'b0, drop_frame_next; +reg overflow_reg = 1'b0, overflow_next; +reg bad_frame_reg = 1'b0, bad_frame_next; +reg good_frame_reg = 1'b0, good_frame_next; -assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3; +reg overflow_sync1_reg = 1'b0; +reg overflow_sync2_reg = 1'b0; +reg overflow_sync3_reg = 1'b0; +reg overflow_sync4_reg = 1'b0; +reg bad_frame_sync1_reg = 1'b0; +reg bad_frame_sync2_reg = 1'b0; +reg bad_frame_sync3_reg = 1'b0; +reg bad_frame_sync4_reg = 1'b0; +reg good_frame_sync1_reg = 1'b0; +reg good_frame_sync2_reg = 1'b0; +reg good_frame_sync3_reg = 1'b0; +reg good_frame_sync4_reg = 1'b0; + +assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3_reg; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; assign input_status_overflow = overflow_reg; assign input_status_bad_frame = bad_frame_reg; assign input_status_good_frame = good_frame_reg; -assign output_status_overflow = overflow_sync3 ^ overflow_sync4; -assign output_status_bad_frame = bad_frame_sync3 ^ bad_frame_sync4; -assign output_status_good_frame = good_frame_sync3 ^ good_frame_sync4; +assign output_status_overflow = overflow_sync3_reg ^ overflow_sync4_reg; +assign output_status_bad_frame = bad_frame_sync3_reg ^ bad_frame_sync4_reg; +assign output_status_good_frame = good_frame_sync3_reg ^ good_frame_sync4_reg; // reset synchronization always @(posedge input_clk or posedge async_rst) begin if (async_rst) begin - input_rst_sync1 <= 1; - input_rst_sync2 <= 1; - input_rst_sync3 <= 1; + input_rst_sync1_reg <= 1'b1; + input_rst_sync2_reg <= 1'b1; + input_rst_sync3_reg <= 1'b1; end else begin - input_rst_sync1 <= 0; - input_rst_sync2 <= input_rst_sync1 | output_rst_sync1; - input_rst_sync3 <= input_rst_sync2; + input_rst_sync1_reg <= 1'b0; + input_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; + input_rst_sync3_reg <= input_rst_sync2_reg; end end always @(posedge output_clk or posedge async_rst) begin if (async_rst) begin - output_rst_sync1 <= 1; - output_rst_sync2 <= 1; - output_rst_sync3 <= 1; + output_rst_sync1_reg <= 1'b1; + output_rst_sync2_reg <= 1'b1; + output_rst_sync3_reg <= 1'b1; end else begin - output_rst_sync1 <= 0; - output_rst_sync2 <= output_rst_sync1; - output_rst_sync3 <= output_rst_sync2; + output_rst_sync1_reg <= 1'b0; + output_rst_sync2_reg <= output_rst_sync1_reg; + output_rst_sync3_reg <= output_rst_sync2_reg; end end -// write -always @(posedge input_clk) begin - if (input_rst_sync3) begin - wr_ptr <= 0; - wr_ptr_cur <= 0; - wr_ptr_gray <= 0; - drop_frame <= 0; - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; - end else if (write) begin - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; - if (full | full_cur | drop_frame) begin - // buffer full, hold current pointer, drop packet at end - drop_frame <= 1; - if (input_axis_tlast) begin - wr_ptr_cur <= wr_ptr; - drop_frame <= 0; - overflow_reg <= 1; - end - end else begin - mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; - wr_ptr_cur <= wr_ptr_cur + 1; - if (input_axis_tlast) begin - if (input_axis_tuser) begin - // bad packet, reset write pointer - wr_ptr_cur <= wr_ptr; - bad_frame_reg <= 1; - end else begin - // good packet, push new write pointer - wr_ptr_next = wr_ptr_cur + 1; - wr_ptr <= wr_ptr_next; - wr_ptr_gray <= wr_ptr_next ^ (wr_ptr_next >> 1); - good_frame_reg <= 1; +// Write logic +always @* begin + write = 1'b0; + + drop_frame_next = 1'b0; + overflow_next = 1'b0; + bad_frame_next = 1'b0; + good_frame_next = 1'b0; + + wr_ptr_next = wr_ptr_reg; + wr_ptr_cur_next = wr_ptr_cur_reg; + wr_ptr_gray_next = wr_ptr_gray_reg; + + if (input_axis_tvalid) begin + // input data valid + if (~full | DROP_WHEN_FULL) begin + // not full, perform write + if (full | full_cur | drop_frame_reg) begin + // full, packet overflow, or currently dropping frame + // drop frame + drop_frame_next = 1'b1; + if (input_axis_tlast) begin + // end of frame, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + drop_frame_next = 1'b0; + overflow_next = 1'b1; + end + end else begin + write = 1'b1; + wr_ptr_cur_next = wr_ptr_cur_reg + 1; + if (input_axis_tlast) begin + // end of frame + if (input_axis_tuser) begin + // bad packet, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + bad_frame_next = 1'b1; + end else begin + // good packet, update write pointer + wr_ptr_next = wr_ptr_cur_reg + 1; + wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); + good_frame_next = 1'b1; + end end end end + end +end + +always @(posedge input_clk) begin + if (input_rst_sync3_reg) begin + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + + drop_frame_reg <= 1'b0; + overflow_reg <= 1'b0; + bad_frame_reg <= 1'b0; + good_frame_reg <= 1'b0; end else begin - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; + wr_ptr_reg <= wr_ptr_next; + wr_ptr_cur_reg <= wr_ptr_cur_next; + wr_ptr_gray_reg <= wr_ptr_gray_next; + + drop_frame_reg <= drop_frame_next; + overflow_reg <= overflow_next; + bad_frame_reg <= bad_frame_next; + good_frame_reg <= good_frame_next; + end + + if (write) begin + mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; end end // pointer synchronization always @(posedge input_clk) begin - if (input_rst_sync3) begin - rd_ptr_gray_sync1 <= 0; - rd_ptr_gray_sync2 <= 0; + if (input_rst_sync3_reg) begin + rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin - rd_ptr_gray_sync1 <= rd_ptr_gray; - rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; + rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg; + rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg; end end -// read always @(posedge output_clk) begin - if (output_rst_sync3) begin - rd_ptr <= 0; - rd_ptr_gray <= 0; - end else if (read) begin - data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; - rd_ptr_next = rd_ptr + 1; - rd_ptr <= rd_ptr_next; - rd_ptr_gray <= rd_ptr_next ^ (rd_ptr_next >> 1); - end -end - -// pointer synchronization -always @(posedge output_clk) begin - if (output_rst_sync3) begin - wr_ptr_gray_sync1 <= 0; - wr_ptr_gray_sync2 <= 0; + if (output_rst_sync3_reg) begin + wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin - wr_ptr_gray_sync1 <= wr_ptr_gray; - wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; - end -end - -// source ready output -always @(posedge output_clk) begin - if (output_rst_sync3) begin - output_axis_tvalid_reg <= 1'b0; - end else if (output_axis_tready | ~output_axis_tvalid_reg) begin - output_axis_tvalid_reg <= ~empty; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_reg; + wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; + wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg; end end // status synchronization always @(posedge input_clk) begin - if (input_rst_sync3) begin - overflow_sync1 <= 1'b0; - bad_frame_sync1 <= 1'b0; - good_frame_sync1 <= 1'b0; + if (input_rst_sync3_reg) begin + overflow_sync1_reg <= 1'b0; + bad_frame_sync1_reg <= 1'b0; + good_frame_sync1_reg <= 1'b0; end else begin - overflow_sync1 <= overflow_sync1 ^ overflow_reg; - bad_frame_sync1 <= bad_frame_sync1 ^ bad_frame_reg; - good_frame_sync1 <= good_frame_sync1 ^ good_frame_reg; + overflow_sync1_reg <= overflow_sync1_reg ^ overflow_reg; + bad_frame_sync1_reg <= bad_frame_sync1_reg ^ bad_frame_reg; + good_frame_sync1_reg <= good_frame_sync1_reg ^ good_frame_reg; end end always @(posedge output_clk) begin - if (output_rst_sync3) begin - overflow_sync2 <= 1'b0; - overflow_sync3 <= 1'b0; - bad_frame_sync2 <= 1'b0; - bad_frame_sync3 <= 1'b0; - good_frame_sync2 <= 1'b0; - good_frame_sync3 <= 1'b0; + if (output_rst_sync3_reg) begin + overflow_sync2_reg <= 1'b0; + overflow_sync3_reg <= 1'b0; + bad_frame_sync2_reg <= 1'b0; + bad_frame_sync3_reg <= 1'b0; + good_frame_sync2_reg <= 1'b0; + good_frame_sync3_reg <= 1'b0; end else begin - overflow_sync2 <= overflow_sync1; - overflow_sync3 <= overflow_sync2; - overflow_sync4 <= overflow_sync3; - bad_frame_sync2 <= bad_frame_sync1; - bad_frame_sync3 <= bad_frame_sync2; - bad_frame_sync4 <= bad_frame_sync3; - good_frame_sync2 <= good_frame_sync1; - good_frame_sync3 <= good_frame_sync2; - good_frame_sync4 <= good_frame_sync3; + overflow_sync2_reg <= overflow_sync1_reg; + overflow_sync3_reg <= overflow_sync2_reg; + overflow_sync4_reg <= overflow_sync3_reg; + bad_frame_sync2_reg <= bad_frame_sync1_reg; + bad_frame_sync3_reg <= bad_frame_sync2_reg; + bad_frame_sync4_reg <= bad_frame_sync3_reg; + good_frame_sync2_reg <= good_frame_sync1_reg; + good_frame_sync3_reg <= good_frame_sync2_reg; + good_frame_sync4_reg <= good_frame_sync3_reg; + end +end + +// Read logic +always @* begin + read = 1'b0; + + rd_ptr_next = rd_ptr_reg; + rd_ptr_gray_next = rd_ptr_gray_reg; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + // output data not valid OR currently being transferred + if (~empty) begin + // not empty, perform read + read = 1'b1; + output_axis_tvalid_next = 1'b1; + rd_ptr_next = rd_ptr_reg + 1; + rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); + end else begin + output_axis_tvalid_next = 1'b0; + end + end +end + +always @(posedge output_clk) begin + if (output_rst_sync3_reg) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + output_axis_tvalid_reg <= 1'b0; + end else begin + rd_ptr_reg <= rd_ptr_next; + rd_ptr_gray_reg <= rd_ptr_gray_next; + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (read) begin + {output_axis_tlast_reg, output_axis_tkeep_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index c31f4ef1c..c34298ac3 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2013 Alex Forencich +Copyright (c) 2013-2015 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 @@ -57,60 +57,93 @@ module axis_fifo # output wire output_axis_tuser ); -reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}}; - -//(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_axis_tvalid_reg = 1'b0; - -wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; // full when first MSB different but rest same -wire full = ((wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && - (wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0])); +wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == rd_ptr_reg[ADDR_WIDTH-1:0])); // empty when pointers match exactly -wire empty = wr_ptr == rd_ptr; +wire empty = wr_ptr_reg == rd_ptr_reg; -wire write = input_axis_tvalid & ~full; -wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; - -assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = data_out_reg; +// control signals +reg write; +reg read; assign input_axis_tready = ~full; + +assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; -// write -always @(posedge clk) begin - if (rst) begin - wr_ptr <= 0; - end else if (write) begin - mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; - wr_ptr <= wr_ptr + 1; +// Write logic +always @* begin + write = 1'b0; + + wr_ptr_next = wr_ptr_reg; + + if (input_axis_tvalid) begin + // input data valid + if (~full) begin + // not full, perform write + write = 1'b1; + wr_ptr_next = wr_ptr_reg + 1; + end end end -// read always @(posedge clk) begin if (rst) begin - rd_ptr <= 0; - end else if (read) begin - data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; - rd_ptr <= rd_ptr + 1; - end -end - -// source ready output -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - end else if (output_axis_tready | ~output_axis_tvalid_reg) begin - output_axis_tvalid_reg <= ~empty; + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_reg; + wr_ptr_reg <= wr_ptr_next; + end + + if (write) begin + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tuser, input_axis_tdata}; + end +end + +// Read logic +always @* begin + read = 1'b0; + + rd_ptr_next = rd_ptr_reg; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + // output data not valid OR currently being transferred + if (~empty) begin + // not empty, perform read + read = 1'b1; + output_axis_tvalid_next = 1'b1; + rd_ptr_next = rd_ptr_reg + 1; + end else begin + output_axis_tvalid_next = 1'b0; + end + end +end + +always @(posedge clk) begin + if (rst) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + output_axis_tvalid_reg <= 1'b0; + end else begin + rd_ptr_reg <= rd_ptr_next; + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (read) begin + {output_axis_tlast_reg, output_axis_tuser_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v index 7409df3e2..4f1d60b1d 100644 --- a/rtl/axis_fifo_64.v +++ b/rtl/axis_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2013 Alex Forencich +Copyright (c) 2013-2015 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 @@ -60,60 +60,96 @@ module axis_fifo_64 # output wire output_axis_tuser ); -reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; - -//(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_axis_tvalid_reg = 1'b0; - -wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; // full when first MSB different but rest same -wire full = ((wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && - (wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0])); +wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == rd_ptr_reg[ADDR_WIDTH-1:0])); // empty when pointers match exactly -wire empty = wr_ptr == rd_ptr; +wire empty = wr_ptr_reg == rd_ptr_reg; -wire write = input_axis_tvalid & ~full; -wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; - -assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = data_out_reg; +// control signals +reg write; +reg read; assign input_axis_tready = ~full; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; -// write -always @(posedge clk) begin - if (rst) begin - wr_ptr <= 0; - end else if (write) begin - mem[wr_ptr[ADDR_WIDTH-1:0]] <= data_in; - wr_ptr <= wr_ptr + 1; +// FIFO write logic +always @* begin + write = 1'b0; + + wr_ptr_next = wr_ptr_reg; + + if (input_axis_tvalid) begin + // input data valid + if (~full) begin + // not full, perform write + write = 1'b1; + wr_ptr_next = wr_ptr_reg + 1; + end end end -// read always @(posedge clk) begin if (rst) begin - rd_ptr <= 0; - end else if (read) begin - data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; - rd_ptr <= rd_ptr + 1; - end -end - -// source ready output -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - end else if (output_axis_tready | ~output_axis_tvalid_reg) begin - output_axis_tvalid_reg <= ~empty; + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_reg; + wr_ptr_reg <= wr_ptr_next; + end + + if (write) begin + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; + end +end + +// FIFO read logic +always @* begin + read = 1'b0; + + rd_ptr_next = rd_ptr_reg; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + // output data not valid OR currently being transferred + if (~empty) begin + // not empty, perform read + read = 1'b1; + output_axis_tvalid_next = 1'b1; + rd_ptr_next = rd_ptr_reg + 1; + end else begin + // empty, invalidate + output_axis_tvalid_next = 1'b0; + end + end +end + +always @(posedge clk) begin + if (rst) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + output_axis_tvalid_reg <= 1'b0; + end else begin + rd_ptr_reg <= rd_ptr_next; + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (read) begin + {output_axis_tlast_reg, output_axis_tuser_reg, output_axis_tkeep_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 10e6805a0..8111eaa3f 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -64,106 +64,147 @@ module axis_frame_fifo # output wire good_frame ); -reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; +reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg drop_frame = 1'b0; -reg overflow_reg = 1'b0; -reg bad_frame_reg = 1'b0; -reg good_frame_reg = 1'b0; - -reg [DATA_WIDTH+1-1:0] data_out_reg = {1'b0, {DATA_WIDTH{1'b0}}}; - -//(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_axis_tvalid_reg = 1'b0; - -wire [DATA_WIDTH+1-1:0] data_in = {input_axis_tlast, input_axis_tdata}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; // full when first MSB different but rest same -wire full = ((wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && - (wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0])); +wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == rd_ptr_reg[ADDR_WIDTH-1:0])); // empty when pointers match exactly -wire empty = wr_ptr == rd_ptr; -// overflow in single packet -wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && - (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); +wire empty = wr_ptr_reg == rd_ptr_reg; +// overflow within packet +wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); -wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL); -wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; +// control signals +reg write; +reg read; -assign {output_axis_tlast, output_axis_tdata} = data_out_reg; +reg drop_frame_reg = 1'b0, drop_frame_next; +reg overflow_reg = 1'b0, overflow_next; +reg bad_frame_reg = 1'b0, bad_frame_next; +reg good_frame_reg = 1'b0, good_frame_next; assign input_axis_tready = (~full | DROP_WHEN_FULL); + +assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; assign overflow = overflow_reg; assign bad_frame = bad_frame_reg; assign good_frame = good_frame_reg; -// write -always @(posedge clk) begin - if (rst) begin - wr_ptr <= 0; - wr_ptr_cur <= 0; - drop_frame <= 0; - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; - end else if (write) begin - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; - if (full | full_cur | drop_frame) begin - // buffer full, hold current pointer, drop packet at end - drop_frame <= 1; - if (input_axis_tlast) begin - wr_ptr_cur <= wr_ptr; - drop_frame <= 0; - overflow_reg <= 1; - end - end else begin - mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; - wr_ptr_cur <= wr_ptr_cur + 1; - if (input_axis_tlast) begin - if (input_axis_tuser) begin - // bad packet, reset write pointer - wr_ptr_cur <= wr_ptr; - bad_frame_reg <= 1; - end else begin - // good packet, push new write pointer - wr_ptr <= wr_ptr_cur + 1; - good_frame_reg <= 1; +// Write logic +always @* begin + write = 1'b0; + + drop_frame_next = 1'b0; + overflow_next = 1'b0; + bad_frame_next = 1'b0; + good_frame_next = 1'b0; + + wr_ptr_next = wr_ptr_reg; + wr_ptr_cur_next = wr_ptr_cur_reg; + + if (input_axis_tvalid) begin + // input data valid + if (~full | DROP_WHEN_FULL) begin + // not full, perform write + if (full | full_cur | drop_frame_reg) begin + // full, packet overflow, or currently dropping frame + // drop frame + drop_frame_next = 1'b1; + if (input_axis_tlast) begin + // end of frame, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + drop_frame_next = 1'b0; + overflow_next = 1'b1; + end + end else begin + write = 1'b1; + wr_ptr_cur_next = wr_ptr_cur_reg + 1; + if (input_axis_tlast) begin + // end of frame + if (input_axis_tuser) begin + // bad packet, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + bad_frame_next = 1'b1; + end else begin + // good packet, update write pointer + wr_ptr_next = wr_ptr_cur_reg + 1; + good_frame_next = 1'b1; + end end end end + end +end + +always @(posedge clk) begin + if (rst) begin + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; + + drop_frame_reg <= 1'b0; + overflow_reg <= 1'b0; + bad_frame_reg <= 1'b0; + good_frame_reg <= 1'b0; end else begin - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; + wr_ptr_reg <= wr_ptr_next; + wr_ptr_cur_reg <= wr_ptr_cur_next; + + drop_frame_reg <= drop_frame_next; + overflow_reg <= overflow_next; + bad_frame_reg <= bad_frame_next; + good_frame_reg <= good_frame_next; + end + + if (write) begin + mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tdata}; end end -// read -always @(posedge clk) begin - if (rst) begin - rd_ptr <= 0; - end else if (read) begin - data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; - rd_ptr <= rd_ptr + 1; +// Read logic +always @* begin + read = 1'b0; + + rd_ptr_next = rd_ptr_reg; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + // output data not valid OR currently being transferred + if (~empty) begin + // not empty, perform read + read = 1'b1; + output_axis_tvalid_next = 1'b1; + rd_ptr_next = rd_ptr_reg + 1; + end else begin + // empty, invalidate + output_axis_tvalid_next = 1'b0; + end end end -// source ready output always @(posedge clk) begin if (rst) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; output_axis_tvalid_reg <= 1'b0; - end else if (output_axis_tready | ~output_axis_tvalid_reg) begin - output_axis_tvalid_reg <= ~empty; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_reg; + rd_ptr_reg <= rd_ptr_next; + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (read) begin + {output_axis_tlast_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index 085d19725..873869ce4 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -67,106 +67,148 @@ module axis_frame_fifo_64 # output wire good_frame ); -reg [ADDR_WIDTH:0] wr_ptr = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_cur = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; +reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg drop_frame = 1'b0; -reg overflow_reg = 1'b0; -reg bad_frame_reg = 1'b0; -reg good_frame_reg = 1'b0; - -reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] data_out_reg = {1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}}; - -//(* RAM_STYLE="BLOCK" *) reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg output_axis_tvalid_reg = 1'b0; - -wire [DATA_WIDTH+KEEP_WIDTH+1-1:0] data_in = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; // full when first MSB different but rest same -wire full = ((wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]) && - (wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0])); +wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == rd_ptr_reg[ADDR_WIDTH-1:0])); // empty when pointers match exactly -wire empty = wr_ptr == rd_ptr; -// overflow in single packet -wire full_cur = ((wr_ptr[ADDR_WIDTH] != wr_ptr_cur[ADDR_WIDTH]) && - (wr_ptr[ADDR_WIDTH-1:0] == wr_ptr_cur[ADDR_WIDTH-1:0])); +wire empty = wr_ptr_reg == rd_ptr_reg; +// overflow within packet +wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); -wire write = input_axis_tvalid & (~full | DROP_WHEN_FULL); -wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty; +// control signals +reg write; +reg read; -assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = data_out_reg; +reg drop_frame_reg = 1'b0, drop_frame_next; +reg overflow_reg = 1'b0, overflow_next; +reg bad_frame_reg = 1'b0, bad_frame_next; +reg good_frame_reg = 1'b0, good_frame_next; assign input_axis_tready = (~full | DROP_WHEN_FULL); + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; assign overflow = overflow_reg; assign bad_frame = bad_frame_reg; assign good_frame = good_frame_reg; -// write -always @(posedge clk) begin - if (rst) begin - wr_ptr <= 0; - wr_ptr_cur <= 0; - drop_frame <= 0; - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; - end else if (write) begin - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; - if (full | full_cur | drop_frame) begin - // buffer full, hold current pointer, drop packet at end - drop_frame <= 1; - if (input_axis_tlast) begin - wr_ptr_cur <= wr_ptr; - drop_frame <= 0; - overflow_reg <= 1; - end - end else begin - mem[wr_ptr_cur[ADDR_WIDTH-1:0]] <= data_in; - wr_ptr_cur <= wr_ptr_cur + 1; - if (input_axis_tlast) begin - if (input_axis_tuser) begin - // bad packet, reset write pointer - wr_ptr_cur <= wr_ptr; - bad_frame_reg <= 1; - end else begin - // good packet, push new write pointer - wr_ptr <= wr_ptr_cur + 1; - good_frame_reg <= 1; +// Write logic +always @* begin + write = 1'b0; + + drop_frame_next = 1'b0; + overflow_next = 1'b0; + bad_frame_next = 1'b0; + good_frame_next = 1'b0; + + wr_ptr_next = wr_ptr_reg; + wr_ptr_cur_next = wr_ptr_cur_reg; + + if (input_axis_tvalid) begin + // input data valid + if (~full | DROP_WHEN_FULL) begin + // not full, perform write + if (full | full_cur | drop_frame_reg) begin + // full, packet overflow, or currently dropping frame + // drop frame + drop_frame_next = 1'b1; + if (input_axis_tlast) begin + // end of frame, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + drop_frame_next = 1'b0; + overflow_next = 1'b1; + end + end else begin + write = 1'b1; + wr_ptr_cur_next = wr_ptr_cur_reg + 1; + if (input_axis_tlast) begin + // end of frame + if (input_axis_tuser) begin + // bad packet, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + bad_frame_next = 1'b1; + end else begin + // good packet, update write pointer + wr_ptr_next = wr_ptr_cur_reg + 1; + good_frame_next = 1'b1; + end end end end + end +end + +always @(posedge clk) begin + if (rst) begin + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; + + drop_frame_reg <= 1'b0; + overflow_reg <= 1'b0; + bad_frame_reg <= 1'b0; + good_frame_reg <= 1'b0; end else begin - overflow_reg <= 0; - bad_frame_reg <= 0; - good_frame_reg <= 0; + wr_ptr_reg <= wr_ptr_next; + wr_ptr_cur_reg <= wr_ptr_cur_next; + + drop_frame_reg <= drop_frame_next; + overflow_reg <= overflow_next; + bad_frame_reg <= bad_frame_next; + good_frame_reg <= good_frame_next; + end + + if (write) begin + mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; end end -// read -always @(posedge clk) begin - if (rst) begin - rd_ptr <= 0; - end else if (read) begin - data_out_reg <= mem[rd_ptr[ADDR_WIDTH-1:0]]; - rd_ptr <= rd_ptr + 1; +// Read logic +always @* begin + read = 1'b0; + + rd_ptr_next = rd_ptr_reg; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + // output data not valid OR currently being transferred + if (~empty) begin + // not empty, perform read + read = 1'b1; + output_axis_tvalid_next = 1'b1; + rd_ptr_next = rd_ptr_reg + 1; + end else begin + output_axis_tvalid_next = 1'b0; + end end end -// source ready output always @(posedge clk) begin if (rst) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; output_axis_tvalid_reg <= 1'b0; - end else if (output_axis_tready | ~output_axis_tvalid_reg) begin - output_axis_tvalid_reg <= ~empty; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_reg; + rd_ptr_reg <= rd_ptr_next; + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (read) begin + {output_axis_tlast_reg, output_axis_tkeep_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end From 5fb4cb159bbdfd65bec61ed3817ad34ea649b182 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 8 Nov 2015 16:18:29 -0800 Subject: [PATCH 259/617] Reorganize register modules --- rtl/axis_register.v | 116 +++++++++++++++++++++--------------- rtl/axis_register_64.v | 129 +++++++++++++++++++++++------------------ 2 files changed, 141 insertions(+), 104 deletions(-) diff --git a/rtl/axis_register.v b/rtl/axis_register.v index 35ce7555d..5c8b2309b 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -57,17 +57,22 @@ module axis_register # ); // datapath registers -reg input_axis_tready_reg = 0; +reg input_axis_tready_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_input_to_output; +reg store_axis_input_to_temp; +reg store_axis_temp_to_output; assign input_axis_tready = input_axis_tready_reg; @@ -76,48 +81,63 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +wire input_axis_tready_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~input_axis_tvalid)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_input_to_output = 1'b0; + store_axis_input_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (input_axis_tready_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = input_axis_tvalid; + store_axis_input_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = input_axis_tvalid; + store_axis_input_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - input_axis_tready_reg <= 0; - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + input_axis_tready_reg <= 1'b0; + output_axis_tvalid_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle - input_axis_tready_reg <= output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~input_axis_tvalid); + input_axis_tready_reg <= input_axis_tready_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (input_axis_tready_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= input_axis_tdata; - output_axis_tvalid_reg <= input_axis_tvalid; - output_axis_tlast_reg <= input_axis_tlast; - output_axis_tuser_reg <= input_axis_tuser; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= input_axis_tdata; - temp_axis_tvalid_reg <= input_axis_tvalid; - temp_axis_tlast_reg <= input_axis_tlast; - temp_axis_tuser_reg <= input_axis_tuser; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_input_to_output) begin + output_axis_tdata_reg <= input_axis_tdata; + output_axis_tlast_reg <= input_axis_tlast; + output_axis_tuser_reg <= input_axis_tuser; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_input_to_temp) begin + temp_axis_tdata_reg <= input_axis_tdata; + temp_axis_tlast_reg <= input_axis_tlast; + temp_axis_tuser_reg <= input_axis_tuser; end end diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v index c635b3f5a..45d631850 100644 --- a/rtl/axis_register_64.v +++ b/rtl/axis_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -60,19 +60,24 @@ module axis_register_64 # ); // datapath registers -reg input_axis_tready_reg = 0; +reg input_axis_tready_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_input_to_output; +reg store_axis_input_to_temp; +reg store_axis_temp_to_output; assign input_axis_tready = input_axis_tready_reg; @@ -82,54 +87,66 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +wire input_axis_tready_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~input_axis_tvalid)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_input_to_output = 1'b0; + store_axis_input_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (input_axis_tready_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = input_axis_tvalid; + store_axis_input_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = input_axis_tvalid; + store_axis_input_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - input_axis_tready_reg <= 0; - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + input_axis_tready_reg <= 1'b0; + output_axis_tvalid_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - // enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle - input_axis_tready_reg <= output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~input_axis_tvalid); + input_axis_tready_reg <= input_axis_tready_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (input_axis_tready_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= input_axis_tdata; - output_axis_tkeep_reg <= input_axis_tkeep; - output_axis_tvalid_reg <= input_axis_tvalid; - output_axis_tlast_reg <= input_axis_tlast; - output_axis_tuser_reg <= input_axis_tuser; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= input_axis_tdata; - temp_axis_tkeep_reg <= input_axis_tkeep; - temp_axis_tvalid_reg <= input_axis_tvalid; - temp_axis_tlast_reg <= input_axis_tlast; - temp_axis_tuser_reg <= input_axis_tuser; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_input_to_output) begin + output_axis_tdata_reg <= input_axis_tdata; + output_axis_tkeep_reg <= input_axis_tkeep; + output_axis_tlast_reg <= input_axis_tlast; + output_axis_tuser_reg <= input_axis_tuser; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_input_to_temp) begin + temp_axis_tdata_reg <= input_axis_tdata; + temp_axis_tkeep_reg <= input_axis_tkeep; + temp_axis_tlast_reg <= input_axis_tlast; + temp_axis_tuser_reg <= input_axis_tuser; end end From 0a79f24d3ca3a559a3dd7d9bbe75535a6dcd43d9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 8 Nov 2015 17:27:13 -0800 Subject: [PATCH 260/617] Do not reset datapath registers in crosspoint switch --- rtl/axis_crosspoint.py | 64 +++--- rtl/axis_crosspoint_4x4.v | 357 ++++++++++++++--------------- rtl/axis_crosspoint_64.py | 74 +++--- rtl/axis_crosspoint_64_4x4.v | 421 +++++++++++++++++------------------ 4 files changed, 446 insertions(+), 470 deletions(-) diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index ac193f2d0..5d0367d3c 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -103,21 +103,21 @@ module {{name}} # {%- endfor %} ); {% for p in ports %} -reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = 0; -reg input_{{p}}_axis_tvalid_reg = 0; -reg input_{{p}}_axis_tlast_reg = 0; -reg input_{{p}}_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg input_{{p}}_axis_tvalid_reg = 1'b0; +reg input_{{p}}_axis_tlast_reg = 1'b0; +reg input_{{p}}_axis_tuser_reg = 1'b0; {% endfor %} {%- for p in ports %} -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = 0; -reg output_{{p}}_axis_tvalid_reg = 0; -reg output_{{p}}_axis_tlast_reg = 0; -reg output_{{p}}_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_{{p}}_axis_tvalid_reg = 1'b0; +reg output_{{p}}_axis_tlast_reg = 1'b0; +reg output_{{p}}_axis_tuser_reg = 1'b0; {% endfor %} {%- for p in ports %} -reg [{{w-1}}:0] output_{{p}}_select_reg = 0; +reg [{{w-1}}:0] output_{{p}}_select_reg = {{w}}'d0; {%- endfor %} {% for p in ports %} assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; @@ -129,44 +129,48 @@ assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; always @(posedge clk) begin if (rst) begin {%- for p in ports %} - output_{{p}}_select_reg <= 0; + output_{{p}}_select_reg <= {{w}}'d0; {%- endfor %} {% for p in ports %} - input_{{p}}_axis_tdata_reg <= 0; - input_{{p}}_axis_tvalid_reg <= 0; - input_{{p}}_axis_tlast_reg <= 0; - input_{{p}}_axis_tuser_reg <= 0; + input_{{p}}_axis_tvalid_reg <= 1'b0; {%- endfor %} {% for p in ports %} - output_{{p}}_axis_tdata_reg <= 0; - output_{{p}}_axis_tvalid_reg <= 0; - output_{{p}}_axis_tlast_reg <= 0; - output_{{p}}_axis_tuser_reg <= 0; + output_{{p}}_axis_tvalid_reg <= 1'b0; {%- endfor %} end else begin {%- for p in ports %} - input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; - input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; - input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; -{% endfor %} -{%- for p in ports %} +{%- endfor %} +{% for p in ports %} output_{{p}}_select_reg <= output_{{p}}_select; {%- endfor %} {%- for p in ports %} case (output_{{p}}_select_reg) {%- for q in ports %} - {{w}}'d{{q}}: begin - output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; - output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; - output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; - output_{{p}}_axis_tuser_reg <= input_{{q}}_axis_tuser_reg; - end + {{w}}'d{{q}}: output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; {%- endfor %} endcase {%- endfor %} end +{%- for p in ports %} + + input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; + input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; + input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; +{%- endfor %} +{%- for p in ports %} + + case (output_{{p}}_select_reg) +{%- for q in ports %} + {{w}}'d{{q}}: begin + output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; + output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; + output_{{p}}_axis_tuser_reg <= input_{{q}}_axis_tuser_reg; + end +{%- endfor %} + endcase +{%- endfor %} end endmodule diff --git a/rtl/axis_crosspoint_4x4.v b/rtl/axis_crosspoint_4x4.v index cb8a26a58..d2be80b0c 100644 --- a/rtl/axis_crosspoint_4x4.v +++ b/rtl/axis_crosspoint_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -92,50 +92,50 @@ module axis_crosspoint_4x4 # input wire [1:0] output_3_select ); -reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = 0; -reg input_0_axis_tvalid_reg = 0; -reg input_0_axis_tlast_reg = 0; -reg input_0_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg input_0_axis_tvalid_reg = 1'b0; +reg input_0_axis_tlast_reg = 1'b0; +reg input_0_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = 0; -reg input_1_axis_tvalid_reg = 0; -reg input_1_axis_tlast_reg = 0; -reg input_1_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg input_1_axis_tvalid_reg = 1'b0; +reg input_1_axis_tlast_reg = 1'b0; +reg input_1_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = 0; -reg input_2_axis_tvalid_reg = 0; -reg input_2_axis_tlast_reg = 0; -reg input_2_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg input_2_axis_tvalid_reg = 1'b0; +reg input_2_axis_tlast_reg = 1'b0; +reg input_2_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = 0; -reg input_3_axis_tvalid_reg = 0; -reg input_3_axis_tlast_reg = 0; -reg input_3_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg input_3_axis_tvalid_reg = 1'b0; +reg input_3_axis_tlast_reg = 1'b0; +reg input_3_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = 0; -reg output_0_axis_tvalid_reg = 0; -reg output_0_axis_tlast_reg = 0; -reg output_0_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_0_axis_tvalid_reg = 1'b0; +reg output_0_axis_tlast_reg = 1'b0; +reg output_0_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = 0; -reg output_1_axis_tvalid_reg = 0; -reg output_1_axis_tlast_reg = 0; -reg output_1_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_1_axis_tvalid_reg = 1'b0; +reg output_1_axis_tlast_reg = 1'b0; +reg output_1_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = 0; -reg output_2_axis_tvalid_reg = 0; -reg output_2_axis_tlast_reg = 0; -reg output_2_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_2_axis_tvalid_reg = 1'b0; +reg output_2_axis_tlast_reg = 1'b0; +reg output_2_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = 0; -reg output_3_axis_tvalid_reg = 0; -reg output_3_axis_tlast_reg = 0; -reg output_3_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_3_axis_tvalid_reg = 1'b0; +reg output_3_axis_tlast_reg = 1'b0; +reg output_3_axis_tuser_reg = 1'b0; -reg [1:0] output_0_select_reg = 0; -reg [1:0] output_1_select_reg = 0; -reg [1:0] output_2_select_reg = 0; -reg [1:0] output_3_select_reg = 0; +reg [1:0] output_0_select_reg = 2'd0; +reg [1:0] output_1_select_reg = 2'd0; +reg [1:0] output_2_select_reg = 2'd0; +reg [1:0] output_3_select_reg = 2'd0; assign output_0_axis_tdata = output_0_axis_tdata_reg; assign output_0_axis_tvalid = output_0_axis_tvalid_reg; @@ -160,64 +160,25 @@ assign output_3_axis_tuser = output_3_axis_tuser_reg; always @(posedge clk) begin if (rst) begin - output_0_select_reg <= 0; - output_1_select_reg <= 0; - output_2_select_reg <= 0; - output_3_select_reg <= 0; + output_0_select_reg <= 2'd0; + output_1_select_reg <= 2'd0; + output_2_select_reg <= 2'd0; + output_3_select_reg <= 2'd0; - input_0_axis_tdata_reg <= 0; - input_0_axis_tvalid_reg <= 0; - input_0_axis_tlast_reg <= 0; - input_0_axis_tuser_reg <= 0; - input_1_axis_tdata_reg <= 0; - input_1_axis_tvalid_reg <= 0; - input_1_axis_tlast_reg <= 0; - input_1_axis_tuser_reg <= 0; - input_2_axis_tdata_reg <= 0; - input_2_axis_tvalid_reg <= 0; - input_2_axis_tlast_reg <= 0; - input_2_axis_tuser_reg <= 0; - input_3_axis_tdata_reg <= 0; - input_3_axis_tvalid_reg <= 0; - input_3_axis_tlast_reg <= 0; - input_3_axis_tuser_reg <= 0; + input_0_axis_tvalid_reg <= 1'b0; + input_1_axis_tvalid_reg <= 1'b0; + input_2_axis_tvalid_reg <= 1'b0; + input_3_axis_tvalid_reg <= 1'b0; - output_0_axis_tdata_reg <= 0; - output_0_axis_tvalid_reg <= 0; - output_0_axis_tlast_reg <= 0; - output_0_axis_tuser_reg <= 0; - output_1_axis_tdata_reg <= 0; - output_1_axis_tvalid_reg <= 0; - output_1_axis_tlast_reg <= 0; - output_1_axis_tuser_reg <= 0; - output_2_axis_tdata_reg <= 0; - output_2_axis_tvalid_reg <= 0; - output_2_axis_tlast_reg <= 0; - output_2_axis_tuser_reg <= 0; - output_3_axis_tdata_reg <= 0; - output_3_axis_tvalid_reg <= 0; - output_3_axis_tlast_reg <= 0; - output_3_axis_tuser_reg <= 0; + output_0_axis_tvalid_reg <= 1'b0; + output_1_axis_tvalid_reg <= 1'b0; + output_2_axis_tvalid_reg <= 1'b0; + output_3_axis_tvalid_reg <= 1'b0; end else begin - input_0_axis_tdata_reg <= input_0_axis_tdata; input_0_axis_tvalid_reg <= input_0_axis_tvalid; - input_0_axis_tlast_reg <= input_0_axis_tlast; - input_0_axis_tuser_reg <= input_0_axis_tuser; - - input_1_axis_tdata_reg <= input_1_axis_tdata; input_1_axis_tvalid_reg <= input_1_axis_tvalid; - input_1_axis_tlast_reg <= input_1_axis_tlast; - input_1_axis_tuser_reg <= input_1_axis_tuser; - - input_2_axis_tdata_reg <= input_2_axis_tdata; input_2_axis_tvalid_reg <= input_2_axis_tvalid; - input_2_axis_tlast_reg <= input_2_axis_tlast; - input_2_axis_tuser_reg <= input_2_axis_tuser; - - input_3_axis_tdata_reg <= input_3_axis_tdata; input_3_axis_tvalid_reg <= input_3_axis_tvalid; - input_3_axis_tlast_reg <= input_3_axis_tlast; - input_3_axis_tuser_reg <= input_3_axis_tuser; output_0_select_reg <= output_0_select; output_1_select_reg <= output_1_select; @@ -225,113 +186,141 @@ always @(posedge clk) begin output_3_select_reg <= output_3_select; case (output_0_select_reg) - 2'd0: begin - output_0_axis_tdata_reg <= input_0_axis_tdata_reg; - output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; - output_0_axis_tlast_reg <= input_0_axis_tlast_reg; - output_0_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_0_axis_tdata_reg <= input_1_axis_tdata_reg; - output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; - output_0_axis_tlast_reg <= input_1_axis_tlast_reg; - output_0_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_0_axis_tdata_reg <= input_2_axis_tdata_reg; - output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; - output_0_axis_tlast_reg <= input_2_axis_tlast_reg; - output_0_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_0_axis_tdata_reg <= input_3_axis_tdata_reg; - output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; - output_0_axis_tlast_reg <= input_3_axis_tlast_reg; - output_0_axis_tuser_reg <= input_3_axis_tuser_reg; - end + 2'd0: output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 2'd1: output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 2'd2: output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 2'd3: output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; endcase case (output_1_select_reg) - 2'd0: begin - output_1_axis_tdata_reg <= input_0_axis_tdata_reg; - output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; - output_1_axis_tlast_reg <= input_0_axis_tlast_reg; - output_1_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_1_axis_tdata_reg <= input_1_axis_tdata_reg; - output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; - output_1_axis_tlast_reg <= input_1_axis_tlast_reg; - output_1_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_1_axis_tdata_reg <= input_2_axis_tdata_reg; - output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; - output_1_axis_tlast_reg <= input_2_axis_tlast_reg; - output_1_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_1_axis_tdata_reg <= input_3_axis_tdata_reg; - output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; - output_1_axis_tlast_reg <= input_3_axis_tlast_reg; - output_1_axis_tuser_reg <= input_3_axis_tuser_reg; - end + 2'd0: output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 2'd1: output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 2'd2: output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 2'd3: output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; endcase case (output_2_select_reg) - 2'd0: begin - output_2_axis_tdata_reg <= input_0_axis_tdata_reg; - output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; - output_2_axis_tlast_reg <= input_0_axis_tlast_reg; - output_2_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_2_axis_tdata_reg <= input_1_axis_tdata_reg; - output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; - output_2_axis_tlast_reg <= input_1_axis_tlast_reg; - output_2_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_2_axis_tdata_reg <= input_2_axis_tdata_reg; - output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; - output_2_axis_tlast_reg <= input_2_axis_tlast_reg; - output_2_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_2_axis_tdata_reg <= input_3_axis_tdata_reg; - output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; - output_2_axis_tlast_reg <= input_3_axis_tlast_reg; - output_2_axis_tuser_reg <= input_3_axis_tuser_reg; - end + 2'd0: output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 2'd1: output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 2'd2: output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 2'd3: output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; endcase case (output_3_select_reg) - 2'd0: begin - output_3_axis_tdata_reg <= input_0_axis_tdata_reg; - output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; - output_3_axis_tlast_reg <= input_0_axis_tlast_reg; - output_3_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_3_axis_tdata_reg <= input_1_axis_tdata_reg; - output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; - output_3_axis_tlast_reg <= input_1_axis_tlast_reg; - output_3_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_3_axis_tdata_reg <= input_2_axis_tdata_reg; - output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; - output_3_axis_tlast_reg <= input_2_axis_tlast_reg; - output_3_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_3_axis_tdata_reg <= input_3_axis_tdata_reg; - output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; - output_3_axis_tlast_reg <= input_3_axis_tlast_reg; - output_3_axis_tuser_reg <= input_3_axis_tuser_reg; - end + 2'd0: output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 2'd1: output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 2'd2: output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 2'd3: output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; endcase end + + input_0_axis_tdata_reg <= input_0_axis_tdata; + input_0_axis_tlast_reg <= input_0_axis_tlast; + input_0_axis_tuser_reg <= input_0_axis_tuser; + + input_1_axis_tdata_reg <= input_1_axis_tdata; + input_1_axis_tlast_reg <= input_1_axis_tlast; + input_1_axis_tuser_reg <= input_1_axis_tuser; + + input_2_axis_tdata_reg <= input_2_axis_tdata; + input_2_axis_tlast_reg <= input_2_axis_tlast; + input_2_axis_tuser_reg <= input_2_axis_tuser; + + input_3_axis_tdata_reg <= input_3_axis_tdata; + input_3_axis_tlast_reg <= input_3_axis_tlast; + input_3_axis_tuser_reg <= input_3_axis_tuser; + + case (output_0_select_reg) + 2'd0: begin + output_0_axis_tdata_reg <= input_0_axis_tdata_reg; + output_0_axis_tlast_reg <= input_0_axis_tlast_reg; + output_0_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 2'd1: begin + output_0_axis_tdata_reg <= input_1_axis_tdata_reg; + output_0_axis_tlast_reg <= input_1_axis_tlast_reg; + output_0_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 2'd2: begin + output_0_axis_tdata_reg <= input_2_axis_tdata_reg; + output_0_axis_tlast_reg <= input_2_axis_tlast_reg; + output_0_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 2'd3: begin + output_0_axis_tdata_reg <= input_3_axis_tdata_reg; + output_0_axis_tlast_reg <= input_3_axis_tlast_reg; + output_0_axis_tuser_reg <= input_3_axis_tuser_reg; + end + endcase + + case (output_1_select_reg) + 2'd0: begin + output_1_axis_tdata_reg <= input_0_axis_tdata_reg; + output_1_axis_tlast_reg <= input_0_axis_tlast_reg; + output_1_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 2'd1: begin + output_1_axis_tdata_reg <= input_1_axis_tdata_reg; + output_1_axis_tlast_reg <= input_1_axis_tlast_reg; + output_1_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 2'd2: begin + output_1_axis_tdata_reg <= input_2_axis_tdata_reg; + output_1_axis_tlast_reg <= input_2_axis_tlast_reg; + output_1_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 2'd3: begin + output_1_axis_tdata_reg <= input_3_axis_tdata_reg; + output_1_axis_tlast_reg <= input_3_axis_tlast_reg; + output_1_axis_tuser_reg <= input_3_axis_tuser_reg; + end + endcase + + case (output_2_select_reg) + 2'd0: begin + output_2_axis_tdata_reg <= input_0_axis_tdata_reg; + output_2_axis_tlast_reg <= input_0_axis_tlast_reg; + output_2_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 2'd1: begin + output_2_axis_tdata_reg <= input_1_axis_tdata_reg; + output_2_axis_tlast_reg <= input_1_axis_tlast_reg; + output_2_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 2'd2: begin + output_2_axis_tdata_reg <= input_2_axis_tdata_reg; + output_2_axis_tlast_reg <= input_2_axis_tlast_reg; + output_2_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 2'd3: begin + output_2_axis_tdata_reg <= input_3_axis_tdata_reg; + output_2_axis_tlast_reg <= input_3_axis_tlast_reg; + output_2_axis_tuser_reg <= input_3_axis_tuser_reg; + end + endcase + + case (output_3_select_reg) + 2'd0: begin + output_3_axis_tdata_reg <= input_0_axis_tdata_reg; + output_3_axis_tlast_reg <= input_0_axis_tlast_reg; + output_3_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 2'd1: begin + output_3_axis_tdata_reg <= input_1_axis_tdata_reg; + output_3_axis_tlast_reg <= input_1_axis_tlast_reg; + output_3_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 2'd2: begin + output_3_axis_tdata_reg <= input_2_axis_tdata_reg; + output_3_axis_tlast_reg <= input_2_axis_tlast_reg; + output_3_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 2'd3: begin + output_3_axis_tdata_reg <= input_3_axis_tdata_reg; + output_3_axis_tlast_reg <= input_3_axis_tlast_reg; + output_3_axis_tuser_reg <= input_3_axis_tuser_reg; + end + endcase end endmodule diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index bb871037b..bb27fc867 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -106,23 +106,23 @@ module {{name}} # {%- endfor %} ); {% for p in ports %} -reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep_reg = 0; -reg input_{{p}}_axis_tvalid_reg = 0; -reg input_{{p}}_axis_tlast_reg = 0; -reg input_{{p}}_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_{{p}}_axis_tvalid_reg = 1'b0; +reg input_{{p}}_axis_tlast_reg = 1'b0; +reg input_{{p}}_axis_tuser_reg = 1'b0; {% endfor %} {%- for p in ports %} -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = 0; -reg output_{{p}}_axis_tvalid_reg = 0; -reg output_{{p}}_axis_tlast_reg = 0; -reg output_{{p}}_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_{{p}}_axis_tvalid_reg = 1'b0; +reg output_{{p}}_axis_tlast_reg = 1'b0; +reg output_{{p}}_axis_tuser_reg = 1'b0; {% endfor %} {%- for p in ports %} -reg [{{w-1}}:0] output_{{p}}_select_reg = 0; +reg [{{w-1}}:0] output_{{p}}_select_reg = {{w}}'d0; {%- endfor %} {% for p in ports %} assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; @@ -135,48 +135,50 @@ assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; always @(posedge clk) begin if (rst) begin {%- for p in ports %} - output_{{p}}_select_reg <= 0; + output_{{p}}_select_reg <= {{w}}'d0; {%- endfor %} {% for p in ports %} - input_{{p}}_axis_tdata_reg <= 0; - input_{{p}}_axis_tkeep_reg <= 0; - input_{{p}}_axis_tvalid_reg <= 0; - input_{{p}}_axis_tlast_reg <= 0; - input_{{p}}_axis_tuser_reg <= 0; + input_{{p}}_axis_tvalid_reg <= 1'b0; {%- endfor %} {% for p in ports %} - output_{{p}}_axis_tdata_reg <= 0; - output_{{p}}_axis_tkeep_reg <= 0; - output_{{p}}_axis_tvalid_reg <= 0; - output_{{p}}_axis_tlast_reg <= 0; - output_{{p}}_axis_tuser_reg <= 0; + output_{{p}}_axis_tvalid_reg <= 1'b0; {%- endfor %} end else begin {%- for p in ports %} - input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; - input_{{p}}_axis_tkeep_reg <= input_{{p}}_axis_tkeep; input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; - input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; - input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; -{% endfor %} -{%- for p in ports %} +{%- endfor %} +{% for p in ports %} output_{{p}}_select_reg <= output_{{p}}_select; {%- endfor %} {%- for p in ports %} case (output_{{p}}_select_reg) {%- for q in ports %} - {{w}}'d{{q}}: begin - output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; - output_{{p}}_axis_tkeep_reg <= input_{{q}}_axis_tkeep_reg; - output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; - output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; - output_{{p}}_axis_tuser_reg <= input_{{q}}_axis_tuser_reg; - end + {{w}}'d{{q}}: output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; {%- endfor %} endcase {%- endfor %} end +{%- for p in ports %} + + input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; + input_{{p}}_axis_tkeep_reg <= input_{{p}}_axis_tkeep; + input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; + input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; +{%- endfor %} +{%- for p in ports %} + + case (output_{{p}}_select_reg) +{%- for q in ports %} + {{w}}'d{{q}}: begin + output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; + output_{{p}}_axis_tkeep_reg <= input_{{q}}_axis_tkeep_reg; + output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; + output_{{p}}_axis_tuser_reg <= input_{{q}}_axis_tuser_reg; + end +{%- endfor %} + endcase +{%- endfor %} end endmodule diff --git a/rtl/axis_crosspoint_64_4x4.v b/rtl/axis_crosspoint_64_4x4.v index 4e7688a36..a241c6993 100644 --- a/rtl/axis_crosspoint_64_4x4.v +++ b/rtl/axis_crosspoint_64_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -101,58 +101,58 @@ module axis_crosspoint_64_4x4 # input wire [1:0] output_3_select ); -reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep_reg = 0; -reg input_0_axis_tvalid_reg = 0; -reg input_0_axis_tlast_reg = 0; -reg input_0_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_0_axis_tvalid_reg = 1'b0; +reg input_0_axis_tlast_reg = 1'b0; +reg input_0_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep_reg = 0; -reg input_1_axis_tvalid_reg = 0; -reg input_1_axis_tlast_reg = 0; -reg input_1_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_1_axis_tvalid_reg = 1'b0; +reg input_1_axis_tlast_reg = 1'b0; +reg input_1_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep_reg = 0; -reg input_2_axis_tvalid_reg = 0; -reg input_2_axis_tlast_reg = 0; -reg input_2_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_2_axis_tvalid_reg = 1'b0; +reg input_2_axis_tlast_reg = 1'b0; +reg input_2_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep_reg = 0; -reg input_3_axis_tvalid_reg = 0; -reg input_3_axis_tlast_reg = 0; -reg input_3_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_3_axis_tvalid_reg = 1'b0; +reg input_3_axis_tlast_reg = 1'b0; +reg input_3_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = 0; -reg output_0_axis_tvalid_reg = 0; -reg output_0_axis_tlast_reg = 0; -reg output_0_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_0_axis_tvalid_reg = 1'b0; +reg output_0_axis_tlast_reg = 1'b0; +reg output_0_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = 0; -reg output_1_axis_tvalid_reg = 0; -reg output_1_axis_tlast_reg = 0; -reg output_1_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_1_axis_tvalid_reg = 1'b0; +reg output_1_axis_tlast_reg = 1'b0; +reg output_1_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = 0; -reg output_2_axis_tvalid_reg = 0; -reg output_2_axis_tlast_reg = 0; -reg output_2_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_2_axis_tvalid_reg = 1'b0; +reg output_2_axis_tlast_reg = 1'b0; +reg output_2_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = 0; -reg output_3_axis_tvalid_reg = 0; -reg output_3_axis_tlast_reg = 0; -reg output_3_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_3_axis_tvalid_reg = 1'b0; +reg output_3_axis_tlast_reg = 1'b0; +reg output_3_axis_tuser_reg = 1'b0; -reg [1:0] output_0_select_reg = 0; -reg [1:0] output_1_select_reg = 0; -reg [1:0] output_2_select_reg = 0; -reg [1:0] output_3_select_reg = 0; +reg [1:0] output_0_select_reg = 2'd0; +reg [1:0] output_1_select_reg = 2'd0; +reg [1:0] output_2_select_reg = 2'd0; +reg [1:0] output_3_select_reg = 2'd0; assign output_0_axis_tdata = output_0_axis_tdata_reg; assign output_0_axis_tkeep = output_0_axis_tkeep_reg; @@ -181,76 +181,25 @@ assign output_3_axis_tuser = output_3_axis_tuser_reg; always @(posedge clk) begin if (rst) begin - output_0_select_reg <= 0; - output_1_select_reg <= 0; - output_2_select_reg <= 0; - output_3_select_reg <= 0; + output_0_select_reg <= 2'd0; + output_1_select_reg <= 2'd0; + output_2_select_reg <= 2'd0; + output_3_select_reg <= 2'd0; - input_0_axis_tdata_reg <= 0; - input_0_axis_tkeep_reg <= 0; - input_0_axis_tvalid_reg <= 0; - input_0_axis_tlast_reg <= 0; - input_0_axis_tuser_reg <= 0; - input_1_axis_tdata_reg <= 0; - input_1_axis_tkeep_reg <= 0; - input_1_axis_tvalid_reg <= 0; - input_1_axis_tlast_reg <= 0; - input_1_axis_tuser_reg <= 0; - input_2_axis_tdata_reg <= 0; - input_2_axis_tkeep_reg <= 0; - input_2_axis_tvalid_reg <= 0; - input_2_axis_tlast_reg <= 0; - input_2_axis_tuser_reg <= 0; - input_3_axis_tdata_reg <= 0; - input_3_axis_tkeep_reg <= 0; - input_3_axis_tvalid_reg <= 0; - input_3_axis_tlast_reg <= 0; - input_3_axis_tuser_reg <= 0; + input_0_axis_tvalid_reg <= 1'b0; + input_1_axis_tvalid_reg <= 1'b0; + input_2_axis_tvalid_reg <= 1'b0; + input_3_axis_tvalid_reg <= 1'b0; - output_0_axis_tdata_reg <= 0; - output_0_axis_tkeep_reg <= 0; - output_0_axis_tvalid_reg <= 0; - output_0_axis_tlast_reg <= 0; - output_0_axis_tuser_reg <= 0; - output_1_axis_tdata_reg <= 0; - output_1_axis_tkeep_reg <= 0; - output_1_axis_tvalid_reg <= 0; - output_1_axis_tlast_reg <= 0; - output_1_axis_tuser_reg <= 0; - output_2_axis_tdata_reg <= 0; - output_2_axis_tkeep_reg <= 0; - output_2_axis_tvalid_reg <= 0; - output_2_axis_tlast_reg <= 0; - output_2_axis_tuser_reg <= 0; - output_3_axis_tdata_reg <= 0; - output_3_axis_tkeep_reg <= 0; - output_3_axis_tvalid_reg <= 0; - output_3_axis_tlast_reg <= 0; - output_3_axis_tuser_reg <= 0; + output_0_axis_tvalid_reg <= 1'b0; + output_1_axis_tvalid_reg <= 1'b0; + output_2_axis_tvalid_reg <= 1'b0; + output_3_axis_tvalid_reg <= 1'b0; end else begin - input_0_axis_tdata_reg <= input_0_axis_tdata; - input_0_axis_tkeep_reg <= input_0_axis_tkeep; input_0_axis_tvalid_reg <= input_0_axis_tvalid; - input_0_axis_tlast_reg <= input_0_axis_tlast; - input_0_axis_tuser_reg <= input_0_axis_tuser; - - input_1_axis_tdata_reg <= input_1_axis_tdata; - input_1_axis_tkeep_reg <= input_1_axis_tkeep; input_1_axis_tvalid_reg <= input_1_axis_tvalid; - input_1_axis_tlast_reg <= input_1_axis_tlast; - input_1_axis_tuser_reg <= input_1_axis_tuser; - - input_2_axis_tdata_reg <= input_2_axis_tdata; - input_2_axis_tkeep_reg <= input_2_axis_tkeep; input_2_axis_tvalid_reg <= input_2_axis_tvalid; - input_2_axis_tlast_reg <= input_2_axis_tlast; - input_2_axis_tuser_reg <= input_2_axis_tuser; - - input_3_axis_tdata_reg <= input_3_axis_tdata; - input_3_axis_tkeep_reg <= input_3_axis_tkeep; input_3_axis_tvalid_reg <= input_3_axis_tvalid; - input_3_axis_tlast_reg <= input_3_axis_tlast; - input_3_axis_tuser_reg <= input_3_axis_tuser; output_0_select_reg <= output_0_select; output_1_select_reg <= output_1_select; @@ -258,129 +207,161 @@ always @(posedge clk) begin output_3_select_reg <= output_3_select; case (output_0_select_reg) - 2'd0: begin - output_0_axis_tdata_reg <= input_0_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; - output_0_axis_tlast_reg <= input_0_axis_tlast_reg; - output_0_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_0_axis_tdata_reg <= input_1_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; - output_0_axis_tlast_reg <= input_1_axis_tlast_reg; - output_0_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_0_axis_tdata_reg <= input_2_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; - output_0_axis_tlast_reg <= input_2_axis_tlast_reg; - output_0_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_0_axis_tdata_reg <= input_3_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; - output_0_axis_tlast_reg <= input_3_axis_tlast_reg; - output_0_axis_tuser_reg <= input_3_axis_tuser_reg; - end + 2'd0: output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 2'd1: output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 2'd2: output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 2'd3: output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; endcase case (output_1_select_reg) - 2'd0: begin - output_1_axis_tdata_reg <= input_0_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; - output_1_axis_tlast_reg <= input_0_axis_tlast_reg; - output_1_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_1_axis_tdata_reg <= input_1_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; - output_1_axis_tlast_reg <= input_1_axis_tlast_reg; - output_1_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_1_axis_tdata_reg <= input_2_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; - output_1_axis_tlast_reg <= input_2_axis_tlast_reg; - output_1_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_1_axis_tdata_reg <= input_3_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; - output_1_axis_tlast_reg <= input_3_axis_tlast_reg; - output_1_axis_tuser_reg <= input_3_axis_tuser_reg; - end + 2'd0: output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 2'd1: output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 2'd2: output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 2'd3: output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; endcase case (output_2_select_reg) - 2'd0: begin - output_2_axis_tdata_reg <= input_0_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; - output_2_axis_tlast_reg <= input_0_axis_tlast_reg; - output_2_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_2_axis_tdata_reg <= input_1_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; - output_2_axis_tlast_reg <= input_1_axis_tlast_reg; - output_2_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_2_axis_tdata_reg <= input_2_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; - output_2_axis_tlast_reg <= input_2_axis_tlast_reg; - output_2_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_2_axis_tdata_reg <= input_3_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; - output_2_axis_tlast_reg <= input_3_axis_tlast_reg; - output_2_axis_tuser_reg <= input_3_axis_tuser_reg; - end + 2'd0: output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 2'd1: output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 2'd2: output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 2'd3: output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; endcase case (output_3_select_reg) - 2'd0: begin - output_3_axis_tdata_reg <= input_0_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; - output_3_axis_tlast_reg <= input_0_axis_tlast_reg; - output_3_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_3_axis_tdata_reg <= input_1_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; - output_3_axis_tlast_reg <= input_1_axis_tlast_reg; - output_3_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_3_axis_tdata_reg <= input_2_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; - output_3_axis_tlast_reg <= input_2_axis_tlast_reg; - output_3_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_3_axis_tdata_reg <= input_3_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; - output_3_axis_tlast_reg <= input_3_axis_tlast_reg; - output_3_axis_tuser_reg <= input_3_axis_tuser_reg; - end + 2'd0: output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 2'd1: output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 2'd2: output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 2'd3: output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; endcase end + + input_0_axis_tdata_reg <= input_0_axis_tdata; + input_0_axis_tkeep_reg <= input_0_axis_tkeep; + input_0_axis_tlast_reg <= input_0_axis_tlast; + input_0_axis_tuser_reg <= input_0_axis_tuser; + + input_1_axis_tdata_reg <= input_1_axis_tdata; + input_1_axis_tkeep_reg <= input_1_axis_tkeep; + input_1_axis_tlast_reg <= input_1_axis_tlast; + input_1_axis_tuser_reg <= input_1_axis_tuser; + + input_2_axis_tdata_reg <= input_2_axis_tdata; + input_2_axis_tkeep_reg <= input_2_axis_tkeep; + input_2_axis_tlast_reg <= input_2_axis_tlast; + input_2_axis_tuser_reg <= input_2_axis_tuser; + + input_3_axis_tdata_reg <= input_3_axis_tdata; + input_3_axis_tkeep_reg <= input_3_axis_tkeep; + input_3_axis_tlast_reg <= input_3_axis_tlast; + input_3_axis_tuser_reg <= input_3_axis_tuser; + + case (output_0_select_reg) + 2'd0: begin + output_0_axis_tdata_reg <= input_0_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_0_axis_tlast_reg; + output_0_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 2'd1: begin + output_0_axis_tdata_reg <= input_1_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_1_axis_tlast_reg; + output_0_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 2'd2: begin + output_0_axis_tdata_reg <= input_2_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_2_axis_tlast_reg; + output_0_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 2'd3: begin + output_0_axis_tdata_reg <= input_3_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_3_axis_tlast_reg; + output_0_axis_tuser_reg <= input_3_axis_tuser_reg; + end + endcase + + case (output_1_select_reg) + 2'd0: begin + output_1_axis_tdata_reg <= input_0_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_0_axis_tlast_reg; + output_1_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 2'd1: begin + output_1_axis_tdata_reg <= input_1_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_1_axis_tlast_reg; + output_1_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 2'd2: begin + output_1_axis_tdata_reg <= input_2_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_2_axis_tlast_reg; + output_1_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 2'd3: begin + output_1_axis_tdata_reg <= input_3_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_3_axis_tlast_reg; + output_1_axis_tuser_reg <= input_3_axis_tuser_reg; + end + endcase + + case (output_2_select_reg) + 2'd0: begin + output_2_axis_tdata_reg <= input_0_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_0_axis_tlast_reg; + output_2_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 2'd1: begin + output_2_axis_tdata_reg <= input_1_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_1_axis_tlast_reg; + output_2_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 2'd2: begin + output_2_axis_tdata_reg <= input_2_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_2_axis_tlast_reg; + output_2_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 2'd3: begin + output_2_axis_tdata_reg <= input_3_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_3_axis_tlast_reg; + output_2_axis_tuser_reg <= input_3_axis_tuser_reg; + end + endcase + + case (output_3_select_reg) + 2'd0: begin + output_3_axis_tdata_reg <= input_0_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_0_axis_tlast_reg; + output_3_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 2'd1: begin + output_3_axis_tdata_reg <= input_1_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_1_axis_tlast_reg; + output_3_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 2'd2: begin + output_3_axis_tdata_reg <= input_2_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_2_axis_tlast_reg; + output_3_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 2'd3: begin + output_3_axis_tdata_reg <= input_3_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_3_axis_tlast_reg; + output_3_axis_tuser_reg <= input_3_axis_tuser_reg; + end + endcase end endmodule From 0d22a35bd855a7f08b34a3f1c24ebb143289d91d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 8 Nov 2015 23:05:38 -0800 Subject: [PATCH 261/617] Update output registers, remove extraneous resets, fix constant widths --- rtl/axis_adapter.v | 236 +++++++++++++------------ rtl/axis_demux.py | 148 +++++++++------- rtl/axis_demux_4.v | 166 ++++++++++-------- rtl/axis_demux_64.py | 161 +++++++++-------- rtl/axis_demux_64_4.v | 179 ++++++++++--------- rtl/axis_frame_join.py | 178 ++++++++++--------- rtl/axis_frame_join_4.v | 202 +++++++++++---------- rtl/axis_frame_length_adjust.v | 309 +++++++++++++++++---------------- rtl/axis_mux.py | 132 ++++++++------ rtl/axis_mux_4.v | 150 +++++++++------- rtl/axis_mux_64.py | 145 +++++++++------- rtl/axis_mux_64_4.v | 163 +++++++++-------- rtl/axis_rate_limit.v | 133 ++++++++------ rtl/axis_rate_limit_64.v | 146 +++++++++------- rtl/axis_stat_counter.v | 166 ++++++++++-------- rtl/axis_tap.v | 140 ++++++++------- rtl/axis_tap_64.v | 157 +++++++++-------- 17 files changed, 1594 insertions(+), 1317 deletions(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index 1eed1403b..c5f4358c5 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -101,25 +101,26 @@ localparam [2:0] reg [2:0] state_reg = STATE_IDLE, state_next; -reg [7:0] cycle_count_reg = 0, cycle_count_next; +reg [7:0] cycle_count_reg = 8'd0, cycle_count_next; reg last_cycle; -reg [DATA_WIDTH-1:0] temp_tdata_reg = 0, temp_tdata_next; -reg [KEEP_WIDTH-1:0] temp_tkeep_reg = 0, temp_tkeep_next; -reg temp_tlast_reg = 0, temp_tlast_next; -reg temp_tuser_reg = 0, temp_tuser_next; +reg [DATA_WIDTH-1:0] temp_tdata_reg = {DATA_WIDTH{1'b0}}, temp_tdata_next; +reg [KEEP_WIDTH-1:0] temp_tkeep_reg = {KEEP_WIDTH{1'b0}}, temp_tkeep_next; +reg temp_tlast_reg = 1'b0, temp_tlast_next; +reg temp_tuser_reg = 1'b0, temp_tuser_next; // internal datapath reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_int; reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; + assign input_axis_tready = input_axis_tready_reg; always @* begin @@ -132,13 +133,13 @@ always @* begin temp_tlast_next = temp_tlast_reg; temp_tuser_next = temp_tuser_reg; - output_axis_tdata_int = 0; - output_axis_tkeep_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = {OUTPUT_DATA_WIDTH{1'b0}}; + output_axis_tkeep_int = {OUTPUT_KEEP_WIDTH{1'b0}}; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; case (state_reg) STATE_IDLE: begin @@ -161,7 +162,7 @@ always @* begin // output bus is wider // accept new data - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store it in data register @@ -173,15 +174,15 @@ always @* begin temp_tuser_next = input_axis_tuser; // first input cycle complete - cycle_count_next = 1; + cycle_count_next = 8'd1; if (input_axis_tlast) begin // got last signal on first cycle, so output it - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_TRANSFER_OUT; end else begin // otherwise, transfer in the rest of the words - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_TRANSFER_IN; end end else begin @@ -191,24 +192,24 @@ always @* begin // output bus is narrower // accept new data - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store it in data register - cycle_count_next = 0; + cycle_count_next = 8'd0; // is this the last cycle? if (CYCLE_COUNT == 1) begin // last cycle by counter value - last_cycle = 1; + last_cycle = 1'b1; end else if (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}) begin // last cycle by tkeep fall in current cycle - last_cycle = 1; + last_cycle = 1'b1; end else if (input_axis_tkeep[(CYCLE_KEEP_WIDTH*2)-1:CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin // last cycle by tkeep fall at end of current cycle - last_cycle = 1; + last_cycle = 1'b1; end else begin - last_cycle = 0; + last_cycle = 1'b0; end // pass complete input word, zero-extended to temp register @@ -220,18 +221,18 @@ always @* begin // short-circuit and get first word out the door output_axis_tdata_int = input_axis_tdata[CYCLE_DATA_WIDTH-1:0]; output_axis_tkeep_int = input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0]; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; output_axis_tlast_int = input_axis_tlast & last_cycle; output_axis_tuser_int = input_axis_tuser & last_cycle; - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin // if output register is ready for first word, then move on to the next one - cycle_count_next = 1; + cycle_count_next = 8'd1; end - if (!last_cycle || !output_axis_tready_int) begin + if (!last_cycle || !output_axis_tready_int_reg) begin // continue outputting words - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_TRANSFER_OUT; end else begin state_next = STATE_IDLE; @@ -246,7 +247,7 @@ always @* begin // only used when output is wider // accept new data - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store in data register @@ -265,7 +266,7 @@ always @* begin state_next = STATE_TRANSFER_OUT; end else begin // more words to read - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_TRANSFER_IN; end end else begin @@ -279,16 +280,16 @@ always @* begin // output bus is wider // do not accept new data - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; // single-cycle output of entire stored word (output wider) output_axis_tdata_int = temp_tdata_reg; output_axis_tkeep_int = temp_tkeep_reg; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; output_axis_tlast_int = temp_tlast_reg; output_axis_tuser_int = temp_tuser_reg; - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin // word transfer out if (input_axis_tready & input_axis_tvalid) begin @@ -301,19 +302,19 @@ always @* begin temp_tuser_next = input_axis_tuser; // first input cycle complete - cycle_count_next = 1; + cycle_count_next = 8'd1; if (input_axis_tlast) begin // got last signal on first cycle, so output it - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_TRANSFER_OUT; end else begin // otherwise, transfer in the rest of the words - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_TRANSFER_IN; end end else begin - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else begin @@ -323,30 +324,30 @@ always @* begin // output bus is narrower // do not accept new data - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; // is this the last cycle? if (cycle_count_reg == CYCLE_COUNT-1) begin // last cycle by counter value - last_cycle = 1; + last_cycle = 1'b1; end else if (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}}) begin // last cycle by tkeep fall in current cycle - last_cycle = 1; + last_cycle = 1'b1; end else if (temp_tkeep_reg[(cycle_count_reg+1)*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin // last cycle by tkeep fall at end of current cycle - last_cycle = 1; + last_cycle = 1'b1; end else begin - last_cycle = 0; + last_cycle = 1'b0; end // output current part of stored word (output narrower) output_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH]; output_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH]; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; output_axis_tlast_int = temp_tlast_reg & last_cycle; output_axis_tuser_int = temp_tuser_reg & last_cycle; - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin // word transfer out cycle_count_next = cycle_count_reg + 1; @@ -354,7 +355,7 @@ always @* begin if (last_cycle) begin // terminated by counter or tlast signal - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_IDLE; end else begin // more words to write @@ -371,38 +372,39 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - cycle_count_reg <= 0; - temp_tdata_reg <= 0; - temp_tkeep_reg <= 0; - temp_tlast_reg <= 0; - temp_tuser_reg <= 0; - input_axis_tready_reg <= 0; + cycle_count_reg <= 8'd0; + input_axis_tready_reg <= 1'b0; end else begin state_reg <= state_next; input_axis_tready_reg <= input_axis_tready_next; - temp_tdata_reg <= temp_tdata_next; - temp_tkeep_reg <= temp_tkeep_next; - temp_tlast_reg <= temp_tlast_next; - temp_tuser_reg <= temp_tuser_next; - cycle_count_reg <= cycle_count_next; end + + temp_tdata_reg <= temp_tdata_next; + temp_tkeep_reg <= temp_tkeep_next; + temp_tlast_reg <= temp_tlast_next; + temp_tuser_reg <= temp_tuser_next; end // output datapath logic -reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}}; +reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}}; +reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -410,56 +412,66 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index 8cd57b75d..28bb7ed2a 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -103,15 +103,15 @@ module {{name}} # input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -136,7 +136,7 @@ always @* begin select_next = select_reg; frame_next = frame_reg; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; if (frame_reg) begin if (input_axis_tvalid & input_axis_tready) begin @@ -145,7 +145,7 @@ always @* begin end end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; end @@ -159,9 +159,9 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_axis_tready_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; + input_axis_tready_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -170,77 +170,95 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; {%- for p in ports %} -reg output_{{p}}_axis_tvalid_reg = 0; +reg output_{{p}}_axis_tvalid_reg = 1'b0, output_{{p}}_axis_tvalid_next; {%- endfor %} -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; {% for p in ports %} assign output_{{p}}_axis_tdata = output_axis_tdata_reg; assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; assign output_{{p}}_axis_tlast = output_axis_tlast_reg; assign output_{{p}}_axis_tuser = output_axis_tuser_reg; {% endfor %} -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & (~current_output_tvalid | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source +{%- for p in ports %} + output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_reg; +{%- endfor %} + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output +{%- for p in ports %} + output_{{p}}_axis_tvalid_next = output_axis_tvalid_int & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready +{%- for p in ports %} + output_{{p}}_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; {%- for p in ports %} - output_{{p}}_axis_tvalid_reg <= 0; + output_{{p}}_axis_tvalid_reg <= 1'b0; {%- endfor %} - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; +{%- for p in ports %} + output_{{p}}_axis_tvalid_reg <= output_{{p}}_axis_tvalid_next; +{%- endfor %} + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_axis_tvalid_reg <= output_axis_tvalid_int; -{%- endfor %} - endcase - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_axis_tvalid_reg <= temp_axis_tvalid_reg; -{%- endfor %} - endcase - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v index 493f5585f..6b853aebf 100644 --- a/rtl/axis_demux_4.v +++ b/rtl/axis_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -80,15 +80,15 @@ module axis_demux_4 # input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -123,7 +123,7 @@ always @* begin select_next = select_reg; frame_next = frame_reg; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; if (frame_reg) begin if (input_axis_tvalid & input_axis_tready) begin @@ -132,7 +132,7 @@ always @* begin end end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; end @@ -146,9 +146,9 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_axis_tready_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_axis_tready_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -157,18 +157,23 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg output_0_axis_tvalid_reg = 0; -reg output_1_axis_tvalid_reg = 0; -reg output_2_axis_tvalid_reg = 0; -reg output_3_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_0_axis_tvalid_reg = 1'b0, output_0_axis_tvalid_next; +reg output_1_axis_tvalid_reg = 1'b0, output_1_axis_tvalid_next; +reg output_2_axis_tvalid_reg = 1'b0, output_2_axis_tvalid_next; +reg output_3_axis_tvalid_reg = 1'b0, output_3_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_0_axis_tdata = output_axis_tdata_reg; assign output_0_axis_tvalid = output_0_axis_tvalid_reg; @@ -190,63 +195,78 @@ assign output_3_axis_tvalid = output_3_axis_tvalid_reg; assign output_3_axis_tlast = output_axis_tlast_reg; assign output_3_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & (~current_output_tvalid | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_0_axis_tvalid_next = output_0_axis_tvalid_reg; + output_1_axis_tvalid_next = output_1_axis_tvalid_reg; + output_2_axis_tvalid_next = output_2_axis_tvalid_reg; + output_3_axis_tvalid_next = output_3_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_0_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd0); + output_1_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd1); + output_2_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd2); + output_3_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd3); + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_0_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd0); + output_1_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd1); + output_2_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd2); + output_3_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd3); + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_0_axis_tvalid_reg <= 0; - output_1_axis_tvalid_reg <= 0; - output_2_axis_tvalid_reg <= 0; - output_3_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_0_axis_tvalid_reg <= 1'b0; + output_1_axis_tvalid_reg <= 1'b0; + output_2_axis_tvalid_reg <= 1'b0; + output_3_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_0_axis_tvalid_reg <= output_0_axis_tvalid_next; + output_1_axis_tvalid_reg <= output_1_axis_tvalid_next; + output_2_axis_tvalid_reg <= output_2_axis_tvalid_next; + output_3_axis_tvalid_reg <= output_3_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - case (select_reg) - 2'd0: output_0_axis_tvalid_reg <= output_axis_tvalid_int; - 2'd1: output_1_axis_tvalid_reg <= output_axis_tvalid_int; - 2'd2: output_2_axis_tvalid_reg <= output_axis_tvalid_int; - 2'd3: output_3_axis_tvalid_reg <= output_axis_tvalid_int; - endcase - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - case (select_reg) - 2'd0: output_0_axis_tvalid_reg <= temp_axis_tvalid_reg; - 2'd1: output_1_axis_tvalid_reg <= temp_axis_tvalid_reg; - 2'd2: output_2_axis_tvalid_reg <= temp_axis_tvalid_reg; - 2'd3: output_3_axis_tvalid_reg <= temp_axis_tvalid_reg; - endcase - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index 8b3271388..898bb6e60 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -106,16 +106,16 @@ module {{name}} # input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -140,7 +140,7 @@ always @* begin select_next = select_reg; frame_next = frame_reg; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; if (frame_reg) begin if (input_axis_tvalid & input_axis_tready) begin @@ -149,7 +149,7 @@ always @* begin end end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; end @@ -164,9 +164,9 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_axis_tready_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; + input_axis_tready_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -175,19 +175,24 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; {%- for p in ports %} -reg output_{{p}}_axis_tvalid_reg = 0; +reg output_{{p}}_axis_tvalid_reg = 1'b0, output_{{p}}_axis_tvalid_next; {%- endfor %} -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; {% for p in ports %} assign output_{{p}}_axis_tdata = output_axis_tdata_reg; assign output_{{p}}_axis_tkeep = output_axis_tkeep_reg; @@ -195,66 +200,76 @@ assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; assign output_{{p}}_axis_tlast = output_axis_tlast_reg; assign output_{{p}}_axis_tuser = output_axis_tuser_reg; {% endfor %} -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & (~current_output_tvalid | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source +{%- for p in ports %} + output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_reg; +{%- endfor %} + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output +{%- for p in ports %} + output_{{p}}_axis_tvalid_next = output_axis_tvalid_int & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready +{%- for p in ports %} + output_{{p}}_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; {%- for p in ports %} - output_{{p}}_axis_tvalid_reg <= 0; + output_{{p}}_axis_tvalid_reg <= 1'b0; {%- endfor %} - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; +{%- for p in ports %} + output_{{p}}_axis_tvalid_reg <= output_{{p}}_axis_tvalid_next; +{%- endfor %} + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_axis_tvalid_reg <= output_axis_tvalid_int; -{%- endfor %} - endcase - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_axis_tvalid_reg <= temp_axis_tvalid_reg; -{%- endfor %} - endcase - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_demux_64_4.v b/rtl/axis_demux_64_4.v index e4fb0a441..489ce179e 100644 --- a/rtl/axis_demux_64_4.v +++ b/rtl/axis_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -86,16 +86,16 @@ module axis_demux_64_4 # input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -130,7 +130,7 @@ always @* begin select_next = select_reg; frame_next = frame_reg; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; if (frame_reg) begin if (input_axis_tvalid & input_axis_tready) begin @@ -139,7 +139,7 @@ always @* begin end end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; end @@ -154,9 +154,9 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_axis_tready_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_axis_tready_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -165,20 +165,25 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_0_axis_tvalid_reg = 0; -reg output_1_axis_tvalid_reg = 0; -reg output_2_axis_tvalid_reg = 0; -reg output_3_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_0_axis_tvalid_reg = 1'b0, output_0_axis_tvalid_next; +reg output_1_axis_tvalid_reg = 1'b0, output_1_axis_tvalid_next; +reg output_2_axis_tvalid_reg = 1'b0, output_2_axis_tvalid_next; +reg output_3_axis_tvalid_reg = 1'b0, output_3_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_0_axis_tdata = output_axis_tdata_reg; assign output_0_axis_tkeep = output_axis_tkeep_reg; @@ -204,69 +209,81 @@ assign output_3_axis_tvalid = output_3_axis_tvalid_reg; assign output_3_axis_tlast = output_axis_tlast_reg; assign output_3_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & ~current_output_tvalid) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & (~current_output_tvalid | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_0_axis_tvalid_next = output_0_axis_tvalid_reg; + output_1_axis_tvalid_next = output_1_axis_tvalid_reg; + output_2_axis_tvalid_next = output_2_axis_tvalid_reg; + output_3_axis_tvalid_next = output_3_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_0_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd0); + output_1_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd1); + output_2_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd2); + output_3_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd3); + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_0_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd0); + output_1_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd1); + output_2_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd2); + output_3_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd3); + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_0_axis_tvalid_reg <= 0; - output_1_axis_tvalid_reg <= 0; - output_2_axis_tvalid_reg <= 0; - output_3_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_0_axis_tvalid_reg <= 1'b0; + output_1_axis_tvalid_reg <= 1'b0; + output_2_axis_tvalid_reg <= 1'b0; + output_3_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_0_axis_tvalid_reg <= output_0_axis_tvalid_next; + output_1_axis_tvalid_reg <= output_1_axis_tvalid_next; + output_2_axis_tvalid_reg <= output_2_axis_tvalid_next; + output_3_axis_tvalid_reg <= output_3_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - case (select_reg) - 2'd0: output_0_axis_tvalid_reg <= output_axis_tvalid_int; - 2'd1: output_1_axis_tvalid_reg <= output_axis_tvalid_int; - 2'd2: output_2_axis_tvalid_reg <= output_axis_tvalid_int; - 2'd3: output_3_axis_tvalid_reg <= output_axis_tvalid_int; - endcase - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - case (select_reg) - 2'd0: output_0_axis_tvalid_reg <= temp_axis_tvalid_reg; - 2'd1: output_1_axis_tvalid_reg <= temp_axis_tvalid_reg; - 2'd2: output_2_axis_tvalid_reg <= temp_axis_tvalid_reg; - 2'd3: output_3_axis_tvalid_reg <= temp_axis_tvalid_reg; - endcase - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index 91c23bb95..63f7bd847 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -118,25 +118,25 @@ localparam [1:0] reg [1:0] state_reg = STATE_IDLE, state_next; -reg [2:0] frame_ptr_reg = 0, frame_ptr_next; -reg [{{w-1}}:0] port_sel_reg = 0, port_sel_next; +reg [2:0] frame_ptr_reg = 3'd0, frame_ptr_next; +reg [{{w-1}}:0] port_sel_reg = {{w}}'d0, port_sel_next; -reg busy_reg = 0, busy_next; +reg busy_reg = 1'b0, busy_next; reg [7:0] input_tdata; reg input_tvalid; reg input_tlast; reg input_tuser; -reg output_tuser_reg = 0, output_tuser_next; +reg output_tuser_reg = 1'b0, output_tuser_next; {% for p in ports %} -reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; {%- endfor %} // internal datapath reg [7:0] output_axis_tdata_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -163,31 +163,31 @@ end integer offset, i; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; frame_ptr_next = frame_ptr_reg; port_sel_next = port_sel_reg; {% for p in ports %} - input_{{p}}_axis_tready_next = 0; + input_{{p}}_axis_tready_next = 1'b0; {%- endfor %} - output_axis_tdata_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; output_tuser_next = output_tuser_reg; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; - port_sel_next = 0; - output_tuser_next = 0; + frame_ptr_next = 3'd0; + port_sel_next = {{w}}'d0; + output_tuser_next = 1'b0; if (TAG_ENABLE) begin // next cycle if started will send tag, so do not enable input - input_0_axis_tready_next = 0; + input_0_axis_tready_next = 1'b0; end else begin // next cycle if started will send data, so enable input input_0_axis_tready_next = output_axis_tready_int_early; @@ -197,19 +197,19 @@ always @* begin // input 0 valid; start transferring data if (TAG_ENABLE) begin // tag enabled, so transmit it - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin // output is ready, so short-circuit first tag byte - frame_ptr_next = 1; + frame_ptr_next = 3'd1; output_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; end state_next = STATE_WRITE_TAG; end else begin // tag disabled, so transmit data - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin // output is ready, so short-circuit first data byte output_axis_tdata_int = input_0_axis_tdata; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; end state_next = STATE_TRANSFER; end @@ -219,11 +219,11 @@ always @* begin end STATE_WRITE_TAG: begin // write tag data - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin // output ready, so send tag byte state_next = STATE_WRITE_TAG; frame_ptr_next = frame_ptr_reg + 1; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; offset = 0; if (TAG_ENABLE) begin @@ -252,7 +252,7 @@ always @* begin {%- endfor %} endcase - if (input_tvalid & output_axis_tready_int) begin + if (input_tvalid & output_axis_tready_int_reg) begin // output ready, transfer byte state_next = STATE_TRANSFER; output_axis_tdata_int = input_tdata; @@ -265,12 +265,12 @@ always @* begin output_tuser_next = output_tuser_next | input_tuser; // disable input {%- for p in ports %} - input_{{p}}_axis_tready_next = 0; + input_{{p}}_axis_tready_next = 1'b0; {%- endfor %} - if (port_sel_reg == {{n-1}}) begin + if (port_sel_reg == {{w}}'d{{n-1}}) begin // last port - send tlast and tuser and revert to idle - output_axis_tlast_int = 1; + output_axis_tlast_int = 1'b1; output_axis_tuser_int = output_tuser_next; state_next = STATE_IDLE; end else begin @@ -292,13 +292,13 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - port_sel_reg <= 0; + frame_ptr_reg <= 3'd0; + port_sel_reg <= {{w}}'d0; {%- for p in ports %} - input_{{p}}_axis_tready_reg <= 0; + input_{{p}}_axis_tready_reg <= 1'b0; {%- endfor %} - output_tuser_reg <= 0; - busy_reg <= 0; + output_tuser_reg <= 1'b0; + busy_reg <= 1'b0; end else begin state_reg <= state_next; @@ -316,65 +316,83 @@ always @(posedge clk) begin end // output datapath logic -reg [7:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [7:0] output_axis_tdata_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [7:0] temp_axis_tdata_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index d57acf7cb..82298e3bd 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -95,27 +95,27 @@ localparam [1:0] reg [1:0] state_reg = STATE_IDLE, state_next; -reg [2:0] frame_ptr_reg = 0, frame_ptr_next; -reg [1:0] port_sel_reg = 0, port_sel_next; +reg [2:0] frame_ptr_reg = 3'd0, frame_ptr_next; +reg [1:0] port_sel_reg = 2'd0, port_sel_next; -reg busy_reg = 0, busy_next; +reg busy_reg = 1'b0, busy_next; reg [7:0] input_tdata; reg input_tvalid; reg input_tlast; reg input_tuser; -reg output_tuser_reg = 0, output_tuser_next; +reg output_tuser_reg = 1'b0, output_tuser_next; -reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; +reg input_0_axis_tready_reg = 1'b0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 1'b0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; // internal datapath reg [7:0] output_axis_tdata_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -160,33 +160,33 @@ end integer offset, i; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; frame_ptr_next = frame_ptr_reg; port_sel_next = port_sel_reg; - input_0_axis_tready_next = 0; - input_1_axis_tready_next = 0; - input_2_axis_tready_next = 0; - input_3_axis_tready_next = 0; + input_0_axis_tready_next = 1'b0; + input_1_axis_tready_next = 1'b0; + input_2_axis_tready_next = 1'b0; + input_3_axis_tready_next = 1'b0; - output_axis_tdata_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; output_tuser_next = output_tuser_reg; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; - port_sel_next = 0; - output_tuser_next = 0; + frame_ptr_next = 3'd0; + port_sel_next = 2'd0; + output_tuser_next = 1'b0; if (TAG_ENABLE) begin // next cycle if started will send tag, so do not enable input - input_0_axis_tready_next = 0; + input_0_axis_tready_next = 1'b0; end else begin // next cycle if started will send data, so enable input input_0_axis_tready_next = output_axis_tready_int_early; @@ -196,19 +196,19 @@ always @* begin // input 0 valid; start transferring data if (TAG_ENABLE) begin // tag enabled, so transmit it - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin // output is ready, so short-circuit first tag byte - frame_ptr_next = 1; + frame_ptr_next = 3'd1; output_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; end state_next = STATE_WRITE_TAG; end else begin // tag disabled, so transmit data - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin // output is ready, so short-circuit first data byte output_axis_tdata_int = input_0_axis_tdata; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; end state_next = STATE_TRANSFER; end @@ -218,11 +218,11 @@ always @* begin end STATE_WRITE_TAG: begin // write tag data - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin // output ready, so send tag byte state_next = STATE_WRITE_TAG; frame_ptr_next = frame_ptr_reg + 1; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; offset = 0; if (TAG_ENABLE) begin @@ -252,7 +252,7 @@ always @* begin 2'd3: input_3_axis_tready_next = output_axis_tready_int_early; endcase - if (input_tvalid & output_axis_tready_int) begin + if (input_tvalid & output_axis_tready_int_reg) begin // output ready, transfer byte state_next = STATE_TRANSFER; output_axis_tdata_int = input_tdata; @@ -264,14 +264,14 @@ always @* begin // save tuser - assert tuser out if ANY tuser asserts received output_tuser_next = output_tuser_next | input_tuser; // disable input - input_0_axis_tready_next = 0; - input_1_axis_tready_next = 0; - input_2_axis_tready_next = 0; - input_3_axis_tready_next = 0; + input_0_axis_tready_next = 1'b0; + input_1_axis_tready_next = 1'b0; + input_2_axis_tready_next = 1'b0; + input_3_axis_tready_next = 1'b0; - if (port_sel_reg == 3) begin + if (port_sel_reg == 2'd3) begin // last port - send tlast and tuser and revert to idle - output_axis_tlast_int = 1; + output_axis_tlast_int = 1'b1; output_axis_tuser_int = output_tuser_next; state_next = STATE_IDLE; end else begin @@ -294,14 +294,14 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - port_sel_reg <= 0; - input_0_axis_tready_reg <= 0; - input_1_axis_tready_reg <= 0; - input_2_axis_tready_reg <= 0; - input_3_axis_tready_reg <= 0; - output_tuser_reg <= 0; - busy_reg <= 0; + frame_ptr_reg <= 3'd0; + port_sel_reg <= 2'd0; + input_0_axis_tready_reg <= 1'b0; + input_1_axis_tready_reg <= 1'b0; + input_2_axis_tready_reg <= 1'b0; + input_3_axis_tready_reg <= 1'b0; + output_tuser_reg <= 1'b0; + busy_reg <= 1'b0; end else begin state_reg <= state_next; @@ -321,65 +321,83 @@ always @(posedge clk) begin end // output datapath logic -reg [7:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [7:0] output_axis_tdata_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [7:0] temp_axis_tdata_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_frame_length_adjust.v b/rtl/axis_frame_length_adjust.v index 6c1c2ae68..5b1073a6c 100644 --- a/rtl/axis_frame_length_adjust.v +++ b/rtl/axis_frame_length_adjust.v @@ -98,33 +98,33 @@ reg [2:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_last_word; -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; // frame length counters -reg [15:0] short_counter_reg = 0, short_counter_next = 0; -reg [15:0] long_counter_reg = 0, long_counter_next = 0; +reg [15:0] short_counter_reg = 16'd0, short_counter_next = 16'd0; +reg [15:0] long_counter_reg = 16'd0, long_counter_next = 16'd0; -reg [DATA_WIDTH-1:0] last_word_data_reg = 0; -reg [KEEP_WIDTH-1:0] last_word_keep_reg = 0; +reg [DATA_WIDTH-1:0] last_word_data_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] last_word_keep_reg = {KEEP_WIDTH{1'b0}}; -reg last_cycle_tuser_reg = 0, last_cycle_tuser_next; +reg last_cycle_tuser_reg = 1'b0, last_cycle_tuser_next; -reg status_valid_reg = 0, status_valid_next; -reg status_frame_pad_reg = 0, status_frame_pad_next; -reg status_frame_truncate_reg = 0, status_frame_truncate_next; -reg [15:0] status_frame_length_reg = 0, status_frame_length_next; -reg [15:0] status_frame_original_length_reg = 0, status_frame_original_length_next; +reg status_valid_reg = 1'b0, status_valid_next; +reg status_frame_pad_reg = 1'b0, status_frame_pad_next; +reg status_frame_truncate_reg = 1'b0, status_frame_truncate_next; +reg [15:0] status_frame_length_reg = 16'd0, status_frame_length_next; +reg [15:0] status_frame_original_length_reg = 16'd0, status_frame_original_length_next; // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; assign status_valid = status_valid_reg; @@ -138,20 +138,20 @@ integer i, word_cnt; always @* begin state_next = STATE_IDLE; - store_last_word = 0; + store_last_word = 1'b0; frame_ptr_next = frame_ptr_reg; short_counter_next = short_counter_reg; long_counter_next = long_counter_reg; - output_axis_tdata_int = 0; - output_axis_tkeep_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; last_cycle_tuser_next = last_cycle_tuser_reg; @@ -188,31 +188,31 @@ always @* begin if (short_counter_reg > KEEP_WIDTH) begin short_counter_next = short_counter_reg - KEEP_WIDTH; end else begin - short_counter_next = 0; + short_counter_next = 16'd0; end if (long_counter_reg > KEEP_WIDTH) begin long_counter_next = long_counter_reg - KEEP_WIDTH; end else begin - long_counter_next = 0; + long_counter_next = 16'd0; end if (long_counter_reg <= word_cnt) begin output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-long_counter_reg); if (input_axis_tlast) begin - status_valid_next = 1; - status_frame_pad_next = 0; + status_valid_next = 1'b1; + status_frame_pad_next = 1'b0; status_frame_truncate_next = word_cnt > long_counter_reg; status_frame_length_next = length_max; status_frame_original_length_next = frame_ptr_reg+word_cnt; input_axis_tready_next = output_axis_tready_int_early & status_ready; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; state_next = STATE_IDLE; end else begin - output_axis_tvalid_int = 0; - store_last_word = 1; + output_axis_tvalid_int = 1'b0; + store_last_word = 1'b1; state_next = STATE_TRUNCATE; end end else begin @@ -221,32 +221,32 @@ always @* begin if (short_counter_reg > word_cnt) begin if (short_counter_reg > KEEP_WIDTH) begin frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; last_cycle_tuser_next = input_axis_tuser; state_next = STATE_PAD; end else begin - status_valid_next = 1; - status_frame_pad_next = 1; - status_frame_truncate_next = 0; + status_valid_next = 1'b1; + status_frame_pad_next = 1'b1; + status_frame_truncate_next = 1'b0; status_frame_length_next = length_min; input_axis_tready_next = output_axis_tready_int_early & status_ready; output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_min - frame_ptr_reg)); - frame_ptr_next = 0; + frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; state_next = STATE_IDLE; end end else begin - status_valid_next = 1; - status_frame_pad_next = 0; - status_frame_truncate_next = 0; + status_valid_next = 1'b1; + status_frame_pad_next = 1'b0; + status_frame_truncate_next = 1'b0; status_frame_length_next = frame_ptr_reg+word_cnt; status_frame_original_length_next = frame_ptr_reg+word_cnt; input_axis_tready_next = output_axis_tready_int_early & status_ready; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; state_next = STATE_IDLE; @@ -282,31 +282,31 @@ always @* begin if (short_counter_reg > KEEP_WIDTH) begin short_counter_next = short_counter_reg - KEEP_WIDTH; end else begin - short_counter_next = 0; + short_counter_next = 16'd0; end if (long_counter_reg > KEEP_WIDTH) begin long_counter_next = long_counter_reg - KEEP_WIDTH; end else begin - long_counter_next = 0; + long_counter_next = 16'd0; end if (long_counter_reg <= word_cnt) begin output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-long_counter_reg); if (input_axis_tlast) begin - status_valid_next = 1; - status_frame_pad_next = 0; + status_valid_next = 1'b1; + status_frame_pad_next = 1'b0; status_frame_truncate_next = word_cnt > long_counter_reg; status_frame_length_next = length_max; status_frame_original_length_next = frame_ptr_reg+word_cnt; input_axis_tready_next = output_axis_tready_int_early & status_ready; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; state_next = STATE_IDLE; end else begin - output_axis_tvalid_int = 0; - store_last_word = 1; + output_axis_tvalid_int = 1'b0; + store_last_word = 1'b1; state_next = STATE_TRUNCATE; end end else begin @@ -315,32 +315,32 @@ always @* begin if (short_counter_reg > word_cnt) begin if (short_counter_reg > KEEP_WIDTH) begin frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; last_cycle_tuser_next = input_axis_tuser; state_next = STATE_PAD; end else begin - status_valid_next = 1; - status_frame_pad_next = 1; - status_frame_truncate_next = 0; + status_valid_next = 1'b1; + status_frame_pad_next = 1'b1; + status_frame_truncate_next = 1'b0; status_frame_length_next = length_min; input_axis_tready_next = output_axis_tready_int_early & status_ready; output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-short_counter_reg); - frame_ptr_next = 0; + frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; state_next = STATE_IDLE; end end else begin - status_valid_next = 1; - status_frame_pad_next = 0; - status_frame_truncate_next = 0; + status_valid_next = 1'b1; + status_frame_pad_next = 1'b0; + status_frame_truncate_next = 1'b0; status_frame_length_next = frame_ptr_reg+word_cnt; status_frame_original_length_next = frame_ptr_reg+word_cnt; input_axis_tready_next = output_axis_tready_int_early & status_ready; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; state_next = STATE_IDLE; @@ -355,39 +355,39 @@ always @* begin end STATE_PAD: begin // pad to minimum length - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; - output_axis_tdata_int = 0; + output_axis_tdata_int = {DATA_WIDTH{1'b0}}; output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; - output_axis_tvalid_int = 1; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tvalid_int = 1'b1; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; if (short_counter_reg > KEEP_WIDTH) begin short_counter_next = short_counter_reg - KEEP_WIDTH; end else begin - short_counter_next = 0; + short_counter_next = 16'd0; end if (long_counter_reg > KEEP_WIDTH) begin long_counter_next = long_counter_reg - KEEP_WIDTH; end else begin - long_counter_next = 0; + long_counter_next = 16'd0; end if (short_counter_reg <= KEEP_WIDTH) begin - status_valid_next = 1; - status_frame_pad_next = 1; - status_frame_truncate_next = 0; + status_valid_next = 1'b1; + status_frame_pad_next = 1'b1; + status_frame_truncate_next = 1'b0; status_frame_length_next = length_min; input_axis_tready_next = output_axis_tready_int_early & status_ready; output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-short_counter_reg); - output_axis_tlast_int = 1; + output_axis_tlast_int = 1'b1; output_axis_tuser_int = last_cycle_tuser_reg; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; state_next = STATE_IDLE; @@ -417,13 +417,13 @@ always @* begin frame_ptr_next = frame_ptr_reg+KEEP_WIDTH; if (input_axis_tlast) begin - status_valid_next = 1; - status_frame_pad_next = 0; - status_frame_truncate_next = 1; + status_valid_next = 1'b1; + status_frame_pad_next = 1'b0; + status_frame_truncate_next = 1'b1; status_frame_length_next = length_max; status_frame_original_length_next = frame_ptr_reg+word_cnt; input_axis_tready_next = output_axis_tready_int_early & status_ready; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; state_next = STATE_IDLE; @@ -440,18 +440,11 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - short_counter_reg <= 0; - long_counter_reg <= 0; - input_axis_tready_reg <= 0; - last_word_data_reg <= 0; - last_word_keep_reg <= 0; - last_cycle_tuser_reg <= 0; - status_valid_reg <= 0; - status_frame_pad_reg <= 0; - status_frame_truncate_reg <= 0; - status_frame_length_reg <= 0; - status_frame_original_length_reg <= 0; + frame_ptr_reg <= 16'd0; + short_counter_reg <= 16'd0; + long_counter_reg <= 16'd0; + input_axis_tready_reg <= 1'b0; + status_valid_reg <= 1'b0; end else begin state_reg <= state_next; @@ -462,33 +455,39 @@ always @(posedge clk) begin input_axis_tready_reg <= input_axis_tready_next; - last_cycle_tuser_reg <= last_cycle_tuser_next; - status_valid_reg <= status_valid_next; - status_frame_pad_reg <= status_frame_pad_next; - status_frame_truncate_reg <= status_frame_truncate_next; - status_frame_length_reg <= status_frame_length_next; - status_frame_original_length_reg <= status_frame_original_length_next; + end - if (store_last_word) begin - last_word_data_reg <= output_axis_tdata_int; - last_word_keep_reg <= output_axis_tkeep_int; - end + last_cycle_tuser_reg <= last_cycle_tuser_next; + + status_frame_pad_reg <= status_frame_pad_next; + status_frame_truncate_reg <= status_frame_truncate_next; + status_frame_length_reg <= status_frame_length_next; + status_frame_original_length_reg <= status_frame_original_length_next; + + if (store_last_word) begin + last_word_data_reg <= output_axis_tdata_int; + last_word_keep_reg <= output_axis_tkeep_int; end end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -496,56 +495,66 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 16fc4c9f9..4d3550e11 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -103,16 +103,16 @@ module {{name}} # input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; {% for p in ports %} -reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; {%- endfor %} // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -154,7 +154,7 @@ always @* begin select_next = select_reg; frame_next = frame_reg; {% for p in ports %} - input_{{p}}_axis_tready_next = 0; + input_{{p}}_axis_tready_next = 1'b0; {%- endfor %} if (frame_reg) begin @@ -164,7 +164,7 @@ always @* begin end end else if (enable & selected_input_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; end @@ -184,10 +184,10 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; {%- for p in ports %} - input_{{p}}_axis_tready_reg <= 0; + input_{{p}}_axis_tready_reg <= 1'b0; {%- endfor %} end else begin select_reg <= select_next; @@ -199,65 +199,83 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v index bafefba14..319acfd9f 100644 --- a/rtl/axis_mux_4.v +++ b/rtl/axis_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -80,18 +80,18 @@ module axis_mux_4 # input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; +reg input_0_axis_tready_reg = 1'b0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 1'b0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -155,10 +155,10 @@ always @* begin select_next = select_reg; frame_next = frame_reg; - input_0_axis_tready_next = 0; - input_1_axis_tready_next = 0; - input_2_axis_tready_next = 0; - input_3_axis_tready_next = 0; + input_0_axis_tready_next = 1'b0; + input_1_axis_tready_next = 1'b0; + input_2_axis_tready_next = 1'b0; + input_3_axis_tready_next = 1'b0; if (frame_reg) begin if (current_input_tvalid & current_input_tready) begin @@ -167,7 +167,7 @@ always @* begin end end else if (enable & selected_input_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; end @@ -188,12 +188,12 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_axis_tready_reg <= 0; - input_1_axis_tready_reg <= 0; - input_2_axis_tready_reg <= 0; - input_3_axis_tready_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_0_axis_tready_reg <= 1'b0; + input_1_axis_tready_reg <= 1'b0; + input_2_axis_tready_reg <= 1'b0; + input_3_axis_tready_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -205,65 +205,83 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index cc5b5ede6..e38d19a96 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -106,17 +106,17 @@ module {{name}} # input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; {% for p in ports %} -reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next; +reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; {%- endfor %} // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -160,7 +160,7 @@ always @* begin select_next = select_reg; frame_next = frame_reg; {% for p in ports %} - input_{{p}}_axis_tready_next = 0; + input_{{p}}_axis_tready_next = 1'b0; {%- endfor %} if (frame_reg) begin @@ -170,7 +170,7 @@ always @* begin end end else if (enable & selected_input_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; end @@ -191,10 +191,10 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; {%- for p in ports %} - input_{{p}}_axis_tready_reg <= 0; + input_{{p}}_axis_tready_reg <= 1'b0; {%- endfor %} end else begin select_reg <= select_next; @@ -206,17 +206,22 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -224,56 +229,66 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_mux_64_4.v b/rtl/axis_mux_64_4.v index 624fad750..5e798aa35 100644 --- a/rtl/axis_mux_64_4.v +++ b/rtl/axis_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -86,19 +86,19 @@ module axis_mux_64_4 # input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_axis_tready_reg = 0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 0, input_3_axis_tready_next; +reg input_0_axis_tready_reg = 1'b0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 1'b0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -167,10 +167,10 @@ always @* begin select_next = select_reg; frame_next = frame_reg; - input_0_axis_tready_next = 0; - input_1_axis_tready_next = 0; - input_2_axis_tready_next = 0; - input_3_axis_tready_next = 0; + input_0_axis_tready_next = 1'b0; + input_1_axis_tready_next = 1'b0; + input_2_axis_tready_next = 1'b0; + input_3_axis_tready_next = 1'b0; if (frame_reg) begin if (current_input_tvalid & current_input_tready) begin @@ -179,7 +179,7 @@ always @* begin end end else if (enable & selected_input_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; end @@ -201,12 +201,12 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_axis_tready_reg <= 0; - input_1_axis_tready_reg <= 0; - input_2_axis_tready_reg <= 0; - input_3_axis_tready_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_0_axis_tready_reg <= 1'b0; + input_1_axis_tready_reg <= 1'b0; + input_2_axis_tready_reg <= 1'b0; + input_3_axis_tready_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -218,17 +218,22 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -236,56 +241,66 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index fb0da33e8..835863bfd 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -66,21 +66,22 @@ module axis_rate_limit # // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg [23:0] acc_reg = 0, acc_next; +reg [23:0] acc_reg = 24'd0, acc_next; reg pause; -reg frame_reg = 0, frame_next; +reg frame_reg = 1'b0, frame_next; + +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; always @* begin acc_next = acc_reg; - pause = 0; + pause = 1'b0; frame_next = frame_reg; if (acc_reg >= rate_num) begin @@ -97,7 +98,7 @@ always @* begin if (rate_by_frame) begin pause = ~frame_next; end else begin - pause = 1; + pause = 1'b1; end end @@ -111,9 +112,9 @@ end always @(posedge clk) begin if (rst) begin - acc_reg <= 0; - frame_reg <= 0; - input_axis_tready_reg <= 0; + acc_reg <= 24'd0; + frame_reg <= 1'b0; + input_axis_tready_reg <= 1'b0; end else begin acc_reg <= acc_next; frame_reg <= frame_next; @@ -122,65 +123,83 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v index be6cc1c2c..b527a3497 100644 --- a/rtl/axis_rate_limit_64.v +++ b/rtl/axis_rate_limit_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -70,21 +70,22 @@ module axis_rate_limit_64 # reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; -reg [23:0] acc_reg = 0, acc_next; +reg [23:0] acc_reg = 24'd0, acc_next; reg pause; -reg frame_reg = 0, frame_next; +reg frame_reg = 1'b0, frame_next; + +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; always @* begin acc_next = acc_reg; - pause = 0; + pause = 1'b0; frame_next = frame_reg; if (acc_reg >= rate_num) begin @@ -101,7 +102,7 @@ always @* begin if (rate_by_frame) begin pause = ~frame_next; end else begin - pause = 1; + pause = 1'b1; end end @@ -116,9 +117,9 @@ end always @(posedge clk) begin if (rst) begin - acc_reg <= 0; - frame_reg <= 0; - input_axis_tready_reg <= 0; + acc_reg <= 24'd0; + frame_reg <= 1'b0; + input_axis_tready_reg <= 1'b0; end else begin acc_reg <= acc_next; frame_reg <= frame_next; @@ -127,17 +128,22 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -145,56 +151,66 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index 77b99e735..cabc98438 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -91,7 +91,7 @@ reg [1:0] state_reg = STATE_IDLE, state_next; reg [TICK_COUNT_WIDTH-1:0] tick_count_reg = 0, tick_count_next; reg [BYTE_COUNT_WIDTH-1:0] byte_count_reg = 0, byte_count_next; reg [FRAME_COUNT_WIDTH-1:0] frame_count_reg = 0, frame_count_next; -reg frame_reg = 0, frame_next; +reg frame_reg = 1'b0, frame_next; reg store_output; reg [$clog2(TOTAL_LENGTH)-1:0] frame_ptr_reg = 0, frame_ptr_next; @@ -100,12 +100,12 @@ reg [TICK_COUNT_WIDTH-1:0] tick_count_output_reg = 0; reg [BYTE_COUNT_WIDTH-1:0] byte_count_output_reg = 0; reg [FRAME_COUNT_WIDTH-1:0] frame_count_output_reg = 0; -reg busy_reg = 0; +reg busy_reg = 1'b0; // internal datapath reg [7:0] output_axis_tdata_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -115,19 +115,19 @@ assign busy = busy_reg; integer offset, i, bit_cnt; always @* begin - state_next = 2'bz; + state_next = STATE_IDLE; tick_count_next = tick_count_reg; byte_count_next = byte_count_reg; frame_count_next = frame_count_reg; frame_next = frame_reg; - output_axis_tdata_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; - store_output = 0; + store_output = 1'b0; frame_ptr_next = frame_ptr_reg; @@ -136,13 +136,13 @@ always @* begin case (state_reg) STATE_IDLE: begin if (trigger) begin - store_output = 1; + store_output = 1'b1; tick_count_next = 0; byte_count_next = 0; frame_count_next = 0; frame_ptr_next = 0; - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin frame_ptr_next = 1; if (TAG_ENABLE) begin output_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; @@ -153,7 +153,7 @@ always @* begin end else if (FRAME_COUNT_ENABLE) begin output_axis_tdata_int = frame_count_reg[(FRAME_COUNT_BYTE_WIDTH-1)*8 +: 8]; end - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; end state_next = STATE_OUTPUT_DATA; @@ -162,10 +162,10 @@ always @* begin end end STATE_OUTPUT_DATA: begin - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin state_next = STATE_OUTPUT_DATA; frame_ptr_next = frame_ptr_reg + 1; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; offset = 0; if (TAG_ENABLE) begin @@ -201,7 +201,7 @@ always @* begin end end if (frame_ptr_reg == offset-1) begin - output_axis_tlast_int = 1; + output_axis_tlast_int = 1'b1; state_next = STATE_IDLE; end end else begin @@ -229,11 +229,11 @@ always @* begin // count frames if (monitor_axis_tlast) begin // end of frame - frame_next = 0; + frame_next = 1'b0; end else if (~frame_reg) begin // first word after end of frame frame_count_next = frame_count_next + 1; - frame_next = 1; + frame_next = 1'b1; end end end @@ -244,12 +244,9 @@ always @(posedge clk) begin tick_count_reg <= 0; byte_count_reg <= 0; frame_count_reg <= 0; - frame_reg <= 0; + frame_reg <= 1'b0; frame_ptr_reg <= 0; - busy_reg <= 0; - tick_count_output_reg <= 0; - byte_count_output_reg <= 0; - frame_count_output_reg <= 0; + busy_reg <= 1'b0; end else begin state_reg <= state_next; tick_count_reg <= tick_count_next; @@ -260,74 +257,93 @@ always @(posedge clk) begin busy_reg <= state_next != STATE_IDLE; - if (store_output) begin - tick_count_output_reg <= tick_count_reg; - byte_count_output_reg <= byte_count_reg; - frame_count_output_reg <= frame_count_reg; - end + end + + if (store_output) begin + tick_count_output_reg <= tick_count_reg; + byte_count_output_reg <= byte_count_reg; + frame_count_output_reg <= frame_count_reg; end end // output datapath logic -reg [7:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [7:0] output_axis_tdata_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [7:0] temp_axis_tdata_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_tap.v b/rtl/axis_tap.v index b4fa25f91..77165a17c 100644 --- a/rtl/axis_tap.v +++ b/rtl/axis_tap.v @@ -59,7 +59,7 @@ module axis_tap # // internal datapath reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -72,17 +72,17 @@ localparam [1:0] reg [1:0] state_reg = STATE_IDLE, state_next; -reg frame_reg = 0, frame_next; +reg frame_reg = 1'b0, frame_next; always @* begin state_next = STATE_IDLE; frame_next = frame_reg; - output_axis_tdata_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; if (tap_axis_tready & tap_axis_tvalid) begin frame_next = ~tap_axis_tlast; @@ -92,7 +92,7 @@ always @* begin STATE_IDLE: begin if (tap_axis_tready & tap_axis_tvalid) begin // start of frame - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin output_axis_tdata_int = tap_axis_tdata; output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; output_axis_tlast_int = tap_axis_tlast; @@ -112,7 +112,7 @@ always @* begin STATE_TRANSFER: begin if (tap_axis_tready & tap_axis_tvalid) begin // transfer data - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin output_axis_tdata_int = tap_axis_tdata; output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; output_axis_tlast_int = tap_axis_tlast; @@ -130,11 +130,11 @@ always @* begin end end STATE_TRUNCATE: begin - if (output_axis_tready_int) begin - output_axis_tdata_int = 0; - output_axis_tvalid_int = 1; - output_axis_tlast_int = 1; - output_axis_tuser_int = 1; + if (output_axis_tready_int_reg) begin + output_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_axis_tvalid_int = 1'b1; + output_axis_tlast_int = 1'b1; + output_axis_tuser_int = 1'b1; if (frame_next) begin state_next = STATE_WAIT; end else begin @@ -161,7 +161,7 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_reg <= 0; + frame_reg <= 1'b0; end else begin state_reg <= state_next; frame_reg <= frame_next; @@ -169,65 +169,83 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_tap_64.v b/rtl/axis_tap_64.v index bed8668bc..0080d5be4 100644 --- a/rtl/axis_tap_64.v +++ b/rtl/axis_tap_64.v @@ -63,7 +63,7 @@ module axis_tap_64 # reg [DATA_WIDTH-1:0] output_axis_tdata_int; reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -76,18 +76,18 @@ localparam [1:0] reg [1:0] state_reg = STATE_IDLE, state_next; -reg frame_reg = 0, frame_next; +reg frame_reg = 1'b0, frame_next; always @* begin state_next = STATE_IDLE; frame_next = frame_reg; - output_axis_tdata_int = 0; - output_axis_tkeep_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; if (tap_axis_tready & tap_axis_tvalid) begin frame_next = ~tap_axis_tlast; @@ -97,7 +97,7 @@ always @* begin STATE_IDLE: begin if (tap_axis_tready & tap_axis_tvalid) begin // start of frame - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin output_axis_tdata_int = tap_axis_tdata; output_axis_tkeep_int = tap_axis_tkeep; output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; @@ -118,7 +118,7 @@ always @* begin STATE_TRANSFER: begin if (tap_axis_tready & tap_axis_tvalid) begin // transfer data - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin output_axis_tdata_int = tap_axis_tdata; output_axis_tkeep_int = tap_axis_tkeep; output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; @@ -137,12 +137,12 @@ always @* begin end end STATE_TRUNCATE: begin - if (output_axis_tready_int) begin - output_axis_tdata_int = 0; - output_axis_tkeep_int = 1; - output_axis_tvalid_int = 1; - output_axis_tlast_int = 1; - output_axis_tuser_int = 1; + if (output_axis_tready_int_reg) begin + output_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_axis_tkeep_int = {{KEEP_WIDTH-1{1'b0}}, 1'b1}; + output_axis_tvalid_int = 1'b1; + output_axis_tlast_int = 1'b1; + output_axis_tuser_int = 1'b1; if (frame_next) begin state_next = STATE_WAIT; end else begin @@ -169,7 +169,7 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_reg <= 0; + frame_reg <= 1'b0; end else begin state_reg <= state_next; frame_reg <= frame_next; @@ -177,17 +177,22 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -195,56 +200,66 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end From 7a9fdb5fc34ca0fa33a20e338c8f0a84cd4f8f96 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 9 Nov 2015 14:54:14 -0800 Subject: [PATCH 262/617] Add default case statements to avoid inferring latches --- rtl/axis_demux.py | 4 ++++ rtl/axis_demux_4.v | 4 ++++ rtl/axis_demux_64.py | 4 ++++ rtl/axis_demux_64_4.v | 4 ++++ rtl/axis_mux.py | 8 ++++++++ rtl/axis_mux_4.v | 8 ++++++++ rtl/axis_mux_64.py | 9 +++++++++ rtl/axis_mux_64_4.v | 9 +++++++++ 8 files changed, 50 insertions(+) diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index 28bb7ed2a..71b37dbae 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -129,6 +129,10 @@ always @* begin current_output_tready = output_{{p}}_axis_tready; end {%- endfor %} + default: begin + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v index 6b853aebf..9d5b83100 100644 --- a/rtl/axis_demux_4.v +++ b/rtl/axis_demux_4.v @@ -116,6 +116,10 @@ always @* begin current_output_tvalid = output_3_axis_tvalid; current_output_tready = output_3_axis_tready; end + default: begin + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index 898bb6e60..d3f6294f2 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -133,6 +133,10 @@ always @* begin current_output_tready = output_{{p}}_axis_tready; end {%- endfor %} + default: begin + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end diff --git a/rtl/axis_demux_64_4.v b/rtl/axis_demux_64_4.v index 489ce179e..f4bb51fc4 100644 --- a/rtl/axis_demux_64_4.v +++ b/rtl/axis_demux_64_4.v @@ -123,6 +123,10 @@ always @* begin current_output_tvalid = output_3_axis_tvalid; current_output_tready = output_3_axis_tready; end + default: begin + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 4d3550e11..95c2ada0b 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -127,6 +127,7 @@ always @* begin {%- for p in ports %} {{w}}'d{{p}}: selected_input_tvalid = input_{{p}}_axis_tvalid; {%- endfor %} + default: selected_input_tvalid = 1'b0; endcase end @@ -147,6 +148,13 @@ always @* begin current_input_tuser = input_{{p}}_axis_tuser; end {%- endfor %} + default: begin + current_input_tdata = {DATA_WIDTH{1'b0}}; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v index 319acfd9f..b52c17e92 100644 --- a/rtl/axis_mux_4.v +++ b/rtl/axis_mux_4.v @@ -109,6 +109,7 @@ always @* begin 2'd1: selected_input_tvalid = input_1_axis_tvalid; 2'd2: selected_input_tvalid = input_2_axis_tvalid; 2'd3: selected_input_tvalid = input_3_axis_tvalid; + default: selected_input_tvalid = 1'b0; endcase end @@ -148,6 +149,13 @@ always @* begin current_input_tlast = input_3_axis_tlast; current_input_tuser = input_3_axis_tuser; end + default: begin + current_input_tdata = {DATA_WIDTH{1'b0}}; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index e38d19a96..bd3b27f3c 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -131,6 +131,7 @@ always @* begin {%- for p in ports %} {{w}}'d{{p}}: selected_input_tvalid = input_{{p}}_axis_tvalid; {%- endfor %} + default: selected_input_tvalid = 1'b0; endcase end @@ -153,6 +154,14 @@ always @* begin current_input_tuser = input_{{p}}_axis_tuser; end {%- endfor %} + default: begin + current_input_tdata = {DATA_WIDTH{1'b0}}; + current_input_tkeep = {KEEP_WIDTH{1'b0}}; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end diff --git a/rtl/axis_mux_64_4.v b/rtl/axis_mux_64_4.v index 5e798aa35..11ee9aeb1 100644 --- a/rtl/axis_mux_64_4.v +++ b/rtl/axis_mux_64_4.v @@ -116,6 +116,7 @@ always @* begin 2'd1: selected_input_tvalid = input_1_axis_tvalid; 2'd2: selected_input_tvalid = input_2_axis_tvalid; 2'd3: selected_input_tvalid = input_3_axis_tvalid; + default: selected_input_tvalid = 1'b0; endcase end @@ -160,6 +161,14 @@ always @* begin current_input_tlast = input_3_axis_tlast; current_input_tuser = input_3_axis_tuser; end + default: begin + current_input_tdata = {DATA_WIDTH{1'b0}}; + current_input_tkeep = {KEEP_WIDTH{1'b0}}; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end From a98dfce09932572044adc6ae845a41643e2bcb2d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 9 Nov 2015 23:50:34 -0800 Subject: [PATCH 263/617] Update output registers, remove extraneous resets, fix constant widths --- rtl/arp.v | 120 +++++---- rtl/arp_64.v | 120 +++++---- rtl/arp_eth_rx.v | 277 ++++++++++---------- rtl/arp_eth_rx_64.v | 193 +++++++------- rtl/arp_eth_tx.v | 233 +++++++++-------- rtl/arp_eth_tx_64.v | 242 +++++++++--------- rtl/axis_eth_fcs.v | 12 +- rtl/axis_eth_fcs_64.v | 14 +- rtl/axis_eth_fcs_check.v | 250 +++++++++--------- rtl/axis_eth_fcs_check_64.v | 255 +++++++++--------- rtl/axis_eth_fcs_insert.v | 234 +++++++++-------- rtl/axis_eth_fcs_insert_64.v | 343 +++++++++++++------------ rtl/eth_axis_rx.v | 261 ++++++++++--------- rtl/eth_axis_rx_64.v | 293 +++++++++++---------- rtl/eth_axis_tx.v | 199 ++++++++------- rtl/eth_axis_tx_64.v | 258 ++++++++++--------- rtl/eth_demux.py | 182 +++++++------ rtl/eth_demux_4.v | 218 +++++++++------- rtl/eth_demux_64.py | 195 +++++++------- rtl/eth_demux_64_4.v | 231 +++++++++-------- rtl/eth_mac_10g_fifo.v | 16 +- rtl/eth_mac_10g_rx.v | 149 +++++------ rtl/eth_mac_10g_tx.v | 238 +++++++++-------- rtl/eth_mac_1g_fifo.v | 16 +- rtl/eth_mac_1g_rx.v | 118 ++++----- rtl/eth_mac_1g_tx.v | 116 ++++----- rtl/eth_mux.py | 173 +++++++------ rtl/eth_mux_2.v | 185 ++++++++------ rtl/eth_mux_4.v | 209 ++++++++------- rtl/eth_mux_64.py | 187 ++++++++------ rtl/eth_mux_64_2.v | 199 ++++++++------- rtl/eth_mux_64_4.v | 223 +++++++++------- rtl/gmii_phy_if.v | 22 +- rtl/ip.v | 38 +-- rtl/ip_64.v | 40 +-- rtl/ip_complete.v | 20 +- rtl/ip_complete_64.v | 20 +- rtl/ip_demux.py | 247 +++++++++--------- rtl/ip_demux_4.v | 283 ++++++++++---------- rtl/ip_demux_64.py | 260 ++++++++++--------- rtl/ip_demux_64_4.v | 296 ++++++++++----------- rtl/ip_eth_rx.v | 421 +++++++++++++++--------------- rtl/ip_eth_rx_64.v | 483 +++++++++++++++++------------------ rtl/ip_eth_tx.v | 288 +++++++++++---------- rtl/ip_eth_tx_64.v | 385 ++++++++++++++-------------- rtl/ip_mux.py | 249 ++++++++++-------- rtl/ip_mux_2.v | 261 ++++++++++--------- rtl/ip_mux_4.v | 285 +++++++++++---------- rtl/ip_mux_64.py | 265 ++++++++++--------- rtl/ip_mux_64_2.v | 277 +++++++++++--------- rtl/ip_mux_64_4.v | 301 ++++++++++++---------- rtl/udp_complete.v | 68 ++--- rtl/udp_complete_64.v | 68 ++--- rtl/udp_demux.py | 267 +++++++++---------- rtl/udp_demux_4.v | 303 +++++++++++----------- rtl/udp_demux_64.py | 280 ++++++++++---------- rtl/udp_demux_64_4.v | 316 ++++++++++++----------- rtl/udp_ip_rx.v | 373 ++++++++++++++------------- rtl/udp_ip_rx_64.v | 370 +++++++++++++-------------- rtl/udp_ip_tx.v | 311 +++++++++++----------- rtl/udp_ip_tx_64.v | 351 +++++++++++++------------ rtl/udp_mux.py | 273 +++++++++++--------- rtl/udp_mux_4.v | 309 ++++++++++++---------- rtl/udp_mux_64.py | 287 +++++++++++---------- rtl/udp_mux_64_4.v | 323 ++++++++++++----------- 65 files changed, 7481 insertions(+), 6818 deletions(-) diff --git a/rtl/arp.v b/rtl/arp.v index 62f834999..3b795f998 100644 --- a/rtl/arp.v +++ b/rtl/arp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -107,15 +107,15 @@ wire [31:0] incoming_arp_spa; wire [47:0] incoming_arp_tha; wire [31:0] incoming_arp_tpa; -reg outgoing_frame_valid_reg = 0, outgoing_frame_valid_next; +reg outgoing_frame_valid_reg = 1'b0, outgoing_frame_valid_next; wire outgoing_frame_ready; -reg [47:0] outgoing_eth_dest_mac_reg = 0, outgoing_eth_dest_mac_next; -reg [15:0] outgoing_arp_oper_reg = 0, outgoing_arp_oper_next; -reg [47:0] outgoing_arp_tha_reg = 0, outgoing_arp_tha_next; -reg [31:0] outgoing_arp_tpa_reg = 0, outgoing_arp_tpa_next; +reg [47:0] outgoing_eth_dest_mac_reg = 48'd0, outgoing_eth_dest_mac_next; +reg [15:0] outgoing_arp_oper_reg = 16'd0, outgoing_arp_oper_next; +reg [47:0] outgoing_arp_tha_reg = 48'd0, outgoing_arp_tha_next; +reg [31:0] outgoing_arp_tpa_reg = 32'd0, outgoing_arp_tpa_next; // drop frame -reg drop_incoming_frame_reg = 0, drop_incoming_frame_next; +reg drop_incoming_frame_reg = 1'b0, drop_incoming_frame_next; // wait on incoming frames until we can reply assign incoming_frame_ready = outgoing_frame_ready | drop_incoming_frame_reg; @@ -216,9 +216,9 @@ wire cache_query_response_valid; wire cache_query_response_error; wire [47:0] cache_query_response_mac; -reg cache_write_request_valid_reg = 0, cache_write_request_valid_next; -reg [31:0] cache_write_request_ip_reg = 0, cache_write_request_ip_next; -reg [47:0] cache_write_request_mac_reg = 0, cache_write_request_mac_next; +reg cache_write_request_valid_reg = 1'b0, cache_write_request_valid_next; +reg [31:0] cache_write_request_ip_reg = 32'd0, cache_write_request_ip_next; +reg [47:0] cache_write_request_mac_reg = 48'd0, cache_write_request_mac_next; wire cache_write_in_progress; wire cache_write_complete; @@ -247,16 +247,16 @@ arp_cache_inst ( .clear_cache(clear_cache) ); -reg arp_request_operation_reg = 0, arp_request_operation_next; +reg arp_request_operation_reg = 1'b0, arp_request_operation_next; -reg arp_request_valid_reg = 0, arp_request_valid_next; -reg [31:0] arp_request_ip_reg = 0, arp_request_ip_next; +reg arp_request_valid_reg = 1'b0, arp_request_valid_next; +reg [31:0] arp_request_ip_reg = 32'd0, arp_request_ip_next; -reg arp_response_error_reg = 0, arp_response_error_next; -reg arp_response_broadcast_reg = 0, arp_response_broadcast_next; +reg arp_response_error_reg = 1'b0, arp_response_error_next; +reg arp_response_broadcast_reg = 1'b0, arp_response_broadcast_next; -reg [5:0] arp_request_retry_cnt_reg = 0, arp_request_retry_cnt_next; -reg [35:0] arp_request_timer_reg = 0, arp_request_timer_next; +reg [5:0] arp_request_retry_cnt_reg = 6'd0, arp_request_retry_cnt_next; +reg [35:0] arp_request_timer_reg = 36'd0, arp_request_timer_next; assign cache_query_request_valid = ~arp_request_operation_reg ? arp_request_valid_reg : 1'b1; assign cache_query_request_ip = arp_request_ip_reg; @@ -272,57 +272,57 @@ always @* begin outgoing_arp_tha_next = outgoing_arp_tha_reg; outgoing_arp_tpa_next = outgoing_arp_tpa_reg; - cache_write_request_valid_next = 0; - cache_write_request_mac_next = 0; - cache_write_request_ip_next = 0; + cache_write_request_valid_next = 1'b0; + cache_write_request_mac_next = 48'd0; + cache_write_request_ip_next = 32'd0; - arp_request_valid_next = 0; + arp_request_valid_next = 1'b0; arp_request_ip_next = arp_request_ip_reg; arp_request_operation_next = arp_request_operation_reg; arp_request_retry_cnt_next = arp_request_retry_cnt_reg; arp_request_timer_next = arp_request_timer_reg; - arp_response_error_next = 0; - arp_response_broadcast_next = 0; + arp_response_error_next = 1'b0; + arp_response_broadcast_next = 1'b0; - drop_incoming_frame_next = 0; + drop_incoming_frame_next = 1'b0; // manage incoming frames if (filtered_incoming_frame_valid & ~(outgoing_frame_valid_reg & ~outgoing_frame_ready)) begin // store sender addresses in cache - cache_write_request_valid_next = 1; + cache_write_request_valid_next = 1'b1; cache_write_request_ip_next = incoming_arp_spa; cache_write_request_mac_next = incoming_arp_sha; if (incoming_arp_oper_arp_request) begin if (incoming_arp_tpa == local_ip) begin // send reply frame to valid incoming request - outgoing_frame_valid_next = 1; + outgoing_frame_valid_next = 1'b1; outgoing_eth_dest_mac_next = incoming_eth_src_mac; outgoing_arp_oper_next = ARP_OPER_ARP_REPLY; outgoing_arp_tha_next = incoming_arp_sha; outgoing_arp_tpa_next = incoming_arp_spa; end else begin // does not match -> drop it - drop_incoming_frame_next = 1; + drop_incoming_frame_next = 1'b1; end end else if (incoming_arp_oper_inarp_request) begin if (incoming_arp_tha == local_mac) begin // send reply frame to valid incoming request - outgoing_frame_valid_next = 1; + outgoing_frame_valid_next = 1'b1; outgoing_eth_dest_mac_next = incoming_eth_src_mac; outgoing_arp_oper_next = ARP_OPER_INARP_REPLY; outgoing_arp_tha_next = incoming_arp_sha; outgoing_arp_tpa_next = incoming_arp_spa; end else begin // does not match -> drop it - drop_incoming_frame_next = 1; + drop_incoming_frame_next = 1'b1; end end else begin // does not match -> drop it - drop_incoming_frame_next = 1; + drop_incoming_frame_next = 1'b1; end end else if (incoming_frame_valid & ~filtered_incoming_frame_valid) begin // incoming invalid frame -> drop it - drop_incoming_frame_next = 1; + drop_incoming_frame_next = 1'b1; end // manage ARP lookup requests @@ -331,23 +331,23 @@ always @* begin if (~(arp_request_ip | subnet_mask) == 0) begin // broadcast address // (all bits in request IP set where subnet mask is clear) - arp_request_valid_next = 0; - arp_response_broadcast_next = 1; + arp_request_valid_next = 1'b0; + arp_response_broadcast_next = 1'b1; end else if (((arp_request_ip ^ gateway_ip) & subnet_mask) == 0) begin // within subnet, look up IP directly // (no bits differ between request IP and gateway IP where subnet mask is set) - arp_request_valid_next = 1; + arp_request_valid_next = 1'b1; arp_request_ip_next = arp_request_ip; end else begin // outside of subnet, so look up gateway address - arp_request_valid_next = 1; + arp_request_valid_next = 1'b1; arp_request_ip_next = gateway_ip; end end if (cache_query_response_error & ~arp_response_error) begin - arp_request_operation_next = 1; + arp_request_operation_next = 1'b1; // send ARP request frame - outgoing_frame_valid_next = 1; + outgoing_frame_valid_next = 1'b1; outgoing_eth_dest_mac_next = 48'hFF_FF_FF_FF_FF_FF; outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; outgoing_arp_tha_next = 48'h00_00_00_00_00_00; @@ -359,7 +359,7 @@ always @* begin arp_request_timer_next = arp_request_timer_reg - 1; // if we got a response, it will go in the cache, so when the query succeds, we're done if (cache_query_response_valid & ~cache_query_response_error) begin - arp_request_operation_next = 0; + arp_request_operation_next = 1'b0; end // timer timeout if (arp_request_timer_reg == 0) begin @@ -379,8 +379,8 @@ always @* begin end end else begin // out of retries - arp_request_operation_next = 0; - arp_response_error_next = 1; + arp_request_operation_next = 1'b0; + arp_response_error_next = 1'b1; end end end @@ -388,33 +388,19 @@ end always @(posedge clk) begin if (rst) begin - outgoing_frame_valid_reg <= 0; - outgoing_eth_dest_mac_reg <= 0; - outgoing_arp_oper_reg <= 0; - outgoing_arp_tha_reg <= 0; - outgoing_arp_tpa_reg <= 0; - cache_write_request_valid_reg <= 0; - cache_write_request_mac_reg <= 0; - cache_write_request_ip_reg <= 0; - arp_request_valid_reg <= 0; - arp_request_ip_reg <= 0; - arp_request_operation_reg <= 0; - arp_request_retry_cnt_reg <= 0; - arp_request_timer_reg <= 0; - arp_response_error_reg <= 0; - arp_response_broadcast_reg <= 0; - drop_incoming_frame_reg <= 0; + outgoing_frame_valid_reg <= 1'b0; + cache_write_request_valid_reg <= 1'b0; + arp_request_valid_reg <= 1'b0; + arp_request_operation_reg <= 1'b0; + arp_request_retry_cnt_reg <= 6'd0; + arp_request_timer_reg <= 36'd0; + arp_response_error_reg <= 1'b0; + arp_response_broadcast_reg <= 1'b0; + drop_incoming_frame_reg <= 1'b0; end else begin outgoing_frame_valid_reg <= outgoing_frame_valid_next; - outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; - outgoing_arp_oper_reg <= outgoing_arp_oper_next; - outgoing_arp_tha_reg <= outgoing_arp_tha_next; - outgoing_arp_tpa_reg <= outgoing_arp_tpa_next; cache_write_request_valid_reg <= cache_write_request_valid_next; - cache_write_request_mac_reg <= cache_write_request_mac_next; - cache_write_request_ip_reg <= cache_write_request_ip_next; arp_request_valid_reg <= arp_request_valid_next; - arp_request_ip_reg <= arp_request_ip_next; arp_request_operation_reg <= arp_request_operation_next; arp_request_retry_cnt_reg <= arp_request_retry_cnt_next; arp_request_timer_reg <= arp_request_timer_next; @@ -422,6 +408,14 @@ always @(posedge clk) begin arp_response_broadcast_reg <= arp_response_broadcast_next; drop_incoming_frame_reg <= drop_incoming_frame_next; end + + outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; + outgoing_arp_oper_reg <= outgoing_arp_oper_next; + outgoing_arp_tha_reg <= outgoing_arp_tha_next; + outgoing_arp_tpa_reg <= outgoing_arp_tpa_next; + cache_write_request_mac_reg <= cache_write_request_mac_next; + cache_write_request_ip_reg <= cache_write_request_ip_next; + arp_request_ip_reg <= arp_request_ip_next; end endmodule diff --git a/rtl/arp_64.v b/rtl/arp_64.v index e8c39424b..9cfb56bd1 100644 --- a/rtl/arp_64.v +++ b/rtl/arp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -109,15 +109,15 @@ wire [31:0] incoming_arp_spa; wire [47:0] incoming_arp_tha; wire [31:0] incoming_arp_tpa; -reg outgoing_frame_valid_reg = 0, outgoing_frame_valid_next; +reg outgoing_frame_valid_reg = 1'b0, outgoing_frame_valid_next; wire outgoing_frame_ready; -reg [47:0] outgoing_eth_dest_mac_reg = 0, outgoing_eth_dest_mac_next; -reg [15:0] outgoing_arp_oper_reg = 0, outgoing_arp_oper_next; -reg [47:0] outgoing_arp_tha_reg = 0, outgoing_arp_tha_next; -reg [31:0] outgoing_arp_tpa_reg = 0, outgoing_arp_tpa_next; +reg [47:0] outgoing_eth_dest_mac_reg = 48'd0, outgoing_eth_dest_mac_next; +reg [15:0] outgoing_arp_oper_reg = 16'd0, outgoing_arp_oper_next; +reg [47:0] outgoing_arp_tha_reg = 48'd0, outgoing_arp_tha_next; +reg [31:0] outgoing_arp_tpa_reg = 32'd0, outgoing_arp_tpa_next; // drop frame -reg drop_incoming_frame_reg = 0, drop_incoming_frame_next; +reg drop_incoming_frame_reg = 1'b0, drop_incoming_frame_next; // wait on incoming frames until we can reply assign incoming_frame_ready = outgoing_frame_ready | drop_incoming_frame_reg; @@ -220,9 +220,9 @@ wire cache_query_response_valid; wire cache_query_response_error; wire [47:0] cache_query_response_mac; -reg cache_write_request_valid_reg = 0, cache_write_request_valid_next; -reg [31:0] cache_write_request_ip_reg = 0, cache_write_request_ip_next; -reg [47:0] cache_write_request_mac_reg = 0, cache_write_request_mac_next; +reg cache_write_request_valid_reg = 1'b0, cache_write_request_valid_next; +reg [31:0] cache_write_request_ip_reg = 32'd0, cache_write_request_ip_next; +reg [47:0] cache_write_request_mac_reg = 48'd0, cache_write_request_mac_next; wire cache_write_in_progress; wire cache_write_complete; @@ -251,16 +251,16 @@ arp_cache_inst ( .clear_cache(clear_cache) ); -reg arp_request_operation_reg = 0, arp_request_operation_next; +reg arp_request_operation_reg = 1'b0, arp_request_operation_next; -reg arp_request_valid_reg = 0, arp_request_valid_next; -reg [31:0] arp_request_ip_reg = 0, arp_request_ip_next; +reg arp_request_valid_reg = 1'b0, arp_request_valid_next; +reg [31:0] arp_request_ip_reg = 32'd0, arp_request_ip_next; -reg arp_response_error_reg = 0, arp_response_error_next; -reg arp_response_broadcast_reg = 0, arp_response_broadcast_next; +reg arp_response_error_reg = 1'b0, arp_response_error_next; +reg arp_response_broadcast_reg = 1'b0, arp_response_broadcast_next; -reg [5:0] arp_request_retry_cnt_reg = 0, arp_request_retry_cnt_next; -reg [35:0] arp_request_timer_reg = 0, arp_request_timer_next; +reg [5:0] arp_request_retry_cnt_reg = 6'd0, arp_request_retry_cnt_next; +reg [35:0] arp_request_timer_reg = 36'd0, arp_request_timer_next; assign cache_query_request_valid = ~arp_request_operation_reg ? arp_request_valid_reg : 1'b1; assign cache_query_request_ip = arp_request_ip_reg; @@ -276,57 +276,57 @@ always @* begin outgoing_arp_tha_next = outgoing_arp_tha_reg; outgoing_arp_tpa_next = outgoing_arp_tpa_reg; - cache_write_request_valid_next = 0; - cache_write_request_mac_next = 0; - cache_write_request_ip_next = 0; + cache_write_request_valid_next = 1'b0; + cache_write_request_mac_next = 48'd0; + cache_write_request_ip_next = 32'd0; - arp_request_valid_next = 0; + arp_request_valid_next = 1'b0; arp_request_ip_next = arp_request_ip_reg; arp_request_operation_next = arp_request_operation_reg; arp_request_retry_cnt_next = arp_request_retry_cnt_reg; arp_request_timer_next = arp_request_timer_reg; - arp_response_error_next = 0; - arp_response_broadcast_next = 0; + arp_response_error_next = 1'b0; + arp_response_broadcast_next = 1'b0; - drop_incoming_frame_next = 0; + drop_incoming_frame_next = 1'b0; // manage incoming frames if (filtered_incoming_frame_valid & ~(outgoing_frame_valid_reg & ~outgoing_frame_ready)) begin // store sender addresses in cache - cache_write_request_valid_next = 1; + cache_write_request_valid_next = 1'b1; cache_write_request_ip_next = incoming_arp_spa; cache_write_request_mac_next = incoming_arp_sha; if (incoming_arp_oper_arp_request) begin if (incoming_arp_tpa == local_ip) begin // send reply frame to valid incoming request - outgoing_frame_valid_next = 1; + outgoing_frame_valid_next = 1'b1; outgoing_eth_dest_mac_next = incoming_eth_src_mac; outgoing_arp_oper_next = ARP_OPER_ARP_REPLY; outgoing_arp_tha_next = incoming_arp_sha; outgoing_arp_tpa_next = incoming_arp_spa; end else begin // does not match -> drop it - drop_incoming_frame_next = 1; + drop_incoming_frame_next = 1'b1; end end else if (incoming_arp_oper_inarp_request) begin if (incoming_arp_tha == local_mac) begin // send reply frame to valid incoming request - outgoing_frame_valid_next = 1; + outgoing_frame_valid_next = 1'b1; outgoing_eth_dest_mac_next = incoming_eth_src_mac; outgoing_arp_oper_next = ARP_OPER_INARP_REPLY; outgoing_arp_tha_next = incoming_arp_sha; outgoing_arp_tpa_next = incoming_arp_spa; end else begin // does not match -> drop it - drop_incoming_frame_next = 1; + drop_incoming_frame_next = 1'b1; end end else begin // does not match -> drop it - drop_incoming_frame_next = 1; + drop_incoming_frame_next = 1'b1; end end else if (incoming_frame_valid & ~filtered_incoming_frame_valid) begin // incoming invalid frame -> drop it - drop_incoming_frame_next = 1; + drop_incoming_frame_next = 1'b1; end // manage ARP lookup requests @@ -335,23 +335,23 @@ always @* begin if (~(arp_request_ip | subnet_mask) == 0) begin // broadcast address // (all bits in request IP set where subnet mask is clear) - arp_request_valid_next = 0; - arp_response_broadcast_next = 1; + arp_request_valid_next = 1'b0; + arp_response_broadcast_next = 1'b1; end else if (((arp_request_ip ^ gateway_ip) & subnet_mask) == 0) begin // within subnet, look up IP directly // (no bits differ between request IP and gateway IP where subnet mask is set) - arp_request_valid_next = 1; + arp_request_valid_next = 1'b1; arp_request_ip_next = arp_request_ip; end else begin // outside of subnet, so look up gateway address - arp_request_valid_next = 1; + arp_request_valid_next = 1'b1; arp_request_ip_next = gateway_ip; end end if (cache_query_response_error & ~arp_response_error) begin - arp_request_operation_next = 1; + arp_request_operation_next = 1'b1; // send ARP request frame - outgoing_frame_valid_next = 1; + outgoing_frame_valid_next = 1'b1; outgoing_eth_dest_mac_next = 48'hFF_FF_FF_FF_FF_FF; outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; outgoing_arp_tha_next = 48'h00_00_00_00_00_00; @@ -363,7 +363,7 @@ always @* begin arp_request_timer_next = arp_request_timer_reg - 1; // if we got a response, it will go in the cache, so when the query succeds, we're done if (cache_query_response_valid & ~cache_query_response_error) begin - arp_request_operation_next = 0; + arp_request_operation_next = 1'b0; end // timer timeout if (arp_request_timer_reg == 0) begin @@ -383,8 +383,8 @@ always @* begin end end else begin // out of retries - arp_request_operation_next = 0; - arp_response_error_next = 1; + arp_request_operation_next = 1'b0; + arp_response_error_next = 1'b1; end end end @@ -392,33 +392,19 @@ end always @(posedge clk) begin if (rst) begin - outgoing_frame_valid_reg <= 0; - outgoing_eth_dest_mac_reg <= 0; - outgoing_arp_oper_reg <= 0; - outgoing_arp_tha_reg <= 0; - outgoing_arp_tpa_reg <= 0; - cache_write_request_valid_reg <= 0; - cache_write_request_mac_reg <= 0; - cache_write_request_ip_reg <= 0; - arp_request_valid_reg <= 0; - arp_request_ip_reg <= 0; - arp_request_operation_reg <= 0; - arp_request_retry_cnt_reg <= 0; - arp_request_timer_reg <= 0; - arp_response_error_reg <= 0; - arp_response_broadcast_reg <= 0; - drop_incoming_frame_reg <= 0; + outgoing_frame_valid_reg <= 1'b0; + cache_write_request_valid_reg <= 1'b0; + arp_request_valid_reg <= 1'b0; + arp_request_operation_reg <= 1'b0; + arp_request_retry_cnt_reg <= 6'd0; + arp_request_timer_reg <= 36'd0; + arp_response_error_reg <= 1'b0; + arp_response_broadcast_reg <= 1'b0; + drop_incoming_frame_reg <= 1'b0; end else begin outgoing_frame_valid_reg <= outgoing_frame_valid_next; - outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; - outgoing_arp_oper_reg <= outgoing_arp_oper_next; - outgoing_arp_tha_reg <= outgoing_arp_tha_next; - outgoing_arp_tpa_reg <= outgoing_arp_tpa_next; cache_write_request_valid_reg <= cache_write_request_valid_next; - cache_write_request_mac_reg <= cache_write_request_mac_next; - cache_write_request_ip_reg <= cache_write_request_ip_next; arp_request_valid_reg <= arp_request_valid_next; - arp_request_ip_reg <= arp_request_ip_next; arp_request_operation_reg <= arp_request_operation_next; arp_request_retry_cnt_reg <= arp_request_retry_cnt_next; arp_request_timer_reg <= arp_request_timer_next; @@ -426,6 +412,14 @@ always @(posedge clk) begin arp_response_broadcast_reg <= arp_response_broadcast_next; drop_incoming_frame_reg <= drop_incoming_frame_next; end + + outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; + outgoing_arp_oper_reg <= outgoing_arp_oper_next; + outgoing_arp_tha_reg <= outgoing_arp_tha_next; + outgoing_arp_tpa_reg <= outgoing_arp_tpa_next; + cache_write_request_mac_reg <= cache_write_request_mac_next; + cache_write_request_ip_reg <= cache_write_request_ip_next; + arp_request_ip_reg <= arp_request_ip_next; end endmodule diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index 54ba2f6a9..0c6e61b9f 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -136,28 +136,28 @@ reg store_arp_tpa_1; reg store_arp_tpa_2; reg store_arp_tpa_3; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; -reg output_frame_valid_reg = 0, output_frame_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; -reg [15:0] output_arp_htype_reg = 0; -reg [15:0] output_arp_ptype_reg = 0; -reg [7:0] output_arp_hlen_reg = 0; -reg [7:0] output_arp_plen_reg = 0; -reg [15:0] output_arp_oper_reg = 0; -reg [47:0] output_arp_sha_reg = 0; -reg [31:0] output_arp_spa_reg = 0; -reg [47:0] output_arp_tha_reg = 0; -reg [31:0] output_arp_tpa_reg = 0; +reg output_frame_valid_reg = 1'b0, output_frame_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; +reg [15:0] output_arp_htype_reg = 16'd0; +reg [15:0] output_arp_ptype_reg = 16'd0; +reg [7:0] output_arp_hlen_reg = 8'd0; +reg [7:0] output_arp_plen_reg = 8'd0; +reg [15:0] output_arp_oper_reg = 16'd0; +reg [47:0] output_arp_sha_reg = 48'd0; +reg [31:0] output_arp_spa_reg = 32'd0; +reg [47:0] output_arp_tha_reg = 48'd0; +reg [31:0] output_arp_tpa_reg = 32'd0; -reg busy_reg = 0; -reg error_header_early_termination_reg = 0, error_header_early_termination_next; -reg error_invalid_header_reg = 0, error_invalid_header_next; +reg busy_reg = 1'b0; +reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; +reg error_invalid_header_reg = 1'b0, error_invalid_header_next; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; @@ -183,56 +183,56 @@ assign error_invalid_header = error_invalid_header_reg; always @* begin state_next = STATE_IDLE; - input_eth_hdr_ready_next = 0; - input_eth_payload_tready_next = 0; + input_eth_hdr_ready_next = 1'b0; + input_eth_payload_tready_next = 1'b0; - store_eth_hdr = 0; - store_arp_htype_0 = 0; - store_arp_htype_1 = 0; - store_arp_ptype_0 = 0; - store_arp_ptype_1 = 0; - store_arp_hlen = 0; - store_arp_plen = 0; - store_arp_oper_0 = 0; - store_arp_oper_1 = 0; - store_arp_sha_0 = 0; - store_arp_sha_1 = 0; - store_arp_sha_2 = 0; - store_arp_sha_3 = 0; - store_arp_sha_4 = 0; - store_arp_sha_5 = 0; - store_arp_spa_0 = 0; - store_arp_spa_1 = 0; - store_arp_spa_2 = 0; - store_arp_spa_3 = 0; - store_arp_tha_0 = 0; - store_arp_tha_1 = 0; - store_arp_tha_2 = 0; - store_arp_tha_3 = 0; - store_arp_tha_4 = 0; - store_arp_tha_5 = 0; - store_arp_tpa_0 = 0; - store_arp_tpa_1 = 0; - store_arp_tpa_2 = 0; - store_arp_tpa_3 = 0; + store_eth_hdr = 1'b0; + store_arp_htype_0 = 1'b0; + store_arp_htype_1 = 1'b0; + store_arp_ptype_0 = 1'b0; + store_arp_ptype_1 = 1'b0; + store_arp_hlen = 1'b0; + store_arp_plen = 1'b0; + store_arp_oper_0 = 1'b0; + store_arp_oper_1 = 1'b0; + store_arp_sha_0 = 1'b0; + store_arp_sha_1 = 1'b0; + store_arp_sha_2 = 1'b0; + store_arp_sha_3 = 1'b0; + store_arp_sha_4 = 1'b0; + store_arp_sha_5 = 1'b0; + store_arp_spa_0 = 1'b0; + store_arp_spa_1 = 1'b0; + store_arp_spa_2 = 1'b0; + store_arp_spa_3 = 1'b0; + store_arp_tha_0 = 1'b0; + store_arp_tha_1 = 1'b0; + store_arp_tha_2 = 1'b0; + store_arp_tha_3 = 1'b0; + store_arp_tha_4 = 1'b0; + store_arp_tha_5 = 1'b0; + store_arp_tpa_0 = 1'b0; + store_arp_tpa_1 = 1'b0; + store_arp_tpa_2 = 1'b0; + store_arp_tpa_3 = 1'b0; frame_ptr_next = frame_ptr_reg; output_frame_valid_next = output_frame_valid_reg & ~output_frame_ready; - error_header_early_termination_next = 0; - error_invalid_header_next = 0; + error_header_early_termination_next = 1'b0; + error_invalid_header_next = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; + frame_ptr_next = 8'd0; input_eth_hdr_ready_next = ~output_frame_valid_reg; if (input_eth_hdr_ready & input_eth_hdr_valid) begin - input_eth_hdr_ready_next = 0; - input_eth_payload_tready_next = 1; - store_eth_hdr = 1; + input_eth_hdr_ready_next = 1'b0; + input_eth_payload_tready_next = 1'b1; + store_eth_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin state_next = STATE_IDLE; @@ -240,42 +240,42 @@ always @* begin end STATE_READ_HEADER: begin // read header state - input_eth_payload_tready_next = 1; + input_eth_payload_tready_next = 1'b1; if (input_eth_payload_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg+1; + frame_ptr_next = frame_ptr_reg + 8'd1; state_next = STATE_READ_HEADER; case (frame_ptr_reg) - 8'h00: store_arp_htype_1 = 1; - 8'h01: store_arp_htype_0 = 1; - 8'h02: store_arp_ptype_1 = 1; - 8'h03: store_arp_ptype_0 = 1; - 8'h04: store_arp_hlen = 1; - 8'h05: store_arp_plen = 1; - 8'h06: store_arp_oper_1 = 1; - 8'h07: store_arp_oper_0 = 1; - 8'h08: store_arp_sha_5 = 1; - 8'h09: store_arp_sha_4 = 1; - 8'h0A: store_arp_sha_3 = 1; - 8'h0B: store_arp_sha_2 = 1; - 8'h0C: store_arp_sha_1 = 1; - 8'h0D: store_arp_sha_0 = 1; - 8'h0E: store_arp_spa_3 = 1; - 8'h0F: store_arp_spa_2 = 1; - 8'h10: store_arp_spa_1 = 1; - 8'h11: store_arp_spa_0 = 1; - 8'h12: store_arp_tha_5 = 1; - 8'h13: store_arp_tha_4 = 1; - 8'h14: store_arp_tha_3 = 1; - 8'h15: store_arp_tha_2 = 1; - 8'h16: store_arp_tha_1 = 1; - 8'h17: store_arp_tha_0 = 1; - 8'h18: store_arp_tpa_3 = 1; - 8'h19: store_arp_tpa_2 = 1; - 8'h1A: store_arp_tpa_1 = 1; + 8'h00: store_arp_htype_1 = 1'b1; + 8'h01: store_arp_htype_0 = 1'b1; + 8'h02: store_arp_ptype_1 = 1'b1; + 8'h03: store_arp_ptype_0 = 1'b1; + 8'h04: store_arp_hlen = 1'b1; + 8'h05: store_arp_plen = 1'b1; + 8'h06: store_arp_oper_1 = 1'b1; + 8'h07: store_arp_oper_0 = 1'b1; + 8'h08: store_arp_sha_5 = 1'b1; + 8'h09: store_arp_sha_4 = 1'b1; + 8'h0A: store_arp_sha_3 = 1'b1; + 8'h0B: store_arp_sha_2 = 1'b1; + 8'h0C: store_arp_sha_1 = 1'b1; + 8'h0D: store_arp_sha_0 = 1'b1; + 8'h0E: store_arp_spa_3 = 1'b1; + 8'h0F: store_arp_spa_2 = 1'b1; + 8'h10: store_arp_spa_1 = 1'b1; + 8'h11: store_arp_spa_0 = 1'b1; + 8'h12: store_arp_tha_5 = 1'b1; + 8'h13: store_arp_tha_4 = 1'b1; + 8'h14: store_arp_tha_3 = 1'b1; + 8'h15: store_arp_tha_2 = 1'b1; + 8'h16: store_arp_tha_1 = 1'b1; + 8'h17: store_arp_tha_0 = 1'b1; + 8'h18: store_arp_tpa_3 = 1'b1; + 8'h19: store_arp_tpa_2 = 1'b1; + 8'h1A: store_arp_tpa_1 = 1'b1; 8'h1B: begin - store_arp_tpa_0 = 1; + store_arp_tpa_0 = 1'b1; state_next = STATE_WAIT_LAST; end endcase @@ -283,16 +283,16 @@ always @* begin // end of frame if (frame_ptr_reg != 8'h1B) begin // don't have the whole header - error_header_early_termination_next = 1; - end else if (output_arp_hlen != 6 || output_arp_plen != 4) begin + error_header_early_termination_next = 1'b1; + end else if (output_arp_hlen != 4'd6 || output_arp_plen != 4'd4) begin // lengths not valid - error_invalid_header_next = 1; + error_invalid_header_next = 1'b1; end else begin // otherwise, transfer tuser output_frame_valid_next = ~input_eth_payload_tuser; end input_eth_hdr_ready_next = ~output_frame_valid_reg; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; state_next = STATE_IDLE; end end else begin @@ -301,19 +301,19 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_eth_payload_tready_next = 1; + input_eth_payload_tready_next = 1'b1; if (input_eth_payload_tvalid) begin if (input_eth_payload_tlast) begin - if (output_arp_hlen != 6 || output_arp_plen != 4) begin + if (output_arp_hlen != 4'd6 || output_arp_plen != 4'd4) begin // lengths not valid - error_invalid_header_next = 1; + error_invalid_header_next = 1'b1; end else begin // otherwise, transfer tuser output_frame_valid_next = ~input_eth_payload_tuser; end input_eth_hdr_ready_next = ~output_frame_valid_reg; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -329,15 +329,12 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_frame_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - busy_reg <= 0; - error_header_early_termination_reg <= 0; - error_invalid_header_reg <= 0; + frame_ptr_reg <= 8'd0; + input_eth_payload_tready_reg <= 1'b0; + output_frame_valid_reg <= 1'b0; + busy_reg <= 1'b0; + error_header_early_termination_reg <= 1'b0; + error_invalid_header_reg <= 1'b0; end else begin state_reg <= state_next; @@ -352,43 +349,43 @@ always @(posedge clk) begin error_invalid_header_reg <= error_invalid_header_next; busy_reg <= state_next != STATE_IDLE; - - // datapath - if (store_eth_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - end - - if (store_arp_htype_0) output_arp_htype_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_htype_1) output_arp_htype_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_ptype_0) output_arp_ptype_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_ptype_1) output_arp_ptype_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_hlen) output_arp_hlen_reg <= input_eth_payload_tdata; - if (store_arp_plen) output_arp_plen_reg <= input_eth_payload_tdata; - if (store_arp_oper_0) output_arp_oper_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_oper_1) output_arp_oper_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_sha_0) output_arp_sha_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_sha_1) output_arp_sha_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_sha_2) output_arp_sha_reg[23:16] <= input_eth_payload_tdata; - if (store_arp_sha_3) output_arp_sha_reg[31:24] <= input_eth_payload_tdata; - if (store_arp_sha_4) output_arp_sha_reg[39:32] <= input_eth_payload_tdata; - if (store_arp_sha_5) output_arp_sha_reg[47:40] <= input_eth_payload_tdata; - if (store_arp_spa_0) output_arp_spa_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_spa_1) output_arp_spa_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_spa_2) output_arp_spa_reg[23:16] <= input_eth_payload_tdata; - if (store_arp_spa_3) output_arp_spa_reg[31:24] <= input_eth_payload_tdata; - if (store_arp_tha_0) output_arp_tha_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_tha_1) output_arp_tha_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_tha_2) output_arp_tha_reg[23:16] <= input_eth_payload_tdata; - if (store_arp_tha_3) output_arp_tha_reg[31:24] <= input_eth_payload_tdata; - if (store_arp_tha_4) output_arp_tha_reg[39:32] <= input_eth_payload_tdata; - if (store_arp_tha_5) output_arp_tha_reg[47:40] <= input_eth_payload_tdata; - if (store_arp_tpa_0) output_arp_tpa_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_tpa_1) output_arp_tpa_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_tpa_2) output_arp_tpa_reg[23:16] <= input_eth_payload_tdata; - if (store_arp_tpa_3) output_arp_tpa_reg[31:24] <= input_eth_payload_tdata; end + + // datapath + if (store_eth_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + end + + if (store_arp_htype_0) output_arp_htype_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_htype_1) output_arp_htype_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_ptype_0) output_arp_ptype_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_ptype_1) output_arp_ptype_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_hlen) output_arp_hlen_reg <= input_eth_payload_tdata; + if (store_arp_plen) output_arp_plen_reg <= input_eth_payload_tdata; + if (store_arp_oper_0) output_arp_oper_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_oper_1) output_arp_oper_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_sha_0) output_arp_sha_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_sha_1) output_arp_sha_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_sha_2) output_arp_sha_reg[23:16] <= input_eth_payload_tdata; + if (store_arp_sha_3) output_arp_sha_reg[31:24] <= input_eth_payload_tdata; + if (store_arp_sha_4) output_arp_sha_reg[39:32] <= input_eth_payload_tdata; + if (store_arp_sha_5) output_arp_sha_reg[47:40] <= input_eth_payload_tdata; + if (store_arp_spa_0) output_arp_spa_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_spa_1) output_arp_spa_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_spa_2) output_arp_spa_reg[23:16] <= input_eth_payload_tdata; + if (store_arp_spa_3) output_arp_spa_reg[31:24] <= input_eth_payload_tdata; + if (store_arp_tha_0) output_arp_tha_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_tha_1) output_arp_tha_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_tha_2) output_arp_tha_reg[23:16] <= input_eth_payload_tdata; + if (store_arp_tha_3) output_arp_tha_reg[31:24] <= input_eth_payload_tdata; + if (store_arp_tha_4) output_arp_tha_reg[39:32] <= input_eth_payload_tdata; + if (store_arp_tha_5) output_arp_tha_reg[47:40] <= input_eth_payload_tdata; + if (store_arp_tpa_0) output_arp_tpa_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_arp_tpa_1) output_arp_tpa_reg[15: 8] <= input_eth_payload_tdata; + if (store_arp_tpa_2) output_arp_tpa_reg[23:16] <= input_eth_payload_tdata; + if (store_arp_tpa_3) output_arp_tpa_reg[31:24] <= input_eth_payload_tdata; end endmodule diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index 64579d82d..1c4e6d9ae 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -113,28 +113,28 @@ reg store_arp_hdr_word_1; reg store_arp_hdr_word_2; reg store_arp_hdr_word_3; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; -reg output_frame_valid_reg = 0, output_frame_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; -reg [15:0] output_arp_htype_reg = 0; -reg [15:0] output_arp_ptype_reg = 0; -reg [7:0] output_arp_hlen_reg = 0; -reg [7:0] output_arp_plen_reg = 0; -reg [15:0] output_arp_oper_reg = 0; -reg [47:0] output_arp_sha_reg = 0; -reg [31:0] output_arp_spa_reg = 0; -reg [47:0] output_arp_tha_reg = 0; -reg [31:0] output_arp_tpa_reg = 0; +reg output_frame_valid_reg = 1'b0, output_frame_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; +reg [15:0] output_arp_htype_reg = 16'd0; +reg [15:0] output_arp_ptype_reg = 16'd0; +reg [7:0] output_arp_hlen_reg = 8'd0; +reg [7:0] output_arp_plen_reg = 8'd0; +reg [15:0] output_arp_oper_reg = 16'd0; +reg [47:0] output_arp_sha_reg = 48'd0; +reg [31:0] output_arp_spa_reg = 32'd0; +reg [47:0] output_arp_tha_reg = 48'd0; +reg [31:0] output_arp_tpa_reg = 32'd0; -reg busy_reg = 0; -reg error_header_early_termination_reg = 0, error_header_early_termination_next; -reg error_invalid_header_reg = 0, error_invalid_header_next; +reg busy_reg = 1'b0; +reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; +reg error_invalid_header_reg = 1'b0, error_invalid_header_next; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; @@ -160,32 +160,32 @@ assign error_invalid_header = error_invalid_header_reg; always @* begin state_next = STATE_IDLE; - input_eth_hdr_ready_next = 0; - input_eth_payload_tready_next = 0; + input_eth_hdr_ready_next = 1'b0; + input_eth_payload_tready_next = 1'b0; - store_eth_hdr = 0; - store_arp_hdr_word_0 = 0; - store_arp_hdr_word_1 = 0; - store_arp_hdr_word_2 = 0; - store_arp_hdr_word_3 = 0; + store_eth_hdr = 1'b0; + store_arp_hdr_word_0 = 1'b0; + store_arp_hdr_word_1 = 1'b0; + store_arp_hdr_word_2 = 1'b0; + store_arp_hdr_word_3 = 1'b0; frame_ptr_next = frame_ptr_reg; output_frame_valid_next = output_frame_valid_reg & ~output_frame_ready; - error_header_early_termination_next = 0; - error_invalid_header_next = 0; + error_header_early_termination_next = 1'b0; + error_invalid_header_next = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; + frame_ptr_next = 8'd0; input_eth_hdr_ready_next = ~output_frame_valid_reg; if (input_eth_hdr_ready & input_eth_hdr_valid) begin - input_eth_hdr_ready_next = 0; - input_eth_payload_tready_next = 1; - store_eth_hdr = 1; + input_eth_hdr_ready_next = 1'b0; + input_eth_payload_tready_next = 1'b1; + store_eth_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin state_next = STATE_IDLE; @@ -193,31 +193,31 @@ always @* begin end STATE_READ_HEADER: begin // read header state - input_eth_payload_tready_next = 1; + input_eth_payload_tready_next = 1'b1; if (input_eth_payload_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg+1; + frame_ptr_next = frame_ptr_reg + 8'd1; state_next = STATE_READ_HEADER; case (frame_ptr_reg) - 8'h00: store_arp_hdr_word_0 = 1; - 8'h01: store_arp_hdr_word_1 = 1; - 8'h02: store_arp_hdr_word_2 = 1; + 8'h00: store_arp_hdr_word_0 = 1'b1; + 8'h01: store_arp_hdr_word_1 = 1'b1; + 8'h02: store_arp_hdr_word_2 = 1'b1; 8'h03: begin - store_arp_hdr_word_3 = 1; + store_arp_hdr_word_3 = 1'b1; state_next = STATE_WAIT_LAST; end endcase if (input_eth_payload_tlast) begin if (frame_ptr_reg != 8'h03 | (input_eth_payload_tkeep & 8'h0F) != 8'h0F) begin - error_header_early_termination_next = 1; - end else if (output_arp_hlen != 6 || output_arp_plen != 4) begin - error_invalid_header_next = 1; + error_header_early_termination_next = 1'b1; + end else if (output_arp_hlen != 4'd6 || output_arp_plen != 4'd4) begin + error_invalid_header_next = 1'b1; end else begin output_frame_valid_next = ~input_eth_payload_tuser; end input_eth_hdr_ready_next = ~output_frame_valid_reg; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; state_next = STATE_IDLE; end end else begin @@ -226,19 +226,19 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_eth_payload_tready_next = 1; + input_eth_payload_tready_next = 1'b1; if (input_eth_payload_tvalid) begin if (input_eth_payload_tlast) begin - if (output_arp_hlen != 6 || output_arp_plen != 4) begin + if (output_arp_hlen != 4'd6 || output_arp_plen != 4'd4) begin // lengths not valid - error_invalid_header_next = 1; + error_invalid_header_next = 1'b1; end else begin // otherwise, transfer tuser output_frame_valid_next = ~input_eth_payload_tuser; end input_eth_hdr_ready_next = ~output_frame_valid_reg; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -254,15 +254,12 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_frame_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - busy_reg <= 0; - error_header_early_termination_reg <= 0; - error_invalid_header_reg <= 0; + frame_ptr_reg <= 8'd0; + input_eth_payload_tready_reg <= 1'b0; + output_frame_valid_reg <= 1'b0; + busy_reg <= 1'b0; + error_header_early_termination_reg <= 1'b0; + error_invalid_header_reg <= 1'b0; end else begin state_reg <= state_next; @@ -277,50 +274,50 @@ always @(posedge clk) begin error_invalid_header_reg <= error_invalid_header_next; busy_reg <= state_next != STATE_IDLE; + end - // datapath - if (store_eth_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - end + // datapath + if (store_eth_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + end - if (store_arp_hdr_word_0) begin - output_arp_htype_reg[15: 8] <= input_eth_payload_tdata[ 7: 0]; - output_arp_htype_reg[ 7: 0] <= input_eth_payload_tdata[15: 8]; - output_arp_ptype_reg[15: 8] <= input_eth_payload_tdata[23:16]; - output_arp_ptype_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; - output_arp_hlen_reg <= input_eth_payload_tdata[39:32]; - output_arp_plen_reg <= input_eth_payload_tdata[47:40]; - output_arp_oper_reg[15: 8] <= input_eth_payload_tdata[55:48]; - output_arp_oper_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; - end - if (store_arp_hdr_word_1) begin - output_arp_sha_reg[47:40] <= input_eth_payload_tdata[ 7: 0]; - output_arp_sha_reg[39:32] <= input_eth_payload_tdata[15: 8]; - output_arp_sha_reg[31:24] <= input_eth_payload_tdata[23:16]; - output_arp_sha_reg[23:16] <= input_eth_payload_tdata[31:24]; - output_arp_sha_reg[15: 8] <= input_eth_payload_tdata[39:32]; - output_arp_sha_reg[ 7: 0] <= input_eth_payload_tdata[47:40]; - output_arp_spa_reg[31:24] <= input_eth_payload_tdata[55:48]; - output_arp_spa_reg[23:16] <= input_eth_payload_tdata[63:56]; - end - if (store_arp_hdr_word_2) begin - output_arp_spa_reg[15: 8] <= input_eth_payload_tdata[ 7: 0]; - output_arp_spa_reg[ 7: 0] <= input_eth_payload_tdata[15: 8]; - output_arp_tha_reg[47:40] <= input_eth_payload_tdata[23:16]; - output_arp_tha_reg[39:32] <= input_eth_payload_tdata[31:24]; - output_arp_tha_reg[31:24] <= input_eth_payload_tdata[39:32]; - output_arp_tha_reg[23:16] <= input_eth_payload_tdata[47:40]; - output_arp_tha_reg[15: 8] <= input_eth_payload_tdata[55:48]; - output_arp_tha_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; - end - if (store_arp_hdr_word_3) begin - output_arp_tpa_reg[31:24] <= input_eth_payload_tdata[ 7: 0]; - output_arp_tpa_reg[23:16] <= input_eth_payload_tdata[15: 8]; - output_arp_tpa_reg[15: 8] <= input_eth_payload_tdata[23:16]; - output_arp_tpa_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; - end + if (store_arp_hdr_word_0) begin + output_arp_htype_reg[15: 8] <= input_eth_payload_tdata[ 7: 0]; + output_arp_htype_reg[ 7: 0] <= input_eth_payload_tdata[15: 8]; + output_arp_ptype_reg[15: 8] <= input_eth_payload_tdata[23:16]; + output_arp_ptype_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + output_arp_hlen_reg <= input_eth_payload_tdata[39:32]; + output_arp_plen_reg <= input_eth_payload_tdata[47:40]; + output_arp_oper_reg[15: 8] <= input_eth_payload_tdata[55:48]; + output_arp_oper_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; + end + if (store_arp_hdr_word_1) begin + output_arp_sha_reg[47:40] <= input_eth_payload_tdata[ 7: 0]; + output_arp_sha_reg[39:32] <= input_eth_payload_tdata[15: 8]; + output_arp_sha_reg[31:24] <= input_eth_payload_tdata[23:16]; + output_arp_sha_reg[23:16] <= input_eth_payload_tdata[31:24]; + output_arp_sha_reg[15: 8] <= input_eth_payload_tdata[39:32]; + output_arp_sha_reg[ 7: 0] <= input_eth_payload_tdata[47:40]; + output_arp_spa_reg[31:24] <= input_eth_payload_tdata[55:48]; + output_arp_spa_reg[23:16] <= input_eth_payload_tdata[63:56]; + end + if (store_arp_hdr_word_2) begin + output_arp_spa_reg[15: 8] <= input_eth_payload_tdata[ 7: 0]; + output_arp_spa_reg[ 7: 0] <= input_eth_payload_tdata[15: 8]; + output_arp_tha_reg[47:40] <= input_eth_payload_tdata[23:16]; + output_arp_tha_reg[39:32] <= input_eth_payload_tdata[31:24]; + output_arp_tha_reg[31:24] <= input_eth_payload_tdata[39:32]; + output_arp_tha_reg[23:16] <= input_eth_payload_tdata[47:40]; + output_arp_tha_reg[15: 8] <= input_eth_payload_tdata[55:48]; + output_arp_tha_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; + end + if (store_arp_hdr_word_3) begin + output_arp_tpa_reg[31:24] <= input_eth_payload_tdata[ 7: 0]; + output_arp_tpa_reg[23:16] <= input_eth_payload_tdata[15: 8]; + output_arp_tpa_reg[15: 8] <= input_eth_payload_tdata[23:16]; + output_arp_tpa_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; end end diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index 4e42473b8..e0674be27 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014 -2015Alex 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 @@ -102,32 +102,32 @@ reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_frame; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg [15:0] arp_htype_reg = 0; -reg [15:0] arp_ptype_reg = 0; -reg [15:0] arp_oper_reg = 0; -reg [47:0] arp_sha_reg = 0; -reg [31:0] arp_spa_reg = 0; -reg [47:0] arp_tha_reg = 0; -reg [31:0] arp_tpa_reg = 0; +reg [15:0] arp_htype_reg = 16'd0; +reg [15:0] arp_ptype_reg = 16'd0; +reg [15:0] arp_oper_reg = 16'd0; +reg [47:0] arp_sha_reg = 48'd0; +reg [31:0] arp_spa_reg = 32'd0; +reg [47:0] arp_tha_reg = 48'd0; +reg [31:0] arp_tpa_reg = 32'd0; -reg input_frame_ready_reg = 0, input_frame_ready_next; +reg input_frame_ready_reg = 1'b0, input_frame_ready_next; -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; -reg busy_reg = 0; +reg busy_reg = 1'b0; // internal datapath -reg [7:0] output_eth_payload_tdata_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; +reg [7:0] output_eth_payload_tdata_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int_reg = 1'b0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; assign input_frame_ready = input_frame_ready_reg; @@ -141,33 +141,33 @@ assign busy = busy_reg; always @* begin state_next = STATE_IDLE; - input_frame_ready_next = 0; + input_frame_ready_next = 1'b0; - store_frame = 0; + store_frame = 1'b0; frame_ptr_next = frame_ptr_reg; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - output_eth_payload_tdata_int = 0; - output_eth_payload_tvalid_int = 0; - output_eth_payload_tlast_int = 0; - output_eth_payload_tuser_int = 0; + output_eth_payload_tdata_int = 8'd0; + output_eth_payload_tvalid_int = 1'b0; + output_eth_payload_tlast_int = 1'b0; + output_eth_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; + frame_ptr_next = 8'd0; input_frame_ready_next = ~output_eth_hdr_valid_reg; if (input_frame_ready & input_frame_valid) begin - store_frame = 1; - input_frame_ready_next = 0; - output_eth_hdr_valid_next = 1; - if (output_eth_payload_tready_int) begin - output_eth_payload_tvalid_int = 1; + store_frame = 1'b1; + input_frame_ready_next = 1'b0; + output_eth_hdr_valid_next = 1'b1; + if (output_eth_payload_tready_int_reg) begin + output_eth_payload_tvalid_int = 1'b1; output_eth_payload_tdata_int = input_arp_htype[15: 8]; - frame_ptr_next = 1; + frame_ptr_next = 8'd1; end state_next = STATE_WRITE_HEADER; end else begin @@ -176,17 +176,17 @@ always @* begin end STATE_WRITE_HEADER: begin // read header state - if (output_eth_payload_tready_int) begin + if (output_eth_payload_tready_int_reg) begin // word transfer out - frame_ptr_next = frame_ptr_reg+1; - output_eth_payload_tvalid_int = 1; + frame_ptr_next = frame_ptr_reg + 8'd1; + output_eth_payload_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h01: output_eth_payload_tdata_int = arp_htype_reg[ 7: 0]; 8'h02: output_eth_payload_tdata_int = arp_ptype_reg[15: 8]; 8'h03: output_eth_payload_tdata_int = arp_ptype_reg[ 7: 0]; - 8'h04: output_eth_payload_tdata_int = 6; // hlen - 8'h05: output_eth_payload_tdata_int = 4; // plen + 8'h04: output_eth_payload_tdata_int = 8'd6; // hlen + 8'h05: output_eth_payload_tdata_int = 8'd4; // plen 8'h06: output_eth_payload_tdata_int = arp_oper_reg[15: 8]; 8'h07: output_eth_payload_tdata_int = arp_oper_reg[ 7: 0]; 8'h08: output_eth_payload_tdata_int = arp_sha_reg[47:40]; @@ -210,7 +210,7 @@ always @* begin 8'h1A: output_eth_payload_tdata_int = arp_tpa_reg[15: 8]; 8'h1B: begin output_eth_payload_tdata_int = arp_tpa_reg[ 7: 0]; - output_eth_payload_tlast_int = 1; + output_eth_payload_tlast_int = 1'b1; input_frame_ready_next = ~output_eth_hdr_valid_reg; state_next = STATE_IDLE; end @@ -225,19 +225,10 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - input_frame_ready_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - arp_htype_reg <= 0; - arp_ptype_reg <= 0; - arp_oper_reg <= 0; - arp_sha_reg <= 0; - arp_spa_reg <= 0; - arp_tha_reg <= 0; - arp_tpa_reg <= 0; - busy_reg <= 0; + frame_ptr_reg <= 8'd0; + input_frame_ready_reg <= 1'b0; + output_eth_hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; end else begin state_reg <= state_next; @@ -248,82 +239,100 @@ always @(posedge clk) begin output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; + end - if (store_frame) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - arp_htype_reg <= input_arp_htype; - arp_ptype_reg <= input_arp_ptype; - arp_oper_reg <= input_arp_oper; - arp_sha_reg <= input_arp_sha; - arp_spa_reg <= input_arp_spa; - arp_tha_reg <= input_arp_tha; - arp_tpa_reg <= input_arp_tpa; - end + if (store_frame) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + arp_htype_reg <= input_arp_htype; + arp_ptype_reg <= input_arp_ptype; + arp_oper_reg <= input_arp_oper; + arp_sha_reg <= input_arp_sha; + arp_spa_reg <= input_arp_spa; + arp_tha_reg <= input_arp_tha; + arp_tpa_reg <= input_arp_tpa; end end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [7:0] output_eth_payload_tdata_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [7:0] temp_eth_payload_tdata_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_eth_payload_tdata_int; - temp_axis_tvalid_reg <= output_eth_payload_tvalid_int; - temp_axis_tlast_reg <= output_eth_payload_tlast_int; - temp_axis_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_axis_tdata_reg; - output_eth_payload_tvalid_reg <= temp_axis_tvalid_reg; - output_eth_payload_tlast_reg <= temp_axis_tlast_reg; - output_eth_payload_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index 197c14c29..64c0e5660 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -103,30 +103,30 @@ reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_frame; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg [15:0] arp_htype_reg = 0; -reg [15:0] arp_ptype_reg = 0; -reg [15:0] arp_oper_reg = 0; -reg [47:0] arp_sha_reg = 0; -reg [31:0] arp_spa_reg = 0; -reg [47:0] arp_tha_reg = 0; -reg [31:0] arp_tpa_reg = 0; +reg [15:0] arp_htype_reg = 16'd0; +reg [15:0] arp_ptype_reg = 16'd0; +reg [15:0] arp_oper_reg = 16'd0; +reg [47:0] arp_sha_reg = 48'd0; +reg [31:0] arp_spa_reg = 32'd0; +reg [47:0] arp_tha_reg = 48'd0; +reg [31:0] arp_tpa_reg = 32'd0; -reg input_frame_ready_reg = 0, input_frame_ready_next; +reg input_frame_ready_reg = 1'b0, input_frame_ready_next; -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; -reg busy_reg = 0; +reg busy_reg = 1'b0; // internal datapath reg [63:0] output_eth_payload_tdata_int; reg [7:0] output_eth_payload_tkeep_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -143,42 +143,42 @@ assign busy = busy_reg; always @* begin state_next = STATE_IDLE; - input_frame_ready_next = 0; + input_frame_ready_next = 1'b0; - store_frame = 0; + store_frame = 1'b0; frame_ptr_next = frame_ptr_reg; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - output_eth_payload_tdata_int = 0; - output_eth_payload_tkeep_int = 0; - output_eth_payload_tvalid_int = 0; - output_eth_payload_tlast_int = 0; - output_eth_payload_tuser_int = 0; + output_eth_payload_tdata_int = 64'd0; + output_eth_payload_tkeep_int = 8'd0; + output_eth_payload_tvalid_int = 1'b0; + output_eth_payload_tlast_int = 1'b0; + output_eth_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; + frame_ptr_next = 8'd0; input_frame_ready_next = ~output_eth_hdr_valid_reg; if (input_frame_ready & input_frame_valid) begin - store_frame = 1; - input_frame_ready_next = 0; - output_eth_hdr_valid_next = 1; - if (output_eth_payload_tready_int) begin - output_eth_payload_tvalid_int = 1; + store_frame = 1'b1; + input_frame_ready_next = 1'b0; + output_eth_hdr_valid_next = 1'b1; + if (output_eth_payload_tready_int_reg) begin + output_eth_payload_tvalid_int = 1'b1; output_eth_payload_tdata_int[ 7: 0] = input_arp_htype[15: 8]; output_eth_payload_tdata_int[15: 8] = input_arp_htype[ 7: 0]; output_eth_payload_tdata_int[23:16] = input_arp_ptype[15: 8]; output_eth_payload_tdata_int[31:24] = input_arp_ptype[ 7: 0]; - output_eth_payload_tdata_int[39:32] = 6; // hlen - output_eth_payload_tdata_int[47:40] = 4; // plen + output_eth_payload_tdata_int[39:32] = 8'd6; // hlen + output_eth_payload_tdata_int[47:40] = 8'd4; // plen output_eth_payload_tdata_int[55:48] = input_arp_oper[15: 8]; output_eth_payload_tdata_int[63:56] = input_arp_oper[ 7: 0]; output_eth_payload_tkeep_int = 8'hff; - frame_ptr_next = 8; + frame_ptr_next = 8'd8; end state_next = STATE_WRITE_HEADER; end else begin @@ -187,10 +187,10 @@ always @* begin end STATE_WRITE_HEADER: begin // read header state - if (output_eth_payload_tready_int) begin + if (output_eth_payload_tready_int_reg) begin // word transfer out - frame_ptr_next = frame_ptr_reg+8; - output_eth_payload_tvalid_int = 1; + frame_ptr_next = frame_ptr_reg + 8'd8; + output_eth_payload_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: begin @@ -198,8 +198,8 @@ always @* begin output_eth_payload_tdata_int[15: 8] = input_arp_htype[ 7: 0]; output_eth_payload_tdata_int[23:16] = input_arp_ptype[15: 8]; output_eth_payload_tdata_int[31:24] = input_arp_ptype[ 7: 0]; - output_eth_payload_tdata_int[39:32] = 6; // hlen - output_eth_payload_tdata_int[47:40] = 4; // plen + output_eth_payload_tdata_int[39:32] = 8'd6; // hlen + output_eth_payload_tdata_int[47:40] = 8'd4; // plen output_eth_payload_tdata_int[55:48] = input_arp_oper[15: 8]; output_eth_payload_tdata_int[63:56] = input_arp_oper[ 7: 0]; output_eth_payload_tkeep_int = 8'hff; @@ -236,7 +236,7 @@ always @* begin output_eth_payload_tdata_int[55:48] = 0; output_eth_payload_tdata_int[63:56] = 0; output_eth_payload_tkeep_int = 8'h0f; - output_eth_payload_tlast_int = 1; + output_eth_payload_tlast_int = 1'b1; input_frame_ready_next = ~output_eth_hdr_valid_reg; state_next = STATE_IDLE; end @@ -251,19 +251,10 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - input_frame_ready_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - arp_htype_reg <= 0; - arp_ptype_reg <= 0; - arp_oper_reg <= 0; - arp_sha_reg <= 0; - arp_spa_reg <= 0; - arp_tha_reg <= 0; - arp_tpa_reg <= 0; - busy_reg <= 0; + frame_ptr_reg <= 8'd0; + input_frame_ready_reg <= 1'b0; + output_eth_hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; end else begin state_reg <= state_next; @@ -274,37 +265,39 @@ always @(posedge clk) begin output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; + end - if (store_frame) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - arp_htype_reg <= input_arp_htype; - arp_ptype_reg <= input_arp_ptype; - arp_oper_reg <= input_arp_oper; - arp_sha_reg <= input_arp_sha; - arp_spa_reg <= input_arp_spa; - arp_tha_reg <= input_arp_tha; - arp_tpa_reg <= input_arp_tpa; - end + if (store_frame) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + arp_htype_reg <= input_arp_htype; + arp_ptype_reg <= input_arp_ptype; + arp_oper_reg <= input_arp_oper; + arp_sha_reg <= input_arp_sha; + arp_spa_reg <= input_arp_spa; + arp_tha_reg <= input_arp_tha; + arp_tpa_reg <= input_arp_tpa; end end // output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [64:0] output_eth_payload_tdata_reg = 64'd0; +reg [7:0] output_eth_payload_tkeep_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [63:0] temp_eth_payload_tdata_reg = 0; -reg [7:0] temp_eth_payload_tkeep_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [64:0] temp_eth_payload_tdata_reg = 64'd0; +reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; @@ -312,53 +305,66 @@ assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tkeep_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/axis_eth_fcs.v b/rtl/axis_eth_fcs.v index fb24ae32c..4d099bc0d 100644 --- a/rtl/axis_eth_fcs.v +++ b/rtl/axis_eth_fcs.v @@ -51,8 +51,8 @@ module axis_eth_fcs ); reg [31:0] crc_state = 32'hFFFFFFFF; -reg [31:0] fcs_reg = 0; -reg fcs_valid_reg = 0; +reg [31:0] fcs_reg = 32'h00000000; +reg fcs_valid_reg = 1'b0; wire [31:0] crc_next; @@ -70,15 +70,15 @@ eth_crc_8_inst ( always @(posedge clk) begin if (rst) begin crc_state <= 32'hFFFFFFFF; - fcs_reg <= 0; - fcs_valid_reg <= 0; + fcs_reg <= 32'h00000000; + fcs_valid_reg <= 1'b0; end else begin - fcs_valid_reg <= 0; + fcs_valid_reg <= 1'b0; if (input_axis_tvalid) begin if (input_axis_tlast) begin crc_state <= 32'hFFFFFFFF; fcs_reg <= ~crc_next; - fcs_valid_reg <= 1; + fcs_valid_reg <= 1'b1; end else begin crc_state <= crc_next; end diff --git a/rtl/axis_eth_fcs_64.v b/rtl/axis_eth_fcs_64.v index 4dacede72..629d77bd0 100644 --- a/rtl/axis_eth_fcs_64.v +++ b/rtl/axis_eth_fcs_64.v @@ -52,8 +52,8 @@ module axis_eth_fcs_64 ); reg [31:0] crc_state = 32'hFFFFFFFF; -reg [31:0] fcs_reg = 0; -reg fcs_valid_reg = 0; +reg [31:0] fcs_reg = 32'h00000000; +reg fcs_valid_reg = 1'b0; wire [31:0] crc_next0; wire [31:0] crc_next1; @@ -64,7 +64,7 @@ wire [31:0] crc_next5; wire [31:0] crc_next6; wire [31:0] crc_next7; -assign input_axis_tready = 1; +assign input_axis_tready = 1'b1; assign output_fcs = fcs_reg; assign output_fcs_valid = fcs_valid_reg; @@ -127,10 +127,10 @@ eth_crc_64_inst ( always @(posedge clk) begin if (rst) begin crc_state <= 32'hFFFFFFFF; - fcs_reg <= 0; - fcs_valid_reg <= 0; + fcs_reg <= 1'b0; + fcs_valid_reg <= 1'b0; end else begin - fcs_valid_reg <= 0; + fcs_valid_reg <= 1'b0; if (input_axis_tvalid) begin if (input_axis_tlast) begin crc_state <= 32'hFFFFFFFF; @@ -144,7 +144,7 @@ always @(posedge clk) begin 8'b01111111: fcs_reg <= ~crc_next6; 8'b11111111: fcs_reg <= ~crc_next7; endcase - fcs_valid_reg <= 1; + fcs_valid_reg <= 1'b1; end else begin crc_state <= crc_next7; end diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v index b83f7c752..044427a2f 100644 --- a/rtl/axis_eth_fcs_check.v +++ b/rtl/axis_eth_fcs_check.v @@ -71,33 +71,31 @@ reg update_crc; reg shift_in; reg shift_reset; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [7:0] input_axis_tdata_d0 = 8'd0; +reg [7:0] input_axis_tdata_d1 = 8'd0; +reg [7:0] input_axis_tdata_d2 = 8'd0; +reg [7:0] input_axis_tdata_d3 = 8'd0; -reg [7:0] input_axis_tdata_d0 = 0; -reg [7:0] input_axis_tdata_d1 = 0; -reg [7:0] input_axis_tdata_d2 = 0; -reg [7:0] input_axis_tdata_d3 = 0; +reg input_axis_tvalid_d0 = 1'b0; +reg input_axis_tvalid_d1 = 1'b0; +reg input_axis_tvalid_d2 = 1'b0; +reg input_axis_tvalid_d3 = 1'b0; -reg input_axis_tvalid_d0 = 0; -reg input_axis_tvalid_d1 = 0; -reg input_axis_tvalid_d2 = 0; -reg input_axis_tvalid_d3 = 0; +reg busy_reg = 1'b0; +reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; -reg busy_reg = 0; -reg error_bad_fcs_reg = 0, error_bad_fcs_next; - -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; // internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; assign input_axis_tready = input_axis_tready_reg; @@ -114,49 +112,45 @@ eth_crc_8_inst ( always @* begin state_next = STATE_IDLE; - reset_crc = 0; - update_crc = 0; - shift_in = 0; - shift_reset = 0; + reset_crc = 1'b0; + update_crc = 1'b0; + shift_in = 1'b0; + shift_reset = 1'b0; - frame_ptr_next = frame_ptr_reg; + input_axis_tready_next = 1'b0; - input_axis_tready_next = 0; + output_axis_tdata_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; - output_axis_tdata_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; - - error_bad_fcs_next = 0; + error_bad_fcs_next = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data input_axis_tready_next = output_axis_tready_int_early; - frame_ptr_next = 0; - reset_crc = 1; + reset_crc = 1'b1; output_axis_tdata_int = input_axis_tdata_d3; output_axis_tvalid_int = input_axis_tvalid_d3 & input_axis_tvalid; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; if (input_axis_tready & input_axis_tvalid) begin - shift_in = 1; + shift_in = 1'b1; if (input_axis_tvalid_d3) begin - frame_ptr_next = 1; - reset_crc = 0; - update_crc = 1; + reset_crc = 1'b0; + update_crc = 1'b1; if (input_axis_tlast) begin - shift_reset = 1; - reset_crc = 1; - output_axis_tlast_int = 1; + shift_reset = 1'b1; + reset_crc = 1'b1; + output_axis_tlast_int = 1'b1; output_axis_tuser_int = input_axis_tuser; if ({input_axis_tdata, input_axis_tdata_d0, input_axis_tdata_d1, input_axis_tdata_d2} != ~crc_next) begin - output_axis_tuser_int = 1; - error_bad_fcs_next = 1; + output_axis_tuser_int = 1'b1; + error_bad_fcs_next = 1'b1; end input_axis_tready_next = output_axis_tready_int_early; state_next = STATE_IDLE; @@ -176,21 +170,20 @@ always @* begin output_axis_tdata_int = input_axis_tdata_d3; output_axis_tvalid_int = input_axis_tvalid_d3 & input_axis_tvalid; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; if (input_axis_tready & input_axis_tvalid) begin - frame_ptr_next = frame_ptr_reg + 1; - shift_in = 1; - update_crc = 1; + shift_in = 1'b1; + update_crc = 1'b1; if (input_axis_tlast) begin - shift_reset = 1; - reset_crc = 1; - output_axis_tlast_int = 1; + shift_reset = 1'b1; + reset_crc = 1'b1; + output_axis_tlast_int = 1'b1; output_axis_tuser_int = input_axis_tuser; if ({input_axis_tdata, input_axis_tdata_d0, input_axis_tdata_d1, input_axis_tdata_d2} != ~crc_next) begin - output_axis_tuser_int = 1; - error_bad_fcs_next = 1; + output_axis_tuser_int = 1'b1; + error_bad_fcs_next = 1'b1; end input_axis_tready_next = output_axis_tready_int_early; state_next = STATE_IDLE; @@ -207,20 +200,21 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - - frame_ptr_reg <= 0; - - input_axis_tready_reg <= 0; - busy_reg <= 0; - error_bad_fcs_reg <= 0; + input_axis_tready_reg <= 1'b0; + + busy_reg <= 1'b0; + error_bad_fcs_reg <= 1'b0; + + input_axis_tvalid_d0 <= 1'b0; + input_axis_tvalid_d1 <= 1'b0; + input_axis_tvalid_d2 <= 1'b0; + input_axis_tvalid_d3 <= 1'b0; crc_state <= 32'hFFFFFFFF; end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; - input_axis_tready_reg <= input_axis_tready_next; busy_reg <= state_next != STATE_IDLE; @@ -234,84 +228,104 @@ always @(posedge clk) begin end if (shift_reset) begin - input_axis_tvalid_d0 <= 0; - input_axis_tvalid_d1 <= 0; - input_axis_tvalid_d2 <= 0; - input_axis_tvalid_d3 <= 0; + input_axis_tvalid_d0 <= 1'b0; + input_axis_tvalid_d1 <= 1'b0; + input_axis_tvalid_d2 <= 1'b0; + input_axis_tvalid_d3 <= 1'b0; end else if (shift_in) begin - input_axis_tdata_d0 <= input_axis_tdata; - input_axis_tdata_d1 <= input_axis_tdata_d0; - input_axis_tdata_d2 <= input_axis_tdata_d1; - input_axis_tdata_d3 <= input_axis_tdata_d2; - input_axis_tvalid_d0 <= input_axis_tvalid; input_axis_tvalid_d1 <= input_axis_tvalid_d0; input_axis_tvalid_d2 <= input_axis_tvalid_d1; input_axis_tvalid_d3 <= input_axis_tvalid_d2; end end + + if (shift_in) begin + input_axis_tdata_d0 <= input_axis_tdata; + input_axis_tdata_d1 <= input_axis_tdata_d0; + input_axis_tdata_d2 <= input_axis_tdata_d1; + input_axis_tdata_d3 <= input_axis_tdata_d2; + end end // output datapath logic -reg [7:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [7:0] output_axis_tdata_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [7:0] temp_axis_tdata_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index 48d0268b7..0fcc8c560 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -74,18 +74,18 @@ reg update_crc; reg shift_in; reg shift_reset; -reg [7:0] last_cycle_tkeep_reg = 0, last_cycle_tkeep_next; -reg last_cycle_tuser_reg = 0, last_cycle_tuser_next; +reg [7:0] last_cycle_tkeep_reg = 8'd0, last_cycle_tkeep_next; +reg last_cycle_tuser_reg = 1'b0, last_cycle_tuser_next; -reg [63:0] input_axis_tdata_d0 = 0; -reg [7:0] input_axis_tkeep_d0 = 0; -reg input_axis_tvalid_d0 = 0; -reg input_axis_tuser_d0 = 0; +reg [63:0] input_axis_tdata_d0 = 64'd0; +reg [7:0] input_axis_tkeep_d0 = 8'd0; +reg input_axis_tvalid_d0 = 1'b0; +reg input_axis_tuser_d0 = 1'b0; -reg busy_reg = 0; -reg error_bad_fcs_reg = 0, error_bad_fcs_next; +reg busy_reg = 1'b0; +reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state3 = 32'hFFFFFFFF; @@ -101,13 +101,11 @@ wire crc_valid1 = crc_next1 == ~32'h2144df1c; wire crc_valid2 = crc_next2 == ~32'h2144df1c; wire crc_valid3 = crc_next3 == ~32'h2144df1c; -reg [31:0] crc_check = 0; - // internal datapath reg [63:0] output_axis_tdata_int; reg [7:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -157,45 +155,45 @@ eth_crc_64_inst ( always @* begin state_next = STATE_IDLE; - reset_crc = 0; - update_crc = 0; - shift_in = 0; - shift_reset = 0; + reset_crc = 1'b0; + update_crc = 1'b0; + shift_in = 1'b0; + shift_reset = 1'b0; last_cycle_tkeep_next = last_cycle_tkeep_reg; last_cycle_tuser_next = last_cycle_tuser_reg; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; - output_axis_tdata_int = 0; - output_axis_tkeep_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = 64'd0; + output_axis_tkeep_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; - error_bad_fcs_next = 0; + error_bad_fcs_next = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data input_axis_tready_next = output_axis_tready_int_early; - reset_crc = 1; + reset_crc = 1'b1; output_axis_tdata_int = input_axis_tdata_d0; output_axis_tkeep_int = input_axis_tkeep_d0; output_axis_tvalid_int = input_axis_tvalid_d0 & input_axis_tvalid; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; if (input_axis_tready & input_axis_tvalid) begin - shift_in = 1; - reset_crc = 0; - update_crc = 1; + shift_in = 1'b1; + reset_crc = 1'b0; + update_crc = 1'b1; if (input_axis_tlast) begin if (input_axis_tkeep[7:4] == 0) begin - shift_reset = 1; - reset_crc = 1; - output_axis_tlast_int = 1; + shift_reset = 1'b1; + reset_crc = 1'b1; + output_axis_tlast_int = 1'b1; output_axis_tuser_int = input_axis_tuser; output_axis_tkeep_int = {input_axis_tkeep[3:0], 4'b1111}; if ((input_axis_tkeep[3:0] == 4'b0001 & crc_valid0) || @@ -204,15 +202,15 @@ always @* begin (input_axis_tkeep[3:0] == 4'b1111 & crc_valid3)) begin // CRC valid end else begin - output_axis_tuser_int = 1; - error_bad_fcs_next = 1; + output_axis_tuser_int = 1'b1; + error_bad_fcs_next = 1'b1; end input_axis_tready_next = output_axis_tready_int_early; state_next = STATE_IDLE; end else begin last_cycle_tkeep_next = {4'b0000, input_axis_tkeep[7:4]}; last_cycle_tuser_next = input_axis_tuser; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_LAST; end end else begin @@ -229,17 +227,17 @@ always @* begin output_axis_tdata_int = input_axis_tdata_d0; output_axis_tkeep_int = input_axis_tkeep_d0; output_axis_tvalid_int = input_axis_tvalid_d0 & input_axis_tvalid; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; if (input_axis_tready & input_axis_tvalid) begin - shift_in = 1; - update_crc = 1; + shift_in = 1'b1; + update_crc = 1'b1; if (input_axis_tlast) begin if (input_axis_tkeep[7:4] == 0) begin - shift_reset = 1; - reset_crc = 1; - output_axis_tlast_int = 1; + shift_reset = 1'b1; + reset_crc = 1'b1; + output_axis_tlast_int = 1'b1; output_axis_tuser_int = input_axis_tuser; output_axis_tkeep_int = {input_axis_tkeep[3:0], 4'b1111}; if ((input_axis_tkeep[3:0] == 4'b0001 & crc_valid0) || @@ -248,15 +246,15 @@ always @* begin (input_axis_tkeep[3:0] == 4'b1111 & crc_valid3)) begin // CRC valid end else begin - output_axis_tuser_int = 1; - error_bad_fcs_next = 1; + output_axis_tuser_int = 1'b1; + error_bad_fcs_next = 1'b1; end input_axis_tready_next = output_axis_tready_int_early; state_next = STATE_IDLE; end else begin last_cycle_tkeep_next = {4'b0000, input_axis_tkeep[7:4]}; last_cycle_tuser_next = input_axis_tuser; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_LAST; end end else begin @@ -268,12 +266,12 @@ always @* begin end STATE_LAST: begin // last cycle - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; output_axis_tdata_int = input_axis_tdata_d0; output_axis_tkeep_int = last_cycle_tkeep_reg; output_axis_tvalid_int = input_axis_tvalid_d0; - output_axis_tlast_int = 1; + output_axis_tlast_int = 1'b1; output_axis_tuser_int = last_cycle_tuser_reg; if ((input_axis_tkeep_d0[7:4] == 4'b0001 & crc_valid0) || @@ -282,13 +280,13 @@ always @* begin (input_axis_tkeep_d0[7:4] == 4'b1111 & crc_valid3)) begin // CRC valid end else begin - output_axis_tuser_int = 1; - error_bad_fcs_next = 1; + output_axis_tuser_int = 1'b1; + error_bad_fcs_next = 1'b1; end - if (output_axis_tready_int) begin - shift_reset = 1; - reset_crc = 1; + if (output_axis_tready_int_reg) begin + shift_reset = 1'b1; + reset_crc = 1'b1; input_axis_tready_next = output_axis_tready_int_early; state_next = STATE_IDLE; end else begin @@ -302,22 +300,18 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - last_cycle_tkeep_reg <= 0; - last_cycle_tuser_reg <= 0; - - input_axis_tready_reg <= 0; + input_axis_tready_reg <= 1'b0; - busy_reg <= 0; - error_bad_fcs_reg <= 0; + busy_reg <= 1'b0; + error_bad_fcs_reg <= 1'b0; + + input_axis_tvalid_d0 <= 1'b0; crc_state <= 32'hFFFFFFFF; crc_state3 <= 32'hFFFFFFFF; end else begin state_reg <= state_next; - last_cycle_tkeep_reg <= last_cycle_tkeep_next; - last_cycle_tuser_reg <= last_cycle_tuser_next; - input_axis_tready_reg <= input_axis_tready_next; busy_reg <= state_next != STATE_IDLE; @@ -333,28 +327,39 @@ always @(posedge clk) begin end if (shift_reset) begin - input_axis_tvalid_d0 <= 0; + input_axis_tvalid_d0 <= 1'b0; end else if (shift_in) begin - input_axis_tdata_d0 <= input_axis_tdata; - input_axis_tkeep_d0 <= input_axis_tkeep; input_axis_tvalid_d0 <= input_axis_tvalid; - input_axis_tuser_d0 <= input_axis_tuser; end end + + last_cycle_tkeep_reg <= last_cycle_tkeep_next; + last_cycle_tuser_reg <= last_cycle_tuser_next; + + if (shift_in) begin + input_axis_tdata_d0 <= input_axis_tdata; + input_axis_tkeep_d0 <= input_axis_tkeep; + input_axis_tuser_d0 <= input_axis_tuser; + end end // output datapath logic -reg [63:0] output_axis_tdata_reg = 0; -reg [7:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [63:0] output_axis_tdata_reg = 64'd0; +reg [7:0] output_axis_tkeep_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [63:0] temp_axis_tdata_reg = 0; -reg [7:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [63:0] temp_axis_tdata_reg = 64'd0; +reg [7:0] temp_axis_tkeep_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -362,56 +367,66 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v index 7cc839fa6..347c3d304 100644 --- a/rtl/axis_eth_fcs_insert.v +++ b/rtl/axis_eth_fcs_insert.v @@ -74,22 +74,22 @@ reg [1:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg busy_reg = 0; +reg busy_reg = 1'b0; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; // internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; assign input_axis_tready = input_axis_tready_reg; @@ -105,47 +105,47 @@ eth_crc_8_inst ( always @* begin state_next = STATE_IDLE; - reset_crc = 0; - update_crc = 0; + reset_crc = 1'b0; + update_crc = 1'b0; frame_ptr_next = frame_ptr_reg; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; - output_axis_tdata_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data input_axis_tready_next = output_axis_tready_int_early; - frame_ptr_next = 0; - reset_crc = 1; + frame_ptr_next = 16'd0; + reset_crc = 1'b1; output_axis_tdata_int = input_axis_tdata; output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; if (input_axis_tready & input_axis_tvalid) begin - frame_ptr_next = 1; - reset_crc = 0; - update_crc = 1; + frame_ptr_next = 16'd1; + reset_crc = 1'b0; + update_crc = 1'b1; if (input_axis_tlast) begin if (input_axis_tuser) begin - output_axis_tlast_int = 1; - output_axis_tuser_int = 1; - reset_crc = 1; - frame_ptr_next = 0; + output_axis_tlast_int = 1'b1; + output_axis_tuser_int = 1'b1; + reset_crc = 1'b1; + frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin state_next = STATE_PAD; end else begin - frame_ptr_next = 0; + frame_ptr_next = 16'd0; state_next = STATE_FCS; end end @@ -162,25 +162,25 @@ always @* begin output_axis_tdata_int = input_axis_tdata; output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; if (input_axis_tready & input_axis_tvalid) begin - frame_ptr_next = frame_ptr_reg + 1; - update_crc = 1; + frame_ptr_next = frame_ptr_reg + 16'd1; + update_crc = 1'b1; if (input_axis_tlast) begin if (input_axis_tuser) begin - output_axis_tlast_int = 1; - output_axis_tuser_int = 1; - reset_crc = 1; - frame_ptr_next = 0; + output_axis_tlast_int = 1'b1; + output_axis_tuser_int = 1'b1; + reset_crc = 1'b1; + frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin state_next = STATE_PAD; end else begin - frame_ptr_next = 0; + frame_ptr_next = 16'd0; state_next = STATE_FCS; end end @@ -193,20 +193,20 @@ always @* begin end STATE_PAD: begin // insert padding - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; - output_axis_tdata_int = 0; - output_axis_tvalid_int = 1; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = 8'd0; + output_axis_tvalid_int = 1'b1; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; - if (output_axis_tready_int) begin - frame_ptr_next = frame_ptr_reg + 1; - update_crc = 1; + if (output_axis_tready_int_reg) begin + frame_ptr_next = frame_ptr_reg + 16'd1; + update_crc = 1'b1; if (frame_ptr_reg < MIN_FRAME_LENGTH-5) begin state_next = STATE_PAD; end else begin - frame_ptr_next = 0; + frame_ptr_next = 16'd0; state_next = STATE_FCS; end end else begin @@ -215,7 +215,7 @@ always @* begin end STATE_FCS: begin // send FCS - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; case (frame_ptr_reg) 2'd0: output_axis_tdata_int = ~crc_state[7:0]; @@ -223,19 +223,19 @@ always @* begin 2'd2: output_axis_tdata_int = ~crc_state[23:16]; 2'd3: output_axis_tdata_int = ~crc_state[31:24]; endcase - output_axis_tvalid_int = 1; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tvalid_int = 1'b1; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; - if (output_axis_tready_int) begin - frame_ptr_next = frame_ptr_reg + 1; + if (output_axis_tready_int_reg) begin + frame_ptr_next = frame_ptr_reg + 16'd1; - if (frame_ptr_reg < 3) begin + if (frame_ptr_reg < 16'd3) begin state_next = STATE_FCS; end else begin - reset_crc = 1; - frame_ptr_next = 0; - output_axis_tlast_int = 1; + reset_crc = 1'b1; + frame_ptr_next = 16'd0; + output_axis_tlast_int = 1'b1; input_axis_tready_next = output_axis_tready_int_early; state_next = STATE_IDLE; end @@ -250,11 +250,11 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; + frame_ptr_reg <= 1'b0; - input_axis_tready_reg <= 0; + input_axis_tready_reg <= 1'b0; - busy_reg <= 0; + busy_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; end else begin @@ -276,65 +276,83 @@ always @(posedge clk) begin end // output datapath logic -reg [7:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [7:0] output_axis_tdata_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [7:0] temp_axis_tdata_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_eth_fcs_insert_64.v b/rtl/axis_eth_fcs_insert_64.v index a38453ff5..b508bffde 100644 --- a/rtl/axis_eth_fcs_insert_64.v +++ b/rtl/axis_eth_fcs_insert_64.v @@ -86,14 +86,14 @@ reg [63:0] fcs_output_tdata_1; reg [7:0] fcs_output_tkeep_0; reg [7:0] fcs_output_tkeep_1; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg [63:0] last_cycle_tdata_reg = 0, last_cycle_tdata_next; -reg [7:0] last_cycle_tkeep_reg = 0, last_cycle_tkeep_next; +reg [63:0] last_cycle_tdata_reg = 64'd0, last_cycle_tdata_next; +reg [7:0] last_cycle_tkeep_reg = 8'd0, last_cycle_tkeep_next; -reg busy_reg = 0; +reg busy_reg = 1'b0; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; @@ -110,7 +110,7 @@ wire [31:0] crc_next7; reg [63:0] output_axis_tdata_int; reg [7:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -178,15 +178,15 @@ eth_crc_64_inst ( function [3:0] keep2count; input [7:0] k; case (k) - 8'b00000000: keep2count = 0; - 8'b00000001: keep2count = 1; - 8'b00000011: keep2count = 2; - 8'b00000111: keep2count = 3; - 8'b00001111: keep2count = 4; - 8'b00011111: keep2count = 5; - 8'b00111111: keep2count = 6; - 8'b01111111: keep2count = 7; - 8'b11111111: keep2count = 8; + 8'b00000000: keep2count = 4'd0; + 8'b00000001: keep2count = 4'd1; + 8'b00000011: keep2count = 4'd2; + 8'b00000111: keep2count = 4'd3; + 8'b00001111: keep2count = 4'd4; + 8'b00011111: keep2count = 4'd5; + 8'b00111111: keep2count = 4'd6; + 8'b01111111: keep2count = 4'd7; + 8'b11111111: keep2count = 4'd8; endcase endfunction @@ -206,15 +206,12 @@ function [7:0] count2keep; endfunction // Mask input data +integer j; + always @* begin - input_axis_tdata_masked[ 7: 0] = input_axis_tkeep[0] ? input_axis_tdata[ 7: 0] : 8'd0; - input_axis_tdata_masked[15: 8] = input_axis_tkeep[1] ? input_axis_tdata[15: 8] : 8'd0; - input_axis_tdata_masked[23:16] = input_axis_tkeep[2] ? input_axis_tdata[23:16] : 8'd0; - input_axis_tdata_masked[31:24] = input_axis_tkeep[3] ? input_axis_tdata[31:24] : 8'd0; - input_axis_tdata_masked[39:32] = input_axis_tkeep[4] ? input_axis_tdata[39:32] : 8'd0; - input_axis_tdata_masked[47:40] = input_axis_tkeep[5] ? input_axis_tdata[47:40] : 8'd0; - input_axis_tdata_masked[55:48] = input_axis_tkeep[6] ? input_axis_tdata[55:48] : 8'd0; - input_axis_tdata_masked[63:56] = input_axis_tkeep[7] ? input_axis_tdata[63:56] : 8'd0; + for (j = 0; j < 8; j = j + 1) begin + input_axis_tdata_masked[j*8 +: 8] = input_axis_tkeep[j] ? input_axis_tdata[j*8 +: 8] : 8'd0; + end end // FCS cycle calculation @@ -222,25 +219,25 @@ always @* begin case (fcs_input_tkeep) 8'b00000001: begin fcs_output_tdata_0 = {24'd0, ~crc_next0[31:0], fcs_input_tdata[7:0]}; - fcs_output_tdata_1 = 0; + fcs_output_tdata_1 = 64'd0; fcs_output_tkeep_0 = 8'b00011111; fcs_output_tkeep_1 = 8'b00000000; end 8'b00000011: begin fcs_output_tdata_0 = {16'd0, ~crc_next1[31:0], fcs_input_tdata[15:0]}; - fcs_output_tdata_1 = 0; + fcs_output_tdata_1 = 64'd0; fcs_output_tkeep_0 = 8'b00111111; fcs_output_tkeep_1 = 8'b00000000; end 8'b00000111: begin fcs_output_tdata_0 = {8'd0, ~crc_next2[31:0], fcs_input_tdata[23:0]}; - fcs_output_tdata_1 = 0; + fcs_output_tdata_1 = 64'd0; fcs_output_tkeep_0 = 8'b01111111; fcs_output_tkeep_1 = 8'b00000000; end 8'b00001111: begin fcs_output_tdata_0 = {~crc_next3[31:0], fcs_input_tdata[31:0]}; - fcs_output_tdata_1 = 0; + fcs_output_tdata_1 = 64'd0; fcs_output_tkeep_0 = 8'b11111111; fcs_output_tkeep_1 = 8'b00000000; end @@ -269,10 +266,10 @@ always @* begin fcs_output_tkeep_1 = 8'b00001111; end default: begin - fcs_output_tdata_0 = 0; - fcs_output_tdata_1 = 0; - fcs_output_tkeep_0 = 0; - fcs_output_tkeep_1 = 0; + fcs_output_tdata_0 = 64'd0; + fcs_output_tdata_1 = 64'd0; + fcs_output_tkeep_0 = 8'd0; + fcs_output_tkeep_1 = 8'd0; end endcase end @@ -280,60 +277,60 @@ end always @* begin state_next = STATE_IDLE; - reset_crc = 0; - update_crc = 0; + reset_crc = 1'b0; + update_crc = 1'b0; frame_ptr_next = frame_ptr_reg; last_cycle_tdata_next = last_cycle_tdata_reg; last_cycle_tkeep_next = last_cycle_tkeep_reg; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; - fcs_input_tdata = 0; - fcs_input_tkeep = 0; + fcs_input_tdata = 64'd0; + fcs_input_tkeep = 8'd0; - output_axis_tdata_int = 0; - output_axis_tkeep_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = 64'd0; + output_axis_tkeep_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data input_axis_tready_next = output_axis_tready_int_early; - frame_ptr_next = 0; - reset_crc = 1; + frame_ptr_next = 16'd0; + reset_crc = 1'b1; output_axis_tdata_int = input_axis_tdata_masked; output_axis_tkeep_int = input_axis_tkeep; output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; fcs_input_tdata = input_axis_tdata_masked; fcs_input_tkeep = input_axis_tkeep; if (input_axis_tready & input_axis_tvalid) begin - reset_crc = 0; - update_crc = 1; + reset_crc = 1'b0; + update_crc = 1'b1; frame_ptr_next = keep2count(input_axis_tkeep); if (input_axis_tlast) begin if (input_axis_tuser) begin - output_axis_tlast_int = 1; - output_axis_tuser_int = 1; - reset_crc = 1; - frame_ptr_next = 0; + output_axis_tlast_int = 1'b1; + output_axis_tuser_int = 1'b1; + reset_crc = 1'b1; + frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-4) begin output_axis_tkeep_int = 8'hff; fcs_input_tkeep = 8'hff; - frame_ptr_next = frame_ptr_reg + 8; + frame_ptr_next = frame_ptr_reg + 16'd8; if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_PAD; end else begin output_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); @@ -344,15 +341,15 @@ always @* begin output_axis_tkeep_int = fcs_output_tkeep_0; last_cycle_tkeep_next = fcs_output_tkeep_1; - reset_crc = 1; + reset_crc = 1'b1; - if (fcs_output_tkeep_1 == 0) begin - output_axis_tlast_int = 1; + if (fcs_output_tkeep_1 == 8'd0) begin + output_axis_tlast_int = 1'b1; input_axis_tready_next = output_axis_tready_int_early; - frame_ptr_next = 0; + frame_ptr_next = 1'b0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_FCS; end end @@ -362,15 +359,15 @@ always @* begin output_axis_tkeep_int = fcs_output_tkeep_0; last_cycle_tkeep_next = fcs_output_tkeep_1; - reset_crc = 1; + reset_crc = 1'b1; - if (fcs_output_tkeep_1 == 0) begin - output_axis_tlast_int = 1; + if (fcs_output_tkeep_1 == 8'd0) begin + output_axis_tlast_int = 1'b1; input_axis_tready_next = output_axis_tready_int_early; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_FCS; end end @@ -389,30 +386,30 @@ always @* begin output_axis_tdata_int = input_axis_tdata_masked; output_axis_tkeep_int = input_axis_tkeep; output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; fcs_input_tdata = input_axis_tdata_masked; fcs_input_tkeep = input_axis_tkeep; if (input_axis_tready & input_axis_tvalid) begin - update_crc = 1; + update_crc = 1'b1; frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); if (input_axis_tlast) begin if (input_axis_tuser) begin - output_axis_tlast_int = 1; - output_axis_tuser_int = 1; - reset_crc = 1; - frame_ptr_next = 0; + output_axis_tlast_int = 1'b1; + output_axis_tuser_int = 1'b1; + reset_crc = 1'b1; + frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-4) begin output_axis_tkeep_int = 8'hff; fcs_input_tkeep = 8'hff; - frame_ptr_next = frame_ptr_reg + 8; + frame_ptr_next = frame_ptr_reg + 16'd8; if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_PAD; end else begin output_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); @@ -423,15 +420,15 @@ always @* begin output_axis_tkeep_int = fcs_output_tkeep_0; last_cycle_tkeep_next = fcs_output_tkeep_1; - reset_crc = 1; + reset_crc = 1'b1; - if (fcs_output_tkeep_1 == 0) begin - output_axis_tlast_int = 1; + if (fcs_output_tkeep_1 == 8'd0) begin + output_axis_tlast_int = 1'b1; input_axis_tready_next = output_axis_tready_int_early; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_FCS; end end @@ -441,15 +438,15 @@ always @* begin output_axis_tkeep_int = fcs_output_tkeep_0; last_cycle_tkeep_next = fcs_output_tkeep_1; - reset_crc = 1; + reset_crc = 1'b1; - if (fcs_output_tkeep_1 == 0) begin - output_axis_tlast_int = 1; + if (fcs_output_tkeep_1 == 8'd0) begin + output_axis_tlast_int = 1'b1; input_axis_tready_next = output_axis_tready_int_early; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_FCS; end end @@ -462,20 +459,20 @@ always @* begin end end STATE_PAD: begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; - output_axis_tdata_int = 0; + output_axis_tdata_int = 64'd0; output_axis_tkeep_int = 8'hff; - output_axis_tvalid_int = 1; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tvalid_int = 1'b1; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; - fcs_input_tdata = 0; + fcs_input_tdata = 64'd0; fcs_input_tkeep = 8'hff; - if (output_axis_tready_int) begin - update_crc = 1; - frame_ptr_next = frame_ptr_reg + 8; + if (output_axis_tready_int_reg) begin + update_crc = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd8; if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin state_next = STATE_PAD; @@ -488,15 +485,15 @@ always @* begin output_axis_tkeep_int = fcs_output_tkeep_0; last_cycle_tkeep_next = fcs_output_tkeep_1; - reset_crc = 1; + reset_crc = 1'b1; - if (fcs_output_tkeep_1 == 0) begin - output_axis_tlast_int = 1; + if (fcs_output_tkeep_1 == 8'd0) begin + output_axis_tlast_int = 1'b1; input_axis_tready_next = output_axis_tready_int_early; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; state_next = STATE_FCS; end end @@ -506,18 +503,18 @@ always @* begin end STATE_FCS: begin // last cycle - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; output_axis_tdata_int = last_cycle_tdata_reg; output_axis_tkeep_int = last_cycle_tkeep_reg; - output_axis_tvalid_int = 1; - output_axis_tlast_int = 1; - output_axis_tuser_int = 0; + output_axis_tvalid_int = 1'b1; + output_axis_tlast_int = 1'b1; + output_axis_tuser_int = 1'b0; - if (output_axis_tready_int) begin - reset_crc = 1; + if (output_axis_tready_int_reg) begin + reset_crc = 1'b1; input_axis_tready_next = output_axis_tready_int_early; - frame_ptr_next = 0; + frame_ptr_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_FCS; @@ -530,14 +527,11 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; + frame_ptr_reg <= 1'b0; - last_cycle_tdata_reg <= 0; - last_cycle_tkeep_reg <= 0; - - input_axis_tready_reg <= 0; + input_axis_tready_reg <= 1'b0; - busy_reg <= 0; + busy_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; end else begin @@ -545,9 +539,6 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; - last_cycle_tdata_reg <= last_cycle_tdata_next; - last_cycle_tkeep_reg <= last_cycle_tkeep_next; - input_axis_tready_reg <= input_axis_tready_next; busy_reg <= state_next != STATE_IDLE; @@ -559,20 +550,28 @@ always @(posedge clk) begin crc_state <= crc_next7; end end + + last_cycle_tdata_reg <= last_cycle_tdata_next; + last_cycle_tkeep_reg <= last_cycle_tkeep_next; end // output datapath logic -reg [63:0] output_axis_tdata_reg = 0; -reg [7:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [63:0] output_axis_tdata_reg = 64'd0; +reg [7:0] output_axis_tkeep_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [63:0] temp_axis_tdata_reg = 0; -reg [7:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [63:0] temp_axis_tdata_reg = 64'd0; +reg [7:0] temp_axis_tkeep_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -580,56 +579,66 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index f4e1b0822..503fd3130 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -102,22 +102,22 @@ reg store_eth_src_mac_5; reg store_eth_type_0; reg store_eth_type_1; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; -reg busy_reg = 0; -reg error_header_early_termination_reg = 0, error_header_early_termination_next; +reg busy_reg = 1'b0; +reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; // internal datapath reg [7:0] output_eth_payload_tdata_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -135,50 +135,50 @@ assign error_header_early_termination = error_header_early_termination_reg; always @* begin state_next = STATE_IDLE; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; - store_eth_dest_mac_0 = 0; - store_eth_dest_mac_1 = 0; - store_eth_dest_mac_2 = 0; - store_eth_dest_mac_3 = 0; - store_eth_dest_mac_4 = 0; - store_eth_dest_mac_5 = 0; - store_eth_src_mac_0 = 0; - store_eth_src_mac_1 = 0; - store_eth_src_mac_2 = 0; - store_eth_src_mac_3 = 0; - store_eth_src_mac_4 = 0; - store_eth_src_mac_5 = 0; - store_eth_type_0 = 0; - store_eth_type_1 = 0; + store_eth_dest_mac_0 = 1'b0; + store_eth_dest_mac_1 = 1'b0; + store_eth_dest_mac_2 = 1'b0; + store_eth_dest_mac_3 = 1'b0; + store_eth_dest_mac_4 = 1'b0; + store_eth_dest_mac_5 = 1'b0; + store_eth_src_mac_0 = 1'b0; + store_eth_src_mac_1 = 1'b0; + store_eth_src_mac_2 = 1'b0; + store_eth_src_mac_3 = 1'b0; + store_eth_src_mac_4 = 1'b0; + store_eth_src_mac_5 = 1'b0; + store_eth_type_0 = 1'b0; + store_eth_type_1 = 1'b0; frame_ptr_next = frame_ptr_reg; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - error_header_early_termination_next = 0; + error_header_early_termination_next = 1'b0; - output_eth_payload_tdata_int = 0; - output_eth_payload_tvalid_int = 0; - output_eth_payload_tlast_int = 0; - output_eth_payload_tuser_int = 0; + output_eth_payload_tdata_int = 8'd0; + output_eth_payload_tvalid_int = 1'b0; + output_eth_payload_tlast_int = 1'b0; + output_eth_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; + frame_ptr_next = 8'd0; input_axis_tready_next = ~output_eth_hdr_valid_reg; if (input_axis_tready & input_axis_tvalid) begin // got first word of packet if (input_axis_tlast) begin // tlast asserted on first word - error_header_early_termination_next = 1; + error_header_early_termination_next = 1'b1; state_next = STATE_IDLE; end else begin // move to read header state - frame_ptr_next = 1; - store_eth_dest_mac_5 = 1; + frame_ptr_next = 1'b1; + store_eth_dest_mac_5 = 1'b1; state_next = STATE_READ_HEADER; end end else begin @@ -187,35 +187,35 @@ always @* begin end STATE_READ_HEADER: begin // read header - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg+1; + frame_ptr_next = frame_ptr_reg + 8'd1; state_next = STATE_READ_HEADER; case (frame_ptr_reg) - 8'h00: store_eth_dest_mac_5 = 1; - 8'h01: store_eth_dest_mac_4 = 1; - 8'h02: store_eth_dest_mac_3 = 1; - 8'h03: store_eth_dest_mac_2 = 1; - 8'h04: store_eth_dest_mac_1 = 1; - 8'h05: store_eth_dest_mac_0 = 1; - 8'h06: store_eth_src_mac_5 = 1; - 8'h07: store_eth_src_mac_4 = 1; - 8'h08: store_eth_src_mac_3 = 1; - 8'h09: store_eth_src_mac_2 = 1; - 8'h0A: store_eth_src_mac_1 = 1; - 8'h0B: store_eth_src_mac_0 = 1; - 8'h0C: store_eth_type_1 = 1; + 8'h00: store_eth_dest_mac_5 = 1'b1; + 8'h01: store_eth_dest_mac_4 = 1'b1; + 8'h02: store_eth_dest_mac_3 = 1'b1; + 8'h03: store_eth_dest_mac_2 = 1'b1; + 8'h04: store_eth_dest_mac_1 = 1'b1; + 8'h05: store_eth_dest_mac_0 = 1'b1; + 8'h06: store_eth_src_mac_5 = 1'b1; + 8'h07: store_eth_src_mac_4 = 1'b1; + 8'h08: store_eth_src_mac_3 = 1'b1; + 8'h09: store_eth_src_mac_2 = 1'b1; + 8'h0A: store_eth_src_mac_1 = 1'b1; + 8'h0B: store_eth_src_mac_0 = 1'b1; + 8'h0C: store_eth_type_1 = 1'b1; 8'h0D: begin - store_eth_type_0 = 1; - output_eth_hdr_valid_next = 1; + store_eth_type_0 = 1'b1; + output_eth_hdr_valid_next = 1'b1; input_axis_tready_next = output_eth_payload_tready_int_early; state_next = STATE_READ_PAYLOAD; end endcase if (input_axis_tlast) begin - error_header_early_termination_next = 1; + error_header_early_termination_next = 1'b1; input_axis_tready_next = ~output_eth_hdr_valid_reg; state_next = STATE_IDLE; end @@ -250,14 +250,11 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - input_axis_tready_reg <= 0; - output_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - busy_reg <= 0; - error_header_early_termination_reg <= 0; + frame_ptr_reg <= 8'd0; + input_axis_tready_reg <= 1'b0; + output_eth_hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; + error_header_early_termination_reg <= 1'b0; end else begin state_reg <= state_next; @@ -270,85 +267,103 @@ always @(posedge clk) begin error_header_early_termination_reg <= error_header_early_termination_next; busy_reg <= state_next != STATE_IDLE; - - // datapath - if (store_eth_dest_mac_0) output_eth_dest_mac_reg[ 7: 0] <= input_axis_tdata; - if (store_eth_dest_mac_1) output_eth_dest_mac_reg[15: 8] <= input_axis_tdata; - if (store_eth_dest_mac_2) output_eth_dest_mac_reg[23:16] <= input_axis_tdata; - if (store_eth_dest_mac_3) output_eth_dest_mac_reg[31:24] <= input_axis_tdata; - if (store_eth_dest_mac_4) output_eth_dest_mac_reg[39:32] <= input_axis_tdata; - if (store_eth_dest_mac_5) output_eth_dest_mac_reg[47:40] <= input_axis_tdata; - if (store_eth_src_mac_0) output_eth_src_mac_reg[ 7: 0] <= input_axis_tdata; - if (store_eth_src_mac_1) output_eth_src_mac_reg[15: 8] <= input_axis_tdata; - if (store_eth_src_mac_2) output_eth_src_mac_reg[23:16] <= input_axis_tdata; - if (store_eth_src_mac_3) output_eth_src_mac_reg[31:24] <= input_axis_tdata; - if (store_eth_src_mac_4) output_eth_src_mac_reg[39:32] <= input_axis_tdata; - if (store_eth_src_mac_5) output_eth_src_mac_reg[47:40] <= input_axis_tdata; - if (store_eth_type_0) output_eth_type_reg[ 7: 0] <= input_axis_tdata; - if (store_eth_type_1) output_eth_type_reg[15: 8] <= input_axis_tdata; end + + // datapath + if (store_eth_dest_mac_0) output_eth_dest_mac_reg[ 7: 0] <= input_axis_tdata; + if (store_eth_dest_mac_1) output_eth_dest_mac_reg[15: 8] <= input_axis_tdata; + if (store_eth_dest_mac_2) output_eth_dest_mac_reg[23:16] <= input_axis_tdata; + if (store_eth_dest_mac_3) output_eth_dest_mac_reg[31:24] <= input_axis_tdata; + if (store_eth_dest_mac_4) output_eth_dest_mac_reg[39:32] <= input_axis_tdata; + if (store_eth_dest_mac_5) output_eth_dest_mac_reg[47:40] <= input_axis_tdata; + if (store_eth_src_mac_0) output_eth_src_mac_reg[ 7: 0] <= input_axis_tdata; + if (store_eth_src_mac_1) output_eth_src_mac_reg[15: 8] <= input_axis_tdata; + if (store_eth_src_mac_2) output_eth_src_mac_reg[23:16] <= input_axis_tdata; + if (store_eth_src_mac_3) output_eth_src_mac_reg[31:24] <= input_axis_tdata; + if (store_eth_src_mac_4) output_eth_src_mac_reg[39:32] <= input_axis_tdata; + if (store_eth_src_mac_5) output_eth_src_mac_reg[47:40] <= input_axis_tdata; + if (store_eth_type_0) output_eth_type_reg[ 7: 0] <= input_axis_tdata; + if (store_eth_type_1) output_eth_type_reg[15: 8] <= input_axis_tdata; end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [7:0] output_eth_payload_tdata_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [7:0] temp_eth_payload_tdata_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [7:0] temp_eth_payload_tdata_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index b947f73b4..77f1f4d84 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -95,22 +95,22 @@ reg store_hdr_word_1; reg flush_save; reg transfer_in_save; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; -reg busy_reg = 0; -reg error_header_early_termination_reg = 0, error_header_early_termination_next; +reg busy_reg = 1'b0; +reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; -reg [63:0] save_axis_tdata_reg = 0; -reg [7:0] save_axis_tkeep_reg = 0; -reg save_axis_tlast_reg = 0; -reg save_axis_tuser_reg = 0; +reg [63:0] save_axis_tdata_reg = 64'd0; +reg [7:0] save_axis_tkeep_reg = 8'd0; +reg save_axis_tlast_reg = 1'b0; +reg save_axis_tuser_reg = 1'b0; reg [63:0] shift_axis_tdata; reg [7:0] shift_axis_tkeep; @@ -124,7 +124,7 @@ reg shift_axis_extra_cycle; reg [63:0] output_eth_payload_tdata_int; reg [7:0] output_eth_payload_tkeep_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -145,9 +145,9 @@ always @* begin shift_axis_extra_cycle = save_axis_tlast_reg & (save_axis_tkeep_reg[7:6] != 0); if (shift_axis_extra_cycle) begin - shift_axis_tdata[63:16] = 0; - shift_axis_tkeep[7:2] = 0; - shift_axis_tvalid = 1; + shift_axis_tdata[63:16] = 48'd0; + shift_axis_tkeep[7:2] = 6'd0; + shift_axis_tvalid = 1'b1; shift_axis_tlast = save_axis_tlast_reg; shift_axis_tuser = save_axis_tuser_reg; shift_axis_input_tready = flush_save; @@ -164,44 +164,44 @@ end always @* begin state_next = STATE_IDLE; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; - flush_save = 0; - transfer_in_save = 0; + flush_save = 1'b0; + transfer_in_save = 1'b0; - store_hdr_word_0 = 0; - store_hdr_word_1 = 0; + store_hdr_word_0 = 1'b0; + store_hdr_word_1 = 1'b0; frame_ptr_next = frame_ptr_reg; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - error_header_early_termination_next = 0; + error_header_early_termination_next = 1'b0; - output_eth_payload_tdata_int = 0; - output_eth_payload_tkeep_int = 0; - output_eth_payload_tvalid_int = 0; - output_eth_payload_tlast_int = 0; - output_eth_payload_tuser_int = 0; + output_eth_payload_tdata_int = 64'd0; + output_eth_payload_tkeep_int = 8'd0; + output_eth_payload_tvalid_int = 1'b0; + output_eth_payload_tlast_int = 1'b0; + output_eth_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; - flush_save = 1; + frame_ptr_next = 8'd0; + flush_save = 1'b1; input_axis_tready_next = ~output_eth_hdr_valid_reg; if (input_axis_tready & input_axis_tvalid) begin // got first word of packet if (input_axis_tlast) begin // tlast asserted on first word - error_header_early_termination_next = 1; + error_header_early_termination_next = 1'b1; state_next = STATE_IDLE; end else begin // move to read header state - frame_ptr_next = 8; - store_hdr_word_0 = 1; - transfer_in_save = 1; + frame_ptr_next = 8'd8; + store_hdr_word_0 = 1'b1; + transfer_in_save = 1'b1; state_next = STATE_READ_HEADER; end end else begin @@ -210,30 +210,30 @@ always @* begin end STATE_READ_HEADER: begin // read header state - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg+8; - transfer_in_save = 1; + frame_ptr_next = frame_ptr_reg + 8'd8; + transfer_in_save = 1'b1; state_next = STATE_READ_HEADER; case (frame_ptr_reg) - 8'h00: store_hdr_word_0 = 1; + 8'h00: store_hdr_word_0 = 1'b1; 8'h08: begin - store_hdr_word_1 = 1; - output_eth_hdr_valid_next = 1; + store_hdr_word_1 = 1'b1; + output_eth_hdr_valid_next = 1'b1; input_axis_tready_next = output_eth_payload_tready_int_early; state_next = STATE_READ_PAYLOAD; end endcase if (input_axis_tlast) begin - if (input_axis_tkeep[7:6] != 0) begin - input_axis_tready_next = 0; + if (input_axis_tkeep[7:6] != 2'd0) begin + input_axis_tready_next = 1'b0; state_next = STATE_READ_PAYLOAD; end else begin - flush_save = 1; - output_eth_hdr_valid_next = 0; - error_header_early_termination_next = 1; + flush_save = 1'b1; + output_eth_hdr_valid_next = 1'b0; + error_header_early_termination_next = 1'b1; input_axis_tready_next = ~output_eth_hdr_valid_reg; state_next = STATE_IDLE; end @@ -252,11 +252,11 @@ always @* begin output_eth_payload_tlast_int = shift_axis_tlast; output_eth_payload_tuser_int = shift_axis_tuser; - if (output_eth_payload_tready_int & shift_axis_tvalid) begin + if (output_eth_payload_tready_int_reg & shift_axis_tvalid) begin // word transfer through - transfer_in_save = 1; + transfer_in_save = 1'b1; if (shift_axis_tlast) begin - flush_save = 1; + flush_save = 1'b1; input_axis_tready_next = ~output_eth_hdr_valid_reg; state_next = STATE_IDLE; end else begin @@ -272,18 +272,12 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - input_axis_tready_reg <= 0; - output_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - save_axis_tdata_reg <= 0; - save_axis_tkeep_reg <= 0; - save_axis_tlast_reg <= 0; - save_axis_tuser_reg <= 0; - busy_reg <= 0; - error_header_early_termination_reg <= 0; + frame_ptr_reg <= 8'd0; + input_axis_tready_reg <= 1'b0; + output_eth_hdr_valid_reg <= 1'b0; + save_axis_tlast_reg <= 1'b0; + busy_reg <= 1'b0; + error_header_early_termination_reg <= 1'b0; end else begin state_reg <= state_next; @@ -297,55 +291,57 @@ always @(posedge clk) begin busy_reg <= state_next != STATE_IDLE; - // datapath - if (store_hdr_word_0) begin - output_eth_dest_mac_reg[47:40] <= input_axis_tdata[ 7: 0]; - output_eth_dest_mac_reg[39:32] <= input_axis_tdata[15: 8]; - output_eth_dest_mac_reg[31:24] <= input_axis_tdata[23:16]; - output_eth_dest_mac_reg[23:16] <= input_axis_tdata[31:24]; - output_eth_dest_mac_reg[15: 8] <= input_axis_tdata[39:32]; - output_eth_dest_mac_reg[ 7: 0] <= input_axis_tdata[47:40]; - output_eth_src_mac_reg[47:40] <= input_axis_tdata[55:48]; - output_eth_src_mac_reg[39:32] <= input_axis_tdata[63:56]; - end - if (store_hdr_word_1) begin - output_eth_src_mac_reg[31:24] <= input_axis_tdata[ 7: 0]; - output_eth_src_mac_reg[23:16] <= input_axis_tdata[15: 8]; - output_eth_src_mac_reg[15: 8] <= input_axis_tdata[23:16]; - output_eth_src_mac_reg[ 7: 0] <= input_axis_tdata[31:24]; - output_eth_type_reg[15:8] <= input_axis_tdata[39:32]; - output_eth_type_reg[ 7:0] <= input_axis_tdata[47:40]; - end - if (flush_save) begin - save_axis_tdata_reg <= 0; - save_axis_tkeep_reg <= 0; - save_axis_tlast_reg <= 0; - save_axis_tuser_reg <= 0; + save_axis_tlast_reg <= 1'b0; end else if (transfer_in_save) begin - save_axis_tdata_reg <= input_axis_tdata; - save_axis_tkeep_reg <= input_axis_tkeep; save_axis_tlast_reg <= input_axis_tlast; - save_axis_tuser_reg <= input_axis_tuser; end end + + // datapath + if (store_hdr_word_0) begin + output_eth_dest_mac_reg[47:40] <= input_axis_tdata[ 7: 0]; + output_eth_dest_mac_reg[39:32] <= input_axis_tdata[15: 8]; + output_eth_dest_mac_reg[31:24] <= input_axis_tdata[23:16]; + output_eth_dest_mac_reg[23:16] <= input_axis_tdata[31:24]; + output_eth_dest_mac_reg[15: 8] <= input_axis_tdata[39:32]; + output_eth_dest_mac_reg[ 7: 0] <= input_axis_tdata[47:40]; + output_eth_src_mac_reg[47:40] <= input_axis_tdata[55:48]; + output_eth_src_mac_reg[39:32] <= input_axis_tdata[63:56]; + end + if (store_hdr_word_1) begin + output_eth_src_mac_reg[31:24] <= input_axis_tdata[ 7: 0]; + output_eth_src_mac_reg[23:16] <= input_axis_tdata[15: 8]; + output_eth_src_mac_reg[15: 8] <= input_axis_tdata[23:16]; + output_eth_src_mac_reg[ 7: 0] <= input_axis_tdata[31:24]; + output_eth_type_reg[15:8] <= input_axis_tdata[39:32]; + output_eth_type_reg[ 7:0] <= input_axis_tdata[47:40]; + end + + if (transfer_in_save) begin + save_axis_tdata_reg <= input_axis_tdata; + save_axis_tkeep_reg <= input_axis_tkeep; + save_axis_tuser_reg <= input_axis_tuser; + end end // output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [64:0] output_eth_payload_tdata_reg = 64'd0; +reg [7:0] output_eth_payload_tkeep_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [63:0] temp_eth_payload_tdata_reg = 0; -reg [7:0] temp_eth_payload_tkeep_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [64:0] temp_eth_payload_tdata_reg = 64'd0; +reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; @@ -353,53 +349,66 @@ assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tkeep_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index 4855c5e02..3cc6bbd99 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -88,24 +88,24 @@ reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg store_eth_hdr; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg [47:0] eth_dest_mac_reg = 0; -reg [47:0] eth_src_mac_reg = 0; -reg [15:0] eth_type_reg = 0; +reg [47:0] eth_dest_mac_reg = 48'd0; +reg [47:0] eth_src_mac_reg = 48'd0; +reg [15:0] eth_type_reg = 16'd0; -reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; -reg busy_reg = 0; +reg busy_reg = 1'b0; // internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; assign input_eth_hdr_ready = input_eth_hdr_ready_reg; assign input_eth_payload_tready = input_eth_payload_tready_reg; @@ -115,31 +115,31 @@ assign busy = busy_reg; always @* begin state_next = STATE_IDLE; - input_eth_hdr_ready_next = 0; - input_eth_payload_tready_next = 0; + input_eth_hdr_ready_next = 1'b0; + input_eth_payload_tready_next = 1'b0; - store_eth_hdr = 0; + store_eth_hdr = 1'b0; frame_ptr_next = frame_ptr_reg; - output_axis_tdata_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; - input_eth_hdr_ready_next = 1; + frame_ptr_next = 8'd0; + input_eth_hdr_ready_next = 1'b1; if (input_eth_hdr_ready & input_eth_hdr_valid) begin - store_eth_hdr = 1; - input_eth_hdr_ready_next = 0; - if (output_axis_tready_int) begin - output_axis_tvalid_int = 1; + store_eth_hdr = 1'b1; + input_eth_hdr_ready_next = 1'b0; + if (output_axis_tready_int_reg) begin + output_axis_tvalid_int = 1'b1; output_axis_tdata_int = input_eth_dest_mac[47:40]; - frame_ptr_next = 1; + frame_ptr_next = 1'b1; end state_next = STATE_WRITE_HEADER; end else begin @@ -148,9 +148,9 @@ always @* begin end STATE_WRITE_HEADER: begin // write header - if (output_axis_tready_int) begin + if (output_axis_tready_int_reg) begin frame_ptr_next = frame_ptr_reg+1; - output_axis_tvalid_int = 1; + output_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: output_axis_tdata_int = eth_dest_mac_reg[47:40]; @@ -188,8 +188,8 @@ always @* begin if (input_eth_payload_tready & input_eth_payload_tvalid) begin // word transfer through if (input_eth_payload_tlast) begin - input_eth_payload_tready_next = 0; - input_eth_hdr_ready_next = 1; + input_eth_payload_tready_next = 1'b0; + input_eth_hdr_ready_next = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -204,13 +204,10 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - eth_dest_mac_reg <= 0; - eth_src_mac_reg <= 0; - eth_type_reg <= 0; - busy_reg <= 0; + frame_ptr_reg <= 8'd0; + input_eth_hdr_ready_reg <= 1'b0; + input_eth_payload_tready_reg <= 1'b0; + busy_reg <= 1'b0; end else begin state_reg <= state_next; @@ -221,76 +218,94 @@ always @(posedge clk) begin input_eth_payload_tready_reg <= input_eth_payload_tready_next; busy_reg <= state_next != STATE_IDLE; + end - // datapath - if (store_eth_hdr) begin - eth_dest_mac_reg <= input_eth_dest_mac; - eth_src_mac_reg <= input_eth_src_mac; - eth_type_reg <= input_eth_type; - end + // datapath + if (store_eth_hdr) begin + eth_dest_mac_reg <= input_eth_dest_mac; + eth_src_mac_reg <= input_eth_src_mac; + eth_type_reg <= input_eth_type; end end // output datapath logic -reg [7:0] output_axis_tdata_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [7:0] output_axis_tdata_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [7:0] temp_axis_tdata_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index 66f90d37e..fb4c4a3af 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -94,21 +94,21 @@ reg store_eth_hdr; reg flush_save; reg transfer_in_save; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg [47:0] eth_dest_mac_reg = 0; -reg [47:0] eth_src_mac_reg = 0; -reg [15:0] eth_type_reg = 0; +reg [47:0] eth_dest_mac_reg = 48'd0; +reg [47:0] eth_src_mac_reg = 48'd0; +reg [15:0] eth_type_reg = 16'd0; -reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; -reg busy_reg = 0; +reg busy_reg = 1'b0; -reg [63:0] save_eth_payload_tdata_reg = 0; -reg [7:0] save_eth_payload_tkeep_reg = 0; -reg save_eth_payload_tlast_reg = 0; -reg save_eth_payload_tuser_reg = 0; +reg [63:0] save_eth_payload_tdata_reg = 64'd0; +reg [7:0] save_eth_payload_tkeep_reg = 8'd0; +reg save_eth_payload_tlast_reg = 1'b0; +reg save_eth_payload_tuser_reg = 1'b0; reg [63:0] shift_eth_payload_tdata; reg [7:0] shift_eth_payload_tkeep; @@ -122,7 +122,7 @@ reg shift_eth_payload_extra_cycle; reg [63:0] output_axis_tdata_int; reg [7:0] output_axis_tkeep_int; reg output_axis_tvalid_int; -reg output_axis_tready_int = 0; +reg output_axis_tready_int_reg = 1'b0; reg output_axis_tlast_int; reg output_axis_tuser_int; wire output_axis_tready_int_early; @@ -138,9 +138,9 @@ always @* begin shift_eth_payload_extra_cycle = save_eth_payload_tlast_reg & (save_eth_payload_tkeep_reg[7:2] != 0); if (shift_eth_payload_extra_cycle) begin - shift_eth_payload_tdata[63:48] = 0; - shift_eth_payload_tkeep[7:6] = 0; - shift_eth_payload_tvalid = 1; + shift_eth_payload_tdata[63:48] = 16'd0; + shift_eth_payload_tkeep[7:6] = 2'd0; + shift_eth_payload_tvalid = 1'b1; shift_eth_payload_tlast = save_eth_payload_tlast_reg; shift_eth_payload_tuser = save_eth_payload_tuser_reg; shift_eth_payload_input_tready = flush_save; @@ -157,35 +157,35 @@ end always @* begin state_next = STATE_IDLE; - input_eth_hdr_ready_next = 0; - input_eth_payload_tready_next = 0; + input_eth_hdr_ready_next = 1'b0; + input_eth_payload_tready_next = 1'b0; - store_eth_hdr = 0; + store_eth_hdr = 1'b0; - flush_save = 0; - transfer_in_save = 0; + flush_save = 1'b0; + transfer_in_save = 1'b0; frame_ptr_next = frame_ptr_reg; - output_axis_tdata_int = 0; - output_axis_tkeep_int = 0; - output_axis_tvalid_int = 0; - output_axis_tlast_int = 0; - output_axis_tuser_int = 0; + output_axis_tdata_int = 64'd0; + output_axis_tkeep_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; - flush_save = 1; - input_eth_hdr_ready_next = 1; + frame_ptr_next = 8'd0; + flush_save = 1'b1; + input_eth_hdr_ready_next = 1'b1; if (input_eth_hdr_ready & input_eth_hdr_valid) begin - store_eth_hdr = 1; - input_eth_hdr_ready_next = 0; + store_eth_hdr = 1'b1; + input_eth_hdr_ready_next = 1'b0; state_next = STATE_WRITE_HEADER; - if (output_axis_tready_int) begin - output_axis_tvalid_int = 1; + if (output_axis_tready_int_reg) begin + output_axis_tvalid_int = 1'b1; output_axis_tdata_int[ 7: 0] = input_eth_dest_mac[47:40]; output_axis_tdata_int[15: 8] = input_eth_dest_mac[39:32]; output_axis_tdata_int[23:16] = input_eth_dest_mac[31:24]; @@ -195,7 +195,7 @@ always @* begin output_axis_tdata_int[55:48] = input_eth_src_mac[47:40]; output_axis_tdata_int[63:56] = input_eth_src_mac[39:32]; output_axis_tkeep_int = 8'hff; - frame_ptr_next = 8; + frame_ptr_next = 8'd8; input_eth_payload_tready_next = output_axis_tready_int_early; state_next = STATE_WRITE_HEADER_LAST; end @@ -205,9 +205,9 @@ always @* begin end STATE_WRITE_HEADER: begin // write header - if (output_axis_tready_int) begin - frame_ptr_next = frame_ptr_reg + 8; - output_axis_tvalid_int = 1; + if (output_axis_tready_int_reg) begin + frame_ptr_next = frame_ptr_reg + 8'd8; + output_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 5'd00: begin @@ -233,9 +233,9 @@ always @* begin input_eth_payload_tready_next = output_axis_tready_int_early & shift_eth_payload_input_tready; if (input_eth_payload_tready & shift_eth_payload_tvalid) begin - frame_ptr_next = frame_ptr_reg + 8; - output_axis_tvalid_int = 1; - transfer_in_save = 1; + frame_ptr_next = frame_ptr_reg + 8'd8; + output_axis_tvalid_int = 1'b1; + transfer_in_save = 1'b1; output_axis_tdata_int[ 7: 0] = eth_src_mac_reg[31:24]; output_axis_tdata_int[15: 8] = eth_src_mac_reg[23:16]; @@ -250,9 +250,9 @@ always @* begin output_axis_tuser_int = shift_eth_payload_tuser; if (shift_eth_payload_tlast) begin - input_eth_payload_tready_next = 0; - flush_save = 1; - input_eth_hdr_ready_next = 1; + input_eth_payload_tready_next = 1'b0; + flush_save = 1'b1; + input_eth_hdr_ready_next = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -271,13 +271,13 @@ always @* begin output_axis_tlast_int = shift_eth_payload_tlast; output_axis_tuser_int = shift_eth_payload_tuser; - if (output_axis_tready_int & shift_eth_payload_tvalid) begin + if (output_axis_tready_int_reg & shift_eth_payload_tvalid) begin // word transfer through - transfer_in_save = 1; + transfer_in_save = 1'b1; if (shift_eth_payload_tlast) begin - input_eth_payload_tready_next = 0; - flush_save = 1; - input_eth_hdr_ready_next = 1; + input_eth_payload_tready_next = 1'b0; + flush_save = 1'b1; + input_eth_hdr_ready_next = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -292,17 +292,11 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - eth_dest_mac_reg <= 0; - eth_src_mac_reg <= 0; - eth_type_reg <= 0; - save_eth_payload_tdata_reg <= 0; - save_eth_payload_tkeep_reg <= 0; - save_eth_payload_tlast_reg <= 0; - save_eth_payload_tuser_reg <= 0; - busy_reg <= 0; + frame_ptr_reg <= 8'd0; + input_eth_hdr_ready_reg <= 1'b0; + input_eth_payload_tready_reg <= 1'b0; + save_eth_payload_tlast_reg <= 1'b0; + busy_reg <= 1'b0; end else begin state_reg <= state_next; @@ -322,34 +316,43 @@ always @(posedge clk) begin end if (flush_save) begin - save_eth_payload_tdata_reg <= 0; - save_eth_payload_tkeep_reg <= 0; - save_eth_payload_tlast_reg <= 0; - save_eth_payload_tuser_reg <= 0; + save_eth_payload_tlast_reg <= 1'b0; end else if (transfer_in_save) begin - save_eth_payload_tdata_reg <= input_eth_payload_tdata; - save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; save_eth_payload_tlast_reg <= input_eth_payload_tlast; - save_eth_payload_tuser_reg <= input_eth_payload_tuser; end end + + // datapath + if (store_eth_hdr) begin + eth_dest_mac_reg <= input_eth_dest_mac; + eth_src_mac_reg <= input_eth_src_mac; + eth_type_reg <= input_eth_type; + end + + if (transfer_in_save) begin + save_eth_payload_tdata_reg <= input_eth_payload_tdata; + save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; + save_eth_payload_tuser_reg <= input_eth_payload_tuser; + end end // output datapath logic -reg [63:0] output_axis_tdata_reg = 0; -reg [7:0] output_axis_tkeep_reg = 0; -reg output_axis_tvalid_reg = 0; -reg output_axis_tlast_reg = 0; -reg output_axis_tuser_reg = 0; +reg [63:0] output_axis_tdata_reg = 64'd0; +reg [7:0] output_axis_tkeep_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; -reg [63:0] temp_axis_tdata_reg = 0; -reg [7:0] temp_axis_tkeep_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [63:0] temp_axis_tdata_reg = 64'd0; +reg [7:0] temp_axis_tkeep_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int); +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -357,53 +360,66 @@ assign output_axis_tvalid = output_axis_tvalid_reg; assign output_axis_tlast = output_axis_tlast_reg; assign output_axis_tuser = output_axis_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; - output_axis_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_axis_tready_int <= output_axis_tready_int_early; + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end - if (output_axis_tready_int) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tvalid_reg <= output_axis_tvalid_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tvalid_reg <= output_axis_tvalid_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tvalid_reg <= temp_axis_tvalid_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tkeep_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py index 8bc36806b..4a5c44f48 100755 --- a/rtl/eth_demux.py +++ b/rtl/eth_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -110,22 +110,22 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; {% for p in ports %} -reg output_{{p}}_eth_hdr_valid_reg = 0, output_{{p}}_eth_hdr_valid_next; +reg output_{{p}}_eth_hdr_valid_reg = 1'b0, output_{{p}}_eth_hdr_valid_next; {%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; // internal datapath reg [7:0] output_eth_payload_tdata_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -153,6 +153,12 @@ always @* begin current_output_tready = output_{{p}}_eth_payload_tready; end {%- endfor %} + default: begin + current_output_eth_hdr_valid = 1'b0; + current_output_eth_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -161,7 +167,7 @@ always @* begin frame_next = frame_reg; input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; {%- for p in ports %} output_{{p}}_eth_hdr_valid_next = output_{{p}}_eth_hdr_valid_reg & ~output_{{p}}_eth_hdr_ready; @@ -177,14 +183,14 @@ always @* begin end end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_eth_hdr_ready_next = 1; + input_eth_hdr_ready_next = 1'b1; case (select) {%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_eth_hdr_valid_next = 1; + {{w}}'d{{p}}: output_{{p}}_eth_hdr_valid_next = 1'b1; {%- endfor %} endcase output_eth_dest_mac_next = input_eth_dest_mac; @@ -202,16 +208,13 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; + input_eth_hdr_ready_reg <= 1'b0; + input_eth_payload_tready_reg <= 1'b0; {%- for p in ports %} - output_{{p}}_eth_hdr_valid_reg <= 0; + output_{{p}}_eth_hdr_valid_reg <= 1'b0; {%- endfor %} - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -220,84 +223,103 @@ always @(posedge clk) begin {%- for p in ports %} output_{{p}}_eth_hdr_valid_reg <= output_{{p}}_eth_hdr_valid_next; {%- endfor %} - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 0; +reg [7:0] output_eth_payload_tdata_reg = 8'd0; {%- for p in ports %} -reg output_{{p}}_eth_payload_tvalid_reg = 0; +reg output_{{p}}_eth_payload_tvalid_reg = 1'b0, output_{{p}}_eth_payload_tvalid_next; {%- endfor %} -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [7:0] temp_eth_payload_tdata_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [7:0] temp_eth_payload_tdata_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; {% for p in ports %} assign output_{{p}}_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_{{p}}_eth_payload_tvalid = output_{{p}}_eth_payload_tvalid_reg; assign output_{{p}}_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_{{p}}_eth_payload_tuser = output_eth_payload_tuser_reg; {% endfor %} -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & (~current_output_tvalid | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source +{%- for p in ports %} + output_{{p}}_eth_payload_tvalid_next = output_{{p}}_eth_payload_tvalid_reg; +{%- endfor %} + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output +{%- for p in ports %} + output_{{p}}_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready +{%- for p in ports %} + output_{{p}}_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; {%- for p in ports %} - output_{{p}}_eth_payload_tvalid_reg <= 0; + output_{{p}}_eth_payload_tvalid_reg <= 1'b0; {%- endfor %} - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; +{%- for p in ports %} + output_{{p}}_eth_payload_tvalid_reg <= output_{{p}}_eth_payload_tvalid_next; +{%- endfor %} + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; -{%- endfor %} - endcase - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; -{%- endfor %} - endcase - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_demux_4.v b/rtl/eth_demux_4.v index 5609da33d..e194a8081 100644 --- a/rtl/eth_demux_4.v +++ b/rtl/eth_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -102,24 +102,24 @@ module eth_demux_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; -reg output_0_eth_hdr_valid_reg = 0, output_0_eth_hdr_valid_next; -reg output_1_eth_hdr_valid_reg = 0, output_1_eth_hdr_valid_next; -reg output_2_eth_hdr_valid_reg = 0, output_2_eth_hdr_valid_next; -reg output_3_eth_hdr_valid_reg = 0, output_3_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg output_0_eth_hdr_valid_reg = 1'b0, output_0_eth_hdr_valid_next; +reg output_1_eth_hdr_valid_reg = 1'b0, output_1_eth_hdr_valid_next; +reg output_2_eth_hdr_valid_reg = 1'b0, output_2_eth_hdr_valid_next; +reg output_3_eth_hdr_valid_reg = 1'b0, output_3_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; // internal datapath reg [7:0] output_eth_payload_tdata_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -178,6 +178,12 @@ always @* begin current_output_tvalid = output_3_eth_payload_tvalid; current_output_tready = output_3_eth_payload_tready; end + default: begin + current_output_eth_hdr_valid = 1'b0; + current_output_eth_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -186,7 +192,7 @@ always @* begin frame_next = frame_reg; input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; output_0_eth_hdr_valid_next = output_0_eth_hdr_valid_reg & ~output_0_eth_hdr_ready; output_1_eth_hdr_valid_next = output_1_eth_hdr_valid_reg & ~output_1_eth_hdr_ready; output_2_eth_hdr_valid_next = output_2_eth_hdr_valid_reg & ~output_2_eth_hdr_ready; @@ -202,16 +208,16 @@ always @* begin end end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_eth_hdr_ready_next = 1; + input_eth_hdr_ready_next = 1'b1; case (select) - 2'd0: output_0_eth_hdr_valid_next = 1; - 2'd1: output_1_eth_hdr_valid_next = 1; - 2'd2: output_2_eth_hdr_valid_next = 1; - 2'd3: output_3_eth_hdr_valid_next = 1; + 2'd0: output_0_eth_hdr_valid_next = 1'b1; + 2'd1: output_1_eth_hdr_valid_next = 1'b1; + 2'd2: output_2_eth_hdr_valid_next = 1'b1; + 2'd3: output_3_eth_hdr_valid_next = 1'b1; endcase output_eth_dest_mac_next = input_eth_dest_mac; output_eth_src_mac_next = input_eth_src_mac; @@ -228,17 +234,14 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_0_eth_hdr_valid_reg <= 0; - output_1_eth_hdr_valid_reg <= 0; - output_2_eth_hdr_valid_reg <= 0; - output_3_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_eth_hdr_ready_reg <= 1'b0; + input_eth_payload_tready_reg <= 1'b0; + output_0_eth_hdr_valid_reg <= 1'b0; + output_1_eth_hdr_valid_reg <= 1'b0; + output_2_eth_hdr_valid_reg <= 1'b0; + output_3_eth_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -248,25 +251,31 @@ always @(posedge clk) begin output_1_eth_hdr_valid_reg <= output_1_eth_hdr_valid_next; output_2_eth_hdr_valid_reg <= output_2_eth_hdr_valid_next; output_3_eth_hdr_valid_reg <= output_3_eth_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 0; -reg output_0_eth_payload_tvalid_reg = 0; -reg output_1_eth_payload_tvalid_reg = 0; -reg output_2_eth_payload_tvalid_reg = 0; -reg output_3_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [7:0] output_eth_payload_tdata_reg = 8'd0; +reg output_0_eth_payload_tvalid_reg = 1'b0, output_0_eth_payload_tvalid_next; +reg output_1_eth_payload_tvalid_reg = 1'b0, output_1_eth_payload_tvalid_next; +reg output_2_eth_payload_tvalid_reg = 1'b0, output_2_eth_payload_tvalid_next; +reg output_3_eth_payload_tvalid_reg = 1'b0, output_3_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [7:0] temp_eth_payload_tdata_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [7:0] temp_eth_payload_tdata_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_0_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_0_eth_payload_tvalid = output_0_eth_payload_tvalid_reg; @@ -288,63 +297,78 @@ assign output_3_eth_payload_tvalid = output_3_eth_payload_tvalid_reg; assign output_3_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_3_eth_payload_tuser = output_eth_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & (~current_output_tvalid | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_0_eth_payload_tvalid_next = output_0_eth_payload_tvalid_reg; + output_1_eth_payload_tvalid_next = output_1_eth_payload_tvalid_reg; + output_2_eth_payload_tvalid_next = output_2_eth_payload_tvalid_reg; + output_3_eth_payload_tvalid_next = output_3_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_0_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd0); + output_1_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd1); + output_2_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd2); + output_3_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd3); + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_0_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd0); + output_1_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd1); + output_2_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd2); + output_3_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd3); + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_0_eth_payload_tvalid_reg <= 0; - output_1_eth_payload_tvalid_reg <= 0; - output_2_eth_payload_tvalid_reg <= 0; - output_3_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_0_eth_payload_tvalid_reg <= 1'b0; + output_1_eth_payload_tvalid_reg <= 1'b0; + output_2_eth_payload_tvalid_reg <= 1'b0; + output_3_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_0_eth_payload_tvalid_reg <= output_0_eth_payload_tvalid_next; + output_1_eth_payload_tvalid_reg <= output_1_eth_payload_tvalid_next; + output_2_eth_payload_tvalid_reg <= output_2_eth_payload_tvalid_next; + output_3_eth_payload_tvalid_reg <= output_3_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - case (select_reg) - 2'd0: output_0_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - 2'd1: output_1_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - 2'd2: output_2_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - 2'd3: output_3_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - endcase - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - case (select_reg) - 2'd0: output_0_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - 2'd1: output_1_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - 2'd2: output_2_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - 2'd3: output_3_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - endcase - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py index e32d4e2b8..993cc2af5 100755 --- a/rtl/eth_demux_64.py +++ b/rtl/eth_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -112,23 +112,23 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; {% for p in ports %} -reg output_{{p}}_eth_hdr_valid_reg = 0, output_{{p}}_eth_hdr_valid_next; +reg output_{{p}}_eth_hdr_valid_reg = 1'b0, output_{{p}}_eth_hdr_valid_next; {%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; // internal datapath reg [63:0] output_eth_payload_tdata_int; reg [7:0] output_eth_payload_tkeep_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -156,6 +156,12 @@ always @* begin current_output_tready = output_{{p}}_eth_payload_tready; end {%- endfor %} + default: begin + current_output_eth_hdr_valid = 1'b0; + current_output_eth_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -164,7 +170,7 @@ always @* begin frame_next = frame_reg; input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; {%- for p in ports %} output_{{p}}_eth_hdr_valid_next = output_{{p}}_eth_hdr_valid_reg & ~output_{{p}}_eth_hdr_ready; @@ -180,14 +186,14 @@ always @* begin end end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_eth_hdr_ready_next = 1; + input_eth_hdr_ready_next = 1'b1; case (select) {%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_eth_hdr_valid_next = 1; + {{w}}'d{{p}}: output_{{p}}_eth_hdr_valid_next = 1'b1; {%- endfor %} endcase output_eth_dest_mac_next = input_eth_dest_mac; @@ -206,16 +212,13 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; + input_eth_hdr_ready_reg <= 1'b0; + input_eth_payload_tready_reg <= 1'b0; {%- for p in ports %} - output_{{p}}_eth_hdr_valid_reg <= 0; + output_{{p}}_eth_hdr_valid_reg <= 1'b0; {%- endfor %} - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -224,26 +227,32 @@ always @(posedge clk) begin {%- for p in ports %} output_{{p}}_eth_hdr_valid_reg <= output_{{p}}_eth_hdr_valid_next; {%- endfor %} - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; end // output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; +reg [63:0] output_eth_payload_tdata_reg = 64'd0; +reg [7:0] output_eth_payload_tkeep_reg = 8'd0; {%- for p in ports %} -reg output_{{p}}_eth_payload_tvalid_reg = 0; +reg output_{{p}}_eth_payload_tvalid_reg = 1'b0, output_{{p}}_eth_payload_tvalid_next; {%- endfor %} -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [63:0] temp_eth_payload_tdata_reg = 0; -reg [7:0] temp_eth_payload_tkeep_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [63:0] temp_eth_payload_tdata_reg = 64'd0; +reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; {% for p in ports %} assign output_{{p}}_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_{{p}}_eth_payload_tkeep = output_eth_payload_tkeep_reg; @@ -251,66 +260,76 @@ assign output_{{p}}_eth_payload_tvalid = output_{{p}}_eth_payload_tvalid_reg; assign output_{{p}}_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_{{p}}_eth_payload_tuser = output_eth_payload_tuser_reg; {% endfor %} -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & (~current_output_tvalid | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source +{%- for p in ports %} + output_{{p}}_eth_payload_tvalid_next = output_{{p}}_eth_payload_tvalid_reg; +{%- endfor %} + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output +{%- for p in ports %} + output_{{p}}_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready +{%- for p in ports %} + output_{{p}}_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tkeep_reg <= 0; {%- for p in ports %} - output_{{p}}_eth_payload_tvalid_reg <= 0; + output_{{p}}_eth_payload_tvalid_reg <= 1'b0; {%- endfor %} - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; +{%- for p in ports %} + output_{{p}}_eth_payload_tvalid_reg <= output_{{p}}_eth_payload_tvalid_next; +{%- endfor %} + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; -{%- endfor %} - endcase - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; -{%- endfor %} - endcase - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_demux_64_4.v b/rtl/eth_demux_64_4.v index cbba1b3a8..dabd2a350 100644 --- a/rtl/eth_demux_64_4.v +++ b/rtl/eth_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -107,25 +107,25 @@ module eth_demux_64_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; -reg output_0_eth_hdr_valid_reg = 0, output_0_eth_hdr_valid_next; -reg output_1_eth_hdr_valid_reg = 0, output_1_eth_hdr_valid_next; -reg output_2_eth_hdr_valid_reg = 0, output_2_eth_hdr_valid_next; -reg output_3_eth_hdr_valid_reg = 0, output_3_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg output_0_eth_hdr_valid_reg = 1'b0, output_0_eth_hdr_valid_next; +reg output_1_eth_hdr_valid_reg = 1'b0, output_1_eth_hdr_valid_next; +reg output_2_eth_hdr_valid_reg = 1'b0, output_2_eth_hdr_valid_next; +reg output_3_eth_hdr_valid_reg = 1'b0, output_3_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; // internal datapath reg [63:0] output_eth_payload_tdata_int; reg [7:0] output_eth_payload_tkeep_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -184,6 +184,12 @@ always @* begin current_output_tvalid = output_3_eth_payload_tvalid; current_output_tready = output_3_eth_payload_tready; end + default: begin + current_output_eth_hdr_valid = 1'b0; + current_output_eth_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -192,7 +198,7 @@ always @* begin frame_next = frame_reg; input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; output_0_eth_hdr_valid_next = output_0_eth_hdr_valid_reg & ~output_0_eth_hdr_ready; output_1_eth_hdr_valid_next = output_1_eth_hdr_valid_reg & ~output_1_eth_hdr_ready; output_2_eth_hdr_valid_next = output_2_eth_hdr_valid_reg & ~output_2_eth_hdr_ready; @@ -208,16 +214,16 @@ always @* begin end end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_eth_hdr_ready_next = 1; + input_eth_hdr_ready_next = 1'b1; case (select) - 2'd0: output_0_eth_hdr_valid_next = 1; - 2'd1: output_1_eth_hdr_valid_next = 1; - 2'd2: output_2_eth_hdr_valid_next = 1; - 2'd3: output_3_eth_hdr_valid_next = 1; + 2'd0: output_0_eth_hdr_valid_next = 1'b1; + 2'd1: output_1_eth_hdr_valid_next = 1'b1; + 2'd2: output_2_eth_hdr_valid_next = 1'b1; + 2'd3: output_3_eth_hdr_valid_next = 1'b1; endcase output_eth_dest_mac_next = input_eth_dest_mac; output_eth_src_mac_next = input_eth_src_mac; @@ -235,17 +241,14 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_0_eth_hdr_valid_reg <= 0; - output_1_eth_hdr_valid_reg <= 0; - output_2_eth_hdr_valid_reg <= 0; - output_3_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_eth_hdr_ready_reg <= 1'b0; + input_eth_payload_tready_reg <= 1'b0; + output_0_eth_hdr_valid_reg <= 1'b0; + output_1_eth_hdr_valid_reg <= 1'b0; + output_2_eth_hdr_valid_reg <= 1'b0; + output_3_eth_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -255,27 +258,33 @@ always @(posedge clk) begin output_1_eth_hdr_valid_reg <= output_1_eth_hdr_valid_next; output_2_eth_hdr_valid_reg <= output_2_eth_hdr_valid_next; output_3_eth_hdr_valid_reg <= output_3_eth_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; end // output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; -reg output_0_eth_payload_tvalid_reg = 0; -reg output_1_eth_payload_tvalid_reg = 0; -reg output_2_eth_payload_tvalid_reg = 0; -reg output_3_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [63:0] output_eth_payload_tdata_reg = 64'd0; +reg [7:0] output_eth_payload_tkeep_reg = 8'd0; +reg output_0_eth_payload_tvalid_reg = 1'b0, output_0_eth_payload_tvalid_next; +reg output_1_eth_payload_tvalid_reg = 1'b0, output_1_eth_payload_tvalid_next; +reg output_2_eth_payload_tvalid_reg = 1'b0, output_2_eth_payload_tvalid_next; +reg output_3_eth_payload_tvalid_reg = 1'b0, output_3_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [63:0] temp_eth_payload_tdata_reg = 0; -reg [7:0] temp_eth_payload_tkeep_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [63:0] temp_eth_payload_tdata_reg = 64'd0; +reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_0_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_0_eth_payload_tkeep = output_eth_payload_tkeep_reg; @@ -301,69 +310,81 @@ assign output_3_eth_payload_tvalid = output_3_eth_payload_tvalid_reg; assign output_3_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_3_eth_payload_tuser = output_eth_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & ~current_output_tvalid) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & (~current_output_tvalid | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_0_eth_payload_tvalid_next = output_0_eth_payload_tvalid_reg; + output_1_eth_payload_tvalid_next = output_1_eth_payload_tvalid_reg; + output_2_eth_payload_tvalid_next = output_2_eth_payload_tvalid_reg; + output_3_eth_payload_tvalid_next = output_3_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_0_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd0); + output_1_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd1); + output_2_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd2); + output_3_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd3); + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_0_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd0); + output_1_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd1); + output_2_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd2); + output_3_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd3); + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tkeep_reg <= 0; - output_0_eth_payload_tvalid_reg <= 0; - output_1_eth_payload_tvalid_reg <= 0; - output_2_eth_payload_tvalid_reg <= 0; - output_3_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_0_eth_payload_tvalid_reg <= 1'b0; + output_1_eth_payload_tvalid_reg <= 1'b0; + output_2_eth_payload_tvalid_reg <= 1'b0; + output_3_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_0_eth_payload_tvalid_reg <= output_0_eth_payload_tvalid_next; + output_1_eth_payload_tvalid_reg <= output_1_eth_payload_tvalid_next; + output_2_eth_payload_tvalid_reg <= output_2_eth_payload_tvalid_next; + output_3_eth_payload_tvalid_reg <= output_3_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - case (select_reg) - 2'd0: output_0_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - 2'd1: output_1_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - 2'd2: output_2_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - 2'd3: output_3_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - endcase - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - case (select_reg) - 2'd0: output_0_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - 2'd1: output_1_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - 2'd2: output_2_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - 2'd3: output_3_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - endcase - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 3740d7bf2..d0a28730a 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -108,17 +108,17 @@ wire rx_fifo_axis_tuser; wire rx_error_bad_frame_int; wire rx_error_bad_fcs_int; -reg [1:0] rx_sync_reg_1 = 0; -reg [1:0] rx_sync_reg_2 = 0; -reg [1:0] rx_sync_reg_3 = 0; -reg [1:0] rx_sync_reg_4 = 0; +reg [1:0] rx_sync_reg_1 = 2'd0; +reg [1:0] rx_sync_reg_2 = 2'd0; +reg [1:0] rx_sync_reg_3 = 2'd0; +reg [1:0] rx_sync_reg_4 = 2'd0; assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; always @(posedge rx_clk or posedge rx_rst) begin if (rx_rst) begin - rx_sync_reg_1 <= 0; + rx_sync_reg_1 <= 2'd0; end else begin rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_error_bad_frame_int, rx_error_bad_frame_int}; end @@ -126,9 +126,9 @@ end always @(posedge logic_clk or posedge logic_rst) begin if (logic_rst) begin - rx_sync_reg_2 <= 0; - rx_sync_reg_3 <= 0; - rx_sync_reg_4 <= 0; + rx_sync_reg_2 <= 2'd0; + rx_sync_reg_3 <= 2'd0; + rx_sync_reg_4 <= 2'd0; end else begin rx_sync_reg_2 <= rx_sync_reg_1; rx_sync_reg_3 <= rx_sync_reg_2; diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index f6814a044..333d2d5ca 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -67,11 +67,11 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [7:0] last_cycle_tkeep_reg = 0, last_cycle_tkeep_next; +reg [7:0] last_cycle_tkeep_reg = 8'd0, last_cycle_tkeep_next; -reg lanes_swapped = 0; -reg [31:0] swap_rxd = 0; -reg [3:0] swap_rxc = 0; +reg lanes_swapped = 1'b0; +reg [31:0] swap_rxd = 32'd0; +reg [3:0] swap_rxc = 4'd0; reg [63:0] xgmii_rxd_d0 = 64'h0707070707070707; reg [63:0] xgmii_rxd_d1 = 64'h0707070707070707; @@ -79,14 +79,14 @@ reg [63:0] xgmii_rxd_d1 = 64'h0707070707070707; reg [7:0] xgmii_rxc_d0 = 8'b11111111; reg [7:0] xgmii_rxc_d1 = 8'b11111111; -reg [63:0] output_axis_tdata_reg = 0, output_axis_tdata_next; -reg [7:0] output_axis_tkeep_reg = 0, output_axis_tkeep_next; -reg output_axis_tvalid_reg = 0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 0, output_axis_tlast_next; -reg output_axis_tuser_reg = 0, output_axis_tuser_next; +reg [63:0] output_axis_tdata_reg = 64'd0, output_axis_tdata_next; +reg [7:0] output_axis_tkeep_reg = 8'd0, output_axis_tkeep_next; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0, output_axis_tlast_next; +reg output_axis_tuser_reg = 1'b0, output_axis_tuser_next; -reg error_bad_frame_reg = 0, error_bad_frame_next; -reg error_bad_fcs_reg = 0, error_bad_fcs_next; +reg error_bad_frame_reg = 1'b0, error_bad_frame_next; +reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state3 = 32'hFFFFFFFF; @@ -103,7 +103,7 @@ wire crc_valid2 = crc_next2 == ~32'h2144df1c; wire crc_valid3 = crc_next3 == ~32'h2144df1c; wire crc_valid7 = crc_next7 == ~32'h2144df1c; -reg crc_valid7_save = 0; +reg crc_valid7_save = 1'b0; assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tkeep = output_axis_tkeep_reg; @@ -231,39 +231,39 @@ end always @* begin state_next = STATE_IDLE; - reset_crc = 0; - update_crc = 0; + reset_crc = 1'b0; + update_crc = 1'b0; last_cycle_tkeep_next = last_cycle_tkeep_reg; - output_axis_tdata_next = 0; - output_axis_tkeep_next = 0; - output_axis_tvalid_next = 0; - output_axis_tlast_next = 0; - output_axis_tuser_next = 0; + output_axis_tdata_next = 64'd0; + output_axis_tkeep_next = 8'd0; + output_axis_tvalid_next = 1'b0; + output_axis_tlast_next = 1'b0; + output_axis_tuser_next = 1'b0; - error_bad_frame_next = 0; - error_bad_fcs_next = 0; + error_bad_frame_next = 1'b0; + error_bad_fcs_next = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for packet - reset_crc = 1; + reset_crc = 1'b1; if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin // start condition if (detect_error_masked) begin // error in first data word - output_axis_tdata_next = 0; - output_axis_tkeep_next = 1; - output_axis_tvalid_next = 1; - output_axis_tlast_next = 1; - output_axis_tuser_next = 1; - error_bad_frame_next = 1; + output_axis_tdata_next = 64'd0; + output_axis_tkeep_next = 8'h01; + output_axis_tvalid_next = 1'b1; + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; state_next = STATE_IDLE; end else begin - reset_crc = 0; - update_crc = 1; + reset_crc = 1'b0; + update_crc = 1'b1; state_next = STATE_PAYLOAD; end end else begin @@ -272,27 +272,27 @@ always @* begin end STATE_PAYLOAD: begin // read payload - update_crc = 1; + update_crc = 1'b1; output_axis_tdata_next = xgmii_rxd_d1; output_axis_tkeep_next = ~xgmii_rxc_d1; - output_axis_tvalid_next = 1; - output_axis_tlast_next = 0; - output_axis_tuser_next = 0; + output_axis_tvalid_next = 1'b1; + output_axis_tlast_next = 1'b0; + output_axis_tuser_next = 1'b0; if (control_masked) begin // control or error characters in packet - output_axis_tlast_next = 1; - output_axis_tuser_next = 1; - error_bad_frame_next = 1; - reset_crc = 1; + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + reset_crc = 1'b1; state_next = STATE_IDLE; end else if (detect_term) begin if (detect_term[4:0]) begin // end this cycle - reset_crc = 1; + reset_crc = 1'b1; output_axis_tkeep_next = {tkeep_mask[3:0], 4'b1111}; - output_axis_tlast_next = 1; + output_axis_tlast_next = 1'b1; if ((detect_term[0] & crc_valid7_save) || (detect_term[1] & crc_valid0) || (detect_term[2] & crc_valid1) || @@ -300,9 +300,9 @@ always @* begin (detect_term[4] & crc_valid3)) begin // CRC valid end else begin - output_axis_tuser_next = 1; - error_bad_frame_next = 1; - error_bad_fcs_next = 1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; end state_next = STATE_IDLE; end else begin @@ -318,20 +318,20 @@ always @* begin // last cycle of packet output_axis_tdata_next = xgmii_rxd_d1; output_axis_tkeep_next = last_cycle_tkeep_reg; - output_axis_tvalid_next = 1; - output_axis_tlast_next = 1; - output_axis_tuser_next = 0; + output_axis_tvalid_next = 1'b1; + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b0; - reset_crc = 1; + reset_crc = 1'b1; if ((detect_term_save[5] & crc_valid0) || (detect_term_save[6] & crc_valid1) || (detect_term_save[7] & crc_valid2)) begin // CRC valid end else begin - output_axis_tuser_next = 1; - error_bad_frame_next = 1; - error_bad_fcs_next = 1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; end if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin @@ -348,22 +348,14 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - output_axis_tdata_reg <= 0; - output_axis_tkeep_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; - last_cycle_tkeep_reg <= 0; - - error_bad_frame_reg <= 0; - error_bad_fcs_reg <= 0; + error_bad_frame_reg <= 1'b0; + error_bad_fcs_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; crc_state3 <= 32'hFFFFFFFF; - crc_valid7_save <= 0; - - detect_term_save <= 0; + crc_valid7_save <= 1'b0; xgmii_rxd_d0 <= 64'h0707070707070707; xgmii_rxd_d1 <= 64'h0707070707070707; @@ -371,29 +363,21 @@ always @(posedge clk) begin xgmii_rxc_d0 <= 8'b11111111; xgmii_rxc_d1 <= 8'b11111111; - lanes_swapped <= 0; - swap_rxd <= 0; - swap_rxc <= 0; + lanes_swapped <= 1'b0; end else begin state_reg <= state_next; - output_axis_tdata_reg <= output_axis_tdata_next; - output_axis_tkeep_reg <= output_axis_tkeep_next; output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tlast_reg <= output_axis_tlast_next; - output_axis_tuser_reg <= output_axis_tuser_next; - - last_cycle_tkeep_reg <= last_cycle_tkeep_next; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; if (xgmii_rxc[0] && xgmii_rxd[7:0] == 8'hfb) begin - lanes_swapped <= 0; + lanes_swapped <= 1'b0; xgmii_rxd_d0 <= xgmii_rxd; xgmii_rxc_d0 <= xgmii_rxc; end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == 8'hfb) begin - lanes_swapped <= 1; + lanes_swapped <= 1'b1; xgmii_rxd_d0 <= 64'h0707070707070707; xgmii_rxc_d0 <= 8'b11111111; end else if (lanes_swapped) begin @@ -404,25 +388,32 @@ always @(posedge clk) begin xgmii_rxc_d0 <= xgmii_rxc; end - swap_rxd <= xgmii_rxd[63:32]; - swap_rxc <= xgmii_rxc[7:4]; - xgmii_rxd_d1 <= xgmii_rxd_d0; xgmii_rxc_d1 <= xgmii_rxc_d0; - detect_term_save <= detect_term; - // datapath if (reset_crc) begin crc_state <= 32'hFFFFFFFF; crc_state3 <= 32'hFFFFFFFF; - crc_valid7_save <= 0; + crc_valid7_save <= 1'b0; end else if (update_crc) begin crc_state <= crc_next7; crc_state3 <= crc_next3; crc_valid7_save <= crc_valid7; end end + + output_axis_tdata_reg <= output_axis_tdata_next; + output_axis_tkeep_reg <= output_axis_tkeep_next; + output_axis_tlast_reg <= output_axis_tlast_next; + output_axis_tuser_reg <= output_axis_tuser_next; + + last_cycle_tkeep_reg <= last_cycle_tkeep_next; + + detect_term_save <= detect_term; + + swap_rxd <= xgmii_rxd[63:32]; + swap_rxc <= xgmii_rxc[7:4]; end endmodule diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 94f049c75..32caeb5a1 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -83,14 +83,14 @@ reg update_crc; reg swap_lanes; reg unswap_lanes; -reg lanes_swapped = 0; -reg [31:0] swap_txd = 0; -reg [3:0] swap_txc = 0; +reg lanes_swapped = 1'b0; +reg [31:0] swap_txd = 32'd0; +reg [3:0] swap_txc = 4'd0; reg [63:0] input_axis_tdata_masked; -reg [63:0] input_tdata_reg = 0, input_tdata_next; -reg [7:0] input_tkeep_reg = 0, input_tkeep_next; +reg [63:0] input_tdata_reg = 64'd0, input_tdata_next; +reg [7:0] input_tkeep_reg = 8'd0, input_tkeep_next; reg [63:0] fcs_output_txd_0; reg [63:0] fcs_output_txd_1; @@ -99,12 +99,12 @@ reg [7:0] fcs_output_txc_1; reg [7:0] ifg_offset; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg [7:0] ifg_count_reg = 0, ifg_count_next; -reg [1:0] deficit_idle_count_reg = 0, deficit_idle_count_next; +reg [7:0] ifg_count_reg = 8'd0, ifg_count_next; +reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; @@ -184,15 +184,15 @@ eth_crc_64_inst ( function [3:0] keep2count; input [7:0] k; case (k) - 8'b00000000: keep2count = 0; - 8'b00000001: keep2count = 1; - 8'b00000011: keep2count = 2; - 8'b00000111: keep2count = 3; - 8'b00001111: keep2count = 4; - 8'b00011111: keep2count = 5; - 8'b00111111: keep2count = 6; - 8'b01111111: keep2count = 7; - 8'b11111111: keep2count = 8; + 8'b00000000: keep2count = 4'd0; + 8'b00000001: keep2count = 4'd1; + 8'b00000011: keep2count = 4'd2; + 8'b00000111: keep2count = 4'd3; + 8'b00001111: keep2count = 4'd4; + 8'b00011111: keep2count = 4'd5; + 8'b00111111: keep2count = 4'd6; + 8'b01111111: keep2count = 4'd7; + 8'b11111111: keep2count = 4'd8; endcase endfunction @@ -212,15 +212,12 @@ function [7:0] count2keep; endfunction // Mask input data +integer j; + always @* begin - input_axis_tdata_masked[ 7: 0] = input_axis_tkeep[0] ? input_axis_tdata[ 7: 0] : 8'd0; - input_axis_tdata_masked[15: 8] = input_axis_tkeep[1] ? input_axis_tdata[15: 8] : 8'd0; - input_axis_tdata_masked[23:16] = input_axis_tkeep[2] ? input_axis_tdata[23:16] : 8'd0; - input_axis_tdata_masked[31:24] = input_axis_tkeep[3] ? input_axis_tdata[31:24] : 8'd0; - input_axis_tdata_masked[39:32] = input_axis_tkeep[4] ? input_axis_tdata[39:32] : 8'd0; - input_axis_tdata_masked[47:40] = input_axis_tkeep[5] ? input_axis_tdata[47:40] : 8'd0; - input_axis_tdata_masked[55:48] = input_axis_tkeep[6] ? input_axis_tdata[55:48] : 8'd0; - input_axis_tdata_masked[63:56] = input_axis_tkeep[7] ? input_axis_tdata[63:56] : 8'd0; + for (j = 0; j < 8; j = j + 1) begin + input_axis_tdata_masked[j*8 +: 8] = input_axis_tkeep[j] ? input_axis_tdata[j*8 +: 8] : 8'd0; + end end // FCS cycle calculation @@ -231,63 +228,63 @@ always @* begin fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b11100000; fcs_output_txc_1 = 8'b11111111; - ifg_offset = 3; + ifg_offset = 8'd3; end 8'b00000011: begin fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], input_tdata_reg[15:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b11000000; fcs_output_txc_1 = 8'b11111111; - ifg_offset = 2; + ifg_offset = 8'd2; end 8'b00000111: begin fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], input_tdata_reg[23:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b10000000; fcs_output_txc_1 = 8'b11111111; - ifg_offset = 1; + ifg_offset = 8'd1; end 8'b00001111: begin fcs_output_txd_0 = {~crc_next3[31:0], input_tdata_reg[31:0]}; fcs_output_txd_1 = {63'h07070707070707fd}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111111; - ifg_offset = 8; + ifg_offset = 8'd8; end 8'b00011111: begin fcs_output_txd_0 = {~crc_next4[23:0], input_tdata_reg[39:0]}; fcs_output_txd_1 = {56'h070707070707fd, ~crc_next4[31:24]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111110; - ifg_offset = 7; + ifg_offset = 8'd7; end 8'b00111111: begin fcs_output_txd_0 = {~crc_next5[15:0], input_tdata_reg[47:0]}; fcs_output_txd_1 = {48'h0707070707fd, ~crc_next5[31:16]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111100; - ifg_offset = 6; + ifg_offset = 8'd6; end 8'b01111111: begin fcs_output_txd_0 = {~crc_next6[7:0], input_tdata_reg[55:0]}; fcs_output_txd_1 = {40'h07070707fd, ~crc_next6[31:8]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111000; - ifg_offset = 5; + ifg_offset = 8'd5; end 8'b11111111: begin fcs_output_txd_0 = input_tdata_reg; fcs_output_txd_1 = {32'h070707fd, ~crc_next7[31:0]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11110000; - ifg_offset = 4; + ifg_offset = 8'd4; end default: begin - fcs_output_txd_0 = 0; - fcs_output_txd_1 = 0; - fcs_output_txc_0 = 0; - fcs_output_txc_1 = 0; - ifg_offset = 0; + fcs_output_txd_0 = 64'd0; + fcs_output_txd_1 = 64'd0; + fcs_output_txc_0 = 8'd0; + fcs_output_txc_1 = 8'd0; + ifg_offset = 8'd0; end endcase end @@ -295,18 +292,18 @@ end always @* begin state_next = STATE_IDLE; - reset_crc = 0; - update_crc = 0; + reset_crc = 1'b0; + update_crc = 1'b0; - swap_lanes = 0; - unswap_lanes = 0; + swap_lanes = 1'b0; + unswap_lanes = 1'b0; frame_ptr_next = frame_ptr_reg; ifg_count_next = ifg_count_reg; deficit_idle_count_next = deficit_idle_count_reg; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; input_tdata_next = input_tdata_reg; input_tkeep_next = input_tkeep_reg; @@ -318,9 +315,9 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 8; - reset_crc = 1; - input_axis_tready_next = 1; + frame_ptr_next = 16'd8; + reset_crc = 1'b1; + input_axis_tready_next = 1'b1; // XGMII idle xgmii_txd_next = 64'h0707070707070707; @@ -331,30 +328,30 @@ always @* begin if (input_axis_tvalid) begin // XGMII start and preamble - if (ifg_count_reg > 0) begin + if (ifg_count_reg > 8'd0) begin // need to send more idles - swap lanes - swap_lanes = 1; + swap_lanes = 1'b1; end else begin // no more idles - unswap - unswap_lanes = 1; + unswap_lanes = 1'b1; end xgmii_txd_next = 64'hd5555555555555fb; xgmii_txc_next = 8'b00000001; - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_PAYLOAD; end else begin - ifg_count_next = 0; - deficit_idle_count_next = 0; - unswap_lanes = 1; + ifg_count_next = 8'd0; + deficit_idle_count_next = 2'd0; + unswap_lanes = 1'b1; state_next = STATE_IDLE; end end STATE_PAYLOAD: begin // transfer payload - update_crc = 1; - input_axis_tready_next = 1; + update_crc = 1'b1; + input_axis_tready_next = 1'b1; - frame_ptr_next = frame_ptr_reg + 8; + frame_ptr_next = frame_ptr_reg + 16'd8; xgmii_txd_next = input_tdata_reg; xgmii_txc_next = 8'b00000000; @@ -365,19 +362,19 @@ always @* begin if (input_axis_tvalid) begin if (input_axis_tlast) begin frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; if (input_axis_tuser) begin xgmii_txd_next = 64'h070707fdfefefefe; xgmii_txc_next = 8'b11111111; - frame_ptr_next = 0; - ifg_count_next = 8; + frame_ptr_next = 16'd0; + ifg_count_next = 8'd8; state_next = STATE_IFG; end else begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(input_axis_tkeep) < MIN_FL_NOCRC_LS))) begin input_tkeep_next = 8'hff; - frame_ptr_next = frame_ptr_reg + 8; + frame_ptr_next = frame_ptr_reg + 16'd8; if (frame_ptr_reg < MIN_FL_NOCRC_MS) begin state_next = STATE_PAD; @@ -396,22 +393,22 @@ always @* begin // tvalid deassert, fail frame xgmii_txd_next = 64'h070707fdfefefefe; xgmii_txc_next = 8'b11111111; - frame_ptr_next = 0; - ifg_count_next = 8; + frame_ptr_next = 16'd0; + ifg_count_next = 8'd8; state_next = STATE_WAIT_END; end end STATE_PAD: begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; xgmii_txd_next = input_tdata_reg; xgmii_txc_next = 8'b00000000; - input_tdata_next = 0; + input_tdata_next = 64'd0; input_tkeep_next = 8'hff; - update_crc = 1; - frame_ptr_next = frame_ptr_reg + 8; + update_crc = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd8; if (frame_ptr_reg < MIN_FL_NOCRC_MS) begin state_next = STATE_PAD; @@ -423,15 +420,15 @@ always @* begin end STATE_FCS_1: begin // last cycle - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; xgmii_txd_next = fcs_output_txd_0; xgmii_txc_next = fcs_output_txc_0; - frame_ptr_next = 0; + frame_ptr_next = 16'd0; - ifg_count_next = (ifg_delay > 12 ? ifg_delay : 12) - ifg_offset + (lanes_swapped ? 4 : 0) + deficit_idle_count_reg; - if (fcs_output_txc_1 != 8'hff || fcs_output_txc_0 == 0) begin + ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + (lanes_swapped ? 8'd4 : 8'd0) + deficit_idle_count_reg; + if (fcs_output_txc_1 != 8'hff || fcs_output_txc_0 == 8'd0) begin state_next = STATE_FCS_2; end else begin state_next = STATE_IFG; @@ -439,98 +436,98 @@ always @* begin end STATE_FCS_2: begin // last cycle - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; xgmii_txd_next = fcs_output_txd_1; xgmii_txc_next = fcs_output_txc_1; - reset_crc = 1; - frame_ptr_next = 0; + reset_crc = 1'b1; + frame_ptr_next = 16'd0; if (ENABLE_DIC) begin - if (ifg_count_next > 7) begin + if (ifg_count_next > 8'd7) begin state_next = STATE_IFG; end else begin - if (ifg_count_next >= 4) begin - deficit_idle_count_next = ifg_count_next - 4; + if (ifg_count_next >= 8'd4) begin + deficit_idle_count_next = ifg_count_next - 8'd4; end else begin deficit_idle_count_next = ifg_count_next; - ifg_count_next = 0; + ifg_count_next = 8'd0; end - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else begin - if (ifg_count_next > 4) begin + if (ifg_count_next > 8'd4) begin state_next = STATE_IFG; end else begin - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end end STATE_IFG: begin // send IFG - if (ifg_count_reg > 8) begin - ifg_count_next = ifg_count_reg - 8; + if (ifg_count_reg > 8'd8) begin + ifg_count_next = ifg_count_reg - 8'd8; end else begin - ifg_count_next = 0; + ifg_count_next = 8'd0; end - reset_crc = 1; + reset_crc = 1'b1; if (ENABLE_DIC) begin - if (ifg_count_next > 7) begin + if (ifg_count_next > 8'd7) begin state_next = STATE_IFG; end else begin - if (ifg_count_next >= 4) begin - deficit_idle_count_next = ifg_count_next - 4; + if (ifg_count_next >= 8'd4) begin + deficit_idle_count_next = ifg_count_next - 8'd4; end else begin deficit_idle_count_next = ifg_count_next; - ifg_count_next = 0; + ifg_count_next = 8'd0; end - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else begin - if (ifg_count_next > 4) begin + if (ifg_count_next > 8'd4) begin state_next = STATE_IFG; end else begin - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end end STATE_WAIT_END: begin // wait for end of frame - if (ifg_count_reg > 8) begin - ifg_count_next = ifg_count_reg - 8; + if (ifg_count_reg > 8'd8) begin + ifg_count_next = ifg_count_reg - 8'd8; end else begin - ifg_count_next = 0; + ifg_count_next = 8'd0; end - reset_crc = 1; + reset_crc = 1'b1; if (input_axis_tvalid) begin if (input_axis_tlast) begin if (ENABLE_DIC) begin - if (ifg_count_next > 7) begin + if (ifg_count_next > 8'd7) begin state_next = STATE_IFG; end else begin - if (ifg_count_next >= 4) begin - deficit_idle_count_next = ifg_count_next - 4; + if (ifg_count_next >= 8'd4) begin + deficit_idle_count_next = ifg_count_next - 8'd4; end else begin deficit_idle_count_next = ifg_count_next; - ifg_count_next = 0; + ifg_count_next = 8'd0; end - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else begin - if (ifg_count_next > 4) begin + if (ifg_count_next > 8'd4) begin state_next = STATE_IFG; end else begin - input_axis_tready_next = 1; + input_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end @@ -547,25 +544,20 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - - frame_ptr_reg <= 0; - ifg_count_reg <= 0; - deficit_idle_count_reg <= 0; + frame_ptr_reg <= 16'd0; - input_tdata_reg <= 0; - input_tkeep_reg <= 0; - - input_axis_tready_reg <= 0; + ifg_count_reg <= 8'd0; + deficit_idle_count_reg <= 2'd0; + + input_axis_tready_reg <= 1'b0; xgmii_txd_reg <= 64'h0707070707070707; xgmii_txc_reg <= 8'b11111111; crc_state <= 32'hFFFFFFFF; - lanes_swapped <= 0; - swap_txd <= 0; - swap_txc <= 0; + lanes_swapped <= 1'b0; end else begin state_reg <= state_next; @@ -574,14 +566,11 @@ always @(posedge clk) begin ifg_count_reg <= ifg_count_next; deficit_idle_count_reg <= deficit_idle_count_next; - input_tdata_reg <= input_tdata_next; - input_tkeep_reg <= input_tkeep_next; - input_axis_tready_reg <= input_axis_tready_next; if (lanes_swapped) begin if (unswap_lanes) begin - lanes_swapped <= 0; + lanes_swapped <= 1'b0; xgmii_txd_reg <= xgmii_txd_next; xgmii_txc_reg <= xgmii_txc_next; end else begin @@ -590,7 +579,7 @@ always @(posedge clk) begin end end else begin if (swap_lanes) begin - lanes_swapped <= 1; + lanes_swapped <= 1'b1; xgmii_txd_reg <= {xgmii_txd_next[31:0], 32'h07070707}; xgmii_txc_reg <= {xgmii_txc_next[3:0], 4'b1111}; end else begin @@ -599,9 +588,6 @@ always @(posedge clk) begin end end - swap_txd <= xgmii_txd_next[63:32]; - swap_txc <= xgmii_txc_next[7:4]; - // datapath if (reset_crc) begin crc_state <= 32'hFFFFFFFF; @@ -609,6 +595,12 @@ always @(posedge clk) begin crc_state <= crc_next7; end end + + input_tdata_reg <= input_tdata_next; + input_tkeep_reg <= input_tkeep_next; + + swap_txd <= xgmii_txd_next[63:32]; + swap_txc <= xgmii_txc_next[7:4]; end endmodule diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index 15b249b70..db4faeaf9 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -105,17 +105,17 @@ wire rx_fifo_axis_tuser; wire rx_error_bad_frame_int; wire rx_error_bad_fcs_int; -reg [1:0] rx_sync_reg_1 = 0; -reg [1:0] rx_sync_reg_2 = 0; -reg [1:0] rx_sync_reg_3 = 0; -reg [1:0] rx_sync_reg_4 = 0; +reg [1:0] rx_sync_reg_1 = 2'd0; +reg [1:0] rx_sync_reg_2 = 2'd0; +reg [1:0] rx_sync_reg_3 = 2'd0; +reg [1:0] rx_sync_reg_4 = 2'd0; assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; always @(posedge rx_clk or posedge rx_rst) begin if (rx_rst) begin - rx_sync_reg_1 <= 0; + rx_sync_reg_1 <= 2'd0; end else begin rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_error_bad_frame_int, rx_error_bad_frame_int}; end @@ -123,9 +123,9 @@ end always @(posedge logic_clk or posedge logic_rst) begin if (logic_rst) begin - rx_sync_reg_2 <= 0; - rx_sync_reg_3 <= 0; - rx_sync_reg_4 <= 0; + rx_sync_reg_2 <= 2'd0; + rx_sync_reg_3 <= 2'd0; + rx_sync_reg_4 <= 2'd0; end else begin rx_sync_reg_2 <= rx_sync_reg_1; rx_sync_reg_3 <= rx_sync_reg_2; diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v index ed4ec30d3..58522e692 100644 --- a/rtl/eth_mac_1g_rx.v +++ b/rtl/eth_mac_1g_rx.v @@ -67,31 +67,31 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [7:0] gmii_rxd_d0 = 0; -reg [7:0] gmii_rxd_d1 = 0; -reg [7:0] gmii_rxd_d2 = 0; -reg [7:0] gmii_rxd_d3 = 0; -reg [7:0] gmii_rxd_d4 = 0; +reg [7:0] gmii_rxd_d0 = 8'd0; +reg [7:0] gmii_rxd_d1 = 8'd0; +reg [7:0] gmii_rxd_d2 = 8'd0; +reg [7:0] gmii_rxd_d3 = 8'd0; +reg [7:0] gmii_rxd_d4 = 8'd0; -reg gmii_rx_dv_d0 = 0; -reg gmii_rx_dv_d1 = 0; -reg gmii_rx_dv_d2 = 0; -reg gmii_rx_dv_d3 = 0; -reg gmii_rx_dv_d4 = 0; +reg gmii_rx_dv_d0 = 1'b0; +reg gmii_rx_dv_d1 = 1'b0; +reg gmii_rx_dv_d2 = 1'b0; +reg gmii_rx_dv_d3 = 1'b0; +reg gmii_rx_dv_d4 = 1'b0; -reg gmii_rx_er_d0 = 0; -reg gmii_rx_er_d1 = 0; -reg gmii_rx_er_d2 = 0; -reg gmii_rx_er_d3 = 0; -reg gmii_rx_er_d4 = 0; +reg gmii_rx_er_d0 = 1'b0; +reg gmii_rx_er_d1 = 1'b0; +reg gmii_rx_er_d2 = 1'b0; +reg gmii_rx_er_d3 = 1'b0; +reg gmii_rx_er_d4 = 1'b0; -reg [7:0] output_axis_tdata_reg = 0, output_axis_tdata_next; -reg output_axis_tvalid_reg = 0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 0, output_axis_tlast_next; -reg output_axis_tuser_reg = 0, output_axis_tuser_next; +reg [7:0] output_axis_tdata_reg = 8'd0, output_axis_tdata_next; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0, output_axis_tlast_next; +reg output_axis_tuser_reg = 1'b0, output_axis_tuser_next; -reg error_bad_frame_reg = 0, error_bad_frame_next; -reg error_bad_fcs_reg = 0, error_bad_fcs_next; +reg error_bad_frame_reg = 1'b0, error_bad_frame_next; +reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; @@ -114,21 +114,21 @@ eth_crc_8_inst ( always @* begin state_next = STATE_IDLE; - reset_crc = 0; - update_crc = 0; + reset_crc = 1'b0; + update_crc = 1'b0; - output_axis_tdata_next = 0; - output_axis_tvalid_next = 0; - output_axis_tlast_next = 0; - output_axis_tuser_next = 0; + output_axis_tdata_next = 8'd0; + output_axis_tvalid_next = 1'b0; + output_axis_tlast_next = 1'b0; + output_axis_tuser_next = 1'b0; - error_bad_frame_next = 0; - error_bad_fcs_next = 0; + error_bad_frame_next = 1'b0; + error_bad_fcs_next = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for packet - reset_crc = 1; + reset_crc = 1'b1; if (gmii_rx_dv_d4 && ~gmii_rx_er_d4 && gmii_rxd_d4 == 8'hD5) begin state_next = STATE_PAYLOAD; @@ -138,32 +138,32 @@ always @* begin end STATE_PAYLOAD: begin // read payload - update_crc = 1; + update_crc = 1'b1; output_axis_tdata_next = gmii_rxd_d4; - output_axis_tvalid_next = 1; + output_axis_tvalid_next = 1'b1; if (gmii_rx_dv_d4 & gmii_rx_er_d4) begin // error - output_axis_tlast_next = 1; - output_axis_tuser_next = 1; - error_bad_frame_next = 1; + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; state_next = STATE_WAIT_LAST; end else if (~gmii_rx_dv) begin // end of packet - output_axis_tlast_next = 1; + output_axis_tlast_next = 1'b1; if (gmii_rx_er_d0 | gmii_rx_er_d1 | gmii_rx_er_d2 | gmii_rx_er_d3) begin // error received in FCS bytes - output_axis_tuser_next = 1; - error_bad_frame_next = 1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; end else if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin // FCS good - output_axis_tuser_next = 0; + output_axis_tuser_next = 1'b0; end else begin // FCS bad - output_axis_tuser_next = 1; - error_bad_frame_next = 1; - error_bad_fcs_next = 1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; end state_next = STATE_IDLE; end else begin @@ -186,22 +186,22 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - output_axis_tdata_reg <= 0; - output_axis_tvalid_reg <= 0; - output_axis_tlast_reg <= 0; - output_axis_tuser_reg <= 0; + output_axis_tvalid_reg <= 1'b0; - error_bad_frame_reg <= 0; - error_bad_fcs_reg <= 0; + error_bad_frame_reg <= 1'b0; + error_bad_fcs_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; + + gmii_rx_dv_d0 <= 1'b0; + gmii_rx_dv_d1 <= 1'b0; + gmii_rx_dv_d2 <= 1'b0; + gmii_rx_dv_d3 <= 1'b0; + gmii_rx_dv_d4 <= 1'b0; end else begin state_reg <= state_next; - output_axis_tdata_reg <= output_axis_tdata_next; output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tlast_reg <= output_axis_tlast_next; - output_axis_tuser_reg <= output_axis_tuser_next; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; @@ -212,8 +212,18 @@ always @(posedge clk) begin end else if (update_crc) begin crc_state <= crc_next; end + + gmii_rx_dv_d0 <= gmii_rx_dv; + gmii_rx_dv_d1 <= gmii_rx_dv_d0; + gmii_rx_dv_d2 <= gmii_rx_dv_d1; + gmii_rx_dv_d3 <= gmii_rx_dv_d2; + gmii_rx_dv_d4 <= gmii_rx_dv_d3; end + output_axis_tdata_reg <= output_axis_tdata_next; + output_axis_tlast_reg <= output_axis_tlast_next; + output_axis_tuser_reg <= output_axis_tuser_next; + // delay input gmii_rxd_d0 <= gmii_rxd; gmii_rxd_d1 <= gmii_rxd_d0; @@ -221,12 +231,6 @@ always @(posedge clk) begin gmii_rxd_d3 <= gmii_rxd_d2; gmii_rxd_d4 <= gmii_rxd_d3; - gmii_rx_dv_d0 <= gmii_rx_dv; - gmii_rx_dv_d1 <= gmii_rx_dv_d0; - gmii_rx_dv_d2 <= gmii_rx_dv_d1; - gmii_rx_dv_d3 <= gmii_rx_dv_d2; - gmii_rx_dv_d4 <= gmii_rx_dv_d3; - gmii_rx_er_d0 <= gmii_rx_er; gmii_rx_er_d1 <= gmii_rx_er_d0; gmii_rx_er_d2 <= gmii_rx_er_d1; diff --git a/rtl/eth_mac_1g_tx.v b/rtl/eth_mac_1g_tx.v index a9b2fff47..100ac6252 100644 --- a/rtl/eth_mac_1g_tx.v +++ b/rtl/eth_mac_1g_tx.v @@ -66,8 +66,8 @@ localparam [2:0] STATE_PAYLOAD = 3'd2, STATE_PAD = 3'd3, STATE_FCS = 3'd4, - STATE_IFG = 3'd5, - STATE_WAIT_END = 3'd6; + STATE_WAIT_END = 3'd5, + STATE_IFG = 3'd6; reg [2:0] state_reg = STATE_IDLE, state_next; @@ -75,13 +75,13 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg [7:0] gmii_txd_reg = 0, gmii_txd_next; -reg gmii_tx_en_reg = 0, gmii_tx_en_next; -reg gmii_tx_er_reg = 0, gmii_tx_er_next; +reg [7:0] gmii_txd_reg = 8'd0, gmii_txd_next; +reg gmii_tx_en_reg = 1'b0, gmii_tx_en_next; +reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next; -reg input_axis_tready_reg = 0, input_axis_tready_next; +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; @@ -102,26 +102,26 @@ eth_crc_8_inst ( always @* begin state_next = STATE_IDLE; - reset_crc = 0; - update_crc = 0; + reset_crc = 1'b0; + update_crc = 1'b0; frame_ptr_next = frame_ptr_reg; - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; - gmii_txd_next = 0; - gmii_tx_en_next = 0; - gmii_tx_er_next = 0; + gmii_txd_next = 8'd0; + gmii_tx_en_next = 1'b0; + gmii_tx_er_next = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for packet - reset_crc = 1; + reset_crc = 1'b1; if (input_axis_tvalid) begin - frame_ptr_next = 1; + frame_ptr_next = 16'd1; gmii_txd_next = 8'h55; // Preamble - gmii_tx_en_next = 1; + gmii_tx_en_next = 1'b1; state_next = STATE_PREAMBLE; end else begin state_next = STATE_IDLE; @@ -129,16 +129,16 @@ always @* begin end STATE_PREAMBLE: begin // send preamble - reset_crc = 1; - frame_ptr_next = frame_ptr_reg + 1; + reset_crc = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd1; gmii_txd_next = 8'h55; // Preamble - gmii_tx_en_next = 1; + gmii_tx_en_next = 1'b1; - if (frame_ptr_reg == 7) begin + if (frame_ptr_reg == 16'd7) begin // end of preamble; start payload - frame_ptr_next = 0; - input_axis_tready_next = 1; + frame_ptr_next = 16'd0; + input_axis_tready_next = 1'b1; gmii_txd_next = 8'hD5; // SFD state_next = STATE_PAYLOAD; end else begin @@ -147,26 +147,26 @@ always @* begin end STATE_PAYLOAD: begin // send payload - update_crc = 1; - input_axis_tready_next = 1; + update_crc = 1'b1; + input_axis_tready_next = 1'b1; - frame_ptr_next = frame_ptr_reg + 1; + frame_ptr_next = frame_ptr_reg + 16'd1; gmii_txd_next = input_axis_tdata; - gmii_tx_en_next = 1; + gmii_tx_en_next = 1'b1; if (input_axis_tvalid) begin if (input_axis_tlast) begin - input_axis_tready_next = 0; + input_axis_tready_next = 1'b0; if (input_axis_tuser) begin - gmii_tx_er_next = 1; - frame_ptr_next = 0; + gmii_tx_er_next = 1'b1; + frame_ptr_next = 1'b0; state_next = STATE_IFG; end else begin if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin state_next = STATE_PAD; end else begin - frame_ptr_next = 0; + frame_ptr_next = 16'd0; state_next = STATE_FCS; end end @@ -175,29 +175,29 @@ always @* begin end end else begin // tvalid deassert, fail frame - gmii_tx_er_next = 1; - frame_ptr_next = 0; + gmii_tx_er_next = 1'b1; + frame_ptr_next = 16'd0; state_next = STATE_WAIT_END; end end STATE_PAD: begin // send padding - update_crc = 1; - frame_ptr_next = frame_ptr_reg + 1; + update_crc = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd1; - gmii_txd_next = 0; - gmii_tx_en_next = 1; + gmii_txd_next = 8'd0; + gmii_tx_en_next = 1'b1; if (frame_ptr_reg < MIN_FRAME_LENGTH-5) begin state_next = STATE_PAD; end else begin - frame_ptr_next = 0; + frame_ptr_next = 16'd0; state_next = STATE_FCS; end end STATE_FCS: begin // send FCS - frame_ptr_next = frame_ptr_reg + 1; + frame_ptr_next = frame_ptr_reg + 16'd1; case (frame_ptr_reg) 2'd0: gmii_txd_next = ~crc_state[7:0]; @@ -205,30 +205,19 @@ always @* begin 2'd2: gmii_txd_next = ~crc_state[23:16]; 2'd3: gmii_txd_next = ~crc_state[31:24]; endcase - gmii_tx_en_next = 1; + gmii_tx_en_next = 1'b1; if (frame_ptr_reg < 3) begin state_next = STATE_FCS; end else begin - frame_ptr_next = 0; + frame_ptr_next = 16'd0; state_next = STATE_IFG; end end - STATE_IFG: begin - // send IFG - frame_ptr_next = frame_ptr_reg + 1; - reset_crc = 1; - - if (frame_ptr_reg < ifg_delay-1) begin - state_next = STATE_IFG; - end else begin - state_next = STATE_IDLE; - end - end STATE_WAIT_END: begin // wait for end of frame - frame_ptr_next = frame_ptr_reg + 1; - reset_crc = 1; + frame_ptr_next = frame_ptr_reg + 16'd1; + reset_crc = 1'b1; if (input_axis_tvalid) begin if (input_axis_tlast) begin @@ -244,6 +233,17 @@ always @* begin state_next = STATE_WAIT_END; end end + STATE_IFG: begin + // send IFG + frame_ptr_next = frame_ptr_reg + 16'd1; + reset_crc = 1'b1; + + if (frame_ptr_reg < ifg_delay-1) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end endcase end @@ -251,13 +251,13 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; + frame_ptr_reg <= 16'd0; - input_axis_tready_reg <= 0; + input_axis_tready_reg <= 1'b0; - gmii_txd_reg <= 0; - gmii_tx_en_reg <= 0; - gmii_tx_er_reg <= 0; + gmii_txd_reg <= 8'd0; + gmii_tx_en_reg <= 1'b0; + gmii_tx_er_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; end else begin diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index 27fb7ab23..ce0e54034 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -110,24 +110,24 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; {% for p in ports %} -reg input_{{p}}_eth_hdr_ready_reg = 0, input_{{p}}_eth_hdr_ready_next; +reg input_{{p}}_eth_hdr_ready_reg = 1'b0, input_{{p}}_eth_hdr_ready_next; {%- endfor %} {% for p in ports %} -reg input_{{p}}_eth_payload_tready_reg = 0, input_{{p}}_eth_payload_tready_next; +reg input_{{p}}_eth_payload_tready_reg = 1'b0, input_{{p}}_eth_payload_tready_next; {%- endfor %} -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; // internal datapath reg [7:0] output_eth_payload_tdata_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -158,6 +158,12 @@ always @* begin selected_input_eth_type = input_{{p}}_eth_type; end {%- endfor %} + default: begin + selected_input_eth_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + end endcase end @@ -178,6 +184,13 @@ always @* begin current_input_tuser = input_{{p}}_eth_payload_tuser; end {%- endfor %} + default: begin + current_input_tdata = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -188,7 +201,7 @@ always @* begin input_{{p}}_eth_hdr_ready_next = input_{{p}}_eth_hdr_ready_reg & ~input_{{p}}_eth_hdr_valid; {%- endfor %} {% for p in ports %} - input_{{p}}_eth_payload_tready_next = 0; + input_{{p}}_eth_payload_tready_next = 1'b0; {%- endfor %} output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; @@ -203,16 +216,16 @@ always @* begin end end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) {%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_eth_hdr_ready_next = 1; + {{w}}'d{{p}}: input_{{p}}_eth_hdr_ready_next = 1'b1; {%- endfor %} endcase - output_eth_hdr_valid_next = 1; + output_eth_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -234,18 +247,15 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; {%- for p in ports %} - input_{{p}}_eth_hdr_ready_reg <= 0; + input_{{p}}_eth_hdr_ready_reg <= 1'b0; {%- endfor %} {%- for p in ports %} - input_{{p}}_eth_payload_tready_reg <= 0; + input_{{p}}_eth_payload_tready_reg <= 1'b0; {%- endfor %} - output_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; + output_eth_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -256,72 +266,91 @@ always @(posedge clk) begin input_{{p}}_eth_payload_tready_reg <= input_{{p}}_eth_payload_tready_next; {%- endfor %} output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [7:0] output_eth_payload_tdata_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [7:0] temp_eth_payload_tdata_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [7:0] temp_eth_payload_tdata_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_mux_2.v b/rtl/eth_mux_2.v index c63a6337b..12b0330eb 100644 --- a/rtl/eth_mux_2.v +++ b/rtl/eth_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -80,24 +80,24 @@ module eth_mux_2 input wire [0:0] select ); -reg [0:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [0:0] select_reg = 1'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_eth_hdr_ready_reg = 0, input_0_eth_hdr_ready_next; -reg input_1_eth_hdr_ready_reg = 0, input_1_eth_hdr_ready_next; +reg input_0_eth_hdr_ready_reg = 1'b0, input_0_eth_hdr_ready_next; +reg input_1_eth_hdr_ready_reg = 1'b0, input_1_eth_hdr_ready_next; -reg input_0_eth_payload_tready_reg = 0, input_0_eth_payload_tready_next; -reg input_1_eth_payload_tready_reg = 0, input_1_eth_payload_tready_next; +reg input_0_eth_payload_tready_reg = 1'b0, input_0_eth_payload_tready_next; +reg input_1_eth_payload_tready_reg = 1'b0, input_1_eth_payload_tready_next; -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; // internal datapath reg [7:0] output_eth_payload_tdata_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -132,6 +132,12 @@ always @* begin selected_input_eth_src_mac = input_1_eth_src_mac; selected_input_eth_type = input_1_eth_type; end + default: begin + selected_input_eth_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + end endcase end @@ -157,6 +163,13 @@ always @* begin current_input_tlast = input_1_eth_payload_tlast; current_input_tuser = input_1_eth_payload_tuser; end + default: begin + current_input_tdata = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -167,8 +180,8 @@ always @* begin input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_reg & ~input_0_eth_hdr_valid; input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_reg & ~input_1_eth_hdr_valid; - input_0_eth_payload_tready_next = 0; - input_1_eth_payload_tready_next = 0; + input_0_eth_payload_tready_next = 1'b0; + input_1_eth_payload_tready_next = 1'b0; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; output_eth_dest_mac_next = output_eth_dest_mac_reg; @@ -182,15 +195,15 @@ always @* begin end end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) - 1'd0: input_0_eth_hdr_ready_next = 1; - 1'd1: input_1_eth_hdr_ready_next = 1; + 1'd0: input_0_eth_hdr_ready_next = 1'b1; + 1'd1: input_1_eth_hdr_ready_next = 1'b1; endcase - output_eth_hdr_valid_next = 1; + output_eth_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -211,16 +224,13 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_eth_hdr_ready_reg <= 0; - input_1_eth_hdr_ready_reg <= 0; - input_0_eth_payload_tready_reg <= 0; - input_1_eth_payload_tready_reg <= 0; - output_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; + select_reg <= 1'd0; + frame_reg <= 1'b0; + input_0_eth_hdr_ready_reg <= 1'b0; + input_1_eth_hdr_ready_reg <= 1'b0; + input_0_eth_payload_tready_reg <= 1'b0; + input_1_eth_payload_tready_reg <= 1'b0; + output_eth_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -229,72 +239,91 @@ always @(posedge clk) begin input_0_eth_payload_tready_reg <= input_0_eth_payload_tready_next; input_1_eth_payload_tready_reg <= input_1_eth_payload_tready_next; output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [7:0] output_eth_payload_tdata_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [7:0] temp_eth_payload_tdata_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [7:0] temp_eth_payload_tdata_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v index ac2ce44c1..3bc5eea31 100644 --- a/rtl/eth_mux_4.v +++ b/rtl/eth_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -102,28 +102,28 @@ module eth_mux_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_eth_hdr_ready_reg = 0, input_0_eth_hdr_ready_next; -reg input_1_eth_hdr_ready_reg = 0, input_1_eth_hdr_ready_next; -reg input_2_eth_hdr_ready_reg = 0, input_2_eth_hdr_ready_next; -reg input_3_eth_hdr_ready_reg = 0, input_3_eth_hdr_ready_next; +reg input_0_eth_hdr_ready_reg = 1'b0, input_0_eth_hdr_ready_next; +reg input_1_eth_hdr_ready_reg = 1'b0, input_1_eth_hdr_ready_next; +reg input_2_eth_hdr_ready_reg = 1'b0, input_2_eth_hdr_ready_next; +reg input_3_eth_hdr_ready_reg = 1'b0, input_3_eth_hdr_ready_next; -reg input_0_eth_payload_tready_reg = 0, input_0_eth_payload_tready_next; -reg input_1_eth_payload_tready_reg = 0, input_1_eth_payload_tready_next; -reg input_2_eth_payload_tready_reg = 0, input_2_eth_payload_tready_next; -reg input_3_eth_payload_tready_reg = 0, input_3_eth_payload_tready_next; +reg input_0_eth_payload_tready_reg = 1'b0, input_0_eth_payload_tready_next; +reg input_1_eth_payload_tready_reg = 1'b0, input_1_eth_payload_tready_next; +reg input_2_eth_payload_tready_reg = 1'b0, input_2_eth_payload_tready_next; +reg input_3_eth_payload_tready_reg = 1'b0, input_3_eth_payload_tready_next; -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; // internal datapath reg [7:0] output_eth_payload_tdata_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -174,6 +174,12 @@ always @* begin selected_input_eth_src_mac = input_3_eth_src_mac; selected_input_eth_type = input_3_eth_type; end + default: begin + selected_input_eth_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + end endcase end @@ -213,6 +219,13 @@ always @* begin current_input_tlast = input_3_eth_payload_tlast; current_input_tuser = input_3_eth_payload_tuser; end + default: begin + current_input_tdata = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -225,10 +238,10 @@ always @* begin input_2_eth_hdr_ready_next = input_2_eth_hdr_ready_reg & ~input_2_eth_hdr_valid; input_3_eth_hdr_ready_next = input_3_eth_hdr_ready_reg & ~input_3_eth_hdr_valid; - input_0_eth_payload_tready_next = 0; - input_1_eth_payload_tready_next = 0; - input_2_eth_payload_tready_next = 0; - input_3_eth_payload_tready_next = 0; + input_0_eth_payload_tready_next = 1'b0; + input_1_eth_payload_tready_next = 1'b0; + input_2_eth_payload_tready_next = 1'b0; + input_3_eth_payload_tready_next = 1'b0; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; output_eth_dest_mac_next = output_eth_dest_mac_reg; @@ -242,17 +255,17 @@ always @* begin end end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) - 2'd0: input_0_eth_hdr_ready_next = 1; - 2'd1: input_1_eth_hdr_ready_next = 1; - 2'd2: input_2_eth_hdr_ready_next = 1; - 2'd3: input_3_eth_hdr_ready_next = 1; + 2'd0: input_0_eth_hdr_ready_next = 1'b1; + 2'd1: input_1_eth_hdr_ready_next = 1'b1; + 2'd2: input_2_eth_hdr_ready_next = 1'b1; + 2'd3: input_3_eth_hdr_ready_next = 1'b1; endcase - output_eth_hdr_valid_next = 1; + output_eth_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -275,20 +288,17 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_eth_hdr_ready_reg <= 0; - input_1_eth_hdr_ready_reg <= 0; - input_2_eth_hdr_ready_reg <= 0; - input_3_eth_hdr_ready_reg <= 0; - input_0_eth_payload_tready_reg <= 0; - input_1_eth_payload_tready_reg <= 0; - input_2_eth_payload_tready_reg <= 0; - input_3_eth_payload_tready_reg <= 0; - output_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_0_eth_hdr_ready_reg <= 1'b0; + input_1_eth_hdr_ready_reg <= 1'b0; + input_2_eth_hdr_ready_reg <= 1'b0; + input_3_eth_hdr_ready_reg <= 1'b0; + input_0_eth_payload_tready_reg <= 1'b0; + input_1_eth_payload_tready_reg <= 1'b0; + input_2_eth_payload_tready_reg <= 1'b0; + input_3_eth_payload_tready_reg <= 1'b0; + output_eth_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -301,72 +311,91 @@ always @(posedge clk) begin input_2_eth_payload_tready_reg <= input_2_eth_payload_tready_next; input_3_eth_payload_tready_reg <= input_3_eth_payload_tready_next; output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [7:0] output_eth_payload_tdata_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [7:0] temp_eth_payload_tdata_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [7:0] temp_eth_payload_tdata_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index 36c47b0f9..b4c5aa460 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -112,25 +112,25 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; {% for p in ports %} -reg input_{{p}}_eth_hdr_ready_reg = 0, input_{{p}}_eth_hdr_ready_next; +reg input_{{p}}_eth_hdr_ready_reg = 1'b0, input_{{p}}_eth_hdr_ready_next; {%- endfor %} {% for p in ports %} -reg input_{{p}}_eth_payload_tready_reg = 0, input_{{p}}_eth_payload_tready_next; +reg input_{{p}}_eth_payload_tready_reg = 1'b0, input_{{p}}_eth_payload_tready_next; {%- endfor %} -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; // internal datapath reg [63:0] output_eth_payload_tdata_int; reg [7:0] output_eth_payload_tkeep_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -161,6 +161,12 @@ always @* begin selected_input_eth_type = input_{{p}}_eth_type; end {%- endfor %} + default: begin + selected_input_eth_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + end endcase end @@ -183,6 +189,14 @@ always @* begin current_input_tuser = input_{{p}}_eth_payload_tuser; end {%- endfor %} + default: begin + current_input_tdata = 64'd0; + current_input_tkeep = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -193,7 +207,7 @@ always @* begin input_{{p}}_eth_hdr_ready_next = input_{{p}}_eth_hdr_ready_reg & ~input_{{p}}_eth_hdr_valid; {%- endfor %} {% for p in ports %} - input_{{p}}_eth_payload_tready_next = 0; + input_{{p}}_eth_payload_tready_next = 1'b0; {%- endfor %} output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; @@ -208,16 +222,16 @@ always @* begin end end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) {%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_eth_hdr_ready_next = 1; + {{w}}'d{{p}}: input_{{p}}_eth_hdr_ready_next = 1'b1; {%- endfor %} endcase - output_eth_hdr_valid_next = 1; + output_eth_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -240,18 +254,15 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; {%- for p in ports %} - input_{{p}}_eth_hdr_ready_reg <= 0; + input_{{p}}_eth_hdr_ready_reg <= 1'b0; {%- endfor %} {%- for p in ports %} - input_{{p}}_eth_payload_tready_reg <= 0; + input_{{p}}_eth_payload_tready_reg <= 1'b0; {%- endfor %} - output_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; + output_eth_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -262,24 +273,30 @@ always @(posedge clk) begin input_{{p}}_eth_payload_tready_reg <= input_{{p}}_eth_payload_tready_next; {%- endfor %} output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; end // output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [63:0] output_eth_payload_tdata_reg = 64'd0; +reg [7:0] output_eth_payload_tkeep_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [63:0] temp_eth_payload_tdata_reg = 0; -reg [7:0] temp_eth_payload_tkeep_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [63:0] temp_eth_payload_tdata_reg = 64'd0; +reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; @@ -287,56 +304,66 @@ assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tkeep_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_mux_64_2.v b/rtl/eth_mux_64_2.v index e9b95d2b5..7281e7d93 100644 --- a/rtl/eth_mux_64_2.v +++ b/rtl/eth_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -83,25 +83,25 @@ module eth_mux_64_2 input wire [0:0] select ); -reg [0:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [0:0] select_reg = 1'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_eth_hdr_ready_reg = 0, input_0_eth_hdr_ready_next; -reg input_1_eth_hdr_ready_reg = 0, input_1_eth_hdr_ready_next; +reg input_0_eth_hdr_ready_reg = 1'b0, input_0_eth_hdr_ready_next; +reg input_1_eth_hdr_ready_reg = 1'b0, input_1_eth_hdr_ready_next; -reg input_0_eth_payload_tready_reg = 0, input_0_eth_payload_tready_next; -reg input_1_eth_payload_tready_reg = 0, input_1_eth_payload_tready_next; +reg input_0_eth_payload_tready_reg = 1'b0, input_0_eth_payload_tready_next; +reg input_1_eth_payload_tready_reg = 1'b0, input_1_eth_payload_tready_next; -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; // internal datapath reg [63:0] output_eth_payload_tdata_int; reg [7:0] output_eth_payload_tkeep_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -136,6 +136,12 @@ always @* begin selected_input_eth_src_mac = input_1_eth_src_mac; selected_input_eth_type = input_1_eth_type; end + default: begin + selected_input_eth_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + end endcase end @@ -164,6 +170,14 @@ always @* begin current_input_tlast = input_1_eth_payload_tlast; current_input_tuser = input_1_eth_payload_tuser; end + default: begin + current_input_tdata = 64'd0; + current_input_tkeep = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -174,8 +188,8 @@ always @* begin input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_reg & ~input_0_eth_hdr_valid; input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_reg & ~input_1_eth_hdr_valid; - input_0_eth_payload_tready_next = 0; - input_1_eth_payload_tready_next = 0; + input_0_eth_payload_tready_next = 1'b0; + input_1_eth_payload_tready_next = 1'b0; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; output_eth_dest_mac_next = output_eth_dest_mac_reg; @@ -189,15 +203,15 @@ always @* begin end end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) - 1'd0: input_0_eth_hdr_ready_next = 1; - 1'd1: input_1_eth_hdr_ready_next = 1; + 1'd0: input_0_eth_hdr_ready_next = 1'b1; + 1'd1: input_1_eth_hdr_ready_next = 1'b1; endcase - output_eth_hdr_valid_next = 1; + output_eth_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -219,16 +233,13 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_eth_hdr_ready_reg <= 0; - input_1_eth_hdr_ready_reg <= 0; - input_0_eth_payload_tready_reg <= 0; - input_1_eth_payload_tready_reg <= 0; - output_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; + select_reg <= 1'd0; + frame_reg <= 1'b0; + input_0_eth_hdr_ready_reg <= 1'b0; + input_1_eth_hdr_ready_reg <= 1'b0; + input_0_eth_payload_tready_reg <= 1'b0; + input_1_eth_payload_tready_reg <= 1'b0; + output_eth_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -237,24 +248,30 @@ always @(posedge clk) begin input_0_eth_payload_tready_reg <= input_0_eth_payload_tready_next; input_1_eth_payload_tready_reg <= input_1_eth_payload_tready_next; output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; end // output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [63:0] output_eth_payload_tdata_reg = 64'd0; +reg [7:0] output_eth_payload_tkeep_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [63:0] temp_eth_payload_tdata_reg = 0; -reg [7:0] temp_eth_payload_tkeep_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [63:0] temp_eth_payload_tdata_reg = 64'd0; +reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; @@ -262,56 +279,66 @@ assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tkeep_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v index a8cd75a3e..e3afd6267 100644 --- a/rtl/eth_mux_64_4.v +++ b/rtl/eth_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -107,29 +107,29 @@ module eth_mux_64_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_eth_hdr_ready_reg = 0, input_0_eth_hdr_ready_next; -reg input_1_eth_hdr_ready_reg = 0, input_1_eth_hdr_ready_next; -reg input_2_eth_hdr_ready_reg = 0, input_2_eth_hdr_ready_next; -reg input_3_eth_hdr_ready_reg = 0, input_3_eth_hdr_ready_next; +reg input_0_eth_hdr_ready_reg = 1'b0, input_0_eth_hdr_ready_next; +reg input_1_eth_hdr_ready_reg = 1'b0, input_1_eth_hdr_ready_next; +reg input_2_eth_hdr_ready_reg = 1'b0, input_2_eth_hdr_ready_next; +reg input_3_eth_hdr_ready_reg = 1'b0, input_3_eth_hdr_ready_next; -reg input_0_eth_payload_tready_reg = 0, input_0_eth_payload_tready_next; -reg input_1_eth_payload_tready_reg = 0, input_1_eth_payload_tready_next; -reg input_2_eth_payload_tready_reg = 0, input_2_eth_payload_tready_next; -reg input_3_eth_payload_tready_reg = 0, input_3_eth_payload_tready_next; +reg input_0_eth_payload_tready_reg = 1'b0, input_0_eth_payload_tready_next; +reg input_1_eth_payload_tready_reg = 1'b0, input_1_eth_payload_tready_next; +reg input_2_eth_payload_tready_reg = 1'b0, input_2_eth_payload_tready_next; +reg input_3_eth_payload_tready_reg = 1'b0, input_3_eth_payload_tready_next; -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; // internal datapath reg [63:0] output_eth_payload_tdata_int; reg [7:0] output_eth_payload_tkeep_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -180,6 +180,12 @@ always @* begin selected_input_eth_src_mac = input_3_eth_src_mac; selected_input_eth_type = input_3_eth_type; end + default: begin + selected_input_eth_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + end endcase end @@ -224,6 +230,14 @@ always @* begin current_input_tlast = input_3_eth_payload_tlast; current_input_tuser = input_3_eth_payload_tuser; end + default: begin + current_input_tdata = 64'd0; + current_input_tkeep = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -236,10 +250,10 @@ always @* begin input_2_eth_hdr_ready_next = input_2_eth_hdr_ready_reg & ~input_2_eth_hdr_valid; input_3_eth_hdr_ready_next = input_3_eth_hdr_ready_reg & ~input_3_eth_hdr_valid; - input_0_eth_payload_tready_next = 0; - input_1_eth_payload_tready_next = 0; - input_2_eth_payload_tready_next = 0; - input_3_eth_payload_tready_next = 0; + input_0_eth_payload_tready_next = 1'b0; + input_1_eth_payload_tready_next = 1'b0; + input_2_eth_payload_tready_next = 1'b0; + input_3_eth_payload_tready_next = 1'b0; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; output_eth_dest_mac_next = output_eth_dest_mac_reg; @@ -253,17 +267,17 @@ always @* begin end end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) - 2'd0: input_0_eth_hdr_ready_next = 1; - 2'd1: input_1_eth_hdr_ready_next = 1; - 2'd2: input_2_eth_hdr_ready_next = 1; - 2'd3: input_3_eth_hdr_ready_next = 1; + 2'd0: input_0_eth_hdr_ready_next = 1'b1; + 2'd1: input_1_eth_hdr_ready_next = 1'b1; + 2'd2: input_2_eth_hdr_ready_next = 1'b1; + 2'd3: input_3_eth_hdr_ready_next = 1'b1; endcase - output_eth_hdr_valid_next = 1; + output_eth_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -287,20 +301,17 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_eth_hdr_ready_reg <= 0; - input_1_eth_hdr_ready_reg <= 0; - input_2_eth_hdr_ready_reg <= 0; - input_3_eth_hdr_ready_reg <= 0; - input_0_eth_payload_tready_reg <= 0; - input_1_eth_payload_tready_reg <= 0; - input_2_eth_payload_tready_reg <= 0; - input_3_eth_payload_tready_reg <= 0; - output_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_0_eth_hdr_ready_reg <= 1'b0; + input_1_eth_hdr_ready_reg <= 1'b0; + input_2_eth_hdr_ready_reg <= 1'b0; + input_3_eth_hdr_ready_reg <= 1'b0; + input_0_eth_payload_tready_reg <= 1'b0; + input_1_eth_payload_tready_reg <= 1'b0; + input_2_eth_payload_tready_reg <= 1'b0; + input_3_eth_payload_tready_reg <= 1'b0; + output_eth_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -313,24 +324,30 @@ always @(posedge clk) begin input_2_eth_payload_tready_reg <= input_2_eth_payload_tready_next; input_3_eth_payload_tready_reg <= input_3_eth_payload_tready_next; output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; end // output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [63:0] output_eth_payload_tdata_reg = 64'd0; +reg [7:0] output_eth_payload_tkeep_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [63:0] temp_eth_payload_tdata_reg = 0; -reg [7:0] temp_eth_payload_tkeep_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [63:0] temp_eth_payload_tdata_reg = 64'd0; +reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; @@ -338,56 +355,66 @@ assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tkeep_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/gmii_phy_if.v b/rtl/gmii_phy_if.v index 5f9d29eb1..cc3cf67fc 100644 --- a/rtl/gmii_phy_if.v +++ b/rtl/gmii_phy_if.v @@ -102,11 +102,11 @@ if (TARGET_XILINX) begin .Q(phy_gmii_tx_clk), .C0(phy_gmii_tx_clk_int), .C1(~phy_gmii_tx_clk_int), - .CE(1), - .D0(0), - .D1(1), - .R(0), - .S(0) + .CE(1'b1), + .D0(1'b0), + .D1(1'b1), + .R(1'b0), + .S(1'b0) ); end else begin @@ -156,11 +156,11 @@ end // register RX data from PHY to MAC (* IOB = "TRUE" *) -reg [7:0] gmii_rxd_reg = 0; +reg [7:0] gmii_rxd_reg = 8'd0; (* IOB = "TRUE" *) -reg gmii_rx_dv_reg = 0; +reg gmii_rx_dv_reg = 1'b0; (* IOB = "TRUE" *) -reg gmii_rx_er_reg = 0; +reg gmii_rx_er_reg = 1'b0; always @(posedge phy_gmii_rx_clk_io) begin gmii_rxd_reg <= phy_gmii_rxd; @@ -174,11 +174,11 @@ assign mac_gmii_rx_er = gmii_rx_er_reg; // register TX data from MAC to PHY (* IOB = "TRUE" *) -reg [7:0] gmii_txd_reg = 0; +reg [7:0] gmii_txd_reg = 8'd0; (* IOB = "TRUE" *) -reg gmii_tx_en_reg = 0; +reg gmii_tx_en_reg = 1'b0; (* IOB = "TRUE" *) -reg gmii_tx_er_reg = 0; +reg gmii_tx_er_reg = 1'b0; always @(posedge phy_gmii_tx_clk_int) begin gmii_txd_reg <= mac_gmii_txd; diff --git a/rtl/ip.v b/rtl/ip.v index e4ff38717..7cdcfc6d2 100644 --- a/rtl/ip.v +++ b/rtl/ip.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -238,11 +238,11 @@ ip_eth_tx_inst ( .error_payload_early_termination(tx_error_payload_early_termination) ); -reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; +reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; -reg arp_request_valid_reg = 0, arp_request_valid_next; +reg arp_request_valid_reg = 1'b0, arp_request_valid_next; -reg drop_packet_reg = 0, drop_packet_next; +reg drop_packet_reg = 1'b0, drop_packet_next; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; @@ -255,10 +255,10 @@ assign tx_error_arp_failed = arp_response_error; always @* begin state_next = STATE_IDLE; - arp_request_valid_next = 0; - drop_packet_next = 0; + arp_request_valid_next = 1'b0; + drop_packet_next = 1'b0; - input_ip_hdr_ready_next = 0; + input_ip_hdr_ready_next = 1'b0; outgoing_ip_hdr_valid_next = outgoing_ip_hdr_valid_reg & ~outgoing_ip_hdr_ready; outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; @@ -268,7 +268,7 @@ always @* begin // wait for outgoing packet if (input_ip_hdr_valid) begin // initiate ARP request - arp_request_valid_next = 1; + arp_request_valid_next = 1'b1; state_next = STATE_ARP_QUERY; end else begin state_next = STATE_IDLE; @@ -281,15 +281,15 @@ always @* begin // wait for ARP reponse if (arp_response_error) begin // did not get MAC address; drop packet - input_ip_hdr_ready_next = 1; - arp_request_valid_next = 0; - drop_packet_next = 1; + input_ip_hdr_ready_next = 1'b1; + arp_request_valid_next = 1'b0; + drop_packet_next = 1'b1; state_next = STATE_WAIT_PACKET; end else begin // got MAC address; send packet - input_ip_hdr_ready_next = 1; - arp_request_valid_next = 0; - outgoing_ip_hdr_valid_next = 1; + input_ip_hdr_ready_next = 1'b1; + arp_request_valid_next = 1'b0; + outgoing_ip_hdr_valid_next = 1'b1; outgoing_eth_dest_mac_next = arp_response_mac; state_next = STATE_WAIT_PACKET; end @@ -313,11 +313,10 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - arp_request_valid_reg <= 0; - drop_packet_reg <= 0; - input_ip_hdr_ready_reg <= 0; + arp_request_valid_reg <= 1'b0; + drop_packet_reg <= 1'b0; + input_ip_hdr_ready_reg <= 1'b0; outgoing_ip_hdr_valid_reg <= 1'b0; - outgoing_eth_dest_mac_reg <= 48'h000000000000; end else begin state_reg <= state_next; @@ -327,8 +326,9 @@ always @(posedge clk) begin input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; outgoing_ip_hdr_valid_reg <= outgoing_ip_hdr_valid_next; - outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; end + + outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; end endmodule diff --git a/rtl/ip_64.v b/rtl/ip_64.v index 3a0bf5156..d9d20277e 100644 --- a/rtl/ip_64.v +++ b/rtl/ip_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -247,11 +247,11 @@ ip_eth_tx_64_inst ( ); -reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; +reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; -reg arp_request_valid_reg = 0, arp_request_valid_next; +reg arp_request_valid_reg = 1'b0, arp_request_valid_next; -reg drop_packet_reg = 0, drop_packet_next; +reg drop_packet_reg = 1'b0, drop_packet_next; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; @@ -264,10 +264,10 @@ assign tx_error_arp_failed = arp_response_error; always @* begin state_next = STATE_IDLE; - arp_request_valid_next = 0; - drop_packet_next = 0; + arp_request_valid_next = 1'b0; + drop_packet_next = 1'b0; - input_ip_hdr_ready_next = 0; + input_ip_hdr_ready_next = 1'b0; outgoing_ip_hdr_valid_next = outgoing_ip_hdr_valid_reg & ~outgoing_ip_hdr_ready; outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; @@ -277,28 +277,28 @@ always @* begin // wait for outgoing packet if (input_ip_hdr_valid) begin // initiate ARP request - arp_request_valid_next = 1; + arp_request_valid_next = 1'b1; state_next = STATE_ARP_QUERY; end else begin state_next = STATE_IDLE; end end STATE_ARP_QUERY: begin - arp_request_valid_next = 1; + arp_request_valid_next = 1'b1; if (arp_response_valid) begin // wait for ARP reponse if (arp_response_error) begin // did not get MAC address; drop packet - input_ip_hdr_ready_next = 1; - arp_request_valid_next = 0; - drop_packet_next = 1; + input_ip_hdr_ready_next = 1'b1; + arp_request_valid_next = 1'b0; + drop_packet_next = 1'b1; state_next = STATE_WAIT_PACKET; end else begin // got MAC address; send packet - input_ip_hdr_ready_next = 1; - arp_request_valid_next = 0; - outgoing_ip_hdr_valid_next = 1; + input_ip_hdr_ready_next = 1'b1; + arp_request_valid_next = 1'b0; + outgoing_ip_hdr_valid_next = 1'b1; outgoing_eth_dest_mac_next = arp_response_mac; state_next = STATE_WAIT_PACKET; end @@ -322,11 +322,10 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - arp_request_valid_reg <= 0; - drop_packet_reg <= 0; - input_ip_hdr_ready_reg <= 0; + arp_request_valid_reg <= 1'b0; + drop_packet_reg <= 1'b0; + input_ip_hdr_ready_reg <= 1'b0; outgoing_ip_hdr_valid_reg <= 1'b0; - outgoing_eth_dest_mac_reg <= 48'h000000000000; end else begin state_reg <= state_next; @@ -336,8 +335,9 @@ always @(posedge clk) begin input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; outgoing_ip_hdr_valid_reg <= outgoing_ip_hdr_valid_next; - outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; end + + outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; end endmodule diff --git a/rtl/ip_complete.v b/rtl/ip_complete.v index ac9d440b5..17ffb3fab 100644 --- a/rtl/ip_complete.v +++ b/rtl/ip_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -197,15 +197,15 @@ wire input_select_ip = (input_eth_type == 16'h0800); wire input_select_arp = (input_eth_type == 16'h0806); wire input_select_none = ~(input_select_ip | input_select_arp); -reg input_select_ip_reg = 0; -reg input_select_arp_reg = 0; -reg input_select_none_reg = 0; +reg input_select_ip_reg = 1'b0; +reg input_select_arp_reg = 1'b0; +reg input_select_none_reg = 1'b0; always @(posedge clk) begin if (rst) begin - input_select_ip_reg <= 0; - input_select_arp_reg <= 0; - input_select_none_reg <= 0; + input_select_ip_reg <= 1'b0; + input_select_arp_reg <= 1'b0; + input_select_none_reg <= 1'b0; end else begin if (input_eth_payload_tvalid) begin if ((~input_select_ip_reg & ~input_select_arp_reg & ~input_select_none_reg) | @@ -215,9 +215,9 @@ always @(posedge clk) begin input_select_none_reg <= input_select_none; end end else begin - input_select_ip_reg <= 0; - input_select_arp_reg <= 0; - input_select_none_reg <= 0; + input_select_ip_reg <= 1'b0; + input_select_arp_reg <= 1'b0; + input_select_none_reg <= 1'b0; end end end diff --git a/rtl/ip_complete_64.v b/rtl/ip_complete_64.v index 4428d6c92..a458f5d05 100644 --- a/rtl/ip_complete_64.v +++ b/rtl/ip_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -205,15 +205,15 @@ wire input_select_ip = (input_eth_type == 16'h0800); wire input_select_arp = (input_eth_type == 16'h0806); wire input_select_none = ~(input_select_ip | input_select_arp); -reg input_select_ip_reg = 0; -reg input_select_arp_reg = 0; -reg input_select_none_reg = 0; +reg input_select_ip_reg = 1'b0; +reg input_select_arp_reg = 1'b0; +reg input_select_none_reg = 1'b0; always @(posedge clk) begin if (rst) begin - input_select_ip_reg <= 0; - input_select_arp_reg <= 0; - input_select_none_reg <= 0; + input_select_ip_reg <= 1'b0; + input_select_arp_reg <= 1'b0; + input_select_none_reg <= 1'b0; end else begin if (input_eth_payload_tvalid) begin if ((~input_select_ip_reg & ~input_select_arp_reg & ~input_select_none_reg) | @@ -223,9 +223,9 @@ always @(posedge clk) begin input_select_none_reg <= input_select_none; end end else begin - input_select_ip_reg <= 0; - input_select_arp_reg <= 0; - input_select_none_reg <= 0; + input_select_ip_reg <= 1'b0; + input_select_arp_reg <= 1'b0; + input_select_none_reg <= 1'b0; end end end diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py index d25b52508..ccd1d2c54 100755 --- a/rtl/ip_demux.py +++ b/rtl/ip_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -136,35 +136,35 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; +reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; {% for p in ports %} -reg output_{{p}}_ip_hdr_valid_reg = 0, output_{{p}}_ip_hdr_valid_next; +reg output_{{p}}_ip_hdr_valid_reg = 1'b0, output_{{p}}_ip_hdr_valid_next; {%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; // internal datapath reg [7:0] output_ip_payload_tdata_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -205,6 +205,12 @@ always @* begin current_output_tready = output_{{p}}_ip_payload_tready; end {%- endfor %} + default: begin + current_output_ip_hdr_valid = 1'b0; + current_output_ip_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -213,7 +219,7 @@ always @* begin frame_next = frame_reg; input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; {%- for p in ports %} output_{{p}}_ip_hdr_valid_next = output_{{p}}_ip_hdr_valid_reg & ~output_{{p}}_ip_hdr_ready; @@ -242,14 +248,14 @@ always @* begin end end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_ip_hdr_ready_next = 1; + input_ip_hdr_ready_next = 1'b1; case (select) {%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_ip_hdr_valid_next = 1; + {{w}}'d{{p}}: output_{{p}}_ip_hdr_valid_next = 1'b1; {%- endfor %} endcase output_eth_dest_mac_next = input_eth_dest_mac; @@ -280,29 +286,13 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; + input_ip_hdr_ready_reg <= 1'b0; + input_ip_payload_tready_reg <= 1'b0; {%- for p in ports %} - output_{{p}}_ip_hdr_valid_reg <= 0; + output_{{p}}_ip_hdr_valid_reg <= 1'b0; {%- endfor %} - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -311,97 +301,116 @@ always @(posedge clk) begin {%- for p in ports %} output_{{p}}_ip_hdr_valid_reg <= output_{{p}}_ip_hdr_valid_next; {%- endfor %} - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; end // output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 0; +reg [7:0] output_ip_payload_tdata_reg = 8'd0; {%- for p in ports %} -reg output_{{p}}_ip_payload_tvalid_reg = 0; +reg output_{{p}}_ip_payload_tvalid_reg = 1'b0, output_{{p}}_ip_payload_tvalid_next; {%- endfor %} -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [7:0] temp_ip_payload_tdata_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [7:0] temp_ip_payload_tdata_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; + +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; {% for p in ports %} assign output_{{p}}_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_{{p}}_ip_payload_tvalid = output_{{p}}_ip_payload_tvalid_reg; assign output_{{p}}_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_{{p}}_ip_payload_tuser = output_ip_payload_tuser_reg; {% endfor %} -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & (~current_output_tvalid | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source +{%- for p in ports %} + output_{{p}}_ip_payload_tvalid_next = output_{{p}}_ip_payload_tvalid_reg; +{%- endfor %} + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output +{%- for p in ports %} + output_{{p}}_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready +{%- for p in ports %} + output_{{p}}_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; {%- for p in ports %} - output_{{p}}_ip_payload_tvalid_reg <= 0; + output_{{p}}_ip_payload_tvalid_reg <= 1'b0; {%- endfor %} - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; +{%- for p in ports %} + output_{{p}}_ip_payload_tvalid_reg <= output_{{p}}_ip_payload_tvalid_next; +{%- endfor %} + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; -{%- endfor %} - endcase - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; -{%- endfor %} - endcase - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_demux_4.v b/rtl/ip_demux_4.v index 2eb72c861..8bb3e99ed 100644 --- a/rtl/ip_demux_4.v +++ b/rtl/ip_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -167,37 +167,37 @@ module ip_demux_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; +reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; -reg output_0_ip_hdr_valid_reg = 0, output_0_ip_hdr_valid_next; -reg output_1_ip_hdr_valid_reg = 0, output_1_ip_hdr_valid_next; -reg output_2_ip_hdr_valid_reg = 0, output_2_ip_hdr_valid_next; -reg output_3_ip_hdr_valid_reg = 0, output_3_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg output_0_ip_hdr_valid_reg = 1'b0, output_0_ip_hdr_valid_next; +reg output_1_ip_hdr_valid_reg = 1'b0, output_1_ip_hdr_valid_next; +reg output_2_ip_hdr_valid_reg = 1'b0, output_2_ip_hdr_valid_next; +reg output_3_ip_hdr_valid_reg = 1'b0, output_3_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; // internal datapath reg [7:0] output_ip_payload_tdata_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -308,6 +308,12 @@ always @* begin current_output_tvalid = output_3_ip_payload_tvalid; current_output_tready = output_3_ip_payload_tready; end + default: begin + current_output_ip_hdr_valid = 1'b0; + current_output_ip_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -316,7 +322,7 @@ always @* begin frame_next = frame_reg; input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; output_0_ip_hdr_valid_next = output_0_ip_hdr_valid_reg & ~output_0_ip_hdr_ready; output_1_ip_hdr_valid_next = output_1_ip_hdr_valid_reg & ~output_1_ip_hdr_ready; output_2_ip_hdr_valid_next = output_2_ip_hdr_valid_reg & ~output_2_ip_hdr_ready; @@ -345,16 +351,16 @@ always @* begin end end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_ip_hdr_ready_next = 1; + input_ip_hdr_ready_next = 1'b1; case (select) - 2'd0: output_0_ip_hdr_valid_next = 1; - 2'd1: output_1_ip_hdr_valid_next = 1; - 2'd2: output_2_ip_hdr_valid_next = 1; - 2'd3: output_3_ip_hdr_valid_next = 1; + 2'd0: output_0_ip_hdr_valid_next = 1'b1; + 2'd1: output_1_ip_hdr_valid_next = 1'b1; + 2'd2: output_2_ip_hdr_valid_next = 1'b1; + 2'd3: output_3_ip_hdr_valid_next = 1'b1; endcase output_eth_dest_mac_next = input_eth_dest_mac; output_eth_src_mac_next = input_eth_src_mac; @@ -384,30 +390,14 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_0_ip_hdr_valid_reg <= 0; - output_1_ip_hdr_valid_reg <= 0; - output_2_ip_hdr_valid_reg <= 0; - output_3_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_ip_hdr_ready_reg <= 1'b0; + input_ip_payload_tready_reg <= 1'b0; + output_0_ip_hdr_valid_reg <= 1'b0; + output_1_ip_hdr_valid_reg <= 1'b0; + output_2_ip_hdr_valid_reg <= 1'b0; + output_3_ip_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -417,38 +407,44 @@ always @(posedge clk) begin output_1_ip_hdr_valid_reg <= output_1_ip_hdr_valid_next; output_2_ip_hdr_valid_reg <= output_2_ip_hdr_valid_next; output_3_ip_hdr_valid_reg <= output_3_ip_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; end // output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 0; -reg output_0_ip_payload_tvalid_reg = 0; -reg output_1_ip_payload_tvalid_reg = 0; -reg output_2_ip_payload_tvalid_reg = 0; -reg output_3_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [7:0] output_ip_payload_tdata_reg = 8'd0; +reg output_0_ip_payload_tvalid_reg = 1'b0, output_0_ip_payload_tvalid_next; +reg output_1_ip_payload_tvalid_reg = 1'b0, output_1_ip_payload_tvalid_next; +reg output_2_ip_payload_tvalid_reg = 1'b0, output_2_ip_payload_tvalid_next; +reg output_3_ip_payload_tvalid_reg = 1'b0, output_3_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [7:0] temp_ip_payload_tdata_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [7:0] temp_ip_payload_tdata_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; + +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_0_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_0_ip_payload_tvalid = output_0_ip_payload_tvalid_reg; @@ -470,63 +466,78 @@ assign output_3_ip_payload_tvalid = output_3_ip_payload_tvalid_reg; assign output_3_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_3_ip_payload_tuser = output_ip_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & (~current_output_tvalid | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_0_ip_payload_tvalid_next = output_0_ip_payload_tvalid_reg; + output_1_ip_payload_tvalid_next = output_1_ip_payload_tvalid_reg; + output_2_ip_payload_tvalid_next = output_2_ip_payload_tvalid_reg; + output_3_ip_payload_tvalid_next = output_3_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_0_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd0); + output_1_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd1); + output_2_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd2); + output_3_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd3); + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_0_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd0); + output_1_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd1); + output_2_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd2); + output_3_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd3); + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_0_ip_payload_tvalid_reg <= 0; - output_1_ip_payload_tvalid_reg <= 0; - output_2_ip_payload_tvalid_reg <= 0; - output_3_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_0_ip_payload_tvalid_reg <= 1'b0; + output_1_ip_payload_tvalid_reg <= 1'b0; + output_2_ip_payload_tvalid_reg <= 1'b0; + output_3_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_0_ip_payload_tvalid_reg <= output_0_ip_payload_tvalid_next; + output_1_ip_payload_tvalid_reg <= output_1_ip_payload_tvalid_next; + output_2_ip_payload_tvalid_reg <= output_2_ip_payload_tvalid_next; + output_3_ip_payload_tvalid_reg <= output_3_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - case (select_reg) - 2'd0: output_0_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - 2'd1: output_1_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - 2'd2: output_2_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - 2'd3: output_3_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - endcase - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - case (select_reg) - 2'd0: output_0_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - 2'd1: output_1_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - 2'd2: output_2_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - 2'd3: output_3_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - endcase - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py index 725694a85..305629777 100755 --- a/rtl/ip_demux_64.py +++ b/rtl/ip_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -138,36 +138,36 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; +reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; {% for p in ports %} -reg output_{{p}}_ip_hdr_valid_reg = 0, output_{{p}}_ip_hdr_valid_next; +reg output_{{p}}_ip_hdr_valid_reg = 1'b0, output_{{p}}_ip_hdr_valid_next; {%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; // internal datapath reg [63:0] output_ip_payload_tdata_int; reg [7:0] output_ip_payload_tkeep_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -208,6 +208,12 @@ always @* begin current_output_tready = output_{{p}}_ip_payload_tready; end {%- endfor %} + default: begin + current_output_ip_hdr_valid = 1'b0; + current_output_ip_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -216,7 +222,7 @@ always @* begin frame_next = frame_reg; input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; {%- for p in ports %} output_{{p}}_ip_hdr_valid_next = output_{{p}}_ip_hdr_valid_reg & ~output_{{p}}_ip_hdr_ready; @@ -245,14 +251,14 @@ always @* begin end end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_ip_hdr_ready_next = 1; + input_ip_hdr_ready_next = 1'b1; case (select) {%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_ip_hdr_valid_next = 1; + {{w}}'d{{p}}: output_{{p}}_ip_hdr_valid_next = 1'b1; {%- endfor %} endcase output_eth_dest_mac_next = input_eth_dest_mac; @@ -284,29 +290,13 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; + input_ip_hdr_ready_reg <= 1'b0; + input_ip_payload_tready_reg <= 1'b0; {%- for p in ports %} - output_{{p}}_ip_hdr_valid_reg <= 0; + output_{{p}}_ip_hdr_valid_reg <= 1'b0; {%- endfor %} - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -315,39 +305,45 @@ always @(posedge clk) begin {%- for p in ports %} output_{{p}}_ip_hdr_valid_reg <= output_{{p}}_ip_hdr_valid_next; {%- endfor %} - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; end // output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 0; -reg [7:0] output_ip_payload_tkeep_reg = 0; +reg [63:0] output_ip_payload_tdata_reg = 64'd0; +reg [7:0] output_ip_payload_tkeep_reg = 8'd0; {%- for p in ports %} -reg output_{{p}}_ip_payload_tvalid_reg = 0; +reg output_{{p}}_ip_payload_tvalid_reg = 1'b0, output_{{p}}_ip_payload_tvalid_next; {%- endfor %} -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [63:0] temp_ip_payload_tdata_reg = 0; -reg [7:0] temp_ip_payload_tkeep_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [63:0] temp_ip_payload_tdata_reg = 64'd0; +reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; + +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; {% for p in ports %} assign output_{{p}}_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_{{p}}_ip_payload_tkeep = output_ip_payload_tkeep_reg; @@ -355,66 +351,76 @@ assign output_{{p}}_ip_payload_tvalid = output_{{p}}_ip_payload_tvalid_reg; assign output_{{p}}_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_{{p}}_ip_payload_tuser = output_ip_payload_tuser_reg; {% endfor %} -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & (~current_output_tvalid | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source +{%- for p in ports %} + output_{{p}}_ip_payload_tvalid_next = output_{{p}}_ip_payload_tvalid_reg; +{%- endfor %} + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output +{%- for p in ports %} + output_{{p}}_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready +{%- for p in ports %} + output_{{p}}_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tkeep_reg <= 0; {%- for p in ports %} - output_{{p}}_ip_payload_tvalid_reg <= 0; + output_{{p}}_ip_payload_tvalid_reg <= 1'b0; {%- endfor %} - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; +{%- for p in ports %} + output_{{p}}_ip_payload_tvalid_reg <= output_{{p}}_ip_payload_tvalid_next; +{%- endfor %} + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; -{%- endfor %} - endcase - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; -{%- endfor %} - endcase - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_demux_64_4.v b/rtl/ip_demux_64_4.v index 2a06d0dde..858190cdb 100644 --- a/rtl/ip_demux_64_4.v +++ b/rtl/ip_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -172,38 +172,38 @@ module ip_demux_64_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; +reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; -reg output_0_ip_hdr_valid_reg = 0, output_0_ip_hdr_valid_next; -reg output_1_ip_hdr_valid_reg = 0, output_1_ip_hdr_valid_next; -reg output_2_ip_hdr_valid_reg = 0, output_2_ip_hdr_valid_next; -reg output_3_ip_hdr_valid_reg = 0, output_3_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg output_0_ip_hdr_valid_reg = 1'b0, output_0_ip_hdr_valid_next; +reg output_1_ip_hdr_valid_reg = 1'b0, output_1_ip_hdr_valid_next; +reg output_2_ip_hdr_valid_reg = 1'b0, output_2_ip_hdr_valid_next; +reg output_3_ip_hdr_valid_reg = 1'b0, output_3_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; // internal datapath reg [63:0] output_ip_payload_tdata_int; reg [7:0] output_ip_payload_tkeep_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -314,6 +314,12 @@ always @* begin current_output_tvalid = output_3_ip_payload_tvalid; current_output_tready = output_3_ip_payload_tready; end + default: begin + current_output_ip_hdr_valid = 1'b0; + current_output_ip_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -322,7 +328,7 @@ always @* begin frame_next = frame_reg; input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; output_0_ip_hdr_valid_next = output_0_ip_hdr_valid_reg & ~output_0_ip_hdr_ready; output_1_ip_hdr_valid_next = output_1_ip_hdr_valid_reg & ~output_1_ip_hdr_ready; output_2_ip_hdr_valid_next = output_2_ip_hdr_valid_reg & ~output_2_ip_hdr_ready; @@ -351,16 +357,16 @@ always @* begin end end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_ip_hdr_ready_next = 1; + input_ip_hdr_ready_next = 1'b1; case (select) - 2'd0: output_0_ip_hdr_valid_next = 1; - 2'd1: output_1_ip_hdr_valid_next = 1; - 2'd2: output_2_ip_hdr_valid_next = 1; - 2'd3: output_3_ip_hdr_valid_next = 1; + 2'd0: output_0_ip_hdr_valid_next = 1'b1; + 2'd1: output_1_ip_hdr_valid_next = 1'b1; + 2'd2: output_2_ip_hdr_valid_next = 1'b1; + 2'd3: output_3_ip_hdr_valid_next = 1'b1; endcase output_eth_dest_mac_next = input_eth_dest_mac; output_eth_src_mac_next = input_eth_src_mac; @@ -391,30 +397,14 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_0_ip_hdr_valid_reg <= 0; - output_1_ip_hdr_valid_reg <= 0; - output_2_ip_hdr_valid_reg <= 0; - output_3_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_ip_hdr_ready_reg <= 1'b0; + input_ip_payload_tready_reg <= 1'b0; + output_0_ip_hdr_valid_reg <= 1'b0; + output_1_ip_hdr_valid_reg <= 1'b0; + output_2_ip_hdr_valid_reg <= 1'b0; + output_3_ip_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -424,40 +414,46 @@ always @(posedge clk) begin output_1_ip_hdr_valid_reg <= output_1_ip_hdr_valid_next; output_2_ip_hdr_valid_reg <= output_2_ip_hdr_valid_next; output_3_ip_hdr_valid_reg <= output_3_ip_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; end // output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 0; -reg [7:0] output_ip_payload_tkeep_reg = 0; -reg output_0_ip_payload_tvalid_reg = 0; -reg output_1_ip_payload_tvalid_reg = 0; -reg output_2_ip_payload_tvalid_reg = 0; -reg output_3_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [63:0] output_ip_payload_tdata_reg = 64'd0; +reg [7:0] output_ip_payload_tkeep_reg = 8'd0; +reg output_0_ip_payload_tvalid_reg = 1'b0, output_0_ip_payload_tvalid_next; +reg output_1_ip_payload_tvalid_reg = 1'b0, output_1_ip_payload_tvalid_next; +reg output_2_ip_payload_tvalid_reg = 1'b0, output_2_ip_payload_tvalid_next; +reg output_3_ip_payload_tvalid_reg = 1'b0, output_3_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [63:0] temp_ip_payload_tdata_reg = 0; -reg [7:0] temp_ip_payload_tkeep_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [63:0] temp_ip_payload_tdata_reg = 64'd0; +reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; + +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_0_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_0_ip_payload_tkeep = output_ip_payload_tkeep_reg; @@ -483,69 +479,81 @@ assign output_3_ip_payload_tvalid = output_3_ip_payload_tvalid_reg; assign output_3_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_3_ip_payload_tuser = output_ip_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & ~current_output_tvalid) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & (~current_output_tvalid | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_0_ip_payload_tvalid_next = output_0_ip_payload_tvalid_reg; + output_1_ip_payload_tvalid_next = output_1_ip_payload_tvalid_reg; + output_2_ip_payload_tvalid_next = output_2_ip_payload_tvalid_reg; + output_3_ip_payload_tvalid_next = output_3_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_0_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd0); + output_1_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd1); + output_2_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd2); + output_3_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd3); + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_0_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd0); + output_1_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd1); + output_2_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd2); + output_3_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd3); + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tkeep_reg <= 0; - output_0_ip_payload_tvalid_reg <= 0; - output_1_ip_payload_tvalid_reg <= 0; - output_2_ip_payload_tvalid_reg <= 0; - output_3_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_0_ip_payload_tvalid_reg <= 1'b0; + output_1_ip_payload_tvalid_reg <= 1'b0; + output_2_ip_payload_tvalid_reg <= 1'b0; + output_3_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_0_ip_payload_tvalid_reg <= output_0_ip_payload_tvalid_next; + output_1_ip_payload_tvalid_reg <= output_1_ip_payload_tvalid_next; + output_2_ip_payload_tvalid_reg <= output_2_ip_payload_tvalid_next; + output_3_ip_payload_tvalid_reg <= output_3_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - case (select_reg) - 2'd0: output_0_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - 2'd1: output_1_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - 2'd2: output_2_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - 2'd3: output_3_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - endcase - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - case (select_reg) - 2'd0: output_0_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - 2'd1: output_1_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - 2'd2: output_2_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - 2'd3: output_3_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - endcase - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index d25231266..4e23bec02 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -149,43 +149,43 @@ reg store_ip_dest_ip_2; reg store_ip_dest_ip_3; reg store_last_word; -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg [15:0] hdr_sum_reg = 0, hdr_sum_next; +reg [15:0] hdr_sum_reg = 16'd0, hdr_sum_next; -reg [7:0] last_word_data_reg = 0; +reg [7:0] last_word_data_reg = 8'd0; -reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; -reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; -reg [3:0] output_ip_version_reg = 0; -reg [3:0] output_ip_ihl_reg = 0; -reg [5:0] output_ip_dscp_reg = 0; -reg [1:0] output_ip_ecn_reg = 0; -reg [15:0] output_ip_length_reg = 0; -reg [15:0] output_ip_identification_reg = 0; -reg [2:0] output_ip_flags_reg = 0; -reg [12:0] output_ip_fragment_offset_reg = 0; -reg [7:0] output_ip_ttl_reg = 0; -reg [7:0] output_ip_protocol_reg = 0; -reg [15:0] output_ip_header_checksum_reg = 0; -reg [31:0] output_ip_source_ip_reg = 0; -reg [31:0] output_ip_dest_ip_reg = 0; +reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; +reg [3:0] output_ip_version_reg = 4'd0; +reg [3:0] output_ip_ihl_reg = 4'd0; +reg [5:0] output_ip_dscp_reg = 6'd0; +reg [1:0] output_ip_ecn_reg = 2'd0; +reg [15:0] output_ip_length_reg = 16'd0; +reg [15:0] output_ip_identification_reg = 16'd0; +reg [2:0] output_ip_flags_reg = 3'd0; +reg [12:0] output_ip_fragment_offset_reg = 13'd0; +reg [7:0] output_ip_ttl_reg = 8'd0; +reg [7:0] output_ip_protocol_reg = 8'd0; +reg [15:0] output_ip_header_checksum_reg = 16'd0; +reg [31:0] output_ip_source_ip_reg = 32'd0; +reg [31:0] output_ip_dest_ip_reg = 32'd0; -reg busy_reg = 0; -reg error_header_early_termination_reg = 0, error_header_early_termination_next; -reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; -reg error_invalid_header_reg = 0, error_invalid_header_next; -reg error_invalid_checksum_reg = 0, error_invalid_checksum_next; +reg busy_reg = 1'b0; +reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; +reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; +reg error_invalid_header_reg = 1'b0, error_invalid_header_next; +reg error_invalid_checksum_reg = 1'b0, error_invalid_checksum_next; // internal datapath reg [7:0] output_ip_payload_tdata_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -229,32 +229,32 @@ endfunction always @* begin state_next = STATE_IDLE; - input_eth_hdr_ready_next = 0; - input_eth_payload_tready_next = 0; + input_eth_hdr_ready_next = 1'b0; + input_eth_payload_tready_next = 1'b0; - store_eth_hdr = 0; - store_ip_version_ihl = 0; - store_ip_dscp_ecn = 0; - store_ip_length_0 = 0; - store_ip_length_1 = 0; - store_ip_identification_0 = 0; - store_ip_identification_1 = 0; - store_ip_flags_fragment_offset_0 = 0; - store_ip_flags_fragment_offset_1 = 0; - store_ip_ttl = 0; - store_ip_protocol = 0; - store_ip_header_checksum_0 = 0; - store_ip_header_checksum_1 = 0; - store_ip_source_ip_0 = 0; - store_ip_source_ip_1 = 0; - store_ip_source_ip_2 = 0; - store_ip_source_ip_3 = 0; - store_ip_dest_ip_0 = 0; - store_ip_dest_ip_1 = 0; - store_ip_dest_ip_2 = 0; - store_ip_dest_ip_3 = 0; + store_eth_hdr = 1'b0; + store_ip_version_ihl = 1'b0; + store_ip_dscp_ecn = 1'b0; + store_ip_length_0 = 1'b0; + store_ip_length_1 = 1'b0; + store_ip_identification_0 = 1'b0; + store_ip_identification_1 = 1'b0; + store_ip_flags_fragment_offset_0 = 1'b0; + store_ip_flags_fragment_offset_1 = 1'b0; + store_ip_ttl = 1'b0; + store_ip_protocol = 1'b0; + store_ip_header_checksum_0 = 1'b0; + store_ip_header_checksum_1 = 1'b0; + store_ip_source_ip_0 = 1'b0; + store_ip_source_ip_1 = 1'b0; + store_ip_source_ip_2 = 1'b0; + store_ip_source_ip_3 = 1'b0; + store_ip_dest_ip_0 = 1'b0; + store_ip_dest_ip_1 = 1'b0; + store_ip_dest_ip_2 = 1'b0; + store_ip_dest_ip_3 = 1'b0; - store_last_word = 0; + store_last_word = 1'b0; frame_ptr_next = frame_ptr_reg; @@ -262,27 +262,27 @@ always @* begin output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; - error_header_early_termination_next = 0; - error_payload_early_termination_next = 0; - error_invalid_header_next = 0; - error_invalid_checksum_next = 0; + error_header_early_termination_next = 1'b0; + error_payload_early_termination_next = 1'b0; + error_invalid_header_next = 1'b0; + error_invalid_checksum_next = 1'b0; - output_ip_payload_tdata_int = 0; - output_ip_payload_tvalid_int = 0; - output_ip_payload_tlast_int = 0; - output_ip_payload_tuser_int = 0; + output_ip_payload_tdata_int = 8'd0; + output_ip_payload_tvalid_int = 1'b0; + output_ip_payload_tlast_int = 1'b0; + output_ip_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for header - frame_ptr_next = 0; - hdr_sum_next = 0; + frame_ptr_next = 16'd0; + hdr_sum_next = 16'd0; input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; if (input_eth_hdr_ready & input_eth_hdr_valid) begin - input_eth_hdr_ready_next = 0; - input_eth_payload_tready_next = 1; - store_eth_hdr = 1; + input_eth_hdr_ready_next = 1'b0; + input_eth_payload_tready_next = 1'b1; + store_eth_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin state_next = STATE_IDLE; @@ -290,11 +290,11 @@ always @* begin end STATE_READ_HEADER: begin // read header - input_eth_payload_tready_next = 1; + input_eth_payload_tready_next = 1'b1; if (input_eth_payload_tready & input_eth_payload_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg+1; + frame_ptr_next = frame_ptr_reg + 16'd1; state_next = STATE_READ_HEADER; if (frame_ptr_reg[0]) begin @@ -304,35 +304,35 @@ always @* begin end case (frame_ptr_reg) - 8'h00: store_ip_version_ihl = 1; - 8'h01: store_ip_dscp_ecn = 1; - 8'h02: store_ip_length_1 = 1; - 8'h03: store_ip_length_0 = 1; - 8'h04: store_ip_identification_1 = 1; - 8'h05: store_ip_identification_0 = 1; - 8'h06: store_ip_flags_fragment_offset_1 = 1; - 8'h07: store_ip_flags_fragment_offset_0 = 1; - 8'h08: store_ip_ttl = 1; - 8'h09: store_ip_protocol = 1; - 8'h0A: store_ip_header_checksum_1 = 1; - 8'h0B: store_ip_header_checksum_0 = 1; - 8'h0C: store_ip_source_ip_3 = 1; - 8'h0D: store_ip_source_ip_2 = 1; - 8'h0E: store_ip_source_ip_1 = 1; - 8'h0F: store_ip_source_ip_0 = 1; - 8'h10: store_ip_dest_ip_3 = 1; - 8'h11: store_ip_dest_ip_2 = 1; - 8'h12: store_ip_dest_ip_1 = 1; + 8'h00: store_ip_version_ihl = 1'b1; + 8'h01: store_ip_dscp_ecn = 1'b1; + 8'h02: store_ip_length_1 = 1'b1; + 8'h03: store_ip_length_0 = 1'b1; + 8'h04: store_ip_identification_1 = 1'b1; + 8'h05: store_ip_identification_0 = 1'b1; + 8'h06: store_ip_flags_fragment_offset_1 = 1'b1; + 8'h07: store_ip_flags_fragment_offset_0 = 1'b1; + 8'h08: store_ip_ttl = 1'b1; + 8'h09: store_ip_protocol = 1'b1; + 8'h0A: store_ip_header_checksum_1 = 1'b1; + 8'h0B: store_ip_header_checksum_0 = 1'b1; + 8'h0C: store_ip_source_ip_3 = 1'b1; + 8'h0D: store_ip_source_ip_2 = 1'b1; + 8'h0E: store_ip_source_ip_1 = 1'b1; + 8'h0F: store_ip_source_ip_0 = 1'b1; + 8'h10: store_ip_dest_ip_3 = 1'b1; + 8'h11: store_ip_dest_ip_2 = 1'b1; + 8'h12: store_ip_dest_ip_1 = 1'b1; 8'h13: begin - store_ip_dest_ip_0 = 1; - if (output_ip_version_reg != 4 || output_ip_ihl_reg != 5) begin - error_invalid_header_next = 1; + store_ip_dest_ip_0 = 1'b1; + if (output_ip_version_reg != 4'd4 || output_ip_ihl_reg != 4'd5) begin + error_invalid_header_next = 1'b1; state_next = STATE_WAIT_LAST; end else if (hdr_sum_next != 16'hffff) begin - error_invalid_checksum_next = 1; + error_invalid_checksum_next = 1'b1; state_next = STATE_WAIT_LAST; end else begin - output_ip_hdr_valid_next = 1; + output_ip_hdr_valid_next = 1'b1; input_eth_payload_tready_next = output_ip_payload_tready_int_early; state_next = STATE_READ_PAYLOAD; end @@ -340,10 +340,10 @@ always @* begin endcase if (input_eth_payload_tlast) begin - error_header_early_termination_next = 1; - output_ip_hdr_valid_next = 0; + error_header_early_termination_next = 1'b1; + output_ip_hdr_valid_next = 1'b0; input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -362,20 +362,20 @@ always @* begin if (input_eth_payload_tready & input_eth_payload_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+1; + frame_ptr_next = frame_ptr_reg + 16'd1; if (input_eth_payload_tlast) begin if (frame_ptr_next != output_ip_length_reg) begin // end of frame, but length does not match - output_ip_payload_tuser_int = 1; - error_payload_early_termination_next = 1; + output_ip_payload_tuser_int = 1'b1; + error_payload_early_termination_next = 1'b1; end input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin if (frame_ptr_next == output_ip_length_reg) begin - store_last_word = 1; - output_ip_payload_tvalid_int = 0; + store_last_word = 1'b1; + output_ip_payload_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; end else begin state_next = STATE_READ_PAYLOAD; @@ -397,7 +397,7 @@ always @* begin if (input_eth_payload_tready & input_eth_payload_tvalid) begin if (input_eth_payload_tlast) begin input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD_LAST; @@ -408,12 +408,12 @@ always @* begin end STATE_WAIT_LAST: begin // read and discard until end of frame - input_eth_payload_tready_next = 1; + input_eth_payload_tready_next = 1'b1; if (input_eth_payload_tready & input_eth_payload_tvalid) begin if (input_eth_payload_tlast) begin input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -428,33 +428,16 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - hdr_sum_reg <= 0; - last_word_data_reg <= 0; - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - busy_reg <= 0; - error_header_early_termination_reg <= 0; - error_payload_early_termination_reg <= 0; - error_invalid_header_reg <= 0; - error_invalid_checksum_reg <= 0; + frame_ptr_reg <= 16'd0; + hdr_sum_reg <= 16'd0; + input_eth_hdr_ready_reg <= 1'b0; + input_eth_payload_tready_reg <= 1'b0; + output_ip_hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; + error_header_early_termination_reg <= 1'b0; + error_payload_early_termination_reg <= 1'b0; + error_invalid_header_reg <= 1'b0; + error_invalid_checksum_reg <= 1'b0; end else begin state_reg <= state_next; @@ -473,101 +456,119 @@ always @(posedge clk) begin error_invalid_checksum_reg <= error_invalid_checksum_next; busy_reg <= state_next != STATE_IDLE; - - // datapath - if (store_eth_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - end - - if (store_last_word) begin - last_word_data_reg <= output_ip_payload_tdata_int; - end - - if (store_ip_version_ihl) {output_ip_version_reg, output_ip_ihl_reg} <= input_eth_payload_tdata; - if (store_ip_dscp_ecn) {output_ip_dscp_reg, output_ip_ecn_reg} <= input_eth_payload_tdata; - if (store_ip_length_0) output_ip_length_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_ip_length_1) output_ip_length_reg[15: 8] <= input_eth_payload_tdata; - if (store_ip_identification_0) output_ip_identification_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_ip_identification_1) output_ip_identification_reg[15: 8] <= input_eth_payload_tdata; - if (store_ip_flags_fragment_offset_0) output_ip_fragment_offset_reg[ 7:0] <= input_eth_payload_tdata; - if (store_ip_flags_fragment_offset_1) {output_ip_flags_reg, output_ip_fragment_offset_reg[12:8]} <= input_eth_payload_tdata; - if (store_ip_ttl) output_ip_ttl_reg <= input_eth_payload_tdata; - if (store_ip_protocol) output_ip_protocol_reg <= input_eth_payload_tdata; - if (store_ip_header_checksum_0) output_ip_header_checksum_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_ip_header_checksum_1) output_ip_header_checksum_reg[15: 8] <= input_eth_payload_tdata; - if (store_ip_source_ip_0) output_ip_source_ip_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_ip_source_ip_1) output_ip_source_ip_reg[15: 8] <= input_eth_payload_tdata; - if (store_ip_source_ip_2) output_ip_source_ip_reg[23:16] <= input_eth_payload_tdata; - if (store_ip_source_ip_3) output_ip_source_ip_reg[31:24] <= input_eth_payload_tdata; - if (store_ip_dest_ip_0) output_ip_dest_ip_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_ip_dest_ip_1) output_ip_dest_ip_reg[15: 8] <= input_eth_payload_tdata; - if (store_ip_dest_ip_2) output_ip_dest_ip_reg[23:16] <= input_eth_payload_tdata; - if (store_ip_dest_ip_3) output_ip_dest_ip_reg[31:24] <= input_eth_payload_tdata; end + + // datapath + if (store_eth_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + end + + if (store_last_word) begin + last_word_data_reg <= output_ip_payload_tdata_int; + end + + if (store_ip_version_ihl) {output_ip_version_reg, output_ip_ihl_reg} <= input_eth_payload_tdata; + if (store_ip_dscp_ecn) {output_ip_dscp_reg, output_ip_ecn_reg} <= input_eth_payload_tdata; + if (store_ip_length_0) output_ip_length_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_ip_length_1) output_ip_length_reg[15: 8] <= input_eth_payload_tdata; + if (store_ip_identification_0) output_ip_identification_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_ip_identification_1) output_ip_identification_reg[15: 8] <= input_eth_payload_tdata; + if (store_ip_flags_fragment_offset_0) output_ip_fragment_offset_reg[ 7:0] <= input_eth_payload_tdata; + if (store_ip_flags_fragment_offset_1) {output_ip_flags_reg, output_ip_fragment_offset_reg[12:8]} <= input_eth_payload_tdata; + if (store_ip_ttl) output_ip_ttl_reg <= input_eth_payload_tdata; + if (store_ip_protocol) output_ip_protocol_reg <= input_eth_payload_tdata; + if (store_ip_header_checksum_0) output_ip_header_checksum_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_ip_header_checksum_1) output_ip_header_checksum_reg[15: 8] <= input_eth_payload_tdata; + if (store_ip_source_ip_0) output_ip_source_ip_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_ip_source_ip_1) output_ip_source_ip_reg[15: 8] <= input_eth_payload_tdata; + if (store_ip_source_ip_2) output_ip_source_ip_reg[23:16] <= input_eth_payload_tdata; + if (store_ip_source_ip_3) output_ip_source_ip_reg[31:24] <= input_eth_payload_tdata; + if (store_ip_dest_ip_0) output_ip_dest_ip_reg[ 7: 0] <= input_eth_payload_tdata; + if (store_ip_dest_ip_1) output_ip_dest_ip_reg[15: 8] <= input_eth_payload_tdata; + if (store_ip_dest_ip_2) output_ip_dest_ip_reg[23:16] <= input_eth_payload_tdata; + if (store_ip_dest_ip_3) output_ip_dest_ip_reg[31:24] <= input_eth_payload_tdata; end // output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [7:0] output_ip_payload_tdata_reg = 8'd0; +reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [7:0] temp_ip_payload_tdata_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [7:0] temp_ip_payload_tdata_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 99b494d2a..219c7569d 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -137,46 +137,46 @@ reg store_last_word; reg flush_save; reg transfer_in_save; -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; reg [31:0] hdr_sum_temp; -reg [31:0] hdr_sum_reg = 0, hdr_sum_next; -reg check_hdr_reg = 0, check_hdr_next; +reg [31:0] hdr_sum_reg = 32'd0, hdr_sum_next; +reg check_hdr_reg = 1'b0, check_hdr_next; -reg [63:0] last_word_data_reg = 0; -reg [7:0] last_word_keep_reg = 0; +reg [63:0] last_word_data_reg = 64'd0; +reg [7:0] last_word_keep_reg = 8'd0; -reg input_eth_hdr_ready_reg = 0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 0, input_eth_payload_tready_next; +reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; +reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; -reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; -reg [3:0] output_ip_version_reg = 0; -reg [3:0] output_ip_ihl_reg = 0; -reg [5:0] output_ip_dscp_reg = 0; -reg [1:0] output_ip_ecn_reg = 0; -reg [15:0] output_ip_length_reg = 0; -reg [15:0] output_ip_identification_reg = 0; -reg [2:0] output_ip_flags_reg = 0; -reg [12:0] output_ip_fragment_offset_reg = 0; -reg [7:0] output_ip_ttl_reg = 0; -reg [7:0] output_ip_protocol_reg = 0; -reg [15:0] output_ip_header_checksum_reg = 0; -reg [31:0] output_ip_source_ip_reg = 0; -reg [31:0] output_ip_dest_ip_reg = 0; +reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; +reg [3:0] output_ip_version_reg = 4'd0; +reg [3:0] output_ip_ihl_reg = 4'd0; +reg [5:0] output_ip_dscp_reg = 6'd0; +reg [1:0] output_ip_ecn_reg = 2'd0; +reg [15:0] output_ip_length_reg = 16'd0; +reg [15:0] output_ip_identification_reg = 16'd0; +reg [2:0] output_ip_flags_reg = 3'd0; +reg [12:0] output_ip_fragment_offset_reg = 13'd0; +reg [7:0] output_ip_ttl_reg = 8'd0; +reg [7:0] output_ip_protocol_reg = 8'd0; +reg [15:0] output_ip_header_checksum_reg = 16'd0; +reg [31:0] output_ip_source_ip_reg = 32'd0; +reg [31:0] output_ip_dest_ip_reg = 32'd0; -reg busy_reg = 0; -reg error_header_early_termination_reg = 0, error_header_early_termination_next; -reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; -reg error_invalid_header_reg = 0, error_invalid_header_next; -reg error_invalid_checksum_reg = 0, error_invalid_checksum_next; +reg busy_reg = 1'b0; +reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; +reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; +reg error_invalid_header_reg = 1'b0, error_invalid_header_next; +reg error_invalid_checksum_reg = 1'b0, error_invalid_checksum_next; -reg [63:0] save_eth_payload_tdata_reg = 0; -reg [7:0] save_eth_payload_tkeep_reg = 0; -reg save_eth_payload_tlast_reg = 0; -reg save_eth_payload_tuser_reg = 0; +reg [63:0] save_eth_payload_tdata_reg = 64'd0; +reg [7:0] save_eth_payload_tkeep_reg = 8'd0; +reg save_eth_payload_tlast_reg = 1'b0; +reg save_eth_payload_tuser_reg = 1'b0; reg [63:0] shift_eth_payload_tdata; reg [7:0] shift_eth_payload_tkeep; @@ -190,7 +190,7 @@ reg shift_eth_payload_extra_cycle; reg [63:0] output_ip_payload_tdata_int; reg [7:0] output_ip_payload_tkeep_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -225,15 +225,15 @@ assign error_invalid_checksum = error_invalid_checksum_reg; function [3:0] keep2count; input [7:0] k; case (k) - 8'b00000000: keep2count = 0; - 8'b00000001: keep2count = 1; - 8'b00000011: keep2count = 2; - 8'b00000111: keep2count = 3; - 8'b00001111: keep2count = 4; - 8'b00011111: keep2count = 5; - 8'b00111111: keep2count = 6; - 8'b01111111: keep2count = 7; - 8'b11111111: keep2count = 8; + 8'b00000000: keep2count = 4'd0; + 8'b00000001: keep2count = 4'd1; + 8'b00000011: keep2count = 4'd2; + 8'b00000111: keep2count = 4'd3; + 8'b00001111: keep2count = 4'd4; + 8'b00011111: keep2count = 4'd5; + 8'b00111111: keep2count = 4'd6; + 8'b01111111: keep2count = 4'd7; + 8'b11111111: keep2count = 4'd8; endcase endfunction @@ -258,9 +258,9 @@ always @* begin shift_eth_payload_extra_cycle = save_eth_payload_tlast_reg & (save_eth_payload_tkeep_reg[7:4] != 0); if (shift_eth_payload_extra_cycle) begin - shift_eth_payload_tdata[63:32] = 0; - shift_eth_payload_tkeep[7:4] = 0; - shift_eth_payload_tvalid = 1; + shift_eth_payload_tdata[63:32] = 32'd0; + shift_eth_payload_tkeep[7:4] = 4'd0; + shift_eth_payload_tvalid = 1'b1; shift_eth_payload_tlast = save_eth_payload_tlast_reg; shift_eth_payload_tuser = save_eth_payload_tuser_reg; shift_eth_payload_input_tready = flush_save; @@ -277,50 +277,50 @@ end always @* begin state_next = STATE_IDLE; - flush_save = 0; - transfer_in_save = 0; + flush_save = 1'b0; + transfer_in_save = 1'b0; - input_eth_hdr_ready_next = 0; - input_eth_payload_tready_next = 0; + input_eth_hdr_ready_next = 1'b0; + input_eth_payload_tready_next = 1'b0; - store_eth_hdr = 0; - store_hdr_word_0 = 0; - store_hdr_word_1 = 0; - store_hdr_word_2 = 0; + store_eth_hdr = 1'b0; + store_hdr_word_0 = 1'b0; + store_hdr_word_1 = 1'b0; + store_hdr_word_2 = 1'b0; - store_last_word = 0; + store_last_word = 1'b0; frame_ptr_next = frame_ptr_reg; - hdr_sum_temp = 0; + hdr_sum_temp = 32'd0; hdr_sum_next = hdr_sum_reg; check_hdr_next = check_hdr_reg; output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; - error_header_early_termination_next = 0; - error_payload_early_termination_next = 0; - error_invalid_header_next = 0; - error_invalid_checksum_next = 0; + error_header_early_termination_next = 1'b0; + error_payload_early_termination_next = 1'b0; + error_invalid_header_next = 1'b0; + error_invalid_checksum_next = 1'b0; - output_ip_payload_tdata_int = 0; - output_ip_payload_tkeep_int = 0; - output_ip_payload_tvalid_int = 0; - output_ip_payload_tlast_int = 0; - output_ip_payload_tuser_int = 0; + output_ip_payload_tdata_int = 64'd0; + output_ip_payload_tkeep_int = 8'd0; + output_ip_payload_tvalid_int = 1'b0; + output_ip_payload_tlast_int = 1'b0; + output_ip_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for header - frame_ptr_next = 0; - hdr_sum_next = 0; - flush_save = 1; + frame_ptr_next = 16'd0; + hdr_sum_next = 32'd0; + flush_save = 1'b1; input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; if (input_eth_hdr_ready & input_eth_hdr_valid) begin - input_eth_hdr_ready_next = 0; - input_eth_payload_tready_next = 1; - store_eth_hdr = 1; + input_eth_hdr_ready_next = 1'b0; + input_eth_payload_tready_next = 1'b1; + store_eth_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin state_next = STATE_IDLE; @@ -332,20 +332,20 @@ always @* begin if (input_eth_payload_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg+8; - transfer_in_save = 1; + frame_ptr_next = frame_ptr_reg + 16'd8; + transfer_in_save = 1'b1; state_next = STATE_READ_HEADER; case (frame_ptr_reg) 8'h00: begin - store_hdr_word_0 = 1; + store_hdr_word_0 = 1'b1; hdr_sum_next = input_eth_payload_tdata[15:0] + input_eth_payload_tdata[31:16] + input_eth_payload_tdata[47:32] + input_eth_payload_tdata[63:48]; end 8'h08: begin - store_hdr_word_1 = 1; + store_hdr_word_1 = 1'b1; hdr_sum_next = hdr_sum_reg + input_eth_payload_tdata[15:0] + input_eth_payload_tdata[31:16] + @@ -353,17 +353,17 @@ always @* begin input_eth_payload_tdata[63:48]; end 8'h10: begin - store_hdr_word_2 = 1; + store_hdr_word_2 = 1'b1; hdr_sum_next = hdr_sum_reg + input_eth_payload_tdata[15:0] + input_eth_payload_tdata[31:16]; - frame_ptr_next = frame_ptr_reg+4; + frame_ptr_next = frame_ptr_reg + 16'd4; // check header checksum on next cycle for improved timing - check_hdr_next = 1; + check_hdr_next = 1'b1; - if (output_ip_version_reg != 4 || output_ip_ihl_reg != 5) begin - error_invalid_header_next = 1; + if (output_ip_version_reg != 4'd4 || output_ip_ihl_reg != 4'd5) begin + error_invalid_header_next = 1'b1; input_eth_payload_tready_next = shift_eth_payload_input_tready; state_next = STATE_WAIT_LAST; end else begin @@ -374,12 +374,12 @@ always @* begin endcase if (shift_eth_payload_tlast) begin - error_header_early_termination_next = 1; - error_invalid_header_next = 0; - error_invalid_checksum_next = 0; - output_ip_hdr_valid_next = 0; + error_header_early_termination_next = 1'b1; + error_invalid_header_next = 1'b0; + error_invalid_checksum_next = 1'b0; + output_ip_hdr_valid_next = 1'b0; input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_eth_payload_tready_next = 0; + input_eth_payload_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -397,31 +397,31 @@ always @* begin output_ip_payload_tlast_int = shift_eth_payload_tlast; output_ip_payload_tuser_int = shift_eth_payload_tuser; - if (output_ip_payload_tready_int & shift_eth_payload_tvalid) begin + if (output_ip_payload_tready_int_reg & shift_eth_payload_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_tkeep); - transfer_in_save = 1; + transfer_in_save = 1'b1; if (frame_ptr_next >= output_ip_length_reg) begin // have entire payload frame_ptr_next = output_ip_length_reg; output_ip_payload_tkeep_int = shift_eth_payload_tkeep & count2keep(output_ip_length_reg - frame_ptr_reg); if (shift_eth_payload_tlast) begin - input_eth_payload_tready_next = 0; - flush_save = 1; + input_eth_payload_tready_next = 1'b0; + flush_save = 1'b1; input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg & ~check_hdr_reg; state_next = STATE_IDLE; end else begin - store_last_word = 1; - output_ip_payload_tvalid_int = 0; + store_last_word = 1'b1; + output_ip_payload_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; end end else begin if (shift_eth_payload_tlast) begin // end of frame, but length does not match - error_payload_early_termination_next = 1; - output_ip_payload_tuser_int = 1; - input_eth_payload_tready_next = 0; - flush_save = 1; + error_payload_early_termination_next = 1'b1; + output_ip_payload_tuser_int = 1'b1; + input_eth_payload_tready_next = 1'b0; + flush_save = 1'b1; input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg & ~check_hdr_reg; state_next = STATE_IDLE; end else begin @@ -433,15 +433,15 @@ always @* begin end if (check_hdr_reg) begin - check_hdr_next = 0; + check_hdr_next = 1'b0; hdr_sum_temp = hdr_sum_reg[15:0] + hdr_sum_reg[31:16]; hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[16]; if (hdr_sum_temp != 16'hffff) begin // bad checksum - error_invalid_checksum_next = 1; - output_ip_payload_tvalid_int = 0; + error_invalid_checksum_next = 1'b1; + output_ip_payload_tvalid_int = 1'b0; if (shift_eth_payload_tlast & shift_eth_payload_tvalid) begin // only one payload cycle; return to idle now input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg & ~check_hdr_reg; @@ -453,7 +453,7 @@ always @* begin end end else begin // good checksum; transfer header - output_ip_hdr_valid_next = 1; + output_ip_hdr_valid_next = 1'b1; end end end @@ -467,12 +467,12 @@ always @* begin output_ip_payload_tlast_int = shift_eth_payload_tlast; output_ip_payload_tuser_int = shift_eth_payload_tuser; - if (output_ip_payload_tready_int & shift_eth_payload_tvalid) begin - transfer_in_save = 1; + if (output_ip_payload_tready_int_reg & shift_eth_payload_tvalid) begin + transfer_in_save = 1'b1; if (shift_eth_payload_tlast) begin - input_eth_payload_tready_next = 0; - flush_save = 1; - input_eth_hdr_ready_next = 1; + input_eth_payload_tready_next = 1'b0; + flush_save = 1'b1; + input_eth_hdr_ready_next = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD_LAST; @@ -486,11 +486,11 @@ always @* begin input_eth_payload_tready_next = shift_eth_payload_input_tready; if (shift_eth_payload_tvalid) begin - transfer_in_save = 1; + transfer_in_save = 1'b1; if (shift_eth_payload_tlast) begin - input_eth_payload_tready_next = 0; - flush_save = 1; - input_eth_hdr_ready_next = 1; + input_eth_payload_tready_next = 1'b0; + flush_save = 1'b1; + input_eth_hdr_ready_next = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -505,39 +505,18 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - hdr_sum_reg <= 0; - check_hdr_reg <= 0; - last_word_data_reg <= 0; - last_word_keep_reg <= 0; - input_eth_hdr_ready_reg <= 0; - input_eth_payload_tready_reg <= 0; - output_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - save_eth_payload_tdata_reg <= 0; - save_eth_payload_tkeep_reg <= 0; - save_eth_payload_tlast_reg <= 0; - save_eth_payload_tuser_reg <= 0; - busy_reg <= 0; - error_header_early_termination_reg <= 0; - error_payload_early_termination_reg <= 0; - error_invalid_header_reg <= 0; - error_invalid_checksum_reg <= 0; + frame_ptr_reg <= 16'd0; + hdr_sum_reg <= 16'd0; + check_hdr_reg <= 1'b0; + input_eth_hdr_ready_reg <= 1'b0; + input_eth_payload_tready_reg <= 1'b0; + output_ip_hdr_valid_reg <= 1'b0; + save_eth_payload_tlast_reg <= 1'b0; + busy_reg <= 1'b0; + error_header_early_termination_reg <= 1'b0; + error_payload_early_termination_reg <= 1'b0; + error_invalid_header_reg <= 1'b0; + error_invalid_checksum_reg <= 1'b0; end else begin state_reg <= state_next; @@ -559,75 +538,78 @@ always @(posedge clk) begin busy_reg <= state_next != STATE_IDLE; // datapath - if (store_eth_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - end - - if (store_last_word) begin - last_word_data_reg <= output_ip_payload_tdata_int; - last_word_keep_reg <= output_ip_payload_tkeep_int; - end - - if (store_hdr_word_0) begin - {output_ip_version_reg, output_ip_ihl_reg} <= input_eth_payload_tdata[ 7: 0]; - {output_ip_dscp_reg, output_ip_ecn_reg} <= input_eth_payload_tdata[15: 8]; - output_ip_length_reg[15: 8] <= input_eth_payload_tdata[23:16]; - output_ip_length_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; - output_ip_identification_reg[15: 8] <= input_eth_payload_tdata[39:32]; - output_ip_identification_reg[ 7: 0] <= input_eth_payload_tdata[47:40]; - {output_ip_flags_reg, output_ip_fragment_offset_reg[12:8]} <= input_eth_payload_tdata[55:48]; - output_ip_fragment_offset_reg[ 7:0] <= input_eth_payload_tdata[63:56]; - end - - if (store_hdr_word_1) begin - output_ip_ttl_reg <= input_eth_payload_tdata[ 7: 0]; - output_ip_protocol_reg <= input_eth_payload_tdata[15: 8]; - output_ip_header_checksum_reg[15: 8] <= input_eth_payload_tdata[23:16]; - output_ip_header_checksum_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; - output_ip_source_ip_reg[31:24] <= input_eth_payload_tdata[39:32]; - output_ip_source_ip_reg[23:16] <= input_eth_payload_tdata[47:40]; - output_ip_source_ip_reg[15: 8] <= input_eth_payload_tdata[55:48]; - output_ip_source_ip_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; - end - - if (store_hdr_word_2) begin - output_ip_dest_ip_reg[31:24] <= input_eth_payload_tdata[ 7: 0]; - output_ip_dest_ip_reg[23:16] <= input_eth_payload_tdata[15: 8]; - output_ip_dest_ip_reg[15: 8] <= input_eth_payload_tdata[23:16]; - output_ip_dest_ip_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; - end - if (flush_save) begin - save_eth_payload_tdata_reg <= 0; - save_eth_payload_tkeep_reg <= 0; - save_eth_payload_tlast_reg <= 0; - save_eth_payload_tuser_reg <= 0; + save_eth_payload_tlast_reg <= 1'b0; end else if (transfer_in_save) begin - save_eth_payload_tdata_reg <= input_eth_payload_tdata; - save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; save_eth_payload_tlast_reg <= input_eth_payload_tlast; - save_eth_payload_tuser_reg <= input_eth_payload_tuser; end end + + // datapath + if (store_eth_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + end + + if (store_last_word) begin + last_word_data_reg <= output_ip_payload_tdata_int; + last_word_keep_reg <= output_ip_payload_tkeep_int; + end + + if (store_hdr_word_0) begin + {output_ip_version_reg, output_ip_ihl_reg} <= input_eth_payload_tdata[ 7: 0]; + {output_ip_dscp_reg, output_ip_ecn_reg} <= input_eth_payload_tdata[15: 8]; + output_ip_length_reg[15: 8] <= input_eth_payload_tdata[23:16]; + output_ip_length_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + output_ip_identification_reg[15: 8] <= input_eth_payload_tdata[39:32]; + output_ip_identification_reg[ 7: 0] <= input_eth_payload_tdata[47:40]; + {output_ip_flags_reg, output_ip_fragment_offset_reg[12:8]} <= input_eth_payload_tdata[55:48]; + output_ip_fragment_offset_reg[ 7:0] <= input_eth_payload_tdata[63:56]; + end + + if (store_hdr_word_1) begin + output_ip_ttl_reg <= input_eth_payload_tdata[ 7: 0]; + output_ip_protocol_reg <= input_eth_payload_tdata[15: 8]; + output_ip_header_checksum_reg[15: 8] <= input_eth_payload_tdata[23:16]; + output_ip_header_checksum_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + output_ip_source_ip_reg[31:24] <= input_eth_payload_tdata[39:32]; + output_ip_source_ip_reg[23:16] <= input_eth_payload_tdata[47:40]; + output_ip_source_ip_reg[15: 8] <= input_eth_payload_tdata[55:48]; + output_ip_source_ip_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; + end + + if (store_hdr_word_2) begin + output_ip_dest_ip_reg[31:24] <= input_eth_payload_tdata[ 7: 0]; + output_ip_dest_ip_reg[23:16] <= input_eth_payload_tdata[15: 8]; + output_ip_dest_ip_reg[15: 8] <= input_eth_payload_tdata[23:16]; + output_ip_dest_ip_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + end + + if (transfer_in_save) begin + save_eth_payload_tdata_reg <= input_eth_payload_tdata; + save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; + save_eth_payload_tuser_reg <= input_eth_payload_tuser; + end end // output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 0; -reg [7:0] output_ip_payload_tkeep_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [63:0] output_ip_payload_tdata_reg = 64'd0; +reg [7:0] output_ip_payload_tkeep_reg = 8'd0; +reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [63:0] temp_ip_payload_tdata_reg = 0; -reg [7:0] temp_ip_payload_tkeep_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [63:0] temp_ip_payload_tdata_reg = 64'd0; +reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; @@ -635,53 +617,66 @@ assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tkeep_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 014e2bdee..b020b7c7b 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -123,41 +123,41 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_ip_hdr; reg store_last_word; -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg [15:0] hdr_sum_reg = 0, hdr_sum_next; +reg [15:0] hdr_sum_reg = 16'd0, hdr_sum_next; -reg [7:0] last_word_data_reg = 0; +reg [7:0] last_word_data_reg = 8'd0; -reg [5:0] ip_dscp_reg = 0; -reg [1:0] ip_ecn_reg = 0; -reg [15:0] ip_length_reg = 0; -reg [15:0] ip_identification_reg = 0; -reg [2:0] ip_flags_reg = 0; -reg [12:0] ip_fragment_offset_reg = 0; -reg [7:0] ip_ttl_reg = 0; -reg [7:0] ip_protocol_reg = 0; -reg [31:0] ip_source_ip_reg = 0; -reg [31:0] ip_dest_ip_reg = 0; +reg [5:0] ip_dscp_reg = 6'd0; +reg [1:0] ip_ecn_reg = 2'd0; +reg [15:0] ip_length_reg = 16'd0; +reg [15:0] ip_identification_reg = 16'd0; +reg [2:0] ip_flags_reg = 3'd0; +reg [12:0] ip_fragment_offset_reg = 13'd0; +reg [7:0] ip_ttl_reg = 8'd0; +reg [7:0] ip_protocol_reg = 8'd0; +reg [31:0] ip_source_ip_reg = 32'd0; +reg [31:0] ip_dest_ip_reg = 32'd0; -reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; +reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; -reg busy_reg = 0; -reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; +reg busy_reg = 1'b0; +reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; // internal datapath -reg [7:0] output_eth_payload_tdata_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; +reg [7:0] output_eth_payload_tdata_int; +reg output_eth_payload_tvalid_int; +reg output_eth_payload_tready_int_reg = 1'b0; +reg output_eth_payload_tlast_int; +reg output_eth_payload_tuser_int; +wire output_eth_payload_tready_int_early; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = input_ip_payload_tready_reg; @@ -182,12 +182,12 @@ endfunction always @* begin state_next = STATE_IDLE; - input_ip_hdr_ready_next = 0; - input_ip_payload_tready_next = 0; + input_ip_hdr_ready_next = 1'b0; + input_ip_payload_tready_next = 1'b0; - store_ip_hdr = 0; + store_ip_hdr = 1'b0; - store_last_word = 0; + store_last_word = 1'b0; frame_ptr_next = frame_ptr_reg; @@ -195,27 +195,27 @@ always @* begin output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - error_payload_early_termination_next = 0; + error_payload_early_termination_next = 1'b0; - output_eth_payload_tdata_int = 0; - output_eth_payload_tvalid_int = 0; - output_eth_payload_tlast_int = 0; - output_eth_payload_tuser_int = 0; + output_eth_payload_tdata_int = 8'd0; + output_eth_payload_tvalid_int = 1'b0; + output_eth_payload_tlast_int = 1'b0; + output_eth_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; + frame_ptr_next = 16'd0; input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; if (input_ip_hdr_ready & input_ip_hdr_valid) begin - store_ip_hdr = 1; - input_ip_hdr_ready_next = 0; - output_eth_hdr_valid_next = 1; - if (output_eth_payload_tready_int) begin - output_eth_payload_tvalid_int = 1; + store_ip_hdr = 1'b1; + input_ip_hdr_ready_next = 1'b0; + output_eth_hdr_valid_next = 1'b1; + if (output_eth_payload_tready_int_reg) begin + output_eth_payload_tvalid_int = 1'b1; output_eth_payload_tdata_int = {4'd4, 4'd5}; // ip_version, ip_ihl - frame_ptr_next = 1; + frame_ptr_next = 16'd1; end state_next = STATE_WRITE_HEADER; end else begin @@ -224,8 +224,8 @@ always @* begin end STATE_WRITE_HEADER: begin // write header - if (output_eth_payload_tready_int) begin - frame_ptr_next = frame_ptr_reg+1; + if (output_eth_payload_tready_int_reg) begin + frame_ptr_next = frame_ptr_reg + 16'd1; output_eth_payload_tvalid_int = 1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) @@ -298,20 +298,20 @@ always @* begin if (input_ip_payload_tready & input_ip_payload_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+1; + frame_ptr_next = frame_ptr_reg + 16'd1; if (input_ip_payload_tlast) begin if (frame_ptr_next != ip_length_reg) begin // end of frame, but length does not match - output_eth_payload_tuser_int = 1; - error_payload_early_termination_next = 1; + output_eth_payload_tuser_int = 1'b1; + error_payload_early_termination_next = 1'b1; end input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin if (frame_ptr_next == ip_length_reg) begin - store_last_word = 1; - output_eth_payload_tvalid_int = 0; + store_last_word = 1'b1; + output_eth_payload_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -333,7 +333,7 @@ always @* begin if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD_LAST; @@ -344,12 +344,12 @@ always @* begin end STATE_WAIT_LAST: begin // read and discard until end of frame - input_ip_payload_tready_next = 1; + input_ip_payload_tready_next = 1'b1; if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -364,27 +364,13 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - hdr_sum_reg <= 0; - last_word_data_reg <= 0; - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - ip_dscp_reg <= 0; - ip_ecn_reg <= 0; - ip_length_reg <= 0; - ip_identification_reg <= 0; - ip_flags_reg <= 0; - ip_fragment_offset_reg <= 0; - ip_ttl_reg <= 0; - ip_protocol_reg <= 0; - ip_source_ip_reg <= 0; - ip_dest_ip_reg <= 0; - output_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - busy_reg <= 0; - error_payload_early_termination_reg <= 0; + frame_ptr_reg <= 16'd0; + hdr_sum_reg <= 16'd0; + input_ip_hdr_ready_reg <= 1'b0; + input_ip_payload_tready_reg <= 1'b0; + output_eth_hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; + error_payload_early_termination_reg <= 1'b0; end else begin state_reg <= state_next; @@ -400,90 +386,108 @@ always @(posedge clk) begin busy_reg <= state_next != STATE_IDLE; error_payload_early_termination_reg <= error_payload_early_termination_next; + end - // datapath - if (store_ip_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - ip_dscp_reg <= input_ip_dscp; - ip_ecn_reg <= input_ip_ecn; - ip_length_reg <= input_ip_length; - ip_identification_reg <= input_ip_identification; - ip_flags_reg <= input_ip_flags; - ip_fragment_offset_reg <= input_ip_fragment_offset; - ip_ttl_reg <= input_ip_ttl; - ip_protocol_reg <= input_ip_protocol; - ip_source_ip_reg <= input_ip_source_ip; - ip_dest_ip_reg <= input_ip_dest_ip; - end + // datapath + if (store_ip_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + ip_dscp_reg <= input_ip_dscp; + ip_ecn_reg <= input_ip_ecn; + ip_length_reg <= input_ip_length; + ip_identification_reg <= input_ip_identification; + ip_flags_reg <= input_ip_flags; + ip_fragment_offset_reg <= input_ip_fragment_offset; + ip_ttl_reg <= input_ip_ttl; + ip_protocol_reg <= input_ip_protocol; + ip_source_ip_reg <= input_ip_source_ip; + ip_dest_ip_reg <= input_ip_dest_ip; + end - if (store_last_word) begin - last_word_data_reg <= output_eth_payload_tdata_int; - end + if (store_last_word) begin + last_word_data_reg <= output_eth_payload_tdata_int; end end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [7:0] output_eth_payload_tdata_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 0; -reg temp_axis_tvalid_reg = 0; -reg temp_axis_tlast_reg = 0; -reg temp_axis_tuser_reg = 0; +reg [7:0] temp_eth_payload_tdata_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; + +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_eth_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_axis_tdata_reg <= output_eth_payload_tdata_int; - temp_axis_tvalid_reg <= output_eth_payload_tvalid_int; - temp_axis_tlast_reg <= output_eth_payload_tlast_int; - temp_axis_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_axis_tdata_reg; - output_eth_payload_tvalid_reg <= temp_axis_tvalid_reg; - output_eth_payload_tlast_reg <= temp_axis_tlast_reg; - output_eth_payload_tuser_reg <= temp_axis_tuser_reg; - temp_axis_tdata_reg <= 0; - temp_axis_tvalid_reg <= 0; - temp_axis_tlast_reg <= 0; - temp_axis_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index cfff84b5f..bd55af8cd 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -126,43 +126,43 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_ip_hdr; reg store_last_word; -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; reg flush_save; reg transfer_in_save; reg [31:0] hdr_sum_temp; -reg [31:0] hdr_sum_reg = 0, hdr_sum_next; +reg [31:0] hdr_sum_reg = 32'd0, hdr_sum_next; -reg [63:0] last_word_data_reg = 0; -reg [7:0] last_word_keep_reg = 0; +reg [63:0] last_word_data_reg = 64'd0; +reg [7:0] last_word_keep_reg = 8'd0; -reg [5:0] ip_dscp_reg = 0; -reg [1:0] ip_ecn_reg = 0; -reg [15:0] ip_length_reg = 0; -reg [15:0] ip_identification_reg = 0; -reg [2:0] ip_flags_reg = 0; -reg [12:0] ip_fragment_offset_reg = 0; -reg [7:0] ip_ttl_reg = 0; -reg [7:0] ip_protocol_reg = 0; -reg [31:0] ip_source_ip_reg = 0; -reg [31:0] ip_dest_ip_reg = 0; +reg [5:0] ip_dscp_reg = 6'd0; +reg [1:0] ip_ecn_reg = 2'd0; +reg [15:0] ip_length_reg = 16'd0; +reg [15:0] ip_identification_reg = 16'd0; +reg [2:0] ip_flags_reg = 3'd0; +reg [12:0] ip_fragment_offset_reg = 13'd0; +reg [7:0] ip_ttl_reg = 8'd0; +reg [7:0] ip_protocol_reg = 8'd0; +reg [31:0] ip_source_ip_reg = 32'd0; +reg [31:0] ip_dest_ip_reg = 32'd0; -reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; +reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; -reg output_eth_hdr_valid_reg = 0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; +reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; -reg busy_reg = 0; -reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; +reg busy_reg = 1'b0; +reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; -reg [63:0] save_ip_payload_tdata_reg = 0; -reg [7:0] save_ip_payload_tkeep_reg = 0; -reg save_ip_payload_tlast_reg = 0; -reg save_ip_payload_tuser_reg = 0; +reg [63:0] save_ip_payload_tdata_reg = 64'd0; +reg [7:0] save_ip_payload_tkeep_reg = 8'd0; +reg save_ip_payload_tlast_reg = 1'b0; +reg save_ip_payload_tuser_reg = 1'b0; reg [63:0] shift_ip_payload_tdata; reg [7:0] shift_ip_payload_tkeep; @@ -176,7 +176,7 @@ reg shift_ip_payload_extra_cycle; reg [63:0] output_eth_payload_tdata_int; reg [7:0] output_eth_payload_tkeep_int; reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int = 0; +reg output_eth_payload_tready_int_reg = 1'b0; reg output_eth_payload_tlast_int; reg output_eth_payload_tuser_int; wire output_eth_payload_tready_int_early; @@ -195,15 +195,15 @@ assign error_payload_early_termination = error_payload_early_termination_reg; function [3:0] keep2count; input [7:0] k; case (k) - 8'b00000000: keep2count = 0; - 8'b00000001: keep2count = 1; - 8'b00000011: keep2count = 2; - 8'b00000111: keep2count = 3; - 8'b00001111: keep2count = 4; - 8'b00011111: keep2count = 5; - 8'b00111111: keep2count = 6; - 8'b01111111: keep2count = 7; - 8'b11111111: keep2count = 8; + 8'b00000000: keep2count = 4'd0; + 8'b00000001: keep2count = 4'd1; + 8'b00000011: keep2count = 4'd2; + 8'b00000111: keep2count = 4'd3; + 8'b00001111: keep2count = 4'd4; + 8'b00011111: keep2count = 4'd5; + 8'b00111111: keep2count = 4'd6; + 8'b01111111: keep2count = 4'd7; + 8'b11111111: keep2count = 4'd8; endcase endfunction @@ -228,9 +228,9 @@ always @* begin shift_ip_payload_extra_cycle = save_ip_payload_tlast_reg & (save_ip_payload_tkeep_reg[7:4] != 0); if (shift_ip_payload_extra_cycle) begin - shift_ip_payload_tdata[63:32] = 0; - shift_ip_payload_tkeep[7:4] = 0; - shift_ip_payload_tvalid = 1; + shift_ip_payload_tdata[63:32] = 32'd0; + shift_ip_payload_tkeep[7:4] = 4'd0; + shift_ip_payload_tvalid = 1'b1; shift_ip_payload_tlast = save_ip_payload_tlast_reg; shift_ip_payload_tuser = save_ip_payload_tuser_reg; shift_ip_payload_input_tready = flush_save; @@ -247,40 +247,40 @@ end always @* begin state_next = STATE_IDLE; - input_ip_hdr_ready_next = 0; - input_ip_payload_tready_next = 0; + input_ip_hdr_ready_next = 1'b0; + input_ip_payload_tready_next = 1'b0; - store_ip_hdr = 0; + store_ip_hdr = 1'b0; - store_last_word = 0; + store_last_word = 1'b0; - flush_save = 0; - transfer_in_save = 0; + flush_save = 1'b0; + transfer_in_save = 1'b0; frame_ptr_next = frame_ptr_reg; - hdr_sum_temp = 0; + hdr_sum_temp = 16'd0; hdr_sum_next = hdr_sum_reg; output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - error_payload_early_termination_next = 0; + error_payload_early_termination_next = 1'b0; - output_eth_payload_tdata_int = 0; - output_eth_payload_tkeep_int = 0; - output_eth_payload_tvalid_int = 0; - output_eth_payload_tlast_int = 0; - output_eth_payload_tuser_int = 0; + output_eth_payload_tdata_int = 1'b0; + output_eth_payload_tkeep_int = 1'b0; + output_eth_payload_tvalid_int = 1'b0; + output_eth_payload_tlast_int = 1'b0; + output_eth_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; - flush_save = 1; + frame_ptr_next = 16'd0; + flush_save = 1'b1; input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; if (input_ip_hdr_ready & input_ip_hdr_valid) begin - store_ip_hdr = 1; + store_ip_hdr = 1'b1; hdr_sum_next = {4'd4, 4'd5, input_ip_dscp, input_ip_ecn} + input_ip_length + input_ip_identification + @@ -290,10 +290,10 @@ always @* begin input_ip_source_ip[15: 0] + input_ip_dest_ip[31:16] + input_ip_dest_ip[15: 0]; - input_ip_hdr_ready_next = 0; - output_eth_hdr_valid_next = 1; - if (output_eth_payload_tready_int) begin - output_eth_payload_tvalid_int = 1; + input_ip_hdr_ready_next = 1'b0; + output_eth_hdr_valid_next = 1'b1; + if (output_eth_payload_tready_int_reg) begin + output_eth_payload_tvalid_int = 1'b1; output_eth_payload_tdata_int[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl output_eth_payload_tdata_int[15: 8] = {input_ip_dscp, input_ip_ecn}; output_eth_payload_tdata_int[23:16] = input_ip_length[15: 8]; @@ -303,7 +303,7 @@ always @* begin output_eth_payload_tdata_int[55:48] = {input_ip_flags, input_ip_fragment_offset[12: 8]}; output_eth_payload_tdata_int[63:56] = input_ip_fragment_offset[ 7: 0]; output_eth_payload_tkeep_int = 8'hff; - frame_ptr_next = 8; + frame_ptr_next = 16'd8; end state_next = STATE_WRITE_HEADER; end else begin @@ -312,9 +312,9 @@ always @* begin end STATE_WRITE_HEADER: begin // write header - if (output_eth_payload_tready_int) begin - frame_ptr_next = frame_ptr_reg+8; - output_eth_payload_tvalid_int = 1; + if (output_eth_payload_tready_int_reg) begin + frame_ptr_next = frame_ptr_reg + 16'd8; + output_eth_payload_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: begin @@ -353,8 +353,8 @@ always @* begin input_ip_payload_tready_next = output_eth_payload_tready_int_early & shift_ip_payload_input_tready; if (input_ip_payload_tready & input_ip_payload_tvalid) begin - output_eth_payload_tvalid_int = 1; - transfer_in_save = 1; + output_eth_payload_tvalid_int = 1'b1; + transfer_in_save = 1'b1; output_eth_payload_tdata_int[ 7: 0] = ip_dest_ip_reg[31:24]; output_eth_payload_tdata_int[15: 8] = ip_dest_ip_reg[23:16]; @@ -375,20 +375,20 @@ always @* begin output_eth_payload_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); if (shift_ip_payload_tlast) begin input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin - store_last_word = 1; + store_last_word = 1'b1; input_ip_payload_tready_next = shift_ip_payload_input_tready; - output_eth_payload_tvalid_int = 0; + output_eth_payload_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin if (shift_ip_payload_tlast) begin // end of frame, but length does not match - error_payload_early_termination_next = 1; + error_payload_early_termination_next = 1'b1; input_ip_payload_tready_next = shift_ip_payload_input_tready; - output_eth_payload_tuser_int = 1; + output_eth_payload_tuser_int = 1'b1; state_next = STATE_WAIT_LAST; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -408,31 +408,31 @@ always @* begin output_eth_payload_tlast_int = shift_ip_payload_tlast; output_eth_payload_tuser_int = shift_ip_payload_tuser; - if (output_eth_payload_tready_int & shift_ip_payload_tvalid) begin + if (output_eth_payload_tready_int_reg & shift_ip_payload_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_tkeep); - transfer_in_save = 1; + transfer_in_save = 1'b1; if (frame_ptr_next >= ip_length_reg) begin // have entire payload frame_ptr_next = ip_length_reg; output_eth_payload_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); if (shift_ip_payload_tlast) begin - input_ip_payload_tready_next = 0; - flush_save = 1; + input_ip_payload_tready_next = 1'b0; + flush_save = 1'b1; input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; state_next = STATE_IDLE; end else begin - store_last_word = 1; - output_eth_payload_tvalid_int = 0; + store_last_word = 1'b1; + output_eth_payload_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin if (shift_ip_payload_tlast) begin // end of frame, but length does not match - error_payload_early_termination_next = 1; - output_eth_payload_tuser_int = 1; - input_ip_payload_tready_next = 0; - flush_save = 1; + error_payload_early_termination_next = 1'b1; + output_eth_payload_tuser_int = 1'b1; + input_ip_payload_tready_next = 1'b0; + flush_save = 1'b1; input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; state_next = STATE_IDLE; end else begin @@ -453,11 +453,11 @@ always @* begin output_eth_payload_tlast_int = shift_ip_payload_tlast; output_eth_payload_tuser_int = shift_ip_payload_tuser; - if (output_eth_payload_tready_int & shift_ip_payload_tvalid) begin - transfer_in_save = 1; + if (output_eth_payload_tready_int_reg & shift_ip_payload_tvalid) begin + transfer_in_save = 1'b1; if (shift_ip_payload_tlast) begin input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD_LAST; @@ -471,10 +471,10 @@ always @* begin input_ip_payload_tready_next = shift_ip_payload_input_tready; if (shift_ip_payload_tvalid) begin - transfer_in_save = 1; + transfer_in_save = 1'b1; if (shift_ip_payload_tlast) begin input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -489,28 +489,14 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - hdr_sum_reg <= 0; - last_word_data_reg <= 0; - last_word_keep_reg <= 0; - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - ip_dscp_reg <= 0; - ip_ecn_reg <= 0; - ip_length_reg <= 0; - ip_identification_reg <= 0; - ip_flags_reg <= 0; - ip_fragment_offset_reg <= 0; - ip_ttl_reg <= 0; - ip_protocol_reg <= 0; - ip_source_ip_reg <= 0; - ip_dest_ip_reg <= 0; - output_eth_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - busy_reg <= 0; - error_payload_early_termination_reg <= 0; + frame_ptr_reg <= 16'd0; + hdr_sum_reg <= 16'd0; + input_ip_hdr_ready_reg <= 1'b0; + input_ip_payload_tready_reg <= 1'b0; + output_eth_hdr_valid_reg <= 1'b0; + save_ip_payload_tlast_reg <= 1'b0; + busy_reg <= 1'b0; + error_payload_early_termination_reg <= 1'b0; end else begin state_reg <= state_next; @@ -527,57 +513,59 @@ always @(posedge clk) begin error_payload_early_termination_reg <= error_payload_early_termination_next; - // datapath - if (store_ip_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - ip_dscp_reg <= input_ip_dscp; - ip_ecn_reg <= input_ip_ecn; - ip_length_reg <= input_ip_length; - ip_identification_reg <= input_ip_identification; - ip_flags_reg <= input_ip_flags; - ip_fragment_offset_reg <= input_ip_fragment_offset; - ip_ttl_reg <= input_ip_ttl; - ip_protocol_reg <= input_ip_protocol; - ip_source_ip_reg <= input_ip_source_ip; - ip_dest_ip_reg <= input_ip_dest_ip; - end - - if (store_last_word) begin - last_word_data_reg <= output_eth_payload_tdata_int; - last_word_keep_reg <= output_eth_payload_tkeep_int; - end - if (flush_save) begin - save_ip_payload_tdata_reg <= 0; - save_ip_payload_tkeep_reg <= 0; - save_ip_payload_tlast_reg <= 0; - save_ip_payload_tuser_reg <= 0; + save_ip_payload_tlast_reg <= 1'b0; end else if (transfer_in_save) begin - save_ip_payload_tdata_reg <= input_ip_payload_tdata; - save_ip_payload_tkeep_reg <= input_ip_payload_tkeep; save_ip_payload_tlast_reg <= input_ip_payload_tlast; - save_ip_payload_tuser_reg <= input_ip_payload_tuser; end end + + // datapath + if (store_ip_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + ip_dscp_reg <= input_ip_dscp; + ip_ecn_reg <= input_ip_ecn; + ip_length_reg <= input_ip_length; + ip_identification_reg <= input_ip_identification; + ip_flags_reg <= input_ip_flags; + ip_fragment_offset_reg <= input_ip_fragment_offset; + ip_ttl_reg <= input_ip_ttl; + ip_protocol_reg <= input_ip_protocol; + ip_source_ip_reg <= input_ip_source_ip; + ip_dest_ip_reg <= input_ip_dest_ip; + end + + if (store_last_word) begin + last_word_data_reg <= output_eth_payload_tdata_int; + last_word_keep_reg <= output_eth_payload_tkeep_int; + end + + if (transfer_in_save) begin + save_ip_payload_tdata_reg <= input_ip_payload_tdata; + save_ip_payload_tkeep_reg <= input_ip_payload_tkeep; + save_ip_payload_tuser_reg <= input_ip_payload_tuser; + end end // output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 0; -reg [7:0] output_eth_payload_tkeep_reg = 0; -reg output_eth_payload_tvalid_reg = 0; -reg output_eth_payload_tlast_reg = 0; -reg output_eth_payload_tuser_reg = 0; +reg [64:0] output_eth_payload_tdata_reg = 64'd0; +reg [7:0] output_eth_payload_tkeep_reg = 8'd0; +reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; +reg output_eth_payload_tlast_reg = 1'b0; +reg output_eth_payload_tuser_reg = 1'b0; -reg [63:0] temp_eth_payload_tdata_reg = 0; -reg [7:0] temp_eth_payload_tkeep_reg = 0; -reg temp_eth_payload_tvalid_reg = 0; -reg temp_eth_payload_tlast_reg = 0; -reg temp_eth_payload_tuser_reg = 0; +reg [64:0] temp_eth_payload_tdata_reg = 64'd0; +reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; +reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; +reg temp_eth_payload_tlast_reg = 1'b0; +reg temp_eth_payload_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_reg) | (~temp_eth_payload_tvalid_reg & ~output_eth_payload_tvalid_int); +// datapath control +reg store_eth_payload_int_to_output; +reg store_eth_payload_int_to_temp; +reg store_eth_payload_temp_to_output; assign output_eth_payload_tdata = output_eth_payload_tdata_reg; assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; @@ -585,53 +573,66 @@ assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; assign output_eth_payload_tlast = output_eth_payload_tlast_reg; assign output_eth_payload_tuser = output_eth_payload_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + + store_eth_payload_int_to_output = 1'b0; + store_eth_payload_int_to_temp = 1'b0; + store_eth_payload_temp_to_output = 1'b0; + + if (output_eth_payload_tready_int_reg) begin + // input is ready + if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + store_eth_payload_int_to_temp = 1'b1; + end + end else if (output_eth_payload_tready) begin + // input is not ready, but output is ready + output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + temp_eth_payload_tvalid_next = 1'b0; + store_eth_payload_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_eth_payload_tdata_reg <= 0; - output_eth_payload_tkeep_reg <= 0; - output_eth_payload_tvalid_reg <= 0; - output_eth_payload_tlast_reg <= 0; - output_eth_payload_tuser_reg <= 0; - output_eth_payload_tready_int <= 0; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; + output_eth_payload_tvalid_reg <= 1'b0; + output_eth_payload_tready_int_reg <= 1'b0; + temp_eth_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_eth_payload_tready_int <= output_eth_payload_tready_int_early; + output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; + output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; + temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + end - if (output_eth_payload_tready_int) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tvalid_reg <= output_eth_payload_tvalid_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - temp_eth_payload_tdata_reg <= 0; - temp_eth_payload_tkeep_reg <= 0; - temp_eth_payload_tvalid_reg <= 0; - temp_eth_payload_tlast_reg <= 0; - temp_eth_payload_tuser_reg <= 0; - end + // datapath + if (store_eth_payload_int_to_output) begin + output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + end else if (store_eth_payload_temp_to_output) begin + output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; + output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; + output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; + output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + end + + if (store_eth_payload_int_to_temp) begin + temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; + temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; + temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; + temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; end end diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py index 875f6e7b0..bf2ce3286 100755 --- a/rtl/ip_mux.py +++ b/rtl/ip_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -136,37 +136,37 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; {% for p in ports %} -reg input_{{p}}_ip_hdr_ready_reg = 0, input_{{p}}_ip_hdr_ready_next; +reg input_{{p}}_ip_hdr_ready_reg = 1'b0, input_{{p}}_ip_hdr_ready_next; {%- endfor %} {% for p in ports %} -reg input_{{p}}_ip_payload_tready_reg = 0, input_{{p}}_ip_payload_tready_next; +reg input_{{p}}_ip_payload_tready_reg = 1'b0, input_{{p}}_ip_payload_tready_next; {%- endfor %} -reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; // internal datapath reg [7:0] output_ip_payload_tdata_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -236,6 +236,25 @@ always @* begin selected_input_ip_dest_ip = input_{{p}}_ip_dest_ip; end {%- endfor %} + default: begin + selected_input_ip_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + selected_input_ip_version = 4'd0; + selected_input_ip_ihl = 4'd0; + selected_input_ip_dscp = 6'd0; + selected_input_ip_ecn = 2'd0; + selected_input_ip_length = 16'd0; + selected_input_ip_identification = 16'd0; + selected_input_ip_flags = 3'd0; + selected_input_ip_fragment_offset = 13'd0; + selected_input_ip_ttl = 8'd0; + selected_input_ip_protocol = 8'd0; + selected_input_ip_header_checksum = 16'd0; + selected_input_ip_source_ip = 32'd0; + selected_input_ip_dest_ip = 32'd0; + end endcase end @@ -256,6 +275,13 @@ always @* begin current_input_tuser = input_{{p}}_ip_payload_tuser; end {%- endfor %} + default: begin + current_input_tdata = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -266,7 +292,7 @@ always @* begin input_{{p}}_ip_hdr_ready_next = input_{{p}}_ip_hdr_ready_reg & ~input_{{p}}_ip_hdr_valid; {%- endfor %} {% for p in ports %} - input_{{p}}_ip_payload_tready_next = 0; + input_{{p}}_ip_payload_tready_next = 1'b0; {%- endfor %} output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; @@ -294,12 +320,12 @@ always @* begin end end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) {%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_ip_hdr_ready_next = 1; + {{w}}'d{{p}}: input_{{p}}_ip_hdr_ready_next = 1'b1; {%- endfor %} endcase @@ -338,31 +364,15 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; {%- for p in ports %} - input_{{p}}_ip_hdr_ready_reg <= 0; + input_{{p}}_ip_hdr_ready_reg <= 1'b0; {%- endfor %} {%- for p in ports %} - input_{{p}}_ip_payload_tready_reg <= 0; + input_{{p}}_ip_payload_tready_reg <= 1'b0; {%- endfor %} - output_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; + output_ip_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -373,85 +383,104 @@ always @(posedge clk) begin input_{{p}}_ip_payload_tready_reg <= input_{{p}}_ip_payload_tready_next; {%- endfor %} output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; end // output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [7:0] output_ip_payload_tdata_reg = 8'd0; +reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [7:0] temp_ip_payload_tdata_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [7:0] temp_ip_payload_tdata_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; + +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_mux_2.v b/rtl/ip_mux_2.v index 704e57cf6..ac8d90cb4 100644 --- a/rtl/ip_mux_2.v +++ b/rtl/ip_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -119,37 +119,37 @@ module ip_mux_2 input wire [0:0] select ); -reg [0:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [0:0] select_reg = 1'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_ip_hdr_ready_reg = 0, input_0_ip_hdr_ready_next; -reg input_1_ip_hdr_ready_reg = 0, input_1_ip_hdr_ready_next; +reg input_0_ip_hdr_ready_reg = 1'b0, input_0_ip_hdr_ready_next; +reg input_1_ip_hdr_ready_reg = 1'b0, input_1_ip_hdr_ready_next; -reg input_0_ip_payload_tready_reg = 0, input_0_ip_payload_tready_next; -reg input_1_ip_payload_tready_reg = 0, input_1_ip_payload_tready_next; +reg input_0_ip_payload_tready_reg = 1'b0, input_0_ip_payload_tready_next; +reg input_1_ip_payload_tready_reg = 1'b0, input_1_ip_payload_tready_next; -reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; // internal datapath reg [7:0] output_ip_payload_tdata_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -236,6 +236,25 @@ always @* begin selected_input_ip_source_ip = input_1_ip_source_ip; selected_input_ip_dest_ip = input_1_ip_dest_ip; end + default: begin + selected_input_ip_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + selected_input_ip_version = 4'd0; + selected_input_ip_ihl = 4'd0; + selected_input_ip_dscp = 6'd0; + selected_input_ip_ecn = 2'd0; + selected_input_ip_length = 16'd0; + selected_input_ip_identification = 16'd0; + selected_input_ip_flags = 3'd0; + selected_input_ip_fragment_offset = 13'd0; + selected_input_ip_ttl = 8'd0; + selected_input_ip_protocol = 8'd0; + selected_input_ip_header_checksum = 16'd0; + selected_input_ip_source_ip = 32'd0; + selected_input_ip_dest_ip = 32'd0; + end endcase end @@ -261,6 +280,13 @@ always @* begin current_input_tlast = input_1_ip_payload_tlast; current_input_tuser = input_1_ip_payload_tuser; end + default: begin + current_input_tdata = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -271,8 +297,8 @@ always @* begin input_0_ip_hdr_ready_next = input_0_ip_hdr_ready_reg & ~input_0_ip_hdr_valid; input_1_ip_hdr_ready_next = input_1_ip_hdr_ready_reg & ~input_1_ip_hdr_valid; - input_0_ip_payload_tready_next = 0; - input_1_ip_payload_tready_next = 0; + input_0_ip_payload_tready_next = 1'b0; + input_1_ip_payload_tready_next = 1'b0; output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; output_eth_dest_mac_next = output_eth_dest_mac_reg; @@ -299,12 +325,12 @@ always @* begin end end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) - 1'd0: input_0_ip_hdr_ready_next = 1; - 1'd1: input_1_ip_hdr_ready_next = 1; + 1'd0: input_0_ip_hdr_ready_next = 1'b1; + 1'd1: input_1_ip_hdr_ready_next = 1'b1; endcase output_ip_hdr_valid_next = 1; @@ -341,29 +367,13 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_ip_hdr_ready_reg <= 0; - input_1_ip_hdr_ready_reg <= 0; - input_0_ip_payload_tready_reg <= 0; - input_1_ip_payload_tready_reg <= 0; - output_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; + select_reg <= 1'd0; + frame_reg <= 1'b0; + input_0_ip_hdr_ready_reg <= 1'b0; + input_1_ip_hdr_ready_reg <= 1'b0; + input_0_ip_payload_tready_reg <= 1'b0; + input_1_ip_payload_tready_reg <= 1'b0; + output_ip_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -372,85 +382,104 @@ always @(posedge clk) begin input_0_ip_payload_tready_reg <= input_0_ip_payload_tready_next; input_1_ip_payload_tready_reg <= input_1_ip_payload_tready_next; output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; end // output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [7:0] output_ip_payload_tdata_reg = 8'd0; +reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [7:0] temp_ip_payload_tdata_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [7:0] temp_ip_payload_tdata_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; + +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_mux_4.v b/rtl/ip_mux_4.v index 553349d42..c4ef12de4 100644 --- a/rtl/ip_mux_4.v +++ b/rtl/ip_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -167,41 +167,41 @@ module ip_mux_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_ip_hdr_ready_reg = 0, input_0_ip_hdr_ready_next; -reg input_1_ip_hdr_ready_reg = 0, input_1_ip_hdr_ready_next; -reg input_2_ip_hdr_ready_reg = 0, input_2_ip_hdr_ready_next; -reg input_3_ip_hdr_ready_reg = 0, input_3_ip_hdr_ready_next; +reg input_0_ip_hdr_ready_reg = 1'b0, input_0_ip_hdr_ready_next; +reg input_1_ip_hdr_ready_reg = 1'b0, input_1_ip_hdr_ready_next; +reg input_2_ip_hdr_ready_reg = 1'b0, input_2_ip_hdr_ready_next; +reg input_3_ip_hdr_ready_reg = 1'b0, input_3_ip_hdr_ready_next; -reg input_0_ip_payload_tready_reg = 0, input_0_ip_payload_tready_next; -reg input_1_ip_payload_tready_reg = 0, input_1_ip_payload_tready_next; -reg input_2_ip_payload_tready_reg = 0, input_2_ip_payload_tready_next; -reg input_3_ip_payload_tready_reg = 0, input_3_ip_payload_tready_next; +reg input_0_ip_payload_tready_reg = 1'b0, input_0_ip_payload_tready_next; +reg input_1_ip_payload_tready_reg = 1'b0, input_1_ip_payload_tready_next; +reg input_2_ip_payload_tready_reg = 1'b0, input_2_ip_payload_tready_next; +reg input_3_ip_payload_tready_reg = 1'b0, input_3_ip_payload_tready_next; -reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; // internal datapath reg [7:0] output_ip_payload_tdata_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -330,6 +330,25 @@ always @* begin selected_input_ip_source_ip = input_3_ip_source_ip; selected_input_ip_dest_ip = input_3_ip_dest_ip; end + default: begin + selected_input_ip_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + selected_input_ip_version = 4'd0; + selected_input_ip_ihl = 4'd0; + selected_input_ip_dscp = 6'd0; + selected_input_ip_ecn = 2'd0; + selected_input_ip_length = 16'd0; + selected_input_ip_identification = 16'd0; + selected_input_ip_flags = 3'd0; + selected_input_ip_fragment_offset = 13'd0; + selected_input_ip_ttl = 8'd0; + selected_input_ip_protocol = 8'd0; + selected_input_ip_header_checksum = 16'd0; + selected_input_ip_source_ip = 32'd0; + selected_input_ip_dest_ip = 32'd0; + end endcase end @@ -369,6 +388,13 @@ always @* begin current_input_tlast = input_3_ip_payload_tlast; current_input_tuser = input_3_ip_payload_tuser; end + default: begin + current_input_tdata = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -381,10 +407,10 @@ always @* begin input_2_ip_hdr_ready_next = input_2_ip_hdr_ready_reg & ~input_2_ip_hdr_valid; input_3_ip_hdr_ready_next = input_3_ip_hdr_ready_reg & ~input_3_ip_hdr_valid; - input_0_ip_payload_tready_next = 0; - input_1_ip_payload_tready_next = 0; - input_2_ip_payload_tready_next = 0; - input_3_ip_payload_tready_next = 0; + input_0_ip_payload_tready_next = 1'b0; + input_1_ip_payload_tready_next = 1'b0; + input_2_ip_payload_tready_next = 1'b0; + input_3_ip_payload_tready_next = 1'b0; output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; output_eth_dest_mac_next = output_eth_dest_mac_reg; @@ -411,14 +437,14 @@ always @* begin end end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) - 2'd0: input_0_ip_hdr_ready_next = 1; - 2'd1: input_1_ip_hdr_ready_next = 1; - 2'd2: input_2_ip_hdr_ready_next = 1; - 2'd3: input_3_ip_hdr_ready_next = 1; + 2'd0: input_0_ip_hdr_ready_next = 1'b1; + 2'd1: input_1_ip_hdr_ready_next = 1'b1; + 2'd2: input_2_ip_hdr_ready_next = 1'b1; + 2'd3: input_3_ip_hdr_ready_next = 1'b1; endcase output_ip_hdr_valid_next = 1; @@ -457,33 +483,17 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_ip_hdr_ready_reg <= 0; - input_1_ip_hdr_ready_reg <= 0; - input_2_ip_hdr_ready_reg <= 0; - input_3_ip_hdr_ready_reg <= 0; - input_0_ip_payload_tready_reg <= 0; - input_1_ip_payload_tready_reg <= 0; - input_2_ip_payload_tready_reg <= 0; - input_3_ip_payload_tready_reg <= 0; - output_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_0_ip_hdr_ready_reg <= 1'b0; + input_1_ip_hdr_ready_reg <= 1'b0; + input_2_ip_hdr_ready_reg <= 1'b0; + input_3_ip_hdr_ready_reg <= 1'b0; + input_0_ip_payload_tready_reg <= 1'b0; + input_1_ip_payload_tready_reg <= 1'b0; + input_2_ip_payload_tready_reg <= 1'b0; + input_3_ip_payload_tready_reg <= 1'b0; + output_ip_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -496,85 +506,104 @@ always @(posedge clk) begin input_2_ip_payload_tready_reg <= input_2_ip_payload_tready_next; input_3_ip_payload_tready_reg <= input_3_ip_payload_tready_next; output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; end // output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [7:0] output_ip_payload_tdata_reg = 8'd0; +reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [7:0] temp_ip_payload_tdata_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [7:0] temp_ip_payload_tdata_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; + +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py index 2c3f198b9..75670ff48 100755 --- a/rtl/ip_mux_64.py +++ b/rtl/ip_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -138,38 +138,38 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; {% for p in ports %} -reg input_{{p}}_ip_hdr_ready_reg = 0, input_{{p}}_ip_hdr_ready_next; +reg input_{{p}}_ip_hdr_ready_reg = 1'b0, input_{{p}}_ip_hdr_ready_next; {%- endfor %} {% for p in ports %} -reg input_{{p}}_ip_payload_tready_reg = 0, input_{{p}}_ip_payload_tready_next; +reg input_{{p}}_ip_payload_tready_reg = 1'b0, input_{{p}}_ip_payload_tready_next; {%- endfor %} -reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; // internal datapath reg [63:0] output_ip_payload_tdata_int; reg [7:0] output_ip_payload_tkeep_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -239,6 +239,25 @@ always @* begin selected_input_ip_dest_ip = input_{{p}}_ip_dest_ip; end {%- endfor %} + default: begin + selected_input_ip_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + selected_input_ip_version = 4'd0; + selected_input_ip_ihl = 4'd0; + selected_input_ip_dscp = 6'd0; + selected_input_ip_ecn = 2'd0; + selected_input_ip_length = 16'd0; + selected_input_ip_identification = 16'd0; + selected_input_ip_flags = 3'd0; + selected_input_ip_fragment_offset = 13'd0; + selected_input_ip_ttl = 8'd0; + selected_input_ip_protocol = 8'd0; + selected_input_ip_header_checksum = 16'd0; + selected_input_ip_source_ip = 32'd0; + selected_input_ip_dest_ip = 32'd0; + end endcase end @@ -261,6 +280,14 @@ always @* begin current_input_tuser = input_{{p}}_ip_payload_tuser; end {%- endfor %} + default: begin + current_input_tdata = 64'd0; + current_input_tkeep = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -271,7 +298,7 @@ always @* begin input_{{p}}_ip_hdr_ready_next = input_{{p}}_ip_hdr_ready_reg & ~input_{{p}}_ip_hdr_valid; {%- endfor %} {% for p in ports %} - input_{{p}}_ip_payload_tready_next = 0; + input_{{p}}_ip_payload_tready_next = 1'b0; {%- endfor %} output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; @@ -299,16 +326,16 @@ always @* begin end end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) {%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_ip_hdr_ready_next = 1; + {{w}}'d{{p}}: input_{{p}}_ip_hdr_ready_next = 1'b1; {%- endfor %} endcase - output_ip_hdr_valid_next = 1; + output_ip_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -344,31 +371,15 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; {%- for p in ports %} - input_{{p}}_ip_hdr_ready_reg <= 0; + input_{{p}}_ip_hdr_ready_reg <= 1'b0; {%- endfor %} {%- for p in ports %} - input_{{p}}_ip_payload_tready_reg <= 0; + input_{{p}}_ip_payload_tready_reg <= 1'b0; {%- endfor %} - output_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; + output_ip_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -379,37 +390,43 @@ always @(posedge clk) begin input_{{p}}_ip_payload_tready_reg <= input_{{p}}_ip_payload_tready_next; {%- endfor %} output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; end // output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 0; -reg [7:0] output_ip_payload_tkeep_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [63:0] output_ip_payload_tdata_reg = 64'd0; +reg [7:0] output_ip_payload_tkeep_reg = 8'd0; +reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [63:0] temp_ip_payload_tdata_reg = 0; -reg [7:0] temp_ip_payload_tkeep_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [63:0] temp_ip_payload_tdata_reg = 64'd0; +reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; + +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; @@ -417,56 +434,66 @@ assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tkeep_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_mux_64_2.v b/rtl/ip_mux_64_2.v index c634c0863..3b58015f2 100644 --- a/rtl/ip_mux_64_2.v +++ b/rtl/ip_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -122,38 +122,38 @@ module ip_mux_64_2 input wire [0:0] select ); -reg [0:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [0:0] select_reg = 1'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_ip_hdr_ready_reg = 0, input_0_ip_hdr_ready_next; -reg input_1_ip_hdr_ready_reg = 0, input_1_ip_hdr_ready_next; +reg input_0_ip_hdr_ready_reg = 1'b0, input_0_ip_hdr_ready_next; +reg input_1_ip_hdr_ready_reg = 1'b0, input_1_ip_hdr_ready_next; -reg input_0_ip_payload_tready_reg = 0, input_0_ip_payload_tready_next; -reg input_1_ip_payload_tready_reg = 0, input_1_ip_payload_tready_next; +reg input_0_ip_payload_tready_reg = 1'b0, input_0_ip_payload_tready_next; +reg input_1_ip_payload_tready_reg = 1'b0, input_1_ip_payload_tready_next; -reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; // internal datapath reg [63:0] output_ip_payload_tdata_int; reg [7:0] output_ip_payload_tkeep_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -240,6 +240,25 @@ always @* begin selected_input_ip_source_ip = input_1_ip_source_ip; selected_input_ip_dest_ip = input_1_ip_dest_ip; end + default: begin + selected_input_ip_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + selected_input_ip_version = 4'd0; + selected_input_ip_ihl = 4'd0; + selected_input_ip_dscp = 6'd0; + selected_input_ip_ecn = 2'd0; + selected_input_ip_length = 16'd0; + selected_input_ip_identification = 16'd0; + selected_input_ip_flags = 3'd0; + selected_input_ip_fragment_offset = 13'd0; + selected_input_ip_ttl = 8'd0; + selected_input_ip_protocol = 8'd0; + selected_input_ip_header_checksum = 16'd0; + selected_input_ip_source_ip = 32'd0; + selected_input_ip_dest_ip = 32'd0; + end endcase end @@ -268,6 +287,14 @@ always @* begin current_input_tlast = input_1_ip_payload_tlast; current_input_tuser = input_1_ip_payload_tuser; end + default: begin + current_input_tdata = 64'd0; + current_input_tkeep = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -278,8 +305,8 @@ always @* begin input_0_ip_hdr_ready_next = input_0_ip_hdr_ready_reg & ~input_0_ip_hdr_valid; input_1_ip_hdr_ready_next = input_1_ip_hdr_ready_reg & ~input_1_ip_hdr_valid; - input_0_ip_payload_tready_next = 0; - input_1_ip_payload_tready_next = 0; + input_0_ip_payload_tready_next = 1'b0; + input_1_ip_payload_tready_next = 1'b0; output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; output_eth_dest_mac_next = output_eth_dest_mac_reg; @@ -306,15 +333,15 @@ always @* begin end end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) - 1'd0: input_0_ip_hdr_ready_next = 1; - 1'd1: input_1_ip_hdr_ready_next = 1; + 1'd0: input_0_ip_hdr_ready_next = 1'b1; + 1'd1: input_1_ip_hdr_ready_next = 1'b1; endcase - output_ip_hdr_valid_next = 1; + output_ip_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -349,29 +376,13 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_ip_hdr_ready_reg <= 0; - input_1_ip_hdr_ready_reg <= 0; - input_0_ip_payload_tready_reg <= 0; - input_1_ip_payload_tready_reg <= 0; - output_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; + select_reg <= 1'd0; + frame_reg <= 1'b0; + input_0_ip_hdr_ready_reg <= 1'b0; + input_1_ip_hdr_ready_reg <= 1'b0; + input_0_ip_payload_tready_reg <= 1'b0; + input_1_ip_payload_tready_reg <= 1'b0; + output_ip_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -380,37 +391,43 @@ always @(posedge clk) begin input_0_ip_payload_tready_reg <= input_0_ip_payload_tready_next; input_1_ip_payload_tready_reg <= input_1_ip_payload_tready_next; output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; end // output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 0; -reg [7:0] output_ip_payload_tkeep_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [63:0] output_ip_payload_tdata_reg = 64'd0; +reg [7:0] output_ip_payload_tkeep_reg = 8'd0; +reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [63:0] temp_ip_payload_tdata_reg = 0; -reg [7:0] temp_ip_payload_tkeep_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [63:0] temp_ip_payload_tdata_reg = 64'd0; +reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; + +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; @@ -418,56 +435,66 @@ assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tkeep_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/ip_mux_64_4.v b/rtl/ip_mux_64_4.v index 623449cdb..7fc063a1e 100644 --- a/rtl/ip_mux_64_4.v +++ b/rtl/ip_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -172,42 +172,42 @@ module ip_mux_64_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_ip_hdr_ready_reg = 0, input_0_ip_hdr_ready_next; -reg input_1_ip_hdr_ready_reg = 0, input_1_ip_hdr_ready_next; -reg input_2_ip_hdr_ready_reg = 0, input_2_ip_hdr_ready_next; -reg input_3_ip_hdr_ready_reg = 0, input_3_ip_hdr_ready_next; +reg input_0_ip_hdr_ready_reg = 1'b0, input_0_ip_hdr_ready_next; +reg input_1_ip_hdr_ready_reg = 1'b0, input_1_ip_hdr_ready_next; +reg input_2_ip_hdr_ready_reg = 1'b0, input_2_ip_hdr_ready_next; +reg input_3_ip_hdr_ready_reg = 1'b0, input_3_ip_hdr_ready_next; -reg input_0_ip_payload_tready_reg = 0, input_0_ip_payload_tready_next; -reg input_1_ip_payload_tready_reg = 0, input_1_ip_payload_tready_next; -reg input_2_ip_payload_tready_reg = 0, input_2_ip_payload_tready_next; -reg input_3_ip_payload_tready_reg = 0, input_3_ip_payload_tready_next; +reg input_0_ip_payload_tready_reg = 1'b0, input_0_ip_payload_tready_next; +reg input_1_ip_payload_tready_reg = 1'b0, input_1_ip_payload_tready_next; +reg input_2_ip_payload_tready_reg = 1'b0, input_2_ip_payload_tready_next; +reg input_3_ip_payload_tready_reg = 1'b0, input_3_ip_payload_tready_next; -reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; +reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; // internal datapath reg [63:0] output_ip_payload_tdata_int; reg [7:0] output_ip_payload_tkeep_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -336,6 +336,25 @@ always @* begin selected_input_ip_source_ip = input_3_ip_source_ip; selected_input_ip_dest_ip = input_3_ip_dest_ip; end + default: begin + selected_input_ip_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + selected_input_ip_version = 4'd0; + selected_input_ip_ihl = 4'd0; + selected_input_ip_dscp = 6'd0; + selected_input_ip_ecn = 2'd0; + selected_input_ip_length = 16'd0; + selected_input_ip_identification = 16'd0; + selected_input_ip_flags = 3'd0; + selected_input_ip_fragment_offset = 13'd0; + selected_input_ip_ttl = 8'd0; + selected_input_ip_protocol = 8'd0; + selected_input_ip_header_checksum = 16'd0; + selected_input_ip_source_ip = 32'd0; + selected_input_ip_dest_ip = 32'd0; + end endcase end @@ -380,6 +399,14 @@ always @* begin current_input_tlast = input_3_ip_payload_tlast; current_input_tuser = input_3_ip_payload_tuser; end + default: begin + current_input_tdata = 64'd0; + current_input_tkeep = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -392,10 +419,10 @@ always @* begin input_2_ip_hdr_ready_next = input_2_ip_hdr_ready_reg & ~input_2_ip_hdr_valid; input_3_ip_hdr_ready_next = input_3_ip_hdr_ready_reg & ~input_3_ip_hdr_valid; - input_0_ip_payload_tready_next = 0; - input_1_ip_payload_tready_next = 0; - input_2_ip_payload_tready_next = 0; - input_3_ip_payload_tready_next = 0; + input_0_ip_payload_tready_next = 1'b0; + input_1_ip_payload_tready_next = 1'b0; + input_2_ip_payload_tready_next = 1'b0; + input_3_ip_payload_tready_next = 1'b0; output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; output_eth_dest_mac_next = output_eth_dest_mac_reg; @@ -422,17 +449,17 @@ always @* begin end end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) - 2'd0: input_0_ip_hdr_ready_next = 1; - 2'd1: input_1_ip_hdr_ready_next = 1; - 2'd2: input_2_ip_hdr_ready_next = 1; - 2'd3: input_3_ip_hdr_ready_next = 1; + 2'd0: input_0_ip_hdr_ready_next = 1'b1; + 2'd1: input_1_ip_hdr_ready_next = 1'b1; + 2'd2: input_2_ip_hdr_ready_next = 1'b1; + 2'd3: input_3_ip_hdr_ready_next = 1'b1; endcase - output_ip_hdr_valid_next = 1; + output_ip_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -469,33 +496,17 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_ip_hdr_ready_reg <= 0; - input_1_ip_hdr_ready_reg <= 0; - input_2_ip_hdr_ready_reg <= 0; - input_3_ip_hdr_ready_reg <= 0; - input_0_ip_payload_tready_reg <= 0; - input_1_ip_payload_tready_reg <= 0; - input_2_ip_payload_tready_reg <= 0; - input_3_ip_payload_tready_reg <= 0; - output_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_0_ip_hdr_ready_reg <= 1'b0; + input_1_ip_hdr_ready_reg <= 1'b0; + input_2_ip_hdr_ready_reg <= 1'b0; + input_3_ip_hdr_ready_reg <= 1'b0; + input_0_ip_payload_tready_reg <= 1'b0; + input_1_ip_payload_tready_reg <= 1'b0; + input_2_ip_payload_tready_reg <= 1'b0; + input_3_ip_payload_tready_reg <= 1'b0; + output_ip_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -508,37 +519,43 @@ always @(posedge clk) begin input_2_ip_payload_tready_reg <= input_2_ip_payload_tready_next; input_3_ip_payload_tready_reg <= input_3_ip_payload_tready_next; output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; end // output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 0; -reg [7:0] output_ip_payload_tkeep_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [63:0] output_ip_payload_tdata_reg = 64'd0; +reg [7:0] output_ip_payload_tkeep_reg = 8'd0; +reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [63:0] temp_ip_payload_tdata_reg = 0; -reg [7:0] temp_ip_payload_tkeep_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [63:0] temp_ip_payload_tdata_reg = 64'd0; +reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; + +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; @@ -546,56 +563,66 @@ assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tkeep_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v index 915dcfe35..02f6ee92c 100644 --- a/rtl/udp_complete.v +++ b/rtl/udp_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -277,13 +277,13 @@ wire udp_tx_ip_payload_tready; wire input_select_udp = (ip_rx_ip_protocol == 8'h11); wire input_select_ip = ~input_select_udp; -reg input_select_udp_reg = 0; -reg input_select_ip_reg = 0; +reg input_select_udp_reg = 1'b0; +reg input_select_ip_reg = 1'b0; always @(posedge clk) begin if (rst) begin - input_select_udp_reg <= 0; - input_select_ip_reg <= 0; + input_select_udp_reg <= 1'b0; + input_select_ip_reg <= 1'b0; end else begin if (ip_rx_ip_payload_tvalid) begin if ((~input_select_udp_reg & ~input_select_ip_reg) | @@ -292,8 +292,8 @@ always @(posedge clk) begin input_select_ip_reg <= input_select_ip; end end else begin - input_select_udp_reg <= 0; - input_select_ip_reg <= 0; + input_select_udp_reg <= 1'b0; + input_select_ip_reg <= 1'b0; end end end @@ -359,20 +359,20 @@ ip_arb_mux_2_inst ( // IP frame input from UDP module .input_0_ip_hdr_valid(udp_tx_ip_hdr_valid), .input_0_ip_hdr_ready(udp_tx_ip_hdr_ready), - .input_0_eth_dest_mac(0), - .input_0_eth_src_mac(0), - .input_0_eth_type(0), - .input_0_ip_version(0), - .input_0_ip_ihl(0), + .input_0_eth_dest_mac(48'd0), + .input_0_eth_src_mac(48'd0), + .input_0_eth_type(16'd0), + .input_0_ip_version(4'd0), + .input_0_ip_ihl(4'd0), .input_0_ip_dscp(udp_tx_ip_dscp), .input_0_ip_ecn(udp_tx_ip_ecn), .input_0_ip_length(udp_tx_ip_length), - .input_0_ip_identification(0), - .input_0_ip_flags(0), - .input_0_ip_fragment_offset(0), + .input_0_ip_identification(16'd0), + .input_0_ip_flags(3'd0), + .input_0_ip_fragment_offset(13'd0), .input_0_ip_ttl(udp_tx_ip_ttl), .input_0_ip_protocol(udp_tx_ip_protocol), - .input_0_ip_header_checksum(0), + .input_0_ip_header_checksum(16'd0), .input_0_ip_source_ip(udp_tx_ip_source_ip), .input_0_ip_dest_ip(udp_tx_ip_dest_ip), .input_0_ip_payload_tdata(udp_tx_ip_payload_tdata), @@ -383,20 +383,20 @@ ip_arb_mux_2_inst ( // External IP frame input .input_1_ip_hdr_valid(input_ip_hdr_valid), .input_1_ip_hdr_ready(input_ip_hdr_ready), - .input_1_eth_dest_mac(0), - .input_1_eth_src_mac(0), - .input_1_eth_type(0), - .input_1_ip_version(0), - .input_1_ip_ihl(0), + .input_1_eth_dest_mac(48'd0), + .input_1_eth_src_mac(48'd0), + .input_1_eth_type(16'd0), + .input_1_ip_version(4'd0), + .input_1_ip_ihl(4'd0), .input_1_ip_dscp(input_ip_dscp), .input_1_ip_ecn(input_ip_ecn), .input_1_ip_length(input_ip_length), - .input_1_ip_identification(0), - .input_1_ip_flags(0), - .input_1_ip_fragment_offset(0), + .input_1_ip_identification(16'd0), + .input_1_ip_flags(3'd0), + .input_1_ip_fragment_offset(13'd0), .input_1_ip_ttl(input_ip_ttl), .input_1_ip_protocol(input_ip_protocol), - .input_1_ip_header_checksum(0), + .input_1_ip_header_checksum(16'd0), .input_1_ip_source_ip(input_ip_source_ip), .input_1_ip_dest_ip(input_ip_dest_ip), .input_1_ip_payload_tdata(input_ip_payload_tdata), @@ -582,18 +582,18 @@ udp_inst ( // UDP frame input .input_udp_hdr_valid(input_udp_hdr_valid), .input_udp_hdr_ready(input_udp_hdr_ready), - .input_udp_eth_dest_mac(0), - .input_udp_eth_src_mac(0), - .input_udp_eth_type(0), - .input_udp_ip_version(0), - .input_udp_ip_ihl(0), + .input_udp_eth_dest_mac(48'd0), + .input_udp_eth_src_mac(48'd0), + .input_udp_eth_type(16'd0), + .input_udp_ip_version(4'd0), + .input_udp_ip_ihl(4'd0), .input_udp_ip_dscp(input_udp_ip_dscp), .input_udp_ip_ecn(input_udp_ip_ecn), - .input_udp_ip_identification(0), - .input_udp_ip_flags(0), - .input_udp_ip_fragment_offset(0), + .input_udp_ip_identification(16'd0), + .input_udp_ip_flags(3'd0), + .input_udp_ip_fragment_offset(13'd0), .input_udp_ip_ttl(input_udp_ip_ttl), - .input_udp_ip_header_checksum(0), + .input_udp_ip_header_checksum(16'd0), .input_udp_ip_source_ip(input_udp_ip_source_ip), .input_udp_ip_dest_ip(input_udp_ip_dest_ip), .input_udp_source_port(input_udp_source_port), diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v index 4389e11ca..69b8ae442 100644 --- a/rtl/udp_complete_64.v +++ b/rtl/udp_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -287,13 +287,13 @@ wire udp_tx_ip_payload_tready; wire input_select_udp = (ip_rx_ip_protocol == 8'h11); wire input_select_ip = ~input_select_udp; -reg input_select_udp_reg = 0; -reg input_select_ip_reg = 0; +reg input_select_udp_reg = 1'b0; +reg input_select_ip_reg = 1'b0; always @(posedge clk) begin if (rst) begin - input_select_udp_reg <= 0; - input_select_ip_reg <= 0; + input_select_udp_reg <= 1'b0; + input_select_ip_reg <= 1'b0; end else begin if (ip_rx_ip_payload_tvalid) begin if ((~input_select_udp_reg & ~input_select_ip_reg) | @@ -302,8 +302,8 @@ always @(posedge clk) begin input_select_ip_reg <= input_select_ip; end end else begin - input_select_udp_reg <= 0; - input_select_ip_reg <= 0; + input_select_udp_reg <= 1'b0; + input_select_ip_reg <= 1'b0; end end end @@ -371,20 +371,20 @@ ip_arb_mux_64_2_inst ( // IP frame input from UDP module .input_0_ip_hdr_valid(udp_tx_ip_hdr_valid), .input_0_ip_hdr_ready(udp_tx_ip_hdr_ready), - .input_0_eth_dest_mac(0), - .input_0_eth_src_mac(0), - .input_0_eth_type(0), - .input_0_ip_version(0), - .input_0_ip_ihl(0), + .input_0_eth_dest_mac(48'd0), + .input_0_eth_src_mac(48'd0), + .input_0_eth_type(16'd0), + .input_0_ip_version(4'd0), + .input_0_ip_ihl(4'd0), .input_0_ip_dscp(udp_tx_ip_dscp), .input_0_ip_ecn(udp_tx_ip_ecn), .input_0_ip_length(udp_tx_ip_length), - .input_0_ip_identification(0), - .input_0_ip_flags(0), - .input_0_ip_fragment_offset(0), + .input_0_ip_identification(16'd0), + .input_0_ip_flags(3'd0), + .input_0_ip_fragment_offset(13'd0), .input_0_ip_ttl(udp_tx_ip_ttl), .input_0_ip_protocol(udp_tx_ip_protocol), - .input_0_ip_header_checksum(0), + .input_0_ip_header_checksum(16'd0), .input_0_ip_source_ip(udp_tx_ip_source_ip), .input_0_ip_dest_ip(udp_tx_ip_dest_ip), .input_0_ip_payload_tdata(udp_tx_ip_payload_tdata), @@ -396,20 +396,20 @@ ip_arb_mux_64_2_inst ( // External IP frame input .input_1_ip_hdr_valid(input_ip_hdr_valid), .input_1_ip_hdr_ready(input_ip_hdr_ready), - .input_1_eth_dest_mac(0), - .input_1_eth_src_mac(0), - .input_1_eth_type(0), - .input_1_ip_version(0), - .input_1_ip_ihl(0), + .input_1_eth_dest_mac(48'd0), + .input_1_eth_src_mac(48'd0), + .input_1_eth_type(16'd0), + .input_1_ip_version(4'd0), + .input_1_ip_ihl(4'd0), .input_1_ip_dscp(input_ip_dscp), .input_1_ip_ecn(input_ip_ecn), .input_1_ip_length(input_ip_length), - .input_1_ip_identification(0), - .input_1_ip_flags(0), - .input_1_ip_fragment_offset(0), + .input_1_ip_identification(16'd0), + .input_1_ip_flags(3'd0), + .input_1_ip_fragment_offset(13'd0), .input_1_ip_ttl(input_ip_ttl), .input_1_ip_protocol(input_ip_protocol), - .input_1_ip_header_checksum(0), + .input_1_ip_header_checksum(16'd0), .input_1_ip_source_ip(input_ip_source_ip), .input_1_ip_dest_ip(input_ip_dest_ip), .input_1_ip_payload_tdata(input_ip_payload_tdata), @@ -603,18 +603,18 @@ udp_64_inst ( // UDP frame input .input_udp_hdr_valid(input_udp_hdr_valid), .input_udp_hdr_ready(input_udp_hdr_ready), - .input_udp_eth_dest_mac(0), - .input_udp_eth_src_mac(0), - .input_udp_eth_type(0), - .input_udp_ip_version(0), - .input_udp_ip_ihl(0), + .input_udp_eth_dest_mac(48'd0), + .input_udp_eth_src_mac(48'd0), + .input_udp_eth_type(16'd0), + .input_udp_ip_version(4'd0), + .input_udp_ip_ihl(4'd0), .input_udp_ip_dscp(input_udp_ip_dscp), .input_udp_ip_ecn(input_udp_ip_ecn), - .input_udp_ip_identification(0), - .input_udp_ip_flags(0), - .input_udp_ip_fragment_offset(0), + .input_udp_ip_identification(16'd0), + .input_udp_ip_flags(3'd0), + .input_udp_ip_fragment_offset(13'd0), .input_udp_ip_ttl(input_udp_ip_ttl), - .input_udp_ip_header_checksum(0), + .input_udp_ip_header_checksum(16'd0), .input_udp_ip_source_ip(input_udp_ip_source_ip), .input_udp_ip_dest_ip(input_udp_ip_dest_ip), .input_udp_source_port(input_udp_source_port), diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py index 9adb19f02..8ee3dc0c8 100755 --- a/rtl/udp_demux.py +++ b/rtl/udp_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -144,39 +144,39 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; +reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; {% for p in ports %} -reg output_{{p}}_udp_hdr_valid_reg = 0, output_{{p}}_udp_hdr_valid_next; +reg output_{{p}}_udp_hdr_valid_reg = 1'b0, output_{{p}}_udp_hdr_valid_next; {%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; // internal datapath reg [7:0] output_udp_payload_tdata_int; reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tready_int_reg = 1'b0; reg output_udp_payload_tlast_int; reg output_udp_payload_tuser_int; wire output_udp_payload_tready_int_early; @@ -221,6 +221,12 @@ always @* begin current_output_tready = output_{{p}}_udp_payload_tready; end {%- endfor %} + default: begin + current_output_udp_hdr_valid = 1'b0; + current_output_udp_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -229,7 +235,7 @@ always @* begin frame_next = frame_reg; input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; - input_udp_payload_tready_next = 0; + input_udp_payload_tready_next = 1'b0; {%- for p in ports %} output_{{p}}_udp_hdr_valid_next = output_{{p}}_udp_hdr_valid_reg & ~output_{{p}}_udp_hdr_ready; @@ -262,14 +268,14 @@ always @* begin end end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_udp_hdr_ready_next = 1; + input_udp_hdr_ready_next = 1'b1; case (select) {%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_udp_hdr_valid_next = 1; + {{w}}'d{{p}}: output_{{p}}_udp_hdr_valid_next = 1'b1; {%- endfor %} endcase output_eth_dest_mac_next = input_eth_dest_mac; @@ -304,33 +310,13 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; + input_udp_hdr_ready_reg <= 1'b0; + input_udp_payload_tready_reg <= 1'b0; {%- for p in ports %} - output_{{p}}_udp_hdr_valid_reg <= 0; + output_{{p}}_udp_hdr_valid_reg <= 1'b0; {%- endfor %} - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - output_udp_source_port_reg <= 0; - output_udp_dest_port_reg <= 0; - output_udp_length_reg <= 0; - output_udp_checksum_reg <= 0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -339,101 +325,120 @@ always @(posedge clk) begin {%- for p in ports %} output_{{p}}_udp_hdr_valid_reg <= output_{{p}}_udp_hdr_valid_next; {%- endfor %} - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; end // output datapath logic -reg [7:0] output_udp_payload_tdata_reg = 0; +reg [7:0] output_udp_payload_tdata_reg = 8'd0; {%- for p in ports %} -reg output_{{p}}_udp_payload_tvalid_reg = 0; +reg output_{{p}}_udp_payload_tvalid_reg = 1'b0, output_{{p}}_udp_payload_tvalid_next; {%- endfor %} -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; +reg output_udp_payload_tlast_reg = 1'b0; +reg output_udp_payload_tuser_reg = 1'b0; -reg [7:0] temp_udp_payload_tdata_reg = 0; -reg temp_udp_payload_tvalid_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +reg [7:0] temp_udp_payload_tdata_reg = 8'd0; +reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; +reg temp_udp_payload_tlast_reg = 1'b0; +reg temp_udp_payload_tuser_reg = 1'b0; + +// datapath control +reg store_udp_payload_int_to_output; +reg store_udp_payload_int_to_temp; +reg store_udp_payload_temp_to_output; {% for p in ports %} assign output_{{p}}_udp_payload_tdata = output_udp_payload_tdata_reg; assign output_{{p}}_udp_payload_tvalid = output_{{p}}_udp_payload_tvalid_reg; assign output_{{p}}_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_{{p}}_udp_payload_tuser = output_udp_payload_tuser_reg; {% endfor %} -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & (~current_output_tvalid | ~output_udp_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source +{%- for p in ports %} + output_{{p}}_udp_payload_tvalid_next = output_{{p}}_udp_payload_tvalid_reg; +{%- endfor %} + temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + + store_udp_payload_int_to_output = 1'b0; + store_udp_payload_int_to_temp = 1'b0; + store_udp_payload_temp_to_output = 1'b0; + + if (output_udp_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output +{%- for p in ports %} + output_{{p}}_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + store_udp_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready +{%- for p in ports %} + output_{{p}}_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + temp_udp_payload_tvalid_next = 1'b0; + store_udp_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_udp_payload_tdata_reg <= 0; {%- for p in ports %} - output_{{p}}_udp_payload_tvalid_reg <= 0; + output_{{p}}_udp_payload_tvalid_reg <= 1'b0; {%- endfor %} - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - output_udp_payload_tready_int <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int_reg <= 1'b0; + temp_udp_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_udp_payload_tready_int <= output_udp_payload_tready_int_early; +{%- for p in ports %} + output_{{p}}_udp_payload_tvalid_reg <= output_{{p}}_udp_payload_tvalid_next; +{%- endfor %} + output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; + temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + end - if (output_udp_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; -{%- endfor %} - endcase - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; -{%- endfor %} - endcase - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; - end + // datapath + if (store_udp_payload_int_to_output) begin + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else if (store_udp_payload_temp_to_output) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (store_udp_payload_int_to_temp) begin + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; end end diff --git a/rtl/udp_demux_4.v b/rtl/udp_demux_4.v index 250e98705..1dc424652 100644 --- a/rtl/udp_demux_4.v +++ b/rtl/udp_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -187,41 +187,41 @@ module udp_demux_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; +reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; -reg output_0_udp_hdr_valid_reg = 0, output_0_udp_hdr_valid_next; -reg output_1_udp_hdr_valid_reg = 0, output_1_udp_hdr_valid_next; -reg output_2_udp_hdr_valid_reg = 0, output_2_udp_hdr_valid_next; -reg output_3_udp_hdr_valid_reg = 0, output_3_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; +reg output_0_udp_hdr_valid_reg = 1'b0, output_0_udp_hdr_valid_next; +reg output_1_udp_hdr_valid_reg = 1'b0, output_1_udp_hdr_valid_next; +reg output_2_udp_hdr_valid_reg = 1'b0, output_2_udp_hdr_valid_next; +reg output_3_udp_hdr_valid_reg = 1'b0, output_3_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; // internal datapath reg [7:0] output_udp_payload_tdata_int; reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tready_int_reg = 1'b0; reg output_udp_payload_tlast_int; reg output_udp_payload_tuser_int; wire output_udp_payload_tready_int_early; @@ -348,6 +348,12 @@ always @* begin current_output_tvalid = output_3_udp_payload_tvalid; current_output_tready = output_3_udp_payload_tready; end + default: begin + current_output_udp_hdr_valid = 1'b0; + current_output_udp_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -356,7 +362,7 @@ always @* begin frame_next = frame_reg; input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; - input_udp_payload_tready_next = 0; + input_udp_payload_tready_next = 1'b0; output_0_udp_hdr_valid_next = output_0_udp_hdr_valid_reg & ~output_0_udp_hdr_ready; output_1_udp_hdr_valid_next = output_1_udp_hdr_valid_reg & ~output_1_udp_hdr_ready; output_2_udp_hdr_valid_next = output_2_udp_hdr_valid_reg & ~output_2_udp_hdr_ready; @@ -389,16 +395,16 @@ always @* begin end end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_udp_hdr_ready_next = 1; + input_udp_hdr_ready_next = 1'b1; case (select) - 2'd0: output_0_udp_hdr_valid_next = 1; - 2'd1: output_1_udp_hdr_valid_next = 1; - 2'd2: output_2_udp_hdr_valid_next = 1; - 2'd3: output_3_udp_hdr_valid_next = 1; + 2'd0: output_0_udp_hdr_valid_next = 1'b1; + 2'd1: output_1_udp_hdr_valid_next = 1'b1; + 2'd2: output_2_udp_hdr_valid_next = 1'b1; + 2'd3: output_3_udp_hdr_valid_next = 1'b1; endcase output_eth_dest_mac_next = input_eth_dest_mac; output_eth_src_mac_next = input_eth_src_mac; @@ -432,34 +438,14 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; - output_0_udp_hdr_valid_reg <= 0; - output_1_udp_hdr_valid_reg <= 0; - output_2_udp_hdr_valid_reg <= 0; - output_3_udp_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - output_udp_source_port_reg <= 0; - output_udp_dest_port_reg <= 0; - output_udp_length_reg <= 0; - output_udp_checksum_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_udp_hdr_ready_reg <= 1'b0; + input_udp_payload_tready_reg <= 1'b0; + output_0_udp_hdr_valid_reg <= 1'b0; + output_1_udp_hdr_valid_reg <= 1'b0; + output_2_udp_hdr_valid_reg <= 1'b0; + output_3_udp_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -469,42 +455,48 @@ always @(posedge clk) begin output_1_udp_hdr_valid_reg <= output_1_udp_hdr_valid_next; output_2_udp_hdr_valid_reg <= output_2_udp_hdr_valid_next; output_3_udp_hdr_valid_reg <= output_3_udp_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; end // output datapath logic -reg [7:0] output_udp_payload_tdata_reg = 0; -reg output_0_udp_payload_tvalid_reg = 0; -reg output_1_udp_payload_tvalid_reg = 0; -reg output_2_udp_payload_tvalid_reg = 0; -reg output_3_udp_payload_tvalid_reg = 0; -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; +reg [7:0] output_udp_payload_tdata_reg = 8'd0; +reg output_0_udp_payload_tvalid_reg = 1'b0, output_0_udp_payload_tvalid_next; +reg output_1_udp_payload_tvalid_reg = 1'b0, output_1_udp_payload_tvalid_next; +reg output_2_udp_payload_tvalid_reg = 1'b0, output_2_udp_payload_tvalid_next; +reg output_3_udp_payload_tvalid_reg = 1'b0, output_3_udp_payload_tvalid_next; +reg output_udp_payload_tlast_reg = 1'b0; +reg output_udp_payload_tuser_reg = 1'b0; -reg [7:0] temp_udp_payload_tdata_reg = 0; -reg temp_udp_payload_tvalid_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +reg [7:0] temp_udp_payload_tdata_reg = 8'd0; +reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; +reg temp_udp_payload_tlast_reg = 1'b0; +reg temp_udp_payload_tuser_reg = 1'b0; + +// datapath control +reg store_udp_payload_int_to_output; +reg store_udp_payload_int_to_temp; +reg store_udp_payload_temp_to_output; assign output_0_udp_payload_tdata = output_udp_payload_tdata_reg; assign output_0_udp_payload_tvalid = output_0_udp_payload_tvalid_reg; @@ -526,63 +518,78 @@ assign output_3_udp_payload_tvalid = output_3_udp_payload_tvalid_reg; assign output_3_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_3_udp_payload_tuser = output_udp_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & (~current_output_tvalid | ~output_udp_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_0_udp_payload_tvalid_next = output_0_udp_payload_tvalid_reg; + output_1_udp_payload_tvalid_next = output_1_udp_payload_tvalid_reg; + output_2_udp_payload_tvalid_next = output_2_udp_payload_tvalid_reg; + output_3_udp_payload_tvalid_next = output_3_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + + store_udp_payload_int_to_output = 1'b0; + store_udp_payload_int_to_temp = 1'b0; + store_udp_payload_temp_to_output = 1'b0; + + if (output_udp_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_0_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd0); + output_1_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd1); + output_2_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd2); + output_3_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd3); + store_udp_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_0_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd0); + output_1_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd1); + output_2_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd2); + output_3_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd3); + temp_udp_payload_tvalid_next = 1'b0; + store_udp_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_udp_payload_tdata_reg <= 0; - output_0_udp_payload_tvalid_reg <= 0; - output_1_udp_payload_tvalid_reg <= 0; - output_2_udp_payload_tvalid_reg <= 0; - output_3_udp_payload_tvalid_reg <= 0; - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - output_udp_payload_tready_int <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; + output_0_udp_payload_tvalid_reg <= 1'b0; + output_1_udp_payload_tvalid_reg <= 1'b0; + output_2_udp_payload_tvalid_reg <= 1'b0; + output_3_udp_payload_tvalid_reg <= 1'b0; + output_udp_payload_tready_int_reg <= 1'b0; + temp_udp_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + output_0_udp_payload_tvalid_reg <= output_0_udp_payload_tvalid_next; + output_1_udp_payload_tvalid_reg <= output_1_udp_payload_tvalid_next; + output_2_udp_payload_tvalid_reg <= output_2_udp_payload_tvalid_next; + output_3_udp_payload_tvalid_reg <= output_3_udp_payload_tvalid_next; + output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; + temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + end - if (output_udp_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - case (select_reg) - 2'd0: output_0_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - 2'd1: output_1_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - 2'd2: output_2_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - 2'd3: output_3_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - endcase - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - case (select_reg) - 2'd0: output_0_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - 2'd1: output_1_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - 2'd2: output_2_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - 2'd3: output_3_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - endcase - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; - end + // datapath + if (store_udp_payload_int_to_output) begin + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else if (store_udp_payload_temp_to_output) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (store_udp_payload_int_to_temp) begin + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; end end diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py index ba54d24c4..afde8173f 100755 --- a/rtl/udp_demux_64.py +++ b/rtl/udp_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -146,40 +146,40 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; +reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; {% for p in ports %} -reg output_{{p}}_udp_hdr_valid_reg = 0, output_{{p}}_udp_hdr_valid_next; +reg output_{{p}}_udp_hdr_valid_reg = 1'b0, output_{{p}}_udp_hdr_valid_next; {%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; // internal datapath reg [63:0] output_udp_payload_tdata_int; reg [7:0] output_udp_payload_tkeep_int; reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tready_int_reg = 1'b0; reg output_udp_payload_tlast_int; reg output_udp_payload_tuser_int; wire output_udp_payload_tready_int_early; @@ -224,6 +224,12 @@ always @* begin current_output_tready = output_{{p}}_udp_payload_tready; end {%- endfor %} + default: begin + current_output_udp_hdr_valid = 1'b0; + current_output_udp_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -232,7 +238,7 @@ always @* begin frame_next = frame_reg; input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; - input_udp_payload_tready_next = 0; + input_udp_payload_tready_next = 1'b0; {%- for p in ports %} output_{{p}}_udp_hdr_valid_next = output_{{p}}_udp_hdr_valid_reg & ~output_{{p}}_udp_hdr_ready; @@ -265,14 +271,14 @@ always @* begin end end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_udp_hdr_ready_next = 1; + input_udp_hdr_ready_next = 1'b1; case (select) {%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_udp_hdr_valid_next = 1; + {{w}}'d{{p}}: output_{{p}}_udp_hdr_valid_next = 1'b1; {%- endfor %} endcase output_eth_dest_mac_next = input_eth_dest_mac; @@ -308,33 +314,13 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; + input_udp_hdr_ready_reg <= 1'b0; + input_udp_payload_tready_reg <= 1'b0; {%- for p in ports %} - output_{{p}}_udp_hdr_valid_reg <= 0; + output_{{p}}_udp_hdr_valid_reg <= 1'b0; {%- endfor %} - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - output_udp_source_port_reg <= 0; - output_udp_dest_port_reg <= 0; - output_udp_length_reg <= 0; - output_udp_checksum_reg <= 0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -343,43 +329,49 @@ always @(posedge clk) begin {%- for p in ports %} output_{{p}}_udp_hdr_valid_reg <= output_{{p}}_udp_hdr_valid_next; {%- endfor %} - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; end // output datapath logic -reg [63:0] output_udp_payload_tdata_reg = 0; -reg [7:0] output_udp_payload_tkeep_reg = 0; +reg [63:0] output_udp_payload_tdata_reg = 64'd0; +reg [7:0] output_udp_payload_tkeep_reg = 8'd0; {%- for p in ports %} -reg output_{{p}}_udp_payload_tvalid_reg = 0; +reg output_{{p}}_udp_payload_tvalid_reg = 1'b0, output_{{p}}_udp_payload_tvalid_next; {%- endfor %} -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; +reg output_udp_payload_tlast_reg = 1'b0; +reg output_udp_payload_tuser_reg = 1'b0; -reg [63:0] temp_udp_payload_tdata_reg = 0; -reg [7:0] temp_udp_payload_tkeep_reg = 0; -reg temp_udp_payload_tvalid_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +reg [63:0] temp_udp_payload_tdata_reg = 64'd0; +reg [7:0] temp_udp_payload_tkeep_reg = 8'd0; +reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; +reg temp_udp_payload_tlast_reg = 1'b0; +reg temp_udp_payload_tuser_reg = 1'b0; + +// datapath control +reg store_udp_payload_int_to_output; +reg store_udp_payload_int_to_temp; +reg store_udp_payload_temp_to_output; {% for p in ports %} assign output_{{p}}_udp_payload_tdata = output_udp_payload_tdata_reg; assign output_{{p}}_udp_payload_tkeep = output_udp_payload_tkeep_reg; @@ -387,66 +379,76 @@ assign output_{{p}}_udp_payload_tvalid = output_{{p}}_udp_payload_tvalid_reg; assign output_{{p}}_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_{{p}}_udp_payload_tuser = output_udp_payload_tuser_reg; {% endfor %} -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & (~current_output_tvalid | ~output_udp_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source +{%- for p in ports %} + output_{{p}}_udp_payload_tvalid_next = output_{{p}}_udp_payload_tvalid_reg; +{%- endfor %} + temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + + store_udp_payload_int_to_output = 1'b0; + store_udp_payload_int_to_temp = 1'b0; + store_udp_payload_temp_to_output = 1'b0; + + if (output_udp_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output +{%- for p in ports %} + output_{{p}}_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + store_udp_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready +{%- for p in ports %} + output_{{p}}_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); +{%- endfor %} + temp_udp_payload_tvalid_next = 1'b0; + store_udp_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_udp_payload_tdata_reg <= 0; - output_udp_payload_tkeep_reg <= 0; {%- for p in ports %} - output_{{p}}_udp_payload_tvalid_reg <= 0; + output_{{p}}_udp_payload_tvalid_reg <= 1'b0; {%- endfor %} - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - output_udp_payload_tready_int <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; + output_udp_payload_tready_int_reg <= 1'b0; + temp_udp_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_udp_payload_tready_int <= output_udp_payload_tready_int_early; +{%- for p in ports %} + output_{{p}}_udp_payload_tvalid_reg <= output_{{p}}_udp_payload_tvalid_next; +{%- endfor %} + output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; + temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + end - if (output_udp_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; -{%- endfor %} - endcase - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; -{%- endfor %} - endcase - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; - end + // datapath + if (store_udp_payload_int_to_output) begin + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else if (store_udp_payload_temp_to_output) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (store_udp_payload_int_to_temp) begin + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; end end diff --git a/rtl/udp_demux_64_4.v b/rtl/udp_demux_64_4.v index 4d3e20f5d..f596eb502 100644 --- a/rtl/udp_demux_64_4.v +++ b/rtl/udp_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -192,42 +192,42 @@ module udp_demux_64_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; +reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; -reg output_0_udp_hdr_valid_reg = 0, output_0_udp_hdr_valid_next; -reg output_1_udp_hdr_valid_reg = 0, output_1_udp_hdr_valid_next; -reg output_2_udp_hdr_valid_reg = 0, output_2_udp_hdr_valid_next; -reg output_3_udp_hdr_valid_reg = 0, output_3_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; +reg output_0_udp_hdr_valid_reg = 1'b0, output_0_udp_hdr_valid_next; +reg output_1_udp_hdr_valid_reg = 1'b0, output_1_udp_hdr_valid_next; +reg output_2_udp_hdr_valid_reg = 1'b0, output_2_udp_hdr_valid_next; +reg output_3_udp_hdr_valid_reg = 1'b0, output_3_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; // internal datapath reg [63:0] output_udp_payload_tdata_int; reg [7:0] output_udp_payload_tkeep_int; reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tready_int_reg = 1'b0; reg output_udp_payload_tlast_int; reg output_udp_payload_tuser_int; wire output_udp_payload_tready_int_early; @@ -354,6 +354,12 @@ always @* begin current_output_tvalid = output_3_udp_payload_tvalid; current_output_tready = output_3_udp_payload_tready; end + default: begin + current_output_udp_hdr_valid = 1'b0; + current_output_udp_hdr_ready = 1'b0; + current_output_tvalid = 1'b0; + current_output_tready = 1'b0; + end endcase end @@ -362,7 +368,7 @@ always @* begin frame_next = frame_reg; input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; - input_udp_payload_tready_next = 0; + input_udp_payload_tready_next = 1'b0; output_0_udp_hdr_valid_next = output_0_udp_hdr_valid_reg & ~output_0_udp_hdr_ready; output_1_udp_hdr_valid_next = output_1_udp_hdr_valid_reg & ~output_1_udp_hdr_ready; output_2_udp_hdr_valid_next = output_2_udp_hdr_valid_reg & ~output_2_udp_hdr_ready; @@ -395,16 +401,16 @@ always @* begin end end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; - input_udp_hdr_ready_next = 1; + input_udp_hdr_ready_next = 1'b1; case (select) - 2'd0: output_0_udp_hdr_valid_next = 1; - 2'd1: output_1_udp_hdr_valid_next = 1; - 2'd2: output_2_udp_hdr_valid_next = 1; - 2'd3: output_3_udp_hdr_valid_next = 1; + 2'd0: output_0_udp_hdr_valid_next = 1'b1; + 2'd1: output_1_udp_hdr_valid_next = 1'b1; + 2'd2: output_2_udp_hdr_valid_next = 1'b1; + 2'd3: output_3_udp_hdr_valid_next = 1'b1; endcase output_eth_dest_mac_next = input_eth_dest_mac; output_eth_src_mac_next = input_eth_src_mac; @@ -439,34 +445,14 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; - output_0_udp_hdr_valid_reg <= 0; - output_1_udp_hdr_valid_reg <= 0; - output_2_udp_hdr_valid_reg <= 0; - output_3_udp_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - output_udp_source_port_reg <= 0; - output_udp_dest_port_reg <= 0; - output_udp_length_reg <= 0; - output_udp_checksum_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_udp_hdr_ready_reg <= 1'b0; + input_udp_payload_tready_reg <= 1'b0; + output_0_udp_hdr_valid_reg <= 1'b0; + output_1_udp_hdr_valid_reg <= 1'b0; + output_2_udp_hdr_valid_reg <= 1'b0; + output_3_udp_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -476,44 +462,50 @@ always @(posedge clk) begin output_1_udp_hdr_valid_reg <= output_1_udp_hdr_valid_next; output_2_udp_hdr_valid_reg <= output_2_udp_hdr_valid_next; output_3_udp_hdr_valid_reg <= output_3_udp_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; end // output datapath logic -reg [63:0] output_udp_payload_tdata_reg = 0; -reg [7:0] output_udp_payload_tkeep_reg = 0; -reg output_0_udp_payload_tvalid_reg = 0; -reg output_1_udp_payload_tvalid_reg = 0; -reg output_2_udp_payload_tvalid_reg = 0; -reg output_3_udp_payload_tvalid_reg = 0; -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; +reg [63:0] output_udp_payload_tdata_reg = 64'd0; +reg [7:0] output_udp_payload_tkeep_reg = 8'd0; +reg output_0_udp_payload_tvalid_reg = 1'b0, output_0_udp_payload_tvalid_next; +reg output_1_udp_payload_tvalid_reg = 1'b0, output_1_udp_payload_tvalid_next; +reg output_2_udp_payload_tvalid_reg = 1'b0, output_2_udp_payload_tvalid_next; +reg output_3_udp_payload_tvalid_reg = 1'b0, output_3_udp_payload_tvalid_next; +reg output_udp_payload_tlast_reg = 1'b0; +reg output_udp_payload_tuser_reg = 1'b0; -reg [63:0] temp_udp_payload_tdata_reg = 0; -reg [7:0] temp_udp_payload_tkeep_reg = 0; -reg temp_udp_payload_tvalid_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +reg [63:0] temp_udp_payload_tdata_reg = 64'd0; +reg [7:0] temp_udp_payload_tkeep_reg = 8'd0; +reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; +reg temp_udp_payload_tlast_reg = 1'b0; +reg temp_udp_payload_tuser_reg = 1'b0; + +// datapath control +reg store_udp_payload_int_to_output; +reg store_udp_payload_int_to_temp; +reg store_udp_payload_temp_to_output; assign output_0_udp_payload_tdata = output_udp_payload_tdata_reg; assign output_0_udp_payload_tkeep = output_udp_payload_tkeep_reg; @@ -539,69 +531,81 @@ assign output_3_udp_payload_tvalid = output_3_udp_payload_tvalid_reg; assign output_3_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_3_udp_payload_tuser = output_udp_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & ~current_output_tvalid) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & (~current_output_tvalid | ~output_udp_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_0_udp_payload_tvalid_next = output_0_udp_payload_tvalid_reg; + output_1_udp_payload_tvalid_next = output_1_udp_payload_tvalid_reg; + output_2_udp_payload_tvalid_next = output_2_udp_payload_tvalid_reg; + output_3_udp_payload_tvalid_next = output_3_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + + store_udp_payload_int_to_output = 1'b0; + store_udp_payload_int_to_temp = 1'b0; + store_udp_payload_temp_to_output = 1'b0; + + if (output_udp_payload_tready_int_reg) begin + // input is ready + if (current_output_tready | ~current_output_tvalid) begin + // output is ready or currently not valid, transfer data to output + output_0_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd0); + output_1_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd1); + output_2_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd2); + output_3_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd3); + store_udp_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_temp = 1'b1; + end + end else if (current_output_tready) begin + // input is not ready, but output is ready + output_0_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd0); + output_1_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd1); + output_2_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd2); + output_3_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd3); + temp_udp_payload_tvalid_next = 1'b0; + store_udp_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_udp_payload_tdata_reg <= 0; - output_udp_payload_tkeep_reg <= 0; - output_0_udp_payload_tvalid_reg <= 0; - output_1_udp_payload_tvalid_reg <= 0; - output_2_udp_payload_tvalid_reg <= 0; - output_3_udp_payload_tvalid_reg <= 0; - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - output_udp_payload_tready_int <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; + output_0_udp_payload_tvalid_reg <= 1'b0; + output_1_udp_payload_tvalid_reg <= 1'b0; + output_2_udp_payload_tvalid_reg <= 1'b0; + output_3_udp_payload_tvalid_reg <= 1'b0; + output_udp_payload_tready_int_reg <= 1'b0; + temp_udp_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + output_0_udp_payload_tvalid_reg <= output_0_udp_payload_tvalid_next; + output_1_udp_payload_tvalid_reg <= output_1_udp_payload_tvalid_next; + output_2_udp_payload_tvalid_reg <= output_2_udp_payload_tvalid_next; + output_3_udp_payload_tvalid_reg <= output_3_udp_payload_tvalid_next; + output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; + temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + end - if (output_udp_payload_tready_int) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - case (select_reg) - 2'd0: output_0_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - 2'd1: output_1_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - 2'd2: output_2_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - 2'd3: output_3_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - endcase - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; - case (select_reg) - 2'd0: output_0_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - 2'd1: output_1_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - 2'd2: output_2_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - 2'd3: output_3_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - endcase - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; - end + // datapath + if (store_udp_payload_int_to_output) begin + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else if (store_udp_payload_temp_to_output) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (store_udp_payload_int_to_temp) begin + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; end end diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v index 52d7735a8..5820a0e7f 100644 --- a/rtl/udp_ip_rx.v +++ b/rtl/udp_ip_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -158,46 +158,46 @@ reg store_udp_checksum_0; reg store_udp_checksum_1; reg store_last_word; -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg [7:0] last_word_data_reg = 0; +reg [7:0] last_word_data_reg = 8'd0; -reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; -reg [3:0] output_ip_version_reg = 0; -reg [3:0] output_ip_ihl_reg = 0; -reg [5:0] output_ip_dscp_reg = 0; -reg [1:0] output_ip_ecn_reg = 0; -reg [15:0] output_ip_length_reg = 0; -reg [15:0] output_ip_identification_reg = 0; -reg [2:0] output_ip_flags_reg = 0; -reg [12:0] output_ip_fragment_offset_reg = 0; -reg [7:0] output_ip_ttl_reg = 0; -reg [7:0] output_ip_protocol_reg = 0; -reg [15:0] output_ip_header_checksum_reg = 0; -reg [31:0] output_ip_source_ip_reg = 0; -reg [31:0] output_ip_dest_ip_reg = 0; -reg [15:0] output_udp_source_port_reg = 0; -reg [15:0] output_udp_dest_port_reg = 0; -reg [15:0] output_udp_length_reg = 0; -reg [15:0] output_udp_checksum_reg = 0; +reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; +reg [3:0] output_ip_version_reg = 4'd0; +reg [3:0] output_ip_ihl_reg = 4'd0; +reg [5:0] output_ip_dscp_reg = 6'd0; +reg [1:0] output_ip_ecn_reg = 2'd0; +reg [15:0] output_ip_length_reg = 16'd0; +reg [15:0] output_ip_identification_reg = 16'd0; +reg [2:0] output_ip_flags_reg = 3'd0; +reg [12:0] output_ip_fragment_offset_reg = 13'd0; +reg [7:0] output_ip_ttl_reg = 8'd0; +reg [7:0] output_ip_protocol_reg = 8'd0; +reg [15:0] output_ip_header_checksum_reg = 16'd0; +reg [31:0] output_ip_source_ip_reg = 32'd0; +reg [31:0] output_ip_dest_ip_reg = 32'd0; +reg [15:0] output_udp_source_port_reg = 16'd0; +reg [15:0] output_udp_dest_port_reg = 16'd0; +reg [15:0] output_udp_length_reg = 16'd0; +reg [15:0] output_udp_checksum_reg = 16'd0; -reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; +reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; -reg busy_reg = 0; -reg error_header_early_termination_reg = 0, error_header_early_termination_next; -reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; +reg busy_reg = 1'b0; +reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; +reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; // internal datapath -reg [7:0] output_udp_payload_tdata_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int = 0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; +reg [7:0] output_udp_payload_tdata_int; +reg output_udp_payload_tvalid_int; +reg output_udp_payload_tready_int_reg = 1'b0; +reg output_udp_payload_tlast_int; +reg output_udp_payload_tuser_int; +wire output_udp_payload_tready_int_early; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = input_ip_payload_tready_reg; @@ -231,43 +231,43 @@ assign error_payload_early_termination = error_payload_early_termination_reg; always @* begin state_next = STATE_IDLE; - input_ip_hdr_ready_next = 0; - input_ip_payload_tready_next = 0; + input_ip_hdr_ready_next = 1'b0; + input_ip_payload_tready_next = 1'b0; - store_ip_hdr = 0; - store_udp_source_port_0 = 0; - store_udp_source_port_1 = 0; - store_udp_dest_port_0 = 0; - store_udp_dest_port_1 = 0; - store_udp_length_0 = 0; - store_udp_length_1 = 0; - store_udp_checksum_0 = 0; - store_udp_checksum_1 = 0; + store_ip_hdr = 1'b0; + store_udp_source_port_0 = 1'b0; + store_udp_source_port_1 = 1'b0; + store_udp_dest_port_0 = 1'b0; + store_udp_dest_port_1 = 1'b0; + store_udp_length_0 = 1'b0; + store_udp_length_1 = 1'b0; + store_udp_checksum_0 = 1'b0; + store_udp_checksum_1 = 1'b0; - store_last_word = 0; + store_last_word = 1'b0; frame_ptr_next = frame_ptr_reg; output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; - error_header_early_termination_next = 0; - error_payload_early_termination_next = 0; + error_header_early_termination_next = 1'b0; + error_payload_early_termination_next = 1'b0; - output_udp_payload_tdata_int = 0; - output_udp_payload_tvalid_int = 0; - output_udp_payload_tlast_int = 0; - output_udp_payload_tuser_int = 0; + output_udp_payload_tdata_int = 8'd0; + output_udp_payload_tvalid_int = 1'b0; + output_udp_payload_tlast_int = 1'b0; + output_udp_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for header - frame_ptr_next = 0; + frame_ptr_next = 16'd0; input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; if (input_ip_hdr_ready & input_ip_hdr_valid) begin - input_ip_hdr_ready_next = 0; - input_ip_payload_tready_next = 1; - store_ip_hdr = 1; + input_ip_hdr_ready_next = 1'b0; + input_ip_payload_tready_next = 1'b1; + store_ip_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin state_next = STATE_IDLE; @@ -275,34 +275,34 @@ always @* begin end STATE_READ_HEADER: begin // read header state - input_ip_payload_tready_next = 1; + input_ip_payload_tready_next = 1'b1; if (input_ip_payload_tready & input_ip_payload_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg+1; + frame_ptr_next = frame_ptr_reg + 16'd1; state_next = STATE_READ_HEADER; case (frame_ptr_reg) - 8'h00: store_udp_source_port_1 = 1; - 8'h01: store_udp_source_port_0 = 1; - 8'h02: store_udp_dest_port_1 = 1; - 8'h03: store_udp_dest_port_0 = 1; - 8'h04: store_udp_length_1 = 1; - 8'h05: store_udp_length_0 = 1; - 8'h06: store_udp_checksum_1 = 1; + 8'h00: store_udp_source_port_1 = 1'b1; + 8'h01: store_udp_source_port_0 = 1'b1; + 8'h02: store_udp_dest_port_1 = 1'b1; + 8'h03: store_udp_dest_port_0 = 1'b1; + 8'h04: store_udp_length_1 = 1'b1; + 8'h05: store_udp_length_0 = 1'b1; + 8'h06: store_udp_checksum_1 = 1'b1; 8'h07: begin - store_udp_checksum_0 = 1; - output_udp_hdr_valid_next = 1; + store_udp_checksum_0 = 1'b1; + output_udp_hdr_valid_next = 1'b1; input_ip_payload_tready_next = output_udp_payload_tready_int_early; state_next = STATE_READ_PAYLOAD; end endcase if (input_ip_payload_tlast) begin - error_header_early_termination_next = 1; - output_udp_hdr_valid_next = 0; + error_header_early_termination_next = 1'b1; + output_udp_hdr_valid_next = 1'b0; input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -321,20 +321,20 @@ always @* begin if (input_ip_payload_tready & input_ip_payload_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+1; + frame_ptr_next = frame_ptr_reg + 16'd1; if (input_ip_payload_tlast) begin if (frame_ptr_next != output_udp_length_reg) begin // end of frame, but length does not match - output_udp_payload_tuser_int = 1; - error_payload_early_termination_next = 1; + output_udp_payload_tuser_int = 1'b1; + error_payload_early_termination_next = 1'b1; end input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin if (frame_ptr_next == output_udp_length_reg) begin - store_last_word = 1; - output_udp_payload_tvalid_int = 0; + store_last_word = 1'b1; + output_udp_payload_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; end else begin state_next = STATE_READ_PAYLOAD; @@ -356,7 +356,7 @@ always @* begin if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD_LAST; @@ -367,12 +367,12 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_ip_payload_tready_next = 1; + input_ip_payload_tready_next = 1'b1; if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -387,34 +387,13 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - last_word_data_reg <= 0; - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_udp_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - output_udp_source_port_reg <= 0; - output_udp_dest_port_reg <= 0; - output_udp_length_reg <= 0; - output_udp_checksum_reg <= 0; - busy_reg <= 0; - error_header_early_termination_reg <= 0; - error_payload_early_termination_reg <= 0; + frame_ptr_reg <= 16'd0; + input_ip_hdr_ready_reg <= 1'b0; + input_ip_payload_tready_reg <= 1'b0; + output_udp_hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; + error_header_early_termination_reg <= 1'b0; + error_payload_early_termination_reg <= 1'b0; end else begin state_reg <= state_next; @@ -429,102 +408,120 @@ always @(posedge clk) begin error_payload_early_termination_reg <= error_payload_early_termination_next; busy_reg <= state_next != STATE_IDLE; - - // datapath - if (store_ip_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - output_ip_version_reg <= input_ip_version; - output_ip_ihl_reg <= input_ip_ihl; - output_ip_dscp_reg <= input_ip_dscp; - output_ip_ecn_reg <= input_ip_ecn; - output_ip_length_reg <= input_ip_length; - output_ip_identification_reg <= input_ip_identification; - output_ip_flags_reg <= input_ip_flags; - output_ip_fragment_offset_reg <= input_ip_fragment_offset; - output_ip_ttl_reg <= input_ip_ttl; - output_ip_protocol_reg <= input_ip_protocol; - output_ip_header_checksum_reg <= input_ip_header_checksum; - output_ip_source_ip_reg <= input_ip_source_ip; - output_ip_dest_ip_reg <= input_ip_dest_ip; - end - - if (store_last_word) begin - last_word_data_reg <= output_udp_payload_tdata_int; - end - - if (store_udp_source_port_0) output_udp_source_port_reg[ 7: 0] <= input_ip_payload_tdata; - if (store_udp_source_port_1) output_udp_source_port_reg[15: 8] <= input_ip_payload_tdata; - if (store_udp_dest_port_0) output_udp_dest_port_reg[ 7: 0] <= input_ip_payload_tdata; - if (store_udp_dest_port_1) output_udp_dest_port_reg[15: 8] <= input_ip_payload_tdata; - if (store_udp_length_0) output_udp_length_reg[ 7: 0] <= input_ip_payload_tdata; - if (store_udp_length_1) output_udp_length_reg[15: 8] <= input_ip_payload_tdata; - if (store_udp_checksum_0) output_udp_checksum_reg[ 7: 0] <= input_ip_payload_tdata; - if (store_udp_checksum_1) output_udp_checksum_reg[15: 8] <= input_ip_payload_tdata; end + + // datapath + if (store_ip_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + output_ip_version_reg <= input_ip_version; + output_ip_ihl_reg <= input_ip_ihl; + output_ip_dscp_reg <= input_ip_dscp; + output_ip_ecn_reg <= input_ip_ecn; + output_ip_length_reg <= input_ip_length; + output_ip_identification_reg <= input_ip_identification; + output_ip_flags_reg <= input_ip_flags; + output_ip_fragment_offset_reg <= input_ip_fragment_offset; + output_ip_ttl_reg <= input_ip_ttl; + output_ip_protocol_reg <= input_ip_protocol; + output_ip_header_checksum_reg <= input_ip_header_checksum; + output_ip_source_ip_reg <= input_ip_source_ip; + output_ip_dest_ip_reg <= input_ip_dest_ip; + end + + if (store_last_word) begin + last_word_data_reg <= output_udp_payload_tdata_int; + end + + if (store_udp_source_port_0) output_udp_source_port_reg[ 7: 0] <= input_ip_payload_tdata; + if (store_udp_source_port_1) output_udp_source_port_reg[15: 8] <= input_ip_payload_tdata; + if (store_udp_dest_port_0) output_udp_dest_port_reg[ 7: 0] <= input_ip_payload_tdata; + if (store_udp_dest_port_1) output_udp_dest_port_reg[15: 8] <= input_ip_payload_tdata; + if (store_udp_length_0) output_udp_length_reg[ 7: 0] <= input_ip_payload_tdata; + if (store_udp_length_1) output_udp_length_reg[15: 8] <= input_ip_payload_tdata; + if (store_udp_checksum_0) output_udp_checksum_reg[ 7: 0] <= input_ip_payload_tdata; + if (store_udp_checksum_1) output_udp_checksum_reg[15: 8] <= input_ip_payload_tdata; end // output datapath logic -reg [7:0] output_udp_payload_tdata_reg = 0; -reg output_udp_payload_tvalid_reg = 0; -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; +reg [7:0] output_udp_payload_tdata_reg = 8'd0; +reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; +reg output_udp_payload_tlast_reg = 1'b0; +reg output_udp_payload_tuser_reg = 1'b0; -reg [7:0] temp_udp_payload_tdata_reg = 0; -reg temp_udp_payload_tvalid_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +reg [7:0] temp_udp_payload_tdata_reg = 8'd0; +reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; +reg temp_udp_payload_tlast_reg = 1'b0; +reg temp_udp_payload_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); +// datapath control +reg store_udp_payload_int_to_output; +reg store_udp_payload_int_to_temp; +reg store_udp_payload_temp_to_output; assign output_udp_payload_tdata = output_udp_payload_tdata_reg; assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; assign output_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_udp_payload_tuser = output_udp_payload_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + + store_udp_payload_int_to_output = 1'b0; + store_udp_payload_int_to_temp = 1'b0; + store_udp_payload_temp_to_output = 1'b0; + + if (output_udp_payload_tready_int_reg) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_temp = 1'b1; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready + output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = 1'b0; + store_udp_payload_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_udp_payload_tdata_reg <= 0; - output_udp_payload_tvalid_reg <= 0; - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - output_udp_payload_tready_int <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; + output_udp_payload_tvalid_reg <= 1'b0; + output_udp_payload_tready_int_reg <= 1'b0; + temp_udp_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; + output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; + temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + end - if (output_udp_payload_tready_int) begin - // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end - end else if (output_udp_payload_tready) begin - // input is not ready, but output is ready - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; - end + // datapath + if (store_udp_payload_int_to_output) begin + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else if (store_udp_payload_temp_to_output) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (store_udp_payload_int_to_temp) begin + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; end end diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index 541135ee4..873a488ca 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -153,45 +153,45 @@ reg store_ip_hdr; reg store_hdr_word_0; reg store_last_word; -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg [63:0] last_word_data_reg = 0; -reg [7:0] last_word_keep_reg = 0; +reg [63:0] last_word_data_reg = 64'd0; +reg [7:0] last_word_keep_reg = 8'd0; -reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; -reg [3:0] output_ip_version_reg = 0; -reg [3:0] output_ip_ihl_reg = 0; -reg [5:0] output_ip_dscp_reg = 0; -reg [1:0] output_ip_ecn_reg = 0; -reg [15:0] output_ip_length_reg = 0; -reg [15:0] output_ip_identification_reg = 0; -reg [2:0] output_ip_flags_reg = 0; -reg [12:0] output_ip_fragment_offset_reg = 0; -reg [7:0] output_ip_ttl_reg = 0; -reg [7:0] output_ip_protocol_reg = 0; -reg [15:0] output_ip_header_checksum_reg = 0; -reg [31:0] output_ip_source_ip_reg = 0; -reg [31:0] output_ip_dest_ip_reg = 0; -reg [15:0] output_udp_source_port_reg = 0; -reg [15:0] output_udp_dest_port_reg = 0; -reg [15:0] output_udp_length_reg = 0; -reg [15:0] output_udp_checksum_reg = 0; +reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; +reg [3:0] output_ip_version_reg = 4'd0; +reg [3:0] output_ip_ihl_reg = 4'd0; +reg [5:0] output_ip_dscp_reg = 6'd0; +reg [1:0] output_ip_ecn_reg = 2'd0; +reg [15:0] output_ip_length_reg = 16'd0; +reg [15:0] output_ip_identification_reg = 16'd0; +reg [2:0] output_ip_flags_reg = 3'd0; +reg [12:0] output_ip_fragment_offset_reg = 13'd0; +reg [7:0] output_ip_ttl_reg = 8'd0; +reg [7:0] output_ip_protocol_reg = 8'd0; +reg [15:0] output_ip_header_checksum_reg = 16'd0; +reg [31:0] output_ip_source_ip_reg = 32'd0; +reg [31:0] output_ip_dest_ip_reg = 32'd0; +reg [15:0] output_udp_source_port_reg = 16'd0; +reg [15:0] output_udp_dest_port_reg = 16'd0; +reg [15:0] output_udp_length_reg = 16'd0; +reg [15:0] output_udp_checksum_reg = 16'd0; -reg input_ip_hdr_ready_reg = 0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 0, input_ip_payload_tready_next; +reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; +reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; -reg busy_reg = 0; -reg error_header_early_termination_reg = 0, error_header_early_termination_next; -reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; +reg busy_reg = 1'b0; +reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; +reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; // internal datapath reg [63:0] output_udp_payload_tdata_int; reg [7:0] output_udp_payload_tkeep_int; reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tready_int_reg = 1'b0; reg output_udp_payload_tlast_int; reg output_udp_payload_tuser_int; wire output_udp_payload_tready_int_early; @@ -228,15 +228,15 @@ assign error_payload_early_termination = error_payload_early_termination_reg; function [3:0] keep2count; input [7:0] k; case (k) - 8'b00000000: keep2count = 0; - 8'b00000001: keep2count = 1; - 8'b00000011: keep2count = 2; - 8'b00000111: keep2count = 3; - 8'b00001111: keep2count = 4; - 8'b00011111: keep2count = 5; - 8'b00111111: keep2count = 6; - 8'b01111111: keep2count = 7; - 8'b11111111: keep2count = 8; + 8'b00000000: keep2count = 4'd0; + 8'b00000001: keep2count = 4'd1; + 8'b00000011: keep2count = 4'd2; + 8'b00000111: keep2count = 4'd3; + 8'b00001111: keep2count = 4'd4; + 8'b00011111: keep2count = 4'd5; + 8'b00111111: keep2count = 4'd6; + 8'b01111111: keep2count = 4'd7; + 8'b11111111: keep2count = 4'd8; endcase endfunction @@ -258,37 +258,37 @@ endfunction always @* begin state_next = STATE_IDLE; - input_ip_hdr_ready_next = 0; - input_ip_payload_tready_next = 0; + input_ip_hdr_ready_next = 1'b0; + input_ip_payload_tready_next = 1'b0; - store_ip_hdr = 0; - store_hdr_word_0 = 0; + store_ip_hdr = 1'b0; + store_hdr_word_0 = 1'b0; - store_last_word = 0; + store_last_word = 1'b0; frame_ptr_next = frame_ptr_reg; output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; - error_header_early_termination_next = 0; - error_payload_early_termination_next = 0; + error_header_early_termination_next = 1'b0; + error_payload_early_termination_next = 1'b0; - output_udp_payload_tdata_int = 0; - output_udp_payload_tkeep_int = 0; - output_udp_payload_tvalid_int = 0; - output_udp_payload_tlast_int = 0; - output_udp_payload_tuser_int = 0; + output_udp_payload_tdata_int = 64'd0; + output_udp_payload_tkeep_int = 8'd0; + output_udp_payload_tvalid_int = 1'b0; + output_udp_payload_tlast_int = 1'b0; + output_udp_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for header - frame_ptr_next = 0; + frame_ptr_next = 16'd0; input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; if (input_ip_hdr_ready & input_ip_hdr_valid) begin - input_ip_hdr_ready_next = 0; - input_ip_payload_tready_next = 1; - store_ip_hdr = 1; + input_ip_hdr_ready_next = 1'b0; + input_ip_payload_tready_next = 1'b1; + store_ip_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin state_next = STATE_IDLE; @@ -296,27 +296,27 @@ always @* begin end STATE_READ_HEADER: begin // read header state - input_ip_payload_tready_next = 1; + input_ip_payload_tready_next = 1'b1; if (input_ip_payload_tready & input_ip_payload_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg+8; + frame_ptr_next = frame_ptr_reg + 16'd8; state_next = STATE_READ_HEADER; case (frame_ptr_reg) 8'h00: begin - store_hdr_word_0 = 1; - output_udp_hdr_valid_next = 1; + store_hdr_word_0 = 1'b1; + output_udp_hdr_valid_next = 1'b1; input_ip_payload_tready_next = output_udp_payload_tready_int_early; state_next = STATE_READ_PAYLOAD; end endcase if (input_ip_payload_tlast) begin - error_header_early_termination_next = 1; - output_udp_hdr_valid_next = 0; + error_header_early_termination_next = 1'b1; + output_udp_hdr_valid_next = 1'b0; input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -342,20 +342,20 @@ always @* begin frame_ptr_next = output_udp_length_reg; output_udp_payload_tkeep_int = input_ip_payload_tkeep & count2keep(output_udp_length_reg - frame_ptr_reg); if (input_ip_payload_tlast) begin - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; state_next = STATE_IDLE; end else begin - store_last_word = 1; - output_udp_payload_tvalid_int = 0; + store_last_word = 1'b1; + output_udp_payload_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; end end else begin if (input_ip_payload_tlast) begin // end of frame, but length does not match - error_payload_early_termination_next = 1; - output_udp_payload_tuser_int = 1; - input_ip_payload_tready_next = 0; + error_payload_early_termination_next = 1'b1; + output_udp_payload_tuser_int = 1'b1; + input_ip_payload_tready_next = 1'b0; input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; state_next = STATE_IDLE; end else begin @@ -379,7 +379,7 @@ always @* begin if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD_LAST; @@ -390,12 +390,12 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_ip_payload_tready_next = 1; + input_ip_payload_tready_next = 1'b1; if (input_ip_payload_tready & input_ip_payload_tvalid) begin if (input_ip_payload_tlast) begin input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 0; + input_ip_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -410,34 +410,13 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - last_word_data_reg <= 0; - input_ip_hdr_ready_reg <= 0; - input_ip_payload_tready_reg <= 0; - output_udp_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - output_udp_source_port_reg <= 0; - output_udp_dest_port_reg <= 0; - output_udp_length_reg <= 0; - output_udp_checksum_reg <= 0; - busy_reg <= 0; - error_header_early_termination_reg <= 0; - error_payload_early_termination_reg <= 0; + frame_ptr_reg <= 16'd0; + input_ip_hdr_ready_reg <= 1'b0; + input_ip_payload_tready_reg <= 1'b0; + output_udp_hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; + error_header_early_termination_reg <= 1'b0; + error_payload_early_termination_reg <= 1'b0; end else begin state_reg <= state_next; @@ -452,60 +431,62 @@ always @(posedge clk) begin error_payload_early_termination_reg <= error_payload_early_termination_next; busy_reg <= state_next != STATE_IDLE; + end - // datapath - if (store_ip_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - output_ip_version_reg <= input_ip_version; - output_ip_ihl_reg <= input_ip_ihl; - output_ip_dscp_reg <= input_ip_dscp; - output_ip_ecn_reg <= input_ip_ecn; - output_ip_length_reg <= input_ip_length; - output_ip_identification_reg <= input_ip_identification; - output_ip_flags_reg <= input_ip_flags; - output_ip_fragment_offset_reg <= input_ip_fragment_offset; - output_ip_ttl_reg <= input_ip_ttl; - output_ip_protocol_reg <= input_ip_protocol; - output_ip_header_checksum_reg <= input_ip_header_checksum; - output_ip_source_ip_reg <= input_ip_source_ip; - output_ip_dest_ip_reg <= input_ip_dest_ip; - end + // datapath + if (store_ip_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + output_ip_version_reg <= input_ip_version; + output_ip_ihl_reg <= input_ip_ihl; + output_ip_dscp_reg <= input_ip_dscp; + output_ip_ecn_reg <= input_ip_ecn; + output_ip_length_reg <= input_ip_length; + output_ip_identification_reg <= input_ip_identification; + output_ip_flags_reg <= input_ip_flags; + output_ip_fragment_offset_reg <= input_ip_fragment_offset; + output_ip_ttl_reg <= input_ip_ttl; + output_ip_protocol_reg <= input_ip_protocol; + output_ip_header_checksum_reg <= input_ip_header_checksum; + output_ip_source_ip_reg <= input_ip_source_ip; + output_ip_dest_ip_reg <= input_ip_dest_ip; + end - if (store_last_word) begin - last_word_data_reg <= output_udp_payload_tdata_int; - last_word_keep_reg <= output_udp_payload_tkeep_int; - end + if (store_last_word) begin + last_word_data_reg <= output_udp_payload_tdata_int; + last_word_keep_reg <= output_udp_payload_tkeep_int; + end - if (store_hdr_word_0) begin - output_udp_source_port_reg[15: 8] <= input_ip_payload_tdata[ 7: 0]; - output_udp_source_port_reg[ 7: 0] <= input_ip_payload_tdata[15: 8]; - output_udp_dest_port_reg[15: 8] <= input_ip_payload_tdata[23:16]; - output_udp_dest_port_reg[ 7: 0] <= input_ip_payload_tdata[31:24]; - output_udp_length_reg[15: 8] <= input_ip_payload_tdata[39:32]; - output_udp_length_reg[ 7: 0] <= input_ip_payload_tdata[47:40]; - output_udp_checksum_reg[15: 8] <= input_ip_payload_tdata[55:48]; - output_udp_checksum_reg[ 7: 0] <= input_ip_payload_tdata[63:56]; - end + if (store_hdr_word_0) begin + output_udp_source_port_reg[15: 8] <= input_ip_payload_tdata[ 7: 0]; + output_udp_source_port_reg[ 7: 0] <= input_ip_payload_tdata[15: 8]; + output_udp_dest_port_reg[15: 8] <= input_ip_payload_tdata[23:16]; + output_udp_dest_port_reg[ 7: 0] <= input_ip_payload_tdata[31:24]; + output_udp_length_reg[15: 8] <= input_ip_payload_tdata[39:32]; + output_udp_length_reg[ 7: 0] <= input_ip_payload_tdata[47:40]; + output_udp_checksum_reg[15: 8] <= input_ip_payload_tdata[55:48]; + output_udp_checksum_reg[ 7: 0] <= input_ip_payload_tdata[63:56]; end end // output datapath logic -reg [63:0] output_udp_payload_tdata_reg = 0; -reg [7:0] output_udp_payload_tkeep_reg = 0; -reg output_udp_payload_tvalid_reg = 0; -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; +reg [63:0] output_udp_payload_tdata_reg = 64'd0; +reg [7:0] output_udp_payload_tkeep_reg = 8'd0; +reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; +reg output_udp_payload_tlast_reg = 1'b0; +reg output_udp_payload_tuser_reg = 1'b0; -reg [63:0] temp_udp_payload_tdata_reg = 0; -reg [7:0] temp_udp_payload_tkeep_reg = 0; -reg temp_udp_payload_tvalid_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +reg [63:0] temp_udp_payload_tdata_reg = 64'd0; +reg [7:0] temp_udp_payload_tkeep_reg = 8'd0; +reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; +reg temp_udp_payload_tlast_reg = 1'b0; +reg temp_udp_payload_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); +// datapath control +reg store_udp_payload_int_to_output; +reg store_udp_payload_int_to_temp; +reg store_udp_payload_temp_to_output; assign output_udp_payload_tdata = output_udp_payload_tdata_reg; assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; @@ -513,53 +494,66 @@ assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; assign output_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_udp_payload_tuser = output_udp_payload_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + + store_udp_payload_int_to_output = 1'b0; + store_udp_payload_int_to_temp = 1'b0; + store_udp_payload_temp_to_output = 1'b0; + + if (output_udp_payload_tready_int_reg) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_temp = 1'b1; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready + output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = 1'b0; + store_udp_payload_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_udp_payload_tdata_reg <= 0; - output_udp_payload_tkeep_reg <= 0; - output_udp_payload_tvalid_reg <= 0; - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - output_udp_payload_tready_int <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; + output_udp_payload_tvalid_reg <= 1'b0; + output_udp_payload_tready_int_reg <= 1'b0; + temp_udp_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; + output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; + temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + end - if (output_udp_payload_tready_int) begin - // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end - end else if (output_udp_payload_tready) begin - // input is not ready, but output is ready - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; - output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; - end + // datapath + if (store_udp_payload_int_to_output) begin + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else if (store_udp_payload_temp_to_output) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (store_udp_payload_int_to_temp) begin + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; end end diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index 652f850d9..033783cb6 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -147,43 +147,43 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_udp_hdr; reg store_last_word; -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg [7:0] last_word_data_reg = 0; +reg [7:0] last_word_data_reg = 8'd0; -reg [15:0] udp_source_port_reg = 0; -reg [15:0] udp_dest_port_reg = 0; -reg [15:0] udp_length_reg = 0; -reg [15:0] udp_checksum_reg = 0; +reg [15:0] udp_source_port_reg = 16'd0; +reg [15:0] udp_dest_port_reg = 16'd0; +reg [15:0] udp_length_reg = 16'd0; +reg [15:0] udp_checksum_reg = 16'd0; -reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; +reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; -reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; -reg [3:0] output_ip_version_reg = 0; -reg [3:0] output_ip_ihl_reg = 0; -reg [5:0] output_ip_dscp_reg = 0; -reg [1:0] output_ip_ecn_reg = 0; -reg [15:0] output_ip_length_reg = 0; -reg [15:0] output_ip_identification_reg = 0; -reg [2:0] output_ip_flags_reg = 0; -reg [12:0] output_ip_fragment_offset_reg = 0; -reg [7:0] output_ip_ttl_reg = 0; -reg [7:0] output_ip_protocol_reg = 0; -reg [15:0] output_ip_header_checksum_reg = 0; -reg [31:0] output_ip_source_ip_reg = 0; -reg [31:0] output_ip_dest_ip_reg = 0; +reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; +reg [3:0] output_ip_version_reg = 4'd0; +reg [3:0] output_ip_ihl_reg = 4'd0; +reg [5:0] output_ip_dscp_reg = 6'd0; +reg [1:0] output_ip_ecn_reg = 2'd0; +reg [15:0] output_ip_length_reg = 16'd0; +reg [15:0] output_ip_identification_reg = 16'd0; +reg [2:0] output_ip_flags_reg = 3'd0; +reg [12:0] output_ip_fragment_offset_reg = 13'd0; +reg [7:0] output_ip_ttl_reg = 8'd0; +reg [7:0] output_ip_protocol_reg = 8'd0; +reg [15:0] output_ip_header_checksum_reg = 16'd0; +reg [31:0] output_ip_source_ip_reg = 32'd0; +reg [31:0] output_ip_dest_ip_reg = 32'd0; -reg busy_reg = 0; -reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; +reg busy_reg = 1'b0; +reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; // internal datapath reg [7:0] output_ip_payload_tdata_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -215,38 +215,38 @@ assign error_payload_early_termination = error_payload_early_termination_reg; always @* begin state_next = STATE_IDLE; - input_udp_hdr_ready_next = 0; - input_udp_payload_tready_next = 0; + input_udp_hdr_ready_next = 1'b0; + input_udp_payload_tready_next = 1'b0; - store_udp_hdr = 0; + store_udp_hdr = 1'b0; - store_last_word = 0; + store_last_word = 1'b0; frame_ptr_next = frame_ptr_reg; output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; - error_payload_early_termination_next = 0; + error_payload_early_termination_next = 1'b0; - output_ip_payload_tdata_int = 0; - output_ip_payload_tvalid_int = 0; - output_ip_payload_tlast_int = 0; - output_ip_payload_tuser_int = 0; + output_ip_payload_tdata_int = 8'd0; + output_ip_payload_tvalid_int = 1'b0; + output_ip_payload_tlast_int = 1'b0; + output_ip_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; + frame_ptr_next = 16'd0; input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; if (input_udp_hdr_ready & input_udp_hdr_valid) begin - store_udp_hdr = 1; - input_udp_hdr_ready_next = 0; - output_ip_hdr_valid_next = 1; - if (output_ip_payload_tready_int) begin - output_ip_payload_tvalid_int = 1; + store_udp_hdr = 1'b1; + input_udp_hdr_ready_next = 1'b0; + output_ip_hdr_valid_next = 1'b1; + if (output_ip_payload_tready_int_reg) begin + output_ip_payload_tvalid_int = 1'b1; output_ip_payload_tdata_int = input_udp_source_port[15: 8]; - frame_ptr_next = 1; + frame_ptr_next = 1'b1; end state_next = STATE_WRITE_HEADER; end else begin @@ -255,10 +255,10 @@ always @* begin end STATE_WRITE_HEADER: begin // write header state - if (output_ip_payload_tready_int) begin + if (output_ip_payload_tready_int_reg) begin // word transfer out - frame_ptr_next = frame_ptr_reg+1; - output_ip_payload_tvalid_int = 1; + frame_ptr_next = frame_ptr_reg + 16'd1; + output_ip_payload_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: output_ip_payload_tdata_int = input_udp_source_port[15: 8]; @@ -289,20 +289,20 @@ always @* begin if (input_udp_payload_tready & input_udp_payload_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+1; + frame_ptr_next = frame_ptr_reg + 16'd1; if (input_udp_payload_tlast) begin if (frame_ptr_next != udp_length_reg) begin // end of frame, but length does not match - output_ip_payload_tuser_int = 1; - error_payload_early_termination_next = 1; + output_ip_payload_tuser_int = 1'b1; + error_payload_early_termination_next = 1'b1; end input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_udp_payload_tready_next = 0; + input_udp_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin if (frame_ptr_next == udp_length_reg) begin - store_last_word = 1; - output_ip_payload_tvalid_int = 0; + store_last_word = 1'b1; + output_ip_payload_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -324,7 +324,7 @@ always @* begin if (input_udp_payload_tready & input_udp_payload_tvalid) begin if (input_udp_payload_tlast) begin input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_udp_payload_tready_next = 0; + input_udp_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD_LAST; @@ -335,12 +335,12 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_udp_payload_tready_next = 1; + input_udp_payload_tready_next = 1'b1; if (input_udp_payload_tvalid) begin if (input_udp_payload_tlast) begin input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_udp_payload_tready_next = 0; + input_udp_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -355,33 +355,12 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - last_word_data_reg <= 0; - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; - udp_source_port_reg <= 0; - udp_dest_port_reg <= 0; - udp_length_reg <= 0; - udp_checksum_reg <= 0; - output_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - busy_reg <= 0; - error_payload_early_termination_reg <= 0; + frame_ptr_reg <= 16'd0; + input_udp_hdr_ready_reg <= 1'b0; + input_udp_payload_tready_reg <= 1'b0; + output_ip_hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; + error_payload_early_termination_reg <= 1'b0; end else begin state_reg <= state_next; @@ -395,97 +374,115 @@ always @(posedge clk) begin busy_reg <= state_next != STATE_IDLE; error_payload_early_termination_reg <= error_payload_early_termination_next; + end - // datapath - if (store_udp_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - output_ip_version_reg <= input_ip_version; - output_ip_ihl_reg <= input_ip_ihl; - output_ip_dscp_reg <= input_ip_dscp; - output_ip_ecn_reg <= input_ip_ecn; - output_ip_length_reg <= input_udp_length + 20; - output_ip_identification_reg <= input_ip_identification; - output_ip_flags_reg <= input_ip_flags; - output_ip_fragment_offset_reg <= input_ip_fragment_offset; - output_ip_ttl_reg <= input_ip_ttl; - output_ip_protocol_reg <= input_ip_protocol; - output_ip_header_checksum_reg <= input_ip_header_checksum; - output_ip_source_ip_reg <= input_ip_source_ip; - output_ip_dest_ip_reg <= input_ip_dest_ip; - udp_source_port_reg <= input_udp_source_port; - udp_dest_port_reg <= input_udp_dest_port; - udp_length_reg <= input_udp_length; - udp_checksum_reg <= input_udp_checksum; - end + // datapath + if (store_udp_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + output_ip_version_reg <= input_ip_version; + output_ip_ihl_reg <= input_ip_ihl; + output_ip_dscp_reg <= input_ip_dscp; + output_ip_ecn_reg <= input_ip_ecn; + output_ip_length_reg <= input_udp_length + 20; + output_ip_identification_reg <= input_ip_identification; + output_ip_flags_reg <= input_ip_flags; + output_ip_fragment_offset_reg <= input_ip_fragment_offset; + output_ip_ttl_reg <= input_ip_ttl; + output_ip_protocol_reg <= input_ip_protocol; + output_ip_header_checksum_reg <= input_ip_header_checksum; + output_ip_source_ip_reg <= input_ip_source_ip; + output_ip_dest_ip_reg <= input_ip_dest_ip; + udp_source_port_reg <= input_udp_source_port; + udp_dest_port_reg <= input_udp_dest_port; + udp_length_reg <= input_udp_length; + udp_checksum_reg <= input_udp_checksum; + end - if (store_last_word) begin - last_word_data_reg <= output_ip_payload_tdata_int; - end + if (store_last_word) begin + last_word_data_reg <= output_ip_payload_tdata_int; end end // output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [7:0] output_ip_payload_tdata_reg = 8'd0; +reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [7:0] temp_ip_payload_tdata_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [7:0] temp_ip_payload_tdata_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index 69b5ba4ed..aee1350c8 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -149,45 +149,45 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_udp_hdr; reg store_last_word; -reg [15:0] frame_ptr_reg = 0, frame_ptr_next; +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg [63:0] last_word_data_reg = 0; -reg [7:0] last_word_keep_reg = 0; +reg [63:0] last_word_data_reg = 64'd0; +reg [7:0] last_word_keep_reg = 8'd0; -reg [15:0] udp_source_port_reg = 0; -reg [15:0] udp_dest_port_reg = 0; -reg [15:0] udp_length_reg = 0; -reg [15:0] udp_checksum_reg = 0; +reg [15:0] udp_source_port_reg = 16'd0; +reg [15:0] udp_dest_port_reg = 16'd0; +reg [15:0] udp_length_reg = 16'd0; +reg [15:0] udp_checksum_reg = 16'd0; -reg input_udp_hdr_ready_reg = 0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 0, input_udp_payload_tready_next; +reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; -reg output_ip_hdr_valid_reg = 0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0; -reg [47:0] output_eth_src_mac_reg = 0; -reg [15:0] output_eth_type_reg = 0; -reg [3:0] output_ip_version_reg = 0; -reg [3:0] output_ip_ihl_reg = 0; -reg [5:0] output_ip_dscp_reg = 0; -reg [1:0] output_ip_ecn_reg = 0; -reg [15:0] output_ip_length_reg = 0; -reg [15:0] output_ip_identification_reg = 0; -reg [2:0] output_ip_flags_reg = 0; -reg [12:0] output_ip_fragment_offset_reg = 0; -reg [7:0] output_ip_ttl_reg = 0; -reg [7:0] output_ip_protocol_reg = 0; -reg [15:0] output_ip_header_checksum_reg = 0; -reg [31:0] output_ip_source_ip_reg = 0; -reg [31:0] output_ip_dest_ip_reg = 0; +reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; +reg [3:0] output_ip_version_reg = 4'd0; +reg [3:0] output_ip_ihl_reg = 4'd0; +reg [5:0] output_ip_dscp_reg = 6'd0; +reg [1:0] output_ip_ecn_reg = 2'd0; +reg [15:0] output_ip_length_reg = 16'd0; +reg [15:0] output_ip_identification_reg = 16'd0; +reg [2:0] output_ip_flags_reg = 3'd0; +reg [12:0] output_ip_fragment_offset_reg = 13'd0; +reg [7:0] output_ip_ttl_reg = 8'd0; +reg [7:0] output_ip_protocol_reg = 8'd0; +reg [15:0] output_ip_header_checksum_reg = 16'd0; +reg [31:0] output_ip_source_ip_reg = 32'd0; +reg [31:0] output_ip_dest_ip_reg = 32'd0; -reg busy_reg = 0; -reg error_payload_early_termination_reg = 0, error_payload_early_termination_next; +reg busy_reg = 1'b0; +reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; // internal datapath reg [63:0] output_ip_payload_tdata_int; reg [7:0] output_ip_payload_tkeep_int; reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int = 0; +reg output_ip_payload_tready_int_reg = 1'b0; reg output_ip_payload_tlast_int; reg output_ip_payload_tuser_int; wire output_ip_payload_tready_int_early; @@ -219,15 +219,15 @@ assign error_payload_early_termination = error_payload_early_termination_reg; function [3:0] keep2count; input [7:0] k; case (k) - 8'b00000000: keep2count = 0; - 8'b00000001: keep2count = 1; - 8'b00000011: keep2count = 2; - 8'b00000111: keep2count = 3; - 8'b00001111: keep2count = 4; - 8'b00011111: keep2count = 5; - 8'b00111111: keep2count = 6; - 8'b01111111: keep2count = 7; - 8'b11111111: keep2count = 8; + 8'b00000000: keep2count = 4'd0; + 8'b00000001: keep2count = 4'd1; + 8'b00000011: keep2count = 4'd2; + 8'b00000111: keep2count = 4'd3; + 8'b00001111: keep2count = 4'd4; + 8'b00011111: keep2count = 4'd5; + 8'b00111111: keep2count = 4'd6; + 8'b01111111: keep2count = 4'd7; + 8'b11111111: keep2count = 4'd8; endcase endfunction @@ -249,38 +249,38 @@ endfunction always @* begin state_next = STATE_IDLE; - input_udp_hdr_ready_next = 0; - input_udp_payload_tready_next = 0; + input_udp_hdr_ready_next = 1'b0; + input_udp_payload_tready_next = 1'b0; - store_udp_hdr = 0; + store_udp_hdr = 1'b0; - store_last_word = 0; + store_last_word = 1'b0; frame_ptr_next = frame_ptr_reg; output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; - error_payload_early_termination_next = 0; + error_payload_early_termination_next = 1'b0; - output_ip_payload_tdata_int = 0; - output_ip_payload_tkeep_int = 0; - output_ip_payload_tvalid_int = 0; - output_ip_payload_tlast_int = 0; - output_ip_payload_tuser_int = 0; + output_ip_payload_tdata_int = 64'd0; + output_ip_payload_tkeep_int = 8'd0; + output_ip_payload_tvalid_int = 1'b0; + output_ip_payload_tlast_int = 1'b0; + output_ip_payload_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 0; + frame_ptr_next = 16'd0; input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; if (input_udp_hdr_ready & input_udp_hdr_valid) begin - store_udp_hdr = 1; - input_udp_hdr_ready_next = 0; - output_ip_hdr_valid_next = 1; + store_udp_hdr = 1'b1; + input_udp_hdr_ready_next = 1'b0; + output_ip_hdr_valid_next = 1'b1; state_next = STATE_WRITE_HEADER; - if (output_ip_payload_tready_int) begin - output_ip_payload_tvalid_int = 1; + if (output_ip_payload_tready_int_reg) begin + output_ip_payload_tvalid_int = 1'b1; output_ip_payload_tdata_int[ 7: 0] = input_udp_source_port[15: 8]; output_ip_payload_tdata_int[15: 8] = input_udp_source_port[ 7: 0]; output_ip_payload_tdata_int[23:16] = input_udp_dest_port[15: 8]; @@ -290,7 +290,7 @@ always @* begin output_ip_payload_tdata_int[55:48] = input_udp_checksum[15: 8]; output_ip_payload_tdata_int[63:56] = input_udp_checksum[ 7: 0]; output_ip_payload_tkeep_int = 8'hff; - frame_ptr_next = 8; + frame_ptr_next = 16'd8; input_udp_payload_tready_next = output_ip_payload_tready_int_early; state_next = STATE_WRITE_PAYLOAD; end @@ -300,10 +300,10 @@ always @* begin end STATE_WRITE_HEADER: begin // write header state - if (output_ip_payload_tready_int) begin + if (output_ip_payload_tready_int_reg) begin // word transfer out - frame_ptr_next = frame_ptr_reg+8; - output_ip_payload_tvalid_int = 1; + frame_ptr_next = frame_ptr_reg + 16'd8; + output_ip_payload_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: begin @@ -334,7 +334,7 @@ always @* begin output_ip_payload_tlast_int = input_udp_payload_tlast; output_ip_payload_tuser_int = input_udp_payload_tuser; - if (output_ip_payload_tready_int & input_udp_payload_tvalid) begin + if (output_ip_payload_tready_int_reg & input_udp_payload_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(input_udp_payload_tkeep); if (frame_ptr_next >= udp_length_reg) begin @@ -342,20 +342,20 @@ always @* begin frame_ptr_next = udp_length_reg; output_ip_payload_tkeep_int = count2keep(udp_length_reg - frame_ptr_reg); if (input_udp_payload_tlast) begin - input_udp_payload_tready_next = 0; + input_udp_payload_tready_next = 1'b0; input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; state_next = STATE_IDLE; end else begin - store_last_word = 1; - output_ip_payload_tvalid_int = 0; + store_last_word = 1'b1; + output_ip_payload_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin if (input_udp_payload_tlast) begin // end of frame, but length does not match - error_payload_early_termination_next = 1; - output_ip_payload_tuser_int = 1; - input_udp_payload_tready_next = 0; + error_payload_early_termination_next = 1'b1; + output_ip_payload_tuser_int = 1'b1; + input_udp_payload_tready_next = 1'b0; input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; state_next = STATE_IDLE; end else begin @@ -379,7 +379,7 @@ always @* begin if (input_udp_payload_tready & input_udp_payload_tvalid) begin if (input_udp_payload_tlast) begin input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_udp_payload_tready_next = 0; + input_udp_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD_LAST; @@ -390,12 +390,12 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_udp_payload_tready_next = 1; + input_udp_payload_tready_next = 1'b1; if (input_udp_payload_tvalid) begin if (input_udp_payload_tlast) begin input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_udp_payload_tready_next = 0; + input_udp_payload_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -410,34 +410,12 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 0; - last_word_data_reg <= 0; - last_word_keep_reg <= 0; - input_udp_hdr_ready_reg <= 0; - input_udp_payload_tready_reg <= 0; - udp_source_port_reg <= 0; - udp_dest_port_reg <= 0; - udp_length_reg <= 0; - udp_checksum_reg <= 0; - output_ip_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - busy_reg <= 0; - error_payload_early_termination_reg <= 0; + frame_ptr_reg <= 16'd0; + input_udp_hdr_ready_reg <= 1'b0; + input_udp_payload_tready_reg <= 1'b0; + output_ip_hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; + error_payload_early_termination_reg <= 1'b0; end else begin state_reg <= state_next; @@ -451,53 +429,55 @@ always @(posedge clk) begin busy_reg <= state_next != STATE_IDLE; error_payload_early_termination_reg <= error_payload_early_termination_next; + end - // datapath - if (store_udp_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - output_ip_version_reg <= input_ip_version; - output_ip_ihl_reg <= input_ip_ihl; - output_ip_dscp_reg <= input_ip_dscp; - output_ip_ecn_reg <= input_ip_ecn; - output_ip_length_reg <= input_udp_length + 20; - output_ip_identification_reg <= input_ip_identification; - output_ip_flags_reg <= input_ip_flags; - output_ip_fragment_offset_reg <= input_ip_fragment_offset; - output_ip_ttl_reg <= input_ip_ttl; - output_ip_protocol_reg <= input_ip_protocol; - output_ip_header_checksum_reg <= input_ip_header_checksum; - output_ip_source_ip_reg <= input_ip_source_ip; - output_ip_dest_ip_reg <= input_ip_dest_ip; - udp_source_port_reg <= input_udp_source_port; - udp_dest_port_reg <= input_udp_dest_port; - udp_length_reg <= input_udp_length; - udp_checksum_reg <= input_udp_checksum; - end + // datapath + if (store_udp_hdr) begin + output_eth_dest_mac_reg <= input_eth_dest_mac; + output_eth_src_mac_reg <= input_eth_src_mac; + output_eth_type_reg <= input_eth_type; + output_ip_version_reg <= input_ip_version; + output_ip_ihl_reg <= input_ip_ihl; + output_ip_dscp_reg <= input_ip_dscp; + output_ip_ecn_reg <= input_ip_ecn; + output_ip_length_reg <= input_udp_length + 20; + output_ip_identification_reg <= input_ip_identification; + output_ip_flags_reg <= input_ip_flags; + output_ip_fragment_offset_reg <= input_ip_fragment_offset; + output_ip_ttl_reg <= input_ip_ttl; + output_ip_protocol_reg <= input_ip_protocol; + output_ip_header_checksum_reg <= input_ip_header_checksum; + output_ip_source_ip_reg <= input_ip_source_ip; + output_ip_dest_ip_reg <= input_ip_dest_ip; + udp_source_port_reg <= input_udp_source_port; + udp_dest_port_reg <= input_udp_dest_port; + udp_length_reg <= input_udp_length; + udp_checksum_reg <= input_udp_checksum; + end - if (store_last_word) begin - last_word_data_reg <= output_ip_payload_tdata_int; - last_word_keep_reg <= output_ip_payload_tkeep_int; - end + if (store_last_word) begin + last_word_data_reg <= output_ip_payload_tdata_int; + last_word_keep_reg <= output_ip_payload_tkeep_int; end end // output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 0; -reg [7:0] output_ip_payload_tkeep_reg = 0; -reg output_ip_payload_tvalid_reg = 0; -reg output_ip_payload_tlast_reg = 0; -reg output_ip_payload_tuser_reg = 0; +reg [63:0] output_ip_payload_tdata_reg = 64'd0; +reg [7:0] output_ip_payload_tkeep_reg = 8'd0; +reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; +reg output_ip_payload_tlast_reg = 1'b0; +reg output_ip_payload_tuser_reg = 1'b0; -reg [63:0] temp_ip_payload_tdata_reg = 0; -reg [7:0] temp_ip_payload_tkeep_reg = 0; -reg temp_ip_payload_tvalid_reg = 0; -reg temp_ip_payload_tlast_reg = 0; -reg temp_ip_payload_tuser_reg = 0; +reg [63:0] temp_ip_payload_tdata_reg = 64'd0; +reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; +reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; +reg temp_ip_payload_tlast_reg = 1'b0; +reg temp_ip_payload_tuser_reg = 1'b0; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_reg) | (~temp_ip_payload_tvalid_reg & ~output_ip_payload_tvalid_int); +// datapath control +reg store_ip_payload_int_to_output; +reg store_ip_payload_int_to_temp; +reg store_ip_payload_temp_to_output; assign output_ip_payload_tdata = output_ip_payload_tdata_reg; assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; @@ -505,53 +485,66 @@ assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; assign output_ip_payload_tlast = output_ip_payload_tlast_reg; assign output_ip_payload_tuser = output_ip_payload_tuser_reg; +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + + store_ip_payload_int_to_output = 1'b0; + store_ip_payload_int_to_temp = 1'b0; + store_ip_payload_temp_to_output = 1'b0; + + if (output_ip_payload_tready_int_reg) begin + // input is ready + if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + store_ip_payload_int_to_temp = 1'b1; + end + end else if (output_ip_payload_tready) begin + // input is not ready, but output is ready + output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + temp_ip_payload_tvalid_next = 1'b0; + store_ip_payload_temp_to_output = 1'b1; + end +end + always @(posedge clk) begin if (rst) begin - output_ip_payload_tdata_reg <= 0; - output_ip_payload_tkeep_reg <= 0; - output_ip_payload_tvalid_reg <= 0; - output_ip_payload_tlast_reg <= 0; - output_ip_payload_tuser_reg <= 0; - output_ip_payload_tready_int <= 0; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; + output_ip_payload_tvalid_reg <= 1'b0; + output_ip_payload_tready_int_reg <= 1'b0; + temp_ip_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_ip_payload_tready_int <= output_ip_payload_tready_int_early; + output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; + output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; + temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + end - if (output_ip_payload_tready_int) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else begin - // output is not ready and currently valid, store input in temp - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tvalid_reg <= output_ip_payload_tvalid_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - temp_ip_payload_tdata_reg <= 0; - temp_ip_payload_tkeep_reg <= 0; - temp_ip_payload_tvalid_reg <= 0; - temp_ip_payload_tlast_reg <= 0; - temp_ip_payload_tuser_reg <= 0; - end + // datapath + if (store_ip_payload_int_to_output) begin + output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + end else if (store_ip_payload_temp_to_output) begin + output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; + output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; + output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; + output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + end + + if (store_ip_payload_int_to_temp) begin + temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; + temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; + temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; + temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; end end diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py index 7fb6b106a..eccaa18bd 100755 --- a/rtl/udp_mux.py +++ b/rtl/udp_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -144,41 +144,41 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; {% for p in ports %} -reg input_{{p}}_udp_hdr_ready_reg = 0, input_{{p}}_udp_hdr_ready_next; +reg input_{{p}}_udp_hdr_ready_reg = 1'b0, input_{{p}}_udp_hdr_ready_next; {%- endfor %} {% for p in ports %} -reg input_{{p}}_udp_payload_tready_reg = 0, input_{{p}}_udp_payload_tready_next; +reg input_{{p}}_udp_payload_tready_reg = 1'b0, input_{{p}}_udp_payload_tready_next; {%- endfor %} -reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; +reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; // internal datapath reg [7:0] output_udp_payload_tdata_int; reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tready_int_reg = 1'b0; reg output_udp_payload_tlast_int; reg output_udp_payload_tuser_int; wire output_udp_payload_tready_int_early; @@ -260,6 +260,29 @@ always @* begin selected_input_udp_checksum = input_{{p}}_udp_checksum; end {%- endfor %} + default: begin + selected_input_udp_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + selected_input_ip_version = 4'd0; + selected_input_ip_ihl = 4'd0; + selected_input_ip_dscp = 6'd0; + selected_input_ip_ecn = 2'd0; + selected_input_ip_length = 16'd0; + selected_input_ip_identification = 16'd0; + selected_input_ip_flags = 3'd0; + selected_input_ip_fragment_offset = 13'd0; + selected_input_ip_ttl = 8'd0; + selected_input_ip_protocol = 8'd0; + selected_input_ip_header_checksum = 16'd0; + selected_input_ip_source_ip = 32'd0; + selected_input_ip_dest_ip = 32'd0; + selected_input_udp_source_port = 16'd0; + selected_input_udp_dest_port = 16'd0; + selected_input_udp_length = 16'd0; + selected_input_udp_checksum = 16'd0; + end endcase end @@ -280,6 +303,13 @@ always @* begin current_input_tuser = input_{{p}}_udp_payload_tuser; end {%- endfor %} + default: begin + current_input_tdata = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -290,7 +320,7 @@ always @* begin input_{{p}}_udp_hdr_ready_next = input_{{p}}_udp_hdr_ready_reg & ~input_{{p}}_udp_hdr_valid; {%- endfor %} {% for p in ports %} - input_{{p}}_udp_payload_tready_next = 0; + input_{{p}}_udp_payload_tready_next = 1'b0; {%- endfor %} output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; @@ -327,11 +357,11 @@ always @* begin case (select_next) {%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_udp_hdr_ready_next = 1; + {{w}}'d{{p}}: input_{{p}}_udp_hdr_ready_next = 1'b1; {%- endfor %} endcase - output_udp_hdr_valid_next = 1; + output_udp_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -370,35 +400,15 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; {%- for p in ports %} - input_{{p}}_udp_hdr_ready_reg <= 0; + input_{{p}}_udp_hdr_ready_reg <= 1'b0; {%- endfor %} {%- for p in ports %} - input_{{p}}_udp_payload_tready_reg <= 0; + input_{{p}}_udp_payload_tready_reg <= 1'b0; {%- endfor %} - output_udp_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - output_udp_source_port_reg <= 0; - output_udp_dest_port_reg <= 0; - output_udp_length_reg <= 0; - output_udp_checksum_reg <= 0; + output_udp_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -409,89 +419,108 @@ always @(posedge clk) begin input_{{p}}_udp_payload_tready_reg <= input_{{p}}_udp_payload_tready_next; {%- endfor %} output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; end // output datapath logic -reg [7:0] output_udp_payload_tdata_reg = 0; -reg output_udp_payload_tvalid_reg = 0; -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; +reg [7:0] output_udp_payload_tdata_reg = 8'd0; +reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; +reg output_udp_payload_tlast_reg = 1'b0; +reg output_udp_payload_tuser_reg = 1'b0; -reg [7:0] temp_udp_payload_tdata_reg = 0; -reg temp_udp_payload_tvalid_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +reg [7:0] temp_udp_payload_tdata_reg = 8'd0; +reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; +reg temp_udp_payload_tlast_reg = 1'b0; +reg temp_udp_payload_tuser_reg = 1'b0; + +// datapath control +reg store_udp_payload_int_to_output; +reg store_udp_payload_int_to_temp; +reg store_udp_payload_temp_to_output; assign output_udp_payload_tdata = output_udp_payload_tdata_reg; assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; assign output_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_udp_payload_tuser = output_udp_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + + store_udp_payload_int_to_output = 1'b0; + store_udp_payload_int_to_temp = 1'b0; + store_udp_payload_temp_to_output = 1'b0; + + if (output_udp_payload_tready_int_reg) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_temp = 1'b1; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready + output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = 1'b0; + store_udp_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_udp_payload_tdata_reg <= 0; - output_udp_payload_tvalid_reg <= 0; - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - output_udp_payload_tready_int <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; + output_udp_payload_tvalid_reg <= 1'b0; + output_udp_payload_tready_int_reg <= 1'b0; + temp_udp_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; + output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; + temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + end - if (output_udp_payload_tready_int) begin - // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end - end else if (output_udp_payload_tready) begin - // input is not ready, but output is ready - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; - end + // datapath + if (store_udp_payload_int_to_output) begin + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else if (store_udp_payload_temp_to_output) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (store_udp_payload_int_to_temp) begin + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; end end diff --git a/rtl/udp_mux_4.v b/rtl/udp_mux_4.v index 360e8f54e..4786b73b2 100644 --- a/rtl/udp_mux_4.v +++ b/rtl/udp_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -187,45 +187,45 @@ module udp_mux_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_udp_hdr_ready_reg = 0, input_0_udp_hdr_ready_next; -reg input_1_udp_hdr_ready_reg = 0, input_1_udp_hdr_ready_next; -reg input_2_udp_hdr_ready_reg = 0, input_2_udp_hdr_ready_next; -reg input_3_udp_hdr_ready_reg = 0, input_3_udp_hdr_ready_next; +reg input_0_udp_hdr_ready_reg = 1'b0, input_0_udp_hdr_ready_next; +reg input_1_udp_hdr_ready_reg = 1'b0, input_1_udp_hdr_ready_next; +reg input_2_udp_hdr_ready_reg = 1'b0, input_2_udp_hdr_ready_next; +reg input_3_udp_hdr_ready_reg = 1'b0, input_3_udp_hdr_ready_next; -reg input_0_udp_payload_tready_reg = 0, input_0_udp_payload_tready_next; -reg input_1_udp_payload_tready_reg = 0, input_1_udp_payload_tready_next; -reg input_2_udp_payload_tready_reg = 0, input_2_udp_payload_tready_next; -reg input_3_udp_payload_tready_reg = 0, input_3_udp_payload_tready_next; +reg input_0_udp_payload_tready_reg = 1'b0, input_0_udp_payload_tready_next; +reg input_1_udp_payload_tready_reg = 1'b0, input_1_udp_payload_tready_next; +reg input_2_udp_payload_tready_reg = 1'b0, input_2_udp_payload_tready_next; +reg input_3_udp_payload_tready_reg = 1'b0, input_3_udp_payload_tready_next; -reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; +reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; // internal datapath reg [7:0] output_udp_payload_tdata_int; reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tready_int_reg = 1'b0; reg output_udp_payload_tlast_int; reg output_udp_payload_tuser_int; wire output_udp_payload_tready_int_early; @@ -378,6 +378,29 @@ always @* begin selected_input_udp_length = input_3_udp_length; selected_input_udp_checksum = input_3_udp_checksum; end + default: begin + selected_input_udp_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + selected_input_ip_version = 4'd0; + selected_input_ip_ihl = 4'd0; + selected_input_ip_dscp = 6'd0; + selected_input_ip_ecn = 2'd0; + selected_input_ip_length = 16'd0; + selected_input_ip_identification = 16'd0; + selected_input_ip_flags = 3'd0; + selected_input_ip_fragment_offset = 13'd0; + selected_input_ip_ttl = 8'd0; + selected_input_ip_protocol = 8'd0; + selected_input_ip_header_checksum = 16'd0; + selected_input_ip_source_ip = 32'd0; + selected_input_ip_dest_ip = 32'd0; + selected_input_udp_source_port = 16'd0; + selected_input_udp_dest_port = 16'd0; + selected_input_udp_length = 16'd0; + selected_input_udp_checksum = 16'd0; + end endcase end @@ -417,6 +440,13 @@ always @* begin current_input_tlast = input_3_udp_payload_tlast; current_input_tuser = input_3_udp_payload_tuser; end + default: begin + current_input_tdata = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -429,10 +459,10 @@ always @* begin input_2_udp_hdr_ready_next = input_2_udp_hdr_ready_reg & ~input_2_udp_hdr_valid; input_3_udp_hdr_ready_next = input_3_udp_hdr_ready_reg & ~input_3_udp_hdr_valid; - input_0_udp_payload_tready_next = 0; - input_1_udp_payload_tready_next = 0; - input_2_udp_payload_tready_next = 0; - input_3_udp_payload_tready_next = 0; + input_0_udp_payload_tready_next = 1'b0; + input_1_udp_payload_tready_next = 1'b0; + input_2_udp_payload_tready_next = 1'b0; + input_3_udp_payload_tready_next = 1'b0; output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; output_eth_dest_mac_next = output_eth_dest_mac_reg; @@ -467,13 +497,13 @@ always @* begin select_next = select; case (select_next) - 2'd0: input_0_udp_hdr_ready_next = 1; - 2'd1: input_1_udp_hdr_ready_next = 1; - 2'd2: input_2_udp_hdr_ready_next = 1; - 2'd3: input_3_udp_hdr_ready_next = 1; + 2'd0: input_0_udp_hdr_ready_next = 1'b1; + 2'd1: input_1_udp_hdr_ready_next = 1'b1; + 2'd2: input_2_udp_hdr_ready_next = 1'b1; + 2'd3: input_3_udp_hdr_ready_next = 1'b1; endcase - output_udp_hdr_valid_next = 1; + output_udp_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -513,37 +543,17 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_udp_hdr_ready_reg <= 0; - input_1_udp_hdr_ready_reg <= 0; - input_2_udp_hdr_ready_reg <= 0; - input_3_udp_hdr_ready_reg <= 0; - input_0_udp_payload_tready_reg <= 0; - input_1_udp_payload_tready_reg <= 0; - input_2_udp_payload_tready_reg <= 0; - input_3_udp_payload_tready_reg <= 0; - output_udp_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - output_udp_source_port_reg <= 0; - output_udp_dest_port_reg <= 0; - output_udp_length_reg <= 0; - output_udp_checksum_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_0_udp_hdr_ready_reg <= 1'b0; + input_1_udp_hdr_ready_reg <= 1'b0; + input_2_udp_hdr_ready_reg <= 1'b0; + input_3_udp_hdr_ready_reg <= 1'b0; + input_0_udp_payload_tready_reg <= 1'b0; + input_1_udp_payload_tready_reg <= 1'b0; + input_2_udp_payload_tready_reg <= 1'b0; + input_3_udp_payload_tready_reg <= 1'b0; + output_udp_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -556,89 +566,108 @@ always @(posedge clk) begin input_2_udp_payload_tready_reg <= input_2_udp_payload_tready_next; input_3_udp_payload_tready_reg <= input_3_udp_payload_tready_next; output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; end // output datapath logic -reg [7:0] output_udp_payload_tdata_reg = 0; -reg output_udp_payload_tvalid_reg = 0; -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; +reg [7:0] output_udp_payload_tdata_reg = 8'd0; +reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; +reg output_udp_payload_tlast_reg = 1'b0; +reg output_udp_payload_tuser_reg = 1'b0; -reg [7:0] temp_udp_payload_tdata_reg = 0; -reg temp_udp_payload_tvalid_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +reg [7:0] temp_udp_payload_tdata_reg = 8'd0; +reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; +reg temp_udp_payload_tlast_reg = 1'b0; +reg temp_udp_payload_tuser_reg = 1'b0; + +// datapath control +reg store_udp_payload_int_to_output; +reg store_udp_payload_int_to_temp; +reg store_udp_payload_temp_to_output; assign output_udp_payload_tdata = output_udp_payload_tdata_reg; assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; assign output_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_udp_payload_tuser = output_udp_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + + store_udp_payload_int_to_output = 1'b0; + store_udp_payload_int_to_temp = 1'b0; + store_udp_payload_temp_to_output = 1'b0; + + if (output_udp_payload_tready_int_reg) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_temp = 1'b1; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready + output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = 1'b0; + store_udp_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_udp_payload_tdata_reg <= 0; - output_udp_payload_tvalid_reg <= 0; - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - output_udp_payload_tready_int <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; + output_udp_payload_tvalid_reg <= 1'b0; + output_udp_payload_tready_int_reg <= 1'b0; + temp_udp_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; + output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; + temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + end - if (output_udp_payload_tready_int) begin - // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end - end else if (output_udp_payload_tready) begin - // input is not ready, but output is ready - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; - end + // datapath + if (store_udp_payload_int_to_output) begin + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else if (store_udp_payload_temp_to_output) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (store_udp_payload_int_to_temp) begin + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; end end diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py index 68869d050..7e7cf53d4 100755 --- a/rtl/udp_mux_64.py +++ b/rtl/udp_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -146,42 +146,42 @@ module {{name}} input wire [{{w-1}}:0] select ); -reg [{{w-1}}:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; +reg frame_reg = 1'b0, frame_next; {% for p in ports %} -reg input_{{p}}_udp_hdr_ready_reg = 0, input_{{p}}_udp_hdr_ready_next; +reg input_{{p}}_udp_hdr_ready_reg = 1'b0, input_{{p}}_udp_hdr_ready_next; {%- endfor %} {% for p in ports %} -reg input_{{p}}_udp_payload_tready_reg = 0, input_{{p}}_udp_payload_tready_next; +reg input_{{p}}_udp_payload_tready_reg = 1'b0, input_{{p}}_udp_payload_tready_next; {%- endfor %} reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; // internal datapath reg [63:0] output_udp_payload_tdata_int; reg [7:0] output_udp_payload_tkeep_int; reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tready_int_reg = 1'b0; reg output_udp_payload_tlast_int; reg output_udp_payload_tuser_int; wire output_udp_payload_tready_int_early; @@ -263,6 +263,29 @@ always @* begin selected_input_udp_checksum = input_{{p}}_udp_checksum; end {%- endfor %} + default: begin + selected_input_udp_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + selected_input_ip_version = 4'd0; + selected_input_ip_ihl = 4'd0; + selected_input_ip_dscp = 6'd0; + selected_input_ip_ecn = 2'd0; + selected_input_ip_length = 16'd0; + selected_input_ip_identification = 16'd0; + selected_input_ip_flags = 3'd0; + selected_input_ip_fragment_offset = 13'd0; + selected_input_ip_ttl = 8'd0; + selected_input_ip_protocol = 8'd0; + selected_input_ip_header_checksum = 16'd0; + selected_input_ip_source_ip = 32'd0; + selected_input_ip_dest_ip = 32'd0; + selected_input_udp_source_port = 16'd0; + selected_input_udp_dest_port = 16'd0; + selected_input_udp_length = 16'd0; + selected_input_udp_checksum = 16'd0; + end endcase end @@ -285,6 +308,14 @@ always @* begin current_input_tuser = input_{{p}}_udp_payload_tuser; end {%- endfor %} + default: begin + current_input_tdata = 64'd0; + current_input_tkeep = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -295,7 +326,7 @@ always @* begin input_{{p}}_udp_hdr_ready_next = input_{{p}}_udp_hdr_ready_reg & ~input_{{p}}_udp_hdr_valid; {%- endfor %} {% for p in ports %} - input_{{p}}_udp_payload_tready_next = 0; + input_{{p}}_udp_payload_tready_next = 1'b0; {%- endfor %} output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; @@ -327,16 +358,16 @@ always @* begin end end else if (enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) {%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_udp_hdr_ready_next = 1; + {{w}}'d{{p}}: input_{{p}}_udp_hdr_ready_next = 1'b1; {%- endfor %} endcase - output_udp_hdr_valid_next = 1; + output_udp_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -376,35 +407,15 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; + select_reg <= {{w}}'d0; + frame_reg <= 1'b0; {%- for p in ports %} - input_{{p}}_udp_hdr_ready_reg <= 0; + input_{{p}}_udp_hdr_ready_reg <= 1'b0; {%- endfor %} {%- for p in ports %} - input_{{p}}_udp_payload_tready_reg <= 0; + input_{{p}}_udp_payload_tready_reg <= 1'b0; {%- endfor %} - output_udp_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - output_udp_source_port_reg <= 0; - output_udp_dest_port_reg <= 0; - output_udp_length_reg <= 0; - output_udp_checksum_reg <= 0; + output_udp_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -415,41 +426,47 @@ always @(posedge clk) begin input_{{p}}_udp_payload_tready_reg <= input_{{p}}_udp_payload_tready_next; {%- endfor %} output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; end // output datapath logic -reg [63:0] output_udp_payload_tdata_reg = 0; -reg [7:0] output_udp_payload_tkeep_reg = 0; -reg output_udp_payload_tvalid_reg = 0; -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; +reg [63:0] output_udp_payload_tdata_reg = 64'd0; +reg [7:0] output_udp_payload_tkeep_reg = 8'd0; +reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; +reg output_udp_payload_tlast_reg = 1'b0; +reg output_udp_payload_tuser_reg = 1'b0; -reg [63:0] temp_udp_payload_tdata_reg = 0; -reg [7:0] temp_udp_payload_tkeep_reg = 0; -reg temp_udp_payload_tvalid_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +reg [63:0] temp_udp_payload_tdata_reg = 64'd0; +reg [7:0] temp_udp_payload_tkeep_reg = 8'd0; +reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; +reg temp_udp_payload_tlast_reg = 1'b0; +reg temp_udp_payload_tuser_reg = 1'b0; + +// datapath control +reg store_udp_payload_int_to_output; +reg store_udp_payload_int_to_temp; +reg store_udp_payload_temp_to_output; assign output_udp_payload_tdata = output_udp_payload_tdata_reg; assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; @@ -457,56 +474,66 @@ assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; assign output_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_udp_payload_tuser = output_udp_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + + store_udp_payload_int_to_output = 1'b0; + store_udp_payload_int_to_temp = 1'b0; + store_udp_payload_temp_to_output = 1'b0; + + if (output_udp_payload_tready_int_reg) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_temp = 1'b1; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready + output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = 1'b0; + store_udp_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_udp_payload_tdata_reg <= 0; - output_udp_payload_tkeep_reg <= 0; - output_udp_payload_tvalid_reg <= 0; - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - output_udp_payload_tready_int <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; + output_udp_payload_tvalid_reg <= 1'b0; + output_udp_payload_tready_int_reg <= 1'b0; + temp_udp_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; + output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; + temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + end - if (output_udp_payload_tready_int) begin - // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end - end else if (output_udp_payload_tready) begin - // input is not ready, but output is ready - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; - output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; - end + // datapath + if (store_udp_payload_int_to_output) begin + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else if (store_udp_payload_temp_to_output) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (store_udp_payload_int_to_temp) begin + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; end end diff --git a/rtl/udp_mux_64_4.v b/rtl/udp_mux_64_4.v index e20425c6d..f981cbf8c 100644 --- a/rtl/udp_mux_64_4.v +++ b/rtl/udp_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2015 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 @@ -192,46 +192,46 @@ module udp_mux_64_4 input wire [1:0] select ); -reg [1:0] select_reg = 0, select_next; -reg frame_reg = 0, frame_next; +reg [1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; -reg input_0_udp_hdr_ready_reg = 0, input_0_udp_hdr_ready_next; -reg input_1_udp_hdr_ready_reg = 0, input_1_udp_hdr_ready_next; -reg input_2_udp_hdr_ready_reg = 0, input_2_udp_hdr_ready_next; -reg input_3_udp_hdr_ready_reg = 0, input_3_udp_hdr_ready_next; +reg input_0_udp_hdr_ready_reg = 1'b0, input_0_udp_hdr_ready_next; +reg input_1_udp_hdr_ready_reg = 1'b0, input_1_udp_hdr_ready_next; +reg input_2_udp_hdr_ready_reg = 1'b0, input_2_udp_hdr_ready_next; +reg input_3_udp_hdr_ready_reg = 1'b0, input_3_udp_hdr_ready_next; -reg input_0_udp_payload_tready_reg = 0, input_0_udp_payload_tready_next; -reg input_1_udp_payload_tready_reg = 0, input_1_udp_payload_tready_next; -reg input_2_udp_payload_tready_reg = 0, input_2_udp_payload_tready_next; -reg input_3_udp_payload_tready_reg = 0, input_3_udp_payload_tready_next; +reg input_0_udp_payload_tready_reg = 1'b0, input_0_udp_payload_tready_next; +reg input_1_udp_payload_tready_reg = 1'b0, input_1_udp_payload_tready_next; +reg input_2_udp_payload_tready_reg = 1'b0, input_2_udp_payload_tready_next; +reg input_3_udp_payload_tready_reg = 1'b0, input_3_udp_payload_tready_next; reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 0, output_udp_checksum_next; +reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; +reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; +reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; +reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; +reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; +reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; +reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; +reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; +reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; +reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; +reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; +reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; +reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; +reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; +reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; +reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; +reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; +reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; +reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; +reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; // internal datapath reg [63:0] output_udp_payload_tdata_int; reg [7:0] output_udp_payload_tkeep_int; reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int = 0; +reg output_udp_payload_tready_int_reg = 1'b0; reg output_udp_payload_tlast_int; reg output_udp_payload_tuser_int; wire output_udp_payload_tready_int_early; @@ -384,6 +384,29 @@ always @* begin selected_input_udp_length = input_3_udp_length; selected_input_udp_checksum = input_3_udp_checksum; end + default: begin + selected_input_udp_hdr_valid = 1'b0; + selected_input_eth_dest_mac = 48'd0; + selected_input_eth_src_mac = 48'd0; + selected_input_eth_type = 16'd0; + selected_input_ip_version = 4'd0; + selected_input_ip_ihl = 4'd0; + selected_input_ip_dscp = 6'd0; + selected_input_ip_ecn = 2'd0; + selected_input_ip_length = 16'd0; + selected_input_ip_identification = 16'd0; + selected_input_ip_flags = 3'd0; + selected_input_ip_fragment_offset = 13'd0; + selected_input_ip_ttl = 8'd0; + selected_input_ip_protocol = 8'd0; + selected_input_ip_header_checksum = 16'd0; + selected_input_ip_source_ip = 32'd0; + selected_input_ip_dest_ip = 32'd0; + selected_input_udp_source_port = 16'd0; + selected_input_udp_dest_port = 16'd0; + selected_input_udp_length = 16'd0; + selected_input_udp_checksum = 16'd0; + end endcase end @@ -428,6 +451,14 @@ always @* begin current_input_tlast = input_3_udp_payload_tlast; current_input_tuser = input_3_udp_payload_tuser; end + default: begin + current_input_tdata = 64'd0; + current_input_tkeep = 8'd0; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tuser = 1'b0; + end endcase end @@ -440,10 +471,10 @@ always @* begin input_2_udp_hdr_ready_next = input_2_udp_hdr_ready_reg & ~input_2_udp_hdr_valid; input_3_udp_hdr_ready_next = input_3_udp_hdr_ready_reg & ~input_3_udp_hdr_valid; - input_0_udp_payload_tready_next = 0; - input_1_udp_payload_tready_next = 0; - input_2_udp_payload_tready_next = 0; - input_3_udp_payload_tready_next = 0; + input_0_udp_payload_tready_next = 1'b0; + input_1_udp_payload_tready_next = 1'b0; + input_2_udp_payload_tready_next = 1'b0; + input_3_udp_payload_tready_next = 1'b0; output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; output_eth_dest_mac_next = output_eth_dest_mac_reg; @@ -474,17 +505,17 @@ always @* begin end end else if (enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin // start of frame, grab select value - frame_next = 1; + frame_next = 1'b1; select_next = select; case (select_next) - 2'd0: input_0_udp_hdr_ready_next = 1; - 2'd1: input_1_udp_hdr_ready_next = 1; - 2'd2: input_2_udp_hdr_ready_next = 1; - 2'd3: input_3_udp_hdr_ready_next = 1; + 2'd0: input_0_udp_hdr_ready_next = 1'b1; + 2'd1: input_1_udp_hdr_ready_next = 1'b1; + 2'd2: input_2_udp_hdr_ready_next = 1'b1; + 2'd3: input_3_udp_hdr_ready_next = 1'b1; endcase - output_udp_hdr_valid_next = 1; + output_udp_hdr_valid_next = 1'b1; output_eth_dest_mac_next = selected_input_eth_dest_mac; output_eth_src_mac_next = selected_input_eth_src_mac; output_eth_type_next = selected_input_eth_type; @@ -525,37 +556,17 @@ end always @(posedge clk) begin if (rst) begin - select_reg <= 0; - frame_reg <= 0; - input_0_udp_hdr_ready_reg <= 0; - input_1_udp_hdr_ready_reg <= 0; - input_2_udp_hdr_ready_reg <= 0; - input_3_udp_hdr_ready_reg <= 0; - input_0_udp_payload_tready_reg <= 0; - input_1_udp_payload_tready_reg <= 0; - input_2_udp_payload_tready_reg <= 0; - input_3_udp_payload_tready_reg <= 0; - output_udp_hdr_valid_reg <= 0; - output_eth_dest_mac_reg <= 0; - output_eth_src_mac_reg <= 0; - output_eth_type_reg <= 0; - output_ip_version_reg <= 0; - output_ip_ihl_reg <= 0; - output_ip_dscp_reg <= 0; - output_ip_ecn_reg <= 0; - output_ip_length_reg <= 0; - output_ip_identification_reg <= 0; - output_ip_flags_reg <= 0; - output_ip_fragment_offset_reg <= 0; - output_ip_ttl_reg <= 0; - output_ip_protocol_reg <= 0; - output_ip_header_checksum_reg <= 0; - output_ip_source_ip_reg <= 0; - output_ip_dest_ip_reg <= 0; - output_udp_source_port_reg <= 0; - output_udp_dest_port_reg <= 0; - output_udp_length_reg <= 0; - output_udp_checksum_reg <= 0; + select_reg <= 2'd0; + frame_reg <= 1'b0; + input_0_udp_hdr_ready_reg <= 1'b0; + input_1_udp_hdr_ready_reg <= 1'b0; + input_2_udp_hdr_ready_reg <= 1'b0; + input_3_udp_hdr_ready_reg <= 1'b0; + input_0_udp_payload_tready_reg <= 1'b0; + input_1_udp_payload_tready_reg <= 1'b0; + input_2_udp_payload_tready_reg <= 1'b0; + input_3_udp_payload_tready_reg <= 1'b0; + output_udp_hdr_valid_reg <= 1'b0; end else begin select_reg <= select_next; frame_reg <= frame_next; @@ -568,41 +579,47 @@ always @(posedge clk) begin input_2_udp_payload_tready_reg <= input_2_udp_payload_tready_next; input_3_udp_payload_tready_reg <= input_3_udp_payload_tready_next; output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; end + + output_eth_dest_mac_reg <= output_eth_dest_mac_next; + output_eth_src_mac_reg <= output_eth_src_mac_next; + output_eth_type_reg <= output_eth_type_next; + output_ip_version_reg <= output_ip_version_next; + output_ip_ihl_reg <= output_ip_ihl_next; + output_ip_dscp_reg <= output_ip_dscp_next; + output_ip_ecn_reg <= output_ip_ecn_next; + output_ip_length_reg <= output_ip_length_next; + output_ip_identification_reg <= output_ip_identification_next; + output_ip_flags_reg <= output_ip_flags_next; + output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; + output_ip_ttl_reg <= output_ip_ttl_next; + output_ip_protocol_reg <= output_ip_protocol_next; + output_ip_header_checksum_reg <= output_ip_header_checksum_next; + output_ip_source_ip_reg <= output_ip_source_ip_next; + output_ip_dest_ip_reg <= output_ip_dest_ip_next; + output_udp_source_port_reg <= output_udp_source_port_next; + output_udp_dest_port_reg <= output_udp_dest_port_next; + output_udp_length_reg <= output_udp_length_next; + output_udp_checksum_reg <= output_udp_checksum_next; end // output datapath logic -reg [63:0] output_udp_payload_tdata_reg = 0; -reg [7:0] output_udp_payload_tkeep_reg = 0; -reg output_udp_payload_tvalid_reg = 0; -reg output_udp_payload_tlast_reg = 0; -reg output_udp_payload_tuser_reg = 0; +reg [63:0] output_udp_payload_tdata_reg = 64'd0; +reg [7:0] output_udp_payload_tkeep_reg = 8'd0; +reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; +reg output_udp_payload_tlast_reg = 1'b0; +reg output_udp_payload_tuser_reg = 1'b0; -reg [63:0] temp_udp_payload_tdata_reg = 0; -reg [7:0] temp_udp_payload_tkeep_reg = 0; -reg temp_udp_payload_tvalid_reg = 0; -reg temp_udp_payload_tlast_reg = 0; -reg temp_udp_payload_tuser_reg = 0; +reg [63:0] temp_udp_payload_tdata_reg = 64'd0; +reg [7:0] temp_udp_payload_tkeep_reg = 8'd0; +reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; +reg temp_udp_payload_tlast_reg = 1'b0; +reg temp_udp_payload_tuser_reg = 1'b0; + +// datapath control +reg store_udp_payload_int_to_output; +reg store_udp_payload_int_to_temp; +reg store_udp_payload_temp_to_output; assign output_udp_payload_tdata = output_udp_payload_tdata_reg; assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; @@ -610,56 +627,66 @@ assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; assign output_udp_payload_tlast = output_udp_payload_tlast_reg; assign output_udp_payload_tuser = output_udp_payload_tuser_reg; -// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_reg) | (~temp_udp_payload_tvalid_reg & ~output_udp_payload_tvalid_int); +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + + store_udp_payload_int_to_output = 1'b0; + store_udp_payload_int_to_temp = 1'b0; + store_udp_payload_temp_to_output = 1'b0; + + if (output_udp_payload_tready_int_reg) begin + // input is ready + if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + store_udp_payload_int_to_temp = 1'b1; + end + end else if (output_udp_payload_tready) begin + // input is not ready, but output is ready + output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + temp_udp_payload_tvalid_next = 1'b0; + store_udp_payload_temp_to_output = 1'b1; + end +end always @(posedge clk) begin if (rst) begin - output_udp_payload_tdata_reg <= 0; - output_udp_payload_tkeep_reg <= 0; - output_udp_payload_tvalid_reg <= 0; - output_udp_payload_tlast_reg <= 0; - output_udp_payload_tuser_reg <= 0; - output_udp_payload_tready_int <= 0; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; + output_udp_payload_tvalid_reg <= 1'b0; + output_udp_payload_tready_int_reg <= 1'b0; + temp_udp_payload_tvalid_reg <= 1'b0; end else begin - // transfer sink ready state to source - output_udp_payload_tready_int <= output_udp_payload_tready_int_early; + output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; + output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; + temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + end - if (output_udp_payload_tready_int) begin - // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - temp_udp_payload_tvalid_reg <= output_udp_payload_tvalid_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end - end else if (output_udp_payload_tready) begin - // input is not ready, but output is ready - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; - output_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - temp_udp_payload_tdata_reg <= 0; - temp_udp_payload_tkeep_reg <= 0; - temp_udp_payload_tvalid_reg <= 0; - temp_udp_payload_tlast_reg <= 0; - temp_udp_payload_tuser_reg <= 0; - end + // datapath + if (store_udp_payload_int_to_output) begin + output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + end else if (store_udp_payload_temp_to_output) begin + output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; + output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; + output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; + output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + end + + if (store_udp_payload_int_to_temp) begin + temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; + temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; + temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; + temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; end end From be4034071b9434fd7e7e6fbadec916892746c33a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 5 Jan 2016 00:24:20 -0800 Subject: [PATCH 264/617] Happy new year --- COPYING | 2 +- rtl/arbiter.v | 2 +- rtl/axis_adapter.v | 2 +- rtl/axis_arb_mux.py | 2 +- rtl/axis_arb_mux_4.v | 2 +- rtl/axis_arb_mux_64.py | 2 +- rtl/axis_arb_mux_64_4.v | 2 +- rtl/axis_async_fifo.v | 2 +- rtl/axis_async_fifo_64.v | 2 +- rtl/axis_async_frame_fifo.v | 2 +- rtl/axis_async_frame_fifo_64.v | 2 +- rtl/axis_crosspoint.py | 2 +- rtl/axis_crosspoint_4x4.v | 2 +- rtl/axis_crosspoint_64.py | 2 +- rtl/axis_crosspoint_64_4x4.v | 2 +- rtl/axis_demux.py | 2 +- rtl/axis_demux_4.v | 2 +- rtl/axis_demux_64.py | 2 +- rtl/axis_demux_64_4.v | 2 +- rtl/axis_fifo.v | 2 +- rtl/axis_fifo_64.v | 2 +- rtl/axis_frame_fifo.v | 2 +- rtl/axis_frame_fifo_64.v | 2 +- rtl/axis_frame_join.py | 2 +- rtl/axis_frame_join_4.v | 2 +- rtl/axis_frame_length_adjust.v | 2 +- rtl/axis_frame_length_adjust_fifo.v | 2 +- rtl/axis_frame_length_adjust_fifo_64.v | 2 +- rtl/axis_ll_bridge.v | 2 +- rtl/axis_mux.py | 2 +- rtl/axis_mux_4.v | 2 +- rtl/axis_mux_64.py | 2 +- rtl/axis_mux_64_4.v | 2 +- rtl/axis_rate_limit.v | 2 +- rtl/axis_rate_limit_64.v | 2 +- rtl/axis_register.v | 2 +- rtl/axis_register_64.v | 2 +- rtl/axis_srl_fifo.v | 2 +- rtl/axis_srl_fifo_64.v | 2 +- rtl/axis_srl_register.v | 2 +- rtl/axis_srl_register_64.v | 2 +- rtl/axis_stat_counter.v | 2 +- rtl/axis_tap.v | 2 +- rtl/axis_tap_64.v | 2 +- rtl/ll_axis_bridge.v | 2 +- rtl/priority_encoder.v | 2 +- tb/axis_ep.py | 2 +- tb/ll_ep.py | 2 +- tb/test_arbiter.py | 2 +- tb/test_arbiter.v | 2 +- tb/test_arbiter_rr.py | 2 +- tb/test_arbiter_rr.v | 2 +- tb/test_axis_adapter_64_8.py | 2 +- tb/test_axis_adapter_64_8.v | 2 +- tb/test_axis_adapter_8_64.py | 2 +- tb/test_axis_adapter_8_64.v | 2 +- tb/test_axis_arb_mux_4.py | 2 +- tb/test_axis_arb_mux_4.v | 2 +- tb/test_axis_arb_mux_64_4.py | 2 +- tb/test_axis_arb_mux_64_4.v | 2 +- tb/test_axis_async_fifo.py | 2 +- tb/test_axis_async_fifo.v | 2 +- tb/test_axis_async_fifo_64.py | 2 +- tb/test_axis_async_fifo_64.v | 2 +- tb/test_axis_async_frame_fifo.py | 2 +- tb/test_axis_async_frame_fifo.v | 2 +- tb/test_axis_async_frame_fifo_64.py | 2 +- tb/test_axis_async_frame_fifo_64.v | 2 +- tb/test_axis_crosspoint_4x4.py | 2 +- tb/test_axis_crosspoint_4x4.v | 2 +- tb/test_axis_crosspoint_64_4x4.py | 2 +- tb/test_axis_crosspoint_64_4x4.v | 2 +- tb/test_axis_demux_4.py | 2 +- tb/test_axis_demux_4.v | 2 +- tb/test_axis_demux_64_4.py | 2 +- tb/test_axis_demux_64_4.v | 2 +- tb/test_axis_fifo.py | 2 +- tb/test_axis_fifo.v | 2 +- tb/test_axis_fifo_64.py | 2 +- tb/test_axis_fifo_64.v | 2 +- tb/test_axis_frame_fifo.py | 2 +- tb/test_axis_frame_fifo.v | 2 +- tb/test_axis_frame_fifo_64.py | 2 +- tb/test_axis_frame_fifo_64.v | 2 +- tb/test_axis_frame_join_4.py | 2 +- tb/test_axis_frame_join_4.v | 2 +- tb/test_axis_frame_length_adjust_64.py | 2 +- tb/test_axis_frame_length_adjust_64.v | 2 +- tb/test_axis_frame_length_adjust_8.py | 2 +- tb/test_axis_frame_length_adjust_8.v | 2 +- tb/test_axis_frame_length_adjust_fifo.py | 2 +- tb/test_axis_frame_length_adjust_fifo.v | 2 +- tb/test_axis_frame_length_adjust_fifo_64.py | 2 +- tb/test_axis_frame_length_adjust_fifo_64.v | 2 +- tb/test_axis_ll_bridge.py | 2 +- tb/test_axis_ll_bridge.v | 2 +- tb/test_axis_mux_4.py | 2 +- tb/test_axis_mux_4.v | 2 +- tb/test_axis_mux_64_4.py | 2 +- tb/test_axis_mux_64_4.v | 2 +- tb/test_axis_rate_limit.py | 2 +- tb/test_axis_rate_limit.v | 2 +- tb/test_axis_rate_limit_64.py | 2 +- tb/test_axis_rate_limit_64.v | 2 +- tb/test_axis_register.py | 2 +- tb/test_axis_register.v | 2 +- tb/test_axis_register_64.py | 2 +- tb/test_axis_register_64.v | 2 +- tb/test_axis_srl_fifo.py | 2 +- tb/test_axis_srl_fifo.v | 2 +- tb/test_axis_srl_fifo_64.py | 2 +- tb/test_axis_srl_fifo_64.v | 2 +- tb/test_axis_srl_register.py | 2 +- tb/test_axis_srl_register.v | 2 +- tb/test_axis_srl_register_64.py | 2 +- tb/test_axis_srl_register_64.v | 2 +- tb/test_axis_stat_counter.py | 2 +- tb/test_axis_stat_counter.v | 2 +- tb/test_axis_tap.py | 2 +- tb/test_axis_tap.v | 2 +- tb/test_axis_tap_64.py | 2 +- tb/test_axis_tap_64.v | 2 +- tb/test_ll_axis_bridge.py | 2 +- tb/test_ll_axis_bridge.v | 2 +- tb/test_priority_encoder.py | 2 +- tb/test_priority_encoder.v | 2 +- 126 files changed, 126 insertions(+), 126 deletions(-) diff --git a/COPYING b/COPYING index c36b1255b..fd4ba4a32 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/arbiter.v b/rtl/arbiter.v index 8932b33de..d2b94f5b7 100644 --- a/rtl/arbiter.v +++ b/rtl/arbiter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index c5f4358c5..3ed7e7053 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index b138386bc..c93ca14c7 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_arb_mux_4.v b/rtl/axis_arb_mux_4.v index 56d2afe23..6c9878356 100644 --- a/rtl/axis_arb_mux_4.v +++ b/rtl/axis_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_arb_mux_64.py b/rtl/axis_arb_mux_64.py index 6fcb936d7..0f4500178 100755 --- a/rtl/axis_arb_mux_64.py +++ b/rtl/axis_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_arb_mux_64_4.v b/rtl/axis_arb_mux_64_4.v index b4947e2ef..b0cb5648a 100644 --- a/rtl/axis_arb_mux_64_4.v +++ b/rtl/axis_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 97a572245..90ce78ca6 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index cf5ae7ed3..c6976ec39 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index e2f9d43e1..335458759 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 2a52d9b6e..ada9f6401 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index 5d0367d3c..f1dd1832e 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_crosspoint_4x4.v b/rtl/axis_crosspoint_4x4.v index d2be80b0c..d39c3f31b 100644 --- a/rtl/axis_crosspoint_4x4.v +++ b/rtl/axis_crosspoint_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index bb27fc867..75ff0bba8 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_crosspoint_64_4x4.v b/rtl/axis_crosspoint_64_4x4.v index a241c6993..489fa139b 100644 --- a/rtl/axis_crosspoint_64_4x4.v +++ b/rtl/axis_crosspoint_64_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index 71b37dbae..bbb9bb858 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v index 9d5b83100..803ce3241 100644 --- a/rtl/axis_demux_4.v +++ b/rtl/axis_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index d3f6294f2..b9db42c6d 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_demux_64_4.v b/rtl/axis_demux_64_4.v index f4bb51fc4..6e452ba9d 100644 --- a/rtl/axis_demux_64_4.v +++ b/rtl/axis_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index c34298ac3..2784059e5 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2013-2015 Alex Forencich +Copyright (c) 2013-2016 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 diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v index 4f1d60b1d..decd34b2d 100644 --- a/rtl/axis_fifo_64.v +++ b/rtl/axis_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2013-2015 Alex Forencich +Copyright (c) 2013-2016 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 diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 8111eaa3f..bc5e4fb24 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index 873869ce4..9526da8a4 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index 63f7bd847..b8567969e 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index 82298e3bd..1c9d87483 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_frame_length_adjust.v b/rtl/axis_frame_length_adjust.v index 5b1073a6c..fa36f3ca8 100644 --- a/rtl/axis_frame_length_adjust.v +++ b/rtl/axis_frame_length_adjust.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/axis_frame_length_adjust_fifo.v b/rtl/axis_frame_length_adjust_fifo.v index 9e827084f..84cabffa2 100644 --- a/rtl/axis_frame_length_adjust_fifo.v +++ b/rtl/axis_frame_length_adjust_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/axis_frame_length_adjust_fifo_64.v b/rtl/axis_frame_length_adjust_fifo_64.v index 9d75ab4ca..eb55d62ba 100644 --- a/rtl/axis_frame_length_adjust_fifo_64.v +++ b/rtl/axis_frame_length_adjust_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/axis_ll_bridge.v b/rtl/axis_ll_bridge.v index e095a261a..4b1932e65 100644 --- a/rtl/axis_ll_bridge.v +++ b/rtl/axis_ll_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 95c2ada0b..14aba1a95 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v index b52c17e92..36cd8d457 100644 --- a/rtl/axis_mux_4.v +++ b/rtl/axis_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index bd3b27f3c..83ebffe89 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_mux_64_4.v b/rtl/axis_mux_64_4.v index 11ee9aeb1..69707e607 100644 --- a/rtl/axis_mux_64_4.v +++ b/rtl/axis_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index 835863bfd..937f4bd98 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v index b527a3497..6760cfbda 100644 --- a/rtl/axis_rate_limit_64.v +++ b/rtl/axis_rate_limit_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_register.v b/rtl/axis_register.v index 5c8b2309b..6fece11cc 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v index 45d631850..b12e82147 100644 --- a/rtl/axis_register_64.v +++ b/rtl/axis_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_srl_fifo.v b/rtl/axis_srl_fifo.v index b5b887cd0..236e7585a 100644 --- a/rtl/axis_srl_fifo.v +++ b/rtl/axis_srl_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_srl_fifo_64.v b/rtl/axis_srl_fifo_64.v index 8411b94d1..761e5617a 100644 --- a/rtl/axis_srl_fifo_64.v +++ b/rtl/axis_srl_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_srl_register.v b/rtl/axis_srl_register.v index 2e4ea4731..d26ad74ee 100644 --- a/rtl/axis_srl_register.v +++ b/rtl/axis_srl_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_srl_register_64.v b/rtl/axis_srl_register_64.v index 3c569f596..edf485110 100644 --- a/rtl/axis_srl_register_64.v +++ b/rtl/axis_srl_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index cabc98438..ba47770d0 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_tap.v b/rtl/axis_tap.v index 77165a17c..a881210c1 100644 --- a/rtl/axis_tap.v +++ b/rtl/axis_tap.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/axis_tap_64.v b/rtl/axis_tap_64.v index 0080d5be4..0b8a1a21e 100644 --- a/rtl/axis_tap_64.v +++ b/rtl/axis_tap_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/ll_axis_bridge.v b/rtl/ll_axis_bridge.v index 99733536c..9f572a5e5 100644 --- a/rtl/ll_axis_bridge.v +++ b/rtl/ll_axis_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/priority_encoder.v b/rtl/priority_encoder.v index e0d3c1a41..2d7faa5dd 100644 --- a/rtl/priority_encoder.v +++ b/rtl/priority_encoder.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 70431ad1a..14983f29f 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/ll_ep.py b/tb/ll_ep.py index d69346be6..e480cb65c 100644 --- a/tb/ll_ep.py +++ b/tb/ll_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arbiter.py b/tb/test_arbiter.py index 3ed18d8e8..3886ec8c1 100755 --- a/tb/test_arbiter.py +++ b/tb/test_arbiter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arbiter.v b/tb/test_arbiter.v index 5f206a52d..fd5df4d45 100644 --- a/tb/test_arbiter.v +++ b/tb/test_arbiter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arbiter_rr.py b/tb/test_arbiter_rr.py index 81bcee2b1..162255c94 100755 --- a/tb/test_arbiter_rr.py +++ b/tb/test_arbiter_rr.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arbiter_rr.v b/tb/test_arbiter_rr.v index 93a4cce70..7089bbc53 100644 --- a/tb/test_arbiter_rr.v +++ b/tb/test_arbiter_rr.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index 39cc80003..489f1511b 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_adapter_64_8.v b/tb/test_axis_adapter_64_8.v index be74bbbe5..cb6c13efd 100644 --- a/tb/test_axis_adapter_64_8.v +++ b/tb/test_axis_adapter_64_8.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index cbbf37456..32177f261 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_adapter_8_64.v b/tb/test_axis_adapter_8_64.v index e27187a4d..def892687 100644 --- a/tb/test_axis_adapter_8_64.v +++ b/tb/test_axis_adapter_8_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index 93c9279f1..7f20e6622 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_arb_mux_4.v b/tb/test_axis_arb_mux_4.v index a9a89daf2..533c5f03d 100644 --- a/tb/test_axis_arb_mux_4.v +++ b/tb/test_axis_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_arb_mux_64_4.py b/tb/test_axis_arb_mux_64_4.py index 193832900..55253cb12 100755 --- a/tb/test_axis_arb_mux_64_4.py +++ b/tb/test_axis_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_arb_mux_64_4.v b/tb/test_axis_arb_mux_64_4.v index e4f5db801..7350e2ef3 100644 --- a/tb/test_axis_arb_mux_64_4.v +++ b/tb/test_axis_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index 28f759c5d..caa337868 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_async_fifo.v b/tb/test_axis_async_fifo.v index fe91682a2..0c5c2138d 100644 --- a/tb/test_axis_async_fifo.v +++ b/tb/test_axis_async_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index a973ecc8c..94a45d0ae 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_async_fifo_64.v b/tb/test_axis_async_fifo_64.v index bd49f80fd..280fa8b0d 100644 --- a/tb/test_axis_async_fifo_64.v +++ b/tb/test_axis_async_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index 378e1bc6e..0eff45e0a 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index 9caa8edc3..b2606ca6e 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index e12404f02..dcf0acb00 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index e8b9bbcf6..11e7cbc07 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_crosspoint_4x4.py b/tb/test_axis_crosspoint_4x4.py index 2aba21c6e..5b1e2d3cf 100755 --- a/tb/test_axis_crosspoint_4x4.py +++ b/tb/test_axis_crosspoint_4x4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_crosspoint_4x4.v b/tb/test_axis_crosspoint_4x4.v index 5114ae959..7a49e8b9b 100644 --- a/tb/test_axis_crosspoint_4x4.v +++ b/tb/test_axis_crosspoint_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_crosspoint_64_4x4.py b/tb/test_axis_crosspoint_64_4x4.py index b74702001..cb2f7b44e 100755 --- a/tb/test_axis_crosspoint_64_4x4.py +++ b/tb/test_axis_crosspoint_64_4x4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_crosspoint_64_4x4.v b/tb/test_axis_crosspoint_64_4x4.v index a302ceef8..4a9b9108d 100644 --- a/tb/test_axis_crosspoint_64_4x4.v +++ b/tb/test_axis_crosspoint_64_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py index 948c26776..e652ab9d8 100755 --- a/tb/test_axis_demux_4.py +++ b/tb/test_axis_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_demux_4.v b/tb/test_axis_demux_4.v index 5f58f8627..1711d3ec1 100644 --- a/tb/test_axis_demux_4.v +++ b/tb/test_axis_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_demux_64_4.py b/tb/test_axis_demux_64_4.py index 6138615d5..be1bb472f 100755 --- a/tb/test_axis_demux_64_4.py +++ b/tb/test_axis_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_demux_64_4.v b/tb/test_axis_demux_64_4.v index 6233ac295..b157d0561 100644 --- a/tb/test_axis_demux_64_4.v +++ b/tb/test_axis_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index 19382b3b5..dd58b3809 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_fifo.v b/tb/test_axis_fifo.v index 896274765..076ca27db 100644 --- a/tb/test_axis_fifo.v +++ b/tb/test_axis_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index 9ebbe3e50..431942731 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_fifo_64.v b/tb/test_axis_fifo_64.v index e95a6ed80..4335d7e5c 100644 --- a/tb/test_axis_fifo_64.v +++ b/tb/test_axis_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index d01334821..8f4b8455f 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v index 9ecf98432..912240cc7 100644 --- a/tb/test_axis_frame_fifo.v +++ b/tb/test_axis_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index b37f483ac..46fcb5c4e 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v index e840e8538..45b683a2a 100644 --- a/tb/test_axis_frame_fifo_64.v +++ b/tb/test_axis_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index 483e1b68a..4e2358b36 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_frame_join_4.v b/tb/test_axis_frame_join_4.v index ea280c3d6..efc6c62d0 100644 --- a/tb/test_axis_frame_join_4.v +++ b/tb/test_axis_frame_join_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_frame_length_adjust_64.py b/tb/test_axis_frame_length_adjust_64.py index 96351c3e4..ca00a7d4f 100755 --- a/tb/test_axis_frame_length_adjust_64.py +++ b/tb/test_axis_frame_length_adjust_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_frame_length_adjust_64.v b/tb/test_axis_frame_length_adjust_64.v index 601df06d1..32c9e41f7 100644 --- a/tb/test_axis_frame_length_adjust_64.v +++ b/tb/test_axis_frame_length_adjust_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_frame_length_adjust_8.py b/tb/test_axis_frame_length_adjust_8.py index f077297ce..e5f87fbc4 100755 --- a/tb/test_axis_frame_length_adjust_8.py +++ b/tb/test_axis_frame_length_adjust_8.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_frame_length_adjust_8.v b/tb/test_axis_frame_length_adjust_8.v index fdfc4c2f6..48eb46657 100644 --- a/tb/test_axis_frame_length_adjust_8.v +++ b/tb/test_axis_frame_length_adjust_8.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_frame_length_adjust_fifo.py b/tb/test_axis_frame_length_adjust_fifo.py index bafea3092..a84a15a57 100755 --- a/tb/test_axis_frame_length_adjust_fifo.py +++ b/tb/test_axis_frame_length_adjust_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_frame_length_adjust_fifo.v b/tb/test_axis_frame_length_adjust_fifo.v index 34f604275..b18ce0ffd 100644 --- a/tb/test_axis_frame_length_adjust_fifo.v +++ b/tb/test_axis_frame_length_adjust_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_frame_length_adjust_fifo_64.py b/tb/test_axis_frame_length_adjust_fifo_64.py index caf985e6b..2bbffe704 100755 --- a/tb/test_axis_frame_length_adjust_fifo_64.py +++ b/tb/test_axis_frame_length_adjust_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_frame_length_adjust_fifo_64.v b/tb/test_axis_frame_length_adjust_fifo_64.v index 80dc558c4..74a8f1cb0 100644 --- a/tb/test_axis_frame_length_adjust_fifo_64.v +++ b/tb/test_axis_frame_length_adjust_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_ll_bridge.py b/tb/test_axis_ll_bridge.py index c531e16a5..069fe06cc 100755 --- a/tb/test_axis_ll_bridge.py +++ b/tb/test_axis_ll_bridge.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_ll_bridge.v b/tb/test_axis_ll_bridge.v index 680b570b9..6435a13f3 100644 --- a/tb/test_axis_ll_bridge.v +++ b/tb/test_axis_ll_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py index 7a1d1fc3c..21e176689 100755 --- a/tb/test_axis_mux_4.py +++ b/tb/test_axis_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_mux_4.v b/tb/test_axis_mux_4.v index 6fcbc7e6b..775da897f 100644 --- a/tb/test_axis_mux_4.v +++ b/tb/test_axis_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_mux_64_4.py b/tb/test_axis_mux_64_4.py index 8deb96e93..b37ee42ea 100755 --- a/tb/test_axis_mux_64_4.py +++ b/tb/test_axis_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_mux_64_4.v b/tb/test_axis_mux_64_4.v index 3209d64ac..fdb83d7d4 100644 --- a/tb/test_axis_mux_64_4.v +++ b/tb/test_axis_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index 913b8ed2e..d35fd24b0 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_rate_limit.v b/tb/test_axis_rate_limit.v index a03f8f83a..eb245d880 100644 --- a/tb/test_axis_rate_limit.v +++ b/tb/test_axis_rate_limit.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index 69dcbcfc1..27fa4a567 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_rate_limit_64.v b/tb/test_axis_rate_limit_64.v index 71644a0da..c7577530f 100644 --- a/tb/test_axis_rate_limit_64.v +++ b/tb/test_axis_rate_limit_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py index acea44d44..3b12059ff 100755 --- a/tb/test_axis_register.py +++ b/tb/test_axis_register.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_register.v b/tb/test_axis_register.v index b442a3604..fe3ed4ee1 100644 --- a/tb/test_axis_register.v +++ b/tb/test_axis_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py index 986201bce..91950b2d1 100755 --- a/tb/test_axis_register_64.py +++ b/tb/test_axis_register_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_register_64.v b/tb/test_axis_register_64.v index 6b2b0e700..c8ed5222f 100644 --- a/tb/test_axis_register_64.v +++ b/tb/test_axis_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py index 0f4faa28f..b74cfda83 100755 --- a/tb/test_axis_srl_fifo.py +++ b/tb/test_axis_srl_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_srl_fifo.v b/tb/test_axis_srl_fifo.v index 596ba10b5..efc030088 100644 --- a/tb/test_axis_srl_fifo.v +++ b/tb/test_axis_srl_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py index ee7004a5f..5215823bd 100755 --- a/tb/test_axis_srl_fifo_64.py +++ b/tb/test_axis_srl_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_srl_fifo_64.v b/tb/test_axis_srl_fifo_64.v index e435176e8..8239f55e6 100644 --- a/tb/test_axis_srl_fifo_64.v +++ b/tb/test_axis_srl_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_srl_register.py b/tb/test_axis_srl_register.py index 25e529de7..ca08a3ebd 100755 --- a/tb/test_axis_srl_register.py +++ b/tb/test_axis_srl_register.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_srl_register.v b/tb/test_axis_srl_register.v index dccb5ff43..38f440735 100644 --- a/tb/test_axis_srl_register.v +++ b/tb/test_axis_srl_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_srl_register_64.py b/tb/test_axis_srl_register_64.py index 13d5ef4ce..2e28e566c 100755 --- a/tb/test_axis_srl_register_64.py +++ b/tb/test_axis_srl_register_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_srl_register_64.v b/tb/test_axis_srl_register_64.v index 1df9036da..dd703dafd 100644 --- a/tb/test_axis_srl_register_64.v +++ b/tb/test_axis_srl_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index a84d34fdf..eb61deaee 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v index c8f1bdf87..f896b0f9e 100644 --- a/tb/test_axis_stat_counter.v +++ b/tb/test_axis_stat_counter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_tap.py b/tb/test_axis_tap.py index 621bd822d..3f4f44d28 100755 --- a/tb/test_axis_tap.py +++ b/tb/test_axis_tap.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_tap.v b/tb/test_axis_tap.v index fab77189e..412b1d939 100644 --- a/tb/test_axis_tap.v +++ b/tb/test_axis_tap.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_tap_64.py b/tb/test_axis_tap_64.py index f8ef3b01e..153c5063a 100755 --- a/tb/test_axis_tap_64.py +++ b/tb/test_axis_tap_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_tap_64.v b/tb/test_axis_tap_64.v index a9a9e4d14..435997b61 100644 --- a/tb/test_axis_tap_64.v +++ b/tb/test_axis_tap_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_ll_axis_bridge.py b/tb/test_ll_axis_bridge.py index 229fdc1dd..763fbe07d 100755 --- a/tb/test_ll_axis_bridge.py +++ b/tb/test_ll_axis_bridge.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ll_axis_bridge.v b/tb/test_ll_axis_bridge.v index 573fec7c5..8ba505b2b 100644 --- a/tb/test_ll_axis_bridge.v +++ b/tb/test_ll_axis_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_priority_encoder.py b/tb/test_priority_encoder.py index 915759e9a..082834b2e 100755 --- a/tb/test_priority_encoder.py +++ b/tb/test_priority_encoder.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_priority_encoder.v b/tb/test_priority_encoder.v index af7f07882..a88e74236 100644 --- a/tb/test_priority_encoder.v +++ b/tb/test_priority_encoder.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 From 9c01e114b42255c97368f69a2c3a2e8aefe7ff2e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 5 Jan 2016 00:34:32 -0800 Subject: [PATCH 265/617] Happy new year --- COPYING | 2 +- rtl/arp.v | 2 +- rtl/arp_64.v | 2 +- rtl/arp_cache.v | 2 +- rtl/arp_eth_rx.v | 2 +- rtl/arp_eth_rx_64.v | 2 +- rtl/arp_eth_tx.v | 2 +- rtl/arp_eth_tx_64.v | 2 +- rtl/axis_eth_fcs.v | 2 +- rtl/axis_eth_fcs_64.v | 2 +- rtl/axis_eth_fcs_check.v | 2 +- rtl/axis_eth_fcs_check_64.v | 2 +- rtl/axis_eth_fcs_insert.v | 2 +- rtl/axis_eth_fcs_insert_64.v | 2 +- rtl/eth_arb_mux.py | 2 +- rtl/eth_arb_mux_2.v | 2 +- rtl/eth_arb_mux_4.v | 2 +- rtl/eth_arb_mux_64.py | 2 +- rtl/eth_arb_mux_64_2.v | 2 +- rtl/eth_arb_mux_64_4.v | 2 +- rtl/eth_axis_rx.v | 2 +- rtl/eth_axis_rx_64.v | 2 +- rtl/eth_axis_tx.v | 2 +- rtl/eth_axis_tx_64.v | 2 +- rtl/eth_crc_16.v | 2 +- rtl/eth_crc_24.v | 2 +- rtl/eth_crc_32.v | 2 +- rtl/eth_crc_40.v | 2 +- rtl/eth_crc_48.v | 2 +- rtl/eth_crc_56.v | 2 +- rtl/eth_crc_64.v | 2 +- rtl/eth_crc_8.v | 2 +- rtl/eth_demux.py | 2 +- rtl/eth_demux_4.v | 2 +- rtl/eth_demux_64.py | 2 +- rtl/eth_demux_64_4.v | 2 +- rtl/eth_mac_10g.v | 2 +- rtl/eth_mac_10g_fifo.v | 2 +- rtl/eth_mac_10g_rx.v | 2 +- rtl/eth_mac_10g_tx.v | 2 +- rtl/eth_mac_1g.v | 2 +- rtl/eth_mac_1g_fifo.v | 2 +- rtl/eth_mac_1g_rx.v | 2 +- rtl/eth_mac_1g_tx.v | 2 +- rtl/eth_mux.py | 2 +- rtl/eth_mux_2.v | 2 +- rtl/eth_mux_4.v | 2 +- rtl/eth_mux_64.py | 2 +- rtl/eth_mux_64_2.v | 2 +- rtl/eth_mux_64_4.v | 2 +- rtl/gmii_phy_if.v | 2 +- rtl/ip.v | 2 +- rtl/ip_64.v | 2 +- rtl/ip_arb_mux.py | 2 +- rtl/ip_arb_mux_2.v | 2 +- rtl/ip_arb_mux_4.v | 2 +- rtl/ip_arb_mux_64.py | 2 +- rtl/ip_arb_mux_64_2.v | 2 +- rtl/ip_arb_mux_64_4.v | 2 +- rtl/ip_complete.v | 2 +- rtl/ip_complete_64.v | 2 +- rtl/ip_demux.py | 2 +- rtl/ip_demux_4.v | 2 +- rtl/ip_demux_64.py | 2 +- rtl/ip_demux_64_4.v | 2 +- rtl/ip_eth_rx.v | 2 +- rtl/ip_eth_rx_64.v | 2 +- rtl/ip_eth_tx.v | 2 +- rtl/ip_eth_tx_64.v | 2 +- rtl/ip_mux.py | 2 +- rtl/ip_mux_2.v | 2 +- rtl/ip_mux_4.v | 2 +- rtl/ip_mux_64.py | 2 +- rtl/ip_mux_64_2.v | 2 +- rtl/ip_mux_64_4.v | 2 +- rtl/udp.v | 2 +- rtl/udp_64.v | 2 +- rtl/udp_arb_mux.py | 2 +- rtl/udp_arb_mux_4.v | 2 +- rtl/udp_arb_mux_64.py | 2 +- rtl/udp_arb_mux_64_4.v | 2 +- rtl/udp_complete.v | 2 +- rtl/udp_complete_64.v | 2 +- rtl/udp_demux.py | 2 +- rtl/udp_demux_4.v | 2 +- rtl/udp_demux_64.py | 2 +- rtl/udp_demux_64_4.v | 2 +- rtl/udp_ip_rx.v | 2 +- rtl/udp_ip_rx_64.v | 2 +- rtl/udp_ip_tx.v | 2 +- rtl/udp_ip_tx_64.v | 2 +- rtl/udp_mux.py | 2 +- rtl/udp_mux_4.v | 2 +- rtl/udp_mux_64.py | 2 +- rtl/udp_mux_64_4.v | 2 +- tb/arp_ep.py | 2 +- tb/eth_ep.py | 2 +- tb/gmii_ep.py | 2 +- tb/ip_ep.py | 2 +- tb/ll_ep.py | 2 +- tb/test_arp.py | 2 +- tb/test_arp.v | 2 +- tb/test_arp_64.py | 2 +- tb/test_arp_64.v | 2 +- tb/test_arp_cache.py | 2 +- tb/test_arp_cache.v | 2 +- tb/test_arp_eth_rx.py | 2 +- tb/test_arp_eth_rx.v | 2 +- tb/test_arp_eth_rx_64.py | 2 +- tb/test_arp_eth_rx_64.v | 2 +- tb/test_arp_eth_tx.py | 2 +- tb/test_arp_eth_tx.v | 2 +- tb/test_arp_eth_tx_64.py | 2 +- tb/test_arp_eth_tx_64.v | 2 +- tb/test_axis_eth_fcs.py | 2 +- tb/test_axis_eth_fcs.v | 2 +- tb/test_axis_eth_fcs_64.py | 2 +- tb/test_axis_eth_fcs_64.v | 2 +- tb/test_axis_eth_fcs_check.py | 2 +- tb/test_axis_eth_fcs_check.v | 2 +- tb/test_axis_eth_fcs_check_64.py | 2 +- tb/test_axis_eth_fcs_check_64.v | 2 +- tb/test_axis_eth_fcs_insert.py | 2 +- tb/test_axis_eth_fcs_insert.v | 2 +- tb/test_axis_eth_fcs_insert_64.py | 2 +- tb/test_axis_eth_fcs_insert_64.v | 2 +- tb/test_axis_eth_fcs_insert_64_pad.py | 2 +- tb/test_axis_eth_fcs_insert_64_pad.v | 2 +- tb/test_axis_eth_fcs_insert_pad.py | 2 +- tb/test_axis_eth_fcs_insert_pad.v | 2 +- tb/test_eth_arb_mux_4.py | 2 +- tb/test_eth_arb_mux_4.v | 2 +- tb/test_eth_arb_mux_64_4.py | 2 +- tb/test_eth_arb_mux_64_4.v | 2 +- tb/test_eth_axis_rx.py | 2 +- tb/test_eth_axis_rx.v | 2 +- tb/test_eth_axis_rx_64.py | 2 +- tb/test_eth_axis_rx_64.v | 2 +- tb/test_eth_axis_tx.py | 2 +- tb/test_eth_axis_tx.v | 2 +- tb/test_eth_axis_tx_64.py | 2 +- tb/test_eth_axis_tx_64.v | 2 +- tb/test_eth_demux_4.py | 2 +- tb/test_eth_demux_4.v | 2 +- tb/test_eth_demux_64_4.py | 2 +- tb/test_eth_demux_64_4.v | 2 +- tb/test_eth_mac_10g.py | 2 +- tb/test_eth_mac_10g.v | 2 +- tb/test_eth_mac_10g_fifo.py | 2 +- tb/test_eth_mac_10g_fifo.v | 2 +- tb/test_eth_mac_10g_rx.py | 2 +- tb/test_eth_mac_10g_rx.v | 2 +- tb/test_eth_mac_10g_tx.py | 2 +- tb/test_eth_mac_10g_tx.v | 2 +- tb/test_eth_mac_1g.py | 2 +- tb/test_eth_mac_1g.v | 2 +- tb/test_eth_mac_1g_fifo.py | 2 +- tb/test_eth_mac_1g_fifo.v | 2 +- tb/test_eth_mac_1g_rx.py | 2 +- tb/test_eth_mac_1g_rx.v | 2 +- tb/test_eth_mac_1g_tx.py | 2 +- tb/test_eth_mac_1g_tx.v | 2 +- tb/test_eth_mux_4.py | 2 +- tb/test_eth_mux_4.v | 2 +- tb/test_eth_mux_64_4.py | 2 +- tb/test_eth_mux_64_4.v | 2 +- tb/test_ip.py | 2 +- tb/test_ip.v | 2 +- tb/test_ip_64.py | 2 +- tb/test_ip_64.v | 2 +- tb/test_ip_arb_mux_4.py | 2 +- tb/test_ip_arb_mux_4.v | 2 +- tb/test_ip_arb_mux_64_4.py | 2 +- tb/test_ip_arb_mux_64_4.v | 2 +- tb/test_ip_complete.py | 2 +- tb/test_ip_complete.v | 2 +- tb/test_ip_complete_64.py | 2 +- tb/test_ip_complete_64.v | 2 +- tb/test_ip_demux_4.py | 2 +- tb/test_ip_demux_4.v | 2 +- tb/test_ip_demux_64_4.py | 2 +- tb/test_ip_demux_64_4.v | 2 +- tb/test_ip_eth_rx.py | 2 +- tb/test_ip_eth_rx.v | 2 +- tb/test_ip_eth_rx_64.py | 2 +- tb/test_ip_eth_rx_64.v | 2 +- tb/test_ip_eth_tx.py | 2 +- tb/test_ip_eth_tx.v | 2 +- tb/test_ip_eth_tx_64.py | 2 +- tb/test_ip_eth_tx_64.v | 2 +- tb/test_ip_mux_4.py | 2 +- tb/test_ip_mux_4.v | 2 +- tb/test_ip_mux_64_4.py | 2 +- tb/test_ip_mux_64_4.v | 2 +- tb/test_udp.py | 2 +- tb/test_udp.v | 2 +- tb/test_udp_64.py | 2 +- tb/test_udp_64.v | 2 +- tb/test_udp_arb_mux_4.py | 2 +- tb/test_udp_arb_mux_4.v | 2 +- tb/test_udp_arb_mux_64_4.py | 2 +- tb/test_udp_arb_mux_64_4.v | 2 +- tb/test_udp_complete.py | 2 +- tb/test_udp_complete.v | 2 +- tb/test_udp_complete_64.py | 2 +- tb/test_udp_complete_64.v | 2 +- tb/test_udp_demux_4.py | 2 +- tb/test_udp_demux_4.v | 2 +- tb/test_udp_demux_64_4.py | 2 +- tb/test_udp_demux_64_4.v | 2 +- tb/test_udp_ip_rx.py | 2 +- tb/test_udp_ip_rx.v | 2 +- tb/test_udp_ip_rx_64.py | 2 +- tb/test_udp_ip_rx_64.v | 2 +- tb/test_udp_ip_tx.py | 2 +- tb/test_udp_ip_tx.v | 2 +- tb/test_udp_ip_tx_64.py | 2 +- tb/test_udp_ip_tx_64.v | 2 +- tb/test_udp_mux_4.py | 2 +- tb/test_udp_mux_4.v | 2 +- tb/test_udp_mux_64_4.py | 2 +- tb/test_udp_mux_64_4.v | 2 +- tb/udp_ep.py | 2 +- tb/xgmii_ep.py | 2 +- 224 files changed, 224 insertions(+), 224 deletions(-) diff --git a/COPYING b/COPYING index c36b1255b..fd4ba4a32 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/arp.v b/rtl/arp.v index 3b795f998..189a6bd20 100644 --- a/rtl/arp.v +++ b/rtl/arp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/arp_64.v b/rtl/arp_64.v index 9cfb56bd1..e4c4afa5d 100644 --- a/rtl/arp_64.v +++ b/rtl/arp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/arp_cache.v b/rtl/arp_cache.v index 88c844311..967843e45 100644 --- a/rtl/arp_cache.v +++ b/rtl/arp_cache.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index 0c6e61b9f..d95d3096b 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index 1c4e6d9ae..3ada52c30 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index e0674be27..911facf32 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 -2015Alex Forencich +Copyright (c) 2014-2016 -2015Alex 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 diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index 64c0e5660..ad0950427 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/axis_eth_fcs.v b/rtl/axis_eth_fcs.v index 4d099bc0d..eed18b78d 100644 --- a/rtl/axis_eth_fcs.v +++ b/rtl/axis_eth_fcs.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/axis_eth_fcs_64.v b/rtl/axis_eth_fcs_64.v index 629d77bd0..71100681f 100644 --- a/rtl/axis_eth_fcs_64.v +++ b/rtl/axis_eth_fcs_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v index 044427a2f..bbe788385 100644 --- a/rtl/axis_eth_fcs_check.v +++ b/rtl/axis_eth_fcs_check.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index 0fcc8c560..bdcb01d02 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v index 347c3d304..e6e381c3e 100644 --- a/rtl/axis_eth_fcs_insert.v +++ b/rtl/axis_eth_fcs_insert.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/axis_eth_fcs_insert_64.v b/rtl/axis_eth_fcs_insert_64.v index b508bffde..034ad3c01 100644 --- a/rtl/axis_eth_fcs_insert_64.v +++ b/rtl/axis_eth_fcs_insert_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/eth_arb_mux.py b/rtl/eth_arb_mux.py index 2ceaec636..139a3343f 100755 --- a/rtl/eth_arb_mux.py +++ b/rtl/eth_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_arb_mux_2.v b/rtl/eth_arb_mux_2.v index 80137efde..89157d384 100644 --- a/rtl/eth_arb_mux_2.v +++ b/rtl/eth_arb_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_arb_mux_4.v b/rtl/eth_arb_mux_4.v index 71e75e091..ef2f5c2cd 100644 --- a/rtl/eth_arb_mux_4.v +++ b/rtl/eth_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_arb_mux_64.py b/rtl/eth_arb_mux_64.py index a4cc9150f..0b9d54c45 100755 --- a/rtl/eth_arb_mux_64.py +++ b/rtl/eth_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_arb_mux_64_2.v b/rtl/eth_arb_mux_64_2.v index bcdb04c58..b28b82dd0 100644 --- a/rtl/eth_arb_mux_64_2.v +++ b/rtl/eth_arb_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_arb_mux_64_4.v b/rtl/eth_arb_mux_64_4.v index 84a7ab1ff..da3e27c35 100644 --- a/rtl/eth_arb_mux_64_4.v +++ b/rtl/eth_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index 503fd3130..ca71f524c 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index 77f1f4d84..c96daa0e8 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index 3cc6bbd99..2b057f093 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index fb4c4a3af..a0da3a5ec 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_crc_16.v b/rtl/eth_crc_16.v index a06b69c3d..c15a8ba31 100644 --- a/rtl/eth_crc_16.v +++ b/rtl/eth_crc_16.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_crc_24.v b/rtl/eth_crc_24.v index 0b75df7bc..3b75df250 100644 --- a/rtl/eth_crc_24.v +++ b/rtl/eth_crc_24.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_crc_32.v b/rtl/eth_crc_32.v index 690560c73..76713e44c 100644 --- a/rtl/eth_crc_32.v +++ b/rtl/eth_crc_32.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_crc_40.v b/rtl/eth_crc_40.v index 56145cfa6..a3cbf9809 100644 --- a/rtl/eth_crc_40.v +++ b/rtl/eth_crc_40.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_crc_48.v b/rtl/eth_crc_48.v index e1ddbfe3d..d733c27f9 100644 --- a/rtl/eth_crc_48.v +++ b/rtl/eth_crc_48.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_crc_56.v b/rtl/eth_crc_56.v index 51871564b..83961de03 100644 --- a/rtl/eth_crc_56.v +++ b/rtl/eth_crc_56.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_crc_64.v b/rtl/eth_crc_64.v index 2979381ad..3ddb549b2 100644 --- a/rtl/eth_crc_64.v +++ b/rtl/eth_crc_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_crc_8.v b/rtl/eth_crc_8.v index 320f55781..8f4525ac3 100644 --- a/rtl/eth_crc_8.v +++ b/rtl/eth_crc_8.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py index 4a5c44f48..46b6557f9 100755 --- a/rtl/eth_demux.py +++ b/rtl/eth_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_demux_4.v b/rtl/eth_demux_4.v index e194a8081..927caa77f 100644 --- a/rtl/eth_demux_4.v +++ b/rtl/eth_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py index 993cc2af5..05e607423 100755 --- a/rtl/eth_demux_64.py +++ b/rtl/eth_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_demux_64_4.v b/rtl/eth_demux_64_4.v index dabd2a350..624338a2a 100644 --- a/rtl/eth_demux_64_4.v +++ b/rtl/eth_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index f09c4da60..34d0361ee 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index d0a28730a..1c370342b 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index 333d2d5ca..7118f727e 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 32caeb5a1..20f63c963 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v index 848630e5b..b801c83e4 100644 --- a/rtl/eth_mac_1g.v +++ b/rtl/eth_mac_1g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index db4faeaf9..f7a3dbc20 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v index 58522e692..fd7128b92 100644 --- a/rtl/eth_mac_1g_rx.v +++ b/rtl/eth_mac_1g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/eth_mac_1g_tx.v b/rtl/eth_mac_1g_tx.v index 100ac6252..b101ec096 100644 --- a/rtl/eth_mac_1g_tx.v +++ b/rtl/eth_mac_1g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index ce0e54034..1ae82094a 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_mux_2.v b/rtl/eth_mux_2.v index 12b0330eb..0048af97a 100644 --- a/rtl/eth_mux_2.v +++ b/rtl/eth_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v index 3bc5eea31..26d5cbe61 100644 --- a/rtl/eth_mux_4.v +++ b/rtl/eth_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index b4c5aa460..9ffad95fc 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_mux_64_2.v b/rtl/eth_mux_64_2.v index 7281e7d93..e17238c2b 100644 --- a/rtl/eth_mux_64_2.v +++ b/rtl/eth_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v index e3afd6267..bd1591416 100644 --- a/rtl/eth_mux_64_4.v +++ b/rtl/eth_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/gmii_phy_if.v b/rtl/gmii_phy_if.v index cc3cf67fc..ebfb83e3f 100644 --- a/rtl/gmii_phy_if.v +++ b/rtl/gmii_phy_if.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/rtl/ip.v b/rtl/ip.v index 7cdcfc6d2..22cdbdbbf 100644 --- a/rtl/ip.v +++ b/rtl/ip.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_64.v b/rtl/ip_64.v index d9d20277e..e6d4cebc4 100644 --- a/rtl/ip_64.v +++ b/rtl/ip_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_arb_mux.py b/rtl/ip_arb_mux.py index 26b461e2f..6c0781176 100755 --- a/rtl/ip_arb_mux.py +++ b/rtl/ip_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_arb_mux_2.v b/rtl/ip_arb_mux_2.v index e1e980642..be9789167 100644 --- a/rtl/ip_arb_mux_2.v +++ b/rtl/ip_arb_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_arb_mux_4.v b/rtl/ip_arb_mux_4.v index d181064ef..e9bee4c30 100644 --- a/rtl/ip_arb_mux_4.v +++ b/rtl/ip_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_arb_mux_64.py b/rtl/ip_arb_mux_64.py index 38b03032a..750e22dd0 100755 --- a/rtl/ip_arb_mux_64.py +++ b/rtl/ip_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_arb_mux_64_2.v b/rtl/ip_arb_mux_64_2.v index f210eaba4..6473e7838 100644 --- a/rtl/ip_arb_mux_64_2.v +++ b/rtl/ip_arb_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_arb_mux_64_4.v b/rtl/ip_arb_mux_64_4.v index 0803be0c0..dc4320b97 100644 --- a/rtl/ip_arb_mux_64_4.v +++ b/rtl/ip_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_complete.v b/rtl/ip_complete.v index 17ffb3fab..ee1363f37 100644 --- a/rtl/ip_complete.v +++ b/rtl/ip_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_complete_64.v b/rtl/ip_complete_64.v index a458f5d05..303535c58 100644 --- a/rtl/ip_complete_64.v +++ b/rtl/ip_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py index ccd1d2c54..5744ce813 100755 --- a/rtl/ip_demux.py +++ b/rtl/ip_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_demux_4.v b/rtl/ip_demux_4.v index 8bb3e99ed..5acae1b46 100644 --- a/rtl/ip_demux_4.v +++ b/rtl/ip_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py index 305629777..5935da9fe 100755 --- a/rtl/ip_demux_64.py +++ b/rtl/ip_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_demux_64_4.v b/rtl/ip_demux_64_4.v index 858190cdb..11cb63783 100644 --- a/rtl/ip_demux_64_4.v +++ b/rtl/ip_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index 4e23bec02..b6afd7cdc 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 219c7569d..2dcaef359 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index b020b7c7b..f9ce364de 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index bd55af8cd..eda4385b6 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py index bf2ce3286..26010cb86 100755 --- a/rtl/ip_mux.py +++ b/rtl/ip_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_mux_2.v b/rtl/ip_mux_2.v index ac8d90cb4..1d694eb67 100644 --- a/rtl/ip_mux_2.v +++ b/rtl/ip_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_mux_4.v b/rtl/ip_mux_4.v index c4ef12de4..7912099fd 100644 --- a/rtl/ip_mux_4.v +++ b/rtl/ip_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py index 75670ff48..4bde325d5 100755 --- a/rtl/ip_mux_64.py +++ b/rtl/ip_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_mux_64_2.v b/rtl/ip_mux_64_2.v index 3b58015f2..bca3424dd 100644 --- a/rtl/ip_mux_64_2.v +++ b/rtl/ip_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/ip_mux_64_4.v b/rtl/ip_mux_64_4.v index 7fc063a1e..4948e2b6a 100644 --- a/rtl/ip_mux_64_4.v +++ b/rtl/ip_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp.v b/rtl/udp.v index 24ed0ab22..23b3508c6 100644 --- a/rtl/udp.v +++ b/rtl/udp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_64.v b/rtl/udp_64.v index c0c90ea4b..52b5b73a8 100644 --- a/rtl/udp_64.v +++ b/rtl/udp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_arb_mux.py b/rtl/udp_arb_mux.py index 08868ec33..5a688117b 100755 --- a/rtl/udp_arb_mux.py +++ b/rtl/udp_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_arb_mux_4.v b/rtl/udp_arb_mux_4.v index 9d926e99f..fc42058e6 100644 --- a/rtl/udp_arb_mux_4.v +++ b/rtl/udp_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_arb_mux_64.py b/rtl/udp_arb_mux_64.py index 3ff26816d..1bb0ba400 100755 --- a/rtl/udp_arb_mux_64.py +++ b/rtl/udp_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_arb_mux_64_4.v b/rtl/udp_arb_mux_64_4.v index 60bb9c5be..8ccd9c437 100644 --- a/rtl/udp_arb_mux_64_4.v +++ b/rtl/udp_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v index 02f6ee92c..3d1195442 100644 --- a/rtl/udp_complete.v +++ b/rtl/udp_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v index 69b8ae442..5ae64483c 100644 --- a/rtl/udp_complete_64.v +++ b/rtl/udp_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py index 8ee3dc0c8..9f7403583 100755 --- a/rtl/udp_demux.py +++ b/rtl/udp_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_demux_4.v b/rtl/udp_demux_4.v index 1dc424652..23c747dd2 100644 --- a/rtl/udp_demux_4.v +++ b/rtl/udp_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py index afde8173f..c85b19586 100755 --- a/rtl/udp_demux_64.py +++ b/rtl/udp_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_demux_64_4.v b/rtl/udp_demux_64_4.v index f596eb502..ba0de5c07 100644 --- a/rtl/udp_demux_64_4.v +++ b/rtl/udp_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v index 5820a0e7f..2468d010f 100644 --- a/rtl/udp_ip_rx.v +++ b/rtl/udp_ip_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index 873a488ca..ae0e5f52c 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index 033783cb6..cce00d96d 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index aee1350c8..2beb717e6 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py index eccaa18bd..b21658aea 100755 --- a/rtl/udp_mux.py +++ b/rtl/udp_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_mux_4.v b/rtl/udp_mux_4.v index 4786b73b2..e6739e6c4 100644 --- a/rtl/udp_mux_4.v +++ b/rtl/udp_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py index 7e7cf53d4..5177650d4 100755 --- a/rtl/udp_mux_64.py +++ b/rtl/udp_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/rtl/udp_mux_64_4.v b/rtl/udp_mux_64_4.v index f981cbf8c..0e89faa81 100644 --- a/rtl/udp_mux_64_4.v +++ b/rtl/udp_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2015 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/arp_ep.py b/tb/arp_ep.py index f7909637c..209ec2862 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/eth_ep.py b/tb/eth_ep.py index 185b1ac25..0dc611e90 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index 379e4a24d..528be9ab2 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/ip_ep.py b/tb/ip_ep.py index ab216fe37..ec13aa320 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/ll_ep.py b/tb/ll_ep.py index d69346be6..e480cb65c 100644 --- a/tb/ll_ep.py +++ b/tb/ll_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp.py b/tb/test_arp.py index 03e633aeb..79f6a4eed 100755 --- a/tb/test_arp.py +++ b/tb/test_arp.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp.v b/tb/test_arp.v index 2e64a6b41..437658754 100644 --- a/tb/test_arp.v +++ b/tb/test_arp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_64.py b/tb/test_arp_64.py index 2a4b3626b..efff251a3 100755 --- a/tb/test_arp_64.py +++ b/tb/test_arp_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_64.v b/tb/test_arp_64.v index dd4113205..ba9b581c0 100644 --- a/tb/test_arp_64.v +++ b/tb/test_arp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_cache.py b/tb/test_arp_cache.py index 537309e84..fae91cb66 100755 --- a/tb/test_arp_cache.py +++ b/tb/test_arp_cache.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_cache.v b/tb/test_arp_cache.v index ff6c81f73..23f687b46 100755 --- a/tb/test_arp_cache.v +++ b/tb/test_arp_cache.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index 01b457187..8f213a34c 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_eth_rx.v b/tb/test_arp_eth_rx.v index 1b6f2b6fb..8e99b1e4b 100644 --- a/tb/test_arp_eth_rx.v +++ b/tb/test_arp_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index 489ff043b..f8ae65eb1 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_eth_rx_64.v b/tb/test_arp_eth_rx_64.v index 8373bec66..e84502a00 100644 --- a/tb/test_arp_eth_rx_64.v +++ b/tb/test_arp_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py index 417dc7100..dab27a931 100755 --- a/tb/test_arp_eth_tx.py +++ b/tb/test_arp_eth_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_eth_tx.v b/tb/test_arp_eth_tx.v index 4bff7700b..fa722335f 100644 --- a/tb/test_arp_eth_tx.v +++ b/tb/test_arp_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py index f25965141..bc5c0af83 100755 --- a/tb/test_arp_eth_tx_64.py +++ b/tb/test_arp_eth_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_arp_eth_tx_64.v b/tb/test_arp_eth_tx_64.v index 8b8c39d5d..0c577bc1e 100644 --- a/tb/test_arp_eth_tx_64.v +++ b/tb/test_arp_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_axis_eth_fcs.py b/tb/test_axis_eth_fcs.py index 461859e5d..7da6f103b 100755 --- a/tb/test_axis_eth_fcs.py +++ b/tb/test_axis_eth_fcs.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs.v b/tb/test_axis_eth_fcs.v index e1a10f78b..29db1180b 100644 --- a/tb/test_axis_eth_fcs.v +++ b/tb/test_axis_eth_fcs.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_64.py b/tb/test_axis_eth_fcs_64.py index c74132b5c..7432e2ab3 100755 --- a/tb/test_axis_eth_fcs_64.py +++ b/tb/test_axis_eth_fcs_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_64.v b/tb/test_axis_eth_fcs_64.v index 68dd4b0c0..9aa67f12a 100644 --- a/tb/test_axis_eth_fcs_64.v +++ b/tb/test_axis_eth_fcs_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index 687605efd..7f55d5bc4 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_check.v b/tb/test_axis_eth_fcs_check.v index bfb00d425..0fef729b5 100644 --- a/tb/test_axis_eth_fcs_check.v +++ b/tb/test_axis_eth_fcs_check.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_check_64.py b/tb/test_axis_eth_fcs_check_64.py index 9d7135149..7431d5e98 100755 --- a/tb/test_axis_eth_fcs_check_64.py +++ b/tb/test_axis_eth_fcs_check_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_check_64.v b/tb/test_axis_eth_fcs_check_64.v index 370880f8c..283427d4f 100644 --- a/tb/test_axis_eth_fcs_check_64.v +++ b/tb/test_axis_eth_fcs_check_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index 6cd5ab452..5c14a407e 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_insert.v b/tb/test_axis_eth_fcs_insert.v index 39f966fd3..8d4648406 100644 --- a/tb/test_axis_eth_fcs_insert.v +++ b/tb/test_axis_eth_fcs_insert.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_insert_64.py b/tb/test_axis_eth_fcs_insert_64.py index 7c723518c..45546b4b1 100755 --- a/tb/test_axis_eth_fcs_insert_64.py +++ b/tb/test_axis_eth_fcs_insert_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_insert_64.v b/tb/test_axis_eth_fcs_insert_64.v index 3f7e8d893..75bf03e68 100644 --- a/tb/test_axis_eth_fcs_insert_64.v +++ b/tb/test_axis_eth_fcs_insert_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_insert_64_pad.py b/tb/test_axis_eth_fcs_insert_64_pad.py index 5215d82c4..4eeacdb2d 100755 --- a/tb/test_axis_eth_fcs_insert_64_pad.py +++ b/tb/test_axis_eth_fcs_insert_64_pad.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_insert_64_pad.v b/tb/test_axis_eth_fcs_insert_64_pad.v index 2defab0fc..e5f9d4594 100644 --- a/tb/test_axis_eth_fcs_insert_64_pad.v +++ b/tb/test_axis_eth_fcs_insert_64_pad.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_insert_pad.py b/tb/test_axis_eth_fcs_insert_pad.py index a6f122649..811b1fe6c 100755 --- a/tb/test_axis_eth_fcs_insert_pad.py +++ b/tb/test_axis_eth_fcs_insert_pad.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_axis_eth_fcs_insert_pad.v b/tb/test_axis_eth_fcs_insert_pad.v index 5464d7c99..2ef1c22d5 100644 --- a/tb/test_axis_eth_fcs_insert_pad.v +++ b/tb/test_axis_eth_fcs_insert_pad.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_arb_mux_4.py b/tb/test_eth_arb_mux_4.py index 8c3216af8..f43fc0171 100755 --- a/tb/test_eth_arb_mux_4.py +++ b/tb/test_eth_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_arb_mux_4.v b/tb/test_eth_arb_mux_4.v index 9b7130ea7..c5ee9472b 100644 --- a/tb/test_eth_arb_mux_4.v +++ b/tb/test_eth_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_arb_mux_64_4.py b/tb/test_eth_arb_mux_64_4.py index d9cd5524f..910d48b95 100755 --- a/tb/test_eth_arb_mux_64_4.py +++ b/tb/test_eth_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_arb_mux_64_4.v b/tb/test_eth_arb_mux_64_4.v index d7a1b6f57..67f39d908 100644 --- a/tb/test_eth_arb_mux_64_4.v +++ b/tb/test_eth_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index 0914cefe3..1dc1bc3f5 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_axis_rx.v b/tb/test_eth_axis_rx.v index 9ad88025f..141475f95 100644 --- a/tb/test_eth_axis_rx.v +++ b/tb/test_eth_axis_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index 1d11f45da..2f8d5592f 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_axis_rx_64.v b/tb/test_eth_axis_rx_64.v index ae3b4c7bd..41a22393f 100644 --- a/tb/test_eth_axis_rx_64.v +++ b/tb/test_eth_axis_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py index 090ce99a6..0f0c814fc 100755 --- a/tb/test_eth_axis_tx.py +++ b/tb/test_eth_axis_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_axis_tx.v b/tb/test_eth_axis_tx.v index 28debdb57..1086a0422 100644 --- a/tb/test_eth_axis_tx.v +++ b/tb/test_eth_axis_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py index 987549ee0..b75a6988d 100755 --- a/tb/test_eth_axis_tx_64.py +++ b/tb/test_eth_axis_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_axis_tx_64.v b/tb/test_eth_axis_tx_64.v index a08fa101e..6e53803d9 100644 --- a/tb/test_eth_axis_tx_64.v +++ b/tb/test_eth_axis_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_demux_4.py b/tb/test_eth_demux_4.py index 8bda3a376..f1bf24578 100755 --- a/tb/test_eth_demux_4.py +++ b/tb/test_eth_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_demux_4.v b/tb/test_eth_demux_4.v index 8bc5d87e6..b07c919f8 100644 --- a/tb/test_eth_demux_4.v +++ b/tb/test_eth_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_demux_64_4.py b/tb/test_eth_demux_64_4.py index afe1cbe7d..71e5712ed 100755 --- a/tb/test_eth_demux_64_4.py +++ b/tb/test_eth_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_demux_64_4.v b/tb/test_eth_demux_64_4.v index 692f68fef..8b7795e6a 100644 --- a/tb/test_eth_demux_64_4.v +++ b/tb/test_eth_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_mac_10g.py b/tb/test_eth_mac_10g.py index a0eaa19db..bccb98275 100755 --- a/tb/test_eth_mac_10g.py +++ b/tb/test_eth_mac_10g.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_10g.v b/tb/test_eth_mac_10g.v index c9c63de6d..44f296bc2 100644 --- a/tb/test_eth_mac_10g.v +++ b/tb/test_eth_mac_10g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_10g_fifo.py b/tb/test_eth_mac_10g_fifo.py index d66815fe1..f7689baf6 100755 --- a/tb/test_eth_mac_10g_fifo.py +++ b/tb/test_eth_mac_10g_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_10g_fifo.v b/tb/test_eth_mac_10g_fifo.v index 2d5ac1036..162a83d62 100644 --- a/tb/test_eth_mac_10g_fifo.v +++ b/tb/test_eth_mac_10g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_10g_rx.py b/tb/test_eth_mac_10g_rx.py index eaacb0e8a..21e1e2a22 100755 --- a/tb/test_eth_mac_10g_rx.py +++ b/tb/test_eth_mac_10g_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_10g_rx.v b/tb/test_eth_mac_10g_rx.v index 96713171d..8e4c47017 100644 --- a/tb/test_eth_mac_10g_rx.v +++ b/tb/test_eth_mac_10g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_10g_tx.py b/tb/test_eth_mac_10g_tx.py index 75c8c6929..921670222 100755 --- a/tb/test_eth_mac_10g_tx.py +++ b/tb/test_eth_mac_10g_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_10g_tx.v b/tb/test_eth_mac_10g_tx.v index 54efc23b7..5889211ff 100644 --- a/tb/test_eth_mac_10g_tx.v +++ b/tb/test_eth_mac_10g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index b3ace71ac..6e446d59d 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_1g.v b/tb/test_eth_mac_1g.v index a56553a10..dda4639e9 100644 --- a/tb/test_eth_mac_1g.v +++ b/tb/test_eth_mac_1g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py index 32dfa3e97..3db86968c 100755 --- a/tb/test_eth_mac_1g_fifo.py +++ b/tb/test_eth_mac_1g_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_1g_fifo.v b/tb/test_eth_mac_1g_fifo.v index b8cd0d6a8..fde9eafbf 100644 --- a/tb/test_eth_mac_1g_fifo.v +++ b/tb/test_eth_mac_1g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py index a3d308414..4bf2afcaf 100755 --- a/tb/test_eth_mac_1g_rx.py +++ b/tb/test_eth_mac_1g_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_1g_rx.v b/tb/test_eth_mac_1g_rx.v index 95a30881e..9057e7e8a 100644 --- a/tb/test_eth_mac_1g_rx.v +++ b/tb/test_eth_mac_1g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index 5824815b4..2963ecad2 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mac_1g_tx.v b/tb/test_eth_mac_1g_tx.v index 60a4a7bd0..0f8849a68 100644 --- a/tb/test_eth_mac_1g_tx.v +++ b/tb/test_eth_mac_1g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 diff --git a/tb/test_eth_mux_4.py b/tb/test_eth_mux_4.py index 854b69992..8d2ab68a2 100755 --- a/tb/test_eth_mux_4.py +++ b/tb/test_eth_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_mux_4.v b/tb/test_eth_mux_4.v index 1826aa743..435e266fb 100644 --- a/tb/test_eth_mux_4.v +++ b/tb/test_eth_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_mux_64_4.py b/tb/test_eth_mux_64_4.py index 2c2b4757e..b7f5ccb20 100755 --- a/tb/test_eth_mux_64_4.py +++ b/tb/test_eth_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_eth_mux_64_4.v b/tb/test_eth_mux_64_4.v index 58d4f2118..b1b868649 100644 --- a/tb/test_eth_mux_64_4.v +++ b/tb/test_eth_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip.py b/tb/test_ip.py index cab09c353..d54491aba 100755 --- a/tb/test_ip.py +++ b/tb/test_ip.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip.v b/tb/test_ip.v index cf63c637d..d194dd2f7 100644 --- a/tb/test_ip.v +++ b/tb/test_ip.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_64.py b/tb/test_ip_64.py index b42196b9b..2496e68b8 100755 --- a/tb/test_ip_64.py +++ b/tb/test_ip_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_64.v b/tb/test_ip_64.v index 2228501ab..b29c90e3a 100644 --- a/tb/test_ip_64.v +++ b/tb/test_ip_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_arb_mux_4.py b/tb/test_ip_arb_mux_4.py index 8c3fa6e34..3bd596947 100755 --- a/tb/test_ip_arb_mux_4.py +++ b/tb/test_ip_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_arb_mux_4.v b/tb/test_ip_arb_mux_4.v index 5270e0643..226301a9a 100644 --- a/tb/test_ip_arb_mux_4.v +++ b/tb/test_ip_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_arb_mux_64_4.py b/tb/test_ip_arb_mux_64_4.py index 707f7b764..f3a62e4e5 100755 --- a/tb/test_ip_arb_mux_64_4.py +++ b/tb/test_ip_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_arb_mux_64_4.v b/tb/test_ip_arb_mux_64_4.v index 930311284..796eafccb 100644 --- a/tb/test_ip_arb_mux_64_4.v +++ b/tb/test_ip_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_complete.py b/tb/test_ip_complete.py index 70eec26db..0ed6c4bdc 100755 --- a/tb/test_ip_complete.py +++ b/tb/test_ip_complete.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_complete.v b/tb/test_ip_complete.v index ed1670ff6..0879eaa7e 100644 --- a/tb/test_ip_complete.v +++ b/tb/test_ip_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_complete_64.py b/tb/test_ip_complete_64.py index 6d276d06b..f72d9003e 100755 --- a/tb/test_ip_complete_64.py +++ b/tb/test_ip_complete_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_complete_64.v b/tb/test_ip_complete_64.v index d835efe45..156447b93 100644 --- a/tb/test_ip_complete_64.v +++ b/tb/test_ip_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_demux_4.py b/tb/test_ip_demux_4.py index 4eb1b7bfe..2694f63c5 100755 --- a/tb/test_ip_demux_4.py +++ b/tb/test_ip_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_demux_4.v b/tb/test_ip_demux_4.v index 32beaabe1..6bec00acd 100644 --- a/tb/test_ip_demux_4.v +++ b/tb/test_ip_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_demux_64_4.py b/tb/test_ip_demux_64_4.py index 5ffb109ed..617ae9b81 100755 --- a/tb/test_ip_demux_64_4.py +++ b/tb/test_ip_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_demux_64_4.v b/tb/test_ip_demux_64_4.v index 60fb08282..966722cc0 100644 --- a/tb/test_ip_demux_64_4.v +++ b/tb/test_ip_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index c42f7e749..d0695d423 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_eth_rx.v b/tb/test_ip_eth_rx.v index 1f61d1d30..b6c4db763 100644 --- a/tb/test_ip_eth_rx.v +++ b/tb/test_ip_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py index 8db947c56..fecc3fccb 100755 --- a/tb/test_ip_eth_rx_64.py +++ b/tb/test_ip_eth_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_eth_rx_64.v b/tb/test_ip_eth_rx_64.v index 70d8a02f4..5bfa6624b 100644 --- a/tb/test_ip_eth_rx_64.v +++ b/tb/test_ip_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py index 8748bccbe..4f7c4ccd2 100755 --- a/tb/test_ip_eth_tx.py +++ b/tb/test_ip_eth_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_eth_tx.v b/tb/test_ip_eth_tx.v index ab14a4efc..920a81f04 100644 --- a/tb/test_ip_eth_tx.v +++ b/tb/test_ip_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_eth_tx_64.py b/tb/test_ip_eth_tx_64.py index 4ac5616c7..9943de905 100755 --- a/tb/test_ip_eth_tx_64.py +++ b/tb/test_ip_eth_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_eth_tx_64.v b/tb/test_ip_eth_tx_64.v index fea39c3e5..1941fa4f2 100644 --- a/tb/test_ip_eth_tx_64.v +++ b/tb/test_ip_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_mux_4.py b/tb/test_ip_mux_4.py index b860a05e7..2a26d5167 100755 --- a/tb/test_ip_mux_4.py +++ b/tb/test_ip_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_mux_4.v b/tb/test_ip_mux_4.v index a5af9d391..384e8483b 100644 --- a/tb/test_ip_mux_4.v +++ b/tb/test_ip_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_mux_64_4.py b/tb/test_ip_mux_64_4.py index 659ffa83e..b5de31ffc 100755 --- a/tb/test_ip_mux_64_4.py +++ b/tb/test_ip_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_ip_mux_64_4.v b/tb/test_ip_mux_64_4.v index ab796d85b..9df30d773 100644 --- a/tb/test_ip_mux_64_4.v +++ b/tb/test_ip_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp.py b/tb/test_udp.py index 755e13a47..830f369ea 100755 --- a/tb/test_udp.py +++ b/tb/test_udp.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp.v b/tb/test_udp.v index e6ba1c716..3085d655f 100644 --- a/tb/test_udp.v +++ b/tb/test_udp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py index 56b6de966..2930b2551 100755 --- a/tb/test_udp_64.py +++ b/tb/test_udp_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_64.v b/tb/test_udp_64.v index 556324b4c..68e8be88f 100644 --- a/tb/test_udp_64.v +++ b/tb/test_udp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_arb_mux_4.py b/tb/test_udp_arb_mux_4.py index ef28100ac..656d9a254 100755 --- a/tb/test_udp_arb_mux_4.py +++ b/tb/test_udp_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_arb_mux_4.v b/tb/test_udp_arb_mux_4.v index f38d96a2c..6a1046ed0 100644 --- a/tb/test_udp_arb_mux_4.v +++ b/tb/test_udp_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_arb_mux_64_4.py b/tb/test_udp_arb_mux_64_4.py index 9dac1b9db..4f846b60d 100755 --- a/tb/test_udp_arb_mux_64_4.py +++ b/tb/test_udp_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_arb_mux_64_4.v b/tb/test_udp_arb_mux_64_4.v index 11f7e7ed2..1e6faf876 100644 --- a/tb/test_udp_arb_mux_64_4.v +++ b/tb/test_udp_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py index f70122101..8d58b647f 100755 --- a/tb/test_udp_complete.py +++ b/tb/test_udp_complete.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_complete.v b/tb/test_udp_complete.v index 76e5b1e30..8a6fb89d2 100644 --- a/tb/test_udp_complete.v +++ b/tb/test_udp_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index d9775d43f..25d6f98ef 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_complete_64.v b/tb/test_udp_complete_64.v index 36e19c609..20d9eaddb 100644 --- a/tb/test_udp_complete_64.v +++ b/tb/test_udp_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_demux_4.py b/tb/test_udp_demux_4.py index 705da471d..065a026d2 100755 --- a/tb/test_udp_demux_4.py +++ b/tb/test_udp_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_demux_4.v b/tb/test_udp_demux_4.v index 1c4865b96..4dd1df410 100644 --- a/tb/test_udp_demux_4.v +++ b/tb/test_udp_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_demux_64_4.py b/tb/test_udp_demux_64_4.py index b4f304660..cd8368752 100755 --- a/tb/test_udp_demux_64_4.py +++ b/tb/test_udp_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_demux_64_4.v b/tb/test_udp_demux_64_4.v index d0853d713..5e87dbcef 100644 --- a/tb/test_udp_demux_64_4.v +++ b/tb/test_udp_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_ip_rx.py b/tb/test_udp_ip_rx.py index 5e216ba2c..be354170a 100755 --- a/tb/test_udp_ip_rx.py +++ b/tb/test_udp_ip_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_ip_rx.v b/tb/test_udp_ip_rx.v index a750e65f9..0c4c44eac 100644 --- a/tb/test_udp_ip_rx.v +++ b/tb/test_udp_ip_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_ip_rx_64.py b/tb/test_udp_ip_rx_64.py index df95e52dd..2e135aaf2 100755 --- a/tb/test_udp_ip_rx_64.py +++ b/tb/test_udp_ip_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_ip_rx_64.v b/tb/test_udp_ip_rx_64.v index b311d7ccf..e11d547f1 100644 --- a/tb/test_udp_ip_rx_64.v +++ b/tb/test_udp_ip_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_ip_tx.py b/tb/test_udp_ip_tx.py index 98db8ce38..be2523b3f 100755 --- a/tb/test_udp_ip_tx.py +++ b/tb/test_udp_ip_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_ip_tx.v b/tb/test_udp_ip_tx.v index fb4e3b4c4..4a076442f 100644 --- a/tb/test_udp_ip_tx.v +++ b/tb/test_udp_ip_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_ip_tx_64.py b/tb/test_udp_ip_tx_64.py index 100d4400c..32cfa9e7c 100755 --- a/tb/test_udp_ip_tx_64.py +++ b/tb/test_udp_ip_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_ip_tx_64.v b/tb/test_udp_ip_tx_64.v index cfc60bf5f..476651762 100644 --- a/tb/test_udp_ip_tx_64.v +++ b/tb/test_udp_ip_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_mux_4.py b/tb/test_udp_mux_4.py index d5b464b4a..865121513 100755 --- a/tb/test_udp_mux_4.py +++ b/tb/test_udp_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_mux_4.v b/tb/test_udp_mux_4.v index 120825e01..e9e724b7e 100644 --- a/tb/test_udp_mux_4.v +++ b/tb/test_udp_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_mux_64_4.py b/tb/test_udp_mux_64_4.py index 197d85d33..764466032 100755 --- a/tb/test_udp_mux_64_4.py +++ b/tb/test_udp_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/test_udp_mux_64_4.v b/tb/test_udp_mux_64_4.v index 4e781d363..59df7c74b 100644 --- a/tb/test_udp_mux_64_4.v +++ b/tb/test_udp_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/udp_ep.py b/tb/udp_ep.py index aac2f1bc2..c5c1d1d6c 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 1d8e71924..5f29af571 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 From 152486bebd40bbf6dfc682d109c523ac049e5b59 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 Jan 2016 01:30:00 -0800 Subject: [PATCH 266/617] Update parametrization --- rtl/gmii_phy_if.v | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rtl/gmii_phy_if.v b/rtl/gmii_phy_if.v index ebfb83e3f..ee15ce183 100644 --- a/rtl/gmii_phy_if.v +++ b/rtl/gmii_phy_if.v @@ -31,7 +31,8 @@ THE SOFTWARE. */ module gmii_phy_if # ( - parameter TARGET_XILINX = 0 + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC" ) ( input wire clk, @@ -70,7 +71,7 @@ wire phy_gmii_tx_clk_int; generate -if (TARGET_XILINX) begin +if (TARGET == "XILINX") begin // use Xilinx clocking primitives From c5b6202174b504dbb772f0adda6c13a3bc76571e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 8 Jan 2016 01:32:04 -0800 Subject: [PATCH 267/617] Update example design --- example/ATLYS/fpga/Makefile | 2 +- example/ATLYS/fpga/coregen/Makefile | 33 --- example/ATLYS/fpga/coregen/coregen.cgp | 20 -- example/ATLYS/fpga/coregen/dcm_i100_o125.xco | 269 ------------------- example/ATLYS/fpga/fpga/Makefile | 5 +- example/ATLYS/fpga/rtl/debounce_switch.v | 2 +- example/ATLYS/fpga/rtl/fpga.v | 247 +++++++++-------- example/ATLYS/fpga/rtl/fpga_core.v | 50 ++-- example/ATLYS/fpga/rtl/fpga_pads.v | 170 ------------ example/ATLYS/fpga/rtl/sync_reset.v | 2 +- example/ATLYS/fpga/rtl/sync_signal.v | 2 +- example/ATLYS/fpga/tb/test_fpga_core.py | 4 +- example/ATLYS/fpga/tb/test_fpga_core.v | 6 +- 13 files changed, 181 insertions(+), 631 deletions(-) delete mode 100644 example/ATLYS/fpga/coregen/Makefile delete mode 100644 example/ATLYS/fpga/coregen/coregen.cgp delete mode 100644 example/ATLYS/fpga/coregen/dcm_i100_o125.xco delete mode 100644 example/ATLYS/fpga/rtl/fpga_pads.v diff --git a/example/ATLYS/fpga/Makefile b/example/ATLYS/fpga/Makefile index 9f8bd4048..f504bd06f 100644 --- a/example/ATLYS/fpga/Makefile +++ b/example/ATLYS/fpga/Makefile @@ -2,7 +2,7 @@ TARGETS:= # Subdirectories -SUBDIRS = coregen fpga +SUBDIRS = fpga SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) # Rules diff --git a/example/ATLYS/fpga/coregen/Makefile b/example/ATLYS/fpga/coregen/Makefile deleted file mode 100644 index 714069069..000000000 --- a/example/ATLYS/fpga/coregen/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# Tools -COREGEN:=coregen -XAW2VERILOG:=xaw2verilog - -# Source -XCO:=dcm_i100_o125.xco -XAW:= - -# Targets -TARGETS += $(XCO:.xco=) -TARGETS += $(XAW:.xaw=) - -# Rules -.PHONY: all -all: $(TARGETS) - -.PHONY: clean -clean: - -rm -rf $(TARGETS) - -%: %.xco - $(eval $@_TMP := $(shell mktemp -d)) - cp -a coregen.cgp $($@_TMP) - cp -a $< $($@_TMP) - cd $($@_TMP) && $(COREGEN) -p coregen.cgp -b $(notdir $<) - mv $($@_TMP) $@ - -%: %.xaw - $(eval $@_TMP := $(shell mktemp -d)) - cp -a coregen.cgp $($@_TMP) - cp -a $< $($@_TMP) - cd $($@_TMP) && $(XAW2VERILOG) -st $(notdir $<) $(notdir $*) - mv $($@_TMP) $@ diff --git a/example/ATLYS/fpga/coregen/coregen.cgp b/example/ATLYS/fpga/coregen/coregen.cgp deleted file mode 100644 index 773be0a87..000000000 --- a/example/ATLYS/fpga/coregen/coregen.cgp +++ /dev/null @@ -1,20 +0,0 @@ -# Date: Sat Jan 07 00:34:24 2012 -SET addpads = false -SET asysymbol = true -SET busformat = BusFormatAngleBracketNotRipped -SET createndf = false -SET designentry = Verilog -SET device = xc6slx45 -SET devicefamily = spartan6 -SET flowvendor = Foundation_ISE -SET formalverification = false -SET foundationsym = false -SET implementationfiletype = Ngc -SET package = csg324 -SET removerpms = false -SET simulationfiles = Behavioral -SET speedgrade = -2 -SET verilogsim = true -SET vhdlsim = false -SET workingdirectory = .\tmp\ -# CRC: 90246c5 diff --git a/example/ATLYS/fpga/coregen/dcm_i100_o125.xco b/example/ATLYS/fpga/coregen/dcm_i100_o125.xco deleted file mode 100644 index 18ce93185..000000000 --- a/example/ATLYS/fpga/coregen/dcm_i100_o125.xco +++ /dev/null @@ -1,269 +0,0 @@ -############################################################## -# -# Xilinx Core Generator version 14.7 -# Date: Sun Mar 1 03:45:12 2015 -# -############################################################## -# -# This file contains the customisation parameters for a -# Xilinx CORE Generator IP GUI. It is strongly recommended -# that you do not manually alter this file as it may cause -# unexpected and unsupported behavior. -# -############################################################## -# -# Generated from component: xilinx.com:ip:clk_wiz:3.6 -# -############################################################## -# -# BEGIN Project Options -SET addpads = false -SET asysymbol = true -SET busformat = BusFormatAngleBracketNotRipped -SET createndf = false -SET designentry = Verilog -SET device = xc6slx45 -SET devicefamily = spartan6 -SET flowvendor = Foundation_ISE -SET formalverification = false -SET foundationsym = false -SET implementationfiletype = Ngc -SET package = csg324 -SET removerpms = false -SET simulationfiles = Behavioral -SET speedgrade = -2 -SET verilogsim = true -SET vhdlsim = false -# END Project Options -# BEGIN Select -SELECT Clocking_Wizard xilinx.com:ip:clk_wiz:3.6 -# END Select -# BEGIN Parameters -CSET calc_done=DONE -CSET clk_in_sel_port=CLK_IN_SEL -CSET clk_out1_port=CLK_OUT1 -CSET clk_out1_use_fine_ps_gui=false -CSET clk_out2_port=CLK_OUT2 -CSET clk_out2_use_fine_ps_gui=false -CSET clk_out3_port=CLK_OUT3 -CSET clk_out3_use_fine_ps_gui=false -CSET clk_out4_port=CLK_OUT4 -CSET clk_out4_use_fine_ps_gui=false -CSET clk_out5_port=CLK_OUT5 -CSET clk_out5_use_fine_ps_gui=false -CSET clk_out6_port=CLK_OUT6 -CSET clk_out6_use_fine_ps_gui=false -CSET clk_out7_port=CLK_OUT7 -CSET clk_out7_use_fine_ps_gui=false -CSET clk_valid_port=CLK_VALID -CSET clkfb_in_n_port=CLKFB_IN_N -CSET clkfb_in_p_port=CLKFB_IN_P -CSET clkfb_in_port=CLKFB_IN -CSET clkfb_in_signaling=SINGLE -CSET clkfb_out_n_port=CLKFB_OUT_N -CSET clkfb_out_p_port=CLKFB_OUT_P -CSET clkfb_out_port=CLKFB_OUT -CSET clkfb_stopped_port=CLKFB_STOPPED -CSET clkin1_jitter_ps=100.0 -CSET clkin1_ui_jitter=0.010 -CSET clkin2_jitter_ps=100.0 -CSET clkin2_ui_jitter=0.010 -CSET clkout1_drives=BUFG -CSET clkout1_requested_duty_cycle=50.000 -CSET clkout1_requested_out_freq=125.000 -CSET clkout1_requested_phase=0.000 -CSET clkout2_drives=BUFG -CSET clkout2_requested_duty_cycle=50.000 -CSET clkout2_requested_out_freq=100.000 -CSET clkout2_requested_phase=0.000 -CSET clkout2_used=false -CSET clkout3_drives=BUFG -CSET clkout3_requested_duty_cycle=50.000 -CSET clkout3_requested_out_freq=100.000 -CSET clkout3_requested_phase=0.000 -CSET clkout3_used=false -CSET clkout4_drives=BUFG -CSET clkout4_requested_duty_cycle=50.000 -CSET clkout4_requested_out_freq=100.000 -CSET clkout4_requested_phase=0.000 -CSET clkout4_used=false -CSET clkout5_drives=BUFG -CSET clkout5_requested_duty_cycle=50.000 -CSET clkout5_requested_out_freq=100.000 -CSET clkout5_requested_phase=0.000 -CSET clkout5_used=false -CSET clkout6_drives=BUFG -CSET clkout6_requested_duty_cycle=50.000 -CSET clkout6_requested_out_freq=100.000 -CSET clkout6_requested_phase=0.000 -CSET clkout6_used=false -CSET clkout7_drives=BUFG -CSET clkout7_requested_duty_cycle=50.000 -CSET clkout7_requested_out_freq=100.000 -CSET clkout7_requested_phase=0.000 -CSET clkout7_used=false -CSET clock_mgr_type=AUTO -CSET component_name=dcm_i100_o125 -CSET daddr_port=DADDR -CSET dclk_port=DCLK -CSET dcm_clk_feedback=1X -CSET dcm_clk_out1_port=CLKFX -CSET dcm_clk_out2_port=CLK0 -CSET dcm_clk_out3_port=CLK0 -CSET dcm_clk_out4_port=CLK0 -CSET dcm_clk_out5_port=CLK0 -CSET dcm_clk_out6_port=CLK0 -CSET dcm_clkdv_divide=2.0 -CSET dcm_clkfx_divide=4 -CSET dcm_clkfx_multiply=5 -CSET dcm_clkgen_clk_out1_port=CLKFX -CSET dcm_clkgen_clk_out2_port=CLKFX -CSET dcm_clkgen_clk_out3_port=CLKFX -CSET dcm_clkgen_clkfx_divide=1 -CSET dcm_clkgen_clkfx_md_max=0.000 -CSET dcm_clkgen_clkfx_multiply=4 -CSET dcm_clkgen_clkfxdv_divide=2 -CSET dcm_clkgen_clkin_period=10.000 -CSET dcm_clkgen_notes=None -CSET dcm_clkgen_spread_spectrum=NONE -CSET dcm_clkgen_startup_wait=false -CSET dcm_clkin_divide_by_2=false -CSET dcm_clkin_period=10.000 -CSET dcm_clkout_phase_shift=NONE -CSET dcm_deskew_adjust=SYSTEM_SYNCHRONOUS -CSET dcm_notes=None -CSET dcm_phase_shift=0 -CSET dcm_pll_cascade=NONE -CSET dcm_startup_wait=false -CSET den_port=DEN -CSET din_port=DIN -CSET dout_port=DOUT -CSET drdy_port=DRDY -CSET dwe_port=DWE -CSET feedback_source=FDBK_AUTO -CSET in_freq_units=Units_MHz -CSET in_jitter_units=Units_UI -CSET input_clk_stopped_port=INPUT_CLK_STOPPED -CSET jitter_options=UI -CSET jitter_sel=No_Jitter -CSET locked_port=LOCKED -CSET mmcm_bandwidth=OPTIMIZED -CSET mmcm_clkfbout_mult_f=4.000 -CSET mmcm_clkfbout_phase=0.000 -CSET mmcm_clkfbout_use_fine_ps=false -CSET mmcm_clkin1_period=10.000 -CSET mmcm_clkin2_period=10.000 -CSET mmcm_clkout0_divide_f=4.000 -CSET mmcm_clkout0_duty_cycle=0.500 -CSET mmcm_clkout0_phase=0.000 -CSET mmcm_clkout0_use_fine_ps=false -CSET mmcm_clkout1_divide=1 -CSET mmcm_clkout1_duty_cycle=0.500 -CSET mmcm_clkout1_phase=0.000 -CSET mmcm_clkout1_use_fine_ps=false -CSET mmcm_clkout2_divide=1 -CSET mmcm_clkout2_duty_cycle=0.500 -CSET mmcm_clkout2_phase=0.000 -CSET mmcm_clkout2_use_fine_ps=false -CSET mmcm_clkout3_divide=1 -CSET mmcm_clkout3_duty_cycle=0.500 -CSET mmcm_clkout3_phase=0.000 -CSET mmcm_clkout3_use_fine_ps=false -CSET mmcm_clkout4_cascade=false -CSET mmcm_clkout4_divide=1 -CSET mmcm_clkout4_duty_cycle=0.500 -CSET mmcm_clkout4_phase=0.000 -CSET mmcm_clkout4_use_fine_ps=false -CSET mmcm_clkout5_divide=1 -CSET mmcm_clkout5_duty_cycle=0.500 -CSET mmcm_clkout5_phase=0.000 -CSET mmcm_clkout5_use_fine_ps=false -CSET mmcm_clkout6_divide=1 -CSET mmcm_clkout6_duty_cycle=0.500 -CSET mmcm_clkout6_phase=0.000 -CSET mmcm_clkout6_use_fine_ps=false -CSET mmcm_clock_hold=false -CSET mmcm_compensation=ZHOLD -CSET mmcm_divclk_divide=1 -CSET mmcm_notes=None -CSET mmcm_ref_jitter1=0.010 -CSET mmcm_ref_jitter2=0.010 -CSET mmcm_startup_wait=false -CSET num_out_clks=1 -CSET override_dcm=false -CSET override_dcm_clkgen=false -CSET override_mmcm=false -CSET override_pll=false -CSET platform=lin64 -CSET pll_bandwidth=OPTIMIZED -CSET pll_clk_feedback=CLKFBOUT -CSET pll_clkfbout_mult=4 -CSET pll_clkfbout_phase=0.000 -CSET pll_clkin_period=10.000 -CSET pll_clkout0_divide=1 -CSET pll_clkout0_duty_cycle=0.500 -CSET pll_clkout0_phase=0.000 -CSET pll_clkout1_divide=1 -CSET pll_clkout1_duty_cycle=0.500 -CSET pll_clkout1_phase=0.000 -CSET pll_clkout2_divide=1 -CSET pll_clkout2_duty_cycle=0.500 -CSET pll_clkout2_phase=0.000 -CSET pll_clkout3_divide=1 -CSET pll_clkout3_duty_cycle=0.500 -CSET pll_clkout3_phase=0.000 -CSET pll_clkout4_divide=1 -CSET pll_clkout4_duty_cycle=0.500 -CSET pll_clkout4_phase=0.000 -CSET pll_clkout5_divide=1 -CSET pll_clkout5_duty_cycle=0.500 -CSET pll_clkout5_phase=0.000 -CSET pll_compensation=SYSTEM_SYNCHRONOUS -CSET pll_divclk_divide=1 -CSET pll_notes=None -CSET pll_ref_jitter=0.010 -CSET power_down_port=POWER_DOWN -CSET prim_in_freq=100.000 -CSET prim_in_jitter=0.010 -CSET prim_source=Single_ended_clock_capable_pin -CSET primary_port=CLK_IN1 -CSET primitive=MMCM -CSET primtype_sel=PLL_BASE -CSET psclk_port=PSCLK -CSET psdone_port=PSDONE -CSET psen_port=PSEN -CSET psincdec_port=PSINCDEC -CSET relative_inclk=REL_PRIMARY -CSET reset_port=RESET -CSET secondary_in_freq=100.000 -CSET secondary_in_jitter=0.010 -CSET secondary_port=CLK_IN2 -CSET secondary_source=Single_ended_clock_capable_pin -CSET ss_mod_freq=250 -CSET ss_mode=CENTER_HIGH -CSET status_port=STATUS -CSET summary_strings=empty -CSET use_clk_valid=false -CSET use_clkfb_stopped=false -CSET use_dyn_phase_shift=false -CSET use_dyn_reconfig=false -CSET use_freeze=false -CSET use_freq_synth=true -CSET use_inclk_stopped=false -CSET use_inclk_switchover=false -CSET use_locked=true -CSET use_max_i_jitter=false -CSET use_min_o_jitter=false -CSET use_min_power=false -CSET use_phase_alignment=true -CSET use_power_down=false -CSET use_reset=true -CSET use_spread_spectrum=false -CSET use_spread_spectrum_1=false -CSET use_status=false -# END Parameters -# BEGIN Extra information -MISC pkg_timestamp=2012-05-10T12:44:55Z -# END Extra information -GENERATE -# CRC: fe0bbd35 diff --git a/example/ATLYS/fpga/fpga/Makefile b/example/ATLYS/fpga/fpga/Makefile index ed7fe28bc..648dbf88b 100644 --- a/example/ATLYS/fpga/fpga/Makefile +++ b/example/ATLYS/fpga/fpga/Makefile @@ -11,7 +11,6 @@ FPGA_ARCH = spartan6 # Files for synthesis SYN_FILES = rtl/fpga.v SYN_FILES += rtl/fpga_core.v -SYN_FILES += rtl/fpga_pads.v SYN_FILES += rtl/debounce_switch.v SYN_FILES += rtl/sync_reset.v SYN_FILES += rtl/sync_signal.v @@ -43,14 +42,14 @@ SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v -SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v +#SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v # UCF files UCF_FILES = fpga.ucf UCF_FILES += clock.ucf # NGC paths for ngdbuild -NGC_PATHS = coregen/dcm_i100_o125 +#NGC_PATHS = coregen/dcm_i100_o125 # Bitgen options BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 diff --git a/example/ATLYS/fpga/rtl/debounce_switch.v b/example/ATLYS/fpga/rtl/debounce_switch.v index f3fb77a16..3e2dc20a5 100644 --- a/example/ATLYS/fpga/rtl/debounce_switch.v +++ b/example/ATLYS/fpga/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/example/ATLYS/fpga/rtl/fpga.v b/example/ATLYS/fpga/rtl/fpga.v index 0aa317e47..46bb17ae4 100644 --- a/example/ATLYS/fpga/rtl/fpga.v +++ b/example/ATLYS/fpga/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 @@ -22,75 +22,162 @@ THE SOFTWARE. */ +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * FPGA top-level module + */ module fpga ( /* * Clock: 100MHz * Reset: Push button, active low */ - input wire clk, - input wire reset_n, + input wire clk, + input wire reset_n, + /* * GPIO */ - input wire btnu, - input wire btnl, - input wire btnd, - input wire btnr, - input wire btnc, - input wire [7:0] sw, + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, output wire [7:0] led, + /* * Ethernet: 1000BASE-T GMII */ - input wire phy_rx_clk, - input wire [7:0] phy_rxd, - input wire phy_rx_dv, - input wire phy_rx_er, - output wire phy_gtx_clk, + input wire phy_rx_clk, + input wire [7:0] phy_rxd, + input wire phy_rx_dv, + input wire phy_rx_er, + output wire phy_gtx_clk, output wire [7:0] phy_txd, - output wire phy_tx_en, - output wire phy_tx_er, - output wire phy_reset_n, + output wire phy_tx_en, + output wire phy_tx_er, + output wire phy_reset_n, + /* * UART: 500000 bps, 8N1 */ - input wire uart_rxd, - output wire uart_txd + input wire uart_rxd, + output wire uart_txd ); -/* - * Clock: 125MHz - * Synchronous reset - */ +// Clock and reset + +wire clk_ibufg; +wire clk_bufg; +wire clk_dcm_out; + +// Internal 125 MHz clock wire clk_int; wire rst_int; -/* - * GPIO - */ + +wire dcm_rst; +wire [7:0] dcm_status; +wire dcm_locked; +wire dcm_clkfx_stopped = dcm_status[2]; + +assign dcm_rst = ~reset_n | (dcm_clkfx_stopped & ~dcm_locked); + +IBUFG +clk_ibufg_inst( + .I(clk), + .O(clk_ibufg) +); + +DCM_SP #( + .CLKIN_PERIOD(10), + .CLK_FEEDBACK("NONE"), + .CLKDV_DIVIDE(2.0), + .CLKFX_MULTIPLY(5.0), + .CLKFX_DIVIDE(4.0), + .PHASE_SHIFT(0), + .CLKOUT_PHASE_SHIFT("NONE"), + .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), + .STARTUP_WAIT("FALSE"), + .CLKIN_DIVIDE_BY_2("FALSE") +) +clk_dcm_inst ( + .CLKIN(clk_ibufg), + .CLKFB(1'b0), + .RST(dcm_rst), + .PSEN(1'b0), + .PSINCDEC(1'b0), + .PSCLK(1'b0), + .CLK0(), + .CLK90(), + .CLK180(), + .CLK270(), + .CLK2X(), + .CLK2X180(), + .CLKDV(), + .CLKFX(clk_dcm_out), + .CLKFX180(), + .STATUS(dcm_status), + .LOCKED(dcm_locked), + .PSDONE() +); + +BUFG +clk_bufg_inst ( + .I(clk_dcm_out), + .O(clk_int) +); + +sync_reset #( + .N(4) +) +sync_reset_inst ( + .clk(clk_int), + .rst(~dcm_locked), + .sync_reset_out(rst_int) +); + +// GPIO wire btnu_int; wire btnl_int; wire btnd_int; wire btnr_int; wire btnc_int; wire [7:0] sw_int; -wire [7:0] led_int; -/* - * Ethernet: 1000BASE-T GMII - */ -wire phy_rx_clk_int; -wire [7:0] phy_rxd_int; -wire phy_rx_dv_int; -wire phy_rx_er_int; -wire phy_gtx_clk_int; -wire [7:0] phy_txd_int; -wire phy_tx_en_int; -wire phy_tx_er_int; -wire phy_reset_n_int; -/* - * UART: 115200 bps, 8N1 - */ -wire uart_rxd_int; -wire uart_txd_int; + +debounce_switch #( + .WIDTH(13), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_int), + .rst(rst_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +sync_signal #( + .WIDTH(1), + .N(2) +) +sync_signal_inst ( + .clk(clk_int), + .in({uart_rxd}), + .out({uart_rxd_int}) +); fpga_core core_inst ( @@ -109,74 +196,24 @@ core_inst ( .btnr(btnr_int), .btnc(btnc_int), .sw(sw_int), - .led(led_int), + .led(led), /* * Ethernet: 1000BASE-T GMII */ - .phy_rx_clk(phy_rx_clk_int), - .phy_rxd(phy_rxd_int), - .phy_rx_dv(phy_rx_dv_int), - .phy_rx_er(phy_rx_er_int), - .phy_gtx_clk(phy_gtx_clk_int), - .phy_txd(phy_txd_int), - .phy_tx_en(phy_tx_en_int), - .phy_tx_er(phy_tx_er_int), - .phy_reset_n(phy_reset_n_int), + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_dv(phy_rx_dv), + .phy_rx_er(phy_rx_er), + .phy_gtx_clk(phy_gtx_clk), + .phy_txd(phy_txd), + .phy_tx_en(phy_tx_en), + .phy_tx_er(phy_tx_er), + .phy_reset_n(phy_reset_n), /* * UART: 115200 bps, 8N1 */ .uart_rxd(uart_rxd_int), - .uart_txd(uart_txd_int) -); - -fpga_pads -pads_inst ( - /* - * Pads - */ - .clk_pad(clk), - .reset_n_pad(reset_n), - .btnu_pad(btnu), - .btnl_pad(btnl), - .btnd_pad(btnd), - .btnr_pad(btnr), - .btnc_pad(btnc), - .sw_pad(sw), - .led_pad(led), - .phy_rx_clk_pad(phy_rx_clk), - .phy_rxd_pad(phy_rxd), - .phy_rx_dv_pad(phy_rx_dv), - .phy_rx_er_pad(phy_rx_er), - .phy_gtx_clk_pad(phy_gtx_clk), - .phy_txd_pad(phy_txd), - .phy_tx_en_pad(phy_tx_en), - .phy_tx_er_pad(phy_tx_er), - .phy_reset_n_pad(phy_reset_n), - .uart_rxd_pad(uart_rxd), - .uart_txd_pad(uart_txd), - /* - * Internal - */ - .clk_int(clk_int), - .rst_int(rst_int), - .btnu_int(btnu_int), - .btnl_int(btnl_int), - .btnd_int(btnd_int), - .btnr_int(btnr_int), - .btnc_int(btnc_int), - .sw_int(sw_int), - .led_int(led_int), - .phy_rx_clk_int(phy_rx_clk_int), - .phy_rxd_int(phy_rxd_int), - .phy_rx_dv_int(phy_rx_dv_int), - .phy_rx_er_int(phy_rx_er_int), - .phy_gtx_clk_int(phy_gtx_clk_int), - .phy_txd_int(phy_txd_int), - .phy_tx_en_int(phy_tx_en_int), - .phy_tx_er_int(phy_tx_er_int), - .phy_reset_n_int(phy_reset_n_int), - .uart_rxd_int(uart_rxd_int), - .uart_txd_int(uart_txd_int) + .uart_txd(uart_txd) ); endmodule diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index d58aa454b..2828b2b7c 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 @@ -24,46 +24,52 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * FPGA core logic + */ module fpga_core # ( - parameter TARGET_XILINX = 1 + parameter TARGET = "XILINX" ) ( /* * Clock: 125MHz * Synchronous reset */ - input wire clk, - input wire rst, + input wire clk, + input wire rst, + /* * GPIO */ - input wire btnu, - input wire btnl, - input wire btnd, - input wire btnr, - input wire btnc, - input wire [7:0] sw, + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, output wire [7:0] led, + /* * Ethernet: 1000BASE-T GMII */ - input wire phy_rx_clk, - input wire [7:0] phy_rxd, - input wire phy_rx_dv, - input wire phy_rx_er, - output wire phy_gtx_clk, + input wire phy_rx_clk, + input wire [7:0] phy_rxd, + input wire phy_rx_dv, + input wire phy_rx_er, + output wire phy_gtx_clk, output wire [7:0] phy_txd, - output wire phy_tx_en, - output wire phy_tx_er, - output wire phy_reset_n, + output wire phy_tx_en, + output wire phy_tx_er, + output wire phy_reset_n, + /* * UART: 115200 bps, 8N1 */ - input wire uart_rxd, - output wire uart_txd + input wire uart_rxd, + output wire uart_txd ); // GMII between MAC and PHY IF @@ -312,7 +318,7 @@ assign phy_reset_n = ~rst; assign uart_txd = 0; gmii_phy_if #( - .TARGET_XILINX(TARGET_XILINX) + .TARGET(TARGET) ) gmii_phy_if_inst ( .clk(clk), diff --git a/example/ATLYS/fpga/rtl/fpga_pads.v b/example/ATLYS/fpga/rtl/fpga_pads.v deleted file mode 100644 index 82222816b..000000000 --- a/example/ATLYS/fpga/rtl/fpga_pads.v +++ /dev/null @@ -1,170 +0,0 @@ -/* - -Copyright (c) 2014 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1 ns / 1 ps - -module fpga_pads ( - /* - * Pads - */ - input wire clk_pad, - input wire reset_n_pad, - input wire btnu_pad, - input wire btnl_pad, - input wire btnd_pad, - input wire btnr_pad, - input wire btnc_pad, - input wire [7:0] sw_pad, - output wire [7:0] led_pad, - input wire phy_rx_clk_pad, - input wire [7:0] phy_rxd_pad, - input wire phy_rx_dv_pad, - input wire phy_rx_er_pad, - output wire phy_gtx_clk_pad, - output wire [7:0] phy_txd_pad, - output wire phy_tx_en_pad, - output wire phy_tx_er_pad, - output wire phy_reset_n_pad, - input wire uart_rxd_pad, - output wire uart_txd_pad, - /* - * Internal - */ - output wire clk_int, - output wire rst_int, - output wire btnu_int, - output wire btnl_int, - output wire btnd_int, - output wire btnr_int, - output wire btnc_int, - output wire [7:0] sw_int, - input wire [7:0] led_int, - output wire phy_rx_clk_int, - output wire [7:0] phy_rxd_int, - output wire phy_rx_dv_int, - output wire phy_rx_er_int, - input wire phy_gtx_clk_int, - input wire [7:0] phy_txd_int, - input wire phy_tx_en_int, - input wire phy_tx_er_int, - input wire phy_reset_n_int, - output wire uart_rxd_int, - input wire uart_txd_int -); - -wire clk_valid; -/* - * Asynchronous reset created by from the combination of the external - * asyncrhonous reset input and the DCM clk_valid output. - */ -wire reset0 = ~reset_n_pad; -wire reset1 = ~clk_valid; - -/* - * Create a 125MHz clock from a 100MHz clock. - */ -dcm_i100_o125 -dcm_inst ( - .CLK_IN1(clk_pad), // IN(1) - .RESET(reset0), // IN(1) - .CLK_OUT1(clk_int), // OUT(1) - .LOCKED(clk_valid) // OUT(1) -); - -/* - * Create a synchronous reset in the 125MHz domain. - */ -sync_reset #( - .N(6) -) -sync_reset_inst ( - .clk(clk_int), // IN(1) - .rst(reset1), // IN(1) - .sync_reset_out(rst_int) // OUT(1) -); - -/* - * Synchronize the inputs. - */ -sync_signal #( - .WIDTH(1), - .N(2) -) -sync_signal_inst ( - .clk(clk_int), //IN(1) - .in({uart_rxd_pad}), //IN(1) - .out({uart_rxd_int}) // OUT(1) -); - -/* - * Debounce the switches - */ -debounce_switch #( - .WIDTH(13), - .N(4), - .RATE(125000) -) -debounce_switch_inst ( - .clk(clk_int), // IN(1) - .rst(rst_int), // IN(1) - .in({btnu_pad, - btnl_pad, - btnd_pad, - btnr_pad, - btnc_pad, - sw_pad}), // IN(13) - .out({btnu_int, - btnl_int, - btnd_int, - btnr_int, - btnc_int, - sw_int}) // OUT(13) -); - -/* - * PHY inputs not synchronized here - */ -assign phy_rx_clk_int = phy_rx_clk_pad; -assign phy_rxd_int = phy_rxd_pad; -assign phy_rx_dv_int = phy_rx_dv_pad; -assign phy_rx_er_int = phy_rx_er_pad; - -/* - * PHY outputs not synchronized here - */ -assign phy_gtx_clk_pad = phy_gtx_clk_int; -assign phy_txd_pad = phy_txd_int; -assign phy_tx_en_pad = phy_tx_en_int; -assign phy_tx_er_pad = phy_tx_er_int; -assign phy_reset_n_pad = phy_reset_n_int; - -/* - * Outputs not synchronized here - */ -assign led_pad = led_int; -assign uart_txd_pad = uart_txd_int; - -endmodule diff --git a/example/ATLYS/fpga/rtl/sync_reset.v b/example/ATLYS/fpga/rtl/sync_reset.v index ffa0530bf..ddd99febe 100644 --- a/example/ATLYS/fpga/rtl/sync_reset.v +++ b/example/ATLYS/fpga/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/example/ATLYS/fpga/rtl/sync_signal.v b/example/ATLYS/fpga/rtl/sync_signal.v index 705d4f8ec..5afcd7170 100644 --- a/example/ATLYS/fpga/rtl/sync_signal.v +++ b/example/ATLYS/fpga/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014 Alex Forencich +Copyright (c) 2014-2016 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 diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index ea14d21b0..2a847ed8b 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 @@ -131,7 +131,7 @@ def dut_fpga_core(clk, def bench(): # Parameters - TARGET_XILINX = 1 + TARGET = "SIM" # Inputs clk = Signal(bool(0)) diff --git a/example/ATLYS/fpga/tb/test_fpga_core.v b/example/ATLYS/fpga/tb/test_fpga_core.v index cf9bf6426..8a2de45d1 100644 --- a/example/ATLYS/fpga/tb/test_fpga_core.v +++ b/example/ATLYS/fpga/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015 Alex Forencich +Copyright (c) 2015-2016 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 @@ -32,7 +32,7 @@ THE SOFTWARE. module test_fpga_core; // Parameters -parameter TARGET_XILINX = 0; +parameter TARGET = "SIM"; // Inputs reg clk = 0; @@ -90,7 +90,7 @@ initial begin end fpga_core #( - .TARGET_XILINX(TARGET_XILINX) + .TARGET(TARGET) ) UUT ( .clk(clk), From 3f2d09624947058addad0731c0b7ce66cf00f009 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 25 Jan 2016 00:50:51 -0800 Subject: [PATCH 268/617] Add XGMII interleaver and deinterleaver --- rtl/xgmii_deinterleave.v | 57 ++++++++++++++++++++++++++++++++++++++++ rtl/xgmii_interleave.v | 57 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 rtl/xgmii_deinterleave.v create mode 100644 rtl/xgmii_interleave.v diff --git a/rtl/xgmii_deinterleave.v b/rtl/xgmii_deinterleave.v new file mode 100644 index 000000000..d19bcb0df --- /dev/null +++ b/rtl/xgmii_deinterleave.v @@ -0,0 +1,57 @@ +/* + +Copyright (c) 2016 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 + +/* + * XGMII control/data deinterleave + */ +module xgmii_deinterleave +( + input wire [72:0] input_xgmii_dc, + + output wire [63:0] output_xgmii_d, + output wire [7:0] output_xgmii_c +); + +assign output_xgmii_d[7:0] = input_xgmii_dc[7:0]; +assign output_xgmii_c[0] = input_xgmii_dc[8]; +assign output_xgmii_d[15:8] = input_xgmii_dc[16:9]; +assign output_xgmii_c[1] = input_xgmii_dc[17]; +assign output_xgmii_d[23:16] = input_xgmii_dc[25:18]; +assign output_xgmii_c[2] = input_xgmii_dc[26]; +assign output_xgmii_d[31:24] = input_xgmii_dc[34:27]; +assign output_xgmii_c[3] = input_xgmii_dc[35]; +assign output_xgmii_d[39:32] = input_xgmii_dc[43:36]; +assign output_xgmii_c[4] = input_xgmii_dc[44]; +assign output_xgmii_d[47:40] = input_xgmii_dc[52:45]; +assign output_xgmii_c[5] = input_xgmii_dc[53]; +assign output_xgmii_d[55:48] = input_xgmii_dc[61:54]; +assign output_xgmii_c[6] = input_xgmii_dc[62]; +assign output_xgmii_d[63:56] = input_xgmii_dc[70:63]; +assign output_xgmii_c[7] = input_xgmii_dc[71]; + +endmodule diff --git a/rtl/xgmii_interleave.v b/rtl/xgmii_interleave.v new file mode 100644 index 000000000..d291703ae --- /dev/null +++ b/rtl/xgmii_interleave.v @@ -0,0 +1,57 @@ +/* + +Copyright (c) 2016 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 + +/* + * XGMII control/data interleave + */ +module xgmii_interleave +( + input wire [63:0] input_xgmii_d, + input wire [7:0] input_xgmii_c, + + output wire [72:0] output_xgmii_dc +); + +assign output_xgmii_dc[7:0] = input_xgmii_d[7:0]; +assign output_xgmii_dc[8] = input_xgmii_c[0]; +assign output_xgmii_dc[16:9] = input_xgmii_d[15:8]; +assign output_xgmii_dc[17] = input_xgmii_c[1]; +assign output_xgmii_dc[25:18] = input_xgmii_d[23:16]; +assign output_xgmii_dc[26] = input_xgmii_c[2]; +assign output_xgmii_dc[34:27] = input_xgmii_d[31:24]; +assign output_xgmii_dc[35] = input_xgmii_c[3]; +assign output_xgmii_dc[43:36] = input_xgmii_d[39:32]; +assign output_xgmii_dc[44] = input_xgmii_c[4]; +assign output_xgmii_dc[52:45] = input_xgmii_d[47:40]; +assign output_xgmii_dc[53] = input_xgmii_c[5]; +assign output_xgmii_dc[61:54] = input_xgmii_d[55:48]; +assign output_xgmii_dc[62] = input_xgmii_c[6]; +assign output_xgmii_dc[70:63] = input_xgmii_d[63:56]; +assign output_xgmii_dc[71] = input_xgmii_c[7]; + +endmodule From eb8dd775a1f1c174111dbca21301937b65ee28ba Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 25 Jan 2016 00:53:06 -0800 Subject: [PATCH 269/617] Add 10G reference design for DE5-Net --- example/DE5-Net/fpga/Makefile | 25 + example/DE5-Net/fpga/README.md | 25 + example/DE5-Net/fpga/common/altera.mk | 141 ++ example/DE5-Net/fpga/cores/Makefile | 23 + example/DE5-Net/fpga/cores/phy.v | 192 +++ example/DE5-Net/fpga/cores/phy_reconfig.v | 101 ++ example/DE5-Net/fpga/fpga.qsf | 1646 ++++++++++++++++++++ example/DE5-Net/fpga/fpga.sdc | 98 ++ example/DE5-Net/fpga/fpga/Makefile | 68 + example/DE5-Net/fpga/lib/eth | 1 + example/DE5-Net/fpga/rtl/debounce_switch.v | 89 ++ example/DE5-Net/fpga/rtl/fpga.v | 422 +++++ example/DE5-Net/fpga/rtl/fpga_core.v | 589 +++++++ example/DE5-Net/fpga/rtl/i2c_master.v | 895 +++++++++++ example/DE5-Net/fpga/rtl/si570_i2c_init.v | 455 ++++++ example/DE5-Net/fpga/rtl/sync_reset.v | 52 + example/DE5-Net/fpga/rtl/sync_signal.v | 58 + example/DE5-Net/fpga/tb/arp_ep.py | 1 + example/DE5-Net/fpga/tb/axis_ep.py | 1 + example/DE5-Net/fpga/tb/eth_ep.py | 1 + example/DE5-Net/fpga/tb/ip_ep.py | 1 + example/DE5-Net/fpga/tb/test_fpga_core.py | 412 +++++ example/DE5-Net/fpga/tb/test_fpga_core.v | 133 ++ example/DE5-Net/fpga/tb/udp_ep.py | 1 + example/DE5-Net/fpga/tb/xgmii_ep.py | 1 + 25 files changed, 5431 insertions(+) create mode 100644 example/DE5-Net/fpga/Makefile create mode 100644 example/DE5-Net/fpga/README.md create mode 100644 example/DE5-Net/fpga/common/altera.mk create mode 100644 example/DE5-Net/fpga/cores/Makefile create mode 100644 example/DE5-Net/fpga/cores/phy.v create mode 100644 example/DE5-Net/fpga/cores/phy_reconfig.v create mode 100644 example/DE5-Net/fpga/fpga.qsf create mode 100644 example/DE5-Net/fpga/fpga.sdc create mode 100644 example/DE5-Net/fpga/fpga/Makefile create mode 120000 example/DE5-Net/fpga/lib/eth create mode 100644 example/DE5-Net/fpga/rtl/debounce_switch.v create mode 100644 example/DE5-Net/fpga/rtl/fpga.v create mode 100644 example/DE5-Net/fpga/rtl/fpga_core.v create mode 100644 example/DE5-Net/fpga/rtl/i2c_master.v create mode 100644 example/DE5-Net/fpga/rtl/si570_i2c_init.v create mode 100644 example/DE5-Net/fpga/rtl/sync_reset.v create mode 100644 example/DE5-Net/fpga/rtl/sync_signal.v create mode 120000 example/DE5-Net/fpga/tb/arp_ep.py create mode 120000 example/DE5-Net/fpga/tb/axis_ep.py create mode 120000 example/DE5-Net/fpga/tb/eth_ep.py create mode 120000 example/DE5-Net/fpga/tb/ip_ep.py create mode 100755 example/DE5-Net/fpga/tb/test_fpga_core.py create mode 100644 example/DE5-Net/fpga/tb/test_fpga_core.v create mode 120000 example/DE5-Net/fpga/tb/udp_ep.py create mode 120000 example/DE5-Net/fpga/tb/xgmii_ep.py diff --git a/example/DE5-Net/fpga/Makefile b/example/DE5-Net/fpga/Makefile new file mode 100644 index 000000000..c0cd7fe7b --- /dev/null +++ b/example/DE5-Net/fpga/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = cores fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #program commands diff --git a/example/DE5-Net/fpga/README.md b/example/DE5-Net/fpga/README.md new file mode 100644 index 000000000..07c43c16e --- /dev/null +++ b/example/DE5-Net/fpga/README.md @@ -0,0 +1,25 @@ +# Verilog Ethernet DE5-Net Example Design + +## Introduction + +This example design targets the Terasic DE5-Net FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +FPGA: 5SGXEA7N2F45C2 +PHY: 10G BASE-R PHY MegaCore + +## How to build + +Run make to build. Ensure that the Altera Quartus toolchain components are +in PATH. + +## How to test + +Run make program to program the DE5-Net board with the Altera software. Then +run netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any +text entered into netcat will be echoed back after pressing enter. + + diff --git a/example/DE5-Net/fpga/common/altera.mk b/example/DE5-Net/fpga/common/altera.mk new file mode 100644 index 000000000..7693415f4 --- /dev/null +++ b/example/DE5-Net/fpga/common/altera.mk @@ -0,0 +1,141 @@ +################################################################### +# +# Altera FPGA Makefile +# +# Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. Stratix V) +# FPGA_DEVICE - FPGA device (e.g. 5SGXEA7N2F45C2) +# SYN_FILES - space-separated list of source files +# QSF_FILES - space-separated list of settings files +# SDC_FILES - space-separated list of timing constraint files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = "Stratix V" +# FPGA_DEVICE = 5SGXEA7N2F45C2 +# SYN_FILES = rtl/fpga.v rtl/clocks.v +# QSF_FILES = fpga.qsf +# SDC_FILES = fpga.sdc +# include ../common/altera.mk +# +################################################################### + +# phony targets +.PHONY: clean + +# output files to hang on to +.PRECIOUS: %.sof %.map.rpt %.fit.rpt %.asm.rpt %.sta.rpt + +# any project specific settings +-include ../config.mk + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) + +ifdef QSF_FILES + QSF_FILES_REL = $(patsubst %, ../%, $(QSF_FILES)) +else + QSF_FILES_REL = ../$(FPGA_TOP).qsf +endif + +SDC_FILES_REL = $(patsubst %, ../%, $(SDC_FILES)) + +ASSIGNMENT_FILES = $(FPGA_TOP).qpf $(FPGA_TOP).qsf + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and database +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).sof + +clean: + rm -rf *.rpt *.summary *.smsg *.chg smart.log *.htm *.eqn *.pin *.sof *.pof *.qsf *.qpf *.jdi *.sld *.txt db incremental_db reconfig_mif + +map: smart.log $(PROJECT).map.rpt +fit: smart.log $(PROJECT).fit.rpt +asm: smart.log $(PROJECT).asm.rpt +sta: smart.log $(PROJECT).sta.rpt +smart: smart.log + +################################################################### +# Executable Configuration +################################################################### + +MAP_ARGS = --family=$(FPGA_FAMILY) +FIT_ARGS = --part=$(FPGA_DEVICE) +ASM_ARGS = +STA_ARGS = + +################################################################### +# Target implementations +################################################################### + +STAMP = echo done > + +%.map.rpt: map.chg $(SYN_FILES_REL) + quartus_map $(MAP_ARGS) $(FPGA_TOP) + +%.fit.rpt: fit.chg %.map.rpt + quartus_fit $(FIT_ARGS) $(FPGA_TOP) + +%.sta.rpt: sta.chg %.fit.rpt + quartus_sta $(STA_ARGS) $(FPGA_TOP) + +%.asm.rpt: asm.chg %.sta.rpt + quartus_asm $(ASM_ARGS) $(FPGA_TOP) + mkdir -p rev + EXT=sof; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $*.$$EXT rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + +%.sof: smart.log %.asm.rpt + + +smart.log: $(ASSIGNMENT_FILES) + quartus_sh --determine_smart_action $(FPGA_TOP) > smart.log + +################################################################### +# Project initialization +################################################################### + +$(ASSIGNMENT_FILES): $(QSF_FILES_REL) $(SYN_FILES_REL) + rm -f $(FPGA_TOP).qsf + quartus_sh --prepare -f $(FPGA_FAMILY) -d $(FPGA_DEVICE) -t $(FPGA_TOP) $(FPGA_TOP) + echo >> $(FPGA_TOP).qsf + echo >> $(FPGA_TOP).qsf + echo "# Source files" >> $(FPGA_TOP).qsf + for x in $(SYN_FILES_REL); do \ + case $${x##*.} in \ + v|V) echo set_global_assignment -name VERILOG_FILE $$x >> $(FPGA_TOP).qsf ;;\ + vhd|VHD) echo set_global_assignment -name VHDL_FILE $$x >> $(FPGA_TOP).qsf ;;\ + qip|QIP) echo set_global_assignment -name QIP_FILE $$x >> $(FPGA_TOP).qsf ;;\ + *) echo set_global_assignment -name SOURCE_FILE $$x >> $(FPGA_TOP).qsf ;;\ + esac; \ + done + echo >> $(FPGA_TOP).qsf + echo "# SDC files" >> $(FPGA_TOP).qsf + for x in $(SDC_FILES_REL); do echo set_global_assignment -name SDC_FILE $$x >> $(FPGA_TOP).qsf; done + for x in $(QSF_FILES_REL); do printf "\n#\n# Included QSF file $$x\n#\n" >> $(FPGA_TOP).qsf; cat $$x >> $(FPGA_TOP).qsf; done + +map.chg: + $(STAMP) map.chg +fit.chg: + $(STAMP) fit.chg +sta.chg: + $(STAMP) sta.chg +asm.chg: + $(STAMP) asm.chg + + diff --git a/example/DE5-Net/fpga/cores/Makefile b/example/DE5-Net/fpga/cores/Makefile new file mode 100644 index 000000000..9124fae06 --- /dev/null +++ b/example/DE5-Net/fpga/cores/Makefile @@ -0,0 +1,23 @@ +# Tools +QMEGAWIZ=qmegawiz + +# Sources +QMWSRC=phy.v +QMWSRC+=phy_reconfig.v + +# Targets +TARGETS=$(QMWSRC:.v=) + +# Rules +.PHONY: all +all: $(TARGETS) + +.PHONY: clean +clean: + -rm -rf $(TARGETS) + +%: %.v + mkdir -p $@ + cp -a $< $@ + cd $@ && $(QMEGAWIZ) -silent $< + diff --git a/example/DE5-Net/fpga/cores/phy.v b/example/DE5-Net/fpga/cores/phy.v new file mode 100644 index 000000000..73ba98c79 --- /dev/null +++ b/example/DE5-Net/fpga/cores/phy.v @@ -0,0 +1,192 @@ +// megafunction wizard: %10GBASE-R PHY v15.0% +// GENERATION: XML +// phy.v + +// Generated using ACDS version 15.0 153 + +`timescale 1 ps / 1 ps +module phy ( + input wire pll_ref_clk, // pll_ref_clk.clk + output wire xgmii_rx_clk, // xgmii_rx_clk.clk + output wire pll_locked, // pll_locked.export + output wire tx_ready, // tx_ready.export + input wire xgmii_tx_clk, // xgmii_tx_clk.clk + output wire rx_ready, // rx_ready.export + output wire [3:0] rx_data_ready, // rx_data_ready.export + output wire [71:0] xgmii_rx_dc_0, // xgmii_rx_dc_0.data + input wire rx_serial_data_0, // rx_serial_data_0.export + output wire [71:0] xgmii_rx_dc_1, // xgmii_rx_dc_1.data + input wire rx_serial_data_1, // rx_serial_data_1.export + output wire [71:0] xgmii_rx_dc_2, // xgmii_rx_dc_2.data + input wire rx_serial_data_2, // rx_serial_data_2.export + output wire [71:0] xgmii_rx_dc_3, // xgmii_rx_dc_3.data + input wire rx_serial_data_3, // rx_serial_data_3.export + input wire [71:0] xgmii_tx_dc_0, // xgmii_tx_dc_0.data + output wire [0:0] tx_serial_data_0, // tx_serial_data_0.export + input wire [71:0] xgmii_tx_dc_1, // xgmii_tx_dc_1.data + output wire [0:0] tx_serial_data_1, // tx_serial_data_1.export + input wire [71:0] xgmii_tx_dc_2, // xgmii_tx_dc_2.data + output wire [0:0] tx_serial_data_2, // tx_serial_data_2.export + input wire [71:0] xgmii_tx_dc_3, // xgmii_tx_dc_3.data + output wire [0:0] tx_serial_data_3, // tx_serial_data_3.export + output wire [367:0] reconfig_from_xcvr, // reconfig_from_xcvr.reconfig_from_xcvr + input wire [559:0] reconfig_to_xcvr, // reconfig_to_xcvr.reconfig_to_xcvr + input wire phy_mgmt_clk, // phy_mgmt_clk.clk + input wire phy_mgmt_clk_reset, // phy_mgmt_clk_reset.reset + input wire [8:0] phy_mgmt_address, // phy_mgmt.address + input wire phy_mgmt_read, // .read + output wire [31:0] phy_mgmt_readdata, // .readdata + input wire phy_mgmt_write, // .write + input wire [31:0] phy_mgmt_writedata, // .writedata + output wire phy_mgmt_waitrequest // .waitrequest + ); + + wire [3:0] phy_inst_tx_serial_data; // port fragment + wire [287:0] phy_inst_xgmii_rx_dc; // port fragment + + altera_xcvr_10gbaser #( + .device_family ("Stratix V"), + .num_channels (4), + .operation_mode ("duplex"), + .external_pma_ctrl_config (0), + .control_pin_out (0), + .recovered_clk_out (0), + .pll_locked_out (1), + .ref_clk_freq ("644.53125 MHz"), + .pma_mode (40), + .pll_type ("CMU"), + .starting_channel_number (0), + .reconfig_interfaces (8), + .rx_use_coreclk (0), + .embedded_reset (1), + .latadj (0), + .high_precision_latadj (1), + .tx_termination ("OCT_100_OHMS"), + .tx_vod_selection (7), + .tx_preemp_pretap (0), + .tx_preemp_pretap_inv (0), + .tx_preemp_tap_1 (15), + .tx_preemp_tap_2 (0), + .tx_preemp_tap_2_inv (0), + .rx_common_mode ("0.82v"), + .rx_termination ("OCT_100_OHMS"), + .rx_eq_dc_gain (0), + .rx_eq_ctrl (0), + .mgmt_clk_in_mhz (150) + ) phy_inst ( + .pll_ref_clk (pll_ref_clk), // pll_ref_clk.clk + .xgmii_rx_clk (xgmii_rx_clk), // xgmii_rx_clk.clk + .pll_locked (pll_locked), // pll_locked.export + .tx_ready (tx_ready), // tx_ready.export + .xgmii_tx_clk (xgmii_tx_clk), // xgmii_tx_clk.clk + .rx_ready (rx_ready), // rx_ready.export + .rx_data_ready (rx_data_ready), // rx_data_ready.export + .xgmii_rx_dc (phy_inst_xgmii_rx_dc), // xgmii_rx_dc_0.data + .rx_serial_data ({rx_serial_data_3,rx_serial_data_2,rx_serial_data_1,rx_serial_data_0}), // rx_serial_data_0.export + .xgmii_tx_dc ({xgmii_tx_dc_3[71:0],xgmii_tx_dc_2[71:0],xgmii_tx_dc_1[71:0],xgmii_tx_dc_0[71:0]}), // xgmii_tx_dc_0.data + .tx_serial_data (phy_inst_tx_serial_data), // tx_serial_data_0.export + .reconfig_from_xcvr (reconfig_from_xcvr), // reconfig_from_xcvr.reconfig_from_xcvr + .reconfig_to_xcvr (reconfig_to_xcvr), // reconfig_to_xcvr.reconfig_to_xcvr + .phy_mgmt_clk (phy_mgmt_clk), // phy_mgmt_clk.clk + .phy_mgmt_clk_reset (phy_mgmt_clk_reset), // phy_mgmt_clk_reset.reset + .phy_mgmt_address (phy_mgmt_address), // phy_mgmt.address + .phy_mgmt_read (phy_mgmt_read), // .read + .phy_mgmt_readdata (phy_mgmt_readdata), // .readdata + .phy_mgmt_write (phy_mgmt_write), // .write + .phy_mgmt_writedata (phy_mgmt_writedata), // .writedata + .phy_mgmt_waitrequest (phy_mgmt_waitrequest), // .waitrequest + .rx_block_lock (), // (terminated) + .rx_hi_ber (), // (terminated) + .rx_recovered_clk (), // (terminated) + .rx_coreclkin (1'b0), // (terminated) + .gxb_pdn (1'b0), // (terminated) + .pll_pdn (1'b0), // (terminated) + .cal_blk_pdn (1'b0), // (terminated) + .cal_blk_clk (1'b0), // (terminated) + .tx_digitalreset (4'b0000), // (terminated) + .tx_analogreset (4'b0000), // (terminated) + .tx_cal_busy (), // (terminated) + .pll_powerdown (4'b0000), // (terminated) + .rx_digitalreset (4'b0000), // (terminated) + .rx_analogreset (4'b0000), // (terminated) + .rx_cal_busy (), // (terminated) + .rx_is_lockedtodata (), // (terminated) + .rx_latency_adj (), // (terminated) + .tx_latency_adj () // (terminated) + ); + + assign tx_serial_data_0 = { phy_inst_tx_serial_data[0:0] }; + + assign xgmii_rx_dc_0 = { phy_inst_xgmii_rx_dc[71:0] }; + + assign tx_serial_data_1 = { phy_inst_tx_serial_data[1:1] }; + + assign xgmii_rx_dc_1 = { phy_inst_xgmii_rx_dc[143:72] }; + + assign xgmii_rx_dc_2 = { phy_inst_xgmii_rx_dc[215:144] }; + + assign xgmii_rx_dc_3 = { phy_inst_xgmii_rx_dc[287:216] }; + + assign tx_serial_data_2 = { phy_inst_tx_serial_data[2:2] }; + + assign tx_serial_data_3 = { phy_inst_tx_serial_data[3:3] }; + +endmodule +// Retrieval info: +// +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// IPFS_FILES : phy.vo +// RELATED_FILES: phy.v, altera_xcvr_functions.sv, alt_reset_ctrl_lego.sv, alt_reset_ctrl_tgx_cdrauto.sv, alt_xcvr_resync.sv, alt_xcvr_csr_common_h.sv, alt_xcvr_csr_common.sv, alt_xcvr_csr_pcs8g_h.sv, alt_xcvr_csr_pcs8g.sv, alt_xcvr_csr_selector.sv, alt_xcvr_mgmt2dec.sv, altera_wait_generate.v, altera_10gbaser_phy_handshake_clock_crosser.v, altera_10gbaser_phy_clock_crosser.v, altera_10gbaser_phy_pipeline_stage.sv, altera_10gbaser_phy_pipeline_base.v, csr_pcs10gbaser_h.sv, csr_pcs10gbaser.sv, sv_pcs.sv, sv_pcs_ch.sv, sv_pma.sv, sv_reconfig_bundle_to_xcvr.sv, sv_reconfig_bundle_to_ip.sv, sv_reconfig_bundle_merger.sv, sv_rx_pma.sv, sv_tx_pma.sv, sv_tx_pma_ch.sv, sv_xcvr_h.sv, sv_xcvr_avmm_csr.sv, sv_xcvr_avmm_dcd.sv, sv_xcvr_avmm.sv, sv_xcvr_data_adapter.sv, sv_xcvr_native.sv, sv_xcvr_plls.sv, sv_hssi_10g_rx_pcs_rbc.sv, sv_hssi_10g_tx_pcs_rbc.sv, sv_hssi_8g_rx_pcs_rbc.sv, sv_hssi_8g_tx_pcs_rbc.sv, sv_hssi_8g_pcs_aggregate_rbc.sv, sv_hssi_common_pcs_pma_interface_rbc.sv, sv_hssi_common_pld_pcs_interface_rbc.sv, sv_hssi_pipe_gen1_2_rbc.sv, sv_hssi_pipe_gen3_rbc.sv, sv_hssi_rx_pcs_pma_interface_rbc.sv, sv_hssi_rx_pld_pcs_interface_rbc.sv, sv_hssi_tx_pcs_pma_interface_rbc.sv, sv_hssi_tx_pld_pcs_interface_rbc.sv, sv_xcvr_10gbaser_nr.sv, sv_xcvr_10gbaser_native.sv, altera_xcvr_10gbaser.sv, altera_xcvr_reset_control.sv, alt_xcvr_reset_counter.sv, alt_xcvr_arbiter.sv, alt_xcvr_m2s.sv diff --git a/example/DE5-Net/fpga/cores/phy_reconfig.v b/example/DE5-Net/fpga/cores/phy_reconfig.v new file mode 100644 index 000000000..c1236c321 --- /dev/null +++ b/example/DE5-Net/fpga/cores/phy_reconfig.v @@ -0,0 +1,101 @@ +// megafunction wizard: %Transceiver Reconfiguration Controller v15.0% +// GENERATION: XML +// phy_reconfig.v + +// Generated using ACDS version 15.0 153 + +`timescale 1 ps / 1 ps +module phy_reconfig ( + output wire reconfig_busy, // reconfig_busy.reconfig_busy + input wire mgmt_clk_clk, // mgmt_clk_clk.clk + input wire mgmt_rst_reset, // mgmt_rst_reset.reset + input wire [6:0] reconfig_mgmt_address, // reconfig_mgmt.address + input wire reconfig_mgmt_read, // .read + output wire [31:0] reconfig_mgmt_readdata, // .readdata + output wire reconfig_mgmt_waitrequest, // .waitrequest + input wire reconfig_mgmt_write, // .write + input wire [31:0] reconfig_mgmt_writedata, // .writedata + output wire [559:0] reconfig_to_xcvr, // reconfig_to_xcvr.reconfig_to_xcvr + input wire [367:0] reconfig_from_xcvr // reconfig_from_xcvr.reconfig_from_xcvr + ); + + alt_xcvr_reconfig #( + .device_family ("Stratix V"), + .number_of_reconfig_interfaces (8), + .enable_offset (1), + .enable_lc (1), + .enable_dcd (0), + .enable_dcd_power_up (1), + .enable_analog (1), + .enable_eyemon (0), + .enable_ber (0), + .enable_dfe (0), + .enable_adce (0), + .enable_mif (0), + .enable_pll (0) + ) phy_reconfig_inst ( + .reconfig_busy (reconfig_busy), // reconfig_busy.reconfig_busy + .mgmt_clk_clk (mgmt_clk_clk), // mgmt_clk_clk.clk + .mgmt_rst_reset (mgmt_rst_reset), // mgmt_rst_reset.reset + .reconfig_mgmt_address (reconfig_mgmt_address), // reconfig_mgmt.address + .reconfig_mgmt_read (reconfig_mgmt_read), // .read + .reconfig_mgmt_readdata (reconfig_mgmt_readdata), // .readdata + .reconfig_mgmt_waitrequest (reconfig_mgmt_waitrequest), // .waitrequest + .reconfig_mgmt_write (reconfig_mgmt_write), // .write + .reconfig_mgmt_writedata (reconfig_mgmt_writedata), // .writedata + .reconfig_to_xcvr (reconfig_to_xcvr), // reconfig_to_xcvr.reconfig_to_xcvr + .reconfig_from_xcvr (reconfig_from_xcvr), // reconfig_from_xcvr.reconfig_from_xcvr + .tx_cal_busy (), // (terminated) + .rx_cal_busy (), // (terminated) + .cal_busy_in (1'b0), // (terminated) + .reconfig_mif_address (), // (terminated) + .reconfig_mif_read (), // (terminated) + .reconfig_mif_readdata (16'b0000000000000000), // (terminated) + .reconfig_mif_waitrequest (1'b0) // (terminated) + ); + +endmodule +// Retrieval info: +// +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// IPFS_FILES : phy_reconfig.vo +// RELATED_FILES: phy_reconfig.v, altera_xcvr_functions.sv, sv_xcvr_h.sv, alt_xcvr_resync.sv, alt_xcvr_reconfig_h.sv, sv_xcvr_dfe_cal_sweep_h.sv, alt_xcvr_reconfig.sv, alt_xcvr_reconfig_sv.sv, alt_xcvr_reconfig_cal_seq.sv, alt_xreconf_cif.sv, alt_xreconf_uif.sv, alt_xreconf_basic_acq.sv, alt_xcvr_reconfig_analog.sv, alt_xcvr_reconfig_analog_sv.sv, alt_xreconf_analog_datactrl.sv, alt_xreconf_analog_rmw.sv, alt_xreconf_analog_ctrlsm.sv, alt_xcvr_reconfig_offset_cancellation.sv, alt_xcvr_reconfig_offset_cancellation_sv.sv, alt_xcvr_reconfig_eyemon.sv, alt_xcvr_reconfig_eyemon_sv.sv, alt_xcvr_reconfig_eyemon_ctrl_sv.sv, alt_xcvr_reconfig_eyemon_ber_sv.sv, ber_reader_dcfifo.v, step_to_mon_sv.sv, mon_to_step_sv.sv, alt_xcvr_reconfig_dfe.sv, alt_xcvr_reconfig_dfe_sv.sv, alt_xcvr_reconfig_dfe_reg_sv.sv, alt_xcvr_reconfig_dfe_cal_sv.sv, alt_xcvr_reconfig_dfe_cal_sweep_sv.sv, alt_xcvr_reconfig_dfe_cal_sweep_datapath_sv.sv, alt_xcvr_reconfig_dfe_oc_cal_sv.sv, alt_xcvr_reconfig_dfe_pi_phase_sv.sv, alt_xcvr_reconfig_dfe_step_to_mon_en_sv.sv, alt_xcvr_reconfig_dfe_adapt_tap_sv.sv, alt_xcvr_reconfig_dfe_ctrl_mux_sv.sv, alt_xcvr_reconfig_dfe_local_reset_sv.sv, alt_xcvr_reconfig_dfe_cal_sim_sv.sv, alt_xcvr_reconfig_dfe_adapt_tap_sim_sv.sv, alt_xcvr_reconfig_adce.sv, alt_xcvr_reconfig_adce_sv.sv, alt_xcvr_reconfig_adce_datactrl_sv.sv, alt_xcvr_reconfig_dcd.sv, alt_xcvr_reconfig_dcd_sv.sv, alt_xcvr_reconfig_dcd_cal.sv, alt_xcvr_reconfig_dcd_control.sv, alt_xcvr_reconfig_dcd_datapath.sv, alt_xcvr_reconfig_dcd_pll_reset.sv, alt_xcvr_reconfig_dcd_eye_width.sv, alt_xcvr_reconfig_dcd_align_clk.sv, alt_xcvr_reconfig_dcd_get_sum.sv, alt_xcvr_reconfig_dcd_cal_sim_model.sv, alt_xcvr_reconfig_mif.sv, sv_xcvr_reconfig_mif.sv, sv_xcvr_reconfig_mif_ctrl.sv, sv_xcvr_reconfig_mif_avmm.sv, alt_xcvr_reconfig_pll.sv, sv_xcvr_reconfig_pll.sv, sv_xcvr_reconfig_pll_ctrl.sv, alt_xcvr_reconfig_soc.sv, alt_xcvr_reconfig_cpu_ram.sv, alt_xcvr_reconfig_direct.sv, sv_xrbasic_l2p_addr.sv, sv_xrbasic_l2p_ch.sv, sv_xrbasic_l2p_rom.sv, sv_xrbasic_lif_csr.sv, sv_xrbasic_lif.sv, sv_xcvr_reconfig_basic.sv, alt_arbiter_acq.sv, alt_xcvr_reconfig_basic.sv, alt_xcvr_arbiter.sv, alt_xcvr_m2s.sv, altera_wait_generate.v, alt_xcvr_csr_selector.sv, sv_reconfig_bundle_to_basic.sv, alt_xcvr_reconfig_cpu.v, alt_xcvr_reconfig_cpu_reconfig_cpu.v, alt_xcvr_reconfig_cpu_reconfig_cpu_test_bench.v, alt_xcvr_reconfig_cpu_mm_interconnect_0.v, alt_xcvr_reconfig_cpu_irq_mapper.sv, altera_reset_controller.v, altera_reset_synchronizer.v, altera_merlin_master_translator.sv, altera_merlin_slave_translator.sv, altera_merlin_master_agent.sv, altera_merlin_slave_agent.sv, altera_merlin_burst_uncompressor.sv, altera_avalon_sc_fifo.v, alt_xcvr_reconfig_cpu_mm_interconnect_0_router.sv, alt_xcvr_reconfig_cpu_mm_interconnect_0_router_001.sv, alt_xcvr_reconfig_cpu_mm_interconnect_0_router_002.sv, alt_xcvr_reconfig_cpu_mm_interconnect_0_router_003.sv, alt_xcvr_reconfig_cpu_mm_interconnect_0_cmd_demux.sv, alt_xcvr_reconfig_cpu_mm_interconnect_0_cmd_demux_001.sv, altera_merlin_arbitrator.sv, alt_xcvr_reconfig_cpu_mm_interconnect_0_cmd_mux.sv, alt_xcvr_reconfig_cpu_mm_interconnect_0_cmd_mux_001.sv, alt_xcvr_reconfig_cpu_mm_interconnect_0_rsp_mux.sv, alt_xcvr_reconfig_cpu_mm_interconnect_0_rsp_mux_001.sv, alt_xcvr_reconfig_cpu_mm_interconnect_0_avalon_st_adapter.v, alt_xcvr_reconfig_cpu_mm_interconnect_0_avalon_st_adapter_error_adapter_0.sv diff --git a/example/DE5-Net/fpga/fpga.qsf b/example/DE5-Net/fpga/fpga.qsf new file mode 100644 index 000000000..4e91c5cef --- /dev/null +++ b/example/DE5-Net/fpga/fpga.qsf @@ -0,0 +1,1646 @@ +#============================================================ +# BUTTON +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to BUTTON[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to BUTTON[1] +set_instance_assignment -name IO_STANDARD "2.5 V" -to BUTTON[2] +set_instance_assignment -name IO_STANDARD "2.5 V" -to BUTTON[3] +#============================================================ +# CLOCK +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to CLOCK_SCL +set_instance_assignment -name IO_STANDARD "2.5 V" -to CLOCK_SDA +#============================================================ +# CPU +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to CPU_RESET_n +#============================================================ +# DDR3A +#============================================================ +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[2] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[3] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[4] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[5] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[6] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[7] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[8] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[9] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[10] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[11] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[12] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[13] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[14] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_A[15] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_BA[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_BA[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_BA[2] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_CAS_n +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_CK[0] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_CK[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_CKE[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_CKE[1] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_CK_n[0] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_CK_n[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_CS_n[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_CS_n[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DM[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DM[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DM[2] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DM[3] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DM[4] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DM[5] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DM[6] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DM[7] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[2] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[3] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[4] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[5] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[6] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[7] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[8] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[9] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[10] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[11] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[12] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[13] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[14] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[15] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[16] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[17] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[18] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[19] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[20] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[21] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[22] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[23] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[24] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[25] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[26] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[27] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[28] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[29] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[30] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[31] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[32] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[33] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[34] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[35] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[36] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[37] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[38] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[39] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[40] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[41] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[42] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[43] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[44] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[45] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[46] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[47] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[48] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[49] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[50] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[51] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[52] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[53] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[54] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[55] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[56] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[57] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[58] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[59] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[60] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[61] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[62] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_DQ[63] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS[0] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS[1] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS[2] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS[3] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS[4] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS[5] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS[6] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS[7] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS_n[0] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS_n[1] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS_n[2] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS_n[3] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS_n[4] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS_n[5] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS_n[6] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3A_DQS_n[7] +set_instance_assignment -name IO_STANDARD "1.5 V" -to DDR3A_EVENT_n +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_ODT[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_ODT[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_RAS_n +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_RESET_n +set_instance_assignment -name IO_STANDARD "1.5 V" -to DDR3A_SCL +set_instance_assignment -name IO_STANDARD "1.5 V" -to DDR3A_SDA +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3A_WE_n +#============================================================ +# DDR3B +#============================================================ +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[2] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[3] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[4] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[5] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[6] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[7] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[8] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[9] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[10] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[11] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[12] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[13] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[14] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_A[15] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_BA[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_BA[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_BA[2] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_CAS_n +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_CK[0] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_CK[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_CKE[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_CKE[1] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_CK_n[0] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_CK_n[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_CS_n[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_CS_n[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DM[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DM[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DM[2] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DM[3] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DM[4] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DM[5] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DM[6] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DM[7] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[2] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[3] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[4] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[5] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[6] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[7] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[8] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[9] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[10] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[11] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[12] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[13] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[14] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[15] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[16] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[17] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[18] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[19] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[20] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[21] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[22] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[23] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[24] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[25] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[26] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[27] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[28] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[29] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[30] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[31] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[32] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[33] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[34] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[35] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[36] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[37] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[38] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[39] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[40] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[41] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[42] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[43] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[44] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[45] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[46] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[47] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[48] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[49] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[50] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[51] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[52] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[53] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[54] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[55] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[56] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[57] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[58] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[59] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[60] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[61] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[62] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_DQ[63] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS[0] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS[1] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS[2] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS[3] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS[4] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS[5] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS[6] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS[7] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS_n[0] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS_n[1] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS_n[2] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS_n[3] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS_n[4] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS_n[5] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS_n[6] +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to DDR3B_DQS_n[7] +set_instance_assignment -name IO_STANDARD "1.5 V" -to DDR3B_EVENT_n +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_ODT[0] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_ODT[1] +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_RAS_n +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_RESET_n +set_instance_assignment -name IO_STANDARD "1.5 V" -to DDR3B_SCL +set_instance_assignment -name IO_STANDARD "1.5 V" -to DDR3B_SDA +set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to DDR3B_WE_n +#============================================================ +# FAN +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to FAN_CTRL +#============================================================ +# FLASH +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to FLASH_ADV_n +set_instance_assignment -name IO_STANDARD "2.5 V" -to FLASH_CE_n[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FLASH_CE_n[1] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FLASH_CLK +set_instance_assignment -name IO_STANDARD "2.5 V" -to FLASH_OE_n +set_instance_assignment -name IO_STANDARD "2.5 V" -to FLASH_RDY_BSY_n[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FLASH_RDY_BSY_n[1] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FLASH_RESET_n +set_instance_assignment -name IO_STANDARD "2.5 V" -to FLASH_WE_n +#============================================================ +# FSM +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[1] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[2] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[3] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[4] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[5] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[6] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[7] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[8] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[9] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[10] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[11] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[12] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[13] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[14] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[15] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[16] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[17] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[18] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[19] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[20] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[21] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[22] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[23] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[24] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[25] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_A[26] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[1] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[2] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[3] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[4] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[5] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[6] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[7] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[8] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[9] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[10] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[11] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[12] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[13] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[14] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[15] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[16] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[17] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[18] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[19] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[20] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[21] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[22] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[23] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[24] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[25] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[26] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[27] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[28] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[29] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[30] +set_instance_assignment -name IO_STANDARD "2.5 V" -to FSM_D[31] +#============================================================ +# HEX0 +#============================================================ +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX0_D[0] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX0_D[1] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX0_D[2] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX0_D[3] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX0_D[4] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX0_D[5] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX0_D[6] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX0_DP +#============================================================ +# HEX1 +#============================================================ +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX1_D[0] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX1_D[1] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX1_D[2] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX1_D[3] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX1_D[4] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX1_D[5] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX1_D[6] +set_instance_assignment -name IO_STANDARD "1.5 V" -to HEX1_DP +#============================================================ +# LED +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED[1] +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED[2] +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED[3] +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED_BRACKET[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED_BRACKET[1] +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED_BRACKET[2] +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED_BRACKET[3] +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED_RJ45_L +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED_RJ45_R +#============================================================ +# MAX2 +#============================================================ +#============================================================ +# OSC +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to OSC_50_B3B +set_instance_assignment -name IO_STANDARD "1.8 V" -to OSC_50_B3D +set_instance_assignment -name IO_STANDARD "1.8 V" -to OSC_50_B4A +set_instance_assignment -name IO_STANDARD "1.8 V" -to OSC_50_B4D +set_instance_assignment -name IO_STANDARD "1.5 V" -to OSC_50_B7A +set_instance_assignment -name IO_STANDARD "1.5 V" -to OSC_50_B7D +set_instance_assignment -name IO_STANDARD "1.5 V" -to OSC_50_B8A +set_instance_assignment -name IO_STANDARD "1.8 V" -to OSC_50_B8D +#============================================================ +# PCIE +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to PCIE_PERST_n +set_instance_assignment -name IO_STANDARD HCSL -to PCIE_REFCLK_p +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_RX_p[0] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_RX_p[1] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_RX_p[2] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_RX_p[3] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_RX_p[4] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_RX_p[5] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_RX_p[6] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_RX_p[7] +set_instance_assignment -name IO_STANDARD "2.5 V" -to PCIE_SMBCLK +set_instance_assignment -name IO_STANDARD "2.5 V" -to PCIE_SMBDAT +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_TX_p[0] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_TX_p[1] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_TX_p[2] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_TX_p[3] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_TX_p[4] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_TX_p[5] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_TX_p[6] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_TX_p[7] +set_instance_assignment -name IO_STANDARD "2.5 V" -to PCIE_WAKE_n +#============================================================ +# QDRIIA +#============================================================ +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[18] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[19] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_A[20] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_BWS_n[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_BWS_n[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_CQ_n +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_CQ_p +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_D[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_DOFF_n +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to QDRIIA_K_n +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to QDRIIA_K_p +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_ODT +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_Q[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_QVLD +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_RPS_n +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIA_WPS_n +#============================================================ +# QDRIIB +#============================================================ +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[18] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[19] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_A[20] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_BWS_n[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_BWS_n[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_CQ_n +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_CQ_p +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_D[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_DOFF_n +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to QDRIIB_K_n +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to QDRIIB_K_p +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_ODT +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_Q[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_QVLD +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_RPS_n +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIB_WPS_n +#============================================================ +# QDRIIC +#============================================================ +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[18] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[19] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_A[20] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_BWS_n[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_BWS_n[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_CQ_n +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_CQ_p +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_D[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_DOFF_n +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to QDRIIC_K_n +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to QDRIIC_K_p +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_ODT +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_Q[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_QVLD +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_RPS_n +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIIC_WPS_n +#============================================================ +# QDRIID +#============================================================ +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[18] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[19] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_A[20] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_BWS_n[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_BWS_n[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_CQ_n +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_CQ_p +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_D[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_DOFF_n +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to QDRIID_K_n +set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to QDRIID_K_p +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_ODT +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[0] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[1] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[2] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[3] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[4] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[5] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[6] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[7] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[8] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[9] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[10] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[11] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[12] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[13] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[14] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[15] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[16] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_Q[17] +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_QVLD +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_RPS_n +set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to QDRIID_WPS_n +#============================================================ +# RS422 +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to RS422_DE +set_instance_assignment -name IO_STANDARD "2.5 V" -to RS422_DIN +set_instance_assignment -name IO_STANDARD "2.5 V" -to RS422_DOUT +set_instance_assignment -name IO_STANDARD "2.5 V" -to RS422_RE_n +set_instance_assignment -name IO_STANDARD "2.5 V" -to RS422_TE +#============================================================ +# RZQ +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to RZQ_0 +set_instance_assignment -name IO_STANDARD "1.8 V" -to RZQ_1 +set_instance_assignment -name IO_STANDARD "1.5 V" -to RZQ_4 +set_instance_assignment -name IO_STANDARD "1.5 V" -to RZQ_5 +#============================================================ +# SATA +#============================================================ +#============================================================ +# SFP10G +#============================================================ +#============================================================ +# SFP1G +#============================================================ +set_instance_assignment -name IO_STANDARD HCSL -to SFP1G_REFCLK_p +#============================================================ +# SFPA +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPA_LOS +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPA_MOD0_PRSNT_n +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPA_MOD1_SCL +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPA_MOD2_SDA +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPA_RATESEL[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPA_RATESEL[1] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SFPA_RX_p +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPA_TXDISABLE +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPA_TXFAULT +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SFPA_TX_p +#============================================================ +# SFPB +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPB_LOS +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPB_MOD0_PRSNT_n +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPB_MOD1_SCL +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPB_MOD2_SDA +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPB_RATESEL[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPB_RATESEL[1] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SFPB_RX_p +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPB_TXDISABLE +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPB_TXFAULT +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SFPB_TX_p +#============================================================ +# SFPC +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPC_LOS +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPC_MOD0_PRSNT_n +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPC_MOD1_SCL +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPC_MOD2_SDA +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPC_RATESEL[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPC_RATESEL[1] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SFPC_RX_p +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPC_TXDISABLE +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPC_TXFAULT +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SFPC_TX_p +#============================================================ +# SFPD +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPD_LOS +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPD_MOD0_PRSNT_n +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPD_MOD1_SCL +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPD_MOD2_SDA +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPD_RATESEL[0] +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPD_RATESEL[1] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SFPD_RX_p +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPD_TXDISABLE +set_instance_assignment -name IO_STANDARD "2.5 V" -to SFPD_TXFAULT +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SFPD_TX_p +set_instance_assignment -name IO_STANDARD HCSL -to SFP_REFCLK_p +#============================================================ +# SMA +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to SMA_CLKIN +set_instance_assignment -name IO_STANDARD "2.5 V" -to SMA_CLKOUT +#============================================================ +# SW +#============================================================ +set_instance_assignment -name IO_STANDARD "1.8 V" -to SW[0] +set_instance_assignment -name IO_STANDARD "1.8 V" -to SW[1] +set_instance_assignment -name IO_STANDARD "1.8 V" -to SW[2] +set_instance_assignment -name IO_STANDARD "1.8 V" -to SW[3] +#============================================================ +# TEMP +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to TEMP_CLK +set_instance_assignment -name IO_STANDARD "2.5 V" -to TEMP_DATA +set_instance_assignment -name IO_STANDARD "2.5 V" -to TEMP_INT_n +set_instance_assignment -name IO_STANDARD "2.5 V" -to TEMP_OVERT_n + +#============================================================ +# SATA +#============================================================ +set_instance_assignment -name IO_STANDARD HCSL -to SATA_HOST_REFCLK_p +set_instance_assignment -name IO_STANDARD HCSL -to SATA_DEVICE_REFCLK_p +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SATA_DEVICE_RX_p[0] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SATA_DEVICE_RX_p[1] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SATA_DEVICE_TX_p[0] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SATA_DEVICE_TX_p[1] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SATA_HOST_RX_p[0] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SATA_HOST_RX_p[1] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SATA_HOST_TX_p[0] +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to SATA_HOST_TX_p[1] + +#============================================================ +# SATA +#============================================================ +set_instance_assignment -name IO_STANDARD "2.5 V" -to PLL_SCL +set_location_assignment PIN_AF32 -to PLL_SCL +set_instance_assignment -name IO_STANDARD "2.5 V" -to PLL_SDA +set_location_assignment PIN_AG32 -to PLL_SDA + +#============================================================ +# End of pin assignments by Terasic System Builder +#============================================================ + + +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_location_assignment PIN_AK15 -to BUTTON[0] +set_location_assignment PIN_AK14 -to BUTTON[1] +set_location_assignment PIN_AL14 -to BUTTON[2] +set_location_assignment PIN_AL15 -to BUTTON[3] +set_location_assignment PIN_AE15 -to CLOCK_SCL +set_location_assignment PIN_AE16 -to CLOCK_SDA +set_location_assignment PIN_BC37 -to CPU_RESET_n +set_location_assignment PIN_M39 -to DDR3A_A[0] +set_location_assignment PIN_L35 -to DDR3A_A[1] +set_location_assignment PIN_N38 -to DDR3A_A[2] +set_location_assignment PIN_L36 -to DDR3A_A[3] +set_location_assignment PIN_H36 -to DDR3A_A[4] +set_location_assignment PIN_K29 -to DDR3A_A[5] +set_location_assignment PIN_D37 -to DDR3A_A[6] +set_location_assignment PIN_K35 -to DDR3A_A[7] +set_location_assignment PIN_K32 -to DDR3A_A[8] +set_location_assignment PIN_K37 -to DDR3A_A[9] +set_location_assignment PIN_M38 -to DDR3A_A[10] +set_location_assignment PIN_C37 -to DDR3A_A[11] +set_location_assignment PIN_K36 -to DDR3A_A[12] +set_location_assignment PIN_M33 -to DDR3A_A[13] +set_location_assignment PIN_K34 -to DDR3A_A[14] +set_location_assignment PIN_B38 -to DDR3A_A[15] +set_location_assignment PIN_M37 -to DDR3A_BA[0] +set_location_assignment PIN_P39 -to DDR3A_BA[1] +set_location_assignment PIN_J36 -to DDR3A_BA[2] +set_location_assignment PIN_M36 -to DDR3A_CAS_n +set_location_assignment PIN_G37 -to DDR3A_CK[0] +set_location_assignment PIN_J37 -to DDR3A_CK[1] +set_location_assignment PIN_E36 -to DDR3A_CKE[0] +set_location_assignment PIN_B35 -to DDR3A_CKE[1] +set_location_assignment PIN_F36 -to DDR3A_CK_n[0] +set_location_assignment PIN_H37 -to DDR3A_CK_n[1] +set_location_assignment PIN_P36 -to DDR3A_CS_n[0] +set_location_assignment PIN_R28 -to DDR3A_CS_n[1] +set_location_assignment PIN_C36 -to DDR3A_DM[0] +set_location_assignment PIN_E32 -to DDR3A_DM[1] +set_location_assignment PIN_H34 -to DDR3A_DM[2] +set_location_assignment PIN_L32 -to DDR3A_DM[3] +set_location_assignment PIN_N32 -to DDR3A_DM[4] +set_location_assignment PIN_W32 -to DDR3A_DM[5] +set_location_assignment PIN_K30 -to DDR3A_DM[6] +set_location_assignment PIN_T28 -to DDR3A_DM[7] +set_location_assignment PIN_A35 -to DDR3A_DQ[0] +set_location_assignment PIN_A34 -to DDR3A_DQ[1] +set_location_assignment PIN_D36 -to DDR3A_DQ[2] +set_location_assignment PIN_C33 -to DDR3A_DQ[3] +set_location_assignment PIN_B32 -to DDR3A_DQ[4] +set_location_assignment PIN_D35 -to DDR3A_DQ[5] +set_location_assignment PIN_D33 -to DDR3A_DQ[6] +set_location_assignment PIN_E33 -to DDR3A_DQ[7] +set_location_assignment PIN_A32 -to DDR3A_DQ[8] +set_location_assignment PIN_A31 -to DDR3A_DQ[9] +set_location_assignment PIN_C30 -to DDR3A_DQ[10] +set_location_assignment PIN_D30 -to DDR3A_DQ[11] +set_location_assignment PIN_B29 -to DDR3A_DQ[12] +set_location_assignment PIN_E30 -to DDR3A_DQ[13] +set_location_assignment PIN_F31 -to DDR3A_DQ[14] +set_location_assignment PIN_G31 -to DDR3A_DQ[15] +set_location_assignment PIN_F35 -to DDR3A_DQ[16] +set_location_assignment PIN_G34 -to DDR3A_DQ[17] +set_location_assignment PIN_J33 -to DDR3A_DQ[18] +set_location_assignment PIN_J34 -to DDR3A_DQ[19] +set_location_assignment PIN_F34 -to DDR3A_DQ[20] +set_location_assignment PIN_E35 -to DDR3A_DQ[21] +set_location_assignment PIN_J31 -to DDR3A_DQ[22] +set_location_assignment PIN_K31 -to DDR3A_DQ[23] +set_location_assignment PIN_P34 -to DDR3A_DQ[24] +set_location_assignment PIN_R33 -to DDR3A_DQ[25] +set_location_assignment PIN_M34 -to DDR3A_DQ[26] +set_location_assignment PIN_L33 -to DDR3A_DQ[27] +set_location_assignment PIN_R34 -to DDR3A_DQ[28] +set_location_assignment PIN_T34 -to DDR3A_DQ[29] +set_location_assignment PIN_W34 -to DDR3A_DQ[30] +set_location_assignment PIN_V35 -to DDR3A_DQ[31] +set_location_assignment PIN_P33 -to DDR3A_DQ[32] +set_location_assignment PIN_P32 -to DDR3A_DQ[33] +set_location_assignment PIN_V33 -to DDR3A_DQ[34] +set_location_assignment PIN_V34 -to DDR3A_DQ[35] +set_location_assignment PIN_N31 -to DDR3A_DQ[36] +set_location_assignment PIN_M31 -to DDR3A_DQ[37] +set_location_assignment PIN_U32 -to DDR3A_DQ[38] +set_location_assignment PIN_U33 -to DDR3A_DQ[39] +set_location_assignment PIN_R31 -to DDR3A_DQ[40] +set_location_assignment PIN_W31 -to DDR3A_DQ[41] +set_location_assignment PIN_U30 -to DDR3A_DQ[42] +set_location_assignment PIN_P31 -to DDR3A_DQ[43] +set_location_assignment PIN_T31 -to DDR3A_DQ[44] +set_location_assignment PIN_Y32 -to DDR3A_DQ[45] +set_location_assignment PIN_T29 -to DDR3A_DQ[46] +set_location_assignment PIN_P30 -to DDR3A_DQ[47] +set_location_assignment PIN_H32 -to DDR3A_DQ[48] +set_location_assignment PIN_H31 -to DDR3A_DQ[49] +set_location_assignment PIN_L30 -to DDR3A_DQ[50] +set_location_assignment PIN_L29 -to DDR3A_DQ[51] +set_location_assignment PIN_F32 -to DDR3A_DQ[52] +set_location_assignment PIN_G32 -to DDR3A_DQ[53] +set_location_assignment PIN_M30 -to DDR3A_DQ[54] +set_location_assignment PIN_N29 -to DDR3A_DQ[55] +set_location_assignment PIN_U29 -to DDR3A_DQ[56] +set_location_assignment PIN_V28 -to DDR3A_DQ[57] +set_location_assignment PIN_Y28 -to DDR3A_DQ[58] +set_location_assignment PIN_W29 -to DDR3A_DQ[59] +set_location_assignment PIN_V30 -to DDR3A_DQ[60] +set_location_assignment PIN_V29 -to DDR3A_DQ[61] +set_location_assignment PIN_W28 -to DDR3A_DQ[62] +set_location_assignment PIN_Y27 -to DDR3A_DQ[63] +set_location_assignment PIN_C34 -to DDR3A_DQS[0] +set_location_assignment PIN_C31 -to DDR3A_DQS[1] +set_location_assignment PIN_H35 -to DDR3A_DQS[2] +set_location_assignment PIN_U35 -to DDR3A_DQS[3] +set_location_assignment PIN_T33 -to DDR3A_DQS[4] +set_location_assignment PIN_T30 -to DDR3A_DQS[5] +set_location_assignment PIN_J30 -to DDR3A_DQS[6] +set_location_assignment PIN_Y30 -to DDR3A_DQS[7] +set_location_assignment PIN_B34 -to DDR3A_DQS_n[0] +set_location_assignment PIN_B31 -to DDR3A_DQS_n[1] +set_location_assignment PIN_G35 -to DDR3A_DQS_n[2] +set_location_assignment PIN_T35 -to DDR3A_DQS_n[3] +set_location_assignment PIN_T32 -to DDR3A_DQS_n[4] +set_location_assignment PIN_R30 -to DDR3A_DQS_n[5] +set_location_assignment PIN_H30 -to DDR3A_DQS_n[6] +set_location_assignment PIN_Y29 -to DDR3A_DQS_n[7] +set_location_assignment PIN_K19 -to DDR3A_EVENT_n +set_location_assignment PIN_V36 -to DDR3A_ODT[0] +set_location_assignment PIN_W35 -to DDR3A_ODT[1] +set_location_assignment PIN_P38 -to DDR3A_RAS_n +set_location_assignment PIN_H33 -to DDR3A_RESET_n +set_location_assignment PIN_C15 -to DDR3A_SCL +set_location_assignment PIN_P15 -to DDR3A_SDA +set_location_assignment PIN_N37 -to DDR3A_WE_n +set_location_assignment PIN_G17 -to DDR3B_A[0] +set_location_assignment PIN_F17 -to DDR3B_A[1] +set_location_assignment PIN_N17 -to DDR3B_A[2] +set_location_assignment PIN_F19 -to DDR3B_A[3] +set_location_assignment PIN_N19 -to DDR3B_A[4] +set_location_assignment PIN_H16 -to DDR3B_A[5] +set_location_assignment PIN_M17 -to DDR3B_A[6] +set_location_assignment PIN_T18 -to DDR3B_A[7] +set_location_assignment PIN_H17 -to DDR3B_A[8] +set_location_assignment PIN_J19 -to DDR3B_A[9] +set_location_assignment PIN_C19 -to DDR3B_A[10] +set_location_assignment PIN_R18 -to DDR3B_A[11] +set_location_assignment PIN_K18 -to DDR3B_A[12] +set_location_assignment PIN_E18 -to DDR3B_A[13] +set_location_assignment PIN_T19 -to DDR3B_A[14] +set_location_assignment PIN_R19 -to DDR3B_A[15] +set_location_assignment PIN_C18 -to DDR3B_BA[0] +set_location_assignment PIN_G19 -to DDR3B_BA[1] +set_location_assignment PIN_M20 -to DDR3B_BA[2] +set_location_assignment PIN_A17 -to DDR3B_CAS_n +set_location_assignment PIN_B16 -to DDR3B_CK[0] +set_location_assignment PIN_E17 -to DDR3B_CK[1] +set_location_assignment PIN_P17 -to DDR3B_CKE[0] +set_location_assignment PIN_V18 -to DDR3B_CKE[1] +set_location_assignment PIN_A16 -to DDR3B_CK_n[0] +set_location_assignment PIN_D17 -to DDR3B_CK_n[1] +set_location_assignment PIN_B19 -to DDR3B_CS_n[0] +set_location_assignment PIN_B17 -to DDR3B_CS_n[1] +set_location_assignment PIN_R15 -to DDR3B_DM[0] +set_location_assignment PIN_K15 -to DDR3B_DM[1] +set_location_assignment PIN_V12 -to DDR3B_DM[2] +set_location_assignment PIN_G10 -to DDR3B_DM[3] +set_location_assignment PIN_T12 -to DDR3B_DM[4] +set_location_assignment PIN_C16 -to DDR3B_DM[5] +set_location_assignment PIN_H15 -to DDR3B_DM[6] +set_location_assignment PIN_B11 -to DDR3B_DM[7] +set_location_assignment PIN_Y17 -to DDR3B_DQ[0] +set_location_assignment PIN_W17 -to DDR3B_DQ[1] +set_location_assignment PIN_V15 -to DDR3B_DQ[2] +set_location_assignment PIN_T15 -to DDR3B_DQ[3] +set_location_assignment PIN_V13 -to DDR3B_DQ[4] +set_location_assignment PIN_V16 -to DDR3B_DQ[5] +set_location_assignment PIN_W14 -to DDR3B_DQ[6] +set_location_assignment PIN_U15 -to DDR3B_DQ[7] +set_location_assignment PIN_T17 -to DDR3B_DQ[8] +set_location_assignment PIN_T16 -to DDR3B_DQ[9] +set_location_assignment PIN_R16 -to DDR3B_DQ[10] +set_location_assignment PIN_P16 -to DDR3B_DQ[11] +set_location_assignment PIN_N16 -to DDR3B_DQ[12] +set_location_assignment PIN_M15 -to DDR3B_DQ[13] +set_location_assignment PIN_M14 -to DDR3B_DQ[14] +set_location_assignment PIN_L14 -to DDR3B_DQ[15] +set_location_assignment PIN_T14 -to DDR3B_DQ[16] +set_location_assignment PIN_U14 -to DDR3B_DQ[17] +set_location_assignment PIN_U11 -to DDR3B_DQ[18] +set_location_assignment PIN_T13 -to DDR3B_DQ[19] +set_location_assignment PIN_U12 -to DDR3B_DQ[20] +set_location_assignment PIN_R13 -to DDR3B_DQ[21] +set_location_assignment PIN_P13 -to DDR3B_DQ[22] +set_location_assignment PIN_N13 -to DDR3B_DQ[23] +set_location_assignment PIN_K12 -to DDR3B_DQ[24] +set_location_assignment PIN_J12 -to DDR3B_DQ[25] +set_location_assignment PIN_J10 -to DDR3B_DQ[26] +set_location_assignment PIN_H12 -to DDR3B_DQ[27] +set_location_assignment PIN_N11 -to DDR3B_DQ[28] +set_location_assignment PIN_M11 -to DDR3B_DQ[29] +set_location_assignment PIN_H10 -to DDR3B_DQ[30] +set_location_assignment PIN_H11 -to DDR3B_DQ[31] +set_location_assignment PIN_T10 -to DDR3B_DQ[32] +set_location_assignment PIN_R10 -to DDR3B_DQ[33] +set_location_assignment PIN_M12 -to DDR3B_DQ[34] +set_location_assignment PIN_L12 -to DDR3B_DQ[35] +set_location_assignment PIN_V10 -to DDR3B_DQ[36] +set_location_assignment PIN_V9 -to DDR3B_DQ[37] +set_location_assignment PIN_R12 -to DDR3B_DQ[38] +set_location_assignment PIN_P12 -to DDR3B_DQ[39] +set_location_assignment PIN_D14 -to DDR3B_DQ[40] +set_location_assignment PIN_C13 -to DDR3B_DQ[41] +set_location_assignment PIN_B14 -to DDR3B_DQ[42] +set_location_assignment PIN_B13 -to DDR3B_DQ[43] +set_location_assignment PIN_E14 -to DDR3B_DQ[44] +set_location_assignment PIN_F14 -to DDR3B_DQ[45] +set_location_assignment PIN_A14 -to DDR3B_DQ[46] +set_location_assignment PIN_A13 -to DDR3B_DQ[47] +set_location_assignment PIN_K13 -to DDR3B_DQ[48] +set_location_assignment PIN_K16 -to DDR3B_DQ[49] +set_location_assignment PIN_H13 -to DDR3B_DQ[50] +set_location_assignment PIN_H14 -to DDR3B_DQ[51] +set_location_assignment PIN_J13 -to DDR3B_DQ[52] +set_location_assignment PIN_J16 -to DDR3B_DQ[53] +set_location_assignment PIN_G13 -to DDR3B_DQ[54] +set_location_assignment PIN_F13 -to DDR3B_DQ[55] +set_location_assignment PIN_D11 -to DDR3B_DQ[56] +set_location_assignment PIN_C10 -to DDR3B_DQ[57] +set_location_assignment PIN_A10 -to DDR3B_DQ[58] +set_location_assignment PIN_B10 -to DDR3B_DQ[59] +set_location_assignment PIN_G11 -to DDR3B_DQ[60] +set_location_assignment PIN_F11 -to DDR3B_DQ[61] +set_location_assignment PIN_E11 -to DDR3B_DQ[62] +set_location_assignment PIN_E12 -to DDR3B_DQ[63] +set_location_assignment PIN_Y16 -to DDR3B_DQS[0] +set_location_assignment PIN_V17 -to DDR3B_DQS[1] +set_location_assignment PIN_P14 -to DDR3B_DQS[2] +set_location_assignment PIN_K11 -to DDR3B_DQS[3] +set_location_assignment PIN_U9 -to DDR3B_DQS[4] +set_location_assignment PIN_E15 -to DDR3B_DQS[5] +set_location_assignment PIN_L15 -to DDR3B_DQS[6] +set_location_assignment PIN_D12 -to DDR3B_DQS[7] +set_location_assignment PIN_W16 -to DDR3B_DQS_n[0] +set_location_assignment PIN_U17 -to DDR3B_DQS_n[1] +set_location_assignment PIN_N14 -to DDR3B_DQS_n[2] +set_location_assignment PIN_L11 -to DDR3B_DQS_n[3] +set_location_assignment PIN_T9 -to DDR3B_DQS_n[4] +set_location_assignment PIN_D15 -to DDR3B_DQS_n[5] +set_location_assignment PIN_K14 -to DDR3B_DQS_n[6] +set_location_assignment PIN_C12 -to DDR3B_DQS_n[7] +set_location_assignment PIN_K17 -to DDR3B_EVENT_n +set_location_assignment PIN_M18 -to DDR3B_ODT[0] +set_location_assignment PIN_A19 -to DDR3B_ODT[1] +set_location_assignment PIN_H19 -to DDR3B_RAS_n +set_location_assignment PIN_T20 -to DDR3B_RESET_n +set_location_assignment PIN_P18 -to DDR3B_SCL +set_location_assignment PIN_P19 -to DDR3B_SDA +set_location_assignment PIN_D18 -to DDR3B_WE_n +set_location_assignment PIN_AR32 -to FAN_CTRL +set_location_assignment PIN_AK29 -to FLASH_ADV_n +set_location_assignment PIN_AE27 -to FLASH_CE_n[0] +set_location_assignment PIN_BA31 -to FLASH_CE_n[1] +set_location_assignment PIN_AL29 -to FLASH_CLK +set_location_assignment PIN_AY30 -to FLASH_OE_n +set_location_assignment PIN_BA29 -to FLASH_RDY_BSY_n[0] +set_location_assignment PIN_BB32 -to FLASH_RDY_BSY_n[1] +set_location_assignment PIN_AE28 -to FLASH_RESET_n +set_location_assignment PIN_AR31 -to FLASH_WE_n +set_location_assignment PIN_AU32 -to FSM_A[0] +set_location_assignment PIN_AH30 -to FSM_A[1] +set_location_assignment PIN_AJ30 -to FSM_A[2] +set_location_assignment PIN_AH31 -to FSM_A[3] +set_location_assignment PIN_AK30 -to FSM_A[4] +set_location_assignment PIN_AJ32 -to FSM_A[5] +set_location_assignment PIN_AG33 -to FSM_A[6] +set_location_assignment PIN_AL30 -to FSM_A[7] +set_location_assignment PIN_AK33 -to FSM_A[8] +set_location_assignment PIN_AJ33 -to FSM_A[9] +set_location_assignment PIN_AN30 -to FSM_A[10] +set_location_assignment PIN_AH33 -to FSM_A[11] +set_location_assignment PIN_AK32 -to FSM_A[12] +set_location_assignment PIN_AM32 -to FSM_A[13] +set_location_assignment PIN_AM31 -to FSM_A[14] +set_location_assignment PIN_AL31 -to FSM_A[15] +set_location_assignment PIN_AN33 -to FSM_A[16] +set_location_assignment PIN_AP33 -to FSM_A[17] +set_location_assignment PIN_AT32 -to FSM_A[18] +set_location_assignment PIN_AT29 -to FSM_A[19] +set_location_assignment PIN_AP31 -to FSM_A[20] +set_location_assignment PIN_AR30 -to FSM_A[21] +set_location_assignment PIN_AU30 -to FSM_A[22] +set_location_assignment PIN_AJ31 -to FSM_A[23] +set_location_assignment PIN_AP30 -to FSM_A[24] +set_location_assignment PIN_AN31 -to FSM_A[25] +set_location_assignment PIN_AT30 -to FSM_A[26] +set_location_assignment PIN_AG26 -to FSM_D[0] +set_location_assignment PIN_AD33 -to FSM_D[1] +set_location_assignment PIN_AE34 -to FSM_D[2] +set_location_assignment PIN_AF31 -to FSM_D[3] +set_location_assignment PIN_AG28 -to FSM_D[4] +set_location_assignment PIN_AG30 -to FSM_D[5] +set_location_assignment PIN_AF29 -to FSM_D[6] +set_location_assignment PIN_AE29 -to FSM_D[7] +set_location_assignment PIN_AG25 -to FSM_D[8] +set_location_assignment PIN_AF34 -to FSM_D[9] +set_location_assignment PIN_AE33 -to FSM_D[10] +set_location_assignment PIN_AE31 -to FSM_D[11] +set_location_assignment PIN_AF28 -to FSM_D[12] +set_location_assignment PIN_AE30 -to FSM_D[13] +set_location_assignment PIN_AG29 -to FSM_D[14] +set_location_assignment PIN_AG27 -to FSM_D[15] +set_location_assignment PIN_AP28 -to FSM_D[16] +set_location_assignment PIN_AN28 -to FSM_D[17] +set_location_assignment PIN_AU31 -to FSM_D[18] +set_location_assignment PIN_AW32 -to FSM_D[19] +set_location_assignment PIN_BD32 -to FSM_D[20] +set_location_assignment PIN_AY31 -to FSM_D[21] +set_location_assignment PIN_BA30 -to FSM_D[22] +set_location_assignment PIN_BB30 -to FSM_D[23] +set_location_assignment PIN_AM29 -to FSM_D[24] +set_location_assignment PIN_AR29 -to FSM_D[25] +set_location_assignment PIN_AV31 -to FSM_D[26] +set_location_assignment PIN_AV32 -to FSM_D[27] +set_location_assignment PIN_BC31 -to FSM_D[28] +set_location_assignment PIN_AW30 -to FSM_D[29] +set_location_assignment PIN_BC32 -to FSM_D[30] +set_location_assignment PIN_BD31 -to FSM_D[31] +set_location_assignment PIN_G8 -to HEX0_D[0] +set_location_assignment PIN_H8 -to HEX0_D[1] +set_location_assignment PIN_J9 -to HEX0_D[2] +set_location_assignment PIN_K10 -to HEX0_D[3] +set_location_assignment PIN_K8 -to HEX0_D[4] +set_location_assignment PIN_K9 -to HEX0_D[5] +set_location_assignment PIN_N8 -to HEX0_D[6] +set_location_assignment PIN_P8 -to HEX0_DP +set_location_assignment PIN_H18 -to HEX1_D[0] +set_location_assignment PIN_G16 -to HEX1_D[1] +set_location_assignment PIN_F16 -to HEX1_D[2] +set_location_assignment PIN_A7 -to HEX1_D[3] +set_location_assignment PIN_B7 -to HEX1_D[4] +set_location_assignment PIN_C9 -to HEX1_D[5] +set_location_assignment PIN_D10 -to HEX1_D[6] +set_location_assignment PIN_E9 -to HEX1_DP +set_location_assignment PIN_AW37 -to LED[0] +set_location_assignment PIN_AV37 -to LED[1] +set_location_assignment PIN_BB36 -to LED[2] +set_location_assignment PIN_BB39 -to LED[3] +set_location_assignment PIN_AH15 -to LED_BRACKET[0] +set_location_assignment PIN_AH13 -to LED_BRACKET[1] +set_location_assignment PIN_AJ13 -to LED_BRACKET[2] +set_location_assignment PIN_AJ14 -to LED_BRACKET[3] +set_location_assignment PIN_AG15 -to LED_RJ45_L +set_location_assignment PIN_AG16 -to LED_RJ45_R +set_location_assignment PIN_AW35 -to OSC_50_B3B +set_location_assignment PIN_BC28 -to OSC_50_B3D +set_location_assignment PIN_AP10 -to OSC_50_B4A +set_location_assignment PIN_AY18 -to OSC_50_B4D +set_location_assignment PIN_M8 -to OSC_50_B7A +set_location_assignment PIN_J18 -to OSC_50_B7D +set_location_assignment PIN_R36 -to OSC_50_B8A +set_location_assignment PIN_R25 -to OSC_50_B8D +set_location_assignment PIN_AU33 -to PCIE_PERST_n +set_location_assignment PIN_AK38 -to PCIE_REFCLK_p +set_location_assignment PIN_BB43 -to PCIE_RX_p[0] +set_location_assignment PIN_BA41 -to PCIE_RX_p[1] +set_location_assignment PIN_AW41 -to PCIE_RX_p[2] +set_location_assignment PIN_AY43 -to PCIE_RX_p[3] +set_location_assignment PIN_AT43 -to PCIE_RX_p[4] +set_location_assignment PIN_AP43 -to PCIE_RX_p[5] +set_location_assignment PIN_AM43 -to PCIE_RX_p[6] +set_location_assignment PIN_AK43 -to PCIE_RX_p[7] +set_location_assignment PIN_BD34 -to PCIE_SMBCLK +set_location_assignment PIN_AT33 -to PCIE_SMBDAT +set_location_assignment PIN_AY39 -to PCIE_TX_p[0] +set_location_assignment PIN_AV39 -to PCIE_TX_p[1] +set_location_assignment PIN_AT39 -to PCIE_TX_p[2] +set_location_assignment PIN_AU41 -to PCIE_TX_p[3] +set_location_assignment PIN_AN41 -to PCIE_TX_p[4] +set_location_assignment PIN_AL41 -to PCIE_TX_p[5] +set_location_assignment PIN_AJ41 -to PCIE_TX_p[6] +set_location_assignment PIN_AG41 -to PCIE_TX_p[7] +set_location_assignment PIN_BD35 -to PCIE_WAKE_n +set_location_assignment PIN_AU29 -to QDRIIA_A[0] +set_location_assignment PIN_BA28 -to QDRIIA_A[1] +set_location_assignment PIN_AP27 -to QDRIIA_A[2] +set_location_assignment PIN_AK27 -to QDRIIA_A[3] +set_location_assignment PIN_AN27 -to QDRIIA_A[4] +set_location_assignment PIN_AM28 -to QDRIIA_A[5] +set_location_assignment PIN_AV28 -to QDRIIA_A[6] +set_location_assignment PIN_AY27 -to QDRIIA_A[7] +set_location_assignment PIN_BC29 -to QDRIIA_A[8] +set_location_assignment PIN_AU28 -to QDRIIA_A[9] +set_location_assignment PIN_AW27 -to QDRIIA_A[10] +set_location_assignment PIN_AY28 -to QDRIIA_A[11] +set_location_assignment PIN_BD28 -to QDRIIA_A[12] +set_location_assignment PIN_AV29 -to QDRIIA_A[13] +set_location_assignment PIN_AW29 -to QDRIIA_A[14] +set_location_assignment PIN_BB29 -to QDRIIA_A[15] +set_location_assignment PIN_BD29 -to QDRIIA_A[16] +set_location_assignment PIN_AL27 -to QDRIIA_A[17] +set_location_assignment PIN_AR27 -to QDRIIA_A[18] +set_location_assignment PIN_AL28 -to QDRIIA_A[19] +set_location_assignment PIN_AR28 -to QDRIIA_A[20] +set_location_assignment PIN_AJ24 -to QDRIIA_BWS_n[0] +set_location_assignment PIN_AT27 -to QDRIIA_BWS_n[1] +set_location_assignment PIN_BA25 -to QDRIIA_CQ_n +set_location_assignment PIN_AH22 -to QDRIIA_CQ_p +set_location_assignment PIN_AH28 -to QDRIIA_D[0] +set_location_assignment PIN_AH27 -to QDRIIA_D[1] +set_location_assignment PIN_AH25 -to QDRIIA_D[2] +set_location_assignment PIN_AJ28 -to QDRIIA_D[3] +set_location_assignment PIN_AJ27 -to QDRIIA_D[4] +set_location_assignment PIN_AJ26 -to QDRIIA_D[5] +set_location_assignment PIN_AJ25 -to QDRIIA_D[6] +set_location_assignment PIN_AL25 -to QDRIIA_D[7] +set_location_assignment PIN_AH24 -to QDRIIA_D[8] +set_location_assignment PIN_AN25 -to QDRIIA_D[9] +set_location_assignment PIN_AM26 -to QDRIIA_D[10] +set_location_assignment PIN_AM25 -to QDRIIA_D[11] +set_location_assignment PIN_AL26 -to QDRIIA_D[12] +set_location_assignment PIN_AK26 -to QDRIIA_D[13] +set_location_assignment PIN_AU27 -to QDRIIA_D[14] +set_location_assignment PIN_AU26 -to QDRIIA_D[15] +set_location_assignment PIN_AV26 -to QDRIIA_D[16] +set_location_assignment PIN_AW26 -to QDRIIA_D[17] +set_location_assignment PIN_AR23 -to QDRIIA_DOFF_n +set_location_assignment PIN_AR26 -to QDRIIA_K_n +set_location_assignment PIN_AP25 -to QDRIIA_K_p +set_location_assignment PIN_AN23 -to QDRIIA_ODT +set_location_assignment PIN_AK23 -to QDRIIA_Q[0] +set_location_assignment PIN_BB26 -to QDRIIA_Q[1] +set_location_assignment PIN_BD26 -to QDRIIA_Q[2] +set_location_assignment PIN_BA24 -to QDRIIA_Q[3] +set_location_assignment PIN_AL23 -to QDRIIA_Q[4] +set_location_assignment PIN_AJ23 -to QDRIIA_Q[5] +set_location_assignment PIN_AL21 -to QDRIIA_Q[6] +set_location_assignment PIN_AK21 -to QDRIIA_Q[7] +set_location_assignment PIN_AJ22 -to QDRIIA_Q[8] +set_location_assignment PIN_AW24 -to QDRIIA_Q[9] +set_location_assignment PIN_BC26 -to QDRIIA_Q[10] +set_location_assignment PIN_AY25 -to QDRIIA_Q[11] +set_location_assignment PIN_AU24 -to QDRIIA_Q[12] +set_location_assignment PIN_AV25 -to QDRIIA_Q[13] +set_location_assignment PIN_AU25 -to QDRIIA_Q[14] +set_location_assignment PIN_AR25 -to QDRIIA_Q[15] +set_location_assignment PIN_AP24 -to QDRIIA_Q[16] +set_location_assignment PIN_AL24 -to QDRIIA_Q[17] +set_location_assignment PIN_AM23 -to QDRIIA_QVLD +set_location_assignment PIN_AT26 -to QDRIIA_RPS_n +set_location_assignment PIN_AK24 -to QDRIIA_WPS_n +set_location_assignment PIN_AR24 -to QDRIIB_A[0] +set_location_assignment PIN_BB23 -to QDRIIB_A[1] +set_location_assignment PIN_AK20 -to QDRIIB_A[2] +set_location_assignment PIN_AJ19 -to QDRIIB_A[3] +set_location_assignment PIN_AL20 -to QDRIIB_A[4] +set_location_assignment PIN_AG19 -to QDRIIB_A[5] +set_location_assignment PIN_AT23 -to QDRIIB_A[6] +set_location_assignment PIN_AU23 -to QDRIIB_A[7] +set_location_assignment PIN_AV23 -to QDRIIB_A[8] +set_location_assignment PIN_AM22 -to QDRIIB_A[9] +set_location_assignment PIN_AJ20 -to QDRIIB_A[10] +set_location_assignment PIN_AG20 -to QDRIIB_A[11] +set_location_assignment PIN_AW23 -to QDRIIB_A[12] +set_location_assignment PIN_BB24 -to QDRIIB_A[13] +set_location_assignment PIN_AY24 -to QDRIIB_A[14] +set_location_assignment PIN_BD23 -to QDRIIB_A[15] +set_location_assignment PIN_BC23 -to QDRIIB_A[16] +set_location_assignment PIN_AG21 -to QDRIIB_A[17] +set_location_assignment PIN_AM20 -to QDRIIB_A[18] +set_location_assignment PIN_AK18 -to QDRIIB_A[19] +set_location_assignment PIN_AN22 -to QDRIIB_A[20] +set_location_assignment PIN_AV20 -to QDRIIB_BWS_n[0] +set_location_assignment PIN_AU21 -to QDRIIB_BWS_n[1] +set_location_assignment PIN_AP18 -to QDRIIB_CQ_n +set_location_assignment PIN_AJ15 -to QDRIIB_CQ_p +set_location_assignment PIN_BB21 -to QDRIIB_D[0] +set_location_assignment PIN_BD20 -to QDRIIB_D[1] +set_location_assignment PIN_BC20 -to QDRIIB_D[2] +set_location_assignment PIN_AR22 -to QDRIIB_D[3] +set_location_assignment PIN_BB20 -to QDRIIB_D[4] +set_location_assignment PIN_AU22 -to QDRIIB_D[5] +set_location_assignment PIN_BA21 -to QDRIIB_D[6] +set_location_assignment PIN_AY21 -to QDRIIB_D[7] +set_location_assignment PIN_AW21 -to QDRIIB_D[8] +set_location_assignment PIN_AT21 -to QDRIIB_D[9] +set_location_assignment PIN_AR21 -to QDRIIB_D[10] +set_location_assignment PIN_AP21 -to QDRIIB_D[11] +set_location_assignment PIN_BD22 -to QDRIIB_D[12] +set_location_assignment PIN_BC22 -to QDRIIB_D[13] +set_location_assignment PIN_BA22 -to QDRIIB_D[14] +set_location_assignment PIN_AV22 -to QDRIIB_D[15] +set_location_assignment PIN_AY22 -to QDRIIB_D[16] +set_location_assignment PIN_AW22 -to QDRIIB_D[17] +set_location_assignment PIN_AH19 -to QDRIIB_DOFF_n +set_location_assignment PIN_AT20 -to QDRIIB_K_n +set_location_assignment PIN_AR20 -to QDRIIB_K_p +set_location_assignment PIN_AH18 -to QDRIIB_ODT +set_location_assignment PIN_AR19 -to QDRIIB_Q[0] +set_location_assignment PIN_AM19 -to QDRIIB_Q[1] +set_location_assignment PIN_AL19 -to QDRIIB_Q[2] +set_location_assignment PIN_AM17 -to QDRIIB_Q[3] +set_location_assignment PIN_AL18 -to QDRIIB_Q[4] +set_location_assignment PIN_AN19 -to QDRIIB_Q[5] +set_location_assignment PIN_AU18 -to QDRIIB_Q[6] +set_location_assignment PIN_AK17 -to QDRIIB_Q[7] +set_location_assignment PIN_AL17 -to QDRIIB_Q[8] +set_location_assignment PIN_AG17 -to QDRIIB_Q[9] +set_location_assignment PIN_AJ18 -to QDRIIB_Q[10] +set_location_assignment PIN_AJ17 -to QDRIIB_Q[11] +set_location_assignment PIN_AG18 -to QDRIIB_Q[12] +set_location_assignment PIN_AU19 -to QDRIIB_Q[13] +set_location_assignment PIN_AW19 -to QDRIIB_Q[14] +set_location_assignment PIN_AV19 -to QDRIIB_Q[15] +set_location_assignment PIN_AP19 -to QDRIIB_Q[16] +set_location_assignment PIN_AN20 -to QDRIIB_Q[17] +set_location_assignment PIN_AJ16 -to QDRIIB_QVLD +set_location_assignment PIN_AW20 -to QDRIIB_RPS_n +set_location_assignment PIN_AU20 -to QDRIIB_WPS_n +set_location_assignment PIN_AV16 -to QDRIIC_A[0] +set_location_assignment PIN_AW16 -to QDRIIC_A[1] +set_location_assignment PIN_AP16 -to QDRIIC_A[2] +set_location_assignment PIN_AW9 -to QDRIIC_A[3] +set_location_assignment PIN_BD7 -to QDRIIC_A[4] +set_location_assignment PIN_BC7 -to QDRIIC_A[5] +set_location_assignment PIN_AR17 -to QDRIIC_A[6] +set_location_assignment PIN_AR18 -to QDRIIC_A[7] +set_location_assignment PIN_AT17 -to QDRIIC_A[8] +set_location_assignment PIN_BB9 -to QDRIIC_A[9] +set_location_assignment PIN_AH21 -to QDRIIC_A[10] +set_location_assignment PIN_AU17 -to QDRIIC_A[11] +set_location_assignment PIN_AU16 -to QDRIIC_A[12] +set_location_assignment PIN_BB8 -to QDRIIC_A[13] +set_location_assignment PIN_AT18 -to QDRIIC_A[14] +set_location_assignment PIN_AW17 -to QDRIIC_A[15] +set_location_assignment PIN_AV17 -to QDRIIC_A[16] +set_location_assignment PIN_AU8 -to QDRIIC_A[17] +set_location_assignment PIN_AT9 -to QDRIIC_A[18] +set_location_assignment PIN_AV8 -to QDRIIC_A[19] +set_location_assignment PIN_AN17 -to QDRIIC_A[20] +set_location_assignment PIN_AJ11 -to QDRIIC_BWS_n[0] +set_location_assignment PIN_AJ10 -to QDRIIC_BWS_n[1] +set_location_assignment PIN_AF13 -to QDRIIC_CQ_n +set_location_assignment PIN_BC11 -to QDRIIC_CQ_p +set_location_assignment PIN_AG9 -to QDRIIC_D[0] +set_location_assignment PIN_AG10 -to QDRIIC_D[1] +set_location_assignment PIN_AG12 -to QDRIIC_D[2] +set_location_assignment PIN_AG11 -to QDRIIC_D[3] +set_location_assignment PIN_AV10 -to QDRIIC_D[4] +set_location_assignment PIN_AH12 -to QDRIIC_D[5] +set_location_assignment PIN_AK12 -to QDRIIC_D[6] +set_location_assignment PIN_AL12 -to QDRIIC_D[7] +set_location_assignment PIN_AJ12 -to QDRIIC_D[8] +set_location_assignment PIN_AN12 -to QDRIIC_D[9] +set_location_assignment PIN_AM13 -to QDRIIC_D[10] +set_location_assignment PIN_AR12 -to QDRIIC_D[11] +set_location_assignment PIN_AR13 -to QDRIIC_D[12] +set_location_assignment PIN_AU9 -to QDRIIC_D[13] +set_location_assignment PIN_AU10 -to QDRIIC_D[14] +set_location_assignment PIN_AU11 -to QDRIIC_D[15] +set_location_assignment PIN_AV11 -to QDRIIC_D[16] +set_location_assignment PIN_AT12 -to QDRIIC_D[17] +set_location_assignment PIN_AE14 -to QDRIIC_DOFF_n +set_location_assignment PIN_AP13 -to QDRIIC_K_n +set_location_assignment PIN_AP12 -to QDRIIC_K_p +set_location_assignment PIN_BD10 -to QDRIIC_ODT +set_location_assignment PIN_BA12 -to QDRIIC_Q[0] +set_location_assignment PIN_AF14 -to QDRIIC_Q[1] +set_location_assignment PIN_AE13 -to QDRIIC_Q[2] +set_location_assignment PIN_AD14 -to QDRIIC_Q[3] +set_location_assignment PIN_AE12 -to QDRIIC_Q[4] +set_location_assignment PIN_AF11 -to QDRIIC_Q[5] +set_location_assignment PIN_AE11 -to QDRIIC_Q[6] +set_location_assignment PIN_AE10 -to QDRIIC_Q[7] +set_location_assignment PIN_AE9 -to QDRIIC_Q[8] +set_location_assignment PIN_BB11 -to QDRIIC_Q[9] +set_location_assignment PIN_AW11 -to QDRIIC_Q[10] +set_location_assignment PIN_AF10 -to QDRIIC_Q[11] +set_location_assignment PIN_AY12 -to QDRIIC_Q[12] +set_location_assignment PIN_AW10 -to QDRIIC_Q[13] +set_location_assignment PIN_AY10 -to QDRIIC_Q[14] +set_location_assignment PIN_BB12 -to QDRIIC_Q[15] +set_location_assignment PIN_BC10 -to QDRIIC_Q[16] +set_location_assignment PIN_BA10 -to QDRIIC_Q[17] +set_location_assignment PIN_BD11 -to QDRIIC_QVLD +set_location_assignment PIN_AH10 -to QDRIIC_RPS_n +set_location_assignment PIN_AL11 -to QDRIIC_WPS_n +set_location_assignment PIN_N26 -to QDRIID_A[0] +set_location_assignment PIN_P28 -to QDRIID_A[1] +set_location_assignment PIN_N28 -to QDRIID_A[2] +set_location_assignment PIN_L26 -to QDRIID_A[3] +set_location_assignment PIN_K27 -to QDRIID_A[4] +set_location_assignment PIN_L27 -to QDRIID_A[5] +set_location_assignment PIN_U26 -to QDRIID_A[6] +set_location_assignment PIN_T26 -to QDRIID_A[7] +set_location_assignment PIN_T27 -to QDRIID_A[8] +set_location_assignment PIN_V27 -to QDRIID_A[9] +set_location_assignment PIN_U27 -to QDRIID_A[10] +set_location_assignment PIN_R27 -to QDRIID_A[11] +set_location_assignment PIN_P27 -to QDRIID_A[12] +set_location_assignment PIN_V25 -to QDRIID_A[13] +set_location_assignment PIN_V26 -to QDRIID_A[14] +set_location_assignment PIN_T25 -to QDRIID_A[15] +set_location_assignment PIN_P26 -to QDRIID_A[16] +set_location_assignment PIN_M27 -to QDRIID_A[17] +set_location_assignment PIN_M28 -to QDRIID_A[18] +set_location_assignment PIN_P29 -to QDRIID_A[19] +set_location_assignment PIN_D29 -to QDRIID_A[20] +set_location_assignment PIN_E26 -to QDRIID_BWS_n[0] +set_location_assignment PIN_K26 -to QDRIID_BWS_n[1] +set_location_assignment PIN_H27 -to QDRIID_CQ_n +set_location_assignment PIN_E29 -to QDRIID_CQ_p +set_location_assignment PIN_H25 -to QDRIID_D[0] +set_location_assignment PIN_H24 -to QDRIID_D[1] +set_location_assignment PIN_H23 -to QDRIID_D[2] +set_location_assignment PIN_J25 -to QDRIID_D[3] +set_location_assignment PIN_J24 -to QDRIID_D[4] +set_location_assignment PIN_K25 -to QDRIID_D[5] +set_location_assignment PIN_D26 -to QDRIID_D[6] +set_location_assignment PIN_F25 -to QDRIID_D[7] +set_location_assignment PIN_G25 -to QDRIID_D[8] +set_location_assignment PIN_N23 -to QDRIID_D[9] +set_location_assignment PIN_P24 -to QDRIID_D[10] +set_location_assignment PIN_P23 -to QDRIID_D[11] +set_location_assignment PIN_L24 -to QDRIID_D[12] +set_location_assignment PIN_R24 -to QDRIID_D[13] +set_location_assignment PIN_U23 -to QDRIID_D[14] +set_location_assignment PIN_U24 -to QDRIID_D[15] +set_location_assignment PIN_T24 -to QDRIID_D[16] +set_location_assignment PIN_T23 -to QDRIID_D[17] +set_location_assignment PIN_E27 -to QDRIID_DOFF_n +set_location_assignment PIN_K24 -to QDRIID_K_n +set_location_assignment PIN_L23 -to QDRIID_K_p +set_location_assignment PIN_H26 -to QDRIID_ODT +set_location_assignment PIN_C27 -to QDRIID_Q[0] +set_location_assignment PIN_A26 -to QDRIID_Q[1] +set_location_assignment PIN_B26 -to QDRIID_Q[2] +set_location_assignment PIN_F26 -to QDRIID_Q[3] +set_location_assignment PIN_G26 -to QDRIID_Q[4] +set_location_assignment PIN_C28 -to QDRIID_Q[5] +set_location_assignment PIN_A29 -to QDRIID_Q[6] +set_location_assignment PIN_A28 -to QDRIID_Q[7] +set_location_assignment PIN_B28 -to QDRIID_Q[8] +set_location_assignment PIN_G28 -to QDRIID_Q[9] +set_location_assignment PIN_F28 -to QDRIID_Q[10] +set_location_assignment PIN_D27 -to QDRIID_Q[11] +set_location_assignment PIN_G29 -to QDRIID_Q[12] +set_location_assignment PIN_F29 -to QDRIID_Q[13] +set_location_assignment PIN_H28 -to QDRIID_Q[14] +set_location_assignment PIN_K28 -to QDRIID_Q[15] +set_location_assignment PIN_J28 -to QDRIID_Q[16] +set_location_assignment PIN_H29 -to QDRIID_Q[17] +set_location_assignment PIN_J27 -to QDRIID_QVLD +set_location_assignment PIN_F24 -to QDRIID_RPS_n +set_location_assignment PIN_M23 -to QDRIID_WPS_n +set_location_assignment PIN_AG14 -to RS422_DE +set_location_assignment PIN_AE18 -to RS422_DIN +set_location_assignment PIN_AE17 -to RS422_DOUT +set_location_assignment PIN_AF17 -to RS422_RE_n +set_location_assignment PIN_AF16 -to RS422_TE +set_location_assignment PIN_BA36 -to RZQ_0 +set_location_assignment PIN_AR8 -to RZQ_1 +set_location_assignment PIN_H9 -to RZQ_4 +set_location_assignment PIN_P35 -to RZQ_5 +set_location_assignment PIN_AH6 -to SFP1G_REFCLK_p +set_location_assignment PIN_F22 -to SFPA_LOS +set_location_assignment PIN_E21 -to SFPA_MOD0_PRSNT_n +set_location_assignment PIN_B20 -to SFPA_MOD1_SCL +set_location_assignment PIN_A20 -to SFPA_MOD2_SDA +set_location_assignment PIN_E20 -to SFPA_RATESEL[0] +set_location_assignment PIN_G22 -to SFPA_RATESEL[1] +set_location_assignment PIN_AK2 -to SFPA_RX_p +set_location_assignment PIN_B22 -to SFPA_TXDISABLE +set_location_assignment PIN_A22 -to SFPA_TXFAULT +set_location_assignment PIN_AG4 -to SFPA_TX_p +set_location_assignment PIN_R22 -to SFPB_LOS +set_location_assignment PIN_K22 -to SFPB_MOD0_PRSNT_n +set_location_assignment PIN_K21 -to SFPB_MOD1_SCL +set_location_assignment PIN_K20 -to SFPB_MOD2_SDA +set_location_assignment PIN_R21 -to SFPB_RATESEL[0] +set_location_assignment PIN_T22 -to SFPB_RATESEL[1] +set_location_assignment PIN_AP2 -to SFPB_RX_p +set_location_assignment PIN_H22 -to SFPB_TXDISABLE +set_location_assignment PIN_H20 -to SFPB_TXFAULT +set_location_assignment PIN_AL4 -to SFPB_TX_p +set_location_assignment PIN_L21 -to SFPC_LOS +set_location_assignment PIN_J21 -to SFPC_MOD0_PRSNT_n +set_location_assignment PIN_H21 -to SFPC_MOD1_SCL +set_location_assignment PIN_G20 -to SFPC_MOD2_SDA +set_location_assignment PIN_J22 -to SFPC_RATESEL[0] +set_location_assignment PIN_P21 -to SFPC_RATESEL[1] +set_location_assignment PIN_AW4 -to SFPC_RX_p +set_location_assignment PIN_F21 -to SFPC_TXDISABLE +set_location_assignment PIN_F20 -to SFPC_TXFAULT +set_location_assignment PIN_AT6 -to SFPC_TX_p +set_location_assignment PIN_N22 -to SFPD_LOS +set_location_assignment PIN_V20 -to SFPD_MOD0_PRSNT_n +set_location_assignment PIN_U21 -to SFPD_MOD1_SCL +set_location_assignment PIN_V19 -to SFPD_MOD2_SDA +set_location_assignment PIN_V21 -to SFPD_RATESEL[0] +set_location_assignment PIN_M22 -to SFPD_RATESEL[1] +set_location_assignment PIN_BB2 -to SFPD_RX_p +set_location_assignment PIN_U20 -to SFPD_TXDISABLE +set_location_assignment PIN_T21 -to SFPD_TXFAULT +set_location_assignment PIN_AY6 -to SFPD_TX_p +set_location_assignment PIN_BB33 -to SMA_CLKIN +set_location_assignment PIN_B25 -to SW[0] +set_location_assignment PIN_A25 -to SW[1] +set_location_assignment PIN_B23 -to SW[2] +set_location_assignment PIN_A23 -to SW[3] +set_location_assignment PIN_D21 -to TEMP_CLK +set_location_assignment PIN_D20 -to TEMP_DATA +set_location_assignment PIN_C21 -to TEMP_INT_n +set_location_assignment PIN_C22 -to TEMP_OVERT_n +set_location_assignment PIN_AV34 -to SMA_CLKOUT +set_location_assignment PIN_V39 -to SATA_DEVICE_REFCLK_p +set_location_assignment PIN_V6 -to SATA_HOST_REFCLK_p +set_location_assignment PIN_V5 -to "SATA_HOST_REFCLK_p(n)" +set_location_assignment PIN_V40 -to "SATA_DEVICE_REFCLK_p(n)" +set_location_assignment PIN_K43 -to SATA_DEVICE_RX_p[0] +set_location_assignment PIN_H43 -to SATA_DEVICE_RX_p[1] +set_location_assignment PIN_K39 -to SATA_DEVICE_TX_p[0] +set_location_assignment PIN_H39 -to SATA_DEVICE_TX_p[1] +set_location_assignment PIN_K44 -to "SATA_DEVICE_RX_p[0](n)" +set_location_assignment PIN_H44 -to "SATA_DEVICE_RX_p[1](n)" +set_location_assignment PIN_K40 -to "SATA_DEVICE_TX_p[0](n)" +set_location_assignment PIN_H40 -to "SATA_DEVICE_TX_p[1](n)" +set_location_assignment PIN_K2 -to SATA_HOST_RX_p[0] +set_location_assignment PIN_K1 -to "SATA_HOST_RX_p[0](n)" +set_location_assignment PIN_H2 -to SATA_HOST_RX_p[1] +set_location_assignment PIN_H1 -to "SATA_HOST_RX_p[1](n)" +set_location_assignment PIN_K6 -to SATA_HOST_TX_p[0] +set_location_assignment PIN_K5 -to "SATA_HOST_TX_p[0](n)" +set_location_assignment PIN_H6 -to SATA_HOST_TX_p[1] +set_location_assignment PIN_H5 -to "SATA_HOST_TX_p[1](n)" +set_location_assignment PIN_AK7 -to SFP_REFCLK_p + +#============================================================ + + + +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "2.5 V" +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" +set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" + +set_location_assignment PIN_PIN -to NETName +set_location_assignment PIN_AK39 -to "PCIE_REFCLK_p(n)" +set_instance_assignment -name IO_STANDARD HCSL -to "PCIE_REFCLK_p(n)" +set_location_assignment PIN_BB44 -to "PCIE_RX_p[0](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_RX_p[0](n)" +set_location_assignment PIN_BA42 -to "PCIE_RX_p[1](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_RX_p[1](n)" +set_location_assignment PIN_AW42 -to "PCIE_RX_p[2](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_RX_p[2](n)" +set_location_assignment PIN_AY44 -to "PCIE_RX_p[3](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_RX_p[3](n)" +set_location_assignment PIN_AT44 -to "PCIE_RX_p[4](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_RX_p[4](n)" +set_location_assignment PIN_AP44 -to "PCIE_RX_p[5](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_RX_p[5](n)" +set_location_assignment PIN_AM44 -to "PCIE_RX_p[6](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_RX_p[6](n)" +set_location_assignment PIN_AK44 -to "PCIE_RX_p[7](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_RX_p[7](n)" +set_location_assignment PIN_AY40 -to "PCIE_TX_p[0](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_TX_p[0](n)" +set_location_assignment PIN_AV40 -to "PCIE_TX_p[1](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_TX_p[1](n)" +set_location_assignment PIN_AT40 -to "PCIE_TX_p[2](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_TX_p[2](n)" +set_location_assignment PIN_AU42 -to "PCIE_TX_p[3](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_TX_p[3](n)" +set_location_assignment PIN_AN42 -to "PCIE_TX_p[4](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_TX_p[4](n)" +set_location_assignment PIN_AL42 -to "PCIE_TX_p[5](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_TX_p[5](n)" +set_location_assignment PIN_AJ42 -to "PCIE_TX_p[6](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_TX_p[6](n)" +set_location_assignment PIN_AG42 -to "PCIE_TX_p[7](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_TX_p[7](n)" +set_instance_assignment -name IO_STANDARD HCSL -to "SATA_DEVICE_REFCLK_p(n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SATA_DEVICE_RX_p[0](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SATA_DEVICE_RX_p[1](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SATA_DEVICE_TX_p[0](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SATA_DEVICE_TX_p[1](n)" +set_instance_assignment -name IO_STANDARD HCSL -to "SATA_HOST_REFCLK_p(n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SATA_HOST_RX_p[0](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SATA_HOST_RX_p[1](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SATA_HOST_TX_p[0](n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SATA_HOST_TX_p[1](n)" +set_location_assignment PIN_AH5 -to "SFP1G_REFCLK_p(n)" +set_instance_assignment -name IO_STANDARD HCSL -to "SFP1G_REFCLK_p(n)" +set_location_assignment PIN_AK1 -to "SFPA_RX_p(n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SFPA_RX_p(n)" +set_location_assignment PIN_AG3 -to "SFPA_TX_p(n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SFPA_TX_p(n)" +set_location_assignment PIN_AP1 -to "SFPB_RX_p(n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SFPB_RX_p(n)" +set_location_assignment PIN_AL3 -to "SFPB_TX_p(n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SFPB_TX_p(n)" +set_location_assignment PIN_AW3 -to "SFPC_RX_p(n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SFPC_RX_p(n)" +set_location_assignment PIN_AT5 -to "SFPC_TX_p(n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SFPC_TX_p(n)" +set_location_assignment PIN_BB1 -to "SFPD_RX_p(n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SFPD_RX_p(n)" +set_location_assignment PIN_AY5 -to "SFPD_TX_p(n)" +set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "SFPD_TX_p(n)" +set_location_assignment PIN_AK7 -to SFP_REFCLK_P +set_instance_assignment -name IO_STANDARD HCSL -to SFP_REFCLK_P +set_location_assignment PIN_AK6 -to "SFP_REFCLK_P(n)" +set_instance_assignment -name IO_STANDARD HCSL -to "SFP_REFCLK_P(n)" +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top + diff --git a/example/DE5-Net/fpga/fpga.sdc b/example/DE5-Net/fpga/fpga.sdc new file mode 100644 index 000000000..7d6348f81 --- /dev/null +++ b/example/DE5-Net/fpga/fpga.sdc @@ -0,0 +1,98 @@ + +#************************************************************** +# Create Clock +#************************************************************** + +create_clock -period 20 [get_ports OSC_50_B3B] +create_clock -period 20 [get_ports OSC_50_B3D] +create_clock -period 20 [get_ports OSC_50_B4A] +create_clock -period 20 [get_ports OSC_50_B4D] + +create_clock -period 20 [get_ports OSC_50_B7A] +create_clock -period 20 [get_ports OSC_50_B7D] +create_clock -period 20 [get_ports OSC_50_B8A] +create_clock -period 20 [get_ports OSC_50_B8D] + +create_clock -period 1.5515 [get_ports SFP_REFCLK_P] + + + + +#************************************************************** +# Create Generated Clock +#************************************************************** +derive_pll_clocks + + + + + + +#************************************************************** +# Set Clock Latency +#************************************************************** + + +#************************************************************** +# Set Clock Uncertainty +#************************************************************** +derive_clock_uncertainty + + + +#************************************************************** +# Set Input Delay +#************************************************************** + + + +#************************************************************** +# Set Output Delay +#************************************************************** + + + +#************************************************************** +# Set Clock Groups +#************************************************************** + + + +#************************************************************** +# Set False Path +#************************************************************** + + + +#************************************************************** +# Set Multicycle Path +#************************************************************** + + + +#************************************************************** +# Set Maximum Delay +#************************************************************** + + + +#************************************************************** +# Set Minimum Delay +#************************************************************** + + + +#************************************************************** +# Set Input Transition +#************************************************************** + + + +#************************************************************** +# Set Load +#************************************************************** + + + + + diff --git a/example/DE5-Net/fpga/fpga/Makefile b/example/DE5-Net/fpga/fpga/Makefile new file mode 100644 index 000000000..b47250444 --- /dev/null +++ b/example/DE5-Net/fpga/fpga/Makefile @@ -0,0 +1,68 @@ + +# FPGA settings +FPGA_TOP = fpga +FPGA_FAMILY = "Stratix V" +FPGA_DEVICE = 5SGXEA7N2F45C2 + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/i2c_master.v +SYN_FILES += rtl/si570_i2c_init.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_crc_8.v +SYN_FILES += lib/eth/rtl/eth_crc_16.v +SYN_FILES += lib/eth/rtl/eth_crc_24.v +SYN_FILES += lib/eth/rtl/eth_crc_32.v +SYN_FILES += lib/eth/rtl/eth_crc_40.v +SYN_FILES += lib/eth/rtl/eth_crc_48.v +SYN_FILES += lib/eth/rtl/eth_crc_56.v +SYN_FILES += lib/eth/rtl/eth_crc_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_64_2.v +SYN_FILES += lib/eth/rtl/ip_mux_64_2.v +SYN_FILES += lib/eth/rtl/arp_64.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v +SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_64_2.v +SYN_FILES += lib/eth/rtl/eth_mux_64_2.v +SYN_FILES += lib/eth/rtl/xgmii_interleave.v +SYN_FILES += lib/eth/rtl/xgmii_deinterleave.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo_64.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v +SYN_FILES += cores/phy/phy.qip +SYN_FILES += cores/phy_reconfig/phy_reconfig.qip + +# QSF files +QSF_FILES = fpga.qsf + +# SDC files +SDC_FILES = fpga.sdc + +include ../common/altera.mk + +program: fpga + quartus_pgm --no_banner --mode=jtag -o "P;$(FPGA_TOP).sof" + +# program with 'factory default' parallel flash loader design (or something else with a NIOS2 that can see the flash chips) +program_flash_pfl: fpga + nios2_command_shell.sh sof2flash --input="$(FPGA_TOP).sof" --output="$(FPGA_TOP).flash" --offset=0x20C0000 --pfl --optionbit=0x00030000 --programmingmode=PS + nios2_command_shell.sh nios2-flash-programmer --base=0x0 "$(FPGA_TOP).flash" diff --git a/example/DE5-Net/fpga/lib/eth b/example/DE5-Net/fpga/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/DE5-Net/fpga/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/DE5-Net/fpga/rtl/debounce_switch.v b/example/DE5-Net/fpga/rtl/debounce_switch.v new file mode 100644 index 000000000..3e2dc20a5 --- /dev/null +++ b/example/DE5-Net/fpga/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/DE5-Net/fpga/rtl/fpga.v b/example/DE5-Net/fpga/rtl/fpga.v new file mode 100644 index 000000000..c3bb27f57 --- /dev/null +++ b/example/DE5-Net/fpga/rtl/fpga.v @@ -0,0 +1,422 @@ +/* + +Copyright (c) 2016 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 + +/* + * FPGA top-level module + */ +module fpga ( + // CPU reset button + input wire CPU_RESET_n, + // buttons + input wire [3:0] BUTTON, + input wire [3:0] SW, + // LEDs + output wire [6:0] HEX0_D, + output wire HEX0_DP, + output wire [6:0] HEX1_D, + output wire HEX1_DP, + output wire [3:0] LED, + output wire [3:0] LED_BRACKET, + output wire LED_RJ45_L, + output wire LED_RJ45_R, + // Temperature control + //inout wire TEMP_CLK, + //inout wire TEMP_DATA, + //input wire TEMP_INT_n, + //input wire TEMP_OVERT_n, + output wire FAN_CTRL, + // 50 MHz clock inputs + input wire OSC_50_B3B, + input wire OSC_50_B3D, + input wire OSC_50_B4A, + input wire OSC_50_B4D, + input wire OSC_50_B7A, + input wire OSC_50_B7D, + input wire OSC_50_B8A, + input wire OSC_50_B8D, + // PCIe interface + //input wire PCIE_PERST_n, + //input wire PCIE_REFCLK_p, + //input wire [7:0] PCIE_RX_p, + //output wire [7:0] PCIE_TX_p, + //input wire PCIE_WAKE_n, + //inout wire PCIE_SMBCLK, + //inout wire PCIE_SMBDAT, + // Si570 + inout wire CLOCK_SCL, + inout wire CLOCK_SDA, + // 10G Ethernet + input wire SFPA_RX_p, + output wire SFPA_TX_p, + input wire SFPB_RX_p, + output wire SFPB_TX_p, + input wire SFPC_RX_p, + output wire SFPC_TX_p, + input wire SFPD_RX_p, + output wire SFPD_TX_p, + input wire SFP_REFCLK_P +); + +// Clock and reset + +wire clk_50mhz = OSC_50_B3B; +wire rst_50mhz; + +sync_reset #( + .N(4) +) +sync_reset_50mhz_inst ( + .clk(clk_50mhz), + .rst(~CPU_RESET_n), + .sync_reset_out(rst_50mhz) +); + +wire clk_156mhz; +wire rst_156mhz; + +wire phy_pll_locked; + +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz), + .rst(rst_50mhz | ~phy_pll_locked), + .sync_reset_out(rst_156mhz) +); + +// GPIO + +wire [3:0] btn_int; +wire [3:0] sw_int; +wire [3:0] led_int; +wire [3:0] led_bkt_int; +wire [6:0] led_hex0_d_int; +wire led_hex0_dp_int; +wire [6:0] led_hex1_d_int; +wire led_hex1_dp_int; + +debounce_switch #( + .WIDTH(8), + .N(4), + .RATE(156250) +) +debounce_switch_inst ( + .clk(clk_156mhz), + .rst(rst_156mhz), + .in({BUTTON, + SW}), + .out({btn_int, + sw_int}) +); + +assign LED = led_int; +assign LED_BRACKET = led_bkt_int; +assign HEX0_D = led_hex0_d_int; +assign HEX0_DP = led_hex0_dp_int; +assign HEX1_D = led_hex1_d_int; +assign HEX1_DP = led_hex1_dp_int; + +assign FAN_CTRL = 1; + +// Si570 oscillator I2C init + +wire si570_scl_i; +wire si570_scl_o; +wire si570_scl_t; +wire si570_sda_i; +wire si570_sda_o; +wire si570_sda_t; + +assign si570_sda_i = CLOCK_SDA; +assign CLOCK_SDA = si570_sda_t ? 1'bz : si570_sda_o; +assign si570_scl_i = CLOCK_SCL; +assign CLOCK_SCL = si570_scl_t ? 1'bz : si570_scl_o; + +wire [6:0] si570_i2c_cmd_address; +wire si570_i2c_cmd_start; +wire si570_i2c_cmd_read; +wire si570_i2c_cmd_write; +wire si570_i2c_cmd_write_multiple; +wire si570_i2c_cmd_stop; +wire si570_i2c_cmd_valid; +wire si570_i2c_cmd_ready; + +wire [7:0] si570_i2c_data; +wire si570_i2c_data_valid; +wire si570_i2c_data_ready; +wire si570_i2c_data_last; + +si570_i2c_init +si570_i2c_init_inst ( + .clk(clk_50mhz), + .rst(rst_50mhz), + .cmd_address(si570_i2c_cmd_address), + .cmd_start(si570_i2c_cmd_start), + .cmd_read(si570_i2c_cmd_read), + .cmd_write(si570_i2c_cmd_write), + .cmd_write_multiple(si570_i2c_cmd_write_multiple), + .cmd_stop(si570_i2c_cmd_stop), + .cmd_valid(si570_i2c_cmd_valid), + .cmd_ready(si570_i2c_cmd_ready), + .data_out(si570_i2c_data), + .data_out_valid(si570_i2c_data_valid), + .data_out_ready(si570_i2c_data_ready), + .data_out_last(si570_i2c_data_last), + .busy(), + .start(1) +); + +i2c_master +si570_i2c_master_inst ( + .clk(clk_50mhz), + .rst(rst_50mhz), + .cmd_address(si570_i2c_cmd_address), + .cmd_start(si570_i2c_cmd_start), + .cmd_read(si570_i2c_cmd_read), + .cmd_write(si570_i2c_cmd_write), + .cmd_write_multiple(si570_i2c_cmd_write_multiple), + .cmd_stop(si570_i2c_cmd_stop), + .cmd_valid(si570_i2c_cmd_valid), + .cmd_ready(si570_i2c_cmd_ready), + .data_in(si570_i2c_data), + .data_in_valid(si570_i2c_data_valid), + .data_in_ready(si570_i2c_data_ready), + .data_in_last(si570_i2c_data_last), + .data_out(), + .data_out_valid(), + .data_out_ready(1), + .data_out_last(), + .scl_i(si570_scl_i), + .scl_o(si570_scl_o), + .scl_t(si570_scl_t), + .sda_i(si570_sda_i), + .sda_o(si570_sda_o), + .sda_t(si570_sda_t), + .busy(), + .bus_control(), + .bus_active(), + .missed_ack(), + .prescale(312), + .stop_on_idle(1) +); + +// 10G Ethernet PHY + +wire [71:0] sfp_a_tx_dc; +wire [71:0] sfp_a_rx_dc; +wire [71:0] sfp_b_tx_dc; +wire [71:0] sfp_b_rx_dc; +wire [71:0] sfp_c_tx_dc; +wire [71:0] sfp_c_rx_dc; +wire [71:0] sfp_d_tx_dc; +wire [71:0] sfp_d_rx_dc; + +wire [367:0] phy_reconfig_from_xcvr; +wire [559:0] phy_reconfig_to_xcvr; + +phy +phy_inst ( + .pll_ref_clk(SFP_REFCLK_P), + .pll_locked(phy_pll_locked), + + .tx_serial_data_0(SFPA_TX_p), + .rx_serial_data_0(SFPA_RX_p), + .tx_serial_data_1(SFPB_TX_p), + .rx_serial_data_1(SFPB_RX_p), + .tx_serial_data_2(SFPC_TX_p), + .rx_serial_data_2(SFPC_RX_p), + .tx_serial_data_3(SFPD_TX_p), + .rx_serial_data_3(SFPD_RX_p), + + .xgmii_tx_dc_0(sfp_a_tx_dc), + .xgmii_rx_dc_0(sfp_a_rx_dc), + .xgmii_tx_dc_1(sfp_b_tx_dc), + .xgmii_rx_dc_1(sfp_b_rx_dc), + .xgmii_tx_dc_2(sfp_c_tx_dc), + .xgmii_rx_dc_2(sfp_c_rx_dc), + .xgmii_tx_dc_3(sfp_d_tx_dc), + .xgmii_rx_dc_3(sfp_d_rx_dc), + + .xgmii_rx_clk(clk_156mhz), + .xgmii_tx_clk(clk_156mhz), + + .tx_ready(~rst_156mhz), + .rx_ready(), + + .rx_data_ready(), + + .phy_mgmt_clk(clk_50mhz), + .phy_mgmt_clk_reset(rst_50mhz), + .phy_mgmt_address(9'd0), + .phy_mgmt_read(1'b0), + .phy_mgmt_readdata(), + .phy_mgmt_waitrequest(), + .phy_mgmt_write(1'b0), + .phy_mgmt_writedata(32'd0), + + .reconfig_from_xcvr(phy_reconfig_from_xcvr), + .reconfig_to_xcvr(phy_reconfig_to_xcvr) +); + +phy_reconfig +phy_reconfig_inst ( + .reconfig_busy(), + + .mgmt_clk_clk(clk_50mhz), + .mgmt_rst_reset(rst_50mhz), + + .reconfig_mgmt_address(7'd0), + .reconfig_mgmt_read(1'b0), + .reconfig_mgmt_readdata(), + .reconfig_mgmt_waitrequest(), + .reconfig_mgmt_write(1'b0), + .reconfig_mgmt_writedata(32'd0), + + .reconfig_to_xcvr(phy_reconfig_to_xcvr), + .reconfig_from_xcvr(phy_reconfig_from_xcvr) +); + +// Convert XGMII interfaces + +wire [63:0] sfp_a_txd_int; +wire [7:0] sfp_a_txc_int; +wire [63:0] sfp_a_rxd_int; +wire [7:0] sfp_a_rxc_int; +wire [63:0] sfp_b_txd_int; +wire [7:0] sfp_b_txc_int; +wire [63:0] sfp_b_rxd_int; +wire [7:0] sfp_b_rxc_int; +wire [63:0] sfp_c_txd_int; +wire [7:0] sfp_c_txc_int; +wire [63:0] sfp_c_rxd_int; +wire [7:0] sfp_c_rxc_int; +wire [63:0] sfp_d_txd_int; +wire [7:0] sfp_d_txc_int; +wire [63:0] sfp_d_rxd_int; +wire [7:0] sfp_d_rxc_int; + +xgmii_interleave +xgmii_interleave_inst_a ( + .input_xgmii_d(sfp_a_txd_int), + .input_xgmii_c(sfp_a_txc_int), + .output_xgmii_dc(sfp_a_tx_dc) +); + +xgmii_deinterleave +xgmii_deinterleave_inst_a ( + .input_xgmii_dc(sfp_a_rx_dc), + .output_xgmii_d(sfp_a_rxd_int), + .output_xgmii_c(sfp_a_rxc_int) +); + +xgmii_interleave +xgmii_interleave_inst_b ( + .input_xgmii_d(sfp_b_txd_int), + .input_xgmii_c(sfp_b_txc_int), + .output_xgmii_dc(sfp_b_tx_dc) +); + +xgmii_deinterleave +xgmii_deinterleave_inst_b ( + .input_xgmii_dc(sfp_b_rx_dc), + .output_xgmii_d(sfp_b_rxd_int), + .output_xgmii_c(sfp_b_rxc_int) +); + +xgmii_interleave +xgmii_interleave_inst_c ( + .input_xgmii_d(sfp_c_txd_int), + .input_xgmii_c(sfp_c_txc_int), + .output_xgmii_dc(sfp_c_tx_dc) +); + +xgmii_deinterleave +xgmii_deinterleave_inst_c ( + .input_xgmii_dc(sfp_c_rx_dc), + .output_xgmii_d(sfp_c_rxd_int), + .output_xgmii_c(sfp_c_rxc_int) +); + +xgmii_interleave +xgmii_interleave_inst_d ( + .input_xgmii_d(sfp_d_txd_int), + .input_xgmii_c(sfp_d_txc_int), + .output_xgmii_dc(sfp_d_tx_dc) +); + +xgmii_deinterleave +xgmii_deinterleave_inst_d ( + .input_xgmii_dc(sfp_d_rx_dc), + .output_xgmii_d(sfp_d_rxd_int), + .output_xgmii_c(sfp_d_rxc_int) +); + +// Core logic + +fpga_core +core_inst ( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + .clk(clk_156mhz), + .rst(rst_156mhz), + /* + * GPIO + */ + .btn(btn_int), + .sw(sw_int), + .led(led_int), + .led_bkt(led_bkt_int), + .led_hex0_d(led_hex0_d_int), + .led_hex0_dp(led_hex0_dp_int), + .led_hex1_d(led_hex1_d_int), + .led_hex1_dp(led_hex1_dp_int), + /* + * 10G Ethernet + */ + .sfp_a_txd(sfp_a_txd_int), + .sfp_a_txc(sfp_a_txc_int), + .sfp_a_rxd(sfp_a_rxd_int), + .sfp_a_rxc(sfp_a_rxc_int), + .sfp_b_txd(sfp_b_txd_int), + .sfp_b_txc(sfp_b_txc_int), + .sfp_b_rxd(sfp_b_rxd_int), + .sfp_b_rxc(sfp_b_rxc_int), + .sfp_c_txd(sfp_c_txd_int), + .sfp_c_txc(sfp_c_txc_int), + .sfp_c_rxd(sfp_c_rxd_int), + .sfp_c_rxc(sfp_c_rxc_int), + .sfp_d_txd(sfp_d_txd_int), + .sfp_d_txc(sfp_d_txc_int), + .sfp_d_rxd(sfp_d_rxd_int), + .sfp_d_rxc(sfp_d_rxc_int) +); + +endmodule diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..0b1f3a952 --- /dev/null +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -0,0 +1,589 @@ +/* + +Copyright (c) 2016 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 + +/* + * FPGA core logic + */ +module fpga_core +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire [3:0] btn, + input wire [3:0] sw, + output wire [3:0] led, + output wire [3:0] led_bkt, + output wire [6:0] led_hex0_d, + output wire led_hex0_dp, + output wire [6:0] led_hex1_d, + output wire led_hex1_dp, + + /* + * 10G Ethernet + */ + output wire [63:0] sfp_a_txd, + output wire [7:0] sfp_a_txc, + input wire [63:0] sfp_a_rxd, + input wire [7:0] sfp_a_rxc, + output wire [63:0] sfp_b_txd, + output wire [7:0] sfp_b_txc, + input wire [63:0] sfp_b_rxd, + input wire [7:0] sfp_b_rxc, + output wire [63:0] sfp_c_txd, + output wire [7:0] sfp_c_txc, + input wire [63:0] sfp_c_rxd, + input wire [7:0] sfp_c_rxc, + output wire [63:0] sfp_d_txd, + output wire [7:0] sfp_d_txc, + input wire [63:0] sfp_d_rxd, + input wire [7:0] sfp_d_rxc +); + +// AXI between MAC and Ethernet modules +wire [63:0] rx_axis_tdata; +wire [7:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [63:0] tx_axis_tdata; +wire [7:0] tx_axis_tkeep; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [63:0] rx_eth_payload_tdata; +wire [7:0] rx_eth_payload_tkeep; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [63:0] tx_eth_payload_tdata; +wire [7:0] tx_eth_payload_tkeep; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [63:0] rx_ip_payload_tdata; +wire [7:0] rx_ip_payload_tkeep; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [63:0] tx_ip_payload_tdata; +wire [7:0] tx_ip_payload_tkeep; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [63:0] rx_udp_payload_tdata; +wire [7:0] rx_udp_payload_tkeep; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [63:0] tx_udp_payload_tdata; +wire [7:0] tx_udp_payload_tkeep; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [63:0] rx_fifo_udp_payload_tdata; +wire [7:0] rx_fifo_udp_payload_tkeep; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [63:0] tx_fifo_udp_payload_tdata; +wire [7:0] tx_fifo_udp_payload_tkeep; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tkeep = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tkeep = rx_udp_payload_tkeep; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tkeep = tx_fifo_udp_payload_tkeep; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tkeep = rx_udp_payload_tkeep; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_tvalid; + if (tx_udp_payload_tvalid & ~valid_last) begin + led_reg <= tx_udp_payload_tdata; + end + end +end + +//assign led = sw; +assign led = ~led_reg; +assign led_bkt = ~led_reg; +assign led_hex0_d = 7'h7F; +assign led_hex0_dp = 1'b1; +assign led_hex1_d = 7'h7F; +assign led_hex1_dp = 1'b1; + +assign sfp_b_txd = 64'h0707070707070707; +assign sfp_b_txc = 8'hff; +assign sfp_c_txd = 64'h0707070707070707; +assign sfp_c_txc = 8'hff; +assign sfp_d_txd = 64'h0707070707070707; +assign sfp_d_txc = 8'hff; + +eth_mac_10g_fifo #( + .ENABLE_PADDING(1), + .ENABLE_DIC(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(9), + .RX_FIFO_ADDR_WIDTH(9) +) +eth_mac_10g_fifo_inst ( + .rx_clk(clk), + .rx_rst(rst), + .tx_clk(clk), + .tx_rst(rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .xgmii_rxd(sfp_a_rxd), + .xgmii_rxc(sfp_a_rxc), + .xgmii_txd(sfp_a_txd), + .xgmii_txc(sfp_a_txc), + + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + + .ifg_delay(8'd12) +); + +eth_axis_rx_64 +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tkeep(rx_axis_tkeep), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tkeep(rx_eth_payload_tkeep), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx_64 +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tkeep(tx_eth_payload_tkeep), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tkeep(tx_axis_tkeep), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete_64 #( + .UDP_CHECKSUM_ENABLE(0) +) +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tkeep(rx_eth_payload_tkeep), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tkeep(tx_eth_payload_tkeep), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tkeep(tx_ip_payload_tkeep), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tkeep(rx_ip_payload_tkeep), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tkeep(tx_udp_payload_tkeep), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tkeep(rx_udp_payload_tkeep), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(1'b0) +); + +axis_fifo_64 #( + .ADDR_WIDTH(10), + .DATA_WIDTH(64) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(rx_fifo_udp_payload_tkeep), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(tx_fifo_udp_payload_tkeep), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/DE5-Net/fpga/rtl/i2c_master.v b/example/DE5-Net/fpga/rtl/i2c_master.v new file mode 100644 index 000000000..4a6b945c1 --- /dev/null +++ b/example/DE5-Net/fpga/rtl/i2c_master.v @@ -0,0 +1,895 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * I2C master + */ +module i2c_master ( + input wire clk, + input wire rst, + + /* + * Host interface + */ + input wire [6:0] cmd_address, + input wire cmd_start, + input wire cmd_read, + input wire cmd_write, + input wire cmd_write_multiple, + input wire cmd_stop, + input wire cmd_valid, + output wire cmd_ready, + + input wire [7:0] data_in, + input wire data_in_valid, + output wire data_in_ready, + input wire data_in_last, + + output wire [7:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + output wire data_out_last, + + /* + * I2C interface + */ + input wire scl_i, + output wire scl_o, + output wire scl_t, + input wire sda_i, + output wire sda_o, + output wire sda_t, + + /* + * Status + */ + output wire busy, + output wire bus_control, + output wire bus_active, + output wire missed_ack, + + /* + * Configuration + */ + input wire [15:0] prescale, + input wire stop_on_idle +); + +/* + +I2C + +Read + __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ +sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_\_R___A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A____/ + ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ +scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP + +Write + __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ +sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_/_W_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_/_N_\__/ + ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ +scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP + +Commands: + +read + read data byte + set start to force generation of a start condition + start is implied when bus is inactive or active with write or different address + set stop to issue a stop condition after reading current byte + if stop is set with read command, then data_out_last will be set + +write + write data byte + set start to force generation of a start condition + start is implied when bus is inactive or active with read or different address + set stop to issue a stop condition after writing current byte + +write multiple + write multiple data bytes (until data_in_last) + set start to force generation of a start condition + start is implied when bus is inactive or active with read or different address + set stop to issue a stop condition after writing block + +stop + issue stop condition if bus is active + +Status: + +busy + module is communicating over the bus + +bus_control + module has control of bus in active state + +bus_active + bus is active, not necessarily controlled by this module + +missed_ack + strobed when a slave ack is missed + +Parameters: + +prescale + set prescale to 1/4 of the minimum clock period in units + of input clk cycles (prescale = Fclk / (FI2Cclk * 4)) + +stop_on_idle + automatically issue stop when command input is not valid + +Example of interfacing with tristate pins: +(this will work for any tristate bus) + +assign scl_i = scl_pin; +assign scl_pin = scl_t ? 1'bz : scl_o; +assign sda_i = sda_pin; +assign sda_pin = sda_t ? 1'bz : sda_o; + +Equivalent code that does not use *_t connections: +(we can get away with this because I2C is open-drain) + +assign scl_i = scl_pin; +assign scl_pin = scl_o ? 1'bz : 1'b0; +assign sda_i = sda_pin; +assign sda_pin = sda_o ? 1'bz : 1'b0; + +Example of two interconnected I2C devices: + +assign scl_1_i = scl_1_o & scl_2_o; +assign scl_2_i = scl_1_o & scl_2_o; +assign sda_1_i = sda_1_o & sda_2_o; +assign sda_2_i = sda_1_o & sda_2_o; + +Example of two I2C devices sharing the same pins: + +assign scl_1_i = scl_pin; +assign scl_2_i = scl_pin; +assign scl_pin = (scl_1_o & scl_2_o) ? 1'bz : 1'b0; +assign sda_1_i = sda_pin; +assign sda_2_i = sda_pin; +assign sda_pin = (sda_1_o & sda_2_o) ? 1'bz : 1'b0; + +Notes: + +scl_o should not be connected directly to scl_i, only via AND logic or a tristate +I/O pin. This would prevent devices from stretching the clock period. + +*/ + +localparam [4:0] + STATE_IDLE = 4'd0, + STATE_ACTIVE_WRITE = 4'd1, + STATE_ACTIVE_READ = 4'd2, + STATE_START_WAIT = 4'd3, + STATE_START = 4'd4, + STATE_ADDRESS_1 = 4'd5, + STATE_ADDRESS_2 = 4'd6, + STATE_WRITE_1 = 4'd7, + STATE_WRITE_2 = 4'd8, + STATE_WRITE_3 = 4'd9, + STATE_READ = 4'd10, + STATE_STOP = 4'd11; + +reg [4:0] state_reg = STATE_IDLE, state_next; + +localparam [4:0] + PHY_STATE_IDLE = 5'd0, + PHY_STATE_ACTIVE = 5'd1, + PHY_STATE_REPEATED_START_1 = 5'd2, + PHY_STATE_REPEATED_START_2 = 5'd3, + PHY_STATE_START_1 = 5'd4, + PHY_STATE_START_2 = 5'd5, + PHY_STATE_WRITE_BIT_1 = 5'd6, + PHY_STATE_WRITE_BIT_2 = 5'd7, + PHY_STATE_WRITE_BIT_3 = 5'd8, + PHY_STATE_READ_BIT_1 = 5'd9, + PHY_STATE_READ_BIT_2 = 5'd10, + PHY_STATE_READ_BIT_3 = 5'd11, + PHY_STATE_READ_BIT_4 = 5'd12, + PHY_STATE_STOP_1 = 5'd13, + PHY_STATE_STOP_2 = 5'd14, + PHY_STATE_STOP_3 = 5'd15; + +reg [4:0] phy_state_reg = STATE_IDLE, phy_state_next; + +reg phy_start_bit; +reg phy_stop_bit; +reg phy_write_bit; +reg phy_read_bit; +reg phy_release_bus; + +reg phy_tx_data; + +reg phy_rx_data_reg = 1'b0, phy_rx_data_next; + +reg [6:0] addr_reg = 7'd0, addr_next; +reg [7:0] data_reg = 8'd0, data_next; +reg last_reg = 1'b0, last_next; + +reg mode_read_reg = 1'b0, mode_read_next; +reg mode_write_multiple_reg = 1'b0, mode_write_multiple_next; +reg mode_stop_reg = 1'b0, mode_stop_next; + +reg [16:0] delay_reg = 16'd0, delay_next; +reg delay_scl_reg = 1'b0, delay_scl_next; +reg delay_sda_reg = 1'b0, delay_sda_next; + +reg [3:0] bit_count_reg = 4'd0, bit_count_next; + +reg cmd_ready_reg = 1'b0, cmd_ready_next; + +reg data_in_ready_reg = 1'b0, data_in_ready_next; + +reg [7:0] data_out_reg = 8'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; +reg data_out_last_reg = 1'b0, data_out_last_next; + +reg scl_i_reg = 1'b1; +reg sda_i_reg = 1'b1; + +reg scl_o_reg = 1'b1, scl_o_next; +reg sda_o_reg = 1'b1, sda_o_next; + +reg last_scl_i_reg = 1'b1; +reg last_sda_i_reg = 1'b1; + +reg busy_reg = 1'b0; +reg bus_active_reg = 1'b0; +reg bus_control_reg = 1'b0, bus_control_next; +reg missed_ack_reg = 1'b0, missed_ack_next; + +assign cmd_ready = cmd_ready_reg; + +assign data_in_ready = data_in_ready_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; +assign data_out_last = data_out_last_reg; + +assign scl_o = scl_o_reg; +assign scl_t = scl_o_reg; +assign sda_o = sda_o_reg; +assign sda_t = sda_o_reg; + +assign busy = busy_reg; +assign bus_active = bus_active_reg; +assign bus_control = bus_control_reg; +assign missed_ack = missed_ack_reg; + +wire scl_posedge = scl_i_reg & ~last_scl_i_reg; +wire scl_negedge = ~scl_i_reg & last_scl_i_reg; +wire sda_posedge = sda_i_reg & ~last_sda_i_reg; +wire sda_negedge = ~sda_i_reg & last_sda_i_reg; + +wire start_bit = sda_negedge & scl_i_reg; +wire stop_bit = sda_posedge & scl_i_reg; + +always @* begin + state_next = STATE_IDLE; + + phy_start_bit = 1'b0; + phy_stop_bit = 1'b0; + phy_write_bit = 1'b0; + phy_read_bit = 1'b0; + phy_tx_data = 1'b0; + phy_release_bus = 1'b0; + + addr_next = addr_reg; + data_next = data_reg; + last_next = last_reg; + + mode_read_next = mode_read_reg; + mode_write_multiple_next = mode_write_multiple_reg; + mode_stop_next = mode_stop_reg; + + bit_count_next = bit_count_reg; + + cmd_ready_next = 1'b0; + + data_in_ready_next = 1'b0; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + data_out_last_next = data_out_last_reg; + + missed_ack_next = 1'b0; + + // generate delays + if (phy_state_reg != PHY_STATE_IDLE && phy_state_reg != PHY_STATE_ACTIVE) begin + // wait for phy operation + state_next = state_reg; + end else begin + // process states + case (state_reg) + STATE_IDLE: begin + // line idle + cmd_ready_next = 1'b1; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + // start bit + if (bus_active) begin + state_next = STATE_START_WAIT; + end else begin + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + end else begin + // invalid or unspecified - ignore + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_ACTIVE_WRITE: begin + // line active with current address and read/write mode + cmd_ready_next = 1'b1; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + if (cmd_start || cmd_address != addr_reg || cmd_read) begin + // address or mode mismatch or forced start - repeated start + + // repeated start bit + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end else begin + // address and mode match + + // start write + data_in_ready_next = 1'b1; + state_next = STATE_WRITE_1; + end + end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin + // stop command + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + // invalid or unspecified - ignore + state_next = STATE_ACTIVE_WRITE; + end + end else begin + if (stop_on_idle & cmd_ready & ~cmd_valid) begin + // no waiting command and stop_on_idle selected, issue stop condition + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + state_next = STATE_ACTIVE_WRITE; + end + end + end + STATE_ACTIVE_READ: begin + // line active to current address + cmd_ready_next = ~data_out_valid; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + if (cmd_start || cmd_address != addr_reg || cmd_write) begin + // address or mode mismatch or forced start - repeated start + + // write nack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // repeated start bit + state_next = STATE_START; + end else begin + // address and mode match + + // write ack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b0; + // start next read + bit_count_next = 4'd8; + data_next = 8'd0; + state_next = STATE_READ; + end + end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin + // stop command + // write nack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // send stop bit + state_next = STATE_STOP; + end else begin + // invalid or unspecified - ignore + state_next = STATE_ACTIVE_READ; + end + end else begin + if (stop_on_idle & cmd_ready & ~cmd_valid) begin + // no waiting command and stop_on_idle selected, issue stop condition + // write ack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // send stop bit + state_next = STATE_STOP; + end else begin + state_next = STATE_ACTIVE_READ; + end + end + end + STATE_START_WAIT: begin + // wait for bus idle + + if (bus_active) begin + state_next = STATE_START_WAIT; + end else begin + // bus is idle, take control + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + end + STATE_START: begin + // send start bit + + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + STATE_ADDRESS_1: begin + // send address + bit_count_next = bit_count_reg - 1; + if (bit_count_reg > 1) begin + // send address + phy_write_bit = 1'b1; + phy_tx_data = addr_reg[bit_count_reg-2]; + state_next = STATE_ADDRESS_1; + end else if (bit_count_reg > 0) begin + // send read/write bit + phy_write_bit = 1'b1; + phy_tx_data = mode_read_reg; + state_next = STATE_ADDRESS_1; + end else begin + // read ack bit + phy_read_bit = 1'b1; + state_next = STATE_ADDRESS_2; + end + end + STATE_ADDRESS_2: begin + // read ack bit + missed_ack_next = phy_rx_data_reg; + + if (mode_read_reg) begin + // start read + bit_count_next = 4'd8; + data_next = 1'b0; + state_next = STATE_READ; + end else begin + // start write + data_in_ready_next = 1'b1; + state_next = STATE_WRITE_1; + end + end + STATE_WRITE_1: begin + data_in_ready_next = 1'b1; + + if (data_in_ready & data_in_valid) begin + // got data, start write + data_next = data_in; + last_next = data_in_last; + bit_count_next = 4'd8; + data_in_ready_next = 1'b0; + state_next = STATE_WRITE_2; + end else begin + // wait for data + state_next = STATE_WRITE_1; + end + end + STATE_WRITE_2: begin + // send data + bit_count_next = bit_count_reg - 1; + if (bit_count_reg > 0) begin + // write data bit + phy_write_bit = 1'b1; + phy_tx_data = data_reg[bit_count_reg-1]; + state_next = STATE_WRITE_2; + end else begin + // read ack bit + phy_read_bit = 1'b1; + state_next = STATE_WRITE_3; + end + end + STATE_WRITE_3: begin + // read ack bit + missed_ack_next = phy_rx_data_reg; + + if (mode_write_multiple_reg && !last_reg) begin + // more to write + state_next = STATE_WRITE_1; + end else if (mode_stop_reg) begin + // last cycle and stop selected + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + // otherwise, return to bus active state + state_next = STATE_ACTIVE_WRITE; + end + end + STATE_READ: begin + // read data + + bit_count_next = bit_count_reg - 1; + data_next = {data_reg[6:0], phy_rx_data_reg}; + if (bit_count_reg > 0) begin + // read next bit + phy_read_bit = 1'b1; + state_next = STATE_READ; + end else begin + // output data word + data_out_next = data_next; + data_out_valid_next = 1'b1; + data_out_last_next = 1'b0; + if (mode_stop_reg) begin + // send nack and stop + data_out_last_next = 1'b1; + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + state_next = STATE_STOP; + end else begin + // return to bus active state + state_next = STATE_ACTIVE_READ; + end + end + end + STATE_STOP: begin + // send stop bit + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end + endcase + end +end + +always @* begin + phy_state_next = PHY_STATE_IDLE; + + phy_rx_data_next = phy_rx_data_reg; + + delay_next = delay_reg; + delay_scl_next = delay_scl_reg; + delay_sda_next = delay_sda_reg; + + scl_o_next = scl_o_reg; + sda_o_next = sda_o_reg; + + bus_control_next = bus_control_reg; + + if (phy_release_bus) begin + // release bus and return to idle state + sda_o_next = 1'b1; + scl_o_next = 1'b1; + delay_scl_next = 1'b0; + delay_sda_next = 1'b0; + delay_next = 1'b0; + phy_state_next = PHY_STATE_IDLE; + end else if (delay_scl_reg) begin + // wait for SCL to match command + delay_scl_next = scl_o_reg & ~scl_i_reg; + phy_state_next = phy_state_reg; + end else if (delay_sda_reg) begin + // wait for SDA to match command + delay_sda_next = sda_o_reg & ~sda_i_reg; + phy_state_next = phy_state_reg; + end else if (delay_reg > 0) begin + // time delay + delay_next = delay_reg - 1; + phy_state_next = phy_state_reg; + end else begin + case (phy_state_reg) + PHY_STATE_IDLE: begin + // bus idle - wait for start command + sda_o_next = 1'b1; + scl_o_next = 1'b1; + if (phy_start_bit) begin + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_1; + end else begin + phy_state_next = PHY_STATE_IDLE; + end + end + PHY_STATE_ACTIVE: begin + // bus active + if (phy_start_bit) begin + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_REPEATED_START_1; + end else if (phy_write_bit) begin + sda_o_next = phy_tx_data; + delay_next = prescale; + phy_state_next = PHY_STATE_WRITE_BIT_1; + end else if (phy_read_bit) begin + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_1; + end else if (phy_stop_bit) begin + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_1; + end else begin + phy_state_next = PHY_STATE_ACTIVE; + end + end + PHY_STATE_REPEATED_START_1: begin + // generate repeated start bit + // ______ + // sda XXX/ \_______ + // _______ + // scl ______/ \___ + // + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_REPEATED_START_2; + end + PHY_STATE_REPEATED_START_2: begin + // generate repeated start bit + // ______ + // sda XXX/ \_______ + // _______ + // scl ______/ \___ + // + + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_1; + end + PHY_STATE_START_1: begin + // generate start bit + // ___ + // sda \_______ + // _______ + // scl \___ + // + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_2; + end + PHY_STATE_START_2: begin + // generate start bit + // ___ + // sda \_______ + // _______ + // scl \___ + // + + bus_control_next = 1'b1; + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_WRITE_BIT_1: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale << 1; + phy_state_next = PHY_STATE_WRITE_BIT_2; + end + PHY_STATE_WRITE_BIT_2: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_WRITE_BIT_3; + end + PHY_STATE_WRITE_BIT_3: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_READ_BIT_1: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_2; + end + PHY_STATE_READ_BIT_2: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_rx_data_next = sda_i_reg; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_3; + end + PHY_STATE_READ_BIT_3: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_4; + end + PHY_STATE_READ_BIT_4: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_STOP_1: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_2; + end + PHY_STATE_STOP_2: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_3; + end + PHY_STATE_STOP_3: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + bus_control_next = 1'b0; + phy_state_next = PHY_STATE_IDLE; + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + phy_state_reg <= PHY_STATE_IDLE; + delay_reg <= 16'd0; + delay_scl_reg <= 1'b0; + delay_sda_reg <= 1'b0; + cmd_ready_reg <= 1'b0; + data_in_ready_reg <= 1'b0; + data_out_valid_reg <= 1'b0; + scl_o_reg <= 1'b1; + sda_o_reg <= 1'b1; + busy_reg <= 1'b0; + bus_active_reg <= 1'b0; + bus_control_reg <= 1'b0; + missed_ack_reg <= 1'b0; + end else begin + state_reg <= state_next; + phy_state_reg <= phy_state_next; + + delay_reg <= delay_next; + delay_scl_reg <= delay_scl_next; + delay_sda_reg <= delay_sda_next; + + cmd_ready_reg <= cmd_ready_next; + data_in_ready_reg <= data_in_ready_next; + data_out_valid_reg <= data_out_valid_next; + + scl_o_reg <= scl_o_next; + sda_o_reg <= sda_o_next; + + busy_reg <= !(state_reg == STATE_IDLE || state_reg == STATE_ACTIVE_WRITE || state_reg == STATE_ACTIVE_READ); + + if (start_bit) begin + bus_active_reg <= 1'b1; + end else if (stop_bit) begin + bus_active_reg <= 1'b0; + end else begin + bus_active_reg <= bus_active_reg; + end + + bus_control_reg <= bus_control_next; + missed_ack_reg <= missed_ack_next; + end + + phy_rx_data_reg <= phy_rx_data_next; + + addr_reg <= addr_next; + data_reg <= data_next; + last_reg <= last_next; + + mode_read_reg <= mode_read_next; + mode_write_multiple_reg <= mode_write_multiple_next; + mode_stop_reg <= mode_stop_next; + + bit_count_reg <= bit_count_next; + + data_out_reg <= data_out_next; + data_out_last_reg <= data_out_last_next; + + scl_i_reg <= scl_i; + sda_i_reg <= sda_i; + last_scl_i_reg <= scl_i_reg; + last_sda_i_reg <= sda_i_reg; +end + +endmodule diff --git a/example/DE5-Net/fpga/rtl/si570_i2c_init.v b/example/DE5-Net/fpga/rtl/si570_i2c_init.v new file mode 100644 index 000000000..8c0130a89 --- /dev/null +++ b/example/DE5-Net/fpga/rtl/si570_i2c_init.v @@ -0,0 +1,455 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * si570_i2c_init + */ +module si570_i2c_init ( + input wire clk, + input wire rst, + + /* + * I2C master interface + */ + output wire [6:0] cmd_address, + output wire cmd_start, + output wire cmd_read, + output wire cmd_write, + output wire cmd_write_multiple, + output wire cmd_stop, + output wire cmd_valid, + input wire cmd_ready, + + output wire [7:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + output wire data_out_last, + + /* + * Status + */ + output wire busy, + + /* + * Configuration + */ + input wire start +); + +/* + +Generic module for I2C bus initialization. Good for use when multiple devices +on an I2C bus must be initialized on system start without intervention of a +general-purpose processor. + +Copy this file and change init_data and INIT_DATA_LEN as needed. + +This module can be used in two modes: simple device initalization, or multiple +device initialization. In multiple device mode, the same initialization sequence +can be performed on multiple different device addresses. + +To use single device mode, only use the start write to address and write data commands. +The module will generate the I2C commands in sequential order. Terminate the list +with a 0 entry. + +To use the multiple device mode, use the start data and start address block commands +to set up lists of initialization data and device addresses. The module enters +multiple device mode upon seeing a start data block command. The module stores the +offset of the start of the data block and then skips ahead until it reaches a start +address block command. The module will store the offset to the address block and +read the first address in the block. Then it will jump back to the data block +and execute it, substituting the stored address for each current address write +command. Upon reaching the start address block command, the module will read out the +next address and start again at the top of the data block. If the module encounters +a start data block command while looking for an address, then it will store a new data +offset and then look for a start address block command. Terminate the list with a 0 +entry. Normal address commands will operate normally inside a data block. + +Commands: + +00 0000000 : stop +00 0000001 : exit multiple device mode +00 0000011 : start write to current address +00 0001000 : start address block +00 0001001 : start data block +01 aaaaaaa : start write to address +1 dddddddd : write 8-bit data + +Examples + +write 0x11223344 to register 0x0004 on device at 0x50 + +01 1010000 start write to 0x50 +1 00000000 write address 0x0004 +1 00000100 +1 00010001 write data 0x11223344 +1 00100010 +1 00110011 +1 01000100 +0 00000000 stop + +write 0x11223344 to register 0x0004 on devices at 0x50, 0x51, 0x52, and 0x53 + +00 0001001 start data block +00 0000011 start write to current address +1 00000000 write address 0x0004 +1 00000100 +1 00010001 write data 0x11223344 +1 00100010 +1 00110011 +1 01000100 +00 0001000 start address block +01 1010000 address 0x50 +01 1010001 address 0x51 +01 1010010 address 0x52 +01 1010011 address 0x53 +00 0000000 stop + +*/ + +// init_data ROM +localparam INIT_DATA_LEN = 18; + +reg [8:0] init_data [INIT_DATA_LEN-1:0]; + +initial begin + // Set Si570 to generate 644.53125 MHz + init_data[0] = {2'b01, 7'h00}; // start write to address 0x00 + init_data[1] = {1'b1, 8'd137}; // write address 137 + init_data[2] = {1'b1, 8'h10}; // write data 0x10 (freeze DCO) + init_data[3] = {2'b01, 7'h00}; // start write to address 0x00 + init_data[4] = {1'b1, 8'd7}; // write address 7 + init_data[5] = {1'b1, {3'b000, 5'b000000}}; // write data (address 7) (HS_DIV = 3'b000) + init_data[6] = {1'b1, {2'b01, 6'h2}}; // write data (address 8) (N1 = 7'b000001) + init_data[7] = {1'b1, 8'hD1}; // write data (address 9) + init_data[8] = {1'b1, 8'hE1}; // write data (address 10) + init_data[9] = {1'b1, 8'h27}; // write data (address 11) + init_data[10] = {1'b1, 8'hAF}; // write data (address 12) (RFREQ = 38'h2D1E127AF) + init_data[11] = {2'b01, 7'h00}; // start write to address 0x00 + init_data[12] = {1'b1, 8'd137}; // write address 137 + init_data[13] = {1'b1, 8'h00}; // write data 0x00 (un-freeze DCO) + init_data[14] = {2'b01, 7'h00}; // start write to address 0x00 + init_data[15] = {1'b1, 8'd135}; // write address 135 + init_data[16] = {1'b1, 8'h40}; // write data 0x40 (new frequency applied) + init_data[17] = 9'd0; // stop +end + +localparam [3:0] + STATE_IDLE = 3'd0, + STATE_RUN = 3'd1, + STATE_TABLE_1 = 3'd2, + STATE_TABLE_2 = 3'd3, + STATE_TABLE_3 = 3'd4; + +reg [4:0] state_reg = STATE_IDLE, state_next; + +parameter AW = $clog2(INIT_DATA_LEN); + +reg [8:0] init_data_reg = 9'd0; + +reg [AW-1:0] address_reg = {AW{1'b0}}, address_next; +reg [AW-1:0] address_ptr_reg = {AW{1'b0}}, address_ptr_next; +reg [AW-1:0] data_ptr_reg = {AW{1'b0}}, data_ptr_next; + +reg [6:0] cur_address_reg = 7'd0, cur_address_next; + +reg [6:0] cmd_address_reg = 7'd0, cmd_address_next; +reg cmd_start_reg = 1'b0, cmd_start_next; +reg cmd_write_reg = 1'b0, cmd_write_next; +reg cmd_stop_reg = 1'b0, cmd_stop_next; +reg cmd_valid_reg = 1'b0, cmd_valid_next; + +reg [7:0] data_out_reg = 8'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; + +reg start_flag_reg = 1'b0, start_flag_next; + +reg busy_reg = 1'b0; + +assign cmd_address = cmd_address_reg; +assign cmd_start = cmd_start_reg; +assign cmd_read = 1'b0; +assign cmd_write = cmd_write_reg; +assign cmd_write_multiple = 1'b0; +assign cmd_stop = cmd_stop_reg; +assign cmd_valid = cmd_valid_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; +assign data_out_last = 1'b1; + +assign busy = busy_reg; + +always @* begin + state_next = STATE_IDLE; + + address_next = address_reg; + address_ptr_next = address_ptr_reg; + data_ptr_next = data_ptr_reg; + + cur_address_next = cur_address_reg; + + cmd_address_next = cmd_address_reg; + cmd_start_next = cmd_start_reg & ~(cmd_valid & cmd_ready); + cmd_write_next = cmd_write_reg & ~(cmd_valid & cmd_ready); + cmd_stop_next = cmd_stop_reg & ~(cmd_valid & cmd_ready); + cmd_valid_next = cmd_valid_reg & ~cmd_ready; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + + start_flag_next = start_flag_reg; + + if (cmd_valid | data_out_valid) begin + // wait for output registers to clear + state_next = state_reg; + end else begin + case (state_reg) + STATE_IDLE: begin + // wait for start signal + if (~start_flag_reg & start) begin + address_next = {AW{1'b0}}; + start_flag_next = 1'b1; + state_next = STATE_RUN; + end else begin + state_next = STATE_IDLE; + end + end + STATE_RUN: begin + // process commands + if (init_data_reg[8] == 1'b1) begin + // write data + cmd_write_next = 1'b1; + cmd_stop_next = 1'b0; + cmd_valid_next = 1'b1; + + data_out_next = init_data_reg[7:0]; + data_out_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg[8:7] == 2'b01) begin + // write address + cmd_address_next = init_data_reg[6:0]; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_RUN; + end + end + STATE_TABLE_1: begin + // find address table start + if (init_data_reg == 9'b000001000) begin + // address table start + address_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_2; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end + end + STATE_TABLE_2: begin + // find next address + if (init_data_reg[8:7] == 2'b01) begin + // write address command + // store address and move to data table + cur_address_next = init_data_reg[6:0]; + address_ptr_next = address_reg + 1; + address_next = data_ptr_reg; + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'd1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_2; + end + end + STATE_TABLE_3: begin + // process data table with selected address + if (init_data_reg[8] == 1'b1) begin + // write data + cmd_write_next = 1'b1; + cmd_stop_next = 1'b0; + cmd_valid_next = 1'b1; + + data_out_next = init_data_reg[7:0]; + data_out_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg[8:7] == 2'b01) begin + // write address + cmd_address_next = init_data_reg[6:0]; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000000011) begin + // write current address + cmd_address_next = cur_address_reg; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'b000001000) begin + // address table start + address_next = address_ptr_reg; + state_next = STATE_TABLE_2; + end else if (init_data_reg == 9'd1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_3; + end + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + init_data_reg <= 9'd0; + + address_reg <= {AW{1'b0}}; + address_ptr_reg <= {AW{1'b0}}; + data_ptr_reg <= {AW{1'b0}}; + + cur_address_reg <= 7'd0; + + cmd_valid_reg <= 1'b0; + + data_out_valid_reg <= 1'b0; + + start_flag_reg <= 1'b0; + + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + + // read init_data ROM + init_data_reg <= init_data[address_next]; + + address_reg <= address_next; + address_ptr_reg <= address_ptr_next; + data_ptr_reg <= data_ptr_next; + + cur_address_reg <= cur_address_next; + + cmd_valid_reg <= cmd_valid_next; + + data_out_valid_reg <= data_out_valid_next; + + start_flag_reg <= start & start_flag_next; + + busy_reg <= (state_reg != STATE_IDLE); + end + + cmd_address_reg <= cmd_address_next; + cmd_start_reg <= cmd_start_next; + cmd_write_reg <= cmd_write_next; + cmd_stop_reg <= cmd_stop_next; + + data_out_reg <= data_out_next; +end + +endmodule diff --git a/example/DE5-Net/fpga/rtl/sync_reset.v b/example/DE5-Net/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..ddd99febe --- /dev/null +++ b/example/DE5-Net/fpga/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/DE5-Net/fpga/rtl/sync_signal.v b/example/DE5-Net/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..5afcd7170 --- /dev/null +++ b/example/DE5-Net/fpga/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/DE5-Net/fpga/tb/arp_ep.py b/example/DE5-Net/fpga/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/DE5-Net/fpga/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/DE5-Net/fpga/tb/axis_ep.py b/example/DE5-Net/fpga/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/DE5-Net/fpga/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/DE5-Net/fpga/tb/eth_ep.py b/example/DE5-Net/fpga/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/DE5-Net/fpga/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/DE5-Net/fpga/tb/ip_ep.py b/example/DE5-Net/fpga/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/DE5-Net/fpga/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py new file mode 100755 index 000000000..e6cf98423 --- /dev/null +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -0,0 +1,412 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import eth_ep +import arp_ep +import udp_ep +import xgmii_ep + +module = 'fpga_core' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/eth_crc_8.v") +srcs.append("../lib/eth/rtl/eth_crc_16.v") +srcs.append("../lib/eth/rtl/eth_crc_24.v") +srcs.append("../lib/eth/rtl/eth_crc_32.v") +srcs.append("../lib/eth/rtl/eth_crc_40.v") +srcs.append("../lib/eth/rtl/eth_crc_48.v") +srcs.append("../lib/eth/rtl/eth_crc_56.v") +srcs.append("../lib/eth/rtl/eth_crc_64.v") +srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_64_2.v") +srcs.append("../lib/eth/rtl/ip_mux_64_2.v") +srcs.append("../lib/eth/rtl/arp_64.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") +srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") +srcs.append("../lib/eth/rtl/eth_mux_64_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo_64.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_fpga_core(clk, + rst, + current_test, + + btn, + sw, + led, + led_bkt, + led_hex0_d, + led_hex0_dp, + led_hex1_d, + led_hex1_dp, + + sfp_a_txd, + sfp_a_txc, + sfp_a_rxd, + sfp_a_rxc, + sfp_b_txd, + sfp_b_txc, + sfp_b_rxd, + sfp_b_rxc, + sfp_c_txd, + sfp_c_txc, + sfp_c_rxd, + sfp_c_rxc, + sfp_d_txd, + sfp_d_txc, + sfp_d_rxd, + sfp_d_rxc): + + 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, + + btn=btn, + sw=sw, + led=led, + led_bkt=led_bkt, + led_hex0_d=led_hex0_d, + led_hex0_dp=led_hex0_dp, + led_hex1_d=led_hex1_d, + led_hex1_dp=led_hex1_dp, + + sfp_a_txd=sfp_a_txd, + sfp_a_txc=sfp_a_txc, + sfp_a_rxd=sfp_a_rxd, + sfp_a_rxc=sfp_a_rxc, + sfp_b_txd=sfp_b_txd, + sfp_b_txc=sfp_b_txc, + sfp_b_rxd=sfp_b_rxd, + sfp_b_rxc=sfp_b_rxc, + sfp_c_txd=sfp_c_txd, + sfp_c_txc=sfp_c_txc, + sfp_c_rxd=sfp_c_rxd, + sfp_c_rxc=sfp_c_rxc, + sfp_d_txd=sfp_d_txd, + sfp_d_txc=sfp_d_txc, + sfp_d_rxd=sfp_d_rxd, + sfp_d_rxc=sfp_d_rxc) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btn = Signal(intbv(0)[4:]) + sw = Signal(intbv(0)[4:]) + sfp_a_rxd = Signal(intbv(0)[64:]) + sfp_a_rxc = Signal(intbv(0)[8:]) + sfp_b_rxd = Signal(intbv(0)[64:]) + sfp_b_rxc = Signal(intbv(0)[8:]) + sfp_c_rxd = Signal(intbv(0)[64:]) + sfp_c_rxc = Signal(intbv(0)[8:]) + sfp_d_rxd = Signal(intbv(0)[64:]) + sfp_d_rxc = Signal(intbv(0)[8:]) + + # Outputs + led = Signal(intbv(0)[4:]) + led_bkt = Signal(intbv(0)[4:]) + led_hex0_d = Signal(intbv(0)[7:]) + led_hex0_dp = Signal(bool(0)) + led_hex1_d = Signal(intbv(0)[7:]) + led_hex1_dp = Signal(bool(0)) + sfp_a_txd = Signal(intbv(0)[64:]) + sfp_a_txc = Signal(intbv(0)[8:]) + sfp_b_txd = Signal(intbv(0)[64:]) + sfp_b_txc = Signal(intbv(0)[8:]) + sfp_c_txd = Signal(intbv(0)[64:]) + sfp_c_txc = Signal(intbv(0)[8:]) + sfp_d_txd = Signal(intbv(0)[64:]) + sfp_d_txc = Signal(intbv(0)[8:]) + + # sources and sinks + xgmii_a_source_queue = Queue() + xgmii_a_sink_queue = Queue() + xgmii_b_source_queue = Queue() + xgmii_b_sink_queue = Queue() + xgmii_c_source_queue = Queue() + xgmii_c_sink_queue = Queue() + xgmii_d_source_queue = Queue() + xgmii_d_sink_queue = Queue() + + xgmii_a_source = xgmii_ep.XGMIISource(clk, + rst, + txd=sfp_a_rxd, + txc=sfp_a_rxc, + fifo=xgmii_a_source_queue, + name='xgmii_a_source') + + xgmii_a_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=sfp_a_txd, + rxc=sfp_a_txc, + fifo=xgmii_a_sink_queue, + name='xgmii_a_sink') + + xgmii_b_source = xgmii_ep.XGMIISource(clk, + rst, + txd=sfp_b_rxd, + txc=sfp_b_rxc, + fifo=xgmii_b_source_queue, + name='xgmii_b_source') + + xgmii_b_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=sfp_b_txd, + rxc=sfp_b_txc, + fifo=xgmii_b_sink_queue, + name='xgmii_b_sink') + + xgmii_c_source = xgmii_ep.XGMIISource(clk, + rst, + txd=sfp_c_rxd, + txc=sfp_c_rxc, + fifo=xgmii_c_source_queue, + name='xgmii_c_source') + + xgmii_c_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=sfp_c_txd, + rxc=sfp_c_txc, + fifo=xgmii_c_sink_queue, + name='xgmii_c_sink') + + xgmii_d_source = xgmii_ep.XGMIISource(clk, + rst, + txd=sfp_d_rxd, + txc=sfp_d_rxc, + fifo=xgmii_d_source_queue, + name='xgmii_d_source') + + xgmii_d_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=sfp_d_txd, + rxc=sfp_d_txc, + fifo=xgmii_d_sink_queue, + name='xgmii_d_sink') + + # DUT + dut = dut_fpga_core(clk, + rst, + current_test, + + btn, + sw, + led, + led_bkt, + led_hex0_d, + led_hex0_dp, + led_hex1_d, + led_hex1_dp, + + sfp_a_txd, + sfp_a_txc, + sfp_a_rxd, + sfp_a_rxc, + sfp_b_txd, + sfp_b_txc, + sfp_b_rxd, + sfp_b_rxc, + sfp_c_txd, + sfp_c_txc, + sfp_c_rxd, + sfp_c_rxc, + sfp_d_txd, + sfp_d_txc, + sfp_d_rxd, + sfp_d_rxc) + + @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 + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + xgmii_a_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while xgmii_a_sink_queue.empty(): + yield clk.posedge + + rx_frame = xgmii_a_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + xgmii_a_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while xgmii_a_sink_queue.empty(): + yield clk.posedge + + rx_frame = xgmii_a_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert xgmii_a_source_queue.empty() + assert xgmii_a_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, xgmii_a_source, xgmii_a_sink, xgmii_b_source, xgmii_b_sink, xgmii_c_source, xgmii_c_sink, xgmii_d_source, xgmii_d_sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.v b/example/DE5-Net/fpga/tb/test_fpga_core.v new file mode 100644 index 000000000..a5e8eb745 --- /dev/null +++ b/example/DE5-Net/fpga/tb/test_fpga_core.v @@ -0,0 +1,133 @@ +/* + +Copyright (c) 2016 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [3:0] btn = 0; +reg [3:0] sw = 0; +reg [63:0] sfp_a_rxd = 0; +reg [7:0] sfp_a_rxc = 0; +reg [63:0] sfp_b_rxd = 0; +reg [7:0] sfp_b_rxc = 0; +reg [63:0] sfp_c_rxd = 0; +reg [7:0] sfp_c_rxc = 0; +reg [63:0] sfp_d_rxd = 0; +reg [7:0] sfp_d_rxc = 0; + +// Outputs +wire [3:0] led; +wire [3:0] led_bkt; +wire [6:0] led_hex0_d; +wire led_hex0_dp; +wire [6:0] led_hex1_d; +wire led_hex1_dp; +wire [63:0] sfp_a_txd; +wire [7:0] sfp_a_txc; +wire [63:0] sfp_b_txd; +wire [7:0] sfp_b_txc; +wire [63:0] sfp_c_txd; +wire [7:0] sfp_c_txc; +wire [63:0] sfp_d_txd; +wire [7:0] sfp_d_txc; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + btn, + sw, + sfp_a_rxd, + sfp_a_rxc, + sfp_b_rxd, + sfp_b_rxc, + sfp_c_rxd, + sfp_c_rxc, + sfp_d_rxd, + sfp_d_rxc); + $to_myhdl(led, + led_bkt, + led_hex0_d, + led_hex0_dp, + led_hex1_d, + led_hex1_dp, + sfp_a_txd, + sfp_a_txc, + sfp_b_txd, + sfp_b_txc, + sfp_c_txd, + sfp_c_txc, + sfp_d_txd, + sfp_d_txc); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .btn(btn), + .sw(sw), + .led(led), + .led_bkt(led_bkt), + .led_hex0_d(led_hex0_d), + .led_hex0_dp(led_hex0_dp), + .led_hex1_d(led_hex1_d), + .led_hex1_dp(led_hex1_dp), + .sfp_a_txd(sfp_a_txd), + .sfp_a_txc(sfp_a_txc), + .sfp_a_rxd(sfp_a_rxd), + .sfp_a_rxc(sfp_a_rxc), + .sfp_b_txd(sfp_b_txd), + .sfp_b_txc(sfp_b_txc), + .sfp_b_rxd(sfp_b_rxd), + .sfp_b_rxc(sfp_b_rxc), + .sfp_c_txd(sfp_c_txd), + .sfp_c_txc(sfp_c_txc), + .sfp_c_rxd(sfp_c_rxd), + .sfp_c_rxc(sfp_c_rxc), + .sfp_d_txd(sfp_d_txd), + .sfp_d_txc(sfp_d_txc), + .sfp_d_rxd(sfp_d_rxd), + .sfp_d_rxc(sfp_d_rxc) +); + +endmodule diff --git a/example/DE5-Net/fpga/tb/udp_ep.py b/example/DE5-Net/fpga/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/DE5-Net/fpga/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/example/DE5-Net/fpga/tb/xgmii_ep.py b/example/DE5-Net/fpga/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/example/DE5-Net/fpga/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file From 5eb0d9f57882cd9831af860229dcf782df800590 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 25 Jan 2016 13:21:35 -0800 Subject: [PATCH 270/617] Move invert to top-level module --- example/DE5-Net/fpga/rtl/fpga.v | 12 ++++++------ example/DE5-Net/fpga/rtl/fpga_core.v | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/example/DE5-Net/fpga/rtl/fpga.v b/example/DE5-Net/fpga/rtl/fpga.v index c3bb27f57..b4276afdb 100644 --- a/example/DE5-Net/fpga/rtl/fpga.v +++ b/example/DE5-Net/fpga/rtl/fpga.v @@ -135,12 +135,12 @@ debounce_switch_inst ( sw_int}) ); -assign LED = led_int; -assign LED_BRACKET = led_bkt_int; -assign HEX0_D = led_hex0_d_int; -assign HEX0_DP = led_hex0_dp_int; -assign HEX1_D = led_hex1_d_int; -assign HEX1_DP = led_hex1_dp_int; +assign LED = ~led_int; +assign LED_BRACKET = ~led_bkt_int; +assign HEX0_D = ~led_hex0_d_int; +assign HEX0_DP = ~led_hex0_dp_int; +assign HEX1_D = ~led_hex1_d_int; +assign HEX1_DP = ~led_hex1_dp_int; assign FAN_CTRL = 1; diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index 0b1f3a952..4176ee3d2 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -312,12 +312,12 @@ always @(posedge clk) begin end //assign led = sw; -assign led = ~led_reg; -assign led_bkt = ~led_reg; -assign led_hex0_d = 7'h7F; -assign led_hex0_dp = 1'b1; -assign led_hex1_d = 7'h7F; -assign led_hex1_dp = 1'b1; +assign led = led_reg; +assign led_bkt = led_reg; +assign led_hex0_d = 7'h00; +assign led_hex0_dp = 1'b0; +assign led_hex1_d = 7'h00; +assign led_hex1_dp = 1'b0; assign sfp_b_txd = 64'h0707070707070707; assign sfp_b_txc = 8'hff; From f36256c541f3d237435b839cd0029574c819d957 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 25 Jan 2016 19:11:42 -0800 Subject: [PATCH 271/617] Add 10G reference design for HXT100G --- example/HXT100G/fpga/Makefile | 25 + example/HXT100G/fpga/README.md | 25 + example/HXT100G/fpga/common/xilinx.mk | 191 +++ example/HXT100G/fpga/coregen/Makefile | 33 + example/HXT100G/fpga/coregen/coregen.cgp | 22 + .../fpga/coregen/ten_gig_eth_pcs_pma_v2_6.xco | 53 + ...ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco | 185 +++ example/HXT100G/fpga/fpga.ucf | 269 ++++ example/HXT100G/fpga/fpga/Makefile | 93 ++ example/HXT100G/fpga/lib/eth | 1 + example/HXT100G/fpga/rtl/debounce_switch.v | 89 ++ example/HXT100G/fpga/rtl/eth_gth_phy_quad.v | 567 +++++++++ example/HXT100G/fpga/rtl/fpga.v | 1059 ++++++++++++++++ example/HXT100G/fpga/rtl/fpga_core.v | 733 +++++++++++ example/HXT100G/fpga/rtl/gth_i2c_init.v | 508 ++++++++ example/HXT100G/fpga/rtl/i2c_master.v | 895 +++++++++++++ example/HXT100G/fpga/rtl/sync_reset.v | 52 + example/HXT100G/fpga/rtl/sync_signal.v | 58 + example/HXT100G/fpga/tb/arp_ep.py | 1 + example/HXT100G/fpga/tb/axis_ep.py | 1 + example/HXT100G/fpga/tb/eth_ep.py | 1 + example/HXT100G/fpga/tb/ip_ep.py | 1 + example/HXT100G/fpga/tb/test_fpga_core.py | 1117 +++++++++++++++++ example/HXT100G/fpga/tb/test_fpga_core.v | 412 ++++++ example/HXT100G/fpga/tb/udp_ep.py | 1 + example/HXT100G/fpga/tb/xgmii_ep.py | 1 + 26 files changed, 6393 insertions(+) create mode 100644 example/HXT100G/fpga/Makefile create mode 100644 example/HXT100G/fpga/README.md create mode 100644 example/HXT100G/fpga/common/xilinx.mk create mode 100644 example/HXT100G/fpga/coregen/Makefile create mode 100644 example/HXT100G/fpga/coregen/coregen.cgp create mode 100644 example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6.xco create mode 100644 example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco create mode 100644 example/HXT100G/fpga/fpga.ucf create mode 100644 example/HXT100G/fpga/fpga/Makefile create mode 120000 example/HXT100G/fpga/lib/eth create mode 100644 example/HXT100G/fpga/rtl/debounce_switch.v create mode 100644 example/HXT100G/fpga/rtl/eth_gth_phy_quad.v create mode 100644 example/HXT100G/fpga/rtl/fpga.v create mode 100644 example/HXT100G/fpga/rtl/fpga_core.v create mode 100644 example/HXT100G/fpga/rtl/gth_i2c_init.v create mode 100644 example/HXT100G/fpga/rtl/i2c_master.v create mode 100644 example/HXT100G/fpga/rtl/sync_reset.v create mode 100644 example/HXT100G/fpga/rtl/sync_signal.v create mode 120000 example/HXT100G/fpga/tb/arp_ep.py create mode 120000 example/HXT100G/fpga/tb/axis_ep.py create mode 120000 example/HXT100G/fpga/tb/eth_ep.py create mode 120000 example/HXT100G/fpga/tb/ip_ep.py create mode 100755 example/HXT100G/fpga/tb/test_fpga_core.py create mode 100644 example/HXT100G/fpga/tb/test_fpga_core.v create mode 120000 example/HXT100G/fpga/tb/udp_ep.py create mode 120000 example/HXT100G/fpga/tb/xgmii_ep.py diff --git a/example/HXT100G/fpga/Makefile b/example/HXT100G/fpga/Makefile new file mode 100644 index 000000000..9f8bd4048 --- /dev/null +++ b/example/HXT100G/fpga/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = coregen fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/HXT100G/fpga/README.md b/example/HXT100G/fpga/README.md new file mode 100644 index 000000000..9da6d1a32 --- /dev/null +++ b/example/HXT100G/fpga/README.md @@ -0,0 +1,25 @@ +# Verilog Ethernet HXT100G Example Design + +## Introduction + +This example design targets the HiTech Global HXT100G FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +FPGA: XC6VHX565T-2FFG1923 +PHY: 10G BASE-R PHY IP core and internal GTH transceiver + +## How to build + +Run make to build. Ensure that the Xilinx ISE toolchain components are +in PATH. + +## How to test + +Run make program to program the HXT100G board with the Xilinx Impact software. +Then run netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. +Anyntext entered into netcat will be echoed back after pressing enter. + + diff --git a/example/HXT100G/fpga/common/xilinx.mk b/example/HXT100G/fpga/common/xilinx.mk new file mode 100644 index 000000000..f10a45f8e --- /dev/null +++ b/example/HXT100G/fpga/common/xilinx.mk @@ -0,0 +1,191 @@ +############################################################################# +# Author: Lane Brooks/Keith Fife +# Date: 04/28/2006 +# License: GPL +# Desc: This is a Makefile intended to take a verilog rtl design +# through the Xilinx ISE tools to generate configuration files for +# Xilinx FPGAs. This file is generic and just a template. As such +# all design specific options such as synthesis files, fpga part type, +# prom part type, etc should be set in the top Makefile prior to +# including this file. Alternatively, all parameters can be passed +# in from the command line as well. +# +############################################################################## +# +# Parameter: +# SYN_FILES - Space seperated list of files to be synthesized +# PART - FPGA part (see Xilinx documentation) +# PROM - PROM part +# NGC_PATHS - Space seperated list of any dirs with pre-compiled ngc files. +# UCF_FILES - Space seperated list of user constraint files. Defaults to xilinx/$(FPGA_TOP).ucf +# +# +# Example Calling Makefile: +# +# SYN_FILES = fpga.v fifo.v clks.v +# PART = xc3s1000 +# FPGA_TOP = fpga +# PROM = xc18v04 +# NGC_PATH = ipLib1 ipLib2 +# FPGA_ARCH = spartan6 +# SPI_PROM_SIZE = (in bytes) +# include xilinx.mk +############################################################################# +# +# Command Line Example: +# make -f xilinx.mk PART=xc3s1000-4fg320 SYN_FILES="fpga.v test.v" FPGA_TOP=fpga +# +############################################################################## +# +# Required Setup: +# +# %.ucf - user constraint file. Needed by ngdbuild +# +# Optional Files: +# %.xcf - user constraint file. Needed by xst. +# %.ut - File for pin states needed by bitgen + + +.PHONY: clean bit prom fpga spi + + +# Mark the intermediate files as PRECIOUS to prevent make from +# deleting them (see make manual section 10.4). +.PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.bit %_timesim.v + +# include the local Makefile for project for any project specific targets +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +INC_PATHS_REL = $(patsubst %, ../%, $(INC_PATHS)) +NGC_PATHS_REL = $(patsubst %, ../%, $(NGC_PATHS)) + +ifdef UCF_FILES + UCF_FILES_REL = $(patsubst %, ../%, $(UCF_FILES)) +else + UCF_FILES_REL = $(FPGA_TOP).ucf +endif + + + +fpga: $(FPGA_TOP).bit + +mcs: $(FPGA_TOP).mcs + +prom: $(FPGA_TOP).spi + +spi: $(FPGA_TOP).spi + +fpgasim: $(FPGA_TOP)_sim.v + + +########################### XST TEMPLATES ############################ +# There are 2 files that XST uses for synthesis that we auto generate. +# The first is a project file which is just a list of all the verilog +# files. The second is the src file which passes XST all the options. +# See XST user manual for XST options. +%.ngc: $(SYN_FILES_REL) $(INC_FILES_REL) + rm -rf xst $*.prj $*.xst defines.v + touch defines.v + mkdir -p xst/tmp + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo verilog work defines.v > $*.prj + for x in $(SYN_FILES_REL); do echo verilog work $$x >> $*.prj; done + @echo "set -tmpdir ./xst/tmp" >> $*.xst + @echo "set -xsthdpdir ./xst" >> $*.xst + @echo "run" >> $*.xst + @echo "-ifn $*.prj" >> $*.xst + @echo "-ifmt mixed" >> $*.xst + @echo "-top $*" >> $*.xst + @echo "-ofn $*" >> $*.xst + @echo "-ofmt NGC" >> $*.xst + @echo "-opt_mode Speed" >> $*.xst + @echo "-opt_level 1" >> $*.xst + # @echo "-verilog2001 YES" >> $*.xst + @echo "-keep_hierarchy NO" >> $*.xst + @echo "-p $(FPGA_PART)" >> $*.xst + xst -ifn $*.xst -ofn $*.log + + +########################### ISE TRANSLATE ############################ +# ngdbuild will automatically use a ucf called %.ucf if one is found. +# We setup the dependancy such that %.ucf file is required. If any +# pre-compiled ncd files are needed, set the NGC_PATH variable as a space +# seperated list of directories that include the pre-compiled ngc files. +%.ngd: %.ngc $(UCF_FILES_REL) + ngdbuild -dd ngdbuild $(patsubst %,-sd %, $(NGC_PATHS_REL)) $(patsubst %,-uc %, $(UCF_FILES_REL)) -p $(FPGA_PART) $< $@ + + +########################### ISE MAP ################################### +ifeq ($(FPGA_ARCH),spartan6) + MAP_OPTS= -register_duplication on -timing -xe n +else + MAP_OPTS= -cm speed -register_duplication on -timing -xe n -pr b +endif + +%_map.ncd: %.ngd + map -p $(FPGA_PART) $(MAP_OPTS) -w -o $@ $< $*.pcf + +# map -p $(FPGA_PART) -cm area -pr b -k 4 -c 100 -o $@ $< $*.pcf + + +########################### ISE PnR ################################### +%.ncd: %_map.ncd + par -w -ol high $< $@ $*.pcf + +# par -w -ol std -t 1 $< $@ $*.pcf + + +##################### ISE Static Timing Analysis ##################### +%.twr: %.ncd + -trce -e 3 -l 3 -u -xml $* $< -o $@ $*.pcf + +%_sim.v: %.ncd + netgen -s 4 -pcf $*.pcf -sdf_anno true -ism -sdf_path netgen -w -dir . -ofmt verilog -sim $< $@ + +# netgen -ise "/home/lane/Second/xilinx/Second/Second" -intstyle ise -s 4 -pcf Second.pcf -sdf_anno true -sdf_path netgen/par -w -dir netgen/par -ofmt verilog -sim Second.ncd Second_timesim.v + + +########################### ISE Bitgen ############################# +%.bit: %.twr + bitgen $(BITGEN_OPTIONS) -w $*.ncd $*.bit + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +########################### ISE Promgen ############################# +%.mcs: %.bit + promgen -spi -w -p mcs -s $(SPI_PROM_SIZE) -o $@ -u 0 $< + # promgen -w -p mcs -c FF -o $@ -u 0 $< -x $(PROM) + mkdir -p rev + EXT=mcs; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +%.spi: %.mcs + objcopy -I ihex -O binary $< $@ + EXT=spi; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + + +tmpclean: + -rm -rf xst ngdbuild *_map.* *.ncd *.ngc *.log *.xst *.prj *.lso *~ *.pcf *.bld *.ngd *.xpi *_pad.* *.unroutes *.twx *.par *.twr *.pad *.drc *.bgn *.prm *.sig netgen *.v *.nlf *.xml + +clean: tmpclean + -rm -rf *.bit *.mcs + +# clean everything +distclean: clean + -rm -rf rev + diff --git a/example/HXT100G/fpga/coregen/Makefile b/example/HXT100G/fpga/coregen/Makefile new file mode 100644 index 000000000..09ec2cdf4 --- /dev/null +++ b/example/HXT100G/fpga/coregen/Makefile @@ -0,0 +1,33 @@ +# Tools +COREGEN:=coregen +XAW2VERILOG:=xaw2verilog + +# Source +XCO:=ten_gig_eth_pcs_pma_v2_6.xco ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco +XAW:= + +# Targets +TARGETS += $(XCO:.xco=) +TARGETS += $(XAW:.xaw=) + +# Rules +.PHONY: all +all: $(TARGETS) + +.PHONY: clean +clean: + -rm -rf $(TARGETS) + +%: %.xco + $(eval $@_TMP := $(shell mktemp -d)) + cp -a coregen.cgp $($@_TMP) + cp -a $< $($@_TMP) + cd $($@_TMP) && $(COREGEN) -p coregen.cgp -b $(notdir $<) + mv $($@_TMP) $@ + +%: %.xaw + $(eval $@_TMP := $(shell mktemp -d)) + cp -a coregen.cgp $($@_TMP) + cp -a $< $($@_TMP) + cd $($@_TMP) && $(XAW2VERILOG) -st $(notdir $<) $(notdir $*) + mv $($@_TMP) $@ diff --git a/example/HXT100G/fpga/coregen/coregen.cgp b/example/HXT100G/fpga/coregen/coregen.cgp new file mode 100644 index 000000000..dbe49f4c0 --- /dev/null +++ b/example/HXT100G/fpga/coregen/coregen.cgp @@ -0,0 +1,22 @@ +# Date: Wed Apr 1 17:38:18 2015 + +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vhx565t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1923 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +SET workingdirectory = ./tmp/ + +# CRC: 3d2f7d04 diff --git a/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6.xco b/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6.xco new file mode 100644 index 000000000..2d141c5b0 --- /dev/null +++ b/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6.xco @@ -0,0 +1,53 @@ +############################################################## +# +# Xilinx Core Generator version 14.7 +# Date: Wed Apr 1 17:39:05 2015 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:ten_gig_eth_pcs_pma:2.6 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vhx565t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1923 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Ten_Gigabit_Ethernet_PCS/PMA_(10GBASE-R/KR) xilinx.com:ip:ten_gig_eth_pcs_pma:2.6 +# END Select +# BEGIN Parameters +CSET autonegotiation=false +CSET base_kr=BASE-R +CSET component_name=ten_gig_eth_pcs_pma_v2_6 +CSET fec=false +CSET ieee_1588=None +CSET mdio_management=false +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2012-10-08T14:58:05Z +# END Extra information +GENERATE +# CRC: d3dbdcf5 diff --git a/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco b/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco new file mode 100644 index 000000000..3c380f101 --- /dev/null +++ b/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco @@ -0,0 +1,185 @@ +############################################################## +# +# Xilinx Core Generator version 14.7 +# Date: Wed Apr 1 18:19:03 2015 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:v6_gthwizard:1.11 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vhx565t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1923 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Virtex-6_FPGA_GTH_Transceiver_Wizard xilinx.com:ip:v6_gthwizard:1.11 +# END Select +# BEGIN Parameters +CSET component_name=ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper +CSET config_identical=true +CSET drp_clock=50.00 +CSET gth0_datapath_width=64 +CSET gth0_encoding=10GbE_64B/66B +CSET gth0_line_rate=10.3125 +CSET gth0_postcursor_emphasis=0 +CSET gth0_precursor_emphasis=0 +CSET gth0_protocol_file=10GBASE-R +CSET gth0_rxeqmix=1000 +CSET gth0_tx_swing=800 +CSET gth0_use_dfetrainctrl=false +CSET gth0_use_lat_msr=false +CSET gth0_use_port_powerdown=true +CSET gth0_use_port_rxbufreset=true +CSET gth0_use_port_rxcodeerr=true +CSET gth0_use_port_rxctrl=true +CSET gth0_use_port_rxdisperr=false +CSET gth0_use_port_rxencommadet=false +CSET gth0_use_port_rxpolarity=false +CSET gth0_use_port_rxpowerdown=true +CSET gth0_use_port_rxslip=false +CSET gth0_use_port_rxvalid=false +CSET gth0_use_port_txbufreset=true +CSET gth0_use_port_txctrl=true +CSET gth0_use_port_txpowerdown=true +CSET gth1_datapath_width=64 +CSET gth1_encoding=10GbE_64B/66B +CSET gth1_line_rate=10.3125 +CSET gth1_postcursor_emphasis=0 +CSET gth1_precursor_emphasis=0 +CSET gth1_protocol_file=10GBASE-R +CSET gth1_rxeqmix=1000 +CSET gth1_tx_swing=800 +CSET gth1_use_dfetrainctrl=false +CSET gth1_use_lat_msr=false +CSET gth1_use_port_powerdown=true +CSET gth1_use_port_rxbufreset=true +CSET gth1_use_port_rxcodeerr=true +CSET gth1_use_port_rxctrl=true +CSET gth1_use_port_rxdisperr=false +CSET gth1_use_port_rxencommadet=false +CSET gth1_use_port_rxpolarity=false +CSET gth1_use_port_rxpowerdown=true +CSET gth1_use_port_rxslip=false +CSET gth1_use_port_rxvalid=false +CSET gth1_use_port_txbufreset=true +CSET gth1_use_port_txctrl=true +CSET gth1_use_port_txpowerdown=true +CSET gth2_datapath_width=64 +CSET gth2_encoding=10GbE_64B/66B +CSET gth2_line_rate=10.3125 +CSET gth2_postcursor_emphasis=0 +CSET gth2_precursor_emphasis=0 +CSET gth2_protocol_file=10GBASE-R +CSET gth2_rxeqmix=1000 +CSET gth2_tx_swing=800 +CSET gth2_use_dfetrainctrl=false +CSET gth2_use_lat_msr=false +CSET gth2_use_port_powerdown=true +CSET gth2_use_port_rxbufreset=true +CSET gth2_use_port_rxcodeerr=true +CSET gth2_use_port_rxctrl=true +CSET gth2_use_port_rxdisperr=false +CSET gth2_use_port_rxencommadet=false +CSET gth2_use_port_rxpolarity=false +CSET gth2_use_port_rxpowerdown=true +CSET gth2_use_port_rxslip=false +CSET gth2_use_port_rxvalid=false +CSET gth2_use_port_txbufreset=true +CSET gth2_use_port_txctrl=true +CSET gth2_use_port_txpowerdown=true +CSET gth3_datapath_width=64 +CSET gth3_encoding=10GbE_64B/66B +CSET gth3_line_rate=10.3125 +CSET gth3_postcursor_emphasis=0 +CSET gth3_precursor_emphasis=0 +CSET gth3_protocol_file=10GBASE-R +CSET gth3_rxeqmix=1000 +CSET gth3_tx_swing=800 +CSET gth3_use_dfetrainctrl=false +CSET gth3_use_lat_msr=false +CSET gth3_use_port_powerdown=true +CSET gth3_use_port_rxbufreset=true +CSET gth3_use_port_rxcodeerr=true +CSET gth3_use_port_rxctrl=true +CSET gth3_use_port_rxdisperr=false +CSET gth3_use_port_rxencommadet=false +CSET gth3_use_port_rxpolarity=false +CSET gth3_use_port_rxpowerdown=true +CSET gth3_use_port_rxslip=false +CSET gth3_use_port_rxvalid=false +CSET gth3_use_port_txbufreset=true +CSET gth3_use_port_txctrl=true +CSET gth3_use_port_txpowerdown=true +CSET gth_column=Right_Column_(X1) +CSET gthx4lane=false +CSET protocol_template=10GBASE-R +CSET refclk_x0y0=CLK_Y0 +CSET refclk_x0y1=CLK_Y1 +CSET refclk_x0y2=CLK_Y2 +CSET refclk_x1y0=CLK_Y0 +CSET refclk_x1y1=CLK_Y1 +CSET refclk_x1y2=CLK_Y2 +CSET reference_clock=156.25 +CSET target_line_rate=10.3125 +CSET use_gth0_x0y0=true +CSET use_gth0_x0y1=true +CSET use_gth0_x0y2=true +CSET use_gth0_x1y0=true +CSET use_gth0_x1y1=true +CSET use_gth0_x1y2=true +CSET use_gth1_x0y0=true +CSET use_gth1_x0y1=true +CSET use_gth1_x0y2=true +CSET use_gth1_x1y0=true +CSET use_gth1_x1y1=true +CSET use_gth1_x1y2=true +CSET use_gth2_x0y0=true +CSET use_gth2_x0y1=true +CSET use_gth2_x0y2=true +CSET use_gth2_x1y0=true +CSET use_gth2_x1y1=true +CSET use_gth2_x1y2=true +CSET use_gth3_x0y0=true +CSET use_gth3_x0y1=true +CSET use_gth3_x0y2=true +CSET use_gth3_x1y0=true +CSET use_gth3_x1y1=true +CSET use_gth3_x1y2=true +CSET use_gth_quad_x0y0=false +CSET use_gth_quad_x0y1=false +CSET use_gth_quad_x0y2=false +CSET use_gth_quad_x1y0=true +CSET use_gth_quad_x1y1=false +CSET use_gth_quad_x1y2=false +CSET use_no_rx=false +CSET use_no_tx=false +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-04-05T17:48:34Z +# END Extra information +GENERATE +# CRC: 75800c49 diff --git a/example/HXT100G/fpga/fpga.ucf b/example/HXT100G/fpga/fpga.ucf new file mode 100644 index 000000000..784dcb369 --- /dev/null +++ b/example/HXT100G/fpga/fpga.ucf @@ -0,0 +1,269 @@ +# User Constraints File for the HTG-V6HXT-100GIG FPGA board + +CONFIG PART = xc6vhx565t-2ff1923; + +# 50 MHz clock +NET "sys_clk" LOC = "AP33" | IOSTANDARD=LVCMOS25; # SYS_CLK, 50MHz +NET "sys_clk" TNM_NET = "sys_clk"; +TIMESPEC "TS_sys_clk" = PERIOD "sys_clk" 20.000 ns HIGH 50% INPUT_JITTER 200.0ps; + +# 156.25 MHz transceiver clock +NET "*txclk156" TNM_NET = "txclk156"; +TIMESPEC "TS_txclk156" = PERIOD "txclk156" 6400 ps; + +NET "*rx_clk_0" TNM_NET = "rx_clk"; +NET "*rx_clk_1" TNM_NET = "rx_clk"; +NET "*rx_clk_2" TNM_NET = "rx_clk"; +NET "*rx_clk_3" TNM_NET = "rx_clk"; +TIMESPEC "TS_rx_clk" = PERIOD "rx_clk" 6400 ps; + +# clock crossing constraints +TIMESPEC "TS_txclk156_to_sys_clk" = FROM "txclk156" TO "sys_clk" 10 ns; +TIMESPEC "TS_sys_clk_to_txclk156" = FROM "sys_clk" TO "txclk156" 10 ns; +TIMESPEC "TS_sys_clk_to_rx_clk" = FROM "sys_clk" TO "rx_clk" 10 ns; +TIMESPEC "TS_rx_clk_to_sys_clk" = FROM "rx_clk" TO "sys_clk" 10 ns; + +# PHY elastic buffer constraints +NET "*elastic_buffer_i*rd_truegray" MAXDELAY = 6.0 ns; +NET "*elastic_buffer_i?can_insert_wra" TIG; +NET "*wr_gray*" MAXDELAY = 6.0 ns; +NET "*rd_lastgray*" MAXDELAY = 6.0 ns; + +TIMESPEC "TS_txclk156_to_rx_clk" = FROM "txclk156" TO "rx_clk" 10 ns; +TIMESPEC "TS_rx_clk_to_txclk156" = FROM "rx_clk" TO "txclk156" 10 ns; + +# 200 MHz DDR3 clock +#NET "clk_ddr3_p" LOC = "AL13" | IOSTANDARD=LVDS_25; +#NET "clk_ddr3_n" LOC = "AL12" | IOSTANDARD=LVDS_25; +#NET "clk_ddr3_p" TNM_NET = "clk_ddr3"; +#TIMESPEC "TS_clk_ddr3" = PERIOD "clk_ddr3" 5.000 ns HIGH 50% INPUT_JITTER 20.0ps; + +# User clock +#NET "clk_usr_p" LOC = "J33" | IOSTANDARD=LVDS_25; +#NET "clk_usr_n" LOC = "H33" | IOSTANDARD=LVDS_25; +#NET "clk_usr_p" TNM_NET = "clk_usr"; +#TIMESPEC "TS_clk_usr" = PERIOD "clk_usr" 5.000 ns HIGH 50% INPUT_JITTER 20.0ps; + +# Button +NET "reset_n" LOC = "AY12" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (S7) + +# DIP switches +NET "sw<0>" LOC = "BB32" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (USER_SW0) +NET "sw<1>" LOC = "AT30" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (USER_SW1) + +# Jumpers +NET "jp<0>" LOC = "AW34" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO0, JP18) +NET "jp<1>" LOC = "AY35" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO1, JP19) +NET "jp<2>" LOC = "AW35" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO2, JP20) +NET "jp<3>" LOC = "AV33" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO3, JP21) + +# LEDs +NET "led<0>" LOC = "AY33" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D20) +NET "led<1>" LOC = "AW33" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D23) +NET "led<2>" LOC = "AK35" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D26) +NET "led<3>" LOC = "AL35" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D31) + +# Silicon Labs CP2102 +NET "uart_rst" LOC = "D10" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_suspend" LOC = "E12" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_ri" LOC = "B12" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_dcd" LOC = "C11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_dtr" LOC = "B11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_dsr" LOC = "D11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_rxd" LOC = "E11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # IO_L66N_SCP0 +NET "uart_txd" LOC = "B9" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # IO_L66P_SCP1 +NET "uart_rts" LOC = "A9" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_cts" LOC = "F12" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # + +# Clock muxes +NET "clk_gth_scl" LOC = "M11"; +NET "clk_gth_sda" LOC = "L10"; +NET "clk_gth_rst_n" LOC = "AR7"; +NET "clk_gthl_alm" LOC = "M34"; +NET "clk_gthr_alm" LOC = "R13"; +NET "clk_gthl_lol" LOC = "L34"; +NET "clk_gthr_lol" LOC = "L12"; + +# AirMax I/O +#NET "amh_right_io<0>" LOC="N33"; # AMH1R_IO0 J6.TX[12]_P mdc +#NET "amh_right_io<1>" LOC="J34"; # AMH1R_IO1 J6.TX[12]_N mdio +#NET "amh_right_io<2>" LOC="F34"; # AMH1R_IO2 J6.TX[13]_P +#NET "amh_right_io<3>" LOC="G34"; # AMH1R_IO3 J6.TX[13]_N +#NET "amh_right_io<4>" LOC="K33"; # AMH1R_IO4 J6.TX[14]_P +#NET "amh_right_io<5>" LOC="L33"; # AMH1R_IO5 J6.TX[14]_N +#NET "amh_right_io<6>" LOC="N34"; # AMH1R_IO6 J6.TX[15]_P +#NET "amh_right_io<7>" LOC="H34"; # AMH1R_IO7 J6.TX[15]_N reset_n + +#NET "amh_left_io<0>" LOC="E35"; # AMH1L_IO0 J3.TX[12]_P mdc +#NET "amh_left_io<1>" LOC="B37"; # AMH1L_IO1 J3.TX[12]_N mdio +#NET "amh_left_io<2>" LOC="A35"; # AMH1L_IO2 J3.TX[13]_P +#NET "amh_left_io<3>" LOC="B35"; # AMH1L_IO3 J3.TX[13]_N +#NET "amh_left_io<4>" LOC="G35"; # AMH1L_IO4 J3.TX[14]_P +#NET "amh_left_io<5>" LOC="F35"; # AMH1L_IO5 J3.TX[14]_N +#NET "amh_left_io<6>" LOC="A37"; # AMH1L_IO6 J3.TX[15]_P +#NET "amh_left_io<7>" LOC="B36"; # AMH1L_IO7 J3.TX[15]_N reset_n + +NET "amh_right_mdc" LOC="N33"; # AMH1R_IO0 J6.TX[12]_P mdc +NET "amh_right_mdio" LOC="J34"; # AMH1R_IO1 J6.TX[12]_N mdio +NET "amh_right_phy_rst_n" LOC="H34" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; + +NET "amh_left_mdc" LOC="E35"; # AMH1L_IO0 J3.TX[12]_P mdc +NET "amh_left_mdio" LOC="B37"; # AMH1L_IO1 J3.TX[12]_N mdio +NET "amh_left_phy_rst_n" LOC="B36" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; + +# 10G Ethernet interfaces +# Quad A X0Y0 +# Ports 11, 9, 10, 8 (right) +# SFP 0, 2, 4, 6 +NET "gth_quad_A_refclk_p" LOC = "R41"; +NET "gth_quad_A_refclk_n" LOC = "R42"; + +NET "gth_quad_A_txp_0" LOC = "T43"; +NET "gth_quad_A_txn_0" LOC = "T44"; +NET "gth_quad_A_rxp_0" LOC = "U41"; +NET "gth_quad_A_rxn_0" LOC = "U42"; + +NET "gth_quad_A_txp_1" LOC = "P43"; +NET "gth_quad_A_txn_1" LOC = "P44"; +NET "gth_quad_A_rxp_1" LOC = "T39"; +NET "gth_quad_A_rxn_1" LOC = "T40"; + +NET "gth_quad_A_txp_2" LOC = "M43"; +NET "gth_quad_A_txn_2" LOC = "M44"; +NET "gth_quad_A_rxp_2" LOC = "N37"; +NET "gth_quad_A_rxn_2" LOC = "N38"; + +NET "gth_quad_A_txp_3" LOC = "N41"; +NET "gth_quad_A_txn_3" LOC = "N42"; +NET "gth_quad_A_rxp_3" LOC = "M39"; +NET "gth_quad_A_rxn_3" LOC = "M40"; + +# Quad B X0Y1 +# Ports 4, 6, 5, 7 (right) +# SFP 3, 5, 1, 7 +NET "gth_quad_B_refclk_p" LOC = "J41"; +NET "gth_quad_B_refclk_n" LOC = "J42"; + +NET "gth_quad_B_txp_0" LOC = "L41"; +NET "gth_quad_B_txn_0" LOC = "L42"; +NET "gth_quad_B_rxp_0" LOC = "K39"; +NET "gth_quad_B_rxn_0" LOC = "K40"; + +NET "gth_quad_B_txp_1" LOC = "K43"; +NET "gth_quad_B_txn_1" LOC = "K44"; +NET "gth_quad_B_rxp_1" LOC = "L37"; +NET "gth_quad_B_rxn_1" LOC = "L38"; + +NET "gth_quad_B_txp_2" LOC = "G41"; +NET "gth_quad_B_txn_2" LOC = "G42"; +NET "gth_quad_B_rxp_2" LOC = "H39"; +NET "gth_quad_B_rxn_2" LOC = "H40"; + +NET "gth_quad_B_txp_3" LOC = "H43"; +NET "gth_quad_B_txn_3" LOC = "H44"; +NET "gth_quad_B_rxp_3" LOC = "J37"; +NET "gth_quad_B_rxn_3" LOC = "J38"; + +# Quad C X0Y2 +# Ports 1, 0, 3, 2 (right) +# SFP 8, 9, 11, 10 +NET "gth_quad_C_refclk_p" LOC = "E41"; +NET "gth_quad_C_refclk_n" LOC = "E42"; + +NET "gth_quad_C_txp_0" LOC = "F43"; +NET "gth_quad_C_txn_0" LOC = "F44"; +NET "gth_quad_C_rxp_0" LOC = "G37"; +NET "gth_quad_C_rxn_0" LOC = "G38"; + +NET "gth_quad_C_txp_1" LOC = "D43"; +NET "gth_quad_C_txn_1" LOC = "D44"; +NET "gth_quad_C_rxp_1" LOC = "F39"; +NET "gth_quad_C_rxn_1" LOC = "F40"; + +NET "gth_quad_C_txp_2" LOC = "A41"; +NET "gth_quad_C_txn_2" LOC = "A42"; +NET "gth_quad_C_rxp_2" LOC = "B39"; +NET "gth_quad_C_rxn_2" LOC = "B40"; + +NET "gth_quad_C_txp_3" LOC = "C41"; +NET "gth_quad_C_txn_3" LOC = "C42"; +NET "gth_quad_C_rxp_3" LOC = "D39"; +NET "gth_quad_C_rxn_3" LOC = "D40"; + +# Quad D X1Y0 +# Ports 11, 9, 10, 8 (left) +# SFP 0, 2, 4, 6 +NET "gth_quad_D_refclk_p" LOC = "R4"; +NET "gth_quad_D_refclk_n" LOC = "R3"; + +NET "gth_quad_D_txp_0" LOC = "T2"; +NET "gth_quad_D_txn_0" LOC = "T1"; +NET "gth_quad_D_rxp_0" LOC = "U4"; +NET "gth_quad_D_rxn_0" LOC = "U3"; + +NET "gth_quad_D_txp_1" LOC = "P2"; +NET "gth_quad_D_txn_1" LOC = "P1"; +NET "gth_quad_D_rxp_1" LOC = "T6"; +NET "gth_quad_D_rxn_1" LOC = "T5"; + +NET "gth_quad_D_txp_2" LOC = "M2"; +NET "gth_quad_D_txn_2" LOC = "M1"; +NET "gth_quad_D_rxp_2" LOC = "N8"; +NET "gth_quad_D_rxn_2" LOC = "N7"; + +NET "gth_quad_D_txp_3" LOC = "N4"; +NET "gth_quad_D_txn_3" LOC = "N3"; +NET "gth_quad_D_rxp_3" LOC = "M6"; +NET "gth_quad_D_rxn_3" LOC = "M5"; + +# Quad E X1Y1 +# Ports 4, 6, 5, 7 (left) +# SFP 3, 5, 1, 7 +NET "gth_quad_E_refclk_p" LOC = "J4"; +NET "gth_quad_E_refclk_n" LOC = "J3"; + +NET "gth_quad_E_txp_0" LOC = "L4"; +NET "gth_quad_E_txn_0" LOC = "L3"; +NET "gth_quad_E_rxp_0" LOC = "K6"; +NET "gth_quad_E_rxn_0" LOC = "K5"; + +NET "gth_quad_E_txp_1" LOC = "K2"; +NET "gth_quad_E_txn_1" LOC = "K1"; +NET "gth_quad_E_rxp_1" LOC = "L8"; +NET "gth_quad_E_rxn_1" LOC = "L7"; + +NET "gth_quad_E_txp_2" LOC = "G4"; +NET "gth_quad_E_txn_2" LOC = "G3"; +NET "gth_quad_E_rxp_2" LOC = "H6"; +NET "gth_quad_E_rxn_2" LOC = "H5"; + +NET "gth_quad_E_txp_3" LOC = "H2"; +NET "gth_quad_E_txn_3" LOC = "H1"; +NET "gth_quad_E_rxp_3" LOC = "J8"; +NET "gth_quad_E_rxn_3" LOC = "J7"; + +# Quad F X1Y2 +# Ports 1, 0, 3, 2 (left) +# SFP 8, 9, 11, 10 +NET "gth_quad_F_refclk_p" LOC = "E4"; +NET "gth_quad_F_refclk_n" LOC = "E3"; + +NET "gth_quad_F_txp_0" LOC = "F2"; +NET "gth_quad_F_txn_0" LOC = "F1"; +NET "gth_quad_F_rxp_0" LOC = "G8"; +NET "gth_quad_F_rxn_0" LOC = "G7"; + +NET "gth_quad_F_txp_1" LOC = "D2"; +NET "gth_quad_F_txn_1" LOC = "D1"; +NET "gth_quad_F_rxp_1" LOC = "F6"; +NET "gth_quad_F_rxn_1" LOC = "F5"; + +NET "gth_quad_F_txp_2" LOC = "A4"; +NET "gth_quad_F_txn_2" LOC = "A3"; +NET "gth_quad_F_rxp_2" LOC = "B6"; +NET "gth_quad_F_rxn_2" LOC = "B5"; + +NET "gth_quad_F_txp_3" LOC = "C4"; +NET "gth_quad_F_txn_3" LOC = "C3"; +NET "gth_quad_F_rxp_3" LOC = "D6"; +NET "gth_quad_F_rxn_3" LOC = "D5"; diff --git a/example/HXT100G/fpga/fpga/Makefile b/example/HXT100G/fpga/fpga/Makefile new file mode 100644 index 000000000..838b74dec --- /dev/null +++ b/example/HXT100G/fpga/fpga/Makefile @@ -0,0 +1,93 @@ + +# FPGA settings +FPGA_PART = xc6vhx565t-2ff1923 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/i2c_master.v +SYN_FILES += rtl/gth_i2c_init.v +SYN_FILES += rtl/eth_gth_phy_quad.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_crc_8.v +SYN_FILES += lib/eth/rtl/eth_crc_16.v +SYN_FILES += lib/eth/rtl/eth_crc_24.v +SYN_FILES += lib/eth/rtl/eth_crc_32.v +SYN_FILES += lib/eth/rtl/eth_crc_40.v +SYN_FILES += lib/eth/rtl/eth_crc_48.v +SYN_FILES += lib/eth/rtl/eth_crc_56.v +SYN_FILES += lib/eth/rtl/eth_crc_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_64_2.v +SYN_FILES += lib/eth/rtl/ip_mux_64_2.v +SYN_FILES += lib/eth/rtl/arp_64.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v +SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_64_2.v +SYN_FILES += lib/eth/rtl/eth_mux_64_2.v +SYN_FILES += lib/eth/rtl/xgmii_interleave.v +SYN_FILES += lib/eth/rtl/xgmii_deinterleave.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo_64.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6/example_design/ten_gig_eth_pcs_pma_v2_6_management_arbiter.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_quad.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_reset.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_init.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_tx_pcs_reset.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_rx_pcs_cdr_reset.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_pulse_synchronizer.v + +# UCF files +UCF_FILES = fpga.ucf + +# NGC paths for ngdbuild +NGC_PATHS = coregen/ten_gig_eth_pcs_pma_v2_6 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 1 -file $(FPGA_TOP).bit" >> program.cmd + echo "program -p 1" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + +program_flash: $(FPGA_TOP).mcs + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 1 -file $(FPGA_TOP).mcs" >> program.cmd + echo "program -p 1 -e" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + diff --git a/example/HXT100G/fpga/lib/eth b/example/HXT100G/fpga/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/HXT100G/fpga/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/HXT100G/fpga/rtl/debounce_switch.v b/example/HXT100G/fpga/rtl/debounce_switch.v new file mode 100644 index 000000000..e820eb416 --- /dev/null +++ b/example/HXT100G/fpga/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v b/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v new file mode 100644 index 000000000..be42ab256 --- /dev/null +++ b/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v @@ -0,0 +1,567 @@ +/* + +Copyright (c) 2015-2016 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. + +*/ + +module eth_gth_phy_quad ( + /* + * Clock and reset + */ + input wire clk156, + input wire rst156, + input wire dclk, + input wire dclk_reset, + + output wire txclk156, + + input wire gth_reset, + output wire gth_reset_done, + + /* + * Transciever pins + */ + input wire refclk_p, + input wire refclk_n, + output wire txp_0, + output wire txn_0, + input wire rxp_0, + input wire rxn_0, + output wire txp_1, + output wire txn_1, + input wire rxp_1, + input wire rxn_1, + output wire txp_2, + output wire txn_2, + input wire rxp_2, + input wire rxn_2, + output wire txp_3, + output wire txn_3, + input wire rxp_3, + input wire rxn_3, + + /* + * XGMII interfaces + */ + input wire [63:0] xgmii_txd_0, + input wire [7:0] xgmii_txc_0, + output wire [63:0] xgmii_rxd_0, + output wire [7:0] xgmii_rxc_0, + input wire [63:0] xgmii_txd_1, + input wire [7:0] xgmii_txc_1, + output wire [63:0] xgmii_rxd_1, + output wire [7:0] xgmii_rxc_1, + input wire [63:0] xgmii_txd_2, + input wire [7:0] xgmii_txc_2, + output wire [63:0] xgmii_rxd_2, + output wire [7:0] xgmii_rxc_2, + input wire [63:0] xgmii_txd_3, + input wire [7:0] xgmii_txc_3, + output wire [63:0] xgmii_rxd_3, + output wire [7:0] xgmii_rxc_3, + + /* + * Control + */ + input wire tx_powerdown_0, + input wire rx_powerdown_0, + input wire tx_powerdown_1, + input wire rx_powerdown_1, + input wire tx_powerdown_2, + input wire rx_powerdown_2, + input wire tx_powerdown_3, + input wire rx_powerdown_3 +); + +wire [63:0] gth_txd_0; +wire [7:0] gth_txc_0; +wire [63:0] gth_rxd_0; +wire [7:0] gth_rxc_0; +wire [63:0] gth_txd_1; +wire [7:0] gth_txc_1; +wire [63:0] gth_rxd_1; +wire [7:0] gth_rxc_1; +wire [63:0] gth_txd_2; +wire [7:0] gth_txc_2; +wire [63:0] gth_rxd_2; +wire [7:0] gth_rxc_2; +wire [63:0] gth_txd_3; +wire [7:0] gth_txc_3; +wire [63:0] gth_rxd_3; +wire [7:0] gth_rxc_3; + +wire mgmt_rd; +wire mgmt_wr; +wire mgmt_rdack; +wire [20:0] mgmt_addr; +wire [15:0] mgmt_rddata; +wire [15:0] mgmt_wrdata; + +wire mgmt_rd0; +wire mgmt_wr0; +wire [20:0] mgmt_addr0; +wire [15:0] mgmt_wrdata0; + +wire mgmt_req0; +wire mgmt_gnt0; + +wire mgmt_rd1; +wire mgmt_wr1; +wire [20:0] mgmt_addr1; +wire [15:0] mgmt_wrdata1; + +wire mgmt_req1; +wire mgmt_gnt1; + +wire mgmt_rd2; +wire mgmt_wr2; +wire [20:0] mgmt_addr2; +wire [15:0] mgmt_wrdata2; + +wire mgmt_req2; +wire mgmt_gnt2; + +wire mgmt_rd3; +wire mgmt_wr3; +wire [20:0] mgmt_addr3; +wire [15:0] mgmt_wrdata3; + +wire mgmt_req3; +wire mgmt_gnt3; + +// clocking +wire refclk; + +IBUFDS_GTHE1 refclk_ibufds_inst +( + .I(refclk_p), + .IB(refclk_n), + .O(refclk) +); + +wire rx_clk_0; +wire rx_clk_0_buf; +wire rx_clk_1; +wire rx_clk_1_buf; +wire rx_clk_2; +wire rx_clk_2_buf; +wire rx_clk_3; +wire rx_clk_3_buf; + +BUFR #( + .SIM_DEVICE("VIRTEX6") +) +rx_clk_0_buf_inst +( + .CE(1'b1), + .CLR(1'b0), + .I(rx_clk_0), + .O(rx_clk_0_buf) +); + +BUFR #( + .SIM_DEVICE("VIRTEX6") +) +rx_clk_1_buf_inst +( + .CE(1'b1), + .CLR(1'b0), + .I(rx_clk_1), + .O(rx_clk_1_buf) +); + +BUFG rx_clk_2_buf_inst +( + .I(rx_clk_2), + .O(rx_clk_2_buf) +); + +BUFG rx_clk_3_buf_inst +( + .I(rx_clk_3), + .O(rx_clk_3_buf) +); + +wire tx_resetdone_0; +wire rx_resetdone_0; +wire tx_resetdone_1; +wire rx_resetdone_1; +wire tx_resetdone_2; +wire rx_resetdone_2; +wire tx_resetdone_3; +wire rx_resetdone_3; + +wire resetdone_0 = tx_resetdone_0 & rx_resetdone_0; +wire resetdone_1 = tx_resetdone_1 & rx_resetdone_1; +wire resetdone_2 = tx_resetdone_2 & rx_resetdone_2; +wire resetdone_3 = tx_resetdone_3 & rx_resetdone_3; + +reg gth_reset_done_reg = 0; + +assign gth_reset_done = gth_reset_done_reg; + +// register overall reset done output +always @(posedge clk156) begin + gth_reset_done_reg <= resetdone_0 & resetdone_1 & resetdone_2 & resetdone_3; +end + +wire disable_drp = gth_reset_done & disable_drp_mgmt; + +wire lane_sel = {mgmt_gnt3, mgmt_gnt2, mgmt_gnt1, mgmt_gnt0}; + +// GTH quad wrapper +ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_QUAD # +( + // Simulation attributes + .QUAD_SIM_GTHRESET_SPEEDUP(0) +) +gth_inst +( + //------------------------------- Resetdone -------------------------------- + .TX_PCS_RESETDONE0_OUT (tx_resetdone_0), + .RX_PCS_CDR_RESETDONE0_OUT (rx_resetdone_0), + .TX_PCS_RESETDONE1_OUT (tx_resetdone_1), + .RX_PCS_CDR_RESETDONE1_OUT (rx_resetdone_1), + .TX_PCS_RESETDONE2_OUT (tx_resetdone_2), + .RX_PCS_CDR_RESETDONE2_OUT (rx_resetdone_2), + .TX_PCS_RESETDONE3_OUT (tx_resetdone_3), + .RX_PCS_CDR_RESETDONE3_OUT (rx_resetdone_3), + //------------------------------- Initdone --------------------------------- + .GTHINITDONE_OUT (), + //------------------------------- PCS Resets ------------------------------- + .TX_PCS_RESET0_IN (1'b0), + .RX_PCS_CDR_RESET0_IN (1'b0), + .TX_PCS_RESET1_IN (1'b0), + .RX_PCS_CDR_RESET1_IN (1'b0), + .TX_PCS_RESET2_IN (1'b0), + .RX_PCS_CDR_RESET2_IN (1'b0), + .TX_PCS_RESET3_IN (1'b0), + .RX_PCS_CDR_RESET3_IN (1'b0), + //------------------------------- Powerdown -------------------------------- + .POWERDOWN0_IN (1'b0), + .POWERDOWN1_IN (1'b0), + .POWERDOWN2_IN (1'b0), + .POWERDOWN3_IN (1'b0), + .RXPOWERDOWN0_IN ({rx_powerdown_0 | (~gth_reset_done), 1'b0}), + .RXPOWERDOWN1_IN ({rx_powerdown_1 | (~gth_reset_done), 1'b0}), + .RXPOWERDOWN2_IN ({rx_powerdown_2 | (~gth_reset_done), 1'b0}), + .RXPOWERDOWN3_IN ({rx_powerdown_3 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN0_IN ({tx_powerdown_0 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN1_IN ({tx_powerdown_1 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN2_IN ({tx_powerdown_2 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN3_IN ({tx_powerdown_3 | (~gth_reset_done), 1'b0}), + //----------------------------- Receive Ports ------------------------------ + .RXBUFRESET0_IN (1'b0), + .RXBUFRESET1_IN (1'b0), + .RXBUFRESET2_IN (1'b0), + .RXBUFRESET3_IN (1'b0), + .RXCODEERR0_OUT (), + .RXCODEERR1_OUT (), + .RXCODEERR2_OUT (), + .RXCODEERR3_OUT (), + .RXCTRL0_OUT (gth_rxc_0), + .RXCTRL1_OUT (gth_rxc_1), + .RXCTRL2_OUT (gth_rxc_2), + .RXCTRL3_OUT (gth_rxc_3), + .RXCTRLACK0_OUT (), + .RXCTRLACK1_OUT (), + .RXCTRLACK2_OUT (), + .RXCTRLACK3_OUT (), + .RXDATA0_OUT (gth_rxd_0), + .RXDATA1_OUT (gth_rxd_1), + .RXDATA2_OUT (gth_rxd_2), + .RXDATA3_OUT (gth_rxd_3), + .RXN0_IN (rxn_0), + .RXN1_IN (rxn_1), + .RXN2_IN (rxn_2), + .RXN3_IN (rxn_3), + .RXP0_IN (rxp_0), + .RXP1_IN (rxp_1), + .RXP2_IN (rxp_2), + .RXP3_IN (rxp_3), + .RXUSERCLKIN0_IN (rx_clk_0_buf), + .RXUSERCLKIN1_IN (rx_clk_1_buf), + .RXUSERCLKIN2_IN (rx_clk_2_buf), + .RXUSERCLKIN3_IN (rx_clk_3_buf), + .RXUSERCLKOUT0_OUT (rx_clk_0), + .RXUSERCLKOUT1_OUT (rx_clk_1), + .RXUSERCLKOUT2_OUT (rx_clk_2), + .RXUSERCLKOUT3_OUT (rx_clk_3), + //----------- Shared Ports - Dynamic Reconfiguration Port () ------------ + .DADDR_IN (16'h0000), + .DCLK_IN (dclk), + .DEN_IN (1'b0), + .DI_IN (16'h0000), + .DISABLEDRP_IN (disable_drp), + .DRDY_OUT (), + .DRPDO_OUT (), + .DWE_IN (1'b0), + //-------------------------- Shared Ports - Other -------------------------- + .TSTREFCLKFAB_OUT (), + .TSTREFCLKOUT_OUT (), + .GTHINIT_IN (1'b0), + .GTHRESET_IN (gth_reset), + .MGMTPCSLANESEL_IN (lane_sel), + .MGMTPCSMMDADDR_IN (mgmt_addr[20:16]), + .MGMTPCSRDACK_OUT (mgmt_rdack), + .MGMTPCSRDDATA_OUT (mgmt_rddata), + .MGMTPCSREGADDR_IN (mgmt_addr[15:0]), + .MGMTPCSREGRD_IN (mgmt_rd), + .MGMTPCSREGWR_IN (mgmt_wr), + .MGMTPCSWRDATA_IN (mgmt_wrdata), + .REFCLK_IN (refclk), + //----------------------------- Transmit Ports ----------------------------- + .TXBUFRESET0_IN (1'b0), + .TXBUFRESET1_IN (1'b0), + .TXBUFRESET2_IN (1'b0), + .TXBUFRESET3_IN (1'b0), + .TXCTRL0_IN (gth_txc_0), + .TXCTRL1_IN (gth_txc_1), + .TXCTRL2_IN (gth_txc_2), + .TXCTRL3_IN (gth_txc_3), + .TXCTRLACK0_OUT (), + .TXCTRLACK1_OUT (), + .TXCTRLACK2_OUT (), + .TXCTRLACK3_OUT (), + .TXDATA0_IN (gth_txd_0), + .TXDATA1_IN (gth_txd_1), + .TXDATA2_IN (gth_txd_2), + .TXDATA3_IN (gth_txd_3), + .TXN0_OUT (txn_0), + .TXN1_OUT (txn_1), + .TXN2_OUT (txn_2), + .TXN3_OUT (txn_3), + .TXP0_OUT (txp_0), + .TXP1_OUT (txp_1), + .TXP2_OUT (txp_2), + .TXP3_OUT (txp_3), + .TXUSERCLKIN0_IN (clk156), + .TXUSERCLKIN1_IN (clk156), + .TXUSERCLKIN2_IN (clk156), + .TXUSERCLKIN3_IN (clk156), + .TXUSERCLKOUT0_OUT (txclk156), + .TXUSERCLKOUT1_OUT (), + .TXUSERCLKOUT2_OUT (), + .TXUSERCLKOUT3_OUT () +); + +wire [535:0] configuration_vector; + +assign configuration_vector[14:1] = 0; +assign configuration_vector[79:17] = 0; +assign configuration_vector[109:84] = 0; +assign configuration_vector[175:170] = 0; +assign configuration_vector[239:234] = 0; +assign configuration_vector[269:246] = 0; +assign configuration_vector[511:272] = 0; +assign configuration_vector[515:513] = 0; +assign configuration_vector[517:517] = 0; +assign configuration_vector[0] = 0; // pma_loopback; +assign configuration_vector[15] = 0; // pma_reset; +assign configuration_vector[16] = 0; // global_tx_disable; +assign configuration_vector[83:80] = 0; // pma_vs_loopback; +assign configuration_vector[110] = 0; // pcs_loopback; +assign configuration_vector[111] = 0; // pcs_reset; +assign configuration_vector[169:112] = 0; // test_patt_a; +assign configuration_vector[233:176] = 0; // test_patt_b; +assign configuration_vector[240] = 0; // data_patt_sel; +assign configuration_vector[241] = 0; // test_patt_sel; +assign configuration_vector[242] = 0; // rx_test_patt_en; +assign configuration_vector[243] = 0; // tx_test_patt_en; +assign configuration_vector[244] = 0; // prbs31_tx_en; +assign configuration_vector[245] = 0; // prbs31_rx_en; +assign configuration_vector[271:270] = 0; // pcs_vs_loopback; +assign configuration_vector[512] = 0; // set_pma_link_status; +assign configuration_vector[516] = 0; // set_pcs_link_status; +assign configuration_vector[518] = 0; // clear_pcs_status2; +assign configuration_vector[519] = 0; // clear_test_patt_err_count; +assign configuration_vector[535:520] = 0; + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_0 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_0_buf), + .xgmii_txd(xgmii_txd_0), + .xgmii_txc(xgmii_txc_0), + .xgmii_rxd(xgmii_rxd_0), + .xgmii_rxc(xgmii_rxc_0), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req0), + .mgmt_gnt(mgmt_gnt0), + .mgmt_rd_out(mgmt_rd0), + .mgmt_wr_out(mgmt_wr0), + .mgmt_addr_out(mgmt_addr0), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata0), + .gt_txd(gth_txd_0), + .gt_txc(gth_txc_0), + .gt_rxd(gth_rxd_0), + .gt_rxc(gth_rxc_0), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_1 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_1_buf), + .xgmii_txd(xgmii_txd_1), + .xgmii_txc(xgmii_txc_1), + .xgmii_rxd(xgmii_rxd_1), + .xgmii_rxc(xgmii_rxc_1), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req1), + .mgmt_gnt(mgmt_gnt1), + .mgmt_rd_out(mgmt_rd1), + .mgmt_wr_out(mgmt_wr1), + .mgmt_addr_out(mgmt_addr1), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata1), + .gt_txd(gth_txd_1), + .gt_txc(gth_txc_1), + .gt_rxd(gth_rxd_1), + .gt_rxc(gth_rxc_1), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_2 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_2_buf), + .xgmii_txd(xgmii_txd_2), + .xgmii_txc(xgmii_txc_2), + .xgmii_rxd(xgmii_rxd_2), + .xgmii_rxc(xgmii_rxc_2), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req2), + .mgmt_gnt(mgmt_gnt2), + .mgmt_rd_out(mgmt_rd2), + .mgmt_wr_out(mgmt_wr2), + .mgmt_addr_out(mgmt_addr2), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata2), + .gt_txd(gth_txd_2), + .gt_txc(gth_txc_2), + .gt_rxd(gth_rxd_2), + .gt_rxc(gth_rxc_2), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_3 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_3_buf), + .xgmii_txd(xgmii_txd_3), + .xgmii_txc(xgmii_txc_3), + .xgmii_rxd(xgmii_rxd_3), + .xgmii_rxc(xgmii_rxc_3), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req3), + .mgmt_gnt(mgmt_gnt3), + .mgmt_rd_out(mgmt_rd3), + .mgmt_wr_out(mgmt_wr3), + .mgmt_addr_out(mgmt_addr3), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata3), + .gt_txd(gth_txd_3), + .gt_txc(gth_txc_3), + .gt_rxd(gth_rxd_3), + .gt_rxc(gth_rxc_3), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6_management_arbiter +mgmt_arb_inst +( + .dclk(dclk), + .reset(dclk_reset), + + .mgmt_rd0(mgmt_rd0), + .mgmt_wr0(mgmt_wr0), + .mgmt_addr0(mgmt_addr0), + .mgmt_wrdata0(mgmt_wrdata0), + + .mgmt_req0(mgmt_req0), + .mgmt_gnt0(mgmt_gnt0), + + .mgmt_rd1(mgmt_rd1), + .mgmt_wr1(mgmt_wr1), + .mgmt_addr1(mgmt_addr1), + .mgmt_wrdata1(mgmt_wrdata1), + + .mgmt_req1(mgmt_req1), + .mgmt_gnt1(mgmt_gnt1), + + .mgmt_rd2(mgmt_rd2), + .mgmt_wr2(mgmt_wr2), + .mgmt_addr2(mgmt_addr2), + .mgmt_wrdata2(mgmt_wrdata2), + + .mgmt_req2(mgmt_req2), + .mgmt_gnt2(mgmt_gnt2), + + .mgmt_rd3(mgmt_rd3), + .mgmt_wr3(mgmt_wr3), + .mgmt_addr3(mgmt_addr3), + .mgmt_wrdata3(mgmt_wrdata3), + + .mgmt_req3(mgmt_req3), + .mgmt_gnt3(mgmt_gnt3), + + .mgmt_rd(mgmt_rd), + .mgmt_wr(mgmt_wr), + .mgmt_addr(mgmt_addr), + .mgmt_wrdata(mgmt_wrdata), + + .drp_req(1'b0), + .drp_gnt(), + + .disable_drp(disable_drp_mgmt) +); + +endmodule diff --git a/example/HXT100G/fpga/rtl/fpga.v b/example/HXT100G/fpga/rtl/fpga.v new file mode 100644 index 000000000..159608c83 --- /dev/null +++ b/example/HXT100G/fpga/rtl/fpga.v @@ -0,0 +1,1059 @@ +/* + +Copyright (c) 2016 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. + +*/ + +module fpga ( + /* + * Clock: 50MHz + */ + input wire sys_clk, + /* + * Clock: 200MHz + */ + //input wire clk_ddr3_p, + //input wire clk_ddr3_n, + /* + * Clock: User + */ + //input wire clk_usr_p, + //input wire clk_usr_pr_n, + /* + * Reset: Push button, active low + */ + input wire reset_n, + /* + * GPIO + */ + input wire [1:0] sw, + input wire [3:0] jp, + output wire [3:0] led, + /* + * Silicon Labs CP2102 USB UART + */ + output wire uart_rst, + input wire uart_suspend, + output wire uart_ri, + output wire uart_dcd, + input wire uart_dtr, + output wire uart_dsr, + input wire uart_txd, + output wire uart_rxd, + input wire uart_rts, + output wire uart_cts, + /* + * Clock muxes + */ + inout wire clk_gth_scl, + inout wire clk_gth_sda, + output wire clk_gth_rst_n, + input wire clk_gthl_alm, + input wire clk_gthl_lol, + input wire clk_gthr_alm, + input wire clk_gthr_lol, + /* + * AirMax I/O + */ + output wire amh_right_mdc, + inout wire amh_right_mdio, + output wire amh_right_phy_rst_n, + output wire amh_left_mdc, + inout wire amh_left_mdio, + output wire amh_left_phy_rst_n, + /* + * 10G Ethernet + */ + input wire gth_quad_A_refclk_p, + input wire gth_quad_A_refclk_n, + output wire gth_quad_A_txp_0, + output wire gth_quad_A_txn_0, + input wire gth_quad_A_rxp_0, + input wire gth_quad_A_rxn_0, + output wire gth_quad_A_txp_1, + output wire gth_quad_A_txn_1, + input wire gth_quad_A_rxp_1, + input wire gth_quad_A_rxn_1, + output wire gth_quad_A_txp_2, + output wire gth_quad_A_txn_2, + input wire gth_quad_A_rxp_2, + input wire gth_quad_A_rxn_2, + output wire gth_quad_A_txp_3, + output wire gth_quad_A_txn_3, + input wire gth_quad_A_rxp_3, + input wire gth_quad_A_rxn_3, + input wire gth_quad_B_refclk_p, + input wire gth_quad_B_refclk_n, + output wire gth_quad_B_txp_0, + output wire gth_quad_B_txn_0, + input wire gth_quad_B_rxp_0, + input wire gth_quad_B_rxn_0, + output wire gth_quad_B_txp_1, + output wire gth_quad_B_txn_1, + input wire gth_quad_B_rxp_1, + input wire gth_quad_B_rxn_1, + output wire gth_quad_B_txp_2, + output wire gth_quad_B_txn_2, + input wire gth_quad_B_rxp_2, + input wire gth_quad_B_rxn_2, + output wire gth_quad_B_txp_3, + output wire gth_quad_B_txn_3, + input wire gth_quad_B_rxp_3, + input wire gth_quad_B_rxn_3, + input wire gth_quad_C_refclk_p, + input wire gth_quad_C_refclk_n, + output wire gth_quad_C_txp_0, + output wire gth_quad_C_txn_0, + input wire gth_quad_C_rxp_0, + input wire gth_quad_C_rxn_0, + output wire gth_quad_C_txp_1, + output wire gth_quad_C_txn_1, + input wire gth_quad_C_rxp_1, + input wire gth_quad_C_rxn_1, + output wire gth_quad_C_txp_2, + output wire gth_quad_C_txn_2, + input wire gth_quad_C_rxp_2, + input wire gth_quad_C_rxn_2, + output wire gth_quad_C_txp_3, + output wire gth_quad_C_txn_3, + input wire gth_quad_C_rxp_3, + input wire gth_quad_C_rxn_3, + input wire gth_quad_D_refclk_p, + input wire gth_quad_D_refclk_n, + output wire gth_quad_D_txp_0, + output wire gth_quad_D_txn_0, + input wire gth_quad_D_rxp_0, + input wire gth_quad_D_rxn_0, + output wire gth_quad_D_txp_1, + output wire gth_quad_D_txn_1, + input wire gth_quad_D_rxp_1, + input wire gth_quad_D_rxn_1, + output wire gth_quad_D_txp_2, + output wire gth_quad_D_txn_2, + input wire gth_quad_D_rxp_2, + input wire gth_quad_D_rxn_2, + output wire gth_quad_D_txp_3, + output wire gth_quad_D_txn_3, + input wire gth_quad_D_rxp_3, + input wire gth_quad_D_rxn_3, + input wire gth_quad_E_refclk_p, + input wire gth_quad_E_refclk_n, + output wire gth_quad_E_txp_0, + output wire gth_quad_E_txn_0, + input wire gth_quad_E_rxp_0, + input wire gth_quad_E_rxn_0, + output wire gth_quad_E_txp_1, + output wire gth_quad_E_txn_1, + input wire gth_quad_E_rxp_1, + input wire gth_quad_E_rxn_1, + output wire gth_quad_E_txp_2, + output wire gth_quad_E_txn_2, + input wire gth_quad_E_rxp_2, + input wire gth_quad_E_rxn_2, + output wire gth_quad_E_txp_3, + output wire gth_quad_E_txn_3, + input wire gth_quad_E_rxp_3, + input wire gth_quad_E_rxn_3, + input wire gth_quad_F_refclk_p, + input wire gth_quad_F_refclk_n, + output wire gth_quad_F_txp_0, + output wire gth_quad_F_txn_0, + input wire gth_quad_F_rxp_0, + input wire gth_quad_F_rxn_0, + output wire gth_quad_F_txp_1, + output wire gth_quad_F_txn_1, + input wire gth_quad_F_rxp_1, + input wire gth_quad_F_rxn_1, + output wire gth_quad_F_txp_2, + output wire gth_quad_F_txn_2, + input wire gth_quad_F_rxp_2, + input wire gth_quad_F_rxn_2, + output wire gth_quad_F_txp_3, + output wire gth_quad_F_txn_3, + input wire gth_quad_F_rxp_3, + input wire gth_quad_F_rxn_3 +); + +/* + * Clock: 50MHz + */ +wire sys_clk_ibufg; +wire sys_clk_int; + +/* + * Clock: 156.25 MHz + */ +wire clk_156mhz; + +/* + * Synchronous reset + */ +wire sys_rst; +wire rst_156mhz; + +/* + * GPIO + */ +wire [1:0] sw_int; +wire [3:0] jp_int; +wire [3:0] led_int; + +/* + * Silicon Labs CP2102 USB UART + */ +wire uart_sys_rst; +wire uart_suspend_int; +wire uart_ri_int; +wire uart_dcd_int; +wire uart_dtr_int; +wire uart_dsr_int; +wire uart_txd_int; +wire uart_rxd_int; +wire uart_rts_int; +wire uart_cts_int; + +/* + * Clock muxes + */ +wire clk_gth_scl_i; +wire clk_gth_scl_o; +wire clk_gth_scl_t; +wire clk_gth_sda_i; +wire clk_gth_sda_o; +wire clk_gth_sda_t; +wire clk_gthl_alm_int; +wire clk_gthl_lol_int; +wire clk_gthr_alm_int; +wire clk_gthr_lol_int; + +/* + * AirMax I/O + */ +wire amh_right_mdc_int; +wire amh_right_mdio_i_int; +wire amh_right_mdio_o_int; +wire amh_right_mdio_t_int; +wire amh_left_mdc_int; +wire amh_left_mdio_i_int; +wire amh_left_mdio_o_int; +wire amh_left_mdio_t_int; + +/* + * 10G Ethernet + */ +wire [63:0] eth_r0_txd; +wire [7:0] eth_r0_txc; +wire [63:0] eth_r0_rxd; +wire [7:0] eth_r0_rxc; +wire [63:0] eth_r1_txd; +wire [7:0] eth_r1_txc; +wire [63:0] eth_r1_rxd; +wire [7:0] eth_r1_rxc; +wire [63:0] eth_r2_txd; +wire [7:0] eth_r2_txc; +wire [63:0] eth_r2_rxd; +wire [7:0] eth_r2_rxc; +wire [63:0] eth_r3_txd; +wire [7:0] eth_r3_txc; +wire [63:0] eth_r3_rxd; +wire [7:0] eth_r3_rxc; +wire [63:0] eth_r4_txd; +wire [7:0] eth_r4_txc; +wire [63:0] eth_r4_rxd; +wire [7:0] eth_r4_rxc; +wire [63:0] eth_r5_txd; +wire [7:0] eth_r5_txc; +wire [63:0] eth_r5_rxd; +wire [7:0] eth_r5_rxc; +wire [63:0] eth_r6_txd; +wire [7:0] eth_r6_txc; +wire [63:0] eth_r6_rxd; +wire [7:0] eth_r6_rxc; +wire [63:0] eth_r7_txd; +wire [7:0] eth_r7_txc; +wire [63:0] eth_r7_rxd; +wire [7:0] eth_r7_rxc; +wire [63:0] eth_r8_txd; +wire [7:0] eth_r8_txc; +wire [63:0] eth_r8_rxd; +wire [7:0] eth_r8_rxc; +wire [63:0] eth_r9_txd; +wire [7:0] eth_r9_txc; +wire [63:0] eth_r9_rxd; +wire [7:0] eth_r9_rxc; +wire [63:0] eth_r10_txd; +wire [7:0] eth_r10_txc; +wire [63:0] eth_r10_rxd; +wire [7:0] eth_r10_rxc; +wire [63:0] eth_r11_txd; +wire [7:0] eth_r11_txc; +wire [63:0] eth_r11_rxd; +wire [7:0] eth_r11_rxc; +wire [63:0] eth_l0_txd; +wire [7:0] eth_l0_txc; +wire [63:0] eth_l0_rxd; +wire [7:0] eth_l0_rxc; +wire [63:0] eth_l1_txd; +wire [7:0] eth_l1_txc; +wire [63:0] eth_l1_rxd; +wire [7:0] eth_l1_rxc; +wire [63:0] eth_l2_txd; +wire [7:0] eth_l2_txc; +wire [63:0] eth_l2_rxd; +wire [7:0] eth_l2_rxc; +wire [63:0] eth_l3_txd; +wire [7:0] eth_l3_txc; +wire [63:0] eth_l3_rxd; +wire [7:0] eth_l3_rxc; +wire [63:0] eth_l4_txd; +wire [7:0] eth_l4_txc; +wire [63:0] eth_l4_rxd; +wire [7:0] eth_l4_rxc; +wire [63:0] eth_l5_txd; +wire [7:0] eth_l5_txc; +wire [63:0] eth_l5_rxd; +wire [7:0] eth_l5_rxc; +wire [63:0] eth_l6_txd; +wire [7:0] eth_l6_txc; +wire [63:0] eth_l6_rxd; +wire [7:0] eth_l6_rxc; +wire [63:0] eth_l7_txd; +wire [7:0] eth_l7_txc; +wire [63:0] eth_l7_rxd; +wire [7:0] eth_l7_rxc; +wire [63:0] eth_l8_txd; +wire [7:0] eth_l8_txc; +wire [63:0] eth_l8_rxd; +wire [7:0] eth_l8_rxc; +wire [63:0] eth_l9_txd; +wire [7:0] eth_l9_txc; +wire [63:0] eth_l9_rxd; +wire [7:0] eth_l9_rxc; +wire [63:0] eth_l10_txd; +wire [7:0] eth_l10_txc; +wire [63:0] eth_l10_rxd; +wire [7:0] eth_l10_rxc; +wire [63:0] eth_l11_txd; +wire [7:0] eth_l11_txc; +wire [63:0] eth_l11_rxd; +wire [7:0] eth_l11_rxc; + +// Clock buffering for 50 MHz sys_clk +IBUFG +sys_clk_ibufg_inst ( + .I(sys_clk), + .O(sys_clk_ibufg) +); + +BUFG +sys_clk_bufg_inst ( + .I(sys_clk_ibufg), + .O(sys_clk_int) +); + +// 156.25 MHz clock from GTH +wire txclk156; + +BUFG +clk156_bufg_inst ( + .I(txclk156), + .O(clk_156mhz) +); + +// Synchronize reset signal +sync_reset #( + .N(6) +) +sync_reset_inst ( + .clk(sys_clk_int), + .rst(~reset_n), + .sync_reset_out(sys_rst) +); + +sync_signal #( + .WIDTH(4), + .N(2) +) +sync_signal_50mhz_inst ( + .clk(sys_clk_int), + .in({clk_gthl_alm, + clk_gthl_lol, + clk_gthr_alm, + clk_gthr_lol}), + .out({clk_gthl_alm_int, + clk_gthl_lol_int, + clk_gthr_alm_int, + clk_gthr_lol_int}) +); + +sync_signal #( + .WIDTH(4), + .N(2) +) +sync_signal_156mhz_inst ( + .clk(clk_156mhz), + .in({uart_suspend, + uart_dtr, + uart_txd, + uart_rts}), + .out({uart_suspend_int, + uart_dtr_int, + uart_txd_int, + uart_rts_int}) +); + +// Debounce switch inputs +debounce_switch #( + .WIDTH(6), + .N(4), + .RATE(50000) +) +debounce_switch_inst ( + .clk(sys_clk_int), + .rst(sys_rst), + .in({sw, jp}), + .out({sw_int, jp_int}) +); + +// pass through outputs +assign led = led_int; + +assign uart_rst = uart_rst_int; +assign uart_ri = uart_ri_int; +assign uart_dcd = uart_dcd_int; +assign uart_dsr = uart_dsr_int; +assign uart_rxd = uart_rxd_int; +assign uart_cts = uart_cts_int; + +// clock mux I2C +assign clk_gth_scl_i = clk_gth_scl; +assign clk_gth_scl = clk_gth_scl_t ? 1'bz : clk_gth_scl_o; +assign clk_gth_sda_i = clk_gth_sda; +assign clk_gth_sda = clk_gth_sda_t ? 1'bz : clk_gth_sda_o; + +assign clk_gth_rst_n = ~sys_rst; + +wire [6:0] clk_gth_i2c_cmd_address; +wire clk_gth_i2c_cmd_start; +wire clk_gth_i2c_cmd_read; +wire clk_gth_i2c_cmd_write; +wire clk_gth_i2c_cmd_write_multiple; +wire clk_gth_i2c_cmd_stop; +wire clk_gth_i2c_cmd_valid; +wire clk_gth_i2c_cmd_ready; + +wire [7:0] clk_gth_i2c_data; +wire clk_gth_i2c_data_valid; +wire clk_gth_i2c_data_ready; +wire clk_gth_i2c_data_last; + +gth_i2c_init +clk_gth_i2c_init ( + .clk(sys_clk_int), + .rst(sys_rst), + .cmd_address(clk_gth_i2c_cmd_address), + .cmd_start(clk_gth_i2c_cmd_start), + .cmd_read(clk_gth_i2c_cmd_read), + .cmd_write(clk_gth_i2c_cmd_write), + .cmd_write_multiple(clk_gth_i2c_cmd_write_multiple), + .cmd_stop(clk_gth_i2c_cmd_stop), + .cmd_valid(clk_gth_i2c_cmd_valid), + .cmd_ready(clk_gth_i2c_cmd_ready), + .data_out(clk_gth_i2c_data), + .data_out_valid(clk_gth_i2c_data_valid), + .data_out_ready(clk_gth_i2c_data_ready), + .data_out_last(clk_gth_i2c_data_last), + .busy(), + .start(1) +); + +i2c_master +clk_gth_i2c_master ( + .clk(sys_clk_int), + .rst(sys_rst), + .cmd_address(clk_gth_i2c_cmd_address), + .cmd_start(clk_gth_i2c_cmd_start), + .cmd_read(clk_gth_i2c_cmd_read), + .cmd_write(clk_gth_i2c_cmd_write), + .cmd_write_multiple(clk_gth_i2c_cmd_write_multiple), + .cmd_stop(clk_gth_i2c_cmd_stop), + .cmd_valid(clk_gth_i2c_cmd_valid), + .cmd_ready(clk_gth_i2c_cmd_ready), + .data_in(clk_gth_i2c_data), + .data_in_valid(clk_gth_i2c_data_valid), + .data_in_ready(clk_gth_i2c_data_ready), + .data_in_last(clk_gth_i2c_data_last), + .data_out(), + .data_out_valid(), + .data_out_ready(1), + .data_out_last(), + .scl_i(clk_gth_scl_i), + .scl_o(clk_gth_scl_o), + .scl_t(clk_gth_scl_t), + .sda_i(clk_gth_sda_i), + .sda_o(clk_gth_sda_o), + .sda_t(clk_gth_sda_t), + .busy(), + .bus_control(), + .bus_active(), + .missed_ack(), + .prescale(312), + .stop_on_idle(1) +); + +// reset logic +wire gth_reset; + +wire gth_reset_done_A; +wire gth_reset_done_B; +wire gth_reset_done_C; +wire gth_reset_done_D; +wire gth_reset_done_E; +wire gth_reset_done_F; + +wire gth_reset_done = gth_reset_done_A & gth_reset_done_B & gth_reset_done_C & gth_reset_done_D & gth_reset_done_E & gth_reset_done_F; + +wire clk_gth_ready = ~clk_gthl_lol_int & ~clk_gthr_lol_int; + +sync_reset #( + .N(6) +) +sync_reset_gth_inst ( + .clk(sys_clk_int), + .rst(sys_rst | ~clk_gth_ready), + .sync_reset_out(gth_reset) +); + +sync_reset #( + .N(6) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz), + .rst(gth_reset | ~gth_reset_done), + .sync_reset_out(rst_156mhz) +); + +assign amh_right_phy_rst_n = ~rst_156mhz; +assign amh_left_phy_rst_n = ~rst_156mhz; + +// AirMax I/O + +assign amh_right_mdc = amh_right_mdc_int; + +assign amh_right_mdio_i_int = amh_right_mdio; +assign amh_right_mdio = amh_right_mdio_t_int ? 1'bz : amh_right_mdio_o_int; + +assign amh_left_mdc = amh_left_mdc_int; + +assign amh_left_mdio_i_int = amh_left_mdio; +assign amh_left_mdio = amh_left_mdio_t_int ? 1'bz : amh_left_mdio_o_int; + +// 10G Ethernet PCS/PMA + +// Quad A X0Y0 +eth_gth_phy_quad +eth_gth_phy_quad_A_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(txclk156), // pickoff one transmit clock for 156.25 MHz core clock + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_A), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_A_refclk_p), + .refclk_n(gth_quad_A_refclk_n), + .txn_0(gth_quad_A_txn_0), + .txp_0(gth_quad_A_txp_0), + .rxn_0(gth_quad_A_rxn_0), + .rxp_0(gth_quad_A_rxp_0), + .txn_1(gth_quad_A_txn_1), + .txp_1(gth_quad_A_txp_1), + .rxn_1(gth_quad_A_rxn_1), + .rxp_1(gth_quad_A_rxp_1), + .txn_2(gth_quad_A_txn_2), + .txp_2(gth_quad_A_txp_2), + .rxn_2(gth_quad_A_rxn_2), + .rxp_2(gth_quad_A_rxp_2), + .txn_3(gth_quad_A_txn_3), + .txp_3(gth_quad_A_txp_3), + .rxn_3(gth_quad_A_rxn_3), + .rxp_3(gth_quad_A_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_r0_txd), + .xgmii_txc_0(eth_r0_txc), + .xgmii_rxd_0(eth_r0_rxd), + .xgmii_rxc_0(eth_r0_rxc), + .xgmii_txd_1(eth_r2_txd), + .xgmii_txc_1(eth_r2_txc), + .xgmii_rxd_1(eth_r2_rxd), + .xgmii_rxc_1(eth_r2_rxc), + .xgmii_txd_2(eth_r4_txd), + .xgmii_txc_2(eth_r4_txc), + .xgmii_rxd_2(eth_r4_rxd), + .xgmii_rxc_2(eth_r4_rxc), + .xgmii_txd_3(eth_r6_txd), + .xgmii_txc_3(eth_r6_txc), + .xgmii_rxd_3(eth_r6_rxd), + .xgmii_rxc_3(eth_r6_rxc) +); + +// Quad B X0Y1 +eth_gth_phy_quad +eth_gth_phy_quad_B_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_B), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_B_refclk_p), + .refclk_n(gth_quad_B_refclk_n), + .txn_0(gth_quad_B_txn_0), + .txp_0(gth_quad_B_txp_0), + .rxn_0(gth_quad_B_rxn_0), + .rxp_0(gth_quad_B_rxp_0), + .txn_1(gth_quad_B_txn_1), + .txp_1(gth_quad_B_txp_1), + .rxn_1(gth_quad_B_rxn_1), + .rxp_1(gth_quad_B_rxp_1), + .txn_2(gth_quad_B_txn_2), + .txp_2(gth_quad_B_txp_2), + .rxn_2(gth_quad_B_rxn_2), + .rxp_2(gth_quad_B_rxp_2), + .txn_3(gth_quad_B_txn_3), + .txp_3(gth_quad_B_txp_3), + .rxn_3(gth_quad_B_rxn_3), + .rxp_3(gth_quad_B_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_r3_txd), + .xgmii_txc_0(eth_r3_txc), + .xgmii_rxd_0(eth_r3_rxd), + .xgmii_rxc_0(eth_r3_rxc), + .xgmii_txd_1(eth_r5_txd), + .xgmii_txc_1(eth_r5_txc), + .xgmii_rxd_1(eth_r5_rxd), + .xgmii_rxc_1(eth_r5_rxc), + .xgmii_txd_2(eth_r1_txd), + .xgmii_txc_2(eth_r1_txc), + .xgmii_rxd_2(eth_r1_rxd), + .xgmii_rxc_2(eth_r1_rxc), + .xgmii_txd_3(eth_r7_txd), + .xgmii_txc_3(eth_r7_txc), + .xgmii_rxd_3(eth_r7_rxd), + .xgmii_rxc_3(eth_r7_rxc) +); + +// Quad C X0Y2 +eth_gth_phy_quad +eth_gth_phy_quad_C_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_C), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_C_refclk_p), + .refclk_n(gth_quad_C_refclk_n), + .txn_0(gth_quad_C_txn_0), + .txp_0(gth_quad_C_txp_0), + .rxn_0(gth_quad_C_rxn_0), + .rxp_0(gth_quad_C_rxp_0), + .txn_1(gth_quad_C_txn_1), + .txp_1(gth_quad_C_txp_1), + .rxn_1(gth_quad_C_rxn_1), + .rxp_1(gth_quad_C_rxp_1), + .txn_2(gth_quad_C_txn_2), + .txp_2(gth_quad_C_txp_2), + .rxn_2(gth_quad_C_rxn_2), + .rxp_2(gth_quad_C_rxp_2), + .txn_3(gth_quad_C_txn_3), + .txp_3(gth_quad_C_txp_3), + .rxn_3(gth_quad_C_rxn_3), + .rxp_3(gth_quad_C_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_r8_txd), + .xgmii_txc_0(eth_r8_txc), + .xgmii_rxd_0(eth_r8_rxd), + .xgmii_rxc_0(eth_r8_rxc), + .xgmii_txd_1(eth_r9_txd), + .xgmii_txc_1(eth_r9_txc), + .xgmii_rxd_1(eth_r9_rxd), + .xgmii_rxc_1(eth_r9_rxc), + .xgmii_txd_2(eth_r11_txd), + .xgmii_txc_2(eth_r11_txc), + .xgmii_rxd_2(eth_r11_rxd), + .xgmii_rxc_2(eth_r11_rxc), + .xgmii_txd_3(eth_r10_txd), + .xgmii_txc_3(eth_r10_txc), + .xgmii_rxd_3(eth_r10_rxd), + .xgmii_rxc_3(eth_r10_rxc) +); + +// Quad D X1Y0 +eth_gth_phy_quad +eth_gth_phy_quad_D_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_D), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_D_refclk_p), + .refclk_n(gth_quad_D_refclk_n), + .txn_0(gth_quad_D_txn_0), + .txp_0(gth_quad_D_txp_0), + .rxn_0(gth_quad_D_rxn_0), + .rxp_0(gth_quad_D_rxp_0), + .txn_1(gth_quad_D_txn_1), + .txp_1(gth_quad_D_txp_1), + .rxn_1(gth_quad_D_rxn_1), + .rxp_1(gth_quad_D_rxp_1), + .txn_2(gth_quad_D_txn_2), + .txp_2(gth_quad_D_txp_2), + .rxn_2(gth_quad_D_rxn_2), + .rxp_2(gth_quad_D_rxp_2), + .txn_3(gth_quad_D_txn_3), + .txp_3(gth_quad_D_txp_3), + .rxn_3(gth_quad_D_rxn_3), + .rxp_3(gth_quad_D_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_l0_txd), + .xgmii_txc_0(eth_l0_txc), + .xgmii_rxd_0(eth_l0_rxd), + .xgmii_rxc_0(eth_l0_rxc), + .xgmii_txd_1(eth_l2_txd), + .xgmii_txc_1(eth_l2_txc), + .xgmii_rxd_1(eth_l2_rxd), + .xgmii_rxc_1(eth_l2_rxc), + .xgmii_txd_2(eth_l4_txd), + .xgmii_txc_2(eth_l4_txc), + .xgmii_rxd_2(eth_l4_rxd), + .xgmii_rxc_2(eth_l4_rxc), + .xgmii_txd_3(eth_l6_txd), + .xgmii_txc_3(eth_l6_txc), + .xgmii_rxd_3(eth_l6_rxd), + .xgmii_rxc_3(eth_l6_rxc) +); + +// Quad E X1Y1 +eth_gth_phy_quad +eth_gth_phy_quad_E_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_E), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_E_refclk_p), + .refclk_n(gth_quad_E_refclk_n), + .txn_0(gth_quad_E_txn_0), + .txp_0(gth_quad_E_txp_0), + .rxn_0(gth_quad_E_rxn_0), + .rxp_0(gth_quad_E_rxp_0), + .txn_1(gth_quad_E_txn_1), + .txp_1(gth_quad_E_txp_1), + .rxn_1(gth_quad_E_rxn_1), + .rxp_1(gth_quad_E_rxp_1), + .txn_2(gth_quad_E_txn_2), + .txp_2(gth_quad_E_txp_2), + .rxn_2(gth_quad_E_rxn_2), + .rxp_2(gth_quad_E_rxp_2), + .txn_3(gth_quad_E_txn_3), + .txp_3(gth_quad_E_txp_3), + .rxn_3(gth_quad_E_rxn_3), + .rxp_3(gth_quad_E_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_l3_txd), + .xgmii_txc_0(eth_l3_txc), + .xgmii_rxd_0(eth_l3_rxd), + .xgmii_rxc_0(eth_l3_rxc), + .xgmii_txd_1(eth_l5_txd), + .xgmii_txc_1(eth_l5_txc), + .xgmii_rxd_1(eth_l5_rxd), + .xgmii_rxc_1(eth_l5_rxc), + .xgmii_txd_2(eth_l1_txd), + .xgmii_txc_2(eth_l1_txc), + .xgmii_rxd_2(eth_l1_rxd), + .xgmii_rxc_2(eth_l1_rxc), + .xgmii_txd_3(eth_l7_txd), + .xgmii_txc_3(eth_l7_txc), + .xgmii_rxd_3(eth_l7_rxd), + .xgmii_rxc_3(eth_l7_rxc) +); + +// Quad F X1Y2 +eth_gth_phy_quad +eth_gth_phy_quad_F_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_F), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_F_refclk_p), + .refclk_n(gth_quad_F_refclk_n), + .txn_0(gth_quad_F_txn_0), + .txp_0(gth_quad_F_txp_0), + .rxn_0(gth_quad_F_rxn_0), + .rxp_0(gth_quad_F_rxp_0), + .txn_1(gth_quad_F_txn_1), + .txp_1(gth_quad_F_txp_1), + .rxn_1(gth_quad_F_rxn_1), + .rxp_1(gth_quad_F_rxp_1), + .txn_2(gth_quad_F_txn_2), + .txp_2(gth_quad_F_txp_2), + .rxn_2(gth_quad_F_rxn_2), + .rxp_2(gth_quad_F_rxp_2), + .txn_3(gth_quad_F_txn_3), + .txp_3(gth_quad_F_txp_3), + .rxn_3(gth_quad_F_rxn_3), + .rxp_3(gth_quad_F_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_l8_txd), + .xgmii_txc_0(eth_l8_txc), + .xgmii_rxd_0(eth_l8_rxd), + .xgmii_rxc_0(eth_l8_rxc), + .xgmii_txd_1(eth_l9_txd), + .xgmii_txc_1(eth_l9_txc), + .xgmii_rxd_1(eth_l9_rxd), + .xgmii_rxc_1(eth_l9_rxc), + .xgmii_txd_2(eth_l11_txd), + .xgmii_txc_2(eth_l11_txc), + .xgmii_rxd_2(eth_l11_rxd), + .xgmii_rxc_2(eth_l11_rxc), + .xgmii_txd_3(eth_l10_txd), + .xgmii_txc_3(eth_l10_txc), + .xgmii_rxd_3(eth_l10_rxd), + .xgmii_rxc_3(eth_l10_rxc) +); + + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz), + .rst(rst_156mhz), + /* + * GPIO + */ + .sw(sw_int), + .jp(jp_int), + .led(led_int), + /* + * Silicon Labs CP2102 USB UART + */ + .uart_rst(uart_rst_int), + .uart_suspend(uart_suspend_int), + .uart_ri(uart_ri_int), + .uart_dcd(uart_dcd_int), + .uart_dtr(uart_dtr_int), + .uart_dsr(uart_dsr_int), + .uart_txd(uart_txd_int), + .uart_rxd(uart_rxd_int), + .uart_rts(uart_rts_int), + .uart_cts(uart_cts_int), + /* + * AirMax I/O + */ + .amh_right_mdc(amh_right_mdc_int), + .amh_right_mdio_i(amh_right_mdio_i_int), + .amh_right_mdio_o(amh_right_mdio_o_int), + .amh_right_mdio_t(amh_right_mdio_t_int), + .amh_left_mdc(amh_left_mdc_int), + .amh_left_mdio_i(amh_left_mdio_i_int), + .amh_left_mdio_o(amh_left_mdio_o_int), + .amh_left_mdio_t(amh_left_mdio_t_int), + /* + * 10G Ethernet XGMII + */ + .eth_r0_txd(eth_r0_txd), + .eth_r0_txc(eth_r0_txc), + .eth_r0_rxd(eth_r0_rxd), + .eth_r0_rxc(eth_r0_rxc), + .eth_r1_txd(eth_r1_txd), + .eth_r1_txc(eth_r1_txc), + .eth_r1_rxd(eth_r1_rxd), + .eth_r1_rxc(eth_r1_rxc), + .eth_r2_txd(eth_r2_txd), + .eth_r2_txc(eth_r2_txc), + .eth_r2_rxd(eth_r2_rxd), + .eth_r2_rxc(eth_r2_rxc), + .eth_r3_txd(eth_r3_txd), + .eth_r3_txc(eth_r3_txc), + .eth_r3_rxd(eth_r3_rxd), + .eth_r3_rxc(eth_r3_rxc), + .eth_r4_txd(eth_r4_txd), + .eth_r4_txc(eth_r4_txc), + .eth_r4_rxd(eth_r4_rxd), + .eth_r4_rxc(eth_r4_rxc), + .eth_r5_txd(eth_r5_txd), + .eth_r5_txc(eth_r5_txc), + .eth_r5_rxd(eth_r5_rxd), + .eth_r5_rxc(eth_r5_rxc), + .eth_r6_txd(eth_r6_txd), + .eth_r6_txc(eth_r6_txc), + .eth_r6_rxd(eth_r6_rxd), + .eth_r6_rxc(eth_r6_rxc), + .eth_r7_txd(eth_r7_txd), + .eth_r7_txc(eth_r7_txc), + .eth_r7_rxd(eth_r7_rxd), + .eth_r7_rxc(eth_r7_rxc), + .eth_r8_txd(eth_r8_txd), + .eth_r8_txc(eth_r8_txc), + .eth_r8_rxd(eth_r8_rxd), + .eth_r8_rxc(eth_r8_rxc), + .eth_r9_txd(eth_r9_txd), + .eth_r9_txc(eth_r9_txc), + .eth_r9_rxd(eth_r9_rxd), + .eth_r9_rxc(eth_r9_rxc), + .eth_r10_txd(eth_r10_txd), + .eth_r10_txc(eth_r10_txc), + .eth_r10_rxd(eth_r10_rxd), + .eth_r10_rxc(eth_r10_rxc), + .eth_r11_txd(eth_r11_txd), + .eth_r11_txc(eth_r11_txc), + .eth_r11_rxd(eth_r11_rxd), + .eth_r11_rxc(eth_r11_rxc), + .eth_l0_txd(eth_l0_txd), + .eth_l0_txc(eth_l0_txc), + .eth_l0_rxd(eth_l0_rxd), + .eth_l0_rxc(eth_l0_rxc), + .eth_l1_txd(eth_l1_txd), + .eth_l1_txc(eth_l1_txc), + .eth_l1_rxd(eth_l1_rxd), + .eth_l1_rxc(eth_l1_rxc), + .eth_l2_txd(eth_l2_txd), + .eth_l2_txc(eth_l2_txc), + .eth_l2_rxd(eth_l2_rxd), + .eth_l2_rxc(eth_l2_rxc), + .eth_l3_txd(eth_l3_txd), + .eth_l3_txc(eth_l3_txc), + .eth_l3_rxd(eth_l3_rxd), + .eth_l3_rxc(eth_l3_rxc), + .eth_l4_txd(eth_l4_txd), + .eth_l4_txc(eth_l4_txc), + .eth_l4_rxd(eth_l4_rxd), + .eth_l4_rxc(eth_l4_rxc), + .eth_l5_txd(eth_l5_txd), + .eth_l5_txc(eth_l5_txc), + .eth_l5_rxd(eth_l5_rxd), + .eth_l5_rxc(eth_l5_rxc), + .eth_l6_txd(eth_l6_txd), + .eth_l6_txc(eth_l6_txc), + .eth_l6_rxd(eth_l6_rxd), + .eth_l6_rxc(eth_l6_rxc), + .eth_l7_txd(eth_l7_txd), + .eth_l7_txc(eth_l7_txc), + .eth_l7_rxd(eth_l7_rxd), + .eth_l7_rxc(eth_l7_rxc), + .eth_l8_txd(eth_l8_txd), + .eth_l8_txc(eth_l8_txc), + .eth_l8_rxd(eth_l8_rxd), + .eth_l8_rxc(eth_l8_rxc), + .eth_l9_txd(eth_l9_txd), + .eth_l9_txc(eth_l9_txc), + .eth_l9_rxd(eth_l9_rxd), + .eth_l9_rxc(eth_l9_rxc), + .eth_l10_txd(eth_l10_txd), + .eth_l10_txc(eth_l10_txc), + .eth_l10_rxd(eth_l10_rxd), + .eth_l10_rxc(eth_l10_rxc), + .eth_l11_txd(eth_l11_txd), + .eth_l11_txc(eth_l11_txc), + .eth_l11_rxd(eth_l11_rxd), + .eth_l11_rxc(eth_l11_rxc) +); + +endmodule diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..232fc9c1c --- /dev/null +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -0,0 +1,733 @@ +/* + +Copyright (c) 2016 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 fpga_core +( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + /* + * GPIO + */ + input wire [1:0] sw, + input wire [3:0] jp, + output wire [3:0] led, + /* + * Silicon Labs CP2102 USB UART + */ + output wire uart_rst, + input wire uart_suspend, + output wire uart_ri, + output wire uart_dcd, + input wire uart_dtr, + output wire uart_dsr, + input wire uart_txd, + output wire uart_rxd, + input wire uart_rts, + output wire uart_cts, + /* + * AirMax I/O + */ + output wire amh_right_mdc, + input wire amh_right_mdio_i, + output wire amh_right_mdio_o, + output wire amh_right_mdio_t, + output wire amh_left_mdc, + input wire amh_left_mdio_i, + output wire amh_left_mdio_o, + output wire amh_left_mdio_t, + /* + * 10G Ethernet + */ + output wire [63:0] eth_r0_txd, + output wire [7:0] eth_r0_txc, + input wire [63:0] eth_r0_rxd, + input wire [7:0] eth_r0_rxc, + output wire [63:0] eth_r1_txd, + output wire [7:0] eth_r1_txc, + input wire [63:0] eth_r1_rxd, + input wire [7:0] eth_r1_rxc, + output wire [63:0] eth_r2_txd, + output wire [7:0] eth_r2_txc, + input wire [63:0] eth_r2_rxd, + input wire [7:0] eth_r2_rxc, + output wire [63:0] eth_r3_txd, + output wire [7:0] eth_r3_txc, + input wire [63:0] eth_r3_rxd, + input wire [7:0] eth_r3_rxc, + output wire [63:0] eth_r4_txd, + output wire [7:0] eth_r4_txc, + input wire [63:0] eth_r4_rxd, + input wire [7:0] eth_r4_rxc, + output wire [63:0] eth_r5_txd, + output wire [7:0] eth_r5_txc, + input wire [63:0] eth_r5_rxd, + input wire [7:0] eth_r5_rxc, + output wire [63:0] eth_r6_txd, + output wire [7:0] eth_r6_txc, + input wire [63:0] eth_r6_rxd, + input wire [7:0] eth_r6_rxc, + output wire [63:0] eth_r7_txd, + output wire [7:0] eth_r7_txc, + input wire [63:0] eth_r7_rxd, + input wire [7:0] eth_r7_rxc, + output wire [63:0] eth_r8_txd, + output wire [7:0] eth_r8_txc, + input wire [63:0] eth_r8_rxd, + input wire [7:0] eth_r8_rxc, + output wire [63:0] eth_r9_txd, + output wire [7:0] eth_r9_txc, + input wire [63:0] eth_r9_rxd, + input wire [7:0] eth_r9_rxc, + output wire [63:0] eth_r10_txd, + output wire [7:0] eth_r10_txc, + input wire [63:0] eth_r10_rxd, + input wire [7:0] eth_r10_rxc, + output wire [63:0] eth_r11_txd, + output wire [7:0] eth_r11_txc, + input wire [63:0] eth_r11_rxd, + input wire [7:0] eth_r11_rxc, + output wire [63:0] eth_l0_txd, + output wire [7:0] eth_l0_txc, + input wire [63:0] eth_l0_rxd, + input wire [7:0] eth_l0_rxc, + output wire [63:0] eth_l1_txd, + output wire [7:0] eth_l1_txc, + input wire [63:0] eth_l1_rxd, + input wire [7:0] eth_l1_rxc, + output wire [63:0] eth_l2_txd, + output wire [7:0] eth_l2_txc, + input wire [63:0] eth_l2_rxd, + input wire [7:0] eth_l2_rxc, + output wire [63:0] eth_l3_txd, + output wire [7:0] eth_l3_txc, + input wire [63:0] eth_l3_rxd, + input wire [7:0] eth_l3_rxc, + output wire [63:0] eth_l4_txd, + output wire [7:0] eth_l4_txc, + input wire [63:0] eth_l4_rxd, + input wire [7:0] eth_l4_rxc, + output wire [63:0] eth_l5_txd, + output wire [7:0] eth_l5_txc, + input wire [63:0] eth_l5_rxd, + input wire [7:0] eth_l5_rxc, + output wire [63:0] eth_l6_txd, + output wire [7:0] eth_l6_txc, + input wire [63:0] eth_l6_rxd, + input wire [7:0] eth_l6_rxc, + output wire [63:0] eth_l7_txd, + output wire [7:0] eth_l7_txc, + input wire [63:0] eth_l7_rxd, + input wire [7:0] eth_l7_rxc, + output wire [63:0] eth_l8_txd, + output wire [7:0] eth_l8_txc, + input wire [63:0] eth_l8_rxd, + input wire [7:0] eth_l8_rxc, + output wire [63:0] eth_l9_txd, + output wire [7:0] eth_l9_txc, + input wire [63:0] eth_l9_rxd, + input wire [7:0] eth_l9_rxc, + output wire [63:0] eth_l10_txd, + output wire [7:0] eth_l10_txc, + input wire [63:0] eth_l10_rxd, + input wire [7:0] eth_l10_rxc, + output wire [63:0] eth_l11_txd, + output wire [7:0] eth_l11_txc, + input wire [63:0] eth_l11_rxd, + input wire [7:0] eth_l11_rxc +); + +// UART +assign uart_rst = 1'b1; +assign uart_txd = 1'b1; + +// AirMax I/O +assign amh_right_mdc = 1'b1; +assign amh_right_mdio_o = 1'b1; +assign amh_right_mdio_t = 1'b1; +assign amh_left_mdc = 1'b1; +assign amh_left_mdio_o = 1'b1; +assign amh_left_mdio_t = 1'b1; + +// AXI between MAC and Ethernet modules +wire [63:0] rx_axis_tdata; +wire [7:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [63:0] tx_axis_tdata; +wire [7:0] tx_axis_tkeep; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [63:0] rx_eth_payload_tdata; +wire [7:0] rx_eth_payload_tkeep; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [63:0] tx_eth_payload_tdata; +wire [7:0] tx_eth_payload_tkeep; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [63:0] rx_ip_payload_tdata; +wire [7:0] rx_ip_payload_tkeep; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [63:0] tx_ip_payload_tdata; +wire [7:0] tx_ip_payload_tkeep; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [63:0] rx_udp_payload_tdata; +wire [7:0] rx_udp_payload_tkeep; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [63:0] tx_udp_payload_tdata; +wire [7:0] tx_udp_payload_tkeep; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [63:0] rx_fifo_udp_payload_tdata; +wire [7:0] rx_fifo_udp_payload_tkeep; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [63:0] tx_fifo_udp_payload_tdata; +wire [7:0] tx_fifo_udp_payload_tkeep; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tkeep = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tkeep = rx_udp_payload_tkeep; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tkeep = tx_fifo_udp_payload_tkeep; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tkeep = rx_udp_payload_tkeep; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_tvalid; + if (tx_udp_payload_tvalid & ~valid_last) begin + led_reg <= tx_udp_payload_tdata; + end + end +end + +//assign led = sw; +assign led = led_reg; + +assign eth_r0_txd = 64'h0707070707070707; +assign eth_r0_txc = 8'hff; +assign eth_r1_txd = 64'h0707070707070707; +assign eth_r1_txc = 8'hff; +assign eth_r2_txd = 64'h0707070707070707; +assign eth_r2_txc = 8'hff; +assign eth_r3_txd = 64'h0707070707070707; +assign eth_r3_txc = 8'hff; +assign eth_r4_txd = 64'h0707070707070707; +assign eth_r4_txc = 8'hff; +assign eth_r5_txd = 64'h0707070707070707; +assign eth_r5_txc = 8'hff; +assign eth_r6_txd = 64'h0707070707070707; +assign eth_r6_txc = 8'hff; +assign eth_r7_txd = 64'h0707070707070707; +assign eth_r7_txc = 8'hff; +assign eth_r8_txd = 64'h0707070707070707; +assign eth_r8_txc = 8'hff; +assign eth_r9_txd = 64'h0707070707070707; +assign eth_r9_txc = 8'hff; +assign eth_r10_txd = 64'h0707070707070707; +assign eth_r10_txc = 8'hff; +assign eth_r11_txd = 64'h0707070707070707; +assign eth_r11_txc = 8'hff; + +//assign eth_l0_txd = 64'h0707070707070707; +//assign eth_l0_txc = 8'hff; +assign eth_l1_txd = 64'h0707070707070707; +assign eth_l1_txc = 8'hff; +assign eth_l2_txd = 64'h0707070707070707; +assign eth_l2_txc = 8'hff; +assign eth_l3_txd = 64'h0707070707070707; +assign eth_l3_txc = 8'hff; +assign eth_l4_txd = 64'h0707070707070707; +assign eth_l4_txc = 8'hff; +assign eth_l5_txd = 64'h0707070707070707; +assign eth_l5_txc = 8'hff; +assign eth_l6_txd = 64'h0707070707070707; +assign eth_l6_txc = 8'hff; +assign eth_l7_txd = 64'h0707070707070707; +assign eth_l7_txc = 8'hff; +assign eth_l8_txd = 64'h0707070707070707; +assign eth_l8_txc = 8'hff; +assign eth_l9_txd = 64'h0707070707070707; +assign eth_l9_txc = 8'hff; +assign eth_l10_txd = 64'h0707070707070707; +assign eth_l10_txc = 8'hff; +assign eth_l11_txd = 64'h0707070707070707; +assign eth_l11_txc = 8'hff; + +eth_mac_10g_fifo #( + .ENABLE_PADDING(1), + .ENABLE_DIC(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(9), + .RX_FIFO_ADDR_WIDTH(9) +) +eth_mac_10g_fifo_inst ( + .rx_clk(clk), + .rx_rst(rst), + .tx_clk(clk), + .tx_rst(rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .xgmii_rxd(eth_l0_rxd), + .xgmii_rxc(eth_l0_rxc), + .xgmii_txd(eth_l0_txd), + .xgmii_txc(eth_l0_txc), + + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + + .ifg_delay(8'd12) +); + +eth_axis_rx_64 +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tkeep(rx_axis_tkeep), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tkeep(rx_eth_payload_tkeep), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx_64 +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tkeep(tx_eth_payload_tkeep), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tkeep(tx_axis_tkeep), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete_64 #( + .UDP_CHECKSUM_ENABLE(0) +) +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tkeep(rx_eth_payload_tkeep), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tkeep(tx_eth_payload_tkeep), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tkeep(tx_ip_payload_tkeep), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tkeep(rx_ip_payload_tkeep), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tkeep(tx_udp_payload_tkeep), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tkeep(rx_udp_payload_tkeep), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(1'b0) +); + +axis_fifo_64 #( + .ADDR_WIDTH(10), + .DATA_WIDTH(64) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(rx_fifo_udp_payload_tkeep), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(tx_fifo_udp_payload_tkeep), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/HXT100G/fpga/rtl/gth_i2c_init.v b/example/HXT100G/fpga/rtl/gth_i2c_init.v new file mode 100644 index 000000000..c92e2136c --- /dev/null +++ b/example/HXT100G/fpga/rtl/gth_i2c_init.v @@ -0,0 +1,508 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * gth_i2c_init + */ +module gth_i2c_init ( + input wire clk, + input wire rst, + + /* + * I2C master interface + */ + output wire [6:0] cmd_address, + output wire cmd_start, + output wire cmd_read, + output wire cmd_write, + output wire cmd_write_multiple, + output wire cmd_stop, + output wire cmd_valid, + input wire cmd_ready, + + output wire [7:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + output wire data_out_last, + + /* + * Status + */ + output wire busy, + + /* + * Configuration + */ + input wire start +); + +/* + +Generic module for I2C bus initialization. Good for use when multiple devices +on an I2C bus must be initialized on system start without intervention of a +general-purpose processor. + +Copy this file and change init_data and INIT_DATA_LEN as needed. + +This module can be used in two modes: simple device initalization, or multiple +device initialization. In multiple device mode, the same initialization sequence +can be performed on multiple different device addresses. + +To use single device mode, only use the start write to address and write data commands. +The module will generate the I2C commands in sequential order. Terminate the list +with a 0 entry. + +To use the multiple device mode, use the start data and start address block commands +to set up lists of initialization data and device addresses. The module enters +multiple device mode upon seeing a start data block command. The module stores the +offset of the start of the data block and then skips ahead until it reaches a start +address block command. The module will store the offset to the address block and +read the first address in the block. Then it will jump back to the data block +and execute it, substituting the stored address for each current address write +command. Upon reaching the start address block command, the module will read out the +next address and start again at the top of the data block. If the module encounters +a start data block command while looking for an address, then it will store a new data +offset and then look for a start address block command. Terminate the list with a 0 +entry. Normal address commands will operate normally inside a data block. + +Commands: + +00 0000000 : stop +00 0000001 : exit multiple device mode +00 0000011 : start write to current address +00 0001000 : start address block +00 0001001 : start data block +01 aaaaaaa : start write to address +1 dddddddd : write 8-bit data + +Examples + +write 0x11223344 to register 0x0004 on device at 0x50 + +01 1010000 start write to 0x50 +1 00000000 write address 0x0004 +1 00000100 +1 00010001 write data 0x11223344 +1 00100010 +1 00110011 +1 01000100 +0 00000000 stop + +write 0x11223344 to register 0x0004 on devices at 0x50, 0x51, 0x52, and 0x53 + +00 0001001 start data block +00 0000011 start write to current address +1 00000100 +1 00010001 write data 0x11223344 +1 00100010 +1 00110011 +1 01000100 +00 0001000 start address block +01 1010000 address 0x50 +01 1010000 address 0x51 +01 1010000 address 0x52 +01 1010000 address 0x53 +00 0000000 stop + +*/ + +// init_data ROM +localparam INIT_DATA_LEN = 68; + +reg [8:0] init_data [INIT_DATA_LEN-1:0]; + +initial begin + // init clock mux registers + init_data[0] = {2'b00, 7'b0001001}; // start data block + init_data[1] = {2'b00, 7'b0000011}; // start write to current address + init_data[2] = {1'b1, 8'd2}; // select PLL bandwidth + //init_data[3] = {1'b1, 8'hA2}; + init_data[3] = {1'b1, 8'hA0}; + init_data[4] = {2'b00, 7'b0000011}; // start write to current address + init_data[5] = {1'b1, 8'd3}; // disable outputs during ICAL + //init_data[6] = {1'b1, 8'h15}; + init_data[6] = {1'b1, 8'h10}; + init_data[7] = {2'b00, 7'b0000011}; // start write to current address + init_data[8] = {1'b1, 8'd5}; // set CLKOUT1 and CLKOUT2 to LVPECL + init_data[9] = {1'b1, 8'hED}; + init_data[10] = {2'b00, 7'b0000011}; // start write to current address + init_data[11] = {1'b1, 8'd6}; // set CLKOUT3 to LVPECL and CLKOUT4 to LVDS + //init_data[12] = {1'b1, 8'h2D}; + init_data[12] = {1'b1, 8'h3D}; + init_data[13] = {2'b00, 7'b0000011}; // start write to current address + init_data[14] = {1'b1, 8'd7}; // set CLKOUT5 to to LVDS + //init_data[15] = {1'b1, 8'h0A}; + init_data[15] = {1'b1, 8'h3A}; + init_data[16] = {2'b00, 7'b0000011}; // start write to current address + init_data[17] = {1'b1, 8'd20}; // enable LOL output + init_data[18] = {1'b1, 8'h3E}; + init_data[19] = {2'b00, 7'b0000011}; // start write to current address + init_data[20] = {1'b1, 8'd25}; // N1_HS + init_data[21] = {1'b1, 8'h40}; + init_data[22] = {2'b00, 7'b0000011}; // start write to current address + init_data[23] = {1'b1, 8'd27}; // NC1_LS + init_data[24] = {1'b1, 8'h05}; + init_data[25] = {2'b00, 7'b0000011}; // start write to current address + init_data[26] = {1'b1, 8'd30}; // NC2_LS + init_data[27] = {1'b1, 8'h05}; + init_data[28] = {2'b00, 7'b0000011}; // start write to current address + init_data[29] = {1'b1, 8'd33}; // NC3_LS + init_data[30] = {1'b1, 8'h05}; + init_data[31] = {2'b00, 7'b0000011}; // start write to current address + init_data[32] = {1'b1, 8'd36}; // NC4_LS + init_data[33] = {1'b1, 8'h05}; + init_data[34] = {2'b00, 7'b0000011}; // start write to current address + init_data[35] = {1'b1, 8'd39}; // NC5_LS + init_data[36] = {1'b1, 8'h05}; + init_data[37] = {2'b00, 7'b0000011}; // start write to current address + init_data[38] = {1'b1, 8'd40}; // N2_HS + init_data[39] = {1'b1, 8'hA0}; + init_data[40] = {2'b00, 7'b0000011}; // start write to current address + init_data[41] = {1'b1, 8'd41}; // N2_LS + init_data[42] = {1'b1, 8'h01}; + init_data[43] = {2'b00, 7'b0000011}; // start write to current address + init_data[44] = {1'b1, 8'd42}; // N2_LS + init_data[45] = {1'b1, 8'h3B}; + init_data[46] = {2'b00, 7'b0000011}; // start write to current address + init_data[47] = {1'b1, 8'd45}; // N31 + init_data[48] = {1'b1, 8'h4E}; + init_data[49] = {2'b00, 7'b0000011}; // start write to current address + init_data[50] = {1'b1, 8'd48}; // N32 + init_data[51] = {1'b1, 8'h4E}; + init_data[52] = {2'b00, 7'b0000011}; // start write to current address + init_data[53] = {1'b1, 8'd51}; // N33 + init_data[54] = {1'b1, 8'h4E}; + init_data[55] = {2'b00, 7'b0000011}; // start write to current address + init_data[56] = {1'b1, 8'd54}; // N34 + init_data[57] = {1'b1, 8'h4E}; + init_data[58] = {2'b00, 7'b0000011}; // start write to current address + init_data[59] = {1'b1, 8'd141}; // Zero independent skew + init_data[60] = {1'b1, 8'h00}; + init_data[61] = {2'b00, 7'b0000011}; // start write to current address + init_data[62] = {1'b1, 8'd136}; // Soft reset + init_data[63] = {1'b1, 8'h40}; + init_data[64] = {2'b00, 7'b0001000}; // start address block + init_data[65] = {2'b01, 7'b1101001}; // first clock mux + init_data[66] = {2'b01, 7'b1101000}; // second clock mux + init_data[67] = 9'd0; // stop +end + +localparam [3:0] + STATE_IDLE = 3'd0, + STATE_RUN = 3'd1, + STATE_TABLE_1 = 3'd2, + STATE_TABLE_2 = 3'd3, + STATE_TABLE_3 = 3'd4; + +reg [4:0] state_reg = STATE_IDLE, state_next; + +parameter AW = $clog2(INIT_DATA_LEN); + +reg [8:0] init_data_reg = 9'd0; + +reg [AW-1:0] address_reg = {AW{1'b0}}, address_next; +reg [AW-1:0] address_ptr_reg = {AW{1'b0}}, address_ptr_next; +reg [AW-1:0] data_ptr_reg = {AW{1'b0}}, data_ptr_next; + +reg [6:0] cur_address_reg = 7'd0, cur_address_next; + +reg [6:0] cmd_address_reg = 7'd0, cmd_address_next; +reg cmd_start_reg = 1'b0, cmd_start_next; +reg cmd_write_reg = 1'b0, cmd_write_next; +reg cmd_stop_reg = 1'b0, cmd_stop_next; +reg cmd_valid_reg = 1'b0, cmd_valid_next; + +reg [7:0] data_out_reg = 8'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; + +reg start_flag_reg = 1'b0, start_flag_next; + +reg busy_reg = 1'b0; + +assign cmd_address = cmd_address_reg; +assign cmd_start = cmd_start_reg; +assign cmd_read = 1'b0; +assign cmd_write = cmd_write_reg; +assign cmd_write_multiple = 1'b0; +assign cmd_stop = cmd_stop_reg; +assign cmd_valid = cmd_valid_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; +assign data_out_last = 1'b1; + +assign busy = busy_reg; + +always @* begin + state_next = STATE_IDLE; + + address_next = address_reg; + address_ptr_next = address_ptr_reg; + data_ptr_next = data_ptr_reg; + + cur_address_next = cur_address_reg; + + cmd_address_next = cmd_address_reg; + cmd_start_next = cmd_start_reg & ~(cmd_valid & cmd_ready); + cmd_write_next = cmd_write_reg & ~(cmd_valid & cmd_ready); + cmd_stop_next = cmd_stop_reg & ~(cmd_valid & cmd_ready); + cmd_valid_next = cmd_valid_reg & ~cmd_ready; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + + start_flag_next = start_flag_reg; + + if (cmd_valid | data_out_valid) begin + // wait for output registers to clear + state_next = state_reg; + end else begin + case (state_reg) + STATE_IDLE: begin + // wait for start signal + if (~start_flag_reg & start) begin + address_next = {AW{1'b0}}; + start_flag_next = 1'b1; + state_next = STATE_RUN; + end else begin + state_next = STATE_IDLE; + end + end + STATE_RUN: begin + // process commands + if (init_data_reg[8] == 1'b1) begin + // write data + cmd_write_next = 1'b1; + cmd_stop_next = 1'b0; + cmd_valid_next = 1'b1; + + data_out_next = init_data_reg[7:0]; + data_out_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg[8:7] == 2'b01) begin + // write address + cmd_address_next = init_data_reg[6:0]; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_RUN; + end + end + STATE_TABLE_1: begin + // find address table start + if (init_data_reg == 9'b000001000) begin + // address table start + address_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_2; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end + end + STATE_TABLE_2: begin + // find next address + if (init_data_reg[8:7] == 2'b01) begin + // write address command + // store address and move to data table + cur_address_next = init_data_reg[6:0]; + address_ptr_next = address_reg + 1; + address_next = data_ptr_reg; + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'd1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_2; + end + end + STATE_TABLE_3: begin + // process data table with selected address + if (init_data_reg[8] == 1'b1) begin + // write data + cmd_write_next = 1'b1; + cmd_stop_next = 1'b0; + cmd_valid_next = 1'b1; + + data_out_next = init_data_reg[7:0]; + data_out_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg[8:7] == 2'b01) begin + // write address + cmd_address_next = init_data_reg[6:0]; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000000011) begin + // write current address + cmd_address_next = cur_address_reg; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'b000001000) begin + // address table start + address_next = address_ptr_reg; + state_next = STATE_TABLE_2; + end else if (init_data_reg == 9'd1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_3; + end + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + init_data_reg <= 9'd0; + + address_reg <= {AW{1'b0}}; + address_ptr_reg <= {AW{1'b0}}; + data_ptr_reg <= {AW{1'b0}}; + + cur_address_reg <= 7'd0; + + cmd_valid_reg <= 1'b0; + + data_out_valid_reg <= 1'b0; + + start_flag_reg <= 1'b0; + + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + + // read init_data ROM + init_data_reg <= init_data[address_next]; + + address_reg <= address_next; + address_ptr_reg <= address_ptr_next; + data_ptr_reg <= data_ptr_next; + + cur_address_reg <= cur_address_next; + + cmd_valid_reg <= cmd_valid_next; + + data_out_valid_reg <= data_out_valid_next; + + start_flag_reg <= start & start_flag_next; + + busy_reg <= (state_reg != STATE_IDLE); + end + + cmd_address_reg <= cmd_address_next; + cmd_start_reg <= cmd_start_next; + cmd_write_reg <= cmd_write_next; + cmd_stop_reg <= cmd_stop_next; + + data_out_reg <= data_out_next; +end + +endmodule diff --git a/example/HXT100G/fpga/rtl/i2c_master.v b/example/HXT100G/fpga/rtl/i2c_master.v new file mode 100644 index 000000000..4a6b945c1 --- /dev/null +++ b/example/HXT100G/fpga/rtl/i2c_master.v @@ -0,0 +1,895 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * I2C master + */ +module i2c_master ( + input wire clk, + input wire rst, + + /* + * Host interface + */ + input wire [6:0] cmd_address, + input wire cmd_start, + input wire cmd_read, + input wire cmd_write, + input wire cmd_write_multiple, + input wire cmd_stop, + input wire cmd_valid, + output wire cmd_ready, + + input wire [7:0] data_in, + input wire data_in_valid, + output wire data_in_ready, + input wire data_in_last, + + output wire [7:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + output wire data_out_last, + + /* + * I2C interface + */ + input wire scl_i, + output wire scl_o, + output wire scl_t, + input wire sda_i, + output wire sda_o, + output wire sda_t, + + /* + * Status + */ + output wire busy, + output wire bus_control, + output wire bus_active, + output wire missed_ack, + + /* + * Configuration + */ + input wire [15:0] prescale, + input wire stop_on_idle +); + +/* + +I2C + +Read + __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ +sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_\_R___A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A____/ + ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ +scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP + +Write + __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ +sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_/_W_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_/_N_\__/ + ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ +scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP + +Commands: + +read + read data byte + set start to force generation of a start condition + start is implied when bus is inactive or active with write or different address + set stop to issue a stop condition after reading current byte + if stop is set with read command, then data_out_last will be set + +write + write data byte + set start to force generation of a start condition + start is implied when bus is inactive or active with read or different address + set stop to issue a stop condition after writing current byte + +write multiple + write multiple data bytes (until data_in_last) + set start to force generation of a start condition + start is implied when bus is inactive or active with read or different address + set stop to issue a stop condition after writing block + +stop + issue stop condition if bus is active + +Status: + +busy + module is communicating over the bus + +bus_control + module has control of bus in active state + +bus_active + bus is active, not necessarily controlled by this module + +missed_ack + strobed when a slave ack is missed + +Parameters: + +prescale + set prescale to 1/4 of the minimum clock period in units + of input clk cycles (prescale = Fclk / (FI2Cclk * 4)) + +stop_on_idle + automatically issue stop when command input is not valid + +Example of interfacing with tristate pins: +(this will work for any tristate bus) + +assign scl_i = scl_pin; +assign scl_pin = scl_t ? 1'bz : scl_o; +assign sda_i = sda_pin; +assign sda_pin = sda_t ? 1'bz : sda_o; + +Equivalent code that does not use *_t connections: +(we can get away with this because I2C is open-drain) + +assign scl_i = scl_pin; +assign scl_pin = scl_o ? 1'bz : 1'b0; +assign sda_i = sda_pin; +assign sda_pin = sda_o ? 1'bz : 1'b0; + +Example of two interconnected I2C devices: + +assign scl_1_i = scl_1_o & scl_2_o; +assign scl_2_i = scl_1_o & scl_2_o; +assign sda_1_i = sda_1_o & sda_2_o; +assign sda_2_i = sda_1_o & sda_2_o; + +Example of two I2C devices sharing the same pins: + +assign scl_1_i = scl_pin; +assign scl_2_i = scl_pin; +assign scl_pin = (scl_1_o & scl_2_o) ? 1'bz : 1'b0; +assign sda_1_i = sda_pin; +assign sda_2_i = sda_pin; +assign sda_pin = (sda_1_o & sda_2_o) ? 1'bz : 1'b0; + +Notes: + +scl_o should not be connected directly to scl_i, only via AND logic or a tristate +I/O pin. This would prevent devices from stretching the clock period. + +*/ + +localparam [4:0] + STATE_IDLE = 4'd0, + STATE_ACTIVE_WRITE = 4'd1, + STATE_ACTIVE_READ = 4'd2, + STATE_START_WAIT = 4'd3, + STATE_START = 4'd4, + STATE_ADDRESS_1 = 4'd5, + STATE_ADDRESS_2 = 4'd6, + STATE_WRITE_1 = 4'd7, + STATE_WRITE_2 = 4'd8, + STATE_WRITE_3 = 4'd9, + STATE_READ = 4'd10, + STATE_STOP = 4'd11; + +reg [4:0] state_reg = STATE_IDLE, state_next; + +localparam [4:0] + PHY_STATE_IDLE = 5'd0, + PHY_STATE_ACTIVE = 5'd1, + PHY_STATE_REPEATED_START_1 = 5'd2, + PHY_STATE_REPEATED_START_2 = 5'd3, + PHY_STATE_START_1 = 5'd4, + PHY_STATE_START_2 = 5'd5, + PHY_STATE_WRITE_BIT_1 = 5'd6, + PHY_STATE_WRITE_BIT_2 = 5'd7, + PHY_STATE_WRITE_BIT_3 = 5'd8, + PHY_STATE_READ_BIT_1 = 5'd9, + PHY_STATE_READ_BIT_2 = 5'd10, + PHY_STATE_READ_BIT_3 = 5'd11, + PHY_STATE_READ_BIT_4 = 5'd12, + PHY_STATE_STOP_1 = 5'd13, + PHY_STATE_STOP_2 = 5'd14, + PHY_STATE_STOP_3 = 5'd15; + +reg [4:0] phy_state_reg = STATE_IDLE, phy_state_next; + +reg phy_start_bit; +reg phy_stop_bit; +reg phy_write_bit; +reg phy_read_bit; +reg phy_release_bus; + +reg phy_tx_data; + +reg phy_rx_data_reg = 1'b0, phy_rx_data_next; + +reg [6:0] addr_reg = 7'd0, addr_next; +reg [7:0] data_reg = 8'd0, data_next; +reg last_reg = 1'b0, last_next; + +reg mode_read_reg = 1'b0, mode_read_next; +reg mode_write_multiple_reg = 1'b0, mode_write_multiple_next; +reg mode_stop_reg = 1'b0, mode_stop_next; + +reg [16:0] delay_reg = 16'd0, delay_next; +reg delay_scl_reg = 1'b0, delay_scl_next; +reg delay_sda_reg = 1'b0, delay_sda_next; + +reg [3:0] bit_count_reg = 4'd0, bit_count_next; + +reg cmd_ready_reg = 1'b0, cmd_ready_next; + +reg data_in_ready_reg = 1'b0, data_in_ready_next; + +reg [7:0] data_out_reg = 8'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; +reg data_out_last_reg = 1'b0, data_out_last_next; + +reg scl_i_reg = 1'b1; +reg sda_i_reg = 1'b1; + +reg scl_o_reg = 1'b1, scl_o_next; +reg sda_o_reg = 1'b1, sda_o_next; + +reg last_scl_i_reg = 1'b1; +reg last_sda_i_reg = 1'b1; + +reg busy_reg = 1'b0; +reg bus_active_reg = 1'b0; +reg bus_control_reg = 1'b0, bus_control_next; +reg missed_ack_reg = 1'b0, missed_ack_next; + +assign cmd_ready = cmd_ready_reg; + +assign data_in_ready = data_in_ready_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; +assign data_out_last = data_out_last_reg; + +assign scl_o = scl_o_reg; +assign scl_t = scl_o_reg; +assign sda_o = sda_o_reg; +assign sda_t = sda_o_reg; + +assign busy = busy_reg; +assign bus_active = bus_active_reg; +assign bus_control = bus_control_reg; +assign missed_ack = missed_ack_reg; + +wire scl_posedge = scl_i_reg & ~last_scl_i_reg; +wire scl_negedge = ~scl_i_reg & last_scl_i_reg; +wire sda_posedge = sda_i_reg & ~last_sda_i_reg; +wire sda_negedge = ~sda_i_reg & last_sda_i_reg; + +wire start_bit = sda_negedge & scl_i_reg; +wire stop_bit = sda_posedge & scl_i_reg; + +always @* begin + state_next = STATE_IDLE; + + phy_start_bit = 1'b0; + phy_stop_bit = 1'b0; + phy_write_bit = 1'b0; + phy_read_bit = 1'b0; + phy_tx_data = 1'b0; + phy_release_bus = 1'b0; + + addr_next = addr_reg; + data_next = data_reg; + last_next = last_reg; + + mode_read_next = mode_read_reg; + mode_write_multiple_next = mode_write_multiple_reg; + mode_stop_next = mode_stop_reg; + + bit_count_next = bit_count_reg; + + cmd_ready_next = 1'b0; + + data_in_ready_next = 1'b0; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + data_out_last_next = data_out_last_reg; + + missed_ack_next = 1'b0; + + // generate delays + if (phy_state_reg != PHY_STATE_IDLE && phy_state_reg != PHY_STATE_ACTIVE) begin + // wait for phy operation + state_next = state_reg; + end else begin + // process states + case (state_reg) + STATE_IDLE: begin + // line idle + cmd_ready_next = 1'b1; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + // start bit + if (bus_active) begin + state_next = STATE_START_WAIT; + end else begin + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + end else begin + // invalid or unspecified - ignore + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_ACTIVE_WRITE: begin + // line active with current address and read/write mode + cmd_ready_next = 1'b1; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + if (cmd_start || cmd_address != addr_reg || cmd_read) begin + // address or mode mismatch or forced start - repeated start + + // repeated start bit + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end else begin + // address and mode match + + // start write + data_in_ready_next = 1'b1; + state_next = STATE_WRITE_1; + end + end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin + // stop command + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + // invalid or unspecified - ignore + state_next = STATE_ACTIVE_WRITE; + end + end else begin + if (stop_on_idle & cmd_ready & ~cmd_valid) begin + // no waiting command and stop_on_idle selected, issue stop condition + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + state_next = STATE_ACTIVE_WRITE; + end + end + end + STATE_ACTIVE_READ: begin + // line active to current address + cmd_ready_next = ~data_out_valid; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + if (cmd_start || cmd_address != addr_reg || cmd_write) begin + // address or mode mismatch or forced start - repeated start + + // write nack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // repeated start bit + state_next = STATE_START; + end else begin + // address and mode match + + // write ack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b0; + // start next read + bit_count_next = 4'd8; + data_next = 8'd0; + state_next = STATE_READ; + end + end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin + // stop command + // write nack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // send stop bit + state_next = STATE_STOP; + end else begin + // invalid or unspecified - ignore + state_next = STATE_ACTIVE_READ; + end + end else begin + if (stop_on_idle & cmd_ready & ~cmd_valid) begin + // no waiting command and stop_on_idle selected, issue stop condition + // write ack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // send stop bit + state_next = STATE_STOP; + end else begin + state_next = STATE_ACTIVE_READ; + end + end + end + STATE_START_WAIT: begin + // wait for bus idle + + if (bus_active) begin + state_next = STATE_START_WAIT; + end else begin + // bus is idle, take control + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + end + STATE_START: begin + // send start bit + + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + STATE_ADDRESS_1: begin + // send address + bit_count_next = bit_count_reg - 1; + if (bit_count_reg > 1) begin + // send address + phy_write_bit = 1'b1; + phy_tx_data = addr_reg[bit_count_reg-2]; + state_next = STATE_ADDRESS_1; + end else if (bit_count_reg > 0) begin + // send read/write bit + phy_write_bit = 1'b1; + phy_tx_data = mode_read_reg; + state_next = STATE_ADDRESS_1; + end else begin + // read ack bit + phy_read_bit = 1'b1; + state_next = STATE_ADDRESS_2; + end + end + STATE_ADDRESS_2: begin + // read ack bit + missed_ack_next = phy_rx_data_reg; + + if (mode_read_reg) begin + // start read + bit_count_next = 4'd8; + data_next = 1'b0; + state_next = STATE_READ; + end else begin + // start write + data_in_ready_next = 1'b1; + state_next = STATE_WRITE_1; + end + end + STATE_WRITE_1: begin + data_in_ready_next = 1'b1; + + if (data_in_ready & data_in_valid) begin + // got data, start write + data_next = data_in; + last_next = data_in_last; + bit_count_next = 4'd8; + data_in_ready_next = 1'b0; + state_next = STATE_WRITE_2; + end else begin + // wait for data + state_next = STATE_WRITE_1; + end + end + STATE_WRITE_2: begin + // send data + bit_count_next = bit_count_reg - 1; + if (bit_count_reg > 0) begin + // write data bit + phy_write_bit = 1'b1; + phy_tx_data = data_reg[bit_count_reg-1]; + state_next = STATE_WRITE_2; + end else begin + // read ack bit + phy_read_bit = 1'b1; + state_next = STATE_WRITE_3; + end + end + STATE_WRITE_3: begin + // read ack bit + missed_ack_next = phy_rx_data_reg; + + if (mode_write_multiple_reg && !last_reg) begin + // more to write + state_next = STATE_WRITE_1; + end else if (mode_stop_reg) begin + // last cycle and stop selected + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + // otherwise, return to bus active state + state_next = STATE_ACTIVE_WRITE; + end + end + STATE_READ: begin + // read data + + bit_count_next = bit_count_reg - 1; + data_next = {data_reg[6:0], phy_rx_data_reg}; + if (bit_count_reg > 0) begin + // read next bit + phy_read_bit = 1'b1; + state_next = STATE_READ; + end else begin + // output data word + data_out_next = data_next; + data_out_valid_next = 1'b1; + data_out_last_next = 1'b0; + if (mode_stop_reg) begin + // send nack and stop + data_out_last_next = 1'b1; + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + state_next = STATE_STOP; + end else begin + // return to bus active state + state_next = STATE_ACTIVE_READ; + end + end + end + STATE_STOP: begin + // send stop bit + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end + endcase + end +end + +always @* begin + phy_state_next = PHY_STATE_IDLE; + + phy_rx_data_next = phy_rx_data_reg; + + delay_next = delay_reg; + delay_scl_next = delay_scl_reg; + delay_sda_next = delay_sda_reg; + + scl_o_next = scl_o_reg; + sda_o_next = sda_o_reg; + + bus_control_next = bus_control_reg; + + if (phy_release_bus) begin + // release bus and return to idle state + sda_o_next = 1'b1; + scl_o_next = 1'b1; + delay_scl_next = 1'b0; + delay_sda_next = 1'b0; + delay_next = 1'b0; + phy_state_next = PHY_STATE_IDLE; + end else if (delay_scl_reg) begin + // wait for SCL to match command + delay_scl_next = scl_o_reg & ~scl_i_reg; + phy_state_next = phy_state_reg; + end else if (delay_sda_reg) begin + // wait for SDA to match command + delay_sda_next = sda_o_reg & ~sda_i_reg; + phy_state_next = phy_state_reg; + end else if (delay_reg > 0) begin + // time delay + delay_next = delay_reg - 1; + phy_state_next = phy_state_reg; + end else begin + case (phy_state_reg) + PHY_STATE_IDLE: begin + // bus idle - wait for start command + sda_o_next = 1'b1; + scl_o_next = 1'b1; + if (phy_start_bit) begin + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_1; + end else begin + phy_state_next = PHY_STATE_IDLE; + end + end + PHY_STATE_ACTIVE: begin + // bus active + if (phy_start_bit) begin + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_REPEATED_START_1; + end else if (phy_write_bit) begin + sda_o_next = phy_tx_data; + delay_next = prescale; + phy_state_next = PHY_STATE_WRITE_BIT_1; + end else if (phy_read_bit) begin + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_1; + end else if (phy_stop_bit) begin + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_1; + end else begin + phy_state_next = PHY_STATE_ACTIVE; + end + end + PHY_STATE_REPEATED_START_1: begin + // generate repeated start bit + // ______ + // sda XXX/ \_______ + // _______ + // scl ______/ \___ + // + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_REPEATED_START_2; + end + PHY_STATE_REPEATED_START_2: begin + // generate repeated start bit + // ______ + // sda XXX/ \_______ + // _______ + // scl ______/ \___ + // + + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_1; + end + PHY_STATE_START_1: begin + // generate start bit + // ___ + // sda \_______ + // _______ + // scl \___ + // + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_2; + end + PHY_STATE_START_2: begin + // generate start bit + // ___ + // sda \_______ + // _______ + // scl \___ + // + + bus_control_next = 1'b1; + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_WRITE_BIT_1: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale << 1; + phy_state_next = PHY_STATE_WRITE_BIT_2; + end + PHY_STATE_WRITE_BIT_2: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_WRITE_BIT_3; + end + PHY_STATE_WRITE_BIT_3: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_READ_BIT_1: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_2; + end + PHY_STATE_READ_BIT_2: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_rx_data_next = sda_i_reg; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_3; + end + PHY_STATE_READ_BIT_3: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_4; + end + PHY_STATE_READ_BIT_4: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_STOP_1: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_2; + end + PHY_STATE_STOP_2: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_3; + end + PHY_STATE_STOP_3: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + bus_control_next = 1'b0; + phy_state_next = PHY_STATE_IDLE; + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + phy_state_reg <= PHY_STATE_IDLE; + delay_reg <= 16'd0; + delay_scl_reg <= 1'b0; + delay_sda_reg <= 1'b0; + cmd_ready_reg <= 1'b0; + data_in_ready_reg <= 1'b0; + data_out_valid_reg <= 1'b0; + scl_o_reg <= 1'b1; + sda_o_reg <= 1'b1; + busy_reg <= 1'b0; + bus_active_reg <= 1'b0; + bus_control_reg <= 1'b0; + missed_ack_reg <= 1'b0; + end else begin + state_reg <= state_next; + phy_state_reg <= phy_state_next; + + delay_reg <= delay_next; + delay_scl_reg <= delay_scl_next; + delay_sda_reg <= delay_sda_next; + + cmd_ready_reg <= cmd_ready_next; + data_in_ready_reg <= data_in_ready_next; + data_out_valid_reg <= data_out_valid_next; + + scl_o_reg <= scl_o_next; + sda_o_reg <= sda_o_next; + + busy_reg <= !(state_reg == STATE_IDLE || state_reg == STATE_ACTIVE_WRITE || state_reg == STATE_ACTIVE_READ); + + if (start_bit) begin + bus_active_reg <= 1'b1; + end else if (stop_bit) begin + bus_active_reg <= 1'b0; + end else begin + bus_active_reg <= bus_active_reg; + end + + bus_control_reg <= bus_control_next; + missed_ack_reg <= missed_ack_next; + end + + phy_rx_data_reg <= phy_rx_data_next; + + addr_reg <= addr_next; + data_reg <= data_next; + last_reg <= last_next; + + mode_read_reg <= mode_read_next; + mode_write_multiple_reg <= mode_write_multiple_next; + mode_stop_reg <= mode_stop_next; + + bit_count_reg <= bit_count_next; + + data_out_reg <= data_out_next; + data_out_last_reg <= data_out_last_next; + + scl_i_reg <= scl_i; + sda_i_reg <= sda_i; + last_scl_i_reg <= scl_i_reg; + last_sda_i_reg <= sda_i_reg; +end + +endmodule diff --git a/example/HXT100G/fpga/rtl/sync_reset.v b/example/HXT100G/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..d74c0337e --- /dev/null +++ b/example/HXT100G/fpga/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/HXT100G/fpga/rtl/sync_signal.v b/example/HXT100G/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..5afcd7170 --- /dev/null +++ b/example/HXT100G/fpga/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/HXT100G/fpga/tb/arp_ep.py b/example/HXT100G/fpga/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/HXT100G/fpga/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga/tb/axis_ep.py b/example/HXT100G/fpga/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/HXT100G/fpga/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga/tb/eth_ep.py b/example/HXT100G/fpga/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/HXT100G/fpga/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga/tb/ip_ep.py b/example/HXT100G/fpga/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/HXT100G/fpga/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py new file mode 100755 index 000000000..ffad66602 --- /dev/null +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -0,0 +1,1117 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import eth_ep +import arp_ep +import udp_ep +import xgmii_ep + +module = 'fpga_core' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/eth_crc_8.v") +srcs.append("../lib/eth/rtl/eth_crc_16.v") +srcs.append("../lib/eth/rtl/eth_crc_24.v") +srcs.append("../lib/eth/rtl/eth_crc_32.v") +srcs.append("../lib/eth/rtl/eth_crc_40.v") +srcs.append("../lib/eth/rtl/eth_crc_48.v") +srcs.append("../lib/eth/rtl/eth_crc_56.v") +srcs.append("../lib/eth/rtl/eth_crc_64.v") +srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_64_2.v") +srcs.append("../lib/eth/rtl/ip_mux_64_2.v") +srcs.append("../lib/eth/rtl/arp_64.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") +srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") +srcs.append("../lib/eth/rtl/eth_mux_64_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo_64.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_fpga_core(clk, + rst, + current_test, + + sw, + jp, + led, + + uart_rst, + uart_suspend, + uart_ri, + uart_dcd, + uart_dtr, + uart_dsr, + uart_txd, + uart_rxd, + uart_rts, + uart_cts, + + amh_right_mdc, + amh_right_mdio_i, + amh_right_mdio_o, + amh_right_mdio_t, + amh_left_mdc, + amh_left_mdio_i, + amh_left_mdio_o, + amh_left_mdio_t, + + eth_r0_txd, + eth_r0_txc, + eth_r0_rxd, + eth_r0_rxc, + eth_r1_txd, + eth_r1_txc, + eth_r1_rxd, + eth_r1_rxc, + eth_r2_txd, + eth_r2_txc, + eth_r2_rxd, + eth_r2_rxc, + eth_r3_txd, + eth_r3_txc, + eth_r3_rxd, + eth_r3_rxc, + eth_r4_txd, + eth_r4_txc, + eth_r4_rxd, + eth_r4_rxc, + eth_r5_txd, + eth_r5_txc, + eth_r5_rxd, + eth_r5_rxc, + eth_r6_txd, + eth_r6_txc, + eth_r6_rxd, + eth_r6_rxc, + eth_r7_txd, + eth_r7_txc, + eth_r7_rxd, + eth_r7_rxc, + eth_r8_txd, + eth_r8_txc, + eth_r8_rxd, + eth_r8_rxc, + eth_r9_txd, + eth_r9_txc, + eth_r9_rxd, + eth_r9_rxc, + eth_r10_txd, + eth_r10_txc, + eth_r10_rxd, + eth_r10_rxc, + eth_r11_txd, + eth_r11_txc, + eth_r11_rxd, + eth_r11_rxc, + eth_l0_txd, + eth_l0_txc, + eth_l0_rxd, + eth_l0_rxc, + eth_l1_txd, + eth_l1_txc, + eth_l1_rxd, + eth_l1_rxc, + eth_l2_txd, + eth_l2_txc, + eth_l2_rxd, + eth_l2_rxc, + eth_l3_txd, + eth_l3_txc, + eth_l3_rxd, + eth_l3_rxc, + eth_l4_txd, + eth_l4_txc, + eth_l4_rxd, + eth_l4_rxc, + eth_l5_txd, + eth_l5_txc, + eth_l5_rxd, + eth_l5_rxc, + eth_l6_txd, + eth_l6_txc, + eth_l6_rxd, + eth_l6_rxc, + eth_l7_txd, + eth_l7_txc, + eth_l7_rxd, + eth_l7_rxc, + eth_l8_txd, + eth_l8_txc, + eth_l8_rxd, + eth_l8_rxc, + eth_l9_txd, + eth_l9_txc, + eth_l9_rxd, + eth_l9_rxc, + eth_l10_txd, + eth_l10_txc, + eth_l10_rxd, + eth_l10_rxc, + eth_l11_txd, + eth_l11_txc, + eth_l11_rxd, + eth_l11_rxc): + + 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, + + sw=sw, + jp=jp, + led=led, + + uart_rst=uart_rst, + uart_suspend=uart_suspend, + uart_ri=uart_ri, + uart_dcd=uart_dcd, + uart_dtr=uart_dtr, + uart_dsr=uart_dsr, + uart_txd=uart_txd, + uart_rxd=uart_rxd, + uart_rts=uart_rts, + uart_cts=uart_cts, + + amh_right_mdc=amh_right_mdc, + amh_right_mdio_i=amh_right_mdio_i, + amh_right_mdio_o=amh_right_mdio_o, + amh_right_mdio_t=amh_right_mdio_t, + amh_left_mdc=amh_left_mdc, + amh_left_mdio_i=amh_left_mdio_i, + amh_left_mdio_o=amh_left_mdio_o, + amh_left_mdio_t=amh_left_mdio_t, + + eth_r0_txd=eth_r0_txd, + eth_r0_txc=eth_r0_txc, + eth_r0_rxd=eth_r0_rxd, + eth_r0_rxc=eth_r0_rxc, + eth_r1_txd=eth_r1_txd, + eth_r1_txc=eth_r1_txc, + eth_r1_rxd=eth_r1_rxd, + eth_r1_rxc=eth_r1_rxc, + eth_r2_txd=eth_r2_txd, + eth_r2_txc=eth_r2_txc, + eth_r2_rxd=eth_r2_rxd, + eth_r2_rxc=eth_r2_rxc, + eth_r3_txd=eth_r3_txd, + eth_r3_txc=eth_r3_txc, + eth_r3_rxd=eth_r3_rxd, + eth_r3_rxc=eth_r3_rxc, + eth_r4_txd=eth_r4_txd, + eth_r4_txc=eth_r4_txc, + eth_r4_rxd=eth_r4_rxd, + eth_r4_rxc=eth_r4_rxc, + eth_r5_txd=eth_r5_txd, + eth_r5_txc=eth_r5_txc, + eth_r5_rxd=eth_r5_rxd, + eth_r5_rxc=eth_r5_rxc, + eth_r6_txd=eth_r6_txd, + eth_r6_txc=eth_r6_txc, + eth_r6_rxd=eth_r6_rxd, + eth_r6_rxc=eth_r6_rxc, + eth_r7_txd=eth_r7_txd, + eth_r7_txc=eth_r7_txc, + eth_r7_rxd=eth_r7_rxd, + eth_r7_rxc=eth_r7_rxc, + eth_r8_txd=eth_r8_txd, + eth_r8_txc=eth_r8_txc, + eth_r8_rxd=eth_r8_rxd, + eth_r8_rxc=eth_r8_rxc, + eth_r9_txd=eth_r9_txd, + eth_r9_txc=eth_r9_txc, + eth_r9_rxd=eth_r9_rxd, + eth_r9_rxc=eth_r9_rxc, + eth_r10_txd=eth_r10_txd, + eth_r10_txc=eth_r10_txc, + eth_r10_rxd=eth_r10_rxd, + eth_r10_rxc=eth_r10_rxc, + eth_r11_txd=eth_r11_txd, + eth_r11_txc=eth_r11_txc, + eth_r11_rxd=eth_r11_rxd, + eth_r11_rxc=eth_r11_rxc, + eth_l0_txd=eth_l0_txd, + eth_l0_txc=eth_l0_txc, + eth_l0_rxd=eth_l0_rxd, + eth_l0_rxc=eth_l0_rxc, + eth_l1_txd=eth_l1_txd, + eth_l1_txc=eth_l1_txc, + eth_l1_rxd=eth_l1_rxd, + eth_l1_rxc=eth_l1_rxc, + eth_l2_txd=eth_l2_txd, + eth_l2_txc=eth_l2_txc, + eth_l2_rxd=eth_l2_rxd, + eth_l2_rxc=eth_l2_rxc, + eth_l3_txd=eth_l3_txd, + eth_l3_txc=eth_l3_txc, + eth_l3_rxd=eth_l3_rxd, + eth_l3_rxc=eth_l3_rxc, + eth_l4_txd=eth_l4_txd, + eth_l4_txc=eth_l4_txc, + eth_l4_rxd=eth_l4_rxd, + eth_l4_rxc=eth_l4_rxc, + eth_l5_txd=eth_l5_txd, + eth_l5_txc=eth_l5_txc, + eth_l5_rxd=eth_l5_rxd, + eth_l5_rxc=eth_l5_rxc, + eth_l6_txd=eth_l6_txd, + eth_l6_txc=eth_l6_txc, + eth_l6_rxd=eth_l6_rxd, + eth_l6_rxc=eth_l6_rxc, + eth_l7_txd=eth_l7_txd, + eth_l7_txc=eth_l7_txc, + eth_l7_rxd=eth_l7_rxd, + eth_l7_rxc=eth_l7_rxc, + eth_l8_txd=eth_l8_txd, + eth_l8_txc=eth_l8_txc, + eth_l8_rxd=eth_l8_rxd, + eth_l8_rxc=eth_l8_rxc, + eth_l9_txd=eth_l9_txd, + eth_l9_txc=eth_l9_txc, + eth_l9_rxd=eth_l9_rxd, + eth_l9_rxc=eth_l9_rxc, + eth_l10_txd=eth_l10_txd, + eth_l10_txc=eth_l10_txc, + eth_l10_rxd=eth_l10_rxd, + eth_l10_rxc=eth_l10_rxc, + eth_l11_txd=eth_l11_txd, + eth_l11_txc=eth_l11_txc, + eth_l11_rxd=eth_l11_rxd, + eth_l11_rxc=eth_l11_rxc) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + sw = Signal(intbv(0)[2:]) + jp = Signal(intbv(0)[4:]) + uart_suspend = Signal(bool(0)) + uart_dtr = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + amh_right_mdio_i = Signal(bool(0)) + amh_left_mdio_i = Signal(bool(0)) + eth_r0_rxd = Signal(intbv(0)[64:]) + eth_r0_rxc = Signal(intbv(0)[8:]) + eth_r1_rxd = Signal(intbv(0)[64:]) + eth_r1_rxc = Signal(intbv(0)[8:]) + eth_r2_rxd = Signal(intbv(0)[64:]) + eth_r2_rxc = Signal(intbv(0)[8:]) + eth_r3_rxd = Signal(intbv(0)[64:]) + eth_r3_rxc = Signal(intbv(0)[8:]) + eth_r4_rxd = Signal(intbv(0)[64:]) + eth_r4_rxc = Signal(intbv(0)[8:]) + eth_r5_rxd = Signal(intbv(0)[64:]) + eth_r5_rxc = Signal(intbv(0)[8:]) + eth_r6_rxd = Signal(intbv(0)[64:]) + eth_r6_rxc = Signal(intbv(0)[8:]) + eth_r7_rxd = Signal(intbv(0)[64:]) + eth_r7_rxc = Signal(intbv(0)[8:]) + eth_r8_rxd = Signal(intbv(0)[64:]) + eth_r8_rxc = Signal(intbv(0)[8:]) + eth_r9_rxd = Signal(intbv(0)[64:]) + eth_r9_rxc = Signal(intbv(0)[8:]) + eth_r10_rxd = Signal(intbv(0)[64:]) + eth_r10_rxc = Signal(intbv(0)[8:]) + eth_r11_rxd = Signal(intbv(0)[64:]) + eth_r11_rxc = Signal(intbv(0)[8:]) + eth_l0_rxd = Signal(intbv(0)[64:]) + eth_l0_rxc = Signal(intbv(0)[8:]) + eth_l1_rxd = Signal(intbv(0)[64:]) + eth_l1_rxc = Signal(intbv(0)[8:]) + eth_l2_rxd = Signal(intbv(0)[64:]) + eth_l2_rxc = Signal(intbv(0)[8:]) + eth_l3_rxd = Signal(intbv(0)[64:]) + eth_l3_rxc = Signal(intbv(0)[8:]) + eth_l4_rxd = Signal(intbv(0)[64:]) + eth_l4_rxc = Signal(intbv(0)[8:]) + eth_l5_rxd = Signal(intbv(0)[64:]) + eth_l5_rxc = Signal(intbv(0)[8:]) + eth_l6_rxd = Signal(intbv(0)[64:]) + eth_l6_rxc = Signal(intbv(0)[8:]) + eth_l7_rxd = Signal(intbv(0)[64:]) + eth_l7_rxc = Signal(intbv(0)[8:]) + eth_l8_rxd = Signal(intbv(0)[64:]) + eth_l8_rxc = Signal(intbv(0)[8:]) + eth_l9_rxd = Signal(intbv(0)[64:]) + eth_l9_rxc = Signal(intbv(0)[8:]) + eth_l10_rxd = Signal(intbv(0)[64:]) + eth_l10_rxc = Signal(intbv(0)[8:]) + eth_l11_rxd = Signal(intbv(0)[64:]) + eth_l11_rxc = Signal(intbv(0)[8:]) + + # Outputs + led = Signal(intbv(0)[4:]) + uart_rst = Signal(bool(0)) + uart_ri = Signal(bool(0)) + uart_dcd = Signal(bool(0)) + uart_dsr = Signal(bool(0)) + uart_rxd = Signal(bool(1)) + uart_cts = Signal(bool(0)) + amh_right_mdc = Signal(bool(1)) + amh_right_mdio_o = Signal(bool(1)) + amh_right_mdio_t = Signal(bool(1)) + amh_left_mdc = Signal(bool(1)) + amh_left_mdio_o = Signal(bool(1)) + amh_left_mdio_t = Signal(bool(1)) + eth_r0_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r0_txc = Signal(intbv(0xff)[8:]) + eth_r1_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r1_txc = Signal(intbv(0xff)[8:]) + eth_r2_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r2_txc = Signal(intbv(0xff)[8:]) + eth_r3_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r3_txc = Signal(intbv(0xff)[8:]) + eth_r4_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r4_txc = Signal(intbv(0xff)[8:]) + eth_r5_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r5_txc = Signal(intbv(0xff)[8:]) + eth_r6_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r6_txc = Signal(intbv(0xff)[8:]) + eth_r7_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r7_txc = Signal(intbv(0xff)[8:]) + eth_r8_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r8_txc = Signal(intbv(0xff)[8:]) + eth_r9_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r9_txc = Signal(intbv(0xff)[8:]) + eth_r10_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r10_txc = Signal(intbv(0xff)[8:]) + eth_r11_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r11_txc = Signal(intbv(0xff)[8:]) + eth_l0_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l0_txc = Signal(intbv(0xff)[8:]) + eth_l1_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l1_txc = Signal(intbv(0xff)[8:]) + eth_l2_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l2_txc = Signal(intbv(0xff)[8:]) + eth_l3_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l3_txc = Signal(intbv(0xff)[8:]) + eth_l4_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l4_txc = Signal(intbv(0xff)[8:]) + eth_l5_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l5_txc = Signal(intbv(0xff)[8:]) + eth_l6_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l6_txc = Signal(intbv(0xff)[8:]) + eth_l7_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l7_txc = Signal(intbv(0xff)[8:]) + eth_l8_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l8_txc = Signal(intbv(0xff)[8:]) + eth_l9_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l9_txc = Signal(intbv(0xff)[8:]) + eth_l10_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l10_txc = Signal(intbv(0xff)[8:]) + eth_l11_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l11_txc = Signal(intbv(0xff)[8:]) + + # sources and sinks + eth_r0_source_queue = Queue() + eth_r0_sink_queue = Queue() + eth_r1_source_queue = Queue() + eth_r1_sink_queue = Queue() + eth_r2_source_queue = Queue() + eth_r2_sink_queue = Queue() + eth_r3_source_queue = Queue() + eth_r3_sink_queue = Queue() + eth_r4_source_queue = Queue() + eth_r4_sink_queue = Queue() + eth_r5_source_queue = Queue() + eth_r5_sink_queue = Queue() + eth_r6_source_queue = Queue() + eth_r6_sink_queue = Queue() + eth_r7_source_queue = Queue() + eth_r7_sink_queue = Queue() + eth_r8_source_queue = Queue() + eth_r8_sink_queue = Queue() + eth_r9_source_queue = Queue() + eth_r9_sink_queue = Queue() + eth_r10_source_queue = Queue() + eth_r10_sink_queue = Queue() + eth_r11_source_queue = Queue() + eth_r11_sink_queue = Queue() + eth_l0_source_queue = Queue() + eth_l0_sink_queue = Queue() + eth_l1_source_queue = Queue() + eth_l1_sink_queue = Queue() + eth_l2_source_queue = Queue() + eth_l2_sink_queue = Queue() + eth_l3_source_queue = Queue() + eth_l3_sink_queue = Queue() + eth_l4_source_queue = Queue() + eth_l4_sink_queue = Queue() + eth_l5_source_queue = Queue() + eth_l5_sink_queue = Queue() + eth_l6_source_queue = Queue() + eth_l6_sink_queue = Queue() + eth_l7_source_queue = Queue() + eth_l7_sink_queue = Queue() + eth_l8_source_queue = Queue() + eth_l8_sink_queue = Queue() + eth_l9_source_queue = Queue() + eth_l9_sink_queue = Queue() + eth_l10_source_queue = Queue() + eth_l10_sink_queue = Queue() + eth_l11_source_queue = Queue() + eth_l11_sink_queue = Queue() + + eth_r0_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r0_rxd, + txc=eth_r0_rxc, + fifo=eth_r0_source_queue, + name='eth_r0_source') + + eth_r0_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r0_txd, + rxc=eth_r0_txc, + fifo=eth_r0_sink_queue, + name='eth_r0_sink') + + eth_r1_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r1_rxd, + txc=eth_r1_rxc, + fifo=eth_r1_source_queue, + name='eth_r1_source') + + eth_r1_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r1_txd, + rxc=eth_r1_txc, + fifo=eth_r1_sink_queue, + name='eth_r1_sink') + + eth_r2_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r2_rxd, + txc=eth_r2_rxc, + fifo=eth_r2_source_queue, + name='eth_r2_source') + + eth_r2_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r2_txd, + rxc=eth_r2_txc, + fifo=eth_r2_sink_queue, + name='eth_r2_sink') + + eth_r3_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r3_rxd, + txc=eth_r3_rxc, + fifo=eth_r3_source_queue, + name='eth_r3_source') + + eth_r3_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r3_txd, + rxc=eth_r3_txc, + fifo=eth_r3_sink_queue, + name='eth_r3_sink') + + eth_r4_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r4_rxd, + txc=eth_r4_rxc, + fifo=eth_r4_source_queue, + name='eth_r4_source') + + eth_r4_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r4_txd, + rxc=eth_r4_txc, + fifo=eth_r4_sink_queue, + name='eth_r4_sink') + + eth_r5_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r5_rxd, + txc=eth_r5_rxc, + fifo=eth_r5_source_queue, + name='eth_r5_source') + + eth_r5_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r5_txd, + rxc=eth_r5_txc, + fifo=eth_r5_sink_queue, + name='eth_r5_sink') + + eth_r6_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r6_rxd, + txc=eth_r6_rxc, + fifo=eth_r6_source_queue, + name='eth_r6_source') + + eth_r6_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r6_txd, + rxc=eth_r6_txc, + fifo=eth_r6_sink_queue, + name='eth_r6_sink') + + eth_r7_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r7_rxd, + txc=eth_r7_rxc, + fifo=eth_r7_source_queue, + name='eth_r7_source') + + eth_r7_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r7_txd, + rxc=eth_r7_txc, + fifo=eth_r7_sink_queue, + name='eth_r7_sink') + + eth_r8_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r8_rxd, + txc=eth_r8_rxc, + fifo=eth_r8_source_queue, + name='eth_r8_source') + + eth_r8_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r8_txd, + rxc=eth_r8_txc, + fifo=eth_r8_sink_queue, + name='eth_r8_sink') + + eth_r9_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r9_rxd, + txc=eth_r9_rxc, + fifo=eth_r9_source_queue, + name='eth_r9_source') + + eth_r9_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r9_txd, + rxc=eth_r9_txc, + fifo=eth_r9_sink_queue, + name='eth_r9_sink') + + eth_r10_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r10_rxd, + txc=eth_r10_rxc, + fifo=eth_r10_source_queue, + name='eth_r10_source') + + eth_r10_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r10_txd, + rxc=eth_r10_txc, + fifo=eth_r10_sink_queue, + name='eth_r10_sink') + + eth_r11_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r11_rxd, + txc=eth_r11_rxc, + fifo=eth_r11_source_queue, + name='eth_r11_source') + + eth_r11_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r11_txd, + rxc=eth_r11_txc, + fifo=eth_r11_sink_queue, + name='eth_r11_sink') + + eth_l0_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l0_rxd, + txc=eth_l0_rxc, + fifo=eth_l0_source_queue, + name='eth_l0_source') + + eth_l0_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l0_txd, + rxc=eth_l0_txc, + fifo=eth_l0_sink_queue, + name='eth_l0_sink') + + eth_l1_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l1_rxd, + txc=eth_l1_rxc, + fifo=eth_l1_source_queue, + name='eth_l1_source') + + eth_l1_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l1_txd, + rxc=eth_l1_txc, + fifo=eth_l1_sink_queue, + name='eth_l1_sink') + + eth_l2_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l2_rxd, + txc=eth_l2_rxc, + fifo=eth_l2_source_queue, + name='eth_l2_source') + + eth_l2_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l2_txd, + rxc=eth_l2_txc, + fifo=eth_l2_sink_queue, + name='eth_l2_sink') + + eth_l3_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l3_rxd, + txc=eth_l3_rxc, + fifo=eth_l3_source_queue, + name='eth_l3_source') + + eth_l3_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l3_txd, + rxc=eth_l3_txc, + fifo=eth_l3_sink_queue, + name='eth_l3_sink') + + eth_l4_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l4_rxd, + txc=eth_l4_rxc, + fifo=eth_l4_source_queue, + name='eth_l4_source') + + eth_l4_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l4_txd, + rxc=eth_l4_txc, + fifo=eth_l4_sink_queue, + name='eth_l4_sink') + + eth_l5_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l5_rxd, + txc=eth_l5_rxc, + fifo=eth_l5_source_queue, + name='eth_l5_source') + + eth_l5_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l5_txd, + rxc=eth_l5_txc, + fifo=eth_l5_sink_queue, + name='eth_l5_sink') + + eth_l6_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l6_rxd, + txc=eth_l6_rxc, + fifo=eth_l6_source_queue, + name='eth_l6_source') + + eth_l6_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l6_txd, + rxc=eth_l6_txc, + fifo=eth_l6_sink_queue, + name='eth_l6_sink') + + eth_l7_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l7_rxd, + txc=eth_l7_rxc, + fifo=eth_l7_source_queue, + name='eth_l7_source') + + eth_l7_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l7_txd, + rxc=eth_l7_txc, + fifo=eth_l7_sink_queue, + name='eth_l7_sink') + + eth_l8_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l8_rxd, + txc=eth_l8_rxc, + fifo=eth_l8_source_queue, + name='eth_l8_source') + + eth_l8_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l8_txd, + rxc=eth_l8_txc, + fifo=eth_l8_sink_queue, + name='eth_l8_sink') + + eth_l9_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l9_rxd, + txc=eth_l9_rxc, + fifo=eth_l9_source_queue, + name='eth_l9_source') + + eth_l9_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l9_txd, + rxc=eth_l9_txc, + fifo=eth_l9_sink_queue, + name='eth_l9_sink') + + eth_l10_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l10_rxd, + txc=eth_l10_rxc, + fifo=eth_l10_source_queue, + name='eth_l10_source') + + eth_l10_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l10_txd, + rxc=eth_l10_txc, + fifo=eth_l10_sink_queue, + name='eth_l10_sink') + + eth_l11_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l11_rxd, + txc=eth_l11_rxc, + fifo=eth_l11_source_queue, + name='eth_l11_source') + + eth_l11_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l11_txd, + rxc=eth_l11_txc, + fifo=eth_l11_sink_queue, + name='eth_l11_sink') + + # DUT + dut = dut_fpga_core(clk, + rst, + current_test, + + sw, + jp, + led, + + uart_rst, + uart_suspend, + uart_ri, + uart_dcd, + uart_dtr, + uart_dsr, + uart_txd, + uart_rxd, + uart_rts, + uart_cts, + + amh_right_mdc, + amh_right_mdio_i, + amh_right_mdio_o, + amh_right_mdio_t, + amh_left_mdc, + amh_left_mdio_i, + amh_left_mdio_o, + amh_left_mdio_t, + + eth_r0_txd, + eth_r0_txc, + eth_r0_rxd, + eth_r0_rxc, + eth_r1_txd, + eth_r1_txc, + eth_r1_rxd, + eth_r1_rxc, + eth_r2_txd, + eth_r2_txc, + eth_r2_rxd, + eth_r2_rxc, + eth_r3_txd, + eth_r3_txc, + eth_r3_rxd, + eth_r3_rxc, + eth_r4_txd, + eth_r4_txc, + eth_r4_rxd, + eth_r4_rxc, + eth_r5_txd, + eth_r5_txc, + eth_r5_rxd, + eth_r5_rxc, + eth_r6_txd, + eth_r6_txc, + eth_r6_rxd, + eth_r6_rxc, + eth_r7_txd, + eth_r7_txc, + eth_r7_rxd, + eth_r7_rxc, + eth_r8_txd, + eth_r8_txc, + eth_r8_rxd, + eth_r8_rxc, + eth_r9_txd, + eth_r9_txc, + eth_r9_rxd, + eth_r9_rxc, + eth_r10_txd, + eth_r10_txc, + eth_r10_rxd, + eth_r10_rxc, + eth_r11_txd, + eth_r11_txc, + eth_r11_rxd, + eth_r11_rxc, + eth_l0_txd, + eth_l0_txc, + eth_l0_rxd, + eth_l0_rxc, + eth_l1_txd, + eth_l1_txc, + eth_l1_rxd, + eth_l1_rxc, + eth_l2_txd, + eth_l2_txc, + eth_l2_rxd, + eth_l2_rxc, + eth_l3_txd, + eth_l3_txc, + eth_l3_rxd, + eth_l3_rxc, + eth_l4_txd, + eth_l4_txc, + eth_l4_rxd, + eth_l4_rxc, + eth_l5_txd, + eth_l5_txc, + eth_l5_rxd, + eth_l5_rxc, + eth_l6_txd, + eth_l6_txc, + eth_l6_rxd, + eth_l6_rxc, + eth_l7_txd, + eth_l7_txc, + eth_l7_rxd, + eth_l7_rxc, + eth_l8_txd, + eth_l8_txc, + eth_l8_rxd, + eth_l8_rxc, + eth_l9_txd, + eth_l9_txc, + eth_l9_rxd, + eth_l9_rxc, + eth_l10_txd, + eth_l10_txc, + eth_l10_rxd, + eth_l10_rxc, + eth_l11_txd, + eth_l11_txc, + eth_l11_rxd, + eth_l11_rxc) + + @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 + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + eth_l0_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while eth_l0_sink_queue.empty(): + yield clk.posedge + + rx_frame = eth_l0_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + eth_l0_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while eth_l0_sink_queue.empty(): + yield clk.posedge + + rx_frame = eth_l0_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert eth_l0_source_queue.empty() + assert eth_l0_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return (dut, clkgen, check, eth_r0_source, eth_r0_sink, eth_r1_source, eth_r1_sink, eth_r2_source, eth_r2_sink, + eth_r3_source, eth_r3_sink, eth_r4_source, eth_r4_sink, eth_r5_source, eth_r5_sink, + eth_r6_source, eth_r6_sink, eth_r7_source, eth_r7_sink, eth_r8_source, eth_r8_sink, + eth_r9_source, eth_r9_sink, eth_r10_source, eth_r10_sink, eth_r11_source, eth_r11_sink, + eth_l0_source, eth_l0_sink, eth_l1_source, eth_l1_sink, eth_l2_source, eth_l2_sink, + eth_l3_source, eth_l3_sink, eth_l4_source, eth_l4_sink, eth_l5_source, eth_l5_sink, + eth_l6_source, eth_l6_sink, eth_l7_source, eth_l7_sink, eth_l8_source, eth_l8_sink, + eth_l9_source, eth_l9_sink, eth_l10_source, eth_l10_sink, eth_l11_source, eth_l11_sink) + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/HXT100G/fpga/tb/test_fpga_core.v b/example/HXT100G/fpga/tb/test_fpga_core.v new file mode 100644 index 000000000..7ce2dfa98 --- /dev/null +++ b/example/HXT100G/fpga/tb/test_fpga_core.v @@ -0,0 +1,412 @@ +/* + +Copyright (c) 2016 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [1:0] sw = 0; +reg [3:0] jp = 0; +reg uart_suspend = 0; +reg uart_dtr = 0; +reg uart_txd = 0; +reg uart_rts = 0; +reg amh_right_mdio_i = 0; +reg amh_left_mdio_i = 0; +reg [63:0] eth_r0_rxd = 0; +reg [7:0] eth_r0_rxc = 0; +reg [63:0] eth_r1_rxd = 0; +reg [7:0] eth_r1_rxc = 0; +reg [63:0] eth_r2_rxd = 0; +reg [7:0] eth_r2_rxc = 0; +reg [63:0] eth_r3_rxd = 0; +reg [7:0] eth_r3_rxc = 0; +reg [63:0] eth_r4_rxd = 0; +reg [7:0] eth_r4_rxc = 0; +reg [63:0] eth_r5_rxd = 0; +reg [7:0] eth_r5_rxc = 0; +reg [63:0] eth_r6_rxd = 0; +reg [7:0] eth_r6_rxc = 0; +reg [63:0] eth_r7_rxd = 0; +reg [7:0] eth_r7_rxc = 0; +reg [63:0] eth_r8_rxd = 0; +reg [7:0] eth_r8_rxc = 0; +reg [63:0] eth_r9_rxd = 0; +reg [7:0] eth_r9_rxc = 0; +reg [63:0] eth_r10_rxd = 0; +reg [7:0] eth_r10_rxc = 0; +reg [63:0] eth_r11_rxd = 0; +reg [7:0] eth_r11_rxc = 0; +reg [63:0] eth_l0_rxd = 0; +reg [7:0] eth_l0_rxc = 0; +reg [63:0] eth_l1_rxd = 0; +reg [7:0] eth_l1_rxc = 0; +reg [63:0] eth_l2_rxd = 0; +reg [7:0] eth_l2_rxc = 0; +reg [63:0] eth_l3_rxd = 0; +reg [7:0] eth_l3_rxc = 0; +reg [63:0] eth_l4_rxd = 0; +reg [7:0] eth_l4_rxc = 0; +reg [63:0] eth_l5_rxd = 0; +reg [7:0] eth_l5_rxc = 0; +reg [63:0] eth_l6_rxd = 0; +reg [7:0] eth_l6_rxc = 0; +reg [63:0] eth_l7_rxd = 0; +reg [7:0] eth_l7_rxc = 0; +reg [63:0] eth_l8_rxd = 0; +reg [7:0] eth_l8_rxc = 0; +reg [63:0] eth_l9_rxd = 0; +reg [7:0] eth_l9_rxc = 0; +reg [63:0] eth_l10_rxd = 0; +reg [7:0] eth_l10_rxc = 0; +reg [63:0] eth_l11_rxd = 0; +reg [7:0] eth_l11_rxc = 0; + +// Outputs +wire [3:0] led; +wire uart_rst; +wire uart_ri; +wire uart_dcd; +wire uart_dsr; +wire uart_rxd; +wire uart_cts; +wire amh_right_mdc; +wire amh_right_mdio_o; +wire amh_right_mdio_t; +wire amh_left_mdc; +wire amh_left_mdio_o; +wire amh_left_mdio_t; +wire [63:0] eth_r0_txd; +wire [7:0] eth_r0_txc; +wire [63:0] eth_r1_txd; +wire [7:0] eth_r1_txc; +wire [63:0] eth_r2_txd; +wire [7:0] eth_r2_txc; +wire [63:0] eth_r3_txd; +wire [7:0] eth_r3_txc; +wire [63:0] eth_r4_txd; +wire [7:0] eth_r4_txc; +wire [63:0] eth_r5_txd; +wire [7:0] eth_r5_txc; +wire [63:0] eth_r6_txd; +wire [7:0] eth_r6_txc; +wire [63:0] eth_r7_txd; +wire [7:0] eth_r7_txc; +wire [63:0] eth_r8_txd; +wire [7:0] eth_r8_txc; +wire [63:0] eth_r9_txd; +wire [7:0] eth_r9_txc; +wire [63:0] eth_r10_txd; +wire [7:0] eth_r10_txc; +wire [63:0] eth_r11_txd; +wire [7:0] eth_r11_txc; +wire [63:0] eth_l0_txd; +wire [7:0] eth_l0_txc; +wire [63:0] eth_l1_txd; +wire [7:0] eth_l1_txc; +wire [63:0] eth_l2_txd; +wire [7:0] eth_l2_txc; +wire [63:0] eth_l3_txd; +wire [7:0] eth_l3_txc; +wire [63:0] eth_l4_txd; +wire [7:0] eth_l4_txc; +wire [63:0] eth_l5_txd; +wire [7:0] eth_l5_txc; +wire [63:0] eth_l6_txd; +wire [7:0] eth_l6_txc; +wire [63:0] eth_l7_txd; +wire [7:0] eth_l7_txc; +wire [63:0] eth_l8_txd; +wire [7:0] eth_l8_txc; +wire [63:0] eth_l9_txd; +wire [7:0] eth_l9_txc; +wire [63:0] eth_l10_txd; +wire [7:0] eth_l10_txc; +wire [63:0] eth_l11_txd; +wire [7:0] eth_l11_txc; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + sw, + jp, + uart_suspend, + uart_dtr, + uart_txd, + uart_rts, + amh_right_mdio_i, + amh_left_mdio_i, + eth_r0_rxd, + eth_r0_rxc, + eth_r1_rxd, + eth_r1_rxc, + eth_r2_rxd, + eth_r2_rxc, + eth_r3_rxd, + eth_r3_rxc, + eth_r4_rxd, + eth_r4_rxc, + eth_r5_rxd, + eth_r5_rxc, + eth_r6_rxd, + eth_r6_rxc, + eth_r7_rxd, + eth_r7_rxc, + eth_r8_rxd, + eth_r8_rxc, + eth_r9_rxd, + eth_r9_rxc, + eth_r10_rxd, + eth_r10_rxc, + eth_r11_rxd, + eth_r11_rxc, + eth_l0_rxd, + eth_l0_rxc, + eth_l1_rxd, + eth_l1_rxc, + eth_l2_rxd, + eth_l2_rxc, + eth_l3_rxd, + eth_l3_rxc, + eth_l4_rxd, + eth_l4_rxc, + eth_l5_rxd, + eth_l5_rxc, + eth_l6_rxd, + eth_l6_rxc, + eth_l7_rxd, + eth_l7_rxc, + eth_l8_rxd, + eth_l8_rxc, + eth_l9_rxd, + eth_l9_rxc, + eth_l10_rxd, + eth_l10_rxc, + eth_l11_rxd, + eth_l11_rxc); + $to_myhdl(led, + uart_rst, + uart_ri, + uart_dcd, + uart_dsr, + uart_rxd, + uart_cts, + amh_right_mdc, + amh_right_mdio_o, + amh_right_mdio_t, + amh_left_mdc, + amh_left_mdio_o, + amh_left_mdio_t, + eth_r0_txd, + eth_r0_txc, + eth_r1_txd, + eth_r1_txc, + eth_r2_txd, + eth_r2_txc, + eth_r3_txd, + eth_r3_txc, + eth_r4_txd, + eth_r4_txc, + eth_r5_txd, + eth_r5_txc, + eth_r6_txd, + eth_r6_txc, + eth_r7_txd, + eth_r7_txc, + eth_r8_txd, + eth_r8_txc, + eth_r9_txd, + eth_r9_txc, + eth_r10_txd, + eth_r10_txc, + eth_r11_txd, + eth_r11_txc, + eth_l0_txd, + eth_l0_txc, + eth_l1_txd, + eth_l1_txc, + eth_l2_txd, + eth_l2_txc, + eth_l3_txd, + eth_l3_txc, + eth_l4_txd, + eth_l4_txc, + eth_l5_txd, + eth_l5_txc, + eth_l6_txd, + eth_l6_txc, + eth_l7_txd, + eth_l7_txc, + eth_l8_txd, + eth_l8_txc, + eth_l9_txd, + eth_l9_txc, + eth_l10_txd, + eth_l10_txc, + eth_l11_txd, + eth_l11_txc); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .sw(sw), + .jp(jp), + .led(led), + .uart_rst(uart_rst), + .uart_suspend(uart_suspend), + .uart_ri(uart_ri), + .uart_dcd(uart_dcd), + .uart_dtr(uart_dtr), + .uart_dsr(uart_dsr), + .uart_txd(uart_txd), + .uart_rxd(uart_rxd), + .uart_rts(uart_rts), + .uart_cts(uart_cts), + .amh_right_mdc(amh_right_mdc), + .amh_right_mdio_i(amh_right_mdio_i), + .amh_right_mdio_o(amh_right_mdio_o), + .amh_right_mdio_t(amh_right_mdio_t), + .amh_left_mdc(amh_left_mdc), + .amh_left_mdio_i(amh_left_mdio_i), + .amh_left_mdio_o(amh_left_mdio_o), + .amh_left_mdio_t(amh_left_mdio_t), + .eth_r0_txd(eth_r0_txd), + .eth_r0_txc(eth_r0_txc), + .eth_r0_rxd(eth_r0_rxd), + .eth_r0_rxc(eth_r0_rxc), + .eth_r1_txd(eth_r1_txd), + .eth_r1_txc(eth_r1_txc), + .eth_r1_rxd(eth_r1_rxd), + .eth_r1_rxc(eth_r1_rxc), + .eth_r2_txd(eth_r2_txd), + .eth_r2_txc(eth_r2_txc), + .eth_r2_rxd(eth_r2_rxd), + .eth_r2_rxc(eth_r2_rxc), + .eth_r3_txd(eth_r3_txd), + .eth_r3_txc(eth_r3_txc), + .eth_r3_rxd(eth_r3_rxd), + .eth_r3_rxc(eth_r3_rxc), + .eth_r4_txd(eth_r4_txd), + .eth_r4_txc(eth_r4_txc), + .eth_r4_rxd(eth_r4_rxd), + .eth_r4_rxc(eth_r4_rxc), + .eth_r5_txd(eth_r5_txd), + .eth_r5_txc(eth_r5_txc), + .eth_r5_rxd(eth_r5_rxd), + .eth_r5_rxc(eth_r5_rxc), + .eth_r6_txd(eth_r6_txd), + .eth_r6_txc(eth_r6_txc), + .eth_r6_rxd(eth_r6_rxd), + .eth_r6_rxc(eth_r6_rxc), + .eth_r7_txd(eth_r7_txd), + .eth_r7_txc(eth_r7_txc), + .eth_r7_rxd(eth_r7_rxd), + .eth_r7_rxc(eth_r7_rxc), + .eth_r8_txd(eth_r8_txd), + .eth_r8_txc(eth_r8_txc), + .eth_r8_rxd(eth_r8_rxd), + .eth_r8_rxc(eth_r8_rxc), + .eth_r9_txd(eth_r9_txd), + .eth_r9_txc(eth_r9_txc), + .eth_r9_rxd(eth_r9_rxd), + .eth_r9_rxc(eth_r9_rxc), + .eth_r10_txd(eth_r10_txd), + .eth_r10_txc(eth_r10_txc), + .eth_r10_rxd(eth_r10_rxd), + .eth_r10_rxc(eth_r10_rxc), + .eth_r11_txd(eth_r11_txd), + .eth_r11_txc(eth_r11_txc), + .eth_r11_rxd(eth_r11_rxd), + .eth_r11_rxc(eth_r11_rxc), + .eth_l0_txd(eth_l0_txd), + .eth_l0_txc(eth_l0_txc), + .eth_l0_rxd(eth_l0_rxd), + .eth_l0_rxc(eth_l0_rxc), + .eth_l1_txd(eth_l1_txd), + .eth_l1_txc(eth_l1_txc), + .eth_l1_rxd(eth_l1_rxd), + .eth_l1_rxc(eth_l1_rxc), + .eth_l2_txd(eth_l2_txd), + .eth_l2_txc(eth_l2_txc), + .eth_l2_rxd(eth_l2_rxd), + .eth_l2_rxc(eth_l2_rxc), + .eth_l3_txd(eth_l3_txd), + .eth_l3_txc(eth_l3_txc), + .eth_l3_rxd(eth_l3_rxd), + .eth_l3_rxc(eth_l3_rxc), + .eth_l4_txd(eth_l4_txd), + .eth_l4_txc(eth_l4_txc), + .eth_l4_rxd(eth_l4_rxd), + .eth_l4_rxc(eth_l4_rxc), + .eth_l5_txd(eth_l5_txd), + .eth_l5_txc(eth_l5_txc), + .eth_l5_rxd(eth_l5_rxd), + .eth_l5_rxc(eth_l5_rxc), + .eth_l6_txd(eth_l6_txd), + .eth_l6_txc(eth_l6_txc), + .eth_l6_rxd(eth_l6_rxd), + .eth_l6_rxc(eth_l6_rxc), + .eth_l7_txd(eth_l7_txd), + .eth_l7_txc(eth_l7_txc), + .eth_l7_rxd(eth_l7_rxd), + .eth_l7_rxc(eth_l7_rxc), + .eth_l8_txd(eth_l8_txd), + .eth_l8_txc(eth_l8_txc), + .eth_l8_rxd(eth_l8_rxd), + .eth_l8_rxc(eth_l8_rxc), + .eth_l9_txd(eth_l9_txd), + .eth_l9_txc(eth_l9_txc), + .eth_l9_rxd(eth_l9_rxd), + .eth_l9_rxc(eth_l9_rxc), + .eth_l10_txd(eth_l10_txd), + .eth_l10_txc(eth_l10_txc), + .eth_l10_rxd(eth_l10_rxd), + .eth_l10_rxc(eth_l10_rxc), + .eth_l11_txd(eth_l11_txd), + .eth_l11_txc(eth_l11_txc), + .eth_l11_rxd(eth_l11_rxd), + .eth_l11_rxc(eth_l11_rxc) +); + +endmodule diff --git a/example/HXT100G/fpga/tb/udp_ep.py b/example/HXT100G/fpga/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/HXT100G/fpga/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga/tb/xgmii_ep.py b/example/HXT100G/fpga/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/example/HXT100G/fpga/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file From b1dca3b57a21ac154b140c7619ded8d91a616316 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 12 Feb 2016 18:27:54 -0800 Subject: [PATCH 272/617] Add missing declaration --- example/HXT100G/fpga/rtl/eth_gth_phy_quad.v | 2 ++ 1 file changed, 2 insertions(+) diff --git a/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v b/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v index be42ab256..fbf134ba5 100644 --- a/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v +++ b/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v @@ -223,6 +223,8 @@ always @(posedge clk156) begin gth_reset_done_reg <= resetdone_0 & resetdone_1 & resetdone_2 & resetdone_3; end +wire disable_drp_mgmt; + wire disable_drp = gth_reset_done & disable_drp_mgmt; wire lane_sel = {mgmt_gnt3, mgmt_gnt2, mgmt_gnt1, mgmt_gnt0}; From cab7d367f2f571c24a999fc65f933d32faa7f6f5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 27 Jun 2016 11:24:36 -0700 Subject: [PATCH 273/617] Fix default width --- rtl/axis_frame_length_adjust_fifo_64.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/axis_frame_length_adjust_fifo_64.v b/rtl/axis_frame_length_adjust_fifo_64.v index eb55d62ba..b5728c6b0 100644 --- a/rtl/axis_frame_length_adjust_fifo_64.v +++ b/rtl/axis_frame_length_adjust_fifo_64.v @@ -31,7 +31,7 @@ THE SOFTWARE. */ module axis_frame_length_adjust_fifo_64 # ( - parameter DATA_WIDTH = 8, + parameter DATA_WIDTH = 64, parameter KEEP_WIDTH = (DATA_WIDTH/8), parameter FRAME_FIFO_ADDR_WIDTH = 12, parameter HEADER_FIFO_ADDR_WIDTH = 3 From f89620008dff35d5599a26f28d9afb0419880677 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 27 Jun 2016 11:26:15 -0700 Subject: [PATCH 274/617] Remove reset dependence --- rtl/axis_srl_fifo.v | 14 +++++++------- rtl/axis_srl_fifo_64.v | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/rtl/axis_srl_fifo.v b/rtl/axis_srl_fifo.v index 236e7585a..5f70a07e4 100644 --- a/rtl/axis_srl_fifo.v +++ b/rtl/axis_srl_fifo.v @@ -118,13 +118,6 @@ always @(posedge clk) begin full_reg <= 0; empty_reg <= 1; 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 @@ -136,6 +129,13 @@ always @(posedge clk) begin full_reg <= full_next; empty_reg <= empty_next; end + + 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 end endmodule diff --git a/rtl/axis_srl_fifo_64.v b/rtl/axis_srl_fifo_64.v index 761e5617a..75736aa42 100644 --- a/rtl/axis_srl_fifo_64.v +++ b/rtl/axis_srl_fifo_64.v @@ -121,13 +121,6 @@ always @(posedge clk) begin full_reg <= 0; empty_reg <= 1; 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 @@ -139,6 +132,13 @@ always @(posedge clk) begin full_reg <= full_next; empty_reg <= empty_next; end + + 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 end endmodule From 4f66059d21fde3b6a29560d4bca036f630893762 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 27 Jun 2016 11:27:04 -0700 Subject: [PATCH 275/617] Adjust constant naming --- rtl/axis_adapter.v | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index 3ed7e7053..bdc08c07f 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -61,9 +61,9 @@ module axis_adapter # output wire output_axis_tuser ); -// bus word widths (must be identical) -localparam INPUT_DATA_WORD_WIDTH = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH; -localparam OUTPUT_DATA_WORD_WIDTH = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH; +// bus word sizes (must be identical) +localparam INPUT_DATA_WORD_SIZE = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH; +localparam OUTPUT_DATA_WORD_SIZE = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH; // output bus is wider localparam EXPAND_BUS = OUTPUT_KEEP_WIDTH > INPUT_KEEP_WIDTH; // total data and keep widths @@ -77,18 +77,18 @@ localparam CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT; // bus width assertions initial begin - if (INPUT_DATA_WORD_WIDTH * INPUT_KEEP_WIDTH != INPUT_DATA_WIDTH) begin + if (INPUT_DATA_WORD_SIZE * INPUT_KEEP_WIDTH != INPUT_DATA_WIDTH) begin $error("Error: input data width not evenly divisble"); $finish; end - if (OUTPUT_DATA_WORD_WIDTH * OUTPUT_KEEP_WIDTH != OUTPUT_DATA_WIDTH) begin + if (OUTPUT_DATA_WORD_SIZE * OUTPUT_KEEP_WIDTH != OUTPUT_DATA_WIDTH) begin $error("Error: output data width not evenly divisble"); $finish; end - if (INPUT_DATA_WORD_WIDTH != OUTPUT_DATA_WORD_WIDTH) begin - $error("Error: word width mismatch"); + if (INPUT_DATA_WORD_SIZE != OUTPUT_DATA_WORD_SIZE) begin + $error("Error: word size mismatch"); $finish; end end From 385c9cc90ade29878d45e6634e2c70ce85d6d6d5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 27 Jun 2016 12:10:36 -0700 Subject: [PATCH 276/617] Fix Vivado block RAM inference --- rtl/axis_async_fifo.v | 15 +++++++-------- rtl/axis_async_fifo_64.v | 17 +++++++---------- rtl/axis_async_frame_fifo.v | 13 +++++++------ rtl/axis_async_frame_fifo_64.v | 15 +++++++-------- rtl/axis_fifo.v | 15 +++++++-------- rtl/axis_fifo_64.v | 17 +++++++---------- rtl/axis_frame_fifo.v | 13 +++++++------ rtl/axis_frame_fifo_64.v | 15 +++++++-------- 8 files changed, 56 insertions(+), 64 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 90ce78ca6..f391a980d 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -79,11 +79,10 @@ reg output_rst_sync2_reg = 1'b1; reg output_rst_sync3_reg = 1'b1; reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [DATA_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +wire [DATA_WIDTH+2-1:0] mem_write_data; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) @@ -99,10 +98,10 @@ reg read; assign input_axis_tready = ~full & ~input_rst_sync3_reg; -assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; + +assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; +assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = mem_read_data_reg; // reset synchronization always @(posedge input_clk or posedge async_rst) begin @@ -157,7 +156,7 @@ always @(posedge input_clk) begin end if (write) begin - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tuser, input_axis_tdata}; + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -217,7 +216,7 @@ always @(posedge output_clk) begin end if (read) begin - {output_axis_tlast_reg, output_axis_tuser_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index c6976ec39..7ee878a60 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -82,12 +82,10 @@ reg output_rst_sync2_reg = 1'b1; reg output_rst_sync3_reg = 1'b1; reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_write_data; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) @@ -103,11 +101,10 @@ reg read; assign input_axis_tready = ~full & ~input_rst_sync3_reg; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; + +assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; +assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = mem_read_data_reg; // reset synchronization always @(posedge input_clk or posedge async_rst) begin @@ -162,7 +159,7 @@ always @(posedge input_clk) begin end if (write) begin - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -222,7 +219,7 @@ always @(posedge output_clk) begin end if (read) begin - {output_axis_tlast_reg, output_axis_tuser_reg, output_axis_tkeep_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 335458759..53525042b 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -90,10 +90,10 @@ reg output_rst_sync2_reg = 1'b1; reg output_rst_sync3_reg = 1'b1; reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [DATA_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +wire [DATA_WIDTH+1-1:0] mem_write_data; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) @@ -130,9 +130,10 @@ reg good_frame_sync4_reg = 1'b0; assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3_reg; -assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; + +assign mem_write_data = {input_axis_tlast, input_axis_tdata}; +assign {output_axis_tlast, output_axis_tdata} = mem_read_data_reg; assign input_status_overflow = overflow_reg; assign input_status_bad_frame = bad_frame_reg; @@ -237,7 +238,7 @@ always @(posedge input_clk) begin end if (write) begin - mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tdata}; + mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -331,7 +332,7 @@ always @(posedge output_clk) begin end if (read) begin - {output_axis_tlast_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index ada9f6401..5409c89a0 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -93,11 +93,10 @@ reg output_rst_sync2_reg = 1'b1; reg output_rst_sync3_reg = 1'b1; reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +wire [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_write_data; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) @@ -134,10 +133,10 @@ reg good_frame_sync4_reg = 1'b0; assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3_reg; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; + +assign mem_write_data = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; +assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = mem_read_data_reg; assign input_status_overflow = overflow_reg; assign input_status_bad_frame = bad_frame_reg; @@ -242,7 +241,7 @@ always @(posedge input_clk) begin end if (write) begin - mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; + mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -336,7 +335,7 @@ always @(posedge output_clk) begin end if (read) begin - {output_axis_tlast_reg, output_axis_tkeep_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index 2784059e5..ded9e1563 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -61,11 +61,10 @@ reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [DATA_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +wire [DATA_WIDTH+2-1:0] mem_write_data; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; // full when first MSB different but rest same wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && @@ -79,10 +78,10 @@ reg read; assign input_axis_tready = ~full; -assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; + +assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; +assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = mem_read_data_reg; // Write logic always @* begin @@ -108,7 +107,7 @@ always @(posedge clk) begin end if (write) begin - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tuser, input_axis_tdata}; + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -143,7 +142,7 @@ always @(posedge clk) begin end if (read) begin - {output_axis_tlast_reg, output_axis_tuser_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v index decd34b2d..0cf739ea9 100644 --- a/rtl/axis_fifo_64.v +++ b/rtl/axis_fifo_64.v @@ -64,12 +64,10 @@ reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_write_data; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; // full when first MSB different but rest same wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && @@ -83,11 +81,10 @@ reg read; assign input_axis_tready = ~full; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; + +assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; +assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = mem_read_data_reg; // FIFO write logic always @* begin @@ -113,7 +110,7 @@ always @(posedge clk) begin end if (write) begin - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -149,7 +146,7 @@ always @(posedge clk) begin end if (read) begin - {output_axis_tlast_reg, output_axis_tuser_reg, output_axis_tkeep_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index bc5e4fb24..8af803f51 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -69,10 +69,10 @@ reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [DATA_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +wire [DATA_WIDTH+1-1:0] mem_write_data; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; // full when first MSB different but rest same wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && @@ -94,9 +94,10 @@ reg good_frame_reg = 1'b0, good_frame_next; assign input_axis_tready = (~full | DROP_WHEN_FULL); -assign output_axis_tdata = output_axis_tdata_reg; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; + +assign mem_write_data = {input_axis_tlast, input_axis_tdata}; +assign {output_axis_tlast, output_axis_tdata} = mem_read_data_reg; assign overflow = overflow_reg; assign bad_frame = bad_frame_reg; @@ -168,7 +169,7 @@ always @(posedge clk) begin end if (write) begin - mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tdata}; + mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -204,7 +205,7 @@ always @(posedge clk) begin end if (read) begin - {output_axis_tlast_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index 9526da8a4..20a292007 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -72,11 +72,10 @@ reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +wire [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_write_data; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; // full when first MSB different but rest same wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && @@ -98,10 +97,10 @@ reg good_frame_reg = 1'b0, good_frame_next; assign input_axis_tready = (~full | DROP_WHEN_FULL); -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; + +assign mem_write_data = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; +assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = mem_read_data_reg; assign overflow = overflow_reg; assign bad_frame = bad_frame_reg; @@ -173,7 +172,7 @@ always @(posedge clk) begin end if (write) begin - mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; + mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -208,7 +207,7 @@ always @(posedge clk) begin end if (read) begin - {output_axis_tlast_reg, output_axis_tkeep_reg, output_axis_tdata_reg} <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; end end From 6fe4a033e59828ee4353fee895dd6fd6ab226a0c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 27 Jun 2016 12:25:18 -0700 Subject: [PATCH 277/617] Add dedicated pipeline registers for RAM addresses that are not reset --- rtl/axis_async_fifo.v | 10 ++++++++-- rtl/axis_async_fifo_64.v | 10 ++++++++-- rtl/axis_async_frame_fifo.v | 10 ++++++++-- rtl/axis_async_frame_fifo_64.v | 10 ++++++++-- rtl/axis_fifo.v | 10 ++++++++-- rtl/axis_fifo_64.v | 10 ++++++++-- rtl/axis_frame_fifo.v | 10 ++++++++-- rtl/axis_frame_fifo_64.v | 10 ++++++++-- 8 files changed, 64 insertions(+), 16 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index f391a980d..f7542281e 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -63,8 +63,10 @@ module axis_async_fifo # reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; +reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; +reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; @@ -155,8 +157,10 @@ always @(posedge input_clk) begin wr_ptr_gray_reg <= wr_ptr_gray_next; end + wr_addr_reg <= wr_ptr_next; + if (write) begin - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -215,8 +219,10 @@ always @(posedge output_clk) begin output_axis_tvalid_reg <= output_axis_tvalid_next; end + rd_addr_reg <= rd_ptr_next; + if (read) begin - mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index 7ee878a60..510d38c4b 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -66,8 +66,10 @@ module axis_async_fifo_64 # reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; +reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; +reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; @@ -158,8 +160,10 @@ always @(posedge input_clk) begin wr_ptr_gray_reg <= wr_ptr_gray_next; end + wr_addr_reg <= wr_ptr_next; + if (write) begin - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -218,8 +222,10 @@ always @(posedge output_clk) begin output_axis_tvalid_reg <= output_axis_tvalid_next; end + rd_addr_reg <= rd_ptr_next; + if (read) begin - mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 53525042b..98d1d87ee 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -74,8 +74,10 @@ module axis_async_frame_fifo # reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; +reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; +reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; @@ -237,8 +239,10 @@ always @(posedge input_clk) begin good_frame_reg <= good_frame_next; end + wr_addr_reg <= wr_ptr_cur_next; + if (write) begin - mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -331,8 +335,10 @@ always @(posedge output_clk) begin output_axis_tvalid_reg <= output_axis_tvalid_next; end + rd_addr_reg <= rd_ptr_next; + if (read) begin - mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 5409c89a0..0e63c4ae5 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -77,8 +77,10 @@ module axis_async_frame_fifo_64 # reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; +reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; +reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; @@ -240,8 +242,10 @@ always @(posedge input_clk) begin good_frame_reg <= good_frame_next; end + wr_addr_reg <= wr_ptr_cur_next; + if (write) begin - mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -334,8 +338,10 @@ always @(posedge output_clk) begin output_axis_tvalid_reg <= output_axis_tvalid_next; end + rd_addr_reg <= rd_ptr_next; + if (read) begin - mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index ded9e1563..7bb040d24 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -58,7 +58,9 @@ module axis_fifo # ); reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; reg [DATA_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; @@ -106,8 +108,10 @@ always @(posedge clk) begin wr_ptr_reg <= wr_ptr_next; end + wr_addr_reg <= wr_ptr_next; + if (write) begin - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -141,8 +145,10 @@ always @(posedge clk) begin output_axis_tvalid_reg <= output_axis_tvalid_next; end + rd_addr_reg <= rd_ptr_next; + if (read) begin - mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v index 0cf739ea9..37f627a0e 100644 --- a/rtl/axis_fifo_64.v +++ b/rtl/axis_fifo_64.v @@ -61,7 +61,9 @@ module axis_fifo_64 # ); reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; @@ -109,8 +111,10 @@ always @(posedge clk) begin wr_ptr_reg <= wr_ptr_next; end + wr_addr_reg <= wr_ptr_next; + if (write) begin - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -145,8 +149,10 @@ always @(posedge clk) begin output_axis_tvalid_reg <= output_axis_tvalid_next; end + rd_addr_reg <= rd_ptr_next; + if (read) begin - mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 8af803f51..8c2105dbe 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -66,7 +66,9 @@ module axis_frame_fifo # reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; +reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; reg [DATA_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; @@ -168,8 +170,10 @@ always @(posedge clk) begin good_frame_reg <= good_frame_next; end + wr_addr_reg <= wr_ptr_cur_next; + if (write) begin - mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -204,8 +208,10 @@ always @(posedge clk) begin output_axis_tvalid_reg <= output_axis_tvalid_next; end + rd_addr_reg <= rd_ptr_next; + if (read) begin - mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; end end diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index 20a292007..c38ef7665 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -69,7 +69,9 @@ module axis_frame_fifo_64 # reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; +reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; +reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; @@ -171,8 +173,10 @@ always @(posedge clk) begin good_frame_reg <= good_frame_next; end + wr_addr_reg <= wr_ptr_cur_next; + if (write) begin - mem[wr_ptr_cur_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; end end @@ -206,8 +210,10 @@ always @(posedge clk) begin output_axis_tvalid_reg <= output_axis_tvalid_next; end + rd_addr_reg <= rd_ptr_next; + if (read) begin - mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; end end From ccd8cd8c2e520e004c6a375caa19a1730b24130c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Jun 2016 17:25:09 -0700 Subject: [PATCH 278/617] Add generic LFSR module --- rtl/lfsr.v | 346 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 rtl/lfsr.v diff --git a/rtl/lfsr.v b/rtl/lfsr.v new file mode 100644 index 000000000..7a92182be --- /dev/null +++ b/rtl/lfsr.v @@ -0,0 +1,346 @@ +/* + +Copyright (c) 2016 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 + +/* + * Parametrizable combinatorial parallel LFSR/CRC + */ +module lfsr # +( + // width of LFSR + parameter LFSR_WIDTH = 31, + // LFSR polynomial + parameter LFSR_POLY = 31'h10000001, + // LFSR configuration: "GALOIS", "FIBONACCI" + parameter LFSR_CONFIG = "FIBONACCI", + // bit-reverse input and output + parameter REVERSE = 0, + // width of data input + parameter DATA_WIDTH = 8, + // width of CRC/LFSR output + parameter OUTPUT_WIDTH = LFSR_WIDTH, + // implementation style: "AUTO", "LOOP", "REDUCTION" + parameter STYLE = "AUTO" +) +( + input wire [DATA_WIDTH-1:0] data_in, + input wire [LFSR_WIDTH-1:0] lfsr_in, + output wire [OUTPUT_WIDTH-1:0] lfsr_out +); + +/* + +Fully parametrizable combinatorial parallel LFSR/CRC module. Implements an unrolled LFSR +next state computation, shifting DATA_WIDTH bits per pass through the module. Input data +is XORed with LFSR feedback path, tie data_in to zero if this is not required. + +Works in two parts: statically computes a set of bit masks, then uses these bit masks to +select bits for XORing to compute the next state. + +Ports: + +data_in + +Data bits to be XORed with the LFSR feedback path (DATA_WIDTH bits) + +lfsr_in + +LFSR/CRC current state input (LFSR_WIDTH bits) + +lfsr_out + +LFSR/CRC next state output (OUTPUT_WIDTH bits) + +Parameters: + +LFSR_WIDTH + +Specify width of LFSR/CRC register + +LFSR_POLY + +Specify the LFSR/CRC polynomial in hex format. For example, the polynomial + +x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + +would be represented as + +32'h04c11db7 + +Note that the largest term (x^32) is suppressed. This term is generated automatically based +on LFSR_WIDTH. + +LFSR_CONFIG + +Specify the LFSR configuration, either Fibonacci or Galois. Fibonacci is generally used +for linear-feedback shift registers (LFSR) for pseudorandom binary sequence (PRBS) generators, +scramblers, and descrambers, while Galois is generally used for cyclic redundancy check +generators and checkers. + +Fibonacci style (example for 64b66b scrambler, 0x8000000001) + + ,-----------------------------(+)<------------------------------, + | ^ | + | .----. .----. .----. | .----. .----. .----. | + `->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |->(+)<-DIN (MSB first) + '----' '----' '----' '----' '----' '----' + +Galois style (example for CRC16, 0x8005) + + ,-------------------+---------------------------------+------------, + | | | | + | .----. .----. V .----. .----. .----. V .----. | + `->| 0 |->| 1 |->(+)->| 2 |->| 3 |->...->| 14 |->(+)->| 15 |->(+)<-DIN (MSB first) + '----' '----' '----' '----' '----' '----' + +REVERSE + +Bit-reverse LFSR input and output. + +DATA_WIDTH + +Specify width of input data bus. The module will perform one shift per input data bit, +so if the input data bus is not required tie data_in to zero and set DATA_WIDTH to the +required number of shifts per clock cycle. + +OUTPUT_WIDTH + +Specify width of output data bus. Defaults to LFSR_WIDTH. Mainly useful for extending +the output width for LFSRs. Ensure that lfsr_out is properly shifted and truncated so +that feeding it back around to lfsr_in produces the expected result. Note that if +OUTPUT_WIDTH is smaller than LFSR_WIDTH, it may not be possible to get the LFSR to +feed back correctly. + +STYLE + +Specify implementation style. Can be "AUTO", "LOOP", or "REDUCTION". When "AUTO" +is selected, implemenation will be "LOOP" or "REDUCTION" based on synthesis translate +directives. "REDUCTION" and "LOOP" are functionally identical, however they simulate +and synthesize differently. "REDUCTION" is implemented with a loop over a Verilog +reduction operator. "LOOP" is implemented as a doubly-nested loop with no reduction +operator. "REDUCTION" is very fast for simulation in iverilog and synthesizes well in +Quartus but synthesizes poorly in ISE, likely due to large inferred XOR gates causing +problems with the optimizer. "LOOP" synthesizes will in both ISE and Quartus. "AUTO" +will default to "REDUCTION" when simulating and "LOOP" for synthesizers that obey +synthesis translate directives. + +Settings for common LFSR/CRC implementations: + +Name Configuration Length Polynomial Initial value Notes +CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output +PRBS6 Fibonacci 6 6'h21 any +PRBS7 Fibonacci 7 7'h41 amy +PRBS9 Fibonacci 9 9'h021 any ITU V.52 +PRBS10 Fibonacci 10 10'h081 any ITU +PRBS11 Fibonacci 11 11'h201 any ITU O.152 +PRBS15 Fibonacci 15 15'h4001 any ITU O.152 +PRBS17 Fibonacci 17 17'h04001 any +PRBS20 Fibonacci 20 20'h00009 any ITU V.57 +PRBS23 Fibonacci 23 23'h040001 any ITU O.151 +PRBS31 Fibonacci 31 31'h10000001 any +64b66b Fibonacci 58 58'h8000000001 any 10G Ethernet +128b130b Fibonacci 23 23'h210125 any PCIe gen 3 + +*/ + +// STATE_WIDTH is OUTPUT_WIDTH or LFSR_WIDTH, whichever is larger +parameter STATE_WIDTH = OUTPUT_WIDTH > LFSR_WIDTH ? OUTPUT_WIDTH : LFSR_WIDTH; + +reg [LFSR_WIDTH-1:0] lfsr_mask_state[STATE_WIDTH-1:0]; +reg [DATA_WIDTH-1:0] lfsr_mask_data[STATE_WIDTH-1:0]; + +reg [LFSR_WIDTH-1:0] state_val = 0; +reg [DATA_WIDTH-1:0] data_val = 0; + +integer i, j, k; + +initial begin + // init bit masks + for (i = 0; i < STATE_WIDTH; i = i + 1) begin + lfsr_mask_state[i] = {LFSR_WIDTH{1'b0}}; + if (i < LFSR_WIDTH) begin + lfsr_mask_state[i][i] = 1'b1; + end + lfsr_mask_data[i] = {DATA_WIDTH{1'b0}}; + end + + // simulate shift register + if (LFSR_CONFIG == "FIBONACCI") begin + // Fibonacci configuration + for (i = DATA_WIDTH-1; i >= 0; i = i - 1) begin + // determine shift in value + // current value in last FF, XOR with input data bit (MSB first) + state_val = lfsr_mask_state[LFSR_WIDTH-1]; + data_val = lfsr_mask_data[LFSR_WIDTH-1]; + data_val = data_val ^ (1 << i); + + // add XOR inputs from correct indicies + for (j = 1; j < STATE_WIDTH; j = j + 1) begin + if (LFSR_POLY & (1 << j)) begin + state_val = lfsr_mask_state[j-1] ^ state_val; + data_val = lfsr_mask_data[j-1] ^ data_val; + end + end + + // shift + for (j = STATE_WIDTH-1; j > 0; j = j - 1) begin + lfsr_mask_state[j] = lfsr_mask_state[j-1]; + lfsr_mask_data[j] = lfsr_mask_data[j-1]; + end + lfsr_mask_state[0] = state_val; + lfsr_mask_data[0] = data_val; + end + end else if (LFSR_CONFIG == "GALOIS") begin + // Galois configuration + for (i = DATA_WIDTH-1; i >= 0; i = i - 1) begin + // determine shift in value + // current value in last FF, XOR with input data bit (MSB first) + state_val = lfsr_mask_state[LFSR_WIDTH-1]; + data_val = lfsr_mask_data[LFSR_WIDTH-1]; + data_val = data_val ^ (1 << i); + + // shift + for (j = STATE_WIDTH-1; j > 0; j = j - 1) begin + lfsr_mask_state[j] = lfsr_mask_state[j-1]; + lfsr_mask_data[j] = lfsr_mask_data[j-1]; + end + lfsr_mask_state[0] = state_val; + lfsr_mask_data[0] = data_val; + + // add XOR inputs at correct indicies + for (j = 1; j < STATE_WIDTH; j = j + 1) begin + if (LFSR_POLY & (1 << j)) begin + lfsr_mask_state[j] = lfsr_mask_state[j] ^ state_val; + lfsr_mask_data[j] = lfsr_mask_data[j] ^ data_val; + end + end + end + end else begin + $error("Error: unknown configuration setting!"); + $finish; + end + + // reverse bits if selected + if (REVERSE) begin + // reverse order + for (i = 0; i < OUTPUT_WIDTH/2; i = i + 1) begin + state_val = lfsr_mask_state[i]; + data_val = lfsr_mask_data[i]; + lfsr_mask_state[i] = lfsr_mask_state[OUTPUT_WIDTH-i-1]; + lfsr_mask_data[i] = lfsr_mask_data[OUTPUT_WIDTH-i-1]; + lfsr_mask_state[OUTPUT_WIDTH-i-1] = state_val; + lfsr_mask_data[OUTPUT_WIDTH-i-1] = data_val; + end + // reverse bits + for (i = 0; i < OUTPUT_WIDTH; i = i + 1) begin + state_val = 0; + for (j = 0; j < STATE_WIDTH; j = j + 1) begin + state_val[j] = lfsr_mask_state[i][STATE_WIDTH-j-1]; + end + lfsr_mask_state[i] = state_val; + + data_val = 0; + for (j = 0; j < DATA_WIDTH; j = j + 1) begin + data_val[j] = lfsr_mask_data[i][DATA_WIDTH-j-1]; + end + lfsr_mask_data[i] = data_val; + end + end + + // for (i = 0; i < OUTPUT_WIDTH; i = i + 1) begin + // $display("%b %b", lfsr_mask_state[i], lfsr_mask_data[i]); + // end +end + +// synthesis translate_off +`define SIMULATION +// synthesis translate_on + +`ifdef SIMULATION +// "AUTO" style is "REDUCTION" for faster simulation +parameter STYLE_INT = (STYLE == "AUTO") ? "REDUCTION" : STYLE; +`else +// "AUTO" style is "LOOP" for better synthesis result +parameter STYLE_INT = (STYLE == "AUTO") ? "LOOP" : STYLE; +`endif + +genvar n; + +generate + +if (STYLE_INT == "REDUCTION") begin + + // use Verilog reduction operator + // fast in iverilog + // significantly larger than generated code with ISE (inferred wide XORs may be tripping up optimizer) + // slightly smaller than generated code with Quartus + // --> better for simulation + + for (n = 0; n < OUTPUT_WIDTH; n = n + 1) begin : loop + assign lfsr_out[n] = ^{(lfsr_in & lfsr_mask_state[n]), (data_in & lfsr_mask_data[n])}; + end + +end else if (STYLE_INT == "LOOP") begin + + // use nested loops + // very slow in iverilog + // slightly smaller than generated code with ISE + // same size as generated code with Quartus + // --> better for synthesis + + reg [OUTPUT_WIDTH-1:0] lfsr_out_reg = 0; + + assign lfsr_out = lfsr_out_reg; + + always @* begin + for (i = 0; i < OUTPUT_WIDTH; i = i + 1) begin + lfsr_out_reg[i] = 0; + for (j = 0; j < STATE_WIDTH; j = j + 1) begin + if (lfsr_mask_state[i][j]) begin + lfsr_out_reg[i] = lfsr_out_reg[i] ^ lfsr_in[j]; + end + end + for (j = 0; j < DATA_WIDTH; j = j + 1) begin + if (lfsr_mask_data[i][j]) begin + lfsr_out_reg[i] = lfsr_out_reg[i] ^ data_in[j]; + end + end + end + end + +end else begin + + initial begin + $error("Error: unknown style setting!"); + $finish; + end + +end + +endgenerate + +endmodule From 47ca9a8725dba00990341470b6af37148c50c5ec Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Jun 2016 17:31:58 -0700 Subject: [PATCH 279/617] Replace eth_crc modules for generic lfsr module --- example/ATLYS/fpga/fpga/Makefile | 2 +- example/ATLYS/fpga/tb/test_fpga_core.py | 2 +- example/DE5-Net/fpga/fpga/Makefile | 9 +- example/DE5-Net/fpga/tb/test_fpga_core.py | 9 +- example/HXT100G/fpga/fpga/Makefile | 9 +- example/HXT100G/fpga/tb/test_fpga_core.py | 9 +- rtl/axis_eth_fcs.v | 16 ++- rtl/axis_eth_fcs_64.v | 128 ++++++++++++++++------ rtl/axis_eth_fcs_check.v | 16 ++- rtl/axis_eth_fcs_check_64.v | 80 ++++++++++---- rtl/axis_eth_fcs_insert.v | 16 ++- rtl/axis_eth_fcs_insert_64.v | 128 ++++++++++++++++------ rtl/eth_mac_10g_rx.v | 80 ++++++++++---- rtl/eth_mac_10g_tx.v | 128 ++++++++++++++++------ rtl/eth_mac_1g_rx.v | 16 ++- rtl/eth_mac_1g_tx.v | 16 ++- tb/test_axis_eth_fcs.py | 2 +- tb/test_axis_eth_fcs_64.py | 9 +- tb/test_axis_eth_fcs_check.py | 2 +- tb/test_axis_eth_fcs_check_64.py | 9 +- tb/test_axis_eth_fcs_insert.py | 2 +- tb/test_axis_eth_fcs_insert_64.py | 9 +- tb/test_axis_eth_fcs_insert_64_pad.py | 9 +- tb/test_axis_eth_fcs_insert_pad.py | 2 +- tb/test_eth_mac_10g.py | 9 +- tb/test_eth_mac_10g_fifo.py | 9 +- tb/test_eth_mac_10g_rx.py | 9 +- tb/test_eth_mac_10g_tx.py | 9 +- tb/test_eth_mac_1g.py | 2 +- tb/test_eth_mac_1g_fifo.py | 2 +- tb/test_eth_mac_1g_rx.py | 2 +- tb/test_eth_mac_1g_tx.py | 2 +- 32 files changed, 490 insertions(+), 262 deletions(-) diff --git a/example/ATLYS/fpga/fpga/Makefile b/example/ATLYS/fpga/fpga/Makefile index 648dbf88b..9745f6886 100644 --- a/example/ATLYS/fpga/fpga/Makefile +++ b/example/ATLYS/fpga/fpga/Makefile @@ -19,7 +19,7 @@ SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v -SYN_FILES += lib/eth/rtl/eth_crc_8.v +SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx.v SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete.v diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index 2a847ed8b..0f03d4a84 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -46,7 +46,7 @@ srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_1g.v") srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") -srcs.append("../lib/eth/rtl/eth_crc_8.v") +srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") srcs.append("../lib/eth/rtl/udp_complete.v") diff --git a/example/DE5-Net/fpga/fpga/Makefile b/example/DE5-Net/fpga/fpga/Makefile index b47250444..713bd0dea 100644 --- a/example/DE5-Net/fpga/fpga/Makefile +++ b/example/DE5-Net/fpga/fpga/Makefile @@ -16,14 +16,7 @@ SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v -SYN_FILES += lib/eth/rtl/eth_crc_8.v -SYN_FILES += lib/eth/rtl/eth_crc_16.v -SYN_FILES += lib/eth/rtl/eth_crc_24.v -SYN_FILES += lib/eth/rtl/eth_crc_32.v -SYN_FILES += lib/eth/rtl/eth_crc_40.v -SYN_FILES += lib/eth/rtl/eth_crc_48.v -SYN_FILES += lib/eth/rtl/eth_crc_56.v -SYN_FILES += lib/eth/rtl/eth_crc_64.v +SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v SYN_FILES += lib/eth/rtl/udp_complete_64.v diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index e6cf98423..2d95e580e 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -45,14 +45,7 @@ srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_10g.v") srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") -srcs.append("../lib/eth/rtl/eth_crc_8.v") -srcs.append("../lib/eth/rtl/eth_crc_16.v") -srcs.append("../lib/eth/rtl/eth_crc_24.v") -srcs.append("../lib/eth/rtl/eth_crc_32.v") -srcs.append("../lib/eth/rtl/eth_crc_40.v") -srcs.append("../lib/eth/rtl/eth_crc_48.v") -srcs.append("../lib/eth/rtl/eth_crc_56.v") -srcs.append("../lib/eth/rtl/eth_crc_64.v") +srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") diff --git a/example/HXT100G/fpga/fpga/Makefile b/example/HXT100G/fpga/fpga/Makefile index 838b74dec..1f2d7375a 100644 --- a/example/HXT100G/fpga/fpga/Makefile +++ b/example/HXT100G/fpga/fpga/Makefile @@ -21,14 +21,7 @@ SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v -SYN_FILES += lib/eth/rtl/eth_crc_8.v -SYN_FILES += lib/eth/rtl/eth_crc_16.v -SYN_FILES += lib/eth/rtl/eth_crc_24.v -SYN_FILES += lib/eth/rtl/eth_crc_32.v -SYN_FILES += lib/eth/rtl/eth_crc_40.v -SYN_FILES += lib/eth/rtl/eth_crc_48.v -SYN_FILES += lib/eth/rtl/eth_crc_56.v -SYN_FILES += lib/eth/rtl/eth_crc_64.v +SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v SYN_FILES += lib/eth/rtl/udp_complete_64.v diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index ffad66602..d70b1ff3b 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -45,14 +45,7 @@ srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_10g.v") srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") -srcs.append("../lib/eth/rtl/eth_crc_8.v") -srcs.append("../lib/eth/rtl/eth_crc_16.v") -srcs.append("../lib/eth/rtl/eth_crc_24.v") -srcs.append("../lib/eth/rtl/eth_crc_32.v") -srcs.append("../lib/eth/rtl/eth_crc_40.v") -srcs.append("../lib/eth/rtl/eth_crc_48.v") -srcs.append("../lib/eth/rtl/eth_crc_56.v") -srcs.append("../lib/eth/rtl/eth_crc_64.v") +srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") diff --git a/rtl/axis_eth_fcs.v b/rtl/axis_eth_fcs.v index eed18b78d..724d095c2 100644 --- a/rtl/axis_eth_fcs.v +++ b/rtl/axis_eth_fcs.v @@ -60,11 +60,19 @@ assign input_axis_tready = 1; assign output_fcs = fcs_reg; assign output_fcs_valid = fcs_valid_reg; -eth_crc_8 -eth_crc_8_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( .data_in(input_axis_tdata), - .crc_state(crc_state), - .crc_next(crc_next) + .lfsr_in(crc_state), + .lfsr_out(crc_next) ); always @(posedge clk) begin diff --git a/rtl/axis_eth_fcs_64.v b/rtl/axis_eth_fcs_64.v index 71100681f..b4390ffb2 100644 --- a/rtl/axis_eth_fcs_64.v +++ b/rtl/axis_eth_fcs_64.v @@ -68,60 +68,124 @@ assign input_axis_tready = 1'b1; assign output_fcs = fcs_reg; assign output_fcs_valid = fcs_valid_reg; -eth_crc_8 -eth_crc_8_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( .data_in(input_axis_tdata[7:0]), - .crc_state(crc_state), - .crc_next(crc_next0) + .lfsr_in(crc_state), + .lfsr_out(crc_next0) ); -eth_crc_16 -eth_crc_16_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(16), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_16 ( .data_in(input_axis_tdata[15:0]), - .crc_state(crc_state), - .crc_next(crc_next1) + .lfsr_in(crc_state), + .lfsr_out(crc_next1) ); -eth_crc_24 -eth_crc_24_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(24), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_24 ( .data_in(input_axis_tdata[23:0]), - .crc_state(crc_state), - .crc_next(crc_next2) + .lfsr_in(crc_state), + .lfsr_out(crc_next2) ); -eth_crc_32 -eth_crc_32_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(32), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( .data_in(input_axis_tdata[31:0]), - .crc_state(crc_state), - .crc_next(crc_next3) + .lfsr_in(crc_state), + .lfsr_out(crc_next3) ); -eth_crc_40 -eth_crc_40_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(40), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_40 ( .data_in(input_axis_tdata[39:0]), - .crc_state(crc_state), - .crc_next(crc_next4) + .lfsr_in(crc_state), + .lfsr_out(crc_next4) ); -eth_crc_48 -eth_crc_48_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(48), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_48 ( .data_in(input_axis_tdata[47:0]), - .crc_state(crc_state), - .crc_next(crc_next5) + .lfsr_in(crc_state), + .lfsr_out(crc_next5) ); -eth_crc_56 -eth_crc_56_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(56), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_56 ( .data_in(input_axis_tdata[55:0]), - .crc_state(crc_state), - .crc_next(crc_next6) + .lfsr_in(crc_state), + .lfsr_out(crc_next6) ); -eth_crc_64 -eth_crc_64_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(64), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_64 ( .data_in(input_axis_tdata[63:0]), - .crc_state(crc_state), - .crc_next(crc_next7) + .lfsr_in(crc_state), + .lfsr_out(crc_next7) ); always @(posedge clk) begin diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v index bbe788385..23412dc2e 100644 --- a/rtl/axis_eth_fcs_check.v +++ b/rtl/axis_eth_fcs_check.v @@ -102,11 +102,19 @@ assign input_axis_tready = input_axis_tready_reg; assign busy = busy_reg; assign error_bad_fcs = error_bad_fcs_reg; -eth_crc_8 -eth_crc_8_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( .data_in(input_axis_tdata_d3), - .crc_state(crc_state), - .crc_next(crc_next) + .lfsr_in(crc_state), + .lfsr_out(crc_next) ); always @* begin diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index bdcb01d02..9a104eb0a 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -117,39 +117,79 @@ assign error_bad_fcs = error_bad_fcs_reg; wire last_cycle = state_reg == STATE_LAST; -eth_crc_8 -eth_crc_8_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( .data_in(last_cycle ? input_axis_tdata_d0[39:32] : input_axis_tdata[7:0]), - .crc_state(last_cycle ? crc_state3 : crc_state), - .crc_next(crc_next0) + .lfsr_in(last_cycle ? crc_state3 : crc_state), + .lfsr_out(crc_next0) ); -eth_crc_16 -eth_crc_16_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(16), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_16 ( .data_in(last_cycle ? input_axis_tdata_d0[47:32] : input_axis_tdata[15:0]), - .crc_state(last_cycle ? crc_state3 : crc_state), - .crc_next(crc_next1) + .lfsr_in(last_cycle ? crc_state3 : crc_state), + .lfsr_out(crc_next1) ); -eth_crc_24 -eth_crc_24_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(24), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_24 ( .data_in(last_cycle ? input_axis_tdata_d0[55:32] : input_axis_tdata[23:0]), - .crc_state(last_cycle ? crc_state3 : crc_state), - .crc_next(crc_next2) + .lfsr_in(last_cycle ? crc_state3 : crc_state), + .lfsr_out(crc_next2) ); -eth_crc_32 -eth_crc_32_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(32), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( .data_in(last_cycle ? input_axis_tdata_d0[63:32] : input_axis_tdata[31:0]), - .crc_state(last_cycle ? crc_state3 : crc_state), - .crc_next(crc_next3) + .lfsr_in(last_cycle ? crc_state3 : crc_state), + .lfsr_out(crc_next3) ); -eth_crc_64 -eth_crc_64_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(64), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_64 ( .data_in(input_axis_tdata[63:0]), - .crc_state(crc_state), - .crc_next(crc_next7) + .lfsr_in(crc_state), + .lfsr_out(crc_next7) ); always @* begin diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v index e6e381c3e..1d7b8174b 100644 --- a/rtl/axis_eth_fcs_insert.v +++ b/rtl/axis_eth_fcs_insert.v @@ -95,11 +95,19 @@ assign input_axis_tready = input_axis_tready_reg; assign busy = busy_reg; -eth_crc_8 -eth_crc_8_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( .data_in(output_axis_tdata_int), - .crc_state(crc_state), - .crc_next(crc_next) + .lfsr_in(crc_state), + .lfsr_out(crc_next) ); always @* begin diff --git a/rtl/axis_eth_fcs_insert_64.v b/rtl/axis_eth_fcs_insert_64.v index 034ad3c01..107f82d1b 100644 --- a/rtl/axis_eth_fcs_insert_64.v +++ b/rtl/axis_eth_fcs_insert_64.v @@ -119,60 +119,124 @@ assign input_axis_tready = input_axis_tready_reg; assign busy = busy_reg; -eth_crc_8 -eth_crc_8_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( .data_in(fcs_input_tdata[7:0]), - .crc_state(crc_state), - .crc_next(crc_next0) + .lfsr_in(crc_state), + .lfsr_out(crc_next0) ); -eth_crc_16 -eth_crc_16_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(16), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_16 ( .data_in(fcs_input_tdata[15:0]), - .crc_state(crc_state), - .crc_next(crc_next1) + .lfsr_in(crc_state), + .lfsr_out(crc_next1) ); -eth_crc_24 -eth_crc_24_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(24), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_24 ( .data_in(fcs_input_tdata[23:0]), - .crc_state(crc_state), - .crc_next(crc_next2) + .lfsr_in(crc_state), + .lfsr_out(crc_next2) ); -eth_crc_32 -eth_crc_32_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(32), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( .data_in(fcs_input_tdata[31:0]), - .crc_state(crc_state), - .crc_next(crc_next3) + .lfsr_in(crc_state), + .lfsr_out(crc_next3) ); -eth_crc_40 -eth_crc_40_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(40), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_40 ( .data_in(fcs_input_tdata[39:0]), - .crc_state(crc_state), - .crc_next(crc_next4) + .lfsr_in(crc_state), + .lfsr_out(crc_next4) ); -eth_crc_48 -eth_crc_48_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(48), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_48 ( .data_in(fcs_input_tdata[47:0]), - .crc_state(crc_state), - .crc_next(crc_next5) + .lfsr_in(crc_state), + .lfsr_out(crc_next5) ); -eth_crc_56 -eth_crc_56_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(56), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_56 ( .data_in(fcs_input_tdata[55:0]), - .crc_state(crc_state), - .crc_next(crc_next6) + .lfsr_in(crc_state), + .lfsr_out(crc_next6) ); -eth_crc_64 -eth_crc_64_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(64), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_64 ( .data_in(fcs_input_tdata[63:0]), - .crc_state(crc_state), - .crc_next(crc_next7) + .lfsr_in(crc_state), + .lfsr_out(crc_next7) ); function [3:0] keep2count; diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index 7118f727e..b8b098fc7 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -116,39 +116,79 @@ assign error_bad_fcs = error_bad_fcs_reg; wire last_cycle = state_reg == STATE_LAST; -eth_crc_8 -eth_crc_8_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( .data_in(last_cycle ? xgmii_rxd_d1[39:32] : xgmii_rxd_d0[7:0]), - .crc_state(last_cycle ? crc_state3 : crc_state), - .crc_next(crc_next0) + .lfsr_in(last_cycle ? crc_state3 : crc_state), + .lfsr_out(crc_next0) ); -eth_crc_16 -eth_crc_16_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(16), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_16 ( .data_in(last_cycle ? xgmii_rxd_d1[47:32] : xgmii_rxd_d0[15:0]), - .crc_state(last_cycle ? crc_state3 : crc_state), - .crc_next(crc_next1) + .lfsr_in(last_cycle ? crc_state3 : crc_state), + .lfsr_out(crc_next1) ); -eth_crc_24 -eth_crc_24_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(24), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_24 ( .data_in(last_cycle ? xgmii_rxd_d1[55:32] : xgmii_rxd_d0[23:0]), - .crc_state(last_cycle ? crc_state3 : crc_state), - .crc_next(crc_next2) + .lfsr_in(last_cycle ? crc_state3 : crc_state), + .lfsr_out(crc_next2) ); -eth_crc_32 -eth_crc_32_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(32), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( .data_in(last_cycle ? xgmii_rxd_d1[63:32] : xgmii_rxd_d0[31:0]), - .crc_state(last_cycle ? crc_state3 : crc_state), - .crc_next(crc_next3) + .lfsr_in(last_cycle ? crc_state3 : crc_state), + .lfsr_out(crc_next3) ); -eth_crc_64 -eth_crc_64_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(64), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_64 ( .data_in(xgmii_rxd_d0[63:0]), - .crc_state(crc_state), - .crc_next(crc_next7) + .lfsr_in(crc_state), + .lfsr_out(crc_next7) ); // detect control characters diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 20f63c963..72e7c9a64 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -125,60 +125,124 @@ assign input_axis_tready = input_axis_tready_reg; assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; -eth_crc_8 -eth_crc_8_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( .data_in(input_tdata_reg[7:0]), - .crc_state(crc_state), - .crc_next(crc_next0) + .lfsr_in(crc_state), + .lfsr_out(crc_next0) ); -eth_crc_16 -eth_crc_16_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(16), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_16 ( .data_in(input_tdata_reg[15:0]), - .crc_state(crc_state), - .crc_next(crc_next1) + .lfsr_in(crc_state), + .lfsr_out(crc_next1) ); -eth_crc_24 -eth_crc_24_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(24), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_24 ( .data_in(input_tdata_reg[23:0]), - .crc_state(crc_state), - .crc_next(crc_next2) + .lfsr_in(crc_state), + .lfsr_out(crc_next2) ); -eth_crc_32 -eth_crc_32_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(32), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( .data_in(input_tdata_reg[31:0]), - .crc_state(crc_state), - .crc_next(crc_next3) + .lfsr_in(crc_state), + .lfsr_out(crc_next3) ); -eth_crc_40 -eth_crc_40_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(40), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_40 ( .data_in(input_tdata_reg[39:0]), - .crc_state(crc_state), - .crc_next(crc_next4) + .lfsr_in(crc_state), + .lfsr_out(crc_next4) ); -eth_crc_48 -eth_crc_48_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(48), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_48 ( .data_in(input_tdata_reg[47:0]), - .crc_state(crc_state), - .crc_next(crc_next5) + .lfsr_in(crc_state), + .lfsr_out(crc_next5) ); -eth_crc_56 -eth_crc_56_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(56), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_56 ( .data_in(input_tdata_reg[55:0]), - .crc_state(crc_state), - .crc_next(crc_next6) + .lfsr_in(crc_state), + .lfsr_out(crc_next6) ); -eth_crc_64 -eth_crc_64_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(64), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_64 ( .data_in(input_tdata_reg[63:0]), - .crc_state(crc_state), - .crc_next(crc_next7) + .lfsr_in(crc_state), + .lfsr_out(crc_next7) ); function [3:0] keep2count; diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v index fd7128b92..9a013016c 100644 --- a/rtl/eth_mac_1g_rx.v +++ b/rtl/eth_mac_1g_rx.v @@ -104,11 +104,19 @@ assign output_axis_tuser = output_axis_tuser_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; -eth_crc_8 -eth_crc_8_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( .data_in(gmii_rxd_d4), - .crc_state(crc_state), - .crc_next(crc_next) + .lfsr_in(crc_state), + .lfsr_out(crc_next) ); always @* begin diff --git a/rtl/eth_mac_1g_tx.v b/rtl/eth_mac_1g_tx.v index b101ec096..6c8b62b57 100644 --- a/rtl/eth_mac_1g_tx.v +++ b/rtl/eth_mac_1g_tx.v @@ -92,11 +92,19 @@ assign gmii_txd = gmii_txd_reg; assign gmii_tx_en = gmii_tx_en_reg; assign gmii_tx_er = gmii_tx_er_reg; -eth_crc_8 -eth_crc_8_inst ( +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( .data_in(gmii_txd_next), - .crc_state(crc_state), - .crc_next(crc_next) + .lfsr_in(crc_state), + .lfsr_out(crc_next) ); always @* begin diff --git a/tb/test_axis_eth_fcs.py b/tb/test_axis_eth_fcs.py index 7da6f103b..c216acb08 100755 --- a/tb/test_axis_eth_fcs.py +++ b/tb/test_axis_eth_fcs.py @@ -39,7 +39,7 @@ module = 'axis_eth_fcs' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s.v" % module) src = ' '.join(srcs) diff --git a/tb/test_axis_eth_fcs_64.py b/tb/test_axis_eth_fcs_64.py index 7432e2ab3..05e9f9ebd 100755 --- a/tb/test_axis_eth_fcs_64.py +++ b/tb/test_axis_eth_fcs_64.py @@ -39,14 +39,7 @@ module = 'axis_eth_fcs_64' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") -srcs.append("../rtl/eth_crc_16.v") -srcs.append("../rtl/eth_crc_24.v") -srcs.append("../rtl/eth_crc_32.v") -srcs.append("../rtl/eth_crc_40.v") -srcs.append("../rtl/eth_crc_48.v") -srcs.append("../rtl/eth_crc_56.v") -srcs.append("../rtl/eth_crc_64.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s.v" % module) src = ' '.join(srcs) diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index 7f55d5bc4..c4bdd2f3a 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -41,7 +41,7 @@ module = 'axis_eth_fcs_check' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s.v" % module) src = ' '.join(srcs) diff --git a/tb/test_axis_eth_fcs_check_64.py b/tb/test_axis_eth_fcs_check_64.py index 7431d5e98..13f841676 100755 --- a/tb/test_axis_eth_fcs_check_64.py +++ b/tb/test_axis_eth_fcs_check_64.py @@ -41,14 +41,7 @@ module = 'axis_eth_fcs_check_64' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") -srcs.append("../rtl/eth_crc_16.v") -srcs.append("../rtl/eth_crc_24.v") -srcs.append("../rtl/eth_crc_32.v") -srcs.append("../rtl/eth_crc_40.v") -srcs.append("../rtl/eth_crc_48.v") -srcs.append("../rtl/eth_crc_56.v") -srcs.append("../rtl/eth_crc_64.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s.v" % module) src = ' '.join(srcs) diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index 5c14a407e..249ffd63a 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -41,7 +41,7 @@ module = 'axis_eth_fcs_insert' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s.v" % module) src = ' '.join(srcs) diff --git a/tb/test_axis_eth_fcs_insert_64.py b/tb/test_axis_eth_fcs_insert_64.py index 45546b4b1..aa58f3b8b 100755 --- a/tb/test_axis_eth_fcs_insert_64.py +++ b/tb/test_axis_eth_fcs_insert_64.py @@ -41,14 +41,7 @@ module = 'axis_eth_fcs_insert_64' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") -srcs.append("../rtl/eth_crc_16.v") -srcs.append("../rtl/eth_crc_24.v") -srcs.append("../rtl/eth_crc_32.v") -srcs.append("../rtl/eth_crc_40.v") -srcs.append("../rtl/eth_crc_48.v") -srcs.append("../rtl/eth_crc_56.v") -srcs.append("../rtl/eth_crc_64.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s.v" % module) src = ' '.join(srcs) diff --git a/tb/test_axis_eth_fcs_insert_64_pad.py b/tb/test_axis_eth_fcs_insert_64_pad.py index 4eeacdb2d..e1ae380a8 100755 --- a/tb/test_axis_eth_fcs_insert_64_pad.py +++ b/tb/test_axis_eth_fcs_insert_64_pad.py @@ -41,14 +41,7 @@ module = 'axis_eth_fcs_insert_64' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") -srcs.append("../rtl/eth_crc_16.v") -srcs.append("../rtl/eth_crc_24.v") -srcs.append("../rtl/eth_crc_32.v") -srcs.append("../rtl/eth_crc_40.v") -srcs.append("../rtl/eth_crc_48.v") -srcs.append("../rtl/eth_crc_56.v") -srcs.append("../rtl/eth_crc_64.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s_pad.v" % module) src = ' '.join(srcs) diff --git a/tb/test_axis_eth_fcs_insert_pad.py b/tb/test_axis_eth_fcs_insert_pad.py index 811b1fe6c..5d537fdd2 100755 --- a/tb/test_axis_eth_fcs_insert_pad.py +++ b/tb/test_axis_eth_fcs_insert_pad.py @@ -41,7 +41,7 @@ module = 'axis_eth_fcs_insert' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s_pad.v" % module) src = ' '.join(srcs) diff --git a/tb/test_eth_mac_10g.py b/tb/test_eth_mac_10g.py index bccb98275..15bdf246a 100755 --- a/tb/test_eth_mac_10g.py +++ b/tb/test_eth_mac_10g.py @@ -40,14 +40,7 @@ module = 'eth_mac_10g' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") -srcs.append("../rtl/eth_crc_16.v") -srcs.append("../rtl/eth_crc_24.v") -srcs.append("../rtl/eth_crc_32.v") -srcs.append("../rtl/eth_crc_40.v") -srcs.append("../rtl/eth_crc_48.v") -srcs.append("../rtl/eth_crc_56.v") -srcs.append("../rtl/eth_crc_64.v") +srcs.append("../rtl/lfsr.v") srcs.append("../rtl/eth_mac_10g_rx.v") srcs.append("../rtl/eth_mac_10g_tx.v") srcs.append("test_%s.v" % module) diff --git a/tb/test_eth_mac_10g_fifo.py b/tb/test_eth_mac_10g_fifo.py index f7689baf6..f647fe51d 100755 --- a/tb/test_eth_mac_10g_fifo.py +++ b/tb/test_eth_mac_10g_fifo.py @@ -40,14 +40,7 @@ module = 'eth_mac_10g_fifo' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") -srcs.append("../rtl/eth_crc_16.v") -srcs.append("../rtl/eth_crc_24.v") -srcs.append("../rtl/eth_crc_32.v") -srcs.append("../rtl/eth_crc_40.v") -srcs.append("../rtl/eth_crc_48.v") -srcs.append("../rtl/eth_crc_56.v") -srcs.append("../rtl/eth_crc_64.v") +srcs.append("../rtl/lfsr.v") srcs.append("../rtl/eth_mac_10g_rx.v") srcs.append("../rtl/eth_mac_10g_tx.v") srcs.append("../rtl/eth_mac_10g.v") diff --git a/tb/test_eth_mac_10g_rx.py b/tb/test_eth_mac_10g_rx.py index 21e1e2a22..e2cf1a681 100755 --- a/tb/test_eth_mac_10g_rx.py +++ b/tb/test_eth_mac_10g_rx.py @@ -42,14 +42,7 @@ module = 'eth_mac_10g_rx' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") -srcs.append("../rtl/eth_crc_16.v") -srcs.append("../rtl/eth_crc_24.v") -srcs.append("../rtl/eth_crc_32.v") -srcs.append("../rtl/eth_crc_40.v") -srcs.append("../rtl/eth_crc_48.v") -srcs.append("../rtl/eth_crc_56.v") -srcs.append("../rtl/eth_crc_64.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s.v" % module) src = ' '.join(srcs) diff --git a/tb/test_eth_mac_10g_tx.py b/tb/test_eth_mac_10g_tx.py index 921670222..a5bdecff4 100755 --- a/tb/test_eth_mac_10g_tx.py +++ b/tb/test_eth_mac_10g_tx.py @@ -40,14 +40,7 @@ module = 'eth_mac_10g_tx' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") -srcs.append("../rtl/eth_crc_16.v") -srcs.append("../rtl/eth_crc_24.v") -srcs.append("../rtl/eth_crc_32.v") -srcs.append("../rtl/eth_crc_40.v") -srcs.append("../rtl/eth_crc_48.v") -srcs.append("../rtl/eth_crc_56.v") -srcs.append("../rtl/eth_crc_64.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s.v" % module) src = ' '.join(srcs) diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index 6e446d59d..88a75ff7a 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -40,7 +40,7 @@ module = 'eth_mac_1g' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/lfsr.v") srcs.append("../rtl/eth_mac_1g_rx.v") srcs.append("../rtl/eth_mac_1g_tx.v") srcs.append("test_%s.v" % module) diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py index 3db86968c..e67a52bd4 100755 --- a/tb/test_eth_mac_1g_fifo.py +++ b/tb/test_eth_mac_1g_fifo.py @@ -40,7 +40,7 @@ module = 'eth_mac_1g_fifo' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/lfsr.v") srcs.append("../rtl/eth_mac_1g_rx.v") srcs.append("../rtl/eth_mac_1g_tx.v") srcs.append("../rtl/eth_mac_1g.v") diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py index 4bf2afcaf..de9a63007 100755 --- a/tb/test_eth_mac_1g_rx.py +++ b/tb/test_eth_mac_1g_rx.py @@ -40,7 +40,7 @@ module = 'eth_mac_1g_rx' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s.v" % module) src = ' '.join(srcs) diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index 2963ecad2..d8cecb3d7 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -40,7 +40,7 @@ module = 'eth_mac_1g_tx' srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_crc_8.v") +srcs.append("../rtl/lfsr.v") srcs.append("test_%s.v" % module) src = ' '.join(srcs) From 635315c402215d67762404efdb72d36aa23f30dd Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Jun 2016 18:58:10 -0700 Subject: [PATCH 280/617] Remove generated eth_crc modules --- rtl/eth_crc_16.v | 85 ------------------------------------------------ rtl/eth_crc_24.v | 85 ------------------------------------------------ rtl/eth_crc_32.v | 85 ------------------------------------------------ rtl/eth_crc_40.v | 85 ------------------------------------------------ rtl/eth_crc_48.v | 85 ------------------------------------------------ rtl/eth_crc_56.v | 85 ------------------------------------------------ rtl/eth_crc_64.v | 85 ------------------------------------------------ rtl/eth_crc_8.v | 85 ------------------------------------------------ 8 files changed, 680 deletions(-) delete mode 100644 rtl/eth_crc_16.v delete mode 100644 rtl/eth_crc_24.v delete mode 100644 rtl/eth_crc_32.v delete mode 100644 rtl/eth_crc_40.v delete mode 100644 rtl/eth_crc_48.v delete mode 100644 rtl/eth_crc_56.v delete mode 100644 rtl/eth_crc_64.v delete mode 100644 rtl/eth_crc_8.v diff --git a/rtl/eth_crc_16.v b/rtl/eth_crc_16.v deleted file mode 100644 index c15a8ba31..000000000 --- a/rtl/eth_crc_16.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Copyright (c) 2014-2016 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 - -/* - * CRC module eth_crc_16 - * - * CRC width: 32 - * Data width: 16 - * CRC polynomial: 32'h4c11db7 - * Configuration: galois - * Bit-reverse: input and output - * - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 - * - * Generated by crcgen.py - * - * crcgen.py -b -r -d 16 -n eth_crc_16 - * - */ -module eth_crc_16 -( - input wire [15:0] data_in, - input wire [31:0] crc_state, - output wire [31:0] crc_next -); - -assign crc_next[0] = crc_state[0] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[16] ^ data_in[0] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[10]; -assign crc_next[1] = crc_state[1] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[17] ^ data_in[1] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[11]; -assign crc_next[2] = crc_state[2] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[12] ^ crc_state[18] ^ data_in[2] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[12]; -assign crc_next[3] = crc_state[3] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[13] ^ crc_state[19] ^ data_in[3] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[13]; -assign crc_next[4] = crc_state[4] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[20] ^ data_in[4] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[14]; -assign crc_next[5] = crc_state[5] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[21] ^ data_in[5] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[15]; -assign crc_next[6] = crc_state[0] ^ crc_state[4] ^ crc_state[7] ^ crc_state[12] ^ crc_state[13] ^ crc_state[22] ^ data_in[0] ^ data_in[4] ^ data_in[7] ^ data_in[12] ^ data_in[13]; -assign crc_next[7] = crc_state[1] ^ crc_state[5] ^ crc_state[8] ^ crc_state[13] ^ crc_state[14] ^ crc_state[23] ^ data_in[1] ^ data_in[5] ^ data_in[8] ^ data_in[13] ^ data_in[14]; -assign crc_next[8] = crc_state[0] ^ crc_state[2] ^ crc_state[6] ^ crc_state[9] ^ crc_state[14] ^ crc_state[15] ^ crc_state[24] ^ data_in[0] ^ data_in[2] ^ data_in[6] ^ data_in[9] ^ data_in[14] ^ data_in[15]; -assign crc_next[9] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[15] ^ crc_state[25] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[15]; -assign crc_next[10] = crc_state[2] ^ crc_state[5] ^ crc_state[6] ^ crc_state[10] ^ crc_state[26] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[10]; -assign crc_next[11] = crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[27] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[11]; -assign crc_next[12] = crc_state[0] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[28] ^ data_in[0] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[12]; -assign crc_next[13] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[13]; -assign crc_next[14] = crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[14]; -assign crc_next[15] = crc_state[2] ^ crc_state[3] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[15] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[15]; -assign crc_next[16] = crc_state[0] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ data_in[0] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12]; -assign crc_next[17] = crc_state[0] ^ crc_state[1] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ data_in[0] ^ data_in[1] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13]; -assign crc_next[18] = crc_state[1] ^ crc_state[2] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ data_in[1] ^ data_in[2] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14]; -assign crc_next[19] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[15]; -assign crc_next[20] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[6] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[6] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15]; -assign crc_next[21] = crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15]; -assign crc_next[22] = crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14]; -assign crc_next[23] = crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15]; -assign crc_next[24] = crc_state[0] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ data_in[0] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15]; -assign crc_next[25] = crc_state[1] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ data_in[1] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14]; -assign crc_next[26] = crc_state[2] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ data_in[2] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15]; -assign crc_next[27] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15]; -assign crc_next[28] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[13] ^ data_in[14]; -assign crc_next[29] = crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[14] ^ data_in[15]; -assign crc_next[30] = crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[14] ^ crc_state[15] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[14] ^ data_in[15]; -assign crc_next[31] = crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[9] ^ crc_state[15] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[15]; - -endmodule diff --git a/rtl/eth_crc_24.v b/rtl/eth_crc_24.v deleted file mode 100644 index 3b75df250..000000000 --- a/rtl/eth_crc_24.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Copyright (c) 2014-2016 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 - -/* - * CRC module eth_crc_24 - * - * CRC width: 32 - * Data width: 24 - * CRC polynomial: 32'h4c11db7 - * Configuration: galois - * Bit-reverse: input and output - * - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 - * - * Generated by crcgen.py - * - * crcgen.py -b -r -d 24 -n eth_crc_24 - * - */ -module eth_crc_24 -( - input wire [23:0] data_in, - input wire [31:0] crc_state, - output wire [31:0] crc_next -); - -assign crc_next[0] = crc_state[0] ^ crc_state[8] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[24] ^ data_in[0] ^ data_in[8] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[18]; -assign crc_next[1] = crc_state[0] ^ crc_state[1] ^ crc_state[9] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[25] ^ data_in[0] ^ data_in[1] ^ data_in[9] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[19]; -assign crc_next[2] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[10] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[20] ^ crc_state[26] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[10] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[20]; -assign crc_next[3] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[11] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[21] ^ crc_state[27] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[11] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[21]; -assign crc_next[4] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[12] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[28] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[12] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[22]; -assign crc_next[5] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[13] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[23] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[13] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[23]; -assign crc_next[6] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[12] ^ crc_state[15] ^ crc_state[20] ^ crc_state[21] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[12] ^ data_in[15] ^ data_in[20] ^ data_in[21]; -assign crc_next[7] = crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[13] ^ crc_state[16] ^ crc_state[21] ^ crc_state[22] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[13] ^ data_in[16] ^ data_in[21] ^ data_in[22]; -assign crc_next[8] = crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[14] ^ crc_state[17] ^ crc_state[22] ^ crc_state[23] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[14] ^ data_in[17] ^ data_in[22] ^ data_in[23]; -assign crc_next[9] = crc_state[0] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[23] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[23]; -assign crc_next[10] = crc_state[1] ^ crc_state[5] ^ crc_state[6] ^ crc_state[10] ^ crc_state[13] ^ crc_state[14] ^ crc_state[18] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[10] ^ data_in[13] ^ data_in[14] ^ data_in[18]; -assign crc_next[11] = crc_state[0] ^ crc_state[2] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ data_in[0] ^ data_in[2] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[19]; -assign crc_next[12] = crc_state[1] ^ crc_state[3] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ data_in[1] ^ data_in[3] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[20]; -assign crc_next[13] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[21]; -assign crc_next[14] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[5] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[17] ^ data_in[18] ^ data_in[22]; -assign crc_next[15] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[6] ^ crc_state[10] ^ crc_state[11] ^ crc_state[15] ^ crc_state[18] ^ crc_state[19] ^ crc_state[23] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[6] ^ data_in[10] ^ data_in[11] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[23]; -assign crc_next[16] = crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20]; -assign crc_next[17] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21]; -assign crc_next[18] = crc_state[1] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[13] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22]; -assign crc_next[19] = crc_state[2] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[23]; -assign crc_next[20] = crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[14] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[14] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23]; -assign crc_next[21] = crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23]; -assign crc_next[22] = crc_state[0] ^ crc_state[5] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ data_in[0] ^ data_in[5] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22]; -assign crc_next[23] = crc_state[0] ^ crc_state[1] ^ crc_state[6] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ data_in[0] ^ data_in[1] ^ data_in[6] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23]; -assign crc_next[24] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[7] ^ crc_state[8] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[7] ^ data_in[8] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23]; -assign crc_next[25] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[9] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[9] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22]; -assign crc_next[26] = crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[10] ^ crc_state[13] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[10] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23]; -assign crc_next[27] = crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[23]; -assign crc_next[28] = crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[21] ^ data_in[22]; -assign crc_next[29] = crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[22] ^ data_in[23]; -assign crc_next[30] = crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[22] ^ crc_state[23] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[22] ^ data_in[23]; -assign crc_next[31] = crc_state[7] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[17] ^ crc_state[23] ^ data_in[7] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[17] ^ data_in[23]; - -endmodule diff --git a/rtl/eth_crc_32.v b/rtl/eth_crc_32.v deleted file mode 100644 index 76713e44c..000000000 --- a/rtl/eth_crc_32.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Copyright (c) 2014-2016 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 - -/* - * CRC module eth_crc_32 - * - * CRC width: 32 - * Data width: 32 - * CRC polynomial: 32'h4c11db7 - * Configuration: galois - * Bit-reverse: input and output - * - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 - * - * Generated by crcgen.py - * - * crcgen.py -b -r -d 32 -n eth_crc_32 - * - */ -module eth_crc_32 -( - input wire [31:0] data_in, - input wire [31:0] crc_state, - output wire [31:0] crc_next -); - -assign crc_next[0] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[16] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[26] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[16] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[26]; -assign crc_next[1] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[17] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[17] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[27]; -assign crc_next[2] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[18] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[28] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[18] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[28]; -assign crc_next[3] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[19] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[29] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[19] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[29]; -assign crc_next[4] = crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[20] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[30] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[20] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[30]; -assign crc_next[5] = crc_state[0] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[21] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[21] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[31]; -assign crc_next[6] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[20] ^ crc_state[23] ^ crc_state[28] ^ crc_state[29] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[20] ^ data_in[23] ^ data_in[28] ^ data_in[29]; -assign crc_next[7] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[21] ^ crc_state[24] ^ crc_state[29] ^ crc_state[30] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[21] ^ data_in[24] ^ data_in[29] ^ data_in[30]; -assign crc_next[8] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[22] ^ crc_state[25] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[22] ^ data_in[25] ^ data_in[30] ^ data_in[31]; -assign crc_next[9] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[31]; -assign crc_next[10] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[13] ^ crc_state[14] ^ crc_state[18] ^ crc_state[21] ^ crc_state[22] ^ crc_state[26] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[13] ^ data_in[14] ^ data_in[18] ^ data_in[21] ^ data_in[22] ^ data_in[26]; -assign crc_next[11] = crc_state[1] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[10] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[27] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[27]; -assign crc_next[12] = crc_state[2] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[11] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[23] ^ crc_state[24] ^ crc_state[28] ^ data_in[2] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[11] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[28]; -assign crc_next[13] = crc_state[0] ^ crc_state[3] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[24] ^ crc_state[25] ^ crc_state[29] ^ data_in[0] ^ data_in[3] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[24] ^ data_in[25] ^ data_in[29]; -assign crc_next[14] = crc_state[0] ^ crc_state[1] ^ crc_state[4] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[13] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[4] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[13] ^ data_in[17] ^ data_in[18] ^ data_in[22] ^ data_in[25] ^ data_in[26] ^ data_in[30]; -assign crc_next[15] = crc_state[1] ^ crc_state[2] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[14] ^ crc_state[18] ^ crc_state[19] ^ crc_state[23] ^ crc_state[26] ^ crc_state[27] ^ crc_state[31] ^ data_in[1] ^ data_in[2] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[14] ^ data_in[18] ^ data_in[19] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[31]; -assign crc_next[16] = crc_state[1] ^ crc_state[4] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ data_in[1] ^ data_in[4] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[28]; -assign crc_next[17] = crc_state[2] ^ crc_state[5] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[20] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ data_in[2] ^ data_in[5] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29]; -assign crc_next[18] = crc_state[0] ^ crc_state[3] ^ crc_state[6] ^ crc_state[9] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[21] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[3] ^ data_in[6] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[21] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[30]; -assign crc_next[19] = crc_state[0] ^ crc_state[1] ^ crc_state[4] ^ crc_state[7] ^ crc_state[10] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[4] ^ data_in[7] ^ data_in[10] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[31]; -assign crc_next[20] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[22] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[22] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31]; -assign crc_next[21] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[22] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[31]; -assign crc_next[22] = crc_state[2] ^ crc_state[7] ^ crc_state[8] ^ crc_state[13] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ data_in[2] ^ data_in[7] ^ data_in[8] ^ data_in[13] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30]; -assign crc_next[23] = crc_state[0] ^ crc_state[3] ^ crc_state[8] ^ crc_state[9] ^ crc_state[14] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[8] ^ data_in[9] ^ data_in[14] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31]; -assign crc_next[24] = crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[15] ^ crc_state[16] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[15] ^ data_in[16] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[31]; -assign crc_next[25] = crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[17] ^ crc_state[20] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[17] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30]; -assign crc_next[26] = crc_state[2] ^ crc_state[3] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[18] ^ crc_state[21] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[18] ^ data_in[21] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31]; -assign crc_next[27] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[19] ^ crc_state[20] ^ crc_state[23] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[19] ^ data_in[20] ^ data_in[23] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[31]; -assign crc_next[28] = crc_state[0] ^ crc_state[4] ^ crc_state[6] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[4] ^ data_in[6] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[28] ^ data_in[29] ^ data_in[30]; -assign crc_next[29] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[7] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[7] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[29] ^ data_in[30] ^ data_in[31]; -assign crc_next[30] = crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[30] ^ crc_state[31] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[14] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[30] ^ data_in[31]; -assign crc_next[31] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[15] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[25] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[15] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[25] ^ data_in[31]; - -endmodule diff --git a/rtl/eth_crc_40.v b/rtl/eth_crc_40.v deleted file mode 100644 index a3cbf9809..000000000 --- a/rtl/eth_crc_40.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Copyright (c) 2014-2016 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 - -/* - * CRC module eth_crc_40 - * - * CRC width: 32 - * Data width: 40 - * CRC polynomial: 32'h4c11db7 - * Configuration: galois - * Bit-reverse: input and output - * - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 - * - * Generated by crcgen.py - * - * crcgen.py -b -r -d 40 -n eth_crc_40 - * - */ -module eth_crc_40 -( - input wire [39:0] data_in, - input wire [31:0] crc_state, - output wire [31:0] crc_next -); - -assign crc_next[0] = crc_state[3] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[24] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[3] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[24] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[34]; -assign crc_next[1] = crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[25] ^ crc_state[29] ^ crc_state[31] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[25] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[35]; -assign crc_next[2] = crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[26] ^ crc_state[30] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[26] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[36]; -assign crc_next[3] = crc_state[6] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[27] ^ crc_state[31] ^ data_in[6] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[27] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[37]; -assign crc_next[4] = crc_state[0] ^ crc_state[7] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[28] ^ data_in[0] ^ data_in[7] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[28] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[38]; -assign crc_next[5] = crc_state[0] ^ crc_state[1] ^ crc_state[8] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[8] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[29] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[39]; -assign crc_next[6] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[28] ^ crc_state[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[28] ^ data_in[31] ^ data_in[36] ^ data_in[37]; -assign crc_next[7] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ crc_state[29] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[29] ^ data_in[32] ^ data_in[37] ^ data_in[38]; -assign crc_next[8] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[30] ^ data_in[33] ^ data_in[38] ^ data_in[39]; -assign crc_next[9] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[39]; -assign crc_next[10] = crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[17] ^ crc_state[21] ^ crc_state[22] ^ crc_state[26] ^ crc_state[29] ^ crc_state[30] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[21] ^ data_in[22] ^ data_in[26] ^ data_in[29] ^ data_in[30] ^ data_in[34]; -assign crc_next[11] = crc_state[0] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[9] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[18] ^ crc_state[22] ^ crc_state[23] ^ crc_state[27] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[18] ^ data_in[22] ^ data_in[23] ^ data_in[27] ^ data_in[30] ^ data_in[31] ^ data_in[35]; -assign crc_next[12] = crc_state[1] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[19] ^ crc_state[23] ^ crc_state[24] ^ crc_state[28] ^ crc_state[31] ^ data_in[1] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[19] ^ data_in[23] ^ data_in[24] ^ data_in[28] ^ data_in[31] ^ data_in[32] ^ data_in[36]; -assign crc_next[13] = crc_state[0] ^ crc_state[2] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[24] ^ crc_state[25] ^ crc_state[29] ^ data_in[0] ^ data_in[2] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[24] ^ data_in[25] ^ data_in[29] ^ data_in[32] ^ data_in[33] ^ data_in[37]; -assign crc_next[14] = crc_state[1] ^ crc_state[3] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[12] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[21] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ data_in[1] ^ data_in[3] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[12] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[21] ^ data_in[25] ^ data_in[26] ^ data_in[30] ^ data_in[33] ^ data_in[34] ^ data_in[38]; -assign crc_next[15] = crc_state[2] ^ crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[13] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[22] ^ crc_state[26] ^ crc_state[27] ^ crc_state[31] ^ data_in[2] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[22] ^ data_in[26] ^ data_in[27] ^ data_in[31] ^ data_in[34] ^ data_in[35] ^ data_in[39]; -assign crc_next[16] = crc_state[5] ^ crc_state[6] ^ crc_state[9] ^ crc_state[12] ^ crc_state[15] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ crc_state[30] ^ crc_state[31] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[12] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[36]; -assign crc_next[17] = crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[13] ^ crc_state[16] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[28] ^ crc_state[31] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[13] ^ data_in[16] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[28] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[37]; -assign crc_next[18] = crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[14] ^ crc_state[17] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[29] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[14] ^ data_in[17] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[29] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[38]; -assign crc_next[19] = crc_state[8] ^ crc_state[9] ^ crc_state[12] ^ crc_state[15] ^ crc_state[18] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[30] ^ data_in[8] ^ data_in[9] ^ data_in[12] ^ data_in[15] ^ data_in[18] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[30] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[39]; -assign crc_next[20] = crc_state[3] ^ crc_state[6] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[30] ^ data_in[3] ^ data_in[6] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[30] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[39]; -assign crc_next[21] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[20] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[20] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[30] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[39]; -assign crc_next[22] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[15] ^ crc_state[16] ^ crc_state[21] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[15] ^ data_in[16] ^ data_in[21] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[38]; -assign crc_next[23] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[16] ^ crc_state[17] ^ crc_state[22] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[16] ^ data_in[17] ^ data_in[22] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[39]; -assign crc_next[24] = crc_state[0] ^ crc_state[2] ^ crc_state[5] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[23] ^ crc_state[24] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[5] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[23] ^ data_in[24] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[39]; -assign crc_next[25] = crc_state[1] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[25] ^ crc_state[28] ^ crc_state[31] ^ data_in[1] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[25] ^ data_in[28] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[38]; -assign crc_next[26] = crc_state[0] ^ crc_state[2] ^ crc_state[10] ^ crc_state[11] ^ crc_state[15] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[26] ^ crc_state[29] ^ data_in[0] ^ data_in[2] ^ data_in[10] ^ data_in[11] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[26] ^ data_in[29] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[39]; -assign crc_next[27] = crc_state[0] ^ crc_state[1] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[24] ^ crc_state[27] ^ crc_state[28] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[24] ^ data_in[27] ^ data_in[28] ^ data_in[31] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[39]; -assign crc_next[28] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[14] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[14] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[36] ^ data_in[37] ^ data_in[38]; -assign crc_next[29] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[15] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[15] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[37] ^ data_in[38] ^ data_in[39]; -assign crc_next[30] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[22] ^ crc_state[23] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[22] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[38] ^ data_in[39]; -assign crc_next[31] = crc_state[2] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[23] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ data_in[2] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[23] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[33] ^ data_in[39]; - -endmodule diff --git a/rtl/eth_crc_48.v b/rtl/eth_crc_48.v deleted file mode 100644 index d733c27f9..000000000 --- a/rtl/eth_crc_48.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Copyright (c) 2014-2016 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 - -/* - * CRC module eth_crc_48 - * - * CRC width: 32 - * Data width: 48 - * CRC polynomial: 32'h4c11db7 - * Configuration: galois - * Bit-reverse: input and output - * - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 - * - * Generated by crcgen.py - * - * crcgen.py -b -r -d 48 -n eth_crc_48 - * - */ -module eth_crc_48 -( - input wire [47:0] data_in, - input wire [31:0] crc_state, - output wire [31:0] crc_next -); - -assign crc_next[0] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[11] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[11] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[32] ^ data_in[36] ^ data_in[38] ^ data_in[39] ^ data_in[42]; -assign crc_next[1] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[33] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[43]; -assign crc_next[2] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[34] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[44]; -assign crc_next[3] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[14] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[14] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[35] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[45]; -assign crc_next[4] = crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[15] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[15] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[36] ^ data_in[40] ^ data_in[42] ^ data_in[43] ^ data_in[46]; -assign crc_next[5] = crc_state[0] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[16] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ data_in[0] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[16] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[37] ^ data_in[41] ^ data_in[43] ^ data_in[44] ^ data_in[47]; -assign crc_next[6] = crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[25] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[32] ^ data_in[36] ^ data_in[39] ^ data_in[44] ^ data_in[45]; -assign crc_next[7] = crc_state[0] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[33] ^ data_in[37] ^ data_in[40] ^ data_in[45] ^ data_in[46]; -assign crc_next[8] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[38] ^ data_in[41] ^ data_in[46] ^ data_in[47]; -assign crc_next[9] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[47]; -assign crc_next[10] = crc_state[5] ^ crc_state[7] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[25] ^ crc_state[29] ^ crc_state[30] ^ data_in[5] ^ data_in[7] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^ data_in[29] ^ data_in[30] ^ data_in[34] ^ data_in[37] ^ data_in[38] ^ data_in[42]; -assign crc_next[11] = crc_state[6] ^ crc_state[8] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[17] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[26] ^ crc_state[30] ^ crc_state[31] ^ data_in[6] ^ data_in[8] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[17] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[26] ^ data_in[30] ^ data_in[31] ^ data_in[35] ^ data_in[38] ^ data_in[39] ^ data_in[43]; -assign crc_next[12] = crc_state[0] ^ crc_state[7] ^ crc_state[9] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ crc_state[27] ^ crc_state[31] ^ data_in[0] ^ data_in[7] ^ data_in[9] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[18] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[27] ^ data_in[31] ^ data_in[32] ^ data_in[36] ^ data_in[39] ^ data_in[40] ^ data_in[44]; -assign crc_next[13] = crc_state[1] ^ crc_state[8] ^ crc_state[10] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[28] ^ data_in[1] ^ data_in[8] ^ data_in[10] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[28] ^ data_in[32] ^ data_in[33] ^ data_in[37] ^ data_in[40] ^ data_in[41] ^ data_in[45]; -assign crc_next[14] = crc_state[0] ^ crc_state[2] ^ crc_state[9] ^ crc_state[11] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[20] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[29] ^ data_in[0] ^ data_in[2] ^ data_in[9] ^ data_in[11] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[20] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[29] ^ data_in[33] ^ data_in[34] ^ data_in[38] ^ data_in[41] ^ data_in[42] ^ data_in[46]; -assign crc_next[15] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[10] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[21] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[28] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[10] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[30] ^ data_in[34] ^ data_in[35] ^ data_in[39] ^ data_in[42] ^ data_in[43] ^ data_in[47]; -assign crc_next[16] = crc_state[2] ^ crc_state[3] ^ crc_state[13] ^ crc_state[14] ^ crc_state[17] ^ crc_state[20] ^ crc_state[23] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[13] ^ data_in[14] ^ data_in[17] ^ data_in[20] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[35] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[42] ^ data_in[43] ^ data_in[44]; -assign crc_next[17] = crc_state[3] ^ crc_state[4] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[21] ^ crc_state[24] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ data_in[3] ^ data_in[4] ^ data_in[14] ^ data_in[15] ^ data_in[18] ^ data_in[21] ^ data_in[24] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[36] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[43] ^ data_in[44] ^ data_in[45]; -assign crc_next[18] = crc_state[0] ^ crc_state[4] ^ crc_state[5] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[22] ^ crc_state[25] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[22] ^ data_in[25] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[37] ^ data_in[40] ^ data_in[41] ^ data_in[42] ^ data_in[44] ^ data_in[45] ^ data_in[46]; -assign crc_next[19] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[6] ^ crc_state[16] ^ crc_state[17] ^ crc_state[20] ^ crc_state[23] ^ crc_state[26] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[16] ^ data_in[17] ^ data_in[20] ^ data_in[23] ^ data_in[26] ^ data_in[29] ^ data_in[30] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[38] ^ data_in[41] ^ data_in[42] ^ data_in[43] ^ data_in[45] ^ data_in[46] ^ data_in[47]; -assign crc_next[20] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[14] ^ crc_state[16] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[27] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[14] ^ data_in[16] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[27] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[35] ^ data_in[38] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[47]; -assign crc_next[21] = crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[28] ^ crc_state[31] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[28] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[38] ^ data_in[42] ^ data_in[44] ^ data_in[45] ^ data_in[47]; -assign crc_next[22] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[23] ^ crc_state[24] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[18] ^ data_in[23] ^ data_in[24] ^ data_in[29] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[42] ^ data_in[43] ^ data_in[45] ^ data_in[46]; -assign crc_next[23] = crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[24] ^ crc_state[25] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[24] ^ data_in[25] ^ data_in[30] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[47]; -assign crc_next[24] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[10] ^ crc_state[13] ^ crc_state[15] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[13] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[31] ^ data_in[32] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[42] ^ data_in[44] ^ data_in[45] ^ data_in[47]; -assign crc_next[25] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[17] ^ data_in[18] ^ data_in[22] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[33] ^ data_in[36] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[42] ^ data_in[43] ^ data_in[45] ^ data_in[46]; -assign crc_next[26] = crc_state[1] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[18] ^ crc_state[19] ^ crc_state[23] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[18] ^ data_in[19] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[34] ^ data_in[37] ^ data_in[40] ^ data_in[41] ^ data_in[42] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[47]; -assign crc_next[27] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[22] ^ crc_state[23] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[22] ^ data_in[23] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[32] ^ data_in[35] ^ data_in[36] ^ data_in[39] ^ data_in[41] ^ data_in[43] ^ data_in[44] ^ data_in[45] ^ data_in[47]; -assign crc_next[28] = crc_state[2] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[22] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[2] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[22] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[44] ^ data_in[45] ^ data_in[46]; -assign crc_next[29] = crc_state[3] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[23] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[3] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[23] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[45] ^ data_in[46] ^ data_in[47]; -assign crc_next[30] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[19] ^ crc_state[20] ^ crc_state[23] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[19] ^ data_in[20] ^ data_in[23] ^ data_in[30] ^ data_in[31] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[46] ^ data_in[47]; -assign crc_next[31] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[10] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[10] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[31] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[41] ^ data_in[47]; - -endmodule diff --git a/rtl/eth_crc_56.v b/rtl/eth_crc_56.v deleted file mode 100644 index 83961de03..000000000 --- a/rtl/eth_crc_56.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Copyright (c) 2014-2016 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 - -/* - * CRC module eth_crc_56 - * - * CRC width: 32 - * Data width: 56 - * CRC polynomial: 32'h4c11db7 - * Configuration: galois - * Bit-reverse: input and output - * - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 - * - * Generated by crcgen.py - * - * crcgen.py -b -r -d 56 -n eth_crc_56 - * - */ -module eth_crc_56 -( - input wire [55:0] data_in, - input wire [31:0] crc_state, - output wire [31:0] crc_next -); - -assign crc_next[0] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[19] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[19] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[40] ^ data_in[44] ^ data_in[46] ^ data_in[47] ^ data_in[50]; -assign crc_next[1] = crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[20] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[20] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[41] ^ data_in[45] ^ data_in[47] ^ data_in[48] ^ data_in[51]; -assign crc_next[2] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[21] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[21] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[42] ^ data_in[46] ^ data_in[48] ^ data_in[49] ^ data_in[52]; -assign crc_next[3] = crc_state[1] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[22] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[22] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[43] ^ data_in[47] ^ data_in[49] ^ data_in[50] ^ data_in[53]; -assign crc_next[4] = crc_state[0] ^ crc_state[2] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[23] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[23] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[44] ^ data_in[48] ^ data_in[50] ^ data_in[51] ^ data_in[54]; -assign crc_next[5] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[24] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[24] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[45] ^ data_in[49] ^ data_in[51] ^ data_in[52] ^ data_in[55]; -assign crc_next[6] = crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[33] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[40] ^ data_in[44] ^ data_in[47] ^ data_in[52] ^ data_in[53]; -assign crc_next[7] = crc_state[0] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[23] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[23] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[41] ^ data_in[45] ^ data_in[48] ^ data_in[53] ^ data_in[54]; -assign crc_next[8] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[24] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[24] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[42] ^ data_in[46] ^ data_in[49] ^ data_in[54] ^ data_in[55]; -assign crc_next[9] = crc_state[0] ^ crc_state[3] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[24] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[24] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[41] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[55]; -assign crc_next[10] = crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[13] ^ crc_state[15] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[24] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[13] ^ data_in[15] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[24] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[31] ^ data_in[33] ^ data_in[37] ^ data_in[38] ^ data_in[42] ^ data_in[45] ^ data_in[46] ^ data_in[50]; -assign crc_next[11] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[14] ^ crc_state[16] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[25] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[14] ^ data_in[16] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[25] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[32] ^ data_in[34] ^ data_in[38] ^ data_in[39] ^ data_in[43] ^ data_in[46] ^ data_in[47] ^ data_in[51]; -assign crc_next[12] = crc_state[1] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[15] ^ crc_state[17] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[26] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[15] ^ data_in[17] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[26] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[33] ^ data_in[35] ^ data_in[39] ^ data_in[40] ^ data_in[44] ^ data_in[47] ^ data_in[48] ^ data_in[52]; -assign crc_next[13] = crc_state[2] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[16] ^ crc_state[18] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ crc_state[29] ^ crc_state[31] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[16] ^ data_in[18] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[36] ^ data_in[40] ^ data_in[41] ^ data_in[45] ^ data_in[48] ^ data_in[49] ^ data_in[53]; -assign crc_next[14] = crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[17] ^ crc_state[19] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[28] ^ crc_state[30] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[17] ^ data_in[19] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[28] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[35] ^ data_in[37] ^ data_in[41] ^ data_in[42] ^ data_in[46] ^ data_in[49] ^ data_in[50] ^ data_in[54]; -assign crc_next[15] = crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[18] ^ crc_state[20] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[29] ^ crc_state[31] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[18] ^ data_in[20] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[29] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[36] ^ data_in[38] ^ data_in[42] ^ data_in[43] ^ data_in[47] ^ data_in[50] ^ data_in[51] ^ data_in[55]; -assign crc_next[16] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[10] ^ crc_state[11] ^ crc_state[21] ^ crc_state[22] ^ crc_state[25] ^ crc_state[28] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[10] ^ data_in[11] ^ data_in[21] ^ data_in[22] ^ data_in[25] ^ data_in[28] ^ data_in[31] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[43] ^ data_in[46] ^ data_in[47] ^ data_in[48] ^ data_in[50] ^ data_in[51] ^ data_in[52]; -assign crc_next[17] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[12] ^ crc_state[22] ^ crc_state[23] ^ crc_state[26] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[12] ^ data_in[22] ^ data_in[23] ^ data_in[26] ^ data_in[29] ^ data_in[32] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[44] ^ data_in[47] ^ data_in[48] ^ data_in[49] ^ data_in[51] ^ data_in[52] ^ data_in[53]; -assign crc_next[18] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[13] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[13] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[30] ^ data_in[33] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[45] ^ data_in[48] ^ data_in[49] ^ data_in[50] ^ data_in[52] ^ data_in[53] ^ data_in[54]; -assign crc_next[19] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[14] ^ crc_state[24] ^ crc_state[25] ^ crc_state[28] ^ crc_state[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[14] ^ data_in[24] ^ data_in[25] ^ data_in[28] ^ data_in[31] ^ data_in[34] ^ data_in[37] ^ data_in[38] ^ data_in[40] ^ data_in[42] ^ data_in[43] ^ data_in[46] ^ data_in[49] ^ data_in[50] ^ data_in[51] ^ data_in[53] ^ data_in[54] ^ data_in[55]; -assign crc_next[20] = crc_state[0] ^ crc_state[1] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[22] ^ crc_state[24] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[22] ^ data_in[24] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[35] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[43] ^ data_in[46] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[55]; -assign crc_next[21] = crc_state[0] ^ crc_state[3] ^ crc_state[5] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ data_in[0] ^ data_in[3] ^ data_in[5] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[36] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[46] ^ data_in[50] ^ data_in[52] ^ data_in[53] ^ data_in[55]; -assign crc_next[22] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[26] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[26] ^ data_in[31] ^ data_in[32] ^ data_in[37] ^ data_in[42] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[50] ^ data_in[51] ^ data_in[53] ^ data_in[54]; -assign crc_next[23] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[32] ^ data_in[33] ^ data_in[38] ^ data_in[43] ^ data_in[44] ^ data_in[45] ^ data_in[47] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[55]; -assign crc_next[24] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[18] ^ crc_state[21] ^ crc_state[23] ^ crc_state[26] ^ crc_state[27] ^ crc_state[30] ^ crc_state[31] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[18] ^ data_in[21] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[39] ^ data_in[40] ^ data_in[45] ^ data_in[47] ^ data_in[48] ^ data_in[50] ^ data_in[52] ^ data_in[53] ^ data_in[55]; -assign crc_next[25] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[25] ^ data_in[26] ^ data_in[30] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[41] ^ data_in[44] ^ data_in[47] ^ data_in[48] ^ data_in[49] ^ data_in[50] ^ data_in[51] ^ data_in[53] ^ data_in[54]; -assign crc_next[26] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[9] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[26] ^ crc_state[27] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[26] ^ data_in[27] ^ data_in[31] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[42] ^ data_in[45] ^ data_in[48] ^ data_in[49] ^ data_in[50] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[55]; -assign crc_next[27] = crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[30] ^ crc_state[31] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[30] ^ data_in[31] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[40] ^ data_in[43] ^ data_in[44] ^ data_in[47] ^ data_in[49] ^ data_in[51] ^ data_in[52] ^ data_in[53] ^ data_in[55]; -assign crc_next[28] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[10] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[28] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[10] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[28] ^ data_in[30] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[45] ^ data_in[46] ^ data_in[47] ^ data_in[48] ^ data_in[52] ^ data_in[53] ^ data_in[54]; -assign crc_next[29] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[11] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[11] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[29] ^ data_in[31] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[46] ^ data_in[47] ^ data_in[48] ^ data_in[49] ^ data_in[53] ^ data_in[54] ^ data_in[55]; -assign crc_next[30] = crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[27] ^ crc_state[28] ^ crc_state[31] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[27] ^ data_in[28] ^ data_in[31] ^ data_in[38] ^ data_in[39] ^ data_in[42] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[48] ^ data_in[49] ^ data_in[54] ^ data_in[55]; -assign crc_next[31] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[18] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[18] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[39] ^ data_in[43] ^ data_in[45] ^ data_in[46] ^ data_in[49] ^ data_in[55]; - -endmodule diff --git a/rtl/eth_crc_64.v b/rtl/eth_crc_64.v deleted file mode 100644 index 3ddb549b2..000000000 --- a/rtl/eth_crc_64.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Copyright (c) 2014-2016 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 - -/* - * CRC module eth_crc_64 - * - * CRC width: 32 - * Data width: 64 - * CRC polynomial: 32'h4c11db7 - * Configuration: galois - * Bit-reverse: input and output - * - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 - * - * Generated by crcgen.py - * - * crcgen.py -b -r -d 64 -n eth_crc_64 - * - */ -module eth_crc_64 -( - input wire [63:0] data_in, - input wire [31:0] crc_state, - output wire [31:0] crc_next -); - -assign crc_next[0] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[27] ^ crc_state[30] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[27] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[48] ^ data_in[52] ^ data_in[54] ^ data_in[55] ^ data_in[58]; -assign crc_next[1] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[15] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[28] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[28] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[49] ^ data_in[53] ^ data_in[55] ^ data_in[56] ^ data_in[59]; -assign crc_next[2] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[29] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[29] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[42] ^ data_in[50] ^ data_in[54] ^ data_in[56] ^ data_in[57] ^ data_in[60]; -assign crc_next[3] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[30] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[43] ^ data_in[51] ^ data_in[55] ^ data_in[57] ^ data_in[58] ^ data_in[61]; -assign crc_next[4] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[10] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[31] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[42] ^ data_in[43] ^ data_in[44] ^ data_in[52] ^ data_in[56] ^ data_in[58] ^ data_in[59] ^ data_in[62]; -assign crc_next[5] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[32] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[43] ^ data_in[44] ^ data_in[45] ^ data_in[53] ^ data_in[57] ^ data_in[59] ^ data_in[60] ^ data_in[63]; -assign crc_next[6] = crc_state[1] ^ crc_state[2] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[30] ^ data_in[1] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[30] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[41] ^ data_in[42] ^ data_in[44] ^ data_in[45] ^ data_in[46] ^ data_in[48] ^ data_in[52] ^ data_in[55] ^ data_in[60] ^ data_in[61]; -assign crc_next[7] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[31] ^ data_in[33] ^ data_in[35] ^ data_in[36] ^ data_in[42] ^ data_in[43] ^ data_in[45] ^ data_in[46] ^ data_in[47] ^ data_in[49] ^ data_in[53] ^ data_in[56] ^ data_in[61] ^ data_in[62]; -assign crc_next[8] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[32] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[47] ^ data_in[48] ^ data_in[50] ^ data_in[54] ^ data_in[57] ^ data_in[62] ^ data_in[63]; -assign crc_next[9] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[11] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[11] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[32] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[44] ^ data_in[45] ^ data_in[47] ^ data_in[49] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[63]; -assign crc_next[10] = crc_state[1] ^ crc_state[2] ^ crc_state[7] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[21] ^ crc_state[23] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ data_in[1] ^ data_in[2] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[21] ^ data_in[23] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[32] ^ data_in[34] ^ data_in[36] ^ data_in[37] ^ data_in[39] ^ data_in[41] ^ data_in[45] ^ data_in[46] ^ data_in[50] ^ data_in[53] ^ data_in[54] ^ data_in[58]; -assign crc_next[11] = crc_state[2] ^ crc_state[3] ^ crc_state[8] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[22] ^ crc_state[24] ^ crc_state[27] ^ crc_state[29] ^ crc_state[30] ^ data_in[2] ^ data_in[3] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[22] ^ data_in[24] ^ data_in[27] ^ data_in[29] ^ data_in[30] ^ data_in[33] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[40] ^ data_in[42] ^ data_in[46] ^ data_in[47] ^ data_in[51] ^ data_in[54] ^ data_in[55] ^ data_in[59]; -assign crc_next[12] = crc_state[3] ^ crc_state[4] ^ crc_state[9] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[23] ^ crc_state[25] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[3] ^ data_in[4] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[23] ^ data_in[25] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[34] ^ data_in[36] ^ data_in[38] ^ data_in[39] ^ data_in[41] ^ data_in[43] ^ data_in[47] ^ data_in[48] ^ data_in[52] ^ data_in[55] ^ data_in[56] ^ data_in[60]; -assign crc_next[13] = crc_state[4] ^ crc_state[5] ^ crc_state[10] ^ crc_state[13] ^ crc_state[14] ^ crc_state[15] ^ crc_state[17] ^ crc_state[24] ^ crc_state[26] ^ crc_state[29] ^ crc_state[31] ^ data_in[4] ^ data_in[5] ^ data_in[10] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^ data_in[17] ^ data_in[24] ^ data_in[26] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[35] ^ data_in[37] ^ data_in[39] ^ data_in[40] ^ data_in[42] ^ data_in[44] ^ data_in[48] ^ data_in[49] ^ data_in[53] ^ data_in[56] ^ data_in[57] ^ data_in[61]; -assign crc_next[14] = crc_state[5] ^ crc_state[6] ^ crc_state[11] ^ crc_state[14] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[25] ^ crc_state[27] ^ crc_state[30] ^ data_in[5] ^ data_in[6] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[25] ^ data_in[27] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[36] ^ data_in[38] ^ data_in[40] ^ data_in[41] ^ data_in[43] ^ data_in[45] ^ data_in[49] ^ data_in[50] ^ data_in[54] ^ data_in[57] ^ data_in[58] ^ data_in[62]; -assign crc_next[15] = crc_state[6] ^ crc_state[7] ^ crc_state[12] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[26] ^ crc_state[28] ^ crc_state[31] ^ data_in[6] ^ data_in[7] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[26] ^ data_in[28] ^ data_in[31] ^ data_in[33] ^ data_in[34] ^ data_in[37] ^ data_in[39] ^ data_in[41] ^ data_in[42] ^ data_in[44] ^ data_in[46] ^ data_in[50] ^ data_in[51] ^ data_in[55] ^ data_in[58] ^ data_in[59] ^ data_in[63]; -assign crc_next[16] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[13] ^ crc_state[14] ^ crc_state[18] ^ crc_state[19] ^ crc_state[29] ^ crc_state[30] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[14] ^ data_in[18] ^ data_in[19] ^ data_in[29] ^ data_in[30] ^ data_in[33] ^ data_in[36] ^ data_in[39] ^ data_in[42] ^ data_in[43] ^ data_in[45] ^ data_in[47] ^ data_in[48] ^ data_in[51] ^ data_in[54] ^ data_in[55] ^ data_in[56] ^ data_in[58] ^ data_in[59] ^ data_in[60]; -assign crc_next[17] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[14] ^ crc_state[15] ^ crc_state[19] ^ crc_state[20] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[15] ^ data_in[19] ^ data_in[20] ^ data_in[30] ^ data_in[31] ^ data_in[34] ^ data_in[37] ^ data_in[40] ^ data_in[43] ^ data_in[44] ^ data_in[46] ^ data_in[48] ^ data_in[49] ^ data_in[52] ^ data_in[55] ^ data_in[56] ^ data_in[57] ^ data_in[59] ^ data_in[60] ^ data_in[61]; -assign crc_next[18] = crc_state[1] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[20] ^ crc_state[21] ^ crc_state[31] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[20] ^ data_in[21] ^ data_in[31] ^ data_in[32] ^ data_in[35] ^ data_in[38] ^ data_in[41] ^ data_in[44] ^ data_in[45] ^ data_in[47] ^ data_in[49] ^ data_in[50] ^ data_in[53] ^ data_in[56] ^ data_in[57] ^ data_in[58] ^ data_in[60] ^ data_in[61] ^ data_in[62]; -assign crc_next[19] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[21] ^ crc_state[22] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[21] ^ data_in[22] ^ data_in[32] ^ data_in[33] ^ data_in[36] ^ data_in[39] ^ data_in[42] ^ data_in[45] ^ data_in[46] ^ data_in[48] ^ data_in[50] ^ data_in[51] ^ data_in[54] ^ data_in[57] ^ data_in[58] ^ data_in[59] ^ data_in[61] ^ data_in[62] ^ data_in[63]; -assign crc_next[20] = crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[12] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[23] ^ crc_state[27] ^ crc_state[30] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[23] ^ data_in[27] ^ data_in[30] ^ data_in[32] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[43] ^ data_in[46] ^ data_in[47] ^ data_in[48] ^ data_in[49] ^ data_in[51] ^ data_in[54] ^ data_in[59] ^ data_in[60] ^ data_in[62] ^ data_in[63]; -assign crc_next[21] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[8] ^ crc_state[11] ^ crc_state[13] ^ crc_state[21] ^ crc_state[23] ^ crc_state[24] ^ crc_state[27] ^ crc_state[28] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[13] ^ data_in[21] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[44] ^ data_in[47] ^ data_in[49] ^ data_in[50] ^ data_in[54] ^ data_in[58] ^ data_in[60] ^ data_in[61] ^ data_in[63]; -assign crc_next[22] = crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[20] ^ crc_state[22] ^ crc_state[24] ^ crc_state[25] ^ crc_state[27] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[34] ^ data_in[39] ^ data_in[40] ^ data_in[45] ^ data_in[50] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[58] ^ data_in[59] ^ data_in[61] ^ data_in[62]; -assign crc_next[23] = crc_state[0] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[23] ^ crc_state[25] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ crc_state[31] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[35] ^ data_in[40] ^ data_in[41] ^ data_in[46] ^ data_in[51] ^ data_in[52] ^ data_in[53] ^ data_in[55] ^ data_in[59] ^ data_in[60] ^ data_in[62] ^ data_in[63]; -assign crc_next[24] = crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[24] ^ crc_state[26] ^ crc_state[29] ^ crc_state[31] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[26] ^ data_in[29] ^ data_in[31] ^ data_in[34] ^ data_in[35] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^ data_in[41] ^ data_in[42] ^ data_in[47] ^ data_in[48] ^ data_in[53] ^ data_in[55] ^ data_in[56] ^ data_in[58] ^ data_in[60] ^ data_in[61] ^ data_in[63]; -assign crc_next[25] = crc_state[1] ^ crc_state[3] ^ crc_state[7] ^ crc_state[8] ^ crc_state[9] ^ crc_state[11] ^ crc_state[12] ^ crc_state[13] ^ crc_state[16] ^ crc_state[18] ^ crc_state[20] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[25] ^ data_in[1] ^ data_in[3] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[33] ^ data_in[34] ^ data_in[38] ^ data_in[41] ^ data_in[42] ^ data_in[43] ^ data_in[49] ^ data_in[52] ^ data_in[55] ^ data_in[56] ^ data_in[57] ^ data_in[58] ^ data_in[59] ^ data_in[61] ^ data_in[62]; -assign crc_next[26] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[17] ^ crc_state[19] ^ crc_state[21] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[26] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[17] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[34] ^ data_in[35] ^ data_in[39] ^ data_in[42] ^ data_in[43] ^ data_in[44] ^ data_in[50] ^ data_in[53] ^ data_in[56] ^ data_in[57] ^ data_in[58] ^ data_in[59] ^ data_in[60] ^ data_in[62] ^ data_in[63]; -assign crc_next[27] = crc_state[0] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[17] ^ crc_state[18] ^ crc_state[19] ^ crc_state[22] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[30] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[30] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[38] ^ data_in[39] ^ data_in[43] ^ data_in[44] ^ data_in[45] ^ data_in[48] ^ data_in[51] ^ data_in[52] ^ data_in[55] ^ data_in[57] ^ data_in[59] ^ data_in[60] ^ data_in[61] ^ data_in[63]; -assign crc_next[28] = crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[9] ^ crc_state[10] ^ crc_state[11] ^ crc_state[18] ^ crc_state[23] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[30] ^ crc_state[31] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[18] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[36] ^ data_in[38] ^ data_in[44] ^ data_in[45] ^ data_in[46] ^ data_in[48] ^ data_in[49] ^ data_in[53] ^ data_in[54] ^ data_in[55] ^ data_in[56] ^ data_in[60] ^ data_in[61] ^ data_in[62]; -assign crc_next[29] = crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[8] ^ crc_state[10] ^ crc_state[11] ^ crc_state[12] ^ crc_state[19] ^ crc_state[24] ^ crc_state[25] ^ crc_state[26] ^ crc_state[27] ^ crc_state[28] ^ crc_state[31] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[19] ^ data_in[24] ^ data_in[25] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[37] ^ data_in[39] ^ data_in[45] ^ data_in[46] ^ data_in[47] ^ data_in[49] ^ data_in[50] ^ data_in[54] ^ data_in[55] ^ data_in[56] ^ data_in[57] ^ data_in[61] ^ data_in[62] ^ data_in[63]; -assign crc_next[30] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[10] ^ crc_state[12] ^ crc_state[13] ^ crc_state[14] ^ crc_state[16] ^ crc_state[17] ^ crc_state[19] ^ crc_state[25] ^ crc_state[26] ^ crc_state[28] ^ crc_state[29] ^ crc_state[30] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[35] ^ data_in[36] ^ data_in[39] ^ data_in[46] ^ data_in[47] ^ data_in[50] ^ data_in[51] ^ data_in[52] ^ data_in[54] ^ data_in[56] ^ data_in[57] ^ data_in[62] ^ data_in[63]; -assign crc_next[31] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[8] ^ crc_state[9] ^ crc_state[10] ^ crc_state[13] ^ crc_state[15] ^ crc_state[16] ^ crc_state[18] ^ crc_state[19] ^ crc_state[26] ^ crc_state[29] ^ crc_state[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[26] ^ data_in[29] ^ data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[47] ^ data_in[51] ^ data_in[53] ^ data_in[54] ^ data_in[57] ^ data_in[63]; - -endmodule diff --git a/rtl/eth_crc_8.v b/rtl/eth_crc_8.v deleted file mode 100644 index 8f4525ac3..000000000 --- a/rtl/eth_crc_8.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Copyright (c) 2014-2016 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 - -/* - * CRC module eth_crc_8 - * - * CRC width: 32 - * Data width: 8 - * CRC polynomial: 32'h4c11db7 - * Configuration: galois - * Bit-reverse: input and output - * - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 - * - * Generated by crcgen.py - * - * crcgen.py -b -r -d 8 -n eth_crc_8 - * - */ -module eth_crc_8 -( - input wire [7:0] data_in, - input wire [31:0] crc_state, - output wire [31:0] crc_next -); - -assign crc_next[0] = crc_state[2] ^ crc_state[8] ^ data_in[2]; -assign crc_next[1] = crc_state[0] ^ crc_state[3] ^ crc_state[9] ^ data_in[0] ^ data_in[3]; -assign crc_next[2] = crc_state[0] ^ crc_state[1] ^ crc_state[4] ^ crc_state[10] ^ data_in[0] ^ data_in[1] ^ data_in[4]; -assign crc_next[3] = crc_state[1] ^ crc_state[2] ^ crc_state[5] ^ crc_state[11] ^ data_in[1] ^ data_in[2] ^ data_in[5]; -assign crc_next[4] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[6] ^ crc_state[12] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[6]; -assign crc_next[5] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[7] ^ crc_state[13] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[7]; -assign crc_next[6] = crc_state[4] ^ crc_state[5] ^ crc_state[14] ^ data_in[4] ^ data_in[5]; -assign crc_next[7] = crc_state[0] ^ crc_state[5] ^ crc_state[6] ^ crc_state[15] ^ data_in[0] ^ data_in[5] ^ data_in[6]; -assign crc_next[8] = crc_state[1] ^ crc_state[6] ^ crc_state[7] ^ crc_state[16] ^ data_in[1] ^ data_in[6] ^ data_in[7]; -assign crc_next[9] = crc_state[7] ^ crc_state[17] ^ data_in[7]; -assign crc_next[10] = crc_state[2] ^ crc_state[18] ^ data_in[2]; -assign crc_next[11] = crc_state[3] ^ crc_state[19] ^ data_in[3]; -assign crc_next[12] = crc_state[0] ^ crc_state[4] ^ crc_state[20] ^ data_in[0] ^ data_in[4]; -assign crc_next[13] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[21] ^ data_in[0] ^ data_in[1] ^ data_in[5]; -assign crc_next[14] = crc_state[1] ^ crc_state[2] ^ crc_state[6] ^ crc_state[22] ^ data_in[1] ^ data_in[2] ^ data_in[6]; -assign crc_next[15] = crc_state[2] ^ crc_state[3] ^ crc_state[7] ^ crc_state[23] ^ data_in[2] ^ data_in[3] ^ data_in[7]; -assign crc_next[16] = crc_state[0] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[24] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4]; -assign crc_next[17] = crc_state[0] ^ crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[25] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5]; -assign crc_next[18] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ crc_state[26] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6]; -assign crc_next[19] = crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ crc_state[27] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7]; -assign crc_next[20] = crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[28] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7]; -assign crc_next[21] = crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ crc_state[29] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7]; -assign crc_next[22] = crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ crc_state[30] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6]; -assign crc_next[23] = crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ crc_state[31] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7]; -assign crc_next[24] = crc_state[0] ^ crc_state[2] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7]; -assign crc_next[25] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[5] ^ crc_state[6] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6]; -assign crc_next[26] = crc_state[0] ^ crc_state[1] ^ crc_state[2] ^ crc_state[3] ^ crc_state[4] ^ crc_state[6] ^ crc_state[7] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7]; -assign crc_next[27] = crc_state[1] ^ crc_state[3] ^ crc_state[4] ^ crc_state[5] ^ crc_state[7] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7]; -assign crc_next[28] = crc_state[0] ^ crc_state[4] ^ crc_state[5] ^ crc_state[6] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[6]; -assign crc_next[29] = crc_state[0] ^ crc_state[1] ^ crc_state[5] ^ crc_state[6] ^ crc_state[7] ^ data_in[0] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[7]; -assign crc_next[30] = crc_state[0] ^ crc_state[1] ^ crc_state[6] ^ crc_state[7] ^ data_in[0] ^ data_in[1] ^ data_in[6] ^ data_in[7]; -assign crc_next[31] = crc_state[1] ^ crc_state[7] ^ data_in[1] ^ data_in[7]; - -endmodule From 8c7a099a91846647f6eb342fba9f665ad21a1ee5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Jun 2016 18:58:25 -0700 Subject: [PATCH 281/617] Update readme --- README.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 475475a1f..f66735f8d 100644 --- a/README.md +++ b/README.md @@ -93,10 +93,6 @@ Ethernet frame transmitter. Ethernet frame transmitter with 64 bit datapath for 10G Ethernet. -### eth_crc_N module - -CRC logic for Ethernet frame check sequence, N input data bits. - ### eth_demux_N module Ethernet frame demuliplexer with 8 bit data width for gigabit Ethernet. @@ -241,6 +237,10 @@ priority and round-robin arbitration. Can be generated with arbitrary port counts with ip_mux_64.py. +### lfsr module + +Fully parametrizable combinatorial parallel LFSR/CRC module. + ### udp module UDP block with 8 bit data width for gigabit Ethernet. Manages UDP packet @@ -354,14 +354,6 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/eth_axis_rx_64.v : Ethernet frame receiver (64 bit) rtl/eth_axis_tx.v : Ethernet frame transmitter rtl/eth_axis_tx_64.v : Ethernet frame transmitter (64 bit) - rtl/eth_crc_8.v : Ethernet CRC logic, 8 bits - rtl/eth_crc_16.v : Ethernet CRC logic, 16 bits - rtl/eth_crc_24.v : Ethernet CRC logic, 24 bits - rtl/eth_crc_32.v : Ethernet CRC logic, 32 bits - rtl/eth_crc_40.v : Ethernet CRC logic, 40 bits - rtl/eth_crc_48.v : Ethernet CRC logic, 48 bits - rtl/eth_crc_56.v : Ethernet CRC logic, 56 bits - rtl/eth_crc_64.v : Ethernet CRC logic, 64 bits rtl/eth_demux.py : Ethernet frame demultiplexer generator rtl/eth_demux_4.v : 4 port Ethernet frame demultiplexer rtl/eth_demux_64.py : Ethernet frame demultiplexer generator (64 bit) @@ -401,6 +393,7 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/ip_mux_4.v : 4 port IP frame multiplexer rtl/ip_mux_64.py : IP frame multiplexer generator (64 bit) rtl/ip_mux_64_4.v : 4 port IP frame multiplexer (64 bit) + rtl/lfsr.v : Generic LFSR/CRC module rtl/udp.v : UDP block rtl/udp_64.v : UDP block (64 bit) rtl/udp_arb_mux.py : UDP frame arbitrated multiplexer generator From b38c643384797694a36f01901f9764d3928f263b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 28 Jun 2016 19:35:52 -0700 Subject: [PATCH 282/617] Add more implementation parameters to gmii_phy_if --- example/ATLYS/fpga/rtl/fpga_core.v | 4 +- rtl/gmii_phy_if.v | 135 +++++++++++++++++++++++------ 2 files changed, 112 insertions(+), 27 deletions(-) diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index 2828b2b7c..20d26a1ca 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -318,7 +318,9 @@ assign phy_reset_n = ~rst; assign uart_txd = 0; gmii_phy_if #( - .TARGET(TARGET) + .TARGET(TARGET), + .IODDR_STYLE("IODDR2"), + .CLOCK_INPUT_STYLE("BUFIO2") ) gmii_phy_if_inst ( .clk(clk), diff --git a/rtl/gmii_phy_if.v b/rtl/gmii_phy_if.v index ee15ce183..2dc7fb34c 100644 --- a/rtl/gmii_phy_if.v +++ b/rtl/gmii_phy_if.v @@ -32,7 +32,15 @@ THE SOFTWARE. module gmii_phy_if # ( // target ("SIM", "GENERIC", "XILINX", "ALTERA") - parameter TARGET = "GENERIC" + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2" ) ( input wire clk, @@ -75,21 +83,83 @@ if (TARGET == "XILINX") begin // use Xilinx clocking primitives - // pass through RX clock to input buffers - BUFIO2 - phy_gmii_rx_clk_bufio ( - .I(phy_gmii_rx_clk), - .DIVCLK(phy_gmii_rx_clk_int), - .IOCLK(phy_gmii_rx_clk_io), - .SERDESSTROBE() - ); + if (CLOCK_INPUT_STYLE == "BUFG") begin - // pass through RX clock to MAC - BUFG - phy_gmii_rx_clk_bufg ( - .I(phy_gmii_rx_clk_int), - .O(mac_gmii_rx_clk) - ); + // buffer RX clock + BUFG + phy_gmii_rx_clk_bufg ( + .I(phy_gmii_rx_clk), + .O(phy_gmii_rx_clk_int) + ); + + // pass through RX clock to MAC and input buffers + assign phy_gmii_rx_clk_io = phy_gmii_rx_clk_int; + assign mac_gmii_rx_clk = phy_gmii_rx_clk_int; + + end else if (CLOCK_INPUT_STYLE == "BUFR") begin + + assign phy_gmii_rx_clk_int = phy_gmii_rx_clk; + + // pass through RX clock to input buffers + BUFIO + phy_gmii_rx_clk_bufio ( + .I(phy_gmii_rx_clk_int), + .O(phy_gmii_rx_clk_io) + ); + + // pass through RX clock to MAC + BUFR #( + .BUFR_DIVIDE("BYPASS") + ) + phy_gmii_rx_clk_bufr ( + .I(phy_gmii_rx_clk_int), + .O(mac_gmii_rx_clk), + .CE(1'b1), + .CLR(1'b0) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO") begin + + assign phy_gmii_rx_clk_int = phy_gmii_rx_clk; + + // pass through RX clock to input buffers + BUFIO + phy_gmii_rx_clk_bufio ( + .I(phy_gmii_rx_clk_int), + .O(phy_gmii_rx_clk_io) + ); + + // pass through RX clock to MAC + BUFG + phy_gmii_rx_clk_bufg ( + .I(phy_gmii_rx_clk_int), + .O(mac_gmii_rx_clk) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO2") begin + + // pass through RX clock to input buffers + BUFIO2 #( + .DIVIDE(1), + .DIVIDE_BYPASS("TRUE"), + .I_INVERT("FALSE"), + .USE_DOUBLER("FALSE") + ) + phy_gmii_rx_clk_bufio ( + .I(phy_gmii_rx_clk), + .DIVCLK(phy_gmii_rx_clk_int), + .IOCLK(phy_gmii_rx_clk_io), + .SERDESSTROBE() + ); + + // pass through RX clock to MAC + BUFG + phy_gmii_rx_clk_bufg ( + .I(phy_gmii_rx_clk_int), + .O(mac_gmii_rx_clk) + ); + + end // pass through clock to MAC assign mac_gmii_tx_clk = clk; @@ -98,17 +168,30 @@ if (TARGET == "XILINX") begin assign phy_gmii_tx_clk_int = clk; // invert to center clock edge in valid window - ODDR2 - phy_gmii_tx_clk_oddr ( - .Q(phy_gmii_tx_clk), - .C0(phy_gmii_tx_clk_int), - .C1(~phy_gmii_tx_clk_int), - .CE(1'b1), - .D0(1'b0), - .D1(1'b1), - .R(1'b0), - .S(1'b0) - ); + if (IODDR_STYLE == "IODDR") begin + ODDR + phy_gmii_tx_clk_oddr ( + .Q(phy_gmii_tx_clk), + .C(phy_gmii_tx_clk_int), + .CE(1'b1), + .D1(1'b0), + .D2(1'b1), + .R(1'b0), + .S(1'b0) + ); + end else if (IODDR_STYLE == "IODDR2") begin + ODDR2 + phy_gmii_tx_clk_oddr ( + .Q(phy_gmii_tx_clk), + .C0(phy_gmii_tx_clk_int), + .C1(~phy_gmii_tx_clk_int), + .CE(1'b1), + .D0(1'b0), + .D1(1'b1), + .R(1'b0), + .S(1'b0) + ); + end end else begin From a430e4463ec73661673d5d7da828c2654d2118af Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 29 Jun 2016 06:13:46 -0700 Subject: [PATCH 283/617] Add RGMII endpoint and PHY interface module --- rtl/rgmii_phy_if.v | 579 +++++++++++++++++++++++++++++++++++++++++++++ tb/rgmii_ep.py | 90 +++++++ 2 files changed, 669 insertions(+) create mode 100644 rtl/rgmii_phy_if.v create mode 100644 tb/rgmii_ep.py diff --git a/rtl/rgmii_phy_if.v b/rtl/rgmii_phy_if.v new file mode 100644 index 000000000..2e9706187 --- /dev/null +++ b/rtl/rgmii_phy_if.v @@ -0,0 +1,579 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * RGMII PHY interface + */ +module rgmii_phy_if # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + // Use 90 degree clock for RGMII transmit ("TRUE", "FALSE") + parameter USE_CLK90 = "TRUE" +) +( + input wire clk, + input wire clk90, + input wire rst, + + /* + * GMII interface to MAC + */ + output wire mac_gmii_rx_clk, + output wire mac_gmii_rx_rst, + output wire [7:0] mac_gmii_rxd, + output wire mac_gmii_rx_dv, + output wire mac_gmii_rx_er, + output wire mac_gmii_tx_clk, + output wire mac_gmii_tx_rst, + input wire [7:0] mac_gmii_txd, + input wire mac_gmii_tx_en, + input wire mac_gmii_tx_er, + + /* + * RGMII interface to PHY + */ + input wire phy_rgmii_rx_clk, + input wire [3:0] phy_rgmii_rxd, + input wire phy_rgmii_rx_ctl, + output wire phy_rgmii_tx_clk, + output wire [3:0] phy_rgmii_txd, + output wire phy_rgmii_tx_ctl +); + +wire phy_rgmii_rx_clk_int; +wire phy_rgmii_rx_clk_io; +wire phy_rgmii_tx_clk_int; +wire phy_rgmii_tx_ref_clk_int; + +generate + +if (TARGET == "XILINX") begin + + // use Xilinx clocking primitives + + if (CLOCK_INPUT_STYLE == "BUFG") begin + + // buffer RX clock + BUFG + phy_rgmii_rx_clk_bufg ( + .I(phy_rgmii_rx_clk), + .O(phy_rgmii_rx_clk_int) + ); + + // pass through RX clock to MAC and input buffers + assign phy_rgmii_rx_clk_io = phy_rgmii_rx_clk_int; + assign mac_gmii_rx_clk = phy_rgmii_rx_clk_int; + + end else if (CLOCK_INPUT_STYLE == "BUFR") begin + + assign phy_rgmii_rx_clk_int = phy_rgmii_rx_clk; + + // pass through RX clock to input buffers + BUFIO + phy_rgmii_rx_clk_bufio ( + .I(phy_rgmii_rx_clk_int), + .O(phy_rgmii_rx_clk_io) + ); + + // pass through RX clock to MAC + BUFR #( + .BUFR_DIVIDE("BYPASS") + ) + phy_rgmii_rx_clk_bufr ( + .I(phy_rgmii_rx_clk_int), + .O(mac_gmii_rx_clk), + .CE(1'b1), + .CLR(1'b0) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO") begin + + assign phy_rgmii_rx_clk_int = phy_rgmii_rx_clk; + + // pass through RX clock to input buffers + BUFIO + phy_rgmii_rx_clk_bufio ( + .I(phy_rgmii_rx_clk_int), + .O(phy_rgmii_rx_clk_io) + ); + + // pass through RX clock to MAC + BUFG + phy_rgmii_rx_clk_bufg ( + .I(phy_rgmii_rx_clk_int), + .O(mac_gmii_rx_clk) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO2") begin + + // pass through RX clock to input buffers + BUFIO2 #( + .DIVIDE(1), + .DIVIDE_BYPASS("TRUE"), + .I_INVERT("FALSE"), + .USE_DOUBLER("FALSE") + ) + phy_rgmii_rx_clk_bufio ( + .I(phy_rgmii_rx_clk), + .DIVCLK(phy_rgmii_rx_clk_int), + .IOCLK(phy_rgmii_rx_clk_io), + .SERDESSTROBE() + ); + + // pass through RX clock to MAC + BUFG + phy_rgmii_rx_clk_bufg ( + .I(phy_rgmii_rx_clk_int), + .O(mac_gmii_rx_clk) + ); + + end + + // pass through clock to MAC + assign mac_gmii_tx_clk = clk; + + // pass through clock to PHY + assign phy_rgmii_tx_clk_int = clk; + assign phy_rgmii_tx_ref_clk_int = USE_CLK90 == "TRUE" ? clk90 : phy_rgmii_tx_clk_int; + + // pass through clock to PHY + if (IODDR_STYLE == "IODDR") begin + ODDR + phy_gmii_tx_clk_oddr ( + .Q(phy_rgmii_tx_clk), + .C(phy_rgmii_tx_ref_clk_int), + .CE(1'b1), + .D1(1'b1), + .D2(1'b0), + .R(1'b0), + .S(1'b0) + ); + end else if (IODDR_STYLE == "IODDR2") begin + ODDR2 + phy_gmii_tx_clk_oddr ( + .Q(phy_rgmii_tx_clk), + .C0(phy_rgmii_tx_ref_clk_int), + .C1(~phy_rgmii_tx_ref_clk_int), + .C0(clk90), + .C1(~clk90), + .CE(1'b1), + .D0(1'b1), + .D1(1'b0), + .R(1'b0), + .S(1'b0) + ); + end + +end else begin + + // pass through RX clock to input buffers + assign phy_rgmii_rx_clk_io = phy_rgmii_rx_clk; + + // pass through RX clock to MAC + assign phy_rgmii_rx_clk_int = phy_rgmii_rx_clk; + assign mac_gmii_rx_clk = phy_rgmii_rx_clk_int; + + // pass through clock to MAC + assign mac_gmii_tx_clk = clk; + + // pass through clock to PHY + assign phy_rgmii_tx_clk_int = clk; + assign phy_rgmii_tx_ref_clk_int = USE_CLK90 == "TRUE" ? clk90 : phy_rgmii_tx_clk_int; + + // pass through clock to phy + assign phy_rgmii_tx_clk = phy_rgmii_tx_ref_clk_int; + +end + +endgenerate + +// reset sync +reg [3:0] tx_rst_reg = 4'hf; +assign mac_gmii_tx_rst = tx_rst_reg[0]; + +always @(posedge mac_gmii_tx_clk or posedge rst) begin + if (rst) begin + tx_rst_reg <= 4'hf; + end else begin + tx_rst_reg <= {1'b0, tx_rst_reg[3:1]}; + end +end + +reg [3:0] rx_rst_reg = 4'hf; +assign mac_gmii_rx_rst = rx_rst_reg[0]; + +always @(posedge mac_gmii_rx_clk or posedge rst) begin + if (rst) begin + rx_rst_reg <= 4'hf; + end else begin + rx_rst_reg <= {1'b0, rx_rst_reg[3:1]}; + end +end + +generate + +if (TARGET == "XILINX") begin + // register RX data from PHY to MAC + wire rgmii_rx_ctl_1; + wire rgmii_rx_ctl_2; + + if (IODDR_STYLE == "IODDR") begin + IDDR #( + .DDR_CLK_EDGE("SAME_EDGE_PIPELINED") + ) + phy_rgmii_rxd_iddr_0 ( + .Q1(mac_gmii_rxd[0]), + .Q2(mac_gmii_rxd[4]), + .C(phy_rgmii_rx_clk_io), + .CE(1'b1), + .D(phy_rgmii_rxd[0]), + .R(1'b0), + .S(1'b0) + ); + IDDR #( + .DDR_CLK_EDGE("SAME_EDGE_PIPELINED") + ) + phy_rgmii_rxd_iddr_1 ( + .Q1(mac_gmii_rxd[1]), + .Q2(mac_gmii_rxd[5]), + .C(phy_rgmii_rx_clk_io), + .CE(1'b1), + .D(phy_rgmii_rxd[1]), + .R(1'b0), + .S(1'b0) + ); + IDDR #( + .DDR_CLK_EDGE("SAME_EDGE_PIPELINED") + ) + phy_rgmii_rxd_iddr_2 ( + .Q1(mac_gmii_rxd[2]), + .Q2(mac_gmii_rxd[6]), + .C(phy_rgmii_rx_clk_io), + .CE(1'b1), + .D(phy_rgmii_rxd[2]), + .R(1'b0), + .S(1'b0) + ); + IDDR #( + .DDR_CLK_EDGE("SAME_EDGE_PIPELINED") + ) + phy_rgmii_rxd_iddr_3 ( + .Q1(mac_gmii_rxd[3]), + .Q2(mac_gmii_rxd[7]), + .C(phy_rgmii_rx_clk_io), + .CE(1'b1), + .D(phy_rgmii_rxd[3]), + .R(1'b0), + .S(1'b0) + ); + IDDR #( + .DDR_CLK_EDGE("SAME_EDGE_PIPELINED") + ) + phy_rgmii_rx_ctl_iddr ( + .Q1(rgmii_rx_ctl_1), + .Q2(rgmii_rx_ctl_2), + .C(phy_rgmii_rx_clk_io), + .CE(1'b1), + .D(phy_rgmii_rx_ctl), + .R(1'b0), + .S(1'b0) + ); + end else if (IODDR_STYLE == "IODDR2") begin + IDDR2 #( + .DDR_ALIGNMENT("C0") + ) + phy_rgmii_rxd_iddr_0 ( + .Q0(mac_gmii_rxd[0]), + .Q1(mac_gmii_rxd[4]), + .C0(phy_rgmii_rx_clk_io), + .C1(~phy_rgmii_rx_clk_io), + .CE(1'b1), + .D(phy_rgmii_rxd[0]), + .R(1'b0), + .S(1'b0) + ); + IDDR2 #( + .DDR_ALIGNMENT("C0") + ) + phy_rgmii_rxd_iddr_1 ( + .Q0(mac_gmii_rxd[1]), + .Q1(mac_gmii_rxd[5]), + .C0(phy_rgmii_rx_clk_io), + .C1(~phy_rgmii_rx_clk_io), + .CE(1'b1), + .D(phy_rgmii_rxd[1]), + .R(1'b0), + .S(1'b0) + ); + IDDR2 #( + .DDR_ALIGNMENT("C0") + ) + phy_rgmii_rxd_iddr_2 ( + .Q0(mac_gmii_rxd[2]), + .Q1(mac_gmii_rxd[6]), + .C0(phy_rgmii_rx_clk_io), + .C1(~phy_rgmii_rx_clk_io), + .CE(1'b1), + .D(phy_rgmii_rxd[2]), + .R(1'b0), + .S(1'b0) + ); + IDDR2 #( + .DDR_ALIGNMENT("C0") + ) + phy_rgmii_rxd_iddr_3 ( + .Q0(mac_gmii_rxd[3]), + .Q1(mac_gmii_rxd[7]), + .C0(phy_rgmii_rx_clk_io), + .C1(~phy_rgmii_rx_clk_io), + .CE(1'b1), + .D(phy_rgmii_rxd[3]), + .R(1'b0), + .S(1'b0) + ); + IDDR2 #( + .DDR_ALIGNMENT("C0") + ) + phy_rgmii_rx_ctl_iddr ( + .Q0(rgmii_rx_ctl_1), + .Q1(rgmii_rx_ctl_2), + .C0(phy_rgmii_rx_clk_io), + .C1(~phy_rgmii_rx_clk_io), + .CE(1'b1), + .D(phy_rgmii_rx_ctl), + .R(1'b0), + .S(1'b0) + ); + end + + assign mac_gmii_rx_dv = rgmii_rx_ctl_1; + assign mac_gmii_rx_er = rgmii_rx_ctl_1 ^ rgmii_rx_ctl_2; + + // register TX data from MAC to PHY + if (IODDR_STYLE == "IODDR") begin + ODDR #( + .DDR_CLK_EDGE("SAME_EDGE") + ) + phy_rgmii_txd_oddr_0 ( + .Q(phy_rgmii_txd[0]), + .C(phy_rgmii_tx_clk_int), + .CE(1'b1), + .D1(mac_gmii_txd[0]), + .D2(mac_gmii_txd[4]), + .R(1'b0), + .S(1'b0) + ); + ODDR #( + .DDR_CLK_EDGE("SAME_EDGE") + ) + phy_rgmii_txd_oddr_1 ( + .Q(phy_rgmii_txd[1]), + .C(phy_rgmii_tx_clk_int), + .CE(1'b1), + .D1(mac_gmii_txd[1]), + .D2(mac_gmii_txd[5]), + .R(1'b0), + .S(1'b0) + ); + ODDR #( + .DDR_CLK_EDGE("SAME_EDGE") + ) + phy_rgmii_txd_oddr_2 ( + .Q(phy_rgmii_txd[2]), + .C(phy_rgmii_tx_clk_int), + .CE(1'b1), + .D1(mac_gmii_txd[2]), + .D2(mac_gmii_txd[6]), + .R(1'b0), + .S(1'b0) + ); + ODDR #( + .DDR_CLK_EDGE("SAME_EDGE") + ) + phy_rgmii_txd_oddr_3 ( + .Q(phy_rgmii_txd[3]), + .C(phy_rgmii_tx_clk_int), + .CE(1'b1), + .D1(mac_gmii_txd[3]), + .D2(mac_gmii_txd[7]), + .R(1'b0), + .S(1'b0) + ); + ODDR #( + .DDR_CLK_EDGE("SAME_EDGE") + ) + phy_rgmii_tx_ctl_oddr ( + .Q(phy_rgmii_tx_ctl), + .C(phy_rgmii_tx_clk_int), + .CE(1'b1), + .D1(mac_gmii_tx_en), + .D2(mac_gmii_tx_en ^ mac_gmii_tx_er), + .R(1'b0), + .S(1'b0) + ); + end else if (IODDR_STYLE == "IODDR2") begin + ODDR2 #( + .DDR_ALIGNMENT("C0") + ) + phy_rgmii_txd_oddr_0 ( + .Q(phy_rgmii_txd[0]), + .C0(phy_rgmii_tx_clk_int), + .C1(~phy_rgmii_tx_clk_int), + .CE(1'b1), + .D0(mac_gmii_txd[0]), + .D1(mac_gmii_txd[4]), + .R(1'b0), + .S(1'b0) + ); + ODDR2 #( + .DDR_ALIGNMENT("C0") + ) + phy_rgmii_txd_oddr_1 ( + .Q(phy_rgmii_txd[1]), + .C0(phy_rgmii_tx_clk_int), + .C1(~phy_rgmii_tx_clk_int), + .CE(1'b1), + .D0(mac_gmii_txd[1]), + .D1(mac_gmii_txd[5]), + .R(1'b0), + .S(1'b0) + ); + ODDR2 #( + .DDR_ALIGNMENT("C0") + ) + phy_rgmii_txd_oddr_2 ( + .Q(phy_rgmii_txd[2]), + .C0(phy_rgmii_tx_clk_int), + .C1(~phy_rgmii_tx_clk_int), + .CE(1'b1), + .D0(mac_gmii_txd[2]), + .D1(mac_gmii_txd[6]), + .R(1'b0), + .S(1'b0) + ); + ODDR2 #( + .DDR_ALIGNMENT("C0") + ) + phy_rgmii_txd_oddr_3 ( + .Q(phy_rgmii_txd[3]), + .C0(phy_rgmii_tx_clk_int), + .C1(~phy_rgmii_tx_clk_int), + .CE(1'b1), + .D0(mac_gmii_txd[3]), + .D1(mac_gmii_txd[7]), + .R(1'b0), + .S(1'b0) + ); + ODDR2 #( + .DDR_ALIGNMENT("C0") + ) + phy_rgmii_tx_ctl_oddr ( + .Q(phy_rgmii_tx_ctl), + .C0(phy_rgmii_tx_clk_int), + .C1(~phy_rgmii_tx_clk_int), + .CE(1'b1), + .D0(mac_gmii_tx_en), + .D1(mac_gmii_tx_en ^ mac_gmii_tx_er), + .R(1'b0), + .S(1'b0) + ); + end + +end else if (TARGET == "ALTERA") begin + +end else begin + // register RX data from PHY to MAC + reg [7:0] gmii_rxd_reg = 8'd0; + reg gmii_rx_dv_reg = 1'b0; + reg gmii_rx_er_reg = 1'b0; + + reg [3:0] rgmii_rxd_reg_1 = 4'd0; + reg [3:0] rgmii_rxd_reg_2 = 4'd0; + reg rgmii_rx_ctl_reg_1 = 1'b0; + reg rgmii_rx_ctl_reg_2 = 1'b0; + + always @(posedge phy_rgmii_rx_clk_io) begin + rgmii_rxd_reg_1 <= phy_rgmii_rxd; + rgmii_rx_ctl_reg_1 <= phy_rgmii_rx_ctl; + end + + always @(negedge phy_rgmii_rx_clk_io) begin + rgmii_rxd_reg_2 <= phy_rgmii_rxd; + rgmii_rx_ctl_reg_2 <= phy_rgmii_rx_ctl; + end + + always @(posedge phy_rgmii_rx_clk_io) begin + gmii_rxd_reg <= {rgmii_rxd_reg_2, rgmii_rxd_reg_1}; + gmii_rx_dv_reg <= rgmii_rx_ctl_reg_1; + gmii_rx_er_reg <= rgmii_rx_ctl_reg_1 ^ rgmii_rx_ctl_reg_2; + end + + assign mac_gmii_rxd = gmii_rxd_reg; + assign mac_gmii_rx_dv = gmii_rx_dv_reg; + assign mac_gmii_rx_er = gmii_rx_er_reg; + + // register TX data from MAC to PHY + reg [7:0] gmii_txd_reg = 8'd0; + reg gmii_tx_en_reg = 1'b0; + reg gmii_tx_er_reg = 1'b0; + + reg [3:0] rgmii_txd_reg = 4'd0; + reg rgmii_tx_ctl_reg = 1'b0; + + always @(posedge phy_rgmii_tx_clk_int) begin + rgmii_txd_reg <= mac_gmii_txd[3:0]; + rgmii_tx_ctl_reg <= mac_gmii_tx_en; + end + + always @(negedge phy_rgmii_tx_clk_int) begin + rgmii_txd_reg <= gmii_txd_reg[7:4]; + rgmii_tx_ctl_reg <= gmii_tx_en_reg ^ gmii_tx_er_reg; + end + + always @(posedge phy_rgmii_tx_clk_int) begin + gmii_txd_reg <= mac_gmii_txd; + gmii_tx_en_reg <= mac_gmii_tx_en; + gmii_tx_er_reg <= mac_gmii_tx_er; + end + + assign phy_rgmii_txd = rgmii_txd_reg; + assign phy_rgmii_tx_ctl = rgmii_tx_ctl_reg; +end + +endgenerate + +endmodule diff --git a/tb/rgmii_ep.py b/tb/rgmii_ep.py new file mode 100644 index 000000000..a686c7703 --- /dev/null +++ b/tb/rgmii_ep.py @@ -0,0 +1,90 @@ +""" + +Copyright (c) 2014-2016 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 gmii_ep + +def RGMIISource(clk, rst, + txd, + tx_ctl, + fifo=None, + name=None): + + gmii_txd = Signal(intbv(0)[8:]) + gmii_tx_en = Signal(bool(0)) + gmii_tx_er = Signal(bool(0)) + + gmii_txd_reg = Signal(intbv(0)[8:]) + gmii_tx_en_reg = Signal(bool(0)) + gmii_tx_er_reg = Signal(bool(0)) + + gmii_source = gmii_ep.GMIISource(clk, rst, gmii_txd, gmii_tx_en, gmii_tx_er, fifo, name) + + @instance + def logic(): + while True: + yield clk.negedge + txd.next = gmii_txd_reg[4:0] + tx_ctl.next = gmii_tx_en_reg + yield clk.posedge + txd.next = gmii_txd_reg[8:4] + tx_ctl.next = gmii_tx_en_reg ^ gmii_tx_er_reg + gmii_txd_reg.next = gmii_txd + gmii_tx_en_reg.next = gmii_tx_en + gmii_tx_er_reg.next = gmii_tx_er + + return gmii_source, logic + + +def RGMIISink(clk, rst, + rxd, + rx_ctl, + fifo=None, + name=None): + + gmii_rxd = Signal(intbv(0)[8:]) + gmii_rx_dv = Signal(bool(0)) + gmii_rx_er = Signal(bool(0)) + + gmii_sink = gmii_ep.GMIISink(clk, rst, gmii_rxd, gmii_rx_dv, gmii_rx_er, fifo, name) + + @instance + def logic(): + dat = 0 + ctl1 = 0 + ctl2 = 0 + + while True: + yield clk.posedge + gmii_rxd.next = dat + gmii_rx_dv.next = ctl1 + gmii_rx_er.next = ctl1 ^ ctl2 + dat = int(rxd.val) + ctl1 = int(rx_ctl.val) + yield clk.negedge + dat |= int(rxd.val) << 4 + ctl2 = int(rx_ctl.val) + + return gmii_sink, logic From cbf1df718abfd1f01b4b9f08970d1c29277294f9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 29 Jun 2016 12:00:05 -0700 Subject: [PATCH 284/617] Add example design for Digilent Nexys Video board --- example/NexysVideo/fpga/Makefile | 25 + example/NexysVideo/fpga/README.md | 26 + example/NexysVideo/fpga/common/vivado.mk | 113 ++++ example/NexysVideo/fpga/eth.xdc | 5 + example/NexysVideo/fpga/fpga.xdc | 68 ++ example/NexysVideo/fpga/fpga/Makefile | 50 ++ .../fpga/fpga/generate_bit_iodelay.tcl | 6 + example/NexysVideo/fpga/lib/eth | 1 + example/NexysVideo/fpga/rtl/debounce_switch.v | 89 +++ example/NexysVideo/fpga/rtl/fpga.v | 370 +++++++++++ example/NexysVideo/fpga/rtl/fpga_core.v | 598 ++++++++++++++++++ example/NexysVideo/fpga/rtl/sync_reset.v | 52 ++ example/NexysVideo/fpga/rtl/sync_signal.v | 58 ++ example/NexysVideo/fpga/tb/arp_ep.py | 1 + example/NexysVideo/fpga/tb/axis_ep.py | 1 + example/NexysVideo/fpga/tb/eth_ep.py | 1 + example/NexysVideo/fpga/tb/gmii_ep.py | 1 + example/NexysVideo/fpga/tb/ip_ep.py | 1 + example/NexysVideo/fpga/tb/rgmii_ep.py | 1 + example/NexysVideo/fpga/tb/test_fpga_core.py | 349 ++++++++++ example/NexysVideo/fpga/tb/test_fpga_core.v | 121 ++++ example/NexysVideo/fpga/tb/udp_ep.py | 1 + 22 files changed, 1938 insertions(+) create mode 100644 example/NexysVideo/fpga/Makefile create mode 100644 example/NexysVideo/fpga/README.md create mode 100644 example/NexysVideo/fpga/common/vivado.mk create mode 100644 example/NexysVideo/fpga/eth.xdc create mode 100644 example/NexysVideo/fpga/fpga.xdc create mode 100644 example/NexysVideo/fpga/fpga/Makefile create mode 100644 example/NexysVideo/fpga/fpga/generate_bit_iodelay.tcl create mode 120000 example/NexysVideo/fpga/lib/eth create mode 100644 example/NexysVideo/fpga/rtl/debounce_switch.v create mode 100644 example/NexysVideo/fpga/rtl/fpga.v create mode 100644 example/NexysVideo/fpga/rtl/fpga_core.v create mode 100644 example/NexysVideo/fpga/rtl/sync_reset.v create mode 100644 example/NexysVideo/fpga/rtl/sync_signal.v create mode 120000 example/NexysVideo/fpga/tb/arp_ep.py create mode 120000 example/NexysVideo/fpga/tb/axis_ep.py create mode 120000 example/NexysVideo/fpga/tb/eth_ep.py create mode 120000 example/NexysVideo/fpga/tb/gmii_ep.py create mode 120000 example/NexysVideo/fpga/tb/ip_ep.py create mode 120000 example/NexysVideo/fpga/tb/rgmii_ep.py create mode 100755 example/NexysVideo/fpga/tb/test_fpga_core.py create mode 100644 example/NexysVideo/fpga/tb/test_fpga_core.v create mode 120000 example/NexysVideo/fpga/tb/udp_ep.py diff --git a/example/NexysVideo/fpga/Makefile b/example/NexysVideo/fpga/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/NexysVideo/fpga/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/NexysVideo/fpga/README.md b/example/NexysVideo/fpga/README.md new file mode 100644 index 000000000..e3ebba018 --- /dev/null +++ b/example/NexysVideo/fpga/README.md @@ -0,0 +1,26 @@ +# Verilog Ethernet Nexys Video Example Design + +## Introduction + +This example design targets the Digilent Nexys Video FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +FPGA: XC7A200TSBG484-1 +PHY: Realtek RTL8211E + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the Nexys Video board with the Digilent command +line tools. Then run netcat -u 192.168.1.128 1234 to open a UDP connection to +port 1234. Any text entered into netcat will be echoed back after pressing +enter. + + diff --git a/example/NexysVideo/fpga/common/vivado.mk b/example/NexysVideo/fpga/common/vivado.mk new file mode 100644 index 000000000..74e914718 --- /dev/null +++ b/example/NexysVideo/fpga/common/vivado.mk @@ -0,0 +1,113 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.tcl *.html *.xml .Xil defines.v + +clean: tmpclean + -rm -rf *.bit + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/NexysVideo/fpga/eth.xdc b/example/NexysVideo/fpga/eth.xdc new file mode 100644 index 000000000..d9780aa1c --- /dev/null +++ b/example/NexysVideo/fpga/eth.xdc @@ -0,0 +1,5 @@ +# Ethernet constraints + +# IDELAY on RGMII from PHY chip +set_property IDELAY_VALUE 0 [get_cells {phy_rx_ctl_idelay phy_rxd_idelay_*}] + diff --git a/example/NexysVideo/fpga/fpga.xdc b/example/NexysVideo/fpga/fpga.xdc new file mode 100644 index 000000000..b6b1580d7 --- /dev/null +++ b/example/NexysVideo/fpga/fpga.xdc @@ -0,0 +1,68 @@ +# XDC constraints for the Digilent Nexys Video board +# part: xc7a200tsbg484-1 + +# General configuration +set_property CFGBVS VCCO [current_design] +set_property CONFIG_VOLTAGE 3.3 [current_design] + +# 100 MHz clock +set_property -dict {LOC R4 IOSTANDARD LVCMOS33} [get_ports clk] +create_clock -period 10.000 -name clk [get_ports clk] +set_clock_groups -asynchronous -group clk + +# LEDs +set_property -dict {LOC T14 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[0]}] +set_property -dict {LOC T15 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[1]}] +set_property -dict {LOC T16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[2]}] +set_property -dict {LOC U16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[3]}] +set_property -dict {LOC V15 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[4]}] +set_property -dict {LOC W16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[5]}] +set_property -dict {LOC W15 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[6]}] +set_property -dict {LOC Y13 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[7]}] + +# Reset button +set_property -dict {LOC G4 IOSTANDARD LVCMOS15} [get_ports reset_n] + +# Push buttons +set_property -dict {LOC F15 IOSTANDARD LVCMOS12} [get_ports btnu] +set_property -dict {LOC C22 IOSTANDARD LVCMOS12} [get_ports btnl] +set_property -dict {LOC D22 IOSTANDARD LVCMOS12} [get_ports btnd] +set_property -dict {LOC D14 IOSTANDARD LVCMOS12} [get_ports btnr] +set_property -dict {LOC B22 IOSTANDARD LVCMOS12} [get_ports btnc] + +# Toggle switches +set_property -dict {LOC E22 IOSTANDARD LVCMOS12} [get_ports {sw[0]}] +set_property -dict {LOC F21 IOSTANDARD LVCMOS12} [get_ports {sw[1]}] +set_property -dict {LOC G21 IOSTANDARD LVCMOS12} [get_ports {sw[2]}] +set_property -dict {LOC G22 IOSTANDARD LVCMOS12} [get_ports {sw[3]}] +set_property -dict {LOC H17 IOSTANDARD LVCMOS12} [get_ports {sw[4]}] +set_property -dict {LOC J16 IOSTANDARD LVCMOS12} [get_ports {sw[5]}] +set_property -dict {LOC K13 IOSTANDARD LVCMOS12} [get_ports {sw[6]}] +set_property -dict {LOC M17 IOSTANDARD LVCMOS12} [get_ports {sw[7]}] + +# UART +set_property -dict {LOC AA19 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports uart_txd] +set_property -dict {LOC V18 IOSTANDARD LVCMOS33} [get_ports uart_rxd] + +# Gigabit Ethernet RGMII PHY +set_property -dict {LOC V13 IOSTANDARD LVCMOS25} [get_ports phy_rx_clk] +set_property -dict {LOC AB16 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[0]}] +set_property -dict {LOC AA15 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[1]}] +set_property -dict {LOC AB15 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[2]}] +set_property -dict {LOC AB11 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[3]}] +set_property -dict {LOC W10 IOSTANDARD LVCMOS25} [get_ports phy_rx_ctl] +set_property -dict {LOC AA14 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports phy_tx_clk] +set_property -dict {LOC Y12 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[0]}] +set_property -dict {LOC W12 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[1]}] +set_property -dict {LOC W11 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[2]}] +set_property -dict {LOC Y11 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[3]}] +set_property -dict {LOC V10 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports phy_tx_ctl] +set_property -dict {LOC U7 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_reset_n] +set_property -dict {LOC Y14 IOSTANDARD LVCMOS25} [get_ports phy_int_n] +set_property -dict {LOC W14 IOSTANDARD LVCMOS25} [get_ports phy_pme_n] +#set_property -dict {LOC Y16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports phy_mdio] +#set_property -dict {LOC AA16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports phy_mdc] + +create_clock -period 8.000 -name phy_rx_clk [get_ports phy_rx_clk] +set_clock_groups -asynchronous -group phy_rx_clk + diff --git a/example/NexysVideo/fpga/fpga/Makefile b/example/NexysVideo/fpga/fpga/Makefile new file mode 100644 index 000000000..733bb785f --- /dev/null +++ b/example/NexysVideo/fpga/fpga/Makefile @@ -0,0 +1,50 @@ + +# FPGA settings +FPGA_PART = xc7a200t-sbg484-1 +FPGA_TOP = fpga +FPGA_ARCH = artix7 + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/rgmii_phy_if.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v +SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v +SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += eth.xdc + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + djtgcfg prog -d NexysVideo --index 0 --file $(FPGA_TOP).bit + diff --git a/example/NexysVideo/fpga/fpga/generate_bit_iodelay.tcl b/example/NexysVideo/fpga/fpga/generate_bit_iodelay.tcl new file mode 100644 index 000000000..d97f96678 --- /dev/null +++ b/example/NexysVideo/fpga/fpga/generate_bit_iodelay.tcl @@ -0,0 +1,6 @@ +open_project fpga.xpr +open_run impl_1 +set_property IDELAY_VALUE 0 [get_cells {phy_rx_ctl_idelay phy_rxd_idelay_*}] +set_property CLKOUT1_PHASE 90 [get_cells clk_mmcm_inst] +write_bitstream -force fpga.bit +exit diff --git a/example/NexysVideo/fpga/lib/eth b/example/NexysVideo/fpga/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/NexysVideo/fpga/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/NexysVideo/fpga/rtl/debounce_switch.v b/example/NexysVideo/fpga/rtl/debounce_switch.v new file mode 100644 index 000000000..3e2dc20a5 --- /dev/null +++ b/example/NexysVideo/fpga/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/NexysVideo/fpga/rtl/fpga.v b/example/NexysVideo/fpga/rtl/fpga.v new file mode 100644 index 000000000..ba18ea96e --- /dev/null +++ b/example/NexysVideo/fpga/rtl/fpga.v @@ -0,0 +1,370 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 100MHz + * Reset: Push button, active low + */ + input wire clk, + input wire reset_n, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T RGMII + */ + input wire phy_rx_clk, + input wire [3:0] phy_rxd, + input wire phy_rx_ctl, + output wire phy_tx_clk, + output wire [3:0] phy_txd, + output wire phy_tx_ctl, + output wire phy_reset_n, + input wire phy_int_n, + input wire phy_pme_n, + + /* + * UART: 500000 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd +); + +// Clock and reset + +wire clk_ibufg; +wire clk_bufg; +wire clk_mmcm_out; + +// Internal 125 MHz clock +wire clk_int; +wire rst_int; + +wire mmcm_rst = ~reset_n; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFG +clk_ibufg_inst( + .I(clk), + .O(clk_ibufg) +); + +wire clk90_mmcm_out; +wire clk90_int; + +wire clk_200_mmcm_out; +wire clk_200_int; + +// MMCM instance +// 100 MHz in, 125 MHz out +// PFD range: 10 MHz to 550 MHz +// VCO range: 600 MHz to 1200 MHz +// M = 10, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +// Need two 125 MHz outputs with 90 degree offset +// Also need 200 MHz out for IODELAY +// 1000 / 5 = 200 MHz +MMCME2_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(8), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(90), + .CLKOUT2_DIVIDE(5), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(10), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(10.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(clk90_mmcm_out), + .CLKOUT1B(), + .CLKOUT2(clk_200_mmcm_out), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_bufg_inst ( + .I(clk_mmcm_out), + .O(clk_int) +); + +BUFG +clk90_bufg_inst ( + .I(clk90_mmcm_out), + .O(clk90_int) +); + +BUFG +clk_200_bufg_inst ( + .I(clk_200_mmcm_out), + .O(clk_200_int) +); + +sync_reset #( + .N(4) +) +sync_reset_inst ( + .clk(clk_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_int) +); + +// GPIO +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [7:0] sw_int; + +debounce_switch #( + .WIDTH(13), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_int), + .rst(rst_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +sync_signal #( + .WIDTH(1), + .N(2) +) +sync_signal_inst ( + .clk(clk_int), + .in({uart_rxd}), + .out({uart_rxd_int}) +); + +// IODELAY elements for RGMII interface to PHY +wire [3:0] phy_rxd_delay; +wire phy_rx_ctl_delay; + +IDELAYCTRL +idelayctrl_inst +( + .REFCLK(clk_200_int), + .RST(rst_int), + .RDY() +); + +IDELAYE2 #( + .IDELAY_TYPE("FIXED") +) +phy_rxd_idelay_0 +( + .IDATAIN(phy_rxd[0]), + .DATAOUT(phy_rxd_delay[0]), + .DATAIN(1'b0), + .C(1'b0), + .CE(1'b0), + .INC(1'b0), + .CINVCTRL(1'b0), + .CNTVALUEIN(5'd0), + .CNTVALUEOUT(), + .LD(1'b0), + .LDPIPEEN(1'b0), + .REGRST(1'b0) +); + +IDELAYE2 #( + .IDELAY_TYPE("FIXED") +) +phy_rxd_idelay_1 +( + .IDATAIN(phy_rxd[1]), + .DATAOUT(phy_rxd_delay[1]), + .DATAIN(1'b0), + .C(1'b0), + .CE(1'b0), + .INC(1'b0), + .CINVCTRL(1'b0), + .CNTVALUEIN(5'd0), + .CNTVALUEOUT(), + .LD(1'b0), + .LDPIPEEN(1'b0), + .REGRST(1'b0) +); + +IDELAYE2 #( + .IDELAY_TYPE("FIXED") +) +phy_rxd_idelay_2 +( + .IDATAIN(phy_rxd[2]), + .DATAOUT(phy_rxd_delay[2]), + .DATAIN(1'b0), + .C(1'b0), + .CE(1'b0), + .INC(1'b0), + .CINVCTRL(1'b0), + .CNTVALUEIN(5'd0), + .CNTVALUEOUT(), + .LD(1'b0), + .LDPIPEEN(1'b0), + .REGRST(1'b0) +); + +IDELAYE2 #( + .IDELAY_TYPE("FIXED") +) +phy_rxd_idelay_3 +( + .IDATAIN(phy_rxd[3]), + .DATAOUT(phy_rxd_delay[3]), + .DATAIN(1'b0), + .C(1'b0), + .CE(1'b0), + .INC(1'b0), + .CINVCTRL(1'b0), + .CNTVALUEIN(5'd0), + .CNTVALUEOUT(), + .LD(1'b0), + .LDPIPEEN(1'b0), + .REGRST(1'b0) +); + +IDELAYE2 #( + .IDELAY_TYPE("FIXED") +) +phy_rx_ctl_idelay +( + .IDATAIN(phy_rx_ctl), + .DATAOUT(phy_rx_ctl_delay), + .DATAIN(1'b0), + .C(1'b0), + .CE(1'b0), + .INC(1'b0), + .CINVCTRL(1'b0), + .CNTVALUEIN(5'd0), + .CNTVALUEOUT(), + .LD(1'b0), + .LDPIPEEN(1'b0), + .REGRST(1'b0) +); + +fpga_core +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk(clk_int), + .clk90(clk90_int), + .rst(rst_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .led(led), + /* + * Ethernet: 1000BASE-T RGMII + */ + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd_delay), + .phy_rx_ctl(phy_rx_ctl_delay), + .phy_tx_clk(phy_tx_clk), + .phy_txd(phy_txd), + .phy_tx_ctl(phy_tx_ctl), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + .phy_pme_n(phy_pme_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd) +); + +endmodule diff --git a/example/NexysVideo/fpga/rtl/fpga_core.v b/example/NexysVideo/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..574d8fd98 --- /dev/null +++ b/example/NexysVideo/fpga/rtl/fpga_core.v @@ -0,0 +1,598 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 125MHz + * Synchronous reset + */ + input wire clk, + input wire clk90, + input wire rst, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T RGMII + */ + input wire phy_rx_clk, + input wire [3:0] phy_rxd, + input wire phy_rx_ctl, + output wire phy_tx_clk, + output wire [3:0] phy_txd, + output wire phy_tx_ctl, + output wire phy_reset_n, + input wire phy_int_n, + input wire phy_pme_n, + + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd +); + +// GMII between MAC and PHY IF +wire gmii_rx_clk; +wire gmii_rx_rst; +wire [7:0] gmii_rxd; +wire gmii_rx_dv; +wire gmii_rx_er; + +wire gmii_tx_clk; +wire gmii_tx_rst; +wire [7:0] gmii_txd; +wire gmii_tx_en; +wire gmii_tx_er; + +// AXI between MAC and Ethernet modules +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [7:0] tx_axis_tdata; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [7:0] rx_eth_payload_tdata; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [7:0] tx_eth_payload_tdata; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [7:0] rx_ip_payload_tdata; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [7:0] tx_ip_payload_tdata; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [7:0] rx_udp_payload_tdata; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_tdata; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [7:0] rx_fifo_udp_payload_tdata; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [7:0] tx_fifo_udp_payload_tdata; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_tvalid; + if (tx_udp_payload_tvalid & ~valid_last) begin + led_reg <= tx_udp_payload_tdata; + end + end +end + +//assign led = sw; +assign led = led_reg; +assign phy_reset_n = ~rst; + +assign uart_txd = 0; + +rgmii_phy_if #( + .TARGET(TARGET), + .IODDR_STYLE("IODDR"), + .CLOCK_INPUT_STYLE("BUFR"), + .USE_CLK90("TRUE") +) +rgmii_phy_if_inst ( + .clk(clk), + .clk90(clk90), + .rst(rst), + + .mac_gmii_rx_clk(gmii_rx_clk), + .mac_gmii_rx_rst(gmii_rx_rst), + .mac_gmii_rxd(gmii_rxd), + .mac_gmii_rx_dv(gmii_rx_dv), + .mac_gmii_rx_er(gmii_rx_er), + .mac_gmii_tx_clk(gmii_tx_clk), + .mac_gmii_tx_rst(gmii_tx_rst), + .mac_gmii_txd(gmii_txd), + .mac_gmii_tx_en(gmii_tx_en), + .mac_gmii_tx_er(gmii_tx_er), + + .phy_rgmii_rx_clk(phy_rx_clk), + .phy_rgmii_rxd(phy_rxd), + .phy_rgmii_rx_ctl(phy_rx_ctl), + .phy_rgmii_tx_clk(phy_tx_clk), + .phy_rgmii_txd(phy_txd), + .phy_rgmii_tx_ctl(phy_tx_ctl) +); + +eth_mac_1g_fifo #( + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .RX_FIFO_ADDR_WIDTH(12) +) +eth_mac_1g_fifo_inst ( + .rx_clk(gmii_rx_clk), + .rx_rst(gmii_rx_rst), + .tx_clk(gmii_tx_clk), + .tx_rst(gmii_tx_rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + + .ifg_delay(12) +); + +eth_axis_rx +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete #( + .UDP_CHECKSUM_ENABLE(0) +) +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(0) +); + +axis_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/NexysVideo/fpga/rtl/sync_reset.v b/example/NexysVideo/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..ddd99febe --- /dev/null +++ b/example/NexysVideo/fpga/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/NexysVideo/fpga/rtl/sync_signal.v b/example/NexysVideo/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..5afcd7170 --- /dev/null +++ b/example/NexysVideo/fpga/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/NexysVideo/fpga/tb/arp_ep.py b/example/NexysVideo/fpga/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/NexysVideo/fpga/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/NexysVideo/fpga/tb/axis_ep.py b/example/NexysVideo/fpga/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/NexysVideo/fpga/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/NexysVideo/fpga/tb/eth_ep.py b/example/NexysVideo/fpga/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/NexysVideo/fpga/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/NexysVideo/fpga/tb/gmii_ep.py b/example/NexysVideo/fpga/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/NexysVideo/fpga/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/NexysVideo/fpga/tb/ip_ep.py b/example/NexysVideo/fpga/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/NexysVideo/fpga/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/NexysVideo/fpga/tb/rgmii_ep.py b/example/NexysVideo/fpga/tb/rgmii_ep.py new file mode 120000 index 000000000..986c56280 --- /dev/null +++ b/example/NexysVideo/fpga/tb/rgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/rgmii_ep.py \ No newline at end of file diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.py b/example/NexysVideo/fpga/tb/test_fpga_core.py new file mode 100755 index 000000000..514466595 --- /dev/null +++ b/example/NexysVideo/fpga/tb/test_fpga_core.py @@ -0,0 +1,349 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import eth_ep +import arp_ep +import udp_ep +import rgmii_ep + +module = 'fpga_core' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/rgmii_phy_if.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp.v") +srcs.append("../lib/eth/rtl/udp_ip_rx.v") +srcs.append("../lib/eth/rtl/udp_ip_tx.v") +srcs.append("../lib/eth/rtl/ip_complete.v") +srcs.append("../lib/eth/rtl/ip.v") +srcs.append("../lib/eth/rtl/ip_eth_rx.v") +srcs.append("../lib/eth/rtl/ip_eth_tx.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") +srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") +srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_fpga_core(clk, + clk90, + rst, + + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + led, + + phy_rx_clk, + phy_rxd, + phy_rx_ctl, + phy_tx_clk, + phy_txd, + phy_tx_ctl, + phy_reset_n, + phy_int_n, + phy_pme_n, + + uart_rxd, + uart_txd): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + clk90=clk90, + rst=rst, + current_test=current_test, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, + + phy_rx_clk=phy_rx_clk, + phy_rxd=phy_rxd, + phy_rx_ctl=phy_rx_ctl, + phy_tx_clk=phy_tx_clk, + phy_txd=phy_txd, + phy_tx_ctl=phy_tx_ctl, + phy_reset_n=phy_reset_n, + phy_int_n=phy_int_n, + phy_pme_n=phy_pme_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd) + +def bench(): + + # Parameters + TARGET = "SIM" + + # Inputs + clk = Signal(bool(0)) + clk90 = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[8:]) + phy_rx_clk = Signal(bool(0)) + phy_rxd = Signal(intbv(0)[4:]) + phy_rx_ctl = Signal(bool(0)) + phy_int_n = Signal(bool(1)) + phy_pme_n = Signal(bool(1)) + uart_rxd = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[8:]) + phy_tx_clk = Signal(bool(0)) + phy_txd = Signal(intbv(0)[4:]) + phy_tx_ctl = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_txd = Signal(bool(0)) + + # sources and sinks + rgmii_source_queue = Queue() + rgmii_sink_queue = Queue() + + rgmii_source = rgmii_ep.RGMIISource(phy_rx_clk, + rst, + txd=phy_rxd, + tx_ctl=phy_rx_ctl, + fifo=rgmii_source_queue, + name='rgmii_source') + + rgmii_sink = rgmii_ep.RGMIISink(phy_tx_clk, + rst, + rxd=phy_txd, + rx_ctl=phy_tx_ctl, + fifo=rgmii_sink_queue, + name='rgmii_sink') + + # DUT + dut = dut_fpga_core(clk, + clk90, + rst, + current_test, + + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + led, + + phy_rx_clk, + phy_rxd, + phy_rx_ctl, + phy_tx_clk, + phy_txd, + phy_tx_ctl, + phy_reset_n, + phy_int_n, + phy_pme_n, + + uart_rxd, + uart_txd) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + phy_rx_clk.next = not phy_rx_clk + + @instance + def clkgen2(): + yield delay(4+2) + while True: + clk90.next = not clk90 + yield delay(4) + + @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 + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + rgmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while rgmii_sink_queue.empty(): + yield clk.posedge + + rx_frame = rgmii_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + rgmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while rgmii_sink_queue.empty(): + yield clk.posedge + + rx_frame = rgmii_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert rgmii_source_queue.empty() + assert rgmii_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, rgmii_source, rgmii_sink, clkgen, clkgen2, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.v b/example/NexysVideo/fpga/tb/test_fpga_core.v new file mode 100644 index 000000000..4185a5335 --- /dev/null +++ b/example/NexysVideo/fpga/tb/test_fpga_core.v @@ -0,0 +1,121 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters +parameter TARGET = "SIM"; + +// Inputs +reg clk = 0; +reg clk90 = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [7:0] sw = 0; +reg phy_rx_clk = 0; +reg [3:0] phy_rxd = 0; +reg phy_rx_ctl = 0; +reg phy_int_n = 1; +reg phy_pme_n = 1; +reg uart_rxd = 0; + +// Outputs +wire [7:0] led; +wire phy_tx_clk; +wire [3:0] phy_txd; +wire phy_tx_ctl; +wire phy_reset_n; +wire uart_txd; + +initial begin + // myhdl integration + $from_myhdl(clk, + clk90, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_rx_clk, + phy_rxd, + phy_rx_ctl, + phy_int_n, + phy_pme_n, + uart_rxd); + $to_myhdl(led, + phy_tx_clk, + phy_txd, + phy_tx_ctl, + phy_reset_n, + uart_txd); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core #( + .TARGET(TARGET) +) +UUT ( + .clk(clk), + .clk90(clk90), + .rst(rst), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_ctl(phy_rx_ctl), + .phy_tx_clk(phy_tx_clk), + .phy_txd(phy_txd), + .phy_tx_ctl(phy_tx_ctl), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + .phy_pme_n(phy_pme_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd) +); + +endmodule diff --git a/example/NexysVideo/fpga/tb/udp_ep.py b/example/NexysVideo/fpga/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/NexysVideo/fpga/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file From 1f52bf826d1f02be06564f7d50f02a503edf9a46 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 5 Jul 2016 11:17:16 -0400 Subject: [PATCH 285/617] Update vivado.mk --- example/NexysVideo/fpga/common/vivado.mk | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/example/NexysVideo/fpga/common/vivado.mk b/example/NexysVideo/fpga/common/vivado.mk index 74e914718..a54b530f6 100644 --- a/example/NexysVideo/fpga/common/vivado.mk +++ b/example/NexysVideo/fpga/common/vivado.mk @@ -13,6 +13,7 @@ # SYN_FILES - space-separated list of source files # INC_FILES - space-separated list of include files # XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files # # Example: # @@ -21,6 +22,7 @@ # FPGA_DEVICE = xcvu095-ffva2104-2-e # SYN_FILES = rtl/fpga.v # XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci # include ../common/vivado.mk # ################################################################### @@ -37,6 +39,7 @@ CONFIG ?= config.mk SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) ifdef XDC_FILES XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) @@ -56,10 +59,11 @@ all: fpga fpga: $(FPGA_TOP).bit tmpclean: - -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.tcl *.html *.xml .Xil defines.v + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit + -rm -rf *.bit program.tcl distclean: clean -rm -rf rev @@ -69,7 +73,7 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile +%.xpr: Makefile $(XCI_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done @@ -77,6 +81,7 @@ distclean: clean echo "add_files -fileset sources_1 defines.v" >> create_project.tcl for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl vivado -mode batch -source create_project.tcl From 5afe1d7e1e0b090cd08ec96f27f4e6f6386bc4ec Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 5 Jul 2016 11:52:28 -0400 Subject: [PATCH 286/617] Add example design for VCU108 board --- example/VCU108/fpga_1g/Makefile | 25 + example/VCU108/fpga_1g/README.md | 25 + example/VCU108/fpga_1g/common/vivado.mk | 118 ++++ example/VCU108/fpga_1g/eth.xdc | 4 + example/VCU108/fpga_1g/fpga.xdc | 77 +++ example/VCU108/fpga_1g/fpga/Makefile | 60 ++ .../fpga_1g/ip/gig_ethernet_pcs_pma_0.xci | 126 ++++ example/VCU108/fpga_1g/lib/eth | 1 + example/VCU108/fpga_1g/rtl/debounce_switch.v | 89 +++ example/VCU108/fpga_1g/rtl/fpga.v | 345 +++++++++++ example/VCU108/fpga_1g/rtl/fpga_core.v | 558 ++++++++++++++++++ example/VCU108/fpga_1g/rtl/sync_reset.v | 52 ++ example/VCU108/fpga_1g/rtl/sync_signal.v | 58 ++ example/VCU108/fpga_1g/tb/arp_ep.py | 1 + example/VCU108/fpga_1g/tb/axis_ep.py | 1 + example/VCU108/fpga_1g/tb/eth_ep.py | 1 + example/VCU108/fpga_1g/tb/gmii_ep.py | 1 + example/VCU108/fpga_1g/tb/ip_ep.py | 1 + example/VCU108/fpga_1g/tb/test_fpga_core.py | 353 +++++++++++ example/VCU108/fpga_1g/tb/test_fpga_core.v | 128 ++++ example/VCU108/fpga_1g/tb/udp_ep.py | 1 + 21 files changed, 2025 insertions(+) create mode 100644 example/VCU108/fpga_1g/Makefile create mode 100644 example/VCU108/fpga_1g/README.md create mode 100644 example/VCU108/fpga_1g/common/vivado.mk create mode 100644 example/VCU108/fpga_1g/eth.xdc create mode 100644 example/VCU108/fpga_1g/fpga.xdc create mode 100644 example/VCU108/fpga_1g/fpga/Makefile create mode 100644 example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci create mode 120000 example/VCU108/fpga_1g/lib/eth create mode 100644 example/VCU108/fpga_1g/rtl/debounce_switch.v create mode 100644 example/VCU108/fpga_1g/rtl/fpga.v create mode 100644 example/VCU108/fpga_1g/rtl/fpga_core.v create mode 100644 example/VCU108/fpga_1g/rtl/sync_reset.v create mode 100644 example/VCU108/fpga_1g/rtl/sync_signal.v create mode 120000 example/VCU108/fpga_1g/tb/arp_ep.py create mode 120000 example/VCU108/fpga_1g/tb/axis_ep.py create mode 120000 example/VCU108/fpga_1g/tb/eth_ep.py create mode 120000 example/VCU108/fpga_1g/tb/gmii_ep.py create mode 120000 example/VCU108/fpga_1g/tb/ip_ep.py create mode 100755 example/VCU108/fpga_1g/tb/test_fpga_core.py create mode 100644 example/VCU108/fpga_1g/tb/test_fpga_core.v create mode 120000 example/VCU108/fpga_1g/tb/udp_ep.py diff --git a/example/VCU108/fpga_1g/Makefile b/example/VCU108/fpga_1g/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/VCU108/fpga_1g/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/VCU108/fpga_1g/README.md b/example/VCU108/fpga_1g/README.md new file mode 100644 index 000000000..196c62926 --- /dev/null +++ b/example/VCU108/fpga_1g/README.md @@ -0,0 +1,25 @@ +# Verilog Ethernet VCU108 Example Design + +## Introduction + +This example design targets the Xilinx VCU108 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +FPGA: xcvu095-ffva2104-2-e +PHY: Marvell M88E1111 + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the VCU108 board with Vivado. Then run +netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any text +entered into netcat will be echoed back after pressing enter. + + diff --git a/example/VCU108/fpga_1g/common/vivado.mk b/example/VCU108/fpga_1g/common/vivado.mk new file mode 100644 index 000000000..a54b530f6 --- /dev/null +++ b/example/VCU108/fpga_1g/common/vivado.mk @@ -0,0 +1,118 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile $(XCI_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/VCU108/fpga_1g/eth.xdc b/example/VCU108/fpga_1g/eth.xdc new file mode 100644 index 000000000..35dd05b08 --- /dev/null +++ b/example/VCU108/fpga_1g/eth.xdc @@ -0,0 +1,4 @@ +# Ethernet constraints + +set_property LOC BITSLICE_RX_TX_X1Y35 [get_cells -hier -filter {name =~ */lvds_transceiver_mw/serdes_1_to_10_ser8_i/idelay_cal}] +#set_false_path -to [get_pins -hier -filter {name =~ *idelayctrl_inst/RST} -include_replicated_objects ] diff --git a/example/VCU108/fpga_1g/fpga.xdc b/example/VCU108/fpga_1g/fpga.xdc new file mode 100644 index 000000000..303ca62cd --- /dev/null +++ b/example/VCU108/fpga_1g/fpga.xdc @@ -0,0 +1,77 @@ +# XDC constraints for the Xilinx VCU108 board +# part: xcvu095-ffva2104-2-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] + +# System clocks +# 300 MHz +#set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p] +#set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n] +#create_clock -period 3.333 -name clk_300_mhz_1 [get_ports clk_300mhz_1_p] +#set_clock_groups -asynchronous -group clk_300mhz_1 + +#set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p] +#set_property -dict {LOC G21 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_n] +#create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p] +#set_clock_groups -asynchronous -group clk_300mhz_2 + +# 125 MHz +set_property -dict {LOC BC9 IOSTANDARD LVDS} [get_ports clk_125mhz_p] +set_property -dict {LOC BC8 IOSTANDARD LVDS} [get_ports clk_125mhz_n] +create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] +set_clock_groups -asynchronous -group clk_125mhz + +# 90 MHz +#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] +#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] +#set_clock_groups -asynchronous -group clk_90mhz + +# LEDs +set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] +set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}] +set_property -dict {LOC AY30 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}] +set_property -dict {LOC BB32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[3]}] +set_property -dict {LOC BF32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[4]}] +set_property -dict {LOC AV36 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[5]}] +set_property -dict {LOC AY35 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[6]}] +set_property -dict {LOC BA37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[7]}] + +# Reset button +set_property -dict {LOC E36 IOSTANDARD LVCMOS12} [get_ports reset] + +# Push buttons +set_property -dict {LOC E34 IOSTANDARD LVCMOS12} [get_ports btnu] +set_property -dict {LOC M22 IOSTANDARD LVCMOS12} [get_ports btnl] +set_property -dict {LOC D9 IOSTANDARD LVCMOS12} [get_ports btnd] +set_property -dict {LOC A10 IOSTANDARD LVCMOS12} [get_ports btnr] +set_property -dict {LOC AW27 IOSTANDARD LVCMOS12} [get_ports btnc] + +# DIP switches +set_property -dict {LOC BC40 IOSTANDARD LVCMOS12} [get_ports {sw[0]}] +set_property -dict {LOC L19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}] +set_property -dict {LOC C37 IOSTANDARD LVCMOS12} [get_ports {sw[2]}] +set_property -dict {LOC C38 IOSTANDARD LVCMOS12} [get_ports {sw[3]}] + +# UART +set_property -dict {LOC BE24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] +set_property -dict {LOC BC24 IOSTANDARD LVCMOS18} [get_ports uart_rxd] +set_property -dict {LOC BF24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_rts] +set_property -dict {LOC BD22 IOSTANDARD LVCMOS18} [get_ports uart_cts] + +# Gigabit Ethernet SGMII PHY +set_property -dict {LOC AR24 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_rx_p] +set_property -dict {LOC AT24 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_rx_n] +set_property -dict {LOC AR23 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_tx_p] +set_property -dict {LOC AR22 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_tx_n] +set_property -dict {LOC AT22 IOSTANDARD LVDS_25} [get_ports phy_sgmii_clk_p] +set_property -dict {LOC AU22 IOSTANDARD LVDS_25} [get_ports phy_sgmii_clk_n] +set_property -dict {LOC AU21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_reset_n] +set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports phy_int_n] +#set_property -dict {LOC AV24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdio] +#set_property -dict {LOC AV21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc] + +create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] +set_clock_groups -asynchronous -group phy_sgmii_clk + diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile new file mode 100644 index 000000000..a2ef51802 --- /dev/null +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -0,0 +1,60 @@ + +# FPGA settings +FPGA_PART = xcvu095-ffva2104-2-e +FPGA_TOP = fpga +FPGA_ARCH = VirtexUltrascale + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v +SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v +SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += eth.xdc + +# IP +XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci + +include ../common/vivado.mk + +program: #$(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl + echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "exit" >> program.tcl + vivado -mode batch -source program.tcl + diff --git a/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci new file mode 100644 index 000000000..0b780494e --- /dev/null +++ b/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci @@ -0,0 +1,126 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gig_ethernet_pcs_pma_0 + + + true + 1 + 0 + 0 + DIFF_PAIR_0 + DIFF_PAIR_1 + false + DIFF_PAIR_0 + DIFF_PAIR_1 + virtexu + gig_ethernet_pcs_pma_0 + 50.0 + false + . + false + virtexu + 17 + 9 + 7 + 4 + GTH + false + true + false + false + false + true + 1 + 125 + TXOUTCLK + true + false + gig_ethernet_pcs_pma_0_gt + true + GTHE3 + false + 1 + true + false + false + xcvu095 + false + 1 + true + 1 + gig_ethernet_pcs_pma_0 + Custom + 50.0 + TEMAC + Custom + 0 + false + false + false + GTH + false + 625 + Custom + false + 1G + 1 + LVDS + 125 + TXOUTCLK + DIFF_PAIR_0 + DIFF_PAIR_1 + false + 10_100_1000 + false + SGMII + Include_Shared_Logic_in_Core + Time_of_day + false + DIFF_PAIR_0 + DIFF_PAIR_1 + 1 + false + virtexu + + xcvu095 + ffva2104 + VERILOG + + MIXED + -2 + E + TRUE + TRUE + IP_Flow + 1 + TRUE + . + + . + 2016.2 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + diff --git a/example/VCU108/fpga_1g/lib/eth b/example/VCU108/fpga_1g/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/VCU108/fpga_1g/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/VCU108/fpga_1g/rtl/debounce_switch.v b/example/VCU108/fpga_1g/rtl/debounce_switch.v new file mode 100644 index 000000000..3e2dc20a5 --- /dev/null +++ b/example/VCU108/fpga_1g/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/VCU108/fpga_1g/rtl/fpga.v b/example/VCU108/fpga_1g/rtl/fpga.v new file mode 100644 index 000000000..d81d2f8b1 --- /dev/null +++ b/example/VCU108/fpga_1g/rtl/fpga.v @@ -0,0 +1,345 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 125MHz LVDS + * Reset: Push button, active low + */ + input wire clk_125mhz_p, + input wire clk_125mhz_n, + input wire reset, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_sgmii_rx_p, + input wire phy_sgmii_rx_n, + output wire phy_sgmii_tx_p, + output wire phy_sgmii_tx_n, + input wire phy_sgmii_clk_p, + input wire phy_sgmii_clk_n, + output wire phy_reset_n, + input wire phy_int_n, + + /* + * UART: 500000 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// Clock and reset + +wire clk_125mhz_ibufg; +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +wire mmcm_rst = reset; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS #( + .DIFF_TERM("FALSE"), + .IBUF_LOW_PWR("FALSE") +) +clk_125mhz_ibufg_inst ( + .O (clk_125mhz_ibufg), + .I (clk_125mhz_p), + .IB (clk_125mhz_n) +); + +// MMCM instance +// 125 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 600 MHz to 1440 MHz +// M = 5, D = 1 sets Fvco = 625 MHz (in range) +// Divide by 5 to get output frequency of 125 MHz +MMCME3_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(5), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(5), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(8.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_125mhz_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [3:0] sw_int; + +debounce_switch #( + .WIDTH(9), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +wire uart_rxd_int; +wire uart_cts_int; + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(clk_125mhz_int), + .in({uart_rxd, uart_cts}), + .out({uart_rxd_int, uart_cts_int}) +); + +// SGMII interface to PHY +wire phy_gmii_clk_int; +wire phy_gmii_rst_int; +wire [7:0] phy_gmii_txd_int; +wire phy_gmii_tx_en_int; +wire phy_gmii_tx_er_int; +wire [7:0] phy_gmii_rxd_int; +wire phy_gmii_rx_dv_int; +wire phy_gmii_rx_er_int; + +wire [15:0] status_vector; + +wire [4:0] pcspma_config_vector = { + 1'b1, // autonegotiation enable + 1'b0, // isolate + 1'b0, // power down + 1'b0, // loopback enable + 1'b0 // unidirectional enable +}; + +wire [15:0] pcspma_an_config_vector = { + 1'b1, // SGMII link status + 1'b1, // SGMII Acknowledge + 2'b01, // full duplex + 2'b10, // SGMII speed + 1'b0, // reserved + 2'b00, // pause frames - SGMII reserved + 1'b0, // reserved + 1'b0, // full duplex - SGMII reserved + 4'b0000, // reserved + 1'b1 // SGMII +}; + +gig_ethernet_pcs_pma_0 +eth_pcspma ( + // SGMII + .txp (phy_sgmii_tx_p), + .txn (phy_sgmii_tx_n), + .rxp (phy_sgmii_rx_p), + .rxn (phy_sgmii_rx_n), + + // Ref clock from PHY + .refclk625_p (phy_sgmii_clk_p), + .refclk625_n (phy_sgmii_clk_n), + + // async reset + .reset (rst_125mhz_int), + + // clock and reset outputs + .clk125_out (phy_gmii_clk_int), + .clk625_out (), + .clk312_out (), + .rst_125_out (phy_gmii_rst_int), + .idelay_rdy_out (), + .mmcm_locked_out (), + + // MAC clocking + .sgmii_clk_r (), + .sgmii_clk_f (), + .sgmii_clk_en (), // need to pass through to MAC + + // Speed control + .speed_is_10_100 (1'b0), + .speed_is_100 (1'b0), + + // Internal GMII + .gmii_txd (phy_gmii_txd_int), + .gmii_tx_en (phy_gmii_tx_en_int), + .gmii_tx_er (phy_gmii_tx_er_int), + .gmii_rxd (phy_gmii_rxd_int), + .gmii_rx_dv (phy_gmii_rx_dv_int), + .gmii_rx_er (phy_gmii_rx_er_int), + .gmii_isolate (), + + // Configuration + .configuration_vector (pcspma_config_vector), + + .an_interrupt (), + .an_adv_config_vector (pcspma_an_config_vector), + .an_restart_config (1'b0), + + // Status + .status_vector (status_vector), + .signal_detect (1'b1) +); + +wire [7:0] led_int; + +// SGMII interface debug: +// SW12:4 (sw[0]) off for payload byte, on for status vector +// SW12:3 (sw[1]) off for LSB of status vector, on for MSB +assign led = sw[0] ? (sw[1] ? status_vector[15:8] : status_vector[7:0]) : led_int; + +fpga_core +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .led(led_int), + /* + * Ethernet: 1000BASE-T SGMII + */ + .phy_gmii_clk(phy_gmii_clk_int), + .phy_gmii_rst(phy_gmii_rst_int), + .phy_gmii_rxd(phy_gmii_rxd_int), + .phy_gmii_rx_dv(phy_gmii_rx_dv_int), + .phy_gmii_rx_er(phy_gmii_rx_er_int), + .phy_gmii_txd(phy_gmii_txd_int), + .phy_gmii_tx_en(phy_gmii_tx_en_int), + .phy_gmii_tx_er(phy_gmii_tx_er_int), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts_int) +); + +endmodule diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v new file mode 100644 index 000000000..88a3ea82e --- /dev/null +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -0,0 +1,558 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 125MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_gmii_clk, + input wire phy_gmii_rst, + input wire [7:0] phy_gmii_rxd, + input wire phy_gmii_rx_dv, + input wire phy_gmii_rx_er, + output wire [7:0] phy_gmii_txd, + output wire phy_gmii_tx_en, + output wire phy_gmii_tx_er, + output wire phy_reset_n, + input wire phy_int_n, + + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// AXI between MAC and Ethernet modules +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [7:0] tx_axis_tdata; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [7:0] rx_eth_payload_tdata; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [7:0] tx_eth_payload_tdata; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [7:0] rx_ip_payload_tdata; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [7:0] tx_ip_payload_tdata; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [7:0] rx_udp_payload_tdata; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_tdata; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [7:0] rx_fifo_udp_payload_tdata; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [7:0] tx_fifo_udp_payload_tdata; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_tvalid; + if (tx_udp_payload_tvalid & ~valid_last) begin + led_reg <= tx_udp_payload_tdata; + end + end +end + +//assign led = sw; +assign led = led_reg; +assign phy_reset_n = ~rst; + +assign uart_txd = 0; +assign uart_rts = 0; + +eth_mac_1g_fifo #( + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .RX_FIFO_ADDR_WIDTH(12) +) +eth_mac_1g_fifo_inst ( + .rx_clk(phy_gmii_clk), + .rx_rst(phy_gmii_rst), + .tx_clk(phy_gmii_clk), + .tx_rst(phy_gmii_rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .gmii_rxd(phy_gmii_rxd), + .gmii_rx_dv(phy_gmii_rx_dv), + .gmii_rx_er(phy_gmii_rx_er), + .gmii_txd(phy_gmii_txd), + .gmii_tx_en(phy_gmii_tx_en), + .gmii_tx_er(phy_gmii_tx_er), + + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + + .ifg_delay(12) +); + +eth_axis_rx +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete #( + .UDP_CHECKSUM_ENABLE(0) +) +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(0) +); + +axis_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/VCU108/fpga_1g/rtl/sync_reset.v b/example/VCU108/fpga_1g/rtl/sync_reset.v new file mode 100644 index 000000000..ddd99febe --- /dev/null +++ b/example/VCU108/fpga_1g/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/VCU108/fpga_1g/rtl/sync_signal.v b/example/VCU108/fpga_1g/rtl/sync_signal.v new file mode 100644 index 000000000..5afcd7170 --- /dev/null +++ b/example/VCU108/fpga_1g/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/VCU108/fpga_1g/tb/arp_ep.py b/example/VCU108/fpga_1g/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/VCU108/fpga_1g/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_1g/tb/axis_ep.py b/example/VCU108/fpga_1g/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/VCU108/fpga_1g/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_1g/tb/eth_ep.py b/example/VCU108/fpga_1g/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/VCU108/fpga_1g/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_1g/tb/gmii_ep.py b/example/VCU108/fpga_1g/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/VCU108/fpga_1g/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_1g/tb/ip_ep.py b/example/VCU108/fpga_1g/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/VCU108/fpga_1g/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py new file mode 100755 index 000000000..65ad083d1 --- /dev/null +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -0,0 +1,353 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import eth_ep +import arp_ep +import udp_ep +import gmii_ep + +module = 'fpga_core' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp.v") +srcs.append("../lib/eth/rtl/udp_ip_rx.v") +srcs.append("../lib/eth/rtl/udp_ip_tx.v") +srcs.append("../lib/eth/rtl/ip_complete.v") +srcs.append("../lib/eth/rtl/ip.v") +srcs.append("../lib/eth/rtl/ip_eth_rx.v") +srcs.append("../lib/eth/rtl/ip_eth_tx.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") +srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") +srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_fpga_core(clk, + rst, + + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + led, + + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + phy_int_n, + + uart_rxd, + uart_txd, + uart_rts, + uart_cts): + + 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, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, + + phy_gmii_clk=phy_gmii_clk, + phy_gmii_rst=phy_gmii_rst, + phy_gmii_rxd=phy_gmii_rxd, + phy_gmii_rx_dv=phy_gmii_rx_dv, + phy_gmii_rx_er=phy_gmii_rx_er, + phy_gmii_txd=phy_gmii_txd, + phy_gmii_tx_en=phy_gmii_tx_en, + phy_gmii_tx_er=phy_gmii_tx_er, + phy_reset_n=phy_reset_n, + phy_int_n=phy_int_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts) + +def bench(): + + # Parameters + TARGET = "SIM" + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[3:]) + phy_gmii_clk = Signal(bool(0)) + phy_gmii_rst = Signal(bool(0)) + phy_gmii_rxd = Signal(intbv(0)[8:]) + phy_gmii_rx_dv = Signal(bool(0)) + phy_gmii_rx_er = Signal(bool(0)) + phy_int_n = Signal(bool(1)) + uart_rxd = Signal(bool(0)) + uart_cts = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[8:]) + phy_gmii_txd = Signal(intbv(0)[8:]) + phy_gmii_tx_en = Signal(bool(0)) + phy_gmii_tx_er = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + + # sources and sinks + gmii_source_queue = Queue() + gmii_sink_queue = Queue() + + gmii_source = gmii_ep.GMIISource(phy_gmii_clk, + phy_gmii_rst, + txd=phy_gmii_rxd, + tx_en=phy_gmii_rx_dv, + tx_er=phy_gmii_rx_er, + fifo=gmii_source_queue, + name='gmii_source') + + gmii_sink = gmii_ep.GMIISink(phy_gmii_clk, + phy_gmii_rst, + rxd=phy_gmii_txd, + rx_dv=phy_gmii_tx_en, + rx_er=phy_gmii_tx_er, + fifo=gmii_sink_queue, + name='gmii_sink') + + # DUT + dut = dut_fpga_core(clk, + rst, + current_test, + + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + led, + + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + phy_int_n, + + uart_rxd, + uart_txd, + uart_rts, + uart_cts) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + phy_gmii_clk.next = not phy_gmii_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + phy_gmii_rst.next = 1 + yield clk.posedge + rst.next = 0 + phy_gmii_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while gmii_sink_queue.empty(): + yield clk.posedge + + rx_frame = gmii_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while gmii_sink_queue.empty(): + yield clk.posedge + + rx_frame = gmii_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source_queue.empty() + assert gmii_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, gmii_source, gmii_sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.v b/example/VCU108/fpga_1g/tb/test_fpga_core.v new file mode 100644 index 000000000..31ee68870 --- /dev/null +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.v @@ -0,0 +1,128 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters +parameter TARGET = "SIM"; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [3:0] sw = 0; +reg phy_gmii_clk = 0; +reg phy_gmii_rst = 0; +reg [7:0] phy_gmii_rxd = 0; +reg phy_gmii_rx_dv = 0; +reg phy_gmii_rx_er = 0; +reg phy_int_n = 1; +reg uart_rxd = 0; +reg uart_cts = 0; + +// Outputs +wire [7:0] led; +wire phy_tx_clk; +wire [7:0] phy_gmii_txd; +wire phy_gmii_tx_en; +wire phy_gmii_tx_er; +wire phy_reset_n; +wire uart_txd; +wire uart_rts; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_int_n, + uart_rxd, + uart_cts); + $to_myhdl(led, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + uart_txd, + uart_rts); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core #( + .TARGET(TARGET) +) +UUT ( + .clk(clk), + .rst(rst), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .phy_gmii_clk(phy_gmii_clk), + .phy_gmii_rst(phy_gmii_rst), + .phy_gmii_rxd(phy_gmii_rxd), + .phy_gmii_rx_dv(phy_gmii_rx_dv), + .phy_gmii_rx_er(phy_gmii_rx_er), + .phy_gmii_txd(phy_gmii_txd), + .phy_gmii_tx_en(phy_gmii_tx_en), + .phy_gmii_tx_er(phy_gmii_tx_er), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts) +); + +endmodule diff --git a/example/VCU108/fpga_1g/tb/udp_ep.py b/example/VCU108/fpga_1g/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/VCU108/fpga_1g/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file From 61d41789d72849fdfafd577e1cb27c96086170ce Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 13 Jul 2016 11:57:14 -0400 Subject: [PATCH 287/617] Remove unused parameter; update XDC file --- example/VCU108/fpga_1g/fpga.xdc | 1 + example/VCU108/fpga_1g/rtl/fpga_core.v | 5 +---- example/VCU108/fpga_1g/tb/test_fpga_core.py | 1 - example/VCU108/fpga_1g/tb/test_fpga_core.v | 5 +---- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/example/VCU108/fpga_1g/fpga.xdc b/example/VCU108/fpga_1g/fpga.xdc index 303ca62cd..f6df87b7e 100644 --- a/example/VCU108/fpga_1g/fpga.xdc +++ b/example/VCU108/fpga_1g/fpga.xdc @@ -72,6 +72,7 @@ set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports phy_int_n] #set_property -dict {LOC AV24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdio] #set_property -dict {LOC AV21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc] +# 625 MHz ref clock from SGMII PHY create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] set_clock_groups -asynchronous -group phy_sgmii_clk diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v index 88a3ea82e..3b2dfdd27 100644 --- a/example/VCU108/fpga_1g/rtl/fpga_core.v +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -29,10 +29,7 @@ THE SOFTWARE. /* * FPGA core logic */ -module fpga_core # -( - parameter TARGET = "XILINX" -) +module fpga_core ( /* * Clock: 125MHz diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py index 65ad083d1..18d45cfd6 100755 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -136,7 +136,6 @@ def dut_fpga_core(clk, def bench(): # Parameters - TARGET = "SIM" # Inputs clk = Signal(bool(0)) diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.v b/example/VCU108/fpga_1g/tb/test_fpga_core.v index 31ee68870..4f39a409f 100644 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.v @@ -32,7 +32,6 @@ THE SOFTWARE. module test_fpga_core; // Parameters -parameter TARGET = "SIM"; // Inputs reg clk = 0; @@ -96,9 +95,7 @@ initial begin $dumpvars(0, test_fpga_core); end -fpga_core #( - .TARGET(TARGET) -) +fpga_core UUT ( .clk(clk), .rst(rst), From 018b3b2691b80657030e332729be96660638eede Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 13 Jul 2016 12:21:37 -0400 Subject: [PATCH 288/617] Fix signal width --- example/VCU108/fpga_1g/tb/test_fpga_core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py index 18d45cfd6..10bcfe5c4 100755 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -147,7 +147,7 @@ def bench(): btnd = Signal(bool(0)) btnr = Signal(bool(0)) btnc = Signal(bool(0)) - sw = Signal(intbv(0)[3:]) + sw = Signal(intbv(0)[4:]) phy_gmii_clk = Signal(bool(0)) phy_gmii_rst = Signal(bool(0)) phy_gmii_rxd = Signal(intbv(0)[8:]) From e38ffe16b8225cfe6977f72c155fb75f4205366b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 13 Jul 2016 14:38:22 -0400 Subject: [PATCH 289/617] Adjust config vector assignment --- example/VCU108/fpga_1g/rtl/fpga.v | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/example/VCU108/fpga_1g/rtl/fpga.v b/example/VCU108/fpga_1g/rtl/fpga.v index d81d2f8b1..044ad3dde 100644 --- a/example/VCU108/fpga_1g/rtl/fpga.v +++ b/example/VCU108/fpga_1g/rtl/fpga.v @@ -221,26 +221,26 @@ wire phy_gmii_rx_er_int; wire [15:0] status_vector; -wire [4:0] pcspma_config_vector = { - 1'b1, // autonegotiation enable - 1'b0, // isolate - 1'b0, // power down - 1'b0, // loopback enable - 1'b0 // unidirectional enable -}; +wire [4:0] pcspma_config_vector; -wire [15:0] pcspma_an_config_vector = { - 1'b1, // SGMII link status - 1'b1, // SGMII Acknowledge - 2'b01, // full duplex - 2'b10, // SGMII speed - 1'b0, // reserved - 2'b00, // pause frames - SGMII reserved - 1'b0, // reserved - 1'b0, // full duplex - SGMII reserved - 4'b0000, // reserved - 1'b1 // SGMII -}; +assign pcspma_config_vector[4] = 1'b1; // autonegotiation enable +assign pcspma_config_vector[3] = 1'b0; // isolate +assign pcspma_config_vector[2] = 1'b0; // power down +assign pcspma_config_vector[1] = 1'b0; // loopback enable +assign pcspma_config_vector[0] = 1'b0; // unidirectional enable + +wire [15:0] pcspma_an_config_vector; + +assign pcspma_an_config_vector[15] = 1'b1; // SGMII link status +assign pcspma_an_config_vector[14] = 1'b1; // SGMII Acknowledge +assign pcspma_an_config_vector[13:12] = 2'b01; // full duplex +assign pcspma_an_config_vector[11:10] = 2'b10; // SGMII speed +assign pcspma_an_config_vector[9] = 1'b0; // reserved +assign pcspma_an_config_vector[8:7] = 2'b00; // pause frames - SGMII reserved +assign pcspma_an_config_vector[6] = 1'b0; // reserved +assign pcspma_an_config_vector[5] = 1'b0; // full duplex - SGMII reserved +assign pcspma_an_config_vector[4:1] = 4'b0000; // reserved +assign pcspma_an_config_vector[0] = 1'b1; // SGMII gig_ethernet_pcs_pma_0 eth_pcspma ( From 7d7cba08382c10f55bf132d5867cd69627bae288 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 19 Jul 2016 16:21:15 -0700 Subject: [PATCH 290/617] Add bus width checks --- tb/gmii_ep.py | 4 ++++ tb/xgmii_ep.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index 528be9ab2..eccbeb398 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -88,6 +88,8 @@ def GMIISource(clk, rst, fifo=None, name=None): + assert len(txd) == 8 + @instance def logic(): frame = None @@ -141,6 +143,8 @@ def GMIISink(clk, rst, fifo=None, name=None): + assert len(rxd) == 8 + @instance def logic(): frame = None diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 5f29af571..cca98fb6a 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -109,6 +109,8 @@ def XGMIISource(clk, rst, fifo=None, name=None): + assert len(txd) == 64 + @instance def logic(): frame = None @@ -210,6 +212,8 @@ def XGMIISink(clk, rst, fifo=None, name=None): + assert len(rxd) == 64 + @instance def logic(): frame = None From c34a9c2197434be9640d021903161a9e92f3c11d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 19 Jul 2016 19:59:47 -0700 Subject: [PATCH 291/617] Add 32 bit XGMII support --- tb/xgmii_ep.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index cca98fb6a..4a1c3ec67 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -109,7 +109,9 @@ def XGMIISource(clk, rst, fifo=None, name=None): - assert len(txd) == 64 + assert len(txd) in [32, 64] + + bw = int(len(txd)/8) @instance def logic(): @@ -125,23 +127,23 @@ def XGMIISource(clk, rst, if rst: frame = None - txd.next = 0x0707070707070707 - txc.next = 0xff + txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 + txc.next = 0xff if bw == 8 else 0xf dl = [] cl = [] ifg_cnt = 0 deficit_idle_cnt = 0 nt = False else: - if ifg_cnt > 7: - ifg_cnt -= 8 - txd.next = 0x0707070707070707 - txc.next = 0xff + if ifg_cnt > bw-1: + ifg_cnt -= bw + txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 + txc.next = 0xff if bw == 8 else 0xf elif len(dl) > 0 or nt: d = 0 c = 0 - for i in range(8): + for i in range(bw): if len(dl) > 0: d |= dl.pop(0) << (8*i) c |= cl.pop(0) << i @@ -150,7 +152,7 @@ def XGMIISource(clk, rst, if nt: d |= 0xfd << (8*i) nt = False - ifg_cnt = 12 - (8-i) + deficit_idle_cnt + ifg_cnt = 12 - (bw-i) + deficit_idle_cnt else: d |= 0x07 << (8*i) c |= 1 << i @@ -182,7 +184,7 @@ def XGMIISource(clk, rst, d = 0xfb07070707 c = 0x1f - for i in range(k,8): + for i in range(k,bw): if len(dl) > 0: d |= dl.pop(0) << (8*i) c |= cl.pop(0) << i @@ -200,8 +202,8 @@ def XGMIISource(clk, rst, else: ifg_cnt = 0 deficit_idle_cnt = 0 - txd.next = 0x0707070707070707 - txc.next = 0xff + txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 + txc.next = 0xff if bw == 8 else 0xf return logic @@ -212,7 +214,9 @@ def XGMIISink(clk, rst, fifo=None, name=None): - assert len(rxd) == 64 + assert len(rxd) in [32, 64] + + bw = int(len(rxd)/8) @instance def logic(): @@ -234,10 +238,10 @@ def XGMIISink(clk, rst, frame = XGMIIFrame() d = [0x55] c = [0] - for i in range(1,8): + for i in range(1,bw): d.append((int(rxd) >> (8*i)) & 0xff) c.append((int(rxc) >> i) & 1) - elif (rxc >> 4) & 1 and (rxd >> 32) & 0xff == 0xfb: + elif bw == 8 and (rxc >> 4) & 1 and (rxd >> 32) & 0xff == 0xfb: # start in lane 4 frame = XGMIIFrame() d = [0x55] @@ -246,7 +250,7 @@ def XGMIISink(clk, rst, d.append((int(rxd) >> (8*i)) & 0xff) c.append((int(rxc) >> i) & 1) else: - for i in range(8): + for i in range(bw): if (rxc >> i) & 1 and (rxd >> (8*i)) & 0xff == 0xfd: # terminate frame.parse(d, c) From 52fc34d82eb5884b03d15bff0c61fa2410d3e1ee Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 20 Jul 2016 12:36:59 -0700 Subject: [PATCH 292/617] Assume first tkeep bit is always set --- rtl/axis_frame_length_adjust.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/axis_frame_length_adjust.v b/rtl/axis_frame_length_adjust.v index fa36f3ca8..59c8d5f3f 100644 --- a/rtl/axis_frame_length_adjust.v +++ b/rtl/axis_frame_length_adjust.v @@ -272,8 +272,8 @@ always @* begin if (input_axis_tready & input_axis_tvalid) begin // transfer through - word_cnt = 0; - for (i = 0; i <= KEEP_WIDTH; i = i + 1) begin + word_cnt = 1; + for (i = 1; i <= KEEP_WIDTH; i = i + 1) begin //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; if (input_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; end From d023213fdac53e390e7d9f4e4953e569eaf983a4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 24 Jul 2016 13:06:59 -0700 Subject: [PATCH 293/617] Support generating asymmetric crosspoints --- rtl/axis_crosspoint.py | 57 ++++++++++++++++++++++----------------- rtl/axis_crosspoint_64.py | 57 ++++++++++++++++++++++----------------- 2 files changed, 64 insertions(+), 50 deletions(-) diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index f1dd1832e..260b23983 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -11,7 +11,7 @@ from jinja2 import Template def main(): parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-p', '--ports', type=int, default=[4], nargs='+', help="number of ports") parser.add_argument('-n', '--name', type=str, help="module name") parser.add_argument('-o', '--output', type=str, help="output file name") @@ -24,8 +24,15 @@ def main(): exit(1) def generate(ports=4, name=None, output=None): + if type(ports) is int: + m = n = ports + elif len(ports) == 1: + m = n = ports[0] + else: + m, n = ports + if name is None: - name = "axis_crosspoint_{0}x{0}".format(ports) + name = "axis_crosspoint_{0}x{1}".format(m, n) if output is None: output = name + ".v" @@ -34,9 +41,9 @@ def generate(ports=4, name=None, output=None): output_file = open(output, 'w') - print("Generating {0} port AXI Stream crosspoint {1}...".format(ports, name)) + print("Generating {0}x{1} port AXI Stream crosspoint {2}...".format(m, n, name)) - select_width = int(math.ceil(math.log(ports, 2))) + select_width = int(math.ceil(math.log(m, 2))) t = Template(u"""/* @@ -67,7 +74,7 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * AXI4-Stream {{n}}x{{n}} crosspoint + * AXI4-Stream {{m}}x{{n}} crosspoint */ module {{name}} # ( @@ -80,7 +87,7 @@ module {{name}} # /* * AXI Stream inputs */ -{%- for p in ports %} +{%- for p in range(m) %} input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, input wire input_{{p}}_axis_tvalid, input wire input_{{p}}_axis_tlast, @@ -89,7 +96,7 @@ module {{name}} # /* * AXI Stream outputs */ -{%- for p in ports %} +{%- for p in range(n) %} output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, output wire output_{{p}}_axis_tvalid, output wire output_{{p}}_axis_tlast, @@ -98,28 +105,28 @@ module {{name}} # /* * Control */ -{%- for p in ports %} +{%- for p in range(n) %} input wire [{{w-1}}:0] output_{{p}}_select{% if not loop.last %},{% endif %} {%- endfor %} ); -{% for p in ports %} +{% for p in range(m) %} reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; reg input_{{p}}_axis_tvalid_reg = 1'b0; reg input_{{p}}_axis_tlast_reg = 1'b0; reg input_{{p}}_axis_tuser_reg = 1'b0; {% endfor %} -{%- for p in ports %} +{%- for p in range(n) %} reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; reg output_{{p}}_axis_tvalid_reg = 1'b0; reg output_{{p}}_axis_tlast_reg = 1'b0; reg output_{{p}}_axis_tuser_reg = 1'b0; {% endfor %} -{%- for p in ports %} +{%- for p in range(n) %} reg [{{w-1}}:0] output_{{p}}_select_reg = {{w}}'d0; {%- endfor %} -{% for p in ports %} +{% for p in range(n) %} assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; @@ -128,41 +135,41 @@ assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; always @(posedge clk) begin if (rst) begin -{%- for p in ports %} +{%- for p in range(n) %} output_{{p}}_select_reg <= {{w}}'d0; {%- endfor %} -{% for p in ports %} +{% for p in range(m) %} input_{{p}}_axis_tvalid_reg <= 1'b0; {%- endfor %} -{% for p in ports %} +{% for p in range(n) %} output_{{p}}_axis_tvalid_reg <= 1'b0; {%- endfor %} end else begin -{%- for p in ports %} +{%- for p in range(m) %} input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; {%- endfor %} -{% for p in ports %} +{% for p in range(n) %} output_{{p}}_select_reg <= output_{{p}}_select; {%- endfor %} -{%- for p in ports %} +{%- for p in range(n) %} case (output_{{p}}_select_reg) -{%- for q in ports %} +{%- for q in range(m) %} {{w}}'d{{q}}: output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; {%- endfor %} endcase {%- endfor %} end -{%- for p in ports %} +{%- for p in range(m) %} input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; {%- endfor %} -{%- for p in ports %} +{%- for p in range(n) %} case (output_{{p}}_select_reg) -{%- for q in ports %} +{%- for q in range(m) %} {{w}}'d{{q}}: begin output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; @@ -178,10 +185,10 @@ endmodule """) output_file.write(t.render( - n=ports, + m=m, + n=n, w=select_width, - name=name, - ports=range(ports) + name=name )) print("Done") diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index 75ff0bba8..25d2acded 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -11,7 +11,7 @@ from jinja2 import Template def main(): parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-p', '--ports', type=int, default=[4], nargs='+', help="number of ports") parser.add_argument('-n', '--name', type=str, help="module name") parser.add_argument('-o', '--output', type=str, help="output file name") @@ -24,8 +24,15 @@ def main(): exit(1) def generate(ports=4, name=None, output=None): + if type(ports) is int: + m = n = ports + elif len(ports) == 1: + m = n = ports[0] + else: + m, n = ports + if name is None: - name = "axis_crosspoint_64_{0}x{0}".format(ports) + name = "axis_crosspoint_64_{0}x{1}".format(m, n) if output is None: output = name + ".v" @@ -34,9 +41,9 @@ def generate(ports=4, name=None, output=None): output_file = open(output, 'w') - print("Generating {0} port AXI Stream crosspoint {1}...".format(ports, name)) + print("Generating {0}x{1} port AXI Stream crosspoint {2}...".format(m, n, name)) - select_width = int(math.ceil(math.log(ports, 2))) + select_width = int(math.ceil(math.log(m, 2))) t = Template(u"""/* @@ -67,7 +74,7 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * AXI4-Stream {{n}}x{{n}} crosspoint (64 bit datapath) + * AXI4-Stream {{m}}x{{n}} crosspoint (64 bit datapath) */ module {{name}} # ( @@ -81,7 +88,7 @@ module {{name}} # /* * AXI Stream inputs */ -{%- for p in ports %} +{%- for p in range(m) %} input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, input wire input_{{p}}_axis_tvalid, @@ -91,7 +98,7 @@ module {{name}} # /* * AXI Stream outputs */ -{%- for p in ports %} +{%- for p in range(n) %} output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, output wire output_{{p}}_axis_tvalid, @@ -101,11 +108,11 @@ module {{name}} # /* * Control */ -{%- for p in ports %} +{%- for p in range(n) %} input wire [{{w-1}}:0] output_{{p}}_select{% if not loop.last %},{% endif %} {%- endfor %} ); -{% for p in ports %} +{% for p in range(m) %} reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; reg [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg input_{{p}}_axis_tvalid_reg = 1'b0; @@ -113,7 +120,7 @@ reg input_{{p}}_axis_tlast_reg = 1'b0; reg input_{{p}}_axis_tuser_reg = 1'b0; {% endfor %} -{%- for p in ports %} +{%- for p in range(n) %} reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_{{p}}_axis_tvalid_reg = 1'b0; @@ -121,10 +128,10 @@ reg output_{{p}}_axis_tlast_reg = 1'b0; reg output_{{p}}_axis_tuser_reg = 1'b0; {% endfor %} -{%- for p in ports %} +{%- for p in range(n) %} reg [{{w-1}}:0] output_{{p}}_select_reg = {{w}}'d0; {%- endfor %} -{% for p in ports %} +{% for p in range(n) %} assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; assign output_{{p}}_axis_tkeep = output_{{p}}_axis_tkeep_reg; assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; @@ -134,42 +141,42 @@ assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; always @(posedge clk) begin if (rst) begin -{%- for p in ports %} +{%- for p in range(n) %} output_{{p}}_select_reg <= {{w}}'d0; {%- endfor %} -{% for p in ports %} +{% for p in range(m) %} input_{{p}}_axis_tvalid_reg <= 1'b0; {%- endfor %} -{% for p in ports %} +{% for p in range(n) %} output_{{p}}_axis_tvalid_reg <= 1'b0; {%- endfor %} end else begin -{%- for p in ports %} +{%- for p in range(m) %} input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; {%- endfor %} -{% for p in ports %} +{% for p in range(n) %} output_{{p}}_select_reg <= output_{{p}}_select; {%- endfor %} -{%- for p in ports %} +{%- for p in range(n) %} case (output_{{p}}_select_reg) -{%- for q in ports %} +{%- for q in range(m) %} {{w}}'d{{q}}: output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; {%- endfor %} endcase {%- endfor %} end -{%- for p in ports %} +{%- for p in range(m) %} input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; input_{{p}}_axis_tkeep_reg <= input_{{p}}_axis_tkeep; input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; {%- endfor %} -{%- for p in ports %} +{%- for p in range(n) %} case (output_{{p}}_select_reg) -{%- for q in ports %} +{%- for q in range(m) %} {{w}}'d{{q}}: begin output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; output_{{p}}_axis_tkeep_reg <= input_{{q}}_axis_tkeep_reg; @@ -186,10 +193,10 @@ endmodule """) output_file.write(t.render( - n=ports, + m=m, + n=n, w=select_width, - name=name, - ports=range(ports) + name=name )) print("Done") From 5fe35a79d2917d89eeb2da568a879fc41bd0b7b1 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 25 Jul 2016 11:28:35 -0700 Subject: [PATCH 294/617] Add tdest support to axis_ep --- tb/axis_ep.py | 57 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 14983f29f..9c7a36ea9 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -27,17 +27,21 @@ from myhdl import * skip_asserts = False class AXIStreamFrame(object): - def __init__(self, data=b'', keep=None, user=None): + def __init__(self, data=b'', keep=None, dest=None, user=None): self.B = 0 self.N = 8 self.M = 1 self.WL = 8 self.data = b'' self.keep = None + self.dest = 0 self.user = None if type(data) is bytes or type(data) is bytearray: self.data = bytearray(data) + self.keep = keep + self.dest = dest + self.user = user elif type(data) is AXIStreamFrame: self.N = data.N self.WL = data.WL @@ -47,6 +51,11 @@ class AXIStreamFrame(object): self.data = list(data.data) if data.keep is not None: self.keep = list(data.keep) + if data.dest is not None: + if type(data.dest) is int: + self.dest = data.dest + else: + self.dest = list(data.dest) if data.user is not None: if type(data.user) is int or type(data.user) is bool: self.user = data.user @@ -54,6 +63,9 @@ class AXIStreamFrame(object): self.user = list(data.user) else: self.data = list(data) + self.keep = keep + self.dest = dest + self.user = user def build(self): if self.data is None: @@ -62,9 +74,15 @@ class AXIStreamFrame(object): f = list(self.data) tdata = [] tkeep = [] + tdest = [] tuser = [] i = 0 + dest = 0 + if type(self.dest) is int: + dest = self.dest + self.dest = None + assert_tuser = False if (type(self.user) is int or type(self.user) is bool) and self.user: assert_tuser = True @@ -83,6 +101,10 @@ class AXIStreamFrame(object): tkeep.append(keep) else: tkeep.append(self.keep[i]) + if self.dest is None: + tdest.append(dest) + else: + tdest.append(self.dest[i]) if self.user is None: tuser.append(0) else: @@ -94,6 +116,10 @@ class AXIStreamFrame(object): data = 0 tdata.append(f.pop(0)) tkeep.append(0) + if self.dest is None: + tdest.append(dest) + else: + tdest.append(self.dest[i]) if self.user is None: tuser.append(0) else: @@ -104,16 +130,20 @@ class AXIStreamFrame(object): tuser[-1] = 1 self.user = 1 - return tdata, tkeep, tuser + if self.dest == None: + self.dest = dest - def parse(self, tdata, tkeep, tuser): + return tdata, tkeep, tdest, tuser + + def parse(self, tdata, tkeep, tdest, tuser): if tdata is None or tkeep is None or tuser is None: return - if len(tdata) != len(tkeep) or len(tdata) != len(tuser): + if len(tdata) != len(tkeep) or len(tdata) != len(tdest) or len(tdata) != len(tuser): raise Exception("Invalid data") self.data = [] self.keep = [] + self.dest = [] self.user = [] if self.B == 0: @@ -124,11 +154,13 @@ class AXIStreamFrame(object): if tkeep[i] & (1 << j): self.data.append((tdata[i] >> (j*self.WL)) & mask) self.keep.append(tkeep[i]) + self.dest.append(tdest[i]) self.user.append(tuser[i]) else: for i in range(len(tdata)): self.data.append(tdata[i]) self.keep.append(tkeep[i]) + self.dest.append(tdest[i]) self.user.append(tuser[i]) if self.WL == 8: @@ -139,7 +171,7 @@ class AXIStreamFrame(object): return self.data == other.data def __repr__(self): - return 'AXIStreamFrame(data=%s, keep=%s, user=%s)' % (repr(self.data), repr(self.keep), repr(self.user)) + return 'AXIStreamFrame(data=%s, keep=%s, dest=%s, user=%s)' % (repr(self.data), repr(self.keep), repr(self.dest), repr(self.user)) def __iter__(self): return self.data.__iter__() @@ -150,6 +182,7 @@ def AXIStreamSource(clk, rst, tvalid=Signal(bool(False)), tready=Signal(bool(True)), tlast=Signal(bool(False)), + tdest=Signal(intbv(0)), tuser=Signal(bool(False)), fifo=None, pause=0, @@ -168,6 +201,7 @@ def AXIStreamSource(clk, rst, frame = AXIStreamFrame() data = [] keep = [] + dest = [] user = [] B = 0 N = len(tdata) @@ -191,6 +225,8 @@ def AXIStreamSource(clk, rst, else: tdata.next = 0 tkeep.next = 0 + tdest.next = 0 + tuser.next = False tvalid_int.next = False tlast.next = False else: @@ -203,6 +239,7 @@ def AXIStreamSource(clk, rst, else: tdata.next = data.pop(0) tkeep.next = keep.pop(0) + tdest.next = dest.pop(0) tuser.next = user.pop(0) tvalid_int.next = True tlast.next = len(data) == 0 @@ -217,7 +254,7 @@ def AXIStreamSource(clk, rst, frame.N = N frame.M = M frame.WL = WL - data, keep, user = frame.build() + data, keep, dest, user = frame.build() if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) if B > 0: @@ -227,6 +264,7 @@ def AXIStreamSource(clk, rst, else: tdata.next = data.pop(0) tkeep.next = keep.pop(0) + tdest.next = dest.pop(0) tuser.next = user.pop(0) tvalid_int.next = True tlast.next = len(data) == 0 @@ -240,6 +278,7 @@ def AXIStreamSink(clk, rst, tvalid=Signal(bool(True)), tready=Signal(bool(True)), tlast=Signal(bool(True)), + tdest=Signal(intbv(0)), tuser=Signal(bool(False)), fifo=None, pause=0, @@ -258,6 +297,7 @@ def AXIStreamSink(clk, rst, frame = AXIStreamFrame() data = [] keep = [] + dest = [] user = [] B = 0 N = len(tdata) @@ -280,6 +320,7 @@ def AXIStreamSink(clk, rst, frame = AXIStreamFrame() data = [] keep = [] + dest = [] user = [] first = True else: @@ -314,6 +355,7 @@ def AXIStreamSink(clk, rst, else: data.append(int(tdata)) keep.append(int(tkeep)) + dest.append(int(tdest)) user.append(int(tuser)) first = False if tlast: @@ -321,7 +363,7 @@ def AXIStreamSink(clk, rst, frame.N = N frame.M = M frame.WL = WL - frame.parse(data, keep, user) + frame.parse(data, keep, dest, user) if fifo is not None: fifo.put(frame) if name is not None: @@ -329,6 +371,7 @@ def AXIStreamSink(clk, rst, frame = AXIStreamFrame() data = [] keep = [] + dest = [] user = [] first = True From 06bfa1944c1f51ef7451284a4a79566fa8675658 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 25 Jul 2016 13:12:10 -0700 Subject: [PATCH 295/617] Add AXI stream switch module, generator script, and testbench --- rtl/axis_switch.py | 477 ++++++++++++ rtl/axis_switch_4x4.v | 1262 +++++++++++++++++++++++++++++++ rtl/axis_switch_64.py | 492 ++++++++++++ rtl/axis_switch_64_4x4.v | 1331 +++++++++++++++++++++++++++++++++ tb/test_axis_switch_4x4.py | 682 +++++++++++++++++ tb/test_axis_switch_4x4.v | 240 ++++++ tb/test_axis_switch_64_4x4.py | 723 ++++++++++++++++++ tb/test_axis_switch_64_4x4.v | 266 +++++++ 8 files changed, 5473 insertions(+) create mode 100755 rtl/axis_switch.py create mode 100644 rtl/axis_switch_4x4.v create mode 100755 rtl/axis_switch_64.py create mode 100644 rtl/axis_switch_64_4x4.v create mode 100755 tb/test_axis_switch_4x4.py create mode 100644 tb/test_axis_switch_4x4.v create mode 100755 tb/test_axis_switch_64_4x4.py create mode 100644 tb/test_axis_switch_64_4x4.v diff --git a/rtl/axis_switch.py b/rtl/axis_switch.py new file mode 100755 index 000000000..35be63175 --- /dev/null +++ b/rtl/axis_switch.py @@ -0,0 +1,477 @@ +#!/usr/bin/env python +""" +Generates an AXI Stream switch with the specified number of ports +""" + +from __future__ import print_function + +import argparse +import math +from jinja2 import Template + +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=[4], nargs='+', help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() + + try: + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) + +def generate(ports=4, name=None, output=None): + if type(ports) is int: + m = n = ports + elif len(ports) == 1: + m = n = ports[0] + else: + m, n = ports + + if name is None: + name = "axis_switch_{0}x{1}".format(m, n) + + if output is None: + output = name + ".v" + + print("Opening file '{0}'...".format(output)) + + output_file = open(output, 'w') + + print("Generating {0}x{1} port AXI Stream switch {2}...".format(m, n, name)) + + cm = int(math.ceil(math.log(m, 2))) + cn = int(math.ceil(math.log(n, 2))) + + t = Template(u"""/* + +Copyright (c) 2016 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 {{m}}x{{n}} switch + */ +module {{name}} # +( + parameter DATA_WIDTH = 8, + parameter DEST_WIDTH = {{cn}}, +{%- for p in range(n) %} + parameter OUT_{{p}}_BASE = {{p}}, + parameter OUT_{{p}}_TOP = {{p}}, + parameter OUT_{{p}}_CONNECT = {{m}}'b{% for p in range(m) %}1{% endfor %}, +{%- endfor %} + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "ROUND_ROBIN", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ +{%- for p in range(m) %} + input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire input_{{p}}_axis_tvalid, + output wire input_{{p}}_axis_tready, + input wire input_{{p}}_axis_tlast, + input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, + input wire input_{{p}}_axis_tuser, +{% endfor %} + /* + * AXI Stream outputs + */ +{%- for p in range(n) %} + output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, + output wire output_{{p}}_axis_tvalid, + input wire output_{{p}}_axis_tready, + output wire output_{{p}}_axis_tlast, + output wire [DEST_WIDTH-1:0] output_{{p}}_axis_tdest, + output wire output_{{p}}_axis_tuser{% if not loop.last %},{% endif %} +{% endfor -%} +); + +// check configuration +initial begin + if (2**DEST_WIDTH < {{n}}) begin + $error("Error: DEST_WIDTH too small for port count"); + $finish; + end + + if ({%- for p in range(n) %}(OUT_{{p}}_BASE & 2**DEST_WIDTH-1) != OUT_{{p}}_BASE || (OUT_{{p}}_TOP & 2**DEST_WIDTH-1) != OUT_{{p}}_TOP{% if not loop.last %} || + {% endif %}{% endfor -%}) begin + $error("Error: value out of range"); + $finish; + end + + if ({%- for p in range(n) %}OUT_{{p}}_BASE > OUT_{{p}}_TOP{% if not loop.last %} || + {% endif %}{% endfor -%}) begin + $error("Error: invalid range"); + $finish; + end + + if ({%- for p in range(n-1) %}{% set outer_loop = loop %}{%- for q in range(p+1,n) %}(OUT_{{p}}_BASE <= OUT_{{q}}_TOP && OUT_{{q}}_BASE <= OUT_{{p}}_TOP){% if not (loop.last and outer_loop.last) %} || + {% endif %}{% endfor -%}{% endfor -%}) begin + $error("Error: ranges overlap"); + $finish; + end +end +{%- for p in range(m) %} + +reg [{{n-1}}:0] input_{{p}}_request_reg = {{n}}'d0, input_{{p}}_request_next; +reg input_{{p}}_request_valid_reg = 1'b0, input_{{p}}_request_valid_next; +reg input_{{p}}_request_error_reg = 1'b0, input_{{p}}_request_error_next; +{%- endfor %} +{% for p in range(n) %} +reg [{{cm-1}}:0] select_{{p}}_reg = {{cm}}'d0, select_{{p}}_next; +{%- endfor %} +{% for p in range(n) %} +reg enable_{{p}}_reg = 1'b0, enable_{{p}}_next; +{%- endfor %} +{% for p in range(m) %} +reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; +{%- endfor %} + +// internal datapath +{%- for p in range(n) %} +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_int; +reg output_{{p}}_axis_tvalid_int; +reg output_{{p}}_axis_tready_int_reg = 1'b0; +reg output_{{p}}_axis_tlast_int; +reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_int; +reg output_{{p}}_axis_tuser_int; +wire output_{{p}}_axis_tready_int_early; +{% endfor %} +{%- for p in range(m) %} +assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; +{%- endfor %} + +// mux for start of packet detection + +{%- for p in range(n) %} +reg selected_input_{{p}}_axis_tvalid; + +always @* begin + case (grant_encoded_{{p}}) +{%- for q in range(m) %} + {{cm}}'d{{q}}: selected_input_{{p}}_axis_tvalid = input_{{q}}_axis_tvalid; +{%- endfor %} + default: selected_input_{{p}}_axis_tvalid = 1'b0; + endcase +end +{% endfor %} +// mux for incoming packet +{% for p in range(n) %} +reg [DATA_WIDTH-1:0] current_input_{{p}}_axis_tdata; +reg current_input_{{p}}_axis_tvalid; +reg current_input_{{p}}_axis_tready; +reg current_input_{{p}}_axis_tlast; +reg [DEST_WIDTH-1:0] current_input_{{p}}_axis_tdest; +reg current_input_{{p}}_axis_tuser; + +always @* begin + case (select_{{p}}_reg) +{%- for q in range(m) %} + {{cm}}'d{{q}}: begin + current_input_{{p}}_axis_tdata = input_{{q}}_axis_tdata; + current_input_{{p}}_axis_tvalid = input_{{q}}_axis_tvalid; + current_input_{{p}}_axis_tready = input_{{q}}_axis_tready; + current_input_{{p}}_axis_tlast = input_{{q}}_axis_tlast; + current_input_{{p}}_axis_tdest = input_{{q}}_axis_tdest; + current_input_{{p}}_axis_tuser = input_{{q}}_axis_tuser; + end +{%- endfor %} + default: begin + current_input_{{p}}_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_{{p}}_axis_tvalid = 1'b0; + current_input_{{p}}_axis_tready = 1'b0; + current_input_{{p}}_axis_tlast = 1'b0; + current_input_{{p}}_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_{{p}}_axis_tuser = 1'b0; + end + endcase +end +{% endfor %} +// arbiter instances +{% for p in range(n) %} +wire [{{m-1}}:0] request_{{p}}; +wire [{{m-1}}:0] acknowledge_{{p}}; +wire [{{m-1}}:0] grant_{{p}}; +wire grant_valid_{{p}}; +wire [{{cm-1}}:0] grant_encoded_{{p}}; +{% endfor %} + +{%- for p in range(n) %} +arbiter #( + .PORTS({{m}}), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_{{p}}_inst ( + .clk(clk), + .rst(rst), + .request(request_{{p}}), + .acknowledge(acknowledge_{{p}}), + .grant(grant_{{p}}), + .grant_valid(grant_valid_{{p}}), + .grant_encoded(grant_encoded_{{p}}) +); +{% endfor %} +// request generation +{%- for p in range(n) %} +{%- for q in range(m) %} +assign request_{{p}}[{{q}}] = input_{{q}}_request_reg[{{p}}] & ~acknowledge_{{p}}[{{q}}]; +{%- endfor %} +{% endfor %} +// acknowledge generation +{%- for p in range(n) %} +{%- for q in range(m) %} +assign acknowledge_{{p}}[{{q}}] = grant_{{p}}[{{q}}] & input_{{q}}_axis_tvalid & input_{{q}}_axis_tready & input_{{q}}_axis_tlast; +{%- endfor %} +{% endfor %} +always @* begin +{%- for p in range(n) %} + select_{{p}}_next = select_{{p}}_reg; +{%- endfor %} +{% for p in range(n) %} + enable_{{p}}_next = enable_{{p}}_reg; +{%- endfor %} +{% for p in range(m) %} + input_{{p}}_request_next = input_{{p}}_request_reg; + input_{{p}}_request_valid_next = input_{{p}}_request_valid_reg; + input_{{p}}_request_error_next = input_{{p}}_request_error_reg; +{% endfor %} +{%- for p in range(m) %} + input_{{p}}_axis_tready_next = 1'b0; +{%- endfor %} +{% for p in range(n) %} + output_{{p}}_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_{{p}}_axis_tvalid_int = 1'b0; + output_{{p}}_axis_tlast_int = 1'b0; + output_{{p}}_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_{{p}}_axis_tuser_int = 1'b0; +{% endfor %} + // input decoding +{% for p in range(m) %} + if (input_{{p}}_request_valid_reg | input_{{p}}_request_error_reg) begin + if (input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast) begin + input_{{p}}_request_next = {DEST_WIDTH{1'b0}}; + input_{{p}}_request_valid_next = 1'b0; + input_{{p}}_request_error_next = 1'b0; + end + end else if (input_{{p}}_axis_tvalid) begin +{%- for q in range(n) %} + input_{{p}}_request_next[{{q}}] = (input_{{p}}_axis_tdest >= OUT_{{q}}_BASE) & (input_{{p}}_axis_tdest <= OUT_{{q}}_TOP) & OUT_{{q}}_CONNECT[{{p}}]; +{%- endfor %} + + if (input_{{p}}_request_next) begin + input_{{p}}_request_valid_next = 1'b1; + end else begin + input_{{p}}_request_error_next = 1'b1; + end + end +{% endfor %} + // output control +{% for p in range(n) %} + if (enable_{{p}}_reg) begin + if (current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready) begin + enable_{{p}}_next = ~current_input_{{p}}_axis_tlast; + end + end else if (grant_valid_{{p}} & selected_input_{{p}}_axis_tvalid) begin + enable_{{p}}_next = 1'b1; + select_{{p}}_next = grant_encoded_{{p}}; + end +{% endfor %} + // generate ready signal on selected port +{% for p in range(n) %} + if (enable_{{p}}_next) begin + case (select_{{p}}_next) +{%- for q in range(m) %} + {{cm}}'d{{q}}: input_{{q}}_axis_tready_next = output_{{p}}_axis_tready_int_early; +{%- endfor %} + endcase + end +{% endfor %} + +{%- for p in range(m) %} + if (input_{{p}}_request_error_next) + input_{{p}}_axis_tready_next = 1'b1; +{%- endfor %} + + // pass through selected packet data +{% for p in range(n) %} + output_{{p}}_axis_tdata_int = current_input_{{p}}_axis_tdata; + output_{{p}}_axis_tvalid_int = current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready & enable_{{p}}_reg; + output_{{p}}_axis_tlast_int = current_input_{{p}}_axis_tlast; + output_{{p}}_axis_tdest_int = current_input_{{p}}_axis_tdest; + output_{{p}}_axis_tuser_int = current_input_{{p}}_axis_tuser; +{% endfor -%} +end + +always @(posedge clk) begin + if (rst) begin +{%- for p in range(m) %} + input_{{p}}_request_reg <= {{n}}'d0; + input_{{p}}_request_valid_reg <= 1'b0; + input_{{p}}_request_error_reg <= 1'b0; +{%- endfor %} +{%- for p in range(n) %} + select_{{p}}_reg <= 2'd0; +{%- endfor %} +{%- for p in range(n) %} + enable_{{p}}_reg <= 1'b0; +{%- endfor %} +{%- for p in range(m) %} + input_{{p}}_axis_tready_reg <= 1'b0; +{%- endfor %} + end else begin +{%- for p in range(m) %} + input_{{p}}_request_reg <= input_{{p}}_request_next; + input_{{p}}_request_valid_reg <= input_{{p}}_request_valid_next; + input_{{p}}_request_error_reg <= input_{{p}}_request_error_next; +{%- endfor %} +{%- for p in range(n) %} + select_{{p}}_reg <= select_{{p}}_next; +{%- endfor %} +{%- for p in range(n) %} + enable_{{p}}_reg <= enable_{{p}}_next; +{%- endfor %} +{%- for p in range(m) %} + input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; +{%- endfor %} + end +end +{% for p in range(n) %} +// output {{p}} datapath logic +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_{{p}}_axis_tvalid_reg = 1'b0, output_{{p}}_axis_tvalid_next; +reg output_{{p}}_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg output_{{p}}_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_{{p}}_axis_tvalid_reg = 1'b0, temp_{{p}}_axis_tvalid_next; +reg temp_{{p}}_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] temp_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg temp_{{p}}_axis_tuser_reg = 1'b0; + +// datapath control +reg store_{{p}}_axis_int_to_output; +reg store_{{p}}_axis_int_to_temp; +reg store_{{p}}_axis_temp_to_output; + +assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; +assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; +assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; +assign output_{{p}}_axis_tdest = output_{{p}}_axis_tdest_reg; +assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_{{p}}_axis_tready_int_early = output_{{p}}_axis_tready | (~temp_{{p}}_axis_tvalid_reg & (~output_{{p}}_axis_tvalid_reg | ~output_{{p}}_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_reg; + temp_{{p}}_axis_tvalid_next = temp_{{p}}_axis_tvalid_reg; + + store_{{p}}_axis_int_to_output = 1'b0; + store_{{p}}_axis_int_to_temp = 1'b0; + store_{{p}}_axis_temp_to_output = 1'b0; + + if (output_{{p}}_axis_tready_int_reg) begin + // input is ready + if (output_{{p}}_axis_tready | ~output_{{p}}_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_int; + store_{{p}}_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_int; + store_{{p}}_axis_int_to_temp = 1'b1; + end + end else if (output_{{p}}_axis_tready) begin + // input is not ready, but output is ready + output_{{p}}_axis_tvalid_next = temp_{{p}}_axis_tvalid_reg; + temp_{{p}}_axis_tvalid_next = 1'b0; + store_{{p}}_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_{{p}}_axis_tvalid_reg <= 1'b0; + output_{{p}}_axis_tready_int_reg <= 1'b0; + temp_{{p}}_axis_tvalid_reg <= 1'b0; + end else begin + output_{{p}}_axis_tvalid_reg <= output_{{p}}_axis_tvalid_next; + output_{{p}}_axis_tready_int_reg <= output_{{p}}_axis_tready_int_early; + temp_{{p}}_axis_tvalid_reg <= temp_{{p}}_axis_tvalid_next; + end + + // datapath + if (store_{{p}}_axis_int_to_output) begin + output_{{p}}_axis_tdata_reg <= output_{{p}}_axis_tdata_int; + output_{{p}}_axis_tlast_reg <= output_{{p}}_axis_tlast_int; + output_{{p}}_axis_tdest_reg <= output_{{p}}_axis_tdest_int; + output_{{p}}_axis_tuser_reg <= output_{{p}}_axis_tuser_int; + end else if (store_{{p}}_axis_temp_to_output) begin + output_{{p}}_axis_tdata_reg <= temp_{{p}}_axis_tdata_reg; + output_{{p}}_axis_tlast_reg <= temp_{{p}}_axis_tlast_reg; + output_{{p}}_axis_tdest_reg <= temp_{{p}}_axis_tdest_reg; + output_{{p}}_axis_tuser_reg <= temp_{{p}}_axis_tuser_reg; + end + + if (store_{{p}}_axis_int_to_temp) begin + temp_{{p}}_axis_tdata_reg <= output_{{p}}_axis_tdata_int; + temp_{{p}}_axis_tlast_reg <= output_{{p}}_axis_tlast_int; + temp_{{p}}_axis_tdest_reg <= output_{{p}}_axis_tdest_int; + temp_{{p}}_axis_tuser_reg <= output_{{p}}_axis_tuser_int; + end +end +{% endfor %} +endmodule + +""") + + output_file.write(t.render( + m=m, + n=n, + cm=cm, + cn=cn, + name=name + )) + + print("Done") + +if __name__ == "__main__": + main() + diff --git a/rtl/axis_switch_4x4.v b/rtl/axis_switch_4x4.v new file mode 100644 index 000000000..0aaf34973 --- /dev/null +++ b/rtl/axis_switch_4x4.v @@ -0,0 +1,1262 @@ +/* + +Copyright (c) 2016 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 4x4 switch + */ +module axis_switch_4x4 # +( + parameter DATA_WIDTH = 8, + parameter DEST_WIDTH = 2, + parameter OUT_0_BASE = 0, + parameter OUT_0_TOP = 0, + parameter OUT_0_CONNECT = 4'b1111, + parameter OUT_1_BASE = 1, + parameter OUT_1_TOP = 1, + parameter OUT_1_CONNECT = 4'b1111, + parameter OUT_2_BASE = 2, + parameter OUT_2_TOP = 2, + parameter OUT_2_CONNECT = 4'b1111, + parameter OUT_3_BASE = 3, + parameter OUT_3_TOP = 3, + parameter OUT_3_CONNECT = 4'b1111, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "ROUND_ROBIN", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ + input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire input_0_axis_tvalid, + output wire input_0_axis_tready, + input wire input_0_axis_tlast, + input wire [DEST_WIDTH-1:0] input_0_axis_tdest, + input wire input_0_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire input_1_axis_tvalid, + output wire input_1_axis_tready, + input wire input_1_axis_tlast, + input wire [DEST_WIDTH-1:0] input_1_axis_tdest, + input wire input_1_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire input_2_axis_tvalid, + output wire input_2_axis_tready, + input wire input_2_axis_tlast, + input wire [DEST_WIDTH-1:0] input_2_axis_tdest, + input wire input_2_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire input_3_axis_tvalid, + output wire input_3_axis_tready, + input wire input_3_axis_tlast, + input wire [DEST_WIDTH-1:0] input_3_axis_tdest, + input wire input_3_axis_tuser, + + /* + * AXI Stream outputs + */ + output wire [DATA_WIDTH-1:0] output_0_axis_tdata, + output wire output_0_axis_tvalid, + input wire output_0_axis_tready, + output wire output_0_axis_tlast, + output wire [DEST_WIDTH-1:0] output_0_axis_tdest, + output wire output_0_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_1_axis_tdata, + output wire output_1_axis_tvalid, + input wire output_1_axis_tready, + output wire output_1_axis_tlast, + output wire [DEST_WIDTH-1:0] output_1_axis_tdest, + output wire output_1_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_2_axis_tdata, + output wire output_2_axis_tvalid, + input wire output_2_axis_tready, + output wire output_2_axis_tlast, + output wire [DEST_WIDTH-1:0] output_2_axis_tdest, + output wire output_2_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_3_axis_tdata, + output wire output_3_axis_tvalid, + input wire output_3_axis_tready, + output wire output_3_axis_tlast, + output wire [DEST_WIDTH-1:0] output_3_axis_tdest, + output wire output_3_axis_tuser +); + +// check configuration +initial begin + if (2**DEST_WIDTH < 4) begin + $error("Error: DEST_WIDTH too small for port count"); + $finish; + end + + if ((OUT_0_BASE & 2**DEST_WIDTH-1) != OUT_0_BASE || (OUT_0_TOP & 2**DEST_WIDTH-1) != OUT_0_TOP || + (OUT_1_BASE & 2**DEST_WIDTH-1) != OUT_1_BASE || (OUT_1_TOP & 2**DEST_WIDTH-1) != OUT_1_TOP || + (OUT_2_BASE & 2**DEST_WIDTH-1) != OUT_2_BASE || (OUT_2_TOP & 2**DEST_WIDTH-1) != OUT_2_TOP || + (OUT_3_BASE & 2**DEST_WIDTH-1) != OUT_3_BASE || (OUT_3_TOP & 2**DEST_WIDTH-1) != OUT_3_TOP) begin + $error("Error: value out of range"); + $finish; + end + + if (OUT_0_BASE > OUT_0_TOP || + OUT_1_BASE > OUT_1_TOP || + OUT_2_BASE > OUT_2_TOP || + OUT_3_BASE > OUT_3_TOP) begin + $error("Error: invalid range"); + $finish; + end + + if ((OUT_0_BASE <= OUT_1_TOP && OUT_1_BASE <= OUT_0_TOP) || + (OUT_0_BASE <= OUT_2_TOP && OUT_2_BASE <= OUT_0_TOP) || + (OUT_0_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_0_TOP) || + (OUT_1_BASE <= OUT_2_TOP && OUT_2_BASE <= OUT_1_TOP) || + (OUT_1_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_1_TOP) || + (OUT_2_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_2_TOP)) begin + $error("Error: ranges overlap"); + $finish; + end +end + +reg [3:0] input_0_request_reg = 4'd0, input_0_request_next; +reg input_0_request_valid_reg = 1'b0, input_0_request_valid_next; +reg input_0_request_error_reg = 1'b0, input_0_request_error_next; + +reg [3:0] input_1_request_reg = 4'd0, input_1_request_next; +reg input_1_request_valid_reg = 1'b0, input_1_request_valid_next; +reg input_1_request_error_reg = 1'b0, input_1_request_error_next; + +reg [3:0] input_2_request_reg = 4'd0, input_2_request_next; +reg input_2_request_valid_reg = 1'b0, input_2_request_valid_next; +reg input_2_request_error_reg = 1'b0, input_2_request_error_next; + +reg [3:0] input_3_request_reg = 4'd0, input_3_request_next; +reg input_3_request_valid_reg = 1'b0, input_3_request_valid_next; +reg input_3_request_error_reg = 1'b0, input_3_request_error_next; + +reg [1:0] select_0_reg = 2'd0, select_0_next; +reg [1:0] select_1_reg = 2'd0, select_1_next; +reg [1:0] select_2_reg = 2'd0, select_2_next; +reg [1:0] select_3_reg = 2'd0, select_3_next; + +reg enable_0_reg = 1'b0, enable_0_next; +reg enable_1_reg = 1'b0, enable_1_next; +reg enable_2_reg = 1'b0, enable_2_next; +reg enable_3_reg = 1'b0, enable_3_next; + +reg input_0_axis_tready_reg = 1'b0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 1'b0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; + +// internal datapath +reg [DATA_WIDTH-1:0] output_0_axis_tdata_int; +reg output_0_axis_tvalid_int; +reg output_0_axis_tready_int_reg = 1'b0; +reg output_0_axis_tlast_int; +reg [DEST_WIDTH-1:0] output_0_axis_tdest_int; +reg output_0_axis_tuser_int; +wire output_0_axis_tready_int_early; + +reg [DATA_WIDTH-1:0] output_1_axis_tdata_int; +reg output_1_axis_tvalid_int; +reg output_1_axis_tready_int_reg = 1'b0; +reg output_1_axis_tlast_int; +reg [DEST_WIDTH-1:0] output_1_axis_tdest_int; +reg output_1_axis_tuser_int; +wire output_1_axis_tready_int_early; + +reg [DATA_WIDTH-1:0] output_2_axis_tdata_int; +reg output_2_axis_tvalid_int; +reg output_2_axis_tready_int_reg = 1'b0; +reg output_2_axis_tlast_int; +reg [DEST_WIDTH-1:0] output_2_axis_tdest_int; +reg output_2_axis_tuser_int; +wire output_2_axis_tready_int_early; + +reg [DATA_WIDTH-1:0] output_3_axis_tdata_int; +reg output_3_axis_tvalid_int; +reg output_3_axis_tready_int_reg = 1'b0; +reg output_3_axis_tlast_int; +reg [DEST_WIDTH-1:0] output_3_axis_tdest_int; +reg output_3_axis_tuser_int; +wire output_3_axis_tready_int_early; + +assign input_0_axis_tready = input_0_axis_tready_reg; +assign input_1_axis_tready = input_1_axis_tready_reg; +assign input_2_axis_tready = input_2_axis_tready_reg; +assign input_3_axis_tready = input_3_axis_tready_reg; + +// mux for start of packet detection +reg selected_input_0_axis_tvalid; + +always @* begin + case (grant_encoded_0) + 2'd0: selected_input_0_axis_tvalid = input_0_axis_tvalid; + 2'd1: selected_input_0_axis_tvalid = input_1_axis_tvalid; + 2'd2: selected_input_0_axis_tvalid = input_2_axis_tvalid; + 2'd3: selected_input_0_axis_tvalid = input_3_axis_tvalid; + default: selected_input_0_axis_tvalid = 1'b0; + endcase +end + +reg selected_input_1_axis_tvalid; + +always @* begin + case (grant_encoded_1) + 2'd0: selected_input_1_axis_tvalid = input_0_axis_tvalid; + 2'd1: selected_input_1_axis_tvalid = input_1_axis_tvalid; + 2'd2: selected_input_1_axis_tvalid = input_2_axis_tvalid; + 2'd3: selected_input_1_axis_tvalid = input_3_axis_tvalid; + default: selected_input_1_axis_tvalid = 1'b0; + endcase +end + +reg selected_input_2_axis_tvalid; + +always @* begin + case (grant_encoded_2) + 2'd0: selected_input_2_axis_tvalid = input_0_axis_tvalid; + 2'd1: selected_input_2_axis_tvalid = input_1_axis_tvalid; + 2'd2: selected_input_2_axis_tvalid = input_2_axis_tvalid; + 2'd3: selected_input_2_axis_tvalid = input_3_axis_tvalid; + default: selected_input_2_axis_tvalid = 1'b0; + endcase +end + +reg selected_input_3_axis_tvalid; + +always @* begin + case (grant_encoded_3) + 2'd0: selected_input_3_axis_tvalid = input_0_axis_tvalid; + 2'd1: selected_input_3_axis_tvalid = input_1_axis_tvalid; + 2'd2: selected_input_3_axis_tvalid = input_2_axis_tvalid; + 2'd3: selected_input_3_axis_tvalid = input_3_axis_tvalid; + default: selected_input_3_axis_tvalid = 1'b0; + endcase +end + +// mux for incoming packet + +reg [DATA_WIDTH-1:0] current_input_0_axis_tdata; +reg current_input_0_axis_tvalid; +reg current_input_0_axis_tready; +reg current_input_0_axis_tlast; +reg [DEST_WIDTH-1:0] current_input_0_axis_tdest; +reg current_input_0_axis_tuser; + +always @* begin + case (select_0_reg) + 2'd0: begin + current_input_0_axis_tdata = input_0_axis_tdata; + current_input_0_axis_tvalid = input_0_axis_tvalid; + current_input_0_axis_tready = input_0_axis_tready; + current_input_0_axis_tlast = input_0_axis_tlast; + current_input_0_axis_tdest = input_0_axis_tdest; + current_input_0_axis_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_0_axis_tdata = input_1_axis_tdata; + current_input_0_axis_tvalid = input_1_axis_tvalid; + current_input_0_axis_tready = input_1_axis_tready; + current_input_0_axis_tlast = input_1_axis_tlast; + current_input_0_axis_tdest = input_1_axis_tdest; + current_input_0_axis_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_0_axis_tdata = input_2_axis_tdata; + current_input_0_axis_tvalid = input_2_axis_tvalid; + current_input_0_axis_tready = input_2_axis_tready; + current_input_0_axis_tlast = input_2_axis_tlast; + current_input_0_axis_tdest = input_2_axis_tdest; + current_input_0_axis_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_0_axis_tdata = input_3_axis_tdata; + current_input_0_axis_tvalid = input_3_axis_tvalid; + current_input_0_axis_tready = input_3_axis_tready; + current_input_0_axis_tlast = input_3_axis_tlast; + current_input_0_axis_tdest = input_3_axis_tdest; + current_input_0_axis_tuser = input_3_axis_tuser; + end + default: begin + current_input_0_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_0_axis_tvalid = 1'b0; + current_input_0_axis_tready = 1'b0; + current_input_0_axis_tlast = 1'b0; + current_input_0_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_0_axis_tuser = 1'b0; + end + endcase +end + +reg [DATA_WIDTH-1:0] current_input_1_axis_tdata; +reg current_input_1_axis_tvalid; +reg current_input_1_axis_tready; +reg current_input_1_axis_tlast; +reg [DEST_WIDTH-1:0] current_input_1_axis_tdest; +reg current_input_1_axis_tuser; + +always @* begin + case (select_1_reg) + 2'd0: begin + current_input_1_axis_tdata = input_0_axis_tdata; + current_input_1_axis_tvalid = input_0_axis_tvalid; + current_input_1_axis_tready = input_0_axis_tready; + current_input_1_axis_tlast = input_0_axis_tlast; + current_input_1_axis_tdest = input_0_axis_tdest; + current_input_1_axis_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_1_axis_tdata = input_1_axis_tdata; + current_input_1_axis_tvalid = input_1_axis_tvalid; + current_input_1_axis_tready = input_1_axis_tready; + current_input_1_axis_tlast = input_1_axis_tlast; + current_input_1_axis_tdest = input_1_axis_tdest; + current_input_1_axis_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_1_axis_tdata = input_2_axis_tdata; + current_input_1_axis_tvalid = input_2_axis_tvalid; + current_input_1_axis_tready = input_2_axis_tready; + current_input_1_axis_tlast = input_2_axis_tlast; + current_input_1_axis_tdest = input_2_axis_tdest; + current_input_1_axis_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_1_axis_tdata = input_3_axis_tdata; + current_input_1_axis_tvalid = input_3_axis_tvalid; + current_input_1_axis_tready = input_3_axis_tready; + current_input_1_axis_tlast = input_3_axis_tlast; + current_input_1_axis_tdest = input_3_axis_tdest; + current_input_1_axis_tuser = input_3_axis_tuser; + end + default: begin + current_input_1_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_1_axis_tvalid = 1'b0; + current_input_1_axis_tready = 1'b0; + current_input_1_axis_tlast = 1'b0; + current_input_1_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_1_axis_tuser = 1'b0; + end + endcase +end + +reg [DATA_WIDTH-1:0] current_input_2_axis_tdata; +reg current_input_2_axis_tvalid; +reg current_input_2_axis_tready; +reg current_input_2_axis_tlast; +reg [DEST_WIDTH-1:0] current_input_2_axis_tdest; +reg current_input_2_axis_tuser; + +always @* begin + case (select_2_reg) + 2'd0: begin + current_input_2_axis_tdata = input_0_axis_tdata; + current_input_2_axis_tvalid = input_0_axis_tvalid; + current_input_2_axis_tready = input_0_axis_tready; + current_input_2_axis_tlast = input_0_axis_tlast; + current_input_2_axis_tdest = input_0_axis_tdest; + current_input_2_axis_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_2_axis_tdata = input_1_axis_tdata; + current_input_2_axis_tvalid = input_1_axis_tvalid; + current_input_2_axis_tready = input_1_axis_tready; + current_input_2_axis_tlast = input_1_axis_tlast; + current_input_2_axis_tdest = input_1_axis_tdest; + current_input_2_axis_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_2_axis_tdata = input_2_axis_tdata; + current_input_2_axis_tvalid = input_2_axis_tvalid; + current_input_2_axis_tready = input_2_axis_tready; + current_input_2_axis_tlast = input_2_axis_tlast; + current_input_2_axis_tdest = input_2_axis_tdest; + current_input_2_axis_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_2_axis_tdata = input_3_axis_tdata; + current_input_2_axis_tvalid = input_3_axis_tvalid; + current_input_2_axis_tready = input_3_axis_tready; + current_input_2_axis_tlast = input_3_axis_tlast; + current_input_2_axis_tdest = input_3_axis_tdest; + current_input_2_axis_tuser = input_3_axis_tuser; + end + default: begin + current_input_2_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_2_axis_tvalid = 1'b0; + current_input_2_axis_tready = 1'b0; + current_input_2_axis_tlast = 1'b0; + current_input_2_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_2_axis_tuser = 1'b0; + end + endcase +end + +reg [DATA_WIDTH-1:0] current_input_3_axis_tdata; +reg current_input_3_axis_tvalid; +reg current_input_3_axis_tready; +reg current_input_3_axis_tlast; +reg [DEST_WIDTH-1:0] current_input_3_axis_tdest; +reg current_input_3_axis_tuser; + +always @* begin + case (select_3_reg) + 2'd0: begin + current_input_3_axis_tdata = input_0_axis_tdata; + current_input_3_axis_tvalid = input_0_axis_tvalid; + current_input_3_axis_tready = input_0_axis_tready; + current_input_3_axis_tlast = input_0_axis_tlast; + current_input_3_axis_tdest = input_0_axis_tdest; + current_input_3_axis_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_3_axis_tdata = input_1_axis_tdata; + current_input_3_axis_tvalid = input_1_axis_tvalid; + current_input_3_axis_tready = input_1_axis_tready; + current_input_3_axis_tlast = input_1_axis_tlast; + current_input_3_axis_tdest = input_1_axis_tdest; + current_input_3_axis_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_3_axis_tdata = input_2_axis_tdata; + current_input_3_axis_tvalid = input_2_axis_tvalid; + current_input_3_axis_tready = input_2_axis_tready; + current_input_3_axis_tlast = input_2_axis_tlast; + current_input_3_axis_tdest = input_2_axis_tdest; + current_input_3_axis_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_3_axis_tdata = input_3_axis_tdata; + current_input_3_axis_tvalid = input_3_axis_tvalid; + current_input_3_axis_tready = input_3_axis_tready; + current_input_3_axis_tlast = input_3_axis_tlast; + current_input_3_axis_tdest = input_3_axis_tdest; + current_input_3_axis_tuser = input_3_axis_tuser; + end + default: begin + current_input_3_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_3_axis_tvalid = 1'b0; + current_input_3_axis_tready = 1'b0; + current_input_3_axis_tlast = 1'b0; + current_input_3_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_3_axis_tuser = 1'b0; + end + endcase +end + +// arbiter instances + +wire [3:0] request_0; +wire [3:0] acknowledge_0; +wire [3:0] grant_0; +wire grant_valid_0; +wire [1:0] grant_encoded_0; + +wire [3:0] request_1; +wire [3:0] acknowledge_1; +wire [3:0] grant_1; +wire grant_valid_1; +wire [1:0] grant_encoded_1; + +wire [3:0] request_2; +wire [3:0] acknowledge_2; +wire [3:0] grant_2; +wire grant_valid_2; +wire [1:0] grant_encoded_2; + +wire [3:0] request_3; +wire [3:0] acknowledge_3; +wire [3:0] grant_3; +wire grant_valid_3; +wire [1:0] grant_encoded_3; + +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_0_inst ( + .clk(clk), + .rst(rst), + .request(request_0), + .acknowledge(acknowledge_0), + .grant(grant_0), + .grant_valid(grant_valid_0), + .grant_encoded(grant_encoded_0) +); + +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_1_inst ( + .clk(clk), + .rst(rst), + .request(request_1), + .acknowledge(acknowledge_1), + .grant(grant_1), + .grant_valid(grant_valid_1), + .grant_encoded(grant_encoded_1) +); + +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_2_inst ( + .clk(clk), + .rst(rst), + .request(request_2), + .acknowledge(acknowledge_2), + .grant(grant_2), + .grant_valid(grant_valid_2), + .grant_encoded(grant_encoded_2) +); + +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_3_inst ( + .clk(clk), + .rst(rst), + .request(request_3), + .acknowledge(acknowledge_3), + .grant(grant_3), + .grant_valid(grant_valid_3), + .grant_encoded(grant_encoded_3) +); + +// request generation +assign request_0[0] = input_0_request_reg[0] & ~acknowledge_0[0]; +assign request_0[1] = input_1_request_reg[0] & ~acknowledge_0[1]; +assign request_0[2] = input_2_request_reg[0] & ~acknowledge_0[2]; +assign request_0[3] = input_3_request_reg[0] & ~acknowledge_0[3]; + +assign request_1[0] = input_0_request_reg[1] & ~acknowledge_1[0]; +assign request_1[1] = input_1_request_reg[1] & ~acknowledge_1[1]; +assign request_1[2] = input_2_request_reg[1] & ~acknowledge_1[2]; +assign request_1[3] = input_3_request_reg[1] & ~acknowledge_1[3]; + +assign request_2[0] = input_0_request_reg[2] & ~acknowledge_2[0]; +assign request_2[1] = input_1_request_reg[2] & ~acknowledge_2[1]; +assign request_2[2] = input_2_request_reg[2] & ~acknowledge_2[2]; +assign request_2[3] = input_3_request_reg[2] & ~acknowledge_2[3]; + +assign request_3[0] = input_0_request_reg[3] & ~acknowledge_3[0]; +assign request_3[1] = input_1_request_reg[3] & ~acknowledge_3[1]; +assign request_3[2] = input_2_request_reg[3] & ~acknowledge_3[2]; +assign request_3[3] = input_3_request_reg[3] & ~acknowledge_3[3]; + +// acknowledge generation +assign acknowledge_0[0] = grant_0[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign acknowledge_0[1] = grant_0[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign acknowledge_0[2] = grant_0[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign acknowledge_0[3] = grant_0[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; + +assign acknowledge_1[0] = grant_1[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign acknowledge_1[1] = grant_1[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign acknowledge_1[2] = grant_1[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign acknowledge_1[3] = grant_1[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; + +assign acknowledge_2[0] = grant_2[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign acknowledge_2[1] = grant_2[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign acknowledge_2[2] = grant_2[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign acknowledge_2[3] = grant_2[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; + +assign acknowledge_3[0] = grant_3[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign acknowledge_3[1] = grant_3[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign acknowledge_3[2] = grant_3[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign acknowledge_3[3] = grant_3[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; + +always @* begin + select_0_next = select_0_reg; + select_1_next = select_1_reg; + select_2_next = select_2_reg; + select_3_next = select_3_reg; + + enable_0_next = enable_0_reg; + enable_1_next = enable_1_reg; + enable_2_next = enable_2_reg; + enable_3_next = enable_3_reg; + + input_0_request_next = input_0_request_reg; + input_0_request_valid_next = input_0_request_valid_reg; + input_0_request_error_next = input_0_request_error_reg; + + input_1_request_next = input_1_request_reg; + input_1_request_valid_next = input_1_request_valid_reg; + input_1_request_error_next = input_1_request_error_reg; + + input_2_request_next = input_2_request_reg; + input_2_request_valid_next = input_2_request_valid_reg; + input_2_request_error_next = input_2_request_error_reg; + + input_3_request_next = input_3_request_reg; + input_3_request_valid_next = input_3_request_valid_reg; + input_3_request_error_next = input_3_request_error_reg; + + input_0_axis_tready_next = 1'b0; + input_1_axis_tready_next = 1'b0; + input_2_axis_tready_next = 1'b0; + input_3_axis_tready_next = 1'b0; + + output_0_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_0_axis_tvalid_int = 1'b0; + output_0_axis_tlast_int = 1'b0; + output_0_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_0_axis_tuser_int = 1'b0; + + output_1_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_1_axis_tvalid_int = 1'b0; + output_1_axis_tlast_int = 1'b0; + output_1_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_1_axis_tuser_int = 1'b0; + + output_2_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_2_axis_tvalid_int = 1'b0; + output_2_axis_tlast_int = 1'b0; + output_2_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_2_axis_tuser_int = 1'b0; + + output_3_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_3_axis_tvalid_int = 1'b0; + output_3_axis_tlast_int = 1'b0; + output_3_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_3_axis_tuser_int = 1'b0; + + // input decoding + + if (input_0_request_valid_reg | input_0_request_error_reg) begin + if (input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast) begin + input_0_request_next = {DEST_WIDTH{1'b0}}; + input_0_request_valid_next = 1'b0; + input_0_request_error_next = 1'b0; + end + end else if (input_0_axis_tvalid) begin + input_0_request_next[0] = (input_0_axis_tdest >= OUT_0_BASE) & (input_0_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[0]; + input_0_request_next[1] = (input_0_axis_tdest >= OUT_1_BASE) & (input_0_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[0]; + input_0_request_next[2] = (input_0_axis_tdest >= OUT_2_BASE) & (input_0_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[0]; + input_0_request_next[3] = (input_0_axis_tdest >= OUT_3_BASE) & (input_0_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[0]; + + if (input_0_request_next) begin + input_0_request_valid_next = 1'b1; + end else begin + input_0_request_error_next = 1'b1; + end + end + + if (input_1_request_valid_reg | input_1_request_error_reg) begin + if (input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast) begin + input_1_request_next = {DEST_WIDTH{1'b0}}; + input_1_request_valid_next = 1'b0; + input_1_request_error_next = 1'b0; + end + end else if (input_1_axis_tvalid) begin + input_1_request_next[0] = (input_1_axis_tdest >= OUT_0_BASE) & (input_1_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[1]; + input_1_request_next[1] = (input_1_axis_tdest >= OUT_1_BASE) & (input_1_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[1]; + input_1_request_next[2] = (input_1_axis_tdest >= OUT_2_BASE) & (input_1_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[1]; + input_1_request_next[3] = (input_1_axis_tdest >= OUT_3_BASE) & (input_1_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[1]; + + if (input_1_request_next) begin + input_1_request_valid_next = 1'b1; + end else begin + input_1_request_error_next = 1'b1; + end + end + + if (input_2_request_valid_reg | input_2_request_error_reg) begin + if (input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast) begin + input_2_request_next = {DEST_WIDTH{1'b0}}; + input_2_request_valid_next = 1'b0; + input_2_request_error_next = 1'b0; + end + end else if (input_2_axis_tvalid) begin + input_2_request_next[0] = (input_2_axis_tdest >= OUT_0_BASE) & (input_2_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[2]; + input_2_request_next[1] = (input_2_axis_tdest >= OUT_1_BASE) & (input_2_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[2]; + input_2_request_next[2] = (input_2_axis_tdest >= OUT_2_BASE) & (input_2_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[2]; + input_2_request_next[3] = (input_2_axis_tdest >= OUT_3_BASE) & (input_2_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[2]; + + if (input_2_request_next) begin + input_2_request_valid_next = 1'b1; + end else begin + input_2_request_error_next = 1'b1; + end + end + + if (input_3_request_valid_reg | input_3_request_error_reg) begin + if (input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast) begin + input_3_request_next = {DEST_WIDTH{1'b0}}; + input_3_request_valid_next = 1'b0; + input_3_request_error_next = 1'b0; + end + end else if (input_3_axis_tvalid) begin + input_3_request_next[0] = (input_3_axis_tdest >= OUT_0_BASE) & (input_3_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[3]; + input_3_request_next[1] = (input_3_axis_tdest >= OUT_1_BASE) & (input_3_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[3]; + input_3_request_next[2] = (input_3_axis_tdest >= OUT_2_BASE) & (input_3_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[3]; + input_3_request_next[3] = (input_3_axis_tdest >= OUT_3_BASE) & (input_3_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[3]; + + if (input_3_request_next) begin + input_3_request_valid_next = 1'b1; + end else begin + input_3_request_error_next = 1'b1; + end + end + + // output control + + if (enable_0_reg) begin + if (current_input_0_axis_tvalid & current_input_0_axis_tready) begin + enable_0_next = ~current_input_0_axis_tlast; + end + end else if (grant_valid_0 & selected_input_0_axis_tvalid) begin + enable_0_next = 1'b1; + select_0_next = grant_encoded_0; + end + + if (enable_1_reg) begin + if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin + enable_1_next = ~current_input_1_axis_tlast; + end + end else if (grant_valid_1 & selected_input_1_axis_tvalid) begin + enable_1_next = 1'b1; + select_1_next = grant_encoded_1; + end + + if (enable_2_reg) begin + if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin + enable_2_next = ~current_input_2_axis_tlast; + end + end else if (grant_valid_2 & selected_input_2_axis_tvalid) begin + enable_2_next = 1'b1; + select_2_next = grant_encoded_2; + end + + if (enable_3_reg) begin + if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin + enable_3_next = ~current_input_3_axis_tlast; + end + end else if (grant_valid_3 & selected_input_3_axis_tvalid) begin + enable_3_next = 1'b1; + select_3_next = grant_encoded_3; + end + + // generate ready signal on selected port + + if (enable_0_next) begin + case (select_0_next) + 2'd0: input_0_axis_tready_next = output_0_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_0_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_0_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_0_axis_tready_int_early; + endcase + end + + if (enable_1_next) begin + case (select_1_next) + 2'd0: input_0_axis_tready_next = output_1_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_1_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_1_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_1_axis_tready_int_early; + endcase + end + + if (enable_2_next) begin + case (select_2_next) + 2'd0: input_0_axis_tready_next = output_2_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_2_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_2_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_2_axis_tready_int_early; + endcase + end + + if (enable_3_next) begin + case (select_3_next) + 2'd0: input_0_axis_tready_next = output_3_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_3_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_3_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_3_axis_tready_int_early; + endcase + end + + if (input_0_request_error_next) + input_0_axis_tready_next = 1'b1; + if (input_1_request_error_next) + input_1_axis_tready_next = 1'b1; + if (input_2_request_error_next) + input_2_axis_tready_next = 1'b1; + if (input_3_request_error_next) + input_3_axis_tready_next = 1'b1; + + // pass through selected packet data + + output_0_axis_tdata_int = current_input_0_axis_tdata; + output_0_axis_tvalid_int = current_input_0_axis_tvalid & current_input_0_axis_tready & enable_0_reg; + output_0_axis_tlast_int = current_input_0_axis_tlast; + output_0_axis_tdest_int = current_input_0_axis_tdest; + output_0_axis_tuser_int = current_input_0_axis_tuser; + + output_1_axis_tdata_int = current_input_1_axis_tdata; + output_1_axis_tvalid_int = current_input_1_axis_tvalid & current_input_1_axis_tready & enable_1_reg; + output_1_axis_tlast_int = current_input_1_axis_tlast; + output_1_axis_tdest_int = current_input_1_axis_tdest; + output_1_axis_tuser_int = current_input_1_axis_tuser; + + output_2_axis_tdata_int = current_input_2_axis_tdata; + output_2_axis_tvalid_int = current_input_2_axis_tvalid & current_input_2_axis_tready & enable_2_reg; + output_2_axis_tlast_int = current_input_2_axis_tlast; + output_2_axis_tdest_int = current_input_2_axis_tdest; + output_2_axis_tuser_int = current_input_2_axis_tuser; + + output_3_axis_tdata_int = current_input_3_axis_tdata; + output_3_axis_tvalid_int = current_input_3_axis_tvalid & current_input_3_axis_tready & enable_3_reg; + output_3_axis_tlast_int = current_input_3_axis_tlast; + output_3_axis_tdest_int = current_input_3_axis_tdest; + output_3_axis_tuser_int = current_input_3_axis_tuser; +end + +always @(posedge clk) begin + if (rst) begin + input_0_request_reg <= 4'd0; + input_0_request_valid_reg <= 1'b0; + input_0_request_error_reg <= 1'b0; + input_1_request_reg <= 4'd0; + input_1_request_valid_reg <= 1'b0; + input_1_request_error_reg <= 1'b0; + input_2_request_reg <= 4'd0; + input_2_request_valid_reg <= 1'b0; + input_2_request_error_reg <= 1'b0; + input_3_request_reg <= 4'd0; + input_3_request_valid_reg <= 1'b0; + input_3_request_error_reg <= 1'b0; + select_0_reg <= 2'd0; + select_1_reg <= 2'd0; + select_2_reg <= 2'd0; + select_3_reg <= 2'd0; + enable_0_reg <= 1'b0; + enable_1_reg <= 1'b0; + enable_2_reg <= 1'b0; + enable_3_reg <= 1'b0; + input_0_axis_tready_reg <= 1'b0; + input_1_axis_tready_reg <= 1'b0; + input_2_axis_tready_reg <= 1'b0; + input_3_axis_tready_reg <= 1'b0; + end else begin + input_0_request_reg <= input_0_request_next; + input_0_request_valid_reg <= input_0_request_valid_next; + input_0_request_error_reg <= input_0_request_error_next; + input_1_request_reg <= input_1_request_next; + input_1_request_valid_reg <= input_1_request_valid_next; + input_1_request_error_reg <= input_1_request_error_next; + input_2_request_reg <= input_2_request_next; + input_2_request_valid_reg <= input_2_request_valid_next; + input_2_request_error_reg <= input_2_request_error_next; + input_3_request_reg <= input_3_request_next; + input_3_request_valid_reg <= input_3_request_valid_next; + input_3_request_error_reg <= input_3_request_error_next; + select_0_reg <= select_0_next; + select_1_reg <= select_1_next; + select_2_reg <= select_2_next; + select_3_reg <= select_3_next; + enable_0_reg <= enable_0_next; + enable_1_reg <= enable_1_next; + enable_2_reg <= enable_2_next; + enable_3_reg <= enable_3_next; + input_0_axis_tready_reg <= input_0_axis_tready_next; + input_1_axis_tready_reg <= input_1_axis_tready_next; + input_2_axis_tready_reg <= input_2_axis_tready_next; + input_3_axis_tready_reg <= input_3_axis_tready_next; + end +end + +// output 0 datapath logic +reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_0_axis_tvalid_reg = 1'b0, output_0_axis_tvalid_next; +reg output_0_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] output_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg output_0_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_0_axis_tvalid_reg = 1'b0, temp_0_axis_tvalid_next; +reg temp_0_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] temp_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg temp_0_axis_tuser_reg = 1'b0; + +// datapath control +reg store_0_axis_int_to_output; +reg store_0_axis_int_to_temp; +reg store_0_axis_temp_to_output; + +assign output_0_axis_tdata = output_0_axis_tdata_reg; +assign output_0_axis_tvalid = output_0_axis_tvalid_reg; +assign output_0_axis_tlast = output_0_axis_tlast_reg; +assign output_0_axis_tdest = output_0_axis_tdest_reg; +assign output_0_axis_tuser = output_0_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_0_axis_tready_int_early = output_0_axis_tready | (~temp_0_axis_tvalid_reg & (~output_0_axis_tvalid_reg | ~output_0_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_0_axis_tvalid_next = output_0_axis_tvalid_reg; + temp_0_axis_tvalid_next = temp_0_axis_tvalid_reg; + + store_0_axis_int_to_output = 1'b0; + store_0_axis_int_to_temp = 1'b0; + store_0_axis_temp_to_output = 1'b0; + + if (output_0_axis_tready_int_reg) begin + // input is ready + if (output_0_axis_tready | ~output_0_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_0_axis_tvalid_next = output_0_axis_tvalid_int; + store_0_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_0_axis_tvalid_next = output_0_axis_tvalid_int; + store_0_axis_int_to_temp = 1'b1; + end + end else if (output_0_axis_tready) begin + // input is not ready, but output is ready + output_0_axis_tvalid_next = temp_0_axis_tvalid_reg; + temp_0_axis_tvalid_next = 1'b0; + store_0_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_0_axis_tvalid_reg <= 1'b0; + output_0_axis_tready_int_reg <= 1'b0; + temp_0_axis_tvalid_reg <= 1'b0; + end else begin + output_0_axis_tvalid_reg <= output_0_axis_tvalid_next; + output_0_axis_tready_int_reg <= output_0_axis_tready_int_early; + temp_0_axis_tvalid_reg <= temp_0_axis_tvalid_next; + end + + // datapath + if (store_0_axis_int_to_output) begin + output_0_axis_tdata_reg <= output_0_axis_tdata_int; + output_0_axis_tlast_reg <= output_0_axis_tlast_int; + output_0_axis_tdest_reg <= output_0_axis_tdest_int; + output_0_axis_tuser_reg <= output_0_axis_tuser_int; + end else if (store_0_axis_temp_to_output) begin + output_0_axis_tdata_reg <= temp_0_axis_tdata_reg; + output_0_axis_tlast_reg <= temp_0_axis_tlast_reg; + output_0_axis_tdest_reg <= temp_0_axis_tdest_reg; + output_0_axis_tuser_reg <= temp_0_axis_tuser_reg; + end + + if (store_0_axis_int_to_temp) begin + temp_0_axis_tdata_reg <= output_0_axis_tdata_int; + temp_0_axis_tlast_reg <= output_0_axis_tlast_int; + temp_0_axis_tdest_reg <= output_0_axis_tdest_int; + temp_0_axis_tuser_reg <= output_0_axis_tuser_int; + end +end + +// output 1 datapath logic +reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_1_axis_tvalid_reg = 1'b0, output_1_axis_tvalid_next; +reg output_1_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] output_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg output_1_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_1_axis_tvalid_reg = 1'b0, temp_1_axis_tvalid_next; +reg temp_1_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] temp_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg temp_1_axis_tuser_reg = 1'b0; + +// datapath control +reg store_1_axis_int_to_output; +reg store_1_axis_int_to_temp; +reg store_1_axis_temp_to_output; + +assign output_1_axis_tdata = output_1_axis_tdata_reg; +assign output_1_axis_tvalid = output_1_axis_tvalid_reg; +assign output_1_axis_tlast = output_1_axis_tlast_reg; +assign output_1_axis_tdest = output_1_axis_tdest_reg; +assign output_1_axis_tuser = output_1_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_1_axis_tready_int_early = output_1_axis_tready | (~temp_1_axis_tvalid_reg & (~output_1_axis_tvalid_reg | ~output_1_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_1_axis_tvalid_next = output_1_axis_tvalid_reg; + temp_1_axis_tvalid_next = temp_1_axis_tvalid_reg; + + store_1_axis_int_to_output = 1'b0; + store_1_axis_int_to_temp = 1'b0; + store_1_axis_temp_to_output = 1'b0; + + if (output_1_axis_tready_int_reg) begin + // input is ready + if (output_1_axis_tready | ~output_1_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_1_axis_tvalid_next = output_1_axis_tvalid_int; + store_1_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_1_axis_tvalid_next = output_1_axis_tvalid_int; + store_1_axis_int_to_temp = 1'b1; + end + end else if (output_1_axis_tready) begin + // input is not ready, but output is ready + output_1_axis_tvalid_next = temp_1_axis_tvalid_reg; + temp_1_axis_tvalid_next = 1'b0; + store_1_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_1_axis_tvalid_reg <= 1'b0; + output_1_axis_tready_int_reg <= 1'b0; + temp_1_axis_tvalid_reg <= 1'b0; + end else begin + output_1_axis_tvalid_reg <= output_1_axis_tvalid_next; + output_1_axis_tready_int_reg <= output_1_axis_tready_int_early; + temp_1_axis_tvalid_reg <= temp_1_axis_tvalid_next; + end + + // datapath + if (store_1_axis_int_to_output) begin + output_1_axis_tdata_reg <= output_1_axis_tdata_int; + output_1_axis_tlast_reg <= output_1_axis_tlast_int; + output_1_axis_tdest_reg <= output_1_axis_tdest_int; + output_1_axis_tuser_reg <= output_1_axis_tuser_int; + end else if (store_1_axis_temp_to_output) begin + output_1_axis_tdata_reg <= temp_1_axis_tdata_reg; + output_1_axis_tlast_reg <= temp_1_axis_tlast_reg; + output_1_axis_tdest_reg <= temp_1_axis_tdest_reg; + output_1_axis_tuser_reg <= temp_1_axis_tuser_reg; + end + + if (store_1_axis_int_to_temp) begin + temp_1_axis_tdata_reg <= output_1_axis_tdata_int; + temp_1_axis_tlast_reg <= output_1_axis_tlast_int; + temp_1_axis_tdest_reg <= output_1_axis_tdest_int; + temp_1_axis_tuser_reg <= output_1_axis_tuser_int; + end +end + +// output 2 datapath logic +reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_2_axis_tvalid_reg = 1'b0, output_2_axis_tvalid_next; +reg output_2_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] output_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg output_2_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_2_axis_tvalid_reg = 1'b0, temp_2_axis_tvalid_next; +reg temp_2_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] temp_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg temp_2_axis_tuser_reg = 1'b0; + +// datapath control +reg store_2_axis_int_to_output; +reg store_2_axis_int_to_temp; +reg store_2_axis_temp_to_output; + +assign output_2_axis_tdata = output_2_axis_tdata_reg; +assign output_2_axis_tvalid = output_2_axis_tvalid_reg; +assign output_2_axis_tlast = output_2_axis_tlast_reg; +assign output_2_axis_tdest = output_2_axis_tdest_reg; +assign output_2_axis_tuser = output_2_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_2_axis_tready_int_early = output_2_axis_tready | (~temp_2_axis_tvalid_reg & (~output_2_axis_tvalid_reg | ~output_2_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_2_axis_tvalid_next = output_2_axis_tvalid_reg; + temp_2_axis_tvalid_next = temp_2_axis_tvalid_reg; + + store_2_axis_int_to_output = 1'b0; + store_2_axis_int_to_temp = 1'b0; + store_2_axis_temp_to_output = 1'b0; + + if (output_2_axis_tready_int_reg) begin + // input is ready + if (output_2_axis_tready | ~output_2_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_2_axis_tvalid_next = output_2_axis_tvalid_int; + store_2_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_2_axis_tvalid_next = output_2_axis_tvalid_int; + store_2_axis_int_to_temp = 1'b1; + end + end else if (output_2_axis_tready) begin + // input is not ready, but output is ready + output_2_axis_tvalid_next = temp_2_axis_tvalid_reg; + temp_2_axis_tvalid_next = 1'b0; + store_2_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_2_axis_tvalid_reg <= 1'b0; + output_2_axis_tready_int_reg <= 1'b0; + temp_2_axis_tvalid_reg <= 1'b0; + end else begin + output_2_axis_tvalid_reg <= output_2_axis_tvalid_next; + output_2_axis_tready_int_reg <= output_2_axis_tready_int_early; + temp_2_axis_tvalid_reg <= temp_2_axis_tvalid_next; + end + + // datapath + if (store_2_axis_int_to_output) begin + output_2_axis_tdata_reg <= output_2_axis_tdata_int; + output_2_axis_tlast_reg <= output_2_axis_tlast_int; + output_2_axis_tdest_reg <= output_2_axis_tdest_int; + output_2_axis_tuser_reg <= output_2_axis_tuser_int; + end else if (store_2_axis_temp_to_output) begin + output_2_axis_tdata_reg <= temp_2_axis_tdata_reg; + output_2_axis_tlast_reg <= temp_2_axis_tlast_reg; + output_2_axis_tdest_reg <= temp_2_axis_tdest_reg; + output_2_axis_tuser_reg <= temp_2_axis_tuser_reg; + end + + if (store_2_axis_int_to_temp) begin + temp_2_axis_tdata_reg <= output_2_axis_tdata_int; + temp_2_axis_tlast_reg <= output_2_axis_tlast_int; + temp_2_axis_tdest_reg <= output_2_axis_tdest_int; + temp_2_axis_tuser_reg <= output_2_axis_tuser_int; + end +end + +// output 3 datapath logic +reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg output_3_axis_tvalid_reg = 1'b0, output_3_axis_tvalid_next; +reg output_3_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] output_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg output_3_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_3_axis_tvalid_reg = 1'b0, temp_3_axis_tvalid_next; +reg temp_3_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] temp_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg temp_3_axis_tuser_reg = 1'b0; + +// datapath control +reg store_3_axis_int_to_output; +reg store_3_axis_int_to_temp; +reg store_3_axis_temp_to_output; + +assign output_3_axis_tdata = output_3_axis_tdata_reg; +assign output_3_axis_tvalid = output_3_axis_tvalid_reg; +assign output_3_axis_tlast = output_3_axis_tlast_reg; +assign output_3_axis_tdest = output_3_axis_tdest_reg; +assign output_3_axis_tuser = output_3_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_3_axis_tready_int_early = output_3_axis_tready | (~temp_3_axis_tvalid_reg & (~output_3_axis_tvalid_reg | ~output_3_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_3_axis_tvalid_next = output_3_axis_tvalid_reg; + temp_3_axis_tvalid_next = temp_3_axis_tvalid_reg; + + store_3_axis_int_to_output = 1'b0; + store_3_axis_int_to_temp = 1'b0; + store_3_axis_temp_to_output = 1'b0; + + if (output_3_axis_tready_int_reg) begin + // input is ready + if (output_3_axis_tready | ~output_3_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_3_axis_tvalid_next = output_3_axis_tvalid_int; + store_3_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_3_axis_tvalid_next = output_3_axis_tvalid_int; + store_3_axis_int_to_temp = 1'b1; + end + end else if (output_3_axis_tready) begin + // input is not ready, but output is ready + output_3_axis_tvalid_next = temp_3_axis_tvalid_reg; + temp_3_axis_tvalid_next = 1'b0; + store_3_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_3_axis_tvalid_reg <= 1'b0; + output_3_axis_tready_int_reg <= 1'b0; + temp_3_axis_tvalid_reg <= 1'b0; + end else begin + output_3_axis_tvalid_reg <= output_3_axis_tvalid_next; + output_3_axis_tready_int_reg <= output_3_axis_tready_int_early; + temp_3_axis_tvalid_reg <= temp_3_axis_tvalid_next; + end + + // datapath + if (store_3_axis_int_to_output) begin + output_3_axis_tdata_reg <= output_3_axis_tdata_int; + output_3_axis_tlast_reg <= output_3_axis_tlast_int; + output_3_axis_tdest_reg <= output_3_axis_tdest_int; + output_3_axis_tuser_reg <= output_3_axis_tuser_int; + end else if (store_3_axis_temp_to_output) begin + output_3_axis_tdata_reg <= temp_3_axis_tdata_reg; + output_3_axis_tlast_reg <= temp_3_axis_tlast_reg; + output_3_axis_tdest_reg <= temp_3_axis_tdest_reg; + output_3_axis_tuser_reg <= temp_3_axis_tuser_reg; + end + + if (store_3_axis_int_to_temp) begin + temp_3_axis_tdata_reg <= output_3_axis_tdata_int; + temp_3_axis_tlast_reg <= output_3_axis_tlast_int; + temp_3_axis_tdest_reg <= output_3_axis_tdest_int; + temp_3_axis_tuser_reg <= output_3_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/axis_switch_64.py b/rtl/axis_switch_64.py new file mode 100755 index 000000000..3eebdbdf4 --- /dev/null +++ b/rtl/axis_switch_64.py @@ -0,0 +1,492 @@ +#!/usr/bin/env python +""" +Generates an AXI Stream switch with the specified number of ports +""" + +from __future__ import print_function + +import argparse +import math +from jinja2 import Template + +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=[4], nargs='+', help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() + + try: + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) + +def generate(ports=4, name=None, output=None): + if type(ports) is int: + m = n = ports + elif len(ports) == 1: + m = n = ports[0] + else: + m, n = ports + + if name is None: + name = "axis_switch_64_{0}x{1}".format(m, n) + + if output is None: + output = name + ".v" + + print("Opening file '{0}'...".format(output)) + + output_file = open(output, 'w') + + print("Generating {0}x{1} port AXI Stream switch {2}...".format(m, n, name)) + + cm = int(math.ceil(math.log(m, 2))) + cn = int(math.ceil(math.log(n, 2))) + + t = Template(u"""/* + +Copyright (c) 2016 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 {{m}}x{{n}} switch (64 bit datapath) + */ +module {{name}} # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter DEST_WIDTH = {{cn}}, +{%- for p in range(n) %} + parameter OUT_{{p}}_BASE = {{p}}, + parameter OUT_{{p}}_TOP = {{p}}, + parameter OUT_{{p}}_CONNECT = {{m}}'b{% for p in range(m) %}1{% endfor %}, +{%- endfor %} + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "ROUND_ROBIN", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ +{%- for p in range(m) %} + input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, + input wire input_{{p}}_axis_tvalid, + output wire input_{{p}}_axis_tready, + input wire input_{{p}}_axis_tlast, + input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, + input wire input_{{p}}_axis_tuser, +{% endfor %} + /* + * AXI Stream outputs + */ +{%- for p in range(n) %} + output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, + output wire output_{{p}}_axis_tvalid, + input wire output_{{p}}_axis_tready, + output wire output_{{p}}_axis_tlast, + output wire [DEST_WIDTH-1:0] output_{{p}}_axis_tdest, + output wire output_{{p}}_axis_tuser{% if not loop.last %},{% endif %} +{% endfor -%} +); + +// check configuration +initial begin + if (2**DEST_WIDTH < {{n}}) begin + $error("Error: DEST_WIDTH too small for port count"); + $finish; + end + + if ({%- for p in range(n) %}(OUT_{{p}}_BASE & 2**DEST_WIDTH-1) != OUT_{{p}}_BASE || (OUT_{{p}}_TOP & 2**DEST_WIDTH-1) != OUT_{{p}}_TOP{% if not loop.last %} || + {% endif %}{% endfor -%}) begin + $error("Error: value out of range"); + $finish; + end + + if ({%- for p in range(n) %}OUT_{{p}}_BASE > OUT_{{p}}_TOP{% if not loop.last %} || + {% endif %}{% endfor -%}) begin + $error("Error: invalid range"); + $finish; + end + + if ({%- for p in range(n-1) %}{% set outer_loop = loop %}{%- for q in range(p+1,n) %}(OUT_{{p}}_BASE <= OUT_{{q}}_TOP && OUT_{{q}}_BASE <= OUT_{{p}}_TOP){% if not (loop.last and outer_loop.last) %} || + {% endif %}{% endfor -%}{% endfor -%}) begin + $error("Error: ranges overlap"); + $finish; + end +end +{%- for p in range(m) %} + +reg [{{n-1}}:0] input_{{p}}_request_reg = {{n}}'d0, input_{{p}}_request_next; +reg input_{{p}}_request_valid_reg = 1'b0, input_{{p}}_request_valid_next; +reg input_{{p}}_request_error_reg = 1'b0, input_{{p}}_request_error_next; +{%- endfor %} +{% for p in range(n) %} +reg [{{cm-1}}:0] select_{{p}}_reg = {{cm}}'d0, select_{{p}}_next; +{%- endfor %} +{% for p in range(n) %} +reg enable_{{p}}_reg = 1'b0, enable_{{p}}_next; +{%- endfor %} +{% for p in range(m) %} +reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; +{%- endfor %} + +// internal datapath +{%- for p in range(n) %} +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_int; +reg output_{{p}}_axis_tvalid_int; +reg output_{{p}}_axis_tready_int_reg = 1'b0; +reg output_{{p}}_axis_tlast_int; +reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_int; +reg output_{{p}}_axis_tuser_int; +wire output_{{p}}_axis_tready_int_early; +{% endfor %} +{%- for p in range(m) %} +assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; +{%- endfor %} + +// mux for start of packet detection + +{%- for p in range(n) %} +reg selected_input_{{p}}_axis_tvalid; + +always @* begin + case (grant_encoded_{{p}}) +{%- for q in range(m) %} + {{cm}}'d{{q}}: selected_input_{{p}}_axis_tvalid = input_{{q}}_axis_tvalid; +{%- endfor %} + default: selected_input_{{p}}_axis_tvalid = 1'b0; + endcase +end +{% endfor %} +// mux for incoming packet +{% for p in range(n) %} +reg [DATA_WIDTH-1:0] current_input_{{p}}_axis_tdata; +reg [KEEP_WIDTH-1:0] current_input_{{p}}_axis_tkeep; +reg current_input_{{p}}_axis_tvalid; +reg current_input_{{p}}_axis_tready; +reg current_input_{{p}}_axis_tlast; +reg [DEST_WIDTH-1:0] current_input_{{p}}_axis_tdest; +reg current_input_{{p}}_axis_tuser; + +always @* begin + case (select_{{p}}_reg) +{%- for q in range(m) %} + {{cm}}'d{{q}}: begin + current_input_{{p}}_axis_tdata = input_{{q}}_axis_tdata; + current_input_{{p}}_axis_tkeep = input_{{q}}_axis_tkeep; + current_input_{{p}}_axis_tvalid = input_{{q}}_axis_tvalid; + current_input_{{p}}_axis_tready = input_{{q}}_axis_tready; + current_input_{{p}}_axis_tlast = input_{{q}}_axis_tlast; + current_input_{{p}}_axis_tdest = input_{{q}}_axis_tdest; + current_input_{{p}}_axis_tuser = input_{{q}}_axis_tuser; + end +{%- endfor %} + default: begin + current_input_{{p}}_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_{{p}}_axis_tkeep = {KEEP_WIDTH{1'b0}}; + current_input_{{p}}_axis_tvalid = 1'b0; + current_input_{{p}}_axis_tready = 1'b0; + current_input_{{p}}_axis_tlast = 1'b0; + current_input_{{p}}_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_{{p}}_axis_tuser = 1'b0; + end + endcase +end +{% endfor %} +// arbiter instances +{% for p in range(n) %} +wire [{{m-1}}:0] request_{{p}}; +wire [{{m-1}}:0] acknowledge_{{p}}; +wire [{{m-1}}:0] grant_{{p}}; +wire grant_valid_{{p}}; +wire [{{cm-1}}:0] grant_encoded_{{p}}; +{% endfor %} + +{%- for p in range(n) %} +arbiter #( + .PORTS({{m}}), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_{{p}}_inst ( + .clk(clk), + .rst(rst), + .request(request_{{p}}), + .acknowledge(acknowledge_{{p}}), + .grant(grant_{{p}}), + .grant_valid(grant_valid_{{p}}), + .grant_encoded(grant_encoded_{{p}}) +); +{% endfor %} +// request generation +{%- for p in range(n) %} +{%- for q in range(m) %} +assign request_{{p}}[{{q}}] = input_{{q}}_request_reg[{{p}}] & ~acknowledge_{{p}}[{{q}}]; +{%- endfor %} +{% endfor %} +// acknowledge generation +{%- for p in range(n) %} +{%- for q in range(m) %} +assign acknowledge_{{p}}[{{q}}] = grant_{{p}}[{{q}}] & input_{{q}}_axis_tvalid & input_{{q}}_axis_tready & input_{{q}}_axis_tlast; +{%- endfor %} +{% endfor %} +always @* begin +{%- for p in range(n) %} + select_{{p}}_next = select_{{p}}_reg; +{%- endfor %} +{% for p in range(n) %} + enable_{{p}}_next = enable_{{p}}_reg; +{%- endfor %} +{% for p in range(m) %} + input_{{p}}_request_next = input_{{p}}_request_reg; + input_{{p}}_request_valid_next = input_{{p}}_request_valid_reg; + input_{{p}}_request_error_next = input_{{p}}_request_error_reg; +{% endfor %} +{%- for p in range(m) %} + input_{{p}}_axis_tready_next = 1'b0; +{%- endfor %} +{% for p in range(n) %} + output_{{p}}_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_{{p}}_axis_tkeep_int = {DATA_WIDTH{1'b0}}; + output_{{p}}_axis_tvalid_int = 1'b0; + output_{{p}}_axis_tlast_int = 1'b0; + output_{{p}}_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_{{p}}_axis_tuser_int = 1'b0; +{% endfor %} + // input decoding +{% for p in range(m) %} + if (input_{{p}}_request_valid_reg | input_{{p}}_request_error_reg) begin + if (input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast) begin + input_{{p}}_request_next = {DEST_WIDTH{1'b0}}; + input_{{p}}_request_valid_next = 1'b0; + input_{{p}}_request_error_next = 1'b0; + end + end else if (input_{{p}}_axis_tvalid) begin +{%- for q in range(n) %} + input_{{p}}_request_next[{{q}}] = (input_{{p}}_axis_tdest >= OUT_{{q}}_BASE) & (input_{{p}}_axis_tdest <= OUT_{{q}}_TOP) & OUT_{{q}}_CONNECT[{{p}}]; +{%- endfor %} + + if (input_{{p}}_request_next) begin + input_{{p}}_request_valid_next = 1'b1; + end else begin + input_{{p}}_request_error_next = 1'b1; + end + end +{% endfor %} + // output control +{% for p in range(n) %} + if (enable_{{p}}_reg) begin + if (current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready) begin + enable_{{p}}_next = ~current_input_{{p}}_axis_tlast; + end + end else if (grant_valid_{{p}} & selected_input_{{p}}_axis_tvalid) begin + enable_{{p}}_next = 1'b1; + select_{{p}}_next = grant_encoded_{{p}}; + end +{% endfor %} + // generate ready signal on selected port +{% for p in range(n) %} + if (enable_{{p}}_next) begin + case (select_{{p}}_next) +{%- for q in range(m) %} + {{cm}}'d{{q}}: input_{{q}}_axis_tready_next = output_{{p}}_axis_tready_int_early; +{%- endfor %} + endcase + end +{% endfor %} + +{%- for p in range(m) %} + if (input_{{p}}_request_error_next) + input_{{p}}_axis_tready_next = 1'b1; +{%- endfor %} + + // pass through selected packet data +{% for p in range(n) %} + output_{{p}}_axis_tdata_int = current_input_{{p}}_axis_tdata; + output_{{p}}_axis_tkeep_int = current_input_{{p}}_axis_tkeep; + output_{{p}}_axis_tvalid_int = current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready & enable_{{p}}_reg; + output_{{p}}_axis_tlast_int = current_input_{{p}}_axis_tlast; + output_{{p}}_axis_tdest_int = current_input_{{p}}_axis_tdest; + output_{{p}}_axis_tuser_int = current_input_{{p}}_axis_tuser; +{% endfor -%} +end + +always @(posedge clk) begin + if (rst) begin +{%- for p in range(m) %} + input_{{p}}_request_reg <= {{n}}'d0; + input_{{p}}_request_valid_reg <= 1'b0; + input_{{p}}_request_error_reg <= 1'b0; +{%- endfor %} +{%- for p in range(n) %} + select_{{p}}_reg <= 2'd0; +{%- endfor %} +{%- for p in range(n) %} + enable_{{p}}_reg <= 1'b0; +{%- endfor %} +{%- for p in range(m) %} + input_{{p}}_axis_tready_reg <= 1'b0; +{%- endfor %} + end else begin +{%- for p in range(m) %} + input_{{p}}_request_reg <= input_{{p}}_request_next; + input_{{p}}_request_valid_reg <= input_{{p}}_request_valid_next; + input_{{p}}_request_error_reg <= input_{{p}}_request_error_next; +{%- endfor %} +{%- for p in range(n) %} + select_{{p}}_reg <= select_{{p}}_next; +{%- endfor %} +{%- for p in range(n) %} + enable_{{p}}_reg <= enable_{{p}}_next; +{%- endfor %} +{%- for p in range(m) %} + input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; +{%- endfor %} + end +end +{% for p in range(n) %} +// output {{p}} datapath logic +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_{{p}}_axis_tvalid_reg = 1'b0, output_{{p}}_axis_tvalid_next; +reg output_{{p}}_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg output_{{p}}_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_{{p}}_axis_tvalid_reg = 1'b0, temp_{{p}}_axis_tvalid_next; +reg temp_{{p}}_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] temp_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg temp_{{p}}_axis_tuser_reg = 1'b0; + +// datapath control +reg store_{{p}}_axis_int_to_output; +reg store_{{p}}_axis_int_to_temp; +reg store_{{p}}_axis_temp_to_output; + +assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; +assign output_{{p}}_axis_tkeep = output_{{p}}_axis_tkeep_reg; +assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; +assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; +assign output_{{p}}_axis_tdest = output_{{p}}_axis_tdest_reg; +assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_{{p}}_axis_tready_int_early = output_{{p}}_axis_tready | (~temp_{{p}}_axis_tvalid_reg & (~output_{{p}}_axis_tvalid_reg | ~output_{{p}}_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_reg; + temp_{{p}}_axis_tvalid_next = temp_{{p}}_axis_tvalid_reg; + + store_{{p}}_axis_int_to_output = 1'b0; + store_{{p}}_axis_int_to_temp = 1'b0; + store_{{p}}_axis_temp_to_output = 1'b0; + + if (output_{{p}}_axis_tready_int_reg) begin + // input is ready + if (output_{{p}}_axis_tready | ~output_{{p}}_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_int; + store_{{p}}_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_int; + store_{{p}}_axis_int_to_temp = 1'b1; + end + end else if (output_{{p}}_axis_tready) begin + // input is not ready, but output is ready + output_{{p}}_axis_tvalid_next = temp_{{p}}_axis_tvalid_reg; + temp_{{p}}_axis_tvalid_next = 1'b0; + store_{{p}}_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_{{p}}_axis_tvalid_reg <= 1'b0; + output_{{p}}_axis_tready_int_reg <= 1'b0; + temp_{{p}}_axis_tvalid_reg <= 1'b0; + end else begin + output_{{p}}_axis_tvalid_reg <= output_{{p}}_axis_tvalid_next; + output_{{p}}_axis_tready_int_reg <= output_{{p}}_axis_tready_int_early; + temp_{{p}}_axis_tvalid_reg <= temp_{{p}}_axis_tvalid_next; + end + + // datapath + if (store_{{p}}_axis_int_to_output) begin + output_{{p}}_axis_tdata_reg <= output_{{p}}_axis_tdata_int; + output_{{p}}_axis_tkeep_reg <= output_{{p}}_axis_tkeep_int; + output_{{p}}_axis_tlast_reg <= output_{{p}}_axis_tlast_int; + output_{{p}}_axis_tdest_reg <= output_{{p}}_axis_tdest_int; + output_{{p}}_axis_tuser_reg <= output_{{p}}_axis_tuser_int; + end else if (store_{{p}}_axis_temp_to_output) begin + output_{{p}}_axis_tdata_reg <= temp_{{p}}_axis_tdata_reg; + output_{{p}}_axis_tkeep_reg <= temp_{{p}}_axis_tkeep_reg; + output_{{p}}_axis_tlast_reg <= temp_{{p}}_axis_tlast_reg; + output_{{p}}_axis_tdest_reg <= temp_{{p}}_axis_tdest_reg; + output_{{p}}_axis_tuser_reg <= temp_{{p}}_axis_tuser_reg; + end + + if (store_{{p}}_axis_int_to_temp) begin + temp_{{p}}_axis_tdata_reg <= output_{{p}}_axis_tdata_int; + temp_{{p}}_axis_tkeep_reg <= output_{{p}}_axis_tkeep_int; + temp_{{p}}_axis_tlast_reg <= output_{{p}}_axis_tlast_int; + temp_{{p}}_axis_tdest_reg <= output_{{p}}_axis_tdest_int; + temp_{{p}}_axis_tuser_reg <= output_{{p}}_axis_tuser_int; + end +end +{% endfor %} +endmodule + +""") + + output_file.write(t.render( + m=m, + n=n, + cm=cm, + cn=cn, + name=name + )) + + print("Done") + +if __name__ == "__main__": + main() + diff --git a/rtl/axis_switch_64_4x4.v b/rtl/axis_switch_64_4x4.v new file mode 100644 index 000000000..6370a1f4a --- /dev/null +++ b/rtl/axis_switch_64_4x4.v @@ -0,0 +1,1331 @@ +/* + +Copyright (c) 2016 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 4x4 switch (64 bit datapath) + */ +module axis_switch_64_4x4 # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter DEST_WIDTH = 2, + parameter OUT_0_BASE = 0, + parameter OUT_0_TOP = 0, + parameter OUT_0_CONNECT = 4'b1111, + parameter OUT_1_BASE = 1, + parameter OUT_1_TOP = 1, + parameter OUT_1_CONNECT = 4'b1111, + parameter OUT_2_BASE = 2, + parameter OUT_2_TOP = 2, + parameter OUT_2_CONNECT = 4'b1111, + parameter OUT_3_BASE = 3, + parameter OUT_3_TOP = 3, + parameter OUT_3_CONNECT = 4'b1111, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "ROUND_ROBIN", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ + input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, + input wire input_0_axis_tvalid, + output wire input_0_axis_tready, + input wire input_0_axis_tlast, + input wire [DEST_WIDTH-1:0] input_0_axis_tdest, + input wire input_0_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, + input wire input_1_axis_tvalid, + output wire input_1_axis_tready, + input wire input_1_axis_tlast, + input wire [DEST_WIDTH-1:0] input_1_axis_tdest, + input wire input_1_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, + input wire input_2_axis_tvalid, + output wire input_2_axis_tready, + input wire input_2_axis_tlast, + input wire [DEST_WIDTH-1:0] input_2_axis_tdest, + input wire input_2_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, + input wire input_3_axis_tvalid, + output wire input_3_axis_tready, + input wire input_3_axis_tlast, + input wire [DEST_WIDTH-1:0] input_3_axis_tdest, + input wire input_3_axis_tuser, + + /* + * AXI Stream outputs + */ + output wire [DATA_WIDTH-1:0] output_0_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, + output wire output_0_axis_tvalid, + input wire output_0_axis_tready, + output wire output_0_axis_tlast, + output wire [DEST_WIDTH-1:0] output_0_axis_tdest, + output wire output_0_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_1_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, + output wire output_1_axis_tvalid, + input wire output_1_axis_tready, + output wire output_1_axis_tlast, + output wire [DEST_WIDTH-1:0] output_1_axis_tdest, + output wire output_1_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_2_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, + output wire output_2_axis_tvalid, + input wire output_2_axis_tready, + output wire output_2_axis_tlast, + output wire [DEST_WIDTH-1:0] output_2_axis_tdest, + output wire output_2_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_3_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, + output wire output_3_axis_tvalid, + input wire output_3_axis_tready, + output wire output_3_axis_tlast, + output wire [DEST_WIDTH-1:0] output_3_axis_tdest, + output wire output_3_axis_tuser +); + +// check configuration +initial begin + if (2**DEST_WIDTH < 4) begin + $error("Error: DEST_WIDTH too small for port count"); + $finish; + end + + if ((OUT_0_BASE & 2**DEST_WIDTH-1) != OUT_0_BASE || (OUT_0_TOP & 2**DEST_WIDTH-1) != OUT_0_TOP || + (OUT_1_BASE & 2**DEST_WIDTH-1) != OUT_1_BASE || (OUT_1_TOP & 2**DEST_WIDTH-1) != OUT_1_TOP || + (OUT_2_BASE & 2**DEST_WIDTH-1) != OUT_2_BASE || (OUT_2_TOP & 2**DEST_WIDTH-1) != OUT_2_TOP || + (OUT_3_BASE & 2**DEST_WIDTH-1) != OUT_3_BASE || (OUT_3_TOP & 2**DEST_WIDTH-1) != OUT_3_TOP) begin + $error("Error: value out of range"); + $finish; + end + + if (OUT_0_BASE > OUT_0_TOP || + OUT_1_BASE > OUT_1_TOP || + OUT_2_BASE > OUT_2_TOP || + OUT_3_BASE > OUT_3_TOP) begin + $error("Error: invalid range"); + $finish; + end + + if ((OUT_0_BASE <= OUT_1_TOP && OUT_1_BASE <= OUT_0_TOP) || + (OUT_0_BASE <= OUT_2_TOP && OUT_2_BASE <= OUT_0_TOP) || + (OUT_0_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_0_TOP) || + (OUT_1_BASE <= OUT_2_TOP && OUT_2_BASE <= OUT_1_TOP) || + (OUT_1_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_1_TOP) || + (OUT_2_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_2_TOP)) begin + $error("Error: ranges overlap"); + $finish; + end +end + +reg [3:0] input_0_request_reg = 4'd0, input_0_request_next; +reg input_0_request_valid_reg = 1'b0, input_0_request_valid_next; +reg input_0_request_error_reg = 1'b0, input_0_request_error_next; + +reg [3:0] input_1_request_reg = 4'd0, input_1_request_next; +reg input_1_request_valid_reg = 1'b0, input_1_request_valid_next; +reg input_1_request_error_reg = 1'b0, input_1_request_error_next; + +reg [3:0] input_2_request_reg = 4'd0, input_2_request_next; +reg input_2_request_valid_reg = 1'b0, input_2_request_valid_next; +reg input_2_request_error_reg = 1'b0, input_2_request_error_next; + +reg [3:0] input_3_request_reg = 4'd0, input_3_request_next; +reg input_3_request_valid_reg = 1'b0, input_3_request_valid_next; +reg input_3_request_error_reg = 1'b0, input_3_request_error_next; + +reg [1:0] select_0_reg = 2'd0, select_0_next; +reg [1:0] select_1_reg = 2'd0, select_1_next; +reg [1:0] select_2_reg = 2'd0, select_2_next; +reg [1:0] select_3_reg = 2'd0, select_3_next; + +reg enable_0_reg = 1'b0, enable_0_next; +reg enable_1_reg = 1'b0, enable_1_next; +reg enable_2_reg = 1'b0, enable_2_next; +reg enable_3_reg = 1'b0, enable_3_next; + +reg input_0_axis_tready_reg = 1'b0, input_0_axis_tready_next; +reg input_1_axis_tready_reg = 1'b0, input_1_axis_tready_next; +reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; +reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; + +// internal datapath +reg [DATA_WIDTH-1:0] output_0_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_int; +reg output_0_axis_tvalid_int; +reg output_0_axis_tready_int_reg = 1'b0; +reg output_0_axis_tlast_int; +reg [DEST_WIDTH-1:0] output_0_axis_tdest_int; +reg output_0_axis_tuser_int; +wire output_0_axis_tready_int_early; + +reg [DATA_WIDTH-1:0] output_1_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_int; +reg output_1_axis_tvalid_int; +reg output_1_axis_tready_int_reg = 1'b0; +reg output_1_axis_tlast_int; +reg [DEST_WIDTH-1:0] output_1_axis_tdest_int; +reg output_1_axis_tuser_int; +wire output_1_axis_tready_int_early; + +reg [DATA_WIDTH-1:0] output_2_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_int; +reg output_2_axis_tvalid_int; +reg output_2_axis_tready_int_reg = 1'b0; +reg output_2_axis_tlast_int; +reg [DEST_WIDTH-1:0] output_2_axis_tdest_int; +reg output_2_axis_tuser_int; +wire output_2_axis_tready_int_early; + +reg [DATA_WIDTH-1:0] output_3_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_int; +reg output_3_axis_tvalid_int; +reg output_3_axis_tready_int_reg = 1'b0; +reg output_3_axis_tlast_int; +reg [DEST_WIDTH-1:0] output_3_axis_tdest_int; +reg output_3_axis_tuser_int; +wire output_3_axis_tready_int_early; + +assign input_0_axis_tready = input_0_axis_tready_reg; +assign input_1_axis_tready = input_1_axis_tready_reg; +assign input_2_axis_tready = input_2_axis_tready_reg; +assign input_3_axis_tready = input_3_axis_tready_reg; + +// mux for start of packet detection +reg selected_input_0_axis_tvalid; + +always @* begin + case (grant_encoded_0) + 2'd0: selected_input_0_axis_tvalid = input_0_axis_tvalid; + 2'd1: selected_input_0_axis_tvalid = input_1_axis_tvalid; + 2'd2: selected_input_0_axis_tvalid = input_2_axis_tvalid; + 2'd3: selected_input_0_axis_tvalid = input_3_axis_tvalid; + default: selected_input_0_axis_tvalid = 1'b0; + endcase +end + +reg selected_input_1_axis_tvalid; + +always @* begin + case (grant_encoded_1) + 2'd0: selected_input_1_axis_tvalid = input_0_axis_tvalid; + 2'd1: selected_input_1_axis_tvalid = input_1_axis_tvalid; + 2'd2: selected_input_1_axis_tvalid = input_2_axis_tvalid; + 2'd3: selected_input_1_axis_tvalid = input_3_axis_tvalid; + default: selected_input_1_axis_tvalid = 1'b0; + endcase +end + +reg selected_input_2_axis_tvalid; + +always @* begin + case (grant_encoded_2) + 2'd0: selected_input_2_axis_tvalid = input_0_axis_tvalid; + 2'd1: selected_input_2_axis_tvalid = input_1_axis_tvalid; + 2'd2: selected_input_2_axis_tvalid = input_2_axis_tvalid; + 2'd3: selected_input_2_axis_tvalid = input_3_axis_tvalid; + default: selected_input_2_axis_tvalid = 1'b0; + endcase +end + +reg selected_input_3_axis_tvalid; + +always @* begin + case (grant_encoded_3) + 2'd0: selected_input_3_axis_tvalid = input_0_axis_tvalid; + 2'd1: selected_input_3_axis_tvalid = input_1_axis_tvalid; + 2'd2: selected_input_3_axis_tvalid = input_2_axis_tvalid; + 2'd3: selected_input_3_axis_tvalid = input_3_axis_tvalid; + default: selected_input_3_axis_tvalid = 1'b0; + endcase +end + +// mux for incoming packet + +reg [DATA_WIDTH-1:0] current_input_0_axis_tdata; +reg [KEEP_WIDTH-1:0] current_input_0_axis_tkeep; +reg current_input_0_axis_tvalid; +reg current_input_0_axis_tready; +reg current_input_0_axis_tlast; +reg [DEST_WIDTH-1:0] current_input_0_axis_tdest; +reg current_input_0_axis_tuser; + +always @* begin + case (select_0_reg) + 2'd0: begin + current_input_0_axis_tdata = input_0_axis_tdata; + current_input_0_axis_tkeep = input_0_axis_tkeep; + current_input_0_axis_tvalid = input_0_axis_tvalid; + current_input_0_axis_tready = input_0_axis_tready; + current_input_0_axis_tlast = input_0_axis_tlast; + current_input_0_axis_tdest = input_0_axis_tdest; + current_input_0_axis_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_0_axis_tdata = input_1_axis_tdata; + current_input_0_axis_tkeep = input_1_axis_tkeep; + current_input_0_axis_tvalid = input_1_axis_tvalid; + current_input_0_axis_tready = input_1_axis_tready; + current_input_0_axis_tlast = input_1_axis_tlast; + current_input_0_axis_tdest = input_1_axis_tdest; + current_input_0_axis_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_0_axis_tdata = input_2_axis_tdata; + current_input_0_axis_tkeep = input_2_axis_tkeep; + current_input_0_axis_tvalid = input_2_axis_tvalid; + current_input_0_axis_tready = input_2_axis_tready; + current_input_0_axis_tlast = input_2_axis_tlast; + current_input_0_axis_tdest = input_2_axis_tdest; + current_input_0_axis_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_0_axis_tdata = input_3_axis_tdata; + current_input_0_axis_tkeep = input_3_axis_tkeep; + current_input_0_axis_tvalid = input_3_axis_tvalid; + current_input_0_axis_tready = input_3_axis_tready; + current_input_0_axis_tlast = input_3_axis_tlast; + current_input_0_axis_tdest = input_3_axis_tdest; + current_input_0_axis_tuser = input_3_axis_tuser; + end + default: begin + current_input_0_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_0_axis_tkeep = {KEEP_WIDTH{1'b0}}; + current_input_0_axis_tvalid = 1'b0; + current_input_0_axis_tready = 1'b0; + current_input_0_axis_tlast = 1'b0; + current_input_0_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_0_axis_tuser = 1'b0; + end + endcase +end + +reg [DATA_WIDTH-1:0] current_input_1_axis_tdata; +reg [KEEP_WIDTH-1:0] current_input_1_axis_tkeep; +reg current_input_1_axis_tvalid; +reg current_input_1_axis_tready; +reg current_input_1_axis_tlast; +reg [DEST_WIDTH-1:0] current_input_1_axis_tdest; +reg current_input_1_axis_tuser; + +always @* begin + case (select_1_reg) + 2'd0: begin + current_input_1_axis_tdata = input_0_axis_tdata; + current_input_1_axis_tkeep = input_0_axis_tkeep; + current_input_1_axis_tvalid = input_0_axis_tvalid; + current_input_1_axis_tready = input_0_axis_tready; + current_input_1_axis_tlast = input_0_axis_tlast; + current_input_1_axis_tdest = input_0_axis_tdest; + current_input_1_axis_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_1_axis_tdata = input_1_axis_tdata; + current_input_1_axis_tkeep = input_1_axis_tkeep; + current_input_1_axis_tvalid = input_1_axis_tvalid; + current_input_1_axis_tready = input_1_axis_tready; + current_input_1_axis_tlast = input_1_axis_tlast; + current_input_1_axis_tdest = input_1_axis_tdest; + current_input_1_axis_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_1_axis_tdata = input_2_axis_tdata; + current_input_1_axis_tkeep = input_2_axis_tkeep; + current_input_1_axis_tvalid = input_2_axis_tvalid; + current_input_1_axis_tready = input_2_axis_tready; + current_input_1_axis_tlast = input_2_axis_tlast; + current_input_1_axis_tdest = input_2_axis_tdest; + current_input_1_axis_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_1_axis_tdata = input_3_axis_tdata; + current_input_1_axis_tkeep = input_3_axis_tkeep; + current_input_1_axis_tvalid = input_3_axis_tvalid; + current_input_1_axis_tready = input_3_axis_tready; + current_input_1_axis_tlast = input_3_axis_tlast; + current_input_1_axis_tdest = input_3_axis_tdest; + current_input_1_axis_tuser = input_3_axis_tuser; + end + default: begin + current_input_1_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_1_axis_tkeep = {KEEP_WIDTH{1'b0}}; + current_input_1_axis_tvalid = 1'b0; + current_input_1_axis_tready = 1'b0; + current_input_1_axis_tlast = 1'b0; + current_input_1_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_1_axis_tuser = 1'b0; + end + endcase +end + +reg [DATA_WIDTH-1:0] current_input_2_axis_tdata; +reg [KEEP_WIDTH-1:0] current_input_2_axis_tkeep; +reg current_input_2_axis_tvalid; +reg current_input_2_axis_tready; +reg current_input_2_axis_tlast; +reg [DEST_WIDTH-1:0] current_input_2_axis_tdest; +reg current_input_2_axis_tuser; + +always @* begin + case (select_2_reg) + 2'd0: begin + current_input_2_axis_tdata = input_0_axis_tdata; + current_input_2_axis_tkeep = input_0_axis_tkeep; + current_input_2_axis_tvalid = input_0_axis_tvalid; + current_input_2_axis_tready = input_0_axis_tready; + current_input_2_axis_tlast = input_0_axis_tlast; + current_input_2_axis_tdest = input_0_axis_tdest; + current_input_2_axis_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_2_axis_tdata = input_1_axis_tdata; + current_input_2_axis_tkeep = input_1_axis_tkeep; + current_input_2_axis_tvalid = input_1_axis_tvalid; + current_input_2_axis_tready = input_1_axis_tready; + current_input_2_axis_tlast = input_1_axis_tlast; + current_input_2_axis_tdest = input_1_axis_tdest; + current_input_2_axis_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_2_axis_tdata = input_2_axis_tdata; + current_input_2_axis_tkeep = input_2_axis_tkeep; + current_input_2_axis_tvalid = input_2_axis_tvalid; + current_input_2_axis_tready = input_2_axis_tready; + current_input_2_axis_tlast = input_2_axis_tlast; + current_input_2_axis_tdest = input_2_axis_tdest; + current_input_2_axis_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_2_axis_tdata = input_3_axis_tdata; + current_input_2_axis_tkeep = input_3_axis_tkeep; + current_input_2_axis_tvalid = input_3_axis_tvalid; + current_input_2_axis_tready = input_3_axis_tready; + current_input_2_axis_tlast = input_3_axis_tlast; + current_input_2_axis_tdest = input_3_axis_tdest; + current_input_2_axis_tuser = input_3_axis_tuser; + end + default: begin + current_input_2_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_2_axis_tkeep = {KEEP_WIDTH{1'b0}}; + current_input_2_axis_tvalid = 1'b0; + current_input_2_axis_tready = 1'b0; + current_input_2_axis_tlast = 1'b0; + current_input_2_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_2_axis_tuser = 1'b0; + end + endcase +end + +reg [DATA_WIDTH-1:0] current_input_3_axis_tdata; +reg [KEEP_WIDTH-1:0] current_input_3_axis_tkeep; +reg current_input_3_axis_tvalid; +reg current_input_3_axis_tready; +reg current_input_3_axis_tlast; +reg [DEST_WIDTH-1:0] current_input_3_axis_tdest; +reg current_input_3_axis_tuser; + +always @* begin + case (select_3_reg) + 2'd0: begin + current_input_3_axis_tdata = input_0_axis_tdata; + current_input_3_axis_tkeep = input_0_axis_tkeep; + current_input_3_axis_tvalid = input_0_axis_tvalid; + current_input_3_axis_tready = input_0_axis_tready; + current_input_3_axis_tlast = input_0_axis_tlast; + current_input_3_axis_tdest = input_0_axis_tdest; + current_input_3_axis_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_3_axis_tdata = input_1_axis_tdata; + current_input_3_axis_tkeep = input_1_axis_tkeep; + current_input_3_axis_tvalid = input_1_axis_tvalid; + current_input_3_axis_tready = input_1_axis_tready; + current_input_3_axis_tlast = input_1_axis_tlast; + current_input_3_axis_tdest = input_1_axis_tdest; + current_input_3_axis_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_3_axis_tdata = input_2_axis_tdata; + current_input_3_axis_tkeep = input_2_axis_tkeep; + current_input_3_axis_tvalid = input_2_axis_tvalid; + current_input_3_axis_tready = input_2_axis_tready; + current_input_3_axis_tlast = input_2_axis_tlast; + current_input_3_axis_tdest = input_2_axis_tdest; + current_input_3_axis_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_3_axis_tdata = input_3_axis_tdata; + current_input_3_axis_tkeep = input_3_axis_tkeep; + current_input_3_axis_tvalid = input_3_axis_tvalid; + current_input_3_axis_tready = input_3_axis_tready; + current_input_3_axis_tlast = input_3_axis_tlast; + current_input_3_axis_tdest = input_3_axis_tdest; + current_input_3_axis_tuser = input_3_axis_tuser; + end + default: begin + current_input_3_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_3_axis_tkeep = {KEEP_WIDTH{1'b0}}; + current_input_3_axis_tvalid = 1'b0; + current_input_3_axis_tready = 1'b0; + current_input_3_axis_tlast = 1'b0; + current_input_3_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_3_axis_tuser = 1'b0; + end + endcase +end + +// arbiter instances + +wire [3:0] request_0; +wire [3:0] acknowledge_0; +wire [3:0] grant_0; +wire grant_valid_0; +wire [1:0] grant_encoded_0; + +wire [3:0] request_1; +wire [3:0] acknowledge_1; +wire [3:0] grant_1; +wire grant_valid_1; +wire [1:0] grant_encoded_1; + +wire [3:0] request_2; +wire [3:0] acknowledge_2; +wire [3:0] grant_2; +wire grant_valid_2; +wire [1:0] grant_encoded_2; + +wire [3:0] request_3; +wire [3:0] acknowledge_3; +wire [3:0] grant_3; +wire grant_valid_3; +wire [1:0] grant_encoded_3; + +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_0_inst ( + .clk(clk), + .rst(rst), + .request(request_0), + .acknowledge(acknowledge_0), + .grant(grant_0), + .grant_valid(grant_valid_0), + .grant_encoded(grant_encoded_0) +); + +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_1_inst ( + .clk(clk), + .rst(rst), + .request(request_1), + .acknowledge(acknowledge_1), + .grant(grant_1), + .grant_valid(grant_valid_1), + .grant_encoded(grant_encoded_1) +); + +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_2_inst ( + .clk(clk), + .rst(rst), + .request(request_2), + .acknowledge(acknowledge_2), + .grant(grant_2), + .grant_valid(grant_valid_2), + .grant_encoded(grant_encoded_2) +); + +arbiter #( + .PORTS(4), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_3_inst ( + .clk(clk), + .rst(rst), + .request(request_3), + .acknowledge(acknowledge_3), + .grant(grant_3), + .grant_valid(grant_valid_3), + .grant_encoded(grant_encoded_3) +); + +// request generation +assign request_0[0] = input_0_request_reg[0] & ~acknowledge_0[0]; +assign request_0[1] = input_1_request_reg[0] & ~acknowledge_0[1]; +assign request_0[2] = input_2_request_reg[0] & ~acknowledge_0[2]; +assign request_0[3] = input_3_request_reg[0] & ~acknowledge_0[3]; + +assign request_1[0] = input_0_request_reg[1] & ~acknowledge_1[0]; +assign request_1[1] = input_1_request_reg[1] & ~acknowledge_1[1]; +assign request_1[2] = input_2_request_reg[1] & ~acknowledge_1[2]; +assign request_1[3] = input_3_request_reg[1] & ~acknowledge_1[3]; + +assign request_2[0] = input_0_request_reg[2] & ~acknowledge_2[0]; +assign request_2[1] = input_1_request_reg[2] & ~acknowledge_2[1]; +assign request_2[2] = input_2_request_reg[2] & ~acknowledge_2[2]; +assign request_2[3] = input_3_request_reg[2] & ~acknowledge_2[3]; + +assign request_3[0] = input_0_request_reg[3] & ~acknowledge_3[0]; +assign request_3[1] = input_1_request_reg[3] & ~acknowledge_3[1]; +assign request_3[2] = input_2_request_reg[3] & ~acknowledge_3[2]; +assign request_3[3] = input_3_request_reg[3] & ~acknowledge_3[3]; + +// acknowledge generation +assign acknowledge_0[0] = grant_0[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign acknowledge_0[1] = grant_0[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign acknowledge_0[2] = grant_0[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign acknowledge_0[3] = grant_0[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; + +assign acknowledge_1[0] = grant_1[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign acknowledge_1[1] = grant_1[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign acknowledge_1[2] = grant_1[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign acknowledge_1[3] = grant_1[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; + +assign acknowledge_2[0] = grant_2[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign acknowledge_2[1] = grant_2[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign acknowledge_2[2] = grant_2[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign acknowledge_2[3] = grant_2[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; + +assign acknowledge_3[0] = grant_3[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign acknowledge_3[1] = grant_3[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign acknowledge_3[2] = grant_3[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign acknowledge_3[3] = grant_3[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; + +always @* begin + select_0_next = select_0_reg; + select_1_next = select_1_reg; + select_2_next = select_2_reg; + select_3_next = select_3_reg; + + enable_0_next = enable_0_reg; + enable_1_next = enable_1_reg; + enable_2_next = enable_2_reg; + enable_3_next = enable_3_reg; + + input_0_request_next = input_0_request_reg; + input_0_request_valid_next = input_0_request_valid_reg; + input_0_request_error_next = input_0_request_error_reg; + + input_1_request_next = input_1_request_reg; + input_1_request_valid_next = input_1_request_valid_reg; + input_1_request_error_next = input_1_request_error_reg; + + input_2_request_next = input_2_request_reg; + input_2_request_valid_next = input_2_request_valid_reg; + input_2_request_error_next = input_2_request_error_reg; + + input_3_request_next = input_3_request_reg; + input_3_request_valid_next = input_3_request_valid_reg; + input_3_request_error_next = input_3_request_error_reg; + + input_0_axis_tready_next = 1'b0; + input_1_axis_tready_next = 1'b0; + input_2_axis_tready_next = 1'b0; + input_3_axis_tready_next = 1'b0; + + output_0_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_0_axis_tkeep_int = {DATA_WIDTH{1'b0}}; + output_0_axis_tvalid_int = 1'b0; + output_0_axis_tlast_int = 1'b0; + output_0_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_0_axis_tuser_int = 1'b0; + + output_1_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_1_axis_tkeep_int = {DATA_WIDTH{1'b0}}; + output_1_axis_tvalid_int = 1'b0; + output_1_axis_tlast_int = 1'b0; + output_1_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_1_axis_tuser_int = 1'b0; + + output_2_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_2_axis_tkeep_int = {DATA_WIDTH{1'b0}}; + output_2_axis_tvalid_int = 1'b0; + output_2_axis_tlast_int = 1'b0; + output_2_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_2_axis_tuser_int = 1'b0; + + output_3_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_3_axis_tkeep_int = {DATA_WIDTH{1'b0}}; + output_3_axis_tvalid_int = 1'b0; + output_3_axis_tlast_int = 1'b0; + output_3_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_3_axis_tuser_int = 1'b0; + + // input decoding + + if (input_0_request_valid_reg | input_0_request_error_reg) begin + if (input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast) begin + input_0_request_next = {DEST_WIDTH{1'b0}}; + input_0_request_valid_next = 1'b0; + input_0_request_error_next = 1'b0; + end + end else if (input_0_axis_tvalid) begin + input_0_request_next[0] = (input_0_axis_tdest >= OUT_0_BASE) & (input_0_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[0]; + input_0_request_next[1] = (input_0_axis_tdest >= OUT_1_BASE) & (input_0_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[0]; + input_0_request_next[2] = (input_0_axis_tdest >= OUT_2_BASE) & (input_0_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[0]; + input_0_request_next[3] = (input_0_axis_tdest >= OUT_3_BASE) & (input_0_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[0]; + + if (input_0_request_next) begin + input_0_request_valid_next = 1'b1; + end else begin + input_0_request_error_next = 1'b1; + end + end + + if (input_1_request_valid_reg | input_1_request_error_reg) begin + if (input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast) begin + input_1_request_next = {DEST_WIDTH{1'b0}}; + input_1_request_valid_next = 1'b0; + input_1_request_error_next = 1'b0; + end + end else if (input_1_axis_tvalid) begin + input_1_request_next[0] = (input_1_axis_tdest >= OUT_0_BASE) & (input_1_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[1]; + input_1_request_next[1] = (input_1_axis_tdest >= OUT_1_BASE) & (input_1_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[1]; + input_1_request_next[2] = (input_1_axis_tdest >= OUT_2_BASE) & (input_1_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[1]; + input_1_request_next[3] = (input_1_axis_tdest >= OUT_3_BASE) & (input_1_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[1]; + + if (input_1_request_next) begin + input_1_request_valid_next = 1'b1; + end else begin + input_1_request_error_next = 1'b1; + end + end + + if (input_2_request_valid_reg | input_2_request_error_reg) begin + if (input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast) begin + input_2_request_next = {DEST_WIDTH{1'b0}}; + input_2_request_valid_next = 1'b0; + input_2_request_error_next = 1'b0; + end + end else if (input_2_axis_tvalid) begin + input_2_request_next[0] = (input_2_axis_tdest >= OUT_0_BASE) & (input_2_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[2]; + input_2_request_next[1] = (input_2_axis_tdest >= OUT_1_BASE) & (input_2_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[2]; + input_2_request_next[2] = (input_2_axis_tdest >= OUT_2_BASE) & (input_2_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[2]; + input_2_request_next[3] = (input_2_axis_tdest >= OUT_3_BASE) & (input_2_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[2]; + + if (input_2_request_next) begin + input_2_request_valid_next = 1'b1; + end else begin + input_2_request_error_next = 1'b1; + end + end + + if (input_3_request_valid_reg | input_3_request_error_reg) begin + if (input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast) begin + input_3_request_next = {DEST_WIDTH{1'b0}}; + input_3_request_valid_next = 1'b0; + input_3_request_error_next = 1'b0; + end + end else if (input_3_axis_tvalid) begin + input_3_request_next[0] = (input_3_axis_tdest >= OUT_0_BASE) & (input_3_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[3]; + input_3_request_next[1] = (input_3_axis_tdest >= OUT_1_BASE) & (input_3_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[3]; + input_3_request_next[2] = (input_3_axis_tdest >= OUT_2_BASE) & (input_3_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[3]; + input_3_request_next[3] = (input_3_axis_tdest >= OUT_3_BASE) & (input_3_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[3]; + + if (input_3_request_next) begin + input_3_request_valid_next = 1'b1; + end else begin + input_3_request_error_next = 1'b1; + end + end + + // output control + + if (enable_0_reg) begin + if (current_input_0_axis_tvalid & current_input_0_axis_tready) begin + enable_0_next = ~current_input_0_axis_tlast; + end + end else if (grant_valid_0 & selected_input_0_axis_tvalid) begin + enable_0_next = 1'b1; + select_0_next = grant_encoded_0; + end + + if (enable_1_reg) begin + if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin + enable_1_next = ~current_input_1_axis_tlast; + end + end else if (grant_valid_1 & selected_input_1_axis_tvalid) begin + enable_1_next = 1'b1; + select_1_next = grant_encoded_1; + end + + if (enable_2_reg) begin + if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin + enable_2_next = ~current_input_2_axis_tlast; + end + end else if (grant_valid_2 & selected_input_2_axis_tvalid) begin + enable_2_next = 1'b1; + select_2_next = grant_encoded_2; + end + + if (enable_3_reg) begin + if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin + enable_3_next = ~current_input_3_axis_tlast; + end + end else if (grant_valid_3 & selected_input_3_axis_tvalid) begin + enable_3_next = 1'b1; + select_3_next = grant_encoded_3; + end + + // generate ready signal on selected port + + if (enable_0_next) begin + case (select_0_next) + 2'd0: input_0_axis_tready_next = output_0_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_0_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_0_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_0_axis_tready_int_early; + endcase + end + + if (enable_1_next) begin + case (select_1_next) + 2'd0: input_0_axis_tready_next = output_1_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_1_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_1_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_1_axis_tready_int_early; + endcase + end + + if (enable_2_next) begin + case (select_2_next) + 2'd0: input_0_axis_tready_next = output_2_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_2_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_2_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_2_axis_tready_int_early; + endcase + end + + if (enable_3_next) begin + case (select_3_next) + 2'd0: input_0_axis_tready_next = output_3_axis_tready_int_early; + 2'd1: input_1_axis_tready_next = output_3_axis_tready_int_early; + 2'd2: input_2_axis_tready_next = output_3_axis_tready_int_early; + 2'd3: input_3_axis_tready_next = output_3_axis_tready_int_early; + endcase + end + + if (input_0_request_error_next) + input_0_axis_tready_next = 1'b1; + if (input_1_request_error_next) + input_1_axis_tready_next = 1'b1; + if (input_2_request_error_next) + input_2_axis_tready_next = 1'b1; + if (input_3_request_error_next) + input_3_axis_tready_next = 1'b1; + + // pass through selected packet data + + output_0_axis_tdata_int = current_input_0_axis_tdata; + output_0_axis_tkeep_int = current_input_0_axis_tkeep; + output_0_axis_tvalid_int = current_input_0_axis_tvalid & current_input_0_axis_tready & enable_0_reg; + output_0_axis_tlast_int = current_input_0_axis_tlast; + output_0_axis_tdest_int = current_input_0_axis_tdest; + output_0_axis_tuser_int = current_input_0_axis_tuser; + + output_1_axis_tdata_int = current_input_1_axis_tdata; + output_1_axis_tkeep_int = current_input_1_axis_tkeep; + output_1_axis_tvalid_int = current_input_1_axis_tvalid & current_input_1_axis_tready & enable_1_reg; + output_1_axis_tlast_int = current_input_1_axis_tlast; + output_1_axis_tdest_int = current_input_1_axis_tdest; + output_1_axis_tuser_int = current_input_1_axis_tuser; + + output_2_axis_tdata_int = current_input_2_axis_tdata; + output_2_axis_tkeep_int = current_input_2_axis_tkeep; + output_2_axis_tvalid_int = current_input_2_axis_tvalid & current_input_2_axis_tready & enable_2_reg; + output_2_axis_tlast_int = current_input_2_axis_tlast; + output_2_axis_tdest_int = current_input_2_axis_tdest; + output_2_axis_tuser_int = current_input_2_axis_tuser; + + output_3_axis_tdata_int = current_input_3_axis_tdata; + output_3_axis_tkeep_int = current_input_3_axis_tkeep; + output_3_axis_tvalid_int = current_input_3_axis_tvalid & current_input_3_axis_tready & enable_3_reg; + output_3_axis_tlast_int = current_input_3_axis_tlast; + output_3_axis_tdest_int = current_input_3_axis_tdest; + output_3_axis_tuser_int = current_input_3_axis_tuser; +end + +always @(posedge clk) begin + if (rst) begin + input_0_request_reg <= 4'd0; + input_0_request_valid_reg <= 1'b0; + input_0_request_error_reg <= 1'b0; + input_1_request_reg <= 4'd0; + input_1_request_valid_reg <= 1'b0; + input_1_request_error_reg <= 1'b0; + input_2_request_reg <= 4'd0; + input_2_request_valid_reg <= 1'b0; + input_2_request_error_reg <= 1'b0; + input_3_request_reg <= 4'd0; + input_3_request_valid_reg <= 1'b0; + input_3_request_error_reg <= 1'b0; + select_0_reg <= 2'd0; + select_1_reg <= 2'd0; + select_2_reg <= 2'd0; + select_3_reg <= 2'd0; + enable_0_reg <= 1'b0; + enable_1_reg <= 1'b0; + enable_2_reg <= 1'b0; + enable_3_reg <= 1'b0; + input_0_axis_tready_reg <= 1'b0; + input_1_axis_tready_reg <= 1'b0; + input_2_axis_tready_reg <= 1'b0; + input_3_axis_tready_reg <= 1'b0; + end else begin + input_0_request_reg <= input_0_request_next; + input_0_request_valid_reg <= input_0_request_valid_next; + input_0_request_error_reg <= input_0_request_error_next; + input_1_request_reg <= input_1_request_next; + input_1_request_valid_reg <= input_1_request_valid_next; + input_1_request_error_reg <= input_1_request_error_next; + input_2_request_reg <= input_2_request_next; + input_2_request_valid_reg <= input_2_request_valid_next; + input_2_request_error_reg <= input_2_request_error_next; + input_3_request_reg <= input_3_request_next; + input_3_request_valid_reg <= input_3_request_valid_next; + input_3_request_error_reg <= input_3_request_error_next; + select_0_reg <= select_0_next; + select_1_reg <= select_1_next; + select_2_reg <= select_2_next; + select_3_reg <= select_3_next; + enable_0_reg <= enable_0_next; + enable_1_reg <= enable_1_next; + enable_2_reg <= enable_2_next; + enable_3_reg <= enable_3_next; + input_0_axis_tready_reg <= input_0_axis_tready_next; + input_1_axis_tready_reg <= input_1_axis_tready_next; + input_2_axis_tready_reg <= input_2_axis_tready_next; + input_3_axis_tready_reg <= input_3_axis_tready_next; + end +end + +// output 0 datapath logic +reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_0_axis_tvalid_reg = 1'b0, output_0_axis_tvalid_next; +reg output_0_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] output_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg output_0_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_0_axis_tvalid_reg = 1'b0, temp_0_axis_tvalid_next; +reg temp_0_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] temp_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg temp_0_axis_tuser_reg = 1'b0; + +// datapath control +reg store_0_axis_int_to_output; +reg store_0_axis_int_to_temp; +reg store_0_axis_temp_to_output; + +assign output_0_axis_tdata = output_0_axis_tdata_reg; +assign output_0_axis_tkeep = output_0_axis_tkeep_reg; +assign output_0_axis_tvalid = output_0_axis_tvalid_reg; +assign output_0_axis_tlast = output_0_axis_tlast_reg; +assign output_0_axis_tdest = output_0_axis_tdest_reg; +assign output_0_axis_tuser = output_0_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_0_axis_tready_int_early = output_0_axis_tready | (~temp_0_axis_tvalid_reg & (~output_0_axis_tvalid_reg | ~output_0_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_0_axis_tvalid_next = output_0_axis_tvalid_reg; + temp_0_axis_tvalid_next = temp_0_axis_tvalid_reg; + + store_0_axis_int_to_output = 1'b0; + store_0_axis_int_to_temp = 1'b0; + store_0_axis_temp_to_output = 1'b0; + + if (output_0_axis_tready_int_reg) begin + // input is ready + if (output_0_axis_tready | ~output_0_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_0_axis_tvalid_next = output_0_axis_tvalid_int; + store_0_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_0_axis_tvalid_next = output_0_axis_tvalid_int; + store_0_axis_int_to_temp = 1'b1; + end + end else if (output_0_axis_tready) begin + // input is not ready, but output is ready + output_0_axis_tvalid_next = temp_0_axis_tvalid_reg; + temp_0_axis_tvalid_next = 1'b0; + store_0_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_0_axis_tvalid_reg <= 1'b0; + output_0_axis_tready_int_reg <= 1'b0; + temp_0_axis_tvalid_reg <= 1'b0; + end else begin + output_0_axis_tvalid_reg <= output_0_axis_tvalid_next; + output_0_axis_tready_int_reg <= output_0_axis_tready_int_early; + temp_0_axis_tvalid_reg <= temp_0_axis_tvalid_next; + end + + // datapath + if (store_0_axis_int_to_output) begin + output_0_axis_tdata_reg <= output_0_axis_tdata_int; + output_0_axis_tkeep_reg <= output_0_axis_tkeep_int; + output_0_axis_tlast_reg <= output_0_axis_tlast_int; + output_0_axis_tdest_reg <= output_0_axis_tdest_int; + output_0_axis_tuser_reg <= output_0_axis_tuser_int; + end else if (store_0_axis_temp_to_output) begin + output_0_axis_tdata_reg <= temp_0_axis_tdata_reg; + output_0_axis_tkeep_reg <= temp_0_axis_tkeep_reg; + output_0_axis_tlast_reg <= temp_0_axis_tlast_reg; + output_0_axis_tdest_reg <= temp_0_axis_tdest_reg; + output_0_axis_tuser_reg <= temp_0_axis_tuser_reg; + end + + if (store_0_axis_int_to_temp) begin + temp_0_axis_tdata_reg <= output_0_axis_tdata_int; + temp_0_axis_tkeep_reg <= output_0_axis_tkeep_int; + temp_0_axis_tlast_reg <= output_0_axis_tlast_int; + temp_0_axis_tdest_reg <= output_0_axis_tdest_int; + temp_0_axis_tuser_reg <= output_0_axis_tuser_int; + end +end + +// output 1 datapath logic +reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_1_axis_tvalid_reg = 1'b0, output_1_axis_tvalid_next; +reg output_1_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] output_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg output_1_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_1_axis_tvalid_reg = 1'b0, temp_1_axis_tvalid_next; +reg temp_1_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] temp_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg temp_1_axis_tuser_reg = 1'b0; + +// datapath control +reg store_1_axis_int_to_output; +reg store_1_axis_int_to_temp; +reg store_1_axis_temp_to_output; + +assign output_1_axis_tdata = output_1_axis_tdata_reg; +assign output_1_axis_tkeep = output_1_axis_tkeep_reg; +assign output_1_axis_tvalid = output_1_axis_tvalid_reg; +assign output_1_axis_tlast = output_1_axis_tlast_reg; +assign output_1_axis_tdest = output_1_axis_tdest_reg; +assign output_1_axis_tuser = output_1_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_1_axis_tready_int_early = output_1_axis_tready | (~temp_1_axis_tvalid_reg & (~output_1_axis_tvalid_reg | ~output_1_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_1_axis_tvalid_next = output_1_axis_tvalid_reg; + temp_1_axis_tvalid_next = temp_1_axis_tvalid_reg; + + store_1_axis_int_to_output = 1'b0; + store_1_axis_int_to_temp = 1'b0; + store_1_axis_temp_to_output = 1'b0; + + if (output_1_axis_tready_int_reg) begin + // input is ready + if (output_1_axis_tready | ~output_1_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_1_axis_tvalid_next = output_1_axis_tvalid_int; + store_1_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_1_axis_tvalid_next = output_1_axis_tvalid_int; + store_1_axis_int_to_temp = 1'b1; + end + end else if (output_1_axis_tready) begin + // input is not ready, but output is ready + output_1_axis_tvalid_next = temp_1_axis_tvalid_reg; + temp_1_axis_tvalid_next = 1'b0; + store_1_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_1_axis_tvalid_reg <= 1'b0; + output_1_axis_tready_int_reg <= 1'b0; + temp_1_axis_tvalid_reg <= 1'b0; + end else begin + output_1_axis_tvalid_reg <= output_1_axis_tvalid_next; + output_1_axis_tready_int_reg <= output_1_axis_tready_int_early; + temp_1_axis_tvalid_reg <= temp_1_axis_tvalid_next; + end + + // datapath + if (store_1_axis_int_to_output) begin + output_1_axis_tdata_reg <= output_1_axis_tdata_int; + output_1_axis_tkeep_reg <= output_1_axis_tkeep_int; + output_1_axis_tlast_reg <= output_1_axis_tlast_int; + output_1_axis_tdest_reg <= output_1_axis_tdest_int; + output_1_axis_tuser_reg <= output_1_axis_tuser_int; + end else if (store_1_axis_temp_to_output) begin + output_1_axis_tdata_reg <= temp_1_axis_tdata_reg; + output_1_axis_tkeep_reg <= temp_1_axis_tkeep_reg; + output_1_axis_tlast_reg <= temp_1_axis_tlast_reg; + output_1_axis_tdest_reg <= temp_1_axis_tdest_reg; + output_1_axis_tuser_reg <= temp_1_axis_tuser_reg; + end + + if (store_1_axis_int_to_temp) begin + temp_1_axis_tdata_reg <= output_1_axis_tdata_int; + temp_1_axis_tkeep_reg <= output_1_axis_tkeep_int; + temp_1_axis_tlast_reg <= output_1_axis_tlast_int; + temp_1_axis_tdest_reg <= output_1_axis_tdest_int; + temp_1_axis_tuser_reg <= output_1_axis_tuser_int; + end +end + +// output 2 datapath logic +reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_2_axis_tvalid_reg = 1'b0, output_2_axis_tvalid_next; +reg output_2_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] output_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg output_2_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_2_axis_tvalid_reg = 1'b0, temp_2_axis_tvalid_next; +reg temp_2_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] temp_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg temp_2_axis_tuser_reg = 1'b0; + +// datapath control +reg store_2_axis_int_to_output; +reg store_2_axis_int_to_temp; +reg store_2_axis_temp_to_output; + +assign output_2_axis_tdata = output_2_axis_tdata_reg; +assign output_2_axis_tkeep = output_2_axis_tkeep_reg; +assign output_2_axis_tvalid = output_2_axis_tvalid_reg; +assign output_2_axis_tlast = output_2_axis_tlast_reg; +assign output_2_axis_tdest = output_2_axis_tdest_reg; +assign output_2_axis_tuser = output_2_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_2_axis_tready_int_early = output_2_axis_tready | (~temp_2_axis_tvalid_reg & (~output_2_axis_tvalid_reg | ~output_2_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_2_axis_tvalid_next = output_2_axis_tvalid_reg; + temp_2_axis_tvalid_next = temp_2_axis_tvalid_reg; + + store_2_axis_int_to_output = 1'b0; + store_2_axis_int_to_temp = 1'b0; + store_2_axis_temp_to_output = 1'b0; + + if (output_2_axis_tready_int_reg) begin + // input is ready + if (output_2_axis_tready | ~output_2_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_2_axis_tvalid_next = output_2_axis_tvalid_int; + store_2_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_2_axis_tvalid_next = output_2_axis_tvalid_int; + store_2_axis_int_to_temp = 1'b1; + end + end else if (output_2_axis_tready) begin + // input is not ready, but output is ready + output_2_axis_tvalid_next = temp_2_axis_tvalid_reg; + temp_2_axis_tvalid_next = 1'b0; + store_2_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_2_axis_tvalid_reg <= 1'b0; + output_2_axis_tready_int_reg <= 1'b0; + temp_2_axis_tvalid_reg <= 1'b0; + end else begin + output_2_axis_tvalid_reg <= output_2_axis_tvalid_next; + output_2_axis_tready_int_reg <= output_2_axis_tready_int_early; + temp_2_axis_tvalid_reg <= temp_2_axis_tvalid_next; + end + + // datapath + if (store_2_axis_int_to_output) begin + output_2_axis_tdata_reg <= output_2_axis_tdata_int; + output_2_axis_tkeep_reg <= output_2_axis_tkeep_int; + output_2_axis_tlast_reg <= output_2_axis_tlast_int; + output_2_axis_tdest_reg <= output_2_axis_tdest_int; + output_2_axis_tuser_reg <= output_2_axis_tuser_int; + end else if (store_2_axis_temp_to_output) begin + output_2_axis_tdata_reg <= temp_2_axis_tdata_reg; + output_2_axis_tkeep_reg <= temp_2_axis_tkeep_reg; + output_2_axis_tlast_reg <= temp_2_axis_tlast_reg; + output_2_axis_tdest_reg <= temp_2_axis_tdest_reg; + output_2_axis_tuser_reg <= temp_2_axis_tuser_reg; + end + + if (store_2_axis_int_to_temp) begin + temp_2_axis_tdata_reg <= output_2_axis_tdata_int; + temp_2_axis_tkeep_reg <= output_2_axis_tkeep_int; + temp_2_axis_tlast_reg <= output_2_axis_tlast_int; + temp_2_axis_tdest_reg <= output_2_axis_tdest_int; + temp_2_axis_tuser_reg <= output_2_axis_tuser_int; + end +end + +// output 3 datapath logic +reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_3_axis_tvalid_reg = 1'b0, output_3_axis_tvalid_next; +reg output_3_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] output_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg output_3_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_3_axis_tvalid_reg = 1'b0, temp_3_axis_tvalid_next; +reg temp_3_axis_tlast_reg = 1'b0; +reg [DEST_WIDTH-1:0] temp_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg temp_3_axis_tuser_reg = 1'b0; + +// datapath control +reg store_3_axis_int_to_output; +reg store_3_axis_int_to_temp; +reg store_3_axis_temp_to_output; + +assign output_3_axis_tdata = output_3_axis_tdata_reg; +assign output_3_axis_tkeep = output_3_axis_tkeep_reg; +assign output_3_axis_tvalid = output_3_axis_tvalid_reg; +assign output_3_axis_tlast = output_3_axis_tlast_reg; +assign output_3_axis_tdest = output_3_axis_tdest_reg; +assign output_3_axis_tuser = output_3_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_3_axis_tready_int_early = output_3_axis_tready | (~temp_3_axis_tvalid_reg & (~output_3_axis_tvalid_reg | ~output_3_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_3_axis_tvalid_next = output_3_axis_tvalid_reg; + temp_3_axis_tvalid_next = temp_3_axis_tvalid_reg; + + store_3_axis_int_to_output = 1'b0; + store_3_axis_int_to_temp = 1'b0; + store_3_axis_temp_to_output = 1'b0; + + if (output_3_axis_tready_int_reg) begin + // input is ready + if (output_3_axis_tready | ~output_3_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_3_axis_tvalid_next = output_3_axis_tvalid_int; + store_3_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_3_axis_tvalid_next = output_3_axis_tvalid_int; + store_3_axis_int_to_temp = 1'b1; + end + end else if (output_3_axis_tready) begin + // input is not ready, but output is ready + output_3_axis_tvalid_next = temp_3_axis_tvalid_reg; + temp_3_axis_tvalid_next = 1'b0; + store_3_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_3_axis_tvalid_reg <= 1'b0; + output_3_axis_tready_int_reg <= 1'b0; + temp_3_axis_tvalid_reg <= 1'b0; + end else begin + output_3_axis_tvalid_reg <= output_3_axis_tvalid_next; + output_3_axis_tready_int_reg <= output_3_axis_tready_int_early; + temp_3_axis_tvalid_reg <= temp_3_axis_tvalid_next; + end + + // datapath + if (store_3_axis_int_to_output) begin + output_3_axis_tdata_reg <= output_3_axis_tdata_int; + output_3_axis_tkeep_reg <= output_3_axis_tkeep_int; + output_3_axis_tlast_reg <= output_3_axis_tlast_int; + output_3_axis_tdest_reg <= output_3_axis_tdest_int; + output_3_axis_tuser_reg <= output_3_axis_tuser_int; + end else if (store_3_axis_temp_to_output) begin + output_3_axis_tdata_reg <= temp_3_axis_tdata_reg; + output_3_axis_tkeep_reg <= temp_3_axis_tkeep_reg; + output_3_axis_tlast_reg <= temp_3_axis_tlast_reg; + output_3_axis_tdest_reg <= temp_3_axis_tdest_reg; + output_3_axis_tuser_reg <= temp_3_axis_tuser_reg; + end + + if (store_3_axis_int_to_temp) begin + temp_3_axis_tdata_reg <= output_3_axis_tdata_int; + temp_3_axis_tkeep_reg <= output_3_axis_tkeep_int; + temp_3_axis_tlast_reg <= output_3_axis_tlast_int; + temp_3_axis_tdest_reg <= output_3_axis_tdest_int; + temp_3_axis_tuser_reg <= output_3_axis_tuser_int; + end +end + +endmodule diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py new file mode 100755 index 000000000..8d2d9dce5 --- /dev/null +++ b/tb/test_axis_switch_4x4.py @@ -0,0 +1,682 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_switch_4x4' +testbench = 'test_axis_switch_4x4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/arbiter.v") +srcs.append("../rtl/priority_encoder.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def dut_axis_switch_4x4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tdest, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tdest, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tdest, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tdest, + input_3_axis_tuser, + + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tready, + output_0_axis_tlast, + output_0_axis_tdest, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tready, + output_1_axis_tlast, + output_1_axis_tdest, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tready, + output_2_axis_tlast, + output_2_axis_tdest, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tready, + output_3_axis_tlast, + output_3_axis_tdest, + output_3_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tdest=input_0_axis_tdest, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tdest=input_1_axis_tdest, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tdest=input_2_axis_tdest, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tdest=input_3_axis_tdest, + input_3_axis_tuser=input_3_axis_tuser, + + output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tready=output_0_axis_tready, + output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tdest=output_0_axis_tdest, + output_0_axis_tuser=output_0_axis_tuser, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tready=output_1_axis_tready, + output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tdest=output_1_axis_tdest, + output_1_axis_tuser=output_1_axis_tuser, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tready=output_2_axis_tready, + output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tdest=output_2_axis_tdest, + output_2_axis_tuser=output_2_axis_tuser, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tready=output_3_axis_tready, + output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tdest=output_3_axis_tdest, + output_3_axis_tuser=output_3_axis_tuser) + +def bench(): + + # Parameters + DATA_WIDTH = 8 + DEST_WIDTH = 3 + OUT_0_BASE = 0 + OUT_0_TOP = 0 + OUT_0_CONNECT = 0xf + OUT_1_BASE = 1 + OUT_1_TOP = 1 + OUT_1_CONNECT = 0xf + OUT_2_BASE = 2 + OUT_2_TOP = 2 + OUT_2_CONNECT = 0xf + OUT_3_BASE = 3 + OUT_3_TOP = 3 + OUT_3_CONNECT = 0xf + ARB_TYPE = "ROUND_ROBIN" + LSB_PRIORITY = "HIGH" + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_0_axis_tvalid = Signal(bool(0)) + input_0_axis_tlast = Signal(bool(0)) + input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_0_axis_tuser = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_1_axis_tvalid = Signal(bool(0)) + input_1_axis_tlast = Signal(bool(0)) + input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_1_axis_tuser = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_2_axis_tvalid = Signal(bool(0)) + input_2_axis_tlast = Signal(bool(0)) + input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_2_axis_tuser = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_3_axis_tvalid = Signal(bool(0)) + input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_3_axis_tuser = Signal(bool(0)) + output_0_axis_tready = Signal(bool(0)) + output_1_axis_tready = Signal(bool(0)) + output_2_axis_tready = Signal(bool(0)) + output_3_axis_tready = Signal(bool(0)) + + # Outputs + input_0_axis_tready = Signal(bool(0)) + input_1_axis_tready = Signal(bool(0)) + input_2_axis_tready = Signal(bool(0)) + input_3_axis_tready = Signal(bool(0)) + output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_0_axis_tvalid = Signal(bool(0)) + output_0_axis_tlast = Signal(bool(0)) + output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_0_axis_tuser = Signal(bool(0)) + output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_1_axis_tvalid = Signal(bool(0)) + output_1_axis_tlast = Signal(bool(0)) + output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_1_axis_tuser = Signal(bool(0)) + output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_2_axis_tvalid = Signal(bool(0)) + output_2_axis_tlast = Signal(bool(0)) + output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_2_axis_tuser = Signal(bool(0)) + output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_3_axis_tvalid = Signal(bool(0)) + output_3_axis_tlast = Signal(bool(0)) + output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_3_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_pause = Signal(bool(0)) + + source_0 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tdest=input_0_axis_tdest, + tuser=input_0_axis_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + source_1 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tdest=input_1_axis_tdest, + tuser=input_1_axis_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + source_2 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tdest=input_2_axis_tdest, + tuser=input_2_axis_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + source_3 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tdest=input_3_axis_tdest, + tuser=input_3_axis_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink_0 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_0_axis_tdata, + tvalid=output_0_axis_tvalid, + tready=output_0_axis_tready, + tlast=output_0_axis_tlast, + tdest=output_0_axis_tdest, + tuser=output_0_axis_tuser, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + sink_1 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_1_axis_tdata, + tvalid=output_1_axis_tvalid, + tready=output_1_axis_tready, + tlast=output_1_axis_tlast, + tdest=output_1_axis_tdest, + tuser=output_1_axis_tuser, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + sink_2 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_2_axis_tdata, + tvalid=output_2_axis_tvalid, + tready=output_2_axis_tready, + tlast=output_2_axis_tlast, + tdest=output_2_axis_tdest, + tuser=output_2_axis_tuser, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + sink_3 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_3_axis_tdata, + tvalid=output_3_axis_tvalid, + tready=output_3_axis_tready, + tlast=output_3_axis_tlast, + tdest=output_3_axis_tdest, + tuser=output_3_axis_tuser, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_axis_switch_4x4(clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tdest, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tdest, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tdest, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tdest, + input_3_axis_tuser, + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tready, + output_0_axis_tlast, + output_0_axis_tdest, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tready, + output_1_axis_tlast, + output_1_axis_tdest, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tready, + output_2_axis_tlast, + output_2_axis_tdest, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tready, + output_3_axis_tlast, + output_3_axis_tdest, + output_3_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + sink_0_pause.next = True + sink_1_pause.next = True + sink_2_pause.next = True + sink_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_0_pause.next = False + sink_1_pause.next = False + sink_2_pause.next = False + sink_3_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: 0123 -> 0123") + current_test.next = 1 + + test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) + test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_0_queue.put(test_frame0) + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + yield clk.posedge + + yield wait() + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame1 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame2 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame3 + + yield delay(100) + + yield clk.posedge + print("test 2: 0123 -> 3210") + current_test.next = 2 + + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_0_queue.put(test_frame0) + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + yield clk.posedge + + yield wait() + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame3 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame2 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame1 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame0 + + yield delay(100) + + yield clk.posedge + print("test 3: 0000 -> 0123") + current_test.next = 3 + + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x00\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x00\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_0_queue.put(test_frame0) + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + source_0_queue.put(test_frame3) + yield clk.posedge + yield clk.posedge + + yield wait() + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame1 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame2 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame3 + + yield delay(100) + + yield clk.posedge + print("test 4: 0123 -> 0000") + current_test.next = 4 + + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_0_queue.put(test_frame0) + yield clk.posedge + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + + yield wait() + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_0_queue.empty(): + rx_frame1 = sink_0_queue.get() + + assert rx_frame1 == test_frame1 + + rx_frame2 = None + if not sink_0_queue.empty(): + rx_frame2 = sink_0_queue.get() + + assert rx_frame2 == test_frame2 + + rx_frame3 = None + if not sink_0_queue.empty(): + rx_frame3 = sink_0_queue.get() + + assert rx_frame3 == test_frame3 + + yield delay(100) + + yield clk.posedge + print("test 1: bad decoding") + current_test.next = 1 + + test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x04\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=4) + test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=5) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_0_queue.put(test_frame0) + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + yield clk.posedge + + yield wait() + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame1 + + yield delay(100) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink_0, sink_1, sink_2, sink_3, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_switch_4x4.v b/tb/test_axis_switch_4x4.v new file mode 100644 index 000000000..0f3fb62b3 --- /dev/null +++ b/tb/test_axis_switch_4x4.v @@ -0,0 +1,240 @@ +/* + +Copyright (c) 2016 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 + +/* + * Testbench for axis_switch_4x4 + */ +module test_axis_switch_4x4; + +// Parameters +parameter DATA_WIDTH = 8; +parameter DEST_WIDTH = 3; +parameter OUT_0_BASE = 0; +parameter OUT_0_TOP = 0; +parameter OUT_0_CONNECT = 4'b1111; +parameter OUT_1_BASE = 1; +parameter OUT_1_TOP = 1; +parameter OUT_1_CONNECT = 4'b1111; +parameter OUT_2_BASE = 2; +parameter OUT_2_TOP = 2; +parameter OUT_2_CONNECT = 4'b1111; +parameter OUT_3_BASE = 3; +parameter OUT_3_TOP = 3; +parameter OUT_3_CONNECT = 4'b1111; +parameter ARB_TYPE = "ROUND_ROBIN"; +parameter LSB_PRIORITY = "HIGH"; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; +reg input_0_axis_tvalid = 0; +reg input_0_axis_tlast = 0; +reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; +reg input_0_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; +reg input_1_axis_tvalid = 0; +reg input_1_axis_tlast = 0; +reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; +reg input_1_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; +reg input_2_axis_tvalid = 0; +reg input_2_axis_tlast = 0; +reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; +reg input_2_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; +reg input_3_axis_tvalid = 0; +reg input_3_axis_tlast = 0; +reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; +reg input_3_axis_tuser = 0; +reg output_0_axis_tready = 0; +reg output_1_axis_tready = 0; +reg output_2_axis_tready = 0; +reg output_3_axis_tready = 0; + +// Outputs +wire input_0_axis_tready; +wire input_1_axis_tready; +wire input_2_axis_tready; +wire input_3_axis_tready; +wire [DATA_WIDTH-1:0] output_0_axis_tdata; +wire output_0_axis_tvalid; +wire output_0_axis_tlast; +wire [DEST_WIDTH-1:0] output_0_axis_tdest; +wire output_0_axis_tuser; +wire [DATA_WIDTH-1:0] output_1_axis_tdata; +wire output_1_axis_tvalid; +wire output_1_axis_tlast; +wire [DEST_WIDTH-1:0] output_1_axis_tdest; +wire output_1_axis_tuser; +wire [DATA_WIDTH-1:0] output_2_axis_tdata; +wire output_2_axis_tvalid; +wire output_2_axis_tlast; +wire [DEST_WIDTH-1:0] output_2_axis_tdest; +wire output_2_axis_tuser; +wire [DATA_WIDTH-1:0] output_3_axis_tdata; +wire output_3_axis_tvalid; +wire output_3_axis_tlast; +wire [DEST_WIDTH-1:0] output_3_axis_tdest; +wire output_3_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tdest, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tdest, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tdest, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tdest, + input_3_axis_tuser, + output_0_axis_tready, + output_1_axis_tready, + output_2_axis_tready, + output_3_axis_tready); + $to_myhdl(input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tlast, + output_0_axis_tdest, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tlast, + output_1_axis_tdest, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tlast, + output_2_axis_tdest, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tlast, + output_3_axis_tdest, + output_3_axis_tuser); + + // dump file + $dumpfile("test_axis_switch_4x4.lxt"); + $dumpvars(0, test_axis_switch_4x4); +end + +axis_switch_4x4 #( + .DATA_WIDTH(DATA_WIDTH), + .DEST_WIDTH(DEST_WIDTH), + .OUT_0_BASE(OUT_0_BASE), + .OUT_0_TOP(OUT_0_TOP), + .OUT_0_CONNECT(OUT_0_CONNECT), + .OUT_1_BASE(OUT_1_BASE), + .OUT_1_TOP(OUT_1_TOP), + .OUT_1_CONNECT(OUT_1_CONNECT), + .OUT_2_BASE(OUT_2_BASE), + .OUT_2_TOP(OUT_2_TOP), + .OUT_2_CONNECT(OUT_2_CONNECT), + .OUT_3_BASE(OUT_3_BASE), + .OUT_3_TOP(OUT_3_TOP), + .OUT_3_CONNECT(OUT_3_CONNECT), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI inputs + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tvalid(input_0_axis_tvalid), + .input_0_axis_tready(input_0_axis_tready), + .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tdest(input_0_axis_tdest), + .input_0_axis_tuser(input_0_axis_tuser), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tvalid(input_1_axis_tvalid), + .input_1_axis_tready(input_1_axis_tready), + .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tdest(input_1_axis_tdest), + .input_1_axis_tuser(input_1_axis_tuser), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tvalid(input_2_axis_tvalid), + .input_2_axis_tready(input_2_axis_tready), + .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tdest(input_2_axis_tdest), + .input_2_axis_tuser(input_2_axis_tuser), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tvalid(input_3_axis_tvalid), + .input_3_axis_tready(input_3_axis_tready), + .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tdest(input_3_axis_tdest), + .input_3_axis_tuser(input_3_axis_tuser), + // AXI outputs + .output_0_axis_tdata(output_0_axis_tdata), + .output_0_axis_tvalid(output_0_axis_tvalid), + .output_0_axis_tready(output_0_axis_tready), + .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tdest(output_0_axis_tdest), + .output_0_axis_tuser(output_0_axis_tuser), + .output_1_axis_tdata(output_1_axis_tdata), + .output_1_axis_tvalid(output_1_axis_tvalid), + .output_1_axis_tready(output_1_axis_tready), + .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tdest(output_1_axis_tdest), + .output_1_axis_tuser(output_1_axis_tuser), + .output_2_axis_tdata(output_2_axis_tdata), + .output_2_axis_tvalid(output_2_axis_tvalid), + .output_2_axis_tready(output_2_axis_tready), + .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tdest(output_2_axis_tdest), + .output_2_axis_tuser(output_2_axis_tuser), + .output_3_axis_tdata(output_3_axis_tdata), + .output_3_axis_tvalid(output_3_axis_tvalid), + .output_3_axis_tready(output_3_axis_tready), + .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tdest(output_3_axis_tdest), + .output_3_axis_tuser(output_3_axis_tuser) +); + +endmodule diff --git a/tb/test_axis_switch_64_4x4.py b/tb/test_axis_switch_64_4x4.py new file mode 100755 index 000000000..bde87e440 --- /dev/null +++ b/tb/test_axis_switch_64_4x4.py @@ -0,0 +1,723 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_switch_64_4x4' +testbench = 'test_axis_switch_64_4x4' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/arbiter.v") +srcs.append("../rtl/priority_encoder.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def dut_axis_switch_64_4x4(clk, + rst, + current_test, + + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tdest, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tdest, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tdest, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tdest, + input_3_axis_tuser, + + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tready, + output_0_axis_tlast, + output_0_axis_tdest, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tready, + output_1_axis_tlast, + output_1_axis_tdest, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tready, + output_2_axis_tlast, + output_2_axis_tdest, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tready, + output_3_axis_tlast, + output_3_axis_tdest, + output_3_axis_tuser): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tdest=input_0_axis_tdest, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tdest=input_1_axis_tdest, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tdest=input_2_axis_tdest, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tdest=input_3_axis_tdest, + input_3_axis_tuser=input_3_axis_tuser, + + output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tkeep=output_0_axis_tkeep, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tready=output_0_axis_tready, + output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tdest=output_0_axis_tdest, + output_0_axis_tuser=output_0_axis_tuser, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tkeep=output_1_axis_tkeep, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tready=output_1_axis_tready, + output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tdest=output_1_axis_tdest, + output_1_axis_tuser=output_1_axis_tuser, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tkeep=output_2_axis_tkeep, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tready=output_2_axis_tready, + output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tdest=output_2_axis_tdest, + output_2_axis_tuser=output_2_axis_tuser, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tkeep=output_3_axis_tkeep, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tready=output_3_axis_tready, + output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tdest=output_3_axis_tdest, + output_3_axis_tuser=output_3_axis_tuser) + +def bench(): + + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = int(DATA_WIDTH/8) + DEST_WIDTH = 3 + OUT_0_BASE = 0 + OUT_0_TOP = 0 + OUT_0_CONNECT = 0xf + OUT_1_BASE = 1 + OUT_1_TOP = 1 + OUT_1_CONNECT = 0xf + OUT_2_BASE = 2 + OUT_2_TOP = 2 + OUT_2_CONNECT = 0xf + OUT_3_BASE = 3 + OUT_3_TOP = 3 + OUT_3_CONNECT = 0xf + ARB_TYPE = "ROUND_ROBIN" + LSB_PRIORITY = "HIGH" + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_0_axis_tvalid = Signal(bool(0)) + input_0_axis_tlast = Signal(bool(0)) + input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_0_axis_tuser = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_1_axis_tvalid = Signal(bool(0)) + input_1_axis_tlast = Signal(bool(0)) + input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_1_axis_tuser = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_2_axis_tvalid = Signal(bool(0)) + input_2_axis_tlast = Signal(bool(0)) + input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_2_axis_tuser = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_3_axis_tvalid = Signal(bool(0)) + input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_3_axis_tuser = Signal(bool(0)) + output_0_axis_tready = Signal(bool(0)) + output_1_axis_tready = Signal(bool(0)) + output_2_axis_tready = Signal(bool(0)) + output_3_axis_tready = Signal(bool(0)) + + # Outputs + input_0_axis_tready = Signal(bool(0)) + input_1_axis_tready = Signal(bool(0)) + input_2_axis_tready = Signal(bool(0)) + input_3_axis_tready = Signal(bool(0)) + output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_0_axis_tvalid = Signal(bool(0)) + output_0_axis_tlast = Signal(bool(0)) + output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_0_axis_tuser = Signal(bool(0)) + output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_1_axis_tvalid = Signal(bool(0)) + output_1_axis_tlast = Signal(bool(0)) + output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_1_axis_tuser = Signal(bool(0)) + output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_2_axis_tvalid = Signal(bool(0)) + output_2_axis_tlast = Signal(bool(0)) + output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_2_axis_tuser = Signal(bool(0)) + output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_3_axis_tvalid = Signal(bool(0)) + output_3_axis_tlast = Signal(bool(0)) + output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_3_axis_tuser = Signal(bool(0)) + + # sources and sinks + source_0_queue = Queue() + source_0_pause = Signal(bool(0)) + source_1_queue = Queue() + source_1_pause = Signal(bool(0)) + source_2_queue = Queue() + source_2_pause = Signal(bool(0)) + source_3_queue = Queue() + source_3_pause = Signal(bool(0)) + sink_0_queue = Queue() + sink_0_pause = Signal(bool(0)) + sink_1_queue = Queue() + sink_1_pause = Signal(bool(0)) + sink_2_queue = Queue() + sink_2_pause = Signal(bool(0)) + sink_3_queue = Queue() + sink_3_pause = Signal(bool(0)) + + source_0 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tdest=input_0_axis_tdest, + tuser=input_0_axis_tuser, + fifo=source_0_queue, + pause=source_0_pause, + name='source0') + source_1 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tdest=input_1_axis_tdest, + tuser=input_1_axis_tuser, + fifo=source_1_queue, + pause=source_1_pause, + name='source1') + source_2 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tdest=input_2_axis_tdest, + tuser=input_2_axis_tuser, + fifo=source_2_queue, + pause=source_2_pause, + name='source2') + source_3 = axis_ep.AXIStreamSource(clk, + rst, + tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tdest=input_3_axis_tdest, + tuser=input_3_axis_tuser, + fifo=source_3_queue, + pause=source_3_pause, + name='source3') + + sink_0 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_0_axis_tdata, + tkeep=output_0_axis_tkeep, + tvalid=output_0_axis_tvalid, + tready=output_0_axis_tready, + tlast=output_0_axis_tlast, + tdest=output_0_axis_tdest, + tuser=output_0_axis_tuser, + fifo=sink_0_queue, + pause=sink_0_pause, + name='sink0') + sink_1 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_1_axis_tdata, + tkeep=output_1_axis_tkeep, + tvalid=output_1_axis_tvalid, + tready=output_1_axis_tready, + tlast=output_1_axis_tlast, + tdest=output_1_axis_tdest, + tuser=output_1_axis_tuser, + fifo=sink_1_queue, + pause=sink_1_pause, + name='sink1') + sink_2 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_2_axis_tdata, + tkeep=output_2_axis_tkeep, + tvalid=output_2_axis_tvalid, + tready=output_2_axis_tready, + tlast=output_2_axis_tlast, + tdest=output_2_axis_tdest, + tuser=output_2_axis_tuser, + fifo=sink_2_queue, + pause=sink_2_pause, + name='sink2') + sink_3 = axis_ep.AXIStreamSink(clk, + rst, + tdata=output_3_axis_tdata, + tkeep=output_3_axis_tkeep, + tvalid=output_3_axis_tvalid, + tready=output_3_axis_tready, + tlast=output_3_axis_tlast, + tdest=output_3_axis_tdest, + tuser=output_3_axis_tuser, + fifo=sink_3_queue, + pause=sink_3_pause, + name='sink3') + + # DUT + dut = dut_axis_switch_64_4x4(clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tready, + input_0_axis_tlast, + input_0_axis_tdest, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tready, + input_1_axis_tlast, + input_1_axis_tdest, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tready, + input_2_axis_tlast, + input_2_axis_tdest, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tready, + input_3_axis_tlast, + input_3_axis_tdest, + input_3_axis_tuser, + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tready, + output_0_axis_tlast, + output_0_axis_tdest, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tready, + output_1_axis_tlast, + output_1_axis_tdest, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tready, + output_2_axis_tlast, + output_2_axis_tdest, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tready, + output_3_axis_tlast, + output_3_axis_tdest, + output_3_axis_tuser) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + source_0_pause.next = True + source_1_pause.next = True + source_2_pause.next = True + source_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_0_pause.next = False + source_1_pause.next = False + source_2_pause.next = False + source_3_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + sink_0_pause.next = True + sink_1_pause.next = True + sink_2_pause.next = True + sink_3_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_0_pause.next = False + sink_1_pause.next = False + sink_2_pause.next = False + sink_3_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: 0123 -> 0123") + current_test.next = 1 + + test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) + test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_0_queue.put(test_frame0) + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + yield clk.posedge + + yield wait() + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame1 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame2 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame3 + + yield delay(100) + + yield clk.posedge + print("test 2: 0123 -> 3210") + current_test.next = 2 + + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_0_queue.put(test_frame0) + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + yield clk.posedge + + yield wait() + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame3 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame2 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame1 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame0 + + yield delay(100) + + yield clk.posedge + print("test 3: 0000 -> 0123") + current_test.next = 3 + + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x00\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x00\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_0_queue.put(test_frame0) + source_0_queue.put(test_frame1) + source_0_queue.put(test_frame2) + source_0_queue.put(test_frame3) + yield clk.posedge + yield clk.posedge + + yield wait() + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame1 + + rx_frame2 = None + if not sink_2_queue.empty(): + rx_frame2 = sink_2_queue.get() + + assert rx_frame2 == test_frame2 + + rx_frame3 = None + if not sink_3_queue.empty(): + rx_frame3 = sink_3_queue.get() + + assert rx_frame3 == test_frame3 + + yield delay(100) + + yield clk.posedge + print("test 4: 0123 -> 0000") + current_test.next = 4 + + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_0_queue.put(test_frame0) + yield clk.posedge + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + + yield wait() + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_0_queue.empty(): + rx_frame1 = sink_0_queue.get() + + assert rx_frame1 == test_frame1 + + rx_frame2 = None + if not sink_0_queue.empty(): + rx_frame2 = sink_0_queue.get() + + assert rx_frame2 == test_frame2 + + rx_frame3 = None + if not sink_0_queue.empty(): + rx_frame3 = sink_0_queue.get() + + assert rx_frame3 == test_frame3 + + yield delay(100) + + yield clk.posedge + print("test 1: bad decoding") + current_test.next = 1 + + test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x04\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=4) + test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=5) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_0_queue.put(test_frame0) + source_1_queue.put(test_frame1) + source_2_queue.put(test_frame2) + source_3_queue.put(test_frame3) + yield clk.posedge + yield clk.posedge + + yield wait() + yield clk.posedge + yield clk.posedge + + rx_frame0 = None + if not sink_0_queue.empty(): + rx_frame0 = sink_0_queue.get() + + assert rx_frame0 == test_frame0 + + rx_frame1 = None + if not sink_1_queue.empty(): + rx_frame1 = sink_1_queue.get() + + assert rx_frame1 == test_frame1 + + yield delay(100) + + raise StopSimulation + + return dut, source_0, source_1, source_2, source_3, sink_0, sink_1, sink_2, sink_3, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_switch_64_4x4.v b/tb/test_axis_switch_64_4x4.v new file mode 100644 index 000000000..e5f939f89 --- /dev/null +++ b/tb/test_axis_switch_64_4x4.v @@ -0,0 +1,266 @@ +/* + +Copyright (c) 2016 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 + +/* + * Testbench for axis_switch_64_4x4 + */ +module test_axis_switch_64_4x4; + +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter DEST_WIDTH = 3; +parameter OUT_0_BASE = 0; +parameter OUT_0_TOP = 0; +parameter OUT_0_CONNECT = 4'b1111; +parameter OUT_1_BASE = 1; +parameter OUT_1_TOP = 1; +parameter OUT_1_CONNECT = 4'b1111; +parameter OUT_2_BASE = 2; +parameter OUT_2_TOP = 2; +parameter OUT_2_CONNECT = 4'b1111; +parameter OUT_3_BASE = 3; +parameter OUT_3_TOP = 3; +parameter OUT_3_CONNECT = 4'b1111; +parameter ARB_TYPE = "ROUND_ROBIN"; +parameter LSB_PRIORITY = "HIGH"; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; +reg input_0_axis_tvalid = 0; +reg input_0_axis_tlast = 0; +reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; +reg input_0_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; +reg input_1_axis_tvalid = 0; +reg input_1_axis_tlast = 0; +reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; +reg input_1_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; +reg input_2_axis_tvalid = 0; +reg input_2_axis_tlast = 0; +reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; +reg input_2_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; +reg input_3_axis_tvalid = 0; +reg input_3_axis_tlast = 0; +reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; +reg input_3_axis_tuser = 0; +reg output_0_axis_tready = 0; +reg output_1_axis_tready = 0; +reg output_2_axis_tready = 0; +reg output_3_axis_tready = 0; + +// Outputs +wire input_0_axis_tready; +wire input_1_axis_tready; +wire input_2_axis_tready; +wire input_3_axis_tready; +wire [DATA_WIDTH-1:0] output_0_axis_tdata; +wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; +wire output_0_axis_tvalid; +wire output_0_axis_tlast; +wire [DEST_WIDTH-1:0] output_0_axis_tdest; +wire output_0_axis_tuser; +wire [DATA_WIDTH-1:0] output_1_axis_tdata; +wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; +wire output_1_axis_tvalid; +wire output_1_axis_tlast; +wire [DEST_WIDTH-1:0] output_1_axis_tdest; +wire output_1_axis_tuser; +wire [DATA_WIDTH-1:0] output_2_axis_tdata; +wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; +wire output_2_axis_tvalid; +wire output_2_axis_tlast; +wire [DEST_WIDTH-1:0] output_2_axis_tdest; +wire output_2_axis_tuser; +wire [DATA_WIDTH-1:0] output_3_axis_tdata; +wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; +wire output_3_axis_tvalid; +wire output_3_axis_tlast; +wire [DEST_WIDTH-1:0] output_3_axis_tdest; +wire output_3_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tdest, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tdest, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tdest, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tdest, + input_3_axis_tuser, + output_0_axis_tready, + output_1_axis_tready, + output_2_axis_tready, + output_3_axis_tready); + $to_myhdl(input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tlast, + output_0_axis_tdest, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tlast, + output_1_axis_tdest, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tlast, + output_2_axis_tdest, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tlast, + output_3_axis_tdest, + output_3_axis_tuser); + + // dump file + $dumpfile("test_axis_switch_64_4x4.lxt"); + $dumpvars(0, test_axis_switch_64_4x4); +end + +axis_switch_64_4x4 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .DEST_WIDTH(DEST_WIDTH), + .OUT_0_BASE(OUT_0_BASE), + .OUT_0_TOP(OUT_0_TOP), + .OUT_0_CONNECT(OUT_0_CONNECT), + .OUT_1_BASE(OUT_1_BASE), + .OUT_1_TOP(OUT_1_TOP), + .OUT_1_CONNECT(OUT_1_CONNECT), + .OUT_2_BASE(OUT_2_BASE), + .OUT_2_TOP(OUT_2_TOP), + .OUT_2_CONNECT(OUT_2_CONNECT), + .OUT_3_BASE(OUT_3_BASE), + .OUT_3_TOP(OUT_3_TOP), + .OUT_3_CONNECT(OUT_3_CONNECT), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI inputs + .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tkeep(input_0_axis_tkeep), + .input_0_axis_tvalid(input_0_axis_tvalid), + .input_0_axis_tready(input_0_axis_tready), + .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tdest(input_0_axis_tdest), + .input_0_axis_tuser(input_0_axis_tuser), + .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tkeep(input_1_axis_tkeep), + .input_1_axis_tvalid(input_1_axis_tvalid), + .input_1_axis_tready(input_1_axis_tready), + .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tdest(input_1_axis_tdest), + .input_1_axis_tuser(input_1_axis_tuser), + .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tkeep(input_2_axis_tkeep), + .input_2_axis_tvalid(input_2_axis_tvalid), + .input_2_axis_tready(input_2_axis_tready), + .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tdest(input_2_axis_tdest), + .input_2_axis_tuser(input_2_axis_tuser), + .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tkeep(input_3_axis_tkeep), + .input_3_axis_tvalid(input_3_axis_tvalid), + .input_3_axis_tready(input_3_axis_tready), + .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tdest(input_3_axis_tdest), + .input_3_axis_tuser(input_3_axis_tuser), + // AXI outputs + .output_0_axis_tdata(output_0_axis_tdata), + .output_0_axis_tkeep(output_0_axis_tkeep), + .output_0_axis_tvalid(output_0_axis_tvalid), + .output_0_axis_tready(output_0_axis_tready), + .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tdest(output_0_axis_tdest), + .output_0_axis_tuser(output_0_axis_tuser), + .output_1_axis_tdata(output_1_axis_tdata), + .output_1_axis_tkeep(output_1_axis_tkeep), + .output_1_axis_tvalid(output_1_axis_tvalid), + .output_1_axis_tready(output_1_axis_tready), + .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tdest(output_1_axis_tdest), + .output_1_axis_tuser(output_1_axis_tuser), + .output_2_axis_tdata(output_2_axis_tdata), + .output_2_axis_tkeep(output_2_axis_tkeep), + .output_2_axis_tvalid(output_2_axis_tvalid), + .output_2_axis_tready(output_2_axis_tready), + .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tdest(output_2_axis_tdest), + .output_2_axis_tuser(output_2_axis_tuser), + .output_3_axis_tdata(output_3_axis_tdata), + .output_3_axis_tkeep(output_3_axis_tkeep), + .output_3_axis_tvalid(output_3_axis_tvalid), + .output_3_axis_tready(output_3_axis_tready), + .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tdest(output_3_axis_tdest), + .output_3_axis_tuser(output_3_axis_tuser) +); + +endmodule From c27e74c7d47ff52de81d34b352550209859506dc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 25 Jul 2016 13:15:59 -0700 Subject: [PATCH 296/617] Update readme --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index bc5d16d83..8dda8fb13 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,18 @@ AXI stream interface. Trigger signal used to reset and dump counts out of AXI interface, along with tag value. Use with axis_frame_join_N to form a single monolithic frame from multiple monitored points with the same trigger. +### axis_switch_NxN module + +Frame-aware AXI stream switch with parametrizable data width. + +Can be generated with arbitrary port counts with axis_switch.py. + +### axis_switch_64_NxN module + +Frame-aware AXI stream switch with tkeep signal and parametrizable data width. + +Can be generated with arbitrary port counts with axis_mux_64.py. + ### axis_tap module AXI stream tap module. Used to make a copy of an AXI stream bus without @@ -276,6 +288,10 @@ Parametrizable priority encoder. axis_srl_fifo_64.v : SRL-based FIFO (64 bit) axis_srl_register.v : SRL-based register axis_srl_register_64.v : SRL-based register (64 bit) + axis_switch.py : AXI stream switch generator + axis_switch_4x4.v : 4x4 port AXI stream switch + axis_switch_64.py : AXI stream switch generator (64 bit) + axis_switch_64_4x4.v : 4x4 port AXI stream switch (64 bit) axis_stat_counter.v : Statistics counter axis_tap.v : AXI stream tap axis_tap_64.v : AXI stream tap (64 bit) From 795ae8a4dbd4aaf00891995f4d12ad974323423a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 26 Jul 2016 14:14:16 -0400 Subject: [PATCH 297/617] Add 10G example design for VCU108 board --- example/VCU108/fpga_10g/Makefile | 25 + example/VCU108/fpga_10g/README.md | 33 + example/VCU108/fpga_10g/clock.xdc | 4 + example/VCU108/fpga_10g/common/vivado.mk | 118 +++ example/VCU108/fpga_10g/eth.xdc | 4 + example/VCU108/fpga_10g/fpga.xdc | 112 +++ example/VCU108/fpga_10g/fpga/Makefile | 70 ++ .../fpga_10g/ip/gig_ethernet_pcs_pma_0.xci | 126 +++ .../fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci | 81 ++ example/VCU108/fpga_10g/lib/eth | 1 + example/VCU108/fpga_10g/rtl/debounce_switch.v | 89 ++ example/VCU108/fpga_10g/rtl/fpga.v | 525 +++++++++++ example/VCU108/fpga_10g/rtl/fpga_core.v | 855 ++++++++++++++++++ example/VCU108/fpga_10g/rtl/sync_reset.v | 52 ++ example/VCU108/fpga_10g/rtl/sync_signal.v | 58 ++ example/VCU108/fpga_10g/tb/arp_ep.py | 1 + example/VCU108/fpga_10g/tb/axis_ep.py | 1 + example/VCU108/fpga_10g/tb/eth_ep.py | 1 + example/VCU108/fpga_10g/tb/gmii_ep.py | 1 + example/VCU108/fpga_10g/tb/ip_ep.py | 1 + example/VCU108/fpga_10g/tb/test_fpga_core.py | 635 +++++++++++++ example/VCU108/fpga_10g/tb/test_fpga_core.v | 173 ++++ example/VCU108/fpga_10g/tb/udp_ep.py | 1 + example/VCU108/fpga_10g/tb/xgmii_ep.py | 1 + 24 files changed, 2968 insertions(+) create mode 100644 example/VCU108/fpga_10g/Makefile create mode 100644 example/VCU108/fpga_10g/README.md create mode 100644 example/VCU108/fpga_10g/clock.xdc create mode 100644 example/VCU108/fpga_10g/common/vivado.mk create mode 100644 example/VCU108/fpga_10g/eth.xdc create mode 100644 example/VCU108/fpga_10g/fpga.xdc create mode 100644 example/VCU108/fpga_10g/fpga/Makefile create mode 100644 example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci create mode 100644 example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci create mode 120000 example/VCU108/fpga_10g/lib/eth create mode 100644 example/VCU108/fpga_10g/rtl/debounce_switch.v create mode 100644 example/VCU108/fpga_10g/rtl/fpga.v create mode 100644 example/VCU108/fpga_10g/rtl/fpga_core.v create mode 100644 example/VCU108/fpga_10g/rtl/sync_reset.v create mode 100644 example/VCU108/fpga_10g/rtl/sync_signal.v create mode 120000 example/VCU108/fpga_10g/tb/arp_ep.py create mode 120000 example/VCU108/fpga_10g/tb/axis_ep.py create mode 120000 example/VCU108/fpga_10g/tb/eth_ep.py create mode 120000 example/VCU108/fpga_10g/tb/gmii_ep.py create mode 120000 example/VCU108/fpga_10g/tb/ip_ep.py create mode 100755 example/VCU108/fpga_10g/tb/test_fpga_core.py create mode 100644 example/VCU108/fpga_10g/tb/test_fpga_core.v create mode 120000 example/VCU108/fpga_10g/tb/udp_ep.py create mode 120000 example/VCU108/fpga_10g/tb/xgmii_ep.py diff --git a/example/VCU108/fpga_10g/Makefile b/example/VCU108/fpga_10g/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/VCU108/fpga_10g/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/VCU108/fpga_10g/README.md b/example/VCU108/fpga_10g/README.md new file mode 100644 index 000000000..fc508c331 --- /dev/null +++ b/example/VCU108/fpga_10g/README.md @@ -0,0 +1,33 @@ +# Verilog Ethernet VCU108 Example Design + +## Introduction + +This example design targets the Xilinx VCU108 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. The design also enables the gigabit Ethernet interface for +testing with a QSFP loopback adapter. + +FPGA: xcvu095-ffva2104-2-e +PHY: 10G BASE-R PHY IP core and internal GTY transceiver + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the VCU108 board with Vivado. Then run +netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any text +entered into netcat will be echoed back after pressing enter. + +Note that the gigabit PHY is also enabled for debugging. The gigabit port can +be inserted into the 10G data path between the 10G MAC and 10G PHY so that the +10G interface can be tested with a QSFP loopback adapter. Turn on SW12.1 to +insert the gigabit port into the 10G data path, or off to bypass the gigabit +port. Turn on SW12.2 to place the port in the TX path or off to place the +port in the RX path. + + diff --git a/example/VCU108/fpga_10g/clock.xdc b/example/VCU108/fpga_10g/clock.xdc new file mode 100644 index 000000000..bf52c8f3b --- /dev/null +++ b/example/VCU108/fpga_10g/clock.xdc @@ -0,0 +1,4 @@ +# Clock constraints + +# internal clock groups +set_clock_groups -asynchronous -group [get_clocks -of_objects [get_nets clk_156mhz_int]] diff --git a/example/VCU108/fpga_10g/common/vivado.mk b/example/VCU108/fpga_10g/common/vivado.mk new file mode 100644 index 000000000..a54b530f6 --- /dev/null +++ b/example/VCU108/fpga_10g/common/vivado.mk @@ -0,0 +1,118 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile $(XCI_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/VCU108/fpga_10g/eth.xdc b/example/VCU108/fpga_10g/eth.xdc new file mode 100644 index 000000000..35dd05b08 --- /dev/null +++ b/example/VCU108/fpga_10g/eth.xdc @@ -0,0 +1,4 @@ +# Ethernet constraints + +set_property LOC BITSLICE_RX_TX_X1Y35 [get_cells -hier -filter {name =~ */lvds_transceiver_mw/serdes_1_to_10_ser8_i/idelay_cal}] +#set_false_path -to [get_pins -hier -filter {name =~ *idelayctrl_inst/RST} -include_replicated_objects ] diff --git a/example/VCU108/fpga_10g/fpga.xdc b/example/VCU108/fpga_10g/fpga.xdc new file mode 100644 index 000000000..e05b6bf60 --- /dev/null +++ b/example/VCU108/fpga_10g/fpga.xdc @@ -0,0 +1,112 @@ +# XDC constraints for the Xilinx VCU108 board +# part: xcvu095-ffva2104-2-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] + +# System clocks +# 300 MHz +#set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p] +#set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n] +#create_clock -period 3.333 -name clk_300_mhz_1 [get_ports clk_300mhz_1_p] +#set_clock_groups -asynchronous -group clk_300mhz_1 + +#set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p] +#set_property -dict {LOC G21 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_n] +#create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p] +#set_clock_groups -asynchronous -group clk_300mhz_2 + +# 125 MHz +set_property -dict {LOC BC9 IOSTANDARD LVDS} [get_ports clk_125mhz_p] +set_property -dict {LOC BC8 IOSTANDARD LVDS} [get_ports clk_125mhz_n] +create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] +set_clock_groups -asynchronous -group clk_125mhz + +# 90 MHz +#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] +#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] +#set_clock_groups -asynchronous -group clk_90mhz + +# LEDs +set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] +set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}] +set_property -dict {LOC AY30 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}] +set_property -dict {LOC BB32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[3]}] +set_property -dict {LOC BF32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[4]}] +set_property -dict {LOC AV36 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[5]}] +set_property -dict {LOC AY35 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[6]}] +set_property -dict {LOC BA37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[7]}] + +# Reset button +set_property -dict {LOC E36 IOSTANDARD LVCMOS12} [get_ports reset] + +# Push buttons +set_property -dict {LOC E34 IOSTANDARD LVCMOS12} [get_ports btnu] +set_property -dict {LOC M22 IOSTANDARD LVCMOS12} [get_ports btnl] +set_property -dict {LOC D9 IOSTANDARD LVCMOS12} [get_ports btnd] +set_property -dict {LOC A10 IOSTANDARD LVCMOS12} [get_ports btnr] +set_property -dict {LOC AW27 IOSTANDARD LVCMOS12} [get_ports btnc] + +# DIP switches +set_property -dict {LOC BC40 IOSTANDARD LVCMOS12} [get_ports {sw[0]}] +set_property -dict {LOC L19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}] +set_property -dict {LOC C37 IOSTANDARD LVCMOS12} [get_ports {sw[2]}] +set_property -dict {LOC C38 IOSTANDARD LVCMOS12} [get_ports {sw[3]}] + +# UART +set_property -dict {LOC BE24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] +set_property -dict {LOC BC24 IOSTANDARD LVCMOS18} [get_ports uart_rxd] +set_property -dict {LOC BF24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_rts] +set_property -dict {LOC BD22 IOSTANDARD LVCMOS18} [get_ports uart_cts] + +# Gigabit Ethernet SGMII PHY +set_property -dict {LOC AR24 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_rx_p] +set_property -dict {LOC AT24 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_rx_n] +set_property -dict {LOC AR23 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_tx_p] +set_property -dict {LOC AR22 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_tx_n] +set_property -dict {LOC AT22 IOSTANDARD LVDS_25} [get_ports phy_sgmii_clk_p] +set_property -dict {LOC AU22 IOSTANDARD LVDS_25} [get_ports phy_sgmii_clk_n] +set_property -dict {LOC AU21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_reset_n] +set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports phy_int_n] +#set_property -dict {LOC AV24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdio] +#set_property -dict {LOC AV21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc] + +# 625 MHz ref clock from SGMII PHY +create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] +set_clock_groups -asynchronous -group phy_sgmii_clk + +# QSFP+ Interface +set_property -dict {LOC AG45} [get_ports qsfp_rx1_p] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AG46} [get_ports qsfp_rx1_n] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AF43} [get_ports qsfp_rx2_p] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AF44} [get_ports qsfp_rx2_n] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AE45} [get_ports qsfp_rx3_p] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AE46} [get_ports qsfp_rx3_n] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AD43} [get_ports qsfp_rx4_p] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AD44} [get_ports qsfp_rx4_n] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC AK42} [get_ports qsfp_tx1_p] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AK43} [get_ports qsfp_tx1_n] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AJ40} [get_ports qsfp_tx2_p] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AJ41} [get_ports qsfp_tx2_n] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AG41} [get_ports qsfp_tx3_p] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AG40} [get_ports qsfp_tx3_n] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AE40} [get_ports qsfp_tx4_p] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AE41} [get_ports qsfp_tx4_n] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC AF38} [get_ports qsfp_mgt_refclk_0_p] ;# MGTREFCLK0P_127 from U32 SI570 via U102 SI53340 +set_property -dict {LOC AF39} [get_ports qsfp_mgt_refclk_0_n] ;# MGTREFCLK0N_127 from U32 SI570 via U102 SI53340 +#set_property -dict {LOC AD38} [get_ports qsfp_mgt_refclk_1_p] ;# MGTREFCLK1P_127 from U57 CKOUT2 SI5328 +#set_property -dict {LOC AD39} [get_ports qsfp_mgt_refclk_1_n] ;# MGTREFCLK1N_127 from U57 CKOUT2 SI5328 +#set_property -dict {LOC AG34 IOSTANDARD LVDS} [get_ports qsfp_recclk_p] ;# to U57 CKIN1 SI5328 +#set_property -dict {LOC AH35 IOSTANDARD LVDS} [get_ports qsfp_recclk_n] ;# to U57 CKIN1 SI5328 +#set_property -dict {LOC AL24 IOSTANDARD LVCMOS18} [get_ports qsfp_modesell] +#set_property -dict {LOC AM24 IOSTANDARD LVCMOS18} [get_ports qsfp_resetl] +#set_property -dict {LOC AL25 IOSTANDARD LVCMOS18} [get_ports qsfp_modpresl] +#set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp_intl] +#set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp_lpmode] + +# I2C interface +#set_property -dict {LOC AN21 IOSTANDARD LVCMOS18} [get_ports i2c_scl] +#set_property -dict {LOC AP21 IOSTANDARD LVCMOS18} [get_ports i2c_sda] + + diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile new file mode 100644 index 000000000..70fe2f090 --- /dev/null +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -0,0 +1,70 @@ + +# FPGA settings +FPGA_PART = xcvu095-ffva2104-2-e +FPGA_TOP = fpga +FPGA_ARCH = VirtexUltrascale + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_64_2.v +SYN_FILES += lib/eth/rtl/ip_mux_64_2.v +SYN_FILES += lib/eth/rtl/arp_64.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v +SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_64_2.v +SYN_FILES += lib/eth/rtl/eth_mux_64_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_adapter.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo_64.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_switch_64_4x4.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += clock.xdc +XDC_FILES += eth.xdc + +# IP +XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci +XCI_FILES += ip/ten_gig_eth_pcs_pma_0.xci + +include ../common/vivado.mk + +program: #$(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl + echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "exit" >> program.tcl + vivado -mode batch -source program.tcl + diff --git a/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci new file mode 100644 index 000000000..0b780494e --- /dev/null +++ b/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci @@ -0,0 +1,126 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gig_ethernet_pcs_pma_0 + + + true + 1 + 0 + 0 + DIFF_PAIR_0 + DIFF_PAIR_1 + false + DIFF_PAIR_0 + DIFF_PAIR_1 + virtexu + gig_ethernet_pcs_pma_0 + 50.0 + false + . + false + virtexu + 17 + 9 + 7 + 4 + GTH + false + true + false + false + false + true + 1 + 125 + TXOUTCLK + true + false + gig_ethernet_pcs_pma_0_gt + true + GTHE3 + false + 1 + true + false + false + xcvu095 + false + 1 + true + 1 + gig_ethernet_pcs_pma_0 + Custom + 50.0 + TEMAC + Custom + 0 + false + false + false + GTH + false + 625 + Custom + false + 1G + 1 + LVDS + 125 + TXOUTCLK + DIFF_PAIR_0 + DIFF_PAIR_1 + false + 10_100_1000 + false + SGMII + Include_Shared_Logic_in_Core + Time_of_day + false + DIFF_PAIR_0 + DIFF_PAIR_1 + 1 + false + virtexu + + xcvu095 + ffva2104 + VERILOG + + MIXED + -2 + E + TRUE + TRUE + IP_Flow + 1 + TRUE + . + + . + 2016.2 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + diff --git a/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci b/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci new file mode 100644 index 000000000..5b02f3f19 --- /dev/null +++ b/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci @@ -0,0 +1,81 @@ + + + xilinx.com + xci + unknown + 1.0 + + + ten_gig_eth_pcs_pma_0 + + + 0 + ten_gig_eth_pcs_pma_0 + 125.00 + virtexu + X0Y12 + 64 + 3 + false + false + false + false + false + false + clk0 + 156 + 10 + ten_gig_eth_pcs_pma_0_gt + ten_gig_eth_pcs_pma_0 + 125.00 + None + X0Y12 + false + clk0 + 156.25 + 1 + Time_of_day + false + false + false + BASE-R + 64bit + false + false + 10Gig + GTY + virtexu + + xcvu095 + ffva2104 + VERILOG + + MIXED + -2 + E + TRUE + TRUE + IP_Flow + 5 + TRUE + . + + . + 2016.2 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + diff --git a/example/VCU108/fpga_10g/lib/eth b/example/VCU108/fpga_10g/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/VCU108/fpga_10g/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/VCU108/fpga_10g/rtl/debounce_switch.v b/example/VCU108/fpga_10g/rtl/debounce_switch.v new file mode 100644 index 000000000..3e2dc20a5 --- /dev/null +++ b/example/VCU108/fpga_10g/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/VCU108/fpga_10g/rtl/fpga.v b/example/VCU108/fpga_10g/rtl/fpga.v new file mode 100644 index 000000000..8666e0eeb --- /dev/null +++ b/example/VCU108/fpga_10g/rtl/fpga.v @@ -0,0 +1,525 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 125MHz LVDS + * Reset: Push button, active low + */ + input wire clk_125mhz_p, + input wire clk_125mhz_n, + input wire reset, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * I2C for board management + */ + // inout wire i2c_scl, + // inout wire i2c_sda, + + /* + * Ethernet: QSFP28 + */ + input wire qsfp_rx1_p, + input wire qsfp_rx1_n, + // input wire qsfp_rx2_p, + // input wire qsfp_rx2_n, + // input wire qsfp_rx3_p, + // input wire qsfp_rx3_n, + // input wire qsfp_rx4_p, + // input wire qsfp_rx4_n, + output wire qsfp_tx1_p, + output wire qsfp_tx1_n, + // output wire qsfp_tx2_p, + // output wire qsfp_tx2_n, + // output wire qsfp_tx3_p, + // output wire qsfp_tx3_n, + // output wire qsfp_tx4_p, + // output wire qsfp_tx4_n, + input wire qsfp_mgt_refclk_0_p, + input wire qsfp_mgt_refclk_0_n, + // input wire qsfp_mgt_refclk_1_p, + // input wire qsfp_mgt_refclk_1_n, + // output wire qsfp_recclk_p, + // output wire qsfp_recclk_n, + // output wire qsfp_modesell, + // output wire qsfp_resetl, + // output wire qsfp_modpresl, + // input wire qsfp_intl, + // output wire qsfp_lpmode, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_sgmii_rx_p, + input wire phy_sgmii_rx_n, + output wire phy_sgmii_tx_p, + output wire phy_sgmii_tx_n, + input wire phy_sgmii_clk_p, + input wire phy_sgmii_clk_n, + output wire phy_reset_n, + input wire phy_int_n, + + /* + * UART: 500000 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// Clock and reset + +wire clk_125mhz_ibufg; +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +// Internal 156.25 MHz clock +wire clk_156mhz_int; +wire rst_156mhz_int; + +wire mmcm_rst = reset; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS #( + .DIFF_TERM("FALSE"), + .IBUF_LOW_PWR("FALSE") +) +clk_125mhz_ibufg_inst ( + .O (clk_125mhz_ibufg), + .I (clk_125mhz_p), + .IB (clk_125mhz_n) +); + +// MMCM instance +// 125 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 600 MHz to 1440 MHz +// M = 5, D = 1 sets Fvco = 625 MHz (in range) +// Divide by 5 to get output frequency of 125 MHz +MMCME3_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(5), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(5), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(8.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_125mhz_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [3:0] sw_int; + +debounce_switch #( + .WIDTH(9), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +wire uart_rxd_int; +wire uart_cts_int; + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(clk_125mhz_int), + .in({uart_rxd, uart_cts}), + .out({uart_rxd_int, uart_cts_int}) +); + +// XGMII 10G PHY +wire [63:0] qsfp_txd_1_int; +wire [7:0] qsfp_txc_1_int; +wire [63:0] qsfp_rxd_1_int; +wire [7:0] qsfp_rxc_1_int; +wire [63:0] qsfp_txd_2_int; +wire [7:0] qsfp_txc_2_int; +wire [63:0] qsfp_rxd_2_int = 64'h0707070707070707; +wire [7:0] qsfp_rxc_2_int = 8'hff; +wire [63:0] qsfp_txd_3_int; +wire [7:0] qsfp_txc_3_int; +wire [63:0] qsfp_rxd_3_int = 64'h0707070707070707; +wire [7:0] qsfp_rxc_3_int = 8'hff; +wire [63:0] qsfp_txd_4_int; +wire [7:0] qsfp_txc_4_int; +wire [63:0] qsfp_rxd_4_int = 64'h0707070707070707; +wire [7:0] qsfp_rxc_4_int = 8'hff; + +wire [535:0] configuration_vector; +wire [447:0] status_vector; + +assign configuration_vector[0] = 1'b0; // PMA Loopback Enable +assign configuration_vector[14:1] = 0; +assign configuration_vector[15] = 1'b0; // PMA Reset +assign configuration_vector[16] = 1'b0; // Global PMD TX Disable +assign configuration_vector[109:17] = 0; +assign configuration_vector[110] = 1'b0; // PCS Loopback Enable +assign configuration_vector[111] = 1'b0; // PCS Reset +assign configuration_vector[169:112] = 58'd0; // 10GBASE-R Test Pattern Seed A0-3 +assign configuration_vector[175:170] = 0; +assign configuration_vector[233:176] = 58'd0; // 10GBASE-R Test Pattern Seed B0-3 +assign configuration_vector[239:234] = 0; +assign configuration_vector[240] = 1'b0; // Data Pattern Select +assign configuration_vector[241] = 1'b0; // Test Pattern Select +assign configuration_vector[242] = 1'b0; // RX Test Pattern Checking Enable +assign configuration_vector[243] = 1'b0; // TX Test Pattern Enable +assign configuration_vector[244] = 1'b0; // PRBS31 TX Test Pattern Enable +assign configuration_vector[245] = 1'b0; // PRBS31 RX Test Pattern Checking Enable +assign configuration_vector[383:246] = 0; +assign configuration_vector[399:384] = 16'h4C4B; // 125 us timer control +assign configuration_vector[511:400] = 0; +assign configuration_vector[512] = 1'b0; // Set PMA Link Status +assign configuration_vector[513] = 1'b0; // Clear PMA/PMD Link Faults +assign configuration_vector[515:514] = 0; +assign configuration_vector[516] = 1'b0; // Set PCS Link Status +assign configuration_vector[517] = 1'b0; // Clear PCS Link Faults +assign configuration_vector[518] = 1'b0; // Clear 10GBASE-R Status 2 +assign configuration_vector[519] = 1'b0; // Clear 10GBASE-R Test Pattern Error Counter +assign configuration_vector[535:520] = 0; + +wire drp_gnt; +wire gt_drprdy; +wire [15:0] gt_drpdo; +wire gt_drpen; +wire gt_drpwe; +wire [15:0] gt_drpaddr; +wire [15:0] gt_drpdi; + +ten_gig_eth_pcs_pma_0 +ten_gig_eth_pcs_pma_inst ( + .refclk_p(qsfp_mgt_refclk_0_p), + .refclk_n(qsfp_mgt_refclk_0_n), + + .dclk(clk_125mhz_int), + + .coreclk_out(), + + .reset(rst_125mhz_int), + + .sim_speedup_control(1'b0), + + .qpll0outclk_out(), + .qpll0outrefclk_out(), + .qpll0lock_out(), + + .rxrecclk_out(), + + .txusrclk_out(), + .txusrclk2_out(clk_156mhz_int), + + .gttxreset_out(), + .gtrxreset_out(), + + .txuserrdy_out(), + + .areset_datapathclk_out(rst_156mhz_int), + .areset_coreclk_out(), + .reset_counter_done_out(), + + .xgmii_txd(qsfp_txd_1_int), + .xgmii_txc(qsfp_txc_1_int), + .xgmii_rxd(qsfp_rxd_1_int), + .xgmii_rxc(qsfp_rxc_1_int), + + .txp(qsfp_tx1_p), + .txn(qsfp_tx1_n), + .rxp(qsfp_rx1_p), + .rxn(qsfp_rx1_n), + + .resetdone_out(), + .signal_detect(1'b1), + .tx_fault(1'b0), + + .drp_req(drp_gnt), + .drp_gnt(drp_gnt), + + .core_to_gt_drprdy(gt_drprdy), + .core_to_gt_drpdo(gt_drpdo), + .core_to_gt_drpen(gt_drpen), + .core_to_gt_drpwe(gt_drpwe), + .core_to_gt_drpaddr(gt_drpaddr), + .core_to_gt_drpdi(gt_drpdi), + + .gt_drprdy(gt_drprdy), + .gt_drpdo(gt_drpdo), + .gt_drpen(gt_drpen), + .gt_drpwe(gt_drpwe), + .gt_drpaddr(gt_drpaddr), + .gt_drpdi(gt_drpdi), + + .tx_disable(), + .configuration_vector(configuration_vector), + .status_vector(status_vector), + .pma_pmd_type(3'b101), + .core_status() +); + +// SGMII interface to PHY +wire phy_gmii_clk_int; +wire phy_gmii_rst_int; +wire [7:0] phy_gmii_txd_int; +wire phy_gmii_tx_en_int; +wire phy_gmii_tx_er_int; +wire [7:0] phy_gmii_rxd_int; +wire phy_gmii_rx_dv_int; +wire phy_gmii_rx_er_int; + +wire [15:0] gig_eth_status_vector; + +wire [4:0] gig_eth_pcspma_config_vector; + +assign gig_eth_pcspma_config_vector[4] = 1'b1; // autonegotiation enable +assign gig_eth_pcspma_config_vector[3] = 1'b0; // isolate +assign gig_eth_pcspma_config_vector[2] = 1'b0; // power down +assign gig_eth_pcspma_config_vector[1] = 1'b0; // loopback enable +assign gig_eth_pcspma_config_vector[0] = 1'b0; // unidirectional enable + +wire [15:0] gig_eth_pcspma_an_config_vector; + +assign gig_eth_pcspma_an_config_vector[15] = 1'b1; // SGMII link status +assign gig_eth_pcspma_an_config_vector[14] = 1'b1; // SGMII Acknowledge +assign gig_eth_pcspma_an_config_vector[13:12] = 2'b01; // full duplex +assign gig_eth_pcspma_an_config_vector[11:10] = 2'b10; // SGMII speed +assign gig_eth_pcspma_an_config_vector[9] = 1'b0; // reserved +assign gig_eth_pcspma_an_config_vector[8:7] = 2'b00; // pause frames - SGMII reserved +assign gig_eth_pcspma_an_config_vector[6] = 1'b0; // reserved +assign gig_eth_pcspma_an_config_vector[5] = 1'b0; // full duplex - SGMII reserved +assign gig_eth_pcspma_an_config_vector[4:1] = 4'b0000; // reserved +assign gig_eth_pcspma_an_config_vector[0] = 1'b1; // SGMII + +gig_ethernet_pcs_pma_0 +gig_eth_pcspma ( + // SGMII + .txp (phy_sgmii_tx_p), + .txn (phy_sgmii_tx_n), + .rxp (phy_sgmii_rx_p), + .rxn (phy_sgmii_rx_n), + + // Ref clock from PHY + .refclk625_p (phy_sgmii_clk_p), + .refclk625_n (phy_sgmii_clk_n), + + // async reset + .reset (rst_125mhz_int), + + // clock and reset outputs + .clk125_out (phy_gmii_clk_int), + .clk625_out (), + .clk312_out (), + .rst_125_out (phy_gmii_rst_int), + .idelay_rdy_out (), + .mmcm_locked_out (), + + // MAC clocking + .sgmii_clk_r (), + .sgmii_clk_f (), + .sgmii_clk_en (), // need to pass through to MAC + + // Speed control + .speed_is_10_100 (1'b0), + .speed_is_100 (1'b0), + + // Internal GMII + .gmii_txd (phy_gmii_txd_int), + .gmii_tx_en (phy_gmii_tx_en_int), + .gmii_tx_er (phy_gmii_tx_er_int), + .gmii_rxd (phy_gmii_rxd_int), + .gmii_rx_dv (phy_gmii_rx_dv_int), + .gmii_rx_er (phy_gmii_rx_er_int), + .gmii_isolate (), + + // Configuration + .configuration_vector (gig_eth_pcspma_config_vector), + + .an_interrupt (), + .an_adv_config_vector (gig_eth_pcspma_an_config_vector), + .an_restart_config (1'b0), + + // Status + .status_vector (gig_eth_status_vector), + .signal_detect (1'b1) +); + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .led(led), + /* + * Ethernet: QSFP28 + */ + .qsfp_txd_1(qsfp_txd_1_int), + .qsfp_txc_1(qsfp_txc_1_int), + .qsfp_rxd_1(qsfp_rxd_1_int), + .qsfp_rxc_1(qsfp_rxc_1_int), + .qsfp_txd_2(qsfp_txd_2_int), + .qsfp_txc_2(qsfp_txc_2_int), + .qsfp_rxd_2(qsfp_rxd_2_int), + .qsfp_rxc_2(qsfp_rxc_2_int), + .qsfp_txd_3(qsfp_txd_3_int), + .qsfp_txc_3(qsfp_txc_3_int), + .qsfp_rxd_3(qsfp_rxd_3_int), + .qsfp_rxc_3(qsfp_rxc_3_int), + .qsfp_txd_4(qsfp_txd_4_int), + .qsfp_txc_4(qsfp_txc_4_int), + .qsfp_rxd_4(qsfp_rxd_4_int), + .qsfp_rxc_4(qsfp_rxc_4_int), + /* + * Ethernet: 1000BASE-T SGMII + */ + .phy_gmii_clk(phy_gmii_clk_int), + .phy_gmii_rst(phy_gmii_rst_int), + .phy_gmii_rxd(phy_gmii_rxd_int), + .phy_gmii_rx_dv(phy_gmii_rx_dv_int), + .phy_gmii_rx_er(phy_gmii_rx_er_int), + .phy_gmii_txd(phy_gmii_txd_int), + .phy_gmii_tx_en(phy_gmii_tx_en_int), + .phy_gmii_tx_er(phy_gmii_tx_er_int), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts_int) +); + +endmodule diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v new file mode 100644 index 000000000..7dbfb1e45 --- /dev/null +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -0,0 +1,855 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * Ethernet: QSFP28 + */ + output wire [63:0] qsfp_txd_1, + output wire [7:0] qsfp_txc_1, + input wire [63:0] qsfp_rxd_1, + input wire [7:0] qsfp_rxc_1, + output wire [63:0] qsfp_txd_2, + output wire [7:0] qsfp_txc_2, + input wire [63:0] qsfp_rxd_2, + input wire [7:0] qsfp_rxc_2, + output wire [63:0] qsfp_txd_3, + output wire [7:0] qsfp_txc_3, + input wire [63:0] qsfp_rxd_3, + input wire [7:0] qsfp_rxc_3, + output wire [63:0] qsfp_txd_4, + output wire [7:0] qsfp_txc_4, + input wire [63:0] qsfp_rxd_4, + input wire [7:0] qsfp_rxc_4, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_gmii_clk, + input wire phy_gmii_rst, + input wire [7:0] phy_gmii_rxd, + input wire phy_gmii_rx_dv, + input wire phy_gmii_rx_er, + output wire [7:0] phy_gmii_txd, + output wire phy_gmii_tx_en, + output wire phy_gmii_tx_er, + output wire phy_reset_n, + input wire phy_int_n, + + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// AXI between MAC and Ethernet modules +wire [63:0] mac_rx_axis_tdata; +wire [7:0] mac_rx_axis_tkeep; +wire mac_rx_axis_tvalid; +wire mac_rx_axis_tready; +wire mac_rx_axis_tlast; +wire mac_rx_axis_tuser; + +wire [63:0] mac_tx_axis_tdata; +wire [7:0] mac_tx_axis_tkeep; +wire mac_tx_axis_tvalid; +wire mac_tx_axis_tready; +wire mac_tx_axis_tlast; +wire mac_tx_axis_tuser; + +wire [63:0] rx_axis_tdata; +wire [7:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [63:0] tx_axis_tdata; +wire [7:0] tx_axis_tkeep; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [63:0] rx_eth_payload_tdata; +wire [7:0] rx_eth_payload_tkeep; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [63:0] tx_eth_payload_tdata; +wire [7:0] tx_eth_payload_tkeep; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [63:0] rx_ip_payload_tdata; +wire [7:0] rx_ip_payload_tkeep; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [63:0] tx_ip_payload_tdata; +wire [7:0] tx_ip_payload_tkeep; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [63:0] rx_udp_payload_tdata; +wire [7:0] rx_udp_payload_tkeep; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [63:0] tx_udp_payload_tdata; +wire [7:0] tx_udp_payload_tkeep; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [63:0] rx_fifo_udp_payload_tdata; +wire [7:0] rx_fifo_udp_payload_tkeep; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [63:0] tx_fifo_udp_payload_tdata; +wire [7:0] tx_fifo_udp_payload_tkeep; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tkeep = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tkeep = rx_udp_payload_tkeep; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tkeep = tx_fifo_udp_payload_tkeep; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tkeep = rx_udp_payload_tkeep; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_tvalid; + if (tx_udp_payload_tvalid & ~valid_last) begin + led_reg <= tx_udp_payload_tdata; + end + end +end + +//assign led = sw; +assign led = led_reg; +assign phy_reset_n = ~rst; + +assign qsfp_txd_2 = 64'h0707070707070707; +assign qsfp_txc_2 = 8'hff; +assign qsfp_txd_3 = 64'h0707070707070707; +assign qsfp_txc_3 = 8'hff; +assign qsfp_txd_4 = 64'h0707070707070707; +assign qsfp_txc_4 = 8'hff; + +eth_mac_10g_fifo #( + .ENABLE_PADDING(1), + .ENABLE_DIC(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(9), + .RX_FIFO_ADDR_WIDTH(9) +) +eth_mac_10g_fifo_inst ( + .rx_clk(clk), + .rx_rst(rst), + .tx_clk(clk), + .tx_rst(rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(mac_tx_axis_tdata), + .tx_axis_tkeep(mac_tx_axis_tkeep), + .tx_axis_tvalid(mac_tx_axis_tvalid), + .tx_axis_tready(mac_tx_axis_tready), + .tx_axis_tlast(mac_tx_axis_tlast), + .tx_axis_tuser(mac_tx_axis_tuser), + + .rx_axis_tdata(mac_rx_axis_tdata), + .rx_axis_tkeep(mac_rx_axis_tkeep), + .rx_axis_tvalid(mac_rx_axis_tvalid), + .rx_axis_tready(mac_rx_axis_tready), + .rx_axis_tlast(mac_rx_axis_tlast), + .rx_axis_tuser(mac_rx_axis_tuser), + + .xgmii_rxd(qsfp_rxd_1), + .xgmii_rxc(qsfp_rxc_1), + .xgmii_txd(qsfp_txd_1), + .xgmii_txc(qsfp_txc_1), + + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + + .ifg_delay(8'd12) +); + +// 1G interface for debugging +wire [7:0] gig_rx_axis_tdata; +wire gig_rx_axis_tvalid; +wire gig_rx_axis_tready; +wire gig_rx_axis_tlast; +wire gig_rx_axis_tuser; + +wire [7:0] gig_tx_axis_tdata; +wire gig_tx_axis_tvalid; +wire gig_tx_axis_tready; +wire gig_tx_axis_tlast; +wire gig_tx_axis_tuser; + +wire [63:0] gig_rx_axis_tdata_64; +wire [7:0] gig_rx_axis_tkeep_64; +wire gig_rx_axis_tvalid_64; +wire gig_rx_axis_tready_64; +wire gig_rx_axis_tlast_64; +wire gig_rx_axis_tuser_64; + +wire [63:0] gig_tx_axis_tdata_64; +wire [7:0] gig_tx_axis_tkeep_64; +wire gig_tx_axis_tvalid_64; +wire gig_tx_axis_tready_64; +wire gig_tx_axis_tlast_64; +wire gig_tx_axis_tuser_64; + +eth_mac_1g_fifo #( + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .RX_FIFO_ADDR_WIDTH(12) +) +eth_mac_1g_fifo_inst ( + .rx_clk(phy_gmii_clk), + .rx_rst(phy_gmii_rst), + .tx_clk(phy_gmii_clk), + .tx_rst(phy_gmii_rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(gig_tx_axis_tdata), + .tx_axis_tvalid(gig_tx_axis_tvalid), + .tx_axis_tready(gig_tx_axis_tready), + .tx_axis_tlast(gig_tx_axis_tlast), + .tx_axis_tuser(gig_tx_axis_tuser), + + .rx_axis_tdata(gig_rx_axis_tdata), + .rx_axis_tvalid(gig_rx_axis_tvalid), + .rx_axis_tready(gig_rx_axis_tready), + .rx_axis_tlast(gig_rx_axis_tlast), + .rx_axis_tuser(gig_rx_axis_tuser), + + .gmii_rxd(phy_gmii_rxd), + .gmii_rx_dv(phy_gmii_rx_dv), + .gmii_rx_er(phy_gmii_rx_er), + .gmii_txd(phy_gmii_txd), + .gmii_tx_en(phy_gmii_tx_en), + .gmii_tx_er(phy_gmii_tx_er), + + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + + .ifg_delay(12) +); + +axis_adapter #( + .INPUT_DATA_WIDTH(8), + .OUTPUT_DATA_WIDTH(64) +) +gig_rx_axis_adapter_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(gig_rx_axis_tdata), + .input_axis_tkeep(1'b1), + .input_axis_tvalid(gig_rx_axis_tvalid), + .input_axis_tready(gig_rx_axis_tready), + .input_axis_tlast(gig_rx_axis_tlast), + .input_axis_tuser(gig_rx_axis_tuser), + // AXI output + .output_axis_tdata(gig_rx_axis_tdata_64), + .output_axis_tkeep(gig_rx_axis_tkeep_64), + .output_axis_tvalid(gig_rx_axis_tvalid_64), + .output_axis_tready(gig_rx_axis_tready_64), + .output_axis_tlast(gig_rx_axis_tlast_64), + .output_axis_tuser(gig_rx_axis_tuser_64) +); + +axis_adapter #( + .INPUT_DATA_WIDTH(64), + .OUTPUT_DATA_WIDTH(8) +) +gig_tx_axis_adapter_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(gig_tx_axis_tdata_64), + .input_axis_tkeep(gig_tx_axis_tkeep_64), + .input_axis_tvalid(gig_tx_axis_tvalid_64), + .input_axis_tready(gig_tx_axis_tready_64), + .input_axis_tlast(gig_tx_axis_tlast_64), + .input_axis_tuser(gig_tx_axis_tuser_64), + // AXI output + .output_axis_tdata(gig_tx_axis_tdata), + .output_axis_tkeep(), + .output_axis_tvalid(gig_tx_axis_tvalid), + .output_axis_tready(gig_tx_axis_tready), + .output_axis_tlast(gig_tx_axis_tlast), + .output_axis_tuser(gig_tx_axis_tuser) +); + +// tap port mux logic +// sw[3] enable +// sw[2] select 0 rx, 1 tx + +reg [1:0] mac_rx_tdest; +reg [1:0] tx_tdest; +reg [1:0] gig_rx_tdest; + +always @* begin + if (sw[3]) begin + if (sw[2]) begin + // Tap on TX path + // MAC RX out -> stack RX in + // stack TX out -> gig TX in + // gig RX out -> MAC TX in + mac_rx_tdest = 2'd1; + tx_tdest = 2'd2; + gig_rx_tdest = 2'd0; + end else begin + // Tap on RX path + // MAC RX out -> gig TX in + // stack TX out -> MAC TX in + // gig RX out -> stack RX in + mac_rx_tdest = 2'd2; + tx_tdest = 2'd0; + gig_rx_tdest = 2'd1; + end + end else begin + // Tap disabled + // MAC RX out -> stack RX in + // stack TX out -> MAC TX in + // gig RX out -> blackhole + mac_rx_tdest = 2'd1; + tx_tdest = 2'd0; + gig_rx_tdest = 2'd3; + end +end + +axis_switch_64_4x4 #( + .DATA_WIDTH(64), + .KEEP_WIDTH(8), + .DEST_WIDTH(2), + .OUT_0_BASE(0), + .OUT_0_TOP(0), + .OUT_0_CONNECT(4'b1111), + .OUT_1_BASE(1), + .OUT_1_TOP(1), + .OUT_1_CONNECT(4'b1111), + .OUT_2_BASE(2), + .OUT_2_TOP(2), + .OUT_2_CONNECT(4'b1111), + .OUT_3_BASE(3), + .OUT_3_TOP(3), + .OUT_3_CONNECT(4'b1111), + .ARB_TYPE("PRIORITY"), + .LSB_PRIORITY("HIGH") +) +axis_switch_inst ( + .clk(clk), + .rst(rst), + // AXI inputs + .input_0_axis_tdata(mac_rx_axis_tdata), + .input_0_axis_tkeep(mac_rx_axis_tkeep), + .input_0_axis_tvalid(mac_rx_axis_tvalid), + .input_0_axis_tready(mac_rx_axis_tready), + .input_0_axis_tlast(mac_rx_axis_tlast), + .input_0_axis_tdest(mac_rx_tdest), + .input_0_axis_tuser(mac_rx_axis_tuser), + .input_1_axis_tdata(tx_axis_tdata), + .input_1_axis_tkeep(tx_axis_tkeep), + .input_1_axis_tvalid(tx_axis_tvalid), + .input_1_axis_tready(tx_axis_tready), + .input_1_axis_tlast(tx_axis_tlast), + .input_1_axis_tdest(tx_tdest), + .input_1_axis_tuser(tx_axis_tuser), + .input_2_axis_tdata(gig_rx_axis_tdata_64), + .input_2_axis_tkeep(gig_rx_axis_tkeep_64), + .input_2_axis_tvalid(gig_rx_axis_tvalid_64), + .input_2_axis_tready(gig_rx_axis_tready_64), + .input_2_axis_tlast(gig_rx_axis_tlast_64), + .input_2_axis_tdest(gig_rx_tdest), + .input_2_axis_tuser(gig_rx_axis_tuser_64), + .input_3_axis_tdata(64'd0), + .input_3_axis_tkeep(8'd0), + .input_3_axis_tvalid(1'b0), + .input_3_axis_tready(), + .input_3_axis_tlast(1'b0), + .input_3_axis_tdest(2'd0), + .input_3_axis_tuser(1'b0), + // AXI outputs + .output_0_axis_tdata(mac_tx_axis_tdata), + .output_0_axis_tkeep(mac_tx_axis_tkeep), + .output_0_axis_tvalid(mac_tx_axis_tvalid), + .output_0_axis_tready(mac_tx_axis_tready), + .output_0_axis_tlast(mac_tx_axis_tlast), + .output_0_axis_tdest(), + .output_0_axis_tuser(mac_tx_axis_tuser), + .output_1_axis_tdata(rx_axis_tdata), + .output_1_axis_tkeep(rx_axis_tkeep), + .output_1_axis_tvalid(rx_axis_tvalid), + .output_1_axis_tready(rx_axis_tready), + .output_1_axis_tlast(rx_axis_tlast), + .output_1_axis_tdest(), + .output_1_axis_tuser(rx_axis_tuser), + .output_2_axis_tdata(gig_tx_axis_tdata_64), + .output_2_axis_tkeep(gig_tx_axis_tkeep_64), + .output_2_axis_tvalid(gig_tx_axis_tvalid_64), + .output_2_axis_tready(gig_tx_axis_tready_64), + .output_2_axis_tlast(gig_tx_axis_tlast_64), + .output_2_axis_tdest(), + .output_2_axis_tuser(gig_tx_axis_tuser_64), + .output_3_axis_tdata(), + .output_3_axis_tkeep(), + .output_3_axis_tvalid(), + .output_3_axis_tready(1'b1), + .output_3_axis_tlast(), + .output_3_axis_tdest(), + .output_3_axis_tuser() +); + +eth_axis_rx_64 +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tkeep(rx_axis_tkeep), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tkeep(rx_eth_payload_tkeep), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx_64 +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tkeep(tx_eth_payload_tkeep), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tkeep(tx_axis_tkeep), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete_64 #( + .UDP_CHECKSUM_ENABLE(0) +) +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tkeep(rx_eth_payload_tkeep), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tkeep(tx_eth_payload_tkeep), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tkeep(tx_ip_payload_tkeep), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tkeep(rx_ip_payload_tkeep), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tkeep(tx_udp_payload_tkeep), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tkeep(rx_udp_payload_tkeep), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(1'b0) +); + +axis_fifo_64 #( + .ADDR_WIDTH(10), + .DATA_WIDTH(64) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(rx_fifo_udp_payload_tkeep), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(tx_fifo_udp_payload_tkeep), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/VCU108/fpga_10g/rtl/sync_reset.v b/example/VCU108/fpga_10g/rtl/sync_reset.v new file mode 100644 index 000000000..ddd99febe --- /dev/null +++ b/example/VCU108/fpga_10g/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/VCU108/fpga_10g/rtl/sync_signal.v b/example/VCU108/fpga_10g/rtl/sync_signal.v new file mode 100644 index 000000000..5afcd7170 --- /dev/null +++ b/example/VCU108/fpga_10g/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2016 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/VCU108/fpga_10g/tb/arp_ep.py b/example/VCU108/fpga_10g/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/VCU108/fpga_10g/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_10g/tb/axis_ep.py b/example/VCU108/fpga_10g/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/VCU108/fpga_10g/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_10g/tb/eth_ep.py b/example/VCU108/fpga_10g/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/VCU108/fpga_10g/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_10g/tb/gmii_ep.py b/example/VCU108/fpga_10g/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/VCU108/fpga_10g/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_10g/tb/ip_ep.py b/example/VCU108/fpga_10g/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/VCU108/fpga_10g/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py new file mode 100755 index 000000000..afb60a373 --- /dev/null +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -0,0 +1,635 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import eth_ep +import arp_ep +import udp_ep +import gmii_ep +import xgmii_ep + +module = 'fpga_core' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_64_2.v") +srcs.append("../lib/eth/rtl/ip_mux_64_2.v") +srcs.append("../lib/eth/rtl/arp_64.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") +srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") +srcs.append("../lib/eth/rtl/eth_mux_64_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_adapter.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo_64.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_switch_64_4x4.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_fpga_core(clk, + rst, + current_test, + + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + led, + + qsfp_txd_1, + qsfp_txc_1, + qsfp_rxd_1, + qsfp_rxc_1, + qsfp_txd_2, + qsfp_txc_2, + qsfp_rxd_2, + qsfp_rxc_2, + qsfp_txd_3, + qsfp_txc_3, + qsfp_rxd_3, + qsfp_rxc_3, + qsfp_txd_4, + qsfp_txc_4, + qsfp_rxd_4, + qsfp_rxc_4, + + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + phy_int_n, + + uart_rxd, + uart_txd, + uart_rts, + uart_cts): + + 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, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, + + qsfp_txd_1=qsfp_txd_1, + qsfp_txc_1=qsfp_txc_1, + qsfp_rxd_1=qsfp_rxd_1, + qsfp_rxc_1=qsfp_rxc_1, + qsfp_txd_2=qsfp_txd_2, + qsfp_txc_2=qsfp_txc_2, + qsfp_rxd_2=qsfp_rxd_2, + qsfp_rxc_2=qsfp_rxc_2, + qsfp_txd_3=qsfp_txd_3, + qsfp_txc_3=qsfp_txc_3, + qsfp_rxd_3=qsfp_rxd_3, + qsfp_rxc_3=qsfp_rxc_3, + qsfp_txd_4=qsfp_txd_4, + qsfp_txc_4=qsfp_txc_4, + qsfp_rxd_4=qsfp_rxd_4, + qsfp_rxc_4=qsfp_rxc_4, + + phy_gmii_clk=phy_gmii_clk, + phy_gmii_rst=phy_gmii_rst, + phy_gmii_rxd=phy_gmii_rxd, + phy_gmii_rx_dv=phy_gmii_rx_dv, + phy_gmii_rx_er=phy_gmii_rx_er, + phy_gmii_txd=phy_gmii_txd, + phy_gmii_tx_en=phy_gmii_tx_en, + phy_gmii_tx_er=phy_gmii_tx_er, + phy_reset_n=phy_reset_n, + phy_int_n=phy_int_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[4:]) + qsfp_rxd_1 = Signal(intbv(0)[64:]) + qsfp_rxc_1 = Signal(intbv(0)[8:]) + qsfp_rxd_2 = Signal(intbv(0)[64:]) + qsfp_rxc_2 = Signal(intbv(0)[8:]) + qsfp_rxd_3 = Signal(intbv(0)[64:]) + qsfp_rxc_3 = Signal(intbv(0)[8:]) + qsfp_rxd_4 = Signal(intbv(0)[64:]) + qsfp_rxc_4 = Signal(intbv(0)[8:]) + phy_gmii_clk = Signal(bool(0)) + phy_gmii_rst = Signal(bool(0)) + phy_gmii_rxd = Signal(intbv(0)[8:]) + phy_gmii_rx_dv = Signal(bool(0)) + phy_gmii_rx_er = Signal(bool(0)) + phy_int_n = Signal(bool(1)) + uart_rxd = Signal(bool(0)) + uart_cts = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[8:]) + qsfp_txd_1 = Signal(intbv(0)[64:]) + qsfp_txc_1 = Signal(intbv(0)[8:]) + qsfp_txd_2 = Signal(intbv(0)[64:]) + qsfp_txc_2 = Signal(intbv(0)[8:]) + qsfp_txd_3 = Signal(intbv(0)[64:]) + qsfp_txc_3 = Signal(intbv(0)[8:]) + qsfp_txd_4 = Signal(intbv(0)[64:]) + qsfp_txc_4 = Signal(intbv(0)[8:]) + phy_gmii_txd = Signal(intbv(0)[8:]) + phy_gmii_tx_en = Signal(bool(0)) + phy_gmii_tx_er = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + + # sources and sinks + xgmii_1_source_queue = Queue() + xgmii_1_sink_queue = Queue() + xgmii_2_source_queue = Queue() + xgmii_2_sink_queue = Queue() + xgmii_3_source_queue = Queue() + xgmii_3_sink_queue = Queue() + xgmii_4_source_queue = Queue() + xgmii_4_sink_queue = Queue() + gmii_source_queue = Queue() + gmii_sink_queue = Queue() + + xgmii_1_source = xgmii_ep.XGMIISource(clk, + rst, + txd=qsfp_rxd_1, + txc=qsfp_rxc_1, + fifo=xgmii_1_source_queue, + name='xgmii_1_source') + + xgmii_1_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=qsfp_txd_1, + rxc=qsfp_txc_1, + fifo=xgmii_1_sink_queue, + name='xgmii_1_sink') + + xgmii_2_source = xgmii_ep.XGMIISource(clk, + rst, + txd=qsfp_rxd_2, + txc=qsfp_rxc_2, + fifo=xgmii_2_source_queue, + name='xgmii_2_source') + + xgmii_2_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=qsfp_txd_2, + rxc=qsfp_txc_2, + fifo=xgmii_2_sink_queue, + name='xgmii_2_sink') + + xgmii_3_source = xgmii_ep.XGMIISource(clk, + rst, + txd=qsfp_rxd_3, + txc=qsfp_rxc_3, + fifo=xgmii_3_source_queue, + name='xgmii_3_source') + + xgmii_3_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=qsfp_txd_3, + rxc=qsfp_txc_3, + fifo=xgmii_3_sink_queue, + name='xgmii_3_sink') + + xgmii_4_source = xgmii_ep.XGMIISource(clk, + rst, + txd=qsfp_rxd_4, + txc=qsfp_rxc_4, + fifo=xgmii_4_source_queue, + name='xgmii_4_source') + + xgmii_4_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=qsfp_txd_4, + rxc=qsfp_txc_4, + fifo=xgmii_4_sink_queue, + name='xgmii_4_sink') + + gmii_source = gmii_ep.GMIISource(phy_gmii_clk, + phy_gmii_rst, + txd=phy_gmii_rxd, + tx_en=phy_gmii_rx_dv, + tx_er=phy_gmii_rx_er, + fifo=gmii_source_queue, + name='gmii_source') + + gmii_sink = gmii_ep.GMIISink(phy_gmii_clk, + phy_gmii_rst, + rxd=phy_gmii_txd, + rx_dv=phy_gmii_tx_en, + rx_er=phy_gmii_tx_er, + fifo=gmii_sink_queue, + name='gmii_sink') + + # DUT + dut = dut_fpga_core(clk, + rst, + current_test, + + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + led, + + qsfp_txd_1, + qsfp_txc_1, + qsfp_rxd_1, + qsfp_rxc_1, + qsfp_txd_2, + qsfp_txc_2, + qsfp_rxd_2, + qsfp_rxc_2, + qsfp_txd_3, + qsfp_txc_3, + qsfp_rxd_3, + qsfp_rxc_3, + qsfp_txd_4, + qsfp_txc_4, + qsfp_rxd_4, + qsfp_rxc_4, + + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + phy_int_n, + + uart_rxd, + uart_txd, + uart_rts, + uart_cts) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + phy_gmii_clk.next = not phy_gmii_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + phy_gmii_rst.next = 1 + yield clk.posedge + rst.next = 0 + phy_gmii_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + xgmii_1_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while xgmii_1_sink_queue.empty(): + yield clk.posedge + + rx_frame = xgmii_1_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + xgmii_1_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while xgmii_1_sink_queue.empty(): + yield clk.posedge + + rx_frame = xgmii_1_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert xgmii_1_source_queue.empty() + assert xgmii_1_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test gigabit tap") + current_test.next = 2 + + sw.next = 0x8 # enable tap on RX + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # loop packet back through on XGMII interface + while xgmii_1_sink_queue.empty(): + yield clk.posedge + + xgmii_1_source_queue.put(xgmii_1_sink_queue.get()) + + while gmii_sink_queue.empty(): + yield clk.posedge + + rx_frame = gmii_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source_queue.empty() + assert gmii_sink_queue.empty() + assert xgmii_1_source_queue.empty() + assert xgmii_1_sink_queue.empty() + + yield delay(100) + + sw.next = 0xc # enable tap on TX + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # loop packet back through on XGMII interface + while xgmii_1_sink_queue.empty(): + yield clk.posedge + + xgmii_1_source_queue.put(xgmii_1_sink_queue.get()) + + while gmii_sink_queue.empty(): + yield clk.posedge + + rx_frame = gmii_sink_queue.get(False) + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source_queue.empty() + assert gmii_sink_queue.empty() + assert xgmii_1_source_queue.empty() + assert xgmii_1_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, xgmii_1_source, xgmii_1_sink, xgmii_2_source, xgmii_2_sink, xgmii_3_source, xgmii_3_sink, xgmii_4_source, xgmii_4_sink, gmii_source, gmii_sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.v b/example/VCU108/fpga_10g/tb/test_fpga_core.v new file mode 100644 index 000000000..45f79af87 --- /dev/null +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.v @@ -0,0 +1,173 @@ +/* + +Copyright (c) 2016 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [3:0] sw = 0; +reg [63:0] qsfp_rxd_1 = 0; +reg [7:0] qsfp_rxc_1 = 0; +reg [63:0] qsfp_rxd_2 = 0; +reg [7:0] qsfp_rxc_2 = 0; +reg [63:0] qsfp_rxd_3 = 0; +reg [7:0] qsfp_rxc_3 = 0; +reg [63:0] qsfp_rxd_4 = 0; +reg [7:0] qsfp_rxc_4 = 0; +reg phy_gmii_clk = 0; +reg phy_gmii_rst = 0; +reg [7:0] phy_gmii_rxd = 0; +reg phy_gmii_rx_dv = 0; +reg phy_gmii_rx_er = 0; +reg phy_int_n = 1; +reg uart_rxd = 0; +reg uart_cts = 0; + +// Outputs +wire [7:0] led; +wire [63:0] qsfp_txd_1; +wire [7:0] qsfp_txc_1; +wire [63:0] qsfp_txd_2; +wire [7:0] qsfp_txc_2; +wire [63:0] qsfp_txd_3; +wire [7:0] qsfp_txc_3; +wire [63:0] qsfp_txd_4; +wire [7:0] qsfp_txc_4; +wire phy_tx_clk; +wire [7:0] phy_gmii_txd; +wire phy_gmii_tx_en; +wire phy_gmii_tx_er; +wire phy_reset_n; +wire uart_txd; +wire uart_rts; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + qsfp_rxd_1, + qsfp_rxc_1, + qsfp_rxd_2, + qsfp_rxc_2, + qsfp_rxd_3, + qsfp_rxc_3, + qsfp_rxd_4, + qsfp_rxc_4, + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_int_n, + uart_rxd, + uart_cts); + $to_myhdl(led, + qsfp_txd_1, + qsfp_txc_1, + qsfp_txd_2, + qsfp_txc_2, + qsfp_txd_3, + qsfp_txc_3, + qsfp_txd_4, + qsfp_txc_4, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + uart_txd, + uart_rts); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .qsfp_txd_1(qsfp_txd_1), + .qsfp_txc_1(qsfp_txc_1), + .qsfp_rxd_1(qsfp_rxd_1), + .qsfp_rxc_1(qsfp_rxc_1), + .qsfp_txd_2(qsfp_txd_2), + .qsfp_txc_2(qsfp_txc_2), + .qsfp_rxd_2(qsfp_rxd_2), + .qsfp_rxc_2(qsfp_rxc_2), + .qsfp_txd_3(qsfp_txd_3), + .qsfp_txc_3(qsfp_txc_3), + .qsfp_rxd_3(qsfp_rxd_3), + .qsfp_rxc_3(qsfp_rxc_3), + .qsfp_txd_4(qsfp_txd_4), + .qsfp_txc_4(qsfp_txc_4), + .qsfp_rxd_4(qsfp_rxd_4), + .qsfp_rxc_4(qsfp_rxc_4), + .phy_gmii_clk(phy_gmii_clk), + .phy_gmii_rst(phy_gmii_rst), + .phy_gmii_rxd(phy_gmii_rxd), + .phy_gmii_rx_dv(phy_gmii_rx_dv), + .phy_gmii_rx_er(phy_gmii_rx_er), + .phy_gmii_txd(phy_gmii_txd), + .phy_gmii_tx_en(phy_gmii_tx_en), + .phy_gmii_tx_er(phy_gmii_tx_er), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts) +); + +endmodule diff --git a/example/VCU108/fpga_10g/tb/udp_ep.py b/example/VCU108/fpga_10g/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/VCU108/fpga_10g/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/example/VCU108/fpga_10g/tb/xgmii_ep.py b/example/VCU108/fpga_10g/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/example/VCU108/fpga_10g/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file From b44e401b95fe68909702d742c04d06f5ffdf46b7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 27 Jul 2016 13:42:44 -0700 Subject: [PATCH 298/617] Update async FIFO resets --- rtl/axis_async_fifo.v | 2 +- rtl/axis_async_fifo_64.v | 2 +- rtl/axis_async_frame_fifo.v | 2 +- rtl/axis_async_frame_fifo_64.v | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index f7542281e..fc7af9352 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -125,7 +125,7 @@ always @(posedge output_clk or posedge async_rst) begin output_rst_sync3_reg <= 1'b1; end else begin output_rst_sync1_reg <= 1'b0; - output_rst_sync2_reg <= output_rst_sync1_reg; + output_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; output_rst_sync3_reg <= output_rst_sync2_reg; end end diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index 510d38c4b..135cee214 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -128,7 +128,7 @@ always @(posedge output_clk or posedge async_rst) begin output_rst_sync3_reg <= 1'b1; end else begin output_rst_sync1_reg <= 1'b0; - output_rst_sync2_reg <= output_rst_sync1_reg; + output_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; output_rst_sync3_reg <= output_rst_sync2_reg; end end diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 98d1d87ee..2469e3b31 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -165,7 +165,7 @@ always @(posedge output_clk or posedge async_rst) begin output_rst_sync3_reg <= 1'b1; end else begin output_rst_sync1_reg <= 1'b0; - output_rst_sync2_reg <= output_rst_sync1_reg; + output_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; output_rst_sync3_reg <= output_rst_sync2_reg; end end diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 0e63c4ae5..5399898c3 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -168,7 +168,7 @@ always @(posedge output_clk or posedge async_rst) begin output_rst_sync3_reg <= 1'b1; end else begin output_rst_sync1_reg <= 1'b0; - output_rst_sync2_reg <= output_rst_sync1_reg; + output_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; output_rst_sync3_reg <= output_rst_sync2_reg; end end From 2365f4b6fcb1b6bd25cbacebf23c9011081139e2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Jul 2016 09:56:13 -0400 Subject: [PATCH 299/617] Connect QSFP module control pins --- example/VCU108/fpga_10g/fpga.xdc | 10 +++++----- example/VCU108/fpga_10g/rtl/fpga.v | 14 +++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/example/VCU108/fpga_10g/fpga.xdc b/example/VCU108/fpga_10g/fpga.xdc index e05b6bf60..185c0ad2f 100644 --- a/example/VCU108/fpga_10g/fpga.xdc +++ b/example/VCU108/fpga_10g/fpga.xdc @@ -99,11 +99,11 @@ set_property -dict {LOC AF39} [get_ports qsfp_mgt_refclk_0_n] ;# MGTREFCLK0N_127 #set_property -dict {LOC AD39} [get_ports qsfp_mgt_refclk_1_n] ;# MGTREFCLK1N_127 from U57 CKOUT2 SI5328 #set_property -dict {LOC AG34 IOSTANDARD LVDS} [get_ports qsfp_recclk_p] ;# to U57 CKIN1 SI5328 #set_property -dict {LOC AH35 IOSTANDARD LVDS} [get_ports qsfp_recclk_n] ;# to U57 CKIN1 SI5328 -#set_property -dict {LOC AL24 IOSTANDARD LVCMOS18} [get_ports qsfp_modesell] -#set_property -dict {LOC AM24 IOSTANDARD LVCMOS18} [get_ports qsfp_resetl] -#set_property -dict {LOC AL25 IOSTANDARD LVCMOS18} [get_ports qsfp_modpresl] -#set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp_intl] -#set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp_lpmode] +set_property -dict {LOC AL24 IOSTANDARD LVCMOS18} [get_ports qsfp_modesell] +set_property -dict {LOC AM24 IOSTANDARD LVCMOS18} [get_ports qsfp_resetl] +set_property -dict {LOC AL25 IOSTANDARD LVCMOS18} [get_ports qsfp_modprsl] +set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp_intl] +set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp_lpmode] # I2C interface #set_property -dict {LOC AN21 IOSTANDARD LVCMOS18} [get_ports i2c_scl] diff --git a/example/VCU108/fpga_10g/rtl/fpga.v b/example/VCU108/fpga_10g/rtl/fpga.v index 8666e0eeb..bedc0441e 100644 --- a/example/VCU108/fpga_10g/rtl/fpga.v +++ b/example/VCU108/fpga_10g/rtl/fpga.v @@ -80,11 +80,11 @@ module fpga ( // input wire qsfp_mgt_refclk_1_n, // output wire qsfp_recclk_p, // output wire qsfp_recclk_n, - // output wire qsfp_modesell, - // output wire qsfp_resetl, - // output wire qsfp_modpresl, - // input wire qsfp_intl, - // output wire qsfp_lpmode, + output wire qsfp_modesell, + output wire qsfp_resetl, + input wire qsfp_modprsl, + input wire qsfp_intl, + output wire qsfp_lpmode, /* * Ethernet: 1000BASE-T SGMII @@ -251,6 +251,10 @@ sync_signal_inst ( ); // XGMII 10G PHY +assign qsfp_modesell = 1'b1; +assign qsfp_resetl = 1'b1; +assign qsfp_lpmode = 1'b0; + wire [63:0] qsfp_txd_1_int; wire [7:0] qsfp_txc_1_int; wire [63:0] qsfp_rxd_1_int; From 833d1dac81b135f92376b0595eec81a643c0fafc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Jul 2016 09:57:36 -0400 Subject: [PATCH 300/617] Route 10G link status to LEDs --- example/VCU108/fpga_10g/rtl/fpga.v | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/example/VCU108/fpga_10g/rtl/fpga.v b/example/VCU108/fpga_10g/rtl/fpga.v index bedc0441e..2401d5d86 100644 --- a/example/VCU108/fpga_10g/rtl/fpga.v +++ b/example/VCU108/fpga_10g/rtl/fpga.v @@ -274,6 +274,7 @@ wire [7:0] qsfp_rxc_4_int = 8'hff; wire [535:0] configuration_vector; wire [447:0] status_vector; +wire [7:0] core_status; assign configuration_vector[0] = 1'b0; // PMA Loopback Enable assign configuration_vector[14:1] = 0; @@ -378,7 +379,7 @@ ten_gig_eth_pcs_pma_inst ( .configuration_vector(configuration_vector), .status_vector(status_vector), .pma_pmd_type(3'b101), - .core_status() + .core_status(core_status) ); // SGMII interface to PHY @@ -467,6 +468,10 @@ gig_eth_pcspma ( .signal_detect (1'b1) ); +wire [7:0] led_int; + +assign led = sw[0] ? {7'd0, core_status[0]} : led_int; + fpga_core core_inst ( /* @@ -484,7 +489,7 @@ core_inst ( .btnr(btnr_int), .btnc(btnc_int), .sw(sw_int), - .led(led), + .led(led_int), /* * Ethernet: QSFP28 */ From 36af29db77c45754d30004e9a145525875bbc99b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 3 Aug 2016 14:44:10 -0400 Subject: [PATCH 301/617] Add i2c init code for si570 reference oscillator --- example/VCU108/fpga_10g/fpga.xdc | 4 +- example/VCU108/fpga_10g/fpga/Makefile | 2 + example/VCU108/fpga_10g/rtl/fpga.v | 102 ++- example/VCU108/fpga_10g/rtl/i2c_master.v | 895 +++++++++++++++++++ example/VCU108/fpga_10g/rtl/si570_i2c_init.v | 486 ++++++++++ 5 files changed, 1484 insertions(+), 5 deletions(-) create mode 100644 example/VCU108/fpga_10g/rtl/i2c_master.v create mode 100644 example/VCU108/fpga_10g/rtl/si570_i2c_init.v diff --git a/example/VCU108/fpga_10g/fpga.xdc b/example/VCU108/fpga_10g/fpga.xdc index 185c0ad2f..e28e4aa93 100644 --- a/example/VCU108/fpga_10g/fpga.xdc +++ b/example/VCU108/fpga_10g/fpga.xdc @@ -106,7 +106,7 @@ set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp_intl] set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp_lpmode] # I2C interface -#set_property -dict {LOC AN21 IOSTANDARD LVCMOS18} [get_ports i2c_scl] -#set_property -dict {LOC AP21 IOSTANDARD LVCMOS18} [get_ports i2c_sda] +set_property -dict {LOC AN21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_scl] +set_property -dict {LOC AP21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_sda] diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 70fe2f090..ef3b2397d 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -10,6 +10,8 @@ SYN_FILES += rtl/fpga_core.v SYN_FILES += rtl/debounce_switch.v SYN_FILES += rtl/sync_reset.v SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/i2c_master.v +SYN_FILES += rtl/si570_i2c_init.v SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v diff --git a/example/VCU108/fpga_10g/rtl/fpga.v b/example/VCU108/fpga_10g/rtl/fpga.v index 2401d5d86..02eac4779 100644 --- a/example/VCU108/fpga_10g/rtl/fpga.v +++ b/example/VCU108/fpga_10g/rtl/fpga.v @@ -52,8 +52,8 @@ module fpga ( /* * I2C for board management */ - // inout wire i2c_scl, - // inout wire i2c_sda, + inout wire i2c_scl, + inout wire i2c_sda, /* * Ethernet: QSFP28 @@ -250,6 +250,102 @@ sync_signal_inst ( .out({uart_rxd_int, uart_cts_int}) ); +// SI570 I2C +wire i2c_scl_i; +wire i2c_scl_o; +wire i2c_scl_t; +wire i2c_sda_i; +wire i2c_sda_o; +wire i2c_sda_t; + +assign i2c_scl_i = i2c_scl; +assign i2c_scl = i2c_scl_t ? 1'bz : i2c_scl_o; +assign i2c_sda_i = i2c_sda; +assign i2c_sda = i2c_sda_t ? 1'bz : i2c_sda_o; + +wire [6:0] si570_i2c_cmd_address; +wire si570_i2c_cmd_start; +wire si570_i2c_cmd_read; +wire si570_i2c_cmd_write; +wire si570_i2c_cmd_write_multiple; +wire si570_i2c_cmd_stop; +wire si570_i2c_cmd_valid; +wire si570_i2c_cmd_ready; + +wire [7:0] si570_i2c_data; +wire si570_i2c_data_valid; +wire si570_i2c_data_ready; +wire si570_i2c_data_last; + +wire si570_i2c_init_busy; + +// delay start by ~10 ms +reg [20:0] si570_i2c_init_start_delay = 21'd0; + +always @(posedge clk_125mhz_int) begin + if (rst_125mhz_int) begin + si570_i2c_init_start_delay <= 21'd0; + end else begin + if (!si570_i2c_init_start_delay[20]) begin + si570_i2c_init_start_delay <= si570_i2c_init_start_delay + 21'd1; + end + end +end + +si570_i2c_init +si570_i2c_init_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .cmd_address(si570_i2c_cmd_address), + .cmd_start(si570_i2c_cmd_start), + .cmd_read(si570_i2c_cmd_read), + .cmd_write(si570_i2c_cmd_write), + .cmd_write_multiple(si570_i2c_cmd_write_multiple), + .cmd_stop(si570_i2c_cmd_stop), + .cmd_valid(si570_i2c_cmd_valid), + .cmd_ready(si570_i2c_cmd_ready), + .data_out(si570_i2c_data), + .data_out_valid(si570_i2c_data_valid), + .data_out_ready(si570_i2c_data_ready), + .data_out_last(si570_i2c_data_last), + .busy(si570_i2c_init_busy), + .start(si570_i2c_init_start_delay[20]) +); + +i2c_master +si570_i2c_master ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .cmd_address(si570_i2c_cmd_address), + .cmd_start(si570_i2c_cmd_start), + .cmd_read(si570_i2c_cmd_read), + .cmd_write(si570_i2c_cmd_write), + .cmd_write_multiple(si570_i2c_cmd_write_multiple), + .cmd_stop(si570_i2c_cmd_stop), + .cmd_valid(si570_i2c_cmd_valid), + .cmd_ready(si570_i2c_cmd_ready), + .data_in(si570_i2c_data), + .data_in_valid(si570_i2c_data_valid), + .data_in_ready(si570_i2c_data_ready), + .data_in_last(si570_i2c_data_last), + .data_out(), + .data_out_valid(), + .data_out_ready(1), + .data_out_last(), + .scl_i(i2c_scl_i), + .scl_o(i2c_scl_o), + .scl_t(i2c_scl_t), + .sda_i(i2c_sda_i), + .sda_o(i2c_sda_o), + .sda_t(i2c_sda_t), + .busy(), + .bus_control(), + .bus_active(), + .missed_ack(), + .prescale(800), + .stop_on_idle(1) +); + // XGMII 10G PHY assign qsfp_modesell = 1'b1; assign qsfp_resetl = 1'b1; @@ -322,7 +418,7 @@ ten_gig_eth_pcs_pma_inst ( .coreclk_out(), - .reset(rst_125mhz_int), + .reset(rst_125mhz_int | si570_i2c_init_busy), .sim_speedup_control(1'b0), diff --git a/example/VCU108/fpga_10g/rtl/i2c_master.v b/example/VCU108/fpga_10g/rtl/i2c_master.v new file mode 100644 index 000000000..4a6b945c1 --- /dev/null +++ b/example/VCU108/fpga_10g/rtl/i2c_master.v @@ -0,0 +1,895 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * I2C master + */ +module i2c_master ( + input wire clk, + input wire rst, + + /* + * Host interface + */ + input wire [6:0] cmd_address, + input wire cmd_start, + input wire cmd_read, + input wire cmd_write, + input wire cmd_write_multiple, + input wire cmd_stop, + input wire cmd_valid, + output wire cmd_ready, + + input wire [7:0] data_in, + input wire data_in_valid, + output wire data_in_ready, + input wire data_in_last, + + output wire [7:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + output wire data_out_last, + + /* + * I2C interface + */ + input wire scl_i, + output wire scl_o, + output wire scl_t, + input wire sda_i, + output wire sda_o, + output wire sda_t, + + /* + * Status + */ + output wire busy, + output wire bus_control, + output wire bus_active, + output wire missed_ack, + + /* + * Configuration + */ + input wire [15:0] prescale, + input wire stop_on_idle +); + +/* + +I2C + +Read + __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ +sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_\_R___A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A____/ + ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ +scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP + +Write + __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ +sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_/_W_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_/_N_\__/ + ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ +scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP + +Commands: + +read + read data byte + set start to force generation of a start condition + start is implied when bus is inactive or active with write or different address + set stop to issue a stop condition after reading current byte + if stop is set with read command, then data_out_last will be set + +write + write data byte + set start to force generation of a start condition + start is implied when bus is inactive or active with read or different address + set stop to issue a stop condition after writing current byte + +write multiple + write multiple data bytes (until data_in_last) + set start to force generation of a start condition + start is implied when bus is inactive or active with read or different address + set stop to issue a stop condition after writing block + +stop + issue stop condition if bus is active + +Status: + +busy + module is communicating over the bus + +bus_control + module has control of bus in active state + +bus_active + bus is active, not necessarily controlled by this module + +missed_ack + strobed when a slave ack is missed + +Parameters: + +prescale + set prescale to 1/4 of the minimum clock period in units + of input clk cycles (prescale = Fclk / (FI2Cclk * 4)) + +stop_on_idle + automatically issue stop when command input is not valid + +Example of interfacing with tristate pins: +(this will work for any tristate bus) + +assign scl_i = scl_pin; +assign scl_pin = scl_t ? 1'bz : scl_o; +assign sda_i = sda_pin; +assign sda_pin = sda_t ? 1'bz : sda_o; + +Equivalent code that does not use *_t connections: +(we can get away with this because I2C is open-drain) + +assign scl_i = scl_pin; +assign scl_pin = scl_o ? 1'bz : 1'b0; +assign sda_i = sda_pin; +assign sda_pin = sda_o ? 1'bz : 1'b0; + +Example of two interconnected I2C devices: + +assign scl_1_i = scl_1_o & scl_2_o; +assign scl_2_i = scl_1_o & scl_2_o; +assign sda_1_i = sda_1_o & sda_2_o; +assign sda_2_i = sda_1_o & sda_2_o; + +Example of two I2C devices sharing the same pins: + +assign scl_1_i = scl_pin; +assign scl_2_i = scl_pin; +assign scl_pin = (scl_1_o & scl_2_o) ? 1'bz : 1'b0; +assign sda_1_i = sda_pin; +assign sda_2_i = sda_pin; +assign sda_pin = (sda_1_o & sda_2_o) ? 1'bz : 1'b0; + +Notes: + +scl_o should not be connected directly to scl_i, only via AND logic or a tristate +I/O pin. This would prevent devices from stretching the clock period. + +*/ + +localparam [4:0] + STATE_IDLE = 4'd0, + STATE_ACTIVE_WRITE = 4'd1, + STATE_ACTIVE_READ = 4'd2, + STATE_START_WAIT = 4'd3, + STATE_START = 4'd4, + STATE_ADDRESS_1 = 4'd5, + STATE_ADDRESS_2 = 4'd6, + STATE_WRITE_1 = 4'd7, + STATE_WRITE_2 = 4'd8, + STATE_WRITE_3 = 4'd9, + STATE_READ = 4'd10, + STATE_STOP = 4'd11; + +reg [4:0] state_reg = STATE_IDLE, state_next; + +localparam [4:0] + PHY_STATE_IDLE = 5'd0, + PHY_STATE_ACTIVE = 5'd1, + PHY_STATE_REPEATED_START_1 = 5'd2, + PHY_STATE_REPEATED_START_2 = 5'd3, + PHY_STATE_START_1 = 5'd4, + PHY_STATE_START_2 = 5'd5, + PHY_STATE_WRITE_BIT_1 = 5'd6, + PHY_STATE_WRITE_BIT_2 = 5'd7, + PHY_STATE_WRITE_BIT_3 = 5'd8, + PHY_STATE_READ_BIT_1 = 5'd9, + PHY_STATE_READ_BIT_2 = 5'd10, + PHY_STATE_READ_BIT_3 = 5'd11, + PHY_STATE_READ_BIT_4 = 5'd12, + PHY_STATE_STOP_1 = 5'd13, + PHY_STATE_STOP_2 = 5'd14, + PHY_STATE_STOP_3 = 5'd15; + +reg [4:0] phy_state_reg = STATE_IDLE, phy_state_next; + +reg phy_start_bit; +reg phy_stop_bit; +reg phy_write_bit; +reg phy_read_bit; +reg phy_release_bus; + +reg phy_tx_data; + +reg phy_rx_data_reg = 1'b0, phy_rx_data_next; + +reg [6:0] addr_reg = 7'd0, addr_next; +reg [7:0] data_reg = 8'd0, data_next; +reg last_reg = 1'b0, last_next; + +reg mode_read_reg = 1'b0, mode_read_next; +reg mode_write_multiple_reg = 1'b0, mode_write_multiple_next; +reg mode_stop_reg = 1'b0, mode_stop_next; + +reg [16:0] delay_reg = 16'd0, delay_next; +reg delay_scl_reg = 1'b0, delay_scl_next; +reg delay_sda_reg = 1'b0, delay_sda_next; + +reg [3:0] bit_count_reg = 4'd0, bit_count_next; + +reg cmd_ready_reg = 1'b0, cmd_ready_next; + +reg data_in_ready_reg = 1'b0, data_in_ready_next; + +reg [7:0] data_out_reg = 8'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; +reg data_out_last_reg = 1'b0, data_out_last_next; + +reg scl_i_reg = 1'b1; +reg sda_i_reg = 1'b1; + +reg scl_o_reg = 1'b1, scl_o_next; +reg sda_o_reg = 1'b1, sda_o_next; + +reg last_scl_i_reg = 1'b1; +reg last_sda_i_reg = 1'b1; + +reg busy_reg = 1'b0; +reg bus_active_reg = 1'b0; +reg bus_control_reg = 1'b0, bus_control_next; +reg missed_ack_reg = 1'b0, missed_ack_next; + +assign cmd_ready = cmd_ready_reg; + +assign data_in_ready = data_in_ready_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; +assign data_out_last = data_out_last_reg; + +assign scl_o = scl_o_reg; +assign scl_t = scl_o_reg; +assign sda_o = sda_o_reg; +assign sda_t = sda_o_reg; + +assign busy = busy_reg; +assign bus_active = bus_active_reg; +assign bus_control = bus_control_reg; +assign missed_ack = missed_ack_reg; + +wire scl_posedge = scl_i_reg & ~last_scl_i_reg; +wire scl_negedge = ~scl_i_reg & last_scl_i_reg; +wire sda_posedge = sda_i_reg & ~last_sda_i_reg; +wire sda_negedge = ~sda_i_reg & last_sda_i_reg; + +wire start_bit = sda_negedge & scl_i_reg; +wire stop_bit = sda_posedge & scl_i_reg; + +always @* begin + state_next = STATE_IDLE; + + phy_start_bit = 1'b0; + phy_stop_bit = 1'b0; + phy_write_bit = 1'b0; + phy_read_bit = 1'b0; + phy_tx_data = 1'b0; + phy_release_bus = 1'b0; + + addr_next = addr_reg; + data_next = data_reg; + last_next = last_reg; + + mode_read_next = mode_read_reg; + mode_write_multiple_next = mode_write_multiple_reg; + mode_stop_next = mode_stop_reg; + + bit_count_next = bit_count_reg; + + cmd_ready_next = 1'b0; + + data_in_ready_next = 1'b0; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + data_out_last_next = data_out_last_reg; + + missed_ack_next = 1'b0; + + // generate delays + if (phy_state_reg != PHY_STATE_IDLE && phy_state_reg != PHY_STATE_ACTIVE) begin + // wait for phy operation + state_next = state_reg; + end else begin + // process states + case (state_reg) + STATE_IDLE: begin + // line idle + cmd_ready_next = 1'b1; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + // start bit + if (bus_active) begin + state_next = STATE_START_WAIT; + end else begin + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + end else begin + // invalid or unspecified - ignore + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_ACTIVE_WRITE: begin + // line active with current address and read/write mode + cmd_ready_next = 1'b1; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + if (cmd_start || cmd_address != addr_reg || cmd_read) begin + // address or mode mismatch or forced start - repeated start + + // repeated start bit + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end else begin + // address and mode match + + // start write + data_in_ready_next = 1'b1; + state_next = STATE_WRITE_1; + end + end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin + // stop command + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + // invalid or unspecified - ignore + state_next = STATE_ACTIVE_WRITE; + end + end else begin + if (stop_on_idle & cmd_ready & ~cmd_valid) begin + // no waiting command and stop_on_idle selected, issue stop condition + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + state_next = STATE_ACTIVE_WRITE; + end + end + end + STATE_ACTIVE_READ: begin + // line active to current address + cmd_ready_next = ~data_out_valid; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + if (cmd_start || cmd_address != addr_reg || cmd_write) begin + // address or mode mismatch or forced start - repeated start + + // write nack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // repeated start bit + state_next = STATE_START; + end else begin + // address and mode match + + // write ack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b0; + // start next read + bit_count_next = 4'd8; + data_next = 8'd0; + state_next = STATE_READ; + end + end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin + // stop command + // write nack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // send stop bit + state_next = STATE_STOP; + end else begin + // invalid or unspecified - ignore + state_next = STATE_ACTIVE_READ; + end + end else begin + if (stop_on_idle & cmd_ready & ~cmd_valid) begin + // no waiting command and stop_on_idle selected, issue stop condition + // write ack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // send stop bit + state_next = STATE_STOP; + end else begin + state_next = STATE_ACTIVE_READ; + end + end + end + STATE_START_WAIT: begin + // wait for bus idle + + if (bus_active) begin + state_next = STATE_START_WAIT; + end else begin + // bus is idle, take control + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + end + STATE_START: begin + // send start bit + + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + STATE_ADDRESS_1: begin + // send address + bit_count_next = bit_count_reg - 1; + if (bit_count_reg > 1) begin + // send address + phy_write_bit = 1'b1; + phy_tx_data = addr_reg[bit_count_reg-2]; + state_next = STATE_ADDRESS_1; + end else if (bit_count_reg > 0) begin + // send read/write bit + phy_write_bit = 1'b1; + phy_tx_data = mode_read_reg; + state_next = STATE_ADDRESS_1; + end else begin + // read ack bit + phy_read_bit = 1'b1; + state_next = STATE_ADDRESS_2; + end + end + STATE_ADDRESS_2: begin + // read ack bit + missed_ack_next = phy_rx_data_reg; + + if (mode_read_reg) begin + // start read + bit_count_next = 4'd8; + data_next = 1'b0; + state_next = STATE_READ; + end else begin + // start write + data_in_ready_next = 1'b1; + state_next = STATE_WRITE_1; + end + end + STATE_WRITE_1: begin + data_in_ready_next = 1'b1; + + if (data_in_ready & data_in_valid) begin + // got data, start write + data_next = data_in; + last_next = data_in_last; + bit_count_next = 4'd8; + data_in_ready_next = 1'b0; + state_next = STATE_WRITE_2; + end else begin + // wait for data + state_next = STATE_WRITE_1; + end + end + STATE_WRITE_2: begin + // send data + bit_count_next = bit_count_reg - 1; + if (bit_count_reg > 0) begin + // write data bit + phy_write_bit = 1'b1; + phy_tx_data = data_reg[bit_count_reg-1]; + state_next = STATE_WRITE_2; + end else begin + // read ack bit + phy_read_bit = 1'b1; + state_next = STATE_WRITE_3; + end + end + STATE_WRITE_3: begin + // read ack bit + missed_ack_next = phy_rx_data_reg; + + if (mode_write_multiple_reg && !last_reg) begin + // more to write + state_next = STATE_WRITE_1; + end else if (mode_stop_reg) begin + // last cycle and stop selected + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + // otherwise, return to bus active state + state_next = STATE_ACTIVE_WRITE; + end + end + STATE_READ: begin + // read data + + bit_count_next = bit_count_reg - 1; + data_next = {data_reg[6:0], phy_rx_data_reg}; + if (bit_count_reg > 0) begin + // read next bit + phy_read_bit = 1'b1; + state_next = STATE_READ; + end else begin + // output data word + data_out_next = data_next; + data_out_valid_next = 1'b1; + data_out_last_next = 1'b0; + if (mode_stop_reg) begin + // send nack and stop + data_out_last_next = 1'b1; + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + state_next = STATE_STOP; + end else begin + // return to bus active state + state_next = STATE_ACTIVE_READ; + end + end + end + STATE_STOP: begin + // send stop bit + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end + endcase + end +end + +always @* begin + phy_state_next = PHY_STATE_IDLE; + + phy_rx_data_next = phy_rx_data_reg; + + delay_next = delay_reg; + delay_scl_next = delay_scl_reg; + delay_sda_next = delay_sda_reg; + + scl_o_next = scl_o_reg; + sda_o_next = sda_o_reg; + + bus_control_next = bus_control_reg; + + if (phy_release_bus) begin + // release bus and return to idle state + sda_o_next = 1'b1; + scl_o_next = 1'b1; + delay_scl_next = 1'b0; + delay_sda_next = 1'b0; + delay_next = 1'b0; + phy_state_next = PHY_STATE_IDLE; + end else if (delay_scl_reg) begin + // wait for SCL to match command + delay_scl_next = scl_o_reg & ~scl_i_reg; + phy_state_next = phy_state_reg; + end else if (delay_sda_reg) begin + // wait for SDA to match command + delay_sda_next = sda_o_reg & ~sda_i_reg; + phy_state_next = phy_state_reg; + end else if (delay_reg > 0) begin + // time delay + delay_next = delay_reg - 1; + phy_state_next = phy_state_reg; + end else begin + case (phy_state_reg) + PHY_STATE_IDLE: begin + // bus idle - wait for start command + sda_o_next = 1'b1; + scl_o_next = 1'b1; + if (phy_start_bit) begin + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_1; + end else begin + phy_state_next = PHY_STATE_IDLE; + end + end + PHY_STATE_ACTIVE: begin + // bus active + if (phy_start_bit) begin + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_REPEATED_START_1; + end else if (phy_write_bit) begin + sda_o_next = phy_tx_data; + delay_next = prescale; + phy_state_next = PHY_STATE_WRITE_BIT_1; + end else if (phy_read_bit) begin + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_1; + end else if (phy_stop_bit) begin + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_1; + end else begin + phy_state_next = PHY_STATE_ACTIVE; + end + end + PHY_STATE_REPEATED_START_1: begin + // generate repeated start bit + // ______ + // sda XXX/ \_______ + // _______ + // scl ______/ \___ + // + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_REPEATED_START_2; + end + PHY_STATE_REPEATED_START_2: begin + // generate repeated start bit + // ______ + // sda XXX/ \_______ + // _______ + // scl ______/ \___ + // + + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_1; + end + PHY_STATE_START_1: begin + // generate start bit + // ___ + // sda \_______ + // _______ + // scl \___ + // + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_2; + end + PHY_STATE_START_2: begin + // generate start bit + // ___ + // sda \_______ + // _______ + // scl \___ + // + + bus_control_next = 1'b1; + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_WRITE_BIT_1: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale << 1; + phy_state_next = PHY_STATE_WRITE_BIT_2; + end + PHY_STATE_WRITE_BIT_2: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_WRITE_BIT_3; + end + PHY_STATE_WRITE_BIT_3: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_READ_BIT_1: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_2; + end + PHY_STATE_READ_BIT_2: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_rx_data_next = sda_i_reg; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_3; + end + PHY_STATE_READ_BIT_3: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_4; + end + PHY_STATE_READ_BIT_4: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_STOP_1: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_2; + end + PHY_STATE_STOP_2: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_3; + end + PHY_STATE_STOP_3: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + bus_control_next = 1'b0; + phy_state_next = PHY_STATE_IDLE; + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + phy_state_reg <= PHY_STATE_IDLE; + delay_reg <= 16'd0; + delay_scl_reg <= 1'b0; + delay_sda_reg <= 1'b0; + cmd_ready_reg <= 1'b0; + data_in_ready_reg <= 1'b0; + data_out_valid_reg <= 1'b0; + scl_o_reg <= 1'b1; + sda_o_reg <= 1'b1; + busy_reg <= 1'b0; + bus_active_reg <= 1'b0; + bus_control_reg <= 1'b0; + missed_ack_reg <= 1'b0; + end else begin + state_reg <= state_next; + phy_state_reg <= phy_state_next; + + delay_reg <= delay_next; + delay_scl_reg <= delay_scl_next; + delay_sda_reg <= delay_sda_next; + + cmd_ready_reg <= cmd_ready_next; + data_in_ready_reg <= data_in_ready_next; + data_out_valid_reg <= data_out_valid_next; + + scl_o_reg <= scl_o_next; + sda_o_reg <= sda_o_next; + + busy_reg <= !(state_reg == STATE_IDLE || state_reg == STATE_ACTIVE_WRITE || state_reg == STATE_ACTIVE_READ); + + if (start_bit) begin + bus_active_reg <= 1'b1; + end else if (stop_bit) begin + bus_active_reg <= 1'b0; + end else begin + bus_active_reg <= bus_active_reg; + end + + bus_control_reg <= bus_control_next; + missed_ack_reg <= missed_ack_next; + end + + phy_rx_data_reg <= phy_rx_data_next; + + addr_reg <= addr_next; + data_reg <= data_next; + last_reg <= last_next; + + mode_read_reg <= mode_read_next; + mode_write_multiple_reg <= mode_write_multiple_next; + mode_stop_reg <= mode_stop_next; + + bit_count_reg <= bit_count_next; + + data_out_reg <= data_out_next; + data_out_last_reg <= data_out_last_next; + + scl_i_reg <= scl_i; + sda_i_reg <= sda_i; + last_scl_i_reg <= scl_i_reg; + last_sda_i_reg <= sda_i_reg; +end + +endmodule diff --git a/example/VCU108/fpga_10g/rtl/si570_i2c_init.v b/example/VCU108/fpga_10g/rtl/si570_i2c_init.v new file mode 100644 index 000000000..afa5b6121 --- /dev/null +++ b/example/VCU108/fpga_10g/rtl/si570_i2c_init.v @@ -0,0 +1,486 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * si570_i2c_init + */ +module si570_i2c_init ( + input wire clk, + input wire rst, + + /* + * I2C master interface + */ + output wire [6:0] cmd_address, + output wire cmd_start, + output wire cmd_read, + output wire cmd_write, + output wire cmd_write_multiple, + output wire cmd_stop, + output wire cmd_valid, + input wire cmd_ready, + + output wire [7:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + output wire data_out_last, + + /* + * Status + */ + output wire busy, + + /* + * Configuration + */ + input wire start +); + +/* + +Generic module for I2C bus initialization. Good for use when multiple devices +on an I2C bus must be initialized on system start without intervention of a +general-purpose processor. + +Copy this file and change init_data and INIT_DATA_LEN as needed. + +This module can be used in two modes: simple device initalization, or multiple +device initialization. In multiple device mode, the same initialization sequence +can be performed on multiple different device addresses. + +To use single device mode, only use the start write to address and write data commands. +The module will generate the I2C commands in sequential order. Terminate the list +with a 0 entry. + +To use the multiple device mode, use the start data and start address block commands +to set up lists of initialization data and device addresses. The module enters +multiple device mode upon seeing a start data block command. The module stores the +offset of the start of the data block and then skips ahead until it reaches a start +address block command. The module will store the offset to the address block and +read the first address in the block. Then it will jump back to the data block +and execute it, substituting the stored address for each current address write +command. Upon reaching the start address block command, the module will read out the +next address and start again at the top of the data block. If the module encounters +a start data block command while looking for an address, then it will store a new data +offset and then look for a start address block command. Terminate the list with a 0 +entry. Normal address commands will operate normally inside a data block. + +Commands: + +00 0000000 : stop +00 0000001 : exit multiple device mode +00 0000011 : start write to current address +00 0001000 : start address block +00 0001001 : start data block +00 1000001 : send I2C stop +01 aaaaaaa : start write to address +1 dddddddd : write 8-bit data + +Examples + +write 0x11223344 to register 0x0004 on device at 0x50 + +01 1010000 start write to 0x50 +1 00000000 write address 0x0004 +1 00000100 +1 00010001 write data 0x11223344 +1 00100010 +1 00110011 +1 01000100 +0 00000000 stop + +write 0x11223344 to register 0x0004 on devices at 0x50, 0x51, 0x52, and 0x53 + +00 0001001 start data block +00 0000011 start write to current address +1 00000100 +1 00010001 write data 0x11223344 +1 00100010 +1 00110011 +1 01000100 +00 0001000 start address block +01 1010000 address 0x50 +01 1010000 address 0x51 +01 1010000 address 0x52 +01 1010000 address 0x53 +00 0000000 stop + +*/ + +// init_data ROM +localparam INIT_DATA_LEN = 24; + +reg [8:0] init_data [INIT_DATA_LEN-1:0]; + +initial begin + // set up I2C muxes to select U32 + init_data[0] = {2'b01, 7'b1110101}; // select U80 (0x75) + init_data[1] = {1'b1, 8'b00000000}; // disconnect all outputs + init_data[2] = {2'b00, 7'b1000001}; // I2C stop + init_data[3] = {2'b01, 7'b1110100}; // select U28 (0x74) + init_data[4] = {1'b1, 8'b00000001}; // connect only output 0 to SI570 + init_data[5] = {2'b00, 7'b1000001}; // I2C stop + // set SI570 output frequency (U32) + // freeze DCO + init_data[6] = {2'b01, 7'b1011101}; + init_data[7] = {1'b1, 8'd137}; + init_data[8] = {1'b1, 8'h10}; // 137: 0x10 + // set output to 156.25 MHz (HS_DIV=4 N1=8 DCO=5000.0 RFREQ=0x02BC035168) + init_data[9] = {2'b01, 7'b1011101}; + init_data[10] = {1'b1, 8'd7}; + init_data[11] = {1'b1, 8'h01}; // 7: HS_DIV[2:0], N1[6:2] + init_data[12] = {1'b1, 8'hC2}; // 8: N1[1:0], RFREQ[37:32] + init_data[13] = {1'b1, 8'hBC}; // 9: RFREQ[31:24] + init_data[14] = {1'b1, 8'h03}; // 10: RFREQ[23:16] + init_data[15] = {1'b1, 8'h51}; // 11: RFREQ[15:8] + init_data[16] = {1'b1, 8'h68}; // 12: RFREQ[7:0] + // un-freeze DCO + init_data[17] = {2'b01, 7'b1011101}; + init_data[18] = {1'b1, 8'd137}; + init_data[19] = {1'b1, 8'h00}; // 137: 0x00 + // new frequency + init_data[20] = {2'b01, 7'b1011101}; + init_data[21] = {1'b1, 8'd135}; + init_data[22] = {1'b1, 8'h40}; // 135: 0x40 + init_data[23] = 9'd0; // stop +end + +localparam [3:0] + STATE_IDLE = 3'd0, + STATE_RUN = 3'd1, + STATE_TABLE_1 = 3'd2, + STATE_TABLE_2 = 3'd3, + STATE_TABLE_3 = 3'd4; + +reg [4:0] state_reg = STATE_IDLE, state_next; + +parameter AW = $clog2(INIT_DATA_LEN); + +reg [8:0] init_data_reg = 9'd0; + +reg [AW-1:0] address_reg = {AW{1'b0}}, address_next; +reg [AW-1:0] address_ptr_reg = {AW{1'b0}}, address_ptr_next; +reg [AW-1:0] data_ptr_reg = {AW{1'b0}}, data_ptr_next; + +reg [6:0] cur_address_reg = 7'd0, cur_address_next; + +reg [6:0] cmd_address_reg = 7'd0, cmd_address_next; +reg cmd_start_reg = 1'b0, cmd_start_next; +reg cmd_write_reg = 1'b0, cmd_write_next; +reg cmd_stop_reg = 1'b0, cmd_stop_next; +reg cmd_valid_reg = 1'b0, cmd_valid_next; + +reg [7:0] data_out_reg = 8'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; + +reg start_flag_reg = 1'b0, start_flag_next; + +reg busy_reg = 1'b0; + +assign cmd_address = cmd_address_reg; +assign cmd_start = cmd_start_reg; +assign cmd_read = 1'b0; +assign cmd_write = cmd_write_reg; +assign cmd_write_multiple = 1'b0; +assign cmd_stop = cmd_stop_reg; +assign cmd_valid = cmd_valid_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; +assign data_out_last = 1'b1; + +assign busy = busy_reg; + +always @* begin + state_next = STATE_IDLE; + + address_next = address_reg; + address_ptr_next = address_ptr_reg; + data_ptr_next = data_ptr_reg; + + cur_address_next = cur_address_reg; + + cmd_address_next = cmd_address_reg; + cmd_start_next = cmd_start_reg & ~(cmd_valid & cmd_ready); + cmd_write_next = cmd_write_reg & ~(cmd_valid & cmd_ready); + cmd_stop_next = cmd_stop_reg & ~(cmd_valid & cmd_ready); + cmd_valid_next = cmd_valid_reg & ~cmd_ready; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + + start_flag_next = start_flag_reg; + + if (cmd_valid | data_out_valid) begin + // wait for output registers to clear + state_next = state_reg; + end else begin + case (state_reg) + STATE_IDLE: begin + // wait for start signal + if (~start_flag_reg & start) begin + address_next = {AW{1'b0}}; + start_flag_next = 1'b1; + state_next = STATE_RUN; + end else begin + state_next = STATE_IDLE; + end + end + STATE_RUN: begin + // process commands + if (init_data_reg[8] == 1'b1) begin + // write data + cmd_write_next = 1'b1; + cmd_stop_next = 1'b0; + cmd_valid_next = 1'b1; + + data_out_next = init_data_reg[7:0]; + data_out_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg[8:7] == 2'b01) begin + // write address + cmd_address_next = init_data_reg[6:0]; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg == 9'b001000001) begin + // send stop + cmd_write_next = 1'b0; + cmd_start_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_RUN; + end + end + STATE_TABLE_1: begin + // find address table start + if (init_data_reg == 9'b000001000) begin + // address table start + address_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_2; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end + end + STATE_TABLE_2: begin + // find next address + if (init_data_reg[8:7] == 2'b01) begin + // write address command + // store address and move to data table + cur_address_next = init_data_reg[6:0]; + address_ptr_next = address_reg + 1; + address_next = data_ptr_reg; + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'd1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_2; + end + end + STATE_TABLE_3: begin + // process data table with selected address + if (init_data_reg[8] == 1'b1) begin + // write data + cmd_write_next = 1'b1; + cmd_stop_next = 1'b0; + cmd_valid_next = 1'b1; + + data_out_next = init_data_reg[7:0]; + data_out_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg[8:7] == 2'b01) begin + // write address + cmd_address_next = init_data_reg[6:0]; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000000011) begin + // write current address + cmd_address_next = cur_address_reg; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b001000001) begin + // send stop + cmd_write_next = 1'b0; + cmd_start_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'b000001000) begin + // address table start + address_next = address_ptr_reg; + state_next = STATE_TABLE_2; + end else if (init_data_reg == 9'd1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_3; + end + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + init_data_reg <= 9'd0; + + address_reg <= {AW{1'b0}}; + address_ptr_reg <= {AW{1'b0}}; + data_ptr_reg <= {AW{1'b0}}; + + cur_address_reg <= 7'd0; + + cmd_valid_reg <= 1'b0; + + data_out_valid_reg <= 1'b0; + + start_flag_reg <= 1'b0; + + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + + // read init_data ROM + init_data_reg <= init_data[address_next]; + + address_reg <= address_next; + address_ptr_reg <= address_ptr_next; + data_ptr_reg <= data_ptr_next; + + cur_address_reg <= cur_address_next; + + cmd_valid_reg <= cmd_valid_next; + + data_out_valid_reg <= data_out_valid_next; + + start_flag_reg <= start & start_flag_next; + + busy_reg <= (state_reg != STATE_IDLE); + end + + cmd_address_reg <= cmd_address_next; + cmd_start_reg <= cmd_start_next; + cmd_write_reg <= cmd_write_next; + cmd_stop_reg <= cmd_stop_next; + + data_out_reg <= data_out_next; +end + +endmodule From a961a9756a961de80239271ab5f813ee37e6a3f9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 4 Aug 2016 18:03:00 -0700 Subject: [PATCH 302/617] Add FIFO output pipeline registers to aid block RAM output timing closure --- rtl/axis_async_fifo.v | 41 +++++++++++++++++++++++++----- rtl/axis_async_fifo_64.v | 43 +++++++++++++++++++++++++------ rtl/axis_async_frame_fifo.v | 43 +++++++++++++++++++++++++------ rtl/axis_async_frame_fifo_64.v | 43 +++++++++++++++++++++++++------ rtl/axis_fifo.v | 41 +++++++++++++++++++++++++----- rtl/axis_fifo_64.v | 46 +++++++++++++++++++++++++++------- rtl/axis_frame_fifo.v | 42 +++++++++++++++++++++++++------ rtl/axis_frame_fifo_64.v | 43 +++++++++++++++++++++++++------ 8 files changed, 286 insertions(+), 56 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index fc7af9352..b27f95bc7 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -82,8 +82,11 @@ reg output_rst_sync3_reg = 1'b1; reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; reg [DATA_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; wire [DATA_WIDTH+2-1:0] mem_write_data; +reg [DATA_WIDTH+2-1:0] output_data_reg = {DATA_WIDTH+2{1'b0}}; + reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first TWO MSBs do NOT match, but rest matches @@ -97,13 +100,14 @@ wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; // control signals reg write; reg read; +reg store_output; assign input_axis_tready = ~full & ~input_rst_sync3_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = mem_read_data_reg; +assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = output_data_reg; // reset synchronization always @(posedge input_clk or posedge async_rst) begin @@ -192,18 +196,19 @@ always @* begin rd_ptr_next = rd_ptr_reg; rd_ptr_gray_next = rd_ptr_gray_reg; - output_axis_tvalid_next = output_axis_tvalid_reg; + mem_read_data_valid_next = mem_read_data_valid_reg; if (output_axis_tready | ~output_axis_tvalid) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read read = 1'b1; - output_axis_tvalid_next = 1'b1; + mem_read_data_valid_next = 1'b1; rd_ptr_next = rd_ptr_reg + 1; rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); end else begin - output_axis_tvalid_next = 1'b0; + // empty, invalidate + mem_read_data_valid_next = 1'b0; end end end @@ -212,11 +217,11 @@ always @(posedge output_clk) begin if (output_rst_sync3_reg) begin rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - output_axis_tvalid_reg <= 1'b0; + mem_read_data_valid_reg <= 1'b0; end else begin rd_ptr_reg <= rd_ptr_next; rd_ptr_gray_reg <= rd_ptr_gray_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + mem_read_data_valid_reg <= mem_read_data_valid_next; end rd_addr_reg <= rd_ptr_next; @@ -226,4 +231,28 @@ always @(posedge output_clk) begin end end +// Output register +always @* begin + store_output = 1'b0; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + store_output = 1'b1; + output_axis_tvalid_next = mem_read_data_valid_reg; + end +end + +always @(posedge output_clk) begin + if (output_rst_sync3_reg) begin + output_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (store_output) begin + output_data_reg <= mem_read_data_reg; + end +end + endmodule diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index 135cee214..bf4c65c80 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -84,9 +84,12 @@ reg output_rst_sync2_reg = 1'b1; reg output_rst_sync3_reg = 1'b1; reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+KEEP_WIDTH+2{1'b0}}; +reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_write_data; +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] output_data_reg = {DATA_WIDTH+KEEP_WIDTH+2{1'b0}}; + reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first TWO MSBs do NOT match, but rest matches @@ -100,13 +103,14 @@ wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; // control signals reg write; reg read; +reg store_output; assign input_axis_tready = ~full & ~input_rst_sync3_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = mem_read_data_reg; +assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = output_data_reg; // reset synchronization always @(posedge input_clk or posedge async_rst) begin @@ -195,18 +199,19 @@ always @* begin rd_ptr_next = rd_ptr_reg; rd_ptr_gray_next = rd_ptr_gray_reg; - output_axis_tvalid_next = output_axis_tvalid_reg; + mem_read_data_valid_next = mem_read_data_valid_reg; if (output_axis_tready | ~output_axis_tvalid) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read read = 1'b1; - output_axis_tvalid_next = 1'b1; + mem_read_data_valid_next = 1'b1; rd_ptr_next = rd_ptr_reg + 1; rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); end else begin - output_axis_tvalid_next = 1'b0; + // empty, invalidate + mem_read_data_valid_next = 1'b0; end end end @@ -215,11 +220,11 @@ always @(posedge output_clk) begin if (output_rst_sync3_reg) begin rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - output_axis_tvalid_reg <= 1'b0; + mem_read_data_valid_reg <= 1'b0; end else begin rd_ptr_reg <= rd_ptr_next; rd_ptr_gray_reg <= rd_ptr_gray_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + mem_read_data_valid_reg <= mem_read_data_valid_next; end rd_addr_reg <= rd_ptr_next; @@ -229,4 +234,28 @@ always @(posedge output_clk) begin end end +// Output register +always @* begin + store_output = 1'b0; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + store_output = 1'b1; + output_axis_tvalid_next = mem_read_data_valid_reg; + end +end + +always @(posedge output_clk) begin + if (output_rst_sync3_reg) begin + output_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (store_output) begin + output_data_reg <= mem_read_data_reg; + end +end + endmodule diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 2469e3b31..5ad1e88fa 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -92,9 +92,12 @@ reg output_rst_sync2_reg = 1'b1; reg output_rst_sync3_reg = 1'b1; reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +reg [DATA_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+1{1'b0}}; +reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; wire [DATA_WIDTH+1-1:0] mem_write_data; +reg [DATA_WIDTH+1-1:0] output_data_reg = {DATA_WIDTH+1{1'b0}}; + reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first TWO MSBs do NOT match, but rest matches @@ -111,6 +114,7 @@ wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && // control signals reg write; reg read; +reg store_output; reg drop_frame_reg = 1'b0, drop_frame_next; reg overflow_reg = 1'b0, overflow_next; @@ -135,7 +139,7 @@ assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign mem_write_data = {input_axis_tlast, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tdata} = mem_read_data_reg; +assign {output_axis_tlast, output_axis_tdata} = output_data_reg; assign input_status_overflow = overflow_reg; assign input_status_bad_frame = bad_frame_reg; @@ -308,18 +312,19 @@ always @* begin rd_ptr_next = rd_ptr_reg; rd_ptr_gray_next = rd_ptr_gray_reg; - output_axis_tvalid_next = output_axis_tvalid_reg; + mem_read_data_valid_next = mem_read_data_valid_reg; if (output_axis_tready | ~output_axis_tvalid) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read read = 1'b1; - output_axis_tvalid_next = 1'b1; + mem_read_data_valid_next = 1'b1; rd_ptr_next = rd_ptr_reg + 1; rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); end else begin - output_axis_tvalid_next = 1'b0; + // empty, invalidate + mem_read_data_valid_next = 1'b0; end end end @@ -328,11 +333,11 @@ always @(posedge output_clk) begin if (output_rst_sync3_reg) begin rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - output_axis_tvalid_reg <= 1'b0; + mem_read_data_valid_reg <= 1'b0; end else begin rd_ptr_reg <= rd_ptr_next; rd_ptr_gray_reg <= rd_ptr_gray_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + mem_read_data_valid_reg <= mem_read_data_valid_next; end rd_addr_reg <= rd_ptr_next; @@ -342,4 +347,28 @@ always @(posedge output_clk) begin end end +// Output register +always @* begin + store_output = 1'b0; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + store_output = 1'b1; + output_axis_tvalid_next = mem_read_data_valid_reg; + end +end + +always @(posedge output_clk) begin + if (output_rst_sync3_reg) begin + output_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (store_output) begin + output_data_reg <= mem_read_data_reg; + end +end + endmodule diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 5399898c3..2f2e576ee 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -95,9 +95,12 @@ reg output_rst_sync2_reg = 1'b1; reg output_rst_sync3_reg = 1'b1; reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+KEEP_WIDTH+1{1'b0}}; +reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; wire [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_write_data; +reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] output_data_reg = {DATA_WIDTH+KEEP_WIDTH+1{1'b0}}; + reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first TWO MSBs do NOT match, but rest matches @@ -114,6 +117,7 @@ wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && // control signals reg write; reg read; +reg store_output; reg drop_frame_reg = 1'b0, drop_frame_next; reg overflow_reg = 1'b0, overflow_next; @@ -138,7 +142,7 @@ assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3_reg; assign output_axis_tvalid = output_axis_tvalid_reg; assign mem_write_data = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = mem_read_data_reg; +assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = output_data_reg; assign input_status_overflow = overflow_reg; assign input_status_bad_frame = bad_frame_reg; @@ -311,18 +315,19 @@ always @* begin rd_ptr_next = rd_ptr_reg; rd_ptr_gray_next = rd_ptr_gray_reg; - output_axis_tvalid_next = output_axis_tvalid_reg; + mem_read_data_valid_next = mem_read_data_valid_reg; if (output_axis_tready | ~output_axis_tvalid) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read read = 1'b1; - output_axis_tvalid_next = 1'b1; + mem_read_data_valid_next = 1'b1; rd_ptr_next = rd_ptr_reg + 1; rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); end else begin - output_axis_tvalid_next = 1'b0; + // empty, invalidate + mem_read_data_valid_next = 1'b0; end end end @@ -331,11 +336,11 @@ always @(posedge output_clk) begin if (output_rst_sync3_reg) begin rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - output_axis_tvalid_reg <= 1'b0; + mem_read_data_valid_reg <= 1'b0; end else begin rd_ptr_reg <= rd_ptr_next; rd_ptr_gray_reg <= rd_ptr_gray_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + mem_read_data_valid_reg <= mem_read_data_valid_next; end rd_addr_reg <= rd_ptr_next; @@ -345,4 +350,28 @@ always @(posedge output_clk) begin end end +// Output register +always @* begin + store_output = 1'b0; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + store_output = 1'b1; + output_axis_tvalid_next = mem_read_data_valid_reg; + end +end + +always @(posedge output_clk) begin + if (output_rst_sync3_reg) begin + output_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (store_output) begin + output_data_reg <= mem_read_data_reg; + end +end + endmodule diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index 7bb040d24..c56b6e4f2 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -64,8 +64,11 @@ reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; reg [DATA_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; wire [DATA_WIDTH+2-1:0] mem_write_data; +reg [DATA_WIDTH+2-1:0] output_data_reg = {DATA_WIDTH+2{1'b0}}; + reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first MSB different but rest same @@ -77,13 +80,14 @@ wire empty = wr_ptr_reg == rd_ptr_reg; // control signals reg write; reg read; +reg store_output; assign input_axis_tready = ~full; assign output_axis_tvalid = output_axis_tvalid_reg; assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = mem_read_data_reg; +assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = output_data_reg; // Write logic always @* begin @@ -121,17 +125,18 @@ always @* begin rd_ptr_next = rd_ptr_reg; - output_axis_tvalid_next = output_axis_tvalid_reg; + mem_read_data_valid_next = mem_read_data_valid_reg; if (output_axis_tready | ~output_axis_tvalid) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read read = 1'b1; - output_axis_tvalid_next = 1'b1; + mem_read_data_valid_next = 1'b1; rd_ptr_next = rd_ptr_reg + 1; end else begin - output_axis_tvalid_next = 1'b0; + // empty, invalidate + mem_read_data_valid_next = 1'b0; end end end @@ -139,10 +144,10 @@ end always @(posedge clk) begin if (rst) begin rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - output_axis_tvalid_reg <= 1'b0; + mem_read_data_valid_reg <= 1'b0; end else begin rd_ptr_reg <= rd_ptr_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + mem_read_data_valid_reg <= mem_read_data_valid_next; end rd_addr_reg <= rd_ptr_next; @@ -152,4 +157,28 @@ always @(posedge clk) begin end end +// Output register +always @* begin + store_output = 1'b0; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + store_output = 1'b1; + output_axis_tvalid_next = mem_read_data_valid_reg; + end +end + +always @(posedge clk) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (store_output) begin + output_data_reg <= mem_read_data_reg; + end +end + endmodule diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v index 37f627a0e..ca7217b5a 100644 --- a/rtl/axis_fifo_64.v +++ b/rtl/axis_fifo_64.v @@ -66,9 +66,12 @@ reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+KEEP_WIDTH+2{1'b0}}; +reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_write_data; +reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] output_data_reg = {DATA_WIDTH+KEEP_WIDTH+2{1'b0}}; + reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first MSB different but rest same @@ -80,15 +83,16 @@ wire empty = wr_ptr_reg == rd_ptr_reg; // control signals reg write; reg read; +reg store_output; assign input_axis_tready = ~full; assign output_axis_tvalid = output_axis_tvalid_reg; assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = mem_read_data_reg; +assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = output_data_reg; -// FIFO write logic +// Write logic always @* begin write = 1'b0; @@ -118,24 +122,24 @@ always @(posedge clk) begin end end -// FIFO read logic +// Read logic always @* begin read = 1'b0; rd_ptr_next = rd_ptr_reg; - output_axis_tvalid_next = output_axis_tvalid_reg; + mem_read_data_valid_next = mem_read_data_valid_reg; if (output_axis_tready | ~output_axis_tvalid) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read read = 1'b1; - output_axis_tvalid_next = 1'b1; + mem_read_data_valid_next = 1'b1; rd_ptr_next = rd_ptr_reg + 1; end else begin // empty, invalidate - output_axis_tvalid_next = 1'b0; + mem_read_data_valid_next = 1'b0; end end end @@ -143,10 +147,10 @@ end always @(posedge clk) begin if (rst) begin rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - output_axis_tvalid_reg <= 1'b0; + mem_read_data_valid_reg <= 1'b0; end else begin rd_ptr_reg <= rd_ptr_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + mem_read_data_valid_reg <= mem_read_data_valid_next; end rd_addr_reg <= rd_ptr_next; @@ -156,4 +160,28 @@ always @(posedge clk) begin end end +// Output register +always @* begin + store_output = 1'b0; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + store_output = 1'b1; + output_axis_tvalid_next = mem_read_data_valid_reg; + end +end + +always @(posedge clk) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (store_output) begin + output_data_reg <= mem_read_data_reg; + end +end + endmodule diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 8c2105dbe..405a8e584 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -71,9 +71,12 @@ reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +reg [DATA_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+1{1'b0}}; +reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; wire [DATA_WIDTH+1-1:0] mem_write_data; +reg [DATA_WIDTH+1-1:0] output_data_reg = {DATA_WIDTH+1{1'b0}}; + reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first MSB different but rest same @@ -88,6 +91,7 @@ wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && // control signals reg write; reg read; +reg store_output; reg drop_frame_reg = 1'b0, drop_frame_next; reg overflow_reg = 1'b0, overflow_next; @@ -99,7 +103,7 @@ assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; assign mem_write_data = {input_axis_tlast, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tdata} = mem_read_data_reg; +assign {output_axis_tlast, output_axis_tdata} = output_data_reg; assign overflow = overflow_reg; assign bad_frame = bad_frame_reg; @@ -183,18 +187,18 @@ always @* begin rd_ptr_next = rd_ptr_reg; - output_axis_tvalid_next = output_axis_tvalid_reg; + mem_read_data_valid_next = mem_read_data_valid_reg; if (output_axis_tready | ~output_axis_tvalid) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read read = 1'b1; - output_axis_tvalid_next = 1'b1; + mem_read_data_valid_next = 1'b1; rd_ptr_next = rd_ptr_reg + 1; end else begin // empty, invalidate - output_axis_tvalid_next = 1'b0; + mem_read_data_valid_next = 1'b0; end end end @@ -202,10 +206,10 @@ end always @(posedge clk) begin if (rst) begin rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - output_axis_tvalid_reg <= 1'b0; + mem_read_data_valid_reg <= 1'b0; end else begin rd_ptr_reg <= rd_ptr_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + mem_read_data_valid_reg <= mem_read_data_valid_next; end rd_addr_reg <= rd_ptr_next; @@ -215,4 +219,28 @@ always @(posedge clk) begin end end +// Output register +always @* begin + store_output = 1'b0; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + store_output = 1'b1; + output_axis_tvalid_next = mem_read_data_valid_reg; + end +end + +always @(posedge clk) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (store_output) begin + output_data_reg <= mem_read_data_reg; + end +end + endmodule diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index c38ef7665..3d1c4623b 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -74,9 +74,12 @@ reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+KEEP_WIDTH+1{1'b0}}; +reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; wire [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_write_data; +reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] output_data_reg = {DATA_WIDTH+KEEP_WIDTH+1{1'b0}}; + reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first MSB different but rest same @@ -91,6 +94,7 @@ wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && // control signals reg write; reg read; +reg store_output; reg drop_frame_reg = 1'b0, drop_frame_next; reg overflow_reg = 1'b0, overflow_next; @@ -102,7 +106,7 @@ assign input_axis_tready = (~full | DROP_WHEN_FULL); assign output_axis_tvalid = output_axis_tvalid_reg; assign mem_write_data = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = mem_read_data_reg; +assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = output_data_reg; assign overflow = overflow_reg; assign bad_frame = bad_frame_reg; @@ -186,17 +190,18 @@ always @* begin rd_ptr_next = rd_ptr_reg; - output_axis_tvalid_next = output_axis_tvalid_reg; + mem_read_data_valid_next = mem_read_data_valid_reg; if (output_axis_tready | ~output_axis_tvalid) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read read = 1'b1; - output_axis_tvalid_next = 1'b1; + mem_read_data_valid_next = 1'b1; rd_ptr_next = rd_ptr_reg + 1; end else begin - output_axis_tvalid_next = 1'b0; + // empty, invalidate + mem_read_data_valid_next = 1'b0; end end end @@ -204,10 +209,10 @@ end always @(posedge clk) begin if (rst) begin rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - output_axis_tvalid_reg <= 1'b0; + mem_read_data_valid_reg <= 1'b0; end else begin rd_ptr_reg <= rd_ptr_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + mem_read_data_valid_reg <= mem_read_data_valid_next; end rd_addr_reg <= rd_ptr_next; @@ -217,4 +222,28 @@ always @(posedge clk) begin end end +// Output register +always @* begin + store_output = 1'b0; + + output_axis_tvalid_next = output_axis_tvalid_reg; + + if (output_axis_tready | ~output_axis_tvalid) begin + store_output = 1'b1; + output_axis_tvalid_next = mem_read_data_valid_reg; + end +end + +always @(posedge clk) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + end + + if (store_output) begin + output_data_reg <= mem_read_data_reg; + end +end + endmodule From e6d78b7ca7a0ab11ecd3798b8ea725a6931e665a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 4 Aug 2016 18:03:24 -0700 Subject: [PATCH 303/617] Add extra testbench delay --- tb/test_axis_frame_length_adjust_fifo.py | 6 ++++++ tb/test_axis_frame_length_adjust_fifo_64.py | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/tb/test_axis_frame_length_adjust_fifo.py b/tb/test_axis_frame_length_adjust_fifo.py index a84a15a57..5f7b579d5 100755 --- a/tb/test_axis_frame_length_adjust_fifo.py +++ b/tb/test_axis_frame_length_adjust_fifo.py @@ -235,6 +235,8 @@ def bench(): yield wait() + yield clk.posedge + yield clk.posedge yield clk.posedge yield clk.posedge yield clk.posedge @@ -276,6 +278,8 @@ def bench(): yield wait() + yield clk.posedge + yield clk.posedge yield clk.posedge yield clk.posedge yield clk.posedge @@ -336,6 +340,8 @@ def bench(): yield wait() + yield clk.posedge + yield clk.posedge yield clk.posedge yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_frame_length_adjust_fifo_64.py b/tb/test_axis_frame_length_adjust_fifo_64.py index 2bbffe704..53b07fc49 100755 --- a/tb/test_axis_frame_length_adjust_fifo_64.py +++ b/tb/test_axis_frame_length_adjust_fifo_64.py @@ -246,6 +246,8 @@ def bench(): yield wait() + yield clk.posedge + yield clk.posedge yield clk.posedge yield clk.posedge yield clk.posedge @@ -287,6 +289,8 @@ def bench(): yield wait() + yield clk.posedge + yield clk.posedge yield clk.posedge yield clk.posedge yield clk.posedge @@ -347,6 +351,8 @@ def bench(): yield wait() + yield clk.posedge + yield clk.posedge yield clk.posedge yield clk.posedge yield clk.posedge From 24f7aee8b2ce90dd39cd61bd324b844749a0909e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 21 Aug 2016 20:03:54 -0700 Subject: [PATCH 304/617] Add COBS encoder and decoder modules and testbench --- rtl/axis_cobs_decode.v | 328 +++++++++++++++++ rtl/axis_cobs_encode.v | 473 ++++++++++++++++++++++++ tb/test_axis_cobs_decode.py | 482 +++++++++++++++++++++++++ tb/test_axis_cobs_decode.v | 91 +++++ tb/test_axis_cobs_encode.py | 381 +++++++++++++++++++ tb/test_axis_cobs_encode.v | 94 +++++ tb/test_axis_cobs_encode_zero_frame.py | 381 +++++++++++++++++++ tb/test_axis_cobs_encode_zero_frame.v | 94 +++++ 8 files changed, 2324 insertions(+) create mode 100644 rtl/axis_cobs_decode.v create mode 100644 rtl/axis_cobs_encode.v create mode 100755 tb/test_axis_cobs_decode.py create mode 100644 tb/test_axis_cobs_decode.v create mode 100755 tb/test_axis_cobs_encode.py create mode 100644 tb/test_axis_cobs_encode.v create mode 100755 tb/test_axis_cobs_encode_zero_frame.py create mode 100644 tb/test_axis_cobs_encode_zero_frame.v diff --git a/rtl/axis_cobs_decode.v b/rtl/axis_cobs_decode.v new file mode 100644 index 000000000..b95639329 --- /dev/null +++ b/rtl/axis_cobs_decode.v @@ -0,0 +1,328 @@ +/* + +Copyright (c) 2016 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 consistent overhead byte stuffing (COBS) decoder + */ +module axis_cobs_decode +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [7: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 [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser +); + +// state register +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_SEGMENT = 2'd1, + STATE_NEXT_SEGMENT = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [7:0] count_reg = 8'd0, count_next; +reg suppress_zero_reg = 1'b0, suppress_zero_next; + +reg [7:0] temp_tdata_reg = 8'd0, temp_tdata_next; +reg temp_tvalid_reg = 1'b0, temp_tvalid_next; + +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; + +assign input_axis_tready = input_axis_tready_reg; + +always @* begin + state_next = STATE_IDLE; + + count_next = count_reg; + suppress_zero_next = suppress_zero_reg; + + temp_tdata_next = temp_tdata_reg; + temp_tvalid_next = temp_tvalid_reg; + + output_axis_tdata_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; + + input_axis_tready_next = 1'b0; + + case (state_reg) + STATE_IDLE: begin + // idle state + input_axis_tready_next = output_axis_tready_int_early | ~temp_tvalid_reg; + + // output final word + output_axis_tdata_int = temp_tdata_reg; + output_axis_tvalid_int = temp_tvalid_reg; + output_axis_tlast_int = temp_tvalid_reg; + temp_tvalid_next = temp_tvalid_reg & ~output_axis_tready_int_reg; + + if (input_axis_tready & input_axis_tvalid) begin + // valid input data + // skip any leading zeros + if (input_axis_tdata != 8'd0) begin + // store count value and zero suppress + count_next = input_axis_tdata-1; + suppress_zero_next = (input_axis_tdata == 8'd255); + input_axis_tready_next = output_axis_tready_int_early; + if (input_axis_tdata == 8'd1) begin + // next byte will be count value + state_next = STATE_NEXT_SEGMENT; + end else begin + // next byte will be data + state_next = STATE_SEGMENT; + end + end else begin + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_SEGMENT: begin + // receive segment + input_axis_tready_next = output_axis_tready_int_early; + + if (input_axis_tready & input_axis_tvalid) begin + // valid input data + // store in temp register + temp_tdata_next = input_axis_tdata; + temp_tvalid_next = 1'b1; + // move temp to output + output_axis_tdata_int = temp_tdata_reg; + output_axis_tvalid_int = temp_tvalid_reg; + // decrement count + count_next = count_reg - 1; + if (input_axis_tdata == 8'd0) begin + // got a zero byte in a frame - mark it as an error and re-sync + temp_tvalid_next = 1'b0; + output_axis_tvalid_int = 1'b1; + output_axis_tuser_int = 1'b1; + output_axis_tlast_int = 1'b1; + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end else if (input_axis_tlast) begin + // end of frame + if (count_reg == 8'd1 && ~input_axis_tuser) begin + // end of frame indication at correct time, go to idle to output final byte + state_next = STATE_IDLE; + end else begin + // end of frame indication at invalid time or tuser assert, so mark as an error and re-sync + temp_tvalid_next = 1'b0; + output_axis_tvalid_int = 1'b1; + output_axis_tuser_int = 1'b1; + output_axis_tlast_int = 1'b1; + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end else if (count_reg == 8'd1) begin + // next byte will be count value + state_next = STATE_NEXT_SEGMENT; + end else begin + // next byte will be data + state_next = STATE_SEGMENT; + end + end else begin + state_next = STATE_SEGMENT; + end + end + STATE_NEXT_SEGMENT: begin + // next segment + input_axis_tready_next = output_axis_tready_int_early; + + if (input_axis_tready & input_axis_tvalid) begin + // valid input data + // store zero in temp if not suppressed + temp_tdata_next = 8'd0; + temp_tvalid_next = ~suppress_zero_reg; + // move temp to output + output_axis_tdata_int = temp_tdata_reg; + output_axis_tvalid_int = temp_tvalid_reg; + if (input_axis_tdata == 8'd0) begin + // got a zero byte delineating the end of the frame, so mark as such and re-sync + temp_tvalid_next = 1'b0; + output_axis_tuser_int = input_axis_tuser; + output_axis_tlast_int = 1'b1; + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end else if (input_axis_tlast) begin + if (input_axis_tdata == 8'd1 && ~input_axis_tuser) begin + // end of frame indication at correct time, go to idle to output final byte + state_next = STATE_IDLE; + end else begin + // end of frame indication at invalid time or tuser assert, so mark as an error and re-sync + temp_tvalid_next = 1'b0; + output_axis_tvalid_int = 1'b1; + output_axis_tuser_int = 1'b1; + output_axis_tlast_int = 1'b1; + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end else begin + // otherwise, store count value and zero suppress + count_next = input_axis_tdata-1; + suppress_zero_next = (input_axis_tdata == 8'd255); + input_axis_tready_next = output_axis_tready_int_early; + if (input_axis_tdata == 8'd1) begin + // next byte will be count value + state_next = STATE_NEXT_SEGMENT; + end else begin + // next byte will be data + state_next = STATE_SEGMENT; + end + end + end else begin + state_next = STATE_NEXT_SEGMENT; + end + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + temp_tvalid_reg <= 1'b0; + input_axis_tready_reg <= 1'b0; + end else begin + state_reg <= state_next; + temp_tvalid_reg <= temp_tvalid_next; + input_axis_tready_reg <= input_axis_tready_next; + end + + temp_tdata_reg <= temp_tdata_next; + + count_reg <= count_next; + suppress_zero_reg <= suppress_zero_next; +end + +// output datapath logic +reg [7:0] output_axis_tdata_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; + +reg [7:0] temp_axis_tdata_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/axis_cobs_encode.v b/rtl/axis_cobs_encode.v new file mode 100644 index 000000000..390e72a80 --- /dev/null +++ b/rtl/axis_cobs_encode.v @@ -0,0 +1,473 @@ +/* + +Copyright (c) 2016 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 consistent overhead byte stuffing (COBS) encoder + */ +module axis_cobs_encode # +( + // append zero for in band framing + parameter APPEND_ZERO = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [7: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 [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser +); + +// state register +localparam [1:0] + INPUT_STATE_IDLE = 2'd0, + INPUT_STATE_SEGMENT = 2'd1, + INPUT_STATE_FINAL_ZERO = 2'd2, + INPUT_STATE_APPEND_ZERO = 2'd3; + +reg [1:0] input_state_reg = INPUT_STATE_IDLE, input_state_next; + +localparam [0:0] + OUTPUT_STATE_IDLE = 1'd0, + OUTPUT_STATE_SEGMENT = 1'd1; + +reg [0:0] output_state_reg = OUTPUT_STATE_IDLE, output_state_next; + +reg [7:0] input_count_reg = 8'd0, input_count_next; +reg [7:0] output_count_reg = 8'd0, output_count_next; +reg fail_frame_reg = 1'b0, fail_frame_next; + +// internal datapath +reg [7:0] output_axis_tdata_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg output_axis_tuser_int; +wire output_axis_tready_int_early; + +reg input_axis_tready_mask; + +assign input_axis_tready = code_fifo_in_tready & data_fifo_in_tready & input_axis_tready_mask; + +reg [7:0] code_fifo_in_tdata; +reg code_fifo_in_tvalid; +reg code_fifo_in_tlast; +reg code_fifo_in_tuser; +wire code_fifo_in_tready; + +wire [7:0] code_fifo_out_tdata; +wire code_fifo_out_tvalid; +wire code_fifo_out_tlast; +wire code_fifo_out_tuser; +reg code_fifo_out_tready; + +axis_fifo #( + .ADDR_WIDTH(8), + .DATA_WIDTH(8) +) +code_fifo_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(code_fifo_in_tdata), + .input_axis_tvalid(code_fifo_in_tvalid), + .input_axis_tready(code_fifo_in_tready), + .input_axis_tlast(code_fifo_in_tlast), + .input_axis_tuser(code_fifo_in_tuser), + // AXI output + .output_axis_tdata(code_fifo_out_tdata), + .output_axis_tvalid(code_fifo_out_tvalid), + .output_axis_tready(code_fifo_out_tready), + .output_axis_tlast(code_fifo_out_tlast), + .output_axis_tuser(code_fifo_out_tuser) +); + +reg [7:0] data_fifo_in_tdata; +reg data_fifo_in_tvalid; +reg data_fifo_in_tlast; +wire data_fifo_in_tready; + +wire [7:0] data_fifo_out_tdata; +wire data_fifo_out_tvalid; +wire data_fifo_out_tlast; +reg data_fifo_out_tready; + +axis_fifo #( + .ADDR_WIDTH(8), + .DATA_WIDTH(8) +) +data_fifo_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(data_fifo_in_tdata), + .input_axis_tvalid(data_fifo_in_tvalid), + .input_axis_tready(data_fifo_in_tready), + .input_axis_tlast(data_fifo_in_tlast), + .input_axis_tuser(1'b0), + // AXI output + .output_axis_tdata(data_fifo_out_tdata), + .output_axis_tvalid(data_fifo_out_tvalid), + .output_axis_tready(data_fifo_out_tready), + .output_axis_tlast(data_fifo_out_tlast), + .output_axis_tuser() +); + +always @* begin + input_state_next = INPUT_STATE_IDLE; + + input_count_next = input_count_reg; + + fail_frame_next = fail_frame_reg; + + input_axis_tready_mask = 1'b0; + + code_fifo_in_tdata = 8'd0; + code_fifo_in_tvalid = 1'b0; + code_fifo_in_tlast = 1'b0; + code_fifo_in_tuser = 1'b0; + + data_fifo_in_tdata = input_axis_tdata; + data_fifo_in_tvalid = 1'b0; + data_fifo_in_tlast = 1'b0; + + case (input_state_reg) + INPUT_STATE_IDLE: begin + // idle state + input_axis_tready_mask = 1'b1; + fail_frame_next = 1'b0; + + if (input_axis_tready & input_axis_tvalid) begin + // valid input data + + if (input_axis_tdata == 8'd0 || (input_axis_tlast & input_axis_tuser)) begin + // got a zero or propagated error, so store a zero code + code_fifo_in_tdata = 8'd1; + code_fifo_in_tvalid = 1'b1; + if (input_axis_tlast) begin + // last byte, so close out the frame + fail_frame_next = input_axis_tuser; + input_state_next = INPUT_STATE_FINAL_ZERO; + end else begin + // return to idle to await next segment + input_state_next = INPUT_STATE_IDLE; + end + end else begin + // got something other than a zero, so store it and init the segment counter + input_count_next = 8'd2; + data_fifo_in_tdata = input_axis_tdata; + data_fifo_in_tvalid = 1'b1; + if (input_axis_tlast) begin + // last byte, so store the code and close out the frame + code_fifo_in_tdata = 8'd2; + code_fifo_in_tvalid = 1'b1; + if (APPEND_ZERO) begin + // zero frame mode, need to add a zero code to end the frame + input_state_next = INPUT_STATE_APPEND_ZERO; + end else begin + // normal frame mode, close out the frame + data_fifo_in_tlast = 1'b1; + input_state_next = INPUT_STATE_IDLE; + end + end else begin + // await more segment data + input_state_next = INPUT_STATE_SEGMENT; + end + end + end else begin + input_state_next = INPUT_STATE_IDLE; + end + end + INPUT_STATE_SEGMENT: begin + // encode segment + input_axis_tready_mask = 1'b1; + fail_frame_next = 1'b0; + + if (input_axis_tready & input_axis_tvalid) begin + // valid input data + + if (input_axis_tdata == 8'd0 || (input_axis_tlast & input_axis_tuser)) begin + // got a zero or propagated error, so store the code + code_fifo_in_tdata = input_count_reg; + code_fifo_in_tvalid = 1'b1; + if (input_axis_tlast) begin + // last byte, so close out the frame + fail_frame_next = input_axis_tuser; + input_state_next = INPUT_STATE_FINAL_ZERO; + end else begin + // return to idle to await next segment + input_state_next = INPUT_STATE_IDLE; + end + end else begin + // got something other than a zero, so store it and increment the segment counter + input_count_next = input_count_reg+1; + data_fifo_in_tdata = input_axis_tdata; + data_fifo_in_tvalid = 1'b1; + if (input_count_reg == 8'd254) begin + // 254 bytes in frame, so dump and reset counter + code_fifo_in_tdata = input_count_reg+1; + code_fifo_in_tvalid = 1'b1; + input_count_next = 8'd1; + end + if (input_axis_tlast) begin + // last byte, so store the code and close out the frame + code_fifo_in_tdata = input_count_reg+1; + code_fifo_in_tvalid = 1'b1; + if (APPEND_ZERO) begin + // zero frame mode, need to add a zero code to end the frame + input_state_next = INPUT_STATE_APPEND_ZERO; + end else begin + // normal frame mode, close out the frame + data_fifo_in_tlast = 1'b1; + input_state_next = INPUT_STATE_IDLE; + end + end else begin + // await more segment data + input_state_next = INPUT_STATE_SEGMENT; + end + end + end else begin + input_state_next = INPUT_STATE_SEGMENT; + end + end + INPUT_STATE_FINAL_ZERO: begin + // final zero code required + input_axis_tready_mask = 1'b0; + + if (code_fifo_in_tready) begin + // push a zero code and close out frame + if (fail_frame_reg) begin + code_fifo_in_tdata = 8'd2; + code_fifo_in_tuser = 1'b1; + end else begin + code_fifo_in_tdata = 8'd1; + end + code_fifo_in_tvalid = 1'b1; + if (APPEND_ZERO) begin + // zero frame mode, need to add a zero code to end the frame + input_state_next = INPUT_STATE_APPEND_ZERO; + end else begin + // normal frame mode, close out the frame + code_fifo_in_tlast = 1'b1; + fail_frame_next = 1'b0; + input_state_next = INPUT_STATE_IDLE; + end + end else begin + input_state_next = INPUT_STATE_FINAL_ZERO; + end + end + INPUT_STATE_APPEND_ZERO: begin + // append zero for zero framing + input_axis_tready_mask = 1'b0; + + if (code_fifo_in_tready) begin + // push frame termination code and close out frame + code_fifo_in_tdata = 8'd0; + code_fifo_in_tlast = 1'b1; + code_fifo_in_tuser = fail_frame_reg; + code_fifo_in_tvalid = 1'b1; + fail_frame_next = 1'b0; + input_state_next = INPUT_STATE_IDLE; + end else begin + input_state_next = INPUT_STATE_APPEND_ZERO; + end + end + endcase +end + +always @* begin + output_state_next = OUTPUT_STATE_IDLE; + + output_count_next = output_count_reg; + + output_axis_tdata_int = 8'd0; + output_axis_tvalid_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tuser_int = 1'b0; + + code_fifo_out_tready = 1'b0; + + data_fifo_out_tready = 1'b0; + + case (output_state_reg) + OUTPUT_STATE_IDLE: begin + // idle state + + if (output_axis_tready_int_reg & code_fifo_out_tvalid) begin + // transfer out code byte and load counter + output_axis_tdata_int = code_fifo_out_tdata; + output_axis_tlast_int = code_fifo_out_tlast; + output_axis_tuser_int = code_fifo_out_tuser & code_fifo_out_tlast; + output_count_next = code_fifo_out_tdata-1; + output_axis_tvalid_int = 1'b1; + code_fifo_out_tready = 1'b1; + if (code_fifo_out_tdata == 8'd0 || code_fifo_out_tdata == 8'd1 || code_fifo_out_tuser) begin + // frame termination and zero codes will be followed by codes + output_state_next = OUTPUT_STATE_IDLE; + end else begin + // transfer out data + output_state_next = OUTPUT_STATE_SEGMENT; + end + end else begin + output_state_next = OUTPUT_STATE_IDLE; + end + end + OUTPUT_STATE_SEGMENT: begin + // segment output + + if (output_axis_tready_int_reg & data_fifo_out_tvalid) begin + // transfer out data byte and decrement counter + output_axis_tdata_int = data_fifo_out_tdata; + output_axis_tlast_int = data_fifo_out_tlast; + output_count_next = output_count_reg - 1; + output_axis_tvalid_int = 1'b1; + data_fifo_out_tready = 1'b1; + if (output_count_reg == 1'b1) begin + // done with segment, get a code byte next + output_state_next = OUTPUT_STATE_IDLE; + end else begin + // more data to transfer + output_state_next = OUTPUT_STATE_SEGMENT; + end + end else begin + output_state_next = OUTPUT_STATE_SEGMENT; + end + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + input_state_reg <= INPUT_STATE_IDLE; + output_state_reg <= OUTPUT_STATE_IDLE; + end else begin + input_state_reg <= input_state_next; + output_state_reg <= output_state_next; + end + + input_count_reg <= input_count_next; + output_count_reg <= output_count_next; + fail_frame_reg <= fail_frame_next; +end + +// output datapath logic +reg [7:0] output_axis_tdata_reg = 8'd0; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg output_axis_tuser_reg = 1'b0; + +reg [7:0] temp_axis_tdata_reg = 8'd0; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg temp_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end +end + +endmodule diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py new file mode 100755 index 000000000..d8ef20f44 --- /dev/null +++ b/tb/test_axis_cobs_decode.py @@ -0,0 +1,482 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_cobs_decode' +testbench = 'test_axis_cobs_decode' + +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 dut_axis_cobs_decode(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 %s.vvp -lxt2" % testbench, + 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 cobs_encode(block): + block = bytearray(block) + enc = bytearray() + + seg = bytearray() + code = 1 + + new_data = True + + for b in block: + if b == 0: + enc.append(code) + enc.extend(seg) + code = 1 + seg = bytearray() + new_data = True + else: + code += 1 + seg.append(b) + new_data = True + if code == 255: + enc.append(code) + enc.extend(seg) + code = 1 + seg = bytearray() + new_data = False + + if new_data: + enc.append(code) + enc.extend(seg) + + return bytes(enc) + +def cobs_decode(block): + block = bytearray(block) + dec = bytearray() + + it = iter(bytearray(block)) + code = 0 + + i = 0 + + if 0 in block: + return None + + while i < len(block): + code = block[i] + i += 1 + if i+code-1 > len(block): + return None + for k in range(code-1): + dec.append(block[i]) + i += 1 + if code < 255 and i < len(block): + dec.append(0) + + return bytes(dec) + +def prbs31(state = 0x7fffffff): + while True: + for i in range(8): + if bool(state & 0x08000000) ^ bool(state & 0x40000000): + state = ((state & 0x3fffffff) << 1) | 1 + else: + state = (state & 0x3fffffff) << 1 + yield state & 0xff + +def bench(): + + # Parameters + + + # 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_cobs_decode(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 + + def wait_normal(): + i = 4 + while i > 0: + i = max(0, i-1) + if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + i = 4 + yield clk.posedge + + def wait_pause_source(): + i = 2 + while i > 0: + i = max(0, i-1) + if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + i = 2 + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + i = 2 + while i > 0: + i = max(0, i-1) + if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + i = 2 + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in list(range(1,33))+list(range(252,261))+[512,1024]: + gen = prbs31() + for block in [bytearray([0]*payload_len), + bytearray([k%255+1 for k in range(payload_len)]), + b'\x00'+bytearray([k%255+1 for k in range(payload_len)])+b'\x00', + bytearray([next(gen) for i in range(payload_len)])]: + + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + enc = cobs_encode(block) + + test_frame = axis_ep.AXIStreamFrame(enc) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test packet, length %d, zero frame" % payload_len) + current_test.next = 2 + + enc = cobs_encode(block) + + test_frame = axis_ep.AXIStreamFrame(enc+b'\x00') + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: back-to-back packets, length %d" % payload_len) + current_test.next = 3 + + test_frame2 = axis_ep.AXIStreamFrame(enc) + test_frame1 = axis_ep.AXIStreamFrame(enc) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == block + assert not rx_frame.user[-1] + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets, length %d, zero frame" % payload_len) + current_test.next = 4 + + test_frame = axis_ep.AXIStreamFrame(enc+b'\x00'+enc+b'\x00') + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == block + assert not rx_frame.user[-1] + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: tuser assert and bad frame, length %d" % payload_len) + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame(enc) + test_frame2 = axis_ep.AXIStreamFrame(enc+b'\x02') + test_frame3 = axis_ep.AXIStreamFrame(enc) + + test_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + source_queue.put(test_frame3) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert rx_frame.user[-1] + + rx_frame = sink_queue.get(False) + + assert rx_frame.user[-1] + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 6: tuser assert and bad frame, length %d, zero frame" % payload_len) + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame(enc+b'\x00') + test_frame2 = axis_ep.AXIStreamFrame(enc+b'\x02\x00') + test_frame3 = axis_ep.AXIStreamFrame(enc+b'\x00') + + test_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + source_queue.put(test_frame3) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert rx_frame.user[-1] + + rx_frame = sink_queue.get(False) + + assert rx_frame.user[-1] + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_cobs_decode.v b/tb/test_axis_cobs_decode.v new file mode 100644 index 000000000..07e20affa --- /dev/null +++ b/tb/test_axis_cobs_decode.v @@ -0,0 +1,91 @@ +/* + +Copyright (c) 2016 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 + +/* + * Testbench for axis_cobs_decode + */ +module test_axis_cobs_decode; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_axis_tdata = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_cobs_decode.lxt"); + $dumpvars(0, test_axis_cobs_decode); +end + +axis_cobs_decode +UUT ( + .clk(clk), + .rst(rst), + .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) +); + +endmodule diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py new file mode 100755 index 000000000..6422de2a9 --- /dev/null +++ b/tb/test_axis_cobs_encode.py @@ -0,0 +1,381 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_cobs_encode' +testbench = 'test_axis_cobs_encode' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def dut_axis_cobs_encode(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 %s.vvp -lxt2" % testbench, + 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 cobs_encode(block): + block = bytearray(block) + enc = bytearray() + + seg = bytearray() + code = 1 + + new_data = True + + for b in block: + if b == 0: + enc.append(code) + enc.extend(seg) + code = 1 + seg = bytearray() + new_data = True + else: + code += 1 + seg.append(b) + new_data = True + if code == 255: + enc.append(code) + enc.extend(seg) + code = 1 + seg = bytearray() + new_data = False + + if new_data: + enc.append(code) + enc.extend(seg) + + return bytes(enc) + +def cobs_decode(block): + block = bytearray(block) + dec = bytearray() + + it = iter(bytearray(block)) + code = 0 + + i = 0 + + if 0 in block: + return None + + while i < len(block): + code = block[i] + i += 1 + if i+code-1 > len(block): + return None + for k in range(code-1): + dec.append(block[i]) + i += 1 + if code < 255 and i < len(block): + dec.append(0) + + return bytes(dec) + +def prbs31(state = 0x7fffffff): + while True: + for i in range(8): + if bool(state & 0x08000000) ^ bool(state & 0x40000000): + state = ((state & 0x3fffffff) << 1) | 1 + else: + state = (state & 0x3fffffff) << 1 + yield state & 0xff + +def bench(): + + # Parameters + APPEND_ZERO = 0 + + # 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_cobs_encode(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 + + def wait_normal(): + i = 4 + while i > 0: + i = max(0, i-1) + if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + i = 4 + yield clk.posedge + + def wait_pause_source(): + i = 2 + while i > 0: + i = max(0, i-1) + if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + i = 2 + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + i = 2 + while i > 0: + i = max(0, i-1) + if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + i = 2 + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in list(range(1,33))+list(range(252,261))+[512,1024]: + gen = prbs31() + for block in [bytearray([0]*payload_len), + bytearray([k%255+1 for k in range(payload_len)]), + b'\x00'+bytearray([k%255+1 for k in range(payload_len)])+b'\x00', + bytearray([next(gen) for i in range(payload_len)])]: + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + enc = cobs_encode(block) + + test_frame = axis_ep.AXIStreamFrame(block) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == enc + assert cobs_decode(rx_frame.data) == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame(block) + test_frame2 = axis_ep.AXIStreamFrame(block) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == enc + assert cobs_decode(rx_frame.data) == block + assert not rx_frame.user[-1] + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == enc + assert cobs_decode(rx_frame.data) == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame(block) + test_frame2 = axis_ep.AXIStreamFrame(block) + + test_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert cobs_decode(rx_frame.data) == None + assert rx_frame.user[-1] + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == enc + assert cobs_decode(rx_frame.data) == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_cobs_encode.v b/tb/test_axis_cobs_encode.v new file mode 100644 index 000000000..9e40ca835 --- /dev/null +++ b/tb/test_axis_cobs_encode.v @@ -0,0 +1,94 @@ +/* + +Copyright (c) 2016 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 + +/* + * Testbench for axis_cobs_encode + */ +module test_axis_cobs_encode; + +// Parameters +parameter APPEND_ZERO = 0; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_axis_tdata = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_cobs_encode.lxt"); + $dumpvars(0, test_axis_cobs_encode); +end + +axis_cobs_encode #( + .APPEND_ZERO(APPEND_ZERO) +) +UUT ( + .clk(clk), + .rst(rst), + .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) +); + +endmodule diff --git a/tb/test_axis_cobs_encode_zero_frame.py b/tb/test_axis_cobs_encode_zero_frame.py new file mode 100755 index 000000000..b4fe9e8bc --- /dev/null +++ b/tb/test_axis_cobs_encode_zero_frame.py @@ -0,0 +1,381 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import axis_ep + +module = 'axis_cobs_encode' +testbench = 'test_axis_cobs_encode_zero_frame' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def dut_axis_cobs_encode(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 %s.vvp -lxt2" % testbench, + 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 cobs_encode(block): + block = bytearray(block) + enc = bytearray() + + seg = bytearray() + code = 1 + + new_data = True + + for b in block: + if b == 0: + enc.append(code) + enc.extend(seg) + code = 1 + seg = bytearray() + new_data = True + else: + code += 1 + seg.append(b) + new_data = True + if code == 255: + enc.append(code) + enc.extend(seg) + code = 1 + seg = bytearray() + new_data = False + + if new_data: + enc.append(code) + enc.extend(seg) + + return bytes(enc) + +def cobs_decode(block): + block = bytearray(block) + dec = bytearray() + + it = iter(bytearray(block)) + code = 0 + + i = 0 + + if 0 in block: + return None + + while i < len(block): + code = block[i] + i += 1 + if i+code-1 > len(block): + return None + for k in range(code-1): + dec.append(block[i]) + i += 1 + if code < 255 and i < len(block): + dec.append(0) + + return bytes(dec) + +def prbs31(state = 0x7fffffff): + while True: + for i in range(8): + if bool(state & 0x08000000) ^ bool(state & 0x40000000): + state = ((state & 0x3fffffff) << 1) | 1 + else: + state = (state & 0x3fffffff) << 1 + yield state & 0xff + +def bench(): + + # Parameters + APPEND_ZERO = 1 + + # 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_cobs_encode(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 + + def wait_normal(): + i = 4 + while i > 0: + i = max(0, i-1) + if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + i = 4 + yield clk.posedge + + def wait_pause_source(): + i = 2 + while i > 0: + i = max(0, i-1) + if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + i = 2 + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + i = 2 + while i > 0: + i = max(0, i-1) + if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + i = 2 + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in list(range(1,33))+list(range(252,261))+[512,1024]: + gen = prbs31() + for block in [bytearray([0]*payload_len), + bytearray([k%255+1 for k in range(payload_len)]), + b'\x00'+bytearray([k%255+1 for k in range(payload_len)])+b'\x00', + bytearray([next(gen) for i in range(payload_len)])]: + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + enc = cobs_encode(block) + + test_frame = axis_ep.AXIStreamFrame(block) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == enc+b'\x00' + assert cobs_decode(rx_frame.data[:-1]) == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame(block) + test_frame2 = axis_ep.AXIStreamFrame(block) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == enc+b'\x00' + assert cobs_decode(rx_frame.data[:-1]) == block + assert not rx_frame.user[-1] + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == enc+b'\x00' + assert cobs_decode(rx_frame.data[:-1]) == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame(block) + test_frame2 = axis_ep.AXIStreamFrame(block) + + test_frame1.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source_queue.put(test_frame1) + source_queue.put(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + + rx_frame = sink_queue.get(False) + + assert cobs_decode(rx_frame.data[:-1]) == None + assert rx_frame.user[-1] + + rx_frame = sink_queue.get(False) + + assert cobs_decode(enc) == block + assert rx_frame.data == enc+b'\x00' + assert cobs_decode(rx_frame.data[:-1]) == block + assert not rx_frame.user[-1] + + assert sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source, sink, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_cobs_encode_zero_frame.v b/tb/test_axis_cobs_encode_zero_frame.v new file mode 100644 index 000000000..14226bc52 --- /dev/null +++ b/tb/test_axis_cobs_encode_zero_frame.v @@ -0,0 +1,94 @@ +/* + +Copyright (c) 2016 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 + +/* + * Testbench for axis_cobs_encode + */ +module test_axis_cobs_encode_zero_frame; + +// Parameters +parameter APPEND_ZERO = 1; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] input_axis_tdata = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; + +// Outputs +wire input_axis_tready; +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready); + $to_myhdl(input_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser); + + // dump file + $dumpfile("test_axis_cobs_encode_zero_frame.lxt"); + $dumpvars(0, test_axis_cobs_encode_zero_frame); +end + +axis_cobs_encode #( + .APPEND_ZERO(APPEND_ZERO) +) +UUT ( + .clk(clk), + .rst(rst), + .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) +); + +endmodule From e989f15ff42ef7a464291574e64ba63dabeb489d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 22 Aug 2016 08:17:26 -0700 Subject: [PATCH 305/617] Remove some test cases --- tb/test_axis_cobs_decode.py | 2 +- tb/test_axis_cobs_encode.py | 2 +- tb/test_axis_cobs_encode_zero_frame.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py index d8ef20f44..4487a30c1 100755 --- a/tb/test_axis_cobs_decode.py +++ b/tb/test_axis_cobs_decode.py @@ -260,7 +260,7 @@ def bench(): # testbench stimulus - for payload_len in list(range(1,33))+list(range(252,261))+[512,1024]: + for payload_len in list(range(1,33))+list(range(253,259))+[512]: gen = prbs31() for block in [bytearray([0]*payload_len), bytearray([k%255+1 for k in range(payload_len)]), diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py index 6422de2a9..e3efef76b 100755 --- a/tb/test_axis_cobs_encode.py +++ b/tb/test_axis_cobs_encode.py @@ -261,7 +261,7 @@ def bench(): # testbench stimulus - for payload_len in list(range(1,33))+list(range(252,261))+[512,1024]: + for payload_len in list(range(1,33))+list(range(253,259))+[512]: gen = prbs31() for block in [bytearray([0]*payload_len), bytearray([k%255+1 for k in range(payload_len)]), diff --git a/tb/test_axis_cobs_encode_zero_frame.py b/tb/test_axis_cobs_encode_zero_frame.py index b4fe9e8bc..a7171f8fc 100755 --- a/tb/test_axis_cobs_encode_zero_frame.py +++ b/tb/test_axis_cobs_encode_zero_frame.py @@ -261,7 +261,7 @@ def bench(): # testbench stimulus - for payload_len in list(range(1,33))+list(range(252,261))+[512,1024]: + for payload_len in list(range(1,33))+list(range(253,259))+[512]: gen = prbs31() for block in [bytearray([0]*payload_len), bytearray([k%255+1 for k in range(payload_len)]), From 3207a2b7d221ea553d536cfc6ddcf1a587fe8b98 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 23 Aug 2016 09:25:19 -0700 Subject: [PATCH 306/617] Remove redundant code --- rtl/axis_switch.py | 16 +---------- rtl/axis_switch_4x4.v | 57 +++------------------------------------- rtl/axis_switch_64.py | 16 +---------- rtl/axis_switch_64_4x4.v | 57 +++------------------------------------- 4 files changed, 10 insertions(+), 136 deletions(-) diff --git a/rtl/axis_switch.py b/rtl/axis_switch.py index 35be63175..2be1af656 100755 --- a/rtl/axis_switch.py +++ b/rtl/axis_switch.py @@ -174,20 +174,6 @@ wire output_{{p}}_axis_tready_int_early; assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; {%- endfor %} -// mux for start of packet detection - -{%- for p in range(n) %} -reg selected_input_{{p}}_axis_tvalid; - -always @* begin - case (grant_encoded_{{p}}) -{%- for q in range(m) %} - {{cm}}'d{{q}}: selected_input_{{p}}_axis_tvalid = input_{{q}}_axis_tvalid; -{%- endfor %} - default: selected_input_{{p}}_axis_tvalid = 1'b0; - endcase -end -{% endfor %} // mux for incoming packet {% for p in range(n) %} reg [DATA_WIDTH-1:0] current_input_{{p}}_axis_tdata; @@ -306,7 +292,7 @@ always @* begin if (current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready) begin enable_{{p}}_next = ~current_input_{{p}}_axis_tlast; end - end else if (grant_valid_{{p}} & selected_input_{{p}}_axis_tvalid) begin + end else if (grant_valid_{{p}}) begin enable_{{p}}_next = 1'b1; select_{{p}}_next = grant_encoded_{{p}}; end diff --git a/rtl/axis_switch_4x4.v b/rtl/axis_switch_4x4.v index 0aaf34973..603528985 100644 --- a/rtl/axis_switch_4x4.v +++ b/rtl/axis_switch_4x4.v @@ -220,55 +220,6 @@ assign input_1_axis_tready = input_1_axis_tready_reg; assign input_2_axis_tready = input_2_axis_tready_reg; assign input_3_axis_tready = input_3_axis_tready_reg; -// mux for start of packet detection -reg selected_input_0_axis_tvalid; - -always @* begin - case (grant_encoded_0) - 2'd0: selected_input_0_axis_tvalid = input_0_axis_tvalid; - 2'd1: selected_input_0_axis_tvalid = input_1_axis_tvalid; - 2'd2: selected_input_0_axis_tvalid = input_2_axis_tvalid; - 2'd3: selected_input_0_axis_tvalid = input_3_axis_tvalid; - default: selected_input_0_axis_tvalid = 1'b0; - endcase -end - -reg selected_input_1_axis_tvalid; - -always @* begin - case (grant_encoded_1) - 2'd0: selected_input_1_axis_tvalid = input_0_axis_tvalid; - 2'd1: selected_input_1_axis_tvalid = input_1_axis_tvalid; - 2'd2: selected_input_1_axis_tvalid = input_2_axis_tvalid; - 2'd3: selected_input_1_axis_tvalid = input_3_axis_tvalid; - default: selected_input_1_axis_tvalid = 1'b0; - endcase -end - -reg selected_input_2_axis_tvalid; - -always @* begin - case (grant_encoded_2) - 2'd0: selected_input_2_axis_tvalid = input_0_axis_tvalid; - 2'd1: selected_input_2_axis_tvalid = input_1_axis_tvalid; - 2'd2: selected_input_2_axis_tvalid = input_2_axis_tvalid; - 2'd3: selected_input_2_axis_tvalid = input_3_axis_tvalid; - default: selected_input_2_axis_tvalid = 1'b0; - endcase -end - -reg selected_input_3_axis_tvalid; - -always @* begin - case (grant_encoded_3) - 2'd0: selected_input_3_axis_tvalid = input_0_axis_tvalid; - 2'd1: selected_input_3_axis_tvalid = input_1_axis_tvalid; - 2'd2: selected_input_3_axis_tvalid = input_2_axis_tvalid; - 2'd3: selected_input_3_axis_tvalid = input_3_axis_tvalid; - default: selected_input_3_axis_tvalid = 1'b0; - endcase -end - // mux for incoming packet reg [DATA_WIDTH-1:0] current_input_0_axis_tdata; @@ -751,7 +702,7 @@ always @* begin if (current_input_0_axis_tvalid & current_input_0_axis_tready) begin enable_0_next = ~current_input_0_axis_tlast; end - end else if (grant_valid_0 & selected_input_0_axis_tvalid) begin + end else if (grant_valid_0) begin enable_0_next = 1'b1; select_0_next = grant_encoded_0; end @@ -760,7 +711,7 @@ always @* begin if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin enable_1_next = ~current_input_1_axis_tlast; end - end else if (grant_valid_1 & selected_input_1_axis_tvalid) begin + end else if (grant_valid_1) begin enable_1_next = 1'b1; select_1_next = grant_encoded_1; end @@ -769,7 +720,7 @@ always @* begin if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin enable_2_next = ~current_input_2_axis_tlast; end - end else if (grant_valid_2 & selected_input_2_axis_tvalid) begin + end else if (grant_valid_2) begin enable_2_next = 1'b1; select_2_next = grant_encoded_2; end @@ -778,7 +729,7 @@ always @* begin if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin enable_3_next = ~current_input_3_axis_tlast; end - end else if (grant_valid_3 & selected_input_3_axis_tvalid) begin + end else if (grant_valid_3) begin enable_3_next = 1'b1; select_3_next = grant_encoded_3; end diff --git a/rtl/axis_switch_64.py b/rtl/axis_switch_64.py index 3eebdbdf4..9a2858d5f 100755 --- a/rtl/axis_switch_64.py +++ b/rtl/axis_switch_64.py @@ -178,20 +178,6 @@ wire output_{{p}}_axis_tready_int_early; assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; {%- endfor %} -// mux for start of packet detection - -{%- for p in range(n) %} -reg selected_input_{{p}}_axis_tvalid; - -always @* begin - case (grant_encoded_{{p}}) -{%- for q in range(m) %} - {{cm}}'d{{q}}: selected_input_{{p}}_axis_tvalid = input_{{q}}_axis_tvalid; -{%- endfor %} - default: selected_input_{{p}}_axis_tvalid = 1'b0; - endcase -end -{% endfor %} // mux for incoming packet {% for p in range(n) %} reg [DATA_WIDTH-1:0] current_input_{{p}}_axis_tdata; @@ -314,7 +300,7 @@ always @* begin if (current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready) begin enable_{{p}}_next = ~current_input_{{p}}_axis_tlast; end - end else if (grant_valid_{{p}} & selected_input_{{p}}_axis_tvalid) begin + end else if (grant_valid_{{p}}) begin enable_{{p}}_next = 1'b1; select_{{p}}_next = grant_encoded_{{p}}; end diff --git a/rtl/axis_switch_64_4x4.v b/rtl/axis_switch_64_4x4.v index 6370a1f4a..7068e136c 100644 --- a/rtl/axis_switch_64_4x4.v +++ b/rtl/axis_switch_64_4x4.v @@ -233,55 +233,6 @@ assign input_1_axis_tready = input_1_axis_tready_reg; assign input_2_axis_tready = input_2_axis_tready_reg; assign input_3_axis_tready = input_3_axis_tready_reg; -// mux for start of packet detection -reg selected_input_0_axis_tvalid; - -always @* begin - case (grant_encoded_0) - 2'd0: selected_input_0_axis_tvalid = input_0_axis_tvalid; - 2'd1: selected_input_0_axis_tvalid = input_1_axis_tvalid; - 2'd2: selected_input_0_axis_tvalid = input_2_axis_tvalid; - 2'd3: selected_input_0_axis_tvalid = input_3_axis_tvalid; - default: selected_input_0_axis_tvalid = 1'b0; - endcase -end - -reg selected_input_1_axis_tvalid; - -always @* begin - case (grant_encoded_1) - 2'd0: selected_input_1_axis_tvalid = input_0_axis_tvalid; - 2'd1: selected_input_1_axis_tvalid = input_1_axis_tvalid; - 2'd2: selected_input_1_axis_tvalid = input_2_axis_tvalid; - 2'd3: selected_input_1_axis_tvalid = input_3_axis_tvalid; - default: selected_input_1_axis_tvalid = 1'b0; - endcase -end - -reg selected_input_2_axis_tvalid; - -always @* begin - case (grant_encoded_2) - 2'd0: selected_input_2_axis_tvalid = input_0_axis_tvalid; - 2'd1: selected_input_2_axis_tvalid = input_1_axis_tvalid; - 2'd2: selected_input_2_axis_tvalid = input_2_axis_tvalid; - 2'd3: selected_input_2_axis_tvalid = input_3_axis_tvalid; - default: selected_input_2_axis_tvalid = 1'b0; - endcase -end - -reg selected_input_3_axis_tvalid; - -always @* begin - case (grant_encoded_3) - 2'd0: selected_input_3_axis_tvalid = input_0_axis_tvalid; - 2'd1: selected_input_3_axis_tvalid = input_1_axis_tvalid; - 2'd2: selected_input_3_axis_tvalid = input_2_axis_tvalid; - 2'd3: selected_input_3_axis_tvalid = input_3_axis_tvalid; - default: selected_input_3_axis_tvalid = 1'b0; - endcase -end - // mux for incoming packet reg [DATA_WIDTH-1:0] current_input_0_axis_tdata; @@ -792,7 +743,7 @@ always @* begin if (current_input_0_axis_tvalid & current_input_0_axis_tready) begin enable_0_next = ~current_input_0_axis_tlast; end - end else if (grant_valid_0 & selected_input_0_axis_tvalid) begin + end else if (grant_valid_0) begin enable_0_next = 1'b1; select_0_next = grant_encoded_0; end @@ -801,7 +752,7 @@ always @* begin if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin enable_1_next = ~current_input_1_axis_tlast; end - end else if (grant_valid_1 & selected_input_1_axis_tvalid) begin + end else if (grant_valid_1) begin enable_1_next = 1'b1; select_1_next = grant_encoded_1; end @@ -810,7 +761,7 @@ always @* begin if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin enable_2_next = ~current_input_2_axis_tlast; end - end else if (grant_valid_2 & selected_input_2_axis_tvalid) begin + end else if (grant_valid_2) begin enable_2_next = 1'b1; select_2_next = grant_encoded_2; end @@ -819,7 +770,7 @@ always @* begin if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin enable_3_next = ~current_input_3_axis_tlast; end - end else if (grant_valid_3 & selected_input_3_axis_tvalid) begin + end else if (grant_valid_3) begin enable_3_next = 1'b1; select_3_next = grant_encoded_3; end From 4245e2bf0033dc2e2f140352be45fb1fb3de1314 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Aug 2016 16:53:13 -0700 Subject: [PATCH 307/617] Rework mux logic --- rtl/axis_demux.py | 12 +++++++----- rtl/axis_demux_4.v | 12 +++++++----- rtl/axis_demux_64.py | 12 +++++++----- rtl/axis_demux_64_4.v | 12 +++++++----- rtl/axis_mux.py | 12 +++++++----- rtl/axis_mux_4.v | 12 +++++++----- rtl/axis_mux_64.py | 12 +++++++----- rtl/axis_mux_64_4.v | 12 +++++++----- rtl/axis_switch.py | 9 +++++---- rtl/axis_switch_4x4.v | 36 ++++++++++++++++++++---------------- rtl/axis_switch_64.py | 9 +++++---- rtl/axis_switch_64_4x4.v | 36 ++++++++++++++++++++---------------- 12 files changed, 106 insertions(+), 80 deletions(-) diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index bbb9bb858..bd2e7c009 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -142,12 +142,14 @@ always @* begin input_axis_tready_next = 1'b0; - if (frame_reg) begin - if (input_axis_tvalid & input_axis_tready) begin - // end of frame detection - frame_next = ~input_axis_tlast; + if (input_axis_tvalid & input_axis_tready) begin + // end of frame detection + if (input_axis_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v index 803ce3241..a30ec133e 100644 --- a/rtl/axis_demux_4.v +++ b/rtl/axis_demux_4.v @@ -129,12 +129,14 @@ always @* begin input_axis_tready_next = 1'b0; - if (frame_reg) begin - if (input_axis_tvalid & input_axis_tready) begin - // end of frame detection - frame_next = ~input_axis_tlast; + if (input_axis_tvalid & input_axis_tready) begin + // end of frame detection + if (input_axis_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index b9db42c6d..774124d92 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -146,12 +146,14 @@ always @* begin input_axis_tready_next = 1'b0; - if (frame_reg) begin - if (input_axis_tvalid & input_axis_tready) begin - // end of frame detection - frame_next = ~input_axis_tlast; + if (input_axis_tvalid & input_axis_tready) begin + // end of frame detection + if (input_axis_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/axis_demux_64_4.v b/rtl/axis_demux_64_4.v index 6e452ba9d..e4eb8d2d7 100644 --- a/rtl/axis_demux_64_4.v +++ b/rtl/axis_demux_64_4.v @@ -136,12 +136,14 @@ always @* begin input_axis_tready_next = 1'b0; - if (frame_reg) begin - if (input_axis_tvalid & input_axis_tready) begin - // end of frame detection - frame_next = ~input_axis_tlast; + if (input_axis_tvalid & input_axis_tready) begin + // end of frame detection + if (input_axis_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_axis_tvalid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_axis_tvalid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 14aba1a95..669618e9b 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -165,12 +165,14 @@ always @* begin input_{{p}}_axis_tready_next = 1'b0; {%- endfor %} - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & selected_input_tvalid) begin + end + + if (~frame_reg & enable & selected_input_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v index 36cd8d457..7ee57307e 100644 --- a/rtl/axis_mux_4.v +++ b/rtl/axis_mux_4.v @@ -168,12 +168,14 @@ always @* begin input_2_axis_tready_next = 1'b0; input_3_axis_tready_next = 1'b0; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & selected_input_tvalid) begin + end + + if (~frame_reg & enable & selected_input_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index 83ebffe89..ec985d81a 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -172,12 +172,14 @@ always @* begin input_{{p}}_axis_tready_next = 1'b0; {%- endfor %} - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & selected_input_tvalid) begin + end + + if (~frame_reg & enable & selected_input_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/axis_mux_64_4.v b/rtl/axis_mux_64_4.v index 69707e607..b0bcce2cb 100644 --- a/rtl/axis_mux_64_4.v +++ b/rtl/axis_mux_64_4.v @@ -181,12 +181,14 @@ always @* begin input_2_axis_tready_next = 1'b0; input_3_axis_tready_next = 1'b0; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & selected_input_tvalid) begin + end + + if (~frame_reg & enable & selected_input_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/axis_switch.py b/rtl/axis_switch.py index 2be1af656..c9ec7c3cf 100755 --- a/rtl/axis_switch.py +++ b/rtl/axis_switch.py @@ -288,11 +288,12 @@ always @* begin {% endfor %} // output control {% for p in range(n) %} - if (enable_{{p}}_reg) begin - if (current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready) begin - enable_{{p}}_next = ~current_input_{{p}}_axis_tlast; + if (current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready) begin + if (current_input_{{p}}_axis_tlast) begin + enable_{{p}}_next = 1'b0; end - end else if (grant_valid_{{p}}) begin + end + if (~enable_{{p}}_reg & grant_valid_{{p}}) begin enable_{{p}}_next = 1'b1; select_{{p}}_next = grant_encoded_{{p}}; end diff --git a/rtl/axis_switch_4x4.v b/rtl/axis_switch_4x4.v index 603528985..bfca35997 100644 --- a/rtl/axis_switch_4x4.v +++ b/rtl/axis_switch_4x4.v @@ -698,38 +698,42 @@ always @* begin // output control - if (enable_0_reg) begin - if (current_input_0_axis_tvalid & current_input_0_axis_tready) begin - enable_0_next = ~current_input_0_axis_tlast; + if (current_input_0_axis_tvalid & current_input_0_axis_tready) begin + if (current_input_0_axis_tlast) begin + enable_0_next = 1'b0; end - end else if (grant_valid_0) begin + end + if (~enable_0_reg & grant_valid_0) begin enable_0_next = 1'b1; select_0_next = grant_encoded_0; end - if (enable_1_reg) begin - if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin - enable_1_next = ~current_input_1_axis_tlast; + if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin + if (current_input_1_axis_tlast) begin + enable_1_next = 1'b0; end - end else if (grant_valid_1) begin + end + if (~enable_1_reg & grant_valid_1) begin enable_1_next = 1'b1; select_1_next = grant_encoded_1; end - if (enable_2_reg) begin - if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin - enable_2_next = ~current_input_2_axis_tlast; + if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin + if (current_input_2_axis_tlast) begin + enable_2_next = 1'b0; end - end else if (grant_valid_2) begin + end + if (~enable_2_reg & grant_valid_2) begin enable_2_next = 1'b1; select_2_next = grant_encoded_2; end - if (enable_3_reg) begin - if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin - enable_3_next = ~current_input_3_axis_tlast; + if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin + if (current_input_3_axis_tlast) begin + enable_3_next = 1'b0; end - end else if (grant_valid_3) begin + end + if (~enable_3_reg & grant_valid_3) begin enable_3_next = 1'b1; select_3_next = grant_encoded_3; end diff --git a/rtl/axis_switch_64.py b/rtl/axis_switch_64.py index 9a2858d5f..dcd4c715d 100755 --- a/rtl/axis_switch_64.py +++ b/rtl/axis_switch_64.py @@ -296,11 +296,12 @@ always @* begin {% endfor %} // output control {% for p in range(n) %} - if (enable_{{p}}_reg) begin - if (current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready) begin - enable_{{p}}_next = ~current_input_{{p}}_axis_tlast; + if (current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready) begin + if (current_input_{{p}}_axis_tlast) begin + enable_{{p}}_next = 1'b0; end - end else if (grant_valid_{{p}}) begin + end + if (~enable_{{p}}_reg & grant_valid_{{p}}) begin enable_{{p}}_next = 1'b1; select_{{p}}_next = grant_encoded_{{p}}; end diff --git a/rtl/axis_switch_64_4x4.v b/rtl/axis_switch_64_4x4.v index 7068e136c..ea449bb2e 100644 --- a/rtl/axis_switch_64_4x4.v +++ b/rtl/axis_switch_64_4x4.v @@ -739,38 +739,42 @@ always @* begin // output control - if (enable_0_reg) begin - if (current_input_0_axis_tvalid & current_input_0_axis_tready) begin - enable_0_next = ~current_input_0_axis_tlast; + if (current_input_0_axis_tvalid & current_input_0_axis_tready) begin + if (current_input_0_axis_tlast) begin + enable_0_next = 1'b0; end - end else if (grant_valid_0) begin + end + if (~enable_0_reg & grant_valid_0) begin enable_0_next = 1'b1; select_0_next = grant_encoded_0; end - if (enable_1_reg) begin - if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin - enable_1_next = ~current_input_1_axis_tlast; + if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin + if (current_input_1_axis_tlast) begin + enable_1_next = 1'b0; end - end else if (grant_valid_1) begin + end + if (~enable_1_reg & grant_valid_1) begin enable_1_next = 1'b1; select_1_next = grant_encoded_1; end - if (enable_2_reg) begin - if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin - enable_2_next = ~current_input_2_axis_tlast; + if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin + if (current_input_2_axis_tlast) begin + enable_2_next = 1'b0; end - end else if (grant_valid_2) begin + end + if (~enable_2_reg & grant_valid_2) begin enable_2_next = 1'b1; select_2_next = grant_encoded_2; end - if (enable_3_reg) begin - if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin - enable_3_next = ~current_input_3_axis_tlast; + if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin + if (current_input_3_axis_tlast) begin + enable_3_next = 1'b0; end - end else if (grant_valid_3) begin + end + if (~enable_3_reg & grant_valid_3) begin enable_3_next = 1'b1; select_3_next = grant_encoded_3; end From 306c0ea590798bbca0f7296895281ac613ef2e63 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 29 Aug 2016 19:25:43 -0700 Subject: [PATCH 308/617] Rework mux logic --- rtl/eth_demux.py | 12 +++++++----- rtl/eth_demux_4.v | 12 +++++++----- rtl/eth_demux_64.py | 12 +++++++----- rtl/eth_demux_64_4.v | 12 +++++++----- rtl/eth_mux.py | 12 +++++++----- rtl/eth_mux_2.v | 12 +++++++----- rtl/eth_mux_4.v | 12 +++++++----- rtl/eth_mux_64.py | 12 +++++++----- rtl/eth_mux_64_2.v | 12 +++++++----- rtl/eth_mux_64_4.v | 12 +++++++----- rtl/ip_demux.py | 12 +++++++----- rtl/ip_demux_4.v | 12 +++++++----- rtl/ip_demux_64.py | 12 +++++++----- rtl/ip_demux_64_4.v | 12 +++++++----- rtl/ip_mux.py | 12 +++++++----- rtl/ip_mux_2.v | 12 +++++++----- rtl/ip_mux_4.v | 12 +++++++----- rtl/ip_mux_64.py | 12 +++++++----- rtl/ip_mux_64_2.v | 12 +++++++----- rtl/ip_mux_64_4.v | 12 +++++++----- rtl/udp_demux.py | 12 +++++++----- rtl/udp_demux_4.v | 12 +++++++----- rtl/udp_demux_64.py | 12 +++++++----- rtl/udp_demux_64_4.v | 12 +++++++----- rtl/udp_mux.py | 12 +++++++----- rtl/udp_mux_4.v | 12 +++++++----- rtl/udp_mux_64.py | 12 +++++++----- rtl/udp_mux_64_4.v | 12 +++++++----- 28 files changed, 196 insertions(+), 140 deletions(-) diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py index 46b6557f9..068c31c28 100755 --- a/rtl/eth_demux.py +++ b/rtl/eth_demux.py @@ -176,12 +176,14 @@ always @* begin output_eth_src_mac_next = output_eth_src_mac_reg; output_eth_type_next = output_eth_type_reg; - if (frame_reg) begin - if (input_eth_payload_tvalid & input_eth_payload_tready) begin - // end of frame detection - frame_next = ~input_eth_payload_tlast; + if (input_eth_payload_tvalid & input_eth_payload_tready) begin + // end of frame detection + if (input_eth_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/eth_demux_4.v b/rtl/eth_demux_4.v index 927caa77f..b87b9e68f 100644 --- a/rtl/eth_demux_4.v +++ b/rtl/eth_demux_4.v @@ -201,12 +201,14 @@ always @* begin output_eth_src_mac_next = output_eth_src_mac_reg; output_eth_type_next = output_eth_type_reg; - if (frame_reg) begin - if (input_eth_payload_tvalid & input_eth_payload_tready) begin - // end of frame detection - frame_next = ~input_eth_payload_tlast; + if (input_eth_payload_tvalid & input_eth_payload_tready) begin + // end of frame detection + if (input_eth_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py index 05e607423..d893689a7 100755 --- a/rtl/eth_demux_64.py +++ b/rtl/eth_demux_64.py @@ -179,12 +179,14 @@ always @* begin output_eth_src_mac_next = output_eth_src_mac_reg; output_eth_type_next = output_eth_type_reg; - if (frame_reg) begin - if (input_eth_payload_tvalid & input_eth_payload_tready) begin - // end of frame detection - frame_next = ~input_eth_payload_tlast; + if (input_eth_payload_tvalid & input_eth_payload_tready) begin + // end of frame detection + if (input_eth_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/eth_demux_64_4.v b/rtl/eth_demux_64_4.v index 624338a2a..177999728 100644 --- a/rtl/eth_demux_64_4.v +++ b/rtl/eth_demux_64_4.v @@ -207,12 +207,14 @@ always @* begin output_eth_src_mac_next = output_eth_src_mac_reg; output_eth_type_next = output_eth_type_reg; - if (frame_reg) begin - if (input_eth_payload_tvalid & input_eth_payload_tready) begin - // end of frame detection - frame_next = ~input_eth_payload_tlast; + if (input_eth_payload_tvalid & input_eth_payload_tready) begin + // end of frame detection + if (input_eth_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index 1ae82094a..75552f6e8 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -209,12 +209,14 @@ always @* begin output_eth_src_mac_next = output_eth_src_mac_reg; output_eth_type_next = output_eth_type_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/eth_mux_2.v b/rtl/eth_mux_2.v index 0048af97a..4abc98df3 100644 --- a/rtl/eth_mux_2.v +++ b/rtl/eth_mux_2.v @@ -188,12 +188,14 @@ always @* begin output_eth_src_mac_next = output_eth_src_mac_reg; output_eth_type_next = output_eth_type_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v index 26d5cbe61..90bba71da 100644 --- a/rtl/eth_mux_4.v +++ b/rtl/eth_mux_4.v @@ -248,12 +248,14 @@ always @* begin output_eth_src_mac_next = output_eth_src_mac_reg; output_eth_type_next = output_eth_type_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index 9ffad95fc..21b1f79ab 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -215,12 +215,14 @@ always @* begin output_eth_src_mac_next = output_eth_src_mac_reg; output_eth_type_next = output_eth_type_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/eth_mux_64_2.v b/rtl/eth_mux_64_2.v index e17238c2b..152f0771e 100644 --- a/rtl/eth_mux_64_2.v +++ b/rtl/eth_mux_64_2.v @@ -196,12 +196,14 @@ always @* begin output_eth_src_mac_next = output_eth_src_mac_reg; output_eth_type_next = output_eth_type_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v index bd1591416..0cea82a64 100644 --- a/rtl/eth_mux_64_4.v +++ b/rtl/eth_mux_64_4.v @@ -260,12 +260,14 @@ always @* begin output_eth_src_mac_next = output_eth_src_mac_reg; output_eth_type_next = output_eth_type_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py index 5744ce813..b0ab37e27 100755 --- a/rtl/ip_demux.py +++ b/rtl/ip_demux.py @@ -241,12 +241,14 @@ always @* begin output_ip_source_ip_next = output_ip_source_ip_reg; output_ip_dest_ip_next = output_ip_dest_ip_reg; - if (frame_reg) begin - if (input_ip_payload_tvalid & input_ip_payload_tready) begin - // end of frame detection - frame_next = ~input_ip_payload_tlast; + if (input_ip_payload_tvalid & input_ip_payload_tready) begin + // end of frame detection + if (input_ip_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/ip_demux_4.v b/rtl/ip_demux_4.v index 5acae1b46..9c5002c9b 100644 --- a/rtl/ip_demux_4.v +++ b/rtl/ip_demux_4.v @@ -344,12 +344,14 @@ always @* begin output_ip_source_ip_next = output_ip_source_ip_reg; output_ip_dest_ip_next = output_ip_dest_ip_reg; - if (frame_reg) begin - if (input_ip_payload_tvalid & input_ip_payload_tready) begin - // end of frame detection - frame_next = ~input_ip_payload_tlast; + if (input_ip_payload_tvalid & input_ip_payload_tready) begin + // end of frame detection + if (input_ip_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py index 5935da9fe..0c8970c3e 100755 --- a/rtl/ip_demux_64.py +++ b/rtl/ip_demux_64.py @@ -244,12 +244,14 @@ always @* begin output_ip_source_ip_next = output_ip_source_ip_reg; output_ip_dest_ip_next = output_ip_dest_ip_reg; - if (frame_reg) begin - if (input_ip_payload_tvalid & input_ip_payload_tready) begin - // end of frame detection - frame_next = ~input_ip_payload_tlast; + if (input_ip_payload_tvalid & input_ip_payload_tready) begin + // end of frame detection + if (input_ip_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/ip_demux_64_4.v b/rtl/ip_demux_64_4.v index 11cb63783..8c8b3a6e6 100644 --- a/rtl/ip_demux_64_4.v +++ b/rtl/ip_demux_64_4.v @@ -350,12 +350,14 @@ always @* begin output_ip_source_ip_next = output_ip_source_ip_reg; output_ip_dest_ip_next = output_ip_dest_ip_reg; - if (frame_reg) begin - if (input_ip_payload_tvalid & input_ip_payload_tready) begin - // end of frame detection - frame_next = ~input_ip_payload_tlast; + if (input_ip_payload_tvalid & input_ip_payload_tready) begin + // end of frame detection + if (input_ip_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py index 26010cb86..8da717b67 100755 --- a/rtl/ip_mux.py +++ b/rtl/ip_mux.py @@ -313,12 +313,14 @@ always @* begin output_ip_source_ip_next = output_ip_source_ip_reg; output_ip_dest_ip_next = output_ip_dest_ip_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/ip_mux_2.v b/rtl/ip_mux_2.v index 1d694eb67..f8e62ae83 100644 --- a/rtl/ip_mux_2.v +++ b/rtl/ip_mux_2.v @@ -318,12 +318,14 @@ always @* begin output_ip_source_ip_next = output_ip_source_ip_reg; output_ip_dest_ip_next = output_ip_dest_ip_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/ip_mux_4.v b/rtl/ip_mux_4.v index 7912099fd..e4785beac 100644 --- a/rtl/ip_mux_4.v +++ b/rtl/ip_mux_4.v @@ -430,12 +430,14 @@ always @* begin output_ip_source_ip_next = output_ip_source_ip_reg; output_ip_dest_ip_next = output_ip_dest_ip_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py index 4bde325d5..5a9e98d35 100755 --- a/rtl/ip_mux_64.py +++ b/rtl/ip_mux_64.py @@ -319,12 +319,14 @@ always @* begin output_ip_source_ip_next = output_ip_source_ip_reg; output_ip_dest_ip_next = output_ip_dest_ip_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/ip_mux_64_2.v b/rtl/ip_mux_64_2.v index bca3424dd..ff4a27c9a 100644 --- a/rtl/ip_mux_64_2.v +++ b/rtl/ip_mux_64_2.v @@ -326,12 +326,14 @@ always @* begin output_ip_source_ip_next = output_ip_source_ip_reg; output_ip_dest_ip_next = output_ip_dest_ip_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/ip_mux_64_4.v b/rtl/ip_mux_64_4.v index 4948e2b6a..3dfdb2306 100644 --- a/rtl/ip_mux_64_4.v +++ b/rtl/ip_mux_64_4.v @@ -442,12 +442,14 @@ always @* begin output_ip_source_ip_next = output_ip_source_ip_reg; output_ip_dest_ip_next = output_ip_dest_ip_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py index 9f7403583..e74706ae8 100755 --- a/rtl/udp_demux.py +++ b/rtl/udp_demux.py @@ -261,12 +261,14 @@ always @* begin output_udp_length_next = output_udp_length_reg; output_udp_checksum_next = output_udp_checksum_reg; - if (frame_reg) begin - if (input_udp_payload_tvalid & input_udp_payload_tready) begin - // end of frame detection - frame_next = ~input_udp_payload_tlast; + if (input_udp_payload_tvalid & input_udp_payload_tready) begin + // end of frame detection + if (input_udp_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/udp_demux_4.v b/rtl/udp_demux_4.v index 23c747dd2..d28a34471 100644 --- a/rtl/udp_demux_4.v +++ b/rtl/udp_demux_4.v @@ -388,12 +388,14 @@ always @* begin output_udp_length_next = output_udp_length_reg; output_udp_checksum_next = output_udp_checksum_reg; - if (frame_reg) begin - if (input_udp_payload_tvalid & input_udp_payload_tready) begin - // end of frame detection - frame_next = ~input_udp_payload_tlast; + if (input_udp_payload_tvalid & input_udp_payload_tready) begin + // end of frame detection + if (input_udp_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py index c85b19586..4c61aa6f9 100755 --- a/rtl/udp_demux_64.py +++ b/rtl/udp_demux_64.py @@ -264,12 +264,14 @@ always @* begin output_udp_length_next = output_udp_length_reg; output_udp_checksum_next = output_udp_checksum_reg; - if (frame_reg) begin - if (input_udp_payload_tvalid & input_udp_payload_tready) begin - // end of frame detection - frame_next = ~input_udp_payload_tlast; + if (input_udp_payload_tvalid & input_udp_payload_tready) begin + // end of frame detection + if (input_udp_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/udp_demux_64_4.v b/rtl/udp_demux_64_4.v index ba0de5c07..9df7f4730 100644 --- a/rtl/udp_demux_64_4.v +++ b/rtl/udp_demux_64_4.v @@ -394,12 +394,14 @@ always @* begin output_udp_length_next = output_udp_length_reg; output_udp_checksum_next = output_udp_checksum_reg; - if (frame_reg) begin - if (input_udp_payload_tvalid & input_udp_payload_tready) begin - // end of frame detection - frame_next = ~input_udp_payload_tlast; + if (input_udp_payload_tvalid & input_udp_payload_tready) begin + // end of frame detection + if (input_udp_payload_tlast) begin + frame_next = 1'b0; end - end else if (enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin + end + + if (~frame_reg & enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py index b21658aea..e1e7ca9a2 100755 --- a/rtl/udp_mux.py +++ b/rtl/udp_mux.py @@ -345,12 +345,14 @@ always @* begin output_udp_length_next = output_udp_length_reg; output_udp_checksum_next = output_udp_checksum_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/udp_mux_4.v b/rtl/udp_mux_4.v index e6739e6c4..e52b7d321 100644 --- a/rtl/udp_mux_4.v +++ b/rtl/udp_mux_4.v @@ -486,12 +486,14 @@ always @* begin output_udp_length_next = output_udp_length_reg; output_udp_checksum_next = output_udp_checksum_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin // start of frame, grab select value frame_next = 1; select_next = select; diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py index 5177650d4..43428a428 100755 --- a/rtl/udp_mux_64.py +++ b/rtl/udp_mux_64.py @@ -351,12 +351,14 @@ always @* begin output_udp_length_next = output_udp_length_reg; output_udp_checksum_next = output_udp_checksum_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; diff --git a/rtl/udp_mux_64_4.v b/rtl/udp_mux_64_4.v index 0e89faa81..7c964a217 100644 --- a/rtl/udp_mux_64_4.v +++ b/rtl/udp_mux_64_4.v @@ -498,12 +498,14 @@ always @* begin output_udp_length_next = output_udp_length_reg; output_udp_checksum_next = output_udp_checksum_reg; - if (frame_reg) begin - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - frame_next = ~current_input_tlast; + if (current_input_tvalid & current_input_tready) begin + // end of frame detection + if (current_input_tlast) begin + frame_next = 1'b0; end - end else if (enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin + end + + if (~frame_reg & enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; From 0691c9d61b102cdbb3ed73a449786ba096d86a08 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 2 Sep 2016 10:43:21 -0700 Subject: [PATCH 309/617] Fix output pipeline issue --- rtl/axis_async_fifo.v | 2 +- rtl/axis_async_fifo_64.v | 2 +- rtl/axis_async_frame_fifo.v | 2 +- rtl/axis_async_frame_fifo_64.v | 2 +- rtl/axis_fifo.v | 2 +- rtl/axis_fifo_64.v | 2 +- rtl/axis_frame_fifo.v | 2 +- rtl/axis_frame_fifo_64.v | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index b27f95bc7..2b65377c2 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -198,7 +198,7 @@ always @* begin mem_read_data_valid_next = mem_read_data_valid_reg; - if (output_axis_tready | ~output_axis_tvalid) begin + if (store_output | ~mem_read_data_valid_reg) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index bf4c65c80..dc06c403f 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -201,7 +201,7 @@ always @* begin mem_read_data_valid_next = mem_read_data_valid_reg; - if (output_axis_tready | ~output_axis_tvalid) begin + if (store_output | ~mem_read_data_valid_reg) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 5ad1e88fa..884b41274 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -314,7 +314,7 @@ always @* begin mem_read_data_valid_next = mem_read_data_valid_reg; - if (output_axis_tready | ~output_axis_tvalid) begin + if (store_output | ~mem_read_data_valid_reg) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 2f2e576ee..8e1747632 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -317,7 +317,7 @@ always @* begin mem_read_data_valid_next = mem_read_data_valid_reg; - if (output_axis_tready | ~output_axis_tvalid) begin + if (store_output | ~mem_read_data_valid_reg) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index c56b6e4f2..93b137aba 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -127,7 +127,7 @@ always @* begin mem_read_data_valid_next = mem_read_data_valid_reg; - if (output_axis_tready | ~output_axis_tvalid) begin + if (store_output | ~mem_read_data_valid_reg) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v index ca7217b5a..03d3394bc 100644 --- a/rtl/axis_fifo_64.v +++ b/rtl/axis_fifo_64.v @@ -130,7 +130,7 @@ always @* begin mem_read_data_valid_next = mem_read_data_valid_reg; - if (output_axis_tready | ~output_axis_tvalid) begin + if (store_output | ~mem_read_data_valid_reg) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 405a8e584..606166a05 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -189,7 +189,7 @@ always @* begin mem_read_data_valid_next = mem_read_data_valid_reg; - if (output_axis_tready | ~output_axis_tvalid) begin + if (store_output | ~mem_read_data_valid_reg) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index 3d1c4623b..5af317b5a 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -192,7 +192,7 @@ always @* begin mem_read_data_valid_next = mem_read_data_valid_reg; - if (output_axis_tready | ~output_axis_tvalid) begin + if (store_output | ~mem_read_data_valid_reg) begin // output data not valid OR currently being transferred if (~empty) begin // not empty, perform read From 5fa36eeaa7c42b163c2ac04d6fc0d2bad580d515 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 12 Sep 2016 13:38:34 -0700 Subject: [PATCH 310/617] Rework endpoints, update testbenches --- tb/axis_ep.py | 420 ++++++++------ tb/ll_ep.py | 201 ++++--- tb/test_arbiter.py | 65 +-- tb/test_arbiter.v | 27 +- tb/test_arbiter_rr.py | 65 +-- tb/test_arbiter_rr.v | 27 +- tb/test_axis_adapter_64_8.py | 189 +++--- tb/test_axis_adapter_64_8.v | 41 +- tb/test_axis_adapter_8_64.py | 189 +++--- tb/test_axis_adapter_8_64.v | 41 +- tb/test_axis_arb_mux_4.py | 379 +++++------- tb/test_axis_arb_mux_4.v | 80 +-- tb/test_axis_arb_mux_64_4.py | 420 ++++++-------- tb/test_axis_arb_mux_64_4.v | 101 ++-- tb/test_axis_async_fifo.py | 209 +++---- tb/test_axis_async_fifo.v | 49 +- tb/test_axis_async_fifo_64.py | 226 +++----- tb/test_axis_async_fifo_64.v | 59 +- tb/test_axis_async_frame_fifo.py | 232 +++----- tb/test_axis_async_frame_fifo.v | 62 +- tb/test_axis_async_frame_fifo_64.py | 249 +++----- tb/test_axis_async_frame_fifo_64.v | 72 ++- tb/test_axis_cobs_decode.py | 188 +++--- tb/test_axis_cobs_decode.v | 30 +- tb/test_axis_cobs_encode.py | 154 +++-- tb/test_axis_cobs_encode.v | 30 +- tb/test_axis_cobs_encode_zero_frame.py | 154 +++-- tb/test_axis_cobs_encode_zero_frame.v | 30 +- tb/test_axis_crosspoint_4x4.py | 428 ++++++-------- tb/test_axis_crosspoint_4x4.v | 116 ++-- tb/test_axis_crosspoint_64_4x4.py | 493 +++++++--------- tb/test_axis_crosspoint_64_4x4.v | 150 +++-- tb/test_axis_demux_4.py | 344 +++++------ tb/test_axis_demux_4.v | 84 +-- tb/test_axis_demux_64_4.py | 385 +++++-------- tb/test_axis_demux_64_4.v | 106 ++-- tb/test_axis_fifo.py | 205 +++---- tb/test_axis_fifo.v | 47 +- tb/test_axis_fifo_64.py | 222 +++---- tb/test_axis_fifo_64.v | 56 +- tb/test_axis_frame_fifo.py | 216 +++---- tb/test_axis_frame_fifo.v | 54 +- tb/test_axis_frame_fifo_64.py | 238 +++----- tb/test_axis_frame_fifo_64.v | 64 ++- tb/test_axis_frame_join_4.py | 401 ++++++------- tb/test_axis_frame_join_4.v | 112 ++-- tb/test_axis_frame_length_adjust_64.py | 249 ++++---- tb/test_axis_frame_length_adjust_64.v | 57 +- tb/test_axis_frame_length_adjust_8.py | 249 ++++---- tb/test_axis_frame_length_adjust_8.v | 57 +- tb/test_axis_frame_length_adjust_fifo.py | 242 ++++---- tb/test_axis_frame_length_adjust_fifo.v | 53 +- tb/test_axis_frame_length_adjust_fifo_64.py | 259 ++++----- tb/test_axis_frame_length_adjust_fifo_64.v | 57 +- tb/test_axis_ll_bridge.py | 166 +++--- tb/test_axis_ll_bridge.v | 50 +- tb/test_axis_mux_4.py | 345 +++++------ tb/test_axis_mux_4.v | 84 +-- tb/test_axis_mux_64_4.py | 386 +++++-------- tb/test_axis_mux_64_4.v | 106 ++-- tb/test_axis_rate_limit.py | 214 +++---- tb/test_axis_rate_limit.v | 58 +- tb/test_axis_rate_limit_64.py | 231 +++----- tb/test_axis_rate_limit_64.v | 68 ++- tb/test_axis_register.py | 190 +++--- tb/test_axis_register.v | 52 +- tb/test_axis_register_64.py | 203 +++---- tb/test_axis_register_64.v | 62 +- tb/test_axis_srl_fifo.py | 211 +++---- tb/test_axis_srl_fifo.v | 49 +- tb/test_axis_srl_fifo_64.py | 228 +++----- tb/test_axis_srl_fifo_64.v | 59 +- tb/test_axis_srl_register.py | 190 +++--- tb/test_axis_srl_register.v | 52 +- tb/test_axis_srl_register_64.py | 203 +++---- tb/test_axis_srl_register_64.v | 62 +- tb/test_axis_stat_counter.py | 278 ++++----- tb/test_axis_stat_counter.v | 61 +- tb/test_axis_switch_4x4.py | 558 +++++++----------- tb/test_axis_switch_4x4.v | 106 ++-- tb/test_axis_switch_64_4x4.py | 608 ++++++++------------ tb/test_axis_switch_64_4x4.v | 122 ++-- tb/test_axis_tap.py | 201 +++---- tb/test_axis_tap.v | 44 +- tb/test_axis_tap_64.py | 218 +++---- tb/test_axis_tap_64.v | 55 +- tb/test_ll_axis_bridge.py | 165 +++--- tb/test_ll_axis_bridge.v | 44 +- tb/test_priority_encoder.py | 57 +- tb/test_priority_encoder.v | 25 +- 90 files changed, 6485 insertions(+), 8259 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 9c7a36ea9..947576752 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -176,204 +176,258 @@ class AXIStreamFrame(object): def __iter__(self): return self.data.__iter__() -def AXIStreamSource(clk, rst, - tdata=None, - tkeep=Signal(bool(True)), - tvalid=Signal(bool(False)), - tready=Signal(bool(True)), - tlast=Signal(bool(False)), - tdest=Signal(intbv(0)), - tuser=Signal(bool(False)), - fifo=None, - pause=0, - name=None): - tready_int = Signal(bool(False)) - tvalid_int = Signal(bool(False)) +class AXIStreamSource(object): + def __init__(self): + self.has_logic = False + self.queue = [] - @always_comb - def pause_logic(): - tready_int.next = tready and not pause - tvalid.next = tvalid_int and not pause + def send(self, frame): + self.queue.append(AXIStreamFrame(frame)) - @instance - def logic(): - frame = AXIStreamFrame() - data = [] - keep = [] - dest = [] - user = [] - B = 0 - N = len(tdata) - M = len(tkeep) - WL = int((len(tdata)+M-1)/M) + def write(self, data): + self.send(data) - if type(tdata) is list or type(tdata) is tuple: - # multiple tdata signals - B = len(tdata) - N = [len(b) for b in tdata] - M = 1 - WL = [1]*B + def count(self): + return len(self.queue) - while True: - yield clk.posedge, rst.posedge + def empty(self): + return self.count() == 0 - if rst: - if B > 0: - for s in tdata: - s.next = 0 - else: - tdata.next = 0 - tkeep.next = 0 - tdest.next = 0 - tuser.next = False - tvalid_int.next = False - tlast.next = False - else: - if tready_int and tvalid: - if len(data) > 0: - if B > 0: - l = data.pop(0) - for i in range(B): - tdata[i].next = l[i] - else: - tdata.next = data.pop(0) - tkeep.next = keep.pop(0) - tdest.next = dest.pop(0) - tuser.next = user.pop(0) - tvalid_int.next = True - tlast.next = len(data) == 0 - else: - tvalid_int.next = False - tlast.next = False - if (tlast and tready_int and tvalid) or not tvalid_int: - if not fifo.empty(): - frame = fifo.get() - frame = AXIStreamFrame(frame) - frame.B = B - frame.N = N - frame.M = M - frame.WL = WL - data, keep, dest, user = frame.build() - if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) - if B > 0: - l = data.pop(0) - for i in range(B): - tdata[i].next = l[i] - else: - tdata.next = data.pop(0) - tkeep.next = keep.pop(0) - tdest.next = dest.pop(0) - tuser.next = user.pop(0) - tvalid_int.next = True - tlast.next = len(data) == 0 + def create_logic(self, + clk, + rst, + tdata=None, + tkeep=Signal(bool(True)), + tvalid=Signal(bool(False)), + tready=Signal(bool(True)), + tlast=Signal(bool(False)), + tdest=Signal(intbv(0)), + tuser=Signal(bool(False)), + pause=0, + name=None + ): - return logic, pause_logic + assert not self.has_logic + self.has_logic = True -def AXIStreamSink(clk, rst, - tdata=None, - tkeep=Signal(bool(True)), - tvalid=Signal(bool(True)), - tready=Signal(bool(True)), - tlast=Signal(bool(True)), - tdest=Signal(intbv(0)), - tuser=Signal(bool(False)), - fifo=None, - pause=0, - name=None): + tready_int = Signal(bool(False)) + tvalid_int = Signal(bool(False)) - tready_int = Signal(bool(False)) - tvalid_int = Signal(bool(False)) + @always_comb + def pause_logic(): + tready_int.next = tready and not pause + tvalid.next = tvalid_int and not pause - @always_comb - def pause_logic(): - tready.next = tready_int and not pause - tvalid_int.next = tvalid and not pause + @instance + def logic(): + frame = AXIStreamFrame() + data = [] + keep = [] + dest = [] + user = [] + B = 0 + N = len(tdata) + M = len(tkeep) + WL = int((len(tdata)+M-1)/M) - @instance - def logic(): - frame = AXIStreamFrame() - data = [] - keep = [] - dest = [] - user = [] - B = 0 - N = len(tdata) - M = len(tkeep) - WL = int((len(tdata)+M-1)/M) - first = True + if type(tdata) is list or type(tdata) is tuple: + # multiple tdata signals + B = len(tdata) + N = [len(b) for b in tdata] + M = 1 + WL = [1]*B - if type(tdata) is list or type(tdata) is tuple: - # multiple tdata signals - B = len(tdata) - N = [len(b) for b in tdata] - M = 1 - WL = [1]*B - - while True: - yield clk.posedge, rst.posedge - - if rst: - tready_int.next = False - frame = AXIStreamFrame() - data = [] - keep = [] - dest = [] - user = [] - first = True - else: - tready_int.next = True - - if tvalid_int: - - if not skip_asserts: - # zero tkeep not allowed - assert int(tkeep) != 0 - # tkeep must be contiguous - # i.e. 0b00011110 allowed, but 0b00011010 not allowed - b = int(tkeep) - while b & 1 == 0: - b = b >> 1 - while b & 1 == 1: - b = b >> 1 - assert b == 0 - # tkeep must not have gaps across cycles - if not first: - # not first cycle; lowest bit must be set - assert int(tkeep) & 1 - if not tlast: - # not last cycle; highest bit must be set - assert int(tkeep) & (1 << len(tkeep)-1) + while True: + yield clk.posedge, rst.posedge + if rst: if B > 0: - l = [] - for i in range(B): - l.append(int(tdata[i])) - data.append(l) + for s in tdata: + s.next = 0 else: - data.append(int(tdata)) - keep.append(int(tkeep)) - dest.append(int(tdest)) - user.append(int(tuser)) - first = False - if tlast: - frame.B = B - frame.N = N - frame.M = M - frame.WL = WL - frame.parse(data, keep, dest, user) - if fifo is not None: - fifo.put(frame) - if name is not None: - print("[%s] Got frame %s" % (name, repr(frame))) - frame = AXIStreamFrame() - data = [] - keep = [] - dest = [] - user = [] - first = True + tdata.next = 0 + tkeep.next = 0 + tdest.next = 0 + tuser.next = False + tvalid_int.next = False + tlast.next = False + else: + if tready_int and tvalid: + if len(data) > 0: + if B > 0: + l = data.pop(0) + for i in range(B): + tdata[i].next = l[i] + else: + tdata.next = data.pop(0) + tkeep.next = keep.pop(0) + tdest.next = dest.pop(0) + tuser.next = user.pop(0) + tvalid_int.next = True + tlast.next = len(data) == 0 + else: + tvalid_int.next = False + tlast.next = False + if (tlast and tready_int and tvalid) or not tvalid_int: + if len(self.queue) > 0: + frame = self.queue.pop(0) + frame.B = B + frame.N = N + frame.M = M + frame.WL = WL + data, keep, dest, user = frame.build() + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + if B > 0: + l = data.pop(0) + for i in range(B): + tdata[i].next = l[i] + else: + tdata.next = data.pop(0) + tkeep.next = keep.pop(0) + tdest.next = dest.pop(0) + tuser.next = user.pop(0) + tvalid_int.next = True + tlast.next = len(data) == 0 - return logic, pause_logic + return logic, pause_logic + + +class AXIStreamSink(object): + def __init__(self): + self.has_logic = False + self.queue = [] + self.read_queue = [] + + def recv(self): + if len(self.queue) > 0: + return self.queue.pop(0) + return None + + def read(self, count=-1): + while len(self.queue) > 0: + self.read_queue.extend(self.queue.pop(0).data) + if count < 0: + count = len(self.read_queue) + data = self.read_queue[:count] + del self.read_queue[:count] + return data + + def count(self): + return len(self.queue) + + def empty(self): + return self.count() == 0 + + def create_logic(self, + clk, + rst, + tdata=None, + tkeep=Signal(bool(True)), + tvalid=Signal(bool(False)), + tready=Signal(bool(True)), + tlast=Signal(bool(True)), + tdest=Signal(intbv(0)), + tuser=Signal(bool(False)), + pause=0, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + tready_int = Signal(bool(False)) + tvalid_int = Signal(bool(False)) + + @always_comb + def pause_logic(): + tready.next = tready_int and not pause + tvalid_int.next = tvalid and not pause + + @instance + def logic(): + frame = AXIStreamFrame() + data = [] + keep = [] + dest = [] + user = [] + B = 0 + N = len(tdata) + M = len(tkeep) + WL = int((len(tdata)+M-1)/M) + first = True + + if type(tdata) is list or type(tdata) is tuple: + # multiple tdata signals + B = len(tdata) + N = [len(b) for b in tdata] + M = 1 + WL = [1]*B + + while True: + yield clk.posedge, rst.posedge + + if rst: + tready_int.next = False + frame = AXIStreamFrame() + data = [] + keep = [] + dest = [] + user = [] + first = True + else: + tready_int.next = True + + if tvalid_int: + + if not skip_asserts: + # zero tkeep not allowed + assert int(tkeep) != 0 + # tkeep must be contiguous + # i.e. 0b00011110 allowed, but 0b00011010 not allowed + b = int(tkeep) + while b & 1 == 0: + b = b >> 1 + while b & 1 == 1: + b = b >> 1 + assert b == 0 + # tkeep must not have gaps across cycles + if not first: + # not first cycle; lowest bit must be set + assert int(tkeep) & 1 + if not tlast: + # not last cycle; highest bit must be set + assert int(tkeep) & (1 << len(tkeep)-1) + + if B > 0: + l = [] + for i in range(B): + l.append(int(tdata[i])) + data.append(l) + else: + data.append(int(tdata)) + keep.append(int(tkeep)) + dest.append(int(tdest)) + user.append(int(tuser)) + first = False + if tlast: + frame.B = B + frame.N = N + frame.M = M + frame.WL = WL + frame.parse(data, keep, dest, user) + self.queue.append(frame) + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + frame = AXIStreamFrame() + data = [] + keep = [] + dest = [] + user = [] + first = True + + return logic, pause_logic diff --git a/tb/ll_ep.py b/tb/ll_ep.py index e480cb65c..943017c51 100644 --- a/tb/ll_ep.py +++ b/tb/ll_ep.py @@ -24,100 +24,139 @@ 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): +class LocalLinkSource(object): + def __init__(self): + self.has_logic = False + self.queue = [] - src_rdy_out_n_int = Signal(bool(True)) - dst_rdy_in_n_int = Signal(bool(True)) + def send(self, frame): + self.queue.append(bytearray(frame)) - @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 + def count(self): + return len(self.queue) - @instance - def logic(): - frame = [] + def empty(self): + return self.count() == 0 - while True: - yield clk.posedge, rst.posedge + def create_logic(self, + clk, + rst, + data_out, + sof_out_n, + eof_out_n, + src_rdy_out_n, + dst_rdy_in_n, + pause=0, + name=None): - 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 + assert not self.has_logic - return logic, pause_logic + self.has_logic = True + + 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 len(self.queue) > 0: + frame = self.queue.pop(0) + 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): +class LocalLinkSink(object): + def __init__(self): + self.has_logic = False + self.queue = [] - src_rdy_in_n_int = Signal(bool(True)) - dst_rdy_out_n_int = Signal(bool(True)) + def recv(self): + if len(self.queue) > 0: + return self.queue.pop(0) + return None - @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 + def count(self): + return len(self.queue) - @instance - def logic(): - frame = [] + def empty(self): + return self.count() == 0 - while True: - yield clk.posedge, rst.posedge + def create_logic(self, + clk, + rst, + data_in, + sof_in_n, + eof_in_n, + src_rdy_in_n, + dst_rdy_out_n, + pause=0, + name=None): - if rst: - dst_rdy_out_n_int.next = True - frame = [] - else: - dst_rdy_out_n_int.next = False + assert not self.has_logic - 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 = [] + self.has_logic = True - return logic, pause_logic + 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: + self.queue.append(frame) + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + frame = [] + + return logic, pause_logic diff --git a/tb/test_arbiter.py b/tb/test_arbiter.py index 3886ec8c1..44fba8dce 100755 --- a/tb/test_arbiter.py +++ b/tb/test_arbiter.py @@ -27,68 +27,55 @@ from myhdl import * import os module = 'arbiter' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/priority_encoder.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_arbiter(clk, - rst, - current_test, - - request, - acknowledge, - - grant, - grant_valid, - grant_encoded): - - 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, - - request=request, - acknowledge=acknowledge, - - grant=grant, - grant_valid=grant_valid, - grant_encoded=grant_encoded) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + PORTS = 32 + TYPE = "PRIORITY" + BLOCK = "REQUEST" + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - request = Signal(intbv(0)[32:]) - acknowledge = Signal(intbv(0)[32:]) + request = Signal(intbv(0)[PORTS:]) + acknowledge = Signal(intbv(0)[PORTS:]) # Outputs - grant = Signal(intbv(0)[32:]) + grant = Signal(intbv(0)[PORTS:]) grant_valid = Signal(bool(0)) grant_encoded = Signal(intbv(0)[5:]) # DUT - dut = dut_arbiter(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - request, - acknowledge, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - grant, - grant_valid, - grant_encoded) + request=request, + acknowledge=acknowledge, + + grant=grant, + grant_valid=grant_valid, + grant_encoded=grant_encoded + ) @always(delay(4)) def clkgen(): @@ -133,7 +120,7 @@ def bench(): print("test 2: two bits") current_test.next = 2 - + for i in range(32): for j in range(32): l = [i, j] diff --git a/tb/test_arbiter.v b/tb/test_arbiter.v index fd5df4d45..ce9481a2c 100644 --- a/tb/test_arbiter.v +++ b/tb/test_arbiter.v @@ -24,11 +24,14 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for arbiter + */ module test_arbiter; -// parameters +// Parameters localparam PORTS = 32; localparam TYPE = "PRIORITY"; localparam BLOCK = "REQUEST"; @@ -48,14 +51,18 @@ wire [$clog2(PORTS)-1:0] grant_encoded; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - request, - acknowledge); - $to_myhdl(grant, - grant_valid, - grant_encoded); + $from_myhdl( + clk, + rst, + current_test, + request, + acknowledge + ); + $to_myhdl( + grant, + grant_valid, + grant_encoded + ); // dump file $dumpfile("test_arbiter.lxt"); diff --git a/tb/test_arbiter_rr.py b/tb/test_arbiter_rr.py index 162255c94..f6c739da3 100755 --- a/tb/test_arbiter_rr.py +++ b/tb/test_arbiter_rr.py @@ -27,68 +27,55 @@ from myhdl import * import os module = 'arbiter' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/priority_encoder.v") -srcs.append("test_%s_rr.v" % module) +srcs.append("%s_rr.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_arbiter_rr(clk, - rst, - current_test, - - request, - acknowledge, - - grant, - grant_valid, - grant_encoded): - - 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, - - request=request, - acknowledge=acknowledge, - - grant=grant, - grant_valid=grant_valid, - grant_encoded=grant_encoded) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + PORTS = 32 + TYPE = "ROUND_ROBIN" + BLOCK = "REQUEST" + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - request = Signal(intbv(0)[32:]) - acknowledge = Signal(intbv(0)[32:]) + request = Signal(intbv(0)[PORTS:]) + acknowledge = Signal(intbv(0)[PORTS:]) # Outputs - grant = Signal(intbv(0)[32:]) + grant = Signal(intbv(0)[PORTS:]) grant_valid = Signal(bool(0)) grant_encoded = Signal(intbv(0)[5:]) # DUT - dut = dut_arbiter_rr(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - request, - acknowledge, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - grant, - grant_valid, - grant_encoded) + request=request, + acknowledge=acknowledge, + + grant=grant, + grant_valid=grant_valid, + grant_encoded=grant_encoded + ) @always(delay(4)) def clkgen(): @@ -173,7 +160,7 @@ def bench(): print("test 3: two bits") current_test.next = 3 - + for i in range(32): for j in range(32): l = [i, j] diff --git a/tb/test_arbiter_rr.v b/tb/test_arbiter_rr.v index 7089bbc53..31c8824e8 100644 --- a/tb/test_arbiter_rr.v +++ b/tb/test_arbiter_rr.v @@ -24,11 +24,14 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for arbiter + */ module test_arbiter_rr; -// parameters +// Parameters localparam PORTS = 32; localparam TYPE = "ROUND_ROBIN"; localparam BLOCK = "REQUEST"; @@ -48,14 +51,18 @@ wire [$clog2(PORTS)-1:0] grant_encoded; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - request, - acknowledge); - $to_myhdl(grant, - grant_valid, - grant_encoded); + $from_myhdl( + clk, + rst, + current_test, + request, + acknowledge + ); + $to_myhdl( + grant, + grant_valid, + grant_encoded + ); // dump file $dumpfile("test_arbiter_rr.lxt"); diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index 489f1511b..3eb74aa51 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -26,72 +26,35 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_adapter' +testbench = 'test_%s_64_8' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s_64_8.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_adapter_64_8(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + INPUT_DATA_WIDTH = 64 + INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8) + OUTPUT_DATA_WIDTH = 8 + OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8) + # 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_tdata = Signal(intbv(0)[INPUT_DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[INPUT_KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -99,60 +62,70 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tkeep = Signal(intbv(0)[1:]) + output_axis_tdata = Signal(intbv(0)[OUTPUT_DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[OUTPUT_KEEP_WIDTH:]) 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_adapter_64_8(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + 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 + ) @always(delay(4)) def clkgen(): @@ -202,7 +175,7 @@ def bench(): bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge @@ -212,13 +185,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -236,8 +207,8 @@ def bench(): bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -247,19 +218,15 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -279,8 +246,8 @@ def bench(): test_frame1.user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -290,26 +257,22 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.user[-1] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_adapter_64_8.v b/tb/test_axis_adapter_64_8.v index cb6c13efd..431fbbe33 100644 --- a/tb/test_axis_adapter_64_8.v +++ b/tb/test_axis_adapter_64_8.v @@ -24,11 +24,14 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_adapter + */ module test_axis_adapter_64_8; -// parameters +// Parameters localparam INPUT_DATA_WIDTH = 64; localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); localparam OUTPUT_DATA_WIDTH = 8; @@ -56,21 +59,25 @@ 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); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready + ); + $to_myhdl( + input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_adapter_64_8.lxt"); diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index 32177f261..11f8e2c63 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -26,72 +26,35 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_adapter' +testbench = 'test_%s_8_64' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s_8_64.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_adapter_8_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + INPUT_DATA_WIDTH = 8 + INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8) + OUTPUT_DATA_WIDTH = 64 + OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) - input_axis_tkeep = Signal(intbv(0)[1:]) + input_axis_tdata = Signal(intbv(0)[INPUT_DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[INPUT_KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -99,60 +62,70 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[OUTPUT_DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[OUTPUT_KEEP_WIDTH:]) 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_adapter_8_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + 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 + ) @always(delay(4)) def clkgen(): @@ -202,7 +175,7 @@ def bench(): bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge @@ -212,13 +185,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -236,8 +207,8 @@ def bench(): bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -247,19 +218,15 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -279,8 +246,8 @@ def bench(): test_frame1.user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -290,26 +257,22 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.user[-1] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_adapter_8_64.v b/tb/test_axis_adapter_8_64.v index def892687..0999520b1 100644 --- a/tb/test_axis_adapter_8_64.v +++ b/tb/test_axis_adapter_8_64.v @@ -24,11 +24,14 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_adapter + */ module test_axis_adapter_8_64; -// parameters +// Parameters localparam INPUT_DATA_WIDTH = 8; localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); localparam OUTPUT_DATA_WIDTH = 64; @@ -56,21 +59,25 @@ 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); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready + ); + $to_myhdl( + input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_adapter_8_64.lxt"); diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index 7f20e6622..482614b6d 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -26,14 +26,10 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_arb_mux_4' +testbench = 'test_%s' % module srcs = [] @@ -41,97 +37,35 @@ srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/axis_mux_4.v") srcs.append("../rtl/arbiter.v") srcs.append("../rtl/priority_encoder.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_arb_mux_4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tuser=input_3_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[8:]) + input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) input_0_axis_tuser = Signal(bool(0)) - input_1_axis_tdata = Signal(intbv(0)[8:]) + input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) input_1_axis_tuser = Signal(bool(0)) - input_2_axis_tdata = Signal(intbv(0)[8:]) + input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) input_2_axis_tuser = Signal(bool(0)) - input_3_axis_tdata = Signal(intbv(0)[8:]) + input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) input_3_axis_tuser = Signal(bool(0)) @@ -144,106 +78,125 @@ def bench(): input_2_axis_tready = Signal(bool(0)) input_3_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) # sources and sinks - source_0_queue = Queue() source_0_pause = Signal(bool(0)) - source_1_queue = Queue() source_1_pause = Signal(bool(0)) - source_2_queue = Queue() source_2_pause = Signal(bool(0)) - source_3_queue = Queue() source_3_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_0_axis_tdata, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tuser=input_0_axis_tuser, - fifo=source_0_queue, - pause=source_0_pause, - name='source0') - source_1 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_1_axis_tdata, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tuser=input_1_axis_tuser, - fifo=source_1_queue, - pause=source_1_pause, - name='source1') - source_2 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_2_axis_tdata, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tuser=input_2_axis_tuser, - fifo=source_2_queue, - pause=source_2_pause, - name='source2') - source_3 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_3_axis_tdata, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tuser=input_3_axis_tuser, - fifo=source_3_queue, - pause=source_3_pause, - name='source3') + source_0 = axis_ep.AXIStreamSource() - 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') + source_0_logic = source_0.create_logic( + clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + pause=source_0_pause, + name='source_0' + ) + + source_1 = axis_ep.AXIStreamSource() + + source_1_logic = source_1.create_logic( + clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + pause=source_1_pause, + name='source_1' + ) + + source_2 = axis_ep.AXIStreamSource() + + source_2_logic = source_2.create_logic( + clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + pause=source_2_pause, + name='source_2' + ) + + source_3 = axis_ep.AXIStreamSource() + + source_3_logic = source_3.create_logic( + clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + pause=source_3_pause, + name='source_3' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_arb_mux_4(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser + ) @always(delay(4)) def clkgen(): @@ -270,7 +223,7 @@ def bench(): b'\x5A\x00\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_0_queue.put(test_frame) + source_0.send(test_frame) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -278,9 +231,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -294,7 +245,7 @@ def bench(): b'\x5A\x01\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame) + source_1.send(test_frame) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -302,9 +253,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -322,8 +271,8 @@ def bench(): b'\x5A\x00\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_0_queue.put(test_frame1) - source_0_queue.put(test_frame2) + source_0.send(test_frame1) + source_0.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -331,15 +280,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -357,8 +302,8 @@ def bench(): b'\x5A\x02\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -366,15 +311,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -392,8 +333,8 @@ def bench(): b'\x5A\x02\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -412,15 +353,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -438,8 +375,8 @@ def bench(): b'\x5A\x02\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -452,23 +389,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 yield delay(100) yield clk.posedge - print("test 4: back-to-back packets, different ports, arbitration test") - current_test.next = 4 + print("test 7: back-to-back packets, different ports, arbitration test") + current_test.next = 7 test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x01\x52\x53\x54\x55' + @@ -478,56 +411,44 @@ def bench(): b'\x5A\x02\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_2_queue.put(test_frame2) - source_2_queue.put(test_frame2) - source_2_queue.put(test_frame2) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_2.send(test_frame2) + source_2.send(test_frame2) + source_2.send(test_frame2) + source_2.send(test_frame2) yield clk.posedge yield delay(800) yield clk.posedge - source_1_queue.put(test_frame1) - + source_1.send(test_frame1) + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -535,7 +456,7 @@ def bench(): raise StopSimulation - return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_arb_mux_4.v b/tb/test_axis_arb_mux_4.v index 533c5f03d..5319976fc 100644 --- a/tb/test_axis_arb_mux_4.v +++ b/tb/test_axis_arb_mux_4.v @@ -24,28 +24,34 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_arb_mux_4 + */ module test_axis_arb_mux_4; +// Parameters +localparam DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_0_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; reg input_0_axis_tuser = 0; -reg [7:0] input_1_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; reg input_1_axis_tuser = 0; -reg [7:0] input_2_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; reg input_2_axis_tuser = 0; -reg [7:0] input_3_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; reg input_3_axis_tuser = 0; @@ -58,41 +64,45 @@ wire input_1_axis_tready; wire input_2_axis_tready; wire input_3_axis_tready; -wire [7:0] output_axis_tdata; +wire [DATA_WIDTH-1: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_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tuser, - output_axis_tready); - $to_myhdl(input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready + ); + $to_myhdl( + input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_arb_mux_4.lxt"); @@ -100,7 +110,7 @@ initial begin end axis_arb_mux_4 #( - .DATA_WIDTH(8) + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_arb_mux_64_4.py b/tb/test_axis_arb_mux_64_4.py index 55253cb12..cbb020dd7 100755 --- a/tb/test_axis_arb_mux_64_4.py +++ b/tb/test_axis_arb_mux_64_4.py @@ -26,14 +26,10 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_arb_mux_64_4' +testbench = 'test_%s' % module srcs = [] @@ -41,111 +37,40 @@ srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/axis_mux_64_4.v") srcs.append("../rtl/arbiter.v") srcs.append("../rtl/priority_encoder.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_arb_mux_64_4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_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_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tuser=input_3_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[64:]) - input_0_axis_tkeep = Signal(intbv(0)[8:]) + input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) input_0_axis_tuser = Signal(bool(0)) - input_1_axis_tdata = Signal(intbv(0)[64:]) - input_1_axis_tkeep = Signal(intbv(0)[8:]) + input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) input_1_axis_tuser = Signal(bool(0)) - input_2_axis_tdata = Signal(intbv(0)[64:]) - input_2_axis_tkeep = Signal(intbv(0)[8:]) + input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) input_2_axis_tuser = Signal(bool(0)) - input_3_axis_tdata = Signal(intbv(0)[64:]) - input_3_axis_tkeep = Signal(intbv(0)[8:]) + input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) input_3_axis_tuser = Signal(bool(0)) @@ -158,117 +83,136 @@ def bench(): input_2_axis_tready = Signal(bool(0)) input_3_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) # sources and sinks - source_0_queue = Queue() source_0_pause = Signal(bool(0)) - source_1_queue = Queue() source_1_pause = Signal(bool(0)) - source_2_queue = Queue() source_2_pause = Signal(bool(0)) - source_3_queue = Queue() source_3_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tuser=input_0_axis_tuser, - fifo=source_0_queue, - pause=source_0_pause, - name='source0') - source_1 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tuser=input_1_axis_tuser, - fifo=source_1_queue, - pause=source_1_pause, - name='source1') - source_2 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tuser=input_2_axis_tuser, - fifo=source_2_queue, - pause=source_2_pause, - name='source2') - source_3 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tuser=input_3_axis_tuser, - fifo=source_3_queue, - pause=source_3_pause, - name='source3') + source_0 = axis_ep.AXIStreamSource() - 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') + source_0_logic = source_0.create_logic( + clk, + rst, + tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + pause=source_0_pause, + name='source_0' + ) + + source_1 = axis_ep.AXIStreamSource() + + source_1_logic = source_1.create_logic( + clk, + rst, + tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + pause=source_1_pause, + name='source_1' + ) + + source_2 = axis_ep.AXIStreamSource() + + source_2_logic = source_2.create_logic( + clk, + rst, + tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + pause=source_2_pause, + name='source_2' + ) + + source_3 = axis_ep.AXIStreamSource() + + source_3_logic = source_3.create_logic( + clk, + rst, + tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + pause=source_3_pause, + name='source_3' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_arb_mux_64_4(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, + + output_axis_tdata=output_axis_tdata, + output_axis_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 + ) @always(delay(4)) def clkgen(): @@ -295,7 +239,7 @@ def bench(): b'\x5A\x00\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_0_queue.put(test_frame) + source_0.send(test_frame) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -303,9 +247,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -319,7 +261,7 @@ def bench(): b'\x5A\x01\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame) + source_1.send(test_frame) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -327,9 +269,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -347,8 +287,8 @@ def bench(): b'\x5A\x00\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_0_queue.put(test_frame1) - source_0_queue.put(test_frame2) + source_0.send(test_frame1) + source_0.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -356,15 +296,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -382,8 +318,8 @@ def bench(): b'\x5A\x02\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -391,15 +327,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -417,8 +349,8 @@ def bench(): b'\x5A\x02\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -437,15 +369,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -463,8 +391,8 @@ def bench(): b'\x5A\x02\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -477,23 +405,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 yield delay(100) yield clk.posedge - print("test 4: back-to-back packets, different ports, arbitration test") - current_test.next = 4 + print("test 7: back-to-back packets, different ports, arbitration test") + current_test.next = 7 test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x01\x52\x53\x54\x55' + @@ -503,56 +427,44 @@ def bench(): b'\x5A\x02\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_2_queue.put(test_frame2) - source_2_queue.put(test_frame2) - source_2_queue.put(test_frame2) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_2.send(test_frame2) + source_2.send(test_frame2) + source_2.send(test_frame2) + source_2.send(test_frame2) yield clk.posedge yield delay(150) yield clk.posedge - source_1_queue.put(test_frame1) - + source_1.send(test_frame1) + while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -560,7 +472,7 @@ def bench(): raise StopSimulation - return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_arb_mux_64_4.v b/tb/test_axis_arb_mux_64_4.v index 7350e2ef3..1ae68d750 100644 --- a/tb/test_axis_arb_mux_64_4.v +++ b/tb/test_axis_arb_mux_64_4.v @@ -24,32 +24,39 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_arb_mux_64_4 + */ module test_axis_arb_mux_64_4; +// Parameters +localparam DATA_WIDTH = 64; +localparam KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] input_0_axis_tdata = 0; -reg [7:0] input_0_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; reg input_0_axis_tuser = 0; -reg [63:0] input_1_axis_tdata = 0; -reg [7:0] input_1_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; reg input_1_axis_tuser = 0; -reg [63:0] input_2_axis_tdata = 0; -reg [7:0] input_2_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; reg input_2_axis_tuser = 0; -reg [63:0] input_3_axis_tdata = 0; -reg [7:0] input_3_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; reg input_3_axis_tuser = 0; @@ -62,47 +69,51 @@ wire input_1_axis_tready; wire input_2_axis_tready; wire input_3_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tuser, - output_axis_tready); - $to_myhdl(input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready + ); + $to_myhdl( + input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_arb_mux_64_4.lxt"); @@ -110,7 +121,7 @@ initial begin end axis_arb_mux_64_4 #( - .DATA_WIDTH(64) + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index caa337868..97f2c93e7 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -26,70 +26,33 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_async_fifo' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_async_fifo(async_rst, - input_clk, - output_clk, - 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, - async_rst=async_rst, - input_clk=input_clk, - output_clk=output_clk, - 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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + ADDR_WIDTH = 2 + DATA_WIDTH = 8 + # Inputs async_rst = Signal(bool(0)) input_clk = Signal(bool(0)) output_clk = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -97,56 +60,66 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) 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(input_clk, - async_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') + source = axis_ep.AXIStreamSource() - sink = axis_ep.AXIStreamSink(output_clk, - async_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') + source_logic = source.create_logic( + input_clk, + async_rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + output_clk, + async_rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_async_fifo(async_rst, - input_clk, - output_clk, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + async_rst=async_rst, + input_clk=input_clk, + output_clk=output_clk, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + 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 + ) @always(delay(4)) def input_clkgen(): @@ -179,16 +152,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield output_axis_tlast.posedge yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -202,16 +173,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield output_axis_tlast.posedge yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -223,7 +192,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield delay(64) @@ -244,9 +213,7 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -264,8 +231,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge yield output_axis_tlast.posedge @@ -274,15 +241,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -300,8 +263,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -315,15 +278,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -341,8 +300,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -356,15 +315,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -379,16 +334,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield output_axis_tlast.posedge yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -402,7 +355,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge @@ -413,9 +366,7 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -428,7 +379,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge @@ -446,13 +397,13 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, input_clkgen, output_clkgen, check + return dut, source_logic, sink_logic, input_clkgen, output_clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_fifo.v b/tb/test_axis_async_fifo.v index 0c5c2138d..cfd0aa00b 100644 --- a/tb/test_axis_async_fifo.v +++ b/tb/test_axis_async_fifo.v @@ -24,17 +24,24 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_async_fifo + */ module test_axis_async_fifo; +// Parameters +parameter ADDR_WIDTH = 2; +parameter DATA_WIDTH = 8; + // Inputs reg async_rst = 0; reg input_clk = 0; reg output_clk = 0; reg [7:0] current_test = 0; -reg [7:0] input_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -42,27 +49,31 @@ reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [7:0] output_axis_tdata; +wire [DATA_WIDTH-1:0] output_axis_tdata; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(async_rst, - input_clk, - output_clk, - 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); + $from_myhdl( + async_rst, + input_clk, + output_clk, + 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_async_fifo.lxt"); @@ -70,8 +81,8 @@ initial begin end axis_async_fifo #( - .ADDR_WIDTH(2), - .DATA_WIDTH(8) + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH) ) UUT ( // Common reset diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index 94a45d0ae..8d4fbcf80 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -26,75 +26,35 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_async_fifo_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_async_fifo_64(async_rst, - input_clk, - output_clk, - 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, - async_rst=async_rst, - input_clk=input_clk, - output_clk=output_clk, - 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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + ADDR_WIDTH = 2 + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # Inputs async_rst = Signal(bool(0)) input_clk = Signal(bool(0)) output_clk = 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -102,61 +62,71 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) 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(input_clk, - async_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') + source = axis_ep.AXIStreamSource() - sink = axis_ep.AXIStreamSink(output_clk, - async_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') + source_logic = source.create_logic( + input_clk, + async_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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + output_clk, + async_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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_async_fifo_64(async_rst, - input_clk, - output_clk, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + async_rst=async_rst, + input_clk=input_clk, + output_clk=output_clk, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + 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 + ) @always(delay(4)) def input_clkgen(): @@ -189,16 +159,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield output_axis_tlast.posedge yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -212,16 +180,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield output_axis_tlast.posedge yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -233,7 +199,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield delay(64) @@ -254,9 +220,7 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -274,8 +238,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge yield output_axis_tlast.posedge @@ -284,15 +248,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -310,8 +270,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -325,15 +285,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -351,8 +307,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -366,15 +322,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -389,16 +341,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield output_axis_tlast.posedge yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -412,7 +362,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge @@ -423,9 +373,7 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -438,7 +386,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge @@ -456,13 +404,13 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, input_clkgen, output_clkgen, check + return dut, source_logic, sink_logic, input_clkgen, output_clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_fifo_64.v b/tb/test_axis_async_fifo_64.v index 280fa8b0d..672a2368d 100644 --- a/tb/test_axis_async_fifo_64.v +++ b/tb/test_axis_async_fifo_64.v @@ -24,18 +24,26 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_async_fifo_64 + */ module test_axis_async_fifo_64; +// Parameters +parameter ADDR_WIDTH = 2; +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg async_rst = 0; reg input_clk = 0; reg output_clk = 0; reg [7:0] current_test = 0; -reg [63:0] input_axis_tdata = 0; -reg [7:0] input_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -43,30 +51,34 @@ reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(async_rst, - input_clk, - output_clk, - 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); + $from_myhdl( + async_rst, + input_clk, + output_clk, + 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_async_fifo_64.lxt"); @@ -74,8 +86,9 @@ initial begin end axis_async_fifo_64 #( - .ADDR_WIDTH(2), - .DATA_WIDTH(64) + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) ) UUT ( // Common reset diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index 0eff45e0a..e69cd5335 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -26,82 +26,34 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_async_frame_fifo' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_async_frame_fifo(async_rst, - input_clk, - output_clk, - 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, - - input_status_overflow, - input_status_bad_frame, - input_status_good_frame, - output_status_overflow, - output_status_bad_frame, - output_status_good_frame): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - async_rst=async_rst, - input_clk=input_clk, - output_clk=output_clk, - 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, - - input_status_overflow=input_status_overflow, - input_status_bad_frame=input_status_bad_frame, - input_status_good_frame=input_status_good_frame, - output_status_overflow=output_status_overflow, - output_status_bad_frame=output_status_bad_frame, - output_status_good_frame=output_status_good_frame) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + ADDR_WIDTH = 9 + DATA_WIDTH = 8 + DROP_WHEN_FULL = 0 + # Inputs async_rst = Signal(bool(0)) input_clk = Signal(bool(0)) output_clk = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -109,7 +61,7 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) input_status_overflow = Signal(bool(0)) @@ -120,55 +72,65 @@ def bench(): output_status_good_frame = 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(input_clk, - async_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') + source = axis_ep.AXIStreamSource() - sink = axis_ep.AXIStreamSink(output_clk, - async_rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - fifo=sink_queue, - pause=sink_pause, - name='sink') + source_logic = source.create_logic( + input_clk, + async_rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + output_clk, + async_rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_async_frame_fifo(async_rst, - input_clk, - output_clk, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + async_rst=async_rst, + input_clk=input_clk, + output_clk=output_clk, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, + 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, - input_status_overflow, - input_status_bad_frame, - input_status_good_frame, - output_status_overflow, - output_status_bad_frame, - output_status_good_frame) + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + + input_status_overflow=input_status_overflow, + input_status_bad_frame=input_status_bad_frame, + input_status_good_frame=input_status_good_frame, + output_status_overflow=output_status_overflow, + output_status_bad_frame=output_status_bad_frame, + output_status_good_frame=output_status_good_frame + ) @always(delay(4)) def input_clkgen(): @@ -234,16 +196,14 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield output_axis_tlast.posedge yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -272,16 +232,14 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield output_axis_tlast.posedge yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -308,7 +266,7 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield delay(64) @@ -329,9 +287,7 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -364,8 +320,8 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge yield output_axis_tlast.posedge @@ -374,15 +330,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -415,8 +367,8 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -434,15 +386,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -475,8 +423,8 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -490,15 +438,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -528,12 +472,12 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield delay(1000) - assert sink_queue.empty() + assert sink.empty() assert not input_status_overflow_asserted assert input_status_bad_frame_asserted @@ -560,12 +504,12 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield delay(10000) - assert sink_queue.empty() + assert sink.empty() assert input_status_overflow_asserted assert not input_status_bad_frame_asserted @@ -583,7 +527,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge @@ -594,9 +538,7 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -609,7 +551,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge @@ -627,13 +569,13 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, monitor_1, monitor_2, source, sink, input_clkgen, output_clkgen, check + return dut, monitor_1, monitor_2, source_logic, sink_logic, input_clkgen, output_clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index b2606ca6e..e55e1ee21 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -24,17 +24,25 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_async_frame_fifo + */ module test_axis_async_frame_fifo; +// Parameters +parameter ADDR_WIDTH = 9; +parameter DATA_WIDTH = 8; +parameter DROP_WHEN_FULL = 0; + // Inputs reg async_rst = 0; reg input_clk = 0; reg output_clk = 0; reg [7:0] current_test = 0; -reg [7:0] input_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -42,7 +50,7 @@ reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [7:0] output_axis_tdata; +wire [DATA_WIDTH-1:0] output_axis_tdata; wire output_axis_tvalid; wire output_axis_tlast; wire input_status_overflow; @@ -54,25 +62,29 @@ wire output_status_good_frame; initial begin // myhdl integration - $from_myhdl(async_rst, - input_clk, - output_clk, - 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, - input_status_overflow, - input_status_bad_frame, - input_status_good_frame, - output_status_overflow, - output_status_bad_frame, - output_status_good_frame); + $from_myhdl( + async_rst, + input_clk, + output_clk, + 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, + input_status_overflow, + input_status_bad_frame, + input_status_good_frame, + output_status_overflow, + output_status_bad_frame, + output_status_good_frame + ); // dump file $dumpfile("test_axis_async_frame_fifo.lxt"); @@ -80,9 +92,9 @@ initial begin end axis_async_frame_fifo #( - .ADDR_WIDTH(9), - .DATA_WIDTH(8), - .DROP_WHEN_FULL(0) + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .DROP_WHEN_FULL(DROP_WHEN_FULL) ) UUT ( // Common reset diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index dcf0acb00..85cb45436 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -26,87 +26,36 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_async_frame_fifo_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_async_frame_fifo_64(async_rst, - input_clk, - output_clk, - 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, - - input_status_overflow, - input_status_bad_frame, - input_status_good_frame, - output_status_overflow, - output_status_bad_frame, - output_status_good_frame): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - async_rst=async_rst, - input_clk=input_clk, - output_clk=output_clk, - 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, - - input_status_overflow=input_status_overflow, - input_status_bad_frame=input_status_bad_frame, - input_status_good_frame=input_status_good_frame, - output_status_overflow=output_status_overflow, - output_status_bad_frame=output_status_bad_frame, - output_status_good_frame=output_status_good_frame) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + ADDR_WIDTH = 6 + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + DROP_WHEN_FULL = 0 + # Inputs async_rst = Signal(bool(0)) input_clk = Signal(bool(0)) output_clk = 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -114,8 +63,8 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) input_status_overflow = Signal(bool(0)) @@ -126,59 +75,69 @@ def bench(): output_status_good_frame = 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(input_clk, - async_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') + source = axis_ep.AXIStreamSource() - sink = axis_ep.AXIStreamSink(output_clk, - async_rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - fifo=sink_queue, - pause=sink_pause, - name='sink') + source_logic = source.create_logic( + input_clk, + async_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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + output_clk, + async_rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_async_frame_fifo_64(async_rst, - input_clk, - output_clk, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + async_rst=async_rst, + input_clk=input_clk, + output_clk=output_clk, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, + 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, - input_status_overflow, - input_status_bad_frame, - input_status_good_frame, - output_status_overflow, - output_status_bad_frame, - output_status_good_frame) + 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, + + input_status_overflow=input_status_overflow, + input_status_bad_frame=input_status_bad_frame, + input_status_good_frame=input_status_good_frame, + output_status_overflow=output_status_overflow, + output_status_bad_frame=output_status_bad_frame, + output_status_good_frame=output_status_good_frame + ) @always(delay(4)) def input_clkgen(): @@ -244,16 +203,14 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield output_axis_tlast.posedge yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -282,16 +239,14 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield output_axis_tlast.posedge yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -318,7 +273,7 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield delay(64) @@ -339,9 +294,7 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -374,8 +327,8 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge yield output_axis_tlast.posedge @@ -384,15 +337,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -425,8 +374,8 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -444,15 +393,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -485,8 +430,8 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield input_clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -500,15 +445,11 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -538,12 +479,12 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield delay(1000) - assert sink_queue.empty() + assert sink.empty() assert not input_status_overflow_asserted assert input_status_bad_frame_asserted @@ -570,12 +511,12 @@ def bench(): output_status_bad_frame_asserted.next = 0 output_status_good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield delay(10000) - assert sink_queue.empty() + assert sink.empty() assert input_status_overflow_asserted assert not input_status_bad_frame_asserted @@ -593,7 +534,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge @@ -604,9 +545,7 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -619,7 +558,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield input_clk.posedge yield input_clk.posedge yield input_clk.posedge @@ -637,13 +576,13 @@ def bench(): yield output_clk.posedge yield output_clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, monitor_1, monitor_2, source, sink, input_clkgen, output_clkgen, check + return dut, monitor_1, monitor_2, source_logic, sink_logic, input_clkgen, output_clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index 11e7cbc07..6337c5e3b 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -24,18 +24,27 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_async_frame_fifo_64 + */ module test_axis_async_frame_fifo_64; +// Parameters +parameter ADDR_WIDTH = 6; +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter DROP_WHEN_FULL = 0; + // Inputs reg async_rst = 0; reg input_clk = 0; reg output_clk = 0; reg [7:0] current_test = 0; -reg [63:0] input_axis_tdata = 0; -reg [7:0] input_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -43,8 +52,8 @@ reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire input_status_overflow; @@ -56,27 +65,31 @@ wire output_status_good_frame; initial begin // myhdl integration - $from_myhdl(async_rst, - input_clk, - output_clk, - 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, - input_status_overflow, - input_status_bad_frame, - input_status_good_frame, - output_status_overflow, - output_status_bad_frame, - output_status_good_frame); + $from_myhdl( + async_rst, + input_clk, + output_clk, + 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, + input_status_overflow, + input_status_bad_frame, + input_status_good_frame, + output_status_overflow, + output_status_bad_frame, + output_status_good_frame + ); // dump file $dumpfile("test_axis_async_frame_fifo_64.lxt"); @@ -84,9 +97,10 @@ initial begin end axis_async_frame_fifo_64 #( - .ADDR_WIDTH(6), - .DATA_WIDTH(64), - .DROP_WHEN_FULL(0) + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .DROP_WHEN_FULL(DROP_WHEN_FULL) ) UUT ( // Common reset diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py index 4487a30c1..1adcac4a1 100755 --- a/tb/test_axis_cobs_decode.py +++ b/tb/test_axis_cobs_decode.py @@ -26,15 +26,10 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_cobs_decode' -testbench = 'test_axis_cobs_decode' +testbench = 'test_%s' % module srcs = [] @@ -45,37 +40,6 @@ src = ' '.join(srcs) build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) -def dut_axis_cobs_decode(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 %s.vvp -lxt2" % testbench, - 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 cobs_encode(block): block = bytearray(block) enc = bytearray() @@ -167,47 +131,59 @@ def bench(): 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_cobs_decode(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") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + 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 + ) @always(delay(4)) def clkgen(): @@ -217,7 +193,7 @@ def bench(): i = 4 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + if input_axis_tvalid or output_axis_tvalid or not source.empty(): i = 4 yield clk.posedge @@ -225,7 +201,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + if input_axis_tvalid or output_axis_tvalid or not source.empty(): i = 2 source_pause.next = True yield clk.posedge @@ -238,7 +214,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + if input_axis_tvalid or output_axis_tvalid or not source.empty(): i = 2 sink_pause.next = True yield clk.posedge @@ -266,7 +242,7 @@ def bench(): bytearray([k%255+1 for k in range(payload_len)]), b'\x00'+bytearray([k%255+1 for k in range(payload_len)])+b'\x00', bytearray([next(gen) for i in range(payload_len)])]: - + yield clk.posedge print("test 1: test packet, length %d" % payload_len) current_test.next = 1 @@ -276,7 +252,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(enc) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge @@ -285,13 +261,13 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -304,7 +280,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(enc+b'\x00') for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge @@ -313,13 +289,13 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -331,8 +307,8 @@ def bench(): test_frame1 = axis_ep.AXIStreamFrame(enc) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -341,19 +317,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block assert not rx_frame.user[-1] - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -364,7 +340,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(enc+b'\x00'+enc+b'\x00') for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge @@ -373,19 +349,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block assert not rx_frame.user[-1] - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -400,9 +376,9 @@ def bench(): test_frame1.user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) - source_queue.put(test_frame3) + source.send(test_frame1) + source.send(test_frame2) + source.send(test_frame3) yield clk.posedge yield clk.posedge @@ -411,21 +387,21 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert rx_frame.user[-1] - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert rx_frame.user[-1] - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -440,9 +416,9 @@ def bench(): test_frame1.user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) - source_queue.put(test_frame3) + source.send(test_frame1) + source.send(test_frame2) + source.send(test_frame3) yield clk.posedge yield clk.posedge @@ -451,27 +427,27 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert rx_frame.user[-1] - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert rx_frame.user[-1] - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_cobs_decode.v b/tb/test_axis_cobs_decode.v index 07e20affa..a831cd712 100644 --- a/tb/test_axis_cobs_decode.v +++ b/tb/test_axis_cobs_decode.v @@ -53,19 +53,23 @@ 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); + $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_cobs_decode.lxt"); diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py index e3efef76b..79ccd2006 100755 --- a/tb/test_axis_cobs_encode.py +++ b/tb/test_axis_cobs_encode.py @@ -26,15 +26,10 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_cobs_encode' -testbench = 'test_axis_cobs_encode' +testbench = 'test_%s' % module srcs = [] @@ -46,37 +41,6 @@ src = ' '.join(srcs) build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) -def dut_axis_cobs_encode(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 %s.vvp -lxt2" % testbench, - 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 cobs_encode(block): block = bytearray(block) enc = bytearray() @@ -168,47 +132,59 @@ def bench(): 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_cobs_encode(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") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + 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 + ) @always(delay(4)) def clkgen(): @@ -218,7 +194,7 @@ def bench(): i = 4 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + if input_axis_tvalid or output_axis_tvalid or not source.empty(): i = 4 yield clk.posedge @@ -226,7 +202,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + if input_axis_tvalid or output_axis_tvalid or not source.empty(): i = 2 source_pause.next = True yield clk.posedge @@ -239,7 +215,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + if input_axis_tvalid or output_axis_tvalid or not source.empty(): i = 2 sink_pause.next = True yield clk.posedge @@ -276,7 +252,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(block) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge @@ -285,14 +261,14 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc assert cobs_decode(rx_frame.data) == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -304,8 +280,8 @@ def bench(): test_frame2 = axis_ep.AXIStreamFrame(block) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -314,21 +290,21 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc assert cobs_decode(rx_frame.data) == block assert not rx_frame.user[-1] - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc assert cobs_decode(rx_frame.data) == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -342,8 +318,8 @@ def bench(): test_frame1.user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -352,25 +328,25 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(rx_frame.data) == None assert rx_frame.user[-1] - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc assert cobs_decode(rx_frame.data) == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_cobs_encode.v b/tb/test_axis_cobs_encode.v index 9e40ca835..7aa47b5d4 100644 --- a/tb/test_axis_cobs_encode.v +++ b/tb/test_axis_cobs_encode.v @@ -54,19 +54,23 @@ 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); + $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_cobs_encode.lxt"); diff --git a/tb/test_axis_cobs_encode_zero_frame.py b/tb/test_axis_cobs_encode_zero_frame.py index a7171f8fc..b24df1131 100755 --- a/tb/test_axis_cobs_encode_zero_frame.py +++ b/tb/test_axis_cobs_encode_zero_frame.py @@ -26,15 +26,10 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_cobs_encode' -testbench = 'test_axis_cobs_encode_zero_frame' +testbench = 'test_%s_zero_frame' % module srcs = [] @@ -46,37 +41,6 @@ src = ' '.join(srcs) build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) -def dut_axis_cobs_encode(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 %s.vvp -lxt2" % testbench, - 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 cobs_encode(block): block = bytearray(block) enc = bytearray() @@ -168,47 +132,59 @@ def bench(): 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_cobs_encode(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") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + 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 + ) @always(delay(4)) def clkgen(): @@ -218,7 +194,7 @@ def bench(): i = 4 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + if input_axis_tvalid or output_axis_tvalid or not source.empty(): i = 4 yield clk.posedge @@ -226,7 +202,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + if input_axis_tvalid or output_axis_tvalid or not source.empty(): i = 2 source_pause.next = True yield clk.posedge @@ -239,7 +215,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source_queue.empty(): + if input_axis_tvalid or output_axis_tvalid or not source.empty(): i = 2 sink_pause.next = True yield clk.posedge @@ -276,7 +252,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(block) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge @@ -285,14 +261,14 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc+b'\x00' assert cobs_decode(rx_frame.data[:-1]) == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -304,8 +280,8 @@ def bench(): test_frame2 = axis_ep.AXIStreamFrame(block) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -314,21 +290,21 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc+b'\x00' assert cobs_decode(rx_frame.data[:-1]) == block assert not rx_frame.user[-1] - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc+b'\x00' assert cobs_decode(rx_frame.data[:-1]) == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -342,8 +318,8 @@ def bench(): test_frame1.user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -352,25 +328,25 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(rx_frame.data[:-1]) == None assert rx_frame.user[-1] - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc+b'\x00' assert cobs_decode(rx_frame.data[:-1]) == block assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_cobs_encode_zero_frame.v b/tb/test_axis_cobs_encode_zero_frame.v index 14226bc52..bdb98bd55 100644 --- a/tb/test_axis_cobs_encode_zero_frame.v +++ b/tb/test_axis_cobs_encode_zero_frame.v @@ -54,19 +54,23 @@ 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); + $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_cobs_encode_zero_frame.lxt"); diff --git a/tb/test_axis_crosspoint_4x4.py b/tb/test_axis_crosspoint_4x4.py index 5b1e2d3cf..753a2288b 100755 --- a/tb/test_axis_crosspoint_4x4.py +++ b/tb/test_axis_crosspoint_4x4.py @@ -26,116 +26,46 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_crosspoint_4x4' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_crosspoint_4x4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tlast, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tlast, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tlast, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tlast, - - output_0_axis_tdata, - output_0_axis_tvalid, - output_0_axis_tlast, - output_1_axis_tdata, - output_1_axis_tvalid, - output_1_axis_tlast, - output_2_axis_tdata, - output_2_axis_tvalid, - output_2_axis_tlast, - output_3_axis_tdata, - output_3_axis_tvalid, - output_3_axis_tlast, - - output_0_select, - output_1_select, - output_2_select, - output_3_select): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tlast=input_0_axis_tlast, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tlast=input_1_axis_tlast, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tlast=input_2_axis_tlast, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tlast=input_3_axis_tlast, - - output_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tlast=output_0_axis_tlast, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tlast=output_1_axis_tlast, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tlast=output_2_axis_tlast, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tlast=output_3_axis_tlast, - - output_0_select=output_0_select, - output_1_select=output_1_select, - output_2_select=output_2_select, - output_3_select=output_3_select) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[8:]) + input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) - input_1_axis_tdata = Signal(intbv(0)[8:]) + input_0_axis_tuser = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) - input_2_axis_tdata = Signal(intbv(0)[8:]) + input_1_axis_tuser = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) - input_3_axis_tdata = Signal(intbv(0)[8:]) + input_2_axis_tuser = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tuser = Signal(bool(0)) output_0_select = Signal(intbv(0)[2:]) output_1_select = Signal(intbv(0)[2:]) @@ -143,138 +73,186 @@ def bench(): output_3_select = Signal(intbv(0)[2:]) # Outputs - output_0_axis_tdata = Signal(intbv(0)[8:]) + output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_0_axis_tvalid = Signal(bool(0)) output_0_axis_tlast = Signal(bool(0)) - output_1_axis_tdata = Signal(intbv(0)[8:]) + output_0_axis_tuser = Signal(bool(0)) + output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_1_axis_tvalid = Signal(bool(0)) output_1_axis_tlast = Signal(bool(0)) - output_2_axis_tdata = Signal(intbv(0)[8:]) + output_1_axis_tuser = Signal(bool(0)) + output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_2_axis_tvalid = Signal(bool(0)) output_2_axis_tlast = Signal(bool(0)) - output_3_axis_tdata = Signal(intbv(0)[8:]) + output_2_axis_tuser = Signal(bool(0)) + output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_3_axis_tvalid = Signal(bool(0)) output_3_axis_tlast = Signal(bool(0)) + output_3_axis_tuser = Signal(bool(0)) # sources and sinks - source_0_queue = Queue() source_0_pause = Signal(bool(0)) - source_1_queue = Queue() source_1_pause = Signal(bool(0)) - source_2_queue = Queue() source_2_pause = Signal(bool(0)) - source_3_queue = Queue() source_3_pause = Signal(bool(0)) - sink_0_queue = Queue() sink_0_pause = Signal(bool(0)) - sink_1_queue = Queue() sink_1_pause = Signal(bool(0)) - sink_2_queue = Queue() sink_2_pause = Signal(bool(0)) - sink_3_queue = Queue() sink_3_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_0_axis_tdata, - tvalid=input_0_axis_tvalid, - tlast=input_0_axis_tlast, - fifo=source_0_queue, - pause=source_0_pause, - name='source0') - source_1 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_1_axis_tdata, - tvalid=input_1_axis_tvalid, - tlast=input_1_axis_tlast, - fifo=source_1_queue, - pause=source_1_pause, - name='source1') - source_2 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_2_axis_tdata, - tvalid=input_2_axis_tvalid, - tlast=input_2_axis_tlast, - fifo=source_2_queue, - pause=source_2_pause, - name='source2') - source_3 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_3_axis_tdata, - tvalid=input_3_axis_tvalid, - tlast=input_3_axis_tlast, - fifo=source_3_queue, - pause=source_3_pause, - name='source3') + source_0 = axis_ep.AXIStreamSource() - sink_0 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_0_axis_tdata, - tvalid=output_0_axis_tvalid, - tlast=output_0_axis_tlast, - fifo=sink_0_queue, - pause=sink_0_pause, - name='sink0') - sink_1 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_1_axis_tdata, - tvalid=output_1_axis_tvalid, - tlast=output_1_axis_tlast, - fifo=sink_1_queue, - pause=sink_1_pause, - name='sink1') - sink_2 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_2_axis_tdata, - tvalid=output_2_axis_tvalid, - tlast=output_2_axis_tlast, - fifo=sink_2_queue, - pause=sink_2_pause, - name='sink2') - sink_3 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_3_axis_tdata, - tvalid=output_3_axis_tvalid, - tlast=output_3_axis_tlast, - fifo=sink_3_queue, - pause=sink_3_pause, - name='sink3') + source_0_logic = source_0.create_logic( + clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + pause=source_0_pause, + name='source_0' + ) + + source_1 = axis_ep.AXIStreamSource() + + source_1_logic = source_1.create_logic( + clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + pause=source_1_pause, + name='source_1' + ) + + source_2 = axis_ep.AXIStreamSource() + + source_2_logic = source_2.create_logic( + clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + pause=source_2_pause, + name='source_2' + ) + + source_3 = axis_ep.AXIStreamSource() + + source_3_logic = source_3.create_logic( + clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + pause=source_3_pause, + name='source_3' + ) + + sink_0 = axis_ep.AXIStreamSink() + + sink_0_logic = sink_0.create_logic( + clk, + rst, + tdata=output_0_axis_tdata, + tvalid=output_0_axis_tvalid, + tlast=output_0_axis_tlast, + tuser=output_0_axis_tuser, + pause=sink_0_pause, + name='sink_0' + ) + + sink_1 = axis_ep.AXIStreamSink() + + sink_1_logic = sink_1.create_logic( + clk, + rst, + tdata=output_1_axis_tdata, + tvalid=output_1_axis_tvalid, + tlast=output_1_axis_tlast, + tuser=output_1_axis_tuser, + pause=sink_1_pause, + name='sink_1' + ) + + sink_2 = axis_ep.AXIStreamSink() + + sink_2_logic = sink_2.create_logic( + clk, + rst, + tdata=output_2_axis_tdata, + tvalid=output_2_axis_tvalid, + tlast=output_2_axis_tlast, + tuser=output_2_axis_tuser, + pause=sink_2_pause, + name='sink_2' + ) + + sink_3 = axis_ep.AXIStreamSink() + + sink_3_logic = sink_3.create_logic( + clk, + rst, + tdata=output_3_axis_tdata, + tvalid=output_3_axis_tvalid, + tlast=output_3_axis_tlast, + tuser=output_3_axis_tuser, + pause=sink_3_pause, + name='sink_3' + ) # DUT - dut = dut_axis_crosspoint_4x4(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tlast, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tlast, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tlast, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tlast, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_0_axis_tdata, - output_0_axis_tvalid, - output_0_axis_tlast, - output_1_axis_tdata, - output_1_axis_tvalid, - output_1_axis_tlast, - output_2_axis_tdata, - output_2_axis_tvalid, - output_2_axis_tlast, - output_3_axis_tdata, - output_3_axis_tvalid, - output_3_axis_tlast, + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, - output_0_select, - output_1_select, - output_2_select, - output_3_select) + output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tuser=output_0_axis_tuser, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tuser=output_1_axis_tuser, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tuser=output_2_axis_tuser, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tuser=output_3_axis_tuser, + + output_0_select=output_0_select, + output_1_select=output_1_select, + output_2_select=output_2_select, + output_3_select=output_3_select + ) @always(delay(4)) def clkgen(): @@ -306,10 +284,10 @@ def bench(): test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04') test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04') test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04') - source_0_queue.put(test_frame0) - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_0.send(test_frame0) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -317,27 +295,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -356,10 +326,10 @@ def bench(): test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04') test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04') test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04') - source_0_queue.put(test_frame0) - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_0.send(test_frame0) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -367,27 +337,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame3 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame2 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame1 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 @@ -403,7 +365,7 @@ def bench(): output_3_select.next = 0 test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04') - source_0_queue.put(test_frame0) + source_0.send(test_frame0) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -411,27 +373,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame0 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame0 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 @@ -439,7 +393,7 @@ def bench(): raise StopSimulation - return dut, source_0, source_1, source_2, source_3, sink_0, sink_1, sink_2, sink_3, clkgen, check + return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_crosspoint_4x4.v b/tb/test_axis_crosspoint_4x4.v index 7a49e8b9b..8d9e0dc19 100644 --- a/tb/test_axis_crosspoint_4x4.v +++ b/tb/test_axis_crosspoint_4x4.v @@ -24,27 +24,37 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_crosspoint_4x4 + */ module test_axis_crosspoint_4x4; +// Parameters +parameter DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_0_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; -reg [7:0] input_1_axis_tdata = 0; +reg input_0_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; -reg [7:0] input_2_axis_tdata = 0; +reg input_1_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; -reg [7:0] input_3_axis_tdata = 0; +reg input_2_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; +reg input_3_axis_tuser = 0; reg [1:0] output_0_select = 0; reg [1:0] output_1_select = 0; @@ -52,52 +62,68 @@ reg [1:0] output_2_select = 0; reg [1:0] output_3_select = 0; // Outputs -wire [7:0] output_0_axis_tdata; +wire [DATA_WIDTH-1:0] output_0_axis_tdata; wire output_0_axis_tvalid; wire output_0_axis_tlast; -wire [7:0] output_1_axis_tdata; +wire output_0_axis_tuser; +wire [DATA_WIDTH-1:0] output_1_axis_tdata; wire output_1_axis_tvalid; wire output_1_axis_tlast; -wire [7:0] output_2_axis_tdata; +wire output_1_axis_tuser; +wire [DATA_WIDTH-1:0] output_2_axis_tdata; wire output_2_axis_tvalid; wire output_2_axis_tlast; -wire [7:0] output_3_axis_tdata; +wire output_2_axis_tuser; +wire [DATA_WIDTH-1:0] output_3_axis_tdata; wire output_3_axis_tvalid; wire output_3_axis_tlast; +wire output_3_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tlast, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tlast, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tlast, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tlast, - output_0_select, - output_1_select, - output_2_select, - output_3_select); - $to_myhdl(output_0_axis_tdata, - output_0_axis_tvalid, - output_0_axis_tlast, - output_1_axis_tdata, - output_1_axis_tvalid, - output_1_axis_tlast, - output_2_axis_tdata, - output_2_axis_tvalid, - output_2_axis_tlast, - output_3_axis_tdata, - output_3_axis_tvalid, - output_3_axis_tlast); + $from_myhdl( + clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_0_select, + output_1_select, + output_2_select, + output_3_select + ); + $to_myhdl( + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tlast, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tlast, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tlast, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tlast, + output_3_axis_tuser + ); // dump file $dumpfile("test_axis_crosspoint_4x4.lxt"); @@ -105,7 +131,7 @@ initial begin end axis_crosspoint_4x4 #( - .DATA_WIDTH(8) + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), @@ -114,28 +140,36 @@ UUT ( .input_0_axis_tdata(input_0_axis_tdata), .input_0_axis_tvalid(input_0_axis_tvalid), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), .input_1_axis_tvalid(input_1_axis_tvalid), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), .input_2_axis_tvalid(input_2_axis_tvalid), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), .input_3_axis_tvalid(input_3_axis_tvalid), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tuser(input_3_axis_tuser), // AXI outputs .output_0_axis_tdata(output_0_axis_tdata), .output_0_axis_tvalid(output_0_axis_tvalid), .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tuser(output_0_axis_tuser), .output_1_axis_tdata(output_1_axis_tdata), .output_1_axis_tvalid(output_1_axis_tvalid), .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tuser(output_1_axis_tuser), .output_2_axis_tdata(output_2_axis_tdata), .output_2_axis_tvalid(output_2_axis_tvalid), .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tuser(output_2_axis_tuser), .output_3_axis_tdata(output_3_axis_tdata), .output_3_axis_tvalid(output_3_axis_tvalid), .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tuser(output_3_axis_tuser), // Control .output_0_select(output_0_select), .output_1_select(output_1_select), diff --git a/tb/test_axis_crosspoint_64_4x4.py b/tb/test_axis_crosspoint_64_4x4.py index cb2f7b44e..315c6a556 100755 --- a/tb/test_axis_crosspoint_64_4x4.py +++ b/tb/test_axis_crosspoint_64_4x4.py @@ -26,136 +26,51 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_crosspoint_64_4x4' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_crosspoint_64_4x4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast, - - output_0_select, - output_1_select, - output_2_select, - output_3_select): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tlast=input_0_axis_tlast, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tlast=input_1_axis_tlast, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tlast=input_2_axis_tlast, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tlast=input_3_axis_tlast, - - output_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tkeep=output_0_axis_tkeep, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tlast=output_0_axis_tlast, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tkeep=output_1_axis_tkeep, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tlast=output_1_axis_tlast, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tkeep=output_2_axis_tkeep, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tlast=output_2_axis_tlast, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tkeep=output_3_axis_tkeep, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tlast=output_3_axis_tlast, - - output_0_select=output_0_select, - output_1_select=output_1_select, - output_2_select=output_2_select, - output_3_select=output_3_select) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[64:]) - input_0_axis_tkeep = Signal(intbv(0)[8:]) + input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) - input_1_axis_tdata = Signal(intbv(0)[64:]) - input_1_axis_tkeep = Signal(intbv(0)[8:]) + input_0_axis_tuser = Signal(bool(0)) + input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) - input_2_axis_tdata = Signal(intbv(0)[64:]) - input_2_axis_tkeep = Signal(intbv(0)[8:]) + input_1_axis_tuser = Signal(bool(0)) + input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) - input_3_axis_tdata = Signal(intbv(0)[64:]) - input_3_axis_tkeep = Signal(intbv(0)[8:]) + input_2_axis_tuser = Signal(bool(0)) + input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tuser = Signal(bool(0)) output_0_select = Signal(intbv(0)[2:]) output_1_select = Signal(intbv(0)[2:]) @@ -163,158 +78,206 @@ def bench(): output_3_select = Signal(intbv(0)[2:]) # Outputs - output_0_axis_tdata = Signal(intbv(0)[64:]) - output_0_axis_tkeep = Signal(intbv(0)[8:]) + output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_0_axis_tvalid = Signal(bool(0)) output_0_axis_tlast = Signal(bool(0)) - output_1_axis_tdata = Signal(intbv(0)[64:]) - output_1_axis_tkeep = Signal(intbv(0)[8:]) + output_0_axis_tuser = Signal(bool(0)) + output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_1_axis_tvalid = Signal(bool(0)) output_1_axis_tlast = Signal(bool(0)) - output_2_axis_tdata = Signal(intbv(0)[64:]) - output_2_axis_tkeep = Signal(intbv(0)[8:]) + output_1_axis_tuser = Signal(bool(0)) + output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_2_axis_tvalid = Signal(bool(0)) output_2_axis_tlast = Signal(bool(0)) - output_3_axis_tdata = Signal(intbv(0)[64:]) - output_3_axis_tkeep = Signal(intbv(0)[8:]) + output_2_axis_tuser = Signal(bool(0)) + output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_3_axis_tvalid = Signal(bool(0)) output_3_axis_tlast = Signal(bool(0)) + output_3_axis_tuser = Signal(bool(0)) # sources and sinks - source_0_queue = Queue() source_0_pause = Signal(bool(0)) - source_1_queue = Queue() source_1_pause = Signal(bool(0)) - source_2_queue = Queue() source_2_pause = Signal(bool(0)) - source_3_queue = Queue() source_3_pause = Signal(bool(0)) - sink_0_queue = Queue() sink_0_pause = Signal(bool(0)) - sink_1_queue = Queue() sink_1_pause = Signal(bool(0)) - sink_2_queue = Queue() sink_2_pause = Signal(bool(0)) - sink_3_queue = Queue() sink_3_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tlast=input_0_axis_tlast, - fifo=source_0_queue, - pause=source_0_pause, - name='source0') - source_1 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tlast=input_1_axis_tlast, - fifo=source_1_queue, - pause=source_1_pause, - name='source1') - source_2 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tlast=input_2_axis_tlast, - fifo=source_2_queue, - pause=source_2_pause, - name='source2') - source_3 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tlast=input_3_axis_tlast, - fifo=source_3_queue, - pause=source_3_pause, - name='source3') + source_0 = axis_ep.AXIStreamSource() - sink_0 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_0_axis_tdata, - tkeep=output_0_axis_tkeep, - tvalid=output_0_axis_tvalid, - tlast=output_0_axis_tlast, - fifo=sink_0_queue, - pause=sink_0_pause, - name='sink0') - sink_1 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_1_axis_tdata, - tkeep=output_1_axis_tkeep, - tvalid=output_1_axis_tvalid, - tlast=output_1_axis_tlast, - fifo=sink_1_queue, - pause=sink_1_pause, - name='sink1') - sink_2 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_2_axis_tdata, - tkeep=output_2_axis_tkeep, - tvalid=output_2_axis_tvalid, - tlast=output_2_axis_tlast, - fifo=sink_2_queue, - pause=sink_2_pause, - name='sink2') - sink_3 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_3_axis_tdata, - tkeep=output_3_axis_tkeep, - tvalid=output_3_axis_tvalid, - tlast=output_3_axis_tlast, - fifo=sink_3_queue, - pause=sink_3_pause, - name='sink3') + source_0_logic = source_0.create_logic( + clk, + rst, + tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, + tvalid=input_0_axis_tvalid, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + pause=source_0_pause, + name='source_0' + ) + + source_1 = axis_ep.AXIStreamSource() + + source_1_logic = source_1.create_logic( + clk, + rst, + tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, + tvalid=input_1_axis_tvalid, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + pause=source_1_pause, + name='source_1' + ) + + source_2 = axis_ep.AXIStreamSource() + + source_2_logic = source_2.create_logic( + clk, + rst, + tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, + tvalid=input_2_axis_tvalid, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + pause=source_2_pause, + name='source_2' + ) + + source_3 = axis_ep.AXIStreamSource() + + source_3_logic = source_3.create_logic( + clk, + rst, + tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, + tvalid=input_3_axis_tvalid, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + pause=source_3_pause, + name='source_3' + ) + + sink_0 = axis_ep.AXIStreamSink() + + sink_0_logic = sink_0.create_logic( + clk, + rst, + tdata=output_0_axis_tdata, + tkeep=output_0_axis_tkeep, + tvalid=output_0_axis_tvalid, + tlast=output_0_axis_tlast, + tuser=output_0_axis_tuser, + pause=sink_0_pause, + name='sink_0' + ) + + sink_1 = axis_ep.AXIStreamSink() + + sink_1_logic = sink_1.create_logic( + clk, + rst, + tdata=output_1_axis_tdata, + tkeep=output_1_axis_tkeep, + tvalid=output_1_axis_tvalid, + tlast=output_1_axis_tlast, + tuser=output_1_axis_tuser, + pause=sink_1_pause, + name='sink_1' + ) + + sink_2 = axis_ep.AXIStreamSink() + + sink_2_logic = sink_2.create_logic( + clk, + rst, + tdata=output_2_axis_tdata, + tkeep=output_2_axis_tkeep, + tvalid=output_2_axis_tvalid, + tlast=output_2_axis_tlast, + tuser=output_2_axis_tuser, + pause=sink_2_pause, + name='sink_2' + ) + + sink_3 = axis_ep.AXIStreamSink() + + sink_3_logic = sink_3.create_logic( + clk, + rst, + tdata=output_3_axis_tdata, + tkeep=output_3_axis_tkeep, + tvalid=output_3_axis_tvalid, + tlast=output_3_axis_tlast, + tuser=output_3_axis_tuser, + pause=sink_3_pause, + name='sink_3' + ) # DUT - dut = dut_axis_crosspoint_64_4x4(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast, + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, - output_0_select, - output_1_select, - output_2_select, - output_3_select) + output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tkeep=output_0_axis_tkeep, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tuser=output_0_axis_tuser, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tkeep=output_1_axis_tkeep, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tuser=output_1_axis_tuser, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tkeep=output_2_axis_tkeep, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tuser=output_2_axis_tuser, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tkeep=output_3_axis_tkeep, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tuser=output_3_axis_tuser, + + output_0_select=output_0_select, + output_1_select=output_1_select, + output_2_select=output_2_select, + output_3_select=output_3_select + ) @always(delay(4)) def clkgen(): @@ -346,10 +309,10 @@ def bench(): test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04') test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04') test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04') - source_0_queue.put(test_frame0) - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_0.send(test_frame0) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -357,27 +320,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -396,10 +351,10 @@ def bench(): test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04') test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04') test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04') - source_0_queue.put(test_frame0) - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_0.send(test_frame0) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -407,27 +362,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame3 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame2 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame1 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 @@ -443,7 +390,7 @@ def bench(): output_3_select.next = 0 test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04') - source_0_queue.put(test_frame0) + source_0.send(test_frame0) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -451,27 +398,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame0 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame0 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 @@ -479,7 +418,7 @@ def bench(): raise StopSimulation - return dut, source_0, source_1, source_2, source_3, sink_0, sink_1, sink_2, sink_3, clkgen, check + return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_crosspoint_64_4x4.v b/tb/test_axis_crosspoint_64_4x4.v index 4a9b9108d..062aeb106 100644 --- a/tb/test_axis_crosspoint_64_4x4.v +++ b/tb/test_axis_crosspoint_64_4x4.v @@ -24,31 +24,42 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_crosspoint_64_4x4 + */ module test_axis_crosspoint_64_4x4; +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] input_0_axis_tdata = 0; -reg [7:0] input_0_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; -reg [63:0] input_1_axis_tdata = 0; -reg [7:0] input_1_axis_tkeep = 0; +reg input_0_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; -reg [63:0] input_2_axis_tdata = 0; -reg [7:0] input_2_axis_tkeep = 0; +reg input_1_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; -reg [63:0] input_3_axis_tdata = 0; -reg [7:0] input_3_axis_tkeep = 0; +reg input_2_axis_tuser = 0; +reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; +reg input_3_axis_tuser = 0; reg [1:0] output_0_select = 0; reg [1:0] output_1_select = 0; @@ -56,64 +67,80 @@ reg [1:0] output_2_select = 0; reg [1:0] output_3_select = 0; // Outputs -wire [63:0] output_0_axis_tdata; -wire [7:0] output_0_axis_tkeep; +wire [DATA_WIDTH-1:0] output_0_axis_tdata; +wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; wire output_0_axis_tvalid; wire output_0_axis_tlast; -wire [63:0] output_1_axis_tdata; -wire [7:0] output_1_axis_tkeep; +wire output_0_axis_tuser; +wire [DATA_WIDTH-1:0] output_1_axis_tdata; +wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; wire output_1_axis_tvalid; wire output_1_axis_tlast; -wire [63:0] output_2_axis_tdata; -wire [7:0] output_2_axis_tkeep; +wire output_1_axis_tuser; +wire [DATA_WIDTH-1:0] output_2_axis_tdata; +wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; wire output_2_axis_tvalid; wire output_2_axis_tlast; -wire [63:0] output_3_axis_tdata; -wire [7:0] output_3_axis_tkeep; +wire output_2_axis_tuser; +wire [DATA_WIDTH-1:0] output_3_axis_tdata; +wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; wire output_3_axis_tvalid; wire output_3_axis_tlast; +wire output_3_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - output_0_select, - output_1_select, - output_2_select, - output_3_select); - $to_myhdl(output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast); + $from_myhdl( + clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_0_select, + output_1_select, + output_2_select, + output_3_select + ); + $to_myhdl( + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tlast, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tlast, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tlast, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tlast, + output_3_axis_tuser + ); // dump file $dumpfile("test_axis_crosspoint_64_4x4.lxt"); @@ -121,7 +148,8 @@ initial begin end axis_crosspoint_64_4x4 #( - .DATA_WIDTH(64) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) ) UUT ( .clk(clk), @@ -131,35 +159,43 @@ UUT ( .input_0_axis_tkeep(input_0_axis_tkeep), .input_0_axis_tvalid(input_0_axis_tvalid), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), .input_1_axis_tkeep(input_1_axis_tkeep), .input_1_axis_tvalid(input_1_axis_tvalid), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), .input_2_axis_tkeep(input_2_axis_tkeep), .input_2_axis_tvalid(input_2_axis_tvalid), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), .input_3_axis_tkeep(input_3_axis_tkeep), .input_3_axis_tvalid(input_3_axis_tvalid), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tuser(input_3_axis_tuser), // AXI outputs .output_0_axis_tdata(output_0_axis_tdata), .output_0_axis_tkeep(output_0_axis_tkeep), .output_0_axis_tvalid(output_0_axis_tvalid), .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tuser(output_0_axis_tuser), .output_1_axis_tdata(output_1_axis_tdata), .output_1_axis_tkeep(output_1_axis_tkeep), .output_1_axis_tvalid(output_1_axis_tvalid), .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tuser(output_1_axis_tuser), .output_2_axis_tdata(output_2_axis_tdata), .output_2_axis_tkeep(output_2_axis_tkeep), .output_2_axis_tvalid(output_2_axis_tvalid), .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tuser(output_2_axis_tuser), .output_3_axis_tdata(output_3_axis_tdata), .output_3_axis_tkeep(output_3_axis_tkeep), .output_3_axis_tvalid(output_3_axis_tvalid), .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tuser(output_3_axis_tuser), // Control .output_0_select(output_0_select), .output_1_select(output_1_select), diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py index e652ab9d8..3e7f59563 100755 --- a/tb/test_axis_demux_4.py +++ b/tb/test_axis_demux_4.py @@ -26,107 +26,35 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_demux_4' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_demux_4(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_0_axis_tdata, - output_0_axis_tvalid, - output_0_axis_tready, - output_0_axis_tlast, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tvalid, - output_1_axis_tready, - output_1_axis_tlast, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tvalid, - output_2_axis_tready, - output_2_axis_tlast, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tvalid, - output_3_axis_tready, - output_3_axis_tlast, - output_3_axis_tuser, - - enable, - select): - - 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_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tready=output_0_axis_tready, - output_0_axis_tlast=output_0_axis_tlast, - output_0_axis_tuser=output_0_axis_tuser, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tready=output_1_axis_tready, - output_1_axis_tlast=output_1_axis_tlast, - output_1_axis_tuser=output_1_axis_tuser, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tready=output_2_axis_tready, - output_2_axis_tlast=output_2_axis_tlast, - output_2_axis_tuser=output_2_axis_tuser, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tready=output_3_axis_tready, - output_3_axis_tlast=output_3_axis_tlast, - output_3_axis_tuser=output_3_axis_tuser, - - enable=enable, - select=select) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) - + output_0_axis_tready = Signal(bool(0)) output_1_axis_tready = Signal(bool(0)) output_2_axis_tready = Signal(bool(0)) @@ -138,124 +66,140 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_0_axis_tdata = Signal(intbv(0)[8:]) + output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_0_axis_tvalid = Signal(bool(0)) output_0_axis_tlast = Signal(bool(0)) output_0_axis_tuser = Signal(bool(0)) - output_1_axis_tdata = Signal(intbv(0)[8:]) + output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_1_axis_tvalid = Signal(bool(0)) output_1_axis_tlast = Signal(bool(0)) output_1_axis_tuser = Signal(bool(0)) - output_2_axis_tdata = Signal(intbv(0)[8:]) + output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_2_axis_tvalid = Signal(bool(0)) output_2_axis_tlast = Signal(bool(0)) output_2_axis_tuser = Signal(bool(0)) - output_3_axis_tdata = Signal(intbv(0)[8:]) + output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_3_axis_tvalid = Signal(bool(0)) output_3_axis_tlast = Signal(bool(0)) output_3_axis_tuser = Signal(bool(0)) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - sink_0_queue = Queue() sink_0_pause = Signal(bool(0)) - sink_1_queue = Queue() sink_1_pause = Signal(bool(0)) - sink_2_queue = Queue() sink_2_pause = Signal(bool(0)) - sink_3_queue = Queue() sink_3_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') + source = axis_ep.AXIStreamSource() - sink_0 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_0_axis_tdata, - tvalid=output_0_axis_tvalid, - tready=output_0_axis_tready, - tlast=output_0_axis_tlast, - tuser=output_0_axis_tuser, - fifo=sink_0_queue, - pause=sink_0_pause, - name='sink0') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) - sink_1 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_1_axis_tdata, - tvalid=output_1_axis_tvalid, - tready=output_1_axis_tready, - tlast=output_1_axis_tlast, - tuser=output_1_axis_tuser, - fifo=sink_1_queue, - pause=sink_1_pause, - name='sink1') + sink_0 = axis_ep.AXIStreamSink() - sink_2 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_2_axis_tdata, - tvalid=output_2_axis_tvalid, - tready=output_2_axis_tready, - tlast=output_2_axis_tlast, - tuser=output_2_axis_tuser, - fifo=sink_2_queue, - pause=sink_2_pause, - name='sink2') + sink_0_logic = sink_0.create_logic( + clk, + rst, + tdata=output_0_axis_tdata, + tvalid=output_0_axis_tvalid, + tready=output_0_axis_tready, + tlast=output_0_axis_tlast, + tuser=output_0_axis_tuser, + pause=sink_0_pause, + name='sink_0' + ) - sink_3 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_3_axis_tdata, - tvalid=output_3_axis_tvalid, - tready=output_3_axis_tready, - tlast=output_3_axis_tlast, - tuser=output_3_axis_tuser, - fifo=sink_3_queue, - pause=sink_3_pause, - name='sink3') + sink_1 = axis_ep.AXIStreamSink() + + sink_1_logic = sink_1.create_logic( + clk, + rst, + tdata=output_1_axis_tdata, + tvalid=output_1_axis_tvalid, + tready=output_1_axis_tready, + tlast=output_1_axis_tlast, + tuser=output_1_axis_tuser, + pause=sink_1_pause, + name='sink_1' + ) + + sink_2 = axis_ep.AXIStreamSink() + + sink_2_logic = sink_2.create_logic( + clk, + rst, + tdata=output_2_axis_tdata, + tvalid=output_2_axis_tvalid, + tready=output_2_axis_tready, + tlast=output_2_axis_tlast, + tuser=output_2_axis_tuser, + pause=sink_2_pause, + name='sink_2' + ) + + sink_3 = axis_ep.AXIStreamSink() + + sink_3_logic = sink_3.create_logic( + clk, + rst, + tdata=output_3_axis_tdata, + tvalid=output_3_axis_tvalid, + tready=output_3_axis_tready, + tlast=output_3_axis_tlast, + tuser=output_3_axis_tuser, + pause=sink_3_pause, + name='sink_3' + ) # DUT - dut = dut_axis_demux_4(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_0_axis_tdata, - output_0_axis_tvalid, - output_0_axis_tready, - output_0_axis_tlast, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tvalid, - output_1_axis_tready, - output_1_axis_tlast, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tvalid, - output_2_axis_tready, - output_2_axis_tlast, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tvalid, - output_3_axis_tready, - output_3_axis_tlast, - output_3_axis_tuser, + 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, - enable, - select) + output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tready=output_0_axis_tready, + output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tuser=output_0_axis_tuser, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tready=output_1_axis_tready, + output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tuser=output_1_axis_tuser, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tready=output_2_axis_tready, + output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tuser=output_2_axis_tuser, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tready=output_3_axis_tready, + output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tuser=output_3_axis_tuser, + + enable=enable, + select=select + ) @always(delay(4)) def clkgen(): @@ -285,7 +229,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while input_axis_tvalid: @@ -293,9 +237,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_0_queue.empty(): - rx_frame = sink_0_queue.get() + rx_frame = sink_0.recv() assert rx_frame == test_frame @@ -311,7 +253,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while input_axis_tvalid: @@ -319,9 +261,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_1_queue.empty(): - rx_frame = sink_1_queue.get() + rx_frame = sink_1.recv() assert rx_frame == test_frame @@ -341,8 +281,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid: @@ -350,15 +290,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_0_queue.empty(): - rx_frame = sink_0_queue.get() + rx_frame = sink_0.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_0_queue.empty(): - rx_frame = sink_0_queue.get() + rx_frame = sink_0.recv() assert rx_frame == test_frame2 @@ -378,8 +314,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid: @@ -388,15 +324,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_2_queue.empty(): - rx_frame = sink_1_queue.get() + rx_frame = sink_1.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_2_queue.empty(): - rx_frame = sink_2_queue.get() + rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -416,8 +348,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid: @@ -431,15 +363,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_1_queue.empty(): - rx_frame = sink_1_queue.get() + rx_frame = sink_1.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_2_queue.empty(): - rx_frame = sink_2_queue.get() + rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -459,8 +387,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid: @@ -480,15 +408,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_1_queue.empty(): - rx_frame = sink_1_queue.get() + rx_frame = sink_1.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_2_queue.empty(): - rx_frame = sink_2_queue.get() + rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -496,7 +420,7 @@ def bench(): raise StopSimulation - return dut, source, sink_0, sink_1, sink_2, sink_3, clkgen, check + return dut, source_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_demux_4.v b/tb/test_axis_demux_4.v index 1711d3ec1..65685c11b 100644 --- a/tb/test_axis_demux_4.v +++ b/tb/test_axis_demux_4.v @@ -24,16 +24,22 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_demux_4 + */ module test_axis_demux_4; +// Parameters +parameter DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -49,55 +55,59 @@ reg [1:0] select = 0; // Outputs wire input_axis_tready; -wire [7:0] output_0_axis_tdata; +wire [DATA_WIDTH-1:0] output_0_axis_tdata; wire output_0_axis_tvalid; wire output_0_axis_tlast; wire output_0_axis_tuser; -wire [7:0] output_1_axis_tdata; +wire [DATA_WIDTH-1:0] output_1_axis_tdata; wire output_1_axis_tvalid; wire output_1_axis_tlast; wire output_1_axis_tuser; -wire [7:0] output_2_axis_tdata; +wire [DATA_WIDTH-1:0] output_2_axis_tdata; wire output_2_axis_tvalid; wire output_2_axis_tlast; wire output_2_axis_tuser; -wire [7:0] output_3_axis_tdata; +wire [DATA_WIDTH-1:0] output_3_axis_tdata; wire output_3_axis_tvalid; wire output_3_axis_tlast; wire output_3_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_0_axis_tready, - output_1_axis_tready, - output_2_axis_tready, - output_3_axis_tready, - enable, - select); - $to_myhdl(input_axis_tready, - output_0_axis_tdata, - output_0_axis_tvalid, - output_0_axis_tlast, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tvalid, - output_1_axis_tlast, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tvalid, - output_2_axis_tlast, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tvalid, - output_3_axis_tlast, - output_3_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_0_axis_tready, + output_1_axis_tready, + output_2_axis_tready, + output_3_axis_tready, + enable, + select + ); + $to_myhdl( + input_axis_tready, + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tlast, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tlast, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tlast, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tlast, + output_3_axis_tuser + ); // dump file $dumpfile("test_axis_demux_4.lxt"); @@ -105,7 +115,7 @@ initial begin end axis_demux_4 #( - .DATA_WIDTH(8) + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_demux_64_4.py b/tb/test_axis_demux_64_4.py index be1bb472f..716e7a303 100755 --- a/tb/test_axis_demux_64_4.py +++ b/tb/test_axis_demux_64_4.py @@ -26,118 +26,37 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_demux_64_4' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_demux_64_4(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tready, - output_0_axis_tlast, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tready, - output_1_axis_tlast, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tready, - output_2_axis_tlast, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tready, - output_3_axis_tlast, - output_3_axis_tuser, - - enable, - select): - - 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_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tkeep=output_0_axis_tkeep, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tready=output_0_axis_tready, - output_0_axis_tlast=output_0_axis_tlast, - output_0_axis_tuser=output_0_axis_tuser, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tkeep=output_1_axis_tkeep, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tready=output_1_axis_tready, - output_1_axis_tlast=output_1_axis_tlast, - output_1_axis_tuser=output_1_axis_tuser, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tkeep=output_2_axis_tkeep, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tready=output_2_axis_tready, - output_2_axis_tlast=output_2_axis_tlast, - output_2_axis_tuser=output_2_axis_tuser, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tkeep=output_3_axis_tkeep, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tready=output_3_axis_tready, - output_3_axis_tlast=output_3_axis_tlast, - output_3_axis_tuser=output_3_axis_tuser, - - enable=enable, - select=select) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) - + output_0_axis_tready = Signal(bool(0)) output_1_axis_tready = Signal(bool(0)) output_2_axis_tready = Signal(bool(0)) @@ -149,138 +68,154 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_0_axis_tdata = Signal(intbv(0)[64:]) - output_0_axis_tkeep = Signal(intbv(0)[8:]) + output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_0_axis_tvalid = Signal(bool(0)) output_0_axis_tlast = Signal(bool(0)) output_0_axis_tuser = Signal(bool(0)) - output_1_axis_tdata = Signal(intbv(0)[64:]) - output_1_axis_tkeep = Signal(intbv(0)[8:]) + output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_1_axis_tvalid = Signal(bool(0)) output_1_axis_tlast = Signal(bool(0)) output_1_axis_tuser = Signal(bool(0)) - output_2_axis_tdata = Signal(intbv(0)[64:]) - output_2_axis_tkeep = Signal(intbv(0)[8:]) + output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_2_axis_tvalid = Signal(bool(0)) output_2_axis_tlast = Signal(bool(0)) output_2_axis_tuser = Signal(bool(0)) - output_3_axis_tdata = Signal(intbv(0)[64:]) - output_3_axis_tkeep = Signal(intbv(0)[8:]) + output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_3_axis_tvalid = Signal(bool(0)) output_3_axis_tlast = Signal(bool(0)) output_3_axis_tuser = Signal(bool(0)) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - sink_0_queue = Queue() sink_0_pause = Signal(bool(0)) - sink_1_queue = Queue() sink_1_pause = Signal(bool(0)) - sink_2_queue = Queue() sink_2_pause = Signal(bool(0)) - sink_3_queue = Queue() sink_3_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') + source = axis_ep.AXIStreamSource() - sink_0 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_0_axis_tdata, - tkeep=output_0_axis_tkeep, - tvalid=output_0_axis_tvalid, - tready=output_0_axis_tready, - tlast=output_0_axis_tlast, - tuser=output_0_axis_tuser, - fifo=sink_0_queue, - pause=sink_0_pause, - name='sink0') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) - sink_1 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_1_axis_tdata, - tkeep=output_1_axis_tkeep, - tvalid=output_1_axis_tvalid, - tready=output_1_axis_tready, - tlast=output_1_axis_tlast, - tuser=output_1_axis_tuser, - fifo=sink_1_queue, - pause=sink_1_pause, - name='sink1') + sink_0 = axis_ep.AXIStreamSink() - sink_2 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_2_axis_tdata, - tkeep=output_2_axis_tkeep, - tvalid=output_2_axis_tvalid, - tready=output_2_axis_tready, - tlast=output_2_axis_tlast, - tuser=output_2_axis_tuser, - fifo=sink_2_queue, - pause=sink_2_pause, - name='sink2') + sink_0_logic = sink_0.create_logic( + clk, + rst, + tdata=output_0_axis_tdata, + tkeep=output_0_axis_tkeep, + tvalid=output_0_axis_tvalid, + tready=output_0_axis_tready, + tlast=output_0_axis_tlast, + tuser=output_0_axis_tuser, + pause=sink_0_pause, + name='sink_0' + ) - sink_3 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_3_axis_tdata, - tkeep=output_3_axis_tkeep, - tvalid=output_3_axis_tvalid, - tready=output_3_axis_tready, - tlast=output_3_axis_tlast, - tuser=output_3_axis_tuser, - fifo=sink_3_queue, - pause=sink_3_pause, - name='sink3') + sink_1 = axis_ep.AXIStreamSink() + + sink_1_logic = sink_1.create_logic( + clk, + rst, + tdata=output_1_axis_tdata, + tkeep=output_1_axis_tkeep, + tvalid=output_1_axis_tvalid, + tready=output_1_axis_tready, + tlast=output_1_axis_tlast, + tuser=output_1_axis_tuser, + pause=sink_1_pause, + name='sink_1' + ) + + sink_2 = axis_ep.AXIStreamSink() + + sink_2_logic = sink_2.create_logic( + clk, + rst, + tdata=output_2_axis_tdata, + tkeep=output_2_axis_tkeep, + tvalid=output_2_axis_tvalid, + tready=output_2_axis_tready, + tlast=output_2_axis_tlast, + tuser=output_2_axis_tuser, + pause=sink_2_pause, + name='sink_2' + ) + + sink_3 = axis_ep.AXIStreamSink() + + sink_3_logic = sink_3.create_logic( + clk, + rst, + tdata=output_3_axis_tdata, + tkeep=output_3_axis_tkeep, + tvalid=output_3_axis_tvalid, + tready=output_3_axis_tready, + tlast=output_3_axis_tlast, + tuser=output_3_axis_tuser, + pause=sink_3_pause, + name='sink_3' + ) # DUT - dut = dut_axis_demux_64_4(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tready, - output_0_axis_tlast, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tready, - output_1_axis_tlast, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tready, - output_2_axis_tlast, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tready, - output_3_axis_tlast, - output_3_axis_tuser, + 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, - enable, - select) + output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tkeep=output_0_axis_tkeep, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tready=output_0_axis_tready, + output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tuser=output_0_axis_tuser, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tkeep=output_1_axis_tkeep, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tready=output_1_axis_tready, + output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tuser=output_1_axis_tuser, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tkeep=output_2_axis_tkeep, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tready=output_2_axis_tready, + output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tuser=output_2_axis_tuser, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tkeep=output_3_axis_tkeep, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tready=output_3_axis_tready, + output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tuser=output_3_axis_tuser, + + enable=enable, + select=select + ) @always(delay(4)) def clkgen(): @@ -310,7 +245,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while input_axis_tvalid: @@ -318,9 +253,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_0_queue.empty(): - rx_frame = sink_0_queue.get() + rx_frame = sink_0.recv() assert rx_frame == test_frame @@ -336,7 +269,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while input_axis_tvalid: @@ -344,9 +277,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_1_queue.empty(): - rx_frame = sink_1_queue.get() + rx_frame = sink_1.recv() assert rx_frame == test_frame @@ -366,8 +297,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid: @@ -375,15 +306,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_0_queue.empty(): - rx_frame = sink_0_queue.get() + rx_frame = sink_0.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_0_queue.empty(): - rx_frame = sink_0_queue.get() + rx_frame = sink_0.recv() assert rx_frame == test_frame2 @@ -403,8 +330,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid: @@ -413,15 +340,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_2_queue.empty(): - rx_frame = sink_1_queue.get() + rx_frame = sink_1.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_2_queue.empty(): - rx_frame = sink_2_queue.get() + rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -441,8 +364,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid: @@ -456,15 +379,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_1_queue.empty(): - rx_frame = sink_1_queue.get() + rx_frame = sink_1.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_2_queue.empty(): - rx_frame = sink_2_queue.get() + rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -484,8 +403,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid: @@ -505,15 +424,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_1_queue.empty(): - rx_frame = sink_1_queue.get() + rx_frame = sink_1.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_2_queue.empty(): - rx_frame = sink_2_queue.get() + rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -521,7 +436,7 @@ def bench(): raise StopSimulation - return dut, source, sink_0, sink_1, sink_2, sink_3, clkgen, check + return dut, source_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_demux_64_4.v b/tb/test_axis_demux_64_4.v index b157d0561..8edd948c9 100644 --- a/tb/test_axis_demux_64_4.v +++ b/tb/test_axis_demux_64_4.v @@ -24,17 +24,24 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_demux_64_4 + */ module test_axis_demux_64_4; +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // 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 [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -50,64 +57,68 @@ reg [1:0] select = 0; // Outputs wire input_axis_tready; -wire [63:0] output_0_axis_tdata; -wire [7:0] output_0_axis_tkeep; +wire [DATA_WIDTH-1:0] output_0_axis_tdata; +wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; wire output_0_axis_tvalid; wire output_0_axis_tlast; wire output_0_axis_tuser; -wire [63:0] output_1_axis_tdata; -wire [7:0] output_1_axis_tkeep; +wire [DATA_WIDTH-1:0] output_1_axis_tdata; +wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; wire output_1_axis_tvalid; wire output_1_axis_tlast; wire output_1_axis_tuser; -wire [63:0] output_2_axis_tdata; -wire [7:0] output_2_axis_tkeep; +wire [DATA_WIDTH-1:0] output_2_axis_tdata; +wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; wire output_2_axis_tvalid; wire output_2_axis_tlast; wire output_2_axis_tuser; -wire [63:0] output_3_axis_tdata; -wire [7:0] output_3_axis_tkeep; +wire [DATA_WIDTH-1:0] output_3_axis_tdata; +wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; wire output_3_axis_tvalid; wire output_3_axis_tlast; wire output_3_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_0_axis_tready, - output_1_axis_tready, - output_2_axis_tready, - output_3_axis_tready, - enable, - select); - $to_myhdl(input_axis_tready, - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast, - output_3_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_0_axis_tready, + output_1_axis_tready, + output_2_axis_tready, + output_3_axis_tready, + enable, + select + ); + $to_myhdl( + input_axis_tready, + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tlast, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tlast, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tlast, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tlast, + output_3_axis_tuser + ); // dump file $dumpfile("test_axis_demux_64_4.lxt"); @@ -115,7 +126,8 @@ initial begin end axis_demux_64_4 #( - .DATA_WIDTH(64) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index dd58b3809..54ba882d1 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -26,67 +26,32 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_fifo' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_fifo(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + ADDR_WIDTH = 2 + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -94,55 +59,65 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_fifo(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + 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 + ) @always(delay(4)) def clkgen(): @@ -169,16 +144,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -192,16 +165,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -213,7 +184,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -234,9 +205,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -254,8 +223,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -264,15 +233,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -290,8 +255,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -305,15 +270,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -331,8 +292,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -346,15 +307,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -369,16 +326,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -392,7 +347,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -403,9 +358,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -418,7 +371,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -436,13 +389,13 @@ def bench(): yield clk.posedge yield clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_fifo.v b/tb/test_axis_fifo.v index 076ca27db..55dee8e62 100644 --- a/tb/test_axis_fifo.v +++ b/tb/test_axis_fifo.v @@ -24,16 +24,23 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_fifo + */ module test_axis_fifo; +// Parameters +parameter ADDR_WIDTH = 2; +parameter DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -41,26 +48,30 @@ reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [7:0] output_axis_tdata; +wire [DATA_WIDTH-1: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); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready + ); + $to_myhdl( + input_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_fifo.lxt"); @@ -68,8 +79,8 @@ initial begin end axis_fifo #( - .ADDR_WIDTH(2), - .DATA_WIDTH(8) + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index 431942731..97bcb22f9 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -26,72 +26,34 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_fifo_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_fifo_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + ADDR_WIDTH = 2 + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -99,60 +61,70 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_fifo_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + 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 + ) @always(delay(4)) def clkgen(): @@ -179,16 +151,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -202,16 +172,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -223,7 +191,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -244,9 +212,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -264,8 +230,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -274,15 +240,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -300,8 +262,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -315,15 +277,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -341,8 +299,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -356,15 +314,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -379,16 +333,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -402,7 +354,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -413,9 +365,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -428,7 +378,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -446,13 +396,13 @@ def bench(): yield clk.posedge yield clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_fifo_64.v b/tb/test_axis_fifo_64.v index 4335d7e5c..01d8d162b 100644 --- a/tb/test_axis_fifo_64.v +++ b/tb/test_axis_fifo_64.v @@ -24,17 +24,25 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_fifo_64 + */ module test_axis_fifo_64; +// Parameters +parameter ADDR_WIDTH = 2; +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // 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 [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -42,29 +50,33 @@ reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready + ); + $to_myhdl( + input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_fifo_64.lxt"); @@ -72,8 +84,8 @@ initial begin end axis_fifo_64 #( - .ADDR_WIDTH(2), - .DATA_WIDTH(64) + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index 8f4b8455f..c9d7dd958 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -26,73 +26,33 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_frame_fifo' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_frame_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, - - overflow, - bad_frame, - good_frame): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - - overflow=overflow, - bad_frame=bad_frame, - good_frame=good_frame) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + ADDR_WIDTH = 9 + DATA_WIDTH = 8 + DROP_WHEN_FULL = 0 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -100,7 +60,7 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) overflow = Signal(bool(0)) @@ -108,51 +68,61 @@ def bench(): good_frame = 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') + source = axis_ep.AXIStreamSource() - sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - fifo=sink_queue, - pause=sink_pause, - name='sink') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_frame_fifo(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, + 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, - overflow, - bad_frame, - good_frame) + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + + overflow=overflow, + bad_frame=bad_frame, + good_frame=good_frame + ) @always(delay(4)) def clkgen(): @@ -197,16 +167,14 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -229,16 +197,14 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -259,7 +225,7 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -280,9 +246,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -309,8 +273,8 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -319,15 +283,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -354,8 +314,8 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -369,15 +329,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -404,8 +360,8 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -419,15 +375,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -451,12 +403,12 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(1000) - assert sink_queue.empty() + assert sink.empty() assert not overflow_asserted assert bad_frame_asserted @@ -477,12 +429,12 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(10000) - assert sink_queue.empty() + assert sink.empty() assert overflow_asserted assert not bad_frame_asserted @@ -497,7 +449,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -508,9 +460,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -523,7 +473,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -541,13 +491,13 @@ def bench(): yield clk.posedge yield clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, monitor, source, sink, clkgen, check + return dut, monitor, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v index 912240cc7..6f4866aa3 100644 --- a/tb/test_axis_frame_fifo.v +++ b/tb/test_axis_frame_fifo.v @@ -24,16 +24,24 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_frame_fifo + */ module test_axis_frame_fifo; +// Parameters +parameter ADDR_WIDTH = 9; +parameter DATA_WIDTH = 8; +parameter DROP_WHEN_FULL = 0; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -41,7 +49,7 @@ reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [7:0] output_axis_tdata; +wire [DATA_WIDTH-1:0] output_axis_tdata; wire output_axis_tvalid; wire output_axis_tlast; wire overflow; @@ -50,21 +58,25 @@ wire good_frame; 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, - overflow, - bad_frame, - good_frame); + $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, + overflow, + bad_frame, + good_frame + ); // dump file $dumpfile("test_axis_frame_fifo.lxt"); @@ -72,9 +84,9 @@ initial begin end axis_frame_fifo #( - .ADDR_WIDTH(9), - .DATA_WIDTH(8), - .DROP_WHEN_FULL(0) + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .DROP_WHEN_FULL(DROP_WHEN_FULL) ) UUT ( .clk(clk), diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index 46fcb5c4e..bf35734f3 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -26,80 +26,35 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_frame_fifo_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_frame_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, - - overflow, - bad_frame, - good_frame): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - overflow=overflow, - bad_frame=bad_frame, - good_frame=good_frame) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + ADDR_WIDTH = 6 + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + DROP_WHEN_FULL = 0 + # 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -107,67 +62,74 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) overflow = Signal(bool(0)) bad_frame = Signal(bool(0)) good_frame = 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_frame_fifo_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + 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, - overflow, - bad_frame, - good_frame) + 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, + + overflow=overflow, + bad_frame=bad_frame, + good_frame=good_frame + ) @always(delay(4)) def clkgen(): @@ -212,16 +174,14 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -244,16 +204,14 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -274,7 +232,7 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -295,9 +253,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -324,8 +280,8 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -334,15 +290,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -369,8 +321,8 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -384,15 +336,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -419,8 +367,8 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -434,15 +382,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -466,12 +410,12 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(1000) - assert sink_queue.empty() + assert sink.empty() assert not overflow_asserted assert bad_frame_asserted @@ -492,12 +436,12 @@ def bench(): bad_frame_asserted.next = 0 good_frame_asserted.next = 0 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(10000) - assert sink_queue.empty() + assert sink.empty() assert overflow_asserted assert not bad_frame_asserted @@ -512,7 +456,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -523,9 +467,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -538,7 +480,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -556,13 +498,13 @@ def bench(): yield clk.posedge yield clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, monitor, source, sink, clkgen, check + return dut, monitor, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v index 45b683a2a..6fb8833c3 100644 --- a/tb/test_axis_frame_fifo_64.v +++ b/tb/test_axis_frame_fifo_64.v @@ -24,17 +24,26 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_frame_fifo_64 + */ module test_axis_frame_fifo_64; +// Parameters +parameter ADDR_WIDTH = 6; +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter DROP_WHEN_FULL = 0; + // 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 [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -42,8 +51,8 @@ reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire overflow; @@ -52,23 +61,27 @@ wire good_frame; 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, - overflow, - bad_frame, - good_frame); + $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, + overflow, + bad_frame, + good_frame + ); // dump file $dumpfile("test_axis_frame_fifo_64.lxt"); @@ -76,9 +89,10 @@ initial begin end axis_frame_fifo_64 #( - .ADDR_WIDTH(6), - .DATA_WIDTH(64), - .DROP_WHEN_FULL(0) + .ADDR_WIDTH(ADDR_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .DROP_WHEN_FULL(DROP_WHEN_FULL) ) UUT ( .clk(clk), diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index 4e2358b36..54b08a218 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -27,103 +27,26 @@ from myhdl import * import os import struct -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_frame_join_4' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_frame_join_4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - tag, - busy): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tuser=input_0_axis_tuser, - - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tuser=input_1_axis_tuser, - - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tuser=input_2_axis_tuser, - - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tuser=input_3_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - tag=tag, - busy=busy) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + TAG_ENABLE = 1 + TAG_WIDTH = 16 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) @@ -146,7 +69,7 @@ def bench(): input_3_axis_tlast = Signal(bool(0)) input_3_axis_tuser = Signal(bool(0)) output_axis_tready = Signal(bool(0)) - tag = Signal(intbv(0)[15:]) + tag = Signal(intbv(0)[TAG_WIDTH:]) # Outputs input_0_axis_tready = Signal(bool(0)) @@ -160,109 +83,125 @@ def bench(): busy = Signal(bool(0)) # sources and sinks - source_0_queue = Queue() source_0_pause = Signal(bool(0)) - source_1_queue = Queue() source_1_pause = Signal(bool(0)) - source_2_queue = Queue() source_2_pause = Signal(bool(0)) - source_3_queue = Queue() source_3_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_0_axis_tdata, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tuser=input_0_axis_tuser, - fifo=source_0_queue, - pause=source_0_pause, - name='source_0') + source_0 = axis_ep.AXIStreamSource() - source_1 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_1_axis_tdata, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tuser=input_1_axis_tuser, - fifo=source_1_queue, - pause=source_1_pause, - name='source_1') + source_0_logic = source_0.create_logic( + clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + pause=source_0_pause, + name='source_0' + ) - source_2 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_2_axis_tdata, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tuser=input_2_axis_tuser, - fifo=source_2_queue, - pause=source_2_pause, - name='source_2') + source_1 = axis_ep.AXIStreamSource() - source_3 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_3_axis_tdata, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tuser=input_3_axis_tuser, - fifo=source_3_queue, - pause=source_3_pause, - name='source_3') + source_1_logic = source_1.create_logic( + clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + pause=source_1_pause, + name='source_1' + ) - 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') + source_2 = axis_ep.AXIStreamSource() + + source_2_logic = source_2.create_logic( + clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + pause=source_2_pause, + name='source_2' + ) + + source_3 = axis_ep.AXIStreamSource() + + source_3_logic = source_3.create_logic( + clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + pause=source_3_pause, + name='source_3' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_frame_join_4(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, - tag, - busy) + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + tag=tag, + busy=busy + ) @always(delay(4)) def clkgen(): @@ -290,19 +229,17 @@ def bench(): test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0) - source_1_queue.put(test_frame_1) - source_2_queue.put(test_frame_2) - source_3_queue.put(test_frame_3) + source_0.send(test_frame_0) + source_1.send(test_frame_1) + source_2.send(test_frame_2) + source_3.send(test_frame_3) yield clk.posedge yield output_axis_tlast.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data @@ -316,19 +253,17 @@ def bench(): test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0) - source_1_queue.put(test_frame_1) - source_2_queue.put(test_frame_2) - source_3_queue.put(test_frame_3) + source_0.send(test_frame_0) + source_1.send(test_frame_1) + source_2.send(test_frame_2) + source_3.send(test_frame_3) yield clk.posedge yield output_axis_tlast.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data @@ -342,10 +277,10 @@ def bench(): test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0) - source_1_queue.put(test_frame_1) - source_2_queue.put(test_frame_2) - source_3_queue.put(test_frame_3) + source_0.send(test_frame_0) + source_1.send(test_frame_1) + source_2.send(test_frame_2) + source_3.send(test_frame_3) yield clk.posedge yield delay(64) @@ -366,9 +301,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data @@ -386,14 +319,14 @@ def bench(): test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0a) - source_0_queue.put(test_frame_0b) - source_1_queue.put(test_frame_1a) - source_1_queue.put(test_frame_1b) - source_2_queue.put(test_frame_2a) - source_2_queue.put(test_frame_2b) - source_3_queue.put(test_frame_3a) - source_3_queue.put(test_frame_3b) + source_0.send(test_frame_0a) + source_0.send(test_frame_0b) + source_1.send(test_frame_1a) + source_1.send(test_frame_1b) + source_2.send(test_frame_2a) + source_2.send(test_frame_2b) + source_3.send(test_frame_3a) + source_3.send(test_frame_3b) yield clk.posedge yield output_axis_tlast.posedge @@ -402,15 +335,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data @@ -428,14 +357,14 @@ def bench(): test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0a) - source_0_queue.put(test_frame_0b) - source_1_queue.put(test_frame_1a) - source_1_queue.put(test_frame_1b) - source_2_queue.put(test_frame_2a) - source_2_queue.put(test_frame_2b) - source_3_queue.put(test_frame_3a) - source_3_queue.put(test_frame_3b) + source_0.send(test_frame_0a) + source_0.send(test_frame_0b) + source_1.send(test_frame_1a) + source_1.send(test_frame_1b) + source_2.send(test_frame_2a) + source_2.send(test_frame_2b) + source_3.send(test_frame_3a) + source_3.send(test_frame_3b) yield clk.posedge while input_3_axis_tvalid or output_axis_tvalid: @@ -455,15 +384,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data @@ -481,14 +406,14 @@ def bench(): test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0_queue.put(test_frame_0a) - source_0_queue.put(test_frame_0b) - source_1_queue.put(test_frame_1a) - source_1_queue.put(test_frame_1b) - source_2_queue.put(test_frame_2a) - source_2_queue.put(test_frame_2b) - source_3_queue.put(test_frame_3a) - source_3_queue.put(test_frame_3b) + source_0.send(test_frame_0a) + source_0.send(test_frame_0b) + source_1.send(test_frame_1a) + source_1.send(test_frame_1b) + source_2.send(test_frame_2a) + source_2.send(test_frame_2b) + source_3.send(test_frame_3a) + source_3.send(test_frame_3b) yield clk.posedge while input_3_axis_tvalid or output_axis_tvalid: @@ -502,15 +427,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data @@ -525,19 +446,17 @@ def bench(): test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') test_frame_0.user = 1 - source_0_queue.put(test_frame_0) - source_1_queue.put(test_frame_1) - source_2_queue.put(test_frame_2) - source_3_queue.put(test_frame_3) + source_0.send(test_frame_0) + source_1.send(test_frame_1) + source_2.send(test_frame_2) + source_3.send(test_frame_3) yield clk.posedge yield output_axis_tlast.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data assert rx_frame.user[-1] @@ -546,7 +465,7 @@ def bench(): raise StopSimulation - return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_join_4.v b/tb/test_axis_frame_join_4.v index efc6c62d0..b02e2f7c8 100644 --- a/tb/test_axis_frame_join_4.v +++ b/tb/test_axis_frame_join_4.v @@ -24,33 +24,40 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_frame_join_4 + */ module test_axis_frame_join_4; +// Parameters +parameter TAG_ENABLE = 1; +parameter TAG_WIDTH = 16; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_0_axis_tdata = 8'd0; -reg input_0_axis_tvalid = 1'b0; -reg input_0_axis_tlast = 1'b0; -reg input_0_axis_tuser = 1'b0; -reg [7:0] input_1_axis_tdata = 8'd0; -reg input_1_axis_tvalid = 1'b0; -reg input_1_axis_tlast = 1'b0; -reg input_1_axis_tuser = 1'b0; -reg [7:0] input_2_axis_tdata = 8'd0; -reg input_2_axis_tvalid = 1'b0; -reg input_2_axis_tlast = 1'b0; -reg input_2_axis_tuser = 1'b0; -reg [7:0] input_3_axis_tdata = 8'd0; -reg input_3_axis_tvalid = 1'b0; -reg input_3_axis_tlast = 1'b0; -reg input_3_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; -reg [15:0] tag = 0; +reg [7:0] input_0_axis_tdata = 0; +reg input_0_axis_tvalid = 0; +reg input_0_axis_tlast = 0; +reg input_0_axis_tuser = 0; +reg [7:0] input_1_axis_tdata = 0; +reg input_1_axis_tvalid = 0; +reg input_1_axis_tlast = 0; +reg input_1_axis_tuser = 0; +reg [7:0] input_2_axis_tdata = 0; +reg input_2_axis_tvalid = 0; +reg input_2_axis_tlast = 0; +reg input_2_axis_tuser = 0; +reg [7:0] input_3_axis_tdata = 0; +reg input_3_axis_tvalid = 0; +reg input_3_axis_tlast = 0; +reg input_3_axis_tuser = 0; +reg output_axis_tready = 0; +reg [TAG_WIDTH-1:0] tag = 0; // Outputs wire input_0_axis_tready; @@ -65,36 +72,40 @@ wire busy; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tuser, - output_axis_tready, - tag); - $to_myhdl(input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, - busy); + $from_myhdl( + clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready, + tag + ); + $to_myhdl( + input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + busy + ); // dump file $dumpfile("test_axis_frame_join_4.lxt"); @@ -102,7 +113,8 @@ initial begin end axis_frame_join_4 #( - .TAG_ENABLE(1) + .TAG_ENABLE(TAG_ENABLE), + .TAG_WIDTH(TAG_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_frame_length_adjust_64.py b/tb/test_axis_frame_length_adjust_64.py index ca00a7d4f..32ac0d342 100755 --- a/tb/test_axis_frame_length_adjust_64.py +++ b/tb/test_axis_frame_length_adjust_64.py @@ -26,92 +26,33 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_frame_length_adjust' +testbench = 'test_%s_64' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s_64.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s_64.vvp %s" % (module, src) - -def dut_axis_frame_length_adjust_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, - - status_valid, - status_ready, - status_frame_pad, - status_frame_truncate, - status_frame_length, - status_frame_original_length, - - length_min, - length_max): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s_64.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, - - status_valid=status_valid, - status_ready=status_ready, - status_frame_pad=status_frame_pad, - status_frame_truncate=status_frame_truncate, - status_frame_length=status_frame_length, - status_frame_original_length=status_frame_original_length, - - length_min=length_min, - length_max=length_max) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -122,8 +63,8 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) @@ -134,74 +75,86 @@ def bench(): status_frame_original_length = Signal(intbv(0)[16:]) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - status_sink_queue = Queue() status_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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) - status_sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=(status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length), - tvalid=status_valid, - tready=status_ready, - fifo=status_sink_queue, - pause=status_sink_pause, - name='status_sink') + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) + + status_sink = axis_ep.AXIStreamSink() + + status_sink_logic = status_sink.create_logic( + clk, + rst, + tdata=(status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length), + tvalid=status_valid, + tready=status_ready, + pause=status_sink_pause, + name='status_sink' + ) # DUT - dut = dut_axis_frame_length_adjust_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + 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, - status_valid, - status_ready, - status_frame_pad, - status_frame_truncate, - status_frame_length, - status_frame_original_length, + 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, - length_min, - length_max) + status_valid=status_valid, + status_ready=status_ready, + status_frame_pad=status_frame_pad, + status_frame_truncate=status_frame_truncate, + status_frame_length=status_frame_length, + status_frame_original_length=status_frame_original_length, + + length_min=length_min, + length_max=length_max + ) @always(delay(4)) def clkgen(): @@ -256,7 +209,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge @@ -266,7 +219,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame.data) @@ -275,14 +228,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame.data[:lm] - status = status_sink_queue.get(False) + status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt - assert sink_queue.empty() - assert status_sink_queue.empty() + assert sink.empty() + assert status_sink.empty() yield delay(100) @@ -294,8 +247,8 @@ def bench(): test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -305,7 +258,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame1.data) @@ -314,13 +267,13 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] - status = status_sink_queue.get(False) + status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame2.data) @@ -329,14 +282,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] - status = status_sink_queue.get(False) + status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt - assert sink_queue.empty() - assert status_sink_queue.empty() + assert sink.empty() + assert status_sink.empty() yield delay(100) @@ -350,8 +303,8 @@ def bench(): test_frame1.user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -361,7 +314,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame1.data) @@ -372,13 +325,13 @@ def bench(): assert rx_frame.user[-1] - status = status_sink_queue.get(False) + status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame2.data) @@ -387,20 +340,20 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] - status = status_sink_queue.get(False) + status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt - assert sink_queue.empty() - assert status_sink_queue.empty() + assert sink.empty() + assert status_sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, status_sink, clkgen, check + return dut, source_logic, sink_logic, status_sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_length_adjust_64.v b/tb/test_axis_frame_length_adjust_64.v index 32c9e41f7..aa00751de 100644 --- a/tb/test_axis_frame_length_adjust_64.v +++ b/tb/test_axis_frame_length_adjust_64.v @@ -24,11 +24,14 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_frame_length_adjust + */ module test_axis_frame_length_adjust_64; -// parameters +// Parameters localparam DATA_WIDTH = 64; localparam KEEP_WIDTH = (DATA_WIDTH/8); @@ -62,29 +65,33 @@ wire [15:0] status_frame_original_length; 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, - status_ready, - length_min, - length_max); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, - status_valid, - status_frame_pad, - status_frame_truncate, - status_frame_length, - status_frame_original_length); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready, + status_ready, + length_min, + length_max + ); + $to_myhdl( + input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + status_valid, + status_frame_pad, + status_frame_truncate, + status_frame_length, + status_frame_original_length + ); // dump file $dumpfile("test_axis_frame_length_adjust_64.lxt"); diff --git a/tb/test_axis_frame_length_adjust_8.py b/tb/test_axis_frame_length_adjust_8.py index e5f87fbc4..4f60f4c06 100755 --- a/tb/test_axis_frame_length_adjust_8.py +++ b/tb/test_axis_frame_length_adjust_8.py @@ -26,92 +26,33 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_frame_length_adjust' +testbench = 'test_%s_8' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s_8.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s_8.vvp %s" % (module, src) - -def dut_axis_frame_length_adjust_8(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - status_valid, - status_ready, - status_frame_pad, - status_frame_truncate, - status_frame_length, - status_frame_original_length, - - length_min, - length_max): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s_8.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, - - status_valid=status_valid, - status_ready=status_ready, - status_frame_pad=status_frame_pad, - status_frame_truncate=status_frame_truncate, - status_frame_length=status_frame_length, - status_frame_original_length=status_frame_original_length, - - length_min=length_min, - length_max=length_max) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + KEEP_WIDTH = (DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) - input_axis_tkeep = Signal(intbv(0)[1:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -122,8 +63,8 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tkeep = Signal(intbv(0)[1:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) @@ -134,74 +75,86 @@ def bench(): status_frame_original_length = Signal(intbv(0)[16:]) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - status_sink_queue = Queue() status_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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) - status_sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=(status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length), - tvalid=status_valid, - tready=status_ready, - fifo=status_sink_queue, - pause=status_sink_pause, - name='status_sink') + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) + + status_sink = axis_ep.AXIStreamSink() + + status_sink_logic = status_sink.create_logic( + clk, + rst, + tdata=(status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length), + tvalid=status_valid, + tready=status_ready, + pause=status_sink_pause, + name='status_sink' + ) # DUT - dut = dut_axis_frame_length_adjust_8(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + 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, - status_valid, - status_ready, - status_frame_pad, - status_frame_truncate, - status_frame_length, - status_frame_original_length, + 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, - length_min, - length_max) + status_valid=status_valid, + status_ready=status_ready, + status_frame_pad=status_frame_pad, + status_frame_truncate=status_frame_truncate, + status_frame_length=status_frame_length, + status_frame_original_length=status_frame_original_length, + + length_min=length_min, + length_max=length_max + ) @always(delay(4)) def clkgen(): @@ -256,7 +209,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge @@ -266,7 +219,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame.data) @@ -275,14 +228,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame.data[:lm] - status = status_sink_queue.get(False) + status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt - assert sink_queue.empty() - assert status_sink_queue.empty() + assert sink.empty() + assert status_sink.empty() yield delay(100) @@ -294,8 +247,8 @@ def bench(): test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -305,7 +258,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame1.data) @@ -314,13 +267,13 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] - status = status_sink_queue.get(False) + status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame2.data) @@ -329,14 +282,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] - status = status_sink_queue.get(False) + status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt - assert sink_queue.empty() - assert status_sink_queue.empty() + assert sink.empty() + assert status_sink.empty() yield delay(100) @@ -350,8 +303,8 @@ def bench(): test_frame1.user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -361,7 +314,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame1.data) @@ -372,13 +325,13 @@ def bench(): assert rx_frame.user[-1] - status = status_sink_queue.get(False) + status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame2.data) @@ -387,20 +340,20 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] - status = status_sink_queue.get(False) + status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt - assert sink_queue.empty() - assert status_sink_queue.empty() + assert sink.empty() + assert status_sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, status_sink, clkgen, check + return dut, source_logic, sink_logic, status_sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_length_adjust_8.v b/tb/test_axis_frame_length_adjust_8.v index 48eb46657..5e76e71e1 100644 --- a/tb/test_axis_frame_length_adjust_8.v +++ b/tb/test_axis_frame_length_adjust_8.v @@ -24,11 +24,14 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_frame_length_adjust + */ module test_axis_frame_length_adjust_8; -// parameters +// Parameters localparam DATA_WIDTH = 8; localparam KEEP_WIDTH = (DATA_WIDTH/8); @@ -62,29 +65,33 @@ wire [15:0] status_frame_original_length; 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, - status_ready, - length_min, - length_max); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, - status_valid, - status_frame_pad, - status_frame_truncate, - status_frame_length, - status_frame_original_length); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready, + status_ready, + length_min, + length_max + ); + $to_myhdl( + input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + status_valid, + status_frame_pad, + status_frame_truncate, + status_frame_length, + status_frame_original_length + ); // dump file $dumpfile("test_axis_frame_length_adjust_8.lxt"); diff --git a/tb/test_axis_frame_length_adjust_fifo.py b/tb/test_axis_frame_length_adjust_fifo.py index 5f7b579d5..a35c1c6fb 100755 --- a/tb/test_axis_frame_length_adjust_fifo.py +++ b/tb/test_axis_frame_length_adjust_fifo.py @@ -26,87 +26,35 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_frame_length_adjust_fifo' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/axis_frame_length_adjust.v") srcs.append("../rtl/axis_fifo.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_frame_length_adjust_fifo(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_hdr_valid, - output_axis_hdr_ready, - output_axis_hdr_pad, - output_axis_hdr_truncate, - output_axis_hdr_length, - output_axis_hdr_original_length, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - length_min, - length_max): - - 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_hdr_valid=output_axis_hdr_valid, - output_axis_hdr_ready=output_axis_hdr_ready, - output_axis_hdr_pad=output_axis_hdr_pad, - output_axis_hdr_truncate=output_axis_hdr_truncate, - output_axis_hdr_length=output_axis_hdr_length, - output_axis_hdr_original_length=output_axis_hdr_original_length, - 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, - - length_min=length_min, - length_max=length_max) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + FRAME_FIFO_ADDR_WIDTH = 12 + HEADER_FIFO_ADDR_WIDTH = 3 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -122,75 +70,87 @@ def bench(): output_axis_hdr_truncate = Signal(bool(0)) output_axis_hdr_length = Signal(intbv(0)[16:]) output_axis_hdr_original_length = Signal(intbv(0)[16:]) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) 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)) - hdr_sink_queue = Queue() hdr_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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) - hdr_sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=(output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length), - tvalid=output_axis_hdr_valid, - tready=output_axis_hdr_ready, - fifo=hdr_sink_queue, - pause=hdr_sink_pause, - name='hdr_sink') + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) + + hdr_sink = axis_ep.AXIStreamSink() + + hdr_sink_logic = hdr_sink.create_logic( + clk, + rst, + tdata=(output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length), + tvalid=output_axis_hdr_valid, + tready=output_axis_hdr_ready, + pause=hdr_sink_pause, + name='hdr_sink' + ) # DUT - dut = dut_axis_frame_length_adjust_fifo(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_hdr_valid, - output_axis_hdr_ready, - output_axis_hdr_pad, - output_axis_hdr_truncate, - output_axis_hdr_length, - output_axis_hdr_original_length, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + 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, - length_min, - length_max) + output_axis_hdr_valid=output_axis_hdr_valid, + output_axis_hdr_ready=output_axis_hdr_ready, + output_axis_hdr_pad=output_axis_hdr_pad, + output_axis_hdr_truncate=output_axis_hdr_truncate, + output_axis_hdr_length=output_axis_hdr_length, + output_axis_hdr_original_length=output_axis_hdr_original_length, + 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, + + length_min=length_min, + length_max=length_max + ) @always(delay(4)) def clkgen(): @@ -227,7 +187,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) for wait in wait_normal,: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -241,9 +201,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame.data) @@ -252,14 +210,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame.data[:lm] - hdr = hdr_sink_queue.get(False) + hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt - assert sink_queue.empty() - assert hdr_sink_queue.empty() + assert sink.empty() + assert hdr_sink.empty() yield delay(100) @@ -271,8 +229,8 @@ def bench(): test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) for wait in wait_normal,: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -284,9 +242,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame1.data) @@ -295,15 +251,13 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] - hdr = hdr_sink_queue.get(False) + hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame2.data) @@ -312,14 +266,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] - hdr = hdr_sink_queue.get(False) + hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt - assert sink_queue.empty() - assert hdr_sink_queue.empty() + assert sink.empty() + assert hdr_sink.empty() yield delay(100) @@ -333,8 +287,8 @@ def bench(): test_frame1.user = 1 for wait in wait_normal,: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -346,9 +300,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame1.data) @@ -357,16 +309,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] - hdr = hdr_sink_queue.get(False) + hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt assert rx_frame.user[-1] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame2.data) @@ -375,20 +325,20 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] - hdr = hdr_sink_queue.get(False) + hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt - assert sink_queue.empty() - assert hdr_sink_queue.empty() + assert sink.empty() + assert hdr_sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, hdr_sink, clkgen, check + return dut, source_logic, sink_logic, hdr_sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_length_adjust_fifo.v b/tb/test_axis_frame_length_adjust_fifo.v index b18ce0ffd..c2d41764a 100644 --- a/tb/test_axis_frame_length_adjust_fifo.v +++ b/tb/test_axis_frame_length_adjust_fifo.v @@ -24,11 +24,14 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_frame_length_adjust_fifo + */ module test_axis_frame_length_adjust_fifo; -// parameters +// Parameters localparam DATA_WIDTH = 8; localparam FRAME_FIFO_ADDR_WIDTH = 12; localparam HEADER_FIFO_ADDR_WIDTH = 3; @@ -61,27 +64,31 @@ wire [15:0] output_axis_hdr_original_length; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_hdr_ready, - output_axis_tready, - length_min, - length_max); - $to_myhdl(input_axis_tready, - output_axis_hdr_valid, - output_axis_hdr_pad, - output_axis_hdr_truncate, - output_axis_hdr_length, - output_axis_hdr_original_length, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_hdr_ready, + output_axis_tready, + length_min, + length_max + ); + $to_myhdl( + input_axis_tready, + output_axis_hdr_valid, + output_axis_hdr_pad, + output_axis_hdr_truncate, + output_axis_hdr_length, + output_axis_hdr_original_length, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_frame_length_adjust_fifo.lxt"); diff --git a/tb/test_axis_frame_length_adjust_fifo_64.py b/tb/test_axis_frame_length_adjust_fifo_64.py index 53b07fc49..17473dc37 100755 --- a/tb/test_axis_frame_length_adjust_fifo_64.py +++ b/tb/test_axis_frame_length_adjust_fifo_64.py @@ -26,14 +26,10 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_frame_length_adjust_fifo_64' +testbench = 'test_%s' % module srcs = [] @@ -41,78 +37,27 @@ srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/axis_frame_length_adjust.v") srcs.append("../rtl/axis_fifo.v") srcs.append("../rtl/axis_fifo_64.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_frame_length_adjust_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_hdr_valid, - output_axis_hdr_ready, - output_axis_hdr_pad, - output_axis_hdr_truncate, - output_axis_hdr_length, - output_axis_hdr_original_length, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - length_min, - length_max): - - 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_hdr_valid=output_axis_hdr_valid, - output_axis_hdr_ready=output_axis_hdr_ready, - output_axis_hdr_pad=output_axis_hdr_pad, - output_axis_hdr_truncate=output_axis_hdr_truncate, - output_axis_hdr_length=output_axis_hdr_length, - output_axis_hdr_original_length=output_axis_hdr_original_length, - 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, - - length_min=length_min, - length_max=length_max) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + FRAME_FIFO_ADDR_WIDTH = 9 + HEADER_FIFO_ADDR_WIDTH = 3 + # 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -128,80 +73,92 @@ def bench(): output_axis_hdr_truncate = Signal(bool(0)) output_axis_hdr_length = Signal(intbv(0)[16:]) output_axis_hdr_original_length = Signal(intbv(0)[16:]) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) 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)) - hdr_sink_queue = Queue() hdr_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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) - hdr_sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=(output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length), - tvalid=output_axis_hdr_valid, - tready=output_axis_hdr_ready, - fifo=hdr_sink_queue, - pause=hdr_sink_pause, - name='hdr_sink') + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) + + hdr_sink = axis_ep.AXIStreamSink() + + hdr_sink_logic = hdr_sink.create_logic( + clk, + rst, + tdata=(output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length), + tvalid=output_axis_hdr_valid, + tready=output_axis_hdr_ready, + pause=hdr_sink_pause, + name='hdr_sink' + ) # DUT - dut = dut_axis_frame_length_adjust_fifo_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_hdr_valid, - output_axis_hdr_ready, - output_axis_hdr_pad, - output_axis_hdr_truncate, - output_axis_hdr_length, - output_axis_hdr_original_length, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + 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, - length_min, - length_max) + output_axis_hdr_valid=output_axis_hdr_valid, + output_axis_hdr_ready=output_axis_hdr_ready, + output_axis_hdr_pad=output_axis_hdr_pad, + output_axis_hdr_truncate=output_axis_hdr_truncate, + output_axis_hdr_length=output_axis_hdr_length, + output_axis_hdr_original_length=output_axis_hdr_original_length, + 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, + + length_min=length_min, + length_max=length_max + ) @always(delay(4)) def clkgen(): @@ -238,7 +195,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) for wait in wait_normal,: - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -252,9 +209,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame.data) @@ -263,14 +218,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame.data[:lm] - hdr = hdr_sink_queue.get(False) + hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt - assert sink_queue.empty() - assert hdr_sink_queue.empty() + assert sink.empty() + assert hdr_sink.empty() yield delay(100) @@ -282,8 +237,8 @@ def bench(): test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) for wait in wait_normal,: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -295,9 +250,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame1.data) @@ -306,15 +259,13 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] - hdr = hdr_sink_queue.get(False) + hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame2.data) @@ -323,14 +274,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] - hdr = hdr_sink_queue.get(False) + hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt - assert sink_queue.empty() - assert hdr_sink_queue.empty() + assert sink.empty() + assert hdr_sink.empty() yield delay(100) @@ -344,8 +295,8 @@ def bench(): test_frame1.user = 1 for wait in wait_normal,: - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -357,9 +308,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame1.data) @@ -368,16 +317,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] - hdr = hdr_sink_queue.get(False) + hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt assert rx_frame.user[-1] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() lrx = len(rx_frame.data) lt = len(test_frame2.data) @@ -386,20 +333,20 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] - hdr = hdr_sink_queue.get(False) + hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt - assert sink_queue.empty() - assert hdr_sink_queue.empty() + assert sink.empty() + assert hdr_sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, hdr_sink, clkgen, check + return dut, source_logic, sink_logic, hdr_sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_length_adjust_fifo_64.v b/tb/test_axis_frame_length_adjust_fifo_64.v index 74a8f1cb0..ac2031e6e 100644 --- a/tb/test_axis_frame_length_adjust_fifo_64.v +++ b/tb/test_axis_frame_length_adjust_fifo_64.v @@ -24,11 +24,14 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_frame_length_adjust_fifo_64 + */ module test_axis_frame_length_adjust_fifo_64; -// parameters +// Parameters localparam DATA_WIDTH = 64; localparam KEEP_WIDTH = (DATA_WIDTH/8); localparam FRAME_FIFO_ADDR_WIDTH = 9; @@ -64,29 +67,33 @@ wire [15:0] output_axis_hdr_original_length; 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_hdr_ready, - output_axis_tready, - length_min, - length_max); - $to_myhdl(input_axis_tready, - output_axis_hdr_valid, - output_axis_hdr_pad, - output_axis_hdr_truncate, - output_axis_hdr_length, - output_axis_hdr_original_length, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_hdr_ready, + output_axis_tready, + length_min, + length_max + ); + $to_myhdl( + input_axis_tready, + output_axis_hdr_valid, + output_axis_hdr_pad, + output_axis_hdr_truncate, + output_axis_hdr_length, + output_axis_hdr_original_length, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_frame_length_adjust_fifo_64.lxt"); diff --git a/tb/test_axis_ll_bridge.py b/tb/test_axis_ll_bridge.py index 069fe06cc..07012bc9a 100755 --- a/tb/test_axis_ll_bridge.py +++ b/tb/test_axis_ll_bridge.py @@ -26,119 +26,95 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep import ll_ep module = 'axis_ll_bridge' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) 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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - axis_tdata = Signal(intbv(0)[8:]) + axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) 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_data_out = Signal(intbv(0)[DATA_WIDTH:]) 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=axis_tdata, + tvalid=axis_tvalid, + tready=axis_tready, + tlast=axis_tlast, + pause=source_pause, + name='source' + ) + + sink = ll_ep.LocalLinkSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_ll_bridge(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - axis_tdata, - axis_tvalid, - axis_tready, - axis_tlast, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - ll_data_out, - ll_sof_out_n, - ll_eof_out_n, - ll_src_rdy_out_n, - ll_dst_rdy_in_n) + 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 + ) @always(delay(4)) def clkgen(): @@ -161,24 +137,21 @@ def bench(): 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')) + test_frame = 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') + + source.send(test_frame) 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() + rx_frame = sink.recv() - 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') + assert bytearray(rx_frame) == test_frame yield delay(100) @@ -186,10 +159,12 @@ def bench(): 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')) + test_frame = 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') + + source.send(test_frame) yield clk.posedge yield delay(64) @@ -210,20 +185,15 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() - 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') + assert bytearray(rx_frame) == test_frame yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_ll_bridge.v b/tb/test_axis_ll_bridge.v index 6435a13f3..c9922870a 100644 --- a/tb/test_axis_ll_bridge.v +++ b/tb/test_axis_ll_bridge.v @@ -24,22 +24,28 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_ll_bridge + */ module test_axis_ll_bridge; +// Parameters +parameter DATA_WIDTH = 8; + // 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; +reg [DATA_WIDTH-1:0] axis_tdata = 0; +reg axis_tvalid = 0; +reg axis_tlast = 0; +reg ll_dst_rdy_in_n = 1; // Outputs -wire [7:0] ll_data_out; +wire [DATA_WIDTH-1:0] ll_data_out; wire ll_sof_out_n; wire ll_eof_out_n; wire ll_src_rdy_out_n; @@ -47,25 +53,31 @@ 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); + $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 +axis_ll_bridge #( + .DATA_WIDTH(DATA_WIDTH) +) UUT ( .clk(clk), .rst(rst), diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py index 21e176689..269b924f6 100755 --- a/tb/test_axis_mux_4.py +++ b/tb/test_axis_mux_4.py @@ -26,115 +26,43 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_mux_4' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_mux_4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - enable, - select): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tuser=input_3_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - enable=enable, - select=select) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[8:]) + input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) input_0_axis_tuser = Signal(bool(0)) - input_1_axis_tdata = Signal(intbv(0)[8:]) + input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) input_1_axis_tuser = Signal(bool(0)) - input_2_axis_tdata = Signal(intbv(0)[8:]) + input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) input_2_axis_tuser = Signal(bool(0)) - input_3_axis_tdata = Signal(intbv(0)[8:]) + input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) input_3_axis_tuser = Signal(bool(0)) @@ -150,109 +78,128 @@ def bench(): input_2_axis_tready = Signal(bool(0)) input_3_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) # sources and sinks - source_0_queue = Queue() source_0_pause = Signal(bool(0)) - source_1_queue = Queue() source_1_pause = Signal(bool(0)) - source_2_queue = Queue() source_2_pause = Signal(bool(0)) - source_3_queue = Queue() source_3_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_0_axis_tdata, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tuser=input_0_axis_tuser, - fifo=source_0_queue, - pause=source_0_pause, - name='source0') - source_1 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_1_axis_tdata, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tuser=input_1_axis_tuser, - fifo=source_1_queue, - pause=source_1_pause, - name='source1') - source_2 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_2_axis_tdata, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tuser=input_2_axis_tuser, - fifo=source_2_queue, - pause=source_2_pause, - name='source2') - source_3 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_3_axis_tdata, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tuser=input_3_axis_tuser, - fifo=source_3_queue, - pause=source_3_pause, - name='source3') + source_0 = axis_ep.AXIStreamSource() - 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') + source_0_logic = source_0.create_logic( + clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + pause=source_0_pause, + name='source_0' + ) + + source_1 = axis_ep.AXIStreamSource() + + source_1_logic = source_1.create_logic( + clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + pause=source_1_pause, + name='source_1' + ) + + source_2 = axis_ep.AXIStreamSource() + + source_2_logic = source_2.create_logic( + clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + pause=source_2_pause, + name='source_2' + ) + + source_3 = axis_ep.AXIStreamSource() + + source_3_logic = source_3.create_logic( + clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + pause=source_3_pause, + name='source_3' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_mux_4(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, - enable, - select) + 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, + + enable=enable, + select=select + ) @always(delay(4)) def clkgen(): @@ -282,7 +229,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_0_queue.put(test_frame) + source_0.send(test_frame) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -290,9 +237,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -308,7 +253,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame) + source_1.send(test_frame) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -316,9 +261,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -338,8 +281,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_0_queue.put(test_frame1) - source_0_queue.put(test_frame2) + source_0.send(test_frame1) + source_0.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -347,15 +290,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -375,8 +314,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -385,15 +324,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -413,8 +348,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -434,15 +369,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -462,8 +393,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -477,15 +408,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -493,7 +420,7 @@ def bench(): raise StopSimulation - return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_mux_4.v b/tb/test_axis_mux_4.v index 775da897f..ec8bc599d 100644 --- a/tb/test_axis_mux_4.v +++ b/tb/test_axis_mux_4.v @@ -24,28 +24,34 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_mux_4 + */ module test_axis_mux_4; +// Parameters +parameter DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_0_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; reg input_0_axis_tuser = 0; -reg [7:0] input_1_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; reg input_1_axis_tuser = 0; -reg [7:0] input_2_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; reg input_2_axis_tuser = 0; -reg [7:0] input_3_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; reg input_3_axis_tuser = 0; @@ -61,43 +67,47 @@ wire input_1_axis_tready; wire input_2_axis_tready; wire input_3_axis_tready; -wire [7:0] output_axis_tdata; +wire [DATA_WIDTH-1: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_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tuser, - output_axis_tready, - enable, - select); - $to_myhdl(input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready, + enable, + select + ); + $to_myhdl( + input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_mux_4.lxt"); @@ -105,7 +115,7 @@ initial begin end axis_mux_4 #( - .DATA_WIDTH(8) + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_mux_64_4.py b/tb/test_axis_mux_64_4.py index b37ee42ea..6946f2d08 100755 --- a/tb/test_axis_mux_64_4.py +++ b/tb/test_axis_mux_64_4.py @@ -26,129 +26,48 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_mux_64_4' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_mux_64_4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - enable, - select): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tuser=input_3_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_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, - - enable=enable, - select=select) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[64:]) - input_0_axis_tkeep = Signal(intbv(0)[8:]) + input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) input_0_axis_tuser = Signal(bool(0)) - input_1_axis_tdata = Signal(intbv(0)[64:]) - input_1_axis_tkeep = Signal(intbv(0)[8:]) + input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) input_1_axis_tuser = Signal(bool(0)) - input_2_axis_tdata = Signal(intbv(0)[64:]) - input_2_axis_tkeep = Signal(intbv(0)[8:]) + input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) input_2_axis_tuser = Signal(bool(0)) - input_3_axis_tdata = Signal(intbv(0)[64:]) - input_3_axis_tkeep = Signal(intbv(0)[8:]) + input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) input_3_axis_tuser = Signal(bool(0)) @@ -164,120 +83,139 @@ def bench(): input_2_axis_tready = Signal(bool(0)) input_3_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) # sources and sinks - source_0_queue = Queue() source_0_pause = Signal(bool(0)) - source_1_queue = Queue() source_1_pause = Signal(bool(0)) - source_2_queue = Queue() source_2_pause = Signal(bool(0)) - source_3_queue = Queue() source_3_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tuser=input_0_axis_tuser, - fifo=source_0_queue, - pause=source_0_pause, - name='source0') - source_1 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tuser=input_1_axis_tuser, - fifo=source_1_queue, - pause=source_1_pause, - name='source1') - source_2 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tuser=input_2_axis_tuser, - fifo=source_2_queue, - pause=source_2_pause, - name='source2') - source_3 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tuser=input_3_axis_tuser, - fifo=source_3_queue, - pause=source_3_pause, - name='source3') + source_0 = axis_ep.AXIStreamSource() - 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') + source_0_logic = source_0.create_logic( + clk, + rst, + tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tuser=input_0_axis_tuser, + pause=source_0_pause, + name='source_0' + ) + + source_1 = axis_ep.AXIStreamSource() + + source_1_logic = source_1.create_logic( + clk, + rst, + tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tuser=input_1_axis_tuser, + pause=source_1_pause, + name='source_1' + ) + + source_2 = axis_ep.AXIStreamSource() + + source_2_logic = source_2.create_logic( + clk, + rst, + tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tuser=input_2_axis_tuser, + pause=source_2_pause, + name='source_2' + ) + + source_3 = axis_ep.AXIStreamSource() + + source_3_logic = source_3.create_logic( + clk, + rst, + tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tuser=input_3_axis_tuser, + pause=source_3_pause, + name='source_3' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_mux_64_4(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tuser=input_3_axis_tuser, - enable, - select) + 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, + + enable=enable, + select=select + ) @always(delay(4)) def clkgen(): @@ -307,7 +245,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_0_queue.put(test_frame) + source_0.send(test_frame) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -315,9 +253,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -333,7 +269,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame) + source_1.send(test_frame) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -341,9 +277,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -363,8 +297,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_0_queue.put(test_frame1) - source_0_queue.put(test_frame2) + source_0.send(test_frame1) + source_0.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -372,15 +306,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -400,8 +330,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -410,15 +340,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -438,8 +364,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -459,15 +385,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -487,8 +409,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) + source_1.send(test_frame1) + source_2.send(test_frame2) yield clk.posedge while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: @@ -502,15 +424,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -518,7 +436,7 @@ def bench(): raise StopSimulation - return dut, source_0, source_1, source_2, source_3, sink, clkgen, check + return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_mux_64_4.v b/tb/test_axis_mux_64_4.v index fdb83d7d4..1ae4bb440 100644 --- a/tb/test_axis_mux_64_4.v +++ b/tb/test_axis_mux_64_4.v @@ -24,32 +24,39 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_mux_64_4 + */ module test_axis_mux_64_4; +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] input_0_axis_tdata = 0; -reg [7:0] input_0_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; reg input_0_axis_tuser = 0; -reg [63:0] input_1_axis_tdata = 0; -reg [7:0] input_1_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; reg input_1_axis_tuser = 0; -reg [63:0] input_2_axis_tdata = 0; -reg [7:0] input_2_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; reg input_2_axis_tuser = 0; -reg [63:0] input_3_axis_tdata = 0; -reg [7:0] input_3_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; reg input_3_axis_tuser = 0; @@ -65,49 +72,53 @@ wire input_1_axis_tready; wire input_2_axis_tready; wire input_3_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tuser, - output_axis_tready, - enable, - select); - $to_myhdl(input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tuser, + output_axis_tready, + enable, + select + ); + $to_myhdl( + input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_mux_64_4.lxt"); @@ -115,7 +126,8 @@ initial begin end axis_mux_64_4 #( - .DATA_WIDTH(64) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index d35fd24b0..f71b61fba 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -26,75 +26,31 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_rate_limit' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_rate_limit(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - rate_num, - rate_denom, - rate_by_frame): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - rate_num=rate_num, - rate_denom=rate_denom, - rate_by_frame=rate_by_frame) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -106,59 +62,69 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_rate_limit(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + 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, - rate_num, - rate_denom, - rate_by_frame) + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + rate_num=rate_num, + rate_denom=rate_denom, + rate_by_frame=rate_by_frame + ) @always(delay(4)) def clkgen(): @@ -223,7 +189,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -232,9 +198,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -248,7 +212,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -257,9 +221,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -271,7 +233,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -294,9 +256,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -314,8 +274,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -324,15 +284,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -350,8 +306,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -368,15 +324,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -394,8 +346,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -412,15 +364,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -435,7 +383,7 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -444,9 +392,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -476,7 +422,7 @@ def bench(): bytearray(range(lens[i])))) for f in test_frame: - source_queue.put(f) + source.send(f) yield clk.posedge yield clk.posedge @@ -490,8 +436,8 @@ def bench(): rx_frame = [] for i in range(len(lens)): - if not sink_queue.empty(): - rx_frame.append(sink_queue.get()) + if not sink.empty(): + rx_frame.append(sink.recv()) assert len(rx_frame) == len(test_frame) @@ -523,7 +469,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, monitor, check + return dut, source_logic, sink_logic, clkgen, monitor, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_rate_limit.v b/tb/test_axis_rate_limit.v index eb245d880..fcab5cca6 100644 --- a/tb/test_axis_rate_limit.v +++ b/tb/test_axis_rate_limit.v @@ -24,49 +24,59 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_rate_limit + */ module test_axis_rate_limit; +// Parameters +parameter DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_axis_tdata = 8'd0; -reg input_axis_tvalid = 1'b0; -reg input_axis_tlast = 1'b0; -reg input_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; +reg [DATA_WIDTH-1: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; reg [7:0] rate_num = 0; reg [7:0] rate_denom = 0; reg rate_by_frame = 0; // Outputs wire input_axis_tready; -wire [7:0] output_axis_tdata; +wire [DATA_WIDTH-1:0] output_axis_tdata; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready, - rate_num, - rate_denom, - rate_by_frame); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready, + rate_num, + rate_denom, + rate_by_frame + ); + $to_myhdl( + input_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_rate_limit.lxt"); @@ -74,7 +84,7 @@ initial begin end axis_rate_limit #( - .DATA_WIDTH(8) + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index 27fa4a567..554fa8bcb 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -26,80 +26,33 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_rate_limit_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_rate_limit_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - rate_num, - rate_denom, - rate_by_frame): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - rate_num=rate_num, - rate_denom=rate_denom, - rate_by_frame=rate_by_frame) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -111,64 +64,74 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_rate_limit_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + 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, - rate_num, - rate_denom, - rate_by_frame) + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + rate_num=rate_num, + rate_denom=rate_denom, + rate_by_frame=rate_by_frame + ) @always(delay(4)) def clkgen(): @@ -233,7 +196,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -242,9 +205,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -258,7 +219,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -267,9 +228,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -281,7 +240,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -304,9 +263,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -324,8 +281,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -334,15 +291,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -360,8 +313,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -378,15 +331,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -404,8 +353,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -422,15 +371,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -445,7 +390,7 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -454,9 +399,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -486,7 +429,7 @@ def bench(): bytearray(range(lens[i])))) for f in test_frame: - source_queue.put(f) + source.send(f) yield clk.posedge yield clk.posedge @@ -500,8 +443,8 @@ def bench(): rx_frame = [] for i in range(len(lens)): - if not sink_queue.empty(): - rx_frame.append(sink_queue.get()) + if not sink.empty(): + rx_frame.append(sink.recv()) assert len(rx_frame) == len(test_frame) @@ -533,7 +476,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, monitor, check + return dut, source_logic, sink_logic, clkgen, monitor, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_rate_limit_64.v b/tb/test_axis_rate_limit_64.v index c7577530f..21392eefd 100644 --- a/tb/test_axis_rate_limit_64.v +++ b/tb/test_axis_rate_limit_64.v @@ -24,53 +24,64 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_rate_limit_64 + */ module test_axis_rate_limit_64; +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] input_axis_tdata = 8'd0; -reg [7:0] input_axis_tkeep = 8'd0; -reg input_axis_tvalid = 1'b0; -reg input_axis_tlast = 1'b0; -reg input_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; reg [7:0] rate_num = 0; reg [7:0] rate_denom = 0; reg rate_by_frame = 0; // Outputs wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready, - rate_num, - rate_denom, - rate_by_frame); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready, + rate_num, + rate_denom, + rate_by_frame + ); + $to_myhdl( + input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_rate_limit_64.lxt"); @@ -78,7 +89,8 @@ initial begin end axis_rate_limit_64 #( - .DATA_WIDTH(64) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py index 3b12059ff..a53e3aede 100755 --- a/tb/test_axis_register.py +++ b/tb/test_axis_register.py @@ -26,61 +26,25 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_register' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_register(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) @@ -100,49 +64,59 @@ def bench(): 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_register(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + 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 + ) @always(delay(4)) def clkgen(): @@ -169,16 +143,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -192,16 +164,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -213,7 +183,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -234,9 +204,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -254,8 +222,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -264,15 +232,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -290,8 +254,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -305,15 +269,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -331,8 +291,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -346,15 +306,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -369,16 +325,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -387,7 +341,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_register.v b/tb/test_axis_register.v index fe3ed4ee1..82c9a8207 100644 --- a/tb/test_axis_register.v +++ b/tb/test_axis_register.v @@ -24,43 +24,53 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_register + */ module test_axis_register; +// Parameters +parameter DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_axis_tdata = 8'd0; -reg input_axis_tvalid = 1'b0; -reg input_axis_tlast = 1'b0; -reg input_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; +reg [DATA_WIDTH-1: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 [DATA_WIDTH-1: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); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready + ); + $to_myhdl( + input_axis_tready, + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_register.lxt"); @@ -68,7 +78,7 @@ initial begin end axis_register #( - .DATA_WIDTH(8) + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py index 91950b2d1..b6b3827d4 100755 --- a/tb/test_axis_register_64.py +++ b/tb/test_axis_register_64.py @@ -26,65 +26,26 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_register_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_register_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_axis_tdata=input_axis_tdata, - input_axis_tkeep=input_axis_tkeep, - input_axis_tvalid=input_axis_tvalid, - input_axis_tready=input_axis_tready, - input_axis_tlast=input_axis_tlast, - input_axis_tuser=input_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) @@ -106,53 +67,63 @@ def bench(): 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_register_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + 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 + ) @always(delay(4)) def clkgen(): @@ -179,16 +150,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -202,16 +171,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -223,7 +190,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -244,9 +211,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -264,8 +229,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -274,15 +239,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -300,8 +261,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -315,15 +276,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -341,8 +298,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -356,15 +313,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -379,16 +332,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -397,7 +348,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_register_64.v b/tb/test_axis_register_64.v index c8ed5222f..069126f4e 100644 --- a/tb/test_axis_register_64.v +++ b/tb/test_axis_register_64.v @@ -24,47 +24,58 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_register_64 + */ module test_axis_register_64; +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] input_axis_tdata = 8'd0; -reg [7:0] input_axis_tkeep = 8'd0; -reg input_axis_tvalid = 1'b0; -reg input_axis_tlast = 1'b0; -reg input_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + output_axis_tready + ); + $to_myhdl( + input_axis_tready, + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_register_64.lxt"); @@ -72,7 +83,8 @@ initial begin end axis_register_64 #( - .DATA_WIDTH(64) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py index b74cfda83..7d2773c27 100755 --- a/tb/test_axis_srl_fifo.py +++ b/tb/test_axis_srl_fifo.py @@ -26,71 +26,32 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_srl_fifo' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) 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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DEPTH = 4 + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -98,7 +59,7 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) @@ -106,51 +67,61 @@ def bench(): 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_srl_fifo(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + 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, - count) + 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 + ) @always(delay(4)) def clkgen(): @@ -177,16 +148,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -200,16 +169,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -221,7 +188,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -242,9 +209,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -262,8 +227,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -272,15 +237,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -298,8 +259,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -313,15 +274,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -339,8 +296,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -354,15 +311,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -377,16 +330,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -400,7 +351,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -411,9 +362,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -426,7 +375,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -444,13 +393,13 @@ def bench(): yield clk.posedge yield clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_srl_fifo.v b/tb/test_axis_srl_fifo.v index efc030088..345859347 100644 --- a/tb/test_axis_srl_fifo.v +++ b/tb/test_axis_srl_fifo.v @@ -24,16 +24,23 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_srl_fifo + */ module test_axis_srl_fifo; +// Parameters +parameter DEPTH = 4; +parameter DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_axis_tdata = 0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -41,7 +48,7 @@ reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [7:0] output_axis_tdata; +wire [DATA_WIDTH-1:0] output_axis_tdata; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; @@ -50,20 +57,24 @@ 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); + $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"); @@ -71,8 +82,8 @@ initial begin end axis_srl_fifo #( - .DEPTH(4), - .DATA_WIDTH(8) + .DEPTH(DEPTH), + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py index 5215823bd..5a44897c6 100755 --- a/tb/test_axis_srl_fifo_64.py +++ b/tb/test_axis_srl_fifo_64.py @@ -26,76 +26,34 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_srl_fifo_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) 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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DEPTH = 4 + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) input_axis_tuser = Signal(bool(0)) @@ -103,8 +61,8 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) output_axis_tuser = Signal(bool(0)) @@ -112,55 +70,65 @@ def bench(): 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_srl_fifo_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + 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, - count) + 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 + ) @always(delay(4)) def clkgen(): @@ -187,16 +155,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -210,16 +176,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -231,7 +195,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -252,9 +216,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -272,8 +234,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -282,15 +244,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -308,8 +266,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -323,15 +281,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -349,8 +303,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -364,15 +318,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -387,16 +337,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -410,7 +358,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -421,9 +369,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -436,7 +382,7 @@ def bench(): test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) sink_pause.next = 1 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield clk.posedge yield clk.posedge @@ -454,13 +400,13 @@ def bench(): yield clk.posedge yield clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_srl_fifo_64.v b/tb/test_axis_srl_fifo_64.v index 8239f55e6..ba83f3ea7 100644 --- a/tb/test_axis_srl_fifo_64.v +++ b/tb/test_axis_srl_fifo_64.v @@ -24,17 +24,25 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_srl_fifo_64 + */ module test_axis_srl_fifo_64; +// Parameters +parameter DEPTH = 4; +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // 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 [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; reg input_axis_tuser = 0; @@ -42,8 +50,8 @@ reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; @@ -52,22 +60,26 @@ 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); + $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"); @@ -75,8 +87,9 @@ initial begin end axis_srl_fifo_64 #( - .DEPTH(4), - .DATA_WIDTH(64) + .DEPTH(DEPTH), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_srl_register.py b/tb/test_axis_srl_register.py index ca08a3ebd..ddd1c455c 100755 --- a/tb/test_axis_srl_register.py +++ b/tb/test_axis_srl_register.py @@ -26,61 +26,25 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_srl_register' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) 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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) @@ -100,49 +64,59 @@ def bench(): 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_srl_register(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + 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 + ) @always(delay(4)) def clkgen(): @@ -169,16 +143,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -192,16 +164,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -213,7 +183,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -234,9 +204,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -254,8 +222,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -264,15 +232,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -290,8 +254,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -305,15 +269,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -331,8 +291,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -346,15 +306,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -369,16 +325,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -387,7 +341,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_srl_register.v b/tb/test_axis_srl_register.v index 38f440735..706a90d29 100644 --- a/tb/test_axis_srl_register.v +++ b/tb/test_axis_srl_register.v @@ -24,43 +24,53 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_srl_register + */ module test_axis_srl_register; +// Parameters +parameter DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] input_axis_tdata = 8'd0; -reg input_axis_tvalid = 1'b0; -reg input_axis_tlast = 1'b0; -reg input_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; +reg [DATA_WIDTH-1: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 [DATA_WIDTH-1: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); + $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"); @@ -68,7 +78,7 @@ initial begin end axis_srl_register #( - .DATA_WIDTH(8) + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_srl_register_64.py b/tb/test_axis_srl_register_64.py index 2e28e566c..0a3d8c24b 100755 --- a/tb/test_axis_srl_register_64.py +++ b/tb/test_axis_srl_register_64.py @@ -26,65 +26,26 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_srl_register_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) 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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) @@ -106,53 +67,63 @@ def bench(): 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_srl_register_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + 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 + ) @always(delay(4)) def clkgen(): @@ -179,16 +150,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -202,16 +171,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -223,7 +190,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -244,9 +211,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -264,8 +229,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -274,15 +239,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -300,8 +261,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -315,15 +276,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -341,8 +298,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while input_axis_tvalid or output_axis_tvalid: @@ -356,15 +313,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -379,16 +332,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -397,7 +348,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_srl_register_64.v b/tb/test_axis_srl_register_64.v index dd703dafd..6e5437084 100644 --- a/tb/test_axis_srl_register_64.v +++ b/tb/test_axis_srl_register_64.v @@ -24,47 +24,58 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_srl_register_64 + */ module test_axis_srl_register_64; +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] input_axis_tdata = 8'd0; -reg [7:0] input_axis_tkeep = 8'd0; -reg input_axis_tvalid = 1'b0; -reg input_axis_tlast = 1'b0; -reg input_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; +reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg output_axis_tready = 0; // Outputs wire input_axis_tready; -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready); - $to_myhdl(input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $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"); @@ -72,7 +83,8 @@ initial begin end axis_srl_register_64 #( - .DATA_WIDTH(64) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index eb61deaee..950eb263f 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -25,87 +25,50 @@ THE SOFTWARE. from myhdl import * import os - -try: - from queue import Queue -except ImportError: - from Queue import Queue import struct import axis_ep module = 'axis_stat_counter' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_stat_counter(clk, - rst, - current_test, - - monitor_axis_tdata, - monitor_axis_tkeep, - monitor_axis_tvalid, - monitor_axis_tready, - monitor_axis_tlast, - monitor_axis_tuser, - - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, - - tag, - trigger, - busy): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - monitor_axis_tdata=monitor_axis_tdata, - monitor_axis_tkeep=monitor_axis_tkeep, - monitor_axis_tvalid=monitor_axis_tvalid, - monitor_axis_tready=monitor_axis_tready, - monitor_axis_tlast=monitor_axis_tlast, - monitor_axis_tuser=monitor_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - tag=tag, - trigger=trigger, - busy=busy) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + TAG_ENABLE = 1 + TAG_WIDTH = 16 + TICK_COUNT_ENABLE = 1 + TICK_COUNT_WIDTH = 32 + BYTE_COUNT_ENABLE = 1 + BYTE_COUNT_WIDTH = 32 + FRAME_COUNT_ENABLE = 1 + FRAME_COUNT_WIDTH = 32 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - monitor_axis_tdata = Signal(intbv(0)[64:]) - monitor_axis_tkeep = Signal(intbv(0)[8:]) + monitor_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + monitor_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) monitor_axis_tvalid = Signal(bool(0)) monitor_axis_tready = Signal(bool(0)) monitor_axis_tlast = Signal(bool(0)) monitor_axis_tuser = Signal(bool(0)) output_axis_tready = Signal(bool(0)) - tag = Signal(intbv(16)[16:]) + tag = Signal(intbv(16)[TAG_WIDTH:]) trigger = Signal(bool(0)) # Outputs @@ -116,69 +79,81 @@ def bench(): busy = Signal(bool(0)) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - monitor_sink_queue = Queue() monitor_sink_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source = axis_ep.AXIStreamSource(clk, - rst, - tdata=monitor_axis_tdata, - tkeep=monitor_axis_tkeep, - tvalid=monitor_axis_tvalid, - tready=monitor_axis_tready, - tlast=monitor_axis_tlast, - tuser=monitor_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') + source = axis_ep.AXIStreamSource() - monitor_sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=monitor_axis_tdata, - tkeep=monitor_axis_tkeep, - tvalid=monitor_axis_tvalid, - tready=monitor_axis_tready, - tlast=monitor_axis_tlast, - tuser=monitor_axis_tuser, - fifo=monitor_sink_queue, - pause=monitor_sink_pause, - name='monitor_sink') + source_logic = source.create_logic( + clk, + rst, + tdata=monitor_axis_tdata, + tkeep=monitor_axis_tkeep, + tvalid=monitor_axis_tvalid, + tready=monitor_axis_tready, + tlast=monitor_axis_tlast, + tuser=monitor_axis_tuser, + 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') + monitor_sink = axis_ep.AXIStreamSink() + + monitor_sink_logic = monitor_sink.create_logic( + clk, + rst, + tdata=monitor_axis_tdata, + tkeep=monitor_axis_tkeep, + tvalid=monitor_axis_tvalid, + tready=monitor_axis_tready, + tlast=monitor_axis_tlast, + tuser=monitor_axis_tuser, + pause=monitor_sink_pause, + name='monitor_sink' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_stat_counter(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - monitor_axis_tdata, - monitor_axis_tkeep, - monitor_axis_tvalid, - monitor_axis_tready, - monitor_axis_tlast, - monitor_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + monitor_axis_tdata=monitor_axis_tdata, + monitor_axis_tkeep=monitor_axis_tkeep, + monitor_axis_tvalid=monitor_axis_tvalid, + monitor_axis_tready=monitor_axis_tready, + monitor_axis_tlast=monitor_axis_tlast, + monitor_axis_tuser=monitor_axis_tuser, - tag, - trigger, - busy) + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tready=output_axis_tready, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + tag=tag, + trigger=trigger, + busy=busy + ) @always(delay(4)) def clkgen(): @@ -223,12 +198,10 @@ def bench(): yield clk.posedge # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 @@ -257,7 +230,7 @@ def bench(): trigger.next = 1 yield clk.posedge trigger.next = 0 - + while trigger or output_axis_tvalid: sink_pause.next = True yield clk.posedge @@ -270,12 +243,10 @@ def bench(): yield clk.posedge # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 @@ -301,7 +272,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while monitor_axis_tvalid: @@ -323,12 +294,10 @@ def bench(): yield clk.posedge # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 @@ -355,7 +324,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge while monitor_axis_tvalid: @@ -377,12 +346,10 @@ def bench(): yield clk.posedge # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 @@ -409,7 +376,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -445,12 +412,10 @@ def bench(): yield clk.posedge # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 @@ -481,8 +446,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while monitor_axis_tvalid: @@ -504,12 +469,10 @@ def bench(): yield clk.posedge # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 @@ -540,8 +503,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while monitor_axis_tvalid: @@ -563,12 +526,10 @@ def bench(): yield clk.posedge # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 @@ -599,8 +560,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while monitor_axis_tvalid: @@ -622,12 +583,10 @@ def bench(): yield clk.posedge # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 @@ -660,7 +619,7 @@ def bench(): bytearray(range(lens[i])))) for f in test_frame: - source_queue.put(f) + source.send(f) yield clk.posedge while monitor_axis_tvalid: @@ -682,12 +641,10 @@ def bench(): yield clk.posedge # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 @@ -720,7 +677,7 @@ def bench(): bytearray(range(lens[i])))) for f in test_frame: - source_queue.put(f) + source.send(f) yield clk.posedge yield delay(200) @@ -751,16 +708,13 @@ def bench(): yield clk.posedge # discard first trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() # check second trigger output - if not sink_queue.empty(): - rx_frame2 = sink_queue.get() + rx_frame2 = sink.recv() rx_frame_values = struct.unpack(">HLLL", bytes(rx_frame.data)) cycles = (stop_time - start_time) / 8 @@ -783,7 +737,7 @@ def bench(): raise StopSimulation - return dut, source, monitor_sink, sink, clkgen, check + return dut, source_logic, monitor_sink_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v index f896b0f9e..d2be74b84 100644 --- a/tb/test_axis_stat_counter.v +++ b/tb/test_axis_stat_counter.v @@ -24,11 +24,14 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_stat_counter + */ module test_axis_stat_counter; -// parameters +// Parameters parameter DATA_WIDTH = 64; parameter KEEP_WIDTH = (DATA_WIDTH/8); parameter TAG_ENABLE = 1; @@ -45,14 +48,14 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] monitor_axis_tdata = 8'd0; -reg [7:0] monitor_axis_tkeep = 8'd0; -reg monitor_axis_tvalid = 1'b0; -reg monitor_axis_tready = 1'b0; -reg monitor_axis_tlast = 1'b0; -reg monitor_axis_tuser = 1'b0; -reg output_axis_tready = 1'b0; -reg [15:0] tag = 0; +reg [DATA_WIDTH-1:0] monitor_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] monitor_axis_tkeep = 0; +reg monitor_axis_tvalid = 0; +reg monitor_axis_tready = 0; +reg monitor_axis_tlast = 0; +reg monitor_axis_tuser = 0; +reg output_axis_tready = 0; +reg [TAG_WIDTH-1:0] tag = 0; reg trigger = 0; // Outputs @@ -64,23 +67,27 @@ wire busy; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - monitor_axis_tdata, - monitor_axis_tkeep, - monitor_axis_tvalid, - monitor_axis_tready, - monitor_axis_tlast, - monitor_axis_tuser, - output_axis_tready, - tag, - trigger); - $to_myhdl(output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, - busy); + $from_myhdl( + clk, + rst, + current_test, + monitor_axis_tdata, + monitor_axis_tkeep, + monitor_axis_tvalid, + monitor_axis_tready, + monitor_axis_tlast, + monitor_axis_tuser, + output_axis_tready, + tag, + trigger + ); + $to_myhdl( + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + busy + ); // dump file $dumpfile("test_axis_stat_counter.lxt"); diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py index 8d2d9dce5..dbd0637ef 100755 --- a/tb/test_axis_switch_4x4.py +++ b/tb/test_axis_switch_4x4.py @@ -26,15 +26,10 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_switch_4x4' -testbench = 'test_axis_switch_4x4' +testbench = 'test_%s' % module srcs = [] @@ -47,117 +42,6 @@ src = ' '.join(srcs) build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) -def dut_axis_switch_4x4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tdest, - input_3_axis_tuser, - - output_0_axis_tdata, - output_0_axis_tvalid, - output_0_axis_tready, - output_0_axis_tlast, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tvalid, - output_1_axis_tready, - output_1_axis_tlast, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tvalid, - output_2_axis_tready, - output_2_axis_tlast, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tvalid, - output_3_axis_tready, - output_3_axis_tlast, - output_3_axis_tdest, - output_3_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tdest=input_0_axis_tdest, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tdest=input_1_axis_tdest, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tdest=input_2_axis_tdest, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tdest=input_3_axis_tdest, - input_3_axis_tuser=input_3_axis_tuser, - - output_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tready=output_0_axis_tready, - output_0_axis_tlast=output_0_axis_tlast, - output_0_axis_tdest=output_0_axis_tdest, - output_0_axis_tuser=output_0_axis_tuser, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tready=output_1_axis_tready, - output_1_axis_tlast=output_1_axis_tlast, - output_1_axis_tdest=output_1_axis_tdest, - output_1_axis_tuser=output_1_axis_tuser, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tready=output_2_axis_tready, - output_2_axis_tlast=output_2_axis_tlast, - output_2_axis_tdest=output_2_axis_tdest, - output_2_axis_tuser=output_2_axis_tuser, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tready=output_3_axis_tready, - output_3_axis_tlast=output_3_axis_tlast, - output_3_axis_tdest=output_3_axis_tdest, - output_3_axis_tuser=output_3_axis_tuser) - def bench(): # Parameters @@ -235,165 +119,195 @@ def bench(): output_3_axis_tuser = Signal(bool(0)) # sources and sinks - source_0_queue = Queue() source_0_pause = Signal(bool(0)) - source_1_queue = Queue() source_1_pause = Signal(bool(0)) - source_2_queue = Queue() source_2_pause = Signal(bool(0)) - source_3_queue = Queue() source_3_pause = Signal(bool(0)) - sink_0_queue = Queue() sink_0_pause = Signal(bool(0)) - sink_1_queue = Queue() sink_1_pause = Signal(bool(0)) - sink_2_queue = Queue() sink_2_pause = Signal(bool(0)) - sink_3_queue = Queue() sink_3_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_0_axis_tdata, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tdest=input_0_axis_tdest, - tuser=input_0_axis_tuser, - fifo=source_0_queue, - pause=source_0_pause, - name='source0') - source_1 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_1_axis_tdata, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tdest=input_1_axis_tdest, - tuser=input_1_axis_tuser, - fifo=source_1_queue, - pause=source_1_pause, - name='source1') - source_2 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_2_axis_tdata, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tdest=input_2_axis_tdest, - tuser=input_2_axis_tuser, - fifo=source_2_queue, - pause=source_2_pause, - name='source2') - source_3 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_3_axis_tdata, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tdest=input_3_axis_tdest, - tuser=input_3_axis_tuser, - fifo=source_3_queue, - pause=source_3_pause, - name='source3') + source_0 = axis_ep.AXIStreamSource() - sink_0 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_0_axis_tdata, - tvalid=output_0_axis_tvalid, - tready=output_0_axis_tready, - tlast=output_0_axis_tlast, - tdest=output_0_axis_tdest, - tuser=output_0_axis_tuser, - fifo=sink_0_queue, - pause=sink_0_pause, - name='sink0') - sink_1 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_1_axis_tdata, - tvalid=output_1_axis_tvalid, - tready=output_1_axis_tready, - tlast=output_1_axis_tlast, - tdest=output_1_axis_tdest, - tuser=output_1_axis_tuser, - fifo=sink_1_queue, - pause=sink_1_pause, - name='sink1') - sink_2 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_2_axis_tdata, - tvalid=output_2_axis_tvalid, - tready=output_2_axis_tready, - tlast=output_2_axis_tlast, - tdest=output_2_axis_tdest, - tuser=output_2_axis_tuser, - fifo=sink_2_queue, - pause=sink_2_pause, - name='sink2') - sink_3 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_3_axis_tdata, - tvalid=output_3_axis_tvalid, - tready=output_3_axis_tready, - tlast=output_3_axis_tlast, - tdest=output_3_axis_tdest, - tuser=output_3_axis_tuser, - fifo=sink_3_queue, - pause=sink_3_pause, - name='sink3') + source_0_logic = source_0.create_logic( + clk, + rst, + tdata=input_0_axis_tdata, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tdest=input_0_axis_tdest, + tuser=input_0_axis_tuser, + pause=source_0_pause, + name='source_0' + ) + + source_1 = axis_ep.AXIStreamSource() + + source_1_logic = source_1.create_logic( + clk, + rst, + tdata=input_1_axis_tdata, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tdest=input_1_axis_tdest, + tuser=input_1_axis_tuser, + pause=source_1_pause, + name='source_1' + ) + + source_2 = axis_ep.AXIStreamSource() + + source_2_logic = source_2.create_logic( + clk, + rst, + tdata=input_2_axis_tdata, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tdest=input_2_axis_tdest, + tuser=input_2_axis_tuser, + pause=source_2_pause, + name='source_2' + ) + + source_3 = axis_ep.AXIStreamSource() + + source_3_logic = source_3.create_logic( + clk, + rst, + tdata=input_3_axis_tdata, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tdest=input_3_axis_tdest, + tuser=input_3_axis_tuser, + pause=source_3_pause, + name='source_3' + ) + + sink_0 = axis_ep.AXIStreamSink() + + sink_0_logic = sink_0.create_logic( + clk, + rst, + tdata=output_0_axis_tdata, + tvalid=output_0_axis_tvalid, + tready=output_0_axis_tready, + tlast=output_0_axis_tlast, + tdest=output_0_axis_tdest, + tuser=output_0_axis_tuser, + pause=sink_0_pause, + name='sink_0' + ) + + sink_1 = axis_ep.AXIStreamSink() + + sink_1_logic = sink_1.create_logic( + clk, + rst, + tdata=output_1_axis_tdata, + tvalid=output_1_axis_tvalid, + tready=output_1_axis_tready, + tlast=output_1_axis_tlast, + tdest=output_1_axis_tdest, + tuser=output_1_axis_tuser, + pause=sink_1_pause, + name='sink_1' + ) + + sink_2 = axis_ep.AXIStreamSink() + + sink_2_logic = sink_2.create_logic( + clk, + rst, + tdata=output_2_axis_tdata, + tvalid=output_2_axis_tvalid, + tready=output_2_axis_tready, + tlast=output_2_axis_tlast, + tdest=output_2_axis_tdest, + tuser=output_2_axis_tuser, + pause=sink_2_pause, + name='sink_2' + ) + + sink_3 = axis_ep.AXIStreamSink() + + sink_3_logic = sink_3.create_logic( + clk, + rst, + tdata=output_3_axis_tdata, + tvalid=output_3_axis_tvalid, + tready=output_3_axis_tready, + tlast=output_3_axis_tlast, + tdest=output_3_axis_tdest, + tuser=output_3_axis_tuser, + pause=sink_3_pause, + name='sink_3' + ) # DUT - dut = dut_axis_switch_4x4(clk, - rst, - current_test, - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tdest, - input_3_axis_tuser, - output_0_axis_tdata, - output_0_axis_tvalid, - output_0_axis_tready, - output_0_axis_tlast, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tvalid, - output_1_axis_tready, - output_1_axis_tlast, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tvalid, - output_2_axis_tready, - output_2_axis_tlast, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tvalid, - output_3_axis_tready, - output_3_axis_tlast, - output_3_axis_tdest, - output_3_axis_tuser) + 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, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tdest=input_0_axis_tdest, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tdest=input_1_axis_tdest, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tdest=input_2_axis_tdest, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tdest=input_3_axis_tdest, + input_3_axis_tuser=input_3_axis_tuser, + + output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tready=output_0_axis_tready, + output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tdest=output_0_axis_tdest, + output_0_axis_tuser=output_0_axis_tuser, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tready=output_1_axis_tready, + output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tdest=output_1_axis_tdest, + output_1_axis_tuser=output_1_axis_tuser, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tready=output_2_axis_tready, + output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tdest=output_2_axis_tdest, + output_2_axis_tuser=output_2_axis_tuser, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tready=output_3_axis_tready, + output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tdest=output_3_axis_tdest, + output_3_axis_tuser=output_3_axis_tuser + ) @always(delay(4)) def clkgen(): @@ -456,10 +370,10 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0_queue.put(test_frame0) - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_0.send(test_frame0) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge yield clk.posedge @@ -467,27 +381,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -503,10 +409,10 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0_queue.put(test_frame0) - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_0.send(test_frame0) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge yield clk.posedge @@ -514,27 +420,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame3 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame2 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame1 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 @@ -550,10 +448,10 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0_queue.put(test_frame0) - source_0_queue.put(test_frame1) - source_0_queue.put(test_frame2) - source_0_queue.put(test_frame3) + source_0.send(test_frame0) + source_0.send(test_frame1) + source_0.send(test_frame2) + source_0.send(test_frame3) yield clk.posedge yield clk.posedge @@ -561,27 +459,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -595,40 +485,32 @@ def bench(): test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - + for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0_queue.put(test_frame0) + source_0.send(test_frame0) yield clk.posedge - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge yield wait() yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_0_queue.empty(): - rx_frame1 = sink_0_queue.get() + rx_frame1 = sink_0.recv() assert rx_frame1 == test_frame1 - rx_frame2 = None - if not sink_0_queue.empty(): - rx_frame2 = sink_0_queue.get() + rx_frame2 = sink_0.recv() assert rx_frame2 == test_frame2 - rx_frame3 = None - if not sink_0_queue.empty(): - rx_frame3 = sink_0_queue.get() + rx_frame3 = sink_0.recv() assert rx_frame3 == test_frame3 @@ -644,10 +526,10 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=5) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0_queue.put(test_frame0) - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_0.send(test_frame0) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge yield clk.posedge @@ -655,15 +537,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 @@ -671,7 +549,7 @@ def bench(): raise StopSimulation - return dut, source_0, source_1, source_2, source_3, sink_0, sink_1, sink_2, sink_3, clkgen, check + return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_switch_4x4.v b/tb/test_axis_switch_4x4.v index 0f3fb62b3..8c1782137 100644 --- a/tb/test_axis_switch_4x4.v +++ b/tb/test_axis_switch_4x4.v @@ -107,57 +107,61 @@ wire output_3_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_0_axis_tdata, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tdest, - input_3_axis_tuser, - output_0_axis_tready, - output_1_axis_tready, - output_2_axis_tready, - output_3_axis_tready); - $to_myhdl(input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_0_axis_tdata, - output_0_axis_tvalid, - output_0_axis_tlast, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tvalid, - output_1_axis_tlast, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tvalid, - output_2_axis_tlast, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tvalid, - output_3_axis_tlast, - output_3_axis_tdest, - output_3_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tdest, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tdest, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tdest, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tdest, + input_3_axis_tuser, + output_0_axis_tready, + output_1_axis_tready, + output_2_axis_tready, + output_3_axis_tready + ); + $to_myhdl( + input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_0_axis_tdata, + output_0_axis_tvalid, + output_0_axis_tlast, + output_0_axis_tdest, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tvalid, + output_1_axis_tlast, + output_1_axis_tdest, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tvalid, + output_2_axis_tlast, + output_2_axis_tdest, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tvalid, + output_3_axis_tlast, + output_3_axis_tdest, + output_3_axis_tuser + ); // dump file $dumpfile("test_axis_switch_4x4.lxt"); diff --git a/tb/test_axis_switch_64_4x4.py b/tb/test_axis_switch_64_4x4.py index bde87e440..4185f122e 100755 --- a/tb/test_axis_switch_64_4x4.py +++ b/tb/test_axis_switch_64_4x4.py @@ -26,15 +26,10 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_switch_64_4x4' -testbench = 'test_axis_switch_64_4x4' +testbench = 'test_%s' % module srcs = [] @@ -47,138 +42,11 @@ src = ' '.join(srcs) build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) -def dut_axis_switch_64_4x4(clk, - rst, - current_test, - - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tdest, - input_3_axis_tuser, - - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tready, - output_0_axis_tlast, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tready, - output_1_axis_tlast, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tready, - output_2_axis_tlast, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tready, - output_3_axis_tlast, - output_3_axis_tdest, - output_3_axis_tuser): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tdest=input_0_axis_tdest, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tdest=input_1_axis_tdest, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tdest=input_2_axis_tdest, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tdest=input_3_axis_tdest, - input_3_axis_tuser=input_3_axis_tuser, - - output_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tkeep=output_0_axis_tkeep, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tready=output_0_axis_tready, - output_0_axis_tlast=output_0_axis_tlast, - output_0_axis_tdest=output_0_axis_tdest, - output_0_axis_tuser=output_0_axis_tuser, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tkeep=output_1_axis_tkeep, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tready=output_1_axis_tready, - output_1_axis_tlast=output_1_axis_tlast, - output_1_axis_tdest=output_1_axis_tdest, - output_1_axis_tuser=output_1_axis_tuser, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tkeep=output_2_axis_tkeep, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tready=output_2_axis_tready, - output_2_axis_tlast=output_2_axis_tlast, - output_2_axis_tdest=output_2_axis_tdest, - output_2_axis_tuser=output_2_axis_tuser, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tkeep=output_3_axis_tkeep, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tready=output_3_axis_tready, - output_3_axis_tlast=output_3_axis_tlast, - output_3_axis_tdest=output_3_axis_tdest, - output_3_axis_tuser=output_3_axis_tuser) - def bench(): # Parameters DATA_WIDTH = 64 - KEEP_WIDTH = int(DATA_WIDTH/8) + KEEP_WIDTH = (DATA_WIDTH/8) DEST_WIDTH = 3 OUT_0_BASE = 0 OUT_0_TOP = 0 @@ -260,181 +128,211 @@ def bench(): output_3_axis_tuser = Signal(bool(0)) # sources and sinks - source_0_queue = Queue() source_0_pause = Signal(bool(0)) - source_1_queue = Queue() source_1_pause = Signal(bool(0)) - source_2_queue = Queue() source_2_pause = Signal(bool(0)) - source_3_queue = Queue() source_3_pause = Signal(bool(0)) - sink_0_queue = Queue() sink_0_pause = Signal(bool(0)) - sink_1_queue = Queue() sink_1_pause = Signal(bool(0)) - sink_2_queue = Queue() sink_2_pause = Signal(bool(0)) - sink_3_queue = Queue() sink_3_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tdest=input_0_axis_tdest, - tuser=input_0_axis_tuser, - fifo=source_0_queue, - pause=source_0_pause, - name='source0') - source_1 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tdest=input_1_axis_tdest, - tuser=input_1_axis_tuser, - fifo=source_1_queue, - pause=source_1_pause, - name='source1') - source_2 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tdest=input_2_axis_tdest, - tuser=input_2_axis_tuser, - fifo=source_2_queue, - pause=source_2_pause, - name='source2') - source_3 = axis_ep.AXIStreamSource(clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tdest=input_3_axis_tdest, - tuser=input_3_axis_tuser, - fifo=source_3_queue, - pause=source_3_pause, - name='source3') + source_0 = axis_ep.AXIStreamSource() - sink_0 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_0_axis_tdata, - tkeep=output_0_axis_tkeep, - tvalid=output_0_axis_tvalid, - tready=output_0_axis_tready, - tlast=output_0_axis_tlast, - tdest=output_0_axis_tdest, - tuser=output_0_axis_tuser, - fifo=sink_0_queue, - pause=sink_0_pause, - name='sink0') - sink_1 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_1_axis_tdata, - tkeep=output_1_axis_tkeep, - tvalid=output_1_axis_tvalid, - tready=output_1_axis_tready, - tlast=output_1_axis_tlast, - tdest=output_1_axis_tdest, - tuser=output_1_axis_tuser, - fifo=sink_1_queue, - pause=sink_1_pause, - name='sink1') - sink_2 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_2_axis_tdata, - tkeep=output_2_axis_tkeep, - tvalid=output_2_axis_tvalid, - tready=output_2_axis_tready, - tlast=output_2_axis_tlast, - tdest=output_2_axis_tdest, - tuser=output_2_axis_tuser, - fifo=sink_2_queue, - pause=sink_2_pause, - name='sink2') - sink_3 = axis_ep.AXIStreamSink(clk, - rst, - tdata=output_3_axis_tdata, - tkeep=output_3_axis_tkeep, - tvalid=output_3_axis_tvalid, - tready=output_3_axis_tready, - tlast=output_3_axis_tlast, - tdest=output_3_axis_tdest, - tuser=output_3_axis_tuser, - fifo=sink_3_queue, - pause=sink_3_pause, - name='sink3') + source_0_logic = source_0.create_logic( + clk, + rst, + tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, + tvalid=input_0_axis_tvalid, + tready=input_0_axis_tready, + tlast=input_0_axis_tlast, + tdest=input_0_axis_tdest, + tuser=input_0_axis_tuser, + pause=source_0_pause, + name='source_0' + ) + + source_1 = axis_ep.AXIStreamSource() + + source_1_logic = source_1.create_logic( + clk, + rst, + tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, + tvalid=input_1_axis_tvalid, + tready=input_1_axis_tready, + tlast=input_1_axis_tlast, + tdest=input_1_axis_tdest, + tuser=input_1_axis_tuser, + pause=source_1_pause, + name='source_1' + ) + + source_2 = axis_ep.AXIStreamSource() + + source_2_logic = source_2.create_logic( + clk, + rst, + tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, + tvalid=input_2_axis_tvalid, + tready=input_2_axis_tready, + tlast=input_2_axis_tlast, + tdest=input_2_axis_tdest, + tuser=input_2_axis_tuser, + pause=source_2_pause, + name='source_2' + ) + + source_3 = axis_ep.AXIStreamSource() + + source_3_logic = source_3.create_logic( + clk, + rst, + tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, + tvalid=input_3_axis_tvalid, + tready=input_3_axis_tready, + tlast=input_3_axis_tlast, + tdest=input_3_axis_tdest, + tuser=input_3_axis_tuser, + pause=source_3_pause, + name='source_3' + ) + + sink_0 = axis_ep.AXIStreamSink() + + sink_0_logic = sink_0.create_logic( + clk, + rst, + tdata=output_0_axis_tdata, + tkeep=output_0_axis_tkeep, + tvalid=output_0_axis_tvalid, + tready=output_0_axis_tready, + tlast=output_0_axis_tlast, + tdest=output_0_axis_tdest, + tuser=output_0_axis_tuser, + pause=sink_0_pause, + name='sink_0' + ) + + sink_1 = axis_ep.AXIStreamSink() + + sink_1_logic = sink_1.create_logic( + clk, + rst, + tdata=output_1_axis_tdata, + tkeep=output_1_axis_tkeep, + tvalid=output_1_axis_tvalid, + tready=output_1_axis_tready, + tlast=output_1_axis_tlast, + tdest=output_1_axis_tdest, + tuser=output_1_axis_tuser, + pause=sink_1_pause, + name='sink_1' + ) + + sink_2 = axis_ep.AXIStreamSink() + + sink_2_logic = sink_2.create_logic( + clk, + rst, + tdata=output_2_axis_tdata, + tkeep=output_2_axis_tkeep, + tvalid=output_2_axis_tvalid, + tready=output_2_axis_tready, + tlast=output_2_axis_tlast, + tdest=output_2_axis_tdest, + tuser=output_2_axis_tuser, + pause=sink_2_pause, + name='sink_2' + ) + + sink_3 = axis_ep.AXIStreamSink() + + sink_3_logic = sink_3.create_logic( + clk, + rst, + tdata=output_3_axis_tdata, + tkeep=output_3_axis_tkeep, + tvalid=output_3_axis_tvalid, + tready=output_3_axis_tready, + tlast=output_3_axis_tlast, + tdest=output_3_axis_tdest, + tuser=output_3_axis_tuser, + pause=sink_3_pause, + name='sink_3' + ) # DUT - dut = dut_axis_switch_64_4x4(clk, - rst, - current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tready, - input_0_axis_tlast, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tready, - input_1_axis_tlast, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tready, - input_2_axis_tlast, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tready, - input_3_axis_tlast, - input_3_axis_tdest, - input_3_axis_tuser, - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tready, - output_0_axis_tlast, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tready, - output_1_axis_tlast, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tready, - output_2_axis_tlast, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tready, - output_3_axis_tlast, - output_3_axis_tdest, - output_3_axis_tuser) + 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, + + input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, + input_0_axis_tvalid=input_0_axis_tvalid, + input_0_axis_tready=input_0_axis_tready, + input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tdest=input_0_axis_tdest, + input_0_axis_tuser=input_0_axis_tuser, + input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, + input_1_axis_tvalid=input_1_axis_tvalid, + input_1_axis_tready=input_1_axis_tready, + input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tdest=input_1_axis_tdest, + input_1_axis_tuser=input_1_axis_tuser, + input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, + input_2_axis_tvalid=input_2_axis_tvalid, + input_2_axis_tready=input_2_axis_tready, + input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tdest=input_2_axis_tdest, + input_2_axis_tuser=input_2_axis_tuser, + input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, + input_3_axis_tvalid=input_3_axis_tvalid, + input_3_axis_tready=input_3_axis_tready, + input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tdest=input_3_axis_tdest, + input_3_axis_tuser=input_3_axis_tuser, + + output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tkeep=output_0_axis_tkeep, + output_0_axis_tvalid=output_0_axis_tvalid, + output_0_axis_tready=output_0_axis_tready, + output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tdest=output_0_axis_tdest, + output_0_axis_tuser=output_0_axis_tuser, + output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tkeep=output_1_axis_tkeep, + output_1_axis_tvalid=output_1_axis_tvalid, + output_1_axis_tready=output_1_axis_tready, + output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tdest=output_1_axis_tdest, + output_1_axis_tuser=output_1_axis_tuser, + output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tkeep=output_2_axis_tkeep, + output_2_axis_tvalid=output_2_axis_tvalid, + output_2_axis_tready=output_2_axis_tready, + output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tdest=output_2_axis_tdest, + output_2_axis_tuser=output_2_axis_tuser, + output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tkeep=output_3_axis_tkeep, + output_3_axis_tvalid=output_3_axis_tvalid, + output_3_axis_tready=output_3_axis_tready, + output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tdest=output_3_axis_tdest, + output_3_axis_tuser=output_3_axis_tuser + ) @always(delay(4)) def clkgen(): @@ -497,10 +395,10 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0_queue.put(test_frame0) - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_0.send(test_frame0) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge yield clk.posedge @@ -508,27 +406,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -544,10 +434,10 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0_queue.put(test_frame0) - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_0.send(test_frame0) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge yield clk.posedge @@ -555,27 +445,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame3 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame2 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame1 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 @@ -591,10 +473,10 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0_queue.put(test_frame0) - source_0_queue.put(test_frame1) - source_0_queue.put(test_frame2) - source_0_queue.put(test_frame3) + source_0.send(test_frame0) + source_0.send(test_frame1) + source_0.send(test_frame2) + source_0.send(test_frame3) yield clk.posedge yield clk.posedge @@ -602,27 +484,19 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 - rx_frame2 = None - if not sink_2_queue.empty(): - rx_frame2 = sink_2_queue.get() + rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 - rx_frame3 = None - if not sink_3_queue.empty(): - rx_frame3 = sink_3_queue.get() + rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -636,40 +510,32 @@ def bench(): test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - + for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0_queue.put(test_frame0) + source_0.send(test_frame0) yield clk.posedge - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge yield wait() yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_0_queue.empty(): - rx_frame1 = sink_0_queue.get() + rx_frame1 = sink_0.recv() assert rx_frame1 == test_frame1 - rx_frame2 = None - if not sink_0_queue.empty(): - rx_frame2 = sink_0_queue.get() + rx_frame2 = sink_0.recv() assert rx_frame2 == test_frame2 - rx_frame3 = None - if not sink_0_queue.empty(): - rx_frame3 = sink_0_queue.get() + rx_frame3 = sink_0.recv() assert rx_frame3 == test_frame3 @@ -685,10 +551,10 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=5) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0_queue.put(test_frame0) - source_1_queue.put(test_frame1) - source_2_queue.put(test_frame2) - source_3_queue.put(test_frame3) + source_0.send(test_frame0) + source_1.send(test_frame1) + source_2.send(test_frame2) + source_3.send(test_frame3) yield clk.posedge yield clk.posedge @@ -696,15 +562,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame0 = None - if not sink_0_queue.empty(): - rx_frame0 = sink_0_queue.get() + rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 - rx_frame1 = None - if not sink_1_queue.empty(): - rx_frame1 = sink_1_queue.get() + rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 @@ -712,7 +574,7 @@ def bench(): raise StopSimulation - return dut, source_0, source_1, source_2, source_3, sink_0, sink_1, sink_2, sink_3, clkgen, check + return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_switch_64_4x4.v b/tb/test_axis_switch_64_4x4.v index e5f939f89..989ef788a 100644 --- a/tb/test_axis_switch_64_4x4.v +++ b/tb/test_axis_switch_64_4x4.v @@ -116,65 +116,69 @@ wire output_3_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tdest, - input_3_axis_tuser, - output_0_axis_tready, - output_1_axis_tready, - output_2_axis_tready, - output_3_axis_tready); - $to_myhdl(input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast, - output_3_axis_tdest, - output_3_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + input_0_axis_tdata, + input_0_axis_tkeep, + input_0_axis_tvalid, + input_0_axis_tlast, + input_0_axis_tdest, + input_0_axis_tuser, + input_1_axis_tdata, + input_1_axis_tkeep, + input_1_axis_tvalid, + input_1_axis_tlast, + input_1_axis_tdest, + input_1_axis_tuser, + input_2_axis_tdata, + input_2_axis_tkeep, + input_2_axis_tvalid, + input_2_axis_tlast, + input_2_axis_tdest, + input_2_axis_tuser, + input_3_axis_tdata, + input_3_axis_tkeep, + input_3_axis_tvalid, + input_3_axis_tlast, + input_3_axis_tdest, + input_3_axis_tuser, + output_0_axis_tready, + output_1_axis_tready, + output_2_axis_tready, + output_3_axis_tready + ); + $to_myhdl( + input_0_axis_tready, + input_1_axis_tready, + input_2_axis_tready, + input_3_axis_tready, + output_0_axis_tdata, + output_0_axis_tkeep, + output_0_axis_tvalid, + output_0_axis_tlast, + output_0_axis_tdest, + output_0_axis_tuser, + output_1_axis_tdata, + output_1_axis_tkeep, + output_1_axis_tvalid, + output_1_axis_tlast, + output_1_axis_tdest, + output_1_axis_tuser, + output_2_axis_tdata, + output_2_axis_tkeep, + output_2_axis_tvalid, + output_2_axis_tlast, + output_2_axis_tdest, + output_2_axis_tuser, + output_3_axis_tdata, + output_3_axis_tkeep, + output_3_axis_tvalid, + output_3_axis_tlast, + output_3_axis_tdest, + output_3_axis_tuser + ); // dump file $dumpfile("test_axis_switch_64_4x4.lxt"); diff --git a/tb/test_axis_tap.py b/tb/test_axis_tap.py index 3f4f44d28..cab8d680c 100755 --- a/tb/test_axis_tap.py +++ b/tb/test_axis_tap.py @@ -26,62 +26,31 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_tap' +testbench = 'test_%s' % module + srcs = [] + srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) + src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) -def dut_axis_tap(clk, - rst, - current_test, - tap_axis_tdata, - tap_axis_tvalid, - tap_axis_tready, - tap_axis_tlast, - tap_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, - - tap_axis_tdata=tap_axis_tdata, - tap_axis_tvalid=tap_axis_tvalid, - tap_axis_tready=tap_axis_tready, - tap_axis_tlast=tap_axis_tlast, - tap_axis_tuser=tap_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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - tap_axis_tdata = Signal(intbv(0)[8:]) + tap_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) tap_axis_tvalid = Signal(bool(0)) tap_axis_tready = Signal(bool(1)) tap_axis_tlast = Signal(bool(0)) @@ -89,55 +58,65 @@ def bench(): output_axis_tready = Signal(bool(0)) # Outputs - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) 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=tap_axis_tdata, - tvalid=tap_axis_tvalid, - tready=tap_axis_tready, - tlast=tap_axis_tlast, - tuser=tap_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=tap_axis_tdata, + tvalid=tap_axis_tvalid, + tready=tap_axis_tready, + tlast=tap_axis_tlast, + tuser=tap_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_tap(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - tap_axis_tdata, - tap_axis_tvalid, - tap_axis_tready, - tap_axis_tlast, - tap_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + tap_axis_tdata=tap_axis_tdata, + tap_axis_tvalid=tap_axis_tvalid, + tap_axis_tready=tap_axis_tready, + tap_axis_tlast=tap_axis_tlast, + tap_axis_tuser=tap_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 + ) @always(delay(4)) def clkgen(): @@ -164,16 +143,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -187,16 +164,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -210,7 +185,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -224,9 +199,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -240,7 +213,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -254,9 +227,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.user[-1] @@ -274,8 +245,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -284,15 +255,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -310,8 +277,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while tap_axis_tvalid or output_axis_tvalid: @@ -325,15 +292,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -351,8 +314,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while tap_axis_tvalid or output_axis_tvalid: @@ -366,15 +329,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.user[-1] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.user[-1] @@ -389,16 +348,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -407,7 +364,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_tap.v b/tb/test_axis_tap.v index 412b1d939..532fafefc 100644 --- a/tb/test_axis_tap.v +++ b/tb/test_axis_tap.v @@ -24,16 +24,22 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_tap + */ module test_axis_tap; +// Parameters +parameter DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] tap_axis_tdata = 0; +reg [DATA_WIDTH-1:0] tap_axis_tdata = 0; reg tap_axis_tvalid = 0; reg tap_axis_tready = 0; reg tap_axis_tlast = 0; @@ -41,26 +47,30 @@ reg tap_axis_tuser = 0; reg output_axis_tready = 0; // Outputs -wire [7:0] output_axis_tdata; +wire [DATA_WIDTH-1: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, - tap_axis_tdata, - tap_axis_tvalid, - tap_axis_tready, - tap_axis_tlast, - tap_axis_tuser, - output_axis_tready); - $to_myhdl(output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + tap_axis_tdata, + tap_axis_tvalid, + tap_axis_tready, + tap_axis_tlast, + tap_axis_tuser, + output_axis_tready + ); + $to_myhdl( + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_tap.lxt"); @@ -68,7 +78,7 @@ initial begin end axis_tap #( - .DATA_WIDTH(8) + .DATA_WIDTH(DATA_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_axis_tap_64.py b/tb/test_axis_tap_64.py index 153c5063a..f05002a1c 100755 --- a/tb/test_axis_tap_64.py +++ b/tb/test_axis_tap_64.py @@ -26,67 +26,33 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep module = 'axis_tap_64' +testbench = 'test_%s' % module + srcs = [] + srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) + src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) -def dut_axis_tap_64(clk, - rst, - current_test, - tap_axis_tdata, - tap_axis_tkeep, - tap_axis_tvalid, - tap_axis_tready, - tap_axis_tlast, - tap_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, - - tap_axis_tdata=tap_axis_tdata, - tap_axis_tkeep=tap_axis_tkeep, - tap_axis_tvalid=tap_axis_tvalid, - tap_axis_tready=tap_axis_tready, - tap_axis_tlast=tap_axis_tlast, - tap_axis_tuser=tap_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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - tap_axis_tdata = Signal(intbv(0)[64:]) - tap_axis_tkeep = Signal(intbv(0)[8:]) + tap_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + tap_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tap_axis_tvalid = Signal(bool(0)) tap_axis_tready = Signal(bool(1)) tap_axis_tlast = Signal(bool(0)) @@ -94,60 +60,70 @@ def bench(): output_axis_tready = Signal(bool(0)) # Outputs - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) 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=tap_axis_tdata, - tkeep=tap_axis_tkeep, - tvalid=tap_axis_tvalid, - tready=tap_axis_tready, - tlast=tap_axis_tlast, - tuser=tap_axis_tuser, - fifo=source_queue, - pause=source_pause, - name='source') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=tap_axis_tdata, + tkeep=tap_axis_tkeep, + tvalid=tap_axis_tvalid, + tready=tap_axis_tready, + tlast=tap_axis_tlast, + tuser=tap_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + 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, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_tap_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - tap_axis_tdata, - tap_axis_tkeep, - tap_axis_tvalid, - tap_axis_tready, - tap_axis_tlast, - tap_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser) + tap_axis_tdata=tap_axis_tdata, + tap_axis_tkeep=tap_axis_tkeep, + tap_axis_tvalid=tap_axis_tvalid, + tap_axis_tready=tap_axis_tready, + tap_axis_tlast=tap_axis_tlast, + tap_axis_tuser=tap_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 + ) @always(delay(4)) def clkgen(): @@ -174,16 +150,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -197,16 +171,14 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -220,7 +192,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -234,9 +206,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -250,7 +220,7 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -264,9 +234,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.user[-1] @@ -284,8 +252,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_axis_tlast.posedge @@ -294,15 +262,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -320,8 +284,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while tap_axis_tvalid or output_axis_tvalid: @@ -335,15 +299,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -361,8 +321,8 @@ def bench(): b'\x5A\x51\x52\x53\x54\x55' + b'\x80\x00' + bytearray(range(256))) - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge while tap_axis_tvalid or output_axis_tvalid: @@ -376,15 +336,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.user[-1] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.user[-1] @@ -399,16 +355,14 @@ def bench(): b'\x80\x00' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') test_frame.user = 1 - source_queue.put(test_frame) + source.send(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() + rx_frame = sink.recv() assert rx_frame == test_frame assert rx_frame.user[-1] @@ -417,7 +371,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_tap_64.v b/tb/test_axis_tap_64.v index 435997b61..c40834e10 100644 --- a/tb/test_axis_tap_64.v +++ b/tb/test_axis_tap_64.v @@ -24,17 +24,24 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for axis_tap_64 + */ module test_axis_tap_64; +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] tap_axis_tdata = 0; -reg [7:0] tap_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] tap_axis_tdata = 0; +reg [DATA_WIDTH-1:0] tap_axis_tkeep = 0; reg tap_axis_tvalid = 0; reg tap_axis_tready = 0; reg tap_axis_tlast = 0; @@ -42,29 +49,33 @@ reg tap_axis_tuser = 0; reg output_axis_tready = 0; // Outputs -wire [63:0] output_axis_tdata; -wire [7:0] output_axis_tkeep; +wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [DATA_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; wire output_axis_tuser; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - tap_axis_tdata, - tap_axis_tkeep, - tap_axis_tvalid, - tap_axis_tready, - tap_axis_tlast, - tap_axis_tuser, - output_axis_tready); - $to_myhdl(output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser); + $from_myhdl( + clk, + rst, + current_test, + tap_axis_tdata, + tap_axis_tkeep, + tap_axis_tvalid, + tap_axis_tready, + tap_axis_tlast, + tap_axis_tuser, + output_axis_tready + ); + $to_myhdl( + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser + ); // dump file $dumpfile("test_axis_tap_64.lxt"); @@ -72,8 +83,8 @@ initial begin end axis_tap_64 #( - .DATA_WIDTH(64), - .KEEP_WIDTH(8) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH) ) UUT ( .clk(clk), diff --git a/tb/test_ll_axis_bridge.py b/tb/test_ll_axis_bridge.py index 763fbe07d..c2099b79c 100755 --- a/tb/test_ll_axis_bridge.py +++ b/tb/test_ll_axis_bridge.py @@ -26,118 +26,95 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep import ll_ep module = 'll_axis_bridge' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) 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) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - ll_data_in = Signal(intbv(0)[8:]) + ll_data_in = Signal(intbv(0)[DATA_WIDTH:]) 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) 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') + source = ll_ep.LocalLinkSource() - 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') + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=axis_tdata, + tvalid=axis_tvalid, + tready=axis_tready, + tlast=axis_tlast, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_ll_axis_bridge(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - ll_data_in, - ll_sof_in_n, - ll_eof_in_n, - ll_src_rdy_in_n, - ll_dst_rdy_out_n, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - axis_tdata, - axis_tvalid, - axis_tready, - axis_tlast) + 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 + ) @always(delay(4)) def clkgen(): @@ -160,24 +137,21 @@ def bench(): 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')) + test_frame = 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') + + source.send(test_frame) 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() + rx_frame = sink.recv() - 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') + assert bytearray(rx_frame) == test_frame yield delay(100) @@ -185,10 +159,12 @@ def bench(): 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')) + test_frame = 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') + + source.send(test_frame) yield clk.posedge yield delay(64) @@ -209,20 +185,15 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() - 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') + assert bytearray(rx_frame) == test_frame yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_ll_axis_bridge.v b/tb/test_ll_axis_bridge.v index 8ba505b2b..9e95975dd 100644 --- a/tb/test_ll_axis_bridge.v +++ b/tb/test_ll_axis_bridge.v @@ -24,16 +24,22 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for ll_axis_bridge + */ module test_ll_axis_bridge; +// Parameters +parameter DATA_WIDTH = 8; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] ll_data_in = 0; +reg [DATA_WIDTH-1:0] ll_data_in = 0; reg ll_sof_in_n = 1; reg ll_eof_in_n = 1; reg ll_src_rdy_in_n = 1; @@ -41,31 +47,37 @@ reg axis_tready = 0; // Outputs wire ll_dst_rdy_out_n; -wire [7:0] axis_tdata; +wire [DATA_WIDTH-1: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); + $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 +ll_axis_bridge #( + .DATA_WIDTH(DATA_WIDTH) +) UUT ( .clk(clk), .rst(rst), diff --git a/tb/test_priority_encoder.py b/tb/test_priority_encoder.py index 082834b2e..db686642f 100755 --- a/tb/test_priority_encoder.py +++ b/tb/test_priority_encoder.py @@ -27,63 +27,50 @@ from myhdl import * import os module = 'priority_encoder' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_priority_encoder(clk, - rst, - current_test, - - input_unencoded, - - output_valid, - output_encoded, - output_unencoded): - - 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_unencoded=input_unencoded, - - output_valid=output_valid, - output_encoded=output_encoded, - output_unencoded=output_unencoded) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + WIDTH = 32 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_unencoded = Signal(intbv(0)[32:]) + input_unencoded = Signal(intbv(0)[WIDTH:]) # Outputs output_valid = Signal(bool(0)) output_encoded = Signal(intbv(0)[5:]) - output_unencoded = Signal(intbv(0)[32:]) + output_unencoded = Signal(intbv(0)[WIDTH:]) # DUT - dut = dut_priority_encoder(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_unencoded, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_valid, - output_encoded, - output_unencoded) + input_unencoded=input_unencoded, + + output_valid=output_valid, + output_encoded=output_encoded, + output_unencoded=output_unencoded + ) @always(delay(4)) def clkgen(): @@ -119,7 +106,7 @@ def bench(): print("test 2: two bits") current_test.next = 2 - + for i in range(32): for j in range(32): diff --git a/tb/test_priority_encoder.v b/tb/test_priority_encoder.v index a88e74236..8d6787e8a 100644 --- a/tb/test_priority_encoder.v +++ b/tb/test_priority_encoder.v @@ -24,11 +24,14 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for priority_encoder + */ module test_priority_encoder; -// parameters +// Parameters localparam WIDTH = 32; // Inputs @@ -45,13 +48,17 @@ wire [WIDTH-1:0] output_unencoded; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_unencoded); - $to_myhdl(output_valid, - output_encoded, - output_unencoded); + $from_myhdl( + clk, + rst, + current_test, + input_unencoded + ); + $to_myhdl( + output_valid, + output_encoded, + output_unencoded + ); // dump file $dumpfile("test_priority_encoder.lxt"); From 88150c9d5f34b0b3141d254bcef9cc5847360800 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 13 Sep 2016 15:24:02 -0700 Subject: [PATCH 311/617] Update and rework endpoints, update testbenches --- example/ATLYS/fpga/tb/test_fpga_core.py | 164 +-- example/ATLYS/fpga/tb/test_fpga_core.v | 46 +- example/DE5-Net/fpga/tb/test_fpga_core.py | 224 +--- example/DE5-Net/fpga/tb/test_fpga_core.v | 58 +- example/HXT100G/fpga/tb/test_fpga_core.py | 974 ++++------------ example/HXT100G/fpga/tb/test_fpga_core.v | 244 ++-- example/NexysVideo/fpga/tb/test_fpga_core.py | 164 +-- example/NexysVideo/fpga/tb/test_fpga_core.v | 48 +- example/VCU108/fpga_10g/tb/test_fpga_core.py | 350 ++---- example/VCU108/fpga_10g/tb/test_fpga_core.v | 84 +- example/VCU108/fpga_1g/tb/test_fpga_core.py | 176 +-- example/VCU108/fpga_1g/tb/test_fpga_core.v | 52 +- tb/arp_ep.py | 275 +++-- tb/eth_ep.py | 299 ++--- tb/gmii_ep.py | 212 ++-- tb/ip_ep.py | 342 +++--- tb/ll_ep.py | 123 -- tb/rgmii_ep.py | 111 +- tb/test_arp.py | 251 ++--- tb/test_arp.v | 75 +- tb/test_arp_64.py | 263 ++--- tb/test_arp_64.v | 79 +- tb/test_arp_cache.py | 78 +- tb/test_arp_cache.v | 37 +- tb/test_arp_eth_rx.py | 287 ++--- tb/test_arp_eth_rx.v | 69 +- tb/test_arp_eth_rx_64.py | 293 ++--- tb/test_arp_eth_rx_64.v | 71 +- tb/test_arp_eth_tx.py | 242 ++-- tb/test_arp_eth_tx.v | 61 +- tb/test_arp_eth_tx_64.py | 248 ++--- tb/test_arp_eth_tx_64.v | 63 +- tb/test_axis_eth_fcs.py | 93 +- tb/test_axis_eth_fcs.v | 24 +- tb/test_axis_eth_fcs_64.py | 99 +- tb/test_axis_eth_fcs_64.v | 26 +- tb/test_axis_eth_fcs_check.py | 195 ++-- tb/test_axis_eth_fcs_check.v | 34 +- tb/test_axis_eth_fcs_check_64.py | 207 ++-- tb/test_axis_eth_fcs_check_64.v | 38 +- tb/test_axis_eth_fcs_insert.py | 177 ++- tb/test_axis_eth_fcs_insert.v | 32 +- tb/test_axis_eth_fcs_insert_64.py | 189 ++-- tb/test_axis_eth_fcs_insert_64.v | 36 +- tb/test_axis_eth_fcs_insert_64_pad.py | 189 ++-- tb/test_axis_eth_fcs_insert_64_pad.v | 36 +- tb/test_axis_eth_fcs_insert_pad.py | 177 ++- tb/test_axis_eth_fcs_insert_pad.v | 32 +- tb/test_eth_arb_mux_4.py | 507 ++++----- tb/test_eth_arb_mux_4.v | 115 +- tb/test_eth_arb_mux_64_4.py | 537 ++++----- tb/test_eth_arb_mux_64_4.v | 125 ++- tb/test_eth_axis_rx.py | 213 ++-- tb/test_eth_axis_rx.v | 49 +- tb/test_eth_axis_rx_64.py | 225 ++-- tb/test_eth_axis_rx_64.v | 53 +- tb/test_eth_axis_tx.py | 199 ++-- tb/test_eth_axis_tx.v | 47 +- tb/test_eth_axis_tx_64.py | 211 ++-- tb/test_eth_axis_tx_64.v | 51 +- tb/test_eth_demux_4.py | 481 +++----- tb/test_eth_demux_4.v | 119 +- tb/test_eth_demux_64_4.py | 511 ++++----- tb/test_eth_demux_64_4.v | 129 ++- tb/test_eth_mac_10g.py | 233 ++-- tb/test_eth_mac_10g.v | 54 +- tb/test_eth_mac_10g_fifo.py | 271 ++--- tb/test_eth_mac_10g_fifo.v | 72 +- tb/test_eth_mac_10g_rx.py | 182 ++- tb/test_eth_mac_10g_rx.v | 28 +- tb/test_eth_mac_10g_tx.py | 161 +-- tb/test_eth_mac_10g_tx.v | 28 +- tb/test_eth_mac_1g.py | 231 ++-- tb/test_eth_mac_1g.v | 54 +- tb/test_eth_mac_1g_fifo.py | 271 ++--- tb/test_eth_mac_1g_fifo.v | 72 +- tb/test_eth_mac_1g_rx.py | 178 ++- tb/test_eth_mac_1g_rx.v | 28 +- tb/test_eth_mac_1g_tx.py | 155 +-- tb/test_eth_mac_1g_tx.v | 28 +- tb/test_eth_mux_4.py | 479 +++----- tb/test_eth_mux_4.v | 119 +- tb/test_eth_mux_64_4.py | 509 +++------ tb/test_eth_mux_64_4.v | 129 ++- tb/test_ip.py | 545 ++++----- tb/test_ip.v | 159 +-- tb/test_ip_64.py | 569 ++++------ tb/test_ip_64.v | 168 +-- tb/test_ip_arb_mux_4.py | 897 ++++++--------- tb/test_ip_arb_mux_4.v | 245 ++-- tb/test_ip_arb_mux_64_4.py | 927 ++++++---------- tb/test_ip_arb_mux_64_4.v | 255 ++--- tb/test_ip_complete.py | 543 ++++----- tb/test_ip_complete.v | 155 +-- tb/test_ip_complete_64.py | 567 ++++------ tb/test_ip_complete_64.v | 163 +-- tb/test_ip_demux_4.py | 871 +++++---------- tb/test_ip_demux_4.v | 249 +++-- tb/test_ip_demux_64_4.py | 901 ++++++--------- tb/test_ip_demux_64_4.v | 259 ++--- tb/test_ip_eth_rx.py | 437 +++----- tb/test_ip_eth_rx.v | 91 +- tb/test_ip_eth_rx_64.py | 449 +++----- tb/test_ip_eth_rx_64.v | 95 +- tb/test_ip_eth_tx.py | 377 +++---- tb/test_ip_eth_tx.v | 79 +- tb/test_ip_eth_tx_64.py | 389 +++---- tb/test_ip_eth_tx_64.v | 83 +- tb/test_ip_mux_4.py | 869 +++++---------- tb/test_ip_mux_4.v | 249 +++-- tb/test_ip_mux_64_4.py | 899 ++++++--------- tb/test_ip_mux_64_4.v | 259 ++--- tb/test_udp.py | 737 +++++------- tb/test_udp.v | 221 ++-- tb/test_udp_64.py | 761 +++++-------- tb/test_udp_64.v | 229 ++-- tb/test_udp_arb_mux_4.py | 1019 ++++++----------- tb/test_udp_arb_mux_4.v | 285 ++--- tb/test_udp_arb_mux_64_4.py | 1049 ++++++------------ tb/test_udp_arb_mux_64_4.v | 295 ++--- tb/test_udp_complete.py | 881 ++++++--------- tb/test_udp_complete.v | 251 +++-- tb/test_udp_complete_64.py | 917 ++++++--------- tb/test_udp_complete_64.v | 263 ++--- tb/test_udp_demux_4.py | 991 ++++++----------- tb/test_udp_demux_4.v | 289 ++--- tb/test_udp_demux_64_4.py | 1021 ++++++----------- tb/test_udp_demux_64_4.v | 299 ++--- tb/test_udp_ip_rx.py | 511 +++------ tb/test_udp_ip_rx.v | 121 +- tb/test_udp_ip_rx_64.py | 523 +++------ tb/test_udp_ip_rx_64.v | 125 ++- tb/test_udp_ip_tx.py | 491 +++----- tb/test_udp_ip_tx.v | 117 +- tb/test_udp_ip_tx_64.py | 503 +++------ tb/test_udp_ip_tx_64.v | 121 +- tb/test_udp_mux_4.py | 989 ++++++----------- tb/test_udp_mux_4.v | 289 ++--- tb/test_udp_mux_64_4.py | 1019 ++++++----------- tb/test_udp_mux_64_4.v | 298 ++--- tb/udp_ep.py | 451 ++++---- tb/xgmii_ep.py | 341 +++--- 142 files changed, 16416 insertions(+), 25241 deletions(-) delete mode 100644 tb/ll_ep.py diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index 0f03d4a84..73450705f 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -26,17 +26,13 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import eth_ep import arp_ep import udp_ep import gmii_ep module = 'fpga_core' +testbench = 'test_%s' % module srcs = [] @@ -69,64 +65,11 @@ srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_fpga_core(clk, - rst, - - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - led, - - phy_rx_clk, - phy_rxd, - phy_rx_dv, - phy_rx_er, - phy_gtx_clk, - phy_txd, - phy_tx_en, - phy_tx_er, - phy_reset_n, - - uart_rxd, - uart_txd): - - 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, - - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - - phy_rx_clk=phy_rx_clk, - phy_rxd=phy_rxd, - phy_rx_dv=phy_rx_dv, - phy_rx_er=phy_rx_er, - phy_gtx_clk=phy_gtx_clk, - phy_txd=phy_txd, - phy_tx_en=phy_tx_en, - phy_tx_er=phy_tx_er, - phy_reset_n=phy_reset_n, - - uart_rxd=uart_rxd, - uart_txd=uart_txd) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -160,50 +103,59 @@ def bench(): uart_txd = Signal(bool(0)) # sources and sinks - gmii_source_queue = Queue() - gmii_sink_queue = Queue() + gmii_source = gmii_ep.GMIISource() - gmii_source = gmii_ep.GMIISource(phy_rx_clk, - rst, - txd=phy_rxd, - tx_en=phy_rx_dv, - tx_er=phy_rx_er, - fifo=gmii_source_queue, - name='gmii_source') + gmii_source_logic = gmii_source.create_logic( + phy_rx_clk, + rst, + txd=phy_rxd, + tx_en=phy_rx_dv, + tx_er=phy_rx_er, + name='gmii_source' + ) - gmii_sink = gmii_ep.GMIISink(phy_gtx_clk, - rst, - rxd=phy_txd, - rx_dv=phy_tx_en, - rx_er=phy_tx_er, - fifo=gmii_sink_queue, - name='gmii_sink') + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + phy_gtx_clk, + rst, + rxd=phy_txd, + rx_dv=phy_tx_en, + rx_er=phy_tx_er, + name='gmii_sink' + ) # DUT - dut = dut_fpga_core(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - led, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - phy_rx_clk, - phy_rxd, - phy_rx_dv, - phy_rx_er, - phy_gtx_clk, - phy_txd, - phy_tx_en, - phy_tx_er, - phy_reset_n, + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, - uart_rxd, - uart_txd) + phy_rx_clk=phy_rx_clk, + phy_rxd=phy_rxd, + phy_rx_dv=phy_rx_dv, + phy_rx_er=phy_rx_er, + phy_gtx_clk=phy_gtx_clk, + phy_txd=phy_txd, + phy_tx_en=phy_tx_en, + phy_tx_er=phy_tx_er, + phy_reset_n=phy_reset_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd + ) @always(delay(4)) def clkgen(): @@ -249,13 +201,13 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) # wait for ARP request packet - while gmii_sink_queue.empty(): + while gmii_sink.empty(): yield clk.posedge - rx_frame = gmii_sink_queue.get(False) + rx_frame = gmii_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = arp_ep.ARPFrame() @@ -291,12 +243,12 @@ def bench(): arp_frame.arp_tha = 0x020000000000 arp_frame.arp_tpa = 0xc0a80180 - gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) - while gmii_sink_queue.empty(): + while gmii_sink.empty(): yield clk.posedge - rx_frame = gmii_sink_queue.get(False) + rx_frame = gmii_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = udp_ep.UDPFrame() @@ -322,14 +274,14 @@ def bench(): assert check_frame.udp_dest_port == 5678 assert check_frame.payload.data == bytearray(range(32)) - assert gmii_source_queue.empty() - assert gmii_sink_queue.empty() + assert gmii_source.empty() + assert gmii_sink.empty() yield delay(100) raise StopSimulation - return dut, gmii_source, gmii_sink, clkgen, check + return dut, gmii_source_logic, gmii_sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/example/ATLYS/fpga/tb/test_fpga_core.v b/example/ATLYS/fpga/tb/test_fpga_core.v index 8a2de45d1..eaf111369 100644 --- a/example/ATLYS/fpga/tb/test_fpga_core.v +++ b/example/ATLYS/fpga/tb/test_fpga_core.v @@ -62,27 +62,31 @@ wire uart_txd; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - phy_rx_clk, - phy_rxd, - phy_rx_dv, - phy_rx_er, - uart_rxd); - $to_myhdl(led, - phy_gtx_clk, - phy_txd, - phy_tx_en, - phy_tx_er, - phy_reset_n, - uart_txd); + $from_myhdl( + clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_rx_clk, + phy_rxd, + phy_rx_dv, + phy_rx_er, + uart_rxd + ); + $to_myhdl( + led, + phy_gtx_clk, + phy_txd, + phy_tx_en, + phy_tx_er, + phy_reset_n, + uart_txd + ); // dump file $dumpfile("test_fpga_core.lxt"); diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index 2d95e580e..08f469940 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -26,17 +26,13 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import eth_ep import arp_ep import udp_ep import xgmii_ep module = 'fpga_core' +testbench = 'test_%s' % module srcs = [] @@ -68,74 +64,11 @@ srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo_64.v") srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_fpga_core(clk, - rst, - current_test, - - btn, - sw, - led, - led_bkt, - led_hex0_d, - led_hex0_dp, - led_hex1_d, - led_hex1_dp, - - sfp_a_txd, - sfp_a_txc, - sfp_a_rxd, - sfp_a_rxc, - sfp_b_txd, - sfp_b_txc, - sfp_b_rxd, - sfp_b_rxc, - sfp_c_txd, - sfp_c_txc, - sfp_c_rxd, - sfp_c_rxc, - sfp_d_txd, - sfp_d_txc, - sfp_d_rxd, - sfp_d_rxc): - - 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, - - btn=btn, - sw=sw, - led=led, - led_bkt=led_bkt, - led_hex0_d=led_hex0_d, - led_hex0_dp=led_hex0_dp, - led_hex1_d=led_hex1_d, - led_hex1_dp=led_hex1_dp, - - sfp_a_txd=sfp_a_txd, - sfp_a_txc=sfp_a_txc, - sfp_a_rxd=sfp_a_rxd, - sfp_a_rxc=sfp_a_rxc, - sfp_b_txd=sfp_b_txd, - sfp_b_txc=sfp_b_txc, - sfp_b_rxd=sfp_b_rxd, - sfp_b_rxc=sfp_b_rxc, - sfp_c_txd=sfp_c_txd, - sfp_c_txc=sfp_c_txc, - sfp_c_rxd=sfp_c_rxd, - sfp_c_rxc=sfp_c_rxc, - sfp_d_txd=sfp_d_txd, - sfp_d_txc=sfp_d_txc, - sfp_d_rxd=sfp_d_rxd, - sfp_d_rxc=sfp_d_rxc) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -175,101 +108,66 @@ def bench(): sfp_d_txc = Signal(intbv(0)[8:]) # sources and sinks - xgmii_a_source_queue = Queue() - xgmii_a_sink_queue = Queue() - xgmii_b_source_queue = Queue() - xgmii_b_sink_queue = Queue() - xgmii_c_source_queue = Queue() - xgmii_c_sink_queue = Queue() - xgmii_d_source_queue = Queue() - xgmii_d_sink_queue = Queue() + sfp_a_source = xgmii_ep.XGMIISource() + sfp_a_source_logic = sfp_a_source.create_logic(clk, rst, txd=sfp_a_rxd, txc=sfp_a_rxc, name='sfp_a_source') - xgmii_a_source = xgmii_ep.XGMIISource(clk, - rst, - txd=sfp_a_rxd, - txc=sfp_a_rxc, - fifo=xgmii_a_source_queue, - name='xgmii_a_source') + sfp_a_sink = xgmii_ep.XGMIISink() + sfp_a_sink_logic = sfp_a_sink.create_logic(clk, rst, rxd=sfp_a_txd, rxc=sfp_a_txc, name='sfp_a_sink') - xgmii_a_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=sfp_a_txd, - rxc=sfp_a_txc, - fifo=xgmii_a_sink_queue, - name='xgmii_a_sink') + sfp_b_source = xgmii_ep.XGMIISource() + sfp_b_source_logic = sfp_b_source.create_logic(clk, rst, txd=sfp_b_rxd, txc=sfp_b_rxc, name='sfp_b_source') - xgmii_b_source = xgmii_ep.XGMIISource(clk, - rst, - txd=sfp_b_rxd, - txc=sfp_b_rxc, - fifo=xgmii_b_source_queue, - name='xgmii_b_source') + sfp_b_sink = xgmii_ep.XGMIISink() + sfp_b_sink_logic = sfp_b_sink.create_logic(clk, rst, rxd=sfp_b_txd, rxc=sfp_b_txc, name='sfp_b_sink') - xgmii_b_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=sfp_b_txd, - rxc=sfp_b_txc, - fifo=xgmii_b_sink_queue, - name='xgmii_b_sink') + sfp_c_source = xgmii_ep.XGMIISource() + sfp_c_source_logic = sfp_c_source.create_logic(clk, rst, txd=sfp_c_rxd, txc=sfp_c_rxc, name='sfp_c_source') - xgmii_c_source = xgmii_ep.XGMIISource(clk, - rst, - txd=sfp_c_rxd, - txc=sfp_c_rxc, - fifo=xgmii_c_source_queue, - name='xgmii_c_source') + sfp_c_sink = xgmii_ep.XGMIISink() + sfp_c_sink_logic = sfp_c_sink.create_logic(clk, rst, rxd=sfp_c_txd, rxc=sfp_c_txc, name='sfp_c_sink') - xgmii_c_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=sfp_c_txd, - rxc=sfp_c_txc, - fifo=xgmii_c_sink_queue, - name='xgmii_c_sink') + sfp_d_source = xgmii_ep.XGMIISource() + sfp_d_source_logic = sfp_d_source.create_logic(clk, rst, txd=sfp_d_rxd, txc=sfp_d_rxc, name='sfp_d_source') - xgmii_d_source = xgmii_ep.XGMIISource(clk, - rst, - txd=sfp_d_rxd, - txc=sfp_d_rxc, - fifo=xgmii_d_source_queue, - name='xgmii_d_source') - - xgmii_d_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=sfp_d_txd, - rxc=sfp_d_txc, - fifo=xgmii_d_sink_queue, - name='xgmii_d_sink') + sfp_d_sink = xgmii_ep.XGMIISink() + sfp_d_sink_logic = sfp_d_sink.create_logic(clk, rst, rxd=sfp_d_txd, rxc=sfp_d_txc, name='sfp_d_sink') # DUT - dut = dut_fpga_core(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - btn, - sw, - led, - led_bkt, - led_hex0_d, - led_hex0_dp, - led_hex1_d, - led_hex1_dp, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - sfp_a_txd, - sfp_a_txc, - sfp_a_rxd, - sfp_a_rxc, - sfp_b_txd, - sfp_b_txc, - sfp_b_rxd, - sfp_b_rxc, - sfp_c_txd, - sfp_c_txc, - sfp_c_rxd, - sfp_c_rxc, - sfp_d_txd, - sfp_d_txc, - sfp_d_rxd, - sfp_d_rxc) + btn=btn, + sw=sw, + led=led, + led_bkt=led_bkt, + led_hex0_d=led_hex0_d, + led_hex0_dp=led_hex0_dp, + led_hex1_d=led_hex1_d, + led_hex1_dp=led_hex1_dp, + + sfp_a_txd=sfp_a_txd, + sfp_a_txc=sfp_a_txc, + sfp_a_rxd=sfp_a_rxd, + sfp_a_rxc=sfp_a_rxc, + sfp_b_txd=sfp_b_txd, + sfp_b_txc=sfp_b_txc, + sfp_b_rxd=sfp_b_rxd, + sfp_b_rxc=sfp_b_rxc, + sfp_c_txd=sfp_c_txd, + sfp_c_txc=sfp_c_txc, + sfp_c_rxd=sfp_c_rxd, + sfp_c_rxc=sfp_c_rxc, + sfp_d_txd=sfp_d_txd, + sfp_d_txc=sfp_d_txc, + sfp_d_rxd=sfp_d_rxd, + sfp_d_rxc=sfp_d_rxc + ) @always(delay(4)) def clkgen(): @@ -314,13 +212,13 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - xgmii_a_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + sfp_a_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) # wait for ARP request packet - while xgmii_a_sink_queue.empty(): + while sfp_a_sink.empty(): yield clk.posedge - rx_frame = xgmii_a_sink_queue.get(False) + rx_frame = sfp_a_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = arp_ep.ARPFrame() @@ -356,12 +254,12 @@ def bench(): arp_frame.arp_tha = 0x020000000000 arp_frame.arp_tpa = 0xc0a80180 - xgmii_a_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + sfp_a_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) - while xgmii_a_sink_queue.empty(): + while sfp_a_sink.empty(): yield clk.posedge - rx_frame = xgmii_a_sink_queue.get(False) + rx_frame = sfp_a_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = udp_ep.UDPFrame() @@ -387,14 +285,14 @@ def bench(): assert check_frame.udp_dest_port == 5678 assert check_frame.payload.data == bytearray(range(32)) - assert xgmii_a_source_queue.empty() - assert xgmii_a_sink_queue.empty() + assert sfp_a_source.empty() + assert sfp_a_sink.empty() yield delay(100) raise StopSimulation - return dut, xgmii_a_source, xgmii_a_sink, xgmii_b_source, xgmii_b_sink, xgmii_c_source, xgmii_c_sink, xgmii_d_source, xgmii_d_sink, clkgen, check + return dut, sfp_a_source_logic, sfp_a_sink_logic, sfp_b_source_logic, sfp_b_sink_logic, sfp_c_source_logic, sfp_c_sink_logic, sfp_d_source_logic, sfp_d_sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.v b/example/DE5-Net/fpga/tb/test_fpga_core.v index a5e8eb745..bcdead8fa 100644 --- a/example/DE5-Net/fpga/tb/test_fpga_core.v +++ b/example/DE5-Net/fpga/tb/test_fpga_core.v @@ -67,33 +67,37 @@ wire [7:0] sfp_d_txc; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - btn, - sw, - sfp_a_rxd, - sfp_a_rxc, - sfp_b_rxd, - sfp_b_rxc, - sfp_c_rxd, - sfp_c_rxc, - sfp_d_rxd, - sfp_d_rxc); - $to_myhdl(led, - led_bkt, - led_hex0_d, - led_hex0_dp, - led_hex1_d, - led_hex1_dp, - sfp_a_txd, - sfp_a_txc, - sfp_b_txd, - sfp_b_txc, - sfp_c_txd, - sfp_c_txc, - sfp_d_txd, - sfp_d_txc); + $from_myhdl( + clk, + rst, + current_test, + btn, + sw, + sfp_a_rxd, + sfp_a_rxc, + sfp_b_rxd, + sfp_b_rxc, + sfp_c_rxd, + sfp_c_rxc, + sfp_d_rxd, + sfp_d_rxc + ); + $to_myhdl( + led, + led_bkt, + led_hex0_d, + led_hex0_dp, + led_hex1_d, + led_hex1_dp, + sfp_a_txd, + sfp_a_txc, + sfp_b_txd, + sfp_b_txc, + sfp_c_txd, + sfp_c_txc, + sfp_d_txd, + sfp_d_txc + ); // dump file $dumpfile("test_fpga_core.lxt"); diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index d70b1ff3b..a03b3e068 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -26,17 +26,13 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import eth_ep import arp_ep import udp_ep import xgmii_ep module = 'fpga_core' +testbench = 'test_%s' % module srcs = [] @@ -68,264 +64,11 @@ srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo_64.v") srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_fpga_core(clk, - rst, - current_test, - - sw, - jp, - led, - - uart_rst, - uart_suspend, - uart_ri, - uart_dcd, - uart_dtr, - uart_dsr, - uart_txd, - uart_rxd, - uart_rts, - uart_cts, - - amh_right_mdc, - amh_right_mdio_i, - amh_right_mdio_o, - amh_right_mdio_t, - amh_left_mdc, - amh_left_mdio_i, - amh_left_mdio_o, - amh_left_mdio_t, - - eth_r0_txd, - eth_r0_txc, - eth_r0_rxd, - eth_r0_rxc, - eth_r1_txd, - eth_r1_txc, - eth_r1_rxd, - eth_r1_rxc, - eth_r2_txd, - eth_r2_txc, - eth_r2_rxd, - eth_r2_rxc, - eth_r3_txd, - eth_r3_txc, - eth_r3_rxd, - eth_r3_rxc, - eth_r4_txd, - eth_r4_txc, - eth_r4_rxd, - eth_r4_rxc, - eth_r5_txd, - eth_r5_txc, - eth_r5_rxd, - eth_r5_rxc, - eth_r6_txd, - eth_r6_txc, - eth_r6_rxd, - eth_r6_rxc, - eth_r7_txd, - eth_r7_txc, - eth_r7_rxd, - eth_r7_rxc, - eth_r8_txd, - eth_r8_txc, - eth_r8_rxd, - eth_r8_rxc, - eth_r9_txd, - eth_r9_txc, - eth_r9_rxd, - eth_r9_rxc, - eth_r10_txd, - eth_r10_txc, - eth_r10_rxd, - eth_r10_rxc, - eth_r11_txd, - eth_r11_txc, - eth_r11_rxd, - eth_r11_rxc, - eth_l0_txd, - eth_l0_txc, - eth_l0_rxd, - eth_l0_rxc, - eth_l1_txd, - eth_l1_txc, - eth_l1_rxd, - eth_l1_rxc, - eth_l2_txd, - eth_l2_txc, - eth_l2_rxd, - eth_l2_rxc, - eth_l3_txd, - eth_l3_txc, - eth_l3_rxd, - eth_l3_rxc, - eth_l4_txd, - eth_l4_txc, - eth_l4_rxd, - eth_l4_rxc, - eth_l5_txd, - eth_l5_txc, - eth_l5_rxd, - eth_l5_rxc, - eth_l6_txd, - eth_l6_txc, - eth_l6_rxd, - eth_l6_rxc, - eth_l7_txd, - eth_l7_txc, - eth_l7_rxd, - eth_l7_rxc, - eth_l8_txd, - eth_l8_txc, - eth_l8_rxd, - eth_l8_rxc, - eth_l9_txd, - eth_l9_txc, - eth_l9_rxd, - eth_l9_rxc, - eth_l10_txd, - eth_l10_txc, - eth_l10_rxd, - eth_l10_rxc, - eth_l11_txd, - eth_l11_txc, - eth_l11_rxd, - eth_l11_rxc): - - 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, - - sw=sw, - jp=jp, - led=led, - - uart_rst=uart_rst, - uart_suspend=uart_suspend, - uart_ri=uart_ri, - uart_dcd=uart_dcd, - uart_dtr=uart_dtr, - uart_dsr=uart_dsr, - uart_txd=uart_txd, - uart_rxd=uart_rxd, - uart_rts=uart_rts, - uart_cts=uart_cts, - - amh_right_mdc=amh_right_mdc, - amh_right_mdio_i=amh_right_mdio_i, - amh_right_mdio_o=amh_right_mdio_o, - amh_right_mdio_t=amh_right_mdio_t, - amh_left_mdc=amh_left_mdc, - amh_left_mdio_i=amh_left_mdio_i, - amh_left_mdio_o=amh_left_mdio_o, - amh_left_mdio_t=amh_left_mdio_t, - - eth_r0_txd=eth_r0_txd, - eth_r0_txc=eth_r0_txc, - eth_r0_rxd=eth_r0_rxd, - eth_r0_rxc=eth_r0_rxc, - eth_r1_txd=eth_r1_txd, - eth_r1_txc=eth_r1_txc, - eth_r1_rxd=eth_r1_rxd, - eth_r1_rxc=eth_r1_rxc, - eth_r2_txd=eth_r2_txd, - eth_r2_txc=eth_r2_txc, - eth_r2_rxd=eth_r2_rxd, - eth_r2_rxc=eth_r2_rxc, - eth_r3_txd=eth_r3_txd, - eth_r3_txc=eth_r3_txc, - eth_r3_rxd=eth_r3_rxd, - eth_r3_rxc=eth_r3_rxc, - eth_r4_txd=eth_r4_txd, - eth_r4_txc=eth_r4_txc, - eth_r4_rxd=eth_r4_rxd, - eth_r4_rxc=eth_r4_rxc, - eth_r5_txd=eth_r5_txd, - eth_r5_txc=eth_r5_txc, - eth_r5_rxd=eth_r5_rxd, - eth_r5_rxc=eth_r5_rxc, - eth_r6_txd=eth_r6_txd, - eth_r6_txc=eth_r6_txc, - eth_r6_rxd=eth_r6_rxd, - eth_r6_rxc=eth_r6_rxc, - eth_r7_txd=eth_r7_txd, - eth_r7_txc=eth_r7_txc, - eth_r7_rxd=eth_r7_rxd, - eth_r7_rxc=eth_r7_rxc, - eth_r8_txd=eth_r8_txd, - eth_r8_txc=eth_r8_txc, - eth_r8_rxd=eth_r8_rxd, - eth_r8_rxc=eth_r8_rxc, - eth_r9_txd=eth_r9_txd, - eth_r9_txc=eth_r9_txc, - eth_r9_rxd=eth_r9_rxd, - eth_r9_rxc=eth_r9_rxc, - eth_r10_txd=eth_r10_txd, - eth_r10_txc=eth_r10_txc, - eth_r10_rxd=eth_r10_rxd, - eth_r10_rxc=eth_r10_rxc, - eth_r11_txd=eth_r11_txd, - eth_r11_txc=eth_r11_txc, - eth_r11_rxd=eth_r11_rxd, - eth_r11_rxc=eth_r11_rxc, - eth_l0_txd=eth_l0_txd, - eth_l0_txc=eth_l0_txc, - eth_l0_rxd=eth_l0_rxd, - eth_l0_rxc=eth_l0_rxc, - eth_l1_txd=eth_l1_txd, - eth_l1_txc=eth_l1_txc, - eth_l1_rxd=eth_l1_rxd, - eth_l1_rxc=eth_l1_rxc, - eth_l2_txd=eth_l2_txd, - eth_l2_txc=eth_l2_txc, - eth_l2_rxd=eth_l2_rxd, - eth_l2_rxc=eth_l2_rxc, - eth_l3_txd=eth_l3_txd, - eth_l3_txc=eth_l3_txc, - eth_l3_rxd=eth_l3_rxd, - eth_l3_rxc=eth_l3_rxc, - eth_l4_txd=eth_l4_txd, - eth_l4_txc=eth_l4_txc, - eth_l4_rxd=eth_l4_rxd, - eth_l4_rxc=eth_l4_rxc, - eth_l5_txd=eth_l5_txd, - eth_l5_txc=eth_l5_txc, - eth_l5_rxd=eth_l5_rxd, - eth_l5_rxc=eth_l5_rxc, - eth_l6_txd=eth_l6_txd, - eth_l6_txc=eth_l6_txc, - eth_l6_rxd=eth_l6_rxd, - eth_l6_rxc=eth_l6_rxc, - eth_l7_txd=eth_l7_txd, - eth_l7_txc=eth_l7_txc, - eth_l7_rxd=eth_l7_rxd, - eth_l7_rxc=eth_l7_rxc, - eth_l8_txd=eth_l8_txd, - eth_l8_txc=eth_l8_txc, - eth_l8_rxd=eth_l8_rxd, - eth_l8_rxc=eth_l8_rxc, - eth_l9_txd=eth_l9_txd, - eth_l9_txc=eth_l9_txc, - eth_l9_rxd=eth_l9_rxd, - eth_l9_rxc=eth_l9_rxc, - eth_l10_txd=eth_l10_txd, - eth_l10_txc=eth_l10_txc, - eth_l10_rxd=eth_l10_rxd, - eth_l10_rxc=eth_l10_rxc, - eth_l11_txd=eth_l11_txd, - eth_l11_txc=eth_l11_txc, - eth_l11_rxd=eth_l11_rxd, - eth_l11_rxc=eth_l11_rxc) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -458,516 +201,281 @@ def bench(): eth_l11_txc = Signal(intbv(0xff)[8:]) # sources and sinks - eth_r0_source_queue = Queue() - eth_r0_sink_queue = Queue() - eth_r1_source_queue = Queue() - eth_r1_sink_queue = Queue() - eth_r2_source_queue = Queue() - eth_r2_sink_queue = Queue() - eth_r3_source_queue = Queue() - eth_r3_sink_queue = Queue() - eth_r4_source_queue = Queue() - eth_r4_sink_queue = Queue() - eth_r5_source_queue = Queue() - eth_r5_sink_queue = Queue() - eth_r6_source_queue = Queue() - eth_r6_sink_queue = Queue() - eth_r7_source_queue = Queue() - eth_r7_sink_queue = Queue() - eth_r8_source_queue = Queue() - eth_r8_sink_queue = Queue() - eth_r9_source_queue = Queue() - eth_r9_sink_queue = Queue() - eth_r10_source_queue = Queue() - eth_r10_sink_queue = Queue() - eth_r11_source_queue = Queue() - eth_r11_sink_queue = Queue() - eth_l0_source_queue = Queue() - eth_l0_sink_queue = Queue() - eth_l1_source_queue = Queue() - eth_l1_sink_queue = Queue() - eth_l2_source_queue = Queue() - eth_l2_sink_queue = Queue() - eth_l3_source_queue = Queue() - eth_l3_sink_queue = Queue() - eth_l4_source_queue = Queue() - eth_l4_sink_queue = Queue() - eth_l5_source_queue = Queue() - eth_l5_sink_queue = Queue() - eth_l6_source_queue = Queue() - eth_l6_sink_queue = Queue() - eth_l7_source_queue = Queue() - eth_l7_sink_queue = Queue() - eth_l8_source_queue = Queue() - eth_l8_sink_queue = Queue() - eth_l9_source_queue = Queue() - eth_l9_sink_queue = Queue() - eth_l10_source_queue = Queue() - eth_l10_sink_queue = Queue() - eth_l11_source_queue = Queue() - eth_l11_sink_queue = Queue() + eth_r0_source = xgmii_ep.XGMIISource() + eth_r0_source_logic = eth_r0_source.create_logic(clk, rst, txd=eth_r0_rxd, txc=eth_r0_rxc, name='eth_r0_source') - eth_r0_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r0_rxd, - txc=eth_r0_rxc, - fifo=eth_r0_source_queue, - name='eth_r0_source') + eth_r0_sink = xgmii_ep.XGMIISink() + eth_r0_sink_logic = eth_r0_sink.create_logic(clk, rst, rxd=eth_r0_txd, rxc=eth_r0_txc, name='eth_r0_sink') - eth_r0_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r0_txd, - rxc=eth_r0_txc, - fifo=eth_r0_sink_queue, - name='eth_r0_sink') + eth_r1_source = xgmii_ep.XGMIISource() + eth_r1_source_logic = eth_r1_source.create_logic(clk, rst, txd=eth_r1_rxd, txc=eth_r1_rxc, name='eth_r1_source') - eth_r1_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r1_rxd, - txc=eth_r1_rxc, - fifo=eth_r1_source_queue, - name='eth_r1_source') + eth_r1_sink = xgmii_ep.XGMIISink() + eth_r1_sink_logic = eth_r1_sink.create_logic(clk, rst, rxd=eth_r1_txd, rxc=eth_r1_txc, name='eth_r1_sink') - eth_r1_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r1_txd, - rxc=eth_r1_txc, - fifo=eth_r1_sink_queue, - name='eth_r1_sink') + eth_r2_source = xgmii_ep.XGMIISource() + eth_r2_source_logic = eth_r2_source.create_logic(clk, rst, txd=eth_r2_rxd, txc=eth_r2_rxc, name='eth_r2_source') - eth_r2_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r2_rxd, - txc=eth_r2_rxc, - fifo=eth_r2_source_queue, - name='eth_r2_source') + eth_r2_sink = xgmii_ep.XGMIISink() + eth_r2_sink_logic = eth_r2_sink.create_logic(clk, rst, rxd=eth_r2_txd, rxc=eth_r2_txc, name='eth_r2_sink') - eth_r2_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r2_txd, - rxc=eth_r2_txc, - fifo=eth_r2_sink_queue, - name='eth_r2_sink') + eth_r3_source = xgmii_ep.XGMIISource() + eth_r3_source_logic = eth_r3_source.create_logic(clk, rst, txd=eth_r3_rxd, txc=eth_r3_rxc, name='eth_r3_source') - eth_r3_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r3_rxd, - txc=eth_r3_rxc, - fifo=eth_r3_source_queue, - name='eth_r3_source') + eth_r3_sink = xgmii_ep.XGMIISink() + eth_r3_sink_logic = eth_r3_sink.create_logic(clk, rst, rxd=eth_r3_txd, rxc=eth_r3_txc, name='eth_r3_sink') - eth_r3_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r3_txd, - rxc=eth_r3_txc, - fifo=eth_r3_sink_queue, - name='eth_r3_sink') + eth_r4_source = xgmii_ep.XGMIISource() + eth_r4_source_logic = eth_r4_source.create_logic(clk, rst, txd=eth_r4_rxd, txc=eth_r4_rxc, name='eth_r4_source') - eth_r4_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r4_rxd, - txc=eth_r4_rxc, - fifo=eth_r4_source_queue, - name='eth_r4_source') + eth_r4_sink = xgmii_ep.XGMIISink() + eth_r4_sink_logic = eth_r4_sink.create_logic(clk, rst, rxd=eth_r4_txd, rxc=eth_r4_txc, name='eth_r4_sink') - eth_r4_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r4_txd, - rxc=eth_r4_txc, - fifo=eth_r4_sink_queue, - name='eth_r4_sink') + eth_r5_source = xgmii_ep.XGMIISource() + eth_r5_source_logic = eth_r5_source.create_logic(clk, rst, txd=eth_r5_rxd, txc=eth_r5_rxc, name='eth_r5_source') - eth_r5_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r5_rxd, - txc=eth_r5_rxc, - fifo=eth_r5_source_queue, - name='eth_r5_source') + eth_r5_sink = xgmii_ep.XGMIISink() + eth_r5_sink_logic = eth_r5_sink.create_logic(clk, rst, rxd=eth_r5_txd, rxc=eth_r5_txc, name='eth_r5_sink') - eth_r5_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r5_txd, - rxc=eth_r5_txc, - fifo=eth_r5_sink_queue, - name='eth_r5_sink') + eth_r6_source = xgmii_ep.XGMIISource() + eth_r6_source_logic = eth_r6_source.create_logic(clk, rst, txd=eth_r6_rxd, txc=eth_r6_rxc, name='eth_r6_source') - eth_r6_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r6_rxd, - txc=eth_r6_rxc, - fifo=eth_r6_source_queue, - name='eth_r6_source') + eth_r6_sink = xgmii_ep.XGMIISink() + eth_r6_sink_logic = eth_r6_sink.create_logic(clk, rst, rxd=eth_r6_txd, rxc=eth_r6_txc, name='eth_r6_sink') - eth_r6_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r6_txd, - rxc=eth_r6_txc, - fifo=eth_r6_sink_queue, - name='eth_r6_sink') + eth_r7_source = xgmii_ep.XGMIISource() + eth_r7_source_logic = eth_r7_source.create_logic(clk, rst, txd=eth_r7_rxd, txc=eth_r7_rxc, name='eth_r7_source') - eth_r7_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r7_rxd, - txc=eth_r7_rxc, - fifo=eth_r7_source_queue, - name='eth_r7_source') + eth_r7_sink = xgmii_ep.XGMIISink() + eth_r7_sink_logic = eth_r7_sink.create_logic(clk, rst, rxd=eth_r7_txd, rxc=eth_r7_txc, name='eth_r7_sink') - eth_r7_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r7_txd, - rxc=eth_r7_txc, - fifo=eth_r7_sink_queue, - name='eth_r7_sink') + eth_r8_source = xgmii_ep.XGMIISource() + eth_r8_source_logic = eth_r8_source.create_logic(clk, rst, txd=eth_r8_rxd, txc=eth_r8_rxc, name='eth_r8_source') - eth_r8_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r8_rxd, - txc=eth_r8_rxc, - fifo=eth_r8_source_queue, - name='eth_r8_source') + eth_r8_sink = xgmii_ep.XGMIISink() + eth_r8_sink_logic = eth_r8_sink.create_logic(clk, rst, rxd=eth_r8_txd, rxc=eth_r8_txc, name='eth_r8_sink') - eth_r8_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r8_txd, - rxc=eth_r8_txc, - fifo=eth_r8_sink_queue, - name='eth_r8_sink') + eth_r9_source = xgmii_ep.XGMIISource() + eth_r9_source_logic = eth_r9_source.create_logic(clk, rst, txd=eth_r9_rxd, txc=eth_r9_rxc, name='eth_r9_source') - eth_r9_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r9_rxd, - txc=eth_r9_rxc, - fifo=eth_r9_source_queue, - name='eth_r9_source') + eth_r9_sink = xgmii_ep.XGMIISink() + eth_r9_sink_logic = eth_r9_sink.create_logic(clk, rst, rxd=eth_r9_txd, rxc=eth_r9_txc, name='eth_r9_sink') - eth_r9_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r9_txd, - rxc=eth_r9_txc, - fifo=eth_r9_sink_queue, - name='eth_r9_sink') + eth_r10_source = xgmii_ep.XGMIISource() + eth_r10_source_logic = eth_r10_source.create_logic(clk, rst, txd=eth_r10_rxd, txc=eth_r10_rxc, name='eth_r10_source') - eth_r10_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r10_rxd, - txc=eth_r10_rxc, - fifo=eth_r10_source_queue, - name='eth_r10_source') + eth_r10_sink = xgmii_ep.XGMIISink() + eth_r10_sink_logic = eth_r10_sink.create_logic(clk, rst, rxd=eth_r10_txd, rxc=eth_r10_txc, name='eth_r10_sink') - eth_r10_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r10_txd, - rxc=eth_r10_txc, - fifo=eth_r10_sink_queue, - name='eth_r10_sink') + eth_r11_source = xgmii_ep.XGMIISource() + eth_r11_source_logic = eth_r11_source.create_logic(clk, rst, txd=eth_r11_rxd, txc=eth_r11_rxc, name='eth_r11_source') - eth_r11_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_r11_rxd, - txc=eth_r11_rxc, - fifo=eth_r11_source_queue, - name='eth_r11_source') + eth_r11_sink = xgmii_ep.XGMIISink() + eth_r11_sink_logic = eth_r11_sink.create_logic(clk, rst, rxd=eth_r11_txd, rxc=eth_r11_txc, name='eth_r11_sink') - eth_r11_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_r11_txd, - rxc=eth_r11_txc, - fifo=eth_r11_sink_queue, - name='eth_r11_sink') + eth_l0_source = xgmii_ep.XGMIISource() + eth_l0_source_logic = eth_l0_source.create_logic(clk, rst, txd=eth_l0_rxd, txc=eth_l0_rxc, name='eth_l0_source') - eth_l0_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l0_rxd, - txc=eth_l0_rxc, - fifo=eth_l0_source_queue, - name='eth_l0_source') + eth_l0_sink = xgmii_ep.XGMIISink() + eth_l0_sink_logic = eth_l0_sink.create_logic(clk, rst, rxd=eth_l0_txd, rxc=eth_l0_txc, name='eth_l0_sink') - eth_l0_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l0_txd, - rxc=eth_l0_txc, - fifo=eth_l0_sink_queue, - name='eth_l0_sink') + eth_l1_source = xgmii_ep.XGMIISource() + eth_l1_source_logic = eth_l1_source.create_logic(clk, rst, txd=eth_l1_rxd, txc=eth_l1_rxc, name='eth_l1_source') - eth_l1_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l1_rxd, - txc=eth_l1_rxc, - fifo=eth_l1_source_queue, - name='eth_l1_source') + eth_l1_sink = xgmii_ep.XGMIISink() + eth_l1_sink_logic = eth_l1_sink.create_logic(clk, rst, rxd=eth_l1_txd, rxc=eth_l1_txc, name='eth_l1_sink') - eth_l1_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l1_txd, - rxc=eth_l1_txc, - fifo=eth_l1_sink_queue, - name='eth_l1_sink') + eth_l2_source = xgmii_ep.XGMIISource() + eth_l2_source_logic = eth_l2_source.create_logic(clk, rst, txd=eth_l2_rxd, txc=eth_l2_rxc, name='eth_l2_source') - eth_l2_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l2_rxd, - txc=eth_l2_rxc, - fifo=eth_l2_source_queue, - name='eth_l2_source') + eth_l2_sink = xgmii_ep.XGMIISink() + eth_l2_sink_logic = eth_l2_sink.create_logic(clk, rst, rxd=eth_l2_txd, rxc=eth_l2_txc, name='eth_l2_sink') - eth_l2_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l2_txd, - rxc=eth_l2_txc, - fifo=eth_l2_sink_queue, - name='eth_l2_sink') + eth_l3_source = xgmii_ep.XGMIISource() + eth_l3_source_logic = eth_l3_source.create_logic(clk, rst, txd=eth_l3_rxd, txc=eth_l3_rxc, name='eth_l3_source') - eth_l3_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l3_rxd, - txc=eth_l3_rxc, - fifo=eth_l3_source_queue, - name='eth_l3_source') + eth_l3_sink = xgmii_ep.XGMIISink() + eth_l3_sink_logic = eth_l3_sink.create_logic(clk, rst, rxd=eth_l3_txd, rxc=eth_l3_txc, name='eth_l3_sink') - eth_l3_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l3_txd, - rxc=eth_l3_txc, - fifo=eth_l3_sink_queue, - name='eth_l3_sink') + eth_l4_source = xgmii_ep.XGMIISource() + eth_l4_source_logic = eth_l4_source.create_logic(clk, rst, txd=eth_l4_rxd, txc=eth_l4_rxc, name='eth_l4_source') - eth_l4_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l4_rxd, - txc=eth_l4_rxc, - fifo=eth_l4_source_queue, - name='eth_l4_source') + eth_l4_sink = xgmii_ep.XGMIISink() + eth_l4_sink_logic = eth_l4_sink.create_logic(clk, rst, rxd=eth_l4_txd, rxc=eth_l4_txc, name='eth_l4_sink') - eth_l4_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l4_txd, - rxc=eth_l4_txc, - fifo=eth_l4_sink_queue, - name='eth_l4_sink') + eth_l5_source = xgmii_ep.XGMIISource() + eth_l5_source_logic = eth_l5_source.create_logic(clk, rst, txd=eth_l5_rxd, txc=eth_l5_rxc, name='eth_l5_source') - eth_l5_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l5_rxd, - txc=eth_l5_rxc, - fifo=eth_l5_source_queue, - name='eth_l5_source') + eth_l5_sink = xgmii_ep.XGMIISink() + eth_l5_sink_logic = eth_l5_sink.create_logic(clk, rst, rxd=eth_l5_txd, rxc=eth_l5_txc, name='eth_l5_sink') - eth_l5_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l5_txd, - rxc=eth_l5_txc, - fifo=eth_l5_sink_queue, - name='eth_l5_sink') + eth_l6_source = xgmii_ep.XGMIISource() + eth_l6_source_logic = eth_l6_source.create_logic(clk, rst, txd=eth_l6_rxd, txc=eth_l6_rxc, name='eth_l6_source') - eth_l6_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l6_rxd, - txc=eth_l6_rxc, - fifo=eth_l6_source_queue, - name='eth_l6_source') + eth_l6_sink = xgmii_ep.XGMIISink() + eth_l6_sink_logic = eth_l6_sink.create_logic(clk, rst, rxd=eth_l6_txd, rxc=eth_l6_txc, name='eth_l6_sink') - eth_l6_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l6_txd, - rxc=eth_l6_txc, - fifo=eth_l6_sink_queue, - name='eth_l6_sink') + eth_l7_source = xgmii_ep.XGMIISource() + eth_l7_source_logic = eth_l7_source.create_logic(clk, rst, txd=eth_l7_rxd, txc=eth_l7_rxc, name='eth_l7_source') - eth_l7_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l7_rxd, - txc=eth_l7_rxc, - fifo=eth_l7_source_queue, - name='eth_l7_source') + eth_l7_sink = xgmii_ep.XGMIISink() + eth_l7_sink_logic = eth_l7_sink.create_logic(clk, rst, rxd=eth_l7_txd, rxc=eth_l7_txc, name='eth_l7_sink') - eth_l7_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l7_txd, - rxc=eth_l7_txc, - fifo=eth_l7_sink_queue, - name='eth_l7_sink') + eth_l8_source = xgmii_ep.XGMIISource() + eth_l8_source_logic = eth_l8_source.create_logic(clk, rst, txd=eth_l8_rxd, txc=eth_l8_rxc, name='eth_l8_source') - eth_l8_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l8_rxd, - txc=eth_l8_rxc, - fifo=eth_l8_source_queue, - name='eth_l8_source') + eth_l8_sink = xgmii_ep.XGMIISink() + eth_l8_sink_logic = eth_l8_sink.create_logic(clk, rst, rxd=eth_l8_txd, rxc=eth_l8_txc, name='eth_l8_sink') - eth_l8_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l8_txd, - rxc=eth_l8_txc, - fifo=eth_l8_sink_queue, - name='eth_l8_sink') + eth_l9_source = xgmii_ep.XGMIISource() + eth_l9_source_logic = eth_l9_source.create_logic(clk, rst, txd=eth_l9_rxd, txc=eth_l9_rxc, name='eth_l9_source') - eth_l9_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l9_rxd, - txc=eth_l9_rxc, - fifo=eth_l9_source_queue, - name='eth_l9_source') + eth_l9_sink = xgmii_ep.XGMIISink() + eth_l9_sink_logic = eth_l9_sink.create_logic(clk, rst, rxd=eth_l9_txd, rxc=eth_l9_txc, name='eth_l9_sink') - eth_l9_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l9_txd, - rxc=eth_l9_txc, - fifo=eth_l9_sink_queue, - name='eth_l9_sink') + eth_l10_source = xgmii_ep.XGMIISource() + eth_l10_source_logic = eth_l10_source.create_logic(clk, rst, txd=eth_l10_rxd, txc=eth_l10_rxc, name='eth_l10_source') - eth_l10_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l10_rxd, - txc=eth_l10_rxc, - fifo=eth_l10_source_queue, - name='eth_l10_source') + eth_l10_sink = xgmii_ep.XGMIISink() + eth_l10_sink_logic = eth_l10_sink.create_logic(clk, rst, rxd=eth_l10_txd, rxc=eth_l10_txc, name='eth_l10_sink') - eth_l10_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l10_txd, - rxc=eth_l10_txc, - fifo=eth_l10_sink_queue, - name='eth_l10_sink') + eth_l11_source = xgmii_ep.XGMIISource() + eth_l11_source_logic = eth_l11_source.create_logic(clk, rst, txd=eth_l11_rxd, txc=eth_l11_rxc, name='eth_l11_source') - eth_l11_source = xgmii_ep.XGMIISource(clk, - rst, - txd=eth_l11_rxd, - txc=eth_l11_rxc, - fifo=eth_l11_source_queue, - name='eth_l11_source') - - eth_l11_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=eth_l11_txd, - rxc=eth_l11_txc, - fifo=eth_l11_sink_queue, - name='eth_l11_sink') + eth_l11_sink = xgmii_ep.XGMIISink() + eth_l11_sink_logic = eth_l11_sink.create_logic(clk, rst, rxd=eth_l11_txd, rxc=eth_l11_txc, name='eth_l11_sink') # DUT - dut = dut_fpga_core(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - sw, - jp, - led, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - uart_rst, - uart_suspend, - uart_ri, - uart_dcd, - uart_dtr, - uart_dsr, - uart_txd, - uart_rxd, - uart_rts, - uart_cts, + sw=sw, + jp=jp, + led=led, - amh_right_mdc, - amh_right_mdio_i, - amh_right_mdio_o, - amh_right_mdio_t, - amh_left_mdc, - amh_left_mdio_i, - amh_left_mdio_o, - amh_left_mdio_t, + uart_rst=uart_rst, + uart_suspend=uart_suspend, + uart_ri=uart_ri, + uart_dcd=uart_dcd, + uart_dtr=uart_dtr, + uart_dsr=uart_dsr, + uart_txd=uart_txd, + uart_rxd=uart_rxd, + uart_rts=uart_rts, + uart_cts=uart_cts, - eth_r0_txd, - eth_r0_txc, - eth_r0_rxd, - eth_r0_rxc, - eth_r1_txd, - eth_r1_txc, - eth_r1_rxd, - eth_r1_rxc, - eth_r2_txd, - eth_r2_txc, - eth_r2_rxd, - eth_r2_rxc, - eth_r3_txd, - eth_r3_txc, - eth_r3_rxd, - eth_r3_rxc, - eth_r4_txd, - eth_r4_txc, - eth_r4_rxd, - eth_r4_rxc, - eth_r5_txd, - eth_r5_txc, - eth_r5_rxd, - eth_r5_rxc, - eth_r6_txd, - eth_r6_txc, - eth_r6_rxd, - eth_r6_rxc, - eth_r7_txd, - eth_r7_txc, - eth_r7_rxd, - eth_r7_rxc, - eth_r8_txd, - eth_r8_txc, - eth_r8_rxd, - eth_r8_rxc, - eth_r9_txd, - eth_r9_txc, - eth_r9_rxd, - eth_r9_rxc, - eth_r10_txd, - eth_r10_txc, - eth_r10_rxd, - eth_r10_rxc, - eth_r11_txd, - eth_r11_txc, - eth_r11_rxd, - eth_r11_rxc, - eth_l0_txd, - eth_l0_txc, - eth_l0_rxd, - eth_l0_rxc, - eth_l1_txd, - eth_l1_txc, - eth_l1_rxd, - eth_l1_rxc, - eth_l2_txd, - eth_l2_txc, - eth_l2_rxd, - eth_l2_rxc, - eth_l3_txd, - eth_l3_txc, - eth_l3_rxd, - eth_l3_rxc, - eth_l4_txd, - eth_l4_txc, - eth_l4_rxd, - eth_l4_rxc, - eth_l5_txd, - eth_l5_txc, - eth_l5_rxd, - eth_l5_rxc, - eth_l6_txd, - eth_l6_txc, - eth_l6_rxd, - eth_l6_rxc, - eth_l7_txd, - eth_l7_txc, - eth_l7_rxd, - eth_l7_rxc, - eth_l8_txd, - eth_l8_txc, - eth_l8_rxd, - eth_l8_rxc, - eth_l9_txd, - eth_l9_txc, - eth_l9_rxd, - eth_l9_rxc, - eth_l10_txd, - eth_l10_txc, - eth_l10_rxd, - eth_l10_rxc, - eth_l11_txd, - eth_l11_txc, - eth_l11_rxd, - eth_l11_rxc) + amh_right_mdc=amh_right_mdc, + amh_right_mdio_i=amh_right_mdio_i, + amh_right_mdio_o=amh_right_mdio_o, + amh_right_mdio_t=amh_right_mdio_t, + amh_left_mdc=amh_left_mdc, + amh_left_mdio_i=amh_left_mdio_i, + amh_left_mdio_o=amh_left_mdio_o, + amh_left_mdio_t=amh_left_mdio_t, + + eth_r0_txd=eth_r0_txd, + eth_r0_txc=eth_r0_txc, + eth_r0_rxd=eth_r0_rxd, + eth_r0_rxc=eth_r0_rxc, + eth_r1_txd=eth_r1_txd, + eth_r1_txc=eth_r1_txc, + eth_r1_rxd=eth_r1_rxd, + eth_r1_rxc=eth_r1_rxc, + eth_r2_txd=eth_r2_txd, + eth_r2_txc=eth_r2_txc, + eth_r2_rxd=eth_r2_rxd, + eth_r2_rxc=eth_r2_rxc, + eth_r3_txd=eth_r3_txd, + eth_r3_txc=eth_r3_txc, + eth_r3_rxd=eth_r3_rxd, + eth_r3_rxc=eth_r3_rxc, + eth_r4_txd=eth_r4_txd, + eth_r4_txc=eth_r4_txc, + eth_r4_rxd=eth_r4_rxd, + eth_r4_rxc=eth_r4_rxc, + eth_r5_txd=eth_r5_txd, + eth_r5_txc=eth_r5_txc, + eth_r5_rxd=eth_r5_rxd, + eth_r5_rxc=eth_r5_rxc, + eth_r6_txd=eth_r6_txd, + eth_r6_txc=eth_r6_txc, + eth_r6_rxd=eth_r6_rxd, + eth_r6_rxc=eth_r6_rxc, + eth_r7_txd=eth_r7_txd, + eth_r7_txc=eth_r7_txc, + eth_r7_rxd=eth_r7_rxd, + eth_r7_rxc=eth_r7_rxc, + eth_r8_txd=eth_r8_txd, + eth_r8_txc=eth_r8_txc, + eth_r8_rxd=eth_r8_rxd, + eth_r8_rxc=eth_r8_rxc, + eth_r9_txd=eth_r9_txd, + eth_r9_txc=eth_r9_txc, + eth_r9_rxd=eth_r9_rxd, + eth_r9_rxc=eth_r9_rxc, + eth_r10_txd=eth_r10_txd, + eth_r10_txc=eth_r10_txc, + eth_r10_rxd=eth_r10_rxd, + eth_r10_rxc=eth_r10_rxc, + eth_r11_txd=eth_r11_txd, + eth_r11_txc=eth_r11_txc, + eth_r11_rxd=eth_r11_rxd, + eth_r11_rxc=eth_r11_rxc, + eth_l0_txd=eth_l0_txd, + eth_l0_txc=eth_l0_txc, + eth_l0_rxd=eth_l0_rxd, + eth_l0_rxc=eth_l0_rxc, + eth_l1_txd=eth_l1_txd, + eth_l1_txc=eth_l1_txc, + eth_l1_rxd=eth_l1_rxd, + eth_l1_rxc=eth_l1_rxc, + eth_l2_txd=eth_l2_txd, + eth_l2_txc=eth_l2_txc, + eth_l2_rxd=eth_l2_rxd, + eth_l2_rxc=eth_l2_rxc, + eth_l3_txd=eth_l3_txd, + eth_l3_txc=eth_l3_txc, + eth_l3_rxd=eth_l3_rxd, + eth_l3_rxc=eth_l3_rxc, + eth_l4_txd=eth_l4_txd, + eth_l4_txc=eth_l4_txc, + eth_l4_rxd=eth_l4_rxd, + eth_l4_rxc=eth_l4_rxc, + eth_l5_txd=eth_l5_txd, + eth_l5_txc=eth_l5_txc, + eth_l5_rxd=eth_l5_rxd, + eth_l5_rxc=eth_l5_rxc, + eth_l6_txd=eth_l6_txd, + eth_l6_txc=eth_l6_txc, + eth_l6_rxd=eth_l6_rxd, + eth_l6_rxc=eth_l6_rxc, + eth_l7_txd=eth_l7_txd, + eth_l7_txc=eth_l7_txc, + eth_l7_rxd=eth_l7_rxd, + eth_l7_rxc=eth_l7_rxc, + eth_l8_txd=eth_l8_txd, + eth_l8_txc=eth_l8_txc, + eth_l8_rxd=eth_l8_rxd, + eth_l8_rxc=eth_l8_rxc, + eth_l9_txd=eth_l9_txd, + eth_l9_txc=eth_l9_txc, + eth_l9_rxd=eth_l9_rxd, + eth_l9_rxc=eth_l9_rxc, + eth_l10_txd=eth_l10_txd, + eth_l10_txc=eth_l10_txc, + eth_l10_rxd=eth_l10_rxd, + eth_l10_rxc=eth_l10_rxc, + eth_l11_txd=eth_l11_txd, + eth_l11_txc=eth_l11_txc, + eth_l11_rxd=eth_l11_rxd, + eth_l11_rxc=eth_l11_rxc + ) @always(delay(4)) def clkgen(): @@ -1012,13 +520,13 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - eth_l0_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + eth_l0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) # wait for ARP request packet - while eth_l0_sink_queue.empty(): + while eth_l0_sink.empty(): yield clk.posedge - rx_frame = eth_l0_sink_queue.get(False) + rx_frame = eth_l0_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = arp_ep.ARPFrame() @@ -1054,12 +562,12 @@ def bench(): arp_frame.arp_tha = 0x020000000000 arp_frame.arp_tpa = 0xc0a80180 - eth_l0_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + eth_l0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) - while eth_l0_sink_queue.empty(): + while eth_l0_sink.empty(): yield clk.posedge - rx_frame = eth_l0_sink_queue.get(False) + rx_frame = eth_l0_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = udp_ep.UDPFrame() @@ -1085,21 +593,21 @@ def bench(): assert check_frame.udp_dest_port == 5678 assert check_frame.payload.data == bytearray(range(32)) - assert eth_l0_source_queue.empty() - assert eth_l0_sink_queue.empty() + assert eth_l0_source.empty() + assert eth_l0_sink.empty() yield delay(100) raise StopSimulation - return (dut, clkgen, check, eth_r0_source, eth_r0_sink, eth_r1_source, eth_r1_sink, eth_r2_source, eth_r2_sink, - eth_r3_source, eth_r3_sink, eth_r4_source, eth_r4_sink, eth_r5_source, eth_r5_sink, - eth_r6_source, eth_r6_sink, eth_r7_source, eth_r7_sink, eth_r8_source, eth_r8_sink, - eth_r9_source, eth_r9_sink, eth_r10_source, eth_r10_sink, eth_r11_source, eth_r11_sink, - eth_l0_source, eth_l0_sink, eth_l1_source, eth_l1_sink, eth_l2_source, eth_l2_sink, - eth_l3_source, eth_l3_sink, eth_l4_source, eth_l4_sink, eth_l5_source, eth_l5_sink, - eth_l6_source, eth_l6_sink, eth_l7_source, eth_l7_sink, eth_l8_source, eth_l8_sink, - eth_l9_source, eth_l9_sink, eth_l10_source, eth_l10_sink, eth_l11_source, eth_l11_sink) + return (dut, clkgen, check, eth_r0_source_logic, eth_r0_sink_logic, eth_r1_source_logic, eth_r1_sink_logic, eth_r2_source_logic, eth_r2_sink_logic, + eth_r3_source_logic, eth_r3_sink_logic, eth_r4_source_logic, eth_r4_sink_logic, eth_r5_source_logic, eth_r5_sink_logic, + eth_r6_source_logic, eth_r6_sink_logic, eth_r7_source_logic, eth_r7_sink_logic, eth_r8_source_logic, eth_r8_sink_logic, + eth_r9_source_logic, eth_r9_sink_logic, eth_r10_source_logic, eth_r10_sink_logic, eth_r11_source_logic, eth_r11_sink_logic, + eth_l0_source_logic, eth_l0_sink_logic, eth_l1_source_logic, eth_l1_sink_logic, eth_l2_source_logic, eth_l2_sink_logic, + eth_l3_source_logic, eth_l3_sink_logic, eth_l4_source_logic, eth_l4_sink_logic, eth_l5_source_logic, eth_l5_sink_logic, + eth_l6_source_logic, eth_l6_sink_logic, eth_l7_source_logic, eth_l7_sink_logic, eth_l8_source_logic, eth_l8_sink_logic, + eth_l9_source_logic, eth_l9_sink_logic, eth_l10_source_logic, eth_l10_sink_logic, eth_l11_source_logic, eth_l11_sink_logic) def test_bench(): sim = Simulation(bench()) diff --git a/example/HXT100G/fpga/tb/test_fpga_core.v b/example/HXT100G/fpga/tb/test_fpga_core.v index 7ce2dfa98..62a146cf5 100644 --- a/example/HXT100G/fpga/tb/test_fpga_core.v +++ b/example/HXT100G/fpga/tb/test_fpga_core.v @@ -160,126 +160,130 @@ wire [7:0] eth_l11_txc; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - sw, - jp, - uart_suspend, - uart_dtr, - uart_txd, - uart_rts, - amh_right_mdio_i, - amh_left_mdio_i, - eth_r0_rxd, - eth_r0_rxc, - eth_r1_rxd, - eth_r1_rxc, - eth_r2_rxd, - eth_r2_rxc, - eth_r3_rxd, - eth_r3_rxc, - eth_r4_rxd, - eth_r4_rxc, - eth_r5_rxd, - eth_r5_rxc, - eth_r6_rxd, - eth_r6_rxc, - eth_r7_rxd, - eth_r7_rxc, - eth_r8_rxd, - eth_r8_rxc, - eth_r9_rxd, - eth_r9_rxc, - eth_r10_rxd, - eth_r10_rxc, - eth_r11_rxd, - eth_r11_rxc, - eth_l0_rxd, - eth_l0_rxc, - eth_l1_rxd, - eth_l1_rxc, - eth_l2_rxd, - eth_l2_rxc, - eth_l3_rxd, - eth_l3_rxc, - eth_l4_rxd, - eth_l4_rxc, - eth_l5_rxd, - eth_l5_rxc, - eth_l6_rxd, - eth_l6_rxc, - eth_l7_rxd, - eth_l7_rxc, - eth_l8_rxd, - eth_l8_rxc, - eth_l9_rxd, - eth_l9_rxc, - eth_l10_rxd, - eth_l10_rxc, - eth_l11_rxd, - eth_l11_rxc); - $to_myhdl(led, - uart_rst, - uart_ri, - uart_dcd, - uart_dsr, - uart_rxd, - uart_cts, - amh_right_mdc, - amh_right_mdio_o, - amh_right_mdio_t, - amh_left_mdc, - amh_left_mdio_o, - amh_left_mdio_t, - eth_r0_txd, - eth_r0_txc, - eth_r1_txd, - eth_r1_txc, - eth_r2_txd, - eth_r2_txc, - eth_r3_txd, - eth_r3_txc, - eth_r4_txd, - eth_r4_txc, - eth_r5_txd, - eth_r5_txc, - eth_r6_txd, - eth_r6_txc, - eth_r7_txd, - eth_r7_txc, - eth_r8_txd, - eth_r8_txc, - eth_r9_txd, - eth_r9_txc, - eth_r10_txd, - eth_r10_txc, - eth_r11_txd, - eth_r11_txc, - eth_l0_txd, - eth_l0_txc, - eth_l1_txd, - eth_l1_txc, - eth_l2_txd, - eth_l2_txc, - eth_l3_txd, - eth_l3_txc, - eth_l4_txd, - eth_l4_txc, - eth_l5_txd, - eth_l5_txc, - eth_l6_txd, - eth_l6_txc, - eth_l7_txd, - eth_l7_txc, - eth_l8_txd, - eth_l8_txc, - eth_l9_txd, - eth_l9_txc, - eth_l10_txd, - eth_l10_txc, - eth_l11_txd, - eth_l11_txc); + $from_myhdl( + clk, + rst, + current_test, + sw, + jp, + uart_suspend, + uart_dtr, + uart_txd, + uart_rts, + amh_right_mdio_i, + amh_left_mdio_i, + eth_r0_rxd, + eth_r0_rxc, + eth_r1_rxd, + eth_r1_rxc, + eth_r2_rxd, + eth_r2_rxc, + eth_r3_rxd, + eth_r3_rxc, + eth_r4_rxd, + eth_r4_rxc, + eth_r5_rxd, + eth_r5_rxc, + eth_r6_rxd, + eth_r6_rxc, + eth_r7_rxd, + eth_r7_rxc, + eth_r8_rxd, + eth_r8_rxc, + eth_r9_rxd, + eth_r9_rxc, + eth_r10_rxd, + eth_r10_rxc, + eth_r11_rxd, + eth_r11_rxc, + eth_l0_rxd, + eth_l0_rxc, + eth_l1_rxd, + eth_l1_rxc, + eth_l2_rxd, + eth_l2_rxc, + eth_l3_rxd, + eth_l3_rxc, + eth_l4_rxd, + eth_l4_rxc, + eth_l5_rxd, + eth_l5_rxc, + eth_l6_rxd, + eth_l6_rxc, + eth_l7_rxd, + eth_l7_rxc, + eth_l8_rxd, + eth_l8_rxc, + eth_l9_rxd, + eth_l9_rxc, + eth_l10_rxd, + eth_l10_rxc, + eth_l11_rxd, + eth_l11_rxc + ); + $to_myhdl( + led, + uart_rst, + uart_ri, + uart_dcd, + uart_dsr, + uart_rxd, + uart_cts, + amh_right_mdc, + amh_right_mdio_o, + amh_right_mdio_t, + amh_left_mdc, + amh_left_mdio_o, + amh_left_mdio_t, + eth_r0_txd, + eth_r0_txc, + eth_r1_txd, + eth_r1_txc, + eth_r2_txd, + eth_r2_txc, + eth_r3_txd, + eth_r3_txc, + eth_r4_txd, + eth_r4_txc, + eth_r5_txd, + eth_r5_txc, + eth_r6_txd, + eth_r6_txc, + eth_r7_txd, + eth_r7_txc, + eth_r8_txd, + eth_r8_txc, + eth_r9_txd, + eth_r9_txc, + eth_r10_txd, + eth_r10_txc, + eth_r11_txd, + eth_r11_txc, + eth_l0_txd, + eth_l0_txc, + eth_l1_txd, + eth_l1_txc, + eth_l2_txd, + eth_l2_txc, + eth_l3_txd, + eth_l3_txc, + eth_l4_txd, + eth_l4_txc, + eth_l5_txd, + eth_l5_txc, + eth_l6_txd, + eth_l6_txc, + eth_l7_txd, + eth_l7_txc, + eth_l8_txd, + eth_l8_txc, + eth_l9_txd, + eth_l9_txc, + eth_l10_txd, + eth_l10_txc, + eth_l11_txd, + eth_l11_txc + ); // dump file $dumpfile("test_fpga_core.lxt"); diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.py b/example/NexysVideo/fpga/tb/test_fpga_core.py index 514466595..0b57b14d3 100755 --- a/example/NexysVideo/fpga/tb/test_fpga_core.py +++ b/example/NexysVideo/fpga/tb/test_fpga_core.py @@ -26,17 +26,13 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import eth_ep import arp_ep import udp_ep import rgmii_ep module = 'fpga_core' +testbench = 'test_%s' % module srcs = [] @@ -69,66 +65,11 @@ srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_fpga_core(clk, - clk90, - rst, - - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - led, - - phy_rx_clk, - phy_rxd, - phy_rx_ctl, - phy_tx_clk, - phy_txd, - phy_tx_ctl, - phy_reset_n, - phy_int_n, - phy_pme_n, - - uart_rxd, - uart_txd): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - clk90=clk90, - rst=rst, - current_test=current_test, - - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - - phy_rx_clk=phy_rx_clk, - phy_rxd=phy_rxd, - phy_rx_ctl=phy_rx_ctl, - phy_tx_clk=phy_tx_clk, - phy_txd=phy_txd, - phy_tx_ctl=phy_tx_ctl, - phy_reset_n=phy_reset_n, - phy_int_n=phy_int_n, - phy_pme_n=phy_pme_n, - - uart_rxd=uart_rxd, - uart_txd=uart_txd) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -163,49 +104,58 @@ def bench(): uart_txd = Signal(bool(0)) # sources and sinks - rgmii_source_queue = Queue() - rgmii_sink_queue = Queue() + rgmii_source = rgmii_ep.RGMIISource() - rgmii_source = rgmii_ep.RGMIISource(phy_rx_clk, - rst, - txd=phy_rxd, - tx_ctl=phy_rx_ctl, - fifo=rgmii_source_queue, - name='rgmii_source') + rgmii_source_logic = rgmii_source.create_logic( + phy_rx_clk, + rst, + txd=phy_rxd, + tx_ctl=phy_rx_ctl, + name='rgmii_source' + ) - rgmii_sink = rgmii_ep.RGMIISink(phy_tx_clk, - rst, - rxd=phy_txd, - rx_ctl=phy_tx_ctl, - fifo=rgmii_sink_queue, - name='rgmii_sink') + rgmii_sink = rgmii_ep.RGMIISink() + + rgmii_sink_logic = rgmii_sink.create_logic( + phy_tx_clk, + rst, + rxd=phy_txd, + rx_ctl=phy_tx_ctl, + name='rgmii_sink' + ) # DUT - dut = dut_fpga_core(clk, - clk90, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - led, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + clk90=clk90, + rst=rst, + current_test=current_test, - phy_rx_clk, - phy_rxd, - phy_rx_ctl, - phy_tx_clk, - phy_txd, - phy_tx_ctl, - phy_reset_n, - phy_int_n, - phy_pme_n, + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, - uart_rxd, - uart_txd) + phy_rx_clk=phy_rx_clk, + phy_rxd=phy_rxd, + phy_rx_ctl=phy_rx_ctl, + phy_tx_clk=phy_tx_clk, + phy_txd=phy_txd, + phy_tx_ctl=phy_tx_ctl, + phy_reset_n=phy_reset_n, + phy_int_n=phy_int_n, + phy_pme_n=phy_pme_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd + ) @always(delay(4)) def clkgen(): @@ -258,13 +208,13 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - rgmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + rgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) # wait for ARP request packet - while rgmii_sink_queue.empty(): + while rgmii_sink.empty(): yield clk.posedge - rx_frame = rgmii_sink_queue.get(False) + rx_frame = rgmii_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = arp_ep.ARPFrame() @@ -300,12 +250,12 @@ def bench(): arp_frame.arp_tha = 0x020000000000 arp_frame.arp_tpa = 0xc0a80180 - rgmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + rgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) - while rgmii_sink_queue.empty(): + while rgmii_sink.empty(): yield clk.posedge - rx_frame = rgmii_sink_queue.get(False) + rx_frame = rgmii_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = udp_ep.UDPFrame() @@ -331,14 +281,14 @@ def bench(): assert check_frame.udp_dest_port == 5678 assert check_frame.payload.data == bytearray(range(32)) - assert rgmii_source_queue.empty() - assert rgmii_sink_queue.empty() + assert rgmii_source.empty() + assert rgmii_sink.empty() yield delay(100) raise StopSimulation - return dut, rgmii_source, rgmii_sink, clkgen, clkgen2, check + return dut, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, check def test_bench(): sim = Simulation(bench()) diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.v b/example/NexysVideo/fpga/tb/test_fpga_core.v index 4185a5335..984184f0b 100644 --- a/example/NexysVideo/fpga/tb/test_fpga_core.v +++ b/example/NexysVideo/fpga/tb/test_fpga_core.v @@ -63,28 +63,32 @@ wire uart_txd; initial begin // myhdl integration - $from_myhdl(clk, - clk90, - rst, - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - phy_rx_clk, - phy_rxd, - phy_rx_ctl, - phy_int_n, - phy_pme_n, - uart_rxd); - $to_myhdl(led, - phy_tx_clk, - phy_txd, - phy_tx_ctl, - phy_reset_n, - uart_txd); + $from_myhdl( + clk, + clk90, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_rx_clk, + phy_rxd, + phy_rx_ctl, + phy_int_n, + phy_pme_n, + uart_rxd + ); + $to_myhdl( + led, + phy_tx_clk, + phy_txd, + phy_tx_ctl, + phy_reset_n, + uart_txd + ); // dump file $dumpfile("test_fpga_core.lxt"); diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index afb60a373..b1e4d9fac 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -26,11 +26,6 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import eth_ep import arp_ep import udp_ep @@ -38,6 +33,7 @@ import gmii_ep import xgmii_ep module = 'fpga_core' +testbench = 'test_%s' % module srcs = [] @@ -79,104 +75,11 @@ srcs.append("../lib/eth/lib/axis/rtl/axis_fifo_64.v") srcs.append("../lib/eth/lib/axis/rtl/axis_switch_64_4x4.v") srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_fpga_core(clk, - rst, - current_test, - - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - led, - - qsfp_txd_1, - qsfp_txc_1, - qsfp_rxd_1, - qsfp_rxc_1, - qsfp_txd_2, - qsfp_txc_2, - qsfp_rxd_2, - qsfp_rxc_2, - qsfp_txd_3, - qsfp_txc_3, - qsfp_rxd_3, - qsfp_rxc_3, - qsfp_txd_4, - qsfp_txc_4, - qsfp_rxd_4, - qsfp_rxc_4, - - phy_gmii_clk, - phy_gmii_rst, - phy_gmii_rxd, - phy_gmii_rx_dv, - phy_gmii_rx_er, - phy_gmii_txd, - phy_gmii_tx_en, - phy_gmii_tx_er, - phy_reset_n, - phy_int_n, - - uart_rxd, - uart_txd, - uart_rts, - uart_cts): - - 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, - - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - - qsfp_txd_1=qsfp_txd_1, - qsfp_txc_1=qsfp_txc_1, - qsfp_rxd_1=qsfp_rxd_1, - qsfp_rxc_1=qsfp_rxc_1, - qsfp_txd_2=qsfp_txd_2, - qsfp_txc_2=qsfp_txc_2, - qsfp_rxd_2=qsfp_rxd_2, - qsfp_rxc_2=qsfp_rxc_2, - qsfp_txd_3=qsfp_txd_3, - qsfp_txc_3=qsfp_txc_3, - qsfp_rxd_3=qsfp_rxd_3, - qsfp_rxc_3=qsfp_rxc_3, - qsfp_txd_4=qsfp_txd_4, - qsfp_txc_4=qsfp_txc_4, - qsfp_rxd_4=qsfp_rxd_4, - qsfp_rxc_4=qsfp_rxc_4, - - phy_gmii_clk=phy_gmii_clk, - phy_gmii_rst=phy_gmii_rst, - phy_gmii_rxd=phy_gmii_rxd, - phy_gmii_rx_dv=phy_gmii_rx_dv, - phy_gmii_rx_er=phy_gmii_rx_er, - phy_gmii_txd=phy_gmii_txd, - phy_gmii_tx_en=phy_gmii_tx_en, - phy_gmii_tx_er=phy_gmii_tx_er, - phy_reset_n=phy_reset_n, - phy_int_n=phy_int_n, - - uart_rxd=uart_rxd, - uart_txd=uart_txd, - uart_rts=uart_rts, - uart_cts=uart_cts) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -229,134 +132,103 @@ def bench(): uart_rts = Signal(bool(0)) # sources and sinks - xgmii_1_source_queue = Queue() - xgmii_1_sink_queue = Queue() - xgmii_2_source_queue = Queue() - xgmii_2_sink_queue = Queue() - xgmii_3_source_queue = Queue() - xgmii_3_sink_queue = Queue() - xgmii_4_source_queue = Queue() - xgmii_4_sink_queue = Queue() - gmii_source_queue = Queue() - gmii_sink_queue = Queue() + qsfp_1_source = xgmii_ep.XGMIISource() + qsfp_1_source_logic = qsfp_1_source.create_logic(clk, rst, txd=qsfp_rxd_1, txc=qsfp_rxc_1, name='qsfp_1_source') - xgmii_1_source = xgmii_ep.XGMIISource(clk, - rst, - txd=qsfp_rxd_1, - txc=qsfp_rxc_1, - fifo=xgmii_1_source_queue, - name='xgmii_1_source') + qsfp_1_sink = xgmii_ep.XGMIISink() + qsfp_1_sink_logic = qsfp_1_sink.create_logic(clk, rst, rxd=qsfp_txd_1, rxc=qsfp_txc_1, name='qsfp_1_sink') - xgmii_1_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=qsfp_txd_1, - rxc=qsfp_txc_1, - fifo=xgmii_1_sink_queue, - name='xgmii_1_sink') + qsfp_2_source = xgmii_ep.XGMIISource() + qsfp_2_source_logic = qsfp_2_source.create_logic(clk, rst, txd=qsfp_rxd_2, txc=qsfp_rxc_2, name='qsfp_2_source') - xgmii_2_source = xgmii_ep.XGMIISource(clk, - rst, - txd=qsfp_rxd_2, - txc=qsfp_rxc_2, - fifo=xgmii_2_source_queue, - name='xgmii_2_source') + qsfp_2_sink = xgmii_ep.XGMIISink() + qsfp_2_sink_logic = qsfp_2_sink.create_logic(clk, rst, rxd=qsfp_txd_2, rxc=qsfp_txc_2, name='qsfp_2_sink') - xgmii_2_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=qsfp_txd_2, - rxc=qsfp_txc_2, - fifo=xgmii_2_sink_queue, - name='xgmii_2_sink') + qsfp_3_source = xgmii_ep.XGMIISource() + qsfp_3_source_logic = qsfp_3_source.create_logic(clk, rst, txd=qsfp_rxd_3, txc=qsfp_rxc_3, name='qsfp_3_source') - xgmii_3_source = xgmii_ep.XGMIISource(clk, - rst, - txd=qsfp_rxd_3, - txc=qsfp_rxc_3, - fifo=xgmii_3_source_queue, - name='xgmii_3_source') + qsfp_3_sink = xgmii_ep.XGMIISink() + qsfp_3_sink_logic = qsfp_3_sink.create_logic(clk, rst, rxd=qsfp_txd_3, rxc=qsfp_txc_3, name='qsfp_3_sink') - xgmii_3_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=qsfp_txd_3, - rxc=qsfp_txc_3, - fifo=xgmii_3_sink_queue, - name='xgmii_3_sink') + qsfp_4_source = xgmii_ep.XGMIISource() + qsfp_4_source_logic = qsfp_4_source.create_logic(clk, rst, txd=qsfp_rxd_4, txc=qsfp_rxc_4, name='qsfp_4_source') - xgmii_4_source = xgmii_ep.XGMIISource(clk, - rst, - txd=qsfp_rxd_4, - txc=qsfp_rxc_4, - fifo=xgmii_4_source_queue, - name='xgmii_4_source') + qsfp_4_sink = xgmii_ep.XGMIISink() + qsfp_4_sink_logic = qsfp_4_sink.create_logic(clk, rst, rxd=qsfp_txd_4, rxc=qsfp_txc_4, name='qsfp_4_sink') - xgmii_4_sink = xgmii_ep.XGMIISink(clk, - rst, - rxd=qsfp_txd_4, - rxc=qsfp_txc_4, - fifo=xgmii_4_sink_queue, - name='xgmii_4_sink') + gmii_source = gmii_ep.GMIISource() - gmii_source = gmii_ep.GMIISource(phy_gmii_clk, - phy_gmii_rst, - txd=phy_gmii_rxd, - tx_en=phy_gmii_rx_dv, - tx_er=phy_gmii_rx_er, - fifo=gmii_source_queue, - name='gmii_source') + gmii_source_logic = gmii_source.create_logic( + phy_gmii_clk, + phy_gmii_rst, + txd=phy_gmii_rxd, + tx_en=phy_gmii_rx_dv, + tx_er=phy_gmii_rx_er, + name='gmii_source' + ) - gmii_sink = gmii_ep.GMIISink(phy_gmii_clk, - phy_gmii_rst, - rxd=phy_gmii_txd, - rx_dv=phy_gmii_tx_en, - rx_er=phy_gmii_tx_er, - fifo=gmii_sink_queue, - name='gmii_sink') + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + phy_gmii_clk, + phy_gmii_rst, + rxd=phy_gmii_txd, + rx_dv=phy_gmii_tx_en, + rx_er=phy_gmii_tx_er, + name='gmii_sink' + ) # DUT - dut = dut_fpga_core(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - led, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - qsfp_txd_1, - qsfp_txc_1, - qsfp_rxd_1, - qsfp_rxc_1, - qsfp_txd_2, - qsfp_txc_2, - qsfp_rxd_2, - qsfp_rxc_2, - qsfp_txd_3, - qsfp_txc_3, - qsfp_rxd_3, - qsfp_rxc_3, - qsfp_txd_4, - qsfp_txc_4, - qsfp_rxd_4, - qsfp_rxc_4, + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, - phy_gmii_clk, - phy_gmii_rst, - phy_gmii_rxd, - phy_gmii_rx_dv, - phy_gmii_rx_er, - phy_gmii_txd, - phy_gmii_tx_en, - phy_gmii_tx_er, - phy_reset_n, - phy_int_n, + qsfp_txd_1=qsfp_txd_1, + qsfp_txc_1=qsfp_txc_1, + qsfp_rxd_1=qsfp_rxd_1, + qsfp_rxc_1=qsfp_rxc_1, + qsfp_txd_2=qsfp_txd_2, + qsfp_txc_2=qsfp_txc_2, + qsfp_rxd_2=qsfp_rxd_2, + qsfp_rxc_2=qsfp_rxc_2, + qsfp_txd_3=qsfp_txd_3, + qsfp_txc_3=qsfp_txc_3, + qsfp_rxd_3=qsfp_rxd_3, + qsfp_rxc_3=qsfp_rxc_3, + qsfp_txd_4=qsfp_txd_4, + qsfp_txc_4=qsfp_txc_4, + qsfp_rxd_4=qsfp_rxd_4, + qsfp_rxc_4=qsfp_rxc_4, - uart_rxd, - uart_txd, - uart_rts, - uart_cts) + phy_gmii_clk=phy_gmii_clk, + phy_gmii_rst=phy_gmii_rst, + phy_gmii_rxd=phy_gmii_rxd, + phy_gmii_rx_dv=phy_gmii_rx_dv, + phy_gmii_rx_er=phy_gmii_rx_er, + phy_gmii_txd=phy_gmii_txd, + phy_gmii_tx_en=phy_gmii_tx_en, + phy_gmii_tx_er=phy_gmii_tx_er, + phy_reset_n=phy_reset_n, + phy_int_n=phy_int_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts + ) @always(delay(4)) def clkgen(): @@ -404,13 +276,13 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - xgmii_1_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + qsfp_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) # wait for ARP request packet - while xgmii_1_sink_queue.empty(): + while qsfp_1_sink.empty(): yield clk.posedge - rx_frame = xgmii_1_sink_queue.get(False) + rx_frame = qsfp_1_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = arp_ep.ARPFrame() @@ -446,12 +318,12 @@ def bench(): arp_frame.arp_tha = 0x020000000000 arp_frame.arp_tpa = 0xc0a80180 - xgmii_1_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + qsfp_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) - while xgmii_1_sink_queue.empty(): + while qsfp_1_sink.empty(): yield clk.posedge - rx_frame = xgmii_1_sink_queue.get(False) + rx_frame = qsfp_1_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = udp_ep.UDPFrame() @@ -477,8 +349,8 @@ def bench(): assert check_frame.udp_dest_port == 5678 assert check_frame.payload.data == bytearray(range(32)) - assert xgmii_1_source_queue.empty() - assert xgmii_1_sink_queue.empty() + assert qsfp_1_source.empty() + assert qsfp_1_sink.empty() yield delay(100) @@ -510,18 +382,18 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) # loop packet back through on XGMII interface - while xgmii_1_sink_queue.empty(): + while qsfp_1_sink.empty(): yield clk.posedge - xgmii_1_source_queue.put(xgmii_1_sink_queue.get()) + qsfp_1_source.send(qsfp_1_sink.recv()) - while gmii_sink_queue.empty(): + while gmii_sink.empty(): yield clk.posedge - rx_frame = gmii_sink_queue.get(False) + rx_frame = gmii_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = udp_ep.UDPFrame() @@ -547,10 +419,10 @@ def bench(): assert check_frame.udp_dest_port == 5678 assert check_frame.payload.data == bytearray(range(32)) - assert gmii_source_queue.empty() - assert gmii_sink_queue.empty() - assert xgmii_1_source_queue.empty() - assert xgmii_1_sink_queue.empty() + assert gmii_source.empty() + assert gmii_sink.empty() + assert qsfp_1_source.empty() + assert qsfp_1_sink.empty() yield delay(100) @@ -578,18 +450,18 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) # loop packet back through on XGMII interface - while xgmii_1_sink_queue.empty(): + while qsfp_1_sink.empty(): yield clk.posedge - xgmii_1_source_queue.put(xgmii_1_sink_queue.get()) + qsfp_1_source.send(qsfp_1_sink.recv()) - while gmii_sink_queue.empty(): + while gmii_sink.empty(): yield clk.posedge - rx_frame = gmii_sink_queue.get(False) + rx_frame = gmii_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = udp_ep.UDPFrame() @@ -615,16 +487,16 @@ def bench(): assert check_frame.udp_dest_port == 5678 assert check_frame.payload.data == bytearray(range(32)) - assert gmii_source_queue.empty() - assert gmii_sink_queue.empty() - assert xgmii_1_source_queue.empty() - assert xgmii_1_sink_queue.empty() + assert gmii_source.empty() + assert gmii_sink.empty() + assert qsfp_1_source.empty() + assert qsfp_1_sink.empty() yield delay(100) raise StopSimulation - return dut, xgmii_1_source, xgmii_1_sink, xgmii_2_source, xgmii_2_sink, xgmii_3_source, xgmii_3_sink, xgmii_4_source, xgmii_4_sink, gmii_source, gmii_sink, clkgen, check + return dut, qsfp_1_source_logic, qsfp_1_sink_logic, qsfp_2_source_logic, qsfp_2_sink_logic, qsfp_3_source_logic, qsfp_3_sink_logic, qsfp_4_source_logic, qsfp_4_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.v b/example/VCU108/fpga_10g/tb/test_fpga_core.v index 45f79af87..0f46108df 100644 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.v @@ -81,46 +81,50 @@ wire uart_rts; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - qsfp_rxd_1, - qsfp_rxc_1, - qsfp_rxd_2, - qsfp_rxc_2, - qsfp_rxd_3, - qsfp_rxc_3, - qsfp_rxd_4, - qsfp_rxc_4, - phy_gmii_clk, - phy_gmii_rst, - phy_gmii_rxd, - phy_gmii_rx_dv, - phy_gmii_rx_er, - phy_int_n, - uart_rxd, - uart_cts); - $to_myhdl(led, - qsfp_txd_1, - qsfp_txc_1, - qsfp_txd_2, - qsfp_txc_2, - qsfp_txd_3, - qsfp_txc_3, - qsfp_txd_4, - qsfp_txc_4, - phy_gmii_txd, - phy_gmii_tx_en, - phy_gmii_tx_er, - phy_reset_n, - uart_txd, - uart_rts); + $from_myhdl( + clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + qsfp_rxd_1, + qsfp_rxc_1, + qsfp_rxd_2, + qsfp_rxc_2, + qsfp_rxd_3, + qsfp_rxc_3, + qsfp_rxd_4, + qsfp_rxc_4, + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_int_n, + uart_rxd, + uart_cts + ); + $to_myhdl( + led, + qsfp_txd_1, + qsfp_txc_1, + qsfp_txd_2, + qsfp_txc_2, + qsfp_txd_3, + qsfp_txc_3, + qsfp_txd_4, + qsfp_txc_4, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + uart_txd, + uart_rts + ); // dump file $dumpfile("test_fpga_core.lxt"); diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py index 10bcfe5c4..6f6689f21 100755 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -26,17 +26,13 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import eth_ep import arp_ep import udp_ep import gmii_ep module = 'fpga_core' +testbench = 'test_%s' % module srcs = [] @@ -68,70 +64,11 @@ srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_fpga_core(clk, - rst, - - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - led, - - phy_gmii_clk, - phy_gmii_rst, - phy_gmii_rxd, - phy_gmii_rx_dv, - phy_gmii_rx_er, - phy_gmii_txd, - phy_gmii_tx_en, - phy_gmii_tx_er, - phy_reset_n, - phy_int_n, - - uart_rxd, - uart_txd, - uart_rts, - uart_cts): - - 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, - - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - - phy_gmii_clk=phy_gmii_clk, - phy_gmii_rst=phy_gmii_rst, - phy_gmii_rxd=phy_gmii_rxd, - phy_gmii_rx_dv=phy_gmii_rx_dv, - phy_gmii_rx_er=phy_gmii_rx_er, - phy_gmii_txd=phy_gmii_txd, - phy_gmii_tx_en=phy_gmii_tx_en, - phy_gmii_tx_er=phy_gmii_tx_er, - phy_reset_n=phy_reset_n, - phy_int_n=phy_int_n, - - uart_rxd=uart_rxd, - uart_txd=uart_txd, - uart_rts=uart_rts, - uart_cts=uart_cts) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -167,53 +104,62 @@ def bench(): uart_rts = Signal(bool(0)) # sources and sinks - gmii_source_queue = Queue() - gmii_sink_queue = Queue() + gmii_source = gmii_ep.GMIISource() - gmii_source = gmii_ep.GMIISource(phy_gmii_clk, - phy_gmii_rst, - txd=phy_gmii_rxd, - tx_en=phy_gmii_rx_dv, - tx_er=phy_gmii_rx_er, - fifo=gmii_source_queue, - name='gmii_source') + gmii_source_logic = gmii_source.create_logic( + phy_gmii_clk, + phy_gmii_rst, + txd=phy_gmii_rxd, + tx_en=phy_gmii_rx_dv, + tx_er=phy_gmii_rx_er, + name='gmii_source' + ) - gmii_sink = gmii_ep.GMIISink(phy_gmii_clk, - phy_gmii_rst, - rxd=phy_gmii_txd, - rx_dv=phy_gmii_tx_en, - rx_er=phy_gmii_tx_er, - fifo=gmii_sink_queue, - name='gmii_sink') + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + phy_gmii_clk, + phy_gmii_rst, + rxd=phy_gmii_txd, + rx_dv=phy_gmii_tx_en, + rx_er=phy_gmii_tx_er, + name='gmii_sink' + ) # DUT - dut = dut_fpga_core(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - led, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - phy_gmii_clk, - phy_gmii_rst, - phy_gmii_rxd, - phy_gmii_rx_dv, - phy_gmii_rx_er, - phy_gmii_txd, - phy_gmii_tx_en, - phy_gmii_tx_er, - phy_reset_n, - phy_int_n, + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, - uart_rxd, - uart_txd, - uart_rts, - uart_cts) + phy_gmii_clk=phy_gmii_clk, + phy_gmii_rst=phy_gmii_rst, + phy_gmii_rxd=phy_gmii_rxd, + phy_gmii_rx_dv=phy_gmii_rx_dv, + phy_gmii_rx_er=phy_gmii_rx_er, + phy_gmii_txd=phy_gmii_txd, + phy_gmii_tx_en=phy_gmii_tx_en, + phy_gmii_tx_er=phy_gmii_tx_er, + phy_reset_n=phy_reset_n, + phy_int_n=phy_int_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts + ) @always(delay(4)) def clkgen(): @@ -261,13 +207,13 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) # wait for ARP request packet - while gmii_sink_queue.empty(): + while gmii_sink.empty(): yield clk.posedge - rx_frame = gmii_sink_queue.get(False) + rx_frame = gmii_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = arp_ep.ARPFrame() @@ -303,12 +249,12 @@ def bench(): arp_frame.arp_tha = 0x020000000000 arp_frame.arp_tpa = 0xc0a80180 - gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) - while gmii_sink_queue.empty(): + while gmii_sink.empty(): yield clk.posedge - rx_frame = gmii_sink_queue.get(False) + rx_frame = gmii_sink.recv() check_eth_frame = eth_ep.EthFrame() check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) check_frame = udp_ep.UDPFrame() @@ -334,14 +280,14 @@ def bench(): assert check_frame.udp_dest_port == 5678 assert check_frame.payload.data == bytearray(range(32)) - assert gmii_source_queue.empty() - assert gmii_sink_queue.empty() + assert gmii_source.empty() + assert gmii_sink.empty() yield delay(100) raise StopSimulation - return dut, gmii_source, gmii_sink, clkgen, check + return dut, gmii_source_logic, gmii_sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.v b/example/VCU108/fpga_1g/tb/test_fpga_core.v index 4f39a409f..e3a75d19e 100644 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.v @@ -65,30 +65,34 @@ wire uart_rts; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - phy_gmii_clk, - phy_gmii_rst, - phy_gmii_rxd, - phy_gmii_rx_dv, - phy_gmii_rx_er, - phy_int_n, - uart_rxd, - uart_cts); - $to_myhdl(led, - phy_gmii_txd, - phy_gmii_tx_en, - phy_gmii_tx_er, - phy_reset_n, - uart_txd, - uart_rts); + $from_myhdl( + clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_int_n, + uart_rxd, + uart_cts + ); + $to_myhdl( + led, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + uart_txd, + uart_rts + ); // dump file $dumpfile("test_fpga_core.lxt"); diff --git a/tb/arp_ep.py b/tb/arp_ep.py index 209ec2862..170a10600 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -27,11 +27,6 @@ import axis_ep import eth_ep import struct -try: - from queue import Queue -except ImportError: - from Queue import Queue - class ARPFrame(object): def __init__(self, eth_dest_mac=0, @@ -154,130 +149,166 @@ class ARPFrame(object): ('arp_tha=0x%012x, ' % self.arp_tha) + ('arp_tpa=0x%08x)' % self.arp_tpa)) -def ARPFrameSource(clk, rst, - frame_valid=None, - frame_ready=None, - eth_dest_mac=Signal(intbv(0)[48:]), - eth_src_mac=Signal(intbv(0)[48:]), - eth_type=Signal(intbv(0)[16:]), - arp_htype=Signal(intbv(0)[16:]), - arp_ptype=Signal(intbv(0)[16:]), - arp_hlen=Signal(intbv(6)[8:]), - arp_plen=Signal(intbv(4)[8:]), - arp_oper=Signal(intbv(0)[16:]), - arp_sha=Signal(intbv(0)[48:]), - arp_spa=Signal(intbv(0)[32:]), - arp_tha=Signal(intbv(0)[48:]), - arp_tpa=Signal(intbv(0)[32:]), - fifo=None, - pause=0, - name=None): - frame_ready_int = Signal(bool(False)) - frame_valid_int = Signal(bool(False)) +class ARPFrameSource(): + def __init__(self): + self.has_logic = False + self.queue = [] - @always_comb - def pause_logic(): - frame_ready_int.next = frame_ready and not pause - frame_valid.next = frame_valid_int and not pause + def send(self, frame): + self.queue.append(ARPFrame(frame)) - @instance - def logic(): - frame = dict() + def count(self): + return len(self.queue) - while True: - yield clk.posedge, rst.posedge + def empty(self): + return self.count() == 0 - if rst: - frame_valid_int.next = False - else: - if frame_ready_int: + def create_logic(self, + clk, + rst, + frame_valid=None, + frame_ready=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + arp_htype=Signal(intbv(0)[16:]), + arp_ptype=Signal(intbv(0)[16:]), + arp_hlen=Signal(intbv(6)[8:]), + arp_plen=Signal(intbv(4)[8:]), + arp_oper=Signal(intbv(0)[16:]), + arp_sha=Signal(intbv(0)[48:]), + arp_spa=Signal(intbv(0)[32:]), + arp_tha=Signal(intbv(0)[48:]), + arp_tpa=Signal(intbv(0)[32:]), + pause=0, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + frame_ready_int = Signal(bool(False)) + frame_valid_int = Signal(bool(False)) + + @always_comb + def pause_logic(): + frame_ready_int.next = frame_ready and not pause + frame_valid.next = frame_valid_int and not pause + + @instance + def logic(): + frame = dict() + + while True: + yield clk.posedge, rst.posedge + + if rst: frame_valid_int.next = False - if (frame_ready_int and frame_valid) or not frame_valid_int: - if not fifo.empty(): - frame = fifo.get() - frame = ARPFrame(frame) - eth_dest_mac.next = frame.eth_dest_mac - eth_src_mac.next = frame.eth_src_mac - eth_type.next = frame.eth_type - arp_htype.next = frame.arp_htype - arp_ptype.next = frame.arp_ptype - arp_hlen.next = frame.arp_hlen - arp_plen.next = frame.arp_plen - arp_oper.next = frame.arp_oper - arp_sha.next = frame.arp_sha - arp_spa.next = frame.arp_spa - arp_tha.next = frame.arp_tha - arp_tpa.next = frame.arp_tpa + else: + if frame_ready_int: + frame_valid_int.next = False + if (frame_ready_int and frame_valid) or not frame_valid_int: + if len(self.queue) > 0: + frame = self.queue.pop(0) + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + arp_htype.next = frame.arp_htype + arp_ptype.next = frame.arp_ptype + arp_hlen.next = frame.arp_hlen + arp_plen.next = frame.arp_plen + arp_oper.next = frame.arp_oper + arp_sha.next = frame.arp_sha + arp_spa.next = frame.arp_spa + arp_tha.next = frame.arp_tha + arp_tpa.next = frame.arp_tpa + + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + + frame_valid_int.next = True + + return logic, pause_logic + + +class ARPFrameSink(): + def __init__(self): + self.has_logic = False + self.queue = [] + + def recv(self): + if len(self.queue) > 0: + return self.queue.pop(0) + + def count(self): + return len(self.queue) + + def empty(self): + return self.count() == 0 + + def create_logic(self, + clk, + rst, + frame_valid=None, + frame_ready=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + arp_htype=Signal(intbv(0)[16:]), + arp_ptype=Signal(intbv(0)[16:]), + arp_hlen=Signal(intbv(6)[8:]), + arp_plen=Signal(intbv(4)[8:]), + arp_oper=Signal(intbv(0)[16:]), + arp_sha=Signal(intbv(0)[48:]), + arp_spa=Signal(intbv(0)[32:]), + arp_tha=Signal(intbv(0)[48:]), + arp_tpa=Signal(intbv(0)[32:]), + pause=0, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + frame_ready_int = Signal(bool(False)) + frame_valid_int = Signal(bool(False)) + + @always_comb + def pause_logic(): + frame_ready.next = frame_ready_int and not pause + frame_valid_int.next = frame_valid and not pause + + @instance + def logic(): + while True: + yield clk.posedge, rst.posedge + + if rst: + frame_ready_int.next = False + else: + frame_ready_int.next = True + + if frame_ready_int and frame_valid_int: + frame = ARPFrame() + frame.eth_dest_mac = int(eth_dest_mac) + frame.eth_src_mac = int(eth_src_mac) + frame.eth_type = int(eth_type) + frame.arp_htype = int(arp_htype) + frame.arp_ptype = int(arp_ptype) + frame.arp_hlen = int(arp_hlen) + frame.arp_plen = int(arp_plen) + frame.arp_oper = int(arp_oper) + frame.arp_sha = int(arp_sha) + frame.arp_spa = int(arp_spa) + frame.arp_tha = int(arp_tha) + frame.arp_tpa = int(arp_tpa) + self.queue.append(frame) if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) + print("[%s] Got frame %s" % (name, repr(frame))) - frame_valid_int.next = True - - return logic, pause_logic - - -def ARPFrameSink(clk, rst, - frame_valid=None, - frame_ready=None, - eth_dest_mac=Signal(intbv(0)[48:]), - eth_src_mac=Signal(intbv(0)[48:]), - eth_type=Signal(intbv(0)[16:]), - arp_htype=Signal(intbv(0)[16:]), - arp_ptype=Signal(intbv(0)[16:]), - arp_hlen=Signal(intbv(6)[8:]), - arp_plen=Signal(intbv(4)[8:]), - arp_oper=Signal(intbv(0)[16:]), - arp_sha=Signal(intbv(0)[48:]), - arp_spa=Signal(intbv(0)[32:]), - arp_tha=Signal(intbv(0)[48:]), - arp_tpa=Signal(intbv(0)[32:]), - fifo=None, - pause=0, - name=None): - - frame_ready_int = Signal(bool(False)) - frame_valid_int = Signal(bool(False)) - - @always_comb - def pause_logic(): - frame_ready.next = frame_ready_int and not pause - frame_valid_int.next = frame_valid and not pause - - @instance - def logic(): - frame = ARPFrame() - - while True: - yield clk.posedge, rst.posedge - - if rst: - frame_ready_int.next = False - frame = ARPFrame() - else: - frame_ready_int.next = True - - if frame_ready_int and frame_valid_int: - frame = ARPFrame() - frame.eth_dest_mac = int(eth_dest_mac) - frame.eth_src_mac = int(eth_src_mac) - frame.eth_type = int(eth_type) - frame.arp_htype = int(arp_htype) - frame.arp_ptype = int(arp_ptype) - frame.arp_hlen = int(arp_hlen) - frame.arp_plen = int(arp_plen) - frame.arp_oper = int(arp_oper) - frame.arp_sha = int(arp_sha) - frame.arp_spa = int(arp_spa) - frame.arp_tha = int(arp_tha) - frame.arp_tpa = int(arp_tpa) - fifo.put(frame) - - if name is not None: - print("[%s] Got frame %s" % (name, repr(frame))) - - frame = dict() - - return logic, pause_logic + return logic, pause_logic diff --git a/tb/eth_ep.py b/tb/eth_ep.py index 0dc611e90..160c4265f 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -27,11 +27,6 @@ import axis_ep import struct import zlib -try: - from queue import Queue -except ImportError: - from Queue import Queue - class EthFrame(object): def __init__(self, payload=b'', eth_dest_mac=0, eth_src_mac=0, eth_type=0, eth_fcs=None): self._payload = axis_ep.AXIStreamFrame() @@ -121,143 +116,181 @@ class EthFrame(object): fcs = '0x%08x' % self.eth_fcs return 'EthFrame(payload=%s, eth_dest_mac=0x%012x, eth_src_mac=0x%012x, eth_type=0x%04x, eth_fcs=%s)' % (repr(self.payload), self.eth_dest_mac, self.eth_src_mac, self.eth_type, fcs) -def EthFrameSource(clk, rst, - eth_hdr_valid=None, - eth_hdr_ready=None, - eth_dest_mac=Signal(intbv(0)[48:]), - eth_src_mac=Signal(intbv(0)[48:]), - eth_type=Signal(intbv(0)[16:]), - eth_payload_tdata=None, - eth_payload_tkeep=Signal(bool(True)), - eth_payload_tvalid=Signal(bool(False)), - eth_payload_tready=Signal(bool(True)), - eth_payload_tlast=Signal(bool(False)), - eth_payload_tuser=Signal(bool(False)), - fifo=None, - pause=0, - name=None): - eth_hdr_ready_int = Signal(bool(False)) - eth_hdr_valid_int = Signal(bool(False)) - eth_payload_pause = Signal(bool(False)) +class EthFrameSource(): + def __init__(self): + self.has_logic = False + self.queue = [] + self.payload_source = axis_ep.AXIStreamSource() - eth_payload_fifo = Queue() + def send(self, frame): + self.queue.append(EthFrame(frame)) - eth_payload_source = axis_ep.AXIStreamSource(clk, - rst, - tdata=eth_payload_tdata, - tkeep=eth_payload_tkeep, - tvalid=eth_payload_tvalid, - tready=eth_payload_tready, - tlast=eth_payload_tlast, - tuser=eth_payload_tuser, - fifo=eth_payload_fifo, - pause=eth_payload_pause) + def count(self): + return len(self.queue) - @always_comb - def pause_logic(): - eth_hdr_ready_int.next = eth_hdr_ready and not pause - eth_hdr_valid.next = eth_hdr_valid_int and not pause - eth_payload_pause.next = pause # or eth_hdr_valid_int + def empty(self): + return self.count() == 0 - @instance - def logic(): - frame = dict() + def create_logic(self, + clk, + rst, + eth_hdr_valid=None, + eth_hdr_ready=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + eth_payload_tdata=None, + eth_payload_tkeep=Signal(bool(True)), + eth_payload_tvalid=Signal(bool(False)), + eth_payload_tready=Signal(bool(True)), + eth_payload_tlast=Signal(bool(False)), + eth_payload_tuser=Signal(bool(False)), + pause=0, + name=None + ): - while True: - yield clk.posedge, rst.posedge + assert not self.has_logic - if rst: - eth_hdr_valid_int.next = False - else: - if eth_hdr_ready_int: + self.has_logic = True + + eth_hdr_ready_int = Signal(bool(False)) + eth_hdr_valid_int = Signal(bool(False)) + eth_payload_pause = Signal(bool(False)) + + eth_payload_source = self.payload_source.create_logic( + clk=clk, + rst=rst, + tdata=eth_payload_tdata, + tkeep=eth_payload_tkeep, + tvalid=eth_payload_tvalid, + tready=eth_payload_tready, + tlast=eth_payload_tlast, + tuser=eth_payload_tuser, + pause=eth_payload_pause, + ) + + @always_comb + def pause_logic(): + eth_hdr_ready_int.next = eth_hdr_ready and not pause + eth_hdr_valid.next = eth_hdr_valid_int and not pause + eth_payload_pause.next = pause # or eth_hdr_valid_int + + @instance + def logic(): + frame = EthFrame() + + while True: + yield clk.posedge, rst.posedge + + if rst: eth_hdr_valid_int.next = False - if (eth_payload_tlast and eth_hdr_ready_int and eth_hdr_valid) or not eth_hdr_valid_int: - if not fifo.empty(): - frame = fifo.get() - frame = EthFrame(frame) - eth_dest_mac.next = frame.eth_dest_mac - eth_src_mac.next = frame.eth_src_mac - eth_type.next = frame.eth_type - eth_payload_fifo.put(frame.payload) + else: + if eth_hdr_ready_int: + eth_hdr_valid_int.next = False + if (eth_payload_tlast and eth_hdr_ready_int and eth_hdr_valid) or not eth_hdr_valid_int: + if len(self.queue) > 0: + frame = self.queue.pop(0) + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + self.payload_source.send(frame.payload) + + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + + eth_hdr_valid_int.next = True + + return logic, pause_logic, eth_payload_source + + +class EthFrameSink(): + def __init__(self): + self.has_logic = False + self.queue = [] + self.payload_sink = axis_ep.AXIStreamSink() + + def recv(self): + if len(self.queue) > 0: + return self.queue.pop(0) + return None + + def count(self): + return len(self.queue) + + def empty(self): + return self.count() == 0 + + def create_logic(self, + clk, + rst, + eth_hdr_valid=None, + eth_hdr_ready=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + eth_payload_tdata=None, + eth_payload_tkeep=Signal(bool(True)), + eth_payload_tvalid=Signal(bool(True)), + eth_payload_tready=Signal(bool(True)), + eth_payload_tlast=Signal(bool(True)), + eth_payload_tuser=Signal(bool(False)), + pause=0, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + eth_hdr_ready_int = Signal(bool(False)) + eth_hdr_valid_int = Signal(bool(False)) + eth_payload_pause = Signal(bool(False)) + + eth_header_queue = [] + + eth_payload_sink = self.payload_sink.create_logic( + clk=clk, + rst=rst, + tdata=eth_payload_tdata, + tkeep=eth_payload_tkeep, + tvalid=eth_payload_tvalid, + tready=eth_payload_tready, + tlast=eth_payload_tlast, + tuser=eth_payload_tuser, + pause=eth_payload_pause + ) + + @always_comb + def pause_logic(): + eth_hdr_ready.next = eth_hdr_ready_int and not pause + eth_hdr_valid_int.next = eth_hdr_valid and not pause + eth_payload_pause.next = pause # or eth_hdr_valid_int + + @instance + def logic(): + while True: + yield clk.posedge, rst.posedge + + if rst: + eth_hdr_ready_int.next = False + else: + eth_hdr_ready_int.next = True + + if eth_hdr_ready_int and eth_hdr_valid_int: + frame = EthFrame() + frame.eth_dest_mac = int(eth_dest_mac) + frame.eth_src_mac = int(eth_src_mac) + frame.eth_type = int(eth_type) + eth_header_queue.append(frame) + + if not self.payload_sink.empty() and len(eth_header_queue) > 0: + frame = eth_header_queue.pop(0) + frame.payload = self.payload_sink.recv() + self.queue.append(frame) if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) + print("[%s] Got frame %s" % (name, repr(frame))) - eth_hdr_valid_int.next = True - - return logic, pause_logic, eth_payload_source - - -def EthFrameSink(clk, rst, - eth_hdr_valid=None, - eth_hdr_ready=None, - eth_dest_mac=Signal(intbv(0)[48:]), - eth_src_mac=Signal(intbv(0)[48:]), - eth_type=Signal(intbv(0)[16:]), - eth_payload_tdata=None, - eth_payload_tkeep=Signal(bool(True)), - eth_payload_tvalid=Signal(bool(True)), - eth_payload_tready=Signal(bool(True)), - eth_payload_tlast=Signal(bool(True)), - eth_payload_tuser=Signal(bool(False)), - fifo=None, - pause=0, - name=None): - - eth_hdr_ready_int = Signal(bool(False)) - eth_hdr_valid_int = Signal(bool(False)) - eth_payload_pause = Signal(bool(False)) - - eth_payload_fifo = Queue() - eth_header_fifo = Queue() - - eth_payload_sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=eth_payload_tdata, - tkeep=eth_payload_tkeep, - tvalid=eth_payload_tvalid, - tready=eth_payload_tready, - tlast=eth_payload_tlast, - tuser=eth_payload_tuser, - fifo=eth_payload_fifo, - pause=eth_payload_pause) - - @always_comb - def pause_logic(): - eth_hdr_ready.next = eth_hdr_ready_int and not pause - eth_hdr_valid_int.next = eth_hdr_valid and not pause - eth_payload_pause.next = pause # or eth_hdr_valid_int - - @instance - def logic(): - frame = EthFrame() - - while True: - yield clk.posedge, rst.posedge - - if rst: - eth_hdr_ready_int.next = False - frame = EthFrame() - else: - eth_hdr_ready_int.next = True - - if eth_hdr_ready_int and eth_hdr_valid_int: - frame = EthFrame() - frame.eth_dest_mac = int(eth_dest_mac) - frame.eth_src_mac = int(eth_src_mac) - frame.eth_type = int(eth_type) - eth_header_fifo.put(frame) - - if not eth_payload_fifo.empty() and not eth_header_fifo.empty(): - frame = eth_header_fifo.get() - frame.payload = eth_payload_fifo.get() - fifo.put(frame) - - if name is not None: - print("[%s] Got frame %s" % (name, repr(frame))) - - frame = dict() - - return logic, pause_logic, eth_payload_sink + return logic, pause_logic, eth_payload_sink diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index eccbeb398..6c8fb1335 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -81,100 +81,142 @@ class GMIIFrame(object): return self.data.__iter__() -def GMIISource(clk, rst, - txd, - tx_en, - tx_er, - fifo=None, - name=None): +class GMIISource(object): + def __init__(self): + self.has_logic = False + self.queue = [] - assert len(txd) == 8 + def send(self, frame): + self.queue.append(GMIIFrame(frame)) - @instance - def logic(): - frame = None - d = [] - er = [] - ifg_cnt = 0 + def count(self): + return len(self.queue) - while True: - yield clk.posedge, rst.posedge + def empty(self): + return self.count() == 0 - if rst: - frame = None - txd.next = 0 - tx_en.next = 0 - tx_er.next = 0 - d = [] - er = [] - ifg_cnt = 0 - else: - if ifg_cnt > 0: - ifg_cnt -= 1 + def create_logic(self, + clk, + rst, + txd, + tx_en, + tx_er, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + assert len(txd) == 8 + + @instance + def logic(): + frame = None + d = [] + er = [] + ifg_cnt = 0 + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame = None txd.next = 0 - tx_er.next = 0 tx_en.next = 0 - elif len(d) > 0: - txd.next = d.pop(0) - tx_er.next = er.pop(0) - tx_en.next = 1 - if len(d) == 0: - ifg_cnt = 12 - elif not fifo.empty(): - frame = GMIIFrame(fifo.get()) - d, er = frame.build() - if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) - txd.next = d.pop(0) - tx_er.next = er.pop(0) - tx_en.next = 1 + tx_er.next = 0 + d = [] + er = [] + ifg_cnt = 0 else: - txd.next = 0 - tx_er.next = 0 - tx_en.next = 0 - - return logic - - -def GMIISink(clk, rst, - rxd, - rx_dv, - rx_er, - fifo=None, - name=None): - - assert len(rxd) == 8 - - @instance - def logic(): - frame = None - d = [] - er = [] - - while True: - yield clk.posedge, rst.posedge - - if rst: - frame = None - d = [] - er = [] - else: - if rx_dv: - if frame is None: - frame = GMIIFrame() - d = [] - er = [] - d.append(int(rxd)) - er.append(int(rx_er)) - elif frame is not None: - if len(d) > 0: - frame.parse(d, er) - if fifo is not None: - fifo.put(frame) + if ifg_cnt > 0: + ifg_cnt -= 1 + txd.next = 0 + tx_er.next = 0 + tx_en.next = 0 + elif len(d) > 0: + txd.next = d.pop(0) + tx_er.next = er.pop(0) + tx_en.next = 1 + if len(d) == 0: + ifg_cnt = 12 + elif len(self.queue) > 0: + frame = GMIIFrame(self.queue.pop(0)) + d, er = frame.build() if name is not None: - print("[%s] Got frame %s" % (name, repr(frame))) + print("[%s] Sending frame %s" % (name, repr(frame))) + txd.next = d.pop(0) + tx_er.next = er.pop(0) + tx_en.next = 1 + else: + txd.next = 0 + tx_er.next = 0 + tx_en.next = 0 + + return logic + + +class GMIISink(object): + def __init__(self): + self.has_logic = False + self.queue = [] + + def recv(self): + if len(self.queue) > 0: + return self.queue.pop(0) + return None + + def count(self): + return len(self.queue) + + def empty(self): + return self.count() == 0 + + def create_logic(self, + clk, + rst, + rxd, + rx_dv, + rx_er, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + assert len(rxd) == 8 + + @instance + def logic(): + frame = None + d = [] + er = [] + + while True: + yield clk.posedge, rst.posedge + + if rst: frame = None d = [] er = [] + else: + if rx_dv: + if frame is None: + frame = GMIIFrame() + d = [] + er = [] + d.append(int(rxd)) + er.append(int(rx_er)) + elif frame is not None: + if len(d) > 0: + frame.parse(d, er) + self.queue.append(frame) + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + frame = None + d = [] + er = [] + + return logic - return logic diff --git a/tb/ip_ep.py b/tb/ip_ep.py index ec13aa320..e6da44caa 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -27,11 +27,6 @@ import axis_ep import eth_ep import struct -try: - from queue import Queue -except ImportError: - from Queue import Queue - class IPFrame(object): def __init__(self, payload=b'', eth_dest_mac=0, @@ -234,102 +229,150 @@ class IPFrame(object): ('ip_source_ip=0x%08x, ' % self.ip_source_ip) + ('ip_dest_ip=0x%08x)' % self.ip_dest_ip)) -def IPFrameSource(clk, rst, - ip_hdr_valid=None, - ip_hdr_ready=None, - eth_dest_mac=Signal(intbv(0)[48:]), - eth_src_mac=Signal(intbv(0)[48:]), - eth_type=Signal(intbv(0)[16:]), - ip_version=Signal(intbv(4)[4:]), - ip_ihl=Signal(intbv(5)[4:]), - ip_dscp=Signal(intbv(0)[6:]), - ip_ecn=Signal(intbv(0)[2:]), - ip_length=Signal(intbv(0)[16:]), - ip_identification=Signal(intbv(0)[16:]), - ip_flags=Signal(intbv(0)[3:]), - ip_fragment_offset=Signal(intbv(0)[13:]), - ip_ttl=Signal(intbv(0)[8:]), - ip_protocol=Signal(intbv(0)[8:]), - ip_header_checksum=Signal(intbv(0)[16:]), - ip_source_ip=Signal(intbv(0)[32:]), - ip_dest_ip=Signal(intbv(0)[32:]), - ip_payload_tdata=None, - ip_payload_tkeep=Signal(bool(True)), - ip_payload_tvalid=Signal(bool(False)), - ip_payload_tready=Signal(bool(True)), - ip_payload_tlast=Signal(bool(False)), - ip_payload_tuser=Signal(bool(False)), - fifo=None, - pause=0, - name=None): - ip_hdr_ready_int = Signal(bool(False)) - ip_hdr_valid_int = Signal(bool(False)) - ip_payload_pause = Signal(bool(False)) +class IPFrameSource(): + def __init__(self): + self.has_logic = False + self.queue = [] + self.payload_source = axis_ep.AXIStreamSource() + self.header_queue = [] - ip_payload_fifo = Queue() + def send(self, frame): + frame = IPFrame(frame) + if len(self.header_queue) == 0: + self.header_queue.append(frame) + self.payload_source.send(frame.payload) + else: + self.queue.append(frame) - ip_payload_source = axis_ep.AXIStreamSource(clk, - rst, - tdata=ip_payload_tdata, - tkeep=ip_payload_tkeep, - tvalid=ip_payload_tvalid, - tready=ip_payload_tready, - tlast=ip_payload_tlast, - tuser=ip_payload_tuser, - fifo=ip_payload_fifo, - pause=ip_payload_pause) + def count(self): + return len(self.queue) - @always_comb - def pause_logic(): - ip_hdr_ready_int.next = ip_hdr_ready and not pause - ip_hdr_valid.next = ip_hdr_valid_int and not pause - ip_payload_pause.next = pause # or ip_hdr_valid_int + def empty(self): + return self.count() == 0 - @instance - def logic(): - frame = dict() + def create_logic(self, + clk, + rst, + ip_hdr_valid=None, + ip_hdr_ready=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + ip_version=Signal(intbv(4)[4:]), + ip_ihl=Signal(intbv(5)[4:]), + ip_dscp=Signal(intbv(0)[6:]), + ip_ecn=Signal(intbv(0)[2:]), + ip_length=Signal(intbv(0)[16:]), + ip_identification=Signal(intbv(0)[16:]), + ip_flags=Signal(intbv(0)[3:]), + ip_fragment_offset=Signal(intbv(0)[13:]), + ip_ttl=Signal(intbv(0)[8:]), + ip_protocol=Signal(intbv(0)[8:]), + ip_header_checksum=Signal(intbv(0)[16:]), + ip_source_ip=Signal(intbv(0)[32:]), + ip_dest_ip=Signal(intbv(0)[32:]), + ip_payload_tdata=None, + ip_payload_tkeep=Signal(bool(True)), + ip_payload_tvalid=Signal(bool(False)), + ip_payload_tready=Signal(bool(True)), + ip_payload_tlast=Signal(bool(False)), + ip_payload_tuser=Signal(bool(False)), + pause=0, + name=None + ): - while True: - yield clk.posedge, rst.posedge + assert not self.has_logic - if rst: - ip_hdr_valid_int.next = False - else: - if ip_hdr_ready_int: + self.has_logic = True + + ip_hdr_ready_int = Signal(bool(False)) + ip_hdr_valid_int = Signal(bool(False)) + ip_payload_pause = Signal(bool(False)) + + ip_payload_source = self.payload_source.create_logic( + clk=clk, + rst=rst, + tdata=ip_payload_tdata, + tkeep=ip_payload_tkeep, + tvalid=ip_payload_tvalid, + tready=ip_payload_tready, + tlast=ip_payload_tlast, + tuser=ip_payload_tuser, + pause=ip_payload_pause, + ) + + @always_comb + def pause_logic(): + ip_hdr_ready_int.next = ip_hdr_ready and not pause + ip_hdr_valid.next = ip_hdr_valid_int and not pause + ip_payload_pause.next = pause + + @instance + def logic(): + while True: + yield clk.posedge, rst.posedge + + if rst: ip_hdr_valid_int.next = False - if (ip_payload_tlast and ip_hdr_ready_int and ip_hdr_valid) or not ip_hdr_valid_int: - if not fifo.empty(): - frame = fifo.get() - frame = IPFrame(frame) - frame.build() - eth_dest_mac.next = frame.eth_dest_mac - eth_src_mac.next = frame.eth_src_mac - eth_type.next = frame.eth_type - ip_version.next = frame.ip_version - ip_ihl.next = frame.ip_ihl - ip_dscp.next = frame.ip_dscp - ip_ecn.next = frame.ip_ecn - ip_length.next = frame.ip_length - ip_identification.next = frame.ip_identification - ip_flags.next = frame.ip_flags - ip_fragment_offset.next = frame.ip_fragment_offset - ip_ttl.next = frame.ip_ttl - ip_protocol.next = frame.ip_protocol - ip_header_checksum.next = frame.ip_header_checksum - ip_source_ip.next = frame.ip_source_ip - ip_dest_ip.next = frame.ip_dest_ip - ip_payload_fifo.put(frame.payload) + else: + if ip_hdr_ready_int: + ip_hdr_valid_int.next = False + if (ip_hdr_ready_int and ip_hdr_valid) or not ip_hdr_valid_int: + if len(self.header_queue) > 0: + frame = self.header_queue.pop(0) + frame.build() + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + ip_version.next = frame.ip_version + ip_ihl.next = frame.ip_ihl + ip_dscp.next = frame.ip_dscp + ip_ecn.next = frame.ip_ecn + ip_length.next = frame.ip_length + ip_identification.next = frame.ip_identification + ip_flags.next = frame.ip_flags + ip_fragment_offset.next = frame.ip_fragment_offset + ip_ttl.next = frame.ip_ttl + ip_protocol.next = frame.ip_protocol + ip_header_checksum.next = frame.ip_header_checksum + ip_source_ip.next = frame.ip_source_ip + ip_dest_ip.next = frame.ip_dest_ip - if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) - ip_hdr_valid_int.next = True + ip_hdr_valid_int.next = True - return logic, pause_logic, ip_payload_source + if len(self.queue) > 0 and len(self.header_queue) == 0: + frame = self.queue.pop(0) + self.header_queue.append(frame) + self.payload_source.send(frame.payload) + + return logic, pause_logic, ip_payload_source -def IPFrameSink(clk, rst, +class IPFrameSink(): + def __init__(self): + self.has_logic = False + self.queue = [] + self.payload_sink = axis_ep.AXIStreamSink() + self.header_queue = [] + + def recv(self): + if len(self.queue) > 0: + return self.queue.pop(0) + return None + + def count(self): + return len(self.queue) + + def empty(self): + return self.count() == 0 + + def create_logic(self, + clk, + rst, ip_hdr_valid=None, ip_hdr_ready=None, eth_dest_mac=Signal(intbv(0)[48:]), @@ -354,80 +397,77 @@ def IPFrameSink(clk, rst, ip_payload_tready=Signal(bool(True)), ip_payload_tlast=Signal(bool(True)), ip_payload_tuser=Signal(bool(False)), - fifo=None, pause=0, - name=None): + name=None + ): - ip_hdr_ready_int = Signal(bool(False)) - ip_hdr_valid_int = Signal(bool(False)) - ip_payload_pause = Signal(bool(False)) + assert not self.has_logic - ip_payload_fifo = Queue() - ip_header_fifo = Queue() + self.has_logic = True - ip_payload_sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=ip_payload_tdata, - tkeep=ip_payload_tkeep, - tvalid=ip_payload_tvalid, - tready=ip_payload_tready, - tlast=ip_payload_tlast, - tuser=ip_payload_tuser, - fifo=ip_payload_fifo, - pause=ip_payload_pause) + ip_hdr_ready_int = Signal(bool(False)) + ip_hdr_valid_int = Signal(bool(False)) + ip_payload_pause = Signal(bool(False)) - @always_comb - def pause_logic(): - ip_hdr_ready.next = ip_hdr_ready_int and not pause - ip_hdr_valid_int.next = ip_hdr_valid and not pause - ip_payload_pause.next = pause # or ip_hdr_valid_int + ip_payload_sink = self.payload_sink.create_logic( + clk=clk, + rst=rst, + tdata=ip_payload_tdata, + tkeep=ip_payload_tkeep, + tvalid=ip_payload_tvalid, + tready=ip_payload_tready, + tlast=ip_payload_tlast, + tuser=ip_payload_tuser, + pause=ip_payload_pause + ) - @instance - def logic(): - frame = IPFrame() + @always_comb + def pause_logic(): + ip_hdr_ready.next = ip_hdr_ready_int and not pause + ip_hdr_valid_int.next = ip_hdr_valid and not pause + ip_payload_pause.next = pause # or ip_hdr_valid_int - while True: - yield clk.posedge, rst.posedge + @instance + def logic(): + while True: + yield clk.posedge, rst.posedge - if rst: - ip_hdr_ready_int.next = False - frame = IPFrame() - else: - ip_hdr_ready_int.next = True + if rst: + ip_hdr_ready_int.next = False + else: + ip_hdr_ready_int.next = True - if ip_hdr_ready_int and ip_hdr_valid_int: - frame = IPFrame() - frame.eth_dest_mac = int(eth_dest_mac) - frame.eth_src_mac = int(eth_src_mac) - frame.eth_type = int(eth_type) - frame.ip_version = int(ip_version) - frame.ip_ihl = int(ip_ihl) - frame.ip_dscp = int(ip_dscp) - frame.ip_ecn = int(ip_ecn) - frame.ip_length = int(ip_length) - frame.ip_identification = int(ip_identification) - frame.ip_flags = int(ip_flags) - frame.ip_fragment_offset = int(ip_fragment_offset) - frame.ip_ttl = int(ip_ttl) - frame.ip_protocol = int(ip_protocol) - frame.ip_header_checksum = int(ip_header_checksum) - frame.ip_source_ip = int(ip_source_ip) - frame.ip_dest_ip = int(ip_dest_ip) - ip_header_fifo.put(frame) + if ip_hdr_ready_int and ip_hdr_valid_int: + frame = IPFrame() + frame.eth_dest_mac = int(eth_dest_mac) + frame.eth_src_mac = int(eth_src_mac) + frame.eth_type = int(eth_type) + frame.ip_version = int(ip_version) + frame.ip_ihl = int(ip_ihl) + frame.ip_dscp = int(ip_dscp) + frame.ip_ecn = int(ip_ecn) + frame.ip_length = int(ip_length) + frame.ip_identification = int(ip_identification) + frame.ip_flags = int(ip_flags) + frame.ip_fragment_offset = int(ip_fragment_offset) + frame.ip_ttl = int(ip_ttl) + frame.ip_protocol = int(ip_protocol) + frame.ip_header_checksum = int(ip_header_checksum) + frame.ip_source_ip = int(ip_source_ip) + frame.ip_dest_ip = int(ip_dest_ip) + self.header_queue.append(frame) - if not ip_payload_fifo.empty() and not ip_header_fifo.empty(): - frame = ip_header_fifo.get() - frame.payload = ip_payload_fifo.get() - fifo.put(frame) + if not self.payload_sink.empty() and len(self.header_queue) > 0: + frame = self.header_queue.pop(0) + frame.payload = self.payload_sink.recv() + self.queue.append(frame) - # ensure all payloads have been matched to headers - if ip_header_fifo.empty(): - assert ip_payload_fifo.empty() + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) - if name is not None: - print("[%s] Got frame %s" % (name, repr(frame))) + # ensure all payloads have been matched to headers + if len(self.header_queue) == 0: + assert self.payload_sink.empty() - frame = dict() - - return logic, pause_logic, ip_payload_sink + return logic, pause_logic, ip_payload_sink diff --git a/tb/ll_ep.py b/tb/ll_ep.py deleted file mode 100644 index e480cb65c..000000000 --- a/tb/ll_ep.py +++ /dev/null @@ -1,123 +0,0 @@ -""" - -Copyright (c) 2014-2016 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 - diff --git a/tb/rgmii_ep.py b/tb/rgmii_ep.py index a686c7703..31dd75c08 100644 --- a/tb/rgmii_ep.py +++ b/tb/rgmii_ep.py @@ -26,65 +26,76 @@ from myhdl import * import gmii_ep -def RGMIISource(clk, rst, - txd, - tx_ctl, - fifo=None, - name=None): +class RGMIISource(gmii_ep.GMIISource): + def create_logic(self, + clk, + rst, + txd, + tx_ctl, + name=None + ): - gmii_txd = Signal(intbv(0)[8:]) - gmii_tx_en = Signal(bool(0)) - gmii_tx_er = Signal(bool(0)) + assert not self.has_logic - gmii_txd_reg = Signal(intbv(0)[8:]) - gmii_tx_en_reg = Signal(bool(0)) - gmii_tx_er_reg = Signal(bool(0)) + gmii_txd = Signal(intbv(0)[8:]) + gmii_tx_en = Signal(bool(0)) + gmii_tx_er = Signal(bool(0)) - gmii_source = gmii_ep.GMIISource(clk, rst, gmii_txd, gmii_tx_en, gmii_tx_er, fifo, name) + gmii_txd_reg = Signal(intbv(0)[8:]) + gmii_tx_en_reg = Signal(bool(0)) + gmii_tx_er_reg = Signal(bool(0)) - @instance - def logic(): - while True: - yield clk.negedge - txd.next = gmii_txd_reg[4:0] - tx_ctl.next = gmii_tx_en_reg - yield clk.posedge - txd.next = gmii_txd_reg[8:4] - tx_ctl.next = gmii_tx_en_reg ^ gmii_tx_er_reg - gmii_txd_reg.next = gmii_txd - gmii_tx_en_reg.next = gmii_tx_en - gmii_tx_er_reg.next = gmii_tx_er + gmii_source = super(RGMIISource, self).create_logic(clk, rst, gmii_txd, gmii_tx_en, gmii_tx_er, name) - return gmii_source, logic + @instance + def logic(): + while True: + yield clk.negedge + txd.next = gmii_txd_reg[4:0] + tx_ctl.next = gmii_tx_en_reg + yield clk.posedge + txd.next = gmii_txd_reg[8:4] + tx_ctl.next = gmii_tx_en_reg ^ gmii_tx_er_reg + gmii_txd_reg.next = gmii_txd + gmii_tx_en_reg.next = gmii_tx_en + gmii_tx_er_reg.next = gmii_tx_er + + return gmii_source, logic -def RGMIISink(clk, rst, - rxd, - rx_ctl, - fifo=None, - name=None): +class RGMIISink(gmii_ep.GMIISink): + def create_logic(self, + clk, + rst, + rxd, + rx_ctl, + name=None + ): - gmii_rxd = Signal(intbv(0)[8:]) - gmii_rx_dv = Signal(bool(0)) - gmii_rx_er = Signal(bool(0)) + assert not self.has_logic - gmii_sink = gmii_ep.GMIISink(clk, rst, gmii_rxd, gmii_rx_dv, gmii_rx_er, fifo, name) + gmii_rxd = Signal(intbv(0)[8:]) + gmii_rx_dv = Signal(bool(0)) + gmii_rx_er = Signal(bool(0)) - @instance - def logic(): - dat = 0 - ctl1 = 0 - ctl2 = 0 + gmii_sink = super(RGMIISink, self).create_logic(clk, rst, gmii_rxd, gmii_rx_dv, gmii_rx_er, name) - while True: - yield clk.posedge - gmii_rxd.next = dat - gmii_rx_dv.next = ctl1 - gmii_rx_er.next = ctl1 ^ ctl2 - dat = int(rxd.val) - ctl1 = int(rx_ctl.val) - yield clk.negedge - dat |= int(rxd.val) << 4 - ctl2 = int(rx_ctl.val) + @instance + def logic(): + dat = 0 + ctl1 = 0 + ctl2 = 0 + + while True: + yield clk.posedge + gmii_rxd.next = dat + gmii_rx_dv.next = ctl1 + gmii_rx_er.next = ctl1 ^ ctl2 + dat = int(rxd.val) + ctl1 = int(rx_ctl.val) + yield clk.negedge + dat |= int(rxd.val) << 4 + ctl2 = int(rx_ctl.val) + + return gmii_sink, logic - return gmii_sink, logic diff --git a/tb/test_arp.py b/tb/test_arp.py index 79f6a4eed..61c7d1edd 100755 --- a/tb/test_arp.py +++ b/tb/test_arp.py @@ -26,15 +26,11 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import eth_ep import arp_ep module = 'arp' +testbench = 'test_%s' % module srcs = [] @@ -42,90 +38,11 @@ srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/arp_cache.v") srcs.append("../rtl/arp_eth_rx.v") srcs.append("../rtl/arp_eth_tx.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_arp(clk, - rst, - current_test, - - input_eth_hdr_valid, - input_eth_hdr_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tready, - input_eth_payload_tlast, - input_eth_payload_tuser, - - output_eth_hdr_valid, - output_eth_hdr_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tready, - output_eth_payload_tlast, - output_eth_payload_tuser, - - arp_request_valid, - arp_request_ip, - arp_response_valid, - arp_response_error, - arp_response_mac, - - local_mac, - local_ip, - gateway_ip, - subnet_mask, - clear_cache): - - 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_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, - - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, - - arp_request_valid=arp_request_valid, - arp_request_ip=arp_request_ip, - arp_response_valid=arp_response_valid, - arp_response_error=arp_response_error, - arp_response_mac=arp_response_mac, - - local_mac=local_mac, - local_ip=local_ip, - gateway_ip=gateway_ip, - subnet_mask=subnet_mask, - clear_cache=clear_cache) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -173,81 +90,91 @@ def bench(): arp_response_mac = Signal(intbv(0)[48:]) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source = eth_ep.EthFrameSource(clk, - rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, - fifo=source_queue, - pause=source_pause, - name='source') + source = eth_ep.EthFrameSource() - sink = eth_ep.EthFrameSink(clk, - rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') + source_logic = source.create_logic( + clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + pause=source_pause, + name='source' + ) + + sink = eth_ep.EthFrameSink() + + sink_logic = sink.create_logic( + clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_arp(clk, - rst, - current_test, - - input_eth_hdr_valid, - input_eth_hdr_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tready, - input_eth_payload_tlast, - input_eth_payload_tuser, + if os.system(build_cmd): + raise Exception("Error running build command") - output_eth_hdr_valid, - output_eth_hdr_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tready, - output_eth_payload_tlast, - output_eth_payload_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - arp_request_valid, - arp_request_ip, - arp_response_valid, - arp_response_error, - arp_response_mac, + input_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, - local_mac, - local_ip, - gateway_ip, - subnet_mask, - clear_cache) + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + arp_request_valid=arp_request_valid, + arp_request_ip=arp_request_ip, + arp_response_valid=arp_response_valid, + arp_response_error=arp_response_error, + arp_response_mac=arp_response_mac, + + local_mac=local_mac, + local_ip=local_ip, + gateway_ip=gateway_ip, + subnet_mask=subnet_mask, + clear_cache=clear_cache + ) @always(delay(4)) def clkgen(): @@ -287,14 +214,14 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0x000000000000 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge yield output_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -344,7 +271,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -375,7 +302,7 @@ def bench(): test_frame.arp_spa = 0xc0a80166 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge # wait for lookup @@ -400,7 +327,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -431,7 +358,7 @@ def bench(): test_frame.arp_spa = 0xc0a80101 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge # wait for lookup @@ -455,10 +382,10 @@ def bench(): assert bool(arp_response_error) # check for 4 ARP requests - assert sink_queue.qsize() == 4 + assert sink.count() == 4 - while not sink_queue.empty(): - rx_frame = sink_queue.get(False) + while not sink.empty(): + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -508,7 +435,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp.v b/tb/test_arp.v index 437658754..e7d407700 100644 --- a/tb/test_arp.v +++ b/tb/test_arp.v @@ -24,8 +24,11 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for arp + */ module test_arp; // Inputs @@ -73,39 +76,43 @@ wire [47:0] arp_response_mac; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, - arp_request_valid, - arp_request_ip, - local_mac, - local_ip, - gateway_ip, - subnet_mask, - clear_cache); - $to_myhdl(input_eth_hdr_ready, - input_eth_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, - arp_response_valid, - arp_response_error, - arp_response_mac); + $from_myhdl( + clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + arp_request_valid, + arp_request_ip, + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_cache + ); + $to_myhdl( + input_eth_hdr_ready, + input_eth_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + arp_response_valid, + arp_response_error, + arp_response_mac + ); // dump file $dumpfile("test_arp.lxt"); diff --git a/tb/test_arp_64.py b/tb/test_arp_64.py index efff251a3..b67d3c4d1 100755 --- a/tb/test_arp_64.py +++ b/tb/test_arp_64.py @@ -26,15 +26,11 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import eth_ep import arp_ep module = 'arp_64' +testbench = 'test_%s' % module srcs = [] @@ -42,94 +38,11 @@ srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/arp_cache.v") srcs.append("../rtl/arp_eth_rx_64.v") srcs.append("../rtl/arp_eth_tx_64.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_arp_64(clk, - rst, - current_test, - - input_eth_hdr_valid, - input_eth_hdr_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tready, - input_eth_payload_tlast, - input_eth_payload_tuser, - - output_eth_hdr_valid, - output_eth_hdr_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tready, - output_eth_payload_tlast, - output_eth_payload_tuser, - - arp_request_valid, - arp_request_ip, - arp_response_valid, - arp_response_error, - arp_response_mac, - - local_mac, - local_ip, - gateway_ip, - subnet_mask, - clear_cache): - - 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_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tkeep=input_eth_payload_tkeep, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, - - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, - - arp_request_valid=arp_request_valid, - arp_request_ip=arp_request_ip, - arp_response_valid=arp_response_valid, - arp_response_error=arp_response_error, - arp_response_mac=arp_response_mac, - - local_mac=local_mac, - local_ip=local_ip, - gateway_ip=gateway_ip, - subnet_mask=subnet_mask, - clear_cache=clear_cache) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -179,85 +92,95 @@ def bench(): arp_response_mac = Signal(intbv(0)[48:]) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source = eth_ep.EthFrameSource(clk, - rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tkeep=input_eth_payload_tkeep, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, - fifo=source_queue, - pause=source_pause, - name='source') + source = eth_ep.EthFrameSource() - sink = eth_ep.EthFrameSink(clk, - rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') + source_logic = source.create_logic( + clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + pause=source_pause, + name='source' + ) + + sink = eth_ep.EthFrameSink() + + sink_logic = sink.create_logic( + clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_arp_64(clk, - rst, - current_test, - - input_eth_hdr_valid, - input_eth_hdr_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tready, - input_eth_payload_tlast, - input_eth_payload_tuser, + if os.system(build_cmd): + raise Exception("Error running build command") - output_eth_hdr_valid, - output_eth_hdr_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tready, - output_eth_payload_tlast, - output_eth_payload_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - arp_request_valid, - arp_request_ip, - arp_response_valid, - arp_response_error, - arp_response_mac, + input_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, - local_mac, - local_ip, - gateway_ip, - subnet_mask, - clear_cache) + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + arp_request_valid=arp_request_valid, + arp_request_ip=arp_request_ip, + arp_response_valid=arp_response_valid, + arp_response_error=arp_response_error, + arp_response_mac=arp_response_mac, + + local_mac=local_mac, + local_ip=local_ip, + gateway_ip=gateway_ip, + subnet_mask=subnet_mask, + clear_cache=clear_cache + ) @always(delay(4)) def clkgen(): @@ -297,14 +220,14 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0x000000000000 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge yield output_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -354,7 +277,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -385,7 +308,7 @@ def bench(): test_frame.arp_spa = 0xc0a80166 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge # wait for lookup @@ -410,7 +333,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = sink_queue.get(False) + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -441,7 +364,7 @@ def bench(): test_frame.arp_spa = 0xc0a80101 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge # wait for lookup @@ -465,10 +388,10 @@ def bench(): assert bool(arp_response_error) # check for 4 ARP requests - assert sink_queue.qsize() == 4 + assert sink.count() == 4 - while not sink_queue.empty(): - rx_frame = sink_queue.get(False) + while not sink.empty(): + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -518,7 +441,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp_64.v b/tb/test_arp_64.v index ba9b581c0..f5f031f8c 100644 --- a/tb/test_arp_64.v +++ b/tb/test_arp_64.v @@ -24,8 +24,11 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for arp_64 + */ module test_arp_64; // Inputs @@ -75,41 +78,45 @@ wire [47:0] arp_response_mac; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, - arp_request_valid, - arp_request_ip, - local_mac, - local_ip, - gateway_ip, - subnet_mask, - clear_cache); - $to_myhdl(input_eth_hdr_ready, - input_eth_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, - arp_response_valid, - arp_response_error, - arp_response_mac); + $from_myhdl( + clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + arp_request_valid, + arp_request_ip, + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_cache + ); + $to_myhdl( + input_eth_hdr_ready, + input_eth_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + arp_response_valid, + arp_response_error, + arp_response_mac + ); // dump file $dumpfile("test_arp_64.lxt"); diff --git a/tb/test_arp_cache.py b/tb/test_arp_cache.py index fae91cb66..c843818ab 100755 --- a/tb/test_arp_cache.py +++ b/tb/test_arp_cache.py @@ -27,54 +27,16 @@ from myhdl import * import os module = 'arp_cache' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_arp_cache(clk, - rst, - current_test, - - query_request_valid, - query_request_ip, - query_response_valid, - query_response_error, - query_response_mac, - - write_request_valid, - write_request_ip, - write_request_mac, - write_in_progress, - write_complete, - - clear_cache): - - 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, - - query_request_valid=query_request_valid, - query_request_ip=query_request_ip, - query_response_valid=query_response_valid, - query_response_error=query_response_error, - query_response_mac=query_response_mac, - - write_request_valid=write_request_valid, - write_request_ip=write_request_ip, - write_request_mac=write_request_mac, - write_in_progress=write_in_progress, - write_complete=write_complete, - - clear_cache=clear_cache) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -101,23 +63,29 @@ def bench(): write_complete = Signal(bool(0)) # DUT - dut = dut_arp_cache(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - query_request_valid, - query_request_ip, - query_response_valid, - query_response_error, - query_response_mac, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - write_request_valid, - write_request_ip, - write_request_mac, - write_in_progress, - write_complete, + query_request_valid=query_request_valid, + query_request_ip=query_request_ip, + query_response_valid=query_response_valid, + query_response_error=query_response_error, + query_response_mac=query_response_mac, - clear_cache) + write_request_valid=write_request_valid, + write_request_ip=write_request_ip, + write_request_mac=write_request_mac, + write_in_progress=write_in_progress, + write_complete=write_complete, + + clear_cache=clear_cache + ) @always(delay(4)) def clkgen(): diff --git a/tb/test_arp_cache.v b/tb/test_arp_cache.v index 23f687b46..cf20007f9 100755 --- a/tb/test_arp_cache.v +++ b/tb/test_arp_cache.v @@ -24,8 +24,11 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for arp_cache + */ module test_arp_cache; // Inputs @@ -52,20 +55,24 @@ wire write_complete; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - query_request_valid, - query_request_ip, - write_request_valid, - write_request_ip, - write_request_mac, - clear_cache); - $to_myhdl(query_response_valid, - query_response_error, - query_response_mac, - write_in_progress, - write_complete); + $from_myhdl( + clk, + rst, + current_test, + query_request_valid, + query_request_ip, + write_request_valid, + write_request_ip, + write_request_mac, + clear_cache + ); + $to_myhdl( + query_response_valid, + query_response_error, + query_response_mac, + write_in_progress, + write_complete + ); // dump file $dumpfile("test_arp_cache.lxt"); diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index 8f213a34c..8aa508774 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -26,95 +26,20 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import arp_ep import eth_ep module = 'arp_eth_rx' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_arp_eth_rx(clk, - rst, - current_test, - - input_eth_hdr_valid, - input_eth_hdr_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tready, - input_eth_payload_tlast, - input_eth_payload_tuser, - - output_frame_valid, - output_frame_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_arp_htype, - output_arp_ptype, - output_arp_hlen, - output_arp_plen, - output_arp_oper, - output_arp_sha, - output_arp_spa, - output_arp_tha, - output_arp_tpa, - - busy, - error_header_early_termination, - error_invalid_header): - - 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_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, - - output_frame_valid=output_frame_valid, - output_frame_ready=output_frame_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_arp_htype=output_arp_htype, - output_arp_ptype=output_arp_ptype, - output_arp_hlen=output_arp_hlen, - output_arp_plen=output_arp_plen, - output_arp_oper=output_arp_oper, - output_arp_sha=output_arp_sha, - output_arp_spa=output_arp_spa, - output_arp_tha=output_arp_tha, - output_arp_tpa=output_arp_tpa, - - busy=busy, - error_header_early_termination=error_header_early_termination, - error_invalid_header=error_invalid_header) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -154,81 +79,91 @@ def bench(): error_invalid_header = Signal(bool(0)) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source = eth_ep.EthFrameSource(clk, - rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, - fifo=source_queue, - pause=source_pause, - name='source') + source = eth_ep.EthFrameSource() - sink = arp_ep.ARPFrameSink(clk, - rst, - frame_ready=output_frame_ready, - frame_valid=output_frame_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - arp_htype=output_arp_htype, - arp_ptype=output_arp_ptype, - arp_hlen=output_arp_hlen, - arp_plen=output_arp_plen, - arp_oper=output_arp_oper, - arp_sha=output_arp_sha, - arp_spa=output_arp_spa, - arp_tha=output_arp_tha, - arp_tpa=output_arp_tpa, - fifo=sink_queue, - pause=sink_pause, - name='sink') + source_logic = source.create_logic( + clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + pause=source_pause, + name='source' + ) + + sink = arp_ep.ARPFrameSink() + + sink_logic = sink.create_logic( + clk, + rst, + frame_ready=output_frame_ready, + frame_valid=output_frame_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + arp_htype=output_arp_htype, + arp_ptype=output_arp_ptype, + arp_hlen=output_arp_hlen, + arp_plen=output_arp_plen, + arp_oper=output_arp_oper, + arp_sha=output_arp_sha, + arp_spa=output_arp_spa, + arp_tha=output_arp_tha, + arp_tpa=output_arp_tpa, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_arp_eth_rx(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_eth_hdr_valid, - input_eth_hdr_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tready, - input_eth_payload_tlast, - input_eth_payload_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_frame_valid, - output_frame_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_arp_htype, - output_arp_ptype, - output_arp_hlen, - output_arp_plen, - output_arp_oper, - output_arp_sha, - output_arp_spa, - output_arp_tha, - output_arp_tpa, + input_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, - busy, - error_header_early_termination, - error_invalid_header) + output_frame_valid=output_frame_valid, + output_frame_ready=output_frame_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_arp_htype=output_arp_htype, + output_arp_ptype=output_arp_ptype, + output_arp_hlen=output_arp_hlen, + output_arp_plen=output_arp_plen, + output_arp_oper=output_arp_oper, + output_arp_sha=output_arp_sha, + output_arp_spa=output_arp_spa, + output_arp_tha=output_arp_tha, + output_arp_tpa=output_arp_tpa, + + busy=busy, + error_header_early_termination=error_header_early_termination, + error_invalid_header=error_invalid_header + ) @always(delay(4)) def clkgen(): @@ -264,16 +199,14 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge yield output_frame_valid.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -298,16 +231,14 @@ def bench(): test_frame.arp_tpa = 0xc0a80165 eth_frame = test_frame.build_eth() eth_frame.payload.data += bytearray(range(10)) - source_queue.put(eth_frame) + source.send(eth_frame) yield clk.posedge yield output_frame_valid.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -330,7 +261,7 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge yield delay(64) @@ -351,9 +282,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -389,8 +318,8 @@ def bench(): test_frame2.arp_spa = 0xc0a80164 test_frame2.arp_tha = 0xDAD1D2D3D4D5 test_frame2.arp_tpa = 0xc0a80165 - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) + source.send(test_frame1.build_eth()) + source.send(test_frame2.build_eth()) yield clk.posedge yield output_frame_valid.posedge @@ -399,15 +328,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -443,8 +368,8 @@ def bench(): test_frame2.arp_spa = 0xc0a80164 test_frame2.arp_tha = 0xDAD1D2D3D4D5 test_frame2.arp_tpa = 0xc0a80165 - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) + source.send(test_frame1.build_eth()) + source.send(test_frame2.build_eth()) yield clk.posedge yield clk.posedge @@ -459,15 +384,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -503,8 +424,8 @@ def bench(): test_frame2.arp_spa = 0xc0a80164 test_frame2.arp_tha = 0xDAD1D2D3D4D5 test_frame2.arp_tpa = 0xc0a80165 - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) + source.send(test_frame1.build_eth()) + source.send(test_frame2.build_eth()) yield clk.posedge yield clk.posedge @@ -519,15 +440,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -552,7 +469,7 @@ def bench(): test_frame.arp_tpa = 0xc0a80165 eth_frame = test_frame.build_eth() eth_frame.payload.data = eth_frame.payload.data[:-2] - source_queue.put(eth_frame) + source.send(eth_frame) yield clk.posedge yield input_eth_payload_tlast.posedge @@ -579,7 +496,7 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge yield input_eth_payload_tlast.posedge @@ -608,19 +525,19 @@ def bench(): test_frame.arp_tpa = 0xc0a80165 eth_frame = test_frame.build_eth() eth_frame.payload.user = 1 - source_queue.put(eth_frame) + source.send(eth_frame) yield clk.posedge yield input_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp_eth_rx.v b/tb/test_arp_eth_rx.v index 8e99b1e4b..35b094dac 100644 --- a/tb/test_arp_eth_rx.v +++ b/tb/test_arp_eth_rx.v @@ -24,8 +24,11 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for arp_eth_rx + */ module test_arp_eth_rx; // Inputs @@ -65,36 +68,40 @@ wire error_invalid_header; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_frame_ready); - $to_myhdl(input_eth_hdr_ready, - input_eth_payload_tready, - output_frame_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_arp_htype, - output_arp_ptype, - output_arp_hlen, - output_arp_plen, - output_arp_oper, - output_arp_sha, - output_arp_spa, - output_arp_tha, - output_arp_tpa, - busy, - error_header_early_termination, - error_invalid_header); + $from_myhdl( + clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_frame_ready + ); + $to_myhdl( + input_eth_hdr_ready, + input_eth_payload_tready, + output_frame_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_arp_htype, + output_arp_ptype, + output_arp_hlen, + output_arp_plen, + output_arp_oper, + output_arp_sha, + output_arp_spa, + output_arp_tha, + output_arp_tpa, + busy, + error_header_early_termination, + error_invalid_header + ); // dump file $dumpfile("test_arp_eth_rx.lxt"); diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index f8ae65eb1..4001e19c3 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -26,97 +26,20 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import arp_ep import eth_ep module = 'arp_eth_rx_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_arp_eth_rx_64(clk, - rst, - current_test, - - input_eth_hdr_valid, - input_eth_hdr_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tready, - input_eth_payload_tlast, - input_eth_payload_tuser, - - output_frame_valid, - output_frame_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_arp_htype, - output_arp_ptype, - output_arp_hlen, - output_arp_plen, - output_arp_oper, - output_arp_sha, - output_arp_spa, - output_arp_tha, - output_arp_tpa, - - busy, - error_header_early_termination, - error_invalid_header): - - 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_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tkeep=input_eth_payload_tkeep, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, - - output_frame_valid=output_frame_valid, - output_frame_ready=output_frame_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_arp_htype=output_arp_htype, - output_arp_ptype=output_arp_ptype, - output_arp_hlen=output_arp_hlen, - output_arp_plen=output_arp_plen, - output_arp_oper=output_arp_oper, - output_arp_sha=output_arp_sha, - output_arp_spa=output_arp_spa, - output_arp_tha=output_arp_tha, - output_arp_tpa=output_arp_tpa, - - busy=busy, - error_header_early_termination=error_header_early_termination, - error_invalid_header=error_invalid_header) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -157,83 +80,93 @@ def bench(): error_invalid_header = Signal(bool(0)) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source = eth_ep.EthFrameSource(clk, - rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tkeep=input_eth_payload_tkeep, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, - fifo=source_queue, - pause=source_pause, - name='source') + source = eth_ep.EthFrameSource() - sink = arp_ep.ARPFrameSink(clk, - rst, - frame_ready=output_frame_ready, - frame_valid=output_frame_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - arp_htype=output_arp_htype, - arp_ptype=output_arp_ptype, - arp_hlen=output_arp_hlen, - arp_plen=output_arp_plen, - arp_oper=output_arp_oper, - arp_sha=output_arp_sha, - arp_spa=output_arp_spa, - arp_tha=output_arp_tha, - arp_tpa=output_arp_tpa, - fifo=sink_queue, - pause=sink_pause, - name='sink') + source_logic = source.create_logic( + clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + pause=source_pause, + name='source' + ) + + sink = arp_ep.ARPFrameSink() + + sink_logic = sink.create_logic( + clk, + rst, + frame_ready=output_frame_ready, + frame_valid=output_frame_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + arp_htype=output_arp_htype, + arp_ptype=output_arp_ptype, + arp_hlen=output_arp_hlen, + arp_plen=output_arp_plen, + arp_oper=output_arp_oper, + arp_sha=output_arp_sha, + arp_spa=output_arp_spa, + arp_tha=output_arp_tha, + arp_tpa=output_arp_tpa, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_arp_eth_rx_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_eth_hdr_valid, - input_eth_hdr_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tready, - input_eth_payload_tlast, - input_eth_payload_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_frame_valid, - output_frame_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_arp_htype, - output_arp_ptype, - output_arp_hlen, - output_arp_plen, - output_arp_oper, - output_arp_sha, - output_arp_spa, - output_arp_tha, - output_arp_tpa, + input_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, - busy, - error_header_early_termination, - error_invalid_header) + output_frame_valid=output_frame_valid, + output_frame_ready=output_frame_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_arp_htype=output_arp_htype, + output_arp_ptype=output_arp_ptype, + output_arp_hlen=output_arp_hlen, + output_arp_plen=output_arp_plen, + output_arp_oper=output_arp_oper, + output_arp_sha=output_arp_sha, + output_arp_spa=output_arp_spa, + output_arp_tha=output_arp_tha, + output_arp_tpa=output_arp_tpa, + + busy=busy, + error_header_early_termination=error_header_early_termination, + error_invalid_header=error_invalid_header + ) @always(delay(4)) def clkgen(): @@ -269,16 +202,14 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge yield output_frame_valid.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -303,16 +234,14 @@ def bench(): test_frame.arp_tpa = 0xc0a80165 eth_frame = test_frame.build_eth() eth_frame.payload.data += bytearray(range(10)) - source_queue.put(eth_frame) + source.send(eth_frame) yield clk.posedge yield output_frame_valid.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -335,7 +264,7 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge yield delay(16) @@ -356,9 +285,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame @@ -394,8 +321,8 @@ def bench(): test_frame2.arp_spa = 0xc0a80164 test_frame2.arp_tha = 0xDAD1D2D3D4D5 test_frame2.arp_tpa = 0xc0a80165 - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) + source.send(test_frame1.build_eth()) + source.send(test_frame2.build_eth()) yield clk.posedge yield output_frame_valid.posedge @@ -404,15 +331,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -448,8 +371,8 @@ def bench(): test_frame2.arp_spa = 0xc0a80164 test_frame2.arp_tha = 0xDAD1D2D3D4D5 test_frame2.arp_tpa = 0xc0a80165 - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) + source.send(test_frame1.build_eth()) + source.send(test_frame2.build_eth()) yield clk.posedge yield clk.posedge @@ -464,15 +387,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -508,8 +427,8 @@ def bench(): test_frame2.arp_spa = 0xc0a80164 test_frame2.arp_tha = 0xDAD1D2D3D4D5 test_frame2.arp_tpa = 0xc0a80165 - source_queue.put(test_frame1.build_eth()) - source_queue.put(test_frame2.build_eth()) + source.send(test_frame1.build_eth()) + source.send(test_frame2.build_eth()) yield clk.posedge yield clk.posedge @@ -524,15 +443,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -557,7 +472,7 @@ def bench(): test_frame.arp_tpa = 0xc0a80165 eth_frame = test_frame.build_eth() eth_frame.payload.data = eth_frame.payload.data[:-2] - source_queue.put(eth_frame) + source.send(eth_frame) yield clk.posedge yield input_eth_payload_tlast.posedge @@ -584,7 +499,7 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame.build_eth()) + source.send(test_frame.build_eth()) yield clk.posedge yield input_eth_payload_tlast.posedge @@ -613,19 +528,19 @@ def bench(): test_frame.arp_tpa = 0xc0a80165 eth_frame = test_frame.build_eth() eth_frame.payload.user = 1 - source_queue.put(eth_frame) + source.send(eth_frame) yield clk.posedge yield input_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - assert sink_queue.empty() + assert sink.empty() yield delay(100) raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp_eth_rx_64.v b/tb/test_arp_eth_rx_64.v index e84502a00..dc9179bcf 100644 --- a/tb/test_arp_eth_rx_64.v +++ b/tb/test_arp_eth_rx_64.v @@ -24,8 +24,11 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for arp_eth_rx_64 + */ module test_arp_eth_rx_64; // Inputs @@ -66,37 +69,41 @@ wire error_invalid_header; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_frame_ready); - $to_myhdl(input_eth_hdr_ready, - input_eth_payload_tready, - output_frame_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_arp_htype, - output_arp_ptype, - output_arp_hlen, - output_arp_plen, - output_arp_oper, - output_arp_sha, - output_arp_spa, - output_arp_tha, - output_arp_tpa, - busy, - error_header_early_termination, - error_invalid_header); + $from_myhdl( + clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + output_frame_ready + ); + $to_myhdl( + input_eth_hdr_ready, + input_eth_payload_tready, + output_frame_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_arp_htype, + output_arp_ptype, + output_arp_hlen, + output_arp_plen, + output_arp_oper, + output_arp_sha, + output_arp_spa, + output_arp_tha, + output_arp_tpa, + busy, + error_header_early_termination, + error_invalid_header + ); // dump file $dumpfile("test_arp_eth_rx_64.lxt"); diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py index dab27a931..519e2d4e8 100755 --- a/tb/test_arp_eth_tx.py +++ b/tb/test_arp_eth_tx.py @@ -26,88 +26,20 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - -import axis_ep import eth_ep import arp_ep module = 'arp_eth_tx' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_arp_eth_tx(clk, - rst, - current_test, - - input_frame_valid, - input_frame_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_arp_htype, - input_arp_ptype, - input_arp_oper, - input_arp_sha, - input_arp_spa, - input_arp_tha, - input_arp_tpa, - - output_eth_hdr_valid, - output_eth_hdr_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tready, - output_eth_payload_tlast, - output_eth_payload_tuser, - - busy): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_frame_valid=input_frame_valid, - input_frame_ready=input_frame_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_arp_htype=input_arp_htype, - input_arp_ptype=input_arp_ptype, - input_arp_oper=input_arp_oper, - input_arp_sha=input_arp_sha, - input_arp_spa=input_arp_spa, - input_arp_tha=input_arp_tha, - input_arp_tpa=input_arp_tpa, - - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, - - busy=busy) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -143,75 +75,85 @@ def bench(): busy = Signal(bool(0)) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source = arp_ep.ARPFrameSource(clk, - rst, - frame_ready=input_frame_ready, - frame_valid=input_frame_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - arp_htype=input_arp_htype, - arp_ptype=input_arp_ptype, - arp_oper=input_arp_oper, - arp_sha=input_arp_sha, - arp_spa=input_arp_spa, - arp_tha=input_arp_tha, - arp_tpa=input_arp_tpa, - fifo=source_queue, - pause=source_pause, - name='source') + source = arp_ep.ARPFrameSource() - sink = eth_ep.EthFrameSink(clk, - rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') + source_logic = source.create_logic( + clk, + rst, + frame_ready=input_frame_ready, + frame_valid=input_frame_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + arp_htype=input_arp_htype, + arp_ptype=input_arp_ptype, + arp_oper=input_arp_oper, + arp_sha=input_arp_sha, + arp_spa=input_arp_spa, + arp_tha=input_arp_tha, + arp_tpa=input_arp_tpa, + pause=source_pause, + name='source' + ) + + sink = eth_ep.EthFrameSink() + + sink_logic = sink.create_logic( + clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_arp_eth_tx(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_frame_valid, - input_frame_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_arp_htype, - input_arp_ptype, - input_arp_oper, - input_arp_sha, - input_arp_spa, - input_arp_tha, - input_arp_tpa, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_eth_hdr_valid, - output_eth_hdr_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tready, - output_eth_payload_tlast, - output_eth_payload_tuser, + input_frame_valid=input_frame_valid, + input_frame_ready=input_frame_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_arp_htype=input_arp_htype, + input_arp_ptype=input_arp_ptype, + input_arp_oper=input_arp_oper, + input_arp_sha=input_arp_sha, + input_arp_spa=input_arp_spa, + input_arp_tha=input_arp_tha, + input_arp_tpa=input_arp_tpa, - busy) + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + busy=busy + ) @always(delay(4)) def clkgen(): @@ -245,16 +187,14 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield output_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -279,7 +219,7 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(64) @@ -293,9 +233,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -333,8 +271,8 @@ def bench(): test_frame2.arp_spa = 0xc0a80164 test_frame2.arp_tha = 0xDAD1D2D3D4D5 test_frame2.arp_tpa = 0xc0a80165 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_eth_payload_tlast.posedge @@ -343,17 +281,13 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) assert check_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -391,8 +325,8 @@ def bench(): test_frame2.arp_spa = 0xc0a80164 test_frame2.arp_tha = 0xDAD1D2D3D4D5 test_frame2.arp_tpa = 0xc0a80165 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -407,17 +341,13 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) assert check_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -427,7 +357,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp_eth_tx.v b/tb/test_arp_eth_tx.v index fa722335f..c783b9dfe 100644 --- a/tb/test_arp_eth_tx.v +++ b/tb/test_arp_eth_tx.v @@ -24,8 +24,11 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for arp_eth_tx + */ module test_arp_eth_tx; // Inputs @@ -61,32 +64,36 @@ wire busy; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_frame_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_arp_htype, - input_arp_ptype, - input_arp_oper, - input_arp_sha, - input_arp_spa, - input_arp_tha, - input_arp_tpa, - output_eth_hdr_ready, - output_eth_payload_tready); - $to_myhdl(input_frame_ready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, - busy); + $from_myhdl( + clk, + rst, + current_test, + input_frame_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_arp_htype, + input_arp_ptype, + input_arp_oper, + input_arp_sha, + input_arp_spa, + input_arp_tha, + input_arp_tpa, + output_eth_hdr_ready, + output_eth_payload_tready + ); + $to_myhdl( + input_frame_ready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + busy + ); // dump file $dumpfile("test_arp_eth_tx.lxt"); diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py index bc5c0af83..b1ddb7f81 100755 --- a/tb/test_arp_eth_tx_64.py +++ b/tb/test_arp_eth_tx_64.py @@ -26,90 +26,20 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - -import axis_ep import eth_ep import arp_ep module = 'arp_eth_tx_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_arp_eth_tx_64(clk, - rst, - current_test, - - input_frame_valid, - input_frame_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_arp_htype, - input_arp_ptype, - input_arp_oper, - input_arp_sha, - input_arp_spa, - input_arp_tha, - input_arp_tpa, - - output_eth_hdr_valid, - output_eth_hdr_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tready, - output_eth_payload_tlast, - output_eth_payload_tuser, - - busy): - - if os.system(build_cmd): - raise Exception("Error running build command") - return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, - clk=clk, - rst=rst, - current_test=current_test, - - input_frame_valid=input_frame_valid, - input_frame_ready=input_frame_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_arp_htype=input_arp_htype, - input_arp_ptype=input_arp_ptype, - input_arp_oper=input_arp_oper, - input_arp_sha=input_arp_sha, - input_arp_spa=input_arp_spa, - input_arp_tha=input_arp_tha, - input_arp_tpa=input_arp_tpa, - - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, - - busy=busy) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -146,77 +76,87 @@ def bench(): busy = Signal(bool(0)) # sources and sinks - source_queue = Queue() source_pause = Signal(bool(0)) - sink_queue = Queue() sink_pause = Signal(bool(0)) - source = arp_ep.ARPFrameSource(clk, - rst, - frame_ready=input_frame_ready, - frame_valid=input_frame_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - arp_htype=input_arp_htype, - arp_ptype=input_arp_ptype, - arp_oper=input_arp_oper, - arp_sha=input_arp_sha, - arp_spa=input_arp_spa, - arp_tha=input_arp_tha, - arp_tpa=input_arp_tpa, - fifo=source_queue, - pause=source_pause, - name='source') + source = arp_ep.ARPFrameSource() - sink = eth_ep.EthFrameSink(clk, - rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, - fifo=sink_queue, - pause=sink_pause, - name='sink') + source_logic = source.create_logic( + clk, + rst, + frame_ready=input_frame_ready, + frame_valid=input_frame_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + arp_htype=input_arp_htype, + arp_ptype=input_arp_ptype, + arp_oper=input_arp_oper, + arp_sha=input_arp_sha, + arp_spa=input_arp_spa, + arp_tha=input_arp_tha, + arp_tpa=input_arp_tpa, + pause=source_pause, + name='source' + ) + + sink = eth_ep.EthFrameSink() + + sink_logic = sink.create_logic( + clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_arp_eth_tx_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_frame_valid, - input_frame_ready, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_arp_htype, - input_arp_ptype, - input_arp_oper, - input_arp_sha, - input_arp_spa, - input_arp_tha, - input_arp_tpa, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_eth_hdr_valid, - output_eth_hdr_ready, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tready, - output_eth_payload_tlast, - output_eth_payload_tuser, + input_frame_valid=input_frame_valid, + input_frame_ready=input_frame_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_arp_htype=input_arp_htype, + input_arp_ptype=input_arp_ptype, + input_arp_oper=input_arp_oper, + input_arp_sha=input_arp_sha, + input_arp_spa=input_arp_spa, + input_arp_tha=input_arp_tha, + input_arp_tpa=input_arp_tpa, - busy) + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + busy=busy + ) @always(delay(4)) def clkgen(): @@ -250,16 +190,14 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield output_eth_payload_tlast.posedge yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -284,7 +222,7 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source_queue.put(test_frame) + source.send(test_frame) yield clk.posedge yield delay(16) @@ -298,9 +236,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -338,8 +274,8 @@ def bench(): test_frame2.arp_spa = 0xc0a80164 test_frame2.arp_tha = 0xDAD1D2D3D4D5 test_frame2.arp_tpa = 0xc0a80165 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield output_eth_payload_tlast.posedge @@ -348,17 +284,13 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) assert check_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -396,8 +328,8 @@ def bench(): test_frame2.arp_spa = 0xc0a80164 test_frame2.arp_tha = 0xDAD1D2D3D4D5 test_frame2.arp_tpa = 0xc0a80165 - source_queue.put(test_frame1) - source_queue.put(test_frame2) + source.send(test_frame1) + source.send(test_frame2) yield clk.posedge yield clk.posedge @@ -412,17 +344,13 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) assert check_frame == test_frame1 - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -432,7 +360,7 @@ def bench(): raise StopSimulation - return dut, source, sink, clkgen, check + return dut, source_logic, sink_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp_eth_tx_64.v b/tb/test_arp_eth_tx_64.v index 0c577bc1e..1625f4660 100644 --- a/tb/test_arp_eth_tx_64.v +++ b/tb/test_arp_eth_tx_64.v @@ -24,8 +24,11 @@ THE SOFTWARE. // Language: Verilog 2001 -`timescale 1 ns / 1 ps +`timescale 1ns / 1ps +/* + * Testbench for arp_eth_tx_64 + */ module test_arp_eth_tx_64; // Inputs @@ -62,33 +65,37 @@ wire busy; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_frame_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_arp_htype, - input_arp_ptype, - input_arp_oper, - input_arp_sha, - input_arp_spa, - input_arp_tha, - input_arp_tpa, - output_eth_hdr_ready, - output_eth_payload_tready); - $to_myhdl(input_frame_ready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, - busy); + $from_myhdl( + clk, + rst, + current_test, + input_frame_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_arp_htype, + input_arp_ptype, + input_arp_oper, + input_arp_sha, + input_arp_spa, + input_arp_tha, + input_arp_tpa, + output_eth_hdr_ready, + output_eth_payload_tready + ); + $to_myhdl( + input_frame_ready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + busy + ); // dump file $dumpfile("test_arp_eth_tx_64.lxt"); diff --git a/tb/test_axis_eth_fcs.py b/tb/test_axis_eth_fcs.py index c216acb08..e39fccc73 100755 --- a/tb/test_axis_eth_fcs.py +++ b/tb/test_axis_eth_fcs.py @@ -26,54 +26,21 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep import eth_ep module = 'axis_eth_fcs' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/lfsr.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_eth_fcs(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_fcs, - output_fcs_valid): - - 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_fcs=output_fcs, - output_fcs_valid=output_fcs_valid) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -96,33 +63,41 @@ def bench(): output_fcs_valid = Signal(bool(0)) # sources and sinks - source_queue = Queue() source_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') + source = axis_ep.AXIStreamSource() + + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) # DUT - dut = dut_axis_eth_fcs(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_fcs, - output_fcs_valid) + 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_fcs=output_fcs, + output_fcs_valid=output_fcs_valid + ) @always(delay(4)) def clkgen(): @@ -155,7 +130,7 @@ def bench(): axis_frame = test_frame.build_axis() - source_queue.put(axis_frame) + source.send(axis_frame) yield clk.posedge yield clk.posedge @@ -170,7 +145,7 @@ def bench(): raise StopSimulation - return dut, source, clkgen, check + return dut, source_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_eth_fcs.v b/tb/test_axis_eth_fcs.v index 29db1180b..6b83c756a 100644 --- a/tb/test_axis_eth_fcs.v +++ b/tb/test_axis_eth_fcs.v @@ -50,16 +50,20 @@ wire output_fcs_valid; initial begin // myhdl integration - $from_myhdl(clk, - rst, - current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser); - $to_myhdl(input_axis_tready, - output_fcs, - output_fcs_valid); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser + ); + $to_myhdl( + input_axis_tready, + output_fcs, + output_fcs_valid + ); // dump file $dumpfile("test_axis_eth_fcs.lxt"); diff --git a/tb/test_axis_eth_fcs_64.py b/tb/test_axis_eth_fcs_64.py index 05e9f9ebd..2b613f0f8 100755 --- a/tb/test_axis_eth_fcs_64.py +++ b/tb/test_axis_eth_fcs_64.py @@ -26,56 +26,21 @@ THE SOFTWARE. from myhdl import * import os -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep import eth_ep module = 'axis_eth_fcs_64' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/lfsr.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_eth_fcs_64(clk, - rst, - current_test, - - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, - - output_fcs, - output_fcs_valid): - - 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_fcs=output_fcs, - output_fcs_valid=output_fcs_valid) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -99,35 +64,43 @@ def bench(): output_fcs_valid = Signal(bool(0)) # sources and sinks - source_queue = Queue() source_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') + source = axis_ep.AXIStreamSource() + + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) # DUT - dut = dut_axis_eth_fcs_64(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_fcs, - output_fcs_valid) + 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_fcs=output_fcs, + output_fcs_valid=output_fcs_valid + ) @always(delay(4)) def clkgen(): @@ -160,7 +133,7 @@ def bench(): axis_frame = test_frame.build_axis() - source_queue.put(axis_frame) + source.send(axis_frame) yield clk.posedge yield clk.posedge @@ -175,7 +148,7 @@ def bench(): raise StopSimulation - return dut, source, clkgen, check + return dut, source_logic, clkgen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_eth_fcs_64.v b/tb/test_axis_eth_fcs_64.v index 9aa67f12a..0a2720a42 100644 --- a/tb/test_axis_eth_fcs_64.v +++ b/tb/test_axis_eth_fcs_64.v @@ -51,17 +51,21 @@ wire output_fcs_valid; 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); - $to_myhdl(input_axis_tready, - output_fcs, - output_fcs_valid); + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tkeep, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser + ); + $to_myhdl( + input_axis_tready, + output_fcs, + output_fcs_valid + ); // dump file $dumpfile("test_axis_eth_fcs_64.lxt"); diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index c4bdd2f3a..12763e98a 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -28,66 +28,21 @@ import os import struct import zlib -try: - from queue import Queue -except ImportError: - from Queue import Queue - import axis_ep import eth_ep module = 'axis_eth_fcs_check' +testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/lfsr.v") -srcs.append("test_%s.v" % module) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) -build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) - -def dut_axis_eth_fcs_check(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, - - busy, - error_bad_fcs): - - 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, - - busy=busy, - error_bad_fcs=error_bad_fcs) +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): @@ -115,52 +70,62 @@ def bench(): error_bad_fcs = 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') + source = axis_ep.AXIStreamSource() - 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') + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tready=output_axis_tready, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + pause=sink_pause, + name='sink' + ) # DUT - dut = dut_axis_eth_fcs_check(clk, - rst, - current_test, + if os.system(build_cmd): + raise Exception("Error running build command") - input_axis_tdata, - input_axis_tvalid, - input_axis_tready, - input_axis_tlast, - input_axis_tuser, + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, - output_axis_tdata, - output_axis_tvalid, - output_axis_tready, - output_axis_tlast, - output_axis_tuser, + 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, - busy, - error_bad_fcs) + 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, + + busy=busy, + error_bad_fcs=error_bad_fcs + ) @always(delay(4)) def clkgen(): @@ -223,7 +188,7 @@ def bench(): axis_frame = test_frame.build_axis_fcs() for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(axis_frame) + source.send(axis_frame) yield clk.posedge yield clk.posedge @@ -233,9 +198,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() eth_frame.parse_axis(rx_frame) @@ -244,7 +207,7 @@ def bench(): assert eth_frame == test_frame assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -269,8 +232,8 @@ def bench(): axis_frame2 = test_frame2.build_axis_fcs() for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(axis_frame1) - source_queue.put(axis_frame2) + source.send(axis_frame1) + source.send(axis_frame2) yield clk.posedge yield clk.posedge @@ -280,9 +243,7 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() eth_frame.parse_axis(rx_frame) @@ -291,9 +252,7 @@ def bench(): assert eth_frame == test_frame1 assert not rx_frame.user[-1] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() eth_frame.parse_axis(rx_frame) @@ -302,7 +261,7 @@ def bench(): assert eth_frame == test_frame2 assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -329,8 +288,8 @@ def bench(): axis_frame1.user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_queue.put(axis_frame1) - source_queue.put(axis_frame2) + source.send(axis_frame1) + source.send(axis_frame2) yield clk.posedge yield clk.posedge @@ -340,15 +299,11 @@ def bench(): yield clk.posedge yield clk.posedge - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.user[-1] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() eth_frame.parse_axis(rx_frame) @@ -357,7 +312,7 @@ def bench(): assert eth_frame == test_frame2 assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -386,8 +341,8 @@ def bench(): for wait in wait_normal, wait_pause_source, wait_pause_sink: error_bad_fcs_asserted.next = 0 - source_queue.put(axis_frame1) - source_queue.put(axis_frame2) + source.send(axis_frame1) + source.send(axis_frame2) yield clk.posedge yield clk.posedge @@ -399,15 +354,11 @@ def bench(): assert error_bad_fcs_asserted - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() assert rx_frame.user[-1] - rx_frame = None - if not sink_queue.empty(): - rx_frame = sink_queue.get() + rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() eth_frame.parse_axis(rx_frame) @@ -416,7 +367,7 @@ def bench(): assert eth_frame == test_frame2 assert not rx_frame.user[-1] - assert sink_queue.empty() + assert sink.empty() yield delay(100) @@ -430,7 +381,7 @@ def bench(): test_frame_fcs = test_frame + struct.pack(' 0: + frame = self.header_queue.pop(0) + frame.build() + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + ip_version.next = frame.ip_version + ip_ihl.next = frame.ip_ihl + ip_dscp.next = frame.ip_dscp + ip_ecn.next = frame.ip_ecn + ip_length.next = frame.ip_length + ip_identification.next = frame.ip_identification + ip_flags.next = frame.ip_flags + ip_fragment_offset.next = frame.ip_fragment_offset + ip_ttl.next = frame.ip_ttl + ip_protocol.next = frame.ip_protocol + ip_header_checksum.next = frame.ip_header_checksum + ip_source_ip.next = frame.ip_source_ip + ip_dest_ip.next = frame.ip_dest_ip + udp_source_port.next = frame.udp_source_port + udp_dest_port.next = frame.udp_dest_port + udp_length.next = frame.udp_length + udp_checksum.next = frame.udp_checksum + + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + + udp_hdr_valid_int.next = True + + if len(self.queue) > 0 and len(self.header_queue) == 0: + frame = self.queue.pop(0) + self.header_queue.append(frame) + self.payload_source.send(frame.payload) + + return logic, pause_logic, udp_payload_source + + +class UDPFrameSink(): + def __init__(self): + self.has_logic = False + self.queue = [] + self.payload_sink = axis_ep.AXIStreamSink() + self.header_queue = [] + + def recv(self): + if len(self.queue) > 0: + return self.queue.pop(0) + return None + + def count(self): + return len(self.queue) + + def empty(self): + return self.count() == 0 + + def create_logic(self, + clk, + rst, + udp_hdr_valid=None, + udp_hdr_ready=None, + eth_dest_mac=Signal(intbv(0)[48:]), + eth_src_mac=Signal(intbv(0)[48:]), + eth_type=Signal(intbv(0)[16:]), + ip_version=Signal(intbv(4)[4:]), + ip_ihl=Signal(intbv(5)[4:]), + ip_dscp=Signal(intbv(0)[6:]), + ip_ecn=Signal(intbv(0)[2:]), + ip_length=Signal(intbv(0)[16:]), + ip_identification=Signal(intbv(0)[16:]), + ip_flags=Signal(intbv(0)[3:]), + ip_fragment_offset=Signal(intbv(0)[13:]), + ip_ttl=Signal(intbv(0)[8:]), + ip_protocol=Signal(intbv(0)[8:]), + ip_header_checksum=Signal(intbv(0)[16:]), + ip_source_ip=Signal(intbv(0)[32:]), + ip_dest_ip=Signal(intbv(0)[32:]), + udp_source_port=(intbv(0)[16:]), + udp_dest_port=(intbv(0)[16:]), + udp_length=(intbv(0)[16:]), + udp_checksum=(intbv(0)[16:]), + udp_payload_tdata=None, + udp_payload_tkeep=Signal(bool(True)), + udp_payload_tvalid=Signal(bool(True)), + udp_payload_tready=Signal(bool(True)), + udp_payload_tlast=Signal(bool(True)), + udp_payload_tuser=Signal(bool(False)), + pause=0, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + udp_hdr_ready_int = Signal(bool(False)) + udp_hdr_valid_int = Signal(bool(False)) + udp_payload_pause = Signal(bool(False)) + + udp_payload_sink = self.payload_sink.create_logic( + clk=clk, + rst=rst, + tdata=udp_payload_tdata, + tkeep=udp_payload_tkeep, + tvalid=udp_payload_tvalid, + tready=udp_payload_tready, + tlast=udp_payload_tlast, + tuser=udp_payload_tuser, + pause=udp_payload_pause + ) + + @always_comb + def pause_logic(): + udp_hdr_ready.next = udp_hdr_ready_int and not pause + udp_hdr_valid_int.next = udp_hdr_valid and not pause + udp_payload_pause.next = pause # or udp_hdr_valid_int + + @instance + def logic(): + while True: + yield clk.posedge, rst.posedge + + if rst: + udp_hdr_ready_int.next = False + frame = UDPFrame() + else: + udp_hdr_ready_int.next = True + + if udp_hdr_ready_int and udp_hdr_valid_int: + frame = UDPFrame() + frame.eth_dest_mac = int(eth_dest_mac) + frame.eth_src_mac = int(eth_src_mac) + frame.eth_type = int(eth_type) + frame.ip_version = int(ip_version) + frame.ip_ihl = int(ip_ihl) + frame.ip_dscp = int(ip_dscp) + frame.ip_ecn = int(ip_ecn) + frame.ip_length = int(ip_length) + frame.ip_identification = int(ip_identification) + frame.ip_flags = int(ip_flags) + frame.ip_fragment_offset = int(ip_fragment_offset) + frame.ip_ttl = int(ip_ttl) + frame.ip_protocol = int(ip_protocol) + frame.ip_header_checksum = int(ip_header_checksum) + frame.ip_source_ip = int(ip_source_ip) + frame.ip_dest_ip = int(ip_dest_ip) + frame.udp_source_port = int(udp_source_port) + frame.udp_dest_port = int(udp_dest_port) + frame.udp_length = int(udp_length) + frame.udp_checksum = int(udp_checksum) + self.header_queue.append(frame) + + if not self.payload_sink.empty() and len(self.header_queue) > 0: + frame = self.header_queue.pop(0) + frame.payload = self.payload_sink.recv() + self.queue.append(frame) if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) + print("[%s] Got frame %s" % (name, repr(frame))) - udp_hdr_valid_int.next = True + # ensure all payloads have been matched to headers + if len(self.header_queue) == 0: + assert self.payload_sink.empty() - return logic, pause_logic, udp_payload_source - - -def UDPFrameSink(clk, rst, - udp_hdr_valid=None, - udp_hdr_ready=None, - eth_dest_mac=Signal(intbv(0)[48:]), - eth_src_mac=Signal(intbv(0)[48:]), - eth_type=Signal(intbv(0)[16:]), - ip_version=Signal(intbv(4)[4:]), - ip_ihl=Signal(intbv(5)[4:]), - ip_dscp=Signal(intbv(0)[6:]), - ip_ecn=Signal(intbv(0)[2:]), - ip_length=Signal(intbv(0)[16:]), - ip_identification=Signal(intbv(0)[16:]), - ip_flags=Signal(intbv(0)[3:]), - ip_fragment_offset=Signal(intbv(0)[13:]), - ip_ttl=Signal(intbv(0)[8:]), - ip_protocol=Signal(intbv(0)[8:]), - ip_header_checksum=Signal(intbv(0)[16:]), - ip_source_ip=Signal(intbv(0)[32:]), - ip_dest_ip=Signal(intbv(0)[32:]), - udp_source_port=(intbv(0)[16:]), - udp_dest_port=(intbv(0)[16:]), - udp_length=(intbv(0)[16:]), - udp_checksum=(intbv(0)[16:]), - udp_payload_tdata=None, - udp_payload_tkeep=Signal(bool(True)), - udp_payload_tvalid=Signal(bool(True)), - udp_payload_tready=Signal(bool(True)), - udp_payload_tlast=Signal(bool(True)), - udp_payload_tuser=Signal(bool(False)), - fifo=None, - pause=0, - name=None): - - udp_hdr_ready_int = Signal(bool(False)) - udp_hdr_valid_int = Signal(bool(False)) - udp_payload_pause = Signal(bool(False)) - - udp_payload_fifo = Queue() - udp_header_fifo = Queue() - - udp_payload_sink = axis_ep.AXIStreamSink(clk, - rst, - tdata=udp_payload_tdata, - tkeep=udp_payload_tkeep, - tvalid=udp_payload_tvalid, - tready=udp_payload_tready, - tlast=udp_payload_tlast, - tuser=udp_payload_tuser, - fifo=udp_payload_fifo, - pause=udp_payload_pause) - - @always_comb - def pause_logic(): - udp_hdr_ready.next = udp_hdr_ready_int and not pause - udp_hdr_valid_int.next = udp_hdr_valid and not pause - udp_payload_pause.next = pause # or udp_hdr_valid_int - - @instance - def logic(): - frame = UDPFrame() - - while True: - yield clk.posedge, rst.posedge - - if rst: - udp_hdr_ready_int.next = False - frame = UDPFrame() - else: - udp_hdr_ready_int.next = True - - if udp_hdr_ready_int and udp_hdr_valid_int: - frame = UDPFrame() - frame.eth_dest_mac = int(eth_dest_mac) - frame.eth_src_mac = int(eth_src_mac) - frame.eth_type = int(eth_type) - frame.ip_version = int(ip_version) - frame.ip_ihl = int(ip_ihl) - frame.ip_dscp = int(ip_dscp) - frame.ip_ecn = int(ip_ecn) - frame.ip_length = int(ip_length) - frame.ip_identification = int(ip_identification) - frame.ip_flags = int(ip_flags) - frame.ip_fragment_offset = int(ip_fragment_offset) - frame.ip_ttl = int(ip_ttl) - frame.ip_protocol = int(ip_protocol) - frame.ip_header_checksum = int(ip_header_checksum) - frame.ip_source_ip = int(ip_source_ip) - frame.ip_dest_ip = int(ip_dest_ip) - frame.udp_source_port = int(udp_source_port) - frame.udp_dest_port = int(udp_dest_port) - frame.udp_length = int(udp_length) - frame.udp_checksum = int(udp_checksum) - udp_header_fifo.put(frame) - - if not udp_payload_fifo.empty() and not udp_header_fifo.empty(): - frame = udp_header_fifo.get() - frame.payload = udp_payload_fifo.get() - fifo.put(frame) - - # ensure all payloads have been matched to headers - if udp_header_fifo.empty(): - assert udp_payload_fifo.empty() - - if name is not None: - print("[%s] Got frame %s" % (name, repr(frame))) - - frame = dict() - - return logic, pause_logic, udp_payload_sink + return logic, pause_logic, udp_payload_sink diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 4a1c3ec67..a30c1f339 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -103,168 +103,209 @@ class XGMIIFrame(object): return self.data.__iter__() -def XGMIISource(clk, rst, +class XGMIISource(object): + def __init__(self): + self.has_logic = False + self.queue = [] + + def send(self, frame): + self.queue.append(XGMIIFrame(frame)) + + def count(self): + return len(self.queue) + + def empty(self): + return self.count() == 0 + + def create_logic(self, + clk, + rst, txd, txc, - fifo=None, - name=None): + name=None + ): - assert len(txd) in [32, 64] + assert not self.has_logic - bw = int(len(txd)/8) + self.has_logic = True - @instance - def logic(): - frame = None - dl = [] - cl = [] - ifg_cnt = 0 - deficit_idle_cnt = 0 - nt = False + assert len(txd) in [32, 64] - while True: - yield clk.posedge, rst.posedge + bw = int(len(txd)/8) - if rst: - frame = None - txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 - txc.next = 0xff if bw == 8 else 0xf - dl = [] - cl = [] - ifg_cnt = 0 - deficit_idle_cnt = 0 - nt = False - else: - if ifg_cnt > bw-1: - ifg_cnt -= bw + @instance + def logic(): + frame = None + dl = [] + cl = [] + ifg_cnt = 0 + deficit_idle_cnt = 0 + nt = False + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame = None txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 txc.next = 0xff if bw == 8 else 0xf - elif len(dl) > 0 or nt: - d = 0 - c = 0 - - for i in range(bw): - if len(dl) > 0: - d |= dl.pop(0) << (8*i) - c |= cl.pop(0) << i - nt = True - else: - if nt: - d |= 0xfd << (8*i) - nt = False - ifg_cnt = 12 - (bw-i) + deficit_idle_cnt - else: - d |= 0x07 << (8*i) - c |= 1 << i - - txd.next = d - txc.next = c - elif not fifo.empty(): - frame = XGMIIFrame(fifo.get()) - dl, cl = frame.build() - if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) - - if ifg_cnt >= 4: - deficit_idle_cnt = ifg_cnt - 4 - else: - deficit_idle_cnt = ifg_cnt - ifg_cnt = 0 - - assert len(dl) > 0 - assert dl.pop(0) == 0x55 - cl.pop(0) - - k = 1 - d = 0xfb - c = 1 - - if ifg_cnt > 0: - k = 5 - d = 0xfb07070707 - c = 0x1f - - for i in range(k,bw): - if len(dl) > 0: - d |= dl.pop(0) << (8*i) - c |= cl.pop(0) << i - nt = True - else: - if nt: - d |= 0xfd << (8*i) - nt = False - else: - d |= 0x07 << (8*i) - c |= 1 << i - - txd.next = d - txc.next = c - else: + dl = [] + cl = [] ifg_cnt = 0 deficit_idle_cnt = 0 - txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 - txc.next = 0xff if bw == 8 else 0xf - - return logic - - -def XGMIISink(clk, rst, - rxd, - rxc, - fifo=None, - name=None): - - assert len(rxd) in [32, 64] - - bw = int(len(rxd)/8) - - @instance - def logic(): - frame = None - d = [] - c = [] - - while True: - yield clk.posedge, rst.posedge - - if rst: - frame = None - d = [] - c = [] - else: - if frame is None: - if rxc & 1 and rxd & 0xff == 0xfb: - # start in lane 0 - frame = XGMIIFrame() - d = [0x55] - c = [0] - for i in range(1,bw): - d.append((int(rxd) >> (8*i)) & 0xff) - c.append((int(rxc) >> i) & 1) - elif bw == 8 and (rxc >> 4) & 1 and (rxd >> 32) & 0xff == 0xfb: - # start in lane 4 - frame = XGMIIFrame() - d = [0x55] - c = [0] - for i in range(5,8): - d.append((int(rxd) >> (8*i)) & 0xff) - c.append((int(rxc) >> i) & 1) + nt = False else: - for i in range(bw): - if (rxc >> i) & 1 and (rxd >> (8*i)) & 0xff == 0xfd: - # terminate - frame.parse(d, c) - if fifo is not None: - fifo.put(frame) - if name is not None: - print("[%s] Got frame %s" % (name, repr(frame))) - frame = None - d = [] - c = [] - break + if ifg_cnt > bw-1: + ifg_cnt -= bw + txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 + txc.next = 0xff if bw == 8 else 0xf + elif len(dl) > 0 or nt: + d = 0 + c = 0 + + for i in range(bw): + if len(dl) > 0: + d |= dl.pop(0) << (8*i) + c |= cl.pop(0) << i + nt = True + else: + if nt: + d |= 0xfd << (8*i) + nt = False + ifg_cnt = 12 - (bw-i) + deficit_idle_cnt + else: + d |= 0x07 << (8*i) + c |= 1 << i + + txd.next = d + txc.next = c + elif len(self.queue) > 0: + frame = self.queue.pop(0) + dl, cl = frame.build() + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + + if ifg_cnt >= 4: + deficit_idle_cnt = ifg_cnt - 4 else: - d.append((int(rxd) >> (8*i)) & 0xff) - c.append((int(rxc) >> i) & 1) + deficit_idle_cnt = ifg_cnt + ifg_cnt = 0 - return logic + assert len(dl) > 0 + assert dl.pop(0) == 0x55 + cl.pop(0) + + k = 1 + d = 0xfb + c = 1 + + if ifg_cnt > 0: + k = 5 + d = 0xfb07070707 + c = 0x1f + + for i in range(k,bw): + if len(dl) > 0: + d |= dl.pop(0) << (8*i) + c |= cl.pop(0) << i + nt = True + else: + if nt: + d |= 0xfd << (8*i) + nt = False + else: + d |= 0x07 << (8*i) + c |= 1 << i + + txd.next = d + txc.next = c + else: + ifg_cnt = 0 + deficit_idle_cnt = 0 + txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 + txc.next = 0xff if bw == 8 else 0xf + + return logic + + +class XGMIISink(object): + def __init__(self): + self.has_logic = False + self.queue = [] + + def recv(self): + if len(self.queue) > 0: + return self.queue.pop(0) + return None + + def count(self): + return len(self.queue) + + def empty(self): + return self.count() == 0 + + def create_logic(self, + clk, + rst, + rxd, + rxc, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + assert len(rxd) in [32, 64] + + bw = int(len(rxd)/8) + + @instance + def logic(): + frame = None + d = [] + c = [] + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame = None + d = [] + c = [] + else: + if frame is None: + if rxc & 1 and rxd & 0xff == 0xfb: + # start in lane 0 + frame = XGMIIFrame() + d = [0x55] + c = [0] + for i in range(1,bw): + d.append((int(rxd) >> (8*i)) & 0xff) + c.append((int(rxc) >> i) & 1) + elif bw == 8 and (rxc >> 4) & 1 and (rxd >> 32) & 0xff == 0xfb: + # start in lane 4 + frame = XGMIIFrame() + d = [0x55] + c = [0] + for i in range(5,8): + d.append((int(rxd) >> (8*i)) & 0xff) + c.append((int(rxc) >> i) & 1) + else: + for i in range(bw): + if (rxc >> i) & 1 and (rxd >> (8*i)) & 0xff == 0xfd: + # terminate + frame.parse(d, c) + self.queue.append(frame) + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + frame = None + d = [] + c = [] + break + else: + d.append((int(rxd) >> (8*i)) & 0xff) + c.append((int(rxc) >> i) & 1) + + return logic From d13abd76c411a38c58d739ca43205932ae0bcf05 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 29 Sep 2016 20:07:29 -0700 Subject: [PATCH 312/617] Add generic IO components --- rtl/iddr.v | 129 ++++++++++++++++++++++++++++++ rtl/oddr.v | 129 ++++++++++++++++++++++++++++++ rtl/ssio_ddr_in.v | 171 ++++++++++++++++++++++++++++++++++++++++ rtl/ssio_ddr_in_diff.v | 119 ++++++++++++++++++++++++++++ rtl/ssio_ddr_out.v | 82 +++++++++++++++++++ rtl/ssio_ddr_out_diff.v | 119 ++++++++++++++++++++++++++++ rtl/ssio_sdr_in.v | 163 ++++++++++++++++++++++++++++++++++++++ rtl/ssio_sdr_in_diff.v | 113 ++++++++++++++++++++++++++ rtl/ssio_sdr_out.v | 73 +++++++++++++++++ rtl/ssio_sdr_out_diff.v | 112 ++++++++++++++++++++++++++ 10 files changed, 1210 insertions(+) create mode 100644 rtl/iddr.v create mode 100644 rtl/oddr.v create mode 100644 rtl/ssio_ddr_in.v create mode 100644 rtl/ssio_ddr_in_diff.v create mode 100644 rtl/ssio_ddr_out.v create mode 100644 rtl/ssio_ddr_out_diff.v create mode 100644 rtl/ssio_sdr_in.v create mode 100644 rtl/ssio_sdr_in_diff.v create mode 100644 rtl/ssio_sdr_out.v create mode 100644 rtl/ssio_sdr_out_diff.v diff --git a/rtl/iddr.v b/rtl/iddr.v new file mode 100644 index 000000000..cc3879ca2 --- /dev/null +++ b/rtl/iddr.v @@ -0,0 +1,129 @@ +/* + +Copyright (c) 2016 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 + +/* + * Generic IDDR module + */ +module iddr # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire clk, + + input wire [WIDTH-1:0] d, + + output wire [WIDTH-1:0] q1, + output wire [WIDTH-1:0] q2 +); + +genvar n; + +generate + +if (TARGET == "XILINX") begin + for (n = 0; n < WIDTH; n = n + 1) begin + if (IODDR_STYLE == "IODDR") begin + IDDR #( + .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), + .SRTYPE("ASYNC") + ) + iddr_inst ( + .Q1(q1[n]), + .Q2(q2[n]), + .C(clk), + .CE(1'b1), + .D(d[n]), + .R(1'b0), + .S(1'b0) + ); + end else if (IODDR_STYLE == "IODDR2") begin + IDDR2 #( + .DDR_ALIGNMENT("C0") + ) + iddr_inst ( + .Q0(q1[n]), + .Q1(q2[n]), + .C0(clk), + .C1(~clk), + .CE(1'b1), + .D(d[n]), + .R(1'b0), + .S(1'b0) + ); + end + end +end else if (TARGET == "ALTERA") begin + altddio_in #( + .WIDTH(WIDTH), + .POWER_UP_HIGH("OFF"), + .INTENDED_DEVICE_FAMILY("Stratix V") + ) + altddio_in_inst ( + .aset(1'b0), + .datain(d), + .inclocken(1'b1), + .inclock(clk), + .aclr(1'b0), + .dataout_h(q1), + .dataout_l(q2) + ); +end else begin + reg [WIDTH-1:0] d_reg_1 = {WIDTH{1'b0}}; + reg [WIDTH-1:0] d_reg_2 = {WIDTH{1'b0}}; + + reg [WIDTH-1:0] q_reg_1 = {WIDTH{1'b0}}; + reg [WIDTH-1:0] q_reg_2 = {WIDTH{1'b0}}; + + always @(posedge clk) begin + d_reg_1 <= d; + end + + always @(negedge clk) begin + d_reg_2 <= d; + end + + always @(posedge clk) begin + q_reg_1 <= d_reg_1; + q_reg_2 <= d_reg_2; + end + + assign q1 = q_reg_1; + assign q2 = q_reg_2; +end + +endgenerate + +endmodule diff --git a/rtl/oddr.v b/rtl/oddr.v new file mode 100644 index 000000000..221045a0c --- /dev/null +++ b/rtl/oddr.v @@ -0,0 +1,129 @@ +/* + +Copyright (c) 2016 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 + +/* + * Generic ODDR module + */ +module oddr # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire clk, + + input wire [WIDTH-1:0] d1, + input wire [WIDTH-1:0] d2, + + output wire [WIDTH-1:0] q +); + +genvar n; + +generate + +if (TARGET == "XILINX") begin + for (n = 0; n < WIDTH; n = n + 1) begin + if (IODDR_STYLE == "IODDR") begin + ODDR #( + .DDR_CLK_EDGE("SAME_EDGE"), + .SRTYPE("ASYNC") + ) + oddr_inst ( + .Q(q[n]), + .C(clk), + .CE(1'b1), + .D1(d1[n]), + .D2(d2[n]), + .R(1'b0), + .S(1'b0) + ); + end else if (IODDR_STYLE == "IODDR2") begin + ODDR2 #( + .DDR_ALIGNMENT("C0"), + .SRTYPE("ASYNC") + ) + oddr_inst ( + .Q(q[n]), + .C0(clk), + .C1(~clk), + .CE(1'b1), + .D0(d1[n]), + .D1(d2[n]), + .R(1'b0), + .S(1'b0) + ); + end + end +end else if (TARGET == "ALTERA") begin + altddio_out #( + .WIDTH(WIDTH), + .POWER_UP_HIGH("OFF"), + .INTENDED_DEVICE_FAMILY("Stratix V"), + .OE_REG("UNUSED") + ) + altddio_out_inst ( + .aset(1'b0), + .datain_h(d1), + .datain_l(d2), + .outclocken(1'b1), + .outclock(clk), + .aclr(1'b0), + .dataout(q) + ); +end else begin + reg [WIDTH-1:0] d_reg_1 = {WIDTH{1'b0}}; + reg [WIDTH-1:0] d_reg_2 = {WIDTH{1'b0}}; + + reg [WIDTH-1:0] q_reg = {WIDTH{1'b0}}; + + always @(posedge clk) begin + d_reg_1 <= d1; + d_reg_2 <= d2; + end + + always @(posedge clk) begin + q_reg <= d1; + end + + always @(negedge clk) begin + q_reg <= d_reg_2; + end + + assign q = q_reg; +end + +endgenerate + +endmodule diff --git a/rtl/ssio_ddr_in.v b/rtl/ssio_ddr_in.v new file mode 100644 index 000000000..1183e1d67 --- /dev/null +++ b/rtl/ssio_ddr_in.v @@ -0,0 +1,171 @@ +/* + +Copyright (c) 2016 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 + +/* + * Generic source synchronous DDR input + */ +module ssio_ddr_in # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire input_clk, + + input wire [WIDTH-1:0] input_d, + + output wire output_clk, + + output wire [WIDTH-1:0] output_q1, + output wire [WIDTH-1:0] output_q2 +); + +wire clk_int; +wire clk_io; + +generate + +if (TARGET == "XILINX") begin + + // use Xilinx clocking primitives + + if (CLOCK_INPUT_STYLE == "BUFG") begin + + // buffer RX clock + BUFG + clk_bufg ( + .I(input_clk), + .O(clk_int) + ); + + // pass through RX clock to logic and input buffers + assign clk_io = clk_int; + assign output_clk = clk_int; + + end else if (CLOCK_INPUT_STYLE == "BUFR") begin + + assign clk_int = input_clk; + + // pass through RX clock to input buffers + BUFIO + clk_bufio ( + .I(clk_int), + .O(clk_io) + ); + + // pass through RX clock to logic + BUFR #( + .BUFR_DIVIDE("BYPASS") + ) + clk_bufr ( + .I(clk_int), + .O(output_clk), + .CE(1'b1), + .CLR(1'b0) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO") begin + + assign clk_int = input_clk; + + // pass through RX clock to input buffers + BUFIO + clk_bufio ( + .I(clk_int), + .O(clk_io) + ); + + // pass through RX clock to MAC + BUFG + clk_bufg ( + .I(clk_int), + .O(output_clk) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO2") begin + + // pass through RX clock to input buffers + BUFIO2 #( + .DIVIDE(1), + .DIVIDE_BYPASS("TRUE"), + .I_INVERT("FALSE"), + .USE_DOUBLER("FALSE") + ) + clk_bufio ( + .I(input_clk), + .DIVCLK(clk_int), + .IOCLK(clk_io), + .SERDESSTROBE() + ); + + // pass through RX clock to MAC + BUFG + clk_bufg ( + .I(clk_int), + .O(output_clk) + ); + + end + +end else begin + + // pass through RX clock to input buffers + assign clk_io = input_clk; + + // pass through RX clock to logic + assign clk_int = input_clk; + assign output_clk = clk_int; + +end + +endgenerate + +iddr #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .WIDTH(WIDTH) +) +data_iddr_inst ( + .clk(clk_io), + .d(input_d), + .q1(output_q1), + .q2(output_q2) +); + +endmodule diff --git a/rtl/ssio_ddr_in_diff.v b/rtl/ssio_ddr_in_diff.v new file mode 100644 index 000000000..e1251d232 --- /dev/null +++ b/rtl/ssio_ddr_in_diff.v @@ -0,0 +1,119 @@ +/* + +Copyright (c) 2016 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 + +/* + * Generic source synchronous DDR input + */ +module ssio_ddr_in_diff # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire input_clk_p, + input wire input_clk_n, + + input wire [WIDTH-1:0] input_d_p, + input wire [WIDTH-1:0] input_d_n, + + output wire output_clk, + + output wire [WIDTH-1:0] output_q1, + output wire [WIDTH-1:0] output_q2 +); + +wire input_clk; +wire [WIDTH-1:0] input_d; + +genvar n; + +generate + +if (TARGET == "XILINX") begin + IBUFDS + clk_ibufds_inst ( + .I(input_clk_p), + .IB(input_clk_n), + .O(input_clk) + ); + for (n = 0; n < WIDTH; n = n + 1) begin + IBUFDS + data_ibufds_inst ( + .I(input_d_p[n]), + .IB(input_d_n[n]), + .O(input_d[n]) + ); + end +end else if (TARGET == "ALTERA") begin + ALT_INBUF_DIFF + clk_inbuf_diff_inst ( + .i(input_clk_p), + .ibar(input_clk_n), + .o(input_clk) + ); + for (n = 0; n < WIDTH; n = n + 1) begin + ALT_INBUF_DIFF + data_inbuf_diff_inst ( + .i(input_d_p[n]), + .ibar(input_d_n[n]), + .o(input_d[n]) + ); + end +end else begin + assign input_clk = input_clk_p; + assign input_d = input_d_p; +end + +endgenerate + +ssio_ddr_in #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .WIDTH(WIDTH) +) +ssio_ddr_in_inst( + .input_clk(input_clk), + .input_d(input_d), + .output_clk(output_clk), + .output_q1(output_q1), + .output_q2(output_q2) +); + +endmodule diff --git a/rtl/ssio_ddr_out.v b/rtl/ssio_ddr_out.v new file mode 100644 index 000000000..9d6ac47a5 --- /dev/null +++ b/rtl/ssio_ddr_out.v @@ -0,0 +1,82 @@ +/* + +Copyright (c) 2016 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 + +/* + * Generic source synchronous DDR output + */ +module ssio_ddr_out # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Use 90 degree clock for transmit ("TRUE", "FALSE") + parameter USE_CLK90 = "TRUE", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire clk, + input wire clk90, + + input wire [WIDTH-1:0] input_d1, + input wire [WIDTH-1:0] input_d2, + + output wire output_clk, + output wire [WIDTH-1:0] output_q +); + +wire ref_clk = USE_CLK90 == "TRUE" ? clk90 : clk; + +oddr #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .WIDTH(1) +) +clk_oddr_inst ( + .clk(ref_clk), + .d1(1'b1), + .d2(1'b0), + .q(output_clk) +); + +oddr #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .WIDTH(WIDTH) +) +data_oddr_inst ( + .clk(clk), + .d1(input_d1), + .d2(input_d2), + .q(output_q) +); + +endmodule diff --git a/rtl/ssio_ddr_out_diff.v b/rtl/ssio_ddr_out_diff.v new file mode 100644 index 000000000..796eb7c9d --- /dev/null +++ b/rtl/ssio_ddr_out_diff.v @@ -0,0 +1,119 @@ +/* + +Copyright (c) 2016 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 + +/* + * Generic source synchronous DDR output + */ +module ssio_ddr_out_diff # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Use 90 degree clock for transmit ("TRUE", "FALSE") + parameter USE_CLK90 = "TRUE", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire clk, + input wire clk90, + + input wire [WIDTH-1:0] input_d1, + input wire [WIDTH-1:0] input_d2, + + output wire output_clk_p, + output wire output_clk_n, + output wire [WIDTH-1:0] output_q_p, + output wire [WIDTH-1:0] output_q_n +); + +wire output_clk; +wire [WIDTH-1:0] output_q; + +ssio_ddr_out #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .USE_CLK90(USE_CLK90), + .WIDTH(WIDTH) +) +ssio_ddr_out_inst( + .clk(clk), + .clk90(clk90), + .input_d1(input_d1), + .input_d2(input_d2), + .output_clk(output_clk), + .output_q(output_q) +); + +genvar n; + +generate + +if (TARGET == "XILINX") begin + OBUFDS + clk_obufds_inst ( + .I(output_clk), + .O(output_clk_p), + .OB(output_clk_n) + ); + for (n = 0; n < WIDTH; n = n + 1) begin + OBUFDS + data_obufds_inst ( + .I(output_q[n]), + .O(output_q_p[n]), + .OB(output_q_n[n]) + ); + end +end else if (TARGET == "ALTERA") begin + ALT_OUTBUF_DIFF + clk_outbuf_diff_inst ( + .i(output_clk), + .o(output_clk_p), + .obar(output_clk_n) + ); + for (n = 0; n < WIDTH; n = n + 1) begin + ALT_OUTBUF_DIFF + data_outbuf_diff_inst ( + .i(output_q[n]), + .o(output_q_p[n]), + .obar(output_q_n[n]) + ); + end +end else begin + assign output_clk_p = output_clk; + assign output_clk_n = ~output_clk; + assign output_q_p = output_q; + assign output_q_n = ~output_q; +end + +endgenerate + +endmodule diff --git a/rtl/ssio_sdr_in.v b/rtl/ssio_sdr_in.v new file mode 100644 index 000000000..92dc9d164 --- /dev/null +++ b/rtl/ssio_sdr_in.v @@ -0,0 +1,163 @@ +/* + +Copyright (c) 2016 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 + +/* + * Generic source synchronous SDR input + */ +module ssio_sdr_in # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire input_clk, + + input wire [WIDTH-1:0] input_d, + + output wire output_clk, + + output wire [WIDTH-1:0] output_q +); + +wire clk_int; +wire clk_io; + +generate + +if (TARGET == "XILINX") begin + + // use Xilinx clocking primitives + + if (CLOCK_INPUT_STYLE == "BUFG") begin + + // buffer RX clock + BUFG + clk_bufg ( + .I(input_clk), + .O(clk_int) + ); + + // pass through RX clock to logic and input buffers + assign clk_io = clk_int; + assign output_clk = clk_int; + + end else if (CLOCK_INPUT_STYLE == "BUFR") begin + + assign clk_int = input_clk; + + // pass through RX clock to input buffers + BUFIO + clk_bufio ( + .I(clk_int), + .O(clk_io) + ); + + // pass through RX clock to logic + BUFR #( + .BUFR_DIVIDE("BYPASS") + ) + clk_bufr ( + .I(clk_int), + .O(output_clk), + .CE(1'b1), + .CLR(1'b0) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO") begin + + assign clk_int = input_clk; + + // pass through RX clock to input buffers + BUFIO + clk_bufio ( + .I(clk_int), + .O(clk_io) + ); + + // pass through RX clock to MAC + BUFG + clk_bufg ( + .I(clk_int), + .O(output_clk) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO2") begin + + // pass through RX clock to input buffers + BUFIO2 #( + .DIVIDE(1), + .DIVIDE_BYPASS("TRUE"), + .I_INVERT("FALSE"), + .USE_DOUBLER("FALSE") + ) + clk_bufio ( + .I(input_clk), + .DIVCLK(clk_int), + .IOCLK(clk_io), + .SERDESSTROBE() + ); + + // pass through RX clock to MAC + BUFG + clk_bufg ( + .I(clk_int), + .O(output_clk) + ); + + end + +end else begin + + // pass through RX clock to input buffers + assign clk_io = input_clk; + + // pass through RX clock to logic + assign clk_int = input_clk; + assign output_clk = clk_int; + +end + +endgenerate + +(* IOB = "TRUE" *) +reg [WIDTH-1:0] output_q_reg = {WIDTH{1'b0}}; + +assign output_q = output_q_reg; + +always @(posedge clk_io) begin + output_q_reg <= input_d; +end + +endmodule diff --git a/rtl/ssio_sdr_in_diff.v b/rtl/ssio_sdr_in_diff.v new file mode 100644 index 000000000..95b0683f3 --- /dev/null +++ b/rtl/ssio_sdr_in_diff.v @@ -0,0 +1,113 @@ +/* + +Copyright (c) 2016 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 + +/* + * Generic source synchronous SDR input + */ +module ssio_sdr_in_diff # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire input_clk_p, + input wire input_clk_n, + + input wire [WIDTH-1:0] input_d_p, + input wire [WIDTH-1:0] input_d_n, + + output wire output_clk, + + output wire [WIDTH-1:0] output_q +); + +wire input_clk; +wire [WIDTH-1:0] input_d; + +genvar n; + +generate + +if (TARGET == "XILINX") begin + IBUFDS + clk_ibufds_inst ( + .I(input_clk_p), + .IB(input_clk_n), + .O(input_clk) + ); + for (n = 0; n < WIDTH; n = n + 1) begin + IBUFDS + data_ibufds_inst ( + .I(input_d_p[n]), + .IB(input_d_n[n]), + .O(input_d[n]) + ); + end +end else if (TARGET == "ALTERA") begin + ALT_INBUF_DIFF + clk_inbuf_diff_inst ( + .i(input_clk_p), + .ibar(input_clk_n), + .o(input_clk) + ); + for (n = 0; n < WIDTH; n = n + 1) begin + ALT_INBUF_DIFF + data_inbuf_diff_inst ( + .i(input_d_p[n]), + .ibar(input_d_n[n]), + .o(input_d[n]) + ); + end +end else begin + assign input_clk = input_clk_p; + assign input_d = input_d_p; +end + +endgenerate + +ssio_sdr_in #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .WIDTH(WIDTH) +) +ssio_ddr_in_inst( + .input_clk(input_clk), + .input_d(input_d), + .output_clk(output_clk), + .output_q(output_q) +); + +endmodule diff --git a/rtl/ssio_sdr_out.v b/rtl/ssio_sdr_out.v new file mode 100644 index 000000000..9f3527bb0 --- /dev/null +++ b/rtl/ssio_sdr_out.v @@ -0,0 +1,73 @@ +/* + +Copyright (c) 2016 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 + +/* + * Generic source synchronous SDR output + */ +module ssio_sdr_out # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire clk, + + input wire [WIDTH-1:0] input_d, + + output wire output_clk, + output wire [WIDTH-1:0] output_q +); + +oddr #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .WIDTH(1) +) +clk_oddr_inst ( + .clk(clk), + .d1(1'b0), + .d2(1'b1), + .q(output_clk) +); + +(* IOB = "TRUE" *) +reg [WIDTH-1:0] output_q_reg = {WIDTH{1'b0}}; + +assign output_q = output_q_reg; + +always @(posedge clk) begin + output_q_reg <= input_d; +end + +endmodule diff --git a/rtl/ssio_sdr_out_diff.v b/rtl/ssio_sdr_out_diff.v new file mode 100644 index 000000000..93a1513d3 --- /dev/null +++ b/rtl/ssio_sdr_out_diff.v @@ -0,0 +1,112 @@ +/* + +Copyright (c) 2016 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 + +/* + * Generic source synchronous SDR output + */ +module ssio_sdr_out_diff # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire clk, + + input wire [WIDTH-1:0] input_d, + + output wire output_clk_p, + output wire output_clk_n, + output wire [WIDTH-1:0] output_q_p, + output wire [WIDTH-1:0] output_q_n +); + +wire output_clk; +wire [WIDTH-1:0] output_q; + +ssio_sdr_out #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .WIDTH(WIDTH) +) +ssio_ddr_out_inst( + .clk(clk), + .input_d(input_d), + .output_clk(output_clk), + .output_q(output_q) +); + +genvar n; + +generate + +if (TARGET == "XILINX") begin + OBUFDS + clk_obufds_inst ( + .I(output_clk), + .O(output_clk_p), + .OB(output_clk_n) + ); + for (n = 0; n < WIDTH; n = n + 1) begin + OBUFDS + data_obufds_inst ( + .I(output_q[n]), + .O(output_q_p[n]), + .OB(output_q_n[n]) + ); + end +end else if (TARGET == "ALTERA") begin + ALT_OUTBUF_DIFF + clk_outbuf_diff_inst ( + .i(output_clk), + .o(output_clk_p), + .obar(output_clk_n) + ); + for (n = 0; n < WIDTH; n = n + 1) begin + ALT_OUTBUF_DIFF + data_outbuf_diff_inst ( + .i(output_q[n]), + .o(output_q_p[n]), + .obar(output_q_n[n]) + ); + end +end else begin + assign output_clk_p = output_clk; + assign output_clk_n = ~output_clk; + assign output_q_p = output_q; + assign output_q_n = ~output_q; +end + +endgenerate + +endmodule From 15330486e836a03816d4cc7d232257e24ae458a8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 29 Sep 2016 20:10:10 -0700 Subject: [PATCH 313/617] Convert GMII and RGMII shims to use generic IO components --- example/ATLYS/fpga/fpga/Makefile | 4 + example/ATLYS/fpga/tb/test_fpga_core.py | 4 + example/NexysVideo/fpga/fpga/Makefile | 4 + example/NexysVideo/fpga/tb/test_fpga_core.py | 4 + rtl/gmii_phy_if.v | 201 +------- rtl/rgmii_phy_if.v | 509 ++----------------- 6 files changed, 77 insertions(+), 649 deletions(-) diff --git a/example/ATLYS/fpga/fpga/Makefile b/example/ATLYS/fpga/fpga/Makefile index 9745f6886..96c994cc6 100644 --- a/example/ATLYS/fpga/fpga/Makefile +++ b/example/ATLYS/fpga/fpga/Makefile @@ -14,6 +14,10 @@ SYN_FILES += rtl/fpga_core.v SYN_FILES += rtl/debounce_switch.v SYN_FILES += rtl/sync_reset.v SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/iddr.v +SYN_FILES += lib/eth/rtl/oddr.v +SYN_FILES += lib/eth/rtl/ssio_sdr_in.v +SYN_FILES += lib/eth/rtl/ssio_sdr_out.v SYN_FILES += lib/eth/rtl/gmii_phy_if.v SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index 73450705f..639c5919f 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -37,6 +37,10 @@ testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/iddr.v") +srcs.append("../lib/eth/rtl/oddr.v") +srcs.append("../lib/eth/rtl/ssio_sdr_in.v") +srcs.append("../lib/eth/rtl/ssio_sdr_out.v") srcs.append("../lib/eth/rtl/gmii_phy_if.v") srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_1g.v") diff --git a/example/NexysVideo/fpga/fpga/Makefile b/example/NexysVideo/fpga/fpga/Makefile index 733bb785f..88f1a76a9 100644 --- a/example/NexysVideo/fpga/fpga/Makefile +++ b/example/NexysVideo/fpga/fpga/Makefile @@ -10,6 +10,10 @@ SYN_FILES += rtl/fpga_core.v SYN_FILES += rtl/debounce_switch.v SYN_FILES += rtl/sync_reset.v SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/iddr.v +SYN_FILES += lib/eth/rtl/oddr.v +SYN_FILES += lib/eth/rtl/ssio_ddr_in.v +SYN_FILES += lib/eth/rtl/ssio_ddr_out.v SYN_FILES += lib/eth/rtl/rgmii_phy_if.v SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.py b/example/NexysVideo/fpga/tb/test_fpga_core.py index 0b57b14d3..8796e7b34 100755 --- a/example/NexysVideo/fpga/tb/test_fpga_core.py +++ b/example/NexysVideo/fpga/tb/test_fpga_core.py @@ -37,6 +37,10 @@ testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/iddr.v") +srcs.append("../lib/eth/rtl/oddr.v") +srcs.append("../lib/eth/rtl/ssio_ddr_in.v") +srcs.append("../lib/eth/rtl/ssio_ddr_out.v") srcs.append("../lib/eth/rtl/rgmii_phy_if.v") srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_1g.v") diff --git a/rtl/gmii_phy_if.v b/rtl/gmii_phy_if.v index 2dc7fb34c..5a2ddd9fa 100644 --- a/rtl/gmii_phy_if.v +++ b/rtl/gmii_phy_if.v @@ -39,6 +39,7 @@ module gmii_phy_if # parameter IODDR_STYLE = "IODDR2", // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale // Use BUFIO2 for Spartan-6 parameter CLOCK_INPUT_STYLE = "BUFIO2" ) @@ -73,147 +74,33 @@ module gmii_phy_if # output wire phy_gmii_tx_er ); -wire phy_gmii_rx_clk_int; -wire phy_gmii_rx_clk_io; -wire phy_gmii_tx_clk_int; +ssio_sdr_in # +( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .WIDTH(10) +) +rx_ssio_sdr_inst ( + .input_clk(phy_gmii_rx_clk), + .input_d({phy_gmii_rxd, phy_gmii_rx_dv, phy_gmii_rx_er}), + .output_clk(mac_gmii_rx_clk), + .output_q({mac_gmii_rxd, mac_gmii_rx_dv, mac_gmii_rx_er}) +); -generate +ssio_sdr_out # +( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .WIDTH(10) +) +tx_ssio_sdr_inst ( + .clk(clk), + .input_d({mac_gmii_txd, mac_gmii_tx_en, mac_gmii_tx_er}), + .output_clk(phy_gmii_tx_clk), + .output_q({phy_gmii_txd, phy_gmii_tx_en, phy_gmii_tx_er}) +); -if (TARGET == "XILINX") begin - - // use Xilinx clocking primitives - - if (CLOCK_INPUT_STYLE == "BUFG") begin - - // buffer RX clock - BUFG - phy_gmii_rx_clk_bufg ( - .I(phy_gmii_rx_clk), - .O(phy_gmii_rx_clk_int) - ); - - // pass through RX clock to MAC and input buffers - assign phy_gmii_rx_clk_io = phy_gmii_rx_clk_int; - assign mac_gmii_rx_clk = phy_gmii_rx_clk_int; - - end else if (CLOCK_INPUT_STYLE == "BUFR") begin - - assign phy_gmii_rx_clk_int = phy_gmii_rx_clk; - - // pass through RX clock to input buffers - BUFIO - phy_gmii_rx_clk_bufio ( - .I(phy_gmii_rx_clk_int), - .O(phy_gmii_rx_clk_io) - ); - - // pass through RX clock to MAC - BUFR #( - .BUFR_DIVIDE("BYPASS") - ) - phy_gmii_rx_clk_bufr ( - .I(phy_gmii_rx_clk_int), - .O(mac_gmii_rx_clk), - .CE(1'b1), - .CLR(1'b0) - ); - - end else if (CLOCK_INPUT_STYLE == "BUFIO") begin - - assign phy_gmii_rx_clk_int = phy_gmii_rx_clk; - - // pass through RX clock to input buffers - BUFIO - phy_gmii_rx_clk_bufio ( - .I(phy_gmii_rx_clk_int), - .O(phy_gmii_rx_clk_io) - ); - - // pass through RX clock to MAC - BUFG - phy_gmii_rx_clk_bufg ( - .I(phy_gmii_rx_clk_int), - .O(mac_gmii_rx_clk) - ); - - end else if (CLOCK_INPUT_STYLE == "BUFIO2") begin - - // pass through RX clock to input buffers - BUFIO2 #( - .DIVIDE(1), - .DIVIDE_BYPASS("TRUE"), - .I_INVERT("FALSE"), - .USE_DOUBLER("FALSE") - ) - phy_gmii_rx_clk_bufio ( - .I(phy_gmii_rx_clk), - .DIVCLK(phy_gmii_rx_clk_int), - .IOCLK(phy_gmii_rx_clk_io), - .SERDESSTROBE() - ); - - // pass through RX clock to MAC - BUFG - phy_gmii_rx_clk_bufg ( - .I(phy_gmii_rx_clk_int), - .O(mac_gmii_rx_clk) - ); - - end - - // pass through clock to MAC - assign mac_gmii_tx_clk = clk; - - // pass through clock to PHY - assign phy_gmii_tx_clk_int = clk; - - // invert to center clock edge in valid window - if (IODDR_STYLE == "IODDR") begin - ODDR - phy_gmii_tx_clk_oddr ( - .Q(phy_gmii_tx_clk), - .C(phy_gmii_tx_clk_int), - .CE(1'b1), - .D1(1'b0), - .D2(1'b1), - .R(1'b0), - .S(1'b0) - ); - end else if (IODDR_STYLE == "IODDR2") begin - ODDR2 - phy_gmii_tx_clk_oddr ( - .Q(phy_gmii_tx_clk), - .C0(phy_gmii_tx_clk_int), - .C1(~phy_gmii_tx_clk_int), - .CE(1'b1), - .D0(1'b0), - .D1(1'b1), - .R(1'b0), - .S(1'b0) - ); - end - -end else begin - - // pass through RX clock to input buffers - assign phy_gmii_rx_clk_io = phy_gmii_rx_clk; - - // pass through RX clock to MAC - assign phy_gmii_rx_clk_int = phy_gmii_rx_clk; - assign mac_gmii_rx_clk = phy_gmii_rx_clk_int; - - // pass through clock to MAC - assign mac_gmii_tx_clk = clk; - - // pass through clock to PHY - assign phy_gmii_tx_clk_int = clk; - - // invert to center clock edge in valid window - assign phy_gmii_tx_clk = ~phy_gmii_tx_clk_int; - -end - -endgenerate +assign mac_gmii_tx_clk = clk; // reset sync reg [3:0] tx_rst_reg = 4'hf; @@ -238,40 +125,4 @@ always @(posedge mac_gmii_rx_clk or posedge rst) begin end end -// register RX data from PHY to MAC -(* IOB = "TRUE" *) -reg [7:0] gmii_rxd_reg = 8'd0; -(* IOB = "TRUE" *) -reg gmii_rx_dv_reg = 1'b0; -(* IOB = "TRUE" *) -reg gmii_rx_er_reg = 1'b0; - -always @(posedge phy_gmii_rx_clk_io) begin - gmii_rxd_reg <= phy_gmii_rxd; - gmii_rx_dv_reg <= phy_gmii_rx_dv; - gmii_rx_er_reg <= phy_gmii_rx_er; -end - -assign mac_gmii_rxd = gmii_rxd_reg; -assign mac_gmii_rx_dv = gmii_rx_dv_reg; -assign mac_gmii_rx_er = gmii_rx_er_reg; - -// register TX data from MAC to PHY -(* IOB = "TRUE" *) -reg [7:0] gmii_txd_reg = 8'd0; -(* IOB = "TRUE" *) -reg gmii_tx_en_reg = 1'b0; -(* IOB = "TRUE" *) -reg gmii_tx_er_reg = 1'b0; - -always @(posedge phy_gmii_tx_clk_int) begin - gmii_txd_reg <= mac_gmii_txd; - gmii_tx_en_reg <= mac_gmii_tx_en; - gmii_tx_er_reg <= mac_gmii_tx_er; -end - -assign phy_gmii_txd = gmii_txd_reg; -assign phy_gmii_tx_en = gmii_tx_en_reg; -assign phy_gmii_tx_er = gmii_tx_er_reg; - endmodule diff --git a/rtl/rgmii_phy_if.v b/rtl/rgmii_phy_if.v index 2e9706187..75664a39d 100644 --- a/rtl/rgmii_phy_if.v +++ b/rtl/rgmii_phy_if.v @@ -39,6 +39,7 @@ module rgmii_phy_if # parameter IODDR_STYLE = "IODDR2", // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale // Use BUFIO2 for Spartan-6 parameter CLOCK_INPUT_STYLE = "BUFIO2", // Use 90 degree clock for RGMII transmit ("TRUE", "FALSE") @@ -74,152 +75,44 @@ module rgmii_phy_if # output wire phy_rgmii_tx_ctl ); -wire phy_rgmii_rx_clk_int; -wire phy_rgmii_rx_clk_io; -wire phy_rgmii_tx_clk_int; -wire phy_rgmii_tx_ref_clk_int; +wire rgmii_rx_ctl_1; +wire rgmii_rx_ctl_2; -generate +ssio_ddr_in # +( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .IODDR_STYLE(IODDR_STYLE), + .WIDTH(5) +) +rx_ssio_ddr_inst ( + .input_clk(phy_rgmii_rx_clk), + .input_d({phy_rgmii_rxd, phy_rgmii_rx_ctl}), + .output_clk(mac_gmii_rx_clk), + .output_q1({mac_gmii_rxd[3:0], rgmii_rx_ctl_1}), + .output_q2({mac_gmii_rxd[7:4], rgmii_rx_ctl_2}) +); -if (TARGET == "XILINX") begin +assign mac_gmii_rx_dv = rgmii_rx_ctl_1; +assign mac_gmii_rx_er = rgmii_rx_ctl_1 ^ rgmii_rx_ctl_2; - // use Xilinx clocking primitives +ssio_ddr_out # +( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .USE_CLK90(USE_CLK90), + .WIDTH(5) +) +tx_ssio_ddr_inst ( + .clk(clk), + .clk90(clk90), + .input_d1({mac_gmii_txd[3:0], mac_gmii_tx_en}), + .input_d2({mac_gmii_txd[7:4], mac_gmii_tx_en ^ mac_gmii_tx_er}), + .output_clk(phy_rgmii_tx_clk), + .output_q({phy_rgmii_txd, phy_rgmii_tx_ctl}) +); - if (CLOCK_INPUT_STYLE == "BUFG") begin - - // buffer RX clock - BUFG - phy_rgmii_rx_clk_bufg ( - .I(phy_rgmii_rx_clk), - .O(phy_rgmii_rx_clk_int) - ); - - // pass through RX clock to MAC and input buffers - assign phy_rgmii_rx_clk_io = phy_rgmii_rx_clk_int; - assign mac_gmii_rx_clk = phy_rgmii_rx_clk_int; - - end else if (CLOCK_INPUT_STYLE == "BUFR") begin - - assign phy_rgmii_rx_clk_int = phy_rgmii_rx_clk; - - // pass through RX clock to input buffers - BUFIO - phy_rgmii_rx_clk_bufio ( - .I(phy_rgmii_rx_clk_int), - .O(phy_rgmii_rx_clk_io) - ); - - // pass through RX clock to MAC - BUFR #( - .BUFR_DIVIDE("BYPASS") - ) - phy_rgmii_rx_clk_bufr ( - .I(phy_rgmii_rx_clk_int), - .O(mac_gmii_rx_clk), - .CE(1'b1), - .CLR(1'b0) - ); - - end else if (CLOCK_INPUT_STYLE == "BUFIO") begin - - assign phy_rgmii_rx_clk_int = phy_rgmii_rx_clk; - - // pass through RX clock to input buffers - BUFIO - phy_rgmii_rx_clk_bufio ( - .I(phy_rgmii_rx_clk_int), - .O(phy_rgmii_rx_clk_io) - ); - - // pass through RX clock to MAC - BUFG - phy_rgmii_rx_clk_bufg ( - .I(phy_rgmii_rx_clk_int), - .O(mac_gmii_rx_clk) - ); - - end else if (CLOCK_INPUT_STYLE == "BUFIO2") begin - - // pass through RX clock to input buffers - BUFIO2 #( - .DIVIDE(1), - .DIVIDE_BYPASS("TRUE"), - .I_INVERT("FALSE"), - .USE_DOUBLER("FALSE") - ) - phy_rgmii_rx_clk_bufio ( - .I(phy_rgmii_rx_clk), - .DIVCLK(phy_rgmii_rx_clk_int), - .IOCLK(phy_rgmii_rx_clk_io), - .SERDESSTROBE() - ); - - // pass through RX clock to MAC - BUFG - phy_rgmii_rx_clk_bufg ( - .I(phy_rgmii_rx_clk_int), - .O(mac_gmii_rx_clk) - ); - - end - - // pass through clock to MAC - assign mac_gmii_tx_clk = clk; - - // pass through clock to PHY - assign phy_rgmii_tx_clk_int = clk; - assign phy_rgmii_tx_ref_clk_int = USE_CLK90 == "TRUE" ? clk90 : phy_rgmii_tx_clk_int; - - // pass through clock to PHY - if (IODDR_STYLE == "IODDR") begin - ODDR - phy_gmii_tx_clk_oddr ( - .Q(phy_rgmii_tx_clk), - .C(phy_rgmii_tx_ref_clk_int), - .CE(1'b1), - .D1(1'b1), - .D2(1'b0), - .R(1'b0), - .S(1'b0) - ); - end else if (IODDR_STYLE == "IODDR2") begin - ODDR2 - phy_gmii_tx_clk_oddr ( - .Q(phy_rgmii_tx_clk), - .C0(phy_rgmii_tx_ref_clk_int), - .C1(~phy_rgmii_tx_ref_clk_int), - .C0(clk90), - .C1(~clk90), - .CE(1'b1), - .D0(1'b1), - .D1(1'b0), - .R(1'b0), - .S(1'b0) - ); - end - -end else begin - - // pass through RX clock to input buffers - assign phy_rgmii_rx_clk_io = phy_rgmii_rx_clk; - - // pass through RX clock to MAC - assign phy_rgmii_rx_clk_int = phy_rgmii_rx_clk; - assign mac_gmii_rx_clk = phy_rgmii_rx_clk_int; - - // pass through clock to MAC - assign mac_gmii_tx_clk = clk; - - // pass through clock to PHY - assign phy_rgmii_tx_clk_int = clk; - assign phy_rgmii_tx_ref_clk_int = USE_CLK90 == "TRUE" ? clk90 : phy_rgmii_tx_clk_int; - - // pass through clock to phy - assign phy_rgmii_tx_clk = phy_rgmii_tx_ref_clk_int; - -end - -endgenerate +assign mac_gmii_tx_clk = clk; // reset sync reg [3:0] tx_rst_reg = 4'hf; @@ -244,336 +137,4 @@ always @(posedge mac_gmii_rx_clk or posedge rst) begin end end -generate - -if (TARGET == "XILINX") begin - // register RX data from PHY to MAC - wire rgmii_rx_ctl_1; - wire rgmii_rx_ctl_2; - - if (IODDR_STYLE == "IODDR") begin - IDDR #( - .DDR_CLK_EDGE("SAME_EDGE_PIPELINED") - ) - phy_rgmii_rxd_iddr_0 ( - .Q1(mac_gmii_rxd[0]), - .Q2(mac_gmii_rxd[4]), - .C(phy_rgmii_rx_clk_io), - .CE(1'b1), - .D(phy_rgmii_rxd[0]), - .R(1'b0), - .S(1'b0) - ); - IDDR #( - .DDR_CLK_EDGE("SAME_EDGE_PIPELINED") - ) - phy_rgmii_rxd_iddr_1 ( - .Q1(mac_gmii_rxd[1]), - .Q2(mac_gmii_rxd[5]), - .C(phy_rgmii_rx_clk_io), - .CE(1'b1), - .D(phy_rgmii_rxd[1]), - .R(1'b0), - .S(1'b0) - ); - IDDR #( - .DDR_CLK_EDGE("SAME_EDGE_PIPELINED") - ) - phy_rgmii_rxd_iddr_2 ( - .Q1(mac_gmii_rxd[2]), - .Q2(mac_gmii_rxd[6]), - .C(phy_rgmii_rx_clk_io), - .CE(1'b1), - .D(phy_rgmii_rxd[2]), - .R(1'b0), - .S(1'b0) - ); - IDDR #( - .DDR_CLK_EDGE("SAME_EDGE_PIPELINED") - ) - phy_rgmii_rxd_iddr_3 ( - .Q1(mac_gmii_rxd[3]), - .Q2(mac_gmii_rxd[7]), - .C(phy_rgmii_rx_clk_io), - .CE(1'b1), - .D(phy_rgmii_rxd[3]), - .R(1'b0), - .S(1'b0) - ); - IDDR #( - .DDR_CLK_EDGE("SAME_EDGE_PIPELINED") - ) - phy_rgmii_rx_ctl_iddr ( - .Q1(rgmii_rx_ctl_1), - .Q2(rgmii_rx_ctl_2), - .C(phy_rgmii_rx_clk_io), - .CE(1'b1), - .D(phy_rgmii_rx_ctl), - .R(1'b0), - .S(1'b0) - ); - end else if (IODDR_STYLE == "IODDR2") begin - IDDR2 #( - .DDR_ALIGNMENT("C0") - ) - phy_rgmii_rxd_iddr_0 ( - .Q0(mac_gmii_rxd[0]), - .Q1(mac_gmii_rxd[4]), - .C0(phy_rgmii_rx_clk_io), - .C1(~phy_rgmii_rx_clk_io), - .CE(1'b1), - .D(phy_rgmii_rxd[0]), - .R(1'b0), - .S(1'b0) - ); - IDDR2 #( - .DDR_ALIGNMENT("C0") - ) - phy_rgmii_rxd_iddr_1 ( - .Q0(mac_gmii_rxd[1]), - .Q1(mac_gmii_rxd[5]), - .C0(phy_rgmii_rx_clk_io), - .C1(~phy_rgmii_rx_clk_io), - .CE(1'b1), - .D(phy_rgmii_rxd[1]), - .R(1'b0), - .S(1'b0) - ); - IDDR2 #( - .DDR_ALIGNMENT("C0") - ) - phy_rgmii_rxd_iddr_2 ( - .Q0(mac_gmii_rxd[2]), - .Q1(mac_gmii_rxd[6]), - .C0(phy_rgmii_rx_clk_io), - .C1(~phy_rgmii_rx_clk_io), - .CE(1'b1), - .D(phy_rgmii_rxd[2]), - .R(1'b0), - .S(1'b0) - ); - IDDR2 #( - .DDR_ALIGNMENT("C0") - ) - phy_rgmii_rxd_iddr_3 ( - .Q0(mac_gmii_rxd[3]), - .Q1(mac_gmii_rxd[7]), - .C0(phy_rgmii_rx_clk_io), - .C1(~phy_rgmii_rx_clk_io), - .CE(1'b1), - .D(phy_rgmii_rxd[3]), - .R(1'b0), - .S(1'b0) - ); - IDDR2 #( - .DDR_ALIGNMENT("C0") - ) - phy_rgmii_rx_ctl_iddr ( - .Q0(rgmii_rx_ctl_1), - .Q1(rgmii_rx_ctl_2), - .C0(phy_rgmii_rx_clk_io), - .C1(~phy_rgmii_rx_clk_io), - .CE(1'b1), - .D(phy_rgmii_rx_ctl), - .R(1'b0), - .S(1'b0) - ); - end - - assign mac_gmii_rx_dv = rgmii_rx_ctl_1; - assign mac_gmii_rx_er = rgmii_rx_ctl_1 ^ rgmii_rx_ctl_2; - - // register TX data from MAC to PHY - if (IODDR_STYLE == "IODDR") begin - ODDR #( - .DDR_CLK_EDGE("SAME_EDGE") - ) - phy_rgmii_txd_oddr_0 ( - .Q(phy_rgmii_txd[0]), - .C(phy_rgmii_tx_clk_int), - .CE(1'b1), - .D1(mac_gmii_txd[0]), - .D2(mac_gmii_txd[4]), - .R(1'b0), - .S(1'b0) - ); - ODDR #( - .DDR_CLK_EDGE("SAME_EDGE") - ) - phy_rgmii_txd_oddr_1 ( - .Q(phy_rgmii_txd[1]), - .C(phy_rgmii_tx_clk_int), - .CE(1'b1), - .D1(mac_gmii_txd[1]), - .D2(mac_gmii_txd[5]), - .R(1'b0), - .S(1'b0) - ); - ODDR #( - .DDR_CLK_EDGE("SAME_EDGE") - ) - phy_rgmii_txd_oddr_2 ( - .Q(phy_rgmii_txd[2]), - .C(phy_rgmii_tx_clk_int), - .CE(1'b1), - .D1(mac_gmii_txd[2]), - .D2(mac_gmii_txd[6]), - .R(1'b0), - .S(1'b0) - ); - ODDR #( - .DDR_CLK_EDGE("SAME_EDGE") - ) - phy_rgmii_txd_oddr_3 ( - .Q(phy_rgmii_txd[3]), - .C(phy_rgmii_tx_clk_int), - .CE(1'b1), - .D1(mac_gmii_txd[3]), - .D2(mac_gmii_txd[7]), - .R(1'b0), - .S(1'b0) - ); - ODDR #( - .DDR_CLK_EDGE("SAME_EDGE") - ) - phy_rgmii_tx_ctl_oddr ( - .Q(phy_rgmii_tx_ctl), - .C(phy_rgmii_tx_clk_int), - .CE(1'b1), - .D1(mac_gmii_tx_en), - .D2(mac_gmii_tx_en ^ mac_gmii_tx_er), - .R(1'b0), - .S(1'b0) - ); - end else if (IODDR_STYLE == "IODDR2") begin - ODDR2 #( - .DDR_ALIGNMENT("C0") - ) - phy_rgmii_txd_oddr_0 ( - .Q(phy_rgmii_txd[0]), - .C0(phy_rgmii_tx_clk_int), - .C1(~phy_rgmii_tx_clk_int), - .CE(1'b1), - .D0(mac_gmii_txd[0]), - .D1(mac_gmii_txd[4]), - .R(1'b0), - .S(1'b0) - ); - ODDR2 #( - .DDR_ALIGNMENT("C0") - ) - phy_rgmii_txd_oddr_1 ( - .Q(phy_rgmii_txd[1]), - .C0(phy_rgmii_tx_clk_int), - .C1(~phy_rgmii_tx_clk_int), - .CE(1'b1), - .D0(mac_gmii_txd[1]), - .D1(mac_gmii_txd[5]), - .R(1'b0), - .S(1'b0) - ); - ODDR2 #( - .DDR_ALIGNMENT("C0") - ) - phy_rgmii_txd_oddr_2 ( - .Q(phy_rgmii_txd[2]), - .C0(phy_rgmii_tx_clk_int), - .C1(~phy_rgmii_tx_clk_int), - .CE(1'b1), - .D0(mac_gmii_txd[2]), - .D1(mac_gmii_txd[6]), - .R(1'b0), - .S(1'b0) - ); - ODDR2 #( - .DDR_ALIGNMENT("C0") - ) - phy_rgmii_txd_oddr_3 ( - .Q(phy_rgmii_txd[3]), - .C0(phy_rgmii_tx_clk_int), - .C1(~phy_rgmii_tx_clk_int), - .CE(1'b1), - .D0(mac_gmii_txd[3]), - .D1(mac_gmii_txd[7]), - .R(1'b0), - .S(1'b0) - ); - ODDR2 #( - .DDR_ALIGNMENT("C0") - ) - phy_rgmii_tx_ctl_oddr ( - .Q(phy_rgmii_tx_ctl), - .C0(phy_rgmii_tx_clk_int), - .C1(~phy_rgmii_tx_clk_int), - .CE(1'b1), - .D0(mac_gmii_tx_en), - .D1(mac_gmii_tx_en ^ mac_gmii_tx_er), - .R(1'b0), - .S(1'b0) - ); - end - -end else if (TARGET == "ALTERA") begin - -end else begin - // register RX data from PHY to MAC - reg [7:0] gmii_rxd_reg = 8'd0; - reg gmii_rx_dv_reg = 1'b0; - reg gmii_rx_er_reg = 1'b0; - - reg [3:0] rgmii_rxd_reg_1 = 4'd0; - reg [3:0] rgmii_rxd_reg_2 = 4'd0; - reg rgmii_rx_ctl_reg_1 = 1'b0; - reg rgmii_rx_ctl_reg_2 = 1'b0; - - always @(posedge phy_rgmii_rx_clk_io) begin - rgmii_rxd_reg_1 <= phy_rgmii_rxd; - rgmii_rx_ctl_reg_1 <= phy_rgmii_rx_ctl; - end - - always @(negedge phy_rgmii_rx_clk_io) begin - rgmii_rxd_reg_2 <= phy_rgmii_rxd; - rgmii_rx_ctl_reg_2 <= phy_rgmii_rx_ctl; - end - - always @(posedge phy_rgmii_rx_clk_io) begin - gmii_rxd_reg <= {rgmii_rxd_reg_2, rgmii_rxd_reg_1}; - gmii_rx_dv_reg <= rgmii_rx_ctl_reg_1; - gmii_rx_er_reg <= rgmii_rx_ctl_reg_1 ^ rgmii_rx_ctl_reg_2; - end - - assign mac_gmii_rxd = gmii_rxd_reg; - assign mac_gmii_rx_dv = gmii_rx_dv_reg; - assign mac_gmii_rx_er = gmii_rx_er_reg; - - // register TX data from MAC to PHY - reg [7:0] gmii_txd_reg = 8'd0; - reg gmii_tx_en_reg = 1'b0; - reg gmii_tx_er_reg = 1'b0; - - reg [3:0] rgmii_txd_reg = 4'd0; - reg rgmii_tx_ctl_reg = 1'b0; - - always @(posedge phy_rgmii_tx_clk_int) begin - rgmii_txd_reg <= mac_gmii_txd[3:0]; - rgmii_tx_ctl_reg <= mac_gmii_tx_en; - end - - always @(negedge phy_rgmii_tx_clk_int) begin - rgmii_txd_reg <= gmii_txd_reg[7:4]; - rgmii_tx_ctl_reg <= gmii_tx_en_reg ^ gmii_tx_er_reg; - end - - always @(posedge phy_rgmii_tx_clk_int) begin - gmii_txd_reg <= mac_gmii_txd; - gmii_tx_en_reg <= mac_gmii_tx_en; - gmii_tx_er_reg <= mac_gmii_tx_er; - end - - assign phy_rgmii_txd = rgmii_txd_reg; - assign phy_rgmii_tx_ctl = rgmii_tx_ctl_reg; -end - -endgenerate - endmodule From 0b6614e8d4e521c93854a56828d7410a88c93e1c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 30 Sep 2016 21:59:04 -0700 Subject: [PATCH 314/617] Add UDP checksum generator modules and testbenches --- rtl/udp_checksum_gen.v | 538 ++++++++++++++++++++++++++++++ rtl/udp_checksum_gen_64.v | 575 +++++++++++++++++++++++++++++++++ tb/test_udp_checksum_gen.py | 504 +++++++++++++++++++++++++++++ tb/test_udp_checksum_gen.v | 223 +++++++++++++ tb/test_udp_checksum_gen_64.py | 510 +++++++++++++++++++++++++++++ tb/test_udp_checksum_gen_64.v | 229 +++++++++++++ 6 files changed, 2579 insertions(+) create mode 100644 rtl/udp_checksum_gen.v create mode 100644 rtl/udp_checksum_gen_64.v create mode 100755 tb/test_udp_checksum_gen.py create mode 100644 tb/test_udp_checksum_gen.v create mode 100755 tb/test_udp_checksum_gen_64.py create mode 100644 tb/test_udp_checksum_gen_64.v diff --git a/rtl/udp_checksum_gen.v b/rtl/udp_checksum_gen.v new file mode 100644 index 000000000..55a9c324e --- /dev/null +++ b/rtl/udp_checksum_gen.v @@ -0,0 +1,538 @@ +/* + +Copyright (c) 2016 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 + +/* + * UDP checksum calculation module + */ +module udp_checksum_gen # +( + parameter PAYLOAD_FIFO_ADDR_WIDTH = 11, + parameter HEADER_FIFO_ADDR_WIDTH = 3 +) +( + input wire clk, + input wire rst, + + /* + * UDP frame input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [7:0] input_udp_payload_tdata, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [7:0] output_udp_payload_tdata, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Status signals + */ + output wire busy +); + +/* + +UDP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + + source port 2 octets + desination port 2 octets + length 2 octets + checksum 2 octets + + payload length octets + +This module receives a UDP frame with header fields in parallel and payload on +an AXI stream interface, calculates the length and checksum, then produces the +header fields in parallel along with the UDP payload in a separate AXI stream. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_SUM_HEADER_1 = 3'd1, + STATE_SUM_HEADER_2 = 3'd2, + STATE_SUM_HEADER_3 = 3'd3, + STATE_SUM_PAYLOAD = 3'd4, + STATE_FINISH_SUM = 3'd5; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_udp_hdr; +reg shift_payload_in; +reg [31:0] checksum_part; + +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; + +reg [31:0] checksum_reg = 32'd0, checksum_next; + +reg [47:0] eth_dest_mac_reg = 48'd0; +reg [47:0] eth_src_mac_reg = 48'd0; +reg [15:0] eth_type_reg = 16'd0; +reg [3:0] ip_version_reg = 4'd0; +reg [3:0] ip_ihl_reg = 4'd0; +reg [5:0] ip_dscp_reg = 6'd0; +reg [1:0] ip_ecn_reg = 2'd0; +reg [15:0] ip_identification_reg = 16'd0; +reg [2:0] ip_flags_reg = 3'd0; +reg [12:0] ip_fragment_offset_reg = 13'd0; +reg [7:0] ip_ttl_reg = 8'd0; +reg [15:0] ip_header_checksum_reg = 16'd0; +reg [31:0] ip_source_ip_reg = 32'd0; +reg [31:0] ip_dest_ip_reg = 32'd0; +reg [15:0] udp_source_port_reg = 16'd0; +reg [15:0] udp_dest_port_reg = 16'd0; + +reg hdr_valid_reg = 0, hdr_valid_next; + +reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; + +reg busy_reg = 1'b0; + +/* + * UDP Payload FIFO + */ +wire [7:0] input_udp_payload_fifo_tdata; +wire input_udp_payload_fifo_tvalid; +wire input_udp_payload_fifo_tready; +wire input_udp_payload_fifo_tlast; +wire input_udp_payload_fifo_tuser; + +wire [7:0] output_udp_payload_fifo_tdata; +wire output_udp_payload_fifo_tvalid; +wire output_udp_payload_fifo_tready; +wire output_udp_payload_fifo_tlast; +wire output_udp_payload_fifo_tuser; + +axis_fifo #( + .DATA_WIDTH(8), + .ADDR_WIDTH(PAYLOAD_FIFO_ADDR_WIDTH) +) +payload_fifo ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_udp_payload_fifo_tdata), + .input_axis_tvalid(input_udp_payload_fifo_tvalid), + .input_axis_tready(input_udp_payload_fifo_tready), + .input_axis_tlast(input_udp_payload_fifo_tlast), + .input_axis_tuser(input_udp_payload_fifo_tuser), + // AXI output + .output_axis_tdata(output_udp_payload_fifo_tdata), + .output_axis_tvalid(output_udp_payload_fifo_tvalid), + .output_axis_tready(output_udp_payload_fifo_tready), + .output_axis_tlast(output_udp_payload_fifo_tlast), + .output_axis_tuser(output_udp_payload_fifo_tuser) +); + +assign input_udp_payload_fifo_tdata = input_udp_payload_tdata; +assign input_udp_payload_fifo_tvalid = input_udp_payload_tvalid & shift_payload_in; +assign input_udp_payload_tready = input_udp_payload_fifo_tready & shift_payload_in; +assign input_udp_payload_fifo_tlast = input_udp_payload_tlast; +assign input_udp_payload_fifo_tuser = input_udp_payload_tuser; + +assign output_udp_payload_tdata = output_udp_payload_fifo_tdata; +assign output_udp_payload_tvalid = output_udp_payload_fifo_tvalid; +assign output_udp_payload_fifo_tready = output_udp_payload_tready; +assign output_udp_payload_tlast = output_udp_payload_fifo_tlast; +assign output_udp_payload_tuser = output_udp_payload_fifo_tuser; + +/* + * UDP Header FIFO + */ +reg [HEADER_FIFO_ADDR_WIDTH:0] header_fifo_wr_ptr_reg = {HEADER_FIFO_ADDR_WIDTH+1{1'b0}}, header_fifo_wr_ptr_next; +reg [HEADER_FIFO_ADDR_WIDTH:0] header_fifo_rd_ptr_reg = {HEADER_FIFO_ADDR_WIDTH+1{1'b0}}, header_fifo_rd_ptr_next; + +reg [47:0] eth_dest_mac_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [47:0] eth_src_mac_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] eth_type_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [3:0] ip_version_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [3:0] ip_ihl_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [5:0] ip_dscp_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [1:0] ip_ecn_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] ip_identification_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [2:0] ip_flags_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [12:0] ip_fragment_offset_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [7:0] ip_ttl_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] ip_header_checksum_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [31:0] ip_source_ip_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [31:0] ip_dest_ip_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] udp_source_port_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] udp_dest_port_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] udp_length_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] udp_checksum_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; + +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; +reg [3:0] output_ip_version_reg = 4'd0; +reg [3:0] output_ip_ihl_reg = 4'd0; +reg [5:0] output_ip_dscp_reg = 6'd0; +reg [1:0] output_ip_ecn_reg = 2'd0; +reg [15:0] output_ip_identification_reg = 16'd0; +reg [2:0] output_ip_flags_reg = 3'd0; +reg [12:0] output_ip_fragment_offset_reg = 13'd0; +reg [7:0] output_ip_ttl_reg = 8'd0; +reg [15:0] output_ip_header_checksum_reg = 16'd0; +reg [31:0] output_ip_source_ip_reg = 32'd0; +reg [31:0] output_ip_dest_ip_reg = 32'd0; +reg [15:0] output_udp_source_port_reg = 16'd0; +reg [15:0] output_udp_dest_port_reg = 16'd0; +reg [15:0] output_udp_length_reg = 16'd0; +reg [15:0] output_udp_checksum_reg = 16'd0; + +reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; + +// full when first MSB different but rest same +wire header_fifo_full = ((header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH] != header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH]) && + (header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0] == header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0])); +// empty when pointers match exactly +wire header_fifo_empty = header_fifo_wr_ptr_reg == header_fifo_rd_ptr_reg; + +// control signals +reg header_fifo_write; +reg header_fifo_read; + +wire header_fifo_ready = ~header_fifo_full; + +assign output_udp_hdr_valid = output_udp_hdr_valid_reg; + +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_udp_length_reg + 16'd20; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = 8'h11; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_udp_source_port = output_udp_source_port_reg; +assign output_udp_dest_port = output_udp_dest_port_reg; +assign output_udp_length = output_udp_length_reg; +assign output_udp_checksum = output_udp_checksum_reg; + +// Write logic +always @* begin + header_fifo_write = 1'b0; + + header_fifo_wr_ptr_next = header_fifo_wr_ptr_reg; + + if (hdr_valid_reg) begin + // input data valid + if (~header_fifo_full) begin + // not full, perform write + header_fifo_write = 1'b1; + header_fifo_wr_ptr_next = header_fifo_wr_ptr_reg + 1; + end + end +end + +always @(posedge clk) begin + if (rst) begin + header_fifo_wr_ptr_reg <= {HEADER_FIFO_ADDR_WIDTH+1{1'b0}}; + end else begin + header_fifo_wr_ptr_reg <= header_fifo_wr_ptr_next; + end + + if (header_fifo_write) begin + eth_dest_mac_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= eth_dest_mac_reg; + eth_src_mac_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= eth_src_mac_reg; + eth_type_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= eth_type_reg; + ip_version_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_version_reg; + ip_ihl_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_ihl_reg; + ip_dscp_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_dscp_reg; + ip_ecn_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_ecn_reg; + ip_identification_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_identification_reg; + ip_flags_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_flags_reg; + ip_fragment_offset_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_fragment_offset_reg; + ip_ttl_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_ttl_reg; + ip_header_checksum_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_header_checksum_reg; + ip_source_ip_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_source_ip_reg; + ip_dest_ip_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_dest_ip_reg; + udp_source_port_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= udp_source_port_reg; + udp_dest_port_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= udp_dest_port_reg; + udp_length_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= frame_ptr_reg; + udp_checksum_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= checksum_reg[15:0]; + end +end + +// Read logic +always @* begin + header_fifo_read = 1'b0; + + header_fifo_rd_ptr_next = header_fifo_rd_ptr_reg; + + output_udp_hdr_valid_next = output_udp_hdr_valid_reg; + + if (output_udp_hdr_ready | ~output_udp_hdr_valid) begin + // output data not valid OR currently being transferred + if (~header_fifo_empty) begin + // not empty, perform read + header_fifo_read = 1'b1; + output_udp_hdr_valid_next = 1'b1; + header_fifo_rd_ptr_next = header_fifo_rd_ptr_reg + 1; + end else begin + // empty, invalidate + output_udp_hdr_valid_next = 1'b0; + end + end +end + +always @(posedge clk) begin + if (rst) begin + header_fifo_rd_ptr_reg <= {HEADER_FIFO_ADDR_WIDTH+1{1'b0}}; + output_udp_hdr_valid_reg <= 1'b0; + end else begin + header_fifo_rd_ptr_reg <= header_fifo_rd_ptr_next; + output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + end + + if (header_fifo_read) begin + output_eth_dest_mac_reg <= eth_dest_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_eth_src_mac_reg <= eth_src_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_eth_type_reg <= eth_type_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_version_reg <= ip_version_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_ihl_reg <= ip_ihl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_dscp_reg <= ip_dscp_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_ecn_reg <= ip_ecn_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_identification_reg <= ip_identification_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_flags_reg <= ip_flags_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_fragment_offset_reg <= ip_fragment_offset_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_ttl_reg <= ip_ttl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_header_checksum_reg <= ip_header_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_source_ip_reg <= ip_source_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_dest_ip_reg <= ip_dest_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_udp_source_port_reg <= udp_source_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_udp_dest_port_reg <= udp_dest_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_udp_length_reg <= udp_length_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_udp_checksum_reg <= udp_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + end +end + +assign input_udp_hdr_ready = input_udp_hdr_ready_reg; + +assign busy = busy_reg; + +always @* begin + state_next = STATE_IDLE; + + input_udp_hdr_ready_next = 1'b0; + input_udp_payload_tready_next = 1'b0; + + store_udp_hdr = 1'b0; + shift_payload_in = 1'b0; + + frame_ptr_next = frame_ptr_reg; + checksum_next = checksum_reg; + + hdr_valid_next = 1'b0; + + case (state_reg) + STATE_IDLE: begin + // idle state + input_udp_hdr_ready_next = header_fifo_ready; + + if (input_udp_hdr_ready & input_udp_hdr_valid) begin + store_udp_hdr = 1'b1; + frame_ptr_next = 0; + // 16'h0011 = zero padded type field + // 16'h0010 = header length times two + checksum_next = 16'h0011 + 16'h0010; + input_udp_hdr_ready_next = 1'b0; + state_next = STATE_SUM_HEADER_1; + end else begin + state_next = STATE_IDLE; + end + end + STATE_SUM_HEADER_1: begin + // sum pseudo header and header + checksum_next = checksum_reg + ip_source_ip_reg[31:16] + ip_source_ip_reg[15:0]; + state_next = STATE_SUM_HEADER_2; + end + STATE_SUM_HEADER_2: begin + // sum pseudo header and header + checksum_next = checksum_reg + ip_dest_ip_reg[31:16] + ip_dest_ip_reg[15:0]; + state_next = STATE_SUM_HEADER_3; + end + STATE_SUM_HEADER_3: begin + // sum pseudo header and header + checksum_next = checksum_reg + udp_source_port_reg + udp_dest_port_reg; + frame_ptr_next = 8; + state_next = STATE_SUM_PAYLOAD; + end + STATE_SUM_PAYLOAD: begin + // sum payload + shift_payload_in = 1'b1; + + if (input_udp_payload_tready & input_udp_payload_tvalid) begin + // checksum computation for payload - alternately store and accumulate + // add 2 for length calculation (two length fields in pseudo header) + if (frame_ptr_reg[0]) begin + checksum_next = checksum_reg + {8'h00, input_udp_payload_tdata} + 2; + end else begin + checksum_next = checksum_reg + {input_udp_payload_tdata, 8'h00} + 2; + end + + frame_ptr_next = frame_ptr_reg + 1; + + if (input_udp_payload_tlast) begin + state_next = STATE_FINISH_SUM; + end else begin + state_next = STATE_SUM_PAYLOAD; + end + end else begin + state_next = STATE_SUM_PAYLOAD; + end + end + STATE_FINISH_SUM: begin + // add MSW (twice!) for proper ones complement sum + checksum_part = checksum_reg[15:0] + checksum_reg[31:16]; + checksum_next = ~(checksum_part[15:0] + checksum_part[16]); + hdr_valid_next = 1; + state_next = STATE_IDLE; + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + input_udp_hdr_ready_reg <= 1'b0; + input_udp_payload_tready_reg <= 1'b0; + hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + + input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; + input_udp_payload_tready_reg <= input_udp_payload_tready_next; + + hdr_valid_reg <= hdr_valid_next; + + busy_reg <= state_next != STATE_IDLE; + end + + frame_ptr_reg <= frame_ptr_next; + checksum_reg <= checksum_next; + + // datapath + if (store_udp_hdr) begin + eth_dest_mac_reg <= input_eth_dest_mac; + eth_src_mac_reg <= input_eth_src_mac; + eth_type_reg <= input_eth_type; + ip_version_reg <= input_ip_version; + ip_ihl_reg <= input_ip_ihl; + ip_dscp_reg <= input_ip_dscp; + ip_ecn_reg <= input_ip_ecn; + ip_identification_reg <= input_ip_identification; + ip_flags_reg <= input_ip_flags; + ip_fragment_offset_reg <= input_ip_fragment_offset; + ip_ttl_reg <= input_ip_ttl; + ip_header_checksum_reg <= input_ip_header_checksum; + ip_source_ip_reg <= input_ip_source_ip; + ip_dest_ip_reg <= input_ip_dest_ip; + udp_source_port_reg <= input_udp_source_port; + udp_dest_port_reg <= input_udp_dest_port; + end +end + +endmodule diff --git a/rtl/udp_checksum_gen_64.v b/rtl/udp_checksum_gen_64.v new file mode 100644 index 000000000..94495d042 --- /dev/null +++ b/rtl/udp_checksum_gen_64.v @@ -0,0 +1,575 @@ +/* + +Copyright (c) 2016 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 + +/* + * UDP checksum calculation module (64 bit datapath) + */ +module udp_checksum_gen_64 # +( + parameter PAYLOAD_FIFO_ADDR_WIDTH = 8, + parameter HEADER_FIFO_ADDR_WIDTH = 3 +) +( + input wire clk, + input wire rst, + + /* + * UDP frame input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [3:0] input_ip_version, + input wire [3:0] input_ip_ihl, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_identification, + input wire [2:0] input_ip_flags, + input wire [12:0] input_ip_fragment_offset, + input wire [7:0] input_ip_ttl, + input wire [15:0] input_ip_header_checksum, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [63:0] input_udp_payload_tdata, + input wire [7:0] input_udp_payload_tkeep, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP frame output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [63:0] output_udp_payload_tdata, + output wire [7:0] output_udp_payload_tkeep, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Status signals + */ + output wire busy +); + +/* + +UDP Frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype (0x0800) 2 octets + Version (4) 4 bits + IHL (5-15) 4 bits + DSCP (0) 6 bits + ECN (0) 2 bits + length 2 octets + identification (0?) 2 octets + flags (010) 3 bits + fragment offset (0) 13 bits + time to live (64?) 1 octet + protocol 1 octet + header checksum 2 octets + source IP 4 octets + destination IP 4 octets + options (IHL-5)*4 octets + + source port 2 octets + desination port 2 octets + length 2 octets + checksum 2 octets + + payload length octets + +This module receives a UDP frame with header fields in parallel and payload on +an AXI stream interface, calculates the length and checksum, then produces the +header fields in parallel along with the UDP payload in a separate AXI stream. + +*/ + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_SUM_HEADER = 3'd1, + STATE_SUM_PAYLOAD = 3'd2, + STATE_FINISH_SUM_1 = 3'd3, + STATE_FINISH_SUM_2 = 3'd4; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg store_udp_hdr; +reg shift_payload_in; +reg [31:0] checksum_part; + +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; + +reg [31:0] checksum_reg = 32'd0, checksum_next; +reg [16:0] checksum_temp1_reg = 17'd0, checksum_temp1_next; +reg [16:0] checksum_temp2_reg = 17'd0, checksum_temp2_next; + +reg [47:0] eth_dest_mac_reg = 48'd0; +reg [47:0] eth_src_mac_reg = 48'd0; +reg [15:0] eth_type_reg = 16'd0; +reg [3:0] ip_version_reg = 4'd0; +reg [3:0] ip_ihl_reg = 4'd0; +reg [5:0] ip_dscp_reg = 6'd0; +reg [1:0] ip_ecn_reg = 2'd0; +reg [15:0] ip_identification_reg = 16'd0; +reg [2:0] ip_flags_reg = 3'd0; +reg [12:0] ip_fragment_offset_reg = 13'd0; +reg [7:0] ip_ttl_reg = 8'd0; +reg [15:0] ip_header_checksum_reg = 16'd0; +reg [31:0] ip_source_ip_reg = 32'd0; +reg [31:0] ip_dest_ip_reg = 32'd0; +reg [15:0] udp_source_port_reg = 16'd0; +reg [15:0] udp_dest_port_reg = 16'd0; + +reg hdr_valid_reg = 0, hdr_valid_next; + +reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; +reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; + +reg busy_reg = 1'b0; + +/* + * UDP Payload FIFO + */ +wire [63:0] input_udp_payload_fifo_tdata; +wire [7:0] input_udp_payload_fifo_tkeep; +wire input_udp_payload_fifo_tvalid; +wire input_udp_payload_fifo_tready; +wire input_udp_payload_fifo_tlast; +wire input_udp_payload_fifo_tuser; + +wire [63:0] output_udp_payload_fifo_tdata; +wire [7:0] output_udp_payload_fifo_tkeep; +wire output_udp_payload_fifo_tvalid; +wire output_udp_payload_fifo_tready; +wire output_udp_payload_fifo_tlast; +wire output_udp_payload_fifo_tuser; + +axis_fifo_64 #( + .DATA_WIDTH(64), + .ADDR_WIDTH(PAYLOAD_FIFO_ADDR_WIDTH) +) +payload_fifo ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(input_udp_payload_fifo_tdata), + .input_axis_tkeep(input_udp_payload_fifo_tkeep), + .input_axis_tvalid(input_udp_payload_fifo_tvalid), + .input_axis_tready(input_udp_payload_fifo_tready), + .input_axis_tlast(input_udp_payload_fifo_tlast), + .input_axis_tuser(input_udp_payload_fifo_tuser), + // AXI output + .output_axis_tdata(output_udp_payload_fifo_tdata), + .output_axis_tkeep(output_udp_payload_fifo_tkeep), + .output_axis_tvalid(output_udp_payload_fifo_tvalid), + .output_axis_tready(output_udp_payload_fifo_tready), + .output_axis_tlast(output_udp_payload_fifo_tlast), + .output_axis_tuser(output_udp_payload_fifo_tuser) +); + +assign input_udp_payload_fifo_tdata = input_udp_payload_tdata; +assign input_udp_payload_fifo_tkeep = input_udp_payload_tkeep; +assign input_udp_payload_fifo_tvalid = input_udp_payload_tvalid & shift_payload_in; +assign input_udp_payload_tready = input_udp_payload_fifo_tready & shift_payload_in; +assign input_udp_payload_fifo_tlast = input_udp_payload_tlast; +assign input_udp_payload_fifo_tuser = input_udp_payload_tuser; + +assign output_udp_payload_tdata = output_udp_payload_fifo_tdata; +assign output_udp_payload_tkeep = output_udp_payload_fifo_tkeep; +assign output_udp_payload_tvalid = output_udp_payload_fifo_tvalid; +assign output_udp_payload_fifo_tready = output_udp_payload_tready; +assign output_udp_payload_tlast = output_udp_payload_fifo_tlast; +assign output_udp_payload_tuser = output_udp_payload_fifo_tuser; + +/* + * UDP Header FIFO + */ +reg [HEADER_FIFO_ADDR_WIDTH:0] header_fifo_wr_ptr_reg = {HEADER_FIFO_ADDR_WIDTH+1{1'b0}}, header_fifo_wr_ptr_next; +reg [HEADER_FIFO_ADDR_WIDTH:0] header_fifo_rd_ptr_reg = {HEADER_FIFO_ADDR_WIDTH+1{1'b0}}, header_fifo_rd_ptr_next; + +reg [47:0] eth_dest_mac_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [47:0] eth_src_mac_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] eth_type_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [3:0] ip_version_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [3:0] ip_ihl_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [5:0] ip_dscp_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [1:0] ip_ecn_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] ip_identification_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [2:0] ip_flags_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [12:0] ip_fragment_offset_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [7:0] ip_ttl_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] ip_header_checksum_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [31:0] ip_source_ip_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [31:0] ip_dest_ip_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] udp_source_port_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] udp_dest_port_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] udp_length_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; +reg [15:0] udp_checksum_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; + +reg [47:0] output_eth_dest_mac_reg = 48'd0; +reg [47:0] output_eth_src_mac_reg = 48'd0; +reg [15:0] output_eth_type_reg = 16'd0; +reg [3:0] output_ip_version_reg = 4'd0; +reg [3:0] output_ip_ihl_reg = 4'd0; +reg [5:0] output_ip_dscp_reg = 6'd0; +reg [1:0] output_ip_ecn_reg = 2'd0; +reg [15:0] output_ip_identification_reg = 16'd0; +reg [2:0] output_ip_flags_reg = 3'd0; +reg [12:0] output_ip_fragment_offset_reg = 13'd0; +reg [7:0] output_ip_ttl_reg = 8'd0; +reg [15:0] output_ip_header_checksum_reg = 16'd0; +reg [31:0] output_ip_source_ip_reg = 32'd0; +reg [31:0] output_ip_dest_ip_reg = 32'd0; +reg [15:0] output_udp_source_port_reg = 16'd0; +reg [15:0] output_udp_dest_port_reg = 16'd0; +reg [15:0] output_udp_length_reg = 16'd0; +reg [15:0] output_udp_checksum_reg = 16'd0; + +reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; + +// full when first MSB different but rest same +wire header_fifo_full = ((header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH] != header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH]) && + (header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0] == header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0])); +// empty when pointers match exactly +wire header_fifo_empty = header_fifo_wr_ptr_reg == header_fifo_rd_ptr_reg; + +// control signals +reg header_fifo_write; +reg header_fifo_read; + +wire header_fifo_ready = ~header_fifo_full; + +assign output_udp_hdr_valid = output_udp_hdr_valid_reg; + +assign output_eth_dest_mac = output_eth_dest_mac_reg; +assign output_eth_src_mac = output_eth_src_mac_reg; +assign output_eth_type = output_eth_type_reg; +assign output_ip_version = output_ip_version_reg; +assign output_ip_ihl = output_ip_ihl_reg; +assign output_ip_dscp = output_ip_dscp_reg; +assign output_ip_ecn = output_ip_ecn_reg; +assign output_ip_length = output_udp_length_reg + 16'd20; +assign output_ip_identification = output_ip_identification_reg; +assign output_ip_flags = output_ip_flags_reg; +assign output_ip_fragment_offset = output_ip_fragment_offset_reg; +assign output_ip_ttl = output_ip_ttl_reg; +assign output_ip_protocol = 8'h11; +assign output_ip_header_checksum = output_ip_header_checksum_reg; +assign output_ip_source_ip = output_ip_source_ip_reg; +assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign output_udp_source_port = output_udp_source_port_reg; +assign output_udp_dest_port = output_udp_dest_port_reg; +assign output_udp_length = output_udp_length_reg; +assign output_udp_checksum = output_udp_checksum_reg; + +// Write logic +always @* begin + header_fifo_write = 1'b0; + + header_fifo_wr_ptr_next = header_fifo_wr_ptr_reg; + + if (hdr_valid_reg) begin + // input data valid + if (~header_fifo_full) begin + // not full, perform write + header_fifo_write = 1'b1; + header_fifo_wr_ptr_next = header_fifo_wr_ptr_reg + 1; + end + end +end + +always @(posedge clk) begin + if (rst) begin + header_fifo_wr_ptr_reg <= {HEADER_FIFO_ADDR_WIDTH+1{1'b0}}; + end else begin + header_fifo_wr_ptr_reg <= header_fifo_wr_ptr_next; + end + + if (header_fifo_write) begin + eth_dest_mac_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= eth_dest_mac_reg; + eth_src_mac_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= eth_src_mac_reg; + eth_type_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= eth_type_reg; + ip_version_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_version_reg; + ip_ihl_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_ihl_reg; + ip_dscp_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_dscp_reg; + ip_ecn_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_ecn_reg; + ip_identification_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_identification_reg; + ip_flags_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_flags_reg; + ip_fragment_offset_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_fragment_offset_reg; + ip_ttl_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_ttl_reg; + ip_header_checksum_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_header_checksum_reg; + ip_source_ip_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_source_ip_reg; + ip_dest_ip_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= ip_dest_ip_reg; + udp_source_port_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= udp_source_port_reg; + udp_dest_port_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= udp_dest_port_reg; + udp_length_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= frame_ptr_reg; + udp_checksum_mem[header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]] <= checksum_reg[15:0]; + end +end + +// Read logic +always @* begin + header_fifo_read = 1'b0; + + header_fifo_rd_ptr_next = header_fifo_rd_ptr_reg; + + output_udp_hdr_valid_next = output_udp_hdr_valid_reg; + + if (output_udp_hdr_ready | ~output_udp_hdr_valid) begin + // output data not valid OR currently being transferred + if (~header_fifo_empty) begin + // not empty, perform read + header_fifo_read = 1'b1; + output_udp_hdr_valid_next = 1'b1; + header_fifo_rd_ptr_next = header_fifo_rd_ptr_reg + 1; + end else begin + // empty, invalidate + output_udp_hdr_valid_next = 1'b0; + end + end +end + +always @(posedge clk) begin + if (rst) begin + header_fifo_rd_ptr_reg <= {HEADER_FIFO_ADDR_WIDTH+1{1'b0}}; + output_udp_hdr_valid_reg <= 1'b0; + end else begin + header_fifo_rd_ptr_reg <= header_fifo_rd_ptr_next; + output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + end + + if (header_fifo_read) begin + output_eth_dest_mac_reg <= eth_dest_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_eth_src_mac_reg <= eth_src_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_eth_type_reg <= eth_type_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_version_reg <= ip_version_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_ihl_reg <= ip_ihl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_dscp_reg <= ip_dscp_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_ecn_reg <= ip_ecn_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_identification_reg <= ip_identification_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_flags_reg <= ip_flags_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_fragment_offset_reg <= ip_fragment_offset_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_ttl_reg <= ip_ttl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_header_checksum_reg <= ip_header_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_source_ip_reg <= ip_source_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_ip_dest_ip_reg <= ip_dest_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_udp_source_port_reg <= udp_source_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_udp_dest_port_reg <= udp_dest_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_udp_length_reg <= udp_length_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + output_udp_checksum_reg <= udp_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + end +end + +assign input_udp_hdr_ready = input_udp_hdr_ready_reg; + +assign busy = busy_reg; + +integer i, word_cnt; + +always @* begin + state_next = STATE_IDLE; + + input_udp_hdr_ready_next = 1'b0; + input_udp_payload_tready_next = 1'b0; + + store_udp_hdr = 1'b0; + shift_payload_in = 1'b0; + + frame_ptr_next = frame_ptr_reg; + checksum_next = checksum_reg; + checksum_temp1_next = checksum_temp1_reg; + checksum_temp2_next = checksum_temp2_reg; + + hdr_valid_next = 1'b0; + + case (state_reg) + STATE_IDLE: begin + // idle state + input_udp_hdr_ready_next = header_fifo_ready; + + if (input_udp_hdr_ready & input_udp_hdr_valid) begin + store_udp_hdr = 1'b1; + frame_ptr_next = 0; + // 16'h0011 = zero padded type field + // 16'h0010 = header length times two + checksum_next = 16'h0011 + 16'h0010; + checksum_temp1_next = input_ip_source_ip[31:16]; + checksum_temp2_next = input_ip_source_ip[15:0]; + input_udp_hdr_ready_next = 1'b0; + state_next = STATE_SUM_HEADER; + end else begin + state_next = STATE_IDLE; + end + end + STATE_SUM_HEADER: begin + // sum pseudo header and header + checksum_next = checksum_reg + checksum_temp1_reg + checksum_temp2_reg; + checksum_temp1_next = ip_dest_ip_reg[31:16] + ip_dest_ip_reg[15:0]; + checksum_temp2_next = udp_source_port_reg + udp_dest_port_reg; + frame_ptr_next = 8; + state_next = STATE_SUM_PAYLOAD; + end + STATE_SUM_PAYLOAD: begin + // sum payload + shift_payload_in = 1'b1; + + if (input_udp_payload_tready & input_udp_payload_tvalid) begin + word_cnt = 1; + for (i = 1; i <= 8; i = i + 1) begin + if (input_udp_payload_tkeep == 8'hff >> (8-i)) word_cnt = i; + end + + checksum_temp1_next = 0; + checksum_temp2_next = 0; + + for (i = 0; i < 4; i = i + 1) begin + if (input_udp_payload_tkeep[i]) begin + if (i & 1) begin + checksum_temp1_next = checksum_temp1_next + {8'h00, input_udp_payload_tdata[i*8 +: 8]}; + end else begin + checksum_temp1_next = checksum_temp1_next + {input_udp_payload_tdata[i*8 +: 8], 8'h00}; + end + end + end + + for (i = 4; i < 8; i = i + 1) begin + if (input_udp_payload_tkeep[i]) begin + if (i & 1) begin + checksum_temp2_next = checksum_temp2_next + {8'h00, input_udp_payload_tdata[i*8 +: 8]}; + end else begin + checksum_temp2_next = checksum_temp2_next + {input_udp_payload_tdata[i*8 +: 8], 8'h00}; + end + end + end + + // add length * 2 (two copies of length field in pseudo header) + checksum_next = checksum_reg + checksum_temp1_reg + checksum_temp2_reg + (word_cnt << 1); + + frame_ptr_next = frame_ptr_reg + word_cnt; + + if (input_udp_payload_tlast) begin + state_next = STATE_FINISH_SUM_1; + end else begin + state_next = STATE_SUM_PAYLOAD; + end + end else begin + state_next = STATE_SUM_PAYLOAD; + end + end + STATE_FINISH_SUM_1: begin + // empty pipeline + checksum_next = checksum_reg + checksum_temp1_reg + checksum_temp2_reg; + state_next = STATE_FINISH_SUM_2; + end + STATE_FINISH_SUM_2: begin + // add MSW (twice!) for proper ones complement sum + checksum_part = checksum_reg[15:0] + checksum_reg[31:16]; + checksum_next = ~(checksum_part[15:0] + checksum_part[16]); + hdr_valid_next = 1; + state_next = STATE_IDLE; + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + input_udp_hdr_ready_reg <= 1'b0; + input_udp_payload_tready_reg <= 1'b0; + hdr_valid_reg <= 1'b0; + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + + input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; + input_udp_payload_tready_reg <= input_udp_payload_tready_next; + + hdr_valid_reg <= hdr_valid_next; + + busy_reg <= state_next != STATE_IDLE; + end + + frame_ptr_reg <= frame_ptr_next; + checksum_reg <= checksum_next; + checksum_temp1_reg <= checksum_temp1_next; + checksum_temp2_reg <= checksum_temp2_next; + + // datapath + if (store_udp_hdr) begin + eth_dest_mac_reg <= input_eth_dest_mac; + eth_src_mac_reg <= input_eth_src_mac; + eth_type_reg <= input_eth_type; + ip_version_reg <= input_ip_version; + ip_ihl_reg <= input_ip_ihl; + ip_dscp_reg <= input_ip_dscp; + ip_ecn_reg <= input_ip_ecn; + ip_identification_reg <= input_ip_identification; + ip_flags_reg <= input_ip_flags; + ip_fragment_offset_reg <= input_ip_fragment_offset; + ip_ttl_reg <= input_ip_ttl; + ip_header_checksum_reg <= input_ip_header_checksum; + ip_source_ip_reg <= input_ip_source_ip; + ip_dest_ip_reg <= input_ip_dest_ip; + udp_source_port_reg <= input_udp_source_port; + udp_dest_port_reg <= input_udp_dest_port; + end +end + +endmodule diff --git a/tb/test_udp_checksum_gen.py b/tb/test_udp_checksum_gen.py new file mode 100755 index 000000000..910f01646 --- /dev/null +++ b/tb/test_udp_checksum_gen.py @@ -0,0 +1,504 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +import eth_ep +import arp_ep +import ip_ep +import udp_ep + +module = 'udp_checksum_gen' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/axis/rtl/axis_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + PAYLOAD_FIFO_ADDR_WIDTH = 11 + HEADER_FIFO_ADDR_WIDTH = 3 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_udp_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + + output_udp_hdr_ready = Signal(bool(0)) + output_udp_payload_tready = Signal(bool(0)) + + # Outputs + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + + output_udp_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0x11)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + + busy = Signal(bool(0)) + + # sources and sinks + source_pause = Signal(bool(0)) + sink_pause = Signal(bool(0)) + + source = udp_ep.UDPFrameSource() + + source_logic = source.create_logic( + clk, + rst, + udp_hdr_ready=input_udp_hdr_ready, + udp_hdr_valid=input_udp_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + pause=source_pause, + name='source' + ) + + sink = udp_ep.UDPFrameSink() + + sink_logic = sink.create_logic( + clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + pause=sink_pause, + 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, + + input_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + busy=busy + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + i = 4 + while i > 0: + i = max(0, i-1) + if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + i = 4 + yield clk.posedge + + def wait_pause_source(): + i = 2 + while i > 0: + i = max(0, i-1) + if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + i = 2 + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + i = 2 + while i > 0: + i = max(0, i-1) + if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + i = 2 + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(payload_len)) + test_frame.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + assert rx_frame == test_frame + + 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 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source_logic, sink_logic, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_udp_checksum_gen.v b/tb/test_udp_checksum_gen.v new file mode 100644 index 000000000..002fa5f0c --- /dev/null +++ b/tb/test_udp_checksum_gen.v @@ -0,0 +1,223 @@ +/* + +Copyright (c) 2016 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 + +/* + * Testbench for udp_checksum_gen + */ +module test_udp_checksum_gen; + +// Parameters +parameter PAYLOAD_FIFO_ADDR_WIDTH = 11; +parameter HEADER_FIFO_ADDR_WIDTH = 3; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_udp_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [7:0] input_udp_payload_tdata = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; + +// Outputs +wire input_udp_hdr_ready; +wire input_udp_payload_tready; +wire output_udp_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [7:0] output_udp_payload_tdata; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; +wire busy; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + input_udp_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_udp_hdr_ready, + output_udp_payload_tready + ); + $to_myhdl( + input_udp_hdr_ready, + input_udp_payload_tready, + output_udp_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser, + busy + ); + + // dump file + $dumpfile("test_udp_checksum_gen.lxt"); + $dumpvars(0, test_udp_checksum_gen); +end + +udp_checksum_gen #( + .PAYLOAD_FIFO_ADDR_WIDTH(PAYLOAD_FIFO_ADDR_WIDTH), + .HEADER_FIFO_ADDR_WIDTH(HEADER_FIFO_ADDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + .busy(busy) +); + +endmodule diff --git a/tb/test_udp_checksum_gen_64.py b/tb/test_udp_checksum_gen_64.py new file mode 100755 index 000000000..5d0f84de2 --- /dev/null +++ b/tb/test_udp_checksum_gen_64.py @@ -0,0 +1,510 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +import eth_ep +import arp_ep +import ip_ep +import udp_ep + +module = 'udp_checksum_gen_64' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/axis/rtl/axis_fifo_64.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + PAYLOAD_FIFO_ADDR_WIDTH = 8 + HEADER_FIFO_ADDR_WIDTH = 3 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_udp_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_ip_version = Signal(intbv(0)[4:]) + input_ip_ihl = Signal(intbv(0)[4:]) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_identification = Signal(intbv(0)[16:]) + input_ip_flags = Signal(intbv(0)[3:]) + input_ip_fragment_offset = Signal(intbv(0)[13:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_header_checksum = Signal(intbv(0)[16:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[64:]) + input_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + + output_udp_hdr_ready = Signal(bool(0)) + output_udp_payload_tready = Signal(bool(0)) + + # Outputs + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + + output_udp_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0x11)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[64:]) + output_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + + busy = Signal(bool(0)) + + # sources and sinks + source_pause = Signal(bool(0)) + sink_pause = Signal(bool(0)) + + source = udp_ep.UDPFrameSource() + + source_logic = source.create_logic( + clk, + rst, + udp_hdr_ready=input_udp_hdr_ready, + udp_hdr_valid=input_udp_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + ip_version=input_ip_version, + ip_ihl=input_ip_ihl, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_identification=input_ip_identification, + ip_flags=input_ip_flags, + ip_fragment_offset=input_ip_fragment_offset, + ip_ttl=input_ip_ttl, + ip_header_checksum=input_ip_header_checksum, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tkeep=input_udp_payload_tkeep, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + pause=source_pause, + name='source' + ) + + sink = udp_ep.UDPFrameSink() + + sink_logic = sink.create_logic( + clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tkeep=output_udp_payload_tkeep, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + pause=sink_pause, + 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, + + input_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_ip_version=input_ip_version, + input_ip_ihl=input_ip_ihl, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_identification=input_ip_identification, + input_ip_flags=input_ip_flags, + input_ip_fragment_offset=input_ip_fragment_offset, + input_ip_ttl=input_ip_ttl, + input_ip_header_checksum=input_ip_header_checksum, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tkeep=input_udp_payload_tkeep, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tkeep=output_udp_payload_tkeep, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + busy=busy + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + i = 4 + while i > 0: + i = max(0, i-1) + if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + i = 4 + yield clk.posedge + + def wait_pause_source(): + i = 2 + while i > 0: + i = max(0, i-1) + if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + i = 2 + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + def wait_pause_sink(): + i = 2 + while i > 0: + i = max(0, i-1) + if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + i = 2 + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80165 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(payload_len)) + test_frame.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + assert rx_frame == test_frame + + 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 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = udp_ep.UDPFrame() + test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame1.eth_src_mac = 0x5A5152535455 + test_frame1.eth_type = 0x0800 + test_frame1.ip_version = 4 + test_frame1.ip_ihl = 5 + test_frame1.ip_length = None + test_frame1.ip_identification = 0 + test_frame1.ip_flags = 2 + test_frame1.ip_fragment_offset = 0 + test_frame1.ip_ttl = 64 + test_frame1.ip_protocol = 0x11 + test_frame1.ip_header_checksum = None + test_frame1.ip_source_ip = 0xc0a80164 + test_frame1.ip_dest_ip = 0xc0a80165 + test_frame1.udp_source_port = 1 + test_frame1.udp_dest_port = 2 + test_frame1.udp_length = None + test_frame1.udp_checksum = None + test_frame1.payload = bytearray(range(payload_len)) + test_frame1.build() + test_frame2 = udp_ep.UDPFrame() + test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame2.eth_src_mac = 0x5A5152535455 + test_frame2.eth_type = 0x0800 + test_frame2.ip_version = 4 + test_frame2.ip_ihl = 5 + test_frame2.ip_length = None + test_frame2.ip_identification = 0 + test_frame2.ip_flags = 2 + test_frame2.ip_fragment_offset = 0 + test_frame2.ip_ttl = 64 + test_frame2.ip_protocol = 0x11 + test_frame2.ip_header_checksum = None + test_frame2.ip_source_ip = 0xc0a80164 + test_frame2.ip_dest_ip = 0xc0a80166 + test_frame2.udp_source_port = 1 + test_frame2.udp_dest_port = 2 + test_frame2.udp_length = None + test_frame2.udp_checksum = None + test_frame2.payload = bytearray(range(payload_len)) + test_frame2.build() + + test_frame1.payload.user = 1 + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + assert rx_frame.payload.user[-1] + + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source_logic, sink_logic, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_udp_checksum_gen_64.v b/tb/test_udp_checksum_gen_64.v new file mode 100644 index 000000000..c09192825 --- /dev/null +++ b/tb/test_udp_checksum_gen_64.v @@ -0,0 +1,229 @@ +/* + +Copyright (c) 2016 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 + +/* + * Testbench for udp_checksum_gen_64 + */ +module test_udp_checksum_gen_64; + +// Parameters +parameter PAYLOAD_FIFO_ADDR_WIDTH = 8; +parameter HEADER_FIFO_ADDR_WIDTH = 3; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_udp_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [3:0] input_ip_version = 0; +reg [3:0] input_ip_ihl = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_identification = 0; +reg [2:0] input_ip_flags = 0; +reg [12:0] input_ip_fragment_offset = 0; +reg [7:0] input_ip_ttl = 0; +reg [15:0] input_ip_header_checksum = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [63:0] input_udp_payload_tdata = 0; +reg [7:0] input_udp_payload_tkeep = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; + +// Outputs +wire input_udp_hdr_ready; +wire input_udp_payload_tready; +wire output_udp_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [63:0] output_udp_payload_tdata; +wire [7:0] output_udp_payload_tkeep; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; +wire busy; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + input_udp_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_ip_version, + input_ip_ihl, + input_ip_dscp, + input_ip_ecn, + input_ip_identification, + input_ip_flags, + input_ip_fragment_offset, + input_ip_ttl, + input_ip_header_checksum, + input_ip_source_ip, + input_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_udp_hdr_ready, + output_udp_payload_tready + ); + $to_myhdl( + input_udp_hdr_ready, + input_udp_payload_tready, + output_udp_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser, + busy + ); + + // dump file + $dumpfile("test_udp_checksum_gen_64.lxt"); + $dumpvars(0, test_udp_checksum_gen_64); +end + +udp_checksum_gen_64 #( + .PAYLOAD_FIFO_ADDR_WIDTH(PAYLOAD_FIFO_ADDR_WIDTH), + .HEADER_FIFO_ADDR_WIDTH(HEADER_FIFO_ADDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_ip_version(input_ip_version), + .input_ip_ihl(input_ip_ihl), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_identification(input_ip_identification), + .input_ip_flags(input_ip_flags), + .input_ip_fragment_offset(input_ip_fragment_offset), + .input_ip_ttl(input_ip_ttl), + .input_ip_header_checksum(input_ip_header_checksum), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tkeep(input_udp_payload_tkeep), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + .busy(busy) +); + +endmodule From 4e522e52af475ebf17c5f4fd25e900cbaba7756f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 30 Sep 2016 22:02:29 -0700 Subject: [PATCH 315/617] Clean up endpoint modules --- tb/arp_ep.py | 74 +++++++++++++++------------- tb/eth_ep.py | 11 +++-- tb/ip_ep.py | 81 +++++++++++++++++-------------- tb/udp_ep.py | 133 +++++++++++++++++++++++++++------------------------ 4 files changed, 162 insertions(+), 137 deletions(-) diff --git a/tb/arp_ep.py b/tb/arp_ep.py index 170a10600..7a283b6b1 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -29,18 +29,19 @@ import struct class ARPFrame(object): def __init__(self, - eth_dest_mac=0, - eth_src_mac=0, - eth_type=0, - arp_htype=1, - arp_ptype=0x0800, - arp_hlen=6, - arp_plen=4, - arp_oper=2, - arp_sha=0x5A5152535455, - arp_spa=0xc0a80164, - arp_tha=0xDAD1D2D3D4D5, - arp_tpa=0xc0a80164): + eth_dest_mac=0, + eth_src_mac=0, + eth_type=0, + arp_htype=1, + arp_ptype=0x0800, + arp_hlen=6, + arp_plen=4, + arp_oper=2, + arp_sha=0x5A5152535455, + arp_spa=0xc0a80164, + arp_tha=0xDAD1D2D3D4D5, + arp_tpa=0xc0a80164 + ): self.eth_dest_mac = eth_dest_mac self.eth_src_mac = eth_src_mac @@ -122,32 +123,37 @@ class ARPFrame(object): def __eq__(self, other): if type(other) is ARPFrame: - return (self.eth_src_mac == other.eth_src_mac and - self.eth_dest_mac == other.eth_dest_mac and - self.eth_type == other.eth_type and - self.arp_htype == other.arp_htype and - self.arp_ptype == other.arp_ptype and - self.arp_hlen == other.arp_hlen and - self.arp_plen == other.arp_plen and - self.arp_oper == other.arp_oper and - self.arp_sha == other.arp_sha and - self.arp_spa == other.arp_spa and - self.arp_tha == other.arp_tha and - self.arp_tpa == other.arp_tpa) + return ( + self.eth_src_mac == other.eth_src_mac and + self.eth_dest_mac == other.eth_dest_mac and + self.eth_type == other.eth_type and + self.arp_htype == other.arp_htype and + self.arp_ptype == other.arp_ptype and + self.arp_hlen == other.arp_hlen and + self.arp_plen == other.arp_plen and + self.arp_oper == other.arp_oper and + self.arp_sha == other.arp_sha and + self.arp_spa == other.arp_spa and + self.arp_tha == other.arp_tha and + self.arp_tpa == other.arp_tpa + ) + return False def __repr__(self): - return (('ArpFrame(eth_dest_mac=0x%012x, ' % self.eth_dest_mac) + + return ( + ('ArpFrame(eth_dest_mac=0x%012x, ' % self.eth_dest_mac) + ('eth_src_mac=0x%012x, ' % self.eth_src_mac) + ('eth_type=0x%04x, ' % self.eth_type) + - ('arp_htype=0x%04x, ' % self.arp_htype) + - ('arp_ptype=0x%04x, ' % self.arp_ptype) + - ('arp_hlen=%d, ' % self.arp_hlen) + - ('arp_plen=%d, ' % self.arp_plen) + - ('arp_oper=0x%04x, ' % self.arp_oper) + - ('arp_sha=0x%012x, ' % self.arp_sha) + - ('arp_spa=0x%08x, ' % self.arp_spa) + - ('arp_tha=0x%012x, ' % self.arp_tha) + - ('arp_tpa=0x%08x)' % self.arp_tpa)) + ('arp_htype=0x%04x, ' % self.arp_htype) + + ('arp_ptype=0x%04x, ' % self.arp_ptype) + + ('arp_hlen=%d, ' % self.arp_hlen) + + ('arp_plen=%d, ' % self.arp_plen) + + ('arp_oper=0x%04x, ' % self.arp_oper) + + ('arp_sha=0x%012x, ' % self.arp_sha) + + ('arp_spa=0x%08x, ' % self.arp_spa) + + ('arp_tha=0x%012x, ' % self.arp_tha) + + ('arp_tpa=0x%08x)' % self.arp_tpa) + ) class ARPFrameSource(): diff --git a/tb/eth_ep.py b/tb/eth_ep.py index 160c4265f..8fe9c4a22 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -105,10 +105,13 @@ class EthFrame(object): def __eq__(self, other): if type(other) is EthFrame: - return (self.eth_src_mac == other.eth_src_mac and - self.eth_dest_mac == other.eth_dest_mac and - self.eth_type == other.eth_type and - self.payload == other.payload) + return ( + self.eth_src_mac == other.eth_src_mac and + self.eth_dest_mac == other.eth_dest_mac and + self.eth_type == other.eth_type and + self.payload == other.payload + ) + return False def __repr__(self): fcs = 'None' diff --git a/tb/ip_ep.py b/tb/ip_ep.py index e6da44caa..29a858aff 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -28,23 +28,25 @@ import eth_ep import struct class IPFrame(object): - def __init__(self, payload=b'', - eth_dest_mac=0, - eth_src_mac=0, - eth_type=0, - ip_version=4, - ip_ihl=5, - ip_dscp=0, - ip_ecn=0, - ip_length=None, - ip_identification=0, - ip_flags=2, - ip_fragment_offset=0, - ip_ttl=64, - ip_protocol=0x11, - ip_header_checksum=None, - ip_source_ip=0xc0a80164, - ip_dest_ip=0xc0a80165): + def __init__(self, + payload=b'', + eth_dest_mac=0, + eth_src_mac=0, + eth_type=0, + ip_version=4, + ip_ihl=5, + ip_dscp=0, + ip_ecn=0, + ip_length=None, + ip_identification=0, + ip_flags=2, + ip_fragment_offset=0, + ip_ttl=64, + ip_protocol=0x11, + ip_header_checksum=None, + ip_source_ip=0xc0a80164, + ip_dest_ip=0xc0a80165 + ): self._payload = axis_ep.AXIStreamFrame() self.eth_dest_mac = eth_dest_mac @@ -192,26 +194,30 @@ class IPFrame(object): def __eq__(self, other): if type(other) is IPFrame: - return (self.eth_src_mac == other.eth_src_mac and - self.eth_dest_mac == other.eth_dest_mac and - self.eth_type == other.eth_type and - self.ip_version == other.ip_version and - self.ip_ihl == other.ip_ihl and - self.ip_dscp == other.ip_dscp and - self.ip_ecn == other.ip_ecn and - self.ip_length == other.ip_length and - self.ip_identification == other.ip_identification and - self.ip_flags == other.ip_flags and - self.ip_fragment_offset == other.ip_fragment_offset and - self.ip_ttl == other.ip_ttl and - self.ip_protocol == other.ip_protocol and - self.ip_header_checksum == other.ip_header_checksum and - self.ip_source_ip == other.ip_source_ip and - self.ip_dest_ip == other.ip_dest_ip and - self.payload == other.payload) + return ( + self.eth_src_mac == other.eth_src_mac and + self.eth_dest_mac == other.eth_dest_mac and + self.eth_type == other.eth_type and + self.ip_version == other.ip_version and + self.ip_ihl == other.ip_ihl and + self.ip_dscp == other.ip_dscp and + self.ip_ecn == other.ip_ecn and + self.ip_length == other.ip_length and + self.ip_identification == other.ip_identification and + self.ip_flags == other.ip_flags and + self.ip_fragment_offset == other.ip_fragment_offset and + self.ip_ttl == other.ip_ttl and + self.ip_protocol == other.ip_protocol and + self.ip_header_checksum == other.ip_header_checksum and + self.ip_source_ip == other.ip_source_ip and + self.ip_dest_ip == other.ip_dest_ip and + self.payload == other.payload + ) + return False def __repr__(self): - return (('IPFrame(payload=%s, ' % repr(self.payload)) + + return ( + ('IPFrame(payload=%s, ' % repr(self.payload)) + ('eth_dest_mac=0x%012x, ' % self.eth_dest_mac) + ('eth_src_mac=0x%012x, ' % self.eth_src_mac) + ('eth_type=0x%04x, ' % self.eth_type) + @@ -225,9 +231,10 @@ class IPFrame(object): ('ip_fragment_offset=%d, ' % self.ip_fragment_offset) + ('ip_ttl=%d, ' % self.ip_ttl) + ('ip_protocol=0x%02x, ' % self.ip_protocol) + - ('ip_header_checksum=%x, ' % self.ip_header_checksum) + + ('ip_header_checksum=0x%x, ' % self.ip_header_checksum) + ('ip_source_ip=0x%08x, ' % self.ip_source_ip) + - ('ip_dest_ip=0x%08x)' % self.ip_dest_ip)) + ('ip_dest_ip=0x%08x)' % self.ip_dest_ip) + ) class IPFrameSource(): diff --git a/tb/udp_ep.py b/tb/udp_ep.py index b84d6f317..5aa73792e 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -29,27 +29,29 @@ import ip_ep import struct class UDPFrame(object): - def __init__(self, payload=b'', - eth_dest_mac=0, - eth_src_mac=0, - eth_type=0, - ip_version=4, - ip_ihl=5, - ip_dscp=0, - ip_ecn=0, - ip_length=None, - ip_identification=0, - ip_flags=2, - ip_fragment_offset=0, - ip_ttl=64, - ip_protocol=0x11, - ip_header_checksum=None, - ip_source_ip=0xc0a80164, - ip_dest_ip=0xc0a80165, - udp_source_port=1, - udp_dest_port=2, - udp_length=None, - udp_checksum=None): + def __init__(self, + payload=b'', + eth_dest_mac=0, + eth_src_mac=0, + eth_type=0, + ip_version=4, + ip_ihl=5, + ip_dscp=0, + ip_ecn=0, + ip_length=None, + ip_identification=0, + ip_flags=2, + ip_fragment_offset=0, + ip_ttl=64, + ip_protocol=0x11, + ip_header_checksum=None, + ip_source_ip=0xc0a80164, + ip_dest_ip=0xc0a80165, + udp_source_port=1, + udp_dest_port=2, + udp_length=None, + udp_checksum=None + ): self._payload = axis_ep.AXIStreamFrame() self.eth_dest_mac = eth_dest_mac @@ -212,23 +214,25 @@ class UDPFrame(object): data += self.payload.data - return ip_ep.IPFrame(data, - self.eth_dest_mac, - self.eth_src_mac, - self.eth_type, - self.ip_version, - self.ip_ihl, - self.ip_dscp, - self.ip_ecn, - self.ip_length, - self.ip_identification, - self.ip_flags, - self.ip_fragment_offset, - self.ip_ttl, - self.ip_protocol, - self.ip_header_checksum, - self.ip_source_ip, - self.ip_dest_ip) + return ip_ep.IPFrame( + data, + self.eth_dest_mac, + self.eth_src_mac, + self.eth_type, + self.ip_version, + self.ip_ihl, + self.ip_dscp, + self.ip_ecn, + self.ip_length, + self.ip_identification, + self.ip_flags, + self.ip_fragment_offset, + self.ip_ttl, + self.ip_protocol, + self.ip_header_checksum, + self.ip_source_ip, + self.ip_dest_ip + ) def parse_axis(self, data): frame = eth_ep.EthFrame() @@ -267,30 +271,34 @@ class UDPFrame(object): def __eq__(self, other): if type(other) is UDPFrame: - return (self.eth_src_mac == other.eth_src_mac and - self.eth_dest_mac == other.eth_dest_mac and - self.eth_type == other.eth_type and - self.ip_version == other.ip_version and - self.ip_ihl == other.ip_ihl and - self.ip_dscp == other.ip_dscp and - self.ip_ecn == other.ip_ecn and - self.ip_length == other.ip_length and - self.ip_identification == other.ip_identification and - self.ip_flags == other.ip_flags and - self.ip_fragment_offset == other.ip_fragment_offset and - self.ip_ttl == other.ip_ttl and - self.ip_protocol == other.ip_protocol and - self.ip_header_checksum == other.ip_header_checksum and - self.ip_source_ip == other.ip_source_ip and - self.ip_dest_ip == other.ip_dest_ip and - self.udp_source_port == other.udp_source_port and - self.udp_dest_port == other.udp_dest_port and - self.udp_length == other.udp_length and - self.udp_checksum == other.udp_checksum and - self.payload == other.payload) + return ( + self.eth_src_mac == other.eth_src_mac and + self.eth_dest_mac == other.eth_dest_mac and + self.eth_type == other.eth_type and + self.ip_version == other.ip_version and + self.ip_ihl == other.ip_ihl and + self.ip_dscp == other.ip_dscp and + self.ip_ecn == other.ip_ecn and + self.ip_length == other.ip_length and + self.ip_identification == other.ip_identification and + self.ip_flags == other.ip_flags and + self.ip_fragment_offset == other.ip_fragment_offset and + self.ip_ttl == other.ip_ttl and + self.ip_protocol == other.ip_protocol and + self.ip_header_checksum == other.ip_header_checksum and + self.ip_source_ip == other.ip_source_ip and + self.ip_dest_ip == other.ip_dest_ip and + self.udp_source_port == other.udp_source_port and + self.udp_dest_port == other.udp_dest_port and + self.udp_length == other.udp_length and + self.udp_checksum == other.udp_checksum and + self.payload == other.payload + ) + return False def __repr__(self): - return (('UDPFrame(payload=%s, ' % repr(self.payload)) + + return ( + ('UDPFrame(payload=%s, ' % repr(self.payload)) + ('eth_dest_mac=0x%012x, ' % self.eth_dest_mac) + ('eth_src_mac=0x%012x, ' % self.eth_src_mac) + ('eth_type=0x%04x, ' % self.eth_type) + @@ -304,13 +312,14 @@ class UDPFrame(object): ('ip_fragment_offset=%d, ' % self.ip_fragment_offset) + ('ip_ttl=%d, ' % self.ip_ttl) + ('ip_protocol=0x%02x, ' % self.ip_protocol) + - ('ip_header_checksum=%x, ' % self.ip_header_checksum) + + ('ip_header_checksum=0x%x, ' % self.ip_header_checksum) + ('ip_source_ip=0x%08x, ' % self.ip_source_ip) + ('ip_dest_ip=0x%08x, ' % self.ip_dest_ip) + ('udp_source_port=%d, ' % self.udp_source_port) + ('udp_dest_port=%d, ' % self.udp_dest_port) + ('udp_length=%d, ' % self.udp_length) + - ('udp_checksum=%04x)' % self.udp_checksum)) + ('udp_checksum=0x%04x)' % self.udp_checksum) + ) class UDPFrameSource(): From 270641b7a32eb043a49642e1bf73f52569f930c1 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 30 Sep 2016 22:15:21 -0700 Subject: [PATCH 316/617] Update UDP modules and example designs to utilize UDP checksum modules --- example/ATLYS/fpga/fpga/Makefile | 1 + example/ATLYS/fpga/rtl/fpga_core.v | 4 +--- example/ATLYS/fpga/tb/test_fpga_core.py | 1 + example/DE5-Net/fpga/fpga/Makefile | 1 + example/DE5-Net/fpga/rtl/fpga_core.v | 4 +--- example/DE5-Net/fpga/tb/test_fpga_core.py | 1 + example/HXT100G/fpga/fpga/Makefile | 1 + example/HXT100G/fpga/rtl/fpga_core.v | 4 +--- example/HXT100G/fpga/tb/test_fpga_core.py | 1 + example/NexysVideo/fpga/fpga/Makefile | 1 + example/NexysVideo/fpga/rtl/fpga_core.v | 4 +--- example/NexysVideo/fpga/tb/test_fpga_core.py | 1 + example/VCU108/fpga_10g/fpga/Makefile | 1 + example/VCU108/fpga_10g/rtl/fpga_core.v | 4 +--- example/VCU108/fpga_10g/tb/test_fpga_core.py | 1 + example/VCU108/fpga_1g/fpga/Makefile | 1 + example/VCU108/fpga_1g/rtl/fpga_core.v | 4 +--- example/VCU108/fpga_1g/tb/test_fpga_core.py | 1 + rtl/udp.v | 10 ++++------ rtl/udp_64.v | 10 ++++------ rtl/udp_complete.v | 4 ++-- rtl/udp_complete_64.v | 4 ++-- tb/test_udp.py | 12 +++++++++--- tb/test_udp.v | 4 ++-- tb/test_udp_64.py | 12 +++++++++--- tb/test_udp_64.v | 4 ++-- tb/test_udp_complete.py | 12 +++++++++--- tb/test_udp_complete.v | 4 ++-- tb/test_udp_complete_64.py | 12 +++++++++--- tb/test_udp_complete_64.v | 4 ++-- 30 files changed, 74 insertions(+), 54 deletions(-) diff --git a/example/ATLYS/fpga/fpga/Makefile b/example/ATLYS/fpga/fpga/Makefile index 96c994cc6..ac22c62f3 100644 --- a/example/ATLYS/fpga/fpga/Makefile +++ b/example/ATLYS/fpga/fpga/Makefile @@ -27,6 +27,7 @@ SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx.v SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v SYN_FILES += lib/eth/rtl/udp.v SYN_FILES += lib/eth/rtl/udp_ip_rx.v SYN_FILES += lib/eth/rtl/udp_ip_tx.v diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index 20d26a1ca..767a3ca82 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -437,9 +437,7 @@ eth_axis_tx_inst ( .busy() ); -udp_complete #( - .UDP_CHECKSUM_ENABLE(0) -) +udp_complete udp_complete_inst ( .clk(clk), .rst(rst), diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index 639c5919f..a1943afb5 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -50,6 +50,7 @@ srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen.v") srcs.append("../lib/eth/rtl/udp.v") srcs.append("../lib/eth/rtl/udp_ip_rx.v") srcs.append("../lib/eth/rtl/udp_ip_tx.v") diff --git a/example/DE5-Net/fpga/fpga/Makefile b/example/DE5-Net/fpga/fpga/Makefile index 713bd0dea..d0eecc4e9 100644 --- a/example/DE5-Net/fpga/fpga/Makefile +++ b/example/DE5-Net/fpga/fpga/Makefile @@ -20,6 +20,7 @@ SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index 4176ee3d2..5b01704ca 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -421,9 +421,7 @@ eth_axis_tx_inst ( .busy() ); -udp_complete_64 #( - .UDP_CHECKSUM_ENABLE(0) -) +udp_complete_64 udp_complete_inst ( .clk(clk), .rst(rst), diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index 08f469940..757e99d9c 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -45,6 +45,7 @@ srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") diff --git a/example/HXT100G/fpga/fpga/Makefile b/example/HXT100G/fpga/fpga/Makefile index 1f2d7375a..533df0179 100644 --- a/example/HXT100G/fpga/fpga/Makefile +++ b/example/HXT100G/fpga/fpga/Makefile @@ -25,6 +25,7 @@ SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v index 232fc9c1c..ee8829cdc 100644 --- a/example/HXT100G/fpga/rtl/fpga_core.v +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -565,9 +565,7 @@ eth_axis_tx_inst ( .busy() ); -udp_complete_64 #( - .UDP_CHECKSUM_ENABLE(0) -) +udp_complete_64 udp_complete_inst ( .clk(clk), .rst(rst), diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index a03b3e068..92721aca7 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -45,6 +45,7 @@ srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") diff --git a/example/NexysVideo/fpga/fpga/Makefile b/example/NexysVideo/fpga/fpga/Makefile index 88f1a76a9..83d89a4ea 100644 --- a/example/NexysVideo/fpga/fpga/Makefile +++ b/example/NexysVideo/fpga/fpga/Makefile @@ -23,6 +23,7 @@ SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx.v SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v SYN_FILES += lib/eth/rtl/udp.v SYN_FILES += lib/eth/rtl/udp_ip_rx.v SYN_FILES += lib/eth/rtl/udp_ip_tx.v diff --git a/example/NexysVideo/fpga/rtl/fpga_core.v b/example/NexysVideo/fpga/rtl/fpga_core.v index 574d8fd98..c3de34541 100644 --- a/example/NexysVideo/fpga/rtl/fpga_core.v +++ b/example/NexysVideo/fpga/rtl/fpga_core.v @@ -438,9 +438,7 @@ eth_axis_tx_inst ( .busy() ); -udp_complete #( - .UDP_CHECKSUM_ENABLE(0) -) +udp_complete udp_complete_inst ( .clk(clk), .rst(rst), diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.py b/example/NexysVideo/fpga/tb/test_fpga_core.py index 8796e7b34..38fbe803f 100755 --- a/example/NexysVideo/fpga/tb/test_fpga_core.py +++ b/example/NexysVideo/fpga/tb/test_fpga_core.py @@ -50,6 +50,7 @@ srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen.v") srcs.append("../lib/eth/rtl/udp.v") srcs.append("../lib/eth/rtl/udp_ip_rx.v") srcs.append("../lib/eth/rtl/udp_ip_tx.v") diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index ef3b2397d..6c7e2151c 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -24,6 +24,7 @@ SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index 7dbfb1e45..70dc4b99b 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -687,9 +687,7 @@ eth_axis_tx_inst ( .busy() ); -udp_complete_64 #( - .UDP_CHECKSUM_ENABLE(0) -) +udp_complete_64 udp_complete_inst ( .clk(clk), .rst(rst), diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index b1e4d9fac..009ef6699 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -52,6 +52,7 @@ srcs.append("../lib/eth/rtl/eth_axis_tx.v") srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index a2ef51802..b6bafd5e2 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -18,6 +18,7 @@ SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx.v SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v SYN_FILES += lib/eth/rtl/udp.v SYN_FILES += lib/eth/rtl/udp_ip_rx.v SYN_FILES += lib/eth/rtl/udp_ip_tx.v diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v index 3b2dfdd27..6a7e6eec7 100644 --- a/example/VCU108/fpga_1g/rtl/fpga_core.v +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -395,9 +395,7 @@ eth_axis_tx_inst ( .busy() ); -udp_complete #( - .UDP_CHECKSUM_ENABLE(0) -) +udp_complete udp_complete_inst ( .clk(clk), .rst(rst), diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py index 6f6689f21..6e232e234 100755 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -45,6 +45,7 @@ srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen.v") srcs.append("../lib/eth/rtl/udp.v") srcs.append("../lib/eth/rtl/udp_ip_rx.v") srcs.append("../lib/eth/rtl/udp_ip_tx.v") diff --git a/rtl/udp.v b/rtl/udp.v index 23b3508c6..e28179977 100644 --- a/rtl/udp.v +++ b/rtl/udp.v @@ -31,7 +31,7 @@ THE SOFTWARE. */ module udp # ( - parameter CHECKSUM_ENABLE = 1, + parameter CHECKSUM_GEN_ENABLE = 1, parameter CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11, parameter CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3 ) @@ -253,13 +253,13 @@ udp_ip_rx_inst ( generate -if (CHECKSUM_ENABLE) begin +if (CHECKSUM_GEN_ENABLE) begin - udp_checksum #( + udp_checksum_gen #( .PAYLOAD_FIFO_ADDR_WIDTH(CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), .HEADER_FIFO_ADDR_WIDTH(CHECKSUM_HEADER_FIFO_ADDR_WIDTH) ) - udp_checksum_inst ( + udp_checksum_gen_inst ( .clk(clk), .rst(rst), // UDP frame input @@ -276,13 +276,11 @@ if (CHECKSUM_ENABLE) begin .input_ip_flags(input_udp_ip_flags), .input_ip_fragment_offset(input_udp_ip_fragment_offset), .input_ip_ttl(input_udp_ip_ttl), - .input_ip_protocol(0), .input_ip_header_checksum(input_udp_ip_header_checksum), .input_ip_source_ip(input_udp_ip_source_ip), .input_ip_dest_ip(input_udp_ip_dest_ip), .input_udp_source_port(input_udp_source_port), .input_udp_dest_port(input_udp_dest_port), - .input_udp_checksum(input_udp_checksum), .input_udp_payload_tdata(input_udp_payload_tdata), .input_udp_payload_tvalid(input_udp_payload_tvalid), .input_udp_payload_tready(input_udp_payload_tready), diff --git a/rtl/udp_64.v b/rtl/udp_64.v index 52b5b73a8..b7f6f2aaf 100644 --- a/rtl/udp_64.v +++ b/rtl/udp_64.v @@ -31,7 +31,7 @@ THE SOFTWARE. */ module udp_64 # ( - parameter CHECKSUM_ENABLE = 1, + parameter CHECKSUM_GEN_ENABLE = 1, parameter CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11, parameter CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3 ) @@ -260,13 +260,13 @@ udp_ip_rx_64_inst ( generate -if (CHECKSUM_ENABLE) begin +if (CHECKSUM_GEN_ENABLE) begin - udp_checksum_64 #( + udp_checksum_gen_64 #( .PAYLOAD_FIFO_ADDR_WIDTH(CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), .HEADER_FIFO_ADDR_WIDTH(CHECKSUM_HEADER_FIFO_ADDR_WIDTH) ) - udp_checksum_64_inst ( + udp_checksum_gen_64_inst ( .clk(clk), .rst(rst), // UDP frame input @@ -283,13 +283,11 @@ if (CHECKSUM_ENABLE) begin .input_ip_flags(input_udp_ip_flags), .input_ip_fragment_offset(input_udp_ip_fragment_offset), .input_ip_ttl(input_udp_ip_ttl), - .input_ip_protocol(0), .input_ip_header_checksum(input_udp_ip_header_checksum), .input_ip_source_ip(input_udp_ip_source_ip), .input_ip_dest_ip(input_udp_ip_dest_ip), .input_udp_source_port(input_udp_source_port), .input_udp_dest_port(input_udp_dest_port), - .input_udp_checksum(input_udp_checksum), .input_udp_payload_tdata(input_udp_payload_tdata), .input_udp_payload_tkeep(input_udp_payload_tkeep), .input_udp_payload_tvalid(input_udp_payload_tvalid), diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v index 3d1195442..de9089bf7 100644 --- a/rtl/udp_complete.v +++ b/rtl/udp_complete.v @@ -34,7 +34,7 @@ module udp_complete #( parameter ARP_REQUEST_RETRY_COUNT = 4, parameter ARP_REQUEST_RETRY_INTERVAL = 125000000*2, parameter ARP_REQUEST_TIMEOUT = 125000000*30, - parameter UDP_CHECKSUM_ENABLE = 1, + parameter UDP_CHECKSUM_GEN_ENABLE = 1, parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11, parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3 ) @@ -524,7 +524,7 @@ ip_complete_inst ( * UDP interface */ udp #( - .CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .CHECKSUM_GEN_ENABLE(UDP_CHECKSUM_GEN_ENABLE), .CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), .CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) ) diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v index 5ae64483c..0f7b09e86 100644 --- a/rtl/udp_complete_64.v +++ b/rtl/udp_complete_64.v @@ -34,7 +34,7 @@ module udp_complete_64 #( parameter ARP_REQUEST_RETRY_COUNT = 4, parameter ARP_REQUEST_RETRY_INTERVAL = 125000000*2, parameter ARP_REQUEST_TIMEOUT = 125000000*30, - parameter UDP_CHECKSUM_ENABLE = 1, + parameter UDP_CHECKSUM_GEN_ENABLE = 1, parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11, parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3 ) @@ -543,7 +543,7 @@ ip_complete_64_inst ( * UDP interface */ udp_64 #( - .CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .CHECKSUM_GEN_ENABLE(UDP_CHECKSUM_GEN_ENABLE), .CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), .CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) ) diff --git a/tb/test_udp.py b/tb/test_udp.py index 6f6f099ad..3697616c4 100755 --- a/tb/test_udp.py +++ b/tb/test_udp.py @@ -36,8 +36,10 @@ testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/udp_checksum_gen.v") srcs.append("../rtl/udp_ip_rx.v") srcs.append("../rtl/udp_ip_tx.v") +srcs.append("../lib/axis/rtl/axis_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) @@ -434,9 +436,13 @@ def bench(): tx_error_payload_early_termination_asserted.next = 1 def wait_normal(): - while (input_ip_payload_tvalid or input_udp_payload_tvalid or - output_ip_payload_tvalid or output_udp_payload_tvalid or - input_ip_hdr_valid or input_udp_hdr_valid): + i = 8 + while i > 0: + i = max(0, i-1) + if (input_ip_payload_tvalid or input_udp_payload_tvalid or + output_ip_payload_tvalid or output_udp_payload_tvalid or + input_ip_hdr_valid or input_udp_hdr_valid): + i = 8 yield clk.posedge @instance diff --git a/tb/test_udp.v b/tb/test_udp.v index b1dbe36be..09fecdf42 100644 --- a/tb/test_udp.v +++ b/tb/test_udp.v @@ -32,7 +32,7 @@ THE SOFTWARE. module test_udp; // Parameters -parameter CHECKSUM_ENABLE = 0; +parameter CHECKSUM_GEN_ENABLE = 1; parameter CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11; parameter CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3; @@ -266,7 +266,7 @@ initial begin end udp #( - .CHECKSUM_ENABLE(CHECKSUM_ENABLE), + .CHECKSUM_GEN_ENABLE(CHECKSUM_GEN_ENABLE), .CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), .CHECKSUM_HEADER_FIFO_ADDR_WIDTH(CHECKSUM_HEADER_FIFO_ADDR_WIDTH) ) diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py index ac4edc1d2..e1efba408 100755 --- a/tb/test_udp_64.py +++ b/tb/test_udp_64.py @@ -36,8 +36,10 @@ testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/udp_checksum_gen_64.v") srcs.append("../rtl/udp_ip_rx_64.v") srcs.append("../rtl/udp_ip_tx_64.v") +srcs.append("../lib/axis/rtl/axis_fifo_64.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) @@ -446,9 +448,13 @@ def bench(): tx_error_payload_early_termination_asserted.next = 1 def wait_normal(): - while (input_ip_payload_tvalid or input_udp_payload_tvalid or - output_ip_payload_tvalid or output_udp_payload_tvalid or - input_ip_hdr_valid or input_udp_hdr_valid): + i = 8 + while i > 0: + i = max(0, i-1) + if (input_ip_payload_tvalid or input_udp_payload_tvalid or + output_ip_payload_tvalid or output_udp_payload_tvalid or + input_ip_hdr_valid or input_udp_hdr_valid): + i = 8 yield clk.posedge @instance diff --git a/tb/test_udp_64.v b/tb/test_udp_64.v index b181bcf8b..0b6bfc731 100644 --- a/tb/test_udp_64.v +++ b/tb/test_udp_64.v @@ -32,7 +32,7 @@ THE SOFTWARE. module test_udp_64; // Parameters -parameter CHECKSUM_ENABLE = 0; +parameter CHECKSUM_GEN_ENABLE = 1; parameter CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11; parameter CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3; @@ -274,7 +274,7 @@ initial begin end udp_64 #( - .CHECKSUM_ENABLE(CHECKSUM_ENABLE), + .CHECKSUM_GEN_ENABLE(CHECKSUM_GEN_ENABLE), .CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), .CHECKSUM_HEADER_FIFO_ADDR_WIDTH(CHECKSUM_HEADER_FIFO_ADDR_WIDTH) ) diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py index c67a7757e..68f6892bd 100755 --- a/tb/test_udp_complete.py +++ b/tb/test_udp_complete.py @@ -38,6 +38,7 @@ srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/udp.v") +srcs.append("../rtl/udp_checksum_gen.v") srcs.append("../rtl/udp_ip_rx.v") srcs.append("../rtl/udp_ip_tx.v") srcs.append("../rtl/ip_complete.v") @@ -54,6 +55,7 @@ srcs.append("../rtl/eth_arb_mux_2.v") srcs.append("../rtl/eth_mux_2.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/axis/rtl/axis_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) @@ -523,9 +525,13 @@ def bench(): udp_tx_error_payload_early_termination_asserted.next = 1 def wait_normal(): - while (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or - output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or - input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): + i = 16 + while i > 0: + i = max(0, i-1) + if (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or + output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or + input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): + i = 16 yield clk.posedge @instance diff --git a/tb/test_udp_complete.v b/tb/test_udp_complete.v index d89cf2ddb..2d3d246b6 100644 --- a/tb/test_udp_complete.v +++ b/tb/test_udp_complete.v @@ -36,7 +36,7 @@ parameter ARP_CACHE_ADDR_WIDTH = 2; parameter ARP_REQUEST_RETRY_COUNT = 4; parameter ARP_REQUEST_RETRY_INTERVAL = 150; parameter ARP_REQUEST_TIMEOUT = 400; -parameter UDP_CHECKSUM_ENABLE = 0; +parameter UDP_CHECKSUM_GEN_ENABLE = 1; parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11; parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3; @@ -309,7 +309,7 @@ udp_complete #( .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT), - .UDP_CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .UDP_CHECKSUM_GEN_ENABLE(UDP_CHECKSUM_GEN_ENABLE), .UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), .UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) ) diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index 1c8d7f5f6..56c53fcf5 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -38,6 +38,7 @@ srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/udp_64.v") +srcs.append("../rtl/udp_checksum_gen_64.v") srcs.append("../rtl/udp_ip_rx_64.v") srcs.append("../rtl/udp_ip_tx_64.v") srcs.append("../rtl/ip_complete_64.v") @@ -54,6 +55,7 @@ srcs.append("../rtl/eth_arb_mux_64_2.v") srcs.append("../rtl/eth_mux_64_2.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/axis/rtl/axis_fifo_64.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) @@ -541,9 +543,13 @@ def bench(): udp_tx_error_payload_early_termination_asserted.next = 1 def wait_normal(): - while (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or - output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or - input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): + i = 16 + while i > 0: + i = max(0, i-1) + if (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or + output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or + input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): + i = 16 yield clk.posedge @instance diff --git a/tb/test_udp_complete_64.v b/tb/test_udp_complete_64.v index 2dd4d00a1..bf1e47e31 100644 --- a/tb/test_udp_complete_64.v +++ b/tb/test_udp_complete_64.v @@ -36,7 +36,7 @@ parameter ARP_CACHE_ADDR_WIDTH = 2; parameter ARP_REQUEST_RETRY_COUNT = 4; parameter ARP_REQUEST_RETRY_INTERVAL = 150; parameter ARP_REQUEST_TIMEOUT = 400; -parameter UDP_CHECKSUM_ENABLE = 0; +parameter UDP_CHECKSUM_GEN_ENABLE = 1; parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11; parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3; @@ -321,7 +321,7 @@ udp_complete_64 #( .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT), - .UDP_CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .UDP_CHECKSUM_GEN_ENABLE(UDP_CHECKSUM_GEN_ENABLE), .UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), .UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) ) From d5928ee776de08decb84bf0f976a94efbb60b930 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 5 Oct 2016 17:33:05 -0700 Subject: [PATCH 317/617] Trim UDP and IP payloads to proper length --- tb/ip_ep.py | 2 +- tb/udp_ep.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tb/ip_ep.py b/tb/ip_ep.py index 29a858aff..24a3fed8f 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -190,7 +190,7 @@ class IPFrame(object): self.ip_source_ip = struct.unpack('>L', data.payload.data[12:16])[0] self.ip_dest_ip = struct.unpack('>L', data.payload.data[16:20])[0] - self.payload = axis_ep.AXIStreamFrame(data.payload.data[20:]) + self.payload = axis_ep.AXIStreamFrame(data.payload.data[20:self.ip_length]) def __eq__(self, other): if type(other) is IPFrame: diff --git a/tb/udp_ep.py b/tb/udp_ep.py index 5aa73792e..7e58cbf33 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -267,7 +267,7 @@ class UDPFrame(object): self.udp_length = struct.unpack('>H', data.payload.data[4:6])[0] self.udp_checksum = struct.unpack('>H', data.payload.data[6:8])[0] - self.payload = axis_ep.AXIStreamFrame(data.payload.data[8:]) + self.payload = axis_ep.AXIStreamFrame(data.payload.data[8:self.udp_length]) def __eq__(self, other): if type(other) is UDPFrame: From 77ecbd7dcb887b98ca5bceab5308b69cb300e2fc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 5 Oct 2016 17:41:00 -0700 Subject: [PATCH 318/617] Makefile updates --- example/DE5-Net/fpga/common/altera.mk | 2 +- example/VCU108/fpga_10g/fpga/Makefile | 2 +- example/VCU108/fpga_1g/fpga/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/example/DE5-Net/fpga/common/altera.mk b/example/DE5-Net/fpga/common/altera.mk index 7693415f4..e06d66313 100644 --- a/example/DE5-Net/fpga/common/altera.mk +++ b/example/DE5-Net/fpga/common/altera.mk @@ -27,7 +27,7 @@ ################################################################### # phony targets -.PHONY: clean +.PHONY: clean fpga # output files to hang on to .PRECIOUS: %.sof %.map.rpt %.fit.rpt %.asm.rpt %.sta.rpt diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 6c7e2151c..11c1ed737 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -60,7 +60,7 @@ XCI_FILES += ip/ten_gig_eth_pcs_pma_0.xci include ../common/vivado.mk -program: #$(FPGA_TOP).bit +program: $(FPGA_TOP).bit echo "open_hw" > program.tcl echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index b6bafd5e2..6c581c779 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -48,7 +48,7 @@ XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci include ../common/vivado.mk -program: #$(FPGA_TOP).bit +program: $(FPGA_TOP).bit echo "open_hw" > program.tcl echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl From 3b47b422fac1f7acb4ad31c8f756c7997a4e3300 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 6 Oct 2016 17:52:23 -0700 Subject: [PATCH 319/617] Fix Vivado clock groups --- example/NexysVideo/fpga/fpga.xdc | 4 ++-- example/VCU108/fpga_10g/fpga.xdc | 10 +++++----- example/VCU108/fpga_1g/fpga.xdc | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/example/NexysVideo/fpga/fpga.xdc b/example/NexysVideo/fpga/fpga.xdc index b6b1580d7..c6da45b8e 100644 --- a/example/NexysVideo/fpga/fpga.xdc +++ b/example/NexysVideo/fpga/fpga.xdc @@ -8,7 +8,7 @@ set_property CONFIG_VOLTAGE 3.3 [current_design] # 100 MHz clock set_property -dict {LOC R4 IOSTANDARD LVCMOS33} [get_ports clk] create_clock -period 10.000 -name clk [get_ports clk] -set_clock_groups -asynchronous -group clk +set_clock_groups -asynchronous -group [get_clocks clk -include_generated_clocks] # LEDs set_property -dict {LOC T14 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[0]}] @@ -64,5 +64,5 @@ set_property -dict {LOC W14 IOSTANDARD LVCMOS25} [get_ports phy_pme_n] #set_property -dict {LOC AA16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports phy_mdc] create_clock -period 8.000 -name phy_rx_clk [get_ports phy_rx_clk] -set_clock_groups -asynchronous -group phy_rx_clk +set_clock_groups -asynchronous -group [get_clocks phy_rx_clk -include_generated_clocks] diff --git a/example/VCU108/fpga_10g/fpga.xdc b/example/VCU108/fpga_10g/fpga.xdc index e28e4aa93..4ad1c74f3 100644 --- a/example/VCU108/fpga_10g/fpga.xdc +++ b/example/VCU108/fpga_10g/fpga.xdc @@ -10,23 +10,23 @@ set_property CONFIG_VOLTAGE 1.8 [current_design] #set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p] #set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n] #create_clock -period 3.333 -name clk_300_mhz_1 [get_ports clk_300mhz_1_p] -#set_clock_groups -asynchronous -group clk_300mhz_1 +#set_clock_groups -asynchronous -group [get_clocks clk_300mhz_1 -include_generated_clocks] #set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p] #set_property -dict {LOC G21 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_n] #create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p] -#set_clock_groups -asynchronous -group clk_300mhz_2 +#set_clock_groups -asynchronous -group [get_clocks clk_300mhz_2 -include_generated_clocks] # 125 MHz set_property -dict {LOC BC9 IOSTANDARD LVDS} [get_ports clk_125mhz_p] set_property -dict {LOC BC8 IOSTANDARD LVDS} [get_ports clk_125mhz_n] create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] -set_clock_groups -asynchronous -group clk_125mhz +set_clock_groups -asynchronous -group [get_clocks clk_125mhz -include_generated_clocks] # 90 MHz #set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] #create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] -#set_clock_groups -asynchronous -group clk_90mhz +#set_clock_groups -asynchronous -group [get_clocks clk_90mhz -include_generated_clocks] # LEDs set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] @@ -74,7 +74,7 @@ set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports phy_int_n] # 625 MHz ref clock from SGMII PHY create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] -set_clock_groups -asynchronous -group phy_sgmii_clk +set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generated_clocks] # QSFP+ Interface set_property -dict {LOC AG45} [get_ports qsfp_rx1_p] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 diff --git a/example/VCU108/fpga_1g/fpga.xdc b/example/VCU108/fpga_1g/fpga.xdc index f6df87b7e..b7cc5658a 100644 --- a/example/VCU108/fpga_1g/fpga.xdc +++ b/example/VCU108/fpga_1g/fpga.xdc @@ -10,23 +10,23 @@ set_property CONFIG_VOLTAGE 1.8 [current_design] #set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p] #set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n] #create_clock -period 3.333 -name clk_300_mhz_1 [get_ports clk_300mhz_1_p] -#set_clock_groups -asynchronous -group clk_300mhz_1 +#set_clock_groups -asynchronous -group [get_clocks clk_300mhz_1 -include_generated_clocks] #set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p] #set_property -dict {LOC G21 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_n] #create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p] -#set_clock_groups -asynchronous -group clk_300mhz_2 +#set_clock_groups -asynchronous -group [get_clocks clk_300mhz_2 -include_generated_clocks] # 125 MHz set_property -dict {LOC BC9 IOSTANDARD LVDS} [get_ports clk_125mhz_p] set_property -dict {LOC BC8 IOSTANDARD LVDS} [get_ports clk_125mhz_n] create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] -set_clock_groups -asynchronous -group clk_125mhz +set_clock_groups -asynchronous -group [get_clocks clk_125mhz -include_generated_clocks] # 90 MHz #set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] #create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] -#set_clock_groups -asynchronous -group clk_90mhz +#set_clock_groups -asynchronous -group [get_clocks clk_90mhz -include_generated_clocks] # LEDs set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] @@ -74,5 +74,5 @@ set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports phy_int_n] # 625 MHz ref clock from SGMII PHY create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] -set_clock_groups -asynchronous -group phy_sgmii_clk +set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generated_clocks] From c2e459c97129106f2ef22e8303946a39625747f5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 9 Mar 2017 17:14:14 -0800 Subject: [PATCH 320/617] Connect transceiver control lines --- example/DE5-Net/fpga/rtl/fpga.v | 132 ++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 42 deletions(-) diff --git a/example/DE5-Net/fpga/rtl/fpga.v b/example/DE5-Net/fpga/rtl/fpga.v index b4276afdb..9190e44c6 100644 --- a/example/DE5-Net/fpga/rtl/fpga.v +++ b/example/DE5-Net/fpga/rtl/fpga.v @@ -31,55 +31,83 @@ THE SOFTWARE. */ module fpga ( // CPU reset button - input wire CPU_RESET_n, + input wire CPU_RESET_n, // buttons - input wire [3:0] BUTTON, - input wire [3:0] SW, + input wire [3:0] BUTTON, + input wire [3:0] SW, // LEDs - output wire [6:0] HEX0_D, - output wire HEX0_DP, - output wire [6:0] HEX1_D, - output wire HEX1_DP, - output wire [3:0] LED, - output wire [3:0] LED_BRACKET, - output wire LED_RJ45_L, - output wire LED_RJ45_R, + output wire [6:0] HEX0_D, + output wire HEX0_DP, + output wire [6:0] HEX1_D, + output wire HEX1_DP, + output wire [3:0] LED, + output wire [3:0] LED_BRACKET, + output wire LED_RJ45_L, + output wire LED_RJ45_R, // Temperature control - //inout wire TEMP_CLK, - //inout wire TEMP_DATA, - //input wire TEMP_INT_n, - //input wire TEMP_OVERT_n, - output wire FAN_CTRL, + //inout wire TEMP_CLK, + //inout wire TEMP_DATA, + //input wire TEMP_INT_n, + //input wire TEMP_OVERT_n, + output wire FAN_CTRL, // 50 MHz clock inputs - input wire OSC_50_B3B, - input wire OSC_50_B3D, - input wire OSC_50_B4A, - input wire OSC_50_B4D, - input wire OSC_50_B7A, - input wire OSC_50_B7D, - input wire OSC_50_B8A, - input wire OSC_50_B8D, + input wire OSC_50_B3B, + input wire OSC_50_B3D, + input wire OSC_50_B4A, + input wire OSC_50_B4D, + input wire OSC_50_B7A, + input wire OSC_50_B7D, + input wire OSC_50_B8A, + input wire OSC_50_B8D, // PCIe interface - //input wire PCIE_PERST_n, - //input wire PCIE_REFCLK_p, - //input wire [7:0] PCIE_RX_p, - //output wire [7:0] PCIE_TX_p, - //input wire PCIE_WAKE_n, - //inout wire PCIE_SMBCLK, - //inout wire PCIE_SMBDAT, + //input wire PCIE_PERST_n, + //input wire PCIE_REFCLK_p, + //input wire [7:0] PCIE_RX_p, + //output wire [7:0] PCIE_TX_p, + //input wire PCIE_WAKE_n, + //inout wire PCIE_SMBCLK, + //inout wire PCIE_SMBDAT, // Si570 - inout wire CLOCK_SCL, - inout wire CLOCK_SDA, + inout wire CLOCK_SCL, + inout wire CLOCK_SDA, // 10G Ethernet - input wire SFPA_RX_p, - output wire SFPA_TX_p, - input wire SFPB_RX_p, - output wire SFPB_TX_p, - input wire SFPC_RX_p, - output wire SFPC_TX_p, - input wire SFPD_RX_p, - output wire SFPD_TX_p, - input wire SFP_REFCLK_P + input wire SFPA_LOS, + input wire SFPA_TXFAULT, + input wire SFPA_MOD0_PRESNT_n, + inout wire SFPA_MOD1_SCL, + inout wire SFPA_MOD2_SDA, + output wire SFPA_TXDISABLE, + output wire [1:0] SPFA_RATESEL, + input wire SFPA_RX_p, + output wire SFPA_TX_p, + input wire SFPB_LOS, + input wire SFPB_TXFAULT, + input wire SFPB_MOD0_PRESNT_n, + inout wire SFPB_MOD1_SCL, + inout wire SFPB_MOD2_SDA, + output wire SFPB_TXDISABLE, + output wire [1:0] SPFB_RATESEL, + input wire SFPB_RX_p, + output wire SFPB_TX_p, + input wire SFPC_LOS, + input wire SFPC_TXFAULT, + input wire SFPC_MOD0_PRESNT_n, + inout wire SFPC_MOD1_SCL, + inout wire SFPC_MOD2_SDA, + output wire SFPC_TXDISABLE, + output wire [1:0] SPFC_RATESEL, + input wire SFPC_RX_p, + output wire SFPC_TX_p, + input wire SFPD_LOS, + input wire SFPD_TXFAULT, + input wire SFPD_MOD0_PRESNT_n, + inout wire SFPD_MOD1_SCL, + inout wire SFPD_MOD2_SDA, + output wire SFPD_TXDISABLE, + output wire [1:0] SPFD_RATESEL, + input wire SFPD_RX_p, + output wire SFPD_TX_p, + input wire SFP_REFCLK_P ); // Clock and reset @@ -240,6 +268,26 @@ wire [71:0] sfp_d_rx_dc; wire [367:0] phy_reconfig_from_xcvr; wire [559:0] phy_reconfig_to_xcvr; +assign SFPA_MOD1_SCL = 1'bz; +assign SFPA_MOD2_SDA = 1'bz; +assign SFPA_TXDISABLE = 1'b0; +assign SPFA_RATESEL = 2'b00; + +assign SFPB_MOD1_SCL = 1'bz; +assign SFPB_MOD2_SDA = 1'bz; +assign SFPB_TXDISABLE = 1'b0; +assign SPFB_RATESEL = 2'b00; + +assign SFPC_MOD1_SCL = 1'bz; +assign SFPC_MOD2_SDA = 1'bz; +assign SFPC_TXDISABLE = 1'b0; +assign SPFC_RATESEL = 2'b00; + +assign SFPD_MOD1_SCL = 1'bz; +assign SFPD_MOD2_SDA = 1'bz; +assign SFPD_TXDISABLE = 1'b0; +assign SPFD_RATESEL = 2'b00; + phy phy_inst ( .pll_ref_clk(SFP_REFCLK_P), From aebe0549dde7f4fcdd9b54691e054972cb5449fc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 18 May 2017 13:35:11 -0700 Subject: [PATCH 321/617] Happy new year --- COPYING | 2 +- rtl/arbiter.v | 2 +- rtl/axis_adapter.v | 2 +- rtl/axis_arb_mux.py | 2 +- rtl/axis_arb_mux_4.v | 2 +- rtl/axis_arb_mux_64.py | 2 +- rtl/axis_arb_mux_64_4.v | 2 +- rtl/axis_async_fifo.v | 2 +- rtl/axis_async_fifo_64.v | 2 +- rtl/axis_async_frame_fifo.v | 2 +- rtl/axis_async_frame_fifo_64.v | 2 +- rtl/axis_cobs_decode.v | 2 +- rtl/axis_cobs_encode.v | 2 +- rtl/axis_crosspoint.py | 2 +- rtl/axis_crosspoint_4x4.v | 2 +- rtl/axis_crosspoint_64.py | 2 +- rtl/axis_crosspoint_64_4x4.v | 2 +- rtl/axis_demux.py | 2 +- rtl/axis_demux_4.v | 2 +- rtl/axis_demux_64.py | 2 +- rtl/axis_demux_64_4.v | 2 +- rtl/axis_fifo.v | 2 +- rtl/axis_fifo_64.v | 2 +- rtl/axis_frame_fifo.v | 2 +- rtl/axis_frame_fifo_64.v | 2 +- rtl/axis_frame_join.py | 2 +- rtl/axis_frame_join_4.v | 2 +- rtl/axis_frame_length_adjust.v | 2 +- rtl/axis_frame_length_adjust_fifo.v | 2 +- rtl/axis_frame_length_adjust_fifo_64.v | 2 +- rtl/axis_ll_bridge.v | 2 +- rtl/axis_mux.py | 2 +- rtl/axis_mux_4.v | 2 +- rtl/axis_mux_64.py | 2 +- rtl/axis_mux_64_4.v | 2 +- rtl/axis_rate_limit.v | 2 +- rtl/axis_rate_limit_64.v | 2 +- rtl/axis_register.v | 2 +- rtl/axis_register_64.v | 2 +- rtl/axis_srl_fifo.v | 2 +- rtl/axis_srl_fifo_64.v | 2 +- rtl/axis_srl_register.v | 2 +- rtl/axis_srl_register_64.v | 2 +- rtl/axis_stat_counter.v | 2 +- rtl/axis_switch.py | 2 +- rtl/axis_switch_4x4.v | 2 +- rtl/axis_switch_64.py | 2 +- rtl/axis_switch_64_4x4.v | 2 +- rtl/axis_tap.v | 2 +- rtl/axis_tap_64.v | 2 +- rtl/ll_axis_bridge.v | 2 +- rtl/priority_encoder.v | 2 +- tb/axis_ep.py | 2 +- tb/ll_ep.py | 2 +- tb/test_arbiter.py | 2 +- tb/test_arbiter.v | 2 +- tb/test_arbiter_rr.py | 2 +- tb/test_arbiter_rr.v | 2 +- tb/test_axis_adapter_64_8.py | 2 +- tb/test_axis_adapter_64_8.v | 2 +- tb/test_axis_adapter_8_64.py | 2 +- tb/test_axis_adapter_8_64.v | 2 +- tb/test_axis_arb_mux_4.py | 2 +- tb/test_axis_arb_mux_4.v | 2 +- tb/test_axis_arb_mux_64_4.py | 2 +- tb/test_axis_arb_mux_64_4.v | 2 +- tb/test_axis_async_fifo.py | 2 +- tb/test_axis_async_fifo.v | 2 +- tb/test_axis_async_fifo_64.py | 2 +- tb/test_axis_async_fifo_64.v | 2 +- tb/test_axis_async_frame_fifo.py | 2 +- tb/test_axis_async_frame_fifo.v | 2 +- tb/test_axis_async_frame_fifo_64.py | 2 +- tb/test_axis_async_frame_fifo_64.v | 2 +- tb/test_axis_cobs_decode.py | 2 +- tb/test_axis_cobs_decode.v | 2 +- tb/test_axis_cobs_encode.py | 2 +- tb/test_axis_cobs_encode.v | 2 +- tb/test_axis_cobs_encode_zero_frame.py | 2 +- tb/test_axis_cobs_encode_zero_frame.v | 2 +- tb/test_axis_crosspoint_4x4.py | 2 +- tb/test_axis_crosspoint_4x4.v | 2 +- tb/test_axis_crosspoint_64_4x4.py | 2 +- tb/test_axis_crosspoint_64_4x4.v | 2 +- tb/test_axis_demux_4.py | 2 +- tb/test_axis_demux_4.v | 2 +- tb/test_axis_demux_64_4.py | 2 +- tb/test_axis_demux_64_4.v | 2 +- tb/test_axis_fifo.py | 2 +- tb/test_axis_fifo.v | 2 +- tb/test_axis_fifo_64.py | 2 +- tb/test_axis_fifo_64.v | 2 +- tb/test_axis_frame_fifo.py | 2 +- tb/test_axis_frame_fifo.v | 2 +- tb/test_axis_frame_fifo_64.py | 2 +- tb/test_axis_frame_fifo_64.v | 2 +- tb/test_axis_frame_join_4.py | 2 +- tb/test_axis_frame_join_4.v | 2 +- tb/test_axis_frame_length_adjust_64.py | 2 +- tb/test_axis_frame_length_adjust_64.v | 2 +- tb/test_axis_frame_length_adjust_8.py | 2 +- tb/test_axis_frame_length_adjust_8.v | 2 +- tb/test_axis_frame_length_adjust_fifo.py | 2 +- tb/test_axis_frame_length_adjust_fifo.v | 2 +- tb/test_axis_frame_length_adjust_fifo_64.py | 2 +- tb/test_axis_frame_length_adjust_fifo_64.v | 2 +- tb/test_axis_ll_bridge.py | 2 +- tb/test_axis_ll_bridge.v | 2 +- tb/test_axis_mux_4.py | 2 +- tb/test_axis_mux_4.v | 2 +- tb/test_axis_mux_64_4.py | 2 +- tb/test_axis_mux_64_4.v | 2 +- tb/test_axis_rate_limit.py | 2 +- tb/test_axis_rate_limit.v | 2 +- tb/test_axis_rate_limit_64.py | 2 +- tb/test_axis_rate_limit_64.v | 2 +- tb/test_axis_register.py | 2 +- tb/test_axis_register.v | 2 +- tb/test_axis_register_64.py | 2 +- tb/test_axis_register_64.v | 2 +- tb/test_axis_srl_fifo.py | 2 +- tb/test_axis_srl_fifo.v | 2 +- tb/test_axis_srl_fifo_64.py | 2 +- tb/test_axis_srl_fifo_64.v | 2 +- tb/test_axis_srl_register.py | 2 +- tb/test_axis_srl_register.v | 2 +- tb/test_axis_srl_register_64.py | 2 +- tb/test_axis_srl_register_64.v | 2 +- tb/test_axis_stat_counter.py | 2 +- tb/test_axis_stat_counter.v | 2 +- tb/test_axis_switch_4x4.py | 2 +- tb/test_axis_switch_4x4.v | 2 +- tb/test_axis_switch_64_4x4.py | 2 +- tb/test_axis_switch_64_4x4.v | 2 +- tb/test_axis_tap.py | 2 +- tb/test_axis_tap.v | 2 +- tb/test_axis_tap_64.py | 2 +- tb/test_axis_tap_64.v | 2 +- tb/test_ll_axis_bridge.py | 2 +- tb/test_ll_axis_bridge.v | 2 +- tb/test_priority_encoder.py | 2 +- tb/test_priority_encoder.v | 2 +- 142 files changed, 142 insertions(+), 142 deletions(-) diff --git a/COPYING b/COPYING index fd4ba4a32..288f3efb7 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/arbiter.v b/rtl/arbiter.v index d2b94f5b7..972218dde 100644 --- a/rtl/arbiter.v +++ b/rtl/arbiter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index bdc08c07f..a65951e3a 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index c93ca14c7..b8300a2f2 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_arb_mux_4.v b/rtl/axis_arb_mux_4.v index 6c9878356..4e6df5b9d 100644 --- a/rtl/axis_arb_mux_4.v +++ b/rtl/axis_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_arb_mux_64.py b/rtl/axis_arb_mux_64.py index 0f4500178..bb2bed92f 100755 --- a/rtl/axis_arb_mux_64.py +++ b/rtl/axis_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_arb_mux_64_4.v b/rtl/axis_arb_mux_64_4.v index b0cb5648a..ca8197d0c 100644 --- a/rtl/axis_arb_mux_64_4.v +++ b/rtl/axis_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 2b65377c2..be63cf37e 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v index dc06c403f..2c2e300e9 100644 --- a/rtl/axis_async_fifo_64.v +++ b/rtl/axis_async_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 884b41274..62fe41245 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v index 8e1747632..59c4fb898 100644 --- a/rtl/axis_async_frame_fifo_64.v +++ b/rtl/axis_async_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_cobs_decode.v b/rtl/axis_cobs_decode.v index b95639329..69dbe7927 100644 --- a/rtl/axis_cobs_decode.v +++ b/rtl/axis_cobs_decode.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/axis_cobs_encode.v b/rtl/axis_cobs_encode.v index 390e72a80..0aad5f8c8 100644 --- a/rtl/axis_cobs_encode.v +++ b/rtl/axis_cobs_encode.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index 260b23983..8236f739f 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -47,7 +47,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_crosspoint_4x4.v b/rtl/axis_crosspoint_4x4.v index d39c3f31b..03e897db1 100644 --- a/rtl/axis_crosspoint_4x4.v +++ b/rtl/axis_crosspoint_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py index 25d2acded..fdad13f94 100755 --- a/rtl/axis_crosspoint_64.py +++ b/rtl/axis_crosspoint_64.py @@ -47,7 +47,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_crosspoint_64_4x4.v b/rtl/axis_crosspoint_64_4x4.v index 489fa139b..a00c45ab8 100644 --- a/rtl/axis_crosspoint_64_4x4.v +++ b/rtl/axis_crosspoint_64_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index bd2e7c009..20e8b21f6 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v index a30ec133e..5373deeb6 100644 --- a/rtl/axis_demux_4.v +++ b/rtl/axis_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py index 774124d92..54eca9263 100755 --- a/rtl/axis_demux_64.py +++ b/rtl/axis_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_demux_64_4.v b/rtl/axis_demux_64_4.v index e4eb8d2d7..164d454cc 100644 --- a/rtl/axis_demux_64_4.v +++ b/rtl/axis_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index 93b137aba..e3b801625 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2013-2016 Alex Forencich +Copyright (c) 2013-2017 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 diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v index 03d3394bc..d82909f68 100644 --- a/rtl/axis_fifo_64.v +++ b/rtl/axis_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2013-2016 Alex Forencich +Copyright (c) 2013-2017 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 diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 606166a05..56e77a00d 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v index 5af317b5a..6533d18f0 100644 --- a/rtl/axis_frame_fifo_64.v +++ b/rtl/axis_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index b8567969e..fb8101ade 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index 1c9d87483..30ab9f4d6 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_frame_length_adjust.v b/rtl/axis_frame_length_adjust.v index 59c8d5f3f..f4735a5dc 100644 --- a/rtl/axis_frame_length_adjust.v +++ b/rtl/axis_frame_length_adjust.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/axis_frame_length_adjust_fifo.v b/rtl/axis_frame_length_adjust_fifo.v index 84cabffa2..3dc7cdec4 100644 --- a/rtl/axis_frame_length_adjust_fifo.v +++ b/rtl/axis_frame_length_adjust_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/axis_frame_length_adjust_fifo_64.v b/rtl/axis_frame_length_adjust_fifo_64.v index b5728c6b0..292322542 100644 --- a/rtl/axis_frame_length_adjust_fifo_64.v +++ b/rtl/axis_frame_length_adjust_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/axis_ll_bridge.v b/rtl/axis_ll_bridge.v index 4b1932e65..6f67892e9 100644 --- a/rtl/axis_ll_bridge.v +++ b/rtl/axis_ll_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 669618e9b..9120d8f3e 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v index 7ee57307e..1b2502f03 100644 --- a/rtl/axis_mux_4.v +++ b/rtl/axis_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py index ec985d81a..6173976a0 100755 --- a/rtl/axis_mux_64.py +++ b/rtl/axis_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_mux_64_4.v b/rtl/axis_mux_64_4.v index b0bcce2cb..b95e081e9 100644 --- a/rtl/axis_mux_64_4.v +++ b/rtl/axis_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index 937f4bd98..166235d33 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v index 6760cfbda..0b6240021 100644 --- a/rtl/axis_rate_limit_64.v +++ b/rtl/axis_rate_limit_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_register.v b/rtl/axis_register.v index 6fece11cc..33dc1b67b 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v index b12e82147..2fbd0dc0d 100644 --- a/rtl/axis_register_64.v +++ b/rtl/axis_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_srl_fifo.v b/rtl/axis_srl_fifo.v index 5f70a07e4..499b19625 100644 --- a/rtl/axis_srl_fifo.v +++ b/rtl/axis_srl_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_srl_fifo_64.v b/rtl/axis_srl_fifo_64.v index 75736aa42..28f0c9478 100644 --- a/rtl/axis_srl_fifo_64.v +++ b/rtl/axis_srl_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_srl_register.v b/rtl/axis_srl_register.v index d26ad74ee..745322ec5 100644 --- a/rtl/axis_srl_register.v +++ b/rtl/axis_srl_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_srl_register_64.v b/rtl/axis_srl_register_64.v index edf485110..c5b9349a4 100644 --- a/rtl/axis_srl_register_64.v +++ b/rtl/axis_srl_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index ba47770d0..43f5c8a62 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_switch.py b/rtl/axis_switch.py index c9ec7c3cf..26c838f74 100755 --- a/rtl/axis_switch.py +++ b/rtl/axis_switch.py @@ -48,7 +48,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/axis_switch_4x4.v b/rtl/axis_switch_4x4.v index bfca35997..06c49a310 100644 --- a/rtl/axis_switch_4x4.v +++ b/rtl/axis_switch_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/axis_switch_64.py b/rtl/axis_switch_64.py index dcd4c715d..8f98540b0 100755 --- a/rtl/axis_switch_64.py +++ b/rtl/axis_switch_64.py @@ -48,7 +48,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/axis_switch_64_4x4.v b/rtl/axis_switch_64_4x4.v index ea449bb2e..c83f79384 100644 --- a/rtl/axis_switch_64_4x4.v +++ b/rtl/axis_switch_64_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/axis_tap.v b/rtl/axis_tap.v index a881210c1..dc8b9e4b0 100644 --- a/rtl/axis_tap.v +++ b/rtl/axis_tap.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/axis_tap_64.v b/rtl/axis_tap_64.v index 0b8a1a21e..ce9d91d05 100644 --- a/rtl/axis_tap_64.v +++ b/rtl/axis_tap_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/ll_axis_bridge.v b/rtl/ll_axis_bridge.v index 9f572a5e5..2c5f326ec 100644 --- a/rtl/ll_axis_bridge.v +++ b/rtl/ll_axis_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/priority_encoder.v b/rtl/priority_encoder.v index 2d7faa5dd..50fbfa5ae 100644 --- a/rtl/priority_encoder.v +++ b/rtl/priority_encoder.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 947576752..78bb742c6 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/ll_ep.py b/tb/ll_ep.py index 943017c51..dc8f8808c 100644 --- a/tb/ll_ep.py +++ b/tb/ll_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arbiter.py b/tb/test_arbiter.py index 44fba8dce..0987be90e 100755 --- a/tb/test_arbiter.py +++ b/tb/test_arbiter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arbiter.v b/tb/test_arbiter.v index ce9481a2c..6ea120edb 100644 --- a/tb/test_arbiter.v +++ b/tb/test_arbiter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arbiter_rr.py b/tb/test_arbiter_rr.py index f6c739da3..e915e9d81 100755 --- a/tb/test_arbiter_rr.py +++ b/tb/test_arbiter_rr.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arbiter_rr.v b/tb/test_arbiter_rr.v index 31c8824e8..b6dde1ee0 100644 --- a/tb/test_arbiter_rr.v +++ b/tb/test_arbiter_rr.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index 3eb74aa51..06b764b8c 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_adapter_64_8.v b/tb/test_axis_adapter_64_8.v index 431fbbe33..acdf7a3c9 100644 --- a/tb/test_axis_adapter_64_8.v +++ b/tb/test_axis_adapter_64_8.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index 11f8e2c63..846278a02 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_adapter_8_64.v b/tb/test_axis_adapter_8_64.v index 0999520b1..910d87fd2 100644 --- a/tb/test_axis_adapter_8_64.v +++ b/tb/test_axis_adapter_8_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index 482614b6d..8a307fbb2 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_arb_mux_4.v b/tb/test_axis_arb_mux_4.v index 5319976fc..1c1774fc3 100644 --- a/tb/test_axis_arb_mux_4.v +++ b/tb/test_axis_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_arb_mux_64_4.py b/tb/test_axis_arb_mux_64_4.py index cbb020dd7..6d70511da 100755 --- a/tb/test_axis_arb_mux_64_4.py +++ b/tb/test_axis_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_arb_mux_64_4.v b/tb/test_axis_arb_mux_64_4.v index 1ae68d750..0480f3c31 100644 --- a/tb/test_axis_arb_mux_64_4.v +++ b/tb/test_axis_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index 97f2c93e7..d1ad35fb1 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_async_fifo.v b/tb/test_axis_async_fifo.v index cfd0aa00b..b1ad88a5a 100644 --- a/tb/test_axis_async_fifo.v +++ b/tb/test_axis_async_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index 8d4fbcf80..e43d63f50 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_async_fifo_64.v b/tb/test_axis_async_fifo_64.v index 672a2368d..da3114e01 100644 --- a/tb/test_axis_async_fifo_64.v +++ b/tb/test_axis_async_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index e69cd5335..84d4ff01f 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index e55e1ee21..f1d4d969a 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index 85cb45436..37c0bac76 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index 6337c5e3b..e68b68875 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py index 1adcac4a1..535400029 100755 --- a/tb/test_axis_cobs_decode.py +++ b/tb/test_axis_cobs_decode.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_axis_cobs_decode.v b/tb/test_axis_cobs_decode.v index a831cd712..2365ce437 100644 --- a/tb/test_axis_cobs_decode.v +++ b/tb/test_axis_cobs_decode.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py index 79ccd2006..ca376cab6 100755 --- a/tb/test_axis_cobs_encode.py +++ b/tb/test_axis_cobs_encode.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_axis_cobs_encode.v b/tb/test_axis_cobs_encode.v index 7aa47b5d4..750bf4e33 100644 --- a/tb/test_axis_cobs_encode.v +++ b/tb/test_axis_cobs_encode.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_axis_cobs_encode_zero_frame.py b/tb/test_axis_cobs_encode_zero_frame.py index b24df1131..ea1da943e 100755 --- a/tb/test_axis_cobs_encode_zero_frame.py +++ b/tb/test_axis_cobs_encode_zero_frame.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_axis_cobs_encode_zero_frame.v b/tb/test_axis_cobs_encode_zero_frame.v index bdb98bd55..7d4ebf664 100644 --- a/tb/test_axis_cobs_encode_zero_frame.v +++ b/tb/test_axis_cobs_encode_zero_frame.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_axis_crosspoint_4x4.py b/tb/test_axis_crosspoint_4x4.py index 753a2288b..a82f7073d 100755 --- a/tb/test_axis_crosspoint_4x4.py +++ b/tb/test_axis_crosspoint_4x4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_crosspoint_4x4.v b/tb/test_axis_crosspoint_4x4.v index 8d9e0dc19..89cc7d45b 100644 --- a/tb/test_axis_crosspoint_4x4.v +++ b/tb/test_axis_crosspoint_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_crosspoint_64_4x4.py b/tb/test_axis_crosspoint_64_4x4.py index 315c6a556..8ed4b2142 100755 --- a/tb/test_axis_crosspoint_64_4x4.py +++ b/tb/test_axis_crosspoint_64_4x4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_crosspoint_64_4x4.v b/tb/test_axis_crosspoint_64_4x4.v index 062aeb106..296f83725 100644 --- a/tb/test_axis_crosspoint_64_4x4.v +++ b/tb/test_axis_crosspoint_64_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py index 3e7f59563..239757853 100755 --- a/tb/test_axis_demux_4.py +++ b/tb/test_axis_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_demux_4.v b/tb/test_axis_demux_4.v index 65685c11b..4308a3f9a 100644 --- a/tb/test_axis_demux_4.v +++ b/tb/test_axis_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_demux_64_4.py b/tb/test_axis_demux_64_4.py index 716e7a303..054d142e2 100755 --- a/tb/test_axis_demux_64_4.py +++ b/tb/test_axis_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_demux_64_4.v b/tb/test_axis_demux_64_4.v index 8edd948c9..c57bb39f5 100644 --- a/tb/test_axis_demux_64_4.v +++ b/tb/test_axis_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index 54ba882d1..f4183f653 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_fifo.v b/tb/test_axis_fifo.v index 55dee8e62..b3b8c5932 100644 --- a/tb/test_axis_fifo.v +++ b/tb/test_axis_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index 97bcb22f9..d111fcfc0 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_fifo_64.v b/tb/test_axis_fifo_64.v index 01d8d162b..fd2264caf 100644 --- a/tb/test_axis_fifo_64.v +++ b/tb/test_axis_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index c9d7dd958..a519c467f 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v index 6f4866aa3..5736f2d64 100644 --- a/tb/test_axis_frame_fifo.v +++ b/tb/test_axis_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index bf35734f3..4dfc363bc 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v index 6fb8833c3..28c5c140e 100644 --- a/tb/test_axis_frame_fifo_64.v +++ b/tb/test_axis_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index 54b08a218..5290df47b 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_frame_join_4.v b/tb/test_axis_frame_join_4.v index b02e2f7c8..cb9b58270 100644 --- a/tb/test_axis_frame_join_4.v +++ b/tb/test_axis_frame_join_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_frame_length_adjust_64.py b/tb/test_axis_frame_length_adjust_64.py index 32ac0d342..34c7b0ed3 100755 --- a/tb/test_axis_frame_length_adjust_64.py +++ b/tb/test_axis_frame_length_adjust_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_frame_length_adjust_64.v b/tb/test_axis_frame_length_adjust_64.v index aa00751de..d1e1547fd 100644 --- a/tb/test_axis_frame_length_adjust_64.v +++ b/tb/test_axis_frame_length_adjust_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_frame_length_adjust_8.py b/tb/test_axis_frame_length_adjust_8.py index 4f60f4c06..d1fff3a30 100755 --- a/tb/test_axis_frame_length_adjust_8.py +++ b/tb/test_axis_frame_length_adjust_8.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_frame_length_adjust_8.v b/tb/test_axis_frame_length_adjust_8.v index 5e76e71e1..74c1c2072 100644 --- a/tb/test_axis_frame_length_adjust_8.v +++ b/tb/test_axis_frame_length_adjust_8.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_frame_length_adjust_fifo.py b/tb/test_axis_frame_length_adjust_fifo.py index a35c1c6fb..ed1fffaa6 100755 --- a/tb/test_axis_frame_length_adjust_fifo.py +++ b/tb/test_axis_frame_length_adjust_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_frame_length_adjust_fifo.v b/tb/test_axis_frame_length_adjust_fifo.v index c2d41764a..09817022e 100644 --- a/tb/test_axis_frame_length_adjust_fifo.v +++ b/tb/test_axis_frame_length_adjust_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_frame_length_adjust_fifo_64.py b/tb/test_axis_frame_length_adjust_fifo_64.py index 17473dc37..fc335227c 100755 --- a/tb/test_axis_frame_length_adjust_fifo_64.py +++ b/tb/test_axis_frame_length_adjust_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_frame_length_adjust_fifo_64.v b/tb/test_axis_frame_length_adjust_fifo_64.v index ac2031e6e..d8b105511 100644 --- a/tb/test_axis_frame_length_adjust_fifo_64.v +++ b/tb/test_axis_frame_length_adjust_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_ll_bridge.py b/tb/test_axis_ll_bridge.py index 07012bc9a..b63a8dcbc 100755 --- a/tb/test_axis_ll_bridge.py +++ b/tb/test_axis_ll_bridge.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_ll_bridge.v b/tb/test_axis_ll_bridge.v index c9922870a..b2aa98ea2 100644 --- a/tb/test_axis_ll_bridge.v +++ b/tb/test_axis_ll_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py index 269b924f6..4ec6a3f84 100755 --- a/tb/test_axis_mux_4.py +++ b/tb/test_axis_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_mux_4.v b/tb/test_axis_mux_4.v index ec8bc599d..fa20b519e 100644 --- a/tb/test_axis_mux_4.v +++ b/tb/test_axis_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_mux_64_4.py b/tb/test_axis_mux_64_4.py index 6946f2d08..861413469 100755 --- a/tb/test_axis_mux_64_4.py +++ b/tb/test_axis_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_mux_64_4.v b/tb/test_axis_mux_64_4.v index 1ae4bb440..b513db2b8 100644 --- a/tb/test_axis_mux_64_4.v +++ b/tb/test_axis_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index f71b61fba..c8e070450 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_rate_limit.v b/tb/test_axis_rate_limit.v index fcab5cca6..06e88e3ae 100644 --- a/tb/test_axis_rate_limit.v +++ b/tb/test_axis_rate_limit.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index 554fa8bcb..8d5349bc7 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_rate_limit_64.v b/tb/test_axis_rate_limit_64.v index 21392eefd..ce8afc1dc 100644 --- a/tb/test_axis_rate_limit_64.v +++ b/tb/test_axis_rate_limit_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py index a53e3aede..69f3cf2ee 100755 --- a/tb/test_axis_register.py +++ b/tb/test_axis_register.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_register.v b/tb/test_axis_register.v index 82c9a8207..b35a2da6e 100644 --- a/tb/test_axis_register.v +++ b/tb/test_axis_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py index b6b3827d4..aa8933daf 100755 --- a/tb/test_axis_register_64.py +++ b/tb/test_axis_register_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_register_64.v b/tb/test_axis_register_64.v index 069126f4e..0453828de 100644 --- a/tb/test_axis_register_64.v +++ b/tb/test_axis_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py index 7d2773c27..60a239fad 100755 --- a/tb/test_axis_srl_fifo.py +++ b/tb/test_axis_srl_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_srl_fifo.v b/tb/test_axis_srl_fifo.v index 345859347..1721e5d5a 100644 --- a/tb/test_axis_srl_fifo.v +++ b/tb/test_axis_srl_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py index 5a44897c6..eba2b7308 100755 --- a/tb/test_axis_srl_fifo_64.py +++ b/tb/test_axis_srl_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_srl_fifo_64.v b/tb/test_axis_srl_fifo_64.v index ba83f3ea7..be6b8ed0c 100644 --- a/tb/test_axis_srl_fifo_64.v +++ b/tb/test_axis_srl_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_srl_register.py b/tb/test_axis_srl_register.py index ddd1c455c..7ee80615f 100755 --- a/tb/test_axis_srl_register.py +++ b/tb/test_axis_srl_register.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_srl_register.v b/tb/test_axis_srl_register.v index 706a90d29..eac2b6d99 100644 --- a/tb/test_axis_srl_register.v +++ b/tb/test_axis_srl_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_srl_register_64.py b/tb/test_axis_srl_register_64.py index 0a3d8c24b..6aa0485c1 100755 --- a/tb/test_axis_srl_register_64.py +++ b/tb/test_axis_srl_register_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_srl_register_64.v b/tb/test_axis_srl_register_64.v index 6e5437084..8450e8cde 100644 --- a/tb/test_axis_srl_register_64.v +++ b/tb/test_axis_srl_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index 950eb263f..6f0d5517b 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v index d2be74b84..d4b2336ce 100644 --- a/tb/test_axis_stat_counter.v +++ b/tb/test_axis_stat_counter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py index dbd0637ef..98c8054fe 100755 --- a/tb/test_axis_switch_4x4.py +++ b/tb/test_axis_switch_4x4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_axis_switch_4x4.v b/tb/test_axis_switch_4x4.v index 8c1782137..773d4087f 100644 --- a/tb/test_axis_switch_4x4.v +++ b/tb/test_axis_switch_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_axis_switch_64_4x4.py b/tb/test_axis_switch_64_4x4.py index 4185f122e..c6e230049 100755 --- a/tb/test_axis_switch_64_4x4.py +++ b/tb/test_axis_switch_64_4x4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_axis_switch_64_4x4.v b/tb/test_axis_switch_64_4x4.v index 989ef788a..b3a10a486 100644 --- a/tb/test_axis_switch_64_4x4.v +++ b/tb/test_axis_switch_64_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_axis_tap.py b/tb/test_axis_tap.py index cab8d680c..79b9e97d9 100755 --- a/tb/test_axis_tap.py +++ b/tb/test_axis_tap.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_tap.v b/tb/test_axis_tap.v index 532fafefc..11f2d9a3f 100644 --- a/tb/test_axis_tap.v +++ b/tb/test_axis_tap.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_tap_64.py b/tb/test_axis_tap_64.py index f05002a1c..bec9f9ba1 100755 --- a/tb/test_axis_tap_64.py +++ b/tb/test_axis_tap_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_tap_64.v b/tb/test_axis_tap_64.v index c40834e10..e56b053c8 100644 --- a/tb/test_axis_tap_64.v +++ b/tb/test_axis_tap_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_ll_axis_bridge.py b/tb/test_ll_axis_bridge.py index c2099b79c..aa3065267 100755 --- a/tb/test_ll_axis_bridge.py +++ b/tb/test_ll_axis_bridge.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ll_axis_bridge.v b/tb/test_ll_axis_bridge.v index 9e95975dd..049a2a6db 100644 --- a/tb/test_ll_axis_bridge.v +++ b/tb/test_ll_axis_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_priority_encoder.py b/tb/test_priority_encoder.py index db686642f..5152dea8a 100755 --- a/tb/test_priority_encoder.py +++ b/tb/test_priority_encoder.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_priority_encoder.v b/tb/test_priority_encoder.v index 8d6787e8a..ef0288461 100644 --- a/tb/test_priority_encoder.v +++ b/tb/test_priority_encoder.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 From 3b0cfbbfed05aed0053650350ffcfe697feda43d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 18 May 2017 13:35:42 -0700 Subject: [PATCH 322/617] Use extend instead of for loop --- tb/test_axis_cobs_decode.py | 5 ++--- tb/test_axis_cobs_encode.py | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py index 535400029..fe4c5b484 100755 --- a/tb/test_axis_cobs_decode.py +++ b/tb/test_axis_cobs_decode.py @@ -90,9 +90,8 @@ def cobs_decode(block): i += 1 if i+code-1 > len(block): return None - for k in range(code-1): - dec.append(block[i]) - i += 1 + dec.extend(block[i:i+code-1]) + i += code-1 if code < 255 and i < len(block): dec.append(0) diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py index ca376cab6..f3892f89b 100755 --- a/tb/test_axis_cobs_encode.py +++ b/tb/test_axis_cobs_encode.py @@ -91,9 +91,8 @@ def cobs_decode(block): i += 1 if i+code-1 > len(block): return None - for k in range(code-1): - dec.append(block[i]) - i += 1 + dec.extend(block[i:i+code-1]) + i += code-1 if code < 255 and i < len(block): dec.append(0) From 9b2ac9dfc18aeda71ee2699409b127abf782aedf Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 18 May 2017 13:47:45 -0700 Subject: [PATCH 323/617] Happy new year --- COPYING | 2 +- example/ATLYS/fpga/rtl/debounce_switch.v | 2 +- example/ATLYS/fpga/rtl/fpga.v | 2 +- example/ATLYS/fpga/rtl/fpga_core.v | 2 +- example/ATLYS/fpga/rtl/sync_reset.v | 2 +- example/ATLYS/fpga/rtl/sync_signal.v | 2 +- example/ATLYS/fpga/tb/test_fpga_core.py | 2 +- example/ATLYS/fpga/tb/test_fpga_core.v | 2 +- example/DE5-Net/fpga/rtl/debounce_switch.v | 2 +- example/DE5-Net/fpga/rtl/fpga.v | 2 +- example/DE5-Net/fpga/rtl/fpga_core.v | 2 +- example/DE5-Net/fpga/rtl/i2c_master.v | 2 +- example/DE5-Net/fpga/rtl/si570_i2c_init.v | 2 +- example/DE5-Net/fpga/rtl/sync_reset.v | 2 +- example/DE5-Net/fpga/rtl/sync_signal.v | 2 +- example/DE5-Net/fpga/tb/test_fpga_core.py | 2 +- example/DE5-Net/fpga/tb/test_fpga_core.v | 2 +- example/HXT100G/fpga/rtl/debounce_switch.v | 2 +- example/HXT100G/fpga/rtl/eth_gth_phy_quad.v | 2 +- example/HXT100G/fpga/rtl/fpga.v | 2 +- example/HXT100G/fpga/rtl/fpga_core.v | 2 +- example/HXT100G/fpga/rtl/gth_i2c_init.v | 2 +- example/HXT100G/fpga/rtl/i2c_master.v | 2 +- example/HXT100G/fpga/rtl/sync_reset.v | 2 +- example/HXT100G/fpga/rtl/sync_signal.v | 2 +- example/HXT100G/fpga/tb/test_fpga_core.py | 2 +- example/HXT100G/fpga/tb/test_fpga_core.v | 2 +- example/NexysVideo/fpga/rtl/debounce_switch.v | 2 +- example/NexysVideo/fpga/rtl/fpga.v | 2 +- example/NexysVideo/fpga/rtl/fpga_core.v | 2 +- example/NexysVideo/fpga/rtl/sync_reset.v | 2 +- example/NexysVideo/fpga/rtl/sync_signal.v | 2 +- example/NexysVideo/fpga/tb/test_fpga_core.py | 2 +- example/NexysVideo/fpga/tb/test_fpga_core.v | 2 +- example/VCU108/fpga_10g/rtl/debounce_switch.v | 2 +- example/VCU108/fpga_10g/rtl/fpga.v | 2 +- example/VCU108/fpga_10g/rtl/fpga_core.v | 2 +- example/VCU108/fpga_10g/rtl/i2c_master.v | 2 +- example/VCU108/fpga_10g/rtl/si570_i2c_init.v | 2 +- example/VCU108/fpga_10g/rtl/sync_reset.v | 2 +- example/VCU108/fpga_10g/rtl/sync_signal.v | 2 +- example/VCU108/fpga_10g/tb/test_fpga_core.py | 2 +- example/VCU108/fpga_10g/tb/test_fpga_core.v | 2 +- example/VCU108/fpga_1g/rtl/debounce_switch.v | 2 +- example/VCU108/fpga_1g/rtl/fpga.v | 2 +- example/VCU108/fpga_1g/rtl/fpga_core.v | 2 +- example/VCU108/fpga_1g/rtl/sync_reset.v | 2 +- example/VCU108/fpga_1g/rtl/sync_signal.v | 2 +- example/VCU108/fpga_1g/tb/test_fpga_core.py | 2 +- example/VCU108/fpga_1g/tb/test_fpga_core.v | 2 +- rtl/arp.v | 2 +- rtl/arp_64.v | 2 +- rtl/arp_cache.v | 2 +- rtl/arp_eth_rx.v | 2 +- rtl/arp_eth_rx_64.v | 2 +- rtl/arp_eth_tx.v | 2 +- rtl/arp_eth_tx_64.v | 2 +- rtl/axis_eth_fcs.v | 2 +- rtl/axis_eth_fcs_64.v | 2 +- rtl/axis_eth_fcs_check.v | 2 +- rtl/axis_eth_fcs_check_64.v | 2 +- rtl/axis_eth_fcs_insert.v | 2 +- rtl/axis_eth_fcs_insert_64.v | 2 +- rtl/eth_arb_mux.py | 2 +- rtl/eth_arb_mux_2.v | 2 +- rtl/eth_arb_mux_4.v | 2 +- rtl/eth_arb_mux_64.py | 2 +- rtl/eth_arb_mux_64_2.v | 2 +- rtl/eth_arb_mux_64_4.v | 2 +- rtl/eth_axis_rx.v | 2 +- rtl/eth_axis_rx_64.v | 2 +- rtl/eth_axis_tx.v | 2 +- rtl/eth_axis_tx_64.v | 2 +- rtl/eth_demux.py | 2 +- rtl/eth_demux_4.v | 2 +- rtl/eth_demux_64.py | 2 +- rtl/eth_demux_64_4.v | 2 +- rtl/eth_mac_10g.v | 2 +- rtl/eth_mac_10g_fifo.v | 2 +- rtl/eth_mac_10g_rx.v | 2 +- rtl/eth_mac_10g_tx.v | 2 +- rtl/eth_mac_1g.v | 2 +- rtl/eth_mac_1g_fifo.v | 2 +- rtl/eth_mac_1g_rx.v | 2 +- rtl/eth_mac_1g_tx.v | 2 +- rtl/eth_mux.py | 2 +- rtl/eth_mux_2.v | 2 +- rtl/eth_mux_4.v | 2 +- rtl/eth_mux_64.py | 2 +- rtl/eth_mux_64_2.v | 2 +- rtl/eth_mux_64_4.v | 2 +- rtl/gmii_phy_if.v | 2 +- rtl/iddr.v | 2 +- rtl/ip.v | 2 +- rtl/ip_64.v | 2 +- rtl/ip_arb_mux.py | 2 +- rtl/ip_arb_mux_2.v | 2 +- rtl/ip_arb_mux_4.v | 2 +- rtl/ip_arb_mux_64.py | 2 +- rtl/ip_arb_mux_64_2.v | 2 +- rtl/ip_arb_mux_64_4.v | 2 +- rtl/ip_complete.v | 2 +- rtl/ip_complete_64.v | 2 +- rtl/ip_demux.py | 2 +- rtl/ip_demux_4.v | 2 +- rtl/ip_demux_64.py | 2 +- rtl/ip_demux_64_4.v | 2 +- rtl/ip_eth_rx.v | 2 +- rtl/ip_eth_rx_64.v | 2 +- rtl/ip_eth_tx.v | 2 +- rtl/ip_eth_tx_64.v | 2 +- rtl/ip_mux.py | 2 +- rtl/ip_mux_2.v | 2 +- rtl/ip_mux_4.v | 2 +- rtl/ip_mux_64.py | 2 +- rtl/ip_mux_64_2.v | 2 +- rtl/ip_mux_64_4.v | 2 +- rtl/lfsr.v | 2 +- rtl/oddr.v | 2 +- rtl/rgmii_phy_if.v | 2 +- rtl/ssio_ddr_in.v | 2 +- rtl/ssio_ddr_in_diff.v | 2 +- rtl/ssio_ddr_out.v | 2 +- rtl/ssio_ddr_out_diff.v | 2 +- rtl/ssio_sdr_in.v | 2 +- rtl/ssio_sdr_in_diff.v | 2 +- rtl/ssio_sdr_out.v | 2 +- rtl/ssio_sdr_out_diff.v | 2 +- rtl/udp.v | 2 +- rtl/udp_64.v | 2 +- rtl/udp_arb_mux.py | 2 +- rtl/udp_arb_mux_4.v | 2 +- rtl/udp_arb_mux_64.py | 2 +- rtl/udp_arb_mux_64_4.v | 2 +- rtl/udp_checksum_gen.v | 2 +- rtl/udp_checksum_gen_64.v | 2 +- rtl/udp_complete.v | 2 +- rtl/udp_complete_64.v | 2 +- rtl/udp_demux.py | 2 +- rtl/udp_demux_4.v | 2 +- rtl/udp_demux_64.py | 2 +- rtl/udp_demux_64_4.v | 2 +- rtl/udp_ip_rx.v | 2 +- rtl/udp_ip_rx_64.v | 2 +- rtl/udp_ip_tx.v | 2 +- rtl/udp_ip_tx_64.v | 2 +- rtl/udp_mux.py | 2 +- rtl/udp_mux_4.v | 2 +- rtl/udp_mux_64.py | 2 +- rtl/udp_mux_64_4.v | 2 +- rtl/xgmii_deinterleave.v | 2 +- rtl/xgmii_interleave.v | 2 +- tb/arp_ep.py | 2 +- tb/eth_ep.py | 2 +- tb/gmii_ep.py | 2 +- tb/ip_ep.py | 2 +- tb/rgmii_ep.py | 2 +- tb/test_arp.py | 2 +- tb/test_arp.v | 2 +- tb/test_arp_64.py | 2 +- tb/test_arp_64.v | 2 +- tb/test_arp_cache.py | 2 +- tb/test_arp_cache.v | 2 +- tb/test_arp_eth_rx.py | 2 +- tb/test_arp_eth_rx.v | 2 +- tb/test_arp_eth_rx_64.py | 2 +- tb/test_arp_eth_rx_64.v | 2 +- tb/test_arp_eth_tx.py | 2 +- tb/test_arp_eth_tx.v | 2 +- tb/test_arp_eth_tx_64.py | 2 +- tb/test_arp_eth_tx_64.v | 2 +- tb/test_axis_eth_fcs.py | 2 +- tb/test_axis_eth_fcs.v | 2 +- tb/test_axis_eth_fcs_64.py | 2 +- tb/test_axis_eth_fcs_64.v | 2 +- tb/test_axis_eth_fcs_check.py | 2 +- tb/test_axis_eth_fcs_check.v | 2 +- tb/test_axis_eth_fcs_check_64.py | 2 +- tb/test_axis_eth_fcs_check_64.v | 2 +- tb/test_axis_eth_fcs_insert.py | 2 +- tb/test_axis_eth_fcs_insert.v | 2 +- tb/test_axis_eth_fcs_insert_64.py | 2 +- tb/test_axis_eth_fcs_insert_64.v | 2 +- tb/test_axis_eth_fcs_insert_64_pad.py | 2 +- tb/test_axis_eth_fcs_insert_64_pad.v | 2 +- tb/test_axis_eth_fcs_insert_pad.py | 2 +- tb/test_axis_eth_fcs_insert_pad.v | 2 +- tb/test_eth_arb_mux_4.py | 2 +- tb/test_eth_arb_mux_4.v | 2 +- tb/test_eth_arb_mux_64_4.py | 2 +- tb/test_eth_arb_mux_64_4.v | 2 +- tb/test_eth_axis_rx.py | 2 +- tb/test_eth_axis_rx.v | 2 +- tb/test_eth_axis_rx_64.py | 2 +- tb/test_eth_axis_rx_64.v | 2 +- tb/test_eth_axis_tx.py | 2 +- tb/test_eth_axis_tx.v | 2 +- tb/test_eth_axis_tx_64.py | 2 +- tb/test_eth_axis_tx_64.v | 2 +- tb/test_eth_demux_4.py | 2 +- tb/test_eth_demux_4.v | 2 +- tb/test_eth_demux_64_4.py | 2 +- tb/test_eth_demux_64_4.v | 2 +- tb/test_eth_mac_10g.py | 2 +- tb/test_eth_mac_10g.v | 2 +- tb/test_eth_mac_10g_fifo.py | 2 +- tb/test_eth_mac_10g_fifo.v | 2 +- tb/test_eth_mac_10g_rx.py | 2 +- tb/test_eth_mac_10g_rx.v | 2 +- tb/test_eth_mac_10g_tx.py | 2 +- tb/test_eth_mac_10g_tx.v | 2 +- tb/test_eth_mac_1g.py | 2 +- tb/test_eth_mac_1g.v | 2 +- tb/test_eth_mac_1g_fifo.py | 2 +- tb/test_eth_mac_1g_fifo.v | 2 +- tb/test_eth_mac_1g_rx.py | 2 +- tb/test_eth_mac_1g_rx.v | 2 +- tb/test_eth_mac_1g_tx.py | 2 +- tb/test_eth_mac_1g_tx.v | 2 +- tb/test_eth_mux_4.py | 2 +- tb/test_eth_mux_4.v | 2 +- tb/test_eth_mux_64_4.py | 2 +- tb/test_eth_mux_64_4.v | 2 +- tb/test_ip.py | 2 +- tb/test_ip.v | 2 +- tb/test_ip_64.py | 2 +- tb/test_ip_64.v | 2 +- tb/test_ip_arb_mux_4.py | 2 +- tb/test_ip_arb_mux_4.v | 2 +- tb/test_ip_arb_mux_64_4.py | 2 +- tb/test_ip_arb_mux_64_4.v | 2 +- tb/test_ip_complete.py | 2 +- tb/test_ip_complete.v | 2 +- tb/test_ip_complete_64.py | 2 +- tb/test_ip_complete_64.v | 2 +- tb/test_ip_demux_4.py | 2 +- tb/test_ip_demux_4.v | 2 +- tb/test_ip_demux_64_4.py | 2 +- tb/test_ip_demux_64_4.v | 2 +- tb/test_ip_eth_rx.py | 2 +- tb/test_ip_eth_rx.v | 2 +- tb/test_ip_eth_rx_64.py | 2 +- tb/test_ip_eth_rx_64.v | 2 +- tb/test_ip_eth_tx.py | 2 +- tb/test_ip_eth_tx.v | 2 +- tb/test_ip_eth_tx_64.py | 2 +- tb/test_ip_eth_tx_64.v | 2 +- tb/test_ip_mux_4.py | 2 +- tb/test_ip_mux_4.v | 2 +- tb/test_ip_mux_64_4.py | 2 +- tb/test_ip_mux_64_4.v | 2 +- tb/test_udp.py | 2 +- tb/test_udp.v | 2 +- tb/test_udp_64.py | 2 +- tb/test_udp_64.v | 2 +- tb/test_udp_arb_mux_4.py | 2 +- tb/test_udp_arb_mux_4.v | 2 +- tb/test_udp_arb_mux_64_4.py | 2 +- tb/test_udp_arb_mux_64_4.v | 2 +- tb/test_udp_checksum_gen.py | 2 +- tb/test_udp_checksum_gen.v | 2 +- tb/test_udp_checksum_gen_64.py | 2 +- tb/test_udp_checksum_gen_64.v | 2 +- tb/test_udp_complete.py | 2 +- tb/test_udp_complete.v | 2 +- tb/test_udp_complete_64.py | 2 +- tb/test_udp_complete_64.v | 2 +- tb/test_udp_demux_4.py | 2 +- tb/test_udp_demux_4.v | 2 +- tb/test_udp_demux_64_4.py | 2 +- tb/test_udp_demux_64_4.v | 2 +- tb/test_udp_ip_rx.py | 2 +- tb/test_udp_ip_rx.v | 2 +- tb/test_udp_ip_rx_64.py | 2 +- tb/test_udp_ip_rx_64.v | 2 +- tb/test_udp_ip_tx.py | 2 +- tb/test_udp_ip_tx.v | 2 +- tb/test_udp_ip_tx_64.py | 2 +- tb/test_udp_ip_tx_64.v | 2 +- tb/test_udp_mux_4.py | 2 +- tb/test_udp_mux_4.v | 2 +- tb/test_udp_mux_64_4.py | 2 +- tb/test_udp_mux_64_4.v | 2 +- tb/udp_ep.py | 2 +- tb/xgmii_ep.py | 2 +- 285 files changed, 285 insertions(+), 285 deletions(-) diff --git a/COPYING b/COPYING index fd4ba4a32..288f3efb7 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/ATLYS/fpga/rtl/debounce_switch.v b/example/ATLYS/fpga/rtl/debounce_switch.v index 3e2dc20a5..ab84126ec 100644 --- a/example/ATLYS/fpga/rtl/debounce_switch.v +++ b/example/ATLYS/fpga/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/ATLYS/fpga/rtl/fpga.v b/example/ATLYS/fpga/rtl/fpga.v index 46bb17ae4..8ea58703a 100644 --- a/example/ATLYS/fpga/rtl/fpga.v +++ b/example/ATLYS/fpga/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index 767a3ca82..9b22dbf47 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/ATLYS/fpga/rtl/sync_reset.v b/example/ATLYS/fpga/rtl/sync_reset.v index ddd99febe..558a67605 100644 --- a/example/ATLYS/fpga/rtl/sync_reset.v +++ b/example/ATLYS/fpga/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/ATLYS/fpga/rtl/sync_signal.v b/example/ATLYS/fpga/rtl/sync_signal.v index 5afcd7170..1b8a32328 100644 --- a/example/ATLYS/fpga/rtl/sync_signal.v +++ b/example/ATLYS/fpga/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index a1943afb5..1785ffb79 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/ATLYS/fpga/tb/test_fpga_core.v b/example/ATLYS/fpga/tb/test_fpga_core.v index eaf111369..ada2a57a9 100644 --- a/example/ATLYS/fpga/tb/test_fpga_core.v +++ b/example/ATLYS/fpga/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/DE5-Net/fpga/rtl/debounce_switch.v b/example/DE5-Net/fpga/rtl/debounce_switch.v index 3e2dc20a5..ab84126ec 100644 --- a/example/DE5-Net/fpga/rtl/debounce_switch.v +++ b/example/DE5-Net/fpga/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/DE5-Net/fpga/rtl/fpga.v b/example/DE5-Net/fpga/rtl/fpga.v index 9190e44c6..4b142a083 100644 --- a/example/DE5-Net/fpga/rtl/fpga.v +++ b/example/DE5-Net/fpga/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index 5b01704ca..8888af3d8 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/example/DE5-Net/fpga/rtl/i2c_master.v b/example/DE5-Net/fpga/rtl/i2c_master.v index 4a6b945c1..61a313ddb 100644 --- a/example/DE5-Net/fpga/rtl/i2c_master.v +++ b/example/DE5-Net/fpga/rtl/i2c_master.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/DE5-Net/fpga/rtl/si570_i2c_init.v b/example/DE5-Net/fpga/rtl/si570_i2c_init.v index 8c0130a89..03104f4d2 100644 --- a/example/DE5-Net/fpga/rtl/si570_i2c_init.v +++ b/example/DE5-Net/fpga/rtl/si570_i2c_init.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/DE5-Net/fpga/rtl/sync_reset.v b/example/DE5-Net/fpga/rtl/sync_reset.v index ddd99febe..558a67605 100644 --- a/example/DE5-Net/fpga/rtl/sync_reset.v +++ b/example/DE5-Net/fpga/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/DE5-Net/fpga/rtl/sync_signal.v b/example/DE5-Net/fpga/rtl/sync_signal.v index 5afcd7170..1b8a32328 100644 --- a/example/DE5-Net/fpga/rtl/sync_signal.v +++ b/example/DE5-Net/fpga/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index 757e99d9c..978de24fe 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.v b/example/DE5-Net/fpga/tb/test_fpga_core.v index bcdead8fa..69b0f55c5 100644 --- a/example/DE5-Net/fpga/tb/test_fpga_core.v +++ b/example/DE5-Net/fpga/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/example/HXT100G/fpga/rtl/debounce_switch.v b/example/HXT100G/fpga/rtl/debounce_switch.v index e820eb416..245f1abea 100644 --- a/example/HXT100G/fpga/rtl/debounce_switch.v +++ b/example/HXT100G/fpga/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v b/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v index fbf134ba5..375640ac4 100644 --- a/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v +++ b/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/HXT100G/fpga/rtl/fpga.v b/example/HXT100G/fpga/rtl/fpga.v index 159608c83..3048b11d1 100644 --- a/example/HXT100G/fpga/rtl/fpga.v +++ b/example/HXT100G/fpga/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v index ee8829cdc..64b36d8b9 100644 --- a/example/HXT100G/fpga/rtl/fpga_core.v +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/example/HXT100G/fpga/rtl/gth_i2c_init.v b/example/HXT100G/fpga/rtl/gth_i2c_init.v index c92e2136c..95864817f 100644 --- a/example/HXT100G/fpga/rtl/gth_i2c_init.v +++ b/example/HXT100G/fpga/rtl/gth_i2c_init.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/HXT100G/fpga/rtl/i2c_master.v b/example/HXT100G/fpga/rtl/i2c_master.v index 4a6b945c1..61a313ddb 100644 --- a/example/HXT100G/fpga/rtl/i2c_master.v +++ b/example/HXT100G/fpga/rtl/i2c_master.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/HXT100G/fpga/rtl/sync_reset.v b/example/HXT100G/fpga/rtl/sync_reset.v index d74c0337e..20622fd64 100644 --- a/example/HXT100G/fpga/rtl/sync_reset.v +++ b/example/HXT100G/fpga/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/HXT100G/fpga/rtl/sync_signal.v b/example/HXT100G/fpga/rtl/sync_signal.v index 5afcd7170..1b8a32328 100644 --- a/example/HXT100G/fpga/rtl/sync_signal.v +++ b/example/HXT100G/fpga/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index 92721aca7..8df1f78e3 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/example/HXT100G/fpga/tb/test_fpga_core.v b/example/HXT100G/fpga/tb/test_fpga_core.v index 62a146cf5..7bfc8cc62 100644 --- a/example/HXT100G/fpga/tb/test_fpga_core.v +++ b/example/HXT100G/fpga/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/example/NexysVideo/fpga/rtl/debounce_switch.v b/example/NexysVideo/fpga/rtl/debounce_switch.v index 3e2dc20a5..ab84126ec 100644 --- a/example/NexysVideo/fpga/rtl/debounce_switch.v +++ b/example/NexysVideo/fpga/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/NexysVideo/fpga/rtl/fpga.v b/example/NexysVideo/fpga/rtl/fpga.v index ba18ea96e..82dca776a 100644 --- a/example/NexysVideo/fpga/rtl/fpga.v +++ b/example/NexysVideo/fpga/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/NexysVideo/fpga/rtl/fpga_core.v b/example/NexysVideo/fpga/rtl/fpga_core.v index c3de34541..15586bc2e 100644 --- a/example/NexysVideo/fpga/rtl/fpga_core.v +++ b/example/NexysVideo/fpga/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/NexysVideo/fpga/rtl/sync_reset.v b/example/NexysVideo/fpga/rtl/sync_reset.v index ddd99febe..558a67605 100644 --- a/example/NexysVideo/fpga/rtl/sync_reset.v +++ b/example/NexysVideo/fpga/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/NexysVideo/fpga/rtl/sync_signal.v b/example/NexysVideo/fpga/rtl/sync_signal.v index 5afcd7170..1b8a32328 100644 --- a/example/NexysVideo/fpga/rtl/sync_signal.v +++ b/example/NexysVideo/fpga/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.py b/example/NexysVideo/fpga/tb/test_fpga_core.py index 38fbe803f..738858a62 100755 --- a/example/NexysVideo/fpga/tb/test_fpga_core.py +++ b/example/NexysVideo/fpga/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.v b/example/NexysVideo/fpga/tb/test_fpga_core.v index 984184f0b..bb93be3aa 100644 --- a/example/NexysVideo/fpga/tb/test_fpga_core.v +++ b/example/NexysVideo/fpga/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/VCU108/fpga_10g/rtl/debounce_switch.v b/example/VCU108/fpga_10g/rtl/debounce_switch.v index 3e2dc20a5..ab84126ec 100644 --- a/example/VCU108/fpga_10g/rtl/debounce_switch.v +++ b/example/VCU108/fpga_10g/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/VCU108/fpga_10g/rtl/fpga.v b/example/VCU108/fpga_10g/rtl/fpga.v index 02eac4779..8537dd5e0 100644 --- a/example/VCU108/fpga_10g/rtl/fpga.v +++ b/example/VCU108/fpga_10g/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index 70dc4b99b..ddbcb2029 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/VCU108/fpga_10g/rtl/i2c_master.v b/example/VCU108/fpga_10g/rtl/i2c_master.v index 4a6b945c1..61a313ddb 100644 --- a/example/VCU108/fpga_10g/rtl/i2c_master.v +++ b/example/VCU108/fpga_10g/rtl/i2c_master.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/VCU108/fpga_10g/rtl/si570_i2c_init.v b/example/VCU108/fpga_10g/rtl/si570_i2c_init.v index afa5b6121..8a852a4ec 100644 --- a/example/VCU108/fpga_10g/rtl/si570_i2c_init.v +++ b/example/VCU108/fpga_10g/rtl/si570_i2c_init.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/VCU108/fpga_10g/rtl/sync_reset.v b/example/VCU108/fpga_10g/rtl/sync_reset.v index ddd99febe..558a67605 100644 --- a/example/VCU108/fpga_10g/rtl/sync_reset.v +++ b/example/VCU108/fpga_10g/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/VCU108/fpga_10g/rtl/sync_signal.v b/example/VCU108/fpga_10g/rtl/sync_signal.v index 5afcd7170..1b8a32328 100644 --- a/example/VCU108/fpga_10g/rtl/sync_signal.v +++ b/example/VCU108/fpga_10g/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index 009ef6699..5641d0935 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.v b/example/VCU108/fpga_10g/tb/test_fpga_core.v index 0f46108df..38c74c6b1 100644 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/example/VCU108/fpga_1g/rtl/debounce_switch.v b/example/VCU108/fpga_1g/rtl/debounce_switch.v index 3e2dc20a5..ab84126ec 100644 --- a/example/VCU108/fpga_1g/rtl/debounce_switch.v +++ b/example/VCU108/fpga_1g/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/VCU108/fpga_1g/rtl/fpga.v b/example/VCU108/fpga_1g/rtl/fpga.v index 044ad3dde..3d60177f7 100644 --- a/example/VCU108/fpga_1g/rtl/fpga.v +++ b/example/VCU108/fpga_1g/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v index 6a7e6eec7..3798867f6 100644 --- a/example/VCU108/fpga_1g/rtl/fpga_core.v +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/VCU108/fpga_1g/rtl/sync_reset.v b/example/VCU108/fpga_1g/rtl/sync_reset.v index ddd99febe..558a67605 100644 --- a/example/VCU108/fpga_1g/rtl/sync_reset.v +++ b/example/VCU108/fpga_1g/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/VCU108/fpga_1g/rtl/sync_signal.v b/example/VCU108/fpga_1g/rtl/sync_signal.v index 5afcd7170..1b8a32328 100644 --- a/example/VCU108/fpga_1g/rtl/sync_signal.v +++ b/example/VCU108/fpga_1g/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py index 6e232e234..a4d3147e4 100755 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.v b/example/VCU108/fpga_1g/tb/test_fpga_core.v index e3a75d19e..6d61842df 100644 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/arp.v b/rtl/arp.v index 189a6bd20..0c9b11b6c 100644 --- a/rtl/arp.v +++ b/rtl/arp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/arp_64.v b/rtl/arp_64.v index e4c4afa5d..a7cecdb44 100644 --- a/rtl/arp_64.v +++ b/rtl/arp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/arp_cache.v b/rtl/arp_cache.v index 967843e45..1e09e691f 100644 --- a/rtl/arp_cache.v +++ b/rtl/arp_cache.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index d95d3096b..2539149bf 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index 3ada52c30..7ce906fe5 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index 911facf32..9640d2ada 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 -2015Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index ad0950427..2c883d780 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/axis_eth_fcs.v b/rtl/axis_eth_fcs.v index 724d095c2..ff74205cc 100644 --- a/rtl/axis_eth_fcs.v +++ b/rtl/axis_eth_fcs.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/axis_eth_fcs_64.v b/rtl/axis_eth_fcs_64.v index b4390ffb2..e310f37ab 100644 --- a/rtl/axis_eth_fcs_64.v +++ b/rtl/axis_eth_fcs_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v index 23412dc2e..1f5c8adcd 100644 --- a/rtl/axis_eth_fcs_check.v +++ b/rtl/axis_eth_fcs_check.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index 9a104eb0a..502a23e07 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v index 1d7b8174b..f1e175f09 100644 --- a/rtl/axis_eth_fcs_insert.v +++ b/rtl/axis_eth_fcs_insert.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/axis_eth_fcs_insert_64.v b/rtl/axis_eth_fcs_insert_64.v index 107f82d1b..fcef07a20 100644 --- a/rtl/axis_eth_fcs_insert_64.v +++ b/rtl/axis_eth_fcs_insert_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/eth_arb_mux.py b/rtl/eth_arb_mux.py index 139a3343f..d5828550b 100755 --- a/rtl/eth_arb_mux.py +++ b/rtl/eth_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_arb_mux_2.v b/rtl/eth_arb_mux_2.v index 89157d384..6428b8d96 100644 --- a/rtl/eth_arb_mux_2.v +++ b/rtl/eth_arb_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_arb_mux_4.v b/rtl/eth_arb_mux_4.v index ef2f5c2cd..0db514131 100644 --- a/rtl/eth_arb_mux_4.v +++ b/rtl/eth_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_arb_mux_64.py b/rtl/eth_arb_mux_64.py index 0b9d54c45..d26dbe6b7 100755 --- a/rtl/eth_arb_mux_64.py +++ b/rtl/eth_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_arb_mux_64_2.v b/rtl/eth_arb_mux_64_2.v index b28b82dd0..09d5847cf 100644 --- a/rtl/eth_arb_mux_64_2.v +++ b/rtl/eth_arb_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_arb_mux_64_4.v b/rtl/eth_arb_mux_64_4.v index da3e27c35..eb8add575 100644 --- a/rtl/eth_arb_mux_64_4.v +++ b/rtl/eth_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index ca71f524c..eed87c912 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index c96daa0e8..b921e4a64 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index 2b057f093..24d74c515 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index a0da3a5ec..2e82864c3 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py index 068c31c28..eb2d9fee1 100755 --- a/rtl/eth_demux.py +++ b/rtl/eth_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_demux_4.v b/rtl/eth_demux_4.v index b87b9e68f..ee3239413 100644 --- a/rtl/eth_demux_4.v +++ b/rtl/eth_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py index d893689a7..21bf4a39b 100755 --- a/rtl/eth_demux_64.py +++ b/rtl/eth_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_demux_64_4.v b/rtl/eth_demux_64_4.v index 177999728..d97158e59 100644 --- a/rtl/eth_demux_64_4.v +++ b/rtl/eth_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index 34d0361ee..e6673c59e 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 1c370342b..107480b84 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index b8b098fc7..af3b4711c 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 72e7c9a64..44777a012 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v index b801c83e4..ecd7b1738 100644 --- a/rtl/eth_mac_1g.v +++ b/rtl/eth_mac_1g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index f7a3dbc20..7d137ab30 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v index 9a013016c..36f3f7e8d 100644 --- a/rtl/eth_mac_1g_rx.v +++ b/rtl/eth_mac_1g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/eth_mac_1g_tx.v b/rtl/eth_mac_1g_tx.v index 6c8b62b57..9407eb692 100644 --- a/rtl/eth_mac_1g_tx.v +++ b/rtl/eth_mac_1g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index 75552f6e8..abf83b3ed 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_mux_2.v b/rtl/eth_mux_2.v index 4abc98df3..9a80d6619 100644 --- a/rtl/eth_mux_2.v +++ b/rtl/eth_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v index 90bba71da..a85db466e 100644 --- a/rtl/eth_mux_4.v +++ b/rtl/eth_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index 21b1f79ab..702b910e4 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_mux_64_2.v b/rtl/eth_mux_64_2.v index 152f0771e..ee4845ab3 100644 --- a/rtl/eth_mux_64_2.v +++ b/rtl/eth_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v index 0cea82a64..74e18be02 100644 --- a/rtl/eth_mux_64_4.v +++ b/rtl/eth_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/gmii_phy_if.v b/rtl/gmii_phy_if.v index 5a2ddd9fa..6c2efb305 100644 --- a/rtl/gmii_phy_if.v +++ b/rtl/gmii_phy_if.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/iddr.v b/rtl/iddr.v index cc3879ca2..c1b73c735 100644 --- a/rtl/iddr.v +++ b/rtl/iddr.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/ip.v b/rtl/ip.v index 22cdbdbbf..4b9853d62 100644 --- a/rtl/ip.v +++ b/rtl/ip.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_64.v b/rtl/ip_64.v index e6d4cebc4..5185d7ca7 100644 --- a/rtl/ip_64.v +++ b/rtl/ip_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_arb_mux.py b/rtl/ip_arb_mux.py index 6c0781176..f85fb2930 100755 --- a/rtl/ip_arb_mux.py +++ b/rtl/ip_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_arb_mux_2.v b/rtl/ip_arb_mux_2.v index be9789167..30f3e3094 100644 --- a/rtl/ip_arb_mux_2.v +++ b/rtl/ip_arb_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_arb_mux_4.v b/rtl/ip_arb_mux_4.v index e9bee4c30..60e0bd57f 100644 --- a/rtl/ip_arb_mux_4.v +++ b/rtl/ip_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_arb_mux_64.py b/rtl/ip_arb_mux_64.py index 750e22dd0..645035987 100755 --- a/rtl/ip_arb_mux_64.py +++ b/rtl/ip_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_arb_mux_64_2.v b/rtl/ip_arb_mux_64_2.v index 6473e7838..4b0e38c1e 100644 --- a/rtl/ip_arb_mux_64_2.v +++ b/rtl/ip_arb_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_arb_mux_64_4.v b/rtl/ip_arb_mux_64_4.v index dc4320b97..9033f8659 100644 --- a/rtl/ip_arb_mux_64_4.v +++ b/rtl/ip_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_complete.v b/rtl/ip_complete.v index ee1363f37..d0dcd6172 100644 --- a/rtl/ip_complete.v +++ b/rtl/ip_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_complete_64.v b/rtl/ip_complete_64.v index 303535c58..69f1cca3d 100644 --- a/rtl/ip_complete_64.v +++ b/rtl/ip_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py index b0ab37e27..593c2d78d 100755 --- a/rtl/ip_demux.py +++ b/rtl/ip_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_demux_4.v b/rtl/ip_demux_4.v index 9c5002c9b..0501be687 100644 --- a/rtl/ip_demux_4.v +++ b/rtl/ip_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py index 0c8970c3e..5270b3287 100755 --- a/rtl/ip_demux_64.py +++ b/rtl/ip_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_demux_64_4.v b/rtl/ip_demux_64_4.v index 8c8b3a6e6..68ae735fd 100644 --- a/rtl/ip_demux_64_4.v +++ b/rtl/ip_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index b6afd7cdc..129f96998 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 2dcaef359..8a794ddf9 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index f9ce364de..9db9c4461 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index eda4385b6..ae793f660 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py index 8da717b67..8e1b40c46 100755 --- a/rtl/ip_mux.py +++ b/rtl/ip_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_mux_2.v b/rtl/ip_mux_2.v index f8e62ae83..3e3ac3d73 100644 --- a/rtl/ip_mux_2.v +++ b/rtl/ip_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_mux_4.v b/rtl/ip_mux_4.v index e4785beac..0108c3b47 100644 --- a/rtl/ip_mux_4.v +++ b/rtl/ip_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py index 5a9e98d35..1620000ca 100755 --- a/rtl/ip_mux_64.py +++ b/rtl/ip_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_mux_64_2.v b/rtl/ip_mux_64_2.v index ff4a27c9a..f1183904d 100644 --- a/rtl/ip_mux_64_2.v +++ b/rtl/ip_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/ip_mux_64_4.v b/rtl/ip_mux_64_4.v index 3dfdb2306..bbf066db1 100644 --- a/rtl/ip_mux_64_4.v +++ b/rtl/ip_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/lfsr.v b/rtl/lfsr.v index 7a92182be..57c0c80d9 100644 --- a/rtl/lfsr.v +++ b/rtl/lfsr.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/oddr.v b/rtl/oddr.v index 221045a0c..433d1f0ea 100644 --- a/rtl/oddr.v +++ b/rtl/oddr.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/rgmii_phy_if.v b/rtl/rgmii_phy_if.v index 75664a39d..35522ef39 100644 --- a/rtl/rgmii_phy_if.v +++ b/rtl/rgmii_phy_if.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/rtl/ssio_ddr_in.v b/rtl/ssio_ddr_in.v index 1183e1d67..0597712cd 100644 --- a/rtl/ssio_ddr_in.v +++ b/rtl/ssio_ddr_in.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/ssio_ddr_in_diff.v b/rtl/ssio_ddr_in_diff.v index e1251d232..ae7562e0e 100644 --- a/rtl/ssio_ddr_in_diff.v +++ b/rtl/ssio_ddr_in_diff.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/ssio_ddr_out.v b/rtl/ssio_ddr_out.v index 9d6ac47a5..387708154 100644 --- a/rtl/ssio_ddr_out.v +++ b/rtl/ssio_ddr_out.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/ssio_ddr_out_diff.v b/rtl/ssio_ddr_out_diff.v index 796eb7c9d..766467096 100644 --- a/rtl/ssio_ddr_out_diff.v +++ b/rtl/ssio_ddr_out_diff.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/ssio_sdr_in.v b/rtl/ssio_sdr_in.v index 92dc9d164..aff063d89 100644 --- a/rtl/ssio_sdr_in.v +++ b/rtl/ssio_sdr_in.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/ssio_sdr_in_diff.v b/rtl/ssio_sdr_in_diff.v index 95b0683f3..60c37f5d2 100644 --- a/rtl/ssio_sdr_in_diff.v +++ b/rtl/ssio_sdr_in_diff.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/ssio_sdr_out.v b/rtl/ssio_sdr_out.v index 9f3527bb0..e63b52e7a 100644 --- a/rtl/ssio_sdr_out.v +++ b/rtl/ssio_sdr_out.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/ssio_sdr_out_diff.v b/rtl/ssio_sdr_out_diff.v index 93a1513d3..e6543a2f3 100644 --- a/rtl/ssio_sdr_out_diff.v +++ b/rtl/ssio_sdr_out_diff.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/udp.v b/rtl/udp.v index e28179977..e4caa3435 100644 --- a/rtl/udp.v +++ b/rtl/udp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_64.v b/rtl/udp_64.v index b7f6f2aaf..1f0f09d43 100644 --- a/rtl/udp_64.v +++ b/rtl/udp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_arb_mux.py b/rtl/udp_arb_mux.py index 5a688117b..35ecb2c34 100755 --- a/rtl/udp_arb_mux.py +++ b/rtl/udp_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_arb_mux_4.v b/rtl/udp_arb_mux_4.v index fc42058e6..db35b9061 100644 --- a/rtl/udp_arb_mux_4.v +++ b/rtl/udp_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_arb_mux_64.py b/rtl/udp_arb_mux_64.py index 1bb0ba400..0f930113e 100755 --- a/rtl/udp_arb_mux_64.py +++ b/rtl/udp_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_arb_mux_64_4.v b/rtl/udp_arb_mux_64_4.v index 8ccd9c437..4a3297e83 100644 --- a/rtl/udp_arb_mux_64_4.v +++ b/rtl/udp_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_checksum_gen.v b/rtl/udp_checksum_gen.v index 55a9c324e..f9e1485ba 100644 --- a/rtl/udp_checksum_gen.v +++ b/rtl/udp_checksum_gen.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/udp_checksum_gen_64.v b/rtl/udp_checksum_gen_64.v index 94495d042..70041d824 100644 --- a/rtl/udp_checksum_gen_64.v +++ b/rtl/udp_checksum_gen_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v index de9089bf7..3b04b1165 100644 --- a/rtl/udp_complete.v +++ b/rtl/udp_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v index 0f7b09e86..331c3e144 100644 --- a/rtl/udp_complete_64.v +++ b/rtl/udp_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py index e74706ae8..416bd0aa5 100755 --- a/rtl/udp_demux.py +++ b/rtl/udp_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_demux_4.v b/rtl/udp_demux_4.v index d28a34471..84f3dbbf7 100644 --- a/rtl/udp_demux_4.v +++ b/rtl/udp_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py index 4c61aa6f9..d0b44e1a3 100755 --- a/rtl/udp_demux_64.py +++ b/rtl/udp_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_demux_64_4.v b/rtl/udp_demux_64_4.v index 9df7f4730..2d37c5b71 100644 --- a/rtl/udp_demux_64_4.v +++ b/rtl/udp_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v index 2468d010f..f71e49d7e 100644 --- a/rtl/udp_ip_rx.v +++ b/rtl/udp_ip_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index ae0e5f52c..3ee5a8864 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index cce00d96d..c9461059e 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index 2beb717e6..b18385628 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py index e1e7ca9a2..1cf7a0962 100755 --- a/rtl/udp_mux.py +++ b/rtl/udp_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_mux_4.v b/rtl/udp_mux_4.v index e52b7d321..caea094dd 100644 --- a/rtl/udp_mux_4.v +++ b/rtl/udp_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py index 43428a428..3d97f8a31 100755 --- a/rtl/udp_mux_64.py +++ b/rtl/udp_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/udp_mux_64_4.v b/rtl/udp_mux_64_4.v index 7c964a217..4dfdb9c2a 100644 --- a/rtl/udp_mux_64_4.v +++ b/rtl/udp_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/rtl/xgmii_deinterleave.v b/rtl/xgmii_deinterleave.v index d19bcb0df..76b92aa6c 100644 --- a/rtl/xgmii_deinterleave.v +++ b/rtl/xgmii_deinterleave.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/rtl/xgmii_interleave.v b/rtl/xgmii_interleave.v index d291703ae..ce8aa3142 100644 --- a/rtl/xgmii_interleave.v +++ b/rtl/xgmii_interleave.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/arp_ep.py b/tb/arp_ep.py index 7a283b6b1..e8ac2fdc3 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/eth_ep.py b/tb/eth_ep.py index 8fe9c4a22..ba486b2e4 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index 6c8fb1335..cafaef9bf 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/ip_ep.py b/tb/ip_ep.py index 24a3fed8f..5cebc0907 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/rgmii_ep.py b/tb/rgmii_ep.py index 31dd75c08..609827fe1 100644 --- a/tb/rgmii_ep.py +++ b/tb/rgmii_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp.py b/tb/test_arp.py index 61c7d1edd..296703f98 100755 --- a/tb/test_arp.py +++ b/tb/test_arp.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp.v b/tb/test_arp.v index e7d407700..6f9f0841b 100644 --- a/tb/test_arp.v +++ b/tb/test_arp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_64.py b/tb/test_arp_64.py index b67d3c4d1..42f47ccc0 100755 --- a/tb/test_arp_64.py +++ b/tb/test_arp_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_64.v b/tb/test_arp_64.v index f5f031f8c..28e84a9f7 100644 --- a/tb/test_arp_64.v +++ b/tb/test_arp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_cache.py b/tb/test_arp_cache.py index c843818ab..b563f8b9f 100755 --- a/tb/test_arp_cache.py +++ b/tb/test_arp_cache.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_cache.v b/tb/test_arp_cache.v index cf20007f9..576847148 100755 --- a/tb/test_arp_cache.v +++ b/tb/test_arp_cache.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index 8aa508774..c408d4ba3 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_eth_rx.v b/tb/test_arp_eth_rx.v index 35b094dac..cf46bab9d 100644 --- a/tb/test_arp_eth_rx.v +++ b/tb/test_arp_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index 4001e19c3..4bb67b266 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_eth_rx_64.v b/tb/test_arp_eth_rx_64.v index dc9179bcf..97429aff8 100644 --- a/tb/test_arp_eth_rx_64.v +++ b/tb/test_arp_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py index 519e2d4e8..025aba105 100755 --- a/tb/test_arp_eth_tx.py +++ b/tb/test_arp_eth_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_eth_tx.v b/tb/test_arp_eth_tx.v index c783b9dfe..eb976fae5 100644 --- a/tb/test_arp_eth_tx.v +++ b/tb/test_arp_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py index b1ddb7f81..34af70453 100755 --- a/tb/test_arp_eth_tx_64.py +++ b/tb/test_arp_eth_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_arp_eth_tx_64.v b/tb/test_arp_eth_tx_64.v index 1625f4660..60b192b90 100644 --- a/tb/test_arp_eth_tx_64.v +++ b/tb/test_arp_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_axis_eth_fcs.py b/tb/test_axis_eth_fcs.py index e39fccc73..43486c6ae 100755 --- a/tb/test_axis_eth_fcs.py +++ b/tb/test_axis_eth_fcs.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs.v b/tb/test_axis_eth_fcs.v index 6b83c756a..af9e06f81 100644 --- a/tb/test_axis_eth_fcs.v +++ b/tb/test_axis_eth_fcs.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_64.py b/tb/test_axis_eth_fcs_64.py index 2b613f0f8..511cc7554 100755 --- a/tb/test_axis_eth_fcs_64.py +++ b/tb/test_axis_eth_fcs_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_64.v b/tb/test_axis_eth_fcs_64.v index 0a2720a42..4a74ce25f 100644 --- a/tb/test_axis_eth_fcs_64.v +++ b/tb/test_axis_eth_fcs_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index 12763e98a..570efcd59 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_check.v b/tb/test_axis_eth_fcs_check.v index 8c8751052..110971176 100644 --- a/tb/test_axis_eth_fcs_check.v +++ b/tb/test_axis_eth_fcs_check.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_check_64.py b/tb/test_axis_eth_fcs_check_64.py index cd4abceb4..4c560ee23 100755 --- a/tb/test_axis_eth_fcs_check_64.py +++ b/tb/test_axis_eth_fcs_check_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_check_64.v b/tb/test_axis_eth_fcs_check_64.v index e1c66e810..d1791c42d 100644 --- a/tb/test_axis_eth_fcs_check_64.v +++ b/tb/test_axis_eth_fcs_check_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index 35d5781b4..3613e03c2 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_insert.v b/tb/test_axis_eth_fcs_insert.v index 9f82e6ffe..d954c4024 100644 --- a/tb/test_axis_eth_fcs_insert.v +++ b/tb/test_axis_eth_fcs_insert.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_insert_64.py b/tb/test_axis_eth_fcs_insert_64.py index c0d7b1c4a..e6ce9a3e4 100755 --- a/tb/test_axis_eth_fcs_insert_64.py +++ b/tb/test_axis_eth_fcs_insert_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_insert_64.v b/tb/test_axis_eth_fcs_insert_64.v index d86093416..dce0d6f46 100644 --- a/tb/test_axis_eth_fcs_insert_64.v +++ b/tb/test_axis_eth_fcs_insert_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_insert_64_pad.py b/tb/test_axis_eth_fcs_insert_64_pad.py index 7716e9740..70fa55405 100755 --- a/tb/test_axis_eth_fcs_insert_64_pad.py +++ b/tb/test_axis_eth_fcs_insert_64_pad.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_insert_64_pad.v b/tb/test_axis_eth_fcs_insert_64_pad.v index 909ef43d4..9bf1c52f9 100644 --- a/tb/test_axis_eth_fcs_insert_64_pad.v +++ b/tb/test_axis_eth_fcs_insert_64_pad.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_insert_pad.py b/tb/test_axis_eth_fcs_insert_pad.py index 2e89bc8bd..813d78653 100755 --- a/tb/test_axis_eth_fcs_insert_pad.py +++ b/tb/test_axis_eth_fcs_insert_pad.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_axis_eth_fcs_insert_pad.v b/tb/test_axis_eth_fcs_insert_pad.v index 1145956f0..8c900a673 100644 --- a/tb/test_axis_eth_fcs_insert_pad.v +++ b/tb/test_axis_eth_fcs_insert_pad.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_arb_mux_4.py b/tb/test_eth_arb_mux_4.py index 670419f7b..38d04029d 100755 --- a/tb/test_eth_arb_mux_4.py +++ b/tb/test_eth_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_arb_mux_4.v b/tb/test_eth_arb_mux_4.v index 8040f7662..106cc18df 100644 --- a/tb/test_eth_arb_mux_4.v +++ b/tb/test_eth_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_arb_mux_64_4.py b/tb/test_eth_arb_mux_64_4.py index 8d2f24222..e0bdcdffc 100755 --- a/tb/test_eth_arb_mux_64_4.py +++ b/tb/test_eth_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_arb_mux_64_4.v b/tb/test_eth_arb_mux_64_4.v index f1b8a15ec..1f133936f 100644 --- a/tb/test_eth_arb_mux_64_4.v +++ b/tb/test_eth_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index 0940fa05a..de6e60023 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_axis_rx.v b/tb/test_eth_axis_rx.v index 03e23335a..ced1db97e 100644 --- a/tb/test_eth_axis_rx.v +++ b/tb/test_eth_axis_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index f06c3d690..de4c16d4a 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_axis_rx_64.v b/tb/test_eth_axis_rx_64.v index 73e5fb67d..7a9ceb1f1 100644 --- a/tb/test_eth_axis_rx_64.v +++ b/tb/test_eth_axis_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py index 8a08a1591..a4749a017 100755 --- a/tb/test_eth_axis_tx.py +++ b/tb/test_eth_axis_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_axis_tx.v b/tb/test_eth_axis_tx.v index 99a5834ef..6207fd740 100644 --- a/tb/test_eth_axis_tx.v +++ b/tb/test_eth_axis_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py index 17a3eb4fe..9ac8fe3ef 100755 --- a/tb/test_eth_axis_tx_64.py +++ b/tb/test_eth_axis_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_axis_tx_64.v b/tb/test_eth_axis_tx_64.v index cf7ba2645..a1901ce2f 100644 --- a/tb/test_eth_axis_tx_64.v +++ b/tb/test_eth_axis_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_demux_4.py b/tb/test_eth_demux_4.py index 2dfe8598f..782e5f221 100755 --- a/tb/test_eth_demux_4.py +++ b/tb/test_eth_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_demux_4.v b/tb/test_eth_demux_4.v index 2044cf138..2d06c3a97 100644 --- a/tb/test_eth_demux_4.v +++ b/tb/test_eth_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_demux_64_4.py b/tb/test_eth_demux_64_4.py index cadd224b4..27f0c1c17 100755 --- a/tb/test_eth_demux_64_4.py +++ b/tb/test_eth_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_demux_64_4.v b/tb/test_eth_demux_64_4.v index ca6b6e174..cb2c17c55 100644 --- a/tb/test_eth_demux_64_4.v +++ b/tb/test_eth_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_mac_10g.py b/tb/test_eth_mac_10g.py index e34ade6fe..bb41d0426 100755 --- a/tb/test_eth_mac_10g.py +++ b/tb/test_eth_mac_10g.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_10g.v b/tb/test_eth_mac_10g.v index ebcb2501a..242657c57 100644 --- a/tb/test_eth_mac_10g.v +++ b/tb/test_eth_mac_10g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_10g_fifo.py b/tb/test_eth_mac_10g_fifo.py index 2ee845ae7..2cf41ed28 100755 --- a/tb/test_eth_mac_10g_fifo.py +++ b/tb/test_eth_mac_10g_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_10g_fifo.v b/tb/test_eth_mac_10g_fifo.v index a520c3d80..720a7527f 100644 --- a/tb/test_eth_mac_10g_fifo.v +++ b/tb/test_eth_mac_10g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_10g_rx.py b/tb/test_eth_mac_10g_rx.py index e5756624f..5e1063976 100755 --- a/tb/test_eth_mac_10g_rx.py +++ b/tb/test_eth_mac_10g_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_10g_rx.v b/tb/test_eth_mac_10g_rx.v index 570c2b8e3..a538cbcab 100644 --- a/tb/test_eth_mac_10g_rx.v +++ b/tb/test_eth_mac_10g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_10g_tx.py b/tb/test_eth_mac_10g_tx.py index fe1c0f271..6b76510aa 100755 --- a/tb/test_eth_mac_10g_tx.py +++ b/tb/test_eth_mac_10g_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_10g_tx.v b/tb/test_eth_mac_10g_tx.v index 4a5de341d..405868261 100644 --- a/tb/test_eth_mac_10g_tx.v +++ b/tb/test_eth_mac_10g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index d8812260e..6f918e260 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_1g.v b/tb/test_eth_mac_1g.v index ece226c52..4264110a9 100644 --- a/tb/test_eth_mac_1g.v +++ b/tb/test_eth_mac_1g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py index 7c9c771d7..228f562cf 100755 --- a/tb/test_eth_mac_1g_fifo.py +++ b/tb/test_eth_mac_1g_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_1g_fifo.v b/tb/test_eth_mac_1g_fifo.v index 3096febe1..9887daaa8 100644 --- a/tb/test_eth_mac_1g_fifo.v +++ b/tb/test_eth_mac_1g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py index 8c2be1edf..1f5d4ce2a 100755 --- a/tb/test_eth_mac_1g_rx.py +++ b/tb/test_eth_mac_1g_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_1g_rx.v b/tb/test_eth_mac_1g_rx.v index 3db6e924d..2f481bd37 100644 --- a/tb/test_eth_mac_1g_rx.v +++ b/tb/test_eth_mac_1g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index c40f29844..3dedfb93d 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mac_1g_tx.v b/tb/test_eth_mac_1g_tx.v index ab5298b27..4c60cd65c 100644 --- a/tb/test_eth_mac_1g_tx.v +++ b/tb/test_eth_mac_1g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 diff --git a/tb/test_eth_mux_4.py b/tb/test_eth_mux_4.py index ed0a718e5..8a624f81d 100755 --- a/tb/test_eth_mux_4.py +++ b/tb/test_eth_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_mux_4.v b/tb/test_eth_mux_4.v index c5e2a2a64..bd466cb12 100644 --- a/tb/test_eth_mux_4.v +++ b/tb/test_eth_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_mux_64_4.py b/tb/test_eth_mux_64_4.py index c7a9e7f97..8ee0c857b 100755 --- a/tb/test_eth_mux_64_4.py +++ b/tb/test_eth_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_eth_mux_64_4.v b/tb/test_eth_mux_64_4.v index e4d006599..142d7f136 100644 --- a/tb/test_eth_mux_64_4.v +++ b/tb/test_eth_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip.py b/tb/test_ip.py index a64790519..d3aa7f453 100755 --- a/tb/test_ip.py +++ b/tb/test_ip.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip.v b/tb/test_ip.v index 5d1e09211..d6d41e823 100644 --- a/tb/test_ip.v +++ b/tb/test_ip.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_64.py b/tb/test_ip_64.py index 5997bb3a5..cf94d2a20 100755 --- a/tb/test_ip_64.py +++ b/tb/test_ip_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_64.v b/tb/test_ip_64.v index 397a9492a..27a49b3cc 100644 --- a/tb/test_ip_64.v +++ b/tb/test_ip_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_arb_mux_4.py b/tb/test_ip_arb_mux_4.py index 2aa510268..1c56c0300 100755 --- a/tb/test_ip_arb_mux_4.py +++ b/tb/test_ip_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_arb_mux_4.v b/tb/test_ip_arb_mux_4.v index a52be7ad3..7a9e4d59e 100644 --- a/tb/test_ip_arb_mux_4.v +++ b/tb/test_ip_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_arb_mux_64_4.py b/tb/test_ip_arb_mux_64_4.py index 3bb1984ed..c7d1e841d 100755 --- a/tb/test_ip_arb_mux_64_4.py +++ b/tb/test_ip_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_arb_mux_64_4.v b/tb/test_ip_arb_mux_64_4.v index 6fac015eb..1b5634861 100644 --- a/tb/test_ip_arb_mux_64_4.v +++ b/tb/test_ip_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_complete.py b/tb/test_ip_complete.py index 64e9664da..02ad1055e 100755 --- a/tb/test_ip_complete.py +++ b/tb/test_ip_complete.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_complete.v b/tb/test_ip_complete.v index 810307830..bf419994b 100644 --- a/tb/test_ip_complete.v +++ b/tb/test_ip_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_complete_64.py b/tb/test_ip_complete_64.py index 8f25c4e22..1c59fc460 100755 --- a/tb/test_ip_complete_64.py +++ b/tb/test_ip_complete_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_complete_64.v b/tb/test_ip_complete_64.v index 146346834..8b59a8d3b 100644 --- a/tb/test_ip_complete_64.v +++ b/tb/test_ip_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_demux_4.py b/tb/test_ip_demux_4.py index f290b48fc..227c054d1 100755 --- a/tb/test_ip_demux_4.py +++ b/tb/test_ip_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_demux_4.v b/tb/test_ip_demux_4.v index bfc59ba65..7d5085581 100644 --- a/tb/test_ip_demux_4.v +++ b/tb/test_ip_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_demux_64_4.py b/tb/test_ip_demux_64_4.py index 2917c9a63..62081b418 100755 --- a/tb/test_ip_demux_64_4.py +++ b/tb/test_ip_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_demux_64_4.v b/tb/test_ip_demux_64_4.v index dd86b3b1c..8b3ca3775 100644 --- a/tb/test_ip_demux_64_4.v +++ b/tb/test_ip_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index e06214bba..726d93494 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_eth_rx.v b/tb/test_ip_eth_rx.v index 527f0527d..aada25add 100644 --- a/tb/test_ip_eth_rx.v +++ b/tb/test_ip_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py index b2418c811..639d5bd52 100755 --- a/tb/test_ip_eth_rx_64.py +++ b/tb/test_ip_eth_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_eth_rx_64.v b/tb/test_ip_eth_rx_64.v index 2f6c302a1..5b2ac2a21 100644 --- a/tb/test_ip_eth_rx_64.v +++ b/tb/test_ip_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py index 1635545bc..b74b5282d 100755 --- a/tb/test_ip_eth_tx.py +++ b/tb/test_ip_eth_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_eth_tx.v b/tb/test_ip_eth_tx.v index 0db5cd478..e0a017a8e 100644 --- a/tb/test_ip_eth_tx.v +++ b/tb/test_ip_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_eth_tx_64.py b/tb/test_ip_eth_tx_64.py index cdf3f450d..5262e59f7 100755 --- a/tb/test_ip_eth_tx_64.py +++ b/tb/test_ip_eth_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_eth_tx_64.v b/tb/test_ip_eth_tx_64.v index ba298fbfd..ede1320f4 100644 --- a/tb/test_ip_eth_tx_64.v +++ b/tb/test_ip_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_mux_4.py b/tb/test_ip_mux_4.py index be8fce9f2..8b237efb6 100755 --- a/tb/test_ip_mux_4.py +++ b/tb/test_ip_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_mux_4.v b/tb/test_ip_mux_4.v index 7eef7d22c..01768289f 100644 --- a/tb/test_ip_mux_4.v +++ b/tb/test_ip_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_mux_64_4.py b/tb/test_ip_mux_64_4.py index 3b6cbd5e8..0e55dd419 100755 --- a/tb/test_ip_mux_64_4.py +++ b/tb/test_ip_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_ip_mux_64_4.v b/tb/test_ip_mux_64_4.v index d0164fd4a..7252121e0 100644 --- a/tb/test_ip_mux_64_4.v +++ b/tb/test_ip_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp.py b/tb/test_udp.py index 3697616c4..68519981b 100755 --- a/tb/test_udp.py +++ b/tb/test_udp.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp.v b/tb/test_udp.v index 09fecdf42..3af79a25f 100644 --- a/tb/test_udp.v +++ b/tb/test_udp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py index e1efba408..d0cd6cca7 100755 --- a/tb/test_udp_64.py +++ b/tb/test_udp_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_64.v b/tb/test_udp_64.v index 0b6bfc731..352195cec 100644 --- a/tb/test_udp_64.v +++ b/tb/test_udp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_arb_mux_4.py b/tb/test_udp_arb_mux_4.py index 2cd8feaf3..60960369b 100755 --- a/tb/test_udp_arb_mux_4.py +++ b/tb/test_udp_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_arb_mux_4.v b/tb/test_udp_arb_mux_4.v index 81609d780..793bc28a4 100644 --- a/tb/test_udp_arb_mux_4.v +++ b/tb/test_udp_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_arb_mux_64_4.py b/tb/test_udp_arb_mux_64_4.py index deda22653..ad0b3f74f 100755 --- a/tb/test_udp_arb_mux_64_4.py +++ b/tb/test_udp_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_arb_mux_64_4.v b/tb/test_udp_arb_mux_64_4.v index f6e71d62b..59609bcc2 100644 --- a/tb/test_udp_arb_mux_64_4.v +++ b/tb/test_udp_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_checksum_gen.py b/tb/test_udp_checksum_gen.py index 910f01646..ceba47d21 100755 --- a/tb/test_udp_checksum_gen.py +++ b/tb/test_udp_checksum_gen.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_udp_checksum_gen.v b/tb/test_udp_checksum_gen.v index 002fa5f0c..c0dec7f08 100644 --- a/tb/test_udp_checksum_gen.v +++ b/tb/test_udp_checksum_gen.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_udp_checksum_gen_64.py b/tb/test_udp_checksum_gen_64.py index 5d0f84de2..fee281c52 100755 --- a/tb/test_udp_checksum_gen_64.py +++ b/tb/test_udp_checksum_gen_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_udp_checksum_gen_64.v b/tb/test_udp_checksum_gen_64.v index c09192825..6c686322d 100644 --- a/tb/test_udp_checksum_gen_64.v +++ b/tb/test_udp_checksum_gen_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016 Alex Forencich +Copyright (c) 2016-2017 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 diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py index 68f6892bd..d6725d314 100755 --- a/tb/test_udp_complete.py +++ b/tb/test_udp_complete.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_complete.v b/tb/test_udp_complete.v index 2d3d246b6..2a29713c9 100644 --- a/tb/test_udp_complete.v +++ b/tb/test_udp_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index 56c53fcf5..7a5437c4f 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_complete_64.v b/tb/test_udp_complete_64.v index bf1e47e31..cd33722d5 100644 --- a/tb/test_udp_complete_64.v +++ b/tb/test_udp_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_demux_4.py b/tb/test_udp_demux_4.py index c8323c592..53fdf5e16 100755 --- a/tb/test_udp_demux_4.py +++ b/tb/test_udp_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_demux_4.v b/tb/test_udp_demux_4.v index f5259553a..f17413d08 100644 --- a/tb/test_udp_demux_4.v +++ b/tb/test_udp_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_demux_64_4.py b/tb/test_udp_demux_64_4.py index 996c22551..9cd0f9861 100755 --- a/tb/test_udp_demux_64_4.py +++ b/tb/test_udp_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_demux_64_4.v b/tb/test_udp_demux_64_4.v index e44c299a0..04021b23e 100644 --- a/tb/test_udp_demux_64_4.v +++ b/tb/test_udp_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_ip_rx.py b/tb/test_udp_ip_rx.py index a8c32f51f..ece437d51 100755 --- a/tb/test_udp_ip_rx.py +++ b/tb/test_udp_ip_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_ip_rx.v b/tb/test_udp_ip_rx.v index 3846cff00..2be89b75f 100644 --- a/tb/test_udp_ip_rx.v +++ b/tb/test_udp_ip_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_ip_rx_64.py b/tb/test_udp_ip_rx_64.py index 2a609b4b1..74d95d9b2 100755 --- a/tb/test_udp_ip_rx_64.py +++ b/tb/test_udp_ip_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_ip_rx_64.v b/tb/test_udp_ip_rx_64.v index 316e20380..b4ef40679 100644 --- a/tb/test_udp_ip_rx_64.v +++ b/tb/test_udp_ip_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_ip_tx.py b/tb/test_udp_ip_tx.py index 766f513f5..74ac92237 100755 --- a/tb/test_udp_ip_tx.py +++ b/tb/test_udp_ip_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_ip_tx.v b/tb/test_udp_ip_tx.v index 05053b84f..3fb582a34 100644 --- a/tb/test_udp_ip_tx.v +++ b/tb/test_udp_ip_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_ip_tx_64.py b/tb/test_udp_ip_tx_64.py index 9036cda65..c09119623 100755 --- a/tb/test_udp_ip_tx_64.py +++ b/tb/test_udp_ip_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_ip_tx_64.v b/tb/test_udp_ip_tx_64.v index 457cca409..d638f6868 100644 --- a/tb/test_udp_ip_tx_64.v +++ b/tb/test_udp_ip_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_mux_4.py b/tb/test_udp_mux_4.py index 8341f63e5..108681576 100755 --- a/tb/test_udp_mux_4.py +++ b/tb/test_udp_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_mux_4.v b/tb/test_udp_mux_4.v index d7b5183d0..b153a94b0 100644 --- a/tb/test_udp_mux_4.v +++ b/tb/test_udp_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_mux_64_4.py b/tb/test_udp_mux_64_4.py index 314182cb9..ace7907a1 100755 --- a/tb/test_udp_mux_64_4.py +++ b/tb/test_udp_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/test_udp_mux_64_4.v b/tb/test_udp_mux_64_4.v index 940c68155..d424e6fed 100644 --- a/tb/test_udp_mux_64_4.v +++ b/tb/test_udp_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/udp_ep.py b/tb/udp_ep.py index 7e58cbf33..1d1a374b7 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2016 Alex Forencich +Copyright (c) 2014-2017 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 diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index a30c1f339..a5ab57a3a 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2015-2016 Alex Forencich +Copyright (c) 2015-2017 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 From 2e3b15239be7c7f57a113bcd41e9cb920ea25ef6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 18 May 2017 13:49:10 -0700 Subject: [PATCH 324/617] Update Vivado IP --- .../fpga_10g/ip/gig_ethernet_pcs_pma_0.xci | 21 ++++++++++++++----- .../fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci | 4 ++-- .../fpga_1g/ip/gig_ethernet_pcs_pma_0.xci | 21 ++++++++++++++----- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci index 0b780494e..908bb2e82 100644 --- a/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci +++ b/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci @@ -7,26 +7,32 @@ gig_ethernet_pcs_pma_0 - + true - 1 0 0 + true + false DIFF_PAIR_0 DIFF_PAIR_1 false DIFF_PAIR_0 DIFF_PAIR_1 virtexu + 0 gig_ethernet_pcs_pma_0 50.0 false . + false + false + false false virtexu 17 9 + X0Y0 7 4 GTH @@ -37,6 +43,7 @@ false true 1 + clk0 125 TXOUTCLK true @@ -53,18 +60,21 @@ false 1 true - 1 + Sync gig_ethernet_pcs_pma_0 Custom 50.0 TEMAC Custom 0 + false false false false + X0Y0 GTH false + false 625 Custom false @@ -72,6 +82,7 @@ 1 LVDS 125 + clk0 TXOUTCLK DIFF_PAIR_0 DIFF_PAIR_1 @@ -98,12 +109,12 @@ TRUE TRUE IP_Flow - 1 + 2 TRUE . . - 2016.2 + 2017.1 OUT_OF_CONTEXT diff --git a/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci b/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci index 5b02f3f19..aaf8ceecd 100644 --- a/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci +++ b/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci @@ -56,12 +56,12 @@ TRUE TRUE IP_Flow - 5 + 8 TRUE . . - 2016.2 + 2017.1 OUT_OF_CONTEXT diff --git a/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci index 0b780494e..908bb2e82 100644 --- a/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci +++ b/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci @@ -7,26 +7,32 @@ gig_ethernet_pcs_pma_0 - + true - 1 0 0 + true + false DIFF_PAIR_0 DIFF_PAIR_1 false DIFF_PAIR_0 DIFF_PAIR_1 virtexu + 0 gig_ethernet_pcs_pma_0 50.0 false . + false + false + false false virtexu 17 9 + X0Y0 7 4 GTH @@ -37,6 +43,7 @@ false true 1 + clk0 125 TXOUTCLK true @@ -53,18 +60,21 @@ false 1 true - 1 + Sync gig_ethernet_pcs_pma_0 Custom 50.0 TEMAC Custom 0 + false false false false + X0Y0 GTH false + false 625 Custom false @@ -72,6 +82,7 @@ 1 LVDS 125 + clk0 TXOUTCLK DIFF_PAIR_0 DIFF_PAIR_1 @@ -98,12 +109,12 @@ TRUE TRUE IP_Flow - 1 + 2 TRUE . . - 2016.2 + 2017.1 OUT_OF_CONTEXT From 3e2b94f6c7fb84a635dfe10cb769bfb1693df871 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 18 May 2017 13:52:05 -0700 Subject: [PATCH 325/617] Return False instead of None for mismatched objects --- tb/axis_ep.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 78bb742c6..56d0a6bee 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -169,6 +169,7 @@ class AXIStreamFrame(object): def __eq__(self, other): if type(other) is AXIStreamFrame: return self.data == other.data + return False def __repr__(self): return 'AXIStreamFrame(data=%s, keep=%s, dest=%s, user=%s)' % (repr(self.data), repr(self.keep), repr(self.dest), repr(self.user)) From 57a16b7d54a19f8b40eb4a8cd92baf994cb0d449 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 19 May 2017 17:33:07 -0700 Subject: [PATCH 326/617] Add ML605 example design --- example/ML605/fpga/Makefile | 25 + example/ML605/fpga/README.md | 25 + example/ML605/fpga/clock.ucf | 6 + example/ML605/fpga/common/xilinx.mk | 191 +++++++ example/ML605/fpga/fpga.ucf | 85 ++++ example/ML605/fpga/fpga/Makefile | 72 +++ example/ML605/fpga/lib/eth | 1 + example/ML605/fpga/rtl/debounce_switch.v | 89 ++++ example/ML605/fpga/rtl/fpga.v | 278 +++++++++++ example/ML605/fpga/rtl/fpga_core.v | 608 +++++++++++++++++++++++ example/ML605/fpga/rtl/sync_reset.v | 52 ++ example/ML605/fpga/rtl/sync_signal.v | 58 +++ example/ML605/fpga/tb/arp_ep.py | 1 + example/ML605/fpga/tb/axis_ep.py | 1 + example/ML605/fpga/tb/eth_ep.py | 1 + example/ML605/fpga/tb/gmii_ep.py | 1 + example/ML605/fpga/tb/ip_ep.py | 1 + example/ML605/fpga/tb/test_fpga_core.py | 316 ++++++++++++ example/ML605/fpga/tb/test_fpga_core.v | 143 ++++++ example/ML605/fpga/tb/udp_ep.py | 1 + 20 files changed, 1955 insertions(+) create mode 100644 example/ML605/fpga/Makefile create mode 100644 example/ML605/fpga/README.md create mode 100644 example/ML605/fpga/clock.ucf create mode 100644 example/ML605/fpga/common/xilinx.mk create mode 100644 example/ML605/fpga/fpga.ucf create mode 100644 example/ML605/fpga/fpga/Makefile create mode 120000 example/ML605/fpga/lib/eth create mode 100644 example/ML605/fpga/rtl/debounce_switch.v create mode 100644 example/ML605/fpga/rtl/fpga.v create mode 100644 example/ML605/fpga/rtl/fpga_core.v create mode 100644 example/ML605/fpga/rtl/sync_reset.v create mode 100644 example/ML605/fpga/rtl/sync_signal.v create mode 120000 example/ML605/fpga/tb/arp_ep.py create mode 120000 example/ML605/fpga/tb/axis_ep.py create mode 120000 example/ML605/fpga/tb/eth_ep.py create mode 120000 example/ML605/fpga/tb/gmii_ep.py create mode 120000 example/ML605/fpga/tb/ip_ep.py create mode 100755 example/ML605/fpga/tb/test_fpga_core.py create mode 100644 example/ML605/fpga/tb/test_fpga_core.v create mode 120000 example/ML605/fpga/tb/udp_ep.py diff --git a/example/ML605/fpga/Makefile b/example/ML605/fpga/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/ML605/fpga/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/ML605/fpga/README.md b/example/ML605/fpga/README.md new file mode 100644 index 000000000..887a41197 --- /dev/null +++ b/example/ML605/fpga/README.md @@ -0,0 +1,25 @@ +# Verilog Ethernet ML605 Example Design + +## Introduction + +This example design targets the Xilinx ML605 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +FPGA: XC6SlX45-2CSG324 +PHY: Marvell M88E1111 + +## How to build + +Run make to build. Ensure that the Xilinx ISE toolchain components are +in PATH. + +## How to test + +Run make program to program the ML605 board with the Xilinx Impact software. +Then run netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. +Any text entered into netcat will be echoed back after pressing enter. + + diff --git a/example/ML605/fpga/clock.ucf b/example/ML605/fpga/clock.ucf new file mode 100644 index 000000000..713379c40 --- /dev/null +++ b/example/ML605/fpga/clock.ucf @@ -0,0 +1,6 @@ +# UCF file for clock module domain crossing constraints + +NET "clk_125mhz_int" TNM = "ffs_clk_125mhz_int"; +NET "core_inst/gmii_rx_clk" TNM = "ffs_gmii_rx_clk"; +TIMESPEC "TS_clk_125mhz_int_to_gmii_rx_clk" = FROM "ffs_clk_125mhz_int" TO "ffs_gmii_rx_clk" 10 ns; +TIMESPEC "TS_gmii_rx_clk_to_clk_125mhz_int" = FROM "ffs_gmii_rx_clk" TO "ffs_clk_125mhz_int" 10 ns; diff --git a/example/ML605/fpga/common/xilinx.mk b/example/ML605/fpga/common/xilinx.mk new file mode 100644 index 000000000..f10a45f8e --- /dev/null +++ b/example/ML605/fpga/common/xilinx.mk @@ -0,0 +1,191 @@ +############################################################################# +# Author: Lane Brooks/Keith Fife +# Date: 04/28/2006 +# License: GPL +# Desc: This is a Makefile intended to take a verilog rtl design +# through the Xilinx ISE tools to generate configuration files for +# Xilinx FPGAs. This file is generic and just a template. As such +# all design specific options such as synthesis files, fpga part type, +# prom part type, etc should be set in the top Makefile prior to +# including this file. Alternatively, all parameters can be passed +# in from the command line as well. +# +############################################################################## +# +# Parameter: +# SYN_FILES - Space seperated list of files to be synthesized +# PART - FPGA part (see Xilinx documentation) +# PROM - PROM part +# NGC_PATHS - Space seperated list of any dirs with pre-compiled ngc files. +# UCF_FILES - Space seperated list of user constraint files. Defaults to xilinx/$(FPGA_TOP).ucf +# +# +# Example Calling Makefile: +# +# SYN_FILES = fpga.v fifo.v clks.v +# PART = xc3s1000 +# FPGA_TOP = fpga +# PROM = xc18v04 +# NGC_PATH = ipLib1 ipLib2 +# FPGA_ARCH = spartan6 +# SPI_PROM_SIZE = (in bytes) +# include xilinx.mk +############################################################################# +# +# Command Line Example: +# make -f xilinx.mk PART=xc3s1000-4fg320 SYN_FILES="fpga.v test.v" FPGA_TOP=fpga +# +############################################################################## +# +# Required Setup: +# +# %.ucf - user constraint file. Needed by ngdbuild +# +# Optional Files: +# %.xcf - user constraint file. Needed by xst. +# %.ut - File for pin states needed by bitgen + + +.PHONY: clean bit prom fpga spi + + +# Mark the intermediate files as PRECIOUS to prevent make from +# deleting them (see make manual section 10.4). +.PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.bit %_timesim.v + +# include the local Makefile for project for any project specific targets +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +INC_PATHS_REL = $(patsubst %, ../%, $(INC_PATHS)) +NGC_PATHS_REL = $(patsubst %, ../%, $(NGC_PATHS)) + +ifdef UCF_FILES + UCF_FILES_REL = $(patsubst %, ../%, $(UCF_FILES)) +else + UCF_FILES_REL = $(FPGA_TOP).ucf +endif + + + +fpga: $(FPGA_TOP).bit + +mcs: $(FPGA_TOP).mcs + +prom: $(FPGA_TOP).spi + +spi: $(FPGA_TOP).spi + +fpgasim: $(FPGA_TOP)_sim.v + + +########################### XST TEMPLATES ############################ +# There are 2 files that XST uses for synthesis that we auto generate. +# The first is a project file which is just a list of all the verilog +# files. The second is the src file which passes XST all the options. +# See XST user manual for XST options. +%.ngc: $(SYN_FILES_REL) $(INC_FILES_REL) + rm -rf xst $*.prj $*.xst defines.v + touch defines.v + mkdir -p xst/tmp + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo verilog work defines.v > $*.prj + for x in $(SYN_FILES_REL); do echo verilog work $$x >> $*.prj; done + @echo "set -tmpdir ./xst/tmp" >> $*.xst + @echo "set -xsthdpdir ./xst" >> $*.xst + @echo "run" >> $*.xst + @echo "-ifn $*.prj" >> $*.xst + @echo "-ifmt mixed" >> $*.xst + @echo "-top $*" >> $*.xst + @echo "-ofn $*" >> $*.xst + @echo "-ofmt NGC" >> $*.xst + @echo "-opt_mode Speed" >> $*.xst + @echo "-opt_level 1" >> $*.xst + # @echo "-verilog2001 YES" >> $*.xst + @echo "-keep_hierarchy NO" >> $*.xst + @echo "-p $(FPGA_PART)" >> $*.xst + xst -ifn $*.xst -ofn $*.log + + +########################### ISE TRANSLATE ############################ +# ngdbuild will automatically use a ucf called %.ucf if one is found. +# We setup the dependancy such that %.ucf file is required. If any +# pre-compiled ncd files are needed, set the NGC_PATH variable as a space +# seperated list of directories that include the pre-compiled ngc files. +%.ngd: %.ngc $(UCF_FILES_REL) + ngdbuild -dd ngdbuild $(patsubst %,-sd %, $(NGC_PATHS_REL)) $(patsubst %,-uc %, $(UCF_FILES_REL)) -p $(FPGA_PART) $< $@ + + +########################### ISE MAP ################################### +ifeq ($(FPGA_ARCH),spartan6) + MAP_OPTS= -register_duplication on -timing -xe n +else + MAP_OPTS= -cm speed -register_duplication on -timing -xe n -pr b +endif + +%_map.ncd: %.ngd + map -p $(FPGA_PART) $(MAP_OPTS) -w -o $@ $< $*.pcf + +# map -p $(FPGA_PART) -cm area -pr b -k 4 -c 100 -o $@ $< $*.pcf + + +########################### ISE PnR ################################### +%.ncd: %_map.ncd + par -w -ol high $< $@ $*.pcf + +# par -w -ol std -t 1 $< $@ $*.pcf + + +##################### ISE Static Timing Analysis ##################### +%.twr: %.ncd + -trce -e 3 -l 3 -u -xml $* $< -o $@ $*.pcf + +%_sim.v: %.ncd + netgen -s 4 -pcf $*.pcf -sdf_anno true -ism -sdf_path netgen -w -dir . -ofmt verilog -sim $< $@ + +# netgen -ise "/home/lane/Second/xilinx/Second/Second" -intstyle ise -s 4 -pcf Second.pcf -sdf_anno true -sdf_path netgen/par -w -dir netgen/par -ofmt verilog -sim Second.ncd Second_timesim.v + + +########################### ISE Bitgen ############################# +%.bit: %.twr + bitgen $(BITGEN_OPTIONS) -w $*.ncd $*.bit + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +########################### ISE Promgen ############################# +%.mcs: %.bit + promgen -spi -w -p mcs -s $(SPI_PROM_SIZE) -o $@ -u 0 $< + # promgen -w -p mcs -c FF -o $@ -u 0 $< -x $(PROM) + mkdir -p rev + EXT=mcs; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +%.spi: %.mcs + objcopy -I ihex -O binary $< $@ + EXT=spi; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + + +tmpclean: + -rm -rf xst ngdbuild *_map.* *.ncd *.ngc *.log *.xst *.prj *.lso *~ *.pcf *.bld *.ngd *.xpi *_pad.* *.unroutes *.twx *.par *.twr *.pad *.drc *.bgn *.prm *.sig netgen *.v *.nlf *.xml + +clean: tmpclean + -rm -rf *.bit *.mcs + +# clean everything +distclean: clean + -rm -rf rev + diff --git a/example/ML605/fpga/fpga.ucf b/example/ML605/fpga/fpga.ucf new file mode 100644 index 000000000..6ce175d2f --- /dev/null +++ b/example/ML605/fpga/fpga.ucf @@ -0,0 +1,85 @@ +# User Constraints File for the Xilinx ML605 board, rev C + +CONFIG PART = xc6vlx130t-1ff1156; + +# 200MHz clock +NET "sys_clk_p" LOC = "J9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0P_GC_34 (GCLK) +NET "sys_clk_n" LOC = "H9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0N_GC_34 (GCLK) +NET "sys_clk_p" TNM_NET = "sys_clk_pin"; +TIMESPEC "TS_sys_clk_pin" = PERIOD "sys_clk_pin" 200000 kHz; + +# Light Emitting Diodes +NET "ledu" LOC = "AH27" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L0P_23 (DS20) +NET "ledl" LOC = "AD21" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 22, IO_L0N_22 (DS17) +NET "ledd" LOC = "AH28" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L0N_23 (DS18) +NET "ledr" LOC = "AE21" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 22, IO_L0P_22 (DS19) +NET "ledc" LOC = "AP24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L19N_23 (DS16) + +NET "led<0>" LOC = "AC22" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L19P_24 (DS12) +NET "led<1>" LOC = "AC24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L18N_24 (DS11) +NET "led<2>" LOC = "AE22" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L17N_VRP_24 (DS9) +NET "led<3>" LOC = "AE23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L17P_VRN_24 (DS10) +NET "led<4>" LOC = "AB23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L16N_CSO_B_24 (DS15) +NET "led<5>" LOC = "AG23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L15N_RS1_24 (DS14) +NET "led<6>" LOC = "AE24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L11N_SRCC_24 (DS22) +NET "led<7>" LOC = "AD24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L11P_SRCC_24 (DS21) + +# Reset Button: I/O Bank 2 +NET "reset" LOC = "H10" | IOSTANDARD=LVCMOS15; # Bank = 35, IO_L6P_SM3P_35 (SW10) + +# Push Buttons: I/O Bank 3 +NET "btnu" LOC = "A19" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L15N_26 (SW5) +NET "btnl" LOC = "H17" | IOSTANDARD=LVCMOS15; # Bank = 36, IO_L3P_36 (SW8) +NET "btnd" LOC = "A18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L15P_26 (SW6) +NET "btnr" LOC = "G17" | IOSTANDARD=LVCMOS15; # Bank = 36, IO_L3N_36 (SW7) +NET "btnc" LOC = "G26" | IOSTANDARD=LVCMOS15; # Bank = 25, IO_L6P_25 (SW9) + +# Toggle Switches +NET "sw<0>" LOC = "D22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L19N_26 (SW1.1) +NET "sw<1>" LOC = "C22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L19P_26 (SW1.2) +NET "sw<2>" LOC = "L21" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L18N_26 (SW1.3) +NET "sw<3>" LOC = "L20" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L18P_26 (SW1.4) +NET "sw<4>" LOC = "C18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L17N_26 (SW1.5) +NET "sw<5>" LOC = "B18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L17P_26 (SW1.6) +NET "sw<6>" LOC = "K22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L16N_26 (SW1.7) +NET "sw<7>" LOC = "K21" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L16P_26 (SW1.8) + +# Marvell M88E1111 Tri-Mode Ethernet PHY (1000BASE-T) +# Interrupt, Reset, MDIO +#NET "phy_int_n" LOC = "AH14" | IOSTANDARD=LVCMOS25; # (E-INT) +NET "phy_reset_n" LOC = "AH13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L18P_33 (E-RESET) +#NET "phy_mdc" LOC = "AP14" | IOSTANDARD=LVCMOS25; # (E-MDC) +#NET "phy_mdio" LOC = "AN14" | IOSTANDARD=LVCMOS25; # (E-MDIO) +# GMII Transmit +NET "phy_gtx_clk" LOC = "AH12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L16N_33 (E-GTXCLK) +NET "phy_txd<0>" LOC = "AM11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L7N_33 (E-TXD0) +NET "phy_txd<1>" LOC = "AL11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L7P_33 (E-TXD1) +NET "phy_txd<2>" LOC = "AG10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L6N_33 (E-TXD2) +NET "phy_txd<3>" LOC = "AG11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L6P_33 (E-TXD3) +NET "phy_txd<4>" LOC = "AL10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L5N_33 (E-TXD4) +NET "phy_txd<5>" LOC = "AM10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L5P_33 (E-TXD5) +NET "phy_txd<6>" LOC = "AE11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L4N_VREF_33 (E-TXD6) +NET "phy_txd<7>" LOC = "AF11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L4P_33 (E-TXD7) +NET "phy_tx_en" LOC = "AJ10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L8P_SRCC_33 (E-TXEN) +NET "phy_tx_er" LOC = "AH10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L8N_SRCC_33 (E-TXER) +# GMII Receive +NET "phy_rx_clk" LOC = "AP11" | IOSTANDARD=LVCMOS25 | TNM_NET = "clk_rx_local"; # (E-RXCLK) +NET "phy_rxd<0>" LOC = "AN13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L15P_33 (E-RXD0) +NET "phy_rxd<1>" LOC = "AF14" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L14N_VREF_33 (E-RXD1) +NET "phy_rxd<2>" LOC = "AE14" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L14P_33 (E-RXD2) +NET "phy_rxd<3>" LOC = "AN12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L13N_33 (E-RXD3) +NET "phy_rxd<4>" LOC = "AM12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L13P_33 (E-RXD4) +NET "phy_rxd<5>" LOC = "AD11" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L10N_MRCC_33 (E-RXD5) +NET "phy_rxd<6>" LOC = "AC12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L9N_MRCC_33 (E-RXD6) +NET "phy_rxd<7>" LOC = "AC13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L9P_MRCC_33 (E-RXD7) +NET "phy_rx_dv" LOC = "AM13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L15N_33 (E-RXDV) +NET "phy_rx_er" LOC = "AG12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L16P_33 (E-RXER) + +# Timing constraints for Ethernet PHY +TIMESPEC "TS_rx_clk_root" = PERIOD "clk_rx_local" 8000 ps HIGH 50 %; + +# Silicon Labs CP2103 +NET "uart_rxd" LOC = "J25" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L9P_MRCC_24 (U24.24) +NET "uart_txd" LOC = "J24" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L9N_MRCC_24 (U24.25) +NET "uart_rts" LOC = "T23" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L8N_SRCC_24 (U24.23) +NET "uart_cts" LOC = "T24" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L8P_SRCC_24 (U24.22) diff --git a/example/ML605/fpga/fpga/Makefile b/example/ML605/fpga/fpga/Makefile new file mode 100644 index 000000000..eaa29656c --- /dev/null +++ b/example/ML605/fpga/fpga/Makefile @@ -0,0 +1,72 @@ + +# FPGA settings +FPGA_PART = xc6vlx130t-1ff1156 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/iddr.v +SYN_FILES += lib/eth/rtl/oddr.v +SYN_FILES += lib/eth/rtl/ssio_sdr_in.v +SYN_FILES += lib/eth/rtl/ssio_sdr_out.v +SYN_FILES += lib/eth/rtl/gmii_phy_if.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v +SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v +SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +#SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v + +# UCF files +UCF_FILES = fpga.ucf +UCF_FILES += clock.ucf + +# NGC paths for ngdbuild +#NGC_PATHS = coregen/dcm_i100_o125 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 2 -file $(FPGA_TOP).bit" >> program.cmd + echo "program -p 2" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + diff --git a/example/ML605/fpga/lib/eth b/example/ML605/fpga/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/ML605/fpga/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/ML605/fpga/rtl/debounce_switch.v b/example/ML605/fpga/rtl/debounce_switch.v new file mode 100644 index 000000000..ab84126ec --- /dev/null +++ b/example/ML605/fpga/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/ML605/fpga/rtl/fpga.v b/example/ML605/fpga/rtl/fpga.v new file mode 100644 index 000000000..083be485a --- /dev/null +++ b/example/ML605/fpga/rtl/fpga.v @@ -0,0 +1,278 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 200MHz + * Reset: Push button, active high + */ + input wire sys_clk_p, + input wire sys_clk_n, + input wire reset, + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire ledu, + output wire ledl, + output wire ledd, + output wire ledr, + output wire ledc, + output wire [7:0] led, + /* + * Ethernet: 1000BASE-T GMII + */ + input wire phy_rx_clk, + input wire [7:0] phy_rxd, + input wire phy_rx_dv, + input wire phy_rx_er, + output wire phy_gtx_clk, + output wire [7:0] phy_txd, + output wire phy_tx_en, + output wire phy_tx_er, + output wire phy_reset_n, + /* + * Silicon Labs CP2103 USB UART + */ + output wire uart_rxd, + input wire uart_txd, + input wire uart_rts, + output wire uart_cts +); + +// Clock and reset + +wire sys_clk_ibufg; +wire sys_clk_bufg; +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +wire mmcm_rst = reset; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS +clk_ibufgds_inst( + .I(sys_clk_p), + .IB(sys_clk_n), + .O(sys_clk_ibufg) +); + +// MMCM instance +// 200 MHz in, 125 MHz out +// PFD range: 10 MHz to 450 MHz +// VCO range: 600 MHz to 1200 MHz +// M = 5, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCM_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(5), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.100), + .CLKIN1_PERIOD(5.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(sys_clk_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [7:0] sw_int; + +wire ledu_int; +wire ledl_int; +wire ledd_int; +wire ledr_int; +wire ledc_int; +wire [7:0] led_int; + +wire uart_rxd_int; +wire uart_txd_int; +wire uart_rts_int; +wire uart_cts_int; + +debounce_switch #( + .WIDTH(13), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(clk_125mhz_int), + .in({uart_txd, + uart_rts}), + .out({uart_txd_int, + uart_rts_int}) +); + +assign ledu = ledu_int; +assign ledl = ledl_int; +assign ledd = ledd_int; +assign ledr = ledr_int; +assign ledc = ledc_int; +assign led = led_int; + +assign uart_rxd = uart_rxd_int; +assign uart_cts = uart_cts_int; + +fpga_core +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk_125mhz(clk_125mhz_int), + .rst_125mhz(rst_125mhz_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .ledu(ledu_int), + .ledl(ledl_int), + .ledd(ledd_int), + .ledr(ledr_int), + .ledc(ledc_int), + .led(led_int), + /* + * Ethernet: 1000BASE-T GMII + */ + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_dv(phy_rx_dv), + .phy_rx_er(phy_rx_er), + .phy_gtx_clk(phy_gtx_clk), + .phy_txd(phy_txd), + .phy_tx_en(phy_tx_en), + .phy_tx_er(phy_tx_er), + .phy_reset_n(phy_reset_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd_int), + .uart_rts(uart_rts_int), + .uart_cts(uart_cts_int) +); + +endmodule diff --git a/example/ML605/fpga/rtl/fpga_core.v b/example/ML605/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..c2fda6a19 --- /dev/null +++ b/example/ML605/fpga/rtl/fpga_core.v @@ -0,0 +1,608 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 125MHz + * Synchronous reset + */ + input wire clk_125mhz, + input wire rst_125mhz, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire ledu, + output wire ledl, + output wire ledd, + output wire ledr, + output wire ledc, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T GMII + */ + input wire phy_rx_clk, + input wire [7:0] phy_rxd, + input wire phy_rx_dv, + input wire phy_rx_er, + output wire phy_gtx_clk, + output wire [7:0] phy_txd, + output wire phy_tx_en, + output wire phy_tx_er, + output wire phy_reset_n, + + /* + * Silicon Labs CP2103 USB UART + */ + output wire uart_rxd, + input wire uart_txd, + input wire uart_rts, + output wire uart_cts +); + +// GMII between MAC and PHY IF +wire gmii_rx_clk; +wire gmii_rx_rst; +wire [7:0] gmii_rxd; +wire gmii_rx_dv; +wire gmii_rx_er; + +wire gmii_tx_clk; +wire gmii_tx_rst; +wire [7:0] gmii_txd; +wire gmii_tx_en; +wire gmii_tx_er; + +// AXI between MAC and Ethernet modules +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [7:0] tx_axis_tdata; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [7:0] rx_eth_payload_tdata; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [7:0] tx_eth_payload_tdata; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [7:0] rx_ip_payload_tdata; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [7:0] tx_ip_payload_tdata; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [7:0] rx_udp_payload_tdata; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_tdata; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [7:0] rx_fifo_udp_payload_tdata; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [7:0] tx_fifo_udp_payload_tdata; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk_125mhz) begin + if (rst_125mhz) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk_125mhz) begin + if (rst_125mhz) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_tvalid; + if (tx_udp_payload_tvalid & ~valid_last) begin + led_reg <= tx_udp_payload_tdata; + end + end +end + +//assign led = sw; +assign ledu = 0; +assign ledl = 0; +assign ledd = 0; +assign ledr = 0; +assign ledc = 0; +assign led = led_reg; +assign phy_reset_n = ~rst_125mhz; + +assign uart_rxd = 0; +assign uart_cts = 0; + +gmii_phy_if #( + .TARGET(TARGET), + .IODDR_STYLE("IODDR"), + .CLOCK_INPUT_STYLE("BUFR") +) +gmii_phy_if_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + + .mac_gmii_rx_clk(gmii_rx_clk), + .mac_gmii_rx_rst(gmii_rx_rst), + .mac_gmii_rxd(gmii_rxd), + .mac_gmii_rx_dv(gmii_rx_dv), + .mac_gmii_rx_er(gmii_rx_er), + .mac_gmii_tx_clk(gmii_tx_clk), + .mac_gmii_tx_rst(gmii_tx_rst), + .mac_gmii_txd(gmii_txd), + .mac_gmii_tx_en(gmii_tx_en), + .mac_gmii_tx_er(gmii_tx_er), + + .phy_gmii_rx_clk(phy_rx_clk), + .phy_gmii_rxd(phy_rxd), + .phy_gmii_rx_dv(phy_rx_dv), + .phy_gmii_rx_er(phy_rx_er), + .phy_gmii_tx_clk(phy_gtx_clk), + .phy_gmii_txd(phy_txd), + .phy_gmii_tx_en(phy_tx_en), + .phy_gmii_tx_er(phy_tx_er) +); + +eth_mac_1g_fifo #( + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .RX_FIFO_ADDR_WIDTH(12) +) +eth_mac_1g_fifo_inst ( + .rx_clk(gmii_rx_clk), + .rx_rst(gmii_rx_rst), + .tx_clk(gmii_tx_clk), + .tx_rst(gmii_tx_rst), + .logic_clk(clk_125mhz), + .logic_rst(rst_125mhz), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + + .ifg_delay(12) +); + +eth_axis_rx +eth_axis_rx_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx +eth_axis_tx_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete +udp_complete_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(0) +); + +axis_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8) +) +udp_payload_fifo ( + .clk(clk_125mhz), + .rst(rst_125mhz), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/ML605/fpga/rtl/sync_reset.v b/example/ML605/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..558a67605 --- /dev/null +++ b/example/ML605/fpga/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/ML605/fpga/rtl/sync_signal.v b/example/ML605/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..1b8a32328 --- /dev/null +++ b/example/ML605/fpga/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/ML605/fpga/tb/arp_ep.py b/example/ML605/fpga/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/ML605/fpga/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/ML605/fpga/tb/axis_ep.py b/example/ML605/fpga/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/ML605/fpga/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/ML605/fpga/tb/eth_ep.py b/example/ML605/fpga/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/ML605/fpga/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/ML605/fpga/tb/gmii_ep.py b/example/ML605/fpga/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/ML605/fpga/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/ML605/fpga/tb/ip_ep.py b/example/ML605/fpga/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/ML605/fpga/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/ML605/fpga/tb/test_fpga_core.py b/example/ML605/fpga/tb/test_fpga_core.py new file mode 100755 index 000000000..a4d621023 --- /dev/null +++ b/example/ML605/fpga/tb/test_fpga_core.py @@ -0,0 +1,316 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import eth_ep +import arp_ep +import udp_ep +import gmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/iddr.v") +srcs.append("../lib/eth/rtl/oddr.v") +srcs.append("../lib/eth/rtl/ssio_sdr_in.v") +srcs.append("../lib/eth/rtl/ssio_sdr_out.v") +srcs.append("../lib/eth/rtl/gmii_phy_if.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen.v") +srcs.append("../lib/eth/rtl/udp.v") +srcs.append("../lib/eth/rtl/udp_ip_rx.v") +srcs.append("../lib/eth/rtl/udp_ip_tx.v") +srcs.append("../lib/eth/rtl/ip_complete.v") +srcs.append("../lib/eth/rtl/ip.v") +srcs.append("../lib/eth/rtl/ip_eth_rx.v") +srcs.append("../lib/eth/rtl/ip_eth_tx.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") +srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") +srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + TARGET = "SIM" + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + clk_125mhz = Signal(bool(0)) + rst_125mhz = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[8:]) + phy_rx_clk = Signal(bool(0)) + phy_rxd = Signal(intbv(0)[8:]) + phy_rx_dv = Signal(bool(0)) + phy_rx_er = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + + # Outputs + ledu = Signal(bool(0)) + ledl = Signal(bool(0)) + ledd = Signal(bool(0)) + ledr = Signal(bool(0)) + ledc = Signal(bool(0)) + led = Signal(intbv(0)[8:]) + phy_gtx_clk = Signal(bool(0)) + phy_txd = Signal(intbv(0)[8:]) + phy_tx_en = Signal(bool(0)) + phy_tx_er = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_rxd = Signal(bool(0)) + uart_cts = Signal(bool(0)) + + # sources and sinks + gmii_source = gmii_ep.GMIISource() + + gmii_source_logic = gmii_source.create_logic( + phy_rx_clk, + rst, + txd=phy_rxd, + tx_en=phy_rx_dv, + tx_er=phy_rx_er, + name='gmii_source' + ) + + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + phy_gtx_clk, + rst, + rxd=phy_txd, + rx_dv=phy_tx_en, + rx_er=phy_tx_er, + name='gmii_sink' + ) + + # DUT + if os.system(build_cmd): + raise Exception("Error running build command") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk_125mhz=clk_125mhz, + rst_125mhz=rst_125mhz, + current_test=current_test, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + ledu=ledu, + ledl=ledl, + ledd=ledd, + ledr=ledr, + ledc=ledc, + led=led, + + phy_rx_clk=phy_rx_clk, + phy_rxd=phy_rxd, + phy_rx_dv=phy_rx_dv, + phy_rx_er=phy_rx_er, + phy_gtx_clk=phy_gtx_clk, + phy_txd=phy_txd, + phy_tx_en=phy_tx_en, + phy_tx_er=phy_tx_er, + phy_reset_n=phy_reset_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + clk_125mhz.next = not clk_125mhz + phy_rx_clk.next = not phy_rx_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + rst_125mhz.next = 1 + yield clk.posedge + rst.next = 0 + rst_125mhz.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source.empty() + assert gmii_sink.empty() + + yield delay(100) + + raise StopSimulation + + return dut, gmii_source_logic, gmii_sink_logic, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/ML605/fpga/tb/test_fpga_core.v b/example/ML605/fpga/tb/test_fpga_core.v new file mode 100644 index 000000000..10a0e8341 --- /dev/null +++ b/example/ML605/fpga/tb/test_fpga_core.v @@ -0,0 +1,143 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters +parameter TARGET = "SIM"; + +// Inputs +reg clk_125mhz = 0; +reg rst_125mhz = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [7:0] sw = 0; +reg phy_rx_clk = 0; +reg [7:0] phy_rxd = 0; +reg phy_rx_dv = 0; +reg phy_rx_er = 0; +reg uart_txd = 0; +reg uart_rts = 0; + +// Outputs +wire ledu; +wire ledl; +wire ledd; +wire ledr; +wire ledc; +wire [7:0] led; +wire phy_gtx_clk; +wire [7:0] phy_txd; +wire phy_tx_en; +wire phy_tx_er; +wire phy_reset_n; +wire uart_rxd; +wire uart_cts; + +initial begin + // myhdl integration + $from_myhdl( + clk_125mhz, + rst_125mhz, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_rx_clk, + phy_rxd, + phy_rx_dv, + phy_rx_er, + uart_txd, + uart_rts + ); + $to_myhdl( + ledu, + ledl, + ledd, + ledr, + ledc, + led, + phy_gtx_clk, + phy_txd, + phy_tx_en, + phy_tx_er, + phy_reset_n, + uart_rxd, + uart_cts + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core #( + .TARGET(TARGET) +) +UUT ( + .clk_125mhz(clk_125mhz), + .rst_125mhz(rst_125mhz), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .ledu(ledu), + .ledl(ledl), + .ledd(ledd), + .ledr(ledr), + .ledc(ledc), + .led(led), + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_dv(phy_rx_dv), + .phy_rx_er(phy_rx_er), + .phy_gtx_clk(phy_gtx_clk), + .phy_txd(phy_txd), + .phy_tx_en(phy_tx_en), + .phy_tx_er(phy_tx_er), + .phy_reset_n(phy_reset_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts) +); + +endmodule diff --git a/example/ML605/fpga/tb/udp_ep.py b/example/ML605/fpga/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/ML605/fpga/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file From 0fc986041e9a936aaa3c21c0d54c2a669316995b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 19 May 2017 17:44:29 -0700 Subject: [PATCH 327/617] Fix example design LED logic --- example/ATLYS/fpga/rtl/fpga_core.v | 11 ++++++++--- example/DE5-Net/fpga/rtl/fpga_core.v | 11 ++++++++--- example/HXT100G/fpga/rtl/fpga_core.v | 11 ++++++++--- example/ML605/fpga/rtl/fpga_core.v | 11 ++++++++--- example/NexysVideo/fpga/rtl/fpga_core.v | 11 ++++++++--- example/VCU108/fpga_1g/rtl/fpga_core.v | 11 ++++++++--- 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index 9b22dbf47..90ffd07e5 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -304,9 +304,14 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - valid_last <= tx_udp_payload_tvalid; - if (tx_udp_payload_tvalid & ~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_tvalid) begin + if (~valid_last) begin + led_reg <= tx_udp_payload_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_tlast) begin + valid_last <= 1'b0; + end end end end diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index 8888af3d8..f3922f5a5 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -304,9 +304,14 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - valid_last <= tx_udp_payload_tvalid; - if (tx_udp_payload_tvalid & ~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_tvalid) begin + if (~valid_last) begin + led_reg <= tx_udp_payload_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_tlast) begin + valid_last <= 1'b0; + end end end end diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v index 64b36d8b9..c4497aea1 100644 --- a/example/HXT100G/fpga/rtl/fpga_core.v +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -410,9 +410,14 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - valid_last <= tx_udp_payload_tvalid; - if (tx_udp_payload_tvalid & ~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_tvalid) begin + if (~valid_last) begin + led_reg <= tx_udp_payload_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_tlast) begin + valid_last <= 1'b0; + end end end end diff --git a/example/ML605/fpga/rtl/fpga_core.v b/example/ML605/fpga/rtl/fpga_core.v index c2fda6a19..1337a3b8f 100644 --- a/example/ML605/fpga/rtl/fpga_core.v +++ b/example/ML605/fpga/rtl/fpga_core.v @@ -311,9 +311,14 @@ always @(posedge clk_125mhz) begin if (rst_125mhz) begin led_reg <= 0; end else begin - valid_last <= tx_udp_payload_tvalid; - if (tx_udp_payload_tvalid & ~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_tvalid) begin + if (~valid_last) begin + led_reg <= tx_udp_payload_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_tlast) begin + valid_last <= 1'b0; + end end end end diff --git a/example/NexysVideo/fpga/rtl/fpga_core.v b/example/NexysVideo/fpga/rtl/fpga_core.v index 15586bc2e..a50935404 100644 --- a/example/NexysVideo/fpga/rtl/fpga_core.v +++ b/example/NexysVideo/fpga/rtl/fpga_core.v @@ -305,9 +305,14 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - valid_last <= tx_udp_payload_tvalid; - if (tx_udp_payload_tvalid & ~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_tvalid) begin + if (~valid_last) begin + led_reg <= tx_udp_payload_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_tlast) begin + valid_last <= 1'b0; + end end end end diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v index 3798867f6..b90780ef2 100644 --- a/example/VCU108/fpga_1g/rtl/fpga_core.v +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -291,9 +291,14 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - valid_last <= tx_udp_payload_tvalid; - if (tx_udp_payload_tvalid & ~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_tvalid) begin + if (~valid_last) begin + led_reg <= tx_udp_payload_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_tlast) begin + valid_last <= 1'b0; + end end end end From b0a4448e69fcafeb7f73580498d70a2371e6c2f7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 May 2017 16:08:05 -0700 Subject: [PATCH 328/617] Add clk_enable and mii_select inputs to GMII and RGMII endpoints --- tb/gmii_ep.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- tb/rgmii_ep.py | 11 ++++++++--- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index cafaef9bf..0622a3a18 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -73,6 +73,7 @@ class GMIIFrame(object): def __eq__(self, other): if type(other) is GMIIFrame: return self.data == other.data + return False def __repr__(self): return 'GMIIFrame(data=%s, error=%s)' % (repr(self.data), repr(self.error)) @@ -101,6 +102,8 @@ class GMIISource(object): txd, tx_en, tx_er, + clk_enable=True, + mii_select=False, name=None ): @@ -129,7 +132,9 @@ class GMIISource(object): er = [] ifg_cnt = 0 else: - if ifg_cnt > 0: + if not clk_enable: + pass + elif ifg_cnt > 0: ifg_cnt -= 1 txd.next = 0 tx_er.next = 0 @@ -139,12 +144,26 @@ class GMIISource(object): tx_er.next = er.pop(0) tx_en.next = 1 if len(d) == 0: - ifg_cnt = 12 + if mii_select: + ifg_cnt = 12*2 + else: + ifg_cnt = 12 elif len(self.queue) > 0: frame = GMIIFrame(self.queue.pop(0)) d, er = frame.build() if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) + if mii_select: + d2 = [] + for b in d: + d2.append(b & 0x0F) + d2.append(b >> 4) + d = d2 + er2 = [] + for b in er: + er2.append(b) + er2.append(b) + er = er2 txd.next = d.pop(0) tx_er.next = er.pop(0) tx_en.next = 1 @@ -178,6 +197,8 @@ class GMIISink(object): rxd, rx_dv, rx_er, + clk_enable=True, + mii_select=False, name=None ): @@ -201,7 +222,9 @@ class GMIISink(object): d = [] er = [] else: - if rx_dv: + if not clk_enable: + pass + elif rx_dv: if frame is None: frame = GMIIFrame() d = [] @@ -210,6 +233,26 @@ class GMIISink(object): er.append(int(rx_er)) elif frame is not None: if len(d) > 0: + if mii_select: + odd = True + sync = False + b = 0 + be = 0 + d2 = [] + er2 = [] + for n, e in zip(d, er): + odd = not odd + b = (n & 0x0F) << 4 | b >> 4 + be |= e + if not sync and b == 0xD5: + odd = True + sync = True + if odd: + d2.append(b) + er2.append(be) + be = False + d = d2 + er = er2 frame.parse(d, er) self.queue.append(frame) if name is not None: diff --git a/tb/rgmii_ep.py b/tb/rgmii_ep.py index 609827fe1..b4f689887 100644 --- a/tb/rgmii_ep.py +++ b/tb/rgmii_ep.py @@ -32,6 +32,8 @@ class RGMIISource(gmii_ep.GMIISource): rst, txd, tx_ctl, + clk_enable=True, + mii_select=False, name=None ): @@ -45,7 +47,7 @@ class RGMIISource(gmii_ep.GMIISource): gmii_tx_en_reg = Signal(bool(0)) gmii_tx_er_reg = Signal(bool(0)) - gmii_source = super(RGMIISource, self).create_logic(clk, rst, gmii_txd, gmii_tx_en, gmii_tx_er, name) + gmii_source = super(RGMIISource, self).create_logic(clk, rst, gmii_txd, gmii_tx_en, gmii_tx_er, clk_enable, mii_select, name) @instance def logic(): @@ -54,7 +56,8 @@ class RGMIISource(gmii_ep.GMIISource): txd.next = gmii_txd_reg[4:0] tx_ctl.next = gmii_tx_en_reg yield clk.posedge - txd.next = gmii_txd_reg[8:4] + if not mii_select: + txd.next = gmii_txd_reg[8:4] tx_ctl.next = gmii_tx_en_reg ^ gmii_tx_er_reg gmii_txd_reg.next = gmii_txd gmii_tx_en_reg.next = gmii_tx_en @@ -69,6 +72,8 @@ class RGMIISink(gmii_ep.GMIISink): rst, rxd, rx_ctl, + clk_enable=True, + mii_select=False, name=None ): @@ -78,7 +83,7 @@ class RGMIISink(gmii_ep.GMIISink): gmii_rx_dv = Signal(bool(0)) gmii_rx_er = Signal(bool(0)) - gmii_sink = super(RGMIISink, self).create_logic(clk, rst, gmii_rxd, gmii_rx_dv, gmii_rx_er, name) + gmii_sink = super(RGMIISink, self).create_logic(clk, rst, gmii_rxd, gmii_rx_dv, gmii_rx_er, clk_enable, mii_select, name) @instance def logic(): From 817e7c2667c4713e31effe693243e934e79a799e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 May 2017 16:11:20 -0700 Subject: [PATCH 329/617] Add AXI stream GMII RX and TX modules and testbenches --- rtl/axis_gmii_rx.v | 313 +++++++++++++++++++++++++++++ rtl/axis_gmii_tx.v | 376 +++++++++++++++++++++++++++++++++++ tb/test_axis_gmii_rx.py | 430 ++++++++++++++++++++++++++++++++++++++++ tb/test_axis_gmii_rx.v | 99 +++++++++ tb/test_axis_gmii_tx.py | 382 +++++++++++++++++++++++++++++++++++ tb/test_axis_gmii_tx.v | 103 ++++++++++ 6 files changed, 1703 insertions(+) create mode 100644 rtl/axis_gmii_rx.v create mode 100644 rtl/axis_gmii_tx.v create mode 100755 tb/test_axis_gmii_rx.py create mode 100644 tb/test_axis_gmii_rx.v create mode 100755 tb/test_axis_gmii_tx.py create mode 100644 tb/test_axis_gmii_tx.v diff --git a/rtl/axis_gmii_rx.v b/rtl/axis_gmii_rx.v new file mode 100644 index 000000000..7c4662b7f --- /dev/null +++ b/rtl/axis_gmii_rx.v @@ -0,0 +1,313 @@ +/* + +Copyright (c) 2015-2017 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 GMII frame receiver (GMII in, AXI out) + */ +module axis_gmii_rx +( + input wire clk, + input wire rst, + + /* + * GMII input + */ + input wire [7:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, + + /* + * AXI output + */ + output wire [7:0] output_axis_tdata, + output wire output_axis_tvalid, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Control + */ + input wire clk_enable, + input wire mii_select, + + /* + * Status + */ + output wire error_bad_frame, + output wire error_bad_fcs +); + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PAYLOAD = 3'd1, + STATE_WAIT_LAST = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg mii_odd = 1'b0; +reg mii_locked = 1'b0; + +reg [7:0] gmii_rxd_d0 = 8'd0; +reg [7:0] gmii_rxd_d1 = 8'd0; +reg [7:0] gmii_rxd_d2 = 8'd0; +reg [7:0] gmii_rxd_d3 = 8'd0; +reg [7:0] gmii_rxd_d4 = 8'd0; + +reg gmii_rx_dv_d0 = 1'b0; +reg gmii_rx_dv_d1 = 1'b0; +reg gmii_rx_dv_d2 = 1'b0; +reg gmii_rx_dv_d3 = 1'b0; +reg gmii_rx_dv_d4 = 1'b0; + +reg gmii_rx_er_d0 = 1'b0; +reg gmii_rx_er_d1 = 1'b0; +reg gmii_rx_er_d2 = 1'b0; +reg gmii_rx_er_d3 = 1'b0; +reg gmii_rx_er_d4 = 1'b0; + +reg [7:0] output_axis_tdata_reg = 8'd0, output_axis_tdata_next; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0, output_axis_tlast_next; +reg output_axis_tuser_reg = 1'b0, output_axis_tuser_next; + +reg error_bad_frame_reg = 1'b0, error_bad_frame_next; +reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; +wire [31:0] crc_next; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +assign error_bad_frame = error_bad_frame_reg; +assign error_bad_fcs = error_bad_fcs_reg; + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( + .data_in(gmii_rxd_d4), + .lfsr_in(crc_state), + .lfsr_out(crc_next) +); + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 1'b0; + update_crc = 1'b0; + + output_axis_tdata_next = 8'd0; + output_axis_tvalid_next = 1'b0; + output_axis_tlast_next = 1'b0; + output_axis_tuser_next = 1'b0; + + error_bad_frame_next = 1'b0; + error_bad_fcs_next = 1'b0; + + if (!clk_enable) begin + // clock disabled - hold state + state_next = state_reg; + end else if (mii_select & ~mii_odd) begin + // MII even cycle - hold state + state_next = state_reg; + end else begin + case (state_reg) + STATE_IDLE: begin + // idle state - wait for packet + reset_crc = 1'b1; + + if (gmii_rx_dv_d4 && ~gmii_rx_er_d4 && gmii_rxd_d4 == 8'hD5) begin + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // read payload + update_crc = 1'b1; + + output_axis_tdata_next = gmii_rxd_d4; + output_axis_tvalid_next = 1'b1; + + if (gmii_rx_dv_d4 & gmii_rx_er_d4) begin + // error + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + state_next = STATE_WAIT_LAST; + end else if (~gmii_rx_dv) begin + // end of packet + output_axis_tlast_next = 1'b1; + if (gmii_rx_er_d0 | gmii_rx_er_d1 | gmii_rx_er_d2 | gmii_rx_er_d3) begin + // error received in FCS bytes + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + end else if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin + // FCS good + output_axis_tuser_next = 1'b0; + end else begin + // FCS bad + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; + end + state_next = STATE_IDLE; + end else begin + state_next = STATE_PAYLOAD; + end + end + STATE_WAIT_LAST: begin + // wait for end of packet + + if (~gmii_rx_dv) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + output_axis_tvalid_reg <= 1'b0; + + error_bad_frame_reg <= 1'b0; + error_bad_fcs_reg <= 1'b0; + + crc_state <= 32'hFFFFFFFF; + + mii_locked <= 1'b0; + mii_odd <= 1'b0; + + gmii_rx_dv_d0 <= 1'b0; + gmii_rx_dv_d1 <= 1'b0; + gmii_rx_dv_d2 <= 1'b0; + gmii_rx_dv_d3 <= 1'b0; + gmii_rx_dv_d4 <= 1'b0; + end else begin + state_reg <= state_next; + + output_axis_tvalid_reg <= output_axis_tvalid_next; + + error_bad_frame_reg <= error_bad_frame_next; + error_bad_fcs_reg <= error_bad_fcs_next; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next; + end + + if (clk_enable) begin + if (mii_select) begin + mii_odd <= ~mii_odd; + + if (mii_locked) begin + mii_locked <= gmii_rx_dv; + end else if (gmii_rx_dv & {gmii_rxd[3:0], gmii_rxd_d0[7:4]} == 8'hD5) begin + mii_locked <= 1'b1; + mii_odd <= 1'b1; + end + + if (mii_odd) begin + gmii_rx_dv_d0 <= gmii_rx_dv & gmii_rx_dv_d0; + gmii_rx_dv_d1 <= gmii_rx_dv_d0 & gmii_rx_dv; + gmii_rx_dv_d2 <= gmii_rx_dv_d1 & gmii_rx_dv; + gmii_rx_dv_d3 <= gmii_rx_dv_d2 & gmii_rx_dv; + gmii_rx_dv_d4 <= gmii_rx_dv_d3 & gmii_rx_dv; + end else begin + gmii_rx_dv_d0 <= gmii_rx_dv; + end + end else begin + gmii_rx_dv_d0 <= gmii_rx_dv; + gmii_rx_dv_d1 <= gmii_rx_dv_d0 & gmii_rx_dv; + gmii_rx_dv_d2 <= gmii_rx_dv_d1 & gmii_rx_dv; + gmii_rx_dv_d3 <= gmii_rx_dv_d2 & gmii_rx_dv; + gmii_rx_dv_d4 <= gmii_rx_dv_d3 & gmii_rx_dv; + end + end + end + + output_axis_tdata_reg <= output_axis_tdata_next; + output_axis_tlast_reg <= output_axis_tlast_next; + output_axis_tuser_reg <= output_axis_tuser_next; + + // delay input + if (clk_enable) begin + if (mii_select) begin + gmii_rxd_d0 <= {gmii_rxd[3:0], gmii_rxd_d0[7:4]}; + + if (mii_odd) begin + gmii_rxd_d1 <= gmii_rxd_d0; + gmii_rxd_d2 <= gmii_rxd_d1; + gmii_rxd_d3 <= gmii_rxd_d2; + gmii_rxd_d4 <= gmii_rxd_d3; + + gmii_rx_er_d0 <= gmii_rx_er | gmii_rx_er_d0; + gmii_rx_er_d1 <= gmii_rx_er_d0; + gmii_rx_er_d2 <= gmii_rx_er_d1; + gmii_rx_er_d3 <= gmii_rx_er_d2; + gmii_rx_er_d4 <= gmii_rx_er_d3; + end else begin + gmii_rx_er_d0 <= gmii_rx_er; + end + end else begin + gmii_rxd_d0 <= gmii_rxd; + gmii_rxd_d1 <= gmii_rxd_d0; + gmii_rxd_d2 <= gmii_rxd_d1; + gmii_rxd_d3 <= gmii_rxd_d2; + gmii_rxd_d4 <= gmii_rxd_d3; + + gmii_rx_er_d0 <= gmii_rx_er; + gmii_rx_er_d1 <= gmii_rx_er_d0; + gmii_rx_er_d2 <= gmii_rx_er_d1; + gmii_rx_er_d3 <= gmii_rx_er_d2; + gmii_rx_er_d4 <= gmii_rx_er_d3; + end + end +end + +endmodule diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v new file mode 100644 index 000000000..680cc8f8c --- /dev/null +++ b/rtl/axis_gmii_tx.v @@ -0,0 +1,376 @@ +/* + +Copyright (c) 2015-2017 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 GMII frame transmitter (AXI in, GMII out) + */ +module axis_gmii_tx # +( + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [7:0] input_axis_tdata, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * GMII output + */ + output wire [7:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * Control + */ + input wire clk_enable, + input wire mii_select, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PREAMBLE = 3'd1, + STATE_PAYLOAD = 3'd2, + STATE_LAST = 3'd3, + STATE_PAD = 3'd4, + STATE_FCS = 3'd5, + STATE_WAIT_END = 3'd6, + STATE_IFG = 3'd7; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg [7:0] input_tdata_reg = 8'd0, input_tdata_next; + +reg mii_odd_reg = 1'b0, mii_odd_next; +reg [3:0] mii_msn_reg = 4'b0, mii_msn_next; + +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; + +reg [7:0] gmii_txd_reg = 8'd0, gmii_txd_next; +reg gmii_tx_en_reg = 1'b0, gmii_tx_en_next; +reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next; + +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; +wire [31:0] crc_next; + +assign input_axis_tready = input_axis_tready_reg; + +assign gmii_txd = gmii_txd_reg; +assign gmii_tx_en = gmii_tx_en_reg; +assign gmii_tx_er = gmii_tx_er_reg; + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .REVERSE(1), + .DATA_WIDTH(8), + .OUTPUT_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_8 ( + .data_in(input_tdata_reg), + .lfsr_in(crc_state), + .lfsr_out(crc_next) +); + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 1'b0; + update_crc = 1'b0; + + mii_odd_next = mii_odd_reg; + mii_msn_next = mii_msn_reg; + + frame_ptr_next = frame_ptr_reg; + + input_axis_tready_next = 1'b0; + + input_tdata_next = input_tdata_reg; + + gmii_txd_next = 8'd0; + gmii_tx_en_next = 1'b0; + gmii_tx_er_next = 1'b0; + + if (!clk_enable) begin + // clock disabled - hold state and outputs + gmii_txd_next = gmii_txd_reg; + gmii_tx_en_next = gmii_tx_en_reg; + gmii_tx_er_next = gmii_tx_er_reg; + state_next = state_reg; + end else if (mii_select & mii_odd_reg) begin + // MII odd cycle - hold state, output MSN + mii_odd_next = 1'b0; + gmii_txd_next = {4'd0, mii_msn_reg}; + gmii_tx_en_next = gmii_tx_en_reg; + gmii_tx_er_next = gmii_tx_er_reg; + state_next = state_reg; + end else begin + case (state_reg) + STATE_IDLE: begin + // idle state - wait for packet + reset_crc = 1'b1; + mii_odd_next = 1'b0; + + if (input_axis_tvalid) begin + mii_odd_next = 1'b1; + frame_ptr_next = 16'd1; + gmii_txd_next = 8'h55; // Preamble + gmii_tx_en_next = 1'b1; + state_next = STATE_PREAMBLE; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PREAMBLE: begin + // send preamble + reset_crc = 1'b1; + + mii_odd_next = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd1; + + gmii_txd_next = 8'h55; // Preamble + gmii_tx_en_next = 1'b1; + + if (frame_ptr_reg == 16'd6) begin + input_axis_tready_next = 1'b1; + input_tdata_next = input_axis_tdata; + state_next = STATE_PREAMBLE; + end else if (frame_ptr_reg == 16'd7) begin + // end of preamble; start payload + frame_ptr_next = 16'd0; + if (input_axis_tready_reg) begin + input_axis_tready_next = 1'b1; + input_tdata_next = input_axis_tdata; + end + gmii_txd_next = 8'hD5; // SFD + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_PREAMBLE; + end + end + STATE_PAYLOAD: begin + // send payload + + update_crc = 1'b1; + input_axis_tready_next = 1'b1; + + mii_odd_next = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd1; + + gmii_txd_next = input_tdata_reg; + gmii_tx_en_next = 1'b1; + + input_tdata_next = input_axis_tdata; + + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + input_axis_tready_next = ~input_axis_tready_reg; + if (input_axis_tuser) begin + gmii_tx_er_next = 1'b1; + frame_ptr_next = 1'b0; + state_next = STATE_IFG; + end else begin + state_next = STATE_LAST; + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + // tvalid deassert, fail frame + gmii_tx_er_next = 1'b1; + frame_ptr_next = 16'd0; + state_next = STATE_WAIT_END; + end + end + STATE_LAST: begin + // last payload word + + update_crc = 1'b1; + + mii_odd_next = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd1; + + gmii_txd_next = input_tdata_reg; + gmii_tx_en_next = 1'b1; + + if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin + input_tdata_next = 8'd0; + state_next = STATE_PAD; + end else begin + frame_ptr_next = 16'd0; + state_next = STATE_FCS; + end + end + STATE_PAD: begin + // send padding + + update_crc = 1'b1; + mii_odd_next = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd1; + + gmii_txd_next = 8'd0; + gmii_tx_en_next = 1'b1; + + input_tdata_next = 8'd0; + + if (frame_ptr_reg < MIN_FRAME_LENGTH-5) begin + state_next = STATE_PAD; + end else begin + frame_ptr_next = 16'd0; + state_next = STATE_FCS; + end + end + STATE_FCS: begin + // send FCS + + mii_odd_next = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd1; + + case (frame_ptr_reg) + 2'd0: gmii_txd_next = ~crc_state[7:0]; + 2'd1: gmii_txd_next = ~crc_state[15:8]; + 2'd2: gmii_txd_next = ~crc_state[23:16]; + 2'd3: gmii_txd_next = ~crc_state[31:24]; + endcase + gmii_tx_en_next = 1'b1; + + if (frame_ptr_reg < 3) begin + state_next = STATE_FCS; + end else begin + frame_ptr_next = 16'd0; + state_next = STATE_IFG; + end + end + STATE_WAIT_END: begin + // wait for end of frame + + reset_crc = 1'b1; + + mii_odd_next = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd1; + input_axis_tready_next = 1'b1; + + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + input_axis_tready_next = 1'b0; + if (frame_ptr_reg < ifg_delay-1) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_WAIT_END; + end + end else begin + state_next = STATE_WAIT_END; + end + end + STATE_IFG: begin + // send IFG + + reset_crc = 1'b1; + + mii_odd_next = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd1; + + if (frame_ptr_reg < ifg_delay-1) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end + endcase + + if (mii_select) begin + mii_msn_next = gmii_txd_next[7:4]; + gmii_txd_next[7:4] = 4'd0; + end + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 16'd0; + + input_axis_tready_reg <= 1'b0; + + gmii_tx_en_reg <= 1'b0; + gmii_tx_er_reg <= 1'b0; + + crc_state <= 32'hFFFFFFFF; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + input_axis_tready_reg <= input_axis_tready_next; + + gmii_tx_en_reg <= gmii_tx_en_next; + gmii_tx_er_reg <= gmii_tx_er_next; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next; + end + end + + mii_odd_reg <= mii_odd_next; + mii_msn_reg <= mii_msn_next; + + input_tdata_reg <= input_tdata_next; + + gmii_txd_reg <= gmii_txd_next; +end + +endmodule diff --git a/tb/test_axis_gmii_rx.py b/tb/test_axis_gmii_rx.py new file mode 100755 index 000000000..bdfc3078c --- /dev/null +++ b/tb/test_axis_gmii_rx.py @@ -0,0 +1,430 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import axis_ep +import eth_ep +import gmii_ep + +module = 'axis_gmii_rx' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + gmii_rxd = Signal(intbv(0)[8:]) + gmii_rx_dv = Signal(bool(0)) + gmii_rx_er = Signal(bool(0)) + clk_enable = Signal(bool(1)) + mii_select = Signal(bool(0)) + + # Outputs + output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + error_bad_frame = Signal(bool(0)) + error_bad_fcs = Signal(bool(0)) + + # sources and sinks + source = gmii_ep.GMIISource() + + source_logic = source.create_logic( + clk, + rst, + txd=gmii_rxd, + tx_en=gmii_rx_dv, + tx_er=gmii_rx_er, + clk_enable=clk_enable, + mii_select=mii_select, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tvalid=output_axis_tvalid, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + 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, + + gmii_rxd=gmii_rxd, + gmii_rx_dv=gmii_rx_dv, + gmii_rx_er=gmii_rx_er, + + output_axis_tdata=output_axis_tdata, + output_axis_tvalid=output_axis_tvalid, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + clk_enable=clk_enable, + mii_select=mii_select, + + error_bad_frame=error_bad_frame, + error_bad_fcs=error_bad_fcs + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_bad_frame_asserted = Signal(bool(0)) + error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_bad_frame): + error_bad_frame_asserted.next = 1 + if (error_bad_fcs): + error_bad_fcs_asserted.next = 1 + + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @always(clk.posedge) + def clk_enable_gen(): + if clk_enable_div.next > 0: + clk_enable.next = 0 + clk_enable_div.next = clk_enable_div - 1 + else: + clk_enable.next = 1 + clk_enable_div.next = clk_enable_rate - 1 + + @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 rate, mii in [(1, 0), (10, 0), (5, 1)]: + clk_enable_rate.next = rate + mii_select.next = mii + + yield delay(100) + + for payload_len in list(range(1,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + gmii_frame = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + source.send(gmii_frame) + yield clk.posedge + yield clk.posedge + + while not clk_enable or not gmii_rx_dv: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_rx_dv or output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + gmii_frame1 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + gmii_frame2 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source.send(gmii_frame1) + source.send(gmii_frame2) + yield clk.posedge + yield clk.posedge + + while not clk_enable or not gmii_rx_dv: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_rx_dv or output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + + while not clk_enable or not gmii_rx_dv: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_rx_dv or output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame1 + + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: truncated frame, length %d" % payload_len) + current_test.next = 3 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + axis_frame1.data = axis_frame1.data[:-1] + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + gmii_frame1 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + gmii_frame2 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source.send(gmii_frame1) + source.send(gmii_frame2) + yield clk.posedge + yield clk.posedge + + while not clk_enable or not gmii_rx_dv: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_rx_dv or output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + + while not clk_enable or not gmii_rx_dv: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_rx_dv or output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_bad_frame_asserted + assert error_bad_fcs_asserted + + rx_frame = sink.recv() + + assert rx_frame.user[-1] + + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: errored frame, length %d" % payload_len) + current_test.next = 4 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + gmii_frame1 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + gmii_frame2 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + gmii_frame1.error = 1 + + source.send(gmii_frame1) + source.send(gmii_frame2) + yield clk.posedge + yield clk.posedge + + while not clk_enable or not gmii_rx_dv: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_rx_dv or output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + + while not clk_enable or not gmii_rx_dv: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_rx_dv or output_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + assert error_bad_frame_asserted + assert not error_bad_fcs_asserted + + rx_frame = sink.recv() + + assert rx_frame.user[-1] + + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + raise StopSimulation + + return dut, monitor, source_logic, sink_logic, clkgen, clk_enable_gen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_gmii_rx.v b/tb/test_axis_gmii_rx.v new file mode 100644 index 000000000..5a15721f7 --- /dev/null +++ b/tb/test_axis_gmii_rx.v @@ -0,0 +1,99 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for axis_gmii_rx + */ +module test_axis_gmii_rx; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] gmii_rxd = 0; +reg gmii_rx_dv = 0; +reg gmii_rx_er = 0; + +reg clk_enable = 1; +reg mii_select = 0; + +// Outputs +wire [7:0] output_axis_tdata; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; +wire error_bad_frame; +wire error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + clk_enable, + mii_select + ); + $to_myhdl( + output_axis_tdata, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + error_bad_frame, + error_bad_fcs + ); + + // dump file + $dumpfile("test_axis_gmii_rx.lxt"); + $dumpvars(0, test_axis_gmii_rx); +end + +axis_gmii_rx +UUT ( + .clk(clk), + .rst(rst), + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .output_axis_tdata(output_axis_tdata), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + .clk_enable(clk_enable), + .mii_select(mii_select), + .error_bad_frame(error_bad_frame), + .error_bad_fcs(error_bad_fcs) +); + +endmodule diff --git a/tb/test_axis_gmii_tx.py b/tb/test_axis_gmii_tx.py new file mode 100755 index 000000000..d27c6c7cd --- /dev/null +++ b/tb/test_axis_gmii_tx.py @@ -0,0 +1,382 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import axis_ep +import eth_ep +import gmii_ep + +module = 'axis_gmii_tx' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # 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)) + clk_enable = Signal(bool(1)) + mii_select = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + input_axis_tready = Signal(bool(0)) + gmii_txd = Signal(intbv(0)[8:]) + gmii_tx_en = Signal(bool(0)) + gmii_tx_er = Signal(bool(0)) + + # sources and sinks + source_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource() + + source_logic = source.create_logic( + clk, + rst, + tdata=input_axis_tdata, + tvalid=input_axis_tvalid, + tready=input_axis_tready, + tlast=input_axis_tlast, + tuser=input_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = gmii_ep.GMIISink() + + sink_logic = sink.create_logic( + clk, + rst, + rxd=gmii_txd, + rx_dv=gmii_tx_en, + rx_er=gmii_tx_er, + clk_enable=clk_enable, + mii_select=mii_select, + 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, + + 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, + + gmii_txd=gmii_txd, + gmii_tx_en=gmii_tx_en, + gmii_tx_er=gmii_tx_er, + + clk_enable=clk_enable, + mii_select=mii_select, + + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + clk_enable_rate = Signal(int(1)) + clk_enable_div = Signal(int(0)) + + @always(clk.posedge) + def clk_enable_gen(): + if clk_enable_div.next > 0: + clk_enable.next = 0 + clk_enable_div.next = clk_enable_div - 1 + else: + clk_enable.next = 1 + clk_enable_div.next = clk_enable_rate - 1 + + @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 + + ifg_delay.next = 12 + + # testbench stimulus + + for rate, mii in [(1, 0), (10, 0), (5, 1)]: + clk_enable_rate.next = rate + mii_select.next = mii + + yield delay(100) + + for payload_len in list(range(1,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source.send(axis_frame) + yield clk.posedge + yield clk.posedge + + while not clk_enable: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_tx_en or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + source.send(axis_frame1) + source.send(axis_frame2) + yield clk.posedge + yield clk.posedge + + while not clk_enable: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_tx_en or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + + while not clk_enable: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_tx_en or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame1.eth_src_mac + assert eth_frame.eth_type == test_frame1.eth_type + assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.user = 1 + + source.send(axis_frame1) + source.send(axis_frame2) + yield clk.posedge + yield clk.posedge + + while not clk_enable: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_tx_en or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + + while not clk_enable: + yield clk.posedge + yield clk.posedge + + while not clk_enable or gmii_tx_en or input_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.error[-1] + + # bad packet + + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink.empty() + + yield delay(100) + + raise StopSimulation + + return dut, source_logic, sink_logic, clkgen, clk_enable_gen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_gmii_tx.v b/tb/test_axis_gmii_tx.v new file mode 100644 index 000000000..b1dba252b --- /dev/null +++ b/tb/test_axis_gmii_tx.v @@ -0,0 +1,103 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for axis_gmii_tx + */ +module test_axis_gmii_tx; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; + +// 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 clk_enable = 1; +reg mii_select = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire input_axis_tready; +wire [7:0] gmii_txd; +wire gmii_tx_en; +wire gmii_tx_er; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + input_axis_tdata, + input_axis_tvalid, + input_axis_tlast, + input_axis_tuser, + clk_enable, + mii_select, + ifg_delay + ); + $to_myhdl( + input_axis_tready, + gmii_txd, + gmii_tx_en, + gmii_tx_er + ); + + // dump file + $dumpfile("test_axis_gmii_tx.lxt"); + $dumpvars(0, test_axis_gmii_tx); +end + +axis_gmii_tx #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .clk(clk), + .rst(rst), + .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), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + .clk_enable(clk_enable), + .mii_select(mii_select), + .ifg_delay(ifg_delay) +); + +endmodule From 8ff4312601d06683543bce6ac0c4937a79d9111a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 May 2017 18:37:33 -0700 Subject: [PATCH 330/617] Update MAC modules to use new modules --- rtl/eth_mac_1g.v | 20 ++++- rtl/eth_mac_1g_fifo.v | 12 +++ tb/test_eth_mac_1g.py | 179 ++++++++++++++++++++++++------------- tb/test_eth_mac_1g.v | 12 +++ tb/test_eth_mac_1g_fifo.py | 176 ++++++++++++++++++++++-------------- tb/test_eth_mac_1g_fifo.v | 12 +++ 6 files changed, 279 insertions(+), 132 deletions(-) diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v index ecd7b1738..b46e31606 100644 --- a/rtl/eth_mac_1g.v +++ b/rtl/eth_mac_1g.v @@ -67,6 +67,14 @@ module eth_mac_1g # output wire gmii_tx_en, output wire gmii_tx_er, + /* + * Control + */ + input wire rx_clk_enable, + input wire tx_clk_enable, + input wire rx_mii_select, + input wire tx_mii_select, + /* * Status */ @@ -79,8 +87,8 @@ module eth_mac_1g # input wire [7:0] ifg_delay ); -eth_mac_1g_rx -eth_mac_1g_rx_inst ( +axis_gmii_rx +axis_gmii_rx_inst ( .clk(rx_clk), .rst(rx_rst), .gmii_rxd(gmii_rxd), @@ -90,15 +98,17 @@ eth_mac_1g_rx_inst ( .output_axis_tvalid(rx_axis_tvalid), .output_axis_tlast(rx_axis_tlast), .output_axis_tuser(rx_axis_tuser), + .clk_enable(rx_clk_enable), + .mii_select(rx_mii_select), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); -eth_mac_1g_tx #( +axis_gmii_tx #( .ENABLE_PADDING(ENABLE_PADDING), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) ) -eth_mac_1g_tx_inst ( +axis_gmii_tx_inst ( .clk(tx_clk), .rst(tx_rst), .input_axis_tdata(tx_axis_tdata), @@ -109,6 +119,8 @@ eth_mac_1g_tx_inst ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .clk_enable(tx_clk_enable), + .mii_select(tx_mii_select), .ifg_delay(ifg_delay) ); diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index 7d137ab30..b06ad34f3 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -72,6 +72,14 @@ module eth_mac_1g_fifo # output wire gmii_tx_en, output wire gmii_tx_er, + /* + * Control + */ + input wire rx_clk_enable, + input wire tx_clk_enable, + input wire rx_mii_select, + input wire tx_mii_select, + /* * Status */ @@ -157,6 +165,10 @@ eth_mac_1g_inst ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .rx_clk_enable(rx_clk_enable), + .tx_clk_enable(tx_clk_enable), + .rx_mii_select(rx_mii_select), + .tx_mii_select(tx_mii_select), .rx_error_bad_frame(rx_error_bad_frame_int), .rx_error_bad_fcs(rx_error_bad_fcs_int), .ifg_delay(ifg_delay) diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index 6f918e260..41050629a 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -37,8 +37,8 @@ srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/lfsr.v") -srcs.append("../rtl/eth_mac_1g_rx.v") -srcs.append("../rtl/eth_mac_1g_tx.v") +srcs.append("../rtl/axis_gmii_rx.v") +srcs.append("../rtl/axis_gmii_tx.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) @@ -67,6 +67,10 @@ def bench(): gmii_rxd = Signal(intbv(0)[8:]) gmii_rx_dv = Signal(bool(0)) gmii_rx_er = Signal(bool(0)) + rx_clk_enable = Signal(bool(1)) + tx_clk_enable = Signal(bool(1)) + rx_mii_select = Signal(bool(0)) + tx_mii_select = Signal(bool(0)) ifg_delay = Signal(intbv(0)[8:]) # Outputs @@ -92,6 +96,8 @@ def bench(): txd=gmii_rxd, tx_en=gmii_rx_dv, tx_er=gmii_rx_er, + clk_enable=rx_clk_enable, + mii_select=rx_mii_select, name='gmii_source' ) @@ -103,6 +109,8 @@ def bench(): rxd=gmii_txd, rx_dv=gmii_tx_en, rx_er=gmii_tx_er, + clk_enable=tx_clk_enable, + mii_select=tx_mii_select, name='gmii_sink' ) @@ -166,6 +174,12 @@ def bench(): gmii_tx_en=gmii_tx_en, gmii_tx_er=gmii_tx_er, + rx_clk_enable=rx_clk_enable, + tx_clk_enable=tx_clk_enable, + + rx_mii_select=rx_mii_select, + tx_mii_select=tx_mii_select, + rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, @@ -178,6 +192,30 @@ def bench(): tx_clk.next = not tx_clk rx_clk.next = not rx_clk + rx_error_bad_frame_asserted = Signal(bool(0)) + rx_error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_bad_frame): + rx_error_bad_frame_asserted.next = 1 + if (rx_error_bad_fcs): + rx_error_bad_fcs_asserted.next = 1 + + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @always(clk.posedge) + def clk_enable_gen(): + if clk_enable_div.next > 0: + rx_clk_enable.next = 0 + tx_clk_enable.next = 0 + clk_enable_div.next = clk_enable_div - 1 + else: + rx_clk_enable.next = 1 + tx_clk_enable.next = 1 + clk_enable_div.next = clk_enable_rate - 1 + @instance def check(): yield delay(100) @@ -197,84 +235,99 @@ def bench(): # testbench stimulus - yield clk.posedge - print("test 1: test rx packet") - current_test.next = 1 + for rate, mii in [(1, 0), (10, 0), (5, 1)]: + clk_enable_rate.next = rate + rx_mii_select.next = mii + tx_mii_select.next = mii - 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(range(32)) - test_frame.update_fcs() + yield clk.posedge + print("test 1: test rx packet") + current_test.next = 1 - axis_frame = test_frame.build_axis_fcs() + 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(range(32)) + test_frame.update_fcs() - gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield clk.posedge - yield clk.posedge + axis_frame = test_frame.build_axis_fcs() - while gmii_rx_dv or rx_axis_tvalid: + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + yield clk.posedge yield clk.posedge - yield clk.posedge - yield clk.posedge - - rx_frame = axis_sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: test tx packet") - current_test.next = 2 - - 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(range(32)) - test_frame.update_fcs() - - axis_frame = test_frame.build_axis() - - axis_source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - while gmii_tx_en or tx_axis_tvalid: + while not rx_clk_enable or not tx_clk_enable or not (gmii_rx_dv or gmii_tx_en): + yield clk.posedge yield clk.posedge - yield clk.posedge - yield clk.posedge + while not rx_clk_enable or not tx_clk_enable or gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: + yield clk.posedge - rx_frame = gmii_sink.recv() + yield clk.posedge + yield clk.posedge + yield clk.posedge - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + rx_frame = axis_sink.recv() - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() - print(hex(eth_frame.eth_fcs)) - print(hex(eth_frame.calc_fcs())) + assert eth_frame == test_frame - assert len(eth_frame.payload.data) == 46 - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame.eth_src_mac - assert eth_frame.eth_type == test_frame.eth_type - assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + yield delay(100) - yield delay(100) + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + yield clk.posedge + yield clk.posedge + + while not rx_clk_enable or not tx_clk_enable or not (gmii_rx_dv or gmii_tx_en): + yield clk.posedge + yield clk.posedge + + while not rx_clk_enable or not tx_clk_enable or gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: + yield clk.posedge + + yield clk.posedge + yield clk.posedge + yield clk.posedge + + rx_frame = gmii_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) raise StopSimulation - return dut, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, check + return dut, monitor, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_1g.v b/tb/test_eth_mac_1g.v index 4264110a9..dff830707 100644 --- a/tb/test_eth_mac_1g.v +++ b/tb/test_eth_mac_1g.v @@ -51,6 +51,10 @@ reg tx_axis_tuser = 0; reg [7:0] gmii_rxd = 0; reg gmii_rx_dv = 0; reg gmii_rx_er = 0; +reg rx_clk_enable = 1; +reg tx_clk_enable = 1; +reg rx_mii_select = 0; +reg tx_mii_select = 0; reg [7:0] ifg_delay = 0; // Outputs @@ -82,6 +86,10 @@ initial begin gmii_rxd, gmii_rx_dv, gmii_rx_er, + rx_clk_enable, + tx_clk_enable, + rx_mii_select, + tx_mii_select, ifg_delay ); $to_myhdl( @@ -126,6 +134,10 @@ UUT ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .rx_clk_enable(rx_clk_enable), + .tx_clk_enable(tx_clk_enable), + .rx_mii_select(rx_mii_select), + .tx_mii_select(tx_mii_select), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .ifg_delay(ifg_delay) diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py index 228f562cf..d9a2e94ac 100755 --- a/tb/test_eth_mac_1g_fifo.py +++ b/tb/test_eth_mac_1g_fifo.py @@ -37,8 +37,8 @@ srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/lfsr.v") -srcs.append("../rtl/eth_mac_1g_rx.v") -srcs.append("../rtl/eth_mac_1g_tx.v") +srcs.append("../rtl/axis_gmii_rx.v") +srcs.append("../rtl/axis_gmii_tx.v") srcs.append("../rtl/eth_mac_1g.v") srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") srcs.append("%s.v" % testbench) @@ -74,6 +74,10 @@ def bench(): gmii_rxd = Signal(intbv(0)[8:]) gmii_rx_dv = Signal(bool(0)) gmii_rx_er = Signal(bool(0)) + rx_clk_enable = Signal(bool(1)) + tx_clk_enable = Signal(bool(1)) + rx_mii_select = Signal(bool(0)) + tx_mii_select = Signal(bool(0)) ifg_delay = Signal(intbv(0)[8:]) # Outputs @@ -106,6 +110,8 @@ def bench(): txd=gmii_rxd, tx_en=gmii_rx_dv, tx_er=gmii_rx_er, + clk_enable=rx_clk_enable, + mii_select=rx_mii_select, name='gmii_source' ) @@ -117,6 +123,8 @@ def bench(): rxd=gmii_txd, rx_dv=gmii_tx_en, rx_er=gmii_tx_er, + clk_enable=tx_clk_enable, + mii_select=tx_mii_select, name='gmii_sink' ) @@ -185,6 +193,12 @@ def bench(): gmii_tx_en=gmii_tx_en, gmii_tx_er=gmii_tx_er, + rx_clk_enable=rx_clk_enable, + tx_clk_enable=tx_clk_enable, + + rx_mii_select=rx_mii_select, + tx_mii_select=tx_mii_select, + tx_fifo_overflow=tx_fifo_overflow, tx_fifo_bad_frame=tx_fifo_bad_frame, tx_fifo_good_frame=tx_fifo_good_frame, @@ -204,6 +218,30 @@ def bench(): rx_clk.next = not rx_clk logic_clk.next = not logic_clk + rx_error_bad_frame_asserted = Signal(bool(0)) + rx_error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_bad_frame): + rx_error_bad_frame_asserted.next = 1 + if (rx_error_bad_fcs): + rx_error_bad_fcs_asserted.next = 1 + + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @always(clk.posedge) + def clk_enable_gen(): + if clk_enable_div.next > 0: + rx_clk_enable.next = 0 + tx_clk_enable.next = 0 + clk_enable_div.next = clk_enable_div - 1 + else: + rx_clk_enable.next = 1 + tx_clk_enable.next = 1 + clk_enable_div.next = clk_enable_rate - 1 + @instance def check(): yield delay(100) @@ -225,94 +263,102 @@ def bench(): # testbench stimulus - yield clk.posedge - print("test 1: test rx packet") - current_test.next = 1 + for rate, mii in [(1, 0), (10, 0), (5, 1)]: + clk_enable_rate.next = rate + rx_mii_select.next = mii + tx_mii_select.next = mii - 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(range(32)) - test_frame.update_fcs() + yield clk.posedge + print("test 1: test rx packet") + current_test.next = 1 - axis_frame = test_frame.build_axis_fcs() + 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(range(32)) + test_frame.update_fcs() - gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield clk.posedge - yield clk.posedge + axis_frame = test_frame.build_axis_fcs() - while gmii_rx_dv: + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + yield clk.posedge yield clk.posedge - yield delay(100) - - while rx_axis_tvalid: + while not rx_clk_enable or not tx_clk_enable or not (gmii_rx_dv or gmii_tx_en): + yield clk.posedge yield clk.posedge - yield clk.posedge - yield clk.posedge + while not rx_clk_enable or not tx_clk_enable or gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: + yield clk.posedge - rx_frame = axis_sink.recv() + yield delay(100) - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() + while rx_axis_tvalid: + yield clk.posedge - assert eth_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 2: test tx packet") - current_test.next = 2 - - 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(range(32)) - test_frame.update_fcs() - - axis_frame = test_frame.build_axis() - - axis_source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - while tx_axis_tvalid: + yield clk.posedge yield clk.posedge - yield delay(100) + rx_frame = axis_sink.recv() - while gmii_tx_en: + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + yield clk.posedge yield clk.posedge - yield clk.posedge - yield clk.posedge + while not rx_clk_enable or not tx_clk_enable or not (gmii_rx_dv or gmii_tx_en): + yield clk.posedge + yield clk.posedge - rx_frame = gmii_sink.recv() + while not rx_clk_enable or not tx_clk_enable or gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: + yield clk.posedge - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + yield clk.posedge + yield clk.posedge - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) + rx_frame = gmii_sink.recv() - print(hex(eth_frame.eth_fcs)) - print(hex(eth_frame.calc_fcs())) + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - assert len(eth_frame.payload.data) == 46 - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame.eth_src_mac - assert eth_frame.eth_type == test_frame.eth_type - assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) - yield delay(100) + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) raise StopSimulation - return dut, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, check + return dut, monitor, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_1g_fifo.v b/tb/test_eth_mac_1g_fifo.v index 9887daaa8..e835388a4 100644 --- a/tb/test_eth_mac_1g_fifo.v +++ b/tb/test_eth_mac_1g_fifo.v @@ -56,6 +56,10 @@ reg rx_axis_tready = 0; reg [7:0] gmii_rxd = 0; reg gmii_rx_dv = 0; reg gmii_rx_er = 0; +reg rx_clk_enable = 1; +reg tx_clk_enable = 1; +reg rx_mii_select = 0; +reg tx_mii_select = 0; reg [7:0] ifg_delay = 0; // Outputs @@ -96,6 +100,10 @@ initial begin gmii_rxd, gmii_rx_dv, gmii_rx_er, + rx_clk_enable, + tx_clk_enable, + rx_mii_select, + tx_mii_select, ifg_delay ); $to_myhdl( @@ -151,6 +159,10 @@ UUT ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .rx_clk_enable(rx_clk_enable), + .tx_clk_enable(tx_clk_enable), + .rx_mii_select(rx_mii_select), + .tx_mii_select(tx_mii_select), .tx_fifo_overflow(tx_fifo_overflow), .tx_fifo_bad_frame(tx_fifo_bad_frame), .tx_fifo_good_frame(tx_fifo_good_frame), From bb9e78964583e6111483ebbe25467b1d7fb2c848 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 May 2017 18:40:18 -0700 Subject: [PATCH 331/617] Update GMII PHY interface and add GMII MAC wrappers --- rtl/eth_mac_1g_gmii.v | 252 ++++++++++++++++++++++ rtl/eth_mac_1g_gmii_fifo.v | 268 +++++++++++++++++++++++ rtl/gmii_phy_if.v | 26 ++- tb/test_eth_mac_1g_gmii.py | 342 +++++++++++++++++++++++++++++ tb/test_eth_mac_1g_gmii.v | 158 ++++++++++++++ tb/test_eth_mac_1g_gmii_fifo.py | 366 ++++++++++++++++++++++++++++++++ tb/test_eth_mac_1g_gmii_fifo.v | 177 +++++++++++++++ 7 files changed, 1586 insertions(+), 3 deletions(-) create mode 100644 rtl/eth_mac_1g_gmii.v create mode 100644 rtl/eth_mac_1g_gmii_fifo.v create mode 100755 tb/test_eth_mac_1g_gmii.py create mode 100644 tb/test_eth_mac_1g_gmii.v create mode 100755 tb/test_eth_mac_1g_gmii_fifo.py create mode 100644 tb/test_eth_mac_1g_gmii_fifo.v diff --git a/rtl/eth_mac_1g_gmii.v b/rtl/eth_mac_1g_gmii.v new file mode 100644 index 000000000..5c476b1cd --- /dev/null +++ b/rtl/eth_mac_1g_gmii.v @@ -0,0 +1,252 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * 1G Ethernet MAC with GMII interface + */ +module eth_mac_1g_gmii # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire gtx_clk, + input wire gtx_rst, + output wire rx_clk, + output wire rx_rst, + output wire tx_clk, + output wire tx_rst, + + /* + * AXI input + */ + input wire [7:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] rx_axis_tdata, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * GMII interface + */ + input wire gmii_rx_clk, + input wire [7:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, + input wire mii_tx_clk, + output wire gmii_tx_clk, + output wire [7:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * Status + */ + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire [1:0] speed, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +wire [7:0] mac_gmii_rxd; +wire mac_gmii_rx_dv; +wire mac_gmii_rx_er; +wire [7:0] mac_gmii_txd; +wire mac_gmii_tx_en; +wire mac_gmii_tx_er; + +reg [1:0] speed_reg = 2'b10; +wire mii_select; + +reg tx_mii_select_1 = 1'b0; +reg tx_mii_select_2 = 1'b0; +reg tx_mii_select_3 = 1'b0; + +always @(posedge tx_clk) begin + tx_mii_select_1 <= mii_select; + tx_mii_select_2 <= tx_mii_select_1; + tx_mii_select_3 <= tx_mii_select_2; +end + +reg rx_mii_select_1 = 1'b0; +reg rx_mii_select_2 = 1'b0; +reg rx_mii_select_3 = 1'b0; + +always @(posedge rx_clk) begin + rx_mii_select_1 <= mii_select; + rx_mii_select_2 <= rx_mii_select_1; + rx_mii_select_3 <= rx_mii_select_2; +end + +// PHY speed detection +reg [2:0] rx_prescale = 3'd0; + +always @(posedge rx_clk) begin + rx_prescale <= rx_prescale + 3'd1; +end + +reg rx_prescale_sync_1 = 1'b0; +reg rx_prescale_sync_2 = 1'b0; +reg rx_prescale_sync_3 = 1'b0; + +always @(posedge gtx_clk) begin + rx_prescale_sync_1 <= rx_prescale[2]; + rx_prescale_sync_2 <= rx_prescale_sync_1; + rx_prescale_sync_3 <= rx_prescale_sync_2; +end + +reg [6:0] rx_speed_count_1 = 0; +reg [1:0] rx_speed_count_2 = 0; + +always @(posedge gtx_clk) begin + if (gtx_rst) begin + rx_speed_count_1 <= 0; + rx_speed_count_2 <= 0; + speed_reg <= 2'b10; + end else begin + rx_speed_count_1 <= rx_speed_count_1 + 1; + + if (rx_prescale_sync_2 ^ rx_prescale_sync_3) begin + rx_speed_count_2 <= rx_speed_count_2 + 1; + end + + if (&rx_speed_count_1) begin + // reference count overflow - 10M + rx_speed_count_1 <= 0; + rx_speed_count_2 <= 0; + speed_reg <= 2'b00; + end + + if (&rx_speed_count_2) begin + // prescaled count overflow - 100M or 1000M + rx_speed_count_1 <= 0; + rx_speed_count_2 <= 0; + if (rx_speed_count_1[6:5]) begin + // large reference count - 100M + speed_reg <= 2'b01; + end else begin + // small reference count - 1000M + speed_reg <= 2'b10; + end + end + end +end + +assign speed = speed_reg; +assign mii_select = speed != 2'b10; + +gmii_phy_if #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE) +) +gmii_phy_if_inst ( + .clk(gtx_clk), + .rst(gtx_rst), + + .mac_gmii_rx_clk(rx_clk), + .mac_gmii_rx_rst(rx_rst), + .mac_gmii_rxd(mac_gmii_rxd), + .mac_gmii_rx_dv(mac_gmii_rx_dv), + .mac_gmii_rx_er(mac_gmii_rx_er), + .mac_gmii_tx_clk(tx_clk), + .mac_gmii_tx_rst(tx_rst), + .mac_gmii_txd(mac_gmii_txd), + .mac_gmii_tx_en(mac_gmii_tx_en), + .mac_gmii_tx_er(mac_gmii_tx_er), + + .phy_gmii_rx_clk(gmii_rx_clk), + .phy_gmii_rxd(gmii_rxd), + .phy_gmii_rx_dv(gmii_rx_dv), + .phy_gmii_rx_er(gmii_rx_er), + .phy_mii_tx_clk(mii_tx_clk), + .phy_gmii_tx_clk(gmii_tx_clk), + .phy_gmii_txd(gmii_txd), + .phy_gmii_tx_en(gmii_tx_en), + .phy_gmii_tx_er(gmii_tx_er), + + .mii_select(mii_select) +); + +eth_mac_1g #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .gmii_rxd(mac_gmii_rxd), + .gmii_rx_dv(mac_gmii_rx_dv), + .gmii_rx_er(mac_gmii_rx_er), + .gmii_txd(mac_gmii_txd), + .gmii_tx_en(mac_gmii_tx_en), + .gmii_tx_er(mac_gmii_tx_er), + .rx_clk_enable(1'b1), + .tx_clk_enable(1'b1), + .rx_mii_select(rx_mii_select_3), + .tx_mii_select(tx_mii_select_3), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/rtl/eth_mac_1g_gmii_fifo.v b/rtl/eth_mac_1g_gmii_fifo.v new file mode 100644 index 000000000..e70690a8c --- /dev/null +++ b/rtl/eth_mac_1g_gmii_fifo.v @@ -0,0 +1,268 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * 1G Ethernet MAC with GMII interface and TX and RX FIFOs + */ +module eth_mac_1g_gmii_fifo # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter TX_FIFO_ADDR_WIDTH = 12, + parameter RX_FIFO_ADDR_WIDTH = 12 +) +( + input wire gtx_clk, + input wire gtx_rst, + input wire logic_clk, + input wire logic_rst, + + /* + * AXI input + */ + input wire [7:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] rx_axis_tdata, + output wire rx_axis_tvalid, + input wire rx_axis_tready, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * GMII interface + */ + input wire gmii_rx_clk, + input wire [7:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, + input wire mii_tx_clk, + output wire gmii_tx_clk, + output wire [7:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * Status + */ + output wire tx_fifo_overflow, + output wire tx_fifo_bad_frame, + output wire tx_fifo_good_frame, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_fifo_overflow, + output wire rx_fifo_bad_frame, + output wire rx_fifo_good_frame, + output wire [1:0] speed, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +wire tx_clk; +wire rx_clk; +wire tx_rst; +wire rx_rst; + +wire [7:0] tx_fifo_axis_tdata; +wire tx_fifo_axis_tvalid; +wire tx_fifo_axis_tready; +wire tx_fifo_axis_tlast; +wire tx_fifo_axis_tuser; + +wire [7:0] rx_fifo_axis_tdata; +wire rx_fifo_axis_tvalid; +wire rx_fifo_axis_tlast; +wire rx_fifo_axis_tuser; + +// synchronize MAC status signals into logic clock domain +wire rx_error_bad_frame_int; +wire rx_error_bad_fcs_int; + +reg [1:0] rx_sync_reg_1 = 2'd0; +reg [1:0] rx_sync_reg_2 = 2'd0; +reg [1:0] rx_sync_reg_3 = 2'd0; +reg [1:0] rx_sync_reg_4 = 2'd0; + +assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; +assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; + +always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + rx_sync_reg_1 <= 2'd0; + end else begin + rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_error_bad_frame_int, rx_error_bad_frame_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + rx_sync_reg_2 <= 2'd0; + rx_sync_reg_3 <= 2'd0; + rx_sync_reg_4 <= 2'd0; + end else begin + rx_sync_reg_2 <= rx_sync_reg_1; + rx_sync_reg_3 <= rx_sync_reg_2; + rx_sync_reg_4 <= rx_sync_reg_3; + end +end + +wire [1:0] speed_int; + +reg [1:0] speed_sync_reg_1 = 2'b10; +reg [1:0] speed_sync_reg_2 = 2'b10; + +assign speed = speed_sync_reg_2; + +always @(posedge logic_clk) begin + speed_sync_reg_1 <= speed_int; + speed_sync_reg_2 <= speed_sync_reg_1; +end + +eth_mac_1g_gmii #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_gmii_inst ( + .gtx_clk(gtx_clk), + .gtx_rst(gtx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_fifo_axis_tdata), + .tx_axis_tvalid(tx_fifo_axis_tvalid), + .tx_axis_tready(tx_fifo_axis_tready), + .tx_axis_tlast(tx_fifo_axis_tlast), + .tx_axis_tuser(tx_fifo_axis_tuser), + .rx_axis_tdata(rx_fifo_axis_tdata), + .rx_axis_tvalid(rx_fifo_axis_tvalid), + .rx_axis_tlast(rx_fifo_axis_tlast), + .rx_axis_tuser(rx_fifo_axis_tuser), + .gmii_rx_clk(gmii_rx_clk), + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .gmii_tx_clk(gmii_tx_clk), + .mii_tx_clk(mii_tx_clk), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + .rx_error_bad_frame(rx_error_bad_frame_int), + .rx_error_bad_fcs(rx_error_bad_fcs_int), + .speed(speed_int), + .ifg_delay(ifg_delay) +); + +axis_async_frame_fifo #( + .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(8), + .DROP_WHEN_FULL(0) +) +tx_fifo ( + // Common reset + .async_rst(logic_rst | tx_rst), + // AXI input + .input_clk(logic_clk), + .input_axis_tdata(tx_axis_tdata), + .input_axis_tvalid(tx_axis_tvalid), + .input_axis_tready(tx_axis_tready), + .input_axis_tlast(tx_axis_tlast), + .input_axis_tuser(tx_axis_tuser), + // AXI output + .output_clk(tx_clk), + .output_axis_tdata(tx_fifo_axis_tdata), + .output_axis_tvalid(tx_fifo_axis_tvalid), + .output_axis_tready(tx_fifo_axis_tready), + .output_axis_tlast(tx_fifo_axis_tlast), + // Status + .input_status_overflow(tx_fifo_overflow), + .input_status_bad_frame(tx_fifo_bad_frame), + .input_status_good_frame(tx_fifo_good_frame), + .output_status_overflow(), + .output_status_bad_frame(), + .output_status_good_frame() +); + +assign tx_fifo_axis_tuser = 1'b0; + +axis_async_frame_fifo #( + .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(8), + .DROP_WHEN_FULL(1) +) +rx_fifo ( + // Common reset + .async_rst(rx_rst | logic_rst), + // AXI input + .input_clk(rx_clk), + .input_axis_tdata(rx_fifo_axis_tdata), + .input_axis_tvalid(rx_fifo_axis_tvalid), + .input_axis_tready(), + .input_axis_tlast(rx_fifo_axis_tlast), + .input_axis_tuser(rx_fifo_axis_tuser), + // AXI output + .output_clk(logic_clk), + .output_axis_tdata(rx_axis_tdata), + .output_axis_tvalid(rx_axis_tvalid), + .output_axis_tready(rx_axis_tready), + .output_axis_tlast(rx_axis_tlast), + // Status + .input_status_overflow(), + .input_status_bad_frame(), + .input_status_good_frame(), + .output_status_overflow(rx_fifo_overflow), + .output_status_bad_frame(rx_fifo_bad_frame), + .output_status_good_frame(rx_fifo_good_frame) +); + +assign rx_axis_tuser = 1'b0; + +endmodule diff --git a/rtl/gmii_phy_if.v b/rtl/gmii_phy_if.v index 6c2efb305..347c20ce1 100644 --- a/rtl/gmii_phy_if.v +++ b/rtl/gmii_phy_if.v @@ -68,10 +68,16 @@ module gmii_phy_if # input wire [7:0] phy_gmii_rxd, input wire phy_gmii_rx_dv, input wire phy_gmii_rx_er, + input wire phy_mii_tx_clk, output wire phy_gmii_tx_clk, output wire [7:0] phy_gmii_txd, output wire phy_gmii_tx_en, - output wire phy_gmii_tx_er + output wire phy_gmii_tx_er, + + /* + * Control + */ + input wire mii_select ); ssio_sdr_in # @@ -94,13 +100,27 @@ ssio_sdr_out # .WIDTH(10) ) tx_ssio_sdr_inst ( - .clk(clk), + .clk(mac_gmii_tx_clk), .input_d({mac_gmii_txd, mac_gmii_tx_en, mac_gmii_tx_er}), .output_clk(phy_gmii_tx_clk), .output_q({phy_gmii_txd, phy_gmii_tx_en, phy_gmii_tx_er}) ); -assign mac_gmii_tx_clk = clk; +generate + +if (TARGET == "XILINX") begin + BUFGMUX + gmii_bufgmux_inst ( + .I0(clk), + .I1(phy_mii_tx_clk), + .S(mii_select), + .O(mac_gmii_tx_clk) + ); +end else begin + assign mac_gmii_tx_clk = mii_select ? phy_mii_tx_clk : clk; +end + +endgenerate // reset sync reg [3:0] tx_rst_reg = 4'hf; diff --git a/tb/test_eth_mac_1g_gmii.py b/tb/test_eth_mac_1g_gmii.py new file mode 100755 index 000000000..2495eeab3 --- /dev/null +++ b/tb/test_eth_mac_1g_gmii.py @@ -0,0 +1,342 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import axis_ep +import eth_ep +import gmii_ep + +module = 'eth_mac_1g_gmii' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("../rtl/axis_gmii_rx.v") +srcs.append("../rtl/axis_gmii_tx.v") +srcs.append("../rtl/eth_mac_1g.v") +srcs.append("../rtl/gmii_phy_if.v") +srcs.append("../rtl/oddr.v") +srcs.append("../rtl/ssio_sdr_in.v") +srcs.append("../rtl/ssio_sdr_out.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + TARGET = "SIM" + IODDR_STYLE = "IODDR2" + CLOCK_INPUT_STYLE = "BUFIO2" + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + gtx_clk = Signal(bool(0)) + gtx_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[8:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + gmii_rx_clk = Signal(bool(0)) + gmii_rxd = Signal(intbv(0)[8:]) + gmii_rx_dv = Signal(bool(0)) + gmii_rx_er = Signal(bool(0)) + mii_tx_clk = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[8:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + gmii_tx_clk = Signal(bool(0)) + gmii_txd = Signal(intbv(0)[8:]) + gmii_tx_en = Signal(bool(0)) + gmii_tx_er = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + speed = Signal(intbv(0)[2:]) + + # sources and sinks + axis_source_pause = Signal(bool(0)) + + mii_select = Signal(bool(0)) + + gmii_source = gmii_ep.GMIISource() + + gmii_source_logic = gmii_source.create_logic( + gmii_rx_clk, + rst, + txd=gmii_rxd, + tx_en=gmii_rx_dv, + tx_er=gmii_rx_er, + mii_select=mii_select, + name='gmii_source' + ) + + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + gmii_tx_clk, + rst, + rxd=gmii_txd, + rx_dv=gmii_tx_en, + rx_er=gmii_tx_er, + mii_select=mii_select, + name='gmii_sink' + ) + + axis_source = axis_ep.AXIStreamSource() + + axis_source_logic = axis_source.create_logic( + tx_clk, + tx_rst, + tdata=tx_axis_tdata, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + pause=axis_source_pause, + name='axis_source' + ) + + axis_sink = axis_ep.AXIStreamSink() + + axis_sink_logic = axis_sink.create_logic( + gmii_rx_clk, + rx_rst, + tdata=rx_axis_tdata, + tvalid=rx_axis_tvalid, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + name='axis_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, + + gtx_clk=gtx_clk, + gtx_rst=gtx_rst, + + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + gmii_rx_clk=gmii_rx_clk, + gmii_rxd=gmii_rxd, + gmii_rx_dv=gmii_rx_dv, + gmii_rx_er=gmii_rx_er, + + gmii_tx_clk=gmii_tx_clk, + mii_tx_clk=mii_tx_clk, + gmii_txd=gmii_txd, + gmii_tx_en=gmii_tx_en, + gmii_tx_er=gmii_tx_er, + + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + speed=speed, + + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + gtx_clk.next = not clk + + rx_clk_hp = Signal(int(4)) + + @instance + def rx_clk_gen(): + while True: + yield delay(int(rx_clk_hp)) + gmii_rx_clk.next = not gmii_rx_clk + mii_tx_clk.next = not gmii_rx_clk + + rx_error_bad_frame_asserted = Signal(bool(0)) + rx_error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_bad_frame): + rx_error_bad_frame_asserted.next = 1 + if (rx_error_bad_fcs): + rx_error_bad_fcs_asserted.next = 1 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + gtx_rst.next = 1 + yield clk.posedge + rst.next = 0 + gtx_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + for rate, mii in [(4, 0), (20, 1), (200, 1)]: + rx_clk_hp.next = rate + mii_select.next = mii + + yield delay(1000) + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + + while not (gmii_rx_dv or gmii_tx_en): + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + + while gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: + yield gmii_rx_clk.posedge + + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + + rx_frame = axis_sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + + while not (gmii_rx_dv or gmii_tx_en): + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + + while gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: + yield gmii_rx_clk.posedge + + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + + rx_frame = gmii_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return dut, monitor, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, rx_clk_gen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_1g_gmii.v b/tb/test_eth_mac_1g_gmii.v new file mode 100644 index 000000000..22ec338c4 --- /dev/null +++ b/tb/test_eth_mac_1g_gmii.v @@ -0,0 +1,158 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for eth_mac_1g_gmii + */ +module test_eth_mac_1g_gmii; + +// Parameters +parameter TARGET = "SIM"; +parameter IODDR_STYLE = "IODDR2"; +parameter CLOCK_INPUT_STYLE = "BUFIO2"; +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg gtx_clk = 0; +reg gtx_rst = 0; +reg [7:0] tx_axis_tdata = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg gmii_rx_clk = 0; +reg [7:0] gmii_rxd = 0; +reg gmii_rx_dv = 0; +reg gmii_rx_er = 0; +reg mii_tx_clk = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire rx_clk; +wire rx_rst; +wire tx_clk; +wire tx_rst; +wire tx_axis_tready; +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire gmii_tx_clk; +wire [7:0] gmii_txd; +wire gmii_tx_en; +wire gmii_tx_er; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; +wire [1:0] speed; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + gtx_clk, + gtx_rst, + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + gmii_rx_clk, + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + mii_tx_clk, + ifg_delay + ); + $to_myhdl( + rx_clk, + rx_rst, + tx_clk, + tx_rst, + tx_axis_tready, + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + gmii_tx_clk, + gmii_txd, + gmii_tx_en, + gmii_tx_er, + rx_error_bad_frame, + rx_error_bad_fcs, + speed + ); + + // dump file + $dumpfile("test_eth_mac_1g_gmii.lxt"); + $dumpvars(0, test_eth_mac_1g_gmii); +end + +eth_mac_1g_gmii #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .gtx_clk(gtx_clk), + .gtx_rst(gtx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .gmii_rx_clk(gmii_rx_clk), + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .gmii_tx_clk(gmii_tx_clk), + .mii_tx_clk(mii_tx_clk), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .speed(speed), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/tb/test_eth_mac_1g_gmii_fifo.py b/tb/test_eth_mac_1g_gmii_fifo.py new file mode 100755 index 000000000..1f6af9b29 --- /dev/null +++ b/tb/test_eth_mac_1g_gmii_fifo.py @@ -0,0 +1,366 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import axis_ep +import eth_ep +import gmii_ep + +module = 'eth_mac_1g_gmii_fifo' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("../rtl/axis_gmii_rx.v") +srcs.append("../rtl/axis_gmii_tx.v") +srcs.append("../rtl/eth_mac_1g.v") +srcs.append("../rtl/eth_mac_1g_gmii.v") +srcs.append("../rtl/gmii_phy_if.v") +srcs.append("../rtl/oddr.v") +srcs.append("../rtl/ssio_sdr_in.v") +srcs.append("../rtl/ssio_sdr_out.v") +srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + TARGET = "SIM" + IODDR_STYLE = "IODDR2" + CLOCK_INPUT_STYLE = "BUFIO2" + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + TX_FIFO_ADDR_WIDTH = 9 + RX_FIFO_ADDR_WIDTH = 9 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + gtx_clk = Signal(bool(0)) + gtx_rst = Signal(bool(0)) + logic_clk = Signal(bool(0)) + logic_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[8:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + rx_axis_tready = Signal(bool(0)) + gmii_rx_clk = Signal(bool(0)) + gmii_rxd = Signal(intbv(0)[8:]) + gmii_rx_dv = Signal(bool(0)) + gmii_rx_er = Signal(bool(0)) + mii_tx_clk = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[8:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + gmii_tx_clk = Signal(bool(0)) + gmii_txd = Signal(intbv(0)[8:]) + gmii_tx_en = Signal(bool(0)) + gmii_tx_er = Signal(bool(0)) + tx_fifo_overflow = Signal(bool(0)) + tx_fifo_bad_frame = Signal(bool(0)) + tx_fifo_good_frame = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + rx_fifo_overflow = Signal(bool(0)) + rx_fifo_bad_frame = Signal(bool(0)) + rx_fifo_good_frame = Signal(bool(0)) + speed = Signal(intbv(0)[1:0]) + + # sources and sinks + axis_source_pause = Signal(bool(0)) + axis_sink_pause = Signal(bool(0)) + + mii_select = Signal(bool(0)) + + gmii_source = gmii_ep.GMIISource() + + gmii_source_logic = gmii_source.create_logic( + gmii_rx_clk, + rst, + txd=gmii_rxd, + tx_en=gmii_rx_dv, + tx_er=gmii_rx_er, + mii_select=mii_select, + name='gmii_source' + ) + + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + gmii_tx_clk, + rst, + rxd=gmii_txd, + rx_dv=gmii_tx_en, + rx_er=gmii_tx_er, + mii_select=mii_select, + name='gmii_sink' + ) + + axis_source = axis_ep.AXIStreamSource() + + axis_source_logic = axis_source.create_logic( + logic_clk, + logic_rst, + tdata=tx_axis_tdata, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + pause=axis_source_pause, + name='axis_source' + ) + + axis_sink = axis_ep.AXIStreamSink() + + axis_sink_logic = axis_sink.create_logic( + logic_clk, + logic_rst, + tdata=rx_axis_tdata, + tvalid=rx_axis_tvalid, + tready=rx_axis_tready, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + pause=axis_sink_pause, + name='axis_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, + + gtx_clk=gtx_clk, + gtx_rst=gtx_rst, + logic_clk=logic_clk, + logic_rst=logic_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tready=rx_axis_tready, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + gmii_rx_clk=gmii_rx_clk, + gmii_rxd=gmii_rxd, + gmii_rx_dv=gmii_rx_dv, + gmii_rx_er=gmii_rx_er, + + gmii_tx_clk=gmii_tx_clk, + mii_tx_clk=mii_tx_clk, + gmii_txd=gmii_txd, + gmii_tx_en=gmii_tx_en, + gmii_tx_er=gmii_tx_er, + + tx_fifo_overflow=tx_fifo_overflow, + tx_fifo_bad_frame=tx_fifo_bad_frame, + tx_fifo_good_frame=tx_fifo_good_frame, + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + rx_fifo_overflow=rx_fifo_overflow, + rx_fifo_bad_frame=rx_fifo_bad_frame, + rx_fifo_good_frame=rx_fifo_good_frame, + speed=speed, + + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + gtx_clk.next = not clk + logic_clk.next = not clk + + rx_clk_hp = Signal(int(4)) + + @instance + def rx_clk_gen(): + while True: + yield delay(int(rx_clk_hp)) + gmii_rx_clk.next = not gmii_rx_clk + mii_tx_clk.next = not gmii_rx_clk + + rx_error_bad_frame_asserted = Signal(bool(0)) + rx_error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_bad_frame): + rx_error_bad_frame_asserted.next = 1 + if (rx_error_bad_fcs): + rx_error_bad_fcs_asserted.next = 1 + + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + gtx_rst.next = 1 + logic_rst.next = 1 + yield clk.posedge + rst.next = 0 + gtx_rst.next = 0 + logic_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + for rate, mii in [(4, 0), (20, 1), (200, 1)]: + rx_clk_hp.next = rate + mii_select.next = mii + + yield delay(1000) + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + + while gmii_rx_dv: + yield gmii_rx_clk.posedge + + for k in range(10): + yield gmii_rx_clk.posedge + + while rx_axis_tvalid: + yield gmii_rx_clk.posedge + + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + + rx_frame = axis_sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + + while tx_axis_tvalid: + yield gmii_rx_clk.posedge + + for k in range(10): + yield gmii_rx_clk.posedge + + while gmii_tx_en: + yield gmii_rx_clk.posedge + + yield gmii_rx_clk.posedge + yield gmii_rx_clk.posedge + + rx_frame = gmii_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return dut, monitor, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, rx_clk_gen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_1g_gmii_fifo.v b/tb/test_eth_mac_1g_gmii_fifo.v new file mode 100644 index 000000000..49ceaf86a --- /dev/null +++ b/tb/test_eth_mac_1g_gmii_fifo.v @@ -0,0 +1,177 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for eth_mac_1g_gmii_fifo + */ +module test_eth_mac_1g_gmii_fifo; + +// Parameters +parameter TARGET = "SIM"; +parameter IODDR_STYLE = "IODDR2"; +parameter CLOCK_INPUT_STYLE = "BUFIO2"; +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; +parameter TX_FIFO_ADDR_WIDTH = 9; +parameter RX_FIFO_ADDR_WIDTH = 9; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg gtx_clk = 0; +reg gtx_rst = 0; +reg logic_clk = 0; +reg logic_rst = 0; +reg [7:0] tx_axis_tdata = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg rx_axis_tready = 0; +reg gmii_rx_clk = 0; +reg [7:0] gmii_rxd = 0; +reg gmii_rx_dv = 0; +reg gmii_rx_er = 0; +reg mii_tx_clk = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire gmii_tx_clk; +wire [7:0] gmii_txd; +wire gmii_tx_en; +wire gmii_tx_er; +wire tx_fifo_overflow; +wire tx_fifo_bad_frame; +wire tx_fifo_good_frame; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; +wire rx_fifo_overflow; +wire rx_fifo_bad_frame; +wire rx_fifo_good_frame; +wire [1:0] speed; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + gtx_clk, + gtx_rst, + logic_clk, + logic_rst, + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + rx_axis_tready, + gmii_rx_clk, + gmii_rxd, + gmii_rx_dv, + gmii_rx_er, + mii_tx_clk, + ifg_delay + ); + $to_myhdl( + tx_axis_tready, + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + gmii_tx_clk, + gmii_txd, + gmii_tx_en, + gmii_tx_er, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, + rx_error_bad_frame, + rx_error_bad_fcs, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame, + speed + ); + + // dump file + $dumpfile("test_eth_mac_1g_gmii_fifo.lxt"); + $dumpvars(0, test_eth_mac_1g_gmii_fifo); +end + +eth_mac_1g_gmii_fifo #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .TX_FIFO_ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .RX_FIFO_ADDR_WIDTH(RX_FIFO_ADDR_WIDTH) +) +UUT ( + .gtx_clk(gtx_clk), + .gtx_rst(gtx_rst), + .logic_clk(logic_clk), + .logic_rst(logic_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .gmii_rx_clk(gmii_rx_clk), + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .gmii_tx_clk(gmii_tx_clk), + .mii_tx_clk(mii_tx_clk), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + .tx_fifo_overflow(tx_fifo_overflow), + .tx_fifo_bad_frame(tx_fifo_bad_frame), + .tx_fifo_good_frame(tx_fifo_good_frame), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(rx_fifo_overflow), + .rx_fifo_bad_frame(rx_fifo_bad_frame), + .rx_fifo_good_frame(rx_fifo_good_frame), + .speed(speed), + .ifg_delay(ifg_delay) +); + +endmodule From a3b5d5d1678a307f632fb8fe58bab53b700517b9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 May 2017 18:40:49 -0700 Subject: [PATCH 332/617] Update RGMII PHY interface and add RGMII MAC wrappers --- rtl/eth_mac_1g_rgmii.v | 253 +++++++++++++++++++++ rtl/eth_mac_1g_rgmii_fifo.v | 267 ++++++++++++++++++++++ rtl/rgmii_phy_if.v | 142 +++++++++++- tb/test_eth_mac_1g_rgmii.py | 344 +++++++++++++++++++++++++++++ tb/test_eth_mac_1g_rgmii.v | 154 +++++++++++++ tb/test_eth_mac_1g_rgmii_fifo.py | 367 +++++++++++++++++++++++++++++++ tb/test_eth_mac_1g_rgmii_fifo.v | 173 +++++++++++++++ 7 files changed, 1690 insertions(+), 10 deletions(-) create mode 100644 rtl/eth_mac_1g_rgmii.v create mode 100644 rtl/eth_mac_1g_rgmii_fifo.v create mode 100755 tb/test_eth_mac_1g_rgmii.py create mode 100644 tb/test_eth_mac_1g_rgmii.v create mode 100755 tb/test_eth_mac_1g_rgmii_fifo.py create mode 100644 tb/test_eth_mac_1g_rgmii_fifo.v diff --git a/rtl/eth_mac_1g_rgmii.v b/rtl/eth_mac_1g_rgmii.v new file mode 100644 index 000000000..a7650a7c5 --- /dev/null +++ b/rtl/eth_mac_1g_rgmii.v @@ -0,0 +1,253 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * 1G Ethernet MAC with RGMII interface + */ +module eth_mac_1g_rgmii # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + // Use 90 degree clock for RGMII transmit ("TRUE", "FALSE") + parameter USE_CLK90 = "TRUE", + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire gtx_clk, + input wire gtx_clk90, + input wire gtx_rst, + output wire rx_clk, + output wire rx_rst, + output wire tx_clk, + output wire tx_rst, + + /* + * AXI input + */ + input wire [7:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] rx_axis_tdata, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * RGMII interface + */ + input wire rgmii_rx_clk, + input wire [3:0] rgmii_rxd, + input wire rgmii_rx_ctl, + output wire rgmii_tx_clk, + output wire [3:0] rgmii_txd, + output wire rgmii_tx_ctl, + + /* + * Status + */ + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire [1:0] speed, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +wire [7:0] mac_gmii_rxd; +wire mac_gmii_rx_dv; +wire mac_gmii_rx_er; +wire mac_gmii_tx_clk_en; +wire [7:0] mac_gmii_txd; +wire mac_gmii_tx_en; +wire mac_gmii_tx_er; + +reg [1:0] speed_reg = 2'b10; +wire mii_select; + +reg tx_mii_select_1 = 1'b0; +reg tx_mii_select_2 = 1'b0; +reg tx_mii_select_3 = 1'b0; + +always @(posedge tx_clk) begin + tx_mii_select_1 <= mii_select; + tx_mii_select_2 <= tx_mii_select_1; + tx_mii_select_3 <= tx_mii_select_2; +end + +reg rx_mii_select_1 = 1'b0; +reg rx_mii_select_2 = 1'b0; +reg rx_mii_select_3 = 1'b0; + +always @(posedge rx_clk) begin + rx_mii_select_1 <= mii_select; + rx_mii_select_2 <= rx_mii_select_1; + rx_mii_select_3 <= rx_mii_select_2; +end + +// PHY speed detection +reg [2:0] rx_prescale = 3'd0; + +always @(posedge rx_clk) begin + rx_prescale <= rx_prescale + 3'd1; +end + +reg rx_prescale_sync_1 = 1'b0; +reg rx_prescale_sync_2 = 1'b0; +reg rx_prescale_sync_3 = 1'b0; + +always @(posedge gtx_clk) begin + rx_prescale_sync_1 <= rx_prescale[2]; + rx_prescale_sync_2 <= rx_prescale_sync_1; + rx_prescale_sync_3 <= rx_prescale_sync_2; +end + +reg [6:0] rx_speed_count_1 = 0; +reg [1:0] rx_speed_count_2 = 0; + +always @(posedge gtx_clk) begin + if (gtx_rst) begin + rx_speed_count_1 <= 0; + rx_speed_count_2 <= 0; + speed_reg <= 2'b10; + end else begin + rx_speed_count_1 <= rx_speed_count_1 + 1; + + if (rx_prescale_sync_2 ^ rx_prescale_sync_3) begin + rx_speed_count_2 <= rx_speed_count_2 + 1; + end + + if (&rx_speed_count_1) begin + // reference count overflow - 10M + rx_speed_count_1 <= 0; + rx_speed_count_2 <= 0; + speed_reg <= 2'b00; + end + + if (&rx_speed_count_2) begin + // prescaled count overflow - 100M or 1000M + rx_speed_count_1 <= 0; + rx_speed_count_2 <= 0; + if (rx_speed_count_1[6:5]) begin + // large reference count - 100M + speed_reg <= 2'b01; + end else begin + // small reference count - 1000M + speed_reg <= 2'b10; + end + end + end +end + +assign speed = speed_reg; +assign mii_select = speed != 2'b10; + +rgmii_phy_if #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .USE_CLK90(USE_CLK90) +) +rgmii_phy_if_inst ( + .clk(gtx_clk), + .clk90(gtx_clk90), + .rst(gtx_rst), + + .mac_gmii_rx_clk(rx_clk), + .mac_gmii_rx_rst(rx_rst), + .mac_gmii_rxd(mac_gmii_rxd), + .mac_gmii_rx_dv(mac_gmii_rx_dv), + .mac_gmii_rx_er(mac_gmii_rx_er), + .mac_gmii_tx_clk(tx_clk), + .mac_gmii_tx_rst(tx_rst), + .mac_gmii_tx_clk_en(mac_gmii_tx_clk_en), + .mac_gmii_txd(mac_gmii_txd), + .mac_gmii_tx_en(mac_gmii_tx_en), + .mac_gmii_tx_er(mac_gmii_tx_er), + + .phy_rgmii_rx_clk(rgmii_rx_clk), + .phy_rgmii_rxd(rgmii_rxd), + .phy_rgmii_rx_ctl(rgmii_rx_ctl), + .phy_rgmii_tx_clk(rgmii_tx_clk), + .phy_rgmii_txd(rgmii_txd), + .phy_rgmii_tx_ctl(rgmii_tx_ctl), + + .speed(speed) +); + +eth_mac_1g #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .gmii_rxd(mac_gmii_rxd), + .gmii_rx_dv(mac_gmii_rx_dv), + .gmii_rx_er(mac_gmii_rx_er), + .gmii_txd(mac_gmii_txd), + .gmii_tx_en(mac_gmii_tx_en), + .gmii_tx_er(mac_gmii_tx_er), + .rx_clk_enable(1'b1), + .tx_clk_enable(mac_gmii_tx_clk_en), + .rx_mii_select(rx_mii_select_3), + .tx_mii_select(tx_mii_select_3), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/rtl/eth_mac_1g_rgmii_fifo.v b/rtl/eth_mac_1g_rgmii_fifo.v new file mode 100644 index 000000000..15a1acf97 --- /dev/null +++ b/rtl/eth_mac_1g_rgmii_fifo.v @@ -0,0 +1,267 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * 1G Ethernet MAC with RGMII interface and TX and RX FIFOs + */ +module eth_mac_1g_rgmii_fifo # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + // Use 90 degree clock for RGMII transmit ("TRUE", "FALSE") + parameter USE_CLK90 = "TRUE", + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter TX_FIFO_ADDR_WIDTH = 12, + parameter RX_FIFO_ADDR_WIDTH = 12 +) +( + input wire gtx_clk, + input wire gtx_clk90, + input wire gtx_rst, + input wire logic_clk, + input wire logic_rst, + + /* + * AXI input + */ + input wire [7:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] rx_axis_tdata, + output wire rx_axis_tvalid, + input wire rx_axis_tready, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * RGMII interface + */ + input wire rgmii_rx_clk, + input wire [3:0] rgmii_rxd, + input wire rgmii_rx_ctl, + output wire rgmii_tx_clk, + output wire [3:0] rgmii_txd, + output wire rgmii_tx_ctl, + + /* + * Status + */ + output wire tx_fifo_overflow, + output wire tx_fifo_bad_frame, + output wire tx_fifo_good_frame, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_fifo_overflow, + output wire rx_fifo_bad_frame, + output wire rx_fifo_good_frame, + output wire [1:0] speed, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +wire tx_clk; +wire rx_clk; +wire tx_rst; +wire rx_rst; + +wire [7:0] tx_fifo_axis_tdata; +wire tx_fifo_axis_tvalid; +wire tx_fifo_axis_tready; +wire tx_fifo_axis_tlast; +wire tx_fifo_axis_tuser; + +wire [7:0] rx_fifo_axis_tdata; +wire rx_fifo_axis_tvalid; +wire rx_fifo_axis_tlast; +wire rx_fifo_axis_tuser; + +// synchronize MAC status signals into logic clock domain +wire rx_error_bad_frame_int; +wire rx_error_bad_fcs_int; + +reg [1:0] rx_sync_reg_1 = 2'd0; +reg [1:0] rx_sync_reg_2 = 2'd0; +reg [1:0] rx_sync_reg_3 = 2'd0; +reg [1:0] rx_sync_reg_4 = 2'd0; + +assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; +assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; + +always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + rx_sync_reg_1 <= 2'd0; + end else begin + rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_error_bad_frame_int, rx_error_bad_frame_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + rx_sync_reg_2 <= 2'd0; + rx_sync_reg_3 <= 2'd0; + rx_sync_reg_4 <= 2'd0; + end else begin + rx_sync_reg_2 <= rx_sync_reg_1; + rx_sync_reg_3 <= rx_sync_reg_2; + rx_sync_reg_4 <= rx_sync_reg_3; + end +end + +wire [1:0] speed_int; + +reg [1:0] speed_sync_reg_1 = 2'b10; +reg [1:0] speed_sync_reg_2 = 2'b10; + +assign speed = speed_sync_reg_2; + +always @(posedge logic_clk) begin + speed_sync_reg_1 <= speed_int; + speed_sync_reg_2 <= speed_sync_reg_1; +end + +eth_mac_1g_rgmii #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .USE_CLK90(USE_CLK90), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_rgmii_inst ( + .gtx_clk(gtx_clk), + .gtx_clk90(gtx_clk90), + .gtx_rst(gtx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_fifo_axis_tdata), + .tx_axis_tvalid(tx_fifo_axis_tvalid), + .tx_axis_tready(tx_fifo_axis_tready), + .tx_axis_tlast(tx_fifo_axis_tlast), + .tx_axis_tuser(tx_fifo_axis_tuser), + .rx_axis_tdata(rx_fifo_axis_tdata), + .rx_axis_tvalid(rx_fifo_axis_tvalid), + .rx_axis_tlast(rx_fifo_axis_tlast), + .rx_axis_tuser(rx_fifo_axis_tuser), + .rgmii_rx_clk(rgmii_rx_clk), + .rgmii_rxd(rgmii_rxd), + .rgmii_rx_ctl(rgmii_rx_ctl), + .rgmii_tx_clk(rgmii_tx_clk), + .rgmii_txd(rgmii_txd), + .rgmii_tx_ctl(rgmii_tx_ctl), + .rx_error_bad_frame(rx_error_bad_frame_int), + .rx_error_bad_fcs(rx_error_bad_fcs_int), + .speed(speed_int), + .ifg_delay(ifg_delay) +); + +axis_async_frame_fifo #( + .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(8), + .DROP_WHEN_FULL(0) +) +tx_fifo ( + // Common reset + .async_rst(logic_rst | tx_rst), + // AXI input + .input_clk(logic_clk), + .input_axis_tdata(tx_axis_tdata), + .input_axis_tvalid(tx_axis_tvalid), + .input_axis_tready(tx_axis_tready), + .input_axis_tlast(tx_axis_tlast), + .input_axis_tuser(tx_axis_tuser), + // AXI output + .output_clk(tx_clk), + .output_axis_tdata(tx_fifo_axis_tdata), + .output_axis_tvalid(tx_fifo_axis_tvalid), + .output_axis_tready(tx_fifo_axis_tready), + .output_axis_tlast(tx_fifo_axis_tlast), + // Status + .input_status_overflow(tx_fifo_overflow), + .input_status_bad_frame(tx_fifo_bad_frame), + .input_status_good_frame(tx_fifo_good_frame), + .output_status_overflow(), + .output_status_bad_frame(), + .output_status_good_frame() +); + +assign tx_fifo_axis_tuser = 1'b0; + +axis_async_frame_fifo #( + .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(8), + .DROP_WHEN_FULL(1) +) +rx_fifo ( + // Common reset + .async_rst(rx_rst | logic_rst), + // AXI input + .input_clk(rx_clk), + .input_axis_tdata(rx_fifo_axis_tdata), + .input_axis_tvalid(rx_fifo_axis_tvalid), + .input_axis_tready(), + .input_axis_tlast(rx_fifo_axis_tlast), + .input_axis_tuser(rx_fifo_axis_tuser), + // AXI output + .output_clk(logic_clk), + .output_axis_tdata(rx_axis_tdata), + .output_axis_tvalid(rx_axis_tvalid), + .output_axis_tready(rx_axis_tready), + .output_axis_tlast(rx_axis_tlast), + // Status + .input_status_overflow(), + .input_status_bad_frame(), + .input_status_good_frame(), + .output_status_overflow(rx_fifo_overflow), + .output_status_bad_frame(rx_fifo_bad_frame), + .output_status_good_frame(rx_fifo_good_frame) +); + +assign rx_axis_tuser = 1'b0; + +endmodule diff --git a/rtl/rgmii_phy_if.v b/rtl/rgmii_phy_if.v index 35522ef39..7edc6e747 100644 --- a/rtl/rgmii_phy_if.v +++ b/rtl/rgmii_phy_if.v @@ -60,6 +60,7 @@ module rgmii_phy_if # output wire mac_gmii_rx_er, output wire mac_gmii_tx_clk, output wire mac_gmii_tx_rst, + output wire mac_gmii_tx_clk_en, input wire [7:0] mac_gmii_txd, input wire mac_gmii_tx_en, input wire mac_gmii_tx_er, @@ -72,9 +73,16 @@ module rgmii_phy_if # input wire phy_rgmii_rx_ctl, output wire phy_rgmii_tx_clk, output wire [3:0] phy_rgmii_txd, - output wire phy_rgmii_tx_ctl + output wire phy_rgmii_tx_ctl, + + /* + * Control + */ + input wire [1:0] speed ); +// receive + wire rgmii_rx_ctl_1; wire rgmii_rx_ctl_2; @@ -96,24 +104,138 @@ rx_ssio_ddr_inst ( assign mac_gmii_rx_dv = rgmii_rx_ctl_1; assign mac_gmii_rx_er = rgmii_rx_ctl_1 ^ rgmii_rx_ctl_2; -ssio_ddr_out # -( +// transmit + +reg rgmii_tx_clk_1 = 1'b1; +reg rgmii_tx_clk_2 = 1'b0; +reg rgmii_tx_clk_rise = 1'b1; +reg rgmii_tx_clk_fall = 1'b1; + +reg [5:0] count_reg = 6'd0, count_next; + +always @(posedge clk) begin + if (rst) begin + rgmii_tx_clk_1 <= 1'b1; + rgmii_tx_clk_2 <= 1'b0; + rgmii_tx_clk_rise <= 1'b1; + rgmii_tx_clk_fall <= 1'b1; + count_reg <= 0; + end else begin + rgmii_tx_clk_1 <= rgmii_tx_clk_2; + + if (speed == 2'b00) begin + // 10M + count_reg <= count_reg + 1; + rgmii_tx_clk_rise <= 1'b0; + rgmii_tx_clk_fall <= 1'b0; + if (count_reg == 24) begin + rgmii_tx_clk_1 <= 1'b1; + rgmii_tx_clk_2 <= 1'b1; + rgmii_tx_clk_rise <= 1'b1; + end else if (count_reg >= 49) begin + rgmii_tx_clk_1 <= 1'b0; + rgmii_tx_clk_2 <= 1'b0; + rgmii_tx_clk_fall <= 1'b1; + count_reg <= 0; + end + end else if (speed == 2'b01) begin + // 100M + count_reg <= count_reg + 1; + rgmii_tx_clk_rise <= 1'b0; + rgmii_tx_clk_fall <= 1'b0; + if (count_reg == 2) begin + rgmii_tx_clk_1 <= 1'b1; + rgmii_tx_clk_2 <= 1'b1; + rgmii_tx_clk_rise <= 1'b1; + end else if (count_reg >= 4) begin + rgmii_tx_clk_2 <= 1'b0; + rgmii_tx_clk_fall <= 1'b1; + count_reg <= 0; + end + end else begin + // 1000M + rgmii_tx_clk_1 <= 1'b1; + rgmii_tx_clk_2 <= 1'b0; + rgmii_tx_clk_rise <= 1'b1; + rgmii_tx_clk_fall <= 1'b1; + end + end +end + +reg [3:0] rgmii_txd_1; +reg [3:0] rgmii_txd_2; +reg rgmii_tx_ctl_1; +reg rgmii_tx_ctl_2; + +reg gmii_clk_en; + +always @* begin + if (speed == 2'b00) begin + // 10M + rgmii_txd_1 = mac_gmii_txd[3:0]; + rgmii_txd_2 = mac_gmii_txd[3:0]; + if (rgmii_tx_clk_2) begin + rgmii_tx_ctl_1 = mac_gmii_tx_en; + rgmii_tx_ctl_2 = mac_gmii_tx_en; + end else begin + rgmii_tx_ctl_1 = mac_gmii_tx_en ^ mac_gmii_tx_er; + rgmii_tx_ctl_2 = mac_gmii_tx_en ^ mac_gmii_tx_er; + end + gmii_clk_en = rgmii_tx_clk_fall; + end else if (speed == 2'b01) begin + // 100M + rgmii_txd_1 = mac_gmii_txd[3:0]; + rgmii_txd_2 = mac_gmii_txd[3:0]; + if (rgmii_tx_clk_2) begin + rgmii_tx_ctl_1 = mac_gmii_tx_en; + rgmii_tx_ctl_2 = mac_gmii_tx_en; + end else begin + rgmii_tx_ctl_1 = mac_gmii_tx_en ^ mac_gmii_tx_er; + rgmii_tx_ctl_2 = mac_gmii_tx_en ^ mac_gmii_tx_er; + end + gmii_clk_en = rgmii_tx_clk_fall; + end else begin + // 1000M + rgmii_txd_1 = mac_gmii_txd[3:0]; + rgmii_txd_2 = mac_gmii_txd[7:4]; + rgmii_tx_ctl_1 = mac_gmii_tx_en; + rgmii_tx_ctl_2 = mac_gmii_tx_en ^ mac_gmii_tx_er; + gmii_clk_en = 1; + end +end + +wire phy_rgmii_tx_clk_new; +wire [3:0] phy_rgmii_txd_new; +wire phy_rgmii_tx_ctl_new; + +oddr #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .WIDTH(1) +) +clk_oddr_inst ( + .clk(USE_CLK90 == "TRUE" ? clk90 : clk), + .d1(rgmii_tx_clk_1), + .d2(rgmii_tx_clk_2), + .q(phy_rgmii_tx_clk) +); + +oddr #( .TARGET(TARGET), .IODDR_STYLE(IODDR_STYLE), - .USE_CLK90(USE_CLK90), .WIDTH(5) ) -tx_ssio_ddr_inst ( +data_oddr_inst ( .clk(clk), - .clk90(clk90), - .input_d1({mac_gmii_txd[3:0], mac_gmii_tx_en}), - .input_d2({mac_gmii_txd[7:4], mac_gmii_tx_en ^ mac_gmii_tx_er}), - .output_clk(phy_rgmii_tx_clk), - .output_q({phy_rgmii_txd, phy_rgmii_tx_ctl}) + .d1({rgmii_txd_1, rgmii_tx_ctl_1}), + .d2({rgmii_txd_2, rgmii_tx_ctl_2}), + .q({phy_rgmii_txd, phy_rgmii_tx_ctl}) ); assign mac_gmii_tx_clk = clk; +assign mac_gmii_tx_clk_en = gmii_clk_en; + // reset sync reg [3:0] tx_rst_reg = 4'hf; assign mac_gmii_tx_rst = tx_rst_reg[0]; diff --git a/tb/test_eth_mac_1g_rgmii.py b/tb/test_eth_mac_1g_rgmii.py new file mode 100755 index 000000000..37235904a --- /dev/null +++ b/tb/test_eth_mac_1g_rgmii.py @@ -0,0 +1,344 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import axis_ep +import eth_ep +import rgmii_ep + +module = 'eth_mac_1g_rgmii' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("../rtl/axis_gmii_rx.v") +srcs.append("../rtl/axis_gmii_tx.v") +srcs.append("../rtl/eth_mac_1g.v") +srcs.append("../rtl/rgmii_phy_if.v") +srcs.append("../rtl/iddr.v") +srcs.append("../rtl/oddr.v") +srcs.append("../rtl/ssio_ddr_in.v") +srcs.append("../rtl/ssio_ddr_out.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + TARGET = "SIM" + IODDR_STYLE = "IODDR2" + CLOCK_INPUT_STYLE = "BUFIO2" + USE_CLK90 = "TRUE" + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + gtx_clk = Signal(bool(0)) + gtx_clk90 = Signal(bool(0)) + gtx_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[8:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + rgmii_rx_clk = Signal(bool(0)) + rgmii_rxd = Signal(intbv(0)[4:]) + rgmii_rx_ctl = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[8:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + rgmii_tx_clk = Signal(bool(0)) + rgmii_txd = Signal(intbv(0)[4:]) + rgmii_tx_ctl = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + speed = Signal(intbv(0)[2:]) + + # sources and sinks + axis_source_pause = Signal(bool(0)) + + mii_select = Signal(bool(0)) + + rgmii_source = rgmii_ep.RGMIISource() + + rgmii_source_logic = rgmii_source.create_logic( + rgmii_rx_clk, + rst, + txd=rgmii_rxd, + tx_ctl=rgmii_rx_ctl, + mii_select=mii_select, + name='rgmii_source' + ) + + rgmii_sink = rgmii_ep.RGMIISink() + + rgmii_sink_logic = rgmii_sink.create_logic( + rgmii_tx_clk, + rst, + rxd=rgmii_txd, + rx_ctl=rgmii_tx_ctl, + mii_select=mii_select, + name='rgmii_sink' + ) + + axis_source = axis_ep.AXIStreamSource() + + axis_source_logic = axis_source.create_logic( + tx_clk, + tx_rst, + tdata=tx_axis_tdata, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + pause=axis_source_pause, + name='axis_source' + ) + + axis_sink = axis_ep.AXIStreamSink() + + axis_sink_logic = axis_sink.create_logic( + rgmii_rx_clk, + rx_rst, + tdata=rx_axis_tdata, + tvalid=rx_axis_tvalid, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + name='axis_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, + + gtx_clk=gtx_clk, + gtx_clk90=gtx_clk90, + gtx_rst=gtx_rst, + + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + rgmii_rx_clk=rgmii_rx_clk, + rgmii_rxd=rgmii_rxd, + rgmii_rx_ctl=rgmii_rx_ctl, + + rgmii_tx_clk=rgmii_tx_clk, + rgmii_txd=rgmii_txd, + rgmii_tx_ctl=rgmii_tx_ctl, + + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + speed=speed, + + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + gtx_clk.next = not clk + + @instance + def clkgen2(): + yield delay(4+2) + while True: + gtx_clk90.next = not gtx_clk90 + yield delay(4) + + rx_clk_hp = Signal(int(4)) + + @instance + def rx_clk_gen(): + while True: + yield delay(int(rx_clk_hp)) + rgmii_rx_clk.next = not rgmii_rx_clk + + rx_error_bad_frame_asserted = Signal(bool(0)) + rx_error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_bad_frame): + rx_error_bad_frame_asserted.next = 1 + if (rx_error_bad_fcs): + rx_error_bad_fcs_asserted.next = 1 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + gtx_rst.next = 1 + yield clk.posedge + rst.next = 0 + gtx_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + for rate, mii in [(4, 0), (20, 1), (200, 1)]: + rx_clk_hp.next = rate + mii_select.next = mii + + yield delay(1000) + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + rgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + + while not (rgmii_rx_ctl or rgmii_tx_ctl): + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + + while rgmii_rx_ctl or rgmii_tx_ctl or tx_axis_tvalid or rx_axis_tvalid: + yield rgmii_rx_clk.posedge + + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + + rx_frame = axis_sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + + while not (rgmii_rx_ctl or rgmii_tx_ctl): + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + + while rgmii_rx_ctl or rgmii_tx_ctl or tx_axis_tvalid or rx_axis_tvalid: + yield rgmii_rx_clk.posedge + + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + + rx_frame = rgmii_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return dut, monitor, axis_source_logic, axis_sink_logic, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, rx_clk_gen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_1g_rgmii.v b/tb/test_eth_mac_1g_rgmii.v new file mode 100644 index 000000000..c443998dd --- /dev/null +++ b/tb/test_eth_mac_1g_rgmii.v @@ -0,0 +1,154 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for eth_mac_1g_rgmii + */ +module test_eth_mac_1g_rgmii; + +// Parameters +parameter TARGET = "SIM"; +parameter IODDR_STYLE = "IODDR2"; +parameter CLOCK_INPUT_STYLE = "BUFIO2"; +parameter USE_CLK90 = "TRUE"; +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg gtx_clk = 0; +reg gtx_clk90 = 0; +reg gtx_rst = 0; +reg [7:0] tx_axis_tdata = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg rgmii_rx_clk = 0; +reg [3:0] rgmii_rxd = 0; +reg rgmii_rx_ctl = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire rx_clk; +wire rx_rst; +wire tx_clk; +wire tx_rst; +wire tx_axis_tready; +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire rgmii_tx_clk; +wire [3:0] rgmii_txd; +wire rgmii_tx_ctl; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; +wire [1:0] speed; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + gtx_clk, + gtx_clk90, + gtx_rst, + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + rgmii_rx_clk, + rgmii_rxd, + rgmii_rx_ctl, + ifg_delay + ); + $to_myhdl( + rx_clk, + rx_rst, + tx_clk, + tx_rst, + tx_axis_tready, + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + rgmii_tx_clk, + rgmii_txd, + rgmii_tx_ctl, + rx_error_bad_frame, + rx_error_bad_fcs, + speed + ); + + // dump file + $dumpfile("test_eth_mac_1g_rgmii.lxt"); + $dumpvars(0, test_eth_mac_1g_rgmii); +end + +eth_mac_1g_rgmii #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .USE_CLK90(USE_CLK90), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .gtx_clk(gtx_clk), + .gtx_clk90(gtx_clk90), + .gtx_rst(gtx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .rgmii_rx_clk(rgmii_rx_clk), + .rgmii_rxd(rgmii_rxd), + .rgmii_rx_ctl(rgmii_rx_ctl), + .rgmii_tx_clk(rgmii_tx_clk), + .rgmii_txd(rgmii_txd), + .rgmii_tx_ctl(rgmii_tx_ctl), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .speed(speed), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/tb/test_eth_mac_1g_rgmii_fifo.py b/tb/test_eth_mac_1g_rgmii_fifo.py new file mode 100755 index 000000000..f6eacf5fe --- /dev/null +++ b/tb/test_eth_mac_1g_rgmii_fifo.py @@ -0,0 +1,367 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import axis_ep +import eth_ep +import rgmii_ep + +module = 'eth_mac_1g_rgmii_fifo' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("../rtl/axis_gmii_rx.v") +srcs.append("../rtl/axis_gmii_tx.v") +srcs.append("../rtl/eth_mac_1g.v") +srcs.append("../rtl/eth_mac_1g_rgmii.v") +srcs.append("../rtl/rgmii_phy_if.v") +srcs.append("../rtl/iddr.v") +srcs.append("../rtl/oddr.v") +srcs.append("../rtl/ssio_ddr_in.v") +srcs.append("../rtl/ssio_ddr_out.v") +srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + TARGET = "SIM" + IODDR_STYLE = "IODDR2" + CLOCK_INPUT_STYLE = "BUFIO2" + USE_CLK90 = "TRUE" + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + gtx_clk = Signal(bool(0)) + gtx_clk90 = Signal(bool(0)) + gtx_rst = Signal(bool(0)) + logic_clk = Signal(bool(0)) + logic_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[8:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + rx_axis_tready = Signal(bool(0)) + rgmii_rx_clk = Signal(bool(0)) + rgmii_rxd = Signal(intbv(0)[4:]) + rgmii_rx_ctl = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[8:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + rgmii_tx_clk = Signal(bool(0)) + rgmii_txd = Signal(intbv(0)[4:]) + rgmii_tx_ctl = Signal(bool(0)) + tx_fifo_overflow = Signal(bool(0)) + tx_fifo_bad_frame = Signal(bool(0)) + tx_fifo_good_frame = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + rx_fifo_overflow = Signal(bool(0)) + rx_fifo_bad_frame = Signal(bool(0)) + rx_fifo_good_frame = Signal(bool(0)) + speed = Signal(intbv(0)[2:]) + + # sources and sinks + axis_source_pause = Signal(bool(0)) + axis_sink_pause = Signal(bool(0)) + + mii_select = Signal(bool(0)) + + rgmii_source = rgmii_ep.RGMIISource() + + rgmii_source_logic = rgmii_source.create_logic( + rgmii_rx_clk, + rst, + txd=rgmii_rxd, + tx_ctl=rgmii_rx_ctl, + mii_select=mii_select, + name='rgmii_source' + ) + + rgmii_sink = rgmii_ep.RGMIISink() + + rgmii_sink_logic = rgmii_sink.create_logic( + rgmii_tx_clk, + rst, + rxd=rgmii_txd, + rx_ctl=rgmii_tx_ctl, + mii_select=mii_select, + name='rgmii_sink' + ) + + axis_source = axis_ep.AXIStreamSource() + + axis_source_logic = axis_source.create_logic( + logic_clk, + logic_rst, + tdata=tx_axis_tdata, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + pause=axis_source_pause, + name='axis_source' + ) + + axis_sink = axis_ep.AXIStreamSink() + + axis_sink_logic = axis_sink.create_logic( + logic_clk, + logic_rst, + tdata=rx_axis_tdata, + tvalid=rx_axis_tvalid, + tready=rx_axis_tready, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + pause=axis_sink_pause, + name='axis_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, + + gtx_clk=gtx_clk, + gtx_clk90=gtx_clk90, + gtx_rst=gtx_rst, + logic_clk=logic_clk, + logic_rst=logic_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tready=rx_axis_tready, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + rgmii_rx_clk=rgmii_rx_clk, + rgmii_rxd=rgmii_rxd, + rgmii_rx_ctl=rgmii_rx_ctl, + + rgmii_tx_clk=rgmii_tx_clk, + rgmii_txd=rgmii_txd, + rgmii_tx_ctl=rgmii_tx_ctl, + + tx_fifo_overflow=tx_fifo_overflow, + tx_fifo_bad_frame=tx_fifo_bad_frame, + tx_fifo_good_frame=tx_fifo_good_frame, + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + rx_fifo_overflow=rx_fifo_overflow, + rx_fifo_bad_frame=rx_fifo_bad_frame, + rx_fifo_good_frame=rx_fifo_good_frame, + speed=speed, + + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + gtx_clk.next = not clk + logic_clk.next = not clk + + @instance + def clkgen2(): + yield delay(4+2) + while True: + gtx_clk90.next = not gtx_clk90 + yield delay(4) + + rx_clk_hp = Signal(int(4)) + + @instance + def rx_clk_gen(): + while True: + yield delay(int(rx_clk_hp)) + rgmii_rx_clk.next = not rgmii_rx_clk + + rx_error_bad_frame_asserted = Signal(bool(0)) + rx_error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_bad_frame): + rx_error_bad_frame_asserted.next = 1 + if (rx_error_bad_fcs): + rx_error_bad_fcs_asserted.next = 1 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + gtx_rst.next = 1 + logic_rst.next = 1 + yield clk.posedge + rst.next = 0 + gtx_rst.next = 0 + logic_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + for rate, mii in [(4, 0), (20, 1), (200, 1)]: + rx_clk_hp.next = rate + mii_select.next = mii + + yield delay(1000) + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + rgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + + while rgmii_rx_ctl: + yield rgmii_rx_clk.posedge + + for k in range(10): + yield rgmii_rx_clk.posedge + + while rx_axis_tvalid: + yield rgmii_rx_clk.posedge + + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + + rx_frame = axis_sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + + while tx_axis_tvalid: + yield rgmii_rx_clk.posedge + + for k in range(10): + yield rgmii_rx_clk.posedge + + while rgmii_tx_ctl: + yield rgmii_rx_clk.posedge + + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + yield rgmii_rx_clk.posedge + + rx_frame = rgmii_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return dut, monitor, axis_source_logic, axis_sink_logic, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, rx_clk_gen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_1g_rgmii_fifo.v b/tb/test_eth_mac_1g_rgmii_fifo.v new file mode 100644 index 000000000..1ec057a69 --- /dev/null +++ b/tb/test_eth_mac_1g_rgmii_fifo.v @@ -0,0 +1,173 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for eth_mac_1g_rgmii_fifo + */ +module test_eth_mac_1g_rgmii_fifo; + +// Parameters +parameter TARGET = "SIM"; +parameter IODDR_STYLE = "IODDR2"; +parameter CLOCK_INPUT_STYLE = "BUFIO2"; +parameter USE_CLK90 = "TRUE"; +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; +parameter TX_FIFO_ADDR_WIDTH = 9; +parameter RX_FIFO_ADDR_WIDTH = 9; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg gtx_clk = 0; +reg gtx_clk90 = 0; +reg gtx_rst = 0; +reg logic_clk = 0; +reg logic_rst = 0; +reg [7:0] tx_axis_tdata = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg rx_axis_tready = 0; +reg rgmii_rx_clk = 0; +reg [3:0] rgmii_rxd = 0; +reg rgmii_rx_ctl = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire rgmii_tx_clk; +wire [3:0] rgmii_txd; +wire rgmii_tx_ctl; +wire tx_fifo_overflow; +wire tx_fifo_bad_frame; +wire tx_fifo_good_frame; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; +wire rx_fifo_overflow; +wire rx_fifo_bad_frame; +wire rx_fifo_good_frame; +wire [1:0] speed; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + gtx_clk, + gtx_clk90, + gtx_rst, + logic_clk, + logic_rst, + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + rx_axis_tready, + rgmii_rx_clk, + rgmii_rxd, + rgmii_rx_ctl, + ifg_delay + ); + $to_myhdl( + tx_axis_tready, + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + rgmii_tx_clk, + rgmii_txd, + rgmii_tx_ctl, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, + rx_error_bad_frame, + rx_error_bad_fcs, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame, + speed + ); + + // dump file + $dumpfile("test_eth_mac_1g_rgmii_fifo.lxt"); + $dumpvars(0, test_eth_mac_1g_rgmii_fifo); +end + +eth_mac_1g_rgmii_fifo #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .USE_CLK90(USE_CLK90), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .TX_FIFO_ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .RX_FIFO_ADDR_WIDTH(RX_FIFO_ADDR_WIDTH) +) +UUT ( + .gtx_clk(gtx_clk), + .gtx_clk90(gtx_clk90), + .gtx_rst(gtx_rst), + .logic_clk(logic_clk), + .logic_rst(logic_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .rgmii_rx_clk(rgmii_rx_clk), + .rgmii_rxd(rgmii_rxd), + .rgmii_rx_ctl(rgmii_rx_ctl), + .rgmii_tx_clk(rgmii_tx_clk), + .rgmii_txd(rgmii_txd), + .rgmii_tx_ctl(rgmii_tx_ctl), + .tx_fifo_overflow(tx_fifo_overflow), + .tx_fifo_bad_frame(tx_fifo_bad_frame), + .tx_fifo_good_frame(tx_fifo_good_frame), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(rx_fifo_overflow), + .rx_fifo_bad_frame(rx_fifo_bad_frame), + .rx_fifo_good_frame(rx_fifo_good_frame), + .speed(speed), + .ifg_delay(ifg_delay) +); + +endmodule From a8a423da0e3b2605f3625c6e6baa7f25dd6a34aa Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 May 2017 19:35:40 -0700 Subject: [PATCH 333/617] Update Atlys example design --- example/ATLYS/fpga/clock.ucf | 2 +- example/ATLYS/fpga/fpga.ucf | 45 +++++++-------- example/ATLYS/fpga/fpga/Makefile | 7 ++- example/ATLYS/fpga/rtl/fpga.v | 2 + example/ATLYS/fpga/rtl/fpga_core.v | 75 ++++++++----------------- example/ATLYS/fpga/tb/test_fpga_core.py | 25 +++++++-- example/ATLYS/fpga/tb/test_fpga_core.v | 3 + 7 files changed, 75 insertions(+), 84 deletions(-) diff --git a/example/ATLYS/fpga/clock.ucf b/example/ATLYS/fpga/clock.ucf index d954d3a0d..cbb807916 100644 --- a/example/ATLYS/fpga/clock.ucf +++ b/example/ATLYS/fpga/clock.ucf @@ -1,6 +1,6 @@ # UCF file for clock module domain crossing constraints NET "clk_int" TNM = "ffs_clk_int"; -NET "core_inst/gmii_rx_clk" TNM = "ffs_gmii_rx_clk"; +NET "core_inst/eth_mac_inst/rx_clk" TNM = "ffs_gmii_rx_clk"; TIMESPEC "TS_clk_int_to_gmii_rx_clk" = FROM "ffs_clk_int" TO "ffs_gmii_rx_clk" 10 ns; TIMESPEC "TS_gmii_rx_clk_to_clk_int" = FROM "ffs_gmii_rx_clk" TO "ffs_clk_int" 10 ns; diff --git a/example/ATLYS/fpga/fpga.ucf b/example/ATLYS/fpga/fpga.ucf index 5dd47d228..292615b76 100644 --- a/example/ATLYS/fpga/fpga.ucf +++ b/example/ATLYS/fpga/fpga.ucf @@ -45,28 +45,29 @@ NET "phy_reset_n" LOC = "G13" | IOSTANDARD=LVCMOS25; # IO_L32N_A16_M1A9 (E-RESET #NET "phy_mdio" LOC = "N17" | IOSTANDARD=LVCMOS25; # IO_L48P_HDC_M1DQ8 (E-MDIO) # GMII Transmit NET "phy_gtx_clk" LOC = "L12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L40P_GCLK11_M1A5 (E-GTXCLK) -NET "phy_txd<0>" LOC = "H16" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L37N_A6_M1A1 (E-TXD0) -NET "phy_txd<1>" LOC = "H13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L36P_A9_M1BA0 (E-TXD1) -NET "phy_txd<2>" LOC = "K14" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L39N_M1ODT (E-TXD2) -NET "phy_txd<3>" LOC = "K13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L34N_A12_M1BA2 (E-TXD3) -NET "phy_txd<4>" LOC = "J13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L39P_M1A3 (E-TXD4) -NET "phy_txd<5>" LOC = "G14" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L30N_A20_M1A11 (E-TXD5) -NET "phy_txd<6>" LOC = "H12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L32P_A17_M1A8 (E-TXD6) -NET "phy_txd<7>" LOC = "K12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L34P_A13_M1WE (E-TXD7) -NET "phy_tx_en" LOC = "H15" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L37P_A7_M1A0 (E-TXEN) -NET "phy_tx_er" LOC = "G18" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L38N_A4_M1CLKN (E-TXER) -# GMII Receive (not used) -NET "phy_rx_clk" LOC = "K15" | IOSTANDARD=LVCMOS25 | TNM_NET = "clk_rx_local"; # IO_L41P_GCLK9_IRDY1_M1RASN (E-RXCLK) -NET "phy_rxd<0>" LOC = "G16" | IOSTANDARD=LVCMOS25; # IO_L38P_A5_M1CLK (E-RXD0) -NET "phy_rxd<1>" LOC = "H14" | IOSTANDARD=LVCMOS25; # IO_L36N_A8_M1BA1 (E-RXD1) -NET "phy_rxd<2>" LOC = "E16" | IOSTANDARD=LVCMOS25; # IO_L33P_A15_M1A10 (E-RXD2) -NET "phy_rxd<3>" LOC = "F15" | IOSTANDARD=LVCMOS25; # IO_L1P_A25 (E-RXD3) -NET "phy_rxd<4>" LOC = "F14" | IOSTANDARD=LVCMOS25; # IO_L30P_A21_M1RESET (E-RXD4) -NET "phy_rxd<5>" LOC = "E18" | IOSTANDARD=LVCMOS25; # IO_L33N_A14_M1A4 (E-RXD5) -NET "phy_rxd<6>" LOC = "D18" | IOSTANDARD=LVCMOS25; # IO_L31N_A18_M1A12 (E-RXD6) -NET "phy_rxd<7>" LOC = "D17" | IOSTANDARD=LVCMOS25; # IO_L31P_A19_M1CKE (E-RXD7) -NET "phy_rx_dv" LOC = "F17" | IOSTANDARD=LVCMOS25; # IO_L35P_A11_M1A7 (E-RXDV) -NET "phy_rx_er" LOC = "F18" | IOSTANDARD=LVCMOS25; # IO_L35N_A10_M1A2 (E-RXER) +NET "phy_tx_clk" LOC = "K16" | IOSTANDARD=LVCMOS25; # IO_L41N_GCLK8_M1CASN (E-TXCLK) +NET "phy_txd<0>" LOC = "H16" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L37N_A6_M1A1 (E-TXD0) +NET "phy_txd<1>" LOC = "H13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L36P_A9_M1BA0 (E-TXD1) +NET "phy_txd<2>" LOC = "K14" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L39N_M1ODT (E-TXD2) +NET "phy_txd<3>" LOC = "K13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L34N_A12_M1BA2 (E-TXD3) +NET "phy_txd<4>" LOC = "J13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L39P_M1A3 (E-TXD4) +NET "phy_txd<5>" LOC = "G14" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L30N_A20_M1A11 (E-TXD5) +NET "phy_txd<6>" LOC = "H12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L32P_A17_M1A8 (E-TXD6) +NET "phy_txd<7>" LOC = "K12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L34P_A13_M1WE (E-TXD7) +NET "phy_tx_en" LOC = "H15" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L37P_A7_M1A0 (E-TXEN) +NET "phy_tx_er" LOC = "G18" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L38N_A4_M1CLKN (E-TXER) +# GMII Receive +NET "phy_rx_clk" LOC = "K15" | IOSTANDARD=LVCMOS25 | TNM_NET = "clk_rx_local"; # IO_L41P_GCLK9_IRDY1_M1RASN (E-RXCLK) +NET "phy_rxd<0>" LOC = "G16" | IOSTANDARD=LVCMOS25; # IO_L38P_A5_M1CLK (E-RXD0) +NET "phy_rxd<1>" LOC = "H14" | IOSTANDARD=LVCMOS25; # IO_L36N_A8_M1BA1 (E-RXD1) +NET "phy_rxd<2>" LOC = "E16" | IOSTANDARD=LVCMOS25; # IO_L33P_A15_M1A10 (E-RXD2) +NET "phy_rxd<3>" LOC = "F15" | IOSTANDARD=LVCMOS25; # IO_L1P_A25 (E-RXD3) +NET "phy_rxd<4>" LOC = "F14" | IOSTANDARD=LVCMOS25; # IO_L30P_A21_M1RESET (E-RXD4) +NET "phy_rxd<5>" LOC = "E18" | IOSTANDARD=LVCMOS25; # IO_L33N_A14_M1A4 (E-RXD5) +NET "phy_rxd<6>" LOC = "D18" | IOSTANDARD=LVCMOS25; # IO_L31N_A18_M1A12 (E-RXD6) +NET "phy_rxd<7>" LOC = "D17" | IOSTANDARD=LVCMOS25; # IO_L31P_A19_M1CKE (E-RXD7) +NET "phy_rx_dv" LOC = "F17" | IOSTANDARD=LVCMOS25; # IO_L35P_A11_M1A7 (E-RXDV) +NET "phy_rx_er" LOC = "F18" | IOSTANDARD=LVCMOS25; # IO_L35N_A10_M1A2 (E-RXER) # Timing constraints for Ethernet PHY TIMESPEC "TS_rx_clk_root" = PERIOD "clk_rx_local" 8000 ps HIGH 50 %; diff --git a/example/ATLYS/fpga/fpga/Makefile b/example/ATLYS/fpga/fpga/Makefile index ac22c62f3..ce0381e91 100644 --- a/example/ATLYS/fpga/fpga/Makefile +++ b/example/ATLYS/fpga/fpga/Makefile @@ -19,10 +19,11 @@ SYN_FILES += lib/eth/rtl/oddr.v SYN_FILES += lib/eth/rtl/ssio_sdr_in.v SYN_FILES += lib/eth/rtl/ssio_sdr_out.v SYN_FILES += lib/eth/rtl/gmii_phy_if.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_gmii_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_gmii.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx.v SYN_FILES += lib/eth/rtl/eth_axis_tx.v diff --git a/example/ATLYS/fpga/rtl/fpga.v b/example/ATLYS/fpga/rtl/fpga.v index 8ea58703a..17edb11d1 100644 --- a/example/ATLYS/fpga/rtl/fpga.v +++ b/example/ATLYS/fpga/rtl/fpga.v @@ -56,6 +56,7 @@ module fpga ( input wire phy_rx_dv, input wire phy_rx_er, output wire phy_gtx_clk, + input wire phy_tx_clk, output wire [7:0] phy_txd, output wire phy_tx_en, output wire phy_tx_er, @@ -205,6 +206,7 @@ core_inst ( .phy_rx_dv(phy_rx_dv), .phy_rx_er(phy_rx_er), .phy_gtx_clk(phy_gtx_clk), + .phy_tx_clk(phy_tx_clk), .phy_txd(phy_txd), .phy_tx_en(phy_tx_en), .phy_tx_er(phy_tx_er), diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index 90ffd07e5..0cab0ddef 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -60,6 +60,7 @@ module fpga_core # input wire phy_rx_dv, input wire phy_rx_er, output wire phy_gtx_clk, + input wire phy_tx_clk, output wire [7:0] phy_txd, output wire phy_tx_en, output wire phy_tx_er, @@ -72,19 +73,6 @@ module fpga_core # output wire uart_txd ); -// GMII between MAC and PHY IF -wire gmii_rx_clk; -wire gmii_rx_rst; -wire [7:0] gmii_rxd; -wire gmii_rx_dv; -wire gmii_rx_er; - -wire gmii_tx_clk; -wire gmii_tx_rst; -wire [7:0] gmii_txd; -wire gmii_tx_en; -wire gmii_tx_er; - // AXI between MAC and Ethernet modules wire [7:0] rx_axis_tdata; wire rx_axis_tvalid; @@ -322,47 +310,18 @@ assign phy_reset_n = ~rst; assign uart_txd = 0; -gmii_phy_if #( +eth_mac_1g_gmii_fifo #( .TARGET(TARGET), .IODDR_STYLE("IODDR2"), - .CLOCK_INPUT_STYLE("BUFIO2") -) -gmii_phy_if_inst ( - .clk(clk), - .rst(rst), - - .mac_gmii_rx_clk(gmii_rx_clk), - .mac_gmii_rx_rst(gmii_rx_rst), - .mac_gmii_rxd(gmii_rxd), - .mac_gmii_rx_dv(gmii_rx_dv), - .mac_gmii_rx_er(gmii_rx_er), - .mac_gmii_tx_clk(gmii_tx_clk), - .mac_gmii_tx_rst(gmii_tx_rst), - .mac_gmii_txd(gmii_txd), - .mac_gmii_tx_en(gmii_tx_en), - .mac_gmii_tx_er(gmii_tx_er), - - .phy_gmii_rx_clk(phy_rx_clk), - .phy_gmii_rxd(phy_rxd), - .phy_gmii_rx_dv(phy_rx_dv), - .phy_gmii_rx_er(phy_rx_er), - .phy_gmii_tx_clk(phy_gtx_clk), - .phy_gmii_txd(phy_txd), - .phy_gmii_tx_en(phy_tx_en), - .phy_gmii_tx_er(phy_tx_er) -); - -eth_mac_1g_fifo #( + .CLOCK_INPUT_STYLE("BUFIO2"), .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), .RX_FIFO_ADDR_WIDTH(12) ) -eth_mac_1g_fifo_inst ( - .rx_clk(gmii_rx_clk), - .rx_rst(gmii_rx_rst), - .tx_clk(gmii_tx_clk), - .tx_rst(gmii_tx_rst), +eth_mac_inst ( + .gtx_clk(clk), + .gtx_rst(rst), .logic_clk(clk), .logic_rst(rst), @@ -378,15 +337,25 @@ eth_mac_1g_fifo_inst ( .rx_axis_tlast(rx_axis_tlast), .rx_axis_tuser(rx_axis_tuser), - .gmii_rxd(gmii_rxd), - .gmii_rx_dv(gmii_rx_dv), - .gmii_rx_er(gmii_rx_er), - .gmii_txd(gmii_txd), - .gmii_tx_en(gmii_tx_en), - .gmii_tx_er(gmii_tx_er), + .gmii_rx_clk(phy_rx_clk), + .gmii_rxd(phy_rxd), + .gmii_rx_dv(phy_rx_dv), + .gmii_rx_er(phy_rx_er), + .gmii_tx_clk(phy_gtx_clk), + .mii_tx_clk(phy_tx_clk), + .gmii_txd(phy_txd), + .gmii_tx_en(phy_tx_en), + .gmii_tx_er(phy_tx_er), + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + .speed(), .ifg_delay(12) ); diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index 1785ffb79..35ad07823 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -42,10 +42,11 @@ srcs.append("../lib/eth/rtl/oddr.v") srcs.append("../lib/eth/rtl/ssio_sdr_in.v") srcs.append("../lib/eth/rtl/ssio_sdr_out.v") srcs.append("../lib/eth/rtl/gmii_phy_if.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_gmii_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_gmii.v") srcs.append("../lib/eth/rtl/eth_mac_1g.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") @@ -96,6 +97,7 @@ def bench(): phy_rxd = Signal(intbv(0)[8:]) phy_rx_dv = Signal(bool(0)) phy_rx_er = Signal(bool(0)) + phy_tx_clk = Signal(bool(0)) uart_rxd = Signal(bool(0)) # Outputs @@ -108,6 +110,8 @@ def bench(): uart_txd = Signal(bool(0)) # sources and sinks + mii_select = Signal(bool(0)) + gmii_source = gmii_ep.GMIISource() gmii_source_logic = gmii_source.create_logic( @@ -116,6 +120,7 @@ def bench(): txd=phy_rxd, tx_en=phy_rx_dv, tx_er=phy_rx_er, + mii_select=mii_select, name='gmii_source' ) @@ -127,6 +132,7 @@ def bench(): rxd=phy_txd, rx_dv=phy_tx_en, rx_er=phy_tx_er, + mii_select=mii_select, name='gmii_sink' ) @@ -153,6 +159,7 @@ def bench(): phy_rx_dv=phy_rx_dv, phy_rx_er=phy_rx_er, phy_gtx_clk=phy_gtx_clk, + phy_tx_clk=phy_tx_clk, phy_txd=phy_txd, phy_tx_en=phy_tx_en, phy_tx_er=phy_tx_er, @@ -165,7 +172,15 @@ def bench(): @always(delay(4)) def clkgen(): clk.next = not clk - phy_rx_clk.next = not phy_rx_clk + + rx_clk_hp = Signal(int(4)) + + @instance + def rx_clk_gen(): + while True: + yield delay(int(rx_clk_hp)) + phy_rx_clk.next = not phy_rx_clk + phy_tx_clk.next = not phy_tx_clk @instance def check(): @@ -286,7 +301,7 @@ def bench(): raise StopSimulation - return dut, gmii_source_logic, gmii_sink_logic, clkgen, check + return dut, gmii_source_logic, gmii_sink_logic, clkgen, rx_clk_gen, check def test_bench(): sim = Simulation(bench()) diff --git a/example/ATLYS/fpga/tb/test_fpga_core.v b/example/ATLYS/fpga/tb/test_fpga_core.v index ada2a57a9..3c3a8816a 100644 --- a/example/ATLYS/fpga/tb/test_fpga_core.v +++ b/example/ATLYS/fpga/tb/test_fpga_core.v @@ -49,6 +49,7 @@ reg phy_rx_clk = 0; reg [7:0] phy_rxd = 0; reg phy_rx_dv = 0; reg phy_rx_er = 0; +reg phy_tx_clk = 0; reg uart_rxd = 0; // Outputs @@ -76,6 +77,7 @@ initial begin phy_rxd, phy_rx_dv, phy_rx_er, + phy_tx_clk, uart_rxd ); $to_myhdl( @@ -111,6 +113,7 @@ UUT ( .phy_rx_dv(phy_rx_dv), .phy_rx_er(phy_rx_er), .phy_gtx_clk(phy_gtx_clk), + .phy_tx_clk(phy_tx_clk), .phy_txd(phy_txd), .phy_tx_en(phy_tx_en), .phy_tx_er(phy_tx_er), From 9fdc36450ad2c08ede02112ceac1cf0b51bfc74a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 May 2017 19:44:39 -0700 Subject: [PATCH 334/617] Update NexysVideo reference design --- example/NexysVideo/fpga/fpga/Makefile | 7 +- example/NexysVideo/fpga/rtl/fpga_core.v | 73 ++++++-------------- example/NexysVideo/fpga/tb/test_fpga_core.py | 22 ++++-- 3 files changed, 41 insertions(+), 61 deletions(-) diff --git a/example/NexysVideo/fpga/fpga/Makefile b/example/NexysVideo/fpga/fpga/Makefile index 83d89a4ea..3c4d634dd 100644 --- a/example/NexysVideo/fpga/fpga/Makefile +++ b/example/NexysVideo/fpga/fpga/Makefile @@ -15,10 +15,11 @@ SYN_FILES += lib/eth/rtl/oddr.v SYN_FILES += lib/eth/rtl/ssio_ddr_in.v SYN_FILES += lib/eth/rtl/ssio_ddr_out.v SYN_FILES += lib/eth/rtl/rgmii_phy_if.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rgmii_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rgmii.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx.v SYN_FILES += lib/eth/rtl/eth_axis_tx.v diff --git a/example/NexysVideo/fpga/rtl/fpga_core.v b/example/NexysVideo/fpga/rtl/fpga_core.v index a50935404..b333f246a 100644 --- a/example/NexysVideo/fpga/rtl/fpga_core.v +++ b/example/NexysVideo/fpga/rtl/fpga_core.v @@ -73,19 +73,6 @@ module fpga_core # output wire uart_txd ); -// GMII between MAC and PHY IF -wire gmii_rx_clk; -wire gmii_rx_rst; -wire [7:0] gmii_rxd; -wire gmii_rx_dv; -wire gmii_rx_er; - -wire gmii_tx_clk; -wire gmii_tx_rst; -wire [7:0] gmii_txd; -wire gmii_tx_en; -wire gmii_tx_er; - // AXI between MAC and Ethernet modules wire [7:0] rx_axis_tdata; wire rx_axis_tvalid; @@ -323,47 +310,20 @@ assign phy_reset_n = ~rst; assign uart_txd = 0; -rgmii_phy_if #( +eth_mac_1g_rgmii_fifo #( .TARGET(TARGET), .IODDR_STYLE("IODDR"), .CLOCK_INPUT_STYLE("BUFR"), - .USE_CLK90("TRUE") -) -rgmii_phy_if_inst ( - .clk(clk), - .clk90(clk90), - .rst(rst), - - .mac_gmii_rx_clk(gmii_rx_clk), - .mac_gmii_rx_rst(gmii_rx_rst), - .mac_gmii_rxd(gmii_rxd), - .mac_gmii_rx_dv(gmii_rx_dv), - .mac_gmii_rx_er(gmii_rx_er), - .mac_gmii_tx_clk(gmii_tx_clk), - .mac_gmii_tx_rst(gmii_tx_rst), - .mac_gmii_txd(gmii_txd), - .mac_gmii_tx_en(gmii_tx_en), - .mac_gmii_tx_er(gmii_tx_er), - - .phy_rgmii_rx_clk(phy_rx_clk), - .phy_rgmii_rxd(phy_rxd), - .phy_rgmii_rx_ctl(phy_rx_ctl), - .phy_rgmii_tx_clk(phy_tx_clk), - .phy_rgmii_txd(phy_txd), - .phy_rgmii_tx_ctl(phy_tx_ctl) -); - -eth_mac_1g_fifo #( + .USE_CLK90("TRUE"), .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), .RX_FIFO_ADDR_WIDTH(12) ) -eth_mac_1g_fifo_inst ( - .rx_clk(gmii_rx_clk), - .rx_rst(gmii_rx_rst), - .tx_clk(gmii_tx_clk), - .tx_rst(gmii_tx_rst), +eth_mac_inst ( + .gtx_clk(clk), + .gtx_clk90(clk90), + .gtx_rst(rst), .logic_clk(clk), .logic_rst(rst), @@ -379,15 +339,22 @@ eth_mac_1g_fifo_inst ( .rx_axis_tlast(rx_axis_tlast), .rx_axis_tuser(rx_axis_tuser), - .gmii_rxd(gmii_rxd), - .gmii_rx_dv(gmii_rx_dv), - .gmii_rx_er(gmii_rx_er), - .gmii_txd(gmii_txd), - .gmii_tx_en(gmii_tx_en), - .gmii_tx_er(gmii_tx_er), - + .rgmii_rx_clk(phy_rx_clk), + .rgmii_rxd(phy_rxd), + .rgmii_rx_ctl(phy_rx_ctl), + .rgmii_tx_clk(phy_tx_clk), + .rgmii_txd(phy_txd), + .rgmii_tx_ctl(phy_tx_ctl), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + .speed(), .ifg_delay(12) ); diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.py b/example/NexysVideo/fpga/tb/test_fpga_core.py index 738858a62..ec01cbd15 100755 --- a/example/NexysVideo/fpga/tb/test_fpga_core.py +++ b/example/NexysVideo/fpga/tb/test_fpga_core.py @@ -42,10 +42,11 @@ srcs.append("../lib/eth/rtl/oddr.v") srcs.append("../lib/eth/rtl/ssio_ddr_in.v") srcs.append("../lib/eth/rtl/ssio_ddr_out.v") srcs.append("../lib/eth/rtl/rgmii_phy_if.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_rgmii_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_rgmii.v") srcs.append("../lib/eth/rtl/eth_mac_1g.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") @@ -109,6 +110,8 @@ def bench(): uart_txd = Signal(bool(0)) # sources and sinks + mii_select = Signal(bool(0)) + rgmii_source = rgmii_ep.RGMIISource() rgmii_source_logic = rgmii_source.create_logic( @@ -116,6 +119,7 @@ def bench(): rst, txd=phy_rxd, tx_ctl=phy_rx_ctl, + mii_select=mii_select, name='rgmii_source' ) @@ -126,6 +130,7 @@ def bench(): rst, rxd=phy_txd, rx_ctl=phy_tx_ctl, + mii_select=mii_select, name='rgmii_sink' ) @@ -165,7 +170,6 @@ def bench(): @always(delay(4)) def clkgen(): clk.next = not clk - phy_rx_clk.next = not phy_rx_clk @instance def clkgen2(): @@ -174,6 +178,14 @@ def bench(): clk90.next = not clk90 yield delay(4) + rx_clk_hp = Signal(int(4)) + + @instance + def rx_clk_gen(): + while True: + yield delay(int(rx_clk_hp)) + phy_rx_clk.next = not phy_rx_clk + @instance def check(): yield delay(100) @@ -293,7 +305,7 @@ def bench(): raise StopSimulation - return dut, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, check + return dut, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, rx_clk_gen, check def test_bench(): sim = Simulation(bench()) From e376c805d2541e98c0fa8cfd873dc4fa79dd127d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 May 2017 19:52:43 -0700 Subject: [PATCH 335/617] Update ML605 reference design --- example/ML605/fpga/clock.ucf | 2 +- example/ML605/fpga/fpga.ucf | 3 +- example/ML605/fpga/fpga/Makefile | 7 ++- example/ML605/fpga/rtl/fpga.v | 2 + example/ML605/fpga/rtl/fpga_core.v | 75 ++++++++----------------- example/ML605/fpga/tb/test_fpga_core.py | 25 +++++++-- example/ML605/fpga/tb/test_fpga_core.v | 3 + 7 files changed, 54 insertions(+), 63 deletions(-) diff --git a/example/ML605/fpga/clock.ucf b/example/ML605/fpga/clock.ucf index 713379c40..e048a42f1 100644 --- a/example/ML605/fpga/clock.ucf +++ b/example/ML605/fpga/clock.ucf @@ -1,6 +1,6 @@ # UCF file for clock module domain crossing constraints NET "clk_125mhz_int" TNM = "ffs_clk_125mhz_int"; -NET "core_inst/gmii_rx_clk" TNM = "ffs_gmii_rx_clk"; +NET "core_inst/eth_mac_inst/rx_clk" TNM = "ffs_gmii_rx_clk"; TIMESPEC "TS_clk_125mhz_int_to_gmii_rx_clk" = FROM "ffs_clk_125mhz_int" TO "ffs_gmii_rx_clk" 10 ns; TIMESPEC "TS_gmii_rx_clk_to_clk_125mhz_int" = FROM "ffs_gmii_rx_clk" TO "ffs_clk_125mhz_int" 10 ns; diff --git a/example/ML605/fpga/fpga.ucf b/example/ML605/fpga/fpga.ucf index 6ce175d2f..04f830308 100644 --- a/example/ML605/fpga/fpga.ucf +++ b/example/ML605/fpga/fpga.ucf @@ -52,6 +52,7 @@ NET "phy_reset_n" LOC = "AH13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L18P_33 (E #NET "phy_mdio" LOC = "AN14" | IOSTANDARD=LVCMOS25; # (E-MDIO) # GMII Transmit NET "phy_gtx_clk" LOC = "AH12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L16N_33 (E-GTXCLK) +NET "phy_tx_clk" LOC = "AD12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L10P_MRCC_33 (E-TXCLK) NET "phy_txd<0>" LOC = "AM11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L7N_33 (E-TXD0) NET "phy_txd<1>" LOC = "AL11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L7P_33 (E-TXD1) NET "phy_txd<2>" LOC = "AG10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L6N_33 (E-TXD2) @@ -63,7 +64,7 @@ NET "phy_txd<7>" LOC = "AF11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, NET "phy_tx_en" LOC = "AJ10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L8P_SRCC_33 (E-TXEN) NET "phy_tx_er" LOC = "AH10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L8N_SRCC_33 (E-TXER) # GMII Receive -NET "phy_rx_clk" LOC = "AP11" | IOSTANDARD=LVCMOS25 | TNM_NET = "clk_rx_local"; # (E-RXCLK) +NET "phy_rx_clk" LOC = "AP11" | IOSTANDARD=LVCMOS25 | TNM_NET = "clk_rx_local"; # (E-RXCLK) NET "phy_rxd<0>" LOC = "AN13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L15P_33 (E-RXD0) NET "phy_rxd<1>" LOC = "AF14" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L14N_VREF_33 (E-RXD1) NET "phy_rxd<2>" LOC = "AE14" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L14P_33 (E-RXD2) diff --git a/example/ML605/fpga/fpga/Makefile b/example/ML605/fpga/fpga/Makefile index eaa29656c..3fb95b4da 100644 --- a/example/ML605/fpga/fpga/Makefile +++ b/example/ML605/fpga/fpga/Makefile @@ -19,10 +19,11 @@ SYN_FILES += lib/eth/rtl/oddr.v SYN_FILES += lib/eth/rtl/ssio_sdr_in.v SYN_FILES += lib/eth/rtl/ssio_sdr_out.v SYN_FILES += lib/eth/rtl/gmii_phy_if.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_gmii_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_gmii.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx.v SYN_FILES += lib/eth/rtl/eth_axis_tx.v diff --git a/example/ML605/fpga/rtl/fpga.v b/example/ML605/fpga/rtl/fpga.v index 083be485a..372607107 100644 --- a/example/ML605/fpga/rtl/fpga.v +++ b/example/ML605/fpga/rtl/fpga.v @@ -60,6 +60,7 @@ module fpga ( input wire phy_rx_dv, input wire phy_rx_er, output wire phy_gtx_clk, + input wire phy_tx_clk, output wire [7:0] phy_txd, output wire phy_tx_en, output wire phy_tx_er, @@ -262,6 +263,7 @@ core_inst ( .phy_rx_dv(phy_rx_dv), .phy_rx_er(phy_rx_er), .phy_gtx_clk(phy_gtx_clk), + .phy_tx_clk(phy_tx_clk), .phy_txd(phy_txd), .phy_tx_en(phy_tx_en), .phy_tx_er(phy_tx_er), diff --git a/example/ML605/fpga/rtl/fpga_core.v b/example/ML605/fpga/rtl/fpga_core.v index 1337a3b8f..fc76a94c6 100644 --- a/example/ML605/fpga/rtl/fpga_core.v +++ b/example/ML605/fpga/rtl/fpga_core.v @@ -65,6 +65,7 @@ module fpga_core # input wire phy_rx_dv, input wire phy_rx_er, output wire phy_gtx_clk, + input wire phy_tx_clk, output wire [7:0] phy_txd, output wire phy_tx_en, output wire phy_tx_er, @@ -79,19 +80,6 @@ module fpga_core # output wire uart_cts ); -// GMII between MAC and PHY IF -wire gmii_rx_clk; -wire gmii_rx_rst; -wire [7:0] gmii_rxd; -wire gmii_rx_dv; -wire gmii_rx_er; - -wire gmii_tx_clk; -wire gmii_tx_rst; -wire [7:0] gmii_txd; -wire gmii_tx_en; -wire gmii_tx_er; - // AXI between MAC and Ethernet modules wire [7:0] rx_axis_tdata; wire rx_axis_tvalid; @@ -335,47 +323,18 @@ assign phy_reset_n = ~rst_125mhz; assign uart_rxd = 0; assign uart_cts = 0; -gmii_phy_if #( +eth_mac_1g_gmii_fifo #( .TARGET(TARGET), .IODDR_STYLE("IODDR"), - .CLOCK_INPUT_STYLE("BUFR") -) -gmii_phy_if_inst ( - .clk(clk_125mhz), - .rst(rst_125mhz), - - .mac_gmii_rx_clk(gmii_rx_clk), - .mac_gmii_rx_rst(gmii_rx_rst), - .mac_gmii_rxd(gmii_rxd), - .mac_gmii_rx_dv(gmii_rx_dv), - .mac_gmii_rx_er(gmii_rx_er), - .mac_gmii_tx_clk(gmii_tx_clk), - .mac_gmii_tx_rst(gmii_tx_rst), - .mac_gmii_txd(gmii_txd), - .mac_gmii_tx_en(gmii_tx_en), - .mac_gmii_tx_er(gmii_tx_er), - - .phy_gmii_rx_clk(phy_rx_clk), - .phy_gmii_rxd(phy_rxd), - .phy_gmii_rx_dv(phy_rx_dv), - .phy_gmii_rx_er(phy_rx_er), - .phy_gmii_tx_clk(phy_gtx_clk), - .phy_gmii_txd(phy_txd), - .phy_gmii_tx_en(phy_tx_en), - .phy_gmii_tx_er(phy_tx_er) -); - -eth_mac_1g_fifo #( + .CLOCK_INPUT_STYLE("BUFR"), .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), .RX_FIFO_ADDR_WIDTH(12) ) -eth_mac_1g_fifo_inst ( - .rx_clk(gmii_rx_clk), - .rx_rst(gmii_rx_rst), - .tx_clk(gmii_tx_clk), - .tx_rst(gmii_tx_rst), +eth_mac_inst ( + .gtx_clk(clk_125mhz), + .gtx_rst(rst_125mhz), .logic_clk(clk_125mhz), .logic_rst(rst_125mhz), @@ -391,15 +350,25 @@ eth_mac_1g_fifo_inst ( .rx_axis_tlast(rx_axis_tlast), .rx_axis_tuser(rx_axis_tuser), - .gmii_rxd(gmii_rxd), - .gmii_rx_dv(gmii_rx_dv), - .gmii_rx_er(gmii_rx_er), - .gmii_txd(gmii_txd), - .gmii_tx_en(gmii_tx_en), - .gmii_tx_er(gmii_tx_er), + .gmii_rx_clk(phy_rx_clk), + .gmii_rxd(phy_rxd), + .gmii_rx_dv(phy_rx_dv), + .gmii_rx_er(phy_rx_er), + .gmii_tx_clk(phy_gtx_clk), + .mii_tx_clk(phy_tx_clk), + .gmii_txd(phy_txd), + .gmii_tx_en(phy_tx_en), + .gmii_tx_er(phy_tx_er), + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + .speed(), .ifg_delay(12) ); diff --git a/example/ML605/fpga/tb/test_fpga_core.py b/example/ML605/fpga/tb/test_fpga_core.py index a4d621023..9e6931b6d 100755 --- a/example/ML605/fpga/tb/test_fpga_core.py +++ b/example/ML605/fpga/tb/test_fpga_core.py @@ -42,10 +42,11 @@ srcs.append("../lib/eth/rtl/oddr.v") srcs.append("../lib/eth/rtl/ssio_sdr_in.v") srcs.append("../lib/eth/rtl/ssio_sdr_out.v") srcs.append("../lib/eth/rtl/gmii_phy_if.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_gmii_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_gmii.v") srcs.append("../lib/eth/rtl/eth_mac_1g.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") @@ -98,6 +99,7 @@ def bench(): phy_rxd = Signal(intbv(0)[8:]) phy_rx_dv = Signal(bool(0)) phy_rx_er = Signal(bool(0)) + phy_tx_clk = Signal(bool(0)) uart_txd = Signal(bool(0)) uart_rts = Signal(bool(0)) @@ -117,6 +119,8 @@ def bench(): uart_cts = Signal(bool(0)) # sources and sinks + mii_select = Signal(bool(0)) + gmii_source = gmii_ep.GMIISource() gmii_source_logic = gmii_source.create_logic( @@ -125,6 +129,7 @@ def bench(): txd=phy_rxd, tx_en=phy_rx_dv, tx_er=phy_rx_er, + mii_select=mii_select, name='gmii_source' ) @@ -136,6 +141,7 @@ def bench(): rxd=phy_txd, rx_dv=phy_tx_en, rx_er=phy_tx_er, + mii_select=mii_select, name='gmii_sink' ) @@ -167,6 +173,7 @@ def bench(): phy_rx_dv=phy_rx_dv, phy_rx_er=phy_rx_er, phy_gtx_clk=phy_gtx_clk, + phy_tx_clk=phy_tx_clk, phy_txd=phy_txd, phy_tx_en=phy_tx_en, phy_tx_er=phy_tx_er, @@ -182,7 +189,15 @@ def bench(): def clkgen(): clk.next = not clk clk_125mhz.next = not clk_125mhz - phy_rx_clk.next = not phy_rx_clk + + rx_clk_hp = Signal(int(4)) + + @instance + def rx_clk_gen(): + while True: + yield delay(int(rx_clk_hp)) + phy_rx_clk.next = not phy_rx_clk + phy_tx_clk.next = not phy_tx_clk @instance def check(): @@ -305,7 +320,7 @@ def bench(): raise StopSimulation - return dut, gmii_source_logic, gmii_sink_logic, clkgen, check + return dut, gmii_source_logic, gmii_sink_logic, clkgen, rx_clk_gen, check def test_bench(): sim = Simulation(bench()) diff --git a/example/ML605/fpga/tb/test_fpga_core.v b/example/ML605/fpga/tb/test_fpga_core.v index 10a0e8341..19a803b6b 100644 --- a/example/ML605/fpga/tb/test_fpga_core.v +++ b/example/ML605/fpga/tb/test_fpga_core.v @@ -49,6 +49,7 @@ reg phy_rx_clk = 0; reg [7:0] phy_rxd = 0; reg phy_rx_dv = 0; reg phy_rx_er = 0; +reg phy_tx_clk = 0; reg uart_txd = 0; reg uart_rts = 0; @@ -83,6 +84,7 @@ initial begin phy_rxd, phy_rx_dv, phy_rx_er, + phy_tx_clk, uart_txd, uart_rts ); @@ -130,6 +132,7 @@ UUT ( .phy_rx_dv(phy_rx_dv), .phy_rx_er(phy_rx_er), .phy_gtx_clk(phy_gtx_clk), + .phy_tx_clk(phy_tx_clk), .phy_txd(phy_txd), .phy_tx_en(phy_tx_en), .phy_tx_er(phy_tx_er), From de00b3e233b777a14cc663727d709baa6069cedd Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 May 2017 20:06:32 -0700 Subject: [PATCH 336/617] Rename ML605 example design --- example/ML605/{fpga => fpga_gmii}/Makefile | 0 example/ML605/{fpga => fpga_gmii}/README.md | 0 example/ML605/{fpga => fpga_gmii}/clock.ucf | 0 example/ML605/{fpga => fpga_gmii}/common/xilinx.mk | 0 example/ML605/{fpga => fpga_gmii}/fpga.ucf | 0 example/ML605/{fpga => fpga_gmii}/fpga/Makefile | 0 example/ML605/{fpga => fpga_gmii}/lib/eth | 0 example/ML605/{fpga => fpga_gmii}/rtl/debounce_switch.v | 0 example/ML605/{fpga => fpga_gmii}/rtl/fpga.v | 0 example/ML605/{fpga => fpga_gmii}/rtl/fpga_core.v | 0 example/ML605/{fpga => fpga_gmii}/rtl/sync_reset.v | 0 example/ML605/{fpga => fpga_gmii}/rtl/sync_signal.v | 0 example/ML605/{fpga => fpga_gmii}/tb/arp_ep.py | 0 example/ML605/{fpga => fpga_gmii}/tb/axis_ep.py | 0 example/ML605/{fpga => fpga_gmii}/tb/eth_ep.py | 0 example/ML605/{fpga => fpga_gmii}/tb/gmii_ep.py | 0 example/ML605/{fpga => fpga_gmii}/tb/ip_ep.py | 0 example/ML605/{fpga => fpga_gmii}/tb/test_fpga_core.py | 0 example/ML605/{fpga => fpga_gmii}/tb/test_fpga_core.v | 0 example/ML605/{fpga => fpga_gmii}/tb/udp_ep.py | 0 20 files changed, 0 insertions(+), 0 deletions(-) rename example/ML605/{fpga => fpga_gmii}/Makefile (100%) rename example/ML605/{fpga => fpga_gmii}/README.md (100%) rename example/ML605/{fpga => fpga_gmii}/clock.ucf (100%) rename example/ML605/{fpga => fpga_gmii}/common/xilinx.mk (100%) rename example/ML605/{fpga => fpga_gmii}/fpga.ucf (100%) rename example/ML605/{fpga => fpga_gmii}/fpga/Makefile (100%) rename example/ML605/{fpga => fpga_gmii}/lib/eth (100%) rename example/ML605/{fpga => fpga_gmii}/rtl/debounce_switch.v (100%) rename example/ML605/{fpga => fpga_gmii}/rtl/fpga.v (100%) rename example/ML605/{fpga => fpga_gmii}/rtl/fpga_core.v (100%) rename example/ML605/{fpga => fpga_gmii}/rtl/sync_reset.v (100%) rename example/ML605/{fpga => fpga_gmii}/rtl/sync_signal.v (100%) rename example/ML605/{fpga => fpga_gmii}/tb/arp_ep.py (100%) rename example/ML605/{fpga => fpga_gmii}/tb/axis_ep.py (100%) rename example/ML605/{fpga => fpga_gmii}/tb/eth_ep.py (100%) rename example/ML605/{fpga => fpga_gmii}/tb/gmii_ep.py (100%) rename example/ML605/{fpga => fpga_gmii}/tb/ip_ep.py (100%) rename example/ML605/{fpga => fpga_gmii}/tb/test_fpga_core.py (100%) rename example/ML605/{fpga => fpga_gmii}/tb/test_fpga_core.v (100%) rename example/ML605/{fpga => fpga_gmii}/tb/udp_ep.py (100%) diff --git a/example/ML605/fpga/Makefile b/example/ML605/fpga_gmii/Makefile similarity index 100% rename from example/ML605/fpga/Makefile rename to example/ML605/fpga_gmii/Makefile diff --git a/example/ML605/fpga/README.md b/example/ML605/fpga_gmii/README.md similarity index 100% rename from example/ML605/fpga/README.md rename to example/ML605/fpga_gmii/README.md diff --git a/example/ML605/fpga/clock.ucf b/example/ML605/fpga_gmii/clock.ucf similarity index 100% rename from example/ML605/fpga/clock.ucf rename to example/ML605/fpga_gmii/clock.ucf diff --git a/example/ML605/fpga/common/xilinx.mk b/example/ML605/fpga_gmii/common/xilinx.mk similarity index 100% rename from example/ML605/fpga/common/xilinx.mk rename to example/ML605/fpga_gmii/common/xilinx.mk diff --git a/example/ML605/fpga/fpga.ucf b/example/ML605/fpga_gmii/fpga.ucf similarity index 100% rename from example/ML605/fpga/fpga.ucf rename to example/ML605/fpga_gmii/fpga.ucf diff --git a/example/ML605/fpga/fpga/Makefile b/example/ML605/fpga_gmii/fpga/Makefile similarity index 100% rename from example/ML605/fpga/fpga/Makefile rename to example/ML605/fpga_gmii/fpga/Makefile diff --git a/example/ML605/fpga/lib/eth b/example/ML605/fpga_gmii/lib/eth similarity index 100% rename from example/ML605/fpga/lib/eth rename to example/ML605/fpga_gmii/lib/eth diff --git a/example/ML605/fpga/rtl/debounce_switch.v b/example/ML605/fpga_gmii/rtl/debounce_switch.v similarity index 100% rename from example/ML605/fpga/rtl/debounce_switch.v rename to example/ML605/fpga_gmii/rtl/debounce_switch.v diff --git a/example/ML605/fpga/rtl/fpga.v b/example/ML605/fpga_gmii/rtl/fpga.v similarity index 100% rename from example/ML605/fpga/rtl/fpga.v rename to example/ML605/fpga_gmii/rtl/fpga.v diff --git a/example/ML605/fpga/rtl/fpga_core.v b/example/ML605/fpga_gmii/rtl/fpga_core.v similarity index 100% rename from example/ML605/fpga/rtl/fpga_core.v rename to example/ML605/fpga_gmii/rtl/fpga_core.v diff --git a/example/ML605/fpga/rtl/sync_reset.v b/example/ML605/fpga_gmii/rtl/sync_reset.v similarity index 100% rename from example/ML605/fpga/rtl/sync_reset.v rename to example/ML605/fpga_gmii/rtl/sync_reset.v diff --git a/example/ML605/fpga/rtl/sync_signal.v b/example/ML605/fpga_gmii/rtl/sync_signal.v similarity index 100% rename from example/ML605/fpga/rtl/sync_signal.v rename to example/ML605/fpga_gmii/rtl/sync_signal.v diff --git a/example/ML605/fpga/tb/arp_ep.py b/example/ML605/fpga_gmii/tb/arp_ep.py similarity index 100% rename from example/ML605/fpga/tb/arp_ep.py rename to example/ML605/fpga_gmii/tb/arp_ep.py diff --git a/example/ML605/fpga/tb/axis_ep.py b/example/ML605/fpga_gmii/tb/axis_ep.py similarity index 100% rename from example/ML605/fpga/tb/axis_ep.py rename to example/ML605/fpga_gmii/tb/axis_ep.py diff --git a/example/ML605/fpga/tb/eth_ep.py b/example/ML605/fpga_gmii/tb/eth_ep.py similarity index 100% rename from example/ML605/fpga/tb/eth_ep.py rename to example/ML605/fpga_gmii/tb/eth_ep.py diff --git a/example/ML605/fpga/tb/gmii_ep.py b/example/ML605/fpga_gmii/tb/gmii_ep.py similarity index 100% rename from example/ML605/fpga/tb/gmii_ep.py rename to example/ML605/fpga_gmii/tb/gmii_ep.py diff --git a/example/ML605/fpga/tb/ip_ep.py b/example/ML605/fpga_gmii/tb/ip_ep.py similarity index 100% rename from example/ML605/fpga/tb/ip_ep.py rename to example/ML605/fpga_gmii/tb/ip_ep.py diff --git a/example/ML605/fpga/tb/test_fpga_core.py b/example/ML605/fpga_gmii/tb/test_fpga_core.py similarity index 100% rename from example/ML605/fpga/tb/test_fpga_core.py rename to example/ML605/fpga_gmii/tb/test_fpga_core.py diff --git a/example/ML605/fpga/tb/test_fpga_core.v b/example/ML605/fpga_gmii/tb/test_fpga_core.v similarity index 100% rename from example/ML605/fpga/tb/test_fpga_core.v rename to example/ML605/fpga_gmii/tb/test_fpga_core.v diff --git a/example/ML605/fpga/tb/udp_ep.py b/example/ML605/fpga_gmii/tb/udp_ep.py similarity index 100% rename from example/ML605/fpga/tb/udp_ep.py rename to example/ML605/fpga_gmii/tb/udp_ep.py From 1b6816b06ff0e011ddccd2195f764804567d18b5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 May 2017 20:24:43 -0700 Subject: [PATCH 337/617] Add ML605 RGMII example design --- example/ML605/fpga_gmii/README.md | 3 + example/ML605/fpga_rgmii/Makefile | 25 + example/ML605/fpga_rgmii/README.md | 28 + example/ML605/fpga_rgmii/clock.ucf | 6 + example/ML605/fpga_rgmii/common/xilinx.mk | 191 ++++++ example/ML605/fpga_rgmii/fpga.ucf | 86 +++ example/ML605/fpga_rgmii/fpga/Makefile | 73 +++ example/ML605/fpga_rgmii/lib/eth | 1 + .../ML605/fpga_rgmii/rtl/debounce_switch.v | 89 +++ example/ML605/fpga_rgmii/rtl/fpga.v | 283 +++++++++ example/ML605/fpga_rgmii/rtl/fpga_core.v | 579 ++++++++++++++++++ example/ML605/fpga_rgmii/rtl/sync_reset.v | 52 ++ example/ML605/fpga_rgmii/rtl/sync_signal.v | 58 ++ example/ML605/fpga_rgmii/tb/arp_ep.py | 1 + example/ML605/fpga_rgmii/tb/axis_ep.py | 1 + example/ML605/fpga_rgmii/tb/eth_ep.py | 1 + example/ML605/fpga_rgmii/tb/gmii_ep.py | 1 + example/ML605/fpga_rgmii/tb/ip_ep.py | 1 + example/ML605/fpga_rgmii/tb/rgmii_ep.py | 1 + example/ML605/fpga_rgmii/tb/test_fpga_core.py | 331 ++++++++++ example/ML605/fpga_rgmii/tb/test_fpga_core.v | 140 +++++ example/ML605/fpga_rgmii/tb/udp_ep.py | 1 + 22 files changed, 1952 insertions(+) create mode 100644 example/ML605/fpga_rgmii/Makefile create mode 100644 example/ML605/fpga_rgmii/README.md create mode 100644 example/ML605/fpga_rgmii/clock.ucf create mode 100644 example/ML605/fpga_rgmii/common/xilinx.mk create mode 100644 example/ML605/fpga_rgmii/fpga.ucf create mode 100644 example/ML605/fpga_rgmii/fpga/Makefile create mode 120000 example/ML605/fpga_rgmii/lib/eth create mode 100644 example/ML605/fpga_rgmii/rtl/debounce_switch.v create mode 100644 example/ML605/fpga_rgmii/rtl/fpga.v create mode 100644 example/ML605/fpga_rgmii/rtl/fpga_core.v create mode 100644 example/ML605/fpga_rgmii/rtl/sync_reset.v create mode 100644 example/ML605/fpga_rgmii/rtl/sync_signal.v create mode 120000 example/ML605/fpga_rgmii/tb/arp_ep.py create mode 120000 example/ML605/fpga_rgmii/tb/axis_ep.py create mode 120000 example/ML605/fpga_rgmii/tb/eth_ep.py create mode 120000 example/ML605/fpga_rgmii/tb/gmii_ep.py create mode 120000 example/ML605/fpga_rgmii/tb/ip_ep.py create mode 120000 example/ML605/fpga_rgmii/tb/rgmii_ep.py create mode 100755 example/ML605/fpga_rgmii/tb/test_fpga_core.py create mode 100644 example/ML605/fpga_rgmii/tb/test_fpga_core.v create mode 120000 example/ML605/fpga_rgmii/tb/udp_ep.py diff --git a/example/ML605/fpga_gmii/README.md b/example/ML605/fpga_gmii/README.md index 887a41197..5b6159716 100644 --- a/example/ML605/fpga_gmii/README.md +++ b/example/ML605/fpga_gmii/README.md @@ -8,6 +8,9 @@ The design by default listens to UDP port 1234 at IP address 192.168.1.128 and will echo back any packets received. The design will also respond correctly to ARP requests. +Configure the PHY for GMII by placing J66 and J67 across pins 1 and 2 and +opening J68. + FPGA: XC6SlX45-2CSG324 PHY: Marvell M88E1111 diff --git a/example/ML605/fpga_rgmii/Makefile b/example/ML605/fpga_rgmii/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/ML605/fpga_rgmii/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/ML605/fpga_rgmii/README.md b/example/ML605/fpga_rgmii/README.md new file mode 100644 index 000000000..43005aad5 --- /dev/null +++ b/example/ML605/fpga_rgmii/README.md @@ -0,0 +1,28 @@ +# Verilog Ethernet ML605 Example Design + +## Introduction + +This example design targets the Xilinx ML605 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +Configure the PHY for RGMII by placing J66 across pins 1 and 2, opening J67, +and shorting J68. + +FPGA: XC6SlX45-2CSG324 +PHY: Marvell M88E1111 + +## How to build + +Run make to build. Ensure that the Xilinx ISE toolchain components are +in PATH. + +## How to test + +Run make program to program the ML605 board with the Xilinx Impact software. +Then run netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. +Any text entered into netcat will be echoed back after pressing enter. + + diff --git a/example/ML605/fpga_rgmii/clock.ucf b/example/ML605/fpga_rgmii/clock.ucf new file mode 100644 index 000000000..e048a42f1 --- /dev/null +++ b/example/ML605/fpga_rgmii/clock.ucf @@ -0,0 +1,6 @@ +# UCF file for clock module domain crossing constraints + +NET "clk_125mhz_int" TNM = "ffs_clk_125mhz_int"; +NET "core_inst/eth_mac_inst/rx_clk" TNM = "ffs_gmii_rx_clk"; +TIMESPEC "TS_clk_125mhz_int_to_gmii_rx_clk" = FROM "ffs_clk_125mhz_int" TO "ffs_gmii_rx_clk" 10 ns; +TIMESPEC "TS_gmii_rx_clk_to_clk_125mhz_int" = FROM "ffs_gmii_rx_clk" TO "ffs_clk_125mhz_int" 10 ns; diff --git a/example/ML605/fpga_rgmii/common/xilinx.mk b/example/ML605/fpga_rgmii/common/xilinx.mk new file mode 100644 index 000000000..f10a45f8e --- /dev/null +++ b/example/ML605/fpga_rgmii/common/xilinx.mk @@ -0,0 +1,191 @@ +############################################################################# +# Author: Lane Brooks/Keith Fife +# Date: 04/28/2006 +# License: GPL +# Desc: This is a Makefile intended to take a verilog rtl design +# through the Xilinx ISE tools to generate configuration files for +# Xilinx FPGAs. This file is generic and just a template. As such +# all design specific options such as synthesis files, fpga part type, +# prom part type, etc should be set in the top Makefile prior to +# including this file. Alternatively, all parameters can be passed +# in from the command line as well. +# +############################################################################## +# +# Parameter: +# SYN_FILES - Space seperated list of files to be synthesized +# PART - FPGA part (see Xilinx documentation) +# PROM - PROM part +# NGC_PATHS - Space seperated list of any dirs with pre-compiled ngc files. +# UCF_FILES - Space seperated list of user constraint files. Defaults to xilinx/$(FPGA_TOP).ucf +# +# +# Example Calling Makefile: +# +# SYN_FILES = fpga.v fifo.v clks.v +# PART = xc3s1000 +# FPGA_TOP = fpga +# PROM = xc18v04 +# NGC_PATH = ipLib1 ipLib2 +# FPGA_ARCH = spartan6 +# SPI_PROM_SIZE = (in bytes) +# include xilinx.mk +############################################################################# +# +# Command Line Example: +# make -f xilinx.mk PART=xc3s1000-4fg320 SYN_FILES="fpga.v test.v" FPGA_TOP=fpga +# +############################################################################## +# +# Required Setup: +# +# %.ucf - user constraint file. Needed by ngdbuild +# +# Optional Files: +# %.xcf - user constraint file. Needed by xst. +# %.ut - File for pin states needed by bitgen + + +.PHONY: clean bit prom fpga spi + + +# Mark the intermediate files as PRECIOUS to prevent make from +# deleting them (see make manual section 10.4). +.PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.bit %_timesim.v + +# include the local Makefile for project for any project specific targets +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +INC_PATHS_REL = $(patsubst %, ../%, $(INC_PATHS)) +NGC_PATHS_REL = $(patsubst %, ../%, $(NGC_PATHS)) + +ifdef UCF_FILES + UCF_FILES_REL = $(patsubst %, ../%, $(UCF_FILES)) +else + UCF_FILES_REL = $(FPGA_TOP).ucf +endif + + + +fpga: $(FPGA_TOP).bit + +mcs: $(FPGA_TOP).mcs + +prom: $(FPGA_TOP).spi + +spi: $(FPGA_TOP).spi + +fpgasim: $(FPGA_TOP)_sim.v + + +########################### XST TEMPLATES ############################ +# There are 2 files that XST uses for synthesis that we auto generate. +# The first is a project file which is just a list of all the verilog +# files. The second is the src file which passes XST all the options. +# See XST user manual for XST options. +%.ngc: $(SYN_FILES_REL) $(INC_FILES_REL) + rm -rf xst $*.prj $*.xst defines.v + touch defines.v + mkdir -p xst/tmp + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo verilog work defines.v > $*.prj + for x in $(SYN_FILES_REL); do echo verilog work $$x >> $*.prj; done + @echo "set -tmpdir ./xst/tmp" >> $*.xst + @echo "set -xsthdpdir ./xst" >> $*.xst + @echo "run" >> $*.xst + @echo "-ifn $*.prj" >> $*.xst + @echo "-ifmt mixed" >> $*.xst + @echo "-top $*" >> $*.xst + @echo "-ofn $*" >> $*.xst + @echo "-ofmt NGC" >> $*.xst + @echo "-opt_mode Speed" >> $*.xst + @echo "-opt_level 1" >> $*.xst + # @echo "-verilog2001 YES" >> $*.xst + @echo "-keep_hierarchy NO" >> $*.xst + @echo "-p $(FPGA_PART)" >> $*.xst + xst -ifn $*.xst -ofn $*.log + + +########################### ISE TRANSLATE ############################ +# ngdbuild will automatically use a ucf called %.ucf if one is found. +# We setup the dependancy such that %.ucf file is required. If any +# pre-compiled ncd files are needed, set the NGC_PATH variable as a space +# seperated list of directories that include the pre-compiled ngc files. +%.ngd: %.ngc $(UCF_FILES_REL) + ngdbuild -dd ngdbuild $(patsubst %,-sd %, $(NGC_PATHS_REL)) $(patsubst %,-uc %, $(UCF_FILES_REL)) -p $(FPGA_PART) $< $@ + + +########################### ISE MAP ################################### +ifeq ($(FPGA_ARCH),spartan6) + MAP_OPTS= -register_duplication on -timing -xe n +else + MAP_OPTS= -cm speed -register_duplication on -timing -xe n -pr b +endif + +%_map.ncd: %.ngd + map -p $(FPGA_PART) $(MAP_OPTS) -w -o $@ $< $*.pcf + +# map -p $(FPGA_PART) -cm area -pr b -k 4 -c 100 -o $@ $< $*.pcf + + +########################### ISE PnR ################################### +%.ncd: %_map.ncd + par -w -ol high $< $@ $*.pcf + +# par -w -ol std -t 1 $< $@ $*.pcf + + +##################### ISE Static Timing Analysis ##################### +%.twr: %.ncd + -trce -e 3 -l 3 -u -xml $* $< -o $@ $*.pcf + +%_sim.v: %.ncd + netgen -s 4 -pcf $*.pcf -sdf_anno true -ism -sdf_path netgen -w -dir . -ofmt verilog -sim $< $@ + +# netgen -ise "/home/lane/Second/xilinx/Second/Second" -intstyle ise -s 4 -pcf Second.pcf -sdf_anno true -sdf_path netgen/par -w -dir netgen/par -ofmt verilog -sim Second.ncd Second_timesim.v + + +########################### ISE Bitgen ############################# +%.bit: %.twr + bitgen $(BITGEN_OPTIONS) -w $*.ncd $*.bit + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +########################### ISE Promgen ############################# +%.mcs: %.bit + promgen -spi -w -p mcs -s $(SPI_PROM_SIZE) -o $@ -u 0 $< + # promgen -w -p mcs -c FF -o $@ -u 0 $< -x $(PROM) + mkdir -p rev + EXT=mcs; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +%.spi: %.mcs + objcopy -I ihex -O binary $< $@ + EXT=spi; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + + +tmpclean: + -rm -rf xst ngdbuild *_map.* *.ncd *.ngc *.log *.xst *.prj *.lso *~ *.pcf *.bld *.ngd *.xpi *_pad.* *.unroutes *.twx *.par *.twr *.pad *.drc *.bgn *.prm *.sig netgen *.v *.nlf *.xml + +clean: tmpclean + -rm -rf *.bit *.mcs + +# clean everything +distclean: clean + -rm -rf rev + diff --git a/example/ML605/fpga_rgmii/fpga.ucf b/example/ML605/fpga_rgmii/fpga.ucf new file mode 100644 index 000000000..8f4ad1176 --- /dev/null +++ b/example/ML605/fpga_rgmii/fpga.ucf @@ -0,0 +1,86 @@ +# User Constraints File for the Xilinx ML605 board, rev C + +CONFIG PART = xc6vlx130t-1ff1156; + +# 200MHz clock +NET "sys_clk_p" LOC = "J9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0P_GC_34 (GCLK) +NET "sys_clk_n" LOC = "H9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0N_GC_34 (GCLK) +NET "sys_clk_p" TNM_NET = "sys_clk_pin"; +TIMESPEC "TS_sys_clk_pin" = PERIOD "sys_clk_pin" 200000 kHz; + +# Light Emitting Diodes +NET "ledu" LOC = "AH27" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L0P_23 (DS20) +NET "ledl" LOC = "AD21" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 22, IO_L0N_22 (DS17) +NET "ledd" LOC = "AH28" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L0N_23 (DS18) +NET "ledr" LOC = "AE21" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 22, IO_L0P_22 (DS19) +NET "ledc" LOC = "AP24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L19N_23 (DS16) + +NET "led<0>" LOC = "AC22" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L19P_24 (DS12) +NET "led<1>" LOC = "AC24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L18N_24 (DS11) +NET "led<2>" LOC = "AE22" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L17N_VRP_24 (DS9) +NET "led<3>" LOC = "AE23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L17P_VRN_24 (DS10) +NET "led<4>" LOC = "AB23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L16N_CSO_B_24 (DS15) +NET "led<5>" LOC = "AG23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L15N_RS1_24 (DS14) +NET "led<6>" LOC = "AE24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L11N_SRCC_24 (DS22) +NET "led<7>" LOC = "AD24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L11P_SRCC_24 (DS21) + +# Reset Button: I/O Bank 2 +NET "reset" LOC = "H10" | IOSTANDARD=LVCMOS15; # Bank = 35, IO_L6P_SM3P_35 (SW10) + +# Push Buttons: I/O Bank 3 +NET "btnu" LOC = "A19" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L15N_26 (SW5) +NET "btnl" LOC = "H17" | IOSTANDARD=LVCMOS15; # Bank = 36, IO_L3P_36 (SW8) +NET "btnd" LOC = "A18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L15P_26 (SW6) +NET "btnr" LOC = "G17" | IOSTANDARD=LVCMOS15; # Bank = 36, IO_L3N_36 (SW7) +NET "btnc" LOC = "G26" | IOSTANDARD=LVCMOS15; # Bank = 25, IO_L6P_25 (SW9) + +# Toggle Switches +NET "sw<0>" LOC = "D22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L19N_26 (SW1.1) +NET "sw<1>" LOC = "C22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L19P_26 (SW1.2) +NET "sw<2>" LOC = "L21" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L18N_26 (SW1.3) +NET "sw<3>" LOC = "L20" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L18P_26 (SW1.4) +NET "sw<4>" LOC = "C18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L17N_26 (SW1.5) +NET "sw<5>" LOC = "B18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L17P_26 (SW1.6) +NET "sw<6>" LOC = "K22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L16N_26 (SW1.7) +NET "sw<7>" LOC = "K21" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L16P_26 (SW1.8) + +# Marvell M88E1111 Tri-Mode Ethernet PHY (1000BASE-T) +# Interrupt, Reset, MDIO +#NET "phy_int_n" LOC = "AH14" | IOSTANDARD=LVCMOS25; # (E-INT) +NET "phy_reset_n" LOC = "AH13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L18P_33 (E-RESET) +#NET "phy_mdc" LOC = "AP14" | IOSTANDARD=LVCMOS25; # (E-MDC) +#NET "phy_mdio" LOC = "AN14" | IOSTANDARD=LVCMOS25; # (E-MDIO) +# RGMII Transmit +NET "phy_tx_clk" LOC = "AH12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L16N_33 (E-GTXCLK) +#NET "phy_tx_clk" LOC = "AD12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L10P_MRCC_33 (E-TXCLK) +NET "phy_txd<0>" LOC = "AM11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L7N_33 (E-TXD0) +NET "phy_txd<1>" LOC = "AL11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L7P_33 (E-TXD1) +NET "phy_txd<2>" LOC = "AG10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L6N_33 (E-TXD2) +NET "phy_txd<3>" LOC = "AG11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L6P_33 (E-TXD3) +#NET "phy_txd<4>" LOC = "AL10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L5N_33 (E-TXD4) +#NET "phy_txd<5>" LOC = "AM10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L5P_33 (E-TXD5) +#NET "phy_txd<6>" LOC = "AE11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L4N_VREF_33 (E-TXD6) +#NET "phy_txd<7>" LOC = "AF11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L4P_33 (E-TXD7) +NET "phy_tx_ctl" LOC = "AJ10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L8P_SRCC_33 (E-TXEN) +#NET "phy_tx_er" LOC = "AH10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L8N_SRCC_33 (E-TXER) +# RGMII Receive +NET "phy_rx_clk" LOC = "AP11" | IOSTANDARD=LVCMOS25 | TNM_NET = "clk_rx_local"; # (E-RXCLK) +NET "phy_rxd<0>" LOC = "AN13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L15P_33 (E-RXD0) +NET "phy_rxd<1>" LOC = "AF14" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L14N_VREF_33 (E-RXD1) +NET "phy_rxd<2>" LOC = "AE14" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L14P_33 (E-RXD2) +NET "phy_rxd<3>" LOC = "AN12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L13N_33 (E-RXD3) +#NET "phy_rxd<4>" LOC = "AM12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L13P_33 (E-RXD4) +#NET "phy_rxd<5>" LOC = "AD11" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L10N_MRCC_33 (E-RXD5) +#NET "phy_rxd<6>" LOC = "AC12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L9N_MRCC_33 (E-RXD6) +#NET "phy_rxd<7>" LOC = "AC13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L9P_MRCC_33 (E-RXD7) +NET "phy_rx_ctl" LOC = "AM13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L15N_33 (E-RXDV) +#NET "phy_rx_er" LOC = "AG12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L16P_33 (E-RXER) + +# Timing constraints for Ethernet PHY +TIMESPEC "TS_rx_clk_root" = PERIOD "clk_rx_local" 8000 ps HIGH 50 %; + +# Silicon Labs CP2103 +NET "uart_rxd" LOC = "J25" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L9P_MRCC_24 (U24.24) +NET "uart_txd" LOC = "J24" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L9N_MRCC_24 (U24.25) +NET "uart_rts" LOC = "T23" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L8N_SRCC_24 (U24.23) +NET "uart_cts" LOC = "T24" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L8P_SRCC_24 (U24.22) diff --git a/example/ML605/fpga_rgmii/fpga/Makefile b/example/ML605/fpga_rgmii/fpga/Makefile new file mode 100644 index 000000000..a601f5990 --- /dev/null +++ b/example/ML605/fpga_rgmii/fpga/Makefile @@ -0,0 +1,73 @@ + +# FPGA settings +FPGA_PART = xc6vlx130t-1ff1156 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/iddr.v +SYN_FILES += lib/eth/rtl/oddr.v +SYN_FILES += lib/eth/rtl/ssio_ddr_in.v +SYN_FILES += lib/eth/rtl/ssio_ddr_out.v +SYN_FILES += lib/eth/rtl/rgmii_phy_if.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rgmii_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rgmii.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v +SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v +SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +#SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v + +# UCF files +UCF_FILES = fpga.ucf +UCF_FILES += clock.ucf + +# NGC paths for ngdbuild +#NGC_PATHS = coregen/dcm_i100_o125 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 2 -file $(FPGA_TOP).bit" >> program.cmd + echo "program -p 2" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + diff --git a/example/ML605/fpga_rgmii/lib/eth b/example/ML605/fpga_rgmii/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/ML605/fpga_rgmii/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/ML605/fpga_rgmii/rtl/debounce_switch.v b/example/ML605/fpga_rgmii/rtl/debounce_switch.v new file mode 100644 index 000000000..ab84126ec --- /dev/null +++ b/example/ML605/fpga_rgmii/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/ML605/fpga_rgmii/rtl/fpga.v b/example/ML605/fpga_rgmii/rtl/fpga.v new file mode 100644 index 000000000..325031ca4 --- /dev/null +++ b/example/ML605/fpga_rgmii/rtl/fpga.v @@ -0,0 +1,283 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 200MHz + * Reset: Push button, active high + */ + input wire sys_clk_p, + input wire sys_clk_n, + input wire reset, + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire ledu, + output wire ledl, + output wire ledd, + output wire ledr, + output wire ledc, + output wire [7:0] led, + /* + * Ethernet: 1000BASE-T RGMII + */ + input wire phy_rx_clk, + input wire [3:0] phy_rxd, + input wire phy_rx_ctl, + output wire phy_tx_clk, + output wire [3:0] phy_txd, + output wire phy_tx_ctl, + output wire phy_reset_n, + /* + * Silicon Labs CP2103 USB UART + */ + output wire uart_rxd, + input wire uart_txd, + input wire uart_rts, + output wire uart_cts +); + +// Clock and reset + +wire sys_clk_ibufg; +wire sys_clk_bufg; +wire clk_125mhz_mmcm_out; +wire clk90_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire clk90_125mhz_int; +wire rst_125mhz_int; + +wire mmcm_rst = reset; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS +clk_ibufgds_inst( + .I(sys_clk_p), + .IB(sys_clk_n), + .O(sys_clk_ibufg) +); + +// MMCM instance +// 200 MHz in, 125 MHz out +// PFD range: 10 MHz to 450 MHz +// VCO range: 600 MHz to 1200 MHz +// M = 5, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCM_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(8), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(90), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(5), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.100), + .CLKIN1_PERIOD(5.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(sys_clk_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(clk90_125mhz_mmcm_out), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +BUFG +clk90_125mhz_bufg_inst ( + .I(clk90_125mhz_mmcm_out), + .O(clk90_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [7:0] sw_int; + +wire ledu_int; +wire ledl_int; +wire ledd_int; +wire ledr_int; +wire ledc_int; +wire [7:0] led_int; + +wire uart_rxd_int; +wire uart_txd_int; +wire uart_rts_int; +wire uart_cts_int; + +debounce_switch #( + .WIDTH(13), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(clk_125mhz_int), + .in({uart_txd, + uart_rts}), + .out({uart_txd_int, + uart_rts_int}) +); + +assign ledu = ledu_int; +assign ledl = ledl_int; +assign ledd = ledd_int; +assign ledr = ledr_int; +assign ledc = ledc_int; +assign led = led_int; + +assign uart_rxd = uart_rxd_int; +assign uart_cts = uart_cts_int; + +fpga_core +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk_125mhz(clk_125mhz_int), + .clk90_125mhz(clk90_125mhz_int), + .rst_125mhz(rst_125mhz_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .ledu(ledu_int), + .ledl(ledl_int), + .ledd(ledd_int), + .ledr(ledr_int), + .ledc(ledc_int), + .led(led_int), + /* + * Ethernet: 1000BASE-T RGMII + */ + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_ctl(phy_rx_ctl), + .phy_tx_clk(phy_tx_clk), + .phy_txd(phy_txd), + .phy_tx_ctl(phy_tx_ctl), + .phy_reset_n(phy_reset_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd_int), + .uart_rts(uart_rts_int), + .uart_cts(uart_cts_int) +); + +endmodule diff --git a/example/ML605/fpga_rgmii/rtl/fpga_core.v b/example/ML605/fpga_rgmii/rtl/fpga_core.v new file mode 100644 index 000000000..392e5d52f --- /dev/null +++ b/example/ML605/fpga_rgmii/rtl/fpga_core.v @@ -0,0 +1,579 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 125MHz + * Synchronous reset + */ + input wire clk_125mhz, + input wire clk90_125mhz, + input wire rst_125mhz, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire ledu, + output wire ledl, + output wire ledd, + output wire ledr, + output wire ledc, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T RGMII + */ + input wire phy_rx_clk, + input wire [3:0] phy_rxd, + input wire phy_rx_ctl, + output wire phy_tx_clk, + output wire [3:0] phy_txd, + output wire phy_tx_ctl, + output wire phy_reset_n, + + /* + * Silicon Labs CP2103 USB UART + */ + output wire uart_rxd, + input wire uart_txd, + input wire uart_rts, + output wire uart_cts +); + +// AXI between MAC and Ethernet modules +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [7:0] tx_axis_tdata; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [7:0] rx_eth_payload_tdata; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [7:0] tx_eth_payload_tdata; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [7:0] rx_ip_payload_tdata; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [7:0] tx_ip_payload_tdata; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [7:0] rx_udp_payload_tdata; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_tdata; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [7:0] rx_fifo_udp_payload_tdata; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [7:0] tx_fifo_udp_payload_tdata; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk_125mhz) begin + if (rst_125mhz) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk_125mhz) begin + if (rst_125mhz) begin + led_reg <= 0; + end else begin + if (tx_udp_payload_tvalid) begin + if (~valid_last) begin + led_reg <= tx_udp_payload_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_tlast) begin + valid_last <= 1'b0; + end + end + end +end + +//assign led = sw; +assign ledu = 0; +assign ledl = 0; +assign ledd = 0; +assign ledr = 0; +assign ledc = 0; +assign led = led_reg; +assign phy_reset_n = ~rst_125mhz; + +assign uart_rxd = 0; +assign uart_cts = 0; + +eth_mac_1g_rgmii_fifo #( + .TARGET(TARGET), + .IODDR_STYLE("IODDR"), + .CLOCK_INPUT_STYLE("BUFR"), + .USE_CLK90("TRUE"), + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .RX_FIFO_ADDR_WIDTH(12) +) +eth_mac_inst ( + .gtx_clk(clk_125mhz), + .gtx_clk90(clk90_125mhz), + .gtx_rst(rst_125mhz), + .logic_clk(clk_125mhz), + .logic_rst(rst_125mhz), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .rgmii_rx_clk(phy_rx_clk), + .rgmii_rxd(phy_rxd), + .rgmii_rx_ctl(phy_rx_ctl), + .rgmii_tx_clk(phy_tx_clk), + .rgmii_txd(phy_txd), + .rgmii_tx_ctl(phy_tx_ctl), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + .speed(), + + .ifg_delay(12) +); + +eth_axis_rx +eth_axis_rx_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx +eth_axis_tx_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete +udp_complete_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(0) +); + +axis_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8) +) +udp_payload_fifo ( + .clk(clk_125mhz), + .rst(rst_125mhz), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/ML605/fpga_rgmii/rtl/sync_reset.v b/example/ML605/fpga_rgmii/rtl/sync_reset.v new file mode 100644 index 000000000..558a67605 --- /dev/null +++ b/example/ML605/fpga_rgmii/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/ML605/fpga_rgmii/rtl/sync_signal.v b/example/ML605/fpga_rgmii/rtl/sync_signal.v new file mode 100644 index 000000000..1b8a32328 --- /dev/null +++ b/example/ML605/fpga_rgmii/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/ML605/fpga_rgmii/tb/arp_ep.py b/example/ML605/fpga_rgmii/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/ML605/fpga_rgmii/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_rgmii/tb/axis_ep.py b/example/ML605/fpga_rgmii/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/ML605/fpga_rgmii/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_rgmii/tb/eth_ep.py b/example/ML605/fpga_rgmii/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/ML605/fpga_rgmii/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_rgmii/tb/gmii_ep.py b/example/ML605/fpga_rgmii/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/ML605/fpga_rgmii/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_rgmii/tb/ip_ep.py b/example/ML605/fpga_rgmii/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/ML605/fpga_rgmii/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_rgmii/tb/rgmii_ep.py b/example/ML605/fpga_rgmii/tb/rgmii_ep.py new file mode 120000 index 000000000..986c56280 --- /dev/null +++ b/example/ML605/fpga_rgmii/tb/rgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/rgmii_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_rgmii/tb/test_fpga_core.py b/example/ML605/fpga_rgmii/tb/test_fpga_core.py new file mode 100755 index 000000000..6df143517 --- /dev/null +++ b/example/ML605/fpga_rgmii/tb/test_fpga_core.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import eth_ep +import arp_ep +import udp_ep +import rgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/iddr.v") +srcs.append("../lib/eth/rtl/oddr.v") +srcs.append("../lib/eth/rtl/ssio_ddr_in.v") +srcs.append("../lib/eth/rtl/ssio_ddr_out.v") +srcs.append("../lib/eth/rtl/rgmii_phy_if.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_rgmii_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_rgmii.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen.v") +srcs.append("../lib/eth/rtl/udp.v") +srcs.append("../lib/eth/rtl/udp_ip_rx.v") +srcs.append("../lib/eth/rtl/udp_ip_tx.v") +srcs.append("../lib/eth/rtl/ip_complete.v") +srcs.append("../lib/eth/rtl/ip.v") +srcs.append("../lib/eth/rtl/ip_eth_rx.v") +srcs.append("../lib/eth/rtl/ip_eth_tx.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") +srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") +srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + TARGET = "SIM" + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + clk_125mhz = Signal(bool(0)) + clk90_125mhz = Signal(bool(0)) + rst_125mhz = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[8:]) + phy_rx_clk = Signal(bool(0)) + phy_rxd = Signal(intbv(0)[4:]) + phy_rx_ctl = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + + # Outputs + ledu = Signal(bool(0)) + ledl = Signal(bool(0)) + ledd = Signal(bool(0)) + ledr = Signal(bool(0)) + ledc = Signal(bool(0)) + led = Signal(intbv(0)[8:]) + phy_tx_clk = Signal(bool(0)) + phy_txd = Signal(intbv(0)[4:]) + phy_tx_ctl = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_rxd = Signal(bool(0)) + uart_cts = Signal(bool(0)) + + # sources and sinks + mii_select = Signal(bool(0)) + + rgmii_source = rgmii_ep.RGMIISource() + + rgmii_source_logic = rgmii_source.create_logic( + phy_rx_clk, + rst, + txd=phy_rxd, + tx_ctl=phy_rx_ctl, + mii_select=mii_select, + name='rgmii_source' + ) + + rgmii_sink = rgmii_ep.RGMIISink() + + rgmii_sink_logic = rgmii_sink.create_logic( + phy_tx_clk, + rst, + rxd=phy_txd, + rx_ctl=phy_tx_ctl, + mii_select=mii_select, + name='rgmii_sink' + ) + + # DUT + if os.system(build_cmd): + raise Exception("Error running build command") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk_125mhz=clk_125mhz, + clk90_125mhz=clk90_125mhz, + rst_125mhz=rst_125mhz, + current_test=current_test, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + ledu=ledu, + ledl=ledl, + ledd=ledd, + ledr=ledr, + ledc=ledc, + led=led, + + phy_rx_clk=phy_rx_clk, + phy_rxd=phy_rxd, + phy_rx_ctl=phy_rx_ctl, + phy_tx_clk=phy_tx_clk, + phy_txd=phy_txd, + phy_tx_ctl=phy_tx_ctl, + phy_reset_n=phy_reset_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + clk_125mhz.next = not clk_125mhz + + @instance + def clkgen2(): + yield delay(4+2) + while True: + clk90_125mhz.next = not clk90_125mhz + yield delay(4) + + rx_clk_hp = Signal(int(4)) + + @instance + def rx_clk_gen(): + while True: + yield delay(int(rx_clk_hp)) + phy_rx_clk.next = not phy_rx_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + rst_125mhz.next = 1 + yield clk.posedge + rst.next = 0 + rst_125mhz.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + rgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while rgmii_sink.empty(): + yield clk.posedge + + rx_frame = rgmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + rgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while rgmii_sink.empty(): + yield clk.posedge + + rx_frame = rgmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert rgmii_source.empty() + assert rgmii_sink.empty() + + yield delay(100) + + raise StopSimulation + + return dut, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, rx_clk_gen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/ML605/fpga_rgmii/tb/test_fpga_core.v b/example/ML605/fpga_rgmii/tb/test_fpga_core.v new file mode 100644 index 000000000..61e64c700 --- /dev/null +++ b/example/ML605/fpga_rgmii/tb/test_fpga_core.v @@ -0,0 +1,140 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters +parameter TARGET = "SIM"; + +// Inputs +reg clk_125mhz = 0; +reg clk90_125mhz = 0; +reg rst_125mhz = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [7:0] sw = 0; +reg phy_rx_clk = 0; +reg [3:0] phy_rxd = 0; +reg phy_rx_ctl = 0; +reg uart_txd = 0; +reg uart_rts = 0; + +// Outputs +wire ledu; +wire ledl; +wire ledd; +wire ledr; +wire ledc; +wire [7:0] led; +wire phy_tx_clk; +wire [3:0] phy_txd; +wire phy_tx_ctl; +wire phy_reset_n; +wire uart_rxd; +wire uart_cts; + +initial begin + // myhdl integration + $from_myhdl( + clk_125mhz, + clk90_125mhz, + rst_125mhz, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_rx_clk, + phy_rxd, + phy_rx_ctl, + uart_txd, + uart_rts + ); + $to_myhdl( + ledu, + ledl, + ledd, + ledr, + ledc, + led, + phy_tx_clk, + phy_txd, + phy_tx_ctl, + phy_reset_n, + uart_rxd, + uart_cts + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core #( + .TARGET(TARGET) +) +UUT ( + .clk_125mhz(clk_125mhz), + .clk90_125mhz(clk90_125mhz), + .rst_125mhz(rst_125mhz), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .ledu(ledu), + .ledl(ledl), + .ledd(ledd), + .ledr(ledr), + .ledc(ledc), + .led(led), + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_ctl(phy_rx_ctl), + .phy_tx_clk(phy_tx_clk), + .phy_txd(phy_txd), + .phy_tx_ctl(phy_tx_ctl), + .phy_reset_n(phy_reset_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts) +); + +endmodule diff --git a/example/ML605/fpga_rgmii/tb/udp_ep.py b/example/ML605/fpga_rgmii/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/ML605/fpga_rgmii/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file From 69253d2d83c1641aa5f8df30789026060d801a70 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 1 Jun 2017 06:48:50 -0700 Subject: [PATCH 338/617] Update VCU108 example design --- example/VCU108/fpga_10g/fpga/Makefile | 4 +-- example/VCU108/fpga_10g/rtl/fpga.v | 26 ++++++++++++++---- example/VCU108/fpga_10g/rtl/fpga_core.v | 18 ++++++++++--- example/VCU108/fpga_10g/tb/test_fpga_core.py | 22 ++++++++++++--- example/VCU108/fpga_10g/tb/test_fpga_core.v | 3 +++ example/VCU108/fpga_1g/fpga/Makefile | 4 +-- example/VCU108/fpga_1g/rtl/fpga.v | 28 +++++++++++++++----- example/VCU108/fpga_1g/rtl/fpga_core.v | 14 +++++++++- example/VCU108/fpga_1g/tb/test_fpga_core.py | 22 ++++++++++++--- example/VCU108/fpga_1g/tb/test_fpga_core.v | 3 +++ 10 files changed, 119 insertions(+), 25 deletions(-) diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 11c1ed737..cfb2bb486 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -14,8 +14,8 @@ SYN_FILES += rtl/i2c_master.v SYN_FILES += rtl/si570_i2c_init.v SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v diff --git a/example/VCU108/fpga_10g/rtl/fpga.v b/example/VCU108/fpga_10g/rtl/fpga.v index 8537dd5e0..c8e71796b 100644 --- a/example/VCU108/fpga_10g/rtl/fpga.v +++ b/example/VCU108/fpga_10g/rtl/fpga.v @@ -481,6 +481,7 @@ ten_gig_eth_pcs_pma_inst ( // SGMII interface to PHY wire phy_gmii_clk_int; wire phy_gmii_rst_int; +wire phy_gmii_clk_en_int; wire [7:0] phy_gmii_txd_int; wire phy_gmii_tx_en_int; wire phy_gmii_tx_er_int; @@ -488,7 +489,21 @@ wire [7:0] phy_gmii_rxd_int; wire phy_gmii_rx_dv_int; wire phy_gmii_rx_er_int; -wire [15:0] gig_eth_status_vector; +wire [15:0] gig_eth_pcspma_status_vector; + +wire gig_eth_pcspma_status_link_status = gig_eth_pcspma_status_vector[0]; +wire gig_eth_pcspma_status_link_synchronization = gig_eth_pcspma_status_vector[1]; +wire gig_eth_pcspma_status_rudi_c = gig_eth_pcspma_status_vector[2]; +wire gig_eth_pcspma_status_rudi_i = gig_eth_pcspma_status_vector[3]; +wire gig_eth_pcspma_status_rudi_invalid = gig_eth_pcspma_status_vector[4]; +wire gig_eth_pcspma_status_rxdisperr = gig_eth_pcspma_status_vector[5]; +wire gig_eth_pcspma_status_rxnotintable = gig_eth_pcspma_status_vector[6]; +wire gig_eth_pcspma_status_phy_link_status = gig_eth_pcspma_status_vector[7]; +wire [1:0] gig_eth_pcspma_status_remote_fault_encdg = gig_eth_pcspma_status_vector[9:8]; +wire [1:0] gig_eth_pcspma_status_speed = gig_eth_pcspma_status_vector[11:10]; +wire gig_eth_pcspma_status_duplex = gig_eth_pcspma_status_vector[12]; +wire gig_eth_pcspma_status_remote_fault = gig_eth_pcspma_status_vector[13]; +wire [1:0] gig_eth_pcspma_status_pause = gig_eth_pcspma_status_vector[15:14]; wire [4:0] gig_eth_pcspma_config_vector; @@ -537,11 +552,11 @@ gig_eth_pcspma ( // MAC clocking .sgmii_clk_r (), .sgmii_clk_f (), - .sgmii_clk_en (), // need to pass through to MAC + .sgmii_clk_en (phy_gmii_clk_en_int), // Speed control - .speed_is_10_100 (1'b0), - .speed_is_100 (1'b0), + .speed_is_10_100 (gig_eth_pcspma_status_speed != 2'b10), + .speed_is_100 (gig_eth_pcspma_status_speed == 2'b01), // Internal GMII .gmii_txd (phy_gmii_txd_int), @@ -560,7 +575,7 @@ gig_eth_pcspma ( .an_restart_config (1'b0), // Status - .status_vector (gig_eth_status_vector), + .status_vector (gig_eth_pcspma_status_vector), .signal_detect (1'b1) ); @@ -610,6 +625,7 @@ core_inst ( */ .phy_gmii_clk(phy_gmii_clk_int), .phy_gmii_rst(phy_gmii_rst_int), + .phy_gmii_clk_en(phy_gmii_clk_en_int), .phy_gmii_rxd(phy_gmii_rxd_int), .phy_gmii_rx_dv(phy_gmii_rx_dv_int), .phy_gmii_rx_er(phy_gmii_rx_er_int), diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index ddbcb2029..91bdb3570 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -77,6 +77,7 @@ module fpga_core # */ input wire phy_gmii_clk, input wire phy_gmii_rst, + input wire phy_gmii_clk_en, input wire [7:0] phy_gmii_rxd, input wire phy_gmii_rx_dv, input wire phy_gmii_rx_er, @@ -433,7 +434,7 @@ eth_mac_1g_fifo #( .TX_FIFO_ADDR_WIDTH(12), .RX_FIFO_ADDR_WIDTH(12) ) -eth_mac_1g_fifo_inst ( +eth_mac_1g_inst ( .rx_clk(phy_gmii_clk), .rx_rst(phy_gmii_rst), .tx_clk(phy_gmii_clk), @@ -460,8 +461,19 @@ eth_mac_1g_fifo_inst ( .gmii_tx_en(phy_gmii_tx_en), .gmii_tx_er(phy_gmii_tx_er), - .rx_error_bad_frame(), - .rx_error_bad_fcs(), + .rx_clk_enable(phy_gmii_clk_en), + .tx_clk_enable(phy_gmii_clk_en), + .rx_mii_select(1'b0), + .tx_mii_select(1'b0), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), .ifg_delay(12) ); diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index 5641d0935..6436e9da1 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -40,8 +40,8 @@ srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_1g.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_10g.v") srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") @@ -108,6 +108,7 @@ def bench(): qsfp_rxc_4 = Signal(intbv(0)[8:]) phy_gmii_clk = Signal(bool(0)) phy_gmii_rst = Signal(bool(0)) + phy_gmii_clk_en = Signal(bool(0)) phy_gmii_rxd = Signal(intbv(0)[8:]) phy_gmii_rx_dv = Signal(bool(0)) phy_gmii_rx_er = Signal(bool(0)) @@ -165,6 +166,7 @@ def bench(): txd=phy_gmii_rxd, tx_en=phy_gmii_rx_dv, tx_er=phy_gmii_rx_er, + clk_enable=phy_gmii_clk_en, name='gmii_source' ) @@ -176,6 +178,7 @@ def bench(): rxd=phy_gmii_txd, rx_dv=phy_gmii_tx_en, rx_er=phy_gmii_tx_er, + clk_enable=phy_gmii_clk_en, name='gmii_sink' ) @@ -216,6 +219,7 @@ def bench(): phy_gmii_clk=phy_gmii_clk, phy_gmii_rst=phy_gmii_rst, + phy_gmii_clk_en=phy_gmii_clk_en, phy_gmii_rxd=phy_gmii_rxd, phy_gmii_rx_dv=phy_gmii_rx_dv, phy_gmii_rx_er=phy_gmii_rx_er, @@ -236,6 +240,18 @@ def bench(): clk.next = not clk phy_gmii_clk.next = not phy_gmii_clk + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @always(clk.posedge) + def clk_enable_gen(): + if clk_enable_div.next > 0: + phy_gmii_clk_en.next = 0 + clk_enable_div.next = clk_enable_div - 1 + else: + phy_gmii_clk_en.next = 1 + clk_enable_div.next = clk_enable_rate - 1 + @instance def check(): yield delay(100) @@ -497,7 +513,7 @@ def bench(): raise StopSimulation - return dut, qsfp_1_source_logic, qsfp_1_sink_logic, qsfp_2_source_logic, qsfp_2_sink_logic, qsfp_3_source_logic, qsfp_3_sink_logic, qsfp_4_source_logic, qsfp_4_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, check + return dut, qsfp_1_source_logic, qsfp_1_sink_logic, qsfp_2_source_logic, qsfp_2_sink_logic, qsfp_3_source_logic, qsfp_3_sink_logic, qsfp_4_source_logic, qsfp_4_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check def test_bench(): sim = Simulation(bench()) diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.v b/example/VCU108/fpga_10g/tb/test_fpga_core.v index 38c74c6b1..56ea34739 100644 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.v @@ -54,6 +54,7 @@ reg [63:0] qsfp_rxd_4 = 0; reg [7:0] qsfp_rxc_4 = 0; reg phy_gmii_clk = 0; reg phy_gmii_rst = 0; +reg phy_gmii_clk_en = 0; reg [7:0] phy_gmii_rxd = 0; reg phy_gmii_rx_dv = 0; reg phy_gmii_rx_er = 0; @@ -101,6 +102,7 @@ initial begin qsfp_rxc_4, phy_gmii_clk, phy_gmii_rst, + phy_gmii_clk_en, phy_gmii_rxd, phy_gmii_rx_dv, phy_gmii_rx_er, @@ -160,6 +162,7 @@ UUT ( .qsfp_rxc_4(qsfp_rxc_4), .phy_gmii_clk(phy_gmii_clk), .phy_gmii_rst(phy_gmii_rst), + .phy_gmii_clk_en(phy_gmii_clk_en), .phy_gmii_rxd(phy_gmii_rxd), .phy_gmii_rx_dv(phy_gmii_rx_dv), .phy_gmii_rx_er(phy_gmii_rx_er), diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index 6c581c779..06fa804e2 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -12,8 +12,8 @@ SYN_FILES += rtl/sync_reset.v SYN_FILES += rtl/sync_signal.v SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v -SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx.v SYN_FILES += lib/eth/rtl/eth_axis_tx.v diff --git a/example/VCU108/fpga_1g/rtl/fpga.v b/example/VCU108/fpga_1g/rtl/fpga.v index 3d60177f7..cfa3add86 100644 --- a/example/VCU108/fpga_1g/rtl/fpga.v +++ b/example/VCU108/fpga_1g/rtl/fpga.v @@ -212,6 +212,7 @@ sync_signal_inst ( // SGMII interface to PHY wire phy_gmii_clk_int; wire phy_gmii_rst_int; +wire phy_gmii_clk_en_int; wire [7:0] phy_gmii_txd_int; wire phy_gmii_tx_en_int; wire phy_gmii_tx_er_int; @@ -219,7 +220,21 @@ wire [7:0] phy_gmii_rxd_int; wire phy_gmii_rx_dv_int; wire phy_gmii_rx_er_int; -wire [15:0] status_vector; +wire [15:0] pcspma_status_vector; + +wire pcspma_status_link_status = pcspma_status_vector[0]; +wire pcspma_status_link_synchronization = pcspma_status_vector[1]; +wire pcspma_status_rudi_c = pcspma_status_vector[2]; +wire pcspma_status_rudi_i = pcspma_status_vector[3]; +wire pcspma_status_rudi_invalid = pcspma_status_vector[4]; +wire pcspma_status_rxdisperr = pcspma_status_vector[5]; +wire pcspma_status_rxnotintable = pcspma_status_vector[6]; +wire pcspma_status_phy_link_status = pcspma_status_vector[7]; +wire [1:0] pcspma_status_remote_fault_encdg = pcspma_status_vector[9:8]; +wire [1:0] pcspma_status_speed = pcspma_status_vector[11:10]; +wire pcspma_status_duplex = pcspma_status_vector[12]; +wire pcspma_status_remote_fault = pcspma_status_vector[13]; +wire [1:0] pcspma_status_pause = pcspma_status_vector[15:14]; wire [4:0] pcspma_config_vector; @@ -268,11 +283,11 @@ eth_pcspma ( // MAC clocking .sgmii_clk_r (), .sgmii_clk_f (), - .sgmii_clk_en (), // need to pass through to MAC + .sgmii_clk_en (phy_gmii_clk_en_int), // Speed control - .speed_is_10_100 (1'b0), - .speed_is_100 (1'b0), + .speed_is_10_100 (pcspma_status_speed != 2'b10), + .speed_is_100 (pcspma_status_speed == 2'b01), // Internal GMII .gmii_txd (phy_gmii_txd_int), @@ -291,7 +306,7 @@ eth_pcspma ( .an_restart_config (1'b0), // Status - .status_vector (status_vector), + .status_vector (pcspma_status_vector), .signal_detect (1'b1) ); @@ -300,7 +315,7 @@ wire [7:0] led_int; // SGMII interface debug: // SW12:4 (sw[0]) off for payload byte, on for status vector // SW12:3 (sw[1]) off for LSB of status vector, on for MSB -assign led = sw[0] ? (sw[1] ? status_vector[15:8] : status_vector[7:0]) : led_int; +assign led = sw[0] ? (sw[1] ? pcspma_status_vector[15:8] : pcspma_status_vector[7:0]) : led_int; fpga_core core_inst ( @@ -325,6 +340,7 @@ core_inst ( */ .phy_gmii_clk(phy_gmii_clk_int), .phy_gmii_rst(phy_gmii_rst_int), + .phy_gmii_clk_en(phy_gmii_clk_en_int), .phy_gmii_rxd(phy_gmii_rxd_int), .phy_gmii_rx_dv(phy_gmii_rx_dv_int), .phy_gmii_rx_er(phy_gmii_rx_er_int), diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v index b90780ef2..08e66a651 100644 --- a/example/VCU108/fpga_1g/rtl/fpga_core.v +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -54,6 +54,7 @@ module fpga_core */ input wire phy_gmii_clk, input wire phy_gmii_rst, + input wire phy_gmii_clk_en, input wire [7:0] phy_gmii_rxd, input wire phy_gmii_rx_dv, input wire phy_gmii_rx_er, @@ -316,7 +317,7 @@ eth_mac_1g_fifo #( .TX_FIFO_ADDR_WIDTH(12), .RX_FIFO_ADDR_WIDTH(12) ) -eth_mac_1g_fifo_inst ( +eth_mac_inst ( .rx_clk(phy_gmii_clk), .rx_rst(phy_gmii_rst), .tx_clk(phy_gmii_clk), @@ -343,8 +344,19 @@ eth_mac_1g_fifo_inst ( .gmii_tx_en(phy_gmii_tx_en), .gmii_tx_er(phy_gmii_tx_er), + .rx_clk_enable(phy_gmii_clk_en), + .tx_clk_enable(phy_gmii_clk_en), + .rx_mii_select(1'b0), + .tx_mii_select(1'b0), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), .ifg_delay(12) ); diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py index a4d3147e4..6d3ee4927 100755 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -39,8 +39,8 @@ srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_1g.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v") -srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") @@ -88,6 +88,7 @@ def bench(): sw = Signal(intbv(0)[4:]) phy_gmii_clk = Signal(bool(0)) phy_gmii_rst = Signal(bool(0)) + phy_gmii_clk_en = Signal(bool(0)) phy_gmii_rxd = Signal(intbv(0)[8:]) phy_gmii_rx_dv = Signal(bool(0)) phy_gmii_rx_er = Signal(bool(0)) @@ -113,6 +114,7 @@ def bench(): txd=phy_gmii_rxd, tx_en=phy_gmii_rx_dv, tx_er=phy_gmii_rx_er, + clk_enable=phy_gmii_clk_en, name='gmii_source' ) @@ -124,6 +126,7 @@ def bench(): rxd=phy_gmii_txd, rx_dv=phy_gmii_tx_en, rx_er=phy_gmii_tx_er, + clk_enable=phy_gmii_clk_en, name='gmii_sink' ) @@ -147,6 +150,7 @@ def bench(): phy_gmii_clk=phy_gmii_clk, phy_gmii_rst=phy_gmii_rst, + phy_gmii_clk_en=phy_gmii_clk_en, phy_gmii_rxd=phy_gmii_rxd, phy_gmii_rx_dv=phy_gmii_rx_dv, phy_gmii_rx_er=phy_gmii_rx_er, @@ -167,6 +171,18 @@ def bench(): clk.next = not clk phy_gmii_clk.next = not phy_gmii_clk + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @always(clk.posedge) + def clk_enable_gen(): + if clk_enable_div.next > 0: + phy_gmii_clk_en.next = 0 + clk_enable_div.next = clk_enable_div - 1 + else: + phy_gmii_clk_en.next = 1 + clk_enable_div.next = clk_enable_rate - 1 + @instance def check(): yield delay(100) @@ -288,7 +304,7 @@ def bench(): raise StopSimulation - return dut, gmii_source_logic, gmii_sink_logic, clkgen, check + return dut, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check def test_bench(): sim = Simulation(bench()) diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.v b/example/VCU108/fpga_1g/tb/test_fpga_core.v index 6d61842df..c36f2a9d6 100644 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.v @@ -46,6 +46,7 @@ reg btnc = 0; reg [3:0] sw = 0; reg phy_gmii_clk = 0; reg phy_gmii_rst = 0; +reg phy_gmii_clk_en = 0; reg [7:0] phy_gmii_rxd = 0; reg phy_gmii_rx_dv = 0; reg phy_gmii_rx_er = 0; @@ -77,6 +78,7 @@ initial begin sw, phy_gmii_clk, phy_gmii_rst, + phy_gmii_clk_en, phy_gmii_rxd, phy_gmii_rx_dv, phy_gmii_rx_er, @@ -112,6 +114,7 @@ UUT ( .led(led), .phy_gmii_clk(phy_gmii_clk), .phy_gmii_rst(phy_gmii_rst), + .phy_gmii_clk_en(phy_gmii_clk_en), .phy_gmii_rxd(phy_gmii_rxd), .phy_gmii_rx_dv(phy_gmii_rx_dv), .phy_gmii_rx_er(phy_gmii_rx_er), From 9a507b388ddddb0a7b54f88ad217d5e4bc48822c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 9 Jun 2017 21:17:28 -0700 Subject: [PATCH 339/617] Update LFSR module --- rtl/axis_eth_fcs.v | 7 +- rtl/axis_eth_fcs_64.v | 56 +++++---- rtl/axis_eth_fcs_check.v | 7 +- rtl/axis_eth_fcs_check_64.v | 35 +++--- rtl/axis_eth_fcs_insert.v | 7 +- rtl/axis_eth_fcs_insert_64.v | 56 +++++---- rtl/axis_gmii_rx.v | 7 +- rtl/axis_gmii_tx.v | 7 +- rtl/eth_mac_10g_rx.v | 35 +++--- rtl/eth_mac_10g_tx.v | 56 +++++---- rtl/eth_mac_1g_rx.v | 7 +- rtl/eth_mac_1g_tx.v | 7 +- rtl/lfsr.v | 232 +++++++++++++++++++++++++---------- 13 files changed, 328 insertions(+), 191 deletions(-) diff --git a/rtl/axis_eth_fcs.v b/rtl/axis_eth_fcs.v index ff74205cc..5dae62bf3 100644 --- a/rtl/axis_eth_fcs.v +++ b/rtl/axis_eth_fcs.v @@ -64,15 +64,16 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(input_axis_tdata), - .lfsr_in(crc_state), - .lfsr_out(crc_next) + .state_in(crc_state), + .data_out(), + .state_out(crc_next) ); always @(posedge clk) begin diff --git a/rtl/axis_eth_fcs_64.v b/rtl/axis_eth_fcs_64.v index e310f37ab..ef7b6ee99 100644 --- a/rtl/axis_eth_fcs_64.v +++ b/rtl/axis_eth_fcs_64.v @@ -72,120 +72,128 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(input_axis_tdata[7:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next0) + .state_in(crc_state), + .data_out(), + .state_out(crc_next0) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(16), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_16 ( .data_in(input_axis_tdata[15:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next1) + .state_in(crc_state), + .data_out(), + .state_out(crc_next1) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(24), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_24 ( .data_in(input_axis_tdata[23:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next2) + .state_in(crc_state), + .data_out(), + .state_out(crc_next2) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(32), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_32 ( .data_in(input_axis_tdata[31:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next3) + .state_in(crc_state), + .data_out(), + .state_out(crc_next3) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(40), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_40 ( .data_in(input_axis_tdata[39:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next4) + .state_in(crc_state), + .data_out(), + .state_out(crc_next4) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(48), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_48 ( .data_in(input_axis_tdata[47:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next5) + .state_in(crc_state), + .data_out(), + .state_out(crc_next5) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(56), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_56 ( .data_in(input_axis_tdata[55:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next6) + .state_in(crc_state), + .data_out(), + .state_out(crc_next6) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(64), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_64 ( .data_in(input_axis_tdata[63:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next7) + .state_in(crc_state), + .data_out(), + .state_out(crc_next7) ); always @(posedge clk) begin diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v index 1f5c8adcd..3c9de7130 100644 --- a/rtl/axis_eth_fcs_check.v +++ b/rtl/axis_eth_fcs_check.v @@ -106,15 +106,16 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(input_axis_tdata_d3), - .lfsr_in(crc_state), - .lfsr_out(crc_next) + .state_in(crc_state), + .data_out(), + .state_out(crc_next) ); always @* begin diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index 502a23e07..a97de8bbe 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -121,75 +121,80 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(last_cycle ? input_axis_tdata_d0[39:32] : input_axis_tdata[7:0]), - .lfsr_in(last_cycle ? crc_state3 : crc_state), - .lfsr_out(crc_next0) + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next0) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(16), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_16 ( .data_in(last_cycle ? input_axis_tdata_d0[47:32] : input_axis_tdata[15:0]), - .lfsr_in(last_cycle ? crc_state3 : crc_state), - .lfsr_out(crc_next1) + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next1) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(24), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_24 ( .data_in(last_cycle ? input_axis_tdata_d0[55:32] : input_axis_tdata[23:0]), - .lfsr_in(last_cycle ? crc_state3 : crc_state), - .lfsr_out(crc_next2) + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next2) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(32), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_32 ( .data_in(last_cycle ? input_axis_tdata_d0[63:32] : input_axis_tdata[31:0]), - .lfsr_in(last_cycle ? crc_state3 : crc_state), - .lfsr_out(crc_next3) + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next3) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(64), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_64 ( .data_in(input_axis_tdata[63:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next7) + .state_in(crc_state), + .data_out(), + .state_out(crc_next7) ); always @* begin diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v index f1e175f09..cf5df1bb9 100644 --- a/rtl/axis_eth_fcs_insert.v +++ b/rtl/axis_eth_fcs_insert.v @@ -99,15 +99,16 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(output_axis_tdata_int), - .lfsr_in(crc_state), - .lfsr_out(crc_next) + .state_in(crc_state), + .data_out(), + .state_out(crc_next) ); always @* begin diff --git a/rtl/axis_eth_fcs_insert_64.v b/rtl/axis_eth_fcs_insert_64.v index fcef07a20..6c9afe0d7 100644 --- a/rtl/axis_eth_fcs_insert_64.v +++ b/rtl/axis_eth_fcs_insert_64.v @@ -123,120 +123,128 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(fcs_input_tdata[7:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next0) + .state_in(crc_state), + .data_out(), + .state_out(crc_next0) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(16), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_16 ( .data_in(fcs_input_tdata[15:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next1) + .state_in(crc_state), + .data_out(), + .state_out(crc_next1) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(24), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_24 ( .data_in(fcs_input_tdata[23:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next2) + .state_in(crc_state), + .data_out(), + .state_out(crc_next2) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(32), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_32 ( .data_in(fcs_input_tdata[31:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next3) + .state_in(crc_state), + .data_out(), + .state_out(crc_next3) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(40), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_40 ( .data_in(fcs_input_tdata[39:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next4) + .state_in(crc_state), + .data_out(), + .state_out(crc_next4) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(48), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_48 ( .data_in(fcs_input_tdata[47:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next5) + .state_in(crc_state), + .data_out(), + .state_out(crc_next5) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(56), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_56 ( .data_in(fcs_input_tdata[55:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next6) + .state_in(crc_state), + .data_out(), + .state_out(crc_next6) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(64), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_64 ( .data_in(fcs_input_tdata[63:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next7) + .state_in(crc_state), + .data_out(), + .state_out(crc_next7) ); function [3:0] keep2count; diff --git a/rtl/axis_gmii_rx.v b/rtl/axis_gmii_rx.v index 7c4662b7f..7505c75cb 100644 --- a/rtl/axis_gmii_rx.v +++ b/rtl/axis_gmii_rx.v @@ -117,15 +117,16 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(gmii_rxd_d4), - .lfsr_in(crc_state), - .lfsr_out(crc_next) + .state_in(crc_state), + .data_out(), + .state_out(crc_next) ); always @* begin diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index 680cc8f8c..f4be5a3fb 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -108,15 +108,16 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(input_tdata_reg), - .lfsr_in(crc_state), - .lfsr_out(crc_next) + .state_in(crc_state), + .data_out(), + .state_out(crc_next) ); always @* begin diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index af3b4711c..5ad826aa4 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -120,75 +120,80 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(last_cycle ? xgmii_rxd_d1[39:32] : xgmii_rxd_d0[7:0]), - .lfsr_in(last_cycle ? crc_state3 : crc_state), - .lfsr_out(crc_next0) + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next0) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(16), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_16 ( .data_in(last_cycle ? xgmii_rxd_d1[47:32] : xgmii_rxd_d0[15:0]), - .lfsr_in(last_cycle ? crc_state3 : crc_state), - .lfsr_out(crc_next1) + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next1) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(24), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_24 ( .data_in(last_cycle ? xgmii_rxd_d1[55:32] : xgmii_rxd_d0[23:0]), - .lfsr_in(last_cycle ? crc_state3 : crc_state), - .lfsr_out(crc_next2) + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next2) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(32), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_32 ( .data_in(last_cycle ? xgmii_rxd_d1[63:32] : xgmii_rxd_d0[31:0]), - .lfsr_in(last_cycle ? crc_state3 : crc_state), - .lfsr_out(crc_next3) + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next3) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(64), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_64 ( .data_in(xgmii_rxd_d0[63:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next7) + .state_in(crc_state), + .data_out(), + .state_out(crc_next7) ); // detect control characters diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 44777a012..90f7a9ffe 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -129,120 +129,128 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(input_tdata_reg[7:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next0) + .state_in(crc_state), + .data_out(), + .state_out(crc_next0) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(16), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_16 ( .data_in(input_tdata_reg[15:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next1) + .state_in(crc_state), + .data_out(), + .state_out(crc_next1) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(24), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_24 ( .data_in(input_tdata_reg[23:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next2) + .state_in(crc_state), + .data_out(), + .state_out(crc_next2) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(32), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_32 ( .data_in(input_tdata_reg[31:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next3) + .state_in(crc_state), + .data_out(), + .state_out(crc_next3) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(40), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_40 ( .data_in(input_tdata_reg[39:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next4) + .state_in(crc_state), + .data_out(), + .state_out(crc_next4) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(48), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_48 ( .data_in(input_tdata_reg[47:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next5) + .state_in(crc_state), + .data_out(), + .state_out(crc_next5) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(56), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_56 ( .data_in(input_tdata_reg[55:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next6) + .state_in(crc_state), + .data_out(), + .state_out(crc_next6) ); lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(64), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_64 ( .data_in(input_tdata_reg[63:0]), - .lfsr_in(crc_state), - .lfsr_out(crc_next7) + .state_in(crc_state), + .data_out(), + .state_out(crc_next7) ); function [3:0] keep2count; diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v index 36f3f7e8d..4e3a524ea 100644 --- a/rtl/eth_mac_1g_rx.v +++ b/rtl/eth_mac_1g_rx.v @@ -108,15 +108,16 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(gmii_rxd_d4), - .lfsr_in(crc_state), - .lfsr_out(crc_next) + .state_in(crc_state), + .data_out(), + .state_out(crc_next) ); always @* begin diff --git a/rtl/eth_mac_1g_tx.v b/rtl/eth_mac_1g_tx.v index 9407eb692..7522ed35d 100644 --- a/rtl/eth_mac_1g_tx.v +++ b/rtl/eth_mac_1g_tx.v @@ -96,15 +96,16 @@ lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), .REVERSE(1), .DATA_WIDTH(8), - .OUTPUT_WIDTH(32), .STYLE("AUTO") ) eth_crc_8 ( .data_in(gmii_txd_next), - .lfsr_in(crc_state), - .lfsr_out(crc_next) + .state_in(crc_state), + .data_out(), + .state_out(crc_next) ); always @* begin diff --git a/rtl/lfsr.v b/rtl/lfsr.v index 57c0c80d9..6325f9c57 100644 --- a/rtl/lfsr.v +++ b/rtl/lfsr.v @@ -37,19 +37,20 @@ module lfsr # parameter LFSR_POLY = 31'h10000001, // LFSR configuration: "GALOIS", "FIBONACCI" parameter LFSR_CONFIG = "FIBONACCI", + // LFSR feed forward enable + parameter LFSR_FEED_FORWARD = 0, // bit-reverse input and output parameter REVERSE = 0, // width of data input parameter DATA_WIDTH = 8, - // width of CRC/LFSR output - parameter OUTPUT_WIDTH = LFSR_WIDTH, // implementation style: "AUTO", "LOOP", "REDUCTION" parameter STYLE = "AUTO" ) ( - input wire [DATA_WIDTH-1:0] data_in, - input wire [LFSR_WIDTH-1:0] lfsr_in, - output wire [OUTPUT_WIDTH-1:0] lfsr_out + input wire [DATA_WIDTH-1:0] data_in, + input wire [LFSR_WIDTH-1:0] state_in, + output wire [DATA_WIDTH-1:0] data_out, + output wire [LFSR_WIDTH-1:0] state_out ); /* @@ -65,15 +66,19 @@ Ports: data_in -Data bits to be XORed with the LFSR feedback path (DATA_WIDTH bits) +Data bits to be shifted through the LFSR (DATA_WIDTH bits) -lfsr_in +state_in LFSR/CRC current state input (LFSR_WIDTH bits) -lfsr_out +data_out -LFSR/CRC next state output (OUTPUT_WIDTH bits) +Data bits shifted out of LFSR (DATA_WIDTH bits) + +state_out + +LFSR/CRC next state output (LFSR_WIDTH bits) Parameters: @@ -103,37 +108,60 @@ generators and checkers. Fibonacci style (example for 64b66b scrambler, 0x8000000001) - ,-----------------------------(+)<------------------------------, - | ^ | - | .----. .----. .----. | .----. .----. .----. | - `->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |->(+)<-DIN (MSB first) - '----' '----' '----' '----' '----' '----' + DIN (LSB first) + | + V + (+)<---------------------------(+)<-----------------------------. + | ^ | + | .----. .----. .----. | .----. .----. .----. | + +->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--' + | '----' '----' '----' '----' '----' '----' + V + DOUT Galois style (example for CRC16, 0x8005) - ,-------------------+---------------------------------+------------, - | | | | - | .----. .----. V .----. .----. .----. V .----. | - `->| 0 |->| 1 |->(+)->| 2 |->| 3 |->...->| 14 |->(+)->| 15 |->(+)<-DIN (MSB first) - '----' '----' '----' '----' '----' '----' + ,-------------------+-------------------------+----------(+)<-- DIN (MSB first) + | | | ^ + | .----. .----. V .----. .----. V .----. | + `->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |--+---> DOUT + '----' '----' '----' '----' '----' + +LFSR_FEED_FORWARD + +Generate feed forward instead of feed back LFSR. Enable this for PRBS checking and self- +synchronous descrambling. + +Fibonacci feed-forward style (example for 64b66b descrambler, 0x8000000001) + + DIN (LSB first) + | + | .----. .----. .----. .----. .----. .----. + +->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--. + | '----' '----' '----' | '----' '----' '----' | + | V | + (+)<---------------------------(+)------------------------------' + | + V + DOUT + +Galois feed-forward style + + ,-------------------+-------------------------+------------+--- DIN (MSB first) + | | | | + | .----. .----. V .----. .----. V .----. V + `->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |->(+)-> DOUT + '----' '----' '----' '----' '----' REVERSE -Bit-reverse LFSR input and output. +Bit-reverse LFSR input and output. Shifts MSB first by default, set REVERSE for LSB first. DATA_WIDTH -Specify width of input data bus. The module will perform one shift per input data bit, -so if the input data bus is not required tie data_in to zero and set DATA_WIDTH to the -required number of shifts per clock cycle. - -OUTPUT_WIDTH - -Specify width of output data bus. Defaults to LFSR_WIDTH. Mainly useful for extending -the output width for LFSRs. Ensure that lfsr_out is properly shifted and truncated so -that feeding it back around to lfsr_in produces the expected result. Note that if -OUTPUT_WIDTH is smaller than LFSR_WIDTH, it may not be possible to get the LFSR to -feed back correctly. +Specify width of input and output data bus. The module will perform one shift per input +data bit, so if the input data bus is not required tie data_in to zero and set DATA_WIDTH +to the required number of shifts per clock cycle. STYLE @@ -151,27 +179,29 @@ synthesis translate directives. Settings for common LFSR/CRC implementations: Name Configuration Length Polynomial Initial value Notes +CRC16-IBM Galois, bit-reverse 16 16'h8005 16'hffff +CRC16-CCITT Galois 16 16'h1021 16'h1d0f CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output PRBS6 Fibonacci 6 6'h21 any -PRBS7 Fibonacci 7 7'h41 amy +PRBS7 Fibonacci 7 7'h41 any PRBS9 Fibonacci 9 9'h021 any ITU V.52 PRBS10 Fibonacci 10 10'h081 any ITU PRBS11 Fibonacci 11 11'h201 any ITU O.152 -PRBS15 Fibonacci 15 15'h4001 any ITU O.152 +PRBS15 Fibonacci, inverted 15 15'h4001 any ITU O.152 PRBS17 Fibonacci 17 17'h04001 any PRBS20 Fibonacci 20 20'h00009 any ITU V.57 -PRBS23 Fibonacci 23 23'h040001 any ITU O.151 -PRBS31 Fibonacci 31 31'h10000001 any -64b66b Fibonacci 58 58'h8000000001 any 10G Ethernet -128b130b Fibonacci 23 23'h210125 any PCIe gen 3 +PRBS23 Fibonacci, inverted 23 23'h040001 any ITU O.151 +PRBS29 Fibonacci, inverted 29 29'h08000001 any +PRBS31 Fibonacci, inverted 31 31'h10000001 any +64b66b Fibonacci, bit-reverse 58 58'h8000000001 any 10G Ethernet +128b130b Galois, bit-reverse 23 23'h210125 any PCIe gen 3 */ -// STATE_WIDTH is OUTPUT_WIDTH or LFSR_WIDTH, whichever is larger -parameter STATE_WIDTH = OUTPUT_WIDTH > LFSR_WIDTH ? OUTPUT_WIDTH : LFSR_WIDTH; - -reg [LFSR_WIDTH-1:0] lfsr_mask_state[STATE_WIDTH-1:0]; -reg [DATA_WIDTH-1:0] lfsr_mask_data[STATE_WIDTH-1:0]; +reg [LFSR_WIDTH-1:0] lfsr_mask_state[LFSR_WIDTH-1:0]; +reg [DATA_WIDTH-1:0] lfsr_mask_data[LFSR_WIDTH-1:0]; +reg [LFSR_WIDTH-1:0] output_mask_state[DATA_WIDTH-1:0]; +reg [DATA_WIDTH-1:0] output_mask_data[DATA_WIDTH-1:0]; reg [LFSR_WIDTH-1:0] state_val = 0; reg [DATA_WIDTH-1:0] data_val = 0; @@ -180,13 +210,18 @@ integer i, j, k; initial begin // init bit masks - for (i = 0; i < STATE_WIDTH; i = i + 1) begin + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin lfsr_mask_state[i] = {LFSR_WIDTH{1'b0}}; - if (i < LFSR_WIDTH) begin - lfsr_mask_state[i][i] = 1'b1; - end + lfsr_mask_state[i][i] = 1'b1; lfsr_mask_data[i] = {DATA_WIDTH{1'b0}}; end + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + output_mask_state[i] = {LFSR_WIDTH{1'b0}}; + if (i < LFSR_WIDTH) begin + output_mask_state[i][i] = 1'b1; + end + output_mask_data[i] = {DATA_WIDTH{1'b0}}; + end // simulate shift register if (LFSR_CONFIG == "FIBONACCI") begin @@ -199,7 +234,7 @@ initial begin data_val = data_val ^ (1 << i); // add XOR inputs from correct indicies - for (j = 1; j < STATE_WIDTH; j = j + 1) begin + for (j = 1; j < LFSR_WIDTH; j = j + 1) begin if (LFSR_POLY & (1 << j)) begin state_val = lfsr_mask_state[j-1] ^ state_val; data_val = lfsr_mask_data[j-1] ^ data_val; @@ -207,10 +242,21 @@ initial begin end // shift - for (j = STATE_WIDTH-1; j > 0; j = j - 1) begin + for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin lfsr_mask_state[j] = lfsr_mask_state[j-1]; lfsr_mask_data[j] = lfsr_mask_data[j-1]; end + for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin + output_mask_state[j] = output_mask_state[j-1]; + output_mask_data[j] = output_mask_data[j-1]; + end + output_mask_state[0] = state_val; + output_mask_data[0] = data_val; + if (LFSR_FEED_FORWARD) begin + // only shift in new input data + state_val = {LFSR_WIDTH{1'b0}}; + data_val = 1 << i; + end lfsr_mask_state[0] = state_val; lfsr_mask_data[0] = data_val; end @@ -224,15 +270,26 @@ initial begin data_val = data_val ^ (1 << i); // shift - for (j = STATE_WIDTH-1; j > 0; j = j - 1) begin + for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin lfsr_mask_state[j] = lfsr_mask_state[j-1]; lfsr_mask_data[j] = lfsr_mask_data[j-1]; end + for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin + output_mask_state[j] = output_mask_state[j-1]; + output_mask_data[j] = output_mask_data[j-1]; + end + output_mask_state[0] = state_val; + output_mask_data[0] = data_val; + if (LFSR_FEED_FORWARD) begin + // only shift in new input data + state_val = {LFSR_WIDTH{1'b0}}; + data_val = 1 << i; + end lfsr_mask_state[0] = state_val; lfsr_mask_data[0] = data_val; // add XOR inputs at correct indicies - for (j = 1; j < STATE_WIDTH; j = j + 1) begin + for (j = 1; j < LFSR_WIDTH; j = j + 1) begin if (LFSR_POLY & (1 << j)) begin lfsr_mask_state[j] = lfsr_mask_state[j] ^ state_val; lfsr_mask_data[j] = lfsr_mask_data[j] ^ data_val; @@ -247,19 +304,27 @@ initial begin // reverse bits if selected if (REVERSE) begin // reverse order - for (i = 0; i < OUTPUT_WIDTH/2; i = i + 1) begin + for (i = 0; i < LFSR_WIDTH/2; i = i + 1) begin state_val = lfsr_mask_state[i]; data_val = lfsr_mask_data[i]; - lfsr_mask_state[i] = lfsr_mask_state[OUTPUT_WIDTH-i-1]; - lfsr_mask_data[i] = lfsr_mask_data[OUTPUT_WIDTH-i-1]; - lfsr_mask_state[OUTPUT_WIDTH-i-1] = state_val; - lfsr_mask_data[OUTPUT_WIDTH-i-1] = data_val; + lfsr_mask_state[i] = lfsr_mask_state[LFSR_WIDTH-i-1]; + lfsr_mask_data[i] = lfsr_mask_data[LFSR_WIDTH-i-1]; + lfsr_mask_state[LFSR_WIDTH-i-1] = state_val; + lfsr_mask_data[LFSR_WIDTH-i-1] = data_val; + end + for (i = 0; i < DATA_WIDTH/2; i = i + 1) begin + state_val = output_mask_state[i]; + data_val = output_mask_data[i]; + output_mask_state[i] = output_mask_state[DATA_WIDTH-i-1]; + output_mask_data[i] = output_mask_data[DATA_WIDTH-i-1]; + output_mask_state[DATA_WIDTH-i-1] = state_val; + output_mask_data[DATA_WIDTH-i-1] = data_val; end // reverse bits - for (i = 0; i < OUTPUT_WIDTH; i = i + 1) begin + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin state_val = 0; - for (j = 0; j < STATE_WIDTH; j = j + 1) begin - state_val[j] = lfsr_mask_state[i][STATE_WIDTH-j-1]; + for (j = 0; j < LFSR_WIDTH; j = j + 1) begin + state_val[j] = lfsr_mask_state[i][LFSR_WIDTH-j-1]; end lfsr_mask_state[i] = state_val; @@ -269,9 +334,22 @@ initial begin end lfsr_mask_data[i] = data_val; end + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + state_val = 0; + for (j = 0; j < LFSR_WIDTH; j = j + 1) begin + state_val[j] = output_mask_state[i][LFSR_WIDTH-j-1]; + end + output_mask_state[i] = state_val; + + data_val = 0; + for (j = 0; j < DATA_WIDTH; j = j + 1) begin + data_val[j] = output_mask_data[i][DATA_WIDTH-j-1]; + end + output_mask_data[i] = data_val; + end end - // for (i = 0; i < OUTPUT_WIDTH; i = i + 1) begin + // for (i = 0; i < LFSR_WIDTH; i = i + 1) begin // $display("%b %b", lfsr_mask_state[i], lfsr_mask_data[i]); // end end @@ -300,8 +378,11 @@ if (STYLE_INT == "REDUCTION") begin // slightly smaller than generated code with Quartus // --> better for simulation - for (n = 0; n < OUTPUT_WIDTH; n = n + 1) begin : loop - assign lfsr_out[n] = ^{(lfsr_in & lfsr_mask_state[n]), (data_in & lfsr_mask_data[n])}; + for (n = 0; n < LFSR_WIDTH; n = n + 1) begin : loop1 + assign state_out[n] = ^{(state_in & lfsr_mask_state[n]), (data_in & lfsr_mask_data[n])}; + end + for (n = 0; n < DATA_WIDTH; n = n + 1) begin : loop2 + assign data_out[n] = ^{(state_in & output_mask_state[n]), (data_in & output_mask_data[n])}; end end else if (STYLE_INT == "LOOP") begin @@ -312,21 +393,36 @@ end else if (STYLE_INT == "LOOP") begin // same size as generated code with Quartus // --> better for synthesis - reg [OUTPUT_WIDTH-1:0] lfsr_out_reg = 0; + reg [LFSR_WIDTH-1:0] state_out_reg = 0; + reg [DATA_WIDTH-1:0] data_out_reg = 0; - assign lfsr_out = lfsr_out_reg; + assign state_out = state_out_reg; + assign data_out = data_out_reg; always @* begin - for (i = 0; i < OUTPUT_WIDTH; i = i + 1) begin - lfsr_out_reg[i] = 0; - for (j = 0; j < STATE_WIDTH; j = j + 1) begin + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin + state_out_reg[i] = 0; + for (j = 0; j < LFSR_WIDTH; j = j + 1) begin if (lfsr_mask_state[i][j]) begin - lfsr_out_reg[i] = lfsr_out_reg[i] ^ lfsr_in[j]; + state_out_reg[i] = state_out_reg[i] ^ state_in[j]; end end for (j = 0; j < DATA_WIDTH; j = j + 1) begin if (lfsr_mask_data[i][j]) begin - lfsr_out_reg[i] = lfsr_out_reg[i] ^ data_in[j]; + state_out_reg[i] = state_out_reg[i] ^ data_in[j]; + end + end + end + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + data_out_reg[i] = 0; + for (j = 0; j < LFSR_WIDTH; j = j + 1) begin + if (output_mask_state[i][j]) begin + data_out_reg[i] = data_out_reg[i] ^ state_in[j]; + end + end + for (j = 0; j < DATA_WIDTH; j = j + 1) begin + if (output_mask_data[i][j]) begin + data_out_reg[i] = data_out_reg[i] ^ data_in[j]; end end end From 77211926f2dd114cdc8d1963e557db832f0df6bf Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 9 Jun 2017 21:27:29 -0700 Subject: [PATCH 340/617] Fix classifier logic --- rtl/ip_complete.v | 4 +++- rtl/ip_complete_64.v | 4 +++- rtl/udp_complete.v | 3 ++- rtl/udp_complete_64.v | 3 ++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/rtl/ip_complete.v b/rtl/ip_complete.v index d0dcd6172..2fcb588bf 100644 --- a/rtl/ip_complete.v +++ b/rtl/ip_complete.v @@ -240,7 +240,9 @@ assign arp_rx_eth_payload_tvalid = input_select_arp_reg & input_eth_payload_tval assign arp_rx_eth_payload_tlast = input_eth_payload_tlast; assign arp_rx_eth_payload_tuser = input_eth_payload_tuser; -assign input_eth_hdr_ready = arp_rx_eth_hdr_ready & ip_rx_eth_hdr_ready; +assign input_eth_hdr_ready = (input_select_ip & ip_rx_eth_hdr_ready) | + (input_select_arp & arp_rx_eth_hdr_ready) | + (input_select_none); assign input_eth_payload_tready = (input_select_ip_reg & ip_rx_eth_payload_tready) | (input_select_arp_reg & arp_rx_eth_payload_tready) | diff --git a/rtl/ip_complete_64.v b/rtl/ip_complete_64.v index 69f1cca3d..9e79b095b 100644 --- a/rtl/ip_complete_64.v +++ b/rtl/ip_complete_64.v @@ -250,7 +250,9 @@ assign arp_rx_eth_payload_tvalid = input_select_arp_reg & input_eth_payload_tval assign arp_rx_eth_payload_tlast = input_eth_payload_tlast; assign arp_rx_eth_payload_tuser = input_eth_payload_tuser; -assign input_eth_hdr_ready = arp_rx_eth_hdr_ready & ip_rx_eth_hdr_ready; +assign input_eth_hdr_ready = (input_select_ip & ip_rx_eth_hdr_ready) | + (input_select_arp & arp_rx_eth_hdr_ready) | + (input_select_none); assign input_eth_payload_tready = (input_select_ip_reg & ip_rx_eth_payload_tready) | (input_select_arp_reg & arp_rx_eth_payload_tready) | diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v index 3b04b1165..199420e33 100644 --- a/rtl/udp_complete.v +++ b/rtl/udp_complete.v @@ -344,7 +344,8 @@ assign output_ip_payload_tvalid = input_select_ip_reg & ip_rx_ip_payload_tvalid; assign output_ip_payload_tlast = ip_rx_ip_payload_tlast; assign output_ip_payload_tuser = ip_rx_ip_payload_tuser; -assign ip_rx_ip_hdr_ready = udp_rx_ip_hdr_ready & output_ip_hdr_ready; +assign ip_rx_ip_hdr_ready = (input_select_udp & udp_rx_ip_hdr_ready) | + (input_select_ip & output_ip_hdr_ready); assign ip_rx_ip_payload_tready = (input_select_udp_reg & udp_rx_ip_payload_tready) | (input_select_ip_reg & output_ip_payload_tready); diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v index 331c3e144..92990922c 100644 --- a/rtl/udp_complete_64.v +++ b/rtl/udp_complete_64.v @@ -356,7 +356,8 @@ assign output_ip_payload_tvalid = input_select_ip_reg & ip_rx_ip_payload_tvalid; assign output_ip_payload_tlast = ip_rx_ip_payload_tlast; assign output_ip_payload_tuser = ip_rx_ip_payload_tuser; -assign ip_rx_ip_hdr_ready = udp_rx_ip_hdr_ready & output_ip_hdr_ready; +assign ip_rx_ip_hdr_ready = (input_select_udp & udp_rx_ip_hdr_ready) | + (input_select_ip & output_ip_hdr_ready); assign ip_rx_ip_payload_tready = (input_select_udp_reg & udp_rx_ip_payload_tready) | (input_select_ip_reg & output_ip_payload_tready); From eb47bea9a1ee4afdf93ba65eb15270068480bcd6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 9 Jun 2017 21:28:08 -0700 Subject: [PATCH 341/617] Use correct clock in testbench --- example/ATLYS/fpga/tb/test_fpga_core.py | 2 +- example/ML605/fpga_gmii/tb/test_fpga_core.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index 35ad07823..bdb7fea7f 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -127,7 +127,7 @@ def bench(): gmii_sink = gmii_ep.GMIISink() gmii_sink_logic = gmii_sink.create_logic( - phy_gtx_clk, + phy_tx_clk, rst, rxd=phy_txd, rx_dv=phy_tx_en, diff --git a/example/ML605/fpga_gmii/tb/test_fpga_core.py b/example/ML605/fpga_gmii/tb/test_fpga_core.py index 9e6931b6d..8ec5d3e6d 100755 --- a/example/ML605/fpga_gmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_gmii/tb/test_fpga_core.py @@ -136,7 +136,7 @@ def bench(): gmii_sink = gmii_ep.GMIISink() gmii_sink_logic = gmii_sink.create_logic( - phy_gtx_clk, + phy_tx_clk, rst, rxd=phy_txd, rx_dv=phy_tx_en, From cf6a01fffeda33b0748f942532ad91e945d4903f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 22 Jul 2017 11:07:23 -0700 Subject: [PATCH 342/617] Add ML605 SGMII design --- example/ML605/fpga_sgmii/Makefile | 25 + example/ML605/fpga_sgmii/README.md | 28 + example/ML605/fpga_sgmii/clock.ucf | 24 + example/ML605/fpga_sgmii/common/xilinx.mk | 191 ++++++ example/ML605/fpga_sgmii/coregen/Makefile | 33 + example/ML605/fpga_sgmii/coregen/coregen.cgp | 22 + .../coregen/gig_eth_pcs_pma_v11_5.xco | 57 ++ example/ML605/fpga_sgmii/fpga.ucf | 94 +++ example/ML605/fpga_sgmii/fpga/Makefile | 81 +++ example/ML605/fpga_sgmii/lib/eth | 1 + .../ML605/fpga_sgmii/rtl/debounce_switch.v | 89 +++ example/ML605/fpga_sgmii/rtl/fpga.v | 398 ++++++++++++ example/ML605/fpga_sgmii/rtl/fpga_core.v | 579 ++++++++++++++++++ example/ML605/fpga_sgmii/rtl/sync_reset.v | 52 ++ example/ML605/fpga_sgmii/rtl/sync_signal.v | 58 ++ example/ML605/fpga_sgmii/tb/arp_ep.py | 1 + example/ML605/fpga_sgmii/tb/axis_ep.py | 1 + example/ML605/fpga_sgmii/tb/eth_ep.py | 1 + example/ML605/fpga_sgmii/tb/gmii_ep.py | 1 + example/ML605/fpga_sgmii/tb/ip_ep.py | 1 + example/ML605/fpga_sgmii/tb/test_fpga_core.py | 328 ++++++++++ example/ML605/fpga_sgmii/tb/test_fpga_core.v | 143 +++++ example/ML605/fpga_sgmii/tb/udp_ep.py | 1 + 23 files changed, 2209 insertions(+) create mode 100644 example/ML605/fpga_sgmii/Makefile create mode 100644 example/ML605/fpga_sgmii/README.md create mode 100644 example/ML605/fpga_sgmii/clock.ucf create mode 100644 example/ML605/fpga_sgmii/common/xilinx.mk create mode 100644 example/ML605/fpga_sgmii/coregen/Makefile create mode 100644 example/ML605/fpga_sgmii/coregen/coregen.cgp create mode 100644 example/ML605/fpga_sgmii/coregen/gig_eth_pcs_pma_v11_5.xco create mode 100644 example/ML605/fpga_sgmii/fpga.ucf create mode 100644 example/ML605/fpga_sgmii/fpga/Makefile create mode 120000 example/ML605/fpga_sgmii/lib/eth create mode 100644 example/ML605/fpga_sgmii/rtl/debounce_switch.v create mode 100644 example/ML605/fpga_sgmii/rtl/fpga.v create mode 100644 example/ML605/fpga_sgmii/rtl/fpga_core.v create mode 100644 example/ML605/fpga_sgmii/rtl/sync_reset.v create mode 100644 example/ML605/fpga_sgmii/rtl/sync_signal.v create mode 120000 example/ML605/fpga_sgmii/tb/arp_ep.py create mode 120000 example/ML605/fpga_sgmii/tb/axis_ep.py create mode 120000 example/ML605/fpga_sgmii/tb/eth_ep.py create mode 120000 example/ML605/fpga_sgmii/tb/gmii_ep.py create mode 120000 example/ML605/fpga_sgmii/tb/ip_ep.py create mode 100755 example/ML605/fpga_sgmii/tb/test_fpga_core.py create mode 100644 example/ML605/fpga_sgmii/tb/test_fpga_core.v create mode 120000 example/ML605/fpga_sgmii/tb/udp_ep.py diff --git a/example/ML605/fpga_sgmii/Makefile b/example/ML605/fpga_sgmii/Makefile new file mode 100644 index 000000000..9f8bd4048 --- /dev/null +++ b/example/ML605/fpga_sgmii/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = coregen fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/ML605/fpga_sgmii/README.md b/example/ML605/fpga_sgmii/README.md new file mode 100644 index 000000000..b08c34422 --- /dev/null +++ b/example/ML605/fpga_sgmii/README.md @@ -0,0 +1,28 @@ +# Verilog Ethernet ML605 SGMII Example Design + +## Introduction + +This example design targets the Xilinx ML605 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +Configure the PHY for SGMII by placing J66 and J67 across pins 2 and 3 and +opening J68. + +FPGA: XC6SlX45-2CSG324 +PHY: Marvell M88E1111 + +## How to build + +Run make to build. Ensure that the Xilinx ISE toolchain components are +in PATH. + +## How to test + +Run make program to program the ML605 board with the Xilinx Impact software. +Then run netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. +Any text entered into netcat will be echoed back after pressing enter. + + diff --git a/example/ML605/fpga_sgmii/clock.ucf b/example/ML605/fpga_sgmii/clock.ucf new file mode 100644 index 000000000..7033a3576 --- /dev/null +++ b/example/ML605/fpga_sgmii/clock.ucf @@ -0,0 +1,24 @@ +# UCF file for clock module domain crossing constraints + +NET "phy_sgmii_txoutclk" TNM_NET = "txoutclk"; +TIMESPEC "TS_txoutclk" = PERIOD "txoutclk" 8 ns HIGH 50 %; + +NET "eth_pcspma/transceiver_inst/RXRECCLK" TNM_NET = "rxrecclk"; +TIMESPEC "ts_rxrecclk" = PERIOD "rxrecclk" 8 ns; + +# Identify clock domain crossing registers +INST "eth_pcspma/transceiver_inst/rx_elastic_buffer_inst/wr_addr_gray*" TNM = "wr_graycode"; +INST "eth_pcspma/transceiver_inst/rx_elastic_buffer_inst/rd_addr_gray*" TNM = "rd_graycode"; + +# Control Gray Code delay and skew across clock boundary +TIMESPEC "ts_rx_skew_control1" = FROM "wr_graycode" TO "FFS" 14 ns DATAPATHONLY; +TIMESPEC "ts_rx_skew_control2" = FROM "rd_graycode" TO "FFS" 14 ns DATAPATHONLY; + +# Constrain between Distributed Memory (output data) and the 1st set of flip-flops +INST "eth_pcspma/transceiver_inst/rx_elastic_buffer_inst/*rd_data*" TNM = "fifo_read"; +TIMESPEC "ts_ram_read_false_path" = FROM "RAMS" TO "fifo_read" 6 ns DATAPATHONLY; + +NET "clk_125mhz_int" TNM = "ffs_clk_125mhz_int"; +NET "phy_sgmii_txoutclk" TNM = "ffs_sgmii_clk"; +TIMESPEC "TS_clk_125mhz_int_to_sgmii_clk" = FROM "ffs_clk_125mhz_int" TO "ffs_sgmii_clk" 10 ns; +TIMESPEC "TS_sgmii_clk_to_clk_125mhz_int" = FROM "ffs_sgmii_clk" TO "ffs_clk_125mhz_int" 10 ns; diff --git a/example/ML605/fpga_sgmii/common/xilinx.mk b/example/ML605/fpga_sgmii/common/xilinx.mk new file mode 100644 index 000000000..f10a45f8e --- /dev/null +++ b/example/ML605/fpga_sgmii/common/xilinx.mk @@ -0,0 +1,191 @@ +############################################################################# +# Author: Lane Brooks/Keith Fife +# Date: 04/28/2006 +# License: GPL +# Desc: This is a Makefile intended to take a verilog rtl design +# through the Xilinx ISE tools to generate configuration files for +# Xilinx FPGAs. This file is generic and just a template. As such +# all design specific options such as synthesis files, fpga part type, +# prom part type, etc should be set in the top Makefile prior to +# including this file. Alternatively, all parameters can be passed +# in from the command line as well. +# +############################################################################## +# +# Parameter: +# SYN_FILES - Space seperated list of files to be synthesized +# PART - FPGA part (see Xilinx documentation) +# PROM - PROM part +# NGC_PATHS - Space seperated list of any dirs with pre-compiled ngc files. +# UCF_FILES - Space seperated list of user constraint files. Defaults to xilinx/$(FPGA_TOP).ucf +# +# +# Example Calling Makefile: +# +# SYN_FILES = fpga.v fifo.v clks.v +# PART = xc3s1000 +# FPGA_TOP = fpga +# PROM = xc18v04 +# NGC_PATH = ipLib1 ipLib2 +# FPGA_ARCH = spartan6 +# SPI_PROM_SIZE = (in bytes) +# include xilinx.mk +############################################################################# +# +# Command Line Example: +# make -f xilinx.mk PART=xc3s1000-4fg320 SYN_FILES="fpga.v test.v" FPGA_TOP=fpga +# +############################################################################## +# +# Required Setup: +# +# %.ucf - user constraint file. Needed by ngdbuild +# +# Optional Files: +# %.xcf - user constraint file. Needed by xst. +# %.ut - File for pin states needed by bitgen + + +.PHONY: clean bit prom fpga spi + + +# Mark the intermediate files as PRECIOUS to prevent make from +# deleting them (see make manual section 10.4). +.PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.bit %_timesim.v + +# include the local Makefile for project for any project specific targets +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +INC_PATHS_REL = $(patsubst %, ../%, $(INC_PATHS)) +NGC_PATHS_REL = $(patsubst %, ../%, $(NGC_PATHS)) + +ifdef UCF_FILES + UCF_FILES_REL = $(patsubst %, ../%, $(UCF_FILES)) +else + UCF_FILES_REL = $(FPGA_TOP).ucf +endif + + + +fpga: $(FPGA_TOP).bit + +mcs: $(FPGA_TOP).mcs + +prom: $(FPGA_TOP).spi + +spi: $(FPGA_TOP).spi + +fpgasim: $(FPGA_TOP)_sim.v + + +########################### XST TEMPLATES ############################ +# There are 2 files that XST uses for synthesis that we auto generate. +# The first is a project file which is just a list of all the verilog +# files. The second is the src file which passes XST all the options. +# See XST user manual for XST options. +%.ngc: $(SYN_FILES_REL) $(INC_FILES_REL) + rm -rf xst $*.prj $*.xst defines.v + touch defines.v + mkdir -p xst/tmp + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo verilog work defines.v > $*.prj + for x in $(SYN_FILES_REL); do echo verilog work $$x >> $*.prj; done + @echo "set -tmpdir ./xst/tmp" >> $*.xst + @echo "set -xsthdpdir ./xst" >> $*.xst + @echo "run" >> $*.xst + @echo "-ifn $*.prj" >> $*.xst + @echo "-ifmt mixed" >> $*.xst + @echo "-top $*" >> $*.xst + @echo "-ofn $*" >> $*.xst + @echo "-ofmt NGC" >> $*.xst + @echo "-opt_mode Speed" >> $*.xst + @echo "-opt_level 1" >> $*.xst + # @echo "-verilog2001 YES" >> $*.xst + @echo "-keep_hierarchy NO" >> $*.xst + @echo "-p $(FPGA_PART)" >> $*.xst + xst -ifn $*.xst -ofn $*.log + + +########################### ISE TRANSLATE ############################ +# ngdbuild will automatically use a ucf called %.ucf if one is found. +# We setup the dependancy such that %.ucf file is required. If any +# pre-compiled ncd files are needed, set the NGC_PATH variable as a space +# seperated list of directories that include the pre-compiled ngc files. +%.ngd: %.ngc $(UCF_FILES_REL) + ngdbuild -dd ngdbuild $(patsubst %,-sd %, $(NGC_PATHS_REL)) $(patsubst %,-uc %, $(UCF_FILES_REL)) -p $(FPGA_PART) $< $@ + + +########################### ISE MAP ################################### +ifeq ($(FPGA_ARCH),spartan6) + MAP_OPTS= -register_duplication on -timing -xe n +else + MAP_OPTS= -cm speed -register_duplication on -timing -xe n -pr b +endif + +%_map.ncd: %.ngd + map -p $(FPGA_PART) $(MAP_OPTS) -w -o $@ $< $*.pcf + +# map -p $(FPGA_PART) -cm area -pr b -k 4 -c 100 -o $@ $< $*.pcf + + +########################### ISE PnR ################################### +%.ncd: %_map.ncd + par -w -ol high $< $@ $*.pcf + +# par -w -ol std -t 1 $< $@ $*.pcf + + +##################### ISE Static Timing Analysis ##################### +%.twr: %.ncd + -trce -e 3 -l 3 -u -xml $* $< -o $@ $*.pcf + +%_sim.v: %.ncd + netgen -s 4 -pcf $*.pcf -sdf_anno true -ism -sdf_path netgen -w -dir . -ofmt verilog -sim $< $@ + +# netgen -ise "/home/lane/Second/xilinx/Second/Second" -intstyle ise -s 4 -pcf Second.pcf -sdf_anno true -sdf_path netgen/par -w -dir netgen/par -ofmt verilog -sim Second.ncd Second_timesim.v + + +########################### ISE Bitgen ############################# +%.bit: %.twr + bitgen $(BITGEN_OPTIONS) -w $*.ncd $*.bit + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +########################### ISE Promgen ############################# +%.mcs: %.bit + promgen -spi -w -p mcs -s $(SPI_PROM_SIZE) -o $@ -u 0 $< + # promgen -w -p mcs -c FF -o $@ -u 0 $< -x $(PROM) + mkdir -p rev + EXT=mcs; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +%.spi: %.mcs + objcopy -I ihex -O binary $< $@ + EXT=spi; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + + +tmpclean: + -rm -rf xst ngdbuild *_map.* *.ncd *.ngc *.log *.xst *.prj *.lso *~ *.pcf *.bld *.ngd *.xpi *_pad.* *.unroutes *.twx *.par *.twr *.pad *.drc *.bgn *.prm *.sig netgen *.v *.nlf *.xml + +clean: tmpclean + -rm -rf *.bit *.mcs + +# clean everything +distclean: clean + -rm -rf rev + diff --git a/example/ML605/fpga_sgmii/coregen/Makefile b/example/ML605/fpga_sgmii/coregen/Makefile new file mode 100644 index 000000000..b36831721 --- /dev/null +++ b/example/ML605/fpga_sgmii/coregen/Makefile @@ -0,0 +1,33 @@ +# Tools +COREGEN:=coregen +XAW2VERILOG:=xaw2verilog + +# Source +XCO:=gig_eth_pcs_pma_v11_5.xco +XAW:= + +# Targets +TARGETS += $(XCO:.xco=) +TARGETS += $(XAW:.xaw=) + +# Rules +.PHONY: all +all: $(TARGETS) + +.PHONY: clean +clean: + -rm -rf $(TARGETS) + +%: %.xco + $(eval $@_TMP := $(shell mktemp -d)) + cp -a coregen.cgp $($@_TMP) + cp -a $< $($@_TMP) + cd $($@_TMP) && $(COREGEN) -p coregen.cgp -b $(notdir $<) + mv $($@_TMP) $@ + +%: %.xaw + $(eval $@_TMP := $(shell mktemp -d)) + cp -a coregen.cgp $($@_TMP) + cp -a $< $($@_TMP) + cd $($@_TMP) && $(XAW2VERILOG) -st $(notdir $<) $(notdir $*) + mv $($@_TMP) $@ diff --git a/example/ML605/fpga_sgmii/coregen/coregen.cgp b/example/ML605/fpga_sgmii/coregen/coregen.cgp new file mode 100644 index 000000000..e9b3f544d --- /dev/null +++ b/example/ML605/fpga_sgmii/coregen/coregen.cgp @@ -0,0 +1,22 @@ +# Date: Wed Jun 21 16:05:33 2017 + +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vlx130t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1156 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -1 +SET verilogsim = true +SET vhdlsim = false +SET workingdirectory = ./tmp/ + +# CRC: 2db0eed3 diff --git a/example/ML605/fpga_sgmii/coregen/gig_eth_pcs_pma_v11_5.xco b/example/ML605/fpga_sgmii/coregen/gig_eth_pcs_pma_v11_5.xco new file mode 100644 index 000000000..efe30f59e --- /dev/null +++ b/example/ML605/fpga_sgmii/coregen/gig_eth_pcs_pma_v11_5.xco @@ -0,0 +1,57 @@ +############################################################## +# +# Xilinx Core Generator version 14.7 +# Date: Wed Jun 21 16:07:22 2017 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:gig_eth_pcs_pma:11.5 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vlx130t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1156 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -1 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Ethernet_1000BASE-X_PCS/PMA_or_SGMII xilinx.com:ip:gig_eth_pcs_pma:11.5 +# END Select +# BEGIN Parameters +CSET auto_negotiation=true +CSET component_name=gig_eth_pcs_pma_v11_5 +CSET enable_1588=false +CSET management_interface=false +CSET physical_interface=Transceiver +CSET sgmii_mode=10_100_1000 +CSET sgmii_phy_mode=false +CSET standard=SGMII +CSET timing_sim=false +CSET transceiver_tile=A +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2012-07-11T07:25:50Z +# END Extra information +GENERATE +# CRC: 7ca270ae diff --git a/example/ML605/fpga_sgmii/fpga.ucf b/example/ML605/fpga_sgmii/fpga.ucf new file mode 100644 index 000000000..e7133e706 --- /dev/null +++ b/example/ML605/fpga_sgmii/fpga.ucf @@ -0,0 +1,94 @@ +# User Constraints File for the Xilinx ML605 board, rev C + +CONFIG PART = xc6vlx130t-1ff1156; + +# 200MHz clock +NET "sys_clk_p" LOC = "J9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0P_GC_34 (GCLK) +NET "sys_clk_n" LOC = "H9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0N_GC_34 (GCLK) +NET "sys_clk_p" TNM_NET = "sys_clk_pin"; +TIMESPEC "TS_sys_clk_pin" = PERIOD "sys_clk_pin" 200000 kHz; + +# Light Emitting Diodes +NET "ledu" LOC = "AH27" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L0P_23 (DS20) +NET "ledl" LOC = "AD21" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 22, IO_L0N_22 (DS17) +NET "ledd" LOC = "AH28" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L0N_23 (DS18) +NET "ledr" LOC = "AE21" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 22, IO_L0P_22 (DS19) +NET "ledc" LOC = "AP24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L19N_23 (DS16) + +NET "led<0>" LOC = "AC22" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L19P_24 (DS12) +NET "led<1>" LOC = "AC24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L18N_24 (DS11) +NET "led<2>" LOC = "AE22" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L17N_VRP_24 (DS9) +NET "led<3>" LOC = "AE23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L17P_VRN_24 (DS10) +NET "led<4>" LOC = "AB23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L16N_CSO_B_24 (DS15) +NET "led<5>" LOC = "AG23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L15N_RS1_24 (DS14) +NET "led<6>" LOC = "AE24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L11N_SRCC_24 (DS22) +NET "led<7>" LOC = "AD24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L11P_SRCC_24 (DS21) + +# Reset Button: I/O Bank 2 +NET "reset" LOC = "H10" | IOSTANDARD=LVCMOS15; # Bank = 35, IO_L6P_SM3P_35 (SW10) + +# Push Buttons: I/O Bank 3 +NET "btnu" LOC = "A19" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L15N_26 (SW5) +NET "btnl" LOC = "H17" | IOSTANDARD=LVCMOS15; # Bank = 36, IO_L3P_36 (SW8) +NET "btnd" LOC = "A18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L15P_26 (SW6) +NET "btnr" LOC = "G17" | IOSTANDARD=LVCMOS15; # Bank = 36, IO_L3N_36 (SW7) +NET "btnc" LOC = "G26" | IOSTANDARD=LVCMOS15; # Bank = 25, IO_L6P_25 (SW9) + +# Toggle Switches +NET "sw<0>" LOC = "D22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L19N_26 (SW1.1) +NET "sw<1>" LOC = "C22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L19P_26 (SW1.2) +NET "sw<2>" LOC = "L21" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L18N_26 (SW1.3) +NET "sw<3>" LOC = "L20" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L18P_26 (SW1.4) +NET "sw<4>" LOC = "C18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L17N_26 (SW1.5) +NET "sw<5>" LOC = "B18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L17P_26 (SW1.6) +NET "sw<6>" LOC = "K22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L16N_26 (SW1.7) +NET "sw<7>" LOC = "K21" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L16P_26 (SW1.8) + +# Marvell M88E1111 Tri-Mode Ethernet PHY (1000BASE-T) +# Interrupt, Reset, MDIO +#NET "phy_int_n" LOC = "AH14" | IOSTANDARD=LVCMOS25; # (E-INT) +NET "phy_reset_n" LOC = "AH13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L18P_33 (E-RESET) +#NET "phy_mdc" LOC = "AP14" | IOSTANDARD=LVCMOS25; # (E-MDC) +#NET "phy_mdio" LOC = "AN14" | IOSTANDARD=LVCMOS25; # (E-MDIO) +# GMII Transmit +#NET "phy_gtx_clk" LOC = "AH12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L16N_33 (E-GTXCLK) +#NET "phy_tx_clk" LOC = "AD12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L10P_MRCC_33 (E-TXCLK) +#NET "phy_txd<0>" LOC = "AM11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L7N_33 (E-TXD0) +#NET "phy_txd<1>" LOC = "AL11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L7P_33 (E-TXD1) +#NET "phy_txd<2>" LOC = "AG10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L6N_33 (E-TXD2) +#NET "phy_txd<3>" LOC = "AG11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L6P_33 (E-TXD3) +#NET "phy_txd<4>" LOC = "AL10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L5N_33 (E-TXD4) +#NET "phy_txd<5>" LOC = "AM10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L5P_33 (E-TXD5) +#NET "phy_txd<6>" LOC = "AE11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L4N_VREF_33 (E-TXD6) +#NET "phy_txd<7>" LOC = "AF11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L4P_33 (E-TXD7) +#NET "phy_tx_en" LOC = "AJ10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L8P_SRCC_33 (E-TXEN) +#NET "phy_tx_er" LOC = "AH10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L8N_SRCC_33 (E-TXER) +# GMII Receive +#NET "phy_rx_clk" LOC = "AP11" | IOSTANDARD=LVCMOS25 | TNM_NET = "clk_rx_local"; # (E-RXCLK) +#NET "phy_rxd<0>" LOC = "AN13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L15P_33 (E-RXD0) +#NET "phy_rxd<1>" LOC = "AF14" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L14N_VREF_33 (E-RXD1) +#NET "phy_rxd<2>" LOC = "AE14" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L14P_33 (E-RXD2) +#NET "phy_rxd<3>" LOC = "AN12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L13N_33 (E-RXD3) +#NET "phy_rxd<4>" LOC = "AM12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L13P_33 (E-RXD4) +#NET "phy_rxd<5>" LOC = "AD11" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L10N_MRCC_33 (E-RXD5) +#NET "phy_rxd<6>" LOC = "AC12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L9N_MRCC_33 (E-RXD6) +#NET "phy_rxd<7>" LOC = "AC13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L9P_MRCC_33 (E-RXD7) +#NET "phy_rx_dv" LOC = "AM13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L15N_33 (E-RXDV) +#NET "phy_rx_er" LOC = "AG12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L16P_33 (E-RXER) +# SGMII interface +NET "phy_sgmii_rx_p" LOC = "B5"; +NET "phy_sgmii_rx_n" LOC = "B6"; +NET "phy_sgmii_tx_p" LOC = "A3"; +NET "phy_sgmii_tx_n" LOC = "A4"; +NET "phy_sgmii_clk_p" LOC = "H6" | TNM_NET = "sgmii_mgtrefclk"; +NET "phy_sgmii_clk_n" LOC = "H5"; + +# Timing constraints for Ethernet PHY +#TIMESPEC "TS_rx_clk_root" = PERIOD "clk_rx_local" 8000 ps HIGH 50 %; +TIMESPEC "TS_mgtrefclk" = PERIOD "sgmii_mgtrefclk" 8 ns HIGH 50 %; + +# Silicon Labs CP2103 +NET "uart_rxd" LOC = "J25" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L9P_MRCC_24 (U24.24) +NET "uart_txd" LOC = "J24" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L9N_MRCC_24 (U24.25) +NET "uart_rts" LOC = "T23" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L8N_SRCC_24 (U24.23) +NET "uart_cts" LOC = "T24" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L8P_SRCC_24 (U24.22) diff --git a/example/ML605/fpga_sgmii/fpga/Makefile b/example/ML605/fpga_sgmii/fpga/Makefile new file mode 100644 index 000000000..dc4fb229e --- /dev/null +++ b/example/ML605/fpga_sgmii/fpga/Makefile @@ -0,0 +1,81 @@ + +# FPGA settings +FPGA_PART = xc6vlx130t-1ff1156 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v +SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v +SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_clk_gen.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_johnson_cntr.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_rx_rate_adapt.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_sgmii_adapt.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_tx_rate_adapt.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_double_reset.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_gtwizard_gtrxreset_seq.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_rx_elastic_buffer.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_v6_gtxwizard.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_v6_gtxwizard_gtx.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_v6_gtxwizard_top.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/gig_eth_pcs_pma_v11_5_block.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/gig_eth_pcs_pma_v11_5_reset_sync.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/gig_eth_pcs_pma_v11_5_sync_block.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5.v + +# UCF files +UCF_FILES = fpga.ucf +UCF_FILES += clock.ucf + +# NGC paths for ngdbuild +NGC_PATHS = coregen/gig_eth_pcs_pma_v11_5 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 2 -file $(FPGA_TOP).bit" >> program.cmd + echo "program -p 2" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + diff --git a/example/ML605/fpga_sgmii/lib/eth b/example/ML605/fpga_sgmii/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/ML605/fpga_sgmii/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/ML605/fpga_sgmii/rtl/debounce_switch.v b/example/ML605/fpga_sgmii/rtl/debounce_switch.v new file mode 100644 index 000000000..ab84126ec --- /dev/null +++ b/example/ML605/fpga_sgmii/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/ML605/fpga_sgmii/rtl/fpga.v b/example/ML605/fpga_sgmii/rtl/fpga.v new file mode 100644 index 000000000..ced6a431c --- /dev/null +++ b/example/ML605/fpga_sgmii/rtl/fpga.v @@ -0,0 +1,398 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 200MHz + * Reset: Push button, active high + */ + input wire sys_clk_p, + input wire sys_clk_n, + input wire reset, + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire ledu, + output wire ledl, + output wire ledd, + output wire ledr, + output wire ledc, + output wire [7:0] led, + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_sgmii_rx_p, + input wire phy_sgmii_rx_n, + output wire phy_sgmii_tx_p, + output wire phy_sgmii_tx_n, + input wire phy_sgmii_clk_p, + input wire phy_sgmii_clk_n, + output wire phy_reset_n, + /* + * Silicon Labs CP2103 USB UART + */ + output wire uart_rxd, + input wire uart_txd, + input wire uart_rts, + output wire uart_cts +); + +// Clock and reset + +wire sys_clk_ibufg; +wire sys_clk_bufg; +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +wire mmcm_rst = reset; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS +clk_ibufgds_inst( + .I(sys_clk_p), + .IB(sys_clk_n), + .O(sys_clk_ibufg) +); + +// MMCM instance +// 200 MHz in, 125 MHz out +// PFD range: 10 MHz to 450 MHz +// VCO range: 600 MHz to 1200 MHz +// M = 5, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCM_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(5), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.100), + .CLKIN1_PERIOD(5.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(sys_clk_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [7:0] sw_int; + +wire ledu_int; +wire ledl_int; +wire ledd_int; +wire ledr_int; +wire ledc_int; +wire [7:0] led_int; + +wire uart_rxd_int; +wire uart_txd_int; +wire uart_rts_int; +wire uart_cts_int; + +debounce_switch #( + .WIDTH(13), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(clk_125mhz_int), + .in({uart_txd, + uart_rts}), + .out({uart_txd_int, + uart_rts_int}) +); + +assign ledu = ledu_int; +assign ledl = ledl_int; +assign ledd = ledd_int; +assign ledr = ledr_int; +assign ledc = ledc_int; +//assign led = led_int; + +assign uart_rxd = uart_rxd_int; +assign uart_cts = uart_cts_int; + +// SGMII interface to PHY +wire phy_gmii_clk_int; +wire phy_gmii_rst_int; +wire phy_gmii_clk_en_int; +wire [7:0] phy_gmii_txd_int; +wire phy_gmii_tx_en_int; +wire phy_gmii_tx_er_int; +wire [7:0] phy_gmii_rxd_int; +wire phy_gmii_rx_dv_int; +wire phy_gmii_rx_er_int; + +wire phy_sgmii_mgtrefclk; +wire phy_sgmii_txoutclk; +wire phy_sgmii_userclk2; + +IBUFDS_GTXE1 +phy_sgmii_ibufds_mgtrefclk ( + .CEB (1'b0), + .I (phy_sgmii_clk_p), + .IB (phy_sgmii_clk_n), + .O (phy_sgmii_mgtrefclk), + .ODIV2 () +); + +BUFG +phy_sgmii_bufg_userclk2 ( + .I (phy_sgmii_txoutclk), + .O (phy_sgmii_userclk2) +); + +assign phy_gmii_clk_int = phy_sgmii_userclk2; + +sync_reset #( + .N(4) +) +sync_reset_pcspma_inst ( + .clk(phy_gmii_clk_int), + .rst(rst_125mhz_int), + .sync_reset_out(phy_gmii_rst_int) +); + +wire [15:0] pcspma_status_vector; + +wire pcspma_status_link_status = pcspma_status_vector[0]; +wire pcspma_status_link_synchronization = pcspma_status_vector[1]; +wire pcspma_status_rudi_c = pcspma_status_vector[2]; +wire pcspma_status_rudi_i = pcspma_status_vector[3]; +wire pcspma_status_rudi_invalid = pcspma_status_vector[4]; +wire pcspma_status_rxdisperr = pcspma_status_vector[5]; +wire pcspma_status_rxnotintable = pcspma_status_vector[6]; +wire pcspma_status_phy_link_status = pcspma_status_vector[7]; +wire [1:0] pcspma_status_remote_fault_encdg = pcspma_status_vector[9:8]; +wire [1:0] pcspma_status_speed = pcspma_status_vector[11:10]; +wire pcspma_status_duplex = pcspma_status_vector[12]; +wire pcspma_status_remote_fault = pcspma_status_vector[13]; +wire [1:0] pcspma_status_pause = pcspma_status_vector[15:14]; + +wire [4:0] pcspma_config_vector; + +assign pcspma_config_vector[4] = 1'b1; // autonegotiation enable +assign pcspma_config_vector[3] = 1'b0; // isolate +assign pcspma_config_vector[2] = 1'b0; // power down +assign pcspma_config_vector[1] = 1'b0; // loopback enable +assign pcspma_config_vector[0] = 1'b0; // unidirectional enable + +wire [15:0] pcspma_an_config_vector; + +assign pcspma_an_config_vector[15] = 1'b1; // SGMII link status +assign pcspma_an_config_vector[14] = 1'b1; // SGMII Acknowledge +assign pcspma_an_config_vector[13:12] = 2'b01; // full duplex +assign pcspma_an_config_vector[11:10] = 2'b10; // SGMII speed +assign pcspma_an_config_vector[9] = 1'b0; // reserved +assign pcspma_an_config_vector[8:7] = 2'b00; // pause frames - SGMII reserved +assign pcspma_an_config_vector[6] = 1'b0; // reserved +assign pcspma_an_config_vector[5] = 1'b0; // full duplex - SGMII reserved +assign pcspma_an_config_vector[4:1] = 4'b0000; // reserved +assign pcspma_an_config_vector[0] = 1'b1; // SGMII + +gig_eth_pcs_pma_v11_5_block +eth_pcspma ( + // Transceiver Interface + .mgtrefclk (phy_sgmii_mgtrefclk), + .gtx_reset_clk (clk_125mhz_int), + .txp (phy_sgmii_tx_p), + .txn (phy_sgmii_tx_n), + .rxp (phy_sgmii_rx_p), + .rxn (phy_sgmii_rx_n), + .txoutclk (phy_sgmii_txoutclk), + .userclk2 (phy_sgmii_userclk2), + .pma_reset (rst_125mhz_int), + // GMII Interface + .sgmii_clk_r (), + .sgmii_clk_f (), + .sgmii_clk_en (phy_gmii_clk_en_int), + .gmii_txd (phy_gmii_txd_int), + .gmii_tx_en (phy_gmii_tx_en_int), + .gmii_tx_er (phy_gmii_tx_er_int), + .gmii_rxd (phy_gmii_rxd_int), + .gmii_rx_dv (phy_gmii_rx_dv_int), + .gmii_rx_er (phy_gmii_rx_er_int), + .gmii_isolate (), + // Management: Alternative to MDIO Interface + .configuration_vector (pcspma_config_vector), + .an_interrupt (), + .an_adv_config_vector (pcspma_an_config_vector), + .an_restart_config (1'b0), + .link_timer_value (9'd50), + // Speed Control + .speed_is_10_100 (pcspma_status_speed != 2'b10), + .speed_is_100 (pcspma_status_speed == 2'b01), + // General IO's + .status_vector (pcspma_status_vector), + .reset (rst_125mhz_int), + .signal_detect (1'b1) +); + +// SGMII interface debug: +// SW1:1 (sw[0]) off for payload byte, on for status vector +// SW1:2 (sw[1]) off for LSB of status vector, on for MSB +assign led = sw[7] ? (sw[6] ? pcspma_status_vector[15:8] : pcspma_status_vector[7:0]) : led_int; + +fpga_core +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk_125mhz(clk_125mhz_int), + .rst_125mhz(rst_125mhz_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .ledu(ledu_int), + .ledl(ledl_int), + .ledd(ledd_int), + .ledr(ledr_int), + .ledc(ledc_int), + .led(led_int), + /* + * Ethernet: 1000BASE-T SGMII + */ + .phy_gmii_clk(phy_gmii_clk_int), + .phy_gmii_rst(phy_gmii_rst_int), + .phy_gmii_clk_en(phy_gmii_clk_en_int), + .phy_gmii_rxd(phy_gmii_rxd_int), + .phy_gmii_rx_dv(phy_gmii_rx_dv_int), + .phy_gmii_rx_er(phy_gmii_rx_er_int), + .phy_gmii_txd(phy_gmii_txd_int), + .phy_gmii_tx_en(phy_gmii_tx_en_int), + .phy_gmii_tx_er(phy_gmii_tx_er_int), + .phy_reset_n(phy_reset_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd_int), + .uart_rts(uart_rts_int), + .uart_cts(uart_cts_int) +); + +endmodule diff --git a/example/ML605/fpga_sgmii/rtl/fpga_core.v b/example/ML605/fpga_sgmii/rtl/fpga_core.v new file mode 100644 index 000000000..9c3ff482c --- /dev/null +++ b/example/ML605/fpga_sgmii/rtl/fpga_core.v @@ -0,0 +1,579 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * FPGA core logic + */ +module fpga_core +( + /* + * Clock: 125MHz + * Synchronous reset + */ + input wire clk_125mhz, + input wire rst_125mhz, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire ledu, + output wire ledl, + output wire ledd, + output wire ledr, + output wire ledc, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_gmii_clk, + input wire phy_gmii_rst, + input wire phy_gmii_clk_en, + input wire [7:0] phy_gmii_rxd, + input wire phy_gmii_rx_dv, + input wire phy_gmii_rx_er, + output wire [7:0] phy_gmii_txd, + output wire phy_gmii_tx_en, + output wire phy_gmii_tx_er, + output wire phy_reset_n, + + /* + * Silicon Labs CP2103 USB UART + */ + output wire uart_rxd, + input wire uart_txd, + input wire uart_rts, + output wire uart_cts +); + +// AXI between MAC and Ethernet modules +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [7:0] tx_axis_tdata; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [7:0] rx_eth_payload_tdata; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [7:0] tx_eth_payload_tdata; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [7:0] rx_ip_payload_tdata; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [7:0] tx_ip_payload_tdata; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [7:0] rx_udp_payload_tdata; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_tdata; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [7:0] rx_fifo_udp_payload_tdata; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [7:0] tx_fifo_udp_payload_tdata; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk_125mhz) begin + if (rst_125mhz) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk_125mhz) begin + if (rst_125mhz) begin + led_reg <= 0; + end else begin + if (tx_udp_payload_tvalid) begin + if (~valid_last) begin + led_reg <= tx_udp_payload_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_tlast) begin + valid_last <= 1'b0; + end + end + end +end + +//assign led = sw; +assign ledu = 0; +assign ledl = 0; +assign ledd = 0; +assign ledr = 0; +assign ledc = 0; +assign led = led_reg; +assign phy_reset_n = ~rst_125mhz; + +assign uart_rxd = 0; +assign uart_cts = 0; + +eth_mac_1g_fifo #( + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .RX_FIFO_ADDR_WIDTH(12) +) +eth_mac_inst ( + .rx_clk(phy_gmii_clk), + .rx_rst(phy_gmii_rst), + .tx_clk(phy_gmii_clk), + .tx_rst(phy_gmii_rst), + .logic_clk(clk_125mhz), + .logic_rst(rst_125mhz), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .gmii_rxd(phy_gmii_rxd), + .gmii_rx_dv(phy_gmii_rx_dv), + .gmii_rx_er(phy_gmii_rx_er), + .gmii_txd(phy_gmii_txd), + .gmii_tx_en(phy_gmii_tx_en), + .gmii_tx_er(phy_gmii_tx_er), + + .rx_clk_enable(phy_gmii_clk_en), + .tx_clk_enable(phy_gmii_clk_en), + .rx_mii_select(1'b0), + .tx_mii_select(1'b0), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + .ifg_delay(12) +); + +eth_axis_rx +eth_axis_rx_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx +eth_axis_tx_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete +udp_complete_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(0) +); + +axis_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8) +) +udp_payload_fifo ( + .clk(clk_125mhz), + .rst(rst_125mhz), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/ML605/fpga_sgmii/rtl/sync_reset.v b/example/ML605/fpga_sgmii/rtl/sync_reset.v new file mode 100644 index 000000000..558a67605 --- /dev/null +++ b/example/ML605/fpga_sgmii/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/ML605/fpga_sgmii/rtl/sync_signal.v b/example/ML605/fpga_sgmii/rtl/sync_signal.v new file mode 100644 index 000000000..1b8a32328 --- /dev/null +++ b/example/ML605/fpga_sgmii/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2017 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/ML605/fpga_sgmii/tb/arp_ep.py b/example/ML605/fpga_sgmii/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/ML605/fpga_sgmii/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_sgmii/tb/axis_ep.py b/example/ML605/fpga_sgmii/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/ML605/fpga_sgmii/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_sgmii/tb/eth_ep.py b/example/ML605/fpga_sgmii/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/ML605/fpga_sgmii/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_sgmii/tb/gmii_ep.py b/example/ML605/fpga_sgmii/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/ML605/fpga_sgmii/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_sgmii/tb/ip_ep.py b/example/ML605/fpga_sgmii/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/ML605/fpga_sgmii/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/ML605/fpga_sgmii/tb/test_fpga_core.py b/example/ML605/fpga_sgmii/tb/test_fpga_core.py new file mode 100755 index 000000000..ba19006bd --- /dev/null +++ b/example/ML605/fpga_sgmii/tb/test_fpga_core.py @@ -0,0 +1,328 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import eth_ep +import arp_ep +import udp_ep +import gmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen.v") +srcs.append("../lib/eth/rtl/udp.v") +srcs.append("../lib/eth/rtl/udp_ip_rx.v") +srcs.append("../lib/eth/rtl/udp_ip_tx.v") +srcs.append("../lib/eth/rtl/ip_complete.v") +srcs.append("../lib/eth/rtl/ip.v") +srcs.append("../lib/eth/rtl/ip_eth_rx.v") +srcs.append("../lib/eth/rtl/ip_eth_tx.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") +srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") +srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + clk_125mhz = Signal(bool(0)) + rst_125mhz = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[8:]) + phy_gmii_clk = Signal(bool(0)) + phy_gmii_rst = Signal(bool(0)) + phy_gmii_clk_en = Signal(bool(0)) + phy_gmii_rxd = Signal(intbv(0)[8:]) + phy_gmii_rx_dv = Signal(bool(0)) + phy_gmii_rx_er = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + + # Outputs + ledu = Signal(bool(0)) + ledl = Signal(bool(0)) + ledd = Signal(bool(0)) + ledr = Signal(bool(0)) + ledc = Signal(bool(0)) + led = Signal(intbv(0)[8:]) + phy_gmii_txd = Signal(intbv(0)[8:]) + phy_gmii_tx_en = Signal(bool(0)) + phy_gmii_tx_er = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_rxd = Signal(bool(0)) + uart_cts = Signal(bool(0)) + + # sources and sinks + gmii_source = gmii_ep.GMIISource() + + gmii_source_logic = gmii_source.create_logic( + phy_gmii_clk, + phy_gmii_rst, + txd=phy_gmii_rxd, + tx_en=phy_gmii_rx_dv, + tx_er=phy_gmii_rx_er, + clk_enable=phy_gmii_clk_en, + name='gmii_source' + ) + + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + phy_gmii_clk, + phy_gmii_rst, + rxd=phy_gmii_txd, + rx_dv=phy_gmii_tx_en, + rx_er=phy_gmii_tx_er, + clk_enable=phy_gmii_clk_en, + name='gmii_sink' + ) + + # DUT + if os.system(build_cmd): + raise Exception("Error running build command") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk_125mhz=clk_125mhz, + rst_125mhz=rst_125mhz, + current_test=current_test, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + ledu=ledu, + ledl=ledl, + ledd=ledd, + ledr=ledr, + ledc=ledc, + led=led, + + phy_gmii_clk=phy_gmii_clk, + phy_gmii_rst=phy_gmii_rst, + phy_gmii_clk_en=phy_gmii_clk_en, + phy_gmii_rxd=phy_gmii_rxd, + phy_gmii_rx_dv=phy_gmii_rx_dv, + phy_gmii_rx_er=phy_gmii_rx_er, + phy_gmii_txd=phy_gmii_txd, + phy_gmii_tx_en=phy_gmii_tx_en, + phy_gmii_tx_er=phy_gmii_tx_er, + phy_reset_n=phy_reset_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + clk_125mhz.next = not clk_125mhz + phy_gmii_clk.next = not phy_gmii_clk + + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @always(clk.posedge) + def clk_enable_gen(): + if clk_enable_div.next > 0: + phy_gmii_clk_en.next = 0 + clk_enable_div.next = clk_enable_div - 1 + else: + phy_gmii_clk_en.next = 1 + clk_enable_div.next = clk_enable_rate - 1 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + rst_125mhz.next = 1 + phy_gmii_rst.next = 1 + yield clk.posedge + rst.next = 0 + rst_125mhz.next = 0 + phy_gmii_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source.empty() + assert gmii_sink.empty() + + yield delay(100) + + raise StopSimulation + + return dut, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/ML605/fpga_sgmii/tb/test_fpga_core.v b/example/ML605/fpga_sgmii/tb/test_fpga_core.v new file mode 100644 index 000000000..b354d4c59 --- /dev/null +++ b/example/ML605/fpga_sgmii/tb/test_fpga_core.v @@ -0,0 +1,143 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk_125mhz = 0; +reg rst_125mhz = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [7:0] sw = 0; +reg phy_gmii_clk = 0; +reg phy_gmii_rst = 0; +reg phy_gmii_clk_en = 0; +reg [7:0] phy_gmii_rxd = 0; +reg phy_gmii_rx_dv = 0; +reg phy_gmii_rx_er = 0; +reg uart_txd = 0; +reg uart_rts = 0; + +// Outputs +wire ledu; +wire ledl; +wire ledd; +wire ledr; +wire ledc; +wire [7:0] led; +wire [7:0] phy_gmii_txd; +wire phy_gmii_tx_en; +wire phy_gmii_tx_er; +wire phy_reset_n; +wire uart_rxd; +wire uart_cts; + +initial begin + // myhdl integration + $from_myhdl( + clk_125mhz, + rst_125mhz, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_clk_en, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + uart_txd, + uart_rts + ); + $to_myhdl( + ledu, + ledl, + ledd, + ledr, + ledc, + led, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + uart_rxd, + uart_cts + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk_125mhz(clk_125mhz), + .rst_125mhz(rst_125mhz), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .ledu(ledu), + .ledl(ledl), + .ledd(ledd), + .ledr(ledr), + .ledc(ledc), + .led(led), + .phy_gmii_clk(phy_gmii_clk), + .phy_gmii_rst(phy_gmii_rst), + .phy_gmii_clk_en(phy_gmii_clk_en), + .phy_gmii_rxd(phy_gmii_rxd), + .phy_gmii_rx_dv(phy_gmii_rx_dv), + .phy_gmii_rx_er(phy_gmii_rx_er), + .phy_gmii_txd(phy_gmii_txd), + .phy_gmii_tx_en(phy_gmii_tx_en), + .phy_gmii_tx_er(phy_gmii_tx_er), + .phy_reset_n(phy_reset_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts) +); + +endmodule diff --git a/example/ML605/fpga_sgmii/tb/udp_ep.py b/example/ML605/fpga_sgmii/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/ML605/fpga_sgmii/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file From 7dc58e5d4954a5607ddddf442e921d4996d0be98 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 12 Nov 2017 18:17:33 -0800 Subject: [PATCH 343/617] Add tid signal to axis_ep --- tb/axis_ep.py | 75 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 19 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 56d0a6bee..9a3de3d83 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -27,19 +27,21 @@ from myhdl import * skip_asserts = False class AXIStreamFrame(object): - def __init__(self, data=b'', keep=None, dest=None, user=None): + def __init__(self, data=b'', keep=None, id=None, dest=None, user=None): self.B = 0 self.N = 8 self.M = 1 self.WL = 8 self.data = b'' self.keep = None + self.id = 0 self.dest = 0 self.user = None if type(data) is bytes or type(data) is bytearray: self.data = bytearray(data) self.keep = keep + self.id = id self.dest = dest self.user = user elif type(data) is AXIStreamFrame: @@ -51,6 +53,11 @@ class AXIStreamFrame(object): self.data = list(data.data) if data.keep is not None: self.keep = list(data.keep) + if data.id is not None: + if type(data.id) is int: + self.id = data.id + else: + self.id = list(data.id) if data.dest is not None: if type(data.dest) is int: self.dest = data.dest @@ -64,6 +71,7 @@ class AXIStreamFrame(object): else: self.data = list(data) self.keep = keep + self.id = id self.dest = dest self.user = user @@ -74,15 +82,11 @@ class AXIStreamFrame(object): f = list(self.data) tdata = [] tkeep = [] + tid = [] tdest = [] tuser = [] i = 0 - dest = 0 - if type(self.dest) is int: - dest = self.dest - self.dest = None - assert_tuser = False if (type(self.user) is int or type(self.user) is bool) and self.user: assert_tuser = True @@ -97,14 +101,26 @@ class AXIStreamFrame(object): keep = keep | (1 << j) if len(f) == 0: break tdata.append(data) + if self.keep is None: tkeep.append(keep) else: tkeep.append(self.keep[i]) + + if self.id is None: + tid.append(0) + elif type(self.id) is int: + tid.append(self.id) + else: + tid.append(self.id[i]) + if self.dest is None: - tdest.append(dest) + tdest.append(0) + elif type(self.dest) is int: + tdest.append(self.dest) else: tdest.append(self.dest[i]) + if self.user is None: tuser.append(0) else: @@ -116,10 +132,21 @@ class AXIStreamFrame(object): data = 0 tdata.append(f.pop(0)) tkeep.append(0) + + if self.id is None: + tid.append(0) + elif type(self.id) is int: + tid.append(self.id) + else: + tid.append(self.id[i]) + if self.dest is None: - tdest.append(dest) + tdest.append(0) + elif type(self.dest) is int: + tdest.append(self.dest) else: tdest.append(self.dest[i]) + if self.user is None: tuser.append(0) else: @@ -130,19 +157,17 @@ class AXIStreamFrame(object): tuser[-1] = 1 self.user = 1 - if self.dest == None: - self.dest = dest + return tdata, tkeep, tid, tdest, tuser - return tdata, tkeep, tdest, tuser - - def parse(self, tdata, tkeep, tdest, tuser): + def parse(self, tdata, tkeep, tid, tdest, tuser): if tdata is None or tkeep is None or tuser is None: return - if len(tdata) != len(tkeep) or len(tdata) != len(tdest) or len(tdata) != len(tuser): + if len(tdata) != len(tkeep) or len(tdata) != len(tid) or len(tdata) != len(tdest) or len(tdata) != len(tuser): raise Exception("Invalid data") self.data = [] self.keep = [] + self.id = [] self.dest = [] self.user = [] @@ -154,12 +179,14 @@ class AXIStreamFrame(object): if tkeep[i] & (1 << j): self.data.append((tdata[i] >> (j*self.WL)) & mask) self.keep.append(tkeep[i]) + self.id.append(tid[i]) self.dest.append(tdest[i]) self.user.append(tuser[i]) else: for i in range(len(tdata)): self.data.append(tdata[i]) self.keep.append(tkeep[i]) + self.id.append(tid[i]) self.dest.append(tdest[i]) self.user.append(tuser[i]) @@ -172,7 +199,7 @@ class AXIStreamFrame(object): return False def __repr__(self): - return 'AXIStreamFrame(data=%s, keep=%s, dest=%s, user=%s)' % (repr(self.data), repr(self.keep), repr(self.dest), repr(self.user)) + return 'AXIStreamFrame(data=%s, keep=%s, id=%s, dest=%s, user=%s)' % (repr(self.data), repr(self.keep), repr(self.id), repr(self.dest), repr(self.user)) def __iter__(self): return self.data.__iter__() @@ -203,8 +230,9 @@ class AXIStreamSource(object): tvalid=Signal(bool(False)), tready=Signal(bool(True)), tlast=Signal(bool(False)), + tid=Signal(intbv(0)), tdest=Signal(intbv(0)), - tuser=Signal(bool(False)), + tuser=Signal(intbv(0)), pause=0, name=None ): @@ -226,6 +254,7 @@ class AXIStreamSource(object): frame = AXIStreamFrame() data = [] keep = [] + id = [] dest = [] user = [] B = 0 @@ -250,6 +279,7 @@ class AXIStreamSource(object): else: tdata.next = 0 tkeep.next = 0 + tid.next = 0 tdest.next = 0 tuser.next = False tvalid_int.next = False @@ -264,6 +294,7 @@ class AXIStreamSource(object): else: tdata.next = data.pop(0) tkeep.next = keep.pop(0) + tid.next = id.pop(0) tdest.next = dest.pop(0) tuser.next = user.pop(0) tvalid_int.next = True @@ -278,7 +309,7 @@ class AXIStreamSource(object): frame.N = N frame.M = M frame.WL = WL - data, keep, dest, user = frame.build() + data, keep, id, dest, user = frame.build() if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) if B > 0: @@ -288,6 +319,7 @@ class AXIStreamSource(object): else: tdata.next = data.pop(0) tkeep.next = keep.pop(0) + tid.next = id.pop(0) tdest.next = dest.pop(0) tuser.next = user.pop(0) tvalid_int.next = True @@ -330,8 +362,9 @@ class AXIStreamSink(object): tvalid=Signal(bool(False)), tready=Signal(bool(True)), tlast=Signal(bool(True)), + tid=Signal(intbv(0)), tdest=Signal(intbv(0)), - tuser=Signal(bool(False)), + tuser=Signal(intbv(0)), pause=0, name=None ): @@ -353,6 +386,7 @@ class AXIStreamSink(object): frame = AXIStreamFrame() data = [] keep = [] + id = [] dest = [] user = [] B = 0 @@ -376,6 +410,7 @@ class AXIStreamSink(object): frame = AXIStreamFrame() data = [] keep = [] + id = [] dest = [] user = [] first = True @@ -411,6 +446,7 @@ class AXIStreamSink(object): else: data.append(int(tdata)) keep.append(int(tkeep)) + id.append(int(tid)) dest.append(int(tdest)) user.append(int(tuser)) first = False @@ -419,13 +455,14 @@ class AXIStreamSink(object): frame.N = N frame.M = M frame.WL = WL - frame.parse(data, keep, dest, user) + frame.parse(data, keep, id, dest, user) self.queue.append(frame) if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) frame = AXIStreamFrame() data = [] keep = [] + id = [] dest = [] user = [] first = True From a35d1a8e7c815df66f55ef0de730a8d24a77c4d2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 12 Nov 2017 18:22:41 -0800 Subject: [PATCH 344/617] Fix CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 394066aff..31d28f7ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ before_install: - sudo apt-get install -y iverilog - git clone https://github.com/jandecaluwe/myhdl.git - cd $d/myhdl && sudo $PYTHON_EXE 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/i386-linux-gnu/ivl/myhdl.vpi - cd $d script: - cd tb && py.test From a51109c7c49ee47c45895f18b016713a7c07b56a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 12 Nov 2017 18:30:08 -0800 Subject: [PATCH 345/617] Use latest python --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 31d28f7ac..d7a6f04e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: python python: - - "3.4" + - "3.6" before_install: - export d=`pwd` - export PYTHON_EXE=`which python` From cb2221b39bae60cc253838319b3951d7ff96e194 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 12 Nov 2017 18:36:15 -0800 Subject: [PATCH 346/617] Use correct path --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d7a6f04e5..15f9a3c31 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ before_install: - sudo apt-get install -y iverilog - git clone https://github.com/jandecaluwe/myhdl.git - cd $d/myhdl && sudo $PYTHON_EXE setup.py install - - cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/i386-linux-gnu/ivl/myhdl.vpi + - cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/x86_64-linux-gnu/ivl/myhdl.vpi - cd $d script: - cd tb && py.test From c9cc9006a3ec1b1d5f61550af705335b02d3cf7c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 15:43:32 -0800 Subject: [PATCH 347/617] Add last_cycle_user parameter to axis_ep --- tb/axis_ep.py | 98 ++++++++++++++++++++++----------------------------- 1 file changed, 43 insertions(+), 55 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 9a3de3d83..72c329008 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -27,7 +27,7 @@ from myhdl import * skip_asserts = False class AXIStreamFrame(object): - def __init__(self, data=b'', keep=None, id=None, dest=None, user=None): + def __init__(self, data=b'', keep=None, id=None, dest=None, user=None, last_cycle_user=None): self.B = 0 self.N = 8 self.M = 1 @@ -37,6 +37,7 @@ class AXIStreamFrame(object): self.id = 0 self.dest = 0 self.user = None + self.last_cycle_user = None if type(data) is bytes or type(data) is bytearray: self.data = bytearray(data) @@ -44,6 +45,7 @@ class AXIStreamFrame(object): self.id = id self.dest = dest self.user = user + self.last_cycle_user = last_cycle_user elif type(data) is AXIStreamFrame: self.N = data.N self.WL = data.WL @@ -68,12 +70,14 @@ class AXIStreamFrame(object): self.user = data.user else: self.user = list(data.user) + self.last_cycle_user = data.last_cycle_user else: self.data = list(data) self.keep = keep self.id = id self.dest = dest self.user = user + self.last_cycle_user = last_cycle_user def build(self): if self.data is None: @@ -87,13 +91,8 @@ class AXIStreamFrame(object): tuser = [] i = 0 - assert_tuser = False - if (type(self.user) is int or type(self.user) is bool) and self.user: - assert_tuser = True - self.user = None - - if self.B == 0: - while len(f) > 0: + while len(f) > 0: + if self.B == 0: data = 0 keep = 0 for j in range(self.M): @@ -106,56 +105,36 @@ class AXIStreamFrame(object): tkeep.append(keep) else: tkeep.append(self.keep[i]) - - if self.id is None: - tid.append(0) - elif type(self.id) is int: - tid.append(self.id) - else: - tid.append(self.id[i]) - - if self.dest is None: - tdest.append(0) - elif type(self.dest) is int: - tdest.append(self.dest) - else: - tdest.append(self.dest[i]) - - if self.user is None: - tuser.append(0) - else: - tuser.append(self.user[i]) - i += 1 - else: - # multiple tdata signals - while len(f) > 0: + else: + # multiple tdata signals data = 0 tdata.append(f.pop(0)) tkeep.append(0) - - if self.id is None: - tid.append(0) - elif type(self.id) is int: - tid.append(self.id) - else: - tid.append(self.id[i]) - - if self.dest is None: - tdest.append(0) - elif type(self.dest) is int: - tdest.append(self.dest) - else: - tdest.append(self.dest[i]) - - if self.user is None: - tuser.append(0) - else: - tuser.append(self.user[i]) - i += 1 - if assert_tuser: - tuser[-1] = 1 - self.user = 1 + if self.id is None: + tid.append(0) + elif type(self.id) is int: + tid.append(self.id) + else: + tid.append(self.id[i]) + + if self.dest is None: + tdest.append(0) + elif type(self.dest) is int: + tdest.append(self.dest) + else: + tdest.append(self.dest[i]) + + if self.user is None: + tuser.append(0) + elif type(self.user) is int: + tuser.append(self.user) + else: + tuser.append(self.user[i]) + i += 1 + + if self.last_cycle_user: + tuser[-1] = self.last_cycle_user return tdata, tkeep, tid, tdest, tuser @@ -193,13 +172,22 @@ class AXIStreamFrame(object): if self.WL == 8: self.data = bytearray(self.data) + self.last_cycle_user = self.user[-1] + def __eq__(self, other): if type(other) is AXIStreamFrame: return self.data == other.data return False def __repr__(self): - return 'AXIStreamFrame(data=%s, keep=%s, id=%s, dest=%s, user=%s)' % (repr(self.data), repr(self.keep), repr(self.id), repr(self.dest), repr(self.user)) + return ( + ('AXIStreamFrame(data=%s, ' % repr(self.data)) + + ('keep=%s, ' % repr(self.keep)) + + ('id=%s, ' % repr(self.id)) + + ('dest=%s, ' % repr(self.dest)) + + ('user=%s, ' % repr(self.user)) + + ('last_cycle_user=%s)' % repr(self.last_cycle_user)) + ) def __iter__(self): return self.data.__iter__() From a0b21db7464293fcac204338174f9b21773a93fe Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 15:43:54 -0800 Subject: [PATCH 348/617] Improve checks in axis_ep --- tb/axis_ep.py | 67 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 72c329008..00eaa25e3 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -39,7 +39,7 @@ class AXIStreamFrame(object): self.user = None self.last_cycle_user = None - if type(data) is bytes or type(data) is bytearray: + if type(data) in (bytes, bytearray): self.data = bytearray(data) self.keep = keep self.id = id @@ -56,17 +56,17 @@ class AXIStreamFrame(object): if data.keep is not None: self.keep = list(data.keep) if data.id is not None: - if type(data.id) is int: + if type(data.id) in (int, bool): self.id = data.id else: self.id = list(data.id) if data.dest is not None: - if type(data.dest) is int: + if type(data.dest) in (int, bool): self.dest = data.dest else: self.dest = list(data.dest) if data.user is not None: - if type(data.user) is int or type(data.user) is bool: + if type(data.user) in (int, bool): self.user = data.user else: self.user = list(data.user) @@ -175,9 +175,62 @@ class AXIStreamFrame(object): self.last_cycle_user = self.user[-1] def __eq__(self, other): - if type(other) is AXIStreamFrame: - return self.data == other.data - return False + if not isinstance(other, AXIStreamFrame): + return False + if self.data != other.data: + return False + if self.keep is not None and other.keep is not None: + if self.keep != other.keep: + return False + if self.id is not None and other.id is not None: + if type(self.id) in (int, bool) and type(other.id) is list: + for k in other.id: + if self.id != k: + return False + elif type(other.id) in (int, bool) and type(self.id) is list: + for k in self.id: + if other.id != k: + return False + elif self.id != other.id: + return False + if self.dest is not None and other.dest is not None: + if type(self.dest) in (int, bool) and type(other.dest) is list: + for k in other.dest: + if self.dest != k: + return False + elif type(other.dest) in (int, bool) and type(self.dest) is list: + for k in self.dest: + if other.dest != k: + return False + elif self.dest != other.dest: + return False + if self.last_cycle_user is not None and other.last_cycle_user is not None: + if self.last_cycle_user != other.last_cycle_user: + return False + if self.user is not None and other.user is not None: + if type(self.user) in (int, bool) and type(other.user) is list: + for k in other.user[:-1]: + if self.user != k: + return False + elif type(other.user) in (int, bool) and type(self.user) is list: + for k in self.user[:-1]: + if other.user != k: + return False + elif self.user != other.user: + return False + else: + if self.user is not None and other.user is not None: + if type(self.user) in (int, bool) and type(other.user) is list: + for k in other.user: + if self.user != k: + return False + elif type(other.user) in (int, bool) and type(self.user) is list: + for k in self.user: + if other.user != k: + return False + elif self.user != other.user: + return False + return True def __repr__(self): return ( From a5524287ca48629854287847c709ea22a0ae41d9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:09:48 -0800 Subject: [PATCH 349/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream register --- rtl/axis_register.v | 59 ++++++++++--- rtl/axis_register_64.v | 153 --------------------------------- tb/test_axis_register.py | 166 +++++++++++++++++++++++++---------- tb/test_axis_register.v | 46 ++++++++-- tb/test_axis_register_64.py | 167 +++++++++++++++++++++++++----------- tb/test_axis_register_64.v | 42 +++++++-- 6 files changed, 359 insertions(+), 274 deletions(-) delete mode 100644 rtl/axis_register_64.v diff --git a/rtl/axis_register.v b/rtl/axis_register.v index 33dc1b67b..1838ccad5 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -31,7 +31,16 @@ THE SOFTWARE. */ module axis_register # ( - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( input wire clk, @@ -41,33 +50,45 @@ module axis_register # * 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, + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, /* * AXI output */ 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 + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser ); // datapath registers reg input_axis_tready_reg = 1'b0; -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_input_to_output; @@ -76,10 +97,13 @@ reg store_axis_temp_to_output; assign input_axis_tready = input_axis_tready_reg; -assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign output_axis_tlast = LAST_ENABLE ? output_axis_tlast_reg : 1'b1; +assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) wire input_axis_tready_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~input_axis_tvalid)); @@ -92,7 +116,7 @@ always @* begin store_axis_input_to_output = 1'b0; store_axis_input_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (input_axis_tready_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin @@ -126,17 +150,26 @@ always @(posedge clk) begin // datapath if (store_axis_input_to_output) begin output_axis_tdata_reg <= input_axis_tdata; + output_axis_tkeep_reg <= input_axis_tkeep; output_axis_tlast_reg <= input_axis_tlast; + output_axis_tid_reg <= input_axis_tid; + output_axis_tdest_reg <= input_axis_tdest; output_axis_tuser_reg <= input_axis_tuser; end else if (store_axis_temp_to_output) begin output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end if (store_axis_input_to_temp) begin temp_axis_tdata_reg <= input_axis_tdata; + temp_axis_tkeep_reg <= input_axis_tkeep; temp_axis_tlast_reg <= input_axis_tlast; + temp_axis_tid_reg <= input_axis_tid; + temp_axis_tdest_reg <= input_axis_tdest; temp_axis_tuser_reg <= input_axis_tuser; end end diff --git a/rtl/axis_register_64.v b/rtl/axis_register_64.v deleted file mode 100644 index 2fbd0dc0d..000000000 --- a/rtl/axis_register_64.v +++ /dev/null @@ -1,153 +0,0 @@ -/* - -Copyright (c) 2014-2017 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream register (64 bit datapath) - */ -module axis_register_64 # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] input_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser -); - -// datapath registers -reg input_axis_tready_reg = 1'b0; - -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_input_to_output; -reg store_axis_input_to_temp; -reg store_axis_temp_to_output; - -assign input_axis_tready = input_axis_tready_reg; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -wire input_axis_tready_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~input_axis_tvalid)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_input_to_output = 1'b0; - store_axis_input_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (input_axis_tready_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = input_axis_tvalid; - store_axis_input_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = input_axis_tvalid; - store_axis_input_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - input_axis_tready_reg <= 1'b0; - output_axis_tvalid_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - input_axis_tready_reg <= input_axis_tready_early; - output_axis_tvalid_reg <= output_axis_tvalid_next; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_input_to_output) begin - output_axis_tdata_reg <= input_axis_tdata; - output_axis_tkeep_reg <= input_axis_tkeep; - output_axis_tlast_reg <= input_axis_tlast; - output_axis_tuser_reg <= input_axis_tuser; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_input_to_temp) begin - temp_axis_tdata_reg <= input_axis_tdata; - temp_axis_tkeep_reg <= input_axis_tkeep; - temp_axis_tlast_reg <= input_axis_tlast; - temp_axis_tuser_reg <= input_axis_tuser; - end -end - -endmodule diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py index 69f3cf2ee..21df526f4 100755 --- a/tb/test_axis_register.py +++ b/tb/test_axis_register.py @@ -44,24 +44,39 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -73,9 +88,12 @@ def bench(): clk, rst, tdata=input_axis_tdata, + tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -87,9 +105,12 @@ def bench(): clk, rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -106,15 +127,21 @@ def bench(): 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_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, 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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -139,10 +166,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -160,10 +192,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -179,10 +216,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -214,14 +256,23 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -246,14 +297,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -283,14 +343,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -320,11 +389,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -335,7 +409,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) diff --git a/tb/test_axis_register.v b/tb/test_axis_register.v index b35a2da6e..6756905e2 100644 --- a/tb/test_axis_register.v +++ b/tb/test_axis_register.v @@ -33,6 +33,15 @@ module test_axis_register; // Parameters parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -40,17 +49,23 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs wire input_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -59,16 +74,22 @@ initial begin rst, current_test, input_axis_tdata, + input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, 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_tid, + output_axis_tdest, output_axis_tuser ); @@ -78,22 +99,37 @@ initial begin end axis_register #( - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .rst(rst), - // axi input + // 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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), - // axi output + // 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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py index aa8933daf..9d8b099d9 100755 --- a/tb/test_axis_register_64.py +++ b/tb/test_axis_register_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_register_64' -testbench = 'test_%s' % module +module = 'axis_register' +testbench = 'test_%s_64' % module srcs = [] @@ -44,27 +44,39 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -80,6 +92,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -95,6 +109,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -115,6 +131,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -122,6 +140,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -146,10 +166,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -167,10 +192,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -186,10 +216,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -221,14 +256,23 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -253,14 +297,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -290,14 +343,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -327,11 +389,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -342,7 +409,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) diff --git a/tb/test_axis_register_64.v b/tb/test_axis_register_64.v index 0453828de..a9453e7b6 100644 --- a/tb/test_axis_register_64.v +++ b/tb/test_axis_register_64.v @@ -27,13 +27,21 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_register_64 + * Testbench for axis_register */ module test_axis_register_64; // Parameters parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -44,7 +52,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs @@ -53,7 +63,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -65,6 +77,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready ); @@ -74,6 +88,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -82,26 +98,38 @@ initial begin $dumpvars(0, test_axis_register_64); end -axis_register_64 #( +axis_register #( .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .rst(rst), - // axi input + // 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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), - // axi output + // 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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); From 190d75df9da1bdca11e05e7a6ce51f9c4929cc47 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:10:41 -0800 Subject: [PATCH 350/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream FIFO --- rtl/axis_fifo.v | 61 ++++++++++--- rtl/axis_fifo_64.v | 187 ---------------------------------------- tb/test_axis_fifo.py | 174 +++++++++++++++++++++++++++---------- tb/test_axis_fifo.v | 42 ++++++++- tb/test_axis_fifo_64.py | 175 ++++++++++++++++++++++++++----------- tb/test_axis_fifo_64.v | 39 +++++++-- 6 files changed, 374 insertions(+), 304 deletions(-) delete mode 100644 rtl/axis_fifo_64.v diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index e3b801625..952eeccfe 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -32,43 +32,65 @@ THE SOFTWARE. module axis_fifo # ( parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( input wire clk, 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, - + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, + /* * AXI output */ 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 + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser ); +localparam KEEP_OFFSET = DATA_WIDTH; +localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); +localparam ID_OFFSET = LAST_OFFSET + (LAST_ENABLE ? 1 : 0); +localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0); +localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); +localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); + reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; -reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [WIDTH-1:0] mem_read_data_reg; reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; -wire [DATA_WIDTH+2-1:0] mem_write_data; -reg [DATA_WIDTH+2-1:0] output_data_reg = {DATA_WIDTH+2{1'b0}}; +wire [WIDTH-1:0] input_axis; +reg [WIDTH-1:0] output_axis_reg; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first MSB different but rest same @@ -84,10 +106,23 @@ reg store_output; assign input_axis_tready = ~full; +generate + assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; + if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; + if (LAST_ENABLE) assign input_axis[LAST_OFFSET] = input_axis_tlast; + if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; + if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; + if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; +endgenerate + assign output_axis_tvalid = output_axis_tvalid_reg; -assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = output_data_reg; +assign output_axis_tdata = output_axis_reg[DATA_WIDTH-1:0]; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_reg[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +assign output_axis_tlast = LAST_ENABLE ? output_axis_reg[LAST_OFFSET] : 1'b1; +assign output_axis_tid = ID_ENABLE ? output_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; // Write logic always @* begin @@ -115,7 +150,7 @@ always @(posedge clk) begin wr_addr_reg <= wr_ptr_next; if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= input_axis; end end @@ -177,7 +212,7 @@ always @(posedge clk) begin end if (store_output) begin - output_data_reg <= mem_read_data_reg; + output_axis_reg <= mem_read_data_reg; end end diff --git a/rtl/axis_fifo_64.v b/rtl/axis_fifo_64.v deleted file mode 100644 index d82909f68..000000000 --- a/rtl/axis_fifo_64.v +++ /dev/null @@ -1,187 +0,0 @@ -/* - -Copyright (c) 2013-2017 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream FIFO (64 bit datapath) - */ -module axis_fifo_64 # -( - parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] input_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser -); - -reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; -reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; - -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+KEEP_WIDTH+2{1'b0}}; -reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; -wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_write_data; - -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] output_data_reg = {DATA_WIDTH+KEEP_WIDTH+2{1'b0}}; - -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; - -// full when first MSB different but rest same -wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && - (wr_ptr_reg[ADDR_WIDTH-1:0] == rd_ptr_reg[ADDR_WIDTH-1:0])); -// empty when pointers match exactly -wire empty = wr_ptr_reg == rd_ptr_reg; - -// control signals -reg write; -reg read; -reg store_output; - -assign input_axis_tready = ~full; - -assign output_axis_tvalid = output_axis_tvalid_reg; - -assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = output_data_reg; - -// Write logic -always @* begin - write = 1'b0; - - wr_ptr_next = wr_ptr_reg; - - if (input_axis_tvalid) begin - // input data valid - if (~full) begin - // not full, perform write - write = 1'b1; - wr_ptr_next = wr_ptr_reg + 1; - end - end -end - -always @(posedge clk) begin - if (rst) begin - wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - end else begin - wr_ptr_reg <= wr_ptr_next; - end - - wr_addr_reg <= wr_ptr_next; - - if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; - end -end - -// Read logic -always @* begin - read = 1'b0; - - rd_ptr_next = rd_ptr_reg; - - mem_read_data_valid_next = mem_read_data_valid_reg; - - if (store_output | ~mem_read_data_valid_reg) begin - // output data not valid OR currently being transferred - if (~empty) begin - // not empty, perform read - read = 1'b1; - mem_read_data_valid_next = 1'b1; - rd_ptr_next = rd_ptr_reg + 1; - end else begin - // empty, invalidate - mem_read_data_valid_next = 1'b0; - end - end -end - -always @(posedge clk) begin - if (rst) begin - rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - mem_read_data_valid_reg <= 1'b0; - end else begin - rd_ptr_reg <= rd_ptr_next; - mem_read_data_valid_reg <= mem_read_data_valid_next; - end - - rd_addr_reg <= rd_ptr_next; - - if (read) begin - mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; - end -end - -// Output register -always @* begin - store_output = 1'b0; - - output_axis_tvalid_next = output_axis_tvalid_reg; - - if (output_axis_tready | ~output_axis_tvalid) begin - store_output = 1'b1; - output_axis_tvalid_next = mem_read_data_valid_reg; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - end - - if (store_output) begin - output_data_reg <= mem_read_data_reg; - end -end - -endmodule diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index f4183f653..a77bb6423 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -45,6 +45,15 @@ def bench(): # Parameters ADDR_WIDTH = 2 DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -52,17 +61,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -74,9 +89,12 @@ def bench(): clk, rst, tdata=input_axis_tdata, + tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -88,9 +106,12 @@ def bench(): clk, rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -107,15 +128,21 @@ def bench(): 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_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, 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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -140,10 +167,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -161,10 +193,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -180,10 +217,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -215,14 +257,23 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -247,14 +298,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -284,14 +344,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -321,11 +390,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -336,7 +410,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -344,7 +418,11 @@ def bench(): print("test 8: initial sink pause") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + test_frame = axis_ep.AXIStreamFrame( + b'\x01\x02\x03', + id=8, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) @@ -368,7 +446,11 @@ def bench(): print("test 9: initial sink pause, reset") current_test.next = 9 - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + test_frame = axis_ep.AXIStreamFrame( + b'\x01\x02\x03', + id=9, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) diff --git a/tb/test_axis_fifo.v b/tb/test_axis_fifo.v index b3b8c5932..d3a0d084f 100644 --- a/tb/test_axis_fifo.v +++ b/tb/test_axis_fifo.v @@ -34,6 +34,15 @@ module test_axis_fifo; // Parameters parameter ADDR_WIDTH = 2; parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -41,17 +50,23 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs wire input_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -60,16 +75,22 @@ initial begin rst, current_test, input_axis_tdata, + input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, 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_tid, + output_axis_tdest, output_axis_tuser ); @@ -80,22 +101,37 @@ end axis_fifo #( .ADDR_WIDTH(ADDR_WIDTH), - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index d111fcfc0..5ef0509a9 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_fifo_64' -testbench = 'test_%s' % module +module = 'axis_fifo' +testbench = 'test_%s_64' % module srcs = [] @@ -45,7 +45,15 @@ def bench(): # Parameters ADDR_WIDTH = 2 DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -53,19 +61,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -81,6 +93,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -96,6 +110,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -116,6 +132,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -123,6 +141,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -147,10 +167,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -168,10 +193,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -187,10 +217,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -222,14 +257,23 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -254,14 +298,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -291,14 +344,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -328,11 +390,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -343,7 +410,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -351,7 +418,11 @@ def bench(): print("test 8: initial sink pause") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(24)), + id=8, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) @@ -375,7 +446,11 @@ def bench(): print("test 9: initial sink pause, reset") current_test.next = 9 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(24)), + id=9, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) diff --git a/tb/test_axis_fifo_64.v b/tb/test_axis_fifo_64.v index fd2264caf..6c5379493 100644 --- a/tb/test_axis_fifo_64.v +++ b/tb/test_axis_fifo_64.v @@ -27,14 +27,22 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_fifo_64 + * Testbench for axis_fifo */ module test_axis_fifo_64; // Parameters parameter ADDR_WIDTH = 2; parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -45,7 +53,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs @@ -54,7 +64,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -66,6 +78,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready ); @@ -75,6 +89,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -83,9 +99,18 @@ initial begin $dumpvars(0, test_axis_fifo_64); end -axis_fifo_64 #( +axis_fifo #( .ADDR_WIDTH(ADDR_WIDTH), - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -96,6 +121,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_axis_tdata(output_axis_tdata), @@ -103,6 +130,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); From 7d237f55c13d4dbe440a45d00031576c8c317bfe Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:11:08 -0800 Subject: [PATCH 351/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream async FIFO --- rtl/axis_async_fifo.v | 59 ++++++-- rtl/axis_async_fifo_64.v | 261 ---------------------------------- tb/test_axis_async_fifo.py | 177 +++++++++++++++++------ tb/test_axis_async_fifo.v | 42 +++++- tb/test_axis_async_fifo_64.py | 178 ++++++++++++++++------- tb/test_axis_async_fifo_64.v | 38 ++++- 6 files changed, 378 insertions(+), 377 deletions(-) delete mode 100644 rtl/axis_async_fifo_64.v diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index be63cf37e..4f5e34946 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -32,7 +32,16 @@ THE SOFTWARE. module axis_async_fifo # ( parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( /* @@ -45,22 +54,35 @@ module axis_async_fifo # */ input wire input_clk, 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, - + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, + /* * AXI output */ input wire output_clk, 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 + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser ); +localparam KEEP_OFFSET = DATA_WIDTH; +localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); +localparam ID_OFFSET = LAST_OFFSET + (LAST_ENABLE ? 1 : 0); +localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0); +localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); +localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); + reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; @@ -80,13 +102,13 @@ reg output_rst_sync1_reg = 1'b1; reg output_rst_sync2_reg = 1'b1; reg output_rst_sync3_reg = 1'b1; -reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+2{1'b0}}; +reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [WIDTH-1:0] mem_read_data_reg; reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; -wire [DATA_WIDTH+2-1:0] mem_write_data; -reg [DATA_WIDTH+2-1:0] output_data_reg = {DATA_WIDTH+2{1'b0}}; +wire [WIDTH-1:0] input_axis; +reg [WIDTH-1:0] output_axis_reg; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first TWO MSBs do NOT match, but rest matches @@ -104,10 +126,23 @@ reg store_output; assign input_axis_tready = ~full & ~input_rst_sync3_reg; +generate + assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; + if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; + if (LAST_ENABLE) assign input_axis[LAST_OFFSET] = input_axis_tlast; + if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; + if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; + if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; +endgenerate + assign output_axis_tvalid = output_axis_tvalid_reg; -assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = output_data_reg; +assign output_axis_tdata = output_axis_reg[DATA_WIDTH-1:0]; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_reg[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +assign output_axis_tlast = LAST_ENABLE ? output_axis_reg[LAST_OFFSET] : 1'b1; +assign output_axis_tid = ID_ENABLE ? output_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; // reset synchronization always @(posedge input_clk or posedge async_rst) begin @@ -164,7 +199,7 @@ always @(posedge input_clk) begin wr_addr_reg <= wr_ptr_next; if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= input_axis; end end @@ -251,7 +286,7 @@ always @(posedge output_clk) begin end if (store_output) begin - output_data_reg <= mem_read_data_reg; + output_axis_reg <= mem_read_data_reg; end end diff --git a/rtl/axis_async_fifo_64.v b/rtl/axis_async_fifo_64.v deleted file mode 100644 index 2c2e300e9..000000000 --- a/rtl/axis_async_fifo_64.v +++ /dev/null @@ -1,261 +0,0 @@ -/* - -Copyright (c) 2014-2017 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 asynchronous FIFO (64 bit datapath) - */ -module axis_async_fifo_64 # -( - parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - /* - * Common asynchronous reset - */ - input wire async_rst, - - /* - * AXI input - */ - input wire input_clk, - 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 - */ - input wire output_clk, - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser -); - -reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; -reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; -reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; -reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; - -reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; - -reg input_rst_sync1_reg = 1'b1; -reg input_rst_sync2_reg = 1'b1; -reg input_rst_sync3_reg = 1'b1; -reg output_rst_sync1_reg = 1'b1; -reg output_rst_sync2_reg = 1'b1; -reg output_rst_sync3_reg = 1'b1; - -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_read_data_reg = {DATA_WIDTH+KEEP_WIDTH+2{1'b0}}; -reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; -wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem_write_data; - -reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] output_data_reg = {DATA_WIDTH+KEEP_WIDTH+2{1'b0}}; - -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; - -// full when first TWO MSBs do NOT match, but rest matches -// (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) && - (wr_ptr_gray_reg[ADDR_WIDTH-1] != rd_ptr_gray_sync2_reg[ADDR_WIDTH-1]) && - (wr_ptr_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); -// empty when pointers match exactly -wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; - -// control signals -reg write; -reg read; -reg store_output; - -assign input_axis_tready = ~full & ~input_rst_sync3_reg; - -assign output_axis_tvalid = output_axis_tvalid_reg; - -assign mem_write_data = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = output_data_reg; - -// reset synchronization -always @(posedge input_clk or posedge async_rst) begin - if (async_rst) begin - input_rst_sync1_reg <= 1'b1; - input_rst_sync2_reg <= 1'b1; - input_rst_sync3_reg <= 1'b1; - end else begin - input_rst_sync1_reg <= 1'b0; - input_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; - input_rst_sync3_reg <= input_rst_sync2_reg; - end -end - -always @(posedge output_clk or posedge async_rst) begin - if (async_rst) begin - output_rst_sync1_reg <= 1'b1; - output_rst_sync2_reg <= 1'b1; - output_rst_sync3_reg <= 1'b1; - end else begin - output_rst_sync1_reg <= 1'b0; - output_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; - output_rst_sync3_reg <= output_rst_sync2_reg; - end -end - -// Write logic -always @* begin - write = 1'b0; - - wr_ptr_next = wr_ptr_reg; - wr_ptr_gray_next = wr_ptr_gray_reg; - - if (input_axis_tvalid) begin - // input data valid - if (~full) begin - // not full, perform write - write = 1'b1; - wr_ptr_next = wr_ptr_reg + 1; - wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); - end - end -end - -always @(posedge input_clk) begin - if (input_rst_sync3_reg) begin - wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - end else begin - wr_ptr_reg <= wr_ptr_next; - wr_ptr_gray_reg <= wr_ptr_gray_next; - end - - wr_addr_reg <= wr_ptr_next; - - if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; - end -end - -// pointer synchronization -always @(posedge input_clk) begin - if (input_rst_sync3_reg) begin - rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; - rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; - end else begin - rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg; - rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg; - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; - end else begin - wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; - wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg; - end -end - -// Read logic -always @* begin - read = 1'b0; - - rd_ptr_next = rd_ptr_reg; - rd_ptr_gray_next = rd_ptr_gray_reg; - - mem_read_data_valid_next = mem_read_data_valid_reg; - - if (store_output | ~mem_read_data_valid_reg) begin - // output data not valid OR currently being transferred - if (~empty) begin - // not empty, perform read - read = 1'b1; - mem_read_data_valid_next = 1'b1; - rd_ptr_next = rd_ptr_reg + 1; - rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); - end else begin - // empty, invalidate - mem_read_data_valid_next = 1'b0; - end - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - mem_read_data_valid_reg <= 1'b0; - end else begin - rd_ptr_reg <= rd_ptr_next; - rd_ptr_gray_reg <= rd_ptr_gray_next; - mem_read_data_valid_reg <= mem_read_data_valid_next; - end - - rd_addr_reg <= rd_ptr_next; - - if (read) begin - mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; - end -end - -// Output register -always @* begin - store_output = 1'b0; - - output_axis_tvalid_next = output_axis_tvalid_reg; - - if (output_axis_tready | ~output_axis_tvalid) begin - store_output = 1'b1; - output_axis_tvalid_next = mem_read_data_valid_reg; - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - output_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - end - - if (store_output) begin - output_data_reg <= mem_read_data_reg; - end -end - -endmodule diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index d1ad35fb1..e7bb74831 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -45,6 +45,15 @@ def bench(): # Parameters ADDR_WIDTH = 2 DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs async_rst = Signal(bool(0)) @@ -53,17 +62,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -75,9 +90,12 @@ def bench(): input_clk, async_rst, tdata=input_axis_tdata, + tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -89,9 +107,12 @@ def bench(): output_clk, async_rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -109,15 +130,21 @@ def bench(): 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_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, 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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -148,10 +175,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield input_clk.posedge @@ -169,10 +201,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield input_clk.posedge @@ -188,10 +225,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + source.send(test_frame) yield input_clk.posedge @@ -223,14 +265,26 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + test_frame1.id = 4 + test_frame1.dest = 1 + test_frame2.id = 4 + test_frame2.dest = 2 source.send(test_frame1) source.send(test_frame2) yield input_clk.posedge @@ -255,14 +309,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield input_clk.posedge @@ -292,14 +355,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield input_clk.posedge @@ -329,11 +401,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield input_clk.posedge @@ -344,7 +421,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -352,7 +429,11 @@ def bench(): print("test 8: initial sink pause") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + test_frame = axis_ep.AXIStreamFrame( + b'\x01\x02\x03', + id=8, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) @@ -376,7 +457,11 @@ def bench(): print("test 9: initial sink pause, assert reset") current_test.next = 9 - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + test_frame = axis_ep.AXIStreamFrame( + b'\x01\x02\x03', + id=9, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) diff --git a/tb/test_axis_async_fifo.v b/tb/test_axis_async_fifo.v index b1ad88a5a..5396d1e5e 100644 --- a/tb/test_axis_async_fifo.v +++ b/tb/test_axis_async_fifo.v @@ -34,6 +34,15 @@ module test_axis_async_fifo; // Parameters parameter ADDR_WIDTH = 2; parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg async_rst = 0; @@ -42,17 +51,23 @@ reg output_clk = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs wire input_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -62,16 +77,22 @@ initial begin output_clk, current_test, input_axis_tdata, + input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, 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_tid, + output_axis_tdest, output_axis_tuser ); @@ -82,7 +103,16 @@ end axis_async_fifo #( .ADDR_WIDTH(ADDR_WIDTH), - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( // Common reset @@ -90,16 +120,22 @@ UUT ( // AXI input .input_clk(input_clk), .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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_clk(output_clk), .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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index e43d63f50..2d26b5b7c 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_async_fifo_64' -testbench = 'test_%s' % module +module = 'axis_async_fifo' +testbench = 'test_%s_64' % module srcs = [] @@ -45,7 +45,15 @@ def bench(): # Parameters ADDR_WIDTH = 2 DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs async_rst = Signal(bool(0)) @@ -54,19 +62,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -82,6 +94,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -97,6 +111,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -118,6 +134,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -125,6 +143,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -155,10 +175,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield input_clk.posedge @@ -176,10 +201,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield input_clk.posedge @@ -195,10 +225,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=3, + dest=1 + ) + source.send(test_frame) yield input_clk.posedge @@ -230,14 +265,26 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame1.id = 4 + test_frame1.dest = 1 + test_frame2.id = 4 + test_frame2.dest = 2 source.send(test_frame1) source.send(test_frame2) yield input_clk.posedge @@ -262,14 +309,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + source.send(test_frame1) source.send(test_frame2) yield input_clk.posedge @@ -299,14 +355,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + source.send(test_frame1) source.send(test_frame2) yield input_clk.posedge @@ -336,11 +401,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield input_clk.posedge @@ -351,7 +421,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -359,7 +429,11 @@ def bench(): print("test 8: initial sink pause") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(24)), + id=8, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) @@ -383,7 +457,11 @@ def bench(): print("test 9: initial sink pause, assert reset") current_test.next = 9 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(24)), + id=9, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) diff --git a/tb/test_axis_async_fifo_64.v b/tb/test_axis_async_fifo_64.v index da3114e01..1751c590d 100644 --- a/tb/test_axis_async_fifo_64.v +++ b/tb/test_axis_async_fifo_64.v @@ -27,14 +27,22 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_async_fifo_64 + * Testbench for axis_async_fifo */ module test_axis_async_fifo_64; // Parameters parameter ADDR_WIDTH = 2; parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg async_rst = 0; @@ -46,7 +54,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs @@ -55,7 +65,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -68,6 +80,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready ); @@ -77,6 +91,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -85,10 +101,18 @@ initial begin $dumpvars(0, test_axis_async_fifo_64); end -axis_async_fifo_64 #( +axis_async_fifo #( .ADDR_WIDTH(ADDR_WIDTH), .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( // Common reset @@ -100,6 +124,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_clk(output_clk), @@ -108,6 +134,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); From 1c7362c717e800e204e970e7dc2b490925ed184a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:11:44 -0800 Subject: [PATCH 352/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream frame FIFO --- rtl/axis_frame_fifo.v | 62 +++++++-- rtl/axis_frame_fifo_64.v | 249 ---------------------------------- tb/test_axis_frame_fifo.py | 180 +++++++++++++++++------- tb/test_axis_frame_fifo.v | 45 +++++- tb/test_axis_frame_fifo_64.py | 181 +++++++++++++++++------- tb/test_axis_frame_fifo_64.v | 43 +++++- 6 files changed, 394 insertions(+), 366 deletions(-) delete mode 100644 rtl/axis_frame_fifo_64.v diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 56e77a00d..13869ad06 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -33,28 +33,46 @@ module axis_frame_fifo # ( parameter ADDR_WIDTH = 12, parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + parameter USER_BAD_FRAME_VALUE = 1'b1, + parameter USER_BAD_FRAME_MASK = 1'b1, + parameter DROP_BAD_FRAME = 1, parameter DROP_WHEN_FULL = 0 ) ( 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, - + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, + /* * AXI output */ 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 [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser, /* * Status @@ -64,19 +82,26 @@ module axis_frame_fifo # output wire good_frame ); +localparam KEEP_OFFSET = DATA_WIDTH; +localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); +localparam ID_OFFSET = LAST_OFFSET + 1; +localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0); +localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); +localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); + reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; -reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+1{1'b0}}; +reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [WIDTH-1:0] mem_read_data_reg; reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; -wire [DATA_WIDTH+1-1:0] mem_write_data; -reg [DATA_WIDTH+1-1:0] output_data_reg = {DATA_WIDTH+1{1'b0}}; +wire [WIDTH-1:0] input_axis; +reg [WIDTH-1:0] output_axis_reg; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first MSB different but rest same @@ -100,10 +125,23 @@ reg good_frame_reg = 1'b0, good_frame_next; assign input_axis_tready = (~full | DROP_WHEN_FULL); +generate + assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; + if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; + assign input_axis[LAST_OFFSET] = input_axis_tlast; + if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; + if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; + if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; +endgenerate + assign output_axis_tvalid = output_axis_tvalid_reg; -assign mem_write_data = {input_axis_tlast, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tdata} = output_data_reg; +assign output_axis_tdata = output_axis_reg[DATA_WIDTH-1:0]; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_reg[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +assign output_axis_tlast = output_axis_reg[LAST_OFFSET]; +assign output_axis_tid = ID_ENABLE ? output_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; assign overflow = overflow_reg; assign bad_frame = bad_frame_reg; @@ -140,7 +178,7 @@ always @* begin wr_ptr_cur_next = wr_ptr_cur_reg + 1; if (input_axis_tlast) begin // end of frame - if (input_axis_tuser) begin + if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & input_axis_tuser == USER_BAD_FRAME_VALUE)) begin // bad packet, reset write pointer wr_ptr_cur_next = wr_ptr_reg; bad_frame_next = 1'b1; @@ -177,7 +215,7 @@ always @(posedge clk) begin wr_addr_reg <= wr_ptr_cur_next; if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= input_axis; end end @@ -239,7 +277,7 @@ always @(posedge clk) begin end if (store_output) begin - output_data_reg <= mem_read_data_reg; + output_axis_reg <= mem_read_data_reg; end end diff --git a/rtl/axis_frame_fifo_64.v b/rtl/axis_frame_fifo_64.v deleted file mode 100644 index 6533d18f0..000000000 --- a/rtl/axis_frame_fifo_64.v +++ /dev/null @@ -1,249 +0,0 @@ -/* - -Copyright (c) 2014-2017 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 frame FIFO (64 bit datapath) - */ -module axis_frame_fifo_64 # -( - parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter DROP_WHEN_FULL = 0 -) -( - 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, - - /* - * Status - */ - output wire overflow, - output wire bad_frame, - output wire good_frame -); - -reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; -reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; -reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; - -reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+KEEP_WIDTH+1{1'b0}}; -reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; -wire [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_write_data; - -reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] output_data_reg = {DATA_WIDTH+KEEP_WIDTH+1{1'b0}}; - -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; - -// full when first MSB different but rest same -wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && - (wr_ptr_reg[ADDR_WIDTH-1:0] == rd_ptr_reg[ADDR_WIDTH-1:0])); -// empty when pointers match exactly -wire empty = wr_ptr_reg == rd_ptr_reg; -// overflow within packet -wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && - (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); - -// control signals -reg write; -reg read; -reg store_output; - -reg drop_frame_reg = 1'b0, drop_frame_next; -reg overflow_reg = 1'b0, overflow_next; -reg bad_frame_reg = 1'b0, bad_frame_next; -reg good_frame_reg = 1'b0, good_frame_next; - -assign input_axis_tready = (~full | DROP_WHEN_FULL); - -assign output_axis_tvalid = output_axis_tvalid_reg; - -assign mem_write_data = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = output_data_reg; - -assign overflow = overflow_reg; -assign bad_frame = bad_frame_reg; -assign good_frame = good_frame_reg; - -// Write logic -always @* begin - write = 1'b0; - - drop_frame_next = 1'b0; - overflow_next = 1'b0; - bad_frame_next = 1'b0; - good_frame_next = 1'b0; - - wr_ptr_next = wr_ptr_reg; - wr_ptr_cur_next = wr_ptr_cur_reg; - - if (input_axis_tvalid) begin - // input data valid - if (~full | DROP_WHEN_FULL) begin - // not full, perform write - if (full | full_cur | drop_frame_reg) begin - // full, packet overflow, or currently dropping frame - // drop frame - drop_frame_next = 1'b1; - if (input_axis_tlast) begin - // end of frame, reset write pointer - wr_ptr_cur_next = wr_ptr_reg; - drop_frame_next = 1'b0; - overflow_next = 1'b1; - end - end else begin - write = 1'b1; - wr_ptr_cur_next = wr_ptr_cur_reg + 1; - if (input_axis_tlast) begin - // end of frame - if (input_axis_tuser) begin - // bad packet, reset write pointer - wr_ptr_cur_next = wr_ptr_reg; - bad_frame_next = 1'b1; - end else begin - // good packet, update write pointer - wr_ptr_next = wr_ptr_cur_reg + 1; - good_frame_next = 1'b1; - end - end - end - end - end -end - -always @(posedge clk) begin - if (rst) begin - wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; - - drop_frame_reg <= 1'b0; - overflow_reg <= 1'b0; - bad_frame_reg <= 1'b0; - good_frame_reg <= 1'b0; - end else begin - wr_ptr_reg <= wr_ptr_next; - wr_ptr_cur_reg <= wr_ptr_cur_next; - - drop_frame_reg <= drop_frame_next; - overflow_reg <= overflow_next; - bad_frame_reg <= bad_frame_next; - good_frame_reg <= good_frame_next; - end - - wr_addr_reg <= wr_ptr_cur_next; - - if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; - end -end - -// Read logic -always @* begin - read = 1'b0; - - rd_ptr_next = rd_ptr_reg; - - mem_read_data_valid_next = mem_read_data_valid_reg; - - if (store_output | ~mem_read_data_valid_reg) begin - // output data not valid OR currently being transferred - if (~empty) begin - // not empty, perform read - read = 1'b1; - mem_read_data_valid_next = 1'b1; - rd_ptr_next = rd_ptr_reg + 1; - end else begin - // empty, invalidate - mem_read_data_valid_next = 1'b0; - end - end -end - -always @(posedge clk) begin - if (rst) begin - rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - mem_read_data_valid_reg <= 1'b0; - end else begin - rd_ptr_reg <= rd_ptr_next; - mem_read_data_valid_reg <= mem_read_data_valid_next; - end - - rd_addr_reg <= rd_ptr_next; - - if (read) begin - mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; - end -end - -// Output register -always @* begin - store_output = 1'b0; - - output_axis_tvalid_next = output_axis_tvalid_reg; - - if (output_axis_tready | ~output_axis_tvalid) begin - store_output = 1'b1; - output_axis_tvalid_next = mem_read_data_valid_reg; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - end - - if (store_output) begin - output_data_reg <= mem_read_data_reg; - end -end - -endmodule diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index a519c467f..8cd0d7181 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -45,6 +45,17 @@ def bench(): # Parameters ADDR_WIDTH = 9 DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 1 DROP_WHEN_FULL = 0 # Inputs @@ -53,16 +64,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) overflow = Signal(bool(0)) bad_frame = Signal(bool(0)) good_frame = Signal(bool(0)) @@ -77,9 +95,12 @@ def bench(): clk, rst, tdata=input_axis_tdata, + tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -91,9 +112,13 @@ def bench(): clk, rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, + tuser=output_axis_tuser, pause=sink_pause, name='sink' ) @@ -109,15 +134,22 @@ def bench(): 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_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, 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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, + output_axis_tuser=output_axis_tuser, overflow=overflow, bad_frame=bad_frame, @@ -158,10 +190,14 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -188,10 +224,14 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -216,10 +256,14 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -260,14 +304,22 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -301,14 +353,22 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -347,14 +407,22 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -393,11 +461,15 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -420,10 +492,14 @@ def bench(): print("test 8: single packet overflow") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))*2) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))*2, + id=8, + dest=1 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -446,7 +522,11 @@ def bench(): print("test 9: initial sink pause") current_test.next = 9 - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + test_frame = axis_ep.AXIStreamFrame( + b'\x01\x02\x03', + id=9, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) @@ -470,7 +550,11 @@ def bench(): print("test 10: initial sink pause, reset") current_test.next = 10 - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + test_frame = axis_ep.AXIStreamFrame( + b'\x01\x02\x03', + id=10, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v index 5736f2d64..0fc99f00f 100644 --- a/tb/test_axis_frame_fifo.v +++ b/tb/test_axis_frame_fifo.v @@ -34,6 +34,17 @@ module test_axis_frame_fifo; // Parameters parameter ADDR_WIDTH = 9; parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 1; parameter DROP_WHEN_FULL = 0; // Inputs @@ -42,16 +53,23 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs wire input_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; wire overflow; wire bad_frame; wire good_frame; @@ -63,16 +81,23 @@ initial begin rst, current_test, input_axis_tdata, + input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, 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_tid, + output_axis_tdest, + output_axis_tuser, overflow, bad_frame, good_frame @@ -86,6 +111,17 @@ end axis_frame_fifo #( .ADDR_WIDTH(ADDR_WIDTH), .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), .DROP_WHEN_FULL(DROP_WHEN_FULL) ) UUT ( @@ -93,15 +129,22 @@ UUT ( .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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), + .output_axis_tuser(output_axis_tuser), // Status .overflow(overflow), .bad_frame(bad_frame), diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index 4dfc363bc..698c4106d 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_frame_fifo_64' -testbench = 'test_%s' % module +module = 'axis_frame_fifo' +testbench = 'test_%s_64' % module srcs = [] @@ -45,7 +45,17 @@ def bench(): # Parameters ADDR_WIDTH = 6 DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 1 DROP_WHEN_FULL = 0 # Inputs @@ -54,18 +64,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) overflow = Signal(bool(0)) bad_frame = Signal(bool(0)) good_frame = Signal(bool(0)) @@ -84,6 +99,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -99,6 +116,9 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, + tuser=output_axis_tuser, pause=sink_pause, name='sink' ) @@ -118,6 +138,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -125,6 +147,9 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, + output_axis_tuser=output_axis_tuser, overflow=overflow, bad_frame=bad_frame, @@ -165,10 +190,14 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -195,10 +224,14 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -223,10 +256,14 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=3, + dest=1 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -267,14 +304,22 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -308,14 +353,22 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -354,14 +407,22 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -400,11 +461,15 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -427,10 +492,14 @@ def bench(): print("test 8: single packet overflow") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))*2) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))*2, + id=8, + dest=1 + ) overflow_asserted.next = 0 bad_frame_asserted.next = 0 @@ -453,7 +522,11 @@ def bench(): print("test 9: initial sink pause") current_test.next = 9 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(24)), + id=9, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) @@ -477,7 +550,11 @@ def bench(): print("test 10: initial sink pause, reset") current_test.next = 10 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(24)), + id=10, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v index 28c5c140e..8dc92fc4f 100644 --- a/tb/test_axis_frame_fifo_64.v +++ b/tb/test_axis_frame_fifo_64.v @@ -27,14 +27,24 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_frame_fifo_64 + * Testbench for axis_frame_fifo */ module test_axis_frame_fifo_64; // Parameters parameter ADDR_WIDTH = 6; parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 1; parameter DROP_WHEN_FULL = 0; // Inputs @@ -46,7 +56,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs @@ -55,6 +67,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; wire overflow; wire bad_frame; wire good_frame; @@ -69,6 +84,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready ); @@ -78,6 +95,9 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, + output_axis_tuser, overflow, bad_frame, good_frame @@ -88,10 +108,20 @@ initial begin $dumpvars(0, test_axis_frame_fifo_64); end -axis_frame_fifo_64 #( +axis_frame_fifo #( .ADDR_WIDTH(ADDR_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH), .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), .DROP_WHEN_FULL(DROP_WHEN_FULL) ) UUT ( @@ -103,6 +133,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_axis_tdata(output_axis_tdata), @@ -110,6 +142,9 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), + .output_axis_tuser(output_axis_tuser), // Status .overflow(overflow), .bad_frame(bad_frame), From fdb881719c8cef8f800d8d8970681c65433a1f2c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:12:02 -0800 Subject: [PATCH 353/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream async frame FIFO --- rtl/axis_async_frame_fifo.v | 60 ++++- rtl/axis_async_frame_fifo_64.v | 377 ---------------------------- tb/test_axis_async_frame_fifo.py | 180 +++++++++---- tb/test_axis_async_frame_fifo.v | 45 +++- tb/test_axis_async_frame_fifo_64.py | 181 +++++++++---- tb/test_axis_async_frame_fifo_64.v | 42 +++- 6 files changed, 393 insertions(+), 492 deletions(-) delete mode 100644 rtl/axis_async_frame_fifo_64.v diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 62fe41245..3890a0387 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -33,6 +33,17 @@ module axis_async_frame_fifo # ( parameter ADDR_WIDTH = 12, parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + parameter USER_BAD_FRAME_VALUE = 1'b1, + parameter USER_BAD_FRAME_MASK = 1'b1, + parameter DROP_BAD_FRAME = 1, parameter DROP_WHEN_FULL = 0 ) ( @@ -46,19 +57,26 @@ module axis_async_frame_fifo # */ input wire input_clk, 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, - + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, + /* * AXI output */ input wire output_clk, 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 [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser, /* * Status @@ -71,6 +89,13 @@ module axis_async_frame_fifo # output wire output_status_good_frame ); +localparam KEEP_OFFSET = DATA_WIDTH; +localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); +localparam ID_OFFSET = LAST_OFFSET + 1; +localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0); +localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); +localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); + reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; @@ -91,13 +116,13 @@ reg output_rst_sync1_reg = 1'b1; reg output_rst_sync2_reg = 1'b1; reg output_rst_sync3_reg = 1'b1; -reg [DATA_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+1{1'b0}}; +reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg [WIDTH-1:0] mem_read_data_reg; reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; -wire [DATA_WIDTH+1-1:0] mem_write_data; -reg [DATA_WIDTH+1-1:0] output_data_reg = {DATA_WIDTH+1{1'b0}}; +wire [WIDTH-1:0] input_axis; +reg [WIDTH-1:0] output_axis_reg; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; // full when first TWO MSBs do NOT match, but rest matches @@ -136,10 +161,23 @@ reg good_frame_sync4_reg = 1'b0; assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3_reg; +generate + assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; + if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; + assign input_axis[LAST_OFFSET] = input_axis_tlast; + if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; + if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; + if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; +endgenerate + assign output_axis_tvalid = output_axis_tvalid_reg; -assign mem_write_data = {input_axis_tlast, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tdata} = output_data_reg; +assign output_axis_tdata = output_axis_reg[DATA_WIDTH-1:0]; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_reg[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +assign output_axis_tlast = output_axis_reg[LAST_OFFSET]; +assign output_axis_tid = ID_ENABLE ? output_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; assign input_status_overflow = overflow_reg; assign input_status_bad_frame = bad_frame_reg; @@ -206,7 +244,7 @@ always @* begin wr_ptr_cur_next = wr_ptr_cur_reg + 1; if (input_axis_tlast) begin // end of frame - if (input_axis_tuser) begin + if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & input_axis_tuser == USER_BAD_FRAME_VALUE)) begin // bad packet, reset write pointer wr_ptr_cur_next = wr_ptr_reg; bad_frame_next = 1'b1; @@ -246,7 +284,7 @@ always @(posedge input_clk) begin wr_addr_reg <= wr_ptr_cur_next; if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= input_axis; end end @@ -367,7 +405,7 @@ always @(posedge output_clk) begin end if (store_output) begin - output_data_reg <= mem_read_data_reg; + output_axis_reg <= mem_read_data_reg; end end diff --git a/rtl/axis_async_frame_fifo_64.v b/rtl/axis_async_frame_fifo_64.v deleted file mode 100644 index 59c4fb898..000000000 --- a/rtl/axis_async_frame_fifo_64.v +++ /dev/null @@ -1,377 +0,0 @@ -/* - -Copyright (c) 2014-2017 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 asynchronous frame FIFO (64 bit datapath) - */ -module axis_async_frame_fifo_64 # -( - parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter DROP_WHEN_FULL = 0 -) -( - /* - * Common asynchronous reset - */ - input wire async_rst, - - /* - * AXI input - */ - input wire input_clk, - 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 - */ - input wire output_clk, - 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, - - /* - * Status - */ - output wire input_status_overflow, - output wire input_status_bad_frame, - output wire input_status_good_frame, - output wire output_status_overflow, - output wire output_status_bad_frame, - output wire output_status_good_frame -); - -reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; -reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; -reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; -reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; -reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; - -reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; - -reg input_rst_sync1_reg = 1'b1; -reg input_rst_sync2_reg = 1'b1; -reg input_rst_sync3_reg = 1'b1; -reg output_rst_sync1_reg = 1'b1; -reg output_rst_sync2_reg = 1'b1; -reg output_rst_sync3_reg = 1'b1; - -reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_read_data_reg = {DATA_WIDTH+KEEP_WIDTH+1{1'b0}}; -reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; -wire [DATA_WIDTH+KEEP_WIDTH+1-1:0] mem_write_data; - -reg [DATA_WIDTH+KEEP_WIDTH+1-1:0] output_data_reg = {DATA_WIDTH+KEEP_WIDTH+1{1'b0}}; - -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; - -// full when first TWO MSBs do NOT match, but rest matches -// (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) && - (wr_ptr_gray_reg[ADDR_WIDTH-1] != rd_ptr_gray_sync2_reg[ADDR_WIDTH-1]) && - (wr_ptr_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); -// empty when pointers match exactly -wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; -// overflow within packet -wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && - (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); - -// control signals -reg write; -reg read; -reg store_output; - -reg drop_frame_reg = 1'b0, drop_frame_next; -reg overflow_reg = 1'b0, overflow_next; -reg bad_frame_reg = 1'b0, bad_frame_next; -reg good_frame_reg = 1'b0, good_frame_next; - -reg overflow_sync1_reg = 1'b0; -reg overflow_sync2_reg = 1'b0; -reg overflow_sync3_reg = 1'b0; -reg overflow_sync4_reg = 1'b0; -reg bad_frame_sync1_reg = 1'b0; -reg bad_frame_sync2_reg = 1'b0; -reg bad_frame_sync3_reg = 1'b0; -reg bad_frame_sync4_reg = 1'b0; -reg good_frame_sync1_reg = 1'b0; -reg good_frame_sync2_reg = 1'b0; -reg good_frame_sync3_reg = 1'b0; -reg good_frame_sync4_reg = 1'b0; - -assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3_reg; - -assign output_axis_tvalid = output_axis_tvalid_reg; - -assign mem_write_data = {input_axis_tlast, input_axis_tkeep, input_axis_tdata}; -assign {output_axis_tlast, output_axis_tkeep, output_axis_tdata} = output_data_reg; - -assign input_status_overflow = overflow_reg; -assign input_status_bad_frame = bad_frame_reg; -assign input_status_good_frame = good_frame_reg; - -assign output_status_overflow = overflow_sync3_reg ^ overflow_sync4_reg; -assign output_status_bad_frame = bad_frame_sync3_reg ^ bad_frame_sync4_reg; -assign output_status_good_frame = good_frame_sync3_reg ^ good_frame_sync4_reg; - -// reset synchronization -always @(posedge input_clk or posedge async_rst) begin - if (async_rst) begin - input_rst_sync1_reg <= 1'b1; - input_rst_sync2_reg <= 1'b1; - input_rst_sync3_reg <= 1'b1; - end else begin - input_rst_sync1_reg <= 1'b0; - input_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; - input_rst_sync3_reg <= input_rst_sync2_reg; - end -end - -always @(posedge output_clk or posedge async_rst) begin - if (async_rst) begin - output_rst_sync1_reg <= 1'b1; - output_rst_sync2_reg <= 1'b1; - output_rst_sync3_reg <= 1'b1; - end else begin - output_rst_sync1_reg <= 1'b0; - output_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; - output_rst_sync3_reg <= output_rst_sync2_reg; - end -end - -// Write logic -always @* begin - write = 1'b0; - - drop_frame_next = 1'b0; - overflow_next = 1'b0; - bad_frame_next = 1'b0; - good_frame_next = 1'b0; - - wr_ptr_next = wr_ptr_reg; - wr_ptr_cur_next = wr_ptr_cur_reg; - wr_ptr_gray_next = wr_ptr_gray_reg; - - if (input_axis_tvalid) begin - // input data valid - if (~full | DROP_WHEN_FULL) begin - // not full, perform write - if (full | full_cur | drop_frame_reg) begin - // full, packet overflow, or currently dropping frame - // drop frame - drop_frame_next = 1'b1; - if (input_axis_tlast) begin - // end of frame, reset write pointer - wr_ptr_cur_next = wr_ptr_reg; - drop_frame_next = 1'b0; - overflow_next = 1'b1; - end - end else begin - write = 1'b1; - wr_ptr_cur_next = wr_ptr_cur_reg + 1; - if (input_axis_tlast) begin - // end of frame - if (input_axis_tuser) begin - // bad packet, reset write pointer - wr_ptr_cur_next = wr_ptr_reg; - bad_frame_next = 1'b1; - end else begin - // good packet, update write pointer - wr_ptr_next = wr_ptr_cur_reg + 1; - wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); - good_frame_next = 1'b1; - end - end - end - end - end -end - -always @(posedge input_clk) begin - if (input_rst_sync3_reg) begin - wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - - drop_frame_reg <= 1'b0; - overflow_reg <= 1'b0; - bad_frame_reg <= 1'b0; - good_frame_reg <= 1'b0; - end else begin - wr_ptr_reg <= wr_ptr_next; - wr_ptr_cur_reg <= wr_ptr_cur_next; - wr_ptr_gray_reg <= wr_ptr_gray_next; - - drop_frame_reg <= drop_frame_next; - overflow_reg <= overflow_next; - bad_frame_reg <= bad_frame_next; - good_frame_reg <= good_frame_next; - end - - wr_addr_reg <= wr_ptr_cur_next; - - if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= mem_write_data; - end -end - -// pointer synchronization -always @(posedge input_clk) begin - if (input_rst_sync3_reg) begin - rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; - rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; - end else begin - rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg; - rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg; - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; - end else begin - wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; - wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg; - end -end - -// status synchronization -always @(posedge input_clk) begin - if (input_rst_sync3_reg) begin - overflow_sync1_reg <= 1'b0; - bad_frame_sync1_reg <= 1'b0; - good_frame_sync1_reg <= 1'b0; - end else begin - overflow_sync1_reg <= overflow_sync1_reg ^ overflow_reg; - bad_frame_sync1_reg <= bad_frame_sync1_reg ^ bad_frame_reg; - good_frame_sync1_reg <= good_frame_sync1_reg ^ good_frame_reg; - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - overflow_sync2_reg <= 1'b0; - overflow_sync3_reg <= 1'b0; - bad_frame_sync2_reg <= 1'b0; - bad_frame_sync3_reg <= 1'b0; - good_frame_sync2_reg <= 1'b0; - good_frame_sync3_reg <= 1'b0; - end else begin - overflow_sync2_reg <= overflow_sync1_reg; - overflow_sync3_reg <= overflow_sync2_reg; - overflow_sync4_reg <= overflow_sync3_reg; - bad_frame_sync2_reg <= bad_frame_sync1_reg; - bad_frame_sync3_reg <= bad_frame_sync2_reg; - bad_frame_sync4_reg <= bad_frame_sync3_reg; - good_frame_sync2_reg <= good_frame_sync1_reg; - good_frame_sync3_reg <= good_frame_sync2_reg; - good_frame_sync4_reg <= good_frame_sync3_reg; - end -end - -// Read logic -always @* begin - read = 1'b0; - - rd_ptr_next = rd_ptr_reg; - rd_ptr_gray_next = rd_ptr_gray_reg; - - mem_read_data_valid_next = mem_read_data_valid_reg; - - if (store_output | ~mem_read_data_valid_reg) begin - // output data not valid OR currently being transferred - if (~empty) begin - // not empty, perform read - read = 1'b1; - mem_read_data_valid_next = 1'b1; - rd_ptr_next = rd_ptr_reg + 1; - rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); - end else begin - // empty, invalidate - mem_read_data_valid_next = 1'b0; - end - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - mem_read_data_valid_reg <= 1'b0; - end else begin - rd_ptr_reg <= rd_ptr_next; - rd_ptr_gray_reg <= rd_ptr_gray_next; - mem_read_data_valid_reg <= mem_read_data_valid_next; - end - - rd_addr_reg <= rd_ptr_next; - - if (read) begin - mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; - end -end - -// Output register -always @* begin - store_output = 1'b0; - - output_axis_tvalid_next = output_axis_tvalid_reg; - - if (output_axis_tready | ~output_axis_tvalid) begin - store_output = 1'b1; - output_axis_tvalid_next = mem_read_data_valid_reg; - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - output_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - end - - if (store_output) begin - output_data_reg <= mem_read_data_reg; - end -end - -endmodule diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index 84d4ff01f..43c0a5a48 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -45,6 +45,17 @@ def bench(): # Parameters ADDR_WIDTH = 9 DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 1 DROP_WHEN_FULL = 0 # Inputs @@ -54,16 +65,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_status_overflow = Signal(bool(0)) input_status_bad_frame = Signal(bool(0)) input_status_good_frame = Signal(bool(0)) @@ -81,9 +99,12 @@ def bench(): input_clk, async_rst, tdata=input_axis_tdata, + tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -95,9 +116,13 @@ def bench(): output_clk, async_rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, + tuser=output_axis_tuser, pause=sink_pause, name='sink' ) @@ -114,15 +139,22 @@ def bench(): 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_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, 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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, + output_axis_tuser=output_axis_tuser, input_status_overflow=input_status_overflow, input_status_bad_frame=input_status_bad_frame, @@ -184,10 +216,14 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -220,10 +256,14 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -254,10 +294,14 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -304,14 +348,22 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -351,14 +403,22 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -407,14 +467,22 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=6 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -459,11 +527,15 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -492,10 +564,14 @@ def bench(): print("test 8: single packet overflow") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))*2) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))*2, + id=8, + dest=1 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -524,7 +600,11 @@ def bench(): print("test 9: initial sink pause") current_test.next = 9 - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + test_frame = axis_ep.AXIStreamFrame( + b'\x01\x02\x03', + id=9, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) @@ -548,7 +628,11 @@ def bench(): print("test 10: initial sink pause, assert reset") current_test.next = 10 - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + test_frame = axis_ep.AXIStreamFrame( + b'\x01\x02\x03', + id=10, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index f1d4d969a..258d74071 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -34,6 +34,17 @@ module test_axis_async_frame_fifo; // Parameters parameter ADDR_WIDTH = 9; parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 1; parameter DROP_WHEN_FULL = 0; // Inputs @@ -43,16 +54,23 @@ reg output_clk = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs wire input_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; wire input_status_overflow; wire input_status_bad_frame; wire input_status_good_frame; @@ -68,16 +86,23 @@ initial begin output_clk, current_test, input_axis_tdata, + input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, 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_tid, + output_axis_tdest, + output_axis_tuser, input_status_overflow, input_status_bad_frame, input_status_good_frame, @@ -94,6 +119,17 @@ end axis_async_frame_fifo #( .ADDR_WIDTH(ADDR_WIDTH), .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), .DROP_WHEN_FULL(DROP_WHEN_FULL) ) UUT ( @@ -102,16 +138,23 @@ UUT ( // AXI input .input_clk(input_clk), .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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_clk(output_clk), .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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), + .output_axis_tuser(output_axis_tuser), // Status .input_status_overflow(input_status_overflow), .input_status_bad_frame(input_status_bad_frame), diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index 37c0bac76..e32b66527 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_async_frame_fifo_64' -testbench = 'test_%s' % module +module = 'axis_async_frame_fifo' +testbench = 'test_%s_64' % module srcs = [] @@ -45,7 +45,17 @@ def bench(): # Parameters ADDR_WIDTH = 6 DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 1 DROP_WHEN_FULL = 0 # Inputs @@ -55,18 +65,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_status_overflow = Signal(bool(0)) input_status_bad_frame = Signal(bool(0)) input_status_good_frame = Signal(bool(0)) @@ -88,6 +103,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -103,6 +120,9 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, + tuser=output_axis_tuser, pause=sink_pause, name='sink' ) @@ -123,6 +143,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -130,6 +152,9 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, + output_axis_tuser=output_axis_tuser, input_status_overflow=input_status_overflow, input_status_bad_frame=input_status_bad_frame, @@ -191,10 +216,14 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -227,10 +256,14 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -261,10 +294,14 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=3, + dest=1 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -311,14 +348,22 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -358,14 +403,22 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -414,14 +467,22 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=6 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -466,11 +527,15 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -499,10 +564,14 @@ def bench(): print("test 8: single packet overflow") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))*2) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256))*2, + id=8, + dest=1 + ) input_status_overflow_asserted.next = 0 input_status_bad_frame_asserted.next = 0 @@ -531,7 +600,11 @@ def bench(): print("test 9: initial sink pause") current_test.next = 9 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(24)), + id=9, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) @@ -555,7 +628,11 @@ def bench(): print("test 10: initial sink pause, assert reset") current_test.next = 10 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(24)), + id=10, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index e68b68875..6a568141e 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -27,14 +27,24 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_async_frame_fifo_64 + * Testbench for axis_async_frame_fifo */ module test_axis_async_frame_fifo_64; // Parameters parameter ADDR_WIDTH = 6; parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 1; parameter DROP_WHEN_FULL = 0; // Inputs @@ -47,7 +57,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs @@ -56,6 +68,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; wire input_status_overflow; wire input_status_bad_frame; wire input_status_good_frame; @@ -74,6 +89,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready ); @@ -83,6 +100,9 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, + output_axis_tuser, input_status_overflow, input_status_bad_frame, input_status_good_frame, @@ -96,10 +116,21 @@ initial begin $dumpvars(0, test_axis_async_frame_fifo_64); end -axis_async_frame_fifo_64 #( +axis_async_frame_fifo #( .ADDR_WIDTH(ADDR_WIDTH), .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), .DROP_WHEN_FULL(DROP_WHEN_FULL) ) UUT ( @@ -112,6 +143,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_clk(output_clk), @@ -120,6 +153,9 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), + .output_axis_tuser(output_axis_tuser), // Status .input_status_overflow(input_status_overflow), .input_status_bad_frame(input_status_bad_frame), From d50c7674823d2ddb8509d14ab36ed533a1fe004e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:12:43 -0800 Subject: [PATCH 354/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream adapter --- rtl/axis_adapter.v | 184 ++++++++++++++++++++++------------- tb/test_axis_adapter_64_8.py | 93 +++++++++++++----- tb/test_axis_adapter_64_8.v | 42 ++++++-- tb/test_axis_adapter_8_64.py | 93 +++++++++++++----- tb/test_axis_adapter_8_64.v | 42 ++++++-- 5 files changed, 321 insertions(+), 133 deletions(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index a65951e3a..d0f7bad49 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -32,9 +32,17 @@ THE SOFTWARE. module axis_adapter # ( parameter INPUT_DATA_WIDTH = 8, + parameter INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8), parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8), parameter OUTPUT_DATA_WIDTH = 8, - parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8) + parameter OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8), + parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( input wire clk, @@ -48,7 +56,9 @@ module axis_adapter # input wire input_axis_tvalid, output wire input_axis_tready, input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, /* * AXI output @@ -58,31 +68,37 @@ module axis_adapter # output wire output_axis_tvalid, input wire output_axis_tready, output wire output_axis_tlast, - output wire output_axis_tuser + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser ); +// force keep width to 1 when disabled +localparam INPUT_KEEP_WIDTH_INT = INPUT_KEEP_ENABLE ? INPUT_KEEP_WIDTH : 1; +localparam OUTPUT_KEEP_WIDTH_INT = OUTPUT_KEEP_ENABLE ? OUTPUT_KEEP_WIDTH : 1; + // bus word sizes (must be identical) -localparam INPUT_DATA_WORD_SIZE = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH; -localparam OUTPUT_DATA_WORD_SIZE = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH; +localparam INPUT_DATA_WORD_SIZE = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH_INT; +localparam OUTPUT_DATA_WORD_SIZE = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH_INT; // output bus is wider -localparam EXPAND_BUS = OUTPUT_KEEP_WIDTH > INPUT_KEEP_WIDTH; +localparam EXPAND_BUS = OUTPUT_KEEP_WIDTH_INT > INPUT_KEEP_WIDTH_INT; // total data and keep widths localparam DATA_WIDTH = EXPAND_BUS ? OUTPUT_DATA_WIDTH : INPUT_DATA_WIDTH; -localparam KEEP_WIDTH = EXPAND_BUS ? OUTPUT_KEEP_WIDTH : INPUT_KEEP_WIDTH; +localparam KEEP_WIDTH = EXPAND_BUS ? OUTPUT_KEEP_WIDTH_INT : INPUT_KEEP_WIDTH_INT; // required number of cycles to match widths -localparam CYCLE_COUNT = EXPAND_BUS ? (OUTPUT_KEEP_WIDTH / INPUT_KEEP_WIDTH) : (INPUT_KEEP_WIDTH / OUTPUT_KEEP_WIDTH); +localparam CYCLE_COUNT = EXPAND_BUS ? (OUTPUT_KEEP_WIDTH_INT / INPUT_KEEP_WIDTH_INT) : (INPUT_KEEP_WIDTH_INT / OUTPUT_KEEP_WIDTH_INT); // data width and keep width per cycle localparam CYCLE_DATA_WIDTH = DATA_WIDTH / CYCLE_COUNT; localparam CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT; // bus width assertions initial begin - if (INPUT_DATA_WORD_SIZE * INPUT_KEEP_WIDTH != INPUT_DATA_WIDTH) begin + if (INPUT_DATA_WORD_SIZE * INPUT_KEEP_WIDTH_INT != INPUT_DATA_WIDTH) begin $error("Error: input data width not evenly divisble"); $finish; end - if (OUTPUT_DATA_WORD_SIZE * OUTPUT_KEEP_WIDTH != OUTPUT_DATA_WIDTH) begin + if (OUTPUT_DATA_WORD_SIZE * OUTPUT_KEEP_WIDTH_INT != OUTPUT_DATA_WIDTH) begin $error("Error: output data width not evenly divisble"); $finish; end @@ -108,16 +124,20 @@ reg last_cycle; reg [DATA_WIDTH-1:0] temp_tdata_reg = {DATA_WIDTH{1'b0}}, temp_tdata_next; reg [KEEP_WIDTH-1:0] temp_tkeep_reg = {KEEP_WIDTH{1'b0}}, temp_tkeep_next; reg temp_tlast_reg = 1'b0, temp_tlast_next; -reg temp_tuser_reg = 1'b0, temp_tuser_next; +reg [ID_WIDTH-1:0] temp_tid_reg = {ID_WIDTH{1'b0}}, temp_tid_next; +reg [DEST_WIDTH-1:0] temp_tdest_reg = {DEST_WIDTH{1'b0}}, temp_tdest_next; +reg [USER_WIDTH-1:0] temp_tuser_reg = {USER_WIDTH{1'b0}}, temp_tuser_next; // internal datapath -reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_int; -reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_int; +reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg [ID_WIDTH-1:0] output_axis_tid_int; +reg [DEST_WIDTH-1:0] output_axis_tdest_int; +reg [USER_WIDTH-1:0] output_axis_tuser_int; +wire output_axis_tready_int_early; reg input_axis_tready_reg = 1'b0, input_axis_tready_next; @@ -131,13 +151,17 @@ always @* begin temp_tdata_next = temp_tdata_reg; temp_tkeep_next = temp_tkeep_reg; temp_tlast_next = temp_tlast_reg; + temp_tid_next = temp_tid_reg; + temp_tdest_next = temp_tdest_reg; temp_tuser_next = temp_tuser_reg; - output_axis_tdata_int = {OUTPUT_DATA_WIDTH{1'b0}}; - output_axis_tkeep_int = {OUTPUT_KEEP_WIDTH{1'b0}}; + output_axis_tdata_int = {OUTPUT_DATA_WIDTH{1'b0}}; + output_axis_tkeep_int = {OUTPUT_KEEP_WIDTH{1'b0}}; output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tid_int = {ID_WIDTH{1'b0}}; + output_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_axis_tuser_int = {USER_WIDTH{1'b0}}; input_axis_tready_next = 1'b0; @@ -151,11 +175,13 @@ always @* begin input_axis_tready_next = output_axis_tready_int_early; // transfer through - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1; output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = input_axis_tlast; - output_axis_tuser_int = input_axis_tuser; + output_axis_tlast_int = input_axis_tlast; + output_axis_tid_int = input_axis_tid; + output_axis_tdest_int = input_axis_tdest; + output_axis_tuser_int = input_axis_tuser; state_next = STATE_IDLE; end else if (EXPAND_BUS) begin @@ -166,11 +192,13 @@ always @* begin if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store it in data register - + // pass complete input word, zero-extended to temp register temp_tdata_next = input_axis_tdata; - temp_tkeep_next = input_axis_tkeep; + temp_tkeep_next = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1; temp_tlast_next = input_axis_tlast; + temp_tid_next = input_axis_tid; + temp_tdest_next = input_axis_tdest; temp_tuser_next = input_axis_tuser; // first input cycle complete @@ -202,10 +230,10 @@ always @* begin if (CYCLE_COUNT == 1) begin // last cycle by counter value last_cycle = 1'b1; - end else if (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}) begin + end else if (INPUT_KEEP_ENABLE && input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}) begin // last cycle by tkeep fall in current cycle last_cycle = 1'b1; - end else if (input_axis_tkeep[(CYCLE_KEEP_WIDTH*2)-1:CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin + end else if (INPUT_KEEP_ENABLE && input_axis_tkeep[(CYCLE_KEEP_WIDTH*2)-1:CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin // last cycle by tkeep fall at end of current cycle last_cycle = 1'b1; end else begin @@ -214,16 +242,20 @@ always @* begin // pass complete input word, zero-extended to temp register temp_tdata_next = input_axis_tdata; - temp_tkeep_next = input_axis_tkeep; + temp_tkeep_next = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1; temp_tlast_next = input_axis_tlast; + temp_tid_next = input_axis_tid; + temp_tdest_next = input_axis_tdest; temp_tuser_next = input_axis_tuser; // short-circuit and get first word out the door - output_axis_tdata_int = input_axis_tdata[CYCLE_DATA_WIDTH-1:0]; - output_axis_tkeep_int = input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0]; + output_axis_tdata_int = input_axis_tdata[CYCLE_DATA_WIDTH-1:0]; + output_axis_tkeep_int = input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0]; output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = input_axis_tlast & last_cycle; - output_axis_tuser_int = input_axis_tuser & last_cycle; + output_axis_tlast_int = input_axis_tlast & last_cycle; + output_axis_tid_int = input_axis_tid; + output_axis_tdest_int = input_axis_tdest; + output_axis_tuser_int = input_axis_tuser; if (output_axis_tready_int_reg) begin // if output register is ready for first word, then move on to the next one @@ -251,14 +283,16 @@ always @* begin if (input_axis_tready & input_axis_tvalid) begin // word transfer in - store in data register - + temp_tdata_next[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH] = input_axis_tdata; - temp_tkeep_next[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] = input_axis_tkeep; + temp_tkeep_next[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1; temp_tlast_next = input_axis_tlast; + temp_tid_next = input_axis_tid; + temp_tdest_next = input_axis_tdest; temp_tuser_next = input_axis_tuser; cycle_count_next = cycle_count_reg + 1; - + if ((cycle_count_reg == CYCLE_COUNT-1) | input_axis_tlast) begin // terminated by counter or tlast signal, output complete word // read input word next cycle if output will be ready @@ -278,17 +312,19 @@ always @* begin if (EXPAND_BUS) begin // output bus is wider - + // do not accept new data input_axis_tready_next = 1'b0; // single-cycle output of entire stored word (output wider) - output_axis_tdata_int = temp_tdata_reg; - output_axis_tkeep_int = temp_tkeep_reg; + output_axis_tdata_int = temp_tdata_reg; + output_axis_tkeep_int = temp_tkeep_reg; output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = temp_tlast_reg; - output_axis_tuser_int = temp_tuser_reg; - + output_axis_tlast_int = temp_tlast_reg; + output_axis_tid_int = temp_tid_reg; + output_axis_tdest_int = temp_tdest_reg; + output_axis_tuser_int = temp_tuser_reg; + if (output_axis_tready_int_reg) begin // word transfer out @@ -297,8 +333,10 @@ always @* begin // pass complete input word, zero-extended to temp register temp_tdata_next = input_axis_tdata; - temp_tkeep_next = input_axis_tkeep; + temp_tkeep_next = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1; temp_tlast_next = input_axis_tlast; + temp_tid_next = input_axis_tid; + temp_tdest_next = input_axis_tdest; temp_tuser_next = input_axis_tuser; // first input cycle complete @@ -341,11 +379,13 @@ always @* begin end // output current part of stored word (output narrower) - output_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH]; - output_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH]; + output_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH]; + output_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH]; output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = temp_tlast_reg & last_cycle; - output_axis_tuser_int = temp_tuser_reg & last_cycle; + output_axis_tlast_int = temp_tlast_reg & last_cycle; + output_axis_tid_int = temp_tid_reg; + output_axis_tdest_int = temp_tdest_reg; + output_axis_tuser_int = temp_tuser_reg; if (output_axis_tready_int_reg) begin // word transfer out @@ -354,7 +394,7 @@ always @* begin if (last_cycle) begin // terminated by counter or tlast signal - + input_axis_tready_next = 1'b1; state_next = STATE_IDLE; end else begin @@ -363,7 +403,7 @@ always @* begin end end else begin state_next = STATE_TRANSFER_OUT; - end + end end end endcase @@ -385,32 +425,40 @@ always @(posedge clk) begin temp_tdata_reg <= temp_tdata_next; temp_tkeep_reg <= temp_tkeep_next; temp_tlast_reg <= temp_tlast_next; - temp_tuser_reg <= temp_tuser_next; + temp_tid_reg <= temp_tid_next; + temp_tdest_reg <= temp_tdest_next; + temp_tuser_reg <= temp_tuser_next; end // output datapath logic -reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}}; -reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}}; +reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}}; +reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}}; -reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}}; +reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}}; +reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}}; reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = OUTPUT_KEEP_ENABLE ? output_axis_tkeep_reg : {OUTPUT_KEEP_WIDTH{1'b1}}; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); @@ -423,7 +471,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin @@ -459,11 +507,15 @@ always @(posedge clk) begin output_axis_tdata_reg <= output_axis_tdata_int; output_axis_tkeep_reg <= output_axis_tkeep_int; output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tid_reg <= output_axis_tid_int; + output_axis_tdest_reg <= output_axis_tdest_int; output_axis_tuser_reg <= output_axis_tuser_int; end else if (store_axis_temp_to_output) begin output_axis_tdata_reg <= temp_axis_tdata_reg; output_axis_tkeep_reg <= temp_axis_tkeep_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end @@ -471,6 +523,8 @@ always @(posedge clk) begin temp_axis_tdata_reg <= output_axis_tdata_int; temp_axis_tkeep_reg <= output_axis_tkeep_int; temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tid_reg <= output_axis_tid_int; + temp_axis_tdest_reg <= output_axis_tdest_int; temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index 06b764b8c..9cca872f7 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -44,9 +44,17 @@ def bench(): # Parameters INPUT_DATA_WIDTH = 64 + INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8) INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8) OUTPUT_DATA_WIDTH = 8 + OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8) OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -54,19 +62,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[INPUT_DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[INPUT_KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[INPUT_KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[OUTPUT_DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[OUTPUT_KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[OUTPUT_KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -82,6 +94,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -97,6 +111,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -117,6 +133,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -124,6 +142,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -169,10 +189,14 @@ def bench(): print("test 1: test packet, length %d" % payload_len) current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len)), + id=1, + dest=1, + ) for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame) @@ -197,14 +221,22 @@ def bench(): print("test 2: back-to-back packets, length %d" % payload_len) current_test.next = 2 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len)), + id=2, + dest=1, + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len)), + id=2, + dest=2, + ) for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -234,16 +266,23 @@ def bench(): print("test 3: tuser assert, length %d" % payload_len) current_test.next = 3 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - - test_frame1.user = 1 + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len)), + id=3, + dest=1, + last_cycle_user=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len)), + id=3, + dest=2, + ) for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -260,7 +299,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame1 - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() diff --git a/tb/test_axis_adapter_64_8.v b/tb/test_axis_adapter_64_8.v index acdf7a3c9..2b453eb6b 100644 --- a/tb/test_axis_adapter_64_8.v +++ b/tb/test_axis_adapter_64_8.v @@ -32,10 +32,18 @@ THE SOFTWARE. module test_axis_adapter_64_8; // Parameters -localparam INPUT_DATA_WIDTH = 64; -localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); -localparam OUTPUT_DATA_WIDTH = 8; -localparam OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); +parameter INPUT_DATA_WIDTH = 64; +parameter INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8); +parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); +parameter OUTPUT_DATA_WIDTH = 8; +parameter OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8); +parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -46,7 +54,9 @@ reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0; reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs @@ -55,7 +65,9 @@ wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata; wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -67,6 +79,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready ); @@ -76,6 +90,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -86,9 +102,17 @@ end axis_adapter #( .INPUT_DATA_WIDTH(INPUT_DATA_WIDTH), + .INPUT_KEEP_ENABLE(INPUT_KEEP_ENABLE), .INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH), .OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH), - .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH) + .OUTPUT_KEEP_ENABLE(OUTPUT_KEEP_ENABLE), + .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -99,6 +123,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_axis_tdata(output_axis_tdata), @@ -106,6 +132,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index 846278a02..7aad2a50a 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -44,9 +44,17 @@ def bench(): # Parameters INPUT_DATA_WIDTH = 8 + INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8) INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8) OUTPUT_DATA_WIDTH = 64 + OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8) OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -54,19 +62,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[INPUT_DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[INPUT_KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[INPUT_KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[OUTPUT_DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[OUTPUT_KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[OUTPUT_KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -82,6 +94,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -97,6 +111,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -117,6 +133,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -124,6 +142,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -169,10 +189,14 @@ def bench(): print("test 1: test packet, length %d" % payload_len) current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len)), + id=1, + dest=1, + ) for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame) @@ -197,14 +221,22 @@ def bench(): print("test 2: back-to-back packets, length %d" % payload_len) current_test.next = 2 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len)), + id=2, + dest=1, + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len)), + id=2, + dest=2, + ) for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -234,16 +266,23 @@ def bench(): print("test 3: tuser assert, length %d" % payload_len) current_test.next = 3 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(payload_len))) - - test_frame1.user = 1 + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len)), + id=3, + dest=1, + last_cycle_user=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(payload_len)), + id=3, + dest=2, + ) for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -260,7 +299,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame1 - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() diff --git a/tb/test_axis_adapter_8_64.v b/tb/test_axis_adapter_8_64.v index 910d87fd2..e133176e4 100644 --- a/tb/test_axis_adapter_8_64.v +++ b/tb/test_axis_adapter_8_64.v @@ -32,10 +32,18 @@ THE SOFTWARE. module test_axis_adapter_8_64; // Parameters -localparam INPUT_DATA_WIDTH = 8; -localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); -localparam OUTPUT_DATA_WIDTH = 64; -localparam OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); +parameter INPUT_DATA_WIDTH = 8; +parameter INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8); +parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); +parameter OUTPUT_DATA_WIDTH = 64; +parameter OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8); +parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -46,7 +54,9 @@ reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0; reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs @@ -55,7 +65,9 @@ wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata; wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -67,6 +79,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready ); @@ -76,6 +90,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -86,9 +102,17 @@ end axis_adapter #( .INPUT_DATA_WIDTH(INPUT_DATA_WIDTH), + .INPUT_KEEP_ENABLE(INPUT_KEEP_ENABLE), .INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH), .OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH), - .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH) + .OUTPUT_KEEP_ENABLE(OUTPUT_KEEP_ENABLE), + .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -99,6 +123,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_axis_tdata(output_axis_tdata), @@ -106,6 +132,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); From 9e4aa38750090f042b28cf4c92c83f33eedb8fd3 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:13:53 -0800 Subject: [PATCH 355/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream mux --- rtl/axis_mux.py | 117 +++++-- rtl/axis_mux_4.v | 155 ++++++--- rtl/axis_mux_64.py | 321 ------------------ rtl/axis_mux_64_4.v | 318 ----------------- tb/test_axis_mux_4.py | 189 ++++++++--- tb/test_axis_mux_4.v | 73 +++- ...axis_mux_64_4.py => test_axis_mux_4_64.py} | 187 +++++++--- ...t_axis_mux_64_4.v => test_axis_mux_4_64.v} | 66 +++- 8 files changed, 593 insertions(+), 833 deletions(-) delete mode 100755 rtl/axis_mux_64.py delete mode 100644 rtl/axis_mux_64_4.v rename tb/{test_axis_mux_64_4.py => test_axis_mux_4_64.py} (68%) rename tb/{test_axis_mux_64_4.v => test_axis_mux_4_64.v} (71%) diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 9120d8f3e..2828b7e08 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -71,30 +71,44 @@ THE SOFTWARE. */ module {{name}} # ( - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( input wire clk, input wire rst, - + /* * AXI inputs */ {%- for p in ports %} input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, input wire input_{{p}}_axis_tvalid, output wire input_{{p}}_axis_tready, input wire input_{{p}}_axis_tlast, - input wire input_{{p}}_axis_tuser, + input wire [ID_WIDTH-1:0] input_{{p}}_axis_tid, + input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, + input wire [USER_WIDTH-1:0] input_{{p}}_axis_tuser, {% endfor %} /* * 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, + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser, /* * Control @@ -110,12 +124,15 @@ reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; {%- endfor %} // internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg [ID_WIDTH-1:0] output_axis_tid_int; +reg [DEST_WIDTH-1:0] output_axis_tdest_int; +reg [USER_WIDTH-1:0] output_axis_tuser_int; +wire output_axis_tready_int_early; {% for p in ports %} assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; {%- endfor %} @@ -133,27 +150,36 @@ end // mux for incoming packet reg [DATA_WIDTH-1:0] current_input_tdata; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; +reg [KEEP_WIDTH-1:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg [ID_WIDTH-1:0] current_input_tid; +reg [DEST_WIDTH-1:0] current_input_tdest; +reg [USER_WIDTH-1:0] current_input_tuser; always @* begin case (select_reg) {%- for p in ports %} {{w}}'d{{p}}: begin - current_input_tdata = input_{{p}}_axis_tdata; + current_input_tdata = input_{{p}}_axis_tdata; + current_input_tkeep = input_{{p}}_axis_tkeep; current_input_tvalid = input_{{p}}_axis_tvalid; current_input_tready = input_{{p}}_axis_tready; - current_input_tlast = input_{{p}}_axis_tlast; - current_input_tuser = input_{{p}}_axis_tuser; + current_input_tlast = input_{{p}}_axis_tlast; + current_input_tid = input_{{p}}_axis_tid; + current_input_tdest = input_{{p}}_axis_tdest; + current_input_tuser = input_{{p}}_axis_tuser; end {%- endfor %} default: begin - current_input_tdata = {DATA_WIDTH{1'b0}}; + current_input_tdata = {DATA_WIDTH{1'b0}}; + current_input_tkeep = {KEEP_WIDTH{1'b0}}; current_input_tvalid = 1'b0; current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; + current_input_tlast = 1'b0; + current_input_tid = {ID_WIDTH{1'b0}}; + current_input_tdest = {DEST_WIDTH{1'b0}}; + current_input_tuser = {USER_WIDTH{1'b0}}; end endcase end @@ -186,10 +212,13 @@ always @* begin endcase // pass through selected packet data - output_axis_tdata_int = current_input_tdata; + output_axis_tdata_int = current_input_tdata; + output_axis_tkeep_int = current_input_tkeep; output_axis_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_axis_tlast_int = current_input_tlast; - output_axis_tuser_int = current_input_tuser; + output_axis_tlast_int = current_input_tlast; + output_axis_tid_int = current_input_tid; + output_axis_tdest_int = current_input_tdest; + output_axis_tuser_int = current_input_tuser; end always @(posedge clk) begin @@ -209,25 +238,34 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); @@ -240,7 +278,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin @@ -274,17 +312,26 @@ always @(posedge clk) begin // datapath if (store_axis_int_to_output) begin output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tid_reg <= output_axis_tid_int; + output_axis_tdest_reg <= output_axis_tdest_int; output_axis_tuser_reg <= output_axis_tuser_int; end else if (store_axis_temp_to_output) begin output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end if (store_axis_int_to_temp) begin temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tid_reg <= output_axis_tid_int; + temp_axis_tdest_reg <= output_axis_tdest_int; temp_axis_tuser_reg <= output_axis_tuser_int; end end @@ -292,14 +339,14 @@ end endmodule """) - + output_file.write(t.render( n=ports, w=select_width, name=name, ports=range(ports) )) - + print("Done") if __name__ == "__main__": diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v index 1b2502f03..2337776ca 100644 --- a/rtl/axis_mux_4.v +++ b/rtl/axis_mux_4.v @@ -31,47 +31,70 @@ THE SOFTWARE. */ module axis_mux_4 # ( - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( input wire clk, input wire rst, - + /* * AXI inputs */ input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, input wire input_0_axis_tvalid, output wire input_0_axis_tready, input wire input_0_axis_tlast, - input wire input_0_axis_tuser, + input wire [ID_WIDTH-1:0] input_0_axis_tid, + input wire [DEST_WIDTH-1:0] input_0_axis_tdest, + input wire [USER_WIDTH-1:0] input_0_axis_tuser, input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, input wire input_1_axis_tvalid, output wire input_1_axis_tready, input wire input_1_axis_tlast, - input wire input_1_axis_tuser, + input wire [ID_WIDTH-1:0] input_1_axis_tid, + input wire [DEST_WIDTH-1:0] input_1_axis_tdest, + input wire [USER_WIDTH-1:0] input_1_axis_tuser, input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, input wire input_2_axis_tvalid, output wire input_2_axis_tready, input wire input_2_axis_tlast, - input wire input_2_axis_tuser, + input wire [ID_WIDTH-1:0] input_2_axis_tid, + input wire [DEST_WIDTH-1:0] input_2_axis_tdest, + input wire [USER_WIDTH-1:0] input_2_axis_tuser, input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, input wire input_3_axis_tvalid, output wire input_3_axis_tready, input wire input_3_axis_tlast, - input wire input_3_axis_tuser, + input wire [ID_WIDTH-1:0] input_3_axis_tid, + input wire [DEST_WIDTH-1:0] input_3_axis_tdest, + input wire [USER_WIDTH-1:0] input_3_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, + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser, /* * Control @@ -89,12 +112,15 @@ reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; // internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg [ID_WIDTH-1:0] output_axis_tid_int; +reg [DEST_WIDTH-1:0] output_axis_tdest_int; +reg [USER_WIDTH-1:0] output_axis_tuser_int; +wire output_axis_tready_int_early; assign input_0_axis_tready = input_0_axis_tready_reg; assign input_1_axis_tready = input_1_axis_tready_reg; @@ -115,46 +141,64 @@ end // mux for incoming packet reg [DATA_WIDTH-1:0] current_input_tdata; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; +reg [KEEP_WIDTH-1:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg [ID_WIDTH-1:0] current_input_tid; +reg [DEST_WIDTH-1:0] current_input_tdest; +reg [USER_WIDTH-1:0] current_input_tuser; always @* begin case (select_reg) 2'd0: begin - current_input_tdata = input_0_axis_tdata; + current_input_tdata = input_0_axis_tdata; + current_input_tkeep = input_0_axis_tkeep; current_input_tvalid = input_0_axis_tvalid; current_input_tready = input_0_axis_tready; - current_input_tlast = input_0_axis_tlast; - current_input_tuser = input_0_axis_tuser; + current_input_tlast = input_0_axis_tlast; + current_input_tid = input_0_axis_tid; + current_input_tdest = input_0_axis_tdest; + current_input_tuser = input_0_axis_tuser; end 2'd1: begin - current_input_tdata = input_1_axis_tdata; + current_input_tdata = input_1_axis_tdata; + current_input_tkeep = input_1_axis_tkeep; current_input_tvalid = input_1_axis_tvalid; current_input_tready = input_1_axis_tready; - current_input_tlast = input_1_axis_tlast; - current_input_tuser = input_1_axis_tuser; + current_input_tlast = input_1_axis_tlast; + current_input_tid = input_1_axis_tid; + current_input_tdest = input_1_axis_tdest; + current_input_tuser = input_1_axis_tuser; end 2'd2: begin - current_input_tdata = input_2_axis_tdata; + current_input_tdata = input_2_axis_tdata; + current_input_tkeep = input_2_axis_tkeep; current_input_tvalid = input_2_axis_tvalid; current_input_tready = input_2_axis_tready; - current_input_tlast = input_2_axis_tlast; - current_input_tuser = input_2_axis_tuser; + current_input_tlast = input_2_axis_tlast; + current_input_tid = input_2_axis_tid; + current_input_tdest = input_2_axis_tdest; + current_input_tuser = input_2_axis_tuser; end 2'd3: begin - current_input_tdata = input_3_axis_tdata; + current_input_tdata = input_3_axis_tdata; + current_input_tkeep = input_3_axis_tkeep; current_input_tvalid = input_3_axis_tvalid; current_input_tready = input_3_axis_tready; - current_input_tlast = input_3_axis_tlast; - current_input_tuser = input_3_axis_tuser; + current_input_tlast = input_3_axis_tlast; + current_input_tid = input_3_axis_tid; + current_input_tdest = input_3_axis_tdest; + current_input_tuser = input_3_axis_tuser; end default: begin - current_input_tdata = {DATA_WIDTH{1'b0}}; + current_input_tdata = {DATA_WIDTH{1'b0}}; + current_input_tkeep = {KEEP_WIDTH{1'b0}}; current_input_tvalid = 1'b0; current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; + current_input_tlast = 1'b0; + current_input_tid = {ID_WIDTH{1'b0}}; + current_input_tdest = {DEST_WIDTH{1'b0}}; + current_input_tuser = {USER_WIDTH{1'b0}}; end endcase end @@ -190,10 +234,13 @@ always @* begin endcase // pass through selected packet data - output_axis_tdata_int = current_input_tdata; + output_axis_tdata_int = current_input_tdata; + output_axis_tkeep_int = current_input_tkeep; output_axis_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_axis_tlast_int = current_input_tlast; - output_axis_tuser_int = current_input_tuser; + output_axis_tlast_int = current_input_tlast; + output_axis_tid_int = current_input_tid; + output_axis_tdest_int = current_input_tdest; + output_axis_tuser_int = current_input_tuser; end always @(posedge clk) begin @@ -215,25 +262,34 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); @@ -246,7 +302,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin @@ -280,17 +336,26 @@ always @(posedge clk) begin // datapath if (store_axis_int_to_output) begin output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tid_reg <= output_axis_tid_int; + output_axis_tdest_reg <= output_axis_tdest_int; output_axis_tuser_reg <= output_axis_tuser_int; end else if (store_axis_temp_to_output) begin output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end if (store_axis_int_to_temp) begin temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tid_reg <= output_axis_tid_int; + temp_axis_tdest_reg <= output_axis_tdest_int; temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_mux_64.py b/rtl/axis_mux_64.py deleted file mode 100755 index 6173976a0..000000000 --- a/rtl/axis_mux_64.py +++ /dev/null @@ -1,321 +0,0 @@ -#!/usr/bin/env python -""" -Generates an AXI Stream mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "axis_mux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port AXI Stream mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2017 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream {{n}} port multiplexer (64 bit datapath) - */ -module {{name}} # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ -{%- for p in ports %} - input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, - input wire input_{{p}}_axis_tvalid, - output wire input_{{p}}_axis_tready, - input wire input_{{p}}_axis_tlast, - input wire input_{{p}}_axis_tuser, -{% endfor %} - /* - * AXI output - */ - output wire [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, - - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; -{% for p in ports %} -reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; -{%- endfor %} - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; -{% for p in ports %} -assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; -{%- endfor %} - -// mux for start of packet detection -reg selected_input_tvalid; -always @* begin - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: selected_input_tvalid = input_{{p}}_axis_tvalid; -{%- endfor %} - default: selected_input_tvalid = 1'b0; - endcase -end - -// mux for incoming packet -reg [DATA_WIDTH-1:0] current_input_tdata; -reg [KEEP_WIDTH-1:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_input_tdata = input_{{p}}_axis_tdata; - current_input_tkeep = input_{{p}}_axis_tkeep; - current_input_tvalid = input_{{p}}_axis_tvalid; - current_input_tready = input_{{p}}_axis_tready; - current_input_tlast = input_{{p}}_axis_tlast; - current_input_tuser = input_{{p}}_axis_tuser; - end -{%- endfor %} - default: begin - current_input_tdata = {DATA_WIDTH{1'b0}}; - current_input_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; -{% for p in ports %} - input_{{p}}_axis_tready_next = 1'b0; -{%- endfor %} - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & selected_input_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - end - - // generate ready signal on selected port - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early & frame_next; -{%- endfor %} - endcase - - // pass through selected packet data - output_axis_tdata_int = current_input_tdata; - output_axis_tkeep_int = current_input_tkeep; - output_axis_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_axis_tlast_int = current_input_tlast; - output_axis_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; -{%- for p in ports %} - input_{{p}}_axis_tready_reg <= 1'b0; -{%- endfor %} - end else begin - select_reg <= select_next; - frame_reg <= frame_next; -{%- for p in ports %} - input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; -{%- endfor %} - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_mux_64_4.v b/rtl/axis_mux_64_4.v deleted file mode 100644 index b95e081e9..000000000 --- a/rtl/axis_mux_64_4.v +++ /dev/null @@ -1,318 +0,0 @@ -/* - -Copyright (c) 2014-2017 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream 4 port multiplexer (64 bit datapath) - */ -module axis_mux_64_4 # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ - input wire [DATA_WIDTH-1:0] input_0_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, - input wire input_0_axis_tvalid, - output wire input_0_axis_tready, - input wire input_0_axis_tlast, - input wire input_0_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_1_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, - input wire input_1_axis_tvalid, - output wire input_1_axis_tready, - input wire input_1_axis_tlast, - input wire input_1_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_2_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, - input wire input_2_axis_tvalid, - output wire input_2_axis_tready, - input wire input_2_axis_tlast, - input wire input_2_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_3_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, - input wire input_3_axis_tvalid, - output wire input_3_axis_tready, - input wire input_3_axis_tlast, - input wire input_3_axis_tuser, - - /* - * AXI output - */ - output wire [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, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_axis_tready_reg = 1'b0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 1'b0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -assign input_0_axis_tready = input_0_axis_tready_reg; -assign input_1_axis_tready = input_1_axis_tready_reg; -assign input_2_axis_tready = input_2_axis_tready_reg; -assign input_3_axis_tready = input_3_axis_tready_reg; - -// mux for start of packet detection -reg selected_input_tvalid; -always @* begin - case (select) - 2'd0: selected_input_tvalid = input_0_axis_tvalid; - 2'd1: selected_input_tvalid = input_1_axis_tvalid; - 2'd2: selected_input_tvalid = input_2_axis_tvalid; - 2'd3: selected_input_tvalid = input_3_axis_tvalid; - default: selected_input_tvalid = 1'b0; - endcase -end - -// mux for incoming packet -reg [DATA_WIDTH-1:0] current_input_tdata; -reg [KEEP_WIDTH-1:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 2'd0: begin - current_input_tdata = input_0_axis_tdata; - current_input_tkeep = input_0_axis_tkeep; - current_input_tvalid = input_0_axis_tvalid; - current_input_tready = input_0_axis_tready; - current_input_tlast = input_0_axis_tlast; - current_input_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_tdata = input_1_axis_tdata; - current_input_tkeep = input_1_axis_tkeep; - current_input_tvalid = input_1_axis_tvalid; - current_input_tready = input_1_axis_tready; - current_input_tlast = input_1_axis_tlast; - current_input_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_tdata = input_2_axis_tdata; - current_input_tkeep = input_2_axis_tkeep; - current_input_tvalid = input_2_axis_tvalid; - current_input_tready = input_2_axis_tready; - current_input_tlast = input_2_axis_tlast; - current_input_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_tdata = input_3_axis_tdata; - current_input_tkeep = input_3_axis_tkeep; - current_input_tvalid = input_3_axis_tvalid; - current_input_tready = input_3_axis_tready; - current_input_tlast = input_3_axis_tlast; - current_input_tuser = input_3_axis_tuser; - end - default: begin - current_input_tdata = {DATA_WIDTH{1'b0}}; - current_input_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_axis_tready_next = 1'b0; - input_1_axis_tready_next = 1'b0; - input_2_axis_tready_next = 1'b0; - input_3_axis_tready_next = 1'b0; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & selected_input_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - end - - // generate ready signal on selected port - case (select_next) - 2'd0: input_0_axis_tready_next = output_axis_tready_int_early & frame_next; - 2'd1: input_1_axis_tready_next = output_axis_tready_int_early & frame_next; - 2'd2: input_2_axis_tready_next = output_axis_tready_int_early & frame_next; - 2'd3: input_3_axis_tready_next = output_axis_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_axis_tdata_int = current_input_tdata; - output_axis_tkeep_int = current_input_tkeep; - output_axis_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_axis_tlast_int = current_input_tlast; - output_axis_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_0_axis_tready_reg <= 1'b0; - input_1_axis_tready_reg <= 1'b0; - input_2_axis_tready_reg <= 1'b0; - input_3_axis_tready_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_axis_tready_reg <= input_0_axis_tready_next; - input_1_axis_tready_reg <= input_1_axis_tready_next; - input_2_axis_tready_reg <= input_2_axis_tready_next; - input_3_axis_tready_reg <= input_3_axis_tready_next; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py index 4ec6a3f84..84986e663 100755 --- a/tb/test_axis_mux_4.py +++ b/tb/test_axis_mux_4.py @@ -44,6 +44,14 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -51,21 +59,33 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tuser = Signal(bool(0)) + input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tuser = Signal(bool(0)) + input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tuser = Signal(bool(0)) + input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tuser = Signal(bool(0)) + input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) @@ -79,9 +99,12 @@ def bench(): input_3_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_0_pause = Signal(bool(0)) @@ -96,9 +119,12 @@ def bench(): clk, rst, tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, tvalid=input_0_axis_tvalid, tready=input_0_axis_tready, tlast=input_0_axis_tlast, + tid=input_0_axis_tid, + tdest=input_0_axis_tdest, tuser=input_0_axis_tuser, pause=source_0_pause, name='source_0' @@ -110,9 +136,12 @@ def bench(): clk, rst, tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, tvalid=input_1_axis_tvalid, tready=input_1_axis_tready, tlast=input_1_axis_tlast, + tid=input_1_axis_tid, + tdest=input_1_axis_tdest, tuser=input_1_axis_tuser, pause=source_1_pause, name='source_1' @@ -124,9 +153,12 @@ def bench(): clk, rst, tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, tvalid=input_2_axis_tvalid, tready=input_2_axis_tready, tlast=input_2_axis_tlast, + tid=input_2_axis_tid, + tdest=input_2_axis_tdest, tuser=input_2_axis_tuser, pause=source_2_pause, name='source_2' @@ -138,9 +170,12 @@ def bench(): clk, rst, tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, tvalid=input_3_axis_tvalid, tready=input_3_axis_tready, tlast=input_3_axis_tlast, + tid=input_3_axis_tid, + tdest=input_3_axis_tdest, tuser=input_3_axis_tuser, pause=source_3_pause, name='source_3' @@ -152,9 +187,12 @@ def bench(): clk, rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -171,30 +209,45 @@ def bench(): current_test=current_test, input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, input_0_axis_tvalid=input_0_axis_tvalid, input_0_axis_tready=input_0_axis_tready, input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tid=input_0_axis_tid, + input_0_axis_tdest=input_0_axis_tdest, input_0_axis_tuser=input_0_axis_tuser, input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, input_1_axis_tvalid=input_1_axis_tvalid, input_1_axis_tready=input_1_axis_tready, input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tid=input_1_axis_tid, + input_1_axis_tdest=input_1_axis_tdest, input_1_axis_tuser=input_1_axis_tuser, input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, input_2_axis_tvalid=input_2_axis_tvalid, input_2_axis_tready=input_2_axis_tready, input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tid=input_2_axis_tid, + input_2_axis_tdest=input_2_axis_tdest, input_2_axis_tuser=input_2_axis_tuser, input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, input_3_axis_tvalid=input_3_axis_tvalid, input_3_axis_tready=input_3_axis_tready, input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tid=input_3_axis_tid, + input_3_axis_tdest=input_3_axis_tdest, input_3_axis_tuser=input_3_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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser, enable=enable, @@ -225,10 +278,15 @@ def bench(): select.next = 0 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source_0.send(test_frame) yield clk.posedge @@ -249,10 +307,15 @@ def bench(): select.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=2, + dest=1 + ) + source_1.send(test_frame) yield clk.posedge @@ -273,14 +336,23 @@ def bench(): select.next = 0 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=2 + ) + source_0.send(test_frame1) source_0.send(test_frame2) yield clk.posedge @@ -306,14 +378,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge @@ -340,14 +421,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge @@ -385,14 +475,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge diff --git a/tb/test_axis_mux_4.v b/tb/test_axis_mux_4.v index fa20b519e..792a783b0 100644 --- a/tb/test_axis_mux_4.v +++ b/tb/test_axis_mux_4.v @@ -33,6 +33,14 @@ module test_axis_mux_4; // Parameters parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -40,21 +48,33 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; -reg input_0_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_0_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; -reg input_1_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_1_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; -reg input_2_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_2_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; -reg input_3_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_3_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; reg output_axis_tready = 0; @@ -68,9 +88,12 @@ wire input_2_axis_tready; wire input_3_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -79,20 +102,32 @@ initial begin rst, current_test, input_0_axis_tdata, + input_0_axis_tkeep, input_0_axis_tvalid, input_0_axis_tlast, + input_0_axis_tid, + input_0_axis_tdest, input_0_axis_tuser, input_1_axis_tdata, + input_1_axis_tkeep, input_1_axis_tvalid, input_1_axis_tlast, + input_1_axis_tid, + input_1_axis_tdest, input_1_axis_tuser, input_2_axis_tdata, + input_2_axis_tkeep, input_2_axis_tvalid, input_2_axis_tlast, + input_2_axis_tid, + input_2_axis_tdest, input_2_axis_tuser, input_3_axis_tdata, + input_3_axis_tkeep, input_3_axis_tvalid, input_3_axis_tlast, + input_3_axis_tid, + input_3_axis_tdest, input_3_axis_tuser, output_axis_tready, enable, @@ -104,8 +139,11 @@ initial begin input_2_axis_tready, input_3_axis_tready, output_axis_tdata, + output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -115,37 +153,60 @@ initial begin end axis_mux_4 #( - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .rst(rst), // AXI inputs .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tkeep(input_0_axis_tkeep), .input_0_axis_tvalid(input_0_axis_tvalid), .input_0_axis_tready(input_0_axis_tready), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tid(input_0_axis_tid), + .input_0_axis_tdest(input_0_axis_tdest), .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tkeep(input_1_axis_tkeep), .input_1_axis_tvalid(input_1_axis_tvalid), .input_1_axis_tready(input_1_axis_tready), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tid(input_1_axis_tid), + .input_1_axis_tdest(input_1_axis_tdest), .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tkeep(input_2_axis_tkeep), .input_2_axis_tvalid(input_2_axis_tvalid), .input_2_axis_tready(input_2_axis_tready), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tid(input_2_axis_tid), + .input_2_axis_tdest(input_2_axis_tdest), .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tkeep(input_3_axis_tkeep), .input_3_axis_tvalid(input_3_axis_tvalid), .input_3_axis_tready(input_3_axis_tready), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tid(input_3_axis_tid), + .input_3_axis_tdest(input_3_axis_tdest), .input_3_axis_tuser(input_3_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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), // Control .enable(enable), diff --git a/tb/test_axis_mux_64_4.py b/tb/test_axis_mux_4_64.py similarity index 68% rename from tb/test_axis_mux_64_4.py rename to tb/test_axis_mux_4_64.py index 861413469..c6b879bdf 100755 --- a/tb/test_axis_mux_64_4.py +++ b/tb/test_axis_mux_4_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_mux_64_4' -testbench = 'test_%s' % module +module = 'axis_mux_4' +testbench = 'test_%s_64' % module srcs = [] @@ -44,7 +44,14 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -52,25 +59,33 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tuser = Signal(bool(0)) + input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tuser = Signal(bool(0)) + input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tuser = Signal(bool(0)) + input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tuser = Signal(bool(0)) + input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) @@ -84,10 +99,12 @@ def bench(): input_3_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_0_pause = Signal(bool(0)) @@ -106,6 +123,8 @@ def bench(): tvalid=input_0_axis_tvalid, tready=input_0_axis_tready, tlast=input_0_axis_tlast, + tid=input_0_axis_tid, + tdest=input_0_axis_tdest, tuser=input_0_axis_tuser, pause=source_0_pause, name='source_0' @@ -121,6 +140,8 @@ def bench(): tvalid=input_1_axis_tvalid, tready=input_1_axis_tready, tlast=input_1_axis_tlast, + tid=input_1_axis_tid, + tdest=input_1_axis_tdest, tuser=input_1_axis_tuser, pause=source_1_pause, name='source_1' @@ -136,6 +157,8 @@ def bench(): tvalid=input_2_axis_tvalid, tready=input_2_axis_tready, tlast=input_2_axis_tlast, + tid=input_2_axis_tid, + tdest=input_2_axis_tdest, tuser=input_2_axis_tuser, pause=source_2_pause, name='source_2' @@ -151,6 +174,8 @@ def bench(): tvalid=input_3_axis_tvalid, tready=input_3_axis_tready, tlast=input_3_axis_tlast, + tid=input_3_axis_tid, + tdest=input_3_axis_tdest, tuser=input_3_axis_tuser, pause=source_3_pause, name='source_3' @@ -166,6 +191,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -186,24 +213,32 @@ def bench(): input_0_axis_tvalid=input_0_axis_tvalid, input_0_axis_tready=input_0_axis_tready, input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tid=input_0_axis_tid, + input_0_axis_tdest=input_0_axis_tdest, input_0_axis_tuser=input_0_axis_tuser, input_1_axis_tdata=input_1_axis_tdata, input_1_axis_tkeep=input_1_axis_tkeep, input_1_axis_tvalid=input_1_axis_tvalid, input_1_axis_tready=input_1_axis_tready, input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tid=input_1_axis_tid, + input_1_axis_tdest=input_1_axis_tdest, input_1_axis_tuser=input_1_axis_tuser, input_2_axis_tdata=input_2_axis_tdata, input_2_axis_tkeep=input_2_axis_tkeep, input_2_axis_tvalid=input_2_axis_tvalid, input_2_axis_tready=input_2_axis_tready, input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tid=input_2_axis_tid, + input_2_axis_tdest=input_2_axis_tdest, input_2_axis_tuser=input_2_axis_tuser, input_3_axis_tdata=input_3_axis_tdata, input_3_axis_tkeep=input_3_axis_tkeep, input_3_axis_tvalid=input_3_axis_tvalid, input_3_axis_tready=input_3_axis_tready, input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tid=input_3_axis_tid, + input_3_axis_tdest=input_3_axis_tdest, input_3_axis_tuser=input_3_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -211,6 +246,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser, enable=enable, @@ -241,10 +278,15 @@ def bench(): select.next = 0 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source_0.send(test_frame) yield clk.posedge @@ -265,10 +307,15 @@ def bench(): select.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=2, + dest=1 + ) + source_1.send(test_frame) yield clk.posedge @@ -289,14 +336,23 @@ def bench(): select.next = 0 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=2 + ) + source_0.send(test_frame1) source_0.send(test_frame2) yield clk.posedge @@ -322,14 +378,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge @@ -356,14 +421,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge @@ -401,14 +475,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge diff --git a/tb/test_axis_mux_64_4.v b/tb/test_axis_mux_4_64.v similarity index 71% rename from tb/test_axis_mux_64_4.v rename to tb/test_axis_mux_4_64.v index b513db2b8..bda8ed60b 100644 --- a/tb/test_axis_mux_64_4.v +++ b/tb/test_axis_mux_4_64.v @@ -27,13 +27,20 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_mux_64_4 + * Testbench for axis_mux_4 */ -module test_axis_mux_64_4; +module test_axis_mux_4_64; // Parameters parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -44,22 +51,30 @@ reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; -reg input_0_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_0_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; -reg input_1_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_1_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; -reg input_2_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_2_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; -reg input_3_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_3_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; reg output_axis_tready = 0; @@ -76,7 +91,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -88,21 +105,29 @@ initial begin input_0_axis_tkeep, input_0_axis_tvalid, input_0_axis_tlast, + input_0_axis_tid, + input_0_axis_tdest, input_0_axis_tuser, input_1_axis_tdata, input_1_axis_tkeep, input_1_axis_tvalid, input_1_axis_tlast, + input_1_axis_tid, + input_1_axis_tdest, input_1_axis_tuser, input_2_axis_tdata, input_2_axis_tkeep, input_2_axis_tvalid, input_2_axis_tlast, + input_2_axis_tid, + input_2_axis_tdest, input_2_axis_tuser, input_3_axis_tdata, input_3_axis_tkeep, input_3_axis_tvalid, input_3_axis_tlast, + input_3_axis_tid, + input_3_axis_tdest, input_3_axis_tuser, output_axis_tready, enable, @@ -117,17 +142,26 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); // dump file - $dumpfile("test_axis_mux_64_4.lxt"); - $dumpvars(0, test_axis_mux_64_4); + $dumpfile("test_axis_mux_4_64.lxt"); + $dumpvars(0, test_axis_mux_4_64); end -axis_mux_64_4 #( +axis_mux_4 #( .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -138,24 +172,32 @@ UUT ( .input_0_axis_tvalid(input_0_axis_tvalid), .input_0_axis_tready(input_0_axis_tready), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tid(input_0_axis_tid), + .input_0_axis_tdest(input_0_axis_tdest), .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), .input_1_axis_tkeep(input_1_axis_tkeep), .input_1_axis_tvalid(input_1_axis_tvalid), .input_1_axis_tready(input_1_axis_tready), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tid(input_1_axis_tid), + .input_1_axis_tdest(input_1_axis_tdest), .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), .input_2_axis_tkeep(input_2_axis_tkeep), .input_2_axis_tvalid(input_2_axis_tvalid), .input_2_axis_tready(input_2_axis_tready), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tid(input_2_axis_tid), + .input_2_axis_tdest(input_2_axis_tdest), .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), .input_3_axis_tkeep(input_3_axis_tkeep), .input_3_axis_tvalid(input_3_axis_tvalid), .input_3_axis_tready(input_3_axis_tready), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tid(input_3_axis_tid), + .input_3_axis_tdest(input_3_axis_tdest), .input_3_axis_tuser(input_3_axis_tuser), // AXI output .output_axis_tdata(output_axis_tdata), @@ -163,6 +205,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), // Control .enable(enable), From 57e700f8020f47dc4d313eb6c0675bb8cb25cfcf Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:14:20 -0800 Subject: [PATCH 356/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream demux --- rtl/axis_demux.py | 90 ++++-- rtl/axis_demux_4.v | 128 +++++--- rtl/axis_demux_64.py | 297 ------------------ rtl/axis_demux_64_4.v | 296 ----------------- tb/test_axis_demux_4.py | 189 ++++++++--- tb/test_axis_demux_4.v | 73 ++++- ..._demux_64_4.py => test_axis_demux_4_64.py} | 187 ++++++++--- ...is_demux_64_4.v => test_axis_demux_4_64.v} | 66 +++- 8 files changed, 557 insertions(+), 769 deletions(-) delete mode 100755 rtl/axis_demux_64.py delete mode 100644 rtl/axis_demux_64_4.v rename tb/{test_axis_demux_64_4.py => test_axis_demux_4_64.py} (67%) rename tb/{test_axis_demux_64_4.v => test_axis_demux_4_64.v} (71%) diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index 20e8b21f6..9103247ce 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -71,30 +71,44 @@ THE SOFTWARE. */ module {{name}} # ( - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( input wire clk, 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, - + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, + /* * AXI outputs */ {%- for p in ports %} output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, output wire output_{{p}}_axis_tvalid, input wire output_{{p}}_axis_tready, output wire output_{{p}}_axis_tlast, - output wire output_{{p}}_axis_tuser, + output wire [ID_WIDTH-1:0] output_{{p}}_axis_tid, + output wire [DEST_WIDTH-1:0] output_{{p}}_axis_tdest, + output wire [USER_WIDTH-1:0] output_{{p}}_axis_tuser, {% endfor %} /* * Control @@ -109,12 +123,15 @@ reg frame_reg = 1'b0, frame_next; reg input_axis_tready_reg = 1'b0, input_axis_tready_next; // internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg [ID_WIDTH-1:0] output_axis_tid_int; +reg [DEST_WIDTH-1:0] output_axis_tdest_int; +reg [USER_WIDTH-1:0] output_axis_tuser_int; +wire output_axis_tready_int_early; assign input_axis_tready = input_axis_tready_reg; @@ -157,10 +174,13 @@ always @* begin input_axis_tready_next = output_axis_tready_int_early & frame_next; - output_axis_tdata_int = input_axis_tdata; + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tuser_int = input_axis_tuser; + output_axis_tlast_int = input_axis_tlast; + output_axis_tid_int = input_axis_tid; + output_axis_tdest_int = input_axis_tdest; + output_axis_tuser_int = input_axis_tuser; end always @(posedge clk) begin @@ -176,27 +196,36 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; {%- for p in ports %} reg output_{{p}}_axis_tvalid_reg = 1'b0, output_{{p}}_axis_tvalid_next; {%- endfor %} -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; {% for p in ports %} -assign output_{{p}}_axis_tdata = output_axis_tdata_reg; +assign output_{{p}}_axis_tdata = output_axis_tdata_reg; +assign output_{{p}}_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; -assign output_{{p}}_axis_tlast = output_axis_tlast_reg; -assign output_{{p}}_axis_tuser = output_axis_tuser_reg; +assign output_{{p}}_axis_tlast = output_axis_tlast_reg; +assign output_{{p}}_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_{{p}}_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_{{p}}_axis_tuser = USER_ENABLE ? output_axis_tuser_int : {USER_WIDTH{1'b0}}; {% endfor %} // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & (~current_output_tvalid | ~output_axis_tvalid_int)); @@ -211,7 +240,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (current_output_tready | ~current_output_tvalid) begin @@ -253,17 +282,26 @@ always @(posedge clk) begin // datapath if (store_axis_int_to_output) begin output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tid_reg <= output_axis_tid_int; + output_axis_tdest_reg <= output_axis_tdest_int; output_axis_tuser_reg <= output_axis_tuser_int; end else if (store_axis_temp_to_output) begin output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end if (store_axis_int_to_temp) begin temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tid_reg <= output_axis_tid_int; + temp_axis_tdest_reg <= output_axis_tdest_int; temp_axis_tuser_reg <= output_axis_tuser_int; end end @@ -271,14 +309,14 @@ end endmodule """) - + output_file.write(t.render( n=ports, w=select_width, name=name, ports=range(ports) )) - + print("Done") if __name__ == "__main__": diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v index 5373deeb6..9247fd645 100644 --- a/rtl/axis_demux_4.v +++ b/rtl/axis_demux_4.v @@ -31,47 +31,70 @@ THE SOFTWARE. */ module axis_demux_4 # ( - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( input wire clk, 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, - + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, + /* * AXI outputs */ output wire [DATA_WIDTH-1:0] output_0_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, output wire output_0_axis_tvalid, input wire output_0_axis_tready, output wire output_0_axis_tlast, - output wire output_0_axis_tuser, + output wire [ID_WIDTH-1:0] output_0_axis_tid, + output wire [DEST_WIDTH-1:0] output_0_axis_tdest, + output wire [USER_WIDTH-1:0] output_0_axis_tuser, output wire [DATA_WIDTH-1:0] output_1_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, output wire output_1_axis_tvalid, input wire output_1_axis_tready, output wire output_1_axis_tlast, - output wire output_1_axis_tuser, + output wire [ID_WIDTH-1:0] output_1_axis_tid, + output wire [DEST_WIDTH-1:0] output_1_axis_tdest, + output wire [USER_WIDTH-1:0] output_1_axis_tuser, output wire [DATA_WIDTH-1:0] output_2_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, output wire output_2_axis_tvalid, input wire output_2_axis_tready, output wire output_2_axis_tlast, - output wire output_2_axis_tuser, + output wire [ID_WIDTH-1:0] output_2_axis_tid, + output wire [DEST_WIDTH-1:0] output_2_axis_tdest, + output wire [USER_WIDTH-1:0] output_2_axis_tuser, output wire [DATA_WIDTH-1:0] output_3_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, output wire output_3_axis_tvalid, input wire output_3_axis_tready, output wire output_3_axis_tlast, - output wire output_3_axis_tuser, + output wire [ID_WIDTH-1:0] output_3_axis_tid, + output wire [DEST_WIDTH-1:0] output_3_axis_tdest, + output wire [USER_WIDTH-1:0] output_3_axis_tuser, /* * Control @@ -86,12 +109,15 @@ reg frame_reg = 1'b0, frame_next; reg input_axis_tready_reg = 1'b0, input_axis_tready_next; // internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg [ID_WIDTH-1:0] output_axis_tid_int; +reg [DEST_WIDTH-1:0] output_axis_tdest_int; +reg [USER_WIDTH-1:0] output_axis_tuser_int; +wire output_axis_tready_int_early; assign input_axis_tready = input_axis_tready_reg; @@ -144,10 +170,13 @@ always @* begin input_axis_tready_next = output_axis_tready_int_early & frame_next; - output_axis_tdata_int = input_axis_tdata; + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tuser_int = input_axis_tuser; + output_axis_tlast_int = input_axis_tlast; + output_axis_tid_int = input_axis_tid; + output_axis_tdest_int = input_axis_tdest; + output_axis_tuser_int = input_axis_tuser; end always @(posedge clk) begin @@ -163,43 +192,61 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_0_axis_tvalid_reg = 1'b0, output_0_axis_tvalid_next; reg output_1_axis_tvalid_reg = 1'b0, output_1_axis_tvalid_next; reg output_2_axis_tvalid_reg = 1'b0, output_2_axis_tvalid_next; reg output_3_axis_tvalid_reg = 1'b0, output_3_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_0_axis_tdata = output_axis_tdata_reg; +assign output_0_axis_tdata = output_axis_tdata_reg; +assign output_0_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_0_axis_tvalid = output_0_axis_tvalid_reg; -assign output_0_axis_tlast = output_axis_tlast_reg; -assign output_0_axis_tuser = output_axis_tuser_reg; +assign output_0_axis_tlast = output_axis_tlast_reg; +assign output_0_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_0_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_0_axis_tuser = USER_ENABLE ? output_axis_tuser_int : {USER_WIDTH{1'b0}}; -assign output_1_axis_tdata = output_axis_tdata_reg; +assign output_1_axis_tdata = output_axis_tdata_reg; +assign output_1_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_1_axis_tvalid = output_1_axis_tvalid_reg; -assign output_1_axis_tlast = output_axis_tlast_reg; -assign output_1_axis_tuser = output_axis_tuser_reg; +assign output_1_axis_tlast = output_axis_tlast_reg; +assign output_1_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_1_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_1_axis_tuser = USER_ENABLE ? output_axis_tuser_int : {USER_WIDTH{1'b0}}; -assign output_2_axis_tdata = output_axis_tdata_reg; +assign output_2_axis_tdata = output_axis_tdata_reg; +assign output_2_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_2_axis_tvalid = output_2_axis_tvalid_reg; -assign output_2_axis_tlast = output_axis_tlast_reg; -assign output_2_axis_tuser = output_axis_tuser_reg; +assign output_2_axis_tlast = output_axis_tlast_reg; +assign output_2_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_2_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_2_axis_tuser = USER_ENABLE ? output_axis_tuser_int : {USER_WIDTH{1'b0}}; -assign output_3_axis_tdata = output_axis_tdata_reg; +assign output_3_axis_tdata = output_axis_tdata_reg; +assign output_3_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_3_axis_tvalid = output_3_axis_tvalid_reg; -assign output_3_axis_tlast = output_axis_tlast_reg; -assign output_3_axis_tuser = output_axis_tuser_reg; +assign output_3_axis_tlast = output_axis_tlast_reg; +assign output_3_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_3_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_3_axis_tuser = USER_ENABLE ? output_axis_tuser_int : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & (~current_output_tvalid | ~output_axis_tvalid_int)); @@ -215,7 +262,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (current_output_tready | ~current_output_tvalid) begin @@ -261,17 +308,26 @@ always @(posedge clk) begin // datapath if (store_axis_int_to_output) begin output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tid_reg <= output_axis_tid_int; + output_axis_tdest_reg <= output_axis_tdest_int; output_axis_tuser_reg <= output_axis_tuser_int; end else if (store_axis_temp_to_output) begin output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end if (store_axis_int_to_temp) begin temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tid_reg <= output_axis_tid_int; + temp_axis_tdest_reg <= output_axis_tdest_int; temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_demux_64.py b/rtl/axis_demux_64.py deleted file mode 100755 index 54eca9263..000000000 --- a/rtl/axis_demux_64.py +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/env python -""" -Generates an AXI Stream demux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "axis_demux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port AXI Stream demux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2017 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream {{n}} port demultiplexer (64 bit datapath) - */ -module {{name}} # -( - 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 outputs - */ -{%- for p in ports %} - output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, - output wire output_{{p}}_axis_tvalid, - input wire output_{{p}}_axis_tready, - output wire output_{{p}}_axis_tlast, - output wire output_{{p}}_axis_tuser, -{% endfor %} - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -assign input_axis_tready = input_axis_tready_reg; - -// mux for output control signals -reg current_output_tready; -reg current_output_tvalid; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_output_tvalid = output_{{p}}_axis_tvalid; - current_output_tready = output_{{p}}_axis_tready; - end -{%- endfor %} - default: begin - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_axis_tready_next = 1'b0; - - if (input_axis_tvalid & input_axis_tready) begin - // end of frame detection - if (input_axis_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_axis_tvalid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - end - - input_axis_tready_next = output_axis_tready_int_early & frame_next; - - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tuser_int = input_axis_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; - input_axis_tready_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_axis_tready_reg <= input_axis_tready_next; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -{%- for p in ports %} -reg output_{{p}}_axis_tvalid_reg = 1'b0, output_{{p}}_axis_tvalid_next; -{%- endfor %} -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; -{% for p in ports %} -assign output_{{p}}_axis_tdata = output_axis_tdata_reg; -assign output_{{p}}_axis_tkeep = output_axis_tkeep_reg; -assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; -assign output_{{p}}_axis_tlast = output_axis_tlast_reg; -assign output_{{p}}_axis_tuser = output_axis_tuser_reg; -{% endfor %} -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & (~current_output_tvalid | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source -{%- for p in ports %} - output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_reg; -{%- endfor %} - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output -{%- for p in ports %} - output_{{p}}_axis_tvalid_next = output_axis_tvalid_int & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready -{%- for p in ports %} - output_{{p}}_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin -{%- for p in ports %} - output_{{p}}_axis_tvalid_reg <= 1'b0; -{%- endfor %} - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin -{%- for p in ports %} - output_{{p}}_axis_tvalid_reg <= output_{{p}}_axis_tvalid_next; -{%- endfor %} - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_demux_64_4.v b/rtl/axis_demux_64_4.v deleted file mode 100644 index 164d454cc..000000000 --- a/rtl/axis_demux_64_4.v +++ /dev/null @@ -1,296 +0,0 @@ -/* - -Copyright (c) 2014-2017 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream 4 port demultiplexer (64 bit datapath) - */ -module axis_demux_64_4 # -( - 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 outputs - */ - output wire [DATA_WIDTH-1:0] output_0_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, - output wire output_0_axis_tvalid, - input wire output_0_axis_tready, - output wire output_0_axis_tlast, - output wire output_0_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_1_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, - output wire output_1_axis_tvalid, - input wire output_1_axis_tready, - output wire output_1_axis_tlast, - output wire output_1_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_2_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, - output wire output_2_axis_tvalid, - input wire output_2_axis_tready, - output wire output_2_axis_tlast, - output wire output_2_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_3_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, - output wire output_3_axis_tvalid, - input wire output_3_axis_tready, - output wire output_3_axis_tlast, - output wire output_3_axis_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -assign input_axis_tready = input_axis_tready_reg; - -// mux for output control signals -reg current_output_tready; -reg current_output_tvalid; -always @* begin - case (select_reg) - 2'd0: begin - current_output_tvalid = output_0_axis_tvalid; - current_output_tready = output_0_axis_tready; - end - 2'd1: begin - current_output_tvalid = output_1_axis_tvalid; - current_output_tready = output_1_axis_tready; - end - 2'd2: begin - current_output_tvalid = output_2_axis_tvalid; - current_output_tready = output_2_axis_tready; - end - 2'd3: begin - current_output_tvalid = output_3_axis_tvalid; - current_output_tready = output_3_axis_tready; - end - default: begin - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_axis_tready_next = 1'b0; - - if (input_axis_tvalid & input_axis_tready) begin - // end of frame detection - if (input_axis_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_axis_tvalid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - end - - input_axis_tready_next = output_axis_tready_int_early & frame_next; - - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tuser_int = input_axis_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_axis_tready_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_axis_tready_reg <= input_axis_tready_next; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_0_axis_tvalid_reg = 1'b0, output_0_axis_tvalid_next; -reg output_1_axis_tvalid_reg = 1'b0, output_1_axis_tvalid_next; -reg output_2_axis_tvalid_reg = 1'b0, output_2_axis_tvalid_next; -reg output_3_axis_tvalid_reg = 1'b0, output_3_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_0_axis_tdata = output_axis_tdata_reg; -assign output_0_axis_tkeep = output_axis_tkeep_reg; -assign output_0_axis_tvalid = output_0_axis_tvalid_reg; -assign output_0_axis_tlast = output_axis_tlast_reg; -assign output_0_axis_tuser = output_axis_tuser_reg; - -assign output_1_axis_tdata = output_axis_tdata_reg; -assign output_1_axis_tkeep = output_axis_tkeep_reg; -assign output_1_axis_tvalid = output_1_axis_tvalid_reg; -assign output_1_axis_tlast = output_axis_tlast_reg; -assign output_1_axis_tuser = output_axis_tuser_reg; - -assign output_2_axis_tdata = output_axis_tdata_reg; -assign output_2_axis_tkeep = output_axis_tkeep_reg; -assign output_2_axis_tvalid = output_2_axis_tvalid_reg; -assign output_2_axis_tlast = output_axis_tlast_reg; -assign output_2_axis_tuser = output_axis_tuser_reg; - -assign output_3_axis_tdata = output_axis_tdata_reg; -assign output_3_axis_tkeep = output_axis_tkeep_reg; -assign output_3_axis_tvalid = output_3_axis_tvalid_reg; -assign output_3_axis_tlast = output_axis_tlast_reg; -assign output_3_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & (~current_output_tvalid | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_0_axis_tvalid_next = output_0_axis_tvalid_reg; - output_1_axis_tvalid_next = output_1_axis_tvalid_reg; - output_2_axis_tvalid_next = output_2_axis_tvalid_reg; - output_3_axis_tvalid_next = output_3_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_0_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd0); - output_1_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd1); - output_2_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd2); - output_3_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd3); - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_0_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd0); - output_1_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd1); - output_2_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd2); - output_3_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd3); - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_0_axis_tvalid_reg <= 1'b0; - output_1_axis_tvalid_reg <= 1'b0; - output_2_axis_tvalid_reg <= 1'b0; - output_3_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_0_axis_tvalid_reg <= output_0_axis_tvalid_next; - output_1_axis_tvalid_reg <= output_1_axis_tvalid_next; - output_2_axis_tvalid_reg <= output_2_axis_tvalid_next; - output_3_axis_tvalid_reg <= output_3_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py index 239757853..bc4a58444 100755 --- a/tb/test_axis_demux_4.py +++ b/tb/test_axis_demux_4.py @@ -44,6 +44,14 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -51,9 +59,12 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_0_axis_tready = Signal(bool(0)) output_1_axis_tready = Signal(bool(0)) @@ -67,21 +78,33 @@ def bench(): input_axis_tready = Signal(bool(0)) output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_0_axis_tvalid = Signal(bool(0)) output_0_axis_tlast = Signal(bool(0)) - output_0_axis_tuser = Signal(bool(0)) + output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_1_axis_tvalid = Signal(bool(0)) output_1_axis_tlast = Signal(bool(0)) - output_1_axis_tuser = Signal(bool(0)) + output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_2_axis_tvalid = Signal(bool(0)) output_2_axis_tlast = Signal(bool(0)) - output_2_axis_tuser = Signal(bool(0)) + output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_3_axis_tvalid = Signal(bool(0)) output_3_axis_tlast = Signal(bool(0)) - output_3_axis_tuser = Signal(bool(0)) + output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -96,9 +119,12 @@ def bench(): clk, rst, tdata=input_axis_tdata, + tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -110,9 +136,12 @@ def bench(): clk, rst, tdata=output_0_axis_tdata, + tkeep=output_0_axis_tkeep, tvalid=output_0_axis_tvalid, tready=output_0_axis_tready, tlast=output_0_axis_tlast, + tid=output_0_axis_tid, + tdest=output_0_axis_tdest, tuser=output_0_axis_tuser, pause=sink_0_pause, name='sink_0' @@ -124,9 +153,12 @@ def bench(): clk, rst, tdata=output_1_axis_tdata, + tkeep=output_1_axis_tkeep, tvalid=output_1_axis_tvalid, tready=output_1_axis_tready, tlast=output_1_axis_tlast, + tid=output_1_axis_tid, + tdest=output_1_axis_tdest, tuser=output_1_axis_tuser, pause=sink_1_pause, name='sink_1' @@ -138,9 +170,12 @@ def bench(): clk, rst, tdata=output_2_axis_tdata, + tkeep=output_2_axis_tkeep, tvalid=output_2_axis_tvalid, tready=output_2_axis_tready, tlast=output_2_axis_tlast, + tid=output_2_axis_tid, + tdest=output_2_axis_tdest, tuser=output_2_axis_tuser, pause=sink_2_pause, name='sink_2' @@ -152,9 +187,12 @@ def bench(): clk, rst, tdata=output_3_axis_tdata, + tkeep=output_3_axis_tkeep, tvalid=output_3_axis_tvalid, tready=output_3_axis_tready, tlast=output_3_axis_tlast, + tid=output_3_axis_tid, + tdest=output_3_axis_tdest, tuser=output_3_axis_tuser, pause=sink_3_pause, name='sink_3' @@ -171,30 +209,45 @@ def bench(): 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_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tkeep=output_0_axis_tkeep, output_0_axis_tvalid=output_0_axis_tvalid, output_0_axis_tready=output_0_axis_tready, output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tid=output_0_axis_tid, + output_0_axis_tdest=output_0_axis_tdest, output_0_axis_tuser=output_0_axis_tuser, output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tkeep=output_1_axis_tkeep, output_1_axis_tvalid=output_1_axis_tvalid, output_1_axis_tready=output_1_axis_tready, output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tid=output_1_axis_tid, + output_1_axis_tdest=output_1_axis_tdest, output_1_axis_tuser=output_1_axis_tuser, output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tkeep=output_2_axis_tkeep, output_2_axis_tvalid=output_2_axis_tvalid, output_2_axis_tready=output_2_axis_tready, output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tid=output_2_axis_tid, + output_2_axis_tdest=output_2_axis_tdest, output_2_axis_tuser=output_2_axis_tuser, output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tkeep=output_3_axis_tkeep, output_3_axis_tvalid=output_3_axis_tvalid, output_3_axis_tready=output_3_axis_tready, output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tid=output_3_axis_tid, + output_3_axis_tdest=output_3_axis_tdest, output_3_axis_tuser=output_3_axis_tuser, enable=enable, @@ -225,10 +278,15 @@ def bench(): select.next = 0 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -249,10 +307,15 @@ def bench(): select.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -273,14 +336,23 @@ def bench(): select.next = 0 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -306,14 +378,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -340,14 +421,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -379,14 +469,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge diff --git a/tb/test_axis_demux_4.v b/tb/test_axis_demux_4.v index 4308a3f9a..80c08a16e 100644 --- a/tb/test_axis_demux_4.v +++ b/tb/test_axis_demux_4.v @@ -33,6 +33,14 @@ module test_axis_demux_4; // Parameters parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -40,9 +48,12 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_0_axis_tready = 0; reg output_1_axis_tready = 0; @@ -56,21 +67,33 @@ reg [1:0] select = 0; wire input_axis_tready; wire [DATA_WIDTH-1:0] output_0_axis_tdata; +wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; wire output_0_axis_tvalid; wire output_0_axis_tlast; -wire output_0_axis_tuser; +wire [ID_WIDTH-1:0] output_0_axis_tid; +wire [DEST_WIDTH-1:0] output_0_axis_tdest; +wire [USER_WIDTH-1:0] output_0_axis_tuser; wire [DATA_WIDTH-1:0] output_1_axis_tdata; +wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; wire output_1_axis_tvalid; wire output_1_axis_tlast; -wire output_1_axis_tuser; +wire [ID_WIDTH-1:0] output_1_axis_tid; +wire [DEST_WIDTH-1:0] output_1_axis_tdest; +wire [USER_WIDTH-1:0] output_1_axis_tuser; wire [DATA_WIDTH-1:0] output_2_axis_tdata; +wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; wire output_2_axis_tvalid; wire output_2_axis_tlast; -wire output_2_axis_tuser; +wire [ID_WIDTH-1:0] output_2_axis_tid; +wire [DEST_WIDTH-1:0] output_2_axis_tdest; +wire [USER_WIDTH-1:0] output_2_axis_tuser; wire [DATA_WIDTH-1:0] output_3_axis_tdata; +wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; wire output_3_axis_tvalid; wire output_3_axis_tlast; -wire output_3_axis_tuser; +wire [ID_WIDTH-1:0] output_3_axis_tid; +wire [DEST_WIDTH-1:0] output_3_axis_tdest; +wire [USER_WIDTH-1:0] output_3_axis_tuser; initial begin // myhdl integration @@ -79,8 +102,11 @@ initial begin rst, current_test, input_axis_tdata, + input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_0_axis_tready, output_1_axis_tready, @@ -92,20 +118,32 @@ initial begin $to_myhdl( input_axis_tready, output_0_axis_tdata, + output_0_axis_tkeep, output_0_axis_tvalid, output_0_axis_tlast, + output_0_axis_tid, + output_0_axis_tdest, output_0_axis_tuser, output_1_axis_tdata, + output_1_axis_tkeep, output_1_axis_tvalid, output_1_axis_tlast, + output_1_axis_tid, + output_1_axis_tdest, output_1_axis_tuser, output_2_axis_tdata, + output_2_axis_tkeep, output_2_axis_tvalid, output_2_axis_tlast, + output_2_axis_tid, + output_2_axis_tdest, output_2_axis_tuser, output_3_axis_tdata, + output_3_axis_tkeep, output_3_axis_tvalid, output_3_axis_tlast, + output_3_axis_tid, + output_3_axis_tdest, output_3_axis_tuser ); @@ -115,37 +153,60 @@ initial begin end axis_demux_4 #( - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI outputs .output_0_axis_tdata(output_0_axis_tdata), + .output_0_axis_tkeep(output_0_axis_tkeep), .output_0_axis_tvalid(output_0_axis_tvalid), .output_0_axis_tready(output_0_axis_tready), .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tid(output_0_axis_tid), + .output_0_axis_tdest(output_0_axis_tdest), .output_0_axis_tuser(output_0_axis_tuser), .output_1_axis_tdata(output_1_axis_tdata), + .output_1_axis_tkeep(output_1_axis_tkeep), .output_1_axis_tvalid(output_1_axis_tvalid), .output_1_axis_tready(output_1_axis_tready), .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tid(output_1_axis_tid), + .output_1_axis_tdest(output_1_axis_tdest), .output_1_axis_tuser(output_1_axis_tuser), .output_2_axis_tdata(output_2_axis_tdata), + .output_2_axis_tkeep(output_2_axis_tkeep), .output_2_axis_tvalid(output_2_axis_tvalid), .output_2_axis_tready(output_2_axis_tready), .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tid(output_2_axis_tid), + .output_2_axis_tdest(output_2_axis_tdest), .output_2_axis_tuser(output_2_axis_tuser), .output_3_axis_tdata(output_3_axis_tdata), + .output_3_axis_tkeep(output_3_axis_tkeep), .output_3_axis_tvalid(output_3_axis_tvalid), .output_3_axis_tready(output_3_axis_tready), .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tid(output_3_axis_tid), + .output_3_axis_tdest(output_3_axis_tdest), .output_3_axis_tuser(output_3_axis_tuser), // Control .enable(enable), diff --git a/tb/test_axis_demux_64_4.py b/tb/test_axis_demux_4_64.py similarity index 67% rename from tb/test_axis_demux_64_4.py rename to tb/test_axis_demux_4_64.py index 054d142e2..ab18a8382 100755 --- a/tb/test_axis_demux_64_4.py +++ b/tb/test_axis_demux_4_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_demux_64_4' -testbench = 'test_%s' % module +module = 'axis_demux_4' +testbench = 'test_%s_64' % module srcs = [] @@ -44,7 +44,14 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -52,10 +59,12 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_0_axis_tready = Signal(bool(0)) output_1_axis_tready = Signal(bool(0)) @@ -69,25 +78,33 @@ def bench(): input_axis_tready = Signal(bool(0)) output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_0_axis_tvalid = Signal(bool(0)) output_0_axis_tlast = Signal(bool(0)) - output_0_axis_tuser = Signal(bool(0)) + output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_1_axis_tvalid = Signal(bool(0)) output_1_axis_tlast = Signal(bool(0)) - output_1_axis_tuser = Signal(bool(0)) + output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_2_axis_tvalid = Signal(bool(0)) output_2_axis_tlast = Signal(bool(0)) - output_2_axis_tuser = Signal(bool(0)) + output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_3_axis_tvalid = Signal(bool(0)) output_3_axis_tlast = Signal(bool(0)) - output_3_axis_tuser = Signal(bool(0)) + output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -106,6 +123,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -121,6 +140,8 @@ def bench(): tvalid=output_0_axis_tvalid, tready=output_0_axis_tready, tlast=output_0_axis_tlast, + tid=output_0_axis_tid, + tdest=output_0_axis_tdest, tuser=output_0_axis_tuser, pause=sink_0_pause, name='sink_0' @@ -136,6 +157,8 @@ def bench(): tvalid=output_1_axis_tvalid, tready=output_1_axis_tready, tlast=output_1_axis_tlast, + tid=output_1_axis_tid, + tdest=output_1_axis_tdest, tuser=output_1_axis_tuser, pause=sink_1_pause, name='sink_1' @@ -151,6 +174,8 @@ def bench(): tvalid=output_2_axis_tvalid, tready=output_2_axis_tready, tlast=output_2_axis_tlast, + tid=output_2_axis_tid, + tdest=output_2_axis_tdest, tuser=output_2_axis_tuser, pause=sink_2_pause, name='sink_2' @@ -166,6 +191,8 @@ def bench(): tvalid=output_3_axis_tvalid, tready=output_3_axis_tready, tlast=output_3_axis_tlast, + tid=output_3_axis_tid, + tdest=output_3_axis_tdest, tuser=output_3_axis_tuser, pause=sink_3_pause, name='sink_3' @@ -186,6 +213,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_0_axis_tdata=output_0_axis_tdata, @@ -193,24 +222,32 @@ def bench(): output_0_axis_tvalid=output_0_axis_tvalid, output_0_axis_tready=output_0_axis_tready, output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tid=output_0_axis_tid, + output_0_axis_tdest=output_0_axis_tdest, output_0_axis_tuser=output_0_axis_tuser, output_1_axis_tdata=output_1_axis_tdata, output_1_axis_tkeep=output_1_axis_tkeep, output_1_axis_tvalid=output_1_axis_tvalid, output_1_axis_tready=output_1_axis_tready, output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tid=output_1_axis_tid, + output_1_axis_tdest=output_1_axis_tdest, output_1_axis_tuser=output_1_axis_tuser, output_2_axis_tdata=output_2_axis_tdata, output_2_axis_tkeep=output_2_axis_tkeep, output_2_axis_tvalid=output_2_axis_tvalid, output_2_axis_tready=output_2_axis_tready, output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tid=output_2_axis_tid, + output_2_axis_tdest=output_2_axis_tdest, output_2_axis_tuser=output_2_axis_tuser, output_3_axis_tdata=output_3_axis_tdata, output_3_axis_tkeep=output_3_axis_tkeep, output_3_axis_tvalid=output_3_axis_tvalid, output_3_axis_tready=output_3_axis_tready, output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tid=output_3_axis_tid, + output_3_axis_tdest=output_3_axis_tdest, output_3_axis_tuser=output_3_axis_tuser, enable=enable, @@ -241,10 +278,15 @@ def bench(): select.next = 0 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -265,10 +307,15 @@ def bench(): select.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -289,14 +336,23 @@ def bench(): select.next = 0 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -322,14 +378,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -356,14 +421,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -395,14 +469,23 @@ def bench(): select.next = 1 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge diff --git a/tb/test_axis_demux_64_4.v b/tb/test_axis_demux_4_64.v similarity index 71% rename from tb/test_axis_demux_64_4.v rename to tb/test_axis_demux_4_64.v index c57bb39f5..bd2824693 100644 --- a/tb/test_axis_demux_64_4.v +++ b/tb/test_axis_demux_4_64.v @@ -27,13 +27,20 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_demux_64_4 + * Testbench for axis_demux_4 */ -module test_axis_demux_64_4; +module test_axis_demux_4_64; // Parameters parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -44,7 +51,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_0_axis_tready = 0; reg output_1_axis_tready = 0; @@ -61,22 +70,30 @@ wire [DATA_WIDTH-1:0] output_0_axis_tdata; wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; wire output_0_axis_tvalid; wire output_0_axis_tlast; -wire output_0_axis_tuser; +wire [ID_WIDTH-1:0] output_0_axis_tid; +wire [DEST_WIDTH-1:0] output_0_axis_tdest; +wire [USER_WIDTH-1:0] output_0_axis_tuser; wire [DATA_WIDTH-1:0] output_1_axis_tdata; wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; wire output_1_axis_tvalid; wire output_1_axis_tlast; -wire output_1_axis_tuser; +wire [ID_WIDTH-1:0] output_1_axis_tid; +wire [DEST_WIDTH-1:0] output_1_axis_tdest; +wire [USER_WIDTH-1:0] output_1_axis_tuser; wire [DATA_WIDTH-1:0] output_2_axis_tdata; wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; wire output_2_axis_tvalid; wire output_2_axis_tlast; -wire output_2_axis_tuser; +wire [ID_WIDTH-1:0] output_2_axis_tid; +wire [DEST_WIDTH-1:0] output_2_axis_tdest; +wire [USER_WIDTH-1:0] output_2_axis_tuser; wire [DATA_WIDTH-1:0] output_3_axis_tdata; wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; wire output_3_axis_tvalid; wire output_3_axis_tlast; -wire output_3_axis_tuser; +wire [ID_WIDTH-1:0] output_3_axis_tid; +wire [DEST_WIDTH-1:0] output_3_axis_tdest; +wire [USER_WIDTH-1:0] output_3_axis_tuser; initial begin // myhdl integration @@ -88,6 +105,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_0_axis_tready, output_1_axis_tready, @@ -102,32 +121,47 @@ initial begin output_0_axis_tkeep, output_0_axis_tvalid, output_0_axis_tlast, + output_0_axis_tid, + output_0_axis_tdest, output_0_axis_tuser, output_1_axis_tdata, output_1_axis_tkeep, output_1_axis_tvalid, output_1_axis_tlast, + output_1_axis_tid, + output_1_axis_tdest, output_1_axis_tuser, output_2_axis_tdata, output_2_axis_tkeep, output_2_axis_tvalid, output_2_axis_tlast, + output_2_axis_tid, + output_2_axis_tdest, output_2_axis_tuser, output_3_axis_tdata, output_3_axis_tkeep, output_3_axis_tvalid, output_3_axis_tlast, + output_3_axis_tid, + output_3_axis_tdest, output_3_axis_tuser ); // dump file - $dumpfile("test_axis_demux_64_4.lxt"); - $dumpvars(0, test_axis_demux_64_4); + $dumpfile("test_axis_demux_4_64.lxt"); + $dumpvars(0, test_axis_demux_4_64); end -axis_demux_64_4 #( +axis_demux_4 #( .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -138,6 +172,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI outputs .output_0_axis_tdata(output_0_axis_tdata), @@ -145,24 +181,32 @@ UUT ( .output_0_axis_tvalid(output_0_axis_tvalid), .output_0_axis_tready(output_0_axis_tready), .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tid(output_0_axis_tid), + .output_0_axis_tdest(output_0_axis_tdest), .output_0_axis_tuser(output_0_axis_tuser), .output_1_axis_tdata(output_1_axis_tdata), .output_1_axis_tkeep(output_1_axis_tkeep), .output_1_axis_tvalid(output_1_axis_tvalid), .output_1_axis_tready(output_1_axis_tready), .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tid(output_1_axis_tid), + .output_1_axis_tdest(output_1_axis_tdest), .output_1_axis_tuser(output_1_axis_tuser), .output_2_axis_tdata(output_2_axis_tdata), .output_2_axis_tkeep(output_2_axis_tkeep), .output_2_axis_tvalid(output_2_axis_tvalid), .output_2_axis_tready(output_2_axis_tready), .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tid(output_2_axis_tid), + .output_2_axis_tdest(output_2_axis_tdest), .output_2_axis_tuser(output_2_axis_tuser), .output_3_axis_tdata(output_3_axis_tdata), .output_3_axis_tkeep(output_3_axis_tkeep), .output_3_axis_tvalid(output_3_axis_tvalid), .output_3_axis_tready(output_3_axis_tready), .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tid(output_3_axis_tid), + .output_3_axis_tdest(output_3_axis_tdest), .output_3_axis_tuser(output_3_axis_tuser), // Control .enable(enable), From 496c63bd1c33ca57e0719884e3eb6bcd1831e1ca Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:15:08 -0800 Subject: [PATCH 357/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream arbitrated mux --- rtl/axis_arb_mux.py | 40 +++- rtl/axis_arb_mux_4.v | 60 ++++- rtl/axis_arb_mux_64.py | 174 -------------- rtl/axis_arb_mux_64_4.v | 160 ------------- tb/test_axis_arb_mux_4.py | 214 +++++++++++++----- tb/test_axis_arb_mux_4.v | 75 +++++- ..._mux_64_4.py => test_axis_arb_mux_4_64.py} | 214 +++++++++++++----- ...rb_mux_64_4.v => test_axis_arb_mux_4_64.v} | 71 ++++-- 8 files changed, 527 insertions(+), 481 deletions(-) delete mode 100755 rtl/axis_arb_mux_64.py delete mode 100644 rtl/axis_arb_mux_64_4.v rename tb/{test_axis_arb_mux_64_4.py => test_axis_arb_mux_4_64.py} (67%) rename tb/{test_axis_arb_mux_64_4.v => test_axis_arb_mux_4_64.v} (69%) diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index b8300a2f2..d969c130b 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -72,6 +72,14 @@ THE SOFTWARE. module {{name}} # ( parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, // arbitration type: "PRIORITY" or "ROUND_ROBIN" parameter ARB_TYPE = "PRIORITY", // LSB priority: "LOW", "HIGH" @@ -80,25 +88,31 @@ module {{name}} # ( input wire clk, input wire rst, - + /* * AXI inputs */ {%- for p in ports %} input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, input wire input_{{p}}_axis_tvalid, output wire input_{{p}}_axis_tready, input wire input_{{p}}_axis_tlast, - input wire input_{{p}}_axis_tuser, + input wire [ID_WIDTH-1:0] input_{{p}}_axis_tid, + input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, + input wire [USER_WIDTH-1:0] input_{{p}}_axis_tuser, {% endfor %} /* * 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 + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser ); wire [{{n-1}}:0] request; @@ -113,22 +127,36 @@ assign request[{{p}}] = input_{{p}}_axis_tvalid & ~acknowledge[{{p}}]; // mux instance axis_mux_{{n}} #( - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) mux_inst ( .clk(clk), .rst(rst), {%- for p in ports %} .input_{{p}}_axis_tdata(input_{{p}}_axis_tdata), + .input_{{p}}_axis_tkeep(input_{{p}}_axis_tkeep), .input_{{p}}_axis_tvalid(input_{{p}}_axis_tvalid & grant[{{p}}]), .input_{{p}}_axis_tready(input_{{p}}_axis_tready), .input_{{p}}_axis_tlast(input_{{p}}_axis_tlast), + .input_{{p}}_axis_tid(input_{{p}}_axis_tid), + .input_{{p}}_axis_tdest(input_{{p}}_axis_tdest), .input_{{p}}_axis_tuser(input_{{p}}_axis_tuser), {%- endfor %} .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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), .enable(grant_valid), .select(grant_encoded) @@ -154,14 +182,14 @@ arb_inst ( endmodule """) - + output_file.write(t.render( n=ports, w=select_width, name=name, ports=range(ports) )) - + print("Done") if __name__ == "__main__": diff --git a/rtl/axis_arb_mux_4.v b/rtl/axis_arb_mux_4.v index 4e6df5b9d..61d1bcd8f 100644 --- a/rtl/axis_arb_mux_4.v +++ b/rtl/axis_arb_mux_4.v @@ -32,6 +32,14 @@ THE SOFTWARE. module axis_arb_mux_4 # ( parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, // arbitration type: "PRIORITY" or "ROUND_ROBIN" parameter ARB_TYPE = "PRIORITY", // LSB priority: "LOW", "HIGH" @@ -40,42 +48,57 @@ module axis_arb_mux_4 # ( input wire clk, input wire rst, - + /* * AXI inputs */ input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, input wire input_0_axis_tvalid, output wire input_0_axis_tready, input wire input_0_axis_tlast, - input wire input_0_axis_tuser, + input wire [ID_WIDTH-1:0] input_0_axis_tid, + input wire [DEST_WIDTH-1:0] input_0_axis_tdest, + input wire [USER_WIDTH-1:0] input_0_axis_tuser, input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, input wire input_1_axis_tvalid, output wire input_1_axis_tready, input wire input_1_axis_tlast, - input wire input_1_axis_tuser, + input wire [ID_WIDTH-1:0] input_1_axis_tid, + input wire [DEST_WIDTH-1:0] input_1_axis_tdest, + input wire [USER_WIDTH-1:0] input_1_axis_tuser, input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, input wire input_2_axis_tvalid, output wire input_2_axis_tready, input wire input_2_axis_tlast, - input wire input_2_axis_tuser, + input wire [ID_WIDTH-1:0] input_2_axis_tid, + input wire [DEST_WIDTH-1:0] input_2_axis_tdest, + input wire [USER_WIDTH-1:0] input_2_axis_tuser, input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, input wire input_3_axis_tvalid, output wire input_3_axis_tready, input wire input_3_axis_tlast, - input wire input_3_axis_tuser, + input wire [ID_WIDTH-1:0] input_3_axis_tid, + input wire [DEST_WIDTH-1:0] input_3_axis_tdest, + input wire [USER_WIDTH-1:0] input_3_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 + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser ); wire [3:0] request; @@ -95,35 +118,58 @@ assign request[3] = input_3_axis_tvalid & ~acknowledge[3]; // mux instance axis_mux_4 #( - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) mux_inst ( .clk(clk), .rst(rst), .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tkeep(input_0_axis_tkeep), .input_0_axis_tvalid(input_0_axis_tvalid & grant[0]), .input_0_axis_tready(input_0_axis_tready), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tid(input_0_axis_tid), + .input_0_axis_tdest(input_0_axis_tdest), .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tkeep(input_1_axis_tkeep), .input_1_axis_tvalid(input_1_axis_tvalid & grant[1]), .input_1_axis_tready(input_1_axis_tready), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tid(input_1_axis_tid), + .input_1_axis_tdest(input_1_axis_tdest), .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tkeep(input_2_axis_tkeep), .input_2_axis_tvalid(input_2_axis_tvalid & grant[2]), .input_2_axis_tready(input_2_axis_tready), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tid(input_2_axis_tid), + .input_2_axis_tdest(input_2_axis_tdest), .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tkeep(input_3_axis_tkeep), .input_3_axis_tvalid(input_3_axis_tvalid & grant[3]), .input_3_axis_tready(input_3_axis_tready), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tid(input_3_axis_tid), + .input_3_axis_tdest(input_3_axis_tdest), .input_3_axis_tuser(input_3_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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), .enable(grant_valid), .select(grant_encoded) diff --git a/rtl/axis_arb_mux_64.py b/rtl/axis_arb_mux_64.py deleted file mode 100755 index bb2bed92f..000000000 --- a/rtl/axis_arb_mux_64.py +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env python -""" -Generates an arbitrated AXI Stream mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "axis_arb_mux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2017 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream {{n}} port arbitrated multiplexer (64 bit datapath) - */ -module {{name}} # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8), - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ -{%- for p in ports %} - input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, - input wire input_{{p}}_axis_tvalid, - output wire input_{{p}}_axis_tready, - input wire input_{{p}}_axis_tlast, - input wire input_{{p}}_axis_tuser, -{% endfor %} - /* - * AXI output - */ - output wire [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 -); - -wire [{{n-1}}:0] request; -wire [{{n-1}}:0] acknowledge; -wire [{{n-1}}:0] grant; -wire grant_valid; -wire [{{w-1}}:0] grant_encoded; -{% for p in ports %} -assign acknowledge[{{p}}] = input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast; -assign request[{{p}}] = input_{{p}}_axis_tvalid & ~acknowledge[{{p}}]; -{%- endfor %} - -// mux instance -axis_mux_64_{{n}} #( - .DATA_WIDTH(DATA_WIDTH) -) -mux_inst ( - .clk(clk), - .rst(rst), -{%- for p in ports %} - .input_{{p}}_axis_tdata(input_{{p}}_axis_tdata), - .input_{{p}}_axis_tkeep(input_{{p}}_axis_tkeep), - .input_{{p}}_axis_tvalid(input_{{p}}_axis_tvalid & grant[{{p}}]), - .input_{{p}}_axis_tready(input_{{p}}_axis_tready), - .input_{{p}}_axis_tlast(input_{{p}}_axis_tlast), - .input_{{p}}_axis_tuser(input_{{p}}_axis_tuser), -{%- endfor %} - .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), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS({{n}}), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_arb_mux_64_4.v b/rtl/axis_arb_mux_64_4.v deleted file mode 100644 index ca8197d0c..000000000 --- a/rtl/axis_arb_mux_64_4.v +++ /dev/null @@ -1,160 +0,0 @@ -/* - -Copyright (c) 2014-2017 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream 4 port arbitrated multiplexer (64 bit datapath) - */ -module axis_arb_mux_64_4 # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8), - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ - input wire [DATA_WIDTH-1:0] input_0_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, - input wire input_0_axis_tvalid, - output wire input_0_axis_tready, - input wire input_0_axis_tlast, - input wire input_0_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_1_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, - input wire input_1_axis_tvalid, - output wire input_1_axis_tready, - input wire input_1_axis_tlast, - input wire input_1_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_2_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, - input wire input_2_axis_tvalid, - output wire input_2_axis_tready, - input wire input_2_axis_tlast, - input wire input_2_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_3_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, - input wire input_3_axis_tvalid, - output wire input_3_axis_tready, - input wire input_3_axis_tlast, - input wire input_3_axis_tuser, - - /* - * AXI output - */ - output wire [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 -); - -wire [3:0] request; -wire [3:0] acknowledge; -wire [3:0] grant; -wire grant_valid; -wire [1:0] grant_encoded; - -assign acknowledge[0] = input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign request[0] = input_0_axis_tvalid & ~acknowledge[0]; -assign acknowledge[1] = input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign request[1] = input_1_axis_tvalid & ~acknowledge[1]; -assign acknowledge[2] = input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign request[2] = input_2_axis_tvalid & ~acknowledge[2]; -assign acknowledge[3] = input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; -assign request[3] = input_3_axis_tvalid & ~acknowledge[3]; - -// mux instance -axis_mux_64_4 #( - .DATA_WIDTH(DATA_WIDTH) -) -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tkeep(input_0_axis_tkeep), - .input_0_axis_tvalid(input_0_axis_tvalid & grant[0]), - .input_0_axis_tready(input_0_axis_tready), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tkeep(input_1_axis_tkeep), - .input_1_axis_tvalid(input_1_axis_tvalid & grant[1]), - .input_1_axis_tready(input_1_axis_tready), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tkeep(input_2_axis_tkeep), - .input_2_axis_tvalid(input_2_axis_tvalid & grant[2]), - .input_2_axis_tready(input_2_axis_tready), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tkeep(input_3_axis_tkeep), - .input_3_axis_tvalid(input_3_axis_tvalid & grant[3]), - .input_3_axis_tready(input_3_axis_tready), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tuser(input_3_axis_tuser), - .output_axis_tdata(output_axis_tdata), - .output_axis_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), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index 8a307fbb2..68ebfaa53 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -47,6 +47,14 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -54,21 +62,33 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tuser = Signal(bool(0)) + input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tuser = Signal(bool(0)) + input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tuser = Signal(bool(0)) + input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tuser = Signal(bool(0)) + input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) @@ -79,9 +99,12 @@ def bench(): input_3_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_0_pause = Signal(bool(0)) @@ -96,9 +119,12 @@ def bench(): clk, rst, tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, tvalid=input_0_axis_tvalid, tready=input_0_axis_tready, tlast=input_0_axis_tlast, + tid=input_0_axis_tid, + tdest=input_0_axis_tdest, tuser=input_0_axis_tuser, pause=source_0_pause, name='source_0' @@ -110,9 +136,12 @@ def bench(): clk, rst, tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, tvalid=input_1_axis_tvalid, tready=input_1_axis_tready, tlast=input_1_axis_tlast, + tid=input_1_axis_tid, + tdest=input_1_axis_tdest, tuser=input_1_axis_tuser, pause=source_1_pause, name='source_1' @@ -124,9 +153,12 @@ def bench(): clk, rst, tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, tvalid=input_2_axis_tvalid, tready=input_2_axis_tready, tlast=input_2_axis_tlast, + tid=input_2_axis_tid, + tdest=input_2_axis_tdest, tuser=input_2_axis_tuser, pause=source_2_pause, name='source_2' @@ -138,9 +170,12 @@ def bench(): clk, rst, tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, tvalid=input_3_axis_tvalid, tready=input_3_axis_tready, tlast=input_3_axis_tlast, + tid=input_3_axis_tid, + tdest=input_3_axis_tdest, tuser=input_3_axis_tuser, pause=source_3_pause, name='source_3' @@ -152,9 +187,12 @@ def bench(): clk, rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -171,30 +209,45 @@ def bench(): current_test=current_test, input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, input_0_axis_tvalid=input_0_axis_tvalid, input_0_axis_tready=input_0_axis_tready, input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tid=input_0_axis_tid, + input_0_axis_tdest=input_0_axis_tdest, input_0_axis_tuser=input_0_axis_tuser, input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, input_1_axis_tvalid=input_1_axis_tvalid, input_1_axis_tready=input_1_axis_tready, input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tid=input_1_axis_tid, + input_1_axis_tdest=input_1_axis_tdest, input_1_axis_tuser=input_1_axis_tuser, input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, input_2_axis_tvalid=input_2_axis_tvalid, input_2_axis_tready=input_2_axis_tready, input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tid=input_2_axis_tid, + input_2_axis_tdest=input_2_axis_tdest, input_2_axis_tuser=input_2_axis_tuser, input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, input_3_axis_tvalid=input_3_axis_tvalid, input_3_axis_tready=input_3_axis_tready, input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tid=input_3_axis_tid, + input_3_axis_tdest=input_3_axis_tdest, input_3_axis_tuser=input_3_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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -219,10 +272,15 @@ def bench(): print("test 1: port 0") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x00\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x00\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', + id=1, + dest=1 + ) + source_0.send(test_frame) yield clk.posedge @@ -241,10 +299,15 @@ def bench(): print("test 2: port 1") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x01\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x00\x52\x53\x54\x55' + + b'\x80\x01' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=2, + dest=1 + ) + source_1.send(test_frame) yield clk.posedge @@ -263,14 +326,23 @@ def bench(): print("test 3: back-to-back packets, same port") current_test.next = 3 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x00\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x00\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x00\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', + id=3, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x00\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', + id=3, + dest=2 + ) + source_0.send(test_frame1) source_0.send(test_frame2) yield clk.posedge @@ -294,14 +366,23 @@ def bench(): print("test 4: back-to-back packets, different ports") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x01\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x02\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x01\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', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x02\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', + id=4, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge @@ -325,14 +406,23 @@ def bench(): print("test 5: alterate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x01\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x02\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x01\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', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x02\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', + id=5, + dest=1 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge @@ -367,14 +457,23 @@ def bench(): print("test 6: alterate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x01\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x02\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x01\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', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x02\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', + id=6, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge @@ -403,14 +502,23 @@ def bench(): print("test 7: back-to-back packets, different ports, arbitration test") current_test.next = 7 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x01\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x02\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x01\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', + id=7, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x02\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', + id=7, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) source_2.send(test_frame2) diff --git a/tb/test_axis_arb_mux_4.v b/tb/test_axis_arb_mux_4.v index 1c1774fc3..0d36dc26b 100644 --- a/tb/test_axis_arb_mux_4.v +++ b/tb/test_axis_arb_mux_4.v @@ -32,7 +32,15 @@ THE SOFTWARE. module test_axis_arb_mux_4; // Parameters -localparam DATA_WIDTH = 8; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -40,21 +48,33 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; -reg input_0_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_0_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; -reg input_1_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_1_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; -reg input_2_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_2_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; -reg input_3_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_3_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; reg output_axis_tready = 0; @@ -65,9 +85,12 @@ wire input_2_axis_tready; wire input_3_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -76,20 +99,32 @@ initial begin rst, current_test, input_0_axis_tdata, + input_0_axis_tkeep, input_0_axis_tvalid, input_0_axis_tlast, + input_0_axis_tid, + input_0_axis_tdest, input_0_axis_tuser, input_1_axis_tdata, + input_1_axis_tkeep, input_1_axis_tvalid, input_1_axis_tlast, + input_1_axis_tid, + input_1_axis_tdest, input_1_axis_tuser, input_2_axis_tdata, + input_2_axis_tkeep, input_2_axis_tvalid, input_2_axis_tlast, + input_2_axis_tid, + input_2_axis_tdest, input_2_axis_tuser, input_3_axis_tdata, + input_3_axis_tkeep, input_3_axis_tvalid, input_3_axis_tlast, + input_3_axis_tid, + input_3_axis_tdest, input_3_axis_tuser, output_axis_tready ); @@ -99,8 +134,11 @@ initial begin input_2_axis_tready, input_3_axis_tready, output_axis_tdata, + output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -110,37 +148,60 @@ initial begin end axis_arb_mux_4 #( - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .rst(rst), // AXI inputs .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tkeep(input_0_axis_tkeep), .input_0_axis_tvalid(input_0_axis_tvalid), .input_0_axis_tready(input_0_axis_tready), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tid(input_0_axis_tid), + .input_0_axis_tdest(input_0_axis_tdest), .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tkeep(input_1_axis_tkeep), .input_1_axis_tvalid(input_1_axis_tvalid), .input_1_axis_tready(input_1_axis_tready), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tid(input_1_axis_tid), + .input_1_axis_tdest(input_1_axis_tdest), .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tkeep(input_2_axis_tkeep), .input_2_axis_tvalid(input_2_axis_tvalid), .input_2_axis_tready(input_2_axis_tready), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tid(input_2_axis_tid), + .input_2_axis_tdest(input_2_axis_tdest), .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tkeep(input_3_axis_tkeep), .input_3_axis_tvalid(input_3_axis_tvalid), .input_3_axis_tready(input_3_axis_tready), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tid(input_3_axis_tid), + .input_3_axis_tdest(input_3_axis_tdest), .input_3_axis_tuser(input_3_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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); diff --git a/tb/test_axis_arb_mux_64_4.py b/tb/test_axis_arb_mux_4_64.py similarity index 67% rename from tb/test_axis_arb_mux_64_4.py rename to tb/test_axis_arb_mux_4_64.py index 6d70511da..31353e8a0 100755 --- a/tb/test_axis_arb_mux_64_4.py +++ b/tb/test_axis_arb_mux_4_64.py @@ -28,13 +28,13 @@ import os import axis_ep -module = 'axis_arb_mux_64_4' -testbench = 'test_%s' % module +module = 'axis_arb_mux_4' +testbench = 'test_%s_64' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axis_mux_64_4.v") +srcs.append("../rtl/axis_mux_4.v") srcs.append("../rtl/arbiter.v") srcs.append("../rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -47,7 +47,14 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -55,25 +62,33 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tuser = Signal(bool(0)) + input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tuser = Signal(bool(0)) + input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tuser = Signal(bool(0)) + input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tuser = Signal(bool(0)) + input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) @@ -84,10 +99,12 @@ def bench(): input_3_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_0_pause = Signal(bool(0)) @@ -106,6 +123,8 @@ def bench(): tvalid=input_0_axis_tvalid, tready=input_0_axis_tready, tlast=input_0_axis_tlast, + tid=input_0_axis_tid, + tdest=input_0_axis_tdest, tuser=input_0_axis_tuser, pause=source_0_pause, name='source_0' @@ -121,6 +140,8 @@ def bench(): tvalid=input_1_axis_tvalid, tready=input_1_axis_tready, tlast=input_1_axis_tlast, + tid=input_1_axis_tid, + tdest=input_1_axis_tdest, tuser=input_1_axis_tuser, pause=source_1_pause, name='source_1' @@ -136,6 +157,8 @@ def bench(): tvalid=input_2_axis_tvalid, tready=input_2_axis_tready, tlast=input_2_axis_tlast, + tid=input_2_axis_tid, + tdest=input_2_axis_tdest, tuser=input_2_axis_tuser, pause=source_2_pause, name='source_2' @@ -151,6 +174,8 @@ def bench(): tvalid=input_3_axis_tvalid, tready=input_3_axis_tready, tlast=input_3_axis_tlast, + tid=input_3_axis_tid, + tdest=input_3_axis_tdest, tuser=input_3_axis_tuser, pause=source_3_pause, name='source_3' @@ -166,6 +191,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -186,24 +213,32 @@ def bench(): input_0_axis_tvalid=input_0_axis_tvalid, input_0_axis_tready=input_0_axis_tready, input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tid=input_0_axis_tid, + input_0_axis_tdest=input_0_axis_tdest, input_0_axis_tuser=input_0_axis_tuser, input_1_axis_tdata=input_1_axis_tdata, input_1_axis_tkeep=input_1_axis_tkeep, input_1_axis_tvalid=input_1_axis_tvalid, input_1_axis_tready=input_1_axis_tready, input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tid=input_1_axis_tid, + input_1_axis_tdest=input_1_axis_tdest, input_1_axis_tuser=input_1_axis_tuser, input_2_axis_tdata=input_2_axis_tdata, input_2_axis_tkeep=input_2_axis_tkeep, input_2_axis_tvalid=input_2_axis_tvalid, input_2_axis_tready=input_2_axis_tready, input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tid=input_2_axis_tid, + input_2_axis_tdest=input_2_axis_tdest, input_2_axis_tuser=input_2_axis_tuser, input_3_axis_tdata=input_3_axis_tdata, input_3_axis_tkeep=input_3_axis_tkeep, input_3_axis_tvalid=input_3_axis_tvalid, input_3_axis_tready=input_3_axis_tready, input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tid=input_3_axis_tid, + input_3_axis_tdest=input_3_axis_tdest, input_3_axis_tuser=input_3_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -211,6 +246,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -235,10 +272,15 @@ def bench(): print("test 1: port 0") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x00\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x00\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', + id=1, + dest=1 + ) + source_0.send(test_frame) yield clk.posedge @@ -257,10 +299,15 @@ def bench(): print("test 2: port 1") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x01\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x00\x52\x53\x54\x55' + + b'\x80\x01' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=2, + dest=1 + ) + source_1.send(test_frame) yield clk.posedge @@ -279,14 +326,23 @@ def bench(): print("test 3: back-to-back packets, same port") current_test.next = 3 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x00\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x00\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x00\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', + id=3, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x00\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', + id=3, + dest=2 + ) + source_0.send(test_frame1) source_0.send(test_frame2) yield clk.posedge @@ -310,14 +366,23 @@ def bench(): print("test 4: back-to-back packets, different ports") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x01\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x02\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x01\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', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x02\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', + id=4, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge @@ -341,14 +406,23 @@ def bench(): print("test 5: alterate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x01\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x02\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x01\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', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x02\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', + id=5, + dest=1 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge @@ -383,14 +457,23 @@ def bench(): print("test 6: alterate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x01\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x02\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x01\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', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x02\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', + id=6, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) yield clk.posedge @@ -419,14 +502,23 @@ def bench(): print("test 7: back-to-back packets, different ports, arbitration test") current_test.next = 7 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x01\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x02\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x01\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', + id=7, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x02\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', + id=7, + dest=2 + ) + source_1.send(test_frame1) source_2.send(test_frame2) source_2.send(test_frame2) diff --git a/tb/test_axis_arb_mux_64_4.v b/tb/test_axis_arb_mux_4_64.v similarity index 69% rename from tb/test_axis_arb_mux_64_4.v rename to tb/test_axis_arb_mux_4_64.v index 0480f3c31..4b73bbc2f 100644 --- a/tb/test_axis_arb_mux_64_4.v +++ b/tb/test_axis_arb_mux_4_64.v @@ -27,13 +27,20 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_arb_mux_64_4 + * Testbench for axis_arb_mux_4 */ -module test_axis_arb_mux_64_4; +module test_axis_arb_mux_4_64; // Parameters -localparam DATA_WIDTH = 64; -localparam KEEP_WIDTH = (DATA_WIDTH/8); +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -44,22 +51,30 @@ reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; -reg input_0_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_0_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; -reg input_1_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_1_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; -reg input_2_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_2_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; -reg input_3_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_3_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; reg output_axis_tready = 0; @@ -73,7 +88,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -85,21 +102,29 @@ initial begin input_0_axis_tkeep, input_0_axis_tvalid, input_0_axis_tlast, + input_0_axis_tid, + input_0_axis_tdest, input_0_axis_tuser, input_1_axis_tdata, input_1_axis_tkeep, input_1_axis_tvalid, input_1_axis_tlast, + input_1_axis_tid, + input_1_axis_tdest, input_1_axis_tuser, input_2_axis_tdata, input_2_axis_tkeep, input_2_axis_tvalid, input_2_axis_tlast, + input_2_axis_tid, + input_2_axis_tdest, input_2_axis_tuser, input_3_axis_tdata, input_3_axis_tkeep, input_3_axis_tvalid, input_3_axis_tlast, + input_3_axis_tid, + input_3_axis_tdest, input_3_axis_tuser, output_axis_tready ); @@ -112,16 +137,26 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); // dump file - $dumpfile("test_axis_arb_mux_64_4.lxt"); - $dumpvars(0, test_axis_arb_mux_64_4); + $dumpfile("test_axis_arb_mux_4_64.lxt"); + $dumpvars(0, test_axis_arb_mux_4_64); end -axis_arb_mux_64_4 #( - .DATA_WIDTH(DATA_WIDTH) +axis_arb_mux_4 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -132,24 +167,32 @@ UUT ( .input_0_axis_tvalid(input_0_axis_tvalid), .input_0_axis_tready(input_0_axis_tready), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tid(input_0_axis_tid), + .input_0_axis_tdest(input_0_axis_tdest), .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), .input_1_axis_tkeep(input_1_axis_tkeep), .input_1_axis_tvalid(input_1_axis_tvalid), .input_1_axis_tready(input_1_axis_tready), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tid(input_1_axis_tid), + .input_1_axis_tdest(input_1_axis_tdest), .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), .input_2_axis_tkeep(input_2_axis_tkeep), .input_2_axis_tvalid(input_2_axis_tvalid), .input_2_axis_tready(input_2_axis_tready), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tid(input_2_axis_tid), + .input_2_axis_tdest(input_2_axis_tdest), .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), .input_3_axis_tkeep(input_3_axis_tkeep), .input_3_axis_tvalid(input_3_axis_tvalid), .input_3_axis_tready(input_3_axis_tready), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tid(input_3_axis_tid), + .input_3_axis_tdest(input_3_axis_tdest), .input_3_axis_tuser(input_3_axis_tuser), // AXI output .output_axis_tdata(output_axis_tdata), @@ -157,6 +200,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); From 91a7169f466f85c9fd31c54846a6dbeaac4b6003 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:16:21 -0800 Subject: [PATCH 358/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream crosspoint --- rtl/axis_crosspoint.py | 63 ++- rtl/axis_crosspoint_4x4.v | 224 ++++++++--- rtl/axis_crosspoint_64.py | 206 ---------- rtl/axis_crosspoint_64_4x4.v | 367 ------------------ tb/test_axis_crosspoint_4x4.py | 115 +++++- tb/test_axis_crosspoint_4x4.v | 108 +++++- ..._4x4.py => test_axis_crosspoint_4x4_64.py} | 110 ++++-- ...64_4x4.v => test_axis_crosspoint_4x4_64.v} | 92 ++++- 8 files changed, 580 insertions(+), 705 deletions(-) delete mode 100755 rtl/axis_crosspoint_64.py delete mode 100644 rtl/axis_crosspoint_64_4x4.v rename tb/{test_axis_crosspoint_64_4x4.py => test_axis_crosspoint_4x4_64.py} (77%) rename tb/{test_axis_crosspoint_64_4x4.v => test_axis_crosspoint_4x4_64.v} (68%) diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index 8236f739f..ce3982979 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -78,29 +78,44 @@ THE SOFTWARE. */ module {{name}} # ( - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI Stream inputs */ {%- for p in range(m) %} input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, input wire input_{{p}}_axis_tvalid, input wire input_{{p}}_axis_tlast, - input wire input_{{p}}_axis_tuser, + input wire [ID_WIDTH-1:0] input_{{p}}_axis_tid, + input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, + input wire [USER_WIDTH-1:0] input_{{p}}_axis_tuser, {% endfor %} /* * AXI Stream outputs */ {%- for p in range(n) %} output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, output wire output_{{p}}_axis_tvalid, output wire output_{{p}}_axis_tlast, - output wire output_{{p}}_axis_tuser, + output wire [ID_WIDTH-1:0] output_{{p}}_axis_tid, + output wire [DEST_WIDTH-1:0] output_{{p}}_axis_tdest, + output wire [USER_WIDTH-1:0] output_{{p}}_axis_tuser, {% endfor %} /* * Control @@ -110,29 +125,37 @@ module {{name}} # {%- endfor %} ); {% for p in range(m) %} -reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg input_{{p}}_axis_tvalid_reg = 1'b0; -reg input_{{p}}_axis_tlast_reg = 1'b0; -reg input_{{p}}_axis_tuser_reg = 1'b0; +reg input_{{p}}_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_{{p}}_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_{{p}}_axis_tuser_reg = {USER_WIDTH{1'b0}}; {% endfor %} {%- for p in range(n) %} -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_{{p}}_axis_tvalid_reg = 1'b0; -reg output_{{p}}_axis_tlast_reg = 1'b0; -reg output_{{p}}_axis_tuser_reg = 1'b0; +reg output_{{p}}_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_{{p}}_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_{{p}}_axis_tuser_reg = {USER_WIDTH{1'b0}}; {% endfor %} {%- for p in range(n) %} reg [{{w-1}}:0] output_{{p}}_select_reg = {{w}}'d0; {%- endfor %} {% for p in range(n) %} -assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; +assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; +assign output_{{p}}_axis_tkeep = KEEP_ENABLE ? output_{{p}}_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; -assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; -assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; +assign output_{{p}}_axis_tlast = LAST_ENABLE ? output_{{p}}_axis_tlast_reg : 1'b1; +assign output_{{p}}_axis_tid = ID_ENABLE ? output_{{p}}_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_{{p}}_axis_tdest = DEST_ENABLE ? output_{{p}}_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_{{p}}_axis_tuser = USER_ENABLE ? output_{{p}}_axis_tuser_reg : {USER_WIDTH{1'b0}}; {% endfor %} - always @(posedge clk) begin if (rst) begin {%- for p in range(n) %} @@ -163,7 +186,10 @@ always @(posedge clk) begin {%- for p in range(m) %} input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; + input_{{p}}_axis_tkeep_reg <= input_{{p}}_axis_tkeep; input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; + input_{{p}}_axis_tid_reg <= input_{{p}}_axis_tid; + input_{{p}}_axis_tdest_reg <= input_{{p}}_axis_tdest; input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; {%- endfor %} {%- for p in range(n) %} @@ -172,7 +198,10 @@ always @(posedge clk) begin {%- for q in range(m) %} {{w}}'d{{q}}: begin output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; + output_{{p}}_axis_tkeep_reg <= input_{{q}}_axis_tkeep_reg; output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; + output_{{p}}_axis_tid_reg <= input_{{q}}_axis_tid_reg; + output_{{p}}_axis_tdest_reg <= input_{{q}}_axis_tdest_reg; output_{{p}}_axis_tuser_reg <= input_{{q}}_axis_tuser_reg; end {%- endfor %} @@ -183,14 +212,14 @@ end endmodule """) - + output_file.write(t.render( m=m, n=n, w=select_width, name=name )) - + print("Done") if __name__ == "__main__": diff --git a/rtl/axis_crosspoint_4x4.v b/rtl/axis_crosspoint_4x4.v index 03e897db1..2242813c8 100644 --- a/rtl/axis_crosspoint_4x4.v +++ b/rtl/axis_crosspoint_4x4.v @@ -31,57 +31,90 @@ THE SOFTWARE. */ module axis_crosspoint_4x4 # ( - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI Stream inputs */ input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, input wire input_0_axis_tvalid, input wire input_0_axis_tlast, - input wire input_0_axis_tuser, + input wire [ID_WIDTH-1:0] input_0_axis_tid, + input wire [DEST_WIDTH-1:0] input_0_axis_tdest, + input wire [USER_WIDTH-1:0] input_0_axis_tuser, input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, input wire input_1_axis_tvalid, input wire input_1_axis_tlast, - input wire input_1_axis_tuser, + input wire [ID_WIDTH-1:0] input_1_axis_tid, + input wire [DEST_WIDTH-1:0] input_1_axis_tdest, + input wire [USER_WIDTH-1:0] input_1_axis_tuser, input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, input wire input_2_axis_tvalid, input wire input_2_axis_tlast, - input wire input_2_axis_tuser, + input wire [ID_WIDTH-1:0] input_2_axis_tid, + input wire [DEST_WIDTH-1:0] input_2_axis_tdest, + input wire [USER_WIDTH-1:0] input_2_axis_tuser, input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, input wire input_3_axis_tvalid, input wire input_3_axis_tlast, - input wire input_3_axis_tuser, + input wire [ID_WIDTH-1:0] input_3_axis_tid, + input wire [DEST_WIDTH-1:0] input_3_axis_tdest, + input wire [USER_WIDTH-1:0] input_3_axis_tuser, /* * AXI Stream outputs */ output wire [DATA_WIDTH-1:0] output_0_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, output wire output_0_axis_tvalid, output wire output_0_axis_tlast, - output wire output_0_axis_tuser, + output wire [ID_WIDTH-1:0] output_0_axis_tid, + output wire [DEST_WIDTH-1:0] output_0_axis_tdest, + output wire [USER_WIDTH-1:0] output_0_axis_tuser, output wire [DATA_WIDTH-1:0] output_1_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, output wire output_1_axis_tvalid, output wire output_1_axis_tlast, - output wire output_1_axis_tuser, + output wire [ID_WIDTH-1:0] output_1_axis_tid, + output wire [DEST_WIDTH-1:0] output_1_axis_tdest, + output wire [USER_WIDTH-1:0] output_1_axis_tuser, output wire [DATA_WIDTH-1:0] output_2_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, output wire output_2_axis_tvalid, output wire output_2_axis_tlast, - output wire output_2_axis_tuser, + output wire [ID_WIDTH-1:0] output_2_axis_tid, + output wire [DEST_WIDTH-1:0] output_2_axis_tdest, + output wire [USER_WIDTH-1:0] output_2_axis_tuser, output wire [DATA_WIDTH-1:0] output_3_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, output wire output_3_axis_tvalid, output wire output_3_axis_tlast, - output wire output_3_axis_tuser, + output wire [ID_WIDTH-1:0] output_3_axis_tid, + output wire [DEST_WIDTH-1:0] output_3_axis_tdest, + output wire [USER_WIDTH-1:0] output_3_axis_tuser, /* * Control @@ -92,71 +125,106 @@ module axis_crosspoint_4x4 # input wire [1:0] output_3_select ); -reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg input_0_axis_tvalid_reg = 1'b0; -reg input_0_axis_tlast_reg = 1'b0; -reg input_0_axis_tuser_reg = 1'b0; +reg input_0_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_0_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_0_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg input_1_axis_tvalid_reg = 1'b0; -reg input_1_axis_tlast_reg = 1'b0; -reg input_1_axis_tuser_reg = 1'b0; +reg input_1_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_1_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_1_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg input_2_axis_tvalid_reg = 1'b0; -reg input_2_axis_tlast_reg = 1'b0; -reg input_2_axis_tuser_reg = 1'b0; +reg input_2_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_2_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_2_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg input_3_axis_tvalid_reg = 1'b0; -reg input_3_axis_tlast_reg = 1'b0; -reg input_3_axis_tuser_reg = 1'b0; +reg input_3_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_3_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_3_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_0_axis_tvalid_reg = 1'b0; -reg output_0_axis_tlast_reg = 1'b0; -reg output_0_axis_tuser_reg = 1'b0; +reg output_0_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_0_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_0_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_1_axis_tvalid_reg = 1'b0; -reg output_1_axis_tlast_reg = 1'b0; -reg output_1_axis_tuser_reg = 1'b0; +reg output_1_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_1_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_1_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_2_axis_tvalid_reg = 1'b0; -reg output_2_axis_tlast_reg = 1'b0; -reg output_2_axis_tuser_reg = 1'b0; +reg output_2_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_2_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_2_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_3_axis_tvalid_reg = 1'b0; -reg output_3_axis_tlast_reg = 1'b0; -reg output_3_axis_tuser_reg = 1'b0; +reg output_3_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_3_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_3_axis_tuser_reg = {USER_WIDTH{1'b0}}; reg [1:0] output_0_select_reg = 2'd0; reg [1:0] output_1_select_reg = 2'd0; reg [1:0] output_2_select_reg = 2'd0; reg [1:0] output_3_select_reg = 2'd0; -assign output_0_axis_tdata = output_0_axis_tdata_reg; +assign output_0_axis_tdata = output_0_axis_tdata_reg; +assign output_0_axis_tkeep = KEEP_ENABLE ? output_0_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_0_axis_tvalid = output_0_axis_tvalid_reg; -assign output_0_axis_tlast = output_0_axis_tlast_reg; -assign output_0_axis_tuser = output_0_axis_tuser_reg; +assign output_0_axis_tlast = LAST_ENABLE ? output_0_axis_tlast_reg : 1'b1; +assign output_0_axis_tid = ID_ENABLE ? output_0_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_0_axis_tdest = DEST_ENABLE ? output_0_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_0_axis_tuser = USER_ENABLE ? output_0_axis_tuser_reg : {USER_WIDTH{1'b0}}; -assign output_1_axis_tdata = output_1_axis_tdata_reg; +assign output_1_axis_tdata = output_1_axis_tdata_reg; +assign output_1_axis_tkeep = KEEP_ENABLE ? output_1_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_1_axis_tvalid = output_1_axis_tvalid_reg; -assign output_1_axis_tlast = output_1_axis_tlast_reg; -assign output_1_axis_tuser = output_1_axis_tuser_reg; +assign output_1_axis_tlast = LAST_ENABLE ? output_1_axis_tlast_reg : 1'b1; +assign output_1_axis_tid = ID_ENABLE ? output_1_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_1_axis_tdest = DEST_ENABLE ? output_1_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_1_axis_tuser = USER_ENABLE ? output_1_axis_tuser_reg : {USER_WIDTH{1'b0}}; -assign output_2_axis_tdata = output_2_axis_tdata_reg; +assign output_2_axis_tdata = output_2_axis_tdata_reg; +assign output_2_axis_tkeep = KEEP_ENABLE ? output_2_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_2_axis_tvalid = output_2_axis_tvalid_reg; -assign output_2_axis_tlast = output_2_axis_tlast_reg; -assign output_2_axis_tuser = output_2_axis_tuser_reg; +assign output_2_axis_tlast = LAST_ENABLE ? output_2_axis_tlast_reg : 1'b1; +assign output_2_axis_tid = ID_ENABLE ? output_2_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_2_axis_tdest = DEST_ENABLE ? output_2_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_2_axis_tuser = USER_ENABLE ? output_2_axis_tuser_reg : {USER_WIDTH{1'b0}}; -assign output_3_axis_tdata = output_3_axis_tdata_reg; +assign output_3_axis_tdata = output_3_axis_tdata_reg; +assign output_3_axis_tkeep = KEEP_ENABLE ? output_3_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_3_axis_tvalid = output_3_axis_tvalid_reg; -assign output_3_axis_tlast = output_3_axis_tlast_reg; -assign output_3_axis_tuser = output_3_axis_tuser_reg; - +assign output_3_axis_tlast = LAST_ENABLE ? output_3_axis_tlast_reg : 1'b1; +assign output_3_axis_tid = ID_ENABLE ? output_3_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_3_axis_tdest = DEST_ENABLE ? output_3_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_3_axis_tuser = USER_ENABLE ? output_3_axis_tuser_reg : {USER_WIDTH{1'b0}}; always @(posedge clk) begin if (rst) begin @@ -215,40 +283,64 @@ always @(posedge clk) begin end input_0_axis_tdata_reg <= input_0_axis_tdata; + input_0_axis_tkeep_reg <= input_0_axis_tkeep; input_0_axis_tlast_reg <= input_0_axis_tlast; + input_0_axis_tid_reg <= input_0_axis_tid; + input_0_axis_tdest_reg <= input_0_axis_tdest; input_0_axis_tuser_reg <= input_0_axis_tuser; input_1_axis_tdata_reg <= input_1_axis_tdata; + input_1_axis_tkeep_reg <= input_1_axis_tkeep; input_1_axis_tlast_reg <= input_1_axis_tlast; + input_1_axis_tid_reg <= input_1_axis_tid; + input_1_axis_tdest_reg <= input_1_axis_tdest; input_1_axis_tuser_reg <= input_1_axis_tuser; input_2_axis_tdata_reg <= input_2_axis_tdata; + input_2_axis_tkeep_reg <= input_2_axis_tkeep; input_2_axis_tlast_reg <= input_2_axis_tlast; + input_2_axis_tid_reg <= input_2_axis_tid; + input_2_axis_tdest_reg <= input_2_axis_tdest; input_2_axis_tuser_reg <= input_2_axis_tuser; input_3_axis_tdata_reg <= input_3_axis_tdata; + input_3_axis_tkeep_reg <= input_3_axis_tkeep; input_3_axis_tlast_reg <= input_3_axis_tlast; + input_3_axis_tid_reg <= input_3_axis_tid; + input_3_axis_tdest_reg <= input_3_axis_tdest; input_3_axis_tuser_reg <= input_3_axis_tuser; case (output_0_select_reg) 2'd0: begin output_0_axis_tdata_reg <= input_0_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_0_axis_tkeep_reg; output_0_axis_tlast_reg <= input_0_axis_tlast_reg; + output_0_axis_tid_reg <= input_0_axis_tid_reg; + output_0_axis_tdest_reg <= input_0_axis_tdest_reg; output_0_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_0_axis_tdata_reg <= input_1_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_1_axis_tkeep_reg; output_0_axis_tlast_reg <= input_1_axis_tlast_reg; + output_0_axis_tid_reg <= input_1_axis_tid_reg; + output_0_axis_tdest_reg <= input_1_axis_tdest_reg; output_0_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_0_axis_tdata_reg <= input_2_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_2_axis_tkeep_reg; output_0_axis_tlast_reg <= input_2_axis_tlast_reg; + output_0_axis_tid_reg <= input_2_axis_tid_reg; + output_0_axis_tdest_reg <= input_2_axis_tdest_reg; output_0_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_0_axis_tdata_reg <= input_3_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_3_axis_tkeep_reg; output_0_axis_tlast_reg <= input_3_axis_tlast_reg; + output_0_axis_tid_reg <= input_3_axis_tid_reg; + output_0_axis_tdest_reg <= input_3_axis_tdest_reg; output_0_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase @@ -256,22 +348,34 @@ always @(posedge clk) begin case (output_1_select_reg) 2'd0: begin output_1_axis_tdata_reg <= input_0_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_0_axis_tkeep_reg; output_1_axis_tlast_reg <= input_0_axis_tlast_reg; + output_1_axis_tid_reg <= input_0_axis_tid_reg; + output_1_axis_tdest_reg <= input_0_axis_tdest_reg; output_1_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_1_axis_tdata_reg <= input_1_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_1_axis_tkeep_reg; output_1_axis_tlast_reg <= input_1_axis_tlast_reg; + output_1_axis_tid_reg <= input_1_axis_tid_reg; + output_1_axis_tdest_reg <= input_1_axis_tdest_reg; output_1_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_1_axis_tdata_reg <= input_2_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_2_axis_tkeep_reg; output_1_axis_tlast_reg <= input_2_axis_tlast_reg; + output_1_axis_tid_reg <= input_2_axis_tid_reg; + output_1_axis_tdest_reg <= input_2_axis_tdest_reg; output_1_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_1_axis_tdata_reg <= input_3_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_3_axis_tkeep_reg; output_1_axis_tlast_reg <= input_3_axis_tlast_reg; + output_1_axis_tid_reg <= input_3_axis_tid_reg; + output_1_axis_tdest_reg <= input_3_axis_tdest_reg; output_1_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase @@ -279,22 +383,34 @@ always @(posedge clk) begin case (output_2_select_reg) 2'd0: begin output_2_axis_tdata_reg <= input_0_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_0_axis_tkeep_reg; output_2_axis_tlast_reg <= input_0_axis_tlast_reg; + output_2_axis_tid_reg <= input_0_axis_tid_reg; + output_2_axis_tdest_reg <= input_0_axis_tdest_reg; output_2_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_2_axis_tdata_reg <= input_1_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_1_axis_tkeep_reg; output_2_axis_tlast_reg <= input_1_axis_tlast_reg; + output_2_axis_tid_reg <= input_1_axis_tid_reg; + output_2_axis_tdest_reg <= input_1_axis_tdest_reg; output_2_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_2_axis_tdata_reg <= input_2_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_2_axis_tkeep_reg; output_2_axis_tlast_reg <= input_2_axis_tlast_reg; + output_2_axis_tid_reg <= input_2_axis_tid_reg; + output_2_axis_tdest_reg <= input_2_axis_tdest_reg; output_2_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_2_axis_tdata_reg <= input_3_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_3_axis_tkeep_reg; output_2_axis_tlast_reg <= input_3_axis_tlast_reg; + output_2_axis_tid_reg <= input_3_axis_tid_reg; + output_2_axis_tdest_reg <= input_3_axis_tdest_reg; output_2_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase @@ -302,22 +418,34 @@ always @(posedge clk) begin case (output_3_select_reg) 2'd0: begin output_3_axis_tdata_reg <= input_0_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_0_axis_tkeep_reg; output_3_axis_tlast_reg <= input_0_axis_tlast_reg; + output_3_axis_tid_reg <= input_0_axis_tid_reg; + output_3_axis_tdest_reg <= input_0_axis_tdest_reg; output_3_axis_tuser_reg <= input_0_axis_tuser_reg; end 2'd1: begin output_3_axis_tdata_reg <= input_1_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_1_axis_tkeep_reg; output_3_axis_tlast_reg <= input_1_axis_tlast_reg; + output_3_axis_tid_reg <= input_1_axis_tid_reg; + output_3_axis_tdest_reg <= input_1_axis_tdest_reg; output_3_axis_tuser_reg <= input_1_axis_tuser_reg; end 2'd2: begin output_3_axis_tdata_reg <= input_2_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_2_axis_tkeep_reg; output_3_axis_tlast_reg <= input_2_axis_tlast_reg; + output_3_axis_tid_reg <= input_2_axis_tid_reg; + output_3_axis_tdest_reg <= input_2_axis_tdest_reg; output_3_axis_tuser_reg <= input_2_axis_tuser_reg; end 2'd3: begin output_3_axis_tdata_reg <= input_3_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_3_axis_tkeep_reg; output_3_axis_tlast_reg <= input_3_axis_tlast_reg; + output_3_axis_tid_reg <= input_3_axis_tid_reg; + output_3_axis_tdest_reg <= input_3_axis_tdest_reg; output_3_axis_tuser_reg <= input_3_axis_tuser_reg; end endcase diff --git a/rtl/axis_crosspoint_64.py b/rtl/axis_crosspoint_64.py deleted file mode 100755 index fdad13f94..000000000 --- a/rtl/axis_crosspoint_64.py +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env python -""" -Generates an AXI Stream crosspoint switch with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=[4], nargs='+', help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if type(ports) is int: - m = n = ports - elif len(ports) == 1: - m = n = ports[0] - else: - m, n = ports - - if name is None: - name = "axis_crosspoint_64_{0}x{1}".format(m, n) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0}x{1} port AXI Stream crosspoint {2}...".format(m, n, name)) - - select_width = int(math.ceil(math.log(m, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2017 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 {{m}}x{{n}} crosspoint (64 bit datapath) - */ -module {{name}} # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI Stream inputs - */ -{%- for p in range(m) %} - input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, - input wire input_{{p}}_axis_tvalid, - input wire input_{{p}}_axis_tlast, - input wire input_{{p}}_axis_tuser, -{% endfor %} - /* - * AXI Stream outputs - */ -{%- for p in range(n) %} - output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, - output wire output_{{p}}_axis_tvalid, - output wire output_{{p}}_axis_tlast, - output wire output_{{p}}_axis_tuser, -{% endfor %} - /* - * Control - */ -{%- for p in range(n) %} - input wire [{{w-1}}:0] output_{{p}}_select{% if not loop.last %},{% endif %} -{%- endfor %} -); -{% for p in range(m) %} -reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_{{p}}_axis_tvalid_reg = 1'b0; -reg input_{{p}}_axis_tlast_reg = 1'b0; -reg input_{{p}}_axis_tuser_reg = 1'b0; -{% endfor %} - -{%- for p in range(n) %} -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_{{p}}_axis_tvalid_reg = 1'b0; -reg output_{{p}}_axis_tlast_reg = 1'b0; -reg output_{{p}}_axis_tuser_reg = 1'b0; -{% endfor %} - -{%- for p in range(n) %} -reg [{{w-1}}:0] output_{{p}}_select_reg = {{w}}'d0; -{%- endfor %} -{% for p in range(n) %} -assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; -assign output_{{p}}_axis_tkeep = output_{{p}}_axis_tkeep_reg; -assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; -assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; -assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; -{% endfor %} - -always @(posedge clk) begin - if (rst) begin -{%- for p in range(n) %} - output_{{p}}_select_reg <= {{w}}'d0; -{%- endfor %} -{% for p in range(m) %} - input_{{p}}_axis_tvalid_reg <= 1'b0; -{%- endfor %} -{% for p in range(n) %} - output_{{p}}_axis_tvalid_reg <= 1'b0; -{%- endfor %} - end else begin -{%- for p in range(m) %} - input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; -{%- endfor %} -{% for p in range(n) %} - output_{{p}}_select_reg <= output_{{p}}_select; -{%- endfor %} -{%- for p in range(n) %} - - case (output_{{p}}_select_reg) -{%- for q in range(m) %} - {{w}}'d{{q}}: output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; -{%- endfor %} - endcase -{%- endfor %} - end -{%- for p in range(m) %} - - input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; - input_{{p}}_axis_tkeep_reg <= input_{{p}}_axis_tkeep; - input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; - input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; -{%- endfor %} -{%- for p in range(n) %} - - case (output_{{p}}_select_reg) -{%- for q in range(m) %} - {{w}}'d{{q}}: begin - output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; - output_{{p}}_axis_tkeep_reg <= input_{{q}}_axis_tkeep_reg; - output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; - output_{{p}}_axis_tuser_reg <= input_{{q}}_axis_tuser_reg; - end -{%- endfor %} - endcase -{%- endfor %} -end - -endmodule - -""") - - output_file.write(t.render( - m=m, - n=n, - w=select_width, - name=name - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_crosspoint_64_4x4.v b/rtl/axis_crosspoint_64_4x4.v deleted file mode 100644 index a00c45ab8..000000000 --- a/rtl/axis_crosspoint_64_4x4.v +++ /dev/null @@ -1,367 +0,0 @@ -/* - -Copyright (c) 2014-2017 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 4x4 crosspoint (64 bit datapath) - */ -module axis_crosspoint_64_4x4 # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI Stream inputs - */ - input wire [DATA_WIDTH-1:0] input_0_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, - input wire input_0_axis_tvalid, - input wire input_0_axis_tlast, - input wire input_0_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_1_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, - input wire input_1_axis_tvalid, - input wire input_1_axis_tlast, - input wire input_1_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_2_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, - input wire input_2_axis_tvalid, - input wire input_2_axis_tlast, - input wire input_2_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_3_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, - input wire input_3_axis_tvalid, - input wire input_3_axis_tlast, - input wire input_3_axis_tuser, - - /* - * AXI Stream outputs - */ - output wire [DATA_WIDTH-1:0] output_0_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, - output wire output_0_axis_tvalid, - output wire output_0_axis_tlast, - output wire output_0_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_1_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, - output wire output_1_axis_tvalid, - output wire output_1_axis_tlast, - output wire output_1_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_2_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, - output wire output_2_axis_tvalid, - output wire output_2_axis_tlast, - output wire output_2_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_3_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, - output wire output_3_axis_tvalid, - output wire output_3_axis_tlast, - output wire output_3_axis_tuser, - - /* - * Control - */ - input wire [1:0] output_0_select, - input wire [1:0] output_1_select, - input wire [1:0] output_2_select, - input wire [1:0] output_3_select -); - -reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_0_axis_tvalid_reg = 1'b0; -reg input_0_axis_tlast_reg = 1'b0; -reg input_0_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_1_axis_tvalid_reg = 1'b0; -reg input_1_axis_tlast_reg = 1'b0; -reg input_1_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_2_axis_tvalid_reg = 1'b0; -reg input_2_axis_tlast_reg = 1'b0; -reg input_2_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_3_axis_tvalid_reg = 1'b0; -reg input_3_axis_tlast_reg = 1'b0; -reg input_3_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_0_axis_tvalid_reg = 1'b0; -reg output_0_axis_tlast_reg = 1'b0; -reg output_0_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_1_axis_tvalid_reg = 1'b0; -reg output_1_axis_tlast_reg = 1'b0; -reg output_1_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_2_axis_tvalid_reg = 1'b0; -reg output_2_axis_tlast_reg = 1'b0; -reg output_2_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_3_axis_tvalid_reg = 1'b0; -reg output_3_axis_tlast_reg = 1'b0; -reg output_3_axis_tuser_reg = 1'b0; - -reg [1:0] output_0_select_reg = 2'd0; -reg [1:0] output_1_select_reg = 2'd0; -reg [1:0] output_2_select_reg = 2'd0; -reg [1:0] output_3_select_reg = 2'd0; - -assign output_0_axis_tdata = output_0_axis_tdata_reg; -assign output_0_axis_tkeep = output_0_axis_tkeep_reg; -assign output_0_axis_tvalid = output_0_axis_tvalid_reg; -assign output_0_axis_tlast = output_0_axis_tlast_reg; -assign output_0_axis_tuser = output_0_axis_tuser_reg; - -assign output_1_axis_tdata = output_1_axis_tdata_reg; -assign output_1_axis_tkeep = output_1_axis_tkeep_reg; -assign output_1_axis_tvalid = output_1_axis_tvalid_reg; -assign output_1_axis_tlast = output_1_axis_tlast_reg; -assign output_1_axis_tuser = output_1_axis_tuser_reg; - -assign output_2_axis_tdata = output_2_axis_tdata_reg; -assign output_2_axis_tkeep = output_2_axis_tkeep_reg; -assign output_2_axis_tvalid = output_2_axis_tvalid_reg; -assign output_2_axis_tlast = output_2_axis_tlast_reg; -assign output_2_axis_tuser = output_2_axis_tuser_reg; - -assign output_3_axis_tdata = output_3_axis_tdata_reg; -assign output_3_axis_tkeep = output_3_axis_tkeep_reg; -assign output_3_axis_tvalid = output_3_axis_tvalid_reg; -assign output_3_axis_tlast = output_3_axis_tlast_reg; -assign output_3_axis_tuser = output_3_axis_tuser_reg; - - -always @(posedge clk) begin - if (rst) begin - output_0_select_reg <= 2'd0; - output_1_select_reg <= 2'd0; - output_2_select_reg <= 2'd0; - output_3_select_reg <= 2'd0; - - input_0_axis_tvalid_reg <= 1'b0; - input_1_axis_tvalid_reg <= 1'b0; - input_2_axis_tvalid_reg <= 1'b0; - input_3_axis_tvalid_reg <= 1'b0; - - output_0_axis_tvalid_reg <= 1'b0; - output_1_axis_tvalid_reg <= 1'b0; - output_2_axis_tvalid_reg <= 1'b0; - output_3_axis_tvalid_reg <= 1'b0; - end else begin - input_0_axis_tvalid_reg <= input_0_axis_tvalid; - input_1_axis_tvalid_reg <= input_1_axis_tvalid; - input_2_axis_tvalid_reg <= input_2_axis_tvalid; - input_3_axis_tvalid_reg <= input_3_axis_tvalid; - - output_0_select_reg <= output_0_select; - output_1_select_reg <= output_1_select; - output_2_select_reg <= output_2_select; - output_3_select_reg <= output_3_select; - - case (output_0_select_reg) - 2'd0: output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 2'd1: output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 2'd2: output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 2'd3: output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; - endcase - - case (output_1_select_reg) - 2'd0: output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 2'd1: output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 2'd2: output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 2'd3: output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; - endcase - - case (output_2_select_reg) - 2'd0: output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 2'd1: output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 2'd2: output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 2'd3: output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; - endcase - - case (output_3_select_reg) - 2'd0: output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 2'd1: output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 2'd2: output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 2'd3: output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; - endcase - end - - input_0_axis_tdata_reg <= input_0_axis_tdata; - input_0_axis_tkeep_reg <= input_0_axis_tkeep; - input_0_axis_tlast_reg <= input_0_axis_tlast; - input_0_axis_tuser_reg <= input_0_axis_tuser; - - input_1_axis_tdata_reg <= input_1_axis_tdata; - input_1_axis_tkeep_reg <= input_1_axis_tkeep; - input_1_axis_tlast_reg <= input_1_axis_tlast; - input_1_axis_tuser_reg <= input_1_axis_tuser; - - input_2_axis_tdata_reg <= input_2_axis_tdata; - input_2_axis_tkeep_reg <= input_2_axis_tkeep; - input_2_axis_tlast_reg <= input_2_axis_tlast; - input_2_axis_tuser_reg <= input_2_axis_tuser; - - input_3_axis_tdata_reg <= input_3_axis_tdata; - input_3_axis_tkeep_reg <= input_3_axis_tkeep; - input_3_axis_tlast_reg <= input_3_axis_tlast; - input_3_axis_tuser_reg <= input_3_axis_tuser; - - case (output_0_select_reg) - 2'd0: begin - output_0_axis_tdata_reg <= input_0_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_0_axis_tlast_reg; - output_0_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_0_axis_tdata_reg <= input_1_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_1_axis_tlast_reg; - output_0_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_0_axis_tdata_reg <= input_2_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_2_axis_tlast_reg; - output_0_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_0_axis_tdata_reg <= input_3_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_3_axis_tlast_reg; - output_0_axis_tuser_reg <= input_3_axis_tuser_reg; - end - endcase - - case (output_1_select_reg) - 2'd0: begin - output_1_axis_tdata_reg <= input_0_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_0_axis_tlast_reg; - output_1_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_1_axis_tdata_reg <= input_1_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_1_axis_tlast_reg; - output_1_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_1_axis_tdata_reg <= input_2_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_2_axis_tlast_reg; - output_1_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_1_axis_tdata_reg <= input_3_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_3_axis_tlast_reg; - output_1_axis_tuser_reg <= input_3_axis_tuser_reg; - end - endcase - - case (output_2_select_reg) - 2'd0: begin - output_2_axis_tdata_reg <= input_0_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_0_axis_tlast_reg; - output_2_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_2_axis_tdata_reg <= input_1_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_1_axis_tlast_reg; - output_2_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_2_axis_tdata_reg <= input_2_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_2_axis_tlast_reg; - output_2_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_2_axis_tdata_reg <= input_3_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_3_axis_tlast_reg; - output_2_axis_tuser_reg <= input_3_axis_tuser_reg; - end - endcase - - case (output_3_select_reg) - 2'd0: begin - output_3_axis_tdata_reg <= input_0_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_0_axis_tlast_reg; - output_3_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_3_axis_tdata_reg <= input_1_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_1_axis_tlast_reg; - output_3_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_3_axis_tdata_reg <= input_2_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_2_axis_tlast_reg; - output_3_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_3_axis_tdata_reg <= input_3_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_3_axis_tlast_reg; - output_3_axis_tuser_reg <= input_3_axis_tuser_reg; - end - endcase -end - -endmodule diff --git a/tb/test_axis_crosspoint_4x4.py b/tb/test_axis_crosspoint_4x4.py index a82f7073d..1c1cd9425 100755 --- a/tb/test_axis_crosspoint_4x4.py +++ b/tb/test_axis_crosspoint_4x4.py @@ -44,6 +44,15 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -51,21 +60,33 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tuser = Signal(bool(0)) + input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tuser = Signal(bool(0)) + input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tuser = Signal(bool(0)) + input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tuser = Signal(bool(0)) + input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_0_select = Signal(intbv(0)[2:]) output_1_select = Signal(intbv(0)[2:]) @@ -74,21 +95,33 @@ def bench(): # Outputs output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_0_axis_tvalid = Signal(bool(0)) output_0_axis_tlast = Signal(bool(0)) - output_0_axis_tuser = Signal(bool(0)) + output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_1_axis_tvalid = Signal(bool(0)) output_1_axis_tlast = Signal(bool(0)) - output_1_axis_tuser = Signal(bool(0)) + output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_2_axis_tvalid = Signal(bool(0)) output_2_axis_tlast = Signal(bool(0)) - output_2_axis_tuser = Signal(bool(0)) + output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_3_axis_tvalid = Signal(bool(0)) output_3_axis_tlast = Signal(bool(0)) - output_3_axis_tuser = Signal(bool(0)) + output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_0_pause = Signal(bool(0)) @@ -106,8 +139,11 @@ def bench(): clk, rst, tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, tvalid=input_0_axis_tvalid, tlast=input_0_axis_tlast, + tid=input_0_axis_tid, + tdest=input_0_axis_tdest, tuser=input_0_axis_tuser, pause=source_0_pause, name='source_0' @@ -119,8 +155,11 @@ def bench(): clk, rst, tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, tvalid=input_1_axis_tvalid, tlast=input_1_axis_tlast, + tid=input_1_axis_tid, + tdest=input_1_axis_tdest, tuser=input_1_axis_tuser, pause=source_1_pause, name='source_1' @@ -132,8 +171,11 @@ def bench(): clk, rst, tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, tvalid=input_2_axis_tvalid, tlast=input_2_axis_tlast, + tid=input_2_axis_tid, + tdest=input_2_axis_tdest, tuser=input_2_axis_tuser, pause=source_2_pause, name='source_2' @@ -145,8 +187,11 @@ def bench(): clk, rst, tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, tvalid=input_3_axis_tvalid, tlast=input_3_axis_tlast, + tid=input_3_axis_tid, + tdest=input_3_axis_tdest, tuser=input_3_axis_tuser, pause=source_3_pause, name='source_3' @@ -158,8 +203,11 @@ def bench(): clk, rst, tdata=output_0_axis_tdata, + tkeep=output_0_axis_tkeep, tvalid=output_0_axis_tvalid, tlast=output_0_axis_tlast, + tid=output_0_axis_tid, + tdest=output_0_axis_tdest, tuser=output_0_axis_tuser, pause=sink_0_pause, name='sink_0' @@ -171,8 +219,11 @@ def bench(): clk, rst, tdata=output_1_axis_tdata, + tkeep=output_1_axis_tkeep, tvalid=output_1_axis_tvalid, tlast=output_1_axis_tlast, + tid=output_1_axis_tid, + tdest=output_1_axis_tdest, tuser=output_1_axis_tuser, pause=sink_1_pause, name='sink_1' @@ -184,8 +235,11 @@ def bench(): clk, rst, tdata=output_2_axis_tdata, + tkeep=output_2_axis_tkeep, tvalid=output_2_axis_tvalid, tlast=output_2_axis_tlast, + tid=output_2_axis_tid, + tdest=output_2_axis_tdest, tuser=output_2_axis_tuser, pause=sink_2_pause, name='sink_2' @@ -197,8 +251,11 @@ def bench(): clk, rst, tdata=output_3_axis_tdata, + tkeep=output_3_axis_tkeep, tvalid=output_3_axis_tvalid, tlast=output_3_axis_tlast, + tid=output_3_axis_tid, + tdest=output_3_axis_tdest, tuser=output_3_axis_tuser, pause=sink_3_pause, name='sink_3' @@ -215,37 +272,61 @@ def bench(): current_test=current_test, input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, input_0_axis_tvalid=input_0_axis_tvalid, input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tid=input_0_axis_tid, + input_0_axis_tdest=input_0_axis_tdest, input_0_axis_tuser=input_0_axis_tuser, input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, input_1_axis_tvalid=input_1_axis_tvalid, input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tid=input_1_axis_tid, + input_1_axis_tdest=input_1_axis_tdest, input_1_axis_tuser=input_1_axis_tuser, input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, input_2_axis_tvalid=input_2_axis_tvalid, input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tid=input_2_axis_tid, + input_2_axis_tdest=input_2_axis_tdest, input_2_axis_tuser=input_2_axis_tuser, input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, input_3_axis_tvalid=input_3_axis_tvalid, input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tid=input_3_axis_tid, + input_3_axis_tdest=input_3_axis_tdest, input_3_axis_tuser=input_3_axis_tuser, output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tkeep=output_0_axis_tkeep, output_0_axis_tvalid=output_0_axis_tvalid, output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tid=output_0_axis_tid, + output_0_axis_tdest=output_0_axis_tdest, output_0_axis_tuser=output_0_axis_tuser, output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tkeep=output_1_axis_tkeep, output_1_axis_tvalid=output_1_axis_tvalid, output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tid=output_1_axis_tid, + output_1_axis_tdest=output_1_axis_tdest, output_1_axis_tuser=output_1_axis_tuser, output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tkeep=output_2_axis_tkeep, output_2_axis_tvalid=output_2_axis_tvalid, output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tid=output_2_axis_tid, + output_2_axis_tdest=output_2_axis_tdest, output_2_axis_tuser=output_2_axis_tuser, output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tkeep=output_3_axis_tkeep, output_3_axis_tvalid=output_3_axis_tvalid, output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tid=output_3_axis_tid, + output_3_axis_tdest=output_3_axis_tdest, output_3_axis_tuser=output_3_axis_tuser, output_0_select=output_0_select, @@ -280,10 +361,10 @@ def bench(): output_2_select.next = 2 output_3_select.next = 3 - test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04') - test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04') - test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04') - test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04') + test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04', id=0, dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04', id=1, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04', id=2, dest=2) + test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04', id=3, dest=3) source_0.send(test_frame0) source_1.send(test_frame1) source_2.send(test_frame2) @@ -322,10 +403,10 @@ def bench(): output_2_select.next = 1 output_3_select.next = 0 - test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04') - test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04') - test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04') - test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04') + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04', id=0, dest=3) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04', id=1, dest=2) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04', id=2, dest=1) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04', id=3, dest=0) source_0.send(test_frame0) source_1.send(test_frame1) source_2.send(test_frame2) @@ -364,7 +445,7 @@ def bench(): output_2_select.next = 0 output_3_select.next = 0 - test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04') + test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04', id=0, dest=0) source_0.send(test_frame0) yield clk.posedge diff --git a/tb/test_axis_crosspoint_4x4.v b/tb/test_axis_crosspoint_4x4.v index 89cc7d45b..3d3dbf93f 100644 --- a/tb/test_axis_crosspoint_4x4.v +++ b/tb/test_axis_crosspoint_4x4.v @@ -33,6 +33,15 @@ module test_axis_crosspoint_4x4; // Parameters parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -40,21 +49,33 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; -reg input_0_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_0_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; -reg input_1_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_1_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; -reg input_2_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_2_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; -reg input_3_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_3_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; reg [1:0] output_0_select = 0; reg [1:0] output_1_select = 0; @@ -63,21 +84,33 @@ reg [1:0] output_3_select = 0; // Outputs wire [DATA_WIDTH-1:0] output_0_axis_tdata; +wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; wire output_0_axis_tvalid; wire output_0_axis_tlast; -wire output_0_axis_tuser; +wire [ID_WIDTH-1:0] output_0_axis_tid; +wire [DEST_WIDTH-1:0] output_0_axis_tdest; +wire [USER_WIDTH-1:0] output_0_axis_tuser; wire [DATA_WIDTH-1:0] output_1_axis_tdata; +wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; wire output_1_axis_tvalid; wire output_1_axis_tlast; -wire output_1_axis_tuser; +wire [ID_WIDTH-1:0] output_1_axis_tid; +wire [DEST_WIDTH-1:0] output_1_axis_tdest; +wire [USER_WIDTH-1:0] output_1_axis_tuser; wire [DATA_WIDTH-1:0] output_2_axis_tdata; +wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; wire output_2_axis_tvalid; wire output_2_axis_tlast; -wire output_2_axis_tuser; +wire [ID_WIDTH-1:0] output_2_axis_tid; +wire [DEST_WIDTH-1:0] output_2_axis_tdest; +wire [USER_WIDTH-1:0] output_2_axis_tuser; wire [DATA_WIDTH-1:0] output_3_axis_tdata; +wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; wire output_3_axis_tvalid; wire output_3_axis_tlast; -wire output_3_axis_tuser; +wire [ID_WIDTH-1:0] output_3_axis_tid; +wire [DEST_WIDTH-1:0] output_3_axis_tdest; +wire [USER_WIDTH-1:0] output_3_axis_tuser; initial begin // myhdl integration @@ -86,20 +119,32 @@ initial begin rst, current_test, input_0_axis_tdata, + input_0_axis_tkeep, input_0_axis_tvalid, input_0_axis_tlast, + input_0_axis_tid, + input_0_axis_tdest, input_0_axis_tuser, input_1_axis_tdata, + input_1_axis_tkeep, input_1_axis_tvalid, input_1_axis_tlast, + input_1_axis_tid, + input_1_axis_tdest, input_1_axis_tuser, input_2_axis_tdata, + input_2_axis_tkeep, input_2_axis_tvalid, input_2_axis_tlast, + input_2_axis_tid, + input_2_axis_tdest, input_2_axis_tuser, input_3_axis_tdata, + input_3_axis_tkeep, input_3_axis_tvalid, input_3_axis_tlast, + input_3_axis_tid, + input_3_axis_tdest, input_3_axis_tuser, output_0_select, output_1_select, @@ -108,20 +153,32 @@ initial begin ); $to_myhdl( output_0_axis_tdata, + output_0_axis_tkeep, output_0_axis_tvalid, output_0_axis_tlast, + output_0_axis_tid, + output_0_axis_tdest, output_0_axis_tuser, output_1_axis_tdata, + output_1_axis_tkeep, output_1_axis_tvalid, output_1_axis_tlast, + output_1_axis_tid, + output_1_axis_tdest, output_1_axis_tuser, output_2_axis_tdata, + output_2_axis_tkeep, output_2_axis_tvalid, output_2_axis_tlast, + output_2_axis_tid, + output_2_axis_tdest, output_2_axis_tuser, output_3_axis_tdata, + output_3_axis_tkeep, output_3_axis_tvalid, output_3_axis_tlast, + output_3_axis_tid, + output_3_axis_tdest, output_3_axis_tuser ); @@ -131,44 +188,77 @@ initial begin end axis_crosspoint_4x4 #( - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .rst(rst), // AXI inputs .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tkeep(input_0_axis_tkeep), .input_0_axis_tvalid(input_0_axis_tvalid), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tid(input_0_axis_tid), + .input_0_axis_tdest(input_0_axis_tdest), .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tkeep(input_1_axis_tkeep), .input_1_axis_tvalid(input_1_axis_tvalid), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tid(input_1_axis_tid), + .input_1_axis_tdest(input_1_axis_tdest), .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tkeep(input_2_axis_tkeep), .input_2_axis_tvalid(input_2_axis_tvalid), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tid(input_2_axis_tid), + .input_2_axis_tdest(input_2_axis_tdest), .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tkeep(input_3_axis_tkeep), .input_3_axis_tvalid(input_3_axis_tvalid), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tid(input_3_axis_tid), + .input_3_axis_tdest(input_3_axis_tdest), .input_3_axis_tuser(input_3_axis_tuser), // AXI outputs .output_0_axis_tdata(output_0_axis_tdata), + .output_0_axis_tkeep(output_0_axis_tkeep), .output_0_axis_tvalid(output_0_axis_tvalid), .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tid(output_0_axis_tid), + .output_0_axis_tdest(output_0_axis_tdest), .output_0_axis_tuser(output_0_axis_tuser), .output_1_axis_tdata(output_1_axis_tdata), + .output_1_axis_tkeep(output_1_axis_tkeep), .output_1_axis_tvalid(output_1_axis_tvalid), .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tid(output_1_axis_tid), + .output_1_axis_tdest(output_1_axis_tdest), .output_1_axis_tuser(output_1_axis_tuser), .output_2_axis_tdata(output_2_axis_tdata), + .output_2_axis_tkeep(output_2_axis_tkeep), .output_2_axis_tvalid(output_2_axis_tvalid), .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tid(output_2_axis_tid), + .output_2_axis_tdest(output_2_axis_tdest), .output_2_axis_tuser(output_2_axis_tuser), .output_3_axis_tdata(output_3_axis_tdata), + .output_3_axis_tkeep(output_3_axis_tkeep), .output_3_axis_tvalid(output_3_axis_tvalid), .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tid(output_3_axis_tid), + .output_3_axis_tdest(output_3_axis_tdest), .output_3_axis_tuser(output_3_axis_tuser), // Control .output_0_select(output_0_select), diff --git a/tb/test_axis_crosspoint_64_4x4.py b/tb/test_axis_crosspoint_4x4_64.py similarity index 77% rename from tb/test_axis_crosspoint_64_4x4.py rename to tb/test_axis_crosspoint_4x4_64.py index 8ed4b2142..a57cb0817 100755 --- a/tb/test_axis_crosspoint_64_4x4.py +++ b/tb/test_axis_crosspoint_4x4_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_crosspoint_64_4x4' -testbench = 'test_%s' % module +module = 'axis_crosspoint_4x4' +testbench = 'test_%s_64' % module srcs = [] @@ -44,7 +44,15 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -52,25 +60,33 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tuser = Signal(bool(0)) + input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tuser = Signal(bool(0)) + input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tuser = Signal(bool(0)) + input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tuser = Signal(bool(0)) + input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_0_select = Signal(intbv(0)[2:]) output_1_select = Signal(intbv(0)[2:]) @@ -79,25 +95,33 @@ def bench(): # Outputs output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_0_axis_tvalid = Signal(bool(0)) output_0_axis_tlast = Signal(bool(0)) - output_0_axis_tuser = Signal(bool(0)) + output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_1_axis_tvalid = Signal(bool(0)) output_1_axis_tlast = Signal(bool(0)) - output_1_axis_tuser = Signal(bool(0)) + output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_2_axis_tvalid = Signal(bool(0)) output_2_axis_tlast = Signal(bool(0)) - output_2_axis_tuser = Signal(bool(0)) + output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_3_axis_tvalid = Signal(bool(0)) output_3_axis_tlast = Signal(bool(0)) - output_3_axis_tuser = Signal(bool(0)) + output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_0_pause = Signal(bool(0)) @@ -118,6 +142,8 @@ def bench(): tkeep=input_0_axis_tkeep, tvalid=input_0_axis_tvalid, tlast=input_0_axis_tlast, + tid=input_0_axis_tid, + tdest=input_0_axis_tdest, tuser=input_0_axis_tuser, pause=source_0_pause, name='source_0' @@ -132,6 +158,8 @@ def bench(): tkeep=input_1_axis_tkeep, tvalid=input_1_axis_tvalid, tlast=input_1_axis_tlast, + tid=input_1_axis_tid, + tdest=input_1_axis_tdest, tuser=input_1_axis_tuser, pause=source_1_pause, name='source_1' @@ -146,6 +174,8 @@ def bench(): tkeep=input_2_axis_tkeep, tvalid=input_2_axis_tvalid, tlast=input_2_axis_tlast, + tid=input_2_axis_tid, + tdest=input_2_axis_tdest, tuser=input_2_axis_tuser, pause=source_2_pause, name='source_2' @@ -160,6 +190,8 @@ def bench(): tkeep=input_3_axis_tkeep, tvalid=input_3_axis_tvalid, tlast=input_3_axis_tlast, + tid=input_3_axis_tid, + tdest=input_3_axis_tdest, tuser=input_3_axis_tuser, pause=source_3_pause, name='source_3' @@ -174,6 +206,8 @@ def bench(): tkeep=output_0_axis_tkeep, tvalid=output_0_axis_tvalid, tlast=output_0_axis_tlast, + tid=output_0_axis_tid, + tdest=output_0_axis_tdest, tuser=output_0_axis_tuser, pause=sink_0_pause, name='sink_0' @@ -188,6 +222,8 @@ def bench(): tkeep=output_1_axis_tkeep, tvalid=output_1_axis_tvalid, tlast=output_1_axis_tlast, + tid=output_1_axis_tid, + tdest=output_1_axis_tdest, tuser=output_1_axis_tuser, pause=sink_1_pause, name='sink_1' @@ -202,6 +238,8 @@ def bench(): tkeep=output_2_axis_tkeep, tvalid=output_2_axis_tvalid, tlast=output_2_axis_tlast, + tid=output_2_axis_tid, + tdest=output_2_axis_tdest, tuser=output_2_axis_tuser, pause=sink_2_pause, name='sink_2' @@ -216,6 +254,8 @@ def bench(): tkeep=output_3_axis_tkeep, tvalid=output_3_axis_tvalid, tlast=output_3_axis_tlast, + tid=output_3_axis_tid, + tdest=output_3_axis_tdest, tuser=output_3_axis_tuser, pause=sink_3_pause, name='sink_3' @@ -235,42 +275,58 @@ def bench(): input_0_axis_tkeep=input_0_axis_tkeep, input_0_axis_tvalid=input_0_axis_tvalid, input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tid=input_0_axis_tid, + input_0_axis_tdest=input_0_axis_tdest, input_0_axis_tuser=input_0_axis_tuser, input_1_axis_tdata=input_1_axis_tdata, input_1_axis_tkeep=input_1_axis_tkeep, input_1_axis_tvalid=input_1_axis_tvalid, input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tid=input_1_axis_tid, + input_1_axis_tdest=input_1_axis_tdest, input_1_axis_tuser=input_1_axis_tuser, input_2_axis_tdata=input_2_axis_tdata, input_2_axis_tkeep=input_2_axis_tkeep, input_2_axis_tvalid=input_2_axis_tvalid, input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tid=input_2_axis_tid, + input_2_axis_tdest=input_2_axis_tdest, input_2_axis_tuser=input_2_axis_tuser, input_3_axis_tdata=input_3_axis_tdata, input_3_axis_tkeep=input_3_axis_tkeep, input_3_axis_tvalid=input_3_axis_tvalid, input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tid=input_3_axis_tid, + input_3_axis_tdest=input_3_axis_tdest, input_3_axis_tuser=input_3_axis_tuser, output_0_axis_tdata=output_0_axis_tdata, output_0_axis_tkeep=output_0_axis_tkeep, output_0_axis_tvalid=output_0_axis_tvalid, output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tid=output_0_axis_tid, + output_0_axis_tdest=output_0_axis_tdest, output_0_axis_tuser=output_0_axis_tuser, output_1_axis_tdata=output_1_axis_tdata, output_1_axis_tkeep=output_1_axis_tkeep, output_1_axis_tvalid=output_1_axis_tvalid, output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tid=output_1_axis_tid, + output_1_axis_tdest=output_1_axis_tdest, output_1_axis_tuser=output_1_axis_tuser, output_2_axis_tdata=output_2_axis_tdata, output_2_axis_tkeep=output_2_axis_tkeep, output_2_axis_tvalid=output_2_axis_tvalid, output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tid=output_2_axis_tid, + output_2_axis_tdest=output_2_axis_tdest, output_2_axis_tuser=output_2_axis_tuser, output_3_axis_tdata=output_3_axis_tdata, output_3_axis_tkeep=output_3_axis_tkeep, output_3_axis_tvalid=output_3_axis_tvalid, output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tid=output_3_axis_tid, + output_3_axis_tdest=output_3_axis_tdest, output_3_axis_tuser=output_3_axis_tuser, output_0_select=output_0_select, @@ -305,10 +361,10 @@ def bench(): output_2_select.next = 2 output_3_select.next = 3 - test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04') - test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04') - test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04') - test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04') + test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04', id=0, dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04', id=1, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04', id=2, dest=2) + test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04', id=3, dest=3) source_0.send(test_frame0) source_1.send(test_frame1) source_2.send(test_frame2) @@ -347,10 +403,10 @@ def bench(): output_2_select.next = 1 output_3_select.next = 0 - test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04') - test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04') - test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04') - test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04') + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04', id=0, dest=3) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04', id=1, dest=2) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04', id=2, dest=1) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04', id=3, dest=0) source_0.send(test_frame0) source_1.send(test_frame1) source_2.send(test_frame2) @@ -389,7 +445,7 @@ def bench(): output_2_select.next = 0 output_3_select.next = 0 - test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04') + test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04', id=0, dest=0) source_0.send(test_frame0) yield clk.posedge diff --git a/tb/test_axis_crosspoint_64_4x4.v b/tb/test_axis_crosspoint_4x4_64.v similarity index 68% rename from tb/test_axis_crosspoint_64_4x4.v rename to tb/test_axis_crosspoint_4x4_64.v index 296f83725..42ed67a44 100644 --- a/tb/test_axis_crosspoint_64_4x4.v +++ b/tb/test_axis_crosspoint_4x4_64.v @@ -27,13 +27,21 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_crosspoint_64_4x4 + * Testbench for axis_crosspoint_4x4 */ -module test_axis_crosspoint_64_4x4; +module test_axis_crosspoint_4x4_64; // Parameters parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -44,22 +52,30 @@ reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; -reg input_0_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_0_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; -reg input_1_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_1_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; -reg input_2_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_2_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; -reg input_3_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_3_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; reg [1:0] output_0_select = 0; reg [1:0] output_1_select = 0; @@ -71,22 +87,30 @@ wire [DATA_WIDTH-1:0] output_0_axis_tdata; wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; wire output_0_axis_tvalid; wire output_0_axis_tlast; -wire output_0_axis_tuser; +wire [ID_WIDTH-1:0] output_0_axis_tid; +wire [DEST_WIDTH-1:0] output_0_axis_tdest; +wire [USER_WIDTH-1:0] output_0_axis_tuser; wire [DATA_WIDTH-1:0] output_1_axis_tdata; wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; wire output_1_axis_tvalid; wire output_1_axis_tlast; -wire output_1_axis_tuser; +wire [ID_WIDTH-1:0] output_1_axis_tid; +wire [DEST_WIDTH-1:0] output_1_axis_tdest; +wire [USER_WIDTH-1:0] output_1_axis_tuser; wire [DATA_WIDTH-1:0] output_2_axis_tdata; wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; wire output_2_axis_tvalid; wire output_2_axis_tlast; -wire output_2_axis_tuser; +wire [ID_WIDTH-1:0] output_2_axis_tid; +wire [DEST_WIDTH-1:0] output_2_axis_tdest; +wire [USER_WIDTH-1:0] output_2_axis_tuser; wire [DATA_WIDTH-1:0] output_3_axis_tdata; wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; wire output_3_axis_tvalid; wire output_3_axis_tlast; -wire output_3_axis_tuser; +wire [ID_WIDTH-1:0] output_3_axis_tid; +wire [DEST_WIDTH-1:0] output_3_axis_tdest; +wire [USER_WIDTH-1:0] output_3_axis_tuser; initial begin // myhdl integration @@ -98,21 +122,29 @@ initial begin input_0_axis_tkeep, input_0_axis_tvalid, input_0_axis_tlast, + input_0_axis_tid, + input_0_axis_tdest, input_0_axis_tuser, input_1_axis_tdata, input_1_axis_tkeep, input_1_axis_tvalid, input_1_axis_tlast, + input_1_axis_tid, + input_1_axis_tdest, input_1_axis_tuser, input_2_axis_tdata, input_2_axis_tkeep, input_2_axis_tvalid, input_2_axis_tlast, + input_2_axis_tid, + input_2_axis_tdest, input_2_axis_tuser, input_3_axis_tdata, input_3_axis_tkeep, input_3_axis_tvalid, input_3_axis_tlast, + input_3_axis_tid, + input_3_axis_tdest, input_3_axis_tuser, output_0_select, output_1_select, @@ -124,32 +156,48 @@ initial begin output_0_axis_tkeep, output_0_axis_tvalid, output_0_axis_tlast, + output_0_axis_tid, + output_0_axis_tdest, output_0_axis_tuser, output_1_axis_tdata, output_1_axis_tkeep, output_1_axis_tvalid, output_1_axis_tlast, + output_1_axis_tid, + output_1_axis_tdest, output_1_axis_tuser, output_2_axis_tdata, output_2_axis_tkeep, output_2_axis_tvalid, output_2_axis_tlast, + output_2_axis_tid, + output_2_axis_tdest, output_2_axis_tuser, output_3_axis_tdata, output_3_axis_tkeep, output_3_axis_tvalid, output_3_axis_tlast, + output_3_axis_tid, + output_3_axis_tdest, output_3_axis_tuser ); // dump file - $dumpfile("test_axis_crosspoint_64_4x4.lxt"); - $dumpvars(0, test_axis_crosspoint_64_4x4); + $dumpfile("test_axis_crosspoint_4x4_64.lxt"); + $dumpvars(0, test_axis_crosspoint_4x4_64); end -axis_crosspoint_64_4x4 #( +axis_crosspoint_4x4 #( .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -159,42 +207,58 @@ UUT ( .input_0_axis_tkeep(input_0_axis_tkeep), .input_0_axis_tvalid(input_0_axis_tvalid), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tid(input_0_axis_tid), + .input_0_axis_tdest(input_0_axis_tdest), .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), .input_1_axis_tkeep(input_1_axis_tkeep), .input_1_axis_tvalid(input_1_axis_tvalid), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tid(input_1_axis_tid), + .input_1_axis_tdest(input_1_axis_tdest), .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), .input_2_axis_tkeep(input_2_axis_tkeep), .input_2_axis_tvalid(input_2_axis_tvalid), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tid(input_2_axis_tid), + .input_2_axis_tdest(input_2_axis_tdest), .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), .input_3_axis_tkeep(input_3_axis_tkeep), .input_3_axis_tvalid(input_3_axis_tvalid), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tid(input_3_axis_tid), + .input_3_axis_tdest(input_3_axis_tdest), .input_3_axis_tuser(input_3_axis_tuser), // AXI outputs .output_0_axis_tdata(output_0_axis_tdata), .output_0_axis_tkeep(output_0_axis_tkeep), .output_0_axis_tvalid(output_0_axis_tvalid), .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tid(output_0_axis_tid), + .output_0_axis_tdest(output_0_axis_tdest), .output_0_axis_tuser(output_0_axis_tuser), .output_1_axis_tdata(output_1_axis_tdata), .output_1_axis_tkeep(output_1_axis_tkeep), .output_1_axis_tvalid(output_1_axis_tvalid), .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tid(output_1_axis_tid), + .output_1_axis_tdest(output_1_axis_tdest), .output_1_axis_tuser(output_1_axis_tuser), .output_2_axis_tdata(output_2_axis_tdata), .output_2_axis_tkeep(output_2_axis_tkeep), .output_2_axis_tvalid(output_2_axis_tvalid), .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tid(output_2_axis_tid), + .output_2_axis_tdest(output_2_axis_tdest), .output_2_axis_tuser(output_2_axis_tuser), .output_3_axis_tdata(output_3_axis_tdata), .output_3_axis_tkeep(output_3_axis_tkeep), .output_3_axis_tvalid(output_3_axis_tvalid), .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tid(output_3_axis_tid), + .output_3_axis_tdest(output_3_axis_tdest), .output_3_axis_tuser(output_3_axis_tuser), // Control .output_0_select(output_0_select), From de590517a92a241846e40373be46e29d0b3ae26b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 20:17:20 -0800 Subject: [PATCH 359/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream switch --- rtl/axis_switch.py | 122 +- rtl/axis_switch_4x4.v | 574 +++++--- rtl/axis_switch_64.py | 479 ------ rtl/axis_switch_64_4x4.v | 1286 ----------------- tb/test_axis_switch_4x4.py | 110 +- tb/test_axis_switch_4x4.v | 76 +- ...h_64_4x4.py => test_axis_switch_4x4_64.py} | 105 +- ...tch_64_4x4.v => test_axis_switch_4x4_64.v} | 60 +- 8 files changed, 700 insertions(+), 2112 deletions(-) delete mode 100755 rtl/axis_switch_64.py delete mode 100644 rtl/axis_switch_64_4x4.v rename tb/{test_axis_switch_64_4x4.py => test_axis_switch_4x4_64.py} (85%) rename tb/{test_axis_switch_64_4x4.v => test_axis_switch_4x4_64.v} (83%) diff --git a/rtl/axis_switch.py b/rtl/axis_switch.py index 26c838f74..9114a6609 100755 --- a/rtl/axis_switch.py +++ b/rtl/axis_switch.py @@ -80,7 +80,13 @@ THE SOFTWARE. module {{name}} # ( parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, parameter DEST_WIDTH = {{cn}}, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, {%- for p in range(n) %} parameter OUT_{{p}}_BASE = {{p}}, parameter OUT_{{p}}_TOP = {{p}}, @@ -100,22 +106,26 @@ module {{name}} # */ {%- for p in range(m) %} input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, input wire input_{{p}}_axis_tvalid, output wire input_{{p}}_axis_tready, input wire input_{{p}}_axis_tlast, + input wire [ID_WIDTH-1:0] input_{{p}}_axis_tid, input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, - input wire input_{{p}}_axis_tuser, + input wire [USER_WIDTH-1:0] input_{{p}}_axis_tuser, {% endfor %} /* * AXI Stream outputs */ {%- for p in range(n) %} output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, output wire output_{{p}}_axis_tvalid, input wire output_{{p}}_axis_tready, output wire output_{{p}}_axis_tlast, + output wire [ID_WIDTH-1:0] output_{{p}}_axis_tid, output wire [DEST_WIDTH-1:0] output_{{p}}_axis_tdest, - output wire output_{{p}}_axis_tuser{% if not loop.last %},{% endif %} + output wire [USER_WIDTH-1:0] output_{{p}}_axis_tuser{% if not loop.last %},{% endif %} {% endfor -%} ); @@ -162,13 +172,15 @@ reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; // internal datapath {%- for p in range(n) %} -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_int; -reg output_{{p}}_axis_tvalid_int; -reg output_{{p}}_axis_tready_int_reg = 1'b0; -reg output_{{p}}_axis_tlast_int; -reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_int; -reg output_{{p}}_axis_tuser_int; -wire output_{{p}}_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_int; +reg output_{{p}}_axis_tvalid_int; +reg output_{{p}}_axis_tready_int_reg = 1'b0; +reg output_{{p}}_axis_tlast_int; +reg [ID_WIDTH-1:0] output_{{p}}_axis_tid_int; +reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_int; +reg [USER_WIDTH-1:0] output_{{p}}_axis_tuser_int; +wire output_{{p}}_axis_tready_int_early; {% endfor %} {%- for p in range(m) %} assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; @@ -177,31 +189,37 @@ assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; // mux for incoming packet {% for p in range(n) %} reg [DATA_WIDTH-1:0] current_input_{{p}}_axis_tdata; -reg current_input_{{p}}_axis_tvalid; -reg current_input_{{p}}_axis_tready; -reg current_input_{{p}}_axis_tlast; +reg [DATA_WIDTH-1:0] current_input_{{p}}_axis_tkeep; +reg current_input_{{p}}_axis_tvalid; +reg current_input_{{p}}_axis_tready; +reg current_input_{{p}}_axis_tlast; +reg [ID_WIDTH-1:0] current_input_{{p}}_axis_tid; reg [DEST_WIDTH-1:0] current_input_{{p}}_axis_tdest; -reg current_input_{{p}}_axis_tuser; +reg [USER_WIDTH-1:0] current_input_{{p}}_axis_tuser; always @* begin case (select_{{p}}_reg) {%- for q in range(m) %} {{cm}}'d{{q}}: begin - current_input_{{p}}_axis_tdata = input_{{q}}_axis_tdata; + current_input_{{p}}_axis_tdata = input_{{q}}_axis_tdata; + current_input_{{p}}_axis_tkeep = input_{{q}}_axis_tkeep; current_input_{{p}}_axis_tvalid = input_{{q}}_axis_tvalid; current_input_{{p}}_axis_tready = input_{{q}}_axis_tready; - current_input_{{p}}_axis_tlast = input_{{q}}_axis_tlast; - current_input_{{p}}_axis_tdest = input_{{q}}_axis_tdest; - current_input_{{p}}_axis_tuser = input_{{q}}_axis_tuser; + current_input_{{p}}_axis_tlast = input_{{q}}_axis_tlast; + current_input_{{p}}_axis_tid = input_{{q}}_axis_tid; + current_input_{{p}}_axis_tdest = input_{{q}}_axis_tdest; + current_input_{{p}}_axis_tuser = input_{{q}}_axis_tuser; end {%- endfor %} default: begin - current_input_{{p}}_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_{{p}}_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_{{p}}_axis_tkeep = {KEEP_WIDTH{1'b0}}; current_input_{{p}}_axis_tvalid = 1'b0; current_input_{{p}}_axis_tready = 1'b0; - current_input_{{p}}_axis_tlast = 1'b0; - current_input_{{p}}_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_{{p}}_axis_tuser = 1'b0; + current_input_{{p}}_axis_tlast = 1'b0; + current_input_{{p}}_axis_tid = {ID_WIDTH{1'b0}}; + current_input_{{p}}_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_{{p}}_axis_tuser = {USER_WIDTH{1'b0}}; end endcase end @@ -260,11 +278,13 @@ always @* begin input_{{p}}_axis_tready_next = 1'b0; {%- endfor %} {% for p in range(n) %} - output_{{p}}_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_{{p}}_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_{{p}}_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; output_{{p}}_axis_tvalid_int = 1'b0; - output_{{p}}_axis_tlast_int = 1'b0; - output_{{p}}_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_{{p}}_axis_tuser_int = 1'b0; + output_{{p}}_axis_tlast_int = 1'b0; + output_{{p}}_axis_tid_int = {ID_WIDTH{1'b0}}; + output_{{p}}_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_{{p}}_axis_tuser_int = {USER_WIDTH{1'b0}}; {% endfor %} // input decoding {% for p in range(m) %} @@ -316,11 +336,13 @@ always @* begin // pass through selected packet data {% for p in range(n) %} - output_{{p}}_axis_tdata_int = current_input_{{p}}_axis_tdata; + output_{{p}}_axis_tdata_int = current_input_{{p}}_axis_tdata; + output_{{p}}_axis_tkeep_int = current_input_{{p}}_axis_tkeep; output_{{p}}_axis_tvalid_int = current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready & enable_{{p}}_reg; - output_{{p}}_axis_tlast_int = current_input_{{p}}_axis_tlast; - output_{{p}}_axis_tdest_int = current_input_{{p}}_axis_tdest; - output_{{p}}_axis_tuser_int = current_input_{{p}}_axis_tuser; + output_{{p}}_axis_tlast_int = current_input_{{p}}_axis_tlast; + output_{{p}}_axis_tid_int = current_input_{{p}}_axis_tid; + output_{{p}}_axis_tdest_int = current_input_{{p}}_axis_tdest; + output_{{p}}_axis_tuser_int = current_input_{{p}}_axis_tuser; {% endfor -%} end @@ -359,28 +381,34 @@ always @(posedge clk) begin end {% for p in range(n) %} // output {{p}} datapath logic -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_{{p}}_axis_tvalid_reg = 1'b0, output_{{p}}_axis_tvalid_next; -reg output_{{p}}_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg output_{{p}}_axis_tuser_reg = 1'b0; +reg output_{{p}}_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_{{p}}_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_{{p}}_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_{{p}}_axis_tvalid_reg = 1'b0, temp_{{p}}_axis_tvalid_next; -reg temp_{{p}}_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] temp_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg temp_{{p}}_axis_tuser_reg = 1'b0; +reg temp_{{p}}_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_{{p}}_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_{{p}}_axis_tuser_reg = 1'b0; // datapath control reg store_{{p}}_axis_int_to_output; reg store_{{p}}_axis_int_to_temp; reg store_{{p}}_axis_temp_to_output; -assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; +assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; +assign output_{{p}}_axis_tkeep = KEEP_ENABLE ? output_{{p}}_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; -assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; -assign output_{{p}}_axis_tdest = output_{{p}}_axis_tdest_reg; -assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; +assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; +assign output_{{p}}_axis_tid = ID_ENABLE ? output_{{p}}_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_{{p}}_axis_tdest = output_{{p}}_axis_tdest_reg; +assign output_{{p}}_axis_tuser = USER_ENABLE ? output_{{p}}_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_{{p}}_axis_tready_int_early = output_{{p}}_axis_tready | (~temp_{{p}}_axis_tvalid_reg & (~output_{{p}}_axis_tvalid_reg | ~output_{{p}}_axis_tvalid_int)); @@ -393,7 +421,7 @@ always @* begin store_{{p}}_axis_int_to_output = 1'b0; store_{{p}}_axis_int_to_temp = 1'b0; store_{{p}}_axis_temp_to_output = 1'b0; - + if (output_{{p}}_axis_tready_int_reg) begin // input is ready if (output_{{p}}_axis_tready | ~output_{{p}}_axis_tvalid_reg) begin @@ -427,19 +455,25 @@ always @(posedge clk) begin // datapath if (store_{{p}}_axis_int_to_output) begin output_{{p}}_axis_tdata_reg <= output_{{p}}_axis_tdata_int; + output_{{p}}_axis_tkeep_reg <= output_{{p}}_axis_tkeep_int; output_{{p}}_axis_tlast_reg <= output_{{p}}_axis_tlast_int; + output_{{p}}_axis_tid_reg <= output_{{p}}_axis_tid_int; output_{{p}}_axis_tdest_reg <= output_{{p}}_axis_tdest_int; output_{{p}}_axis_tuser_reg <= output_{{p}}_axis_tuser_int; end else if (store_{{p}}_axis_temp_to_output) begin output_{{p}}_axis_tdata_reg <= temp_{{p}}_axis_tdata_reg; + output_{{p}}_axis_tkeep_reg <= temp_{{p}}_axis_tkeep_reg; output_{{p}}_axis_tlast_reg <= temp_{{p}}_axis_tlast_reg; + output_{{p}}_axis_tid_reg <= temp_{{p}}_axis_tid_reg; output_{{p}}_axis_tdest_reg <= temp_{{p}}_axis_tdest_reg; output_{{p}}_axis_tuser_reg <= temp_{{p}}_axis_tuser_reg; end if (store_{{p}}_axis_int_to_temp) begin temp_{{p}}_axis_tdata_reg <= output_{{p}}_axis_tdata_int; + temp_{{p}}_axis_tkeep_reg <= output_{{p}}_axis_tkeep_int; temp_{{p}}_axis_tlast_reg <= output_{{p}}_axis_tlast_int; + temp_{{p}}_axis_tid_reg <= output_{{p}}_axis_tid_int; temp_{{p}}_axis_tdest_reg <= output_{{p}}_axis_tdest_int; temp_{{p}}_axis_tuser_reg <= output_{{p}}_axis_tuser_int; end @@ -448,7 +482,7 @@ end endmodule """) - + output_file.write(t.render( m=m, n=n, @@ -456,7 +490,7 @@ endmodule cn=cn, name=name )) - + print("Done") if __name__ == "__main__": diff --git a/rtl/axis_switch_4x4.v b/rtl/axis_switch_4x4.v index 06c49a310..7f28b4a8f 100644 --- a/rtl/axis_switch_4x4.v +++ b/rtl/axis_switch_4x4.v @@ -32,7 +32,13 @@ THE SOFTWARE. module axis_switch_4x4 # ( parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, parameter DEST_WIDTH = 2, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, parameter OUT_0_BASE = 0, parameter OUT_0_TOP = 0, parameter OUT_0_CONNECT = 4'b1111, @@ -58,63 +64,79 @@ module axis_switch_4x4 # * AXI Stream inputs */ input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, input wire input_0_axis_tvalid, output wire input_0_axis_tready, input wire input_0_axis_tlast, + input wire [ID_WIDTH-1:0] input_0_axis_tid, input wire [DEST_WIDTH-1:0] input_0_axis_tdest, - input wire input_0_axis_tuser, + input wire [USER_WIDTH-1:0] input_0_axis_tuser, input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, input wire input_1_axis_tvalid, output wire input_1_axis_tready, input wire input_1_axis_tlast, + input wire [ID_WIDTH-1:0] input_1_axis_tid, input wire [DEST_WIDTH-1:0] input_1_axis_tdest, - input wire input_1_axis_tuser, + input wire [USER_WIDTH-1:0] input_1_axis_tuser, input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, input wire input_2_axis_tvalid, output wire input_2_axis_tready, input wire input_2_axis_tlast, + input wire [ID_WIDTH-1:0] input_2_axis_tid, input wire [DEST_WIDTH-1:0] input_2_axis_tdest, - input wire input_2_axis_tuser, + input wire [USER_WIDTH-1:0] input_2_axis_tuser, input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, input wire input_3_axis_tvalid, output wire input_3_axis_tready, input wire input_3_axis_tlast, + input wire [ID_WIDTH-1:0] input_3_axis_tid, input wire [DEST_WIDTH-1:0] input_3_axis_tdest, - input wire input_3_axis_tuser, + input wire [USER_WIDTH-1:0] input_3_axis_tuser, /* * AXI Stream outputs */ output wire [DATA_WIDTH-1:0] output_0_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, output wire output_0_axis_tvalid, input wire output_0_axis_tready, output wire output_0_axis_tlast, + output wire [ID_WIDTH-1:0] output_0_axis_tid, output wire [DEST_WIDTH-1:0] output_0_axis_tdest, - output wire output_0_axis_tuser, + output wire [USER_WIDTH-1:0] output_0_axis_tuser, output wire [DATA_WIDTH-1:0] output_1_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, output wire output_1_axis_tvalid, input wire output_1_axis_tready, output wire output_1_axis_tlast, + output wire [ID_WIDTH-1:0] output_1_axis_tid, output wire [DEST_WIDTH-1:0] output_1_axis_tdest, - output wire output_1_axis_tuser, + output wire [USER_WIDTH-1:0] output_1_axis_tuser, output wire [DATA_WIDTH-1:0] output_2_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, output wire output_2_axis_tvalid, input wire output_2_axis_tready, output wire output_2_axis_tlast, + output wire [ID_WIDTH-1:0] output_2_axis_tid, output wire [DEST_WIDTH-1:0] output_2_axis_tdest, - output wire output_2_axis_tuser, + output wire [USER_WIDTH-1:0] output_2_axis_tuser, output wire [DATA_WIDTH-1:0] output_3_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, output wire output_3_axis_tvalid, input wire output_3_axis_tready, output wire output_3_axis_tlast, + output wire [ID_WIDTH-1:0] output_3_axis_tid, output wire [DEST_WIDTH-1:0] output_3_axis_tdest, - output wire output_3_axis_tuser + output wire [USER_WIDTH-1:0] output_3_axis_tuser ); // check configuration @@ -183,37 +205,45 @@ reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; // internal datapath -reg [DATA_WIDTH-1:0] output_0_axis_tdata_int; -reg output_0_axis_tvalid_int; -reg output_0_axis_tready_int_reg = 1'b0; -reg output_0_axis_tlast_int; -reg [DEST_WIDTH-1:0] output_0_axis_tdest_int; -reg output_0_axis_tuser_int; -wire output_0_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_0_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_int; +reg output_0_axis_tvalid_int; +reg output_0_axis_tready_int_reg = 1'b0; +reg output_0_axis_tlast_int; +reg [ID_WIDTH-1:0] output_0_axis_tid_int; +reg [DEST_WIDTH-1:0] output_0_axis_tdest_int; +reg [USER_WIDTH-1:0] output_0_axis_tuser_int; +wire output_0_axis_tready_int_early; -reg [DATA_WIDTH-1:0] output_1_axis_tdata_int; -reg output_1_axis_tvalid_int; -reg output_1_axis_tready_int_reg = 1'b0; -reg output_1_axis_tlast_int; -reg [DEST_WIDTH-1:0] output_1_axis_tdest_int; -reg output_1_axis_tuser_int; -wire output_1_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_1_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_int; +reg output_1_axis_tvalid_int; +reg output_1_axis_tready_int_reg = 1'b0; +reg output_1_axis_tlast_int; +reg [ID_WIDTH-1:0] output_1_axis_tid_int; +reg [DEST_WIDTH-1:0] output_1_axis_tdest_int; +reg [USER_WIDTH-1:0] output_1_axis_tuser_int; +wire output_1_axis_tready_int_early; -reg [DATA_WIDTH-1:0] output_2_axis_tdata_int; -reg output_2_axis_tvalid_int; -reg output_2_axis_tready_int_reg = 1'b0; -reg output_2_axis_tlast_int; -reg [DEST_WIDTH-1:0] output_2_axis_tdest_int; -reg output_2_axis_tuser_int; -wire output_2_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_2_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_int; +reg output_2_axis_tvalid_int; +reg output_2_axis_tready_int_reg = 1'b0; +reg output_2_axis_tlast_int; +reg [ID_WIDTH-1:0] output_2_axis_tid_int; +reg [DEST_WIDTH-1:0] output_2_axis_tdest_int; +reg [USER_WIDTH-1:0] output_2_axis_tuser_int; +wire output_2_axis_tready_int_early; -reg [DATA_WIDTH-1:0] output_3_axis_tdata_int; -reg output_3_axis_tvalid_int; -reg output_3_axis_tready_int_reg = 1'b0; -reg output_3_axis_tlast_int; -reg [DEST_WIDTH-1:0] output_3_axis_tdest_int; -reg output_3_axis_tuser_int; -wire output_3_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_3_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_int; +reg output_3_axis_tvalid_int; +reg output_3_axis_tready_int_reg = 1'b0; +reg output_3_axis_tlast_int; +reg [ID_WIDTH-1:0] output_3_axis_tid_int; +reg [DEST_WIDTH-1:0] output_3_axis_tdest_int; +reg [USER_WIDTH-1:0] output_3_axis_tuser_int; +wire output_3_axis_tready_int_early; assign input_0_axis_tready = input_0_axis_tready_reg; assign input_1_axis_tready = input_1_axis_tready_reg; @@ -223,209 +253,257 @@ assign input_3_axis_tready = input_3_axis_tready_reg; // mux for incoming packet reg [DATA_WIDTH-1:0] current_input_0_axis_tdata; -reg current_input_0_axis_tvalid; -reg current_input_0_axis_tready; -reg current_input_0_axis_tlast; +reg [DATA_WIDTH-1:0] current_input_0_axis_tkeep; +reg current_input_0_axis_tvalid; +reg current_input_0_axis_tready; +reg current_input_0_axis_tlast; +reg [ID_WIDTH-1:0] current_input_0_axis_tid; reg [DEST_WIDTH-1:0] current_input_0_axis_tdest; -reg current_input_0_axis_tuser; +reg [USER_WIDTH-1:0] current_input_0_axis_tuser; always @* begin case (select_0_reg) 2'd0: begin - current_input_0_axis_tdata = input_0_axis_tdata; + current_input_0_axis_tdata = input_0_axis_tdata; + current_input_0_axis_tkeep = input_0_axis_tkeep; current_input_0_axis_tvalid = input_0_axis_tvalid; current_input_0_axis_tready = input_0_axis_tready; - current_input_0_axis_tlast = input_0_axis_tlast; - current_input_0_axis_tdest = input_0_axis_tdest; - current_input_0_axis_tuser = input_0_axis_tuser; + current_input_0_axis_tlast = input_0_axis_tlast; + current_input_0_axis_tid = input_0_axis_tid; + current_input_0_axis_tdest = input_0_axis_tdest; + current_input_0_axis_tuser = input_0_axis_tuser; end 2'd1: begin - current_input_0_axis_tdata = input_1_axis_tdata; + current_input_0_axis_tdata = input_1_axis_tdata; + current_input_0_axis_tkeep = input_1_axis_tkeep; current_input_0_axis_tvalid = input_1_axis_tvalid; current_input_0_axis_tready = input_1_axis_tready; - current_input_0_axis_tlast = input_1_axis_tlast; - current_input_0_axis_tdest = input_1_axis_tdest; - current_input_0_axis_tuser = input_1_axis_tuser; + current_input_0_axis_tlast = input_1_axis_tlast; + current_input_0_axis_tid = input_1_axis_tid; + current_input_0_axis_tdest = input_1_axis_tdest; + current_input_0_axis_tuser = input_1_axis_tuser; end 2'd2: begin - current_input_0_axis_tdata = input_2_axis_tdata; + current_input_0_axis_tdata = input_2_axis_tdata; + current_input_0_axis_tkeep = input_2_axis_tkeep; current_input_0_axis_tvalid = input_2_axis_tvalid; current_input_0_axis_tready = input_2_axis_tready; - current_input_0_axis_tlast = input_2_axis_tlast; - current_input_0_axis_tdest = input_2_axis_tdest; - current_input_0_axis_tuser = input_2_axis_tuser; + current_input_0_axis_tlast = input_2_axis_tlast; + current_input_0_axis_tid = input_2_axis_tid; + current_input_0_axis_tdest = input_2_axis_tdest; + current_input_0_axis_tuser = input_2_axis_tuser; end 2'd3: begin - current_input_0_axis_tdata = input_3_axis_tdata; + current_input_0_axis_tdata = input_3_axis_tdata; + current_input_0_axis_tkeep = input_3_axis_tkeep; current_input_0_axis_tvalid = input_3_axis_tvalid; current_input_0_axis_tready = input_3_axis_tready; - current_input_0_axis_tlast = input_3_axis_tlast; - current_input_0_axis_tdest = input_3_axis_tdest; - current_input_0_axis_tuser = input_3_axis_tuser; + current_input_0_axis_tlast = input_3_axis_tlast; + current_input_0_axis_tid = input_3_axis_tid; + current_input_0_axis_tdest = input_3_axis_tdest; + current_input_0_axis_tuser = input_3_axis_tuser; end default: begin - current_input_0_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_0_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_0_axis_tkeep = {KEEP_WIDTH{1'b0}}; current_input_0_axis_tvalid = 1'b0; current_input_0_axis_tready = 1'b0; - current_input_0_axis_tlast = 1'b0; - current_input_0_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_0_axis_tuser = 1'b0; + current_input_0_axis_tlast = 1'b0; + current_input_0_axis_tid = {ID_WIDTH{1'b0}}; + current_input_0_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_0_axis_tuser = {USER_WIDTH{1'b0}}; end endcase end reg [DATA_WIDTH-1:0] current_input_1_axis_tdata; -reg current_input_1_axis_tvalid; -reg current_input_1_axis_tready; -reg current_input_1_axis_tlast; +reg [DATA_WIDTH-1:0] current_input_1_axis_tkeep; +reg current_input_1_axis_tvalid; +reg current_input_1_axis_tready; +reg current_input_1_axis_tlast; +reg [ID_WIDTH-1:0] current_input_1_axis_tid; reg [DEST_WIDTH-1:0] current_input_1_axis_tdest; -reg current_input_1_axis_tuser; +reg [USER_WIDTH-1:0] current_input_1_axis_tuser; always @* begin case (select_1_reg) 2'd0: begin - current_input_1_axis_tdata = input_0_axis_tdata; + current_input_1_axis_tdata = input_0_axis_tdata; + current_input_1_axis_tkeep = input_0_axis_tkeep; current_input_1_axis_tvalid = input_0_axis_tvalid; current_input_1_axis_tready = input_0_axis_tready; - current_input_1_axis_tlast = input_0_axis_tlast; - current_input_1_axis_tdest = input_0_axis_tdest; - current_input_1_axis_tuser = input_0_axis_tuser; + current_input_1_axis_tlast = input_0_axis_tlast; + current_input_1_axis_tid = input_0_axis_tid; + current_input_1_axis_tdest = input_0_axis_tdest; + current_input_1_axis_tuser = input_0_axis_tuser; end 2'd1: begin - current_input_1_axis_tdata = input_1_axis_tdata; + current_input_1_axis_tdata = input_1_axis_tdata; + current_input_1_axis_tkeep = input_1_axis_tkeep; current_input_1_axis_tvalid = input_1_axis_tvalid; current_input_1_axis_tready = input_1_axis_tready; - current_input_1_axis_tlast = input_1_axis_tlast; - current_input_1_axis_tdest = input_1_axis_tdest; - current_input_1_axis_tuser = input_1_axis_tuser; + current_input_1_axis_tlast = input_1_axis_tlast; + current_input_1_axis_tid = input_1_axis_tid; + current_input_1_axis_tdest = input_1_axis_tdest; + current_input_1_axis_tuser = input_1_axis_tuser; end 2'd2: begin - current_input_1_axis_tdata = input_2_axis_tdata; + current_input_1_axis_tdata = input_2_axis_tdata; + current_input_1_axis_tkeep = input_2_axis_tkeep; current_input_1_axis_tvalid = input_2_axis_tvalid; current_input_1_axis_tready = input_2_axis_tready; - current_input_1_axis_tlast = input_2_axis_tlast; - current_input_1_axis_tdest = input_2_axis_tdest; - current_input_1_axis_tuser = input_2_axis_tuser; + current_input_1_axis_tlast = input_2_axis_tlast; + current_input_1_axis_tid = input_2_axis_tid; + current_input_1_axis_tdest = input_2_axis_tdest; + current_input_1_axis_tuser = input_2_axis_tuser; end 2'd3: begin - current_input_1_axis_tdata = input_3_axis_tdata; + current_input_1_axis_tdata = input_3_axis_tdata; + current_input_1_axis_tkeep = input_3_axis_tkeep; current_input_1_axis_tvalid = input_3_axis_tvalid; current_input_1_axis_tready = input_3_axis_tready; - current_input_1_axis_tlast = input_3_axis_tlast; - current_input_1_axis_tdest = input_3_axis_tdest; - current_input_1_axis_tuser = input_3_axis_tuser; + current_input_1_axis_tlast = input_3_axis_tlast; + current_input_1_axis_tid = input_3_axis_tid; + current_input_1_axis_tdest = input_3_axis_tdest; + current_input_1_axis_tuser = input_3_axis_tuser; end default: begin - current_input_1_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_1_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_1_axis_tkeep = {KEEP_WIDTH{1'b0}}; current_input_1_axis_tvalid = 1'b0; current_input_1_axis_tready = 1'b0; - current_input_1_axis_tlast = 1'b0; - current_input_1_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_1_axis_tuser = 1'b0; + current_input_1_axis_tlast = 1'b0; + current_input_1_axis_tid = {ID_WIDTH{1'b0}}; + current_input_1_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_1_axis_tuser = {USER_WIDTH{1'b0}}; end endcase end reg [DATA_WIDTH-1:0] current_input_2_axis_tdata; -reg current_input_2_axis_tvalid; -reg current_input_2_axis_tready; -reg current_input_2_axis_tlast; +reg [DATA_WIDTH-1:0] current_input_2_axis_tkeep; +reg current_input_2_axis_tvalid; +reg current_input_2_axis_tready; +reg current_input_2_axis_tlast; +reg [ID_WIDTH-1:0] current_input_2_axis_tid; reg [DEST_WIDTH-1:0] current_input_2_axis_tdest; -reg current_input_2_axis_tuser; +reg [USER_WIDTH-1:0] current_input_2_axis_tuser; always @* begin case (select_2_reg) 2'd0: begin - current_input_2_axis_tdata = input_0_axis_tdata; + current_input_2_axis_tdata = input_0_axis_tdata; + current_input_2_axis_tkeep = input_0_axis_tkeep; current_input_2_axis_tvalid = input_0_axis_tvalid; current_input_2_axis_tready = input_0_axis_tready; - current_input_2_axis_tlast = input_0_axis_tlast; - current_input_2_axis_tdest = input_0_axis_tdest; - current_input_2_axis_tuser = input_0_axis_tuser; + current_input_2_axis_tlast = input_0_axis_tlast; + current_input_2_axis_tid = input_0_axis_tid; + current_input_2_axis_tdest = input_0_axis_tdest; + current_input_2_axis_tuser = input_0_axis_tuser; end 2'd1: begin - current_input_2_axis_tdata = input_1_axis_tdata; + current_input_2_axis_tdata = input_1_axis_tdata; + current_input_2_axis_tkeep = input_1_axis_tkeep; current_input_2_axis_tvalid = input_1_axis_tvalid; current_input_2_axis_tready = input_1_axis_tready; - current_input_2_axis_tlast = input_1_axis_tlast; - current_input_2_axis_tdest = input_1_axis_tdest; - current_input_2_axis_tuser = input_1_axis_tuser; + current_input_2_axis_tlast = input_1_axis_tlast; + current_input_2_axis_tid = input_1_axis_tid; + current_input_2_axis_tdest = input_1_axis_tdest; + current_input_2_axis_tuser = input_1_axis_tuser; end 2'd2: begin - current_input_2_axis_tdata = input_2_axis_tdata; + current_input_2_axis_tdata = input_2_axis_tdata; + current_input_2_axis_tkeep = input_2_axis_tkeep; current_input_2_axis_tvalid = input_2_axis_tvalid; current_input_2_axis_tready = input_2_axis_tready; - current_input_2_axis_tlast = input_2_axis_tlast; - current_input_2_axis_tdest = input_2_axis_tdest; - current_input_2_axis_tuser = input_2_axis_tuser; + current_input_2_axis_tlast = input_2_axis_tlast; + current_input_2_axis_tid = input_2_axis_tid; + current_input_2_axis_tdest = input_2_axis_tdest; + current_input_2_axis_tuser = input_2_axis_tuser; end 2'd3: begin - current_input_2_axis_tdata = input_3_axis_tdata; + current_input_2_axis_tdata = input_3_axis_tdata; + current_input_2_axis_tkeep = input_3_axis_tkeep; current_input_2_axis_tvalid = input_3_axis_tvalid; current_input_2_axis_tready = input_3_axis_tready; - current_input_2_axis_tlast = input_3_axis_tlast; - current_input_2_axis_tdest = input_3_axis_tdest; - current_input_2_axis_tuser = input_3_axis_tuser; + current_input_2_axis_tlast = input_3_axis_tlast; + current_input_2_axis_tid = input_3_axis_tid; + current_input_2_axis_tdest = input_3_axis_tdest; + current_input_2_axis_tuser = input_3_axis_tuser; end default: begin - current_input_2_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_2_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_2_axis_tkeep = {KEEP_WIDTH{1'b0}}; current_input_2_axis_tvalid = 1'b0; current_input_2_axis_tready = 1'b0; - current_input_2_axis_tlast = 1'b0; - current_input_2_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_2_axis_tuser = 1'b0; + current_input_2_axis_tlast = 1'b0; + current_input_2_axis_tid = {ID_WIDTH{1'b0}}; + current_input_2_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_2_axis_tuser = {USER_WIDTH{1'b0}}; end endcase end reg [DATA_WIDTH-1:0] current_input_3_axis_tdata; -reg current_input_3_axis_tvalid; -reg current_input_3_axis_tready; -reg current_input_3_axis_tlast; +reg [DATA_WIDTH-1:0] current_input_3_axis_tkeep; +reg current_input_3_axis_tvalid; +reg current_input_3_axis_tready; +reg current_input_3_axis_tlast; +reg [ID_WIDTH-1:0] current_input_3_axis_tid; reg [DEST_WIDTH-1:0] current_input_3_axis_tdest; -reg current_input_3_axis_tuser; +reg [USER_WIDTH-1:0] current_input_3_axis_tuser; always @* begin case (select_3_reg) 2'd0: begin - current_input_3_axis_tdata = input_0_axis_tdata; + current_input_3_axis_tdata = input_0_axis_tdata; + current_input_3_axis_tkeep = input_0_axis_tkeep; current_input_3_axis_tvalid = input_0_axis_tvalid; current_input_3_axis_tready = input_0_axis_tready; - current_input_3_axis_tlast = input_0_axis_tlast; - current_input_3_axis_tdest = input_0_axis_tdest; - current_input_3_axis_tuser = input_0_axis_tuser; + current_input_3_axis_tlast = input_0_axis_tlast; + current_input_3_axis_tid = input_0_axis_tid; + current_input_3_axis_tdest = input_0_axis_tdest; + current_input_3_axis_tuser = input_0_axis_tuser; end 2'd1: begin - current_input_3_axis_tdata = input_1_axis_tdata; + current_input_3_axis_tdata = input_1_axis_tdata; + current_input_3_axis_tkeep = input_1_axis_tkeep; current_input_3_axis_tvalid = input_1_axis_tvalid; current_input_3_axis_tready = input_1_axis_tready; - current_input_3_axis_tlast = input_1_axis_tlast; - current_input_3_axis_tdest = input_1_axis_tdest; - current_input_3_axis_tuser = input_1_axis_tuser; + current_input_3_axis_tlast = input_1_axis_tlast; + current_input_3_axis_tid = input_1_axis_tid; + current_input_3_axis_tdest = input_1_axis_tdest; + current_input_3_axis_tuser = input_1_axis_tuser; end 2'd2: begin - current_input_3_axis_tdata = input_2_axis_tdata; + current_input_3_axis_tdata = input_2_axis_tdata; + current_input_3_axis_tkeep = input_2_axis_tkeep; current_input_3_axis_tvalid = input_2_axis_tvalid; current_input_3_axis_tready = input_2_axis_tready; - current_input_3_axis_tlast = input_2_axis_tlast; - current_input_3_axis_tdest = input_2_axis_tdest; - current_input_3_axis_tuser = input_2_axis_tuser; + current_input_3_axis_tlast = input_2_axis_tlast; + current_input_3_axis_tid = input_2_axis_tid; + current_input_3_axis_tdest = input_2_axis_tdest; + current_input_3_axis_tuser = input_2_axis_tuser; end 2'd3: begin - current_input_3_axis_tdata = input_3_axis_tdata; + current_input_3_axis_tdata = input_3_axis_tdata; + current_input_3_axis_tkeep = input_3_axis_tkeep; current_input_3_axis_tvalid = input_3_axis_tvalid; current_input_3_axis_tready = input_3_axis_tready; - current_input_3_axis_tlast = input_3_axis_tlast; - current_input_3_axis_tdest = input_3_axis_tdest; - current_input_3_axis_tuser = input_3_axis_tuser; + current_input_3_axis_tlast = input_3_axis_tlast; + current_input_3_axis_tid = input_3_axis_tid; + current_input_3_axis_tdest = input_3_axis_tdest; + current_input_3_axis_tuser = input_3_axis_tuser; end default: begin - current_input_3_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_3_axis_tdata = {DATA_WIDTH{1'b0}}; + current_input_3_axis_tkeep = {KEEP_WIDTH{1'b0}}; current_input_3_axis_tvalid = 1'b0; current_input_3_axis_tready = 1'b0; - current_input_3_axis_tlast = 1'b0; - current_input_3_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_3_axis_tuser = 1'b0; + current_input_3_axis_tlast = 1'b0; + current_input_3_axis_tid = {ID_WIDTH{1'b0}}; + current_input_3_axis_tdest = {DEST_WIDTH{1'b0}}; + current_input_3_axis_tuser = {USER_WIDTH{1'b0}}; end endcase end @@ -594,29 +672,37 @@ always @* begin input_2_axis_tready_next = 1'b0; input_3_axis_tready_next = 1'b0; - output_0_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_0_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_0_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; output_0_axis_tvalid_int = 1'b0; - output_0_axis_tlast_int = 1'b0; - output_0_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_0_axis_tuser_int = 1'b0; + output_0_axis_tlast_int = 1'b0; + output_0_axis_tid_int = {ID_WIDTH{1'b0}}; + output_0_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_0_axis_tuser_int = {USER_WIDTH{1'b0}}; - output_1_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_1_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_1_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; output_1_axis_tvalid_int = 1'b0; - output_1_axis_tlast_int = 1'b0; - output_1_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_1_axis_tuser_int = 1'b0; + output_1_axis_tlast_int = 1'b0; + output_1_axis_tid_int = {ID_WIDTH{1'b0}}; + output_1_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_1_axis_tuser_int = {USER_WIDTH{1'b0}}; - output_2_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_2_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_2_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; output_2_axis_tvalid_int = 1'b0; - output_2_axis_tlast_int = 1'b0; - output_2_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_2_axis_tuser_int = 1'b0; + output_2_axis_tlast_int = 1'b0; + output_2_axis_tid_int = {ID_WIDTH{1'b0}}; + output_2_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_2_axis_tuser_int = {USER_WIDTH{1'b0}}; - output_3_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_3_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_3_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; output_3_axis_tvalid_int = 1'b0; - output_3_axis_tlast_int = 1'b0; - output_3_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_3_axis_tuser_int = 1'b0; + output_3_axis_tlast_int = 1'b0; + output_3_axis_tid_int = {ID_WIDTH{1'b0}}; + output_3_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_3_axis_tuser_int = {USER_WIDTH{1'b0}}; // input decoding @@ -787,29 +873,37 @@ always @* begin // pass through selected packet data - output_0_axis_tdata_int = current_input_0_axis_tdata; + output_0_axis_tdata_int = current_input_0_axis_tdata; + output_0_axis_tkeep_int = current_input_0_axis_tkeep; output_0_axis_tvalid_int = current_input_0_axis_tvalid & current_input_0_axis_tready & enable_0_reg; - output_0_axis_tlast_int = current_input_0_axis_tlast; - output_0_axis_tdest_int = current_input_0_axis_tdest; - output_0_axis_tuser_int = current_input_0_axis_tuser; + output_0_axis_tlast_int = current_input_0_axis_tlast; + output_0_axis_tid_int = current_input_0_axis_tid; + output_0_axis_tdest_int = current_input_0_axis_tdest; + output_0_axis_tuser_int = current_input_0_axis_tuser; - output_1_axis_tdata_int = current_input_1_axis_tdata; + output_1_axis_tdata_int = current_input_1_axis_tdata; + output_1_axis_tkeep_int = current_input_1_axis_tkeep; output_1_axis_tvalid_int = current_input_1_axis_tvalid & current_input_1_axis_tready & enable_1_reg; - output_1_axis_tlast_int = current_input_1_axis_tlast; - output_1_axis_tdest_int = current_input_1_axis_tdest; - output_1_axis_tuser_int = current_input_1_axis_tuser; + output_1_axis_tlast_int = current_input_1_axis_tlast; + output_1_axis_tid_int = current_input_1_axis_tid; + output_1_axis_tdest_int = current_input_1_axis_tdest; + output_1_axis_tuser_int = current_input_1_axis_tuser; - output_2_axis_tdata_int = current_input_2_axis_tdata; + output_2_axis_tdata_int = current_input_2_axis_tdata; + output_2_axis_tkeep_int = current_input_2_axis_tkeep; output_2_axis_tvalid_int = current_input_2_axis_tvalid & current_input_2_axis_tready & enable_2_reg; - output_2_axis_tlast_int = current_input_2_axis_tlast; - output_2_axis_tdest_int = current_input_2_axis_tdest; - output_2_axis_tuser_int = current_input_2_axis_tuser; + output_2_axis_tlast_int = current_input_2_axis_tlast; + output_2_axis_tid_int = current_input_2_axis_tid; + output_2_axis_tdest_int = current_input_2_axis_tdest; + output_2_axis_tuser_int = current_input_2_axis_tuser; - output_3_axis_tdata_int = current_input_3_axis_tdata; + output_3_axis_tdata_int = current_input_3_axis_tdata; + output_3_axis_tkeep_int = current_input_3_axis_tkeep; output_3_axis_tvalid_int = current_input_3_axis_tvalid & current_input_3_axis_tready & enable_3_reg; - output_3_axis_tlast_int = current_input_3_axis_tlast; - output_3_axis_tdest_int = current_input_3_axis_tdest; - output_3_axis_tuser_int = current_input_3_axis_tuser; + output_3_axis_tlast_int = current_input_3_axis_tlast; + output_3_axis_tid_int = current_input_3_axis_tid; + output_3_axis_tdest_int = current_input_3_axis_tdest; + output_3_axis_tuser_int = current_input_3_axis_tuser; end always @(posedge clk) begin @@ -867,28 +961,34 @@ always @(posedge clk) begin end // output 0 datapath logic -reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_0_axis_tvalid_reg = 1'b0, output_0_axis_tvalid_next; -reg output_0_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] output_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg output_0_axis_tuser_reg = 1'b0; +reg output_0_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_0_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_0_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_0_axis_tvalid_reg = 1'b0, temp_0_axis_tvalid_next; -reg temp_0_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] temp_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg temp_0_axis_tuser_reg = 1'b0; +reg temp_0_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_0_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_0_axis_tuser_reg = 1'b0; // datapath control reg store_0_axis_int_to_output; reg store_0_axis_int_to_temp; reg store_0_axis_temp_to_output; -assign output_0_axis_tdata = output_0_axis_tdata_reg; +assign output_0_axis_tdata = output_0_axis_tdata_reg; +assign output_0_axis_tkeep = KEEP_ENABLE ? output_0_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_0_axis_tvalid = output_0_axis_tvalid_reg; -assign output_0_axis_tlast = output_0_axis_tlast_reg; -assign output_0_axis_tdest = output_0_axis_tdest_reg; -assign output_0_axis_tuser = output_0_axis_tuser_reg; +assign output_0_axis_tlast = output_0_axis_tlast_reg; +assign output_0_axis_tid = ID_ENABLE ? output_0_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_0_axis_tdest = output_0_axis_tdest_reg; +assign output_0_axis_tuser = USER_ENABLE ? output_0_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_0_axis_tready_int_early = output_0_axis_tready | (~temp_0_axis_tvalid_reg & (~output_0_axis_tvalid_reg | ~output_0_axis_tvalid_int)); @@ -901,7 +1001,7 @@ always @* begin store_0_axis_int_to_output = 1'b0; store_0_axis_int_to_temp = 1'b0; store_0_axis_temp_to_output = 1'b0; - + if (output_0_axis_tready_int_reg) begin // input is ready if (output_0_axis_tready | ~output_0_axis_tvalid_reg) begin @@ -935,47 +1035,59 @@ always @(posedge clk) begin // datapath if (store_0_axis_int_to_output) begin output_0_axis_tdata_reg <= output_0_axis_tdata_int; + output_0_axis_tkeep_reg <= output_0_axis_tkeep_int; output_0_axis_tlast_reg <= output_0_axis_tlast_int; + output_0_axis_tid_reg <= output_0_axis_tid_int; output_0_axis_tdest_reg <= output_0_axis_tdest_int; output_0_axis_tuser_reg <= output_0_axis_tuser_int; end else if (store_0_axis_temp_to_output) begin output_0_axis_tdata_reg <= temp_0_axis_tdata_reg; + output_0_axis_tkeep_reg <= temp_0_axis_tkeep_reg; output_0_axis_tlast_reg <= temp_0_axis_tlast_reg; + output_0_axis_tid_reg <= temp_0_axis_tid_reg; output_0_axis_tdest_reg <= temp_0_axis_tdest_reg; output_0_axis_tuser_reg <= temp_0_axis_tuser_reg; end if (store_0_axis_int_to_temp) begin temp_0_axis_tdata_reg <= output_0_axis_tdata_int; + temp_0_axis_tkeep_reg <= output_0_axis_tkeep_int; temp_0_axis_tlast_reg <= output_0_axis_tlast_int; + temp_0_axis_tid_reg <= output_0_axis_tid_int; temp_0_axis_tdest_reg <= output_0_axis_tdest_int; temp_0_axis_tuser_reg <= output_0_axis_tuser_int; end end // output 1 datapath logic -reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_1_axis_tvalid_reg = 1'b0, output_1_axis_tvalid_next; -reg output_1_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] output_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg output_1_axis_tuser_reg = 1'b0; +reg output_1_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_1_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_1_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_1_axis_tvalid_reg = 1'b0, temp_1_axis_tvalid_next; -reg temp_1_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] temp_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg temp_1_axis_tuser_reg = 1'b0; +reg temp_1_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_1_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_1_axis_tuser_reg = 1'b0; // datapath control reg store_1_axis_int_to_output; reg store_1_axis_int_to_temp; reg store_1_axis_temp_to_output; -assign output_1_axis_tdata = output_1_axis_tdata_reg; +assign output_1_axis_tdata = output_1_axis_tdata_reg; +assign output_1_axis_tkeep = KEEP_ENABLE ? output_1_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_1_axis_tvalid = output_1_axis_tvalid_reg; -assign output_1_axis_tlast = output_1_axis_tlast_reg; -assign output_1_axis_tdest = output_1_axis_tdest_reg; -assign output_1_axis_tuser = output_1_axis_tuser_reg; +assign output_1_axis_tlast = output_1_axis_tlast_reg; +assign output_1_axis_tid = ID_ENABLE ? output_1_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_1_axis_tdest = output_1_axis_tdest_reg; +assign output_1_axis_tuser = USER_ENABLE ? output_1_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_1_axis_tready_int_early = output_1_axis_tready | (~temp_1_axis_tvalid_reg & (~output_1_axis_tvalid_reg | ~output_1_axis_tvalid_int)); @@ -988,7 +1100,7 @@ always @* begin store_1_axis_int_to_output = 1'b0; store_1_axis_int_to_temp = 1'b0; store_1_axis_temp_to_output = 1'b0; - + if (output_1_axis_tready_int_reg) begin // input is ready if (output_1_axis_tready | ~output_1_axis_tvalid_reg) begin @@ -1022,47 +1134,59 @@ always @(posedge clk) begin // datapath if (store_1_axis_int_to_output) begin output_1_axis_tdata_reg <= output_1_axis_tdata_int; + output_1_axis_tkeep_reg <= output_1_axis_tkeep_int; output_1_axis_tlast_reg <= output_1_axis_tlast_int; + output_1_axis_tid_reg <= output_1_axis_tid_int; output_1_axis_tdest_reg <= output_1_axis_tdest_int; output_1_axis_tuser_reg <= output_1_axis_tuser_int; end else if (store_1_axis_temp_to_output) begin output_1_axis_tdata_reg <= temp_1_axis_tdata_reg; + output_1_axis_tkeep_reg <= temp_1_axis_tkeep_reg; output_1_axis_tlast_reg <= temp_1_axis_tlast_reg; + output_1_axis_tid_reg <= temp_1_axis_tid_reg; output_1_axis_tdest_reg <= temp_1_axis_tdest_reg; output_1_axis_tuser_reg <= temp_1_axis_tuser_reg; end if (store_1_axis_int_to_temp) begin temp_1_axis_tdata_reg <= output_1_axis_tdata_int; + temp_1_axis_tkeep_reg <= output_1_axis_tkeep_int; temp_1_axis_tlast_reg <= output_1_axis_tlast_int; + temp_1_axis_tid_reg <= output_1_axis_tid_int; temp_1_axis_tdest_reg <= output_1_axis_tdest_int; temp_1_axis_tuser_reg <= output_1_axis_tuser_int; end end // output 2 datapath logic -reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_2_axis_tvalid_reg = 1'b0, output_2_axis_tvalid_next; -reg output_2_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] output_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg output_2_axis_tuser_reg = 1'b0; +reg output_2_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_2_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_2_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_2_axis_tvalid_reg = 1'b0, temp_2_axis_tvalid_next; -reg temp_2_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] temp_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg temp_2_axis_tuser_reg = 1'b0; +reg temp_2_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_2_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_2_axis_tuser_reg = 1'b0; // datapath control reg store_2_axis_int_to_output; reg store_2_axis_int_to_temp; reg store_2_axis_temp_to_output; -assign output_2_axis_tdata = output_2_axis_tdata_reg; +assign output_2_axis_tdata = output_2_axis_tdata_reg; +assign output_2_axis_tkeep = KEEP_ENABLE ? output_2_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_2_axis_tvalid = output_2_axis_tvalid_reg; -assign output_2_axis_tlast = output_2_axis_tlast_reg; -assign output_2_axis_tdest = output_2_axis_tdest_reg; -assign output_2_axis_tuser = output_2_axis_tuser_reg; +assign output_2_axis_tlast = output_2_axis_tlast_reg; +assign output_2_axis_tid = ID_ENABLE ? output_2_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_2_axis_tdest = output_2_axis_tdest_reg; +assign output_2_axis_tuser = USER_ENABLE ? output_2_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_2_axis_tready_int_early = output_2_axis_tready | (~temp_2_axis_tvalid_reg & (~output_2_axis_tvalid_reg | ~output_2_axis_tvalid_int)); @@ -1075,7 +1199,7 @@ always @* begin store_2_axis_int_to_output = 1'b0; store_2_axis_int_to_temp = 1'b0; store_2_axis_temp_to_output = 1'b0; - + if (output_2_axis_tready_int_reg) begin // input is ready if (output_2_axis_tready | ~output_2_axis_tvalid_reg) begin @@ -1109,47 +1233,59 @@ always @(posedge clk) begin // datapath if (store_2_axis_int_to_output) begin output_2_axis_tdata_reg <= output_2_axis_tdata_int; + output_2_axis_tkeep_reg <= output_2_axis_tkeep_int; output_2_axis_tlast_reg <= output_2_axis_tlast_int; + output_2_axis_tid_reg <= output_2_axis_tid_int; output_2_axis_tdest_reg <= output_2_axis_tdest_int; output_2_axis_tuser_reg <= output_2_axis_tuser_int; end else if (store_2_axis_temp_to_output) begin output_2_axis_tdata_reg <= temp_2_axis_tdata_reg; + output_2_axis_tkeep_reg <= temp_2_axis_tkeep_reg; output_2_axis_tlast_reg <= temp_2_axis_tlast_reg; + output_2_axis_tid_reg <= temp_2_axis_tid_reg; output_2_axis_tdest_reg <= temp_2_axis_tdest_reg; output_2_axis_tuser_reg <= temp_2_axis_tuser_reg; end if (store_2_axis_int_to_temp) begin temp_2_axis_tdata_reg <= output_2_axis_tdata_int; + temp_2_axis_tkeep_reg <= output_2_axis_tkeep_int; temp_2_axis_tlast_reg <= output_2_axis_tlast_int; + temp_2_axis_tid_reg <= output_2_axis_tid_int; temp_2_axis_tdest_reg <= output_2_axis_tdest_int; temp_2_axis_tuser_reg <= output_2_axis_tuser_int; end end // output 3 datapath logic -reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_3_axis_tvalid_reg = 1'b0, output_3_axis_tvalid_next; -reg output_3_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] output_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg output_3_axis_tuser_reg = 1'b0; +reg output_3_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_3_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_3_axis_tuser_reg = 1'b0; -reg [DATA_WIDTH-1:0] temp_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_3_axis_tvalid_reg = 1'b0, temp_3_axis_tvalid_next; -reg temp_3_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] temp_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg temp_3_axis_tuser_reg = 1'b0; +reg temp_3_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_3_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_3_axis_tuser_reg = 1'b0; // datapath control reg store_3_axis_int_to_output; reg store_3_axis_int_to_temp; reg store_3_axis_temp_to_output; -assign output_3_axis_tdata = output_3_axis_tdata_reg; +assign output_3_axis_tdata = output_3_axis_tdata_reg; +assign output_3_axis_tkeep = KEEP_ENABLE ? output_3_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_3_axis_tvalid = output_3_axis_tvalid_reg; -assign output_3_axis_tlast = output_3_axis_tlast_reg; -assign output_3_axis_tdest = output_3_axis_tdest_reg; -assign output_3_axis_tuser = output_3_axis_tuser_reg; +assign output_3_axis_tlast = output_3_axis_tlast_reg; +assign output_3_axis_tid = ID_ENABLE ? output_3_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_3_axis_tdest = output_3_axis_tdest_reg; +assign output_3_axis_tuser = USER_ENABLE ? output_3_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_3_axis_tready_int_early = output_3_axis_tready | (~temp_3_axis_tvalid_reg & (~output_3_axis_tvalid_reg | ~output_3_axis_tvalid_int)); @@ -1162,7 +1298,7 @@ always @* begin store_3_axis_int_to_output = 1'b0; store_3_axis_int_to_temp = 1'b0; store_3_axis_temp_to_output = 1'b0; - + if (output_3_axis_tready_int_reg) begin // input is ready if (output_3_axis_tready | ~output_3_axis_tvalid_reg) begin @@ -1196,19 +1332,25 @@ always @(posedge clk) begin // datapath if (store_3_axis_int_to_output) begin output_3_axis_tdata_reg <= output_3_axis_tdata_int; + output_3_axis_tkeep_reg <= output_3_axis_tkeep_int; output_3_axis_tlast_reg <= output_3_axis_tlast_int; + output_3_axis_tid_reg <= output_3_axis_tid_int; output_3_axis_tdest_reg <= output_3_axis_tdest_int; output_3_axis_tuser_reg <= output_3_axis_tuser_int; end else if (store_3_axis_temp_to_output) begin output_3_axis_tdata_reg <= temp_3_axis_tdata_reg; + output_3_axis_tkeep_reg <= temp_3_axis_tkeep_reg; output_3_axis_tlast_reg <= temp_3_axis_tlast_reg; + output_3_axis_tid_reg <= temp_3_axis_tid_reg; output_3_axis_tdest_reg <= temp_3_axis_tdest_reg; output_3_axis_tuser_reg <= temp_3_axis_tuser_reg; end if (store_3_axis_int_to_temp) begin temp_3_axis_tdata_reg <= output_3_axis_tdata_int; + temp_3_axis_tkeep_reg <= output_3_axis_tkeep_int; temp_3_axis_tlast_reg <= output_3_axis_tlast_int; + temp_3_axis_tid_reg <= output_3_axis_tid_int; temp_3_axis_tdest_reg <= output_3_axis_tdest_int; temp_3_axis_tuser_reg <= output_3_axis_tuser_int; end diff --git a/rtl/axis_switch_64.py b/rtl/axis_switch_64.py deleted file mode 100755 index 8f98540b0..000000000 --- a/rtl/axis_switch_64.py +++ /dev/null @@ -1,479 +0,0 @@ -#!/usr/bin/env python -""" -Generates an AXI Stream switch with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=[4], nargs='+', help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if type(ports) is int: - m = n = ports - elif len(ports) == 1: - m = n = ports[0] - else: - m, n = ports - - if name is None: - name = "axis_switch_64_{0}x{1}".format(m, n) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0}x{1} port AXI Stream switch {2}...".format(m, n, name)) - - cm = int(math.ceil(math.log(m, 2))) - cn = int(math.ceil(math.log(n, 2))) - - t = Template(u"""/* - -Copyright (c) 2016-2017 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 {{m}}x{{n}} switch (64 bit datapath) - */ -module {{name}} # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter DEST_WIDTH = {{cn}}, -{%- for p in range(n) %} - parameter OUT_{{p}}_BASE = {{p}}, - parameter OUT_{{p}}_TOP = {{p}}, - parameter OUT_{{p}}_CONNECT = {{m}}'b{% for p in range(m) %}1{% endfor %}, -{%- endfor %} - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "ROUND_ROBIN", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * AXI Stream inputs - */ -{%- for p in range(m) %} - input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, - input wire input_{{p}}_axis_tvalid, - output wire input_{{p}}_axis_tready, - input wire input_{{p}}_axis_tlast, - input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, - input wire input_{{p}}_axis_tuser, -{% endfor %} - /* - * AXI Stream outputs - */ -{%- for p in range(n) %} - output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, - output wire output_{{p}}_axis_tvalid, - input wire output_{{p}}_axis_tready, - output wire output_{{p}}_axis_tlast, - output wire [DEST_WIDTH-1:0] output_{{p}}_axis_tdest, - output wire output_{{p}}_axis_tuser{% if not loop.last %},{% endif %} -{% endfor -%} -); - -// check configuration -initial begin - if (2**DEST_WIDTH < {{n}}) begin - $error("Error: DEST_WIDTH too small for port count"); - $finish; - end - - if ({%- for p in range(n) %}(OUT_{{p}}_BASE & 2**DEST_WIDTH-1) != OUT_{{p}}_BASE || (OUT_{{p}}_TOP & 2**DEST_WIDTH-1) != OUT_{{p}}_TOP{% if not loop.last %} || - {% endif %}{% endfor -%}) begin - $error("Error: value out of range"); - $finish; - end - - if ({%- for p in range(n) %}OUT_{{p}}_BASE > OUT_{{p}}_TOP{% if not loop.last %} || - {% endif %}{% endfor -%}) begin - $error("Error: invalid range"); - $finish; - end - - if ({%- for p in range(n-1) %}{% set outer_loop = loop %}{%- for q in range(p+1,n) %}(OUT_{{p}}_BASE <= OUT_{{q}}_TOP && OUT_{{q}}_BASE <= OUT_{{p}}_TOP){% if not (loop.last and outer_loop.last) %} || - {% endif %}{% endfor -%}{% endfor -%}) begin - $error("Error: ranges overlap"); - $finish; - end -end -{%- for p in range(m) %} - -reg [{{n-1}}:0] input_{{p}}_request_reg = {{n}}'d0, input_{{p}}_request_next; -reg input_{{p}}_request_valid_reg = 1'b0, input_{{p}}_request_valid_next; -reg input_{{p}}_request_error_reg = 1'b0, input_{{p}}_request_error_next; -{%- endfor %} -{% for p in range(n) %} -reg [{{cm-1}}:0] select_{{p}}_reg = {{cm}}'d0, select_{{p}}_next; -{%- endfor %} -{% for p in range(n) %} -reg enable_{{p}}_reg = 1'b0, enable_{{p}}_next; -{%- endfor %} -{% for p in range(m) %} -reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; -{%- endfor %} - -// internal datapath -{%- for p in range(n) %} -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_int; -reg output_{{p}}_axis_tvalid_int; -reg output_{{p}}_axis_tready_int_reg = 1'b0; -reg output_{{p}}_axis_tlast_int; -reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_int; -reg output_{{p}}_axis_tuser_int; -wire output_{{p}}_axis_tready_int_early; -{% endfor %} -{%- for p in range(m) %} -assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; -{%- endfor %} - -// mux for incoming packet -{% for p in range(n) %} -reg [DATA_WIDTH-1:0] current_input_{{p}}_axis_tdata; -reg [KEEP_WIDTH-1:0] current_input_{{p}}_axis_tkeep; -reg current_input_{{p}}_axis_tvalid; -reg current_input_{{p}}_axis_tready; -reg current_input_{{p}}_axis_tlast; -reg [DEST_WIDTH-1:0] current_input_{{p}}_axis_tdest; -reg current_input_{{p}}_axis_tuser; - -always @* begin - case (select_{{p}}_reg) -{%- for q in range(m) %} - {{cm}}'d{{q}}: begin - current_input_{{p}}_axis_tdata = input_{{q}}_axis_tdata; - current_input_{{p}}_axis_tkeep = input_{{q}}_axis_tkeep; - current_input_{{p}}_axis_tvalid = input_{{q}}_axis_tvalid; - current_input_{{p}}_axis_tready = input_{{q}}_axis_tready; - current_input_{{p}}_axis_tlast = input_{{q}}_axis_tlast; - current_input_{{p}}_axis_tdest = input_{{q}}_axis_tdest; - current_input_{{p}}_axis_tuser = input_{{q}}_axis_tuser; - end -{%- endfor %} - default: begin - current_input_{{p}}_axis_tdata = {DATA_WIDTH{1'b0}}; - current_input_{{p}}_axis_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_{{p}}_axis_tvalid = 1'b0; - current_input_{{p}}_axis_tready = 1'b0; - current_input_{{p}}_axis_tlast = 1'b0; - current_input_{{p}}_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_{{p}}_axis_tuser = 1'b0; - end - endcase -end -{% endfor %} -// arbiter instances -{% for p in range(n) %} -wire [{{m-1}}:0] request_{{p}}; -wire [{{m-1}}:0] acknowledge_{{p}}; -wire [{{m-1}}:0] grant_{{p}}; -wire grant_valid_{{p}}; -wire [{{cm-1}}:0] grant_encoded_{{p}}; -{% endfor %} - -{%- for p in range(n) %} -arbiter #( - .PORTS({{m}}), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_{{p}}_inst ( - .clk(clk), - .rst(rst), - .request(request_{{p}}), - .acknowledge(acknowledge_{{p}}), - .grant(grant_{{p}}), - .grant_valid(grant_valid_{{p}}), - .grant_encoded(grant_encoded_{{p}}) -); -{% endfor %} -// request generation -{%- for p in range(n) %} -{%- for q in range(m) %} -assign request_{{p}}[{{q}}] = input_{{q}}_request_reg[{{p}}] & ~acknowledge_{{p}}[{{q}}]; -{%- endfor %} -{% endfor %} -// acknowledge generation -{%- for p in range(n) %} -{%- for q in range(m) %} -assign acknowledge_{{p}}[{{q}}] = grant_{{p}}[{{q}}] & input_{{q}}_axis_tvalid & input_{{q}}_axis_tready & input_{{q}}_axis_tlast; -{%- endfor %} -{% endfor %} -always @* begin -{%- for p in range(n) %} - select_{{p}}_next = select_{{p}}_reg; -{%- endfor %} -{% for p in range(n) %} - enable_{{p}}_next = enable_{{p}}_reg; -{%- endfor %} -{% for p in range(m) %} - input_{{p}}_request_next = input_{{p}}_request_reg; - input_{{p}}_request_valid_next = input_{{p}}_request_valid_reg; - input_{{p}}_request_error_next = input_{{p}}_request_error_reg; -{% endfor %} -{%- for p in range(m) %} - input_{{p}}_axis_tready_next = 1'b0; -{%- endfor %} -{% for p in range(n) %} - output_{{p}}_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_{{p}}_axis_tkeep_int = {DATA_WIDTH{1'b0}}; - output_{{p}}_axis_tvalid_int = 1'b0; - output_{{p}}_axis_tlast_int = 1'b0; - output_{{p}}_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_{{p}}_axis_tuser_int = 1'b0; -{% endfor %} - // input decoding -{% for p in range(m) %} - if (input_{{p}}_request_valid_reg | input_{{p}}_request_error_reg) begin - if (input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast) begin - input_{{p}}_request_next = {DEST_WIDTH{1'b0}}; - input_{{p}}_request_valid_next = 1'b0; - input_{{p}}_request_error_next = 1'b0; - end - end else if (input_{{p}}_axis_tvalid) begin -{%- for q in range(n) %} - input_{{p}}_request_next[{{q}}] = (input_{{p}}_axis_tdest >= OUT_{{q}}_BASE) & (input_{{p}}_axis_tdest <= OUT_{{q}}_TOP) & OUT_{{q}}_CONNECT[{{p}}]; -{%- endfor %} - - if (input_{{p}}_request_next) begin - input_{{p}}_request_valid_next = 1'b1; - end else begin - input_{{p}}_request_error_next = 1'b1; - end - end -{% endfor %} - // output control -{% for p in range(n) %} - if (current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready) begin - if (current_input_{{p}}_axis_tlast) begin - enable_{{p}}_next = 1'b0; - end - end - if (~enable_{{p}}_reg & grant_valid_{{p}}) begin - enable_{{p}}_next = 1'b1; - select_{{p}}_next = grant_encoded_{{p}}; - end -{% endfor %} - // generate ready signal on selected port -{% for p in range(n) %} - if (enable_{{p}}_next) begin - case (select_{{p}}_next) -{%- for q in range(m) %} - {{cm}}'d{{q}}: input_{{q}}_axis_tready_next = output_{{p}}_axis_tready_int_early; -{%- endfor %} - endcase - end -{% endfor %} - -{%- for p in range(m) %} - if (input_{{p}}_request_error_next) - input_{{p}}_axis_tready_next = 1'b1; -{%- endfor %} - - // pass through selected packet data -{% for p in range(n) %} - output_{{p}}_axis_tdata_int = current_input_{{p}}_axis_tdata; - output_{{p}}_axis_tkeep_int = current_input_{{p}}_axis_tkeep; - output_{{p}}_axis_tvalid_int = current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready & enable_{{p}}_reg; - output_{{p}}_axis_tlast_int = current_input_{{p}}_axis_tlast; - output_{{p}}_axis_tdest_int = current_input_{{p}}_axis_tdest; - output_{{p}}_axis_tuser_int = current_input_{{p}}_axis_tuser; -{% endfor -%} -end - -always @(posedge clk) begin - if (rst) begin -{%- for p in range(m) %} - input_{{p}}_request_reg <= {{n}}'d0; - input_{{p}}_request_valid_reg <= 1'b0; - input_{{p}}_request_error_reg <= 1'b0; -{%- endfor %} -{%- for p in range(n) %} - select_{{p}}_reg <= 2'd0; -{%- endfor %} -{%- for p in range(n) %} - enable_{{p}}_reg <= 1'b0; -{%- endfor %} -{%- for p in range(m) %} - input_{{p}}_axis_tready_reg <= 1'b0; -{%- endfor %} - end else begin -{%- for p in range(m) %} - input_{{p}}_request_reg <= input_{{p}}_request_next; - input_{{p}}_request_valid_reg <= input_{{p}}_request_valid_next; - input_{{p}}_request_error_reg <= input_{{p}}_request_error_next; -{%- endfor %} -{%- for p in range(n) %} - select_{{p}}_reg <= select_{{p}}_next; -{%- endfor %} -{%- for p in range(n) %} - enable_{{p}}_reg <= enable_{{p}}_next; -{%- endfor %} -{%- for p in range(m) %} - input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; -{%- endfor %} - end -end -{% for p in range(n) %} -// output {{p}} datapath logic -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_{{p}}_axis_tvalid_reg = 1'b0, output_{{p}}_axis_tvalid_next; -reg output_{{p}}_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg output_{{p}}_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_{{p}}_axis_tvalid_reg = 1'b0, temp_{{p}}_axis_tvalid_next; -reg temp_{{p}}_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] temp_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg temp_{{p}}_axis_tuser_reg = 1'b0; - -// datapath control -reg store_{{p}}_axis_int_to_output; -reg store_{{p}}_axis_int_to_temp; -reg store_{{p}}_axis_temp_to_output; - -assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; -assign output_{{p}}_axis_tkeep = output_{{p}}_axis_tkeep_reg; -assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; -assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; -assign output_{{p}}_axis_tdest = output_{{p}}_axis_tdest_reg; -assign output_{{p}}_axis_tuser = output_{{p}}_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_{{p}}_axis_tready_int_early = output_{{p}}_axis_tready | (~temp_{{p}}_axis_tvalid_reg & (~output_{{p}}_axis_tvalid_reg | ~output_{{p}}_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_reg; - temp_{{p}}_axis_tvalid_next = temp_{{p}}_axis_tvalid_reg; - - store_{{p}}_axis_int_to_output = 1'b0; - store_{{p}}_axis_int_to_temp = 1'b0; - store_{{p}}_axis_temp_to_output = 1'b0; - - if (output_{{p}}_axis_tready_int_reg) begin - // input is ready - if (output_{{p}}_axis_tready | ~output_{{p}}_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_int; - store_{{p}}_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_int; - store_{{p}}_axis_int_to_temp = 1'b1; - end - end else if (output_{{p}}_axis_tready) begin - // input is not ready, but output is ready - output_{{p}}_axis_tvalid_next = temp_{{p}}_axis_tvalid_reg; - temp_{{p}}_axis_tvalid_next = 1'b0; - store_{{p}}_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_{{p}}_axis_tvalid_reg <= 1'b0; - output_{{p}}_axis_tready_int_reg <= 1'b0; - temp_{{p}}_axis_tvalid_reg <= 1'b0; - end else begin - output_{{p}}_axis_tvalid_reg <= output_{{p}}_axis_tvalid_next; - output_{{p}}_axis_tready_int_reg <= output_{{p}}_axis_tready_int_early; - temp_{{p}}_axis_tvalid_reg <= temp_{{p}}_axis_tvalid_next; - end - - // datapath - if (store_{{p}}_axis_int_to_output) begin - output_{{p}}_axis_tdata_reg <= output_{{p}}_axis_tdata_int; - output_{{p}}_axis_tkeep_reg <= output_{{p}}_axis_tkeep_int; - output_{{p}}_axis_tlast_reg <= output_{{p}}_axis_tlast_int; - output_{{p}}_axis_tdest_reg <= output_{{p}}_axis_tdest_int; - output_{{p}}_axis_tuser_reg <= output_{{p}}_axis_tuser_int; - end else if (store_{{p}}_axis_temp_to_output) begin - output_{{p}}_axis_tdata_reg <= temp_{{p}}_axis_tdata_reg; - output_{{p}}_axis_tkeep_reg <= temp_{{p}}_axis_tkeep_reg; - output_{{p}}_axis_tlast_reg <= temp_{{p}}_axis_tlast_reg; - output_{{p}}_axis_tdest_reg <= temp_{{p}}_axis_tdest_reg; - output_{{p}}_axis_tuser_reg <= temp_{{p}}_axis_tuser_reg; - end - - if (store_{{p}}_axis_int_to_temp) begin - temp_{{p}}_axis_tdata_reg <= output_{{p}}_axis_tdata_int; - temp_{{p}}_axis_tkeep_reg <= output_{{p}}_axis_tkeep_int; - temp_{{p}}_axis_tlast_reg <= output_{{p}}_axis_tlast_int; - temp_{{p}}_axis_tdest_reg <= output_{{p}}_axis_tdest_int; - temp_{{p}}_axis_tuser_reg <= output_{{p}}_axis_tuser_int; - end -end -{% endfor %} -endmodule - -""") - - output_file.write(t.render( - m=m, - n=n, - cm=cm, - cn=cn, - name=name - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_switch_64_4x4.v b/rtl/axis_switch_64_4x4.v deleted file mode 100644 index c83f79384..000000000 --- a/rtl/axis_switch_64_4x4.v +++ /dev/null @@ -1,1286 +0,0 @@ -/* - -Copyright (c) 2016-2017 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 4x4 switch (64 bit datapath) - */ -module axis_switch_64_4x4 # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter DEST_WIDTH = 2, - parameter OUT_0_BASE = 0, - parameter OUT_0_TOP = 0, - parameter OUT_0_CONNECT = 4'b1111, - parameter OUT_1_BASE = 1, - parameter OUT_1_TOP = 1, - parameter OUT_1_CONNECT = 4'b1111, - parameter OUT_2_BASE = 2, - parameter OUT_2_TOP = 2, - parameter OUT_2_CONNECT = 4'b1111, - parameter OUT_3_BASE = 3, - parameter OUT_3_TOP = 3, - parameter OUT_3_CONNECT = 4'b1111, - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "ROUND_ROBIN", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * AXI Stream inputs - */ - input wire [DATA_WIDTH-1:0] input_0_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, - input wire input_0_axis_tvalid, - output wire input_0_axis_tready, - input wire input_0_axis_tlast, - input wire [DEST_WIDTH-1:0] input_0_axis_tdest, - input wire input_0_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_1_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, - input wire input_1_axis_tvalid, - output wire input_1_axis_tready, - input wire input_1_axis_tlast, - input wire [DEST_WIDTH-1:0] input_1_axis_tdest, - input wire input_1_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_2_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, - input wire input_2_axis_tvalid, - output wire input_2_axis_tready, - input wire input_2_axis_tlast, - input wire [DEST_WIDTH-1:0] input_2_axis_tdest, - input wire input_2_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_3_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, - input wire input_3_axis_tvalid, - output wire input_3_axis_tready, - input wire input_3_axis_tlast, - input wire [DEST_WIDTH-1:0] input_3_axis_tdest, - input wire input_3_axis_tuser, - - /* - * AXI Stream outputs - */ - output wire [DATA_WIDTH-1:0] output_0_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, - output wire output_0_axis_tvalid, - input wire output_0_axis_tready, - output wire output_0_axis_tlast, - output wire [DEST_WIDTH-1:0] output_0_axis_tdest, - output wire output_0_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_1_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, - output wire output_1_axis_tvalid, - input wire output_1_axis_tready, - output wire output_1_axis_tlast, - output wire [DEST_WIDTH-1:0] output_1_axis_tdest, - output wire output_1_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_2_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, - output wire output_2_axis_tvalid, - input wire output_2_axis_tready, - output wire output_2_axis_tlast, - output wire [DEST_WIDTH-1:0] output_2_axis_tdest, - output wire output_2_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_3_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, - output wire output_3_axis_tvalid, - input wire output_3_axis_tready, - output wire output_3_axis_tlast, - output wire [DEST_WIDTH-1:0] output_3_axis_tdest, - output wire output_3_axis_tuser -); - -// check configuration -initial begin - if (2**DEST_WIDTH < 4) begin - $error("Error: DEST_WIDTH too small for port count"); - $finish; - end - - if ((OUT_0_BASE & 2**DEST_WIDTH-1) != OUT_0_BASE || (OUT_0_TOP & 2**DEST_WIDTH-1) != OUT_0_TOP || - (OUT_1_BASE & 2**DEST_WIDTH-1) != OUT_1_BASE || (OUT_1_TOP & 2**DEST_WIDTH-1) != OUT_1_TOP || - (OUT_2_BASE & 2**DEST_WIDTH-1) != OUT_2_BASE || (OUT_2_TOP & 2**DEST_WIDTH-1) != OUT_2_TOP || - (OUT_3_BASE & 2**DEST_WIDTH-1) != OUT_3_BASE || (OUT_3_TOP & 2**DEST_WIDTH-1) != OUT_3_TOP) begin - $error("Error: value out of range"); - $finish; - end - - if (OUT_0_BASE > OUT_0_TOP || - OUT_1_BASE > OUT_1_TOP || - OUT_2_BASE > OUT_2_TOP || - OUT_3_BASE > OUT_3_TOP) begin - $error("Error: invalid range"); - $finish; - end - - if ((OUT_0_BASE <= OUT_1_TOP && OUT_1_BASE <= OUT_0_TOP) || - (OUT_0_BASE <= OUT_2_TOP && OUT_2_BASE <= OUT_0_TOP) || - (OUT_0_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_0_TOP) || - (OUT_1_BASE <= OUT_2_TOP && OUT_2_BASE <= OUT_1_TOP) || - (OUT_1_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_1_TOP) || - (OUT_2_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_2_TOP)) begin - $error("Error: ranges overlap"); - $finish; - end -end - -reg [3:0] input_0_request_reg = 4'd0, input_0_request_next; -reg input_0_request_valid_reg = 1'b0, input_0_request_valid_next; -reg input_0_request_error_reg = 1'b0, input_0_request_error_next; - -reg [3:0] input_1_request_reg = 4'd0, input_1_request_next; -reg input_1_request_valid_reg = 1'b0, input_1_request_valid_next; -reg input_1_request_error_reg = 1'b0, input_1_request_error_next; - -reg [3:0] input_2_request_reg = 4'd0, input_2_request_next; -reg input_2_request_valid_reg = 1'b0, input_2_request_valid_next; -reg input_2_request_error_reg = 1'b0, input_2_request_error_next; - -reg [3:0] input_3_request_reg = 4'd0, input_3_request_next; -reg input_3_request_valid_reg = 1'b0, input_3_request_valid_next; -reg input_3_request_error_reg = 1'b0, input_3_request_error_next; - -reg [1:0] select_0_reg = 2'd0, select_0_next; -reg [1:0] select_1_reg = 2'd0, select_1_next; -reg [1:0] select_2_reg = 2'd0, select_2_next; -reg [1:0] select_3_reg = 2'd0, select_3_next; - -reg enable_0_reg = 1'b0, enable_0_next; -reg enable_1_reg = 1'b0, enable_1_next; -reg enable_2_reg = 1'b0, enable_2_next; -reg enable_3_reg = 1'b0, enable_3_next; - -reg input_0_axis_tready_reg = 1'b0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 1'b0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; - -// internal datapath -reg [DATA_WIDTH-1:0] output_0_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_int; -reg output_0_axis_tvalid_int; -reg output_0_axis_tready_int_reg = 1'b0; -reg output_0_axis_tlast_int; -reg [DEST_WIDTH-1:0] output_0_axis_tdest_int; -reg output_0_axis_tuser_int; -wire output_0_axis_tready_int_early; - -reg [DATA_WIDTH-1:0] output_1_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_int; -reg output_1_axis_tvalid_int; -reg output_1_axis_tready_int_reg = 1'b0; -reg output_1_axis_tlast_int; -reg [DEST_WIDTH-1:0] output_1_axis_tdest_int; -reg output_1_axis_tuser_int; -wire output_1_axis_tready_int_early; - -reg [DATA_WIDTH-1:0] output_2_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_int; -reg output_2_axis_tvalid_int; -reg output_2_axis_tready_int_reg = 1'b0; -reg output_2_axis_tlast_int; -reg [DEST_WIDTH-1:0] output_2_axis_tdest_int; -reg output_2_axis_tuser_int; -wire output_2_axis_tready_int_early; - -reg [DATA_WIDTH-1:0] output_3_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_int; -reg output_3_axis_tvalid_int; -reg output_3_axis_tready_int_reg = 1'b0; -reg output_3_axis_tlast_int; -reg [DEST_WIDTH-1:0] output_3_axis_tdest_int; -reg output_3_axis_tuser_int; -wire output_3_axis_tready_int_early; - -assign input_0_axis_tready = input_0_axis_tready_reg; -assign input_1_axis_tready = input_1_axis_tready_reg; -assign input_2_axis_tready = input_2_axis_tready_reg; -assign input_3_axis_tready = input_3_axis_tready_reg; - -// mux for incoming packet - -reg [DATA_WIDTH-1:0] current_input_0_axis_tdata; -reg [KEEP_WIDTH-1:0] current_input_0_axis_tkeep; -reg current_input_0_axis_tvalid; -reg current_input_0_axis_tready; -reg current_input_0_axis_tlast; -reg [DEST_WIDTH-1:0] current_input_0_axis_tdest; -reg current_input_0_axis_tuser; - -always @* begin - case (select_0_reg) - 2'd0: begin - current_input_0_axis_tdata = input_0_axis_tdata; - current_input_0_axis_tkeep = input_0_axis_tkeep; - current_input_0_axis_tvalid = input_0_axis_tvalid; - current_input_0_axis_tready = input_0_axis_tready; - current_input_0_axis_tlast = input_0_axis_tlast; - current_input_0_axis_tdest = input_0_axis_tdest; - current_input_0_axis_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_0_axis_tdata = input_1_axis_tdata; - current_input_0_axis_tkeep = input_1_axis_tkeep; - current_input_0_axis_tvalid = input_1_axis_tvalid; - current_input_0_axis_tready = input_1_axis_tready; - current_input_0_axis_tlast = input_1_axis_tlast; - current_input_0_axis_tdest = input_1_axis_tdest; - current_input_0_axis_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_0_axis_tdata = input_2_axis_tdata; - current_input_0_axis_tkeep = input_2_axis_tkeep; - current_input_0_axis_tvalid = input_2_axis_tvalid; - current_input_0_axis_tready = input_2_axis_tready; - current_input_0_axis_tlast = input_2_axis_tlast; - current_input_0_axis_tdest = input_2_axis_tdest; - current_input_0_axis_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_0_axis_tdata = input_3_axis_tdata; - current_input_0_axis_tkeep = input_3_axis_tkeep; - current_input_0_axis_tvalid = input_3_axis_tvalid; - current_input_0_axis_tready = input_3_axis_tready; - current_input_0_axis_tlast = input_3_axis_tlast; - current_input_0_axis_tdest = input_3_axis_tdest; - current_input_0_axis_tuser = input_3_axis_tuser; - end - default: begin - current_input_0_axis_tdata = {DATA_WIDTH{1'b0}}; - current_input_0_axis_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_0_axis_tvalid = 1'b0; - current_input_0_axis_tready = 1'b0; - current_input_0_axis_tlast = 1'b0; - current_input_0_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_0_axis_tuser = 1'b0; - end - endcase -end - -reg [DATA_WIDTH-1:0] current_input_1_axis_tdata; -reg [KEEP_WIDTH-1:0] current_input_1_axis_tkeep; -reg current_input_1_axis_tvalid; -reg current_input_1_axis_tready; -reg current_input_1_axis_tlast; -reg [DEST_WIDTH-1:0] current_input_1_axis_tdest; -reg current_input_1_axis_tuser; - -always @* begin - case (select_1_reg) - 2'd0: begin - current_input_1_axis_tdata = input_0_axis_tdata; - current_input_1_axis_tkeep = input_0_axis_tkeep; - current_input_1_axis_tvalid = input_0_axis_tvalid; - current_input_1_axis_tready = input_0_axis_tready; - current_input_1_axis_tlast = input_0_axis_tlast; - current_input_1_axis_tdest = input_0_axis_tdest; - current_input_1_axis_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_1_axis_tdata = input_1_axis_tdata; - current_input_1_axis_tkeep = input_1_axis_tkeep; - current_input_1_axis_tvalid = input_1_axis_tvalid; - current_input_1_axis_tready = input_1_axis_tready; - current_input_1_axis_tlast = input_1_axis_tlast; - current_input_1_axis_tdest = input_1_axis_tdest; - current_input_1_axis_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_1_axis_tdata = input_2_axis_tdata; - current_input_1_axis_tkeep = input_2_axis_tkeep; - current_input_1_axis_tvalid = input_2_axis_tvalid; - current_input_1_axis_tready = input_2_axis_tready; - current_input_1_axis_tlast = input_2_axis_tlast; - current_input_1_axis_tdest = input_2_axis_tdest; - current_input_1_axis_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_1_axis_tdata = input_3_axis_tdata; - current_input_1_axis_tkeep = input_3_axis_tkeep; - current_input_1_axis_tvalid = input_3_axis_tvalid; - current_input_1_axis_tready = input_3_axis_tready; - current_input_1_axis_tlast = input_3_axis_tlast; - current_input_1_axis_tdest = input_3_axis_tdest; - current_input_1_axis_tuser = input_3_axis_tuser; - end - default: begin - current_input_1_axis_tdata = {DATA_WIDTH{1'b0}}; - current_input_1_axis_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_1_axis_tvalid = 1'b0; - current_input_1_axis_tready = 1'b0; - current_input_1_axis_tlast = 1'b0; - current_input_1_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_1_axis_tuser = 1'b0; - end - endcase -end - -reg [DATA_WIDTH-1:0] current_input_2_axis_tdata; -reg [KEEP_WIDTH-1:0] current_input_2_axis_tkeep; -reg current_input_2_axis_tvalid; -reg current_input_2_axis_tready; -reg current_input_2_axis_tlast; -reg [DEST_WIDTH-1:0] current_input_2_axis_tdest; -reg current_input_2_axis_tuser; - -always @* begin - case (select_2_reg) - 2'd0: begin - current_input_2_axis_tdata = input_0_axis_tdata; - current_input_2_axis_tkeep = input_0_axis_tkeep; - current_input_2_axis_tvalid = input_0_axis_tvalid; - current_input_2_axis_tready = input_0_axis_tready; - current_input_2_axis_tlast = input_0_axis_tlast; - current_input_2_axis_tdest = input_0_axis_tdest; - current_input_2_axis_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_2_axis_tdata = input_1_axis_tdata; - current_input_2_axis_tkeep = input_1_axis_tkeep; - current_input_2_axis_tvalid = input_1_axis_tvalid; - current_input_2_axis_tready = input_1_axis_tready; - current_input_2_axis_tlast = input_1_axis_tlast; - current_input_2_axis_tdest = input_1_axis_tdest; - current_input_2_axis_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_2_axis_tdata = input_2_axis_tdata; - current_input_2_axis_tkeep = input_2_axis_tkeep; - current_input_2_axis_tvalid = input_2_axis_tvalid; - current_input_2_axis_tready = input_2_axis_tready; - current_input_2_axis_tlast = input_2_axis_tlast; - current_input_2_axis_tdest = input_2_axis_tdest; - current_input_2_axis_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_2_axis_tdata = input_3_axis_tdata; - current_input_2_axis_tkeep = input_3_axis_tkeep; - current_input_2_axis_tvalid = input_3_axis_tvalid; - current_input_2_axis_tready = input_3_axis_tready; - current_input_2_axis_tlast = input_3_axis_tlast; - current_input_2_axis_tdest = input_3_axis_tdest; - current_input_2_axis_tuser = input_3_axis_tuser; - end - default: begin - current_input_2_axis_tdata = {DATA_WIDTH{1'b0}}; - current_input_2_axis_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_2_axis_tvalid = 1'b0; - current_input_2_axis_tready = 1'b0; - current_input_2_axis_tlast = 1'b0; - current_input_2_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_2_axis_tuser = 1'b0; - end - endcase -end - -reg [DATA_WIDTH-1:0] current_input_3_axis_tdata; -reg [KEEP_WIDTH-1:0] current_input_3_axis_tkeep; -reg current_input_3_axis_tvalid; -reg current_input_3_axis_tready; -reg current_input_3_axis_tlast; -reg [DEST_WIDTH-1:0] current_input_3_axis_tdest; -reg current_input_3_axis_tuser; - -always @* begin - case (select_3_reg) - 2'd0: begin - current_input_3_axis_tdata = input_0_axis_tdata; - current_input_3_axis_tkeep = input_0_axis_tkeep; - current_input_3_axis_tvalid = input_0_axis_tvalid; - current_input_3_axis_tready = input_0_axis_tready; - current_input_3_axis_tlast = input_0_axis_tlast; - current_input_3_axis_tdest = input_0_axis_tdest; - current_input_3_axis_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_3_axis_tdata = input_1_axis_tdata; - current_input_3_axis_tkeep = input_1_axis_tkeep; - current_input_3_axis_tvalid = input_1_axis_tvalid; - current_input_3_axis_tready = input_1_axis_tready; - current_input_3_axis_tlast = input_1_axis_tlast; - current_input_3_axis_tdest = input_1_axis_tdest; - current_input_3_axis_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_3_axis_tdata = input_2_axis_tdata; - current_input_3_axis_tkeep = input_2_axis_tkeep; - current_input_3_axis_tvalid = input_2_axis_tvalid; - current_input_3_axis_tready = input_2_axis_tready; - current_input_3_axis_tlast = input_2_axis_tlast; - current_input_3_axis_tdest = input_2_axis_tdest; - current_input_3_axis_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_3_axis_tdata = input_3_axis_tdata; - current_input_3_axis_tkeep = input_3_axis_tkeep; - current_input_3_axis_tvalid = input_3_axis_tvalid; - current_input_3_axis_tready = input_3_axis_tready; - current_input_3_axis_tlast = input_3_axis_tlast; - current_input_3_axis_tdest = input_3_axis_tdest; - current_input_3_axis_tuser = input_3_axis_tuser; - end - default: begin - current_input_3_axis_tdata = {DATA_WIDTH{1'b0}}; - current_input_3_axis_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_3_axis_tvalid = 1'b0; - current_input_3_axis_tready = 1'b0; - current_input_3_axis_tlast = 1'b0; - current_input_3_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_3_axis_tuser = 1'b0; - end - endcase -end - -// arbiter instances - -wire [3:0] request_0; -wire [3:0] acknowledge_0; -wire [3:0] grant_0; -wire grant_valid_0; -wire [1:0] grant_encoded_0; - -wire [3:0] request_1; -wire [3:0] acknowledge_1; -wire [3:0] grant_1; -wire grant_valid_1; -wire [1:0] grant_encoded_1; - -wire [3:0] request_2; -wire [3:0] acknowledge_2; -wire [3:0] grant_2; -wire grant_valid_2; -wire [1:0] grant_encoded_2; - -wire [3:0] request_3; -wire [3:0] acknowledge_3; -wire [3:0] grant_3; -wire grant_valid_3; -wire [1:0] grant_encoded_3; - -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_0_inst ( - .clk(clk), - .rst(rst), - .request(request_0), - .acknowledge(acknowledge_0), - .grant(grant_0), - .grant_valid(grant_valid_0), - .grant_encoded(grant_encoded_0) -); - -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_1_inst ( - .clk(clk), - .rst(rst), - .request(request_1), - .acknowledge(acknowledge_1), - .grant(grant_1), - .grant_valid(grant_valid_1), - .grant_encoded(grant_encoded_1) -); - -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_2_inst ( - .clk(clk), - .rst(rst), - .request(request_2), - .acknowledge(acknowledge_2), - .grant(grant_2), - .grant_valid(grant_valid_2), - .grant_encoded(grant_encoded_2) -); - -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_3_inst ( - .clk(clk), - .rst(rst), - .request(request_3), - .acknowledge(acknowledge_3), - .grant(grant_3), - .grant_valid(grant_valid_3), - .grant_encoded(grant_encoded_3) -); - -// request generation -assign request_0[0] = input_0_request_reg[0] & ~acknowledge_0[0]; -assign request_0[1] = input_1_request_reg[0] & ~acknowledge_0[1]; -assign request_0[2] = input_2_request_reg[0] & ~acknowledge_0[2]; -assign request_0[3] = input_3_request_reg[0] & ~acknowledge_0[3]; - -assign request_1[0] = input_0_request_reg[1] & ~acknowledge_1[0]; -assign request_1[1] = input_1_request_reg[1] & ~acknowledge_1[1]; -assign request_1[2] = input_2_request_reg[1] & ~acknowledge_1[2]; -assign request_1[3] = input_3_request_reg[1] & ~acknowledge_1[3]; - -assign request_2[0] = input_0_request_reg[2] & ~acknowledge_2[0]; -assign request_2[1] = input_1_request_reg[2] & ~acknowledge_2[1]; -assign request_2[2] = input_2_request_reg[2] & ~acknowledge_2[2]; -assign request_2[3] = input_3_request_reg[2] & ~acknowledge_2[3]; - -assign request_3[0] = input_0_request_reg[3] & ~acknowledge_3[0]; -assign request_3[1] = input_1_request_reg[3] & ~acknowledge_3[1]; -assign request_3[2] = input_2_request_reg[3] & ~acknowledge_3[2]; -assign request_3[3] = input_3_request_reg[3] & ~acknowledge_3[3]; - -// acknowledge generation -assign acknowledge_0[0] = grant_0[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign acknowledge_0[1] = grant_0[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign acknowledge_0[2] = grant_0[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign acknowledge_0[3] = grant_0[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; - -assign acknowledge_1[0] = grant_1[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign acknowledge_1[1] = grant_1[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign acknowledge_1[2] = grant_1[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign acknowledge_1[3] = grant_1[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; - -assign acknowledge_2[0] = grant_2[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign acknowledge_2[1] = grant_2[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign acknowledge_2[2] = grant_2[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign acknowledge_2[3] = grant_2[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; - -assign acknowledge_3[0] = grant_3[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign acknowledge_3[1] = grant_3[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign acknowledge_3[2] = grant_3[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign acknowledge_3[3] = grant_3[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; - -always @* begin - select_0_next = select_0_reg; - select_1_next = select_1_reg; - select_2_next = select_2_reg; - select_3_next = select_3_reg; - - enable_0_next = enable_0_reg; - enable_1_next = enable_1_reg; - enable_2_next = enable_2_reg; - enable_3_next = enable_3_reg; - - input_0_request_next = input_0_request_reg; - input_0_request_valid_next = input_0_request_valid_reg; - input_0_request_error_next = input_0_request_error_reg; - - input_1_request_next = input_1_request_reg; - input_1_request_valid_next = input_1_request_valid_reg; - input_1_request_error_next = input_1_request_error_reg; - - input_2_request_next = input_2_request_reg; - input_2_request_valid_next = input_2_request_valid_reg; - input_2_request_error_next = input_2_request_error_reg; - - input_3_request_next = input_3_request_reg; - input_3_request_valid_next = input_3_request_valid_reg; - input_3_request_error_next = input_3_request_error_reg; - - input_0_axis_tready_next = 1'b0; - input_1_axis_tready_next = 1'b0; - input_2_axis_tready_next = 1'b0; - input_3_axis_tready_next = 1'b0; - - output_0_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_0_axis_tkeep_int = {DATA_WIDTH{1'b0}}; - output_0_axis_tvalid_int = 1'b0; - output_0_axis_tlast_int = 1'b0; - output_0_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_0_axis_tuser_int = 1'b0; - - output_1_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_1_axis_tkeep_int = {DATA_WIDTH{1'b0}}; - output_1_axis_tvalid_int = 1'b0; - output_1_axis_tlast_int = 1'b0; - output_1_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_1_axis_tuser_int = 1'b0; - - output_2_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_2_axis_tkeep_int = {DATA_WIDTH{1'b0}}; - output_2_axis_tvalid_int = 1'b0; - output_2_axis_tlast_int = 1'b0; - output_2_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_2_axis_tuser_int = 1'b0; - - output_3_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_3_axis_tkeep_int = {DATA_WIDTH{1'b0}}; - output_3_axis_tvalid_int = 1'b0; - output_3_axis_tlast_int = 1'b0; - output_3_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_3_axis_tuser_int = 1'b0; - - // input decoding - - if (input_0_request_valid_reg | input_0_request_error_reg) begin - if (input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast) begin - input_0_request_next = {DEST_WIDTH{1'b0}}; - input_0_request_valid_next = 1'b0; - input_0_request_error_next = 1'b0; - end - end else if (input_0_axis_tvalid) begin - input_0_request_next[0] = (input_0_axis_tdest >= OUT_0_BASE) & (input_0_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[0]; - input_0_request_next[1] = (input_0_axis_tdest >= OUT_1_BASE) & (input_0_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[0]; - input_0_request_next[2] = (input_0_axis_tdest >= OUT_2_BASE) & (input_0_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[0]; - input_0_request_next[3] = (input_0_axis_tdest >= OUT_3_BASE) & (input_0_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[0]; - - if (input_0_request_next) begin - input_0_request_valid_next = 1'b1; - end else begin - input_0_request_error_next = 1'b1; - end - end - - if (input_1_request_valid_reg | input_1_request_error_reg) begin - if (input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast) begin - input_1_request_next = {DEST_WIDTH{1'b0}}; - input_1_request_valid_next = 1'b0; - input_1_request_error_next = 1'b0; - end - end else if (input_1_axis_tvalid) begin - input_1_request_next[0] = (input_1_axis_tdest >= OUT_0_BASE) & (input_1_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[1]; - input_1_request_next[1] = (input_1_axis_tdest >= OUT_1_BASE) & (input_1_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[1]; - input_1_request_next[2] = (input_1_axis_tdest >= OUT_2_BASE) & (input_1_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[1]; - input_1_request_next[3] = (input_1_axis_tdest >= OUT_3_BASE) & (input_1_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[1]; - - if (input_1_request_next) begin - input_1_request_valid_next = 1'b1; - end else begin - input_1_request_error_next = 1'b1; - end - end - - if (input_2_request_valid_reg | input_2_request_error_reg) begin - if (input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast) begin - input_2_request_next = {DEST_WIDTH{1'b0}}; - input_2_request_valid_next = 1'b0; - input_2_request_error_next = 1'b0; - end - end else if (input_2_axis_tvalid) begin - input_2_request_next[0] = (input_2_axis_tdest >= OUT_0_BASE) & (input_2_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[2]; - input_2_request_next[1] = (input_2_axis_tdest >= OUT_1_BASE) & (input_2_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[2]; - input_2_request_next[2] = (input_2_axis_tdest >= OUT_2_BASE) & (input_2_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[2]; - input_2_request_next[3] = (input_2_axis_tdest >= OUT_3_BASE) & (input_2_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[2]; - - if (input_2_request_next) begin - input_2_request_valid_next = 1'b1; - end else begin - input_2_request_error_next = 1'b1; - end - end - - if (input_3_request_valid_reg | input_3_request_error_reg) begin - if (input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast) begin - input_3_request_next = {DEST_WIDTH{1'b0}}; - input_3_request_valid_next = 1'b0; - input_3_request_error_next = 1'b0; - end - end else if (input_3_axis_tvalid) begin - input_3_request_next[0] = (input_3_axis_tdest >= OUT_0_BASE) & (input_3_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[3]; - input_3_request_next[1] = (input_3_axis_tdest >= OUT_1_BASE) & (input_3_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[3]; - input_3_request_next[2] = (input_3_axis_tdest >= OUT_2_BASE) & (input_3_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[3]; - input_3_request_next[3] = (input_3_axis_tdest >= OUT_3_BASE) & (input_3_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[3]; - - if (input_3_request_next) begin - input_3_request_valid_next = 1'b1; - end else begin - input_3_request_error_next = 1'b1; - end - end - - // output control - - if (current_input_0_axis_tvalid & current_input_0_axis_tready) begin - if (current_input_0_axis_tlast) begin - enable_0_next = 1'b0; - end - end - if (~enable_0_reg & grant_valid_0) begin - enable_0_next = 1'b1; - select_0_next = grant_encoded_0; - end - - if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin - if (current_input_1_axis_tlast) begin - enable_1_next = 1'b0; - end - end - if (~enable_1_reg & grant_valid_1) begin - enable_1_next = 1'b1; - select_1_next = grant_encoded_1; - end - - if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin - if (current_input_2_axis_tlast) begin - enable_2_next = 1'b0; - end - end - if (~enable_2_reg & grant_valid_2) begin - enable_2_next = 1'b1; - select_2_next = grant_encoded_2; - end - - if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin - if (current_input_3_axis_tlast) begin - enable_3_next = 1'b0; - end - end - if (~enable_3_reg & grant_valid_3) begin - enable_3_next = 1'b1; - select_3_next = grant_encoded_3; - end - - // generate ready signal on selected port - - if (enable_0_next) begin - case (select_0_next) - 2'd0: input_0_axis_tready_next = output_0_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_0_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_0_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_0_axis_tready_int_early; - endcase - end - - if (enable_1_next) begin - case (select_1_next) - 2'd0: input_0_axis_tready_next = output_1_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_1_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_1_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_1_axis_tready_int_early; - endcase - end - - if (enable_2_next) begin - case (select_2_next) - 2'd0: input_0_axis_tready_next = output_2_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_2_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_2_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_2_axis_tready_int_early; - endcase - end - - if (enable_3_next) begin - case (select_3_next) - 2'd0: input_0_axis_tready_next = output_3_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_3_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_3_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_3_axis_tready_int_early; - endcase - end - - if (input_0_request_error_next) - input_0_axis_tready_next = 1'b1; - if (input_1_request_error_next) - input_1_axis_tready_next = 1'b1; - if (input_2_request_error_next) - input_2_axis_tready_next = 1'b1; - if (input_3_request_error_next) - input_3_axis_tready_next = 1'b1; - - // pass through selected packet data - - output_0_axis_tdata_int = current_input_0_axis_tdata; - output_0_axis_tkeep_int = current_input_0_axis_tkeep; - output_0_axis_tvalid_int = current_input_0_axis_tvalid & current_input_0_axis_tready & enable_0_reg; - output_0_axis_tlast_int = current_input_0_axis_tlast; - output_0_axis_tdest_int = current_input_0_axis_tdest; - output_0_axis_tuser_int = current_input_0_axis_tuser; - - output_1_axis_tdata_int = current_input_1_axis_tdata; - output_1_axis_tkeep_int = current_input_1_axis_tkeep; - output_1_axis_tvalid_int = current_input_1_axis_tvalid & current_input_1_axis_tready & enable_1_reg; - output_1_axis_tlast_int = current_input_1_axis_tlast; - output_1_axis_tdest_int = current_input_1_axis_tdest; - output_1_axis_tuser_int = current_input_1_axis_tuser; - - output_2_axis_tdata_int = current_input_2_axis_tdata; - output_2_axis_tkeep_int = current_input_2_axis_tkeep; - output_2_axis_tvalid_int = current_input_2_axis_tvalid & current_input_2_axis_tready & enable_2_reg; - output_2_axis_tlast_int = current_input_2_axis_tlast; - output_2_axis_tdest_int = current_input_2_axis_tdest; - output_2_axis_tuser_int = current_input_2_axis_tuser; - - output_3_axis_tdata_int = current_input_3_axis_tdata; - output_3_axis_tkeep_int = current_input_3_axis_tkeep; - output_3_axis_tvalid_int = current_input_3_axis_tvalid & current_input_3_axis_tready & enable_3_reg; - output_3_axis_tlast_int = current_input_3_axis_tlast; - output_3_axis_tdest_int = current_input_3_axis_tdest; - output_3_axis_tuser_int = current_input_3_axis_tuser; -end - -always @(posedge clk) begin - if (rst) begin - input_0_request_reg <= 4'd0; - input_0_request_valid_reg <= 1'b0; - input_0_request_error_reg <= 1'b0; - input_1_request_reg <= 4'd0; - input_1_request_valid_reg <= 1'b0; - input_1_request_error_reg <= 1'b0; - input_2_request_reg <= 4'd0; - input_2_request_valid_reg <= 1'b0; - input_2_request_error_reg <= 1'b0; - input_3_request_reg <= 4'd0; - input_3_request_valid_reg <= 1'b0; - input_3_request_error_reg <= 1'b0; - select_0_reg <= 2'd0; - select_1_reg <= 2'd0; - select_2_reg <= 2'd0; - select_3_reg <= 2'd0; - enable_0_reg <= 1'b0; - enable_1_reg <= 1'b0; - enable_2_reg <= 1'b0; - enable_3_reg <= 1'b0; - input_0_axis_tready_reg <= 1'b0; - input_1_axis_tready_reg <= 1'b0; - input_2_axis_tready_reg <= 1'b0; - input_3_axis_tready_reg <= 1'b0; - end else begin - input_0_request_reg <= input_0_request_next; - input_0_request_valid_reg <= input_0_request_valid_next; - input_0_request_error_reg <= input_0_request_error_next; - input_1_request_reg <= input_1_request_next; - input_1_request_valid_reg <= input_1_request_valid_next; - input_1_request_error_reg <= input_1_request_error_next; - input_2_request_reg <= input_2_request_next; - input_2_request_valid_reg <= input_2_request_valid_next; - input_2_request_error_reg <= input_2_request_error_next; - input_3_request_reg <= input_3_request_next; - input_3_request_valid_reg <= input_3_request_valid_next; - input_3_request_error_reg <= input_3_request_error_next; - select_0_reg <= select_0_next; - select_1_reg <= select_1_next; - select_2_reg <= select_2_next; - select_3_reg <= select_3_next; - enable_0_reg <= enable_0_next; - enable_1_reg <= enable_1_next; - enable_2_reg <= enable_2_next; - enable_3_reg <= enable_3_next; - input_0_axis_tready_reg <= input_0_axis_tready_next; - input_1_axis_tready_reg <= input_1_axis_tready_next; - input_2_axis_tready_reg <= input_2_axis_tready_next; - input_3_axis_tready_reg <= input_3_axis_tready_next; - end -end - -// output 0 datapath logic -reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_0_axis_tvalid_reg = 1'b0, output_0_axis_tvalid_next; -reg output_0_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] output_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg output_0_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_0_axis_tvalid_reg = 1'b0, temp_0_axis_tvalid_next; -reg temp_0_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] temp_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg temp_0_axis_tuser_reg = 1'b0; - -// datapath control -reg store_0_axis_int_to_output; -reg store_0_axis_int_to_temp; -reg store_0_axis_temp_to_output; - -assign output_0_axis_tdata = output_0_axis_tdata_reg; -assign output_0_axis_tkeep = output_0_axis_tkeep_reg; -assign output_0_axis_tvalid = output_0_axis_tvalid_reg; -assign output_0_axis_tlast = output_0_axis_tlast_reg; -assign output_0_axis_tdest = output_0_axis_tdest_reg; -assign output_0_axis_tuser = output_0_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_0_axis_tready_int_early = output_0_axis_tready | (~temp_0_axis_tvalid_reg & (~output_0_axis_tvalid_reg | ~output_0_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_0_axis_tvalid_next = output_0_axis_tvalid_reg; - temp_0_axis_tvalid_next = temp_0_axis_tvalid_reg; - - store_0_axis_int_to_output = 1'b0; - store_0_axis_int_to_temp = 1'b0; - store_0_axis_temp_to_output = 1'b0; - - if (output_0_axis_tready_int_reg) begin - // input is ready - if (output_0_axis_tready | ~output_0_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_0_axis_tvalid_next = output_0_axis_tvalid_int; - store_0_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_0_axis_tvalid_next = output_0_axis_tvalid_int; - store_0_axis_int_to_temp = 1'b1; - end - end else if (output_0_axis_tready) begin - // input is not ready, but output is ready - output_0_axis_tvalid_next = temp_0_axis_tvalid_reg; - temp_0_axis_tvalid_next = 1'b0; - store_0_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_0_axis_tvalid_reg <= 1'b0; - output_0_axis_tready_int_reg <= 1'b0; - temp_0_axis_tvalid_reg <= 1'b0; - end else begin - output_0_axis_tvalid_reg <= output_0_axis_tvalid_next; - output_0_axis_tready_int_reg <= output_0_axis_tready_int_early; - temp_0_axis_tvalid_reg <= temp_0_axis_tvalid_next; - end - - // datapath - if (store_0_axis_int_to_output) begin - output_0_axis_tdata_reg <= output_0_axis_tdata_int; - output_0_axis_tkeep_reg <= output_0_axis_tkeep_int; - output_0_axis_tlast_reg <= output_0_axis_tlast_int; - output_0_axis_tdest_reg <= output_0_axis_tdest_int; - output_0_axis_tuser_reg <= output_0_axis_tuser_int; - end else if (store_0_axis_temp_to_output) begin - output_0_axis_tdata_reg <= temp_0_axis_tdata_reg; - output_0_axis_tkeep_reg <= temp_0_axis_tkeep_reg; - output_0_axis_tlast_reg <= temp_0_axis_tlast_reg; - output_0_axis_tdest_reg <= temp_0_axis_tdest_reg; - output_0_axis_tuser_reg <= temp_0_axis_tuser_reg; - end - - if (store_0_axis_int_to_temp) begin - temp_0_axis_tdata_reg <= output_0_axis_tdata_int; - temp_0_axis_tkeep_reg <= output_0_axis_tkeep_int; - temp_0_axis_tlast_reg <= output_0_axis_tlast_int; - temp_0_axis_tdest_reg <= output_0_axis_tdest_int; - temp_0_axis_tuser_reg <= output_0_axis_tuser_int; - end -end - -// output 1 datapath logic -reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_1_axis_tvalid_reg = 1'b0, output_1_axis_tvalid_next; -reg output_1_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] output_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg output_1_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_1_axis_tvalid_reg = 1'b0, temp_1_axis_tvalid_next; -reg temp_1_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] temp_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg temp_1_axis_tuser_reg = 1'b0; - -// datapath control -reg store_1_axis_int_to_output; -reg store_1_axis_int_to_temp; -reg store_1_axis_temp_to_output; - -assign output_1_axis_tdata = output_1_axis_tdata_reg; -assign output_1_axis_tkeep = output_1_axis_tkeep_reg; -assign output_1_axis_tvalid = output_1_axis_tvalid_reg; -assign output_1_axis_tlast = output_1_axis_tlast_reg; -assign output_1_axis_tdest = output_1_axis_tdest_reg; -assign output_1_axis_tuser = output_1_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_1_axis_tready_int_early = output_1_axis_tready | (~temp_1_axis_tvalid_reg & (~output_1_axis_tvalid_reg | ~output_1_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_1_axis_tvalid_next = output_1_axis_tvalid_reg; - temp_1_axis_tvalid_next = temp_1_axis_tvalid_reg; - - store_1_axis_int_to_output = 1'b0; - store_1_axis_int_to_temp = 1'b0; - store_1_axis_temp_to_output = 1'b0; - - if (output_1_axis_tready_int_reg) begin - // input is ready - if (output_1_axis_tready | ~output_1_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_1_axis_tvalid_next = output_1_axis_tvalid_int; - store_1_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_1_axis_tvalid_next = output_1_axis_tvalid_int; - store_1_axis_int_to_temp = 1'b1; - end - end else if (output_1_axis_tready) begin - // input is not ready, but output is ready - output_1_axis_tvalid_next = temp_1_axis_tvalid_reg; - temp_1_axis_tvalid_next = 1'b0; - store_1_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_1_axis_tvalid_reg <= 1'b0; - output_1_axis_tready_int_reg <= 1'b0; - temp_1_axis_tvalid_reg <= 1'b0; - end else begin - output_1_axis_tvalid_reg <= output_1_axis_tvalid_next; - output_1_axis_tready_int_reg <= output_1_axis_tready_int_early; - temp_1_axis_tvalid_reg <= temp_1_axis_tvalid_next; - end - - // datapath - if (store_1_axis_int_to_output) begin - output_1_axis_tdata_reg <= output_1_axis_tdata_int; - output_1_axis_tkeep_reg <= output_1_axis_tkeep_int; - output_1_axis_tlast_reg <= output_1_axis_tlast_int; - output_1_axis_tdest_reg <= output_1_axis_tdest_int; - output_1_axis_tuser_reg <= output_1_axis_tuser_int; - end else if (store_1_axis_temp_to_output) begin - output_1_axis_tdata_reg <= temp_1_axis_tdata_reg; - output_1_axis_tkeep_reg <= temp_1_axis_tkeep_reg; - output_1_axis_tlast_reg <= temp_1_axis_tlast_reg; - output_1_axis_tdest_reg <= temp_1_axis_tdest_reg; - output_1_axis_tuser_reg <= temp_1_axis_tuser_reg; - end - - if (store_1_axis_int_to_temp) begin - temp_1_axis_tdata_reg <= output_1_axis_tdata_int; - temp_1_axis_tkeep_reg <= output_1_axis_tkeep_int; - temp_1_axis_tlast_reg <= output_1_axis_tlast_int; - temp_1_axis_tdest_reg <= output_1_axis_tdest_int; - temp_1_axis_tuser_reg <= output_1_axis_tuser_int; - end -end - -// output 2 datapath logic -reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_2_axis_tvalid_reg = 1'b0, output_2_axis_tvalid_next; -reg output_2_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] output_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg output_2_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_2_axis_tvalid_reg = 1'b0, temp_2_axis_tvalid_next; -reg temp_2_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] temp_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg temp_2_axis_tuser_reg = 1'b0; - -// datapath control -reg store_2_axis_int_to_output; -reg store_2_axis_int_to_temp; -reg store_2_axis_temp_to_output; - -assign output_2_axis_tdata = output_2_axis_tdata_reg; -assign output_2_axis_tkeep = output_2_axis_tkeep_reg; -assign output_2_axis_tvalid = output_2_axis_tvalid_reg; -assign output_2_axis_tlast = output_2_axis_tlast_reg; -assign output_2_axis_tdest = output_2_axis_tdest_reg; -assign output_2_axis_tuser = output_2_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_2_axis_tready_int_early = output_2_axis_tready | (~temp_2_axis_tvalid_reg & (~output_2_axis_tvalid_reg | ~output_2_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_2_axis_tvalid_next = output_2_axis_tvalid_reg; - temp_2_axis_tvalid_next = temp_2_axis_tvalid_reg; - - store_2_axis_int_to_output = 1'b0; - store_2_axis_int_to_temp = 1'b0; - store_2_axis_temp_to_output = 1'b0; - - if (output_2_axis_tready_int_reg) begin - // input is ready - if (output_2_axis_tready | ~output_2_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_2_axis_tvalid_next = output_2_axis_tvalid_int; - store_2_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_2_axis_tvalid_next = output_2_axis_tvalid_int; - store_2_axis_int_to_temp = 1'b1; - end - end else if (output_2_axis_tready) begin - // input is not ready, but output is ready - output_2_axis_tvalid_next = temp_2_axis_tvalid_reg; - temp_2_axis_tvalid_next = 1'b0; - store_2_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_2_axis_tvalid_reg <= 1'b0; - output_2_axis_tready_int_reg <= 1'b0; - temp_2_axis_tvalid_reg <= 1'b0; - end else begin - output_2_axis_tvalid_reg <= output_2_axis_tvalid_next; - output_2_axis_tready_int_reg <= output_2_axis_tready_int_early; - temp_2_axis_tvalid_reg <= temp_2_axis_tvalid_next; - end - - // datapath - if (store_2_axis_int_to_output) begin - output_2_axis_tdata_reg <= output_2_axis_tdata_int; - output_2_axis_tkeep_reg <= output_2_axis_tkeep_int; - output_2_axis_tlast_reg <= output_2_axis_tlast_int; - output_2_axis_tdest_reg <= output_2_axis_tdest_int; - output_2_axis_tuser_reg <= output_2_axis_tuser_int; - end else if (store_2_axis_temp_to_output) begin - output_2_axis_tdata_reg <= temp_2_axis_tdata_reg; - output_2_axis_tkeep_reg <= temp_2_axis_tkeep_reg; - output_2_axis_tlast_reg <= temp_2_axis_tlast_reg; - output_2_axis_tdest_reg <= temp_2_axis_tdest_reg; - output_2_axis_tuser_reg <= temp_2_axis_tuser_reg; - end - - if (store_2_axis_int_to_temp) begin - temp_2_axis_tdata_reg <= output_2_axis_tdata_int; - temp_2_axis_tkeep_reg <= output_2_axis_tkeep_int; - temp_2_axis_tlast_reg <= output_2_axis_tlast_int; - temp_2_axis_tdest_reg <= output_2_axis_tdest_int; - temp_2_axis_tuser_reg <= output_2_axis_tuser_int; - end -end - -// output 3 datapath logic -reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_3_axis_tvalid_reg = 1'b0, output_3_axis_tvalid_next; -reg output_3_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] output_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg output_3_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_3_axis_tvalid_reg = 1'b0, temp_3_axis_tvalid_next; -reg temp_3_axis_tlast_reg = 1'b0; -reg [DEST_WIDTH-1:0] temp_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg temp_3_axis_tuser_reg = 1'b0; - -// datapath control -reg store_3_axis_int_to_output; -reg store_3_axis_int_to_temp; -reg store_3_axis_temp_to_output; - -assign output_3_axis_tdata = output_3_axis_tdata_reg; -assign output_3_axis_tkeep = output_3_axis_tkeep_reg; -assign output_3_axis_tvalid = output_3_axis_tvalid_reg; -assign output_3_axis_tlast = output_3_axis_tlast_reg; -assign output_3_axis_tdest = output_3_axis_tdest_reg; -assign output_3_axis_tuser = output_3_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_3_axis_tready_int_early = output_3_axis_tready | (~temp_3_axis_tvalid_reg & (~output_3_axis_tvalid_reg | ~output_3_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_3_axis_tvalid_next = output_3_axis_tvalid_reg; - temp_3_axis_tvalid_next = temp_3_axis_tvalid_reg; - - store_3_axis_int_to_output = 1'b0; - store_3_axis_int_to_temp = 1'b0; - store_3_axis_temp_to_output = 1'b0; - - if (output_3_axis_tready_int_reg) begin - // input is ready - if (output_3_axis_tready | ~output_3_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_3_axis_tvalid_next = output_3_axis_tvalid_int; - store_3_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_3_axis_tvalid_next = output_3_axis_tvalid_int; - store_3_axis_int_to_temp = 1'b1; - end - end else if (output_3_axis_tready) begin - // input is not ready, but output is ready - output_3_axis_tvalid_next = temp_3_axis_tvalid_reg; - temp_3_axis_tvalid_next = 1'b0; - store_3_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_3_axis_tvalid_reg <= 1'b0; - output_3_axis_tready_int_reg <= 1'b0; - temp_3_axis_tvalid_reg <= 1'b0; - end else begin - output_3_axis_tvalid_reg <= output_3_axis_tvalid_next; - output_3_axis_tready_int_reg <= output_3_axis_tready_int_early; - temp_3_axis_tvalid_reg <= temp_3_axis_tvalid_next; - end - - // datapath - if (store_3_axis_int_to_output) begin - output_3_axis_tdata_reg <= output_3_axis_tdata_int; - output_3_axis_tkeep_reg <= output_3_axis_tkeep_int; - output_3_axis_tlast_reg <= output_3_axis_tlast_int; - output_3_axis_tdest_reg <= output_3_axis_tdest_int; - output_3_axis_tuser_reg <= output_3_axis_tuser_int; - end else if (store_3_axis_temp_to_output) begin - output_3_axis_tdata_reg <= temp_3_axis_tdata_reg; - output_3_axis_tkeep_reg <= temp_3_axis_tkeep_reg; - output_3_axis_tlast_reg <= temp_3_axis_tlast_reg; - output_3_axis_tdest_reg <= temp_3_axis_tdest_reg; - output_3_axis_tuser_reg <= temp_3_axis_tuser_reg; - end - - if (store_3_axis_int_to_temp) begin - temp_3_axis_tdata_reg <= output_3_axis_tdata_int; - temp_3_axis_tkeep_reg <= output_3_axis_tkeep_int; - temp_3_axis_tlast_reg <= output_3_axis_tlast_int; - temp_3_axis_tdest_reg <= output_3_axis_tdest_int; - temp_3_axis_tuser_reg <= output_3_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py index 98c8054fe..9cba3fd44 100755 --- a/tb/test_axis_switch_4x4.py +++ b/tb/test_axis_switch_4x4.py @@ -46,7 +46,13 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 DEST_WIDTH = 3 + USER_ENABLE = 1 + USER_WIDTH = 1 OUT_0_BASE = 0 OUT_0_TOP = 0 OUT_0_CONNECT = 0xf @@ -68,25 +74,33 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) + input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_0_axis_tuser = Signal(bool(0)) + input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) + input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_1_axis_tuser = Signal(bool(0)) + input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) + input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_2_axis_tuser = Signal(bool(0)) + input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_3_axis_tuser = Signal(bool(0)) + input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_0_axis_tready = Signal(bool(0)) output_1_axis_tready = Signal(bool(0)) output_2_axis_tready = Signal(bool(0)) @@ -98,25 +112,33 @@ def bench(): input_2_axis_tready = Signal(bool(0)) input_3_axis_tready = Signal(bool(0)) output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_0_axis_tvalid = Signal(bool(0)) output_0_axis_tlast = Signal(bool(0)) + output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_0_axis_tuser = Signal(bool(0)) + output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_1_axis_tvalid = Signal(bool(0)) output_1_axis_tlast = Signal(bool(0)) + output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_1_axis_tuser = Signal(bool(0)) + output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_2_axis_tvalid = Signal(bool(0)) output_2_axis_tlast = Signal(bool(0)) + output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_2_axis_tuser = Signal(bool(0)) + output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_3_axis_tvalid = Signal(bool(0)) output_3_axis_tlast = Signal(bool(0)) + output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_3_axis_tuser = Signal(bool(0)) + output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_0_pause = Signal(bool(0)) @@ -134,9 +156,11 @@ def bench(): clk, rst, tdata=input_0_axis_tdata, + tkeep=input_0_axis_tkeep, tvalid=input_0_axis_tvalid, tready=input_0_axis_tready, tlast=input_0_axis_tlast, + tid=input_0_axis_tid, tdest=input_0_axis_tdest, tuser=input_0_axis_tuser, pause=source_0_pause, @@ -149,9 +173,11 @@ def bench(): clk, rst, tdata=input_1_axis_tdata, + tkeep=input_1_axis_tkeep, tvalid=input_1_axis_tvalid, tready=input_1_axis_tready, tlast=input_1_axis_tlast, + tid=input_1_axis_tid, tdest=input_1_axis_tdest, tuser=input_1_axis_tuser, pause=source_1_pause, @@ -164,9 +190,11 @@ def bench(): clk, rst, tdata=input_2_axis_tdata, + tkeep=input_2_axis_tkeep, tvalid=input_2_axis_tvalid, tready=input_2_axis_tready, tlast=input_2_axis_tlast, + tid=input_2_axis_tid, tdest=input_2_axis_tdest, tuser=input_2_axis_tuser, pause=source_2_pause, @@ -179,9 +207,11 @@ def bench(): clk, rst, tdata=input_3_axis_tdata, + tkeep=input_3_axis_tkeep, tvalid=input_3_axis_tvalid, tready=input_3_axis_tready, tlast=input_3_axis_tlast, + tid=input_3_axis_tid, tdest=input_3_axis_tdest, tuser=input_3_axis_tuser, pause=source_3_pause, @@ -194,9 +224,11 @@ def bench(): clk, rst, tdata=output_0_axis_tdata, + tkeep=output_0_axis_tkeep, tvalid=output_0_axis_tvalid, tready=output_0_axis_tready, tlast=output_0_axis_tlast, + tid=output_0_axis_tid, tdest=output_0_axis_tdest, tuser=output_0_axis_tuser, pause=sink_0_pause, @@ -209,9 +241,11 @@ def bench(): clk, rst, tdata=output_1_axis_tdata, + tkeep=output_1_axis_tkeep, tvalid=output_1_axis_tvalid, tready=output_1_axis_tready, tlast=output_1_axis_tlast, + tid=output_1_axis_tid, tdest=output_1_axis_tdest, tuser=output_1_axis_tuser, pause=sink_1_pause, @@ -224,9 +258,11 @@ def bench(): clk, rst, tdata=output_2_axis_tdata, + tkeep=output_2_axis_tkeep, tvalid=output_2_axis_tvalid, tready=output_2_axis_tready, tlast=output_2_axis_tlast, + tid=output_2_axis_tid, tdest=output_2_axis_tdest, tuser=output_2_axis_tuser, pause=sink_2_pause, @@ -239,9 +275,11 @@ def bench(): clk, rst, tdata=output_3_axis_tdata, + tkeep=output_3_axis_tkeep, tvalid=output_3_axis_tvalid, tready=output_3_axis_tready, tlast=output_3_axis_tlast, + tid=output_3_axis_tid, tdest=output_3_axis_tdest, tuser=output_3_axis_tuser, pause=sink_3_pause, @@ -259,52 +297,68 @@ def bench(): current_test=current_test, input_0_axis_tdata=input_0_axis_tdata, + input_0_axis_tkeep=input_0_axis_tkeep, input_0_axis_tvalid=input_0_axis_tvalid, input_0_axis_tready=input_0_axis_tready, input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tid=input_0_axis_tid, input_0_axis_tdest=input_0_axis_tdest, input_0_axis_tuser=input_0_axis_tuser, input_1_axis_tdata=input_1_axis_tdata, + input_1_axis_tkeep=input_1_axis_tkeep, input_1_axis_tvalid=input_1_axis_tvalid, input_1_axis_tready=input_1_axis_tready, input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tid=input_1_axis_tid, input_1_axis_tdest=input_1_axis_tdest, input_1_axis_tuser=input_1_axis_tuser, input_2_axis_tdata=input_2_axis_tdata, + input_2_axis_tkeep=input_2_axis_tkeep, input_2_axis_tvalid=input_2_axis_tvalid, input_2_axis_tready=input_2_axis_tready, input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tid=input_2_axis_tid, input_2_axis_tdest=input_2_axis_tdest, input_2_axis_tuser=input_2_axis_tuser, input_3_axis_tdata=input_3_axis_tdata, + input_3_axis_tkeep=input_3_axis_tkeep, input_3_axis_tvalid=input_3_axis_tvalid, input_3_axis_tready=input_3_axis_tready, input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tid=input_3_axis_tid, input_3_axis_tdest=input_3_axis_tdest, input_3_axis_tuser=input_3_axis_tuser, output_0_axis_tdata=output_0_axis_tdata, + output_0_axis_tkeep=output_0_axis_tkeep, output_0_axis_tvalid=output_0_axis_tvalid, output_0_axis_tready=output_0_axis_tready, output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tid=output_0_axis_tid, output_0_axis_tdest=output_0_axis_tdest, output_0_axis_tuser=output_0_axis_tuser, output_1_axis_tdata=output_1_axis_tdata, + output_1_axis_tkeep=output_1_axis_tkeep, output_1_axis_tvalid=output_1_axis_tvalid, output_1_axis_tready=output_1_axis_tready, output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tid=output_1_axis_tid, output_1_axis_tdest=output_1_axis_tdest, output_1_axis_tuser=output_1_axis_tuser, output_2_axis_tdata=output_2_axis_tdata, + output_2_axis_tkeep=output_2_axis_tkeep, output_2_axis_tvalid=output_2_axis_tvalid, output_2_axis_tready=output_2_axis_tready, output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tid=output_2_axis_tid, output_2_axis_tdest=output_2_axis_tdest, output_2_axis_tuser=output_2_axis_tuser, output_3_axis_tdata=output_3_axis_tdata, + output_3_axis_tkeep=output_3_axis_tkeep, output_3_axis_tvalid=output_3_axis_tvalid, output_3_axis_tready=output_3_axis_tready, output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tid=output_3_axis_tid, output_3_axis_tdest=output_3_axis_tdest, output_3_axis_tuser=output_3_axis_tuser ) @@ -364,10 +418,10 @@ def bench(): print("test 1: 0123 -> 0123") current_test.next = 1 - test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) - test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) - test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) + test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=2) + test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: source_0.send(test_frame0) @@ -403,10 +457,10 @@ def bench(): print("test 2: 0123 -> 3210") current_test.next = 2 - test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) - test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) - test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) - test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=3) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=2) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=1) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=0) for wait in wait_normal, wait_pause_source, wait_pause_sink: source_0.send(test_frame0) @@ -442,10 +496,10 @@ def bench(): print("test 3: 0000 -> 0123") current_test.next = 3 - test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x00\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) - test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x00\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) - test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x00\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x00\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=2) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: source_0.send(test_frame0) @@ -481,10 +535,10 @@ def bench(): print("test 4: 0123 -> 0000") current_test.next = 4 - test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=0) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=0) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=0) for wait in wait_normal, wait_pause_source, wait_pause_sink: source_0.send(test_frame0) @@ -520,10 +574,10 @@ def bench(): print("test 1: bad decoding") current_test.next = 1 - test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) - test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x04\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=4) - test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=5) + test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x04\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=4) + test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=5) for wait in wait_normal, wait_pause_source, wait_pause_sink: source_0.send(test_frame0) diff --git a/tb/test_axis_switch_4x4.v b/tb/test_axis_switch_4x4.v index 773d4087f..76b57a128 100644 --- a/tb/test_axis_switch_4x4.v +++ b/tb/test_axis_switch_4x4.v @@ -33,7 +33,13 @@ module test_axis_switch_4x4; // Parameters parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; parameter DEST_WIDTH = 3; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; parameter OUT_0_BASE = 0; parameter OUT_0_TOP = 0; parameter OUT_0_CONNECT = 4'b1111; @@ -55,25 +61,33 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; +reg [ID_WIDTH-1:0] input_0_axis_tid = 0; reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; -reg input_0_axis_tuser = 0; +reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; +reg [ID_WIDTH-1:0] input_1_axis_tid = 0; reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; -reg input_1_axis_tuser = 0; +reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; +reg [ID_WIDTH-1:0] input_2_axis_tid = 0; reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; -reg input_2_axis_tuser = 0; +reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; +reg [ID_WIDTH-1:0] input_3_axis_tid = 0; reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; -reg input_3_axis_tuser = 0; +reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; reg output_0_axis_tready = 0; reg output_1_axis_tready = 0; reg output_2_axis_tready = 0; @@ -85,25 +99,33 @@ wire input_1_axis_tready; wire input_2_axis_tready; wire input_3_axis_tready; wire [DATA_WIDTH-1:0] output_0_axis_tdata; +wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; wire output_0_axis_tvalid; wire output_0_axis_tlast; +wire [ID_WIDTH-1:0] output_0_axis_tid; wire [DEST_WIDTH-1:0] output_0_axis_tdest; -wire output_0_axis_tuser; +wire [USER_WIDTH-1:0] output_0_axis_tuser; wire [DATA_WIDTH-1:0] output_1_axis_tdata; +wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; wire output_1_axis_tvalid; wire output_1_axis_tlast; +wire [ID_WIDTH-1:0] output_1_axis_tid; wire [DEST_WIDTH-1:0] output_1_axis_tdest; -wire output_1_axis_tuser; +wire [USER_WIDTH-1:0] output_1_axis_tuser; wire [DATA_WIDTH-1:0] output_2_axis_tdata; +wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; wire output_2_axis_tvalid; wire output_2_axis_tlast; +wire [ID_WIDTH-1:0] output_2_axis_tid; wire [DEST_WIDTH-1:0] output_2_axis_tdest; -wire output_2_axis_tuser; +wire [USER_WIDTH-1:0] output_2_axis_tuser; wire [DATA_WIDTH-1:0] output_3_axis_tdata; +wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; wire output_3_axis_tvalid; wire output_3_axis_tlast; +wire [ID_WIDTH-1:0] output_3_axis_tid; wire [DEST_WIDTH-1:0] output_3_axis_tdest; -wire output_3_axis_tuser; +wire [USER_WIDTH-1:0] output_3_axis_tuser; initial begin // myhdl integration @@ -112,23 +134,31 @@ initial begin rst, current_test, input_0_axis_tdata, + input_0_axis_tkeep, input_0_axis_tvalid, input_0_axis_tlast, + input_0_axis_tid, input_0_axis_tdest, input_0_axis_tuser, input_1_axis_tdata, + input_1_axis_tkeep, input_1_axis_tvalid, input_1_axis_tlast, + input_1_axis_tid, input_1_axis_tdest, input_1_axis_tuser, input_2_axis_tdata, + input_2_axis_tkeep, input_2_axis_tvalid, input_2_axis_tlast, + input_2_axis_tid, input_2_axis_tdest, input_2_axis_tuser, input_3_axis_tdata, + input_3_axis_tkeep, input_3_axis_tvalid, input_3_axis_tlast, + input_3_axis_tid, input_3_axis_tdest, input_3_axis_tuser, output_0_axis_tready, @@ -142,23 +172,31 @@ initial begin input_2_axis_tready, input_3_axis_tready, output_0_axis_tdata, + output_0_axis_tkeep, output_0_axis_tvalid, output_0_axis_tlast, + output_0_axis_tid, output_0_axis_tdest, output_0_axis_tuser, output_1_axis_tdata, + output_1_axis_tkeep, output_1_axis_tvalid, output_1_axis_tlast, + output_1_axis_tid, output_1_axis_tdest, output_1_axis_tuser, output_2_axis_tdata, + output_2_axis_tkeep, output_2_axis_tvalid, output_2_axis_tlast, + output_2_axis_tid, output_2_axis_tdest, output_2_axis_tuser, output_3_axis_tdata, + output_3_axis_tkeep, output_3_axis_tvalid, output_3_axis_tlast, + output_3_axis_tid, output_3_axis_tdest, output_3_axis_tuser ); @@ -170,7 +208,13 @@ end axis_switch_4x4 #( .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), .OUT_0_BASE(OUT_0_BASE), .OUT_0_TOP(OUT_0_TOP), .OUT_0_CONNECT(OUT_0_CONNECT), @@ -191,52 +235,68 @@ UUT ( .rst(rst), // AXI inputs .input_0_axis_tdata(input_0_axis_tdata), + .input_0_axis_tkeep(input_0_axis_tkeep), .input_0_axis_tvalid(input_0_axis_tvalid), .input_0_axis_tready(input_0_axis_tready), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tid(input_0_axis_tid), .input_0_axis_tdest(input_0_axis_tdest), .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), + .input_1_axis_tkeep(input_1_axis_tkeep), .input_1_axis_tvalid(input_1_axis_tvalid), .input_1_axis_tready(input_1_axis_tready), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tid(input_1_axis_tid), .input_1_axis_tdest(input_1_axis_tdest), .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), + .input_2_axis_tkeep(input_2_axis_tkeep), .input_2_axis_tvalid(input_2_axis_tvalid), .input_2_axis_tready(input_2_axis_tready), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tid(input_2_axis_tid), .input_2_axis_tdest(input_2_axis_tdest), .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), + .input_3_axis_tkeep(input_3_axis_tkeep), .input_3_axis_tvalid(input_3_axis_tvalid), .input_3_axis_tready(input_3_axis_tready), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tid(input_3_axis_tid), .input_3_axis_tdest(input_3_axis_tdest), .input_3_axis_tuser(input_3_axis_tuser), // AXI outputs .output_0_axis_tdata(output_0_axis_tdata), + .output_0_axis_tkeep(output_0_axis_tkeep), .output_0_axis_tvalid(output_0_axis_tvalid), .output_0_axis_tready(output_0_axis_tready), .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tid(output_0_axis_tid), .output_0_axis_tdest(output_0_axis_tdest), .output_0_axis_tuser(output_0_axis_tuser), .output_1_axis_tdata(output_1_axis_tdata), + .output_1_axis_tkeep(output_1_axis_tkeep), .output_1_axis_tvalid(output_1_axis_tvalid), .output_1_axis_tready(output_1_axis_tready), .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tid(output_1_axis_tid), .output_1_axis_tdest(output_1_axis_tdest), .output_1_axis_tuser(output_1_axis_tuser), .output_2_axis_tdata(output_2_axis_tdata), + .output_2_axis_tkeep(output_2_axis_tkeep), .output_2_axis_tvalid(output_2_axis_tvalid), .output_2_axis_tready(output_2_axis_tready), .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tid(output_2_axis_tid), .output_2_axis_tdest(output_2_axis_tdest), .output_2_axis_tuser(output_2_axis_tuser), .output_3_axis_tdata(output_3_axis_tdata), + .output_3_axis_tkeep(output_3_axis_tkeep), .output_3_axis_tvalid(output_3_axis_tvalid), .output_3_axis_tready(output_3_axis_tready), .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tid(output_3_axis_tid), .output_3_axis_tdest(output_3_axis_tdest), .output_3_axis_tuser(output_3_axis_tuser) ); diff --git a/tb/test_axis_switch_64_4x4.py b/tb/test_axis_switch_4x4_64.py similarity index 85% rename from tb/test_axis_switch_64_4x4.py rename to tb/test_axis_switch_4x4_64.py index c6e230049..69de32437 100755 --- a/tb/test_axis_switch_64_4x4.py +++ b/tb/test_axis_switch_4x4_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_switch_64_4x4' -testbench = 'test_%s' % module +module = 'axis_switch_4x4' +testbench = 'test_%s_64' % module srcs = [] @@ -46,8 +46,13 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 DEST_WIDTH = 3 + USER_ENABLE = 1 + USER_WIDTH = 1 OUT_0_BASE = 0 OUT_0_TOP = 0 OUT_0_CONNECT = 0xf @@ -69,29 +74,33 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_0_axis_tvalid = Signal(bool(0)) input_0_axis_tlast = Signal(bool(0)) + input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_0_axis_tuser = Signal(bool(0)) + input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_1_axis_tvalid = Signal(bool(0)) input_1_axis_tlast = Signal(bool(0)) + input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_1_axis_tuser = Signal(bool(0)) + input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_2_axis_tvalid = Signal(bool(0)) input_2_axis_tlast = Signal(bool(0)) + input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_2_axis_tuser = Signal(bool(0)) + input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_3_axis_tvalid = Signal(bool(0)) input_3_axis_tlast = Signal(bool(0)) + input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_3_axis_tuser = Signal(bool(0)) + input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_0_axis_tready = Signal(bool(0)) output_1_axis_tready = Signal(bool(0)) output_2_axis_tready = Signal(bool(0)) @@ -103,29 +112,33 @@ def bench(): input_2_axis_tready = Signal(bool(0)) input_3_axis_tready = Signal(bool(0)) output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_0_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_0_axis_tvalid = Signal(bool(0)) output_0_axis_tlast = Signal(bool(0)) + output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_0_axis_tuser = Signal(bool(0)) + output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_1_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_1_axis_tvalid = Signal(bool(0)) output_1_axis_tlast = Signal(bool(0)) + output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_1_axis_tuser = Signal(bool(0)) + output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_2_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_2_axis_tvalid = Signal(bool(0)) output_2_axis_tlast = Signal(bool(0)) + output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_2_axis_tuser = Signal(bool(0)) + output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_3_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_3_axis_tvalid = Signal(bool(0)) output_3_axis_tlast = Signal(bool(0)) + output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_3_axis_tuser = Signal(bool(0)) + output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_0_pause = Signal(bool(0)) @@ -147,6 +160,7 @@ def bench(): tvalid=input_0_axis_tvalid, tready=input_0_axis_tready, tlast=input_0_axis_tlast, + tid=input_0_axis_tid, tdest=input_0_axis_tdest, tuser=input_0_axis_tuser, pause=source_0_pause, @@ -163,6 +177,7 @@ def bench(): tvalid=input_1_axis_tvalid, tready=input_1_axis_tready, tlast=input_1_axis_tlast, + tid=input_1_axis_tid, tdest=input_1_axis_tdest, tuser=input_1_axis_tuser, pause=source_1_pause, @@ -179,6 +194,7 @@ def bench(): tvalid=input_2_axis_tvalid, tready=input_2_axis_tready, tlast=input_2_axis_tlast, + tid=input_2_axis_tid, tdest=input_2_axis_tdest, tuser=input_2_axis_tuser, pause=source_2_pause, @@ -195,6 +211,7 @@ def bench(): tvalid=input_3_axis_tvalid, tready=input_3_axis_tready, tlast=input_3_axis_tlast, + tid=input_3_axis_tid, tdest=input_3_axis_tdest, tuser=input_3_axis_tuser, pause=source_3_pause, @@ -211,6 +228,7 @@ def bench(): tvalid=output_0_axis_tvalid, tready=output_0_axis_tready, tlast=output_0_axis_tlast, + tid=output_0_axis_tid, tdest=output_0_axis_tdest, tuser=output_0_axis_tuser, pause=sink_0_pause, @@ -227,6 +245,7 @@ def bench(): tvalid=output_1_axis_tvalid, tready=output_1_axis_tready, tlast=output_1_axis_tlast, + tid=output_1_axis_tid, tdest=output_1_axis_tdest, tuser=output_1_axis_tuser, pause=sink_1_pause, @@ -243,6 +262,7 @@ def bench(): tvalid=output_2_axis_tvalid, tready=output_2_axis_tready, tlast=output_2_axis_tlast, + tid=output_2_axis_tid, tdest=output_2_axis_tdest, tuser=output_2_axis_tuser, pause=sink_2_pause, @@ -259,6 +279,7 @@ def bench(): tvalid=output_3_axis_tvalid, tready=output_3_axis_tready, tlast=output_3_axis_tlast, + tid=output_3_axis_tid, tdest=output_3_axis_tdest, tuser=output_3_axis_tuser, pause=sink_3_pause, @@ -280,6 +301,7 @@ def bench(): input_0_axis_tvalid=input_0_axis_tvalid, input_0_axis_tready=input_0_axis_tready, input_0_axis_tlast=input_0_axis_tlast, + input_0_axis_tid=input_0_axis_tid, input_0_axis_tdest=input_0_axis_tdest, input_0_axis_tuser=input_0_axis_tuser, input_1_axis_tdata=input_1_axis_tdata, @@ -287,6 +309,7 @@ def bench(): input_1_axis_tvalid=input_1_axis_tvalid, input_1_axis_tready=input_1_axis_tready, input_1_axis_tlast=input_1_axis_tlast, + input_1_axis_tid=input_1_axis_tid, input_1_axis_tdest=input_1_axis_tdest, input_1_axis_tuser=input_1_axis_tuser, input_2_axis_tdata=input_2_axis_tdata, @@ -294,6 +317,7 @@ def bench(): input_2_axis_tvalid=input_2_axis_tvalid, input_2_axis_tready=input_2_axis_tready, input_2_axis_tlast=input_2_axis_tlast, + input_2_axis_tid=input_2_axis_tid, input_2_axis_tdest=input_2_axis_tdest, input_2_axis_tuser=input_2_axis_tuser, input_3_axis_tdata=input_3_axis_tdata, @@ -301,6 +325,7 @@ def bench(): input_3_axis_tvalid=input_3_axis_tvalid, input_3_axis_tready=input_3_axis_tready, input_3_axis_tlast=input_3_axis_tlast, + input_3_axis_tid=input_3_axis_tid, input_3_axis_tdest=input_3_axis_tdest, input_3_axis_tuser=input_3_axis_tuser, @@ -309,6 +334,7 @@ def bench(): output_0_axis_tvalid=output_0_axis_tvalid, output_0_axis_tready=output_0_axis_tready, output_0_axis_tlast=output_0_axis_tlast, + output_0_axis_tid=output_0_axis_tid, output_0_axis_tdest=output_0_axis_tdest, output_0_axis_tuser=output_0_axis_tuser, output_1_axis_tdata=output_1_axis_tdata, @@ -316,6 +342,7 @@ def bench(): output_1_axis_tvalid=output_1_axis_tvalid, output_1_axis_tready=output_1_axis_tready, output_1_axis_tlast=output_1_axis_tlast, + output_1_axis_tid=output_1_axis_tid, output_1_axis_tdest=output_1_axis_tdest, output_1_axis_tuser=output_1_axis_tuser, output_2_axis_tdata=output_2_axis_tdata, @@ -323,6 +350,7 @@ def bench(): output_2_axis_tvalid=output_2_axis_tvalid, output_2_axis_tready=output_2_axis_tready, output_2_axis_tlast=output_2_axis_tlast, + output_2_axis_tid=output_2_axis_tid, output_2_axis_tdest=output_2_axis_tdest, output_2_axis_tuser=output_2_axis_tuser, output_3_axis_tdata=output_3_axis_tdata, @@ -330,6 +358,7 @@ def bench(): output_3_axis_tvalid=output_3_axis_tvalid, output_3_axis_tready=output_3_axis_tready, output_3_axis_tlast=output_3_axis_tlast, + output_3_axis_tid=output_3_axis_tid, output_3_axis_tdest=output_3_axis_tdest, output_3_axis_tuser=output_3_axis_tuser ) @@ -389,10 +418,10 @@ def bench(): print("test 1: 0123 -> 0123") current_test.next = 1 - test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) - test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) - test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) + test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=2) + test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: source_0.send(test_frame0) @@ -428,10 +457,10 @@ def bench(): print("test 2: 0123 -> 3210") current_test.next = 2 - test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) - test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) - test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) - test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=3) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=2) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=1) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=0) for wait in wait_normal, wait_pause_source, wait_pause_sink: source_0.send(test_frame0) @@ -467,10 +496,10 @@ def bench(): print("test 3: 0000 -> 0123") current_test.next = 3 - test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x00\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) - test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x00\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=2) - test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=3) + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x00\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x00\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=2) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: source_0.send(test_frame0) @@ -506,10 +535,10 @@ def bench(): print("test 4: 0123 -> 0000") current_test.next = 4 - test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) + test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=0) + test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=0) + test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=0) for wait in wait_normal, wait_pause_source, wait_pause_sink: source_0.send(test_frame0) @@ -545,10 +574,10 @@ def bench(): print("test 1: bad decoding") current_test.next = 1 - test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=0) - test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=1) - test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x04\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=4) - test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', dest=5) + test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0) + test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x04\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=4) + test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=5) for wait in wait_normal, wait_pause_source, wait_pause_sink: source_0.send(test_frame0) diff --git a/tb/test_axis_switch_64_4x4.v b/tb/test_axis_switch_4x4_64.v similarity index 83% rename from tb/test_axis_switch_64_4x4.v rename to tb/test_axis_switch_4x4_64.v index b3a10a486..90fc198bd 100644 --- a/tb/test_axis_switch_64_4x4.v +++ b/tb/test_axis_switch_4x4_64.v @@ -27,14 +27,19 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_switch_64_4x4 + * Testbench for axis_switch_4x4 */ -module test_axis_switch_64_4x4; +module test_axis_switch_4x4_64; // Parameters parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; parameter DEST_WIDTH = 3; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; parameter OUT_0_BASE = 0; parameter OUT_0_TOP = 0; parameter OUT_0_CONNECT = 4'b1111; @@ -59,26 +64,30 @@ reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; reg input_0_axis_tvalid = 0; reg input_0_axis_tlast = 0; +reg [ID_WIDTH-1:0] input_0_axis_tid = 0; reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; -reg input_0_axis_tuser = 0; +reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; reg input_1_axis_tvalid = 0; reg input_1_axis_tlast = 0; +reg [ID_WIDTH-1:0] input_1_axis_tid = 0; reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; -reg input_1_axis_tuser = 0; +reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; reg input_2_axis_tvalid = 0; reg input_2_axis_tlast = 0; +reg [ID_WIDTH-1:0] input_2_axis_tid = 0; reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; -reg input_2_axis_tuser = 0; +reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; reg input_3_axis_tvalid = 0; reg input_3_axis_tlast = 0; +reg [ID_WIDTH-1:0] input_3_axis_tid = 0; reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; -reg input_3_axis_tuser = 0; +reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; reg output_0_axis_tready = 0; reg output_1_axis_tready = 0; reg output_2_axis_tready = 0; @@ -93,26 +102,30 @@ wire [DATA_WIDTH-1:0] output_0_axis_tdata; wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; wire output_0_axis_tvalid; wire output_0_axis_tlast; +wire [ID_WIDTH-1:0] output_0_axis_tid; wire [DEST_WIDTH-1:0] output_0_axis_tdest; -wire output_0_axis_tuser; +wire [USER_WIDTH-1:0] output_0_axis_tuser; wire [DATA_WIDTH-1:0] output_1_axis_tdata; wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; wire output_1_axis_tvalid; wire output_1_axis_tlast; +wire [ID_WIDTH-1:0] output_1_axis_tid; wire [DEST_WIDTH-1:0] output_1_axis_tdest; -wire output_1_axis_tuser; +wire [USER_WIDTH-1:0] output_1_axis_tuser; wire [DATA_WIDTH-1:0] output_2_axis_tdata; wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; wire output_2_axis_tvalid; wire output_2_axis_tlast; +wire [ID_WIDTH-1:0] output_2_axis_tid; wire [DEST_WIDTH-1:0] output_2_axis_tdest; -wire output_2_axis_tuser; +wire [USER_WIDTH-1:0] output_2_axis_tuser; wire [DATA_WIDTH-1:0] output_3_axis_tdata; wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; wire output_3_axis_tvalid; wire output_3_axis_tlast; +wire [ID_WIDTH-1:0] output_3_axis_tid; wire [DEST_WIDTH-1:0] output_3_axis_tdest; -wire output_3_axis_tuser; +wire [USER_WIDTH-1:0] output_3_axis_tuser; initial begin // myhdl integration @@ -124,24 +137,28 @@ initial begin input_0_axis_tkeep, input_0_axis_tvalid, input_0_axis_tlast, + input_0_axis_tid, input_0_axis_tdest, input_0_axis_tuser, input_1_axis_tdata, input_1_axis_tkeep, input_1_axis_tvalid, input_1_axis_tlast, + input_1_axis_tid, input_1_axis_tdest, input_1_axis_tuser, input_2_axis_tdata, input_2_axis_tkeep, input_2_axis_tvalid, input_2_axis_tlast, + input_2_axis_tid, input_2_axis_tdest, input_2_axis_tuser, input_3_axis_tdata, input_3_axis_tkeep, input_3_axis_tvalid, input_3_axis_tlast, + input_3_axis_tid, input_3_axis_tdest, input_3_axis_tuser, output_0_axis_tready, @@ -158,37 +175,46 @@ initial begin output_0_axis_tkeep, output_0_axis_tvalid, output_0_axis_tlast, + output_0_axis_tid, output_0_axis_tdest, output_0_axis_tuser, output_1_axis_tdata, output_1_axis_tkeep, output_1_axis_tvalid, output_1_axis_tlast, + output_1_axis_tid, output_1_axis_tdest, output_1_axis_tuser, output_2_axis_tdata, output_2_axis_tkeep, output_2_axis_tvalid, output_2_axis_tlast, + output_2_axis_tid, output_2_axis_tdest, output_2_axis_tuser, output_3_axis_tdata, output_3_axis_tkeep, output_3_axis_tvalid, output_3_axis_tlast, + output_3_axis_tid, output_3_axis_tdest, output_3_axis_tuser ); // dump file - $dumpfile("test_axis_switch_64_4x4.lxt"); - $dumpvars(0, test_axis_switch_64_4x4); + $dumpfile("test_axis_switch_4x4_64.lxt"); + $dumpvars(0, test_axis_switch_4x4_64); end -axis_switch_64_4x4 #( +axis_switch_4x4 #( .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), .OUT_0_BASE(OUT_0_BASE), .OUT_0_TOP(OUT_0_TOP), .OUT_0_CONNECT(OUT_0_CONNECT), @@ -213,6 +239,7 @@ UUT ( .input_0_axis_tvalid(input_0_axis_tvalid), .input_0_axis_tready(input_0_axis_tready), .input_0_axis_tlast(input_0_axis_tlast), + .input_0_axis_tid(input_0_axis_tid), .input_0_axis_tdest(input_0_axis_tdest), .input_0_axis_tuser(input_0_axis_tuser), .input_1_axis_tdata(input_1_axis_tdata), @@ -220,6 +247,7 @@ UUT ( .input_1_axis_tvalid(input_1_axis_tvalid), .input_1_axis_tready(input_1_axis_tready), .input_1_axis_tlast(input_1_axis_tlast), + .input_1_axis_tid(input_1_axis_tid), .input_1_axis_tdest(input_1_axis_tdest), .input_1_axis_tuser(input_1_axis_tuser), .input_2_axis_tdata(input_2_axis_tdata), @@ -227,6 +255,7 @@ UUT ( .input_2_axis_tvalid(input_2_axis_tvalid), .input_2_axis_tready(input_2_axis_tready), .input_2_axis_tlast(input_2_axis_tlast), + .input_2_axis_tid(input_2_axis_tid), .input_2_axis_tdest(input_2_axis_tdest), .input_2_axis_tuser(input_2_axis_tuser), .input_3_axis_tdata(input_3_axis_tdata), @@ -234,6 +263,7 @@ UUT ( .input_3_axis_tvalid(input_3_axis_tvalid), .input_3_axis_tready(input_3_axis_tready), .input_3_axis_tlast(input_3_axis_tlast), + .input_3_axis_tid(input_3_axis_tid), .input_3_axis_tdest(input_3_axis_tdest), .input_3_axis_tuser(input_3_axis_tuser), // AXI outputs @@ -242,6 +272,7 @@ UUT ( .output_0_axis_tvalid(output_0_axis_tvalid), .output_0_axis_tready(output_0_axis_tready), .output_0_axis_tlast(output_0_axis_tlast), + .output_0_axis_tid(output_0_axis_tid), .output_0_axis_tdest(output_0_axis_tdest), .output_0_axis_tuser(output_0_axis_tuser), .output_1_axis_tdata(output_1_axis_tdata), @@ -249,6 +280,7 @@ UUT ( .output_1_axis_tvalid(output_1_axis_tvalid), .output_1_axis_tready(output_1_axis_tready), .output_1_axis_tlast(output_1_axis_tlast), + .output_1_axis_tid(output_1_axis_tid), .output_1_axis_tdest(output_1_axis_tdest), .output_1_axis_tuser(output_1_axis_tuser), .output_2_axis_tdata(output_2_axis_tdata), @@ -256,6 +288,7 @@ UUT ( .output_2_axis_tvalid(output_2_axis_tvalid), .output_2_axis_tready(output_2_axis_tready), .output_2_axis_tlast(output_2_axis_tlast), + .output_2_axis_tid(output_2_axis_tid), .output_2_axis_tdest(output_2_axis_tdest), .output_2_axis_tuser(output_2_axis_tuser), .output_3_axis_tdata(output_3_axis_tdata), @@ -263,6 +296,7 @@ UUT ( .output_3_axis_tvalid(output_3_axis_tvalid), .output_3_axis_tready(output_3_axis_tready), .output_3_axis_tlast(output_3_axis_tlast), + .output_3_axis_tid(output_3_axis_tid), .output_3_axis_tdest(output_3_axis_tdest), .output_3_axis_tuser(output_3_axis_tuser) ); From 772e433ee9f51ea4b3bea13b5ad7b373c35a18a6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 21:30:26 -0800 Subject: [PATCH 360/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream frame length adjuster --- rtl/axis_frame_length_adjust.v | 112 ++++++++----- rtl/axis_frame_length_adjust_fifo.v | 71 ++++++-- rtl/axis_frame_length_adjust_fifo_64.v | 169 -------------------- tb/test_axis_frame_length_adjust_64.py | 41 +++-- tb/test_axis_frame_length_adjust_64.v | 36 ++++- tb/test_axis_frame_length_adjust_8.py | 41 +++-- tb/test_axis_frame_length_adjust_8.v | 36 ++++- tb/test_axis_frame_length_adjust_fifo.py | 44 +++-- tb/test_axis_frame_length_adjust_fifo.v | 44 ++++- tb/test_axis_frame_length_adjust_fifo_64.py | 46 ++++-- tb/test_axis_frame_length_adjust_fifo_64.v | 42 ++++- 11 files changed, 396 insertions(+), 286 deletions(-) delete mode 100644 rtl/axis_frame_length_adjust_fifo_64.v diff --git a/rtl/axis_frame_length_adjust.v b/rtl/axis_frame_length_adjust.v index f4735a5dc..b15d492aa 100644 --- a/rtl/axis_frame_length_adjust.v +++ b/rtl/axis_frame_length_adjust.v @@ -31,8 +31,15 @@ THE SOFTWARE. */ module axis_frame_length_adjust # ( - parameter DATA_WIDTH = 1, - parameter KEEP_WIDTH = (DATA_WIDTH/8) + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( input wire clk, @@ -46,7 +53,9 @@ module axis_frame_length_adjust # input wire input_axis_tvalid, output wire input_axis_tready, input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, /* * AXI output @@ -56,7 +65,9 @@ module axis_frame_length_adjust # output wire output_axis_tvalid, input wire output_axis_tready, output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser, /* * Status @@ -106,8 +117,9 @@ reg [15:0] long_counter_reg = 16'd0, long_counter_next = 16'd0; reg [DATA_WIDTH-1:0] last_word_data_reg = {DATA_WIDTH{1'b0}}; reg [KEEP_WIDTH-1:0] last_word_keep_reg = {KEEP_WIDTH{1'b0}}; - -reg last_cycle_tuser_reg = 1'b0, last_cycle_tuser_next; +reg [ID_WIDTH-1:0] last_word_id_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] last_word_dest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] last_word_user_reg = {USER_WIDTH{1'b0}}; reg status_valid_reg = 1'b0, status_valid_next; reg status_frame_pad_reg = 1'b0, status_frame_pad_next; @@ -116,13 +128,15 @@ reg [15:0] status_frame_length_reg = 16'd0, status_frame_length_next; reg [15:0] status_frame_original_length_reg = 16'd0, status_frame_original_length_next; // internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg [ID_WIDTH-1:0] output_axis_tid_int; +reg [DEST_WIDTH-1:0] output_axis_tdest_int; +reg [USER_WIDTH-1:0] output_axis_tuser_int; +wire output_axis_tready_int_early; reg input_axis_tready_reg = 1'b0, input_axis_tready_next; assign input_axis_tready = input_axis_tready_reg; @@ -145,16 +159,16 @@ always @* begin short_counter_next = short_counter_reg; long_counter_next = long_counter_reg; - output_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; + output_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tid_int = {ID_WIDTH{1'b0}}; + output_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_axis_tuser_int = {USER_WIDTH{1'b0}}; input_axis_tready_next = 1'b0; - last_cycle_tuser_next = last_cycle_tuser_reg; - status_valid_next = status_valid_reg & ~status_ready; status_frame_pad_next = status_frame_pad_reg; status_frame_truncate_next = status_frame_truncate_reg; @@ -171,6 +185,8 @@ always @* begin output_axis_tkeep_int = input_axis_tkeep; output_axis_tvalid_int = input_axis_tvalid; output_axis_tlast_int = input_axis_tlast; + output_axis_tid_int = input_axis_tid; + output_axis_tdest_int = input_axis_tdest; output_axis_tuser_int = input_axis_tuser; short_counter_next = length_min; @@ -224,8 +240,7 @@ always @* begin input_axis_tready_next = 1'b0; output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; - last_cycle_tuser_next = input_axis_tuser; + store_last_word = 1'b1; state_next = STATE_PAD; end else begin status_valid_next = 1'b1; @@ -268,6 +283,8 @@ always @* begin output_axis_tkeep_int = input_axis_tkeep; output_axis_tvalid_int = input_axis_tvalid; output_axis_tlast_int = input_axis_tlast; + output_axis_tid_int = input_axis_tid; + output_axis_tdest_int = input_axis_tdest; output_axis_tuser_int = input_axis_tuser; if (input_axis_tready & input_axis_tvalid) begin @@ -318,8 +335,7 @@ always @* begin input_axis_tready_next = 1'b0; output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; - last_cycle_tuser_next = input_axis_tuser; + store_last_word = 1'b1; state_next = STATE_PAD; end else begin status_valid_next = 1'b1; @@ -361,7 +377,9 @@ always @* begin output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; output_axis_tvalid_int = 1'b1; output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + output_axis_tid_int = last_word_id_reg; + output_axis_tdest_int = last_word_dest_reg; + output_axis_tuser_int = last_word_user_reg; if (output_axis_tready_int_reg) begin frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; @@ -386,7 +404,6 @@ always @* begin input_axis_tready_next = output_axis_tready_int_early & status_ready; output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-short_counter_reg); output_axis_tlast_int = 1'b1; - output_axis_tuser_int = last_cycle_tuser_reg; frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; @@ -406,6 +423,8 @@ always @* begin output_axis_tkeep_int = last_word_keep_reg; output_axis_tvalid_int = input_axis_tvalid & input_axis_tlast; output_axis_tlast_int = input_axis_tlast; + output_axis_tid_int = last_word_id_reg; + output_axis_tdest_int = last_word_dest_reg; output_axis_tuser_int = input_axis_tuser; if (input_axis_tready & input_axis_tvalid) begin @@ -458,8 +477,6 @@ always @(posedge clk) begin status_valid_reg <= status_valid_next; end - last_cycle_tuser_reg <= last_cycle_tuser_next; - status_frame_pad_reg <= status_frame_pad_next; status_frame_truncate_reg <= status_frame_truncate_next; status_frame_length_reg <= status_frame_length_next; @@ -468,32 +485,41 @@ always @(posedge clk) begin if (store_last_word) begin last_word_data_reg <= output_axis_tdata_int; last_word_keep_reg <= output_axis_tkeep_int; + last_word_id_reg <= output_axis_tid_int; + last_word_dest_reg <= output_axis_tdest_int; + last_word_user_reg <= output_axis_tuser_int; end end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); @@ -506,7 +532,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin @@ -542,11 +568,15 @@ always @(posedge clk) begin output_axis_tdata_reg <= output_axis_tdata_int; output_axis_tkeep_reg <= output_axis_tkeep_int; output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tid_reg <= output_axis_tid_int; + output_axis_tdest_reg <= output_axis_tdest_int; output_axis_tuser_reg <= output_axis_tuser_int; end else if (store_axis_temp_to_output) begin output_axis_tdata_reg <= temp_axis_tdata_reg; output_axis_tkeep_reg <= temp_axis_tkeep_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end @@ -554,6 +584,8 @@ always @(posedge clk) begin temp_axis_tdata_reg <= output_axis_tdata_int; temp_axis_tkeep_reg <= output_axis_tkeep_int; temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tid_reg <= output_axis_tid_int; + temp_axis_tdest_reg <= output_axis_tdest_int; temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_frame_length_adjust_fifo.v b/rtl/axis_frame_length_adjust_fifo.v index 3dc7cdec4..750c7ceed 100644 --- a/rtl/axis_frame_length_adjust_fifo.v +++ b/rtl/axis_frame_length_adjust_fifo.v @@ -32,6 +32,14 @@ THE SOFTWARE. module axis_frame_length_adjust_fifo # ( parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, parameter FRAME_FIFO_ADDR_WIDTH = 12, parameter HEADER_FIFO_ADDR_WIDTH = 3 ) @@ -43,10 +51,13 @@ module axis_frame_length_adjust_fifo # * 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, + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, /* * AXI output @@ -58,10 +69,13 @@ module axis_frame_length_adjust_fifo # output wire [15:0] output_axis_hdr_length, output wire [15:0] output_axis_hdr_original_length, 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, + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser, /* * Configuration @@ -71,10 +85,13 @@ module axis_frame_length_adjust_fifo # ); wire [DATA_WIDTH-1:0] fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] fifo_axis_tkeep; wire fifo_axis_tvalid; wire fifo_axis_tready; wire fifo_axis_tlast; -wire fifo_axis_tuser; +wire [ID_WIDTH-1:0] fifo_axis_tid; +wire [DEST_WIDTH-1:0] fifo_axis_tdest; +wire [USER_WIDTH-1:0] fifo_axis_tuser; wire status_valid; wire status_ready; @@ -85,24 +102,35 @@ wire [15:0] status_frame_original_length; axis_frame_length_adjust #( .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(1) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) axis_frame_length_adjust_inst ( .clk(clk), .rst(rst), // AXI input .input_axis_tdata(input_axis_tdata), - .input_axis_tkeep(1), + .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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_axis_tdata(fifo_axis_tdata), - .output_axis_tkeep(), + .output_axis_tkeep(fifo_axis_tkeep), .output_axis_tvalid(fifo_axis_tvalid), .output_axis_tready(fifo_axis_tready), .output_axis_tlast(fifo_axis_tlast), + .output_axis_tid(fifo_axis_tid), + .output_axis_tdest(fifo_axis_tdest), .output_axis_tuser(fifo_axis_tuser), // Status .status_valid(status_valid), @@ -118,45 +146,70 @@ axis_frame_length_adjust_inst ( axis_fifo #( .ADDR_WIDTH(FRAME_FIFO_ADDR_WIDTH), - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(1), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) frame_fifo_inst ( .clk(clk), .rst(rst), // AXI input .input_axis_tdata(fifo_axis_tdata), + .input_axis_tkeep(fifo_axis_tkeep), .input_axis_tvalid(fifo_axis_tvalid), .input_axis_tready(fifo_axis_tready), .input_axis_tlast(fifo_axis_tlast), + .input_axis_tid(fifo_axis_tid), + .input_axis_tdest(fifo_axis_tdest), .input_axis_tuser(fifo_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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); axis_fifo #( .ADDR_WIDTH(HEADER_FIFO_ADDR_WIDTH), - .DATA_WIDTH(1+1+16+16) + .DATA_WIDTH(1+1+16+16), + .KEEP_ENABLE(0), + .LAST_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(0) ) header_fifo_inst ( .clk(clk), .rst(rst), // AXI input .input_axis_tdata({status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length}), + .input_axis_tkeep(0), .input_axis_tvalid(status_valid), .input_axis_tready(status_ready), .input_axis_tlast(0), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(0), // AXI output .output_axis_tdata({output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length}), + .output_axis_tkeep(), .output_axis_tvalid(output_axis_hdr_valid), .output_axis_tready(output_axis_hdr_ready), .output_axis_tlast(), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser() ); - endmodule diff --git a/rtl/axis_frame_length_adjust_fifo_64.v b/rtl/axis_frame_length_adjust_fifo_64.v deleted file mode 100644 index 292322542..000000000 --- a/rtl/axis_frame_length_adjust_fifo_64.v +++ /dev/null @@ -1,169 +0,0 @@ -/* - -Copyright (c) 2015-2017 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 frame length adjuster with FIFO (64 bit datapath) - */ -module axis_frame_length_adjust_fifo_64 # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter FRAME_FIFO_ADDR_WIDTH = 12, - parameter HEADER_FIFO_ADDR_WIDTH = 3 -) -( - 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 output_axis_hdr_valid, - input wire output_axis_hdr_ready, - output wire output_axis_hdr_pad, - output wire output_axis_hdr_truncate, - output wire [15:0] output_axis_hdr_length, - output wire [15:0] output_axis_hdr_original_length, - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Configuration - */ - input wire [15:0] length_min, - input wire [15:0] length_max -); - -wire [DATA_WIDTH-1:0] fifo_axis_tdata; -wire [KEEP_WIDTH-1:0] fifo_axis_tkeep; -wire fifo_axis_tvalid; -wire fifo_axis_tready; -wire fifo_axis_tlast; -wire fifo_axis_tuser; - -wire status_valid; -wire status_ready; -wire status_frame_pad; -wire status_frame_truncate; -wire [15:0] status_frame_length; -wire [15:0] status_frame_original_length; - -axis_frame_length_adjust #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) -) -axis_frame_length_adjust_inst ( - .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(fifo_axis_tdata), - .output_axis_tkeep(fifo_axis_tkeep), - .output_axis_tvalid(fifo_axis_tvalid), - .output_axis_tready(fifo_axis_tready), - .output_axis_tlast(fifo_axis_tlast), - .output_axis_tuser(fifo_axis_tuser), - // Status - .status_valid(status_valid), - .status_ready(status_ready), - .status_frame_pad(status_frame_pad), - .status_frame_truncate(status_frame_truncate), - .status_frame_length(status_frame_length), - .status_frame_original_length(status_frame_original_length), - // Configuration - .length_min(length_min), - .length_max(length_max) -); - -axis_fifo_64 #( - .ADDR_WIDTH(FRAME_FIFO_ADDR_WIDTH), - .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) -) -frame_fifo_inst ( - .clk(clk), - .rst(rst), - // AXI input - .input_axis_tdata(fifo_axis_tdata), - .input_axis_tkeep(fifo_axis_tkeep), - .input_axis_tvalid(fifo_axis_tvalid), - .input_axis_tready(fifo_axis_tready), - .input_axis_tlast(fifo_axis_tlast), - .input_axis_tuser(fifo_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) -); - -axis_fifo #( - .ADDR_WIDTH(HEADER_FIFO_ADDR_WIDTH), - .DATA_WIDTH(1+1+16+16) -) -header_fifo_inst ( - .clk(clk), - .rst(rst), - // AXI input - .input_axis_tdata({status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length}), - .input_axis_tvalid(status_valid), - .input_axis_tready(status_ready), - .input_axis_tlast(0), - .input_axis_tuser(0), - // AXI output - .output_axis_tdata({output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length}), - .output_axis_tvalid(output_axis_hdr_valid), - .output_axis_tready(output_axis_hdr_ready), - .output_axis_tlast(), - .output_axis_tuser() -); - - -endmodule diff --git a/tb/test_axis_frame_length_adjust_64.py b/tb/test_axis_frame_length_adjust_64.py index 34c7b0ed3..cf83dc2f2 100755 --- a/tb/test_axis_frame_length_adjust_64.py +++ b/tb/test_axis_frame_length_adjust_64.py @@ -44,7 +44,14 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -52,10 +59,12 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) status_ready = Signal(bool(0)) length_min = Signal(intbv(0)[16:]) @@ -64,10 +73,12 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) status_valid = Signal(bool(0)) status_frame_pad = Signal(bool(0)) status_frame_truncate = Signal(bool(0)) @@ -89,6 +100,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -104,6 +117,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -136,6 +151,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -143,6 +160,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser, status_valid=status_valid, @@ -206,7 +225,7 @@ def bench(): print("test 1: test packet, length %d" % payload_len) current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=1, dest=1) for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame) @@ -243,8 +262,8 @@ def bench(): print("test 2: back-to-back packets, length %d" % payload_len) current_test.next = 2 - test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=2, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=2, dest=2) for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -297,10 +316,10 @@ def bench(): print("test 3: tuser assert, length %d" % payload_len) current_test.next = 3 - test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=3, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=3, dest=2) - test_frame1.user = 1 + test_frame1.last_cycle_user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -323,7 +342,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user status = status_sink.recv() assert status.data[0][0] == (lt < lmin) diff --git a/tb/test_axis_frame_length_adjust_64.v b/tb/test_axis_frame_length_adjust_64.v index d1e1547fd..6ef943081 100644 --- a/tb/test_axis_frame_length_adjust_64.v +++ b/tb/test_axis_frame_length_adjust_64.v @@ -32,8 +32,15 @@ THE SOFTWARE. module test_axis_frame_length_adjust_64; // Parameters -localparam DATA_WIDTH = 64; -localparam KEEP_WIDTH = (DATA_WIDTH/8); +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -44,7 +51,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; reg status_ready = 0; reg [15:0] length_min = 0; @@ -56,7 +65,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; wire status_valid; wire status_frame_pad; wire status_frame_truncate; @@ -73,6 +84,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready, status_ready, @@ -85,6 +98,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser, status_valid, status_frame_pad, @@ -100,7 +115,14 @@ end axis_frame_length_adjust #( .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -111,6 +133,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_axis_tdata(output_axis_tdata), @@ -118,6 +142,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), // Status .status_valid(status_valid), diff --git a/tb/test_axis_frame_length_adjust_8.py b/tb/test_axis_frame_length_adjust_8.py index d1fff3a30..ab17bc579 100755 --- a/tb/test_axis_frame_length_adjust_8.py +++ b/tb/test_axis_frame_length_adjust_8.py @@ -44,7 +44,14 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -52,10 +59,12 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) status_ready = Signal(bool(0)) length_min = Signal(intbv(0)[16:]) @@ -64,10 +73,12 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) status_valid = Signal(bool(0)) status_frame_pad = Signal(bool(0)) status_frame_truncate = Signal(bool(0)) @@ -89,6 +100,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -104,6 +117,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -136,6 +151,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -143,6 +160,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser, status_valid=status_valid, @@ -206,7 +225,7 @@ def bench(): print("test 1: test packet, length %d" % payload_len) current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=1, dest=1) for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame) @@ -243,8 +262,8 @@ def bench(): print("test 2: back-to-back packets, length %d" % payload_len) current_test.next = 2 - test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=2, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=2, dest=2) for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -297,10 +316,10 @@ def bench(): print("test 3: tuser assert, length %d" % payload_len) current_test.next = 3 - test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=3, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=3, dest=2) - test_frame1.user = 1 + test_frame1.last_cycle_user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -323,7 +342,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user status = status_sink.recv() assert status.data[0][0] == (lt < lmin) diff --git a/tb/test_axis_frame_length_adjust_8.v b/tb/test_axis_frame_length_adjust_8.v index 74c1c2072..d1c82e312 100644 --- a/tb/test_axis_frame_length_adjust_8.v +++ b/tb/test_axis_frame_length_adjust_8.v @@ -32,8 +32,15 @@ THE SOFTWARE. module test_axis_frame_length_adjust_8; // Parameters -localparam DATA_WIDTH = 8; -localparam KEEP_WIDTH = (DATA_WIDTH/8); +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -44,7 +51,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; reg status_ready = 0; reg [15:0] length_min = 0; @@ -56,7 +65,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; wire status_valid; wire status_frame_pad; wire status_frame_truncate; @@ -73,6 +84,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready, status_ready, @@ -85,6 +98,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser, status_valid, status_frame_pad, @@ -100,7 +115,14 @@ end axis_frame_length_adjust #( .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -111,6 +133,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_axis_tdata(output_axis_tdata), @@ -118,6 +142,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), // Status .status_valid(status_valid), diff --git a/tb/test_axis_frame_length_adjust_fifo.py b/tb/test_axis_frame_length_adjust_fifo.py index ed1fffaa6..a9359ca64 100755 --- a/tb/test_axis_frame_length_adjust_fifo.py +++ b/tb/test_axis_frame_length_adjust_fifo.py @@ -46,6 +46,14 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 FRAME_FIFO_ADDR_WIDTH = 12 HEADER_FIFO_ADDR_WIDTH = 3 @@ -55,9 +63,12 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_hdr_ready = Signal(bool(0)) output_axis_tready = Signal(bool(0)) length_min = Signal(intbv(0)[16:]) @@ -71,9 +82,12 @@ def bench(): output_axis_hdr_length = Signal(intbv(0)[16:]) output_axis_hdr_original_length = Signal(intbv(0)[16:]) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -86,9 +100,12 @@ def bench(): clk, rst, tdata=input_axis_tdata, + tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -100,9 +117,12 @@ def bench(): clk, rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -131,9 +151,12 @@ def bench(): 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_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_hdr_valid=output_axis_hdr_valid, @@ -143,9 +166,12 @@ def bench(): output_axis_hdr_length=output_axis_hdr_length, output_axis_hdr_original_length=output_axis_hdr_original_length, 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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser, length_min=length_min, @@ -184,7 +210,7 @@ def bench(): print("test 1: test packet, length %d" % payload_len) current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=1, dest=1) for wait in wait_normal,: source.send(test_frame) @@ -225,8 +251,8 @@ def bench(): print("test 2: back-to-back packets, length %d" % payload_len) current_test.next = 2 - test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=2, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=2, dest=2) for wait in wait_normal,: source.send(test_frame1) @@ -281,10 +307,10 @@ def bench(): print("test 3: tuser assert, length %d" % payload_len) current_test.next = 3 - test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=3, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=3, dest=2) - test_frame1.user = 1 + test_frame1.last_cycle_user = 1 for wait in wait_normal,: source.send(test_frame1) @@ -314,7 +340,7 @@ def bench(): assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() diff --git a/tb/test_axis_frame_length_adjust_fifo.v b/tb/test_axis_frame_length_adjust_fifo.v index 09817022e..a5250f0d7 100644 --- a/tb/test_axis_frame_length_adjust_fifo.v +++ b/tb/test_axis_frame_length_adjust_fifo.v @@ -32,9 +32,17 @@ THE SOFTWARE. module test_axis_frame_length_adjust_fifo; // Parameters -localparam DATA_WIDTH = 8; -localparam FRAME_FIFO_ADDR_WIDTH = 12; -localparam HEADER_FIFO_ADDR_WIDTH = 3; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter FRAME_FIFO_ADDR_WIDTH = 12; +parameter HEADER_FIFO_ADDR_WIDTH = 3; // Inputs reg clk = 0; @@ -42,9 +50,12 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_hdr_ready = 0; reg output_axis_tready = 0; reg [15:0] length_min = 0; @@ -53,9 +64,12 @@ reg [15:0] length_max = 0; // Outputs wire input_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; wire output_axis_hdr_valid; wire output_axis_hdr_pad; wire output_axis_hdr_truncate; @@ -69,8 +83,11 @@ initial begin rst, current_test, input_axis_tdata, + input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_hdr_ready, output_axis_tready, @@ -85,8 +102,11 @@ initial begin output_axis_hdr_length, output_axis_hdr_original_length, output_axis_tdata, + output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -97,6 +117,14 @@ end axis_frame_length_adjust_fifo #( .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), .FRAME_FIFO_ADDR_WIDTH(FRAME_FIFO_ADDR_WIDTH), .HEADER_FIFO_ADDR_WIDTH(HEADER_FIFO_ADDR_WIDTH) ) @@ -105,9 +133,12 @@ UUT ( .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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_axis_hdr_valid(output_axis_hdr_valid), @@ -117,9 +148,12 @@ UUT ( .output_axis_hdr_length(output_axis_hdr_length), .output_axis_hdr_original_length(output_axis_hdr_original_length), .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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), // Configuration .length_min(length_min), diff --git a/tb/test_axis_frame_length_adjust_fifo_64.py b/tb/test_axis_frame_length_adjust_fifo_64.py index fc335227c..e423ba67c 100755 --- a/tb/test_axis_frame_length_adjust_fifo_64.py +++ b/tb/test_axis_frame_length_adjust_fifo_64.py @@ -28,15 +28,14 @@ import os import axis_ep -module = 'axis_frame_length_adjust_fifo_64' -testbench = 'test_%s' % module +module = 'axis_frame_length_adjust_fifo' +testbench = 'test_%s_64' % module srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/axis_frame_length_adjust.v") srcs.append("../rtl/axis_fifo.v") -srcs.append("../rtl/axis_fifo_64.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) @@ -47,7 +46,14 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 FRAME_FIFO_ADDR_WIDTH = 9 HEADER_FIFO_ADDR_WIDTH = 3 @@ -57,10 +63,12 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_hdr_ready = Signal(bool(0)) output_axis_tready = Signal(bool(0)) length_min = Signal(intbv(0)[16:]) @@ -74,10 +82,12 @@ def bench(): output_axis_hdr_length = Signal(intbv(0)[16:]) output_axis_hdr_original_length = Signal(intbv(0)[16:]) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -94,6 +104,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -109,6 +121,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -141,6 +155,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_hdr_valid=output_axis_hdr_valid, @@ -154,6 +170,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser, length_min=length_min, @@ -192,7 +210,7 @@ def bench(): print("test 1: test packet, length %d" % payload_len) current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=1, dest=1) for wait in wait_normal,: source.send(test_frame) @@ -233,8 +251,8 @@ def bench(): print("test 2: back-to-back packets, length %d" % payload_len) current_test.next = 2 - test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=2, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=2, dest=2) for wait in wait_normal,: source.send(test_frame1) @@ -289,10 +307,10 @@ def bench(): print("test 3: tuser assert, length %d" % payload_len) current_test.next = 3 - test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) - test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len))) + test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=3, dest=1) + test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)), id=3, dest=2) - test_frame1.user = 1 + test_frame1.last_cycle_user = 1 for wait in wait_normal,: source.send(test_frame1) @@ -322,7 +340,7 @@ def bench(): assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() diff --git a/tb/test_axis_frame_length_adjust_fifo_64.v b/tb/test_axis_frame_length_adjust_fifo_64.v index d8b105511..941fa8b64 100644 --- a/tb/test_axis_frame_length_adjust_fifo_64.v +++ b/tb/test_axis_frame_length_adjust_fifo_64.v @@ -27,15 +27,22 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_frame_length_adjust_fifo_64 + * Testbench for axis_frame_length_adjust_fifo */ module test_axis_frame_length_adjust_fifo_64; // Parameters -localparam DATA_WIDTH = 64; -localparam KEEP_WIDTH = (DATA_WIDTH/8); -localparam FRAME_FIFO_ADDR_WIDTH = 9; -localparam HEADER_FIFO_ADDR_WIDTH = 3; +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter FRAME_FIFO_ADDR_WIDTH = 9; +parameter HEADER_FIFO_ADDR_WIDTH = 3; // Inputs reg clk = 0; @@ -46,7 +53,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_hdr_ready = 0; reg output_axis_tready = 0; reg [15:0] length_min = 0; @@ -58,7 +67,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; wire output_axis_hdr_valid; wire output_axis_hdr_pad; wire output_axis_hdr_truncate; @@ -75,6 +86,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_hdr_ready, output_axis_tready, @@ -92,6 +105,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -100,9 +115,16 @@ initial begin $dumpvars(0, test_axis_frame_length_adjust_fifo_64); end -axis_frame_length_adjust_fifo_64 #( +axis_frame_length_adjust_fifo #( .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), .FRAME_FIFO_ADDR_WIDTH(FRAME_FIFO_ADDR_WIDTH), .HEADER_FIFO_ADDR_WIDTH(HEADER_FIFO_ADDR_WIDTH) ) @@ -115,6 +137,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_axis_hdr_valid(output_axis_hdr_valid), @@ -128,6 +152,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), // Configuration .length_min(length_min), From d16f19f67e42179ed429fa726d96a02cb475ed63 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 21:31:41 -0800 Subject: [PATCH 361/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream rate limiter --- rtl/axis_rate_limit.v | 85 +++++++++---- rtl/axis_rate_limit_64.v | 217 ---------------------------------- tb/test_axis_rate_limit.py | 180 ++++++++++++++++++++-------- tb/test_axis_rate_limit.v | 48 +++++++- tb/test_axis_rate_limit_64.py | 177 ++++++++++++++++++--------- tb/test_axis_rate_limit_64.v | 44 +++++-- 6 files changed, 393 insertions(+), 358 deletions(-) delete mode 100644 rtl/axis_rate_limit_64.v diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index 166235d33..5ea7fd7d6 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -31,7 +31,16 @@ THE SOFTWARE. */ module axis_rate_limit # ( - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( input wire clk, @@ -41,19 +50,25 @@ module axis_rate_limit # * 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, + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, /* * AXI output */ 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, + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser, /* * Configuration @@ -64,12 +79,15 @@ module axis_rate_limit # ); // internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg [ID_WIDTH-1:0] output_axis_tid_int; +reg [DEST_WIDTH-1:0] output_axis_tdest_int; +reg [USER_WIDTH-1:0] output_axis_tuser_int; +wire output_axis_tready_int_early; reg [23:0] acc_reg = 24'd0, acc_next; reg pause; @@ -95,7 +113,7 @@ always @* begin end if (acc_next >= rate_num) begin - if (rate_by_frame) begin + if (LAST_ENABLE && rate_by_frame) begin pause = ~frame_next; end else begin pause = 1'b1; @@ -104,10 +122,13 @@ always @* begin input_axis_tready_next = output_axis_tready_int_early & ~pause; - output_axis_tdata_int = input_axis_tdata; + output_axis_tdata_int = input_axis_tdata; + output_axis_tkeep_int = input_axis_tkeep; output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tuser_int = input_axis_tuser; + output_axis_tlast_int = input_axis_tlast; + output_axis_tid_int = input_axis_tid; + output_axis_tdest_int = input_axis_tdest; + output_axis_tuser_int = input_axis_tuser; end always @(posedge clk) begin @@ -123,25 +144,34 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign output_axis_tlast = LAST_ENABLE ? output_axis_tlast_reg : 1'b1; +assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); @@ -154,7 +184,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin @@ -188,17 +218,26 @@ always @(posedge clk) begin // datapath if (store_axis_int_to_output) begin output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tid_reg <= output_axis_tid_int; + output_axis_tdest_reg <= output_axis_tdest_int; output_axis_tuser_reg <= output_axis_tuser_int; end else if (store_axis_temp_to_output) begin output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end if (store_axis_int_to_temp) begin temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tid_reg <= output_axis_tid_int; + temp_axis_tdest_reg <= output_axis_tdest_int; temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_rate_limit_64.v b/rtl/axis_rate_limit_64.v deleted file mode 100644 index 0b6240021..000000000 --- a/rtl/axis_rate_limit_64.v +++ /dev/null @@ -1,217 +0,0 @@ -/* - -Copyright (c) 2014-2017 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream rate limiter (64 bit datapath) - */ -module axis_rate_limit_64 # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] input_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] output_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Configuration - */ - input wire [7:0] rate_num, - input wire [7:0] rate_denom, - input wire rate_by_frame -); - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -reg [23:0] acc_reg = 24'd0, acc_next; -reg pause; -reg frame_reg = 1'b0, frame_next; - -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; - -assign input_axis_tready = input_axis_tready_reg; - -always @* begin - acc_next = acc_reg; - pause = 1'b0; - frame_next = frame_reg; - - if (acc_reg >= rate_num) begin - acc_next = acc_reg - rate_num; - end - - if (input_axis_tready & input_axis_tvalid) begin - // read input - frame_next = ~input_axis_tlast; - acc_next = acc_reg + (rate_denom - rate_num); - end - - if (acc_next >= rate_num) begin - if (rate_by_frame) begin - pause = ~frame_next; - end else begin - pause = 1'b1; - end - end - - input_axis_tready_next = output_axis_tready_int_early & ~pause; - - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tuser_int = input_axis_tuser; -end - -always @(posedge clk) begin - if (rst) begin - acc_reg <= 24'd0; - frame_reg <= 1'b0; - input_axis_tready_reg <= 1'b0; - end else begin - acc_reg <= acc_next; - frame_reg <= frame_next; - input_axis_tready_reg <= input_axis_tready_next; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index c8e070450..6f3ea0360 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -44,6 +44,15 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -51,9 +60,12 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) rate_num = Signal(intbv(0)[8:]) @@ -63,9 +75,12 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -77,9 +92,12 @@ def bench(): clk, rst, tdata=input_axis_tdata, + tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -91,9 +109,12 @@ def bench(): clk, rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -110,15 +131,21 @@ def bench(): 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_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, 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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser, rate_num=rate_num, @@ -146,9 +173,9 @@ def bench(): cbc = 0 cfc = 0 reset_stats.next = 0 - ctc += 1 + ctc += len(output_axis_tkeep) if output_axis_tready and output_axis_tvalid: - cbc += 1 + cbc += bin(output_axis_tkeep).count('1') if output_axis_tlast: cur_frame.next = False elif not cur_frame: @@ -185,10 +212,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -208,10 +240,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -229,10 +266,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -266,14 +308,23 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -298,14 +349,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -338,14 +398,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -378,11 +447,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -395,7 +469,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -416,10 +490,14 @@ def bench(): test_frame = [] for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(lens[i])))) + test_frame.append(axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i])), + id=i, + dest=1 + )) for f in test_frame: source.send(f) @@ -451,7 +529,7 @@ def bench(): print("byte count %d" % byte_count) print("frame count %d" % frame_count) - assert tick_count == cycle + assert tick_count == cycle*len(output_axis_tkeep) assert byte_count == sum(len(f.data) for f in test_frame) assert frame_count == len(test_frame) diff --git a/tb/test_axis_rate_limit.v b/tb/test_axis_rate_limit.v index 06e88e3ae..a22aaf2f7 100644 --- a/tb/test_axis_rate_limit.v +++ b/tb/test_axis_rate_limit.v @@ -33,6 +33,15 @@ module test_axis_rate_limit; // Parameters parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -40,9 +49,12 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; reg [7:0] rate_num = 0; reg [7:0] rate_denom = 0; @@ -51,9 +63,12 @@ reg rate_by_frame = 0; // Outputs wire input_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -62,8 +77,11 @@ initial begin rst, current_test, input_axis_tdata, + input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready, rate_num, @@ -73,8 +91,11 @@ initial begin $to_myhdl( input_axis_tready, output_axis_tdata, + output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -84,24 +105,39 @@ initial begin end axis_rate_limit #( - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .rst(rst), - // axi input + // 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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), - // axi output + // 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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), - // configuration + // Configuration .rate_num(rate_num), .rate_denom(rate_denom), .rate_by_frame(rate_by_frame) diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index 8d5349bc7..ded85b1a0 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_rate_limit_64' -testbench = 'test_%s' % module +module = 'axis_rate_limit' +testbench = 'test_%s_64' % module srcs = [] @@ -44,7 +44,15 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -52,10 +60,12 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) rate_num = Signal(intbv(0)[8:]) @@ -65,10 +75,12 @@ def bench(): # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -84,6 +96,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -99,6 +113,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -119,6 +135,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -126,6 +144,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser, rate_num=rate_num, @@ -192,10 +212,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -215,10 +240,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -236,10 +266,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -273,14 +308,23 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -305,14 +349,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -345,14 +398,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -385,11 +447,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -402,7 +469,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -423,10 +490,14 @@ def bench(): test_frame = [] for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(lens[i])))) + test_frame.append(axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i])), + id=i, + dest=1 + )) for f in test_frame: source.send(f) @@ -458,7 +529,7 @@ def bench(): print("byte count %d" % byte_count) print("frame count %d" % frame_count) - assert tick_count == cycle*8 + assert tick_count == cycle*len(output_axis_tkeep) assert byte_count == sum(len(f.data) for f in test_frame) assert frame_count == len(test_frame) diff --git a/tb/test_axis_rate_limit_64.v b/tb/test_axis_rate_limit_64.v index ce8afc1dc..6926c3c07 100644 --- a/tb/test_axis_rate_limit_64.v +++ b/tb/test_axis_rate_limit_64.v @@ -27,13 +27,21 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_rate_limit_64 + * Testbench for axis_rate_limit */ module test_axis_rate_limit_64; // Parameters parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -44,7 +52,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; reg [7:0] rate_num = 0; reg [7:0] rate_denom = 0; @@ -56,7 +66,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -68,6 +80,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready, rate_num, @@ -80,6 +94,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -88,28 +104,40 @@ initial begin $dumpvars(0, test_axis_rate_limit_64); end -axis_rate_limit_64 #( +axis_rate_limit #( .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .rst(rst), - // axi input + // 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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), - // axi output + // 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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), - // configuration + // Configuration .rate_num(rate_num), .rate_denom(rate_denom), .rate_by_frame(rate_by_frame) From b0d7820f5b1f918505fee9340540be68d1a029a8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 21:32:46 -0800 Subject: [PATCH 362/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream SRL FIFO --- rtl/axis_srl_fifo.v | 53 +++++++++-- rtl/axis_srl_fifo_64.v | 144 ----------------------------- tb/test_axis_srl_fifo.py | 174 +++++++++++++++++++++++++---------- tb/test_axis_srl_fifo.v | 42 ++++++++- tb/test_axis_srl_fifo_64.py | 175 +++++++++++++++++++++++++----------- tb/test_axis_srl_fifo_64.v | 38 ++++++-- 6 files changed, 371 insertions(+), 255 deletions(-) delete mode 100644 rtl/axis_srl_fifo_64.v diff --git a/rtl/axis_srl_fifo.v b/rtl/axis_srl_fifo.v index 499b19625..e800fe073 100644 --- a/rtl/axis_srl_fifo.v +++ b/rtl/axis_srl_fifo.v @@ -32,6 +32,15 @@ THE SOFTWARE. module axis_srl_fifo # ( parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, parameter DEPTH = 16 ) ( @@ -42,19 +51,25 @@ module axis_srl_fifo # * 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, + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, /* * AXI output */ 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, + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser, /* * Status @@ -62,14 +77,42 @@ module axis_srl_fifo # output wire [$clog2(DEPTH+1)-1:0] count ); -reg [DATA_WIDTH+2-1:0] data_reg[DEPTH-1:0]; +localparam KEEP_OFFSET = DATA_WIDTH; +localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); +localparam ID_OFFSET = LAST_OFFSET + (LAST_ENABLE ? 1 : 0); +localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0); +localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); +localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); + +reg [WIDTH-1:0] data_reg[DEPTH-1:0]; reg [$clog2(DEPTH+1)-1:0] ptr_reg = 0; 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]; +wire [WIDTH-1:0] input_axis; + +wire [WIDTH-1:0] output_axis = data_reg[ptr_reg-1]; + assign input_axis_tready = ~full_reg; + +generate + assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; + if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; + if (LAST_ENABLE) assign input_axis[LAST_OFFSET] = input_axis_tlast; + if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; + if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; + if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; +endgenerate + assign output_axis_tvalid = ~empty_reg; + +assign output_axis_tdata = output_axis[DATA_WIDTH-1:0]; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +assign output_axis_tlast = LAST_ENABLE ? output_axis[LAST_OFFSET] : 1'b1; +assign output_axis_tid = ID_ENABLE ? output_axis[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; + assign count = ptr_reg; wire ptr_empty = ptr_reg == 0; @@ -131,7 +174,7 @@ always @(posedge clk) begin end if (shift) begin - data_reg[0] <= {input_axis_tlast, input_axis_tuser, input_axis_tdata}; + data_reg[0] <= input_axis; for (i = 0; i < DEPTH-1; i = i + 1) begin data_reg[i+1] <= data_reg[i]; end diff --git a/rtl/axis_srl_fifo_64.v b/rtl/axis_srl_fifo_64.v deleted file mode 100644 index 28f0c9478..000000000 --- a/rtl/axis_srl_fifo_64.v +++ /dev/null @@ -1,144 +0,0 @@ -/* - -Copyright (c) 2014-2017 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; -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; - 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; - full_reg <= 0; - empty_reg <= 1; - end else begin - 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 - - 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 -end - -endmodule diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py index 60a239fad..b04d70f4f 100755 --- a/tb/test_axis_srl_fifo.py +++ b/tb/test_axis_srl_fifo.py @@ -45,6 +45,15 @@ def bench(): # Parameters DEPTH = 4 DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -52,18 +61,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) count = Signal(intbv(0)[3:]) # sources and sinks @@ -76,9 +90,12 @@ def bench(): clk, rst, tdata=input_axis_tdata, + tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -90,9 +107,12 @@ def bench(): clk, rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -109,15 +129,21 @@ def bench(): 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_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, 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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser, count=count @@ -144,10 +170,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -165,10 +196,14 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1) + source.send(test_frame) yield clk.posedge @@ -184,10 +219,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -219,14 +259,23 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -251,14 +300,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -288,14 +346,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -325,11 +392,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -340,7 +412,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -348,7 +420,11 @@ def bench(): print("test 8: initial sink pause") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + test_frame = axis_ep.AXIStreamFrame( + b'\x01\x02\x03', + id=8, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) @@ -372,7 +448,11 @@ def bench(): print("test 9: initial sink pause, reset") current_test.next = 9 - test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03') + test_frame = axis_ep.AXIStreamFrame( + b'\x01\x02\x03', + id=9, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) diff --git a/tb/test_axis_srl_fifo.v b/tb/test_axis_srl_fifo.v index 1721e5d5a..e449e5af7 100644 --- a/tb/test_axis_srl_fifo.v +++ b/tb/test_axis_srl_fifo.v @@ -34,6 +34,15 @@ module test_axis_srl_fifo; // Parameters parameter DEPTH = 4; parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -41,17 +50,23 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs wire input_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; wire [2:0] count; @@ -62,16 +77,22 @@ initial begin rst, current_test, input_axis_tdata, + input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, 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_tid, + output_axis_tdest, output_axis_tuser, count ); @@ -83,22 +104,37 @@ end axis_srl_fifo #( .DEPTH(DEPTH), - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), // Status .count(count) diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py index eba2b7308..78cedb9e0 100755 --- a/tb/test_axis_srl_fifo_64.py +++ b/tb/test_axis_srl_fifo_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_srl_fifo_64' -testbench = 'test_%s' % module +module = 'axis_srl_fifo' +testbench = 'test_%s_64' % module srcs = [] @@ -45,7 +45,15 @@ def bench(): # Parameters DEPTH = 4 DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) @@ -53,20 +61,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) count = Signal(intbv(0)[3:]) # sources and sinks @@ -83,6 +94,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -98,6 +111,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -118,6 +133,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -125,6 +142,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser, count=count @@ -151,10 +170,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -172,10 +196,14 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1) + source.send(test_frame) yield clk.posedge @@ -191,10 +219,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -226,14 +259,23 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -258,14 +300,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -295,14 +346,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -332,11 +392,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -347,7 +412,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -355,7 +420,11 @@ def bench(): print("test 8: initial sink pause") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(24)), + id=8, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) @@ -379,7 +448,11 @@ def bench(): print("test 9: initial sink pause, reset") current_test.next = 9 - test_frame = axis_ep.AXIStreamFrame(bytearray(range(24))) + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(24)), + id=9, + dest=1 + ) sink_pause.next = 1 source.send(test_frame) diff --git a/tb/test_axis_srl_fifo_64.v b/tb/test_axis_srl_fifo_64.v index be6b8ed0c..a4773e80d 100644 --- a/tb/test_axis_srl_fifo_64.v +++ b/tb/test_axis_srl_fifo_64.v @@ -27,14 +27,22 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_srl_fifo_64 + * Testbench for axis_srl_fifo */ module test_axis_srl_fifo_64; // Parameters parameter DEPTH = 4; parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -45,7 +53,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs @@ -54,7 +64,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; wire [2:0] count; @@ -68,6 +80,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready ); @@ -77,6 +91,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser, count ); @@ -86,10 +102,18 @@ initial begin $dumpvars(0, test_axis_srl_fifo_64); end -axis_srl_fifo_64 #( +axis_srl_fifo #( .DEPTH(DEPTH), .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -100,6 +124,8 @@ UUT ( .input_axis_tvalid(input_axis_tvalid), .input_axis_tready(input_axis_tready), .input_axis_tlast(input_axis_tlast), + .input_axis_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), // AXI output .output_axis_tdata(output_axis_tdata), @@ -107,6 +133,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser), // Status .count(count) From 4ef4ef262239633ef2ae30565e8d8ad47eea5235 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 21:34:25 -0800 Subject: [PATCH 363/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream SRL register --- rtl/axis_srl_register.v | 54 +++++++++-- rtl/axis_srl_register_64.v | 105 -------------------- tb/test_axis_srl_register.py | 166 ++++++++++++++++++++++--------- tb/test_axis_srl_register.v | 46 ++++++++- tb/test_axis_srl_register_64.py | 167 ++++++++++++++++++++++---------- tb/test_axis_srl_register_64.v | 42 ++++++-- 6 files changed, 361 insertions(+), 219 deletions(-) delete mode 100644 rtl/axis_srl_register_64.v diff --git a/rtl/axis_srl_register.v b/rtl/axis_srl_register.v index 745322ec5..c601dc0e7 100644 --- a/rtl/axis_srl_register.v +++ b/rtl/axis_srl_register.v @@ -31,7 +31,16 @@ THE SOFTWARE. */ module axis_srl_register # ( - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 ) ( input wire clk, @@ -41,30 +50,63 @@ module axis_srl_register # * 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, + input wire [ID_WIDTH-1:0] input_axis_tid, + input wire [DEST_WIDTH-1:0] input_axis_tdest, + input wire [USER_WIDTH-1:0] input_axis_tuser, /* * AXI output */ 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 + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser ); -reg [DATA_WIDTH+2-1:0] data_reg[1:0]; +localparam KEEP_OFFSET = DATA_WIDTH; +localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); +localparam ID_OFFSET = LAST_OFFSET + (LAST_ENABLE ? 1 : 0); +localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0); +localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); +localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); + +reg [WIDTH-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]; +wire [WIDTH-1:0] input_axis; + +wire [WIDTH-1:0] output_axis = data_reg[ptr_reg]; + assign input_axis_tready = ~full_reg; + +generate + assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; + if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; + if (LAST_ENABLE) assign input_axis[LAST_OFFSET] = input_axis_tlast; + if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; + if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; + if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; +endgenerate + assign output_axis_tvalid = valid_reg[ptr_reg]; +assign output_axis_tdata = output_axis[DATA_WIDTH-1:0]; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +assign output_axis_tlast = LAST_ENABLE ? output_axis[LAST_OFFSET] : 1'b1; +assign output_axis_tid = ID_ENABLE ? output_axis[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; + integer i; initial begin @@ -84,7 +126,7 @@ always @(posedge clk) begin // transfer in if not full if (input_axis_tready) begin - data_reg[0] <= {input_axis_tlast, input_axis_tuser, input_axis_tdata}; + data_reg[0] <= input_axis; valid_reg[0] <= input_axis_tvalid; for (i = 0; i < 1; i = i + 1) begin data_reg[i+1] <= data_reg[i]; diff --git a/rtl/axis_srl_register_64.v b/rtl/axis_srl_register_64.v deleted file mode 100644 index c5b9349a4..000000000 --- a/rtl/axis_srl_register_64.v +++ /dev/null @@ -1,105 +0,0 @@ -/* - -Copyright (c) 2014-2017 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; - full_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 diff --git a/tb/test_axis_srl_register.py b/tb/test_axis_srl_register.py index 7ee80615f..dc7286506 100755 --- a/tb/test_axis_srl_register.py +++ b/tb/test_axis_srl_register.py @@ -44,24 +44,39 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[8:]) + input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -73,9 +88,12 @@ def bench(): clk, rst, tdata=input_axis_tdata, + tkeep=input_axis_tkeep, tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -87,9 +105,12 @@ def bench(): clk, rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -106,15 +127,21 @@ def bench(): 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_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, 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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -139,10 +166,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -160,10 +192,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -179,10 +216,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -214,14 +256,23 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -246,14 +297,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -283,14 +343,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -320,11 +389,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -335,7 +409,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) diff --git a/tb/test_axis_srl_register.v b/tb/test_axis_srl_register.v index eac2b6d99..f553f1e67 100644 --- a/tb/test_axis_srl_register.v +++ b/tb/test_axis_srl_register.v @@ -33,6 +33,15 @@ module test_axis_srl_register; // Parameters parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -40,17 +49,23 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] input_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs wire input_axis_tready; wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -59,16 +74,22 @@ initial begin rst, current_test, input_axis_tdata, + input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, 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_tid, + output_axis_tdest, output_axis_tuser ); @@ -78,22 +99,37 @@ initial begin end axis_srl_register #( - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .rst(rst), - // axi input + // 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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), - // axi output + // 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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); diff --git a/tb/test_axis_srl_register_64.py b/tb/test_axis_srl_register_64.py index 6aa0485c1..cd229b35c 100755 --- a/tb/test_axis_srl_register_64.py +++ b/tb/test_axis_srl_register_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_srl_register_64' -testbench = 'test_%s' % module +module = 'axis_srl_register' +testbench = 'test_%s_64' % module srcs = [] @@ -44,27 +44,39 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 # 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_tdata = Signal(intbv(0)[DATA_WIDTH:]) + input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) input_axis_tvalid = Signal(bool(0)) input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[64:]) - output_axis_tkeep = Signal(intbv(0)[8:]) + output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -80,6 +92,8 @@ def bench(): tvalid=input_axis_tvalid, tready=input_axis_tready, tlast=input_axis_tlast, + tid=input_axis_tid, + tdest=input_axis_tdest, tuser=input_axis_tuser, pause=source_pause, name='source' @@ -95,6 +109,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -115,6 +131,8 @@ def bench(): input_axis_tvalid=input_axis_tvalid, input_axis_tready=input_axis_tready, input_axis_tlast=input_axis_tlast, + input_axis_tid=input_axis_tid, + input_axis_tdest=input_axis_tdest, input_axis_tuser=input_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -122,6 +140,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -146,10 +166,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -167,10 +192,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -186,10 +216,15 @@ def bench(): print("test 3: test packet with pauses") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -221,14 +256,23 @@ def bench(): print("test 4: back-to-back packets") current_test.next = 4 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -253,14 +297,23 @@ def bench(): print("test 5: alternate pause source") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -290,14 +343,23 @@ def bench(): print("test 6: alternate pause sink") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -327,11 +389,16 @@ def bench(): print("test 7: tuser assert") current_test.next = 7 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -342,7 +409,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) diff --git a/tb/test_axis_srl_register_64.v b/tb/test_axis_srl_register_64.v index 8450e8cde..a1940a3b8 100644 --- a/tb/test_axis_srl_register_64.v +++ b/tb/test_axis_srl_register_64.v @@ -27,13 +27,21 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_srl_register_64 + * Testbench for axis_srl_register */ module test_axis_srl_register_64; // Parameters parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; // Inputs reg clk = 0; @@ -44,7 +52,9 @@ reg [DATA_WIDTH-1:0] input_axis_tdata = 0; reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; reg input_axis_tvalid = 0; reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [ID_WIDTH-1:0] input_axis_tid = 0; +reg [DEST_WIDTH-1:0] input_axis_tdest = 0; +reg [USER_WIDTH-1:0] input_axis_tuser = 0; reg output_axis_tready = 0; // Outputs @@ -53,7 +63,9 @@ wire [DATA_WIDTH-1:0] output_axis_tdata; wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -65,6 +77,8 @@ initial begin input_axis_tkeep, input_axis_tvalid, input_axis_tlast, + input_axis_tid, + input_axis_tdest, input_axis_tuser, output_axis_tready ); @@ -74,6 +88,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -82,26 +98,38 @@ initial begin $dumpvars(0, test_axis_srl_register_64); end -axis_srl_register_64 #( +axis_srl_register #( .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), .rst(rst), - // axi input + // 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_tid(input_axis_tid), + .input_axis_tdest(input_axis_tdest), .input_axis_tuser(input_axis_tuser), - // axi output + // 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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); From 0edafd58acc139880ff0b9736092af7bc10aed50 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 20 Nov 2017 23:45:34 -0800 Subject: [PATCH 364/617] Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream tap --- rtl/axis_tap.v | 127 +++++++++++++++----- rtl/axis_tap_64.v | 266 ----------------------------------------- tb/test_axis_tap.py | 182 ++++++++++++++++++++-------- tb/test_axis_tap.v | 44 ++++++- tb/test_axis_tap_64.py | 183 +++++++++++++++++++--------- tb/test_axis_tap_64.v | 44 +++++-- 6 files changed, 433 insertions(+), 413 deletions(-) delete mode 100644 rtl/axis_tap_64.v diff --git a/rtl/axis_tap.v b/rtl/axis_tap.v index dc8b9e4b0..de64ef945 100644 --- a/rtl/axis_tap.v +++ b/rtl/axis_tap.v @@ -31,7 +31,17 @@ THE SOFTWARE. */ module axis_tap # ( - parameter DATA_WIDTH = 8 + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + parameter USER_BAD_FRAME_VALUE = 1'b1, + parameter USER_BAD_FRAME_MASK = 1'b1 ) ( input wire clk, @@ -41,28 +51,44 @@ module axis_tap # * AXI tap */ input wire [DATA_WIDTH-1:0] tap_axis_tdata, + input wire [KEEP_WIDTH-1:0] tap_axis_tkeep, input wire tap_axis_tvalid, input wire tap_axis_tready, input wire tap_axis_tlast, - input wire tap_axis_tuser, + input wire [ID_WIDTH-1:0] tap_axis_tid, + input wire [DEST_WIDTH-1:0] tap_axis_tdest, + input wire [USER_WIDTH-1:0] tap_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 + output wire [ID_WIDTH-1:0] output_axis_tid, + output wire [DEST_WIDTH-1:0] output_axis_tdest, + output wire [USER_WIDTH-1:0] output_axis_tuser ); +// datapath control signals +reg store_last_word; + +reg [ID_WIDTH-1:0] last_word_id_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] last_word_dest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] last_word_user_reg = {USER_WIDTH{1'b0}}; + // internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg [ID_WIDTH-1:0] output_axis_tid_int; +reg [DEST_WIDTH-1:0] output_axis_tdest_int; +reg [USER_WIDTH-1:0] output_axis_tuser_int; +wire output_axis_tready_int_early; localparam [1:0] STATE_IDLE = 2'd0, @@ -77,12 +103,17 @@ reg frame_reg = 1'b0, frame_next; always @* begin state_next = STATE_IDLE; + store_last_word = 1'b0; + frame_next = frame_reg; - output_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + output_axis_tlast_int = 1'b0; + output_axis_tid_int = {ID_WIDTH{1'b0}}; + output_axis_tdest_int = {DEST_WIDTH{1'b0}}; + output_axis_tuser_int = {USER_WIDTH{1'b0}}; if (tap_axis_tready & tap_axis_tvalid) begin frame_next = ~tap_axis_tlast; @@ -93,10 +124,13 @@ always @* begin if (tap_axis_tready & tap_axis_tvalid) begin // start of frame if (output_axis_tready_int_reg) begin - output_axis_tdata_int = tap_axis_tdata; + output_axis_tdata_int = tap_axis_tdata; + output_axis_tkeep_int = tap_axis_tkeep; output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; - output_axis_tlast_int = tap_axis_tlast; - output_axis_tuser_int = tap_axis_tuser; + output_axis_tlast_int = tap_axis_tlast; + output_axis_tid_int = tap_axis_tid; + output_axis_tdest_int = tap_axis_tdest; + output_axis_tuser_int = tap_axis_tuser; if (tap_axis_tlast) begin state_next = STATE_IDLE; end else begin @@ -113,16 +147,20 @@ always @* begin if (tap_axis_tready & tap_axis_tvalid) begin // transfer data if (output_axis_tready_int_reg) begin - output_axis_tdata_int = tap_axis_tdata; + output_axis_tdata_int = tap_axis_tdata; + output_axis_tkeep_int = tap_axis_tkeep; output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; - output_axis_tlast_int = tap_axis_tlast; - output_axis_tuser_int = tap_axis_tuser; + output_axis_tlast_int = tap_axis_tlast; + output_axis_tid_int = tap_axis_tid; + output_axis_tdest_int = tap_axis_tdest; + output_axis_tuser_int = tap_axis_tuser; if (tap_axis_tlast) begin state_next = STATE_IDLE; end else begin state_next = STATE_TRANSFER; end end else begin + store_last_word = 1'b1; state_next = STATE_TRUNCATE; end end else begin @@ -131,10 +169,13 @@ always @* begin end STATE_TRUNCATE: begin if (output_axis_tready_int_reg) begin - output_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_axis_tdata_int = {DATA_WIDTH{1'b0}}; + output_axis_tkeep_int = {{KEEP_WIDTH-1{1'b0}}, 1'b1}; output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = 1'b1; + output_axis_tlast_int = 1'b1; + output_axis_tid_int = last_word_id_reg; + output_axis_tdest_int = last_word_dest_reg; + output_axis_tuser_int = (last_word_user_reg & ~USER_BAD_FRAME_MASK) | (USER_BAD_FRAME_VALUE & USER_BAD_FRAME_MASK); if (frame_next) begin state_next = STATE_WAIT; end else begin @@ -166,28 +207,43 @@ always @(posedge clk) begin state_reg <= state_next; frame_reg <= frame_next; end + + if (store_last_word) begin + last_word_id_reg <= tap_axis_tid; + last_word_dest_reg <= tap_axis_tdest; + last_word_user_reg <= tap_axis_tuser; + end end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); @@ -200,7 +256,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin @@ -234,17 +290,26 @@ always @(posedge clk) begin // datapath if (store_axis_int_to_output) begin output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tid_reg <= output_axis_tid_int; + output_axis_tdest_reg <= output_axis_tdest_int; output_axis_tuser_reg <= output_axis_tuser_int; end else if (store_axis_temp_to_output) begin output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; output_axis_tuser_reg <= temp_axis_tuser_reg; end if (store_axis_int_to_temp) begin temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tid_reg <= output_axis_tid_int; + temp_axis_tdest_reg <= output_axis_tdest_int; temp_axis_tuser_reg <= output_axis_tuser_int; end end diff --git a/rtl/axis_tap_64.v b/rtl/axis_tap_64.v deleted file mode 100644 index ce9d91d05..000000000 --- a/rtl/axis_tap_64.v +++ /dev/null @@ -1,266 +0,0 @@ -/* - -Copyright (c) 2015-2017 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 tap (64 bit datapath) - */ -module axis_tap_64 # -( - parameter DATA_WIDTH = 64, - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * AXI tap - */ - input wire [DATA_WIDTH-1:0] tap_axis_tdata, - input wire [KEEP_WIDTH-1:0] tap_axis_tkeep, - input wire tap_axis_tvalid, - input wire tap_axis_tready, - input wire tap_axis_tlast, - input wire tap_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 -); - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_TRANSFER = 2'd1, - STATE_TRUNCATE = 2'd2, - STATE_WAIT = 2'd3; - -reg [1:0] state_reg = STATE_IDLE, state_next; - -reg frame_reg = 1'b0, frame_next; - -always @* begin - state_next = STATE_IDLE; - - frame_next = frame_reg; - - output_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; - - if (tap_axis_tready & tap_axis_tvalid) begin - frame_next = ~tap_axis_tlast; - end - - case (state_reg) - STATE_IDLE: begin - if (tap_axis_tready & tap_axis_tvalid) begin - // start of frame - if (output_axis_tready_int_reg) begin - output_axis_tdata_int = tap_axis_tdata; - output_axis_tkeep_int = tap_axis_tkeep; - output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; - output_axis_tlast_int = tap_axis_tlast; - output_axis_tuser_int = tap_axis_tuser; - if (tap_axis_tlast) begin - state_next = STATE_IDLE; - end else begin - state_next = STATE_TRANSFER; - end - end else begin - state_next = STATE_WAIT; - end - end else begin - state_next = STATE_IDLE; - end - end - STATE_TRANSFER: begin - if (tap_axis_tready & tap_axis_tvalid) begin - // transfer data - if (output_axis_tready_int_reg) begin - output_axis_tdata_int = tap_axis_tdata; - output_axis_tkeep_int = tap_axis_tkeep; - output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; - output_axis_tlast_int = tap_axis_tlast; - output_axis_tuser_int = tap_axis_tuser; - if (tap_axis_tlast) begin - state_next = STATE_IDLE; - end else begin - state_next = STATE_TRANSFER; - end - end else begin - state_next = STATE_TRUNCATE; - end - end else begin - state_next = STATE_TRANSFER; - end - end - STATE_TRUNCATE: begin - if (output_axis_tready_int_reg) begin - output_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_axis_tkeep_int = {{KEEP_WIDTH-1{1'b0}}, 1'b1}; - output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = 1'b1; - if (frame_next) begin - state_next = STATE_WAIT; - end else begin - state_next = STATE_IDLE; - end - end else begin - state_next = STATE_TRUNCATE; - end - end - STATE_WAIT: begin - if (tap_axis_tready & tap_axis_tvalid) begin - if (tap_axis_tlast) begin - state_next = STATE_IDLE; - end else begin - state_next = STATE_WAIT; - end - end else begin - state_next = STATE_WAIT; - end - end - endcase -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - frame_reg <= 1'b0; - end else begin - state_reg <= state_next; - frame_reg <= frame_next; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_axis_tap.py b/tb/test_axis_tap.py index 79b9e97d9..c54892fd7 100755 --- a/tb/test_axis_tap.py +++ b/tb/test_axis_tap.py @@ -44,6 +44,16 @@ def bench(): # Parameters DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 # Inputs clk = Signal(bool(0)) @@ -51,17 +61,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) tap_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + tap_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) tap_axis_tvalid = Signal(bool(0)) tap_axis_tready = Signal(bool(1)) tap_axis_tlast = Signal(bool(0)) - tap_axis_tuser = Signal(bool(0)) + tap_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + tap_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + tap_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -73,9 +89,12 @@ def bench(): clk, rst, tdata=tap_axis_tdata, + tkeep=tap_axis_tkeep, tvalid=tap_axis_tvalid, tready=tap_axis_tready, tlast=tap_axis_tlast, + tid=tap_axis_tid, + tdest=tap_axis_tdest, tuser=tap_axis_tuser, pause=source_pause, name='source' @@ -87,9 +106,12 @@ def bench(): clk, rst, tdata=output_axis_tdata, + tkeep=output_axis_tkeep, tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -106,15 +128,21 @@ def bench(): current_test=current_test, tap_axis_tdata=tap_axis_tdata, + tap_axis_tkeep=tap_axis_tkeep, tap_axis_tvalid=tap_axis_tvalid, tap_axis_tready=tap_axis_tready, tap_axis_tlast=tap_axis_tlast, + tap_axis_tid=tap_axis_tid, + tap_axis_tdest=tap_axis_tdest, tap_axis_tuser=tap_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_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -139,10 +167,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -160,10 +193,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -181,10 +219,15 @@ def bench(): print("test 3: test packet with source pause") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -209,10 +252,15 @@ def bench(): print("test 4: test packet with sink pause") current_test.next = 4 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -229,7 +277,7 @@ def bench(): rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -237,14 +285,23 @@ def bench(): print("test 5: back-to-back packets") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -269,14 +326,23 @@ def bench(): print("test 6: alternate pause source") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -306,14 +372,23 @@ def bench(): print("test 7: alternate pause sink") current_test.next = 7 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -331,11 +406,11 @@ def bench(): rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -343,11 +418,16 @@ def bench(): print("test 8: tuser assert") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=8, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -358,7 +438,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) diff --git a/tb/test_axis_tap.v b/tb/test_axis_tap.v index 11f2d9a3f..8ee6ce3e0 100644 --- a/tb/test_axis_tap.v +++ b/tb/test_axis_tap.v @@ -33,6 +33,16 @@ module test_axis_tap; // Parameters parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; // Inputs reg clk = 0; @@ -40,17 +50,23 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] tap_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] tap_axis_tkeep = 0; reg tap_axis_tvalid = 0; reg tap_axis_tready = 0; reg tap_axis_tlast = 0; -reg tap_axis_tuser = 0; +reg [ID_WIDTH-1:0] tap_axis_tid = 0; +reg [DEST_WIDTH-1:0] tap_axis_tdest = 0; +reg [USER_WIDTH-1:0] tap_axis_tuser = 0; reg output_axis_tready = 0; // Outputs wire [DATA_WIDTH-1:0] output_axis_tdata; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -59,16 +75,22 @@ initial begin rst, current_test, tap_axis_tdata, + tap_axis_tkeep, tap_axis_tvalid, tap_axis_tready, tap_axis_tlast, + tap_axis_tid, + tap_axis_tdest, tap_axis_tuser, output_axis_tready ); $to_myhdl( output_axis_tdata, + output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -78,22 +100,38 @@ initial begin end axis_tap #( - .DATA_WIDTH(DATA_WIDTH) + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK) ) UUT ( .clk(clk), .rst(rst), // AXI tap .tap_axis_tdata(tap_axis_tdata), + .tap_axis_tkeep(tap_axis_tkeep), .tap_axis_tvalid(tap_axis_tvalid), .tap_axis_tready(tap_axis_tready), .tap_axis_tlast(tap_axis_tlast), + .tap_axis_tid(tap_axis_tid), + .tap_axis_tdest(tap_axis_tdest), .tap_axis_tuser(tap_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_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); diff --git a/tb/test_axis_tap_64.py b/tb/test_axis_tap_64.py index bec9f9ba1..31c68cd94 100755 --- a/tb/test_axis_tap_64.py +++ b/tb/test_axis_tap_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_tap_64' -testbench = 'test_%s' % module +module = 'axis_tap' +testbench = 'test_%s_64' % module srcs = [] @@ -44,7 +44,16 @@ def bench(): # Parameters DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 # Inputs clk = Signal(bool(0)) @@ -52,19 +61,23 @@ def bench(): current_test = Signal(intbv(0)[8:]) tap_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - tap_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + tap_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) tap_axis_tvalid = Signal(bool(0)) tap_axis_tready = Signal(bool(1)) tap_axis_tlast = Signal(bool(0)) - tap_axis_tuser = Signal(bool(0)) + tap_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + tap_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + tap_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) output_axis_tready = Signal(bool(0)) # Outputs output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) output_axis_tvalid = Signal(bool(0)) output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -80,6 +93,8 @@ def bench(): tvalid=tap_axis_tvalid, tready=tap_axis_tready, tlast=tap_axis_tlast, + tid=tap_axis_tid, + tdest=tap_axis_tdest, tuser=tap_axis_tuser, pause=source_pause, name='source' @@ -95,6 +110,8 @@ def bench(): tvalid=output_axis_tvalid, tready=output_axis_tready, tlast=output_axis_tlast, + tid=output_axis_tid, + tdest=output_axis_tdest, tuser=output_axis_tuser, pause=sink_pause, name='sink' @@ -115,6 +132,8 @@ def bench(): tap_axis_tvalid=tap_axis_tvalid, tap_axis_tready=tap_axis_tready, tap_axis_tlast=tap_axis_tlast, + tap_axis_tid=tap_axis_tid, + tap_axis_tdest=tap_axis_tdest, tap_axis_tuser=tap_axis_tuser, output_axis_tdata=output_axis_tdata, @@ -122,6 +141,8 @@ def bench(): output_axis_tvalid=output_axis_tvalid, output_axis_tready=output_axis_tready, output_axis_tlast=output_axis_tlast, + output_axis_tid=output_axis_tid, + output_axis_tdest=output_axis_tdest, output_axis_tuser=output_axis_tuser ) @@ -146,10 +167,15 @@ def bench(): print("test 1: test packet") current_test.next = 1 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -167,10 +193,15 @@ def bench(): print("test 2: longer packet") current_test.next = 2 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=2, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -188,10 +219,15 @@ def bench(): print("test 3: test packet with source pause") current_test.next = 3 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=3, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -216,10 +252,15 @@ def bench(): print("test 4: test packet with sink pause") current_test.next = 4 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=4, + dest=1 + ) + source.send(test_frame) yield clk.posedge @@ -236,7 +277,7 @@ def bench(): rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -244,14 +285,23 @@ def bench(): print("test 5: back-to-back packets") current_test.next = 5 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -276,14 +326,23 @@ def bench(): print("test 6: alternate pause source") current_test.next = 6 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -313,14 +372,23 @@ def bench(): print("test 7: alternate pause sink") current_test.next = 7 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=7, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=7, + dest=2 + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -338,11 +406,11 @@ def bench(): rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) @@ -350,11 +418,16 @@ def bench(): print("test 8: tuser assert") current_test.next = 8 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame.user = 1 + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=8, + dest=1, + last_cycle_user=1 + ) + source.send(test_frame) yield clk.posedge @@ -365,7 +438,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame == test_frame - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) diff --git a/tb/test_axis_tap_64.v b/tb/test_axis_tap_64.v index e56b053c8..6149e3ef3 100644 --- a/tb/test_axis_tap_64.v +++ b/tb/test_axis_tap_64.v @@ -27,13 +27,22 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_tap_64 + * Testbench for axis_tap */ module test_axis_tap_64; // Parameters parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; // Inputs reg clk = 0; @@ -41,19 +50,23 @@ reg rst = 0; reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] tap_axis_tdata = 0; -reg [DATA_WIDTH-1:0] tap_axis_tkeep = 0; +reg [KEEP_WIDTH-1:0] tap_axis_tkeep = 0; reg tap_axis_tvalid = 0; reg tap_axis_tready = 0; reg tap_axis_tlast = 0; -reg tap_axis_tuser = 0; +reg [ID_WIDTH-1:0] tap_axis_tid = 0; +reg [DEST_WIDTH-1:0] tap_axis_tdest = 0; +reg [USER_WIDTH-1:0] tap_axis_tuser = 0; reg output_axis_tready = 0; // Outputs wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [DATA_WIDTH-1:0] output_axis_tkeep; +wire [KEEP_WIDTH-1:0] output_axis_tkeep; wire output_axis_tvalid; wire output_axis_tlast; -wire output_axis_tuser; +wire [ID_WIDTH-1:0] output_axis_tid; +wire [DEST_WIDTH-1:0] output_axis_tdest; +wire [USER_WIDTH-1:0] output_axis_tuser; initial begin // myhdl integration @@ -66,6 +79,8 @@ initial begin tap_axis_tvalid, tap_axis_tready, tap_axis_tlast, + tap_axis_tid, + tap_axis_tdest, tap_axis_tuser, output_axis_tready ); @@ -74,6 +89,8 @@ initial begin output_axis_tkeep, output_axis_tvalid, output_axis_tlast, + output_axis_tid, + output_axis_tdest, output_axis_tuser ); @@ -82,9 +99,18 @@ initial begin $dumpvars(0, test_axis_tap_64); end -axis_tap_64 #( +axis_tap #( .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK) ) UUT ( .clk(clk), @@ -95,6 +121,8 @@ UUT ( .tap_axis_tvalid(tap_axis_tvalid), .tap_axis_tready(tap_axis_tready), .tap_axis_tlast(tap_axis_tlast), + .tap_axis_tid(tap_axis_tid), + .tap_axis_tdest(tap_axis_tdest), .tap_axis_tuser(tap_axis_tuser), // AXI output .output_axis_tdata(output_axis_tdata), @@ -102,6 +130,8 @@ UUT ( .output_axis_tvalid(output_axis_tvalid), .output_axis_tready(output_axis_tready), .output_axis_tlast(output_axis_tlast), + .output_axis_tid(output_axis_tid), + .output_axis_tdest(output_axis_tdest), .output_axis_tuser(output_axis_tuser) ); From a1a6d523e3da32e3c7ac9b4a210b28be14c2863a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Nov 2017 00:14:26 -0800 Subject: [PATCH 365/617] Update FIFO instances and testbenches for COBS encoder and decoder --- rtl/axis_cobs_decode.v | 2 +- rtl/axis_cobs_encode.v | 35 +++++++++++++++++++++----- tb/test_axis_cobs_decode.py | 28 ++++++++++----------- tb/test_axis_cobs_encode.py | 12 ++++----- tb/test_axis_cobs_encode_zero_frame.py | 12 ++++----- 5 files changed, 56 insertions(+), 33 deletions(-) diff --git a/rtl/axis_cobs_decode.v b/rtl/axis_cobs_decode.v index 69dbe7927..964bf7fdf 100644 --- a/rtl/axis_cobs_decode.v +++ b/rtl/axis_cobs_decode.v @@ -276,7 +276,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin diff --git a/rtl/axis_cobs_encode.v b/rtl/axis_cobs_encode.v index 0aad5f8c8..5249aba2c 100644 --- a/rtl/axis_cobs_encode.v +++ b/rtl/axis_cobs_encode.v @@ -102,22 +102,34 @@ reg code_fifo_out_tready; axis_fifo #( .ADDR_WIDTH(8), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .LAST_ENABLE(1), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) code_fifo_inst ( .clk(clk), .rst(rst), // AXI input .input_axis_tdata(code_fifo_in_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(code_fifo_in_tvalid), .input_axis_tready(code_fifo_in_tready), .input_axis_tlast(code_fifo_in_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(code_fifo_in_tuser), // AXI output .output_axis_tdata(code_fifo_out_tdata), + .output_axis_tkeep(), .output_axis_tvalid(code_fifo_out_tvalid), .output_axis_tready(code_fifo_out_tready), .output_axis_tlast(code_fifo_out_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(code_fifo_out_tuser) ); @@ -133,22 +145,33 @@ reg data_fifo_out_tready; axis_fifo #( .ADDR_WIDTH(8), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .LAST_ENABLE(1), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(0) ) data_fifo_inst ( .clk(clk), .rst(rst), // AXI input .input_axis_tdata(data_fifo_in_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(data_fifo_in_tvalid), .input_axis_tready(data_fifo_in_tready), .input_axis_tlast(data_fifo_in_tlast), - .input_axis_tuser(1'b0), + .input_axis_tid(0), + .input_axis_tdest(0), + .input_axis_tuser(0), // AXI output .output_axis_tdata(data_fifo_out_tdata), + .output_axis_tkeep(), .output_axis_tvalid(data_fifo_out_tvalid), .output_axis_tready(data_fifo_out_tready), .output_axis_tlast(data_fifo_out_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser() ); @@ -178,7 +201,7 @@ always @* begin if (input_axis_tready & input_axis_tvalid) begin // valid input data - + if (input_axis_tdata == 8'd0 || (input_axis_tlast & input_axis_tuser)) begin // got a zero or propagated error, so store a zero code code_fifo_in_tdata = 8'd1; @@ -224,7 +247,7 @@ always @* begin if (input_axis_tready & input_axis_tvalid) begin // valid input data - + if (input_axis_tdata == 8'd0 || (input_axis_tlast & input_axis_tuser)) begin // got a zero or propagated error, so store the code code_fifo_in_tdata = input_count_reg; @@ -421,7 +444,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py index fe4c5b484..faa131c37 100755 --- a/tb/test_axis_cobs_decode.py +++ b/tb/test_axis_cobs_decode.py @@ -264,7 +264,7 @@ def bench(): assert cobs_decode(enc) == block assert rx_frame.data == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() @@ -292,7 +292,7 @@ def bench(): assert cobs_decode(enc) == block assert rx_frame.data == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() @@ -320,13 +320,13 @@ def bench(): assert cobs_decode(enc) == block assert rx_frame.data == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() @@ -352,13 +352,13 @@ def bench(): assert cobs_decode(enc) == block assert rx_frame.data == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() @@ -372,7 +372,7 @@ def bench(): test_frame2 = axis_ep.AXIStreamFrame(enc+b'\x02') test_frame3 = axis_ep.AXIStreamFrame(enc) - test_frame1.user = 1 + test_frame1.last_cycle_user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -388,17 +388,17 @@ def bench(): rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() @@ -412,7 +412,7 @@ def bench(): test_frame2 = axis_ep.AXIStreamFrame(enc+b'\x02\x00') test_frame3 = axis_ep.AXIStreamFrame(enc+b'\x00') - test_frame1.user = 1 + test_frame1.last_cycle_user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -428,17 +428,17 @@ def bench(): rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py index f3892f89b..3eb7ae8db 100755 --- a/tb/test_axis_cobs_encode.py +++ b/tb/test_axis_cobs_encode.py @@ -265,7 +265,7 @@ def bench(): assert cobs_decode(enc) == block assert rx_frame.data == enc assert cobs_decode(rx_frame.data) == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() @@ -294,14 +294,14 @@ def bench(): assert cobs_decode(enc) == block assert rx_frame.data == enc assert cobs_decode(rx_frame.data) == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc assert cobs_decode(rx_frame.data) == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() @@ -314,7 +314,7 @@ def bench(): test_frame1 = axis_ep.AXIStreamFrame(block) test_frame2 = axis_ep.AXIStreamFrame(block) - test_frame1.user = 1 + test_frame1.last_cycle_user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -330,14 +330,14 @@ def bench(): rx_frame = sink.recv() assert cobs_decode(rx_frame.data) == None - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc assert cobs_decode(rx_frame.data) == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() diff --git a/tb/test_axis_cobs_encode_zero_frame.py b/tb/test_axis_cobs_encode_zero_frame.py index ea1da943e..3f4066dc5 100755 --- a/tb/test_axis_cobs_encode_zero_frame.py +++ b/tb/test_axis_cobs_encode_zero_frame.py @@ -266,7 +266,7 @@ def bench(): assert cobs_decode(enc) == block assert rx_frame.data == enc+b'\x00' assert cobs_decode(rx_frame.data[:-1]) == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() @@ -295,14 +295,14 @@ def bench(): assert cobs_decode(enc) == block assert rx_frame.data == enc+b'\x00' assert cobs_decode(rx_frame.data[:-1]) == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc+b'\x00' assert cobs_decode(rx_frame.data[:-1]) == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() @@ -315,7 +315,7 @@ def bench(): test_frame1 = axis_ep.AXIStreamFrame(block) test_frame2 = axis_ep.AXIStreamFrame(block) - test_frame1.user = 1 + test_frame1.last_cycle_user = 1 for wait in wait_normal, wait_pause_source, wait_pause_sink: source.send(test_frame1) @@ -331,14 +331,14 @@ def bench(): rx_frame = sink.recv() assert cobs_decode(rx_frame.data[:-1]) == None - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == enc+b'\x00' assert cobs_decode(rx_frame.data[:-1]) == block - assert not rx_frame.user[-1] + assert not rx_frame.last_cycle_user assert sink.empty() From ad0e3e1eb54d68fbd14baa9b3445ab5b33568f3c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Nov 2017 00:16:15 -0800 Subject: [PATCH 366/617] Whitespace fixes and testbench update for frame joiner --- rtl/axis_frame_join.py | 16 ++++++++-------- rtl/axis_frame_join_4.v | 6 +++--- tb/test_axis_frame_join_4.py | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index fb8101ade..c15c099a5 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -33,11 +33,11 @@ def generate(ports=4, name=None, output=None): print("Opening file '{0}'...".format(output)) output_file = open(output, 'w') - + print("Generating {0} port AXI Stream frame joiner {1}...".format(ports, name)) - + select_width = int(math.ceil(math.log(ports, 2))) - + t = Template(u"""/* Copyright (c) 2014-2017 Alex Forencich @@ -192,7 +192,7 @@ always @* begin // next cycle if started will send data, so enable input input_0_axis_tready_next = output_axis_tready_int_early; end - + if (input_0_axis_tvalid) begin // input 0 valid; start transferring data if (TAG_ENABLE) begin @@ -284,7 +284,7 @@ always @* begin end end else begin state_next = STATE_TRANSFER; - end + end end endcase end @@ -347,7 +347,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin @@ -399,14 +399,14 @@ end endmodule """) - + output_file.write(t.render( n=ports, w=select_width, name=name, ports=range(ports) )) - + print("Done") if __name__ == "__main__": diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index 30ab9f4d6..907ae74d3 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -191,7 +191,7 @@ always @* begin // next cycle if started will send data, so enable input input_0_axis_tready_next = output_axis_tready_int_early; end - + if (input_0_axis_tvalid) begin // input 0 valid; start transferring data if (TAG_ENABLE) begin @@ -286,7 +286,7 @@ always @* begin end end else begin state_next = STATE_TRANSFER; - end + end end endcase end @@ -352,7 +352,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index 5290df47b..aaafbca88 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -445,7 +445,7 @@ def bench(): test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - test_frame_0.user = 1 + test_frame_0.last_cycle_user = 1 source_0.send(test_frame_0) source_1.send(test_frame_1) source_2.send(test_frame_2) @@ -459,7 +459,7 @@ def bench(): rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user yield delay(100) From b00eaf4d3ce6564c8c1e1bbe953ea12a3d5c2839 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Nov 2017 00:17:42 -0800 Subject: [PATCH 367/617] Add tkeep signal and update testbench for stat counter --- rtl/axis_stat_counter.v | 35 ++++++----- tb/test_axis_stat_counter.py | 116 ++++++++++++++++++++++------------- 2 files changed, 92 insertions(+), 59 deletions(-) diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index 43f5c8a62..5f0b5c678 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -32,6 +32,7 @@ THE SOFTWARE. module axis_stat_counter # ( parameter DATA_WIDTH = 64, + parameter KEEP_ENABLE = (DATA_WIDTH>8), parameter KEEP_WIDTH = (DATA_WIDTH/8), parameter TAG_ENABLE = 1, parameter TAG_WIDTH = 16, @@ -57,22 +58,22 @@ module axis_stat_counter # /* * AXI status data output */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [7:0] output_axis_tdata, + output wire output_axis_tvalid, + input wire output_axis_tready, + output wire output_axis_tlast, + output wire output_axis_tuser, /* * Configuration */ - input wire [TAG_WIDTH-1:0] tag, - input wire trigger, + input wire [TAG_WIDTH-1:0] tag, + input wire trigger, /* * Status */ - output wire busy + output wire busy ); localparam TAG_BYTE_WIDTH = (TAG_WIDTH + 7) / 8; @@ -213,18 +214,22 @@ always @* begin // stats collection // increment tick count by number of words that can be transferred per cycle - tick_count_next = tick_count_next + KEEP_WIDTH; + tick_count_next = tick_count_next + (KEEP_ENABLE ? KEEP_WIDTH : 1); if (monitor_axis_tready & monitor_axis_tvalid) begin // valid transfer cycle // increment byte count by number of words transferred - bit_cnt = 0; - for (i = 0; i <= KEEP_WIDTH; i = i + 1) begin - //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; - if (monitor_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) bit_cnt = i; + if (KEEP_ENABLE) begin + bit_cnt = 0; + for (i = 0; i <= KEEP_WIDTH; i = i + 1) begin + //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; + if (monitor_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) bit_cnt = i; + end + byte_count_next = byte_count_next + bit_cnt; + end else begin + byte_count_next = byte_count_next + 1; end - byte_count_next = byte_count_next + bit_cnt; // count frames if (monitor_axis_tlast) begin @@ -298,7 +303,7 @@ always @* begin store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - + if (output_axis_tready_int_reg) begin // input is ready if (output_axis_tready | ~output_axis_tvalid_reg) begin diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index 6f0d5517b..fe30617fd 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -268,10 +268,13 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + source.send(test_frame) yield clk.posedge @@ -320,10 +323,13 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)) + ) + source.send(test_frame) yield clk.posedge @@ -372,10 +378,13 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(256))) + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)) + ) + source.send(test_frame) yield clk.posedge @@ -438,14 +447,19 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -495,14 +509,19 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -552,14 +571,19 @@ def bench(): yield clk.posedge trigger.next = 0 - test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') - test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + source.send(test_frame1) source.send(test_frame2) yield clk.posedge @@ -613,10 +637,12 @@ def bench(): test_frame = [] for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(lens[i])))) + test_frame.append(axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i]))) + ) for f in test_frame: source.send(f) @@ -671,10 +697,12 @@ def bench(): test_frame = [] for i in range(len(lens)): - test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + - bytearray(range(lens[i])))) + test_frame.append(axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(lens[i]))) + ) for f in test_frame: source.send(f) From 4ec4c901e8f82be74e471e3b4464b4e0fb6b8e57 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Nov 2017 00:18:09 -0800 Subject: [PATCH 368/617] Whitespace fixes --- rtl/arbiter.v | 2 +- rtl/axis_ll_bridge.v | 4 ++-- rtl/ll_axis_bridge.v | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rtl/arbiter.v b/rtl/arbiter.v index 972218dde..24ae74c61 100644 --- a/rtl/arbiter.v +++ b/rtl/arbiter.v @@ -42,7 +42,7 @@ module arbiter # ( input wire clk, input wire rst, - + input wire [PORTS-1:0] request, input wire [PORTS-1:0] acknowledge, diff --git a/rtl/axis_ll_bridge.v b/rtl/axis_ll_bridge.v index 6f67892e9..410081e89 100644 --- a/rtl/axis_ll_bridge.v +++ b/rtl/axis_ll_bridge.v @@ -36,7 +36,7 @@ module axis_ll_bridge # ( input wire clk, input wire rst, - + /* * AXI input */ @@ -44,7 +44,7 @@ module axis_ll_bridge # input wire axis_tvalid, output wire axis_tready, input wire axis_tlast, - + /* * LocalLink output */ diff --git a/rtl/ll_axis_bridge.v b/rtl/ll_axis_bridge.v index 2c5f326ec..7b2090b84 100644 --- a/rtl/ll_axis_bridge.v +++ b/rtl/ll_axis_bridge.v @@ -36,7 +36,7 @@ module ll_axis_bridge # ( input wire clk, input wire rst, - + /* * LocalLink input */ @@ -45,7 +45,7 @@ module ll_axis_bridge # input wire ll_eof_in_n, input wire ll_src_rdy_in_n, output wire ll_dst_rdy_out_n, - + /* * AXI output */ From 93688dc88e7d5ae63006ed10e72250eb2a2def8b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Nov 2017 00:21:15 -0800 Subject: [PATCH 369/617] Update readme --- README.md | 132 ++++++++---------------------------------------------- 1 file changed, 19 insertions(+), 113 deletions(-) diff --git a/README.md b/README.md index 8dda8fb13..25ea2c7bc 100644 --- a/README.md +++ b/README.md @@ -34,33 +34,16 @@ Supports priority and round-robin arbitration. Can be generated with arbitrary port counts with axis_arb_mux.py. -### axis_arb_mux_64_N module - -Frame-aware AXI stream arbitrated muliplexer with tkeep signal and -parametrizable data width. Supports priority and round-robin arbitration. - -Can be generated with arbitrary port counts with axis_arb_mux_64.py. - ### axis_async_fifo module Basic word-based asynchronous FIFO with parametrizable data width and depth. Supports power of two depths only. -### axis_async_fifo_64 module - -Basic word-based asynchronous FIFO with tkeep signal and parametrizable data -width and depth. Supports power of two depths only. - ### axis_async_frame_fifo module Basic frame-based asynchronous FIFO with parametrizable data width and depth. Supports power of two depths only. -### axis_async_fifo_64 module - -Basic frame-based asynchronous FIFO with tkeep signal and parametrizable data -width and depth. Supports power of two depths only. - ### axis_crosspoint module Basic crosspoint switch. tready signal not supported. Parametrizable data @@ -68,46 +51,22 @@ width. Can be generated with arbitrary port counts with axis_crosspoint.py. -### axis_crosspoint_64 module - -Basic crosspoint switch with tkeep. tready signal not supported. -Parametrizable data width. - -Can be generated with arbitrary port counts with axis_crosspoint_64.py. - ### axis_demux_N module Frame-aware AXI stream demuliplexer with parametrizable data width. Can be generated with arbitrary port counts with axis_demux.py. -### axis_demux_64_N module - -Frame-aware AXI stream demuliplexer with tkeep signal and parametrizable data -width. - -Can be generated with arbitrary port counts with axis_demux_64.py. - ### axis_fifo module Basic word-based synchronous FIFO with parametrizable data width and depth. Supports power of two depths only. -### axis_fifo_64 module - -Basic word-based synchronous FIFO with tkeep signal and parametrizable data -width and depth. Supports power of two depths only. - ### axis_frame_fifo module Basic frame-based synchronous FIFO with parametrizable data width and depth. Supports power of two depths only. -### axis_frame_fifo_64 module - -Basic frame-based synchronous FIFO with tkeep signal and parametrizable data -width and depth. Supports power of two depths only. - ### axis_frame_join_N module Frame joiner with optional tag. 8 bit data path only. @@ -129,14 +88,6 @@ current lengths as well as whether the packet was truncated or padded. FIFOs are used so that the status information can be read before the packet itself. Length limits are configurable at run time. -### axis_frame_length_adjust_fifo_64 module - -Frame length adjuster module with FIFO. Truncates or pads frames as necessary -to meet the specified minimum and maximum length. Reports the original and -current lengths as well as whether the packet was truncated or padded. FIFOs -are used so that the status information can be read before the packet itself. -Length limits are configurable at run time. Packet FIFO has a tkeep signal. - ### axis_ll_bridge module AXI stream to LocalLink bridge. @@ -147,13 +98,6 @@ Frame-aware AXI stream muliplexer with parametrizable data width. Can be generated with arbitrary port counts with axis_mux.py. -### axis_mux_64_N module - -Frame-aware AXI stream muliplexer with tkeep signal and parametrizable data -width. - -Can be generated with arbitrary port counts with axis_mux_64.py. - ### axis_rate_limit module Fractional rate limiter, supports word and frame modes. Inserts wait states @@ -161,43 +105,20 @@ to limit data rate to specified ratio. Frame mode inserts wait states at end of frames, word mode ignores frames and inserts wait states at any point. Parametrizable data width. Rate and mode are configurable at run time. -### axis_rate_limit_64 module - -Fractional rate limiter with tkeep signal, supports word and frame modes. -Inserts wait states to limit data rate to specified ratio. Frame mode inserts -wait states at end of frames, word mode ignores frames and inserts wait states -at any point. Parametrizable data width. Rate and mode are configurable at -run time. - ### axis_register module Datapath register. Use to improve timing for long routes. -### axis_register_64 module - -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 Statistics counter module. Counts bytes and frames passing through monitored @@ -211,24 +132,12 @@ Frame-aware AXI stream switch with parametrizable data width. Can be generated with arbitrary port counts with axis_switch.py. -### axis_switch_64_NxN module - -Frame-aware AXI stream switch with tkeep signal and parametrizable data width. - -Can be generated with arbitrary port counts with axis_mux_64.py. - ### axis_tap module AXI stream tap module. Used to make a copy of an AXI stream bus without affecting the bus. Back-pressure on the output results in truncated frames with tuser set. -### axis_tap_64 module - -AXI stream tap module with tkeep signal. Used to make a copy of an AXI stream -bus without affecting the bus. Back-pressure on the output results in -truncated frames with tuser set. - ### ll_axis_bridge module LocalLink to AXI stream bridge. @@ -240,11 +149,28 @@ Parametrizable priority encoder. ### Common signals tdata : Data (width generally DATA_WIDTH) - tkeep : Data word valid (width generally KEEP_WIDTH, present on _64 modules) + tkeep : Data word valid (width generally KEEP_WIDTH) tvalid : Data valid tready : Sink ready tlast : End-of-frame - tuser : Bad frame (valid with tlast & tvalid) + tid : Identifier tag (width generally ID_WIDTH) + tdest : Destination tag (width generally DEST_WIDTH) + tuser : User sideband signals (width generally USER_WIDTH) + +### Common parameters + + DATA_WIDTH : width of tdata signal + KEEP_ENABLE : enable tkeep signal (default DATA_WIDTH>8) + KEEP_WIDTH : width of tkeep signal (default DATA_WIDTH/8) + LAST_ENABLE : enable tlast signal + ID_ENABLE : enable tid signal + ID_WIDTH : width of tid signal + DEST_ENABLE : enable tdest signal + DEST_WIDTH : width of tdest signal + USER_ENABLE : enable tuser signal + USER_WIDTH : width of tuser signal + USER_BAD_FRAME_VALUE : value of tuser indicating bad frame + USER_BAD_FRAME_MASK : bitmask for tuser bad frame indication ### Source Files @@ -252,49 +178,29 @@ Parametrizable priority encoder. axis_adapter.v : Parametrizable bus width adapter axis_arb_mux.py : Arbitrated multiplexer generator axis_arb_mux_4.v : 4 port arbitrated multiplexer - axis_arb_mux_64.py : Arbitrated multiplexer generator (64 bit) - axis_arb_mux_64_4.v : 4 port arbitrated multiplexer (64 bit) axis_async_fifo.v : Asynchronous FIFO - axis_async_fifo_64.v : Asynchronous FIFO (64 bit) axis_async_frame_fifo.v : Asynchronous frame FIFO - axis_async_frame_fifo_64.v : Asynchronous frame FIFO (64 bit) axis_crosspoint.py : Crosspoint switch generator axis_crosspoint_4x4.v : 4x4 crosspoint switch - axis_crosspoint_64.py : Crosspoint switch generator (64 bit) - axis_crosspoint_64_4x4.v : 4x4 crosspoint switch (64 bit) axis_demux.py : Demultiplexer generator axis_demux_4.v : 4 port demultiplexer - axis_demux_64.py : Demultiplexer generator (64 bit) - axis_demux_64_4.v : 4 port demultiplexer (64 bit) axis_fifo.v : Synchronous FIFO - axis_fifo_64.v : Synchronous FIFO (64 bit) axis_frame_fifo.v : Synchronous frame FIFO - axis_frame_fifo_64.v : Synchronous frame FIFO (64 bit) axis_frame_join.py : Frame joiner generator axis_frame_join_4.v : 4 port frame joiner axis_frame_length_adjust.v : Frame length adjuster axis_frame_length_adjust_fifo.v : Frame length adjuster with FIFO - axis_frame_length_adjust_fifo_64.v : Frame length adjuster with FIFO (64 bit) axis_ll_bridge.v : AXI stream to LocalLink bridge axis_mux.py : Multiplexer generator axis_mux_4.v : 4 port multiplexer - axis_mux_64.py : Multiplexer generator (64 bit) - axis_mux_64_4.v : 4 port multiplexer (64 bit) axis_rate_limit.v : Fractional rate limiter - axis_rate_limit_64.v : Fractional rate limiter (64 bit) axis_register.v : AXI Stream register - axis_register_64.v : AXI Stream register (64 bit) axis_srl_fifo.v : SRL-based FIFO - axis_srl_fifo_64.v : SRL-based FIFO (64 bit) axis_srl_register.v : SRL-based register - axis_srl_register_64.v : SRL-based register (64 bit) axis_switch.py : AXI stream switch generator axis_switch_4x4.v : 4x4 port AXI stream switch - axis_switch_64.py : AXI stream switch generator (64 bit) - axis_switch_64_4x4.v : 4x4 port AXI stream switch (64 bit) axis_stat_counter.v : Statistics counter axis_tap.v : AXI stream tap - axis_tap_64.v : AXI stream tap (64 bit) ll_axis_bridge.v : LocalLink to AXI stream bridge priority_encoder.v : Parametrizable priority encoder From c33985d7ba81715adccc7d521c9c54f28cc194da Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 21 Nov 2017 08:54:21 -0800 Subject: [PATCH 370/617] Remove extraneous parameter --- tb/test_axis_async_frame_fifo_64.v | 1 - 1 file changed, 1 deletion(-) diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index 6a568141e..4f252b045 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -121,7 +121,6 @@ axis_async_frame_fifo #( .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), - .LAST_ENABLE(LAST_ENABLE), .ID_ENABLE(ID_ENABLE), .ID_WIDTH(ID_WIDTH), .DEST_ENABLE(DEST_ENABLE), From bd27156f356e3884f458c0e534fca6aa52a2ead7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 26 Feb 2018 00:08:08 -0800 Subject: [PATCH 371/617] AXI stream updates --- example/ATLYS/fpga/rtl/fpga_core.v | 13 +++++++- example/DE5-Net/fpga/fpga/Makefile | 4 +-- example/DE5-Net/fpga/rtl/fpga_core.v | 14 +++++++-- example/DE5-Net/fpga/tb/test_fpga_core.py | 4 +-- example/HXT100G/fpga/fpga/Makefile | 4 +-- example/HXT100G/fpga/rtl/fpga_core.v | 14 +++++++-- example/HXT100G/fpga/tb/test_fpga_core.py | 4 +-- example/ML605/fpga_gmii/rtl/fpga_core.v | 13 +++++++- example/ML605/fpga_rgmii/rtl/fpga_core.v | 13 +++++++- example/ML605/fpga_sgmii/rtl/fpga_core.v | 13 +++++++- example/NexysVideo/fpga/rtl/fpga_core.v | 13 +++++++- example/VCU108/fpga_10g/fpga/Makefile | 4 +-- example/VCU108/fpga_10g/rtl/fpga_core.v | 27 +++++++++++++++-- example/VCU108/fpga_10g/tb/test_fpga_core.py | 4 +-- example/VCU108/fpga_1g/rtl/fpga_core.v | 13 +++++++- rtl/eth_mac_10g_fifo.v | 32 ++++++++++++++++++-- rtl/eth_mac_1g_fifo.v | 26 ++++++++++++++++ rtl/eth_mac_1g_gmii_fifo.v | 26 ++++++++++++++++ rtl/eth_mac_1g_rgmii_fifo.v | 26 ++++++++++++++++ rtl/udp_checksum_gen.v | 14 ++++++++- rtl/udp_checksum_gen_64.v | 15 +++++++-- tb/test_eth_mac_10g_fifo.py | 2 +- tb/test_eth_mac_10g_rx.py | 2 +- tb/test_eth_mac_10g_tx.py | 2 +- tb/test_eth_mac_1g_rx.py | 2 +- tb/test_eth_mac_1g_tx.py | 2 +- tb/test_udp_64.py | 2 +- tb/test_udp_checksum_gen_64.py | 2 +- tb/test_udp_complete_64.py | 2 +- 29 files changed, 272 insertions(+), 40 deletions(-) diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index 0cab0ddef..12c779c15 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -545,7 +545,12 @@ udp_complete_inst ( axis_fifo #( .ADDR_WIDTH(12), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) udp_payload_fifo ( .clk(clk), @@ -553,16 +558,22 @@ udp_payload_fifo ( // AXI input .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(rx_fifo_udp_payload_tvalid), .input_axis_tready(rx_fifo_udp_payload_tready), .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(), .output_axis_tvalid(tx_fifo_udp_payload_tvalid), .output_axis_tready(tx_fifo_udp_payload_tready), .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(tx_fifo_udp_payload_tuser) ); diff --git a/example/DE5-Net/fpga/fpga/Makefile b/example/DE5-Net/fpga/fpga/Makefile index d0eecc4e9..61d619cc7 100644 --- a/example/DE5-Net/fpga/fpga/Makefile +++ b/example/DE5-Net/fpga/fpga/Makefile @@ -40,8 +40,8 @@ SYN_FILES += lib/eth/rtl/xgmii_interleave.v SYN_FILES += lib/eth/rtl/xgmii_deinterleave.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo_64.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v SYN_FILES += cores/phy/phy.qip SYN_FILES += cores/phy_reconfig/phy_reconfig.qip diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index f3922f5a5..81686fd5c 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -564,9 +564,15 @@ udp_complete_inst ( .clear_arp_cache(1'b0) ); -axis_fifo_64 #( +axis_fifo #( .ADDR_WIDTH(10), - .DATA_WIDTH(64) + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(64), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) udp_payload_fifo ( .clk(clk), @@ -578,6 +584,8 @@ udp_payload_fifo ( .input_axis_tvalid(rx_fifo_udp_payload_tvalid), .input_axis_tready(rx_fifo_udp_payload_tready), .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output @@ -586,6 +594,8 @@ udp_payload_fifo ( .output_axis_tvalid(tx_fifo_udp_payload_tvalid), .output_axis_tready(tx_fifo_udp_payload_tready), .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(tx_fifo_udp_payload_tuser) ); diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index 978de24fe..ef06b7505 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -63,8 +63,8 @@ srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") srcs.append("../lib/eth/rtl/eth_mux_64_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_fifo_64.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/HXT100G/fpga/fpga/Makefile b/example/HXT100G/fpga/fpga/Makefile index 533df0179..5fb7cef84 100644 --- a/example/HXT100G/fpga/fpga/Makefile +++ b/example/HXT100G/fpga/fpga/Makefile @@ -45,8 +45,8 @@ SYN_FILES += lib/eth/rtl/xgmii_interleave.v SYN_FILES += lib/eth/rtl/xgmii_deinterleave.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo_64.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6.v SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6/example_design/ten_gig_eth_pcs_pma_v2_6_management_arbiter.v SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_quad.v diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v index c4497aea1..c1ec2ecc0 100644 --- a/example/HXT100G/fpga/rtl/fpga_core.v +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -708,9 +708,15 @@ udp_complete_inst ( .clear_arp_cache(1'b0) ); -axis_fifo_64 #( +axis_fifo #( .ADDR_WIDTH(10), - .DATA_WIDTH(64) + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(64), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) udp_payload_fifo ( .clk(clk), @@ -722,6 +728,8 @@ udp_payload_fifo ( .input_axis_tvalid(rx_fifo_udp_payload_tvalid), .input_axis_tready(rx_fifo_udp_payload_tready), .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output @@ -730,6 +738,8 @@ udp_payload_fifo ( .output_axis_tvalid(tx_fifo_udp_payload_tvalid), .output_axis_tready(tx_fifo_udp_payload_tready), .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(tx_fifo_udp_payload_tuser) ); diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index 8df1f78e3..01d91209e 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -63,8 +63,8 @@ srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") srcs.append("../lib/eth/rtl/eth_mux_64_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_fifo_64.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/ML605/fpga_gmii/rtl/fpga_core.v b/example/ML605/fpga_gmii/rtl/fpga_core.v index fc76a94c6..37a1721bd 100644 --- a/example/ML605/fpga_gmii/rtl/fpga_core.v +++ b/example/ML605/fpga_gmii/rtl/fpga_core.v @@ -558,7 +558,12 @@ udp_complete_inst ( axis_fifo #( .ADDR_WIDTH(12), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) udp_payload_fifo ( .clk(clk_125mhz), @@ -566,16 +571,22 @@ udp_payload_fifo ( // AXI input .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(rx_fifo_udp_payload_tvalid), .input_axis_tready(rx_fifo_udp_payload_tready), .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(), .output_axis_tvalid(tx_fifo_udp_payload_tvalid), .output_axis_tready(tx_fifo_udp_payload_tready), .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(tx_fifo_udp_payload_tuser) ); diff --git a/example/ML605/fpga_rgmii/rtl/fpga_core.v b/example/ML605/fpga_rgmii/rtl/fpga_core.v index 392e5d52f..425f92b62 100644 --- a/example/ML605/fpga_rgmii/rtl/fpga_core.v +++ b/example/ML605/fpga_rgmii/rtl/fpga_core.v @@ -555,7 +555,12 @@ udp_complete_inst ( axis_fifo #( .ADDR_WIDTH(12), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) udp_payload_fifo ( .clk(clk_125mhz), @@ -563,16 +568,22 @@ udp_payload_fifo ( // AXI input .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(rx_fifo_udp_payload_tvalid), .input_axis_tready(rx_fifo_udp_payload_tready), .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(), .output_axis_tvalid(tx_fifo_udp_payload_tvalid), .output_axis_tready(tx_fifo_udp_payload_tready), .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(tx_fifo_udp_payload_tuser) ); diff --git a/example/ML605/fpga_sgmii/rtl/fpga_core.v b/example/ML605/fpga_sgmii/rtl/fpga_core.v index 9c3ff482c..17bc74a67 100644 --- a/example/ML605/fpga_sgmii/rtl/fpga_core.v +++ b/example/ML605/fpga_sgmii/rtl/fpga_core.v @@ -555,7 +555,12 @@ udp_complete_inst ( axis_fifo #( .ADDR_WIDTH(12), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) udp_payload_fifo ( .clk(clk_125mhz), @@ -563,16 +568,22 @@ udp_payload_fifo ( // AXI input .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(rx_fifo_udp_payload_tvalid), .input_axis_tready(rx_fifo_udp_payload_tready), .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(), .output_axis_tvalid(tx_fifo_udp_payload_tvalid), .output_axis_tready(tx_fifo_udp_payload_tready), .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(tx_fifo_udp_payload_tuser) ); diff --git a/example/NexysVideo/fpga/rtl/fpga_core.v b/example/NexysVideo/fpga/rtl/fpga_core.v index b333f246a..7cf1eada8 100644 --- a/example/NexysVideo/fpga/rtl/fpga_core.v +++ b/example/NexysVideo/fpga/rtl/fpga_core.v @@ -544,7 +544,12 @@ udp_complete_inst ( axis_fifo #( .ADDR_WIDTH(12), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) udp_payload_fifo ( .clk(clk), @@ -552,16 +557,22 @@ udp_payload_fifo ( // AXI input .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(rx_fifo_udp_payload_tvalid), .input_axis_tready(rx_fifo_udp_payload_tready), .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(), .output_axis_tvalid(tx_fifo_udp_payload_tvalid), .output_axis_tready(tx_fifo_udp_payload_tready), .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(tx_fifo_udp_payload_tuser) ); diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index cfb2bb486..fd4c7c93b 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -44,10 +44,8 @@ SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_adapter.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo_64.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_switch_64_4x4.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_switch_4x4.v SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v # XDC files XDC_FILES = fpga.xdc diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index 91bdb3570..b497bbc73 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -562,10 +562,13 @@ always @* begin end end -axis_switch_64_4x4 #( +axis_switch_4x4 #( .DATA_WIDTH(64), .KEEP_WIDTH(8), + .ID_ENABLE(0), .DEST_WIDTH(2), + .USER_ENABLE(1), + .USER_WIDTH(1), .OUT_0_BASE(0), .OUT_0_TOP(0), .OUT_0_CONNECT(4'b1111), @@ -590,6 +593,7 @@ axis_switch_inst ( .input_0_axis_tvalid(mac_rx_axis_tvalid), .input_0_axis_tready(mac_rx_axis_tready), .input_0_axis_tlast(mac_rx_axis_tlast), + .input_0_axis_tid(0), .input_0_axis_tdest(mac_rx_tdest), .input_0_axis_tuser(mac_rx_axis_tuser), .input_1_axis_tdata(tx_axis_tdata), @@ -597,6 +601,7 @@ axis_switch_inst ( .input_1_axis_tvalid(tx_axis_tvalid), .input_1_axis_tready(tx_axis_tready), .input_1_axis_tlast(tx_axis_tlast), + .input_1_axis_tid(0), .input_1_axis_tdest(tx_tdest), .input_1_axis_tuser(tx_axis_tuser), .input_2_axis_tdata(gig_rx_axis_tdata_64), @@ -604,6 +609,7 @@ axis_switch_inst ( .input_2_axis_tvalid(gig_rx_axis_tvalid_64), .input_2_axis_tready(gig_rx_axis_tready_64), .input_2_axis_tlast(gig_rx_axis_tlast_64), + .input_2_axis_tid(0), .input_2_axis_tdest(gig_rx_tdest), .input_2_axis_tuser(gig_rx_axis_tuser_64), .input_3_axis_tdata(64'd0), @@ -611,6 +617,7 @@ axis_switch_inst ( .input_3_axis_tvalid(1'b0), .input_3_axis_tready(), .input_3_axis_tlast(1'b0), + .input_3_axis_tid(0), .input_3_axis_tdest(2'd0), .input_3_axis_tuser(1'b0), // AXI outputs @@ -619,6 +626,7 @@ axis_switch_inst ( .output_0_axis_tvalid(mac_tx_axis_tvalid), .output_0_axis_tready(mac_tx_axis_tready), .output_0_axis_tlast(mac_tx_axis_tlast), + .output_0_axis_tid(), .output_0_axis_tdest(), .output_0_axis_tuser(mac_tx_axis_tuser), .output_1_axis_tdata(rx_axis_tdata), @@ -626,6 +634,7 @@ axis_switch_inst ( .output_1_axis_tvalid(rx_axis_tvalid), .output_1_axis_tready(rx_axis_tready), .output_1_axis_tlast(rx_axis_tlast), + .output_1_axis_tid(), .output_1_axis_tdest(), .output_1_axis_tuser(rx_axis_tuser), .output_2_axis_tdata(gig_tx_axis_tdata_64), @@ -633,6 +642,7 @@ axis_switch_inst ( .output_2_axis_tvalid(gig_tx_axis_tvalid_64), .output_2_axis_tready(gig_tx_axis_tready_64), .output_2_axis_tlast(gig_tx_axis_tlast_64), + .output_2_axis_tid(), .output_2_axis_tdest(), .output_2_axis_tuser(gig_tx_axis_tuser_64), .output_3_axis_tdata(), @@ -640,6 +650,7 @@ axis_switch_inst ( .output_3_axis_tvalid(), .output_3_axis_tready(1'b1), .output_3_axis_tlast(), + .output_3_axis_tid(), .output_3_axis_tdest(), .output_3_axis_tuser() ); @@ -837,9 +848,15 @@ udp_complete_inst ( .clear_arp_cache(1'b0) ); -axis_fifo_64 #( +axis_fifo #( .ADDR_WIDTH(10), - .DATA_WIDTH(64) + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(64), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) udp_payload_fifo ( .clk(clk), @@ -851,6 +868,8 @@ udp_payload_fifo ( .input_axis_tvalid(rx_fifo_udp_payload_tvalid), .input_axis_tready(rx_fifo_udp_payload_tready), .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output @@ -859,6 +878,8 @@ udp_payload_fifo ( .output_axis_tvalid(tx_fifo_udp_payload_tvalid), .output_axis_tready(tx_fifo_udp_payload_tready), .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(tx_fifo_udp_payload_tuser) ); diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index 6436e9da1..5a370e32b 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -72,10 +72,8 @@ srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_adapter.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_fifo_64.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_switch_64_4x4.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_switch_4x4.v") srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v index 08e66a651..8e21f12b6 100644 --- a/example/VCU108/fpga_1g/rtl/fpga_core.v +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -546,7 +546,12 @@ udp_complete_inst ( axis_fifo #( .ADDR_WIDTH(12), - .DATA_WIDTH(8) + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) udp_payload_fifo ( .clk(clk), @@ -554,16 +559,22 @@ udp_payload_fifo ( // AXI input .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(rx_fifo_udp_payload_tvalid), .input_axis_tready(rx_fifo_udp_payload_tready), .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(), .output_axis_tvalid(tx_fifo_udp_payload_tvalid), .output_axis_tready(tx_fifo_udp_payload_tready), .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(tx_fifo_udp_payload_tuser) ); diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 107480b84..aa5f8e31f 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -166,9 +166,18 @@ eth_mac_10g_inst ( .ifg_delay(ifg_delay) ); -axis_async_frame_fifo_64 #( +axis_async_frame_fifo #( .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(8), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(1), .DROP_WHEN_FULL(0) ) tx_fifo ( @@ -181,6 +190,8 @@ tx_fifo ( .input_axis_tvalid(tx_axis_tvalid), .input_axis_tready(tx_axis_tready), .input_axis_tlast(tx_axis_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(tx_axis_tuser), // AXI output .output_clk(tx_clk), @@ -189,6 +200,9 @@ tx_fifo ( .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), .output_axis_tlast(tx_fifo_axis_tlast), + .output_axis_tid(), + .output_axis_tdest(), + .output_axis_tuser(), // Status .input_status_overflow(tx_fifo_overflow), .input_status_bad_frame(tx_fifo_bad_frame), @@ -200,9 +214,18 @@ tx_fifo ( assign tx_fifo_axis_tuser = 1'b0; -axis_async_frame_fifo_64 #( +axis_async_frame_fifo #( .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(8), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(1), .DROP_WHEN_FULL(1) ) rx_fifo ( @@ -215,6 +238,8 @@ rx_fifo ( .input_axis_tvalid(rx_fifo_axis_tvalid), .input_axis_tready(), .input_axis_tlast(rx_fifo_axis_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_axis_tuser), // AXI output .output_clk(logic_clk), @@ -223,6 +248,9 @@ rx_fifo ( .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), .output_axis_tlast(rx_axis_tlast), + .output_axis_tid(), + .output_axis_tdest(), + .output_axis_tuser(), // Status .input_status_overflow(), .input_status_bad_frame(), diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index b06ad34f3..f26507637 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -177,6 +177,14 @@ eth_mac_1g_inst ( axis_async_frame_fifo #( .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(1), .DROP_WHEN_FULL(0) ) tx_fifo ( @@ -188,6 +196,8 @@ tx_fifo ( .input_axis_tvalid(tx_axis_tvalid), .input_axis_tready(tx_axis_tready), .input_axis_tlast(tx_axis_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(tx_axis_tuser), // AXI output .output_clk(tx_clk), @@ -195,6 +205,9 @@ tx_fifo ( .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), .output_axis_tlast(tx_fifo_axis_tlast), + .output_axis_tid(), + .output_axis_tdest(), + .output_axis_tuser(), // Status .input_status_overflow(tx_fifo_overflow), .input_status_bad_frame(tx_fifo_bad_frame), @@ -209,6 +222,14 @@ assign tx_fifo_axis_tuser = 1'b0; axis_async_frame_fifo #( .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(1), .DROP_WHEN_FULL(1) ) rx_fifo ( @@ -220,6 +241,8 @@ rx_fifo ( .input_axis_tvalid(rx_fifo_axis_tvalid), .input_axis_tready(), .input_axis_tlast(rx_fifo_axis_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_axis_tuser), // AXI output .output_clk(logic_clk), @@ -227,6 +250,9 @@ rx_fifo ( .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), .output_axis_tlast(rx_axis_tlast), + .output_axis_tid(), + .output_axis_tdest(), + .output_axis_tuser(), // Status .input_status_overflow(), .input_status_bad_frame(), diff --git a/rtl/eth_mac_1g_gmii_fifo.v b/rtl/eth_mac_1g_gmii_fifo.v index e70690a8c..f964a01a3 100644 --- a/rtl/eth_mac_1g_gmii_fifo.v +++ b/rtl/eth_mac_1g_gmii_fifo.v @@ -204,6 +204,14 @@ eth_mac_1g_gmii_inst ( axis_async_frame_fifo #( .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(1), .DROP_WHEN_FULL(0) ) tx_fifo ( @@ -215,6 +223,8 @@ tx_fifo ( .input_axis_tvalid(tx_axis_tvalid), .input_axis_tready(tx_axis_tready), .input_axis_tlast(tx_axis_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(tx_axis_tuser), // AXI output .output_clk(tx_clk), @@ -222,6 +232,9 @@ tx_fifo ( .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), .output_axis_tlast(tx_fifo_axis_tlast), + .output_axis_tid(), + .output_axis_tdest(), + .output_axis_tuser(), // Status .input_status_overflow(tx_fifo_overflow), .input_status_bad_frame(tx_fifo_bad_frame), @@ -236,6 +249,14 @@ assign tx_fifo_axis_tuser = 1'b0; axis_async_frame_fifo #( .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(1), .DROP_WHEN_FULL(1) ) rx_fifo ( @@ -247,6 +268,8 @@ rx_fifo ( .input_axis_tvalid(rx_fifo_axis_tvalid), .input_axis_tready(), .input_axis_tlast(rx_fifo_axis_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_axis_tuser), // AXI output .output_clk(logic_clk), @@ -254,6 +277,9 @@ rx_fifo ( .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), .output_axis_tlast(rx_axis_tlast), + .output_axis_tid(), + .output_axis_tdest(), + .output_axis_tuser(), // Status .input_status_overflow(), .input_status_bad_frame(), diff --git a/rtl/eth_mac_1g_rgmii_fifo.v b/rtl/eth_mac_1g_rgmii_fifo.v index 15a1acf97..599ef9627 100644 --- a/rtl/eth_mac_1g_rgmii_fifo.v +++ b/rtl/eth_mac_1g_rgmii_fifo.v @@ -203,6 +203,14 @@ eth_mac_1g_rgmii_inst ( axis_async_frame_fifo #( .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(1), .DROP_WHEN_FULL(0) ) tx_fifo ( @@ -214,6 +222,8 @@ tx_fifo ( .input_axis_tvalid(tx_axis_tvalid), .input_axis_tready(tx_axis_tready), .input_axis_tlast(tx_axis_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(tx_axis_tuser), // AXI output .output_clk(tx_clk), @@ -221,6 +231,9 @@ tx_fifo ( .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), .output_axis_tlast(tx_fifo_axis_tlast), + .output_axis_tid(), + .output_axis_tdest(), + .output_axis_tuser(), // Status .input_status_overflow(tx_fifo_overflow), .input_status_bad_frame(tx_fifo_bad_frame), @@ -235,6 +248,14 @@ assign tx_fifo_axis_tuser = 1'b0; axis_async_frame_fifo #( .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(1), .DROP_WHEN_FULL(1) ) rx_fifo ( @@ -246,6 +267,8 @@ rx_fifo ( .input_axis_tvalid(rx_fifo_axis_tvalid), .input_axis_tready(), .input_axis_tlast(rx_fifo_axis_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(rx_fifo_axis_tuser), // AXI output .output_clk(logic_clk), @@ -253,6 +276,9 @@ rx_fifo ( .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), .output_axis_tlast(rx_axis_tlast), + .output_axis_tid(), + .output_axis_tdest(), + .output_axis_tuser(), // Status .input_status_overflow(), .input_status_bad_frame(), diff --git a/rtl/udp_checksum_gen.v b/rtl/udp_checksum_gen.v index f9e1485ba..549694b90 100644 --- a/rtl/udp_checksum_gen.v +++ b/rtl/udp_checksum_gen.v @@ -197,23 +197,35 @@ wire output_udp_payload_fifo_tlast; wire output_udp_payload_fifo_tuser; axis_fifo #( + .ADDR_WIDTH(PAYLOAD_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), - .ADDR_WIDTH(PAYLOAD_FIFO_ADDR_WIDTH) + .KEEP_ENABLE(0), + .LAST_ENABLE(1), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) payload_fifo ( .clk(clk), .rst(rst), // AXI input .input_axis_tdata(input_udp_payload_fifo_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(input_udp_payload_fifo_tvalid), .input_axis_tready(input_udp_payload_fifo_tready), .input_axis_tlast(input_udp_payload_fifo_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(input_udp_payload_fifo_tuser), // AXI output .output_axis_tdata(output_udp_payload_fifo_tdata), + .output_axis_tkeep(), .output_axis_tvalid(output_udp_payload_fifo_tvalid), .output_axis_tready(output_udp_payload_fifo_tready), .output_axis_tlast(output_udp_payload_fifo_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(output_udp_payload_fifo_tuser) ); diff --git a/rtl/udp_checksum_gen_64.v b/rtl/udp_checksum_gen_64.v index 70041d824..5ebed86d2 100644 --- a/rtl/udp_checksum_gen_64.v +++ b/rtl/udp_checksum_gen_64.v @@ -201,9 +201,16 @@ wire output_udp_payload_fifo_tready; wire output_udp_payload_fifo_tlast; wire output_udp_payload_fifo_tuser; -axis_fifo_64 #( +axis_fifo #( + .ADDR_WIDTH(PAYLOAD_FIFO_ADDR_WIDTH), .DATA_WIDTH(64), - .ADDR_WIDTH(PAYLOAD_FIFO_ADDR_WIDTH) + .KEEP_ENABLE(1), + .KEEP_WIDTH(8), + .LAST_ENABLE(1), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) payload_fifo ( .clk(clk), @@ -214,6 +221,8 @@ payload_fifo ( .input_axis_tvalid(input_udp_payload_fifo_tvalid), .input_axis_tready(input_udp_payload_fifo_tready), .input_axis_tlast(input_udp_payload_fifo_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), .input_axis_tuser(input_udp_payload_fifo_tuser), // AXI output .output_axis_tdata(output_udp_payload_fifo_tdata), @@ -221,6 +230,8 @@ payload_fifo ( .output_axis_tvalid(output_udp_payload_fifo_tvalid), .output_axis_tready(output_udp_payload_fifo_tready), .output_axis_tlast(output_udp_payload_fifo_tlast), + .output_axis_tid(), + .output_axis_tdest(), .output_axis_tuser(output_udp_payload_fifo_tuser) ); diff --git a/tb/test_eth_mac_10g_fifo.py b/tb/test_eth_mac_10g_fifo.py index 2cf41ed28..3920f7c67 100755 --- a/tb/test_eth_mac_10g_fifo.py +++ b/tb/test_eth_mac_10g_fifo.py @@ -40,7 +40,7 @@ srcs.append("../rtl/lfsr.v") srcs.append("../rtl/eth_mac_10g_rx.v") srcs.append("../rtl/eth_mac_10g_tx.v") srcs.append("../rtl/eth_mac_10g.v") -srcs.append("../lib/axis/rtl/axis_async_frame_fifo_64.v") +srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/tb/test_eth_mac_10g_rx.py b/tb/test_eth_mac_10g_rx.py index 5e1063976..a08bf7885 100755 --- a/tb/test_eth_mac_10g_rx.py +++ b/tb/test_eth_mac_10g_rx.py @@ -354,7 +354,7 @@ def bench(): rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() diff --git a/tb/test_eth_mac_10g_tx.py b/tb/test_eth_mac_10g_tx.py index 6b76510aa..862d105cf 100755 --- a/tb/test_eth_mac_10g_tx.py +++ b/tb/test_eth_mac_10g_tx.py @@ -272,7 +272,7 @@ def bench(): axis_frame1 = test_frame1.build_axis() axis_frame2 = test_frame2.build_axis() - axis_frame1.user = 1 + axis_frame1.last_cycle_user = 1 source.send(axis_frame1) source.send(axis_frame2) diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py index 1f5d4ce2a..94ef6071c 100755 --- a/tb/test_eth_mac_1g_rx.py +++ b/tb/test_eth_mac_1g_rx.py @@ -350,7 +350,7 @@ def bench(): rx_frame = sink.recv() - assert rx_frame.user[-1] + assert rx_frame.last_cycle_user rx_frame = sink.recv() diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index 3dedfb93d..0a735d90d 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -272,7 +272,7 @@ def bench(): axis_frame1 = test_frame1.build_axis() axis_frame2 = test_frame2.build_axis() - axis_frame1.user = 1 + axis_frame1.last_cycle_user = 1 source.send(axis_frame1) source.send(axis_frame2) diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py index d0cd6cca7..0c914a6a2 100755 --- a/tb/test_udp_64.py +++ b/tb/test_udp_64.py @@ -39,7 +39,7 @@ srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/udp_checksum_gen_64.v") srcs.append("../rtl/udp_ip_rx_64.v") srcs.append("../rtl/udp_ip_tx_64.v") -srcs.append("../lib/axis/rtl/axis_fifo_64.v") +srcs.append("../lib/axis/rtl/axis_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/tb/test_udp_checksum_gen_64.py b/tb/test_udp_checksum_gen_64.py index fee281c52..b70d35b51 100755 --- a/tb/test_udp_checksum_gen_64.py +++ b/tb/test_udp_checksum_gen_64.py @@ -37,7 +37,7 @@ testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../lib/axis/rtl/axis_fifo_64.v") +srcs.append("../lib/axis/rtl/axis_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index 7a5437c4f..f2a72d886 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -55,7 +55,7 @@ srcs.append("../rtl/eth_arb_mux_64_2.v") srcs.append("../rtl/eth_mux_64_2.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_fifo_64.v") +srcs.append("../lib/axis/rtl/axis_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) From 3063a761e5eea8da47947cd1240c621639a178be Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 26 Feb 2018 00:18:14 -0800 Subject: [PATCH 372/617] Support both versions of ML605 --- example/ML605/fpga_gmii/fpga.ucf | 3 +- .../fpga_gmii/{fpga => fpga_130t}/Makefile | 0 example/ML605/fpga_gmii/fpga_240t/Makefile | 73 +++++++++++++++++ example/ML605/fpga_rgmii/fpga.ucf | 3 +- .../fpga_rgmii/{fpga => fpga_130t}/Makefile | 0 example/ML605/fpga_rgmii/fpga_240t/Makefile | 73 +++++++++++++++++ example/ML605/fpga_sgmii/fpga.ucf | 3 +- .../fpga_sgmii/{fpga => fpga_130t}/Makefile | 0 example/ML605/fpga_sgmii/fpga_240t/Makefile | 81 +++++++++++++++++++ 9 files changed, 233 insertions(+), 3 deletions(-) rename example/ML605/fpga_gmii/{fpga => fpga_130t}/Makefile (100%) create mode 100644 example/ML605/fpga_gmii/fpga_240t/Makefile rename example/ML605/fpga_rgmii/{fpga => fpga_130t}/Makefile (100%) create mode 100644 example/ML605/fpga_rgmii/fpga_240t/Makefile rename example/ML605/fpga_sgmii/{fpga => fpga_130t}/Makefile (100%) create mode 100644 example/ML605/fpga_sgmii/fpga_240t/Makefile diff --git a/example/ML605/fpga_gmii/fpga.ucf b/example/ML605/fpga_gmii/fpga.ucf index 04f830308..1da1978d6 100644 --- a/example/ML605/fpga_gmii/fpga.ucf +++ b/example/ML605/fpga_gmii/fpga.ucf @@ -1,6 +1,7 @@ # User Constraints File for the Xilinx ML605 board, rev C -CONFIG PART = xc6vlx130t-1ff1156; +#CONFIG PART = xc6vlx130t-1ff1156; +#CONFIG PART = xc6vlx240t-1ff1156; # 200MHz clock NET "sys_clk_p" LOC = "J9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0P_GC_34 (GCLK) diff --git a/example/ML605/fpga_gmii/fpga/Makefile b/example/ML605/fpga_gmii/fpga_130t/Makefile similarity index 100% rename from example/ML605/fpga_gmii/fpga/Makefile rename to example/ML605/fpga_gmii/fpga_130t/Makefile diff --git a/example/ML605/fpga_gmii/fpga_240t/Makefile b/example/ML605/fpga_gmii/fpga_240t/Makefile new file mode 100644 index 000000000..ab73d9bbf --- /dev/null +++ b/example/ML605/fpga_gmii/fpga_240t/Makefile @@ -0,0 +1,73 @@ + +# FPGA settings +FPGA_PART = xc6vlx240t-1ff1156 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/iddr.v +SYN_FILES += lib/eth/rtl/oddr.v +SYN_FILES += lib/eth/rtl/ssio_sdr_in.v +SYN_FILES += lib/eth/rtl/ssio_sdr_out.v +SYN_FILES += lib/eth/rtl/gmii_phy_if.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_gmii_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_gmii.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v +SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v +SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +#SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v + +# UCF files +UCF_FILES = fpga.ucf +UCF_FILES += clock.ucf + +# NGC paths for ngdbuild +#NGC_PATHS = coregen/dcm_i100_o125 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 2 -file $(FPGA_TOP).bit" >> program.cmd + echo "program -p 2" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + diff --git a/example/ML605/fpga_rgmii/fpga.ucf b/example/ML605/fpga_rgmii/fpga.ucf index 8f4ad1176..e87d4ed39 100644 --- a/example/ML605/fpga_rgmii/fpga.ucf +++ b/example/ML605/fpga_rgmii/fpga.ucf @@ -1,6 +1,7 @@ # User Constraints File for the Xilinx ML605 board, rev C -CONFIG PART = xc6vlx130t-1ff1156; +#CONFIG PART = xc6vlx130t-1ff1156; +#CONFIG PART = xc6vlx240t-1ff1156; # 200MHz clock NET "sys_clk_p" LOC = "J9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0P_GC_34 (GCLK) diff --git a/example/ML605/fpga_rgmii/fpga/Makefile b/example/ML605/fpga_rgmii/fpga_130t/Makefile similarity index 100% rename from example/ML605/fpga_rgmii/fpga/Makefile rename to example/ML605/fpga_rgmii/fpga_130t/Makefile diff --git a/example/ML605/fpga_rgmii/fpga_240t/Makefile b/example/ML605/fpga_rgmii/fpga_240t/Makefile new file mode 100644 index 000000000..e46f861a8 --- /dev/null +++ b/example/ML605/fpga_rgmii/fpga_240t/Makefile @@ -0,0 +1,73 @@ + +# FPGA settings +FPGA_PART = xc6vlx240t-1ff1156 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/iddr.v +SYN_FILES += lib/eth/rtl/oddr.v +SYN_FILES += lib/eth/rtl/ssio_ddr_in.v +SYN_FILES += lib/eth/rtl/ssio_ddr_out.v +SYN_FILES += lib/eth/rtl/rgmii_phy_if.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rgmii_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rgmii.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v +SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v +SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +#SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v + +# UCF files +UCF_FILES = fpga.ucf +UCF_FILES += clock.ucf + +# NGC paths for ngdbuild +#NGC_PATHS = coregen/dcm_i100_o125 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 2 -file $(FPGA_TOP).bit" >> program.cmd + echo "program -p 2" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + diff --git a/example/ML605/fpga_sgmii/fpga.ucf b/example/ML605/fpga_sgmii/fpga.ucf index e7133e706..fdffeba94 100644 --- a/example/ML605/fpga_sgmii/fpga.ucf +++ b/example/ML605/fpga_sgmii/fpga.ucf @@ -1,6 +1,7 @@ # User Constraints File for the Xilinx ML605 board, rev C -CONFIG PART = xc6vlx130t-1ff1156; +#CONFIG PART = xc6vlx130t-1ff1156; +#CONFIG PART = xc6vlx240t-1ff1156; # 200MHz clock NET "sys_clk_p" LOC = "J9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0P_GC_34 (GCLK) diff --git a/example/ML605/fpga_sgmii/fpga/Makefile b/example/ML605/fpga_sgmii/fpga_130t/Makefile similarity index 100% rename from example/ML605/fpga_sgmii/fpga/Makefile rename to example/ML605/fpga_sgmii/fpga_130t/Makefile diff --git a/example/ML605/fpga_sgmii/fpga_240t/Makefile b/example/ML605/fpga_sgmii/fpga_240t/Makefile new file mode 100644 index 000000000..ac9178695 --- /dev/null +++ b/example/ML605/fpga_sgmii/fpga_240t/Makefile @@ -0,0 +1,81 @@ + +# FPGA settings +FPGA_PART = xc6vlx240t-1ff1156 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v +SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v +SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_clk_gen.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_johnson_cntr.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_rx_rate_adapt.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_sgmii_adapt.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_tx_rate_adapt.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_double_reset.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_gtwizard_gtrxreset_seq.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_rx_elastic_buffer.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_v6_gtxwizard.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_v6_gtxwizard_gtx.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/transceiver/gig_eth_pcs_pma_v11_5_v6_gtxwizard_top.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/gig_eth_pcs_pma_v11_5_block.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/gig_eth_pcs_pma_v11_5_reset_sync.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/gig_eth_pcs_pma_v11_5_sync_block.v +SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5.v + +# UCF files +UCF_FILES = fpga.ucf +UCF_FILES += clock.ucf + +# NGC paths for ngdbuild +NGC_PATHS = coregen/gig_eth_pcs_pma_v11_5 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 2 -file $(FPGA_TOP).bit" >> program.cmd + echo "program -p 2" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + From 5df7efe5169f6ab164256385fddd35791a5243b4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 26 Feb 2018 12:25:20 -0800 Subject: [PATCH 373/617] Happy new year --- COPYING | 2 +- rtl/arbiter.v | 2 +- rtl/axis_adapter.v | 2 +- rtl/axis_arb_mux_4.v | 2 +- rtl/axis_async_fifo.v | 2 +- rtl/axis_async_frame_fifo.v | 2 +- rtl/axis_cobs_decode.v | 2 +- rtl/axis_cobs_encode.v | 2 +- rtl/axis_crosspoint_4x4.v | 2 +- rtl/axis_demux_4.v | 2 +- rtl/axis_fifo.v | 2 +- rtl/axis_frame_fifo.v | 2 +- rtl/axis_frame_join_4.v | 2 +- rtl/axis_frame_length_adjust.v | 2 +- rtl/axis_frame_length_adjust_fifo.v | 2 +- rtl/axis_ll_bridge.v | 2 +- rtl/axis_mux_4.v | 2 +- rtl/axis_rate_limit.v | 2 +- rtl/axis_register.v | 2 +- rtl/axis_srl_fifo.v | 2 +- rtl/axis_srl_register.v | 2 +- rtl/axis_stat_counter.v | 2 +- rtl/axis_switch_4x4.v | 2 +- rtl/axis_tap.v | 2 +- rtl/ll_axis_bridge.v | 2 +- rtl/priority_encoder.v | 2 +- tb/axis_ep.py | 2 +- tb/ll_ep.py | 2 +- tb/test_arbiter.py | 2 +- tb/test_arbiter.v | 2 +- tb/test_arbiter_rr.py | 2 +- tb/test_arbiter_rr.v | 2 +- tb/test_axis_adapter_64_8.py | 2 +- tb/test_axis_adapter_64_8.v | 2 +- tb/test_axis_adapter_8_64.py | 2 +- tb/test_axis_adapter_8_64.v | 2 +- tb/test_axis_arb_mux_4.py | 2 +- tb/test_axis_arb_mux_4.v | 2 +- tb/test_axis_arb_mux_4_64.py | 2 +- tb/test_axis_arb_mux_4_64.v | 2 +- tb/test_axis_async_fifo.py | 2 +- tb/test_axis_async_fifo.v | 2 +- tb/test_axis_async_fifo_64.py | 2 +- tb/test_axis_async_fifo_64.v | 2 +- tb/test_axis_async_frame_fifo.py | 2 +- tb/test_axis_async_frame_fifo.v | 2 +- tb/test_axis_async_frame_fifo_64.py | 2 +- tb/test_axis_async_frame_fifo_64.v | 2 +- tb/test_axis_cobs_decode.py | 2 +- tb/test_axis_cobs_decode.v | 2 +- tb/test_axis_cobs_encode.py | 2 +- tb/test_axis_cobs_encode.v | 2 +- tb/test_axis_cobs_encode_zero_frame.py | 2 +- tb/test_axis_cobs_encode_zero_frame.v | 2 +- tb/test_axis_crosspoint_4x4.py | 2 +- tb/test_axis_crosspoint_4x4.v | 2 +- tb/test_axis_crosspoint_4x4_64.py | 2 +- tb/test_axis_crosspoint_4x4_64.v | 2 +- tb/test_axis_demux_4.py | 2 +- tb/test_axis_demux_4.v | 2 +- tb/test_axis_demux_4_64.py | 2 +- tb/test_axis_demux_4_64.v | 2 +- tb/test_axis_fifo.py | 2 +- tb/test_axis_fifo.v | 2 +- tb/test_axis_fifo_64.py | 2 +- tb/test_axis_fifo_64.v | 2 +- tb/test_axis_frame_fifo.py | 2 +- tb/test_axis_frame_fifo.v | 2 +- tb/test_axis_frame_fifo_64.py | 2 +- tb/test_axis_frame_fifo_64.v | 2 +- tb/test_axis_frame_join_4.py | 2 +- tb/test_axis_frame_join_4.v | 2 +- tb/test_axis_frame_length_adjust_64.py | 2 +- tb/test_axis_frame_length_adjust_64.v | 2 +- tb/test_axis_frame_length_adjust_8.py | 2 +- tb/test_axis_frame_length_adjust_8.v | 2 +- tb/test_axis_frame_length_adjust_fifo.py | 2 +- tb/test_axis_frame_length_adjust_fifo.v | 2 +- tb/test_axis_frame_length_adjust_fifo_64.py | 2 +- tb/test_axis_frame_length_adjust_fifo_64.v | 2 +- tb/test_axis_ll_bridge.py | 2 +- tb/test_axis_ll_bridge.v | 2 +- tb/test_axis_mux_4.py | 2 +- tb/test_axis_mux_4.v | 2 +- tb/test_axis_mux_4_64.py | 2 +- tb/test_axis_mux_4_64.v | 2 +- tb/test_axis_rate_limit.py | 2 +- tb/test_axis_rate_limit.v | 2 +- tb/test_axis_rate_limit_64.py | 2 +- tb/test_axis_rate_limit_64.v | 2 +- tb/test_axis_register.py | 2 +- tb/test_axis_register.v | 2 +- tb/test_axis_register_64.py | 2 +- tb/test_axis_register_64.v | 2 +- tb/test_axis_srl_fifo.py | 2 +- tb/test_axis_srl_fifo.v | 2 +- tb/test_axis_srl_fifo_64.py | 2 +- tb/test_axis_srl_fifo_64.v | 2 +- tb/test_axis_srl_register.py | 2 +- tb/test_axis_srl_register.v | 2 +- tb/test_axis_srl_register_64.py | 2 +- tb/test_axis_srl_register_64.v | 2 +- tb/test_axis_stat_counter.py | 2 +- tb/test_axis_stat_counter.v | 2 +- tb/test_axis_switch_4x4.py | 2 +- tb/test_axis_switch_4x4.v | 2 +- tb/test_axis_switch_4x4_64.py | 2 +- tb/test_axis_switch_4x4_64.v | 2 +- tb/test_axis_tap.py | 2 +- tb/test_axis_tap.v | 2 +- tb/test_axis_tap_64.py | 2 +- tb/test_axis_tap_64.v | 2 +- tb/test_ll_axis_bridge.py | 2 +- tb/test_ll_axis_bridge.v | 2 +- tb/test_priority_encoder.py | 2 +- tb/test_priority_encoder.v | 2 +- 116 files changed, 116 insertions(+), 116 deletions(-) diff --git a/COPYING b/COPYING index 288f3efb7..dc298464e 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/arbiter.v b/rtl/arbiter.v index 24ae74c61..8b0443fdb 100644 --- a/rtl/arbiter.v +++ b/rtl/arbiter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index d0f7bad49..487bfdd65 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_arb_mux_4.v b/rtl/axis_arb_mux_4.v index 61d1bcd8f..a7de9bfb2 100644 --- a/rtl/axis_arb_mux_4.v +++ b/rtl/axis_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 4f5e34946..8a73ba83e 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v index 3890a0387..b17526018 100644 --- a/rtl/axis_async_frame_fifo.v +++ b/rtl/axis_async_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_cobs_decode.v b/rtl/axis_cobs_decode.v index 964bf7fdf..a6cff3d09 100644 --- a/rtl/axis_cobs_decode.v +++ b/rtl/axis_cobs_decode.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/axis_cobs_encode.v b/rtl/axis_cobs_encode.v index 5249aba2c..eaa1e76a8 100644 --- a/rtl/axis_cobs_encode.v +++ b/rtl/axis_cobs_encode.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/axis_crosspoint_4x4.v b/rtl/axis_crosspoint_4x4.v index 2242813c8..9e0ca7919 100644 --- a/rtl/axis_crosspoint_4x4.v +++ b/rtl/axis_crosspoint_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v index 9247fd645..2e12aebb9 100644 --- a/rtl/axis_demux_4.v +++ b/rtl/axis_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index 952eeccfe..93e62c382 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2013-2017 Alex Forencich +Copyright (c) 2013-2018 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 diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v index 13869ad06..9af6d286f 100644 --- a/rtl/axis_frame_fifo.v +++ b/rtl/axis_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v index 907ae74d3..5aabd7035 100644 --- a/rtl/axis_frame_join_4.v +++ b/rtl/axis_frame_join_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_frame_length_adjust.v b/rtl/axis_frame_length_adjust.v index b15d492aa..88297cb18 100644 --- a/rtl/axis_frame_length_adjust.v +++ b/rtl/axis_frame_length_adjust.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/axis_frame_length_adjust_fifo.v b/rtl/axis_frame_length_adjust_fifo.v index 750c7ceed..c1ae3edb8 100644 --- a/rtl/axis_frame_length_adjust_fifo.v +++ b/rtl/axis_frame_length_adjust_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/axis_ll_bridge.v b/rtl/axis_ll_bridge.v index 410081e89..5e83e3de0 100644 --- a/rtl/axis_ll_bridge.v +++ b/rtl/axis_ll_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v index 2337776ca..dea78aca7 100644 --- a/rtl/axis_mux_4.v +++ b/rtl/axis_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index 5ea7fd7d6..240644da6 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_register.v b/rtl/axis_register.v index 1838ccad5..ccee82b7e 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_srl_fifo.v b/rtl/axis_srl_fifo.v index e800fe073..af965854e 100644 --- a/rtl/axis_srl_fifo.v +++ b/rtl/axis_srl_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_srl_register.v b/rtl/axis_srl_register.v index c601dc0e7..f8eba0ab5 100644 --- a/rtl/axis_srl_register.v +++ b/rtl/axis_srl_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index 5f0b5c678..abc5530be 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_switch_4x4.v b/rtl/axis_switch_4x4.v index 7f28b4a8f..8f7bbf943 100644 --- a/rtl/axis_switch_4x4.v +++ b/rtl/axis_switch_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/axis_tap.v b/rtl/axis_tap.v index de64ef945..3cd1f9ed2 100644 --- a/rtl/axis_tap.v +++ b/rtl/axis_tap.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/ll_axis_bridge.v b/rtl/ll_axis_bridge.v index 7b2090b84..5ddd6bc2a 100644 --- a/rtl/ll_axis_bridge.v +++ b/rtl/ll_axis_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/priority_encoder.v b/rtl/priority_encoder.v index 50fbfa5ae..e40b27293 100644 --- a/rtl/priority_encoder.v +++ b/rtl/priority_encoder.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 00eaa25e3..75356b54d 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/ll_ep.py b/tb/ll_ep.py index dc8f8808c..4dc45d4f6 100644 --- a/tb/ll_ep.py +++ b/tb/ll_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arbiter.py b/tb/test_arbiter.py index 0987be90e..f75aa6940 100755 --- a/tb/test_arbiter.py +++ b/tb/test_arbiter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arbiter.v b/tb/test_arbiter.v index 6ea120edb..e11ee9675 100644 --- a/tb/test_arbiter.v +++ b/tb/test_arbiter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arbiter_rr.py b/tb/test_arbiter_rr.py index e915e9d81..4db2219e5 100755 --- a/tb/test_arbiter_rr.py +++ b/tb/test_arbiter_rr.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arbiter_rr.v b/tb/test_arbiter_rr.v index b6dde1ee0..5ddd2da02 100644 --- a/tb/test_arbiter_rr.v +++ b/tb/test_arbiter_rr.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index 9cca872f7..15aea7c0f 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_adapter_64_8.v b/tb/test_axis_adapter_64_8.v index 2b453eb6b..b48214a02 100644 --- a/tb/test_axis_adapter_64_8.v +++ b/tb/test_axis_adapter_64_8.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index 7aad2a50a..d734bff95 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_adapter_8_64.v b/tb/test_axis_adapter_8_64.v index e133176e4..b3d1fb090 100644 --- a/tb/test_axis_adapter_8_64.v +++ b/tb/test_axis_adapter_8_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index 68ebfaa53..3604e682a 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_arb_mux_4.v b/tb/test_axis_arb_mux_4.v index 0d36dc26b..258957110 100644 --- a/tb/test_axis_arb_mux_4.v +++ b/tb/test_axis_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_arb_mux_4_64.py b/tb/test_axis_arb_mux_4_64.py index 31353e8a0..6117fbc9c 100755 --- a/tb/test_axis_arb_mux_4_64.py +++ b/tb/test_axis_arb_mux_4_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_arb_mux_4_64.v b/tb/test_axis_arb_mux_4_64.v index 4b73bbc2f..ee21ef60c 100644 --- a/tb/test_axis_arb_mux_4_64.v +++ b/tb/test_axis_arb_mux_4_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index e7bb74831..91e64d52d 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_async_fifo.v b/tb/test_axis_async_fifo.v index 5396d1e5e..de82f79cb 100644 --- a/tb/test_axis_async_fifo.v +++ b/tb/test_axis_async_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index 2d26b5b7c..019a0b0cf 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_async_fifo_64.v b/tb/test_axis_async_fifo_64.v index 1751c590d..4d590df1b 100644 --- a/tb/test_axis_async_fifo_64.v +++ b/tb/test_axis_async_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index 43c0a5a48..d08f026f1 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index 258d74071..da9498117 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index e32b66527..ec6de8397 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index 4f252b045..60446b89a 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py index faa131c37..381b91355 100755 --- a/tb/test_axis_cobs_decode.py +++ b/tb/test_axis_cobs_decode.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_axis_cobs_decode.v b/tb/test_axis_cobs_decode.v index 2365ce437..f5841f43a 100644 --- a/tb/test_axis_cobs_decode.v +++ b/tb/test_axis_cobs_decode.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py index 3eb7ae8db..ccba256c4 100755 --- a/tb/test_axis_cobs_encode.py +++ b/tb/test_axis_cobs_encode.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_axis_cobs_encode.v b/tb/test_axis_cobs_encode.v index 750bf4e33..6a14bb203 100644 --- a/tb/test_axis_cobs_encode.v +++ b/tb/test_axis_cobs_encode.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_axis_cobs_encode_zero_frame.py b/tb/test_axis_cobs_encode_zero_frame.py index 3f4066dc5..924bb7570 100755 --- a/tb/test_axis_cobs_encode_zero_frame.py +++ b/tb/test_axis_cobs_encode_zero_frame.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_axis_cobs_encode_zero_frame.v b/tb/test_axis_cobs_encode_zero_frame.v index 7d4ebf664..e1af31f8d 100644 --- a/tb/test_axis_cobs_encode_zero_frame.v +++ b/tb/test_axis_cobs_encode_zero_frame.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_axis_crosspoint_4x4.py b/tb/test_axis_crosspoint_4x4.py index 1c1cd9425..53d69421c 100755 --- a/tb/test_axis_crosspoint_4x4.py +++ b/tb/test_axis_crosspoint_4x4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_crosspoint_4x4.v b/tb/test_axis_crosspoint_4x4.v index 3d3dbf93f..651d3e5f5 100644 --- a/tb/test_axis_crosspoint_4x4.v +++ b/tb/test_axis_crosspoint_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_crosspoint_4x4_64.py b/tb/test_axis_crosspoint_4x4_64.py index a57cb0817..a07287fa0 100755 --- a/tb/test_axis_crosspoint_4x4_64.py +++ b/tb/test_axis_crosspoint_4x4_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_crosspoint_4x4_64.v b/tb/test_axis_crosspoint_4x4_64.v index 42ed67a44..e1e54e8d6 100644 --- a/tb/test_axis_crosspoint_4x4_64.v +++ b/tb/test_axis_crosspoint_4x4_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py index bc4a58444..47fd50a9e 100755 --- a/tb/test_axis_demux_4.py +++ b/tb/test_axis_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_demux_4.v b/tb/test_axis_demux_4.v index 80c08a16e..99d09f115 100644 --- a/tb/test_axis_demux_4.v +++ b/tb/test_axis_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_demux_4_64.py b/tb/test_axis_demux_4_64.py index ab18a8382..431cf5b34 100755 --- a/tb/test_axis_demux_4_64.py +++ b/tb/test_axis_demux_4_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_demux_4_64.v b/tb/test_axis_demux_4_64.v index bd2824693..9eb86ec0c 100644 --- a/tb/test_axis_demux_4_64.v +++ b/tb/test_axis_demux_4_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index a77bb6423..c7d83b45f 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_fifo.v b/tb/test_axis_fifo.v index d3a0d084f..2b7a76e50 100644 --- a/tb/test_axis_fifo.v +++ b/tb/test_axis_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index 5ef0509a9..2265bad69 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_fifo_64.v b/tb/test_axis_fifo_64.v index 6c5379493..d1e58c0f0 100644 --- a/tb/test_axis_fifo_64.v +++ b/tb/test_axis_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index 8cd0d7181..ab1a92ffb 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v index 0fc99f00f..2aaaa6c4c 100644 --- a/tb/test_axis_frame_fifo.v +++ b/tb/test_axis_frame_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index 698c4106d..43fd39a6d 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v index 8dc92fc4f..a2e1a08fc 100644 --- a/tb/test_axis_frame_fifo_64.v +++ b/tb/test_axis_frame_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index aaafbca88..47b59de72 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_frame_join_4.v b/tb/test_axis_frame_join_4.v index cb9b58270..530c61f1c 100644 --- a/tb/test_axis_frame_join_4.v +++ b/tb/test_axis_frame_join_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_frame_length_adjust_64.py b/tb/test_axis_frame_length_adjust_64.py index cf83dc2f2..60eb56f9a 100755 --- a/tb/test_axis_frame_length_adjust_64.py +++ b/tb/test_axis_frame_length_adjust_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_frame_length_adjust_64.v b/tb/test_axis_frame_length_adjust_64.v index 6ef943081..b02e7611e 100644 --- a/tb/test_axis_frame_length_adjust_64.v +++ b/tb/test_axis_frame_length_adjust_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_frame_length_adjust_8.py b/tb/test_axis_frame_length_adjust_8.py index ab17bc579..9a2238129 100755 --- a/tb/test_axis_frame_length_adjust_8.py +++ b/tb/test_axis_frame_length_adjust_8.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_frame_length_adjust_8.v b/tb/test_axis_frame_length_adjust_8.v index d1c82e312..93cc4f1ab 100644 --- a/tb/test_axis_frame_length_adjust_8.v +++ b/tb/test_axis_frame_length_adjust_8.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_frame_length_adjust_fifo.py b/tb/test_axis_frame_length_adjust_fifo.py index a9359ca64..80e754345 100755 --- a/tb/test_axis_frame_length_adjust_fifo.py +++ b/tb/test_axis_frame_length_adjust_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_frame_length_adjust_fifo.v b/tb/test_axis_frame_length_adjust_fifo.v index a5250f0d7..c5a2715aa 100644 --- a/tb/test_axis_frame_length_adjust_fifo.v +++ b/tb/test_axis_frame_length_adjust_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_frame_length_adjust_fifo_64.py b/tb/test_axis_frame_length_adjust_fifo_64.py index e423ba67c..263679bb0 100755 --- a/tb/test_axis_frame_length_adjust_fifo_64.py +++ b/tb/test_axis_frame_length_adjust_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_frame_length_adjust_fifo_64.v b/tb/test_axis_frame_length_adjust_fifo_64.v index 941fa8b64..169efa5ae 100644 --- a/tb/test_axis_frame_length_adjust_fifo_64.v +++ b/tb/test_axis_frame_length_adjust_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_ll_bridge.py b/tb/test_axis_ll_bridge.py index b63a8dcbc..f03818000 100755 --- a/tb/test_axis_ll_bridge.py +++ b/tb/test_axis_ll_bridge.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_ll_bridge.v b/tb/test_axis_ll_bridge.v index b2aa98ea2..05d4d6cd1 100644 --- a/tb/test_axis_ll_bridge.v +++ b/tb/test_axis_ll_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py index 84986e663..91b266b6f 100755 --- a/tb/test_axis_mux_4.py +++ b/tb/test_axis_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_mux_4.v b/tb/test_axis_mux_4.v index 792a783b0..ca4345821 100644 --- a/tb/test_axis_mux_4.v +++ b/tb/test_axis_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_mux_4_64.py b/tb/test_axis_mux_4_64.py index c6b879bdf..da89e5fa9 100755 --- a/tb/test_axis_mux_4_64.py +++ b/tb/test_axis_mux_4_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_mux_4_64.v b/tb/test_axis_mux_4_64.v index bda8ed60b..ad62fd3d9 100644 --- a/tb/test_axis_mux_4_64.v +++ b/tb/test_axis_mux_4_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index 6f3ea0360..1af1f7349 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_rate_limit.v b/tb/test_axis_rate_limit.v index a22aaf2f7..699c05268 100644 --- a/tb/test_axis_rate_limit.v +++ b/tb/test_axis_rate_limit.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index ded85b1a0..bb8121328 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_rate_limit_64.v b/tb/test_axis_rate_limit_64.v index 6926c3c07..6ed64cd59 100644 --- a/tb/test_axis_rate_limit_64.v +++ b/tb/test_axis_rate_limit_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py index 21df526f4..2b1b000b9 100755 --- a/tb/test_axis_register.py +++ b/tb/test_axis_register.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_register.v b/tb/test_axis_register.v index 6756905e2..94c3c853c 100644 --- a/tb/test_axis_register.v +++ b/tb/test_axis_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py index 9d8b099d9..bde5194b3 100755 --- a/tb/test_axis_register_64.py +++ b/tb/test_axis_register_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_register_64.v b/tb/test_axis_register_64.v index a9453e7b6..21f92b0d4 100644 --- a/tb/test_axis_register_64.v +++ b/tb/test_axis_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py index b04d70f4f..c7a289256 100755 --- a/tb/test_axis_srl_fifo.py +++ b/tb/test_axis_srl_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_srl_fifo.v b/tb/test_axis_srl_fifo.v index e449e5af7..b556386ce 100644 --- a/tb/test_axis_srl_fifo.v +++ b/tb/test_axis_srl_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py index 78cedb9e0..2b4e91c4a 100755 --- a/tb/test_axis_srl_fifo_64.py +++ b/tb/test_axis_srl_fifo_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_srl_fifo_64.v b/tb/test_axis_srl_fifo_64.v index a4773e80d..c11280dfa 100644 --- a/tb/test_axis_srl_fifo_64.v +++ b/tb/test_axis_srl_fifo_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_srl_register.py b/tb/test_axis_srl_register.py index dc7286506..18ad7be8d 100755 --- a/tb/test_axis_srl_register.py +++ b/tb/test_axis_srl_register.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_srl_register.v b/tb/test_axis_srl_register.v index f553f1e67..f45d3fd9b 100644 --- a/tb/test_axis_srl_register.v +++ b/tb/test_axis_srl_register.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_srl_register_64.py b/tb/test_axis_srl_register_64.py index cd229b35c..7bf20da63 100755 --- a/tb/test_axis_srl_register_64.py +++ b/tb/test_axis_srl_register_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_srl_register_64.v b/tb/test_axis_srl_register_64.v index a1940a3b8..e9c510138 100644 --- a/tb/test_axis_srl_register_64.v +++ b/tb/test_axis_srl_register_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index fe30617fd..34b5cb9a3 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v index d4b2336ce..2fb6fa312 100644 --- a/tb/test_axis_stat_counter.v +++ b/tb/test_axis_stat_counter.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py index 9cba3fd44..bc30f5ab3 100755 --- a/tb/test_axis_switch_4x4.py +++ b/tb/test_axis_switch_4x4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_axis_switch_4x4.v b/tb/test_axis_switch_4x4.v index 76b57a128..41edd7681 100644 --- a/tb/test_axis_switch_4x4.v +++ b/tb/test_axis_switch_4x4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_axis_switch_4x4_64.py b/tb/test_axis_switch_4x4_64.py index 69de32437..dda6d852e 100755 --- a/tb/test_axis_switch_4x4_64.py +++ b/tb/test_axis_switch_4x4_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_axis_switch_4x4_64.v b/tb/test_axis_switch_4x4_64.v index 90fc198bd..cc8ed02da 100644 --- a/tb/test_axis_switch_4x4_64.v +++ b/tb/test_axis_switch_4x4_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_axis_tap.py b/tb/test_axis_tap.py index c54892fd7..29a7423b4 100755 --- a/tb/test_axis_tap.py +++ b/tb/test_axis_tap.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_tap.v b/tb/test_axis_tap.v index 8ee6ce3e0..4d38c7c8e 100644 --- a/tb/test_axis_tap.v +++ b/tb/test_axis_tap.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_tap_64.py b/tb/test_axis_tap_64.py index 31c68cd94..1e06ca6fe 100755 --- a/tb/test_axis_tap_64.py +++ b/tb/test_axis_tap_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_tap_64.v b/tb/test_axis_tap_64.v index 6149e3ef3..5a8dbdf23 100644 --- a/tb/test_axis_tap_64.v +++ b/tb/test_axis_tap_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_ll_axis_bridge.py b/tb/test_ll_axis_bridge.py index aa3065267..41b0532bf 100755 --- a/tb/test_ll_axis_bridge.py +++ b/tb/test_ll_axis_bridge.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ll_axis_bridge.v b/tb/test_ll_axis_bridge.v index 049a2a6db..c6a9bbb36 100644 --- a/tb/test_ll_axis_bridge.v +++ b/tb/test_ll_axis_bridge.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_priority_encoder.py b/tb/test_priority_encoder.py index 5152dea8a..9ba980646 100755 --- a/tb/test_priority_encoder.py +++ b/tb/test_priority_encoder.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_priority_encoder.v b/tb/test_priority_encoder.v index ef0288461..07c398880 100644 --- a/tb/test_priority_encoder.v +++ b/tb/test_priority_encoder.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 From 0fd157964a753048ff6c712e0959b5f583b33e57 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 26 Feb 2018 12:50:51 -0800 Subject: [PATCH 374/617] Happy new year --- COPYING | 2 +- example/ATLYS/fpga/rtl/debounce_switch.v | 2 +- example/ATLYS/fpga/rtl/fpga.v | 2 +- example/ATLYS/fpga/rtl/fpga_core.v | 2 +- example/ATLYS/fpga/rtl/sync_reset.v | 2 +- example/ATLYS/fpga/rtl/sync_signal.v | 2 +- example/ATLYS/fpga/tb/test_fpga_core.py | 2 +- example/ATLYS/fpga/tb/test_fpga_core.v | 2 +- example/DE5-Net/fpga/rtl/debounce_switch.v | 2 +- example/DE5-Net/fpga/rtl/fpga.v | 2 +- example/DE5-Net/fpga/rtl/fpga_core.v | 2 +- example/DE5-Net/fpga/rtl/i2c_master.v | 2 +- example/DE5-Net/fpga/rtl/si570_i2c_init.v | 2 +- example/DE5-Net/fpga/rtl/sync_reset.v | 2 +- example/DE5-Net/fpga/rtl/sync_signal.v | 2 +- example/DE5-Net/fpga/tb/test_fpga_core.py | 2 +- example/DE5-Net/fpga/tb/test_fpga_core.v | 2 +- example/HXT100G/fpga/rtl/debounce_switch.v | 2 +- example/HXT100G/fpga/rtl/eth_gth_phy_quad.v | 2 +- example/HXT100G/fpga/rtl/fpga.v | 2 +- example/HXT100G/fpga/rtl/fpga_core.v | 2 +- example/HXT100G/fpga/rtl/gth_i2c_init.v | 2 +- example/HXT100G/fpga/rtl/i2c_master.v | 2 +- example/HXT100G/fpga/rtl/sync_reset.v | 2 +- example/HXT100G/fpga/rtl/sync_signal.v | 2 +- example/HXT100G/fpga/tb/test_fpga_core.py | 2 +- example/HXT100G/fpga/tb/test_fpga_core.v | 2 +- example/ML605/fpga_gmii/rtl/debounce_switch.v | 2 +- example/ML605/fpga_gmii/rtl/fpga.v | 2 +- example/ML605/fpga_gmii/rtl/fpga_core.v | 2 +- example/ML605/fpga_gmii/rtl/sync_reset.v | 2 +- example/ML605/fpga_gmii/rtl/sync_signal.v | 2 +- example/ML605/fpga_gmii/tb/test_fpga_core.py | 2 +- example/ML605/fpga_gmii/tb/test_fpga_core.v | 2 +- example/ML605/fpga_rgmii/rtl/debounce_switch.v | 2 +- example/ML605/fpga_rgmii/rtl/fpga.v | 2 +- example/ML605/fpga_rgmii/rtl/fpga_core.v | 2 +- example/ML605/fpga_rgmii/rtl/sync_reset.v | 2 +- example/ML605/fpga_rgmii/rtl/sync_signal.v | 2 +- example/ML605/fpga_rgmii/tb/test_fpga_core.py | 2 +- example/ML605/fpga_rgmii/tb/test_fpga_core.v | 2 +- example/ML605/fpga_sgmii/rtl/debounce_switch.v | 2 +- example/ML605/fpga_sgmii/rtl/fpga.v | 2 +- example/ML605/fpga_sgmii/rtl/fpga_core.v | 2 +- example/ML605/fpga_sgmii/rtl/sync_reset.v | 2 +- example/ML605/fpga_sgmii/rtl/sync_signal.v | 2 +- example/ML605/fpga_sgmii/tb/test_fpga_core.py | 2 +- example/ML605/fpga_sgmii/tb/test_fpga_core.v | 2 +- example/NexysVideo/fpga/rtl/debounce_switch.v | 2 +- example/NexysVideo/fpga/rtl/fpga.v | 2 +- example/NexysVideo/fpga/rtl/fpga_core.v | 2 +- example/NexysVideo/fpga/rtl/sync_reset.v | 2 +- example/NexysVideo/fpga/rtl/sync_signal.v | 2 +- example/NexysVideo/fpga/tb/test_fpga_core.py | 2 +- example/NexysVideo/fpga/tb/test_fpga_core.v | 2 +- example/VCU108/fpga_10g/rtl/debounce_switch.v | 2 +- example/VCU108/fpga_10g/rtl/fpga.v | 2 +- example/VCU108/fpga_10g/rtl/fpga_core.v | 2 +- example/VCU108/fpga_10g/rtl/i2c_master.v | 2 +- example/VCU108/fpga_10g/rtl/si570_i2c_init.v | 2 +- example/VCU108/fpga_10g/rtl/sync_reset.v | 2 +- example/VCU108/fpga_10g/rtl/sync_signal.v | 2 +- example/VCU108/fpga_10g/tb/test_fpga_core.py | 2 +- example/VCU108/fpga_10g/tb/test_fpga_core.v | 2 +- example/VCU108/fpga_1g/rtl/debounce_switch.v | 2 +- example/VCU108/fpga_1g/rtl/fpga.v | 2 +- example/VCU108/fpga_1g/rtl/fpga_core.v | 2 +- example/VCU108/fpga_1g/rtl/sync_reset.v | 2 +- example/VCU108/fpga_1g/rtl/sync_signal.v | 2 +- example/VCU108/fpga_1g/tb/test_fpga_core.py | 2 +- example/VCU108/fpga_1g/tb/test_fpga_core.v | 2 +- rtl/arp.v | 2 +- rtl/arp_64.v | 2 +- rtl/arp_cache.v | 2 +- rtl/arp_eth_rx.v | 2 +- rtl/arp_eth_rx_64.v | 2 +- rtl/arp_eth_tx.v | 2 +- rtl/arp_eth_tx_64.v | 2 +- rtl/axis_eth_fcs.v | 2 +- rtl/axis_eth_fcs_64.v | 2 +- rtl/axis_eth_fcs_check.v | 2 +- rtl/axis_eth_fcs_check_64.v | 2 +- rtl/axis_eth_fcs_insert.v | 2 +- rtl/axis_eth_fcs_insert_64.v | 2 +- rtl/axis_gmii_rx.v | 2 +- rtl/axis_gmii_tx.v | 2 +- rtl/eth_arb_mux_2.v | 2 +- rtl/eth_arb_mux_4.v | 2 +- rtl/eth_arb_mux_64_2.v | 2 +- rtl/eth_arb_mux_64_4.v | 2 +- rtl/eth_axis_rx.v | 2 +- rtl/eth_axis_rx_64.v | 2 +- rtl/eth_axis_tx.v | 2 +- rtl/eth_axis_tx_64.v | 2 +- rtl/eth_demux_4.v | 2 +- rtl/eth_demux_64_4.v | 2 +- rtl/eth_mac_10g.v | 2 +- rtl/eth_mac_10g_fifo.v | 2 +- rtl/eth_mac_10g_rx.v | 2 +- rtl/eth_mac_10g_tx.v | 2 +- rtl/eth_mac_1g.v | 2 +- rtl/eth_mac_1g_fifo.v | 2 +- rtl/eth_mac_1g_gmii.v | 2 +- rtl/eth_mac_1g_gmii_fifo.v | 2 +- rtl/eth_mac_1g_rgmii.v | 2 +- rtl/eth_mac_1g_rgmii_fifo.v | 2 +- rtl/eth_mac_1g_rx.v | 2 +- rtl/eth_mac_1g_tx.v | 2 +- rtl/eth_mux_2.v | 2 +- rtl/eth_mux_4.v | 2 +- rtl/eth_mux_64_2.v | 2 +- rtl/eth_mux_64_4.v | 2 +- rtl/gmii_phy_if.v | 2 +- rtl/iddr.v | 2 +- rtl/ip.v | 2 +- rtl/ip_64.v | 2 +- rtl/ip_arb_mux_2.v | 2 +- rtl/ip_arb_mux_4.v | 2 +- rtl/ip_arb_mux_64_2.v | 2 +- rtl/ip_arb_mux_64_4.v | 2 +- rtl/ip_complete.v | 2 +- rtl/ip_complete_64.v | 2 +- rtl/ip_demux_4.v | 2 +- rtl/ip_demux_64_4.v | 2 +- rtl/ip_eth_rx.v | 2 +- rtl/ip_eth_rx_64.v | 2 +- rtl/ip_eth_tx.v | 2 +- rtl/ip_eth_tx_64.v | 2 +- rtl/ip_mux_2.v | 2 +- rtl/ip_mux_4.v | 2 +- rtl/ip_mux_64_2.v | 2 +- rtl/ip_mux_64_4.v | 2 +- rtl/lfsr.v | 2 +- rtl/oddr.v | 2 +- rtl/rgmii_phy_if.v | 2 +- rtl/ssio_ddr_in.v | 2 +- rtl/ssio_ddr_in_diff.v | 2 +- rtl/ssio_ddr_out.v | 2 +- rtl/ssio_ddr_out_diff.v | 2 +- rtl/ssio_sdr_in.v | 2 +- rtl/ssio_sdr_in_diff.v | 2 +- rtl/ssio_sdr_out.v | 2 +- rtl/ssio_sdr_out_diff.v | 2 +- rtl/udp.v | 2 +- rtl/udp_64.v | 2 +- rtl/udp_arb_mux_4.v | 2 +- rtl/udp_arb_mux_64_4.v | 2 +- rtl/udp_checksum_gen.v | 2 +- rtl/udp_checksum_gen_64.v | 2 +- rtl/udp_complete.v | 2 +- rtl/udp_complete_64.v | 2 +- rtl/udp_demux_4.v | 2 +- rtl/udp_demux_64_4.v | 2 +- rtl/udp_ip_rx.v | 2 +- rtl/udp_ip_rx_64.v | 2 +- rtl/udp_ip_tx.v | 2 +- rtl/udp_ip_tx_64.v | 2 +- rtl/udp_mux_4.v | 2 +- rtl/udp_mux_64_4.v | 2 +- rtl/xgmii_deinterleave.v | 2 +- rtl/xgmii_interleave.v | 2 +- tb/arp_ep.py | 2 +- tb/eth_ep.py | 2 +- tb/gmii_ep.py | 2 +- tb/ip_ep.py | 2 +- tb/rgmii_ep.py | 2 +- tb/test_arp.py | 2 +- tb/test_arp.v | 2 +- tb/test_arp_64.py | 2 +- tb/test_arp_64.v | 2 +- tb/test_arp_cache.py | 2 +- tb/test_arp_cache.v | 2 +- tb/test_arp_eth_rx.py | 2 +- tb/test_arp_eth_rx.v | 2 +- tb/test_arp_eth_rx_64.py | 2 +- tb/test_arp_eth_rx_64.v | 2 +- tb/test_arp_eth_tx.py | 2 +- tb/test_arp_eth_tx.v | 2 +- tb/test_arp_eth_tx_64.py | 2 +- tb/test_arp_eth_tx_64.v | 2 +- tb/test_axis_eth_fcs.py | 2 +- tb/test_axis_eth_fcs.v | 2 +- tb/test_axis_eth_fcs_64.py | 2 +- tb/test_axis_eth_fcs_64.v | 2 +- tb/test_axis_eth_fcs_check.py | 2 +- tb/test_axis_eth_fcs_check.v | 2 +- tb/test_axis_eth_fcs_check_64.py | 2 +- tb/test_axis_eth_fcs_check_64.v | 2 +- tb/test_axis_eth_fcs_insert.py | 2 +- tb/test_axis_eth_fcs_insert.v | 2 +- tb/test_axis_eth_fcs_insert_64.py | 2 +- tb/test_axis_eth_fcs_insert_64.v | 2 +- tb/test_axis_eth_fcs_insert_64_pad.py | 2 +- tb/test_axis_eth_fcs_insert_64_pad.v | 2 +- tb/test_axis_eth_fcs_insert_pad.py | 2 +- tb/test_axis_eth_fcs_insert_pad.v | 2 +- tb/test_axis_gmii_rx.py | 2 +- tb/test_axis_gmii_rx.v | 2 +- tb/test_axis_gmii_tx.py | 2 +- tb/test_axis_gmii_tx.v | 2 +- tb/test_eth_arb_mux_4.py | 2 +- tb/test_eth_arb_mux_4.v | 2 +- tb/test_eth_arb_mux_64_4.py | 2 +- tb/test_eth_arb_mux_64_4.v | 2 +- tb/test_eth_axis_rx.py | 2 +- tb/test_eth_axis_rx.v | 2 +- tb/test_eth_axis_rx_64.py | 2 +- tb/test_eth_axis_rx_64.v | 2 +- tb/test_eth_axis_tx.py | 2 +- tb/test_eth_axis_tx.v | 2 +- tb/test_eth_axis_tx_64.py | 2 +- tb/test_eth_axis_tx_64.v | 2 +- tb/test_eth_demux_4.py | 2 +- tb/test_eth_demux_4.v | 2 +- tb/test_eth_demux_64_4.py | 2 +- tb/test_eth_demux_64_4.v | 2 +- tb/test_eth_mac_10g.py | 2 +- tb/test_eth_mac_10g.v | 2 +- tb/test_eth_mac_10g_fifo.py | 2 +- tb/test_eth_mac_10g_fifo.v | 2 +- tb/test_eth_mac_10g_rx.py | 2 +- tb/test_eth_mac_10g_rx.v | 2 +- tb/test_eth_mac_10g_tx.py | 2 +- tb/test_eth_mac_10g_tx.v | 2 +- tb/test_eth_mac_1g.py | 2 +- tb/test_eth_mac_1g.v | 2 +- tb/test_eth_mac_1g_fifo.py | 2 +- tb/test_eth_mac_1g_fifo.v | 2 +- tb/test_eth_mac_1g_gmii.py | 2 +- tb/test_eth_mac_1g_gmii.v | 2 +- tb/test_eth_mac_1g_gmii_fifo.py | 2 +- tb/test_eth_mac_1g_gmii_fifo.v | 2 +- tb/test_eth_mac_1g_rgmii.py | 2 +- tb/test_eth_mac_1g_rgmii.v | 2 +- tb/test_eth_mac_1g_rgmii_fifo.py | 2 +- tb/test_eth_mac_1g_rgmii_fifo.v | 2 +- tb/test_eth_mac_1g_rx.py | 2 +- tb/test_eth_mac_1g_rx.v | 2 +- tb/test_eth_mac_1g_tx.py | 2 +- tb/test_eth_mac_1g_tx.v | 2 +- tb/test_eth_mux_4.py | 2 +- tb/test_eth_mux_4.v | 2 +- tb/test_eth_mux_64_4.py | 2 +- tb/test_eth_mux_64_4.v | 2 +- tb/test_ip.py | 2 +- tb/test_ip.v | 2 +- tb/test_ip_64.py | 2 +- tb/test_ip_64.v | 2 +- tb/test_ip_arb_mux_4.py | 2 +- tb/test_ip_arb_mux_4.v | 2 +- tb/test_ip_arb_mux_64_4.py | 2 +- tb/test_ip_arb_mux_64_4.v | 2 +- tb/test_ip_complete.py | 2 +- tb/test_ip_complete.v | 2 +- tb/test_ip_complete_64.py | 2 +- tb/test_ip_complete_64.v | 2 +- tb/test_ip_demux_4.py | 2 +- tb/test_ip_demux_4.v | 2 +- tb/test_ip_demux_64_4.py | 2 +- tb/test_ip_demux_64_4.v | 2 +- tb/test_ip_eth_rx.py | 2 +- tb/test_ip_eth_rx.v | 2 +- tb/test_ip_eth_rx_64.py | 2 +- tb/test_ip_eth_rx_64.v | 2 +- tb/test_ip_eth_tx.py | 2 +- tb/test_ip_eth_tx.v | 2 +- tb/test_ip_eth_tx_64.py | 2 +- tb/test_ip_eth_tx_64.v | 2 +- tb/test_ip_mux_4.py | 2 +- tb/test_ip_mux_4.v | 2 +- tb/test_ip_mux_64_4.py | 2 +- tb/test_ip_mux_64_4.v | 2 +- tb/test_udp.py | 2 +- tb/test_udp.v | 2 +- tb/test_udp_64.py | 2 +- tb/test_udp_64.v | 2 +- tb/test_udp_arb_mux_4.py | 2 +- tb/test_udp_arb_mux_4.v | 2 +- tb/test_udp_arb_mux_64_4.py | 2 +- tb/test_udp_arb_mux_64_4.v | 2 +- tb/test_udp_checksum_gen.py | 2 +- tb/test_udp_checksum_gen.v | 2 +- tb/test_udp_checksum_gen_64.py | 2 +- tb/test_udp_checksum_gen_64.v | 2 +- tb/test_udp_complete.py | 2 +- tb/test_udp_complete.v | 2 +- tb/test_udp_complete_64.py | 2 +- tb/test_udp_complete_64.v | 2 +- tb/test_udp_demux_4.py | 2 +- tb/test_udp_demux_4.v | 2 +- tb/test_udp_demux_64_4.py | 2 +- tb/test_udp_demux_64_4.v | 2 +- tb/test_udp_ip_rx.py | 2 +- tb/test_udp_ip_rx.v | 2 +- tb/test_udp_ip_rx_64.py | 2 +- tb/test_udp_ip_rx_64.v | 2 +- tb/test_udp_ip_tx.py | 2 +- tb/test_udp_ip_tx.v | 2 +- tb/test_udp_ip_tx_64.py | 2 +- tb/test_udp_ip_tx_64.v | 2 +- tb/test_udp_mux_4.py | 2 +- tb/test_udp_mux_4.v | 2 +- tb/test_udp_mux_64_4.py | 2 +- tb/test_udp_mux_64_4.v | 2 +- tb/udp_ep.py | 2 +- tb/xgmii_ep.py | 2 +- 306 files changed, 306 insertions(+), 306 deletions(-) diff --git a/COPYING b/COPYING index 288f3efb7..dc298464e 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ATLYS/fpga/rtl/debounce_switch.v b/example/ATLYS/fpga/rtl/debounce_switch.v index ab84126ec..bb631cc35 100644 --- a/example/ATLYS/fpga/rtl/debounce_switch.v +++ b/example/ATLYS/fpga/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ATLYS/fpga/rtl/fpga.v b/example/ATLYS/fpga/rtl/fpga.v index 17edb11d1..eeeb96cb5 100644 --- a/example/ATLYS/fpga/rtl/fpga.v +++ b/example/ATLYS/fpga/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index 12c779c15..5ad408f91 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ATLYS/fpga/rtl/sync_reset.v b/example/ATLYS/fpga/rtl/sync_reset.v index 558a67605..acbcf1c6e 100644 --- a/example/ATLYS/fpga/rtl/sync_reset.v +++ b/example/ATLYS/fpga/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ATLYS/fpga/rtl/sync_signal.v b/example/ATLYS/fpga/rtl/sync_signal.v index 1b8a32328..b2a8ce3de 100644 --- a/example/ATLYS/fpga/rtl/sync_signal.v +++ b/example/ATLYS/fpga/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index bdb7fea7f..7cc6dbb38 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/ATLYS/fpga/tb/test_fpga_core.v b/example/ATLYS/fpga/tb/test_fpga_core.v index 3c3a8816a..bbd8df6a4 100644 --- a/example/ATLYS/fpga/tb/test_fpga_core.v +++ b/example/ATLYS/fpga/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/DE5-Net/fpga/rtl/debounce_switch.v b/example/DE5-Net/fpga/rtl/debounce_switch.v index ab84126ec..bb631cc35 100644 --- a/example/DE5-Net/fpga/rtl/debounce_switch.v +++ b/example/DE5-Net/fpga/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/DE5-Net/fpga/rtl/fpga.v b/example/DE5-Net/fpga/rtl/fpga.v index 4b142a083..404f3cf94 100644 --- a/example/DE5-Net/fpga/rtl/fpga.v +++ b/example/DE5-Net/fpga/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index 81686fd5c..1940672ec 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/example/DE5-Net/fpga/rtl/i2c_master.v b/example/DE5-Net/fpga/rtl/i2c_master.v index 61a313ddb..95d3a5212 100644 --- a/example/DE5-Net/fpga/rtl/i2c_master.v +++ b/example/DE5-Net/fpga/rtl/i2c_master.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/DE5-Net/fpga/rtl/si570_i2c_init.v b/example/DE5-Net/fpga/rtl/si570_i2c_init.v index 03104f4d2..e4dc5625b 100644 --- a/example/DE5-Net/fpga/rtl/si570_i2c_init.v +++ b/example/DE5-Net/fpga/rtl/si570_i2c_init.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/DE5-Net/fpga/rtl/sync_reset.v b/example/DE5-Net/fpga/rtl/sync_reset.v index 558a67605..acbcf1c6e 100644 --- a/example/DE5-Net/fpga/rtl/sync_reset.v +++ b/example/DE5-Net/fpga/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/DE5-Net/fpga/rtl/sync_signal.v b/example/DE5-Net/fpga/rtl/sync_signal.v index 1b8a32328..b2a8ce3de 100644 --- a/example/DE5-Net/fpga/rtl/sync_signal.v +++ b/example/DE5-Net/fpga/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index ef06b7505..c1eb15068 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.v b/example/DE5-Net/fpga/tb/test_fpga_core.v index 69b0f55c5..d441f0cce 100644 --- a/example/DE5-Net/fpga/tb/test_fpga_core.v +++ b/example/DE5-Net/fpga/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/example/HXT100G/fpga/rtl/debounce_switch.v b/example/HXT100G/fpga/rtl/debounce_switch.v index 245f1abea..69f30d706 100644 --- a/example/HXT100G/fpga/rtl/debounce_switch.v +++ b/example/HXT100G/fpga/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v b/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v index 375640ac4..60ab0f137 100644 --- a/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v +++ b/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/HXT100G/fpga/rtl/fpga.v b/example/HXT100G/fpga/rtl/fpga.v index 3048b11d1..4301afecb 100644 --- a/example/HXT100G/fpga/rtl/fpga.v +++ b/example/HXT100G/fpga/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v index c1ec2ecc0..c000ecc74 100644 --- a/example/HXT100G/fpga/rtl/fpga_core.v +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/example/HXT100G/fpga/rtl/gth_i2c_init.v b/example/HXT100G/fpga/rtl/gth_i2c_init.v index 95864817f..a8eff170a 100644 --- a/example/HXT100G/fpga/rtl/gth_i2c_init.v +++ b/example/HXT100G/fpga/rtl/gth_i2c_init.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/HXT100G/fpga/rtl/i2c_master.v b/example/HXT100G/fpga/rtl/i2c_master.v index 61a313ddb..95d3a5212 100644 --- a/example/HXT100G/fpga/rtl/i2c_master.v +++ b/example/HXT100G/fpga/rtl/i2c_master.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/HXT100G/fpga/rtl/sync_reset.v b/example/HXT100G/fpga/rtl/sync_reset.v index 20622fd64..fe097029f 100644 --- a/example/HXT100G/fpga/rtl/sync_reset.v +++ b/example/HXT100G/fpga/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/HXT100G/fpga/rtl/sync_signal.v b/example/HXT100G/fpga/rtl/sync_signal.v index 1b8a32328..b2a8ce3de 100644 --- a/example/HXT100G/fpga/rtl/sync_signal.v +++ b/example/HXT100G/fpga/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index 01d91209e..21e9b971d 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/example/HXT100G/fpga/tb/test_fpga_core.v b/example/HXT100G/fpga/tb/test_fpga_core.v index 7bfc8cc62..370c25e29 100644 --- a/example/HXT100G/fpga/tb/test_fpga_core.v +++ b/example/HXT100G/fpga/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/example/ML605/fpga_gmii/rtl/debounce_switch.v b/example/ML605/fpga_gmii/rtl/debounce_switch.v index ab84126ec..bb631cc35 100644 --- a/example/ML605/fpga_gmii/rtl/debounce_switch.v +++ b/example/ML605/fpga_gmii/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_gmii/rtl/fpga.v b/example/ML605/fpga_gmii/rtl/fpga.v index 372607107..566fd7547 100644 --- a/example/ML605/fpga_gmii/rtl/fpga.v +++ b/example/ML605/fpga_gmii/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_gmii/rtl/fpga_core.v b/example/ML605/fpga_gmii/rtl/fpga_core.v index 37a1721bd..8555af5c5 100644 --- a/example/ML605/fpga_gmii/rtl/fpga_core.v +++ b/example/ML605/fpga_gmii/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_gmii/rtl/sync_reset.v b/example/ML605/fpga_gmii/rtl/sync_reset.v index 558a67605..acbcf1c6e 100644 --- a/example/ML605/fpga_gmii/rtl/sync_reset.v +++ b/example/ML605/fpga_gmii/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_gmii/rtl/sync_signal.v b/example/ML605/fpga_gmii/rtl/sync_signal.v index 1b8a32328..b2a8ce3de 100644 --- a/example/ML605/fpga_gmii/rtl/sync_signal.v +++ b/example/ML605/fpga_gmii/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_gmii/tb/test_fpga_core.py b/example/ML605/fpga_gmii/tb/test_fpga_core.py index 8ec5d3e6d..cfc769658 100755 --- a/example/ML605/fpga_gmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_gmii/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/ML605/fpga_gmii/tb/test_fpga_core.v b/example/ML605/fpga_gmii/tb/test_fpga_core.v index 19a803b6b..b237ed924 100644 --- a/example/ML605/fpga_gmii/tb/test_fpga_core.v +++ b/example/ML605/fpga_gmii/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/ML605/fpga_rgmii/rtl/debounce_switch.v b/example/ML605/fpga_rgmii/rtl/debounce_switch.v index ab84126ec..bb631cc35 100644 --- a/example/ML605/fpga_rgmii/rtl/debounce_switch.v +++ b/example/ML605/fpga_rgmii/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_rgmii/rtl/fpga.v b/example/ML605/fpga_rgmii/rtl/fpga.v index 325031ca4..ba445b48c 100644 --- a/example/ML605/fpga_rgmii/rtl/fpga.v +++ b/example/ML605/fpga_rgmii/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_rgmii/rtl/fpga_core.v b/example/ML605/fpga_rgmii/rtl/fpga_core.v index 425f92b62..f48d841fc 100644 --- a/example/ML605/fpga_rgmii/rtl/fpga_core.v +++ b/example/ML605/fpga_rgmii/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_rgmii/rtl/sync_reset.v b/example/ML605/fpga_rgmii/rtl/sync_reset.v index 558a67605..acbcf1c6e 100644 --- a/example/ML605/fpga_rgmii/rtl/sync_reset.v +++ b/example/ML605/fpga_rgmii/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_rgmii/rtl/sync_signal.v b/example/ML605/fpga_rgmii/rtl/sync_signal.v index 1b8a32328..b2a8ce3de 100644 --- a/example/ML605/fpga_rgmii/rtl/sync_signal.v +++ b/example/ML605/fpga_rgmii/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_rgmii/tb/test_fpga_core.py b/example/ML605/fpga_rgmii/tb/test_fpga_core.py index 6df143517..544dc88e6 100755 --- a/example/ML605/fpga_rgmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_rgmii/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/ML605/fpga_rgmii/tb/test_fpga_core.v b/example/ML605/fpga_rgmii/tb/test_fpga_core.v index 61e64c700..a2c412486 100644 --- a/example/ML605/fpga_rgmii/tb/test_fpga_core.v +++ b/example/ML605/fpga_rgmii/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/ML605/fpga_sgmii/rtl/debounce_switch.v b/example/ML605/fpga_sgmii/rtl/debounce_switch.v index ab84126ec..bb631cc35 100644 --- a/example/ML605/fpga_sgmii/rtl/debounce_switch.v +++ b/example/ML605/fpga_sgmii/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_sgmii/rtl/fpga.v b/example/ML605/fpga_sgmii/rtl/fpga.v index ced6a431c..74f43503e 100644 --- a/example/ML605/fpga_sgmii/rtl/fpga.v +++ b/example/ML605/fpga_sgmii/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_sgmii/rtl/fpga_core.v b/example/ML605/fpga_sgmii/rtl/fpga_core.v index 17bc74a67..e686c18d0 100644 --- a/example/ML605/fpga_sgmii/rtl/fpga_core.v +++ b/example/ML605/fpga_sgmii/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_sgmii/rtl/sync_reset.v b/example/ML605/fpga_sgmii/rtl/sync_reset.v index 558a67605..acbcf1c6e 100644 --- a/example/ML605/fpga_sgmii/rtl/sync_reset.v +++ b/example/ML605/fpga_sgmii/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_sgmii/rtl/sync_signal.v b/example/ML605/fpga_sgmii/rtl/sync_signal.v index 1b8a32328..b2a8ce3de 100644 --- a/example/ML605/fpga_sgmii/rtl/sync_signal.v +++ b/example/ML605/fpga_sgmii/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/ML605/fpga_sgmii/tb/test_fpga_core.py b/example/ML605/fpga_sgmii/tb/test_fpga_core.py index ba19006bd..16c4495ec 100755 --- a/example/ML605/fpga_sgmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_sgmii/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/ML605/fpga_sgmii/tb/test_fpga_core.v b/example/ML605/fpga_sgmii/tb/test_fpga_core.v index b354d4c59..5b0f8d538 100644 --- a/example/ML605/fpga_sgmii/tb/test_fpga_core.v +++ b/example/ML605/fpga_sgmii/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/NexysVideo/fpga/rtl/debounce_switch.v b/example/NexysVideo/fpga/rtl/debounce_switch.v index ab84126ec..bb631cc35 100644 --- a/example/NexysVideo/fpga/rtl/debounce_switch.v +++ b/example/NexysVideo/fpga/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/NexysVideo/fpga/rtl/fpga.v b/example/NexysVideo/fpga/rtl/fpga.v index 82dca776a..4a7925caa 100644 --- a/example/NexysVideo/fpga/rtl/fpga.v +++ b/example/NexysVideo/fpga/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/NexysVideo/fpga/rtl/fpga_core.v b/example/NexysVideo/fpga/rtl/fpga_core.v index 7cf1eada8..f28d6fe3a 100644 --- a/example/NexysVideo/fpga/rtl/fpga_core.v +++ b/example/NexysVideo/fpga/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/NexysVideo/fpga/rtl/sync_reset.v b/example/NexysVideo/fpga/rtl/sync_reset.v index 558a67605..acbcf1c6e 100644 --- a/example/NexysVideo/fpga/rtl/sync_reset.v +++ b/example/NexysVideo/fpga/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/NexysVideo/fpga/rtl/sync_signal.v b/example/NexysVideo/fpga/rtl/sync_signal.v index 1b8a32328..b2a8ce3de 100644 --- a/example/NexysVideo/fpga/rtl/sync_signal.v +++ b/example/NexysVideo/fpga/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.py b/example/NexysVideo/fpga/tb/test_fpga_core.py index ec01cbd15..b0ab838c9 100755 --- a/example/NexysVideo/fpga/tb/test_fpga_core.py +++ b/example/NexysVideo/fpga/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.v b/example/NexysVideo/fpga/tb/test_fpga_core.v index bb93be3aa..088a94d2c 100644 --- a/example/NexysVideo/fpga/tb/test_fpga_core.v +++ b/example/NexysVideo/fpga/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/VCU108/fpga_10g/rtl/debounce_switch.v b/example/VCU108/fpga_10g/rtl/debounce_switch.v index ab84126ec..bb631cc35 100644 --- a/example/VCU108/fpga_10g/rtl/debounce_switch.v +++ b/example/VCU108/fpga_10g/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/VCU108/fpga_10g/rtl/fpga.v b/example/VCU108/fpga_10g/rtl/fpga.v index c8e71796b..e6d3d61a0 100644 --- a/example/VCU108/fpga_10g/rtl/fpga.v +++ b/example/VCU108/fpga_10g/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index b497bbc73..129f3ccdb 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/VCU108/fpga_10g/rtl/i2c_master.v b/example/VCU108/fpga_10g/rtl/i2c_master.v index 61a313ddb..95d3a5212 100644 --- a/example/VCU108/fpga_10g/rtl/i2c_master.v +++ b/example/VCU108/fpga_10g/rtl/i2c_master.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/VCU108/fpga_10g/rtl/si570_i2c_init.v b/example/VCU108/fpga_10g/rtl/si570_i2c_init.v index 8a852a4ec..cea21ed6e 100644 --- a/example/VCU108/fpga_10g/rtl/si570_i2c_init.v +++ b/example/VCU108/fpga_10g/rtl/si570_i2c_init.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/VCU108/fpga_10g/rtl/sync_reset.v b/example/VCU108/fpga_10g/rtl/sync_reset.v index 558a67605..acbcf1c6e 100644 --- a/example/VCU108/fpga_10g/rtl/sync_reset.v +++ b/example/VCU108/fpga_10g/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/VCU108/fpga_10g/rtl/sync_signal.v b/example/VCU108/fpga_10g/rtl/sync_signal.v index 1b8a32328..b2a8ce3de 100644 --- a/example/VCU108/fpga_10g/rtl/sync_signal.v +++ b/example/VCU108/fpga_10g/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index 5a370e32b..061c65f3f 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.v b/example/VCU108/fpga_10g/tb/test_fpga_core.v index 56ea34739..6093a0a61 100644 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/example/VCU108/fpga_1g/rtl/debounce_switch.v b/example/VCU108/fpga_1g/rtl/debounce_switch.v index ab84126ec..bb631cc35 100644 --- a/example/VCU108/fpga_1g/rtl/debounce_switch.v +++ b/example/VCU108/fpga_1g/rtl/debounce_switch.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/VCU108/fpga_1g/rtl/fpga.v b/example/VCU108/fpga_1g/rtl/fpga.v index cfa3add86..87a59a66e 100644 --- a/example/VCU108/fpga_1g/rtl/fpga.v +++ b/example/VCU108/fpga_1g/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v index 8e21f12b6..e8ad51b27 100644 --- a/example/VCU108/fpga_1g/rtl/fpga_core.v +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/VCU108/fpga_1g/rtl/sync_reset.v b/example/VCU108/fpga_1g/rtl/sync_reset.v index 558a67605..acbcf1c6e 100644 --- a/example/VCU108/fpga_1g/rtl/sync_reset.v +++ b/example/VCU108/fpga_1g/rtl/sync_reset.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/VCU108/fpga_1g/rtl/sync_signal.v b/example/VCU108/fpga_1g/rtl/sync_signal.v index 1b8a32328..b2a8ce3de 100644 --- a/example/VCU108/fpga_1g/rtl/sync_signal.v +++ b/example/VCU108/fpga_1g/rtl/sync_signal.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py index 6d3ee4927..0302962b2 100755 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.v b/example/VCU108/fpga_1g/tb/test_fpga_core.v index c36f2a9d6..aa29c4011 100644 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/arp.v b/rtl/arp.v index 0c9b11b6c..ad80fe305 100644 --- a/rtl/arp.v +++ b/rtl/arp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/arp_64.v b/rtl/arp_64.v index a7cecdb44..82c19e3f5 100644 --- a/rtl/arp_64.v +++ b/rtl/arp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/arp_cache.v b/rtl/arp_cache.v index 1e09e691f..f57434ed6 100644 --- a/rtl/arp_cache.v +++ b/rtl/arp_cache.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index 2539149bf..63782d2e2 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index 7ce906fe5..b5e57ad8f 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index 9640d2ada..c3c40b13d 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index 2c883d780..1b89651c4 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_eth_fcs.v b/rtl/axis_eth_fcs.v index 5dae62bf3..b9bb8172f 100644 --- a/rtl/axis_eth_fcs.v +++ b/rtl/axis_eth_fcs.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/axis_eth_fcs_64.v b/rtl/axis_eth_fcs_64.v index ef7b6ee99..dfc489645 100644 --- a/rtl/axis_eth_fcs_64.v +++ b/rtl/axis_eth_fcs_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v index 3c9de7130..c7b18a137 100644 --- a/rtl/axis_eth_fcs_check.v +++ b/rtl/axis_eth_fcs_check.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index a97de8bbe..fb8104b1a 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v index cf5df1bb9..ab5083d0b 100644 --- a/rtl/axis_eth_fcs_insert.v +++ b/rtl/axis_eth_fcs_insert.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/axis_eth_fcs_insert_64.v b/rtl/axis_eth_fcs_insert_64.v index 6c9afe0d7..aa3c3dbad 100644 --- a/rtl/axis_eth_fcs_insert_64.v +++ b/rtl/axis_eth_fcs_insert_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/axis_gmii_rx.v b/rtl/axis_gmii_rx.v index 7505c75cb..0a5c0c04c 100644 --- a/rtl/axis_gmii_rx.v +++ b/rtl/axis_gmii_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index f4be5a3fb..06cc6f5f3 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_arb_mux_2.v b/rtl/eth_arb_mux_2.v index 6428b8d96..705830b81 100644 --- a/rtl/eth_arb_mux_2.v +++ b/rtl/eth_arb_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_arb_mux_4.v b/rtl/eth_arb_mux_4.v index 0db514131..3a8c1e6e0 100644 --- a/rtl/eth_arb_mux_4.v +++ b/rtl/eth_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_arb_mux_64_2.v b/rtl/eth_arb_mux_64_2.v index 09d5847cf..7e8553be4 100644 --- a/rtl/eth_arb_mux_64_2.v +++ b/rtl/eth_arb_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_arb_mux_64_4.v b/rtl/eth_arb_mux_64_4.v index eb8add575..b46b088c4 100644 --- a/rtl/eth_arb_mux_64_4.v +++ b/rtl/eth_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index eed87c912..e036f3cf0 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index b921e4a64..932adee76 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index 24d74c515..ab09c79cd 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index 2e82864c3..a74e182eb 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_demux_4.v b/rtl/eth_demux_4.v index ee3239413..3f1758eae 100644 --- a/rtl/eth_demux_4.v +++ b/rtl/eth_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_demux_64_4.v b/rtl/eth_demux_64_4.v index d97158e59..96105ccef 100644 --- a/rtl/eth_demux_64_4.v +++ b/rtl/eth_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index e6673c59e..3022ae555 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index aa5f8e31f..6ef32e9fa 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index 5ad826aa4..b9cb66c97 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 90f7a9ffe..ed2b955a2 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v index b46e31606..35195addb 100644 --- a/rtl/eth_mac_1g.v +++ b/rtl/eth_mac_1g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index f26507637..b8941b259 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_1g_gmii.v b/rtl/eth_mac_1g_gmii.v index 5c476b1cd..c0f4ed4d7 100644 --- a/rtl/eth_mac_1g_gmii.v +++ b/rtl/eth_mac_1g_gmii.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_1g_gmii_fifo.v b/rtl/eth_mac_1g_gmii_fifo.v index f964a01a3..bb4f1c661 100644 --- a/rtl/eth_mac_1g_gmii_fifo.v +++ b/rtl/eth_mac_1g_gmii_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_1g_rgmii.v b/rtl/eth_mac_1g_rgmii.v index a7650a7c5..e1b01902c 100644 --- a/rtl/eth_mac_1g_rgmii.v +++ b/rtl/eth_mac_1g_rgmii.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_1g_rgmii_fifo.v b/rtl/eth_mac_1g_rgmii_fifo.v index 599ef9627..fa925799e 100644 --- a/rtl/eth_mac_1g_rgmii_fifo.v +++ b/rtl/eth_mac_1g_rgmii_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v index 4e3a524ea..0f13d32ae 100644 --- a/rtl/eth_mac_1g_rx.v +++ b/rtl/eth_mac_1g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mac_1g_tx.v b/rtl/eth_mac_1g_tx.v index 7522ed35d..97dea3d92 100644 --- a/rtl/eth_mac_1g_tx.v +++ b/rtl/eth_mac_1g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/eth_mux_2.v b/rtl/eth_mux_2.v index 9a80d6619..d7e2677a4 100644 --- a/rtl/eth_mux_2.v +++ b/rtl/eth_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v index a85db466e..7ae3eca90 100644 --- a/rtl/eth_mux_4.v +++ b/rtl/eth_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_mux_64_2.v b/rtl/eth_mux_64_2.v index ee4845ab3..114820c7a 100644 --- a/rtl/eth_mux_64_2.v +++ b/rtl/eth_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v index 74e18be02..6145efc55 100644 --- a/rtl/eth_mux_64_4.v +++ b/rtl/eth_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/gmii_phy_if.v b/rtl/gmii_phy_if.v index 347c20ce1..be6ea4ec3 100644 --- a/rtl/gmii_phy_if.v +++ b/rtl/gmii_phy_if.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/iddr.v b/rtl/iddr.v index c1b73c735..f3fb61997 100644 --- a/rtl/iddr.v +++ b/rtl/iddr.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/ip.v b/rtl/ip.v index 4b9853d62..d76e9a8df 100644 --- a/rtl/ip.v +++ b/rtl/ip.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_64.v b/rtl/ip_64.v index 5185d7ca7..476cc979f 100644 --- a/rtl/ip_64.v +++ b/rtl/ip_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_arb_mux_2.v b/rtl/ip_arb_mux_2.v index 30f3e3094..95aad55db 100644 --- a/rtl/ip_arb_mux_2.v +++ b/rtl/ip_arb_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_arb_mux_4.v b/rtl/ip_arb_mux_4.v index 60e0bd57f..db9797dfc 100644 --- a/rtl/ip_arb_mux_4.v +++ b/rtl/ip_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_arb_mux_64_2.v b/rtl/ip_arb_mux_64_2.v index 4b0e38c1e..ce509bd76 100644 --- a/rtl/ip_arb_mux_64_2.v +++ b/rtl/ip_arb_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_arb_mux_64_4.v b/rtl/ip_arb_mux_64_4.v index 9033f8659..611ae431c 100644 --- a/rtl/ip_arb_mux_64_4.v +++ b/rtl/ip_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_complete.v b/rtl/ip_complete.v index 2fcb588bf..0833a2ef2 100644 --- a/rtl/ip_complete.v +++ b/rtl/ip_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_complete_64.v b/rtl/ip_complete_64.v index 9e79b095b..7134e017b 100644 --- a/rtl/ip_complete_64.v +++ b/rtl/ip_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_demux_4.v b/rtl/ip_demux_4.v index 0501be687..e45a196e1 100644 --- a/rtl/ip_demux_4.v +++ b/rtl/ip_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_demux_64_4.v b/rtl/ip_demux_64_4.v index 68ae735fd..b48f10e53 100644 --- a/rtl/ip_demux_64_4.v +++ b/rtl/ip_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index 129f96998..008b53537 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 8a794ddf9..246623e2f 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 9db9c4461..5a7f2da05 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index ae793f660..59c356985 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_mux_2.v b/rtl/ip_mux_2.v index 3e3ac3d73..5a41c2675 100644 --- a/rtl/ip_mux_2.v +++ b/rtl/ip_mux_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_mux_4.v b/rtl/ip_mux_4.v index 0108c3b47..0e7cdfb14 100644 --- a/rtl/ip_mux_4.v +++ b/rtl/ip_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_mux_64_2.v b/rtl/ip_mux_64_2.v index f1183904d..ae7465a1d 100644 --- a/rtl/ip_mux_64_2.v +++ b/rtl/ip_mux_64_2.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_mux_64_4.v b/rtl/ip_mux_64_4.v index bbf066db1..53fab6513 100644 --- a/rtl/ip_mux_64_4.v +++ b/rtl/ip_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/lfsr.v b/rtl/lfsr.v index 6325f9c57..1548daef7 100644 --- a/rtl/lfsr.v +++ b/rtl/lfsr.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/oddr.v b/rtl/oddr.v index 433d1f0ea..52afbd826 100644 --- a/rtl/oddr.v +++ b/rtl/oddr.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/rgmii_phy_if.v b/rtl/rgmii_phy_if.v index 7edc6e747..15f5943f5 100644 --- a/rtl/rgmii_phy_if.v +++ b/rtl/rgmii_phy_if.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/rtl/ssio_ddr_in.v b/rtl/ssio_ddr_in.v index 0597712cd..4c2f6f421 100644 --- a/rtl/ssio_ddr_in.v +++ b/rtl/ssio_ddr_in.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/ssio_ddr_in_diff.v b/rtl/ssio_ddr_in_diff.v index ae7562e0e..cab427915 100644 --- a/rtl/ssio_ddr_in_diff.v +++ b/rtl/ssio_ddr_in_diff.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/ssio_ddr_out.v b/rtl/ssio_ddr_out.v index 387708154..c77aa691e 100644 --- a/rtl/ssio_ddr_out.v +++ b/rtl/ssio_ddr_out.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/ssio_ddr_out_diff.v b/rtl/ssio_ddr_out_diff.v index 766467096..ba1beadc4 100644 --- a/rtl/ssio_ddr_out_diff.v +++ b/rtl/ssio_ddr_out_diff.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/ssio_sdr_in.v b/rtl/ssio_sdr_in.v index aff063d89..09797f4c8 100644 --- a/rtl/ssio_sdr_in.v +++ b/rtl/ssio_sdr_in.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/ssio_sdr_in_diff.v b/rtl/ssio_sdr_in_diff.v index 60c37f5d2..625014389 100644 --- a/rtl/ssio_sdr_in_diff.v +++ b/rtl/ssio_sdr_in_diff.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/ssio_sdr_out.v b/rtl/ssio_sdr_out.v index e63b52e7a..702f9060a 100644 --- a/rtl/ssio_sdr_out.v +++ b/rtl/ssio_sdr_out.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/ssio_sdr_out_diff.v b/rtl/ssio_sdr_out_diff.v index e6543a2f3..5fe26076b 100644 --- a/rtl/ssio_sdr_out_diff.v +++ b/rtl/ssio_sdr_out_diff.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/udp.v b/rtl/udp.v index e4caa3435..b32930176 100644 --- a/rtl/udp.v +++ b/rtl/udp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_64.v b/rtl/udp_64.v index 1f0f09d43..75b199652 100644 --- a/rtl/udp_64.v +++ b/rtl/udp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_arb_mux_4.v b/rtl/udp_arb_mux_4.v index db35b9061..3c2a1b292 100644 --- a/rtl/udp_arb_mux_4.v +++ b/rtl/udp_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_arb_mux_64_4.v b/rtl/udp_arb_mux_64_4.v index 4a3297e83..93c6ae9a0 100644 --- a/rtl/udp_arb_mux_64_4.v +++ b/rtl/udp_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_checksum_gen.v b/rtl/udp_checksum_gen.v index 549694b90..8f63e78bb 100644 --- a/rtl/udp_checksum_gen.v +++ b/rtl/udp_checksum_gen.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/udp_checksum_gen_64.v b/rtl/udp_checksum_gen_64.v index 5ebed86d2..69b8ae3e8 100644 --- a/rtl/udp_checksum_gen_64.v +++ b/rtl/udp_checksum_gen_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v index 199420e33..1633f1c18 100644 --- a/rtl/udp_complete.v +++ b/rtl/udp_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v index 92990922c..fec881149 100644 --- a/rtl/udp_complete_64.v +++ b/rtl/udp_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_demux_4.v b/rtl/udp_demux_4.v index 84f3dbbf7..a97ec4965 100644 --- a/rtl/udp_demux_4.v +++ b/rtl/udp_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_demux_64_4.v b/rtl/udp_demux_64_4.v index 2d37c5b71..8817a2097 100644 --- a/rtl/udp_demux_64_4.v +++ b/rtl/udp_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v index f71e49d7e..5410905fe 100644 --- a/rtl/udp_ip_rx.v +++ b/rtl/udp_ip_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index 3ee5a8864..491cf3577 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index c9461059e..5de078593 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index b18385628..6771af971 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_mux_4.v b/rtl/udp_mux_4.v index caea094dd..2e6c31871 100644 --- a/rtl/udp_mux_4.v +++ b/rtl/udp_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_mux_64_4.v b/rtl/udp_mux_64_4.v index 4dfdb9c2a..e336b226a 100644 --- a/rtl/udp_mux_64_4.v +++ b/rtl/udp_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/xgmii_deinterleave.v b/rtl/xgmii_deinterleave.v index 76b92aa6c..5410bc955 100644 --- a/rtl/xgmii_deinterleave.v +++ b/rtl/xgmii_deinterleave.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/rtl/xgmii_interleave.v b/rtl/xgmii_interleave.v index ce8aa3142..cf365e2f1 100644 --- a/rtl/xgmii_interleave.v +++ b/rtl/xgmii_interleave.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/arp_ep.py b/tb/arp_ep.py index e8ac2fdc3..9f07516bf 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/eth_ep.py b/tb/eth_ep.py index ba486b2e4..0949454d7 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index 0622a3a18..fb53b2ba1 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/ip_ep.py b/tb/ip_ep.py index 5cebc0907..1f8c41387 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/rgmii_ep.py b/tb/rgmii_ep.py index b4f689887..3a46ba0cf 100644 --- a/tb/rgmii_ep.py +++ b/tb/rgmii_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp.py b/tb/test_arp.py index 296703f98..f7d86a53b 100755 --- a/tb/test_arp.py +++ b/tb/test_arp.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp.v b/tb/test_arp.v index 6f9f0841b..98b938297 100644 --- a/tb/test_arp.v +++ b/tb/test_arp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_64.py b/tb/test_arp_64.py index 42f47ccc0..2f6c763d1 100755 --- a/tb/test_arp_64.py +++ b/tb/test_arp_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_64.v b/tb/test_arp_64.v index 28e84a9f7..aea5f3533 100644 --- a/tb/test_arp_64.v +++ b/tb/test_arp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_cache.py b/tb/test_arp_cache.py index b563f8b9f..a956d9b09 100755 --- a/tb/test_arp_cache.py +++ b/tb/test_arp_cache.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_cache.v b/tb/test_arp_cache.v index 576847148..8ee077d0c 100755 --- a/tb/test_arp_cache.v +++ b/tb/test_arp_cache.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index c408d4ba3..64cc9bf1f 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_eth_rx.v b/tb/test_arp_eth_rx.v index cf46bab9d..4f2fa860d 100644 --- a/tb/test_arp_eth_rx.v +++ b/tb/test_arp_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index 4bb67b266..a15b2eef4 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_eth_rx_64.v b/tb/test_arp_eth_rx_64.v index 97429aff8..5e9194654 100644 --- a/tb/test_arp_eth_rx_64.v +++ b/tb/test_arp_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py index 025aba105..27ad7c2fe 100755 --- a/tb/test_arp_eth_tx.py +++ b/tb/test_arp_eth_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_eth_tx.v b/tb/test_arp_eth_tx.v index eb976fae5..30ea9c595 100644 --- a/tb/test_arp_eth_tx.v +++ b/tb/test_arp_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py index 34af70453..47e34e744 100755 --- a/tb/test_arp_eth_tx_64.py +++ b/tb/test_arp_eth_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_arp_eth_tx_64.v b/tb/test_arp_eth_tx_64.v index 60b192b90..37e3bbb0b 100644 --- a/tb/test_arp_eth_tx_64.v +++ b/tb/test_arp_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_axis_eth_fcs.py b/tb/test_axis_eth_fcs.py index 43486c6ae..4952c827f 100755 --- a/tb/test_axis_eth_fcs.py +++ b/tb/test_axis_eth_fcs.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs.v b/tb/test_axis_eth_fcs.v index af9e06f81..c22034af1 100644 --- a/tb/test_axis_eth_fcs.v +++ b/tb/test_axis_eth_fcs.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_64.py b/tb/test_axis_eth_fcs_64.py index 511cc7554..8da4ae571 100755 --- a/tb/test_axis_eth_fcs_64.py +++ b/tb/test_axis_eth_fcs_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_64.v b/tb/test_axis_eth_fcs_64.v index 4a74ce25f..cd84cec27 100644 --- a/tb/test_axis_eth_fcs_64.v +++ b/tb/test_axis_eth_fcs_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index 570efcd59..8baec66e3 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_check.v b/tb/test_axis_eth_fcs_check.v index 110971176..effe04d08 100644 --- a/tb/test_axis_eth_fcs_check.v +++ b/tb/test_axis_eth_fcs_check.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_check_64.py b/tb/test_axis_eth_fcs_check_64.py index 4c560ee23..c8fd9a377 100755 --- a/tb/test_axis_eth_fcs_check_64.py +++ b/tb/test_axis_eth_fcs_check_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_check_64.v b/tb/test_axis_eth_fcs_check_64.v index d1791c42d..8e360893b 100644 --- a/tb/test_axis_eth_fcs_check_64.v +++ b/tb/test_axis_eth_fcs_check_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index 3613e03c2..7224cd89f 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_insert.v b/tb/test_axis_eth_fcs_insert.v index d954c4024..e64a6a913 100644 --- a/tb/test_axis_eth_fcs_insert.v +++ b/tb/test_axis_eth_fcs_insert.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_insert_64.py b/tb/test_axis_eth_fcs_insert_64.py index e6ce9a3e4..eb0983b06 100755 --- a/tb/test_axis_eth_fcs_insert_64.py +++ b/tb/test_axis_eth_fcs_insert_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_insert_64.v b/tb/test_axis_eth_fcs_insert_64.v index dce0d6f46..143f3ae3d 100644 --- a/tb/test_axis_eth_fcs_insert_64.v +++ b/tb/test_axis_eth_fcs_insert_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_insert_64_pad.py b/tb/test_axis_eth_fcs_insert_64_pad.py index 70fa55405..4d4ea070f 100755 --- a/tb/test_axis_eth_fcs_insert_64_pad.py +++ b/tb/test_axis_eth_fcs_insert_64_pad.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_insert_64_pad.v b/tb/test_axis_eth_fcs_insert_64_pad.v index 9bf1c52f9..53b073cb2 100644 --- a/tb/test_axis_eth_fcs_insert_64_pad.v +++ b/tb/test_axis_eth_fcs_insert_64_pad.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_insert_pad.py b/tb/test_axis_eth_fcs_insert_pad.py index 813d78653..e9d877a12 100755 --- a/tb/test_axis_eth_fcs_insert_pad.py +++ b/tb/test_axis_eth_fcs_insert_pad.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_eth_fcs_insert_pad.v b/tb/test_axis_eth_fcs_insert_pad.v index 8c900a673..f82b780b0 100644 --- a/tb/test_axis_eth_fcs_insert_pad.v +++ b/tb/test_axis_eth_fcs_insert_pad.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_gmii_rx.py b/tb/test_axis_gmii_rx.py index bdfc3078c..71e743d0c 100755 --- a/tb/test_axis_gmii_rx.py +++ b/tb/test_axis_gmii_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_gmii_rx.v b/tb/test_axis_gmii_rx.v index 5a15721f7..67f13d400 100644 --- a/tb/test_axis_gmii_rx.v +++ b/tb/test_axis_gmii_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_gmii_tx.py b/tb/test_axis_gmii_tx.py index d27c6c7cd..895095252 100755 --- a/tb/test_axis_gmii_tx.py +++ b/tb/test_axis_gmii_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_axis_gmii_tx.v b/tb/test_axis_gmii_tx.v index b1dba252b..86d33168b 100644 --- a/tb/test_axis_gmii_tx.v +++ b/tb/test_axis_gmii_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_arb_mux_4.py b/tb/test_eth_arb_mux_4.py index 38d04029d..3a1788e3d 100755 --- a/tb/test_eth_arb_mux_4.py +++ b/tb/test_eth_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_arb_mux_4.v b/tb/test_eth_arb_mux_4.v index 106cc18df..55e8bb8dd 100644 --- a/tb/test_eth_arb_mux_4.v +++ b/tb/test_eth_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_arb_mux_64_4.py b/tb/test_eth_arb_mux_64_4.py index e0bdcdffc..f91254821 100755 --- a/tb/test_eth_arb_mux_64_4.py +++ b/tb/test_eth_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_arb_mux_64_4.v b/tb/test_eth_arb_mux_64_4.v index 1f133936f..3a8c30d77 100644 --- a/tb/test_eth_arb_mux_64_4.v +++ b/tb/test_eth_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index de6e60023..1901478cc 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_axis_rx.v b/tb/test_eth_axis_rx.v index ced1db97e..f83624752 100644 --- a/tb/test_eth_axis_rx.v +++ b/tb/test_eth_axis_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index de4c16d4a..b1fae272b 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_axis_rx_64.v b/tb/test_eth_axis_rx_64.v index 7a9ceb1f1..fcd5dabde 100644 --- a/tb/test_eth_axis_rx_64.v +++ b/tb/test_eth_axis_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py index a4749a017..d19eb90a1 100755 --- a/tb/test_eth_axis_tx.py +++ b/tb/test_eth_axis_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_axis_tx.v b/tb/test_eth_axis_tx.v index 6207fd740..3ce6b672c 100644 --- a/tb/test_eth_axis_tx.v +++ b/tb/test_eth_axis_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py index 9ac8fe3ef..70e1ed769 100755 --- a/tb/test_eth_axis_tx_64.py +++ b/tb/test_eth_axis_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_axis_tx_64.v b/tb/test_eth_axis_tx_64.v index a1901ce2f..045d13ddb 100644 --- a/tb/test_eth_axis_tx_64.v +++ b/tb/test_eth_axis_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_demux_4.py b/tb/test_eth_demux_4.py index 782e5f221..905b58993 100755 --- a/tb/test_eth_demux_4.py +++ b/tb/test_eth_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_demux_4.v b/tb/test_eth_demux_4.v index 2d06c3a97..e6f00489a 100644 --- a/tb/test_eth_demux_4.v +++ b/tb/test_eth_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_demux_64_4.py b/tb/test_eth_demux_64_4.py index 27f0c1c17..56ad331af 100755 --- a/tb/test_eth_demux_64_4.py +++ b/tb/test_eth_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_demux_64_4.v b/tb/test_eth_demux_64_4.v index cb2c17c55..b809b93a1 100644 --- a/tb/test_eth_demux_64_4.v +++ b/tb/test_eth_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_mac_10g.py b/tb/test_eth_mac_10g.py index bb41d0426..42f8510a6 100755 --- a/tb/test_eth_mac_10g.py +++ b/tb/test_eth_mac_10g.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_10g.v b/tb/test_eth_mac_10g.v index 242657c57..3d2d2f9d4 100644 --- a/tb/test_eth_mac_10g.v +++ b/tb/test_eth_mac_10g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_10g_fifo.py b/tb/test_eth_mac_10g_fifo.py index 3920f7c67..3ff39da69 100755 --- a/tb/test_eth_mac_10g_fifo.py +++ b/tb/test_eth_mac_10g_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_10g_fifo.v b/tb/test_eth_mac_10g_fifo.v index 720a7527f..ceaa2a1f0 100644 --- a/tb/test_eth_mac_10g_fifo.v +++ b/tb/test_eth_mac_10g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_10g_rx.py b/tb/test_eth_mac_10g_rx.py index a08bf7885..15a173cff 100755 --- a/tb/test_eth_mac_10g_rx.py +++ b/tb/test_eth_mac_10g_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_10g_rx.v b/tb/test_eth_mac_10g_rx.v index a538cbcab..1eeed9e48 100644 --- a/tb/test_eth_mac_10g_rx.v +++ b/tb/test_eth_mac_10g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_10g_tx.py b/tb/test_eth_mac_10g_tx.py index 862d105cf..665a10a79 100755 --- a/tb/test_eth_mac_10g_tx.py +++ b/tb/test_eth_mac_10g_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_10g_tx.v b/tb/test_eth_mac_10g_tx.v index 405868261..14505fc0e 100644 --- a/tb/test_eth_mac_10g_tx.v +++ b/tb/test_eth_mac_10g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index 41050629a..06cf5fe62 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g.v b/tb/test_eth_mac_1g.v index dff830707..387808879 100644 --- a/tb/test_eth_mac_1g.v +++ b/tb/test_eth_mac_1g.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py index d9a2e94ac..b324bf018 100755 --- a/tb/test_eth_mac_1g_fifo.py +++ b/tb/test_eth_mac_1g_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_fifo.v b/tb/test_eth_mac_1g_fifo.v index e835388a4..0b20f9235 100644 --- a/tb/test_eth_mac_1g_fifo.v +++ b/tb/test_eth_mac_1g_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_gmii.py b/tb/test_eth_mac_1g_gmii.py index 2495eeab3..088e689c1 100755 --- a/tb/test_eth_mac_1g_gmii.py +++ b/tb/test_eth_mac_1g_gmii.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_gmii.v b/tb/test_eth_mac_1g_gmii.v index 22ec338c4..1a14270fc 100644 --- a/tb/test_eth_mac_1g_gmii.v +++ b/tb/test_eth_mac_1g_gmii.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_gmii_fifo.py b/tb/test_eth_mac_1g_gmii_fifo.py index 1f6af9b29..903d75396 100755 --- a/tb/test_eth_mac_1g_gmii_fifo.py +++ b/tb/test_eth_mac_1g_gmii_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_gmii_fifo.v b/tb/test_eth_mac_1g_gmii_fifo.v index 49ceaf86a..04da01928 100644 --- a/tb/test_eth_mac_1g_gmii_fifo.v +++ b/tb/test_eth_mac_1g_gmii_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_rgmii.py b/tb/test_eth_mac_1g_rgmii.py index 37235904a..c7fd94f02 100755 --- a/tb/test_eth_mac_1g_rgmii.py +++ b/tb/test_eth_mac_1g_rgmii.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_rgmii.v b/tb/test_eth_mac_1g_rgmii.v index c443998dd..918acf721 100644 --- a/tb/test_eth_mac_1g_rgmii.v +++ b/tb/test_eth_mac_1g_rgmii.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_rgmii_fifo.py b/tb/test_eth_mac_1g_rgmii_fifo.py index f6eacf5fe..01d9ec447 100755 --- a/tb/test_eth_mac_1g_rgmii_fifo.py +++ b/tb/test_eth_mac_1g_rgmii_fifo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_rgmii_fifo.v b/tb/test_eth_mac_1g_rgmii_fifo.v index 1ec057a69..7664454ca 100644 --- a/tb/test_eth_mac_1g_rgmii_fifo.v +++ b/tb/test_eth_mac_1g_rgmii_fifo.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py index 94ef6071c..abf1c088d 100755 --- a/tb/test_eth_mac_1g_rx.py +++ b/tb/test_eth_mac_1g_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_rx.v b/tb/test_eth_mac_1g_rx.v index 2f481bd37..2c174d5ed 100644 --- a/tb/test_eth_mac_1g_rx.v +++ b/tb/test_eth_mac_1g_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index 0a735d90d..5bda44da1 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mac_1g_tx.v b/tb/test_eth_mac_1g_tx.v index 4c60cd65c..a0db6462e 100644 --- a/tb/test_eth_mac_1g_tx.v +++ b/tb/test_eth_mac_1g_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 diff --git a/tb/test_eth_mux_4.py b/tb/test_eth_mux_4.py index 8a624f81d..c8adc4b90 100755 --- a/tb/test_eth_mux_4.py +++ b/tb/test_eth_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_mux_4.v b/tb/test_eth_mux_4.v index bd466cb12..637ef1200 100644 --- a/tb/test_eth_mux_4.v +++ b/tb/test_eth_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_mux_64_4.py b/tb/test_eth_mux_64_4.py index 8ee0c857b..61b9860a9 100755 --- a/tb/test_eth_mux_64_4.py +++ b/tb/test_eth_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_eth_mux_64_4.v b/tb/test_eth_mux_64_4.v index 142d7f136..46d9110b5 100644 --- a/tb/test_eth_mux_64_4.v +++ b/tb/test_eth_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip.py b/tb/test_ip.py index d3aa7f453..2bc39b5c8 100755 --- a/tb/test_ip.py +++ b/tb/test_ip.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip.v b/tb/test_ip.v index d6d41e823..e1d967fce 100644 --- a/tb/test_ip.v +++ b/tb/test_ip.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_64.py b/tb/test_ip_64.py index cf94d2a20..450004847 100755 --- a/tb/test_ip_64.py +++ b/tb/test_ip_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_64.v b/tb/test_ip_64.v index 27a49b3cc..17865bf8c 100644 --- a/tb/test_ip_64.v +++ b/tb/test_ip_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_arb_mux_4.py b/tb/test_ip_arb_mux_4.py index 1c56c0300..8418ad7e0 100755 --- a/tb/test_ip_arb_mux_4.py +++ b/tb/test_ip_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_arb_mux_4.v b/tb/test_ip_arb_mux_4.v index 7a9e4d59e..5a14131b7 100644 --- a/tb/test_ip_arb_mux_4.v +++ b/tb/test_ip_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_arb_mux_64_4.py b/tb/test_ip_arb_mux_64_4.py index c7d1e841d..b1ca7e6da 100755 --- a/tb/test_ip_arb_mux_64_4.py +++ b/tb/test_ip_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_arb_mux_64_4.v b/tb/test_ip_arb_mux_64_4.v index 1b5634861..a8ef17a9c 100644 --- a/tb/test_ip_arb_mux_64_4.v +++ b/tb/test_ip_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_complete.py b/tb/test_ip_complete.py index 02ad1055e..12a54e554 100755 --- a/tb/test_ip_complete.py +++ b/tb/test_ip_complete.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_complete.v b/tb/test_ip_complete.v index bf419994b..6710822e4 100644 --- a/tb/test_ip_complete.v +++ b/tb/test_ip_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_complete_64.py b/tb/test_ip_complete_64.py index 1c59fc460..e2164bd40 100755 --- a/tb/test_ip_complete_64.py +++ b/tb/test_ip_complete_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_complete_64.v b/tb/test_ip_complete_64.v index 8b59a8d3b..58db828da 100644 --- a/tb/test_ip_complete_64.v +++ b/tb/test_ip_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_demux_4.py b/tb/test_ip_demux_4.py index 227c054d1..4016c13f7 100755 --- a/tb/test_ip_demux_4.py +++ b/tb/test_ip_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_demux_4.v b/tb/test_ip_demux_4.v index 7d5085581..9f997e9bd 100644 --- a/tb/test_ip_demux_4.v +++ b/tb/test_ip_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_demux_64_4.py b/tb/test_ip_demux_64_4.py index 62081b418..051c833d1 100755 --- a/tb/test_ip_demux_64_4.py +++ b/tb/test_ip_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_demux_64_4.v b/tb/test_ip_demux_64_4.v index 8b3ca3775..af66e4573 100644 --- a/tb/test_ip_demux_64_4.v +++ b/tb/test_ip_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index 726d93494..71d9169c1 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_eth_rx.v b/tb/test_ip_eth_rx.v index aada25add..b4f4c5e60 100644 --- a/tb/test_ip_eth_rx.v +++ b/tb/test_ip_eth_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py index 639d5bd52..3561148f8 100755 --- a/tb/test_ip_eth_rx_64.py +++ b/tb/test_ip_eth_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_eth_rx_64.v b/tb/test_ip_eth_rx_64.v index 5b2ac2a21..cb3d62cc9 100644 --- a/tb/test_ip_eth_rx_64.v +++ b/tb/test_ip_eth_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py index b74b5282d..fe5836451 100755 --- a/tb/test_ip_eth_tx.py +++ b/tb/test_ip_eth_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_eth_tx.v b/tb/test_ip_eth_tx.v index e0a017a8e..08e96f1ed 100644 --- a/tb/test_ip_eth_tx.v +++ b/tb/test_ip_eth_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_eth_tx_64.py b/tb/test_ip_eth_tx_64.py index 5262e59f7..3cf9a8030 100755 --- a/tb/test_ip_eth_tx_64.py +++ b/tb/test_ip_eth_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_eth_tx_64.v b/tb/test_ip_eth_tx_64.v index ede1320f4..ea576f799 100644 --- a/tb/test_ip_eth_tx_64.v +++ b/tb/test_ip_eth_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_mux_4.py b/tb/test_ip_mux_4.py index 8b237efb6..bea4aa1cf 100755 --- a/tb/test_ip_mux_4.py +++ b/tb/test_ip_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_mux_4.v b/tb/test_ip_mux_4.v index 01768289f..0d4516825 100644 --- a/tb/test_ip_mux_4.v +++ b/tb/test_ip_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_mux_64_4.py b/tb/test_ip_mux_64_4.py index 0e55dd419..5cd32314a 100755 --- a/tb/test_ip_mux_64_4.py +++ b/tb/test_ip_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_ip_mux_64_4.v b/tb/test_ip_mux_64_4.v index 7252121e0..53fe1f6a6 100644 --- a/tb/test_ip_mux_64_4.v +++ b/tb/test_ip_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp.py b/tb/test_udp.py index 68519981b..584ff07b1 100755 --- a/tb/test_udp.py +++ b/tb/test_udp.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp.v b/tb/test_udp.v index 3af79a25f..39f425bf8 100644 --- a/tb/test_udp.v +++ b/tb/test_udp.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py index 0c914a6a2..e9fe9b25d 100755 --- a/tb/test_udp_64.py +++ b/tb/test_udp_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_64.v b/tb/test_udp_64.v index 352195cec..ce9904367 100644 --- a/tb/test_udp_64.v +++ b/tb/test_udp_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_arb_mux_4.py b/tb/test_udp_arb_mux_4.py index 60960369b..96ed5176e 100755 --- a/tb/test_udp_arb_mux_4.py +++ b/tb/test_udp_arb_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_arb_mux_4.v b/tb/test_udp_arb_mux_4.v index 793bc28a4..922bf798d 100644 --- a/tb/test_udp_arb_mux_4.v +++ b/tb/test_udp_arb_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_arb_mux_64_4.py b/tb/test_udp_arb_mux_64_4.py index ad0b3f74f..b090e0e84 100755 --- a/tb/test_udp_arb_mux_64_4.py +++ b/tb/test_udp_arb_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_arb_mux_64_4.v b/tb/test_udp_arb_mux_64_4.v index 59609bcc2..88765489c 100644 --- a/tb/test_udp_arb_mux_64_4.v +++ b/tb/test_udp_arb_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_checksum_gen.py b/tb/test_udp_checksum_gen.py index ceba47d21..3c30d7584 100755 --- a/tb/test_udp_checksum_gen.py +++ b/tb/test_udp_checksum_gen.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_udp_checksum_gen.v b/tb/test_udp_checksum_gen.v index c0dec7f08..94f2e2543 100644 --- a/tb/test_udp_checksum_gen.v +++ b/tb/test_udp_checksum_gen.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_udp_checksum_gen_64.py b/tb/test_udp_checksum_gen_64.py index b70d35b51..0fc7a62c2 100755 --- a/tb/test_udp_checksum_gen_64.py +++ b/tb/test_udp_checksum_gen_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_udp_checksum_gen_64.v b/tb/test_udp_checksum_gen_64.v index 6c686322d..434ed3a09 100644 --- a/tb/test_udp_checksum_gen_64.v +++ b/tb/test_udp_checksum_gen_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py index d6725d314..c4ccad286 100755 --- a/tb/test_udp_complete.py +++ b/tb/test_udp_complete.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_complete.v b/tb/test_udp_complete.v index 2a29713c9..5707fed57 100644 --- a/tb/test_udp_complete.v +++ b/tb/test_udp_complete.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index f2a72d886..9da8c1b04 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_complete_64.v b/tb/test_udp_complete_64.v index cd33722d5..348a0de26 100644 --- a/tb/test_udp_complete_64.v +++ b/tb/test_udp_complete_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_demux_4.py b/tb/test_udp_demux_4.py index 53fdf5e16..6a0a36eca 100755 --- a/tb/test_udp_demux_4.py +++ b/tb/test_udp_demux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_demux_4.v b/tb/test_udp_demux_4.v index f17413d08..d64513111 100644 --- a/tb/test_udp_demux_4.v +++ b/tb/test_udp_demux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_demux_64_4.py b/tb/test_udp_demux_64_4.py index 9cd0f9861..0060f455a 100755 --- a/tb/test_udp_demux_64_4.py +++ b/tb/test_udp_demux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_demux_64_4.v b/tb/test_udp_demux_64_4.v index 04021b23e..5dacdc1fd 100644 --- a/tb/test_udp_demux_64_4.v +++ b/tb/test_udp_demux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_ip_rx.py b/tb/test_udp_ip_rx.py index ece437d51..cbe490c35 100755 --- a/tb/test_udp_ip_rx.py +++ b/tb/test_udp_ip_rx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_ip_rx.v b/tb/test_udp_ip_rx.v index 2be89b75f..f05f23a47 100644 --- a/tb/test_udp_ip_rx.v +++ b/tb/test_udp_ip_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_ip_rx_64.py b/tb/test_udp_ip_rx_64.py index 74d95d9b2..08144b687 100755 --- a/tb/test_udp_ip_rx_64.py +++ b/tb/test_udp_ip_rx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_ip_rx_64.v b/tb/test_udp_ip_rx_64.v index b4ef40679..48911aefb 100644 --- a/tb/test_udp_ip_rx_64.v +++ b/tb/test_udp_ip_rx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_ip_tx.py b/tb/test_udp_ip_tx.py index 74ac92237..a5bca5afd 100755 --- a/tb/test_udp_ip_tx.py +++ b/tb/test_udp_ip_tx.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_ip_tx.v b/tb/test_udp_ip_tx.v index 3fb582a34..5bba007e6 100644 --- a/tb/test_udp_ip_tx.v +++ b/tb/test_udp_ip_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_ip_tx_64.py b/tb/test_udp_ip_tx_64.py index c09119623..f1a7a7012 100755 --- a/tb/test_udp_ip_tx_64.py +++ b/tb/test_udp_ip_tx_64.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_ip_tx_64.v b/tb/test_udp_ip_tx_64.v index d638f6868..398da6bdd 100644 --- a/tb/test_udp_ip_tx_64.v +++ b/tb/test_udp_ip_tx_64.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_mux_4.py b/tb/test_udp_mux_4.py index 108681576..244da968e 100755 --- a/tb/test_udp_mux_4.py +++ b/tb/test_udp_mux_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_mux_4.v b/tb/test_udp_mux_4.v index b153a94b0..ed2fee733 100644 --- a/tb/test_udp_mux_4.v +++ b/tb/test_udp_mux_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_mux_64_4.py b/tb/test_udp_mux_64_4.py index ace7907a1..c1d0b4320 100755 --- a/tb/test_udp_mux_64_4.py +++ b/tb/test_udp_mux_64_4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/test_udp_mux_64_4.v b/tb/test_udp_mux_64_4.v index d424e6fed..f72555650 100644 --- a/tb/test_udp_mux_64_4.v +++ b/tb/test_udp_mux_64_4.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/udp_ep.py b/tb/udp_ep.py index 1d1a374b7..7d2b87d38 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index a5ab57a3a..adf3f0a12 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -1,6 +1,6 @@ """ -Copyright (c) 2015-2017 Alex Forencich +Copyright (c) 2015-2018 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 From 7c6da337b05e5eea675159798aa979f459d89095 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 27 Feb 2018 01:39:25 -0800 Subject: [PATCH 375/617] Happy new year --- rtl/axis_arb_mux.py | 2 +- rtl/axis_crosspoint.py | 2 +- rtl/axis_demux.py | 2 +- rtl/axis_frame_join.py | 2 +- rtl/axis_mux.py | 2 +- rtl/axis_switch.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index d969c130b..7598cfcb6 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py index ce3982979..8d21191d3 100755 --- a/rtl/axis_crosspoint.py +++ b/rtl/axis_crosspoint.py @@ -47,7 +47,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py index 9103247ce..4d2832484 100755 --- a/rtl/axis_demux.py +++ b/rtl/axis_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py index c15c099a5..8522397e7 100755 --- a/rtl/axis_frame_join.py +++ b/rtl/axis_frame_join.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py index 2828b7e08..e327e21f7 100755 --- a/rtl/axis_mux.py +++ b/rtl/axis_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/axis_switch.py b/rtl/axis_switch.py index 9114a6609..f537854c5 100755 --- a/rtl/axis_switch.py +++ b/rtl/axis_switch.py @@ -48,7 +48,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2016-2017 Alex Forencich +Copyright (c) 2016-2018 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 From 6727e5a0bd915304b74b5769cd356cd44fde7c90 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 27 Feb 2018 01:47:56 -0800 Subject: [PATCH 376/617] Happy new year --- rtl/eth_arb_mux.py | 2 +- rtl/eth_arb_mux_64.py | 2 +- rtl/eth_demux.py | 2 +- rtl/eth_demux_64.py | 2 +- rtl/eth_mux.py | 2 +- rtl/eth_mux_64.py | 2 +- rtl/ip_arb_mux.py | 2 +- rtl/ip_arb_mux_64.py | 2 +- rtl/ip_demux.py | 2 +- rtl/ip_demux_64.py | 2 +- rtl/ip_mux.py | 2 +- rtl/ip_mux_64.py | 2 +- rtl/udp_arb_mux.py | 2 +- rtl/udp_arb_mux_64.py | 2 +- rtl/udp_demux.py | 2 +- rtl/udp_demux_64.py | 2 +- rtl/udp_mux.py | 2 +- rtl/udp_mux_64.py | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/rtl/eth_arb_mux.py b/rtl/eth_arb_mux.py index d5828550b..0e35ec61b 100755 --- a/rtl/eth_arb_mux.py +++ b/rtl/eth_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_arb_mux_64.py b/rtl/eth_arb_mux_64.py index d26dbe6b7..7ed719d01 100755 --- a/rtl/eth_arb_mux_64.py +++ b/rtl/eth_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py index eb2d9fee1..047410925 100755 --- a/rtl/eth_demux.py +++ b/rtl/eth_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py index 21bf4a39b..97986a3b6 100755 --- a/rtl/eth_demux_64.py +++ b/rtl/eth_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py index abf83b3ed..204c1d068 100755 --- a/rtl/eth_mux.py +++ b/rtl/eth_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py index 702b910e4..479f825c0 100755 --- a/rtl/eth_mux_64.py +++ b/rtl/eth_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_arb_mux.py b/rtl/ip_arb_mux.py index f85fb2930..81d22b6cc 100755 --- a/rtl/ip_arb_mux.py +++ b/rtl/ip_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_arb_mux_64.py b/rtl/ip_arb_mux_64.py index 645035987..0845cfc6b 100755 --- a/rtl/ip_arb_mux_64.py +++ b/rtl/ip_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py index 593c2d78d..5fb2fb292 100755 --- a/rtl/ip_demux.py +++ b/rtl/ip_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py index 5270b3287..f3ed25e88 100755 --- a/rtl/ip_demux_64.py +++ b/rtl/ip_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py index 8e1b40c46..20c053979 100755 --- a/rtl/ip_mux.py +++ b/rtl/ip_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py index 1620000ca..c7c503a53 100755 --- a/rtl/ip_mux_64.py +++ b/rtl/ip_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_arb_mux.py b/rtl/udp_arb_mux.py index 35ecb2c34..4024993fa 100755 --- a/rtl/udp_arb_mux.py +++ b/rtl/udp_arb_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_arb_mux_64.py b/rtl/udp_arb_mux_64.py index 0f930113e..b4094cde3 100755 --- a/rtl/udp_arb_mux_64.py +++ b/rtl/udp_arb_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py index 416bd0aa5..f5684dcd0 100755 --- a/rtl/udp_demux.py +++ b/rtl/udp_demux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py index d0b44e1a3..158135a96 100755 --- a/rtl/udp_demux_64.py +++ b/rtl/udp_demux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py index 1cf7a0962..2a4d1e910 100755 --- a/rtl/udp_mux.py +++ b/rtl/udp_mux.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py index 3d97f8a31..8436306a1 100755 --- a/rtl/udp_mux_64.py +++ b/rtl/udp_mux_64.py @@ -40,7 +40,7 @@ def generate(ports=4, name=None, output=None): t = Template(u"""/* -Copyright (c) 2014-2017 Alex Forencich +Copyright (c) 2014-2018 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 From 3e28af152a560141ac9e57cda4b9b28658f4c9d4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 27 Feb 2018 11:00:31 -0800 Subject: [PATCH 377/617] Fix CI --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 394066aff..15f9a3c31 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: python python: - - "3.4" + - "3.6" before_install: - export d=`pwd` - export PYTHON_EXE=`which python` @@ -8,7 +8,7 @@ before_install: - sudo apt-get install -y iverilog - git clone https://github.com/jandecaluwe/myhdl.git - cd $d/myhdl && sudo $PYTHON_EXE 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/x86_64-linux-gnu/ivl/myhdl.vpi - cd $d script: - cd tb && py.test From 855b593ce5dbaa9c76754966a21d4c916af2bfe7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 31 May 2018 16:05:41 -0700 Subject: [PATCH 378/617] Minor updates to 10G example designs --- example/DE5-Net/fpga/rtl/fpga_core.v | 2 +- example/HXT100G/fpga/fpga/Makefile | 2 - example/HXT100G/fpga/rtl/fpga.v | 84 +++++++++++++++++++++++-- example/HXT100G/fpga/rtl/fpga_core.v | 2 +- example/VCU108/fpga_10g/rtl/fpga_core.v | 2 +- 5 files changed, 81 insertions(+), 11 deletions(-) diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index 1940672ec..88b6c3764 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -568,7 +568,7 @@ axis_fifo #( .ADDR_WIDTH(10), .DATA_WIDTH(64), .KEEP_ENABLE(1), - .KEEP_WIDTH(64), + .KEEP_WIDTH(8), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), diff --git a/example/HXT100G/fpga/fpga/Makefile b/example/HXT100G/fpga/fpga/Makefile index 5fb7cef84..60e3ea71f 100644 --- a/example/HXT100G/fpga/fpga/Makefile +++ b/example/HXT100G/fpga/fpga/Makefile @@ -41,8 +41,6 @@ SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v SYN_FILES += lib/eth/rtl/eth_arb_mux_64_2.v SYN_FILES += lib/eth/rtl/eth_mux_64_2.v -SYN_FILES += lib/eth/rtl/xgmii_interleave.v -SYN_FILES += lib/eth/rtl/xgmii_deinterleave.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/HXT100G/fpga/rtl/fpga.v b/example/HXT100G/fpga/rtl/fpga.v index 4301afecb..66f1df8d7 100644 --- a/example/HXT100G/fpga/rtl/fpga.v +++ b/example/HXT100G/fpga/rtl/fpga.v @@ -623,7 +623,19 @@ eth_gth_phy_quad_A_inst ( .xgmii_txd_3(eth_r6_txd), .xgmii_txc_3(eth_r6_txc), .xgmii_rxd_3(eth_r6_rxd), - .xgmii_rxc_3(eth_r6_rxc) + .xgmii_rxc_3(eth_r6_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) ); // Quad B X0Y1 @@ -681,7 +693,19 @@ eth_gth_phy_quad_B_inst ( .xgmii_txd_3(eth_r7_txd), .xgmii_txc_3(eth_r7_txc), .xgmii_rxd_3(eth_r7_rxd), - .xgmii_rxc_3(eth_r7_rxc) + .xgmii_rxc_3(eth_r7_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) ); // Quad C X0Y2 @@ -739,7 +763,19 @@ eth_gth_phy_quad_C_inst ( .xgmii_txd_3(eth_r10_txd), .xgmii_txc_3(eth_r10_txc), .xgmii_rxd_3(eth_r10_rxd), - .xgmii_rxc_3(eth_r10_rxc) + .xgmii_rxc_3(eth_r10_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) ); // Quad D X1Y0 @@ -797,7 +833,19 @@ eth_gth_phy_quad_D_inst ( .xgmii_txd_3(eth_l6_txd), .xgmii_txc_3(eth_l6_txc), .xgmii_rxd_3(eth_l6_rxd), - .xgmii_rxc_3(eth_l6_rxc) + .xgmii_rxc_3(eth_l6_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) ); // Quad E X1Y1 @@ -855,7 +903,19 @@ eth_gth_phy_quad_E_inst ( .xgmii_txd_3(eth_l7_txd), .xgmii_txc_3(eth_l7_txc), .xgmii_rxd_3(eth_l7_rxd), - .xgmii_rxc_3(eth_l7_rxc) + .xgmii_rxc_3(eth_l7_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) ); // Quad F X1Y2 @@ -913,7 +973,19 @@ eth_gth_phy_quad_F_inst ( .xgmii_txd_3(eth_l10_txd), .xgmii_txc_3(eth_l10_txc), .xgmii_rxd_3(eth_l10_rxd), - .xgmii_rxc_3(eth_l10_rxc) + .xgmii_rxc_3(eth_l10_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) ); diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v index c000ecc74..f9f864a8e 100644 --- a/example/HXT100G/fpga/rtl/fpga_core.v +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -712,7 +712,7 @@ axis_fifo #( .ADDR_WIDTH(10), .DATA_WIDTH(64), .KEEP_ENABLE(1), - .KEEP_WIDTH(64), + .KEEP_WIDTH(8), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index 129f3ccdb..340ad3531 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -852,7 +852,7 @@ axis_fifo #( .ADDR_WIDTH(10), .DATA_WIDTH(64), .KEEP_ENABLE(1), - .KEEP_WIDTH(64), + .KEEP_WIDTH(8), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), From c31757552b31d85fdac6e8a91a3b73693e99d3b3 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 31 May 2018 16:27:56 -0700 Subject: [PATCH 379/617] Add crosspoint design --- example/HXT100G/fpga_cxpt16/Makefile | 25 + example/HXT100G/fpga_cxpt16/README.md | 27 + example/HXT100G/fpga_cxpt16/common/xilinx.mk | 191 + example/HXT100G/fpga_cxpt16/coregen/Makefile | 33 + .../HXT100G/fpga_cxpt16/coregen/coregen.cgp | 22 + .../coregen/ten_gig_eth_pcs_pma_v2_6.xco | 53 + ...ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco | 185 + example/HXT100G/fpga_cxpt16/fpga.ucf | 269 ++ example/HXT100G/fpga_cxpt16/fpga/Makefile | 66 + example/HXT100G/fpga_cxpt16/lib/eth | 1 + .../fpga_cxpt16/rtl/axis_crosspoint_16x16.v | 3334 +++++++++++++++++ .../HXT100G/fpga_cxpt16/rtl/debounce_switch.v | 89 + .../fpga_cxpt16/rtl/eth_gth_phy_quad.v | 569 +++ example/HXT100G/fpga_cxpt16/rtl/fpga.v | 1131 ++++++ example/HXT100G/fpga_cxpt16/rtl/fpga_core.v | 549 +++ .../HXT100G/fpga_cxpt16/rtl/gth_i2c_init.v | 508 +++ example/HXT100G/fpga_cxpt16/rtl/i2c_master.v | 895 +++++ example/HXT100G/fpga_cxpt16/rtl/sync_reset.v | 52 + example/HXT100G/fpga_cxpt16/rtl/sync_signal.v | 58 + example/HXT100G/fpga_cxpt16/tb/axis_ep.py | 1 + example/HXT100G/fpga_cxpt16/tb/eth_ep.py | 1 + .../HXT100G/fpga_cxpt16/tb/test_fpga_core.py | 551 +++ .../HXT100G/fpga_cxpt16/tb/test_fpga_core.v | 416 ++ example/HXT100G/fpga_cxpt16/tb/xgmii_ep.py | 1 + 24 files changed, 9027 insertions(+) create mode 100644 example/HXT100G/fpga_cxpt16/Makefile create mode 100644 example/HXT100G/fpga_cxpt16/README.md create mode 100644 example/HXT100G/fpga_cxpt16/common/xilinx.mk create mode 100644 example/HXT100G/fpga_cxpt16/coregen/Makefile create mode 100644 example/HXT100G/fpga_cxpt16/coregen/coregen.cgp create mode 100644 example/HXT100G/fpga_cxpt16/coregen/ten_gig_eth_pcs_pma_v2_6.xco create mode 100644 example/HXT100G/fpga_cxpt16/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco create mode 100644 example/HXT100G/fpga_cxpt16/fpga.ucf create mode 100644 example/HXT100G/fpga_cxpt16/fpga/Makefile create mode 120000 example/HXT100G/fpga_cxpt16/lib/eth create mode 100644 example/HXT100G/fpga_cxpt16/rtl/axis_crosspoint_16x16.v create mode 100644 example/HXT100G/fpga_cxpt16/rtl/debounce_switch.v create mode 100644 example/HXT100G/fpga_cxpt16/rtl/eth_gth_phy_quad.v create mode 100644 example/HXT100G/fpga_cxpt16/rtl/fpga.v create mode 100644 example/HXT100G/fpga_cxpt16/rtl/fpga_core.v create mode 100644 example/HXT100G/fpga_cxpt16/rtl/gth_i2c_init.v create mode 100644 example/HXT100G/fpga_cxpt16/rtl/i2c_master.v create mode 100644 example/HXT100G/fpga_cxpt16/rtl/sync_reset.v create mode 100644 example/HXT100G/fpga_cxpt16/rtl/sync_signal.v create mode 120000 example/HXT100G/fpga_cxpt16/tb/axis_ep.py create mode 120000 example/HXT100G/fpga_cxpt16/tb/eth_ep.py create mode 100755 example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py create mode 100644 example/HXT100G/fpga_cxpt16/tb/test_fpga_core.v create mode 120000 example/HXT100G/fpga_cxpt16/tb/xgmii_ep.py diff --git a/example/HXT100G/fpga_cxpt16/Makefile b/example/HXT100G/fpga_cxpt16/Makefile new file mode 100644 index 000000000..9f8bd4048 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = coregen fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/HXT100G/fpga_cxpt16/README.md b/example/HXT100G/fpga_cxpt16/README.md new file mode 100644 index 000000000..1128f97c5 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/README.md @@ -0,0 +1,27 @@ +# Verilog Ethernet HXT100G Crosspoint Switch Design + +## Introduction + +This design targets the HiTech Global HXT100G FPGA board. + +The design forms a 16x16 crosspoint switch for 10G Ethernet. It is capable of +connecting any output port to any input port based on configuration frames +received over a dedicated configuration interface. + +FPGA: XC6VHX565T-2FFG1923 +PHY: 10G BASE-R PHY IP core and internal GTH transceiver + +## How to build + +Run make to build. Ensure that the Xilinx ISE toolchain components are +in PATH. + +## How to use + +SFP left ports 0-7 are connected to crosspoint input/output ports 0-7, SFP +right ports 0-7 are connected to crosspoint input/output ports 8-15. SFP port +left 11 is the control port. Send an Ethernet frame with ethtype 0x8099 to +this port to reconfigure the switch, the first 16 payload bytes corresponding +to the 16 switch output ports, each byte selecting which input port will be +connected. It is possible to connect multiple output ports to the same input +port. diff --git a/example/HXT100G/fpga_cxpt16/common/xilinx.mk b/example/HXT100G/fpga_cxpt16/common/xilinx.mk new file mode 100644 index 000000000..f10a45f8e --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/common/xilinx.mk @@ -0,0 +1,191 @@ +############################################################################# +# Author: Lane Brooks/Keith Fife +# Date: 04/28/2006 +# License: GPL +# Desc: This is a Makefile intended to take a verilog rtl design +# through the Xilinx ISE tools to generate configuration files for +# Xilinx FPGAs. This file is generic and just a template. As such +# all design specific options such as synthesis files, fpga part type, +# prom part type, etc should be set in the top Makefile prior to +# including this file. Alternatively, all parameters can be passed +# in from the command line as well. +# +############################################################################## +# +# Parameter: +# SYN_FILES - Space seperated list of files to be synthesized +# PART - FPGA part (see Xilinx documentation) +# PROM - PROM part +# NGC_PATHS - Space seperated list of any dirs with pre-compiled ngc files. +# UCF_FILES - Space seperated list of user constraint files. Defaults to xilinx/$(FPGA_TOP).ucf +# +# +# Example Calling Makefile: +# +# SYN_FILES = fpga.v fifo.v clks.v +# PART = xc3s1000 +# FPGA_TOP = fpga +# PROM = xc18v04 +# NGC_PATH = ipLib1 ipLib2 +# FPGA_ARCH = spartan6 +# SPI_PROM_SIZE = (in bytes) +# include xilinx.mk +############################################################################# +# +# Command Line Example: +# make -f xilinx.mk PART=xc3s1000-4fg320 SYN_FILES="fpga.v test.v" FPGA_TOP=fpga +# +############################################################################## +# +# Required Setup: +# +# %.ucf - user constraint file. Needed by ngdbuild +# +# Optional Files: +# %.xcf - user constraint file. Needed by xst. +# %.ut - File for pin states needed by bitgen + + +.PHONY: clean bit prom fpga spi + + +# Mark the intermediate files as PRECIOUS to prevent make from +# deleting them (see make manual section 10.4). +.PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.bit %_timesim.v + +# include the local Makefile for project for any project specific targets +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +INC_PATHS_REL = $(patsubst %, ../%, $(INC_PATHS)) +NGC_PATHS_REL = $(patsubst %, ../%, $(NGC_PATHS)) + +ifdef UCF_FILES + UCF_FILES_REL = $(patsubst %, ../%, $(UCF_FILES)) +else + UCF_FILES_REL = $(FPGA_TOP).ucf +endif + + + +fpga: $(FPGA_TOP).bit + +mcs: $(FPGA_TOP).mcs + +prom: $(FPGA_TOP).spi + +spi: $(FPGA_TOP).spi + +fpgasim: $(FPGA_TOP)_sim.v + + +########################### XST TEMPLATES ############################ +# There are 2 files that XST uses for synthesis that we auto generate. +# The first is a project file which is just a list of all the verilog +# files. The second is the src file which passes XST all the options. +# See XST user manual for XST options. +%.ngc: $(SYN_FILES_REL) $(INC_FILES_REL) + rm -rf xst $*.prj $*.xst defines.v + touch defines.v + mkdir -p xst/tmp + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo verilog work defines.v > $*.prj + for x in $(SYN_FILES_REL); do echo verilog work $$x >> $*.prj; done + @echo "set -tmpdir ./xst/tmp" >> $*.xst + @echo "set -xsthdpdir ./xst" >> $*.xst + @echo "run" >> $*.xst + @echo "-ifn $*.prj" >> $*.xst + @echo "-ifmt mixed" >> $*.xst + @echo "-top $*" >> $*.xst + @echo "-ofn $*" >> $*.xst + @echo "-ofmt NGC" >> $*.xst + @echo "-opt_mode Speed" >> $*.xst + @echo "-opt_level 1" >> $*.xst + # @echo "-verilog2001 YES" >> $*.xst + @echo "-keep_hierarchy NO" >> $*.xst + @echo "-p $(FPGA_PART)" >> $*.xst + xst -ifn $*.xst -ofn $*.log + + +########################### ISE TRANSLATE ############################ +# ngdbuild will automatically use a ucf called %.ucf if one is found. +# We setup the dependancy such that %.ucf file is required. If any +# pre-compiled ncd files are needed, set the NGC_PATH variable as a space +# seperated list of directories that include the pre-compiled ngc files. +%.ngd: %.ngc $(UCF_FILES_REL) + ngdbuild -dd ngdbuild $(patsubst %,-sd %, $(NGC_PATHS_REL)) $(patsubst %,-uc %, $(UCF_FILES_REL)) -p $(FPGA_PART) $< $@ + + +########################### ISE MAP ################################### +ifeq ($(FPGA_ARCH),spartan6) + MAP_OPTS= -register_duplication on -timing -xe n +else + MAP_OPTS= -cm speed -register_duplication on -timing -xe n -pr b +endif + +%_map.ncd: %.ngd + map -p $(FPGA_PART) $(MAP_OPTS) -w -o $@ $< $*.pcf + +# map -p $(FPGA_PART) -cm area -pr b -k 4 -c 100 -o $@ $< $*.pcf + + +########################### ISE PnR ################################### +%.ncd: %_map.ncd + par -w -ol high $< $@ $*.pcf + +# par -w -ol std -t 1 $< $@ $*.pcf + + +##################### ISE Static Timing Analysis ##################### +%.twr: %.ncd + -trce -e 3 -l 3 -u -xml $* $< -o $@ $*.pcf + +%_sim.v: %.ncd + netgen -s 4 -pcf $*.pcf -sdf_anno true -ism -sdf_path netgen -w -dir . -ofmt verilog -sim $< $@ + +# netgen -ise "/home/lane/Second/xilinx/Second/Second" -intstyle ise -s 4 -pcf Second.pcf -sdf_anno true -sdf_path netgen/par -w -dir netgen/par -ofmt verilog -sim Second.ncd Second_timesim.v + + +########################### ISE Bitgen ############################# +%.bit: %.twr + bitgen $(BITGEN_OPTIONS) -w $*.ncd $*.bit + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +########################### ISE Promgen ############################# +%.mcs: %.bit + promgen -spi -w -p mcs -s $(SPI_PROM_SIZE) -o $@ -u 0 $< + # promgen -w -p mcs -c FF -o $@ -u 0 $< -x $(PROM) + mkdir -p rev + EXT=mcs; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +%.spi: %.mcs + objcopy -I ihex -O binary $< $@ + EXT=spi; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + + +tmpclean: + -rm -rf xst ngdbuild *_map.* *.ncd *.ngc *.log *.xst *.prj *.lso *~ *.pcf *.bld *.ngd *.xpi *_pad.* *.unroutes *.twx *.par *.twr *.pad *.drc *.bgn *.prm *.sig netgen *.v *.nlf *.xml + +clean: tmpclean + -rm -rf *.bit *.mcs + +# clean everything +distclean: clean + -rm -rf rev + diff --git a/example/HXT100G/fpga_cxpt16/coregen/Makefile b/example/HXT100G/fpga_cxpt16/coregen/Makefile new file mode 100644 index 000000000..09ec2cdf4 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/coregen/Makefile @@ -0,0 +1,33 @@ +# Tools +COREGEN:=coregen +XAW2VERILOG:=xaw2verilog + +# Source +XCO:=ten_gig_eth_pcs_pma_v2_6.xco ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco +XAW:= + +# Targets +TARGETS += $(XCO:.xco=) +TARGETS += $(XAW:.xaw=) + +# Rules +.PHONY: all +all: $(TARGETS) + +.PHONY: clean +clean: + -rm -rf $(TARGETS) + +%: %.xco + $(eval $@_TMP := $(shell mktemp -d)) + cp -a coregen.cgp $($@_TMP) + cp -a $< $($@_TMP) + cd $($@_TMP) && $(COREGEN) -p coregen.cgp -b $(notdir $<) + mv $($@_TMP) $@ + +%: %.xaw + $(eval $@_TMP := $(shell mktemp -d)) + cp -a coregen.cgp $($@_TMP) + cp -a $< $($@_TMP) + cd $($@_TMP) && $(XAW2VERILOG) -st $(notdir $<) $(notdir $*) + mv $($@_TMP) $@ diff --git a/example/HXT100G/fpga_cxpt16/coregen/coregen.cgp b/example/HXT100G/fpga_cxpt16/coregen/coregen.cgp new file mode 100644 index 000000000..dbe49f4c0 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/coregen/coregen.cgp @@ -0,0 +1,22 @@ +# Date: Wed Apr 1 17:38:18 2015 + +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vhx565t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1923 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +SET workingdirectory = ./tmp/ + +# CRC: 3d2f7d04 diff --git a/example/HXT100G/fpga_cxpt16/coregen/ten_gig_eth_pcs_pma_v2_6.xco b/example/HXT100G/fpga_cxpt16/coregen/ten_gig_eth_pcs_pma_v2_6.xco new file mode 100644 index 000000000..2d141c5b0 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/coregen/ten_gig_eth_pcs_pma_v2_6.xco @@ -0,0 +1,53 @@ +############################################################## +# +# Xilinx Core Generator version 14.7 +# Date: Wed Apr 1 17:39:05 2015 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:ten_gig_eth_pcs_pma:2.6 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vhx565t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1923 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Ten_Gigabit_Ethernet_PCS/PMA_(10GBASE-R/KR) xilinx.com:ip:ten_gig_eth_pcs_pma:2.6 +# END Select +# BEGIN Parameters +CSET autonegotiation=false +CSET base_kr=BASE-R +CSET component_name=ten_gig_eth_pcs_pma_v2_6 +CSET fec=false +CSET ieee_1588=None +CSET mdio_management=false +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2012-10-08T14:58:05Z +# END Extra information +GENERATE +# CRC: d3dbdcf5 diff --git a/example/HXT100G/fpga_cxpt16/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco b/example/HXT100G/fpga_cxpt16/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco new file mode 100644 index 000000000..3c380f101 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco @@ -0,0 +1,185 @@ +############################################################## +# +# Xilinx Core Generator version 14.7 +# Date: Wed Apr 1 18:19:03 2015 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:v6_gthwizard:1.11 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vhx565t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1923 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Virtex-6_FPGA_GTH_Transceiver_Wizard xilinx.com:ip:v6_gthwizard:1.11 +# END Select +# BEGIN Parameters +CSET component_name=ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper +CSET config_identical=true +CSET drp_clock=50.00 +CSET gth0_datapath_width=64 +CSET gth0_encoding=10GbE_64B/66B +CSET gth0_line_rate=10.3125 +CSET gth0_postcursor_emphasis=0 +CSET gth0_precursor_emphasis=0 +CSET gth0_protocol_file=10GBASE-R +CSET gth0_rxeqmix=1000 +CSET gth0_tx_swing=800 +CSET gth0_use_dfetrainctrl=false +CSET gth0_use_lat_msr=false +CSET gth0_use_port_powerdown=true +CSET gth0_use_port_rxbufreset=true +CSET gth0_use_port_rxcodeerr=true +CSET gth0_use_port_rxctrl=true +CSET gth0_use_port_rxdisperr=false +CSET gth0_use_port_rxencommadet=false +CSET gth0_use_port_rxpolarity=false +CSET gth0_use_port_rxpowerdown=true +CSET gth0_use_port_rxslip=false +CSET gth0_use_port_rxvalid=false +CSET gth0_use_port_txbufreset=true +CSET gth0_use_port_txctrl=true +CSET gth0_use_port_txpowerdown=true +CSET gth1_datapath_width=64 +CSET gth1_encoding=10GbE_64B/66B +CSET gth1_line_rate=10.3125 +CSET gth1_postcursor_emphasis=0 +CSET gth1_precursor_emphasis=0 +CSET gth1_protocol_file=10GBASE-R +CSET gth1_rxeqmix=1000 +CSET gth1_tx_swing=800 +CSET gth1_use_dfetrainctrl=false +CSET gth1_use_lat_msr=false +CSET gth1_use_port_powerdown=true +CSET gth1_use_port_rxbufreset=true +CSET gth1_use_port_rxcodeerr=true +CSET gth1_use_port_rxctrl=true +CSET gth1_use_port_rxdisperr=false +CSET gth1_use_port_rxencommadet=false +CSET gth1_use_port_rxpolarity=false +CSET gth1_use_port_rxpowerdown=true +CSET gth1_use_port_rxslip=false +CSET gth1_use_port_rxvalid=false +CSET gth1_use_port_txbufreset=true +CSET gth1_use_port_txctrl=true +CSET gth1_use_port_txpowerdown=true +CSET gth2_datapath_width=64 +CSET gth2_encoding=10GbE_64B/66B +CSET gth2_line_rate=10.3125 +CSET gth2_postcursor_emphasis=0 +CSET gth2_precursor_emphasis=0 +CSET gth2_protocol_file=10GBASE-R +CSET gth2_rxeqmix=1000 +CSET gth2_tx_swing=800 +CSET gth2_use_dfetrainctrl=false +CSET gth2_use_lat_msr=false +CSET gth2_use_port_powerdown=true +CSET gth2_use_port_rxbufreset=true +CSET gth2_use_port_rxcodeerr=true +CSET gth2_use_port_rxctrl=true +CSET gth2_use_port_rxdisperr=false +CSET gth2_use_port_rxencommadet=false +CSET gth2_use_port_rxpolarity=false +CSET gth2_use_port_rxpowerdown=true +CSET gth2_use_port_rxslip=false +CSET gth2_use_port_rxvalid=false +CSET gth2_use_port_txbufreset=true +CSET gth2_use_port_txctrl=true +CSET gth2_use_port_txpowerdown=true +CSET gth3_datapath_width=64 +CSET gth3_encoding=10GbE_64B/66B +CSET gth3_line_rate=10.3125 +CSET gth3_postcursor_emphasis=0 +CSET gth3_precursor_emphasis=0 +CSET gth3_protocol_file=10GBASE-R +CSET gth3_rxeqmix=1000 +CSET gth3_tx_swing=800 +CSET gth3_use_dfetrainctrl=false +CSET gth3_use_lat_msr=false +CSET gth3_use_port_powerdown=true +CSET gth3_use_port_rxbufreset=true +CSET gth3_use_port_rxcodeerr=true +CSET gth3_use_port_rxctrl=true +CSET gth3_use_port_rxdisperr=false +CSET gth3_use_port_rxencommadet=false +CSET gth3_use_port_rxpolarity=false +CSET gth3_use_port_rxpowerdown=true +CSET gth3_use_port_rxslip=false +CSET gth3_use_port_rxvalid=false +CSET gth3_use_port_txbufreset=true +CSET gth3_use_port_txctrl=true +CSET gth3_use_port_txpowerdown=true +CSET gth_column=Right_Column_(X1) +CSET gthx4lane=false +CSET protocol_template=10GBASE-R +CSET refclk_x0y0=CLK_Y0 +CSET refclk_x0y1=CLK_Y1 +CSET refclk_x0y2=CLK_Y2 +CSET refclk_x1y0=CLK_Y0 +CSET refclk_x1y1=CLK_Y1 +CSET refclk_x1y2=CLK_Y2 +CSET reference_clock=156.25 +CSET target_line_rate=10.3125 +CSET use_gth0_x0y0=true +CSET use_gth0_x0y1=true +CSET use_gth0_x0y2=true +CSET use_gth0_x1y0=true +CSET use_gth0_x1y1=true +CSET use_gth0_x1y2=true +CSET use_gth1_x0y0=true +CSET use_gth1_x0y1=true +CSET use_gth1_x0y2=true +CSET use_gth1_x1y0=true +CSET use_gth1_x1y1=true +CSET use_gth1_x1y2=true +CSET use_gth2_x0y0=true +CSET use_gth2_x0y1=true +CSET use_gth2_x0y2=true +CSET use_gth2_x1y0=true +CSET use_gth2_x1y1=true +CSET use_gth2_x1y2=true +CSET use_gth3_x0y0=true +CSET use_gth3_x0y1=true +CSET use_gth3_x0y2=true +CSET use_gth3_x1y0=true +CSET use_gth3_x1y1=true +CSET use_gth3_x1y2=true +CSET use_gth_quad_x0y0=false +CSET use_gth_quad_x0y1=false +CSET use_gth_quad_x0y2=false +CSET use_gth_quad_x1y0=true +CSET use_gth_quad_x1y1=false +CSET use_gth_quad_x1y2=false +CSET use_no_rx=false +CSET use_no_tx=false +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-04-05T17:48:34Z +# END Extra information +GENERATE +# CRC: 75800c49 diff --git a/example/HXT100G/fpga_cxpt16/fpga.ucf b/example/HXT100G/fpga_cxpt16/fpga.ucf new file mode 100644 index 000000000..784dcb369 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/fpga.ucf @@ -0,0 +1,269 @@ +# User Constraints File for the HTG-V6HXT-100GIG FPGA board + +CONFIG PART = xc6vhx565t-2ff1923; + +# 50 MHz clock +NET "sys_clk" LOC = "AP33" | IOSTANDARD=LVCMOS25; # SYS_CLK, 50MHz +NET "sys_clk" TNM_NET = "sys_clk"; +TIMESPEC "TS_sys_clk" = PERIOD "sys_clk" 20.000 ns HIGH 50% INPUT_JITTER 200.0ps; + +# 156.25 MHz transceiver clock +NET "*txclk156" TNM_NET = "txclk156"; +TIMESPEC "TS_txclk156" = PERIOD "txclk156" 6400 ps; + +NET "*rx_clk_0" TNM_NET = "rx_clk"; +NET "*rx_clk_1" TNM_NET = "rx_clk"; +NET "*rx_clk_2" TNM_NET = "rx_clk"; +NET "*rx_clk_3" TNM_NET = "rx_clk"; +TIMESPEC "TS_rx_clk" = PERIOD "rx_clk" 6400 ps; + +# clock crossing constraints +TIMESPEC "TS_txclk156_to_sys_clk" = FROM "txclk156" TO "sys_clk" 10 ns; +TIMESPEC "TS_sys_clk_to_txclk156" = FROM "sys_clk" TO "txclk156" 10 ns; +TIMESPEC "TS_sys_clk_to_rx_clk" = FROM "sys_clk" TO "rx_clk" 10 ns; +TIMESPEC "TS_rx_clk_to_sys_clk" = FROM "rx_clk" TO "sys_clk" 10 ns; + +# PHY elastic buffer constraints +NET "*elastic_buffer_i*rd_truegray" MAXDELAY = 6.0 ns; +NET "*elastic_buffer_i?can_insert_wra" TIG; +NET "*wr_gray*" MAXDELAY = 6.0 ns; +NET "*rd_lastgray*" MAXDELAY = 6.0 ns; + +TIMESPEC "TS_txclk156_to_rx_clk" = FROM "txclk156" TO "rx_clk" 10 ns; +TIMESPEC "TS_rx_clk_to_txclk156" = FROM "rx_clk" TO "txclk156" 10 ns; + +# 200 MHz DDR3 clock +#NET "clk_ddr3_p" LOC = "AL13" | IOSTANDARD=LVDS_25; +#NET "clk_ddr3_n" LOC = "AL12" | IOSTANDARD=LVDS_25; +#NET "clk_ddr3_p" TNM_NET = "clk_ddr3"; +#TIMESPEC "TS_clk_ddr3" = PERIOD "clk_ddr3" 5.000 ns HIGH 50% INPUT_JITTER 20.0ps; + +# User clock +#NET "clk_usr_p" LOC = "J33" | IOSTANDARD=LVDS_25; +#NET "clk_usr_n" LOC = "H33" | IOSTANDARD=LVDS_25; +#NET "clk_usr_p" TNM_NET = "clk_usr"; +#TIMESPEC "TS_clk_usr" = PERIOD "clk_usr" 5.000 ns HIGH 50% INPUT_JITTER 20.0ps; + +# Button +NET "reset_n" LOC = "AY12" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (S7) + +# DIP switches +NET "sw<0>" LOC = "BB32" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (USER_SW0) +NET "sw<1>" LOC = "AT30" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (USER_SW1) + +# Jumpers +NET "jp<0>" LOC = "AW34" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO0, JP18) +NET "jp<1>" LOC = "AY35" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO1, JP19) +NET "jp<2>" LOC = "AW35" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO2, JP20) +NET "jp<3>" LOC = "AV33" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO3, JP21) + +# LEDs +NET "led<0>" LOC = "AY33" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D20) +NET "led<1>" LOC = "AW33" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D23) +NET "led<2>" LOC = "AK35" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D26) +NET "led<3>" LOC = "AL35" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D31) + +# Silicon Labs CP2102 +NET "uart_rst" LOC = "D10" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_suspend" LOC = "E12" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_ri" LOC = "B12" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_dcd" LOC = "C11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_dtr" LOC = "B11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_dsr" LOC = "D11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_rxd" LOC = "E11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # IO_L66N_SCP0 +NET "uart_txd" LOC = "B9" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # IO_L66P_SCP1 +NET "uart_rts" LOC = "A9" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_cts" LOC = "F12" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # + +# Clock muxes +NET "clk_gth_scl" LOC = "M11"; +NET "clk_gth_sda" LOC = "L10"; +NET "clk_gth_rst_n" LOC = "AR7"; +NET "clk_gthl_alm" LOC = "M34"; +NET "clk_gthr_alm" LOC = "R13"; +NET "clk_gthl_lol" LOC = "L34"; +NET "clk_gthr_lol" LOC = "L12"; + +# AirMax I/O +#NET "amh_right_io<0>" LOC="N33"; # AMH1R_IO0 J6.TX[12]_P mdc +#NET "amh_right_io<1>" LOC="J34"; # AMH1R_IO1 J6.TX[12]_N mdio +#NET "amh_right_io<2>" LOC="F34"; # AMH1R_IO2 J6.TX[13]_P +#NET "amh_right_io<3>" LOC="G34"; # AMH1R_IO3 J6.TX[13]_N +#NET "amh_right_io<4>" LOC="K33"; # AMH1R_IO4 J6.TX[14]_P +#NET "amh_right_io<5>" LOC="L33"; # AMH1R_IO5 J6.TX[14]_N +#NET "amh_right_io<6>" LOC="N34"; # AMH1R_IO6 J6.TX[15]_P +#NET "amh_right_io<7>" LOC="H34"; # AMH1R_IO7 J6.TX[15]_N reset_n + +#NET "amh_left_io<0>" LOC="E35"; # AMH1L_IO0 J3.TX[12]_P mdc +#NET "amh_left_io<1>" LOC="B37"; # AMH1L_IO1 J3.TX[12]_N mdio +#NET "amh_left_io<2>" LOC="A35"; # AMH1L_IO2 J3.TX[13]_P +#NET "amh_left_io<3>" LOC="B35"; # AMH1L_IO3 J3.TX[13]_N +#NET "amh_left_io<4>" LOC="G35"; # AMH1L_IO4 J3.TX[14]_P +#NET "amh_left_io<5>" LOC="F35"; # AMH1L_IO5 J3.TX[14]_N +#NET "amh_left_io<6>" LOC="A37"; # AMH1L_IO6 J3.TX[15]_P +#NET "amh_left_io<7>" LOC="B36"; # AMH1L_IO7 J3.TX[15]_N reset_n + +NET "amh_right_mdc" LOC="N33"; # AMH1R_IO0 J6.TX[12]_P mdc +NET "amh_right_mdio" LOC="J34"; # AMH1R_IO1 J6.TX[12]_N mdio +NET "amh_right_phy_rst_n" LOC="H34" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; + +NET "amh_left_mdc" LOC="E35"; # AMH1L_IO0 J3.TX[12]_P mdc +NET "amh_left_mdio" LOC="B37"; # AMH1L_IO1 J3.TX[12]_N mdio +NET "amh_left_phy_rst_n" LOC="B36" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; + +# 10G Ethernet interfaces +# Quad A X0Y0 +# Ports 11, 9, 10, 8 (right) +# SFP 0, 2, 4, 6 +NET "gth_quad_A_refclk_p" LOC = "R41"; +NET "gth_quad_A_refclk_n" LOC = "R42"; + +NET "gth_quad_A_txp_0" LOC = "T43"; +NET "gth_quad_A_txn_0" LOC = "T44"; +NET "gth_quad_A_rxp_0" LOC = "U41"; +NET "gth_quad_A_rxn_0" LOC = "U42"; + +NET "gth_quad_A_txp_1" LOC = "P43"; +NET "gth_quad_A_txn_1" LOC = "P44"; +NET "gth_quad_A_rxp_1" LOC = "T39"; +NET "gth_quad_A_rxn_1" LOC = "T40"; + +NET "gth_quad_A_txp_2" LOC = "M43"; +NET "gth_quad_A_txn_2" LOC = "M44"; +NET "gth_quad_A_rxp_2" LOC = "N37"; +NET "gth_quad_A_rxn_2" LOC = "N38"; + +NET "gth_quad_A_txp_3" LOC = "N41"; +NET "gth_quad_A_txn_3" LOC = "N42"; +NET "gth_quad_A_rxp_3" LOC = "M39"; +NET "gth_quad_A_rxn_3" LOC = "M40"; + +# Quad B X0Y1 +# Ports 4, 6, 5, 7 (right) +# SFP 3, 5, 1, 7 +NET "gth_quad_B_refclk_p" LOC = "J41"; +NET "gth_quad_B_refclk_n" LOC = "J42"; + +NET "gth_quad_B_txp_0" LOC = "L41"; +NET "gth_quad_B_txn_0" LOC = "L42"; +NET "gth_quad_B_rxp_0" LOC = "K39"; +NET "gth_quad_B_rxn_0" LOC = "K40"; + +NET "gth_quad_B_txp_1" LOC = "K43"; +NET "gth_quad_B_txn_1" LOC = "K44"; +NET "gth_quad_B_rxp_1" LOC = "L37"; +NET "gth_quad_B_rxn_1" LOC = "L38"; + +NET "gth_quad_B_txp_2" LOC = "G41"; +NET "gth_quad_B_txn_2" LOC = "G42"; +NET "gth_quad_B_rxp_2" LOC = "H39"; +NET "gth_quad_B_rxn_2" LOC = "H40"; + +NET "gth_quad_B_txp_3" LOC = "H43"; +NET "gth_quad_B_txn_3" LOC = "H44"; +NET "gth_quad_B_rxp_3" LOC = "J37"; +NET "gth_quad_B_rxn_3" LOC = "J38"; + +# Quad C X0Y2 +# Ports 1, 0, 3, 2 (right) +# SFP 8, 9, 11, 10 +NET "gth_quad_C_refclk_p" LOC = "E41"; +NET "gth_quad_C_refclk_n" LOC = "E42"; + +NET "gth_quad_C_txp_0" LOC = "F43"; +NET "gth_quad_C_txn_0" LOC = "F44"; +NET "gth_quad_C_rxp_0" LOC = "G37"; +NET "gth_quad_C_rxn_0" LOC = "G38"; + +NET "gth_quad_C_txp_1" LOC = "D43"; +NET "gth_quad_C_txn_1" LOC = "D44"; +NET "gth_quad_C_rxp_1" LOC = "F39"; +NET "gth_quad_C_rxn_1" LOC = "F40"; + +NET "gth_quad_C_txp_2" LOC = "A41"; +NET "gth_quad_C_txn_2" LOC = "A42"; +NET "gth_quad_C_rxp_2" LOC = "B39"; +NET "gth_quad_C_rxn_2" LOC = "B40"; + +NET "gth_quad_C_txp_3" LOC = "C41"; +NET "gth_quad_C_txn_3" LOC = "C42"; +NET "gth_quad_C_rxp_3" LOC = "D39"; +NET "gth_quad_C_rxn_3" LOC = "D40"; + +# Quad D X1Y0 +# Ports 11, 9, 10, 8 (left) +# SFP 0, 2, 4, 6 +NET "gth_quad_D_refclk_p" LOC = "R4"; +NET "gth_quad_D_refclk_n" LOC = "R3"; + +NET "gth_quad_D_txp_0" LOC = "T2"; +NET "gth_quad_D_txn_0" LOC = "T1"; +NET "gth_quad_D_rxp_0" LOC = "U4"; +NET "gth_quad_D_rxn_0" LOC = "U3"; + +NET "gth_quad_D_txp_1" LOC = "P2"; +NET "gth_quad_D_txn_1" LOC = "P1"; +NET "gth_quad_D_rxp_1" LOC = "T6"; +NET "gth_quad_D_rxn_1" LOC = "T5"; + +NET "gth_quad_D_txp_2" LOC = "M2"; +NET "gth_quad_D_txn_2" LOC = "M1"; +NET "gth_quad_D_rxp_2" LOC = "N8"; +NET "gth_quad_D_rxn_2" LOC = "N7"; + +NET "gth_quad_D_txp_3" LOC = "N4"; +NET "gth_quad_D_txn_3" LOC = "N3"; +NET "gth_quad_D_rxp_3" LOC = "M6"; +NET "gth_quad_D_rxn_3" LOC = "M5"; + +# Quad E X1Y1 +# Ports 4, 6, 5, 7 (left) +# SFP 3, 5, 1, 7 +NET "gth_quad_E_refclk_p" LOC = "J4"; +NET "gth_quad_E_refclk_n" LOC = "J3"; + +NET "gth_quad_E_txp_0" LOC = "L4"; +NET "gth_quad_E_txn_0" LOC = "L3"; +NET "gth_quad_E_rxp_0" LOC = "K6"; +NET "gth_quad_E_rxn_0" LOC = "K5"; + +NET "gth_quad_E_txp_1" LOC = "K2"; +NET "gth_quad_E_txn_1" LOC = "K1"; +NET "gth_quad_E_rxp_1" LOC = "L8"; +NET "gth_quad_E_rxn_1" LOC = "L7"; + +NET "gth_quad_E_txp_2" LOC = "G4"; +NET "gth_quad_E_txn_2" LOC = "G3"; +NET "gth_quad_E_rxp_2" LOC = "H6"; +NET "gth_quad_E_rxn_2" LOC = "H5"; + +NET "gth_quad_E_txp_3" LOC = "H2"; +NET "gth_quad_E_txn_3" LOC = "H1"; +NET "gth_quad_E_rxp_3" LOC = "J8"; +NET "gth_quad_E_rxn_3" LOC = "J7"; + +# Quad F X1Y2 +# Ports 1, 0, 3, 2 (left) +# SFP 8, 9, 11, 10 +NET "gth_quad_F_refclk_p" LOC = "E4"; +NET "gth_quad_F_refclk_n" LOC = "E3"; + +NET "gth_quad_F_txp_0" LOC = "F2"; +NET "gth_quad_F_txn_0" LOC = "F1"; +NET "gth_quad_F_rxp_0" LOC = "G8"; +NET "gth_quad_F_rxn_0" LOC = "G7"; + +NET "gth_quad_F_txp_1" LOC = "D2"; +NET "gth_quad_F_txn_1" LOC = "D1"; +NET "gth_quad_F_rxp_1" LOC = "F6"; +NET "gth_quad_F_rxn_1" LOC = "F5"; + +NET "gth_quad_F_txp_2" LOC = "A4"; +NET "gth_quad_F_txn_2" LOC = "A3"; +NET "gth_quad_F_rxp_2" LOC = "B6"; +NET "gth_quad_F_rxn_2" LOC = "B5"; + +NET "gth_quad_F_txp_3" LOC = "C4"; +NET "gth_quad_F_txn_3" LOC = "C3"; +NET "gth_quad_F_rxp_3" LOC = "D6"; +NET "gth_quad_F_rxn_3" LOC = "D5"; diff --git a/example/HXT100G/fpga_cxpt16/fpga/Makefile b/example/HXT100G/fpga_cxpt16/fpga/Makefile new file mode 100644 index 000000000..e152f17a4 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/fpga/Makefile @@ -0,0 +1,66 @@ + +# FPGA settings +FPGA_PART = xc6vhx565t-2ff1923 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/i2c_master.v +SYN_FILES += rtl/gth_i2c_init.v +SYN_FILES += rtl/eth_gth_phy_quad.v +SYN_FILES += rtl/axis_crosspoint_16x16.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6/example_design/ten_gig_eth_pcs_pma_v2_6_management_arbiter.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_quad.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_reset.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_init.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_tx_pcs_reset.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_rx_pcs_cdr_reset.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_pulse_synchronizer.v + +# UCF files +UCF_FILES = fpga.ucf + +# NGC paths for ngdbuild +NGC_PATHS = coregen/ten_gig_eth_pcs_pma_v2_6 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 1 -file $(FPGA_TOP).bit" >> program.cmd + echo "program -p 1" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + +program_flash: $(FPGA_TOP).mcs + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 1 -file $(FPGA_TOP).mcs" >> program.cmd + echo "program -p 1 -e" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + diff --git a/example/HXT100G/fpga_cxpt16/lib/eth b/example/HXT100G/fpga_cxpt16/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/HXT100G/fpga_cxpt16/rtl/axis_crosspoint_16x16.v b/example/HXT100G/fpga_cxpt16/rtl/axis_crosspoint_16x16.v new file mode 100644 index 000000000..25fa61576 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/rtl/axis_crosspoint_16x16.v @@ -0,0 +1,3334 @@ +/* + +Copyright (c) 2014-2018 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 16x16 crosspoint + */ +module axis_crosspoint_16x16 # +( + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ + input wire [DATA_WIDTH-1:0] input_0_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, + input wire input_0_axis_tvalid, + input wire input_0_axis_tlast, + input wire [ID_WIDTH-1:0] input_0_axis_tid, + input wire [DEST_WIDTH-1:0] input_0_axis_tdest, + input wire [USER_WIDTH-1:0] input_0_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_1_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, + input wire input_1_axis_tvalid, + input wire input_1_axis_tlast, + input wire [ID_WIDTH-1:0] input_1_axis_tid, + input wire [DEST_WIDTH-1:0] input_1_axis_tdest, + input wire [USER_WIDTH-1:0] input_1_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_2_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, + input wire input_2_axis_tvalid, + input wire input_2_axis_tlast, + input wire [ID_WIDTH-1:0] input_2_axis_tid, + input wire [DEST_WIDTH-1:0] input_2_axis_tdest, + input wire [USER_WIDTH-1:0] input_2_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_3_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, + input wire input_3_axis_tvalid, + input wire input_3_axis_tlast, + input wire [ID_WIDTH-1:0] input_3_axis_tid, + input wire [DEST_WIDTH-1:0] input_3_axis_tdest, + input wire [USER_WIDTH-1:0] input_3_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_4_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_4_axis_tkeep, + input wire input_4_axis_tvalid, + input wire input_4_axis_tlast, + input wire [ID_WIDTH-1:0] input_4_axis_tid, + input wire [DEST_WIDTH-1:0] input_4_axis_tdest, + input wire [USER_WIDTH-1:0] input_4_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_5_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_5_axis_tkeep, + input wire input_5_axis_tvalid, + input wire input_5_axis_tlast, + input wire [ID_WIDTH-1:0] input_5_axis_tid, + input wire [DEST_WIDTH-1:0] input_5_axis_tdest, + input wire [USER_WIDTH-1:0] input_5_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_6_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_6_axis_tkeep, + input wire input_6_axis_tvalid, + input wire input_6_axis_tlast, + input wire [ID_WIDTH-1:0] input_6_axis_tid, + input wire [DEST_WIDTH-1:0] input_6_axis_tdest, + input wire [USER_WIDTH-1:0] input_6_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_7_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_7_axis_tkeep, + input wire input_7_axis_tvalid, + input wire input_7_axis_tlast, + input wire [ID_WIDTH-1:0] input_7_axis_tid, + input wire [DEST_WIDTH-1:0] input_7_axis_tdest, + input wire [USER_WIDTH-1:0] input_7_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_8_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_8_axis_tkeep, + input wire input_8_axis_tvalid, + input wire input_8_axis_tlast, + input wire [ID_WIDTH-1:0] input_8_axis_tid, + input wire [DEST_WIDTH-1:0] input_8_axis_tdest, + input wire [USER_WIDTH-1:0] input_8_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_9_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_9_axis_tkeep, + input wire input_9_axis_tvalid, + input wire input_9_axis_tlast, + input wire [ID_WIDTH-1:0] input_9_axis_tid, + input wire [DEST_WIDTH-1:0] input_9_axis_tdest, + input wire [USER_WIDTH-1:0] input_9_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_10_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_10_axis_tkeep, + input wire input_10_axis_tvalid, + input wire input_10_axis_tlast, + input wire [ID_WIDTH-1:0] input_10_axis_tid, + input wire [DEST_WIDTH-1:0] input_10_axis_tdest, + input wire [USER_WIDTH-1:0] input_10_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_11_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_11_axis_tkeep, + input wire input_11_axis_tvalid, + input wire input_11_axis_tlast, + input wire [ID_WIDTH-1:0] input_11_axis_tid, + input wire [DEST_WIDTH-1:0] input_11_axis_tdest, + input wire [USER_WIDTH-1:0] input_11_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_12_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_12_axis_tkeep, + input wire input_12_axis_tvalid, + input wire input_12_axis_tlast, + input wire [ID_WIDTH-1:0] input_12_axis_tid, + input wire [DEST_WIDTH-1:0] input_12_axis_tdest, + input wire [USER_WIDTH-1:0] input_12_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_13_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_13_axis_tkeep, + input wire input_13_axis_tvalid, + input wire input_13_axis_tlast, + input wire [ID_WIDTH-1:0] input_13_axis_tid, + input wire [DEST_WIDTH-1:0] input_13_axis_tdest, + input wire [USER_WIDTH-1:0] input_13_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_14_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_14_axis_tkeep, + input wire input_14_axis_tvalid, + input wire input_14_axis_tlast, + input wire [ID_WIDTH-1:0] input_14_axis_tid, + input wire [DEST_WIDTH-1:0] input_14_axis_tdest, + input wire [USER_WIDTH-1:0] input_14_axis_tuser, + + input wire [DATA_WIDTH-1:0] input_15_axis_tdata, + input wire [KEEP_WIDTH-1:0] input_15_axis_tkeep, + input wire input_15_axis_tvalid, + input wire input_15_axis_tlast, + input wire [ID_WIDTH-1:0] input_15_axis_tid, + input wire [DEST_WIDTH-1:0] input_15_axis_tdest, + input wire [USER_WIDTH-1:0] input_15_axis_tuser, + + /* + * AXI Stream outputs + */ + output wire [DATA_WIDTH-1:0] output_0_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, + output wire output_0_axis_tvalid, + output wire output_0_axis_tlast, + output wire [ID_WIDTH-1:0] output_0_axis_tid, + output wire [DEST_WIDTH-1:0] output_0_axis_tdest, + output wire [USER_WIDTH-1:0] output_0_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_1_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, + output wire output_1_axis_tvalid, + output wire output_1_axis_tlast, + output wire [ID_WIDTH-1:0] output_1_axis_tid, + output wire [DEST_WIDTH-1:0] output_1_axis_tdest, + output wire [USER_WIDTH-1:0] output_1_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_2_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, + output wire output_2_axis_tvalid, + output wire output_2_axis_tlast, + output wire [ID_WIDTH-1:0] output_2_axis_tid, + output wire [DEST_WIDTH-1:0] output_2_axis_tdest, + output wire [USER_WIDTH-1:0] output_2_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_3_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, + output wire output_3_axis_tvalid, + output wire output_3_axis_tlast, + output wire [ID_WIDTH-1:0] output_3_axis_tid, + output wire [DEST_WIDTH-1:0] output_3_axis_tdest, + output wire [USER_WIDTH-1:0] output_3_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_4_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_4_axis_tkeep, + output wire output_4_axis_tvalid, + output wire output_4_axis_tlast, + output wire [ID_WIDTH-1:0] output_4_axis_tid, + output wire [DEST_WIDTH-1:0] output_4_axis_tdest, + output wire [USER_WIDTH-1:0] output_4_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_5_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_5_axis_tkeep, + output wire output_5_axis_tvalid, + output wire output_5_axis_tlast, + output wire [ID_WIDTH-1:0] output_5_axis_tid, + output wire [DEST_WIDTH-1:0] output_5_axis_tdest, + output wire [USER_WIDTH-1:0] output_5_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_6_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_6_axis_tkeep, + output wire output_6_axis_tvalid, + output wire output_6_axis_tlast, + output wire [ID_WIDTH-1:0] output_6_axis_tid, + output wire [DEST_WIDTH-1:0] output_6_axis_tdest, + output wire [USER_WIDTH-1:0] output_6_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_7_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_7_axis_tkeep, + output wire output_7_axis_tvalid, + output wire output_7_axis_tlast, + output wire [ID_WIDTH-1:0] output_7_axis_tid, + output wire [DEST_WIDTH-1:0] output_7_axis_tdest, + output wire [USER_WIDTH-1:0] output_7_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_8_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_8_axis_tkeep, + output wire output_8_axis_tvalid, + output wire output_8_axis_tlast, + output wire [ID_WIDTH-1:0] output_8_axis_tid, + output wire [DEST_WIDTH-1:0] output_8_axis_tdest, + output wire [USER_WIDTH-1:0] output_8_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_9_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_9_axis_tkeep, + output wire output_9_axis_tvalid, + output wire output_9_axis_tlast, + output wire [ID_WIDTH-1:0] output_9_axis_tid, + output wire [DEST_WIDTH-1:0] output_9_axis_tdest, + output wire [USER_WIDTH-1:0] output_9_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_10_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_10_axis_tkeep, + output wire output_10_axis_tvalid, + output wire output_10_axis_tlast, + output wire [ID_WIDTH-1:0] output_10_axis_tid, + output wire [DEST_WIDTH-1:0] output_10_axis_tdest, + output wire [USER_WIDTH-1:0] output_10_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_11_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_11_axis_tkeep, + output wire output_11_axis_tvalid, + output wire output_11_axis_tlast, + output wire [ID_WIDTH-1:0] output_11_axis_tid, + output wire [DEST_WIDTH-1:0] output_11_axis_tdest, + output wire [USER_WIDTH-1:0] output_11_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_12_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_12_axis_tkeep, + output wire output_12_axis_tvalid, + output wire output_12_axis_tlast, + output wire [ID_WIDTH-1:0] output_12_axis_tid, + output wire [DEST_WIDTH-1:0] output_12_axis_tdest, + output wire [USER_WIDTH-1:0] output_12_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_13_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_13_axis_tkeep, + output wire output_13_axis_tvalid, + output wire output_13_axis_tlast, + output wire [ID_WIDTH-1:0] output_13_axis_tid, + output wire [DEST_WIDTH-1:0] output_13_axis_tdest, + output wire [USER_WIDTH-1:0] output_13_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_14_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_14_axis_tkeep, + output wire output_14_axis_tvalid, + output wire output_14_axis_tlast, + output wire [ID_WIDTH-1:0] output_14_axis_tid, + output wire [DEST_WIDTH-1:0] output_14_axis_tdest, + output wire [USER_WIDTH-1:0] output_14_axis_tuser, + + output wire [DATA_WIDTH-1:0] output_15_axis_tdata, + output wire [KEEP_WIDTH-1:0] output_15_axis_tkeep, + output wire output_15_axis_tvalid, + output wire output_15_axis_tlast, + output wire [ID_WIDTH-1:0] output_15_axis_tid, + output wire [DEST_WIDTH-1:0] output_15_axis_tdest, + output wire [USER_WIDTH-1:0] output_15_axis_tuser, + + /* + * Control + */ + input wire [3:0] output_0_select, + input wire [3:0] output_1_select, + input wire [3:0] output_2_select, + input wire [3:0] output_3_select, + input wire [3:0] output_4_select, + input wire [3:0] output_5_select, + input wire [3:0] output_6_select, + input wire [3:0] output_7_select, + input wire [3:0] output_8_select, + input wire [3:0] output_9_select, + input wire [3:0] output_10_select, + input wire [3:0] output_11_select, + input wire [3:0] output_12_select, + input wire [3:0] output_13_select, + input wire [3:0] output_14_select, + input wire [3:0] output_15_select +); + +reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_0_axis_tvalid_reg = 1'b0; +reg input_0_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_0_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_0_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_1_axis_tvalid_reg = 1'b0; +reg input_1_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_1_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_1_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_2_axis_tvalid_reg = 1'b0; +reg input_2_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_2_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_2_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_3_axis_tvalid_reg = 1'b0; +reg input_3_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_3_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_3_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_4_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_4_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_4_axis_tvalid_reg = 1'b0; +reg input_4_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_4_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_4_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_4_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_5_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_5_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_5_axis_tvalid_reg = 1'b0; +reg input_5_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_5_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_5_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_5_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_6_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_6_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_6_axis_tvalid_reg = 1'b0; +reg input_6_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_6_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_6_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_6_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_7_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_7_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_7_axis_tvalid_reg = 1'b0; +reg input_7_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_7_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_7_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_7_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_8_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_8_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_8_axis_tvalid_reg = 1'b0; +reg input_8_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_8_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_8_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_8_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_9_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_9_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_9_axis_tvalid_reg = 1'b0; +reg input_9_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_9_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_9_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_9_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_10_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_10_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_10_axis_tvalid_reg = 1'b0; +reg input_10_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_10_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_10_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_10_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_11_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_11_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_11_axis_tvalid_reg = 1'b0; +reg input_11_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_11_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_11_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_11_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_12_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_12_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_12_axis_tvalid_reg = 1'b0; +reg input_12_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_12_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_12_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_12_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_13_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_13_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_13_axis_tvalid_reg = 1'b0; +reg input_13_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_13_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_13_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_13_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_14_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_14_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_14_axis_tvalid_reg = 1'b0; +reg input_14_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_14_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_14_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_14_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] input_15_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] input_15_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg input_15_axis_tvalid_reg = 1'b0; +reg input_15_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] input_15_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] input_15_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] input_15_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_0_axis_tvalid_reg = 1'b0; +reg output_0_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_0_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_0_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_1_axis_tvalid_reg = 1'b0; +reg output_1_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_1_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_1_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_2_axis_tvalid_reg = 1'b0; +reg output_2_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_2_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_2_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_3_axis_tvalid_reg = 1'b0; +reg output_3_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_3_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_3_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_4_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_4_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_4_axis_tvalid_reg = 1'b0; +reg output_4_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_4_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_4_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_4_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_5_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_5_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_5_axis_tvalid_reg = 1'b0; +reg output_5_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_5_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_5_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_5_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_6_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_6_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_6_axis_tvalid_reg = 1'b0; +reg output_6_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_6_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_6_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_6_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_7_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_7_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_7_axis_tvalid_reg = 1'b0; +reg output_7_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_7_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_7_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_7_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_8_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_8_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_8_axis_tvalid_reg = 1'b0; +reg output_8_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_8_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_8_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_8_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_9_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_9_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_9_axis_tvalid_reg = 1'b0; +reg output_9_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_9_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_9_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_9_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_10_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_10_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_10_axis_tvalid_reg = 1'b0; +reg output_10_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_10_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_10_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_10_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_11_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_11_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_11_axis_tvalid_reg = 1'b0; +reg output_11_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_11_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_11_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_11_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_12_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_12_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_12_axis_tvalid_reg = 1'b0; +reg output_12_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_12_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_12_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_12_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_13_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_13_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_13_axis_tvalid_reg = 1'b0; +reg output_13_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_13_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_13_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_13_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_14_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_14_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_14_axis_tvalid_reg = 1'b0; +reg output_14_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_14_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_14_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_14_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] output_15_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_15_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_15_axis_tvalid_reg = 1'b0; +reg output_15_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_15_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_15_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_15_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [3:0] output_0_select_reg = 4'd0; +reg [3:0] output_1_select_reg = 4'd0; +reg [3:0] output_2_select_reg = 4'd0; +reg [3:0] output_3_select_reg = 4'd0; +reg [3:0] output_4_select_reg = 4'd0; +reg [3:0] output_5_select_reg = 4'd0; +reg [3:0] output_6_select_reg = 4'd0; +reg [3:0] output_7_select_reg = 4'd0; +reg [3:0] output_8_select_reg = 4'd0; +reg [3:0] output_9_select_reg = 4'd0; +reg [3:0] output_10_select_reg = 4'd0; +reg [3:0] output_11_select_reg = 4'd0; +reg [3:0] output_12_select_reg = 4'd0; +reg [3:0] output_13_select_reg = 4'd0; +reg [3:0] output_14_select_reg = 4'd0; +reg [3:0] output_15_select_reg = 4'd0; + +assign output_0_axis_tdata = output_0_axis_tdata_reg; +assign output_0_axis_tkeep = KEEP_ENABLE ? output_0_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_0_axis_tvalid = output_0_axis_tvalid_reg; +assign output_0_axis_tlast = LAST_ENABLE ? output_0_axis_tlast_reg : 1'b1; +assign output_0_axis_tid = ID_ENABLE ? output_0_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_0_axis_tdest = DEST_ENABLE ? output_0_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_0_axis_tuser = USER_ENABLE ? output_0_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_1_axis_tdata = output_1_axis_tdata_reg; +assign output_1_axis_tkeep = KEEP_ENABLE ? output_1_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_1_axis_tvalid = output_1_axis_tvalid_reg; +assign output_1_axis_tlast = LAST_ENABLE ? output_1_axis_tlast_reg : 1'b1; +assign output_1_axis_tid = ID_ENABLE ? output_1_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_1_axis_tdest = DEST_ENABLE ? output_1_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_1_axis_tuser = USER_ENABLE ? output_1_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_2_axis_tdata = output_2_axis_tdata_reg; +assign output_2_axis_tkeep = KEEP_ENABLE ? output_2_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_2_axis_tvalid = output_2_axis_tvalid_reg; +assign output_2_axis_tlast = LAST_ENABLE ? output_2_axis_tlast_reg : 1'b1; +assign output_2_axis_tid = ID_ENABLE ? output_2_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_2_axis_tdest = DEST_ENABLE ? output_2_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_2_axis_tuser = USER_ENABLE ? output_2_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_3_axis_tdata = output_3_axis_tdata_reg; +assign output_3_axis_tkeep = KEEP_ENABLE ? output_3_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_3_axis_tvalid = output_3_axis_tvalid_reg; +assign output_3_axis_tlast = LAST_ENABLE ? output_3_axis_tlast_reg : 1'b1; +assign output_3_axis_tid = ID_ENABLE ? output_3_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_3_axis_tdest = DEST_ENABLE ? output_3_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_3_axis_tuser = USER_ENABLE ? output_3_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_4_axis_tdata = output_4_axis_tdata_reg; +assign output_4_axis_tkeep = KEEP_ENABLE ? output_4_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_4_axis_tvalid = output_4_axis_tvalid_reg; +assign output_4_axis_tlast = LAST_ENABLE ? output_4_axis_tlast_reg : 1'b1; +assign output_4_axis_tid = ID_ENABLE ? output_4_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_4_axis_tdest = DEST_ENABLE ? output_4_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_4_axis_tuser = USER_ENABLE ? output_4_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_5_axis_tdata = output_5_axis_tdata_reg; +assign output_5_axis_tkeep = KEEP_ENABLE ? output_5_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_5_axis_tvalid = output_5_axis_tvalid_reg; +assign output_5_axis_tlast = LAST_ENABLE ? output_5_axis_tlast_reg : 1'b1; +assign output_5_axis_tid = ID_ENABLE ? output_5_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_5_axis_tdest = DEST_ENABLE ? output_5_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_5_axis_tuser = USER_ENABLE ? output_5_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_6_axis_tdata = output_6_axis_tdata_reg; +assign output_6_axis_tkeep = KEEP_ENABLE ? output_6_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_6_axis_tvalid = output_6_axis_tvalid_reg; +assign output_6_axis_tlast = LAST_ENABLE ? output_6_axis_tlast_reg : 1'b1; +assign output_6_axis_tid = ID_ENABLE ? output_6_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_6_axis_tdest = DEST_ENABLE ? output_6_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_6_axis_tuser = USER_ENABLE ? output_6_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_7_axis_tdata = output_7_axis_tdata_reg; +assign output_7_axis_tkeep = KEEP_ENABLE ? output_7_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_7_axis_tvalid = output_7_axis_tvalid_reg; +assign output_7_axis_tlast = LAST_ENABLE ? output_7_axis_tlast_reg : 1'b1; +assign output_7_axis_tid = ID_ENABLE ? output_7_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_7_axis_tdest = DEST_ENABLE ? output_7_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_7_axis_tuser = USER_ENABLE ? output_7_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_8_axis_tdata = output_8_axis_tdata_reg; +assign output_8_axis_tkeep = KEEP_ENABLE ? output_8_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_8_axis_tvalid = output_8_axis_tvalid_reg; +assign output_8_axis_tlast = LAST_ENABLE ? output_8_axis_tlast_reg : 1'b1; +assign output_8_axis_tid = ID_ENABLE ? output_8_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_8_axis_tdest = DEST_ENABLE ? output_8_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_8_axis_tuser = USER_ENABLE ? output_8_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_9_axis_tdata = output_9_axis_tdata_reg; +assign output_9_axis_tkeep = KEEP_ENABLE ? output_9_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_9_axis_tvalid = output_9_axis_tvalid_reg; +assign output_9_axis_tlast = LAST_ENABLE ? output_9_axis_tlast_reg : 1'b1; +assign output_9_axis_tid = ID_ENABLE ? output_9_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_9_axis_tdest = DEST_ENABLE ? output_9_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_9_axis_tuser = USER_ENABLE ? output_9_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_10_axis_tdata = output_10_axis_tdata_reg; +assign output_10_axis_tkeep = KEEP_ENABLE ? output_10_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_10_axis_tvalid = output_10_axis_tvalid_reg; +assign output_10_axis_tlast = LAST_ENABLE ? output_10_axis_tlast_reg : 1'b1; +assign output_10_axis_tid = ID_ENABLE ? output_10_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_10_axis_tdest = DEST_ENABLE ? output_10_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_10_axis_tuser = USER_ENABLE ? output_10_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_11_axis_tdata = output_11_axis_tdata_reg; +assign output_11_axis_tkeep = KEEP_ENABLE ? output_11_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_11_axis_tvalid = output_11_axis_tvalid_reg; +assign output_11_axis_tlast = LAST_ENABLE ? output_11_axis_tlast_reg : 1'b1; +assign output_11_axis_tid = ID_ENABLE ? output_11_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_11_axis_tdest = DEST_ENABLE ? output_11_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_11_axis_tuser = USER_ENABLE ? output_11_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_12_axis_tdata = output_12_axis_tdata_reg; +assign output_12_axis_tkeep = KEEP_ENABLE ? output_12_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_12_axis_tvalid = output_12_axis_tvalid_reg; +assign output_12_axis_tlast = LAST_ENABLE ? output_12_axis_tlast_reg : 1'b1; +assign output_12_axis_tid = ID_ENABLE ? output_12_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_12_axis_tdest = DEST_ENABLE ? output_12_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_12_axis_tuser = USER_ENABLE ? output_12_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_13_axis_tdata = output_13_axis_tdata_reg; +assign output_13_axis_tkeep = KEEP_ENABLE ? output_13_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_13_axis_tvalid = output_13_axis_tvalid_reg; +assign output_13_axis_tlast = LAST_ENABLE ? output_13_axis_tlast_reg : 1'b1; +assign output_13_axis_tid = ID_ENABLE ? output_13_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_13_axis_tdest = DEST_ENABLE ? output_13_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_13_axis_tuser = USER_ENABLE ? output_13_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_14_axis_tdata = output_14_axis_tdata_reg; +assign output_14_axis_tkeep = KEEP_ENABLE ? output_14_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_14_axis_tvalid = output_14_axis_tvalid_reg; +assign output_14_axis_tlast = LAST_ENABLE ? output_14_axis_tlast_reg : 1'b1; +assign output_14_axis_tid = ID_ENABLE ? output_14_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_14_axis_tdest = DEST_ENABLE ? output_14_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_14_axis_tuser = USER_ENABLE ? output_14_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +assign output_15_axis_tdata = output_15_axis_tdata_reg; +assign output_15_axis_tkeep = KEEP_ENABLE ? output_15_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_15_axis_tvalid = output_15_axis_tvalid_reg; +assign output_15_axis_tlast = LAST_ENABLE ? output_15_axis_tlast_reg : 1'b1; +assign output_15_axis_tid = ID_ENABLE ? output_15_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_15_axis_tdest = DEST_ENABLE ? output_15_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_15_axis_tuser = USER_ENABLE ? output_15_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +always @(posedge clk) begin + if (rst) begin + output_0_select_reg <= 4'd0; + output_1_select_reg <= 4'd0; + output_2_select_reg <= 4'd0; + output_3_select_reg <= 4'd0; + output_4_select_reg <= 4'd0; + output_5_select_reg <= 4'd0; + output_6_select_reg <= 4'd0; + output_7_select_reg <= 4'd0; + output_8_select_reg <= 4'd0; + output_9_select_reg <= 4'd0; + output_10_select_reg <= 4'd0; + output_11_select_reg <= 4'd0; + output_12_select_reg <= 4'd0; + output_13_select_reg <= 4'd0; + output_14_select_reg <= 4'd0; + output_15_select_reg <= 4'd0; + + input_0_axis_tvalid_reg <= 1'b0; + input_1_axis_tvalid_reg <= 1'b0; + input_2_axis_tvalid_reg <= 1'b0; + input_3_axis_tvalid_reg <= 1'b0; + input_4_axis_tvalid_reg <= 1'b0; + input_5_axis_tvalid_reg <= 1'b0; + input_6_axis_tvalid_reg <= 1'b0; + input_7_axis_tvalid_reg <= 1'b0; + input_8_axis_tvalid_reg <= 1'b0; + input_9_axis_tvalid_reg <= 1'b0; + input_10_axis_tvalid_reg <= 1'b0; + input_11_axis_tvalid_reg <= 1'b0; + input_12_axis_tvalid_reg <= 1'b0; + input_13_axis_tvalid_reg <= 1'b0; + input_14_axis_tvalid_reg <= 1'b0; + input_15_axis_tvalid_reg <= 1'b0; + + output_0_axis_tvalid_reg <= 1'b0; + output_1_axis_tvalid_reg <= 1'b0; + output_2_axis_tvalid_reg <= 1'b0; + output_3_axis_tvalid_reg <= 1'b0; + output_4_axis_tvalid_reg <= 1'b0; + output_5_axis_tvalid_reg <= 1'b0; + output_6_axis_tvalid_reg <= 1'b0; + output_7_axis_tvalid_reg <= 1'b0; + output_8_axis_tvalid_reg <= 1'b0; + output_9_axis_tvalid_reg <= 1'b0; + output_10_axis_tvalid_reg <= 1'b0; + output_11_axis_tvalid_reg <= 1'b0; + output_12_axis_tvalid_reg <= 1'b0; + output_13_axis_tvalid_reg <= 1'b0; + output_14_axis_tvalid_reg <= 1'b0; + output_15_axis_tvalid_reg <= 1'b0; + end else begin + input_0_axis_tvalid_reg <= input_0_axis_tvalid; + input_1_axis_tvalid_reg <= input_1_axis_tvalid; + input_2_axis_tvalid_reg <= input_2_axis_tvalid; + input_3_axis_tvalid_reg <= input_3_axis_tvalid; + input_4_axis_tvalid_reg <= input_4_axis_tvalid; + input_5_axis_tvalid_reg <= input_5_axis_tvalid; + input_6_axis_tvalid_reg <= input_6_axis_tvalid; + input_7_axis_tvalid_reg <= input_7_axis_tvalid; + input_8_axis_tvalid_reg <= input_8_axis_tvalid; + input_9_axis_tvalid_reg <= input_9_axis_tvalid; + input_10_axis_tvalid_reg <= input_10_axis_tvalid; + input_11_axis_tvalid_reg <= input_11_axis_tvalid; + input_12_axis_tvalid_reg <= input_12_axis_tvalid; + input_13_axis_tvalid_reg <= input_13_axis_tvalid; + input_14_axis_tvalid_reg <= input_14_axis_tvalid; + input_15_axis_tvalid_reg <= input_15_axis_tvalid; + + output_0_select_reg <= output_0_select; + output_1_select_reg <= output_1_select; + output_2_select_reg <= output_2_select; + output_3_select_reg <= output_3_select; + output_4_select_reg <= output_4_select; + output_5_select_reg <= output_5_select; + output_6_select_reg <= output_6_select; + output_7_select_reg <= output_7_select; + output_8_select_reg <= output_8_select; + output_9_select_reg <= output_9_select; + output_10_select_reg <= output_10_select; + output_11_select_reg <= output_11_select; + output_12_select_reg <= output_12_select; + output_13_select_reg <= output_13_select; + output_14_select_reg <= output_14_select; + output_15_select_reg <= output_15_select; + + case (output_0_select_reg) + 4'd0: output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_0_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_0_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_0_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_0_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_0_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_0_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_0_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_0_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_0_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_0_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_0_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_0_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_1_select_reg) + 4'd0: output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_1_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_1_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_1_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_1_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_1_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_1_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_1_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_1_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_1_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_1_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_1_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_1_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_2_select_reg) + 4'd0: output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_2_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_2_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_2_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_2_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_2_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_2_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_2_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_2_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_2_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_2_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_2_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_2_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_3_select_reg) + 4'd0: output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_3_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_3_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_3_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_3_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_3_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_3_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_3_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_3_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_3_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_3_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_3_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_3_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_4_select_reg) + 4'd0: output_4_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_4_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_4_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_4_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_4_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_4_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_4_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_4_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_4_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_4_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_4_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_4_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_4_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_4_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_4_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_4_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_5_select_reg) + 4'd0: output_5_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_5_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_5_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_5_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_5_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_5_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_5_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_5_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_5_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_5_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_5_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_5_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_5_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_5_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_5_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_5_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_6_select_reg) + 4'd0: output_6_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_6_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_6_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_6_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_6_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_6_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_6_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_6_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_6_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_6_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_6_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_6_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_6_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_6_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_6_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_6_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_7_select_reg) + 4'd0: output_7_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_7_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_7_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_7_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_7_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_7_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_7_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_7_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_7_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_7_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_7_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_7_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_7_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_7_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_7_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_7_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_8_select_reg) + 4'd0: output_8_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_8_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_8_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_8_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_8_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_8_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_8_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_8_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_8_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_8_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_8_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_8_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_8_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_8_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_8_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_8_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_9_select_reg) + 4'd0: output_9_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_9_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_9_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_9_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_9_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_9_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_9_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_9_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_9_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_9_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_9_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_9_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_9_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_9_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_9_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_9_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_10_select_reg) + 4'd0: output_10_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_10_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_10_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_10_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_10_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_10_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_10_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_10_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_10_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_10_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_10_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_10_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_10_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_10_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_10_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_10_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_11_select_reg) + 4'd0: output_11_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_11_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_11_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_11_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_11_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_11_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_11_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_11_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_11_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_11_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_11_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_11_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_11_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_11_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_11_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_11_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_12_select_reg) + 4'd0: output_12_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_12_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_12_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_12_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_12_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_12_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_12_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_12_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_12_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_12_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_12_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_12_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_12_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_12_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_12_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_12_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_13_select_reg) + 4'd0: output_13_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_13_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_13_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_13_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_13_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_13_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_13_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_13_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_13_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_13_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_13_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_13_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_13_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_13_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_13_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_13_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_14_select_reg) + 4'd0: output_14_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_14_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_14_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_14_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_14_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_14_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_14_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_14_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_14_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_14_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_14_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_14_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_14_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_14_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_14_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_14_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + + case (output_15_select_reg) + 4'd0: output_15_axis_tvalid_reg <= input_0_axis_tvalid_reg; + 4'd1: output_15_axis_tvalid_reg <= input_1_axis_tvalid_reg; + 4'd2: output_15_axis_tvalid_reg <= input_2_axis_tvalid_reg; + 4'd3: output_15_axis_tvalid_reg <= input_3_axis_tvalid_reg; + 4'd4: output_15_axis_tvalid_reg <= input_4_axis_tvalid_reg; + 4'd5: output_15_axis_tvalid_reg <= input_5_axis_tvalid_reg; + 4'd6: output_15_axis_tvalid_reg <= input_6_axis_tvalid_reg; + 4'd7: output_15_axis_tvalid_reg <= input_7_axis_tvalid_reg; + 4'd8: output_15_axis_tvalid_reg <= input_8_axis_tvalid_reg; + 4'd9: output_15_axis_tvalid_reg <= input_9_axis_tvalid_reg; + 4'd10: output_15_axis_tvalid_reg <= input_10_axis_tvalid_reg; + 4'd11: output_15_axis_tvalid_reg <= input_11_axis_tvalid_reg; + 4'd12: output_15_axis_tvalid_reg <= input_12_axis_tvalid_reg; + 4'd13: output_15_axis_tvalid_reg <= input_13_axis_tvalid_reg; + 4'd14: output_15_axis_tvalid_reg <= input_14_axis_tvalid_reg; + 4'd15: output_15_axis_tvalid_reg <= input_15_axis_tvalid_reg; + endcase + end + + input_0_axis_tdata_reg <= input_0_axis_tdata; + input_0_axis_tkeep_reg <= input_0_axis_tkeep; + input_0_axis_tlast_reg <= input_0_axis_tlast; + input_0_axis_tid_reg <= input_0_axis_tid; + input_0_axis_tdest_reg <= input_0_axis_tdest; + input_0_axis_tuser_reg <= input_0_axis_tuser; + + input_1_axis_tdata_reg <= input_1_axis_tdata; + input_1_axis_tkeep_reg <= input_1_axis_tkeep; + input_1_axis_tlast_reg <= input_1_axis_tlast; + input_1_axis_tid_reg <= input_1_axis_tid; + input_1_axis_tdest_reg <= input_1_axis_tdest; + input_1_axis_tuser_reg <= input_1_axis_tuser; + + input_2_axis_tdata_reg <= input_2_axis_tdata; + input_2_axis_tkeep_reg <= input_2_axis_tkeep; + input_2_axis_tlast_reg <= input_2_axis_tlast; + input_2_axis_tid_reg <= input_2_axis_tid; + input_2_axis_tdest_reg <= input_2_axis_tdest; + input_2_axis_tuser_reg <= input_2_axis_tuser; + + input_3_axis_tdata_reg <= input_3_axis_tdata; + input_3_axis_tkeep_reg <= input_3_axis_tkeep; + input_3_axis_tlast_reg <= input_3_axis_tlast; + input_3_axis_tid_reg <= input_3_axis_tid; + input_3_axis_tdest_reg <= input_3_axis_tdest; + input_3_axis_tuser_reg <= input_3_axis_tuser; + + input_4_axis_tdata_reg <= input_4_axis_tdata; + input_4_axis_tkeep_reg <= input_4_axis_tkeep; + input_4_axis_tlast_reg <= input_4_axis_tlast; + input_4_axis_tid_reg <= input_4_axis_tid; + input_4_axis_tdest_reg <= input_4_axis_tdest; + input_4_axis_tuser_reg <= input_4_axis_tuser; + + input_5_axis_tdata_reg <= input_5_axis_tdata; + input_5_axis_tkeep_reg <= input_5_axis_tkeep; + input_5_axis_tlast_reg <= input_5_axis_tlast; + input_5_axis_tid_reg <= input_5_axis_tid; + input_5_axis_tdest_reg <= input_5_axis_tdest; + input_5_axis_tuser_reg <= input_5_axis_tuser; + + input_6_axis_tdata_reg <= input_6_axis_tdata; + input_6_axis_tkeep_reg <= input_6_axis_tkeep; + input_6_axis_tlast_reg <= input_6_axis_tlast; + input_6_axis_tid_reg <= input_6_axis_tid; + input_6_axis_tdest_reg <= input_6_axis_tdest; + input_6_axis_tuser_reg <= input_6_axis_tuser; + + input_7_axis_tdata_reg <= input_7_axis_tdata; + input_7_axis_tkeep_reg <= input_7_axis_tkeep; + input_7_axis_tlast_reg <= input_7_axis_tlast; + input_7_axis_tid_reg <= input_7_axis_tid; + input_7_axis_tdest_reg <= input_7_axis_tdest; + input_7_axis_tuser_reg <= input_7_axis_tuser; + + input_8_axis_tdata_reg <= input_8_axis_tdata; + input_8_axis_tkeep_reg <= input_8_axis_tkeep; + input_8_axis_tlast_reg <= input_8_axis_tlast; + input_8_axis_tid_reg <= input_8_axis_tid; + input_8_axis_tdest_reg <= input_8_axis_tdest; + input_8_axis_tuser_reg <= input_8_axis_tuser; + + input_9_axis_tdata_reg <= input_9_axis_tdata; + input_9_axis_tkeep_reg <= input_9_axis_tkeep; + input_9_axis_tlast_reg <= input_9_axis_tlast; + input_9_axis_tid_reg <= input_9_axis_tid; + input_9_axis_tdest_reg <= input_9_axis_tdest; + input_9_axis_tuser_reg <= input_9_axis_tuser; + + input_10_axis_tdata_reg <= input_10_axis_tdata; + input_10_axis_tkeep_reg <= input_10_axis_tkeep; + input_10_axis_tlast_reg <= input_10_axis_tlast; + input_10_axis_tid_reg <= input_10_axis_tid; + input_10_axis_tdest_reg <= input_10_axis_tdest; + input_10_axis_tuser_reg <= input_10_axis_tuser; + + input_11_axis_tdata_reg <= input_11_axis_tdata; + input_11_axis_tkeep_reg <= input_11_axis_tkeep; + input_11_axis_tlast_reg <= input_11_axis_tlast; + input_11_axis_tid_reg <= input_11_axis_tid; + input_11_axis_tdest_reg <= input_11_axis_tdest; + input_11_axis_tuser_reg <= input_11_axis_tuser; + + input_12_axis_tdata_reg <= input_12_axis_tdata; + input_12_axis_tkeep_reg <= input_12_axis_tkeep; + input_12_axis_tlast_reg <= input_12_axis_tlast; + input_12_axis_tid_reg <= input_12_axis_tid; + input_12_axis_tdest_reg <= input_12_axis_tdest; + input_12_axis_tuser_reg <= input_12_axis_tuser; + + input_13_axis_tdata_reg <= input_13_axis_tdata; + input_13_axis_tkeep_reg <= input_13_axis_tkeep; + input_13_axis_tlast_reg <= input_13_axis_tlast; + input_13_axis_tid_reg <= input_13_axis_tid; + input_13_axis_tdest_reg <= input_13_axis_tdest; + input_13_axis_tuser_reg <= input_13_axis_tuser; + + input_14_axis_tdata_reg <= input_14_axis_tdata; + input_14_axis_tkeep_reg <= input_14_axis_tkeep; + input_14_axis_tlast_reg <= input_14_axis_tlast; + input_14_axis_tid_reg <= input_14_axis_tid; + input_14_axis_tdest_reg <= input_14_axis_tdest; + input_14_axis_tuser_reg <= input_14_axis_tuser; + + input_15_axis_tdata_reg <= input_15_axis_tdata; + input_15_axis_tkeep_reg <= input_15_axis_tkeep; + input_15_axis_tlast_reg <= input_15_axis_tlast; + input_15_axis_tid_reg <= input_15_axis_tid; + input_15_axis_tdest_reg <= input_15_axis_tdest; + input_15_axis_tuser_reg <= input_15_axis_tuser; + + case (output_0_select_reg) + 4'd0: begin + output_0_axis_tdata_reg <= input_0_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_0_axis_tlast_reg; + output_0_axis_tid_reg <= input_0_axis_tid_reg; + output_0_axis_tdest_reg <= input_0_axis_tdest_reg; + output_0_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_0_axis_tdata_reg <= input_1_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_1_axis_tlast_reg; + output_0_axis_tid_reg <= input_1_axis_tid_reg; + output_0_axis_tdest_reg <= input_1_axis_tdest_reg; + output_0_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_0_axis_tdata_reg <= input_2_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_2_axis_tlast_reg; + output_0_axis_tid_reg <= input_2_axis_tid_reg; + output_0_axis_tdest_reg <= input_2_axis_tdest_reg; + output_0_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_0_axis_tdata_reg <= input_3_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_3_axis_tlast_reg; + output_0_axis_tid_reg <= input_3_axis_tid_reg; + output_0_axis_tdest_reg <= input_3_axis_tdest_reg; + output_0_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_0_axis_tdata_reg <= input_4_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_4_axis_tlast_reg; + output_0_axis_tid_reg <= input_4_axis_tid_reg; + output_0_axis_tdest_reg <= input_4_axis_tdest_reg; + output_0_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_0_axis_tdata_reg <= input_5_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_5_axis_tlast_reg; + output_0_axis_tid_reg <= input_5_axis_tid_reg; + output_0_axis_tdest_reg <= input_5_axis_tdest_reg; + output_0_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_0_axis_tdata_reg <= input_6_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_6_axis_tlast_reg; + output_0_axis_tid_reg <= input_6_axis_tid_reg; + output_0_axis_tdest_reg <= input_6_axis_tdest_reg; + output_0_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_0_axis_tdata_reg <= input_7_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_7_axis_tlast_reg; + output_0_axis_tid_reg <= input_7_axis_tid_reg; + output_0_axis_tdest_reg <= input_7_axis_tdest_reg; + output_0_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_0_axis_tdata_reg <= input_8_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_8_axis_tlast_reg; + output_0_axis_tid_reg <= input_8_axis_tid_reg; + output_0_axis_tdest_reg <= input_8_axis_tdest_reg; + output_0_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_0_axis_tdata_reg <= input_9_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_9_axis_tlast_reg; + output_0_axis_tid_reg <= input_9_axis_tid_reg; + output_0_axis_tdest_reg <= input_9_axis_tdest_reg; + output_0_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_0_axis_tdata_reg <= input_10_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_10_axis_tlast_reg; + output_0_axis_tid_reg <= input_10_axis_tid_reg; + output_0_axis_tdest_reg <= input_10_axis_tdest_reg; + output_0_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_0_axis_tdata_reg <= input_11_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_11_axis_tlast_reg; + output_0_axis_tid_reg <= input_11_axis_tid_reg; + output_0_axis_tdest_reg <= input_11_axis_tdest_reg; + output_0_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_0_axis_tdata_reg <= input_12_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_12_axis_tlast_reg; + output_0_axis_tid_reg <= input_12_axis_tid_reg; + output_0_axis_tdest_reg <= input_12_axis_tdest_reg; + output_0_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_0_axis_tdata_reg <= input_13_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_13_axis_tlast_reg; + output_0_axis_tid_reg <= input_13_axis_tid_reg; + output_0_axis_tdest_reg <= input_13_axis_tdest_reg; + output_0_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_0_axis_tdata_reg <= input_14_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_14_axis_tlast_reg; + output_0_axis_tid_reg <= input_14_axis_tid_reg; + output_0_axis_tdest_reg <= input_14_axis_tdest_reg; + output_0_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_0_axis_tdata_reg <= input_15_axis_tdata_reg; + output_0_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_0_axis_tlast_reg <= input_15_axis_tlast_reg; + output_0_axis_tid_reg <= input_15_axis_tid_reg; + output_0_axis_tdest_reg <= input_15_axis_tdest_reg; + output_0_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_1_select_reg) + 4'd0: begin + output_1_axis_tdata_reg <= input_0_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_0_axis_tlast_reg; + output_1_axis_tid_reg <= input_0_axis_tid_reg; + output_1_axis_tdest_reg <= input_0_axis_tdest_reg; + output_1_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_1_axis_tdata_reg <= input_1_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_1_axis_tlast_reg; + output_1_axis_tid_reg <= input_1_axis_tid_reg; + output_1_axis_tdest_reg <= input_1_axis_tdest_reg; + output_1_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_1_axis_tdata_reg <= input_2_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_2_axis_tlast_reg; + output_1_axis_tid_reg <= input_2_axis_tid_reg; + output_1_axis_tdest_reg <= input_2_axis_tdest_reg; + output_1_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_1_axis_tdata_reg <= input_3_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_3_axis_tlast_reg; + output_1_axis_tid_reg <= input_3_axis_tid_reg; + output_1_axis_tdest_reg <= input_3_axis_tdest_reg; + output_1_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_1_axis_tdata_reg <= input_4_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_4_axis_tlast_reg; + output_1_axis_tid_reg <= input_4_axis_tid_reg; + output_1_axis_tdest_reg <= input_4_axis_tdest_reg; + output_1_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_1_axis_tdata_reg <= input_5_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_5_axis_tlast_reg; + output_1_axis_tid_reg <= input_5_axis_tid_reg; + output_1_axis_tdest_reg <= input_5_axis_tdest_reg; + output_1_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_1_axis_tdata_reg <= input_6_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_6_axis_tlast_reg; + output_1_axis_tid_reg <= input_6_axis_tid_reg; + output_1_axis_tdest_reg <= input_6_axis_tdest_reg; + output_1_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_1_axis_tdata_reg <= input_7_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_7_axis_tlast_reg; + output_1_axis_tid_reg <= input_7_axis_tid_reg; + output_1_axis_tdest_reg <= input_7_axis_tdest_reg; + output_1_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_1_axis_tdata_reg <= input_8_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_8_axis_tlast_reg; + output_1_axis_tid_reg <= input_8_axis_tid_reg; + output_1_axis_tdest_reg <= input_8_axis_tdest_reg; + output_1_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_1_axis_tdata_reg <= input_9_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_9_axis_tlast_reg; + output_1_axis_tid_reg <= input_9_axis_tid_reg; + output_1_axis_tdest_reg <= input_9_axis_tdest_reg; + output_1_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_1_axis_tdata_reg <= input_10_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_10_axis_tlast_reg; + output_1_axis_tid_reg <= input_10_axis_tid_reg; + output_1_axis_tdest_reg <= input_10_axis_tdest_reg; + output_1_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_1_axis_tdata_reg <= input_11_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_11_axis_tlast_reg; + output_1_axis_tid_reg <= input_11_axis_tid_reg; + output_1_axis_tdest_reg <= input_11_axis_tdest_reg; + output_1_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_1_axis_tdata_reg <= input_12_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_12_axis_tlast_reg; + output_1_axis_tid_reg <= input_12_axis_tid_reg; + output_1_axis_tdest_reg <= input_12_axis_tdest_reg; + output_1_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_1_axis_tdata_reg <= input_13_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_13_axis_tlast_reg; + output_1_axis_tid_reg <= input_13_axis_tid_reg; + output_1_axis_tdest_reg <= input_13_axis_tdest_reg; + output_1_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_1_axis_tdata_reg <= input_14_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_14_axis_tlast_reg; + output_1_axis_tid_reg <= input_14_axis_tid_reg; + output_1_axis_tdest_reg <= input_14_axis_tdest_reg; + output_1_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_1_axis_tdata_reg <= input_15_axis_tdata_reg; + output_1_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_1_axis_tlast_reg <= input_15_axis_tlast_reg; + output_1_axis_tid_reg <= input_15_axis_tid_reg; + output_1_axis_tdest_reg <= input_15_axis_tdest_reg; + output_1_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_2_select_reg) + 4'd0: begin + output_2_axis_tdata_reg <= input_0_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_0_axis_tlast_reg; + output_2_axis_tid_reg <= input_0_axis_tid_reg; + output_2_axis_tdest_reg <= input_0_axis_tdest_reg; + output_2_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_2_axis_tdata_reg <= input_1_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_1_axis_tlast_reg; + output_2_axis_tid_reg <= input_1_axis_tid_reg; + output_2_axis_tdest_reg <= input_1_axis_tdest_reg; + output_2_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_2_axis_tdata_reg <= input_2_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_2_axis_tlast_reg; + output_2_axis_tid_reg <= input_2_axis_tid_reg; + output_2_axis_tdest_reg <= input_2_axis_tdest_reg; + output_2_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_2_axis_tdata_reg <= input_3_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_3_axis_tlast_reg; + output_2_axis_tid_reg <= input_3_axis_tid_reg; + output_2_axis_tdest_reg <= input_3_axis_tdest_reg; + output_2_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_2_axis_tdata_reg <= input_4_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_4_axis_tlast_reg; + output_2_axis_tid_reg <= input_4_axis_tid_reg; + output_2_axis_tdest_reg <= input_4_axis_tdest_reg; + output_2_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_2_axis_tdata_reg <= input_5_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_5_axis_tlast_reg; + output_2_axis_tid_reg <= input_5_axis_tid_reg; + output_2_axis_tdest_reg <= input_5_axis_tdest_reg; + output_2_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_2_axis_tdata_reg <= input_6_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_6_axis_tlast_reg; + output_2_axis_tid_reg <= input_6_axis_tid_reg; + output_2_axis_tdest_reg <= input_6_axis_tdest_reg; + output_2_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_2_axis_tdata_reg <= input_7_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_7_axis_tlast_reg; + output_2_axis_tid_reg <= input_7_axis_tid_reg; + output_2_axis_tdest_reg <= input_7_axis_tdest_reg; + output_2_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_2_axis_tdata_reg <= input_8_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_8_axis_tlast_reg; + output_2_axis_tid_reg <= input_8_axis_tid_reg; + output_2_axis_tdest_reg <= input_8_axis_tdest_reg; + output_2_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_2_axis_tdata_reg <= input_9_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_9_axis_tlast_reg; + output_2_axis_tid_reg <= input_9_axis_tid_reg; + output_2_axis_tdest_reg <= input_9_axis_tdest_reg; + output_2_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_2_axis_tdata_reg <= input_10_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_10_axis_tlast_reg; + output_2_axis_tid_reg <= input_10_axis_tid_reg; + output_2_axis_tdest_reg <= input_10_axis_tdest_reg; + output_2_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_2_axis_tdata_reg <= input_11_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_11_axis_tlast_reg; + output_2_axis_tid_reg <= input_11_axis_tid_reg; + output_2_axis_tdest_reg <= input_11_axis_tdest_reg; + output_2_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_2_axis_tdata_reg <= input_12_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_12_axis_tlast_reg; + output_2_axis_tid_reg <= input_12_axis_tid_reg; + output_2_axis_tdest_reg <= input_12_axis_tdest_reg; + output_2_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_2_axis_tdata_reg <= input_13_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_13_axis_tlast_reg; + output_2_axis_tid_reg <= input_13_axis_tid_reg; + output_2_axis_tdest_reg <= input_13_axis_tdest_reg; + output_2_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_2_axis_tdata_reg <= input_14_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_14_axis_tlast_reg; + output_2_axis_tid_reg <= input_14_axis_tid_reg; + output_2_axis_tdest_reg <= input_14_axis_tdest_reg; + output_2_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_2_axis_tdata_reg <= input_15_axis_tdata_reg; + output_2_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_2_axis_tlast_reg <= input_15_axis_tlast_reg; + output_2_axis_tid_reg <= input_15_axis_tid_reg; + output_2_axis_tdest_reg <= input_15_axis_tdest_reg; + output_2_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_3_select_reg) + 4'd0: begin + output_3_axis_tdata_reg <= input_0_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_0_axis_tlast_reg; + output_3_axis_tid_reg <= input_0_axis_tid_reg; + output_3_axis_tdest_reg <= input_0_axis_tdest_reg; + output_3_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_3_axis_tdata_reg <= input_1_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_1_axis_tlast_reg; + output_3_axis_tid_reg <= input_1_axis_tid_reg; + output_3_axis_tdest_reg <= input_1_axis_tdest_reg; + output_3_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_3_axis_tdata_reg <= input_2_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_2_axis_tlast_reg; + output_3_axis_tid_reg <= input_2_axis_tid_reg; + output_3_axis_tdest_reg <= input_2_axis_tdest_reg; + output_3_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_3_axis_tdata_reg <= input_3_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_3_axis_tlast_reg; + output_3_axis_tid_reg <= input_3_axis_tid_reg; + output_3_axis_tdest_reg <= input_3_axis_tdest_reg; + output_3_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_3_axis_tdata_reg <= input_4_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_4_axis_tlast_reg; + output_3_axis_tid_reg <= input_4_axis_tid_reg; + output_3_axis_tdest_reg <= input_4_axis_tdest_reg; + output_3_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_3_axis_tdata_reg <= input_5_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_5_axis_tlast_reg; + output_3_axis_tid_reg <= input_5_axis_tid_reg; + output_3_axis_tdest_reg <= input_5_axis_tdest_reg; + output_3_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_3_axis_tdata_reg <= input_6_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_6_axis_tlast_reg; + output_3_axis_tid_reg <= input_6_axis_tid_reg; + output_3_axis_tdest_reg <= input_6_axis_tdest_reg; + output_3_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_3_axis_tdata_reg <= input_7_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_7_axis_tlast_reg; + output_3_axis_tid_reg <= input_7_axis_tid_reg; + output_3_axis_tdest_reg <= input_7_axis_tdest_reg; + output_3_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_3_axis_tdata_reg <= input_8_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_8_axis_tlast_reg; + output_3_axis_tid_reg <= input_8_axis_tid_reg; + output_3_axis_tdest_reg <= input_8_axis_tdest_reg; + output_3_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_3_axis_tdata_reg <= input_9_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_9_axis_tlast_reg; + output_3_axis_tid_reg <= input_9_axis_tid_reg; + output_3_axis_tdest_reg <= input_9_axis_tdest_reg; + output_3_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_3_axis_tdata_reg <= input_10_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_10_axis_tlast_reg; + output_3_axis_tid_reg <= input_10_axis_tid_reg; + output_3_axis_tdest_reg <= input_10_axis_tdest_reg; + output_3_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_3_axis_tdata_reg <= input_11_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_11_axis_tlast_reg; + output_3_axis_tid_reg <= input_11_axis_tid_reg; + output_3_axis_tdest_reg <= input_11_axis_tdest_reg; + output_3_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_3_axis_tdata_reg <= input_12_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_12_axis_tlast_reg; + output_3_axis_tid_reg <= input_12_axis_tid_reg; + output_3_axis_tdest_reg <= input_12_axis_tdest_reg; + output_3_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_3_axis_tdata_reg <= input_13_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_13_axis_tlast_reg; + output_3_axis_tid_reg <= input_13_axis_tid_reg; + output_3_axis_tdest_reg <= input_13_axis_tdest_reg; + output_3_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_3_axis_tdata_reg <= input_14_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_14_axis_tlast_reg; + output_3_axis_tid_reg <= input_14_axis_tid_reg; + output_3_axis_tdest_reg <= input_14_axis_tdest_reg; + output_3_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_3_axis_tdata_reg <= input_15_axis_tdata_reg; + output_3_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_3_axis_tlast_reg <= input_15_axis_tlast_reg; + output_3_axis_tid_reg <= input_15_axis_tid_reg; + output_3_axis_tdest_reg <= input_15_axis_tdest_reg; + output_3_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_4_select_reg) + 4'd0: begin + output_4_axis_tdata_reg <= input_0_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_0_axis_tlast_reg; + output_4_axis_tid_reg <= input_0_axis_tid_reg; + output_4_axis_tdest_reg <= input_0_axis_tdest_reg; + output_4_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_4_axis_tdata_reg <= input_1_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_1_axis_tlast_reg; + output_4_axis_tid_reg <= input_1_axis_tid_reg; + output_4_axis_tdest_reg <= input_1_axis_tdest_reg; + output_4_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_4_axis_tdata_reg <= input_2_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_2_axis_tlast_reg; + output_4_axis_tid_reg <= input_2_axis_tid_reg; + output_4_axis_tdest_reg <= input_2_axis_tdest_reg; + output_4_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_4_axis_tdata_reg <= input_3_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_3_axis_tlast_reg; + output_4_axis_tid_reg <= input_3_axis_tid_reg; + output_4_axis_tdest_reg <= input_3_axis_tdest_reg; + output_4_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_4_axis_tdata_reg <= input_4_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_4_axis_tlast_reg; + output_4_axis_tid_reg <= input_4_axis_tid_reg; + output_4_axis_tdest_reg <= input_4_axis_tdest_reg; + output_4_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_4_axis_tdata_reg <= input_5_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_5_axis_tlast_reg; + output_4_axis_tid_reg <= input_5_axis_tid_reg; + output_4_axis_tdest_reg <= input_5_axis_tdest_reg; + output_4_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_4_axis_tdata_reg <= input_6_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_6_axis_tlast_reg; + output_4_axis_tid_reg <= input_6_axis_tid_reg; + output_4_axis_tdest_reg <= input_6_axis_tdest_reg; + output_4_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_4_axis_tdata_reg <= input_7_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_7_axis_tlast_reg; + output_4_axis_tid_reg <= input_7_axis_tid_reg; + output_4_axis_tdest_reg <= input_7_axis_tdest_reg; + output_4_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_4_axis_tdata_reg <= input_8_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_8_axis_tlast_reg; + output_4_axis_tid_reg <= input_8_axis_tid_reg; + output_4_axis_tdest_reg <= input_8_axis_tdest_reg; + output_4_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_4_axis_tdata_reg <= input_9_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_9_axis_tlast_reg; + output_4_axis_tid_reg <= input_9_axis_tid_reg; + output_4_axis_tdest_reg <= input_9_axis_tdest_reg; + output_4_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_4_axis_tdata_reg <= input_10_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_10_axis_tlast_reg; + output_4_axis_tid_reg <= input_10_axis_tid_reg; + output_4_axis_tdest_reg <= input_10_axis_tdest_reg; + output_4_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_4_axis_tdata_reg <= input_11_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_11_axis_tlast_reg; + output_4_axis_tid_reg <= input_11_axis_tid_reg; + output_4_axis_tdest_reg <= input_11_axis_tdest_reg; + output_4_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_4_axis_tdata_reg <= input_12_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_12_axis_tlast_reg; + output_4_axis_tid_reg <= input_12_axis_tid_reg; + output_4_axis_tdest_reg <= input_12_axis_tdest_reg; + output_4_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_4_axis_tdata_reg <= input_13_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_13_axis_tlast_reg; + output_4_axis_tid_reg <= input_13_axis_tid_reg; + output_4_axis_tdest_reg <= input_13_axis_tdest_reg; + output_4_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_4_axis_tdata_reg <= input_14_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_14_axis_tlast_reg; + output_4_axis_tid_reg <= input_14_axis_tid_reg; + output_4_axis_tdest_reg <= input_14_axis_tdest_reg; + output_4_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_4_axis_tdata_reg <= input_15_axis_tdata_reg; + output_4_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_4_axis_tlast_reg <= input_15_axis_tlast_reg; + output_4_axis_tid_reg <= input_15_axis_tid_reg; + output_4_axis_tdest_reg <= input_15_axis_tdest_reg; + output_4_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_5_select_reg) + 4'd0: begin + output_5_axis_tdata_reg <= input_0_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_0_axis_tlast_reg; + output_5_axis_tid_reg <= input_0_axis_tid_reg; + output_5_axis_tdest_reg <= input_0_axis_tdest_reg; + output_5_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_5_axis_tdata_reg <= input_1_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_1_axis_tlast_reg; + output_5_axis_tid_reg <= input_1_axis_tid_reg; + output_5_axis_tdest_reg <= input_1_axis_tdest_reg; + output_5_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_5_axis_tdata_reg <= input_2_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_2_axis_tlast_reg; + output_5_axis_tid_reg <= input_2_axis_tid_reg; + output_5_axis_tdest_reg <= input_2_axis_tdest_reg; + output_5_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_5_axis_tdata_reg <= input_3_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_3_axis_tlast_reg; + output_5_axis_tid_reg <= input_3_axis_tid_reg; + output_5_axis_tdest_reg <= input_3_axis_tdest_reg; + output_5_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_5_axis_tdata_reg <= input_4_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_4_axis_tlast_reg; + output_5_axis_tid_reg <= input_4_axis_tid_reg; + output_5_axis_tdest_reg <= input_4_axis_tdest_reg; + output_5_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_5_axis_tdata_reg <= input_5_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_5_axis_tlast_reg; + output_5_axis_tid_reg <= input_5_axis_tid_reg; + output_5_axis_tdest_reg <= input_5_axis_tdest_reg; + output_5_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_5_axis_tdata_reg <= input_6_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_6_axis_tlast_reg; + output_5_axis_tid_reg <= input_6_axis_tid_reg; + output_5_axis_tdest_reg <= input_6_axis_tdest_reg; + output_5_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_5_axis_tdata_reg <= input_7_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_7_axis_tlast_reg; + output_5_axis_tid_reg <= input_7_axis_tid_reg; + output_5_axis_tdest_reg <= input_7_axis_tdest_reg; + output_5_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_5_axis_tdata_reg <= input_8_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_8_axis_tlast_reg; + output_5_axis_tid_reg <= input_8_axis_tid_reg; + output_5_axis_tdest_reg <= input_8_axis_tdest_reg; + output_5_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_5_axis_tdata_reg <= input_9_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_9_axis_tlast_reg; + output_5_axis_tid_reg <= input_9_axis_tid_reg; + output_5_axis_tdest_reg <= input_9_axis_tdest_reg; + output_5_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_5_axis_tdata_reg <= input_10_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_10_axis_tlast_reg; + output_5_axis_tid_reg <= input_10_axis_tid_reg; + output_5_axis_tdest_reg <= input_10_axis_tdest_reg; + output_5_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_5_axis_tdata_reg <= input_11_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_11_axis_tlast_reg; + output_5_axis_tid_reg <= input_11_axis_tid_reg; + output_5_axis_tdest_reg <= input_11_axis_tdest_reg; + output_5_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_5_axis_tdata_reg <= input_12_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_12_axis_tlast_reg; + output_5_axis_tid_reg <= input_12_axis_tid_reg; + output_5_axis_tdest_reg <= input_12_axis_tdest_reg; + output_5_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_5_axis_tdata_reg <= input_13_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_13_axis_tlast_reg; + output_5_axis_tid_reg <= input_13_axis_tid_reg; + output_5_axis_tdest_reg <= input_13_axis_tdest_reg; + output_5_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_5_axis_tdata_reg <= input_14_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_14_axis_tlast_reg; + output_5_axis_tid_reg <= input_14_axis_tid_reg; + output_5_axis_tdest_reg <= input_14_axis_tdest_reg; + output_5_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_5_axis_tdata_reg <= input_15_axis_tdata_reg; + output_5_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_5_axis_tlast_reg <= input_15_axis_tlast_reg; + output_5_axis_tid_reg <= input_15_axis_tid_reg; + output_5_axis_tdest_reg <= input_15_axis_tdest_reg; + output_5_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_6_select_reg) + 4'd0: begin + output_6_axis_tdata_reg <= input_0_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_0_axis_tlast_reg; + output_6_axis_tid_reg <= input_0_axis_tid_reg; + output_6_axis_tdest_reg <= input_0_axis_tdest_reg; + output_6_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_6_axis_tdata_reg <= input_1_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_1_axis_tlast_reg; + output_6_axis_tid_reg <= input_1_axis_tid_reg; + output_6_axis_tdest_reg <= input_1_axis_tdest_reg; + output_6_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_6_axis_tdata_reg <= input_2_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_2_axis_tlast_reg; + output_6_axis_tid_reg <= input_2_axis_tid_reg; + output_6_axis_tdest_reg <= input_2_axis_tdest_reg; + output_6_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_6_axis_tdata_reg <= input_3_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_3_axis_tlast_reg; + output_6_axis_tid_reg <= input_3_axis_tid_reg; + output_6_axis_tdest_reg <= input_3_axis_tdest_reg; + output_6_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_6_axis_tdata_reg <= input_4_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_4_axis_tlast_reg; + output_6_axis_tid_reg <= input_4_axis_tid_reg; + output_6_axis_tdest_reg <= input_4_axis_tdest_reg; + output_6_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_6_axis_tdata_reg <= input_5_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_5_axis_tlast_reg; + output_6_axis_tid_reg <= input_5_axis_tid_reg; + output_6_axis_tdest_reg <= input_5_axis_tdest_reg; + output_6_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_6_axis_tdata_reg <= input_6_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_6_axis_tlast_reg; + output_6_axis_tid_reg <= input_6_axis_tid_reg; + output_6_axis_tdest_reg <= input_6_axis_tdest_reg; + output_6_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_6_axis_tdata_reg <= input_7_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_7_axis_tlast_reg; + output_6_axis_tid_reg <= input_7_axis_tid_reg; + output_6_axis_tdest_reg <= input_7_axis_tdest_reg; + output_6_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_6_axis_tdata_reg <= input_8_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_8_axis_tlast_reg; + output_6_axis_tid_reg <= input_8_axis_tid_reg; + output_6_axis_tdest_reg <= input_8_axis_tdest_reg; + output_6_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_6_axis_tdata_reg <= input_9_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_9_axis_tlast_reg; + output_6_axis_tid_reg <= input_9_axis_tid_reg; + output_6_axis_tdest_reg <= input_9_axis_tdest_reg; + output_6_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_6_axis_tdata_reg <= input_10_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_10_axis_tlast_reg; + output_6_axis_tid_reg <= input_10_axis_tid_reg; + output_6_axis_tdest_reg <= input_10_axis_tdest_reg; + output_6_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_6_axis_tdata_reg <= input_11_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_11_axis_tlast_reg; + output_6_axis_tid_reg <= input_11_axis_tid_reg; + output_6_axis_tdest_reg <= input_11_axis_tdest_reg; + output_6_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_6_axis_tdata_reg <= input_12_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_12_axis_tlast_reg; + output_6_axis_tid_reg <= input_12_axis_tid_reg; + output_6_axis_tdest_reg <= input_12_axis_tdest_reg; + output_6_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_6_axis_tdata_reg <= input_13_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_13_axis_tlast_reg; + output_6_axis_tid_reg <= input_13_axis_tid_reg; + output_6_axis_tdest_reg <= input_13_axis_tdest_reg; + output_6_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_6_axis_tdata_reg <= input_14_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_14_axis_tlast_reg; + output_6_axis_tid_reg <= input_14_axis_tid_reg; + output_6_axis_tdest_reg <= input_14_axis_tdest_reg; + output_6_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_6_axis_tdata_reg <= input_15_axis_tdata_reg; + output_6_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_6_axis_tlast_reg <= input_15_axis_tlast_reg; + output_6_axis_tid_reg <= input_15_axis_tid_reg; + output_6_axis_tdest_reg <= input_15_axis_tdest_reg; + output_6_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_7_select_reg) + 4'd0: begin + output_7_axis_tdata_reg <= input_0_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_0_axis_tlast_reg; + output_7_axis_tid_reg <= input_0_axis_tid_reg; + output_7_axis_tdest_reg <= input_0_axis_tdest_reg; + output_7_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_7_axis_tdata_reg <= input_1_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_1_axis_tlast_reg; + output_7_axis_tid_reg <= input_1_axis_tid_reg; + output_7_axis_tdest_reg <= input_1_axis_tdest_reg; + output_7_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_7_axis_tdata_reg <= input_2_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_2_axis_tlast_reg; + output_7_axis_tid_reg <= input_2_axis_tid_reg; + output_7_axis_tdest_reg <= input_2_axis_tdest_reg; + output_7_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_7_axis_tdata_reg <= input_3_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_3_axis_tlast_reg; + output_7_axis_tid_reg <= input_3_axis_tid_reg; + output_7_axis_tdest_reg <= input_3_axis_tdest_reg; + output_7_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_7_axis_tdata_reg <= input_4_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_4_axis_tlast_reg; + output_7_axis_tid_reg <= input_4_axis_tid_reg; + output_7_axis_tdest_reg <= input_4_axis_tdest_reg; + output_7_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_7_axis_tdata_reg <= input_5_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_5_axis_tlast_reg; + output_7_axis_tid_reg <= input_5_axis_tid_reg; + output_7_axis_tdest_reg <= input_5_axis_tdest_reg; + output_7_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_7_axis_tdata_reg <= input_6_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_6_axis_tlast_reg; + output_7_axis_tid_reg <= input_6_axis_tid_reg; + output_7_axis_tdest_reg <= input_6_axis_tdest_reg; + output_7_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_7_axis_tdata_reg <= input_7_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_7_axis_tlast_reg; + output_7_axis_tid_reg <= input_7_axis_tid_reg; + output_7_axis_tdest_reg <= input_7_axis_tdest_reg; + output_7_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_7_axis_tdata_reg <= input_8_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_8_axis_tlast_reg; + output_7_axis_tid_reg <= input_8_axis_tid_reg; + output_7_axis_tdest_reg <= input_8_axis_tdest_reg; + output_7_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_7_axis_tdata_reg <= input_9_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_9_axis_tlast_reg; + output_7_axis_tid_reg <= input_9_axis_tid_reg; + output_7_axis_tdest_reg <= input_9_axis_tdest_reg; + output_7_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_7_axis_tdata_reg <= input_10_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_10_axis_tlast_reg; + output_7_axis_tid_reg <= input_10_axis_tid_reg; + output_7_axis_tdest_reg <= input_10_axis_tdest_reg; + output_7_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_7_axis_tdata_reg <= input_11_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_11_axis_tlast_reg; + output_7_axis_tid_reg <= input_11_axis_tid_reg; + output_7_axis_tdest_reg <= input_11_axis_tdest_reg; + output_7_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_7_axis_tdata_reg <= input_12_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_12_axis_tlast_reg; + output_7_axis_tid_reg <= input_12_axis_tid_reg; + output_7_axis_tdest_reg <= input_12_axis_tdest_reg; + output_7_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_7_axis_tdata_reg <= input_13_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_13_axis_tlast_reg; + output_7_axis_tid_reg <= input_13_axis_tid_reg; + output_7_axis_tdest_reg <= input_13_axis_tdest_reg; + output_7_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_7_axis_tdata_reg <= input_14_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_14_axis_tlast_reg; + output_7_axis_tid_reg <= input_14_axis_tid_reg; + output_7_axis_tdest_reg <= input_14_axis_tdest_reg; + output_7_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_7_axis_tdata_reg <= input_15_axis_tdata_reg; + output_7_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_7_axis_tlast_reg <= input_15_axis_tlast_reg; + output_7_axis_tid_reg <= input_15_axis_tid_reg; + output_7_axis_tdest_reg <= input_15_axis_tdest_reg; + output_7_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_8_select_reg) + 4'd0: begin + output_8_axis_tdata_reg <= input_0_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_0_axis_tlast_reg; + output_8_axis_tid_reg <= input_0_axis_tid_reg; + output_8_axis_tdest_reg <= input_0_axis_tdest_reg; + output_8_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_8_axis_tdata_reg <= input_1_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_1_axis_tlast_reg; + output_8_axis_tid_reg <= input_1_axis_tid_reg; + output_8_axis_tdest_reg <= input_1_axis_tdest_reg; + output_8_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_8_axis_tdata_reg <= input_2_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_2_axis_tlast_reg; + output_8_axis_tid_reg <= input_2_axis_tid_reg; + output_8_axis_tdest_reg <= input_2_axis_tdest_reg; + output_8_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_8_axis_tdata_reg <= input_3_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_3_axis_tlast_reg; + output_8_axis_tid_reg <= input_3_axis_tid_reg; + output_8_axis_tdest_reg <= input_3_axis_tdest_reg; + output_8_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_8_axis_tdata_reg <= input_4_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_4_axis_tlast_reg; + output_8_axis_tid_reg <= input_4_axis_tid_reg; + output_8_axis_tdest_reg <= input_4_axis_tdest_reg; + output_8_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_8_axis_tdata_reg <= input_5_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_5_axis_tlast_reg; + output_8_axis_tid_reg <= input_5_axis_tid_reg; + output_8_axis_tdest_reg <= input_5_axis_tdest_reg; + output_8_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_8_axis_tdata_reg <= input_6_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_6_axis_tlast_reg; + output_8_axis_tid_reg <= input_6_axis_tid_reg; + output_8_axis_tdest_reg <= input_6_axis_tdest_reg; + output_8_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_8_axis_tdata_reg <= input_7_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_7_axis_tlast_reg; + output_8_axis_tid_reg <= input_7_axis_tid_reg; + output_8_axis_tdest_reg <= input_7_axis_tdest_reg; + output_8_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_8_axis_tdata_reg <= input_8_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_8_axis_tlast_reg; + output_8_axis_tid_reg <= input_8_axis_tid_reg; + output_8_axis_tdest_reg <= input_8_axis_tdest_reg; + output_8_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_8_axis_tdata_reg <= input_9_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_9_axis_tlast_reg; + output_8_axis_tid_reg <= input_9_axis_tid_reg; + output_8_axis_tdest_reg <= input_9_axis_tdest_reg; + output_8_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_8_axis_tdata_reg <= input_10_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_10_axis_tlast_reg; + output_8_axis_tid_reg <= input_10_axis_tid_reg; + output_8_axis_tdest_reg <= input_10_axis_tdest_reg; + output_8_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_8_axis_tdata_reg <= input_11_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_11_axis_tlast_reg; + output_8_axis_tid_reg <= input_11_axis_tid_reg; + output_8_axis_tdest_reg <= input_11_axis_tdest_reg; + output_8_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_8_axis_tdata_reg <= input_12_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_12_axis_tlast_reg; + output_8_axis_tid_reg <= input_12_axis_tid_reg; + output_8_axis_tdest_reg <= input_12_axis_tdest_reg; + output_8_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_8_axis_tdata_reg <= input_13_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_13_axis_tlast_reg; + output_8_axis_tid_reg <= input_13_axis_tid_reg; + output_8_axis_tdest_reg <= input_13_axis_tdest_reg; + output_8_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_8_axis_tdata_reg <= input_14_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_14_axis_tlast_reg; + output_8_axis_tid_reg <= input_14_axis_tid_reg; + output_8_axis_tdest_reg <= input_14_axis_tdest_reg; + output_8_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_8_axis_tdata_reg <= input_15_axis_tdata_reg; + output_8_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_8_axis_tlast_reg <= input_15_axis_tlast_reg; + output_8_axis_tid_reg <= input_15_axis_tid_reg; + output_8_axis_tdest_reg <= input_15_axis_tdest_reg; + output_8_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_9_select_reg) + 4'd0: begin + output_9_axis_tdata_reg <= input_0_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_0_axis_tlast_reg; + output_9_axis_tid_reg <= input_0_axis_tid_reg; + output_9_axis_tdest_reg <= input_0_axis_tdest_reg; + output_9_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_9_axis_tdata_reg <= input_1_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_1_axis_tlast_reg; + output_9_axis_tid_reg <= input_1_axis_tid_reg; + output_9_axis_tdest_reg <= input_1_axis_tdest_reg; + output_9_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_9_axis_tdata_reg <= input_2_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_2_axis_tlast_reg; + output_9_axis_tid_reg <= input_2_axis_tid_reg; + output_9_axis_tdest_reg <= input_2_axis_tdest_reg; + output_9_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_9_axis_tdata_reg <= input_3_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_3_axis_tlast_reg; + output_9_axis_tid_reg <= input_3_axis_tid_reg; + output_9_axis_tdest_reg <= input_3_axis_tdest_reg; + output_9_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_9_axis_tdata_reg <= input_4_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_4_axis_tlast_reg; + output_9_axis_tid_reg <= input_4_axis_tid_reg; + output_9_axis_tdest_reg <= input_4_axis_tdest_reg; + output_9_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_9_axis_tdata_reg <= input_5_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_5_axis_tlast_reg; + output_9_axis_tid_reg <= input_5_axis_tid_reg; + output_9_axis_tdest_reg <= input_5_axis_tdest_reg; + output_9_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_9_axis_tdata_reg <= input_6_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_6_axis_tlast_reg; + output_9_axis_tid_reg <= input_6_axis_tid_reg; + output_9_axis_tdest_reg <= input_6_axis_tdest_reg; + output_9_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_9_axis_tdata_reg <= input_7_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_7_axis_tlast_reg; + output_9_axis_tid_reg <= input_7_axis_tid_reg; + output_9_axis_tdest_reg <= input_7_axis_tdest_reg; + output_9_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_9_axis_tdata_reg <= input_8_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_8_axis_tlast_reg; + output_9_axis_tid_reg <= input_8_axis_tid_reg; + output_9_axis_tdest_reg <= input_8_axis_tdest_reg; + output_9_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_9_axis_tdata_reg <= input_9_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_9_axis_tlast_reg; + output_9_axis_tid_reg <= input_9_axis_tid_reg; + output_9_axis_tdest_reg <= input_9_axis_tdest_reg; + output_9_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_9_axis_tdata_reg <= input_10_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_10_axis_tlast_reg; + output_9_axis_tid_reg <= input_10_axis_tid_reg; + output_9_axis_tdest_reg <= input_10_axis_tdest_reg; + output_9_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_9_axis_tdata_reg <= input_11_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_11_axis_tlast_reg; + output_9_axis_tid_reg <= input_11_axis_tid_reg; + output_9_axis_tdest_reg <= input_11_axis_tdest_reg; + output_9_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_9_axis_tdata_reg <= input_12_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_12_axis_tlast_reg; + output_9_axis_tid_reg <= input_12_axis_tid_reg; + output_9_axis_tdest_reg <= input_12_axis_tdest_reg; + output_9_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_9_axis_tdata_reg <= input_13_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_13_axis_tlast_reg; + output_9_axis_tid_reg <= input_13_axis_tid_reg; + output_9_axis_tdest_reg <= input_13_axis_tdest_reg; + output_9_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_9_axis_tdata_reg <= input_14_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_14_axis_tlast_reg; + output_9_axis_tid_reg <= input_14_axis_tid_reg; + output_9_axis_tdest_reg <= input_14_axis_tdest_reg; + output_9_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_9_axis_tdata_reg <= input_15_axis_tdata_reg; + output_9_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_9_axis_tlast_reg <= input_15_axis_tlast_reg; + output_9_axis_tid_reg <= input_15_axis_tid_reg; + output_9_axis_tdest_reg <= input_15_axis_tdest_reg; + output_9_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_10_select_reg) + 4'd0: begin + output_10_axis_tdata_reg <= input_0_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_0_axis_tlast_reg; + output_10_axis_tid_reg <= input_0_axis_tid_reg; + output_10_axis_tdest_reg <= input_0_axis_tdest_reg; + output_10_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_10_axis_tdata_reg <= input_1_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_1_axis_tlast_reg; + output_10_axis_tid_reg <= input_1_axis_tid_reg; + output_10_axis_tdest_reg <= input_1_axis_tdest_reg; + output_10_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_10_axis_tdata_reg <= input_2_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_2_axis_tlast_reg; + output_10_axis_tid_reg <= input_2_axis_tid_reg; + output_10_axis_tdest_reg <= input_2_axis_tdest_reg; + output_10_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_10_axis_tdata_reg <= input_3_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_3_axis_tlast_reg; + output_10_axis_tid_reg <= input_3_axis_tid_reg; + output_10_axis_tdest_reg <= input_3_axis_tdest_reg; + output_10_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_10_axis_tdata_reg <= input_4_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_4_axis_tlast_reg; + output_10_axis_tid_reg <= input_4_axis_tid_reg; + output_10_axis_tdest_reg <= input_4_axis_tdest_reg; + output_10_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_10_axis_tdata_reg <= input_5_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_5_axis_tlast_reg; + output_10_axis_tid_reg <= input_5_axis_tid_reg; + output_10_axis_tdest_reg <= input_5_axis_tdest_reg; + output_10_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_10_axis_tdata_reg <= input_6_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_6_axis_tlast_reg; + output_10_axis_tid_reg <= input_6_axis_tid_reg; + output_10_axis_tdest_reg <= input_6_axis_tdest_reg; + output_10_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_10_axis_tdata_reg <= input_7_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_7_axis_tlast_reg; + output_10_axis_tid_reg <= input_7_axis_tid_reg; + output_10_axis_tdest_reg <= input_7_axis_tdest_reg; + output_10_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_10_axis_tdata_reg <= input_8_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_8_axis_tlast_reg; + output_10_axis_tid_reg <= input_8_axis_tid_reg; + output_10_axis_tdest_reg <= input_8_axis_tdest_reg; + output_10_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_10_axis_tdata_reg <= input_9_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_9_axis_tlast_reg; + output_10_axis_tid_reg <= input_9_axis_tid_reg; + output_10_axis_tdest_reg <= input_9_axis_tdest_reg; + output_10_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_10_axis_tdata_reg <= input_10_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_10_axis_tlast_reg; + output_10_axis_tid_reg <= input_10_axis_tid_reg; + output_10_axis_tdest_reg <= input_10_axis_tdest_reg; + output_10_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_10_axis_tdata_reg <= input_11_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_11_axis_tlast_reg; + output_10_axis_tid_reg <= input_11_axis_tid_reg; + output_10_axis_tdest_reg <= input_11_axis_tdest_reg; + output_10_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_10_axis_tdata_reg <= input_12_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_12_axis_tlast_reg; + output_10_axis_tid_reg <= input_12_axis_tid_reg; + output_10_axis_tdest_reg <= input_12_axis_tdest_reg; + output_10_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_10_axis_tdata_reg <= input_13_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_13_axis_tlast_reg; + output_10_axis_tid_reg <= input_13_axis_tid_reg; + output_10_axis_tdest_reg <= input_13_axis_tdest_reg; + output_10_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_10_axis_tdata_reg <= input_14_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_14_axis_tlast_reg; + output_10_axis_tid_reg <= input_14_axis_tid_reg; + output_10_axis_tdest_reg <= input_14_axis_tdest_reg; + output_10_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_10_axis_tdata_reg <= input_15_axis_tdata_reg; + output_10_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_10_axis_tlast_reg <= input_15_axis_tlast_reg; + output_10_axis_tid_reg <= input_15_axis_tid_reg; + output_10_axis_tdest_reg <= input_15_axis_tdest_reg; + output_10_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_11_select_reg) + 4'd0: begin + output_11_axis_tdata_reg <= input_0_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_0_axis_tlast_reg; + output_11_axis_tid_reg <= input_0_axis_tid_reg; + output_11_axis_tdest_reg <= input_0_axis_tdest_reg; + output_11_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_11_axis_tdata_reg <= input_1_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_1_axis_tlast_reg; + output_11_axis_tid_reg <= input_1_axis_tid_reg; + output_11_axis_tdest_reg <= input_1_axis_tdest_reg; + output_11_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_11_axis_tdata_reg <= input_2_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_2_axis_tlast_reg; + output_11_axis_tid_reg <= input_2_axis_tid_reg; + output_11_axis_tdest_reg <= input_2_axis_tdest_reg; + output_11_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_11_axis_tdata_reg <= input_3_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_3_axis_tlast_reg; + output_11_axis_tid_reg <= input_3_axis_tid_reg; + output_11_axis_tdest_reg <= input_3_axis_tdest_reg; + output_11_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_11_axis_tdata_reg <= input_4_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_4_axis_tlast_reg; + output_11_axis_tid_reg <= input_4_axis_tid_reg; + output_11_axis_tdest_reg <= input_4_axis_tdest_reg; + output_11_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_11_axis_tdata_reg <= input_5_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_5_axis_tlast_reg; + output_11_axis_tid_reg <= input_5_axis_tid_reg; + output_11_axis_tdest_reg <= input_5_axis_tdest_reg; + output_11_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_11_axis_tdata_reg <= input_6_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_6_axis_tlast_reg; + output_11_axis_tid_reg <= input_6_axis_tid_reg; + output_11_axis_tdest_reg <= input_6_axis_tdest_reg; + output_11_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_11_axis_tdata_reg <= input_7_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_7_axis_tlast_reg; + output_11_axis_tid_reg <= input_7_axis_tid_reg; + output_11_axis_tdest_reg <= input_7_axis_tdest_reg; + output_11_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_11_axis_tdata_reg <= input_8_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_8_axis_tlast_reg; + output_11_axis_tid_reg <= input_8_axis_tid_reg; + output_11_axis_tdest_reg <= input_8_axis_tdest_reg; + output_11_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_11_axis_tdata_reg <= input_9_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_9_axis_tlast_reg; + output_11_axis_tid_reg <= input_9_axis_tid_reg; + output_11_axis_tdest_reg <= input_9_axis_tdest_reg; + output_11_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_11_axis_tdata_reg <= input_10_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_10_axis_tlast_reg; + output_11_axis_tid_reg <= input_10_axis_tid_reg; + output_11_axis_tdest_reg <= input_10_axis_tdest_reg; + output_11_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_11_axis_tdata_reg <= input_11_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_11_axis_tlast_reg; + output_11_axis_tid_reg <= input_11_axis_tid_reg; + output_11_axis_tdest_reg <= input_11_axis_tdest_reg; + output_11_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_11_axis_tdata_reg <= input_12_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_12_axis_tlast_reg; + output_11_axis_tid_reg <= input_12_axis_tid_reg; + output_11_axis_tdest_reg <= input_12_axis_tdest_reg; + output_11_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_11_axis_tdata_reg <= input_13_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_13_axis_tlast_reg; + output_11_axis_tid_reg <= input_13_axis_tid_reg; + output_11_axis_tdest_reg <= input_13_axis_tdest_reg; + output_11_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_11_axis_tdata_reg <= input_14_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_14_axis_tlast_reg; + output_11_axis_tid_reg <= input_14_axis_tid_reg; + output_11_axis_tdest_reg <= input_14_axis_tdest_reg; + output_11_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_11_axis_tdata_reg <= input_15_axis_tdata_reg; + output_11_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_11_axis_tlast_reg <= input_15_axis_tlast_reg; + output_11_axis_tid_reg <= input_15_axis_tid_reg; + output_11_axis_tdest_reg <= input_15_axis_tdest_reg; + output_11_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_12_select_reg) + 4'd0: begin + output_12_axis_tdata_reg <= input_0_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_0_axis_tlast_reg; + output_12_axis_tid_reg <= input_0_axis_tid_reg; + output_12_axis_tdest_reg <= input_0_axis_tdest_reg; + output_12_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_12_axis_tdata_reg <= input_1_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_1_axis_tlast_reg; + output_12_axis_tid_reg <= input_1_axis_tid_reg; + output_12_axis_tdest_reg <= input_1_axis_tdest_reg; + output_12_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_12_axis_tdata_reg <= input_2_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_2_axis_tlast_reg; + output_12_axis_tid_reg <= input_2_axis_tid_reg; + output_12_axis_tdest_reg <= input_2_axis_tdest_reg; + output_12_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_12_axis_tdata_reg <= input_3_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_3_axis_tlast_reg; + output_12_axis_tid_reg <= input_3_axis_tid_reg; + output_12_axis_tdest_reg <= input_3_axis_tdest_reg; + output_12_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_12_axis_tdata_reg <= input_4_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_4_axis_tlast_reg; + output_12_axis_tid_reg <= input_4_axis_tid_reg; + output_12_axis_tdest_reg <= input_4_axis_tdest_reg; + output_12_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_12_axis_tdata_reg <= input_5_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_5_axis_tlast_reg; + output_12_axis_tid_reg <= input_5_axis_tid_reg; + output_12_axis_tdest_reg <= input_5_axis_tdest_reg; + output_12_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_12_axis_tdata_reg <= input_6_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_6_axis_tlast_reg; + output_12_axis_tid_reg <= input_6_axis_tid_reg; + output_12_axis_tdest_reg <= input_6_axis_tdest_reg; + output_12_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_12_axis_tdata_reg <= input_7_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_7_axis_tlast_reg; + output_12_axis_tid_reg <= input_7_axis_tid_reg; + output_12_axis_tdest_reg <= input_7_axis_tdest_reg; + output_12_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_12_axis_tdata_reg <= input_8_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_8_axis_tlast_reg; + output_12_axis_tid_reg <= input_8_axis_tid_reg; + output_12_axis_tdest_reg <= input_8_axis_tdest_reg; + output_12_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_12_axis_tdata_reg <= input_9_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_9_axis_tlast_reg; + output_12_axis_tid_reg <= input_9_axis_tid_reg; + output_12_axis_tdest_reg <= input_9_axis_tdest_reg; + output_12_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_12_axis_tdata_reg <= input_10_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_10_axis_tlast_reg; + output_12_axis_tid_reg <= input_10_axis_tid_reg; + output_12_axis_tdest_reg <= input_10_axis_tdest_reg; + output_12_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_12_axis_tdata_reg <= input_11_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_11_axis_tlast_reg; + output_12_axis_tid_reg <= input_11_axis_tid_reg; + output_12_axis_tdest_reg <= input_11_axis_tdest_reg; + output_12_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_12_axis_tdata_reg <= input_12_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_12_axis_tlast_reg; + output_12_axis_tid_reg <= input_12_axis_tid_reg; + output_12_axis_tdest_reg <= input_12_axis_tdest_reg; + output_12_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_12_axis_tdata_reg <= input_13_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_13_axis_tlast_reg; + output_12_axis_tid_reg <= input_13_axis_tid_reg; + output_12_axis_tdest_reg <= input_13_axis_tdest_reg; + output_12_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_12_axis_tdata_reg <= input_14_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_14_axis_tlast_reg; + output_12_axis_tid_reg <= input_14_axis_tid_reg; + output_12_axis_tdest_reg <= input_14_axis_tdest_reg; + output_12_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_12_axis_tdata_reg <= input_15_axis_tdata_reg; + output_12_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_12_axis_tlast_reg <= input_15_axis_tlast_reg; + output_12_axis_tid_reg <= input_15_axis_tid_reg; + output_12_axis_tdest_reg <= input_15_axis_tdest_reg; + output_12_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_13_select_reg) + 4'd0: begin + output_13_axis_tdata_reg <= input_0_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_0_axis_tlast_reg; + output_13_axis_tid_reg <= input_0_axis_tid_reg; + output_13_axis_tdest_reg <= input_0_axis_tdest_reg; + output_13_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_13_axis_tdata_reg <= input_1_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_1_axis_tlast_reg; + output_13_axis_tid_reg <= input_1_axis_tid_reg; + output_13_axis_tdest_reg <= input_1_axis_tdest_reg; + output_13_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_13_axis_tdata_reg <= input_2_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_2_axis_tlast_reg; + output_13_axis_tid_reg <= input_2_axis_tid_reg; + output_13_axis_tdest_reg <= input_2_axis_tdest_reg; + output_13_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_13_axis_tdata_reg <= input_3_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_3_axis_tlast_reg; + output_13_axis_tid_reg <= input_3_axis_tid_reg; + output_13_axis_tdest_reg <= input_3_axis_tdest_reg; + output_13_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_13_axis_tdata_reg <= input_4_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_4_axis_tlast_reg; + output_13_axis_tid_reg <= input_4_axis_tid_reg; + output_13_axis_tdest_reg <= input_4_axis_tdest_reg; + output_13_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_13_axis_tdata_reg <= input_5_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_5_axis_tlast_reg; + output_13_axis_tid_reg <= input_5_axis_tid_reg; + output_13_axis_tdest_reg <= input_5_axis_tdest_reg; + output_13_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_13_axis_tdata_reg <= input_6_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_6_axis_tlast_reg; + output_13_axis_tid_reg <= input_6_axis_tid_reg; + output_13_axis_tdest_reg <= input_6_axis_tdest_reg; + output_13_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_13_axis_tdata_reg <= input_7_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_7_axis_tlast_reg; + output_13_axis_tid_reg <= input_7_axis_tid_reg; + output_13_axis_tdest_reg <= input_7_axis_tdest_reg; + output_13_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_13_axis_tdata_reg <= input_8_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_8_axis_tlast_reg; + output_13_axis_tid_reg <= input_8_axis_tid_reg; + output_13_axis_tdest_reg <= input_8_axis_tdest_reg; + output_13_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_13_axis_tdata_reg <= input_9_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_9_axis_tlast_reg; + output_13_axis_tid_reg <= input_9_axis_tid_reg; + output_13_axis_tdest_reg <= input_9_axis_tdest_reg; + output_13_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_13_axis_tdata_reg <= input_10_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_10_axis_tlast_reg; + output_13_axis_tid_reg <= input_10_axis_tid_reg; + output_13_axis_tdest_reg <= input_10_axis_tdest_reg; + output_13_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_13_axis_tdata_reg <= input_11_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_11_axis_tlast_reg; + output_13_axis_tid_reg <= input_11_axis_tid_reg; + output_13_axis_tdest_reg <= input_11_axis_tdest_reg; + output_13_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_13_axis_tdata_reg <= input_12_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_12_axis_tlast_reg; + output_13_axis_tid_reg <= input_12_axis_tid_reg; + output_13_axis_tdest_reg <= input_12_axis_tdest_reg; + output_13_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_13_axis_tdata_reg <= input_13_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_13_axis_tlast_reg; + output_13_axis_tid_reg <= input_13_axis_tid_reg; + output_13_axis_tdest_reg <= input_13_axis_tdest_reg; + output_13_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_13_axis_tdata_reg <= input_14_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_14_axis_tlast_reg; + output_13_axis_tid_reg <= input_14_axis_tid_reg; + output_13_axis_tdest_reg <= input_14_axis_tdest_reg; + output_13_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_13_axis_tdata_reg <= input_15_axis_tdata_reg; + output_13_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_13_axis_tlast_reg <= input_15_axis_tlast_reg; + output_13_axis_tid_reg <= input_15_axis_tid_reg; + output_13_axis_tdest_reg <= input_15_axis_tdest_reg; + output_13_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_14_select_reg) + 4'd0: begin + output_14_axis_tdata_reg <= input_0_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_0_axis_tlast_reg; + output_14_axis_tid_reg <= input_0_axis_tid_reg; + output_14_axis_tdest_reg <= input_0_axis_tdest_reg; + output_14_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_14_axis_tdata_reg <= input_1_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_1_axis_tlast_reg; + output_14_axis_tid_reg <= input_1_axis_tid_reg; + output_14_axis_tdest_reg <= input_1_axis_tdest_reg; + output_14_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_14_axis_tdata_reg <= input_2_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_2_axis_tlast_reg; + output_14_axis_tid_reg <= input_2_axis_tid_reg; + output_14_axis_tdest_reg <= input_2_axis_tdest_reg; + output_14_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_14_axis_tdata_reg <= input_3_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_3_axis_tlast_reg; + output_14_axis_tid_reg <= input_3_axis_tid_reg; + output_14_axis_tdest_reg <= input_3_axis_tdest_reg; + output_14_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_14_axis_tdata_reg <= input_4_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_4_axis_tlast_reg; + output_14_axis_tid_reg <= input_4_axis_tid_reg; + output_14_axis_tdest_reg <= input_4_axis_tdest_reg; + output_14_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_14_axis_tdata_reg <= input_5_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_5_axis_tlast_reg; + output_14_axis_tid_reg <= input_5_axis_tid_reg; + output_14_axis_tdest_reg <= input_5_axis_tdest_reg; + output_14_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_14_axis_tdata_reg <= input_6_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_6_axis_tlast_reg; + output_14_axis_tid_reg <= input_6_axis_tid_reg; + output_14_axis_tdest_reg <= input_6_axis_tdest_reg; + output_14_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_14_axis_tdata_reg <= input_7_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_7_axis_tlast_reg; + output_14_axis_tid_reg <= input_7_axis_tid_reg; + output_14_axis_tdest_reg <= input_7_axis_tdest_reg; + output_14_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_14_axis_tdata_reg <= input_8_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_8_axis_tlast_reg; + output_14_axis_tid_reg <= input_8_axis_tid_reg; + output_14_axis_tdest_reg <= input_8_axis_tdest_reg; + output_14_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_14_axis_tdata_reg <= input_9_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_9_axis_tlast_reg; + output_14_axis_tid_reg <= input_9_axis_tid_reg; + output_14_axis_tdest_reg <= input_9_axis_tdest_reg; + output_14_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_14_axis_tdata_reg <= input_10_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_10_axis_tlast_reg; + output_14_axis_tid_reg <= input_10_axis_tid_reg; + output_14_axis_tdest_reg <= input_10_axis_tdest_reg; + output_14_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_14_axis_tdata_reg <= input_11_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_11_axis_tlast_reg; + output_14_axis_tid_reg <= input_11_axis_tid_reg; + output_14_axis_tdest_reg <= input_11_axis_tdest_reg; + output_14_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_14_axis_tdata_reg <= input_12_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_12_axis_tlast_reg; + output_14_axis_tid_reg <= input_12_axis_tid_reg; + output_14_axis_tdest_reg <= input_12_axis_tdest_reg; + output_14_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_14_axis_tdata_reg <= input_13_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_13_axis_tlast_reg; + output_14_axis_tid_reg <= input_13_axis_tid_reg; + output_14_axis_tdest_reg <= input_13_axis_tdest_reg; + output_14_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_14_axis_tdata_reg <= input_14_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_14_axis_tlast_reg; + output_14_axis_tid_reg <= input_14_axis_tid_reg; + output_14_axis_tdest_reg <= input_14_axis_tdest_reg; + output_14_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_14_axis_tdata_reg <= input_15_axis_tdata_reg; + output_14_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_14_axis_tlast_reg <= input_15_axis_tlast_reg; + output_14_axis_tid_reg <= input_15_axis_tid_reg; + output_14_axis_tdest_reg <= input_15_axis_tdest_reg; + output_14_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase + + case (output_15_select_reg) + 4'd0: begin + output_15_axis_tdata_reg <= input_0_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_0_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_0_axis_tlast_reg; + output_15_axis_tid_reg <= input_0_axis_tid_reg; + output_15_axis_tdest_reg <= input_0_axis_tdest_reg; + output_15_axis_tuser_reg <= input_0_axis_tuser_reg; + end + 4'd1: begin + output_15_axis_tdata_reg <= input_1_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_1_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_1_axis_tlast_reg; + output_15_axis_tid_reg <= input_1_axis_tid_reg; + output_15_axis_tdest_reg <= input_1_axis_tdest_reg; + output_15_axis_tuser_reg <= input_1_axis_tuser_reg; + end + 4'd2: begin + output_15_axis_tdata_reg <= input_2_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_2_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_2_axis_tlast_reg; + output_15_axis_tid_reg <= input_2_axis_tid_reg; + output_15_axis_tdest_reg <= input_2_axis_tdest_reg; + output_15_axis_tuser_reg <= input_2_axis_tuser_reg; + end + 4'd3: begin + output_15_axis_tdata_reg <= input_3_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_3_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_3_axis_tlast_reg; + output_15_axis_tid_reg <= input_3_axis_tid_reg; + output_15_axis_tdest_reg <= input_3_axis_tdest_reg; + output_15_axis_tuser_reg <= input_3_axis_tuser_reg; + end + 4'd4: begin + output_15_axis_tdata_reg <= input_4_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_4_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_4_axis_tlast_reg; + output_15_axis_tid_reg <= input_4_axis_tid_reg; + output_15_axis_tdest_reg <= input_4_axis_tdest_reg; + output_15_axis_tuser_reg <= input_4_axis_tuser_reg; + end + 4'd5: begin + output_15_axis_tdata_reg <= input_5_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_5_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_5_axis_tlast_reg; + output_15_axis_tid_reg <= input_5_axis_tid_reg; + output_15_axis_tdest_reg <= input_5_axis_tdest_reg; + output_15_axis_tuser_reg <= input_5_axis_tuser_reg; + end + 4'd6: begin + output_15_axis_tdata_reg <= input_6_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_6_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_6_axis_tlast_reg; + output_15_axis_tid_reg <= input_6_axis_tid_reg; + output_15_axis_tdest_reg <= input_6_axis_tdest_reg; + output_15_axis_tuser_reg <= input_6_axis_tuser_reg; + end + 4'd7: begin + output_15_axis_tdata_reg <= input_7_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_7_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_7_axis_tlast_reg; + output_15_axis_tid_reg <= input_7_axis_tid_reg; + output_15_axis_tdest_reg <= input_7_axis_tdest_reg; + output_15_axis_tuser_reg <= input_7_axis_tuser_reg; + end + 4'd8: begin + output_15_axis_tdata_reg <= input_8_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_8_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_8_axis_tlast_reg; + output_15_axis_tid_reg <= input_8_axis_tid_reg; + output_15_axis_tdest_reg <= input_8_axis_tdest_reg; + output_15_axis_tuser_reg <= input_8_axis_tuser_reg; + end + 4'd9: begin + output_15_axis_tdata_reg <= input_9_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_9_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_9_axis_tlast_reg; + output_15_axis_tid_reg <= input_9_axis_tid_reg; + output_15_axis_tdest_reg <= input_9_axis_tdest_reg; + output_15_axis_tuser_reg <= input_9_axis_tuser_reg; + end + 4'd10: begin + output_15_axis_tdata_reg <= input_10_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_10_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_10_axis_tlast_reg; + output_15_axis_tid_reg <= input_10_axis_tid_reg; + output_15_axis_tdest_reg <= input_10_axis_tdest_reg; + output_15_axis_tuser_reg <= input_10_axis_tuser_reg; + end + 4'd11: begin + output_15_axis_tdata_reg <= input_11_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_11_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_11_axis_tlast_reg; + output_15_axis_tid_reg <= input_11_axis_tid_reg; + output_15_axis_tdest_reg <= input_11_axis_tdest_reg; + output_15_axis_tuser_reg <= input_11_axis_tuser_reg; + end + 4'd12: begin + output_15_axis_tdata_reg <= input_12_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_12_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_12_axis_tlast_reg; + output_15_axis_tid_reg <= input_12_axis_tid_reg; + output_15_axis_tdest_reg <= input_12_axis_tdest_reg; + output_15_axis_tuser_reg <= input_12_axis_tuser_reg; + end + 4'd13: begin + output_15_axis_tdata_reg <= input_13_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_13_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_13_axis_tlast_reg; + output_15_axis_tid_reg <= input_13_axis_tid_reg; + output_15_axis_tdest_reg <= input_13_axis_tdest_reg; + output_15_axis_tuser_reg <= input_13_axis_tuser_reg; + end + 4'd14: begin + output_15_axis_tdata_reg <= input_14_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_14_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_14_axis_tlast_reg; + output_15_axis_tid_reg <= input_14_axis_tid_reg; + output_15_axis_tdest_reg <= input_14_axis_tdest_reg; + output_15_axis_tuser_reg <= input_14_axis_tuser_reg; + end + 4'd15: begin + output_15_axis_tdata_reg <= input_15_axis_tdata_reg; + output_15_axis_tkeep_reg <= input_15_axis_tkeep_reg; + output_15_axis_tlast_reg <= input_15_axis_tlast_reg; + output_15_axis_tid_reg <= input_15_axis_tid_reg; + output_15_axis_tdest_reg <= input_15_axis_tdest_reg; + output_15_axis_tuser_reg <= input_15_axis_tuser_reg; + end + endcase +end + +endmodule diff --git a/example/HXT100G/fpga_cxpt16/rtl/debounce_switch.v b/example/HXT100G/fpga_cxpt16/rtl/debounce_switch.v new file mode 100644 index 000000000..69f30d706 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/HXT100G/fpga_cxpt16/rtl/eth_gth_phy_quad.v b/example/HXT100G/fpga_cxpt16/rtl/eth_gth_phy_quad.v new file mode 100644 index 000000000..60ab0f137 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/rtl/eth_gth_phy_quad.v @@ -0,0 +1,569 @@ +/* + +Copyright (c) 2015-2018 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. + +*/ + +module eth_gth_phy_quad ( + /* + * Clock and reset + */ + input wire clk156, + input wire rst156, + input wire dclk, + input wire dclk_reset, + + output wire txclk156, + + input wire gth_reset, + output wire gth_reset_done, + + /* + * Transciever pins + */ + input wire refclk_p, + input wire refclk_n, + output wire txp_0, + output wire txn_0, + input wire rxp_0, + input wire rxn_0, + output wire txp_1, + output wire txn_1, + input wire rxp_1, + input wire rxn_1, + output wire txp_2, + output wire txn_2, + input wire rxp_2, + input wire rxn_2, + output wire txp_3, + output wire txn_3, + input wire rxp_3, + input wire rxn_3, + + /* + * XGMII interfaces + */ + input wire [63:0] xgmii_txd_0, + input wire [7:0] xgmii_txc_0, + output wire [63:0] xgmii_rxd_0, + output wire [7:0] xgmii_rxc_0, + input wire [63:0] xgmii_txd_1, + input wire [7:0] xgmii_txc_1, + output wire [63:0] xgmii_rxd_1, + output wire [7:0] xgmii_rxc_1, + input wire [63:0] xgmii_txd_2, + input wire [7:0] xgmii_txc_2, + output wire [63:0] xgmii_rxd_2, + output wire [7:0] xgmii_rxc_2, + input wire [63:0] xgmii_txd_3, + input wire [7:0] xgmii_txc_3, + output wire [63:0] xgmii_rxd_3, + output wire [7:0] xgmii_rxc_3, + + /* + * Control + */ + input wire tx_powerdown_0, + input wire rx_powerdown_0, + input wire tx_powerdown_1, + input wire rx_powerdown_1, + input wire tx_powerdown_2, + input wire rx_powerdown_2, + input wire tx_powerdown_3, + input wire rx_powerdown_3 +); + +wire [63:0] gth_txd_0; +wire [7:0] gth_txc_0; +wire [63:0] gth_rxd_0; +wire [7:0] gth_rxc_0; +wire [63:0] gth_txd_1; +wire [7:0] gth_txc_1; +wire [63:0] gth_rxd_1; +wire [7:0] gth_rxc_1; +wire [63:0] gth_txd_2; +wire [7:0] gth_txc_2; +wire [63:0] gth_rxd_2; +wire [7:0] gth_rxc_2; +wire [63:0] gth_txd_3; +wire [7:0] gth_txc_3; +wire [63:0] gth_rxd_3; +wire [7:0] gth_rxc_3; + +wire mgmt_rd; +wire mgmt_wr; +wire mgmt_rdack; +wire [20:0] mgmt_addr; +wire [15:0] mgmt_rddata; +wire [15:0] mgmt_wrdata; + +wire mgmt_rd0; +wire mgmt_wr0; +wire [20:0] mgmt_addr0; +wire [15:0] mgmt_wrdata0; + +wire mgmt_req0; +wire mgmt_gnt0; + +wire mgmt_rd1; +wire mgmt_wr1; +wire [20:0] mgmt_addr1; +wire [15:0] mgmt_wrdata1; + +wire mgmt_req1; +wire mgmt_gnt1; + +wire mgmt_rd2; +wire mgmt_wr2; +wire [20:0] mgmt_addr2; +wire [15:0] mgmt_wrdata2; + +wire mgmt_req2; +wire mgmt_gnt2; + +wire mgmt_rd3; +wire mgmt_wr3; +wire [20:0] mgmt_addr3; +wire [15:0] mgmt_wrdata3; + +wire mgmt_req3; +wire mgmt_gnt3; + +// clocking +wire refclk; + +IBUFDS_GTHE1 refclk_ibufds_inst +( + .I(refclk_p), + .IB(refclk_n), + .O(refclk) +); + +wire rx_clk_0; +wire rx_clk_0_buf; +wire rx_clk_1; +wire rx_clk_1_buf; +wire rx_clk_2; +wire rx_clk_2_buf; +wire rx_clk_3; +wire rx_clk_3_buf; + +BUFR #( + .SIM_DEVICE("VIRTEX6") +) +rx_clk_0_buf_inst +( + .CE(1'b1), + .CLR(1'b0), + .I(rx_clk_0), + .O(rx_clk_0_buf) +); + +BUFR #( + .SIM_DEVICE("VIRTEX6") +) +rx_clk_1_buf_inst +( + .CE(1'b1), + .CLR(1'b0), + .I(rx_clk_1), + .O(rx_clk_1_buf) +); + +BUFG rx_clk_2_buf_inst +( + .I(rx_clk_2), + .O(rx_clk_2_buf) +); + +BUFG rx_clk_3_buf_inst +( + .I(rx_clk_3), + .O(rx_clk_3_buf) +); + +wire tx_resetdone_0; +wire rx_resetdone_0; +wire tx_resetdone_1; +wire rx_resetdone_1; +wire tx_resetdone_2; +wire rx_resetdone_2; +wire tx_resetdone_3; +wire rx_resetdone_3; + +wire resetdone_0 = tx_resetdone_0 & rx_resetdone_0; +wire resetdone_1 = tx_resetdone_1 & rx_resetdone_1; +wire resetdone_2 = tx_resetdone_2 & rx_resetdone_2; +wire resetdone_3 = tx_resetdone_3 & rx_resetdone_3; + +reg gth_reset_done_reg = 0; + +assign gth_reset_done = gth_reset_done_reg; + +// register overall reset done output +always @(posedge clk156) begin + gth_reset_done_reg <= resetdone_0 & resetdone_1 & resetdone_2 & resetdone_3; +end + +wire disable_drp_mgmt; + +wire disable_drp = gth_reset_done & disable_drp_mgmt; + +wire lane_sel = {mgmt_gnt3, mgmt_gnt2, mgmt_gnt1, mgmt_gnt0}; + +// GTH quad wrapper +ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_QUAD # +( + // Simulation attributes + .QUAD_SIM_GTHRESET_SPEEDUP(0) +) +gth_inst +( + //------------------------------- Resetdone -------------------------------- + .TX_PCS_RESETDONE0_OUT (tx_resetdone_0), + .RX_PCS_CDR_RESETDONE0_OUT (rx_resetdone_0), + .TX_PCS_RESETDONE1_OUT (tx_resetdone_1), + .RX_PCS_CDR_RESETDONE1_OUT (rx_resetdone_1), + .TX_PCS_RESETDONE2_OUT (tx_resetdone_2), + .RX_PCS_CDR_RESETDONE2_OUT (rx_resetdone_2), + .TX_PCS_RESETDONE3_OUT (tx_resetdone_3), + .RX_PCS_CDR_RESETDONE3_OUT (rx_resetdone_3), + //------------------------------- Initdone --------------------------------- + .GTHINITDONE_OUT (), + //------------------------------- PCS Resets ------------------------------- + .TX_PCS_RESET0_IN (1'b0), + .RX_PCS_CDR_RESET0_IN (1'b0), + .TX_PCS_RESET1_IN (1'b0), + .RX_PCS_CDR_RESET1_IN (1'b0), + .TX_PCS_RESET2_IN (1'b0), + .RX_PCS_CDR_RESET2_IN (1'b0), + .TX_PCS_RESET3_IN (1'b0), + .RX_PCS_CDR_RESET3_IN (1'b0), + //------------------------------- Powerdown -------------------------------- + .POWERDOWN0_IN (1'b0), + .POWERDOWN1_IN (1'b0), + .POWERDOWN2_IN (1'b0), + .POWERDOWN3_IN (1'b0), + .RXPOWERDOWN0_IN ({rx_powerdown_0 | (~gth_reset_done), 1'b0}), + .RXPOWERDOWN1_IN ({rx_powerdown_1 | (~gth_reset_done), 1'b0}), + .RXPOWERDOWN2_IN ({rx_powerdown_2 | (~gth_reset_done), 1'b0}), + .RXPOWERDOWN3_IN ({rx_powerdown_3 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN0_IN ({tx_powerdown_0 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN1_IN ({tx_powerdown_1 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN2_IN ({tx_powerdown_2 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN3_IN ({tx_powerdown_3 | (~gth_reset_done), 1'b0}), + //----------------------------- Receive Ports ------------------------------ + .RXBUFRESET0_IN (1'b0), + .RXBUFRESET1_IN (1'b0), + .RXBUFRESET2_IN (1'b0), + .RXBUFRESET3_IN (1'b0), + .RXCODEERR0_OUT (), + .RXCODEERR1_OUT (), + .RXCODEERR2_OUT (), + .RXCODEERR3_OUT (), + .RXCTRL0_OUT (gth_rxc_0), + .RXCTRL1_OUT (gth_rxc_1), + .RXCTRL2_OUT (gth_rxc_2), + .RXCTRL3_OUT (gth_rxc_3), + .RXCTRLACK0_OUT (), + .RXCTRLACK1_OUT (), + .RXCTRLACK2_OUT (), + .RXCTRLACK3_OUT (), + .RXDATA0_OUT (gth_rxd_0), + .RXDATA1_OUT (gth_rxd_1), + .RXDATA2_OUT (gth_rxd_2), + .RXDATA3_OUT (gth_rxd_3), + .RXN0_IN (rxn_0), + .RXN1_IN (rxn_1), + .RXN2_IN (rxn_2), + .RXN3_IN (rxn_3), + .RXP0_IN (rxp_0), + .RXP1_IN (rxp_1), + .RXP2_IN (rxp_2), + .RXP3_IN (rxp_3), + .RXUSERCLKIN0_IN (rx_clk_0_buf), + .RXUSERCLKIN1_IN (rx_clk_1_buf), + .RXUSERCLKIN2_IN (rx_clk_2_buf), + .RXUSERCLKIN3_IN (rx_clk_3_buf), + .RXUSERCLKOUT0_OUT (rx_clk_0), + .RXUSERCLKOUT1_OUT (rx_clk_1), + .RXUSERCLKOUT2_OUT (rx_clk_2), + .RXUSERCLKOUT3_OUT (rx_clk_3), + //----------- Shared Ports - Dynamic Reconfiguration Port () ------------ + .DADDR_IN (16'h0000), + .DCLK_IN (dclk), + .DEN_IN (1'b0), + .DI_IN (16'h0000), + .DISABLEDRP_IN (disable_drp), + .DRDY_OUT (), + .DRPDO_OUT (), + .DWE_IN (1'b0), + //-------------------------- Shared Ports - Other -------------------------- + .TSTREFCLKFAB_OUT (), + .TSTREFCLKOUT_OUT (), + .GTHINIT_IN (1'b0), + .GTHRESET_IN (gth_reset), + .MGMTPCSLANESEL_IN (lane_sel), + .MGMTPCSMMDADDR_IN (mgmt_addr[20:16]), + .MGMTPCSRDACK_OUT (mgmt_rdack), + .MGMTPCSRDDATA_OUT (mgmt_rddata), + .MGMTPCSREGADDR_IN (mgmt_addr[15:0]), + .MGMTPCSREGRD_IN (mgmt_rd), + .MGMTPCSREGWR_IN (mgmt_wr), + .MGMTPCSWRDATA_IN (mgmt_wrdata), + .REFCLK_IN (refclk), + //----------------------------- Transmit Ports ----------------------------- + .TXBUFRESET0_IN (1'b0), + .TXBUFRESET1_IN (1'b0), + .TXBUFRESET2_IN (1'b0), + .TXBUFRESET3_IN (1'b0), + .TXCTRL0_IN (gth_txc_0), + .TXCTRL1_IN (gth_txc_1), + .TXCTRL2_IN (gth_txc_2), + .TXCTRL3_IN (gth_txc_3), + .TXCTRLACK0_OUT (), + .TXCTRLACK1_OUT (), + .TXCTRLACK2_OUT (), + .TXCTRLACK3_OUT (), + .TXDATA0_IN (gth_txd_0), + .TXDATA1_IN (gth_txd_1), + .TXDATA2_IN (gth_txd_2), + .TXDATA3_IN (gth_txd_3), + .TXN0_OUT (txn_0), + .TXN1_OUT (txn_1), + .TXN2_OUT (txn_2), + .TXN3_OUT (txn_3), + .TXP0_OUT (txp_0), + .TXP1_OUT (txp_1), + .TXP2_OUT (txp_2), + .TXP3_OUT (txp_3), + .TXUSERCLKIN0_IN (clk156), + .TXUSERCLKIN1_IN (clk156), + .TXUSERCLKIN2_IN (clk156), + .TXUSERCLKIN3_IN (clk156), + .TXUSERCLKOUT0_OUT (txclk156), + .TXUSERCLKOUT1_OUT (), + .TXUSERCLKOUT2_OUT (), + .TXUSERCLKOUT3_OUT () +); + +wire [535:0] configuration_vector; + +assign configuration_vector[14:1] = 0; +assign configuration_vector[79:17] = 0; +assign configuration_vector[109:84] = 0; +assign configuration_vector[175:170] = 0; +assign configuration_vector[239:234] = 0; +assign configuration_vector[269:246] = 0; +assign configuration_vector[511:272] = 0; +assign configuration_vector[515:513] = 0; +assign configuration_vector[517:517] = 0; +assign configuration_vector[0] = 0; // pma_loopback; +assign configuration_vector[15] = 0; // pma_reset; +assign configuration_vector[16] = 0; // global_tx_disable; +assign configuration_vector[83:80] = 0; // pma_vs_loopback; +assign configuration_vector[110] = 0; // pcs_loopback; +assign configuration_vector[111] = 0; // pcs_reset; +assign configuration_vector[169:112] = 0; // test_patt_a; +assign configuration_vector[233:176] = 0; // test_patt_b; +assign configuration_vector[240] = 0; // data_patt_sel; +assign configuration_vector[241] = 0; // test_patt_sel; +assign configuration_vector[242] = 0; // rx_test_patt_en; +assign configuration_vector[243] = 0; // tx_test_patt_en; +assign configuration_vector[244] = 0; // prbs31_tx_en; +assign configuration_vector[245] = 0; // prbs31_rx_en; +assign configuration_vector[271:270] = 0; // pcs_vs_loopback; +assign configuration_vector[512] = 0; // set_pma_link_status; +assign configuration_vector[516] = 0; // set_pcs_link_status; +assign configuration_vector[518] = 0; // clear_pcs_status2; +assign configuration_vector[519] = 0; // clear_test_patt_err_count; +assign configuration_vector[535:520] = 0; + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_0 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_0_buf), + .xgmii_txd(xgmii_txd_0), + .xgmii_txc(xgmii_txc_0), + .xgmii_rxd(xgmii_rxd_0), + .xgmii_rxc(xgmii_rxc_0), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req0), + .mgmt_gnt(mgmt_gnt0), + .mgmt_rd_out(mgmt_rd0), + .mgmt_wr_out(mgmt_wr0), + .mgmt_addr_out(mgmt_addr0), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata0), + .gt_txd(gth_txd_0), + .gt_txc(gth_txc_0), + .gt_rxd(gth_rxd_0), + .gt_rxc(gth_rxc_0), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_1 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_1_buf), + .xgmii_txd(xgmii_txd_1), + .xgmii_txc(xgmii_txc_1), + .xgmii_rxd(xgmii_rxd_1), + .xgmii_rxc(xgmii_rxc_1), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req1), + .mgmt_gnt(mgmt_gnt1), + .mgmt_rd_out(mgmt_rd1), + .mgmt_wr_out(mgmt_wr1), + .mgmt_addr_out(mgmt_addr1), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata1), + .gt_txd(gth_txd_1), + .gt_txc(gth_txc_1), + .gt_rxd(gth_rxd_1), + .gt_rxc(gth_rxc_1), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_2 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_2_buf), + .xgmii_txd(xgmii_txd_2), + .xgmii_txc(xgmii_txc_2), + .xgmii_rxd(xgmii_rxd_2), + .xgmii_rxc(xgmii_rxc_2), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req2), + .mgmt_gnt(mgmt_gnt2), + .mgmt_rd_out(mgmt_rd2), + .mgmt_wr_out(mgmt_wr2), + .mgmt_addr_out(mgmt_addr2), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata2), + .gt_txd(gth_txd_2), + .gt_txc(gth_txc_2), + .gt_rxd(gth_rxd_2), + .gt_rxc(gth_rxc_2), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_3 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_3_buf), + .xgmii_txd(xgmii_txd_3), + .xgmii_txc(xgmii_txc_3), + .xgmii_rxd(xgmii_rxd_3), + .xgmii_rxc(xgmii_rxc_3), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req3), + .mgmt_gnt(mgmt_gnt3), + .mgmt_rd_out(mgmt_rd3), + .mgmt_wr_out(mgmt_wr3), + .mgmt_addr_out(mgmt_addr3), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata3), + .gt_txd(gth_txd_3), + .gt_txc(gth_txc_3), + .gt_rxd(gth_rxd_3), + .gt_rxc(gth_rxc_3), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6_management_arbiter +mgmt_arb_inst +( + .dclk(dclk), + .reset(dclk_reset), + + .mgmt_rd0(mgmt_rd0), + .mgmt_wr0(mgmt_wr0), + .mgmt_addr0(mgmt_addr0), + .mgmt_wrdata0(mgmt_wrdata0), + + .mgmt_req0(mgmt_req0), + .mgmt_gnt0(mgmt_gnt0), + + .mgmt_rd1(mgmt_rd1), + .mgmt_wr1(mgmt_wr1), + .mgmt_addr1(mgmt_addr1), + .mgmt_wrdata1(mgmt_wrdata1), + + .mgmt_req1(mgmt_req1), + .mgmt_gnt1(mgmt_gnt1), + + .mgmt_rd2(mgmt_rd2), + .mgmt_wr2(mgmt_wr2), + .mgmt_addr2(mgmt_addr2), + .mgmt_wrdata2(mgmt_wrdata2), + + .mgmt_req2(mgmt_req2), + .mgmt_gnt2(mgmt_gnt2), + + .mgmt_rd3(mgmt_rd3), + .mgmt_wr3(mgmt_wr3), + .mgmt_addr3(mgmt_addr3), + .mgmt_wrdata3(mgmt_wrdata3), + + .mgmt_req3(mgmt_req3), + .mgmt_gnt3(mgmt_gnt3), + + .mgmt_rd(mgmt_rd), + .mgmt_wr(mgmt_wr), + .mgmt_addr(mgmt_addr), + .mgmt_wrdata(mgmt_wrdata), + + .drp_req(1'b0), + .drp_gnt(), + + .disable_drp(disable_drp_mgmt) +); + +endmodule diff --git a/example/HXT100G/fpga_cxpt16/rtl/fpga.v b/example/HXT100G/fpga_cxpt16/rtl/fpga.v new file mode 100644 index 000000000..66f1df8d7 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/rtl/fpga.v @@ -0,0 +1,1131 @@ +/* + +Copyright (c) 2016-2018 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. + +*/ + +module fpga ( + /* + * Clock: 50MHz + */ + input wire sys_clk, + /* + * Clock: 200MHz + */ + //input wire clk_ddr3_p, + //input wire clk_ddr3_n, + /* + * Clock: User + */ + //input wire clk_usr_p, + //input wire clk_usr_pr_n, + /* + * Reset: Push button, active low + */ + input wire reset_n, + /* + * GPIO + */ + input wire [1:0] sw, + input wire [3:0] jp, + output wire [3:0] led, + /* + * Silicon Labs CP2102 USB UART + */ + output wire uart_rst, + input wire uart_suspend, + output wire uart_ri, + output wire uart_dcd, + input wire uart_dtr, + output wire uart_dsr, + input wire uart_txd, + output wire uart_rxd, + input wire uart_rts, + output wire uart_cts, + /* + * Clock muxes + */ + inout wire clk_gth_scl, + inout wire clk_gth_sda, + output wire clk_gth_rst_n, + input wire clk_gthl_alm, + input wire clk_gthl_lol, + input wire clk_gthr_alm, + input wire clk_gthr_lol, + /* + * AirMax I/O + */ + output wire amh_right_mdc, + inout wire amh_right_mdio, + output wire amh_right_phy_rst_n, + output wire amh_left_mdc, + inout wire amh_left_mdio, + output wire amh_left_phy_rst_n, + /* + * 10G Ethernet + */ + input wire gth_quad_A_refclk_p, + input wire gth_quad_A_refclk_n, + output wire gth_quad_A_txp_0, + output wire gth_quad_A_txn_0, + input wire gth_quad_A_rxp_0, + input wire gth_quad_A_rxn_0, + output wire gth_quad_A_txp_1, + output wire gth_quad_A_txn_1, + input wire gth_quad_A_rxp_1, + input wire gth_quad_A_rxn_1, + output wire gth_quad_A_txp_2, + output wire gth_quad_A_txn_2, + input wire gth_quad_A_rxp_2, + input wire gth_quad_A_rxn_2, + output wire gth_quad_A_txp_3, + output wire gth_quad_A_txn_3, + input wire gth_quad_A_rxp_3, + input wire gth_quad_A_rxn_3, + input wire gth_quad_B_refclk_p, + input wire gth_quad_B_refclk_n, + output wire gth_quad_B_txp_0, + output wire gth_quad_B_txn_0, + input wire gth_quad_B_rxp_0, + input wire gth_quad_B_rxn_0, + output wire gth_quad_B_txp_1, + output wire gth_quad_B_txn_1, + input wire gth_quad_B_rxp_1, + input wire gth_quad_B_rxn_1, + output wire gth_quad_B_txp_2, + output wire gth_quad_B_txn_2, + input wire gth_quad_B_rxp_2, + input wire gth_quad_B_rxn_2, + output wire gth_quad_B_txp_3, + output wire gth_quad_B_txn_3, + input wire gth_quad_B_rxp_3, + input wire gth_quad_B_rxn_3, + input wire gth_quad_C_refclk_p, + input wire gth_quad_C_refclk_n, + output wire gth_quad_C_txp_0, + output wire gth_quad_C_txn_0, + input wire gth_quad_C_rxp_0, + input wire gth_quad_C_rxn_0, + output wire gth_quad_C_txp_1, + output wire gth_quad_C_txn_1, + input wire gth_quad_C_rxp_1, + input wire gth_quad_C_rxn_1, + output wire gth_quad_C_txp_2, + output wire gth_quad_C_txn_2, + input wire gth_quad_C_rxp_2, + input wire gth_quad_C_rxn_2, + output wire gth_quad_C_txp_3, + output wire gth_quad_C_txn_3, + input wire gth_quad_C_rxp_3, + input wire gth_quad_C_rxn_3, + input wire gth_quad_D_refclk_p, + input wire gth_quad_D_refclk_n, + output wire gth_quad_D_txp_0, + output wire gth_quad_D_txn_0, + input wire gth_quad_D_rxp_0, + input wire gth_quad_D_rxn_0, + output wire gth_quad_D_txp_1, + output wire gth_quad_D_txn_1, + input wire gth_quad_D_rxp_1, + input wire gth_quad_D_rxn_1, + output wire gth_quad_D_txp_2, + output wire gth_quad_D_txn_2, + input wire gth_quad_D_rxp_2, + input wire gth_quad_D_rxn_2, + output wire gth_quad_D_txp_3, + output wire gth_quad_D_txn_3, + input wire gth_quad_D_rxp_3, + input wire gth_quad_D_rxn_3, + input wire gth_quad_E_refclk_p, + input wire gth_quad_E_refclk_n, + output wire gth_quad_E_txp_0, + output wire gth_quad_E_txn_0, + input wire gth_quad_E_rxp_0, + input wire gth_quad_E_rxn_0, + output wire gth_quad_E_txp_1, + output wire gth_quad_E_txn_1, + input wire gth_quad_E_rxp_1, + input wire gth_quad_E_rxn_1, + output wire gth_quad_E_txp_2, + output wire gth_quad_E_txn_2, + input wire gth_quad_E_rxp_2, + input wire gth_quad_E_rxn_2, + output wire gth_quad_E_txp_3, + output wire gth_quad_E_txn_3, + input wire gth_quad_E_rxp_3, + input wire gth_quad_E_rxn_3, + input wire gth_quad_F_refclk_p, + input wire gth_quad_F_refclk_n, + output wire gth_quad_F_txp_0, + output wire gth_quad_F_txn_0, + input wire gth_quad_F_rxp_0, + input wire gth_quad_F_rxn_0, + output wire gth_quad_F_txp_1, + output wire gth_quad_F_txn_1, + input wire gth_quad_F_rxp_1, + input wire gth_quad_F_rxn_1, + output wire gth_quad_F_txp_2, + output wire gth_quad_F_txn_2, + input wire gth_quad_F_rxp_2, + input wire gth_quad_F_rxn_2, + output wire gth_quad_F_txp_3, + output wire gth_quad_F_txn_3, + input wire gth_quad_F_rxp_3, + input wire gth_quad_F_rxn_3 +); + +/* + * Clock: 50MHz + */ +wire sys_clk_ibufg; +wire sys_clk_int; + +/* + * Clock: 156.25 MHz + */ +wire clk_156mhz; + +/* + * Synchronous reset + */ +wire sys_rst; +wire rst_156mhz; + +/* + * GPIO + */ +wire [1:0] sw_int; +wire [3:0] jp_int; +wire [3:0] led_int; + +/* + * Silicon Labs CP2102 USB UART + */ +wire uart_sys_rst; +wire uart_suspend_int; +wire uart_ri_int; +wire uart_dcd_int; +wire uart_dtr_int; +wire uart_dsr_int; +wire uart_txd_int; +wire uart_rxd_int; +wire uart_rts_int; +wire uart_cts_int; + +/* + * Clock muxes + */ +wire clk_gth_scl_i; +wire clk_gth_scl_o; +wire clk_gth_scl_t; +wire clk_gth_sda_i; +wire clk_gth_sda_o; +wire clk_gth_sda_t; +wire clk_gthl_alm_int; +wire clk_gthl_lol_int; +wire clk_gthr_alm_int; +wire clk_gthr_lol_int; + +/* + * AirMax I/O + */ +wire amh_right_mdc_int; +wire amh_right_mdio_i_int; +wire amh_right_mdio_o_int; +wire amh_right_mdio_t_int; +wire amh_left_mdc_int; +wire amh_left_mdio_i_int; +wire amh_left_mdio_o_int; +wire amh_left_mdio_t_int; + +/* + * 10G Ethernet + */ +wire [63:0] eth_r0_txd; +wire [7:0] eth_r0_txc; +wire [63:0] eth_r0_rxd; +wire [7:0] eth_r0_rxc; +wire [63:0] eth_r1_txd; +wire [7:0] eth_r1_txc; +wire [63:0] eth_r1_rxd; +wire [7:0] eth_r1_rxc; +wire [63:0] eth_r2_txd; +wire [7:0] eth_r2_txc; +wire [63:0] eth_r2_rxd; +wire [7:0] eth_r2_rxc; +wire [63:0] eth_r3_txd; +wire [7:0] eth_r3_txc; +wire [63:0] eth_r3_rxd; +wire [7:0] eth_r3_rxc; +wire [63:0] eth_r4_txd; +wire [7:0] eth_r4_txc; +wire [63:0] eth_r4_rxd; +wire [7:0] eth_r4_rxc; +wire [63:0] eth_r5_txd; +wire [7:0] eth_r5_txc; +wire [63:0] eth_r5_rxd; +wire [7:0] eth_r5_rxc; +wire [63:0] eth_r6_txd; +wire [7:0] eth_r6_txc; +wire [63:0] eth_r6_rxd; +wire [7:0] eth_r6_rxc; +wire [63:0] eth_r7_txd; +wire [7:0] eth_r7_txc; +wire [63:0] eth_r7_rxd; +wire [7:0] eth_r7_rxc; +wire [63:0] eth_r8_txd; +wire [7:0] eth_r8_txc; +wire [63:0] eth_r8_rxd; +wire [7:0] eth_r8_rxc; +wire [63:0] eth_r9_txd; +wire [7:0] eth_r9_txc; +wire [63:0] eth_r9_rxd; +wire [7:0] eth_r9_rxc; +wire [63:0] eth_r10_txd; +wire [7:0] eth_r10_txc; +wire [63:0] eth_r10_rxd; +wire [7:0] eth_r10_rxc; +wire [63:0] eth_r11_txd; +wire [7:0] eth_r11_txc; +wire [63:0] eth_r11_rxd; +wire [7:0] eth_r11_rxc; +wire [63:0] eth_l0_txd; +wire [7:0] eth_l0_txc; +wire [63:0] eth_l0_rxd; +wire [7:0] eth_l0_rxc; +wire [63:0] eth_l1_txd; +wire [7:0] eth_l1_txc; +wire [63:0] eth_l1_rxd; +wire [7:0] eth_l1_rxc; +wire [63:0] eth_l2_txd; +wire [7:0] eth_l2_txc; +wire [63:0] eth_l2_rxd; +wire [7:0] eth_l2_rxc; +wire [63:0] eth_l3_txd; +wire [7:0] eth_l3_txc; +wire [63:0] eth_l3_rxd; +wire [7:0] eth_l3_rxc; +wire [63:0] eth_l4_txd; +wire [7:0] eth_l4_txc; +wire [63:0] eth_l4_rxd; +wire [7:0] eth_l4_rxc; +wire [63:0] eth_l5_txd; +wire [7:0] eth_l5_txc; +wire [63:0] eth_l5_rxd; +wire [7:0] eth_l5_rxc; +wire [63:0] eth_l6_txd; +wire [7:0] eth_l6_txc; +wire [63:0] eth_l6_rxd; +wire [7:0] eth_l6_rxc; +wire [63:0] eth_l7_txd; +wire [7:0] eth_l7_txc; +wire [63:0] eth_l7_rxd; +wire [7:0] eth_l7_rxc; +wire [63:0] eth_l8_txd; +wire [7:0] eth_l8_txc; +wire [63:0] eth_l8_rxd; +wire [7:0] eth_l8_rxc; +wire [63:0] eth_l9_txd; +wire [7:0] eth_l9_txc; +wire [63:0] eth_l9_rxd; +wire [7:0] eth_l9_rxc; +wire [63:0] eth_l10_txd; +wire [7:0] eth_l10_txc; +wire [63:0] eth_l10_rxd; +wire [7:0] eth_l10_rxc; +wire [63:0] eth_l11_txd; +wire [7:0] eth_l11_txc; +wire [63:0] eth_l11_rxd; +wire [7:0] eth_l11_rxc; + +// Clock buffering for 50 MHz sys_clk +IBUFG +sys_clk_ibufg_inst ( + .I(sys_clk), + .O(sys_clk_ibufg) +); + +BUFG +sys_clk_bufg_inst ( + .I(sys_clk_ibufg), + .O(sys_clk_int) +); + +// 156.25 MHz clock from GTH +wire txclk156; + +BUFG +clk156_bufg_inst ( + .I(txclk156), + .O(clk_156mhz) +); + +// Synchronize reset signal +sync_reset #( + .N(6) +) +sync_reset_inst ( + .clk(sys_clk_int), + .rst(~reset_n), + .sync_reset_out(sys_rst) +); + +sync_signal #( + .WIDTH(4), + .N(2) +) +sync_signal_50mhz_inst ( + .clk(sys_clk_int), + .in({clk_gthl_alm, + clk_gthl_lol, + clk_gthr_alm, + clk_gthr_lol}), + .out({clk_gthl_alm_int, + clk_gthl_lol_int, + clk_gthr_alm_int, + clk_gthr_lol_int}) +); + +sync_signal #( + .WIDTH(4), + .N(2) +) +sync_signal_156mhz_inst ( + .clk(clk_156mhz), + .in({uart_suspend, + uart_dtr, + uart_txd, + uart_rts}), + .out({uart_suspend_int, + uart_dtr_int, + uart_txd_int, + uart_rts_int}) +); + +// Debounce switch inputs +debounce_switch #( + .WIDTH(6), + .N(4), + .RATE(50000) +) +debounce_switch_inst ( + .clk(sys_clk_int), + .rst(sys_rst), + .in({sw, jp}), + .out({sw_int, jp_int}) +); + +// pass through outputs +assign led = led_int; + +assign uart_rst = uart_rst_int; +assign uart_ri = uart_ri_int; +assign uart_dcd = uart_dcd_int; +assign uart_dsr = uart_dsr_int; +assign uart_rxd = uart_rxd_int; +assign uart_cts = uart_cts_int; + +// clock mux I2C +assign clk_gth_scl_i = clk_gth_scl; +assign clk_gth_scl = clk_gth_scl_t ? 1'bz : clk_gth_scl_o; +assign clk_gth_sda_i = clk_gth_sda; +assign clk_gth_sda = clk_gth_sda_t ? 1'bz : clk_gth_sda_o; + +assign clk_gth_rst_n = ~sys_rst; + +wire [6:0] clk_gth_i2c_cmd_address; +wire clk_gth_i2c_cmd_start; +wire clk_gth_i2c_cmd_read; +wire clk_gth_i2c_cmd_write; +wire clk_gth_i2c_cmd_write_multiple; +wire clk_gth_i2c_cmd_stop; +wire clk_gth_i2c_cmd_valid; +wire clk_gth_i2c_cmd_ready; + +wire [7:0] clk_gth_i2c_data; +wire clk_gth_i2c_data_valid; +wire clk_gth_i2c_data_ready; +wire clk_gth_i2c_data_last; + +gth_i2c_init +clk_gth_i2c_init ( + .clk(sys_clk_int), + .rst(sys_rst), + .cmd_address(clk_gth_i2c_cmd_address), + .cmd_start(clk_gth_i2c_cmd_start), + .cmd_read(clk_gth_i2c_cmd_read), + .cmd_write(clk_gth_i2c_cmd_write), + .cmd_write_multiple(clk_gth_i2c_cmd_write_multiple), + .cmd_stop(clk_gth_i2c_cmd_stop), + .cmd_valid(clk_gth_i2c_cmd_valid), + .cmd_ready(clk_gth_i2c_cmd_ready), + .data_out(clk_gth_i2c_data), + .data_out_valid(clk_gth_i2c_data_valid), + .data_out_ready(clk_gth_i2c_data_ready), + .data_out_last(clk_gth_i2c_data_last), + .busy(), + .start(1) +); + +i2c_master +clk_gth_i2c_master ( + .clk(sys_clk_int), + .rst(sys_rst), + .cmd_address(clk_gth_i2c_cmd_address), + .cmd_start(clk_gth_i2c_cmd_start), + .cmd_read(clk_gth_i2c_cmd_read), + .cmd_write(clk_gth_i2c_cmd_write), + .cmd_write_multiple(clk_gth_i2c_cmd_write_multiple), + .cmd_stop(clk_gth_i2c_cmd_stop), + .cmd_valid(clk_gth_i2c_cmd_valid), + .cmd_ready(clk_gth_i2c_cmd_ready), + .data_in(clk_gth_i2c_data), + .data_in_valid(clk_gth_i2c_data_valid), + .data_in_ready(clk_gth_i2c_data_ready), + .data_in_last(clk_gth_i2c_data_last), + .data_out(), + .data_out_valid(), + .data_out_ready(1), + .data_out_last(), + .scl_i(clk_gth_scl_i), + .scl_o(clk_gth_scl_o), + .scl_t(clk_gth_scl_t), + .sda_i(clk_gth_sda_i), + .sda_o(clk_gth_sda_o), + .sda_t(clk_gth_sda_t), + .busy(), + .bus_control(), + .bus_active(), + .missed_ack(), + .prescale(312), + .stop_on_idle(1) +); + +// reset logic +wire gth_reset; + +wire gth_reset_done_A; +wire gth_reset_done_B; +wire gth_reset_done_C; +wire gth_reset_done_D; +wire gth_reset_done_E; +wire gth_reset_done_F; + +wire gth_reset_done = gth_reset_done_A & gth_reset_done_B & gth_reset_done_C & gth_reset_done_D & gth_reset_done_E & gth_reset_done_F; + +wire clk_gth_ready = ~clk_gthl_lol_int & ~clk_gthr_lol_int; + +sync_reset #( + .N(6) +) +sync_reset_gth_inst ( + .clk(sys_clk_int), + .rst(sys_rst | ~clk_gth_ready), + .sync_reset_out(gth_reset) +); + +sync_reset #( + .N(6) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz), + .rst(gth_reset | ~gth_reset_done), + .sync_reset_out(rst_156mhz) +); + +assign amh_right_phy_rst_n = ~rst_156mhz; +assign amh_left_phy_rst_n = ~rst_156mhz; + +// AirMax I/O + +assign amh_right_mdc = amh_right_mdc_int; + +assign amh_right_mdio_i_int = amh_right_mdio; +assign amh_right_mdio = amh_right_mdio_t_int ? 1'bz : amh_right_mdio_o_int; + +assign amh_left_mdc = amh_left_mdc_int; + +assign amh_left_mdio_i_int = amh_left_mdio; +assign amh_left_mdio = amh_left_mdio_t_int ? 1'bz : amh_left_mdio_o_int; + +// 10G Ethernet PCS/PMA + +// Quad A X0Y0 +eth_gth_phy_quad +eth_gth_phy_quad_A_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(txclk156), // pickoff one transmit clock for 156.25 MHz core clock + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_A), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_A_refclk_p), + .refclk_n(gth_quad_A_refclk_n), + .txn_0(gth_quad_A_txn_0), + .txp_0(gth_quad_A_txp_0), + .rxn_0(gth_quad_A_rxn_0), + .rxp_0(gth_quad_A_rxp_0), + .txn_1(gth_quad_A_txn_1), + .txp_1(gth_quad_A_txp_1), + .rxn_1(gth_quad_A_rxn_1), + .rxp_1(gth_quad_A_rxp_1), + .txn_2(gth_quad_A_txn_2), + .txp_2(gth_quad_A_txp_2), + .rxn_2(gth_quad_A_rxn_2), + .rxp_2(gth_quad_A_rxp_2), + .txn_3(gth_quad_A_txn_3), + .txp_3(gth_quad_A_txp_3), + .rxn_3(gth_quad_A_rxn_3), + .rxp_3(gth_quad_A_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_r0_txd), + .xgmii_txc_0(eth_r0_txc), + .xgmii_rxd_0(eth_r0_rxd), + .xgmii_rxc_0(eth_r0_rxc), + .xgmii_txd_1(eth_r2_txd), + .xgmii_txc_1(eth_r2_txc), + .xgmii_rxd_1(eth_r2_rxd), + .xgmii_rxc_1(eth_r2_rxc), + .xgmii_txd_2(eth_r4_txd), + .xgmii_txc_2(eth_r4_txc), + .xgmii_rxd_2(eth_r4_rxd), + .xgmii_rxc_2(eth_r4_rxc), + .xgmii_txd_3(eth_r6_txd), + .xgmii_txc_3(eth_r6_txc), + .xgmii_rxd_3(eth_r6_rxd), + .xgmii_rxc_3(eth_r6_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) +); + +// Quad B X0Y1 +eth_gth_phy_quad +eth_gth_phy_quad_B_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_B), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_B_refclk_p), + .refclk_n(gth_quad_B_refclk_n), + .txn_0(gth_quad_B_txn_0), + .txp_0(gth_quad_B_txp_0), + .rxn_0(gth_quad_B_rxn_0), + .rxp_0(gth_quad_B_rxp_0), + .txn_1(gth_quad_B_txn_1), + .txp_1(gth_quad_B_txp_1), + .rxn_1(gth_quad_B_rxn_1), + .rxp_1(gth_quad_B_rxp_1), + .txn_2(gth_quad_B_txn_2), + .txp_2(gth_quad_B_txp_2), + .rxn_2(gth_quad_B_rxn_2), + .rxp_2(gth_quad_B_rxp_2), + .txn_3(gth_quad_B_txn_3), + .txp_3(gth_quad_B_txp_3), + .rxn_3(gth_quad_B_rxn_3), + .rxp_3(gth_quad_B_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_r3_txd), + .xgmii_txc_0(eth_r3_txc), + .xgmii_rxd_0(eth_r3_rxd), + .xgmii_rxc_0(eth_r3_rxc), + .xgmii_txd_1(eth_r5_txd), + .xgmii_txc_1(eth_r5_txc), + .xgmii_rxd_1(eth_r5_rxd), + .xgmii_rxc_1(eth_r5_rxc), + .xgmii_txd_2(eth_r1_txd), + .xgmii_txc_2(eth_r1_txc), + .xgmii_rxd_2(eth_r1_rxd), + .xgmii_rxc_2(eth_r1_rxc), + .xgmii_txd_3(eth_r7_txd), + .xgmii_txc_3(eth_r7_txc), + .xgmii_rxd_3(eth_r7_rxd), + .xgmii_rxc_3(eth_r7_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) +); + +// Quad C X0Y2 +eth_gth_phy_quad +eth_gth_phy_quad_C_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_C), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_C_refclk_p), + .refclk_n(gth_quad_C_refclk_n), + .txn_0(gth_quad_C_txn_0), + .txp_0(gth_quad_C_txp_0), + .rxn_0(gth_quad_C_rxn_0), + .rxp_0(gth_quad_C_rxp_0), + .txn_1(gth_quad_C_txn_1), + .txp_1(gth_quad_C_txp_1), + .rxn_1(gth_quad_C_rxn_1), + .rxp_1(gth_quad_C_rxp_1), + .txn_2(gth_quad_C_txn_2), + .txp_2(gth_quad_C_txp_2), + .rxn_2(gth_quad_C_rxn_2), + .rxp_2(gth_quad_C_rxp_2), + .txn_3(gth_quad_C_txn_3), + .txp_3(gth_quad_C_txp_3), + .rxn_3(gth_quad_C_rxn_3), + .rxp_3(gth_quad_C_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_r8_txd), + .xgmii_txc_0(eth_r8_txc), + .xgmii_rxd_0(eth_r8_rxd), + .xgmii_rxc_0(eth_r8_rxc), + .xgmii_txd_1(eth_r9_txd), + .xgmii_txc_1(eth_r9_txc), + .xgmii_rxd_1(eth_r9_rxd), + .xgmii_rxc_1(eth_r9_rxc), + .xgmii_txd_2(eth_r11_txd), + .xgmii_txc_2(eth_r11_txc), + .xgmii_rxd_2(eth_r11_rxd), + .xgmii_rxc_2(eth_r11_rxc), + .xgmii_txd_3(eth_r10_txd), + .xgmii_txc_3(eth_r10_txc), + .xgmii_rxd_3(eth_r10_rxd), + .xgmii_rxc_3(eth_r10_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) +); + +// Quad D X1Y0 +eth_gth_phy_quad +eth_gth_phy_quad_D_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_D), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_D_refclk_p), + .refclk_n(gth_quad_D_refclk_n), + .txn_0(gth_quad_D_txn_0), + .txp_0(gth_quad_D_txp_0), + .rxn_0(gth_quad_D_rxn_0), + .rxp_0(gth_quad_D_rxp_0), + .txn_1(gth_quad_D_txn_1), + .txp_1(gth_quad_D_txp_1), + .rxn_1(gth_quad_D_rxn_1), + .rxp_1(gth_quad_D_rxp_1), + .txn_2(gth_quad_D_txn_2), + .txp_2(gth_quad_D_txp_2), + .rxn_2(gth_quad_D_rxn_2), + .rxp_2(gth_quad_D_rxp_2), + .txn_3(gth_quad_D_txn_3), + .txp_3(gth_quad_D_txp_3), + .rxn_3(gth_quad_D_rxn_3), + .rxp_3(gth_quad_D_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_l0_txd), + .xgmii_txc_0(eth_l0_txc), + .xgmii_rxd_0(eth_l0_rxd), + .xgmii_rxc_0(eth_l0_rxc), + .xgmii_txd_1(eth_l2_txd), + .xgmii_txc_1(eth_l2_txc), + .xgmii_rxd_1(eth_l2_rxd), + .xgmii_rxc_1(eth_l2_rxc), + .xgmii_txd_2(eth_l4_txd), + .xgmii_txc_2(eth_l4_txc), + .xgmii_rxd_2(eth_l4_rxd), + .xgmii_rxc_2(eth_l4_rxc), + .xgmii_txd_3(eth_l6_txd), + .xgmii_txc_3(eth_l6_txc), + .xgmii_rxd_3(eth_l6_rxd), + .xgmii_rxc_3(eth_l6_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) +); + +// Quad E X1Y1 +eth_gth_phy_quad +eth_gth_phy_quad_E_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_E), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_E_refclk_p), + .refclk_n(gth_quad_E_refclk_n), + .txn_0(gth_quad_E_txn_0), + .txp_0(gth_quad_E_txp_0), + .rxn_0(gth_quad_E_rxn_0), + .rxp_0(gth_quad_E_rxp_0), + .txn_1(gth_quad_E_txn_1), + .txp_1(gth_quad_E_txp_1), + .rxn_1(gth_quad_E_rxn_1), + .rxp_1(gth_quad_E_rxp_1), + .txn_2(gth_quad_E_txn_2), + .txp_2(gth_quad_E_txp_2), + .rxn_2(gth_quad_E_rxn_2), + .rxp_2(gth_quad_E_rxp_2), + .txn_3(gth_quad_E_txn_3), + .txp_3(gth_quad_E_txp_3), + .rxn_3(gth_quad_E_rxn_3), + .rxp_3(gth_quad_E_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_l3_txd), + .xgmii_txc_0(eth_l3_txc), + .xgmii_rxd_0(eth_l3_rxd), + .xgmii_rxc_0(eth_l3_rxc), + .xgmii_txd_1(eth_l5_txd), + .xgmii_txc_1(eth_l5_txc), + .xgmii_rxd_1(eth_l5_rxd), + .xgmii_rxc_1(eth_l5_rxc), + .xgmii_txd_2(eth_l1_txd), + .xgmii_txc_2(eth_l1_txc), + .xgmii_rxd_2(eth_l1_rxd), + .xgmii_rxc_2(eth_l1_rxc), + .xgmii_txd_3(eth_l7_txd), + .xgmii_txc_3(eth_l7_txc), + .xgmii_rxd_3(eth_l7_rxd), + .xgmii_rxc_3(eth_l7_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) +); + +// Quad F X1Y2 +eth_gth_phy_quad +eth_gth_phy_quad_F_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_F), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_F_refclk_p), + .refclk_n(gth_quad_F_refclk_n), + .txn_0(gth_quad_F_txn_0), + .txp_0(gth_quad_F_txp_0), + .rxn_0(gth_quad_F_rxn_0), + .rxp_0(gth_quad_F_rxp_0), + .txn_1(gth_quad_F_txn_1), + .txp_1(gth_quad_F_txp_1), + .rxn_1(gth_quad_F_rxn_1), + .rxp_1(gth_quad_F_rxp_1), + .txn_2(gth_quad_F_txn_2), + .txp_2(gth_quad_F_txp_2), + .rxn_2(gth_quad_F_rxn_2), + .rxp_2(gth_quad_F_rxp_2), + .txn_3(gth_quad_F_txn_3), + .txp_3(gth_quad_F_txp_3), + .rxn_3(gth_quad_F_rxn_3), + .rxp_3(gth_quad_F_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_l8_txd), + .xgmii_txc_0(eth_l8_txc), + .xgmii_rxd_0(eth_l8_rxd), + .xgmii_rxc_0(eth_l8_rxc), + .xgmii_txd_1(eth_l9_txd), + .xgmii_txc_1(eth_l9_txc), + .xgmii_rxd_1(eth_l9_rxd), + .xgmii_rxc_1(eth_l9_rxc), + .xgmii_txd_2(eth_l11_txd), + .xgmii_txc_2(eth_l11_txc), + .xgmii_rxd_2(eth_l11_rxd), + .xgmii_rxc_2(eth_l11_rxc), + .xgmii_txd_3(eth_l10_txd), + .xgmii_txc_3(eth_l10_txc), + .xgmii_rxd_3(eth_l10_rxd), + .xgmii_rxc_3(eth_l10_rxc), + + /* + * Control + */ + .tx_powerdown_0(1'b0), + .rx_powerdown_0(1'b0), + .tx_powerdown_1(1'b0), + .rx_powerdown_1(1'b0), + .tx_powerdown_2(1'b0), + .rx_powerdown_2(1'b0), + .tx_powerdown_3(1'b0), + .rx_powerdown_3(1'b0) +); + + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz), + .rst(rst_156mhz), + /* + * GPIO + */ + .sw(sw_int), + .jp(jp_int), + .led(led_int), + /* + * Silicon Labs CP2102 USB UART + */ + .uart_rst(uart_rst_int), + .uart_suspend(uart_suspend_int), + .uart_ri(uart_ri_int), + .uart_dcd(uart_dcd_int), + .uart_dtr(uart_dtr_int), + .uart_dsr(uart_dsr_int), + .uart_txd(uart_txd_int), + .uart_rxd(uart_rxd_int), + .uart_rts(uart_rts_int), + .uart_cts(uart_cts_int), + /* + * AirMax I/O + */ + .amh_right_mdc(amh_right_mdc_int), + .amh_right_mdio_i(amh_right_mdio_i_int), + .amh_right_mdio_o(amh_right_mdio_o_int), + .amh_right_mdio_t(amh_right_mdio_t_int), + .amh_left_mdc(amh_left_mdc_int), + .amh_left_mdio_i(amh_left_mdio_i_int), + .amh_left_mdio_o(amh_left_mdio_o_int), + .amh_left_mdio_t(amh_left_mdio_t_int), + /* + * 10G Ethernet XGMII + */ + .eth_r0_txd(eth_r0_txd), + .eth_r0_txc(eth_r0_txc), + .eth_r0_rxd(eth_r0_rxd), + .eth_r0_rxc(eth_r0_rxc), + .eth_r1_txd(eth_r1_txd), + .eth_r1_txc(eth_r1_txc), + .eth_r1_rxd(eth_r1_rxd), + .eth_r1_rxc(eth_r1_rxc), + .eth_r2_txd(eth_r2_txd), + .eth_r2_txc(eth_r2_txc), + .eth_r2_rxd(eth_r2_rxd), + .eth_r2_rxc(eth_r2_rxc), + .eth_r3_txd(eth_r3_txd), + .eth_r3_txc(eth_r3_txc), + .eth_r3_rxd(eth_r3_rxd), + .eth_r3_rxc(eth_r3_rxc), + .eth_r4_txd(eth_r4_txd), + .eth_r4_txc(eth_r4_txc), + .eth_r4_rxd(eth_r4_rxd), + .eth_r4_rxc(eth_r4_rxc), + .eth_r5_txd(eth_r5_txd), + .eth_r5_txc(eth_r5_txc), + .eth_r5_rxd(eth_r5_rxd), + .eth_r5_rxc(eth_r5_rxc), + .eth_r6_txd(eth_r6_txd), + .eth_r6_txc(eth_r6_txc), + .eth_r6_rxd(eth_r6_rxd), + .eth_r6_rxc(eth_r6_rxc), + .eth_r7_txd(eth_r7_txd), + .eth_r7_txc(eth_r7_txc), + .eth_r7_rxd(eth_r7_rxd), + .eth_r7_rxc(eth_r7_rxc), + .eth_r8_txd(eth_r8_txd), + .eth_r8_txc(eth_r8_txc), + .eth_r8_rxd(eth_r8_rxd), + .eth_r8_rxc(eth_r8_rxc), + .eth_r9_txd(eth_r9_txd), + .eth_r9_txc(eth_r9_txc), + .eth_r9_rxd(eth_r9_rxd), + .eth_r9_rxc(eth_r9_rxc), + .eth_r10_txd(eth_r10_txd), + .eth_r10_txc(eth_r10_txc), + .eth_r10_rxd(eth_r10_rxd), + .eth_r10_rxc(eth_r10_rxc), + .eth_r11_txd(eth_r11_txd), + .eth_r11_txc(eth_r11_txc), + .eth_r11_rxd(eth_r11_rxd), + .eth_r11_rxc(eth_r11_rxc), + .eth_l0_txd(eth_l0_txd), + .eth_l0_txc(eth_l0_txc), + .eth_l0_rxd(eth_l0_rxd), + .eth_l0_rxc(eth_l0_rxc), + .eth_l1_txd(eth_l1_txd), + .eth_l1_txc(eth_l1_txc), + .eth_l1_rxd(eth_l1_rxd), + .eth_l1_rxc(eth_l1_rxc), + .eth_l2_txd(eth_l2_txd), + .eth_l2_txc(eth_l2_txc), + .eth_l2_rxd(eth_l2_rxd), + .eth_l2_rxc(eth_l2_rxc), + .eth_l3_txd(eth_l3_txd), + .eth_l3_txc(eth_l3_txc), + .eth_l3_rxd(eth_l3_rxd), + .eth_l3_rxc(eth_l3_rxc), + .eth_l4_txd(eth_l4_txd), + .eth_l4_txc(eth_l4_txc), + .eth_l4_rxd(eth_l4_rxd), + .eth_l4_rxc(eth_l4_rxc), + .eth_l5_txd(eth_l5_txd), + .eth_l5_txc(eth_l5_txc), + .eth_l5_rxd(eth_l5_rxd), + .eth_l5_rxc(eth_l5_rxc), + .eth_l6_txd(eth_l6_txd), + .eth_l6_txc(eth_l6_txc), + .eth_l6_rxd(eth_l6_rxd), + .eth_l6_rxc(eth_l6_rxc), + .eth_l7_txd(eth_l7_txd), + .eth_l7_txc(eth_l7_txc), + .eth_l7_rxd(eth_l7_rxd), + .eth_l7_rxc(eth_l7_rxc), + .eth_l8_txd(eth_l8_txd), + .eth_l8_txc(eth_l8_txc), + .eth_l8_rxd(eth_l8_rxd), + .eth_l8_rxc(eth_l8_rxc), + .eth_l9_txd(eth_l9_txd), + .eth_l9_txc(eth_l9_txc), + .eth_l9_rxd(eth_l9_rxd), + .eth_l9_rxc(eth_l9_rxc), + .eth_l10_txd(eth_l10_txd), + .eth_l10_txc(eth_l10_txc), + .eth_l10_rxd(eth_l10_rxd), + .eth_l10_rxc(eth_l10_rxc), + .eth_l11_txd(eth_l11_txd), + .eth_l11_txc(eth_l11_txc), + .eth_l11_rxd(eth_l11_rxd), + .eth_l11_rxc(eth_l11_rxc) +); + +endmodule diff --git a/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v b/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v new file mode 100644 index 000000000..661271db5 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v @@ -0,0 +1,549 @@ +/* + +Copyright (c) 2016-2018 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 fpga_core +( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + /* + * GPIO + */ + input wire [1:0] sw, + input wire [3:0] jp, + output wire [3:0] led, + /* + * Silicon Labs CP2102 USB UART + */ + output wire uart_rst, + input wire uart_suspend, + output wire uart_ri, + output wire uart_dcd, + input wire uart_dtr, + output wire uart_dsr, + input wire uart_txd, + output wire uart_rxd, + input wire uart_rts, + output wire uart_cts, + /* + * AirMax I/O + */ + output wire amh_right_mdc, + input wire amh_right_mdio_i, + output wire amh_right_mdio_o, + output wire amh_right_mdio_t, + output wire amh_left_mdc, + input wire amh_left_mdio_i, + output wire amh_left_mdio_o, + output wire amh_left_mdio_t, + /* + * 10G Ethernet + */ + output wire [63:0] eth_r0_txd, + output wire [7:0] eth_r0_txc, + input wire [63:0] eth_r0_rxd, + input wire [7:0] eth_r0_rxc, + output wire [63:0] eth_r1_txd, + output wire [7:0] eth_r1_txc, + input wire [63:0] eth_r1_rxd, + input wire [7:0] eth_r1_rxc, + output wire [63:0] eth_r2_txd, + output wire [7:0] eth_r2_txc, + input wire [63:0] eth_r2_rxd, + input wire [7:0] eth_r2_rxc, + output wire [63:0] eth_r3_txd, + output wire [7:0] eth_r3_txc, + input wire [63:0] eth_r3_rxd, + input wire [7:0] eth_r3_rxc, + output wire [63:0] eth_r4_txd, + output wire [7:0] eth_r4_txc, + input wire [63:0] eth_r4_rxd, + input wire [7:0] eth_r4_rxc, + output wire [63:0] eth_r5_txd, + output wire [7:0] eth_r5_txc, + input wire [63:0] eth_r5_rxd, + input wire [7:0] eth_r5_rxc, + output wire [63:0] eth_r6_txd, + output wire [7:0] eth_r6_txc, + input wire [63:0] eth_r6_rxd, + input wire [7:0] eth_r6_rxc, + output wire [63:0] eth_r7_txd, + output wire [7:0] eth_r7_txc, + input wire [63:0] eth_r7_rxd, + input wire [7:0] eth_r7_rxc, + output wire [63:0] eth_r8_txd, + output wire [7:0] eth_r8_txc, + input wire [63:0] eth_r8_rxd, + input wire [7:0] eth_r8_rxc, + output wire [63:0] eth_r9_txd, + output wire [7:0] eth_r9_txc, + input wire [63:0] eth_r9_rxd, + input wire [7:0] eth_r9_rxc, + output wire [63:0] eth_r10_txd, + output wire [7:0] eth_r10_txc, + input wire [63:0] eth_r10_rxd, + input wire [7:0] eth_r10_rxc, + output wire [63:0] eth_r11_txd, + output wire [7:0] eth_r11_txc, + input wire [63:0] eth_r11_rxd, + input wire [7:0] eth_r11_rxc, + output wire [63:0] eth_l0_txd, + output wire [7:0] eth_l0_txc, + input wire [63:0] eth_l0_rxd, + input wire [7:0] eth_l0_rxc, + output wire [63:0] eth_l1_txd, + output wire [7:0] eth_l1_txc, + input wire [63:0] eth_l1_rxd, + input wire [7:0] eth_l1_rxc, + output wire [63:0] eth_l2_txd, + output wire [7:0] eth_l2_txc, + input wire [63:0] eth_l2_rxd, + input wire [7:0] eth_l2_rxc, + output wire [63:0] eth_l3_txd, + output wire [7:0] eth_l3_txc, + input wire [63:0] eth_l3_rxd, + input wire [7:0] eth_l3_rxc, + output wire [63:0] eth_l4_txd, + output wire [7:0] eth_l4_txc, + input wire [63:0] eth_l4_rxd, + input wire [7:0] eth_l4_rxc, + output wire [63:0] eth_l5_txd, + output wire [7:0] eth_l5_txc, + input wire [63:0] eth_l5_rxd, + input wire [7:0] eth_l5_rxc, + output wire [63:0] eth_l6_txd, + output wire [7:0] eth_l6_txc, + input wire [63:0] eth_l6_rxd, + input wire [7:0] eth_l6_rxc, + output wire [63:0] eth_l7_txd, + output wire [7:0] eth_l7_txc, + input wire [63:0] eth_l7_rxd, + input wire [7:0] eth_l7_rxc, + output wire [63:0] eth_l8_txd, + output wire [7:0] eth_l8_txc, + input wire [63:0] eth_l8_rxd, + input wire [7:0] eth_l8_rxc, + output wire [63:0] eth_l9_txd, + output wire [7:0] eth_l9_txc, + input wire [63:0] eth_l9_rxd, + input wire [7:0] eth_l9_rxc, + output wire [63:0] eth_l10_txd, + output wire [7:0] eth_l10_txc, + input wire [63:0] eth_l10_rxd, + input wire [7:0] eth_l10_rxc, + output wire [63:0] eth_l11_txd, + output wire [7:0] eth_l11_txc, + input wire [63:0] eth_l11_rxd, + input wire [7:0] eth_l11_rxc +); + +// UART +assign uart_rst = 1'b1; +assign uart_txd = 1'b1; + +// AirMax I/O +assign amh_right_mdc = 1'b1; +assign amh_right_mdio_o = 1'b1; +assign amh_right_mdio_t = 1'b1; +assign amh_left_mdc = 1'b1; +assign amh_left_mdio_o = 1'b1; +assign amh_left_mdio_t = 1'b1; + +assign eth_l8_txd = 64'h0707070707070707; +assign eth_l8_txc = 8'hff; +assign eth_l9_txd = 64'h0707070707070707; +assign eth_l9_txc = 8'hff; +assign eth_l10_txd = 64'h0707070707070707; +assign eth_l10_txc = 8'hff; +//assign eth_l11_txd = 64'h0707070707070707; +//assign eth_l11_txc = 8'hff; + +assign eth_r8_txd = 64'h0707070707070707; +assign eth_r8_txc = 8'hff; +assign eth_r9_txd = 64'h0707070707070707; +assign eth_r9_txc = 8'hff; +assign eth_r10_txd = 64'h0707070707070707; +assign eth_r10_txc = 8'hff; +assign eth_r11_txd = 64'h0707070707070707; +assign eth_r11_txc = 8'hff; + +reg [7:0] select_reg_0 = 0; +reg [7:0] select_reg_1 = 1; +reg [7:0] select_reg_2 = 2; +reg [7:0] select_reg_3 = 3; +reg [7:0] select_reg_4 = 4; +reg [7:0] select_reg_5 = 5; +reg [7:0] select_reg_6 = 6; +reg [7:0] select_reg_7 = 7; +reg [7:0] select_reg_8 = 8; +reg [7:0] select_reg_9 = 9; +reg [7:0] select_reg_10 = 10; +reg [7:0] select_reg_11 = 11; +reg [7:0] select_reg_12 = 12; +reg [7:0] select_reg_13 = 13; +reg [7:0] select_reg_14 = 14; +reg [7:0] select_reg_15 = 15; + + +axis_crosspoint_16x16 #( + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(8), + .LAST_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(0) +) +axis_crosspoint_inst ( + .clk(clk), + .rst(rst), + + .input_0_axis_tdata(eth_l0_rxd), + .input_0_axis_tkeep(eth_l0_rxc), + .input_0_axis_tvalid(1'b1), + .input_1_axis_tdata(eth_l1_rxd), + .input_1_axis_tkeep(eth_l1_rxc), + .input_1_axis_tvalid(1'b1), + .input_2_axis_tdata(eth_l2_rxd), + .input_2_axis_tkeep(eth_l2_rxc), + .input_2_axis_tvalid(1'b1), + .input_3_axis_tdata(eth_l3_rxd), + .input_3_axis_tkeep(eth_l3_rxc), + .input_3_axis_tvalid(1'b1), + .input_4_axis_tdata(eth_l4_rxd), + .input_4_axis_tkeep(eth_l4_rxc), + .input_4_axis_tvalid(1'b1), + .input_5_axis_tdata(eth_l5_rxd), + .input_5_axis_tkeep(eth_l5_rxc), + .input_5_axis_tvalid(1'b1), + .input_6_axis_tdata(eth_l6_rxd), + .input_6_axis_tkeep(eth_l6_rxc), + .input_6_axis_tvalid(1'b1), + .input_7_axis_tdata(eth_l7_rxd), + .input_7_axis_tkeep(eth_l7_rxc), + .input_7_axis_tvalid(1'b1), + .input_8_axis_tdata(eth_r0_rxd), + .input_8_axis_tkeep(eth_r0_rxc), + .input_8_axis_tvalid(1'b1), + .input_9_axis_tdata(eth_r1_rxd), + .input_9_axis_tkeep(eth_r1_rxc), + .input_9_axis_tvalid(1'b1), + .input_10_axis_tdata(eth_r2_rxd), + .input_10_axis_tkeep(eth_r2_rxc), + .input_10_axis_tvalid(1'b1), + .input_11_axis_tdata(eth_r3_rxd), + .input_11_axis_tkeep(eth_r3_rxc), + .input_11_axis_tvalid(1'b1), + .input_12_axis_tdata(eth_r4_rxd), + .input_12_axis_tkeep(eth_r4_rxc), + .input_12_axis_tvalid(1'b1), + .input_13_axis_tdata(eth_r5_rxd), + .input_13_axis_tkeep(eth_r5_rxc), + .input_13_axis_tvalid(1'b1), + .input_14_axis_tdata(eth_r6_rxd), + .input_14_axis_tkeep(eth_r6_rxc), + .input_14_axis_tvalid(1'b1), + .input_15_axis_tdata(eth_r7_rxd), + .input_15_axis_tkeep(eth_r7_rxc), + .input_15_axis_tvalid(1'b1), + + .output_0_axis_tdata(eth_l0_txd), + .output_0_axis_tkeep(eth_l0_txc), + .output_0_axis_tvalid(), + .output_1_axis_tdata(eth_l1_txd), + .output_1_axis_tkeep(eth_l1_txc), + .output_1_axis_tvalid(), + .output_2_axis_tdata(eth_l2_txd), + .output_2_axis_tkeep(eth_l2_txc), + .output_2_axis_tvalid(), + .output_3_axis_tdata(eth_l3_txd), + .output_3_axis_tkeep(eth_l3_txc), + .output_3_axis_tvalid(), + .output_4_axis_tdata(eth_l4_txd), + .output_4_axis_tkeep(eth_l4_txc), + .output_4_axis_tvalid(), + .output_5_axis_tdata(eth_l5_txd), + .output_5_axis_tkeep(eth_l5_txc), + .output_5_axis_tvalid(), + .output_6_axis_tdata(eth_l6_txd), + .output_6_axis_tkeep(eth_l6_txc), + .output_6_axis_tvalid(), + .output_7_axis_tdata(eth_l7_txd), + .output_7_axis_tkeep(eth_l7_txc), + .output_7_axis_tvalid(), + .output_8_axis_tdata(eth_r0_txd), + .output_8_axis_tkeep(eth_r0_txc), + .output_8_axis_tvalid(), + .output_9_axis_tdata(eth_r1_txd), + .output_9_axis_tkeep(eth_r1_txc), + .output_9_axis_tvalid(), + .output_10_axis_tdata(eth_r2_txd), + .output_10_axis_tkeep(eth_r2_txc), + .output_10_axis_tvalid(), + .output_11_axis_tdata(eth_r3_txd), + .output_11_axis_tkeep(eth_r3_txc), + .output_11_axis_tvalid(), + .output_12_axis_tdata(eth_r4_txd), + .output_12_axis_tkeep(eth_r4_txc), + .output_12_axis_tvalid(), + .output_13_axis_tdata(eth_r5_txd), + .output_13_axis_tkeep(eth_r5_txc), + .output_13_axis_tvalid(), + .output_14_axis_tdata(eth_r6_txd), + .output_14_axis_tkeep(eth_r6_txc), + .output_14_axis_tvalid(), + .output_15_axis_tdata(eth_r7_txd), + .output_15_axis_tkeep(eth_r7_txc), + .output_15_axis_tvalid(), + + .output_0_select(select_reg_0), + .output_1_select(select_reg_1), + .output_2_select(select_reg_2), + .output_3_select(select_reg_3), + .output_4_select(select_reg_4), + .output_5_select(select_reg_5), + .output_6_select(select_reg_6), + .output_7_select(select_reg_7), + .output_8_select(select_reg_8), + .output_9_select(select_reg_9), + .output_10_select(select_reg_10), + .output_11_select(select_reg_11), + .output_12_select(select_reg_12), + .output_13_select(select_reg_13), + .output_14_select(select_reg_14), + .output_15_select(select_reg_15) +); + +wire [63:0] eth_rx_axis_tdata; +wire [7:0] eth_rx_axis_tkeep; +wire eth_rx_axis_tvalid; +wire eth_rx_axis_tready; +wire eth_rx_axis_tlast; +wire eth_rx_axis_tuser; + +wire eth_rx_hdr_valid; +wire eth_rx_hdr_ready; +wire [47:0] eth_rx_dest_mac; +wire [47:0] eth_rx_src_mac; +wire [15:0] eth_rx_type; +wire [63:0] eth_rx_payload_tdata; +wire [7:0] eth_rx_payload_tkeep; +wire eth_rx_payload_tvalid; +wire eth_rx_payload_tready; +wire eth_rx_payload_tlast; +wire eth_rx_payload_tuser; + +eth_mac_10g_fifo #( + .ENABLE_PADDING(1), + .ENABLE_DIC(1), + .MIN_FRAME_LENGTH(64) +) +eth_mac_fifo_inst ( + .rx_clk(clk), + .rx_rst(rst), + .tx_clk(clk), + .tx_rst(rst), + .logic_clk(clk), + .logic_rst(rst), + .tx_axis_tdata(0), + .tx_axis_tkeep(0), + .tx_axis_tvalid(0), + .tx_axis_tready(), + .tx_axis_tlast(0), + .tx_axis_tuser(0), + .rx_axis_tdata(eth_rx_axis_tdata), + .rx_axis_tkeep(eth_rx_axis_tkeep), + .rx_axis_tvalid(eth_rx_axis_tvalid), + .rx_axis_tready(eth_rx_axis_tready), + .rx_axis_tlast(eth_rx_axis_tlast), + .rx_axis_tuser(eth_rx_axis_tuser), + .xgmii_rxd(eth_l11_rxd), + .xgmii_rxc(eth_l11_rxc), + .xgmii_txd(eth_l11_txd), + .xgmii_txc(eth_l11_txc), + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + .ifg_delay(12) +); + +eth_axis_rx_64 +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(eth_rx_axis_tdata), + .input_axis_tkeep(eth_rx_axis_tkeep), + .input_axis_tvalid(eth_rx_axis_tvalid), + .input_axis_tready(eth_rx_axis_tready), + .input_axis_tlast(eth_rx_axis_tlast), + .input_axis_tuser(eth_rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(eth_rx_hdr_valid), + .output_eth_hdr_ready(eth_rx_hdr_ready), + .output_eth_dest_mac(eth_rx_dest_mac), + .output_eth_src_mac(eth_rx_src_mac), + .output_eth_type(eth_rx_type), + .output_eth_payload_tdata(eth_rx_payload_tdata), + .output_eth_payload_tkeep(eth_rx_payload_tkeep), + .output_eth_payload_tvalid(eth_rx_payload_tvalid), + .output_eth_payload_tready(eth_rx_payload_tready), + .output_eth_payload_tlast(eth_rx_payload_tlast), + .output_eth_payload_tuser(eth_rx_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +// interpret config packet +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_WORD_0 = 3'd1, + STATE_WORD_1 = 3'd2, + STATE_WAIT = 3'd3; + +reg [2:0] state_reg = STATE_IDLE; + +reg eth_rx_hdr_ready_reg = 0; +reg eth_rx_payload_tready_reg = 0; + +assign eth_rx_hdr_ready = eth_rx_hdr_ready_reg; +assign eth_rx_payload_tready = eth_rx_payload_tready_reg; + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + eth_rx_hdr_ready_reg <= 0; + eth_rx_payload_tready_reg <= 0; + select_reg_0 <= 0; + select_reg_1 <= 1; + select_reg_2 <= 2; + select_reg_3 <= 3; + select_reg_4 <= 4; + select_reg_5 <= 5; + select_reg_6 <= 6; + select_reg_7 <= 7; + select_reg_8 <= 8; + select_reg_9 <= 9; + select_reg_10 <= 10; + select_reg_11 <= 11; + select_reg_12 <= 12; + select_reg_13 <= 13; + select_reg_14 <= 14; + select_reg_15 <= 15; + end else begin + case (state_reg) + STATE_IDLE: begin + eth_rx_hdr_ready_reg <= 1; + eth_rx_payload_tready_reg <= 0; + if (eth_rx_hdr_ready & eth_rx_hdr_valid) begin + if (eth_rx_type == 16'h8099) begin + state_reg <= STATE_WORD_0; + eth_rx_hdr_ready_reg <= 0; + eth_rx_payload_tready_reg <= 1; + end else begin + state_reg <= STATE_WAIT; + eth_rx_hdr_ready_reg <= 0; + eth_rx_payload_tready_reg <= 1; + end + end + end + STATE_WORD_0: begin + eth_rx_hdr_ready_reg <= 0; + eth_rx_payload_tready_reg <= 1; + if (eth_rx_payload_tready & eth_rx_payload_tvalid) begin + if (eth_rx_payload_tlast) begin + state_reg <= STATE_IDLE; + eth_rx_hdr_ready_reg <= 1; + eth_rx_payload_tready_reg <= 0; + end else begin + select_reg_0 <= eth_rx_payload_tdata[7:0]; + select_reg_1 <= eth_rx_payload_tdata[15:8]; + select_reg_2 <= eth_rx_payload_tdata[23:16]; + select_reg_3 <= eth_rx_payload_tdata[31:24]; + select_reg_4 <= eth_rx_payload_tdata[39:32]; + select_reg_5 <= eth_rx_payload_tdata[47:40]; + select_reg_6 <= eth_rx_payload_tdata[55:48]; + select_reg_7 <= eth_rx_payload_tdata[63:56]; + state_reg <= STATE_WORD_1; + eth_rx_hdr_ready_reg <= 0; + eth_rx_payload_tready_reg <= 1; + end + end + end + STATE_WORD_1: begin + eth_rx_hdr_ready_reg <= 0; + eth_rx_payload_tready_reg <= 1; + if (eth_rx_payload_tready & eth_rx_payload_tvalid) begin + if (eth_rx_payload_tlast) begin + state_reg <= STATE_IDLE; + eth_rx_hdr_ready_reg <= 1; + eth_rx_payload_tready_reg <= 0; + end else begin + select_reg_8 <= eth_rx_payload_tdata[7:0]; + select_reg_9 <= eth_rx_payload_tdata[15:8]; + select_reg_10 <= eth_rx_payload_tdata[23:16]; + select_reg_11 <= eth_rx_payload_tdata[31:24]; + select_reg_12 <= eth_rx_payload_tdata[39:32]; + select_reg_13 <= eth_rx_payload_tdata[47:40]; + select_reg_14 <= eth_rx_payload_tdata[55:48]; + select_reg_15 <= eth_rx_payload_tdata[63:56]; + state_reg <= STATE_WAIT; + eth_rx_hdr_ready_reg <= 0; + eth_rx_payload_tready_reg <= 1; + end + end + end + STATE_WAIT: begin + eth_rx_hdr_ready_reg <= 0; + eth_rx_payload_tready_reg <= 1; + if (eth_rx_payload_tready & eth_rx_payload_tvalid) begin + if (eth_rx_payload_tlast) begin + state_reg <= STATE_IDLE; + eth_rx_hdr_ready_reg <= 1; + eth_rx_payload_tready_reg <= 0; + end else begin + state_reg <= STATE_WAIT; + eth_rx_hdr_ready_reg <= 0; + eth_rx_payload_tready_reg <= 1; + end + end + end + endcase + end +end + +endmodule diff --git a/example/HXT100G/fpga_cxpt16/rtl/gth_i2c_init.v b/example/HXT100G/fpga_cxpt16/rtl/gth_i2c_init.v new file mode 100644 index 000000000..a8eff170a --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/rtl/gth_i2c_init.v @@ -0,0 +1,508 @@ +/* + +Copyright (c) 2015-2018 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 + +/* + * gth_i2c_init + */ +module gth_i2c_init ( + input wire clk, + input wire rst, + + /* + * I2C master interface + */ + output wire [6:0] cmd_address, + output wire cmd_start, + output wire cmd_read, + output wire cmd_write, + output wire cmd_write_multiple, + output wire cmd_stop, + output wire cmd_valid, + input wire cmd_ready, + + output wire [7:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + output wire data_out_last, + + /* + * Status + */ + output wire busy, + + /* + * Configuration + */ + input wire start +); + +/* + +Generic module for I2C bus initialization. Good for use when multiple devices +on an I2C bus must be initialized on system start without intervention of a +general-purpose processor. + +Copy this file and change init_data and INIT_DATA_LEN as needed. + +This module can be used in two modes: simple device initalization, or multiple +device initialization. In multiple device mode, the same initialization sequence +can be performed on multiple different device addresses. + +To use single device mode, only use the start write to address and write data commands. +The module will generate the I2C commands in sequential order. Terminate the list +with a 0 entry. + +To use the multiple device mode, use the start data and start address block commands +to set up lists of initialization data and device addresses. The module enters +multiple device mode upon seeing a start data block command. The module stores the +offset of the start of the data block and then skips ahead until it reaches a start +address block command. The module will store the offset to the address block and +read the first address in the block. Then it will jump back to the data block +and execute it, substituting the stored address for each current address write +command. Upon reaching the start address block command, the module will read out the +next address and start again at the top of the data block. If the module encounters +a start data block command while looking for an address, then it will store a new data +offset and then look for a start address block command. Terminate the list with a 0 +entry. Normal address commands will operate normally inside a data block. + +Commands: + +00 0000000 : stop +00 0000001 : exit multiple device mode +00 0000011 : start write to current address +00 0001000 : start address block +00 0001001 : start data block +01 aaaaaaa : start write to address +1 dddddddd : write 8-bit data + +Examples + +write 0x11223344 to register 0x0004 on device at 0x50 + +01 1010000 start write to 0x50 +1 00000000 write address 0x0004 +1 00000100 +1 00010001 write data 0x11223344 +1 00100010 +1 00110011 +1 01000100 +0 00000000 stop + +write 0x11223344 to register 0x0004 on devices at 0x50, 0x51, 0x52, and 0x53 + +00 0001001 start data block +00 0000011 start write to current address +1 00000100 +1 00010001 write data 0x11223344 +1 00100010 +1 00110011 +1 01000100 +00 0001000 start address block +01 1010000 address 0x50 +01 1010000 address 0x51 +01 1010000 address 0x52 +01 1010000 address 0x53 +00 0000000 stop + +*/ + +// init_data ROM +localparam INIT_DATA_LEN = 68; + +reg [8:0] init_data [INIT_DATA_LEN-1:0]; + +initial begin + // init clock mux registers + init_data[0] = {2'b00, 7'b0001001}; // start data block + init_data[1] = {2'b00, 7'b0000011}; // start write to current address + init_data[2] = {1'b1, 8'd2}; // select PLL bandwidth + //init_data[3] = {1'b1, 8'hA2}; + init_data[3] = {1'b1, 8'hA0}; + init_data[4] = {2'b00, 7'b0000011}; // start write to current address + init_data[5] = {1'b1, 8'd3}; // disable outputs during ICAL + //init_data[6] = {1'b1, 8'h15}; + init_data[6] = {1'b1, 8'h10}; + init_data[7] = {2'b00, 7'b0000011}; // start write to current address + init_data[8] = {1'b1, 8'd5}; // set CLKOUT1 and CLKOUT2 to LVPECL + init_data[9] = {1'b1, 8'hED}; + init_data[10] = {2'b00, 7'b0000011}; // start write to current address + init_data[11] = {1'b1, 8'd6}; // set CLKOUT3 to LVPECL and CLKOUT4 to LVDS + //init_data[12] = {1'b1, 8'h2D}; + init_data[12] = {1'b1, 8'h3D}; + init_data[13] = {2'b00, 7'b0000011}; // start write to current address + init_data[14] = {1'b1, 8'd7}; // set CLKOUT5 to to LVDS + //init_data[15] = {1'b1, 8'h0A}; + init_data[15] = {1'b1, 8'h3A}; + init_data[16] = {2'b00, 7'b0000011}; // start write to current address + init_data[17] = {1'b1, 8'd20}; // enable LOL output + init_data[18] = {1'b1, 8'h3E}; + init_data[19] = {2'b00, 7'b0000011}; // start write to current address + init_data[20] = {1'b1, 8'd25}; // N1_HS + init_data[21] = {1'b1, 8'h40}; + init_data[22] = {2'b00, 7'b0000011}; // start write to current address + init_data[23] = {1'b1, 8'd27}; // NC1_LS + init_data[24] = {1'b1, 8'h05}; + init_data[25] = {2'b00, 7'b0000011}; // start write to current address + init_data[26] = {1'b1, 8'd30}; // NC2_LS + init_data[27] = {1'b1, 8'h05}; + init_data[28] = {2'b00, 7'b0000011}; // start write to current address + init_data[29] = {1'b1, 8'd33}; // NC3_LS + init_data[30] = {1'b1, 8'h05}; + init_data[31] = {2'b00, 7'b0000011}; // start write to current address + init_data[32] = {1'b1, 8'd36}; // NC4_LS + init_data[33] = {1'b1, 8'h05}; + init_data[34] = {2'b00, 7'b0000011}; // start write to current address + init_data[35] = {1'b1, 8'd39}; // NC5_LS + init_data[36] = {1'b1, 8'h05}; + init_data[37] = {2'b00, 7'b0000011}; // start write to current address + init_data[38] = {1'b1, 8'd40}; // N2_HS + init_data[39] = {1'b1, 8'hA0}; + init_data[40] = {2'b00, 7'b0000011}; // start write to current address + init_data[41] = {1'b1, 8'd41}; // N2_LS + init_data[42] = {1'b1, 8'h01}; + init_data[43] = {2'b00, 7'b0000011}; // start write to current address + init_data[44] = {1'b1, 8'd42}; // N2_LS + init_data[45] = {1'b1, 8'h3B}; + init_data[46] = {2'b00, 7'b0000011}; // start write to current address + init_data[47] = {1'b1, 8'd45}; // N31 + init_data[48] = {1'b1, 8'h4E}; + init_data[49] = {2'b00, 7'b0000011}; // start write to current address + init_data[50] = {1'b1, 8'd48}; // N32 + init_data[51] = {1'b1, 8'h4E}; + init_data[52] = {2'b00, 7'b0000011}; // start write to current address + init_data[53] = {1'b1, 8'd51}; // N33 + init_data[54] = {1'b1, 8'h4E}; + init_data[55] = {2'b00, 7'b0000011}; // start write to current address + init_data[56] = {1'b1, 8'd54}; // N34 + init_data[57] = {1'b1, 8'h4E}; + init_data[58] = {2'b00, 7'b0000011}; // start write to current address + init_data[59] = {1'b1, 8'd141}; // Zero independent skew + init_data[60] = {1'b1, 8'h00}; + init_data[61] = {2'b00, 7'b0000011}; // start write to current address + init_data[62] = {1'b1, 8'd136}; // Soft reset + init_data[63] = {1'b1, 8'h40}; + init_data[64] = {2'b00, 7'b0001000}; // start address block + init_data[65] = {2'b01, 7'b1101001}; // first clock mux + init_data[66] = {2'b01, 7'b1101000}; // second clock mux + init_data[67] = 9'd0; // stop +end + +localparam [3:0] + STATE_IDLE = 3'd0, + STATE_RUN = 3'd1, + STATE_TABLE_1 = 3'd2, + STATE_TABLE_2 = 3'd3, + STATE_TABLE_3 = 3'd4; + +reg [4:0] state_reg = STATE_IDLE, state_next; + +parameter AW = $clog2(INIT_DATA_LEN); + +reg [8:0] init_data_reg = 9'd0; + +reg [AW-1:0] address_reg = {AW{1'b0}}, address_next; +reg [AW-1:0] address_ptr_reg = {AW{1'b0}}, address_ptr_next; +reg [AW-1:0] data_ptr_reg = {AW{1'b0}}, data_ptr_next; + +reg [6:0] cur_address_reg = 7'd0, cur_address_next; + +reg [6:0] cmd_address_reg = 7'd0, cmd_address_next; +reg cmd_start_reg = 1'b0, cmd_start_next; +reg cmd_write_reg = 1'b0, cmd_write_next; +reg cmd_stop_reg = 1'b0, cmd_stop_next; +reg cmd_valid_reg = 1'b0, cmd_valid_next; + +reg [7:0] data_out_reg = 8'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; + +reg start_flag_reg = 1'b0, start_flag_next; + +reg busy_reg = 1'b0; + +assign cmd_address = cmd_address_reg; +assign cmd_start = cmd_start_reg; +assign cmd_read = 1'b0; +assign cmd_write = cmd_write_reg; +assign cmd_write_multiple = 1'b0; +assign cmd_stop = cmd_stop_reg; +assign cmd_valid = cmd_valid_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; +assign data_out_last = 1'b1; + +assign busy = busy_reg; + +always @* begin + state_next = STATE_IDLE; + + address_next = address_reg; + address_ptr_next = address_ptr_reg; + data_ptr_next = data_ptr_reg; + + cur_address_next = cur_address_reg; + + cmd_address_next = cmd_address_reg; + cmd_start_next = cmd_start_reg & ~(cmd_valid & cmd_ready); + cmd_write_next = cmd_write_reg & ~(cmd_valid & cmd_ready); + cmd_stop_next = cmd_stop_reg & ~(cmd_valid & cmd_ready); + cmd_valid_next = cmd_valid_reg & ~cmd_ready; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + + start_flag_next = start_flag_reg; + + if (cmd_valid | data_out_valid) begin + // wait for output registers to clear + state_next = state_reg; + end else begin + case (state_reg) + STATE_IDLE: begin + // wait for start signal + if (~start_flag_reg & start) begin + address_next = {AW{1'b0}}; + start_flag_next = 1'b1; + state_next = STATE_RUN; + end else begin + state_next = STATE_IDLE; + end + end + STATE_RUN: begin + // process commands + if (init_data_reg[8] == 1'b1) begin + // write data + cmd_write_next = 1'b1; + cmd_stop_next = 1'b0; + cmd_valid_next = 1'b1; + + data_out_next = init_data_reg[7:0]; + data_out_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg[8:7] == 2'b01) begin + // write address + cmd_address_next = init_data_reg[6:0]; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_RUN; + end + end + STATE_TABLE_1: begin + // find address table start + if (init_data_reg == 9'b000001000) begin + // address table start + address_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_2; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end + end + STATE_TABLE_2: begin + // find next address + if (init_data_reg[8:7] == 2'b01) begin + // write address command + // store address and move to data table + cur_address_next = init_data_reg[6:0]; + address_ptr_next = address_reg + 1; + address_next = data_ptr_reg; + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'd1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_2; + end + end + STATE_TABLE_3: begin + // process data table with selected address + if (init_data_reg[8] == 1'b1) begin + // write data + cmd_write_next = 1'b1; + cmd_stop_next = 1'b0; + cmd_valid_next = 1'b1; + + data_out_next = init_data_reg[7:0]; + data_out_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg[8:7] == 2'b01) begin + // write address + cmd_address_next = init_data_reg[6:0]; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000000011) begin + // write current address + cmd_address_next = cur_address_reg; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'b000001000) begin + // address table start + address_next = address_ptr_reg; + state_next = STATE_TABLE_2; + end else if (init_data_reg == 9'd1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_3; + end + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + init_data_reg <= 9'd0; + + address_reg <= {AW{1'b0}}; + address_ptr_reg <= {AW{1'b0}}; + data_ptr_reg <= {AW{1'b0}}; + + cur_address_reg <= 7'd0; + + cmd_valid_reg <= 1'b0; + + data_out_valid_reg <= 1'b0; + + start_flag_reg <= 1'b0; + + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + + // read init_data ROM + init_data_reg <= init_data[address_next]; + + address_reg <= address_next; + address_ptr_reg <= address_ptr_next; + data_ptr_reg <= data_ptr_next; + + cur_address_reg <= cur_address_next; + + cmd_valid_reg <= cmd_valid_next; + + data_out_valid_reg <= data_out_valid_next; + + start_flag_reg <= start & start_flag_next; + + busy_reg <= (state_reg != STATE_IDLE); + end + + cmd_address_reg <= cmd_address_next; + cmd_start_reg <= cmd_start_next; + cmd_write_reg <= cmd_write_next; + cmd_stop_reg <= cmd_stop_next; + + data_out_reg <= data_out_next; +end + +endmodule diff --git a/example/HXT100G/fpga_cxpt16/rtl/i2c_master.v b/example/HXT100G/fpga_cxpt16/rtl/i2c_master.v new file mode 100644 index 000000000..95d3a5212 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/rtl/i2c_master.v @@ -0,0 +1,895 @@ +/* + +Copyright (c) 2015-2018 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 + +/* + * I2C master + */ +module i2c_master ( + input wire clk, + input wire rst, + + /* + * Host interface + */ + input wire [6:0] cmd_address, + input wire cmd_start, + input wire cmd_read, + input wire cmd_write, + input wire cmd_write_multiple, + input wire cmd_stop, + input wire cmd_valid, + output wire cmd_ready, + + input wire [7:0] data_in, + input wire data_in_valid, + output wire data_in_ready, + input wire data_in_last, + + output wire [7:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + output wire data_out_last, + + /* + * I2C interface + */ + input wire scl_i, + output wire scl_o, + output wire scl_t, + input wire sda_i, + output wire sda_o, + output wire sda_t, + + /* + * Status + */ + output wire busy, + output wire bus_control, + output wire bus_active, + output wire missed_ack, + + /* + * Configuration + */ + input wire [15:0] prescale, + input wire stop_on_idle +); + +/* + +I2C + +Read + __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ +sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_\_R___A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A____/ + ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ +scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP + +Write + __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ +sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_/_W_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_/_N_\__/ + ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ +scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP + +Commands: + +read + read data byte + set start to force generation of a start condition + start is implied when bus is inactive or active with write or different address + set stop to issue a stop condition after reading current byte + if stop is set with read command, then data_out_last will be set + +write + write data byte + set start to force generation of a start condition + start is implied when bus is inactive or active with read or different address + set stop to issue a stop condition after writing current byte + +write multiple + write multiple data bytes (until data_in_last) + set start to force generation of a start condition + start is implied when bus is inactive or active with read or different address + set stop to issue a stop condition after writing block + +stop + issue stop condition if bus is active + +Status: + +busy + module is communicating over the bus + +bus_control + module has control of bus in active state + +bus_active + bus is active, not necessarily controlled by this module + +missed_ack + strobed when a slave ack is missed + +Parameters: + +prescale + set prescale to 1/4 of the minimum clock period in units + of input clk cycles (prescale = Fclk / (FI2Cclk * 4)) + +stop_on_idle + automatically issue stop when command input is not valid + +Example of interfacing with tristate pins: +(this will work for any tristate bus) + +assign scl_i = scl_pin; +assign scl_pin = scl_t ? 1'bz : scl_o; +assign sda_i = sda_pin; +assign sda_pin = sda_t ? 1'bz : sda_o; + +Equivalent code that does not use *_t connections: +(we can get away with this because I2C is open-drain) + +assign scl_i = scl_pin; +assign scl_pin = scl_o ? 1'bz : 1'b0; +assign sda_i = sda_pin; +assign sda_pin = sda_o ? 1'bz : 1'b0; + +Example of two interconnected I2C devices: + +assign scl_1_i = scl_1_o & scl_2_o; +assign scl_2_i = scl_1_o & scl_2_o; +assign sda_1_i = sda_1_o & sda_2_o; +assign sda_2_i = sda_1_o & sda_2_o; + +Example of two I2C devices sharing the same pins: + +assign scl_1_i = scl_pin; +assign scl_2_i = scl_pin; +assign scl_pin = (scl_1_o & scl_2_o) ? 1'bz : 1'b0; +assign sda_1_i = sda_pin; +assign sda_2_i = sda_pin; +assign sda_pin = (sda_1_o & sda_2_o) ? 1'bz : 1'b0; + +Notes: + +scl_o should not be connected directly to scl_i, only via AND logic or a tristate +I/O pin. This would prevent devices from stretching the clock period. + +*/ + +localparam [4:0] + STATE_IDLE = 4'd0, + STATE_ACTIVE_WRITE = 4'd1, + STATE_ACTIVE_READ = 4'd2, + STATE_START_WAIT = 4'd3, + STATE_START = 4'd4, + STATE_ADDRESS_1 = 4'd5, + STATE_ADDRESS_2 = 4'd6, + STATE_WRITE_1 = 4'd7, + STATE_WRITE_2 = 4'd8, + STATE_WRITE_3 = 4'd9, + STATE_READ = 4'd10, + STATE_STOP = 4'd11; + +reg [4:0] state_reg = STATE_IDLE, state_next; + +localparam [4:0] + PHY_STATE_IDLE = 5'd0, + PHY_STATE_ACTIVE = 5'd1, + PHY_STATE_REPEATED_START_1 = 5'd2, + PHY_STATE_REPEATED_START_2 = 5'd3, + PHY_STATE_START_1 = 5'd4, + PHY_STATE_START_2 = 5'd5, + PHY_STATE_WRITE_BIT_1 = 5'd6, + PHY_STATE_WRITE_BIT_2 = 5'd7, + PHY_STATE_WRITE_BIT_3 = 5'd8, + PHY_STATE_READ_BIT_1 = 5'd9, + PHY_STATE_READ_BIT_2 = 5'd10, + PHY_STATE_READ_BIT_3 = 5'd11, + PHY_STATE_READ_BIT_4 = 5'd12, + PHY_STATE_STOP_1 = 5'd13, + PHY_STATE_STOP_2 = 5'd14, + PHY_STATE_STOP_3 = 5'd15; + +reg [4:0] phy_state_reg = STATE_IDLE, phy_state_next; + +reg phy_start_bit; +reg phy_stop_bit; +reg phy_write_bit; +reg phy_read_bit; +reg phy_release_bus; + +reg phy_tx_data; + +reg phy_rx_data_reg = 1'b0, phy_rx_data_next; + +reg [6:0] addr_reg = 7'd0, addr_next; +reg [7:0] data_reg = 8'd0, data_next; +reg last_reg = 1'b0, last_next; + +reg mode_read_reg = 1'b0, mode_read_next; +reg mode_write_multiple_reg = 1'b0, mode_write_multiple_next; +reg mode_stop_reg = 1'b0, mode_stop_next; + +reg [16:0] delay_reg = 16'd0, delay_next; +reg delay_scl_reg = 1'b0, delay_scl_next; +reg delay_sda_reg = 1'b0, delay_sda_next; + +reg [3:0] bit_count_reg = 4'd0, bit_count_next; + +reg cmd_ready_reg = 1'b0, cmd_ready_next; + +reg data_in_ready_reg = 1'b0, data_in_ready_next; + +reg [7:0] data_out_reg = 8'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; +reg data_out_last_reg = 1'b0, data_out_last_next; + +reg scl_i_reg = 1'b1; +reg sda_i_reg = 1'b1; + +reg scl_o_reg = 1'b1, scl_o_next; +reg sda_o_reg = 1'b1, sda_o_next; + +reg last_scl_i_reg = 1'b1; +reg last_sda_i_reg = 1'b1; + +reg busy_reg = 1'b0; +reg bus_active_reg = 1'b0; +reg bus_control_reg = 1'b0, bus_control_next; +reg missed_ack_reg = 1'b0, missed_ack_next; + +assign cmd_ready = cmd_ready_reg; + +assign data_in_ready = data_in_ready_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; +assign data_out_last = data_out_last_reg; + +assign scl_o = scl_o_reg; +assign scl_t = scl_o_reg; +assign sda_o = sda_o_reg; +assign sda_t = sda_o_reg; + +assign busy = busy_reg; +assign bus_active = bus_active_reg; +assign bus_control = bus_control_reg; +assign missed_ack = missed_ack_reg; + +wire scl_posedge = scl_i_reg & ~last_scl_i_reg; +wire scl_negedge = ~scl_i_reg & last_scl_i_reg; +wire sda_posedge = sda_i_reg & ~last_sda_i_reg; +wire sda_negedge = ~sda_i_reg & last_sda_i_reg; + +wire start_bit = sda_negedge & scl_i_reg; +wire stop_bit = sda_posedge & scl_i_reg; + +always @* begin + state_next = STATE_IDLE; + + phy_start_bit = 1'b0; + phy_stop_bit = 1'b0; + phy_write_bit = 1'b0; + phy_read_bit = 1'b0; + phy_tx_data = 1'b0; + phy_release_bus = 1'b0; + + addr_next = addr_reg; + data_next = data_reg; + last_next = last_reg; + + mode_read_next = mode_read_reg; + mode_write_multiple_next = mode_write_multiple_reg; + mode_stop_next = mode_stop_reg; + + bit_count_next = bit_count_reg; + + cmd_ready_next = 1'b0; + + data_in_ready_next = 1'b0; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + data_out_last_next = data_out_last_reg; + + missed_ack_next = 1'b0; + + // generate delays + if (phy_state_reg != PHY_STATE_IDLE && phy_state_reg != PHY_STATE_ACTIVE) begin + // wait for phy operation + state_next = state_reg; + end else begin + // process states + case (state_reg) + STATE_IDLE: begin + // line idle + cmd_ready_next = 1'b1; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + // start bit + if (bus_active) begin + state_next = STATE_START_WAIT; + end else begin + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + end else begin + // invalid or unspecified - ignore + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_ACTIVE_WRITE: begin + // line active with current address and read/write mode + cmd_ready_next = 1'b1; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + if (cmd_start || cmd_address != addr_reg || cmd_read) begin + // address or mode mismatch or forced start - repeated start + + // repeated start bit + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end else begin + // address and mode match + + // start write + data_in_ready_next = 1'b1; + state_next = STATE_WRITE_1; + end + end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin + // stop command + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + // invalid or unspecified - ignore + state_next = STATE_ACTIVE_WRITE; + end + end else begin + if (stop_on_idle & cmd_ready & ~cmd_valid) begin + // no waiting command and stop_on_idle selected, issue stop condition + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + state_next = STATE_ACTIVE_WRITE; + end + end + end + STATE_ACTIVE_READ: begin + // line active to current address + cmd_ready_next = ~data_out_valid; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + if (cmd_start || cmd_address != addr_reg || cmd_write) begin + // address or mode mismatch or forced start - repeated start + + // write nack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // repeated start bit + state_next = STATE_START; + end else begin + // address and mode match + + // write ack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b0; + // start next read + bit_count_next = 4'd8; + data_next = 8'd0; + state_next = STATE_READ; + end + end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin + // stop command + // write nack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // send stop bit + state_next = STATE_STOP; + end else begin + // invalid or unspecified - ignore + state_next = STATE_ACTIVE_READ; + end + end else begin + if (stop_on_idle & cmd_ready & ~cmd_valid) begin + // no waiting command and stop_on_idle selected, issue stop condition + // write ack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // send stop bit + state_next = STATE_STOP; + end else begin + state_next = STATE_ACTIVE_READ; + end + end + end + STATE_START_WAIT: begin + // wait for bus idle + + if (bus_active) begin + state_next = STATE_START_WAIT; + end else begin + // bus is idle, take control + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + end + STATE_START: begin + // send start bit + + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + STATE_ADDRESS_1: begin + // send address + bit_count_next = bit_count_reg - 1; + if (bit_count_reg > 1) begin + // send address + phy_write_bit = 1'b1; + phy_tx_data = addr_reg[bit_count_reg-2]; + state_next = STATE_ADDRESS_1; + end else if (bit_count_reg > 0) begin + // send read/write bit + phy_write_bit = 1'b1; + phy_tx_data = mode_read_reg; + state_next = STATE_ADDRESS_1; + end else begin + // read ack bit + phy_read_bit = 1'b1; + state_next = STATE_ADDRESS_2; + end + end + STATE_ADDRESS_2: begin + // read ack bit + missed_ack_next = phy_rx_data_reg; + + if (mode_read_reg) begin + // start read + bit_count_next = 4'd8; + data_next = 1'b0; + state_next = STATE_READ; + end else begin + // start write + data_in_ready_next = 1'b1; + state_next = STATE_WRITE_1; + end + end + STATE_WRITE_1: begin + data_in_ready_next = 1'b1; + + if (data_in_ready & data_in_valid) begin + // got data, start write + data_next = data_in; + last_next = data_in_last; + bit_count_next = 4'd8; + data_in_ready_next = 1'b0; + state_next = STATE_WRITE_2; + end else begin + // wait for data + state_next = STATE_WRITE_1; + end + end + STATE_WRITE_2: begin + // send data + bit_count_next = bit_count_reg - 1; + if (bit_count_reg > 0) begin + // write data bit + phy_write_bit = 1'b1; + phy_tx_data = data_reg[bit_count_reg-1]; + state_next = STATE_WRITE_2; + end else begin + // read ack bit + phy_read_bit = 1'b1; + state_next = STATE_WRITE_3; + end + end + STATE_WRITE_3: begin + // read ack bit + missed_ack_next = phy_rx_data_reg; + + if (mode_write_multiple_reg && !last_reg) begin + // more to write + state_next = STATE_WRITE_1; + end else if (mode_stop_reg) begin + // last cycle and stop selected + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + // otherwise, return to bus active state + state_next = STATE_ACTIVE_WRITE; + end + end + STATE_READ: begin + // read data + + bit_count_next = bit_count_reg - 1; + data_next = {data_reg[6:0], phy_rx_data_reg}; + if (bit_count_reg > 0) begin + // read next bit + phy_read_bit = 1'b1; + state_next = STATE_READ; + end else begin + // output data word + data_out_next = data_next; + data_out_valid_next = 1'b1; + data_out_last_next = 1'b0; + if (mode_stop_reg) begin + // send nack and stop + data_out_last_next = 1'b1; + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + state_next = STATE_STOP; + end else begin + // return to bus active state + state_next = STATE_ACTIVE_READ; + end + end + end + STATE_STOP: begin + // send stop bit + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end + endcase + end +end + +always @* begin + phy_state_next = PHY_STATE_IDLE; + + phy_rx_data_next = phy_rx_data_reg; + + delay_next = delay_reg; + delay_scl_next = delay_scl_reg; + delay_sda_next = delay_sda_reg; + + scl_o_next = scl_o_reg; + sda_o_next = sda_o_reg; + + bus_control_next = bus_control_reg; + + if (phy_release_bus) begin + // release bus and return to idle state + sda_o_next = 1'b1; + scl_o_next = 1'b1; + delay_scl_next = 1'b0; + delay_sda_next = 1'b0; + delay_next = 1'b0; + phy_state_next = PHY_STATE_IDLE; + end else if (delay_scl_reg) begin + // wait for SCL to match command + delay_scl_next = scl_o_reg & ~scl_i_reg; + phy_state_next = phy_state_reg; + end else if (delay_sda_reg) begin + // wait for SDA to match command + delay_sda_next = sda_o_reg & ~sda_i_reg; + phy_state_next = phy_state_reg; + end else if (delay_reg > 0) begin + // time delay + delay_next = delay_reg - 1; + phy_state_next = phy_state_reg; + end else begin + case (phy_state_reg) + PHY_STATE_IDLE: begin + // bus idle - wait for start command + sda_o_next = 1'b1; + scl_o_next = 1'b1; + if (phy_start_bit) begin + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_1; + end else begin + phy_state_next = PHY_STATE_IDLE; + end + end + PHY_STATE_ACTIVE: begin + // bus active + if (phy_start_bit) begin + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_REPEATED_START_1; + end else if (phy_write_bit) begin + sda_o_next = phy_tx_data; + delay_next = prescale; + phy_state_next = PHY_STATE_WRITE_BIT_1; + end else if (phy_read_bit) begin + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_1; + end else if (phy_stop_bit) begin + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_1; + end else begin + phy_state_next = PHY_STATE_ACTIVE; + end + end + PHY_STATE_REPEATED_START_1: begin + // generate repeated start bit + // ______ + // sda XXX/ \_______ + // _______ + // scl ______/ \___ + // + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_REPEATED_START_2; + end + PHY_STATE_REPEATED_START_2: begin + // generate repeated start bit + // ______ + // sda XXX/ \_______ + // _______ + // scl ______/ \___ + // + + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_1; + end + PHY_STATE_START_1: begin + // generate start bit + // ___ + // sda \_______ + // _______ + // scl \___ + // + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_2; + end + PHY_STATE_START_2: begin + // generate start bit + // ___ + // sda \_______ + // _______ + // scl \___ + // + + bus_control_next = 1'b1; + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_WRITE_BIT_1: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale << 1; + phy_state_next = PHY_STATE_WRITE_BIT_2; + end + PHY_STATE_WRITE_BIT_2: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_WRITE_BIT_3; + end + PHY_STATE_WRITE_BIT_3: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_READ_BIT_1: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_2; + end + PHY_STATE_READ_BIT_2: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_rx_data_next = sda_i_reg; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_3; + end + PHY_STATE_READ_BIT_3: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_4; + end + PHY_STATE_READ_BIT_4: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_STOP_1: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_2; + end + PHY_STATE_STOP_2: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_3; + end + PHY_STATE_STOP_3: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + bus_control_next = 1'b0; + phy_state_next = PHY_STATE_IDLE; + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + phy_state_reg <= PHY_STATE_IDLE; + delay_reg <= 16'd0; + delay_scl_reg <= 1'b0; + delay_sda_reg <= 1'b0; + cmd_ready_reg <= 1'b0; + data_in_ready_reg <= 1'b0; + data_out_valid_reg <= 1'b0; + scl_o_reg <= 1'b1; + sda_o_reg <= 1'b1; + busy_reg <= 1'b0; + bus_active_reg <= 1'b0; + bus_control_reg <= 1'b0; + missed_ack_reg <= 1'b0; + end else begin + state_reg <= state_next; + phy_state_reg <= phy_state_next; + + delay_reg <= delay_next; + delay_scl_reg <= delay_scl_next; + delay_sda_reg <= delay_sda_next; + + cmd_ready_reg <= cmd_ready_next; + data_in_ready_reg <= data_in_ready_next; + data_out_valid_reg <= data_out_valid_next; + + scl_o_reg <= scl_o_next; + sda_o_reg <= sda_o_next; + + busy_reg <= !(state_reg == STATE_IDLE || state_reg == STATE_ACTIVE_WRITE || state_reg == STATE_ACTIVE_READ); + + if (start_bit) begin + bus_active_reg <= 1'b1; + end else if (stop_bit) begin + bus_active_reg <= 1'b0; + end else begin + bus_active_reg <= bus_active_reg; + end + + bus_control_reg <= bus_control_next; + missed_ack_reg <= missed_ack_next; + end + + phy_rx_data_reg <= phy_rx_data_next; + + addr_reg <= addr_next; + data_reg <= data_next; + last_reg <= last_next; + + mode_read_reg <= mode_read_next; + mode_write_multiple_reg <= mode_write_multiple_next; + mode_stop_reg <= mode_stop_next; + + bit_count_reg <= bit_count_next; + + data_out_reg <= data_out_next; + data_out_last_reg <= data_out_last_next; + + scl_i_reg <= scl_i; + sda_i_reg <= sda_i; + last_scl_i_reg <= scl_i_reg; + last_sda_i_reg <= sda_i_reg; +end + +endmodule diff --git a/example/HXT100G/fpga_cxpt16/rtl/sync_reset.v b/example/HXT100G/fpga_cxpt16/rtl/sync_reset.v new file mode 100644 index 000000000..fe097029f --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/HXT100G/fpga_cxpt16/rtl/sync_signal.v b/example/HXT100G/fpga_cxpt16/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/HXT100G/fpga_cxpt16/tb/axis_ep.py b/example/HXT100G/fpga_cxpt16/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga_cxpt16/tb/eth_ep.py b/example/HXT100G/fpga_cxpt16/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py b/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py new file mode 100755 index 000000000..98b826015 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py @@ -0,0 +1,551 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016-2018 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 + +import eth_ep +import xgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_crosspoint_16x16.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + sw = Signal(intbv(0)[2:]) + jp = Signal(intbv(0)[4:]) + uart_suspend = Signal(bool(0)) + uart_dtr = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + amh_right_mdio_i = Signal(bool(0)) + amh_left_mdio_i = Signal(bool(0)) + eth_r0_rxd = Signal(intbv(0)[64:]) + eth_r0_rxc = Signal(intbv(0)[8:]) + eth_r1_rxd = Signal(intbv(0)[64:]) + eth_r1_rxc = Signal(intbv(0)[8:]) + eth_r2_rxd = Signal(intbv(0)[64:]) + eth_r2_rxc = Signal(intbv(0)[8:]) + eth_r3_rxd = Signal(intbv(0)[64:]) + eth_r3_rxc = Signal(intbv(0)[8:]) + eth_r4_rxd = Signal(intbv(0)[64:]) + eth_r4_rxc = Signal(intbv(0)[8:]) + eth_r5_rxd = Signal(intbv(0)[64:]) + eth_r5_rxc = Signal(intbv(0)[8:]) + eth_r6_rxd = Signal(intbv(0)[64:]) + eth_r6_rxc = Signal(intbv(0)[8:]) + eth_r7_rxd = Signal(intbv(0)[64:]) + eth_r7_rxc = Signal(intbv(0)[8:]) + eth_r8_rxd = Signal(intbv(0)[64:]) + eth_r8_rxc = Signal(intbv(0)[8:]) + eth_r9_rxd = Signal(intbv(0)[64:]) + eth_r9_rxc = Signal(intbv(0)[8:]) + eth_r10_rxd = Signal(intbv(0)[64:]) + eth_r10_rxc = Signal(intbv(0)[8:]) + eth_r11_rxd = Signal(intbv(0)[64:]) + eth_r11_rxc = Signal(intbv(0)[8:]) + eth_l0_rxd = Signal(intbv(0)[64:]) + eth_l0_rxc = Signal(intbv(0)[8:]) + eth_l1_rxd = Signal(intbv(0)[64:]) + eth_l1_rxc = Signal(intbv(0)[8:]) + eth_l2_rxd = Signal(intbv(0)[64:]) + eth_l2_rxc = Signal(intbv(0)[8:]) + eth_l3_rxd = Signal(intbv(0)[64:]) + eth_l3_rxc = Signal(intbv(0)[8:]) + eth_l4_rxd = Signal(intbv(0)[64:]) + eth_l4_rxc = Signal(intbv(0)[8:]) + eth_l5_rxd = Signal(intbv(0)[64:]) + eth_l5_rxc = Signal(intbv(0)[8:]) + eth_l6_rxd = Signal(intbv(0)[64:]) + eth_l6_rxc = Signal(intbv(0)[8:]) + eth_l7_rxd = Signal(intbv(0)[64:]) + eth_l7_rxc = Signal(intbv(0)[8:]) + eth_l8_rxd = Signal(intbv(0)[64:]) + eth_l8_rxc = Signal(intbv(0)[8:]) + eth_l9_rxd = Signal(intbv(0)[64:]) + eth_l9_rxc = Signal(intbv(0)[8:]) + eth_l10_rxd = Signal(intbv(0)[64:]) + eth_l10_rxc = Signal(intbv(0)[8:]) + eth_l11_rxd = Signal(intbv(0)[64:]) + eth_l11_rxc = Signal(intbv(0)[8:]) + + # Outputs + led = Signal(intbv(0)[4:]) + uart_rst = Signal(bool(0)) + uart_ri = Signal(bool(0)) + uart_dcd = Signal(bool(0)) + uart_dsr = Signal(bool(0)) + uart_rxd = Signal(bool(1)) + uart_cts = Signal(bool(0)) + amh_right_mdc = Signal(bool(1)) + amh_right_mdio_o = Signal(bool(1)) + amh_right_mdio_t = Signal(bool(1)) + amh_left_mdc = Signal(bool(1)) + amh_left_mdio_o = Signal(bool(1)) + amh_left_mdio_t = Signal(bool(1)) + eth_r0_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r0_txc = Signal(intbv(0xff)[8:]) + eth_r1_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r1_txc = Signal(intbv(0xff)[8:]) + eth_r2_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r2_txc = Signal(intbv(0xff)[8:]) + eth_r3_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r3_txc = Signal(intbv(0xff)[8:]) + eth_r4_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r4_txc = Signal(intbv(0xff)[8:]) + eth_r5_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r5_txc = Signal(intbv(0xff)[8:]) + eth_r6_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r6_txc = Signal(intbv(0xff)[8:]) + eth_r7_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r7_txc = Signal(intbv(0xff)[8:]) + eth_r8_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r8_txc = Signal(intbv(0xff)[8:]) + eth_r9_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r9_txc = Signal(intbv(0xff)[8:]) + eth_r10_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r10_txc = Signal(intbv(0xff)[8:]) + eth_r11_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r11_txc = Signal(intbv(0xff)[8:]) + eth_l0_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l0_txc = Signal(intbv(0xff)[8:]) + eth_l1_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l1_txc = Signal(intbv(0xff)[8:]) + eth_l2_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l2_txc = Signal(intbv(0xff)[8:]) + eth_l3_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l3_txc = Signal(intbv(0xff)[8:]) + eth_l4_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l4_txc = Signal(intbv(0xff)[8:]) + eth_l5_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l5_txc = Signal(intbv(0xff)[8:]) + eth_l6_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l6_txc = Signal(intbv(0xff)[8:]) + eth_l7_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l7_txc = Signal(intbv(0xff)[8:]) + eth_l8_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l8_txc = Signal(intbv(0xff)[8:]) + eth_l9_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l9_txc = Signal(intbv(0xff)[8:]) + eth_l10_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l10_txc = Signal(intbv(0xff)[8:]) + eth_l11_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l11_txc = Signal(intbv(0xff)[8:]) + + # sources and sinks + eth_r0_source = xgmii_ep.XGMIISource() + eth_r0_source_logic = eth_r0_source.create_logic(clk, rst, txd=eth_r0_rxd, txc=eth_r0_rxc, name='eth_r0_source') + + eth_r0_sink = xgmii_ep.XGMIISink() + eth_r0_sink_logic = eth_r0_sink.create_logic(clk, rst, rxd=eth_r0_txd, rxc=eth_r0_txc, name='eth_r0_sink') + + eth_r1_source = xgmii_ep.XGMIISource() + eth_r1_source_logic = eth_r1_source.create_logic(clk, rst, txd=eth_r1_rxd, txc=eth_r1_rxc, name='eth_r1_source') + + eth_r1_sink = xgmii_ep.XGMIISink() + eth_r1_sink_logic = eth_r1_sink.create_logic(clk, rst, rxd=eth_r1_txd, rxc=eth_r1_txc, name='eth_r1_sink') + + eth_r2_source = xgmii_ep.XGMIISource() + eth_r2_source_logic = eth_r2_source.create_logic(clk, rst, txd=eth_r2_rxd, txc=eth_r2_rxc, name='eth_r2_source') + + eth_r2_sink = xgmii_ep.XGMIISink() + eth_r2_sink_logic = eth_r2_sink.create_logic(clk, rst, rxd=eth_r2_txd, rxc=eth_r2_txc, name='eth_r2_sink') + + eth_r3_source = xgmii_ep.XGMIISource() + eth_r3_source_logic = eth_r3_source.create_logic(clk, rst, txd=eth_r3_rxd, txc=eth_r3_rxc, name='eth_r3_source') + + eth_r3_sink = xgmii_ep.XGMIISink() + eth_r3_sink_logic = eth_r3_sink.create_logic(clk, rst, rxd=eth_r3_txd, rxc=eth_r3_txc, name='eth_r3_sink') + + eth_r4_source = xgmii_ep.XGMIISource() + eth_r4_source_logic = eth_r4_source.create_logic(clk, rst, txd=eth_r4_rxd, txc=eth_r4_rxc, name='eth_r4_source') + + eth_r4_sink = xgmii_ep.XGMIISink() + eth_r4_sink_logic = eth_r4_sink.create_logic(clk, rst, rxd=eth_r4_txd, rxc=eth_r4_txc, name='eth_r4_sink') + + eth_r5_source = xgmii_ep.XGMIISource() + eth_r5_source_logic = eth_r5_source.create_logic(clk, rst, txd=eth_r5_rxd, txc=eth_r5_rxc, name='eth_r5_source') + + eth_r5_sink = xgmii_ep.XGMIISink() + eth_r5_sink_logic = eth_r5_sink.create_logic(clk, rst, rxd=eth_r5_txd, rxc=eth_r5_txc, name='eth_r5_sink') + + eth_r6_source = xgmii_ep.XGMIISource() + eth_r6_source_logic = eth_r6_source.create_logic(clk, rst, txd=eth_r6_rxd, txc=eth_r6_rxc, name='eth_r6_source') + + eth_r6_sink = xgmii_ep.XGMIISink() + eth_r6_sink_logic = eth_r6_sink.create_logic(clk, rst, rxd=eth_r6_txd, rxc=eth_r6_txc, name='eth_r6_sink') + + eth_r7_source = xgmii_ep.XGMIISource() + eth_r7_source_logic = eth_r7_source.create_logic(clk, rst, txd=eth_r7_rxd, txc=eth_r7_rxc, name='eth_r7_source') + + eth_r7_sink = xgmii_ep.XGMIISink() + eth_r7_sink_logic = eth_r7_sink.create_logic(clk, rst, rxd=eth_r7_txd, rxc=eth_r7_txc, name='eth_r7_sink') + + eth_r8_source = xgmii_ep.XGMIISource() + eth_r8_source_logic = eth_r8_source.create_logic(clk, rst, txd=eth_r8_rxd, txc=eth_r8_rxc, name='eth_r8_source') + + eth_r8_sink = xgmii_ep.XGMIISink() + eth_r8_sink_logic = eth_r8_sink.create_logic(clk, rst, rxd=eth_r8_txd, rxc=eth_r8_txc, name='eth_r8_sink') + + eth_r9_source = xgmii_ep.XGMIISource() + eth_r9_source_logic = eth_r9_source.create_logic(clk, rst, txd=eth_r9_rxd, txc=eth_r9_rxc, name='eth_r9_source') + + eth_r9_sink = xgmii_ep.XGMIISink() + eth_r9_sink_logic = eth_r9_sink.create_logic(clk, rst, rxd=eth_r9_txd, rxc=eth_r9_txc, name='eth_r9_sink') + + eth_r10_source = xgmii_ep.XGMIISource() + eth_r10_source_logic = eth_r10_source.create_logic(clk, rst, txd=eth_r10_rxd, txc=eth_r10_rxc, name='eth_r10_source') + + eth_r10_sink = xgmii_ep.XGMIISink() + eth_r10_sink_logic = eth_r10_sink.create_logic(clk, rst, rxd=eth_r10_txd, rxc=eth_r10_txc, name='eth_r10_sink') + + eth_r11_source = xgmii_ep.XGMIISource() + eth_r11_source_logic = eth_r11_source.create_logic(clk, rst, txd=eth_r11_rxd, txc=eth_r11_rxc, name='eth_r11_source') + + eth_r11_sink = xgmii_ep.XGMIISink() + eth_r11_sink_logic = eth_r11_sink.create_logic(clk, rst, rxd=eth_r11_txd, rxc=eth_r11_txc, name='eth_r11_sink') + + eth_l0_source = xgmii_ep.XGMIISource() + eth_l0_source_logic = eth_l0_source.create_logic(clk, rst, txd=eth_l0_rxd, txc=eth_l0_rxc, name='eth_l0_source') + + eth_l0_sink = xgmii_ep.XGMIISink() + eth_l0_sink_logic = eth_l0_sink.create_logic(clk, rst, rxd=eth_l0_txd, rxc=eth_l0_txc, name='eth_l0_sink') + + eth_l1_source = xgmii_ep.XGMIISource() + eth_l1_source_logic = eth_l1_source.create_logic(clk, rst, txd=eth_l1_rxd, txc=eth_l1_rxc, name='eth_l1_source') + + eth_l1_sink = xgmii_ep.XGMIISink() + eth_l1_sink_logic = eth_l1_sink.create_logic(clk, rst, rxd=eth_l1_txd, rxc=eth_l1_txc, name='eth_l1_sink') + + eth_l2_source = xgmii_ep.XGMIISource() + eth_l2_source_logic = eth_l2_source.create_logic(clk, rst, txd=eth_l2_rxd, txc=eth_l2_rxc, name='eth_l2_source') + + eth_l2_sink = xgmii_ep.XGMIISink() + eth_l2_sink_logic = eth_l2_sink.create_logic(clk, rst, rxd=eth_l2_txd, rxc=eth_l2_txc, name='eth_l2_sink') + + eth_l3_source = xgmii_ep.XGMIISource() + eth_l3_source_logic = eth_l3_source.create_logic(clk, rst, txd=eth_l3_rxd, txc=eth_l3_rxc, name='eth_l3_source') + + eth_l3_sink = xgmii_ep.XGMIISink() + eth_l3_sink_logic = eth_l3_sink.create_logic(clk, rst, rxd=eth_l3_txd, rxc=eth_l3_txc, name='eth_l3_sink') + + eth_l4_source = xgmii_ep.XGMIISource() + eth_l4_source_logic = eth_l4_source.create_logic(clk, rst, txd=eth_l4_rxd, txc=eth_l4_rxc, name='eth_l4_source') + + eth_l4_sink = xgmii_ep.XGMIISink() + eth_l4_sink_logic = eth_l4_sink.create_logic(clk, rst, rxd=eth_l4_txd, rxc=eth_l4_txc, name='eth_l4_sink') + + eth_l5_source = xgmii_ep.XGMIISource() + eth_l5_source_logic = eth_l5_source.create_logic(clk, rst, txd=eth_l5_rxd, txc=eth_l5_rxc, name='eth_l5_source') + + eth_l5_sink = xgmii_ep.XGMIISink() + eth_l5_sink_logic = eth_l5_sink.create_logic(clk, rst, rxd=eth_l5_txd, rxc=eth_l5_txc, name='eth_l5_sink') + + eth_l6_source = xgmii_ep.XGMIISource() + eth_l6_source_logic = eth_l6_source.create_logic(clk, rst, txd=eth_l6_rxd, txc=eth_l6_rxc, name='eth_l6_source') + + eth_l6_sink = xgmii_ep.XGMIISink() + eth_l6_sink_logic = eth_l6_sink.create_logic(clk, rst, rxd=eth_l6_txd, rxc=eth_l6_txc, name='eth_l6_sink') + + eth_l7_source = xgmii_ep.XGMIISource() + eth_l7_source_logic = eth_l7_source.create_logic(clk, rst, txd=eth_l7_rxd, txc=eth_l7_rxc, name='eth_l7_source') + + eth_l7_sink = xgmii_ep.XGMIISink() + eth_l7_sink_logic = eth_l7_sink.create_logic(clk, rst, rxd=eth_l7_txd, rxc=eth_l7_txc, name='eth_l7_sink') + + eth_l8_source = xgmii_ep.XGMIISource() + eth_l8_source_logic = eth_l8_source.create_logic(clk, rst, txd=eth_l8_rxd, txc=eth_l8_rxc, name='eth_l8_source') + + eth_l8_sink = xgmii_ep.XGMIISink() + eth_l8_sink_logic = eth_l8_sink.create_logic(clk, rst, rxd=eth_l8_txd, rxc=eth_l8_txc, name='eth_l8_sink') + + eth_l9_source = xgmii_ep.XGMIISource() + eth_l9_source_logic = eth_l9_source.create_logic(clk, rst, txd=eth_l9_rxd, txc=eth_l9_rxc, name='eth_l9_source') + + eth_l9_sink = xgmii_ep.XGMIISink() + eth_l9_sink_logic = eth_l9_sink.create_logic(clk, rst, rxd=eth_l9_txd, rxc=eth_l9_txc, name='eth_l9_sink') + + eth_l10_source = xgmii_ep.XGMIISource() + eth_l10_source_logic = eth_l10_source.create_logic(clk, rst, txd=eth_l10_rxd, txc=eth_l10_rxc, name='eth_l10_source') + + eth_l10_sink = xgmii_ep.XGMIISink() + eth_l10_sink_logic = eth_l10_sink.create_logic(clk, rst, rxd=eth_l10_txd, rxc=eth_l10_txc, name='eth_l10_sink') + + eth_l11_source = xgmii_ep.XGMIISource() + eth_l11_source_logic = eth_l11_source.create_logic(clk, rst, txd=eth_l11_rxd, txc=eth_l11_rxc, name='eth_l11_source') + + eth_l11_sink = xgmii_ep.XGMIISink() + eth_l11_sink_logic = eth_l11_sink.create_logic(clk, rst, rxd=eth_l11_txd, rxc=eth_l11_txc, name='eth_l11_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, + + sw=sw, + jp=jp, + led=led, + + uart_rst=uart_rst, + uart_suspend=uart_suspend, + uart_ri=uart_ri, + uart_dcd=uart_dcd, + uart_dtr=uart_dtr, + uart_dsr=uart_dsr, + uart_txd=uart_txd, + uart_rxd=uart_rxd, + uart_rts=uart_rts, + uart_cts=uart_cts, + + amh_right_mdc=amh_right_mdc, + amh_right_mdio_i=amh_right_mdio_i, + amh_right_mdio_o=amh_right_mdio_o, + amh_right_mdio_t=amh_right_mdio_t, + amh_left_mdc=amh_left_mdc, + amh_left_mdio_i=amh_left_mdio_i, + amh_left_mdio_o=amh_left_mdio_o, + amh_left_mdio_t=amh_left_mdio_t, + + eth_r0_txd=eth_r0_txd, + eth_r0_txc=eth_r0_txc, + eth_r0_rxd=eth_r0_rxd, + eth_r0_rxc=eth_r0_rxc, + eth_r1_txd=eth_r1_txd, + eth_r1_txc=eth_r1_txc, + eth_r1_rxd=eth_r1_rxd, + eth_r1_rxc=eth_r1_rxc, + eth_r2_txd=eth_r2_txd, + eth_r2_txc=eth_r2_txc, + eth_r2_rxd=eth_r2_rxd, + eth_r2_rxc=eth_r2_rxc, + eth_r3_txd=eth_r3_txd, + eth_r3_txc=eth_r3_txc, + eth_r3_rxd=eth_r3_rxd, + eth_r3_rxc=eth_r3_rxc, + eth_r4_txd=eth_r4_txd, + eth_r4_txc=eth_r4_txc, + eth_r4_rxd=eth_r4_rxd, + eth_r4_rxc=eth_r4_rxc, + eth_r5_txd=eth_r5_txd, + eth_r5_txc=eth_r5_txc, + eth_r5_rxd=eth_r5_rxd, + eth_r5_rxc=eth_r5_rxc, + eth_r6_txd=eth_r6_txd, + eth_r6_txc=eth_r6_txc, + eth_r6_rxd=eth_r6_rxd, + eth_r6_rxc=eth_r6_rxc, + eth_r7_txd=eth_r7_txd, + eth_r7_txc=eth_r7_txc, + eth_r7_rxd=eth_r7_rxd, + eth_r7_rxc=eth_r7_rxc, + eth_r8_txd=eth_r8_txd, + eth_r8_txc=eth_r8_txc, + eth_r8_rxd=eth_r8_rxd, + eth_r8_rxc=eth_r8_rxc, + eth_r9_txd=eth_r9_txd, + eth_r9_txc=eth_r9_txc, + eth_r9_rxd=eth_r9_rxd, + eth_r9_rxc=eth_r9_rxc, + eth_r10_txd=eth_r10_txd, + eth_r10_txc=eth_r10_txc, + eth_r10_rxd=eth_r10_rxd, + eth_r10_rxc=eth_r10_rxc, + eth_r11_txd=eth_r11_txd, + eth_r11_txc=eth_r11_txc, + eth_r11_rxd=eth_r11_rxd, + eth_r11_rxc=eth_r11_rxc, + eth_l0_txd=eth_l0_txd, + eth_l0_txc=eth_l0_txc, + eth_l0_rxd=eth_l0_rxd, + eth_l0_rxc=eth_l0_rxc, + eth_l1_txd=eth_l1_txd, + eth_l1_txc=eth_l1_txc, + eth_l1_rxd=eth_l1_rxd, + eth_l1_rxc=eth_l1_rxc, + eth_l2_txd=eth_l2_txd, + eth_l2_txc=eth_l2_txc, + eth_l2_rxd=eth_l2_rxd, + eth_l2_rxc=eth_l2_rxc, + eth_l3_txd=eth_l3_txd, + eth_l3_txc=eth_l3_txc, + eth_l3_rxd=eth_l3_rxd, + eth_l3_rxc=eth_l3_rxc, + eth_l4_txd=eth_l4_txd, + eth_l4_txc=eth_l4_txc, + eth_l4_rxd=eth_l4_rxd, + eth_l4_rxc=eth_l4_rxc, + eth_l5_txd=eth_l5_txd, + eth_l5_txc=eth_l5_txc, + eth_l5_rxd=eth_l5_rxd, + eth_l5_rxc=eth_l5_rxc, + eth_l6_txd=eth_l6_txd, + eth_l6_txc=eth_l6_txc, + eth_l6_rxd=eth_l6_rxd, + eth_l6_rxc=eth_l6_rxc, + eth_l7_txd=eth_l7_txd, + eth_l7_txc=eth_l7_txc, + eth_l7_rxd=eth_l7_rxd, + eth_l7_rxc=eth_l7_rxc, + eth_l8_txd=eth_l8_txd, + eth_l8_txc=eth_l8_txc, + eth_l8_rxd=eth_l8_rxd, + eth_l8_rxc=eth_l8_rxc, + eth_l9_txd=eth_l9_txd, + eth_l9_txc=eth_l9_txc, + eth_l9_rxd=eth_l9_rxd, + eth_l9_rxc=eth_l9_rxc, + eth_l10_txd=eth_l10_txd, + eth_l10_txc=eth_l10_txc, + eth_l10_rxd=eth_l10_rxd, + eth_l10_rxc=eth_l10_rxc, + eth_l11_txd=eth_l11_txd, + eth_l11_txc=eth_l11_txc, + eth_l11_rxd=eth_l11_rxd, + eth_l11_rxc=eth_l11_rxc + ) + + @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 + + # testbench stimulus + + 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(range(46)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + eth_l0_source.send(xgmii_frame) + + while eth_l0_sink.empty(): + yield clk.posedge + + check_frame = eth_l0_sink.recv() + + assert check_frame == xgmii_frame + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8099 + test_frame.payload = bytearray(range(15,-1,-1)) + bytearray([0]*(46-16)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + eth_l11_source.send(xgmii_frame) + + yield delay(400) + + 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(range(46)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + eth_l0_source.send(xgmii_frame) + + while eth_r7_sink.empty(): + yield clk.posedge + + check_frame = eth_r7_sink.recv() + + assert check_frame == xgmii_frame + + yield delay(100) + + raise StopSimulation + + return (dut, clkgen, check, eth_r0_source_logic, eth_r0_sink_logic, eth_r1_source_logic, eth_r1_sink_logic, eth_r2_source_logic, eth_r2_sink_logic, + eth_r3_source_logic, eth_r3_sink_logic, eth_r4_source_logic, eth_r4_sink_logic, eth_r5_source_logic, eth_r5_sink_logic, + eth_r6_source_logic, eth_r6_sink_logic, eth_r7_source_logic, eth_r7_sink_logic, eth_r8_source_logic, eth_r8_sink_logic, + eth_r9_source_logic, eth_r9_sink_logic, eth_r10_source_logic, eth_r10_sink_logic, eth_r11_source_logic, eth_r11_sink_logic, + eth_l0_source_logic, eth_l0_sink_logic, eth_l1_source_logic, eth_l1_sink_logic, eth_l2_source_logic, eth_l2_sink_logic, + eth_l3_source_logic, eth_l3_sink_logic, eth_l4_source_logic, eth_l4_sink_logic, eth_l5_source_logic, eth_l5_sink_logic, + eth_l6_source_logic, eth_l6_sink_logic, eth_l7_source_logic, eth_l7_sink_logic, eth_l8_source_logic, eth_l8_sink_logic, + eth_l9_source_logic, eth_l9_sink_logic, eth_l10_source_logic, eth_l10_sink_logic, eth_l11_source_logic, eth_l11_sink_logic) + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.v b/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.v new file mode 100644 index 000000000..370c25e29 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.v @@ -0,0 +1,416 @@ +/* + +Copyright (c) 2016-2018 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [1:0] sw = 0; +reg [3:0] jp = 0; +reg uart_suspend = 0; +reg uart_dtr = 0; +reg uart_txd = 0; +reg uart_rts = 0; +reg amh_right_mdio_i = 0; +reg amh_left_mdio_i = 0; +reg [63:0] eth_r0_rxd = 0; +reg [7:0] eth_r0_rxc = 0; +reg [63:0] eth_r1_rxd = 0; +reg [7:0] eth_r1_rxc = 0; +reg [63:0] eth_r2_rxd = 0; +reg [7:0] eth_r2_rxc = 0; +reg [63:0] eth_r3_rxd = 0; +reg [7:0] eth_r3_rxc = 0; +reg [63:0] eth_r4_rxd = 0; +reg [7:0] eth_r4_rxc = 0; +reg [63:0] eth_r5_rxd = 0; +reg [7:0] eth_r5_rxc = 0; +reg [63:0] eth_r6_rxd = 0; +reg [7:0] eth_r6_rxc = 0; +reg [63:0] eth_r7_rxd = 0; +reg [7:0] eth_r7_rxc = 0; +reg [63:0] eth_r8_rxd = 0; +reg [7:0] eth_r8_rxc = 0; +reg [63:0] eth_r9_rxd = 0; +reg [7:0] eth_r9_rxc = 0; +reg [63:0] eth_r10_rxd = 0; +reg [7:0] eth_r10_rxc = 0; +reg [63:0] eth_r11_rxd = 0; +reg [7:0] eth_r11_rxc = 0; +reg [63:0] eth_l0_rxd = 0; +reg [7:0] eth_l0_rxc = 0; +reg [63:0] eth_l1_rxd = 0; +reg [7:0] eth_l1_rxc = 0; +reg [63:0] eth_l2_rxd = 0; +reg [7:0] eth_l2_rxc = 0; +reg [63:0] eth_l3_rxd = 0; +reg [7:0] eth_l3_rxc = 0; +reg [63:0] eth_l4_rxd = 0; +reg [7:0] eth_l4_rxc = 0; +reg [63:0] eth_l5_rxd = 0; +reg [7:0] eth_l5_rxc = 0; +reg [63:0] eth_l6_rxd = 0; +reg [7:0] eth_l6_rxc = 0; +reg [63:0] eth_l7_rxd = 0; +reg [7:0] eth_l7_rxc = 0; +reg [63:0] eth_l8_rxd = 0; +reg [7:0] eth_l8_rxc = 0; +reg [63:0] eth_l9_rxd = 0; +reg [7:0] eth_l9_rxc = 0; +reg [63:0] eth_l10_rxd = 0; +reg [7:0] eth_l10_rxc = 0; +reg [63:0] eth_l11_rxd = 0; +reg [7:0] eth_l11_rxc = 0; + +// Outputs +wire [3:0] led; +wire uart_rst; +wire uart_ri; +wire uart_dcd; +wire uart_dsr; +wire uart_rxd; +wire uart_cts; +wire amh_right_mdc; +wire amh_right_mdio_o; +wire amh_right_mdio_t; +wire amh_left_mdc; +wire amh_left_mdio_o; +wire amh_left_mdio_t; +wire [63:0] eth_r0_txd; +wire [7:0] eth_r0_txc; +wire [63:0] eth_r1_txd; +wire [7:0] eth_r1_txc; +wire [63:0] eth_r2_txd; +wire [7:0] eth_r2_txc; +wire [63:0] eth_r3_txd; +wire [7:0] eth_r3_txc; +wire [63:0] eth_r4_txd; +wire [7:0] eth_r4_txc; +wire [63:0] eth_r5_txd; +wire [7:0] eth_r5_txc; +wire [63:0] eth_r6_txd; +wire [7:0] eth_r6_txc; +wire [63:0] eth_r7_txd; +wire [7:0] eth_r7_txc; +wire [63:0] eth_r8_txd; +wire [7:0] eth_r8_txc; +wire [63:0] eth_r9_txd; +wire [7:0] eth_r9_txc; +wire [63:0] eth_r10_txd; +wire [7:0] eth_r10_txc; +wire [63:0] eth_r11_txd; +wire [7:0] eth_r11_txc; +wire [63:0] eth_l0_txd; +wire [7:0] eth_l0_txc; +wire [63:0] eth_l1_txd; +wire [7:0] eth_l1_txc; +wire [63:0] eth_l2_txd; +wire [7:0] eth_l2_txc; +wire [63:0] eth_l3_txd; +wire [7:0] eth_l3_txc; +wire [63:0] eth_l4_txd; +wire [7:0] eth_l4_txc; +wire [63:0] eth_l5_txd; +wire [7:0] eth_l5_txc; +wire [63:0] eth_l6_txd; +wire [7:0] eth_l6_txc; +wire [63:0] eth_l7_txd; +wire [7:0] eth_l7_txc; +wire [63:0] eth_l8_txd; +wire [7:0] eth_l8_txc; +wire [63:0] eth_l9_txd; +wire [7:0] eth_l9_txc; +wire [63:0] eth_l10_txd; +wire [7:0] eth_l10_txc; +wire [63:0] eth_l11_txd; +wire [7:0] eth_l11_txc; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + sw, + jp, + uart_suspend, + uart_dtr, + uart_txd, + uart_rts, + amh_right_mdio_i, + amh_left_mdio_i, + eth_r0_rxd, + eth_r0_rxc, + eth_r1_rxd, + eth_r1_rxc, + eth_r2_rxd, + eth_r2_rxc, + eth_r3_rxd, + eth_r3_rxc, + eth_r4_rxd, + eth_r4_rxc, + eth_r5_rxd, + eth_r5_rxc, + eth_r6_rxd, + eth_r6_rxc, + eth_r7_rxd, + eth_r7_rxc, + eth_r8_rxd, + eth_r8_rxc, + eth_r9_rxd, + eth_r9_rxc, + eth_r10_rxd, + eth_r10_rxc, + eth_r11_rxd, + eth_r11_rxc, + eth_l0_rxd, + eth_l0_rxc, + eth_l1_rxd, + eth_l1_rxc, + eth_l2_rxd, + eth_l2_rxc, + eth_l3_rxd, + eth_l3_rxc, + eth_l4_rxd, + eth_l4_rxc, + eth_l5_rxd, + eth_l5_rxc, + eth_l6_rxd, + eth_l6_rxc, + eth_l7_rxd, + eth_l7_rxc, + eth_l8_rxd, + eth_l8_rxc, + eth_l9_rxd, + eth_l9_rxc, + eth_l10_rxd, + eth_l10_rxc, + eth_l11_rxd, + eth_l11_rxc + ); + $to_myhdl( + led, + uart_rst, + uart_ri, + uart_dcd, + uart_dsr, + uart_rxd, + uart_cts, + amh_right_mdc, + amh_right_mdio_o, + amh_right_mdio_t, + amh_left_mdc, + amh_left_mdio_o, + amh_left_mdio_t, + eth_r0_txd, + eth_r0_txc, + eth_r1_txd, + eth_r1_txc, + eth_r2_txd, + eth_r2_txc, + eth_r3_txd, + eth_r3_txc, + eth_r4_txd, + eth_r4_txc, + eth_r5_txd, + eth_r5_txc, + eth_r6_txd, + eth_r6_txc, + eth_r7_txd, + eth_r7_txc, + eth_r8_txd, + eth_r8_txc, + eth_r9_txd, + eth_r9_txc, + eth_r10_txd, + eth_r10_txc, + eth_r11_txd, + eth_r11_txc, + eth_l0_txd, + eth_l0_txc, + eth_l1_txd, + eth_l1_txc, + eth_l2_txd, + eth_l2_txc, + eth_l3_txd, + eth_l3_txc, + eth_l4_txd, + eth_l4_txc, + eth_l5_txd, + eth_l5_txc, + eth_l6_txd, + eth_l6_txc, + eth_l7_txd, + eth_l7_txc, + eth_l8_txd, + eth_l8_txc, + eth_l9_txd, + eth_l9_txc, + eth_l10_txd, + eth_l10_txc, + eth_l11_txd, + eth_l11_txc + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .sw(sw), + .jp(jp), + .led(led), + .uart_rst(uart_rst), + .uart_suspend(uart_suspend), + .uart_ri(uart_ri), + .uart_dcd(uart_dcd), + .uart_dtr(uart_dtr), + .uart_dsr(uart_dsr), + .uart_txd(uart_txd), + .uart_rxd(uart_rxd), + .uart_rts(uart_rts), + .uart_cts(uart_cts), + .amh_right_mdc(amh_right_mdc), + .amh_right_mdio_i(amh_right_mdio_i), + .amh_right_mdio_o(amh_right_mdio_o), + .amh_right_mdio_t(amh_right_mdio_t), + .amh_left_mdc(amh_left_mdc), + .amh_left_mdio_i(amh_left_mdio_i), + .amh_left_mdio_o(amh_left_mdio_o), + .amh_left_mdio_t(amh_left_mdio_t), + .eth_r0_txd(eth_r0_txd), + .eth_r0_txc(eth_r0_txc), + .eth_r0_rxd(eth_r0_rxd), + .eth_r0_rxc(eth_r0_rxc), + .eth_r1_txd(eth_r1_txd), + .eth_r1_txc(eth_r1_txc), + .eth_r1_rxd(eth_r1_rxd), + .eth_r1_rxc(eth_r1_rxc), + .eth_r2_txd(eth_r2_txd), + .eth_r2_txc(eth_r2_txc), + .eth_r2_rxd(eth_r2_rxd), + .eth_r2_rxc(eth_r2_rxc), + .eth_r3_txd(eth_r3_txd), + .eth_r3_txc(eth_r3_txc), + .eth_r3_rxd(eth_r3_rxd), + .eth_r3_rxc(eth_r3_rxc), + .eth_r4_txd(eth_r4_txd), + .eth_r4_txc(eth_r4_txc), + .eth_r4_rxd(eth_r4_rxd), + .eth_r4_rxc(eth_r4_rxc), + .eth_r5_txd(eth_r5_txd), + .eth_r5_txc(eth_r5_txc), + .eth_r5_rxd(eth_r5_rxd), + .eth_r5_rxc(eth_r5_rxc), + .eth_r6_txd(eth_r6_txd), + .eth_r6_txc(eth_r6_txc), + .eth_r6_rxd(eth_r6_rxd), + .eth_r6_rxc(eth_r6_rxc), + .eth_r7_txd(eth_r7_txd), + .eth_r7_txc(eth_r7_txc), + .eth_r7_rxd(eth_r7_rxd), + .eth_r7_rxc(eth_r7_rxc), + .eth_r8_txd(eth_r8_txd), + .eth_r8_txc(eth_r8_txc), + .eth_r8_rxd(eth_r8_rxd), + .eth_r8_rxc(eth_r8_rxc), + .eth_r9_txd(eth_r9_txd), + .eth_r9_txc(eth_r9_txc), + .eth_r9_rxd(eth_r9_rxd), + .eth_r9_rxc(eth_r9_rxc), + .eth_r10_txd(eth_r10_txd), + .eth_r10_txc(eth_r10_txc), + .eth_r10_rxd(eth_r10_rxd), + .eth_r10_rxc(eth_r10_rxc), + .eth_r11_txd(eth_r11_txd), + .eth_r11_txc(eth_r11_txc), + .eth_r11_rxd(eth_r11_rxd), + .eth_r11_rxc(eth_r11_rxc), + .eth_l0_txd(eth_l0_txd), + .eth_l0_txc(eth_l0_txc), + .eth_l0_rxd(eth_l0_rxd), + .eth_l0_rxc(eth_l0_rxc), + .eth_l1_txd(eth_l1_txd), + .eth_l1_txc(eth_l1_txc), + .eth_l1_rxd(eth_l1_rxd), + .eth_l1_rxc(eth_l1_rxc), + .eth_l2_txd(eth_l2_txd), + .eth_l2_txc(eth_l2_txc), + .eth_l2_rxd(eth_l2_rxd), + .eth_l2_rxc(eth_l2_rxc), + .eth_l3_txd(eth_l3_txd), + .eth_l3_txc(eth_l3_txc), + .eth_l3_rxd(eth_l3_rxd), + .eth_l3_rxc(eth_l3_rxc), + .eth_l4_txd(eth_l4_txd), + .eth_l4_txc(eth_l4_txc), + .eth_l4_rxd(eth_l4_rxd), + .eth_l4_rxc(eth_l4_rxc), + .eth_l5_txd(eth_l5_txd), + .eth_l5_txc(eth_l5_txc), + .eth_l5_rxd(eth_l5_rxd), + .eth_l5_rxc(eth_l5_rxc), + .eth_l6_txd(eth_l6_txd), + .eth_l6_txc(eth_l6_txc), + .eth_l6_rxd(eth_l6_rxd), + .eth_l6_rxc(eth_l6_rxc), + .eth_l7_txd(eth_l7_txd), + .eth_l7_txc(eth_l7_txc), + .eth_l7_rxd(eth_l7_rxd), + .eth_l7_rxc(eth_l7_rxc), + .eth_l8_txd(eth_l8_txd), + .eth_l8_txc(eth_l8_txc), + .eth_l8_rxd(eth_l8_rxd), + .eth_l8_rxc(eth_l8_rxc), + .eth_l9_txd(eth_l9_txd), + .eth_l9_txc(eth_l9_txc), + .eth_l9_rxd(eth_l9_rxd), + .eth_l9_rxc(eth_l9_rxc), + .eth_l10_txd(eth_l10_txd), + .eth_l10_txc(eth_l10_txc), + .eth_l10_rxd(eth_l10_rxd), + .eth_l10_rxc(eth_l10_rxc), + .eth_l11_txd(eth_l11_txd), + .eth_l11_txc(eth_l11_txc), + .eth_l11_rxd(eth_l11_rxd), + .eth_l11_rxc(eth_l11_rxc) +); + +endmodule diff --git a/example/HXT100G/fpga_cxpt16/tb/xgmii_ep.py b/example/HXT100G/fpga_cxpt16/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/example/HXT100G/fpga_cxpt16/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file From e95b39b36d0d680054aceafb6a80d5185ddfcef0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 4 Jun 2018 18:20:31 -0700 Subject: [PATCH 380/617] Update iddr/oddr Altera device support --- rtl/iddr.v | 16 ++++++++++++---- rtl/oddr.v | 3 +-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/rtl/iddr.v b/rtl/iddr.v index f3fb61997..d58e7b688 100644 --- a/rtl/iddr.v +++ b/rtl/iddr.v @@ -54,7 +54,7 @@ genvar n; generate if (TARGET == "XILINX") begin - for (n = 0; n < WIDTH; n = n + 1) begin + for (n = 0; n < WIDTH; n = n + 1) begin : iddr if (IODDR_STYLE == "IODDR") begin IDDR #( .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), @@ -86,10 +86,12 @@ if (TARGET == "XILINX") begin end end end else if (TARGET == "ALTERA") begin + wire [WIDTH-1:0] q1_int; + reg [WIDTH-1:0] q1_delay; + altddio_in #( .WIDTH(WIDTH), - .POWER_UP_HIGH("OFF"), - .INTENDED_DEVICE_FAMILY("Stratix V") + .POWER_UP_HIGH("OFF") ) altddio_in_inst ( .aset(1'b0), @@ -97,9 +99,15 @@ end else if (TARGET == "ALTERA") begin .inclocken(1'b1), .inclock(clk), .aclr(1'b0), - .dataout_h(q1), + .dataout_h(q1_int), .dataout_l(q2) ); + + always @(posedge clk) begin + q1_delay <= q1_int; + end + + assign q1 = q1_delay; end else begin reg [WIDTH-1:0] d_reg_1 = {WIDTH{1'b0}}; reg [WIDTH-1:0] d_reg_2 = {WIDTH{1'b0}}; diff --git a/rtl/oddr.v b/rtl/oddr.v index 52afbd826..77e62f0c7 100644 --- a/rtl/oddr.v +++ b/rtl/oddr.v @@ -54,7 +54,7 @@ genvar n; generate if (TARGET == "XILINX") begin - for (n = 0; n < WIDTH; n = n + 1) begin + for (n = 0; n < WIDTH; n = n + 1) begin : oddr if (IODDR_STYLE == "IODDR") begin ODDR #( .DDR_CLK_EDGE("SAME_EDGE"), @@ -90,7 +90,6 @@ end else if (TARGET == "ALTERA") begin altddio_out #( .WIDTH(WIDTH), .POWER_UP_HIGH("OFF"), - .INTENDED_DEVICE_FAMILY("Stratix V"), .OE_REG("UNUSED") ) altddio_out_inst ( From 3ae97c71a02c8f1b0f46c13357670001acc6e1a0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 4 Jun 2018 18:21:55 -0700 Subject: [PATCH 381/617] Add documentation --- rtl/iddr.v | 14 ++++++++++++++ rtl/oddr.v | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/rtl/iddr.v b/rtl/iddr.v index d58e7b688..473a06d35 100644 --- a/rtl/iddr.v +++ b/rtl/iddr.v @@ -49,6 +49,20 @@ module iddr # output wire [WIDTH-1:0] q2 ); +/* + +Provides a consistent input DDR flip flop across multiple FPGA families + _____ _____ _____ _____ ____ + clk ____/ \_____/ \_____/ \_____/ \_____/ + _ _____ _____ _____ _____ _____ _____ _____ _____ _____ _ + d _X_D0__X_D1__X_D2__X_D3__X_D4__X_D5__X_D6__X_D7__X_D8__X_ + _______ ___________ ___________ ___________ ___________ _ + q1 _______X___________X____D0_____X____D2_____X____D4_____X_ + _______ ___________ ___________ ___________ ___________ _ + q2 _______X___________X____D1_____X____D3_____X____D5_____X_ + +*/ + genvar n; generate diff --git a/rtl/oddr.v b/rtl/oddr.v index 77e62f0c7..db2d14429 100644 --- a/rtl/oddr.v +++ b/rtl/oddr.v @@ -49,6 +49,20 @@ module oddr # output wire [WIDTH-1:0] q ); +/* + +Provides a consistent output DDR flip flop across multiple FPGA families + _____ _____ _____ _____ + clk ____/ \_____/ \_____/ \_____/ \_____ + _ ___________ ___________ ___________ ___________ __ + d1 _X____D0_____X____D2_____X____D4_____X____D6_____X__ + _ ___________ ___________ ___________ ___________ __ + d2 _X____D1_____X____D3_____X____D5_____X____D7_____X__ + _____ _____ _____ _____ _____ _____ _____ _____ ____ + d _____X_D0__X_D1__X_D2__X_D3__X_D4__X_D5__X_D6__X_D7_ + +*/ + genvar n; generate From fea477db0936f077e8caaa4d3d3a6d9d3c3aa583 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 11 Jun 2018 16:36:44 -0700 Subject: [PATCH 382/617] Add unused ports --- rtl/eth_mac_1g_fifo.v | 4 ++++ rtl/eth_mac_1g_gmii_fifo.v | 4 ++++ rtl/eth_mac_1g_rgmii_fifo.v | 4 ++++ rtl/udp.v | 4 +++- rtl/udp_64.v | 4 +++- 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index b8941b259..4abdf4560 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -193,6 +193,7 @@ tx_fifo ( // AXI input .input_clk(logic_clk), .input_axis_tdata(tx_axis_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(tx_axis_tvalid), .input_axis_tready(tx_axis_tready), .input_axis_tlast(tx_axis_tlast), @@ -202,6 +203,7 @@ tx_fifo ( // AXI output .output_clk(tx_clk), .output_axis_tdata(tx_fifo_axis_tdata), + .output_axis_tkeep(), .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), .output_axis_tlast(tx_fifo_axis_tlast), @@ -238,6 +240,7 @@ rx_fifo ( // AXI input .input_clk(rx_clk), .input_axis_tdata(rx_fifo_axis_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(rx_fifo_axis_tvalid), .input_axis_tready(), .input_axis_tlast(rx_fifo_axis_tlast), @@ -247,6 +250,7 @@ rx_fifo ( // AXI output .output_clk(logic_clk), .output_axis_tdata(rx_axis_tdata), + .output_axis_tkeep(), .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), .output_axis_tlast(rx_axis_tlast), diff --git a/rtl/eth_mac_1g_gmii_fifo.v b/rtl/eth_mac_1g_gmii_fifo.v index bb4f1c661..885359d71 100644 --- a/rtl/eth_mac_1g_gmii_fifo.v +++ b/rtl/eth_mac_1g_gmii_fifo.v @@ -220,6 +220,7 @@ tx_fifo ( // AXI input .input_clk(logic_clk), .input_axis_tdata(tx_axis_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(tx_axis_tvalid), .input_axis_tready(tx_axis_tready), .input_axis_tlast(tx_axis_tlast), @@ -229,6 +230,7 @@ tx_fifo ( // AXI output .output_clk(tx_clk), .output_axis_tdata(tx_fifo_axis_tdata), + .output_axis_tkeep(), .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), .output_axis_tlast(tx_fifo_axis_tlast), @@ -265,6 +267,7 @@ rx_fifo ( // AXI input .input_clk(rx_clk), .input_axis_tdata(rx_fifo_axis_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(rx_fifo_axis_tvalid), .input_axis_tready(), .input_axis_tlast(rx_fifo_axis_tlast), @@ -274,6 +277,7 @@ rx_fifo ( // AXI output .output_clk(logic_clk), .output_axis_tdata(rx_axis_tdata), + .output_axis_tkeep(), .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), .output_axis_tlast(rx_axis_tlast), diff --git a/rtl/eth_mac_1g_rgmii_fifo.v b/rtl/eth_mac_1g_rgmii_fifo.v index fa925799e..27a3676d9 100644 --- a/rtl/eth_mac_1g_rgmii_fifo.v +++ b/rtl/eth_mac_1g_rgmii_fifo.v @@ -219,6 +219,7 @@ tx_fifo ( // AXI input .input_clk(logic_clk), .input_axis_tdata(tx_axis_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(tx_axis_tvalid), .input_axis_tready(tx_axis_tready), .input_axis_tlast(tx_axis_tlast), @@ -228,6 +229,7 @@ tx_fifo ( // AXI output .output_clk(tx_clk), .output_axis_tdata(tx_fifo_axis_tdata), + .output_axis_tkeep(), .output_axis_tvalid(tx_fifo_axis_tvalid), .output_axis_tready(tx_fifo_axis_tready), .output_axis_tlast(tx_fifo_axis_tlast), @@ -264,6 +266,7 @@ rx_fifo ( // AXI input .input_clk(rx_clk), .input_axis_tdata(rx_fifo_axis_tdata), + .input_axis_tkeep(0), .input_axis_tvalid(rx_fifo_axis_tvalid), .input_axis_tready(), .input_axis_tlast(rx_fifo_axis_tlast), @@ -273,6 +276,7 @@ rx_fifo ( // AXI output .output_clk(logic_clk), .output_axis_tdata(rx_axis_tdata), + .output_axis_tkeep(), .output_axis_tvalid(rx_axis_tvalid), .output_axis_tready(rx_axis_tready), .output_axis_tlast(rx_axis_tlast), diff --git a/rtl/udp.v b/rtl/udp.v index b32930176..aba9740ff 100644 --- a/rtl/udp.v +++ b/rtl/udp.v @@ -313,7 +313,9 @@ if (CHECKSUM_GEN_ENABLE) begin .output_udp_payload_tvalid(tx_udp_payload_tvalid), .output_udp_payload_tready(tx_udp_payload_tready), .output_udp_payload_tlast(tx_udp_payload_tlast), - .output_udp_payload_tuser(tx_udp_payload_tuser) + .output_udp_payload_tuser(tx_udp_payload_tuser), + // Status signals + .busy() ); end else begin diff --git a/rtl/udp_64.v b/rtl/udp_64.v index 75b199652..26c40ae09 100644 --- a/rtl/udp_64.v +++ b/rtl/udp_64.v @@ -321,7 +321,9 @@ if (CHECKSUM_GEN_ENABLE) begin .output_udp_payload_tvalid(tx_udp_payload_tvalid), .output_udp_payload_tready(tx_udp_payload_tready), .output_udp_payload_tlast(tx_udp_payload_tlast), - .output_udp_payload_tuser(tx_udp_payload_tuser) + .output_udp_payload_tuser(tx_udp_payload_tuser), + // Status signals + .busy() ); end else begin From 415f723edc7c9dfc5de82f5822122b2d014a645a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 11 Jun 2018 16:37:34 -0700 Subject: [PATCH 383/617] Fix clock name --- example/VCU108/fpga_10g/fpga.xdc | 2 +- example/VCU108/fpga_1g/fpga.xdc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/VCU108/fpga_10g/fpga.xdc b/example/VCU108/fpga_10g/fpga.xdc index 4ad1c74f3..be8bed33b 100644 --- a/example/VCU108/fpga_10g/fpga.xdc +++ b/example/VCU108/fpga_10g/fpga.xdc @@ -9,7 +9,7 @@ set_property CONFIG_VOLTAGE 1.8 [current_design] # 300 MHz #set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p] #set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n] -#create_clock -period 3.333 -name clk_300_mhz_1 [get_ports clk_300mhz_1_p] +#create_clock -period 3.333 -name clk_300mhz_1 [get_ports clk_300mhz_1_p] #set_clock_groups -asynchronous -group [get_clocks clk_300mhz_1 -include_generated_clocks] #set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p] diff --git a/example/VCU108/fpga_1g/fpga.xdc b/example/VCU108/fpga_1g/fpga.xdc index b7cc5658a..48a01e1c3 100644 --- a/example/VCU108/fpga_1g/fpga.xdc +++ b/example/VCU108/fpga_1g/fpga.xdc @@ -9,7 +9,7 @@ set_property CONFIG_VOLTAGE 1.8 [current_design] # 300 MHz #set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p] #set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n] -#create_clock -period 3.333 -name clk_300_mhz_1 [get_ports clk_300mhz_1_p] +#create_clock -period 3.333 -name clk_300mhz_1 [get_ports clk_300mhz_1_p] #set_clock_groups -asynchronous -group [get_clocks clk_300mhz_1 -include_generated_clocks] #set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p] From f4d7edf23f53192178c16c95e8140ec7539dc17a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 13 Jun 2018 14:33:07 -0700 Subject: [PATCH 384/617] Add VCU118 example design --- example/VCU118/fpga_1g/Makefile | 25 + example/VCU118/fpga_1g/README.md | 25 + example/VCU118/fpga_1g/common/vivado.mk | 118 ++++ example/VCU118/fpga_1g/fpga.xdc | 84 +++ example/VCU118/fpga_1g/fpga/Makefile | 61 ++ .../fpga_1g/ip/gig_ethernet_pcs_pma_0.xci | 142 +++++ example/VCU118/fpga_1g/lib/eth | 1 + example/VCU118/fpga_1g/rtl/debounce_switch.v | 89 +++ example/VCU118/fpga_1g/rtl/fpga.v | 570 +++++++++++++++++ example/VCU118/fpga_1g/rtl/fpga_core.v | 581 ++++++++++++++++++ example/VCU118/fpga_1g/rtl/mdio_master.v | 225 +++++++ example/VCU118/fpga_1g/rtl/sync_reset.v | 52 ++ example/VCU118/fpga_1g/rtl/sync_signal.v | 58 ++ example/VCU118/fpga_1g/tb/arp_ep.py | 1 + example/VCU118/fpga_1g/tb/axis_ep.py | 1 + example/VCU118/fpga_1g/tb/eth_ep.py | 1 + example/VCU118/fpga_1g/tb/gmii_ep.py | 1 + example/VCU118/fpga_1g/tb/ip_ep.py | 1 + example/VCU118/fpga_1g/tb/test_fpga_core.py | 315 ++++++++++ example/VCU118/fpga_1g/tb/test_fpga_core.v | 132 ++++ example/VCU118/fpga_1g/tb/udp_ep.py | 1 + 21 files changed, 2484 insertions(+) create mode 100644 example/VCU118/fpga_1g/Makefile create mode 100644 example/VCU118/fpga_1g/README.md create mode 100644 example/VCU118/fpga_1g/common/vivado.mk create mode 100644 example/VCU118/fpga_1g/fpga.xdc create mode 100644 example/VCU118/fpga_1g/fpga/Makefile create mode 100644 example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci create mode 120000 example/VCU118/fpga_1g/lib/eth create mode 100644 example/VCU118/fpga_1g/rtl/debounce_switch.v create mode 100644 example/VCU118/fpga_1g/rtl/fpga.v create mode 100644 example/VCU118/fpga_1g/rtl/fpga_core.v create mode 100644 example/VCU118/fpga_1g/rtl/mdio_master.v create mode 100644 example/VCU118/fpga_1g/rtl/sync_reset.v create mode 100644 example/VCU118/fpga_1g/rtl/sync_signal.v create mode 120000 example/VCU118/fpga_1g/tb/arp_ep.py create mode 120000 example/VCU118/fpga_1g/tb/axis_ep.py create mode 120000 example/VCU118/fpga_1g/tb/eth_ep.py create mode 120000 example/VCU118/fpga_1g/tb/gmii_ep.py create mode 120000 example/VCU118/fpga_1g/tb/ip_ep.py create mode 100755 example/VCU118/fpga_1g/tb/test_fpga_core.py create mode 100644 example/VCU118/fpga_1g/tb/test_fpga_core.v create mode 120000 example/VCU118/fpga_1g/tb/udp_ep.py diff --git a/example/VCU118/fpga_1g/Makefile b/example/VCU118/fpga_1g/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/VCU118/fpga_1g/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/VCU118/fpga_1g/README.md b/example/VCU118/fpga_1g/README.md new file mode 100644 index 000000000..66172f75f --- /dev/null +++ b/example/VCU118/fpga_1g/README.md @@ -0,0 +1,25 @@ +# Verilog Ethernet VCU118 Example Design + +## Introduction + +This example design targets the Xilinx VCU118 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +FPGA: xcvu9p-flga2104-2L-e +PHY: TI DP83867ISRGZ + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the VCU108 board with Vivado. Then run +netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any text +entered into netcat will be echoed back after pressing enter. + + diff --git a/example/VCU118/fpga_1g/common/vivado.mk b/example/VCU118/fpga_1g/common/vivado.mk new file mode 100644 index 000000000..a54b530f6 --- /dev/null +++ b/example/VCU118/fpga_1g/common/vivado.mk @@ -0,0 +1,118 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile $(XCI_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/VCU118/fpga_1g/fpga.xdc b/example/VCU118/fpga_1g/fpga.xdc new file mode 100644 index 000000000..fd556e8e8 --- /dev/null +++ b/example/VCU118/fpga_1g/fpga.xdc @@ -0,0 +1,84 @@ +# XDC constraints for the Xilinx VCU118 board +# part: xcvu9p-flga2104-2L-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] + +# System clocks +# 300 MHz +#set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_p] +#set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_n] +#create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p] +#set_clock_groups -asynchronous -group [get_clocks clk_300mhz -include_generated_clocks] + +# 250 MHz +#set_property -dict {LOC E12 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_1_p] +#set_property -dict {LOC D12 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_1_n] +#create_clock -period 4 -name clk_250mhz_1 [get_ports clk_250mhz_1_p] +#set_clock_groups -asynchronous -group [get_clocks clk_250mhz_1 -include_generated_clocks] + +#set_property -dict {LOC AW26 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_2_p] +#set_property -dict {LOC AW27 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_2_n] +#create_clock -period 4 -name clk_250mhz_2 [get_ports clk_250mhz_2_p] +#set_clock_groups -asynchronous -group [get_clocks clk_250mhz_2 -include_generated_clocks] + +# 125 MHz +set_property -dict {LOC AY24 IOSTANDARD LVDS} [get_ports clk_125mhz_p] +set_property -dict {LOC AY23 IOSTANDARD LVDS} [get_ports clk_125mhz_n] +create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] +set_clock_groups -asynchronous -group [get_clocks clk_125mhz -include_generated_clocks] + +# 90 MHz +#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] +#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] +#set_clock_groups -asynchronous -group [get_clocks clk_90mhz -include_generated_clocks] + +# LEDs +set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] +set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}] +set_property -dict {LOC AY30 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}] +set_property -dict {LOC BB32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[3]}] +set_property -dict {LOC BF32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[4]}] +set_property -dict {LOC AU37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[5]}] +set_property -dict {LOC AV36 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[6]}] +set_property -dict {LOC BA37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[7]}] + +# Reset button +set_property -dict {LOC L19 IOSTANDARD LVCMOS12} [get_ports reset] + +# Push buttons +set_property -dict {LOC BB24 IOSTANDARD LVCMOS18} [get_ports btnu] +set_property -dict {LOC BF22 IOSTANDARD LVCMOS18} [get_ports btnl] +set_property -dict {LOC BE22 IOSTANDARD LVCMOS18} [get_ports btnd] +set_property -dict {LOC BE23 IOSTANDARD LVCMOS18} [get_ports btnr] +set_property -dict {LOC BD23 IOSTANDARD LVCMOS18} [get_ports btnc] + +# DIP switches +set_property -dict {LOC B17 IOSTANDARD LVCMOS12} [get_ports {sw[0]}] +set_property -dict {LOC G16 IOSTANDARD LVCMOS12} [get_ports {sw[1]}] +set_property -dict {LOC J16 IOSTANDARD LVCMOS12} [get_ports {sw[2]}] +set_property -dict {LOC D21 IOSTANDARD LVCMOS12} [get_ports {sw[3]}] + +# UART +set_property -dict {LOC BB21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] +set_property -dict {LOC AW25 IOSTANDARD LVCMOS18} [get_ports uart_rxd] +set_property -dict {LOC BB22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_rts] +set_property -dict {LOC AY25 IOSTANDARD LVCMOS18} [get_ports uart_cts] + +# Gigabit Ethernet SGMII PHY +set_property -dict {LOC AU24 IOSTANDARD LVDS} [get_ports phy_sgmii_rx_p] +set_property -dict {LOC AV24 IOSTANDARD LVDS} [get_ports phy_sgmii_rx_n] +set_property -dict {LOC AU21 IOSTANDARD LVDS} [get_ports phy_sgmii_tx_p] +set_property -dict {LOC AV21 IOSTANDARD LVDS} [get_ports phy_sgmii_tx_n] +set_property -dict {LOC AT22 IOSTANDARD LVDS} [get_ports phy_sgmii_clk_p] +set_property -dict {LOC AU22 IOSTANDARD LVDS} [get_ports phy_sgmii_clk_n] +set_property -dict {LOC BA21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_reset_n] +set_property -dict {LOC AR24 IOSTANDARD LVCMOS18} [get_ports phy_int_n] +set_property -dict {LOC AR23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdio] +set_property -dict {LOC AV23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc] + +# 625 MHz ref clock from SGMII PHY +#create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] +#set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generated_clocks] + diff --git a/example/VCU118/fpga_1g/fpga/Makefile b/example/VCU118/fpga_1g/fpga/Makefile new file mode 100644 index 000000000..d97bfee7a --- /dev/null +++ b/example/VCU118/fpga_1g/fpga/Makefile @@ -0,0 +1,61 @@ + +# FPGA settings +FPGA_PART = xcvu9p-flga2104-2l-e +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/mdio_master.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v +SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v +SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v + +# XDC files +XDC_FILES = fpga.xdc + +# IP +XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl + echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "exit" >> program.tcl + vivado -mode batch -source program.tcl + diff --git a/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci new file mode 100644 index 000000000..c23253498 --- /dev/null +++ b/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci @@ -0,0 +1,142 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gig_ethernet_pcs_pma_0 + + + true + 0 + 0 + true + false + DIFF_PAIR_0 + DIFF_PAIR_1 + false + DIFF_PAIR_2 + DIFF_PAIR_1 + virtexuplus + Sync + gig_ethernet_pcs_pma_0 + 50.0 + false + . + true + false + false + true + virtexuplus + 16 + 10 + X0Y4 + 8 + 5 + GTH + false + true + false + false + false + true + 1 + clk0 + 125 + TXOUTCLK + true + false + gig_ethernet_pcs_pma_0_gt + true + GTHE4 + false + 0 + true + false + false + xcvu9p + false + 1 + true + Sync + gig_ethernet_pcs_pma_0 + Custom + 50.0 + TEMAC + Custom + 0 + false + false + false + false + X0Y4 + GTH + false + false + 625 + Custom + false + 1G + 1 + LVDS + 125 + clk0 + TXOUTCLK + DIFF_PAIR_0 + DIFF_PAIR_1 + false + 10_100_1000 + false + SGMII + Include_Shared_Logic_in_Core + Time_of_day + false + DIFF_PAIR_2 + DIFF_PAIR_1 + 0 + false + virtexuplus + + xcvu9p + flga2104 + VERILOG + + MIXED + -2L + E + TRUE + TRUE + IP_Flow + 0 + TRUE + . + + . + 2017.2.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/VCU118/fpga_1g/lib/eth b/example/VCU118/fpga_1g/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/VCU118/fpga_1g/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/VCU118/fpga_1g/rtl/debounce_switch.v b/example/VCU118/fpga_1g/rtl/debounce_switch.v new file mode 100644 index 000000000..bb631cc35 --- /dev/null +++ b/example/VCU118/fpga_1g/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/VCU118/fpga_1g/rtl/fpga.v b/example/VCU118/fpga_1g/rtl/fpga.v new file mode 100644 index 000000000..bf3c095c8 --- /dev/null +++ b/example/VCU118/fpga_1g/rtl/fpga.v @@ -0,0 +1,570 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 125MHz LVDS + * Reset: Push button, active low + */ + input wire clk_125mhz_p, + input wire clk_125mhz_n, + input wire reset, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_sgmii_rx_p, + input wire phy_sgmii_rx_n, + output wire phy_sgmii_tx_p, + output wire phy_sgmii_tx_n, + input wire phy_sgmii_clk_p, + input wire phy_sgmii_clk_n, + output wire phy_reset_n, + input wire phy_int_n, + inout wire phy_mdio, + output wire phy_mdc, + + /* + * UART: 500000 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// Clock and reset + +wire clk_125mhz_ibufg; +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +wire mmcm_rst = reset; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS #( + .DIFF_TERM("FALSE"), + .IBUF_LOW_PWR("FALSE") +) +clk_125mhz_ibufg_inst ( + .O (clk_125mhz_ibufg), + .I (clk_125mhz_p), + .IB (clk_125mhz_n) +); + +// MMCM instance +// 125 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 8, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCME3_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(8), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(8.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_125mhz_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [3:0] sw_int; + +debounce_switch #( + .WIDTH(9), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +wire uart_rxd_int; +wire uart_cts_int; + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(clk_125mhz_int), + .in({uart_rxd, uart_cts}), + .out({uart_rxd_int, uart_cts_int}) +); + +// SGMII interface to PHY +wire phy_gmii_clk_int; +wire phy_gmii_rst_int; +wire phy_gmii_clk_en_int; +wire [7:0] phy_gmii_txd_int; +wire phy_gmii_tx_en_int; +wire phy_gmii_tx_er_int; +wire [7:0] phy_gmii_rxd_int; +wire phy_gmii_rx_dv_int; +wire phy_gmii_rx_er_int; + +wire [15:0] pcspma_status_vector; + +wire pcspma_status_link_status = pcspma_status_vector[0]; +wire pcspma_status_link_synchronization = pcspma_status_vector[1]; +wire pcspma_status_rudi_c = pcspma_status_vector[2]; +wire pcspma_status_rudi_i = pcspma_status_vector[3]; +wire pcspma_status_rudi_invalid = pcspma_status_vector[4]; +wire pcspma_status_rxdisperr = pcspma_status_vector[5]; +wire pcspma_status_rxnotintable = pcspma_status_vector[6]; +wire pcspma_status_phy_link_status = pcspma_status_vector[7]; +wire [1:0] pcspma_status_remote_fault_encdg = pcspma_status_vector[9:8]; +wire [1:0] pcspma_status_speed = pcspma_status_vector[11:10]; +wire pcspma_status_duplex = pcspma_status_vector[12]; +wire pcspma_status_remote_fault = pcspma_status_vector[13]; +wire [1:0] pcspma_status_pause = pcspma_status_vector[15:14]; + +wire [4:0] pcspma_config_vector; + +assign pcspma_config_vector[4] = 1'b1; // autonegotiation enable +assign pcspma_config_vector[3] = 1'b0; // isolate +assign pcspma_config_vector[2] = 1'b0; // power down +assign pcspma_config_vector[1] = 1'b0; // loopback enable +assign pcspma_config_vector[0] = 1'b0; // unidirectional enable + +wire [15:0] pcspma_an_config_vector; + +assign pcspma_an_config_vector[15] = 1'b1; // SGMII link status +assign pcspma_an_config_vector[14] = 1'b1; // SGMII Acknowledge +assign pcspma_an_config_vector[13:12] = 2'b01; // full duplex +assign pcspma_an_config_vector[11:10] = 2'b10; // SGMII speed +assign pcspma_an_config_vector[9] = 1'b0; // reserved +assign pcspma_an_config_vector[8:7] = 2'b00; // pause frames - SGMII reserved +assign pcspma_an_config_vector[6] = 1'b0; // reserved +assign pcspma_an_config_vector[5] = 1'b0; // full duplex - SGMII reserved +assign pcspma_an_config_vector[4:1] = 4'b0000; // reserved +assign pcspma_an_config_vector[0] = 1'b1; // SGMII + +gig_ethernet_pcs_pma_0 +eth_pcspma ( + // SGMII + .txp_0 (phy_sgmii_tx_p), + .txn_0 (phy_sgmii_tx_n), + .rxp_0 (phy_sgmii_rx_p), + .rxn_0 (phy_sgmii_rx_n), + + // Ref clock from PHY + .refclk625_p (phy_sgmii_clk_p), + .refclk625_n (phy_sgmii_clk_n), + + // async reset + .reset (rst_125mhz_int), + + // clock and reset outputs + .clk125_out (phy_gmii_clk_int), + .clk312_out (), + .rst_125_out (phy_gmii_rst_int), + .tx_logic_reset (), + .rx_logic_reset (), + .tx_locked (), + .rx_locked (), + .tx_pll_clk_out (), + .rx_pll_clk_out (), + + // MAC clocking + .sgmii_clk_r_0 (), + .sgmii_clk_f_0 (), + .sgmii_clk_en_0 (phy_gmii_clk_en_int), + + // Speed control + .speed_is_10_100_0 (pcspma_status_speed != 2'b10), + .speed_is_100_0 (pcspma_status_speed == 2'b01), + + // Internal GMII + .gmii_txd_0 (phy_gmii_txd_int), + .gmii_tx_en_0 (phy_gmii_tx_en_int), + .gmii_tx_er_0 (phy_gmii_tx_er_int), + .gmii_rxd_0 (phy_gmii_rxd_int), + .gmii_rx_dv_0 (phy_gmii_rx_dv_int), + .gmii_rx_er_0 (phy_gmii_rx_er_int), + .gmii_isolate_0 (), + + // Configuration + .configuration_vector_0 (pcspma_config_vector), + + .an_interrupt_0 (), + .an_adv_config_vector_0 (pcspma_an_config_vector), + .an_restart_config_0 (1'b0), + + // Status + .status_vector_0 (pcspma_status_vector), + .signal_detect_0 (1'b1), + + // Cascade + .tx_bsc_rst_out (), + .rx_bsc_rst_out (), + .tx_bs_rst_out (), + .rx_bs_rst_out (), + .tx_rst_dly_out (), + .rx_rst_dly_out (), + .tx_bsc_en_vtc_out (), + .rx_bsc_en_vtc_out (), + .tx_bs_en_vtc_out (), + .rx_bs_en_vtc_out (), + .riu_clk_out (), + .riu_addr_out (), + .riu_wr_data_out (), + .riu_wr_en_out (), + .riu_nibble_sel_out (), + .riu_rddata_1 (16'b0), + .riu_valid_1 (1'b0), + .riu_prsnt_1 (1'b0), + .riu_rddata_2 (16'b0), + .riu_valid_2 (1'b0), + .riu_prsnt_2 (1'b0), + .riu_rddata_3 (16'b0), + .riu_valid_3 (1'b0), + .riu_prsnt_3 (1'b0), + .rx_btval_1 (), + .rx_btval_2 (), + .rx_btval_3 (), + .tx_dly_rdy_1 (1'b1), + .rx_dly_rdy_1 (1'b1), + .rx_vtc_rdy_1 (1'b1), + .tx_vtc_rdy_1 (1'b1), + .tx_dly_rdy_2 (1'b1), + .rx_dly_rdy_2 (1'b1), + .rx_vtc_rdy_2 (1'b1), + .tx_vtc_rdy_2 (1'b1), + .tx_dly_rdy_3 (1'b1), + .rx_dly_rdy_3 (1'b1), + .rx_vtc_rdy_3 (1'b1), + .tx_vtc_rdy_3 (1'b1), + .tx_rdclk_out () +); + +reg [19:0] delay_reg = 20'hfffff; + +reg [4:0] mdio_cmd_phy_addr = 5'h03; +reg [4:0] mdio_cmd_reg_addr = 5'h00; +reg [15:0] mdio_cmd_data = 16'd0; +reg [1:0] mdio_cmd_opcode = 2'b01; +reg mdio_cmd_valid = 1'b0; +wire mdio_cmd_ready; + +reg [3:0] state_reg = 0; + +always @(posedge clk_125mhz_int) begin + if (rst_125mhz_int) begin + state_reg <= 0; + delay_reg <= 20'hfffff; + mdio_cmd_reg_addr <= 5'h00; + mdio_cmd_data <= 16'd0; + mdio_cmd_valid <= 1'b0; + end else begin + mdio_cmd_valid <= mdio_cmd_valid & !mdio_cmd_ready; + if (delay_reg > 0) begin + delay_reg <= delay_reg - 1; + end else if (!mdio_cmd_ready) begin + // wait for ready + state_reg <= state_reg; + end else begin + mdio_cmd_valid <= 1'b0; + case (state_reg) + // set SGMII autonegotiation timer to 11 ms + // write 0x0070 to CFG4 (0x0031) + 4'd0: begin + // write to REGCR to load address + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h001F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd1; + end + 4'd1: begin + // write address of CFG4 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h0031; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd2; + end + 4'd2: begin + // write to REGCR to load data + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h401F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd3; + end + 4'd3: begin + // write data for CFG4 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h0070; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd4; + end + // enable SGMII clock output + // write 0x4000 to SGMIICTL1 (0x00D3) + 4'd4: begin + // write to REGCR to load address + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h001F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd5; + end + 4'd5: begin + // write address of SGMIICTL1 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h00D3; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd6; + end + 4'd6: begin + // write to REGCR to load data + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h401F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd7; + end + 4'd7: begin + // write data for SGMIICTL1 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h4000; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd8; + end + // enable 10Mbps operation + // write 0x0015 to 10M_SGMII_CFG (0x016F) + 4'd8: begin + // write to REGCR to load address + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h001F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd9; + end + 4'd9: begin + // write address of 10M_SGMII_CFG to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h016F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd10; + end + 4'd10: begin + // write to REGCR to load data + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h401F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd11; + end + 4'd11: begin + // write data for 10M_SGMII_CFG to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h0015; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd12; + end + 4'd12: begin + // done + state_reg <= 4'd12; + end + endcase + end + end +end + +wire mdc; +wire mdio_i; +wire mdio_o; +wire mdio_t; + +mdio_master +mdio_master_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + + .cmd_phy_addr(mdio_cmd_phy_addr), + .cmd_reg_addr(mdio_cmd_reg_addr), + .cmd_data(mdio_cmd_data), + .cmd_opcode(mdio_cmd_opcode), + .cmd_valid(mdio_cmd_valid), + .cmd_ready(mdio_cmd_ready), + + .data_out(), + .data_out_valid(), + .data_out_ready(1'b1), + + .mdc_o(mdc), + .mdio_i(mdio_i), + .mdio_o(mdio_o), + .mdio_t(mdio_t), + + .busy(), + + .prescale(8'd3) +); + +assign phy_mdc = mdc; +assign mdio_i = phy_mdio; +assign phy_mdio = mdio_t ? 1'bz : mdio_o; + +wire [7:0] led_int; + +// SGMII interface debug: +// SW12:4 (sw[0]) off for payload byte, on for status vector +// SW12:3 (sw[1]) off for LSB of status vector, on for MSB +assign led = sw[0] ? (sw[1] ? pcspma_status_vector[15:8] : pcspma_status_vector[7:0]) : led_int; + +fpga_core +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .led(led_int), + /* + * Ethernet: 1000BASE-T SGMII + */ + .phy_gmii_clk(phy_gmii_clk_int), + .phy_gmii_rst(phy_gmii_rst_int), + .phy_gmii_clk_en(phy_gmii_clk_en_int), + .phy_gmii_rxd(phy_gmii_rxd_int), + .phy_gmii_rx_dv(phy_gmii_rx_dv_int), + .phy_gmii_rx_er(phy_gmii_rx_er_int), + .phy_gmii_txd(phy_gmii_txd_int), + .phy_gmii_tx_en(phy_gmii_tx_en_int), + .phy_gmii_tx_er(phy_gmii_tx_er_int), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts_int) +); + +endmodule diff --git a/example/VCU118/fpga_1g/rtl/fpga_core.v b/example/VCU118/fpga_1g/rtl/fpga_core.v new file mode 100644 index 000000000..e8ad51b27 --- /dev/null +++ b/example/VCU118/fpga_1g/rtl/fpga_core.v @@ -0,0 +1,581 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA core logic + */ +module fpga_core +( + /* + * Clock: 125MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_gmii_clk, + input wire phy_gmii_rst, + input wire phy_gmii_clk_en, + input wire [7:0] phy_gmii_rxd, + input wire phy_gmii_rx_dv, + input wire phy_gmii_rx_er, + output wire [7:0] phy_gmii_txd, + output wire phy_gmii_tx_en, + output wire phy_gmii_tx_er, + output wire phy_reset_n, + input wire phy_int_n, + + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// AXI between MAC and Ethernet modules +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [7:0] tx_axis_tdata; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [7:0] rx_eth_payload_tdata; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [7:0] tx_eth_payload_tdata; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [7:0] rx_ip_payload_tdata; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [7:0] tx_ip_payload_tdata; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [7:0] rx_udp_payload_tdata; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_tdata; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [7:0] rx_fifo_udp_payload_tdata; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [7:0] tx_fifo_udp_payload_tdata; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + if (tx_udp_payload_tvalid) begin + if (~valid_last) begin + led_reg <= tx_udp_payload_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_tlast) begin + valid_last <= 1'b0; + end + end + end +end + +//assign led = sw; +assign led = led_reg; +assign phy_reset_n = ~rst; + +assign uart_txd = 0; +assign uart_rts = 0; + +eth_mac_1g_fifo #( + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .RX_FIFO_ADDR_WIDTH(12) +) +eth_mac_inst ( + .rx_clk(phy_gmii_clk), + .rx_rst(phy_gmii_rst), + .tx_clk(phy_gmii_clk), + .tx_rst(phy_gmii_rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .gmii_rxd(phy_gmii_rxd), + .gmii_rx_dv(phy_gmii_rx_dv), + .gmii_rx_er(phy_gmii_rx_er), + .gmii_txd(phy_gmii_txd), + .gmii_tx_en(phy_gmii_tx_en), + .gmii_tx_er(phy_gmii_tx_er), + + .rx_clk_enable(phy_gmii_clk_en), + .tx_clk_enable(phy_gmii_clk_en), + .rx_mii_select(1'b0), + .tx_mii_select(1'b0), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + .ifg_delay(12) +); + +eth_axis_rx +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(0) +); + +axis_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(0), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/VCU118/fpga_1g/rtl/mdio_master.v b/example/VCU118/fpga_1g/rtl/mdio_master.v new file mode 100644 index 000000000..1dc56a8cf --- /dev/null +++ b/example/VCU118/fpga_1g/rtl/mdio_master.v @@ -0,0 +1,225 @@ +/* + +Copyright (c) 2015-2018 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 + +/* + * MDIO master + */ +module mdio_master ( + input wire clk, + input wire rst, + + /* + * Host interface + */ + input wire [4:0] cmd_phy_addr, + input wire [4:0] cmd_reg_addr, + input wire [15:0] cmd_data, + input wire [1:0] cmd_opcode, + input wire cmd_valid, + output wire cmd_ready, + + output wire [15:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + + /* + * MDIO to PHY + */ + output wire mdc_o, + input wire mdio_i, + output wire mdio_o, + output wire mdio_t, + + /* + * Status + */ + output wire busy, + + /* + * Configuration + */ + input wire [7:0] prescale +); + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PREAMBLE = 2'd1, + STATE_TRANSFER = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [16:0] count_reg = 16'd0, count_next; +reg [6:0] bit_count_reg = 6'd0, bit_count_next; +reg cycle_reg = 1'b0, cycle_next; + +reg [31:0] data_reg = 32'd0, data_next; + +reg [1:0] op_reg = 2'b00, op_next; + +reg cmd_ready_reg = 1'b0, cmd_ready_next; + +reg [15:0] data_out_reg = 15'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; + +reg mdio_i_reg = 1'b1; + +reg mdc_o_reg = 1'b0, mdc_o_next; +reg mdio_o_reg = 1'b0, mdio_o_next; +reg mdio_t_reg = 1'b1, mdio_t_next; + +reg busy_reg = 1'b0; + +assign cmd_ready = cmd_ready_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; + +assign mdc_o = mdc_o_reg; +assign mdio_o = mdio_o_reg; +assign mdio_t = mdio_t_reg; + +assign busy = busy_reg; + +always @* begin + state_next = STATE_IDLE; + + count_next = count_reg; + bit_count_next = bit_count_reg; + cycle_next = cycle_reg; + + data_next = data_reg; + + op_next = op_reg; + + cmd_ready_next = 1'b0; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + + mdc_o_next = mdc_o_reg; + mdio_o_next = mdio_o_reg; + mdio_t_next = mdio_t_reg; + + if (count_reg > 16'd0) begin + count_next = count_reg - 16'd1; + state_next = state_reg; + end else if (cycle_reg) begin + cycle_next = 1'b0; + mdc_o_next = 1'b1; + count_next = prescale; + state_next = state_reg; + end else begin + mdc_o_next = 1'b0; + case (state_reg) + STATE_IDLE: begin + // idle - accept new command + cmd_ready_next = ~data_out_valid; + + if (cmd_ready & cmd_valid) begin + cmd_ready_next = 1'b0; + data_next = {2'b01, cmd_opcode, cmd_phy_addr, cmd_reg_addr, 2'b10, cmd_data}; + op_next = cmd_opcode; + mdio_t_next = 1'b0; + mdio_o_next = 1'b1; + bit_count_next = 6'd32; + cycle_next = 1'b1; + count_next = prescale; + state_next = STATE_PREAMBLE; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PREAMBLE: begin + cycle_next = 1'b1; + count_next = prescale; + if (bit_count_reg > 6'd1) begin + bit_count_next = bit_count_reg - 6'd1; + state_next = STATE_PREAMBLE; + end else begin + bit_count_next = 6'd32; + {mdio_o_next, data_next} = {data_reg, mdio_i_reg}; + state_next = STATE_TRANSFER; + end + end + STATE_TRANSFER: begin + cycle_next = 1'b1; + count_next = prescale; + if ((op_reg == 2'b10 || op_reg == 2'b11) && bit_count_reg == 6'd19) begin + mdio_t_next = 1'b1; + end + if (bit_count_reg > 6'd1) begin + bit_count_next = bit_count_reg - 6'd1; + {mdio_o_next, data_next} = {data_reg, mdio_i_reg}; + state_next = STATE_TRANSFER; + end else begin + if (op_reg == 2'b10 || op_reg == 2'b11) begin + data_out_next = data_reg[15:0]; + data_out_valid_next = 1'b1; + end + mdio_t_next = 1'b1; + state_next = STATE_IDLE; + end + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + count_reg <= 16'd0; + bit_count_reg <= 6'd0; + cycle_reg <= 1'b0; + cmd_ready_reg <= 1'b0; + data_out_valid_reg <= 1'b0; + mdc_o_reg <= 1'b0; + mdio_o_reg <= 1'b0; + mdio_t_reg <= 1'b1; + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + count_reg <= count_next; + bit_count_reg <= bit_count_next; + cycle_reg <= cycle_next; + cmd_ready_reg <= cmd_ready_next; + data_out_valid_reg <= data_out_valid_next; + mdc_o_reg <= mdc_o_next; + mdio_o_reg <= mdio_o_next; + mdio_t_reg <= mdio_t_next; + busy_reg <= (state_next != STATE_IDLE || count_reg != 0 || cycle_reg || mdc_o); + end + + data_reg <= data_next; + op_reg <= op_next; + + data_out_reg <= data_out_next; + + mdio_i_reg <= mdio_i; +end + +endmodule diff --git a/example/VCU118/fpga_1g/rtl/sync_reset.v b/example/VCU118/fpga_1g/rtl/sync_reset.v new file mode 100644 index 000000000..acbcf1c6e --- /dev/null +++ b/example/VCU118/fpga_1g/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/VCU118/fpga_1g/rtl/sync_signal.v b/example/VCU118/fpga_1g/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/example/VCU118/fpga_1g/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/VCU118/fpga_1g/tb/arp_ep.py b/example/VCU118/fpga_1g/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/VCU118/fpga_1g/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_1g/tb/axis_ep.py b/example/VCU118/fpga_1g/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/VCU118/fpga_1g/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_1g/tb/eth_ep.py b/example/VCU118/fpga_1g/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/VCU118/fpga_1g/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_1g/tb/gmii_ep.py b/example/VCU118/fpga_1g/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/VCU118/fpga_1g/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_1g/tb/ip_ep.py b/example/VCU118/fpga_1g/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/VCU118/fpga_1g/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_1g/tb/test_fpga_core.py b/example/VCU118/fpga_1g/tb/test_fpga_core.py new file mode 100755 index 000000000..0302962b2 --- /dev/null +++ b/example/VCU118/fpga_1g/tb/test_fpga_core.py @@ -0,0 +1,315 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2018 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 + +import eth_ep +import arp_ep +import udp_ep +import gmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen.v") +srcs.append("../lib/eth/rtl/udp.v") +srcs.append("../lib/eth/rtl/udp_ip_rx.v") +srcs.append("../lib/eth/rtl/udp_ip_tx.v") +srcs.append("../lib/eth/rtl/ip_complete.v") +srcs.append("../lib/eth/rtl/ip.v") +srcs.append("../lib/eth/rtl/ip_eth_rx.v") +srcs.append("../lib/eth/rtl/ip_eth_tx.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") +srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") +srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[4:]) + phy_gmii_clk = Signal(bool(0)) + phy_gmii_rst = Signal(bool(0)) + phy_gmii_clk_en = Signal(bool(0)) + phy_gmii_rxd = Signal(intbv(0)[8:]) + phy_gmii_rx_dv = Signal(bool(0)) + phy_gmii_rx_er = Signal(bool(0)) + phy_int_n = Signal(bool(1)) + uart_rxd = Signal(bool(0)) + uart_cts = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[8:]) + phy_gmii_txd = Signal(intbv(0)[8:]) + phy_gmii_tx_en = Signal(bool(0)) + phy_gmii_tx_er = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + + # sources and sinks + gmii_source = gmii_ep.GMIISource() + + gmii_source_logic = gmii_source.create_logic( + phy_gmii_clk, + phy_gmii_rst, + txd=phy_gmii_rxd, + tx_en=phy_gmii_rx_dv, + tx_er=phy_gmii_rx_er, + clk_enable=phy_gmii_clk_en, + name='gmii_source' + ) + + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + phy_gmii_clk, + phy_gmii_rst, + rxd=phy_gmii_txd, + rx_dv=phy_gmii_tx_en, + rx_er=phy_gmii_tx_er, + clk_enable=phy_gmii_clk_en, + name='gmii_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, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, + + phy_gmii_clk=phy_gmii_clk, + phy_gmii_rst=phy_gmii_rst, + phy_gmii_clk_en=phy_gmii_clk_en, + phy_gmii_rxd=phy_gmii_rxd, + phy_gmii_rx_dv=phy_gmii_rx_dv, + phy_gmii_rx_er=phy_gmii_rx_er, + phy_gmii_txd=phy_gmii_txd, + phy_gmii_tx_en=phy_gmii_tx_en, + phy_gmii_tx_er=phy_gmii_tx_er, + phy_reset_n=phy_reset_n, + phy_int_n=phy_int_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + phy_gmii_clk.next = not phy_gmii_clk + + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @always(clk.posedge) + def clk_enable_gen(): + if clk_enable_div.next > 0: + phy_gmii_clk_en.next = 0 + clk_enable_div.next = clk_enable_div - 1 + else: + phy_gmii_clk_en.next = 1 + clk_enable_div.next = clk_enable_rate - 1 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + phy_gmii_rst.next = 1 + yield clk.posedge + rst.next = 0 + phy_gmii_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source.empty() + assert gmii_sink.empty() + + yield delay(100) + + raise StopSimulation + + return dut, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/VCU118/fpga_1g/tb/test_fpga_core.v b/example/VCU118/fpga_1g/tb/test_fpga_core.v new file mode 100644 index 000000000..aa29c4011 --- /dev/null +++ b/example/VCU118/fpga_1g/tb/test_fpga_core.v @@ -0,0 +1,132 @@ +/* + +Copyright (c) 2015-2018 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [3:0] sw = 0; +reg phy_gmii_clk = 0; +reg phy_gmii_rst = 0; +reg phy_gmii_clk_en = 0; +reg [7:0] phy_gmii_rxd = 0; +reg phy_gmii_rx_dv = 0; +reg phy_gmii_rx_er = 0; +reg phy_int_n = 1; +reg uart_rxd = 0; +reg uart_cts = 0; + +// Outputs +wire [7:0] led; +wire phy_tx_clk; +wire [7:0] phy_gmii_txd; +wire phy_gmii_tx_en; +wire phy_gmii_tx_er; +wire phy_reset_n; +wire uart_txd; +wire uart_rts; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_clk_en, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_int_n, + uart_rxd, + uart_cts + ); + $to_myhdl( + led, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + uart_txd, + uart_rts + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .phy_gmii_clk(phy_gmii_clk), + .phy_gmii_rst(phy_gmii_rst), + .phy_gmii_clk_en(phy_gmii_clk_en), + .phy_gmii_rxd(phy_gmii_rxd), + .phy_gmii_rx_dv(phy_gmii_rx_dv), + .phy_gmii_rx_er(phy_gmii_rx_er), + .phy_gmii_txd(phy_gmii_txd), + .phy_gmii_tx_en(phy_gmii_tx_en), + .phy_gmii_tx_er(phy_gmii_tx_er), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts) +); + +endmodule diff --git a/example/VCU118/fpga_1g/tb/udp_ep.py b/example/VCU118/fpga_1g/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/VCU118/fpga_1g/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file From 05c674347385d149b9576ab0f1f92b314cdbb308 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 13 Jun 2018 19:18:59 -0700 Subject: [PATCH 385/617] Update xdc --- example/VCU118/fpga_1g/fpga.xdc | 71 ++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/example/VCU118/fpga_1g/fpga.xdc b/example/VCU118/fpga_1g/fpga.xdc index fd556e8e8..5d3f614b2 100644 --- a/example/VCU118/fpga_1g/fpga.xdc +++ b/example/VCU118/fpga_1g/fpga.xdc @@ -79,6 +79,73 @@ set_property -dict {LOC AR23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports p set_property -dict {LOC AV23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc] # 625 MHz ref clock from SGMII PHY -#create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] -#set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generated_clocks] +create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] +set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generated_clocks] + +# QSFP28 Interfaces +#set_property -dict {LOC V7 } [get_ports qsfp1_tx1_p] ;# MGTYTXN0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC V6 } [get_ports qsfp1_tx1_n] ;# MGTYTXP0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC Y2 } [get_ports qsfp1_rx1_p] ;# MGTYTXN1_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC Y1 } [get_ports qsfp1_rx1_n] ;# MGTYTXP1_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC T7 } [get_ports qsfp1_tx2_p] ;# MGTYTXN2_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXP2_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC W4 } [get_ports qsfp1_rx2_p] ;# MGTYTXN3_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC W3 } [get_ports qsfp1_rx2_n] ;# MGTYTXP3_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC P7 } [get_ports qsfp1_tx3_p] ;# MGTYTXN0_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC P6 } [get_ports qsfp1_tx3_n] ;# MGTYTXP0_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC V2 } [get_ports qsfp1_rx3_p] ;# MGTYTXN1_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC V1 } [get_ports qsfp1_rx3_n] ;# MGTYTXP1_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC M7 } [get_ports qsfp1_tx4_p] ;# MGTYTXN2_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC M6 } [get_ports qsfp1_tx4_n] ;# MGTYTXP2_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC U4 } [get_ports qsfp1_rx4_p] ;# MGTYTXN3_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC U3 } [get_ports qsfp1_rx4_n] ;# MGTYTXP3_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC W9 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_231 from U38.4 +#set_property -dict {LOC W8 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_231 from U38.5 +#set_property -dict {LOC U9 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_231 from U57.28 +#set_property -dict {LOC U8 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U57.29 +#set_property -dict {LOC AM23 IOSTANDARD LVDS} [get_ports qsfp1_recclk_p] ;# to U57.16 +#set_property -dict {LOC AM22 IOSTANDARD LVDS} [get_ports qsfp1_recclk_n] ;# to U57.17 +#set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modesell] +#set_property -dict {LOC BA22 IOSTANDARD LVCMOS18} [get_ports qsfp1_resetl] +#set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modprsl] +#set_property -dict {LOC AP21 IOSTANDARD LVCMOS18} [get_ports qsfp1_intl] +#set_property -dict {LOC AN21 IOSTANDARD LVCMOS18} [get_ports qsfp1_lpmode] + +#create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p] +#set_clock_groups -asynchronous -group [get_clocks qsfp1_mgt_refclk_0 -include_generated_clocks] + +#set_property -dict {LOC L5 } [get_ports qsfp2_tx1_p] ;# MGTYTXN0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC L4 } [get_ports qsfp2_tx1_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC T2 } [get_ports qsfp2_rx1_p] ;# MGTYTXN1_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC T1 } [get_ports qsfp2_rx1_n] ;# MGTYTXP1_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC K7 } [get_ports qsfp2_tx2_p] ;# MGTYTXN2_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC K6 } [get_ports qsfp2_tx2_n] ;# MGTYTXP2_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC R4 } [get_ports qsfp2_rx2_p] ;# MGTYTXN3_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC R3 } [get_ports qsfp2_rx2_n] ;# MGTYTXP3_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC J5 } [get_ports qsfp2_tx3_p] ;# MGTYTXN0_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC J4 } [get_ports qsfp2_tx3_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC P2 } [get_ports qsfp2_rx3_p] ;# MGTYTXN1_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC P1 } [get_ports qsfp2_rx3_n] ;# MGTYTXP1_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC H7 } [get_ports qsfp2_tx4_p] ;# MGTYTXN2_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC H6 } [get_ports qsfp2_tx4_n] ;# MGTYTXP2_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC M2 } [get_ports qsfp2_rx4_p] ;# MGTYTXN3_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC M1 } [get_ports qsfp2_rx4_n] ;# MGTYTXP3_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC R9 } [get_ports qsfp2_mgt_refclk_0_p] ;# MGTREFCLK0P_232 from U104.13 +#set_property -dict {LOC R8 } [get_ports qsfp2_mgt_refclk_0_n] ;# MGTREFCLK0N_232 from U104.14 +#set_property -dict {LOC N9 } [get_ports qsfp2_mgt_refclk_1_p] ;# MGTREFCLK1P_232 from U57.35 +#set_property -dict {LOC N8 } [get_ports qsfp2_mgt_refclk_1_n] ;# MGTREFCLK1N_232 from U57.34 +#set_property -dict {LOC AP23 IOSTANDARD LVDS} [get_ports qsfp2_recclk_p] ;# to U57.12 +#set_property -dict {LOC AP22 IOSTANDARD LVDS} [get_ports qsfp2_recclk_n] ;# to U57.13 +#set_property -dict {LOC AN23 IOSTANDARD LVCMOS18} [get_ports qsfp2_modesell] +#set_property -dict {LOC AY22 IOSTANDARD LVCMOS18} [get_ports qsfp2_resetl] +#set_property -dict {LOC AN24 IOSTANDARD LVCMOS18} [get_ports qsfp2_modprsl] +#set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports qsfp2_intl] +#set_property -dict {LOC AT24 IOSTANDARD LVCMOS18} [get_ports qsfp2_lpmode] + +#create_clock -period 6.400 -name qsfp2_mgt_refclk_0 [get_ports qsfp2_mgt_refclk_0_p] +#set_clock_groups -asynchronous -group [get_clocks qsfp2_mgt_refclk_0 -include_generated_clocks] + +# I2C interface +#set_property -dict {LOC AM24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_scl] +#set_property -dict {LOC AL24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_sda] From 8e1f14e9a78c1159f23cc9fcd49c4f189181cbc1 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 13 Jun 2018 19:30:07 -0700 Subject: [PATCH 386/617] Add VCU118 10G example design --- example/VCU118/fpga_10g/Makefile | 25 + example/VCU118/fpga_10g/README.md | 33 + example/VCU118/fpga_10g/clock.xdc | 4 + example/VCU118/fpga_10g/common/vivado.mk | 118 ++ example/VCU118/fpga_10g/fpga.xdc | 152 ++ example/VCU118/fpga_10g/fpga/Makefile | 69 + .../fpga_10g/ip/gig_ethernet_pcs_pma_0.xci | 142 ++ .../fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci | 131 ++ example/VCU118/fpga_10g/lib/eth | 1 + example/VCU118/fpga_10g/rtl/debounce_switch.v | 89 ++ example/VCU118/fpga_10g/rtl/fpga.v | 1352 +++++++++++++++++ example/VCU118/fpga_10g/rtl/fpga_core.v | 949 ++++++++++++ example/VCU118/fpga_10g/rtl/mdio_master.v | 225 +++ example/VCU118/fpga_10g/rtl/sync_reset.v | 52 + example/VCU118/fpga_10g/rtl/sync_signal.v | 58 + example/VCU118/fpga_10g/tb/arp_ep.py | 1 + example/VCU118/fpga_10g/tb/axis_ep.py | 1 + example/VCU118/fpga_10g/tb/eth_ep.py | 1 + example/VCU118/fpga_10g/tb/gmii_ep.py | 1 + example/VCU118/fpga_10g/tb/ip_ep.py | 1 + example/VCU118/fpga_10g/tb/test_fpga_core.py | 690 +++++++++ example/VCU118/fpga_10g/tb/test_fpga_core.v | 324 ++++ example/VCU118/fpga_10g/tb/udp_ep.py | 1 + example/VCU118/fpga_10g/tb/xgmii_ep.py | 1 + 24 files changed, 4421 insertions(+) create mode 100644 example/VCU118/fpga_10g/Makefile create mode 100644 example/VCU118/fpga_10g/README.md create mode 100644 example/VCU118/fpga_10g/clock.xdc create mode 100644 example/VCU118/fpga_10g/common/vivado.mk create mode 100644 example/VCU118/fpga_10g/fpga.xdc create mode 100644 example/VCU118/fpga_10g/fpga/Makefile create mode 100644 example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci create mode 100644 example/VCU118/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci create mode 120000 example/VCU118/fpga_10g/lib/eth create mode 100644 example/VCU118/fpga_10g/rtl/debounce_switch.v create mode 100644 example/VCU118/fpga_10g/rtl/fpga.v create mode 100644 example/VCU118/fpga_10g/rtl/fpga_core.v create mode 100644 example/VCU118/fpga_10g/rtl/mdio_master.v create mode 100644 example/VCU118/fpga_10g/rtl/sync_reset.v create mode 100644 example/VCU118/fpga_10g/rtl/sync_signal.v create mode 120000 example/VCU118/fpga_10g/tb/arp_ep.py create mode 120000 example/VCU118/fpga_10g/tb/axis_ep.py create mode 120000 example/VCU118/fpga_10g/tb/eth_ep.py create mode 120000 example/VCU118/fpga_10g/tb/gmii_ep.py create mode 120000 example/VCU118/fpga_10g/tb/ip_ep.py create mode 100755 example/VCU118/fpga_10g/tb/test_fpga_core.py create mode 100644 example/VCU118/fpga_10g/tb/test_fpga_core.v create mode 120000 example/VCU118/fpga_10g/tb/udp_ep.py create mode 120000 example/VCU118/fpga_10g/tb/xgmii_ep.py diff --git a/example/VCU118/fpga_10g/Makefile b/example/VCU118/fpga_10g/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/VCU118/fpga_10g/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/VCU118/fpga_10g/README.md b/example/VCU118/fpga_10g/README.md new file mode 100644 index 000000000..c8beebcaf --- /dev/null +++ b/example/VCU118/fpga_10g/README.md @@ -0,0 +1,33 @@ +# Verilog Ethernet VCU118 Example Design + +## Introduction + +This example design targets the Xilinx VCU118 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. The design also enables the gigabit Ethernet interface for +testing with a QSFP loopback adapter. + +FPGA: xcvu9p-flga2104-2L-e +PHY: 10G BASE-R PHY IP core and internal GTY transceiver + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the VCU118 board with Vivado. Then run +netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any text +entered into netcat will be echoed back after pressing enter. + +Note that the gigabit PHY is also enabled for debugging. The gigabit port can +be inserted into the 10G data path between the 10G MAC and 10G PHY so that the +10G interface can be tested with a QSFP loopback adapter. Turn on SW12.1 to +insert the gigabit port into the 10G data path, or off to bypass the gigabit +port. Turn on SW12.2 to place the port in the TX path or off to place the +port in the RX path. + + diff --git a/example/VCU118/fpga_10g/clock.xdc b/example/VCU118/fpga_10g/clock.xdc new file mode 100644 index 000000000..bf52c8f3b --- /dev/null +++ b/example/VCU118/fpga_10g/clock.xdc @@ -0,0 +1,4 @@ +# Clock constraints + +# internal clock groups +set_clock_groups -asynchronous -group [get_clocks -of_objects [get_nets clk_156mhz_int]] diff --git a/example/VCU118/fpga_10g/common/vivado.mk b/example/VCU118/fpga_10g/common/vivado.mk new file mode 100644 index 000000000..a54b530f6 --- /dev/null +++ b/example/VCU118/fpga_10g/common/vivado.mk @@ -0,0 +1,118 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile $(XCI_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/VCU118/fpga_10g/fpga.xdc b/example/VCU118/fpga_10g/fpga.xdc new file mode 100644 index 000000000..e790d0bea --- /dev/null +++ b/example/VCU118/fpga_10g/fpga.xdc @@ -0,0 +1,152 @@ +# XDC constraints for the Xilinx VCU118 board +# part: xcvu9p-flga2104-2L-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] + +# System clocks +# 300 MHz +#set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_p] +#set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_n] +#create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p] +#set_clock_groups -asynchronous -group [get_clocks clk_300mhz -include_generated_clocks] + +# 250 MHz +#set_property -dict {LOC E12 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_1_p] +#set_property -dict {LOC D12 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_1_n] +#create_clock -period 4 -name clk_250mhz_1 [get_ports clk_250mhz_1_p] +#set_clock_groups -asynchronous -group [get_clocks clk_250mhz_1 -include_generated_clocks] + +#set_property -dict {LOC AW26 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_2_p] +#set_property -dict {LOC AW27 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_2_n] +#create_clock -period 4 -name clk_250mhz_2 [get_ports clk_250mhz_2_p] +#set_clock_groups -asynchronous -group [get_clocks clk_250mhz_2 -include_generated_clocks] + +# 125 MHz +set_property -dict {LOC AY24 IOSTANDARD LVDS} [get_ports clk_125mhz_p] +set_property -dict {LOC AY23 IOSTANDARD LVDS} [get_ports clk_125mhz_n] +create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] +set_clock_groups -asynchronous -group [get_clocks clk_125mhz -include_generated_clocks] + +# 90 MHz +#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] +#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] +#set_clock_groups -asynchronous -group [get_clocks clk_90mhz -include_generated_clocks] + +# LEDs +set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] +set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}] +set_property -dict {LOC AY30 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}] +set_property -dict {LOC BB32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[3]}] +set_property -dict {LOC BF32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[4]}] +set_property -dict {LOC AU37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[5]}] +set_property -dict {LOC AV36 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[6]}] +set_property -dict {LOC BA37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[7]}] + +# Reset button +set_property -dict {LOC L19 IOSTANDARD LVCMOS12} [get_ports reset] + +# Push buttons +set_property -dict {LOC BB24 IOSTANDARD LVCMOS18} [get_ports btnu] +set_property -dict {LOC BF22 IOSTANDARD LVCMOS18} [get_ports btnl] +set_property -dict {LOC BE22 IOSTANDARD LVCMOS18} [get_ports btnd] +set_property -dict {LOC BE23 IOSTANDARD LVCMOS18} [get_ports btnr] +set_property -dict {LOC BD23 IOSTANDARD LVCMOS18} [get_ports btnc] + +# DIP switches +set_property -dict {LOC B17 IOSTANDARD LVCMOS12} [get_ports {sw[0]}] +set_property -dict {LOC G16 IOSTANDARD LVCMOS12} [get_ports {sw[1]}] +set_property -dict {LOC J16 IOSTANDARD LVCMOS12} [get_ports {sw[2]}] +set_property -dict {LOC D21 IOSTANDARD LVCMOS12} [get_ports {sw[3]}] + +# UART +set_property -dict {LOC BB21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] +set_property -dict {LOC AW25 IOSTANDARD LVCMOS18} [get_ports uart_rxd] +set_property -dict {LOC BB22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_rts] +set_property -dict {LOC AY25 IOSTANDARD LVCMOS18} [get_ports uart_cts] + +# Gigabit Ethernet SGMII PHY +set_property -dict {LOC AU24 IOSTANDARD LVDS} [get_ports phy_sgmii_rx_p] +set_property -dict {LOC AV24 IOSTANDARD LVDS} [get_ports phy_sgmii_rx_n] +set_property -dict {LOC AU21 IOSTANDARD LVDS} [get_ports phy_sgmii_tx_p] +set_property -dict {LOC AV21 IOSTANDARD LVDS} [get_ports phy_sgmii_tx_n] +set_property -dict {LOC AT22 IOSTANDARD LVDS} [get_ports phy_sgmii_clk_p] +set_property -dict {LOC AU22 IOSTANDARD LVDS} [get_ports phy_sgmii_clk_n] +set_property -dict {LOC BA21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_reset_n] +set_property -dict {LOC AR24 IOSTANDARD LVCMOS18} [get_ports phy_int_n] +set_property -dict {LOC AR23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdio] +set_property -dict {LOC AV23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc] + +# 625 MHz ref clock from SGMII PHY +create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] +set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generated_clocks] + +# QSFP28 Interfaces +set_property -dict {LOC V7 } [get_ports qsfp1_tx1_p] ;# MGTYTXN0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC V6 } [get_ports qsfp1_tx1_n] ;# MGTYTXP0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC Y2 } [get_ports qsfp1_rx1_p] ;# MGTYTXN1_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC Y1 } [get_ports qsfp1_rx1_n] ;# MGTYTXP1_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC T7 } [get_ports qsfp1_tx2_p] ;# MGTYTXN2_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXP2_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC W4 } [get_ports qsfp1_rx2_p] ;# MGTYTXN3_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC W3 } [get_ports qsfp1_rx2_n] ;# MGTYTXP3_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC P7 } [get_ports qsfp1_tx3_p] ;# MGTYTXN0_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC P6 } [get_ports qsfp1_tx3_n] ;# MGTYTXP0_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC V2 } [get_ports qsfp1_rx3_p] ;# MGTYTXN1_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC V1 } [get_ports qsfp1_rx3_n] ;# MGTYTXP1_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC M7 } [get_ports qsfp1_tx4_p] ;# MGTYTXN2_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC M6 } [get_ports qsfp1_tx4_n] ;# MGTYTXP2_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC U4 } [get_ports qsfp1_rx4_p] ;# MGTYTXN3_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC U3 } [get_ports qsfp1_rx4_n] ;# MGTYTXP3_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC W9 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_231 from U38.4 +set_property -dict {LOC W8 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_231 from U38.5 +#set_property -dict {LOC U9 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_231 from U57.28 +#set_property -dict {LOC U8 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U57.29 +#set_property -dict {LOC AM23 IOSTANDARD LVDS} [get_ports qsfp1_recclk_p] ;# to U57.16 +#set_property -dict {LOC AM22 IOSTANDARD LVDS} [get_ports qsfp1_recclk_n] ;# to U57.17 +set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modesell] +set_property -dict {LOC BA22 IOSTANDARD LVCMOS18} [get_ports qsfp1_resetl] +set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modprsl] +set_property -dict {LOC AP21 IOSTANDARD LVCMOS18} [get_ports qsfp1_intl] +set_property -dict {LOC AN21 IOSTANDARD LVCMOS18} [get_ports qsfp1_lpmode] + +create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p] +set_clock_groups -asynchronous -group [get_clocks qsfp1_mgt_refclk_0 -include_generated_clocks] + +set_property -dict {LOC L5 } [get_ports qsfp2_tx1_p] ;# MGTYTXN0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC L4 } [get_ports qsfp2_tx1_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC T2 } [get_ports qsfp2_rx1_p] ;# MGTYTXN1_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC T1 } [get_ports qsfp2_rx1_n] ;# MGTYTXP1_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC K7 } [get_ports qsfp2_tx2_p] ;# MGTYTXN2_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC K6 } [get_ports qsfp2_tx2_n] ;# MGTYTXP2_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC R4 } [get_ports qsfp2_rx2_p] ;# MGTYTXN3_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC R3 } [get_ports qsfp2_rx2_n] ;# MGTYTXP3_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC J5 } [get_ports qsfp2_tx3_p] ;# MGTYTXN0_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC J4 } [get_ports qsfp2_tx3_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC P2 } [get_ports qsfp2_rx3_p] ;# MGTYTXN1_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC P1 } [get_ports qsfp2_rx3_n] ;# MGTYTXP1_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC H7 } [get_ports qsfp2_tx4_p] ;# MGTYTXN2_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC H6 } [get_ports qsfp2_tx4_n] ;# MGTYTXP2_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC M2 } [get_ports qsfp2_rx4_p] ;# MGTYTXN3_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC M1 } [get_ports qsfp2_rx4_n] ;# MGTYTXP3_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC R9 } [get_ports qsfp2_mgt_refclk_0_p] ;# MGTREFCLK0P_232 from U104.13 +set_property -dict {LOC R8 } [get_ports qsfp2_mgt_refclk_0_n] ;# MGTREFCLK0N_232 from U104.14 +#set_property -dict {LOC N9 } [get_ports qsfp2_mgt_refclk_1_p] ;# MGTREFCLK1P_232 from U57.35 +#set_property -dict {LOC N8 } [get_ports qsfp2_mgt_refclk_1_n] ;# MGTREFCLK1N_232 from U57.34 +#set_property -dict {LOC AP23 IOSTANDARD LVDS} [get_ports qsfp2_recclk_p] ;# to U57.12 +#set_property -dict {LOC AP22 IOSTANDARD LVDS} [get_ports qsfp2_recclk_n] ;# to U57.13 +set_property -dict {LOC AN23 IOSTANDARD LVCMOS18} [get_ports qsfp2_modesell] +set_property -dict {LOC AY22 IOSTANDARD LVCMOS18} [get_ports qsfp2_resetl] +set_property -dict {LOC AN24 IOSTANDARD LVCMOS18} [get_ports qsfp2_modprsl] +set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports qsfp2_intl] +set_property -dict {LOC AT24 IOSTANDARD LVCMOS18} [get_ports qsfp2_lpmode] + +create_clock -period 6.400 -name qsfp2_mgt_refclk_0 [get_ports qsfp2_mgt_refclk_0_p] +set_clock_groups -asynchronous -group [get_clocks qsfp2_mgt_refclk_0 -include_generated_clocks] + +# I2C interface +set_property -dict {LOC AM24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_scl] +set_property -dict {LOC AL24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_sda] + + diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile new file mode 100644 index 000000000..3f273da63 --- /dev/null +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -0,0 +1,69 @@ + +# FPGA settings +FPGA_PART = xcvu9p-flga2104-2L-e +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/mdio_master.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux_64_2.v +SYN_FILES += lib/eth/rtl/ip_mux_64_2.v +SYN_FILES += lib/eth/rtl/arp_64.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v +SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_64_2.v +SYN_FILES += lib/eth/rtl/eth_mux_64_2.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_adapter.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_switch_4x4.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += clock.xdc + +# IP +XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci +XCI_FILES += ip/ten_gig_eth_pcs_pma_0.xci + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl + echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "exit" >> program.tcl + vivado -mode batch -source program.tcl + diff --git a/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci new file mode 100644 index 000000000..c23253498 --- /dev/null +++ b/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci @@ -0,0 +1,142 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gig_ethernet_pcs_pma_0 + + + true + 0 + 0 + true + false + DIFF_PAIR_0 + DIFF_PAIR_1 + false + DIFF_PAIR_2 + DIFF_PAIR_1 + virtexuplus + Sync + gig_ethernet_pcs_pma_0 + 50.0 + false + . + true + false + false + true + virtexuplus + 16 + 10 + X0Y4 + 8 + 5 + GTH + false + true + false + false + false + true + 1 + clk0 + 125 + TXOUTCLK + true + false + gig_ethernet_pcs_pma_0_gt + true + GTHE4 + false + 0 + true + false + false + xcvu9p + false + 1 + true + Sync + gig_ethernet_pcs_pma_0 + Custom + 50.0 + TEMAC + Custom + 0 + false + false + false + false + X0Y4 + GTH + false + false + 625 + Custom + false + 1G + 1 + LVDS + 125 + clk0 + TXOUTCLK + DIFF_PAIR_0 + DIFF_PAIR_1 + false + 10_100_1000 + false + SGMII + Include_Shared_Logic_in_Core + Time_of_day + false + DIFF_PAIR_2 + DIFF_PAIR_1 + 0 + false + virtexuplus + + xcvu9p + flga2104 + VERILOG + + MIXED + -2L + E + TRUE + TRUE + IP_Flow + 0 + TRUE + . + + . + 2017.2.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/VCU118/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci b/example/VCU118/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci new file mode 100644 index 000000000..2d73f4a1c --- /dev/null +++ b/example/VCU118/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci @@ -0,0 +1,131 @@ + + + xilinx.com + xci + unknown + 1.0 + + + ten_gig_eth_pcs_pma_0 + + + 0 + 75 + 64 + 7 + BASE-R + Asynchronous + Ethernet PCS/PMA 64-bit + MII + 0 + 0 + 0 + 0 + 0 + virtexuplus + 0 + 125 + Quad X0Y0 + 1 + 156.25 + GTY + None + 0 + 0 + 0 + 1 + 0 + X1Y48 + X1Y49 + X1Y50 + X1Y51 + 10 + 4 + 0 + 2 + 0 + 0 + 4 + 1 + 0 + 0 + 100 + BASE-R + Asynchronous + Ethernet PCS/PMA 64-bit + ten_gig_eth_pcs_pma_0 + MII + Custom + 0 + 0 + 0 + 0 + 0 + Custom + 0 + 125 + Quad_X1Y12 + 1 + 156.25 + GTY + None + 0 + 0 + 0 + 1 + 0 + X1Y48 + X1Y49 + X1Y50 + X1Y51 + 10 + 4 + 0 + 2 + 0 + 0 + false + 1 + virtexuplus + + xcvu9p + flga2104 + VERILOG + + MIXED + -2L + E + TRUE + TRUE + IP_Flow + 0 + TRUE + . + + . + 2017.2.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/VCU118/fpga_10g/lib/eth b/example/VCU118/fpga_10g/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/VCU118/fpga_10g/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/VCU118/fpga_10g/rtl/debounce_switch.v b/example/VCU118/fpga_10g/rtl/debounce_switch.v new file mode 100644 index 000000000..bb631cc35 --- /dev/null +++ b/example/VCU118/fpga_10g/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/VCU118/fpga_10g/rtl/fpga.v b/example/VCU118/fpga_10g/rtl/fpga.v new file mode 100644 index 000000000..a3897c49d --- /dev/null +++ b/example/VCU118/fpga_10g/rtl/fpga.v @@ -0,0 +1,1352 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 125MHz LVDS + * Reset: Push button, active low + */ + input wire clk_125mhz_p, + input wire clk_125mhz_n, + input wire reset, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * I2C for board management + */ + inout wire i2c_scl, + inout wire i2c_sda, + + /* + * Ethernet: QSFP28 + */ + output wire qsfp1_tx1_p, + output wire qsfp1_tx1_n, + input wire qsfp1_rx1_p, + input wire qsfp1_rx1_n, + output wire qsfp1_tx2_p, + output wire qsfp1_tx2_n, + input wire qsfp1_rx2_p, + input wire qsfp1_rx2_n, + output wire qsfp1_tx3_p, + output wire qsfp1_tx3_n, + input wire qsfp1_rx3_p, + input wire qsfp1_rx3_n, + output wire qsfp1_tx4_p, + output wire qsfp1_tx4_n, + input wire qsfp1_rx4_p, + input wire qsfp1_rx4_n, + input wire qsfp1_mgt_refclk_0_p, + input wire qsfp1_mgt_refclk_0_n, + // input wire qsfp1_mgt_refclk_1_p, + // input wire qsfp1_mgt_refclk_1_n, + // output wire qsfp1_recclk_p, + // output wire qsfp1_recclk_n, + output wire qsfp1_modesell, + output wire qsfp1_resetl, + input wire qsfp1_modprsl, + input wire qsfp1_intl, + output wire qsfp1_lpmode, + + output wire qsfp2_tx1_p, + output wire qsfp2_tx1_n, + input wire qsfp2_rx1_p, + input wire qsfp2_rx1_n, + output wire qsfp2_tx2_p, + output wire qsfp2_tx2_n, + input wire qsfp2_rx2_p, + input wire qsfp2_rx2_n, + output wire qsfp2_tx3_p, + output wire qsfp2_tx3_n, + input wire qsfp2_rx3_p, + input wire qsfp2_rx3_n, + output wire qsfp2_tx4_p, + output wire qsfp2_tx4_n, + input wire qsfp2_rx4_p, + input wire qsfp2_rx4_n, + input wire qsfp2_mgt_refclk_0_p, + input wire qsfp2_mgt_refclk_0_n, + // input wire qsfp2_mgt_refclk_1_p, + // input wire qsfp2_mgt_refclk_1_n, + // output wire qsfp2_recclk_p, + // output wire qsfp2_recclk_n, + output wire qsfp2_modesell, + output wire qsfp2_resetl, + input wire qsfp2_modprsl, + input wire qsfp2_intl, + output wire qsfp2_lpmode, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_sgmii_rx_p, + input wire phy_sgmii_rx_n, + output wire phy_sgmii_tx_p, + output wire phy_sgmii_tx_n, + input wire phy_sgmii_clk_p, + input wire phy_sgmii_clk_n, + output wire phy_reset_n, + input wire phy_int_n, + inout wire phy_mdio, + output wire phy_mdc, + + /* + * UART: 500000 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// Clock and reset + +wire clk_125mhz_ibufg; +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +// Internal 156.25 MHz clock +wire clk_156mhz_int; +wire rst_156mhz_int; + +wire mmcm_rst = reset; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS #( + .DIFF_TERM("FALSE"), + .IBUF_LOW_PWR("FALSE") +) +clk_125mhz_ibufg_inst ( + .O (clk_125mhz_ibufg), + .I (clk_125mhz_p), + .IB (clk_125mhz_n) +); + +// MMCM instance +// 125 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 8, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCME3_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(8), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(8.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_125mhz_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [3:0] sw_int; + +debounce_switch #( + .WIDTH(9), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +wire uart_rxd_int; +wire uart_cts_int; + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(clk_125mhz_int), + .in({uart_rxd, uart_cts}), + .out({uart_rxd_int, uart_cts_int}) +); + +// SI570 I2C +wire i2c_scl_i; +wire i2c_scl_o = 1; +wire i2c_scl_t = 1; +wire i2c_sda_i; +wire i2c_sda_o = 1; +wire i2c_sda_t = 1; + +assign i2c_scl_i = i2c_scl; +assign i2c_scl = i2c_scl_t ? 1'bz : i2c_scl_o; +assign i2c_sda_i = i2c_sda; +assign i2c_sda = i2c_sda_t ? 1'bz : i2c_sda_o; + +// XGMII 10G PHY +assign qsfp1_modesell = 1'b1; +assign qsfp1_resetl = 1'b1; +assign qsfp1_lpmode = 1'b0; + +wire qsfp1_tx_clk_1_int; +wire qsfp1_tx_rst_1_int; +wire [63:0] qsfp1_txd_1_int; +wire [7:0] qsfp1_txc_1_int; +wire qsfp1_rx_clk_1_int = qsfp1_tx_clk_1_int; +wire qsfp1_rx_rst_1_int; +wire [63:0] qsfp1_rxd_1_int; +wire [7:0] qsfp1_rxc_1_int; +wire qsfp1_tx_clk_2_int; +wire qsfp1_tx_rst_2_int; +wire [63:0] qsfp1_txd_2_int; +wire [7:0] qsfp1_txc_2_int; +wire qsfp1_rx_clk_2_int = qsfp1_tx_clk_2_int; +wire qsfp1_rx_rst_2_int; +wire [63:0] qsfp1_rxd_2_int; +wire [7:0] qsfp1_rxc_2_int; +wire qsfp1_tx_clk_3_int; +wire qsfp1_tx_rst_3_int; +wire [63:0] qsfp1_txd_3_int; +wire [7:0] qsfp1_txc_3_int; +wire qsfp1_rx_clk_3_int = qsfp1_tx_clk_3_int; +wire qsfp1_rx_rst_3_int; +wire [63:0] qsfp1_rxd_3_int; +wire [7:0] qsfp1_rxc_3_int; +wire qsfp1_tx_clk_4_int; +wire qsfp1_tx_rst_4_int; +wire [63:0] qsfp1_txd_4_int; +wire [7:0] qsfp1_txc_4_int; +wire qsfp1_rx_clk_4_int = qsfp1_tx_clk_4_int; +wire qsfp1_rx_rst_4_int; +wire [63:0] qsfp1_rxd_4_int; +wire [7:0] qsfp1_rxc_4_int; + +assign qsfp2_modesell = 1'b1; +assign qsfp2_resetl = 1'b1; +assign qsfp2_lpmode = 1'b0; + +wire qsfp2_tx_clk_1_int; +wire qsfp2_tx_rst_1_int; +wire [63:0] qsfp2_txd_1_int; +wire [7:0] qsfp2_txc_1_int; +wire qsfp2_rx_clk_1_int = qsfp2_tx_clk_1_int; +wire qsfp2_rx_rst_1_int; +wire [63:0] qsfp2_rxd_1_int; +wire [7:0] qsfp2_rxc_1_int; +wire qsfp2_tx_clk_2_int; +wire qsfp2_tx_rst_2_int; +wire [63:0] qsfp2_txd_2_int; +wire [7:0] qsfp2_txc_2_int; +wire qsfp2_rx_clk_2_int = qsfp2_tx_clk_2_int; +wire qsfp2_rx_rst_2_int; +wire [63:0] qsfp2_rxd_2_int; +wire [7:0] qsfp2_rxc_2_int; +wire qsfp2_tx_clk_3_int; +wire qsfp2_tx_rst_3_int; +wire [63:0] qsfp2_txd_3_int; +wire [7:0] qsfp2_txc_3_int; +wire qsfp2_rx_clk_3_int = qsfp2_tx_clk_3_int; +wire qsfp2_rx_rst_3_int; +wire [63:0] qsfp2_rxd_3_int; +wire [7:0] qsfp2_rxc_3_int; +wire qsfp2_tx_clk_4_int; +wire qsfp2_tx_rst_4_int; +wire [63:0] qsfp2_txd_4_int; +wire [7:0] qsfp2_txc_4_int; +wire qsfp2_rx_clk_4_int = qsfp2_tx_clk_4_int; +wire qsfp2_rx_rst_4_int; +wire [63:0] qsfp2_rxd_4_int; +wire [7:0] qsfp2_rxc_4_int; + +wire qsfp1_rx_block_lock_1; +wire qsfp1_rx_block_lock_2; +wire qsfp1_rx_block_lock_3; +wire qsfp1_rx_block_lock_4; + +wire qsfp2_rx_block_lock_1; +wire qsfp2_rx_block_lock_2; +wire qsfp2_rx_block_lock_3; +wire qsfp2_rx_block_lock_4; + +assign clk_156mhz_int = qsfp1_tx_clk_1_int; +assign rst_156mhz_int = qsfp1_tx_rst_1_int; + +ten_gig_eth_pcs_pma_0 +ten_gig_eth_pcs_pma_inst_qsfp1 ( + //// Channel 0 + .gt_rxp_in_0(qsfp1_rx1_p), + .gt_rxn_in_0(qsfp1_rx1_n), + .gt_txp_out_0(qsfp1_tx1_p), + .gt_txn_out_0(qsfp1_tx1_n), + + .tx_mii_clk_0(qsfp1_tx_clk_1_int), + .rx_core_clk_0(qsfp1_rx_clk_1_int), + .rx_clk_out_0(), + .gt_loopback_in_0(3'd0), + + //// RX_0 Signals + .rx_reset_0(1'b0), + .user_rx_reset_0(qsfp1_rx_rst_1_int), + .rxrecclkout_0(), + + //// RX_0 User Interface Signals + .rx_mii_d_0(qsfp1_rxd_1_int), + .rx_mii_c_0(qsfp1_rxc_1_int), + + //// RX_0 Control Signals + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + //// RX_0 Stats Signals + .stat_rx_block_lock_0(qsfp1_rx_block_lock_1), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + //// TX_0 Signals + .tx_reset_0(1'b0), + .user_tx_reset_0(qsfp1_tx_rst_1_int), + + //// TX_0 User Interface Signals + .tx_mii_d_0(qsfp1_txd_1_int), + .tx_mii_c_0(qsfp1_txc_1_int), + + //// TX_0 Control Signals + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + //// TX_0 Stats Signals + .stat_tx_local_fault_0(), + + .gtwiz_reset_tx_datapath_0(1'b0), + .gtwiz_reset_rx_datapath_0(1'b0), + + .gtpowergood_out_0(), + + + //// Channel 1 + .gt_rxp_in_1(qsfp1_rx2_p), + .gt_rxn_in_1(qsfp1_rx2_n), + .gt_txp_out_1(qsfp1_tx2_p), + .gt_txn_out_1(qsfp1_tx2_n), + + .tx_mii_clk_1(qsfp1_tx_clk_2_int), + .rx_core_clk_1(qsfp1_rx_clk_2_int), + .rx_clk_out_1(), + .gt_loopback_in_1(3'd0), + + //// RX_1 Signals + .rx_reset_1(1'b0), + .user_rx_reset_1(qsfp1_rx_rst_2_int), + .rxrecclkout_1(), + + //// RX_1 User Interface Signals + .rx_mii_d_1(qsfp1_rxd_2_int), + .rx_mii_c_1(qsfp1_rxc_2_int), + + //// RX_1 Control Signals + .ctl_rx_test_pattern_1(1'b0), + .ctl_rx_test_pattern_enable_1(1'b0), + .ctl_rx_data_pattern_select_1(1'b0), + .ctl_rx_prbs31_test_pattern_enable_1(1'b0), + + //// RX_1 Stats Signals + .stat_rx_block_lock_1(qsfp1_rx_block_lock_2), + .stat_rx_framing_err_valid_1(), + .stat_rx_framing_err_1(), + .stat_rx_hi_ber_1(), + .stat_rx_valid_ctrl_code_1(), + .stat_rx_bad_code_1(), + .stat_rx_bad_code_valid_1(), + .stat_rx_error_valid_1(), + .stat_rx_error_1(), + .stat_rx_fifo_error_1(), + .stat_rx_local_fault_1(), + .stat_rx_status_1(), + + //// TX_1 Signals + .tx_reset_1(1'b0), + .user_tx_reset_1(qsfp1_tx_rst_2_int), + + //// TX_1 User Interface Signals + .tx_mii_d_1(qsfp1_txd_2_int), + .tx_mii_c_1(qsfp1_txc_2_int), + + //// TX_1 Control Signals + .ctl_tx_test_pattern_1(1'b0), + .ctl_tx_test_pattern_enable_1(1'b0), + .ctl_tx_test_pattern_select_1(1'b0), + .ctl_tx_data_pattern_select_1(1'b0), + .ctl_tx_test_pattern_seed_a_1(58'd0), + .ctl_tx_test_pattern_seed_b_1(58'd0), + .ctl_tx_prbs31_test_pattern_enable_1(1'b0), + + //// TX_1 Stats Signals + .stat_tx_local_fault_1(), + + .gtwiz_reset_tx_datapath_1(1'b0), + .gtwiz_reset_rx_datapath_1(1'b0), + + .gtpowergood_out_1(), + + + //// Channel 2 + .gt_rxp_in_2(qsfp1_rx3_p), + .gt_rxn_in_2(qsfp1_rx3_n), + .gt_txp_out_2(qsfp1_tx3_p), + .gt_txn_out_2(qsfp1_tx3_n), + + .tx_mii_clk_2(qsfp1_tx_clk_3_int), + .rx_core_clk_2(qsfp1_rx_clk_3_int), + .rx_clk_out_2(), + .gt_loopback_in_2(3'd0), + + //// RX_2 Signals + .rx_reset_2(1'b0), + .user_rx_reset_2(qsfp1_rx_rst_3_int), + .rxrecclkout_2(), + + //// RX_2 User Interface Signals + .rx_mii_d_2(qsfp1_rxd_3_int), + .rx_mii_c_2(qsfp1_rxc_3_int), + + //// RX_2 Control Signals + .ctl_rx_test_pattern_2(1'b0), + .ctl_rx_test_pattern_enable_2(1'b0), + .ctl_rx_data_pattern_select_2(1'b0), + .ctl_rx_prbs31_test_pattern_enable_2(1'b0), + + //// RX_2 Stats Signals + .stat_rx_block_lock_2(qsfp1_rx_block_lock_3), + .stat_rx_framing_err_valid_2(), + .stat_rx_framing_err_2(), + .stat_rx_hi_ber_2(), + .stat_rx_valid_ctrl_code_2(), + .stat_rx_bad_code_2(), + .stat_rx_bad_code_valid_2(), + .stat_rx_error_valid_2(), + .stat_rx_error_2(), + .stat_rx_fifo_error_2(), + .stat_rx_local_fault_2(), + .stat_rx_status_2(), + + //// TX_2 Signals + .tx_reset_2(1'b0), + .user_tx_reset_2(qsfp1_tx_rst_3_int), + + //// TX_2 User Interface Signals + .tx_mii_d_2(qsfp1_txd_3_int), + .tx_mii_c_2(qsfp1_txc_3_int), + + //// TX_2 Control Signals + .ctl_tx_test_pattern_2(1'b0), + .ctl_tx_test_pattern_enable_2(1'b0), + .ctl_tx_test_pattern_select_2(1'b0), + .ctl_tx_data_pattern_select_2(1'b0), + .ctl_tx_test_pattern_seed_a_2(58'd0), + .ctl_tx_test_pattern_seed_b_2(58'd0), + .ctl_tx_prbs31_test_pattern_enable_2(1'b0), + + //// TX_2 Stats Signals + .stat_tx_local_fault_2(), + + .gtwiz_reset_tx_datapath_2(1'b0), + .gtwiz_reset_rx_datapath_2(1'b0), + + .gtpowergood_out_2(), + + + //// Channel 3 + .gt_rxp_in_3(qsfp1_rx4_p), + .gt_rxn_in_3(qsfp1_rx4_n), + .gt_txp_out_3(qsfp1_tx4_p), + .gt_txn_out_3(qsfp1_tx4_n), + + .tx_mii_clk_3(qsfp1_tx_clk_4_int), + .rx_core_clk_3(qsfp1_rx_clk_4_int), + .rx_clk_out_3(), + .gt_loopback_in_3(3'd0), + + //// RX_3 Signals + .rx_reset_3(1'b0), + .user_rx_reset_3(qsfp1_rx_rst_4_int), + .rxrecclkout_3(), + + //// RX_3 User Interface Signals + .rx_mii_d_3(qsfp1_rxd_4_int), + .rx_mii_c_3(qsfp1_rxc_4_int), + + //// RX_3 Control Signals + .ctl_rx_test_pattern_3(1'b0), + .ctl_rx_test_pattern_enable_3(1'b0), + .ctl_rx_data_pattern_select_3(1'b0), + .ctl_rx_prbs31_test_pattern_enable_3(1'b0), + + //// RX_3 Stats Signals + .stat_rx_block_lock_3(qsfp1_rx_block_lock_4), + .stat_rx_framing_err_valid_3(), + .stat_rx_framing_err_3(), + .stat_rx_hi_ber_3(), + .stat_rx_valid_ctrl_code_3(), + .stat_rx_bad_code_3(), + .stat_rx_bad_code_valid_3(), + .stat_rx_error_valid_3(), + .stat_rx_error_3(), + .stat_rx_fifo_error_3(), + .stat_rx_local_fault_3(), + .stat_rx_status_3(), + + //// TX_3 Signals + .tx_reset_3(1'b0), + .user_tx_reset_3(qsfp1_tx_rst_4_int), + + //// TX_3 User Interface Signals + .tx_mii_d_3(qsfp1_txd_4_int), + .tx_mii_c_3(qsfp1_txc_4_int), + + //// TX_3 Control Signals + .ctl_tx_test_pattern_3(1'b0), + .ctl_tx_test_pattern_enable_3(1'b0), + .ctl_tx_test_pattern_select_3(1'b0), + .ctl_tx_data_pattern_select_3(1'b0), + .ctl_tx_test_pattern_seed_a_3(58'd0), + .ctl_tx_test_pattern_seed_b_3(58'd0), + .ctl_tx_prbs31_test_pattern_enable_3(1'b0), + + //// TX_3 Stats Signals + .stat_tx_local_fault_3(), + + .gtwiz_reset_tx_datapath_3(1'b0), + .gtwiz_reset_rx_datapath_3(1'b0), + + .gtpowergood_out_3(), + + .gt_refclk_p(qsfp1_mgt_refclk_0_p), + .gt_refclk_n(qsfp1_mgt_refclk_0_n), + + .gt_refclk_out(), + + .sys_reset(rst_125mhz_int), + .dclk(clk_125mhz_int) +); + +ten_gig_eth_pcs_pma_0 +ten_gig_eth_pcs_pma_inst_qsfp2 ( + //// Channel 0 + .gt_rxp_in_0(qsfp2_rx1_p), + .gt_rxn_in_0(qsfp2_rx1_n), + .gt_txp_out_0(qsfp2_tx1_p), + .gt_txn_out_0(qsfp2_tx1_n), + + .tx_mii_clk_0(qsfp2_tx_clk_1_int), + .rx_core_clk_0(qsfp2_rx_clk_1_int), + .rx_clk_out_0(), + .gt_loopback_in_0(3'd0), + + //// RX_0 Signals + .rx_reset_0(1'b0), + .user_rx_reset_0(qsfp2_rx_rst_1_int), + .rxrecclkout_0(), + + //// RX_0 User Interface Signals + .rx_mii_d_0(qsfp2_rxd_1_int), + .rx_mii_c_0(qsfp2_rxc_1_int), + + //// RX_0 Control Signals + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + //// RX_0 Stats Signals + .stat_rx_block_lock_0(qsfp2_rx_block_lock_1), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + //// TX_0 Signals + .tx_reset_0(1'b0), + .user_tx_reset_0(qsfp2_tx_rst_1_int), + + //// TX_0 User Interface Signals + .tx_mii_d_0(qsfp2_txd_1_int), + .tx_mii_c_0(qsfp2_txc_1_int), + + //// TX_0 Control Signals + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + //// TX_0 Stats Signals + .stat_tx_local_fault_0(), + + .gtwiz_reset_tx_datapath_0(1'b0), + .gtwiz_reset_rx_datapath_0(1'b0), + + .gtpowergood_out_0(), + + + //// Channel 1 + .gt_rxp_in_1(qsfp2_rx2_p), + .gt_rxn_in_1(qsfp2_rx2_n), + .gt_txp_out_1(qsfp2_tx2_p), + .gt_txn_out_1(qsfp2_tx2_n), + + .tx_mii_clk_1(qsfp2_tx_clk_2_int), + .rx_core_clk_1(qsfp2_rx_clk_2_int), + .rx_clk_out_1(), + .gt_loopback_in_1(3'd0), + + //// RX_1 Signals + .rx_reset_1(1'b0), + .user_rx_reset_1(qsfp2_rx_rst_2_int), + .rxrecclkout_1(), + + //// RX_1 User Interface Signals + .rx_mii_d_1(qsfp2_rxd_2_int), + .rx_mii_c_1(qsfp2_rxc_2_int), + + //// RX_1 Control Signals + .ctl_rx_test_pattern_1(1'b0), + .ctl_rx_test_pattern_enable_1(1'b0), + .ctl_rx_data_pattern_select_1(1'b0), + .ctl_rx_prbs31_test_pattern_enable_1(1'b0), + + //// RX_1 Stats Signals + .stat_rx_block_lock_1(qsfp2_rx_block_lock_2), + .stat_rx_framing_err_valid_1(), + .stat_rx_framing_err_1(), + .stat_rx_hi_ber_1(), + .stat_rx_valid_ctrl_code_1(), + .stat_rx_bad_code_1(), + .stat_rx_bad_code_valid_1(), + .stat_rx_error_valid_1(), + .stat_rx_error_1(), + .stat_rx_fifo_error_1(), + .stat_rx_local_fault_1(), + .stat_rx_status_1(), + + //// TX_1 Signals + .tx_reset_1(1'b0), + .user_tx_reset_1(qsfp2_tx_rst_2_int), + + //// TX_1 User Interface Signals + .tx_mii_d_1(qsfp2_txd_2_int), + .tx_mii_c_1(qsfp2_txc_2_int), + + //// TX_1 Control Signals + .ctl_tx_test_pattern_1(1'b0), + .ctl_tx_test_pattern_enable_1(1'b0), + .ctl_tx_test_pattern_select_1(1'b0), + .ctl_tx_data_pattern_select_1(1'b0), + .ctl_tx_test_pattern_seed_a_1(58'd0), + .ctl_tx_test_pattern_seed_b_1(58'd0), + .ctl_tx_prbs31_test_pattern_enable_1(1'b0), + + //// TX_1 Stats Signals + .stat_tx_local_fault_1(), + + .gtwiz_reset_tx_datapath_1(1'b0), + .gtwiz_reset_rx_datapath_1(1'b0), + + .gtpowergood_out_1(), + + + //// Channel 2 + .gt_rxp_in_2(qsfp2_rx3_p), + .gt_rxn_in_2(qsfp2_rx3_n), + .gt_txp_out_2(qsfp2_tx3_p), + .gt_txn_out_2(qsfp2_tx3_n), + + .tx_mii_clk_2(qsfp2_tx_clk_3_int), + .rx_core_clk_2(qsfp2_rx_clk_3_int), + .rx_clk_out_2(), + .gt_loopback_in_2(3'd0), + + //// RX_2 Signals + .rx_reset_2(1'b0), + .user_rx_reset_2(qsfp2_rx_rst_3_int), + .rxrecclkout_2(), + + //// RX_2 User Interface Signals + .rx_mii_d_2(qsfp2_rxd_3_int), + .rx_mii_c_2(qsfp2_rxc_3_int), + + //// RX_2 Control Signals + .ctl_rx_test_pattern_2(1'b0), + .ctl_rx_test_pattern_enable_2(1'b0), + .ctl_rx_data_pattern_select_2(1'b0), + .ctl_rx_prbs31_test_pattern_enable_2(1'b0), + + //// RX_2 Stats Signals + .stat_rx_block_lock_2(qsfp2_rx_block_lock_3), + .stat_rx_framing_err_valid_2(), + .stat_rx_framing_err_2(), + .stat_rx_hi_ber_2(), + .stat_rx_valid_ctrl_code_2(), + .stat_rx_bad_code_2(), + .stat_rx_bad_code_valid_2(), + .stat_rx_error_valid_2(), + .stat_rx_error_2(), + .stat_rx_fifo_error_2(), + .stat_rx_local_fault_2(), + .stat_rx_status_2(), + + //// TX_2 Signals + .tx_reset_2(1'b0), + .user_tx_reset_2(qsfp2_tx_rst_3_int), + + //// TX_2 User Interface Signals + .tx_mii_d_2(qsfp2_txd_3_int), + .tx_mii_c_2(qsfp2_txc_3_int), + + //// TX_2 Control Signals + .ctl_tx_test_pattern_2(1'b0), + .ctl_tx_test_pattern_enable_2(1'b0), + .ctl_tx_test_pattern_select_2(1'b0), + .ctl_tx_data_pattern_select_2(1'b0), + .ctl_tx_test_pattern_seed_a_2(58'd0), + .ctl_tx_test_pattern_seed_b_2(58'd0), + .ctl_tx_prbs31_test_pattern_enable_2(1'b0), + + //// TX_2 Stats Signals + .stat_tx_local_fault_2(), + + .gtwiz_reset_tx_datapath_2(1'b0), + .gtwiz_reset_rx_datapath_2(1'b0), + + .gtpowergood_out_2(), + + + //// Channel 3 + .gt_rxp_in_3(qsfp2_rx4_p), + .gt_rxn_in_3(qsfp2_rx4_n), + .gt_txp_out_3(qsfp2_tx4_p), + .gt_txn_out_3(qsfp2_tx4_n), + + .tx_mii_clk_3(qsfp2_tx_clk_4_int), + .rx_core_clk_3(qsfp2_rx_clk_4_int), + .rx_clk_out_3(), + .gt_loopback_in_3(3'd0), + + //// RX_3 Signals + .rx_reset_3(1'b0), + .user_rx_reset_3(qsfp2_rx_rst_4_int), + .rxrecclkout_3(), + + //// RX_3 User Interface Signals + .rx_mii_d_3(qsfp2_rxd_4_int), + .rx_mii_c_3(qsfp2_rxc_4_int), + + //// RX_3 Control Signals + .ctl_rx_test_pattern_3(1'b0), + .ctl_rx_test_pattern_enable_3(1'b0), + .ctl_rx_data_pattern_select_3(1'b0), + .ctl_rx_prbs31_test_pattern_enable_3(1'b0), + + //// RX_3 Stats Signals + .stat_rx_block_lock_3(qsfp2_rx_block_lock_4), + .stat_rx_framing_err_valid_3(), + .stat_rx_framing_err_3(), + .stat_rx_hi_ber_3(), + .stat_rx_valid_ctrl_code_3(), + .stat_rx_bad_code_3(), + .stat_rx_bad_code_valid_3(), + .stat_rx_error_valid_3(), + .stat_rx_error_3(), + .stat_rx_fifo_error_3(), + .stat_rx_local_fault_3(), + .stat_rx_status_3(), + + //// TX_3 Signals + .tx_reset_3(1'b0), + .user_tx_reset_3(qsfp2_tx_rst_4_int), + + //// TX_3 User Interface Signals + .tx_mii_d_3(qsfp2_txd_4_int), + .tx_mii_c_3(qsfp2_txc_4_int), + + //// TX_3 Control Signals + .ctl_tx_test_pattern_3(1'b0), + .ctl_tx_test_pattern_enable_3(1'b0), + .ctl_tx_test_pattern_select_3(1'b0), + .ctl_tx_data_pattern_select_3(1'b0), + .ctl_tx_test_pattern_seed_a_3(58'd0), + .ctl_tx_test_pattern_seed_b_3(58'd0), + .ctl_tx_prbs31_test_pattern_enable_3(1'b0), + + //// TX_3 Stats Signals + .stat_tx_local_fault_3(), + + .gtwiz_reset_tx_datapath_3(1'b0), + .gtwiz_reset_rx_datapath_3(1'b0), + + .gtpowergood_out_3(), + + .gt_refclk_p(qsfp2_mgt_refclk_0_p), + .gt_refclk_n(qsfp2_mgt_refclk_0_n), + + .gt_refclk_out(), + + .sys_reset(rst_125mhz_int), + .dclk(clk_125mhz_int) +); + +// SGMII interface to PHY +wire phy_gmii_clk_int; +wire phy_gmii_rst_int; +wire phy_gmii_clk_en_int; +wire [7:0] phy_gmii_txd_int; +wire phy_gmii_tx_en_int; +wire phy_gmii_tx_er_int; +wire [7:0] phy_gmii_rxd_int; +wire phy_gmii_rx_dv_int; +wire phy_gmii_rx_er_int; + +wire [15:0] gig_eth_pcspma_status_vector; + +wire gig_eth_pcspma_status_link_status = gig_eth_pcspma_status_vector[0]; +wire gig_eth_pcspma_status_link_synchronization = gig_eth_pcspma_status_vector[1]; +wire gig_eth_pcspma_status_rudi_c = gig_eth_pcspma_status_vector[2]; +wire gig_eth_pcspma_status_rudi_i = gig_eth_pcspma_status_vector[3]; +wire gig_eth_pcspma_status_rudi_invalid = gig_eth_pcspma_status_vector[4]; +wire gig_eth_pcspma_status_rxdisperr = gig_eth_pcspma_status_vector[5]; +wire gig_eth_pcspma_status_rxnotintable = gig_eth_pcspma_status_vector[6]; +wire gig_eth_pcspma_status_phy_link_status = gig_eth_pcspma_status_vector[7]; +wire [1:0] gig_eth_pcspma_status_remote_fault_encdg = gig_eth_pcspma_status_vector[9:8]; +wire [1:0] gig_eth_pcspma_status_speed = gig_eth_pcspma_status_vector[11:10]; +wire gig_eth_pcspma_status_duplex = gig_eth_pcspma_status_vector[12]; +wire gig_eth_pcspma_status_remote_fault = gig_eth_pcspma_status_vector[13]; +wire [1:0] gig_eth_pcspma_status_pause = gig_eth_pcspma_status_vector[15:14]; + +wire [4:0] gig_eth_pcspma_config_vector; + +assign gig_eth_pcspma_config_vector[4] = 1'b1; // autonegotiation enable +assign gig_eth_pcspma_config_vector[3] = 1'b0; // isolate +assign gig_eth_pcspma_config_vector[2] = 1'b0; // power down +assign gig_eth_pcspma_config_vector[1] = 1'b0; // loopback enable +assign gig_eth_pcspma_config_vector[0] = 1'b0; // unidirectional enable + +wire [15:0] gig_eth_pcspma_an_config_vector; + +assign gig_eth_pcspma_an_config_vector[15] = 1'b1; // SGMII link status +assign gig_eth_pcspma_an_config_vector[14] = 1'b1; // SGMII Acknowledge +assign gig_eth_pcspma_an_config_vector[13:12] = 2'b01; // full duplex +assign gig_eth_pcspma_an_config_vector[11:10] = 2'b10; // SGMII speed +assign gig_eth_pcspma_an_config_vector[9] = 1'b0; // reserved +assign gig_eth_pcspma_an_config_vector[8:7] = 2'b00; // pause frames - SGMII reserved +assign gig_eth_pcspma_an_config_vector[6] = 1'b0; // reserved +assign gig_eth_pcspma_an_config_vector[5] = 1'b0; // full duplex - SGMII reserved +assign gig_eth_pcspma_an_config_vector[4:1] = 4'b0000; // reserved +assign gig_eth_pcspma_an_config_vector[0] = 1'b1; // SGMII + +gig_ethernet_pcs_pma_0 +eth_pcspma ( + // SGMII + .txp_0 (phy_sgmii_tx_p), + .txn_0 (phy_sgmii_tx_n), + .rxp_0 (phy_sgmii_rx_p), + .rxn_0 (phy_sgmii_rx_n), + + // Ref clock from PHY + .refclk625_p (phy_sgmii_clk_p), + .refclk625_n (phy_sgmii_clk_n), + + // async reset + .reset (rst_125mhz_int), + + // clock and reset outputs + .clk125_out (phy_gmii_clk_int), + .clk312_out (), + .rst_125_out (phy_gmii_rst_int), + .tx_logic_reset (), + .rx_logic_reset (), + .tx_locked (), + .rx_locked (), + .tx_pll_clk_out (), + .rx_pll_clk_out (), + + // MAC clocking + .sgmii_clk_r_0 (), + .sgmii_clk_f_0 (), + .sgmii_clk_en_0 (phy_gmii_clk_en_int), + + // Speed control + .speed_is_10_100_0 (gig_eth_pcspma_status_speed != 2'b10), + .speed_is_100_0 (gig_eth_pcspma_status_speed == 2'b01), + + // Internal GMII + .gmii_txd_0 (phy_gmii_txd_int), + .gmii_tx_en_0 (phy_gmii_tx_en_int), + .gmii_tx_er_0 (phy_gmii_tx_er_int), + .gmii_rxd_0 (phy_gmii_rxd_int), + .gmii_rx_dv_0 (phy_gmii_rx_dv_int), + .gmii_rx_er_0 (phy_gmii_rx_er_int), + .gmii_isolate_0 (), + + // Configuration + .configuration_vector_0 (gig_eth_pcspma_config_vector), + + .an_interrupt_0 (), + .an_adv_config_vector_0 (gig_eth_pcspma_an_config_vector), + .an_restart_config_0 (1'b0), + + // Status + .status_vector_0 (gig_eth_pcspma_status_vector), + .signal_detect_0 (1'b1), + + // Cascade + .tx_bsc_rst_out (), + .rx_bsc_rst_out (), + .tx_bs_rst_out (), + .rx_bs_rst_out (), + .tx_rst_dly_out (), + .rx_rst_dly_out (), + .tx_bsc_en_vtc_out (), + .rx_bsc_en_vtc_out (), + .tx_bs_en_vtc_out (), + .rx_bs_en_vtc_out (), + .riu_clk_out (), + .riu_addr_out (), + .riu_wr_data_out (), + .riu_wr_en_out (), + .riu_nibble_sel_out (), + .riu_rddata_1 (16'b0), + .riu_valid_1 (1'b0), + .riu_prsnt_1 (1'b0), + .riu_rddata_2 (16'b0), + .riu_valid_2 (1'b0), + .riu_prsnt_2 (1'b0), + .riu_rddata_3 (16'b0), + .riu_valid_3 (1'b0), + .riu_prsnt_3 (1'b0), + .rx_btval_1 (), + .rx_btval_2 (), + .rx_btval_3 (), + .tx_dly_rdy_1 (1'b1), + .rx_dly_rdy_1 (1'b1), + .rx_vtc_rdy_1 (1'b1), + .tx_vtc_rdy_1 (1'b1), + .tx_dly_rdy_2 (1'b1), + .rx_dly_rdy_2 (1'b1), + .rx_vtc_rdy_2 (1'b1), + .tx_vtc_rdy_2 (1'b1), + .tx_dly_rdy_3 (1'b1), + .rx_dly_rdy_3 (1'b1), + .rx_vtc_rdy_3 (1'b1), + .tx_vtc_rdy_3 (1'b1), + .tx_rdclk_out () +); + +reg [19:0] delay_reg = 20'hfffff; + +reg [4:0] mdio_cmd_phy_addr = 5'h03; +reg [4:0] mdio_cmd_reg_addr = 5'h00; +reg [15:0] mdio_cmd_data = 16'd0; +reg [1:0] mdio_cmd_opcode = 2'b01; +reg mdio_cmd_valid = 1'b0; +wire mdio_cmd_ready; + +reg [3:0] state_reg = 0; + +always @(posedge clk_125mhz_int) begin + if (rst_125mhz_int) begin + state_reg <= 0; + delay_reg <= 20'hfffff; + mdio_cmd_reg_addr <= 5'h00; + mdio_cmd_data <= 16'd0; + mdio_cmd_valid <= 1'b0; + end else begin + mdio_cmd_valid <= mdio_cmd_valid & !mdio_cmd_ready; + if (delay_reg > 0) begin + delay_reg <= delay_reg - 1; + end else if (!mdio_cmd_ready) begin + // wait for ready + state_reg <= state_reg; + end else begin + mdio_cmd_valid <= 1'b0; + case (state_reg) + // set SGMII autonegotiation timer to 11 ms + // write 0x0070 to CFG4 (0x0031) + 4'd0: begin + // write to REGCR to load address + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h001F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd1; + end + 4'd1: begin + // write address of CFG4 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h0031; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd2; + end + 4'd2: begin + // write to REGCR to load data + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h401F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd3; + end + 4'd3: begin + // write data for CFG4 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h0070; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd4; + end + // enable SGMII clock output + // write 0x4000 to SGMIICTL1 (0x00D3) + 4'd4: begin + // write to REGCR to load address + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h001F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd5; + end + 4'd5: begin + // write address of SGMIICTL1 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h00D3; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd6; + end + 4'd6: begin + // write to REGCR to load data + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h401F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd7; + end + 4'd7: begin + // write data for SGMIICTL1 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h4000; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd8; + end + // enable 10Mbps operation + // write 0x0015 to 10M_SGMII_CFG (0x016F) + 4'd8: begin + // write to REGCR to load address + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h001F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd9; + end + 4'd9: begin + // write address of 10M_SGMII_CFG to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h016F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd10; + end + 4'd10: begin + // write to REGCR to load data + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h401F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd11; + end + 4'd11: begin + // write data for 10M_SGMII_CFG to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h0015; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd12; + end + 4'd12: begin + // done + state_reg <= 4'd12; + end + endcase + end + end +end + +wire mdc; +wire mdio_i; +wire mdio_o; +wire mdio_t; + +mdio_master +mdio_master_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + + .cmd_phy_addr(mdio_cmd_phy_addr), + .cmd_reg_addr(mdio_cmd_reg_addr), + .cmd_data(mdio_cmd_data), + .cmd_opcode(mdio_cmd_opcode), + .cmd_valid(mdio_cmd_valid), + .cmd_ready(mdio_cmd_ready), + + .data_out(), + .data_out_valid(), + .data_out_ready(1'b1), + + .mdc_o(mdc), + .mdio_i(mdio_i), + .mdio_o(mdio_o), + .mdio_t(mdio_t), + + .busy(), + + .prescale(8'd3) +); + +assign phy_mdc = mdc; +assign mdio_i = phy_mdio; +assign phy_mdio = mdio_t ? 1'bz : mdio_o; + +wire [7:0] led_int; + +assign led = sw[0] ? {qsfp2_rx_block_lock_4, qsfp2_rx_block_lock_3, qsfp2_rx_block_lock_2, qsfp2_rx_block_lock_1, qsfp1_rx_block_lock_4, qsfp1_rx_block_lock_3, qsfp1_rx_block_lock_2, qsfp1_rx_block_lock_1} : led_int; + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .led(led_int), + /* + * Ethernet: QSFP28 + */ + .qsfp1_tx_clk_1(qsfp1_tx_clk_1_int), + .qsfp1_tx_rst_1(qsfp1_tx_rst_1_int), + .qsfp1_txd_1(qsfp1_txd_1_int), + .qsfp1_txc_1(qsfp1_txc_1_int), + .qsfp1_rx_clk_1(qsfp1_rx_clk_1_int), + .qsfp1_rx_rst_1(qsfp1_rx_rst_1_int), + .qsfp1_rxd_1(qsfp1_rxd_1_int), + .qsfp1_rxc_1(qsfp1_rxc_1_int), + .qsfp1_tx_clk_2(qsfp1_tx_clk_2_int), + .qsfp1_tx_rst_2(qsfp1_tx_rst_2_int), + .qsfp1_txd_2(qsfp1_txd_2_int), + .qsfp1_txc_2(qsfp1_txc_2_int), + .qsfp1_rx_clk_2(qsfp1_rx_clk_2_int), + .qsfp1_rx_rst_2(qsfp1_rx_rst_2_int), + .qsfp1_rxd_2(qsfp1_rxd_2_int), + .qsfp1_rxc_2(qsfp1_rxc_2_int), + .qsfp1_tx_clk_3(qsfp1_tx_clk_3_int), + .qsfp1_tx_rst_3(qsfp1_tx_rst_3_int), + .qsfp1_txd_3(qsfp1_txd_3_int), + .qsfp1_txc_3(qsfp1_txc_3_int), + .qsfp1_rx_clk_3(qsfp1_rx_clk_3_int), + .qsfp1_rx_rst_3(qsfp1_rx_rst_3_int), + .qsfp1_rxd_3(qsfp1_rxd_3_int), + .qsfp1_rxc_3(qsfp1_rxc_3_int), + .qsfp1_tx_clk_4(qsfp1_tx_clk_4_int), + .qsfp1_tx_rst_4(qsfp1_tx_rst_4_int), + .qsfp1_txd_4(qsfp1_txd_4_int), + .qsfp1_txc_4(qsfp1_txc_4_int), + .qsfp1_rx_clk_4(qsfp1_rx_clk_4_int), + .qsfp1_rx_rst_4(qsfp1_rx_rst_4_int), + .qsfp1_rxd_4(qsfp1_rxd_4_int), + .qsfp1_rxc_4(qsfp1_rxc_4_int), + .qsfp2_tx_clk_1(qsfp2_tx_clk_1_int), + .qsfp2_tx_rst_1(qsfp2_tx_rst_1_int), + .qsfp2_txd_1(qsfp2_txd_1_int), + .qsfp2_txc_1(qsfp2_txc_1_int), + .qsfp2_rx_clk_1(qsfp2_rx_clk_1_int), + .qsfp2_rx_rst_1(qsfp2_rx_rst_1_int), + .qsfp2_rxd_1(qsfp2_rxd_1_int), + .qsfp2_rxc_1(qsfp2_rxc_1_int), + .qsfp2_tx_clk_2(qsfp2_tx_clk_2_int), + .qsfp2_tx_rst_2(qsfp2_tx_rst_2_int), + .qsfp2_txd_2(qsfp2_txd_2_int), + .qsfp2_txc_2(qsfp2_txc_2_int), + .qsfp2_rx_clk_2(qsfp2_rx_clk_2_int), + .qsfp2_rx_rst_2(qsfp2_rx_rst_2_int), + .qsfp2_rxd_2(qsfp2_rxd_2_int), + .qsfp2_rxc_2(qsfp2_rxc_2_int), + .qsfp2_tx_clk_3(qsfp2_tx_clk_3_int), + .qsfp2_tx_rst_3(qsfp2_tx_rst_3_int), + .qsfp2_txd_3(qsfp2_txd_3_int), + .qsfp2_txc_3(qsfp2_txc_3_int), + .qsfp2_rx_clk_3(qsfp2_rx_clk_3_int), + .qsfp2_rx_rst_3(qsfp2_rx_rst_3_int), + .qsfp2_rxd_3(qsfp2_rxd_3_int), + .qsfp2_rxc_3(qsfp2_rxc_3_int), + .qsfp2_tx_clk_4(qsfp2_tx_clk_4_int), + .qsfp2_tx_rst_4(qsfp2_tx_rst_4_int), + .qsfp2_txd_4(qsfp2_txd_4_int), + .qsfp2_txc_4(qsfp2_txc_4_int), + .qsfp2_rx_clk_4(qsfp2_rx_clk_4_int), + .qsfp2_rx_rst_4(qsfp2_rx_rst_4_int), + .qsfp2_rxd_4(qsfp2_rxd_4_int), + .qsfp2_rxc_4(qsfp2_rxc_4_int), + /* + * Ethernet: 1000BASE-T SGMII + */ + .phy_gmii_clk(phy_gmii_clk_int), + .phy_gmii_rst(phy_gmii_rst_int), + .phy_gmii_clk_en(phy_gmii_clk_en_int), + .phy_gmii_rxd(phy_gmii_rxd_int), + .phy_gmii_rx_dv(phy_gmii_rx_dv_int), + .phy_gmii_rx_er(phy_gmii_rx_er_int), + .phy_gmii_txd(phy_gmii_txd_int), + .phy_gmii_tx_en(phy_gmii_tx_en_int), + .phy_gmii_tx_er(phy_gmii_tx_er_int), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts_int) +); + +endmodule diff --git a/example/VCU118/fpga_10g/rtl/fpga_core.v b/example/VCU118/fpga_10g/rtl/fpga_core.v new file mode 100644 index 000000000..be0715979 --- /dev/null +++ b/example/VCU118/fpga_10g/rtl/fpga_core.v @@ -0,0 +1,949 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * Ethernet: QSFP28 + */ + input wire qsfp1_tx_clk_1, + input wire qsfp1_tx_rst_1, + output wire [63:0] qsfp1_txd_1, + output wire [7:0] qsfp1_txc_1, + input wire qsfp1_rx_clk_1, + input wire qsfp1_rx_rst_1, + input wire [63:0] qsfp1_rxd_1, + input wire [7:0] qsfp1_rxc_1, + input wire qsfp1_tx_clk_2, + input wire qsfp1_tx_rst_2, + output wire [63:0] qsfp1_txd_2, + output wire [7:0] qsfp1_txc_2, + input wire qsfp1_rx_clk_2, + input wire qsfp1_rx_rst_2, + input wire [63:0] qsfp1_rxd_2, + input wire [7:0] qsfp1_rxc_2, + input wire qsfp1_tx_clk_3, + input wire qsfp1_tx_rst_3, + output wire [63:0] qsfp1_txd_3, + output wire [7:0] qsfp1_txc_3, + input wire qsfp1_rx_clk_3, + input wire qsfp1_rx_rst_3, + input wire [63:0] qsfp1_rxd_3, + input wire [7:0] qsfp1_rxc_3, + input wire qsfp1_tx_clk_4, + input wire qsfp1_tx_rst_4, + output wire [63:0] qsfp1_txd_4, + output wire [7:0] qsfp1_txc_4, + input wire qsfp1_rx_clk_4, + input wire qsfp1_rx_rst_4, + input wire [63:0] qsfp1_rxd_4, + input wire [7:0] qsfp1_rxc_4, + input wire qsfp2_tx_clk_1, + input wire qsfp2_tx_rst_1, + output wire [63:0] qsfp2_txd_1, + output wire [7:0] qsfp2_txc_1, + input wire qsfp2_rx_clk_1, + input wire qsfp2_rx_rst_1, + input wire [63:0] qsfp2_rxd_1, + input wire [7:0] qsfp2_rxc_1, + input wire qsfp2_tx_clk_2, + input wire qsfp2_tx_rst_2, + output wire [63:0] qsfp2_txd_2, + output wire [7:0] qsfp2_txc_2, + input wire qsfp2_rx_clk_2, + input wire qsfp2_rx_rst_2, + input wire [63:0] qsfp2_rxd_2, + input wire [7:0] qsfp2_rxc_2, + input wire qsfp2_tx_clk_3, + input wire qsfp2_tx_rst_3, + output wire [63:0] qsfp2_txd_3, + output wire [7:0] qsfp2_txc_3, + input wire qsfp2_rx_clk_3, + input wire qsfp2_rx_rst_3, + input wire [63:0] qsfp2_rxd_3, + input wire [7:0] qsfp2_rxc_3, + input wire qsfp2_tx_clk_4, + input wire qsfp2_tx_rst_4, + output wire [63:0] qsfp2_txd_4, + output wire [7:0] qsfp2_txc_4, + input wire qsfp2_rx_clk_4, + input wire qsfp2_rx_rst_4, + input wire [63:0] qsfp2_rxd_4, + input wire [7:0] qsfp2_rxc_4, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_gmii_clk, + input wire phy_gmii_rst, + input wire phy_gmii_clk_en, + input wire [7:0] phy_gmii_rxd, + input wire phy_gmii_rx_dv, + input wire phy_gmii_rx_er, + output wire [7:0] phy_gmii_txd, + output wire phy_gmii_tx_en, + output wire phy_gmii_tx_er, + output wire phy_reset_n, + input wire phy_int_n, + + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// AXI between MAC and Ethernet modules +wire [63:0] mac_rx_axis_tdata; +wire [7:0] mac_rx_axis_tkeep; +wire mac_rx_axis_tvalid; +wire mac_rx_axis_tready; +wire mac_rx_axis_tlast; +wire mac_rx_axis_tuser; + +wire [63:0] mac_tx_axis_tdata; +wire [7:0] mac_tx_axis_tkeep; +wire mac_tx_axis_tvalid; +wire mac_tx_axis_tready; +wire mac_tx_axis_tlast; +wire mac_tx_axis_tuser; + +wire [63:0] rx_axis_tdata; +wire [7:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [63:0] tx_axis_tdata; +wire [7:0] tx_axis_tkeep; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [63:0] rx_eth_payload_tdata; +wire [7:0] rx_eth_payload_tkeep; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [63:0] tx_eth_payload_tdata; +wire [7:0] tx_eth_payload_tkeep; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [63:0] rx_ip_payload_tdata; +wire [7:0] rx_ip_payload_tkeep; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [63:0] tx_ip_payload_tdata; +wire [7:0] tx_ip_payload_tkeep; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [63:0] rx_udp_payload_tdata; +wire [7:0] rx_udp_payload_tkeep; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [63:0] tx_udp_payload_tdata; +wire [7:0] tx_udp_payload_tkeep; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [63:0] rx_fifo_udp_payload_tdata; +wire [7:0] rx_fifo_udp_payload_tkeep; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [63:0] tx_fifo_udp_payload_tdata; +wire [7:0] tx_fifo_udp_payload_tkeep; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_tdata = 0; +assign tx_ip_payload_tkeep = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; +//assign tx_udp_payload_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tkeep = rx_udp_payload_tkeep; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tkeep = tx_fifo_udp_payload_tkeep; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tkeep = rx_udp_payload_tkeep; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_tvalid; + if (tx_udp_payload_tvalid & ~valid_last) begin + led_reg <= tx_udp_payload_tdata; + end + end +end + +//assign led = sw; +assign led = led_reg; +assign phy_reset_n = ~rst; + +assign qsfp1_txd_2 = 64'h0707070707070707; +assign qsfp1_txc_2 = 8'hff; +assign qsfp1_txd_3 = 64'h0707070707070707; +assign qsfp1_txc_3 = 8'hff; +assign qsfp1_txd_4 = 64'h0707070707070707; +assign qsfp1_txc_4 = 8'hff; + +assign qsfp2_txd_1 = 64'h0707070707070707; +assign qsfp2_txc_1 = 8'hff; +assign qsfp2_txd_2 = 64'h0707070707070707; +assign qsfp2_txc_2 = 8'hff; +assign qsfp2_txd_3 = 64'h0707070707070707; +assign qsfp2_txc_3 = 8'hff; +assign qsfp2_txd_4 = 64'h0707070707070707; +assign qsfp2_txc_4 = 8'hff; + +eth_mac_10g_fifo #( + .ENABLE_PADDING(1), + .ENABLE_DIC(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(9), + .RX_FIFO_ADDR_WIDTH(9) +) +eth_mac_10g_fifo_inst ( + .rx_clk(qsfp1_rx_clk_1), + .rx_rst(qsfp1_rx_rst_1), + .tx_clk(qsfp1_tx_clk_1), + .tx_rst(qsfp1_tx_rst_1), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(mac_tx_axis_tdata), + .tx_axis_tkeep(mac_tx_axis_tkeep), + .tx_axis_tvalid(mac_tx_axis_tvalid), + .tx_axis_tready(mac_tx_axis_tready), + .tx_axis_tlast(mac_tx_axis_tlast), + .tx_axis_tuser(mac_tx_axis_tuser), + + .rx_axis_tdata(mac_rx_axis_tdata), + .rx_axis_tkeep(mac_rx_axis_tkeep), + .rx_axis_tvalid(mac_rx_axis_tvalid), + .rx_axis_tready(mac_rx_axis_tready), + .rx_axis_tlast(mac_rx_axis_tlast), + .rx_axis_tuser(mac_rx_axis_tuser), + + .xgmii_rxd(qsfp1_rxd_1), + .xgmii_rxc(qsfp1_rxc_1), + .xgmii_txd(qsfp1_txd_1), + .xgmii_txc(qsfp1_txc_1), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + .ifg_delay(8'd12) +); + +// 1G interface for debugging +wire [7:0] gig_rx_axis_tdata; +wire gig_rx_axis_tvalid; +wire gig_rx_axis_tready; +wire gig_rx_axis_tlast; +wire gig_rx_axis_tuser; + +wire [7:0] gig_tx_axis_tdata; +wire gig_tx_axis_tvalid; +wire gig_tx_axis_tready; +wire gig_tx_axis_tlast; +wire gig_tx_axis_tuser; + +wire [63:0] gig_rx_axis_tdata_64; +wire [7:0] gig_rx_axis_tkeep_64; +wire gig_rx_axis_tvalid_64; +wire gig_rx_axis_tready_64; +wire gig_rx_axis_tlast_64; +wire gig_rx_axis_tuser_64; + +wire [63:0] gig_tx_axis_tdata_64; +wire [7:0] gig_tx_axis_tkeep_64; +wire gig_tx_axis_tvalid_64; +wire gig_tx_axis_tready_64; +wire gig_tx_axis_tlast_64; +wire gig_tx_axis_tuser_64; + +eth_mac_1g_fifo #( + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .RX_FIFO_ADDR_WIDTH(12) +) +eth_mac_1g_inst ( + .rx_clk(phy_gmii_clk), + .rx_rst(phy_gmii_rst), + .tx_clk(phy_gmii_clk), + .tx_rst(phy_gmii_rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(gig_tx_axis_tdata), + .tx_axis_tvalid(gig_tx_axis_tvalid), + .tx_axis_tready(gig_tx_axis_tready), + .tx_axis_tlast(gig_tx_axis_tlast), + .tx_axis_tuser(gig_tx_axis_tuser), + + .rx_axis_tdata(gig_rx_axis_tdata), + .rx_axis_tvalid(gig_rx_axis_tvalid), + .rx_axis_tready(gig_rx_axis_tready), + .rx_axis_tlast(gig_rx_axis_tlast), + .rx_axis_tuser(gig_rx_axis_tuser), + + .gmii_rxd(phy_gmii_rxd), + .gmii_rx_dv(phy_gmii_rx_dv), + .gmii_rx_er(phy_gmii_rx_er), + .gmii_txd(phy_gmii_txd), + .gmii_tx_en(phy_gmii_tx_en), + .gmii_tx_er(phy_gmii_tx_er), + + .rx_clk_enable(phy_gmii_clk_en), + .tx_clk_enable(phy_gmii_clk_en), + .rx_mii_select(1'b0), + .tx_mii_select(1'b0), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + .ifg_delay(12) +); + +axis_adapter #( + .INPUT_DATA_WIDTH(8), + .OUTPUT_DATA_WIDTH(64) +) +gig_rx_axis_adapter_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(gig_rx_axis_tdata), + .input_axis_tkeep(1'b1), + .input_axis_tvalid(gig_rx_axis_tvalid), + .input_axis_tready(gig_rx_axis_tready), + .input_axis_tlast(gig_rx_axis_tlast), + .input_axis_tuser(gig_rx_axis_tuser), + // AXI output + .output_axis_tdata(gig_rx_axis_tdata_64), + .output_axis_tkeep(gig_rx_axis_tkeep_64), + .output_axis_tvalid(gig_rx_axis_tvalid_64), + .output_axis_tready(gig_rx_axis_tready_64), + .output_axis_tlast(gig_rx_axis_tlast_64), + .output_axis_tuser(gig_rx_axis_tuser_64) +); + +axis_adapter #( + .INPUT_DATA_WIDTH(64), + .OUTPUT_DATA_WIDTH(8) +) +gig_tx_axis_adapter_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(gig_tx_axis_tdata_64), + .input_axis_tkeep(gig_tx_axis_tkeep_64), + .input_axis_tvalid(gig_tx_axis_tvalid_64), + .input_axis_tready(gig_tx_axis_tready_64), + .input_axis_tlast(gig_tx_axis_tlast_64), + .input_axis_tuser(gig_tx_axis_tuser_64), + // AXI output + .output_axis_tdata(gig_tx_axis_tdata), + .output_axis_tkeep(), + .output_axis_tvalid(gig_tx_axis_tvalid), + .output_axis_tready(gig_tx_axis_tready), + .output_axis_tlast(gig_tx_axis_tlast), + .output_axis_tuser(gig_tx_axis_tuser) +); + +// tap port mux logic +// sw[3] enable +// sw[2] select 0 rx, 1 tx + +reg [1:0] mac_rx_tdest; +reg [1:0] tx_tdest; +reg [1:0] gig_rx_tdest; + +always @* begin + if (sw[3]) begin + if (sw[2]) begin + // Tap on TX path + // MAC RX out -> stack RX in + // stack TX out -> gig TX in + // gig RX out -> MAC TX in + mac_rx_tdest = 2'd1; + tx_tdest = 2'd2; + gig_rx_tdest = 2'd0; + end else begin + // Tap on RX path + // MAC RX out -> gig TX in + // stack TX out -> MAC TX in + // gig RX out -> stack RX in + mac_rx_tdest = 2'd2; + tx_tdest = 2'd0; + gig_rx_tdest = 2'd1; + end + end else begin + // Tap disabled + // MAC RX out -> stack RX in + // stack TX out -> MAC TX in + // gig RX out -> blackhole + mac_rx_tdest = 2'd1; + tx_tdest = 2'd0; + gig_rx_tdest = 2'd3; + end +end + +axis_switch_4x4 #( + .DATA_WIDTH(64), + .KEEP_WIDTH(8), + .ID_ENABLE(0), + .DEST_WIDTH(2), + .USER_ENABLE(1), + .USER_WIDTH(1), + .OUT_0_BASE(0), + .OUT_0_TOP(0), + .OUT_0_CONNECT(4'b1111), + .OUT_1_BASE(1), + .OUT_1_TOP(1), + .OUT_1_CONNECT(4'b1111), + .OUT_2_BASE(2), + .OUT_2_TOP(2), + .OUT_2_CONNECT(4'b1111), + .OUT_3_BASE(3), + .OUT_3_TOP(3), + .OUT_3_CONNECT(4'b1111), + .ARB_TYPE("PRIORITY"), + .LSB_PRIORITY("HIGH") +) +axis_switch_inst ( + .clk(clk), + .rst(rst), + // AXI inputs + .input_0_axis_tdata(mac_rx_axis_tdata), + .input_0_axis_tkeep(mac_rx_axis_tkeep), + .input_0_axis_tvalid(mac_rx_axis_tvalid), + .input_0_axis_tready(mac_rx_axis_tready), + .input_0_axis_tlast(mac_rx_axis_tlast), + .input_0_axis_tid(0), + .input_0_axis_tdest(mac_rx_tdest), + .input_0_axis_tuser(mac_rx_axis_tuser), + .input_1_axis_tdata(tx_axis_tdata), + .input_1_axis_tkeep(tx_axis_tkeep), + .input_1_axis_tvalid(tx_axis_tvalid), + .input_1_axis_tready(tx_axis_tready), + .input_1_axis_tlast(tx_axis_tlast), + .input_1_axis_tid(0), + .input_1_axis_tdest(tx_tdest), + .input_1_axis_tuser(tx_axis_tuser), + .input_2_axis_tdata(gig_rx_axis_tdata_64), + .input_2_axis_tkeep(gig_rx_axis_tkeep_64), + .input_2_axis_tvalid(gig_rx_axis_tvalid_64), + .input_2_axis_tready(gig_rx_axis_tready_64), + .input_2_axis_tlast(gig_rx_axis_tlast_64), + .input_2_axis_tid(0), + .input_2_axis_tdest(gig_rx_tdest), + .input_2_axis_tuser(gig_rx_axis_tuser_64), + .input_3_axis_tdata(64'd0), + .input_3_axis_tkeep(8'd0), + .input_3_axis_tvalid(1'b0), + .input_3_axis_tready(), + .input_3_axis_tlast(1'b0), + .input_3_axis_tid(0), + .input_3_axis_tdest(2'd0), + .input_3_axis_tuser(1'b0), + // AXI outputs + .output_0_axis_tdata(mac_tx_axis_tdata), + .output_0_axis_tkeep(mac_tx_axis_tkeep), + .output_0_axis_tvalid(mac_tx_axis_tvalid), + .output_0_axis_tready(mac_tx_axis_tready), + .output_0_axis_tlast(mac_tx_axis_tlast), + .output_0_axis_tid(), + .output_0_axis_tdest(), + .output_0_axis_tuser(mac_tx_axis_tuser), + .output_1_axis_tdata(rx_axis_tdata), + .output_1_axis_tkeep(rx_axis_tkeep), + .output_1_axis_tvalid(rx_axis_tvalid), + .output_1_axis_tready(rx_axis_tready), + .output_1_axis_tlast(rx_axis_tlast), + .output_1_axis_tid(), + .output_1_axis_tdest(), + .output_1_axis_tuser(rx_axis_tuser), + .output_2_axis_tdata(gig_tx_axis_tdata_64), + .output_2_axis_tkeep(gig_tx_axis_tkeep_64), + .output_2_axis_tvalid(gig_tx_axis_tvalid_64), + .output_2_axis_tready(gig_tx_axis_tready_64), + .output_2_axis_tlast(gig_tx_axis_tlast_64), + .output_2_axis_tid(), + .output_2_axis_tdest(), + .output_2_axis_tuser(gig_tx_axis_tuser_64), + .output_3_axis_tdata(), + .output_3_axis_tkeep(), + .output_3_axis_tvalid(), + .output_3_axis_tready(1'b1), + .output_3_axis_tlast(), + .output_3_axis_tid(), + .output_3_axis_tdest(), + .output_3_axis_tuser() +); + +eth_axis_rx_64 +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tkeep(rx_axis_tkeep), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tkeep(rx_eth_payload_tkeep), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx_64 +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tkeep(tx_eth_payload_tkeep), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tkeep(tx_axis_tkeep), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete_64 +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tkeep(rx_eth_payload_tkeep), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tkeep(tx_eth_payload_tkeep), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tkeep(tx_ip_payload_tkeep), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tkeep(rx_ip_payload_tkeep), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tkeep(tx_udp_payload_tkeep), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tkeep(rx_udp_payload_tkeep), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(1'b0) +); + +axis_fifo #( + .ADDR_WIDTH(10), + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(8), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(rx_fifo_udp_payload_tkeep), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tid(0), + .input_axis_tdest(0), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(tx_fifo_udp_payload_tkeep), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tid(), + .output_axis_tdest(), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/VCU118/fpga_10g/rtl/mdio_master.v b/example/VCU118/fpga_10g/rtl/mdio_master.v new file mode 100644 index 000000000..1dc56a8cf --- /dev/null +++ b/example/VCU118/fpga_10g/rtl/mdio_master.v @@ -0,0 +1,225 @@ +/* + +Copyright (c) 2015-2018 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 + +/* + * MDIO master + */ +module mdio_master ( + input wire clk, + input wire rst, + + /* + * Host interface + */ + input wire [4:0] cmd_phy_addr, + input wire [4:0] cmd_reg_addr, + input wire [15:0] cmd_data, + input wire [1:0] cmd_opcode, + input wire cmd_valid, + output wire cmd_ready, + + output wire [15:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + + /* + * MDIO to PHY + */ + output wire mdc_o, + input wire mdio_i, + output wire mdio_o, + output wire mdio_t, + + /* + * Status + */ + output wire busy, + + /* + * Configuration + */ + input wire [7:0] prescale +); + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PREAMBLE = 2'd1, + STATE_TRANSFER = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [16:0] count_reg = 16'd0, count_next; +reg [6:0] bit_count_reg = 6'd0, bit_count_next; +reg cycle_reg = 1'b0, cycle_next; + +reg [31:0] data_reg = 32'd0, data_next; + +reg [1:0] op_reg = 2'b00, op_next; + +reg cmd_ready_reg = 1'b0, cmd_ready_next; + +reg [15:0] data_out_reg = 15'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; + +reg mdio_i_reg = 1'b1; + +reg mdc_o_reg = 1'b0, mdc_o_next; +reg mdio_o_reg = 1'b0, mdio_o_next; +reg mdio_t_reg = 1'b1, mdio_t_next; + +reg busy_reg = 1'b0; + +assign cmd_ready = cmd_ready_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; + +assign mdc_o = mdc_o_reg; +assign mdio_o = mdio_o_reg; +assign mdio_t = mdio_t_reg; + +assign busy = busy_reg; + +always @* begin + state_next = STATE_IDLE; + + count_next = count_reg; + bit_count_next = bit_count_reg; + cycle_next = cycle_reg; + + data_next = data_reg; + + op_next = op_reg; + + cmd_ready_next = 1'b0; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + + mdc_o_next = mdc_o_reg; + mdio_o_next = mdio_o_reg; + mdio_t_next = mdio_t_reg; + + if (count_reg > 16'd0) begin + count_next = count_reg - 16'd1; + state_next = state_reg; + end else if (cycle_reg) begin + cycle_next = 1'b0; + mdc_o_next = 1'b1; + count_next = prescale; + state_next = state_reg; + end else begin + mdc_o_next = 1'b0; + case (state_reg) + STATE_IDLE: begin + // idle - accept new command + cmd_ready_next = ~data_out_valid; + + if (cmd_ready & cmd_valid) begin + cmd_ready_next = 1'b0; + data_next = {2'b01, cmd_opcode, cmd_phy_addr, cmd_reg_addr, 2'b10, cmd_data}; + op_next = cmd_opcode; + mdio_t_next = 1'b0; + mdio_o_next = 1'b1; + bit_count_next = 6'd32; + cycle_next = 1'b1; + count_next = prescale; + state_next = STATE_PREAMBLE; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PREAMBLE: begin + cycle_next = 1'b1; + count_next = prescale; + if (bit_count_reg > 6'd1) begin + bit_count_next = bit_count_reg - 6'd1; + state_next = STATE_PREAMBLE; + end else begin + bit_count_next = 6'd32; + {mdio_o_next, data_next} = {data_reg, mdio_i_reg}; + state_next = STATE_TRANSFER; + end + end + STATE_TRANSFER: begin + cycle_next = 1'b1; + count_next = prescale; + if ((op_reg == 2'b10 || op_reg == 2'b11) && bit_count_reg == 6'd19) begin + mdio_t_next = 1'b1; + end + if (bit_count_reg > 6'd1) begin + bit_count_next = bit_count_reg - 6'd1; + {mdio_o_next, data_next} = {data_reg, mdio_i_reg}; + state_next = STATE_TRANSFER; + end else begin + if (op_reg == 2'b10 || op_reg == 2'b11) begin + data_out_next = data_reg[15:0]; + data_out_valid_next = 1'b1; + end + mdio_t_next = 1'b1; + state_next = STATE_IDLE; + end + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + count_reg <= 16'd0; + bit_count_reg <= 6'd0; + cycle_reg <= 1'b0; + cmd_ready_reg <= 1'b0; + data_out_valid_reg <= 1'b0; + mdc_o_reg <= 1'b0; + mdio_o_reg <= 1'b0; + mdio_t_reg <= 1'b1; + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + count_reg <= count_next; + bit_count_reg <= bit_count_next; + cycle_reg <= cycle_next; + cmd_ready_reg <= cmd_ready_next; + data_out_valid_reg <= data_out_valid_next; + mdc_o_reg <= mdc_o_next; + mdio_o_reg <= mdio_o_next; + mdio_t_reg <= mdio_t_next; + busy_reg <= (state_next != STATE_IDLE || count_reg != 0 || cycle_reg || mdc_o); + end + + data_reg <= data_next; + op_reg <= op_next; + + data_out_reg <= data_out_next; + + mdio_i_reg <= mdio_i; +end + +endmodule diff --git a/example/VCU118/fpga_10g/rtl/sync_reset.v b/example/VCU118/fpga_10g/rtl/sync_reset.v new file mode 100644 index 000000000..acbcf1c6e --- /dev/null +++ b/example/VCU118/fpga_10g/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/VCU118/fpga_10g/rtl/sync_signal.v b/example/VCU118/fpga_10g/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/example/VCU118/fpga_10g/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/VCU118/fpga_10g/tb/arp_ep.py b/example/VCU118/fpga_10g/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/VCU118/fpga_10g/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_10g/tb/axis_ep.py b/example/VCU118/fpga_10g/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/VCU118/fpga_10g/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_10g/tb/eth_ep.py b/example/VCU118/fpga_10g/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/VCU118/fpga_10g/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_10g/tb/gmii_ep.py b/example/VCU118/fpga_10g/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/VCU118/fpga_10g/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_10g/tb/ip_ep.py b/example/VCU118/fpga_10g/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/VCU118/fpga_10g/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_10g/tb/test_fpga_core.py b/example/VCU118/fpga_10g/tb/test_fpga_core.py new file mode 100755 index 000000000..7c63bd06d --- /dev/null +++ b/example/VCU118/fpga_10g/tb/test_fpga_core.py @@ -0,0 +1,690 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016-2018 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 + +import eth_ep +import arp_ep +import udp_ep +import gmii_ep +import xgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux_64_2.v") +srcs.append("../lib/eth/rtl/ip_mux_64_2.v") +srcs.append("../lib/eth/rtl/arp_64.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") +srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") +srcs.append("../lib/eth/rtl/eth_mux_64_2.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_adapter.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_switch_4x4.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[4:]) + qsfp1_tx_clk_1 = Signal(bool(0)) + qsfp1_tx_rst_1 = Signal(bool(0)) + qsfp1_rx_clk_1 = Signal(bool(0)) + qsfp1_rx_rst_1 = Signal(bool(0)) + qsfp1_rxd_1 = Signal(intbv(0)[64:]) + qsfp1_rxc_1 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_2 = Signal(bool(0)) + qsfp1_tx_rst_2 = Signal(bool(0)) + qsfp1_rx_clk_2 = Signal(bool(0)) + qsfp1_rx_rst_2 = Signal(bool(0)) + qsfp1_rxd_2 = Signal(intbv(0)[64:]) + qsfp1_rxc_2 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_3 = Signal(bool(0)) + qsfp1_tx_rst_3 = Signal(bool(0)) + qsfp1_rx_clk_3 = Signal(bool(0)) + qsfp1_rx_rst_3 = Signal(bool(0)) + qsfp1_rxd_3 = Signal(intbv(0)[64:]) + qsfp1_rxc_3 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_4 = Signal(bool(0)) + qsfp1_tx_rst_4 = Signal(bool(0)) + qsfp1_rx_clk_4 = Signal(bool(0)) + qsfp1_rx_rst_4 = Signal(bool(0)) + qsfp1_rxd_4 = Signal(intbv(0)[64:]) + qsfp1_rxc_4 = Signal(intbv(0)[8:]) + qsfp2_tx_clk_1 = Signal(bool(0)) + qsfp2_tx_rst_1 = Signal(bool(0)) + qsfp2_rx_clk_1 = Signal(bool(0)) + qsfp2_rx_rst_1 = Signal(bool(0)) + qsfp2_rxd_1 = Signal(intbv(0)[64:]) + qsfp2_rxc_1 = Signal(intbv(0)[8:]) + qsfp2_tx_clk_2 = Signal(bool(0)) + qsfp2_tx_rst_2 = Signal(bool(0)) + qsfp2_rx_clk_2 = Signal(bool(0)) + qsfp2_rx_rst_2 = Signal(bool(0)) + qsfp2_rxd_2 = Signal(intbv(0)[64:]) + qsfp2_rxc_2 = Signal(intbv(0)[8:]) + qsfp2_tx_clk_3 = Signal(bool(0)) + qsfp2_tx_rst_3 = Signal(bool(0)) + qsfp2_rx_clk_3 = Signal(bool(0)) + qsfp2_rx_rst_3 = Signal(bool(0)) + qsfp2_rxd_3 = Signal(intbv(0)[64:]) + qsfp2_rxc_3 = Signal(intbv(0)[8:]) + qsfp2_tx_clk_4 = Signal(bool(0)) + qsfp2_tx_rst_4 = Signal(bool(0)) + qsfp2_rx_clk_4 = Signal(bool(0)) + qsfp2_rx_rst_4 = Signal(bool(0)) + qsfp2_rxd_4 = Signal(intbv(0)[64:]) + qsfp2_rxc_4 = Signal(intbv(0)[8:]) + phy_gmii_clk = Signal(bool(0)) + phy_gmii_rst = Signal(bool(0)) + phy_gmii_clk_en = Signal(bool(0)) + phy_gmii_rxd = Signal(intbv(0)[8:]) + phy_gmii_rx_dv = Signal(bool(0)) + phy_gmii_rx_er = Signal(bool(0)) + phy_int_n = Signal(bool(1)) + uart_rxd = Signal(bool(0)) + uart_cts = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[8:]) + qsfp1_txd_1 = Signal(intbv(0)[64:]) + qsfp1_txc_1 = Signal(intbv(0)[8:]) + qsfp1_txd_2 = Signal(intbv(0)[64:]) + qsfp1_txc_2 = Signal(intbv(0)[8:]) + qsfp1_txd_3 = Signal(intbv(0)[64:]) + qsfp1_txc_3 = Signal(intbv(0)[8:]) + qsfp1_txd_4 = Signal(intbv(0)[64:]) + qsfp1_txc_4 = Signal(intbv(0)[8:]) + qsfp2_txd_1 = Signal(intbv(0)[64:]) + qsfp2_txc_1 = Signal(intbv(0)[8:]) + qsfp2_txd_2 = Signal(intbv(0)[64:]) + qsfp2_txc_2 = Signal(intbv(0)[8:]) + qsfp2_txd_3 = Signal(intbv(0)[64:]) + qsfp2_txc_3 = Signal(intbv(0)[8:]) + qsfp2_txd_4 = Signal(intbv(0)[64:]) + qsfp2_txc_4 = Signal(intbv(0)[8:]) + phy_gmii_txd = Signal(intbv(0)[8:]) + phy_gmii_tx_en = Signal(bool(0)) + phy_gmii_tx_er = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + + # sources and sinks + qsfp1_1_source = xgmii_ep.XGMIISource() + qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') + + qsfp1_1_sink = xgmii_ep.XGMIISink() + qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') + + qsfp1_2_source = xgmii_ep.XGMIISource() + qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') + + qsfp1_2_sink = xgmii_ep.XGMIISink() + qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') + + qsfp1_3_source = xgmii_ep.XGMIISource() + qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') + + qsfp1_3_sink = xgmii_ep.XGMIISink() + qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') + + qsfp1_4_source = xgmii_ep.XGMIISource() + qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') + + qsfp1_4_sink = xgmii_ep.XGMIISink() + qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') + + qsfp1_1_source = xgmii_ep.XGMIISource() + qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') + + qsfp1_1_sink = xgmii_ep.XGMIISink() + qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') + + qsfp1_2_source = xgmii_ep.XGMIISource() + qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') + + qsfp1_2_sink = xgmii_ep.XGMIISink() + qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') + + qsfp1_3_source = xgmii_ep.XGMIISource() + qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') + + qsfp1_3_sink = xgmii_ep.XGMIISink() + qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') + + qsfp1_4_source = xgmii_ep.XGMIISource() + qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') + + qsfp1_4_sink = xgmii_ep.XGMIISink() + qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') + + gmii_source = gmii_ep.GMIISource() + + gmii_source_logic = gmii_source.create_logic( + phy_gmii_clk, + phy_gmii_rst, + txd=phy_gmii_rxd, + tx_en=phy_gmii_rx_dv, + tx_er=phy_gmii_rx_er, + clk_enable=phy_gmii_clk_en, + name='gmii_source' + ) + + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + phy_gmii_clk, + phy_gmii_rst, + rxd=phy_gmii_txd, + rx_dv=phy_gmii_tx_en, + rx_er=phy_gmii_tx_er, + clk_enable=phy_gmii_clk_en, + name='gmii_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, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, + + qsfp1_tx_clk_1=qsfp1_tx_clk_1, + qsfp1_tx_rst_1=qsfp1_tx_rst_1, + qsfp1_txd_1=qsfp1_txd_1, + qsfp1_txc_1=qsfp1_txc_1, + qsfp1_rx_clk_1=qsfp1_rx_clk_1, + qsfp1_rx_rst_1=qsfp1_rx_rst_1, + qsfp1_rxd_1=qsfp1_rxd_1, + qsfp1_rxc_1=qsfp1_rxc_1, + qsfp1_tx_clk_2=qsfp1_tx_clk_2, + qsfp1_tx_rst_2=qsfp1_tx_rst_2, + qsfp1_txd_2=qsfp1_txd_2, + qsfp1_txc_2=qsfp1_txc_2, + qsfp1_rx_clk_2=qsfp1_rx_clk_2, + qsfp1_rx_rst_2=qsfp1_rx_rst_2, + qsfp1_rxd_2=qsfp1_rxd_2, + qsfp1_rxc_2=qsfp1_rxc_2, + qsfp1_tx_clk_3=qsfp1_tx_clk_3, + qsfp1_tx_rst_3=qsfp1_tx_rst_3, + qsfp1_txd_3=qsfp1_txd_3, + qsfp1_txc_3=qsfp1_txc_3, + qsfp1_rx_clk_3=qsfp1_rx_clk_3, + qsfp1_rx_rst_3=qsfp1_rx_rst_3, + qsfp1_rxd_3=qsfp1_rxd_3, + qsfp1_rxc_3=qsfp1_rxc_3, + qsfp1_tx_clk_4=qsfp1_tx_clk_4, + qsfp1_tx_rst_4=qsfp1_tx_rst_4, + qsfp1_txd_4=qsfp1_txd_4, + qsfp1_txc_4=qsfp1_txc_4, + qsfp1_rx_clk_4=qsfp1_rx_clk_4, + qsfp1_rx_rst_4=qsfp1_rx_rst_4, + qsfp1_rxd_4=qsfp1_rxd_4, + qsfp1_rxc_4=qsfp1_rxc_4, + qsfp2_tx_clk_1=qsfp2_tx_clk_1, + qsfp2_tx_rst_1=qsfp2_tx_rst_1, + qsfp2_txd_1=qsfp2_txd_1, + qsfp2_txc_1=qsfp2_txc_1, + qsfp2_rx_clk_1=qsfp2_rx_clk_1, + qsfp2_rx_rst_1=qsfp2_rx_rst_1, + qsfp2_rxd_1=qsfp2_rxd_1, + qsfp2_rxc_1=qsfp2_rxc_1, + qsfp2_tx_clk_2=qsfp2_tx_clk_2, + qsfp2_tx_rst_2=qsfp2_tx_rst_2, + qsfp2_txd_2=qsfp2_txd_2, + qsfp2_txc_2=qsfp2_txc_2, + qsfp2_rx_clk_2=qsfp2_rx_clk_2, + qsfp2_rx_rst_2=qsfp2_rx_rst_2, + qsfp2_rxd_2=qsfp2_rxd_2, + qsfp2_rxc_2=qsfp2_rxc_2, + qsfp2_tx_clk_3=qsfp2_tx_clk_3, + qsfp2_tx_rst_3=qsfp2_tx_rst_3, + qsfp2_txd_3=qsfp2_txd_3, + qsfp2_txc_3=qsfp2_txc_3, + qsfp2_rx_clk_3=qsfp2_rx_clk_3, + qsfp2_rx_rst_3=qsfp2_rx_rst_3, + qsfp2_rxd_3=qsfp2_rxd_3, + qsfp2_rxc_3=qsfp2_rxc_3, + qsfp2_tx_clk_4=qsfp2_tx_clk_4, + qsfp2_tx_rst_4=qsfp2_tx_rst_4, + qsfp2_txd_4=qsfp2_txd_4, + qsfp2_txc_4=qsfp2_txc_4, + qsfp2_rx_clk_4=qsfp2_rx_clk_4, + qsfp2_rx_rst_4=qsfp2_rx_rst_4, + qsfp2_rxd_4=qsfp2_rxd_4, + qsfp2_rxc_4=qsfp2_rxc_4, + + phy_gmii_clk=phy_gmii_clk, + phy_gmii_rst=phy_gmii_rst, + phy_gmii_clk_en=phy_gmii_clk_en, + phy_gmii_rxd=phy_gmii_rxd, + phy_gmii_rx_dv=phy_gmii_rx_dv, + phy_gmii_rx_er=phy_gmii_rx_er, + phy_gmii_txd=phy_gmii_txd, + phy_gmii_tx_en=phy_gmii_tx_en, + phy_gmii_tx_er=phy_gmii_tx_er, + phy_reset_n=phy_reset_n, + phy_int_n=phy_int_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + qsfp1_tx_clk_1.next = not qsfp1_tx_clk_1 + qsfp1_rx_clk_1.next = not qsfp1_rx_clk_1 + qsfp1_tx_clk_2.next = not qsfp1_tx_clk_2 + qsfp1_rx_clk_2.next = not qsfp1_rx_clk_2 + qsfp1_tx_clk_3.next = not qsfp1_tx_clk_3 + qsfp1_rx_clk_3.next = not qsfp1_rx_clk_3 + qsfp1_tx_clk_4.next = not qsfp1_tx_clk_4 + qsfp1_rx_clk_4.next = not qsfp1_rx_clk_4 + qsfp2_tx_clk_1.next = not qsfp2_tx_clk_1 + qsfp2_rx_clk_1.next = not qsfp2_rx_clk_1 + qsfp2_tx_clk_2.next = not qsfp2_tx_clk_2 + qsfp2_rx_clk_2.next = not qsfp2_rx_clk_2 + qsfp2_tx_clk_3.next = not qsfp2_tx_clk_3 + qsfp2_rx_clk_3.next = not qsfp2_rx_clk_3 + qsfp2_tx_clk_4.next = not qsfp2_tx_clk_4 + qsfp2_rx_clk_4.next = not qsfp2_rx_clk_4 + phy_gmii_clk.next = not phy_gmii_clk + + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @always(clk.posedge) + def clk_enable_gen(): + if clk_enable_div.next > 0: + phy_gmii_clk_en.next = 0 + clk_enable_div.next = clk_enable_div - 1 + else: + phy_gmii_clk_en.next = 1 + clk_enable_div.next = clk_enable_rate - 1 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + qsfp1_tx_rst_1.next = 1 + qsfp1_rx_rst_1.next = 1 + qsfp1_tx_rst_2.next = 1 + qsfp1_rx_rst_2.next = 1 + qsfp1_tx_rst_3.next = 1 + qsfp1_rx_rst_3.next = 1 + qsfp1_tx_rst_4.next = 1 + qsfp1_rx_rst_4.next = 1 + qsfp2_tx_rst_1.next = 1 + qsfp2_rx_rst_1.next = 1 + qsfp2_tx_rst_2.next = 1 + qsfp2_rx_rst_2.next = 1 + qsfp2_tx_rst_3.next = 1 + qsfp2_rx_rst_3.next = 1 + qsfp2_tx_rst_4.next = 1 + qsfp2_rx_rst_4.next = 1 + phy_gmii_rst.next = 1 + yield clk.posedge + rst.next = 0 + qsfp1_tx_rst_1.next = 0 + qsfp1_rx_rst_1.next = 0 + qsfp1_tx_rst_2.next = 0 + qsfp1_rx_rst_2.next = 0 + qsfp1_tx_rst_3.next = 0 + qsfp1_rx_rst_3.next = 0 + qsfp1_tx_rst_4.next = 0 + qsfp1_rx_rst_4.next = 0 + qsfp2_tx_rst_1.next = 0 + qsfp2_rx_rst_1.next = 0 + qsfp2_tx_rst_2.next = 0 + qsfp2_rx_rst_2.next = 0 + qsfp2_tx_rst_3.next = 0 + qsfp2_rx_rst_3.next = 0 + qsfp2_tx_rst_4.next = 0 + qsfp2_rx_rst_4.next = 0 + phy_gmii_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + qsfp1_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while qsfp1_1_sink.empty(): + yield clk.posedge + + rx_frame = qsfp1_1_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + qsfp1_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while qsfp1_1_sink.empty(): + yield clk.posedge + + rx_frame = qsfp1_1_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert qsfp1_1_source.empty() + assert qsfp1_1_sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test gigabit tap") + current_test.next = 2 + + sw.next = 0x8 # enable tap on RX + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # loop packet back through on XGMII interface + while qsfp1_1_sink.empty(): + yield clk.posedge + + qsfp1_1_source.send(qsfp1_1_sink.recv()) + + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source.empty() + assert gmii_sink.empty() + assert qsfp1_1_source.empty() + assert qsfp1_1_sink.empty() + + yield delay(100) + + sw.next = 0xc # enable tap on TX + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # loop packet back through on XGMII interface + while qsfp1_1_sink.empty(): + yield clk.posedge + + qsfp1_1_source.send(qsfp1_1_sink.recv()) + + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source.empty() + assert gmii_sink.empty() + assert qsfp1_1_source.empty() + assert qsfp1_1_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() diff --git a/example/VCU118/fpga_10g/tb/test_fpga_core.v b/example/VCU118/fpga_10g/tb/test_fpga_core.v new file mode 100644 index 000000000..24db5dc0c --- /dev/null +++ b/example/VCU118/fpga_10g/tb/test_fpga_core.v @@ -0,0 +1,324 @@ +/* + +Copyright (c) 2016-2018 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [3:0] sw = 0; +reg qsfp1_tx_clk_1 = 0; +reg qsfp1_tx_rst_1 = 0; +reg qsfp1_rx_clk_1 = 0; +reg qsfp1_rx_rst_1 = 0; +reg [63:0] qsfp1_rxd_1 = 0; +reg [7:0] qsfp1_rxc_1 = 0; +reg qsfp1_tx_clk_2 = 0; +reg qsfp1_tx_rst_2 = 0; +reg qsfp1_rx_clk_2 = 0; +reg qsfp1_rx_rst_2 = 0; +reg [63:0] qsfp1_rxd_2 = 0; +reg [7:0] qsfp1_rxc_2 = 0; +reg qsfp1_tx_clk_3 = 0; +reg qsfp1_tx_rst_3 = 0; +reg qsfp1_rx_clk_3 = 0; +reg qsfp1_rx_rst_3 = 0; +reg [63:0] qsfp1_rxd_3 = 0; +reg [7:0] qsfp1_rxc_3 = 0; +reg qsfp1_tx_clk_4 = 0; +reg qsfp1_tx_rst_4 = 0; +reg qsfp1_rx_clk_4 = 0; +reg qsfp1_rx_rst_4 = 0; +reg [63:0] qsfp1_rxd_4 = 0; +reg [7:0] qsfp1_rxc_4 = 0; +reg qsfp2_tx_clk_1 = 0; +reg qsfp2_tx_rst_1 = 0; +reg qsfp2_rx_clk_1 = 0; +reg qsfp2_rx_rst_1 = 0; +reg [63:0] qsfp2_rxd_1 = 0; +reg [7:0] qsfp2_rxc_1 = 0; +reg qsfp2_tx_clk_2 = 0; +reg qsfp2_tx_rst_2 = 0; +reg qsfp2_rx_clk_2 = 0; +reg qsfp2_rx_rst_2 = 0; +reg [63:0] qsfp2_rxd_2 = 0; +reg [7:0] qsfp2_rxc_2 = 0; +reg qsfp2_tx_clk_3 = 0; +reg qsfp2_tx_rst_3 = 0; +reg qsfp2_rx_clk_3 = 0; +reg qsfp2_rx_rst_3 = 0; +reg [63:0] qsfp2_rxd_3 = 0; +reg [7:0] qsfp2_rxc_3 = 0; +reg qsfp2_tx_clk_4 = 0; +reg qsfp2_tx_rst_4 = 0; +reg qsfp2_rx_clk_4 = 0; +reg qsfp2_rx_rst_4 = 0; +reg [63:0] qsfp2_rxd_4 = 0; +reg [7:0] qsfp2_rxc_4 = 0; +reg phy_gmii_clk = 0; +reg phy_gmii_rst = 0; +reg phy_gmii_clk_en = 0; +reg [7:0] phy_gmii_rxd = 0; +reg phy_gmii_rx_dv = 0; +reg phy_gmii_rx_er = 0; +reg phy_int_n = 1; +reg uart_rxd = 0; +reg uart_cts = 0; + +// Outputs +wire [7:0] led; +wire [63:0] qsfp1_txd_1; +wire [7:0] qsfp1_txc_1; +wire [63:0] qsfp1_txd_2; +wire [7:0] qsfp1_txc_2; +wire [63:0] qsfp1_txd_3; +wire [7:0] qsfp1_txc_3; +wire [63:0] qsfp1_txd_4; +wire [7:0] qsfp1_txc_4; +wire [63:0] qsfp2_txd_1; +wire [7:0] qsfp2_txc_1; +wire [63:0] qsfp2_txd_2; +wire [7:0] qsfp2_txc_2; +wire [63:0] qsfp2_txd_3; +wire [7:0] qsfp2_txc_3; +wire [63:0] qsfp2_txd_4; +wire [7:0] qsfp2_txc_4; +wire phy_tx_clk; +wire [7:0] phy_gmii_txd; +wire phy_gmii_tx_en; +wire phy_gmii_tx_er; +wire phy_reset_n; +wire uart_txd; +wire uart_rts; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + qsfp1_tx_clk_1, + qsfp1_tx_rst_1, + qsfp1_rx_clk_1, + qsfp1_rx_rst_1, + qsfp1_rxd_1, + qsfp1_rxc_1, + qsfp1_tx_clk_2, + qsfp1_tx_rst_2, + qsfp1_rx_clk_2, + qsfp1_rx_rst_2, + qsfp1_rxd_2, + qsfp1_rxc_2, + qsfp1_tx_clk_3, + qsfp1_tx_rst_3, + qsfp1_rx_clk_3, + qsfp1_rx_rst_3, + qsfp1_rxd_3, + qsfp1_rxc_3, + qsfp1_tx_clk_4, + qsfp1_tx_rst_4, + qsfp1_rx_clk_4, + qsfp1_rx_rst_4, + qsfp1_rxd_4, + qsfp1_rxc_4, + qsfp2_tx_clk_1, + qsfp2_tx_rst_1, + qsfp2_rx_clk_1, + qsfp2_rx_rst_1, + qsfp2_rxd_1, + qsfp2_rxc_1, + qsfp2_tx_clk_2, + qsfp2_tx_rst_2, + qsfp2_rx_clk_2, + qsfp2_rx_rst_2, + qsfp2_rxd_2, + qsfp2_rxc_2, + qsfp2_tx_clk_3, + qsfp2_tx_rst_3, + qsfp2_rx_clk_3, + qsfp2_rx_rst_3, + qsfp2_rxd_3, + qsfp2_rxc_3, + qsfp2_tx_clk_4, + qsfp2_tx_rst_4, + qsfp2_rx_clk_4, + qsfp2_rx_rst_4, + qsfp2_rxd_4, + qsfp2_rxc_4, + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_clk_en, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_int_n, + uart_rxd, + uart_cts + ); + $to_myhdl( + led, + qsfp1_txd_1, + qsfp1_txc_1, + qsfp1_txd_2, + qsfp1_txc_2, + qsfp1_txd_3, + qsfp1_txc_3, + qsfp1_txd_4, + qsfp1_txc_4, + qsfp2_txd_1, + qsfp2_txc_1, + qsfp2_txd_2, + qsfp2_txc_2, + qsfp2_txd_3, + qsfp2_txc_3, + qsfp2_txd_4, + qsfp2_txc_4, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + uart_txd, + uart_rts + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .qsfp1_tx_clk_1(qsfp1_tx_clk_1), + .qsfp1_tx_rst_1(qsfp1_tx_rst_1), + .qsfp1_txd_1(qsfp1_txd_1), + .qsfp1_txc_1(qsfp1_txc_1), + .qsfp1_rx_clk_1(qsfp1_rx_clk_1), + .qsfp1_rx_rst_1(qsfp1_rx_rst_1), + .qsfp1_rxd_1(qsfp1_rxd_1), + .qsfp1_rxc_1(qsfp1_rxc_1), + .qsfp1_tx_clk_2(qsfp1_tx_clk_2), + .qsfp1_tx_rst_2(qsfp1_tx_rst_2), + .qsfp1_txd_2(qsfp1_txd_2), + .qsfp1_txc_2(qsfp1_txc_2), + .qsfp1_rx_clk_2(qsfp1_rx_clk_2), + .qsfp1_rx_rst_2(qsfp1_rx_rst_2), + .qsfp1_rxd_2(qsfp1_rxd_2), + .qsfp1_rxc_2(qsfp1_rxc_2), + .qsfp1_tx_clk_3(qsfp1_tx_clk_3), + .qsfp1_tx_rst_3(qsfp1_tx_rst_3), + .qsfp1_txd_3(qsfp1_txd_3), + .qsfp1_txc_3(qsfp1_txc_3), + .qsfp1_rx_clk_3(qsfp1_rx_clk_3), + .qsfp1_rx_rst_3(qsfp1_rx_rst_3), + .qsfp1_rxd_3(qsfp1_rxd_3), + .qsfp1_rxc_3(qsfp1_rxc_3), + .qsfp1_tx_clk_4(qsfp1_tx_clk_4), + .qsfp1_tx_rst_4(qsfp1_tx_rst_4), + .qsfp1_txd_4(qsfp1_txd_4), + .qsfp1_txc_4(qsfp1_txc_4), + .qsfp1_rx_clk_4(qsfp1_rx_clk_4), + .qsfp1_rx_rst_4(qsfp1_rx_rst_4), + .qsfp1_rxd_4(qsfp1_rxd_4), + .qsfp1_rxc_4(qsfp1_rxc_4), + .qsfp2_tx_clk_1(qsfp2_tx_clk_1), + .qsfp2_tx_rst_1(qsfp2_tx_rst_1), + .qsfp2_txd_1(qsfp2_txd_1), + .qsfp2_txc_1(qsfp2_txc_1), + .qsfp2_rx_clk_1(qsfp2_rx_clk_1), + .qsfp2_rx_rst_1(qsfp2_rx_rst_1), + .qsfp2_rxd_1(qsfp2_rxd_1), + .qsfp2_rxc_1(qsfp2_rxc_1), + .qsfp2_tx_clk_2(qsfp2_tx_clk_2), + .qsfp2_tx_rst_2(qsfp2_tx_rst_2), + .qsfp2_txd_2(qsfp2_txd_2), + .qsfp2_txc_2(qsfp2_txc_2), + .qsfp2_rx_clk_2(qsfp2_rx_clk_2), + .qsfp2_rx_rst_2(qsfp2_rx_rst_2), + .qsfp2_rxd_2(qsfp2_rxd_2), + .qsfp2_rxc_2(qsfp2_rxc_2), + .qsfp2_tx_clk_3(qsfp2_tx_clk_3), + .qsfp2_tx_rst_3(qsfp2_tx_rst_3), + .qsfp2_txd_3(qsfp2_txd_3), + .qsfp2_txc_3(qsfp2_txc_3), + .qsfp2_rx_clk_3(qsfp2_rx_clk_3), + .qsfp2_rx_rst_3(qsfp2_rx_rst_3), + .qsfp2_rxd_3(qsfp2_rxd_3), + .qsfp2_rxc_3(qsfp2_rxc_3), + .qsfp2_tx_clk_4(qsfp2_tx_clk_4), + .qsfp2_tx_rst_4(qsfp2_tx_rst_4), + .qsfp2_txd_4(qsfp2_txd_4), + .qsfp2_txc_4(qsfp2_txc_4), + .qsfp2_rx_clk_4(qsfp2_rx_clk_4), + .qsfp2_rx_rst_4(qsfp2_rx_rst_4), + .qsfp2_rxd_4(qsfp2_rxd_4), + .qsfp2_rxc_4(qsfp2_rxc_4), + .phy_gmii_clk(phy_gmii_clk), + .phy_gmii_rst(phy_gmii_rst), + .phy_gmii_clk_en(phy_gmii_clk_en), + .phy_gmii_rxd(phy_gmii_rxd), + .phy_gmii_rx_dv(phy_gmii_rx_dv), + .phy_gmii_rx_er(phy_gmii_rx_er), + .phy_gmii_txd(phy_gmii_txd), + .phy_gmii_tx_en(phy_gmii_tx_en), + .phy_gmii_tx_er(phy_gmii_tx_er), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts) +); + +endmodule diff --git a/example/VCU118/fpga_10g/tb/udp_ep.py b/example/VCU118/fpga_10g/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/VCU118/fpga_10g/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_10g/tb/xgmii_ep.py b/example/VCU118/fpga_10g/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/example/VCU118/fpga_10g/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file From 298ae4defa60184468cea15090b0197ba7e2de75 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 13 Jun 2018 22:16:02 -0700 Subject: [PATCH 387/617] Update MAC module instantiation --- example/ATLYS/fpga/rtl/fpga_core.v | 4 ++-- example/DE5-Net/fpga/rtl/fpga_core.v | 12 +++++++++--- example/HXT100G/fpga/rtl/fpga_core.v | 12 +++++++++--- example/ML605/fpga_gmii/rtl/fpga_core.v | 4 ++-- example/ML605/fpga_rgmii/rtl/fpga_core.v | 4 ++-- example/ML605/fpga_sgmii/rtl/fpga_core.v | 4 ++-- example/NexysVideo/fpga/rtl/fpga_core.v | 6 +++--- example/VCU108/fpga_10g/rtl/fpga_core.v | 12 +++++++++--- example/VCU108/fpga_1g/rtl/fpga_core.v | 4 ++-- example/VCU118/fpga_1g/rtl/fpga_core.v | 4 ++-- 10 files changed, 42 insertions(+), 24 deletions(-) diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index 5ad408f91..b55dae1c5 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -350,8 +350,8 @@ eth_mac_inst ( .tx_fifo_overflow(), .tx_fifo_bad_frame(), .tx_fifo_good_frame(), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), .rx_fifo_overflow(), .rx_fifo_bad_frame(), .rx_fifo_good_frame(), diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index 88b6c3764..c97f87dd9 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -364,9 +364,15 @@ eth_mac_10g_fifo_inst ( .xgmii_rxc(sfp_a_rxc), .xgmii_txd(sfp_a_txd), .xgmii_txc(sfp_a_txc), - - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), .ifg_delay(8'd12) ); diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v index f9f864a8e..56fee2161 100644 --- a/example/HXT100G/fpga/rtl/fpga_core.v +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -508,9 +508,15 @@ eth_mac_10g_fifo_inst ( .xgmii_rxc(eth_l0_rxc), .xgmii_txd(eth_l0_txd), .xgmii_txc(eth_l0_txc), - - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), .ifg_delay(8'd12) ); diff --git a/example/ML605/fpga_gmii/rtl/fpga_core.v b/example/ML605/fpga_gmii/rtl/fpga_core.v index 8555af5c5..401a36595 100644 --- a/example/ML605/fpga_gmii/rtl/fpga_core.v +++ b/example/ML605/fpga_gmii/rtl/fpga_core.v @@ -363,8 +363,8 @@ eth_mac_inst ( .tx_fifo_overflow(), .tx_fifo_bad_frame(), .tx_fifo_good_frame(), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), .rx_fifo_overflow(), .rx_fifo_bad_frame(), .rx_fifo_good_frame(), diff --git a/example/ML605/fpga_rgmii/rtl/fpga_core.v b/example/ML605/fpga_rgmii/rtl/fpga_core.v index f48d841fc..107b83052 100644 --- a/example/ML605/fpga_rgmii/rtl/fpga_core.v +++ b/example/ML605/fpga_rgmii/rtl/fpga_core.v @@ -360,8 +360,8 @@ eth_mac_inst ( .tx_fifo_overflow(), .tx_fifo_bad_frame(), .tx_fifo_good_frame(), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), .rx_fifo_overflow(), .rx_fifo_bad_frame(), .rx_fifo_good_frame(), diff --git a/example/ML605/fpga_sgmii/rtl/fpga_core.v b/example/ML605/fpga_sgmii/rtl/fpga_core.v index e686c18d0..ef00064ca 100644 --- a/example/ML605/fpga_sgmii/rtl/fpga_core.v +++ b/example/ML605/fpga_sgmii/rtl/fpga_core.v @@ -361,8 +361,8 @@ eth_mac_inst ( .tx_fifo_overflow(), .tx_fifo_bad_frame(), .tx_fifo_good_frame(), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), .rx_fifo_overflow(), .rx_fifo_bad_frame(), .rx_fifo_good_frame(), diff --git a/example/NexysVideo/fpga/rtl/fpga_core.v b/example/NexysVideo/fpga/rtl/fpga_core.v index f28d6fe3a..06a6bdb5a 100644 --- a/example/NexysVideo/fpga/rtl/fpga_core.v +++ b/example/NexysVideo/fpga/rtl/fpga_core.v @@ -345,12 +345,12 @@ eth_mac_inst ( .rgmii_tx_clk(phy_tx_clk), .rgmii_txd(phy_txd), .rgmii_tx_ctl(phy_tx_ctl), - + .tx_fifo_overflow(), .tx_fifo_bad_frame(), .tx_fifo_good_frame(), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), .rx_fifo_overflow(), .rx_fifo_bad_frame(), .rx_fifo_good_frame(), diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index 340ad3531..daf9fe9d8 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -394,9 +394,15 @@ eth_mac_10g_fifo_inst ( .xgmii_rxc(qsfp_rxc_1), .xgmii_txd(qsfp_txd_1), .xgmii_txc(qsfp_txc_1), - + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), .ifg_delay(8'd12) ); @@ -469,8 +475,8 @@ eth_mac_1g_inst ( .tx_fifo_overflow(), .tx_fifo_bad_frame(), .tx_fifo_good_frame(), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), .rx_fifo_overflow(), .rx_fifo_bad_frame(), .rx_fifo_good_frame(), diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v index e8ad51b27..f43f65acf 100644 --- a/example/VCU108/fpga_1g/rtl/fpga_core.v +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -352,8 +352,8 @@ eth_mac_inst ( .tx_fifo_overflow(), .tx_fifo_bad_frame(), .tx_fifo_good_frame(), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), .rx_fifo_overflow(), .rx_fifo_bad_frame(), .rx_fifo_good_frame(), diff --git a/example/VCU118/fpga_1g/rtl/fpga_core.v b/example/VCU118/fpga_1g/rtl/fpga_core.v index e8ad51b27..f43f65acf 100644 --- a/example/VCU118/fpga_1g/rtl/fpga_core.v +++ b/example/VCU118/fpga_1g/rtl/fpga_core.v @@ -352,8 +352,8 @@ eth_mac_inst ( .tx_fifo_overflow(), .tx_fifo_bad_frame(), .tx_fifo_good_frame(), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), .rx_fifo_overflow(), .rx_fifo_bad_frame(), .rx_fifo_good_frame(), From c5837daa2f04842b4dd4a9b5b7ee8bc45ce2ed7a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 13 Jun 2018 22:26:10 -0700 Subject: [PATCH 388/617] Update testbenches to use instances() --- tb/axis_ep.py | 4 ++-- tb/ll_ep.py | 4 ++-- tb/test_arbiter.py | 2 +- tb/test_arbiter_rr.py | 2 +- tb/test_axis_adapter_64_8.py | 2 +- tb/test_axis_adapter_8_64.py | 2 +- tb/test_axis_arb_mux_4.py | 2 +- tb/test_axis_arb_mux_4_64.py | 2 +- tb/test_axis_async_fifo.py | 2 +- tb/test_axis_async_fifo_64.py | 2 +- tb/test_axis_async_frame_fifo.py | 2 +- tb/test_axis_async_frame_fifo_64.py | 2 +- tb/test_axis_cobs_decode.py | 2 +- tb/test_axis_cobs_encode.py | 2 +- tb/test_axis_cobs_encode_zero_frame.py | 2 +- tb/test_axis_crosspoint_4x4.py | 2 +- tb/test_axis_crosspoint_4x4_64.py | 2 +- tb/test_axis_demux_4.py | 2 +- tb/test_axis_demux_4_64.py | 2 +- tb/test_axis_fifo.py | 2 +- tb/test_axis_fifo_64.py | 2 +- tb/test_axis_frame_fifo.py | 2 +- tb/test_axis_frame_fifo_64.py | 2 +- tb/test_axis_frame_join_4.py | 2 +- tb/test_axis_frame_length_adjust_64.py | 2 +- tb/test_axis_frame_length_adjust_8.py | 2 +- tb/test_axis_frame_length_adjust_fifo.py | 2 +- tb/test_axis_frame_length_adjust_fifo_64.py | 2 +- tb/test_axis_ll_bridge.py | 2 +- tb/test_axis_mux_4.py | 2 +- tb/test_axis_mux_4_64.py | 2 +- tb/test_axis_rate_limit.py | 2 +- tb/test_axis_rate_limit_64.py | 2 +- tb/test_axis_register.py | 2 +- tb/test_axis_register_64.py | 2 +- tb/test_axis_srl_fifo.py | 2 +- tb/test_axis_srl_fifo_64.py | 2 +- tb/test_axis_srl_register.py | 2 +- tb/test_axis_srl_register_64.py | 2 +- tb/test_axis_stat_counter.py | 2 +- tb/test_axis_switch_4x4.py | 2 +- tb/test_axis_switch_4x4_64.py | 2 +- tb/test_axis_tap.py | 2 +- tb/test_axis_tap_64.py | 2 +- tb/test_ll_axis_bridge.py | 2 +- tb/test_priority_encoder.py | 2 +- 46 files changed, 48 insertions(+), 48 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 75356b54d..de4528efb 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -366,7 +366,7 @@ class AXIStreamSource(object): tvalid_int.next = True tlast.next = len(data) == 0 - return logic, pause_logic + return instances() class AXIStreamSink(object): @@ -508,5 +508,5 @@ class AXIStreamSink(object): user = [] first = True - return logic, pause_logic + return instances() diff --git a/tb/ll_ep.py b/tb/ll_ep.py index 4dc45d4f6..c3e7e9aae 100644 --- a/tb/ll_ep.py +++ b/tb/ll_ep.py @@ -93,7 +93,7 @@ class LocalLinkSource(object): sof_out_n.next = False eof_out_n.next = len(frame) != 0 - return logic, pause_logic + return instances() class LocalLinkSink(object): @@ -158,5 +158,5 @@ class LocalLinkSink(object): print("[%s] Got frame %s" % (name, repr(frame))) frame = [] - return logic, pause_logic + return instances() diff --git a/tb/test_arbiter.py b/tb/test_arbiter.py index f75aa6940..6c2db5ac8 100755 --- a/tb/test_arbiter.py +++ b/tb/test_arbiter.py @@ -163,7 +163,7 @@ def bench(): raise StopSimulation - return dut, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_arbiter_rr.py b/tb/test_arbiter_rr.py index 4db2219e5..983ef5566 100755 --- a/tb/test_arbiter_rr.py +++ b/tb/test_arbiter_rr.py @@ -223,7 +223,7 @@ def bench(): raise StopSimulation - return dut, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index 15aea7c0f..8319dd1c6 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -311,7 +311,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index d734bff95..679e759e6 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -311,7 +311,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index 3604e682a..9e56080c0 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -564,7 +564,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_arb_mux_4_64.py b/tb/test_axis_arb_mux_4_64.py index 6117fbc9c..5e9b85f01 100755 --- a/tb/test_axis_arb_mux_4_64.py +++ b/tb/test_axis_arb_mux_4_64.py @@ -564,7 +564,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index 91e64d52d..f61e2137b 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -488,7 +488,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, input_clkgen, output_clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index 019a0b0cf..14be052a3 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -488,7 +488,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, input_clkgen, output_clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index d08f026f1..dbd1ec2e9 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -659,7 +659,7 @@ def bench(): raise StopSimulation - return dut, monitor_1, monitor_2, source_logic, sink_logic, input_clkgen, output_clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index ec6de8397..886032143 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -659,7 +659,7 @@ def bench(): raise StopSimulation - return dut, monitor_1, monitor_2, source_logic, sink_logic, input_clkgen, output_clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py index 381b91355..ceb92c787 100755 --- a/tb/test_axis_cobs_decode.py +++ b/tb/test_axis_cobs_decode.py @@ -446,7 +446,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py index ccba256c4..db2419eb4 100755 --- a/tb/test_axis_cobs_encode.py +++ b/tb/test_axis_cobs_encode.py @@ -345,7 +345,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_cobs_encode_zero_frame.py b/tb/test_axis_cobs_encode_zero_frame.py index 924bb7570..5f1642b06 100755 --- a/tb/test_axis_cobs_encode_zero_frame.py +++ b/tb/test_axis_cobs_encode_zero_frame.py @@ -346,7 +346,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_crosspoint_4x4.py b/tb/test_axis_crosspoint_4x4.py index 53d69421c..bb707b7d7 100755 --- a/tb/test_axis_crosspoint_4x4.py +++ b/tb/test_axis_crosspoint_4x4.py @@ -474,7 +474,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_crosspoint_4x4_64.py b/tb/test_axis_crosspoint_4x4_64.py index a07287fa0..ba0b5068a 100755 --- a/tb/test_axis_crosspoint_4x4_64.py +++ b/tb/test_axis_crosspoint_4x4_64.py @@ -474,7 +474,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py index 47fd50a9e..3eb5ee55b 100755 --- a/tb/test_axis_demux_4.py +++ b/tb/test_axis_demux_4.py @@ -519,7 +519,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_demux_4_64.py b/tb/test_axis_demux_4_64.py index 431cf5b34..7b814a3b6 100755 --- a/tb/test_axis_demux_4_64.py +++ b/tb/test_axis_demux_4_64.py @@ -519,7 +519,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index c7d83b45f..9c20622af 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -477,7 +477,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index 2265bad69..f93e77fb4 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -477,7 +477,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index ab1a92ffb..a1c429bb1 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -581,7 +581,7 @@ def bench(): raise StopSimulation - return dut, monitor, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index 43fd39a6d..b7858b3d1 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -581,7 +581,7 @@ def bench(): raise StopSimulation - return dut, monitor, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index 47b59de72..ee0d03f16 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -465,7 +465,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_length_adjust_64.py b/tb/test_axis_frame_length_adjust_64.py index 60eb56f9a..cdef5a35b 100755 --- a/tb/test_axis_frame_length_adjust_64.py +++ b/tb/test_axis_frame_length_adjust_64.py @@ -372,7 +372,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, status_sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_length_adjust_8.py b/tb/test_axis_frame_length_adjust_8.py index 9a2238129..4eccbb97d 100755 --- a/tb/test_axis_frame_length_adjust_8.py +++ b/tb/test_axis_frame_length_adjust_8.py @@ -372,7 +372,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, status_sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_length_adjust_fifo.py b/tb/test_axis_frame_length_adjust_fifo.py index 80e754345..8cb8d4a28 100755 --- a/tb/test_axis_frame_length_adjust_fifo.py +++ b/tb/test_axis_frame_length_adjust_fifo.py @@ -364,7 +364,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, hdr_sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_frame_length_adjust_fifo_64.py b/tb/test_axis_frame_length_adjust_fifo_64.py index 263679bb0..522c932ac 100755 --- a/tb/test_axis_frame_length_adjust_fifo_64.py +++ b/tb/test_axis_frame_length_adjust_fifo_64.py @@ -364,7 +364,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, hdr_sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_ll_bridge.py b/tb/test_axis_ll_bridge.py index f03818000..d5f556bae 100755 --- a/tb/test_axis_ll_bridge.py +++ b/tb/test_axis_ll_bridge.py @@ -193,7 +193,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py index 91b266b6f..8d15c2e86 100755 --- a/tb/test_axis_mux_4.py +++ b/tb/test_axis_mux_4.py @@ -519,7 +519,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_mux_4_64.py b/tb/test_axis_mux_4_64.py index da89e5fa9..e3022f7a8 100755 --- a/tb/test_axis_mux_4_64.py +++ b/tb/test_axis_mux_4_64.py @@ -519,7 +519,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index 1af1f7349..a566926ea 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -547,7 +547,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index bb8121328..6c2205c4d 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -547,7 +547,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py index 2b1b000b9..c46eacdba 100755 --- a/tb/test_axis_register.py +++ b/tb/test_axis_register.py @@ -415,7 +415,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py index bde5194b3..5b03c0cf5 100755 --- a/tb/test_axis_register_64.py +++ b/tb/test_axis_register_64.py @@ -415,7 +415,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py index c7a289256..7ebd9bfa0 100755 --- a/tb/test_axis_srl_fifo.py +++ b/tb/test_axis_srl_fifo.py @@ -479,7 +479,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py index 2b4e91c4a..3b4b58b91 100755 --- a/tb/test_axis_srl_fifo_64.py +++ b/tb/test_axis_srl_fifo_64.py @@ -479,7 +479,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_srl_register.py b/tb/test_axis_srl_register.py index 18ad7be8d..81c300655 100755 --- a/tb/test_axis_srl_register.py +++ b/tb/test_axis_srl_register.py @@ -415,7 +415,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_srl_register_64.py b/tb/test_axis_srl_register_64.py index 7bf20da63..918f4bc8b 100755 --- a/tb/test_axis_srl_register_64.py +++ b/tb/test_axis_srl_register_64.py @@ -415,7 +415,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index 34b5cb9a3..528287c0f 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -765,7 +765,7 @@ def bench(): raise StopSimulation - return dut, source_logic, monitor_sink_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py index bc30f5ab3..a32d1f9b0 100755 --- a/tb/test_axis_switch_4x4.py +++ b/tb/test_axis_switch_4x4.py @@ -603,7 +603,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_switch_4x4_64.py b/tb/test_axis_switch_4x4_64.py index dda6d852e..0c604f694 100755 --- a/tb/test_axis_switch_4x4_64.py +++ b/tb/test_axis_switch_4x4_64.py @@ -603,7 +603,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_tap.py b/tb/test_axis_tap.py index 29a7423b4..4310dae85 100755 --- a/tb/test_axis_tap.py +++ b/tb/test_axis_tap.py @@ -444,7 +444,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_axis_tap_64.py b/tb/test_axis_tap_64.py index 1e06ca6fe..343075498 100755 --- a/tb/test_axis_tap_64.py +++ b/tb/test_axis_tap_64.py @@ -444,7 +444,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_ll_axis_bridge.py b/tb/test_ll_axis_bridge.py index 41b0532bf..5c0a1995c 100755 --- a/tb/test_ll_axis_bridge.py +++ b/tb/test_ll_axis_bridge.py @@ -193,7 +193,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_priority_encoder.py b/tb/test_priority_encoder.py index 9ba980646..f6747e329 100755 --- a/tb/test_priority_encoder.py +++ b/tb/test_priority_encoder.py @@ -121,7 +121,7 @@ def bench(): raise StopSimulation - return dut, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) From e4672915e6214fefb3394951d8e88e185c4b5d8d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 13 Jun 2018 22:43:11 -0700 Subject: [PATCH 389/617] Update testbenches to use instances() --- example/ATLYS/fpga/tb/test_fpga_core.py | 2 +- example/DE5-Net/fpga/tb/test_fpga_core.py | 2 +- example/HXT100G/fpga/tb/test_fpga_core.py | 9 +-------- example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py | 9 +-------- example/ML605/fpga_gmii/tb/test_fpga_core.py | 2 +- example/ML605/fpga_rgmii/tb/test_fpga_core.py | 2 +- example/ML605/fpga_sgmii/tb/test_fpga_core.py | 2 +- example/NexysVideo/fpga/tb/test_fpga_core.py | 2 +- example/VCU108/fpga_10g/tb/test_fpga_core.py | 2 +- example/VCU108/fpga_1g/tb/test_fpga_core.py | 2 +- example/VCU118/fpga_1g/tb/test_fpga_core.py | 2 +- tb/arp_ep.py | 4 ++-- tb/eth_ep.py | 4 ++-- tb/gmii_ep.py | 4 ++-- tb/ip_ep.py | 4 ++-- tb/rgmii_ep.py | 4 ++-- tb/test_arp.py | 2 +- tb/test_arp_64.py | 2 +- tb/test_arp_cache.py | 2 +- tb/test_arp_eth_rx.py | 2 +- tb/test_arp_eth_rx_64.py | 2 +- tb/test_arp_eth_tx.py | 2 +- tb/test_arp_eth_tx_64.py | 2 +- tb/test_axis_eth_fcs.py | 2 +- tb/test_axis_eth_fcs_64.py | 2 +- tb/test_axis_eth_fcs_check.py | 2 +- tb/test_axis_eth_fcs_check_64.py | 2 +- tb/test_axis_eth_fcs_insert.py | 2 +- tb/test_axis_eth_fcs_insert_64.py | 2 +- tb/test_axis_eth_fcs_insert_64_pad.py | 2 +- tb/test_axis_eth_fcs_insert_pad.py | 2 +- tb/test_axis_gmii_rx.py | 2 +- tb/test_axis_gmii_tx.py | 2 +- tb/test_eth_arb_mux_4.py | 2 +- tb/test_eth_arb_mux_64_4.py | 2 +- tb/test_eth_axis_rx.py | 2 +- tb/test_eth_axis_rx_64.py | 2 +- tb/test_eth_axis_tx.py | 2 +- tb/test_eth_axis_tx_64.py | 2 +- tb/test_eth_demux_4.py | 2 +- tb/test_eth_demux_64_4.py | 2 +- tb/test_eth_mac_10g.py | 2 +- tb/test_eth_mac_10g_fifo.py | 2 +- tb/test_eth_mac_10g_rx.py | 2 +- tb/test_eth_mac_10g_tx.py | 2 +- tb/test_eth_mac_1g.py | 2 +- tb/test_eth_mac_1g_fifo.py | 2 +- tb/test_eth_mac_1g_gmii.py | 2 +- tb/test_eth_mac_1g_gmii_fifo.py | 2 +- tb/test_eth_mac_1g_rgmii.py | 2 +- tb/test_eth_mac_1g_rgmii_fifo.py | 2 +- tb/test_eth_mac_1g_rx.py | 2 +- tb/test_eth_mac_1g_tx.py | 2 +- tb/test_eth_mux_4.py | 2 +- tb/test_eth_mux_64_4.py | 2 +- tb/test_ip.py | 2 +- tb/test_ip_64.py | 2 +- tb/test_ip_arb_mux_4.py | 2 +- tb/test_ip_arb_mux_64_4.py | 2 +- tb/test_ip_complete.py | 2 +- tb/test_ip_complete_64.py | 2 +- tb/test_ip_demux_4.py | 2 +- tb/test_ip_demux_64_4.py | 2 +- tb/test_ip_eth_rx.py | 2 +- tb/test_ip_eth_rx_64.py | 2 +- tb/test_ip_eth_tx.py | 2 +- tb/test_ip_eth_tx_64.py | 2 +- tb/test_ip_mux_4.py | 2 +- tb/test_ip_mux_64_4.py | 2 +- tb/test_udp.py | 2 +- tb/test_udp_64.py | 2 +- tb/test_udp_arb_mux_4.py | 2 +- tb/test_udp_arb_mux_64_4.py | 2 +- tb/test_udp_checksum_gen.py | 2 +- tb/test_udp_checksum_gen_64.py | 2 +- tb/test_udp_complete.py | 2 +- tb/test_udp_complete_64.py | 2 +- tb/test_udp_demux_4.py | 2 +- tb/test_udp_demux_64_4.py | 2 +- tb/test_udp_ip_rx.py | 2 +- tb/test_udp_ip_rx_64.py | 2 +- tb/test_udp_ip_tx.py | 2 +- tb/test_udp_ip_tx_64.py | 2 +- tb/test_udp_mux_4.py | 2 +- tb/test_udp_mux_64_4.py | 2 +- tb/udp_ep.py | 4 ++-- tb/xgmii_ep.py | 4 ++-- 87 files changed, 94 insertions(+), 108 deletions(-) diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index 7cc6dbb38..9a4eaa413 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -301,7 +301,7 @@ def bench(): raise StopSimulation - return dut, gmii_source_logic, gmii_sink_logic, clkgen, rx_clk_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index c1eb15068..56ded4c0f 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -293,7 +293,7 @@ def bench(): raise StopSimulation - return dut, sfp_a_source_logic, sfp_a_sink_logic, sfp_b_source_logic, sfp_b_sink_logic, sfp_c_source_logic, sfp_c_sink_logic, sfp_d_source_logic, sfp_d_sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index 21e9b971d..024c6957b 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -601,14 +601,7 @@ def bench(): raise StopSimulation - return (dut, clkgen, check, eth_r0_source_logic, eth_r0_sink_logic, eth_r1_source_logic, eth_r1_sink_logic, eth_r2_source_logic, eth_r2_sink_logic, - eth_r3_source_logic, eth_r3_sink_logic, eth_r4_source_logic, eth_r4_sink_logic, eth_r5_source_logic, eth_r5_sink_logic, - eth_r6_source_logic, eth_r6_sink_logic, eth_r7_source_logic, eth_r7_sink_logic, eth_r8_source_logic, eth_r8_sink_logic, - eth_r9_source_logic, eth_r9_sink_logic, eth_r10_source_logic, eth_r10_sink_logic, eth_r11_source_logic, eth_r11_sink_logic, - eth_l0_source_logic, eth_l0_sink_logic, eth_l1_source_logic, eth_l1_sink_logic, eth_l2_source_logic, eth_l2_sink_logic, - eth_l3_source_logic, eth_l3_sink_logic, eth_l4_source_logic, eth_l4_sink_logic, eth_l5_source_logic, eth_l5_sink_logic, - eth_l6_source_logic, eth_l6_sink_logic, eth_l7_source_logic, eth_l7_sink_logic, eth_l8_source_logic, eth_l8_sink_logic, - eth_l9_source_logic, eth_l9_sink_logic, eth_l10_source_logic, eth_l10_sink_logic, eth_l11_source_logic, eth_l11_sink_logic) + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py b/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py index 98b826015..b2a1cd1a8 100755 --- a/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py +++ b/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py @@ -533,14 +533,7 @@ def bench(): raise StopSimulation - return (dut, clkgen, check, eth_r0_source_logic, eth_r0_sink_logic, eth_r1_source_logic, eth_r1_sink_logic, eth_r2_source_logic, eth_r2_sink_logic, - eth_r3_source_logic, eth_r3_sink_logic, eth_r4_source_logic, eth_r4_sink_logic, eth_r5_source_logic, eth_r5_sink_logic, - eth_r6_source_logic, eth_r6_sink_logic, eth_r7_source_logic, eth_r7_sink_logic, eth_r8_source_logic, eth_r8_sink_logic, - eth_r9_source_logic, eth_r9_sink_logic, eth_r10_source_logic, eth_r10_sink_logic, eth_r11_source_logic, eth_r11_sink_logic, - eth_l0_source_logic, eth_l0_sink_logic, eth_l1_source_logic, eth_l1_sink_logic, eth_l2_source_logic, eth_l2_sink_logic, - eth_l3_source_logic, eth_l3_sink_logic, eth_l4_source_logic, eth_l4_sink_logic, eth_l5_source_logic, eth_l5_sink_logic, - eth_l6_source_logic, eth_l6_sink_logic, eth_l7_source_logic, eth_l7_sink_logic, eth_l8_source_logic, eth_l8_sink_logic, - eth_l9_source_logic, eth_l9_sink_logic, eth_l10_source_logic, eth_l10_sink_logic, eth_l11_source_logic, eth_l11_sink_logic) + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/example/ML605/fpga_gmii/tb/test_fpga_core.py b/example/ML605/fpga_gmii/tb/test_fpga_core.py index cfc769658..b4c0cf27b 100755 --- a/example/ML605/fpga_gmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_gmii/tb/test_fpga_core.py @@ -320,7 +320,7 @@ def bench(): raise StopSimulation - return dut, gmii_source_logic, gmii_sink_logic, clkgen, rx_clk_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/example/ML605/fpga_rgmii/tb/test_fpga_core.py b/example/ML605/fpga_rgmii/tb/test_fpga_core.py index 544dc88e6..4847fe10e 100755 --- a/example/ML605/fpga_rgmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_rgmii/tb/test_fpga_core.py @@ -320,7 +320,7 @@ def bench(): raise StopSimulation - return dut, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, rx_clk_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/example/ML605/fpga_sgmii/tb/test_fpga_core.py b/example/ML605/fpga_sgmii/tb/test_fpga_core.py index 16c4495ec..32db62f37 100755 --- a/example/ML605/fpga_sgmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_sgmii/tb/test_fpga_core.py @@ -317,7 +317,7 @@ def bench(): raise StopSimulation - return dut, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.py b/example/NexysVideo/fpga/tb/test_fpga_core.py index b0ab838c9..b42e78d2f 100755 --- a/example/NexysVideo/fpga/tb/test_fpga_core.py +++ b/example/NexysVideo/fpga/tb/test_fpga_core.py @@ -305,7 +305,7 @@ def bench(): raise StopSimulation - return dut, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, rx_clk_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index 061c65f3f..f16c8cb44 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -511,7 +511,7 @@ def bench(): raise StopSimulation - return dut, qsfp_1_source_logic, qsfp_1_sink_logic, qsfp_2_source_logic, qsfp_2_sink_logic, qsfp_3_source_logic, qsfp_3_sink_logic, qsfp_4_source_logic, qsfp_4_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py index 0302962b2..91a778681 100755 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -304,7 +304,7 @@ def bench(): raise StopSimulation - return dut, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/example/VCU118/fpga_1g/tb/test_fpga_core.py b/example/VCU118/fpga_1g/tb/test_fpga_core.py index 0302962b2..91a778681 100755 --- a/example/VCU118/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU118/fpga_1g/tb/test_fpga_core.py @@ -304,7 +304,7 @@ def bench(): raise StopSimulation - return dut, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/arp_ep.py b/tb/arp_ep.py index 9f07516bf..9e1eb576d 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -236,7 +236,7 @@ class ARPFrameSource(): frame_valid_int.next = True - return logic, pause_logic + return instances() class ARPFrameSink(): @@ -316,5 +316,5 @@ class ARPFrameSink(): if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) - return logic, pause_logic + return instances() diff --git a/tb/eth_ep.py b/tb/eth_ep.py index 0949454d7..893989498 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -204,7 +204,7 @@ class EthFrameSource(): eth_hdr_valid_int.next = True - return logic, pause_logic, eth_payload_source + return instances() class EthFrameSink(): @@ -295,5 +295,5 @@ class EthFrameSink(): if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) - return logic, pause_logic, eth_payload_sink + return instances() diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index fb53b2ba1..f7beca920 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -172,7 +172,7 @@ class GMIISource(object): tx_er.next = 0 tx_en.next = 0 - return logic + return instances() class GMIISink(object): @@ -261,5 +261,5 @@ class GMIISink(object): d = [] er = [] - return logic + return instances() diff --git a/tb/ip_ep.py b/tb/ip_ep.py index 1f8c41387..26937a9d5 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -356,7 +356,7 @@ class IPFrameSource(): self.header_queue.append(frame) self.payload_source.send(frame.payload) - return logic, pause_logic, ip_payload_source + return instances() class IPFrameSink(): @@ -476,5 +476,5 @@ class IPFrameSink(): if len(self.header_queue) == 0: assert self.payload_sink.empty() - return logic, pause_logic, ip_payload_sink + return instances() diff --git a/tb/rgmii_ep.py b/tb/rgmii_ep.py index 3a46ba0cf..705b098c0 100644 --- a/tb/rgmii_ep.py +++ b/tb/rgmii_ep.py @@ -63,7 +63,7 @@ class RGMIISource(gmii_ep.GMIISource): gmii_tx_en_reg.next = gmii_tx_en gmii_tx_er_reg.next = gmii_tx_er - return gmii_source, logic + return instances() class RGMIISink(gmii_ep.GMIISink): @@ -102,5 +102,5 @@ class RGMIISink(gmii_ep.GMIISink): dat |= int(rxd.val) << 4 ctl2 = int(rx_ctl.val) - return gmii_sink, logic + return instances() diff --git a/tb/test_arp.py b/tb/test_arp.py index f7d86a53b..465bfe637 100755 --- a/tb/test_arp.py +++ b/tb/test_arp.py @@ -435,7 +435,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp_64.py b/tb/test_arp_64.py index 2f6c763d1..3357ee134 100755 --- a/tb/test_arp_64.py +++ b/tb/test_arp_64.py @@ -441,7 +441,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp_cache.py b/tb/test_arp_cache.py index a956d9b09..af268d44e 100755 --- a/tb/test_arp_cache.py +++ b/tb/test_arp_cache.py @@ -504,7 +504,7 @@ def bench(): raise StopSimulation - return dut, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index 64cc9bf1f..5641166c1 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -537,7 +537,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index a15b2eef4..97bc0ea0d 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -540,7 +540,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py index 27ad7c2fe..e8751f946 100755 --- a/tb/test_arp_eth_tx.py +++ b/tb/test_arp_eth_tx.py @@ -357,7 +357,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py index 47e34e744..c8c9a6926 100755 --- a/tb/test_arp_eth_tx_64.py +++ b/tb/test_arp_eth_tx_64.py @@ -360,7 +360,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_eth_fcs.py b/tb/test_axis_eth_fcs.py index 4952c827f..906a3fb49 100755 --- a/tb/test_axis_eth_fcs.py +++ b/tb/test_axis_eth_fcs.py @@ -145,7 +145,7 @@ def bench(): raise StopSimulation - return dut, source_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_eth_fcs_64.py b/tb/test_axis_eth_fcs_64.py index 8da4ae571..c89e5c9c9 100755 --- a/tb/test_axis_eth_fcs_64.py +++ b/tb/test_axis_eth_fcs_64.py @@ -148,7 +148,7 @@ def bench(): raise StopSimulation - return dut, source_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index 8baec66e3..a45f05576 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -401,7 +401,7 @@ def bench(): raise StopSimulation - return dut, monitor, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_eth_fcs_check_64.py b/tb/test_axis_eth_fcs_check_64.py index c8fd9a377..9a0e684c6 100755 --- a/tb/test_axis_eth_fcs_check_64.py +++ b/tb/test_axis_eth_fcs_check_64.py @@ -407,7 +407,7 @@ def bench(): raise StopSimulation - return dut, monitor, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index 7224cd89f..139c14144 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -368,7 +368,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_eth_fcs_insert_64.py b/tb/test_axis_eth_fcs_insert_64.py index eb0983b06..69abd9d89 100755 --- a/tb/test_axis_eth_fcs_insert_64.py +++ b/tb/test_axis_eth_fcs_insert_64.py @@ -374,7 +374,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_eth_fcs_insert_64_pad.py b/tb/test_axis_eth_fcs_insert_64_pad.py index 4d4ea070f..84ce34065 100755 --- a/tb/test_axis_eth_fcs_insert_64_pad.py +++ b/tb/test_axis_eth_fcs_insert_64_pad.py @@ -375,7 +375,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_eth_fcs_insert_pad.py b/tb/test_axis_eth_fcs_insert_pad.py index e9d877a12..aa2123e6e 100755 --- a/tb/test_axis_eth_fcs_insert_pad.py +++ b/tb/test_axis_eth_fcs_insert_pad.py @@ -369,7 +369,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_gmii_rx.py b/tb/test_axis_gmii_rx.py index 71e743d0c..a94e57df6 100755 --- a/tb/test_axis_gmii_rx.py +++ b/tb/test_axis_gmii_rx.py @@ -419,7 +419,7 @@ def bench(): raise StopSimulation - return dut, monitor, source_logic, sink_logic, clkgen, clk_enable_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_axis_gmii_tx.py b/tb/test_axis_gmii_tx.py index 895095252..dc3c064f7 100755 --- a/tb/test_axis_gmii_tx.py +++ b/tb/test_axis_gmii_tx.py @@ -371,7 +371,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, clk_enable_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_arb_mux_4.py b/tb/test_eth_arb_mux_4.py index 3a1788e3d..f8bf12aa9 100755 --- a/tb/test_eth_arb_mux_4.py +++ b/tb/test_eth_arb_mux_4.py @@ -554,7 +554,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_eth_arb_mux_64_4.py b/tb/test_eth_arb_mux_64_4.py index f91254821..ded2000ae 100755 --- a/tb/test_eth_arb_mux_64_4.py +++ b/tb/test_eth_arb_mux_64_4.py @@ -569,7 +569,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index 1901478cc..a6af9d50e 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -346,7 +346,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index b1fae272b..5eccee574 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -352,7 +352,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py index d19eb90a1..254f7ef1f 100755 --- a/tb/test_eth_axis_tx.py +++ b/tb/test_eth_axis_tx.py @@ -299,7 +299,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py index 70e1ed769..332c626d8 100755 --- a/tb/test_eth_axis_tx_64.py +++ b/tb/test_eth_axis_tx_64.py @@ -305,7 +305,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_demux_4.py b/tb/test_eth_demux_4.py index 905b58993..36915abbd 100755 --- a/tb/test_eth_demux_4.py +++ b/tb/test_eth_demux_4.py @@ -508,7 +508,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_eth_demux_64_4.py b/tb/test_eth_demux_64_4.py index 56ad331af..19f446f1c 100755 --- a/tb/test_eth_demux_64_4.py +++ b/tb/test_eth_demux_64_4.py @@ -523,7 +523,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_eth_mac_10g.py b/tb/test_eth_mac_10g.py index 42f8510a6..bda37312c 100755 --- a/tb/test_eth_mac_10g.py +++ b/tb/test_eth_mac_10g.py @@ -275,7 +275,7 @@ def bench(): raise StopSimulation - return dut, axis_source_logic, axis_sink_logic, xgmii_source_logic, xgmii_sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_10g_fifo.py b/tb/test_eth_mac_10g_fifo.py index 3ff39da69..0194e818d 100755 --- a/tb/test_eth_mac_10g_fifo.py +++ b/tb/test_eth_mac_10g_fifo.py @@ -313,7 +313,7 @@ def bench(): raise StopSimulation - return dut, axis_source_logic, axis_sink_logic, xgmii_source_logic, xgmii_sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_10g_rx.py b/tb/test_eth_mac_10g_rx.py index 15a173cff..290fe5d2e 100755 --- a/tb/test_eth_mac_10g_rx.py +++ b/tb/test_eth_mac_10g_rx.py @@ -399,7 +399,7 @@ def bench(): raise StopSimulation - return dut, monitor, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_10g_tx.py b/tb/test_eth_mac_10g_tx.py index 665a10a79..06c35d61a 100755 --- a/tb/test_eth_mac_10g_tx.py +++ b/tb/test_eth_mac_10g_tx.py @@ -345,7 +345,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index 06cf5fe62..8ec119549 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -327,7 +327,7 @@ def bench(): raise StopSimulation - return dut, monitor, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py index b324bf018..2681fde7d 100755 --- a/tb/test_eth_mac_1g_fifo.py +++ b/tb/test_eth_mac_1g_fifo.py @@ -358,7 +358,7 @@ def bench(): raise StopSimulation - return dut, monitor, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, clk_enable_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_1g_gmii.py b/tb/test_eth_mac_1g_gmii.py index 088e689c1..294cd9ba2 100755 --- a/tb/test_eth_mac_1g_gmii.py +++ b/tb/test_eth_mac_1g_gmii.py @@ -331,7 +331,7 @@ def bench(): raise StopSimulation - return dut, monitor, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, rx_clk_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_1g_gmii_fifo.py b/tb/test_eth_mac_1g_gmii_fifo.py index 903d75396..8dda57731 100755 --- a/tb/test_eth_mac_1g_gmii_fifo.py +++ b/tb/test_eth_mac_1g_gmii_fifo.py @@ -355,7 +355,7 @@ def bench(): raise StopSimulation - return dut, monitor, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, rx_clk_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_1g_rgmii.py b/tb/test_eth_mac_1g_rgmii.py index c7fd94f02..e0060c951 100755 --- a/tb/test_eth_mac_1g_rgmii.py +++ b/tb/test_eth_mac_1g_rgmii.py @@ -333,7 +333,7 @@ def bench(): raise StopSimulation - return dut, monitor, axis_source_logic, axis_sink_logic, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, rx_clk_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_1g_rgmii_fifo.py b/tb/test_eth_mac_1g_rgmii_fifo.py index 01d9ec447..111c22f37 100755 --- a/tb/test_eth_mac_1g_rgmii_fifo.py +++ b/tb/test_eth_mac_1g_rgmii_fifo.py @@ -356,7 +356,7 @@ def bench(): raise StopSimulation - return dut, monitor, axis_source_logic, axis_sink_logic, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, rx_clk_gen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py index abf1c088d..cfd1c1a0a 100755 --- a/tb/test_eth_mac_1g_rx.py +++ b/tb/test_eth_mac_1g_rx.py @@ -366,7 +366,7 @@ def bench(): raise StopSimulation - return dut, monitor, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index 5bda44da1..62c3f111d 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -316,7 +316,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_eth_mux_4.py b/tb/test_eth_mux_4.py index c8adc4b90..d3dd3cfc2 100755 --- a/tb/test_eth_mux_4.py +++ b/tb/test_eth_mux_4.py @@ -515,7 +515,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_eth_mux_64_4.py b/tb/test_eth_mux_64_4.py index 61b9860a9..8d0128518 100755 --- a/tb/test_eth_mux_64_4.py +++ b/tb/test_eth_mux_64_4.py @@ -530,7 +530,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_ip.py b/tb/test_ip.py index 2bc39b5c8..fcfdd26f1 100755 --- a/tb/test_ip.py +++ b/tb/test_ip.py @@ -524,7 +524,7 @@ def bench(): raise StopSimulation - return dut, eth_source_logic, eth_sink_logic, ip_source_logic, ip_sink_logic, clkgen, arp_emu, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_ip_64.py b/tb/test_ip_64.py index 450004847..a1e5299c0 100755 --- a/tb/test_ip_64.py +++ b/tb/test_ip_64.py @@ -536,7 +536,7 @@ def bench(): raise StopSimulation - return dut, eth_source_logic, eth_sink_logic, ip_source_logic, ip_sink_logic, clkgen, arp_emu, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_ip_arb_mux_4.py b/tb/test_ip_arb_mux_4.py index 8418ad7e0..54d03d09f 100755 --- a/tb/test_ip_arb_mux_4.py +++ b/tb/test_ip_arb_mux_4.py @@ -917,7 +917,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_ip_arb_mux_64_4.py b/tb/test_ip_arb_mux_64_4.py index b1ca7e6da..ea0746139 100755 --- a/tb/test_ip_arb_mux_64_4.py +++ b/tb/test_ip_arb_mux_64_4.py @@ -932,7 +932,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_ip_complete.py b/tb/test_ip_complete.py index 12a54e554..1a17adeb6 100755 --- a/tb/test_ip_complete.py +++ b/tb/test_ip_complete.py @@ -572,7 +572,7 @@ def bench(): raise StopSimulation - return dut, eth_source_logic, eth_sink_logic, ip_source_logic, ip_sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_ip_complete_64.py b/tb/test_ip_complete_64.py index e2164bd40..0923d7719 100755 --- a/tb/test_ip_complete_64.py +++ b/tb/test_ip_complete_64.py @@ -584,7 +584,7 @@ def bench(): raise StopSimulation - return dut, eth_source_logic, eth_sink_logic, ip_source_logic, ip_sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_ip_demux_4.py b/tb/test_ip_demux_4.py index 4016c13f7..d3efa6c76 100755 --- a/tb/test_ip_demux_4.py +++ b/tb/test_ip_demux_4.py @@ -843,7 +843,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_ip_demux_64_4.py b/tb/test_ip_demux_64_4.py index 051c833d1..7dbed7897 100755 --- a/tb/test_ip_demux_64_4.py +++ b/tb/test_ip_demux_64_4.py @@ -858,7 +858,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index 71d9169c1..9cdbed496 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -1048,7 +1048,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py index 3561148f8..941af90a7 100755 --- a/tb/test_ip_eth_rx_64.py +++ b/tb/test_ip_eth_rx_64.py @@ -1054,7 +1054,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py index fe5836451..64f5012a5 100755 --- a/tb/test_ip_eth_tx.py +++ b/tb/test_ip_eth_tx.py @@ -849,7 +849,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_ip_eth_tx_64.py b/tb/test_ip_eth_tx_64.py index 3cf9a8030..664a0b481 100755 --- a/tb/test_ip_eth_tx_64.py +++ b/tb/test_ip_eth_tx_64.py @@ -855,7 +855,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_ip_mux_4.py b/tb/test_ip_mux_4.py index bea4aa1cf..d0feab038 100755 --- a/tb/test_ip_mux_4.py +++ b/tb/test_ip_mux_4.py @@ -850,7 +850,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_ip_mux_64_4.py b/tb/test_ip_mux_64_4.py index 5cd32314a..c8509a690 100755 --- a/tb/test_ip_mux_64_4.py +++ b/tb/test_ip_mux_64_4.py @@ -865,7 +865,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_udp.py b/tb/test_udp.py index 584ff07b1..a6e395c5d 100755 --- a/tb/test_udp.py +++ b/tb/test_udp.py @@ -556,7 +556,7 @@ def bench(): raise StopSimulation - return dut, ip_source_logic, ip_sink_logic, udp_source_logic, udp_sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py index e9fe9b25d..f8d4e75d9 100755 --- a/tb/test_udp_64.py +++ b/tb/test_udp_64.py @@ -568,7 +568,7 @@ def bench(): raise StopSimulation - return dut, ip_source_logic, ip_sink_logic, udp_source_logic, udp_sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_udp_arb_mux_4.py b/tb/test_udp_arb_mux_4.py index 96ed5176e..4792317ed 100755 --- a/tb/test_udp_arb_mux_4.py +++ b/tb/test_udp_arb_mux_4.py @@ -1025,7 +1025,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_udp_arb_mux_64_4.py b/tb/test_udp_arb_mux_64_4.py index b090e0e84..bf9c9dbf9 100755 --- a/tb/test_udp_arb_mux_64_4.py +++ b/tb/test_udp_arb_mux_64_4.py @@ -1040,7 +1040,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_udp_checksum_gen.py b/tb/test_udp_checksum_gen.py index 3c30d7584..36472b104 100755 --- a/tb/test_udp_checksum_gen.py +++ b/tb/test_udp_checksum_gen.py @@ -493,7 +493,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_udp_checksum_gen_64.py b/tb/test_udp_checksum_gen_64.py index 0fc7a62c2..b38633dfb 100755 --- a/tb/test_udp_checksum_gen_64.py +++ b/tb/test_udp_checksum_gen_64.py @@ -499,7 +499,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py index c4ccad286..d5e880d77 100755 --- a/tb/test_udp_complete.py +++ b/tb/test_udp_complete.py @@ -853,7 +853,7 @@ def bench(): raise StopSimulation - return dut, eth_source_logic, eth_sink_logic, ip_source_logic, ip_sink_logic, udp_source_logic, udp_sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index 9da8c1b04..1c01361ca 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -871,7 +871,7 @@ def bench(): raise StopSimulation - return dut, eth_source_logic, eth_sink_logic, ip_source_logic, ip_sink_logic, udp_source_logic, udp_sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_udp_demux_4.py b/tb/test_udp_demux_4.py index 6a0a36eca..379a60d66 100755 --- a/tb/test_udp_demux_4.py +++ b/tb/test_udp_demux_4.py @@ -943,7 +943,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_udp_demux_64_4.py b/tb/test_udp_demux_64_4.py index 0060f455a..4320d5505 100755 --- a/tb/test_udp_demux_64_4.py +++ b/tb/test_udp_demux_64_4.py @@ -958,7 +958,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_0_logic, sink_1_logic, sink_2_logic, sink_3_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_udp_ip_rx.py b/tb/test_udp_ip_rx.py index cbe490c35..f2a7f2066 100755 --- a/tb/test_udp_ip_rx.py +++ b/tb/test_udp_ip_rx.py @@ -1034,7 +1034,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_udp_ip_rx_64.py b/tb/test_udp_ip_rx_64.py index 08144b687..dacc540c6 100755 --- a/tb/test_udp_ip_rx_64.py +++ b/tb/test_udp_ip_rx_64.py @@ -1040,7 +1040,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_udp_ip_tx.py b/tb/test_udp_ip_tx.py index a5bca5afd..c14b6e99f 100755 --- a/tb/test_udp_ip_tx.py +++ b/tb/test_udp_ip_tx.py @@ -981,7 +981,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_udp_ip_tx_64.py b/tb/test_udp_ip_tx_64.py index f1a7a7012..b6e427cce 100755 --- a/tb/test_udp_ip_tx_64.py +++ b/tb/test_udp_ip_tx_64.py @@ -987,7 +987,7 @@ def bench(): raise StopSimulation - return dut, source_logic, sink_logic, clkgen, monitor, check + return instances() def test_bench(): sim = Simulation(bench()) diff --git a/tb/test_udp_mux_4.py b/tb/test_udp_mux_4.py index 244da968e..d65979163 100755 --- a/tb/test_udp_mux_4.py +++ b/tb/test_udp_mux_4.py @@ -950,7 +950,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/test_udp_mux_64_4.py b/tb/test_udp_mux_64_4.py index c1d0b4320..cff25d07e 100755 --- a/tb/test_udp_mux_64_4.py +++ b/tb/test_udp_mux_64_4.py @@ -965,7 +965,7 @@ def bench(): raise StopSimulation - return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check + return instances() def test_bench(): os.chdir(os.path.dirname(os.path.abspath(__file__))) diff --git a/tb/udp_ep.py b/tb/udp_ep.py index 7d2b87d38..401e11317 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -449,7 +449,7 @@ class UDPFrameSource(): self.header_queue.append(frame) self.payload_source.send(frame.payload) - return logic, pause_logic, udp_payload_source + return instances() class UDPFrameSink(): @@ -578,5 +578,5 @@ class UDPFrameSink(): if len(self.header_queue) == 0: assert self.payload_sink.empty() - return logic, pause_logic, udp_payload_sink + return instances() diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index adf3f0a12..ca657b158 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -225,7 +225,7 @@ class XGMIISource(object): txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 txc.next = 0xff if bw == 8 else 0xf - return logic + return instances() class XGMIISink(object): @@ -307,5 +307,5 @@ class XGMIISink(object): d.append((int(rxd) >> (8*i)) & 0xff) c.append((int(rxc) >> i) & 1) - return logic + return instances() From 6368529b6fc4c2f8c0a13aff7f8218490467c3aa Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 14 Jun 2018 13:42:10 -0700 Subject: [PATCH 390/617] Add clock frequency annotation --- example/VCU118/fpga_10g/fpga.xdc | 2 ++ example/VCU118/fpga_1g/fpga.xdc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/example/VCU118/fpga_10g/fpga.xdc b/example/VCU118/fpga_10g/fpga.xdc index e790d0bea..a74495872 100644 --- a/example/VCU118/fpga_10g/fpga.xdc +++ b/example/VCU118/fpga_10g/fpga.xdc @@ -111,6 +111,7 @@ set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modprsl] set_property -dict {LOC AP21 IOSTANDARD LVCMOS18} [get_ports qsfp1_intl] set_property -dict {LOC AN21 IOSTANDARD LVCMOS18} [get_ports qsfp1_lpmode] +# 156.25 MHz MGT reference clock create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p] set_clock_groups -asynchronous -group [get_clocks qsfp1_mgt_refclk_0 -include_generated_clocks] @@ -142,6 +143,7 @@ set_property -dict {LOC AN24 IOSTANDARD LVCMOS18} [get_ports qsfp2_modprsl] set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports qsfp2_intl] set_property -dict {LOC AT24 IOSTANDARD LVCMOS18} [get_ports qsfp2_lpmode] +# 156.25 MHz MGT reference clock create_clock -period 6.400 -name qsfp2_mgt_refclk_0 [get_ports qsfp2_mgt_refclk_0_p] set_clock_groups -asynchronous -group [get_clocks qsfp2_mgt_refclk_0 -include_generated_clocks] diff --git a/example/VCU118/fpga_1g/fpga.xdc b/example/VCU118/fpga_1g/fpga.xdc index 5d3f614b2..e2f5f9c5b 100644 --- a/example/VCU118/fpga_1g/fpga.xdc +++ b/example/VCU118/fpga_1g/fpga.xdc @@ -111,6 +111,7 @@ set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generat #set_property -dict {LOC AP21 IOSTANDARD LVCMOS18} [get_ports qsfp1_intl] #set_property -dict {LOC AN21 IOSTANDARD LVCMOS18} [get_ports qsfp1_lpmode] +# 156.25 MHz MGT reference clock #create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p] #set_clock_groups -asynchronous -group [get_clocks qsfp1_mgt_refclk_0 -include_generated_clocks] @@ -142,6 +143,7 @@ set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generat #set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports qsfp2_intl] #set_property -dict {LOC AT24 IOSTANDARD LVCMOS18} [get_ports qsfp2_lpmode] +# 156.25 MHz MGT reference clock #create_clock -period 6.400 -name qsfp2_mgt_refclk_0 [get_ports qsfp2_mgt_refclk_0_p] #set_clock_groups -asynchronous -group [get_clocks qsfp2_mgt_refclk_0 -include_generated_clocks] From 25d1b373ccbee1dc367d00da6accc7ac654c078f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 14 Jun 2018 15:20:20 -0700 Subject: [PATCH 391/617] Use don't care bits --- rtl/axis_eth_fcs_insert_64.v | 30 +++++++++++++++--------------- rtl/eth_mac_10g_rx.v | 16 ++++++++-------- rtl/eth_mac_10g_tx.v | 30 +++++++++++++++--------------- rtl/ip_eth_rx_64.v | 16 ++++++++-------- rtl/ip_eth_tx_64.v | 16 ++++++++-------- rtl/udp_ip_rx_64.v | 16 ++++++++-------- rtl/udp_ip_tx_64.v | 16 ++++++++-------- 7 files changed, 70 insertions(+), 70 deletions(-) diff --git a/rtl/axis_eth_fcs_insert_64.v b/rtl/axis_eth_fcs_insert_64.v index aa3c3dbad..23242beea 100644 --- a/rtl/axis_eth_fcs_insert_64.v +++ b/rtl/axis_eth_fcs_insert_64.v @@ -249,14 +249,14 @@ eth_crc_64 ( function [3:0] keep2count; input [7:0] k; - case (k) - 8'b00000000: keep2count = 4'd0; - 8'b00000001: keep2count = 4'd1; - 8'b00000011: keep2count = 4'd2; - 8'b00000111: keep2count = 4'd3; - 8'b00001111: keep2count = 4'd4; - 8'b00011111: keep2count = 4'd5; - 8'b00111111: keep2count = 4'd6; + casez (k) + 8'bzzzzzzz0: keep2count = 4'd0; + 8'bzzzzzz01: keep2count = 4'd1; + 8'bzzzzz011: keep2count = 4'd2; + 8'bzzzz0111: keep2count = 4'd3; + 8'bzzz01111: keep2count = 4'd4; + 8'bzz011111: keep2count = 4'd5; + 8'bz0111111: keep2count = 4'd6; 8'b01111111: keep2count = 4'd7; 8'b11111111: keep2count = 4'd8; endcase @@ -288,38 +288,38 @@ end // FCS cycle calculation always @* begin - case (fcs_input_tkeep) - 8'b00000001: begin + casez (fcs_input_tkeep) + 8'bzzzzzz01: begin fcs_output_tdata_0 = {24'd0, ~crc_next0[31:0], fcs_input_tdata[7:0]}; fcs_output_tdata_1 = 64'd0; fcs_output_tkeep_0 = 8'b00011111; fcs_output_tkeep_1 = 8'b00000000; end - 8'b00000011: begin + 8'bzzzzz011: begin fcs_output_tdata_0 = {16'd0, ~crc_next1[31:0], fcs_input_tdata[15:0]}; fcs_output_tdata_1 = 64'd0; fcs_output_tkeep_0 = 8'b00111111; fcs_output_tkeep_1 = 8'b00000000; end - 8'b00000111: begin + 8'bzzzz0111: begin fcs_output_tdata_0 = {8'd0, ~crc_next2[31:0], fcs_input_tdata[23:0]}; fcs_output_tdata_1 = 64'd0; fcs_output_tkeep_0 = 8'b01111111; fcs_output_tkeep_1 = 8'b00000000; end - 8'b00001111: begin + 8'bzzz01111: begin fcs_output_tdata_0 = {~crc_next3[31:0], fcs_input_tdata[31:0]}; fcs_output_tdata_1 = 64'd0; fcs_output_tkeep_0 = 8'b11111111; fcs_output_tkeep_1 = 8'b00000000; end - 8'b00011111: begin + 8'bzz011111: begin fcs_output_tdata_0 = {~crc_next4[23:0], fcs_input_tdata[39:0]}; fcs_output_tdata_1 = {56'd0, ~crc_next4[31:24]}; fcs_output_tkeep_0 = 8'b11111111; fcs_output_tkeep_1 = 8'b00000001; end - 8'b00111111: begin + 8'bz0111111: begin fcs_output_tdata_0 = {~crc_next5[15:0], fcs_input_tdata[47:0]}; fcs_output_tdata_1 = {48'd0, ~crc_next5[31:16]}; fcs_output_tkeep_0 = 8'b11111111; diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index b9cb66c97..04d63e3f1 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -219,43 +219,43 @@ reg [7:0] control_masked; reg [7:0] tkeep_mask; always @* begin - case (detect_term) + casez (detect_term) 8'b00000000: begin detect_error_masked = detect_error; control_masked = xgmii_rxc_d0; tkeep_mask = 8'b11111111; end - 8'b00000001: begin + 8'bzzzzzzz1: begin detect_error_masked = 0; control_masked = 0; tkeep_mask = 8'b00000000; end - 8'b00000010: begin + 8'bzzzzzz10: begin detect_error_masked = detect_error[0]; control_masked = xgmii_rxc_d0[0]; tkeep_mask = 8'b00000001; end - 8'b00000100: begin + 8'bzzzzz100: begin detect_error_masked = detect_error[1:0]; control_masked = xgmii_rxc_d0[1:0]; tkeep_mask = 8'b00000011; end - 8'b00001000: begin + 8'bzzzz1000: begin detect_error_masked = detect_error[2:0]; control_masked = xgmii_rxc_d0[2:0]; tkeep_mask = 8'b00000111; end - 8'b00010000: begin + 8'bzzz10000: begin detect_error_masked = detect_error[3:0]; control_masked = xgmii_rxc_d0[3:0]; tkeep_mask = 8'b00001111; end - 8'b00100000: begin + 8'bzz100000: begin detect_error_masked = detect_error[4:0]; control_masked = xgmii_rxc_d0[4:0]; tkeep_mask = 8'b00011111; end - 8'b01000000: begin + 8'bz1000000: begin detect_error_masked = detect_error[5:0]; control_masked = xgmii_rxc_d0[5:0]; tkeep_mask = 8'b00111111; diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index ed2b955a2..77da1089b 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -255,14 +255,14 @@ eth_crc_64 ( function [3:0] keep2count; input [7:0] k; - case (k) - 8'b00000000: keep2count = 4'd0; - 8'b00000001: keep2count = 4'd1; - 8'b00000011: keep2count = 4'd2; - 8'b00000111: keep2count = 4'd3; - 8'b00001111: keep2count = 4'd4; - 8'b00011111: keep2count = 4'd5; - 8'b00111111: keep2count = 4'd6; + casez (k) + 8'bzzzzzzz0: keep2count = 4'd0; + 8'bzzzzzz01: keep2count = 4'd1; + 8'bzzzzz011: keep2count = 4'd2; + 8'bzzzz0111: keep2count = 4'd3; + 8'bzzz01111: keep2count = 4'd4; + 8'bzz011111: keep2count = 4'd5; + 8'bz0111111: keep2count = 4'd6; 8'b01111111: keep2count = 4'd7; 8'b11111111: keep2count = 4'd8; endcase @@ -294,43 +294,43 @@ end // FCS cycle calculation always @* begin - case (input_tkeep_reg) - 8'b00000001: begin + casez (input_tkeep_reg) + 8'bzzzzzz01: begin fcs_output_txd_0 = {24'h0707fd, ~crc_next0[31:0], input_tdata_reg[7:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b11100000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd3; end - 8'b00000011: begin + 8'bzzzzz011: begin fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], input_tdata_reg[15:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b11000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd2; end - 8'b00000111: begin + 8'bzzzz0111: begin fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], input_tdata_reg[23:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b10000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd1; end - 8'b00001111: begin + 8'bzzz01111: begin fcs_output_txd_0 = {~crc_next3[31:0], input_tdata_reg[31:0]}; fcs_output_txd_1 = {63'h07070707070707fd}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd8; end - 8'b00011111: begin + 8'bzz011111: begin fcs_output_txd_0 = {~crc_next4[23:0], input_tdata_reg[39:0]}; fcs_output_txd_1 = {56'h070707070707fd, ~crc_next4[31:24]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111110; ifg_offset = 8'd7; end - 8'b00111111: begin + 8'bz0111111: begin fcs_output_txd_0 = {~crc_next5[15:0], input_tdata_reg[47:0]}; fcs_output_txd_1 = {48'h0707070707fd, ~crc_next5[31:16]}; fcs_output_txc_0 = 8'b00000000; diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 246623e2f..0d82e4c8b 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -224,14 +224,14 @@ assign error_invalid_checksum = error_invalid_checksum_reg; function [3:0] keep2count; input [7:0] k; - case (k) - 8'b00000000: keep2count = 4'd0; - 8'b00000001: keep2count = 4'd1; - 8'b00000011: keep2count = 4'd2; - 8'b00000111: keep2count = 4'd3; - 8'b00001111: keep2count = 4'd4; - 8'b00011111: keep2count = 4'd5; - 8'b00111111: keep2count = 4'd6; + casez (k) + 8'bzzzzzzz0: keep2count = 4'd0; + 8'bzzzzzz01: keep2count = 4'd1; + 8'bzzzzz011: keep2count = 4'd2; + 8'bzzzz0111: keep2count = 4'd3; + 8'bzzz01111: keep2count = 4'd4; + 8'bzz011111: keep2count = 4'd5; + 8'bz0111111: keep2count = 4'd6; 8'b01111111: keep2count = 4'd7; 8'b11111111: keep2count = 4'd8; endcase diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 59c356985..6f7b42e70 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -194,14 +194,14 @@ assign error_payload_early_termination = error_payload_early_termination_reg; function [3:0] keep2count; input [7:0] k; - case (k) - 8'b00000000: keep2count = 4'd0; - 8'b00000001: keep2count = 4'd1; - 8'b00000011: keep2count = 4'd2; - 8'b00000111: keep2count = 4'd3; - 8'b00001111: keep2count = 4'd4; - 8'b00011111: keep2count = 4'd5; - 8'b00111111: keep2count = 4'd6; + casez (k) + 8'bzzzzzzz0: keep2count = 4'd0; + 8'bzzzzzz01: keep2count = 4'd1; + 8'bzzzzz011: keep2count = 4'd2; + 8'bzzzz0111: keep2count = 4'd3; + 8'bzzz01111: keep2count = 4'd4; + 8'bzz011111: keep2count = 4'd5; + 8'bz0111111: keep2count = 4'd6; 8'b01111111: keep2count = 4'd7; 8'b11111111: keep2count = 4'd8; endcase diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index 491cf3577..f9afeda74 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -227,14 +227,14 @@ assign error_payload_early_termination = error_payload_early_termination_reg; function [3:0] keep2count; input [7:0] k; - case (k) - 8'b00000000: keep2count = 4'd0; - 8'b00000001: keep2count = 4'd1; - 8'b00000011: keep2count = 4'd2; - 8'b00000111: keep2count = 4'd3; - 8'b00001111: keep2count = 4'd4; - 8'b00011111: keep2count = 4'd5; - 8'b00111111: keep2count = 4'd6; + casez (k) + 8'bzzzzzzz0: keep2count = 4'd0; + 8'bzzzzzz01: keep2count = 4'd1; + 8'bzzzzz011: keep2count = 4'd2; + 8'bzzzz0111: keep2count = 4'd3; + 8'bzzz01111: keep2count = 4'd4; + 8'bzz011111: keep2count = 4'd5; + 8'bz0111111: keep2count = 4'd6; 8'b01111111: keep2count = 4'd7; 8'b11111111: keep2count = 4'd8; endcase diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index 6771af971..4012eb157 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -218,14 +218,14 @@ assign error_payload_early_termination = error_payload_early_termination_reg; function [3:0] keep2count; input [7:0] k; - case (k) - 8'b00000000: keep2count = 4'd0; - 8'b00000001: keep2count = 4'd1; - 8'b00000011: keep2count = 4'd2; - 8'b00000111: keep2count = 4'd3; - 8'b00001111: keep2count = 4'd4; - 8'b00011111: keep2count = 4'd5; - 8'b00111111: keep2count = 4'd6; + casez (k) + 8'bzzzzzzz0: keep2count = 4'd0; + 8'bzzzzzz01: keep2count = 4'd1; + 8'bzzzzz011: keep2count = 4'd2; + 8'bzzzz0111: keep2count = 4'd3; + 8'bzzz01111: keep2count = 4'd4; + 8'bzz011111: keep2count = 4'd5; + 8'bz0111111: keep2count = 4'd6; 8'b01111111: keep2count = 4'd7; 8'b11111111: keep2count = 4'd8; endcase From 5b7646ccda32424530d350599f9520a33d474a40 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 18 Jun 2018 13:59:58 -0700 Subject: [PATCH 392/617] Rework ARP subsystem --- rtl/arp.v | 255 ++++++++++++++++++------------------ rtl/arp_64.v | 259 ++++++++++++++++++------------------- rtl/arp_cache.v | 236 +++++++++++++++++++-------------- rtl/ip.v | 17 ++- rtl/ip_64.v | 18 ++- rtl/ip_complete.v | 8 +- rtl/ip_complete_64.v | 8 +- rtl/udp_complete.v | 2 +- rtl/udp_complete_64.v | 2 +- tb/test_arp.py | 175 ++++++++++++++----------- tb/test_arp.v | 6 + tb/test_arp_64.py | 175 ++++++++++++++----------- tb/test_arp_64.v | 6 + tb/test_arp_cache.py | 223 ++++++++++++++++--------------- tb/test_arp_cache.v | 17 ++- tb/test_ip.py | 41 ++++-- tb/test_ip.v | 6 + tb/test_ip_64.py | 41 ++++-- tb/test_ip_64.v | 6 + tb/test_ip_complete.py | 1 + tb/test_ip_complete_64.py | 1 + tb/test_udp_complete.py | 5 +- tb/test_udp_complete_64.py | 5 +- 23 files changed, 857 insertions(+), 656 deletions(-) diff --git a/rtl/arp.v b/rtl/arp.v index ad80fe305..fdf6b87e9 100644 --- a/rtl/arp.v +++ b/rtl/arp.v @@ -30,7 +30,7 @@ THE SOFTWARE. * ARP block for IPv4, ethernet frame interface */ module arp #( - parameter CACHE_ADDR_WIDTH = 2, + parameter CACHE_ADDR_WIDTH = 9, parameter REQUEST_RETRY_COUNT = 4, parameter REQUEST_RETRY_INTERVAL = 125000000*2, parameter REQUEST_TIMEOUT = 125000000*30 @@ -71,8 +71,10 @@ module arp #( * ARP requests */ input wire arp_request_valid, + output wire arp_request_ready, input wire [31:0] arp_request_ip, output wire arp_response_valid, + input wire arp_response_ready, output wire arp_response_error, output wire [47:0] arp_response_mac, @@ -93,7 +95,7 @@ localparam [15:0] ARP_OPER_INARP_REPLY = 16'h0009; wire incoming_frame_valid; -wire incoming_frame_ready; +reg incoming_frame_ready; wire [47:0] incoming_eth_dest_mac; wire [47:0] incoming_eth_src_mac; wire [15:0] incoming_eth_type; @@ -107,19 +109,6 @@ wire [31:0] incoming_arp_spa; wire [47:0] incoming_arp_tha; wire [31:0] incoming_arp_tpa; -reg outgoing_frame_valid_reg = 1'b0, outgoing_frame_valid_next; -wire outgoing_frame_ready; -reg [47:0] outgoing_eth_dest_mac_reg = 48'd0, outgoing_eth_dest_mac_next; -reg [15:0] outgoing_arp_oper_reg = 16'd0, outgoing_arp_oper_next; -reg [47:0] outgoing_arp_tha_reg = 48'd0, outgoing_arp_tha_next; -reg [31:0] outgoing_arp_tpa_reg = 32'd0, outgoing_arp_tpa_next; - -// drop frame -reg drop_incoming_frame_reg = 1'b0, drop_incoming_frame_next; - -// wait on incoming frames until we can reply -assign incoming_frame_ready = outgoing_frame_ready | drop_incoming_frame_reg; - /* * ARP frame processing */ @@ -159,6 +148,13 @@ arp_eth_rx_inst ( .error_invalid_header() ); +reg outgoing_frame_valid_reg = 1'b0, outgoing_frame_valid_next; +wire outgoing_frame_ready; +reg [47:0] outgoing_eth_dest_mac_reg = 48'd0, outgoing_eth_dest_mac_next; +reg [15:0] outgoing_arp_oper_reg = 16'd0, outgoing_arp_oper_next; +reg [47:0] outgoing_arp_tha_reg = 48'd0, outgoing_arp_tha_next; +reg [31:0] outgoing_arp_tpa_reg = 32'd0, outgoing_arp_tpa_next; + arp_eth_tx arp_eth_tx_inst ( .clk(clk), @@ -191,27 +187,8 @@ arp_eth_tx_inst ( .busy() ); -wire incoming_eth_type_valid = (incoming_eth_type == 16'h0806); -wire incoming_arp_htype_valid = (incoming_arp_htype == 16'h0001); -wire incoming_arp_ptype_valid = (incoming_arp_ptype == 16'h0800); - -wire incoming_arp_oper_arp_request = (incoming_arp_oper == ARP_OPER_ARP_REQUEST); -wire incoming_arp_oper_arp_reply = (incoming_arp_oper == ARP_OPER_ARP_REPLY); -wire incoming_arp_oper_inarp_request = (incoming_arp_oper == ARP_OPER_INARP_REQUEST); -wire incoming_arp_oper_inarp_reply = (incoming_arp_oper == ARP_OPER_INARP_REPLY); - -wire filtered_incoming_frame_valid = incoming_frame_valid & - incoming_eth_type_valid & - incoming_arp_htype_valid & - incoming_arp_ptype_valid; - -wire filtered_incoming_arp_oper_arp_request = filtered_incoming_frame_valid & incoming_arp_oper_arp_request; -wire filtered_incoming_arp_oper_arp_reply = filtered_incoming_frame_valid & incoming_arp_oper_arp_reply; -wire filtered_incoming_arp_oper_inarp_request = filtered_incoming_frame_valid & incoming_arp_oper_inarp_request; -wire filtered_incoming_arp_oper_inarp_reply = filtered_incoming_frame_valid & incoming_arp_oper_inarp_reply; - -wire cache_query_request_valid; -wire [31:0] cache_query_request_ip; +reg cache_query_request_valid_reg = 1'b0, cache_query_request_valid_next; +reg [31:0] cache_query_request_ip_reg = 32'd0, cache_query_request_ip_next; wire cache_query_response_valid; wire cache_query_response_error; wire [47:0] cache_query_response_mac; @@ -219,8 +196,6 @@ wire [47:0] cache_query_response_mac; reg cache_write_request_valid_reg = 1'b0, cache_write_request_valid_next; reg [31:0] cache_write_request_ip_reg = 32'd0, cache_write_request_ip_next; reg [47:0] cache_write_request_mac_reg = 48'd0, cache_write_request_mac_next; -wire cache_write_in_progress; -wire cache_write_complete; /* * ARP cache @@ -232,134 +207,109 @@ arp_cache_inst ( .clk(clk), .rst(rst), // Query cache - .query_request_valid(cache_query_request_valid), - .query_request_ip(cache_query_request_ip), + .query_request_valid(cache_query_request_valid_reg), + .query_request_ready(), + .query_request_ip(cache_query_request_ip_reg), .query_response_valid(cache_query_response_valid), + .query_response_ready(1'b1), .query_response_error(cache_query_response_error), .query_response_mac(cache_query_response_mac), // Write cache .write_request_valid(cache_write_request_valid_reg), + .write_request_ready(), .write_request_ip(cache_write_request_ip_reg), .write_request_mac(cache_write_request_mac_reg), - .write_in_progress(cache_write_in_progress), - .write_complete(cache_write_complete), // Configuration .clear_cache(clear_cache) ); reg arp_request_operation_reg = 1'b0, arp_request_operation_next; -reg arp_request_valid_reg = 1'b0, arp_request_valid_next; +reg arp_request_ready_reg = 1'b0, arp_request_ready_next; reg [31:0] arp_request_ip_reg = 32'd0, arp_request_ip_next; +reg arp_response_valid_reg = 1'b0, arp_response_valid_next; reg arp_response_error_reg = 1'b0, arp_response_error_next; -reg arp_response_broadcast_reg = 1'b0, arp_response_broadcast_next; +reg [47:0] arp_response_mac_reg = 48'd0, arp_response_mac_next; reg [5:0] arp_request_retry_cnt_reg = 6'd0, arp_request_retry_cnt_next; reg [35:0] arp_request_timer_reg = 36'd0, arp_request_timer_next; -assign cache_query_request_valid = ~arp_request_operation_reg ? arp_request_valid_reg : 1'b1; -assign cache_query_request_ip = arp_request_ip_reg; +assign arp_request_ready = arp_request_ready_reg; -assign arp_response_valid = arp_response_error_reg | (cache_query_response_valid & ~cache_query_response_error & ~arp_request_operation_reg) | arp_response_broadcast_reg; +assign arp_response_valid = arp_response_valid_reg; assign arp_response_error = arp_response_error_reg; -assign arp_response_mac = arp_response_broadcast_reg ? 48'hffffffffffff : cache_query_response_mac; +assign arp_response_mac = arp_response_mac_reg; always @* begin + incoming_frame_ready = 1'b0; + outgoing_frame_valid_next = outgoing_frame_valid_reg & ~outgoing_frame_ready; outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; outgoing_arp_oper_next = outgoing_arp_oper_reg; outgoing_arp_tha_next = outgoing_arp_tha_reg; outgoing_arp_tpa_next = outgoing_arp_tpa_reg; - cache_write_request_valid_next = 1'b0; - cache_write_request_mac_next = 48'd0; - cache_write_request_ip_next = 32'd0; + cache_query_request_valid_next = 1'b0; + cache_query_request_ip_next = cache_query_request_ip_reg; - arp_request_valid_next = 1'b0; + cache_write_request_valid_next = 1'b0; + cache_write_request_mac_next = cache_write_request_mac_reg; + cache_write_request_ip_next = cache_write_request_ip_reg; + + arp_request_ready_next = 1'b0; arp_request_ip_next = arp_request_ip_reg; arp_request_operation_next = arp_request_operation_reg; arp_request_retry_cnt_next = arp_request_retry_cnt_reg; arp_request_timer_next = arp_request_timer_reg; + arp_response_valid_next = arp_response_valid_reg & ~arp_response_ready; arp_response_error_next = 1'b0; - arp_response_broadcast_next = 1'b0; - - drop_incoming_frame_next = 1'b0; + arp_response_mac_next = 48'd0; // manage incoming frames - if (filtered_incoming_frame_valid & ~(outgoing_frame_valid_reg & ~outgoing_frame_ready)) begin - // store sender addresses in cache - cache_write_request_valid_next = 1'b1; - cache_write_request_ip_next = incoming_arp_spa; - cache_write_request_mac_next = incoming_arp_sha; - if (incoming_arp_oper_arp_request) begin - if (incoming_arp_tpa == local_ip) begin - // send reply frame to valid incoming request - outgoing_frame_valid_next = 1'b1; - outgoing_eth_dest_mac_next = incoming_eth_src_mac; - outgoing_arp_oper_next = ARP_OPER_ARP_REPLY; - outgoing_arp_tha_next = incoming_arp_sha; - outgoing_arp_tpa_next = incoming_arp_spa; - end else begin - // does not match -> drop it - drop_incoming_frame_next = 1'b1; + incoming_frame_ready = outgoing_frame_ready; + if (incoming_frame_valid & incoming_frame_ready) begin + if (incoming_eth_type == 16'h0806 && incoming_arp_htype == 16'h0001 && incoming_arp_ptype == 16'h0800) begin + // store sender addresses in cache + cache_write_request_valid_next = 1'b1; + cache_write_request_ip_next = incoming_arp_spa; + cache_write_request_mac_next = incoming_arp_sha; + if (incoming_arp_oper == ARP_OPER_ARP_REQUEST) begin + // ARP request + if (incoming_arp_tpa == local_ip) begin + // send reply frame to valid incoming request + outgoing_frame_valid_next = 1'b1; + outgoing_eth_dest_mac_next = incoming_eth_src_mac; + outgoing_arp_oper_next = ARP_OPER_ARP_REPLY; + outgoing_arp_tha_next = incoming_arp_sha; + outgoing_arp_tpa_next = incoming_arp_spa; + end + end else if (incoming_arp_oper == ARP_OPER_INARP_REPLY) begin + // INARP request + if (incoming_arp_tha == local_mac) begin + // send reply frame to valid incoming request + outgoing_frame_valid_next = 1'b1; + outgoing_eth_dest_mac_next = incoming_eth_src_mac; + outgoing_arp_oper_next = ARP_OPER_INARP_REPLY; + outgoing_arp_tha_next = incoming_arp_sha; + outgoing_arp_tpa_next = incoming_arp_spa; + end end - end else if (incoming_arp_oper_inarp_request) begin - if (incoming_arp_tha == local_mac) begin - // send reply frame to valid incoming request - outgoing_frame_valid_next = 1'b1; - outgoing_eth_dest_mac_next = incoming_eth_src_mac; - outgoing_arp_oper_next = ARP_OPER_INARP_REPLY; - outgoing_arp_tha_next = incoming_arp_sha; - outgoing_arp_tpa_next = incoming_arp_spa; - end else begin - // does not match -> drop it - drop_incoming_frame_next = 1'b1; - end - end else begin - // does not match -> drop it - drop_incoming_frame_next = 1'b1; end - end else if (incoming_frame_valid & ~filtered_incoming_frame_valid) begin - // incoming invalid frame -> drop it - drop_incoming_frame_next = 1'b1; end // manage ARP lookup requests - if (~arp_request_operation_reg & ~arp_response_valid) begin - if (arp_request_valid) begin - if (~(arp_request_ip | subnet_mask) == 0) begin - // broadcast address - // (all bits in request IP set where subnet mask is clear) - arp_request_valid_next = 1'b0; - arp_response_broadcast_next = 1'b1; - end else if (((arp_request_ip ^ gateway_ip) & subnet_mask) == 0) begin - // within subnet, look up IP directly - // (no bits differ between request IP and gateway IP where subnet mask is set) - arp_request_valid_next = 1'b1; - arp_request_ip_next = arp_request_ip; - end else begin - // outside of subnet, so look up gateway address - arp_request_valid_next = 1'b1; - arp_request_ip_next = gateway_ip; - end - end - if (cache_query_response_error & ~arp_response_error) begin - arp_request_operation_next = 1'b1; - // send ARP request frame - outgoing_frame_valid_next = 1'b1; - outgoing_eth_dest_mac_next = 48'hFF_FF_FF_FF_FF_FF; - outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; - outgoing_arp_tha_next = 48'h00_00_00_00_00_00; - outgoing_arp_tpa_next = arp_request_ip_reg; - arp_request_retry_cnt_next = REQUEST_RETRY_COUNT-1; - arp_request_timer_next = REQUEST_RETRY_INTERVAL; - end - end else if (arp_request_operation_reg) begin + if (arp_request_operation_reg) begin + arp_request_ready_next = 1'b0; + cache_query_request_valid_next = 1'b1; arp_request_timer_next = arp_request_timer_reg - 1; // if we got a response, it will go in the cache, so when the query succeds, we're done - if (cache_query_response_valid & ~cache_query_response_error) begin + if (cache_query_response_valid & ~cache_query_response_error) begin arp_request_operation_next = 1'b0; + cache_query_request_valid_next = 1'b0; + arp_response_valid_next = 1'b1; + arp_response_error_next = 1'b0; + arp_response_mac_next = cache_query_response_mac; end // timer timeout if (arp_request_timer_reg == 0) begin @@ -367,9 +317,9 @@ always @* begin // have more retries // send ARP request frame outgoing_frame_valid_next = 1'b1; - outgoing_eth_dest_mac_next = 48'hFF_FF_FF_FF_FF_FF; + outgoing_eth_dest_mac_next = 48'hffffffffffff; outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; - outgoing_arp_tha_next = 48'h00_00_00_00_00_00; + outgoing_arp_tha_next = 48'h000000000000; outgoing_arp_tpa_next = arp_request_ip_reg; arp_request_retry_cnt_next = arp_request_retry_cnt_reg - 1; if (arp_request_retry_cnt_reg > 1) begin @@ -380,7 +330,51 @@ always @* begin end else begin // out of retries arp_request_operation_next = 1'b0; + arp_response_valid_next = 1'b1; arp_response_error_next = 1'b1; + cache_query_request_valid_next = 1'b0; + end + end + end else begin + arp_request_ready_next = ~arp_response_valid_next; + if (cache_query_request_valid_reg) begin + cache_query_request_valid_next = 1'b1; + if (cache_query_response_valid) begin + if (cache_query_response_error) begin + arp_request_operation_next = 1'b1; + // send ARP request frame + outgoing_frame_valid_next = 1'b1; + outgoing_eth_dest_mac_next = 48'hffffffffffff; + outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; + outgoing_arp_tha_next = 48'h000000000000; + outgoing_arp_tpa_next = arp_request_ip_reg; + arp_request_retry_cnt_next = REQUEST_RETRY_COUNT-1; + arp_request_timer_next = REQUEST_RETRY_INTERVAL; + end else begin + cache_query_request_valid_next = 1'b0; + arp_response_valid_next = 1'b1; + arp_response_error_next = 1'b0; + arp_response_mac_next = cache_query_response_mac; + end + end + end else if (arp_request_valid & arp_request_ready) begin + if (~(arp_request_ip | subnet_mask) == 0) begin + // broadcast address + // (all bits in request IP set where subnet mask is clear) + arp_response_valid_next = 1'b1; + arp_response_error_next = 1'b0; + arp_response_mac_next = 48'hffffffffffff; + end else if (((arp_request_ip ^ gateway_ip) & subnet_mask) == 0) begin + // within subnet, look up IP directly + // (no bits differ between request IP and gateway IP where subnet mask is set) + cache_query_request_valid_next = 1'b1; + cache_query_request_ip_next = arp_request_ip; + arp_request_ip_next = arp_request_ip; + end else begin + // outside of subnet, so look up gateway address + cache_query_request_valid_next = 1'b1; + cache_query_request_ip_next = gateway_ip; + arp_request_ip_next = gateway_ip; end end end @@ -389,26 +383,25 @@ end always @(posedge clk) begin if (rst) begin outgoing_frame_valid_reg <= 1'b0; + cache_query_request_valid_reg <= 1'b0; cache_write_request_valid_reg <= 1'b0; - arp_request_valid_reg <= 1'b0; + arp_request_ready_reg <= 1'b0; arp_request_operation_reg <= 1'b0; arp_request_retry_cnt_reg <= 6'd0; arp_request_timer_reg <= 36'd0; - arp_response_error_reg <= 1'b0; - arp_response_broadcast_reg <= 1'b0; - drop_incoming_frame_reg <= 1'b0; + arp_response_valid_reg <= 1'b0; end else begin outgoing_frame_valid_reg <= outgoing_frame_valid_next; + cache_query_request_valid_reg <= cache_query_request_valid_next; cache_write_request_valid_reg <= cache_write_request_valid_next; - arp_request_valid_reg <= arp_request_valid_next; + arp_request_ready_reg <= arp_request_ready_next; arp_request_operation_reg <= arp_request_operation_next; arp_request_retry_cnt_reg <= arp_request_retry_cnt_next; arp_request_timer_reg <= arp_request_timer_next; - arp_response_error_reg <= arp_response_error_next; - arp_response_broadcast_reg <= arp_response_broadcast_next; - drop_incoming_frame_reg <= drop_incoming_frame_next; + arp_response_valid_reg <= arp_response_valid_next; end + cache_query_request_ip_reg <= cache_query_request_ip_next; outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; outgoing_arp_oper_reg <= outgoing_arp_oper_next; outgoing_arp_tha_reg <= outgoing_arp_tha_next; @@ -416,6 +409,8 @@ always @(posedge clk) begin cache_write_request_mac_reg <= cache_write_request_mac_next; cache_write_request_ip_reg <= cache_write_request_ip_next; arp_request_ip_reg <= arp_request_ip_next; + arp_response_error_reg <= arp_response_error_next; + arp_response_mac_reg <= arp_response_mac_next; end endmodule diff --git a/rtl/arp_64.v b/rtl/arp_64.v index 82c19e3f5..28de11a5e 100644 --- a/rtl/arp_64.v +++ b/rtl/arp_64.v @@ -30,10 +30,10 @@ THE SOFTWARE. * ARP block for IPv4, ethernet frame interface (64 bit datapath) */ module arp_64 #( - parameter CACHE_ADDR_WIDTH = 2, + parameter CACHE_ADDR_WIDTH = 9, parameter REQUEST_RETRY_COUNT = 4, - parameter REQUEST_RETRY_INTERVAL = 125000000*2, - parameter REQUEST_TIMEOUT = 125000000*30 + parameter REQUEST_RETRY_INTERVAL = 156250000*2, + parameter REQUEST_TIMEOUT = 156250000*30 ) ( input wire clk, @@ -73,8 +73,10 @@ module arp_64 #( * ARP requests */ input wire arp_request_valid, + output wire arp_request_ready, input wire [31:0] arp_request_ip, output wire arp_response_valid, + input wire arp_response_ready, output wire arp_response_error, output wire [47:0] arp_response_mac, @@ -95,7 +97,7 @@ localparam [15:0] ARP_OPER_INARP_REPLY = 16'h0009; wire incoming_frame_valid; -wire incoming_frame_ready; +reg incoming_frame_ready; wire [47:0] incoming_eth_dest_mac; wire [47:0] incoming_eth_src_mac; wire [15:0] incoming_eth_type; @@ -109,19 +111,6 @@ wire [31:0] incoming_arp_spa; wire [47:0] incoming_arp_tha; wire [31:0] incoming_arp_tpa; -reg outgoing_frame_valid_reg = 1'b0, outgoing_frame_valid_next; -wire outgoing_frame_ready; -reg [47:0] outgoing_eth_dest_mac_reg = 48'd0, outgoing_eth_dest_mac_next; -reg [15:0] outgoing_arp_oper_reg = 16'd0, outgoing_arp_oper_next; -reg [47:0] outgoing_arp_tha_reg = 48'd0, outgoing_arp_tha_next; -reg [31:0] outgoing_arp_tpa_reg = 32'd0, outgoing_arp_tpa_next; - -// drop frame -reg drop_incoming_frame_reg = 1'b0, drop_incoming_frame_next; - -// wait on incoming frames until we can reply -assign incoming_frame_ready = outgoing_frame_ready | drop_incoming_frame_reg; - /* * ARP frame processing */ @@ -162,6 +151,13 @@ arp_eth_rx_inst ( .error_invalid_header() ); +reg outgoing_frame_valid_reg = 1'b0, outgoing_frame_valid_next; +wire outgoing_frame_ready; +reg [47:0] outgoing_eth_dest_mac_reg = 48'd0, outgoing_eth_dest_mac_next; +reg [15:0] outgoing_arp_oper_reg = 16'd0, outgoing_arp_oper_next; +reg [47:0] outgoing_arp_tha_reg = 48'd0, outgoing_arp_tha_next; +reg [31:0] outgoing_arp_tpa_reg = 32'd0, outgoing_arp_tpa_next; + arp_eth_tx_64 arp_eth_tx_inst ( .clk(clk), @@ -195,27 +191,8 @@ arp_eth_tx_inst ( .busy() ); -wire incoming_eth_type_valid = (incoming_eth_type == 16'h0806); -wire incoming_arp_htype_valid = (incoming_arp_htype == 16'h0001); -wire incoming_arp_ptype_valid = (incoming_arp_ptype == 16'h0800); - -wire incoming_arp_oper_arp_request = (incoming_arp_oper == ARP_OPER_ARP_REQUEST); -wire incoming_arp_oper_arp_reply = (incoming_arp_oper == ARP_OPER_ARP_REPLY); -wire incoming_arp_oper_inarp_request = (incoming_arp_oper == ARP_OPER_INARP_REQUEST); -wire incoming_arp_oper_inarp_reply = (incoming_arp_oper == ARP_OPER_INARP_REPLY); - -wire filtered_incoming_frame_valid = incoming_frame_valid & - incoming_eth_type_valid & - incoming_arp_htype_valid & - incoming_arp_ptype_valid; - -wire filtered_incoming_arp_oper_arp_request = filtered_incoming_frame_valid & incoming_arp_oper_arp_request; -wire filtered_incoming_arp_oper_arp_reply = filtered_incoming_frame_valid & incoming_arp_oper_arp_reply; -wire filtered_incoming_arp_oper_inarp_request = filtered_incoming_frame_valid & incoming_arp_oper_inarp_request; -wire filtered_incoming_arp_oper_inarp_reply = filtered_incoming_frame_valid & incoming_arp_oper_inarp_reply; - -wire cache_query_request_valid; -wire [31:0] cache_query_request_ip; +reg cache_query_request_valid_reg = 1'b0, cache_query_request_valid_next; +reg [31:0] cache_query_request_ip_reg = 32'd0, cache_query_request_ip_next; wire cache_query_response_valid; wire cache_query_response_error; wire [47:0] cache_query_response_mac; @@ -223,8 +200,6 @@ wire [47:0] cache_query_response_mac; reg cache_write_request_valid_reg = 1'b0, cache_write_request_valid_next; reg [31:0] cache_write_request_ip_reg = 32'd0, cache_write_request_ip_next; reg [47:0] cache_write_request_mac_reg = 48'd0, cache_write_request_mac_next; -wire cache_write_in_progress; -wire cache_write_complete; /* * ARP cache @@ -236,134 +211,109 @@ arp_cache_inst ( .clk(clk), .rst(rst), // Query cache - .query_request_valid(cache_query_request_valid), - .query_request_ip(cache_query_request_ip), + .query_request_valid(cache_query_request_valid_reg), + .query_request_ready(), + .query_request_ip(cache_query_request_ip_reg), .query_response_valid(cache_query_response_valid), + .query_response_ready(1'b1), .query_response_error(cache_query_response_error), .query_response_mac(cache_query_response_mac), // Write cache .write_request_valid(cache_write_request_valid_reg), + .write_request_ready(), .write_request_ip(cache_write_request_ip_reg), .write_request_mac(cache_write_request_mac_reg), - .write_in_progress(cache_write_in_progress), - .write_complete(cache_write_complete), // Configuration .clear_cache(clear_cache) ); reg arp_request_operation_reg = 1'b0, arp_request_operation_next; -reg arp_request_valid_reg = 1'b0, arp_request_valid_next; +reg arp_request_ready_reg = 1'b0, arp_request_ready_next; reg [31:0] arp_request_ip_reg = 32'd0, arp_request_ip_next; +reg arp_response_valid_reg = 1'b0, arp_response_valid_next; reg arp_response_error_reg = 1'b0, arp_response_error_next; -reg arp_response_broadcast_reg = 1'b0, arp_response_broadcast_next; +reg [47:0] arp_response_mac_reg = 48'd0, arp_response_mac_next; reg [5:0] arp_request_retry_cnt_reg = 6'd0, arp_request_retry_cnt_next; reg [35:0] arp_request_timer_reg = 36'd0, arp_request_timer_next; -assign cache_query_request_valid = ~arp_request_operation_reg ? arp_request_valid_reg : 1'b1; -assign cache_query_request_ip = arp_request_ip_reg; +assign arp_request_ready = arp_request_ready_reg; -assign arp_response_valid = arp_response_error_reg | (cache_query_response_valid & ~cache_query_response_error & ~arp_request_operation_reg) | arp_response_broadcast_reg; +assign arp_response_valid = arp_response_valid_reg; assign arp_response_error = arp_response_error_reg; -assign arp_response_mac = arp_response_broadcast_reg ? 48'hffffffffffff : cache_query_response_mac; +assign arp_response_mac = arp_response_mac_reg; always @* begin + incoming_frame_ready = 1'b0; + outgoing_frame_valid_next = outgoing_frame_valid_reg & ~outgoing_frame_ready; outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; outgoing_arp_oper_next = outgoing_arp_oper_reg; outgoing_arp_tha_next = outgoing_arp_tha_reg; outgoing_arp_tpa_next = outgoing_arp_tpa_reg; - cache_write_request_valid_next = 1'b0; - cache_write_request_mac_next = 48'd0; - cache_write_request_ip_next = 32'd0; + cache_query_request_valid_next = 1'b0; + cache_query_request_ip_next = cache_query_request_ip_reg; - arp_request_valid_next = 1'b0; + cache_write_request_valid_next = 1'b0; + cache_write_request_mac_next = cache_write_request_mac_reg; + cache_write_request_ip_next = cache_write_request_ip_reg; + + arp_request_ready_next = 1'b0; arp_request_ip_next = arp_request_ip_reg; arp_request_operation_next = arp_request_operation_reg; arp_request_retry_cnt_next = arp_request_retry_cnt_reg; arp_request_timer_next = arp_request_timer_reg; + arp_response_valid_next = arp_response_valid_reg & ~arp_response_ready; arp_response_error_next = 1'b0; - arp_response_broadcast_next = 1'b0; - - drop_incoming_frame_next = 1'b0; + arp_response_mac_next = 48'd0; // manage incoming frames - if (filtered_incoming_frame_valid & ~(outgoing_frame_valid_reg & ~outgoing_frame_ready)) begin - // store sender addresses in cache - cache_write_request_valid_next = 1'b1; - cache_write_request_ip_next = incoming_arp_spa; - cache_write_request_mac_next = incoming_arp_sha; - if (incoming_arp_oper_arp_request) begin - if (incoming_arp_tpa == local_ip) begin - // send reply frame to valid incoming request - outgoing_frame_valid_next = 1'b1; - outgoing_eth_dest_mac_next = incoming_eth_src_mac; - outgoing_arp_oper_next = ARP_OPER_ARP_REPLY; - outgoing_arp_tha_next = incoming_arp_sha; - outgoing_arp_tpa_next = incoming_arp_spa; - end else begin - // does not match -> drop it - drop_incoming_frame_next = 1'b1; + incoming_frame_ready = outgoing_frame_ready; + if (incoming_frame_valid & incoming_frame_ready) begin + if (incoming_eth_type == 16'h0806 && incoming_arp_htype == 16'h0001 && incoming_arp_ptype == 16'h0800) begin + // store sender addresses in cache + cache_write_request_valid_next = 1'b1; + cache_write_request_ip_next = incoming_arp_spa; + cache_write_request_mac_next = incoming_arp_sha; + if (incoming_arp_oper == ARP_OPER_ARP_REQUEST) begin + // ARP request + if (incoming_arp_tpa == local_ip) begin + // send reply frame to valid incoming request + outgoing_frame_valid_next = 1'b1; + outgoing_eth_dest_mac_next = incoming_eth_src_mac; + outgoing_arp_oper_next = ARP_OPER_ARP_REPLY; + outgoing_arp_tha_next = incoming_arp_sha; + outgoing_arp_tpa_next = incoming_arp_spa; + end + end else if (incoming_arp_oper == ARP_OPER_INARP_REPLY) begin + // INARP request + if (incoming_arp_tha == local_mac) begin + // send reply frame to valid incoming request + outgoing_frame_valid_next = 1'b1; + outgoing_eth_dest_mac_next = incoming_eth_src_mac; + outgoing_arp_oper_next = ARP_OPER_INARP_REPLY; + outgoing_arp_tha_next = incoming_arp_sha; + outgoing_arp_tpa_next = incoming_arp_spa; + end end - end else if (incoming_arp_oper_inarp_request) begin - if (incoming_arp_tha == local_mac) begin - // send reply frame to valid incoming request - outgoing_frame_valid_next = 1'b1; - outgoing_eth_dest_mac_next = incoming_eth_src_mac; - outgoing_arp_oper_next = ARP_OPER_INARP_REPLY; - outgoing_arp_tha_next = incoming_arp_sha; - outgoing_arp_tpa_next = incoming_arp_spa; - end else begin - // does not match -> drop it - drop_incoming_frame_next = 1'b1; - end - end else begin - // does not match -> drop it - drop_incoming_frame_next = 1'b1; end - end else if (incoming_frame_valid & ~filtered_incoming_frame_valid) begin - // incoming invalid frame -> drop it - drop_incoming_frame_next = 1'b1; end // manage ARP lookup requests - if (~arp_request_operation_reg & ~arp_response_valid) begin - if (arp_request_valid) begin - if (~(arp_request_ip | subnet_mask) == 0) begin - // broadcast address - // (all bits in request IP set where subnet mask is clear) - arp_request_valid_next = 1'b0; - arp_response_broadcast_next = 1'b1; - end else if (((arp_request_ip ^ gateway_ip) & subnet_mask) == 0) begin - // within subnet, look up IP directly - // (no bits differ between request IP and gateway IP where subnet mask is set) - arp_request_valid_next = 1'b1; - arp_request_ip_next = arp_request_ip; - end else begin - // outside of subnet, so look up gateway address - arp_request_valid_next = 1'b1; - arp_request_ip_next = gateway_ip; - end - end - if (cache_query_response_error & ~arp_response_error) begin - arp_request_operation_next = 1'b1; - // send ARP request frame - outgoing_frame_valid_next = 1'b1; - outgoing_eth_dest_mac_next = 48'hFF_FF_FF_FF_FF_FF; - outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; - outgoing_arp_tha_next = 48'h00_00_00_00_00_00; - outgoing_arp_tpa_next = arp_request_ip_reg; - arp_request_retry_cnt_next = REQUEST_RETRY_COUNT-1; - arp_request_timer_next = REQUEST_RETRY_INTERVAL; - end - end else if (arp_request_operation_reg) begin + if (arp_request_operation_reg) begin + arp_request_ready_next = 1'b0; + cache_query_request_valid_next = 1'b1; arp_request_timer_next = arp_request_timer_reg - 1; // if we got a response, it will go in the cache, so when the query succeds, we're done - if (cache_query_response_valid & ~cache_query_response_error) begin + if (cache_query_response_valid & ~cache_query_response_error) begin arp_request_operation_next = 1'b0; + cache_query_request_valid_next = 1'b0; + arp_response_valid_next = 1'b1; + arp_response_error_next = 1'b0; + arp_response_mac_next = cache_query_response_mac; end // timer timeout if (arp_request_timer_reg == 0) begin @@ -371,9 +321,9 @@ always @* begin // have more retries // send ARP request frame outgoing_frame_valid_next = 1'b1; - outgoing_eth_dest_mac_next = 48'hFF_FF_FF_FF_FF_FF; + outgoing_eth_dest_mac_next = 48'hffffffffffff; outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; - outgoing_arp_tha_next = 48'h00_00_00_00_00_00; + outgoing_arp_tha_next = 48'h000000000000; outgoing_arp_tpa_next = arp_request_ip_reg; arp_request_retry_cnt_next = arp_request_retry_cnt_reg - 1; if (arp_request_retry_cnt_reg > 1) begin @@ -384,7 +334,51 @@ always @* begin end else begin // out of retries arp_request_operation_next = 1'b0; + arp_response_valid_next = 1'b1; arp_response_error_next = 1'b1; + cache_query_request_valid_next = 1'b0; + end + end + end else begin + arp_request_ready_next = ~arp_response_valid_next; + if (cache_query_request_valid_reg) begin + cache_query_request_valid_next = 1'b1; + if (cache_query_response_valid) begin + if (cache_query_response_error) begin + arp_request_operation_next = 1'b1; + // send ARP request frame + outgoing_frame_valid_next = 1'b1; + outgoing_eth_dest_mac_next = 48'hffffffffffff; + outgoing_arp_oper_next = ARP_OPER_ARP_REQUEST; + outgoing_arp_tha_next = 48'h000000000000; + outgoing_arp_tpa_next = arp_request_ip_reg; + arp_request_retry_cnt_next = REQUEST_RETRY_COUNT-1; + arp_request_timer_next = REQUEST_RETRY_INTERVAL; + end else begin + cache_query_request_valid_next = 1'b0; + arp_response_valid_next = 1'b1; + arp_response_error_next = 1'b0; + arp_response_mac_next = cache_query_response_mac; + end + end + end else if (arp_request_valid & arp_request_ready) begin + if (~(arp_request_ip | subnet_mask) == 0) begin + // broadcast address + // (all bits in request IP set where subnet mask is clear) + arp_response_valid_next = 1'b1; + arp_response_error_next = 1'b0; + arp_response_mac_next = 48'hffffffffffff; + end else if (((arp_request_ip ^ gateway_ip) & subnet_mask) == 0) begin + // within subnet, look up IP directly + // (no bits differ between request IP and gateway IP where subnet mask is set) + cache_query_request_valid_next = 1'b1; + cache_query_request_ip_next = arp_request_ip; + arp_request_ip_next = arp_request_ip; + end else begin + // outside of subnet, so look up gateway address + cache_query_request_valid_next = 1'b1; + cache_query_request_ip_next = gateway_ip; + arp_request_ip_next = gateway_ip; end end end @@ -393,26 +387,25 @@ end always @(posedge clk) begin if (rst) begin outgoing_frame_valid_reg <= 1'b0; + cache_query_request_valid_reg <= 1'b0; cache_write_request_valid_reg <= 1'b0; - arp_request_valid_reg <= 1'b0; + arp_request_ready_reg <= 1'b0; arp_request_operation_reg <= 1'b0; arp_request_retry_cnt_reg <= 6'd0; arp_request_timer_reg <= 36'd0; - arp_response_error_reg <= 1'b0; - arp_response_broadcast_reg <= 1'b0; - drop_incoming_frame_reg <= 1'b0; + arp_response_valid_reg <= 1'b0; end else begin outgoing_frame_valid_reg <= outgoing_frame_valid_next; + cache_query_request_valid_reg <= cache_query_request_valid_next; cache_write_request_valid_reg <= cache_write_request_valid_next; - arp_request_valid_reg <= arp_request_valid_next; + arp_request_ready_reg <= arp_request_ready_next; arp_request_operation_reg <= arp_request_operation_next; arp_request_retry_cnt_reg <= arp_request_retry_cnt_next; arp_request_timer_reg <= arp_request_timer_next; - arp_response_error_reg <= arp_response_error_next; - arp_response_broadcast_reg <= arp_response_broadcast_next; - drop_incoming_frame_reg <= drop_incoming_frame_next; + arp_response_valid_reg <= arp_response_valid_next; end + cache_query_request_ip_reg <= cache_query_request_ip_next; outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next; outgoing_arp_oper_reg <= outgoing_arp_oper_next; outgoing_arp_tha_reg <= outgoing_arp_tha_next; @@ -420,6 +413,8 @@ always @(posedge clk) begin cache_write_request_mac_reg <= cache_write_request_mac_next; cache_write_request_ip_reg <= cache_write_request_ip_next; arp_request_ip_reg <= arp_request_ip_next; + arp_response_error_reg <= arp_response_error_next; + arp_response_mac_reg <= arp_response_mac_next; end endmodule diff --git a/rtl/arp_cache.v b/rtl/arp_cache.v index f57434ed6..fd695f3b6 100644 --- a/rtl/arp_cache.v +++ b/rtl/arp_cache.v @@ -27,32 +27,34 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * ARP cache block + * ARP cache */ module arp_cache #( - parameter CACHE_ADDR_WIDTH = 2 + parameter CACHE_ADDR_WIDTH = 9 ) ( input wire clk, input wire rst, /* - * Query cache + * Cache query */ input wire query_request_valid, + output wire query_request_ready, input wire [31:0] query_request_ip, + output wire query_response_valid, + input wire query_response_ready, output wire query_response_error, output wire [47:0] query_response_mac, /* - * Write cache + * Cache write */ input wire write_request_valid, + output wire write_request_ready, input wire [31:0] write_request_ip, input wire [47:0] write_request_mac, - output wire write_in_progress, - output wire write_complete, /* * Configuration @@ -60,118 +62,156 @@ module arp_cache #( input wire clear_cache ); -// bit LRU cache +reg mem_write = 0; +reg store_query = 0; +reg store_write = 0; -reg [31:0] ip_addr_mem[(2**CACHE_ADDR_WIDTH)-1:0]; -reg [47:0] mac_addr_mem[(2**CACHE_ADDR_WIDTH)-1:0]; -reg [(2**CACHE_ADDR_WIDTH)-1:0] lru_bit = 0; - -reg query_response_valid_reg = 0; -reg query_response_error_reg = 0; -reg [47:0] query_response_mac_reg = 0; - -reg write_complete_reg = 0; - -localparam [2:0] - WRITE_STATE_IDLE = 0, - WRITE_STATE_SEARCH = 1, - WRITE_STATE_NOTFOUND = 2; - -reg [2:0] write_state = WRITE_STATE_IDLE; +reg query_ip_valid_reg = 0, query_ip_valid_next; +reg [31:0] query_ip_reg = 0; +reg write_ip_valid_reg = 0, write_ip_valid_next; reg [31:0] write_ip_reg = 0; reg [47:0] write_mac_reg = 0; -reg [CACHE_ADDR_WIDTH-1:0] write_addr = 0; -reg [CACHE_ADDR_WIDTH-1:0] write_ptr = 0; -wire write_state_idle = (write_state == WRITE_STATE_IDLE); -wire write_state_search = (write_state == WRITE_STATE_SEARCH); -wire write_state_notfound = (write_state == WRITE_STATE_NOTFOUND); +reg [CACHE_ADDR_WIDTH-1:0] wr_ptr_reg = {CACHE_ADDR_WIDTH{1'b0}}, wr_ptr_next; +reg [CACHE_ADDR_WIDTH-1:0] rd_ptr_reg = {CACHE_ADDR_WIDTH{1'b0}}, rd_ptr_next; -reg clear_cache_operation = 0; +reg valid_mem[(2**CACHE_ADDR_WIDTH)-1:0]; +reg [31:0] ip_addr_mem[(2**CACHE_ADDR_WIDTH)-1:0]; +reg [47:0] mac_addr_mem[(2**CACHE_ADDR_WIDTH)-1:0]; + +reg query_request_ready_reg = 0, query_request_ready_next; + +reg query_response_valid_reg = 0, query_response_valid_next; +reg query_response_error_reg = 0, query_response_error_next; +reg [47:0] query_response_mac_reg = 0; + +reg write_request_ready_reg = 0, write_request_ready_next; + +wire [31:0] query_request_hash; +wire [31:0] write_request_hash; + +assign query_request_ready = query_request_ready_reg; assign query_response_valid = query_response_valid_reg; assign query_response_error = query_response_error_reg; assign query_response_mac = query_response_mac_reg; -assign write_in_progress = ~write_state_idle; -assign write_complete = write_complete_reg; +assign write_request_ready = write_request_ready_reg; -wire lru_full = &lru_bit; +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(32), + .STYLE("AUTO") +) +rd_hash ( + .data_in(query_request_ip), + .state_in(32'hffffffff), + .data_out(), + .state_out(query_request_hash) +); -integer i; +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(32), + .STYLE("AUTO") +) +wr_hash ( + .data_in(write_request_ip), + .state_in(32'hffffffff), + .data_out(), + .state_out(write_request_hash) +); + +always @* begin + mem_write = 1'b0; + store_query = 1'b0; + store_write = 1'b0; + + wr_ptr_next = wr_ptr_reg; + rd_ptr_next = rd_ptr_reg; + + query_ip_valid_next = query_ip_valid_reg; + + query_request_ready_next = ~query_ip_valid_reg || ~query_request_valid || query_response_ready; + + query_response_valid_next = query_response_valid_reg & ~query_response_ready; + query_response_error_next = query_response_error_reg; + + if (query_ip_valid_reg && (~query_request_valid || query_response_ready)) begin + query_response_valid_next = 1; + query_ip_valid_next = 0; + if (valid_mem[rd_ptr_reg] && ip_addr_mem[rd_ptr_reg] == query_ip_reg) begin + query_response_error_next = 0; + end else begin + query_response_error_next = 1; + end + end + + if (query_request_valid && query_request_ready && (~query_ip_valid_reg || ~query_request_valid || query_response_ready)) begin + store_query = 1; + query_ip_valid_next = 1; + rd_ptr_next = query_request_hash[CACHE_ADDR_WIDTH-1:0]; + end + + write_ip_valid_next = write_ip_valid_reg; + + write_request_ready_next = 1'b1; + + if (write_ip_valid_reg) begin + write_ip_valid_next = 0; + mem_write = 1; + end + + if (write_request_valid && write_request_ready) begin + store_write = 1; + write_ip_valid_next = 1; + wr_ptr_next = write_request_hash[CACHE_ADDR_WIDTH-1:0]; + end +end always @(posedge clk) begin if (rst) begin - query_response_valid_reg <= 0; - query_response_error_reg <= 0; - write_complete_reg <= 0; - write_state <= WRITE_STATE_IDLE; - write_addr <= 0; - write_ptr <= 0; - clear_cache_operation <= 1; - lru_bit <= 0; + query_ip_valid_reg <= 1'b0; + query_request_ready_reg <= 1'b0; + query_response_valid_reg <= 1'b0; + write_ip_valid_reg <= 1'b0; + write_request_ready_reg <= 1'b0; end else begin - write_complete_reg <= 0; - query_response_valid_reg <= 0; - query_response_error_reg <= 0; + query_ip_valid_reg <= query_ip_valid_next; + query_request_ready_reg <= query_request_ready_next; + query_response_valid_reg <= query_response_valid_next; + write_ip_valid_reg <= write_ip_valid_next; + write_request_ready_reg <= write_request_ready_next; + end - // clear LRU bits when full - if (lru_full) begin - lru_bit <= 0; - end + query_response_error_reg <= query_response_error_next; - // fast IP match and readout - if (query_request_valid) begin - query_response_valid_reg <= 1; - query_response_error_reg <= 1; - for (i = 0; i < 2**CACHE_ADDR_WIDTH; i = i + 1) begin - if (ip_addr_mem[i] == query_request_ip) begin - query_response_error_reg <= 0; - query_response_mac_reg <= mac_addr_mem[i]; - lru_bit[i] <= 1'b1; - end - end - end + if (store_query) begin + query_ip_reg <= query_request_ip; + end - // manage writes - if (write_state_idle) begin - if (write_request_valid) begin - write_state <= WRITE_STATE_SEARCH; - write_ip_reg <= write_request_ip; - write_mac_reg <= write_request_mac; - end - write_addr <= 0; - end else if (write_state_search) begin - write_addr <= write_addr + 1; - if (&write_addr) begin - write_state <= WRITE_STATE_NOTFOUND; - end - if (ip_addr_mem[write_addr] == write_ip_reg) begin - write_state <= WRITE_STATE_IDLE; - mac_addr_mem[write_addr] <= write_mac_reg; - write_complete_reg <= 1; - end - end else if (write_state_notfound) begin - write_ptr <= write_ptr + 1; - if (~lru_bit[write_ptr]) begin - ip_addr_mem[write_ptr] <= write_ip_reg; - mac_addr_mem[write_ptr] <= write_mac_reg; - write_state <= WRITE_STATE_IDLE; - write_complete_reg <= 1; - end - end + if (store_write) begin + write_ip_reg <= write_request_ip; + write_mac_reg <= write_request_mac; + end - // clear cache - if (clear_cache & ~clear_cache_operation) begin - clear_cache_operation <= 1; - write_addr <= 0; - end - if (clear_cache_operation) begin - write_addr <= write_addr + 1; - ip_addr_mem[write_addr] <= 0; - mac_addr_mem[write_addr] <= 0; - clear_cache_operation <= ~&write_addr; - end + wr_ptr_reg <= wr_ptr_next; + rd_ptr_reg <= rd_ptr_next; + + query_response_mac_reg <= mac_addr_mem[rd_ptr_reg]; + + if (mem_write) begin + valid_mem[wr_ptr_reg] <= 1'b1; + ip_addr_mem[wr_ptr_reg] <= write_ip_reg; + mac_addr_mem[wr_ptr_reg] <= write_mac_reg; end end diff --git a/rtl/ip.v b/rtl/ip.v index d76e9a8df..0a520f645 100644 --- a/rtl/ip.v +++ b/rtl/ip.v @@ -66,8 +66,10 @@ module ip * ARP requests */ output wire arp_request_valid, + input wire arp_request_ready, output wire [31:0] arp_request_ip, input wire arp_response_valid, + output wire arp_response_ready, input wire arp_response_error, input wire [47:0] arp_response_mac, @@ -242,20 +244,24 @@ reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; reg arp_request_valid_reg = 1'b0, arp_request_valid_next; +reg arp_response_ready_reg = 1'b0, arp_response_ready_next; + reg drop_packet_reg = 1'b0, drop_packet_next; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; -assign arp_request_valid = arp_request_valid_reg | (input_ip_hdr_valid & ~input_ip_hdr_ready_reg); +assign arp_request_valid = arp_request_valid_reg; assign arp_request_ip = input_ip_dest_ip; +assign arp_response_ready = arp_response_ready_reg; assign tx_error_arp_failed = arp_response_error; always @* begin state_next = STATE_IDLE; - arp_request_valid_next = 1'b0; + arp_request_valid_next = arp_request_valid_reg & ~arp_request_ready; + arp_response_ready_next = 1'b0; drop_packet_next = 1'b0; input_ip_hdr_ready_next = 1'b0; @@ -269,26 +275,25 @@ always @* begin if (input_ip_hdr_valid) begin // initiate ARP request arp_request_valid_next = 1'b1; + arp_response_ready_next = 1'b1; state_next = STATE_ARP_QUERY; end else begin state_next = STATE_IDLE; end end STATE_ARP_QUERY: begin - arp_request_valid_next = 1; + arp_response_ready_next = 1'b1; if (arp_response_valid) begin // wait for ARP reponse if (arp_response_error) begin // did not get MAC address; drop packet input_ip_hdr_ready_next = 1'b1; - arp_request_valid_next = 1'b0; drop_packet_next = 1'b1; state_next = STATE_WAIT_PACKET; end else begin // got MAC address; send packet input_ip_hdr_ready_next = 1'b1; - arp_request_valid_next = 1'b0; outgoing_ip_hdr_valid_next = 1'b1; outgoing_eth_dest_mac_next = arp_response_mac; state_next = STATE_WAIT_PACKET; @@ -314,6 +319,7 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; arp_request_valid_reg <= 1'b0; + arp_response_ready_reg <= 1'b0; drop_packet_reg <= 1'b0; input_ip_hdr_ready_reg <= 1'b0; outgoing_ip_hdr_valid_reg <= 1'b0; @@ -321,6 +327,7 @@ always @(posedge clk) begin state_reg <= state_next; arp_request_valid_reg <= arp_request_valid_next; + arp_response_ready_reg <= arp_response_ready_next; drop_packet_reg <= drop_packet_next; input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; diff --git a/rtl/ip_64.v b/rtl/ip_64.v index 476cc979f..806f20faf 100644 --- a/rtl/ip_64.v +++ b/rtl/ip_64.v @@ -68,8 +68,10 @@ module ip_64 * ARP requests */ output wire arp_request_valid, + input wire arp_request_ready, output wire [31:0] arp_request_ip, input wire arp_response_valid, + output wire arp_response_ready, input wire arp_response_error, input wire [47:0] arp_response_mac, @@ -246,25 +248,28 @@ ip_eth_tx_64_inst ( .error_payload_early_termination(tx_error_payload_early_termination) ); - reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; reg arp_request_valid_reg = 1'b0, arp_request_valid_next; +reg arp_response_ready_reg = 1'b0, arp_response_ready_next; + reg drop_packet_reg = 1'b0, drop_packet_next; assign input_ip_hdr_ready = input_ip_hdr_ready_reg; assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; -assign arp_request_valid = arp_request_valid_reg | (input_ip_hdr_valid & ~input_ip_hdr_ready_reg); +assign arp_request_valid = arp_request_valid_reg; assign arp_request_ip = input_ip_dest_ip; +assign arp_response_ready = arp_response_ready_reg; assign tx_error_arp_failed = arp_response_error; always @* begin state_next = STATE_IDLE; - arp_request_valid_next = 1'b0; + arp_request_valid_next = arp_request_valid_reg & ~arp_request_ready; + arp_response_ready_next = 1'b0; drop_packet_next = 1'b0; input_ip_hdr_ready_next = 1'b0; @@ -278,26 +283,25 @@ always @* begin if (input_ip_hdr_valid) begin // initiate ARP request arp_request_valid_next = 1'b1; + arp_response_ready_next = 1'b1; state_next = STATE_ARP_QUERY; end else begin state_next = STATE_IDLE; end end STATE_ARP_QUERY: begin - arp_request_valid_next = 1'b1; + arp_response_ready_next = 1'b1; if (arp_response_valid) begin // wait for ARP reponse if (arp_response_error) begin // did not get MAC address; drop packet input_ip_hdr_ready_next = 1'b1; - arp_request_valid_next = 1'b0; drop_packet_next = 1'b1; state_next = STATE_WAIT_PACKET; end else begin // got MAC address; send packet input_ip_hdr_ready_next = 1'b1; - arp_request_valid_next = 1'b0; outgoing_ip_hdr_valid_next = 1'b1; outgoing_eth_dest_mac_next = arp_response_mac; state_next = STATE_WAIT_PACKET; @@ -323,6 +327,7 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; arp_request_valid_reg <= 1'b0; + arp_response_ready_reg <= 1'b0; drop_packet_reg <= 1'b0; input_ip_hdr_ready_reg <= 1'b0; outgoing_ip_hdr_valid_reg <= 1'b0; @@ -330,6 +335,7 @@ always @(posedge clk) begin state_reg <= state_next; arp_request_valid_reg <= arp_request_valid_next; + arp_response_ready_reg <= arp_response_ready_next; drop_packet_reg <= drop_packet_next; input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; diff --git a/rtl/ip_complete.v b/rtl/ip_complete.v index 0833a2ef2..c5ddc67bc 100644 --- a/rtl/ip_complete.v +++ b/rtl/ip_complete.v @@ -30,7 +30,7 @@ THE SOFTWARE. * IPv4 and ARP block, ethernet frame interface */ module ip_complete #( - parameter ARP_CACHE_ADDR_WIDTH = 2, + parameter ARP_CACHE_ADDR_WIDTH = 9, parameter ARP_REQUEST_RETRY_COUNT = 4, parameter ARP_REQUEST_RETRY_INTERVAL = 125000000*2, parameter ARP_REQUEST_TIMEOUT = 125000000*30 @@ -141,8 +141,10 @@ This module integrates the IP and ARP modules for a complete IP stack */ wire arp_request_valid; +wire arp_request_ready; wire [31:0] arp_request_ip; wire arp_response_valid; +wire arp_response_ready; wire arp_response_error; wire [47:0] arp_response_mac; @@ -361,8 +363,10 @@ ip_inst ( .input_ip_payload_tuser(input_ip_payload_tuser), // ARP requests .arp_request_valid(arp_request_valid), + .arp_request_ready(arp_request_ready), .arp_request_ip(arp_request_ip), .arp_response_valid(arp_response_valid), + .arp_response_ready(arp_response_ready), .arp_response_error(arp_response_error), .arp_response_mac(arp_response_mac), // Status @@ -415,8 +419,10 @@ arp_inst ( .output_eth_payload_tuser(arp_tx_eth_payload_tuser), // ARP requests .arp_request_valid(arp_request_valid), + .arp_request_ready(arp_request_ready), .arp_request_ip(arp_request_ip), .arp_response_valid(arp_response_valid), + .arp_response_ready(arp_response_ready), .arp_response_error(arp_response_error), .arp_response_mac(arp_response_mac), // Configuration diff --git a/rtl/ip_complete_64.v b/rtl/ip_complete_64.v index 7134e017b..14271670e 100644 --- a/rtl/ip_complete_64.v +++ b/rtl/ip_complete_64.v @@ -30,7 +30,7 @@ THE SOFTWARE. * IPv4 and ARP block, ethernet frame interface (64 bit datapath) */ module ip_complete_64 #( - parameter ARP_CACHE_ADDR_WIDTH = 2, + parameter ARP_CACHE_ADDR_WIDTH = 9, parameter ARP_REQUEST_RETRY_COUNT = 4, parameter ARP_REQUEST_RETRY_INTERVAL = 156250000*2, parameter ARP_REQUEST_TIMEOUT = 156250000*30 @@ -145,8 +145,10 @@ This module integrates the IP and ARP modules for a complete IP stack */ wire arp_request_valid; +wire arp_request_ready; wire [31:0] arp_request_ip; wire arp_response_valid; +wire arp_response_ready; wire arp_response_error; wire [47:0] arp_response_mac; @@ -378,8 +380,10 @@ ip_inst ( .input_ip_payload_tuser(input_ip_payload_tuser), // ARP requests .arp_request_valid(arp_request_valid), + .arp_request_ready(arp_request_ready), .arp_request_ip(arp_request_ip), .arp_response_valid(arp_response_valid), + .arp_response_ready(arp_response_ready), .arp_response_error(arp_response_error), .arp_response_mac(arp_response_mac), // Status @@ -434,8 +438,10 @@ arp_inst ( .output_eth_payload_tuser(arp_tx_eth_payload_tuser), // ARP requests .arp_request_valid(arp_request_valid), + .arp_request_ready(arp_request_ready), .arp_request_ip(arp_request_ip), .arp_response_valid(arp_response_valid), + .arp_response_ready(arp_response_ready), .arp_response_error(arp_response_error), .arp_response_mac(arp_response_mac), // Configuration diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v index 1633f1c18..7593b3acd 100644 --- a/rtl/udp_complete.v +++ b/rtl/udp_complete.v @@ -30,7 +30,7 @@ THE SOFTWARE. * IPv4 and ARP block with UDP support, ethernet frame interface */ module udp_complete #( - parameter ARP_CACHE_ADDR_WIDTH = 2, + parameter ARP_CACHE_ADDR_WIDTH = 9, parameter ARP_REQUEST_RETRY_COUNT = 4, parameter ARP_REQUEST_RETRY_INTERVAL = 125000000*2, parameter ARP_REQUEST_TIMEOUT = 125000000*30, diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v index fec881149..041519876 100644 --- a/rtl/udp_complete_64.v +++ b/rtl/udp_complete_64.v @@ -30,7 +30,7 @@ THE SOFTWARE. * IPv4 and ARP block with UDP support, ethernet frame interface (64 bit datapath) */ module udp_complete_64 #( - parameter ARP_CACHE_ADDR_WIDTH = 2, + parameter ARP_CACHE_ADDR_WIDTH = 9, parameter ARP_REQUEST_RETRY_COUNT = 4, parameter ARP_REQUEST_RETRY_INTERVAL = 125000000*2, parameter ARP_REQUEST_TIMEOUT = 125000000*30, diff --git a/tb/test_arp.py b/tb/test_arp.py index 465bfe637..e9fcd16d2 100755 --- a/tb/test_arp.py +++ b/tb/test_arp.py @@ -26,6 +26,7 @@ THE SOFTWARE. from myhdl import * import os +import axis_ep import eth_ep import arp_ep @@ -35,6 +36,7 @@ testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") srcs.append("../rtl/arp_cache.v") srcs.append("../rtl/arp_eth_rx.v") srcs.append("../rtl/arp_eth_tx.v") @@ -65,6 +67,7 @@ def bench(): arp_request_valid = Signal(bool(0)) arp_request_ip = Signal(intbv(0)[32:]) + arp_response_ready = Signal(bool(0)) local_mac = Signal(intbv(0)[48:]) local_ip = Signal(intbv(0)[32:]) @@ -85,17 +88,18 @@ def bench(): output_eth_payload_tlast = Signal(bool(0)) output_eth_payload_tuser = Signal(bool(0)) + arp_request_ready = Signal(bool(0)) arp_response_valid = Signal(bool(0)) arp_response_error = Signal(bool(0)) arp_response_mac = Signal(intbv(0)[48:]) # sources and sinks - source_pause = Signal(bool(0)) - sink_pause = Signal(bool(0)) + eth_source_pause = Signal(bool(0)) + eth_sink_pause = Signal(bool(0)) - source = eth_ep.EthFrameSource() + eth_source = eth_ep.EthFrameSource() - source_logic = source.create_logic( + eth_source_logic = eth_source.create_logic( clk, rst, eth_hdr_ready=input_eth_hdr_ready, @@ -108,13 +112,13 @@ def bench(): eth_payload_tready=input_eth_payload_tready, eth_payload_tlast=input_eth_payload_tlast, eth_payload_tuser=input_eth_payload_tuser, - pause=source_pause, - name='source' + pause=eth_source_pause, + name='eth_source' ) - sink = eth_ep.EthFrameSink() + eth_sink = eth_ep.EthFrameSink() - sink_logic = sink.create_logic( + eth_sink_logic = eth_sink.create_logic( clk, rst, eth_hdr_ready=output_eth_hdr_ready, @@ -127,8 +131,30 @@ def bench(): eth_payload_tready=output_eth_payload_tready, eth_payload_tlast=output_eth_payload_tlast, eth_payload_tuser=output_eth_payload_tuser, - pause=sink_pause, - name='sink' + pause=eth_sink_pause, + name='eth_sink' + ) + + arp_request_source = axis_ep.AXIStreamSource() + + arp_request_source_logic = arp_request_source.create_logic( + clk, + rst, + tdata=(arp_request_ip,), + tvalid=arp_request_valid, + tready=arp_request_ready, + name='arp_request_source' + ) + + arp_response_sink = axis_ep.AXIStreamSink() + + arp_response_sink_logic = arp_response_sink.create_logic( + clk, + rst, + tdata=(arp_response_error, arp_response_mac), + tvalid=arp_response_valid, + tready=arp_response_ready, + name='arp_response_sink' ) # DUT @@ -164,8 +190,10 @@ def bench(): output_eth_payload_tuser=output_eth_payload_tuser, arp_request_valid=arp_request_valid, + arp_request_ready=arp_request_ready, arp_request_ip=arp_request_ip, arp_response_valid=arp_response_valid, + arp_response_ready=arp_response_ready, arp_response_error=arp_response_error, arp_response_mac=arp_response_mac, @@ -214,14 +242,13 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0x000000000000 test_frame.arp_tpa = 0xc0a80165 - source.send(test_frame.build_eth()) + eth_source.send(test_frame.build_eth()) yield clk.posedge - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge + while eth_sink.empty(): + yield clk.posedge - rx_frame = sink.recv() + rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -244,15 +271,15 @@ def bench(): print("test 2: Cached read") current_test.next = 2 - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0xc0a80164 - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0xc0a80164,)]) - yield arp_response_valid.posedge - assert not bool(arp_response_error) - assert int(arp_response_mac) == 0x5A5152535455 + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert not err + assert mac == 0x5A5152535455 yield delay(100) @@ -260,18 +287,13 @@ def bench(): print("test 3: Unached read") current_test.next = 3 - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0xc0a80166 - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0xc0a80166,)]) # wait for ARP request packet - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge + while eth_sink.empty(): + yield clk.posedge - rx_frame = sink.recv() + rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -302,13 +324,17 @@ def bench(): test_frame.arp_spa = 0xc0a80166 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source.send(test_frame.build_eth()) + eth_source.send(test_frame.build_eth()) yield clk.posedge # wait for lookup - yield arp_response_valid.posedge - assert not bool(arp_response_error) - assert int(arp_response_mac) == 0x6A6162636465 + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert not err + assert mac == 0x6A6162636465 yield delay(100) @@ -316,18 +342,13 @@ def bench(): print("test 4: Unached read, outside of subnet") current_test.next = 4 - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0x08080808 - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0x08080808,)]) # wait for ARP request packet - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge + while eth_sink.empty(): + yield clk.posedge - rx_frame = sink.recv() + rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -358,13 +379,17 @@ def bench(): test_frame.arp_spa = 0xc0a80101 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source.send(test_frame.build_eth()) + eth_source.send(test_frame.build_eth()) yield clk.posedge # wait for lookup - yield arp_response_valid.posedge - assert not bool(arp_response_error) - assert int(arp_response_mac) == 0xAABBCCDDEEFF + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert not err + assert mac == 0xAABBCCDDEEFF yield delay(100) @@ -372,20 +397,20 @@ def bench(): print("test 5: Unached read, timeout") current_test.next = 5 - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0xc0a80167 - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0xc0a80167,)]) - yield arp_response_valid.posedge - assert bool(arp_response_error) + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert err # check for 4 ARP requests - assert sink.count() == 4 + assert eth_sink.count() == 4 - while not sink.empty(): - rx_frame = sink.recv() + while not eth_sink.empty(): + rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -410,26 +435,26 @@ def bench(): current_test.next = 6 # subnet broadcast - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0xc0a801FF - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0xc0a801ff,)]) - yield arp_response_valid.posedge - assert not bool(arp_response_error) - assert int(arp_response_mac) == 0xFFFFFFFFFFFF + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert not err + assert mac == 0xffffffffffff # general broadcast - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0xFFFFFFFF - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0xffffffff,)]) - yield arp_response_valid.posedge - assert not bool(arp_response_error) - assert int(arp_response_mac) == 0xFFFFFFFFFFFF + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert not err + assert mac == 0xffffffffffff yield delay(100) diff --git a/tb/test_arp.v b/tb/test_arp.v index 98b938297..416a2b332 100644 --- a/tb/test_arp.v +++ b/tb/test_arp.v @@ -50,6 +50,7 @@ reg output_eth_payload_tready = 0; reg arp_request_valid = 0; reg [31:0] arp_request_ip = 0; +reg arp_response_ready = 0; reg [47:0] local_mac = 0; reg [31:0] local_ip = 0; @@ -70,6 +71,7 @@ wire output_eth_payload_tvalid; wire output_eth_payload_tlast; wire output_eth_payload_tuser; +wire arp_request_ready; wire arp_response_valid; wire arp_response_error; wire [47:0] arp_response_mac; @@ -92,6 +94,7 @@ initial begin output_eth_payload_tready, arp_request_valid, arp_request_ip, + arp_response_ready, local_mac, local_ip, gateway_ip, @@ -109,6 +112,7 @@ initial begin output_eth_payload_tvalid, output_eth_payload_tlast, output_eth_payload_tuser, + arp_request_ready, arp_response_valid, arp_response_error, arp_response_mac @@ -152,8 +156,10 @@ UUT ( .output_eth_payload_tuser(output_eth_payload_tuser), // ARP requests .arp_request_valid(arp_request_valid), + .arp_request_ready(arp_request_ready), .arp_request_ip(arp_request_ip), .arp_response_valid(arp_response_valid), + .arp_response_ready(arp_response_ready), .arp_response_error(arp_response_error), .arp_response_mac(arp_response_mac), // Configuration diff --git a/tb/test_arp_64.py b/tb/test_arp_64.py index 3357ee134..0f7992b4b 100755 --- a/tb/test_arp_64.py +++ b/tb/test_arp_64.py @@ -26,6 +26,7 @@ THE SOFTWARE. from myhdl import * import os +import axis_ep import eth_ep import arp_ep @@ -35,6 +36,7 @@ testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") srcs.append("../rtl/arp_cache.v") srcs.append("../rtl/arp_eth_rx_64.v") srcs.append("../rtl/arp_eth_tx_64.v") @@ -66,6 +68,7 @@ def bench(): arp_request_valid = Signal(bool(0)) arp_request_ip = Signal(intbv(0)[32:]) + arp_response_ready = Signal(bool(0)) local_mac = Signal(intbv(0)[48:]) local_ip = Signal(intbv(0)[32:]) @@ -87,17 +90,18 @@ def bench(): output_eth_payload_tlast = Signal(bool(0)) output_eth_payload_tuser = Signal(bool(0)) + arp_request_ready = Signal(bool(0)) arp_response_valid = Signal(bool(0)) arp_response_error = Signal(bool(0)) arp_response_mac = Signal(intbv(0)[48:]) # sources and sinks - source_pause = Signal(bool(0)) - sink_pause = Signal(bool(0)) + eth_source_pause = Signal(bool(0)) + eth_sink_pause = Signal(bool(0)) - source = eth_ep.EthFrameSource() + eth_source = eth_ep.EthFrameSource() - source_logic = source.create_logic( + eth_source_logic = eth_source.create_logic( clk, rst, eth_hdr_ready=input_eth_hdr_ready, @@ -111,13 +115,13 @@ def bench(): eth_payload_tready=input_eth_payload_tready, eth_payload_tlast=input_eth_payload_tlast, eth_payload_tuser=input_eth_payload_tuser, - pause=source_pause, - name='source' + pause=eth_source_pause, + name='eth_source' ) - sink = eth_ep.EthFrameSink() + eth_sink = eth_ep.EthFrameSink() - sink_logic = sink.create_logic( + eth_sink_logic = eth_sink.create_logic( clk, rst, eth_hdr_ready=output_eth_hdr_ready, @@ -131,8 +135,30 @@ def bench(): eth_payload_tready=output_eth_payload_tready, eth_payload_tlast=output_eth_payload_tlast, eth_payload_tuser=output_eth_payload_tuser, - pause=sink_pause, - name='sink' + pause=eth_sink_pause, + name='eth_sink' + ) + + arp_request_source = axis_ep.AXIStreamSource() + + arp_request_source_logic = arp_request_source.create_logic( + clk, + rst, + tdata=(arp_request_ip,), + tvalid=arp_request_valid, + tready=arp_request_ready, + name='arp_request_source' + ) + + arp_response_sink = axis_ep.AXIStreamSink() + + arp_response_sink_logic = arp_response_sink.create_logic( + clk, + rst, + tdata=(arp_response_error, arp_response_mac), + tvalid=arp_response_valid, + tready=arp_response_ready, + name='arp_response_sink' ) # DUT @@ -170,8 +196,10 @@ def bench(): output_eth_payload_tuser=output_eth_payload_tuser, arp_request_valid=arp_request_valid, + arp_request_ready=arp_request_ready, arp_request_ip=arp_request_ip, arp_response_valid=arp_response_valid, + arp_response_ready=arp_response_ready, arp_response_error=arp_response_error, arp_response_mac=arp_response_mac, @@ -220,14 +248,13 @@ def bench(): test_frame.arp_spa = 0xc0a80164 test_frame.arp_tha = 0x000000000000 test_frame.arp_tpa = 0xc0a80165 - source.send(test_frame.build_eth()) + eth_source.send(test_frame.build_eth()) yield clk.posedge - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge + while eth_sink.empty(): + yield clk.posedge - rx_frame = sink.recv() + rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -250,15 +277,15 @@ def bench(): print("test 2: Cached read") current_test.next = 2 - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0xc0a80164 - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0xc0a80164,)]) - yield arp_response_valid.posedge - assert not bool(arp_response_error) - assert int(arp_response_mac) == 0x5A5152535455 + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert not err + assert mac == 0x5A5152535455 yield delay(100) @@ -266,18 +293,13 @@ def bench(): print("test 3: Unached read") current_test.next = 3 - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0xc0a80166 - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0xc0a80166,)]) # wait for ARP request packet - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge + while eth_sink.empty(): + yield clk.posedge - rx_frame = sink.recv() + rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -308,13 +330,17 @@ def bench(): test_frame.arp_spa = 0xc0a80166 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source.send(test_frame.build_eth()) + eth_source.send(test_frame.build_eth()) yield clk.posedge # wait for lookup - yield arp_response_valid.posedge - assert not bool(arp_response_error) - assert int(arp_response_mac) == 0x6A6162636465 + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert not err + assert mac == 0x6A6162636465 yield delay(100) @@ -322,18 +348,13 @@ def bench(): print("test 4: Unached read, outside of subnet") current_test.next = 4 - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0x08080808 - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0x08080808,)]) # wait for ARP request packet - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge + while eth_sink.empty(): + yield clk.posedge - rx_frame = sink.recv() + rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -364,13 +385,17 @@ def bench(): test_frame.arp_spa = 0xc0a80101 test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 - source.send(test_frame.build_eth()) + eth_source.send(test_frame.build_eth()) yield clk.posedge # wait for lookup - yield arp_response_valid.posedge - assert not bool(arp_response_error) - assert int(arp_response_mac) == 0xAABBCCDDEEFF + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert not err + assert mac == 0xAABBCCDDEEFF yield delay(100) @@ -378,20 +403,20 @@ def bench(): print("test 5: Unached read, timeout") current_test.next = 5 - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0xc0a80167 - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0xc0a80167,)]) - yield arp_response_valid.posedge - assert bool(arp_response_error) + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert err # check for 4 ARP requests - assert sink.count() == 4 + assert eth_sink.count() == 4 - while not sink.empty(): - rx_frame = sink.recv() + while not eth_sink.empty(): + rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -416,26 +441,26 @@ def bench(): current_test.next = 6 # subnet broadcast - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0xc0a801FF - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0xc0a801ff,)]) - yield arp_response_valid.posedge - assert not bool(arp_response_error) - assert int(arp_response_mac) == 0xFFFFFFFFFFFF + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert not err + assert mac == 0xffffffffffff # general broadcast - yield clk.posedge - arp_request_valid.next = True - arp_request_ip.next = 0xFFFFFFFF - yield clk.posedge - arp_request_valid.next = False + arp_request_source.send([(0xffffffff,)]) - yield arp_response_valid.posedge - assert not bool(arp_response_error) - assert int(arp_response_mac) == 0xFFFFFFFFFFFF + while arp_response_sink.empty(): + yield clk.posedge + + err, mac = arp_response_sink.recv().data[0] + + assert not err + assert mac == 0xffffffffffff yield delay(100) diff --git a/tb/test_arp_64.v b/tb/test_arp_64.v index aea5f3533..f1d79721a 100644 --- a/tb/test_arp_64.v +++ b/tb/test_arp_64.v @@ -51,6 +51,7 @@ reg output_eth_payload_tready = 0; reg arp_request_valid = 0; reg [31:0] arp_request_ip = 0; +reg arp_response_ready = 0; reg [47:0] local_mac = 0; reg [31:0] local_ip = 0; @@ -72,6 +73,7 @@ wire output_eth_payload_tvalid; wire output_eth_payload_tlast; wire output_eth_payload_tuser; +wire arp_request_ready; wire arp_response_valid; wire arp_response_error; wire [47:0] arp_response_mac; @@ -95,6 +97,7 @@ initial begin output_eth_payload_tready, arp_request_valid, arp_request_ip, + arp_response_ready, local_mac, local_ip, gateway_ip, @@ -113,6 +116,7 @@ initial begin output_eth_payload_tvalid, output_eth_payload_tlast, output_eth_payload_tuser, + arp_request_ready, arp_response_valid, arp_response_error, arp_response_mac @@ -158,8 +162,10 @@ UUT ( .output_eth_payload_tuser(output_eth_payload_tuser), // ARP requests .arp_request_valid(arp_request_valid), + .arp_request_ready(arp_request_ready), .arp_request_ip(arp_request_ip), .arp_response_valid(arp_response_valid), + .arp_response_ready(arp_response_ready), .arp_response_error(arp_response_error), .arp_response_mac(arp_response_mac), // Configuration diff --git a/tb/test_arp_cache.py b/tb/test_arp_cache.py index af268d44e..3fb8d527e 100755 --- a/tb/test_arp_cache.py +++ b/tb/test_arp_cache.py @@ -26,12 +26,15 @@ THE SOFTWARE. from myhdl import * import os +import axis_ep + module = 'arp_cache' testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) @@ -48,6 +51,8 @@ def bench(): query_request_valid = Signal(bool(0)) query_request_ip = Signal(intbv(0)[32:]) + query_response_ready = Signal(bool(0)) + write_request_valid = Signal(bool(0)) write_request_ip = Signal(intbv(0)[32:]) write_request_mac = Signal(intbv(0)[48:]) @@ -55,12 +60,55 @@ def bench(): clear_cache = Signal(bool(0)) # Outputs + query_request_ready = Signal(bool(0)) + query_response_valid = Signal(bool(0)) query_response_error = Signal(bool(0)) query_response_mac = Signal(intbv(0)[48:]) - write_in_progress = Signal(bool(0)) - write_complete = Signal(bool(0)) + write_request_ready = Signal(bool(0)) + + # sources and sinks + query_request_source_pause = Signal(bool(0)) + query_response_sink_pause = Signal(bool(0)) + write_request_source_pause = Signal(bool(0)) + + query_request_source = axis_ep.AXIStreamSource() + + query_request_source_logic = query_request_source.create_logic( + clk, + rst, + tdata=(query_request_ip,), + tvalid=query_request_valid, + tready=query_request_ready, + pause=query_request_source_pause, + name='query_request_source' + ) + + query_response_sink = axis_ep.AXIStreamSink() + + query_response_sink_logic = query_response_sink.create_logic( + clk, + rst, + tdata=(query_response_mac,), + tvalid=query_response_valid, + tready=query_response_ready, + tuser=query_response_error, + pause=query_response_sink_pause, + name='query_response_sink' + ) + + write_request_source = axis_ep.AXIStreamSource() + + write_request_source_logic = write_request_source.create_logic( + clk, + rst, + tdata=(write_request_ip, write_request_mac), + tvalid=write_request_valid, + tready=write_request_ready, + pause=write_request_source_pause, + name='write_request_source' + ) # DUT if os.system(build_cmd): @@ -73,16 +121,18 @@ def bench(): current_test=current_test, query_request_valid=query_request_valid, + query_request_ready=query_request_ready, query_request_ip=query_request_ip, + query_response_valid=query_response_valid, + query_response_ready=query_response_ready, query_response_error=query_response_error, query_response_mac=query_response_mac, write_request_valid=write_request_valid, + write_request_ready=write_request_ready, write_request_ip=write_request_ip, write_request_mac=write_request_mac, - write_in_progress=write_in_progress, - write_complete=write_complete, clear_cache=clear_cache ) @@ -107,24 +157,13 @@ def bench(): current_test.next = 1 yield clk.posedge - write_request_valid.next = True - write_request_ip.next = 0xc0a80111 - write_request_mac.next = 0x0000c0a80111 - yield clk.posedge - write_request_valid.next = False + write_request_source.send([(0xc0a80111, 0x0000c0a80111)]) + write_request_source.send([(0xc0a80112, 0x0000c0a80112)]) - yield write_complete.posedge - yield clk.posedge + yield delay(100) - yield clk.posedge - write_request_valid.next = True - write_request_ip.next = 0xc0a80112 - write_request_mac.next = 0x0000c0a80112 - yield clk.posedge - write_request_valid.next = False - - yield write_complete.posedge - yield clk.posedge + while not write_request_source.empty(): + yield clk.posedge yield delay(100) @@ -133,71 +172,47 @@ def bench(): current_test.next = 2 yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80111 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80111, )]) + query_request_source.send([(0xc0a80112, )]) + query_request_source.send([(0xc0a80113, )]) - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80111 + while query_response_sink.empty(): + yield clk.posedge - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80112 - yield clk.posedge - query_request_valid.next = False + resp = query_response_sink.recv() + assert resp.data[0][0] == 0x0000c0a80111 + assert not resp.user[0] - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80112 + while query_response_sink.empty(): + yield clk.posedge + + resp = query_response_sink.recv() + assert resp.data[0][0] == 0x0000c0a80112 + assert not resp.user[0] # not in cache; was not written - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80113 - yield clk.posedge - query_request_valid.next = False + while query_response_sink.empty(): + yield clk.posedge - yield query_response_valid.posedge - assert bool(query_response_error) + resp = query_response_sink.recv() + assert resp.user[0] yield delay(100) + raise StopSimulation + yield clk.posedge print("test 3: write more") current_test.next = 3 yield clk.posedge - write_request_valid.next = True - write_request_ip.next = 0xc0a80121 - write_request_mac.next = 0x0000c0a80121 - yield clk.posedge - write_request_valid.next = False - - yield write_complete.posedge - yield clk.posedge - - yield clk.posedge - write_request_valid.next = True - write_request_ip.next = 0xc0a80122 - write_request_mac.next = 0x0000c0a80122 - yield clk.posedge - write_request_valid.next = False - - yield write_complete.posedge - yield clk.posedge - + write_request_source.send([(0xc0a80121, 0x0000c0a80121)]) + write_request_source.send([(0xc0a80122, 0x0000c0a80122)]) # overwrites 0xc0a80121 due to LRU - yield clk.posedge - write_request_valid.next = True - write_request_ip.next = 0xc0a80123 - write_request_mac.next = 0x0000c0a80123 - yield clk.posedge - write_request_valid.next = False + write_request_source.send([(0xc0a80123, 0x0000c0a80123)]) - yield write_complete.posedge - yield clk.posedge + while not write_request_source.empty(): + yield clk.posedge yield delay(100) @@ -206,59 +221,61 @@ def bench(): current_test.next = 4 yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80111 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80111, )]) - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80111 + while query_response_sink.empty(): + yield clk.posedge + + resp = query_response_sink.recv() + assert resp.data[0][0] == 0x0000c0a80111 + assert not resp.user[0] yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80112 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80112, )]) - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80112 + while query_response_sink.empty(): + yield clk.posedge + + resp = query_response_sink.recv() + assert resp.data[0][0] == 0x0000c0a80112 + assert not resp.user[0] # not in cache; was overwritten yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80121 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80121, )]) - yield query_response_valid.posedge - assert bool(query_response_error) + while query_response_sink.empty(): + yield clk.posedge + + resp = query_response_sink.recv() + assert resp.user[0] yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80122 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80122, )]) - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80122 + while query_response_sink.empty(): + yield clk.posedge + + resp = query_response_sink.recv() + assert resp.data[0][0] == 0x0000c0a80122 + assert not resp.user[0] yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80123 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80123, )]) - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80123 + while query_response_sink.empty(): + yield clk.posedge + + resp = query_response_sink.recv() + assert resp.data[0][0] == 0x0000c0a80123 + assert not resp.user[0] # LRU reset by previous operation yield delay(100) + raise StopSimulation + yield clk.posedge print("test 5: LRU test") current_test.next = 5 diff --git a/tb/test_arp_cache.v b/tb/test_arp_cache.v index 8ee077d0c..ad0e8129c 100755 --- a/tb/test_arp_cache.v +++ b/tb/test_arp_cache.v @@ -39,6 +39,8 @@ reg [7:0] current_test = 0; reg query_request_valid = 0; reg [31:0] query_request_ip = 0; +reg query_response_ready = 0; + reg write_request_valid = 0; reg [31:0] write_request_ip = 0; reg [47:0] write_request_mac = 0; @@ -46,12 +48,13 @@ reg [47:0] write_request_mac = 0; reg clear_cache = 0; // Outputs +wire query_request_ready; + wire query_response_valid; wire query_response_error; wire [47:0] query_response_mac; -wire write_in_progress; -wire write_complete; +wire write_request_ready; initial begin // myhdl integration @@ -61,17 +64,18 @@ initial begin current_test, query_request_valid, query_request_ip, + query_response_ready, write_request_valid, write_request_ip, write_request_mac, clear_cache ); $to_myhdl( + query_request_ready, query_response_valid, query_response_error, query_response_mac, - write_in_progress, - write_complete + write_request_ready ); // dump file @@ -87,16 +91,17 @@ UUT ( .rst(rst), // Query cache .query_request_valid(query_request_valid), + .query_request_ready(query_request_ready), .query_request_ip(query_request_ip), .query_response_valid(query_response_valid), + .query_response_ready(query_response_ready), .query_response_error(query_response_error), .query_response_mac(query_response_mac), // Write cache .write_request_valid(write_request_valid), + .write_request_ready(write_request_ready), .write_request_ip(write_request_ip), .write_request_mac(write_request_mac), - .write_in_progress(write_in_progress), - .write_complete(write_complete), // Configuration .clear_cache(clear_cache) ); diff --git a/tb/test_ip.py b/tb/test_ip.py index fcfdd26f1..1fafbc96e 100755 --- a/tb/test_ip.py +++ b/tb/test_ip.py @@ -26,6 +26,7 @@ THE SOFTWARE. from myhdl import * import os +import axis_ep import eth_ep import ip_ep @@ -58,6 +59,7 @@ def bench(): input_eth_payload_tvalid = Signal(bool(0)) input_eth_payload_tlast = Signal(bool(0)) input_eth_payload_tuser = Signal(bool(0)) + arp_request_ready = Signal(bool(0)) arp_response_valid = Signal(bool(0)) arp_response_error = Signal(bool(0)) arp_response_mac = Signal(intbv(0)[48:]) @@ -93,6 +95,7 @@ def bench(): output_eth_payload_tuser = Signal(bool(0)) arp_request_valid = Signal(bool(0)) arp_request_ip = Signal(intbv(0)[32:]) + arp_response_ready = Signal(bool(0)) output_ip_hdr_valid = Signal(bool(0)) output_ip_eth_dest_mac = Signal(intbv(0)[48:]) output_ip_eth_src_mac = Signal(intbv(0)[48:]) @@ -224,6 +227,28 @@ def bench(): name='ip_sink' ) + arp_request_sink = axis_ep.AXIStreamSink() + + arp_request_sink_logic = arp_request_sink.create_logic( + clk, + rst, + tdata=(arp_request_ip,), + tvalid=arp_request_valid, + tready=arp_request_ready, + name='arp_request_sink' + ) + + arp_response_source = axis_ep.AXIStreamSource() + + arp_response_source_logic = arp_response_source.create_logic( + clk, + rst, + tdata=(arp_response_error, arp_response_mac), + tvalid=arp_response_valid, + tready=arp_response_ready, + name='arp_response_source' + ) + # DUT if os.system(build_cmd): raise Exception("Error running build command") @@ -257,8 +282,10 @@ def bench(): output_eth_payload_tuser=output_eth_payload_tuser, arp_request_valid=arp_request_valid, + arp_request_ready=arp_request_ready, arp_request_ip=arp_request_ip, arp_response_valid=arp_response_valid, + arp_response_ready=arp_response_ready, arp_response_error=arp_response_error, arp_response_mac=arp_response_mac, @@ -325,17 +352,13 @@ def bench(): while True: yield clk.posedge - arp_response_valid.next = 0 - arp_response_error.next = 0 - arp_response_mac.next = 0 + if not arp_request_sink.empty(): + req_ip = arp_request_sink.recv().data[0][0] - if arp_request_valid: - if int(arp_request_ip) in arp_table: - arp_response_valid.next = 1 - arp_response_mac.next = arp_table[int(arp_request_ip)] + if req_ip in arp_table: + arp_response_source.send([(0, arp_table[req_ip])]) else: - arp_response_valid.next = 1 - arp_response_error.next = 1 + arp_response_source.send([(1, 0)]) rx_error_header_early_termination_asserted = Signal(bool(0)) rx_error_payload_early_termination_asserted = Signal(bool(0)) diff --git a/tb/test_ip.v b/tb/test_ip.v index e1d967fce..cf29178ec 100644 --- a/tb/test_ip.v +++ b/tb/test_ip.v @@ -44,6 +44,7 @@ reg [7:0] input_eth_payload_tdata = 0; reg input_eth_payload_tvalid = 0; reg input_eth_payload_tlast = 0; reg input_eth_payload_tuser = 0; +reg arp_request_ready = 0; reg arp_response_valid = 0; reg arp_response_error = 0; reg [47:0] arp_response_mac = 0; @@ -81,6 +82,7 @@ wire output_eth_payload_tlast; wire output_eth_payload_tuser; wire arp_request_valid; wire [31:0] arp_request_ip; +wire arp_response_ready; wire output_ip_hdr_valid; wire [47:0] output_ip_eth_dest_mac; wire [47:0] output_ip_eth_src_mac; @@ -125,6 +127,7 @@ initial begin input_eth_payload_tvalid, input_eth_payload_tlast, input_eth_payload_tuser, + arp_request_ready, arp_response_valid, arp_response_error, arp_response_mac, @@ -162,6 +165,7 @@ initial begin output_eth_payload_tuser, arp_request_valid, arp_request_ip, + arp_response_ready, output_ip_hdr_valid, output_ip_eth_dest_mac, output_ip_eth_src_mac, @@ -226,8 +230,10 @@ UUT ( .output_eth_payload_tuser(output_eth_payload_tuser), // ARP requests .arp_request_valid(arp_request_valid), + .arp_request_ready(arp_request_ready), .arp_request_ip(arp_request_ip), .arp_response_valid(arp_response_valid), + .arp_response_ready(arp_response_ready), .arp_response_error(arp_response_error), .arp_response_mac(arp_response_mac), // IP frame input diff --git a/tb/test_ip_64.py b/tb/test_ip_64.py index a1e5299c0..c14b980f1 100755 --- a/tb/test_ip_64.py +++ b/tb/test_ip_64.py @@ -26,6 +26,7 @@ THE SOFTWARE. from myhdl import * import os +import axis_ep import eth_ep import ip_ep @@ -59,6 +60,7 @@ def bench(): input_eth_payload_tvalid = Signal(bool(0)) input_eth_payload_tlast = Signal(bool(0)) input_eth_payload_tuser = Signal(bool(0)) + arp_request_ready = Signal(bool(0)) arp_response_valid = Signal(bool(0)) arp_response_error = Signal(bool(0)) arp_response_mac = Signal(intbv(0)[48:]) @@ -96,6 +98,7 @@ def bench(): output_eth_payload_tuser = Signal(bool(0)) arp_request_valid = Signal(bool(0)) arp_request_ip = Signal(intbv(0)[32:]) + arp_response_ready = Signal(bool(0)) output_ip_hdr_valid = Signal(bool(0)) output_ip_eth_dest_mac = Signal(intbv(0)[48:]) output_ip_eth_src_mac = Signal(intbv(0)[48:]) @@ -232,6 +235,28 @@ def bench(): name='ip_sink' ) + arp_request_sink = axis_ep.AXIStreamSink() + + arp_request_sink_logic = arp_request_sink.create_logic( + clk, + rst, + tdata=(arp_request_ip,), + tvalid=arp_request_valid, + tready=arp_request_ready, + name='arp_request_sink' + ) + + arp_response_source = axis_ep.AXIStreamSource() + + arp_response_source_logic = arp_response_source.create_logic( + clk, + rst, + tdata=(arp_response_error, arp_response_mac), + tvalid=arp_response_valid, + tready=arp_response_ready, + name='arp_response_source' + ) + # DUT if os.system(build_cmd): raise Exception("Error running build command") @@ -267,8 +292,10 @@ def bench(): output_eth_payload_tuser=output_eth_payload_tuser, arp_request_valid=arp_request_valid, + arp_request_ready=arp_request_ready, arp_request_ip=arp_request_ip, arp_response_valid=arp_response_valid, + arp_response_ready=arp_response_ready, arp_response_error=arp_response_error, arp_response_mac=arp_response_mac, @@ -337,17 +364,13 @@ def bench(): while True: yield clk.posedge - arp_response_valid.next = 0 - arp_response_error.next = 0 - arp_response_mac.next = 0 + if not arp_request_sink.empty(): + req_ip = arp_request_sink.recv().data[0][0] - if arp_request_valid: - if int(arp_request_ip) in arp_table: - arp_response_valid.next = 1 - arp_response_mac.next = arp_table[int(arp_request_ip)] + if req_ip in arp_table: + arp_response_source.send([(0, arp_table[req_ip])]) else: - arp_response_valid.next = 1 - arp_response_error.next = 1 + arp_response_source.send([(1, 0)]) rx_error_header_early_termination_asserted = Signal(bool(0)) rx_error_payload_early_termination_asserted = Signal(bool(0)) diff --git a/tb/test_ip_64.v b/tb/test_ip_64.v index 17865bf8c..421bffdf8 100644 --- a/tb/test_ip_64.v +++ b/tb/test_ip_64.v @@ -44,6 +44,7 @@ reg [7:0] input_eth_payload_tkeep = 0; reg input_eth_payload_tvalid = 0; reg input_eth_payload_tlast = 0; reg input_eth_payload_tuser = 0; +reg arp_request_ready = 0; reg arp_response_valid = 0; reg arp_response_error = 0; reg [47:0] arp_response_mac = 0; @@ -83,6 +84,7 @@ wire output_eth_payload_tlast; wire output_eth_payload_tuser; wire arp_request_valid; wire [31:0] arp_request_ip; +wire arp_response_ready; wire output_ip_hdr_valid; wire [47:0] output_ip_eth_dest_mac; wire [47:0] output_ip_eth_src_mac; @@ -129,6 +131,7 @@ initial begin input_eth_payload_tvalid, input_eth_payload_tlast, input_eth_payload_tuser, + arp_request_ready, arp_response_valid, arp_response_error, arp_response_mac, @@ -168,6 +171,7 @@ initial begin output_eth_payload_tuser, arp_request_valid, arp_request_ip, + arp_response_ready, output_ip_hdr_valid, output_ip_eth_dest_mac, output_ip_eth_src_mac, @@ -235,8 +239,10 @@ UUT ( .output_eth_payload_tuser(output_eth_payload_tuser), // ARP requests .arp_request_valid(arp_request_valid), + .arp_request_ready(arp_request_ready), .arp_request_ip(arp_request_ip), .arp_response_valid(arp_response_valid), + .arp_response_ready(arp_response_ready), .arp_response_error(arp_response_error), .arp_response_mac(arp_response_mac), // IP frame input diff --git a/tb/test_ip_complete.py b/tb/test_ip_complete.py index 1a17adeb6..4362c0626 100755 --- a/tb/test_ip_complete.py +++ b/tb/test_ip_complete.py @@ -45,6 +45,7 @@ srcs.append("../rtl/arp_eth_rx.v") srcs.append("../rtl/arp_eth_tx.v") srcs.append("../rtl/eth_arb_mux_2.v") srcs.append("../rtl/eth_mux_2.v") +srcs.append("../rtl/lfsr.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") srcs.append("%s.v" % testbench) diff --git a/tb/test_ip_complete_64.py b/tb/test_ip_complete_64.py index 0923d7719..9f837b889 100755 --- a/tb/test_ip_complete_64.py +++ b/tb/test_ip_complete_64.py @@ -45,6 +45,7 @@ srcs.append("../rtl/arp_eth_rx_64.v") srcs.append("../rtl/arp_eth_tx_64.v") srcs.append("../rtl/eth_arb_mux_64_2.v") srcs.append("../rtl/eth_mux_64_2.v") +srcs.append("../rtl/lfsr.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") srcs.append("%s.v" % testbench) diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py index d5e880d77..e99fd8a71 100755 --- a/tb/test_udp_complete.py +++ b/tb/test_udp_complete.py @@ -53,6 +53,7 @@ srcs.append("../rtl/arp_eth_rx.v") srcs.append("../rtl/arp_eth_tx.v") srcs.append("../rtl/eth_arb_mux_2.v") srcs.append("../rtl/eth_mux_2.v") +srcs.append("../rtl/lfsr.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") srcs.append("../lib/axis/rtl/axis_fifo.v") @@ -525,13 +526,13 @@ def bench(): udp_tx_error_payload_early_termination_asserted.next = 1 def wait_normal(): - i = 16 + i = 20 while i > 0: i = max(0, i-1) if (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): - i = 16 + i = 20 yield clk.posedge @instance diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index 1c01361ca..c0af01476 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -53,6 +53,7 @@ srcs.append("../rtl/arp_eth_rx_64.v") srcs.append("../rtl/arp_eth_tx_64.v") srcs.append("../rtl/eth_arb_mux_64_2.v") srcs.append("../rtl/eth_mux_64_2.v") +srcs.append("../rtl/lfsr.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") srcs.append("../lib/axis/rtl/axis_fifo.v") @@ -543,13 +544,13 @@ def bench(): udp_tx_error_payload_early_termination_asserted.next = 1 def wait_normal(): - i = 16 + i = 20 while i > 0: i = max(0, i-1) if (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): - i = 16 + i = 20 yield clk.posedge @instance From cd51821bf7c54e84a30e03c4a77c555dbf667874 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 22 Jun 2018 18:56:05 -0700 Subject: [PATCH 393/617] Add parameters --- example/VCU108/fpga_10g/rtl/fpga_core.v | 12 ++++++++++-- example/VCU118/fpga_10g/rtl/fpga_core.v | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index daf9fe9d8..667ddabb4 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -486,7 +486,11 @@ eth_mac_1g_inst ( axis_adapter #( .INPUT_DATA_WIDTH(8), - .OUTPUT_DATA_WIDTH(64) + .OUTPUT_DATA_WIDTH(64), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) gig_rx_axis_adapter_inst ( .clk(clk), @@ -509,7 +513,11 @@ gig_rx_axis_adapter_inst ( axis_adapter #( .INPUT_DATA_WIDTH(64), - .OUTPUT_DATA_WIDTH(8) + .OUTPUT_DATA_WIDTH(8), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) gig_tx_axis_adapter_inst ( .clk(clk), diff --git a/example/VCU118/fpga_10g/rtl/fpga_core.v b/example/VCU118/fpga_10g/rtl/fpga_core.v index be0715979..ec0e84300 100644 --- a/example/VCU118/fpga_10g/rtl/fpga_core.v +++ b/example/VCU118/fpga_10g/rtl/fpga_core.v @@ -543,7 +543,11 @@ eth_mac_1g_inst ( axis_adapter #( .INPUT_DATA_WIDTH(8), - .OUTPUT_DATA_WIDTH(64) + .OUTPUT_DATA_WIDTH(64), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) gig_rx_axis_adapter_inst ( .clk(clk), @@ -566,7 +570,11 @@ gig_rx_axis_adapter_inst ( axis_adapter #( .INPUT_DATA_WIDTH(64), - .OUTPUT_DATA_WIDTH(8) + .OUTPUT_DATA_WIDTH(8), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) ) gig_tx_axis_adapter_inst ( .clk(clk), From 8982b4f4e1b11d3eedf0f95dbfbf07c5eb0a4f41 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 29 Jun 2018 13:00:41 -0700 Subject: [PATCH 394/617] Fix modsell pin --- example/VCU108/fpga_10g/fpga.xdc | 2 +- example/VCU108/fpga_10g/rtl/fpga.v | 4 ++-- example/VCU118/fpga_10g/fpga.xdc | 4 ++-- example/VCU118/fpga_10g/rtl/fpga.v | 8 ++++---- example/VCU118/fpga_1g/fpga.xdc | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/example/VCU108/fpga_10g/fpga.xdc b/example/VCU108/fpga_10g/fpga.xdc index be8bed33b..a289f96fe 100644 --- a/example/VCU108/fpga_10g/fpga.xdc +++ b/example/VCU108/fpga_10g/fpga.xdc @@ -99,7 +99,7 @@ set_property -dict {LOC AF39} [get_ports qsfp_mgt_refclk_0_n] ;# MGTREFCLK0N_127 #set_property -dict {LOC AD39} [get_ports qsfp_mgt_refclk_1_n] ;# MGTREFCLK1N_127 from U57 CKOUT2 SI5328 #set_property -dict {LOC AG34 IOSTANDARD LVDS} [get_ports qsfp_recclk_p] ;# to U57 CKIN1 SI5328 #set_property -dict {LOC AH35 IOSTANDARD LVDS} [get_ports qsfp_recclk_n] ;# to U57 CKIN1 SI5328 -set_property -dict {LOC AL24 IOSTANDARD LVCMOS18} [get_ports qsfp_modesell] +set_property -dict {LOC AL24 IOSTANDARD LVCMOS18} [get_ports qsfp_modsell] set_property -dict {LOC AM24 IOSTANDARD LVCMOS18} [get_ports qsfp_resetl] set_property -dict {LOC AL25 IOSTANDARD LVCMOS18} [get_ports qsfp_modprsl] set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp_intl] diff --git a/example/VCU108/fpga_10g/rtl/fpga.v b/example/VCU108/fpga_10g/rtl/fpga.v index e6d3d61a0..4aecc407b 100644 --- a/example/VCU108/fpga_10g/rtl/fpga.v +++ b/example/VCU108/fpga_10g/rtl/fpga.v @@ -80,7 +80,7 @@ module fpga ( // input wire qsfp_mgt_refclk_1_n, // output wire qsfp_recclk_p, // output wire qsfp_recclk_n, - output wire qsfp_modesell, + output wire qsfp_modsell, output wire qsfp_resetl, input wire qsfp_modprsl, input wire qsfp_intl, @@ -347,7 +347,7 @@ si570_i2c_master ( ); // XGMII 10G PHY -assign qsfp_modesell = 1'b1; +assign qsfp_modsell = 1'b0; assign qsfp_resetl = 1'b1; assign qsfp_lpmode = 1'b0; diff --git a/example/VCU118/fpga_10g/fpga.xdc b/example/VCU118/fpga_10g/fpga.xdc index a74495872..5f67fd2b1 100644 --- a/example/VCU118/fpga_10g/fpga.xdc +++ b/example/VCU118/fpga_10g/fpga.xdc @@ -105,7 +105,7 @@ set_property -dict {LOC W8 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_23 #set_property -dict {LOC U8 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U57.29 #set_property -dict {LOC AM23 IOSTANDARD LVDS} [get_ports qsfp1_recclk_p] ;# to U57.16 #set_property -dict {LOC AM22 IOSTANDARD LVDS} [get_ports qsfp1_recclk_n] ;# to U57.17 -set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modesell] +set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modsell] set_property -dict {LOC BA22 IOSTANDARD LVCMOS18} [get_ports qsfp1_resetl] set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modprsl] set_property -dict {LOC AP21 IOSTANDARD LVCMOS18} [get_ports qsfp1_intl] @@ -137,7 +137,7 @@ set_property -dict {LOC R8 } [get_ports qsfp2_mgt_refclk_0_n] ;# MGTREFCLK0N_23 #set_property -dict {LOC N8 } [get_ports qsfp2_mgt_refclk_1_n] ;# MGTREFCLK1N_232 from U57.34 #set_property -dict {LOC AP23 IOSTANDARD LVDS} [get_ports qsfp2_recclk_p] ;# to U57.12 #set_property -dict {LOC AP22 IOSTANDARD LVDS} [get_ports qsfp2_recclk_n] ;# to U57.13 -set_property -dict {LOC AN23 IOSTANDARD LVCMOS18} [get_ports qsfp2_modesell] +set_property -dict {LOC AN23 IOSTANDARD LVCMOS18} [get_ports qsfp2_modsell] set_property -dict {LOC AY22 IOSTANDARD LVCMOS18} [get_ports qsfp2_resetl] set_property -dict {LOC AN24 IOSTANDARD LVCMOS18} [get_ports qsfp2_modprsl] set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports qsfp2_intl] diff --git a/example/VCU118/fpga_10g/rtl/fpga.v b/example/VCU118/fpga_10g/rtl/fpga.v index a3897c49d..3d704efb3 100644 --- a/example/VCU118/fpga_10g/rtl/fpga.v +++ b/example/VCU118/fpga_10g/rtl/fpga.v @@ -80,7 +80,7 @@ module fpga ( // input wire qsfp1_mgt_refclk_1_n, // output wire qsfp1_recclk_p, // output wire qsfp1_recclk_n, - output wire qsfp1_modesell, + output wire qsfp1_modsell, output wire qsfp1_resetl, input wire qsfp1_modprsl, input wire qsfp1_intl, @@ -108,7 +108,7 @@ module fpga ( // input wire qsfp2_mgt_refclk_1_n, // output wire qsfp2_recclk_p, // output wire qsfp2_recclk_n, - output wire qsfp2_modesell, + output wire qsfp2_modsell, output wire qsfp2_resetl, input wire qsfp2_modprsl, input wire qsfp2_intl, @@ -294,7 +294,7 @@ assign i2c_sda_i = i2c_sda; assign i2c_sda = i2c_sda_t ? 1'bz : i2c_sda_o; // XGMII 10G PHY -assign qsfp1_modesell = 1'b1; +assign qsfp1_modsell = 1'b0; assign qsfp1_resetl = 1'b1; assign qsfp1_lpmode = 1'b0; @@ -331,7 +331,7 @@ wire qsfp1_rx_rst_4_int; wire [63:0] qsfp1_rxd_4_int; wire [7:0] qsfp1_rxc_4_int; -assign qsfp2_modesell = 1'b1; +assign qsfp2_modsell = 1'b0; assign qsfp2_resetl = 1'b1; assign qsfp2_lpmode = 1'b0; diff --git a/example/VCU118/fpga_1g/fpga.xdc b/example/VCU118/fpga_1g/fpga.xdc index e2f5f9c5b..d9297bb15 100644 --- a/example/VCU118/fpga_1g/fpga.xdc +++ b/example/VCU118/fpga_1g/fpga.xdc @@ -105,7 +105,7 @@ set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generat #set_property -dict {LOC U8 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U57.29 #set_property -dict {LOC AM23 IOSTANDARD LVDS} [get_ports qsfp1_recclk_p] ;# to U57.16 #set_property -dict {LOC AM22 IOSTANDARD LVDS} [get_ports qsfp1_recclk_n] ;# to U57.17 -#set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modesell] +#set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modsell] #set_property -dict {LOC BA22 IOSTANDARD LVCMOS18} [get_ports qsfp1_resetl] #set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modprsl] #set_property -dict {LOC AP21 IOSTANDARD LVCMOS18} [get_ports qsfp1_intl] @@ -137,7 +137,7 @@ set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generat #set_property -dict {LOC N8 } [get_ports qsfp2_mgt_refclk_1_n] ;# MGTREFCLK1N_232 from U57.34 #set_property -dict {LOC AP23 IOSTANDARD LVDS} [get_ports qsfp2_recclk_p] ;# to U57.12 #set_property -dict {LOC AP22 IOSTANDARD LVDS} [get_ports qsfp2_recclk_n] ;# to U57.13 -#set_property -dict {LOC AN23 IOSTANDARD LVCMOS18} [get_ports qsfp2_modesell] +#set_property -dict {LOC AN23 IOSTANDARD LVCMOS18} [get_ports qsfp2_modsell] #set_property -dict {LOC AY22 IOSTANDARD LVCMOS18} [get_ports qsfp2_resetl] #set_property -dict {LOC AN24 IOSTANDARD LVCMOS18} [get_ports qsfp2_modprsl] #set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports qsfp2_intl] From 2ebffeb223bc757a6c0b779ed0ff31e75072aaab Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 30 Jun 2018 00:21:02 -0700 Subject: [PATCH 395/617] Be more pythonic --- tb/axis_ep.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index de4528efb..7af4d378c 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -261,7 +261,7 @@ class AXIStreamSource(object): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue def create_logic(self, clk, @@ -376,12 +376,12 @@ class AXIStreamSink(object): self.read_queue = [] def recv(self): - if len(self.queue) > 0: + if self.queue: return self.queue.pop(0) return None def read(self, count=-1): - while len(self.queue) > 0: + while self.queue: self.read_queue.extend(self.queue.pop(0).data) if count < 0: count = len(self.read_queue) @@ -393,7 +393,7 @@ class AXIStreamSink(object): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue def create_logic(self, clk, From 268d011b893b48705ea0fac6f2a4aca40af79d31 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 30 Jun 2018 00:21:26 -0700 Subject: [PATCH 396/617] Add wait method to sink --- tb/axis_ep.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 7af4d378c..661743238 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -374,6 +374,7 @@ class AXIStreamSink(object): self.has_logic = False self.queue = [] self.read_queue = [] + self.sync = Signal(intbv(0)) def recv(self): if self.queue: @@ -395,6 +396,12 @@ class AXIStreamSink(object): def empty(self): return not self.queue + def wait(self, timeout=0): + if timeout: + yield self.sync, delay(timeout) + else: + yield self.sync + def create_logic(self, clk, rst, @@ -498,6 +505,7 @@ class AXIStreamSink(object): frame.WL = WL frame.parse(data, keep, id, dest, user) self.queue.append(frame) + self.sync.next = not self.sync if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) frame = AXIStreamFrame() From 63f9bbeced1df176d215affb00d9473bdf13636a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 2 Jul 2018 13:20:49 -0700 Subject: [PATCH 397/617] Update endpoints --- tb/arp_ep.py | 15 ++++++++++++--- tb/eth_ep.py | 23 +++++++++++++++-------- tb/gmii_ep.py | 14 +++++++++++--- tb/ip_ep.py | 16 ++++++++++++---- tb/udp_ep.py | 16 ++++++++++++---- tb/xgmii_ep.py | 14 +++++++++++--- 6 files changed, 73 insertions(+), 25 deletions(-) diff --git a/tb/arp_ep.py b/tb/arp_ep.py index 9e1eb576d..445e4ebf1 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -168,7 +168,7 @@ class ARPFrameSource(): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue def create_logic(self, clk, @@ -243,16 +243,24 @@ class ARPFrameSink(): def __init__(self): self.has_logic = False self.queue = [] + self.sync = Signal(intbv(0)) def recv(self): - if len(self.queue) > 0: + if self.queue: return self.queue.pop(0) + return None def count(self): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue + + def wait(self, timeout=0): + if timeout: + yield self.sync, delay(timeout) + else: + yield self.sync def create_logic(self, clk, @@ -312,6 +320,7 @@ class ARPFrameSink(): frame.arp_tha = int(arp_tha) frame.arp_tpa = int(arp_tpa) self.queue.append(frame) + self.sync.next = not self.sync if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) diff --git a/tb/eth_ep.py b/tb/eth_ep.py index 893989498..ede266172 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -133,7 +133,7 @@ class EthFrameSource(): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue def create_logic(self, clk, @@ -212,9 +212,11 @@ class EthFrameSink(): self.has_logic = False self.queue = [] self.payload_sink = axis_ep.AXIStreamSink() + self.header_queue = [] + self.sync = Signal(intbv(0)) def recv(self): - if len(self.queue) > 0: + if self.queue: return self.queue.pop(0) return None @@ -222,7 +224,13 @@ class EthFrameSink(): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue + + def wait(self, timeout=0): + if timeout: + yield self.sync, delay(timeout) + else: + yield self.sync def create_logic(self, clk, @@ -250,8 +258,6 @@ class EthFrameSink(): eth_hdr_valid_int = Signal(bool(False)) eth_payload_pause = Signal(bool(False)) - eth_header_queue = [] - eth_payload_sink = self.payload_sink.create_logic( clk=clk, rst=rst, @@ -285,12 +291,13 @@ class EthFrameSink(): frame.eth_dest_mac = int(eth_dest_mac) frame.eth_src_mac = int(eth_src_mac) frame.eth_type = int(eth_type) - eth_header_queue.append(frame) + self.header_queue.append(frame) - if not self.payload_sink.empty() and len(eth_header_queue) > 0: - frame = eth_header_queue.pop(0) + if not self.payload_sink.empty() and self.header_queue: + frame = self.header_queue.pop(0) frame.payload = self.payload_sink.recv() self.queue.append(frame) + self.sync.next = not self.sync if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index f7beca920..e53202f92 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -94,7 +94,7 @@ class GMIISource(object): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue def create_logic(self, clk, @@ -179,9 +179,10 @@ class GMIISink(object): def __init__(self): self.has_logic = False self.queue = [] + self.sync = Signal(intbv(0)) def recv(self): - if len(self.queue) > 0: + if self.queue: return self.queue.pop(0) return None @@ -189,7 +190,13 @@ class GMIISink(object): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue + + def wait(self, timeout=0): + if timeout: + yield self.sync, delay(timeout) + else: + yield self.sync def create_logic(self, clk, @@ -255,6 +262,7 @@ class GMIISink(object): er = er2 frame.parse(d, er) self.queue.append(frame) + self.sync.next = not self.sync if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) frame = None diff --git a/tb/ip_ep.py b/tb/ip_ep.py index 26937a9d5..fa21e5a16 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -256,7 +256,7 @@ class IPFrameSource(): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue def create_logic(self, clk, @@ -365,9 +365,10 @@ class IPFrameSink(): self.queue = [] self.payload_sink = axis_ep.AXIStreamSink() self.header_queue = [] + self.sync = Signal(intbv(0)) def recv(self): - if len(self.queue) > 0: + if self.queue: return self.queue.pop(0) return None @@ -375,7 +376,13 @@ class IPFrameSink(): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue + + def wait(self, timeout=0): + if timeout: + yield self.sync, delay(timeout) + else: + yield self.sync def create_logic(self, clk, @@ -464,10 +471,11 @@ class IPFrameSink(): frame.ip_dest_ip = int(ip_dest_ip) self.header_queue.append(frame) - if not self.payload_sink.empty() and len(self.header_queue) > 0: + if not self.payload_sink.empty() and self.header_queue: frame = self.header_queue.pop(0) frame.payload = self.payload_sink.recv() self.queue.append(frame) + self.sync.next = not self.sync if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) diff --git a/tb/udp_ep.py b/tb/udp_ep.py index 401e11317..868e01ca5 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -341,7 +341,7 @@ class UDPFrameSource(): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue def create_logic(self, clk, @@ -458,9 +458,10 @@ class UDPFrameSink(): self.queue = [] self.payload_sink = axis_ep.AXIStreamSink() self.header_queue = [] + self.sync = Signal(intbv(0)) def recv(self): - if len(self.queue) > 0: + if self.queue: return self.queue.pop(0) return None @@ -468,7 +469,13 @@ class UDPFrameSink(): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue + + def wait(self, timeout=0): + if timeout: + yield self.sync, delay(timeout) + else: + yield self.sync def create_logic(self, clk, @@ -566,10 +573,11 @@ class UDPFrameSink(): frame.udp_checksum = int(udp_checksum) self.header_queue.append(frame) - if not self.payload_sink.empty() and len(self.header_queue) > 0: + if not self.payload_sink.empty() and self.header_queue: frame = self.header_queue.pop(0) frame.payload = self.payload_sink.recv() self.queue.append(frame) + self.sync.next = not self.sync if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index ca657b158..813965a2c 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -115,7 +115,7 @@ class XGMIISource(object): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue def create_logic(self, clk, @@ -232,9 +232,10 @@ class XGMIISink(object): def __init__(self): self.has_logic = False self.queue = [] + self.sync = Signal(intbv(0)) def recv(self): - if len(self.queue) > 0: + if self.queue: return self.queue.pop(0) return None @@ -242,7 +243,13 @@ class XGMIISink(object): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue + + def wait(self, timeout=0): + if timeout: + yield self.sync, delay(timeout) + else: + yield self.sync def create_logic(self, clk, @@ -297,6 +304,7 @@ class XGMIISink(object): # terminate frame.parse(d, c) self.queue.append(frame) + self.sync.next = not self.sync if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) frame = None From 9390c3639b950e280256f6be70014ec50e56d408 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 2 Jul 2018 14:13:47 -0700 Subject: [PATCH 398/617] More endpoint updates --- tb/axis_ep.py | 4 +++- tb/ll_ep.py | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 661743238..351df0b49 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -344,7 +344,7 @@ class AXIStreamSource(object): tvalid_int.next = False tlast.next = False if (tlast and tready_int and tvalid) or not tvalid_int: - if len(self.queue) > 0: + if self.queue: frame = self.queue.pop(0) frame.B = B frame.N = N @@ -397,6 +397,8 @@ class AXIStreamSink(object): return not self.queue def wait(self, timeout=0): + if self.queue: + return if timeout: yield self.sync, delay(timeout) else: diff --git a/tb/ll_ep.py b/tb/ll_ep.py index c3e7e9aae..e009516d8 100644 --- a/tb/ll_ep.py +++ b/tb/ll_ep.py @@ -84,7 +84,7 @@ class LocalLinkSource(object): 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 len(self.queue) > 0: + if self.queue: frame = self.queue.pop(0) if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) @@ -100,9 +100,10 @@ class LocalLinkSink(object): def __init__(self): self.has_logic = False self.queue = [] + self.sync = Signal(intbv(0)) def recv(self): - if len(self.queue) > 0: + if self.queue: return self.queue.pop(0) return None @@ -110,7 +111,15 @@ class LocalLinkSink(object): return len(self.queue) def empty(self): - return self.count() == 0 + return not self.queue + + def wait(self, timeout=0): + if self.queue: + return + if timeout: + yield self.sync, delay(timeout) + else: + yield self.sync def create_logic(self, clk, @@ -154,6 +163,7 @@ class LocalLinkSink(object): frame.append(int(data_in)) if not eof_in_n: self.queue.append(frame) + self.sync.next = not self.sync if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) frame = [] From 3063bba54bf15eebc54262abd3c1c2cf3154e5b5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 2 Jul 2018 16:19:35 -0700 Subject: [PATCH 399/617] Update testbenches to use wait --- tb/test_axis_adapter_64_8.py | 17 ++--- tb/test_axis_adapter_8_64.py | 17 ++--- tb/test_axis_arb_mux_4.py | 49 +++++-------- tb/test_axis_arb_mux_4_64.py | 49 +++++-------- tb/test_axis_async_fifo.py | 47 +++---------- tb/test_axis_async_fifo_64.py | 47 +++---------- tb/test_axis_async_frame_fifo.py | 45 +++--------- tb/test_axis_async_frame_fifo_64.py | 45 +++--------- tb/test_axis_cobs_decode.py | 30 ++++---- tb/test_axis_cobs_encode.py | 14 ++-- tb/test_axis_cobs_encode_zero_frame.py | 14 ++-- tb/test_axis_crosspoint_4x4.py | 30 ++++---- tb/test_axis_crosspoint_4x4_64.py | 30 ++++---- tb/test_axis_demux_4.py | 34 +++------ tb/test_axis_demux_4_64.py | 34 +++------ tb/test_axis_fifo.py | 47 +++---------- tb/test_axis_fifo_64.py | 47 +++---------- tb/test_axis_frame_fifo.py | 41 +++-------- tb/test_axis_frame_fifo_64.py | 41 +++-------- tb/test_axis_frame_join_4.py | 42 +++-------- tb/test_axis_frame_length_adjust_64.py | 22 +++--- tb/test_axis_frame_length_adjust_8.py | 22 +++--- tb/test_axis_frame_length_adjust_fifo.py | 28 +++----- tb/test_axis_frame_length_adjust_fifo_64.py | 28 +++----- tb/test_axis_ll_bridge.py | 11 +-- tb/test_axis_mux_4.py | 34 +++------ tb/test_axis_mux_4_64.py | 34 +++------ tb/test_axis_rate_limit.py | 78 ++++++--------------- tb/test_axis_rate_limit_64.py | 78 ++++++--------------- tb/test_axis_register.py | 42 +++-------- tb/test_axis_register_64.py | 42 +++-------- tb/test_axis_srl_fifo.py | 47 +++---------- tb/test_axis_srl_fifo_64.py | 47 +++---------- tb/test_axis_srl_register.py | 42 +++-------- tb/test_axis_srl_register_64.py | 42 +++-------- tb/test_axis_switch_4x4.py | 28 +++++--- tb/test_axis_switch_4x4_64.py | 28 +++++--- tb/test_axis_tap.py | 47 +++---------- tb/test_axis_tap_64.py | 47 +++---------- tb/test_ll_axis_bridge.py | 11 +-- 40 files changed, 428 insertions(+), 1050 deletions(-) diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index 8319dd1c6..cba5c29b7 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -205,10 +205,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -246,14 +243,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -292,15 +287,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index 679e759e6..a51464b3b 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -205,10 +205,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -246,14 +243,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -292,15 +287,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index 9e56080c0..60e0cf2a8 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -282,13 +282,8 @@ def bench(): ) source_0.send(test_frame) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -309,13 +304,8 @@ def bench(): ) source_1.send(test_frame) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -345,17 +335,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -385,17 +371,13 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -440,13 +422,13 @@ def bench(): source_2_pause.next = False source_3_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -485,13 +467,13 @@ def bench(): yield clk.posedge sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -531,31 +513,32 @@ def bench(): yield clk.posedge source_1.send(test_frame1) - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_axis_arb_mux_4_64.py b/tb/test_axis_arb_mux_4_64.py index 5e9b85f01..0cf7c09f7 100755 --- a/tb/test_axis_arb_mux_4_64.py +++ b/tb/test_axis_arb_mux_4_64.py @@ -282,13 +282,8 @@ def bench(): ) source_0.send(test_frame) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -309,13 +304,8 @@ def bench(): ) source_1.send(test_frame) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -345,17 +335,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -385,17 +371,13 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -440,13 +422,13 @@ def bench(): source_2_pause.next = False source_3_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -485,13 +467,13 @@ def bench(): yield clk.posedge sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -531,31 +513,32 @@ def bench(): yield clk.posedge source_1.send(test_frame1) - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index f61e2137b..0947dd1a6 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -185,12 +185,8 @@ def bench(): ) source.send(test_frame) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -211,12 +207,8 @@ def bench(): ) source.send(test_frame) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -251,10 +243,7 @@ def bench(): yield output_clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -287,18 +276,13 @@ def bench(): test_frame2.dest = 2 source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -338,13 +322,12 @@ def bench(): source_pause.next = False yield input_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -384,13 +367,12 @@ def bench(): sink_pause.next = False yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -412,12 +394,8 @@ def bench(): ) source.send(test_frame) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -443,10 +421,7 @@ def bench(): yield input_clk.posedge sink_pause.next = 0 - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index 14be052a3..35bac2361 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -185,12 +185,8 @@ def bench(): ) source.send(test_frame) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -211,12 +207,8 @@ def bench(): ) source.send(test_frame) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -251,10 +243,7 @@ def bench(): yield output_clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -287,18 +276,13 @@ def bench(): test_frame2.dest = 2 source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -338,13 +322,12 @@ def bench(): source_pause.next = False yield input_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -384,13 +367,12 @@ def bench(): sink_pause.next = False yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -412,12 +394,8 @@ def bench(): ) source.send(test_frame) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -443,10 +421,7 @@ def bench(): yield input_clk.posedge sink_pause.next = 0 - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index dbd1ec2e9..90ea9fe6f 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -233,12 +233,8 @@ def bench(): output_status_good_frame_asserted.next = 0 source.send(test_frame) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -273,12 +269,8 @@ def bench(): output_status_good_frame_asserted.next = 0 source.send(test_frame) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -327,10 +319,7 @@ def bench(): yield output_clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -374,18 +363,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -439,17 +423,12 @@ def bench(): source_pause.next = False yield input_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - if output_axis_tvalid: - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -503,13 +482,12 @@ def bench(): sink_pause.next = False yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -614,10 +592,7 @@ def bench(): yield input_clk.posedge sink_pause.next = 0 - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index 886032143..a30818649 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -233,12 +233,8 @@ def bench(): output_status_good_frame_asserted.next = 0 source.send(test_frame) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -273,12 +269,8 @@ def bench(): output_status_good_frame_asserted.next = 0 source.send(test_frame) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -327,10 +319,7 @@ def bench(): yield output_clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -374,18 +363,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge - - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -439,17 +423,12 @@ def bench(): source_pause.next = False yield input_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - if output_axis_tvalid: - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -503,13 +482,12 @@ def bench(): sink_pause.next = False yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -614,10 +592,7 @@ def bench(): yield input_clk.posedge sink_pause.next = 0 - yield output_axis_tlast.posedge - yield output_clk.posedge - yield output_clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py index ceb92c787..ea2da0fdc 100755 --- a/tb/test_axis_cobs_decode.py +++ b/tb/test_axis_cobs_decode.py @@ -257,9 +257,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -285,9 +283,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -313,15 +309,14 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block assert not rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -345,15 +340,14 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block assert rx_frame.data == block assert not rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -383,17 +377,17 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -423,17 +417,17 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py index db2419eb4..da5b7eefd 100755 --- a/tb/test_axis_cobs_encode.py +++ b/tb/test_axis_cobs_encode.py @@ -257,9 +257,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -286,9 +284,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -296,6 +292,7 @@ def bench(): assert cobs_decode(rx_frame.data) == block assert not rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -324,14 +321,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(rx_frame.data) == None assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block diff --git a/tb/test_axis_cobs_encode_zero_frame.py b/tb/test_axis_cobs_encode_zero_frame.py index 5f1642b06..0fbc15422 100755 --- a/tb/test_axis_cobs_encode_zero_frame.py +++ b/tb/test_axis_cobs_encode_zero_frame.py @@ -258,9 +258,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -287,9 +285,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -297,6 +293,7 @@ def bench(): assert cobs_decode(rx_frame.data[:-1]) == block assert not rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block @@ -325,14 +322,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(rx_frame.data[:-1]) == None assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert cobs_decode(enc) == block diff --git a/tb/test_axis_crosspoint_4x4.py b/tb/test_axis_crosspoint_4x4.py index bb707b7d7..11df2c56e 100755 --- a/tb/test_axis_crosspoint_4x4.py +++ b/tb/test_axis_crosspoint_4x4.py @@ -369,25 +369,23 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) source_3.send(test_frame3) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -411,25 +409,23 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) source_3.send(test_frame3) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame3 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame2 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame1 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 @@ -447,25 +443,23 @@ def bench(): test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04', id=0, dest=0) source_0.send(test_frame0) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame0 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame0 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 diff --git a/tb/test_axis_crosspoint_4x4_64.py b/tb/test_axis_crosspoint_4x4_64.py index ba0b5068a..cf4c9dd46 100755 --- a/tb/test_axis_crosspoint_4x4_64.py +++ b/tb/test_axis_crosspoint_4x4_64.py @@ -369,25 +369,23 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) source_3.send(test_frame3) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -411,25 +409,23 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) source_3.send(test_frame3) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame3 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame2 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame1 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 @@ -447,25 +443,23 @@ def bench(): test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04', id=0, dest=0) source_0.send(test_frame0) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame0 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame0 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py index 3eb5ee55b..1c481a82b 100755 --- a/tb/test_axis_demux_4.py +++ b/tb/test_axis_demux_4.py @@ -288,13 +288,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - while input_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame @@ -317,13 +312,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - while input_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame @@ -355,17 +345,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - while input_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame1 + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame2 @@ -402,13 +388,13 @@ def bench(): while input_axis_tvalid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -450,13 +436,13 @@ def bench(): source_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -504,13 +490,13 @@ def bench(): sink_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 diff --git a/tb/test_axis_demux_4_64.py b/tb/test_axis_demux_4_64.py index 7b814a3b6..ea00eced1 100755 --- a/tb/test_axis_demux_4_64.py +++ b/tb/test_axis_demux_4_64.py @@ -288,13 +288,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - while input_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame @@ -317,13 +312,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - while input_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame @@ -355,17 +345,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - while input_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame1 + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame2 @@ -402,13 +388,13 @@ def bench(): while input_axis_tvalid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -450,13 +436,13 @@ def bench(): source_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -504,13 +490,13 @@ def bench(): sink_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index 9c20622af..72268f321 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -177,12 +177,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -203,12 +199,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -243,10 +235,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -276,18 +265,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -327,13 +311,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -373,13 +356,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -401,12 +383,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -432,10 +410,7 @@ def bench(): yield clk.posedge sink_pause.next = 0 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index f93e77fb4..b9c6ff572 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -177,12 +177,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -203,12 +199,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -243,10 +235,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -276,18 +265,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -327,13 +311,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -373,13 +356,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -401,12 +383,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -432,10 +410,7 @@ def bench(): yield clk.posedge sink_pause.next = 0 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index a1c429bb1..e10319e30 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -204,12 +204,8 @@ def bench(): good_frame_asserted.next = 0 source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -238,12 +234,8 @@ def bench(): good_frame_asserted.next = 0 source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -286,10 +278,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -327,18 +316,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -386,13 +370,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -440,13 +423,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -536,10 +518,7 @@ def bench(): yield clk.posedge sink_pause.next = 0 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index b7858b3d1..ef500a3c2 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -204,12 +204,8 @@ def bench(): good_frame_asserted.next = 0 source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -238,12 +234,8 @@ def bench(): good_frame_asserted.next = 0 source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -286,10 +278,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -327,18 +316,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -386,13 +370,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -440,13 +423,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -536,10 +518,7 @@ def bench(): yield clk.posedge sink_pause.next = 0 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index ee0d03f16..160999380 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -233,12 +233,8 @@ def bench(): source_1.send(test_frame_1) source_2.send(test_frame_2) source_3.send(test_frame_3) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data @@ -257,12 +253,8 @@ def bench(): source_1.send(test_frame_1) source_2.send(test_frame_2) source_3.send(test_frame_3) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data @@ -297,10 +289,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data @@ -327,18 +316,13 @@ def bench(): source_2.send(test_frame_2b) source_3.send(test_frame_3a) source_3.send(test_frame_3b) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data @@ -381,13 +365,12 @@ def bench(): source_3_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data @@ -424,13 +407,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data @@ -450,12 +432,8 @@ def bench(): source_1.send(test_frame_1) source_2.send(test_frame_2) source_3.send(test_frame_3) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data diff --git a/tb/test_axis_frame_length_adjust_64.py b/tb/test_axis_frame_length_adjust_64.py index cdef5a35b..d864a2910 100755 --- a/tb/test_axis_frame_length_adjust_64.py +++ b/tb/test_axis_frame_length_adjust_64.py @@ -234,10 +234,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -247,6 +244,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame.data[:lm] + yield status_sink.wait() status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) @@ -273,10 +271,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -286,12 +281,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] + yield status_sink.wait() status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -301,6 +298,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] + yield status_sink.wait() status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) @@ -329,10 +327,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -344,12 +339,14 @@ def bench(): assert rx_frame.last_cycle_user + yield status_sink.wait() status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -359,6 +356,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] + yield status_sink.wait() status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) diff --git a/tb/test_axis_frame_length_adjust_8.py b/tb/test_axis_frame_length_adjust_8.py index 4eccbb97d..86235c487 100755 --- a/tb/test_axis_frame_length_adjust_8.py +++ b/tb/test_axis_frame_length_adjust_8.py @@ -234,10 +234,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -247,6 +244,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame.data[:lm] + yield status_sink.wait() status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) @@ -273,10 +271,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -286,12 +281,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] + yield status_sink.wait() status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -301,6 +298,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] + yield status_sink.wait() status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) @@ -329,10 +327,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -344,12 +339,14 @@ def bench(): assert rx_frame.last_cycle_user + yield status_sink.wait() status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) assert status.data[0][2] == lrx assert status.data[0][3] == lt + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -359,6 +356,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] + yield status_sink.wait() status = status_sink.recv() assert status.data[0][0] == (lt < lmin) assert status.data[0][1] == (lt > lmax) diff --git a/tb/test_axis_frame_length_adjust_fifo.py b/tb/test_axis_frame_length_adjust_fifo.py index 8cb8d4a28..f01edada1 100755 --- a/tb/test_axis_frame_length_adjust_fifo.py +++ b/tb/test_axis_frame_length_adjust_fifo.py @@ -221,12 +221,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -236,6 +231,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame.data[:lm] + yield hdr_sink.wait() hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) @@ -262,12 +258,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -277,12 +268,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] + yield hdr_sink.wait() hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -292,6 +285,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] + yield hdr_sink.wait() hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) @@ -320,12 +314,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -335,6 +324,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] + yield hdr_sink.wait() hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) @@ -342,6 +332,7 @@ def bench(): assert hdr.data[0][3] == lt assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -351,6 +342,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] + yield hdr_sink.wait() hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) diff --git a/tb/test_axis_frame_length_adjust_fifo_64.py b/tb/test_axis_frame_length_adjust_fifo_64.py index 522c932ac..c816c0661 100755 --- a/tb/test_axis_frame_length_adjust_fifo_64.py +++ b/tb/test_axis_frame_length_adjust_fifo_64.py @@ -221,12 +221,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -236,6 +231,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame.data[:lm] + yield hdr_sink.wait() hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) @@ -262,12 +258,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -277,12 +268,14 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] + yield hdr_sink.wait() hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) assert hdr.data[0][2] == lrx assert hdr.data[0][3] == lt + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -292,6 +285,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] + yield hdr_sink.wait() hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) @@ -320,12 +314,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -335,6 +324,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame1.data[:lm] + yield hdr_sink.wait() hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) @@ -342,6 +332,7 @@ def bench(): assert hdr.data[0][3] == lt assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() lrx = len(rx_frame.data) @@ -351,6 +342,7 @@ def bench(): assert lrx <= lmax assert rx_frame.data[:lm] == test_frame2.data[:lm] + yield hdr_sink.wait() hdr = hdr_sink.recv() assert hdr.data[0][0] == (lt < lmin) assert hdr.data[0][1] == (lt > lmax) diff --git a/tb/test_axis_ll_bridge.py b/tb/test_axis_ll_bridge.py index d5f556bae..9b4989c46 100755 --- a/tb/test_axis_ll_bridge.py +++ b/tb/test_axis_ll_bridge.py @@ -143,12 +143,8 @@ def bench(): b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') source.send(test_frame) - yield clk.posedge - - yield ll_eof_out_n.negedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert bytearray(rx_frame) == test_frame @@ -181,10 +177,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield ll_eof_out_n.negedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert bytearray(rx_frame) == test_frame diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py index 8d15c2e86..04dbcb7f6 100755 --- a/tb/test_axis_mux_4.py +++ b/tb/test_axis_mux_4.py @@ -288,13 +288,8 @@ def bench(): ) source_0.send(test_frame) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -317,13 +312,8 @@ def bench(): ) source_1.send(test_frame) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -355,17 +345,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -402,13 +388,13 @@ def bench(): while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -456,13 +442,13 @@ def bench(): source_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -504,13 +490,13 @@ def bench(): sink_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_axis_mux_4_64.py b/tb/test_axis_mux_4_64.py index e3022f7a8..de7b1e01a 100755 --- a/tb/test_axis_mux_4_64.py +++ b/tb/test_axis_mux_4_64.py @@ -288,13 +288,8 @@ def bench(): ) source_0.send(test_frame) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -317,13 +312,8 @@ def bench(): ) source_1.send(test_frame) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -355,17 +345,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -402,13 +388,13 @@ def bench(): while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -456,13 +442,13 @@ def bench(): source_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -504,13 +490,13 @@ def bench(): sink_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index a566926ea..c8a6aeed4 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -222,14 +222,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -250,14 +244,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -292,12 +280,7 @@ def bench(): yield clk.posedge sink_pause.next = False - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -327,18 +310,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -378,16 +356,12 @@ def bench(): source_pause.next = False yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -427,16 +401,12 @@ def bench(): sink_pause.next = False yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -458,14 +428,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -482,6 +446,8 @@ def bench(): rate_num.next = rate[0] rate_denom.next = rate[1] + yield delay(100) + reset_stats.next = 1 yield clk.posedge start_time = now() @@ -501,21 +467,19 @@ def bench(): for f in test_frame: source.send(f) - yield clk.posedge - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - - stop_time = now() rx_frame = [] for i in range(len(lens)): - if not sink.empty(): - rx_frame.append(sink.recv()) + yield sink.wait() + rx_frame.append(sink.recv()) + + yield clk.posedge + + while not input_axis_tready: + yield clk.posedge + + stop_time = now() assert len(rx_frame) == len(test_frame) diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index 6c2205c4d..0a72785c0 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -222,14 +222,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -250,14 +244,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -292,12 +280,7 @@ def bench(): yield clk.posedge sink_pause.next = False - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -327,18 +310,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -378,16 +356,12 @@ def bench(): source_pause.next = False yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -427,16 +401,12 @@ def bench(): sink_pause.next = False yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -458,14 +428,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -482,6 +446,8 @@ def bench(): rate_num.next = rate[0] rate_denom.next = rate[1] + yield delay(100) + reset_stats.next = 1 yield clk.posedge start_time = now() @@ -501,21 +467,19 @@ def bench(): for f in test_frame: source.send(f) - yield clk.posedge - yield clk.posedge - - while input_axis_tvalid or output_axis_tvalid: - yield clk.posedge - while not input_axis_tready: - yield clk.posedge - - stop_time = now() rx_frame = [] for i in range(len(lens)): - if not sink.empty(): - rx_frame.append(sink.recv()) + yield sink.wait() + rx_frame.append(sink.recv()) + + yield clk.posedge + + while not input_axis_tready: + yield clk.posedge + + stop_time = now() assert len(rx_frame) == len(test_frame) diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py index c46eacdba..c470d4420 100755 --- a/tb/test_axis_register.py +++ b/tb/test_axis_register.py @@ -176,12 +176,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -202,12 +198,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -242,10 +234,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -275,18 +264,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -326,13 +310,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -372,13 +355,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -400,12 +382,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py index 5b03c0cf5..6f62fe0dc 100755 --- a/tb/test_axis_register_64.py +++ b/tb/test_axis_register_64.py @@ -176,12 +176,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -202,12 +198,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -242,10 +234,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -275,18 +264,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -326,13 +310,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -372,13 +355,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -400,12 +382,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py index 7ebd9bfa0..e9d5a7865 100755 --- a/tb/test_axis_srl_fifo.py +++ b/tb/test_axis_srl_fifo.py @@ -180,12 +180,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -205,12 +201,8 @@ def bench(): dest=1) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -245,10 +237,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -278,18 +267,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -329,13 +313,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -375,13 +358,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -403,12 +385,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -434,10 +412,7 @@ def bench(): yield clk.posedge sink_pause.next = 0 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py index 3b4b58b91..18d0929b6 100755 --- a/tb/test_axis_srl_fifo_64.py +++ b/tb/test_axis_srl_fifo_64.py @@ -180,12 +180,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -205,12 +201,8 @@ def bench(): dest=1) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -245,10 +237,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -278,18 +267,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -329,13 +313,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -375,13 +358,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -403,12 +385,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -434,10 +412,7 @@ def bench(): yield clk.posedge sink_pause.next = 0 - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_srl_register.py b/tb/test_axis_srl_register.py index 81c300655..3cb547840 100755 --- a/tb/test_axis_srl_register.py +++ b/tb/test_axis_srl_register.py @@ -176,12 +176,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -202,12 +198,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -242,10 +234,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -275,18 +264,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -326,13 +310,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -372,13 +355,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -400,12 +382,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_srl_register_64.py b/tb/test_axis_srl_register_64.py index 918f4bc8b..4122e72ea 100755 --- a/tb/test_axis_srl_register_64.py +++ b/tb/test_axis_srl_register_64.py @@ -176,12 +176,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -202,12 +198,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -242,10 +234,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -275,18 +264,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -326,13 +310,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -372,13 +355,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -400,12 +382,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py index a32d1f9b0..de44bf771 100755 --- a/tb/test_axis_switch_4x4.py +++ b/tb/test_axis_switch_4x4.py @@ -432,21 +432,23 @@ def bench(): yield clk.posedge yield wait() - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -471,21 +473,23 @@ def bench(): yield clk.posedge yield wait() - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame3 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame2 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame1 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 @@ -510,21 +514,23 @@ def bench(): yield clk.posedge yield wait() - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -549,21 +555,23 @@ def bench(): yield clk.posedge yield wait() - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_0.wait() rx_frame1 = sink_0.recv() assert rx_frame1 == test_frame1 + yield sink_0.wait() rx_frame2 = sink_0.recv() assert rx_frame2 == test_frame2 + yield sink_0.wait() rx_frame3 = sink_0.recv() assert rx_frame3 == test_frame3 @@ -588,13 +596,13 @@ def bench(): yield clk.posedge yield wait() - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 diff --git a/tb/test_axis_switch_4x4_64.py b/tb/test_axis_switch_4x4_64.py index 0c604f694..29baad888 100755 --- a/tb/test_axis_switch_4x4_64.py +++ b/tb/test_axis_switch_4x4_64.py @@ -432,21 +432,23 @@ def bench(): yield clk.posedge yield wait() - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -471,21 +473,23 @@ def bench(): yield clk.posedge yield wait() - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame3 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame2 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame1 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame0 @@ -510,21 +514,23 @@ def bench(): yield clk.posedge yield wait() - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 + yield sink_2.wait() rx_frame2 = sink_2.recv() assert rx_frame2 == test_frame2 + yield sink_3.wait() rx_frame3 = sink_3.recv() assert rx_frame3 == test_frame3 @@ -549,21 +555,23 @@ def bench(): yield clk.posedge yield wait() - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_0.wait() rx_frame1 = sink_0.recv() assert rx_frame1 == test_frame1 + yield sink_0.wait() rx_frame2 = sink_0.recv() assert rx_frame2 == test_frame2 + yield sink_0.wait() rx_frame3 = sink_0.recv() assert rx_frame3 == test_frame3 @@ -588,13 +596,13 @@ def bench(): yield clk.posedge yield wait() - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame0 = sink_0.recv() assert rx_frame0 == test_frame0 + yield sink_1.wait() rx_frame1 = sink_1.recv() assert rx_frame1 == test_frame1 diff --git a/tb/test_axis_tap.py b/tb/test_axis_tap.py index 4310dae85..5f7f94416 100755 --- a/tb/test_axis_tap.py +++ b/tb/test_axis_tap.py @@ -177,12 +177,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -203,12 +199,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -238,10 +230,7 @@ def bench(): yield clk.posedge source_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -271,10 +260,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.last_cycle_user @@ -304,18 +290,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -355,13 +336,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -401,13 +381,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert rx_frame.last_cycle_user @@ -429,12 +408,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_axis_tap_64.py b/tb/test_axis_tap_64.py index 343075498..9937d9c9e 100755 --- a/tb/test_axis_tap_64.py +++ b/tb/test_axis_tap_64.py @@ -177,12 +177,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -203,12 +199,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -238,10 +230,7 @@ def bench(): yield clk.posedge source_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -271,10 +260,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.last_cycle_user @@ -304,18 +290,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -355,13 +336,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -401,13 +381,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() assert rx_frame.last_cycle_user @@ -429,12 +408,8 @@ def bench(): ) source.send(test_frame) - yield clk.posedge - - yield output_axis_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame diff --git a/tb/test_ll_axis_bridge.py b/tb/test_ll_axis_bridge.py index 5c0a1995c..3bbd356bd 100755 --- a/tb/test_ll_axis_bridge.py +++ b/tb/test_ll_axis_bridge.py @@ -143,12 +143,8 @@ def bench(): b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10') source.send(test_frame) - yield clk.posedge - - yield axis_tlast.negedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert bytearray(rx_frame) == test_frame @@ -181,10 +177,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield axis_tlast.negedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert bytearray(rx_frame) == test_frame From ffc63e4b0d4acc4c5a6058c9df68e739082f98c4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 2 Jul 2018 16:25:29 -0700 Subject: [PATCH 400/617] Update readme --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 25ea2c7bc..5c031168e 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,15 @@ Supports power of two depths only. Basic frame-based asynchronous FIFO with parametrizable data width and depth. Supports power of two depths only. +### axis_cobs_decode + +Consistent Overhead Byte Stuffing (COBS) decoder. Fixed 8 bit width. + +### axis_cobs_encode + +Consistent Overhead Byte Stuffing (COBS) encoder. Fixed 8 bit width. +Configurable zero insertion. + ### axis_crosspoint module Basic crosspoint switch. tready signal not supported. Parametrizable data @@ -180,6 +189,8 @@ Parametrizable priority encoder. axis_arb_mux_4.v : 4 port arbitrated multiplexer axis_async_fifo.v : Asynchronous FIFO axis_async_frame_fifo.v : Asynchronous frame FIFO + axis_cobs_decode.v : COBS decoder + axis_cobs_encode.v : COBS encoder axis_crosspoint.py : Crosspoint switch generator axis_crosspoint_4x4.v : 4x4 crosspoint switch axis_demux.py : Demultiplexer generator From 65c64588a6f87faeabe89d37681e32d67fb72696 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 2 Jul 2018 16:33:13 -0700 Subject: [PATCH 401/617] More endpoint updates --- tb/arp_ep.py | 4 +++- tb/eth_ep.py | 22 +++++++++++++++++----- tb/gmii_ep.py | 4 +++- tb/ip_ep.py | 8 +++++--- tb/udp_ep.py | 8 +++++--- tb/xgmii_ep.py | 4 +++- 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/tb/arp_ep.py b/tb/arp_ep.py index 445e4ebf1..22a4197e4 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -216,7 +216,7 @@ class ARPFrameSource(): if frame_ready_int: frame_valid_int.next = False if (frame_ready_int and frame_valid) or not frame_valid_int: - if len(self.queue) > 0: + if self.queue: frame = self.queue.pop(0) eth_dest_mac.next = frame.eth_dest_mac eth_src_mac.next = frame.eth_src_mac @@ -257,6 +257,8 @@ class ARPFrameSink(): return not self.queue def wait(self, timeout=0): + if self.queue: + return if timeout: yield self.sync, delay(timeout) else: diff --git a/tb/eth_ep.py b/tb/eth_ep.py index ede266172..431c09958 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -125,9 +125,15 @@ class EthFrameSource(): self.has_logic = False self.queue = [] self.payload_source = axis_ep.AXIStreamSource() + self.header_queue = [] def send(self, frame): - self.queue.append(EthFrame(frame)) + frame = EthFrame(frame) + if not self.header_queue: + self.header_queue.append(frame) + self.payload_source.send(frame.payload) + else: + self.queue.append(frame) def count(self): return len(self.queue) @@ -191,19 +197,23 @@ class EthFrameSource(): else: if eth_hdr_ready_int: eth_hdr_valid_int.next = False - if (eth_payload_tlast and eth_hdr_ready_int and eth_hdr_valid) or not eth_hdr_valid_int: - if len(self.queue) > 0: - frame = self.queue.pop(0) + if (eth_hdr_ready_int and eth_hdr_valid) or not eth_hdr_valid_int: + if self.header_queue: + frame = self.header_queue.pop(0) eth_dest_mac.next = frame.eth_dest_mac eth_src_mac.next = frame.eth_src_mac eth_type.next = frame.eth_type - self.payload_source.send(frame.payload) if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) eth_hdr_valid_int.next = True + if self.queue and not self.header_queue: + frame = self.queue.pop(0) + self.header_queue.append(frame) + self.payload_source.send(frame.payload) + return instances() @@ -227,6 +237,8 @@ class EthFrameSink(): return not self.queue def wait(self, timeout=0): + if self.queue: + return if timeout: yield self.sync, delay(timeout) else: diff --git a/tb/gmii_ep.py b/tb/gmii_ep.py index e53202f92..e4ff42925 100644 --- a/tb/gmii_ep.py +++ b/tb/gmii_ep.py @@ -148,7 +148,7 @@ class GMIISource(object): ifg_cnt = 12*2 else: ifg_cnt = 12 - elif len(self.queue) > 0: + elif self.queue: frame = GMIIFrame(self.queue.pop(0)) d, er = frame.build() if name is not None: @@ -193,6 +193,8 @@ class GMIISink(object): return not self.queue def wait(self, timeout=0): + if self.queue: + return if timeout: yield self.sync, delay(timeout) else: diff --git a/tb/ip_ep.py b/tb/ip_ep.py index fa21e5a16..46b0e30ed 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -246,7 +246,7 @@ class IPFrameSource(): def send(self, frame): frame = IPFrame(frame) - if len(self.header_queue) == 0: + if not self.header_queue: self.header_queue.append(frame) self.payload_source.send(frame.payload) else: @@ -326,7 +326,7 @@ class IPFrameSource(): if ip_hdr_ready_int: ip_hdr_valid_int.next = False if (ip_hdr_ready_int and ip_hdr_valid) or not ip_hdr_valid_int: - if len(self.header_queue) > 0: + if self.header_queue: frame = self.header_queue.pop(0) frame.build() eth_dest_mac.next = frame.eth_dest_mac @@ -351,7 +351,7 @@ class IPFrameSource(): ip_hdr_valid_int.next = True - if len(self.queue) > 0 and len(self.header_queue) == 0: + if self.queue and not self.header_queue: frame = self.queue.pop(0) self.header_queue.append(frame) self.payload_source.send(frame.payload) @@ -379,6 +379,8 @@ class IPFrameSink(): return not self.queue def wait(self, timeout=0): + if self.queue: + return if timeout: yield self.sync, delay(timeout) else: diff --git a/tb/udp_ep.py b/tb/udp_ep.py index 868e01ca5..1edaaf3f4 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -331,7 +331,7 @@ class UDPFrameSource(): def send(self, frame): frame = UDPFrame(frame) - if len(self.header_queue) == 0: + if not self.header_queue: self.header_queue.append(frame) self.payload_source.send(frame.payload) else: @@ -415,7 +415,7 @@ class UDPFrameSource(): if udp_hdr_ready_int: udp_hdr_valid_int.next = False if (udp_hdr_ready_int and udp_hdr_valid) or not udp_hdr_valid_int: - if len(self.header_queue) > 0: + if self.header_queue: frame = self.header_queue.pop(0) frame.build() eth_dest_mac.next = frame.eth_dest_mac @@ -444,7 +444,7 @@ class UDPFrameSource(): udp_hdr_valid_int.next = True - if len(self.queue) > 0 and len(self.header_queue) == 0: + if self.queue and not self.header_queue: frame = self.queue.pop(0) self.header_queue.append(frame) self.payload_source.send(frame.payload) @@ -472,6 +472,8 @@ class UDPFrameSink(): return not self.queue def wait(self, timeout=0): + if self.queue: + return if timeout: yield self.sync, delay(timeout) else: diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 813965a2c..4c1b733ed 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -179,7 +179,7 @@ class XGMIISource(object): txd.next = d txc.next = c - elif len(self.queue) > 0: + elif self.queue: frame = self.queue.pop(0) dl, cl = frame.build() if name is not None: @@ -246,6 +246,8 @@ class XGMIISink(object): return not self.queue def wait(self, timeout=0): + if self.queue: + return if timeout: yield self.sync, delay(timeout) else: From 2e9602b5b42f3fb87643d11986dbd98f11fa451f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 2 Jul 2018 18:20:07 -0700 Subject: [PATCH 402/617] Update testbenches to use wait --- tb/test_arp.py | 39 +++--------- tb/test_arp_64.py | 39 +++--------- tb/test_arp_cache.py | 32 +++------- tb/test_arp_eth_rx.py | 36 +++-------- tb/test_arp_eth_rx_64.py | 36 +++-------- tb/test_arp_eth_tx.py | 25 ++------ tb/test_arp_eth_tx_64.py | 25 ++------ tb/test_axis_eth_fcs_check.py | 30 +++------ tb/test_axis_eth_fcs_check_64.py | 30 +++------ tb/test_axis_eth_fcs_insert.py | 22 ++----- tb/test_axis_eth_fcs_insert_64.py | 22 ++----- tb/test_axis_eth_fcs_insert_64_pad.py | 22 ++----- tb/test_axis_eth_fcs_insert_pad.py | 22 ++----- tb/test_axis_gmii_rx.py | 90 +++------------------------ tb/test_axis_gmii_tx.py | 62 ++---------------- tb/test_eth_arb_mux_4.py | 54 +++++----------- tb/test_eth_arb_mux_64_4.py | 54 +++++----------- tb/test_eth_axis_rx.py | 24 +++---- tb/test_eth_axis_rx_64.py | 24 +++---- tb/test_eth_axis_tx.py | 17 ++--- tb/test_eth_axis_tx_64.py | 17 ++--- tb/test_eth_demux_4.py | 34 +++------- tb/test_eth_demux_64_4.py | 34 +++------- tb/test_eth_mac_10g.py | 18 +----- tb/test_eth_mac_10g_fifo.py | 28 +-------- tb/test_eth_mac_10g_rx.py | 62 +++--------------- tb/test_eth_mac_10g_tx.py | 32 ++-------- tb/test_eth_mac_1g.py | 28 +-------- tb/test_eth_mac_1g_fifo.py | 31 +-------- tb/test_eth_mac_1g_gmii.py | 28 +-------- tb/test_eth_mac_1g_gmii_fifo.py | 30 +-------- tb/test_eth_mac_1g_rgmii.py | 28 +-------- tb/test_eth_mac_1g_rgmii_fifo.py | 34 +--------- tb/test_eth_mac_1g_rx.py | 62 +++--------------- tb/test_eth_mac_1g_tx.py | 32 ++-------- tb/test_eth_mux_4.py | 38 +++-------- tb/test_eth_mux_64_4.py | 38 +++-------- tb/test_ip.py | 18 +----- tb/test_ip_64.py | 18 +----- tb/test_ip_arb_mux_4.py | 54 +++++----------- tb/test_ip_arb_mux_64_4.py | 54 +++++----------- tb/test_ip_complete.py | 22 +------ tb/test_ip_complete_64.py | 22 +------ tb/test_ip_demux_4.py | 34 +++------- tb/test_ip_demux_64_4.py | 34 +++------- tb/test_ip_eth_rx.py | 74 +++++++--------------- tb/test_ip_eth_rx_64.py | 74 +++++++--------------- tb/test_ip_eth_tx.py | 53 +++++----------- tb/test_ip_eth_tx_64.py | 53 +++++----------- tb/test_ip_mux_4.py | 38 +++-------- tb/test_ip_mux_64_4.py | 38 +++-------- tb/test_udp.py | 28 +-------- tb/test_udp_64.py | 28 +-------- tb/test_udp_arb_mux_4.py | 54 +++++----------- tb/test_udp_arb_mux_64_4.py | 54 +++++----------- tb/test_udp_checksum_gen.py | 17 ++--- tb/test_udp_checksum_gen_64.py | 17 ++--- tb/test_udp_complete.py | 40 ++---------- tb/test_udp_complete_64.py | 40 ++---------- tb/test_udp_demux_4.py | 34 +++------- tb/test_udp_demux_64_4.py | 34 +++------- tb/test_udp_ip_rx.py | 60 ++++++------------ tb/test_udp_ip_rx_64.py | 60 ++++++------------ tb/test_udp_ip_tx.py | 53 +++++----------- tb/test_udp_ip_tx_64.py | 53 +++++----------- tb/test_udp_mux_4.py | 38 +++-------- tb/test_udp_mux_64_4.py | 38 +++-------- 67 files changed, 582 insertions(+), 1931 deletions(-) diff --git a/tb/test_arp.py b/tb/test_arp.py index e9fcd16d2..798b1cae9 100755 --- a/tb/test_arp.py +++ b/tb/test_arp.py @@ -243,11 +243,8 @@ def bench(): test_frame.arp_tha = 0x000000000000 test_frame.arp_tpa = 0xc0a80165 eth_source.send(test_frame.build_eth()) - yield clk.posedge - - while eth_sink.empty(): - yield clk.posedge + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -273,9 +270,7 @@ def bench(): arp_request_source.send([(0xc0a80164,)]) - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert not err @@ -290,9 +285,7 @@ def bench(): arp_request_source.send([(0xc0a80166,)]) # wait for ARP request packet - while eth_sink.empty(): - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -325,12 +318,9 @@ def bench(): test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 eth_source.send(test_frame.build_eth()) - yield clk.posedge # wait for lookup - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert not err @@ -345,9 +335,7 @@ def bench(): arp_request_source.send([(0x08080808,)]) # wait for ARP request packet - while eth_sink.empty(): - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -380,12 +368,9 @@ def bench(): test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 eth_source.send(test_frame.build_eth()) - yield clk.posedge # wait for lookup - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert not err @@ -399,9 +384,7 @@ def bench(): arp_request_source.send([(0xc0a80167,)]) - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert err @@ -437,9 +420,7 @@ def bench(): # subnet broadcast arp_request_source.send([(0xc0a801ff,)]) - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert not err @@ -448,9 +429,7 @@ def bench(): # general broadcast arp_request_source.send([(0xffffffff,)]) - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert not err diff --git a/tb/test_arp_64.py b/tb/test_arp_64.py index 0f7992b4b..01d964cf5 100755 --- a/tb/test_arp_64.py +++ b/tb/test_arp_64.py @@ -249,11 +249,8 @@ def bench(): test_frame.arp_tha = 0x000000000000 test_frame.arp_tpa = 0xc0a80165 eth_source.send(test_frame.build_eth()) - yield clk.posedge - - while eth_sink.empty(): - yield clk.posedge + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -279,9 +276,7 @@ def bench(): arp_request_source.send([(0xc0a80164,)]) - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert not err @@ -296,9 +291,7 @@ def bench(): arp_request_source.send([(0xc0a80166,)]) # wait for ARP request packet - while eth_sink.empty(): - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -331,12 +324,9 @@ def bench(): test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 eth_source.send(test_frame.build_eth()) - yield clk.posedge # wait for lookup - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert not err @@ -351,9 +341,7 @@ def bench(): arp_request_source.send([(0x08080808,)]) # wait for ARP request packet - while eth_sink.empty(): - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -386,12 +374,9 @@ def bench(): test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 eth_source.send(test_frame.build_eth()) - yield clk.posedge # wait for lookup - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert not err @@ -405,9 +390,7 @@ def bench(): arp_request_source.send([(0xc0a80167,)]) - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert err @@ -443,9 +426,7 @@ def bench(): # subnet broadcast arp_request_source.send([(0xc0a801ff,)]) - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert not err @@ -454,9 +435,7 @@ def bench(): # general broadcast arp_request_source.send([(0xffffffff,)]) - while arp_response_sink.empty(): - yield clk.posedge - + yield arp_response_sink.wait() err, mac = arp_response_sink.recv().data[0] assert not err diff --git a/tb/test_arp_cache.py b/tb/test_arp_cache.py index 3fb8d527e..a576facda 100755 --- a/tb/test_arp_cache.py +++ b/tb/test_arp_cache.py @@ -176,24 +176,18 @@ def bench(): query_request_source.send([(0xc0a80112, )]) query_request_source.send([(0xc0a80113, )]) - while query_response_sink.empty(): - yield clk.posedge - + yield query_response_sink.wait() resp = query_response_sink.recv() assert resp.data[0][0] == 0x0000c0a80111 assert not resp.user[0] - while query_response_sink.empty(): - yield clk.posedge - + yield query_response_sink.wait() resp = query_response_sink.recv() assert resp.data[0][0] == 0x0000c0a80112 assert not resp.user[0] # not in cache; was not written - while query_response_sink.empty(): - yield clk.posedge - + yield query_response_sink.wait() resp = query_response_sink.recv() assert resp.user[0] @@ -223,9 +217,7 @@ def bench(): yield clk.posedge query_request_source.send([(0xc0a80111, )]) - while query_response_sink.empty(): - yield clk.posedge - + yield query_response_sink.wait() resp = query_response_sink.recv() assert resp.data[0][0] == 0x0000c0a80111 assert not resp.user[0] @@ -233,9 +225,7 @@ def bench(): yield clk.posedge query_request_source.send([(0xc0a80112, )]) - while query_response_sink.empty(): - yield clk.posedge - + yield query_response_sink.wait() resp = query_response_sink.recv() assert resp.data[0][0] == 0x0000c0a80112 assert not resp.user[0] @@ -244,18 +234,14 @@ def bench(): yield clk.posedge query_request_source.send([(0xc0a80121, )]) - while query_response_sink.empty(): - yield clk.posedge - + yield query_response_sink.wait() resp = query_response_sink.recv() assert resp.user[0] yield clk.posedge query_request_source.send([(0xc0a80122, )]) - while query_response_sink.empty(): - yield clk.posedge - + yield query_response_sink.wait() resp = query_response_sink.recv() assert resp.data[0][0] == 0x0000c0a80122 assert not resp.user[0] @@ -263,9 +249,7 @@ def bench(): yield clk.posedge query_request_source.send([(0xc0a80123, )]) - while query_response_sink.empty(): - yield clk.posedge - + yield query_response_sink.wait() resp = query_response_sink.recv() assert resp.data[0][0] == 0x0000c0a80123 assert not resp.user[0] diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index 5641166c1..e0d8c02a8 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -200,12 +200,8 @@ def bench(): test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 source.send(test_frame.build_eth()) - yield clk.posedge - - yield output_frame_valid.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -232,12 +228,8 @@ def bench(): eth_frame = test_frame.build_eth() eth_frame.payload.data += bytearray(range(10)) source.send(eth_frame) - yield clk.posedge - - yield output_frame_valid.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -278,10 +270,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_frame_valid.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -320,18 +309,13 @@ def bench(): test_frame2.arp_tpa = 0xc0a80165 source.send(test_frame1.build_eth()) source.send(test_frame2.build_eth()) - yield clk.posedge - - yield output_frame_valid.posedge - yield clk.posedge - yield output_frame_valid.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -381,13 +365,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -437,13 +420,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index 97bc0ea0d..17e5ec51e 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -203,12 +203,8 @@ def bench(): test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 source.send(test_frame.build_eth()) - yield clk.posedge - - yield output_frame_valid.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -235,12 +231,8 @@ def bench(): eth_frame = test_frame.build_eth() eth_frame.payload.data += bytearray(range(10)) source.send(eth_frame) - yield clk.posedge - - yield output_frame_valid.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -281,10 +273,7 @@ def bench(): yield clk.posedge sink_pause.next = False - #yield output_frame_valid.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -323,18 +312,13 @@ def bench(): test_frame2.arp_tpa = 0xc0a80165 source.send(test_frame1.build_eth()) source.send(test_frame2.build_eth()) - yield clk.posedge - - yield output_frame_valid.posedge - yield clk.posedge - yield output_frame_valid.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -384,13 +368,12 @@ def bench(): source_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -440,13 +423,12 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py index e8751f946..ddf0a8504 100755 --- a/tb/test_arp_eth_tx.py +++ b/tb/test_arp_eth_tx.py @@ -188,12 +188,8 @@ def bench(): test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 source.send(test_frame) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() @@ -229,10 +225,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() @@ -273,20 +266,15 @@ def bench(): test_frame2.arp_tpa = 0xc0a80165 source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() @@ -338,15 +326,14 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py index c8c9a6926..c26fbae2f 100755 --- a/tb/test_arp_eth_tx_64.py +++ b/tb/test_arp_eth_tx_64.py @@ -191,12 +191,8 @@ def bench(): test_frame.arp_tha = 0xDAD1D2D3D4D5 test_frame.arp_tpa = 0xc0a80165 source.send(test_frame) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() @@ -232,10 +228,7 @@ def bench(): yield clk.posedge sink_pause.next = False - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() @@ -276,20 +269,15 @@ def bench(): test_frame2.arp_tpa = 0xc0a80165 source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield output_eth_payload_tlast.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() @@ -341,15 +329,14 @@ def bench(): sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = arp_ep.ARPFrame() diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index a45f05576..6fac8ebbb 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -194,10 +194,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -239,10 +236,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -252,6 +246,7 @@ def bench(): assert eth_frame == test_frame1 assert not rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -295,14 +290,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -348,16 +341,14 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_bad_fcs_asserted - rx_frame = sink.recv() - assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -387,10 +378,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert test_frame == bytearray(rx_frame) diff --git a/tb/test_axis_eth_fcs_check_64.py b/tb/test_axis_eth_fcs_check_64.py index 9a0e684c6..f05d1d677 100755 --- a/tb/test_axis_eth_fcs_check_64.py +++ b/tb/test_axis_eth_fcs_check_64.py @@ -200,10 +200,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -245,10 +242,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -258,6 +252,7 @@ def bench(): assert eth_frame == test_frame1 assert not rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -301,14 +296,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -354,16 +347,14 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_bad_fcs_asserted - rx_frame = sink.recv() - assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -393,10 +384,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert test_frame == bytearray(rx_frame) diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index 139c14144..566f184b2 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -186,10 +186,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -237,10 +234,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -256,6 +250,7 @@ def bench(): assert eth_frame.eth_type == test_frame1.eth_type assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -305,14 +300,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -346,10 +339,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() payload = rx_frame.data[:-4] diff --git a/tb/test_axis_eth_fcs_insert_64.py b/tb/test_axis_eth_fcs_insert_64.py index 69abd9d89..6b81a516a 100755 --- a/tb/test_axis_eth_fcs_insert_64.py +++ b/tb/test_axis_eth_fcs_insert_64.py @@ -192,10 +192,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -243,10 +240,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -262,6 +256,7 @@ def bench(): assert eth_frame.eth_type == test_frame1.eth_type assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -311,14 +306,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -352,10 +345,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() payload = rx_frame.data[:-4] diff --git a/tb/test_axis_eth_fcs_insert_64_pad.py b/tb/test_axis_eth_fcs_insert_64_pad.py index 84ce34065..9b7a95ddb 100755 --- a/tb/test_axis_eth_fcs_insert_64_pad.py +++ b/tb/test_axis_eth_fcs_insert_64_pad.py @@ -192,10 +192,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -243,10 +240,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -262,6 +256,7 @@ def bench(): assert eth_frame.eth_type == test_frame1.eth_type assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -311,14 +306,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -352,10 +345,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() payload = rx_frame.data[:-4] diff --git a/tb/test_axis_eth_fcs_insert_pad.py b/tb/test_axis_eth_fcs_insert_pad.py index aa2123e6e..fe753d57c 100755 --- a/tb/test_axis_eth_fcs_insert_pad.py +++ b/tb/test_axis_eth_fcs_insert_pad.py @@ -186,10 +186,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -237,10 +234,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -256,6 +250,7 @@ def bench(): assert eth_frame.eth_type == test_frame1.eth_type assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -305,14 +300,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -346,10 +339,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() payload = rx_frame.data[:-4] diff --git a/tb/test_axis_gmii_rx.py b/tb/test_axis_gmii_rx.py index a94e57df6..ccf9f9d33 100755 --- a/tb/test_axis_gmii_rx.py +++ b/tb/test_axis_gmii_rx.py @@ -180,20 +180,8 @@ def bench(): gmii_frame = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) source.send(gmii_frame) - yield clk.posedge - yield clk.posedge - - while not clk_enable or not gmii_rx_dv: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_rx_dv or output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -230,29 +218,8 @@ def bench(): source.send(gmii_frame1) source.send(gmii_frame2) - yield clk.posedge - yield clk.posedge - - while not clk_enable or not gmii_rx_dv: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_rx_dv or output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - - while not clk_enable or not gmii_rx_dv: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_rx_dv or output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -261,6 +228,7 @@ def bench(): assert eth_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -303,36 +271,16 @@ def bench(): source.send(gmii_frame1) source.send(gmii_frame2) - yield clk.posedge - yield clk.posedge - while not clk_enable or not gmii_rx_dv: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_rx_dv or output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - - while not clk_enable or not gmii_rx_dv: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_rx_dv or output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_bad_frame_asserted assert error_bad_fcs_asserted - rx_frame = sink.recv() - assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -375,36 +323,16 @@ def bench(): source.send(gmii_frame1) source.send(gmii_frame2) - yield clk.posedge - yield clk.posedge - while not clk_enable or not gmii_rx_dv: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_rx_dv or output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - - while not clk_enable or not gmii_rx_dv: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_rx_dv or output_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_bad_frame_asserted assert not error_bad_fcs_asserted - rx_frame = sink.recv() - assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() diff --git a/tb/test_axis_gmii_tx.py b/tb/test_axis_gmii_tx.py index dc3c064f7..562403b68 100755 --- a/tb/test_axis_gmii_tx.py +++ b/tb/test_axis_gmii_tx.py @@ -176,20 +176,8 @@ def bench(): axis_frame = test_frame.build_axis() source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - while not clk_enable: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_tx_en or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -233,29 +221,8 @@ def bench(): source.send(axis_frame1) source.send(axis_frame2) - yield clk.posedge - yield clk.posedge - - while not clk_enable: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_tx_en or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - - while not clk_enable: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_tx_en or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -273,6 +240,7 @@ def bench(): assert eth_frame.eth_type == test_frame1.eth_type assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -318,29 +286,8 @@ def bench(): source.send(axis_frame1) source.send(axis_frame2) - yield clk.posedge - yield clk.posedge - - while not clk_enable: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_tx_en or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - - while not clk_enable: - yield clk.posedge - yield clk.posedge - - while not clk_enable or gmii_tx_en or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -348,6 +295,7 @@ def bench(): # bad packet + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_arb_mux_4.py b/tb/test_eth_arb_mux_4.py index f8bf12aa9..55f2308e8 100755 --- a/tb/test_eth_arb_mux_4.py +++ b/tb/test_eth_arb_mux_4.py @@ -298,14 +298,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -323,14 +317,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -354,18 +342,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -389,18 +372,13 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -440,13 +418,13 @@ def bench(): source_2_pause.next = False source_3_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -480,14 +458,13 @@ def bench(): yield clk.posedge sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -521,31 +498,32 @@ def bench(): yield clk.posedge source_1.send(test_frame1) - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_eth_arb_mux_64_4.py b/tb/test_eth_arb_mux_64_4.py index ded2000ae..e90d9208c 100755 --- a/tb/test_eth_arb_mux_64_4.py +++ b/tb/test_eth_arb_mux_64_4.py @@ -313,14 +313,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -338,14 +332,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -369,18 +357,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -404,18 +387,13 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -455,13 +433,13 @@ def bench(): source_2_pause.next = False source_3_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -495,14 +473,13 @@ def bench(): yield clk.posedge sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -536,31 +513,32 @@ def bench(): yield clk.posedge source_1.send(test_frame1) - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index a6af9d50e..0667e16eb 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -200,10 +200,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -238,14 +235,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -282,15 +277,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -330,14 +323,11 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_header_early_termination_asserted - rx_frame = sink.recv() - assert rx_frame == test_frame2 assert sink.empty() diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index 5eccee574..32439a894 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -206,10 +206,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -244,14 +241,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -288,15 +283,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -336,14 +329,11 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_header_early_termination_asserted - rx_frame = sink.recv() - assert rx_frame == test_frame2 assert sink.empty() diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py index 254f7ef1f..6e26d459a 100755 --- a/tb/test_eth_axis_tx.py +++ b/tb/test_eth_axis_tx.py @@ -189,10 +189,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = eth_ep.EthFrame() @@ -227,10 +224,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = eth_ep.EthFrame() @@ -238,6 +232,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = eth_ep.EthFrame() @@ -274,10 +269,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = eth_ep.EthFrame() @@ -286,6 +278,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = eth_ep.EthFrame() diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py index 332c626d8..8a366edd6 100755 --- a/tb/test_eth_axis_tx_64.py +++ b/tb/test_eth_axis_tx_64.py @@ -195,10 +195,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = eth_ep.EthFrame() @@ -233,10 +230,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = eth_ep.EthFrame() @@ -244,6 +238,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = eth_ep.EthFrame() @@ -280,10 +275,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = eth_ep.EthFrame() @@ -292,6 +284,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = eth_ep.EthFrame() diff --git a/tb/test_eth_demux_4.py b/tb/test_eth_demux_4.py index 36915abbd..7a0f10777 100755 --- a/tb/test_eth_demux_4.py +++ b/tb/test_eth_demux_4.py @@ -304,13 +304,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source.send(test_frame) - yield clk.posedge - - while input_eth_payload_tvalid or input_eth_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame @@ -330,13 +325,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source.send(test_frame) - yield clk.posedge - - while input_eth_payload_tvalid or input_eth_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame @@ -362,17 +352,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - while input_eth_payload_tvalid or input_eth_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame1 + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame2 @@ -403,13 +389,13 @@ def bench(): while input_eth_payload_tvalid or input_eth_hdr_valid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -445,13 +431,13 @@ def bench(): source_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -493,13 +479,13 @@ def bench(): sink_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 diff --git a/tb/test_eth_demux_64_4.py b/tb/test_eth_demux_64_4.py index 19f446f1c..67f57315c 100755 --- a/tb/test_eth_demux_64_4.py +++ b/tb/test_eth_demux_64_4.py @@ -319,13 +319,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source.send(test_frame) - yield clk.posedge - - while input_eth_payload_tvalid or input_eth_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame @@ -345,13 +340,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source.send(test_frame) - yield clk.posedge - - while input_eth_payload_tvalid or input_eth_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame @@ -377,17 +367,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - while input_eth_payload_tvalid or input_eth_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame1 + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame2 @@ -418,13 +404,13 @@ def bench(): while input_eth_payload_tvalid or input_eth_hdr_valid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -460,13 +446,13 @@ def bench(): source_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -508,13 +494,13 @@ def bench(): sink_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 diff --git a/tb/test_eth_mac_10g.py b/tb/test_eth_mac_10g.py index bda37312c..5b35f3473 100755 --- a/tb/test_eth_mac_10g.py +++ b/tb/test_eth_mac_10g.py @@ -212,15 +212,8 @@ def bench(): axis_frame = test_frame.build_axis_fcs() xgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield clk.posedge - yield clk.posedge - - while xgmii_rxc != 0xff or rx_axis_tvalid or not xgmii_source.empty(): - yield clk.posedge - - yield clk.posedge - yield clk.posedge + yield axis_sink.wait() rx_frame = axis_sink.recv() eth_frame = eth_ep.EthFrame() @@ -245,15 +238,8 @@ def bench(): axis_frame = test_frame.build_axis() axis_source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - while xgmii_txc != 0xff or tx_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge + yield xgmii_sink.wait() rx_frame = xgmii_sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_mac_10g_fifo.py b/tb/test_eth_mac_10g_fifo.py index 0194e818d..7df185730 100755 --- a/tb/test_eth_mac_10g_fifo.py +++ b/tb/test_eth_mac_10g_fifo.py @@ -240,20 +240,8 @@ def bench(): axis_frame = test_frame.build_axis_fcs() xgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield clk.posedge - yield clk.posedge - - while xgmii_rxc != 0xff: - yield clk.posedge - - yield delay(100) - - while rx_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge + yield axis_sink.wait() rx_frame = axis_sink.recv() eth_frame = eth_ep.EthFrame() @@ -278,20 +266,8 @@ def bench(): axis_frame = test_frame.build_axis() axis_source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - while tx_axis_tvalid: - yield clk.posedge - - yield delay(100) - - while xgmii_txc != 0xff: - yield clk.posedge - - yield clk.posedge - yield clk.posedge + yield xgmii_sink.wait() rx_frame = xgmii_sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_mac_10g_rx.py b/tb/test_eth_mac_10g_rx.py index 290fe5d2e..55d32f454 100755 --- a/tb/test_eth_mac_10g_rx.py +++ b/tb/test_eth_mac_10g_rx.py @@ -158,16 +158,8 @@ def bench(): xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) source.send(xgmii_frame) - yield clk.posedge - yield clk.posedge - - while xgmii_rxc != 0xff or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -205,21 +197,8 @@ def bench(): source.send(xgmii_frame1) source.send(xgmii_frame2) - yield clk.posedge - yield clk.posedge - - while xgmii_rxc != 0xff or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - - while xgmii_rxc != 0xff or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -228,6 +207,7 @@ def bench(): assert eth_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -270,28 +250,16 @@ def bench(): source.send(xgmii_frame1) source.send(xgmii_frame2) - yield clk.posedge - yield clk.posedge - while xgmii_rxc != 0xff or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - - while xgmii_rxc != 0xff or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_bad_frame_asserted assert error_bad_fcs_asserted - rx_frame = sink.recv() - assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -334,28 +302,16 @@ def bench(): source.send(xgmii_frame1) source.send(xgmii_frame2) - yield clk.posedge - yield clk.posedge - while xgmii_rxc != 0xff or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - - while xgmii_rxc != 0xff or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_bad_frame_asserted assert not error_bad_fcs_asserted - rx_frame = sink.recv() - assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() diff --git a/tb/test_eth_mac_10g_tx.py b/tb/test_eth_mac_10g_tx.py index 06c35d61a..1b6ba6238 100755 --- a/tb/test_eth_mac_10g_tx.py +++ b/tb/test_eth_mac_10g_tx.py @@ -151,16 +151,8 @@ def bench(): axis_frame = test_frame.build_axis() source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - while xgmii_txc != 0xff or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -204,16 +196,8 @@ def bench(): source.send(axis_frame1) source.send(axis_frame2) - yield clk.posedge - yield clk.posedge - - while xgmii_txc != 0xff or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -231,6 +215,7 @@ def bench(): assert eth_frame.eth_type == test_frame1.eth_type assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -276,16 +261,8 @@ def bench(): source.send(axis_frame1) source.send(axis_frame2) - yield clk.posedge - yield clk.posedge - - while xgmii_txc != 0xff or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -293,6 +270,7 @@ def bench(): # bad packet + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index 8ec119549..d0053099a 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -254,20 +254,8 @@ def bench(): axis_frame = test_frame.build_axis_fcs() gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield clk.posedge - yield clk.posedge - - while not rx_clk_enable or not tx_clk_enable or not (gmii_rx_dv or gmii_tx_en): - yield clk.posedge - yield clk.posedge - - while not rx_clk_enable or not tx_clk_enable or gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield axis_sink.wait() rx_frame = axis_sink.recv() eth_frame = eth_ep.EthFrame() @@ -292,20 +280,8 @@ def bench(): axis_frame = test_frame.build_axis() axis_source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - while not rx_clk_enable or not tx_clk_enable or not (gmii_rx_dv or gmii_tx_en): - yield clk.posedge - yield clk.posedge - - while not rx_clk_enable or not tx_clk_enable or gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield gmii_sink.wait() rx_frame = gmii_sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py index 2681fde7d..7c7a5f6b8 100755 --- a/tb/test_eth_mac_1g_fifo.py +++ b/tb/test_eth_mac_1g_fifo.py @@ -282,24 +282,8 @@ def bench(): axis_frame = test_frame.build_axis_fcs() gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield clk.posedge - yield clk.posedge - - while not rx_clk_enable or not tx_clk_enable or not (gmii_rx_dv or gmii_tx_en): - yield clk.posedge - yield clk.posedge - - while not rx_clk_enable or not tx_clk_enable or gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: - yield clk.posedge - - yield delay(100) - - while rx_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge + yield axis_sink.wait() rx_frame = axis_sink.recv() eth_frame = eth_ep.EthFrame() @@ -324,19 +308,8 @@ def bench(): axis_frame = test_frame.build_axis() axis_source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - while not rx_clk_enable or not tx_clk_enable or not (gmii_rx_dv or gmii_tx_en): - yield clk.posedge - yield clk.posedge - - while not rx_clk_enable or not tx_clk_enable or gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge + yield gmii_sink.wait() rx_frame = gmii_sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_mac_1g_gmii.py b/tb/test_eth_mac_1g_gmii.py index 294cd9ba2..ac887843c 100755 --- a/tb/test_eth_mac_1g_gmii.py +++ b/tb/test_eth_mac_1g_gmii.py @@ -258,20 +258,8 @@ def bench(): axis_frame = test_frame.build_axis_fcs() gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge - - while not (gmii_rx_dv or gmii_tx_en): - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge - - while gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: - yield gmii_rx_clk.posedge - - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge + yield axis_sink.wait() rx_frame = axis_sink.recv() eth_frame = eth_ep.EthFrame() @@ -296,20 +284,8 @@ def bench(): axis_frame = test_frame.build_axis() axis_source.send(axis_frame) - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge - - while not (gmii_rx_dv or gmii_tx_en): - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge - - while gmii_rx_dv or gmii_tx_en or tx_axis_tvalid or rx_axis_tvalid: - yield gmii_rx_clk.posedge - - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge + yield gmii_sink.wait() rx_frame = gmii_sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_mac_1g_gmii_fifo.py b/tb/test_eth_mac_1g_gmii_fifo.py index 8dda57731..a66886a51 100755 --- a/tb/test_eth_mac_1g_gmii_fifo.py +++ b/tb/test_eth_mac_1g_gmii_fifo.py @@ -280,21 +280,8 @@ def bench(): axis_frame = test_frame.build_axis_fcs() gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge - - while gmii_rx_dv: - yield gmii_rx_clk.posedge - - for k in range(10): - yield gmii_rx_clk.posedge - - while rx_axis_tvalid: - yield gmii_rx_clk.posedge - - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge + yield axis_sink.wait() rx_frame = axis_sink.recv() eth_frame = eth_ep.EthFrame() @@ -319,21 +306,8 @@ def bench(): axis_frame = test_frame.build_axis() axis_source.send(axis_frame) - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge - - while tx_axis_tvalid: - yield gmii_rx_clk.posedge - - for k in range(10): - yield gmii_rx_clk.posedge - - while gmii_tx_en: - yield gmii_rx_clk.posedge - - yield gmii_rx_clk.posedge - yield gmii_rx_clk.posedge + yield gmii_sink.wait() rx_frame = gmii_sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_mac_1g_rgmii.py b/tb/test_eth_mac_1g_rgmii.py index e0060c951..b439e4860 100755 --- a/tb/test_eth_mac_1g_rgmii.py +++ b/tb/test_eth_mac_1g_rgmii.py @@ -260,20 +260,8 @@ def bench(): axis_frame = test_frame.build_axis_fcs() rgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - - while not (rgmii_rx_ctl or rgmii_tx_ctl): - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - - while rgmii_rx_ctl or rgmii_tx_ctl or tx_axis_tvalid or rx_axis_tvalid: - yield rgmii_rx_clk.posedge - - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge + yield axis_sink.wait() rx_frame = axis_sink.recv() eth_frame = eth_ep.EthFrame() @@ -298,20 +286,8 @@ def bench(): axis_frame = test_frame.build_axis() axis_source.send(axis_frame) - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - - while not (rgmii_rx_ctl or rgmii_tx_ctl): - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - - while rgmii_rx_ctl or rgmii_tx_ctl or tx_axis_tvalid or rx_axis_tvalid: - yield rgmii_rx_clk.posedge - - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge + yield rgmii_sink.wait() rx_frame = rgmii_sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_mac_1g_rgmii_fifo.py b/tb/test_eth_mac_1g_rgmii_fifo.py index 111c22f37..24ea0cf48 100755 --- a/tb/test_eth_mac_1g_rgmii_fifo.py +++ b/tb/test_eth_mac_1g_rgmii_fifo.py @@ -277,23 +277,8 @@ def bench(): axis_frame = test_frame.build_axis_fcs() rgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - - while rgmii_rx_ctl: - yield rgmii_rx_clk.posedge - - for k in range(10): - yield rgmii_rx_clk.posedge - - while rx_axis_tvalid: - yield rgmii_rx_clk.posedge - - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge + yield axis_sink.wait() rx_frame = axis_sink.recv() eth_frame = eth_ep.EthFrame() @@ -318,23 +303,8 @@ def bench(): axis_frame = test_frame.build_axis() axis_source.send(axis_frame) - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - - while tx_axis_tvalid: - yield rgmii_rx_clk.posedge - - for k in range(10): - yield rgmii_rx_clk.posedge - - while rgmii_tx_ctl: - yield rgmii_rx_clk.posedge - - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge - yield rgmii_rx_clk.posedge + yield rgmii_sink.wait() rx_frame = rgmii_sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py index cfd1c1a0a..c247923a4 100755 --- a/tb/test_eth_mac_1g_rx.py +++ b/tb/test_eth_mac_1g_rx.py @@ -155,16 +155,8 @@ def bench(): gmii_frame = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) source.send(gmii_frame) - yield clk.posedge - yield clk.posedge - - while gmii_rx_dv or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -201,21 +193,8 @@ def bench(): source.send(gmii_frame1) source.send(gmii_frame2) - yield clk.posedge - yield clk.posedge - - while gmii_rx_dv or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - - while gmii_rx_dv or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -224,6 +203,7 @@ def bench(): assert eth_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -266,28 +246,16 @@ def bench(): source.send(gmii_frame1) source.send(gmii_frame2) - yield clk.posedge - yield clk.posedge - while gmii_rx_dv or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - - while gmii_rx_dv or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_bad_frame_asserted assert error_bad_fcs_asserted - rx_frame = sink.recv() - assert rx_frame.user[-1] + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() @@ -330,28 +298,16 @@ def bench(): source.send(gmii_frame1) source.send(gmii_frame2) - yield clk.posedge - yield clk.posedge - while gmii_rx_dv or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - - while gmii_rx_dv or output_axis_tvalid or not source.empty(): - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_bad_frame_asserted assert not error_bad_fcs_asserted - rx_frame = sink.recv() - assert rx_frame.last_cycle_user + yield sink.wait() rx_frame = sink.recv() eth_frame = eth_ep.EthFrame() diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py index 62c3f111d..a3a9e341f 100755 --- a/tb/test_eth_mac_1g_tx.py +++ b/tb/test_eth_mac_1g_tx.py @@ -151,16 +151,8 @@ def bench(): axis_frame = test_frame.build_axis() source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - while gmii_tx_en or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -204,16 +196,8 @@ def bench(): source.send(axis_frame1) source.send(axis_frame2) - yield clk.posedge - yield clk.posedge - - while gmii_tx_en or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -231,6 +215,7 @@ def bench(): assert eth_frame.eth_type == test_frame1.eth_type assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -276,16 +261,8 @@ def bench(): source.send(axis_frame1) source.send(axis_frame2) - yield clk.posedge - yield clk.posedge - - while gmii_tx_en or input_axis_tvalid: - yield clk.posedge - - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') @@ -293,6 +270,7 @@ def bench(): # bad packet + yield sink.wait() rx_frame = sink.recv() assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') diff --git a/tb/test_eth_mux_4.py b/tb/test_eth_mux_4.py index d3dd3cfc2..92b25d34b 100755 --- a/tb/test_eth_mux_4.py +++ b/tb/test_eth_mux_4.py @@ -304,14 +304,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -331,14 +325,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -364,18 +352,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -407,13 +390,13 @@ def bench(): while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -456,13 +439,13 @@ def bench(): source_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -499,14 +482,13 @@ def bench(): sink_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_eth_mux_64_4.py b/tb/test_eth_mux_64_4.py index 8d0128518..e629e3f1f 100755 --- a/tb/test_eth_mux_64_4.py +++ b/tb/test_eth_mux_64_4.py @@ -319,14 +319,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -346,14 +340,8 @@ def bench(): test_frame.payload = bytearray(range(32)) source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -379,18 +367,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -422,13 +405,13 @@ def bench(): while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -471,13 +454,13 @@ def bench(): source_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -514,14 +497,13 @@ def bench(): sink_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_ip.py b/tb/test_ip.py index 1fafbc96e..d0bd2c72a 100755 --- a/tb/test_ip.py +++ b/tb/test_ip.py @@ -433,14 +433,7 @@ def bench(): eth_source.send(eth_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield ip_sink.wait() rx_frame = ip_sink.recv() assert rx_frame == test_frame @@ -478,14 +471,7 @@ def bench(): ip_source.send(test_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = ip_ep.IPFrame() diff --git a/tb/test_ip_64.py b/tb/test_ip_64.py index c14b980f1..112c0ab04 100755 --- a/tb/test_ip_64.py +++ b/tb/test_ip_64.py @@ -445,14 +445,7 @@ def bench(): eth_source.send(eth_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield ip_sink.wait() rx_frame = ip_sink.recv() assert rx_frame == test_frame @@ -490,14 +483,7 @@ def bench(): ip_source.send(test_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = ip_ep.IPFrame() diff --git a/tb/test_ip_arb_mux_4.py b/tb/test_ip_arb_mux_4.py index 54d03d09f..6e11001f9 100755 --- a/tb/test_ip_arb_mux_4.py +++ b/tb/test_ip_arb_mux_4.py @@ -507,14 +507,8 @@ def bench(): test_frame.build() source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -546,14 +540,8 @@ def bench(): test_frame.build() source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -605,18 +593,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -668,18 +651,13 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -747,13 +725,13 @@ def bench(): source_2_pause.next = False source_3_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -815,14 +793,13 @@ def bench(): yield clk.posedge sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -884,31 +861,32 @@ def bench(): yield clk.posedge source_1.send(test_frame1) - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_ip_arb_mux_64_4.py b/tb/test_ip_arb_mux_64_4.py index ea0746139..44cc9ac04 100755 --- a/tb/test_ip_arb_mux_64_4.py +++ b/tb/test_ip_arb_mux_64_4.py @@ -522,14 +522,8 @@ def bench(): test_frame.build() source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -561,14 +555,8 @@ def bench(): test_frame.build() source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -620,18 +608,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -683,18 +666,13 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -762,13 +740,13 @@ def bench(): source_2_pause.next = False source_3_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -830,14 +808,13 @@ def bench(): yield clk.posedge sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -899,31 +876,32 @@ def bench(): yield clk.posedge source_1.send(test_frame1) - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_ip_complete.py b/tb/test_ip_complete.py index 4362c0626..020cefdda 100755 --- a/tb/test_ip_complete.py +++ b/tb/test_ip_complete.py @@ -396,14 +396,7 @@ def bench(): eth_source.send(eth_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield ip_sink.wait() rx_frame = ip_sink.recv() assert rx_frame == test_frame @@ -443,9 +436,7 @@ def bench(): ip_source.send(test_frame) # wait for ARP request packet - while eth_sink.empty(): - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -479,14 +470,7 @@ def bench(): arp_frame.arp_tpa = 0xc0a80164 eth_source.send(arp_frame.build_eth()) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = ip_ep.IPFrame() diff --git a/tb/test_ip_complete_64.py b/tb/test_ip_complete_64.py index 9f837b889..9749f02af 100755 --- a/tb/test_ip_complete_64.py +++ b/tb/test_ip_complete_64.py @@ -408,14 +408,7 @@ def bench(): eth_source.send(eth_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield ip_sink.wait() rx_frame = ip_sink.recv() assert rx_frame == test_frame @@ -455,9 +448,7 @@ def bench(): ip_source.send(test_frame) # wait for ARP request packet - while eth_sink.empty(): - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -491,14 +482,7 @@ def bench(): arp_frame.arp_tpa = 0xc0a80164 eth_source.send(arp_frame.build_eth()) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = ip_ep.IPFrame() diff --git a/tb/test_ip_demux_4.py b/tb/test_ip_demux_4.py index d3efa6c76..06c1dddcd 100755 --- a/tb/test_ip_demux_4.py +++ b/tb/test_ip_demux_4.py @@ -513,13 +513,8 @@ def bench(): test_frame.build() source.send(test_frame) - yield clk.posedge - - while input_ip_payload_tvalid or input_ip_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame @@ -553,13 +548,8 @@ def bench(): test_frame.build() source.send(test_frame) - yield clk.posedge - - while input_ip_payload_tvalid or input_ip_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame @@ -613,17 +603,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - while input_ip_payload_tvalid or input_ip_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame1 + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame2 @@ -682,13 +668,13 @@ def bench(): while input_ip_payload_tvalid or input_ip_hdr_valid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -752,13 +738,13 @@ def bench(): source_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -828,13 +814,13 @@ def bench(): sink_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 diff --git a/tb/test_ip_demux_64_4.py b/tb/test_ip_demux_64_4.py index 7dbed7897..547e7a389 100755 --- a/tb/test_ip_demux_64_4.py +++ b/tb/test_ip_demux_64_4.py @@ -528,13 +528,8 @@ def bench(): test_frame.build() source.send(test_frame) - yield clk.posedge - - while input_ip_payload_tvalid or input_ip_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame @@ -568,13 +563,8 @@ def bench(): test_frame.build() source.send(test_frame) - yield clk.posedge - - while input_ip_payload_tvalid or input_ip_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame @@ -628,17 +618,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - while input_ip_payload_tvalid or input_ip_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame1 + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame2 @@ -697,13 +683,13 @@ def bench(): while input_ip_payload_tvalid or input_ip_hdr_valid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -767,13 +753,13 @@ def bench(): source_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -843,13 +829,13 @@ def bench(): sink_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index 9cdbed496..eb964e039 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -280,10 +280,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -342,14 +339,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -410,15 +405,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -479,14 +472,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -547,14 +538,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -616,15 +605,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -686,15 +673,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -757,15 +742,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -828,15 +811,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -897,14 +878,11 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_invalid_header_asserted - rx_frame = sink.recv() - assert rx_frame == test_frame2 assert sink.empty() @@ -963,14 +941,11 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_invalid_checksum_asserted - rx_frame = sink.recv() - assert rx_frame == test_frame2 assert sink.empty() @@ -1032,14 +1007,11 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_header_early_termination_asserted - rx_frame = sink.recv() - assert rx_frame == test_frame2 assert sink.empty() diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py index 941af90a7..f12b0ae38 100755 --- a/tb/test_ip_eth_rx_64.py +++ b/tb/test_ip_eth_rx_64.py @@ -286,10 +286,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -348,14 +345,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -416,15 +411,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -485,14 +478,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -553,14 +544,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -622,15 +611,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -692,15 +679,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -763,15 +748,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -834,15 +817,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -903,14 +884,11 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_invalid_header_asserted - rx_frame = sink.recv() - assert rx_frame == test_frame2 assert sink.empty() @@ -969,14 +947,11 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_invalid_checksum_asserted - rx_frame = sink.recv() - assert rx_frame == test_frame2 assert sink.empty() @@ -1038,14 +1013,11 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_header_early_termination_asserted - rx_frame = sink.recv() - assert rx_frame == test_frame2 assert sink.empty() diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py index 64f5012a5..2fea6d751 100755 --- a/tb/test_ip_eth_tx.py +++ b/tb/test_ip_eth_tx.py @@ -255,10 +255,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -317,10 +314,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -328,6 +322,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -388,10 +383,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -400,6 +392,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -461,10 +454,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -472,6 +462,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -533,10 +524,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -544,6 +532,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -606,10 +595,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -618,6 +604,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -680,10 +667,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -692,6 +676,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -755,15 +740,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -827,15 +810,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() diff --git a/tb/test_ip_eth_tx_64.py b/tb/test_ip_eth_tx_64.py index 664a0b481..dde510986 100755 --- a/tb/test_ip_eth_tx_64.py +++ b/tb/test_ip_eth_tx_64.py @@ -261,10 +261,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -323,10 +320,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -334,6 +328,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -394,10 +389,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -406,6 +398,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -467,10 +460,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -478,6 +468,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -539,10 +530,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -550,6 +538,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -612,10 +601,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -624,6 +610,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -686,10 +673,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -698,6 +682,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -761,15 +746,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() @@ -833,15 +816,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() check_frame = ip_ep.IPFrame() diff --git a/tb/test_ip_mux_4.py b/tb/test_ip_mux_4.py index d0feab038..6e61369b3 100755 --- a/tb/test_ip_mux_4.py +++ b/tb/test_ip_mux_4.py @@ -513,14 +513,8 @@ def bench(): test_frame.build() source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -554,14 +548,8 @@ def bench(): test_frame.build() source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -615,18 +603,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -686,13 +669,13 @@ def bench(): while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -763,13 +746,13 @@ def bench(): source_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -834,14 +817,13 @@ def bench(): sink_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_ip_mux_64_4.py b/tb/test_ip_mux_64_4.py index c8509a690..ae09a00da 100755 --- a/tb/test_ip_mux_64_4.py +++ b/tb/test_ip_mux_64_4.py @@ -528,14 +528,8 @@ def bench(): test_frame.build() source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -569,14 +563,8 @@ def bench(): test_frame.build() source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -630,18 +618,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -701,13 +684,13 @@ def bench(): while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -778,13 +761,13 @@ def bench(): source_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -849,14 +832,13 @@ def bench(): sink_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_udp.py b/tb/test_udp.py index a6e395c5d..a4a5c4033 100755 --- a/tb/test_udp.py +++ b/tb/test_udp.py @@ -435,16 +435,6 @@ def bench(): if (tx_error_payload_early_termination): tx_error_payload_early_termination_asserted.next = 1 - def wait_normal(): - i = 8 - while i > 0: - i = max(0, i-1) - if (input_ip_payload_tvalid or input_udp_payload_tvalid or - output_ip_payload_tvalid or output_udp_payload_tvalid or - input_ip_hdr_valid or input_udp_hdr_valid): - i = 8 - yield clk.posedge - @instance def check(): yield delay(100) @@ -485,14 +475,7 @@ def bench(): ip_source.send(ip_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield udp_sink.wait() rx_frame = udp_sink.recv() assert rx_frame == test_frame @@ -532,14 +515,7 @@ def bench(): udp_source.send(test_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield ip_sink.wait() rx_frame = ip_sink.recv() check_frame = udp_ep.UDPFrame() diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py index f8d4e75d9..b11939f10 100755 --- a/tb/test_udp_64.py +++ b/tb/test_udp_64.py @@ -447,16 +447,6 @@ def bench(): if (tx_error_payload_early_termination): tx_error_payload_early_termination_asserted.next = 1 - def wait_normal(): - i = 8 - while i > 0: - i = max(0, i-1) - if (input_ip_payload_tvalid or input_udp_payload_tvalid or - output_ip_payload_tvalid or output_udp_payload_tvalid or - input_ip_hdr_valid or input_udp_hdr_valid): - i = 8 - yield clk.posedge - @instance def check(): yield delay(100) @@ -497,14 +487,7 @@ def bench(): ip_source.send(ip_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield udp_sink.wait() rx_frame = udp_sink.recv() assert rx_frame == test_frame @@ -544,14 +527,7 @@ def bench(): udp_source.send(test_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield ip_sink.wait() rx_frame = ip_sink.recv() check_frame = udp_ep.UDPFrame() diff --git a/tb/test_udp_arb_mux_4.py b/tb/test_udp_arb_mux_4.py index 4792317ed..1c8f2bea9 100755 --- a/tb/test_udp_arb_mux_4.py +++ b/tb/test_udp_arb_mux_4.py @@ -571,14 +571,8 @@ def bench(): test_frame.build() source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -614,14 +608,8 @@ def bench(): test_frame.build() source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -681,18 +669,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -752,18 +735,13 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -839,13 +817,13 @@ def bench(): source_2_pause.next = False source_3_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -915,14 +893,13 @@ def bench(): yield clk.posedge sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -992,31 +969,32 @@ def bench(): yield clk.posedge source_1.send(test_frame1) - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_udp_arb_mux_64_4.py b/tb/test_udp_arb_mux_64_4.py index bf9c9dbf9..867b3af5a 100755 --- a/tb/test_udp_arb_mux_64_4.py +++ b/tb/test_udp_arb_mux_64_4.py @@ -586,14 +586,8 @@ def bench(): test_frame.build() source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -629,14 +623,8 @@ def bench(): test_frame.build() source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -696,18 +684,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -767,18 +750,13 @@ def bench(): source_1.send(test_frame1) source_2.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -854,13 +832,13 @@ def bench(): source_2_pause.next = False source_3_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -930,14 +908,13 @@ def bench(): yield clk.posedge sink_pause.next = False yield clk.posedge - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -1007,31 +984,32 @@ def bench(): yield clk.posedge source_1.send(test_frame1) - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_udp_checksum_gen.py b/tb/test_udp_checksum_gen.py index 36472b104..b1564fda2 100755 --- a/tb/test_udp_checksum_gen.py +++ b/tb/test_udp_checksum_gen.py @@ -334,10 +334,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -401,14 +398,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -474,15 +469,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_udp_checksum_gen_64.py b/tb/test_udp_checksum_gen_64.py index b38633dfb..8f4adb485 100755 --- a/tb/test_udp_checksum_gen_64.py +++ b/tb/test_udp_checksum_gen_64.py @@ -340,10 +340,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -407,14 +404,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -480,15 +475,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py index e99fd8a71..fa99ce034 100755 --- a/tb/test_udp_complete.py +++ b/tb/test_udp_complete.py @@ -579,14 +579,7 @@ def bench(): eth_source.send(eth_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield ip_sink.wait() rx_frame = ip_sink.recv() assert rx_frame == test_frame @@ -626,9 +619,7 @@ def bench(): ip_source.send(test_frame) # wait for ARP request packet - while eth_sink.empty(): - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -662,14 +653,7 @@ def bench(): arp_frame.arp_tpa = 0xc0a80164 eth_source.send(arp_frame.build_eth()) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = ip_ep.IPFrame() @@ -783,14 +767,7 @@ def bench(): eth_source.send(eth_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield udp_sink.wait() rx_frame = udp_sink.recv() assert rx_frame == test_frame @@ -830,14 +807,7 @@ def bench(): udp_source.send(test_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = udp_ep.UDPFrame() diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index c0af01476..3ee61fd6f 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -597,14 +597,7 @@ def bench(): eth_source.send(eth_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield ip_sink.wait() rx_frame = ip_sink.recv() assert rx_frame == test_frame @@ -644,9 +637,7 @@ def bench(): ip_source.send(test_frame) # wait for ARP request packet - while eth_sink.empty(): - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = arp_ep.ARPFrame() check_frame.parse_eth(rx_frame) @@ -680,14 +671,7 @@ def bench(): arp_frame.arp_tpa = 0xc0a80164 eth_source.send(arp_frame.build_eth()) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = ip_ep.IPFrame() @@ -801,14 +785,7 @@ def bench(): eth_source.send(eth_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield udp_sink.wait() rx_frame = udp_sink.recv() assert rx_frame == test_frame @@ -848,14 +825,7 @@ def bench(): udp_source.send(test_frame) - yield clk.posedge - yield clk.posedge - - yield wait_normal() - - yield clk.posedge - yield clk.posedge - + yield eth_sink.wait() rx_frame = eth_sink.recv() check_frame = udp_ep.UDPFrame() diff --git a/tb/test_udp_demux_4.py b/tb/test_udp_demux_4.py index 379a60d66..f35b3b1a3 100755 --- a/tb/test_udp_demux_4.py +++ b/tb/test_udp_demux_4.py @@ -577,13 +577,8 @@ def bench(): test_frame.build() source.send(test_frame) - yield clk.posedge - - while input_udp_payload_tvalid or input_udp_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame @@ -621,13 +616,8 @@ def bench(): test_frame.build() source.send(test_frame) - yield clk.posedge - - while input_udp_payload_tvalid or input_udp_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame @@ -689,17 +679,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - while input_udp_payload_tvalid or input_udp_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame1 + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame2 @@ -766,13 +752,13 @@ def bench(): while input_udp_payload_tvalid or input_udp_hdr_valid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -844,13 +830,13 @@ def bench(): source_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -928,13 +914,13 @@ def bench(): sink_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 diff --git a/tb/test_udp_demux_64_4.py b/tb/test_udp_demux_64_4.py index 4320d5505..cf8b5185e 100755 --- a/tb/test_udp_demux_64_4.py +++ b/tb/test_udp_demux_64_4.py @@ -592,13 +592,8 @@ def bench(): test_frame.build() source.send(test_frame) - yield clk.posedge - - while input_udp_payload_tvalid or input_udp_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame @@ -636,13 +631,8 @@ def bench(): test_frame.build() source.send(test_frame) - yield clk.posedge - - while input_udp_payload_tvalid or input_udp_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame @@ -704,17 +694,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield clk.posedge - - while input_udp_payload_tvalid or input_udp_hdr_valid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame1 + yield sink_0.wait() rx_frame = sink_0.recv() assert rx_frame == test_frame2 @@ -781,13 +767,13 @@ def bench(): while input_udp_payload_tvalid or input_udp_hdr_valid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -859,13 +845,13 @@ def bench(): source_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 @@ -943,13 +929,13 @@ def bench(): sink_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink_1.wait() rx_frame = sink_1.recv() assert rx_frame == test_frame1 + yield sink_2.wait() rx_frame = sink_2.recv() assert rx_frame == test_frame2 diff --git a/tb/test_udp_ip_rx.py b/tb/test_udp_ip_rx.py index f2a7f2066..4e20a029e 100755 --- a/tb/test_udp_ip_rx.py +++ b/tb/test_udp_ip_rx.py @@ -326,10 +326,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -396,14 +393,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -472,15 +467,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -549,14 +542,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -625,14 +616,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -702,15 +691,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -780,15 +767,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -859,15 +844,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -938,15 +921,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -1018,14 +999,11 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_header_early_termination_asserted - rx_frame = sink.recv() - assert rx_frame == test_frame2 assert sink.empty() diff --git a/tb/test_udp_ip_rx_64.py b/tb/test_udp_ip_rx_64.py index dacc540c6..62357cc21 100755 --- a/tb/test_udp_ip_rx_64.py +++ b/tb/test_udp_ip_rx_64.py @@ -332,10 +332,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -402,14 +399,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -478,15 +473,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -555,14 +548,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -631,14 +622,12 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -708,15 +697,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -786,15 +773,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -865,15 +850,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -944,15 +927,13 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -1024,14 +1005,11 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() + rx_frame = sink.recv() assert error_header_early_termination_asserted - rx_frame = sink.recv() - assert rx_frame == test_frame2 assert sink.empty() diff --git a/tb/test_udp_ip_tx.py b/tb/test_udp_ip_tx.py index c14b6e99f..deb3c3a5c 100755 --- a/tb/test_udp_ip_tx.py +++ b/tb/test_udp_ip_tx.py @@ -317,10 +317,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -387,10 +384,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -398,6 +392,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -466,10 +461,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -478,6 +470,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -547,10 +540,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -558,6 +548,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -627,10 +618,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -638,6 +626,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -708,10 +697,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -720,6 +706,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -790,10 +777,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -802,6 +786,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -873,10 +858,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -885,6 +867,7 @@ def bench(): assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -956,10 +939,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -968,6 +948,7 @@ def bench(): assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() diff --git a/tb/test_udp_ip_tx_64.py b/tb/test_udp_ip_tx_64.py index b6e427cce..4043e589a 100755 --- a/tb/test_udp_ip_tx_64.py +++ b/tb/test_udp_ip_tx_64.py @@ -323,10 +323,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -393,10 +390,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -404,6 +398,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -472,10 +467,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -484,6 +476,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -553,10 +546,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -564,6 +554,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -633,10 +624,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -644,6 +632,7 @@ def bench(): assert check_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -714,10 +703,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -726,6 +712,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -796,10 +783,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -808,6 +792,7 @@ def bench(): assert check_frame == test_frame1 assert rx_frame.payload.user[-1] + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -879,10 +864,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -891,6 +873,7 @@ def bench(): assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -962,10 +945,7 @@ def bench(): yield wait() - yield clk.posedge - yield clk.posedge - yield clk.posedge - + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() @@ -974,6 +954,7 @@ def bench(): assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield sink.wait() rx_frame = sink.recv() check_frame = udp_ep.UDPFrame() diff --git a/tb/test_udp_mux_4.py b/tb/test_udp_mux_4.py index d65979163..848f62193 100755 --- a/tb/test_udp_mux_4.py +++ b/tb/test_udp_mux_4.py @@ -577,14 +577,8 @@ def bench(): test_frame.build() source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -622,14 +616,8 @@ def bench(): test_frame.build() source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -691,18 +679,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -770,13 +753,13 @@ def bench(): while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -855,13 +838,13 @@ def bench(): source_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -934,14 +917,13 @@ def bench(): sink_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 diff --git a/tb/test_udp_mux_64_4.py b/tb/test_udp_mux_64_4.py index cff25d07e..521598330 100755 --- a/tb/test_udp_mux_64_4.py +++ b/tb/test_udp_mux_64_4.py @@ -592,14 +592,8 @@ def bench(): test_frame.build() source_0.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -637,14 +631,8 @@ def bench(): test_frame.build() source_1.send(test_frame) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame @@ -706,18 +694,13 @@ def bench(): source_0.send(test_frame1) source_0.send(test_frame2) - yield clk.posedge - yield clk.posedge - - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -785,13 +768,13 @@ def bench(): while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -870,13 +853,13 @@ def bench(): source_3_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 @@ -949,14 +932,13 @@ def bench(): sink_pause.next = False yield clk.posedge select.next = 2 - yield clk.posedge - yield clk.posedge - yield clk.posedge + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame2 From 202fbcbb6f7db4bef355001996323a29c9dfaf23 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 9 Aug 2018 11:23:27 -0700 Subject: [PATCH 403/617] Fix typo --- rtl/axis_switch.py | 2 +- rtl/axis_switch_4x4.v | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rtl/axis_switch.py b/rtl/axis_switch.py index f537854c5..edf4c0cd8 100755 --- a/rtl/axis_switch.py +++ b/rtl/axis_switch.py @@ -189,7 +189,7 @@ assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; // mux for incoming packet {% for p in range(n) %} reg [DATA_WIDTH-1:0] current_input_{{p}}_axis_tdata; -reg [DATA_WIDTH-1:0] current_input_{{p}}_axis_tkeep; +reg [KEEP_WIDTH-1:0] current_input_{{p}}_axis_tkeep; reg current_input_{{p}}_axis_tvalid; reg current_input_{{p}}_axis_tready; reg current_input_{{p}}_axis_tlast; diff --git a/rtl/axis_switch_4x4.v b/rtl/axis_switch_4x4.v index 8f7bbf943..48e8e89a3 100644 --- a/rtl/axis_switch_4x4.v +++ b/rtl/axis_switch_4x4.v @@ -253,7 +253,7 @@ assign input_3_axis_tready = input_3_axis_tready_reg; // mux for incoming packet reg [DATA_WIDTH-1:0] current_input_0_axis_tdata; -reg [DATA_WIDTH-1:0] current_input_0_axis_tkeep; +reg [KEEP_WIDTH-1:0] current_input_0_axis_tkeep; reg current_input_0_axis_tvalid; reg current_input_0_axis_tready; reg current_input_0_axis_tlast; @@ -317,7 +317,7 @@ always @* begin end reg [DATA_WIDTH-1:0] current_input_1_axis_tdata; -reg [DATA_WIDTH-1:0] current_input_1_axis_tkeep; +reg [KEEP_WIDTH-1:0] current_input_1_axis_tkeep; reg current_input_1_axis_tvalid; reg current_input_1_axis_tready; reg current_input_1_axis_tlast; @@ -381,7 +381,7 @@ always @* begin end reg [DATA_WIDTH-1:0] current_input_2_axis_tdata; -reg [DATA_WIDTH-1:0] current_input_2_axis_tkeep; +reg [KEEP_WIDTH-1:0] current_input_2_axis_tkeep; reg current_input_2_axis_tvalid; reg current_input_2_axis_tready; reg current_input_2_axis_tlast; @@ -445,7 +445,7 @@ always @* begin end reg [DATA_WIDTH-1:0] current_input_3_axis_tdata; -reg [DATA_WIDTH-1:0] current_input_3_axis_tkeep; +reg [KEEP_WIDTH-1:0] current_input_3_axis_tkeep; reg current_input_3_axis_tvalid; reg current_input_3_axis_tready; reg current_input_3_axis_tlast; From 7a879aec1c36c227c27e39dd1fac78fbb19cc244 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 9 Aug 2018 18:38:41 -0700 Subject: [PATCH 404/617] Remove extra registers --- rtl/axis_switch.py | 21 ++++----------------- rtl/axis_switch_4x4.v | 41 ++++++++++------------------------------- 2 files changed, 14 insertions(+), 48 deletions(-) diff --git a/rtl/axis_switch.py b/rtl/axis_switch.py index edf4c0cd8..f57951c19 100755 --- a/rtl/axis_switch.py +++ b/rtl/axis_switch.py @@ -98,8 +98,8 @@ module {{name}} # parameter LSB_PRIORITY = "HIGH" ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI Stream inputs @@ -161,9 +161,6 @@ reg input_{{p}}_request_valid_reg = 1'b0, input_{{p}}_request_valid_next; reg input_{{p}}_request_error_reg = 1'b0, input_{{p}}_request_error_next; {%- endfor %} {% for p in range(n) %} -reg [{{cm-1}}:0] select_{{p}}_reg = {{cm}}'d0, select_{{p}}_next; -{%- endfor %} -{% for p in range(n) %} reg enable_{{p}}_reg = 1'b0, enable_{{p}}_next; {%- endfor %} {% for p in range(m) %} @@ -198,7 +195,7 @@ reg [DEST_WIDTH-1:0] current_input_{{p}}_axis_tdest; reg [USER_WIDTH-1:0] current_input_{{p}}_axis_tuser; always @* begin - case (select_{{p}}_reg) + case (grant_encoded_{{p}}) {%- for q in range(m) %} {{cm}}'d{{q}}: begin current_input_{{p}}_axis_tdata = input_{{q}}_axis_tdata; @@ -263,9 +260,6 @@ assign acknowledge_{{p}}[{{q}}] = grant_{{p}}[{{q}}] & input_{{q}}_axis_tvalid & {%- endfor %} {% endfor %} always @* begin -{%- for p in range(n) %} - select_{{p}}_next = select_{{p}}_reg; -{%- endfor %} {% for p in range(n) %} enable_{{p}}_next = enable_{{p}}_reg; {%- endfor %} @@ -315,13 +309,12 @@ always @* begin end if (~enable_{{p}}_reg & grant_valid_{{p}}) begin enable_{{p}}_next = 1'b1; - select_{{p}}_next = grant_encoded_{{p}}; end {% endfor %} // generate ready signal on selected port {% for p in range(n) %} if (enable_{{p}}_next) begin - case (select_{{p}}_next) + case (grant_encoded_{{p}}) {%- for q in range(m) %} {{cm}}'d{{q}}: input_{{q}}_axis_tready_next = output_{{p}}_axis_tready_int_early; {%- endfor %} @@ -353,9 +346,6 @@ always @(posedge clk) begin input_{{p}}_request_valid_reg <= 1'b0; input_{{p}}_request_error_reg <= 1'b0; {%- endfor %} -{%- for p in range(n) %} - select_{{p}}_reg <= 2'd0; -{%- endfor %} {%- for p in range(n) %} enable_{{p}}_reg <= 1'b0; {%- endfor %} @@ -368,9 +358,6 @@ always @(posedge clk) begin input_{{p}}_request_valid_reg <= input_{{p}}_request_valid_next; input_{{p}}_request_error_reg <= input_{{p}}_request_error_next; {%- endfor %} -{%- for p in range(n) %} - select_{{p}}_reg <= select_{{p}}_next; -{%- endfor %} {%- for p in range(n) %} enable_{{p}}_reg <= enable_{{p}}_next; {%- endfor %} diff --git a/rtl/axis_switch_4x4.v b/rtl/axis_switch_4x4.v index 48e8e89a3..76264ad1b 100644 --- a/rtl/axis_switch_4x4.v +++ b/rtl/axis_switch_4x4.v @@ -57,8 +57,8 @@ module axis_switch_4x4 # parameter LSB_PRIORITY = "HIGH" ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI Stream inputs @@ -189,11 +189,6 @@ reg [3:0] input_3_request_reg = 4'd0, input_3_request_next; reg input_3_request_valid_reg = 1'b0, input_3_request_valid_next; reg input_3_request_error_reg = 1'b0, input_3_request_error_next; -reg [1:0] select_0_reg = 2'd0, select_0_next; -reg [1:0] select_1_reg = 2'd0, select_1_next; -reg [1:0] select_2_reg = 2'd0, select_2_next; -reg [1:0] select_3_reg = 2'd0, select_3_next; - reg enable_0_reg = 1'b0, enable_0_next; reg enable_1_reg = 1'b0, enable_1_next; reg enable_2_reg = 1'b0, enable_2_next; @@ -262,7 +257,7 @@ reg [DEST_WIDTH-1:0] current_input_0_axis_tdest; reg [USER_WIDTH-1:0] current_input_0_axis_tuser; always @* begin - case (select_0_reg) + case (grant_encoded_0) 2'd0: begin current_input_0_axis_tdata = input_0_axis_tdata; current_input_0_axis_tkeep = input_0_axis_tkeep; @@ -326,7 +321,7 @@ reg [DEST_WIDTH-1:0] current_input_1_axis_tdest; reg [USER_WIDTH-1:0] current_input_1_axis_tuser; always @* begin - case (select_1_reg) + case (grant_encoded_1) 2'd0: begin current_input_1_axis_tdata = input_0_axis_tdata; current_input_1_axis_tkeep = input_0_axis_tkeep; @@ -390,7 +385,7 @@ reg [DEST_WIDTH-1:0] current_input_2_axis_tdest; reg [USER_WIDTH-1:0] current_input_2_axis_tuser; always @* begin - case (select_2_reg) + case (grant_encoded_2) 2'd0: begin current_input_2_axis_tdata = input_0_axis_tdata; current_input_2_axis_tkeep = input_0_axis_tkeep; @@ -454,7 +449,7 @@ reg [DEST_WIDTH-1:0] current_input_3_axis_tdest; reg [USER_WIDTH-1:0] current_input_3_axis_tuser; always @* begin - case (select_3_reg) + case (grant_encoded_3) 2'd0: begin current_input_3_axis_tdata = input_0_axis_tdata; current_input_3_axis_tkeep = input_0_axis_tkeep; @@ -641,10 +636,6 @@ assign acknowledge_3[2] = grant_3[2] & input_2_axis_tvalid & input_2_axis_tready assign acknowledge_3[3] = grant_3[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; always @* begin - select_0_next = select_0_reg; - select_1_next = select_1_reg; - select_2_next = select_2_reg; - select_3_next = select_3_reg; enable_0_next = enable_0_reg; enable_1_next = enable_1_reg; @@ -791,7 +782,6 @@ always @* begin end if (~enable_0_reg & grant_valid_0) begin enable_0_next = 1'b1; - select_0_next = grant_encoded_0; end if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin @@ -801,7 +791,6 @@ always @* begin end if (~enable_1_reg & grant_valid_1) begin enable_1_next = 1'b1; - select_1_next = grant_encoded_1; end if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin @@ -811,7 +800,6 @@ always @* begin end if (~enable_2_reg & grant_valid_2) begin enable_2_next = 1'b1; - select_2_next = grant_encoded_2; end if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin @@ -821,13 +809,12 @@ always @* begin end if (~enable_3_reg & grant_valid_3) begin enable_3_next = 1'b1; - select_3_next = grant_encoded_3; end // generate ready signal on selected port if (enable_0_next) begin - case (select_0_next) + case (grant_encoded_0) 2'd0: input_0_axis_tready_next = output_0_axis_tready_int_early; 2'd1: input_1_axis_tready_next = output_0_axis_tready_int_early; 2'd2: input_2_axis_tready_next = output_0_axis_tready_int_early; @@ -836,7 +823,7 @@ always @* begin end if (enable_1_next) begin - case (select_1_next) + case (grant_encoded_1) 2'd0: input_0_axis_tready_next = output_1_axis_tready_int_early; 2'd1: input_1_axis_tready_next = output_1_axis_tready_int_early; 2'd2: input_2_axis_tready_next = output_1_axis_tready_int_early; @@ -845,7 +832,7 @@ always @* begin end if (enable_2_next) begin - case (select_2_next) + case (grant_encoded_2) 2'd0: input_0_axis_tready_next = output_2_axis_tready_int_early; 2'd1: input_1_axis_tready_next = output_2_axis_tready_int_early; 2'd2: input_2_axis_tready_next = output_2_axis_tready_int_early; @@ -854,7 +841,7 @@ always @* begin end if (enable_3_next) begin - case (select_3_next) + case (grant_encoded_3) 2'd0: input_0_axis_tready_next = output_3_axis_tready_int_early; 2'd1: input_1_axis_tready_next = output_3_axis_tready_int_early; 2'd2: input_2_axis_tready_next = output_3_axis_tready_int_early; @@ -920,10 +907,6 @@ always @(posedge clk) begin input_3_request_reg <= 4'd0; input_3_request_valid_reg <= 1'b0; input_3_request_error_reg <= 1'b0; - select_0_reg <= 2'd0; - select_1_reg <= 2'd0; - select_2_reg <= 2'd0; - select_3_reg <= 2'd0; enable_0_reg <= 1'b0; enable_1_reg <= 1'b0; enable_2_reg <= 1'b0; @@ -945,10 +928,6 @@ always @(posedge clk) begin input_3_request_reg <= input_3_request_next; input_3_request_valid_reg <= input_3_request_valid_next; input_3_request_error_reg <= input_3_request_error_next; - select_0_reg <= select_0_next; - select_1_reg <= select_1_next; - select_2_reg <= select_2_next; - select_3_reg <= select_3_next; enable_0_reg <= enable_0_next; enable_1_reg <= enable_1_next; enable_2_reg <= enable_2_next; From 8e5ec36ced28cdf30107a46a7f4b88110dd78e7d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 9 Aug 2018 18:40:50 -0700 Subject: [PATCH 405/617] Optimize axis_arb_mux and improve latency --- rtl/axis_arb_mux.py | 202 +++++++++++++++++++++----- rtl/axis_arb_mux_4.v | 267 ++++++++++++++++++++++++++--------- tb/test_axis_arb_mux_4_64.py | 6 +- 3 files changed, 370 insertions(+), 105 deletions(-) diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py index 7598cfcb6..59025e212 100755 --- a/rtl/axis_arb_mux.py +++ b/rtl/axis_arb_mux.py @@ -120,49 +120,59 @@ wire [{{n-1}}:0] acknowledge; wire [{{n-1}}:0] grant; wire grant_valid; wire [{{w-1}}:0] grant_encoded; + +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg [ID_WIDTH-1:0] output_axis_tid_int; +reg [DEST_WIDTH-1:0] output_axis_tdest_int; +reg [USER_WIDTH-1:0] output_axis_tuser_int; +wire output_axis_tready_int_early; {% for p in ports %} -assign acknowledge[{{p}}] = input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast; -assign request[{{p}}] = input_{{p}}_axis_tvalid & ~acknowledge[{{p}}]; +assign input_{{p}}_axis_tready = grant[{{p}}] & output_axis_tready_int_reg; {%- endfor %} -// mux instance -axis_mux_{{n}} #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_ENABLE(KEEP_ENABLE), - .KEEP_WIDTH(KEEP_WIDTH), - .ID_ENABLE(ID_ENABLE), - .ID_WIDTH(ID_WIDTH), - .DEST_ENABLE(DEST_ENABLE), - .DEST_WIDTH(DEST_WIDTH), - .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) -) -mux_inst ( - .clk(clk), - .rst(rst), +// mux for incoming packet +reg [DATA_WIDTH-1:0] current_input_tdata; +reg [KEEP_WIDTH-1:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg [ID_WIDTH-1:0] current_input_tid; +reg [DEST_WIDTH-1:0] current_input_tdest; +reg [USER_WIDTH-1:0] current_input_tuser; +always @* begin + case (grant_encoded) {%- for p in ports %} - .input_{{p}}_axis_tdata(input_{{p}}_axis_tdata), - .input_{{p}}_axis_tkeep(input_{{p}}_axis_tkeep), - .input_{{p}}_axis_tvalid(input_{{p}}_axis_tvalid & grant[{{p}}]), - .input_{{p}}_axis_tready(input_{{p}}_axis_tready), - .input_{{p}}_axis_tlast(input_{{p}}_axis_tlast), - .input_{{p}}_axis_tid(input_{{p}}_axis_tid), - .input_{{p}}_axis_tdest(input_{{p}}_axis_tdest), - .input_{{p}}_axis_tuser(input_{{p}}_axis_tuser), + {{w}}'d{{p}}: begin + current_input_tdata = input_{{p}}_axis_tdata; + current_input_tkeep = input_{{p}}_axis_tkeep; + current_input_tvalid = input_{{p}}_axis_tvalid; + current_input_tready = input_{{p}}_axis_tready; + current_input_tlast = input_{{p}}_axis_tlast; + current_input_tid = input_{{p}}_axis_tid; + current_input_tdest = input_{{p}}_axis_tdest; + current_input_tuser = input_{{p}}_axis_tuser; + end {%- endfor %} - .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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), - .enable(grant_valid), - .select(grant_encoded) -); + default: begin + current_input_tdata = {DATA_WIDTH{1'b0}}; + current_input_tkeep = {KEEP_WIDTH{1'b0}}; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tid = {ID_WIDTH{1'b0}}; + current_input_tdest = {DEST_WIDTH{1'b0}}; + current_input_tuser = {USER_WIDTH{1'b0}}; + end + endcase +end // arbiter instance + arbiter #( .PORTS({{n}}), .TYPE(ARB_TYPE), @@ -179,6 +189,126 @@ arb_inst ( .grant_encoded(grant_encoded) ); +// request generation +{%- for p in ports %} +assign request[{{p}}] = input_{{p}}_axis_tvalid & ~acknowledge[{{p}}]; +{%- endfor %} + +// acknowledge generation +{%- for p in ports %} +assign acknowledge[{{p}}] = grant[{{p}}] & input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast; +{%- endfor %} + +always @* begin + // pass through selected packet data + output_axis_tdata_int = current_input_tdata; + output_axis_tkeep_int = current_input_tkeep; + output_axis_tvalid_int = current_input_tvalid & current_input_tready; + output_axis_tlast_int = current_input_tlast; + output_axis_tid_int = current_input_tid; + output_axis_tdest_int = current_input_tdest; + output_axis_tuser_int = current_input_tuser; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tid_reg <= output_axis_tid_int; + output_axis_tdest_reg <= output_axis_tdest_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tid_reg <= output_axis_tid_int; + temp_axis_tdest_reg <= output_axis_tdest_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end +end + endmodule """) diff --git a/rtl/axis_arb_mux_4.v b/rtl/axis_arb_mux_4.v index a7de9bfb2..b572e6410 100644 --- a/rtl/axis_arb_mux_4.v +++ b/rtl/axis_arb_mux_4.v @@ -107,75 +107,88 @@ wire [3:0] grant; wire grant_valid; wire [1:0] grant_encoded; -assign acknowledge[0] = input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign request[0] = input_0_axis_tvalid & ~acknowledge[0]; -assign acknowledge[1] = input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign request[1] = input_1_axis_tvalid & ~acknowledge[1]; -assign acknowledge[2] = input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign request[2] = input_2_axis_tvalid & ~acknowledge[2]; -assign acknowledge[3] = input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; -assign request[3] = input_3_axis_tvalid & ~acknowledge[3]; +// internal datapath +reg [DATA_WIDTH-1:0] output_axis_tdata_int; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; +reg output_axis_tvalid_int; +reg output_axis_tready_int_reg = 1'b0; +reg output_axis_tlast_int; +reg [ID_WIDTH-1:0] output_axis_tid_int; +reg [DEST_WIDTH-1:0] output_axis_tdest_int; +reg [USER_WIDTH-1:0] output_axis_tuser_int; +wire output_axis_tready_int_early; -// mux instance -axis_mux_4 #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_ENABLE(KEEP_ENABLE), - .KEEP_WIDTH(KEEP_WIDTH), - .ID_ENABLE(ID_ENABLE), - .ID_WIDTH(ID_WIDTH), - .DEST_ENABLE(DEST_ENABLE), - .DEST_WIDTH(DEST_WIDTH), - .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) -) -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tkeep(input_0_axis_tkeep), - .input_0_axis_tvalid(input_0_axis_tvalid & grant[0]), - .input_0_axis_tready(input_0_axis_tready), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tid(input_0_axis_tid), - .input_0_axis_tdest(input_0_axis_tdest), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tkeep(input_1_axis_tkeep), - .input_1_axis_tvalid(input_1_axis_tvalid & grant[1]), - .input_1_axis_tready(input_1_axis_tready), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tid(input_1_axis_tid), - .input_1_axis_tdest(input_1_axis_tdest), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tkeep(input_2_axis_tkeep), - .input_2_axis_tvalid(input_2_axis_tvalid & grant[2]), - .input_2_axis_tready(input_2_axis_tready), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tid(input_2_axis_tid), - .input_2_axis_tdest(input_2_axis_tdest), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tkeep(input_3_axis_tkeep), - .input_3_axis_tvalid(input_3_axis_tvalid & grant[3]), - .input_3_axis_tready(input_3_axis_tready), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tid(input_3_axis_tid), - .input_3_axis_tdest(input_3_axis_tdest), - .input_3_axis_tuser(input_3_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), - .enable(grant_valid), - .select(grant_encoded) -); +assign input_0_axis_tready = grant[0] & output_axis_tready_int_reg; +assign input_1_axis_tready = grant[1] & output_axis_tready_int_reg; +assign input_2_axis_tready = grant[2] & output_axis_tready_int_reg; +assign input_3_axis_tready = grant[3] & output_axis_tready_int_reg; + +// mux for incoming packet +reg [DATA_WIDTH-1:0] current_input_tdata; +reg [KEEP_WIDTH-1:0] current_input_tkeep; +reg current_input_tvalid; +reg current_input_tready; +reg current_input_tlast; +reg [ID_WIDTH-1:0] current_input_tid; +reg [DEST_WIDTH-1:0] current_input_tdest; +reg [USER_WIDTH-1:0] current_input_tuser; +always @* begin + case (grant_encoded) + 2'd0: begin + current_input_tdata = input_0_axis_tdata; + current_input_tkeep = input_0_axis_tkeep; + current_input_tvalid = input_0_axis_tvalid; + current_input_tready = input_0_axis_tready; + current_input_tlast = input_0_axis_tlast; + current_input_tid = input_0_axis_tid; + current_input_tdest = input_0_axis_tdest; + current_input_tuser = input_0_axis_tuser; + end + 2'd1: begin + current_input_tdata = input_1_axis_tdata; + current_input_tkeep = input_1_axis_tkeep; + current_input_tvalid = input_1_axis_tvalid; + current_input_tready = input_1_axis_tready; + current_input_tlast = input_1_axis_tlast; + current_input_tid = input_1_axis_tid; + current_input_tdest = input_1_axis_tdest; + current_input_tuser = input_1_axis_tuser; + end + 2'd2: begin + current_input_tdata = input_2_axis_tdata; + current_input_tkeep = input_2_axis_tkeep; + current_input_tvalid = input_2_axis_tvalid; + current_input_tready = input_2_axis_tready; + current_input_tlast = input_2_axis_tlast; + current_input_tid = input_2_axis_tid; + current_input_tdest = input_2_axis_tdest; + current_input_tuser = input_2_axis_tuser; + end + 2'd3: begin + current_input_tdata = input_3_axis_tdata; + current_input_tkeep = input_3_axis_tkeep; + current_input_tvalid = input_3_axis_tvalid; + current_input_tready = input_3_axis_tready; + current_input_tlast = input_3_axis_tlast; + current_input_tid = input_3_axis_tid; + current_input_tdest = input_3_axis_tdest; + current_input_tuser = input_3_axis_tuser; + end + default: begin + current_input_tdata = {DATA_WIDTH{1'b0}}; + current_input_tkeep = {KEEP_WIDTH{1'b0}}; + current_input_tvalid = 1'b0; + current_input_tready = 1'b0; + current_input_tlast = 1'b0; + current_input_tid = {ID_WIDTH{1'b0}}; + current_input_tdest = {DEST_WIDTH{1'b0}}; + current_input_tuser = {USER_WIDTH{1'b0}}; + end + endcase +end // arbiter instance + arbiter #( .PORTS(4), .TYPE(ARB_TYPE), @@ -192,4 +205,126 @@ arb_inst ( .grant_encoded(grant_encoded) ); +// request generation +assign request[0] = input_0_axis_tvalid & ~acknowledge[0]; +assign request[1] = input_1_axis_tvalid & ~acknowledge[1]; +assign request[2] = input_2_axis_tvalid & ~acknowledge[2]; +assign request[3] = input_3_axis_tvalid & ~acknowledge[3]; + +// acknowledge generation +assign acknowledge[0] = grant[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; +assign acknowledge[1] = grant[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; +assign acknowledge[2] = grant[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; +assign acknowledge[3] = grant[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; + +always @* begin + // pass through selected packet data + output_axis_tdata_int = current_input_tdata; + output_axis_tkeep_int = current_input_tkeep; + output_axis_tvalid_int = current_input_tvalid & current_input_tready; + output_axis_tlast_int = current_input_tlast; + output_axis_tid_int = current_input_tid; + output_axis_tdest_int = current_input_tdest; + output_axis_tuser_int = current_input_tuser; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; +reg temp_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + output_axis_tvalid_next = output_axis_tvalid_reg; + temp_axis_tvalid_next = temp_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (output_axis_tready_int_reg) begin + // input is ready + if (output_axis_tready | ~output_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + output_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_axis_tvalid_next = output_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (output_axis_tready) begin + // input is not ready, but output is ready + output_axis_tvalid_next = temp_axis_tvalid_reg; + temp_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + output_axis_tvalid_reg <= 1'b0; + output_axis_tready_int_reg <= 1'b0; + temp_axis_tvalid_reg <= 1'b0; + end else begin + output_axis_tvalid_reg <= output_axis_tvalid_next; + output_axis_tready_int_reg <= output_axis_tready_int_early; + temp_axis_tvalid_reg <= temp_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + output_axis_tdata_reg <= output_axis_tdata_int; + output_axis_tkeep_reg <= output_axis_tkeep_int; + output_axis_tlast_reg <= output_axis_tlast_int; + output_axis_tid_reg <= output_axis_tid_int; + output_axis_tdest_reg <= output_axis_tdest_int; + output_axis_tuser_reg <= output_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + output_axis_tdata_reg <= temp_axis_tdata_reg; + output_axis_tkeep_reg <= temp_axis_tkeep_reg; + output_axis_tlast_reg <= temp_axis_tlast_reg; + output_axis_tid_reg <= temp_axis_tid_reg; + output_axis_tdest_reg <= temp_axis_tdest_reg; + output_axis_tuser_reg <= temp_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_axis_tdata_reg <= output_axis_tdata_int; + temp_axis_tkeep_reg <= output_axis_tkeep_int; + temp_axis_tlast_reg <= output_axis_tlast_int; + temp_axis_tid_reg <= output_axis_tid_int; + temp_axis_tdest_reg <= output_axis_tdest_int; + temp_axis_tuser_reg <= output_axis_tuser_int; + end +end + endmodule diff --git a/tb/test_axis_arb_mux_4_64.py b/tb/test_axis_arb_mux_4_64.py index 0cf7c09f7..03c6faf8a 100755 --- a/tb/test_axis_arb_mux_4_64.py +++ b/tb/test_axis_arb_mux_4_64.py @@ -509,7 +509,7 @@ def bench(): source_2.send(test_frame2) yield clk.posedge - yield delay(150) + yield delay(100) yield clk.posedge source_1.send(test_frame1) @@ -531,12 +531,12 @@ def bench(): yield sink.wait() rx_frame = sink.recv() - assert rx_frame == test_frame2 + assert rx_frame == test_frame1 yield sink.wait() rx_frame = sink.recv() - assert rx_frame == test_frame1 + assert rx_frame == test_frame2 yield sink.wait() rx_frame = sink.recv() From becfbf44252f038fe1e9131f943ed7e81f3e17ea Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 15 Aug 2018 00:11:39 -0700 Subject: [PATCH 406/617] When pausing the AXI stream model, do not drop tvalid if it is asserted and waiting for tready to be asserted --- tb/axis_ep.py | 74 +++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 351df0b49..67417520e 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -282,22 +282,14 @@ class AXIStreamSource(object): self.has_logic = True - tready_int = Signal(bool(False)) - tvalid_int = Signal(bool(False)) - - @always_comb - def pause_logic(): - tready_int.next = tready and not pause - tvalid.next = tvalid_int and not pause - @instance def logic(): - frame = AXIStreamFrame() data = [] keep = [] id = [] dest = [] user = [] + valid = False B = 0 N = len(tdata) M = len(tkeep) @@ -314,6 +306,12 @@ class AXIStreamSource(object): yield clk.posedge, rst.posedge if rst: + data = [] + keep = [] + id = [] + dest = [] + user = [] + valid = False if B > 0: for s in tdata: s.next = 0 @@ -323,10 +321,11 @@ class AXIStreamSource(object): tid.next = 0 tdest.next = 0 tuser.next = False - tvalid_int.next = False + tvalid.next = False tlast.next = False else: - if tready_int and tvalid: + tvalid.next = valid and (tvalid or not pause) + if tready and tvalid: if len(data) > 0: if B > 0: l = data.pop(0) @@ -338,33 +337,34 @@ class AXIStreamSource(object): tid.next = id.pop(0) tdest.next = dest.pop(0) tuser.next = user.pop(0) - tvalid_int.next = True + tvalid.next = not pause tlast.next = len(data) == 0 else: - tvalid_int.next = False + tvalid.next = False tlast.next = False - if (tlast and tready_int and tvalid) or not tvalid_int: - if self.queue: - frame = self.queue.pop(0) - frame.B = B - frame.N = N - frame.M = M - frame.WL = WL - data, keep, id, dest, user = frame.build() - if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) - if B > 0: - l = data.pop(0) - for i in range(B): - tdata[i].next = l[i] - else: - tdata.next = data.pop(0) - tkeep.next = keep.pop(0) - tid.next = id.pop(0) - tdest.next = dest.pop(0) - tuser.next = user.pop(0) - tvalid_int.next = True - tlast.next = len(data) == 0 + valid = False + if not valid and self.queue: + frame = self.queue.pop(0) + frame.B = B + frame.N = N + frame.M = M + frame.WL = WL + data, keep, id, dest, user = frame.build() + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + if B > 0: + l = data.pop(0) + for i in range(B): + tdata[i].next = l[i] + else: + tdata.next = data.pop(0) + tkeep.next = keep.pop(0) + tid.next = id.pop(0) + tdest.next = dest.pop(0) + tuser.next = user.pop(0) + tvalid.next = not pause + tlast.next = len(data) == 0 + valid = True return instances() @@ -433,7 +433,6 @@ class AXIStreamSink(object): @instance def logic(): - frame = AXIStreamFrame() data = [] keep = [] id = [] @@ -457,7 +456,6 @@ class AXIStreamSink(object): if rst: tready_int.next = False - frame = AXIStreamFrame() data = [] keep = [] id = [] @@ -501,6 +499,7 @@ class AXIStreamSink(object): user.append(int(tuser)) first = False if tlast: + frame = AXIStreamFrame() frame.B = B frame.N = N frame.M = M @@ -510,7 +509,6 @@ class AXIStreamSink(object): self.sync.next = not self.sync if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) - frame = AXIStreamFrame() data = [] keep = [] id = [] From 553547f661f54153e618ebf8297f6e4f92253e6e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 9 Sep 2018 13:52:13 -0700 Subject: [PATCH 407/617] Fix test naming --- tb/test_arbiter_rr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tb/test_arbiter_rr.py b/tb/test_arbiter_rr.py index 983ef5566..5624e41f8 100755 --- a/tb/test_arbiter_rr.py +++ b/tb/test_arbiter_rr.py @@ -27,13 +27,13 @@ from myhdl import * import os module = 'arbiter' -testbench = 'test_%s' % module +testbench = 'test_%s_rr' % module srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/priority_encoder.v") -srcs.append("%s_rr.v" % testbench) +srcs.append("%s.v" % testbench) src = ' '.join(srcs) From 5e12f975185b8456ce00c7022c508e13db7fc791 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 19 Oct 2018 15:24:33 -0700 Subject: [PATCH 408/617] MAC optimizations --- rtl/eth_mac_10g_rx.v | 17 +++++++++++------ rtl/eth_mac_10g_tx.v | 17 ++++++++++++++--- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v index 04d63e3f1..89f5ff34a 100644 --- a/rtl/eth_mac_10g_rx.v +++ b/rtl/eth_mac_10g_rx.v @@ -126,7 +126,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(last_cycle ? xgmii_rxd_d1[39:32] : xgmii_rxd_d0[7:0]), + .data_in(xgmii_rxd_d0[7:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next0) @@ -142,7 +142,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_16 ( - .data_in(last_cycle ? xgmii_rxd_d1[47:32] : xgmii_rxd_d0[15:0]), + .data_in(xgmii_rxd_d0[15:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next1) @@ -158,7 +158,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_24 ( - .data_in(last_cycle ? xgmii_rxd_d1[55:32] : xgmii_rxd_d0[23:0]), + .data_in(xgmii_rxd_d0[23:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next2) @@ -174,7 +174,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_32 ( - .data_in(last_cycle ? xgmii_rxd_d1[63:32] : xgmii_rxd_d0[31:0]), + .data_in(xgmii_rxd_d0[31:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next3) @@ -423,8 +423,8 @@ always @(posedge clk) begin xgmii_rxc_d0 <= xgmii_rxc; end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == 8'hfb) begin lanes_swapped <= 1'b1; - xgmii_rxd_d0 <= 64'h0707070707070707; - xgmii_rxc_d0 <= 8'b11111111; + xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; + xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; end else if (lanes_swapped) begin xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; @@ -433,6 +433,11 @@ always @(posedge clk) begin xgmii_rxc_d0 <= xgmii_rxc; end + if (state_next == STATE_LAST) begin + xgmii_rxd_d0[31:0] <= xgmii_rxd_d0[63:32]; + xgmii_rxc_d0[3:0] <= xgmii_rxc_d0[7:4]; + end + xgmii_rxd_d1 <= xgmii_rxd_d0; xgmii_rxc_d1 <= xgmii_rxc_d0; diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v index 77da1089b..aeb99a752 100644 --- a/rtl/eth_mac_10g_tx.v +++ b/rtl/eth_mac_10g_tx.v @@ -99,6 +99,8 @@ reg [7:0] fcs_output_txc_1; reg [7:0] ifg_offset; +reg extra_cycle; + reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; reg [7:0] ifg_count_reg = 8'd0, ifg_count_next; @@ -301,6 +303,7 @@ always @* begin fcs_output_txc_0 = 8'b11100000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd3; + extra_cycle = 1'b0; end 8'bzzzzz011: begin fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], input_tdata_reg[15:0]}; @@ -308,6 +311,7 @@ always @* begin fcs_output_txc_0 = 8'b11000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd2; + extra_cycle = 1'b0; end 8'bzzzz0111: begin fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], input_tdata_reg[23:0]}; @@ -315,6 +319,7 @@ always @* begin fcs_output_txc_0 = 8'b10000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd1; + extra_cycle = 1'b0; end 8'bzzz01111: begin fcs_output_txd_0 = {~crc_next3[31:0], input_tdata_reg[31:0]}; @@ -322,6 +327,7 @@ always @* begin fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd8; + extra_cycle = 1'b1; end 8'bzz011111: begin fcs_output_txd_0 = {~crc_next4[23:0], input_tdata_reg[39:0]}; @@ -329,6 +335,7 @@ always @* begin fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111110; ifg_offset = 8'd7; + extra_cycle = 1'b1; end 8'bz0111111: begin fcs_output_txd_0 = {~crc_next5[15:0], input_tdata_reg[47:0]}; @@ -336,6 +343,7 @@ always @* begin fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111100; ifg_offset = 8'd6; + extra_cycle = 1'b1; end 8'b01111111: begin fcs_output_txd_0 = {~crc_next6[7:0], input_tdata_reg[55:0]}; @@ -343,6 +351,7 @@ always @* begin fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111000; ifg_offset = 8'd5; + extra_cycle = 1'b1; end 8'b11111111: begin fcs_output_txd_0 = input_tdata_reg; @@ -350,6 +359,7 @@ always @* begin fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11110000; ifg_offset = 8'd4; + extra_cycle = 1'b1; end default: begin fcs_output_txd_0 = 64'd0; @@ -357,6 +367,7 @@ always @* begin fcs_output_txc_0 = 8'd0; fcs_output_txc_1 = 8'd0; ifg_offset = 8'd0; + extra_cycle = 1'b1; end endcase end @@ -500,7 +511,7 @@ always @* begin frame_ptr_next = 16'd0; ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + (lanes_swapped ? 8'd4 : 8'd0) + deficit_idle_count_reg; - if (fcs_output_txc_1 != 8'hff || fcs_output_txc_0 == 8'd0) begin + if (extra_cycle) begin state_next = STATE_FCS_2; end else begin state_next = STATE_IFG; @@ -652,8 +663,8 @@ always @(posedge clk) begin end else begin if (swap_lanes) begin lanes_swapped <= 1'b1; - xgmii_txd_reg <= {xgmii_txd_next[31:0], 32'h07070707}; - xgmii_txc_reg <= {xgmii_txc_next[3:0], 4'b1111}; + xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd}; + xgmii_txc_reg <= {xgmii_txc_next[3:0], swap_txc}; end else begin xgmii_txd_reg <= xgmii_txd_next; xgmii_txc_reg <= xgmii_txc_next; From fbe698ebb707ac6ee19ef89a42aceaa3b99185c6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 19 Oct 2018 15:31:47 -0700 Subject: [PATCH 409/617] Update Ethernet MAC testbenches --- tb/test_eth_mac_10g_rx.py | 52 +++++++++++++++++++++++++++++++++------ tb/test_eth_mac_10g_tx.py | 20 +++++++++------ 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/tb/test_eth_mac_10g_rx.py b/tb/test_eth_mac_10g_rx.py index 55d32f454..f792cc211 100755 --- a/tb/test_eth_mac_10g_rx.py +++ b/tb/test_eth_mac_10g_rx.py @@ -341,18 +341,56 @@ def bench(): source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - yield clk.posedge - yield clk.posedge + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() - while xgmii_rxc != 0xff or output_axis_tvalid or not source.empty(): - yield clk.posedge + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() - yield clk.posedge - yield clk.posedge - yield clk.posedge + assert eth_frame == test_frame yield delay(100) + yield clk.posedge + print("test 6: Ensure 0xfb in FCS in lane 4 is not detected as start code in lane 0") + current_test.next = 6 + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x806f + test_frame.payload = bytearray(range(60)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + source.send(xgmii_frame) + + yield sink.wait() + rx_frame = sink.recv() + + assert not error_bad_frame_asserted + assert not error_bad_fcs_asserted + + assert not rx_frame.last_cycle_user + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + assert sink.empty() + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_eth_mac_10g_tx.py b/tb/test_eth_mac_10g_tx.py index 1b6ba6238..0bcf42df0 100755 --- a/tb/test_eth_mac_10g_tx.py +++ b/tb/test_eth_mac_10g_tx.py @@ -309,15 +309,21 @@ def bench(): source.send(axis_frame) - yield clk.posedge - yield clk.posedge + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() - while xgmii_txc != 0xff or input_axis_tvalid: - yield clk.posedge + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - yield clk.posedge - yield clk.posedge - yield clk.posedge + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 yield delay(100) From 030fe90bf5a40c7f74d8f2968f4754c835372ab0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 19 Oct 2018 15:33:25 -0700 Subject: [PATCH 410/617] Fix example design testbench --- example/VCU118/fpga_10g/tb/test_fpga_core.py | 32 ++++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/example/VCU118/fpga_10g/tb/test_fpga_core.py b/example/VCU118/fpga_10g/tb/test_fpga_core.py index 7c63bd06d..8226bb74e 100755 --- a/example/VCU118/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU118/fpga_10g/tb/test_fpga_core.py @@ -204,29 +204,29 @@ def bench(): qsfp1_4_sink = xgmii_ep.XGMIISink() qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') - qsfp1_1_source = xgmii_ep.XGMIISource() - qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') + qsfp2_1_source = xgmii_ep.XGMIISource() + qsfp2_1_source_logic = qsfp2_1_source.create_logic(qsfp2_rx_clk_1, qsfp2_rx_rst_1, txd=qsfp2_rxd_1, txc=qsfp2_rxc_1, name='qsfp2_1_source') - qsfp1_1_sink = xgmii_ep.XGMIISink() - qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') + qsfp2_1_sink = xgmii_ep.XGMIISink() + qsfp2_1_sink_logic = qsfp2_1_sink.create_logic(qsfp2_tx_clk_1, qsfp2_tx_rst_1, rxd=qsfp2_txd_1, rxc=qsfp2_txc_1, name='qsfp2_1_sink') - qsfp1_2_source = xgmii_ep.XGMIISource() - qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') + qsfp2_2_source = xgmii_ep.XGMIISource() + qsfp2_2_source_logic = qsfp2_2_source.create_logic(qsfp2_rx_clk_2, qsfp2_rx_rst_2, txd=qsfp2_rxd_2, txc=qsfp2_rxc_2, name='qsfp2_2_source') - qsfp1_2_sink = xgmii_ep.XGMIISink() - qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') + qsfp2_2_sink = xgmii_ep.XGMIISink() + qsfp2_2_sink_logic = qsfp2_2_sink.create_logic(qsfp2_tx_clk_2, qsfp2_tx_rst_2, rxd=qsfp2_txd_2, rxc=qsfp2_txc_2, name='qsfp2_2_sink') - qsfp1_3_source = xgmii_ep.XGMIISource() - qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') + qsfp2_3_source = xgmii_ep.XGMIISource() + qsfp2_3_source_logic = qsfp2_3_source.create_logic(qsfp2_rx_clk_3, qsfp2_rx_rst_3, txd=qsfp2_rxd_3, txc=qsfp2_rxc_3, name='qsfp2_3_source') - qsfp1_3_sink = xgmii_ep.XGMIISink() - qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') + qsfp2_3_sink = xgmii_ep.XGMIISink() + qsfp2_3_sink_logic = qsfp2_3_sink.create_logic(qsfp2_tx_clk_3, qsfp2_tx_rst_3, rxd=qsfp2_txd_3, rxc=qsfp2_txc_3, name='qsfp2_3_sink') - qsfp1_4_source = xgmii_ep.XGMIISource() - qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') + qsfp2_4_source = xgmii_ep.XGMIISource() + qsfp2_4_source_logic = qsfp2_4_source.create_logic(qsfp2_rx_clk_4, qsfp2_rx_rst_4, txd=qsfp2_rxd_4, txc=qsfp2_rxc_4, name='qsfp2_4_source') - qsfp1_4_sink = xgmii_ep.XGMIISink() - qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') + qsfp2_4_sink = xgmii_ep.XGMIISink() + qsfp2_4_sink_logic = qsfp2_4_sink.create_logic(qsfp2_tx_clk_4, qsfp2_tx_rst_4, rxd=qsfp2_txd_4, rxc=qsfp2_txc_4, name='qsfp2_4_sink') gmii_source = gmii_ep.GMIISource() From de699758722a30c534d0ce2107a2d9340046689a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 23 Oct 2018 23:34:43 -0700 Subject: [PATCH 411/617] Add AXI stream XGMII RX and TX modules and testbenches --- rtl/axis_xgmii_rx_32.v | 415 ++++++++++++++++++++++ rtl/axis_xgmii_rx_64.v | 476 +++++++++++++++++++++++++ rtl/axis_xgmii_tx_32.v | 549 ++++++++++++++++++++++++++++ rtl/axis_xgmii_tx_64.v | 691 ++++++++++++++++++++++++++++++++++++ tb/test_axis_xgmii_rx_32.py | 364 +++++++++++++++++++ tb/test_axis_xgmii_rx_32.v | 92 +++++ tb/test_axis_xgmii_rx_64.py | 402 +++++++++++++++++++++ tb/test_axis_xgmii_rx_64.v | 92 +++++ tb/test_axis_xgmii_tx_32.py | 340 ++++++++++++++++++ tb/test_axis_xgmii_tx_32.v | 97 +++++ tb/test_axis_xgmii_tx_64.py | 340 ++++++++++++++++++ tb/test_axis_xgmii_tx_64.v | 97 +++++ 12 files changed, 3955 insertions(+) create mode 100644 rtl/axis_xgmii_rx_32.v create mode 100644 rtl/axis_xgmii_rx_64.v create mode 100644 rtl/axis_xgmii_tx_32.v create mode 100644 rtl/axis_xgmii_tx_64.v create mode 100755 tb/test_axis_xgmii_rx_32.py create mode 100644 tb/test_axis_xgmii_rx_32.v create mode 100755 tb/test_axis_xgmii_rx_64.py create mode 100644 tb/test_axis_xgmii_rx_64.v create mode 100755 tb/test_axis_xgmii_tx_32.py create mode 100644 tb/test_axis_xgmii_tx_32.v create mode 100755 tb/test_axis_xgmii_tx_64.py create mode 100644 tb/test_axis_xgmii_tx_64.v diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v new file mode 100644 index 000000000..aa8f4a9c3 --- /dev/null +++ b/rtl/axis_xgmii_rx_32.v @@ -0,0 +1,415 @@ +/* + +Copyright (c) 2015-2017 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 XGMII frame receiver (XGMII in, AXI out) + */ +module axis_xgmii_rx_32 +( + input wire clk, + input wire rst, + + /* + * XGMII input + */ + input wire [31:0] xgmii_rxd, + input wire [3:0] xgmii_rxc, + + /* + * AXI output + */ + output wire [31:0] output_axis_tdata, + output wire [3:0] output_axis_tkeep, + output wire output_axis_tvalid, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Status + */ + output wire error_bad_frame, + output wire error_bad_fcs +); + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PREAMBLE = 3'd1, + STATE_PAYLOAD = 3'd2, + STATE_LAST = 3'd3; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg [3:0] last_cycle_tkeep_reg = 4'd0, last_cycle_tkeep_next; + +reg [31:0] xgmii_rxd_d0 = 32'd0; +reg [31:0] xgmii_rxd_d1 = 32'd0; +reg [31:0] xgmii_rxd_d2 = 32'd0; + +reg [3:0] xgmii_rxc_d0 = 4'd0; +reg [3:0] xgmii_rxc_d1 = 4'd0; +reg [3:0] xgmii_rxc_d2 = 4'd0; + +reg [31:0] output_axis_tdata_reg = 32'd0, output_axis_tdata_next; +reg [3:0] output_axis_tkeep_reg = 4'd0, output_axis_tkeep_next; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0, output_axis_tlast_next; +reg output_axis_tuser_reg = 1'b0, output_axis_tuser_next; + +reg error_bad_frame_reg = 1'b0, error_bad_frame_next; +reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; + +wire crc_valid0 = crc_next0 == ~32'h2144df1c; +wire crc_valid1 = crc_next1 == ~32'h2144df1c; +wire crc_valid2 = crc_next2 == ~32'h2144df1c; +wire crc_valid3 = crc_next3 == ~32'h2144df1c; + +reg crc_valid0_save = 1'b0; +reg crc_valid1_save = 1'b0; +reg crc_valid2_save = 1'b0; +reg crc_valid3_save = 1'b0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +assign error_bad_frame = error_bad_frame_reg; +assign error_bad_fcs = error_bad_fcs_reg; + +wire last_cycle = state_reg == STATE_LAST; + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(8), + .STYLE("AUTO") +) +eth_crc_8 ( + .data_in(xgmii_rxd_d0[7:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next0) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(16), + .STYLE("AUTO") +) +eth_crc_16 ( + .data_in(xgmii_rxd_d0[15:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next1) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(24), + .STYLE("AUTO") +) +eth_crc_24 ( + .data_in(xgmii_rxd_d0[23:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next2) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( + .data_in(xgmii_rxd_d0[31:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next3) +); + +// detect control characters +reg [3:0] detect_start; +reg [3:0] detect_term; +reg [3:0] detect_error; + +reg [3:0] detect_term_save; + +integer i; + +always @* begin + for (i = 0; i < 4; i = i + 1) begin + detect_start[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfb); + detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfd); + detect_error[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfe); + end +end + +// mask errors to within packet +reg [3:0] detect_error_masked; +reg [3:0] control_masked; +reg [3:0] tkeep_mask; + +always @* begin + casez (detect_term) + 4'b0000: begin + detect_error_masked = detect_error; + control_masked = xgmii_rxc_d0; + tkeep_mask = 4'b1111; + end + 4'bzzz1: begin + detect_error_masked = 0; + control_masked = 0; + tkeep_mask = 4'b0000; + end + 4'bzz10: begin + detect_error_masked = detect_error[0]; + control_masked = xgmii_rxc_d0[0]; + tkeep_mask = 4'b0001; + end + 4'bz100: begin + detect_error_masked = detect_error[1:0]; + control_masked = xgmii_rxc_d0[1:0]; + tkeep_mask = 4'b0011; + end + 4'b1000: begin + detect_error_masked = detect_error[2:0]; + control_masked = xgmii_rxc_d0[2:0]; + tkeep_mask = 4'b0111; + end + default: begin + detect_error_masked = detect_error; + control_masked = xgmii_rxc_d0; + tkeep_mask = 4'b1111; + end + endcase +end + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 1'b0; + update_crc = 1'b0; + + last_cycle_tkeep_next = last_cycle_tkeep_reg; + + output_axis_tdata_next = 32'd0; + output_axis_tkeep_next = 4'd0; + output_axis_tvalid_next = 1'b0; + output_axis_tlast_next = 1'b0; + output_axis_tuser_next = 1'b0; + + error_bad_frame_next = 1'b0; + error_bad_fcs_next = 1'b0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for packet + reset_crc = 1'b1; + + if (xgmii_rxc_d2[0] && xgmii_rxd_d2[7:0] == 8'hfb) begin + // start condition + if (detect_error_masked) begin + // error in first data word + output_axis_tdata_next = 32'd0; + output_axis_tkeep_next = 4'h1; + output_axis_tvalid_next = 1'b1; + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + state_next = STATE_IDLE; + end else begin + reset_crc = 1'b0; + update_crc = 1'b1; + state_next = STATE_PREAMBLE; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_PREAMBLE: begin + // drop preamble + update_crc = 1'b1; + state_next = STATE_PAYLOAD; + end + STATE_PAYLOAD: begin + // read payload + update_crc = 1'b1; + + output_axis_tdata_next = xgmii_rxd_d2; + output_axis_tkeep_next = ~xgmii_rxc_d2; + output_axis_tvalid_next = 1'b1; + output_axis_tlast_next = 1'b0; + output_axis_tuser_next = 1'b0; + + if (control_masked) begin + // control or error characters in packet + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + reset_crc = 1'b1; + state_next = STATE_IDLE; + end else if (detect_term) begin + if (detect_term[0]) begin + // end this cycle + reset_crc = 1'b1; + output_axis_tkeep_next = 4'b1111; + output_axis_tlast_next = 1'b1; + if (detect_term[0] & crc_valid3_save) begin + // CRC valid + end else begin + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; + end + state_next = STATE_IDLE; + end else begin + // need extra cycle + last_cycle_tkeep_next = tkeep_mask; + state_next = STATE_LAST; + end + end else begin + state_next = STATE_PAYLOAD; + end + end + STATE_LAST: begin + // last cycle of packet + output_axis_tdata_next = xgmii_rxd_d2; + output_axis_tkeep_next = last_cycle_tkeep_reg; + output_axis_tvalid_next = 1'b1; + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b0; + + reset_crc = 1'b1; + + if ((detect_term_save[1] & crc_valid0_save) || + (detect_term_save[2] & crc_valid1_save) || + (detect_term_save[3] & crc_valid2_save)) begin + // CRC valid + end else begin + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; + end + + if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin + // start condition + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_IDLE; + end + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + output_axis_tvalid_reg <= 1'b0; + + error_bad_frame_reg <= 1'b0; + error_bad_fcs_reg <= 1'b0; + + crc_state <= 32'hFFFFFFFF; + crc_valid0_save <= 1'b0; + crc_valid1_save <= 1'b0; + crc_valid2_save <= 1'b0; + crc_valid3_save <= 1'b0; + + xgmii_rxc_d0 <= 4'd0; + xgmii_rxc_d1 <= 4'd0; + end else begin + state_reg <= state_next; + + output_axis_tvalid_reg <= output_axis_tvalid_next; + + error_bad_frame_reg <= error_bad_frame_next; + error_bad_fcs_reg <= error_bad_fcs_next; + + xgmii_rxc_d0 <= xgmii_rxc; + xgmii_rxc_d1 <= xgmii_rxc_d0; + xgmii_rxc_d2 <= xgmii_rxc_d1; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + crc_valid0_save <= 1'b0; + crc_valid1_save <= 1'b0; + crc_valid2_save <= 1'b0; + crc_valid3_save <= 1'b0; + end else if (update_crc) begin + crc_state <= crc_next3; + crc_valid0_save <= crc_valid0; + crc_valid1_save <= crc_valid1; + crc_valid2_save <= crc_valid2; + crc_valid3_save <= crc_valid3; + end + end + + output_axis_tdata_reg <= output_axis_tdata_next; + output_axis_tkeep_reg <= output_axis_tkeep_next; + output_axis_tlast_reg <= output_axis_tlast_next; + output_axis_tuser_reg <= output_axis_tuser_next; + + last_cycle_tkeep_reg <= last_cycle_tkeep_next; + + detect_term_save <= detect_term; + + xgmii_rxd_d0 <= xgmii_rxd; + xgmii_rxd_d1 <= xgmii_rxd_d0; + xgmii_rxd_d2 <= xgmii_rxd_d1; +end + +endmodule diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v new file mode 100644 index 000000000..dd4e138ce --- /dev/null +++ b/rtl/axis_xgmii_rx_64.v @@ -0,0 +1,476 @@ +/* + +Copyright (c) 2015-2017 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 XGMII frame receiver (XGMII in, AXI out) + */ +module axis_xgmii_rx_64 +( + input wire clk, + input wire rst, + + /* + * XGMII input + */ + input wire [63:0] xgmii_rxd, + input wire [7:0] xgmii_rxc, + + /* + * AXI output + */ + output wire [63:0] output_axis_tdata, + output wire [7:0] output_axis_tkeep, + output wire output_axis_tvalid, + output wire output_axis_tlast, + output wire output_axis_tuser, + + /* + * Status + */ + output wire error_bad_frame, + output wire error_bad_fcs +); + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PAYLOAD = 3'd1, + STATE_LAST = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg [7:0] last_cycle_tkeep_reg = 8'd0, last_cycle_tkeep_next; + +reg lanes_swapped = 1'b0; +reg [31:0] swap_rxd = 32'd0; +reg [3:0] swap_rxc = 4'd0; + +reg [63:0] xgmii_rxd_d0 = 32'd0; +reg [63:0] xgmii_rxd_d1 = 32'd0; + +reg [7:0] xgmii_rxc_d0 = 8'd0; +reg [7:0] xgmii_rxc_d1 = 8'd0; + +reg [63:0] output_axis_tdata_reg = 64'd0, output_axis_tdata_next; +reg [7:0] output_axis_tkeep_reg = 8'd0, output_axis_tkeep_next; +reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg output_axis_tlast_reg = 1'b0, output_axis_tlast_next; +reg output_axis_tuser_reg = 1'b0, output_axis_tuser_next; + +reg error_bad_frame_reg = 1'b0, error_bad_frame_next; +reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; +reg [31:0] crc_state3 = 32'hFFFFFFFF; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; +wire [31:0] crc_next7; + +wire crc_valid0 = crc_next0 == ~32'h2144df1c; +wire crc_valid1 = crc_next1 == ~32'h2144df1c; +wire crc_valid2 = crc_next2 == ~32'h2144df1c; +wire crc_valid3 = crc_next3 == ~32'h2144df1c; +wire crc_valid7 = crc_next7 == ~32'h2144df1c; + +reg crc_valid7_save = 1'b0; + +assign output_axis_tdata = output_axis_tdata_reg; +assign output_axis_tkeep = output_axis_tkeep_reg; +assign output_axis_tvalid = output_axis_tvalid_reg; +assign output_axis_tlast = output_axis_tlast_reg; +assign output_axis_tuser = output_axis_tuser_reg; + +assign error_bad_frame = error_bad_frame_reg; +assign error_bad_fcs = error_bad_fcs_reg; + +wire last_cycle = state_reg == STATE_LAST; + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(8), + .STYLE("AUTO") +) +eth_crc_8 ( + .data_in(xgmii_rxd_d0[7:0]), + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next0) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(16), + .STYLE("AUTO") +) +eth_crc_16 ( + .data_in(xgmii_rxd_d0[15:0]), + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next1) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(24), + .STYLE("AUTO") +) +eth_crc_24 ( + .data_in(xgmii_rxd_d0[23:0]), + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next2) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( + .data_in(xgmii_rxd_d0[31:0]), + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next3) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(64), + .STYLE("AUTO") +) +eth_crc_64 ( + .data_in(xgmii_rxd_d0[63:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next7) +); + +// detect control characters +reg [7:0] detect_start; +reg [7:0] detect_term; +reg [7:0] detect_error; + +reg [7:0] detect_term_save = 8'd0; + +integer i; + +always @* begin + for (i = 0; i < 8; i = i + 1) begin + detect_start[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfb); + detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfd); + detect_error[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfe); + end +end + +// mask errors to within packet +reg [7:0] detect_error_masked; +reg [7:0] control_masked; +reg [7:0] tkeep_mask; + +always @* begin + casez (detect_term) + 8'b00000000: begin + detect_error_masked = detect_error; + control_masked = xgmii_rxc_d0; + tkeep_mask = 8'b11111111; + end + 8'bzzzzzzz1: begin + detect_error_masked = 0; + control_masked = 0; + tkeep_mask = 8'b00000000; + end + 8'bzzzzzz10: begin + detect_error_masked = detect_error[0]; + control_masked = xgmii_rxc_d0[0]; + tkeep_mask = 8'b00000001; + end + 8'bzzzzz100: begin + detect_error_masked = detect_error[1:0]; + control_masked = xgmii_rxc_d0[1:0]; + tkeep_mask = 8'b00000011; + end + 8'bzzzz1000: begin + detect_error_masked = detect_error[2:0]; + control_masked = xgmii_rxc_d0[2:0]; + tkeep_mask = 8'b00000111; + end + 8'bzzz10000: begin + detect_error_masked = detect_error[3:0]; + control_masked = xgmii_rxc_d0[3:0]; + tkeep_mask = 8'b00001111; + end + 8'bzz100000: begin + detect_error_masked = detect_error[4:0]; + control_masked = xgmii_rxc_d0[4:0]; + tkeep_mask = 8'b00011111; + end + 8'bz1000000: begin + detect_error_masked = detect_error[5:0]; + control_masked = xgmii_rxc_d0[5:0]; + tkeep_mask = 8'b00111111; + end + 8'b10000000: begin + detect_error_masked = detect_error[6:0]; + control_masked = xgmii_rxc_d0[6:0]; + tkeep_mask = 8'b01111111; + end + default: begin + detect_error_masked = detect_error; + control_masked = xgmii_rxc_d0; + tkeep_mask = 8'b11111111; + end + endcase +end + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 1'b0; + update_crc = 1'b0; + + last_cycle_tkeep_next = last_cycle_tkeep_reg; + + output_axis_tdata_next = 64'd0; + output_axis_tkeep_next = 8'd0; + output_axis_tvalid_next = 1'b0; + output_axis_tlast_next = 1'b0; + output_axis_tuser_next = 1'b0; + + error_bad_frame_next = 1'b0; + error_bad_fcs_next = 1'b0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for packet + reset_crc = 1'b1; + + if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin + // start condition + if (detect_error_masked) begin + // error in first data word + output_axis_tdata_next = 64'd0; + output_axis_tkeep_next = 8'h01; + output_axis_tvalid_next = 1'b1; + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + state_next = STATE_IDLE; + end else begin + reset_crc = 1'b0; + update_crc = 1'b1; + state_next = STATE_PAYLOAD; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // read payload + update_crc = 1'b1; + + output_axis_tdata_next = xgmii_rxd_d1; + output_axis_tkeep_next = ~xgmii_rxc_d1; + output_axis_tvalid_next = 1'b1; + output_axis_tlast_next = 1'b0; + output_axis_tuser_next = 1'b0; + + if (control_masked) begin + // control or error characters in packet + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + reset_crc = 1'b1; + state_next = STATE_IDLE; + end else if (detect_term) begin + if (detect_term[4:0]) begin + // end this cycle + reset_crc = 1'b1; + output_axis_tkeep_next = {tkeep_mask[3:0], 4'b1111}; + output_axis_tlast_next = 1'b1; + if ((detect_term[0] & crc_valid7_save) || + (detect_term[1] & crc_valid0) || + (detect_term[2] & crc_valid1) || + (detect_term[3] & crc_valid2) || + (detect_term[4] & crc_valid3)) begin + // CRC valid + end else begin + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; + end + state_next = STATE_IDLE; + end else begin + // need extra cycle + last_cycle_tkeep_next = {4'b0000, tkeep_mask[7:4]}; + state_next = STATE_LAST; + end + end else begin + state_next = STATE_PAYLOAD; + end + end + STATE_LAST: begin + // last cycle of packet + output_axis_tdata_next = xgmii_rxd_d1; + output_axis_tkeep_next = last_cycle_tkeep_reg; + output_axis_tvalid_next = 1'b1; + output_axis_tlast_next = 1'b1; + output_axis_tuser_next = 1'b0; + + reset_crc = 1'b1; + + if ((detect_term_save[5] & crc_valid0) || + (detect_term_save[6] & crc_valid1) || + (detect_term_save[7] & crc_valid2)) begin + // CRC valid + end else begin + output_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; + end + + if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin + // start condition + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_IDLE; + end + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + output_axis_tvalid_reg <= 1'b0; + + error_bad_frame_reg <= 1'b0; + error_bad_fcs_reg <= 1'b0; + + crc_state <= 32'hFFFFFFFF; + crc_state3 <= 32'hFFFFFFFF; + crc_valid7_save <= 1'b0; + + xgmii_rxc_d0 <= 8'd0; + xgmii_rxc_d1 <= 8'd0; + + lanes_swapped <= 1'b0; + end else begin + state_reg <= state_next; + + output_axis_tvalid_reg <= output_axis_tvalid_next; + + error_bad_frame_reg <= error_bad_frame_next; + error_bad_fcs_reg <= error_bad_fcs_next; + + if (xgmii_rxc[0] && xgmii_rxd[7:0] == 8'hfb) begin + lanes_swapped <= 1'b0; + xgmii_rxc_d0 <= xgmii_rxc; + end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == 8'hfb) begin + lanes_swapped <= 1'b1; + xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; + end else if (lanes_swapped) begin + xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; + end else begin + xgmii_rxc_d0 <= xgmii_rxc; + end + + if (state_next == STATE_LAST) begin + xgmii_rxc_d0[3:0] <= xgmii_rxc_d0[7:4]; + end + + xgmii_rxc_d1 <= xgmii_rxc_d0; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + crc_state3 <= 32'hFFFFFFFF; + crc_valid7_save <= 1'b0; + end else if (update_crc) begin + crc_state <= crc_next7; + crc_state3 <= crc_next3; + crc_valid7_save <= crc_valid7; + end + end + + output_axis_tdata_reg <= output_axis_tdata_next; + output_axis_tkeep_reg <= output_axis_tkeep_next; + output_axis_tlast_reg <= output_axis_tlast_next; + output_axis_tuser_reg <= output_axis_tuser_next; + + last_cycle_tkeep_reg <= last_cycle_tkeep_next; + + detect_term_save <= detect_term; + + swap_rxd <= xgmii_rxd[63:32]; + swap_rxc <= xgmii_rxc[7:4]; + + if (xgmii_rxc[0] && xgmii_rxd[7:0] == 8'hfb) begin + xgmii_rxd_d0 <= xgmii_rxd; + end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == 8'hfb) begin + xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; + end else if (lanes_swapped) begin + xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; + end else begin + xgmii_rxd_d0 <= xgmii_rxd; + end + + if (state_next == STATE_LAST) begin + xgmii_rxd_d0[31:0] <= xgmii_rxd_d0[63:32]; + end + + xgmii_rxd_d1 <= xgmii_rxd_d0; +end + +endmodule diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v new file mode 100644 index 000000000..7761b8581 --- /dev/null +++ b/rtl/axis_xgmii_tx_32.v @@ -0,0 +1,549 @@ +/* + +Copyright (c) 2015-2017 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 XGMII frame transmitter (AXI in, XGMII out) + */ +module axis_xgmii_tx_32 # +( + parameter ENABLE_PADDING = 1, + parameter ENABLE_DIC = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [31:0] input_axis_tdata, + input wire [3:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * XGMII output + */ + output wire [31:0] xgmii_txd, + output wire [3:0] xgmii_txc, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; +localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfffc; +localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0003; + +localparam [3:0] + STATE_IDLE = 4'd0, + STATE_PREAMBLE = 4'd1, + STATE_PAYLOAD = 4'd2, + STATE_PAD = 4'd3, + STATE_FCS_1 = 4'd4, + STATE_FCS_2 = 4'd5, + STATE_FCS_3 = 4'd6, + STATE_IFG = 4'd7, + STATE_WAIT_END = 4'd8; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg [31:0] input_axis_tdata_masked; + +reg [31:0] input_tdata_reg = 64'd0, input_tdata_next; +reg [3:0] input_tkeep_reg = 8'd0, input_tkeep_next; + +reg [31:0] fcs_output_txd_0; +reg [31:0] fcs_output_txd_1; +reg [3:0] fcs_output_txc_0; +reg [3:0] fcs_output_txc_1; + +reg [7:0] ifg_offset; + +reg extra_cycle; + +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; + +reg [7:0] ifg_count_reg = 8'd0, ifg_count_next; +reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; + +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; + +reg [31:0] xgmii_txd_reg = 32'h07070707, xgmii_txd_next; +reg [3:0] xgmii_txc_reg = 4'b1111, xgmii_txc_next; + +assign input_axis_tready = input_axis_tready_reg; + +assign xgmii_txd = xgmii_txd_reg; +assign xgmii_txc = xgmii_txc_reg; + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(8), + .STYLE("AUTO") +) +eth_crc_8 ( + .data_in(input_tdata_reg[7:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next0) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(16), + .STYLE("AUTO") +) +eth_crc_16 ( + .data_in(input_tdata_reg[15:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next1) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(24), + .STYLE("AUTO") +) +eth_crc_24 ( + .data_in(input_tdata_reg[23:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next2) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( + .data_in(input_tdata_reg[31:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next3) +); + +function [2:0] keep2count; + input [3:0] k; + casez (k) + 4'bzzz0: keep2count = 3'd0; + 4'bzz01: keep2count = 3'd1; + 4'bz011: keep2count = 3'd2; + 4'b0111: keep2count = 3'd3; + 4'b1111: keep2count = 3'd4; + endcase +endfunction + +function [3:0] count2keep; + input [2:0] k; + case (k) + 3'd0: count2keep = 4'b0000; + 3'd1: count2keep = 4'b0001; + 3'd2: count2keep = 4'b0011; + 3'd3: count2keep = 4'b0111; + 3'd4: count2keep = 4'b1111; + endcase +endfunction + +// Mask input data +integer j; + +always @* begin + for (j = 0; j < 4; j = j + 1) begin + input_axis_tdata_masked[j*8 +: 8] = input_axis_tkeep[j] ? input_axis_tdata[j*8 +: 8] : 8'd0; + end +end + +// FCS cycle calculation +always @* begin + casez (input_tkeep_reg) + 4'bzz01: begin + fcs_output_txd_0 = {~crc_next0[23:0], input_tdata_reg[7:0]}; + fcs_output_txd_1 = {24'h0707fd, ~crc_next0[31:24]}; + fcs_output_txc_0 = 4'b0000; + fcs_output_txc_1 = 4'b1110; + ifg_offset = 8'd3; + extra_cycle = 1'b0; + end + 4'bz011: begin + fcs_output_txd_0 = {~crc_next1[15:0], input_tdata_reg[15:0]}; + fcs_output_txd_1 = {16'h07fd, ~crc_next1[31:16]}; + fcs_output_txc_0 = 4'b0000; + fcs_output_txc_1 = 4'b1100; + ifg_offset = 8'd2; + extra_cycle = 1'b0; + end + 4'b0111: begin + fcs_output_txd_0 = {~crc_next2[7:0], input_tdata_reg[23:0]}; + fcs_output_txd_1 = {16'hfd, ~crc_next2[31:8]}; + fcs_output_txc_0 = 4'b0000; + fcs_output_txc_1 = 4'b1000; + ifg_offset = 8'd1; + extra_cycle = 1'b0; + end + 4'b1111: begin + fcs_output_txd_0 = input_tdata_reg; + fcs_output_txd_1 = ~crc_next3; + fcs_output_txc_0 = 4'b0000; + fcs_output_txc_1 = 4'b0000; + ifg_offset = 8'd4; + extra_cycle = 1'b1; + end + default: begin + fcs_output_txd_0 = 32'd0; + fcs_output_txd_1 = 32'd0; + fcs_output_txc_0 = 4'd0; + fcs_output_txc_1 = 4'd0; + ifg_offset = 8'd0; + extra_cycle = 1'b0; + end + endcase +end + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 1'b0; + update_crc = 1'b0; + + frame_ptr_next = frame_ptr_reg; + + ifg_count_next = ifg_count_reg; + deficit_idle_count_next = deficit_idle_count_reg; + + input_axis_tready_next = 1'b0; + + input_tdata_next = input_tdata_reg; + input_tkeep_next = input_tkeep_reg; + + // XGMII idle + xgmii_txd_next = 32'h07070707; + xgmii_txc_next = 4'b1111; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 16'd4; + reset_crc = 1'b1; + + // XGMII idle + xgmii_txd_next = 32'h07070707; + xgmii_txc_next = 4'b1111; + + input_tdata_next = input_axis_tdata_masked; + input_tkeep_next = input_axis_tkeep; + + if (input_axis_tvalid) begin + // XGMII start and preamble + xgmii_txd_next = 32'h555555fb; + xgmii_txc_next = 4'b0001; + input_axis_tready_next = 1'b1; + state_next = STATE_PREAMBLE; + end else begin + ifg_count_next = 8'd0; + deficit_idle_count_next = 2'd0; + state_next = STATE_IDLE; + end + end + STATE_PREAMBLE: begin + // send preamble + + input_tdata_next = input_axis_tdata_masked; + input_tkeep_next = input_axis_tkeep; + + xgmii_txd_next = 32'hd5555555; + xgmii_txc_next = 4'b0000; + input_axis_tready_next = 1'b1; + state_next = STATE_PAYLOAD; + end + STATE_PAYLOAD: begin + // transfer payload + update_crc = 1'b1; + input_axis_tready_next = 1'b1; + + frame_ptr_next = frame_ptr_reg + 16'd4; + + xgmii_txd_next = input_tdata_reg; + xgmii_txc_next = 4'b0000; + + input_tdata_next = input_axis_tdata_masked; + input_tkeep_next = input_axis_tkeep; + + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); + input_axis_tready_next = 1'b0; + if (input_axis_tuser) begin + xgmii_txd_next = 32'h07fdfefe; + xgmii_txc_next = 4'b1111; + frame_ptr_next = 16'd0; + ifg_count_next = 8'd10; + state_next = STATE_IFG; + end else begin + input_axis_tready_next = 1'b0; + + if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(input_axis_tkeep) < MIN_FL_NOCRC_LS))) begin + input_tkeep_next = 4'hf; + frame_ptr_next = frame_ptr_reg + 16'd4; + + if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-4)) begin + state_next = STATE_PAD; + end else begin + input_tkeep_next = 4'hf >> ((4-MIN_FL_NOCRC_LS) % 4); + + state_next = STATE_FCS_1; + end + end else begin + state_next = STATE_FCS_1; + end + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + // tvalid deassert, fail frame + xgmii_txd_next = 32'h07fdfefe; + xgmii_txc_next = 4'b1111; + frame_ptr_next = 16'd0; + ifg_count_next = 8'd10; + state_next = STATE_WAIT_END; + end + end + STATE_PAD: begin + // pad frame to MIN_FRAME_LENGTH + input_axis_tready_next = 1'b0; + + xgmii_txd_next = input_tdata_reg; + xgmii_txc_next = 4'b0000; + + input_tdata_next = 32'd0; + input_tkeep_next = 4'hf; + + update_crc = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd4; + + if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-4)) begin + state_next = STATE_PAD; + end else begin + input_tkeep_next = 4'hf >> ((4-MIN_FL_NOCRC_LS) % 4); + + state_next = STATE_FCS_1; + end + end + STATE_FCS_1: begin + // last cycle + input_axis_tready_next = 1'b0; + + xgmii_txd_next = fcs_output_txd_0; + xgmii_txc_next = fcs_output_txc_0; + + frame_ptr_next = 16'd0; + + ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + deficit_idle_count_reg; + state_next = STATE_FCS_2; + end + STATE_FCS_2: begin + // last cycle + input_axis_tready_next = 1'b0; + + xgmii_txd_next = fcs_output_txd_1; + xgmii_txc_next = fcs_output_txc_1; + + frame_ptr_next = 16'd0; + + if (extra_cycle) begin + state_next = STATE_FCS_3; + end else begin + state_next = STATE_IFG; + end + end + STATE_FCS_3: begin + // last cycle + input_axis_tready_next = 1'b0; + + xgmii_txd_next = 32'h070707fd; + xgmii_txc_next = 4'b1111; + + reset_crc = 1'b1; + frame_ptr_next = 16'd0; + + if (ENABLE_DIC) begin + if (ifg_count_next > 8'd3) begin + state_next = STATE_IFG; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 8'd0; + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 8'd0) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end + end + STATE_IFG: begin + // send IFG + if (ifg_count_reg > 8'd4) begin + ifg_count_next = ifg_count_reg - 8'd4; + end else begin + ifg_count_next = 8'd0; + end + + reset_crc = 1'b1; + + if (ENABLE_DIC) begin + if (ifg_count_next > 8'd3) begin + state_next = STATE_IFG; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 8'd0; + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 8'd0) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end + end + STATE_WAIT_END: begin + // wait for end of frame + if (ifg_count_reg > 8'd8) begin + ifg_count_next = ifg_count_reg - 8'd8; + end else begin + ifg_count_next = 8'd0; + end + + reset_crc = 1'b1; + + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + if (ENABLE_DIC) begin + if (ifg_count_next > 8'd3) begin + state_next = STATE_IFG; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 8'd0; + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 8'd0) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end + end else begin + state_next = STATE_WAIT_END; + end + end else begin + state_next = STATE_WAIT_END; + end + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 16'd0; + + ifg_count_reg <= 8'd0; + deficit_idle_count_reg <= 2'd0; + + input_axis_tready_reg <= 1'b0; + + xgmii_txd_reg <= 32'h07070707; + xgmii_txc_reg <= 4'b1111; + + crc_state <= 32'hFFFFFFFF; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + ifg_count_reg <= ifg_count_next; + deficit_idle_count_reg <= deficit_idle_count_next; + + input_axis_tready_reg <= input_axis_tready_next; + + xgmii_txd_reg <= xgmii_txd_next; + xgmii_txc_reg <= xgmii_txc_next; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next3; + end + end + + input_tdata_reg <= input_tdata_next; + input_tkeep_reg <= input_tkeep_next; +end + +endmodule diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v new file mode 100644 index 000000000..ce118dfa9 --- /dev/null +++ b/rtl/axis_xgmii_tx_64.v @@ -0,0 +1,691 @@ +/* + +Copyright (c) 2015-2017 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 XGMII frame transmitter (AXI in, XGMII out) + */ +module axis_xgmii_tx_64 # +( + parameter ENABLE_PADDING = 1, + parameter ENABLE_DIC = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [63:0] input_axis_tdata, + input wire [7:0] input_axis_tkeep, + input wire input_axis_tvalid, + output wire input_axis_tready, + input wire input_axis_tlast, + input wire input_axis_tuser, + + /* + * XGMII output + */ + output wire [63:0] xgmii_txd, + output wire [7:0] xgmii_txc, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; +localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8; +localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007; + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PAYLOAD = 3'd1, + STATE_PAD = 3'd2, + STATE_FCS_1 = 3'd3, + STATE_FCS_2 = 3'd4, + STATE_IFG = 3'd5, + STATE_WAIT_END = 3'd6; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg swap_lanes; +reg unswap_lanes; + +reg lanes_swapped = 1'b0; +reg [31:0] swap_txd = 32'd0; +reg [3:0] swap_txc = 4'd0; + +reg [63:0] input_axis_tdata_masked; + +reg [63:0] input_tdata_reg = 64'd0, input_tdata_next; +reg [7:0] input_tkeep_reg = 8'd0, input_tkeep_next; + +reg [63:0] fcs_output_txd_0; +reg [63:0] fcs_output_txd_1; +reg [7:0] fcs_output_txc_0; +reg [7:0] fcs_output_txc_1; + +reg [7:0] ifg_offset; + +reg extra_cycle; + +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; + +reg [7:0] ifg_count_reg = 8'd0, ifg_count_next; +reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; + +reg input_axis_tready_reg = 1'b0, input_axis_tready_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; +wire [31:0] crc_next4; +wire [31:0] crc_next5; +wire [31:0] crc_next6; +wire [31:0] crc_next7; + +reg [63:0] xgmii_txd_reg = 64'h0707070707070707, xgmii_txd_next; +reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; + +assign input_axis_tready = input_axis_tready_reg; + +assign xgmii_txd = xgmii_txd_reg; +assign xgmii_txc = xgmii_txc_reg; + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(8), + .STYLE("AUTO") +) +eth_crc_8 ( + .data_in(input_tdata_reg[7:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next0) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(16), + .STYLE("AUTO") +) +eth_crc_16 ( + .data_in(input_tdata_reg[15:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next1) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(24), + .STYLE("AUTO") +) +eth_crc_24 ( + .data_in(input_tdata_reg[23:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next2) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( + .data_in(input_tdata_reg[31:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next3) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(40), + .STYLE("AUTO") +) +eth_crc_40 ( + .data_in(input_tdata_reg[39:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next4) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(48), + .STYLE("AUTO") +) +eth_crc_48 ( + .data_in(input_tdata_reg[47:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next5) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(56), + .STYLE("AUTO") +) +eth_crc_56 ( + .data_in(input_tdata_reg[55:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next6) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(64), + .STYLE("AUTO") +) +eth_crc_64 ( + .data_in(input_tdata_reg[63:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next7) +); + +function [3:0] keep2count; + input [7:0] k; + casez (k) + 8'bzzzzzzz0: keep2count = 4'd0; + 8'bzzzzzz01: keep2count = 4'd1; + 8'bzzzzz011: keep2count = 4'd2; + 8'bzzzz0111: keep2count = 4'd3; + 8'bzzz01111: keep2count = 4'd4; + 8'bzz011111: keep2count = 4'd5; + 8'bz0111111: keep2count = 4'd6; + 8'b01111111: keep2count = 4'd7; + 8'b11111111: keep2count = 4'd8; + endcase +endfunction + +function [7:0] count2keep; + input [3:0] k; + case (k) + 4'd0: count2keep = 8'b00000000; + 4'd1: count2keep = 8'b00000001; + 4'd2: count2keep = 8'b00000011; + 4'd3: count2keep = 8'b00000111; + 4'd4: count2keep = 8'b00001111; + 4'd5: count2keep = 8'b00011111; + 4'd6: count2keep = 8'b00111111; + 4'd7: count2keep = 8'b01111111; + 4'd8: count2keep = 8'b11111111; + endcase +endfunction + +// Mask input data +integer j; + +always @* begin + for (j = 0; j < 8; j = j + 1) begin + input_axis_tdata_masked[j*8 +: 8] = input_axis_tkeep[j] ? input_axis_tdata[j*8 +: 8] : 8'd0; + end +end + +// FCS cycle calculation +always @* begin + casez (input_tkeep_reg) + 8'bzzzzzz01: begin + fcs_output_txd_0 = {24'h0707fd, ~crc_next0[31:0], input_tdata_reg[7:0]}; + fcs_output_txd_1 = {63'h0707070707070707}; + fcs_output_txc_0 = 8'b11100000; + fcs_output_txc_1 = 8'b11111111; + ifg_offset = 8'd3; + extra_cycle = 1'b0; + end + 8'bzzzzz011: begin + fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], input_tdata_reg[15:0]}; + fcs_output_txd_1 = {63'h0707070707070707}; + fcs_output_txc_0 = 8'b11000000; + fcs_output_txc_1 = 8'b11111111; + ifg_offset = 8'd2; + extra_cycle = 1'b0; + end + 8'bzzzz0111: begin + fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], input_tdata_reg[23:0]}; + fcs_output_txd_1 = {63'h0707070707070707}; + fcs_output_txc_0 = 8'b10000000; + fcs_output_txc_1 = 8'b11111111; + ifg_offset = 8'd1; + extra_cycle = 1'b0; + end + 8'bzzz01111: begin + fcs_output_txd_0 = {~crc_next3[31:0], input_tdata_reg[31:0]}; + fcs_output_txd_1 = {63'h07070707070707fd}; + fcs_output_txc_0 = 8'b00000000; + fcs_output_txc_1 = 8'b11111111; + ifg_offset = 8'd8; + extra_cycle = 1'b1; + end + 8'bzz011111: begin + fcs_output_txd_0 = {~crc_next4[23:0], input_tdata_reg[39:0]}; + fcs_output_txd_1 = {56'h070707070707fd, ~crc_next4[31:24]}; + fcs_output_txc_0 = 8'b00000000; + fcs_output_txc_1 = 8'b11111110; + ifg_offset = 8'd7; + extra_cycle = 1'b1; + end + 8'bz0111111: begin + fcs_output_txd_0 = {~crc_next5[15:0], input_tdata_reg[47:0]}; + fcs_output_txd_1 = {48'h0707070707fd, ~crc_next5[31:16]}; + fcs_output_txc_0 = 8'b00000000; + fcs_output_txc_1 = 8'b11111100; + ifg_offset = 8'd6; + extra_cycle = 1'b1; + end + 8'b01111111: begin + fcs_output_txd_0 = {~crc_next6[7:0], input_tdata_reg[55:0]}; + fcs_output_txd_1 = {40'h07070707fd, ~crc_next6[31:8]}; + fcs_output_txc_0 = 8'b00000000; + fcs_output_txc_1 = 8'b11111000; + ifg_offset = 8'd5; + extra_cycle = 1'b1; + end + 8'b11111111: begin + fcs_output_txd_0 = input_tdata_reg; + fcs_output_txd_1 = {32'h070707fd, ~crc_next7[31:0]}; + fcs_output_txc_0 = 8'b00000000; + fcs_output_txc_1 = 8'b11110000; + ifg_offset = 8'd4; + extra_cycle = 1'b1; + end + default: begin + fcs_output_txd_0 = 64'd0; + fcs_output_txd_1 = 64'd0; + fcs_output_txc_0 = 8'd0; + fcs_output_txc_1 = 8'd0; + ifg_offset = 8'd0; + extra_cycle = 1'b1; + end + endcase +end + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 1'b0; + update_crc = 1'b0; + + swap_lanes = 1'b0; + unswap_lanes = 1'b0; + + frame_ptr_next = frame_ptr_reg; + + ifg_count_next = ifg_count_reg; + deficit_idle_count_next = deficit_idle_count_reg; + + input_axis_tready_next = 1'b0; + + input_tdata_next = input_tdata_reg; + input_tkeep_next = input_tkeep_reg; + + // XGMII idle + xgmii_txd_next = 64'h0707070707070707; + xgmii_txc_next = 8'b11111111; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 16'd8; + reset_crc = 1'b1; + input_axis_tready_next = 1'b1; + + // XGMII idle + xgmii_txd_next = 64'h0707070707070707; + xgmii_txc_next = 8'b11111111; + + input_tdata_next = input_axis_tdata_masked; + input_tkeep_next = input_axis_tkeep; + + if (input_axis_tvalid) begin + // XGMII start and preamble + if (ifg_count_reg > 8'd0) begin + // need to send more idles - swap lanes + swap_lanes = 1'b1; + end else begin + // no more idles - unswap + unswap_lanes = 1'b1; + end + xgmii_txd_next = 64'hd5555555555555fb; + xgmii_txc_next = 8'b00000001; + input_axis_tready_next = 1'b1; + state_next = STATE_PAYLOAD; + end else begin + ifg_count_next = 8'd0; + deficit_idle_count_next = 2'd0; + unswap_lanes = 1'b1; + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // transfer payload + update_crc = 1'b1; + input_axis_tready_next = 1'b1; + + frame_ptr_next = frame_ptr_reg + 16'd8; + + xgmii_txd_next = input_tdata_reg; + xgmii_txc_next = 8'b00000000; + + input_tdata_next = input_axis_tdata_masked; + input_tkeep_next = input_axis_tkeep; + + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); + input_axis_tready_next = 1'b0; + if (input_axis_tuser) begin + xgmii_txd_next = 64'h070707fdfefefefe; + xgmii_txc_next = 8'b11111111; + frame_ptr_next = 16'd0; + ifg_count_next = 8'd8; + state_next = STATE_IFG; + end else begin + input_axis_tready_next = 1'b0; + + if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(input_axis_tkeep) < MIN_FL_NOCRC_LS))) begin + input_tkeep_next = 8'hff; + frame_ptr_next = frame_ptr_reg + 16'd8; + + if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-8)) begin + state_next = STATE_PAD; + end else begin + input_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8); + + state_next = STATE_FCS_1; + end + end else begin + state_next = STATE_FCS_1; + end + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + // tvalid deassert, fail frame + xgmii_txd_next = 64'h070707fdfefefefe; + xgmii_txc_next = 8'b11111111; + frame_ptr_next = 16'd0; + ifg_count_next = 8'd8; + state_next = STATE_WAIT_END; + end + end + STATE_PAD: begin + // pad frame to MIN_FRAME_LENGTH + input_axis_tready_next = 1'b0; + + xgmii_txd_next = input_tdata_reg; + xgmii_txc_next = 8'b00000000; + + input_tdata_next = 64'd0; + input_tkeep_next = 8'hff; + + update_crc = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd8; + + if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-8)) begin + state_next = STATE_PAD; + end else begin + input_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8); + + state_next = STATE_FCS_1; + end + end + STATE_FCS_1: begin + // last cycle + input_axis_tready_next = 1'b0; + + xgmii_txd_next = fcs_output_txd_0; + xgmii_txc_next = fcs_output_txc_0; + + frame_ptr_next = 16'd0; + + ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + (lanes_swapped ? 8'd4 : 8'd0) + deficit_idle_count_reg; + if (extra_cycle) begin + state_next = STATE_FCS_2; + end else begin + state_next = STATE_IFG; + end + end + STATE_FCS_2: begin + // last cycle + input_axis_tready_next = 1'b0; + + xgmii_txd_next = fcs_output_txd_1; + xgmii_txc_next = fcs_output_txc_1; + + reset_crc = 1'b1; + frame_ptr_next = 16'd0; + + if (ENABLE_DIC) begin + if (ifg_count_next > 8'd7) begin + state_next = STATE_IFG; + end else begin + if (ifg_count_next >= 8'd4) begin + deficit_idle_count_next = ifg_count_next - 8'd4; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 8'd0; + end + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 8'd4) begin + state_next = STATE_IFG; + end else begin + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end + end + STATE_IFG: begin + // send IFG + if (ifg_count_reg > 8'd8) begin + ifg_count_next = ifg_count_reg - 8'd8; + end else begin + ifg_count_next = 8'd0; + end + + reset_crc = 1'b1; + + if (ENABLE_DIC) begin + if (ifg_count_next > 8'd7) begin + state_next = STATE_IFG; + end else begin + if (ifg_count_next >= 8'd4) begin + deficit_idle_count_next = ifg_count_next - 8'd4; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 8'd0; + end + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 8'd4) begin + state_next = STATE_IFG; + end else begin + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end + end + STATE_WAIT_END: begin + // wait for end of frame + if (ifg_count_reg > 8'd8) begin + ifg_count_next = ifg_count_reg - 8'd8; + end else begin + ifg_count_next = 8'd0; + end + + reset_crc = 1'b1; + + if (input_axis_tvalid) begin + if (input_axis_tlast) begin + if (ENABLE_DIC) begin + if (ifg_count_next > 8'd7) begin + state_next = STATE_IFG; + end else begin + if (ifg_count_next >= 8'd4) begin + deficit_idle_count_next = ifg_count_next - 8'd4; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 8'd0; + end + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 8'd4) begin + state_next = STATE_IFG; + end else begin + input_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end + end else begin + state_next = STATE_WAIT_END; + end + end else begin + state_next = STATE_WAIT_END; + end + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 16'd0; + + ifg_count_reg <= 8'd0; + deficit_idle_count_reg <= 2'd0; + + input_axis_tready_reg <= 1'b0; + + xgmii_txd_reg <= 64'h0707070707070707; + xgmii_txc_reg <= 8'b11111111; + + crc_state <= 32'hFFFFFFFF; + + lanes_swapped <= 1'b0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + ifg_count_reg <= ifg_count_next; + deficit_idle_count_reg <= deficit_idle_count_next; + + input_axis_tready_reg <= input_axis_tready_next; + + if (lanes_swapped) begin + if (unswap_lanes) begin + lanes_swapped <= 1'b0; + xgmii_txd_reg <= xgmii_txd_next; + xgmii_txc_reg <= xgmii_txc_next; + end else begin + xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd}; + xgmii_txc_reg <= {xgmii_txc_next[3:0], swap_txc}; + end + end else begin + if (swap_lanes) begin + lanes_swapped <= 1'b1; + xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd}; + xgmii_txc_reg <= {xgmii_txc_next[3:0], swap_txc}; + end else begin + xgmii_txd_reg <= xgmii_txd_next; + xgmii_txc_reg <= xgmii_txc_next; + end + end + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next7; + end + end + + input_tdata_reg <= input_tdata_next; + input_tkeep_reg <= input_tkeep_next; + + swap_txd <= xgmii_txd_next[63:32]; + swap_txc <= xgmii_txc_next[7:4]; +end + +endmodule diff --git a/tb/test_axis_xgmii_rx_32.py b/tb/test_axis_xgmii_rx_32.py new file mode 100755 index 000000000..9f340f703 --- /dev/null +++ b/tb/test_axis_xgmii_rx_32.py @@ -0,0 +1,364 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import axis_ep +import eth_ep +import xgmii_ep + +module = 'axis_xgmii_rx_32' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[4:]) + + xgmii_rxd = Signal(intbv(0x07070707)[32:]) + xgmii_rxc = Signal(intbv(0xf)[4:]) + + # Outputs + output_axis_tdata = Signal(intbv(0)[32:]) + output_axis_tkeep = Signal(intbv(0)[4:]) + output_axis_tvalid = Signal(bool(0)) + output_axis_tlast = Signal(bool(0)) + output_axis_tuser = Signal(bool(0)) + error_bad_frame = Signal(bool(0)) + error_bad_fcs = Signal(bool(0)) + + # sources and sinks + source = xgmii_ep.XGMIISource() + + source_logic = source.create_logic( + clk, + rst, + txd=xgmii_rxd, + txc=xgmii_rxc, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + 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, + + xgmii_rxd=xgmii_rxd, + xgmii_rxc=xgmii_rxc, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + error_bad_frame=error_bad_frame, + error_bad_fcs=error_bad_fcs + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_bad_frame_asserted = Signal(bool(0)) + error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_bad_frame): + error_bad_frame_asserted.next = 1 + if (error_bad_fcs): + error_bad_fcs_asserted.next = 1 + + @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,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + source.send(xgmii_frame) + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: truncated frame, length %d" % payload_len) + current_test.next = 3 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + axis_frame1.data = axis_frame1.data[:-1] + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert error_bad_frame_asserted + assert error_bad_fcs_asserted + + assert rx_frame.user[-1] + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: errored frame, length %d" % payload_len) + current_test.next = 4 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + xgmii_frame1.error = 1 + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert error_bad_frame_asserted + assert not error_bad_fcs_asserted + + assert rx_frame.last_cycle_user + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 5: test stream, length %d" % payload_len) + current_test.next = 5 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_xgmii_rx_32.v b/tb/test_axis_xgmii_rx_32.v new file mode 100644 index 000000000..838fc41a8 --- /dev/null +++ b/tb/test_axis_xgmii_rx_32.v @@ -0,0 +1,92 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for axis_xgmii_rx_32 + */ +module test_axis_xgmii_rx_32; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [3:0] current_test = 0; + +reg [31:0] xgmii_rxd = 32'h07070707; +reg [3:0] xgmii_rxc = 4'hf; + +// Outputs +wire [31:0] output_axis_tdata; +wire [3:0] output_axis_tkeep; +wire output_axis_tvalid; +wire output_axis_tlast; +wire output_axis_tuser; +wire error_bad_frame; +wire error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + xgmii_rxd, + xgmii_rxc + ); + $to_myhdl( + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + error_bad_frame, + error_bad_fcs + ); + + // dump file + $dumpfile("test_axis_xgmii_rx_32.lxt"); + $dumpvars(0, test_axis_xgmii_rx_32); +end + +axis_xgmii_rx_32 +UUT ( + .clk(clk), + .rst(rst), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + .error_bad_frame(error_bad_frame), + .error_bad_fcs(error_bad_fcs) +); + +endmodule diff --git a/tb/test_axis_xgmii_rx_64.py b/tb/test_axis_xgmii_rx_64.py new file mode 100755 index 000000000..c62c022f5 --- /dev/null +++ b/tb/test_axis_xgmii_rx_64.py @@ -0,0 +1,402 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import axis_ep +import eth_ep +import xgmii_ep + +module = 'axis_xgmii_rx_64' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + xgmii_rxd = Signal(intbv(0x0707070707070707)[64:]) + xgmii_rxc = Signal(intbv(0xff)[8:]) + + # Outputs + 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)) + error_bad_frame = Signal(bool(0)) + error_bad_fcs = Signal(bool(0)) + + # sources and sinks + source = xgmii_ep.XGMIISource() + + source_logic = source.create_logic( + clk, + rst, + txd=xgmii_rxd, + txc=xgmii_rxc, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=output_axis_tdata, + tkeep=output_axis_tkeep, + tvalid=output_axis_tvalid, + tlast=output_axis_tlast, + tuser=output_axis_tuser, + 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, + + xgmii_rxd=xgmii_rxd, + xgmii_rxc=xgmii_rxc, + + output_axis_tdata=output_axis_tdata, + output_axis_tkeep=output_axis_tkeep, + output_axis_tvalid=output_axis_tvalid, + output_axis_tlast=output_axis_tlast, + output_axis_tuser=output_axis_tuser, + + error_bad_frame=error_bad_frame, + error_bad_fcs=error_bad_fcs + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_bad_frame_asserted = Signal(bool(0)) + error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_bad_frame): + error_bad_frame_asserted.next = 1 + if (error_bad_fcs): + error_bad_fcs_asserted.next = 1 + + @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,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + source.send(xgmii_frame) + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: truncated frame, length %d" % payload_len) + current_test.next = 3 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + axis_frame1.data = axis_frame1.data[:-1] + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert error_bad_frame_asserted + assert error_bad_fcs_asserted + + assert rx_frame.user[-1] + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: errored frame, length %d" % payload_len) + current_test.next = 4 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + xgmii_frame1.error = 1 + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert error_bad_frame_asserted + assert not error_bad_fcs_asserted + + assert rx_frame.last_cycle_user + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 5: test stream, length %d" % payload_len) + current_test.next = 5 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 6: Ensure 0xfb in FCS in lane 4 is not detected as start code in lane 0") + current_test.next = 6 + + test_frame = eth_ep.EthFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x806f + test_frame.payload = bytearray(range(60)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + source.send(xgmii_frame) + + yield sink.wait() + rx_frame = sink.recv() + + assert not error_bad_frame_asserted + assert not error_bad_fcs_asserted + + assert not rx_frame.last_cycle_user + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + 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() diff --git a/tb/test_axis_xgmii_rx_64.v b/tb/test_axis_xgmii_rx_64.v new file mode 100644 index 000000000..e18adcb6a --- /dev/null +++ b/tb/test_axis_xgmii_rx_64.v @@ -0,0 +1,92 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for axis_xgmii_rx_64 + */ +module test_axis_xgmii_rx_64; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [63:0] xgmii_rxd = 64'h0707070707070707; +reg [7:0] xgmii_rxc = 8'hff; + +// Outputs +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 error_bad_frame; +wire error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + xgmii_rxd, + xgmii_rxc + ); + $to_myhdl( + output_axis_tdata, + output_axis_tkeep, + output_axis_tvalid, + output_axis_tlast, + output_axis_tuser, + error_bad_frame, + error_bad_fcs + ); + + // dump file + $dumpfile("test_axis_xgmii_rx_64.lxt"); + $dumpvars(0, test_axis_xgmii_rx_64); +end + +axis_xgmii_rx_64 +UUT ( + .clk(clk), + .rst(rst), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .output_axis_tdata(output_axis_tdata), + .output_axis_tkeep(output_axis_tkeep), + .output_axis_tvalid(output_axis_tvalid), + .output_axis_tlast(output_axis_tlast), + .output_axis_tuser(output_axis_tuser), + .error_bad_frame(error_bad_frame), + .error_bad_fcs(error_bad_fcs) +); + +endmodule diff --git a/tb/test_axis_xgmii_tx_32.py b/tb/test_axis_xgmii_tx_32.py new file mode 100755 index 000000000..241b2f6ac --- /dev/null +++ b/tb/test_axis_xgmii_tx_32.py @@ -0,0 +1,340 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import axis_ep +import eth_ep +import xgmii_ep + +module = 'axis_xgmii_tx_32' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[4:]) + + input_axis_tdata = Signal(intbv(0)[32:]) + input_axis_tkeep = Signal(intbv(0)[4:]) + input_axis_tvalid = Signal(bool(0)) + input_axis_tlast = Signal(bool(0)) + input_axis_tuser = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + input_axis_tready = Signal(bool(0)) + xgmii_txd = Signal(intbv(0x07070707)[32:]) + xgmii_txc = Signal(intbv(0xf)[4:]) + + # sources and sinks + source_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource() + + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = xgmii_ep.XGMIISink() + + sink_logic = sink.create_logic( + clk, + rst, + rxd=xgmii_txd, + rxc=xgmii_txc, + 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, + + 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, + + xgmii_txd=xgmii_txd, + xgmii_txc=xgmii_txc, + + ifg_delay=ifg_delay + ) + + @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 + + ifg_delay.next = 12 + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(40,58)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source.send(axis_frame) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + source.send(axis_frame1) + source.send(axis_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame1.eth_src_mac + assert eth_frame.eth_type == test_frame1.eth_type + assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.last_cycle_user = 1 + + source.send(axis_frame1) + source.send(axis_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.error[-1] + + # bad packet + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink.empty() + + yield delay(100) + + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 4: test stream, length %d" % payload_len) + current_test.next = 4 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source.send(axis_frame) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_xgmii_tx_32.v b/tb/test_axis_xgmii_tx_32.v new file mode 100644 index 000000000..883a0ed6f --- /dev/null +++ b/tb/test_axis_xgmii_tx_32.v @@ -0,0 +1,97 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for axis_xgmii_tx_32 + */ +module test_axis_xgmii_tx_32; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [3:0] current_test = 0; + +reg [31:0] input_axis_tdata = 0; +reg [3:0] input_axis_tkeep = 0; +reg input_axis_tvalid = 0; +reg input_axis_tlast = 0; +reg input_axis_tuser = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire input_axis_tready; +wire [31:0] xgmii_txd; +wire [3:0] xgmii_txc; + +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, + ifg_delay + ); + $to_myhdl( + input_axis_tready, + xgmii_txd, + xgmii_txc + ); + + // dump file + $dumpfile("test_axis_xgmii_tx_32.lxt"); + $dumpvars(0, test_axis_xgmii_tx_32); +end + +axis_xgmii_tx_32 #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .clk(clk), + .rst(rst), + .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), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/tb/test_axis_xgmii_tx_64.py b/tb/test_axis_xgmii_tx_64.py new file mode 100755 index 000000000..370336fbb --- /dev/null +++ b/tb/test_axis_xgmii_tx_64.py @@ -0,0 +1,340 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2017 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 + +import axis_ep +import eth_ep +import xgmii_ep + +module = 'axis_xgmii_tx_64' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # 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)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + input_axis_tready = Signal(bool(0)) + xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) + xgmii_txc = Signal(intbv(0xff)[8:]) + + # sources and sinks + source_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource() + + source_logic = source.create_logic( + 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, + pause=source_pause, + name='source' + ) + + sink = xgmii_ep.XGMIISink() + + sink_logic = sink.create_logic( + clk, + rst, + rxd=xgmii_txd, + rxc=xgmii_txc, + 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, + + 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, + + xgmii_txd=xgmii_txd, + xgmii_txc=xgmii_txc, + + ifg_delay=ifg_delay + ) + + @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 + + ifg_delay.next = 12 + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(40,58)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source.send(axis_frame) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + source.send(axis_frame1) + source.send(axis_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame1.eth_src_mac + assert eth_frame.eth_type == test_frame1.eth_type + assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.last_cycle_user = 1 + + source.send(axis_frame1) + source.send(axis_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.error[-1] + + # bad packet + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink.empty() + + yield delay(100) + + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 4: test stream, length %d" % payload_len) + current_test.next = 4 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source.send(axis_frame) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_xgmii_tx_64.v b/tb/test_axis_xgmii_tx_64.v new file mode 100644 index 000000000..e7a480703 --- /dev/null +++ b/tb/test_axis_xgmii_tx_64.v @@ -0,0 +1,97 @@ +/* + +Copyright (c) 2015-2017 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 + +/* + * Testbench for axis_xgmii_tx_64 + */ +module test_axis_xgmii_tx_64; + +// Parameters +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 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 [7:0] ifg_delay = 0; + +// Outputs +wire input_axis_tready; +wire [63:0] xgmii_txd; +wire [7:0] xgmii_txc; + +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, + ifg_delay + ); + $to_myhdl( + input_axis_tready, + xgmii_txd, + xgmii_txc + ); + + // dump file + $dumpfile("test_axis_xgmii_tx_64.lxt"); + $dumpvars(0, test_axis_xgmii_tx_64); +end + +axis_xgmii_tx_64 #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .clk(clk), + .rst(rst), + .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), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .ifg_delay(ifg_delay) +); + +endmodule From 0aca4c7dccb5c05166fbdaea64d417a2b2f4920b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 00:54:41 -0700 Subject: [PATCH 412/617] Update 10G MAC to use new modules --- rtl/eth_mac_10g.v | 112 +++++-- rtl/eth_mac_10g_fifo.v | 98 +++--- ..._eth_mac_10g.py => test_eth_mac_10g_32.py} | 25 +- ...st_eth_mac_10g.v => test_eth_mac_10g_32.v} | 28 +- tb/test_eth_mac_10g_64.py | 275 ++++++++++++++++ tb/test_eth_mac_10g_64.v | 142 ++++++++ ...0g_fifo.py => test_eth_mac_10g_fifo_32.py} | 25 +- ..._10g_fifo.v => test_eth_mac_10g_fifo_32.v} | 28 +- tb/test_eth_mac_10g_fifo_64.py | 303 ++++++++++++++++++ tb/test_eth_mac_10g_fifo_64.v | 173 ++++++++++ 10 files changed, 1093 insertions(+), 116 deletions(-) rename tb/{test_eth_mac_10g.py => test_eth_mac_10g_32.py} (91%) rename tb/{test_eth_mac_10g.v => test_eth_mac_10g_32.v} (83%) create mode 100755 tb/test_eth_mac_10g_64.py create mode 100644 tb/test_eth_mac_10g_64.v rename tb/{test_eth_mac_10g_fifo.py => test_eth_mac_10g_fifo_32.py} (92%) rename tb/{test_eth_mac_10g_fifo.v => test_eth_mac_10g_fifo_32.v} (86%) create mode 100755 tb/test_eth_mac_10g_fifo_64.py create mode 100644 tb/test_eth_mac_10g_fifo_64.v diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index 3022ae555..45c4cfe26 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -31,57 +31,77 @@ THE SOFTWARE. */ module eth_mac_10g # ( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64 ) ( - input wire rx_clk, - input wire rx_rst, - input wire tx_clk, - input wire tx_rst, + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, /* * AXI input */ - input wire [63:0] tx_axis_tdata, - input wire [7:0] tx_axis_tkeep, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire tx_axis_tuser, + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, /* * AXI output */ - output wire [63:0] rx_axis_tdata, - output wire [7:0] rx_axis_tkeep, - output wire rx_axis_tvalid, - output wire rx_axis_tlast, - output wire rx_axis_tuser, + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire rx_axis_tuser, /* * XGMII interface */ - input wire [63:0] xgmii_rxd, - input wire [7:0] xgmii_rxc, - output wire [63:0] xgmii_txd, - output wire [7:0] xgmii_txc, + input wire [DATA_WIDTH-1:0] xgmii_rxd, + input wire [CTRL_WIDTH-1:0] xgmii_rxc, + output wire [DATA_WIDTH-1:0] xgmii_txd, + output wire [CTRL_WIDTH-1:0] xgmii_txc, /* * Status */ - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay ); -eth_mac_10g_rx -eth_mac_10g_rx_inst ( +// bus width assertions +initial begin + if (DATA_WIDTH != 32 && DATA_WIDTH != 64) begin + $error("Error: Interface width must be 32 or 64"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end +end + +generate + +if (DATA_WIDTH == 64) begin + +axis_xgmii_rx_64 +axis_xgmii_rx_inst ( .clk(rx_clk), .rst(rx_rst), .xgmii_rxd(xgmii_rxd), @@ -95,12 +115,12 @@ eth_mac_10g_rx_inst ( .error_bad_fcs(rx_error_bad_fcs) ); -eth_mac_10g_tx #( +axis_xgmii_tx_64 #( .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) ) -eth_mac_10g_tx_inst ( +axis_xgmii_tx_inst ( .clk(tx_clk), .rst(tx_rst), .input_axis_tdata(tx_axis_tdata), @@ -114,4 +134,44 @@ eth_mac_10g_tx_inst ( .ifg_delay(ifg_delay) ); +end else begin + +axis_xgmii_rx_32 +axis_xgmii_rx_inst ( + .clk(rx_clk), + .rst(rx_rst), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .output_axis_tdata(rx_axis_tdata), + .output_axis_tkeep(rx_axis_tkeep), + .output_axis_tvalid(rx_axis_tvalid), + .output_axis_tlast(rx_axis_tlast), + .output_axis_tuser(rx_axis_tuser), + .error_bad_frame(rx_error_bad_frame), + .error_bad_fcs(rx_error_bad_fcs) +); + +axis_xgmii_tx_32 #( + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +axis_xgmii_tx_inst ( + .clk(tx_clk), + .rst(tx_rst), + .input_axis_tdata(tx_axis_tdata), + .input_axis_tkeep(tx_axis_tkeep), + .input_axis_tvalid(tx_axis_tvalid), + .input_axis_tready(tx_axis_tready), + .input_axis_tlast(tx_axis_tlast), + .input_axis_tuser(tx_axis_tuser), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .ifg_delay(ifg_delay) +); + +end + +endgenerate + endmodule diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 6ef32e9fa..1f5e278df 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -31,6 +31,9 @@ THE SOFTWARE. */ module eth_mac_10g_fifo # ( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -38,71 +41,71 @@ module eth_mac_10g_fifo # parameter RX_FIFO_ADDR_WIDTH = 9 ) ( - input wire rx_clk, - input wire rx_rst, - input wire tx_clk, - input wire tx_rst, - input wire logic_clk, - input wire logic_rst, + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, + input wire logic_clk, + input wire logic_rst, /* * AXI input */ - input wire [63:0] tx_axis_tdata, - input wire [7:0] tx_axis_tkeep, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire tx_axis_tuser, + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, /* * AXI output */ - output wire [63:0] rx_axis_tdata, - output wire [7:0] rx_axis_tkeep, - output wire rx_axis_tvalid, - input wire rx_axis_tready, - output wire rx_axis_tlast, - output wire rx_axis_tuser, + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + input wire rx_axis_tready, + output wire rx_axis_tlast, + output wire rx_axis_tuser, /* * XGMII interface */ - input wire [63:0] xgmii_rxd, - input wire [7:0] xgmii_rxc, - output wire [63:0] xgmii_txd, - output wire [7:0] xgmii_txc, + input wire [DATA_WIDTH-1:0] xgmii_rxd, + input wire [CTRL_WIDTH-1:0] xgmii_rxc, + output wire [DATA_WIDTH-1:0] xgmii_txd, + output wire [CTRL_WIDTH-1:0] xgmii_txc, /* * Status */ - output wire tx_fifo_overflow, - output wire tx_fifo_bad_frame, - output wire tx_fifo_good_frame, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, - output wire rx_fifo_overflow, - output wire rx_fifo_bad_frame, - output wire rx_fifo_good_frame, + output wire tx_fifo_overflow, + output wire tx_fifo_bad_frame, + output wire tx_fifo_good_frame, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_fifo_overflow, + output wire rx_fifo_bad_frame, + output wire rx_fifo_good_frame, /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay ); -wire [63:0] tx_fifo_axis_tdata; -wire [7:0] tx_fifo_axis_tkeep; -wire tx_fifo_axis_tvalid; -wire tx_fifo_axis_tready; -wire tx_fifo_axis_tlast; -wire tx_fifo_axis_tuser; +wire [DATA_WIDTH-1:0] tx_fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] tx_fifo_axis_tkeep; +wire tx_fifo_axis_tvalid; +wire tx_fifo_axis_tready; +wire tx_fifo_axis_tlast; +wire tx_fifo_axis_tuser; -wire [63:0] rx_fifo_axis_tdata; -wire [7:0] rx_fifo_axis_tkeep; -wire rx_fifo_axis_tvalid; -wire rx_fifo_axis_tlast; -wire rx_fifo_axis_tuser; +wire [DATA_WIDTH-1:0] rx_fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] rx_fifo_axis_tkeep; +wire rx_fifo_axis_tvalid; +wire rx_fifo_axis_tlast; +wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain wire rx_error_bad_frame_int; @@ -137,6 +140,9 @@ always @(posedge logic_clk or posedge logic_rst) begin end eth_mac_10g #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) @@ -168,9 +174,9 @@ eth_mac_10g_inst ( axis_async_frame_fifo #( .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), - .DATA_WIDTH(64), + .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(1), - .KEEP_WIDTH(8), + .KEEP_WIDTH(KEEP_WIDTH), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), @@ -216,9 +222,9 @@ assign tx_fifo_axis_tuser = 1'b0; axis_async_frame_fifo #( .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), - .DATA_WIDTH(64), + .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(1), - .KEEP_WIDTH(8), + .KEEP_WIDTH(KEEP_WIDTH), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), diff --git a/tb/test_eth_mac_10g.py b/tb/test_eth_mac_10g_32.py similarity index 91% rename from tb/test_eth_mac_10g.py rename to tb/test_eth_mac_10g_32.py index 5b35f3473..04112b47b 100755 --- a/tb/test_eth_mac_10g.py +++ b/tb/test_eth_mac_10g_32.py @@ -31,14 +31,14 @@ import eth_ep import xgmii_ep module = 'eth_mac_10g' -testbench = 'test_%s' % module +testbench = 'test_%s_32' % module srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/lfsr.v") -srcs.append("../rtl/eth_mac_10g_rx.v") -srcs.append("../rtl/eth_mac_10g_tx.v") +srcs.append("../rtl/axis_xgmii_rx_32.v") +srcs.append("../rtl/axis_xgmii_tx_32.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) @@ -48,6 +48,9 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + DATA_WIDTH = 32 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) ENABLE_PADDING = 1 ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 @@ -61,24 +64,24 @@ def bench(): rx_rst = Signal(bool(0)) tx_clk = Signal(bool(0)) tx_rst = Signal(bool(0)) - tx_axis_tdata = Signal(intbv(0)[64:]) - tx_axis_tkeep = Signal(intbv(0)[8:]) + tx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tvalid = Signal(bool(0)) tx_axis_tlast = Signal(bool(0)) tx_axis_tuser = Signal(bool(0)) - xgmii_rxd = Signal(intbv(0x0707070707070707)[64:]) - xgmii_rxc = Signal(intbv(0xff)[8:]) + xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs tx_axis_tready = Signal(bool(0)) - rx_axis_tdata = Signal(intbv(0)[64:]) - rx_axis_tkeep = Signal(intbv(0)[8:]) + rx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tvalid = Signal(bool(0)) rx_axis_tlast = Signal(bool(0)) rx_axis_tuser = Signal(bool(0)) - xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) - xgmii_txc = Signal(intbv(0xff)[8:]) + xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) diff --git a/tb/test_eth_mac_10g.v b/tb/test_eth_mac_10g_32.v similarity index 83% rename from tb/test_eth_mac_10g.v rename to tb/test_eth_mac_10g_32.v index 3d2d2f9d4..62b55bfad 100644 --- a/tb/test_eth_mac_10g.v +++ b/tb/test_eth_mac_10g_32.v @@ -29,9 +29,12 @@ THE SOFTWARE. /* * Testbench for eth_mac_10g */ -module test_eth_mac_10g; +module test_eth_mac_10g_32; // Parameters +parameter DATA_WIDTH = 32; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter ENABLE_PADDING = 1; parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; @@ -45,24 +48,24 @@ reg rx_clk = 0; reg rx_rst = 0; reg tx_clk = 0; reg tx_rst = 0; -reg [63:0] tx_axis_tdata = 0; -reg [7:0] tx_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg tx_axis_tvalid = 0; reg tx_axis_tlast = 0; reg tx_axis_tuser = 0; -reg [63:0] xgmii_rxd = 0; -reg [7:0] xgmii_rxc = 0; +reg [DATA_WIDTH-1:0] xgmii_rxd = 0; +reg [CTRL_WIDTH-1:0] xgmii_rxc = 0; reg [7:0] ifg_delay = 0; // Outputs wire tx_axis_tready; -wire [63:0] rx_axis_tdata; -wire [7:0] rx_axis_tkeep; +wire [DATA_WIDTH-1:0] rx_axis_tdata; +wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire rx_axis_tvalid; wire rx_axis_tlast; wire rx_axis_tuser; -wire [63:0] xgmii_txd; -wire [7:0] xgmii_txc; +wire [DATA_WIDTH-1:0] xgmii_txd; +wire [CTRL_WIDTH-1:0] xgmii_txc; wire rx_error_bad_frame; wire rx_error_bad_fcs; @@ -99,11 +102,14 @@ initial begin ); // dump file - $dumpfile("test_eth_mac_10g.lxt"); - $dumpvars(0, test_eth_mac_10g); + $dumpfile("test_eth_mac_10g_32.lxt"); + $dumpvars(0, test_eth_mac_10g_32); end eth_mac_10g #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) diff --git a/tb/test_eth_mac_10g_64.py b/tb/test_eth_mac_10g_64.py new file mode 100755 index 000000000..c21fe2a61 --- /dev/null +++ b/tb/test_eth_mac_10g_64.py @@ -0,0 +1,275 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2018 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 + +import axis_ep +import eth_ep +import xgmii_ep + +module = 'eth_mac_10g' +testbench = 'test_%s_64' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("../rtl/axis_xgmii_rx_64.v") +srcs.append("../rtl/axis_xgmii_tx_64.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) + ENABLE_PADDING = 1 + ENABLE_DIC = 1 + MIN_FRAME_LENGTH = 64 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + + # sources and sinks + axis_source_pause = Signal(bool(0)) + + xgmii_source = xgmii_ep.XGMIISource() + + xgmii_source_logic = xgmii_source.create_logic( + clk, + rst, + txd=xgmii_rxd, + txc=xgmii_rxc, + name='xgmii_source' + ) + + xgmii_sink = xgmii_ep.XGMIISink() + + xgmii_sink_logic = xgmii_sink.create_logic( + clk, + rst, + rxd=xgmii_txd, + rxc=xgmii_txc, + name='xgmii_sink' + ) + + axis_source = axis_ep.AXIStreamSource() + + axis_source_logic = axis_source.create_logic( + clk, + rst, + tdata=tx_axis_tdata, + tkeep=tx_axis_tkeep, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + pause=axis_source_pause, + name='axis_source' + ) + + axis_sink = axis_ep.AXIStreamSink() + + axis_sink_logic = axis_sink.create_logic( + clk, + rst, + tdata=rx_axis_tdata, + tkeep=rx_axis_tkeep, + tvalid=rx_axis_tvalid, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + name='axis_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, + + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tkeep=tx_axis_tkeep, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tkeep=rx_axis_tkeep, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + xgmii_rxd=xgmii_rxd, + xgmii_rxc=xgmii_rxc, + + xgmii_txd=xgmii_txd, + xgmii_txc=xgmii_txc, + + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + tx_clk.next = not tx_clk + rx_clk.next = not rx_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + tx_rst.next = 1 + rx_rst.next = 1 + yield clk.posedge + rst.next = 0 + tx_rst.next = 0 + rx_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + yield axis_sink.wait() + rx_frame = axis_sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + + yield xgmii_sink.wait() + rx_frame = xgmii_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_10g_64.v b/tb/test_eth_mac_10g_64.v new file mode 100644 index 000000000..608edfe45 --- /dev/null +++ b/tb/test_eth_mac_10g_64.v @@ -0,0 +1,142 @@ +/* + +Copyright (c) 2015-2018 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 + +/* + * Testbench for eth_mac_10g + */ +module test_eth_mac_10g_64; + +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; +parameter MIN_FRAME_LENGTH = 64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg rx_clk = 0; +reg rx_rst = 0; +reg tx_clk = 0; +reg tx_rst = 0; +reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg [DATA_WIDTH-1:0] xgmii_rxd = 0; +reg [CTRL_WIDTH-1:0] xgmii_rxc = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [DATA_WIDTH-1:0] rx_axis_tdata; +wire [KEEP_WIDTH-1:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire [DATA_WIDTH-1:0] xgmii_txd; +wire [CTRL_WIDTH-1:0] xgmii_txc; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + rx_clk, + rx_rst, + tx_clk, + tx_rst, + tx_axis_tdata, + tx_axis_tkeep, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + xgmii_rxd, + xgmii_rxc, + ifg_delay + ); + $to_myhdl( + tx_axis_tready, + rx_axis_tdata, + rx_axis_tkeep, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + xgmii_txd, + xgmii_txc, + rx_error_bad_frame, + rx_error_bad_fcs + ); + + // dump file + $dumpfile("test_eth_mac_10g_64.lxt"); + $dumpvars(0, test_eth_mac_10g_64); +end + +eth_mac_10g #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/tb/test_eth_mac_10g_fifo.py b/tb/test_eth_mac_10g_fifo_32.py similarity index 92% rename from tb/test_eth_mac_10g_fifo.py rename to tb/test_eth_mac_10g_fifo_32.py index 7df185730..78a20dbc9 100755 --- a/tb/test_eth_mac_10g_fifo.py +++ b/tb/test_eth_mac_10g_fifo_32.py @@ -31,14 +31,14 @@ import eth_ep import xgmii_ep module = 'eth_mac_10g_fifo' -testbench = 'test_%s' % module +testbench = 'test_%s_32' % module srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/lfsr.v") -srcs.append("../rtl/eth_mac_10g_rx.v") -srcs.append("../rtl/eth_mac_10g_tx.v") +srcs.append("../rtl/axis_xgmii_rx_32.v") +srcs.append("../rtl/axis_xgmii_tx_32.v") srcs.append("../rtl/eth_mac_10g.v") srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") srcs.append("%s.v" % testbench) @@ -50,6 +50,9 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + DATA_WIDTH = 32 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) ENABLE_PADDING = 1 ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 @@ -67,25 +70,25 @@ def bench(): tx_rst = Signal(bool(0)) logic_clk = Signal(bool(0)) logic_rst = Signal(bool(0)) - tx_axis_tdata = Signal(intbv(0)[64:]) - tx_axis_tkeep = Signal(intbv(0)[8:]) + tx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tvalid = Signal(bool(0)) tx_axis_tlast = Signal(bool(0)) tx_axis_tuser = Signal(bool(0)) rx_axis_tready = Signal(bool(0)) - xgmii_rxd = Signal(intbv(0x0707070707070707)[64:]) - xgmii_rxc = Signal(intbv(0xff)[8:]) + xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs tx_axis_tready = Signal(bool(0)) - rx_axis_tdata = Signal(intbv(0)[64:]) - rx_axis_tkeep = Signal(intbv(0)[8:]) + rx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tvalid = Signal(bool(0)) rx_axis_tlast = Signal(bool(0)) rx_axis_tuser = Signal(bool(0)) - xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) - xgmii_txc = Signal(intbv(0xff)[8:]) + xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) tx_fifo_overflow = Signal(bool(0)) tx_fifo_bad_frame = Signal(bool(0)) tx_fifo_good_frame = Signal(bool(0)) diff --git a/tb/test_eth_mac_10g_fifo.v b/tb/test_eth_mac_10g_fifo_32.v similarity index 86% rename from tb/test_eth_mac_10g_fifo.v rename to tb/test_eth_mac_10g_fifo_32.v index ceaa2a1f0..f83c68933 100644 --- a/tb/test_eth_mac_10g_fifo.v +++ b/tb/test_eth_mac_10g_fifo_32.v @@ -29,9 +29,12 @@ THE SOFTWARE. /* * Testbench for eth_mac_10g_fifo */ -module test_eth_mac_10g_fifo; +module test_eth_mac_10g_fifo_32; // Parameters +parameter DATA_WIDTH = 32; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter ENABLE_PADDING = 1; parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; @@ -49,25 +52,25 @@ reg tx_clk = 0; reg tx_rst = 0; reg logic_clk = 0; reg logic_rst = 0; -reg [63:0] tx_axis_tdata = 0; -reg [7:0] tx_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg tx_axis_tvalid = 0; reg tx_axis_tlast = 0; reg tx_axis_tuser = 0; reg rx_axis_tready = 0; -reg [63:0] xgmii_rxd = 0; -reg [7:0] xgmii_rxc = 0; +reg [DATA_WIDTH-1:0] xgmii_rxd = 0; +reg [CTRL_WIDTH-1:0] xgmii_rxc = 0; reg [7:0] ifg_delay = 0; // Outputs wire tx_axis_tready; -wire [63:0] rx_axis_tdata; -wire [7:0] rx_axis_tkeep; +wire [DATA_WIDTH-1:0] rx_axis_tdata; +wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire rx_axis_tvalid; wire rx_axis_tlast; wire rx_axis_tuser; -wire [63:0] xgmii_txd; -wire [7:0] xgmii_txc; +wire [DATA_WIDTH-1:0] xgmii_txd; +wire [CTRL_WIDTH-1:0] xgmii_txc; wire tx_fifo_overflow; wire tx_fifo_bad_frame; wire tx_fifo_good_frame; @@ -119,11 +122,14 @@ initial begin ); // dump file - $dumpfile("test_eth_mac_10g_fifo.lxt"); - $dumpvars(0, test_eth_mac_10g_fifo); + $dumpfile("test_eth_mac_10g_fifo_32.lxt"); + $dumpvars(0, test_eth_mac_10g_fifo_32); end eth_mac_10g_fifo #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/tb/test_eth_mac_10g_fifo_64.py b/tb/test_eth_mac_10g_fifo_64.py new file mode 100755 index 000000000..349bda134 --- /dev/null +++ b/tb/test_eth_mac_10g_fifo_64.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2018 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 + +import axis_ep +import eth_ep +import xgmii_ep + +module = 'eth_mac_10g_fifo' +testbench = 'test_%s_64' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("../rtl/axis_xgmii_rx_64.v") +srcs.append("../rtl/axis_xgmii_tx_64.v") +srcs.append("../rtl/eth_mac_10g.v") +srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) + ENABLE_PADDING = 1 + ENABLE_DIC = 1 + MIN_FRAME_LENGTH = 64 + TX_FIFO_ADDR_WIDTH = 9 + RX_FIFO_ADDR_WIDTH = 9 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + logic_clk = Signal(bool(0)) + logic_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + rx_axis_tready = Signal(bool(0)) + xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_fifo_overflow = Signal(bool(0)) + tx_fifo_bad_frame = Signal(bool(0)) + tx_fifo_good_frame = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + rx_fifo_overflow = Signal(bool(0)) + rx_fifo_bad_frame = Signal(bool(0)) + rx_fifo_good_frame = Signal(bool(0)) + + # sources and sinks + axis_source_pause = Signal(bool(0)) + axis_sink_pause = Signal(bool(0)) + + xgmii_source = xgmii_ep.XGMIISource() + + xgmii_source_logic = xgmii_source.create_logic( + rx_clk, + rx_rst, + txd=xgmii_rxd, + txc=xgmii_rxc, + name='xgmii_source' + ) + + xgmii_sink = xgmii_ep.XGMIISink() + + xgmii_sink_logic = xgmii_sink.create_logic( + tx_clk, + tx_rst, + rxd=xgmii_txd, + rxc=xgmii_txc, + name='xgmii_sink' + ) + + axis_source = axis_ep.AXIStreamSource() + + axis_source_logic = axis_source.create_logic( + logic_clk, + logic_rst, + tdata=tx_axis_tdata, + tkeep=tx_axis_tkeep, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + pause=axis_source_pause, + name='axis_source' + ) + + axis_sink = axis_ep.AXIStreamSink() + + axis_sink_logic = axis_sink.create_logic( + logic_clk, + logic_rst, + tdata=rx_axis_tdata, + tkeep=rx_axis_tkeep, + tvalid=rx_axis_tvalid, + tready=rx_axis_tready, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + pause=axis_sink_pause, + name='axis_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, + + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + logic_clk=logic_clk, + logic_rst=logic_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tkeep=tx_axis_tkeep, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tkeep=rx_axis_tkeep, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tready=rx_axis_tready, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + xgmii_rxd=xgmii_rxd, + xgmii_rxc=xgmii_rxc, + + xgmii_txd=xgmii_txd, + xgmii_txc=xgmii_txc, + + tx_fifo_overflow=tx_fifo_overflow, + tx_fifo_bad_frame=tx_fifo_bad_frame, + tx_fifo_good_frame=tx_fifo_good_frame, + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + rx_fifo_overflow=rx_fifo_overflow, + rx_fifo_bad_frame=rx_fifo_bad_frame, + rx_fifo_good_frame=rx_fifo_good_frame, + + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + tx_clk.next = not tx_clk + rx_clk.next = not rx_clk + logic_clk.next = not logic_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + tx_rst.next = 1 + rx_rst.next = 1 + logic_rst.next = 1 + yield clk.posedge + rst.next = 0 + tx_rst.next = 0 + rx_rst.next = 0 + logic_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + yield axis_sink.wait() + rx_frame = axis_sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + + yield xgmii_sink.wait() + rx_frame = xgmii_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_10g_fifo_64.v b/tb/test_eth_mac_10g_fifo_64.v new file mode 100644 index 000000000..cf87b62c3 --- /dev/null +++ b/tb/test_eth_mac_10g_fifo_64.v @@ -0,0 +1,173 @@ +/* + +Copyright (c) 2015-2018 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 + +/* + * Testbench for eth_mac_10g_fifo + */ +module test_eth_mac_10g_fifo_64; + +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; +parameter MIN_FRAME_LENGTH = 64; +parameter TX_FIFO_ADDR_WIDTH = 9; +parameter RX_FIFO_ADDR_WIDTH = 9; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg rx_clk = 0; +reg rx_rst = 0; +reg tx_clk = 0; +reg tx_rst = 0; +reg logic_clk = 0; +reg logic_rst = 0; +reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg rx_axis_tready = 0; +reg [DATA_WIDTH-1:0] xgmii_rxd = 0; +reg [CTRL_WIDTH-1:0] xgmii_rxc = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [DATA_WIDTH-1:0] rx_axis_tdata; +wire [KEEP_WIDTH-1:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire [DATA_WIDTH-1:0] xgmii_txd; +wire [CTRL_WIDTH-1:0] xgmii_txc; +wire tx_fifo_overflow; +wire tx_fifo_bad_frame; +wire tx_fifo_good_frame; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; +wire rx_fifo_overflow; +wire rx_fifo_bad_frame; +wire rx_fifo_good_frame; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + rx_clk, + rx_rst, + tx_clk, + tx_rst, + logic_clk, + logic_rst, + tx_axis_tdata, + tx_axis_tkeep, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + rx_axis_tready, + xgmii_rxd, + xgmii_rxc, + ifg_delay + ); + $to_myhdl( + tx_axis_tready, + rx_axis_tdata, + rx_axis_tkeep, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + xgmii_txd, + xgmii_txc, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, + rx_error_bad_frame, + rx_error_bad_fcs, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame + ); + + // dump file + $dumpfile("test_eth_mac_10g_fifo_64.lxt"); + $dumpvars(0, test_eth_mac_10g_fifo_64); +end + +eth_mac_10g_fifo #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .TX_FIFO_ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .RX_FIFO_ADDR_WIDTH(RX_FIFO_ADDR_WIDTH) +) +UUT ( + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .logic_clk(logic_clk), + .logic_rst(logic_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .tx_fifo_overflow(tx_fifo_overflow), + .tx_fifo_bad_frame(tx_fifo_bad_frame), + .tx_fifo_good_frame(tx_fifo_good_frame), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(rx_fifo_overflow), + .rx_fifo_bad_frame(rx_fifo_bad_frame), + .rx_fifo_good_frame(rx_fifo_good_frame), + .ifg_delay(ifg_delay) +); + +endmodule From 00dc50826d38ef6e3031c099f03becae9f9de90f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 01:03:44 -0700 Subject: [PATCH 413/617] Update example designs --- example/DE5-Net/fpga/fpga/Makefile | 4 ++-- example/DE5-Net/fpga/tb/test_fpga_core.py | 4 ++-- example/HXT100G/fpga/fpga/Makefile | 4 ++-- example/HXT100G/fpga/tb/test_fpga_core.py | 4 ++-- example/HXT100G/fpga_cxpt16/fpga/Makefile | 4 ++-- example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py | 4 ++-- example/VCU108/fpga_10g/fpga/Makefile | 4 ++-- example/VCU108/fpga_10g/tb/test_fpga_core.py | 4 ++-- example/VCU118/fpga_10g/fpga/Makefile | 4 ++-- example/VCU118/fpga_10g/tb/test_fpga_core.py | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/example/DE5-Net/fpga/fpga/Makefile b/example/DE5-Net/fpga/fpga/Makefile index 61d619cc7..fba61fa3a 100644 --- a/example/DE5-Net/fpga/fpga/Makefile +++ b/example/DE5-Net/fpga/fpga/Makefile @@ -14,8 +14,8 @@ SYN_FILES += rtl/i2c_master.v SYN_FILES += rtl/si570_i2c_init.v SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v -SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v -SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index 56ded4c0f..0fd1a8b1b 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -39,8 +39,8 @@ srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") diff --git a/example/HXT100G/fpga/fpga/Makefile b/example/HXT100G/fpga/fpga/Makefile index 60e3ea71f..06c1a6e4a 100644 --- a/example/HXT100G/fpga/fpga/Makefile +++ b/example/HXT100G/fpga/fpga/Makefile @@ -19,8 +19,8 @@ SYN_FILES += rtl/gth_i2c_init.v SYN_FILES += rtl/eth_gth_phy_quad.v SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v -SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v -SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index 024c6957b..baf1c7b17 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -39,8 +39,8 @@ srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") diff --git a/example/HXT100G/fpga_cxpt16/fpga/Makefile b/example/HXT100G/fpga_cxpt16/fpga/Makefile index e152f17a4..721af3e0e 100644 --- a/example/HXT100G/fpga_cxpt16/fpga/Makefile +++ b/example/HXT100G/fpga_cxpt16/fpga/Makefile @@ -20,8 +20,8 @@ SYN_FILES += rtl/eth_gth_phy_quad.v SYN_FILES += rtl/axis_crosspoint_16x16.v SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v -SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v -SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v diff --git a/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py b/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py index b2a1cd1a8..b2ac78167 100755 --- a/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py +++ b/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py @@ -38,8 +38,8 @@ srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/axis_crosspoint_16x16.v") srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index fd4c7c93b..8715ba573 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -18,8 +18,8 @@ SYN_FILES += lib/eth/rtl/axis_gmii_rx.v SYN_FILES += lib/eth/rtl/axis_gmii_tx.v SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v -SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v -SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index f16c8cb44..b1dc4cfef 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -44,8 +44,8 @@ srcs.append("../lib/eth/rtl/axis_gmii_rx.v") srcs.append("../lib/eth/rtl/axis_gmii_tx.v") srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile index 3f273da63..ffd94c3b9 100644 --- a/example/VCU118/fpga_10g/fpga/Makefile +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -17,8 +17,8 @@ SYN_FILES += lib/eth/rtl/axis_gmii_rx.v SYN_FILES += lib/eth/rtl/axis_gmii_tx.v SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v -SYN_FILES += lib/eth/rtl/eth_mac_10g_rx.v -SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v diff --git a/example/VCU118/fpga_10g/tb/test_fpga_core.py b/example/VCU118/fpga_10g/tb/test_fpga_core.py index 8226bb74e..87f8c3db5 100755 --- a/example/VCU118/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU118/fpga_10g/tb/test_fpga_core.py @@ -44,8 +44,8 @@ srcs.append("../lib/eth/rtl/axis_gmii_rx.v") srcs.append("../lib/eth/rtl/axis_gmii_tx.v") srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_rx.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") From fe0bf3b7c6b03cdda866bd065024947832f2d010 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 01:08:27 -0700 Subject: [PATCH 414/617] Remove old modules --- rtl/eth_mac_10g_rx.v | 469 -------------------------- rtl/eth_mac_10g_tx.v | 689 -------------------------------------- rtl/eth_mac_1g_rx.v | 250 -------------- rtl/eth_mac_1g_tx.v | 292 ---------------- tb/test_eth_mac_10g_rx.py | 404 ---------------------- tb/test_eth_mac_10g_rx.v | 92 ----- tb/test_eth_mac_10g_tx.py | 340 ------------------- tb/test_eth_mac_10g_tx.v | 97 ------ tb/test_eth_mac_1g_rx.py | 333 ------------------ tb/test_eth_mac_1g_rx.v | 92 ----- tb/test_eth_mac_1g_tx.py | 305 ----------------- tb/test_eth_mac_1g_tx.v | 97 ------ 12 files changed, 3460 deletions(-) delete mode 100644 rtl/eth_mac_10g_rx.v delete mode 100644 rtl/eth_mac_10g_tx.v delete mode 100644 rtl/eth_mac_1g_rx.v delete mode 100644 rtl/eth_mac_1g_tx.v delete mode 100755 tb/test_eth_mac_10g_rx.py delete mode 100644 tb/test_eth_mac_10g_rx.v delete mode 100755 tb/test_eth_mac_10g_tx.py delete mode 100644 tb/test_eth_mac_10g_tx.v delete mode 100755 tb/test_eth_mac_1g_rx.py delete mode 100644 tb/test_eth_mac_1g_rx.v delete mode 100755 tb/test_eth_mac_1g_tx.py delete mode 100644 tb/test_eth_mac_1g_tx.v diff --git a/rtl/eth_mac_10g_rx.v b/rtl/eth_mac_10g_rx.v deleted file mode 100644 index 89f5ff34a..000000000 --- a/rtl/eth_mac_10g_rx.v +++ /dev/null @@ -1,469 +0,0 @@ -/* - -Copyright (c) 2015-2018 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 - -/* - * 10G Ethernet MAC - */ -module eth_mac_10g_rx -( - input wire clk, - input wire rst, - - /* - * XGMII input - */ - input wire [63:0] xgmii_rxd, - input wire [7:0] xgmii_rxc, - - /* - * AXI output - */ - output wire [63:0] output_axis_tdata, - output wire [7:0] output_axis_tkeep, - output wire output_axis_tvalid, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Status - */ - output wire error_bad_frame, - output wire error_bad_fcs -); - -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_PAYLOAD = 3'd1, - STATE_LAST = 3'd2; - -reg [2:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg reset_crc; -reg update_crc; - -reg [7:0] last_cycle_tkeep_reg = 8'd0, last_cycle_tkeep_next; - -reg lanes_swapped = 1'b0; -reg [31:0] swap_rxd = 32'd0; -reg [3:0] swap_rxc = 4'd0; - -reg [63:0] xgmii_rxd_d0 = 64'h0707070707070707; -reg [63:0] xgmii_rxd_d1 = 64'h0707070707070707; - -reg [7:0] xgmii_rxc_d0 = 8'b11111111; -reg [7:0] xgmii_rxc_d1 = 8'b11111111; - -reg [63:0] output_axis_tdata_reg = 64'd0, output_axis_tdata_next; -reg [7:0] output_axis_tkeep_reg = 8'd0, output_axis_tkeep_next; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0, output_axis_tlast_next; -reg output_axis_tuser_reg = 1'b0, output_axis_tuser_next; - -reg error_bad_frame_reg = 1'b0, error_bad_frame_next; -reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; - -reg [31:0] crc_state = 32'hFFFFFFFF; -reg [31:0] crc_state3 = 32'hFFFFFFFF; - -wire [31:0] crc_next0; -wire [31:0] crc_next1; -wire [31:0] crc_next2; -wire [31:0] crc_next3; -wire [31:0] crc_next7; - -wire crc_valid0 = crc_next0 == ~32'h2144df1c; -wire crc_valid1 = crc_next1 == ~32'h2144df1c; -wire crc_valid2 = crc_next2 == ~32'h2144df1c; -wire crc_valid3 = crc_next3 == ~32'h2144df1c; -wire crc_valid7 = crc_next7 == ~32'h2144df1c; - -reg crc_valid7_save = 1'b0; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -assign error_bad_frame = error_bad_frame_reg; -assign error_bad_fcs = error_bad_fcs_reg; - -wire last_cycle = state_reg == STATE_LAST; - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(8), - .STYLE("AUTO") -) -eth_crc_8 ( - .data_in(xgmii_rxd_d0[7:0]), - .state_in(last_cycle ? crc_state3 : crc_state), - .data_out(), - .state_out(crc_next0) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(16), - .STYLE("AUTO") -) -eth_crc_16 ( - .data_in(xgmii_rxd_d0[15:0]), - .state_in(last_cycle ? crc_state3 : crc_state), - .data_out(), - .state_out(crc_next1) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(24), - .STYLE("AUTO") -) -eth_crc_24 ( - .data_in(xgmii_rxd_d0[23:0]), - .state_in(last_cycle ? crc_state3 : crc_state), - .data_out(), - .state_out(crc_next2) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(32), - .STYLE("AUTO") -) -eth_crc_32 ( - .data_in(xgmii_rxd_d0[31:0]), - .state_in(last_cycle ? crc_state3 : crc_state), - .data_out(), - .state_out(crc_next3) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(64), - .STYLE("AUTO") -) -eth_crc_64 ( - .data_in(xgmii_rxd_d0[63:0]), - .state_in(crc_state), - .data_out(), - .state_out(crc_next7) -); - -// detect control characters -reg [7:0] detect_start; -reg [7:0] detect_term; -reg [7:0] detect_error; - -reg [7:0] detect_term_save; - -integer i; - -always @* begin - for (i = 0; i < 8; i = i + 1) begin - detect_start[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfb); - detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfd); - detect_error[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfe); - end -end - -// mask errors to within packet -reg [7:0] detect_error_masked; -reg [7:0] control_masked; -reg [7:0] tkeep_mask; - -always @* begin - casez (detect_term) - 8'b00000000: begin - detect_error_masked = detect_error; - control_masked = xgmii_rxc_d0; - tkeep_mask = 8'b11111111; - end - 8'bzzzzzzz1: begin - detect_error_masked = 0; - control_masked = 0; - tkeep_mask = 8'b00000000; - end - 8'bzzzzzz10: begin - detect_error_masked = detect_error[0]; - control_masked = xgmii_rxc_d0[0]; - tkeep_mask = 8'b00000001; - end - 8'bzzzzz100: begin - detect_error_masked = detect_error[1:0]; - control_masked = xgmii_rxc_d0[1:0]; - tkeep_mask = 8'b00000011; - end - 8'bzzzz1000: begin - detect_error_masked = detect_error[2:0]; - control_masked = xgmii_rxc_d0[2:0]; - tkeep_mask = 8'b00000111; - end - 8'bzzz10000: begin - detect_error_masked = detect_error[3:0]; - control_masked = xgmii_rxc_d0[3:0]; - tkeep_mask = 8'b00001111; - end - 8'bzz100000: begin - detect_error_masked = detect_error[4:0]; - control_masked = xgmii_rxc_d0[4:0]; - tkeep_mask = 8'b00011111; - end - 8'bz1000000: begin - detect_error_masked = detect_error[5:0]; - control_masked = xgmii_rxc_d0[5:0]; - tkeep_mask = 8'b00111111; - end - 8'b10000000: begin - detect_error_masked = detect_error[6:0]; - control_masked = xgmii_rxc_d0[6:0]; - tkeep_mask = 8'b01111111; - end - default: begin - detect_error_masked = detect_error; - control_masked = xgmii_rxc_d0; - tkeep_mask = 8'b11111111; - end - endcase -end - -always @* begin - state_next = STATE_IDLE; - - reset_crc = 1'b0; - update_crc = 1'b0; - - last_cycle_tkeep_next = last_cycle_tkeep_reg; - - output_axis_tdata_next = 64'd0; - output_axis_tkeep_next = 8'd0; - output_axis_tvalid_next = 1'b0; - output_axis_tlast_next = 1'b0; - output_axis_tuser_next = 1'b0; - - error_bad_frame_next = 1'b0; - error_bad_fcs_next = 1'b0; - - case (state_reg) - STATE_IDLE: begin - // idle state - wait for packet - reset_crc = 1'b1; - - if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin - // start condition - if (detect_error_masked) begin - // error in first data word - output_axis_tdata_next = 64'd0; - output_axis_tkeep_next = 8'h01; - output_axis_tvalid_next = 1'b1; - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - state_next = STATE_IDLE; - end else begin - reset_crc = 1'b0; - update_crc = 1'b1; - state_next = STATE_PAYLOAD; - end - end else begin - state_next = STATE_IDLE; - end - end - STATE_PAYLOAD: begin - // read payload - update_crc = 1'b1; - - output_axis_tdata_next = xgmii_rxd_d1; - output_axis_tkeep_next = ~xgmii_rxc_d1; - output_axis_tvalid_next = 1'b1; - output_axis_tlast_next = 1'b0; - output_axis_tuser_next = 1'b0; - - if (control_masked) begin - // control or error characters in packet - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - reset_crc = 1'b1; - state_next = STATE_IDLE; - end else if (detect_term) begin - if (detect_term[4:0]) begin - // end this cycle - reset_crc = 1'b1; - output_axis_tkeep_next = {tkeep_mask[3:0], 4'b1111}; - output_axis_tlast_next = 1'b1; - if ((detect_term[0] & crc_valid7_save) || - (detect_term[1] & crc_valid0) || - (detect_term[2] & crc_valid1) || - (detect_term[3] & crc_valid2) || - (detect_term[4] & crc_valid3)) begin - // CRC valid - end else begin - output_axis_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - error_bad_fcs_next = 1'b1; - end - state_next = STATE_IDLE; - end else begin - // need extra cycle - last_cycle_tkeep_next = {4'b0000, tkeep_mask[7:4]}; - state_next = STATE_LAST; - end - end else begin - state_next = STATE_PAYLOAD; - end - end - STATE_LAST: begin - // last cycle of packet - output_axis_tdata_next = xgmii_rxd_d1; - output_axis_tkeep_next = last_cycle_tkeep_reg; - output_axis_tvalid_next = 1'b1; - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b0; - - reset_crc = 1'b1; - - if ((detect_term_save[5] & crc_valid0) || - (detect_term_save[6] & crc_valid1) || - (detect_term_save[7] & crc_valid2)) begin - // CRC valid - end else begin - output_axis_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - error_bad_fcs_next = 1'b1; - end - - if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin - // start condition - state_next = STATE_PAYLOAD; - end else begin - state_next = STATE_IDLE; - end - end - endcase -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - - output_axis_tvalid_reg <= 1'b0; - - error_bad_frame_reg <= 1'b0; - error_bad_fcs_reg <= 1'b0; - - crc_state <= 32'hFFFFFFFF; - crc_state3 <= 32'hFFFFFFFF; - crc_valid7_save <= 1'b0; - - xgmii_rxd_d0 <= 64'h0707070707070707; - xgmii_rxd_d1 <= 64'h0707070707070707; - - xgmii_rxc_d0 <= 8'b11111111; - xgmii_rxc_d1 <= 8'b11111111; - - lanes_swapped <= 1'b0; - end else begin - state_reg <= state_next; - - output_axis_tvalid_reg <= output_axis_tvalid_next; - - error_bad_frame_reg <= error_bad_frame_next; - error_bad_fcs_reg <= error_bad_fcs_next; - - if (xgmii_rxc[0] && xgmii_rxd[7:0] == 8'hfb) begin - lanes_swapped <= 1'b0; - xgmii_rxd_d0 <= xgmii_rxd; - xgmii_rxc_d0 <= xgmii_rxc; - end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == 8'hfb) begin - lanes_swapped <= 1'b1; - xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; - xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; - end else if (lanes_swapped) begin - xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; - xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; - end else begin - xgmii_rxd_d0 <= xgmii_rxd; - xgmii_rxc_d0 <= xgmii_rxc; - end - - if (state_next == STATE_LAST) begin - xgmii_rxd_d0[31:0] <= xgmii_rxd_d0[63:32]; - xgmii_rxc_d0[3:0] <= xgmii_rxc_d0[7:4]; - end - - xgmii_rxd_d1 <= xgmii_rxd_d0; - xgmii_rxc_d1 <= xgmii_rxc_d0; - - // datapath - if (reset_crc) begin - crc_state <= 32'hFFFFFFFF; - crc_state3 <= 32'hFFFFFFFF; - crc_valid7_save <= 1'b0; - end else if (update_crc) begin - crc_state <= crc_next7; - crc_state3 <= crc_next3; - crc_valid7_save <= crc_valid7; - end - end - - output_axis_tdata_reg <= output_axis_tdata_next; - output_axis_tkeep_reg <= output_axis_tkeep_next; - output_axis_tlast_reg <= output_axis_tlast_next; - output_axis_tuser_reg <= output_axis_tuser_next; - - last_cycle_tkeep_reg <= last_cycle_tkeep_next; - - detect_term_save <= detect_term; - - swap_rxd <= xgmii_rxd[63:32]; - swap_rxc <= xgmii_rxc[7:4]; -end - -endmodule diff --git a/rtl/eth_mac_10g_tx.v b/rtl/eth_mac_10g_tx.v deleted file mode 100644 index aeb99a752..000000000 --- a/rtl/eth_mac_10g_tx.v +++ /dev/null @@ -1,689 +0,0 @@ -/* - -Copyright (c) 2015-2018 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 - -/* - * 10G Ethernet MAC - */ -module eth_mac_10g_tx # -( - parameter ENABLE_PADDING = 1, - parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64 -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [63:0] input_axis_tdata, - input wire [7:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * XGMII output - */ - output wire [63:0] xgmii_txd, - output wire [7:0] xgmii_txc, - - /* - * Configuration - */ - input wire [7:0] ifg_delay -); - -localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; -localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8; -localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007; - -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_PAYLOAD = 3'd1, - STATE_PAD = 3'd2, - STATE_FCS_1 = 3'd3, - STATE_FCS_2 = 3'd4, - STATE_IFG = 3'd5, - STATE_WAIT_END = 3'd6; - -reg [2:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg reset_crc; -reg update_crc; - -reg swap_lanes; -reg unswap_lanes; - -reg lanes_swapped = 1'b0; -reg [31:0] swap_txd = 32'd0; -reg [3:0] swap_txc = 4'd0; - -reg [63:0] input_axis_tdata_masked; - -reg [63:0] input_tdata_reg = 64'd0, input_tdata_next; -reg [7:0] input_tkeep_reg = 8'd0, input_tkeep_next; - -reg [63:0] fcs_output_txd_0; -reg [63:0] fcs_output_txd_1; -reg [7:0] fcs_output_txc_0; -reg [7:0] fcs_output_txc_1; - -reg [7:0] ifg_offset; - -reg extra_cycle; - -reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; - -reg [7:0] ifg_count_reg = 8'd0, ifg_count_next; -reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; - -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; - -reg [31:0] crc_state = 32'hFFFFFFFF; - -wire [31:0] crc_next0; -wire [31:0] crc_next1; -wire [31:0] crc_next2; -wire [31:0] crc_next3; -wire [31:0] crc_next4; -wire [31:0] crc_next5; -wire [31:0] crc_next6; -wire [31:0] crc_next7; - -reg [63:0] xgmii_txd_reg = 64'h0707070707070707, xgmii_txd_next; -reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; - -assign input_axis_tready = input_axis_tready_reg; - -assign xgmii_txd = xgmii_txd_reg; -assign xgmii_txc = xgmii_txc_reg; - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(8), - .STYLE("AUTO") -) -eth_crc_8 ( - .data_in(input_tdata_reg[7:0]), - .state_in(crc_state), - .data_out(), - .state_out(crc_next0) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(16), - .STYLE("AUTO") -) -eth_crc_16 ( - .data_in(input_tdata_reg[15:0]), - .state_in(crc_state), - .data_out(), - .state_out(crc_next1) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(24), - .STYLE("AUTO") -) -eth_crc_24 ( - .data_in(input_tdata_reg[23:0]), - .state_in(crc_state), - .data_out(), - .state_out(crc_next2) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(32), - .STYLE("AUTO") -) -eth_crc_32 ( - .data_in(input_tdata_reg[31:0]), - .state_in(crc_state), - .data_out(), - .state_out(crc_next3) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(40), - .STYLE("AUTO") -) -eth_crc_40 ( - .data_in(input_tdata_reg[39:0]), - .state_in(crc_state), - .data_out(), - .state_out(crc_next4) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(48), - .STYLE("AUTO") -) -eth_crc_48 ( - .data_in(input_tdata_reg[47:0]), - .state_in(crc_state), - .data_out(), - .state_out(crc_next5) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(56), - .STYLE("AUTO") -) -eth_crc_56 ( - .data_in(input_tdata_reg[55:0]), - .state_in(crc_state), - .data_out(), - .state_out(crc_next6) -); - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(64), - .STYLE("AUTO") -) -eth_crc_64 ( - .data_in(input_tdata_reg[63:0]), - .state_in(crc_state), - .data_out(), - .state_out(crc_next7) -); - -function [3:0] keep2count; - input [7:0] k; - casez (k) - 8'bzzzzzzz0: keep2count = 4'd0; - 8'bzzzzzz01: keep2count = 4'd1; - 8'bzzzzz011: keep2count = 4'd2; - 8'bzzzz0111: keep2count = 4'd3; - 8'bzzz01111: keep2count = 4'd4; - 8'bzz011111: keep2count = 4'd5; - 8'bz0111111: keep2count = 4'd6; - 8'b01111111: keep2count = 4'd7; - 8'b11111111: keep2count = 4'd8; - endcase -endfunction - -function [7:0] count2keep; - input [3:0] k; - case (k) - 4'd0: count2keep = 8'b00000000; - 4'd1: count2keep = 8'b00000001; - 4'd2: count2keep = 8'b00000011; - 4'd3: count2keep = 8'b00000111; - 4'd4: count2keep = 8'b00001111; - 4'd5: count2keep = 8'b00011111; - 4'd6: count2keep = 8'b00111111; - 4'd7: count2keep = 8'b01111111; - 4'd8: count2keep = 8'b11111111; - endcase -endfunction - -// Mask input data -integer j; - -always @* begin - for (j = 0; j < 8; j = j + 1) begin - input_axis_tdata_masked[j*8 +: 8] = input_axis_tkeep[j] ? input_axis_tdata[j*8 +: 8] : 8'd0; - end -end - -// FCS cycle calculation -always @* begin - casez (input_tkeep_reg) - 8'bzzzzzz01: begin - fcs_output_txd_0 = {24'h0707fd, ~crc_next0[31:0], input_tdata_reg[7:0]}; - fcs_output_txd_1 = {63'h0707070707070707}; - fcs_output_txc_0 = 8'b11100000; - fcs_output_txc_1 = 8'b11111111; - ifg_offset = 8'd3; - extra_cycle = 1'b0; - end - 8'bzzzzz011: begin - fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], input_tdata_reg[15:0]}; - fcs_output_txd_1 = {63'h0707070707070707}; - fcs_output_txc_0 = 8'b11000000; - fcs_output_txc_1 = 8'b11111111; - ifg_offset = 8'd2; - extra_cycle = 1'b0; - end - 8'bzzzz0111: begin - fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], input_tdata_reg[23:0]}; - fcs_output_txd_1 = {63'h0707070707070707}; - fcs_output_txc_0 = 8'b10000000; - fcs_output_txc_1 = 8'b11111111; - ifg_offset = 8'd1; - extra_cycle = 1'b0; - end - 8'bzzz01111: begin - fcs_output_txd_0 = {~crc_next3[31:0], input_tdata_reg[31:0]}; - fcs_output_txd_1 = {63'h07070707070707fd}; - fcs_output_txc_0 = 8'b00000000; - fcs_output_txc_1 = 8'b11111111; - ifg_offset = 8'd8; - extra_cycle = 1'b1; - end - 8'bzz011111: begin - fcs_output_txd_0 = {~crc_next4[23:0], input_tdata_reg[39:0]}; - fcs_output_txd_1 = {56'h070707070707fd, ~crc_next4[31:24]}; - fcs_output_txc_0 = 8'b00000000; - fcs_output_txc_1 = 8'b11111110; - ifg_offset = 8'd7; - extra_cycle = 1'b1; - end - 8'bz0111111: begin - fcs_output_txd_0 = {~crc_next5[15:0], input_tdata_reg[47:0]}; - fcs_output_txd_1 = {48'h0707070707fd, ~crc_next5[31:16]}; - fcs_output_txc_0 = 8'b00000000; - fcs_output_txc_1 = 8'b11111100; - ifg_offset = 8'd6; - extra_cycle = 1'b1; - end - 8'b01111111: begin - fcs_output_txd_0 = {~crc_next6[7:0], input_tdata_reg[55:0]}; - fcs_output_txd_1 = {40'h07070707fd, ~crc_next6[31:8]}; - fcs_output_txc_0 = 8'b00000000; - fcs_output_txc_1 = 8'b11111000; - ifg_offset = 8'd5; - extra_cycle = 1'b1; - end - 8'b11111111: begin - fcs_output_txd_0 = input_tdata_reg; - fcs_output_txd_1 = {32'h070707fd, ~crc_next7[31:0]}; - fcs_output_txc_0 = 8'b00000000; - fcs_output_txc_1 = 8'b11110000; - ifg_offset = 8'd4; - extra_cycle = 1'b1; - end - default: begin - fcs_output_txd_0 = 64'd0; - fcs_output_txd_1 = 64'd0; - fcs_output_txc_0 = 8'd0; - fcs_output_txc_1 = 8'd0; - ifg_offset = 8'd0; - extra_cycle = 1'b1; - end - endcase -end - -always @* begin - state_next = STATE_IDLE; - - reset_crc = 1'b0; - update_crc = 1'b0; - - swap_lanes = 1'b0; - unswap_lanes = 1'b0; - - frame_ptr_next = frame_ptr_reg; - - ifg_count_next = ifg_count_reg; - deficit_idle_count_next = deficit_idle_count_reg; - - input_axis_tready_next = 1'b0; - - input_tdata_next = input_tdata_reg; - input_tkeep_next = input_tkeep_reg; - - // XGMII idle - xgmii_txd_next = 64'h0707070707070707; - xgmii_txc_next = 8'b11111111; - - case (state_reg) - STATE_IDLE: begin - // idle state - wait for data - frame_ptr_next = 16'd8; - reset_crc = 1'b1; - input_axis_tready_next = 1'b1; - - // XGMII idle - xgmii_txd_next = 64'h0707070707070707; - xgmii_txc_next = 8'b11111111; - - input_tdata_next = input_axis_tdata_masked; - input_tkeep_next = input_axis_tkeep; - - if (input_axis_tvalid) begin - // XGMII start and preamble - if (ifg_count_reg > 8'd0) begin - // need to send more idles - swap lanes - swap_lanes = 1'b1; - end else begin - // no more idles - unswap - unswap_lanes = 1'b1; - end - xgmii_txd_next = 64'hd5555555555555fb; - xgmii_txc_next = 8'b00000001; - input_axis_tready_next = 1'b1; - state_next = STATE_PAYLOAD; - end else begin - ifg_count_next = 8'd0; - deficit_idle_count_next = 2'd0; - unswap_lanes = 1'b1; - state_next = STATE_IDLE; - end - end - STATE_PAYLOAD: begin - // transfer payload - update_crc = 1'b1; - input_axis_tready_next = 1'b1; - - frame_ptr_next = frame_ptr_reg + 16'd8; - - xgmii_txd_next = input_tdata_reg; - xgmii_txc_next = 8'b00000000; - - input_tdata_next = input_axis_tdata_masked; - input_tkeep_next = input_axis_tkeep; - - if (input_axis_tvalid) begin - if (input_axis_tlast) begin - frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); - input_axis_tready_next = 1'b0; - if (input_axis_tuser) begin - xgmii_txd_next = 64'h070707fdfefefefe; - xgmii_txc_next = 8'b11111111; - frame_ptr_next = 16'd0; - ifg_count_next = 8'd8; - state_next = STATE_IFG; - end else begin - input_axis_tready_next = 1'b0; - - if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(input_axis_tkeep) < MIN_FL_NOCRC_LS))) begin - input_tkeep_next = 8'hff; - frame_ptr_next = frame_ptr_reg + 16'd8; - - if (frame_ptr_reg < MIN_FL_NOCRC_MS) begin - state_next = STATE_PAD; - end else begin - input_tkeep_next = 8'hff >> (8-MIN_FL_NOCRC_LS); - state_next = STATE_FCS_1; - end - end else begin - state_next = STATE_FCS_1; - end - end - end else begin - state_next = STATE_PAYLOAD; - end - end else begin - // tvalid deassert, fail frame - xgmii_txd_next = 64'h070707fdfefefefe; - xgmii_txc_next = 8'b11111111; - frame_ptr_next = 16'd0; - ifg_count_next = 8'd8; - state_next = STATE_WAIT_END; - end - end - STATE_PAD: begin - input_axis_tready_next = 1'b0; - - xgmii_txd_next = input_tdata_reg; - xgmii_txc_next = 8'b00000000; - - input_tdata_next = 64'd0; - input_tkeep_next = 8'hff; - - update_crc = 1'b1; - frame_ptr_next = frame_ptr_reg + 16'd8; - - if (frame_ptr_reg < MIN_FL_NOCRC_MS) begin - state_next = STATE_PAD; - end else begin - input_tkeep_next = 8'hff >> (8-MIN_FL_NOCRC_LS); - - state_next = STATE_FCS_1; - end - end - STATE_FCS_1: begin - // last cycle - input_axis_tready_next = 1'b0; - - xgmii_txd_next = fcs_output_txd_0; - xgmii_txc_next = fcs_output_txc_0; - - frame_ptr_next = 16'd0; - - ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + (lanes_swapped ? 8'd4 : 8'd0) + deficit_idle_count_reg; - if (extra_cycle) begin - state_next = STATE_FCS_2; - end else begin - state_next = STATE_IFG; - end - end - STATE_FCS_2: begin - // last cycle - input_axis_tready_next = 1'b0; - - xgmii_txd_next = fcs_output_txd_1; - xgmii_txc_next = fcs_output_txc_1; - - reset_crc = 1'b1; - frame_ptr_next = 16'd0; - - if (ENABLE_DIC) begin - if (ifg_count_next > 8'd7) begin - state_next = STATE_IFG; - end else begin - if (ifg_count_next >= 8'd4) begin - deficit_idle_count_next = ifg_count_next - 8'd4; - end else begin - deficit_idle_count_next = ifg_count_next; - ifg_count_next = 8'd0; - end - input_axis_tready_next = 1'b1; - state_next = STATE_IDLE; - end - end else begin - if (ifg_count_next > 8'd4) begin - state_next = STATE_IFG; - end else begin - input_axis_tready_next = 1'b1; - state_next = STATE_IDLE; - end - end - end - STATE_IFG: begin - // send IFG - if (ifg_count_reg > 8'd8) begin - ifg_count_next = ifg_count_reg - 8'd8; - end else begin - ifg_count_next = 8'd0; - end - - reset_crc = 1'b1; - - if (ENABLE_DIC) begin - if (ifg_count_next > 8'd7) begin - state_next = STATE_IFG; - end else begin - if (ifg_count_next >= 8'd4) begin - deficit_idle_count_next = ifg_count_next - 8'd4; - end else begin - deficit_idle_count_next = ifg_count_next; - ifg_count_next = 8'd0; - end - input_axis_tready_next = 1'b1; - state_next = STATE_IDLE; - end - end else begin - if (ifg_count_next > 8'd4) begin - state_next = STATE_IFG; - end else begin - input_axis_tready_next = 1'b1; - state_next = STATE_IDLE; - end - end - end - STATE_WAIT_END: begin - // wait for end of frame - if (ifg_count_reg > 8'd8) begin - ifg_count_next = ifg_count_reg - 8'd8; - end else begin - ifg_count_next = 8'd0; - end - - reset_crc = 1'b1; - - if (input_axis_tvalid) begin - if (input_axis_tlast) begin - if (ENABLE_DIC) begin - if (ifg_count_next > 8'd7) begin - state_next = STATE_IFG; - end else begin - if (ifg_count_next >= 8'd4) begin - deficit_idle_count_next = ifg_count_next - 8'd4; - end else begin - deficit_idle_count_next = ifg_count_next; - ifg_count_next = 8'd0; - end - input_axis_tready_next = 1'b1; - state_next = STATE_IDLE; - end - end else begin - if (ifg_count_next > 8'd4) begin - state_next = STATE_IFG; - end else begin - input_axis_tready_next = 1'b1; - state_next = STATE_IDLE; - end - end - end else begin - state_next = STATE_WAIT_END; - end - end else begin - state_next = STATE_WAIT_END; - end - end - endcase -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - - frame_ptr_reg <= 16'd0; - - ifg_count_reg <= 8'd0; - deficit_idle_count_reg <= 2'd0; - - input_axis_tready_reg <= 1'b0; - - xgmii_txd_reg <= 64'h0707070707070707; - xgmii_txc_reg <= 8'b11111111; - - crc_state <= 32'hFFFFFFFF; - - lanes_swapped <= 1'b0; - end else begin - state_reg <= state_next; - - frame_ptr_reg <= frame_ptr_next; - - ifg_count_reg <= ifg_count_next; - deficit_idle_count_reg <= deficit_idle_count_next; - - input_axis_tready_reg <= input_axis_tready_next; - - if (lanes_swapped) begin - if (unswap_lanes) begin - lanes_swapped <= 1'b0; - xgmii_txd_reg <= xgmii_txd_next; - xgmii_txc_reg <= xgmii_txc_next; - end else begin - xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd}; - xgmii_txc_reg <= {xgmii_txc_next[3:0], swap_txc}; - end - end else begin - if (swap_lanes) begin - lanes_swapped <= 1'b1; - xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd}; - xgmii_txc_reg <= {xgmii_txc_next[3:0], swap_txc}; - end else begin - xgmii_txd_reg <= xgmii_txd_next; - xgmii_txc_reg <= xgmii_txc_next; - end - end - - // datapath - if (reset_crc) begin - crc_state <= 32'hFFFFFFFF; - end else if (update_crc) begin - crc_state <= crc_next7; - end - end - - input_tdata_reg <= input_tdata_next; - input_tkeep_reg <= input_tkeep_next; - - swap_txd <= xgmii_txd_next[63:32]; - swap_txc <= xgmii_txc_next[7:4]; -end - -endmodule diff --git a/rtl/eth_mac_1g_rx.v b/rtl/eth_mac_1g_rx.v deleted file mode 100644 index 0f13d32ae..000000000 --- a/rtl/eth_mac_1g_rx.v +++ /dev/null @@ -1,250 +0,0 @@ -/* - -Copyright (c) 2015-2018 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 - -/* - * 1G Ethernet MAC - */ -module eth_mac_1g_rx -( - input wire clk, - input wire rst, - - /* - * GMII input - */ - input wire [7:0] gmii_rxd, - input wire gmii_rx_dv, - input wire gmii_rx_er, - - /* - * AXI output - */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Status - */ - output wire error_bad_frame, - output wire error_bad_fcs -); - -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_PAYLOAD = 3'd1, - STATE_WAIT_LAST = 3'd2; - -reg [2:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg reset_crc; -reg update_crc; - -reg [7:0] gmii_rxd_d0 = 8'd0; -reg [7:0] gmii_rxd_d1 = 8'd0; -reg [7:0] gmii_rxd_d2 = 8'd0; -reg [7:0] gmii_rxd_d3 = 8'd0; -reg [7:0] gmii_rxd_d4 = 8'd0; - -reg gmii_rx_dv_d0 = 1'b0; -reg gmii_rx_dv_d1 = 1'b0; -reg gmii_rx_dv_d2 = 1'b0; -reg gmii_rx_dv_d3 = 1'b0; -reg gmii_rx_dv_d4 = 1'b0; - -reg gmii_rx_er_d0 = 1'b0; -reg gmii_rx_er_d1 = 1'b0; -reg gmii_rx_er_d2 = 1'b0; -reg gmii_rx_er_d3 = 1'b0; -reg gmii_rx_er_d4 = 1'b0; - -reg [7:0] output_axis_tdata_reg = 8'd0, output_axis_tdata_next; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0, output_axis_tlast_next; -reg output_axis_tuser_reg = 1'b0, output_axis_tuser_next; - -reg error_bad_frame_reg = 1'b0, error_bad_frame_next; -reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; - -reg [31:0] crc_state = 32'hFFFFFFFF; -wire [31:0] crc_next; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -assign error_bad_frame = error_bad_frame_reg; -assign error_bad_fcs = error_bad_fcs_reg; - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(8), - .STYLE("AUTO") -) -eth_crc_8 ( - .data_in(gmii_rxd_d4), - .state_in(crc_state), - .data_out(), - .state_out(crc_next) -); - -always @* begin - state_next = STATE_IDLE; - - reset_crc = 1'b0; - update_crc = 1'b0; - - output_axis_tdata_next = 8'd0; - output_axis_tvalid_next = 1'b0; - output_axis_tlast_next = 1'b0; - output_axis_tuser_next = 1'b0; - - error_bad_frame_next = 1'b0; - error_bad_fcs_next = 1'b0; - - case (state_reg) - STATE_IDLE: begin - // idle state - wait for packet - reset_crc = 1'b1; - - if (gmii_rx_dv_d4 && ~gmii_rx_er_d4 && gmii_rxd_d4 == 8'hD5) begin - state_next = STATE_PAYLOAD; - end else begin - state_next = STATE_IDLE; - end - end - STATE_PAYLOAD: begin - // read payload - update_crc = 1'b1; - - output_axis_tdata_next = gmii_rxd_d4; - output_axis_tvalid_next = 1'b1; - - if (gmii_rx_dv_d4 & gmii_rx_er_d4) begin - // error - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - state_next = STATE_WAIT_LAST; - end else if (~gmii_rx_dv) begin - // end of packet - output_axis_tlast_next = 1'b1; - if (gmii_rx_er_d0 | gmii_rx_er_d1 | gmii_rx_er_d2 | gmii_rx_er_d3) begin - // error received in FCS bytes - output_axis_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - end else if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin - // FCS good - output_axis_tuser_next = 1'b0; - end else begin - // FCS bad - output_axis_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - error_bad_fcs_next = 1'b1; - end - state_next = STATE_IDLE; - end else begin - state_next = STATE_PAYLOAD; - end - end - STATE_WAIT_LAST: begin - // wait for end of packet - - if (~gmii_rx_dv) begin - state_next = STATE_IDLE; - end else begin - state_next = STATE_WAIT_LAST; - end - end - endcase -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - - output_axis_tvalid_reg <= 1'b0; - - error_bad_frame_reg <= 1'b0; - error_bad_fcs_reg <= 1'b0; - - crc_state <= 32'hFFFFFFFF; - - gmii_rx_dv_d0 <= 1'b0; - gmii_rx_dv_d1 <= 1'b0; - gmii_rx_dv_d2 <= 1'b0; - gmii_rx_dv_d3 <= 1'b0; - gmii_rx_dv_d4 <= 1'b0; - end else begin - state_reg <= state_next; - - output_axis_tvalid_reg <= output_axis_tvalid_next; - - error_bad_frame_reg <= error_bad_frame_next; - error_bad_fcs_reg <= error_bad_fcs_next; - - // datapath - if (reset_crc) begin - crc_state <= 32'hFFFFFFFF; - end else if (update_crc) begin - crc_state <= crc_next; - end - - gmii_rx_dv_d0 <= gmii_rx_dv; - gmii_rx_dv_d1 <= gmii_rx_dv_d0; - gmii_rx_dv_d2 <= gmii_rx_dv_d1; - gmii_rx_dv_d3 <= gmii_rx_dv_d2; - gmii_rx_dv_d4 <= gmii_rx_dv_d3; - end - - output_axis_tdata_reg <= output_axis_tdata_next; - output_axis_tlast_reg <= output_axis_tlast_next; - output_axis_tuser_reg <= output_axis_tuser_next; - - // delay input - gmii_rxd_d0 <= gmii_rxd; - gmii_rxd_d1 <= gmii_rxd_d0; - gmii_rxd_d2 <= gmii_rxd_d1; - gmii_rxd_d3 <= gmii_rxd_d2; - gmii_rxd_d4 <= gmii_rxd_d3; - - gmii_rx_er_d0 <= gmii_rx_er; - gmii_rx_er_d1 <= gmii_rx_er_d0; - gmii_rx_er_d2 <= gmii_rx_er_d1; - gmii_rx_er_d3 <= gmii_rx_er_d2; - gmii_rx_er_d4 <= gmii_rx_er_d3; -end - -endmodule diff --git a/rtl/eth_mac_1g_tx.v b/rtl/eth_mac_1g_tx.v deleted file mode 100644 index 97dea3d92..000000000 --- a/rtl/eth_mac_1g_tx.v +++ /dev/null @@ -1,292 +0,0 @@ -/* - -Copyright (c) 2015-2018 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 - -/* - * 1G Ethernet MAC - */ -module eth_mac_1g_tx # -( - parameter ENABLE_PADDING = 1, - parameter MIN_FRAME_LENGTH = 64 -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [7:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, - - /* - * GMII output - */ - output wire [7:0] gmii_txd, - output wire gmii_tx_en, - output wire gmii_tx_er, - - /* - * Configuration - */ - input wire [7:0] ifg_delay -); - -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_PREAMBLE = 3'd1, - STATE_PAYLOAD = 3'd2, - STATE_PAD = 3'd3, - STATE_FCS = 3'd4, - STATE_WAIT_END = 3'd5, - STATE_IFG = 3'd6; - -reg [2:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg reset_crc; -reg update_crc; - -reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; - -reg [7:0] gmii_txd_reg = 8'd0, gmii_txd_next; -reg gmii_tx_en_reg = 1'b0, gmii_tx_en_next; -reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next; - -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; - -reg [31:0] crc_state = 32'hFFFFFFFF; -wire [31:0] crc_next; - -assign input_axis_tready = input_axis_tready_reg; - -assign gmii_txd = gmii_txd_reg; -assign gmii_tx_en = gmii_tx_en_reg; -assign gmii_tx_er = gmii_tx_er_reg; - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(8), - .STYLE("AUTO") -) -eth_crc_8 ( - .data_in(gmii_txd_next), - .state_in(crc_state), - .data_out(), - .state_out(crc_next) -); - -always @* begin - state_next = STATE_IDLE; - - reset_crc = 1'b0; - update_crc = 1'b0; - - frame_ptr_next = frame_ptr_reg; - - input_axis_tready_next = 1'b0; - - gmii_txd_next = 8'd0; - gmii_tx_en_next = 1'b0; - gmii_tx_er_next = 1'b0; - - case (state_reg) - STATE_IDLE: begin - // idle state - wait for packet - reset_crc = 1'b1; - - if (input_axis_tvalid) begin - frame_ptr_next = 16'd1; - gmii_txd_next = 8'h55; // Preamble - gmii_tx_en_next = 1'b1; - state_next = STATE_PREAMBLE; - end else begin - state_next = STATE_IDLE; - end - end - STATE_PREAMBLE: begin - // send preamble - reset_crc = 1'b1; - frame_ptr_next = frame_ptr_reg + 16'd1; - - gmii_txd_next = 8'h55; // Preamble - gmii_tx_en_next = 1'b1; - - if (frame_ptr_reg == 16'd7) begin - // end of preamble; start payload - frame_ptr_next = 16'd0; - input_axis_tready_next = 1'b1; - gmii_txd_next = 8'hD5; // SFD - state_next = STATE_PAYLOAD; - end else begin - state_next = STATE_PREAMBLE; - end - end - STATE_PAYLOAD: begin - // send payload - update_crc = 1'b1; - input_axis_tready_next = 1'b1; - - frame_ptr_next = frame_ptr_reg + 16'd1; - - gmii_txd_next = input_axis_tdata; - gmii_tx_en_next = 1'b1; - - if (input_axis_tvalid) begin - if (input_axis_tlast) begin - input_axis_tready_next = 1'b0; - if (input_axis_tuser) begin - gmii_tx_er_next = 1'b1; - frame_ptr_next = 1'b0; - state_next = STATE_IFG; - end else begin - if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin - state_next = STATE_PAD; - end else begin - frame_ptr_next = 16'd0; - state_next = STATE_FCS; - end - end - end else begin - state_next = STATE_PAYLOAD; - end - end else begin - // tvalid deassert, fail frame - gmii_tx_er_next = 1'b1; - frame_ptr_next = 16'd0; - state_next = STATE_WAIT_END; - end - end - STATE_PAD: begin - // send padding - update_crc = 1'b1; - frame_ptr_next = frame_ptr_reg + 16'd1; - - gmii_txd_next = 8'd0; - gmii_tx_en_next = 1'b1; - - if (frame_ptr_reg < MIN_FRAME_LENGTH-5) begin - state_next = STATE_PAD; - end else begin - frame_ptr_next = 16'd0; - state_next = STATE_FCS; - end - end - STATE_FCS: begin - // send FCS - frame_ptr_next = frame_ptr_reg + 16'd1; - - case (frame_ptr_reg) - 2'd0: gmii_txd_next = ~crc_state[7:0]; - 2'd1: gmii_txd_next = ~crc_state[15:8]; - 2'd2: gmii_txd_next = ~crc_state[23:16]; - 2'd3: gmii_txd_next = ~crc_state[31:24]; - endcase - gmii_tx_en_next = 1'b1; - - if (frame_ptr_reg < 3) begin - state_next = STATE_FCS; - end else begin - frame_ptr_next = 16'd0; - state_next = STATE_IFG; - end - end - STATE_WAIT_END: begin - // wait for end of frame - frame_ptr_next = frame_ptr_reg + 16'd1; - reset_crc = 1'b1; - - if (input_axis_tvalid) begin - if (input_axis_tlast) begin - if (frame_ptr_reg < ifg_delay-1) begin - state_next = STATE_IFG; - end else begin - state_next = STATE_IDLE; - end - end else begin - state_next = STATE_WAIT_END; - end - end else begin - state_next = STATE_WAIT_END; - end - end - STATE_IFG: begin - // send IFG - frame_ptr_next = frame_ptr_reg + 16'd1; - reset_crc = 1'b1; - - if (frame_ptr_reg < ifg_delay-1) begin - state_next = STATE_IFG; - end else begin - state_next = STATE_IDLE; - end - end - endcase -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - - frame_ptr_reg <= 16'd0; - - input_axis_tready_reg <= 1'b0; - - gmii_txd_reg <= 8'd0; - gmii_tx_en_reg <= 1'b0; - gmii_tx_er_reg <= 1'b0; - - crc_state <= 32'hFFFFFFFF; - end else begin - state_reg <= state_next; - - frame_ptr_reg <= frame_ptr_next; - - input_axis_tready_reg <= input_axis_tready_next; - - gmii_txd_reg <= gmii_txd_next; - gmii_tx_en_reg <= gmii_tx_en_next; - gmii_tx_er_reg <= gmii_tx_er_next; - - // datapath - if (reset_crc) begin - crc_state <= 32'hFFFFFFFF; - end else if (update_crc) begin - crc_state <= crc_next; - end - end -end - -endmodule diff --git a/tb/test_eth_mac_10g_rx.py b/tb/test_eth_mac_10g_rx.py deleted file mode 100755 index f792cc211..000000000 --- a/tb/test_eth_mac_10g_rx.py +++ /dev/null @@ -1,404 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2015-2018 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 - -import axis_ep -import eth_ep -import xgmii_ep - -axis_ep.skip_assert = True - -module = 'eth_mac_10g_rx' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/lfsr.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - xgmii_rxd = Signal(intbv(0x0707070707070707)[64:]) - xgmii_rxc = Signal(intbv(0xff)[8:]) - - # Outputs - 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)) - error_bad_frame = Signal(bool(0)) - error_bad_fcs = Signal(bool(0)) - - # sources and sinks - source = xgmii_ep.XGMIISource() - - source_logic = source.create_logic( - clk, - rst, - txd=xgmii_rxd, - txc=xgmii_rxc, - name='source' - ) - - sink = axis_ep.AXIStreamSink() - - sink_logic = sink.create_logic( - clk, - rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - 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, - - xgmii_rxd=xgmii_rxd, - xgmii_rxc=xgmii_rxc, - - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - error_bad_frame=error_bad_frame, - error_bad_fcs=error_bad_fcs - ) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - error_bad_frame_asserted = Signal(bool(0)) - error_bad_fcs_asserted = Signal(bool(0)) - - @always(clk.posedge) - def monitor(): - if (error_bad_frame): - error_bad_frame_asserted.next = 1 - if (error_bad_fcs): - error_bad_fcs_asserted.next = 1 - - @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,18))+list(range(64,82)): - 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(range(payload_len)) - test_frame.update_fcs() - - axis_frame = test_frame.build_axis_fcs() - - xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - - source.send(xgmii_frame) - - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame - - 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(range(payload_len)) - test_frame1.update_fcs() - 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(range(payload_len)) - test_frame2.update_fcs() - - axis_frame1 = test_frame1.build_axis_fcs() - axis_frame2 = test_frame2.build_axis_fcs() - - xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) - xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) - - source.send(xgmii_frame1) - source.send(xgmii_frame2) - - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame1 - - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame2 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: truncated frame, length %d" % payload_len) - current_test.next = 3 - - 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(range(payload_len)) - test_frame1.update_fcs() - 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(range(payload_len)) - test_frame2.update_fcs() - - axis_frame1 = test_frame1.build_axis_fcs() - axis_frame2 = test_frame2.build_axis_fcs() - - axis_frame1.data = axis_frame1.data[:-1] - - error_bad_frame_asserted.next = 0 - error_bad_fcs_asserted.next = 0 - - xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) - xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) - - source.send(xgmii_frame1) - source.send(xgmii_frame2) - - yield sink.wait() - rx_frame = sink.recv() - - assert error_bad_frame_asserted - assert error_bad_fcs_asserted - - assert rx_frame.user[-1] - - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame2 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 4: errored frame, length %d" % payload_len) - current_test.next = 4 - - 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(range(payload_len)) - test_frame1.update_fcs() - 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(range(payload_len)) - test_frame2.update_fcs() - - axis_frame1 = test_frame1.build_axis_fcs() - axis_frame2 = test_frame2.build_axis_fcs() - - error_bad_frame_asserted.next = 0 - error_bad_fcs_asserted.next = 0 - - xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) - xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) - - xgmii_frame1.error = 1 - - source.send(xgmii_frame1) - source.send(xgmii_frame2) - - yield sink.wait() - rx_frame = sink.recv() - - assert error_bad_frame_asserted - assert not error_bad_fcs_asserted - - assert rx_frame.last_cycle_user - - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame2 - - assert sink.empty() - - yield delay(100) - - for payload_len in list(range(46,54)): - yield clk.posedge - print("test 5: test stream, length %d" % payload_len) - current_test.next = 5 - - for i in range(10): - 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(range(payload_len)) - test_frame.update_fcs() - - axis_frame = test_frame.build_axis_fcs() - - source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - - for i in range(10): - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame - - yield delay(100) - - yield clk.posedge - print("test 6: Ensure 0xfb in FCS in lane 4 is not detected as start code in lane 0") - current_test.next = 6 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x806f - test_frame.payload = bytearray(range(60)) - test_frame.update_fcs() - - axis_frame = test_frame.build_axis_fcs() - - error_bad_frame_asserted.next = 0 - error_bad_fcs_asserted.next = 0 - - xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - - source.send(xgmii_frame) - - yield sink.wait() - rx_frame = sink.recv() - - assert not error_bad_frame_asserted - assert not error_bad_fcs_asserted - - assert not rx_frame.last_cycle_user - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame - - 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() diff --git a/tb/test_eth_mac_10g_rx.v b/tb/test_eth_mac_10g_rx.v deleted file mode 100644 index 1eeed9e48..000000000 --- a/tb/test_eth_mac_10g_rx.v +++ /dev/null @@ -1,92 +0,0 @@ -/* - -Copyright (c) 2015-2018 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 - -/* - * Testbench for eth_mac_10g_rx - */ -module test_eth_mac_10g_rx; - -// Parameters - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [63:0] xgmii_rxd = 64'h0707070707070707; -reg [7:0] xgmii_rxc = 8'hff; - -// Outputs -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 error_bad_frame; -wire error_bad_fcs; - -initial begin - // myhdl integration - $from_myhdl( - clk, - rst, - current_test, - xgmii_rxd, - xgmii_rxc - ); - $to_myhdl( - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, - error_bad_frame, - error_bad_fcs - ); - - // dump file - $dumpfile("test_eth_mac_10g_rx.lxt"); - $dumpvars(0, test_eth_mac_10g_rx); -end - -eth_mac_10g_rx -UUT ( - .clk(clk), - .rst(rst), - .xgmii_rxd(xgmii_rxd), - .xgmii_rxc(xgmii_rxc), - .output_axis_tdata(output_axis_tdata), - .output_axis_tkeep(output_axis_tkeep), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser), - .error_bad_frame(error_bad_frame), - .error_bad_fcs(error_bad_fcs) -); - -endmodule diff --git a/tb/test_eth_mac_10g_tx.py b/tb/test_eth_mac_10g_tx.py deleted file mode 100755 index 0bcf42df0..000000000 --- a/tb/test_eth_mac_10g_tx.py +++ /dev/null @@ -1,340 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2015-2018 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 - -import axis_ep -import eth_ep -import xgmii_ep - -module = 'eth_mac_10g_tx' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/lfsr.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - ENABLE_PADDING = 1 - MIN_FRAME_LENGTH = 64 - - # 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)) - ifg_delay = Signal(intbv(0)[8:]) - - # Outputs - input_axis_tready = Signal(bool(0)) - xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) - xgmii_txc = Signal(intbv(0xff)[8:]) - - # sources and sinks - source_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource() - - source_logic = source.create_logic( - 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, - pause=source_pause, - name='source' - ) - - sink = xgmii_ep.XGMIISink() - - sink_logic = sink.create_logic( - clk, - rst, - rxd=xgmii_txd, - rxc=xgmii_txc, - 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, - - 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, - - xgmii_txd=xgmii_txd, - xgmii_txc=xgmii_txc, - - ifg_delay=ifg_delay - ) - - @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 - - ifg_delay.next = 12 - - # testbench stimulus - - for payload_len in list(range(1,18))+list(range(40,58)): - 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(range(payload_len)) - test_frame.update_fcs() - - axis_frame = test_frame.build_axis() - - source.send(axis_frame) - - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) - - print(hex(eth_frame.eth_fcs)) - print(hex(eth_frame.calc_fcs())) - - assert len(eth_frame.payload.data) == max(payload_len, 46) - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame.eth_src_mac - assert eth_frame.eth_type == test_frame.eth_type - assert eth_frame.payload.data.index(test_frame.payload.data) == 0 - - 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(range(payload_len)) - test_frame1.update_fcs() - 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(range(payload_len)) - test_frame2.update_fcs() - - axis_frame1 = test_frame1.build_axis() - axis_frame2 = test_frame2.build_axis() - - source.send(axis_frame1) - source.send(axis_frame2) - - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) - - print(hex(eth_frame.eth_fcs)) - print(hex(eth_frame.calc_fcs())) - - assert len(eth_frame.payload.data) == max(payload_len, 46) - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame1.eth_src_mac - assert eth_frame.eth_type == test_frame1.eth_type - assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 - - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) - - print(hex(eth_frame.eth_fcs)) - print(hex(eth_frame.calc_fcs())) - - assert len(eth_frame.payload.data) == max(payload_len, 46) - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame2.eth_src_mac - assert eth_frame.eth_type == test_frame2.eth_type - assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: tuser assert, length %d" % payload_len) - current_test.next = 3 - - 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(range(payload_len)) - test_frame1.update_fcs() - 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(range(payload_len)) - test_frame2.update_fcs() - - axis_frame1 = test_frame1.build_axis() - axis_frame2 = test_frame2.build_axis() - - axis_frame1.last_cycle_user = 1 - - source.send(axis_frame1) - source.send(axis_frame2) - - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - assert rx_frame.error[-1] - - # bad packet - - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) - - print(hex(eth_frame.eth_fcs)) - print(hex(eth_frame.calc_fcs())) - - assert len(eth_frame.payload.data) == max(payload_len, 46) - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame2.eth_src_mac - assert eth_frame.eth_type == test_frame2.eth_type - assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 - - assert sink.empty() - - yield delay(100) - - for payload_len in list(range(46,54)): - yield clk.posedge - print("test 4: test stream, length %d" % payload_len) - current_test.next = 4 - - for i in range(10): - 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(range(payload_len)) - test_frame.update_fcs() - - axis_frame = test_frame.build_axis() - - source.send(axis_frame) - - for i in range(10): - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) - - assert len(eth_frame.payload.data) == max(payload_len, 46) - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame.eth_src_mac - assert eth_frame.eth_type == test_frame.eth_type - assert eth_frame.payload.data.index(test_frame.payload.data) == 0 - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/tb/test_eth_mac_10g_tx.v b/tb/test_eth_mac_10g_tx.v deleted file mode 100644 index 14505fc0e..000000000 --- a/tb/test_eth_mac_10g_tx.v +++ /dev/null @@ -1,97 +0,0 @@ -/* - -Copyright (c) 2015-2018 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 - -/* - * Testbench for eth_mac_10g_tx - */ -module test_eth_mac_10g_tx; - -// Parameters -parameter ENABLE_PADDING = 1; -parameter MIN_FRAME_LENGTH = 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 [7:0] ifg_delay = 0; - -// Outputs -wire input_axis_tready; -wire [63:0] xgmii_txd; -wire [7:0] xgmii_txc; - -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, - ifg_delay - ); - $to_myhdl( - input_axis_tready, - xgmii_txd, - xgmii_txc - ); - - // dump file - $dumpfile("test_eth_mac_10g_tx.lxt"); - $dumpvars(0, test_eth_mac_10g_tx); -end - -eth_mac_10g_tx #( - .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) -) -UUT ( - .clk(clk), - .rst(rst), - .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), - .xgmii_txd(xgmii_txd), - .xgmii_txc(xgmii_txc), - .ifg_delay(ifg_delay) -); - -endmodule diff --git a/tb/test_eth_mac_1g_rx.py b/tb/test_eth_mac_1g_rx.py deleted file mode 100755 index c247923a4..000000000 --- a/tb/test_eth_mac_1g_rx.py +++ /dev/null @@ -1,333 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2015-2018 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 - -import axis_ep -import eth_ep -import gmii_ep - -module = 'eth_mac_1g_rx' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/lfsr.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - gmii_rxd = Signal(intbv(0)[8:]) - gmii_rx_dv = Signal(bool(0)) - gmii_rx_er = Signal(bool(0)) - - # Outputs - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - error_bad_frame = Signal(bool(0)) - error_bad_fcs = Signal(bool(0)) - - # sources and sinks - source = gmii_ep.GMIISource() - - source_logic = source.create_logic( - clk, - rst, - txd=gmii_rxd, - tx_en=gmii_rx_dv, - tx_er=gmii_rx_er, - name='source' - ) - - sink = axis_ep.AXIStreamSink() - - sink_logic = sink.create_logic( - clk, - rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tlast=output_axis_tlast, - tuser=output_axis_tuser, - 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, - - gmii_rxd=gmii_rxd, - gmii_rx_dv=gmii_rx_dv, - gmii_rx_er=gmii_rx_er, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, - - error_bad_frame=error_bad_frame, - error_bad_fcs=error_bad_fcs - ) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - error_bad_frame_asserted = Signal(bool(0)) - error_bad_fcs_asserted = Signal(bool(0)) - - @always(clk.posedge) - def monitor(): - if (error_bad_frame): - error_bad_frame_asserted.next = 1 - if (error_bad_fcs): - error_bad_fcs_asserted.next = 1 - - @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,18))+list(range(64,82)): - 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(range(payload_len)) - test_frame.update_fcs() - - axis_frame = test_frame.build_axis_fcs() - gmii_frame = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) - - source.send(gmii_frame) - - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame - - 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(range(payload_len)) - test_frame1.update_fcs() - 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(range(payload_len)) - test_frame2.update_fcs() - - axis_frame1 = test_frame1.build_axis_fcs() - axis_frame2 = test_frame2.build_axis_fcs() - gmii_frame1 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) - gmii_frame2 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) - - source.send(gmii_frame1) - source.send(gmii_frame2) - - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame1 - - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame2 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: truncated frame, length %d" % payload_len) - current_test.next = 3 - - 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(range(payload_len)) - test_frame1.update_fcs() - 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(range(payload_len)) - test_frame2.update_fcs() - - axis_frame1 = test_frame1.build_axis_fcs() - axis_frame2 = test_frame2.build_axis_fcs() - - axis_frame1.data = axis_frame1.data[:-1] - - error_bad_frame_asserted.next = 0 - error_bad_fcs_asserted.next = 0 - - gmii_frame1 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) - gmii_frame2 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) - - source.send(gmii_frame1) - source.send(gmii_frame2) - - yield sink.wait() - rx_frame = sink.recv() - - assert error_bad_frame_asserted - assert error_bad_fcs_asserted - - assert rx_frame.user[-1] - - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame2 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 4: errored frame, length %d" % payload_len) - current_test.next = 4 - - 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(range(payload_len)) - test_frame1.update_fcs() - 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(range(payload_len)) - test_frame2.update_fcs() - - axis_frame1 = test_frame1.build_axis_fcs() - axis_frame2 = test_frame2.build_axis_fcs() - - error_bad_frame_asserted.next = 0 - error_bad_fcs_asserted.next = 0 - - gmii_frame1 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) - gmii_frame2 = gmii_ep.GMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) - - gmii_frame1.error = 1 - - source.send(gmii_frame1) - source.send(gmii_frame2) - - yield sink.wait() - rx_frame = sink.recv() - - assert error_bad_frame_asserted - assert not error_bad_fcs_asserted - - assert rx_frame.last_cycle_user - - yield sink.wait() - rx_frame = sink.recv() - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis(rx_frame) - eth_frame.update_fcs() - - assert eth_frame == test_frame2 - - 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() diff --git a/tb/test_eth_mac_1g_rx.v b/tb/test_eth_mac_1g_rx.v deleted file mode 100644 index 2c174d5ed..000000000 --- a/tb/test_eth_mac_1g_rx.v +++ /dev/null @@ -1,92 +0,0 @@ -/* - -Copyright (c) 2015-2018 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 - -/* - * Testbench for eth_mac_1g_rx - */ -module test_eth_mac_1g_rx; - -// Parameters - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [7:0] gmii_rxd = 0; -reg gmii_rx_dv = 0; -reg gmii_rx_er = 0; - -// Outputs -wire [7:0] output_axis_tdata; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; -wire error_bad_frame; -wire error_bad_fcs; - -initial begin - // myhdl integration - $from_myhdl( - clk, - rst, - current_test, - gmii_rxd, - gmii_rx_dv, - gmii_rx_er - ); - $to_myhdl( - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, - error_bad_frame, - error_bad_fcs - ); - - // dump file - $dumpfile("test_eth_mac_1g_rx.lxt"); - $dumpvars(0, test_eth_mac_1g_rx); -end - -eth_mac_1g_rx -UUT ( - .clk(clk), - .rst(rst), - .gmii_rxd(gmii_rxd), - .gmii_rx_dv(gmii_rx_dv), - .gmii_rx_er(gmii_rx_er), - .output_axis_tdata(output_axis_tdata), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser), - .error_bad_frame(error_bad_frame), - .error_bad_fcs(error_bad_fcs) -); - -endmodule diff --git a/tb/test_eth_mac_1g_tx.py b/tb/test_eth_mac_1g_tx.py deleted file mode 100755 index a3a9e341f..000000000 --- a/tb/test_eth_mac_1g_tx.py +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2015-2018 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 - -import axis_ep -import eth_ep -import gmii_ep - -module = 'eth_mac_1g_tx' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/lfsr.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - ENABLE_PADDING = 1 - MIN_FRAME_LENGTH = 64 - - # 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)) - ifg_delay = Signal(intbv(0)[8:]) - - # Outputs - input_axis_tready = Signal(bool(0)) - gmii_txd = Signal(intbv(0)[8:]) - gmii_tx_en = Signal(bool(0)) - gmii_tx_er = Signal(bool(0)) - - # sources and sinks - source_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource() - - source_logic = source.create_logic( - clk, - rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, - pause=source_pause, - name='source' - ) - - sink = gmii_ep.GMIISink() - - sink_logic = sink.create_logic( - clk, - rst, - rxd=gmii_txd, - rx_dv=gmii_tx_en, - rx_er=gmii_tx_er, - 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, - - 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, - - gmii_txd=gmii_txd, - gmii_tx_en=gmii_tx_en, - gmii_tx_er=gmii_tx_er, - - ifg_delay=ifg_delay - ) - - @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 - - ifg_delay.next = 12 - - # testbench stimulus - - for payload_len in list(range(1,18))+list(range(64,82)): - 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(range(payload_len)) - test_frame.update_fcs() - - axis_frame = test_frame.build_axis() - - source.send(axis_frame) - - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) - - print(hex(eth_frame.eth_fcs)) - print(hex(eth_frame.calc_fcs())) - - assert len(eth_frame.payload.data) == max(payload_len, 46) - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame.eth_src_mac - assert eth_frame.eth_type == test_frame.eth_type - assert eth_frame.payload.data.index(test_frame.payload.data) == 0 - - 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(range(payload_len)) - test_frame1.update_fcs() - 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(range(payload_len)) - test_frame2.update_fcs() - - axis_frame1 = test_frame1.build_axis() - axis_frame2 = test_frame2.build_axis() - - source.send(axis_frame1) - source.send(axis_frame2) - - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) - - print(hex(eth_frame.eth_fcs)) - print(hex(eth_frame.calc_fcs())) - - assert len(eth_frame.payload.data) == max(payload_len, 46) - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame1.eth_src_mac - assert eth_frame.eth_type == test_frame1.eth_type - assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 - - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) - - print(hex(eth_frame.eth_fcs)) - print(hex(eth_frame.calc_fcs())) - - assert len(eth_frame.payload.data) == max(payload_len, 46) - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame2.eth_src_mac - assert eth_frame.eth_type == test_frame2.eth_type - assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: tuser assert, length %d" % payload_len) - current_test.next = 3 - - 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(range(payload_len)) - test_frame1.update_fcs() - 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(range(payload_len)) - test_frame2.update_fcs() - - axis_frame1 = test_frame1.build_axis() - axis_frame2 = test_frame2.build_axis() - - axis_frame1.last_cycle_user = 1 - - source.send(axis_frame1) - source.send(axis_frame2) - - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - assert rx_frame.error[-1] - - # bad packet - - yield sink.wait() - rx_frame = sink.recv() - - assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') - - eth_frame = eth_ep.EthFrame() - eth_frame.parse_axis_fcs(rx_frame.data[8:]) - - print(hex(eth_frame.eth_fcs)) - print(hex(eth_frame.calc_fcs())) - - assert len(eth_frame.payload.data) == max(payload_len, 46) - assert eth_frame.eth_fcs == eth_frame.calc_fcs() - assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac - assert eth_frame.eth_src_mac == test_frame2.eth_src_mac - assert eth_frame.eth_type == test_frame2.eth_type - assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 - - 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() diff --git a/tb/test_eth_mac_1g_tx.v b/tb/test_eth_mac_1g_tx.v deleted file mode 100644 index a0db6462e..000000000 --- a/tb/test_eth_mac_1g_tx.v +++ /dev/null @@ -1,97 +0,0 @@ -/* - -Copyright (c) 2015-2018 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 - -/* - * Testbench for eth_mac_1g_tx - */ -module test_eth_mac_1g_tx; - -// Parameters -parameter ENABLE_PADDING = 1; -parameter MIN_FRAME_LENGTH = 64; - -// 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 [7:0] ifg_delay = 0; - -// Outputs -wire input_axis_tready; -wire [7:0] gmii_txd; -wire gmii_tx_en; -wire gmii_tx_er; - -initial begin - // myhdl integration - $from_myhdl( - clk, - rst, - current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - ifg_delay - ); - $to_myhdl( - input_axis_tready, - gmii_txd, - gmii_tx_en, - gmii_tx_er - ); - - // dump file - $dumpfile("test_eth_mac_1g_tx.lxt"); - $dumpvars(0, test_eth_mac_1g_tx); -end - -eth_mac_1g_tx #( - .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) -) -UUT ( - .clk(clk), - .rst(rst), - .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), - .gmii_txd(gmii_txd), - .gmii_tx_en(gmii_tx_en), - .gmii_tx_er(gmii_tx_er), - .ifg_delay(ifg_delay) -); - -endmodule From 4c711b8c7a9fef6a3e0d5f2badc0c9e76d088192 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 01:19:26 -0700 Subject: [PATCH 415/617] Update readme --- README.md | 90 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f66735f8d..f93bce038 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ datapath for 10G Ethernet. ### arp_cache module -Basic LRU cache for ARP entries. Parametrizable depth. +Basic hash-based cache for ARP entries. Parametrizable depth. ### arp_eth_rx module @@ -63,6 +63,30 @@ Ethernet frame check sequence checker. Ethernet frame check sequence inserter. +### axis_gmii_rx module + +AXI stream GMII/MII frame receiver with clock enable and MII select. + +### axis_gmii_tx module + +AXI stream GMII/MII frame transmitter with clock enable and MII select. + +### axis_xgmii_rx_32 module + +AXI stream XGMII frame receiver with 32 bit datapath. + +### axis_xgmii_rx_64 module + +AXI stream XGMII frame receiver with 64 bit datapath. + +### axis_xgmii_tx_32 module + +AXI stream XGMII frame transmitter with 32 bit datapath. + +### axis_xgmii_tx_64 module + +AXI stream XGMII frame transmitter with 64 bit datapath. + ### eth_arb_mux_N module Ethernet frame arbitrated muliplexer with 8 bit data width for gigabit @@ -115,13 +139,25 @@ Gigabit Ethernet MAC with GMII interface. Gigabit Ethernet MAC with GMII interface and FIFOs. -### eth_mac_1g_rx module +### eth_mac_1g_gmii module -Gigabit Ethernet MAC RX with GMII interface. +Tri-mode Ethernet MAC with GMII/MII interface and automatic PHY rate +adaptation logic. -### eth_mac_1g_tx module +### eth_mac_1g_gmii_fifo module -Gigabit Ethernet MAC TX with GMII interface. +Tri-mode Ethernet MAC with GMII/MII interface, FIFOs, and automatic PHY rate +adaptation logic. + +### eth_mac_1g_rgmii module + +Tri-mode Ethernet MAC with RGMII interface and automatic PHY rate adaptation +logic. + +### eth_mac_1g_rgmii_fifo module + +Tri-mode Ethernet MAC with RGMII interface, FIFOs, and automatic PHY rate +adaptation logic. ### eth_mac_10g module @@ -155,7 +191,7 @@ Can be generated with arbitrary port counts with eth_mux_64.py. ### gmii_phy_if -GMII PHY interface and clocking logic. +GMII/MII PHY interface and clocking logic. ### ip module @@ -241,6 +277,10 @@ Can be generated with arbitrary port counts with ip_mux_64.py. Fully parametrizable combinatorial parallel LFSR/CRC module. +### rgmii_phy_if + +RGMII PHY interface and clocking logic. + ### udp module UDP block with 8 bit data width for gigabit Ethernet. Manages UDP packet @@ -265,6 +305,16 @@ Supports priority and round-robin arbitration. Can be generated with arbitrary port counts with udp_arb_mux_64.py. +### udp_checksum_gen module + +UDP checksum generator module. Calculates UDP length, IP length, and +UDP checksum fields. + +### udp_checksum_gen_64 module + +UDP checksum generator module with 64 bit datapath. Calculates UDP +length, IP length, and UDP checksum fields. + ### udp_complete module UDP module with IPv4 and ARP integration. @@ -345,6 +395,12 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/axis_eth_fcs_64.v : Ethernet FCS calculator (64 bit) rtl/axis_eth_fcs_insert.v : Ethernet FCS inserter rtl/axis_eth_fcs_check.v : Ethernet FCS checker + rtl/axis_gmii_rx.v : AXI stream GMII/MII receiver + rtl/axis_gmii_tx.v : AXI stream GMII/MII transmitter + rtl/axis_xgmii_rx_32.v : AXI stream XGMII receiver (32 bit) + rtl/axis_xgmii_rx_64.v : AXI stream XGMII receiver (64 bit) + rtl/axis_xgmii_tx_32.v : AXI stream XGMII transmitter (32 bit) + rtl/axis_xgmii_tx_64.v : AXI stream XGMII transmitter (64 bit) rtl/eth_arb_mux_2.v : 2 port Ethernet frame arbitrated multiplexer rtl/eth_arb_mux_4.v : 4 port Ethernet frame arbitrated multiplexer rtl/eth_arb_mux_64.py : Ethernet frame arbitrated multiplexer generator (64 bit) @@ -360,8 +416,10 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/eth_demux_64_4.v : 4 port Ethernet frame demultiplexer (64 bit) rtl/eth_mac_1g.v : Gigabit Etherent GMII MAC rtl/eth_mac_1g_fifo.v : Gigabit Etherent GMII MAC with FIFO - rtl/eth_mac_1g_rx.v : Gigabit Etherent GMII MAC RX - rtl/eth_mac_1g_tx.v : Gigabit Etherent GMII MAC TX + rtl/eth_mac_1g_gmii.v : Tri-mode Ethernet GMII/MII MAC + rtl/eth_mac_1g_gmii_fifo.v : Tri-mode Ethernet GMII/MII MAC with FIFO + rtl/eth_mac_1g_rgmii.v : Tri-mode Ethernet RGMII MAC + rtl/eth_mac_1g_rgmii_fifo.v : Tri-mode Ethernet RGMII MAC with FIFO rtl/eth_mac_10g.v : 10G Etherent XGMII MAC rtl/eth_mac_10g_fifo.v : 10G Etherent XGMII MAC with FIFO rtl/eth_mac_10g_rx.v : 10G Etherent XGMII MAC RX @@ -373,6 +431,7 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/eth_mux_64_2.v : 4 port Ethernet frame multiplexer (64 bit) rtl/eth_mux_64_4.v : 4 port Ethernet frame multiplexer (64 bit) rtl/gmii_phy_if.v : GMII PHY interface + rtl/iddr.v : Generic DDR input register rtl/ip.v : IPv4 block rtl/ip_64.v : IPv4 block (64 bit) rtl/ip_arb_mux.py : IP frame arbitrated multiplexer generator @@ -394,12 +453,24 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/ip_mux_64.py : IP frame multiplexer generator (64 bit) rtl/ip_mux_64_4.v : 4 port IP frame multiplexer (64 bit) rtl/lfsr.v : Generic LFSR/CRC module + rtl/oddr.v : Generic DDR output register + rtl/rgmii_phy_if.v : RGMII PHY interface + rtl/ssio_ddr_in.v : Generic source synchronous IO DDR input module + rtl/ssio_ddr_in_diff.v : Generic source synchronous IO DDR differential input module + rtl/ssio_ddr_out.v : Generic source synchronous IO DDR output module + rtl/ssio_ddr_out_diff.v : Generic source synchronous IO DDR differential output module + rtl/ssio_sdr_in.v : Generic source synchronous IO SDR input module + rtl/ssio_sdr_in_diff.v : Generic source synchronous IO SDR differential input module + rtl/ssio_sdr_out.v : Generic source synchronous IO SDR output module + rtl/ssio_sdr_out_diff.v : Generic source synchronous IO SDR differential output module rtl/udp.v : UDP block rtl/udp_64.v : UDP block (64 bit) rtl/udp_arb_mux.py : UDP frame arbitrated multiplexer generator rtl/udp_arb_mux_4.v : 4 port UDP frame arbitrated multiplexer rtl/udp_arb_mux_64.py : UDP frame arbitrated multiplexer generator (64 bit) rtl/udp_arb_mux_64_4.v : 4 port UDP frame arbitrated multiplexer (64 bit) + rtl/udp_checksum_gen.v : UDP checksum generator + rtl/udp_checksum_gen_64.v : UDP checksum generator (64 bit) rtl/udp_complete.v : UDP stack (IP-ARP-UDP) rtl/udp_complete_64.v : UDP stack (IP-ARP-UDP) (64 bit) rtl/udp_ip_rx.v : UDP frame receiver @@ -430,8 +501,6 @@ transfer with header data ___________ _____ _____ tdata XXXXXXXXX_A0________X_A1__X_A2__XXXXXXXXXXXX ___________ _____ _____ - tdata XXXXXXXXX_A0________X_A1__X_A2__XXXXXXXXXXXX - ___________ _____ _____ tkeep XXXXXXXXX_K0________X_K1__X_K2__XXXXXXXXXXXX _______________________ tvalid ________/ \___________ @@ -511,5 +580,6 @@ individual test scripts can be run with python directly. tb/eth_ep.py : MyHDL Ethernet frame endpoints tb/gmii_ep.py : MyHDL GMII endpoints tb/ip_ep.py : MyHDL IP frame endpoints + tb/rgmii_ep.py : MyHDL RGMII endpoints tb/udp_ep.py : MyHDL UDP frame endpoints tb/xgmii_ep.py : MyHDL XGMII endpoints From 2c5679ff6a7886979c433ed3bdd140431c5e3179 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 10:59:02 -0700 Subject: [PATCH 416/617] Update readme --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index f93bce038..ad19f9367 100644 --- a/README.md +++ b/README.md @@ -167,14 +167,6 @@ adaptation logic. 10G Ethernet MAC with XGMII interface and FIFOs. -### eth_mac_10g_rx module - -10G Ethernet MAC RX with XGMII interface. - -### eth_mac_10g_tx module - -10G Ethernet MAC TX with XGMII interface. - ### eth_mux_N module Ethernet frame muliplexer with 8 bit data width for gigabit Ethernet. @@ -422,8 +414,6 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/eth_mac_1g_rgmii_fifo.v : Tri-mode Ethernet RGMII MAC with FIFO rtl/eth_mac_10g.v : 10G Etherent XGMII MAC rtl/eth_mac_10g_fifo.v : 10G Etherent XGMII MAC with FIFO - rtl/eth_mac_10g_rx.v : 10G Etherent XGMII MAC RX - rtl/eth_mac_10g_tx.v : 10G Etherent XGMII MAC TX rtl/eth_mux.py : Ethernet frame multiplexer generator rtl/eth_mux_2.v : 4 port Ethernet frame multiplexer rtl/eth_mux_4.v : 4 port Ethernet frame multiplexer From fe77db822d8a327f0fabc07f4e8172db472d8dcc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 13:44:39 -0700 Subject: [PATCH 417/617] Convert generated crosspoint to verilog parametrized crosspoint --- rtl/axis_crosspoint.py | 227 --------------- rtl/axis_crosspoint.v | 139 +++++++++ rtl/axis_crosspoint_4x4.v | 454 ------------------------------ tb/test_axis_crosspoint_4x4.py | 437 +++++++++------------------- tb/test_axis_crosspoint_4x4.v | 235 ++++------------ tb/test_axis_crosspoint_4x4_64.py | 437 +++++++++------------------- tb/test_axis_crosspoint_4x4_64.v | 235 ++++------------ 7 files changed, 523 insertions(+), 1641 deletions(-) delete mode 100755 rtl/axis_crosspoint.py create mode 100644 rtl/axis_crosspoint.v delete mode 100644 rtl/axis_crosspoint_4x4.v diff --git a/rtl/axis_crosspoint.py b/rtl/axis_crosspoint.py deleted file mode 100755 index 8d21191d3..000000000 --- a/rtl/axis_crosspoint.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/env python -""" -Generates an AXI Stream crosspoint switch with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=[4], nargs='+', help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if type(ports) is int: - m = n = ports - elif len(ports) == 1: - m = n = ports[0] - else: - m, n = ports - - if name is None: - name = "axis_crosspoint_{0}x{1}".format(m, n) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0}x{1} port AXI Stream crosspoint {2}...".format(m, n, name)) - - select_width = int(math.ceil(math.log(m, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 {{m}}x{{n}} crosspoint - */ -module {{name}} # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter LAST_ENABLE = 1, - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1 -) -( - input wire clk, - input wire rst, - - /* - * AXI Stream inputs - */ -{%- for p in range(m) %} - input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, - input wire input_{{p}}_axis_tvalid, - input wire input_{{p}}_axis_tlast, - input wire [ID_WIDTH-1:0] input_{{p}}_axis_tid, - input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, - input wire [USER_WIDTH-1:0] input_{{p}}_axis_tuser, -{% endfor %} - /* - * AXI Stream outputs - */ -{%- for p in range(n) %} - output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, - output wire output_{{p}}_axis_tvalid, - output wire output_{{p}}_axis_tlast, - output wire [ID_WIDTH-1:0] output_{{p}}_axis_tid, - output wire [DEST_WIDTH-1:0] output_{{p}}_axis_tdest, - output wire [USER_WIDTH-1:0] output_{{p}}_axis_tuser, -{% endfor %} - /* - * Control - */ -{%- for p in range(n) %} - input wire [{{w-1}}:0] output_{{p}}_select{% if not loop.last %},{% endif %} -{%- endfor %} -); -{% for p in range(m) %} -reg [DATA_WIDTH-1:0] input_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_{{p}}_axis_tvalid_reg = 1'b0; -reg input_{{p}}_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_{{p}}_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_{{p}}_axis_tuser_reg = {USER_WIDTH{1'b0}}; -{% endfor %} - -{%- for p in range(n) %} -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_{{p}}_axis_tvalid_reg = 1'b0; -reg output_{{p}}_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_{{p}}_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_{{p}}_axis_tuser_reg = {USER_WIDTH{1'b0}}; -{% endfor %} - -{%- for p in range(n) %} -reg [{{w-1}}:0] output_{{p}}_select_reg = {{w}}'d0; -{%- endfor %} -{% for p in range(n) %} -assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; -assign output_{{p}}_axis_tkeep = KEEP_ENABLE ? output_{{p}}_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; -assign output_{{p}}_axis_tlast = LAST_ENABLE ? output_{{p}}_axis_tlast_reg : 1'b1; -assign output_{{p}}_axis_tid = ID_ENABLE ? output_{{p}}_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_{{p}}_axis_tdest = DEST_ENABLE ? output_{{p}}_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_{{p}}_axis_tuser = USER_ENABLE ? output_{{p}}_axis_tuser_reg : {USER_WIDTH{1'b0}}; -{% endfor %} -always @(posedge clk) begin - if (rst) begin -{%- for p in range(n) %} - output_{{p}}_select_reg <= {{w}}'d0; -{%- endfor %} -{% for p in range(m) %} - input_{{p}}_axis_tvalid_reg <= 1'b0; -{%- endfor %} -{% for p in range(n) %} - output_{{p}}_axis_tvalid_reg <= 1'b0; -{%- endfor %} - end else begin -{%- for p in range(m) %} - input_{{p}}_axis_tvalid_reg <= input_{{p}}_axis_tvalid; -{%- endfor %} -{% for p in range(n) %} - output_{{p}}_select_reg <= output_{{p}}_select; -{%- endfor %} -{%- for p in range(n) %} - - case (output_{{p}}_select_reg) -{%- for q in range(m) %} - {{w}}'d{{q}}: output_{{p}}_axis_tvalid_reg <= input_{{q}}_axis_tvalid_reg; -{%- endfor %} - endcase -{%- endfor %} - end -{%- for p in range(m) %} - - input_{{p}}_axis_tdata_reg <= input_{{p}}_axis_tdata; - input_{{p}}_axis_tkeep_reg <= input_{{p}}_axis_tkeep; - input_{{p}}_axis_tlast_reg <= input_{{p}}_axis_tlast; - input_{{p}}_axis_tid_reg <= input_{{p}}_axis_tid; - input_{{p}}_axis_tdest_reg <= input_{{p}}_axis_tdest; - input_{{p}}_axis_tuser_reg <= input_{{p}}_axis_tuser; -{%- endfor %} -{%- for p in range(n) %} - - case (output_{{p}}_select_reg) -{%- for q in range(m) %} - {{w}}'d{{q}}: begin - output_{{p}}_axis_tdata_reg <= input_{{q}}_axis_tdata_reg; - output_{{p}}_axis_tkeep_reg <= input_{{q}}_axis_tkeep_reg; - output_{{p}}_axis_tlast_reg <= input_{{q}}_axis_tlast_reg; - output_{{p}}_axis_tid_reg <= input_{{q}}_axis_tid_reg; - output_{{p}}_axis_tdest_reg <= input_{{q}}_axis_tdest_reg; - output_{{p}}_axis_tuser_reg <= input_{{q}}_axis_tuser_reg; - end -{%- endfor %} - endcase -{%- endfor %} -end - -endmodule - -""") - - output_file.write(t.render( - m=m, - n=n, - w=select_width, - name=name - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_crosspoint.v b/rtl/axis_crosspoint.v new file mode 100644 index 000000000..86abdb08a --- /dev/null +++ b/rtl/axis_crosspoint.v @@ -0,0 +1,139 @@ +/* + +Copyright (c) 2014-2018 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 crosspoint + */ +module axis_crosspoint # +( + parameter S_COUNT = 4, + parameter M_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ + input wire [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep, + input wire [S_COUNT-1:0] s_axis_tvalid, + input wire [S_COUNT-1:0] s_axis_tlast, + input wire [S_COUNT*ID_WIDTH-1:0] s_axis_tid, + input wire [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest, + input wire [S_COUNT*USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI Stream outputs + */ + output wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata, + output wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep, + output wire [M_COUNT-1:0] m_axis_tvalid, + output wire [M_COUNT-1:0] m_axis_tlast, + output wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid, + output wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest, + output wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser, + + /* + * Control + */ + input wire [M_COUNT*$clog2(S_COUNT)-1:0] select +); + +parameter CL_S_COUNT = $clog2(S_COUNT); + +reg [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata_reg = {S_COUNT*DATA_WIDTH{1'b0}}; +reg [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep_reg = {S_COUNT*KEEP_WIDTH{1'b0}}; +reg [S_COUNT-1:0] s_axis_tvalid_reg = {S_COUNT{1'b0}}; +reg [S_COUNT-1:0] s_axis_tlast_reg = {S_COUNT{1'b0}}; +reg [S_COUNT*ID_WIDTH-1:0] s_axis_tid_reg = {S_COUNT*ID_WIDTH{1'b0}}; +reg [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest_reg = {S_COUNT*DEST_WIDTH{1'b0}}; +reg [S_COUNT*USER_WIDTH-1:0] s_axis_tuser_reg = {S_COUNT*USER_WIDTH{1'b0}}; + +reg [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata_reg = {M_COUNT*DATA_WIDTH{1'b0}}; +reg [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep_reg = {M_COUNT*KEEP_WIDTH{1'b0}}; +reg [M_COUNT-1:0] m_axis_tvalid_reg = {M_COUNT{1'b0}}; +reg [M_COUNT-1:0] m_axis_tlast_reg = {M_COUNT{1'b0}}; +reg [M_COUNT*ID_WIDTH-1:0] m_axis_tid_reg = {M_COUNT*ID_WIDTH{1'b0}}; +reg [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest_reg = {M_COUNT*DEST_WIDTH{1'b0}}; +reg [M_COUNT*USER_WIDTH-1:0] m_axis_tuser_reg = {M_COUNT*USER_WIDTH{1'b0}}; + +reg [M_COUNT*CL_S_COUNT-1:0] select_reg = {M_COUNT*CL_S_COUNT{1'b0}}; + +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {M_COUNT*KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : {M_COUNT{1'b1}}; +assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {M_COUNT*ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {M_COUNT*DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {M_COUNT*USER_WIDTH{1'b0}}; + +integer i; + +always @(posedge clk) begin + if (rst) begin + s_axis_tvalid_reg <= {S_COUNT{1'b0}}; + m_axis_tvalid_reg <= {S_COUNT{1'b0}}; + select_reg <= {M_COUNT*CL_S_COUNT{1'b0}}; + end else begin + s_axis_tvalid_reg <= s_axis_tvalid; + for (i = 0; i < M_COUNT; i = i + 1) begin + m_axis_tvalid_reg[i] = s_axis_tvalid_reg[select_reg[i*CL_S_COUNT +: CL_S_COUNT]]; + end + select_reg <= select; + end + + s_axis_tdata_reg <= s_axis_tdata; + s_axis_tkeep_reg <= s_axis_tkeep; + s_axis_tlast_reg <= s_axis_tlast; + s_axis_tid_reg <= s_axis_tid; + s_axis_tdest_reg <= s_axis_tdest; + s_axis_tuser_reg <= s_axis_tuser; + + for (i = 0; i < M_COUNT; i = i + 1) begin + m_axis_tdata_reg[i*DATA_WIDTH +: DATA_WIDTH] <= s_axis_tdata_reg[select_reg[i*CL_S_COUNT +: CL_S_COUNT]*DATA_WIDTH +: DATA_WIDTH]; + m_axis_tkeep_reg[i*KEEP_WIDTH +: KEEP_WIDTH] <= s_axis_tkeep_reg[select_reg[i*CL_S_COUNT +: CL_S_COUNT]*KEEP_WIDTH +: KEEP_WIDTH]; + m_axis_tlast_reg[i] <= s_axis_tlast_reg[select_reg[i*CL_S_COUNT +: CL_S_COUNT]]; + m_axis_tid_reg[i*ID_WIDTH +: ID_WIDTH] <= s_axis_tid_reg[select_reg[i*CL_S_COUNT +: CL_S_COUNT]*ID_WIDTH +: ID_WIDTH]; + m_axis_tdest_reg[i*DEST_WIDTH +: DEST_WIDTH] <= s_axis_tdest_reg[select_reg[i*CL_S_COUNT +: CL_S_COUNT]*DEST_WIDTH +: DEST_WIDTH]; + m_axis_tuser_reg[i*USER_WIDTH +: USER_WIDTH] <= s_axis_tuser_reg[select_reg[i*CL_S_COUNT +: CL_S_COUNT]*USER_WIDTH +: USER_WIDTH]; + end +end + +endmodule diff --git a/rtl/axis_crosspoint_4x4.v b/rtl/axis_crosspoint_4x4.v deleted file mode 100644 index 9e0ca7919..000000000 --- a/rtl/axis_crosspoint_4x4.v +++ /dev/null @@ -1,454 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 4x4 crosspoint - */ -module axis_crosspoint_4x4 # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter LAST_ENABLE = 1, - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1 -) -( - input wire clk, - input wire rst, - - /* - * AXI Stream inputs - */ - input wire [DATA_WIDTH-1:0] input_0_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, - input wire input_0_axis_tvalid, - input wire input_0_axis_tlast, - input wire [ID_WIDTH-1:0] input_0_axis_tid, - input wire [DEST_WIDTH-1:0] input_0_axis_tdest, - input wire [USER_WIDTH-1:0] input_0_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_1_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, - input wire input_1_axis_tvalid, - input wire input_1_axis_tlast, - input wire [ID_WIDTH-1:0] input_1_axis_tid, - input wire [DEST_WIDTH-1:0] input_1_axis_tdest, - input wire [USER_WIDTH-1:0] input_1_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_2_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, - input wire input_2_axis_tvalid, - input wire input_2_axis_tlast, - input wire [ID_WIDTH-1:0] input_2_axis_tid, - input wire [DEST_WIDTH-1:0] input_2_axis_tdest, - input wire [USER_WIDTH-1:0] input_2_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_3_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, - input wire input_3_axis_tvalid, - input wire input_3_axis_tlast, - input wire [ID_WIDTH-1:0] input_3_axis_tid, - input wire [DEST_WIDTH-1:0] input_3_axis_tdest, - input wire [USER_WIDTH-1:0] input_3_axis_tuser, - - /* - * AXI Stream outputs - */ - output wire [DATA_WIDTH-1:0] output_0_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, - output wire output_0_axis_tvalid, - output wire output_0_axis_tlast, - output wire [ID_WIDTH-1:0] output_0_axis_tid, - output wire [DEST_WIDTH-1:0] output_0_axis_tdest, - output wire [USER_WIDTH-1:0] output_0_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_1_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, - output wire output_1_axis_tvalid, - output wire output_1_axis_tlast, - output wire [ID_WIDTH-1:0] output_1_axis_tid, - output wire [DEST_WIDTH-1:0] output_1_axis_tdest, - output wire [USER_WIDTH-1:0] output_1_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_2_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, - output wire output_2_axis_tvalid, - output wire output_2_axis_tlast, - output wire [ID_WIDTH-1:0] output_2_axis_tid, - output wire [DEST_WIDTH-1:0] output_2_axis_tdest, - output wire [USER_WIDTH-1:0] output_2_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_3_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, - output wire output_3_axis_tvalid, - output wire output_3_axis_tlast, - output wire [ID_WIDTH-1:0] output_3_axis_tid, - output wire [DEST_WIDTH-1:0] output_3_axis_tdest, - output wire [USER_WIDTH-1:0] output_3_axis_tuser, - - /* - * Control - */ - input wire [1:0] output_0_select, - input wire [1:0] output_1_select, - input wire [1:0] output_2_select, - input wire [1:0] output_3_select -); - -reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_0_axis_tvalid_reg = 1'b0; -reg input_0_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_0_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_0_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_1_axis_tvalid_reg = 1'b0; -reg input_1_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_1_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_1_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_2_axis_tvalid_reg = 1'b0; -reg input_2_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_2_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_2_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_3_axis_tvalid_reg = 1'b0; -reg input_3_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_3_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_3_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_0_axis_tvalid_reg = 1'b0; -reg output_0_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_0_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_0_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_1_axis_tvalid_reg = 1'b0; -reg output_1_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_1_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_1_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_2_axis_tvalid_reg = 1'b0; -reg output_2_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_2_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_2_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_3_axis_tvalid_reg = 1'b0; -reg output_3_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_3_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_3_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [1:0] output_0_select_reg = 2'd0; -reg [1:0] output_1_select_reg = 2'd0; -reg [1:0] output_2_select_reg = 2'd0; -reg [1:0] output_3_select_reg = 2'd0; - -assign output_0_axis_tdata = output_0_axis_tdata_reg; -assign output_0_axis_tkeep = KEEP_ENABLE ? output_0_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_0_axis_tvalid = output_0_axis_tvalid_reg; -assign output_0_axis_tlast = LAST_ENABLE ? output_0_axis_tlast_reg : 1'b1; -assign output_0_axis_tid = ID_ENABLE ? output_0_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_0_axis_tdest = DEST_ENABLE ? output_0_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_0_axis_tuser = USER_ENABLE ? output_0_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_1_axis_tdata = output_1_axis_tdata_reg; -assign output_1_axis_tkeep = KEEP_ENABLE ? output_1_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_1_axis_tvalid = output_1_axis_tvalid_reg; -assign output_1_axis_tlast = LAST_ENABLE ? output_1_axis_tlast_reg : 1'b1; -assign output_1_axis_tid = ID_ENABLE ? output_1_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_1_axis_tdest = DEST_ENABLE ? output_1_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_1_axis_tuser = USER_ENABLE ? output_1_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_2_axis_tdata = output_2_axis_tdata_reg; -assign output_2_axis_tkeep = KEEP_ENABLE ? output_2_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_2_axis_tvalid = output_2_axis_tvalid_reg; -assign output_2_axis_tlast = LAST_ENABLE ? output_2_axis_tlast_reg : 1'b1; -assign output_2_axis_tid = ID_ENABLE ? output_2_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_2_axis_tdest = DEST_ENABLE ? output_2_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_2_axis_tuser = USER_ENABLE ? output_2_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_3_axis_tdata = output_3_axis_tdata_reg; -assign output_3_axis_tkeep = KEEP_ENABLE ? output_3_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_3_axis_tvalid = output_3_axis_tvalid_reg; -assign output_3_axis_tlast = LAST_ENABLE ? output_3_axis_tlast_reg : 1'b1; -assign output_3_axis_tid = ID_ENABLE ? output_3_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_3_axis_tdest = DEST_ENABLE ? output_3_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_3_axis_tuser = USER_ENABLE ? output_3_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -always @(posedge clk) begin - if (rst) begin - output_0_select_reg <= 2'd0; - output_1_select_reg <= 2'd0; - output_2_select_reg <= 2'd0; - output_3_select_reg <= 2'd0; - - input_0_axis_tvalid_reg <= 1'b0; - input_1_axis_tvalid_reg <= 1'b0; - input_2_axis_tvalid_reg <= 1'b0; - input_3_axis_tvalid_reg <= 1'b0; - - output_0_axis_tvalid_reg <= 1'b0; - output_1_axis_tvalid_reg <= 1'b0; - output_2_axis_tvalid_reg <= 1'b0; - output_3_axis_tvalid_reg <= 1'b0; - end else begin - input_0_axis_tvalid_reg <= input_0_axis_tvalid; - input_1_axis_tvalid_reg <= input_1_axis_tvalid; - input_2_axis_tvalid_reg <= input_2_axis_tvalid; - input_3_axis_tvalid_reg <= input_3_axis_tvalid; - - output_0_select_reg <= output_0_select; - output_1_select_reg <= output_1_select; - output_2_select_reg <= output_2_select; - output_3_select_reg <= output_3_select; - - case (output_0_select_reg) - 2'd0: output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 2'd1: output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 2'd2: output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 2'd3: output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; - endcase - - case (output_1_select_reg) - 2'd0: output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 2'd1: output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 2'd2: output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 2'd3: output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; - endcase - - case (output_2_select_reg) - 2'd0: output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 2'd1: output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 2'd2: output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 2'd3: output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; - endcase - - case (output_3_select_reg) - 2'd0: output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 2'd1: output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 2'd2: output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 2'd3: output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; - endcase - end - - input_0_axis_tdata_reg <= input_0_axis_tdata; - input_0_axis_tkeep_reg <= input_0_axis_tkeep; - input_0_axis_tlast_reg <= input_0_axis_tlast; - input_0_axis_tid_reg <= input_0_axis_tid; - input_0_axis_tdest_reg <= input_0_axis_tdest; - input_0_axis_tuser_reg <= input_0_axis_tuser; - - input_1_axis_tdata_reg <= input_1_axis_tdata; - input_1_axis_tkeep_reg <= input_1_axis_tkeep; - input_1_axis_tlast_reg <= input_1_axis_tlast; - input_1_axis_tid_reg <= input_1_axis_tid; - input_1_axis_tdest_reg <= input_1_axis_tdest; - input_1_axis_tuser_reg <= input_1_axis_tuser; - - input_2_axis_tdata_reg <= input_2_axis_tdata; - input_2_axis_tkeep_reg <= input_2_axis_tkeep; - input_2_axis_tlast_reg <= input_2_axis_tlast; - input_2_axis_tid_reg <= input_2_axis_tid; - input_2_axis_tdest_reg <= input_2_axis_tdest; - input_2_axis_tuser_reg <= input_2_axis_tuser; - - input_3_axis_tdata_reg <= input_3_axis_tdata; - input_3_axis_tkeep_reg <= input_3_axis_tkeep; - input_3_axis_tlast_reg <= input_3_axis_tlast; - input_3_axis_tid_reg <= input_3_axis_tid; - input_3_axis_tdest_reg <= input_3_axis_tdest; - input_3_axis_tuser_reg <= input_3_axis_tuser; - - case (output_0_select_reg) - 2'd0: begin - output_0_axis_tdata_reg <= input_0_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_0_axis_tlast_reg; - output_0_axis_tid_reg <= input_0_axis_tid_reg; - output_0_axis_tdest_reg <= input_0_axis_tdest_reg; - output_0_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_0_axis_tdata_reg <= input_1_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_1_axis_tlast_reg; - output_0_axis_tid_reg <= input_1_axis_tid_reg; - output_0_axis_tdest_reg <= input_1_axis_tdest_reg; - output_0_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_0_axis_tdata_reg <= input_2_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_2_axis_tlast_reg; - output_0_axis_tid_reg <= input_2_axis_tid_reg; - output_0_axis_tdest_reg <= input_2_axis_tdest_reg; - output_0_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_0_axis_tdata_reg <= input_3_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_3_axis_tlast_reg; - output_0_axis_tid_reg <= input_3_axis_tid_reg; - output_0_axis_tdest_reg <= input_3_axis_tdest_reg; - output_0_axis_tuser_reg <= input_3_axis_tuser_reg; - end - endcase - - case (output_1_select_reg) - 2'd0: begin - output_1_axis_tdata_reg <= input_0_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_0_axis_tlast_reg; - output_1_axis_tid_reg <= input_0_axis_tid_reg; - output_1_axis_tdest_reg <= input_0_axis_tdest_reg; - output_1_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_1_axis_tdata_reg <= input_1_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_1_axis_tlast_reg; - output_1_axis_tid_reg <= input_1_axis_tid_reg; - output_1_axis_tdest_reg <= input_1_axis_tdest_reg; - output_1_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_1_axis_tdata_reg <= input_2_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_2_axis_tlast_reg; - output_1_axis_tid_reg <= input_2_axis_tid_reg; - output_1_axis_tdest_reg <= input_2_axis_tdest_reg; - output_1_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_1_axis_tdata_reg <= input_3_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_3_axis_tlast_reg; - output_1_axis_tid_reg <= input_3_axis_tid_reg; - output_1_axis_tdest_reg <= input_3_axis_tdest_reg; - output_1_axis_tuser_reg <= input_3_axis_tuser_reg; - end - endcase - - case (output_2_select_reg) - 2'd0: begin - output_2_axis_tdata_reg <= input_0_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_0_axis_tlast_reg; - output_2_axis_tid_reg <= input_0_axis_tid_reg; - output_2_axis_tdest_reg <= input_0_axis_tdest_reg; - output_2_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_2_axis_tdata_reg <= input_1_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_1_axis_tlast_reg; - output_2_axis_tid_reg <= input_1_axis_tid_reg; - output_2_axis_tdest_reg <= input_1_axis_tdest_reg; - output_2_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_2_axis_tdata_reg <= input_2_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_2_axis_tlast_reg; - output_2_axis_tid_reg <= input_2_axis_tid_reg; - output_2_axis_tdest_reg <= input_2_axis_tdest_reg; - output_2_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_2_axis_tdata_reg <= input_3_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_3_axis_tlast_reg; - output_2_axis_tid_reg <= input_3_axis_tid_reg; - output_2_axis_tdest_reg <= input_3_axis_tdest_reg; - output_2_axis_tuser_reg <= input_3_axis_tuser_reg; - end - endcase - - case (output_3_select_reg) - 2'd0: begin - output_3_axis_tdata_reg <= input_0_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_0_axis_tlast_reg; - output_3_axis_tid_reg <= input_0_axis_tid_reg; - output_3_axis_tdest_reg <= input_0_axis_tdest_reg; - output_3_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 2'd1: begin - output_3_axis_tdata_reg <= input_1_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_1_axis_tlast_reg; - output_3_axis_tid_reg <= input_1_axis_tid_reg; - output_3_axis_tdest_reg <= input_1_axis_tdest_reg; - output_3_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 2'd2: begin - output_3_axis_tdata_reg <= input_2_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_2_axis_tlast_reg; - output_3_axis_tid_reg <= input_2_axis_tid_reg; - output_3_axis_tdest_reg <= input_2_axis_tdest_reg; - output_3_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 2'd3: begin - output_3_axis_tdata_reg <= input_3_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_3_axis_tlast_reg; - output_3_axis_tid_reg <= input_3_axis_tid_reg; - output_3_axis_tdest_reg <= input_3_axis_tdest_reg; - output_3_axis_tuser_reg <= input_3_axis_tuser_reg; - end - endcase -end - -endmodule diff --git a/tb/test_axis_crosspoint_4x4.py b/tb/test_axis_crosspoint_4x4.py index 11df2c56e..b832355ee 100755 --- a/tb/test_axis_crosspoint_4x4.py +++ b/tb/test_axis_crosspoint_4x4.py @@ -27,9 +27,10 @@ from myhdl import * import os import axis_ep +import math -module = 'axis_crosspoint_4x4' -testbench = 'test_%s' % module +module = 'axis_crosspoint' +testbench = 'test_%s_4x4' % module srcs = [] @@ -43,6 +44,8 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + S_COUNT = 4 + M_COUNT = 4 DATA_WIDTH = 8 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) @@ -59,207 +62,92 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_0_axis_tvalid = Signal(bool(0)) - input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_1_axis_tvalid = Signal(bool(0)) - input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_2_axis_tvalid = Signal(bool(0)) - input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_3_axis_tvalid = Signal(bool(0)) - input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_0_select = Signal(intbv(0)[2:]) - output_1_select = Signal(intbv(0)[2:]) - output_2_select = Signal(intbv(0)[2:]) - output_3_select = Signal(intbv(0)[2:]) + s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list)) + s_axis_tkeep = ConcatSignal(*reversed(s_axis_tkeep_list)) + s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list)) + s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list)) + s_axis_tid = ConcatSignal(*reversed(s_axis_tid_list)) + s_axis_tdest = ConcatSignal(*reversed(s_axis_tdest_list)) + s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list)) + + select_list = [Signal(intbv(0)[math.ceil(math.log(S_COUNT, 2)):]) for i in range(M_COUNT)] + + select = ConcatSignal(*reversed(select_list)) # Outputs - output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_0_axis_tvalid = Signal(bool(0)) - output_0_axis_tlast = Signal(bool(0)) - output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_1_axis_tvalid = Signal(bool(0)) - output_1_axis_tlast = Signal(bool(0)) - output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_2_axis_tvalid = Signal(bool(0)) - output_2_axis_tlast = Signal(bool(0)) - output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_3_axis_tvalid = Signal(bool(0)) - output_3_axis_tlast = Signal(bool(0)) - output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_axis_tdata_list = [m_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_axis_tkeep_list = [m_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_axis_tvalid_list = [m_axis_tvalid(i) for i in range(M_COUNT)] + m_axis_tlast_list = [m_axis_tlast(i) for i in range(M_COUNT)] + m_axis_tid_list = [m_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_axis_tdest_list = [m_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_axis_tuser_list = [m_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] - source_0 = axis_ep.AXIStreamSource() + for k in range(S_COUNT): + s = axis_ep.AXIStreamSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tlast=input_0_axis_tlast, - tid=input_0_axis_tid, - tdest=input_0_axis_tdest, - tuser=input_0_axis_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = axis_ep.AXIStreamSource() + source_logic_list.append(s.create_logic( + clk, + rst, + tdata=s_axis_tdata_list[k], + tkeep=s_axis_tkeep_list[k], + tvalid=s_axis_tvalid_list[k], + tlast=s_axis_tlast_list[k], + tid=s_axis_tid_list[k], + tdest=s_axis_tdest_list[k], + tuser=s_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) - source_1_logic = source_1.create_logic( - clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tlast=input_1_axis_tlast, - tid=input_1_axis_tid, - tdest=input_1_axis_tdest, - tuser=input_1_axis_tuser, - pause=source_1_pause, - name='source_1' - ) + for k in range(M_COUNT): + s = axis_ep.AXIStreamSink() + p = Signal(bool(0)) - source_2 = axis_ep.AXIStreamSource() + sink_list.append(s) + sink_pause_list.append(p) - source_2_logic = source_2.create_logic( - clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tlast=input_2_axis_tlast, - tid=input_2_axis_tid, - tdest=input_2_axis_tdest, - tuser=input_2_axis_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = axis_ep.AXIStreamSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tlast=input_3_axis_tlast, - tid=input_3_axis_tid, - tdest=input_3_axis_tdest, - tuser=input_3_axis_tuser, - pause=source_3_pause, - name='source_3' - ) - - sink_0 = axis_ep.AXIStreamSink() - - sink_0_logic = sink_0.create_logic( - clk, - rst, - tdata=output_0_axis_tdata, - tkeep=output_0_axis_tkeep, - tvalid=output_0_axis_tvalid, - tlast=output_0_axis_tlast, - tid=output_0_axis_tid, - tdest=output_0_axis_tdest, - tuser=output_0_axis_tuser, - pause=sink_0_pause, - name='sink_0' - ) - - sink_1 = axis_ep.AXIStreamSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - tdata=output_1_axis_tdata, - tkeep=output_1_axis_tkeep, - tvalid=output_1_axis_tvalid, - tlast=output_1_axis_tlast, - tid=output_1_axis_tid, - tdest=output_1_axis_tdest, - tuser=output_1_axis_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = axis_ep.AXIStreamSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - tdata=output_2_axis_tdata, - tkeep=output_2_axis_tkeep, - tvalid=output_2_axis_tvalid, - tlast=output_2_axis_tlast, - tid=output_2_axis_tid, - tdest=output_2_axis_tdest, - tuser=output_2_axis_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = axis_ep.AXIStreamSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - tdata=output_3_axis_tdata, - tkeep=output_3_axis_tkeep, - tvalid=output_3_axis_tvalid, - tlast=output_3_axis_tlast, - tid=output_3_axis_tid, - tdest=output_3_axis_tdest, - tuser=output_3_axis_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + tdata=m_axis_tdata_list[k], + tkeep=m_axis_tkeep_list[k], + tvalid=m_axis_tvalid_list[k], + tlast=m_axis_tlast_list[k], + tid=m_axis_tid_list[k], + tdest=m_axis_tdest_list[k], + tuser=m_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -271,68 +159,23 @@ def bench(): rst=rst, current_test=current_test, - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tid=input_0_axis_tid, - input_0_axis_tdest=input_0_axis_tdest, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tid=input_1_axis_tid, - input_1_axis_tdest=input_1_axis_tdest, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tid=input_2_axis_tid, - input_2_axis_tdest=input_2_axis_tdest, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tid=input_3_axis_tid, - input_3_axis_tdest=input_3_axis_tdest, - input_3_axis_tuser=input_3_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, - output_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tkeep=output_0_axis_tkeep, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tlast=output_0_axis_tlast, - output_0_axis_tid=output_0_axis_tid, - output_0_axis_tdest=output_0_axis_tdest, - output_0_axis_tuser=output_0_axis_tuser, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tkeep=output_1_axis_tkeep, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tlast=output_1_axis_tlast, - output_1_axis_tid=output_1_axis_tid, - output_1_axis_tdest=output_1_axis_tdest, - output_1_axis_tuser=output_1_axis_tuser, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tkeep=output_2_axis_tkeep, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tlast=output_2_axis_tlast, - output_2_axis_tid=output_2_axis_tid, - output_2_axis_tdest=output_2_axis_tdest, - output_2_axis_tuser=output_2_axis_tuser, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tkeep=output_3_axis_tkeep, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tlast=output_3_axis_tlast, - output_3_axis_tid=output_3_axis_tid, - output_3_axis_tdest=output_3_axis_tdest, - output_3_axis_tuser=output_3_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, - output_0_select=output_0_select, - output_1_select=output_1_select, - output_2_select=output_2_select, - output_3_select=output_3_select + select=select ) @always(delay(4)) @@ -356,37 +199,37 @@ def bench(): print("test 1: 0123 -> 0123") current_test.next = 1 - output_0_select.next = 0 - output_1_select.next = 1 - output_2_select.next = 2 - output_3_select.next = 3 + select_list[0].next = 0 + select_list[1].next = 1 + select_list[2].next = 2 + select_list[3].next = 3 test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04', id=0, dest=0) test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04', id=1, dest=1) test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04', id=2, dest=2) test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04', id=3, dest=3) - source_0.send(test_frame0) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[0].send(test_frame0) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame1 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame2 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame3 @@ -396,37 +239,37 @@ def bench(): print("test 2: 0123 -> 3210") current_test.next = 2 - output_0_select.next = 3 - output_1_select.next = 2 - output_2_select.next = 1 - output_3_select.next = 0 + select_list[0].next = 3 + select_list[1].next = 2 + select_list[2].next = 1 + select_list[3].next = 0 test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04', id=0, dest=3) test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04', id=1, dest=2) test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04', id=2, dest=1) test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04', id=3, dest=0) - source_0.send(test_frame0) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[0].send(test_frame0) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame3 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame2 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame1 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame0 @@ -436,31 +279,31 @@ def bench(): print("test 3: 0000 -> 0123") current_test.next = 3 - output_0_select.next = 0 - output_1_select.next = 0 - output_2_select.next = 0 - output_3_select.next = 0 + select_list[0].next = 0 + select_list[1].next = 0 + select_list[2].next = 0 + select_list[3].next = 0 test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04', id=0, dest=0) - source_0.send(test_frame0) + source_list[0].send(test_frame0) - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame0 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame0 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame0 diff --git a/tb/test_axis_crosspoint_4x4.v b/tb/test_axis_crosspoint_4x4.v index 651d3e5f5..33889afc6 100644 --- a/tb/test_axis_crosspoint_4x4.v +++ b/tb/test_axis_crosspoint_4x4.v @@ -27,11 +27,13 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_crosspoint_4x4 + * Testbench for axis_crosspoint */ module test_axis_crosspoint_4x4; // Parameters +parameter S_COUNT = 4; +parameter M_COUNT = 4; parameter DATA_WIDTH = 8; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); @@ -48,69 +50,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; -reg input_0_axis_tvalid = 0; -reg input_0_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_0_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; -reg input_1_axis_tvalid = 0; -reg input_1_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_1_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; -reg input_2_axis_tvalid = 0; -reg input_2_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_2_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; -reg input_3_axis_tvalid = 0; -reg input_3_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_3_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg [S_COUNT-1:0] s_axis_tvalid = 0; +reg [S_COUNT-1:0] s_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_axis_tuser = 0; -reg [1:0] output_0_select = 0; -reg [1:0] output_1_select = 0; -reg [1:0] output_2_select = 0; -reg [1:0] output_3_select = 0; +reg [M_COUNT*$clog2(S_COUNT)-1:0] select = 0; // Outputs -wire [DATA_WIDTH-1:0] output_0_axis_tdata; -wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; -wire output_0_axis_tvalid; -wire output_0_axis_tlast; -wire [ID_WIDTH-1:0] output_0_axis_tid; -wire [DEST_WIDTH-1:0] output_0_axis_tdest; -wire [USER_WIDTH-1:0] output_0_axis_tuser; -wire [DATA_WIDTH-1:0] output_1_axis_tdata; -wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; -wire output_1_axis_tvalid; -wire output_1_axis_tlast; -wire [ID_WIDTH-1:0] output_1_axis_tid; -wire [DEST_WIDTH-1:0] output_1_axis_tdest; -wire [USER_WIDTH-1:0] output_1_axis_tuser; -wire [DATA_WIDTH-1:0] output_2_axis_tdata; -wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; -wire output_2_axis_tvalid; -wire output_2_axis_tlast; -wire [ID_WIDTH-1:0] output_2_axis_tid; -wire [DEST_WIDTH-1:0] output_2_axis_tdest; -wire [USER_WIDTH-1:0] output_2_axis_tuser; -wire [DATA_WIDTH-1:0] output_3_axis_tdata; -wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; -wire output_3_axis_tvalid; -wire output_3_axis_tlast; -wire [ID_WIDTH-1:0] output_3_axis_tid; -wire [DEST_WIDTH-1:0] output_3_axis_tdest; -wire [USER_WIDTH-1:0] output_3_axis_tuser; +wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep; +wire [M_COUNT-1:0] m_axis_tvalid; +wire [M_COUNT-1:0] m_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -118,68 +75,23 @@ initial begin clk, rst, current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tid, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tid, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tid, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tid, - input_3_axis_tdest, - input_3_axis_tuser, - output_0_select, - output_1_select, - output_2_select, - output_3_select + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + select ); $to_myhdl( - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_0_axis_tid, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_1_axis_tid, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_2_axis_tid, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast, - output_3_axis_tid, - output_3_axis_tdest, - output_3_axis_tuser + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -187,7 +99,9 @@ initial begin $dumpvars(0, test_axis_crosspoint_4x4); end -axis_crosspoint_4x4 #( +axis_crosspoint #( + .S_COUNT(S_COUNT), + .M_COUNT(M_COUNT), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), @@ -203,68 +117,23 @@ UUT ( .clk(clk), .rst(rst), // AXI inputs - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tkeep(input_0_axis_tkeep), - .input_0_axis_tvalid(input_0_axis_tvalid), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tid(input_0_axis_tid), - .input_0_axis_tdest(input_0_axis_tdest), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tkeep(input_1_axis_tkeep), - .input_1_axis_tvalid(input_1_axis_tvalid), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tid(input_1_axis_tid), - .input_1_axis_tdest(input_1_axis_tdest), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tkeep(input_2_axis_tkeep), - .input_2_axis_tvalid(input_2_axis_tvalid), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tid(input_2_axis_tid), - .input_2_axis_tdest(input_2_axis_tdest), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tkeep(input_3_axis_tkeep), - .input_3_axis_tvalid(input_3_axis_tvalid), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tid(input_3_axis_tid), - .input_3_axis_tdest(input_3_axis_tdest), - .input_3_axis_tuser(input_3_axis_tuser), - // AXI outputs - .output_0_axis_tdata(output_0_axis_tdata), - .output_0_axis_tkeep(output_0_axis_tkeep), - .output_0_axis_tvalid(output_0_axis_tvalid), - .output_0_axis_tlast(output_0_axis_tlast), - .output_0_axis_tid(output_0_axis_tid), - .output_0_axis_tdest(output_0_axis_tdest), - .output_0_axis_tuser(output_0_axis_tuser), - .output_1_axis_tdata(output_1_axis_tdata), - .output_1_axis_tkeep(output_1_axis_tkeep), - .output_1_axis_tvalid(output_1_axis_tvalid), - .output_1_axis_tlast(output_1_axis_tlast), - .output_1_axis_tid(output_1_axis_tid), - .output_1_axis_tdest(output_1_axis_tdest), - .output_1_axis_tuser(output_1_axis_tuser), - .output_2_axis_tdata(output_2_axis_tdata), - .output_2_axis_tkeep(output_2_axis_tkeep), - .output_2_axis_tvalid(output_2_axis_tvalid), - .output_2_axis_tlast(output_2_axis_tlast), - .output_2_axis_tid(output_2_axis_tid), - .output_2_axis_tdest(output_2_axis_tdest), - .output_2_axis_tuser(output_2_axis_tuser), - .output_3_axis_tdata(output_3_axis_tdata), - .output_3_axis_tkeep(output_3_axis_tkeep), - .output_3_axis_tvalid(output_3_axis_tvalid), - .output_3_axis_tlast(output_3_axis_tlast), - .output_3_axis_tid(output_3_axis_tid), - .output_3_axis_tdest(output_3_axis_tdest), - .output_3_axis_tuser(output_3_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Control - .output_0_select(output_0_select), - .output_1_select(output_1_select), - .output_2_select(output_2_select), - .output_3_select(output_3_select) + .select(select) ); endmodule diff --git a/tb/test_axis_crosspoint_4x4_64.py b/tb/test_axis_crosspoint_4x4_64.py index cf4c9dd46..ee48ba586 100755 --- a/tb/test_axis_crosspoint_4x4_64.py +++ b/tb/test_axis_crosspoint_4x4_64.py @@ -27,9 +27,10 @@ from myhdl import * import os import axis_ep +import math -module = 'axis_crosspoint_4x4' -testbench = 'test_%s_64' % module +module = 'axis_crosspoint' +testbench = 'test_%s_4x4_64' % module srcs = [] @@ -43,6 +44,8 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + S_COUNT = 4 + M_COUNT = 4 DATA_WIDTH = 64 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) @@ -59,207 +62,92 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_0_axis_tvalid = Signal(bool(0)) - input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_1_axis_tvalid = Signal(bool(0)) - input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_2_axis_tvalid = Signal(bool(0)) - input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_3_axis_tvalid = Signal(bool(0)) - input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_0_select = Signal(intbv(0)[2:]) - output_1_select = Signal(intbv(0)[2:]) - output_2_select = Signal(intbv(0)[2:]) - output_3_select = Signal(intbv(0)[2:]) + s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list)) + s_axis_tkeep = ConcatSignal(*reversed(s_axis_tkeep_list)) + s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list)) + s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list)) + s_axis_tid = ConcatSignal(*reversed(s_axis_tid_list)) + s_axis_tdest = ConcatSignal(*reversed(s_axis_tdest_list)) + s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list)) + + select_list = [Signal(intbv(0)[math.ceil(math.log(S_COUNT, 2)):]) for i in range(M_COUNT)] + + select = ConcatSignal(*reversed(select_list)) # Outputs - output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_0_axis_tvalid = Signal(bool(0)) - output_0_axis_tlast = Signal(bool(0)) - output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_1_axis_tvalid = Signal(bool(0)) - output_1_axis_tlast = Signal(bool(0)) - output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_2_axis_tvalid = Signal(bool(0)) - output_2_axis_tlast = Signal(bool(0)) - output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_3_axis_tvalid = Signal(bool(0)) - output_3_axis_tlast = Signal(bool(0)) - output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_axis_tdata_list = [m_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_axis_tkeep_list = [m_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_axis_tvalid_list = [m_axis_tvalid(i) for i in range(M_COUNT)] + m_axis_tlast_list = [m_axis_tlast(i) for i in range(M_COUNT)] + m_axis_tid_list = [m_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_axis_tdest_list = [m_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_axis_tuser_list = [m_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] - source_0 = axis_ep.AXIStreamSource() + for k in range(S_COUNT): + s = axis_ep.AXIStreamSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tlast=input_0_axis_tlast, - tid=input_0_axis_tid, - tdest=input_0_axis_tdest, - tuser=input_0_axis_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = axis_ep.AXIStreamSource() + source_logic_list.append(s.create_logic( + clk, + rst, + tdata=s_axis_tdata_list[k], + tkeep=s_axis_tkeep_list[k], + tvalid=s_axis_tvalid_list[k], + tlast=s_axis_tlast_list[k], + tid=s_axis_tid_list[k], + tdest=s_axis_tdest_list[k], + tuser=s_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) - source_1_logic = source_1.create_logic( - clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tlast=input_1_axis_tlast, - tid=input_1_axis_tid, - tdest=input_1_axis_tdest, - tuser=input_1_axis_tuser, - pause=source_1_pause, - name='source_1' - ) + for k in range(M_COUNT): + s = axis_ep.AXIStreamSink() + p = Signal(bool(0)) - source_2 = axis_ep.AXIStreamSource() + sink_list.append(s) + sink_pause_list.append(p) - source_2_logic = source_2.create_logic( - clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tlast=input_2_axis_tlast, - tid=input_2_axis_tid, - tdest=input_2_axis_tdest, - tuser=input_2_axis_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = axis_ep.AXIStreamSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tlast=input_3_axis_tlast, - tid=input_3_axis_tid, - tdest=input_3_axis_tdest, - tuser=input_3_axis_tuser, - pause=source_3_pause, - name='source_3' - ) - - sink_0 = axis_ep.AXIStreamSink() - - sink_0_logic = sink_0.create_logic( - clk, - rst, - tdata=output_0_axis_tdata, - tkeep=output_0_axis_tkeep, - tvalid=output_0_axis_tvalid, - tlast=output_0_axis_tlast, - tid=output_0_axis_tid, - tdest=output_0_axis_tdest, - tuser=output_0_axis_tuser, - pause=sink_0_pause, - name='sink_0' - ) - - sink_1 = axis_ep.AXIStreamSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - tdata=output_1_axis_tdata, - tkeep=output_1_axis_tkeep, - tvalid=output_1_axis_tvalid, - tlast=output_1_axis_tlast, - tid=output_1_axis_tid, - tdest=output_1_axis_tdest, - tuser=output_1_axis_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = axis_ep.AXIStreamSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - tdata=output_2_axis_tdata, - tkeep=output_2_axis_tkeep, - tvalid=output_2_axis_tvalid, - tlast=output_2_axis_tlast, - tid=output_2_axis_tid, - tdest=output_2_axis_tdest, - tuser=output_2_axis_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = axis_ep.AXIStreamSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - tdata=output_3_axis_tdata, - tkeep=output_3_axis_tkeep, - tvalid=output_3_axis_tvalid, - tlast=output_3_axis_tlast, - tid=output_3_axis_tid, - tdest=output_3_axis_tdest, - tuser=output_3_axis_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + tdata=m_axis_tdata_list[k], + tkeep=m_axis_tkeep_list[k], + tvalid=m_axis_tvalid_list[k], + tlast=m_axis_tlast_list[k], + tid=m_axis_tid_list[k], + tdest=m_axis_tdest_list[k], + tuser=m_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -271,68 +159,23 @@ def bench(): rst=rst, current_test=current_test, - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tid=input_0_axis_tid, - input_0_axis_tdest=input_0_axis_tdest, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tid=input_1_axis_tid, - input_1_axis_tdest=input_1_axis_tdest, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tid=input_2_axis_tid, - input_2_axis_tdest=input_2_axis_tdest, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tid=input_3_axis_tid, - input_3_axis_tdest=input_3_axis_tdest, - input_3_axis_tuser=input_3_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, - output_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tkeep=output_0_axis_tkeep, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tlast=output_0_axis_tlast, - output_0_axis_tid=output_0_axis_tid, - output_0_axis_tdest=output_0_axis_tdest, - output_0_axis_tuser=output_0_axis_tuser, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tkeep=output_1_axis_tkeep, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tlast=output_1_axis_tlast, - output_1_axis_tid=output_1_axis_tid, - output_1_axis_tdest=output_1_axis_tdest, - output_1_axis_tuser=output_1_axis_tuser, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tkeep=output_2_axis_tkeep, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tlast=output_2_axis_tlast, - output_2_axis_tid=output_2_axis_tid, - output_2_axis_tdest=output_2_axis_tdest, - output_2_axis_tuser=output_2_axis_tuser, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tkeep=output_3_axis_tkeep, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tlast=output_3_axis_tlast, - output_3_axis_tid=output_3_axis_tid, - output_3_axis_tdest=output_3_axis_tdest, - output_3_axis_tuser=output_3_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, - output_0_select=output_0_select, - output_1_select=output_1_select, - output_2_select=output_2_select, - output_3_select=output_3_select + select=select ) @always(delay(4)) @@ -356,37 +199,37 @@ def bench(): print("test 1: 0123 -> 0123") current_test.next = 1 - output_0_select.next = 0 - output_1_select.next = 1 - output_2_select.next = 2 - output_3_select.next = 3 + select_list[0].next = 0 + select_list[1].next = 1 + select_list[2].next = 2 + select_list[3].next = 3 test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04', id=0, dest=0) test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04', id=1, dest=1) test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04', id=2, dest=2) test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04', id=3, dest=3) - source_0.send(test_frame0) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[0].send(test_frame0) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame1 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame2 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame3 @@ -396,37 +239,37 @@ def bench(): print("test 2: 0123 -> 3210") current_test.next = 2 - output_0_select.next = 3 - output_1_select.next = 2 - output_2_select.next = 1 - output_3_select.next = 0 + select_list[0].next = 3 + select_list[1].next = 2 + select_list[2].next = 1 + select_list[3].next = 0 test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04', id=0, dest=3) test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04', id=1, dest=2) test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04', id=2, dest=1) test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04', id=3, dest=0) - source_0.send(test_frame0) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[0].send(test_frame0) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame3 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame2 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame1 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame0 @@ -436,31 +279,31 @@ def bench(): print("test 3: 0000 -> 0123") current_test.next = 3 - output_0_select.next = 0 - output_1_select.next = 0 - output_2_select.next = 0 - output_3_select.next = 0 + select_list[0].next = 0 + select_list[1].next = 0 + select_list[2].next = 0 + select_list[3].next = 0 test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04', id=0, dest=0) - source_0.send(test_frame0) + source_list[0].send(test_frame0) - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame0 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame0 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame0 diff --git a/tb/test_axis_crosspoint_4x4_64.v b/tb/test_axis_crosspoint_4x4_64.v index e1e54e8d6..238390ac6 100644 --- a/tb/test_axis_crosspoint_4x4_64.v +++ b/tb/test_axis_crosspoint_4x4_64.v @@ -27,11 +27,13 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_crosspoint_4x4 + * Testbench for axis_crosspoint */ module test_axis_crosspoint_4x4_64; // Parameters +parameter S_COUNT = 4; +parameter M_COUNT = 4; parameter DATA_WIDTH = 64; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); @@ -48,69 +50,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; -reg input_0_axis_tvalid = 0; -reg input_0_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_0_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; -reg input_1_axis_tvalid = 0; -reg input_1_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_1_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; -reg input_2_axis_tvalid = 0; -reg input_2_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_2_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; -reg input_3_axis_tvalid = 0; -reg input_3_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_3_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg [S_COUNT-1:0] s_axis_tvalid = 0; +reg [S_COUNT-1:0] s_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_axis_tuser = 0; -reg [1:0] output_0_select = 0; -reg [1:0] output_1_select = 0; -reg [1:0] output_2_select = 0; -reg [1:0] output_3_select = 0; +reg [M_COUNT*$clog2(S_COUNT)-1:0] select = 0; // Outputs -wire [DATA_WIDTH-1:0] output_0_axis_tdata; -wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; -wire output_0_axis_tvalid; -wire output_0_axis_tlast; -wire [ID_WIDTH-1:0] output_0_axis_tid; -wire [DEST_WIDTH-1:0] output_0_axis_tdest; -wire [USER_WIDTH-1:0] output_0_axis_tuser; -wire [DATA_WIDTH-1:0] output_1_axis_tdata; -wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; -wire output_1_axis_tvalid; -wire output_1_axis_tlast; -wire [ID_WIDTH-1:0] output_1_axis_tid; -wire [DEST_WIDTH-1:0] output_1_axis_tdest; -wire [USER_WIDTH-1:0] output_1_axis_tuser; -wire [DATA_WIDTH-1:0] output_2_axis_tdata; -wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; -wire output_2_axis_tvalid; -wire output_2_axis_tlast; -wire [ID_WIDTH-1:0] output_2_axis_tid; -wire [DEST_WIDTH-1:0] output_2_axis_tdest; -wire [USER_WIDTH-1:0] output_2_axis_tuser; -wire [DATA_WIDTH-1:0] output_3_axis_tdata; -wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; -wire output_3_axis_tvalid; -wire output_3_axis_tlast; -wire [ID_WIDTH-1:0] output_3_axis_tid; -wire [DEST_WIDTH-1:0] output_3_axis_tdest; -wire [USER_WIDTH-1:0] output_3_axis_tuser; +wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep; +wire [M_COUNT-1:0] m_axis_tvalid; +wire [M_COUNT-1:0] m_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -118,68 +75,23 @@ initial begin clk, rst, current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tid, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tid, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tid, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tid, - input_3_axis_tdest, - input_3_axis_tuser, - output_0_select, - output_1_select, - output_2_select, - output_3_select + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + select ); $to_myhdl( - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_0_axis_tid, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_1_axis_tid, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_2_axis_tid, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast, - output_3_axis_tid, - output_3_axis_tdest, - output_3_axis_tuser + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -187,7 +99,9 @@ initial begin $dumpvars(0, test_axis_crosspoint_4x4_64); end -axis_crosspoint_4x4 #( +axis_crosspoint #( + .S_COUNT(S_COUNT), + .M_COUNT(M_COUNT), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), @@ -203,68 +117,23 @@ UUT ( .clk(clk), .rst(rst), // AXI inputs - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tkeep(input_0_axis_tkeep), - .input_0_axis_tvalid(input_0_axis_tvalid), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tid(input_0_axis_tid), - .input_0_axis_tdest(input_0_axis_tdest), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tkeep(input_1_axis_tkeep), - .input_1_axis_tvalid(input_1_axis_tvalid), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tid(input_1_axis_tid), - .input_1_axis_tdest(input_1_axis_tdest), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tkeep(input_2_axis_tkeep), - .input_2_axis_tvalid(input_2_axis_tvalid), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tid(input_2_axis_tid), - .input_2_axis_tdest(input_2_axis_tdest), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tkeep(input_3_axis_tkeep), - .input_3_axis_tvalid(input_3_axis_tvalid), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tid(input_3_axis_tid), - .input_3_axis_tdest(input_3_axis_tdest), - .input_3_axis_tuser(input_3_axis_tuser), - // AXI outputs - .output_0_axis_tdata(output_0_axis_tdata), - .output_0_axis_tkeep(output_0_axis_tkeep), - .output_0_axis_tvalid(output_0_axis_tvalid), - .output_0_axis_tlast(output_0_axis_tlast), - .output_0_axis_tid(output_0_axis_tid), - .output_0_axis_tdest(output_0_axis_tdest), - .output_0_axis_tuser(output_0_axis_tuser), - .output_1_axis_tdata(output_1_axis_tdata), - .output_1_axis_tkeep(output_1_axis_tkeep), - .output_1_axis_tvalid(output_1_axis_tvalid), - .output_1_axis_tlast(output_1_axis_tlast), - .output_1_axis_tid(output_1_axis_tid), - .output_1_axis_tdest(output_1_axis_tdest), - .output_1_axis_tuser(output_1_axis_tuser), - .output_2_axis_tdata(output_2_axis_tdata), - .output_2_axis_tkeep(output_2_axis_tkeep), - .output_2_axis_tvalid(output_2_axis_tvalid), - .output_2_axis_tlast(output_2_axis_tlast), - .output_2_axis_tid(output_2_axis_tid), - .output_2_axis_tdest(output_2_axis_tdest), - .output_2_axis_tuser(output_2_axis_tuser), - .output_3_axis_tdata(output_3_axis_tdata), - .output_3_axis_tkeep(output_3_axis_tkeep), - .output_3_axis_tvalid(output_3_axis_tvalid), - .output_3_axis_tlast(output_3_axis_tlast), - .output_3_axis_tid(output_3_axis_tid), - .output_3_axis_tdest(output_3_axis_tdest), - .output_3_axis_tuser(output_3_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Control - .output_0_select(output_0_select), - .output_1_select(output_1_select), - .output_2_select(output_2_select), - .output_3_select(output_3_select) + .select(select) ); endmodule From 940c1210c18c6811b339d95484ae7d676eb7a663 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 13:49:17 -0700 Subject: [PATCH 418/617] Convert arbitrated mux to verilog parametrized arbitrated mux --- rtl/axis_arb_mux.py | 327 ---------------------------------- rtl/axis_arb_mux.v | 245 ++++++++++++++++++++++++++ rtl/axis_arb_mux_4.v | 330 ----------------------------------- tb/test_axis_arb_mux_4.py | 285 +++++++++++------------------- tb/test_axis_arb_mux_4.v | 174 ++++++------------ tb/test_axis_arb_mux_4_64.py | 285 +++++++++++------------------- tb/test_axis_arb_mux_4_64.v | 174 ++++++------------ 7 files changed, 545 insertions(+), 1275 deletions(-) delete mode 100755 rtl/axis_arb_mux.py create mode 100644 rtl/axis_arb_mux.v delete mode 100644 rtl/axis_arb_mux_4.v diff --git a/rtl/axis_arb_mux.py b/rtl/axis_arb_mux.py deleted file mode 100755 index 59025e212..000000000 --- a/rtl/axis_arb_mux.py +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/env python -""" -Generates an arbitrated AXI Stream mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "axis_arb_mux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port AXI Stream arbitrated mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream {{n}} port arbitrated multiplexer - */ -module {{name}} # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1, - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ -{%- for p in ports %} - input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, - input wire input_{{p}}_axis_tvalid, - output wire input_{{p}}_axis_tready, - input wire input_{{p}}_axis_tlast, - input wire [ID_WIDTH-1:0] input_{{p}}_axis_tid, - input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, - input wire [USER_WIDTH-1:0] input_{{p}}_axis_tuser, -{% endfor %} - /* - * 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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser -); - -wire [{{n-1}}:0] request; -wire [{{n-1}}:0] acknowledge; -wire [{{n-1}}:0] grant; -wire grant_valid; -wire [{{w-1}}:0] grant_encoded; - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg [ID_WIDTH-1:0] output_axis_tid_int; -reg [DEST_WIDTH-1:0] output_axis_tdest_int; -reg [USER_WIDTH-1:0] output_axis_tuser_int; -wire output_axis_tready_int_early; -{% for p in ports %} -assign input_{{p}}_axis_tready = grant[{{p}}] & output_axis_tready_int_reg; -{%- endfor %} - -// mux for incoming packet -reg [DATA_WIDTH-1:0] current_input_tdata; -reg [KEEP_WIDTH-1:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg [ID_WIDTH-1:0] current_input_tid; -reg [DEST_WIDTH-1:0] current_input_tdest; -reg [USER_WIDTH-1:0] current_input_tuser; -always @* begin - case (grant_encoded) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_input_tdata = input_{{p}}_axis_tdata; - current_input_tkeep = input_{{p}}_axis_tkeep; - current_input_tvalid = input_{{p}}_axis_tvalid; - current_input_tready = input_{{p}}_axis_tready; - current_input_tlast = input_{{p}}_axis_tlast; - current_input_tid = input_{{p}}_axis_tid; - current_input_tdest = input_{{p}}_axis_tdest; - current_input_tuser = input_{{p}}_axis_tuser; - end -{%- endfor %} - default: begin - current_input_tdata = {DATA_WIDTH{1'b0}}; - current_input_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tid = {ID_WIDTH{1'b0}}; - current_input_tdest = {DEST_WIDTH{1'b0}}; - current_input_tuser = {USER_WIDTH{1'b0}}; - end - endcase -end - -// arbiter instance - -arbiter #( - .PORTS({{n}}), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -// request generation -{%- for p in ports %} -assign request[{{p}}] = input_{{p}}_axis_tvalid & ~acknowledge[{{p}}]; -{%- endfor %} - -// acknowledge generation -{%- for p in ports %} -assign acknowledge[{{p}}] = grant[{{p}}] & input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast; -{%- endfor %} - -always @* begin - // pass through selected packet data - output_axis_tdata_int = current_input_tdata; - output_axis_tkeep_int = current_input_tkeep; - output_axis_tvalid_int = current_input_tvalid & current_input_tready; - output_axis_tlast_int = current_input_tlast; - output_axis_tid_int = current_input_tid; - output_axis_tdest_int = current_input_tdest; - output_axis_tuser_int = current_input_tuser; -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tid_reg <= output_axis_tid_int; - output_axis_tdest_reg <= output_axis_tdest_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tid_reg <= output_axis_tid_int; - temp_axis_tdest_reg <= output_axis_tdest_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_arb_mux.v b/rtl/axis_arb_mux.v new file mode 100644 index 000000000..3e2ce62b4 --- /dev/null +++ b/rtl/axis_arb_mux.v @@ -0,0 +1,245 @@ +/* + +Copyright (c) 2014-2018 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 arbitrated multiplexer + */ +module axis_arb_mux # +( + parameter S_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ + input wire [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep, + input wire [S_COUNT-1:0] s_axis_tvalid, + output wire [S_COUNT-1:0] s_axis_tready, + input wire [S_COUNT-1:0] s_axis_tlast, + input wire [S_COUNT*ID_WIDTH-1:0] s_axis_tid, + input wire [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest, + input wire [S_COUNT*USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI Stream output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser +); + +parameter CL_S_COUNT = $clog2(S_COUNT); + +wire [S_COUNT-1:0] request; +wire [S_COUNT-1:0] acknowledge; +wire [S_COUNT-1:0] grant; +wire grant_valid; +wire [CL_S_COUNT-1:0] grant_encoded; + +// internal datapath +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg [ID_WIDTH-1:0] m_axis_tid_int; +reg [DEST_WIDTH-1:0] m_axis_tdest_int; +reg [USER_WIDTH-1:0] m_axis_tuser_int; +wire m_axis_tready_int_early; + +assign s_axis_tready = (m_axis_tready_int_reg && grant_valid) << grant_encoded; + +// mux for incoming packet +wire [DATA_WIDTH-1:0] current_s_tdata = s_axis_tdata[grant_encoded*DATA_WIDTH +: DATA_WIDTH]; +wire [KEEP_WIDTH-1:0] current_s_tkeep = s_axis_tkeep[grant_encoded*KEEP_WIDTH +: KEEP_WIDTH]; +wire current_s_tvalid = s_axis_tvalid[grant_encoded]; +wire current_s_tready = s_axis_tready[grant_encoded]; +wire current_s_tlast = s_axis_tlast[grant_encoded]; +wire [ID_WIDTH-1:0] current_s_tid = s_axis_tid[grant_encoded*ID_WIDTH +: ID_WIDTH]; +wire [DEST_WIDTH-1:0] current_s_tdest = s_axis_tdest[grant_encoded*DEST_WIDTH +: DEST_WIDTH]; +wire [USER_WIDTH-1:0] current_s_tuser = s_axis_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH]; + +// arbiter instance +arbiter #( + .PORTS(S_COUNT), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +generate + genvar n; + + for (n = 0; n < S_COUNT; n = n + 1) begin + assign request[n] = s_axis_tvalid[n] && !grant[n]; + assign acknowledge[n] = grant[n] && s_axis_tvalid[n] && s_axis_tready[n] && s_axis_tlast[n]; + end +endgenerate + +always @* begin + // pass through selected packet data + m_axis_tdata_int = current_s_tdata; + m_axis_tkeep_int = current_s_tkeep; + m_axis_tvalid_int = current_s_tvalid && m_axis_tready_int_reg && grant_valid; + m_axis_tlast_int = current_s_tlast; + m_axis_tid_int = current_s_tid; + m_axis_tdest_int = current_s_tdest; + m_axis_tuser_int = current_s_tuser; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_axis_tready_int_early = m_axis_tready | (~temp_m_axis_tvalid_reg & (~m_axis_tvalid_reg | ~m_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (m_axis_tready_int_reg) begin + // input is ready + if (m_axis_tready | ~m_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_axis_tready) begin + // input is not ready, but output is ready + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; + end else begin + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tid_reg <= m_axis_tid_int; + m_axis_tdest_reg <= m_axis_tdest_int; + m_axis_tuser_reg <= m_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tid_reg <= m_axis_tid_int; + temp_m_axis_tdest_reg <= m_axis_tdest_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/axis_arb_mux_4.v b/rtl/axis_arb_mux_4.v deleted file mode 100644 index b572e6410..000000000 --- a/rtl/axis_arb_mux_4.v +++ /dev/null @@ -1,330 +0,0 @@ -/* - -Copyright (c) 2014-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream 4 port arbitrated multiplexer - */ -module axis_arb_mux_4 # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1, - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ - input wire [DATA_WIDTH-1:0] input_0_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, - input wire input_0_axis_tvalid, - output wire input_0_axis_tready, - input wire input_0_axis_tlast, - input wire [ID_WIDTH-1:0] input_0_axis_tid, - input wire [DEST_WIDTH-1:0] input_0_axis_tdest, - input wire [USER_WIDTH-1:0] input_0_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_1_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, - input wire input_1_axis_tvalid, - output wire input_1_axis_tready, - input wire input_1_axis_tlast, - input wire [ID_WIDTH-1:0] input_1_axis_tid, - input wire [DEST_WIDTH-1:0] input_1_axis_tdest, - input wire [USER_WIDTH-1:0] input_1_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_2_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, - input wire input_2_axis_tvalid, - output wire input_2_axis_tready, - input wire input_2_axis_tlast, - input wire [ID_WIDTH-1:0] input_2_axis_tid, - input wire [DEST_WIDTH-1:0] input_2_axis_tdest, - input wire [USER_WIDTH-1:0] input_2_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_3_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, - input wire input_3_axis_tvalid, - output wire input_3_axis_tready, - input wire input_3_axis_tlast, - input wire [ID_WIDTH-1:0] input_3_axis_tid, - input wire [DEST_WIDTH-1:0] input_3_axis_tdest, - input wire [USER_WIDTH-1:0] input_3_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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser -); - -wire [3:0] request; -wire [3:0] acknowledge; -wire [3:0] grant; -wire grant_valid; -wire [1:0] grant_encoded; - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg [ID_WIDTH-1:0] output_axis_tid_int; -reg [DEST_WIDTH-1:0] output_axis_tdest_int; -reg [USER_WIDTH-1:0] output_axis_tuser_int; -wire output_axis_tready_int_early; - -assign input_0_axis_tready = grant[0] & output_axis_tready_int_reg; -assign input_1_axis_tready = grant[1] & output_axis_tready_int_reg; -assign input_2_axis_tready = grant[2] & output_axis_tready_int_reg; -assign input_3_axis_tready = grant[3] & output_axis_tready_int_reg; - -// mux for incoming packet -reg [DATA_WIDTH-1:0] current_input_tdata; -reg [KEEP_WIDTH-1:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg [ID_WIDTH-1:0] current_input_tid; -reg [DEST_WIDTH-1:0] current_input_tdest; -reg [USER_WIDTH-1:0] current_input_tuser; -always @* begin - case (grant_encoded) - 2'd0: begin - current_input_tdata = input_0_axis_tdata; - current_input_tkeep = input_0_axis_tkeep; - current_input_tvalid = input_0_axis_tvalid; - current_input_tready = input_0_axis_tready; - current_input_tlast = input_0_axis_tlast; - current_input_tid = input_0_axis_tid; - current_input_tdest = input_0_axis_tdest; - current_input_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_tdata = input_1_axis_tdata; - current_input_tkeep = input_1_axis_tkeep; - current_input_tvalid = input_1_axis_tvalid; - current_input_tready = input_1_axis_tready; - current_input_tlast = input_1_axis_tlast; - current_input_tid = input_1_axis_tid; - current_input_tdest = input_1_axis_tdest; - current_input_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_tdata = input_2_axis_tdata; - current_input_tkeep = input_2_axis_tkeep; - current_input_tvalid = input_2_axis_tvalid; - current_input_tready = input_2_axis_tready; - current_input_tlast = input_2_axis_tlast; - current_input_tid = input_2_axis_tid; - current_input_tdest = input_2_axis_tdest; - current_input_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_tdata = input_3_axis_tdata; - current_input_tkeep = input_3_axis_tkeep; - current_input_tvalid = input_3_axis_tvalid; - current_input_tready = input_3_axis_tready; - current_input_tlast = input_3_axis_tlast; - current_input_tid = input_3_axis_tid; - current_input_tdest = input_3_axis_tdest; - current_input_tuser = input_3_axis_tuser; - end - default: begin - current_input_tdata = {DATA_WIDTH{1'b0}}; - current_input_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tid = {ID_WIDTH{1'b0}}; - current_input_tdest = {DEST_WIDTH{1'b0}}; - current_input_tuser = {USER_WIDTH{1'b0}}; - end - endcase -end - -// arbiter instance - -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -// request generation -assign request[0] = input_0_axis_tvalid & ~acknowledge[0]; -assign request[1] = input_1_axis_tvalid & ~acknowledge[1]; -assign request[2] = input_2_axis_tvalid & ~acknowledge[2]; -assign request[3] = input_3_axis_tvalid & ~acknowledge[3]; - -// acknowledge generation -assign acknowledge[0] = grant[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign acknowledge[1] = grant[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign acknowledge[2] = grant[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign acknowledge[3] = grant[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; - -always @* begin - // pass through selected packet data - output_axis_tdata_int = current_input_tdata; - output_axis_tkeep_int = current_input_tkeep; - output_axis_tvalid_int = current_input_tvalid & current_input_tready; - output_axis_tlast_int = current_input_tlast; - output_axis_tid_int = current_input_tid; - output_axis_tdest_int = current_input_tdest; - output_axis_tuser_int = current_input_tuser; -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tid_reg <= output_axis_tid_int; - output_axis_tdest_reg <= output_axis_tdest_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tid_reg <= output_axis_tid_int; - temp_axis_tdest_reg <= output_axis_tdest_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index 60e0cf2a8..77e52d35e 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -28,13 +28,12 @@ import os import axis_ep -module = 'axis_arb_mux_4' -testbench = 'test_%s' % module +module = 'axis_arb_mux' +testbench = 'test_%s_4' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axis_mux_4.v") srcs.append("../rtl/arbiter.v") srcs.append("../rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -46,6 +45,7 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + S_COUNT = 4 DATA_WIDTH = 8 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) @@ -61,139 +61,78 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_0_axis_tvalid = Signal(bool(0)) - input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_1_axis_tvalid = Signal(bool(0)) - input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_2_axis_tvalid = Signal(bool(0)) - input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_3_axis_tvalid = Signal(bool(0)) - input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_axis_tkeep_list = [Signal(intbv(0)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_axis_tready = Signal(bool(0)) + s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list)) + s_axis_tkeep = ConcatSignal(*reversed(s_axis_tkeep_list)) + s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list)) + s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list)) + s_axis_tid = ConcatSignal(*reversed(s_axis_tid_list)) + s_axis_tdest = ConcatSignal(*reversed(s_axis_tdest_list)) + s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list)) + + m_axis_tready = Signal(bool(0)) # Outputs - input_0_axis_tready = Signal(bool(0)) - input_1_axis_tready = Signal(bool(0)) - input_2_axis_tready = Signal(bool(0)) - input_3_axis_tready = Signal(bool(0)) + s_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready_list = [s_axis_tready(i) for i in range(S_COUNT)] + + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource() + for k in range(S_COUNT): + s = axis_ep.AXIStreamSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tid=input_0_axis_tid, - tdest=input_0_axis_tdest, - tuser=input_0_axis_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = axis_ep.AXIStreamSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tid=input_1_axis_tid, - tdest=input_1_axis_tdest, - tuser=input_1_axis_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = axis_ep.AXIStreamSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tid=input_2_axis_tid, - tdest=input_2_axis_tdest, - tuser=input_2_axis_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = axis_ep.AXIStreamSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tid=input_3_axis_tid, - tdest=input_3_axis_tdest, - tuser=input_3_axis_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + tdata=s_axis_tdata_list[k], + tkeep=s_axis_tkeep_list[k], + tvalid=s_axis_tvalid_list[k], + tready=s_axis_tready_list[k], + tlast=s_axis_tlast_list[k], + tid=s_axis_tid_list[k], + tdest=s_axis_tdest_list[k], + tuser=s_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = axis_ep.AXIStreamSink() sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -208,47 +147,23 @@ def bench(): rst=rst, current_test=current_test, - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tid=input_0_axis_tid, - input_0_axis_tdest=input_0_axis_tdest, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tid=input_1_axis_tid, - input_1_axis_tdest=input_1_axis_tdest, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tid=input_2_axis_tid, - input_2_axis_tdest=input_2_axis_tdest, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tid=input_3_axis_tid, - input_3_axis_tdest=input_3_axis_tdest, - input_3_axis_tuser=input_3_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -281,7 +196,7 @@ def bench(): dest=1 ) - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -303,7 +218,7 @@ def bench(): dest=1 ) - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -333,8 +248,8 @@ def bench(): dest=2 ) - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -369,8 +284,8 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -405,22 +320,18 @@ def bench(): dest=1 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_axis_tvalid: + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge yield sink.wait() @@ -456,11 +367,11 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + while s_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -501,17 +412,17 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) yield clk.posedge yield delay(800) yield clk.posedge - source_1.send(test_frame1) + source_list[1].send(test_frame1) yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_arb_mux_4.v b/tb/test_axis_arb_mux_4.v index 258957110..79c4f2736 100644 --- a/tb/test_axis_arb_mux_4.v +++ b/tb/test_axis_arb_mux_4.v @@ -27,11 +27,12 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_arb_mux_4 + * Testbench for axis_arb_mux */ module test_axis_arb_mux_4; // Parameters +parameter S_COUNT = 4; parameter DATA_WIDTH = 8; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); @@ -47,50 +48,26 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; -reg input_0_axis_tvalid = 0; -reg input_0_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_0_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; -reg input_1_axis_tvalid = 0; -reg input_1_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_1_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; -reg input_2_axis_tvalid = 0; -reg input_2_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_2_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; -reg input_3_axis_tvalid = 0; -reg input_3_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_3_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg [S_COUNT-1:0] s_axis_tvalid = 0; +reg [S_COUNT-1:0] s_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_axis_tuser = 0; -reg output_axis_tready = 0; +reg m_axis_tready = 0; // Outputs -wire input_0_axis_tready; -wire input_1_axis_tready; -wire input_2_axis_tready; -wire input_3_axis_tready; +wire [S_COUNT-1:0] s_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -98,48 +75,24 @@ initial begin clk, rst, current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tid, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tid, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tid, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tid, - input_3_axis_tdest, - input_3_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -147,7 +100,8 @@ initial begin $dumpvars(0, test_axis_arb_mux_4); end -axis_arb_mux_4 #( +axis_arb_mux #( + .S_COUNT(S_COUNT), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), @@ -162,47 +116,23 @@ UUT ( .clk(clk), .rst(rst), // AXI inputs - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tkeep(input_0_axis_tkeep), - .input_0_axis_tvalid(input_0_axis_tvalid), - .input_0_axis_tready(input_0_axis_tready), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tid(input_0_axis_tid), - .input_0_axis_tdest(input_0_axis_tdest), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tkeep(input_1_axis_tkeep), - .input_1_axis_tvalid(input_1_axis_tvalid), - .input_1_axis_tready(input_1_axis_tready), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tid(input_1_axis_tid), - .input_1_axis_tdest(input_1_axis_tdest), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tkeep(input_2_axis_tkeep), - .input_2_axis_tvalid(input_2_axis_tvalid), - .input_2_axis_tready(input_2_axis_tready), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tid(input_2_axis_tid), - .input_2_axis_tdest(input_2_axis_tdest), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tkeep(input_3_axis_tkeep), - .input_3_axis_tvalid(input_3_axis_tvalid), - .input_3_axis_tready(input_3_axis_tready), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tid(input_3_axis_tid), - .input_3_axis_tdest(input_3_axis_tdest), - .input_3_axis_tuser(input_3_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule diff --git a/tb/test_axis_arb_mux_4_64.py b/tb/test_axis_arb_mux_4_64.py index 03c6faf8a..f17ba4ec2 100755 --- a/tb/test_axis_arb_mux_4_64.py +++ b/tb/test_axis_arb_mux_4_64.py @@ -28,13 +28,12 @@ import os import axis_ep -module = 'axis_arb_mux_4' -testbench = 'test_%s_64' % module +module = 'axis_arb_mux' +testbench = 'test_%s_4_64' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axis_mux_4.v") srcs.append("../rtl/arbiter.v") srcs.append("../rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -46,6 +45,7 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + S_COUNT = 4 DATA_WIDTH = 64 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) @@ -61,139 +61,78 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_0_axis_tvalid = Signal(bool(0)) - input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_1_axis_tvalid = Signal(bool(0)) - input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_2_axis_tvalid = Signal(bool(0)) - input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_3_axis_tvalid = Signal(bool(0)) - input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_axis_tkeep_list = [Signal(intbv(0)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_axis_tready = Signal(bool(0)) + s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list)) + s_axis_tkeep = ConcatSignal(*reversed(s_axis_tkeep_list)) + s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list)) + s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list)) + s_axis_tid = ConcatSignal(*reversed(s_axis_tid_list)) + s_axis_tdest = ConcatSignal(*reversed(s_axis_tdest_list)) + s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list)) + + m_axis_tready = Signal(bool(0)) # Outputs - input_0_axis_tready = Signal(bool(0)) - input_1_axis_tready = Signal(bool(0)) - input_2_axis_tready = Signal(bool(0)) - input_3_axis_tready = Signal(bool(0)) + s_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready_list = [s_axis_tready(i) for i in range(S_COUNT)] + + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource() + for k in range(S_COUNT): + s = axis_ep.AXIStreamSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tid=input_0_axis_tid, - tdest=input_0_axis_tdest, - tuser=input_0_axis_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = axis_ep.AXIStreamSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tid=input_1_axis_tid, - tdest=input_1_axis_tdest, - tuser=input_1_axis_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = axis_ep.AXIStreamSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tid=input_2_axis_tid, - tdest=input_2_axis_tdest, - tuser=input_2_axis_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = axis_ep.AXIStreamSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tid=input_3_axis_tid, - tdest=input_3_axis_tdest, - tuser=input_3_axis_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + tdata=s_axis_tdata_list[k], + tkeep=s_axis_tkeep_list[k], + tvalid=s_axis_tvalid_list[k], + tready=s_axis_tready_list[k], + tlast=s_axis_tlast_list[k], + tid=s_axis_tid_list[k], + tdest=s_axis_tdest_list[k], + tuser=s_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = axis_ep.AXIStreamSink() sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -208,47 +147,23 @@ def bench(): rst=rst, current_test=current_test, - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tid=input_0_axis_tid, - input_0_axis_tdest=input_0_axis_tdest, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tid=input_1_axis_tid, - input_1_axis_tdest=input_1_axis_tdest, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tid=input_2_axis_tid, - input_2_axis_tdest=input_2_axis_tdest, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tid=input_3_axis_tid, - input_3_axis_tdest=input_3_axis_tdest, - input_3_axis_tuser=input_3_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -281,7 +196,7 @@ def bench(): dest=1 ) - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -303,7 +218,7 @@ def bench(): dest=1 ) - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -333,8 +248,8 @@ def bench(): dest=2 ) - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -369,8 +284,8 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -405,22 +320,18 @@ def bench(): dest=1 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_axis_tvalid: + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge yield sink.wait() @@ -456,11 +367,11 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + while s_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -501,17 +412,17 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) yield clk.posedge yield delay(100) yield clk.posedge - source_1.send(test_frame1) + source_list[1].send(test_frame1) yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_arb_mux_4_64.v b/tb/test_axis_arb_mux_4_64.v index ee21ef60c..eaa9c96d8 100644 --- a/tb/test_axis_arb_mux_4_64.v +++ b/tb/test_axis_arb_mux_4_64.v @@ -27,11 +27,12 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_arb_mux_4 + * Testbench for axis_arb_mux */ module test_axis_arb_mux_4_64; // Parameters +parameter S_COUNT = 4; parameter DATA_WIDTH = 64; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); @@ -47,50 +48,26 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; -reg input_0_axis_tvalid = 0; -reg input_0_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_0_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; -reg input_1_axis_tvalid = 0; -reg input_1_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_1_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; -reg input_2_axis_tvalid = 0; -reg input_2_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_2_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; -reg input_3_axis_tvalid = 0; -reg input_3_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_3_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg [S_COUNT-1:0] s_axis_tvalid = 0; +reg [S_COUNT-1:0] s_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_axis_tuser = 0; -reg output_axis_tready = 0; +reg m_axis_tready = 0; // Outputs -wire input_0_axis_tready; -wire input_1_axis_tready; -wire input_2_axis_tready; -wire input_3_axis_tready; +wire [S_COUNT-1:0] s_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -98,48 +75,24 @@ initial begin clk, rst, current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tid, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tid, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tid, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tid, - input_3_axis_tdest, - input_3_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -147,7 +100,8 @@ initial begin $dumpvars(0, test_axis_arb_mux_4_64); end -axis_arb_mux_4 #( +axis_arb_mux #( + .S_COUNT(S_COUNT), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), @@ -162,47 +116,23 @@ UUT ( .clk(clk), .rst(rst), // AXI inputs - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tkeep(input_0_axis_tkeep), - .input_0_axis_tvalid(input_0_axis_tvalid), - .input_0_axis_tready(input_0_axis_tready), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tid(input_0_axis_tid), - .input_0_axis_tdest(input_0_axis_tdest), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tkeep(input_1_axis_tkeep), - .input_1_axis_tvalid(input_1_axis_tvalid), - .input_1_axis_tready(input_1_axis_tready), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tid(input_1_axis_tid), - .input_1_axis_tdest(input_1_axis_tdest), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tkeep(input_2_axis_tkeep), - .input_2_axis_tvalid(input_2_axis_tvalid), - .input_2_axis_tready(input_2_axis_tready), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tid(input_2_axis_tid), - .input_2_axis_tdest(input_2_axis_tdest), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tkeep(input_3_axis_tkeep), - .input_3_axis_tvalid(input_3_axis_tvalid), - .input_3_axis_tready(input_3_axis_tready), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tid(input_3_axis_tid), - .input_3_axis_tdest(input_3_axis_tdest), - .input_3_axis_tuser(input_3_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule From 631147069f746517e153833eca3a8e0792a52d29 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 14:35:08 -0700 Subject: [PATCH 419/617] Rename ports and add reg_type parameter to axis_register --- rtl/axis_register.v | 303 +++++++++++++++++++++++------------- tb/test_axis_register.py | 101 ++++++------ tb/test_axis_register.v | 100 ++++++------ tb/test_axis_register_64.py | 101 ++++++------ tb/test_axis_register_64.v | 100 ++++++------ 5 files changed, 399 insertions(+), 306 deletions(-) diff --git a/rtl/axis_register.v b/rtl/axis_register.v index ccee82b7e..a98441964 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -40,138 +40,225 @@ module axis_register # parameter DEST_ENABLE = 0, parameter DEST_WIDTH = 8, parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1 + parameter USER_WIDTH = 1, + parameter REG_TYPE = 2 ) ( input wire clk, input wire rst, /* - * AXI input + * AXI Stream 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* - * AXI output + * AXI Stream 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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser ); -// datapath registers -reg input_axis_tready_reg = 1'b0; +generate -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; +if (REG_TYPE > 1) begin + // skid buffer, no bubble cycles -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; + // datapath registers + reg s_axis_tready_reg = 1'b0; -// datapath control -reg store_axis_input_to_output; -reg store_axis_input_to_temp; -reg store_axis_temp_to_output; + reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; + reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; + reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; + reg m_axis_tlast_reg = 1'b0; + reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; + reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; + reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; -assign input_axis_tready = input_axis_tready_reg; + reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; + reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; + reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; + reg temp_m_axis_tlast_reg = 1'b0; + reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; + reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; + reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = LAST_ENABLE ? output_axis_tlast_reg : 1'b1; -assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; + // datapath control + reg store_axis_input_to_output; + reg store_axis_input_to_temp; + reg store_axis_temp_to_output; -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -wire input_axis_tready_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~input_axis_tvalid)); + assign s_axis_tready = s_axis_tready_reg; -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + assign m_axis_tdata = m_axis_tdata_reg; + assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; + assign m_axis_tvalid = m_axis_tvalid_reg; + assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1; + assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; + assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; + assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; - store_axis_input_to_output = 1'b0; - store_axis_input_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; + // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) + wire s_axis_tready_early = m_axis_tready | (~temp_m_axis_tvalid_reg & (~m_axis_tvalid_reg | ~s_axis_tvalid)); - if (input_axis_tready_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = input_axis_tvalid; - store_axis_input_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = input_axis_tvalid; - store_axis_input_to_temp = 1'b1; + always @* begin + // transfer sink ready state to source + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; + + store_axis_input_to_output = 1'b0; + store_axis_input_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (s_axis_tready_reg) begin + // input is ready + if (m_axis_tready | ~m_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_axis_tvalid_next = s_axis_tvalid; + store_axis_input_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_axis_tvalid_next = s_axis_tvalid; + store_axis_input_to_temp = 1'b1; + end + end else if (m_axis_tready) begin + // input is not ready, but output is ready + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; end + + always @(posedge clk) begin + if (rst) begin + s_axis_tready_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; + end else begin + s_axis_tready_reg <= s_axis_tready_early; + m_axis_tvalid_reg <= m_axis_tvalid_next; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; + end + + // datapath + if (store_axis_input_to_output) begin + m_axis_tdata_reg <= s_axis_tdata; + m_axis_tkeep_reg <= s_axis_tkeep; + m_axis_tlast_reg <= s_axis_tlast; + m_axis_tid_reg <= s_axis_tid; + m_axis_tdest_reg <= s_axis_tdest; + m_axis_tuser_reg <= s_axis_tuser; + end else if (store_axis_temp_to_output) begin + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; + end + + if (store_axis_input_to_temp) begin + temp_m_axis_tdata_reg <= s_axis_tdata; + temp_m_axis_tkeep_reg <= s_axis_tkeep; + temp_m_axis_tlast_reg <= s_axis_tlast; + temp_m_axis_tid_reg <= s_axis_tid; + temp_m_axis_tdest_reg <= s_axis_tdest; + temp_m_axis_tuser_reg <= s_axis_tuser; + end + end + +end else if (REG_TYPE == 1) begin + // simple register, inserts bubble cycles + + // datapath registers + reg s_axis_tready_reg = 1'b0; + + reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; + reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; + reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; + reg m_axis_tlast_reg = 1'b0; + reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; + reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; + reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + + // datapath control + reg store_axis_input_to_output; + + assign s_axis_tready = s_axis_tready_reg; + + assign m_axis_tdata = m_axis_tdata_reg; + assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; + assign m_axis_tvalid = m_axis_tvalid_reg; + assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1; + assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; + assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; + assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; + + // enable ready input next cycle if output buffer will be empty + wire s_axis_tready_early = !m_axis_tvalid_next; + + always @* begin + // transfer sink ready state to source + m_axis_tvalid_next = m_axis_tvalid_reg; + + store_axis_input_to_output = 1'b0; + + if (s_axis_tready_reg) begin + m_axis_tvalid_next = s_axis_tvalid; + store_axis_input_to_output = 1'b1; + end else if (m_axis_tready) begin + m_axis_tvalid_next = 1'b0; + end + end + + always @(posedge clk) begin + if (rst) begin + s_axis_tready_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + end else begin + s_axis_tready_reg <= s_axis_tready_early; + m_axis_tvalid_reg <= m_axis_tvalid_next; + end + + // datapath + if (store_axis_input_to_output) begin + m_axis_tdata_reg <= s_axis_tdata; + m_axis_tkeep_reg <= s_axis_tkeep; + m_axis_tlast_reg <= s_axis_tlast; + m_axis_tid_reg <= s_axis_tid; + m_axis_tdest_reg <= s_axis_tdest; + m_axis_tuser_reg <= s_axis_tuser; + end + end + +end else begin + // bypass + + assign m_axis_tdata = s_axis_tdata; + assign m_axis_tkeep = KEEP_ENABLE ? s_axis_tkeep : {KEEP_WIDTH{1'b1}}; + assign m_axis_tvalid = s_axis_tvalid; + assign m_axis_tlast = LAST_ENABLE ? s_axis_tlast : 1'b1; + assign m_axis_tid = ID_ENABLE ? s_axis_tid : {ID_WIDTH{1'b0}}; + assign m_axis_tdest = DEST_ENABLE ? s_axis_tdest : {DEST_WIDTH{1'b0}}; + assign m_axis_tuser = USER_ENABLE ? s_axis_tuser : {USER_WIDTH{1'b0}}; + + assign s_axis_tready = m_axis_tready; + end -always @(posedge clk) begin - if (rst) begin - input_axis_tready_reg <= 1'b0; - output_axis_tvalid_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - input_axis_tready_reg <= input_axis_tready_early; - output_axis_tvalid_reg <= output_axis_tvalid_next; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_input_to_output) begin - output_axis_tdata_reg <= input_axis_tdata; - output_axis_tkeep_reg <= input_axis_tkeep; - output_axis_tlast_reg <= input_axis_tlast; - output_axis_tid_reg <= input_axis_tid; - output_axis_tdest_reg <= input_axis_tdest; - output_axis_tuser_reg <= input_axis_tuser; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_input_to_temp) begin - temp_axis_tdata_reg <= input_axis_tdata; - temp_axis_tkeep_reg <= input_axis_tkeep; - temp_axis_tlast_reg <= input_axis_tlast; - temp_axis_tid_reg <= input_axis_tid; - temp_axis_tdest_reg <= input_axis_tdest; - temp_axis_tuser_reg <= input_axis_tuser; - end -end +endgenerate endmodule diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py index c470d4420..95527a97d 100755 --- a/tb/test_axis_register.py +++ b/tb/test_axis_register.py @@ -53,30 +53,31 @@ def bench(): DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + REG_TYPE = 2 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -87,14 +88,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -104,14 +105,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -126,23 +127,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -302,7 +303,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -347,7 +348,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_register.v b/tb/test_axis_register.v index 94c3c853c..52a52c999 100644 --- a/tb/test_axis_register.v +++ b/tb/test_axis_register.v @@ -42,30 +42,31 @@ parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter REG_TYPE = 2; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -73,24 +74,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -108,29 +109,30 @@ axis_register #( .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) + .USER_WIDTH(USER_WIDTH), + .REG_TYPE(REG_TYPE) ) 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py index 6f62fe0dc..7021a22fd 100755 --- a/tb/test_axis_register_64.py +++ b/tb/test_axis_register_64.py @@ -53,30 +53,31 @@ def bench(): DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + REG_TYPE = 2 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -87,14 +88,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -104,14 +105,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -126,23 +127,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -302,7 +303,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -347,7 +348,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_register_64.v b/tb/test_axis_register_64.v index 21f92b0d4..cf523b601 100644 --- a/tb/test_axis_register_64.v +++ b/tb/test_axis_register_64.v @@ -42,30 +42,31 @@ parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter REG_TYPE = 2; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -73,24 +74,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -108,29 +109,30 @@ axis_register #( .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) + .USER_WIDTH(USER_WIDTH), + .REG_TYPE(REG_TYPE) ) 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule From fd7f65d5ad3415901ad91f0ca32c4578cb0f976c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 16:12:56 -0700 Subject: [PATCH 420/617] Convert generated switch to verilog parametrized switch --- rtl/axis_switch.py | 485 ------------ rtl/axis_switch.v | 298 ++++++++ rtl/axis_switch_4x4.v | 1338 --------------------------------- tb/test_axis_switch_4x4.py | 538 +++++-------- tb/test_axis_switch_4x4.v | 282 ++----- tb/test_axis_switch_4x4_64.py | 521 +++++-------- tb/test_axis_switch_4x4_64.v | 282 ++----- 7 files changed, 785 insertions(+), 2959 deletions(-) delete mode 100755 rtl/axis_switch.py create mode 100644 rtl/axis_switch.v delete mode 100644 rtl/axis_switch_4x4.v diff --git a/rtl/axis_switch.py b/rtl/axis_switch.py deleted file mode 100755 index f57951c19..000000000 --- a/rtl/axis_switch.py +++ /dev/null @@ -1,485 +0,0 @@ -#!/usr/bin/env python -""" -Generates an AXI Stream switch with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=[4], nargs='+', help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if type(ports) is int: - m = n = ports - elif len(ports) == 1: - m = n = ports[0] - else: - m, n = ports - - if name is None: - name = "axis_switch_{0}x{1}".format(m, n) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0}x{1} port AXI Stream switch {2}...".format(m, n, name)) - - cm = int(math.ceil(math.log(m, 2))) - cn = int(math.ceil(math.log(n, 2))) - - t = Template(u"""/* - -Copyright (c) 2016-2018 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 {{m}}x{{n}} switch - */ -module {{name}} # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_WIDTH = {{cn}}, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1, -{%- for p in range(n) %} - parameter OUT_{{p}}_BASE = {{p}}, - parameter OUT_{{p}}_TOP = {{p}}, - parameter OUT_{{p}}_CONNECT = {{m}}'b{% for p in range(m) %}1{% endfor %}, -{%- endfor %} - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "ROUND_ROBIN", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * AXI Stream inputs - */ -{%- for p in range(m) %} - input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, - input wire input_{{p}}_axis_tvalid, - output wire input_{{p}}_axis_tready, - input wire input_{{p}}_axis_tlast, - input wire [ID_WIDTH-1:0] input_{{p}}_axis_tid, - input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, - input wire [USER_WIDTH-1:0] input_{{p}}_axis_tuser, -{% endfor %} - /* - * AXI Stream outputs - */ -{%- for p in range(n) %} - output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, - output wire output_{{p}}_axis_tvalid, - input wire output_{{p}}_axis_tready, - output wire output_{{p}}_axis_tlast, - output wire [ID_WIDTH-1:0] output_{{p}}_axis_tid, - output wire [DEST_WIDTH-1:0] output_{{p}}_axis_tdest, - output wire [USER_WIDTH-1:0] output_{{p}}_axis_tuser{% if not loop.last %},{% endif %} -{% endfor -%} -); - -// check configuration -initial begin - if (2**DEST_WIDTH < {{n}}) begin - $error("Error: DEST_WIDTH too small for port count"); - $finish; - end - - if ({%- for p in range(n) %}(OUT_{{p}}_BASE & 2**DEST_WIDTH-1) != OUT_{{p}}_BASE || (OUT_{{p}}_TOP & 2**DEST_WIDTH-1) != OUT_{{p}}_TOP{% if not loop.last %} || - {% endif %}{% endfor -%}) begin - $error("Error: value out of range"); - $finish; - end - - if ({%- for p in range(n) %}OUT_{{p}}_BASE > OUT_{{p}}_TOP{% if not loop.last %} || - {% endif %}{% endfor -%}) begin - $error("Error: invalid range"); - $finish; - end - - if ({%- for p in range(n-1) %}{% set outer_loop = loop %}{%- for q in range(p+1,n) %}(OUT_{{p}}_BASE <= OUT_{{q}}_TOP && OUT_{{q}}_BASE <= OUT_{{p}}_TOP){% if not (loop.last and outer_loop.last) %} || - {% endif %}{% endfor -%}{% endfor -%}) begin - $error("Error: ranges overlap"); - $finish; - end -end -{%- for p in range(m) %} - -reg [{{n-1}}:0] input_{{p}}_request_reg = {{n}}'d0, input_{{p}}_request_next; -reg input_{{p}}_request_valid_reg = 1'b0, input_{{p}}_request_valid_next; -reg input_{{p}}_request_error_reg = 1'b0, input_{{p}}_request_error_next; -{%- endfor %} -{% for p in range(n) %} -reg enable_{{p}}_reg = 1'b0, enable_{{p}}_next; -{%- endfor %} -{% for p in range(m) %} -reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; -{%- endfor %} - -// internal datapath -{%- for p in range(n) %} -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_int; -reg output_{{p}}_axis_tvalid_int; -reg output_{{p}}_axis_tready_int_reg = 1'b0; -reg output_{{p}}_axis_tlast_int; -reg [ID_WIDTH-1:0] output_{{p}}_axis_tid_int; -reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_int; -reg [USER_WIDTH-1:0] output_{{p}}_axis_tuser_int; -wire output_{{p}}_axis_tready_int_early; -{% endfor %} -{%- for p in range(m) %} -assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; -{%- endfor %} - -// mux for incoming packet -{% for p in range(n) %} -reg [DATA_WIDTH-1:0] current_input_{{p}}_axis_tdata; -reg [KEEP_WIDTH-1:0] current_input_{{p}}_axis_tkeep; -reg current_input_{{p}}_axis_tvalid; -reg current_input_{{p}}_axis_tready; -reg current_input_{{p}}_axis_tlast; -reg [ID_WIDTH-1:0] current_input_{{p}}_axis_tid; -reg [DEST_WIDTH-1:0] current_input_{{p}}_axis_tdest; -reg [USER_WIDTH-1:0] current_input_{{p}}_axis_tuser; - -always @* begin - case (grant_encoded_{{p}}) -{%- for q in range(m) %} - {{cm}}'d{{q}}: begin - current_input_{{p}}_axis_tdata = input_{{q}}_axis_tdata; - current_input_{{p}}_axis_tkeep = input_{{q}}_axis_tkeep; - current_input_{{p}}_axis_tvalid = input_{{q}}_axis_tvalid; - current_input_{{p}}_axis_tready = input_{{q}}_axis_tready; - current_input_{{p}}_axis_tlast = input_{{q}}_axis_tlast; - current_input_{{p}}_axis_tid = input_{{q}}_axis_tid; - current_input_{{p}}_axis_tdest = input_{{q}}_axis_tdest; - current_input_{{p}}_axis_tuser = input_{{q}}_axis_tuser; - end -{%- endfor %} - default: begin - current_input_{{p}}_axis_tdata = {DATA_WIDTH{1'b0}}; - current_input_{{p}}_axis_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_{{p}}_axis_tvalid = 1'b0; - current_input_{{p}}_axis_tready = 1'b0; - current_input_{{p}}_axis_tlast = 1'b0; - current_input_{{p}}_axis_tid = {ID_WIDTH{1'b0}}; - current_input_{{p}}_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_{{p}}_axis_tuser = {USER_WIDTH{1'b0}}; - end - endcase -end -{% endfor %} -// arbiter instances -{% for p in range(n) %} -wire [{{m-1}}:0] request_{{p}}; -wire [{{m-1}}:0] acknowledge_{{p}}; -wire [{{m-1}}:0] grant_{{p}}; -wire grant_valid_{{p}}; -wire [{{cm-1}}:0] grant_encoded_{{p}}; -{% endfor %} - -{%- for p in range(n) %} -arbiter #( - .PORTS({{m}}), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_{{p}}_inst ( - .clk(clk), - .rst(rst), - .request(request_{{p}}), - .acknowledge(acknowledge_{{p}}), - .grant(grant_{{p}}), - .grant_valid(grant_valid_{{p}}), - .grant_encoded(grant_encoded_{{p}}) -); -{% endfor %} -// request generation -{%- for p in range(n) %} -{%- for q in range(m) %} -assign request_{{p}}[{{q}}] = input_{{q}}_request_reg[{{p}}] & ~acknowledge_{{p}}[{{q}}]; -{%- endfor %} -{% endfor %} -// acknowledge generation -{%- for p in range(n) %} -{%- for q in range(m) %} -assign acknowledge_{{p}}[{{q}}] = grant_{{p}}[{{q}}] & input_{{q}}_axis_tvalid & input_{{q}}_axis_tready & input_{{q}}_axis_tlast; -{%- endfor %} -{% endfor %} -always @* begin -{% for p in range(n) %} - enable_{{p}}_next = enable_{{p}}_reg; -{%- endfor %} -{% for p in range(m) %} - input_{{p}}_request_next = input_{{p}}_request_reg; - input_{{p}}_request_valid_next = input_{{p}}_request_valid_reg; - input_{{p}}_request_error_next = input_{{p}}_request_error_reg; -{% endfor %} -{%- for p in range(m) %} - input_{{p}}_axis_tready_next = 1'b0; -{%- endfor %} -{% for p in range(n) %} - output_{{p}}_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_{{p}}_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; - output_{{p}}_axis_tvalid_int = 1'b0; - output_{{p}}_axis_tlast_int = 1'b0; - output_{{p}}_axis_tid_int = {ID_WIDTH{1'b0}}; - output_{{p}}_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_{{p}}_axis_tuser_int = {USER_WIDTH{1'b0}}; -{% endfor %} - // input decoding -{% for p in range(m) %} - if (input_{{p}}_request_valid_reg | input_{{p}}_request_error_reg) begin - if (input_{{p}}_axis_tvalid & input_{{p}}_axis_tready & input_{{p}}_axis_tlast) begin - input_{{p}}_request_next = {DEST_WIDTH{1'b0}}; - input_{{p}}_request_valid_next = 1'b0; - input_{{p}}_request_error_next = 1'b0; - end - end else if (input_{{p}}_axis_tvalid) begin -{%- for q in range(n) %} - input_{{p}}_request_next[{{q}}] = (input_{{p}}_axis_tdest >= OUT_{{q}}_BASE) & (input_{{p}}_axis_tdest <= OUT_{{q}}_TOP) & OUT_{{q}}_CONNECT[{{p}}]; -{%- endfor %} - - if (input_{{p}}_request_next) begin - input_{{p}}_request_valid_next = 1'b1; - end else begin - input_{{p}}_request_error_next = 1'b1; - end - end -{% endfor %} - // output control -{% for p in range(n) %} - if (current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready) begin - if (current_input_{{p}}_axis_tlast) begin - enable_{{p}}_next = 1'b0; - end - end - if (~enable_{{p}}_reg & grant_valid_{{p}}) begin - enable_{{p}}_next = 1'b1; - end -{% endfor %} - // generate ready signal on selected port -{% for p in range(n) %} - if (enable_{{p}}_next) begin - case (grant_encoded_{{p}}) -{%- for q in range(m) %} - {{cm}}'d{{q}}: input_{{q}}_axis_tready_next = output_{{p}}_axis_tready_int_early; -{%- endfor %} - endcase - end -{% endfor %} - -{%- for p in range(m) %} - if (input_{{p}}_request_error_next) - input_{{p}}_axis_tready_next = 1'b1; -{%- endfor %} - - // pass through selected packet data -{% for p in range(n) %} - output_{{p}}_axis_tdata_int = current_input_{{p}}_axis_tdata; - output_{{p}}_axis_tkeep_int = current_input_{{p}}_axis_tkeep; - output_{{p}}_axis_tvalid_int = current_input_{{p}}_axis_tvalid & current_input_{{p}}_axis_tready & enable_{{p}}_reg; - output_{{p}}_axis_tlast_int = current_input_{{p}}_axis_tlast; - output_{{p}}_axis_tid_int = current_input_{{p}}_axis_tid; - output_{{p}}_axis_tdest_int = current_input_{{p}}_axis_tdest; - output_{{p}}_axis_tuser_int = current_input_{{p}}_axis_tuser; -{% endfor -%} -end - -always @(posedge clk) begin - if (rst) begin -{%- for p in range(m) %} - input_{{p}}_request_reg <= {{n}}'d0; - input_{{p}}_request_valid_reg <= 1'b0; - input_{{p}}_request_error_reg <= 1'b0; -{%- endfor %} -{%- for p in range(n) %} - enable_{{p}}_reg <= 1'b0; -{%- endfor %} -{%- for p in range(m) %} - input_{{p}}_axis_tready_reg <= 1'b0; -{%- endfor %} - end else begin -{%- for p in range(m) %} - input_{{p}}_request_reg <= input_{{p}}_request_next; - input_{{p}}_request_valid_reg <= input_{{p}}_request_valid_next; - input_{{p}}_request_error_reg <= input_{{p}}_request_error_next; -{%- endfor %} -{%- for p in range(n) %} - enable_{{p}}_reg <= enable_{{p}}_next; -{%- endfor %} -{%- for p in range(m) %} - input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; -{%- endfor %} - end -end -{% for p in range(n) %} -// output {{p}} datapath logic -reg [DATA_WIDTH-1:0] output_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_{{p}}_axis_tvalid_reg = 1'b0, output_{{p}}_axis_tvalid_next; -reg output_{{p}}_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_{{p}}_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_{{p}}_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_{{p}}_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_{{p}}_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_{{p}}_axis_tvalid_reg = 1'b0, temp_{{p}}_axis_tvalid_next; -reg temp_{{p}}_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_{{p}}_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_{{p}}_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_{{p}}_axis_tuser_reg = 1'b0; - -// datapath control -reg store_{{p}}_axis_int_to_output; -reg store_{{p}}_axis_int_to_temp; -reg store_{{p}}_axis_temp_to_output; - -assign output_{{p}}_axis_tdata = output_{{p}}_axis_tdata_reg; -assign output_{{p}}_axis_tkeep = KEEP_ENABLE ? output_{{p}}_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; -assign output_{{p}}_axis_tlast = output_{{p}}_axis_tlast_reg; -assign output_{{p}}_axis_tid = ID_ENABLE ? output_{{p}}_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_{{p}}_axis_tdest = output_{{p}}_axis_tdest_reg; -assign output_{{p}}_axis_tuser = USER_ENABLE ? output_{{p}}_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_{{p}}_axis_tready_int_early = output_{{p}}_axis_tready | (~temp_{{p}}_axis_tvalid_reg & (~output_{{p}}_axis_tvalid_reg | ~output_{{p}}_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_reg; - temp_{{p}}_axis_tvalid_next = temp_{{p}}_axis_tvalid_reg; - - store_{{p}}_axis_int_to_output = 1'b0; - store_{{p}}_axis_int_to_temp = 1'b0; - store_{{p}}_axis_temp_to_output = 1'b0; - - if (output_{{p}}_axis_tready_int_reg) begin - // input is ready - if (output_{{p}}_axis_tready | ~output_{{p}}_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_int; - store_{{p}}_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_int; - store_{{p}}_axis_int_to_temp = 1'b1; - end - end else if (output_{{p}}_axis_tready) begin - // input is not ready, but output is ready - output_{{p}}_axis_tvalid_next = temp_{{p}}_axis_tvalid_reg; - temp_{{p}}_axis_tvalid_next = 1'b0; - store_{{p}}_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_{{p}}_axis_tvalid_reg <= 1'b0; - output_{{p}}_axis_tready_int_reg <= 1'b0; - temp_{{p}}_axis_tvalid_reg <= 1'b0; - end else begin - output_{{p}}_axis_tvalid_reg <= output_{{p}}_axis_tvalid_next; - output_{{p}}_axis_tready_int_reg <= output_{{p}}_axis_tready_int_early; - temp_{{p}}_axis_tvalid_reg <= temp_{{p}}_axis_tvalid_next; - end - - // datapath - if (store_{{p}}_axis_int_to_output) begin - output_{{p}}_axis_tdata_reg <= output_{{p}}_axis_tdata_int; - output_{{p}}_axis_tkeep_reg <= output_{{p}}_axis_tkeep_int; - output_{{p}}_axis_tlast_reg <= output_{{p}}_axis_tlast_int; - output_{{p}}_axis_tid_reg <= output_{{p}}_axis_tid_int; - output_{{p}}_axis_tdest_reg <= output_{{p}}_axis_tdest_int; - output_{{p}}_axis_tuser_reg <= output_{{p}}_axis_tuser_int; - end else if (store_{{p}}_axis_temp_to_output) begin - output_{{p}}_axis_tdata_reg <= temp_{{p}}_axis_tdata_reg; - output_{{p}}_axis_tkeep_reg <= temp_{{p}}_axis_tkeep_reg; - output_{{p}}_axis_tlast_reg <= temp_{{p}}_axis_tlast_reg; - output_{{p}}_axis_tid_reg <= temp_{{p}}_axis_tid_reg; - output_{{p}}_axis_tdest_reg <= temp_{{p}}_axis_tdest_reg; - output_{{p}}_axis_tuser_reg <= temp_{{p}}_axis_tuser_reg; - end - - if (store_{{p}}_axis_int_to_temp) begin - temp_{{p}}_axis_tdata_reg <= output_{{p}}_axis_tdata_int; - temp_{{p}}_axis_tkeep_reg <= output_{{p}}_axis_tkeep_int; - temp_{{p}}_axis_tlast_reg <= output_{{p}}_axis_tlast_int; - temp_{{p}}_axis_tid_reg <= output_{{p}}_axis_tid_int; - temp_{{p}}_axis_tdest_reg <= output_{{p}}_axis_tdest_int; - temp_{{p}}_axis_tuser_reg <= output_{{p}}_axis_tuser_int; - end -end -{% endfor %} -endmodule - -""") - - output_file.write(t.render( - m=m, - n=n, - cm=cm, - cn=cn, - name=name - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_switch.v b/rtl/axis_switch.v new file mode 100644 index 000000000..b8c776008 --- /dev/null +++ b/rtl/axis_switch.v @@ -0,0 +1,298 @@ +/* + +Copyright (c) 2016-2018 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 switch + */ +module axis_switch # +( + parameter S_COUNT = 4, + parameter M_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_WIDTH = $clog2(S_COUNT), + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + parameter M_BASE = {32'd3, 32'd2, 32'd1, 32'd0}, + parameter M_TOP = {32'd3, 32'd2, 32'd1, 32'd0}, + parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}}, + parameter S_REG_TYPE = 0, + parameter M_REG_TYPE = 2, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "ROUND_ROBIN", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ + input wire [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep, + input wire [S_COUNT-1:0] s_axis_tvalid, + output wire [S_COUNT-1:0] s_axis_tready, + input wire [S_COUNT-1:0] s_axis_tlast, + input wire [S_COUNT*ID_WIDTH-1:0] s_axis_tid, + input wire [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest, + input wire [S_COUNT*USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI Stream outputs + */ + output wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata, + output wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep, + output wire [M_COUNT-1:0] m_axis_tvalid, + input wire [M_COUNT-1:0] m_axis_tready, + output wire [M_COUNT-1:0] m_axis_tlast, + output wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid, + output wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest, + output wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser +); + +parameter CL_S_COUNT = $clog2(S_COUNT); +parameter CL_M_COUNT = $clog2(M_COUNT); + +integer i, j; + +// check configuration +initial begin + if (2**DEST_WIDTH < CL_M_COUNT) begin + $error("Error: DEST_WIDTH too small for port count"); + $finish; + end + + for (i = 0; i < M_COUNT; i = i + 1) begin + if (M_BASE[i*32 +: 32] < 0 || M_BASE[i*32 +: 32] > 2**DEST_WIDTH-1 || M_TOP[i*32 +: 32] < 0 || M_TOP[i*32 +: 32] > 2**DEST_WIDTH-1) begin + $error("Error: value out of range"); + $finish; + end + end + + for (i = 0; i < M_COUNT; i = i + 1) begin + if (M_BASE[i*32 +: 32] > M_TOP[i*32 +: 32]) begin + $error("Error: invalid range"); + $finish; + end + end + + for (i = 0; i < M_COUNT; i = i + 1) begin + for (j = i+1; j < M_COUNT; j = j + 1) begin + if (M_BASE[i*32 +: 32] <= M_TOP[j*32 +: 32] && M_BASE[j*32 +: 32] <= M_TOP[i*32 +: 32]) begin + $display("%d: %08x-%08x", i, M_BASE[i*32 +: 32], M_TOP[i*32 +: 32]); + $display("%d: %08x-%08x", j, M_BASE[j*32 +: 32], M_TOP[j*32 +: 32]); + $error("Error: ranges overlap"); + $finish; + end + end + end +end + +wire [S_COUNT*DATA_WIDTH-1:0] int_s_axis_tdata; +wire [S_COUNT*KEEP_WIDTH-1:0] int_s_axis_tkeep; +wire [S_COUNT-1:0] int_s_axis_tvalid; +wire [S_COUNT-1:0] int_s_axis_tready; +wire [S_COUNT-1:0] int_s_axis_tlast; +wire [S_COUNT*ID_WIDTH-1:0] int_s_axis_tid; +wire [S_COUNT*DEST_WIDTH-1:0] int_s_axis_tdest; +wire [S_COUNT*USER_WIDTH-1:0] int_s_axis_tuser; + +wire [S_COUNT*M_COUNT-1:0] int_axis_tvalid; +wire [M_COUNT*S_COUNT-1:0] int_axis_tready; + +generate + + genvar m, n; + + for (m = 0; m < S_COUNT; m = m + 1) begin : s_ifaces + + // decoding + reg [CL_S_COUNT-1:0] select_reg = 0, select_next; + reg drop_reg = 1'b0, drop_next; + reg select_valid_reg = 1'b0, select_valid_next; + + always @* begin + select_next = select_reg; + drop_next = drop_reg && !(int_s_axis_tvalid[m] && int_s_axis_tready[m] && int_s_axis_tlast[m]); + select_valid_next = select_valid_reg && !(int_s_axis_tvalid[m] && int_s_axis_tready[m] && int_s_axis_tlast[m]); + + if (int_s_axis_tvalid[m] && !select_valid_reg) begin + select_next = 1'b0; + select_valid_next = 1'b0; + drop_next = 1'b1; + for (i = 0; i < M_COUNT; i = i + 1) begin + if (int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] >= M_BASE[i*32 +: 32] && int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[i*32 +: 32] && (M_CONNECT & (1 << (m+i*S_COUNT)))) begin + select_next = i; + select_valid_next = 1'b1; + drop_next = 1'b0; + end + end + end + end + + always @(posedge clk) begin + if (rst) begin + select_valid_reg <= 1'b0; + end else begin + select_valid_reg <= select_valid_next; + end + + select_reg <= select_next; + drop_reg <= drop_next; + end + + // forwarding + assign int_axis_tvalid[m*M_COUNT +: M_COUNT] = (int_s_axis_tvalid[m] && select_valid_reg && !drop_reg) << select_reg; + assign int_s_axis_tready[m] = int_axis_tready[select_reg*M_COUNT+m] || drop_reg; + + // S side register + axis_register #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(1), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(1), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .REG_TYPE(S_REG_TYPE) + ) + reg_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(s_axis_tdata[m*DATA_WIDTH +: DATA_WIDTH]), + .s_axis_tkeep(s_axis_tkeep[m*KEEP_WIDTH +: KEEP_WIDTH]), + .s_axis_tvalid(s_axis_tvalid[m]), + .s_axis_tready(s_axis_tready[m]), + .s_axis_tlast(s_axis_tlast[m]), + .s_axis_tid(s_axis_tid[m*ID_WIDTH +: ID_WIDTH]), + .s_axis_tdest(s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH]), + .s_axis_tuser(s_axis_tuser[m*USER_WIDTH +: USER_WIDTH]), + // AXI output + .m_axis_tdata(int_s_axis_tdata[m*DATA_WIDTH +: DATA_WIDTH]), + .m_axis_tkeep(int_s_axis_tkeep[m*KEEP_WIDTH +: KEEP_WIDTH]), + .m_axis_tvalid(int_s_axis_tvalid[m]), + .m_axis_tready(int_s_axis_tready[m]), + .m_axis_tlast(int_s_axis_tlast[m]), + .m_axis_tid(int_s_axis_tid[m*ID_WIDTH +: ID_WIDTH]), + .m_axis_tdest(int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH]), + .m_axis_tuser(int_s_axis_tuser[m*USER_WIDTH +: USER_WIDTH]) + ); + end // s_ifaces + + for (n = 0; n < M_COUNT; n = n + 1) begin : m_ifaces + + // arbitration + wire [S_COUNT-1:0] request; + wire [S_COUNT-1:0] acknowledge; + wire [S_COUNT-1:0] grant; + wire grant_valid; + wire [CL_S_COUNT-1:0] grant_encoded; + + arbiter #( + .PORTS(S_COUNT), + .TYPE("ROUND_ROBIN"), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY("HIGH") + ) + arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) + ); + + // mux + wire [DATA_WIDTH-1:0] s_axis_tdata_mux = int_s_axis_tdata[grant_encoded*DATA_WIDTH +: DATA_WIDTH]; + wire [KEEP_WIDTH-1:0] s_axis_tkeep_mux = int_s_axis_tkeep[grant_encoded*KEEP_WIDTH +: KEEP_WIDTH]; + wire s_axis_tvalid_mux = int_axis_tvalid[grant_encoded*S_COUNT+n] && grant_valid; + wire s_axis_tready_mux; + wire s_axis_tlast_mux = int_s_axis_tlast[grant_encoded]; + wire [ID_WIDTH-1:0] s_axis_tid_mux = int_s_axis_tid[grant_encoded*ID_WIDTH +: ID_WIDTH]; + wire [DEST_WIDTH-1:0] s_axis_tdest_mux = int_s_axis_tdest[grant_encoded*DEST_WIDTH +: DEST_WIDTH]; + wire [USER_WIDTH-1:0] s_axis_tuser_mux = int_s_axis_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH]; + + assign int_axis_tready[n*S_COUNT +: S_COUNT] = (grant_valid && s_axis_tready_mux) << grant_encoded; + + for (m = 0; m < S_COUNT; m = m + 1) begin + assign request[m] = int_axis_tvalid[m*M_COUNT+n] && !grant[m]; + assign acknowledge[m] = grant[m] && int_axis_tvalid[m*M_COUNT+n] && s_axis_tlast_mux && s_axis_tready_mux; + end + + // M side register + axis_register #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(1), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(1), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .REG_TYPE(M_REG_TYPE) + ) + reg_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(s_axis_tdata_mux), + .s_axis_tkeep(s_axis_tkeep_mux), + .s_axis_tvalid(s_axis_tvalid_mux), + .s_axis_tready(s_axis_tready_mux), + .s_axis_tlast(s_axis_tlast_mux), + .s_axis_tid(s_axis_tid_mux), + .s_axis_tdest(s_axis_tdest_mux), + .s_axis_tuser(s_axis_tuser_mux), + // AXI output + .m_axis_tdata(m_axis_tdata[n*DATA_WIDTH +: DATA_WIDTH]), + .m_axis_tkeep(m_axis_tkeep[n*KEEP_WIDTH +: KEEP_WIDTH]), + .m_axis_tvalid(m_axis_tvalid[n]), + .m_axis_tready(m_axis_tready[n]), + .m_axis_tlast(m_axis_tlast[n]), + .m_axis_tid(m_axis_tid[n*ID_WIDTH +: ID_WIDTH]), + .m_axis_tdest(m_axis_tdest[n*DEST_WIDTH +: DEST_WIDTH]), + .m_axis_tuser(m_axis_tuser[n*USER_WIDTH +: USER_WIDTH]) + ); + end // m_ifaces + +endgenerate + +endmodule diff --git a/rtl/axis_switch_4x4.v b/rtl/axis_switch_4x4.v deleted file mode 100644 index 76264ad1b..000000000 --- a/rtl/axis_switch_4x4.v +++ /dev/null @@ -1,1338 +0,0 @@ -/* - -Copyright (c) 2016-2018 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 4x4 switch - */ -module axis_switch_4x4 # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_WIDTH = 2, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1, - parameter OUT_0_BASE = 0, - parameter OUT_0_TOP = 0, - parameter OUT_0_CONNECT = 4'b1111, - parameter OUT_1_BASE = 1, - parameter OUT_1_TOP = 1, - parameter OUT_1_CONNECT = 4'b1111, - parameter OUT_2_BASE = 2, - parameter OUT_2_TOP = 2, - parameter OUT_2_CONNECT = 4'b1111, - parameter OUT_3_BASE = 3, - parameter OUT_3_TOP = 3, - parameter OUT_3_CONNECT = 4'b1111, - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "ROUND_ROBIN", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * AXI Stream inputs - */ - input wire [DATA_WIDTH-1:0] input_0_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, - input wire input_0_axis_tvalid, - output wire input_0_axis_tready, - input wire input_0_axis_tlast, - input wire [ID_WIDTH-1:0] input_0_axis_tid, - input wire [DEST_WIDTH-1:0] input_0_axis_tdest, - input wire [USER_WIDTH-1:0] input_0_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_1_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, - input wire input_1_axis_tvalid, - output wire input_1_axis_tready, - input wire input_1_axis_tlast, - input wire [ID_WIDTH-1:0] input_1_axis_tid, - input wire [DEST_WIDTH-1:0] input_1_axis_tdest, - input wire [USER_WIDTH-1:0] input_1_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_2_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, - input wire input_2_axis_tvalid, - output wire input_2_axis_tready, - input wire input_2_axis_tlast, - input wire [ID_WIDTH-1:0] input_2_axis_tid, - input wire [DEST_WIDTH-1:0] input_2_axis_tdest, - input wire [USER_WIDTH-1:0] input_2_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_3_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, - input wire input_3_axis_tvalid, - output wire input_3_axis_tready, - input wire input_3_axis_tlast, - input wire [ID_WIDTH-1:0] input_3_axis_tid, - input wire [DEST_WIDTH-1:0] input_3_axis_tdest, - input wire [USER_WIDTH-1:0] input_3_axis_tuser, - - /* - * AXI Stream outputs - */ - output wire [DATA_WIDTH-1:0] output_0_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, - output wire output_0_axis_tvalid, - input wire output_0_axis_tready, - output wire output_0_axis_tlast, - output wire [ID_WIDTH-1:0] output_0_axis_tid, - output wire [DEST_WIDTH-1:0] output_0_axis_tdest, - output wire [USER_WIDTH-1:0] output_0_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_1_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, - output wire output_1_axis_tvalid, - input wire output_1_axis_tready, - output wire output_1_axis_tlast, - output wire [ID_WIDTH-1:0] output_1_axis_tid, - output wire [DEST_WIDTH-1:0] output_1_axis_tdest, - output wire [USER_WIDTH-1:0] output_1_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_2_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, - output wire output_2_axis_tvalid, - input wire output_2_axis_tready, - output wire output_2_axis_tlast, - output wire [ID_WIDTH-1:0] output_2_axis_tid, - output wire [DEST_WIDTH-1:0] output_2_axis_tdest, - output wire [USER_WIDTH-1:0] output_2_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_3_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, - output wire output_3_axis_tvalid, - input wire output_3_axis_tready, - output wire output_3_axis_tlast, - output wire [ID_WIDTH-1:0] output_3_axis_tid, - output wire [DEST_WIDTH-1:0] output_3_axis_tdest, - output wire [USER_WIDTH-1:0] output_3_axis_tuser -); - -// check configuration -initial begin - if (2**DEST_WIDTH < 4) begin - $error("Error: DEST_WIDTH too small for port count"); - $finish; - end - - if ((OUT_0_BASE & 2**DEST_WIDTH-1) != OUT_0_BASE || (OUT_0_TOP & 2**DEST_WIDTH-1) != OUT_0_TOP || - (OUT_1_BASE & 2**DEST_WIDTH-1) != OUT_1_BASE || (OUT_1_TOP & 2**DEST_WIDTH-1) != OUT_1_TOP || - (OUT_2_BASE & 2**DEST_WIDTH-1) != OUT_2_BASE || (OUT_2_TOP & 2**DEST_WIDTH-1) != OUT_2_TOP || - (OUT_3_BASE & 2**DEST_WIDTH-1) != OUT_3_BASE || (OUT_3_TOP & 2**DEST_WIDTH-1) != OUT_3_TOP) begin - $error("Error: value out of range"); - $finish; - end - - if (OUT_0_BASE > OUT_0_TOP || - OUT_1_BASE > OUT_1_TOP || - OUT_2_BASE > OUT_2_TOP || - OUT_3_BASE > OUT_3_TOP) begin - $error("Error: invalid range"); - $finish; - end - - if ((OUT_0_BASE <= OUT_1_TOP && OUT_1_BASE <= OUT_0_TOP) || - (OUT_0_BASE <= OUT_2_TOP && OUT_2_BASE <= OUT_0_TOP) || - (OUT_0_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_0_TOP) || - (OUT_1_BASE <= OUT_2_TOP && OUT_2_BASE <= OUT_1_TOP) || - (OUT_1_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_1_TOP) || - (OUT_2_BASE <= OUT_3_TOP && OUT_3_BASE <= OUT_2_TOP)) begin - $error("Error: ranges overlap"); - $finish; - end -end - -reg [3:0] input_0_request_reg = 4'd0, input_0_request_next; -reg input_0_request_valid_reg = 1'b0, input_0_request_valid_next; -reg input_0_request_error_reg = 1'b0, input_0_request_error_next; - -reg [3:0] input_1_request_reg = 4'd0, input_1_request_next; -reg input_1_request_valid_reg = 1'b0, input_1_request_valid_next; -reg input_1_request_error_reg = 1'b0, input_1_request_error_next; - -reg [3:0] input_2_request_reg = 4'd0, input_2_request_next; -reg input_2_request_valid_reg = 1'b0, input_2_request_valid_next; -reg input_2_request_error_reg = 1'b0, input_2_request_error_next; - -reg [3:0] input_3_request_reg = 4'd0, input_3_request_next; -reg input_3_request_valid_reg = 1'b0, input_3_request_valid_next; -reg input_3_request_error_reg = 1'b0, input_3_request_error_next; - -reg enable_0_reg = 1'b0, enable_0_next; -reg enable_1_reg = 1'b0, enable_1_next; -reg enable_2_reg = 1'b0, enable_2_next; -reg enable_3_reg = 1'b0, enable_3_next; - -reg input_0_axis_tready_reg = 1'b0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 1'b0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; - -// internal datapath -reg [DATA_WIDTH-1:0] output_0_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_int; -reg output_0_axis_tvalid_int; -reg output_0_axis_tready_int_reg = 1'b0; -reg output_0_axis_tlast_int; -reg [ID_WIDTH-1:0] output_0_axis_tid_int; -reg [DEST_WIDTH-1:0] output_0_axis_tdest_int; -reg [USER_WIDTH-1:0] output_0_axis_tuser_int; -wire output_0_axis_tready_int_early; - -reg [DATA_WIDTH-1:0] output_1_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_int; -reg output_1_axis_tvalid_int; -reg output_1_axis_tready_int_reg = 1'b0; -reg output_1_axis_tlast_int; -reg [ID_WIDTH-1:0] output_1_axis_tid_int; -reg [DEST_WIDTH-1:0] output_1_axis_tdest_int; -reg [USER_WIDTH-1:0] output_1_axis_tuser_int; -wire output_1_axis_tready_int_early; - -reg [DATA_WIDTH-1:0] output_2_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_int; -reg output_2_axis_tvalid_int; -reg output_2_axis_tready_int_reg = 1'b0; -reg output_2_axis_tlast_int; -reg [ID_WIDTH-1:0] output_2_axis_tid_int; -reg [DEST_WIDTH-1:0] output_2_axis_tdest_int; -reg [USER_WIDTH-1:0] output_2_axis_tuser_int; -wire output_2_axis_tready_int_early; - -reg [DATA_WIDTH-1:0] output_3_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_int; -reg output_3_axis_tvalid_int; -reg output_3_axis_tready_int_reg = 1'b0; -reg output_3_axis_tlast_int; -reg [ID_WIDTH-1:0] output_3_axis_tid_int; -reg [DEST_WIDTH-1:0] output_3_axis_tdest_int; -reg [USER_WIDTH-1:0] output_3_axis_tuser_int; -wire output_3_axis_tready_int_early; - -assign input_0_axis_tready = input_0_axis_tready_reg; -assign input_1_axis_tready = input_1_axis_tready_reg; -assign input_2_axis_tready = input_2_axis_tready_reg; -assign input_3_axis_tready = input_3_axis_tready_reg; - -// mux for incoming packet - -reg [DATA_WIDTH-1:0] current_input_0_axis_tdata; -reg [KEEP_WIDTH-1:0] current_input_0_axis_tkeep; -reg current_input_0_axis_tvalid; -reg current_input_0_axis_tready; -reg current_input_0_axis_tlast; -reg [ID_WIDTH-1:0] current_input_0_axis_tid; -reg [DEST_WIDTH-1:0] current_input_0_axis_tdest; -reg [USER_WIDTH-1:0] current_input_0_axis_tuser; - -always @* begin - case (grant_encoded_0) - 2'd0: begin - current_input_0_axis_tdata = input_0_axis_tdata; - current_input_0_axis_tkeep = input_0_axis_tkeep; - current_input_0_axis_tvalid = input_0_axis_tvalid; - current_input_0_axis_tready = input_0_axis_tready; - current_input_0_axis_tlast = input_0_axis_tlast; - current_input_0_axis_tid = input_0_axis_tid; - current_input_0_axis_tdest = input_0_axis_tdest; - current_input_0_axis_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_0_axis_tdata = input_1_axis_tdata; - current_input_0_axis_tkeep = input_1_axis_tkeep; - current_input_0_axis_tvalid = input_1_axis_tvalid; - current_input_0_axis_tready = input_1_axis_tready; - current_input_0_axis_tlast = input_1_axis_tlast; - current_input_0_axis_tid = input_1_axis_tid; - current_input_0_axis_tdest = input_1_axis_tdest; - current_input_0_axis_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_0_axis_tdata = input_2_axis_tdata; - current_input_0_axis_tkeep = input_2_axis_tkeep; - current_input_0_axis_tvalid = input_2_axis_tvalid; - current_input_0_axis_tready = input_2_axis_tready; - current_input_0_axis_tlast = input_2_axis_tlast; - current_input_0_axis_tid = input_2_axis_tid; - current_input_0_axis_tdest = input_2_axis_tdest; - current_input_0_axis_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_0_axis_tdata = input_3_axis_tdata; - current_input_0_axis_tkeep = input_3_axis_tkeep; - current_input_0_axis_tvalid = input_3_axis_tvalid; - current_input_0_axis_tready = input_3_axis_tready; - current_input_0_axis_tlast = input_3_axis_tlast; - current_input_0_axis_tid = input_3_axis_tid; - current_input_0_axis_tdest = input_3_axis_tdest; - current_input_0_axis_tuser = input_3_axis_tuser; - end - default: begin - current_input_0_axis_tdata = {DATA_WIDTH{1'b0}}; - current_input_0_axis_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_0_axis_tvalid = 1'b0; - current_input_0_axis_tready = 1'b0; - current_input_0_axis_tlast = 1'b0; - current_input_0_axis_tid = {ID_WIDTH{1'b0}}; - current_input_0_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_0_axis_tuser = {USER_WIDTH{1'b0}}; - end - endcase -end - -reg [DATA_WIDTH-1:0] current_input_1_axis_tdata; -reg [KEEP_WIDTH-1:0] current_input_1_axis_tkeep; -reg current_input_1_axis_tvalid; -reg current_input_1_axis_tready; -reg current_input_1_axis_tlast; -reg [ID_WIDTH-1:0] current_input_1_axis_tid; -reg [DEST_WIDTH-1:0] current_input_1_axis_tdest; -reg [USER_WIDTH-1:0] current_input_1_axis_tuser; - -always @* begin - case (grant_encoded_1) - 2'd0: begin - current_input_1_axis_tdata = input_0_axis_tdata; - current_input_1_axis_tkeep = input_0_axis_tkeep; - current_input_1_axis_tvalid = input_0_axis_tvalid; - current_input_1_axis_tready = input_0_axis_tready; - current_input_1_axis_tlast = input_0_axis_tlast; - current_input_1_axis_tid = input_0_axis_tid; - current_input_1_axis_tdest = input_0_axis_tdest; - current_input_1_axis_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_1_axis_tdata = input_1_axis_tdata; - current_input_1_axis_tkeep = input_1_axis_tkeep; - current_input_1_axis_tvalid = input_1_axis_tvalid; - current_input_1_axis_tready = input_1_axis_tready; - current_input_1_axis_tlast = input_1_axis_tlast; - current_input_1_axis_tid = input_1_axis_tid; - current_input_1_axis_tdest = input_1_axis_tdest; - current_input_1_axis_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_1_axis_tdata = input_2_axis_tdata; - current_input_1_axis_tkeep = input_2_axis_tkeep; - current_input_1_axis_tvalid = input_2_axis_tvalid; - current_input_1_axis_tready = input_2_axis_tready; - current_input_1_axis_tlast = input_2_axis_tlast; - current_input_1_axis_tid = input_2_axis_tid; - current_input_1_axis_tdest = input_2_axis_tdest; - current_input_1_axis_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_1_axis_tdata = input_3_axis_tdata; - current_input_1_axis_tkeep = input_3_axis_tkeep; - current_input_1_axis_tvalid = input_3_axis_tvalid; - current_input_1_axis_tready = input_3_axis_tready; - current_input_1_axis_tlast = input_3_axis_tlast; - current_input_1_axis_tid = input_3_axis_tid; - current_input_1_axis_tdest = input_3_axis_tdest; - current_input_1_axis_tuser = input_3_axis_tuser; - end - default: begin - current_input_1_axis_tdata = {DATA_WIDTH{1'b0}}; - current_input_1_axis_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_1_axis_tvalid = 1'b0; - current_input_1_axis_tready = 1'b0; - current_input_1_axis_tlast = 1'b0; - current_input_1_axis_tid = {ID_WIDTH{1'b0}}; - current_input_1_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_1_axis_tuser = {USER_WIDTH{1'b0}}; - end - endcase -end - -reg [DATA_WIDTH-1:0] current_input_2_axis_tdata; -reg [KEEP_WIDTH-1:0] current_input_2_axis_tkeep; -reg current_input_2_axis_tvalid; -reg current_input_2_axis_tready; -reg current_input_2_axis_tlast; -reg [ID_WIDTH-1:0] current_input_2_axis_tid; -reg [DEST_WIDTH-1:0] current_input_2_axis_tdest; -reg [USER_WIDTH-1:0] current_input_2_axis_tuser; - -always @* begin - case (grant_encoded_2) - 2'd0: begin - current_input_2_axis_tdata = input_0_axis_tdata; - current_input_2_axis_tkeep = input_0_axis_tkeep; - current_input_2_axis_tvalid = input_0_axis_tvalid; - current_input_2_axis_tready = input_0_axis_tready; - current_input_2_axis_tlast = input_0_axis_tlast; - current_input_2_axis_tid = input_0_axis_tid; - current_input_2_axis_tdest = input_0_axis_tdest; - current_input_2_axis_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_2_axis_tdata = input_1_axis_tdata; - current_input_2_axis_tkeep = input_1_axis_tkeep; - current_input_2_axis_tvalid = input_1_axis_tvalid; - current_input_2_axis_tready = input_1_axis_tready; - current_input_2_axis_tlast = input_1_axis_tlast; - current_input_2_axis_tid = input_1_axis_tid; - current_input_2_axis_tdest = input_1_axis_tdest; - current_input_2_axis_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_2_axis_tdata = input_2_axis_tdata; - current_input_2_axis_tkeep = input_2_axis_tkeep; - current_input_2_axis_tvalid = input_2_axis_tvalid; - current_input_2_axis_tready = input_2_axis_tready; - current_input_2_axis_tlast = input_2_axis_tlast; - current_input_2_axis_tid = input_2_axis_tid; - current_input_2_axis_tdest = input_2_axis_tdest; - current_input_2_axis_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_2_axis_tdata = input_3_axis_tdata; - current_input_2_axis_tkeep = input_3_axis_tkeep; - current_input_2_axis_tvalid = input_3_axis_tvalid; - current_input_2_axis_tready = input_3_axis_tready; - current_input_2_axis_tlast = input_3_axis_tlast; - current_input_2_axis_tid = input_3_axis_tid; - current_input_2_axis_tdest = input_3_axis_tdest; - current_input_2_axis_tuser = input_3_axis_tuser; - end - default: begin - current_input_2_axis_tdata = {DATA_WIDTH{1'b0}}; - current_input_2_axis_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_2_axis_tvalid = 1'b0; - current_input_2_axis_tready = 1'b0; - current_input_2_axis_tlast = 1'b0; - current_input_2_axis_tid = {ID_WIDTH{1'b0}}; - current_input_2_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_2_axis_tuser = {USER_WIDTH{1'b0}}; - end - endcase -end - -reg [DATA_WIDTH-1:0] current_input_3_axis_tdata; -reg [KEEP_WIDTH-1:0] current_input_3_axis_tkeep; -reg current_input_3_axis_tvalid; -reg current_input_3_axis_tready; -reg current_input_3_axis_tlast; -reg [ID_WIDTH-1:0] current_input_3_axis_tid; -reg [DEST_WIDTH-1:0] current_input_3_axis_tdest; -reg [USER_WIDTH-1:0] current_input_3_axis_tuser; - -always @* begin - case (grant_encoded_3) - 2'd0: begin - current_input_3_axis_tdata = input_0_axis_tdata; - current_input_3_axis_tkeep = input_0_axis_tkeep; - current_input_3_axis_tvalid = input_0_axis_tvalid; - current_input_3_axis_tready = input_0_axis_tready; - current_input_3_axis_tlast = input_0_axis_tlast; - current_input_3_axis_tid = input_0_axis_tid; - current_input_3_axis_tdest = input_0_axis_tdest; - current_input_3_axis_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_3_axis_tdata = input_1_axis_tdata; - current_input_3_axis_tkeep = input_1_axis_tkeep; - current_input_3_axis_tvalid = input_1_axis_tvalid; - current_input_3_axis_tready = input_1_axis_tready; - current_input_3_axis_tlast = input_1_axis_tlast; - current_input_3_axis_tid = input_1_axis_tid; - current_input_3_axis_tdest = input_1_axis_tdest; - current_input_3_axis_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_3_axis_tdata = input_2_axis_tdata; - current_input_3_axis_tkeep = input_2_axis_tkeep; - current_input_3_axis_tvalid = input_2_axis_tvalid; - current_input_3_axis_tready = input_2_axis_tready; - current_input_3_axis_tlast = input_2_axis_tlast; - current_input_3_axis_tid = input_2_axis_tid; - current_input_3_axis_tdest = input_2_axis_tdest; - current_input_3_axis_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_3_axis_tdata = input_3_axis_tdata; - current_input_3_axis_tkeep = input_3_axis_tkeep; - current_input_3_axis_tvalid = input_3_axis_tvalid; - current_input_3_axis_tready = input_3_axis_tready; - current_input_3_axis_tlast = input_3_axis_tlast; - current_input_3_axis_tid = input_3_axis_tid; - current_input_3_axis_tdest = input_3_axis_tdest; - current_input_3_axis_tuser = input_3_axis_tuser; - end - default: begin - current_input_3_axis_tdata = {DATA_WIDTH{1'b0}}; - current_input_3_axis_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_3_axis_tvalid = 1'b0; - current_input_3_axis_tready = 1'b0; - current_input_3_axis_tlast = 1'b0; - current_input_3_axis_tid = {ID_WIDTH{1'b0}}; - current_input_3_axis_tdest = {DEST_WIDTH{1'b0}}; - current_input_3_axis_tuser = {USER_WIDTH{1'b0}}; - end - endcase -end - -// arbiter instances - -wire [3:0] request_0; -wire [3:0] acknowledge_0; -wire [3:0] grant_0; -wire grant_valid_0; -wire [1:0] grant_encoded_0; - -wire [3:0] request_1; -wire [3:0] acknowledge_1; -wire [3:0] grant_1; -wire grant_valid_1; -wire [1:0] grant_encoded_1; - -wire [3:0] request_2; -wire [3:0] acknowledge_2; -wire [3:0] grant_2; -wire grant_valid_2; -wire [1:0] grant_encoded_2; - -wire [3:0] request_3; -wire [3:0] acknowledge_3; -wire [3:0] grant_3; -wire grant_valid_3; -wire [1:0] grant_encoded_3; - -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_0_inst ( - .clk(clk), - .rst(rst), - .request(request_0), - .acknowledge(acknowledge_0), - .grant(grant_0), - .grant_valid(grant_valid_0), - .grant_encoded(grant_encoded_0) -); - -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_1_inst ( - .clk(clk), - .rst(rst), - .request(request_1), - .acknowledge(acknowledge_1), - .grant(grant_1), - .grant_valid(grant_valid_1), - .grant_encoded(grant_encoded_1) -); - -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_2_inst ( - .clk(clk), - .rst(rst), - .request(request_2), - .acknowledge(acknowledge_2), - .grant(grant_2), - .grant_valid(grant_valid_2), - .grant_encoded(grant_encoded_2) -); - -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_3_inst ( - .clk(clk), - .rst(rst), - .request(request_3), - .acknowledge(acknowledge_3), - .grant(grant_3), - .grant_valid(grant_valid_3), - .grant_encoded(grant_encoded_3) -); - -// request generation -assign request_0[0] = input_0_request_reg[0] & ~acknowledge_0[0]; -assign request_0[1] = input_1_request_reg[0] & ~acknowledge_0[1]; -assign request_0[2] = input_2_request_reg[0] & ~acknowledge_0[2]; -assign request_0[3] = input_3_request_reg[0] & ~acknowledge_0[3]; - -assign request_1[0] = input_0_request_reg[1] & ~acknowledge_1[0]; -assign request_1[1] = input_1_request_reg[1] & ~acknowledge_1[1]; -assign request_1[2] = input_2_request_reg[1] & ~acknowledge_1[2]; -assign request_1[3] = input_3_request_reg[1] & ~acknowledge_1[3]; - -assign request_2[0] = input_0_request_reg[2] & ~acknowledge_2[0]; -assign request_2[1] = input_1_request_reg[2] & ~acknowledge_2[1]; -assign request_2[2] = input_2_request_reg[2] & ~acknowledge_2[2]; -assign request_2[3] = input_3_request_reg[2] & ~acknowledge_2[3]; - -assign request_3[0] = input_0_request_reg[3] & ~acknowledge_3[0]; -assign request_3[1] = input_1_request_reg[3] & ~acknowledge_3[1]; -assign request_3[2] = input_2_request_reg[3] & ~acknowledge_3[2]; -assign request_3[3] = input_3_request_reg[3] & ~acknowledge_3[3]; - -// acknowledge generation -assign acknowledge_0[0] = grant_0[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign acknowledge_0[1] = grant_0[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign acknowledge_0[2] = grant_0[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign acknowledge_0[3] = grant_0[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; - -assign acknowledge_1[0] = grant_1[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign acknowledge_1[1] = grant_1[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign acknowledge_1[2] = grant_1[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign acknowledge_1[3] = grant_1[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; - -assign acknowledge_2[0] = grant_2[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign acknowledge_2[1] = grant_2[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign acknowledge_2[2] = grant_2[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign acknowledge_2[3] = grant_2[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; - -assign acknowledge_3[0] = grant_3[0] & input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast; -assign acknowledge_3[1] = grant_3[1] & input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast; -assign acknowledge_3[2] = grant_3[2] & input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast; -assign acknowledge_3[3] = grant_3[3] & input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast; - -always @* begin - - enable_0_next = enable_0_reg; - enable_1_next = enable_1_reg; - enable_2_next = enable_2_reg; - enable_3_next = enable_3_reg; - - input_0_request_next = input_0_request_reg; - input_0_request_valid_next = input_0_request_valid_reg; - input_0_request_error_next = input_0_request_error_reg; - - input_1_request_next = input_1_request_reg; - input_1_request_valid_next = input_1_request_valid_reg; - input_1_request_error_next = input_1_request_error_reg; - - input_2_request_next = input_2_request_reg; - input_2_request_valid_next = input_2_request_valid_reg; - input_2_request_error_next = input_2_request_error_reg; - - input_3_request_next = input_3_request_reg; - input_3_request_valid_next = input_3_request_valid_reg; - input_3_request_error_next = input_3_request_error_reg; - - input_0_axis_tready_next = 1'b0; - input_1_axis_tready_next = 1'b0; - input_2_axis_tready_next = 1'b0; - input_3_axis_tready_next = 1'b0; - - output_0_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_0_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; - output_0_axis_tvalid_int = 1'b0; - output_0_axis_tlast_int = 1'b0; - output_0_axis_tid_int = {ID_WIDTH{1'b0}}; - output_0_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_0_axis_tuser_int = {USER_WIDTH{1'b0}}; - - output_1_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_1_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; - output_1_axis_tvalid_int = 1'b0; - output_1_axis_tlast_int = 1'b0; - output_1_axis_tid_int = {ID_WIDTH{1'b0}}; - output_1_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_1_axis_tuser_int = {USER_WIDTH{1'b0}}; - - output_2_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_2_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; - output_2_axis_tvalid_int = 1'b0; - output_2_axis_tlast_int = 1'b0; - output_2_axis_tid_int = {ID_WIDTH{1'b0}}; - output_2_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_2_axis_tuser_int = {USER_WIDTH{1'b0}}; - - output_3_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_3_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; - output_3_axis_tvalid_int = 1'b0; - output_3_axis_tlast_int = 1'b0; - output_3_axis_tid_int = {ID_WIDTH{1'b0}}; - output_3_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_3_axis_tuser_int = {USER_WIDTH{1'b0}}; - - // input decoding - - if (input_0_request_valid_reg | input_0_request_error_reg) begin - if (input_0_axis_tvalid & input_0_axis_tready & input_0_axis_tlast) begin - input_0_request_next = {DEST_WIDTH{1'b0}}; - input_0_request_valid_next = 1'b0; - input_0_request_error_next = 1'b0; - end - end else if (input_0_axis_tvalid) begin - input_0_request_next[0] = (input_0_axis_tdest >= OUT_0_BASE) & (input_0_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[0]; - input_0_request_next[1] = (input_0_axis_tdest >= OUT_1_BASE) & (input_0_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[0]; - input_0_request_next[2] = (input_0_axis_tdest >= OUT_2_BASE) & (input_0_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[0]; - input_0_request_next[3] = (input_0_axis_tdest >= OUT_3_BASE) & (input_0_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[0]; - - if (input_0_request_next) begin - input_0_request_valid_next = 1'b1; - end else begin - input_0_request_error_next = 1'b1; - end - end - - if (input_1_request_valid_reg | input_1_request_error_reg) begin - if (input_1_axis_tvalid & input_1_axis_tready & input_1_axis_tlast) begin - input_1_request_next = {DEST_WIDTH{1'b0}}; - input_1_request_valid_next = 1'b0; - input_1_request_error_next = 1'b0; - end - end else if (input_1_axis_tvalid) begin - input_1_request_next[0] = (input_1_axis_tdest >= OUT_0_BASE) & (input_1_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[1]; - input_1_request_next[1] = (input_1_axis_tdest >= OUT_1_BASE) & (input_1_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[1]; - input_1_request_next[2] = (input_1_axis_tdest >= OUT_2_BASE) & (input_1_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[1]; - input_1_request_next[3] = (input_1_axis_tdest >= OUT_3_BASE) & (input_1_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[1]; - - if (input_1_request_next) begin - input_1_request_valid_next = 1'b1; - end else begin - input_1_request_error_next = 1'b1; - end - end - - if (input_2_request_valid_reg | input_2_request_error_reg) begin - if (input_2_axis_tvalid & input_2_axis_tready & input_2_axis_tlast) begin - input_2_request_next = {DEST_WIDTH{1'b0}}; - input_2_request_valid_next = 1'b0; - input_2_request_error_next = 1'b0; - end - end else if (input_2_axis_tvalid) begin - input_2_request_next[0] = (input_2_axis_tdest >= OUT_0_BASE) & (input_2_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[2]; - input_2_request_next[1] = (input_2_axis_tdest >= OUT_1_BASE) & (input_2_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[2]; - input_2_request_next[2] = (input_2_axis_tdest >= OUT_2_BASE) & (input_2_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[2]; - input_2_request_next[3] = (input_2_axis_tdest >= OUT_3_BASE) & (input_2_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[2]; - - if (input_2_request_next) begin - input_2_request_valid_next = 1'b1; - end else begin - input_2_request_error_next = 1'b1; - end - end - - if (input_3_request_valid_reg | input_3_request_error_reg) begin - if (input_3_axis_tvalid & input_3_axis_tready & input_3_axis_tlast) begin - input_3_request_next = {DEST_WIDTH{1'b0}}; - input_3_request_valid_next = 1'b0; - input_3_request_error_next = 1'b0; - end - end else if (input_3_axis_tvalid) begin - input_3_request_next[0] = (input_3_axis_tdest >= OUT_0_BASE) & (input_3_axis_tdest <= OUT_0_TOP) & OUT_0_CONNECT[3]; - input_3_request_next[1] = (input_3_axis_tdest >= OUT_1_BASE) & (input_3_axis_tdest <= OUT_1_TOP) & OUT_1_CONNECT[3]; - input_3_request_next[2] = (input_3_axis_tdest >= OUT_2_BASE) & (input_3_axis_tdest <= OUT_2_TOP) & OUT_2_CONNECT[3]; - input_3_request_next[3] = (input_3_axis_tdest >= OUT_3_BASE) & (input_3_axis_tdest <= OUT_3_TOP) & OUT_3_CONNECT[3]; - - if (input_3_request_next) begin - input_3_request_valid_next = 1'b1; - end else begin - input_3_request_error_next = 1'b1; - end - end - - // output control - - if (current_input_0_axis_tvalid & current_input_0_axis_tready) begin - if (current_input_0_axis_tlast) begin - enable_0_next = 1'b0; - end - end - if (~enable_0_reg & grant_valid_0) begin - enable_0_next = 1'b1; - end - - if (current_input_1_axis_tvalid & current_input_1_axis_tready) begin - if (current_input_1_axis_tlast) begin - enable_1_next = 1'b0; - end - end - if (~enable_1_reg & grant_valid_1) begin - enable_1_next = 1'b1; - end - - if (current_input_2_axis_tvalid & current_input_2_axis_tready) begin - if (current_input_2_axis_tlast) begin - enable_2_next = 1'b0; - end - end - if (~enable_2_reg & grant_valid_2) begin - enable_2_next = 1'b1; - end - - if (current_input_3_axis_tvalid & current_input_3_axis_tready) begin - if (current_input_3_axis_tlast) begin - enable_3_next = 1'b0; - end - end - if (~enable_3_reg & grant_valid_3) begin - enable_3_next = 1'b1; - end - - // generate ready signal on selected port - - if (enable_0_next) begin - case (grant_encoded_0) - 2'd0: input_0_axis_tready_next = output_0_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_0_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_0_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_0_axis_tready_int_early; - endcase - end - - if (enable_1_next) begin - case (grant_encoded_1) - 2'd0: input_0_axis_tready_next = output_1_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_1_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_1_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_1_axis_tready_int_early; - endcase - end - - if (enable_2_next) begin - case (grant_encoded_2) - 2'd0: input_0_axis_tready_next = output_2_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_2_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_2_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_2_axis_tready_int_early; - endcase - end - - if (enable_3_next) begin - case (grant_encoded_3) - 2'd0: input_0_axis_tready_next = output_3_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_3_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_3_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_3_axis_tready_int_early; - endcase - end - - if (input_0_request_error_next) - input_0_axis_tready_next = 1'b1; - if (input_1_request_error_next) - input_1_axis_tready_next = 1'b1; - if (input_2_request_error_next) - input_2_axis_tready_next = 1'b1; - if (input_3_request_error_next) - input_3_axis_tready_next = 1'b1; - - // pass through selected packet data - - output_0_axis_tdata_int = current_input_0_axis_tdata; - output_0_axis_tkeep_int = current_input_0_axis_tkeep; - output_0_axis_tvalid_int = current_input_0_axis_tvalid & current_input_0_axis_tready & enable_0_reg; - output_0_axis_tlast_int = current_input_0_axis_tlast; - output_0_axis_tid_int = current_input_0_axis_tid; - output_0_axis_tdest_int = current_input_0_axis_tdest; - output_0_axis_tuser_int = current_input_0_axis_tuser; - - output_1_axis_tdata_int = current_input_1_axis_tdata; - output_1_axis_tkeep_int = current_input_1_axis_tkeep; - output_1_axis_tvalid_int = current_input_1_axis_tvalid & current_input_1_axis_tready & enable_1_reg; - output_1_axis_tlast_int = current_input_1_axis_tlast; - output_1_axis_tid_int = current_input_1_axis_tid; - output_1_axis_tdest_int = current_input_1_axis_tdest; - output_1_axis_tuser_int = current_input_1_axis_tuser; - - output_2_axis_tdata_int = current_input_2_axis_tdata; - output_2_axis_tkeep_int = current_input_2_axis_tkeep; - output_2_axis_tvalid_int = current_input_2_axis_tvalid & current_input_2_axis_tready & enable_2_reg; - output_2_axis_tlast_int = current_input_2_axis_tlast; - output_2_axis_tid_int = current_input_2_axis_tid; - output_2_axis_tdest_int = current_input_2_axis_tdest; - output_2_axis_tuser_int = current_input_2_axis_tuser; - - output_3_axis_tdata_int = current_input_3_axis_tdata; - output_3_axis_tkeep_int = current_input_3_axis_tkeep; - output_3_axis_tvalid_int = current_input_3_axis_tvalid & current_input_3_axis_tready & enable_3_reg; - output_3_axis_tlast_int = current_input_3_axis_tlast; - output_3_axis_tid_int = current_input_3_axis_tid; - output_3_axis_tdest_int = current_input_3_axis_tdest; - output_3_axis_tuser_int = current_input_3_axis_tuser; -end - -always @(posedge clk) begin - if (rst) begin - input_0_request_reg <= 4'd0; - input_0_request_valid_reg <= 1'b0; - input_0_request_error_reg <= 1'b0; - input_1_request_reg <= 4'd0; - input_1_request_valid_reg <= 1'b0; - input_1_request_error_reg <= 1'b0; - input_2_request_reg <= 4'd0; - input_2_request_valid_reg <= 1'b0; - input_2_request_error_reg <= 1'b0; - input_3_request_reg <= 4'd0; - input_3_request_valid_reg <= 1'b0; - input_3_request_error_reg <= 1'b0; - enable_0_reg <= 1'b0; - enable_1_reg <= 1'b0; - enable_2_reg <= 1'b0; - enable_3_reg <= 1'b0; - input_0_axis_tready_reg <= 1'b0; - input_1_axis_tready_reg <= 1'b0; - input_2_axis_tready_reg <= 1'b0; - input_3_axis_tready_reg <= 1'b0; - end else begin - input_0_request_reg <= input_0_request_next; - input_0_request_valid_reg <= input_0_request_valid_next; - input_0_request_error_reg <= input_0_request_error_next; - input_1_request_reg <= input_1_request_next; - input_1_request_valid_reg <= input_1_request_valid_next; - input_1_request_error_reg <= input_1_request_error_next; - input_2_request_reg <= input_2_request_next; - input_2_request_valid_reg <= input_2_request_valid_next; - input_2_request_error_reg <= input_2_request_error_next; - input_3_request_reg <= input_3_request_next; - input_3_request_valid_reg <= input_3_request_valid_next; - input_3_request_error_reg <= input_3_request_error_next; - enable_0_reg <= enable_0_next; - enable_1_reg <= enable_1_next; - enable_2_reg <= enable_2_next; - enable_3_reg <= enable_3_next; - input_0_axis_tready_reg <= input_0_axis_tready_next; - input_1_axis_tready_reg <= input_1_axis_tready_next; - input_2_axis_tready_reg <= input_2_axis_tready_next; - input_3_axis_tready_reg <= input_3_axis_tready_next; - end -end - -// output 0 datapath logic -reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_0_axis_tvalid_reg = 1'b0, output_0_axis_tvalid_next; -reg output_0_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_0_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_0_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_0_axis_tvalid_reg = 1'b0, temp_0_axis_tvalid_next; -reg temp_0_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_0_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_0_axis_tuser_reg = 1'b0; - -// datapath control -reg store_0_axis_int_to_output; -reg store_0_axis_int_to_temp; -reg store_0_axis_temp_to_output; - -assign output_0_axis_tdata = output_0_axis_tdata_reg; -assign output_0_axis_tkeep = KEEP_ENABLE ? output_0_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_0_axis_tvalid = output_0_axis_tvalid_reg; -assign output_0_axis_tlast = output_0_axis_tlast_reg; -assign output_0_axis_tid = ID_ENABLE ? output_0_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_0_axis_tdest = output_0_axis_tdest_reg; -assign output_0_axis_tuser = USER_ENABLE ? output_0_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_0_axis_tready_int_early = output_0_axis_tready | (~temp_0_axis_tvalid_reg & (~output_0_axis_tvalid_reg | ~output_0_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_0_axis_tvalid_next = output_0_axis_tvalid_reg; - temp_0_axis_tvalid_next = temp_0_axis_tvalid_reg; - - store_0_axis_int_to_output = 1'b0; - store_0_axis_int_to_temp = 1'b0; - store_0_axis_temp_to_output = 1'b0; - - if (output_0_axis_tready_int_reg) begin - // input is ready - if (output_0_axis_tready | ~output_0_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_0_axis_tvalid_next = output_0_axis_tvalid_int; - store_0_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_0_axis_tvalid_next = output_0_axis_tvalid_int; - store_0_axis_int_to_temp = 1'b1; - end - end else if (output_0_axis_tready) begin - // input is not ready, but output is ready - output_0_axis_tvalid_next = temp_0_axis_tvalid_reg; - temp_0_axis_tvalid_next = 1'b0; - store_0_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_0_axis_tvalid_reg <= 1'b0; - output_0_axis_tready_int_reg <= 1'b0; - temp_0_axis_tvalid_reg <= 1'b0; - end else begin - output_0_axis_tvalid_reg <= output_0_axis_tvalid_next; - output_0_axis_tready_int_reg <= output_0_axis_tready_int_early; - temp_0_axis_tvalid_reg <= temp_0_axis_tvalid_next; - end - - // datapath - if (store_0_axis_int_to_output) begin - output_0_axis_tdata_reg <= output_0_axis_tdata_int; - output_0_axis_tkeep_reg <= output_0_axis_tkeep_int; - output_0_axis_tlast_reg <= output_0_axis_tlast_int; - output_0_axis_tid_reg <= output_0_axis_tid_int; - output_0_axis_tdest_reg <= output_0_axis_tdest_int; - output_0_axis_tuser_reg <= output_0_axis_tuser_int; - end else if (store_0_axis_temp_to_output) begin - output_0_axis_tdata_reg <= temp_0_axis_tdata_reg; - output_0_axis_tkeep_reg <= temp_0_axis_tkeep_reg; - output_0_axis_tlast_reg <= temp_0_axis_tlast_reg; - output_0_axis_tid_reg <= temp_0_axis_tid_reg; - output_0_axis_tdest_reg <= temp_0_axis_tdest_reg; - output_0_axis_tuser_reg <= temp_0_axis_tuser_reg; - end - - if (store_0_axis_int_to_temp) begin - temp_0_axis_tdata_reg <= output_0_axis_tdata_int; - temp_0_axis_tkeep_reg <= output_0_axis_tkeep_int; - temp_0_axis_tlast_reg <= output_0_axis_tlast_int; - temp_0_axis_tid_reg <= output_0_axis_tid_int; - temp_0_axis_tdest_reg <= output_0_axis_tdest_int; - temp_0_axis_tuser_reg <= output_0_axis_tuser_int; - end -end - -// output 1 datapath logic -reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_1_axis_tvalid_reg = 1'b0, output_1_axis_tvalid_next; -reg output_1_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_1_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_1_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_1_axis_tvalid_reg = 1'b0, temp_1_axis_tvalid_next; -reg temp_1_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_1_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_1_axis_tuser_reg = 1'b0; - -// datapath control -reg store_1_axis_int_to_output; -reg store_1_axis_int_to_temp; -reg store_1_axis_temp_to_output; - -assign output_1_axis_tdata = output_1_axis_tdata_reg; -assign output_1_axis_tkeep = KEEP_ENABLE ? output_1_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_1_axis_tvalid = output_1_axis_tvalid_reg; -assign output_1_axis_tlast = output_1_axis_tlast_reg; -assign output_1_axis_tid = ID_ENABLE ? output_1_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_1_axis_tdest = output_1_axis_tdest_reg; -assign output_1_axis_tuser = USER_ENABLE ? output_1_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_1_axis_tready_int_early = output_1_axis_tready | (~temp_1_axis_tvalid_reg & (~output_1_axis_tvalid_reg | ~output_1_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_1_axis_tvalid_next = output_1_axis_tvalid_reg; - temp_1_axis_tvalid_next = temp_1_axis_tvalid_reg; - - store_1_axis_int_to_output = 1'b0; - store_1_axis_int_to_temp = 1'b0; - store_1_axis_temp_to_output = 1'b0; - - if (output_1_axis_tready_int_reg) begin - // input is ready - if (output_1_axis_tready | ~output_1_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_1_axis_tvalid_next = output_1_axis_tvalid_int; - store_1_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_1_axis_tvalid_next = output_1_axis_tvalid_int; - store_1_axis_int_to_temp = 1'b1; - end - end else if (output_1_axis_tready) begin - // input is not ready, but output is ready - output_1_axis_tvalid_next = temp_1_axis_tvalid_reg; - temp_1_axis_tvalid_next = 1'b0; - store_1_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_1_axis_tvalid_reg <= 1'b0; - output_1_axis_tready_int_reg <= 1'b0; - temp_1_axis_tvalid_reg <= 1'b0; - end else begin - output_1_axis_tvalid_reg <= output_1_axis_tvalid_next; - output_1_axis_tready_int_reg <= output_1_axis_tready_int_early; - temp_1_axis_tvalid_reg <= temp_1_axis_tvalid_next; - end - - // datapath - if (store_1_axis_int_to_output) begin - output_1_axis_tdata_reg <= output_1_axis_tdata_int; - output_1_axis_tkeep_reg <= output_1_axis_tkeep_int; - output_1_axis_tlast_reg <= output_1_axis_tlast_int; - output_1_axis_tid_reg <= output_1_axis_tid_int; - output_1_axis_tdest_reg <= output_1_axis_tdest_int; - output_1_axis_tuser_reg <= output_1_axis_tuser_int; - end else if (store_1_axis_temp_to_output) begin - output_1_axis_tdata_reg <= temp_1_axis_tdata_reg; - output_1_axis_tkeep_reg <= temp_1_axis_tkeep_reg; - output_1_axis_tlast_reg <= temp_1_axis_tlast_reg; - output_1_axis_tid_reg <= temp_1_axis_tid_reg; - output_1_axis_tdest_reg <= temp_1_axis_tdest_reg; - output_1_axis_tuser_reg <= temp_1_axis_tuser_reg; - end - - if (store_1_axis_int_to_temp) begin - temp_1_axis_tdata_reg <= output_1_axis_tdata_int; - temp_1_axis_tkeep_reg <= output_1_axis_tkeep_int; - temp_1_axis_tlast_reg <= output_1_axis_tlast_int; - temp_1_axis_tid_reg <= output_1_axis_tid_int; - temp_1_axis_tdest_reg <= output_1_axis_tdest_int; - temp_1_axis_tuser_reg <= output_1_axis_tuser_int; - end -end - -// output 2 datapath logic -reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_2_axis_tvalid_reg = 1'b0, output_2_axis_tvalid_next; -reg output_2_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_2_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_2_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_2_axis_tvalid_reg = 1'b0, temp_2_axis_tvalid_next; -reg temp_2_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_2_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_2_axis_tuser_reg = 1'b0; - -// datapath control -reg store_2_axis_int_to_output; -reg store_2_axis_int_to_temp; -reg store_2_axis_temp_to_output; - -assign output_2_axis_tdata = output_2_axis_tdata_reg; -assign output_2_axis_tkeep = KEEP_ENABLE ? output_2_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_2_axis_tvalid = output_2_axis_tvalid_reg; -assign output_2_axis_tlast = output_2_axis_tlast_reg; -assign output_2_axis_tid = ID_ENABLE ? output_2_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_2_axis_tdest = output_2_axis_tdest_reg; -assign output_2_axis_tuser = USER_ENABLE ? output_2_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_2_axis_tready_int_early = output_2_axis_tready | (~temp_2_axis_tvalid_reg & (~output_2_axis_tvalid_reg | ~output_2_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_2_axis_tvalid_next = output_2_axis_tvalid_reg; - temp_2_axis_tvalid_next = temp_2_axis_tvalid_reg; - - store_2_axis_int_to_output = 1'b0; - store_2_axis_int_to_temp = 1'b0; - store_2_axis_temp_to_output = 1'b0; - - if (output_2_axis_tready_int_reg) begin - // input is ready - if (output_2_axis_tready | ~output_2_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_2_axis_tvalid_next = output_2_axis_tvalid_int; - store_2_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_2_axis_tvalid_next = output_2_axis_tvalid_int; - store_2_axis_int_to_temp = 1'b1; - end - end else if (output_2_axis_tready) begin - // input is not ready, but output is ready - output_2_axis_tvalid_next = temp_2_axis_tvalid_reg; - temp_2_axis_tvalid_next = 1'b0; - store_2_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_2_axis_tvalid_reg <= 1'b0; - output_2_axis_tready_int_reg <= 1'b0; - temp_2_axis_tvalid_reg <= 1'b0; - end else begin - output_2_axis_tvalid_reg <= output_2_axis_tvalid_next; - output_2_axis_tready_int_reg <= output_2_axis_tready_int_early; - temp_2_axis_tvalid_reg <= temp_2_axis_tvalid_next; - end - - // datapath - if (store_2_axis_int_to_output) begin - output_2_axis_tdata_reg <= output_2_axis_tdata_int; - output_2_axis_tkeep_reg <= output_2_axis_tkeep_int; - output_2_axis_tlast_reg <= output_2_axis_tlast_int; - output_2_axis_tid_reg <= output_2_axis_tid_int; - output_2_axis_tdest_reg <= output_2_axis_tdest_int; - output_2_axis_tuser_reg <= output_2_axis_tuser_int; - end else if (store_2_axis_temp_to_output) begin - output_2_axis_tdata_reg <= temp_2_axis_tdata_reg; - output_2_axis_tkeep_reg <= temp_2_axis_tkeep_reg; - output_2_axis_tlast_reg <= temp_2_axis_tlast_reg; - output_2_axis_tid_reg <= temp_2_axis_tid_reg; - output_2_axis_tdest_reg <= temp_2_axis_tdest_reg; - output_2_axis_tuser_reg <= temp_2_axis_tuser_reg; - end - - if (store_2_axis_int_to_temp) begin - temp_2_axis_tdata_reg <= output_2_axis_tdata_int; - temp_2_axis_tkeep_reg <= output_2_axis_tkeep_int; - temp_2_axis_tlast_reg <= output_2_axis_tlast_int; - temp_2_axis_tid_reg <= output_2_axis_tid_int; - temp_2_axis_tdest_reg <= output_2_axis_tdest_int; - temp_2_axis_tuser_reg <= output_2_axis_tuser_int; - end -end - -// output 3 datapath logic -reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_3_axis_tvalid_reg = 1'b0, output_3_axis_tvalid_next; -reg output_3_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_3_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_3_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_3_axis_tvalid_reg = 1'b0, temp_3_axis_tvalid_next; -reg temp_3_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_3_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_3_axis_tuser_reg = 1'b0; - -// datapath control -reg store_3_axis_int_to_output; -reg store_3_axis_int_to_temp; -reg store_3_axis_temp_to_output; - -assign output_3_axis_tdata = output_3_axis_tdata_reg; -assign output_3_axis_tkeep = KEEP_ENABLE ? output_3_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_3_axis_tvalid = output_3_axis_tvalid_reg; -assign output_3_axis_tlast = output_3_axis_tlast_reg; -assign output_3_axis_tid = ID_ENABLE ? output_3_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_3_axis_tdest = output_3_axis_tdest_reg; -assign output_3_axis_tuser = USER_ENABLE ? output_3_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_3_axis_tready_int_early = output_3_axis_tready | (~temp_3_axis_tvalid_reg & (~output_3_axis_tvalid_reg | ~output_3_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_3_axis_tvalid_next = output_3_axis_tvalid_reg; - temp_3_axis_tvalid_next = temp_3_axis_tvalid_reg; - - store_3_axis_int_to_output = 1'b0; - store_3_axis_int_to_temp = 1'b0; - store_3_axis_temp_to_output = 1'b0; - - if (output_3_axis_tready_int_reg) begin - // input is ready - if (output_3_axis_tready | ~output_3_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_3_axis_tvalid_next = output_3_axis_tvalid_int; - store_3_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_3_axis_tvalid_next = output_3_axis_tvalid_int; - store_3_axis_int_to_temp = 1'b1; - end - end else if (output_3_axis_tready) begin - // input is not ready, but output is ready - output_3_axis_tvalid_next = temp_3_axis_tvalid_reg; - temp_3_axis_tvalid_next = 1'b0; - store_3_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_3_axis_tvalid_reg <= 1'b0; - output_3_axis_tready_int_reg <= 1'b0; - temp_3_axis_tvalid_reg <= 1'b0; - end else begin - output_3_axis_tvalid_reg <= output_3_axis_tvalid_next; - output_3_axis_tready_int_reg <= output_3_axis_tready_int_early; - temp_3_axis_tvalid_reg <= temp_3_axis_tvalid_next; - end - - // datapath - if (store_3_axis_int_to_output) begin - output_3_axis_tdata_reg <= output_3_axis_tdata_int; - output_3_axis_tkeep_reg <= output_3_axis_tkeep_int; - output_3_axis_tlast_reg <= output_3_axis_tlast_int; - output_3_axis_tid_reg <= output_3_axis_tid_int; - output_3_axis_tdest_reg <= output_3_axis_tdest_int; - output_3_axis_tuser_reg <= output_3_axis_tuser_int; - end else if (store_3_axis_temp_to_output) begin - output_3_axis_tdata_reg <= temp_3_axis_tdata_reg; - output_3_axis_tkeep_reg <= temp_3_axis_tkeep_reg; - output_3_axis_tlast_reg <= temp_3_axis_tlast_reg; - output_3_axis_tid_reg <= temp_3_axis_tid_reg; - output_3_axis_tdest_reg <= temp_3_axis_tdest_reg; - output_3_axis_tuser_reg <= temp_3_axis_tuser_reg; - end - - if (store_3_axis_int_to_temp) begin - temp_3_axis_tdata_reg <= output_3_axis_tdata_int; - temp_3_axis_tkeep_reg <= output_3_axis_tkeep_int; - temp_3_axis_tlast_reg <= output_3_axis_tlast_int; - temp_3_axis_tid_reg <= output_3_axis_tid_int; - temp_3_axis_tdest_reg <= output_3_axis_tdest_int; - temp_3_axis_tuser_reg <= output_3_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py index de44bf771..f8663fbe7 100755 --- a/tb/test_axis_switch_4x4.py +++ b/tb/test_axis_switch_4x4.py @@ -28,12 +28,13 @@ import os import axis_ep -module = 'axis_switch_4x4' -testbench = 'test_%s' % module +module = 'axis_switch' +testbench = 'test_%s_4x4' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_register.v") srcs.append("../rtl/arbiter.v") srcs.append("../rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -45,6 +46,8 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + S_COUNT = 4 + M_COUNT = 4 DATA_WIDTH = 8 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) @@ -53,18 +56,11 @@ def bench(): DEST_WIDTH = 3 USER_ENABLE = 1 USER_WIDTH = 1 - OUT_0_BASE = 0 - OUT_0_TOP = 0 - OUT_0_CONNECT = 0xf - OUT_1_BASE = 1 - OUT_1_TOP = 1 - OUT_1_CONNECT = 0xf - OUT_2_BASE = 2 - OUT_2_TOP = 2 - OUT_2_CONNECT = 0xf - OUT_3_BASE = 3 - OUT_3_TOP = 3 - OUT_3_CONNECT = 0xf + M_BASE = [0, 1, 2, 3] + M_TOP = [0, 1, 2, 3] + M_CONNECT = [0b1111]*M_COUNT + S_REG_TYPE = 0 + M_REG_TYPE = 2 ARB_TYPE = "ROUND_ROBIN" LSB_PRIORITY = "HIGH" @@ -73,218 +69,98 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_0_axis_tvalid = Signal(bool(0)) - input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_1_axis_tvalid = Signal(bool(0)) - input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_2_axis_tvalid = Signal(bool(0)) - input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_3_axis_tvalid = Signal(bool(0)) - input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_0_axis_tready = Signal(bool(0)) - output_1_axis_tready = Signal(bool(0)) - output_2_axis_tready = Signal(bool(0)) - output_3_axis_tready = Signal(bool(0)) + s_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] + + s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list)) + s_axis_tkeep = ConcatSignal(*reversed(s_axis_tkeep_list)) + s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list)) + s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list)) + s_axis_tid = ConcatSignal(*reversed(s_axis_tid_list)) + s_axis_tdest = ConcatSignal(*reversed(s_axis_tdest_list)) + s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list)) + + m_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_axis_tready = ConcatSignal(*reversed(m_axis_tready_list)) # Outputs - input_0_axis_tready = Signal(bool(0)) - input_1_axis_tready = Signal(bool(0)) - input_2_axis_tready = Signal(bool(0)) - input_3_axis_tready = Signal(bool(0)) - output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_0_axis_tvalid = Signal(bool(0)) - output_0_axis_tlast = Signal(bool(0)) - output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_1_axis_tvalid = Signal(bool(0)) - output_1_axis_tlast = Signal(bool(0)) - output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_2_axis_tvalid = Signal(bool(0)) - output_2_axis_tlast = Signal(bool(0)) - output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_3_axis_tvalid = Signal(bool(0)) - output_3_axis_tlast = Signal(bool(0)) - output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(intbv(0)[S_COUNT:]) + + s_axis_tready_list = [s_axis_tready(i) for i in range(S_COUNT)] + + m_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_axis_tdata_list = [m_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_axis_tkeep_list = [m_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_axis_tvalid_list = [m_axis_tvalid(i) for i in range(M_COUNT)] + m_axis_tlast_list = [m_axis_tlast(i) for i in range(M_COUNT)] + m_axis_tid_list = [m_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_axis_tdest_list = [m_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_axis_tuser_list = [m_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] - source_0 = axis_ep.AXIStreamSource() + for k in range(S_COUNT): + s = axis_ep.AXIStreamSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tid=input_0_axis_tid, - tdest=input_0_axis_tdest, - tuser=input_0_axis_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = axis_ep.AXIStreamSource() + source_logic_list.append(s.create_logic( + clk, + rst, + tdata=s_axis_tdata_list[k], + tkeep=s_axis_tkeep_list[k], + tvalid=s_axis_tvalid_list[k], + tready=s_axis_tready_list[k], + tlast=s_axis_tlast_list[k], + tid=s_axis_tid_list[k], + tdest=s_axis_tdest_list[k], + tuser=s_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) - source_1_logic = source_1.create_logic( - clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tid=input_1_axis_tid, - tdest=input_1_axis_tdest, - tuser=input_1_axis_tuser, - pause=source_1_pause, - name='source_1' - ) + for k in range(M_COUNT): + s = axis_ep.AXIStreamSink() + p = Signal(bool(0)) - source_2 = axis_ep.AXIStreamSource() + sink_list.append(s) + sink_pause_list.append(p) - source_2_logic = source_2.create_logic( - clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tid=input_2_axis_tid, - tdest=input_2_axis_tdest, - tuser=input_2_axis_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = axis_ep.AXIStreamSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tid=input_3_axis_tid, - tdest=input_3_axis_tdest, - tuser=input_3_axis_tuser, - pause=source_3_pause, - name='source_3' - ) - - sink_0 = axis_ep.AXIStreamSink() - - sink_0_logic = sink_0.create_logic( - clk, - rst, - tdata=output_0_axis_tdata, - tkeep=output_0_axis_tkeep, - tvalid=output_0_axis_tvalid, - tready=output_0_axis_tready, - tlast=output_0_axis_tlast, - tid=output_0_axis_tid, - tdest=output_0_axis_tdest, - tuser=output_0_axis_tuser, - pause=sink_0_pause, - name='sink_0' - ) - - sink_1 = axis_ep.AXIStreamSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - tdata=output_1_axis_tdata, - tkeep=output_1_axis_tkeep, - tvalid=output_1_axis_tvalid, - tready=output_1_axis_tready, - tlast=output_1_axis_tlast, - tid=output_1_axis_tid, - tdest=output_1_axis_tdest, - tuser=output_1_axis_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = axis_ep.AXIStreamSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - tdata=output_2_axis_tdata, - tkeep=output_2_axis_tkeep, - tvalid=output_2_axis_tvalid, - tready=output_2_axis_tready, - tlast=output_2_axis_tlast, - tid=output_2_axis_tid, - tdest=output_2_axis_tdest, - tuser=output_2_axis_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = axis_ep.AXIStreamSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - tdata=output_3_axis_tdata, - tkeep=output_3_axis_tkeep, - tvalid=output_3_axis_tvalid, - tready=output_3_axis_tready, - tlast=output_3_axis_tlast, - tid=output_3_axis_tid, - tdest=output_3_axis_tdest, - tuser=output_3_axis_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + tdata=m_axis_tdata_list[k], + tkeep=m_axis_tkeep_list[k], + tvalid=m_axis_tvalid_list[k], + tready=m_axis_tready_list[k], + tlast=m_axis_tlast_list[k], + tid=m_axis_tid_list[k], + tdest=m_axis_tdest_list[k], + tuser=m_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -296,71 +172,23 @@ def bench(): rst=rst, current_test=current_test, - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tid=input_0_axis_tid, - input_0_axis_tdest=input_0_axis_tdest, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tid=input_1_axis_tid, - input_1_axis_tdest=input_1_axis_tdest, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tid=input_2_axis_tid, - input_2_axis_tdest=input_2_axis_tdest, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tid=input_3_axis_tid, - input_3_axis_tdest=input_3_axis_tdest, - input_3_axis_tuser=input_3_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, - output_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tkeep=output_0_axis_tkeep, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tready=output_0_axis_tready, - output_0_axis_tlast=output_0_axis_tlast, - output_0_axis_tid=output_0_axis_tid, - output_0_axis_tdest=output_0_axis_tdest, - output_0_axis_tuser=output_0_axis_tuser, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tkeep=output_1_axis_tkeep, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tready=output_1_axis_tready, - output_1_axis_tlast=output_1_axis_tlast, - output_1_axis_tid=output_1_axis_tid, - output_1_axis_tdest=output_1_axis_tdest, - output_1_axis_tuser=output_1_axis_tuser, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tkeep=output_2_axis_tkeep, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tready=output_2_axis_tready, - output_2_axis_tlast=output_2_axis_tlast, - output_2_axis_tid=output_2_axis_tid, - output_2_axis_tdest=output_2_axis_tdest, - output_2_axis_tuser=output_2_axis_tuser, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tkeep=output_3_axis_tkeep, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tready=output_3_axis_tready, - output_3_axis_tlast=output_3_axis_tlast, - output_3_axis_tid=output_3_axis_tid, - output_3_axis_tdest=output_3_axis_tdest, - output_3_axis_tuser=output_3_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -368,37 +196,37 @@ def bench(): clk.next = not clk def wait_normal(): - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + while s_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge def wait_pause_sink(): - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - sink_0_pause.next = True - sink_1_pause.next = True - sink_2_pause.next = True - sink_3_pause.next = True + while s_axis_tvalid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_0_pause.next = False - sink_1_pause.next = False - sink_2_pause.next = False - sink_3_pause.next = False + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False yield clk.posedge @instance @@ -424,32 +252,32 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0.send(test_frame0) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[0].send(test_frame0) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) yield clk.posedge yield clk.posedge yield wait() - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame1 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame2 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame3 @@ -465,32 +293,32 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=0) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0.send(test_frame0) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[0].send(test_frame0) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) yield clk.posedge yield clk.posedge yield wait() - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame3 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame2 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame1 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame0 @@ -506,32 +334,32 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0.send(test_frame0) - source_0.send(test_frame1) - source_0.send(test_frame2) - source_0.send(test_frame3) + source_list[0].send(test_frame0) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) + source_list[0].send(test_frame3) yield clk.posedge yield clk.posedge yield wait() - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame1 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame2 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame3 @@ -547,32 +375,32 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=0) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0.send(test_frame0) + source_list[0].send(test_frame0) yield clk.posedge - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) yield clk.posedge yield wait() - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_0.wait() - rx_frame1 = sink_0.recv() + yield sink_list[0].wait() + rx_frame1 = sink_list[0].recv() assert rx_frame1 == test_frame1 - yield sink_0.wait() - rx_frame2 = sink_0.recv() + yield sink_list[0].wait() + rx_frame2 = sink_list[0].recv() assert rx_frame2 == test_frame2 - yield sink_0.wait() - rx_frame3 = sink_0.recv() + yield sink_list[0].wait() + rx_frame3 = sink_list[0].recv() assert rx_frame3 == test_frame3 @@ -588,22 +416,22 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=5) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0.send(test_frame0) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[0].send(test_frame0) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) yield clk.posedge yield clk.posedge yield wait() - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame1 diff --git a/tb/test_axis_switch_4x4.v b/tb/test_axis_switch_4x4.v index 41edd7681..7dad71d0d 100644 --- a/tb/test_axis_switch_4x4.v +++ b/tb/test_axis_switch_4x4.v @@ -27,11 +27,13 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_switch_4x4 + * Testbench for axis_switch */ module test_axis_switch_4x4; // Parameters +parameter S_COUNT = 4; +parameter M_COUNT = 4; parameter DATA_WIDTH = 8; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); @@ -40,18 +42,11 @@ parameter ID_WIDTH = 8; parameter DEST_WIDTH = 3; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; -parameter OUT_0_BASE = 0; -parameter OUT_0_TOP = 0; -parameter OUT_0_CONNECT = 4'b1111; -parameter OUT_1_BASE = 1; -parameter OUT_1_TOP = 1; -parameter OUT_1_CONNECT = 4'b1111; -parameter OUT_2_BASE = 2; -parameter OUT_2_TOP = 2; -parameter OUT_2_CONNECT = 4'b1111; -parameter OUT_3_BASE = 3; -parameter OUT_3_TOP = 3; -parameter OUT_3_CONNECT = 4'b1111; +parameter M_BASE = {32'd3, 32'd2, 32'd1, 32'd0}; +parameter M_TOP = {32'd3, 32'd2, 32'd1, 32'd0}; +parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}}; +parameter S_REG_TYPE = 0; +parameter M_REG_TYPE = 2; parameter ARB_TYPE = "ROUND_ROBIN"; parameter LSB_PRIORITY = "HIGH"; @@ -60,72 +55,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; -reg input_0_axis_tvalid = 0; -reg input_0_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_0_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; -reg input_1_axis_tvalid = 0; -reg input_1_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_1_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; -reg input_2_axis_tvalid = 0; -reg input_2_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_2_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; -reg input_3_axis_tvalid = 0; -reg input_3_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_3_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; -reg output_0_axis_tready = 0; -reg output_1_axis_tready = 0; -reg output_2_axis_tready = 0; -reg output_3_axis_tready = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg [S_COUNT-1:0] s_axis_tvalid = 0; +reg [S_COUNT-1:0] s_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_axis_tuser = 0; +reg [M_COUNT-1:0] m_axis_tready = 0; // Outputs -wire input_0_axis_tready; -wire input_1_axis_tready; -wire input_2_axis_tready; -wire input_3_axis_tready; -wire [DATA_WIDTH-1:0] output_0_axis_tdata; -wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; -wire output_0_axis_tvalid; -wire output_0_axis_tlast; -wire [ID_WIDTH-1:0] output_0_axis_tid; -wire [DEST_WIDTH-1:0] output_0_axis_tdest; -wire [USER_WIDTH-1:0] output_0_axis_tuser; -wire [DATA_WIDTH-1:0] output_1_axis_tdata; -wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; -wire output_1_axis_tvalid; -wire output_1_axis_tlast; -wire [ID_WIDTH-1:0] output_1_axis_tid; -wire [DEST_WIDTH-1:0] output_1_axis_tdest; -wire [USER_WIDTH-1:0] output_1_axis_tuser; -wire [DATA_WIDTH-1:0] output_2_axis_tdata; -wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; -wire output_2_axis_tvalid; -wire output_2_axis_tlast; -wire [ID_WIDTH-1:0] output_2_axis_tid; -wire [DEST_WIDTH-1:0] output_2_axis_tdest; -wire [USER_WIDTH-1:0] output_2_axis_tuser; -wire [DATA_WIDTH-1:0] output_3_axis_tdata; -wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; -wire output_3_axis_tvalid; -wire output_3_axis_tlast; -wire [ID_WIDTH-1:0] output_3_axis_tid; -wire [DEST_WIDTH-1:0] output_3_axis_tdest; -wire [USER_WIDTH-1:0] output_3_axis_tuser; +wire [S_COUNT-1:0] s_axis_tready; +wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep; +wire [M_COUNT-1:0] m_axis_tvalid; +wire [M_COUNT-1:0] m_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -133,72 +80,24 @@ initial begin clk, rst, current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tid, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tid, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tid, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tid, - input_3_axis_tdest, - input_3_axis_tuser, - output_0_axis_tready, - output_1_axis_tready, - output_2_axis_tready, - output_3_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_0_axis_tid, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_1_axis_tid, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_2_axis_tid, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast, - output_3_axis_tid, - output_3_axis_tdest, - output_3_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -206,7 +105,7 @@ initial begin $dumpvars(0, test_axis_switch_4x4); end -axis_switch_4x4 #( +axis_switch #( .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), @@ -215,18 +114,11 @@ axis_switch_4x4 #( .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), .USER_WIDTH(USER_WIDTH), - .OUT_0_BASE(OUT_0_BASE), - .OUT_0_TOP(OUT_0_TOP), - .OUT_0_CONNECT(OUT_0_CONNECT), - .OUT_1_BASE(OUT_1_BASE), - .OUT_1_TOP(OUT_1_TOP), - .OUT_1_CONNECT(OUT_1_CONNECT), - .OUT_2_BASE(OUT_2_BASE), - .OUT_2_TOP(OUT_2_TOP), - .OUT_2_CONNECT(OUT_2_CONNECT), - .OUT_3_BASE(OUT_3_BASE), - .OUT_3_TOP(OUT_3_TOP), - .OUT_3_CONNECT(OUT_3_CONNECT), + .M_BASE(M_BASE), + .M_TOP(M_TOP), + .M_CONNECT(M_CONNECT), + .S_REG_TYPE(S_REG_TYPE), + .M_REG_TYPE(M_REG_TYPE), .ARB_TYPE(ARB_TYPE), .LSB_PRIORITY(LSB_PRIORITY) ) @@ -234,71 +126,23 @@ UUT ( .clk(clk), .rst(rst), // AXI inputs - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tkeep(input_0_axis_tkeep), - .input_0_axis_tvalid(input_0_axis_tvalid), - .input_0_axis_tready(input_0_axis_tready), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tid(input_0_axis_tid), - .input_0_axis_tdest(input_0_axis_tdest), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tkeep(input_1_axis_tkeep), - .input_1_axis_tvalid(input_1_axis_tvalid), - .input_1_axis_tready(input_1_axis_tready), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tid(input_1_axis_tid), - .input_1_axis_tdest(input_1_axis_tdest), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tkeep(input_2_axis_tkeep), - .input_2_axis_tvalid(input_2_axis_tvalid), - .input_2_axis_tready(input_2_axis_tready), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tid(input_2_axis_tid), - .input_2_axis_tdest(input_2_axis_tdest), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tkeep(input_3_axis_tkeep), - .input_3_axis_tvalid(input_3_axis_tvalid), - .input_3_axis_tready(input_3_axis_tready), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tid(input_3_axis_tid), - .input_3_axis_tdest(input_3_axis_tdest), - .input_3_axis_tuser(input_3_axis_tuser), - // AXI outputs - .output_0_axis_tdata(output_0_axis_tdata), - .output_0_axis_tkeep(output_0_axis_tkeep), - .output_0_axis_tvalid(output_0_axis_tvalid), - .output_0_axis_tready(output_0_axis_tready), - .output_0_axis_tlast(output_0_axis_tlast), - .output_0_axis_tid(output_0_axis_tid), - .output_0_axis_tdest(output_0_axis_tdest), - .output_0_axis_tuser(output_0_axis_tuser), - .output_1_axis_tdata(output_1_axis_tdata), - .output_1_axis_tkeep(output_1_axis_tkeep), - .output_1_axis_tvalid(output_1_axis_tvalid), - .output_1_axis_tready(output_1_axis_tready), - .output_1_axis_tlast(output_1_axis_tlast), - .output_1_axis_tid(output_1_axis_tid), - .output_1_axis_tdest(output_1_axis_tdest), - .output_1_axis_tuser(output_1_axis_tuser), - .output_2_axis_tdata(output_2_axis_tdata), - .output_2_axis_tkeep(output_2_axis_tkeep), - .output_2_axis_tvalid(output_2_axis_tvalid), - .output_2_axis_tready(output_2_axis_tready), - .output_2_axis_tlast(output_2_axis_tlast), - .output_2_axis_tid(output_2_axis_tid), - .output_2_axis_tdest(output_2_axis_tdest), - .output_2_axis_tuser(output_2_axis_tuser), - .output_3_axis_tdata(output_3_axis_tdata), - .output_3_axis_tkeep(output_3_axis_tkeep), - .output_3_axis_tvalid(output_3_axis_tvalid), - .output_3_axis_tready(output_3_axis_tready), - .output_3_axis_tlast(output_3_axis_tlast), - .output_3_axis_tid(output_3_axis_tid), - .output_3_axis_tdest(output_3_axis_tdest), - .output_3_axis_tuser(output_3_axis_tuser) + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule diff --git a/tb/test_axis_switch_4x4_64.py b/tb/test_axis_switch_4x4_64.py index 29baad888..41f709699 100755 --- a/tb/test_axis_switch_4x4_64.py +++ b/tb/test_axis_switch_4x4_64.py @@ -28,12 +28,13 @@ import os import axis_ep -module = 'axis_switch_4x4' -testbench = 'test_%s_64' % module +module = 'axis_switch' +testbench = 'test_%s_4x4_64' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_register.v") srcs.append("../rtl/arbiter.v") srcs.append("../rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -45,6 +46,8 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + S_COUNT = 4 + M_COUNT = 4 DATA_WIDTH = 64 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) @@ -73,218 +76,98 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_0_axis_tvalid = Signal(bool(0)) - input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_1_axis_tvalid = Signal(bool(0)) - input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_2_axis_tvalid = Signal(bool(0)) - input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_3_axis_tvalid = Signal(bool(0)) - input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_0_axis_tready = Signal(bool(0)) - output_1_axis_tready = Signal(bool(0)) - output_2_axis_tready = Signal(bool(0)) - output_3_axis_tready = Signal(bool(0)) + s_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] + + s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list)) + s_axis_tkeep = ConcatSignal(*reversed(s_axis_tkeep_list)) + s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list)) + s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list)) + s_axis_tid = ConcatSignal(*reversed(s_axis_tid_list)) + s_axis_tdest = ConcatSignal(*reversed(s_axis_tdest_list)) + s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list)) + + m_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_axis_tready = ConcatSignal(*reversed(m_axis_tready_list)) # Outputs - input_0_axis_tready = Signal(bool(0)) - input_1_axis_tready = Signal(bool(0)) - input_2_axis_tready = Signal(bool(0)) - input_3_axis_tready = Signal(bool(0)) - output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_0_axis_tvalid = Signal(bool(0)) - output_0_axis_tlast = Signal(bool(0)) - output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_1_axis_tvalid = Signal(bool(0)) - output_1_axis_tlast = Signal(bool(0)) - output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_2_axis_tvalid = Signal(bool(0)) - output_2_axis_tlast = Signal(bool(0)) - output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_3_axis_tvalid = Signal(bool(0)) - output_3_axis_tlast = Signal(bool(0)) - output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(intbv(0)[S_COUNT:]) + + s_axis_tready_list = [s_axis_tready(i) for i in range(S_COUNT)] + + m_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_axis_tdata_list = [m_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_axis_tkeep_list = [m_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_axis_tvalid_list = [m_axis_tvalid(i) for i in range(M_COUNT)] + m_axis_tlast_list = [m_axis_tlast(i) for i in range(M_COUNT)] + m_axis_tid_list = [m_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_axis_tdest_list = [m_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_axis_tuser_list = [m_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] - source_0 = axis_ep.AXIStreamSource() + for k in range(S_COUNT): + s = axis_ep.AXIStreamSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tid=input_0_axis_tid, - tdest=input_0_axis_tdest, - tuser=input_0_axis_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = axis_ep.AXIStreamSource() + source_logic_list.append(s.create_logic( + clk, + rst, + tdata=s_axis_tdata_list[k], + tkeep=s_axis_tkeep_list[k], + tvalid=s_axis_tvalid_list[k], + tready=s_axis_tready_list[k], + tlast=s_axis_tlast_list[k], + tid=s_axis_tid_list[k], + tdest=s_axis_tdest_list[k], + tuser=s_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) - source_1_logic = source_1.create_logic( - clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tid=input_1_axis_tid, - tdest=input_1_axis_tdest, - tuser=input_1_axis_tuser, - pause=source_1_pause, - name='source_1' - ) + for k in range(M_COUNT): + s = axis_ep.AXIStreamSink() + p = Signal(bool(0)) - source_2 = axis_ep.AXIStreamSource() + sink_list.append(s) + sink_pause_list.append(p) - source_2_logic = source_2.create_logic( - clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tid=input_2_axis_tid, - tdest=input_2_axis_tdest, - tuser=input_2_axis_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = axis_ep.AXIStreamSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tid=input_3_axis_tid, - tdest=input_3_axis_tdest, - tuser=input_3_axis_tuser, - pause=source_3_pause, - name='source_3' - ) - - sink_0 = axis_ep.AXIStreamSink() - - sink_0_logic = sink_0.create_logic( - clk, - rst, - tdata=output_0_axis_tdata, - tkeep=output_0_axis_tkeep, - tvalid=output_0_axis_tvalid, - tready=output_0_axis_tready, - tlast=output_0_axis_tlast, - tid=output_0_axis_tid, - tdest=output_0_axis_tdest, - tuser=output_0_axis_tuser, - pause=sink_0_pause, - name='sink_0' - ) - - sink_1 = axis_ep.AXIStreamSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - tdata=output_1_axis_tdata, - tkeep=output_1_axis_tkeep, - tvalid=output_1_axis_tvalid, - tready=output_1_axis_tready, - tlast=output_1_axis_tlast, - tid=output_1_axis_tid, - tdest=output_1_axis_tdest, - tuser=output_1_axis_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = axis_ep.AXIStreamSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - tdata=output_2_axis_tdata, - tkeep=output_2_axis_tkeep, - tvalid=output_2_axis_tvalid, - tready=output_2_axis_tready, - tlast=output_2_axis_tlast, - tid=output_2_axis_tid, - tdest=output_2_axis_tdest, - tuser=output_2_axis_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = axis_ep.AXIStreamSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - tdata=output_3_axis_tdata, - tkeep=output_3_axis_tkeep, - tvalid=output_3_axis_tvalid, - tready=output_3_axis_tready, - tlast=output_3_axis_tlast, - tid=output_3_axis_tid, - tdest=output_3_axis_tdest, - tuser=output_3_axis_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + tdata=m_axis_tdata_list[k], + tkeep=m_axis_tkeep_list[k], + tvalid=m_axis_tvalid_list[k], + tready=m_axis_tready_list[k], + tlast=m_axis_tlast_list[k], + tid=m_axis_tid_list[k], + tdest=m_axis_tdest_list[k], + tuser=m_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -296,71 +179,23 @@ def bench(): rst=rst, current_test=current_test, - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tid=input_0_axis_tid, - input_0_axis_tdest=input_0_axis_tdest, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tid=input_1_axis_tid, - input_1_axis_tdest=input_1_axis_tdest, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tid=input_2_axis_tid, - input_2_axis_tdest=input_2_axis_tdest, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tid=input_3_axis_tid, - input_3_axis_tdest=input_3_axis_tdest, - input_3_axis_tuser=input_3_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, - output_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tkeep=output_0_axis_tkeep, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tready=output_0_axis_tready, - output_0_axis_tlast=output_0_axis_tlast, - output_0_axis_tid=output_0_axis_tid, - output_0_axis_tdest=output_0_axis_tdest, - output_0_axis_tuser=output_0_axis_tuser, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tkeep=output_1_axis_tkeep, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tready=output_1_axis_tready, - output_1_axis_tlast=output_1_axis_tlast, - output_1_axis_tid=output_1_axis_tid, - output_1_axis_tdest=output_1_axis_tdest, - output_1_axis_tuser=output_1_axis_tuser, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tkeep=output_2_axis_tkeep, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tready=output_2_axis_tready, - output_2_axis_tlast=output_2_axis_tlast, - output_2_axis_tid=output_2_axis_tid, - output_2_axis_tdest=output_2_axis_tdest, - output_2_axis_tuser=output_2_axis_tuser, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tkeep=output_3_axis_tkeep, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tready=output_3_axis_tready, - output_3_axis_tlast=output_3_axis_tlast, - output_3_axis_tid=output_3_axis_tid, - output_3_axis_tdest=output_3_axis_tdest, - output_3_axis_tuser=output_3_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -368,37 +203,37 @@ def bench(): clk.next = not clk def wait_normal(): - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + while s_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge def wait_pause_sink(): - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - sink_0_pause.next = True - sink_1_pause.next = True - sink_2_pause.next = True - sink_3_pause.next = True + while s_axis_tvalid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_0_pause.next = False - sink_1_pause.next = False - sink_2_pause.next = False - sink_3_pause.next = False + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False yield clk.posedge @instance @@ -424,32 +259,32 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0.send(test_frame0) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[0].send(test_frame0) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) yield clk.posedge yield clk.posedge yield wait() - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame1 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame2 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame3 @@ -465,32 +300,32 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=0) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0.send(test_frame0) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[0].send(test_frame0) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) yield clk.posedge yield clk.posedge yield wait() - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame3 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame2 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame1 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame0 @@ -506,32 +341,32 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=3) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0.send(test_frame0) - source_0.send(test_frame1) - source_0.send(test_frame2) - source_0.send(test_frame3) + source_list[0].send(test_frame0) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) + source_list[0].send(test_frame3) yield clk.posedge yield clk.posedge yield wait() - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame1 - yield sink_2.wait() - rx_frame2 = sink_2.recv() + yield sink_list[2].wait() + rx_frame2 = sink_list[2].recv() assert rx_frame2 == test_frame2 - yield sink_3.wait() - rx_frame3 = sink_3.recv() + yield sink_list[3].wait() + rx_frame3 = sink_list[3].recv() assert rx_frame3 == test_frame3 @@ -547,32 +382,32 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=0) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0.send(test_frame0) + source_list[0].send(test_frame0) yield clk.posedge - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) yield clk.posedge yield wait() - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_0.wait() - rx_frame1 = sink_0.recv() + yield sink_list[0].wait() + rx_frame1 = sink_list[0].recv() assert rx_frame1 == test_frame1 - yield sink_0.wait() - rx_frame2 = sink_0.recv() + yield sink_list[0].wait() + rx_frame2 = sink_list[0].recv() assert rx_frame2 == test_frame2 - yield sink_0.wait() - rx_frame3 = sink_0.recv() + yield sink_list[0].wait() + rx_frame3 = sink_list[0].recv() assert rx_frame3 == test_frame3 @@ -588,22 +423,22 @@ def bench(): test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=5) for wait in wait_normal, wait_pause_source, wait_pause_sink: - source_0.send(test_frame0) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_3.send(test_frame3) + source_list[0].send(test_frame0) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[3].send(test_frame3) yield clk.posedge yield clk.posedge yield wait() - yield sink_0.wait() - rx_frame0 = sink_0.recv() + yield sink_list[0].wait() + rx_frame0 = sink_list[0].recv() assert rx_frame0 == test_frame0 - yield sink_1.wait() - rx_frame1 = sink_1.recv() + yield sink_list[1].wait() + rx_frame1 = sink_list[1].recv() assert rx_frame1 == test_frame1 diff --git a/tb/test_axis_switch_4x4_64.v b/tb/test_axis_switch_4x4_64.v index cc8ed02da..7f43ac26f 100644 --- a/tb/test_axis_switch_4x4_64.v +++ b/tb/test_axis_switch_4x4_64.v @@ -27,11 +27,13 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_switch_4x4 + * Testbench for axis_switch */ module test_axis_switch_4x4_64; // Parameters +parameter S_COUNT = 4; +parameter M_COUNT = 4; parameter DATA_WIDTH = 64; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); @@ -40,18 +42,11 @@ parameter ID_WIDTH = 8; parameter DEST_WIDTH = 3; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; -parameter OUT_0_BASE = 0; -parameter OUT_0_TOP = 0; -parameter OUT_0_CONNECT = 4'b1111; -parameter OUT_1_BASE = 1; -parameter OUT_1_TOP = 1; -parameter OUT_1_CONNECT = 4'b1111; -parameter OUT_2_BASE = 2; -parameter OUT_2_TOP = 2; -parameter OUT_2_CONNECT = 4'b1111; -parameter OUT_3_BASE = 3; -parameter OUT_3_TOP = 3; -parameter OUT_3_CONNECT = 4'b1111; +parameter M_BASE = {32'd3, 32'd2, 32'd1, 32'd0}; +parameter M_TOP = {32'd3, 32'd2, 32'd1, 32'd0}; +parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}}; +parameter S_REG_TYPE = 0; +parameter M_REG_TYPE = 2; parameter ARB_TYPE = "ROUND_ROBIN"; parameter LSB_PRIORITY = "HIGH"; @@ -60,72 +55,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; -reg input_0_axis_tvalid = 0; -reg input_0_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_0_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; -reg input_1_axis_tvalid = 0; -reg input_1_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_1_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; -reg input_2_axis_tvalid = 0; -reg input_2_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_2_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; -reg input_3_axis_tvalid = 0; -reg input_3_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_3_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; -reg output_0_axis_tready = 0; -reg output_1_axis_tready = 0; -reg output_2_axis_tready = 0; -reg output_3_axis_tready = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg [S_COUNT-1:0] s_axis_tvalid = 0; +reg [S_COUNT-1:0] s_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_axis_tuser = 0; +reg [M_COUNT-1:0] m_axis_tready = 0; // Outputs -wire input_0_axis_tready; -wire input_1_axis_tready; -wire input_2_axis_tready; -wire input_3_axis_tready; -wire [DATA_WIDTH-1:0] output_0_axis_tdata; -wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; -wire output_0_axis_tvalid; -wire output_0_axis_tlast; -wire [ID_WIDTH-1:0] output_0_axis_tid; -wire [DEST_WIDTH-1:0] output_0_axis_tdest; -wire [USER_WIDTH-1:0] output_0_axis_tuser; -wire [DATA_WIDTH-1:0] output_1_axis_tdata; -wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; -wire output_1_axis_tvalid; -wire output_1_axis_tlast; -wire [ID_WIDTH-1:0] output_1_axis_tid; -wire [DEST_WIDTH-1:0] output_1_axis_tdest; -wire [USER_WIDTH-1:0] output_1_axis_tuser; -wire [DATA_WIDTH-1:0] output_2_axis_tdata; -wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; -wire output_2_axis_tvalid; -wire output_2_axis_tlast; -wire [ID_WIDTH-1:0] output_2_axis_tid; -wire [DEST_WIDTH-1:0] output_2_axis_tdest; -wire [USER_WIDTH-1:0] output_2_axis_tuser; -wire [DATA_WIDTH-1:0] output_3_axis_tdata; -wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; -wire output_3_axis_tvalid; -wire output_3_axis_tlast; -wire [ID_WIDTH-1:0] output_3_axis_tid; -wire [DEST_WIDTH-1:0] output_3_axis_tdest; -wire [USER_WIDTH-1:0] output_3_axis_tuser; +wire [S_COUNT-1:0] s_axis_tready; +wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep; +wire [M_COUNT-1:0] m_axis_tvalid; +wire [M_COUNT-1:0] m_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -133,72 +80,24 @@ initial begin clk, rst, current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tid, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tid, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tid, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tid, - input_3_axis_tdest, - input_3_axis_tuser, - output_0_axis_tready, - output_1_axis_tready, - output_2_axis_tready, - output_3_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_0_axis_tid, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_1_axis_tid, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_2_axis_tid, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast, - output_3_axis_tid, - output_3_axis_tdest, - output_3_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -206,7 +105,7 @@ initial begin $dumpvars(0, test_axis_switch_4x4_64); end -axis_switch_4x4 #( +axis_switch #( .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), @@ -215,18 +114,11 @@ axis_switch_4x4 #( .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), .USER_WIDTH(USER_WIDTH), - .OUT_0_BASE(OUT_0_BASE), - .OUT_0_TOP(OUT_0_TOP), - .OUT_0_CONNECT(OUT_0_CONNECT), - .OUT_1_BASE(OUT_1_BASE), - .OUT_1_TOP(OUT_1_TOP), - .OUT_1_CONNECT(OUT_1_CONNECT), - .OUT_2_BASE(OUT_2_BASE), - .OUT_2_TOP(OUT_2_TOP), - .OUT_2_CONNECT(OUT_2_CONNECT), - .OUT_3_BASE(OUT_3_BASE), - .OUT_3_TOP(OUT_3_TOP), - .OUT_3_CONNECT(OUT_3_CONNECT), + .M_BASE(M_BASE), + .M_TOP(M_TOP), + .M_CONNECT(M_CONNECT), + .S_REG_TYPE(S_REG_TYPE), + .M_REG_TYPE(M_REG_TYPE), .ARB_TYPE(ARB_TYPE), .LSB_PRIORITY(LSB_PRIORITY) ) @@ -234,71 +126,23 @@ UUT ( .clk(clk), .rst(rst), // AXI inputs - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tkeep(input_0_axis_tkeep), - .input_0_axis_tvalid(input_0_axis_tvalid), - .input_0_axis_tready(input_0_axis_tready), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tid(input_0_axis_tid), - .input_0_axis_tdest(input_0_axis_tdest), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tkeep(input_1_axis_tkeep), - .input_1_axis_tvalid(input_1_axis_tvalid), - .input_1_axis_tready(input_1_axis_tready), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tid(input_1_axis_tid), - .input_1_axis_tdest(input_1_axis_tdest), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tkeep(input_2_axis_tkeep), - .input_2_axis_tvalid(input_2_axis_tvalid), - .input_2_axis_tready(input_2_axis_tready), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tid(input_2_axis_tid), - .input_2_axis_tdest(input_2_axis_tdest), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tkeep(input_3_axis_tkeep), - .input_3_axis_tvalid(input_3_axis_tvalid), - .input_3_axis_tready(input_3_axis_tready), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tid(input_3_axis_tid), - .input_3_axis_tdest(input_3_axis_tdest), - .input_3_axis_tuser(input_3_axis_tuser), - // AXI outputs - .output_0_axis_tdata(output_0_axis_tdata), - .output_0_axis_tkeep(output_0_axis_tkeep), - .output_0_axis_tvalid(output_0_axis_tvalid), - .output_0_axis_tready(output_0_axis_tready), - .output_0_axis_tlast(output_0_axis_tlast), - .output_0_axis_tid(output_0_axis_tid), - .output_0_axis_tdest(output_0_axis_tdest), - .output_0_axis_tuser(output_0_axis_tuser), - .output_1_axis_tdata(output_1_axis_tdata), - .output_1_axis_tkeep(output_1_axis_tkeep), - .output_1_axis_tvalid(output_1_axis_tvalid), - .output_1_axis_tready(output_1_axis_tready), - .output_1_axis_tlast(output_1_axis_tlast), - .output_1_axis_tid(output_1_axis_tid), - .output_1_axis_tdest(output_1_axis_tdest), - .output_1_axis_tuser(output_1_axis_tuser), - .output_2_axis_tdata(output_2_axis_tdata), - .output_2_axis_tkeep(output_2_axis_tkeep), - .output_2_axis_tvalid(output_2_axis_tvalid), - .output_2_axis_tready(output_2_axis_tready), - .output_2_axis_tlast(output_2_axis_tlast), - .output_2_axis_tid(output_2_axis_tid), - .output_2_axis_tdest(output_2_axis_tdest), - .output_2_axis_tuser(output_2_axis_tuser), - .output_3_axis_tdata(output_3_axis_tdata), - .output_3_axis_tkeep(output_3_axis_tkeep), - .output_3_axis_tvalid(output_3_axis_tvalid), - .output_3_axis_tready(output_3_axis_tready), - .output_3_axis_tlast(output_3_axis_tlast), - .output_3_axis_tid(output_3_axis_tid), - .output_3_axis_tdest(output_3_axis_tdest), - .output_3_axis_tuser(output_3_axis_tuser) + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule From fc6c07e5f973c100350c456f8a755bc592437e29 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 17:07:22 -0700 Subject: [PATCH 421/617] Convert generated frame joiner to verilog parametrized frame joiner --- rtl/axis_frame_join.py | 414 ----------------------------------- rtl/axis_frame_join.v | 323 +++++++++++++++++++++++++++ rtl/axis_frame_join_4.v | 404 ---------------------------------- tb/test_axis_frame_join_4.py | 298 ++++++++++--------------- tb/test_axis_frame_join_4.v | 113 +++------- 5 files changed, 478 insertions(+), 1074 deletions(-) delete mode 100755 rtl/axis_frame_join.py create mode 100644 rtl/axis_frame_join.v delete mode 100644 rtl/axis_frame_join_4.v diff --git a/rtl/axis_frame_join.py b/rtl/axis_frame_join.py deleted file mode 100755 index 8522397e7..000000000 --- a/rtl/axis_frame_join.py +++ /dev/null @@ -1,414 +0,0 @@ -#!/usr/bin/env python -""" -Generates an AXI Stream frame join module with a specific number of input ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "axis_frame_join_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port AXI Stream frame joiner {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream {{n}} port frame joiner - */ -module {{name}} # -( - parameter TAG_ENABLE = 1, - parameter TAG_WIDTH = 16 -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ -{%- for p in ports %} - input wire [7:0] input_{{p}}_axis_tdata, - input wire input_{{p}}_axis_tvalid, - output wire input_{{p}}_axis_tready, - input wire input_{{p}}_axis_tlast, - input wire input_{{p}}_axis_tuser, -{% endfor %} - /* - * AXI output - */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Configuration - */ - input wire [TAG_WIDTH-1:0] tag, - - /* - * Status signals - */ - output wire busy -); - -localparam TAG_BYTE_WIDTH = (TAG_WIDTH + 7) / 8; - -// state register -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_WRITE_TAG = 2'd1, - STATE_TRANSFER = 2'd2; - -reg [1:0] state_reg = STATE_IDLE, state_next; - -reg [2:0] frame_ptr_reg = 3'd0, frame_ptr_next; -reg [{{w-1}}:0] port_sel_reg = {{w}}'d0, port_sel_next; - -reg busy_reg = 1'b0, busy_next; - -reg [7:0] input_tdata; -reg input_tvalid; -reg input_tlast; -reg input_tuser; - -reg output_tuser_reg = 1'b0, output_tuser_next; -{% for p in ports %} -reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; -{%- endfor %} - -// internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; -{% for p in ports %} -assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; -{%- endfor %} - -assign busy = busy_reg; - -always @* begin - // input port mux - case (port_sel_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - input_tdata = input_{{p}}_axis_tdata; - input_tvalid = input_{{p}}_axis_tvalid; - input_tlast = input_{{p}}_axis_tlast; - input_tuser = input_{{p}}_axis_tuser; - end -{%- endfor %} - endcase -end - -integer offset, i; - -always @* begin - state_next = STATE_IDLE; - - frame_ptr_next = frame_ptr_reg; - port_sel_next = port_sel_reg; -{% for p in ports %} - input_{{p}}_axis_tready_next = 1'b0; -{%- endfor %} - - output_axis_tdata_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; - - output_tuser_next = output_tuser_reg; - - case (state_reg) - STATE_IDLE: begin - // idle state - wait for data - frame_ptr_next = 3'd0; - port_sel_next = {{w}}'d0; - output_tuser_next = 1'b0; - - if (TAG_ENABLE) begin - // next cycle if started will send tag, so do not enable input - input_0_axis_tready_next = 1'b0; - end else begin - // next cycle if started will send data, so enable input - input_0_axis_tready_next = output_axis_tready_int_early; - end - - if (input_0_axis_tvalid) begin - // input 0 valid; start transferring data - if (TAG_ENABLE) begin - // tag enabled, so transmit it - if (output_axis_tready_int_reg) begin - // output is ready, so short-circuit first tag byte - frame_ptr_next = 3'd1; - output_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; - output_axis_tvalid_int = 1'b1; - end - state_next = STATE_WRITE_TAG; - end else begin - // tag disabled, so transmit data - if (output_axis_tready_int_reg) begin - // output is ready, so short-circuit first data byte - output_axis_tdata_int = input_0_axis_tdata; - output_axis_tvalid_int = 1'b1; - end - state_next = STATE_TRANSFER; - end - end else begin - state_next = STATE_IDLE; - end - end - STATE_WRITE_TAG: begin - // write tag data - if (output_axis_tready_int_reg) begin - // output ready, so send tag byte - state_next = STATE_WRITE_TAG; - frame_ptr_next = frame_ptr_reg + 1; - output_axis_tvalid_int = 1'b1; - - offset = 0; - if (TAG_ENABLE) begin - for (i = TAG_BYTE_WIDTH-1; i >= 0; i = i - 1) begin - if (frame_ptr_reg == offset) begin - output_axis_tdata_int = tag[i*8 +: 8]; - end - offset = offset + 1; - end - end - if (frame_ptr_reg == offset-1) begin - input_0_axis_tready_next = output_axis_tready_int_early; - state_next = STATE_TRANSFER; - end - end else begin - state_next = STATE_WRITE_TAG; - end - end - STATE_TRANSFER: begin - // transfer input data - - // set ready for current input - case (port_sel_reg) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early; -{%- endfor %} - endcase - - if (input_tvalid & output_axis_tready_int_reg) begin - // output ready, transfer byte - state_next = STATE_TRANSFER; - output_axis_tdata_int = input_tdata; - output_axis_tvalid_int = input_tvalid; - - if (input_tlast) begin - // last flag received, switch to next port - port_sel_next = port_sel_reg + 1; - // save tuser - assert tuser out if ANY tuser asserts received - output_tuser_next = output_tuser_next | input_tuser; - // disable input -{%- for p in ports %} - input_{{p}}_axis_tready_next = 1'b0; -{%- endfor %} - - if (port_sel_reg == {{w}}'d{{n-1}}) begin - // last port - send tlast and tuser and revert to idle - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = output_tuser_next; - state_next = STATE_IDLE; - end else begin - // otherwise, disable enable next port - case (port_sel_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early; -{%- endfor %} - endcase - end - end - end else begin - state_next = STATE_TRANSFER; - end - end - endcase -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - frame_ptr_reg <= 3'd0; - port_sel_reg <= {{w}}'d0; -{%- for p in ports %} - input_{{p}}_axis_tready_reg <= 1'b0; -{%- endfor %} - output_tuser_reg <= 1'b0; - busy_reg <= 1'b0; - end else begin - state_reg <= state_next; - - frame_ptr_reg <= frame_ptr_next; - - port_sel_reg <= port_sel_next; -{% for p in ports %} - input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; -{%- endfor %} - - output_tuser_reg <= output_tuser_next; - - busy_reg <= state_next != STATE_IDLE; - end -end - -// output datapath logic -reg [7:0] output_axis_tdata_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; - -reg [7:0] temp_axis_tdata_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_frame_join.v b/rtl/axis_frame_join.v new file mode 100644 index 000000000..e5cd29f44 --- /dev/null +++ b/rtl/axis_frame_join.v @@ -0,0 +1,323 @@ +/* + +Copyright (c) 2014-2018 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 frame joiner + */ +module axis_frame_join # +( + parameter DATA_WIDTH = 8, + parameter S_COUNT = 4, + parameter TAG_ENABLE = 1, + parameter TAG_WIDTH = 16 +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ + input wire [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_COUNT-1:0] s_axis_tvalid, + output wire [S_COUNT-1:0] s_axis_tready, + input wire [S_COUNT-1:0] s_axis_tlast, + input wire [S_COUNT-1:0] s_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, + + /* + * Configuration + */ + input wire [TAG_WIDTH-1:0] tag, + + /* + * Status signals + */ + output wire busy +); + +parameter CL_S_COUNT = $clog2(S_COUNT); + +parameter TAG_WORD_WIDTH = (TAG_WIDTH + DATA_WIDTH - 1) / DATA_WIDTH; +parameter CL_TAG_WORD_WIDTH = $clog2(TAG_WORD_WIDTH); + +// state register +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_WRITE_TAG = 2'd1, + STATE_TRANSFER = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [CL_TAG_WORD_WIDTH-1:0] frame_ptr_reg = {CL_TAG_WORD_WIDTH{1'b0}}, frame_ptr_next; +reg [CL_S_COUNT-1:0] port_sel_reg = {CL_S_COUNT{1'b0}}, port_sel_next; + +reg busy_reg = 1'b0, busy_next; + +reg output_tuser_reg = 1'b0, output_tuser_next; + +reg [S_COUNT-1:0] s_axis_tready_reg = {S_COUNT{1'b0}}, s_axis_tready_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; + +assign s_axis_tready = s_axis_tready_reg; + +assign busy = busy_reg; + +wire [DATA_WIDTH-1:0] input_tdata = s_axis_tdata[port_sel_reg*DATA_WIDTH +: DATA_WIDTH]; +wire input_tvalid = s_axis_tvalid[port_sel_reg]; +wire input_tlast = s_axis_tlast[port_sel_reg]; +wire input_tuser = s_axis_tuser[port_sel_reg]; + +always @* begin + state_next = STATE_IDLE; + + frame_ptr_next = frame_ptr_reg; + port_sel_next = port_sel_reg; + + s_axis_tready_next = {S_COUNT{1'b0}}; + + m_axis_tdata_int = 8'd0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; + + output_tuser_next = output_tuser_reg; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = {CL_TAG_WORD_WIDTH{1'b0}}; + port_sel_next = {CL_S_COUNT{1'b0}}; + output_tuser_next = 1'b0; + + if (TAG_ENABLE) begin + // next cycle if started will send tag, so do not enable input + s_axis_tready_next = 1'b0; + end else begin + // next cycle if started will send data, so enable input + s_axis_tready_next = m_axis_tready_int_early; + end + + if (s_axis_tvalid) begin + // input 0 valid; start transferring data + if (TAG_ENABLE) begin + // tag enabled, so transmit it + if (m_axis_tready_int_reg) begin + // output is ready, so short-circuit first tag word + frame_ptr_next = 1; + m_axis_tdata_int = tag; + m_axis_tvalid_int = 1'b1; + end + state_next = STATE_WRITE_TAG; + end else begin + // tag disabled, so transmit data + if (m_axis_tready_int_reg) begin + // output is ready, so short-circuit first data word + m_axis_tdata_int = s_axis_tdata; + m_axis_tvalid_int = 1'b1; + end + state_next = STATE_TRANSFER; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_WRITE_TAG: begin + // write tag data + if (m_axis_tready_int_reg) begin + // output ready, so send tag word + state_next = STATE_WRITE_TAG; + frame_ptr_next = frame_ptr_reg + 1; + m_axis_tvalid_int = 1'b1; + + m_axis_tdata_int = tag >> frame_ptr_reg*DATA_WIDTH; + if (frame_ptr_reg == TAG_WORD_WIDTH-1) begin + s_axis_tready_next = m_axis_tready_int_early << 0; + state_next = STATE_TRANSFER; + end + end else begin + state_next = STATE_WRITE_TAG; + end + end + STATE_TRANSFER: begin + // transfer input data + + // set ready for current input + s_axis_tready_next = m_axis_tready_int_early << port_sel_reg; + + if (input_tvalid && m_axis_tready_int_reg) begin + // output ready, transfer byte + state_next = STATE_TRANSFER; + m_axis_tdata_int = input_tdata; + m_axis_tvalid_int = input_tvalid; + + if (input_tlast) begin + // last flag received, switch to next port + port_sel_next = port_sel_reg + 1; + // save tuser - assert tuser out if ANY tuser asserts received + output_tuser_next = output_tuser_next | input_tuser; + // disable input + s_axis_tready_next = {S_COUNT{1'b0}}; + + if (S_COUNT == 1 || port_sel_reg == S_COUNT-1) begin + // last port - send tlast and tuser and revert to idle + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = output_tuser_next; + state_next = STATE_IDLE; + end else begin + // otherwise, disable enable next port + s_axis_tready_next = m_axis_tready_int_early << port_sel_next; + end + end + end else begin + state_next = STATE_TRANSFER; + end + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + frame_ptr_reg <= {CL_TAG_WORD_WIDTH{1'b0}}; + port_sel_reg <= {CL_S_COUNT{1'b0}}; + s_axis_tready_reg <= {S_COUNT{1'b0}}; + output_tuser_reg <= 1'b0; + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + port_sel_reg <= port_sel_next; + + s_axis_tready_reg <= s_axis_tready_next; + + output_tuser_reg <= output_tuser_next; + + busy_reg <= state_next != STATE_IDLE; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (m_axis_tready_int_reg) begin + // input is ready + if (m_axis_tready || !m_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_axis_tready) begin + // input is not ready, but output is ready + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; + end else begin + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/axis_frame_join_4.v b/rtl/axis_frame_join_4.v deleted file mode 100644 index 5aabd7035..000000000 --- a/rtl/axis_frame_join_4.v +++ /dev/null @@ -1,404 +0,0 @@ -/* - -Copyright (c) 2014-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream 4 port frame joiner - */ -module axis_frame_join_4 # -( - parameter TAG_ENABLE = 1, - parameter TAG_WIDTH = 16 -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ - input wire [7:0] input_0_axis_tdata, - input wire input_0_axis_tvalid, - output wire input_0_axis_tready, - input wire input_0_axis_tlast, - input wire input_0_axis_tuser, - - input wire [7:0] input_1_axis_tdata, - input wire input_1_axis_tvalid, - output wire input_1_axis_tready, - input wire input_1_axis_tlast, - input wire input_1_axis_tuser, - - input wire [7:0] input_2_axis_tdata, - input wire input_2_axis_tvalid, - output wire input_2_axis_tready, - input wire input_2_axis_tlast, - input wire input_2_axis_tuser, - - input wire [7:0] input_3_axis_tdata, - input wire input_3_axis_tvalid, - output wire input_3_axis_tready, - input wire input_3_axis_tlast, - input wire input_3_axis_tuser, - - /* - * AXI output - */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, - - /* - * Configuration - */ - input wire [TAG_WIDTH-1:0] tag, - - /* - * Status signals - */ - output wire busy -); - -localparam TAG_BYTE_WIDTH = (TAG_WIDTH + 7) / 8; - -// state register -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_WRITE_TAG = 2'd1, - STATE_TRANSFER = 2'd2; - -reg [1:0] state_reg = STATE_IDLE, state_next; - -reg [2:0] frame_ptr_reg = 3'd0, frame_ptr_next; -reg [1:0] port_sel_reg = 2'd0, port_sel_next; - -reg busy_reg = 1'b0, busy_next; - -reg [7:0] input_tdata; -reg input_tvalid; -reg input_tlast; -reg input_tuser; - -reg output_tuser_reg = 1'b0, output_tuser_next; - -reg input_0_axis_tready_reg = 1'b0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 1'b0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; - -// internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; - -assign input_0_axis_tready = input_0_axis_tready_reg; -assign input_1_axis_tready = input_1_axis_tready_reg; -assign input_2_axis_tready = input_2_axis_tready_reg; -assign input_3_axis_tready = input_3_axis_tready_reg; - -assign busy = busy_reg; - -always @* begin - // input port mux - case (port_sel_reg) - 2'd0: begin - input_tdata = input_0_axis_tdata; - input_tvalid = input_0_axis_tvalid; - input_tlast = input_0_axis_tlast; - input_tuser = input_0_axis_tuser; - end - 2'd1: begin - input_tdata = input_1_axis_tdata; - input_tvalid = input_1_axis_tvalid; - input_tlast = input_1_axis_tlast; - input_tuser = input_1_axis_tuser; - end - 2'd2: begin - input_tdata = input_2_axis_tdata; - input_tvalid = input_2_axis_tvalid; - input_tlast = input_2_axis_tlast; - input_tuser = input_2_axis_tuser; - end - 2'd3: begin - input_tdata = input_3_axis_tdata; - input_tvalid = input_3_axis_tvalid; - input_tlast = input_3_axis_tlast; - input_tuser = input_3_axis_tuser; - end - endcase -end - -integer offset, i; - -always @* begin - state_next = STATE_IDLE; - - frame_ptr_next = frame_ptr_reg; - port_sel_next = port_sel_reg; - - input_0_axis_tready_next = 1'b0; - input_1_axis_tready_next = 1'b0; - input_2_axis_tready_next = 1'b0; - input_3_axis_tready_next = 1'b0; - - output_axis_tdata_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; - - output_tuser_next = output_tuser_reg; - - case (state_reg) - STATE_IDLE: begin - // idle state - wait for data - frame_ptr_next = 3'd0; - port_sel_next = 2'd0; - output_tuser_next = 1'b0; - - if (TAG_ENABLE) begin - // next cycle if started will send tag, so do not enable input - input_0_axis_tready_next = 1'b0; - end else begin - // next cycle if started will send data, so enable input - input_0_axis_tready_next = output_axis_tready_int_early; - end - - if (input_0_axis_tvalid) begin - // input 0 valid; start transferring data - if (TAG_ENABLE) begin - // tag enabled, so transmit it - if (output_axis_tready_int_reg) begin - // output is ready, so short-circuit first tag byte - frame_ptr_next = 3'd1; - output_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; - output_axis_tvalid_int = 1'b1; - end - state_next = STATE_WRITE_TAG; - end else begin - // tag disabled, so transmit data - if (output_axis_tready_int_reg) begin - // output is ready, so short-circuit first data byte - output_axis_tdata_int = input_0_axis_tdata; - output_axis_tvalid_int = 1'b1; - end - state_next = STATE_TRANSFER; - end - end else begin - state_next = STATE_IDLE; - end - end - STATE_WRITE_TAG: begin - // write tag data - if (output_axis_tready_int_reg) begin - // output ready, so send tag byte - state_next = STATE_WRITE_TAG; - frame_ptr_next = frame_ptr_reg + 1; - output_axis_tvalid_int = 1'b1; - - offset = 0; - if (TAG_ENABLE) begin - for (i = TAG_BYTE_WIDTH-1; i >= 0; i = i - 1) begin - if (frame_ptr_reg == offset) begin - output_axis_tdata_int = tag[i*8 +: 8]; - end - offset = offset + 1; - end - end - if (frame_ptr_reg == offset-1) begin - input_0_axis_tready_next = output_axis_tready_int_early; - state_next = STATE_TRANSFER; - end - end else begin - state_next = STATE_WRITE_TAG; - end - end - STATE_TRANSFER: begin - // transfer input data - - // set ready for current input - case (port_sel_reg) - 2'd0: input_0_axis_tready_next = output_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_axis_tready_int_early; - endcase - - if (input_tvalid & output_axis_tready_int_reg) begin - // output ready, transfer byte - state_next = STATE_TRANSFER; - output_axis_tdata_int = input_tdata; - output_axis_tvalid_int = input_tvalid; - - if (input_tlast) begin - // last flag received, switch to next port - port_sel_next = port_sel_reg + 1; - // save tuser - assert tuser out if ANY tuser asserts received - output_tuser_next = output_tuser_next | input_tuser; - // disable input - input_0_axis_tready_next = 1'b0; - input_1_axis_tready_next = 1'b0; - input_2_axis_tready_next = 1'b0; - input_3_axis_tready_next = 1'b0; - - if (port_sel_reg == 2'd3) begin - // last port - send tlast and tuser and revert to idle - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = output_tuser_next; - state_next = STATE_IDLE; - end else begin - // otherwise, disable enable next port - case (port_sel_next) - 2'd0: input_0_axis_tready_next = output_axis_tready_int_early; - 2'd1: input_1_axis_tready_next = output_axis_tready_int_early; - 2'd2: input_2_axis_tready_next = output_axis_tready_int_early; - 2'd3: input_3_axis_tready_next = output_axis_tready_int_early; - endcase - end - end - end else begin - state_next = STATE_TRANSFER; - end - end - endcase -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - frame_ptr_reg <= 3'd0; - port_sel_reg <= 2'd0; - input_0_axis_tready_reg <= 1'b0; - input_1_axis_tready_reg <= 1'b0; - input_2_axis_tready_reg <= 1'b0; - input_3_axis_tready_reg <= 1'b0; - output_tuser_reg <= 1'b0; - busy_reg <= 1'b0; - end else begin - state_reg <= state_next; - - frame_ptr_reg <= frame_ptr_next; - - port_sel_reg <= port_sel_next; - - input_0_axis_tready_reg <= input_0_axis_tready_next; - input_1_axis_tready_reg <= input_1_axis_tready_next; - input_2_axis_tready_reg <= input_2_axis_tready_next; - input_3_axis_tready_reg <= input_3_axis_tready_next; - - output_tuser_reg <= output_tuser_next; - - busy_reg <= state_next != STATE_IDLE; - end -end - -// output datapath logic -reg [7:0] output_axis_tdata_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; - -reg [7:0] temp_axis_tdata_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index 160999380..31a0a1f34 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -29,8 +29,8 @@ import struct import axis_ep -module = 'axis_frame_join_4' -testbench = 'test_%s' % module +module = 'axis_frame_join' +testbench = 'test_%s_4' % module srcs = [] @@ -44,6 +44,8 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + DATA_WIDTH = 8 + S_COUNT = 4 TAG_ENABLE = 1 TAG_WIDTH = 16 @@ -52,109 +54,65 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[8:]) - input_0_axis_tvalid = Signal(bool(0)) - input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tuser = Signal(bool(0)) - input_1_axis_tdata = Signal(intbv(0)[8:]) - input_1_axis_tvalid = Signal(bool(0)) - input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tuser = Signal(bool(0)) - input_2_axis_tdata = Signal(intbv(0)[8:]) - input_2_axis_tvalid = Signal(bool(0)) - input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tuser = Signal(bool(0)) - input_3_axis_tdata = Signal(intbv(0)[8:]) - input_3_axis_tvalid = Signal(bool(0)) - input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) + s_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tuser_list = [Signal(bool(0)) for i in range(S_COUNT)] + + s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list)) + s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list)) + s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list)) + s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list)) + + m_axis_tready = Signal(bool(0)) tag = Signal(intbv(0)[TAG_WIDTH:]) # Outputs - input_0_axis_tready = Signal(bool(0)) - input_1_axis_tready = Signal(bool(0)) - input_2_axis_tready = Signal(bool(0)) - input_3_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + s_axis_tready = Signal(intbv(0)[S_COUNT:]) + + s_axis_tready_list = [s_axis_tready(i) for i in range(S_COUNT)] + + m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource() + for k in range(S_COUNT): + s = axis_ep.AXIStreamSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - tdata=input_0_axis_tdata, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tuser=input_0_axis_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = axis_ep.AXIStreamSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - tdata=input_1_axis_tdata, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tuser=input_1_axis_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = axis_ep.AXIStreamSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - tdata=input_2_axis_tdata, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tuser=input_2_axis_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = axis_ep.AXIStreamSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - tdata=input_3_axis_tdata, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tuser=input_3_axis_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + tdata=s_axis_tdata_list[k], + tvalid=s_axis_tvalid_list[k], + tready=s_axis_tready_list[k], + tlast=s_axis_tlast_list[k], + tuser=s_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = axis_ep.AXIStreamSink() sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -169,35 +127,17 @@ def bench(): rst=rst, current_test=current_test, - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tuser=input_0_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tuser=input_1_axis_tuser, - - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tuser=input_2_axis_tuser, - - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tuser=input_3_axis_tuser, - - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, tag=tag, busy=busy @@ -229,15 +169,15 @@ def bench(): test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01') test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02') test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03') - source_0.send(test_frame_0) - source_1.send(test_frame_1) - source_2.send(test_frame_2) - source_3.send(test_frame_3) + source_list[0].send(test_frame_0) + source_list[1].send(test_frame_1) + source_list[2].send(test_frame_2) + source_list[3].send(test_frame_3) yield sink.wait() rx_frame = sink.recv() - assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + assert rx_frame.data == struct.pack('H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + assert rx_frame.data == struct.pack('H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + assert rx_frame.data == struct.pack('H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + assert rx_frame.data == struct.pack('H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data + assert rx_frame.data == struct.pack('H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + assert rx_frame.data == struct.pack('H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data + assert rx_frame.data == struct.pack('H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data + assert rx_frame.data == struct.pack('H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data + assert rx_frame.data == struct.pack('H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data + assert rx_frame.data == struct.pack(' Date: Wed, 24 Oct 2018 17:58:39 -0700 Subject: [PATCH 422/617] Fix loop count variable scoping issue --- rtl/axis_switch.v | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rtl/axis_switch.v b/rtl/axis_switch.v index b8c776008..392b64049 100644 --- a/rtl/axis_switch.v +++ b/rtl/axis_switch.v @@ -141,6 +141,8 @@ generate reg drop_reg = 1'b0, drop_next; reg select_valid_reg = 1'b0, select_valid_next; + integer k; + always @* begin select_next = select_reg; drop_next = drop_reg && !(int_s_axis_tvalid[m] && int_s_axis_tready[m] && int_s_axis_tlast[m]); @@ -150,9 +152,9 @@ generate select_next = 1'b0; select_valid_next = 1'b0; drop_next = 1'b1; - for (i = 0; i < M_COUNT; i = i + 1) begin - if (int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] >= M_BASE[i*32 +: 32] && int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[i*32 +: 32] && (M_CONNECT & (1 << (m+i*S_COUNT)))) begin - select_next = i; + for (k = 0; k < M_COUNT; k = k + 1) begin + if (int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] >= M_BASE[k*32 +: 32] && int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[k*32 +: 32] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin + select_next = k; select_valid_next = 1'b1; drop_next = 1'b0; end From 2bf15706cd876415f56b5c8e74445ceb29899d20 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 18:23:14 -0700 Subject: [PATCH 423/617] Convert generated mux to verilog parametrized mux --- rtl/axis_mux.py | 354 -------------------------------------- rtl/axis_mux.v | 253 +++++++++++++++++++++++++++ rtl/axis_mux_4.v | 363 --------------------------------------- tb/test_axis_mux_4.py | 276 +++++++++++------------------ tb/test_axis_mux_4.v | 174 ++++++------------- tb/test_axis_mux_4_64.py | 276 +++++++++++------------------ tb/test_axis_mux_4_64.v | 174 ++++++------------- 7 files changed, 549 insertions(+), 1321 deletions(-) delete mode 100755 rtl/axis_mux.py create mode 100644 rtl/axis_mux.v delete mode 100644 rtl/axis_mux_4.v diff --git a/rtl/axis_mux.py b/rtl/axis_mux.py deleted file mode 100755 index e327e21f7..000000000 --- a/rtl/axis_mux.py +++ /dev/null @@ -1,354 +0,0 @@ -#!/usr/bin/env python -""" -Generates an AXI Stream mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "axis_mux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port AXI Stream mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream {{n}} port multiplexer - */ -module {{name}} # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1 -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ -{%- for p in ports %} - input wire [DATA_WIDTH-1:0] input_{{p}}_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_{{p}}_axis_tkeep, - input wire input_{{p}}_axis_tvalid, - output wire input_{{p}}_axis_tready, - input wire input_{{p}}_axis_tlast, - input wire [ID_WIDTH-1:0] input_{{p}}_axis_tid, - input wire [DEST_WIDTH-1:0] input_{{p}}_axis_tdest, - input wire [USER_WIDTH-1:0] input_{{p}}_axis_tuser, -{% endfor %} - /* - * 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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser, - - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; -{% for p in ports %} -reg input_{{p}}_axis_tready_reg = 1'b0, input_{{p}}_axis_tready_next; -{%- endfor %} - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg [ID_WIDTH-1:0] output_axis_tid_int; -reg [DEST_WIDTH-1:0] output_axis_tdest_int; -reg [USER_WIDTH-1:0] output_axis_tuser_int; -wire output_axis_tready_int_early; -{% for p in ports %} -assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg; -{%- endfor %} - -// mux for start of packet detection -reg selected_input_tvalid; -always @* begin - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: selected_input_tvalid = input_{{p}}_axis_tvalid; -{%- endfor %} - default: selected_input_tvalid = 1'b0; - endcase -end - -// mux for incoming packet -reg [DATA_WIDTH-1:0] current_input_tdata; -reg [KEEP_WIDTH-1:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg [ID_WIDTH-1:0] current_input_tid; -reg [DEST_WIDTH-1:0] current_input_tdest; -reg [USER_WIDTH-1:0] current_input_tuser; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_input_tdata = input_{{p}}_axis_tdata; - current_input_tkeep = input_{{p}}_axis_tkeep; - current_input_tvalid = input_{{p}}_axis_tvalid; - current_input_tready = input_{{p}}_axis_tready; - current_input_tlast = input_{{p}}_axis_tlast; - current_input_tid = input_{{p}}_axis_tid; - current_input_tdest = input_{{p}}_axis_tdest; - current_input_tuser = input_{{p}}_axis_tuser; - end -{%- endfor %} - default: begin - current_input_tdata = {DATA_WIDTH{1'b0}}; - current_input_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tid = {ID_WIDTH{1'b0}}; - current_input_tdest = {DEST_WIDTH{1'b0}}; - current_input_tuser = {USER_WIDTH{1'b0}}; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; -{% for p in ports %} - input_{{p}}_axis_tready_next = 1'b0; -{%- endfor %} - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & selected_input_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - end - - // generate ready signal on selected port - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early & frame_next; -{%- endfor %} - endcase - - // pass through selected packet data - output_axis_tdata_int = current_input_tdata; - output_axis_tkeep_int = current_input_tkeep; - output_axis_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_axis_tlast_int = current_input_tlast; - output_axis_tid_int = current_input_tid; - output_axis_tdest_int = current_input_tdest; - output_axis_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; -{%- for p in ports %} - input_{{p}}_axis_tready_reg <= 1'b0; -{%- endfor %} - end else begin - select_reg <= select_next; - frame_reg <= frame_next; -{%- for p in ports %} - input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next; -{%- endfor %} - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tid_reg <= output_axis_tid_int; - output_axis_tdest_reg <= output_axis_tdest_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tid_reg <= output_axis_tid_int; - temp_axis_tdest_reg <= output_axis_tdest_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_mux.v b/rtl/axis_mux.v new file mode 100644 index 000000000..fcec24676 --- /dev/null +++ b/rtl/axis_mux.v @@ -0,0 +1,253 @@ +/* + +Copyright (c) 2014-2018 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 multiplexer + */ +module axis_mux # +( + parameter S_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI inputs + */ + input wire [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep, + input wire [S_COUNT-1:0] s_axis_tvalid, + output wire [S_COUNT-1:0] s_axis_tready, + input wire [S_COUNT-1:0] s_axis_tlast, + input wire [S_COUNT*ID_WIDTH-1:0] s_axis_tid, + input wire [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest, + input wire [S_COUNT*USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * Control + */ + input wire enable, + input wire [$clog2(S_COUNT)-1:0] select +); + +parameter CL_S_COUNT = $clog2(S_COUNT); + +reg [CL_S_COUNT-1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; + +reg [S_COUNT-1:0] s_axis_tready_reg = 0, s_axis_tready_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg [ID_WIDTH-1:0] m_axis_tid_int; +reg [DEST_WIDTH-1:0] m_axis_tdest_int; +reg [USER_WIDTH-1:0] m_axis_tuser_int; +wire m_axis_tready_int_early; + +assign s_axis_tready = s_axis_tready_reg; + +// mux for incoming packet +wire [DATA_WIDTH-1:0] current_s_tdata = s_axis_tdata[select_reg*DATA_WIDTH +: DATA_WIDTH]; +wire [KEEP_WIDTH-1:0] current_s_tkeep = s_axis_tkeep[select_reg*KEEP_WIDTH +: KEEP_WIDTH]; +wire current_s_tvalid = s_axis_tvalid[select_reg]; +wire current_s_tready = s_axis_tready[select_reg]; +wire current_s_tlast = s_axis_tlast[select_reg]; +wire [ID_WIDTH-1:0] current_s_tid = s_axis_tid[select_reg*ID_WIDTH +: ID_WIDTH]; +wire [DEST_WIDTH-1:0] current_s_tdest = s_axis_tdest[select_reg*DEST_WIDTH +: DEST_WIDTH]; +wire [USER_WIDTH-1:0] current_s_tuser = s_axis_tuser[select_reg*USER_WIDTH +: USER_WIDTH]; + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + s_axis_tready_next = 0; + + if (current_s_tvalid & current_s_tready) begin + // end of frame detection + if (current_s_tlast) begin + frame_next = 1'b0; + end + end + + if (~frame_reg && enable && (s_axis_tvalid & (1 << select))) begin + // start of frame, grab select value + frame_next = 1'b1; + select_next = select; + end + + // generate ready signal on selected port + s_axis_tready_next = (m_axis_tready_int_early && frame_next) << select_next; + + // pass through selected packet data + m_axis_tdata_int = current_s_tdata; + m_axis_tkeep_int = current_s_tkeep; + m_axis_tvalid_int = current_s_tvalid && current_s_tready && frame_reg; + m_axis_tlast_int = current_s_tlast; + m_axis_tid_int = current_s_tid; + m_axis_tdest_int = current_s_tdest; + m_axis_tuser_int = current_s_tuser; +end + +always @(posedge clk) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 1'b0; + s_axis_tready_reg <= 0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + s_axis_tready_reg <= s_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_axis_tready_int_early = m_axis_tready | (~temp_m_axis_tvalid_reg & (~m_axis_tvalid_reg | ~m_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (m_axis_tready_int_reg) begin + // input is ready + if (m_axis_tready | ~m_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_axis_tready) begin + // input is not ready, but output is ready + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; + end else begin + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tid_reg <= m_axis_tid_int; + m_axis_tdest_reg <= m_axis_tdest_int; + m_axis_tuser_reg <= m_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tid_reg <= m_axis_tid_int; + temp_m_axis_tdest_reg <= m_axis_tdest_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/axis_mux_4.v b/rtl/axis_mux_4.v deleted file mode 100644 index dea78aca7..000000000 --- a/rtl/axis_mux_4.v +++ /dev/null @@ -1,363 +0,0 @@ -/* - -Copyright (c) 2014-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream 4 port multiplexer - */ -module axis_mux_4 # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1 -) -( - input wire clk, - input wire rst, - - /* - * AXI inputs - */ - input wire [DATA_WIDTH-1:0] input_0_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, - input wire input_0_axis_tvalid, - output wire input_0_axis_tready, - input wire input_0_axis_tlast, - input wire [ID_WIDTH-1:0] input_0_axis_tid, - input wire [DEST_WIDTH-1:0] input_0_axis_tdest, - input wire [USER_WIDTH-1:0] input_0_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_1_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, - input wire input_1_axis_tvalid, - output wire input_1_axis_tready, - input wire input_1_axis_tlast, - input wire [ID_WIDTH-1:0] input_1_axis_tid, - input wire [DEST_WIDTH-1:0] input_1_axis_tdest, - input wire [USER_WIDTH-1:0] input_1_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_2_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, - input wire input_2_axis_tvalid, - output wire input_2_axis_tready, - input wire input_2_axis_tlast, - input wire [ID_WIDTH-1:0] input_2_axis_tid, - input wire [DEST_WIDTH-1:0] input_2_axis_tdest, - input wire [USER_WIDTH-1:0] input_2_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_3_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, - input wire input_3_axis_tvalid, - output wire input_3_axis_tready, - input wire input_3_axis_tlast, - input wire [ID_WIDTH-1:0] input_3_axis_tid, - input wire [DEST_WIDTH-1:0] input_3_axis_tdest, - input wire [USER_WIDTH-1:0] input_3_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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_axis_tready_reg = 1'b0, input_0_axis_tready_next; -reg input_1_axis_tready_reg = 1'b0, input_1_axis_tready_next; -reg input_2_axis_tready_reg = 1'b0, input_2_axis_tready_next; -reg input_3_axis_tready_reg = 1'b0, input_3_axis_tready_next; - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg [ID_WIDTH-1:0] output_axis_tid_int; -reg [DEST_WIDTH-1:0] output_axis_tdest_int; -reg [USER_WIDTH-1:0] output_axis_tuser_int; -wire output_axis_tready_int_early; - -assign input_0_axis_tready = input_0_axis_tready_reg; -assign input_1_axis_tready = input_1_axis_tready_reg; -assign input_2_axis_tready = input_2_axis_tready_reg; -assign input_3_axis_tready = input_3_axis_tready_reg; - -// mux for start of packet detection -reg selected_input_tvalid; -always @* begin - case (select) - 2'd0: selected_input_tvalid = input_0_axis_tvalid; - 2'd1: selected_input_tvalid = input_1_axis_tvalid; - 2'd2: selected_input_tvalid = input_2_axis_tvalid; - 2'd3: selected_input_tvalid = input_3_axis_tvalid; - default: selected_input_tvalid = 1'b0; - endcase -end - -// mux for incoming packet -reg [DATA_WIDTH-1:0] current_input_tdata; -reg [KEEP_WIDTH-1:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg [ID_WIDTH-1:0] current_input_tid; -reg [DEST_WIDTH-1:0] current_input_tdest; -reg [USER_WIDTH-1:0] current_input_tuser; -always @* begin - case (select_reg) - 2'd0: begin - current_input_tdata = input_0_axis_tdata; - current_input_tkeep = input_0_axis_tkeep; - current_input_tvalid = input_0_axis_tvalid; - current_input_tready = input_0_axis_tready; - current_input_tlast = input_0_axis_tlast; - current_input_tid = input_0_axis_tid; - current_input_tdest = input_0_axis_tdest; - current_input_tuser = input_0_axis_tuser; - end - 2'd1: begin - current_input_tdata = input_1_axis_tdata; - current_input_tkeep = input_1_axis_tkeep; - current_input_tvalid = input_1_axis_tvalid; - current_input_tready = input_1_axis_tready; - current_input_tlast = input_1_axis_tlast; - current_input_tid = input_1_axis_tid; - current_input_tdest = input_1_axis_tdest; - current_input_tuser = input_1_axis_tuser; - end - 2'd2: begin - current_input_tdata = input_2_axis_tdata; - current_input_tkeep = input_2_axis_tkeep; - current_input_tvalid = input_2_axis_tvalid; - current_input_tready = input_2_axis_tready; - current_input_tlast = input_2_axis_tlast; - current_input_tid = input_2_axis_tid; - current_input_tdest = input_2_axis_tdest; - current_input_tuser = input_2_axis_tuser; - end - 2'd3: begin - current_input_tdata = input_3_axis_tdata; - current_input_tkeep = input_3_axis_tkeep; - current_input_tvalid = input_3_axis_tvalid; - current_input_tready = input_3_axis_tready; - current_input_tlast = input_3_axis_tlast; - current_input_tid = input_3_axis_tid; - current_input_tdest = input_3_axis_tdest; - current_input_tuser = input_3_axis_tuser; - end - default: begin - current_input_tdata = {DATA_WIDTH{1'b0}}; - current_input_tkeep = {KEEP_WIDTH{1'b0}}; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tid = {ID_WIDTH{1'b0}}; - current_input_tdest = {DEST_WIDTH{1'b0}}; - current_input_tuser = {USER_WIDTH{1'b0}}; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_axis_tready_next = 1'b0; - input_1_axis_tready_next = 1'b0; - input_2_axis_tready_next = 1'b0; - input_3_axis_tready_next = 1'b0; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & selected_input_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - end - - // generate ready signal on selected port - case (select_next) - 2'd0: input_0_axis_tready_next = output_axis_tready_int_early & frame_next; - 2'd1: input_1_axis_tready_next = output_axis_tready_int_early & frame_next; - 2'd2: input_2_axis_tready_next = output_axis_tready_int_early & frame_next; - 2'd3: input_3_axis_tready_next = output_axis_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_axis_tdata_int = current_input_tdata; - output_axis_tkeep_int = current_input_tkeep; - output_axis_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_axis_tlast_int = current_input_tlast; - output_axis_tid_int = current_input_tid; - output_axis_tdest_int = current_input_tdest; - output_axis_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_0_axis_tready_reg <= 1'b0; - input_1_axis_tready_reg <= 1'b0; - input_2_axis_tready_reg <= 1'b0; - input_3_axis_tready_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_axis_tready_reg <= input_0_axis_tready_next; - input_1_axis_tready_reg <= input_1_axis_tready_next; - input_2_axis_tready_reg <= input_2_axis_tready_next; - input_3_axis_tready_reg <= input_3_axis_tready_next; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (output_axis_tready) begin - // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tid_reg <= output_axis_tid_int; - output_axis_tdest_reg <= output_axis_tdest_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tid_reg <= output_axis_tid_int; - temp_axis_tdest_reg <= output_axis_tdest_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py index 04dbcb7f6..4d469375c 100755 --- a/tb/test_axis_mux_4.py +++ b/tb/test_axis_mux_4.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_mux_4' -testbench = 'test_%s' % module +module = 'axis_mux' +testbench = 'test_%s_4' % module srcs = [] @@ -43,6 +43,7 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + S_COUNT = 4 DATA_WIDTH = 8 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) @@ -58,142 +59,81 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_0_axis_tvalid = Signal(bool(0)) - input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_1_axis_tvalid = Signal(bool(0)) - input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_2_axis_tvalid = Signal(bool(0)) - input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_3_axis_tvalid = Signal(bool(0)) - input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_axis_tready = Signal(bool(0)) + s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list)) + s_axis_tkeep = ConcatSignal(*reversed(s_axis_tkeep_list)) + s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list)) + s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list)) + s_axis_tid = ConcatSignal(*reversed(s_axis_tid_list)) + s_axis_tdest = ConcatSignal(*reversed(s_axis_tdest_list)) + s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list)) + + m_axis_tready = Signal(bool(0)) enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_0_axis_tready = Signal(bool(0)) - input_1_axis_tready = Signal(bool(0)) - input_2_axis_tready = Signal(bool(0)) - input_3_axis_tready = Signal(bool(0)) + s_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready_list = [s_axis_tready(i) for i in range(S_COUNT)] + + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource() + for k in range(S_COUNT): + s = axis_ep.AXIStreamSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tid=input_0_axis_tid, - tdest=input_0_axis_tdest, - tuser=input_0_axis_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = axis_ep.AXIStreamSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tid=input_1_axis_tid, - tdest=input_1_axis_tdest, - tuser=input_1_axis_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = axis_ep.AXIStreamSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tid=input_2_axis_tid, - tdest=input_2_axis_tdest, - tuser=input_2_axis_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = axis_ep.AXIStreamSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tid=input_3_axis_tid, - tdest=input_3_axis_tdest, - tuser=input_3_axis_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + tdata=s_axis_tdata_list[k], + tkeep=s_axis_tkeep_list[k], + tvalid=s_axis_tvalid_list[k], + tready=s_axis_tready_list[k], + tlast=s_axis_tlast_list[k], + tid=s_axis_tid_list[k], + tdest=s_axis_tdest_list[k], + tuser=s_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = axis_ep.AXIStreamSink() sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -208,47 +148,23 @@ def bench(): rst=rst, current_test=current_test, - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tid=input_0_axis_tid, - input_0_axis_tdest=input_0_axis_tdest, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tid=input_1_axis_tid, - input_1_axis_tdest=input_1_axis_tdest, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tid=input_2_axis_tid, - input_2_axis_tdest=input_2_axis_tdest, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tid=input_3_axis_tid, - input_3_axis_tdest=input_3_axis_tdest, - input_3_axis_tuser=input_3_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, enable=enable, select=select @@ -287,7 +203,7 @@ def bench(): dest=1 ) - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -311,7 +227,7 @@ def bench(): dest=1 ) - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -343,8 +259,8 @@ def bench(): dest=2 ) - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -381,11 +297,11 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + while s_axis_tvalid: yield clk.posedge select.next = 2 @@ -424,22 +340,22 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge select.next = 2 @@ -478,11 +394,11 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + while s_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_mux_4.v b/tb/test_axis_mux_4.v index ca4345821..a72c24446 100644 --- a/tb/test_axis_mux_4.v +++ b/tb/test_axis_mux_4.v @@ -27,11 +27,12 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_mux_4 + * Testbench for axis_mux */ module test_axis_mux_4; // Parameters +parameter S_COUNT = 4; parameter DATA_WIDTH = 8; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); @@ -47,53 +48,29 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; -reg input_0_axis_tvalid = 0; -reg input_0_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_0_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; -reg input_1_axis_tvalid = 0; -reg input_1_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_1_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; -reg input_2_axis_tvalid = 0; -reg input_2_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_2_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; -reg input_3_axis_tvalid = 0; -reg input_3_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_3_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg [S_COUNT-1:0] s_axis_tvalid = 0; +reg [S_COUNT-1:0] s_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_axis_tuser = 0; -reg output_axis_tready = 0; +reg m_axis_tready = 0; reg enable = 0; reg [1:0] select = 0; // Outputs -wire input_0_axis_tready; -wire input_1_axis_tready; -wire input_2_axis_tready; -wire input_3_axis_tready; +wire [S_COUNT-1:0] s_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -101,50 +78,26 @@ initial begin clk, rst, current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tid, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tid, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tid, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tid, - input_3_axis_tdest, - input_3_axis_tuser, - output_axis_tready, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready, enable, select ); $to_myhdl( - input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -152,7 +105,8 @@ initial begin $dumpvars(0, test_axis_mux_4); end -axis_mux_4 #( +axis_mux #( + .S_COUNT(S_COUNT), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), @@ -167,47 +121,23 @@ UUT ( .clk(clk), .rst(rst), // AXI inputs - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tkeep(input_0_axis_tkeep), - .input_0_axis_tvalid(input_0_axis_tvalid), - .input_0_axis_tready(input_0_axis_tready), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tid(input_0_axis_tid), - .input_0_axis_tdest(input_0_axis_tdest), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tkeep(input_1_axis_tkeep), - .input_1_axis_tvalid(input_1_axis_tvalid), - .input_1_axis_tready(input_1_axis_tready), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tid(input_1_axis_tid), - .input_1_axis_tdest(input_1_axis_tdest), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tkeep(input_2_axis_tkeep), - .input_2_axis_tvalid(input_2_axis_tvalid), - .input_2_axis_tready(input_2_axis_tready), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tid(input_2_axis_tid), - .input_2_axis_tdest(input_2_axis_tdest), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tkeep(input_3_axis_tkeep), - .input_3_axis_tvalid(input_3_axis_tvalid), - .input_3_axis_tready(input_3_axis_tready), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tid(input_3_axis_tid), - .input_3_axis_tdest(input_3_axis_tdest), - .input_3_axis_tuser(input_3_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Control .enable(enable), .select(select) diff --git a/tb/test_axis_mux_4_64.py b/tb/test_axis_mux_4_64.py index de7b1e01a..0b9d8a471 100755 --- a/tb/test_axis_mux_4_64.py +++ b/tb/test_axis_mux_4_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_mux_4' -testbench = 'test_%s_64' % module +module = 'axis_mux' +testbench = 'test_%s_4_64' % module srcs = [] @@ -43,6 +43,7 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + S_COUNT = 4 DATA_WIDTH = 64 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) @@ -58,142 +59,81 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_0_axis_tvalid = Signal(bool(0)) - input_0_axis_tlast = Signal(bool(0)) - input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_1_axis_tvalid = Signal(bool(0)) - input_1_axis_tlast = Signal(bool(0)) - input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_2_axis_tvalid = Signal(bool(0)) - input_2_axis_tlast = Signal(bool(0)) - input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_3_axis_tvalid = Signal(bool(0)) - input_3_axis_tlast = Signal(bool(0)) - input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_axis_tready = Signal(bool(0)) + s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list)) + s_axis_tkeep = ConcatSignal(*reversed(s_axis_tkeep_list)) + s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list)) + s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list)) + s_axis_tid = ConcatSignal(*reversed(s_axis_tid_list)) + s_axis_tdest = ConcatSignal(*reversed(s_axis_tdest_list)) + s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list)) + + m_axis_tready = Signal(bool(0)) enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_0_axis_tready = Signal(bool(0)) - input_1_axis_tready = Signal(bool(0)) - input_2_axis_tready = Signal(bool(0)) - input_3_axis_tready = Signal(bool(0)) + s_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready_list = [s_axis_tready(i) for i in range(S_COUNT)] + + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = axis_ep.AXIStreamSource() + for k in range(S_COUNT): + s = axis_ep.AXIStreamSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - tdata=input_0_axis_tdata, - tkeep=input_0_axis_tkeep, - tvalid=input_0_axis_tvalid, - tready=input_0_axis_tready, - tlast=input_0_axis_tlast, - tid=input_0_axis_tid, - tdest=input_0_axis_tdest, - tuser=input_0_axis_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = axis_ep.AXIStreamSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - tdata=input_1_axis_tdata, - tkeep=input_1_axis_tkeep, - tvalid=input_1_axis_tvalid, - tready=input_1_axis_tready, - tlast=input_1_axis_tlast, - tid=input_1_axis_tid, - tdest=input_1_axis_tdest, - tuser=input_1_axis_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = axis_ep.AXIStreamSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - tdata=input_2_axis_tdata, - tkeep=input_2_axis_tkeep, - tvalid=input_2_axis_tvalid, - tready=input_2_axis_tready, - tlast=input_2_axis_tlast, - tid=input_2_axis_tid, - tdest=input_2_axis_tdest, - tuser=input_2_axis_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = axis_ep.AXIStreamSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - tdata=input_3_axis_tdata, - tkeep=input_3_axis_tkeep, - tvalid=input_3_axis_tvalid, - tready=input_3_axis_tready, - tlast=input_3_axis_tlast, - tid=input_3_axis_tid, - tdest=input_3_axis_tdest, - tuser=input_3_axis_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + tdata=s_axis_tdata_list[k], + tkeep=s_axis_tkeep_list[k], + tvalid=s_axis_tvalid_list[k], + tready=s_axis_tready_list[k], + tlast=s_axis_tlast_list[k], + tid=s_axis_tid_list[k], + tdest=s_axis_tdest_list[k], + tuser=s_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = axis_ep.AXIStreamSink() sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -208,47 +148,23 @@ def bench(): rst=rst, current_test=current_test, - input_0_axis_tdata=input_0_axis_tdata, - input_0_axis_tkeep=input_0_axis_tkeep, - input_0_axis_tvalid=input_0_axis_tvalid, - input_0_axis_tready=input_0_axis_tready, - input_0_axis_tlast=input_0_axis_tlast, - input_0_axis_tid=input_0_axis_tid, - input_0_axis_tdest=input_0_axis_tdest, - input_0_axis_tuser=input_0_axis_tuser, - input_1_axis_tdata=input_1_axis_tdata, - input_1_axis_tkeep=input_1_axis_tkeep, - input_1_axis_tvalid=input_1_axis_tvalid, - input_1_axis_tready=input_1_axis_tready, - input_1_axis_tlast=input_1_axis_tlast, - input_1_axis_tid=input_1_axis_tid, - input_1_axis_tdest=input_1_axis_tdest, - input_1_axis_tuser=input_1_axis_tuser, - input_2_axis_tdata=input_2_axis_tdata, - input_2_axis_tkeep=input_2_axis_tkeep, - input_2_axis_tvalid=input_2_axis_tvalid, - input_2_axis_tready=input_2_axis_tready, - input_2_axis_tlast=input_2_axis_tlast, - input_2_axis_tid=input_2_axis_tid, - input_2_axis_tdest=input_2_axis_tdest, - input_2_axis_tuser=input_2_axis_tuser, - input_3_axis_tdata=input_3_axis_tdata, - input_3_axis_tkeep=input_3_axis_tkeep, - input_3_axis_tvalid=input_3_axis_tvalid, - input_3_axis_tready=input_3_axis_tready, - input_3_axis_tlast=input_3_axis_tlast, - input_3_axis_tid=input_3_axis_tid, - input_3_axis_tdest=input_3_axis_tdest, - input_3_axis_tuser=input_3_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, enable=enable, select=select @@ -287,7 +203,7 @@ def bench(): dest=1 ) - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -311,7 +227,7 @@ def bench(): dest=1 ) - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -343,8 +259,8 @@ def bench(): dest=2 ) - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -381,11 +297,11 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + while s_axis_tvalid: yield clk.posedge select.next = 2 @@ -424,22 +340,22 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge select.next = 2 @@ -478,11 +394,11 @@ def bench(): dest=2 ) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge - while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid: + while s_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_mux_4_64.v b/tb/test_axis_mux_4_64.v index ad62fd3d9..a8d9c280b 100644 --- a/tb/test_axis_mux_4_64.v +++ b/tb/test_axis_mux_4_64.v @@ -27,11 +27,12 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_mux_4 + * Testbench for axis_mux */ module test_axis_mux_4_64; // Parameters +parameter S_COUNT = 4; parameter DATA_WIDTH = 64; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); @@ -47,53 +48,29 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_0_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep = 0; -reg input_0_axis_tvalid = 0; -reg input_0_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_0_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_0_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_0_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_1_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep = 0; -reg input_1_axis_tvalid = 0; -reg input_1_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_1_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_1_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_1_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_2_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep = 0; -reg input_2_axis_tvalid = 0; -reg input_2_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_2_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_2_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_2_axis_tuser = 0; -reg [DATA_WIDTH-1:0] input_3_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep = 0; -reg input_3_axis_tvalid = 0; -reg input_3_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_3_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_3_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_3_axis_tuser = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg [S_COUNT-1:0] s_axis_tvalid = 0; +reg [S_COUNT-1:0] s_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_axis_tuser = 0; -reg output_axis_tready = 0; +reg m_axis_tready = 0; reg enable = 0; reg [1:0] select = 0; // Outputs -wire input_0_axis_tready; -wire input_1_axis_tready; -wire input_2_axis_tready; -wire input_3_axis_tready; +wire [S_COUNT-1:0] s_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -101,50 +78,26 @@ initial begin clk, rst, current_test, - input_0_axis_tdata, - input_0_axis_tkeep, - input_0_axis_tvalid, - input_0_axis_tlast, - input_0_axis_tid, - input_0_axis_tdest, - input_0_axis_tuser, - input_1_axis_tdata, - input_1_axis_tkeep, - input_1_axis_tvalid, - input_1_axis_tlast, - input_1_axis_tid, - input_1_axis_tdest, - input_1_axis_tuser, - input_2_axis_tdata, - input_2_axis_tkeep, - input_2_axis_tvalid, - input_2_axis_tlast, - input_2_axis_tid, - input_2_axis_tdest, - input_2_axis_tuser, - input_3_axis_tdata, - input_3_axis_tkeep, - input_3_axis_tvalid, - input_3_axis_tlast, - input_3_axis_tid, - input_3_axis_tdest, - input_3_axis_tuser, - output_axis_tready, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready, enable, select ); $to_myhdl( - input_0_axis_tready, - input_1_axis_tready, - input_2_axis_tready, - input_3_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -152,7 +105,8 @@ initial begin $dumpvars(0, test_axis_mux_4_64); end -axis_mux_4 #( +axis_mux #( + .S_COUNT(S_COUNT), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), @@ -167,47 +121,23 @@ UUT ( .clk(clk), .rst(rst), // AXI inputs - .input_0_axis_tdata(input_0_axis_tdata), - .input_0_axis_tkeep(input_0_axis_tkeep), - .input_0_axis_tvalid(input_0_axis_tvalid), - .input_0_axis_tready(input_0_axis_tready), - .input_0_axis_tlast(input_0_axis_tlast), - .input_0_axis_tid(input_0_axis_tid), - .input_0_axis_tdest(input_0_axis_tdest), - .input_0_axis_tuser(input_0_axis_tuser), - .input_1_axis_tdata(input_1_axis_tdata), - .input_1_axis_tkeep(input_1_axis_tkeep), - .input_1_axis_tvalid(input_1_axis_tvalid), - .input_1_axis_tready(input_1_axis_tready), - .input_1_axis_tlast(input_1_axis_tlast), - .input_1_axis_tid(input_1_axis_tid), - .input_1_axis_tdest(input_1_axis_tdest), - .input_1_axis_tuser(input_1_axis_tuser), - .input_2_axis_tdata(input_2_axis_tdata), - .input_2_axis_tkeep(input_2_axis_tkeep), - .input_2_axis_tvalid(input_2_axis_tvalid), - .input_2_axis_tready(input_2_axis_tready), - .input_2_axis_tlast(input_2_axis_tlast), - .input_2_axis_tid(input_2_axis_tid), - .input_2_axis_tdest(input_2_axis_tdest), - .input_2_axis_tuser(input_2_axis_tuser), - .input_3_axis_tdata(input_3_axis_tdata), - .input_3_axis_tkeep(input_3_axis_tkeep), - .input_3_axis_tvalid(input_3_axis_tvalid), - .input_3_axis_tready(input_3_axis_tready), - .input_3_axis_tlast(input_3_axis_tlast), - .input_3_axis_tid(input_3_axis_tid), - .input_3_axis_tdest(input_3_axis_tdest), - .input_3_axis_tuser(input_3_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Control .enable(enable), .select(select) From 145ea2c40c88fac6dff138db7e7670260a6d4569 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 21:09:00 -0700 Subject: [PATCH 424/617] Connect arbiter parameters to top level --- rtl/axis_switch.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/axis_switch.v b/rtl/axis_switch.v index 392b64049..6f58a2230 100644 --- a/rtl/axis_switch.v +++ b/rtl/axis_switch.v @@ -226,9 +226,9 @@ generate arbiter #( .PORTS(S_COUNT), - .TYPE("ROUND_ROBIN"), + .TYPE(ARB_TYPE), .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY("HIGH") + .LSB_PRIORITY(LSB_PRIORITY) ) arb_inst ( .clk(clk), From 9d813226d0e17c2737f542ec0ca181e0c03b5907 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 22:16:05 -0700 Subject: [PATCH 425/617] Convert generated demux to verilog parametrized demux --- rtl/axis_demux.py | 324 --------------------------------- rtl/axis_demux.v | 258 ++++++++++++++++++++++++++ rtl/axis_demux_4.v | 335 ---------------------------------- tb/test_axis_demux_4.py | 359 +++++++++++++++++-------------------- tb/test_axis_demux_4.v | 179 ++++++------------ tb/test_axis_demux_4_64.py | 359 +++++++++++++++++-------------------- tb/test_axis_demux_4_64.v | 179 ++++++------------ 7 files changed, 706 insertions(+), 1287 deletions(-) delete mode 100755 rtl/axis_demux.py create mode 100644 rtl/axis_demux.v delete mode 100644 rtl/axis_demux_4.v diff --git a/rtl/axis_demux.py b/rtl/axis_demux.py deleted file mode 100755 index 4d2832484..000000000 --- a/rtl/axis_demux.py +++ /dev/null @@ -1,324 +0,0 @@ -#!/usr/bin/env python -""" -Generates an AXI Stream demux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "axis_demux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port AXI Stream demux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream {{n}} port demultiplexer - */ -module {{name}} # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1 -) -( - input wire clk, - 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, - - /* - * AXI outputs - */ -{%- for p in ports %} - output wire [DATA_WIDTH-1:0] output_{{p}}_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_{{p}}_axis_tkeep, - output wire output_{{p}}_axis_tvalid, - input wire output_{{p}}_axis_tready, - output wire output_{{p}}_axis_tlast, - output wire [ID_WIDTH-1:0] output_{{p}}_axis_tid, - output wire [DEST_WIDTH-1:0] output_{{p}}_axis_tdest, - output wire [USER_WIDTH-1:0] output_{{p}}_axis_tuser, -{% endfor %} - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg [ID_WIDTH-1:0] output_axis_tid_int; -reg [DEST_WIDTH-1:0] output_axis_tdest_int; -reg [USER_WIDTH-1:0] output_axis_tuser_int; -wire output_axis_tready_int_early; - -assign input_axis_tready = input_axis_tready_reg; - -// mux for output control signals -reg current_output_tready; -reg current_output_tvalid; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_output_tvalid = output_{{p}}_axis_tvalid; - current_output_tready = output_{{p}}_axis_tready; - end -{%- endfor %} - default: begin - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_axis_tready_next = 1'b0; - - if (input_axis_tvalid & input_axis_tready) begin - // end of frame detection - if (input_axis_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_axis_tvalid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - end - - input_axis_tready_next = output_axis_tready_int_early & frame_next; - - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tid_int = input_axis_tid; - output_axis_tdest_int = input_axis_tdest; - output_axis_tuser_int = input_axis_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; - input_axis_tready_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_axis_tready_reg <= input_axis_tready_next; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -{%- for p in ports %} -reg output_{{p}}_axis_tvalid_reg = 1'b0, output_{{p}}_axis_tvalid_next; -{%- endfor %} -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; -{% for p in ports %} -assign output_{{p}}_axis_tdata = output_axis_tdata_reg; -assign output_{{p}}_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_{{p}}_axis_tvalid = output_{{p}}_axis_tvalid_reg; -assign output_{{p}}_axis_tlast = output_axis_tlast_reg; -assign output_{{p}}_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_{{p}}_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_{{p}}_axis_tuser = USER_ENABLE ? output_axis_tuser_int : {USER_WIDTH{1'b0}}; -{% endfor %} -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & (~current_output_tvalid | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source -{%- for p in ports %} - output_{{p}}_axis_tvalid_next = output_{{p}}_axis_tvalid_reg; -{%- endfor %} - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output -{%- for p in ports %} - output_{{p}}_axis_tvalid_next = output_axis_tvalid_int & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready -{%- for p in ports %} - output_{{p}}_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin -{%- for p in ports %} - output_{{p}}_axis_tvalid_reg <= 1'b0; -{%- endfor %} - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin -{%- for p in ports %} - output_{{p}}_axis_tvalid_reg <= output_{{p}}_axis_tvalid_next; -{%- endfor %} - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tid_reg <= output_axis_tid_int; - output_axis_tdest_reg <= output_axis_tdest_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tid_reg <= output_axis_tid_int; - temp_axis_tdest_reg <= output_axis_tdest_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/axis_demux.v b/rtl/axis_demux.v new file mode 100644 index 000000000..6edff1eec --- /dev/null +++ b/rtl/axis_demux.v @@ -0,0 +1,258 @@ +/* + +Copyright (c) 2018 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 demultiplexer + */ +module axis_demux # +( + parameter M_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + 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, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI outputs + */ + output wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata, + output wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep, + output wire [M_COUNT-1:0] m_axis_tvalid, + input wire [M_COUNT-1:0] m_axis_tready, + output wire [M_COUNT-1:0] m_axis_tlast, + output wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid, + output wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest, + output wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser, + + /* + * Control + */ + input wire enable, + input wire drop, + input wire [$clog2(M_COUNT)-1:0] select +); + +parameter CL_M_COUNT = $clog2(M_COUNT); + +reg [CL_M_COUNT-1:0] select_reg = {CL_M_COUNT{1'b0}}, select_ctl, select_next; +reg drop_reg = 1'b0, drop_ctl, drop_next; +reg frame_reg = 1'b0, frame_ctl, frame_next; + +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg [M_COUNT-1:0] m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg [ID_WIDTH-1:0] m_axis_tid_int; +reg [DEST_WIDTH-1:0] m_axis_tdest_int; +reg [USER_WIDTH-1:0] m_axis_tuser_int; +wire m_axis_tready_int_early; + +assign s_axis_tready = s_axis_tready_reg && enable; + +integer i; + +always @* begin + select_next = select_reg; + select_ctl = select_reg; + drop_next = drop_reg; + drop_ctl = drop_reg; + frame_next = frame_reg; + frame_ctl = frame_reg; + + s_axis_tready_next = 1'b0; + + if (s_axis_tvalid && s_axis_tready) begin + // end of frame detection + if (s_axis_tlast) begin + frame_next = 1'b0; + drop_next = 1'b0; + end + end + + if (!frame_reg && s_axis_tvalid && s_axis_tready) begin + // start of frame, grab select value + select_ctl = select; + drop_ctl = drop; + frame_ctl = 1'b1; + if (!(s_axis_tready && s_axis_tvalid && s_axis_tlast)) begin + select_next = select_ctl; + drop_next = drop_ctl; + frame_next = 1'b1; + end + end + + s_axis_tready_next = (m_axis_tready_int_early || drop_ctl); + + m_axis_tdata_int = s_axis_tdata; + m_axis_tkeep_int = s_axis_tkeep; + m_axis_tvalid_int = (s_axis_tvalid && s_axis_tready && !drop_ctl) << select_ctl; + m_axis_tlast_int = s_axis_tlast; + m_axis_tid_int = s_axis_tid; + m_axis_tdest_int = s_axis_tdest; + m_axis_tuser_int = s_axis_tuser; +end + +always @(posedge clk) begin + if (rst) begin + select_reg <= 2'd0; + drop_reg <= 1'b0; + frame_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; + end else begin + select_reg <= select_next; + drop_reg <= drop_next; + frame_reg <= frame_next; + s_axis_tready_reg <= s_axis_tready_next; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [M_COUNT-1:0] m_axis_tvalid_reg = {M_COUNT{1'b0}}, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [M_COUNT-1:0] temp_m_axis_tvalid_reg = {M_COUNT{1'b0}}, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign m_axis_tdata = {M_COUNT{m_axis_tdata_reg}}; +assign m_axis_tkeep = KEEP_ENABLE ? {M_COUNT{m_axis_tkeep_reg}} : {M_COUNT*KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = {M_COUNT{m_axis_tlast_reg}}; +assign m_axis_tid = ID_ENABLE ? {M_COUNT{m_axis_tid_reg}} : {M_COUNT*ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? {M_COUNT{m_axis_tdest_reg}} : {M_COUNT*DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? {M_COUNT{m_axis_tuser_reg}} : {M_COUNT*USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_axis_tready_int_early = (m_axis_tready & m_axis_tvalid) || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid || !m_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (m_axis_tready_int_reg) begin + // input is ready + if ((m_axis_tready & m_axis_tvalid) || !m_axis_tvalid) begin + // output is ready or currently not valid, transfer data to output + m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_axis_tready & m_axis_tvalid) begin + // input is not ready, but output is ready + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_axis_tvalid_reg <= {M_COUNT{1'b0}}; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; + end else begin + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tid_reg <= m_axis_tid_int; + m_axis_tdest_reg <= m_axis_tdest_int; + m_axis_tuser_reg <= m_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tid_reg <= m_axis_tid_int; + temp_m_axis_tdest_reg <= m_axis_tdest_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/axis_demux_4.v b/rtl/axis_demux_4.v deleted file mode 100644 index 2e12aebb9..000000000 --- a/rtl/axis_demux_4.v +++ /dev/null @@ -1,335 +0,0 @@ -/* - -Copyright (c) 2014-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * AXI4-Stream 4 port demultiplexer - */ -module axis_demux_4 # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1 -) -( - input wire clk, - 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, - - /* - * AXI outputs - */ - output wire [DATA_WIDTH-1:0] output_0_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, - output wire output_0_axis_tvalid, - input wire output_0_axis_tready, - output wire output_0_axis_tlast, - output wire [ID_WIDTH-1:0] output_0_axis_tid, - output wire [DEST_WIDTH-1:0] output_0_axis_tdest, - output wire [USER_WIDTH-1:0] output_0_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_1_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, - output wire output_1_axis_tvalid, - input wire output_1_axis_tready, - output wire output_1_axis_tlast, - output wire [ID_WIDTH-1:0] output_1_axis_tid, - output wire [DEST_WIDTH-1:0] output_1_axis_tdest, - output wire [USER_WIDTH-1:0] output_1_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_2_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, - output wire output_2_axis_tvalid, - input wire output_2_axis_tready, - output wire output_2_axis_tlast, - output wire [ID_WIDTH-1:0] output_2_axis_tid, - output wire [DEST_WIDTH-1:0] output_2_axis_tdest, - output wire [USER_WIDTH-1:0] output_2_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_3_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, - output wire output_3_axis_tvalid, - input wire output_3_axis_tready, - output wire output_3_axis_tlast, - output wire [ID_WIDTH-1:0] output_3_axis_tid, - output wire [DEST_WIDTH-1:0] output_3_axis_tdest, - output wire [USER_WIDTH-1:0] output_3_axis_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; - -// internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg [ID_WIDTH-1:0] output_axis_tid_int; -reg [DEST_WIDTH-1:0] output_axis_tdest_int; -reg [USER_WIDTH-1:0] output_axis_tuser_int; -wire output_axis_tready_int_early; - -assign input_axis_tready = input_axis_tready_reg; - -// mux for output control signals -reg current_output_tready; -reg current_output_tvalid; -always @* begin - case (select_reg) - 2'd0: begin - current_output_tvalid = output_0_axis_tvalid; - current_output_tready = output_0_axis_tready; - end - 2'd1: begin - current_output_tvalid = output_1_axis_tvalid; - current_output_tready = output_1_axis_tready; - end - 2'd2: begin - current_output_tvalid = output_2_axis_tvalid; - current_output_tready = output_2_axis_tready; - end - 2'd3: begin - current_output_tvalid = output_3_axis_tvalid; - current_output_tready = output_3_axis_tready; - end - default: begin - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_axis_tready_next = 1'b0; - - if (input_axis_tvalid & input_axis_tready) begin - // end of frame detection - if (input_axis_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_axis_tvalid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - end - - input_axis_tready_next = output_axis_tready_int_early & frame_next; - - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tid_int = input_axis_tid; - output_axis_tdest_int = input_axis_tdest; - output_axis_tuser_int = input_axis_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_axis_tready_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_axis_tready_reg <= input_axis_tready_next; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_0_axis_tvalid_reg = 1'b0, output_0_axis_tvalid_next; -reg output_1_axis_tvalid_reg = 1'b0, output_1_axis_tvalid_next; -reg output_2_axis_tvalid_reg = 1'b0, output_2_axis_tvalid_next; -reg output_3_axis_tvalid_reg = 1'b0, output_3_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign output_0_axis_tdata = output_axis_tdata_reg; -assign output_0_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_0_axis_tvalid = output_0_axis_tvalid_reg; -assign output_0_axis_tlast = output_axis_tlast_reg; -assign output_0_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_0_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_0_axis_tuser = USER_ENABLE ? output_axis_tuser_int : {USER_WIDTH{1'b0}}; - -assign output_1_axis_tdata = output_axis_tdata_reg; -assign output_1_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_1_axis_tvalid = output_1_axis_tvalid_reg; -assign output_1_axis_tlast = output_axis_tlast_reg; -assign output_1_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_1_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_1_axis_tuser = USER_ENABLE ? output_axis_tuser_int : {USER_WIDTH{1'b0}}; - -assign output_2_axis_tdata = output_axis_tdata_reg; -assign output_2_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_2_axis_tvalid = output_2_axis_tvalid_reg; -assign output_2_axis_tlast = output_axis_tlast_reg; -assign output_2_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_2_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_2_axis_tuser = USER_ENABLE ? output_axis_tuser_int : {USER_WIDTH{1'b0}}; - -assign output_3_axis_tdata = output_axis_tdata_reg; -assign output_3_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_3_axis_tvalid = output_3_axis_tvalid_reg; -assign output_3_axis_tlast = output_axis_tlast_reg; -assign output_3_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_3_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_3_axis_tuser = USER_ENABLE ? output_axis_tuser_int : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = current_output_tready | (~temp_axis_tvalid_reg & (~current_output_tvalid | ~output_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_0_axis_tvalid_next = output_0_axis_tvalid_reg; - output_1_axis_tvalid_next = output_1_axis_tvalid_reg; - output_2_axis_tvalid_next = output_2_axis_tvalid_reg; - output_3_axis_tvalid_next = output_3_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (output_axis_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_0_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd0); - output_1_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd1); - output_2_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd2); - output_3_axis_tvalid_next = output_axis_tvalid_int & (select_reg == 2'd3); - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_0_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd0); - output_1_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd1); - output_2_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd2); - output_3_axis_tvalid_next = temp_axis_tvalid_reg & (select_reg == 2'd3); - temp_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_0_axis_tvalid_reg <= 1'b0; - output_1_axis_tvalid_reg <= 1'b0; - output_2_axis_tvalid_reg <= 1'b0; - output_3_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; - end else begin - output_0_axis_tvalid_reg <= output_0_axis_tvalid_next; - output_1_axis_tvalid_reg <= output_1_axis_tvalid_next; - output_2_axis_tvalid_reg <= output_2_axis_tvalid_next; - output_3_axis_tvalid_reg <= output_3_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tid_reg <= output_axis_tid_int; - output_axis_tdest_reg <= output_axis_tdest_int; - output_axis_tuser_reg <= output_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tid_reg <= output_axis_tid_int; - temp_axis_tdest_reg <= output_axis_tdest_int; - temp_axis_tuser_reg <= output_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py index 1c481a82b..b6b780c7b 100755 --- a/tb/test_axis_demux_4.py +++ b/tb/test_axis_demux_4.py @@ -27,9 +27,10 @@ from myhdl import * import os import axis_ep +import math -module = 'axis_demux_4' -testbench = 'test_%s' % module +module = 'axis_demux' +testbench = 'test_%s_4' % module srcs = [] @@ -43,6 +44,7 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + M_COUNT = 4 DATA_WIDTH = 8 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) @@ -58,145 +60,85 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_0_axis_tready = Signal(bool(0)) - output_1_axis_tready = Signal(bool(0)) - output_2_axis_tready = Signal(bool(0)) - output_3_axis_tready = Signal(bool(0)) + m_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_axis_tready = ConcatSignal(*reversed(m_axis_tready_list)) enable = Signal(bool(0)) - select = Signal(intbv(0)[2:]) + drop = Signal(bool(0)) + select = Signal(intbv(0)[math.ceil(math.log(M_COUNT, 2)):]) # Outputs - input_axis_tready = Signal(bool(0)) + s_axis_tready = Signal(bool(0)) - output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_0_axis_tvalid = Signal(bool(0)) - output_0_axis_tlast = Signal(bool(0)) - output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_1_axis_tvalid = Signal(bool(0)) - output_1_axis_tlast = Signal(bool(0)) - output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_2_axis_tvalid = Signal(bool(0)) - output_2_axis_tlast = Signal(bool(0)) - output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_3_axis_tvalid = Signal(bool(0)) - output_3_axis_tlast = Signal(bool(0)) - output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_axis_tdata_list = [m_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_axis_tkeep_list = [m_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_axis_tvalid_list = [m_axis_tvalid(i) for i in range(M_COUNT)] + m_axis_tlast_list = [m_axis_tlast(i) for i in range(M_COUNT)] + m_axis_tid_list = [m_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_axis_tdest_list = [m_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_axis_tuser_list = [m_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks source_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] source = axis_ep.AXIStreamSource() source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) - sink_0 = axis_ep.AXIStreamSink() + for k in range(M_COUNT): + s = axis_ep.AXIStreamSink() + p = Signal(bool(0)) - sink_0_logic = sink_0.create_logic( - clk, - rst, - tdata=output_0_axis_tdata, - tkeep=output_0_axis_tkeep, - tvalid=output_0_axis_tvalid, - tready=output_0_axis_tready, - tlast=output_0_axis_tlast, - tid=output_0_axis_tid, - tdest=output_0_axis_tdest, - tuser=output_0_axis_tuser, - pause=sink_0_pause, - name='sink_0' - ) + sink_list.append(s) + sink_pause_list.append(p) - sink_1 = axis_ep.AXIStreamSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - tdata=output_1_axis_tdata, - tkeep=output_1_axis_tkeep, - tvalid=output_1_axis_tvalid, - tready=output_1_axis_tready, - tlast=output_1_axis_tlast, - tid=output_1_axis_tid, - tdest=output_1_axis_tdest, - tuser=output_1_axis_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = axis_ep.AXIStreamSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - tdata=output_2_axis_tdata, - tkeep=output_2_axis_tkeep, - tvalid=output_2_axis_tvalid, - tready=output_2_axis_tready, - tlast=output_2_axis_tlast, - tid=output_2_axis_tid, - tdest=output_2_axis_tdest, - tuser=output_2_axis_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = axis_ep.AXIStreamSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - tdata=output_3_axis_tdata, - tkeep=output_3_axis_tkeep, - tvalid=output_3_axis_tvalid, - tready=output_3_axis_tready, - tlast=output_3_axis_tlast, - tid=output_3_axis_tid, - tdest=output_3_axis_tdest, - tuser=output_3_axis_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + tdata=m_axis_tdata_list[k], + tkeep=m_axis_tkeep_list[k], + tvalid=m_axis_tvalid_list[k], + tready=m_axis_tready_list[k], + tlast=m_axis_tlast_list[k], + tid=m_axis_tid_list[k], + tdest=m_axis_tdest_list[k], + tuser=m_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -208,49 +150,26 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, - output_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tkeep=output_0_axis_tkeep, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tready=output_0_axis_tready, - output_0_axis_tlast=output_0_axis_tlast, - output_0_axis_tid=output_0_axis_tid, - output_0_axis_tdest=output_0_axis_tdest, - output_0_axis_tuser=output_0_axis_tuser, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tkeep=output_1_axis_tkeep, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tready=output_1_axis_tready, - output_1_axis_tlast=output_1_axis_tlast, - output_1_axis_tid=output_1_axis_tid, - output_1_axis_tdest=output_1_axis_tdest, - output_1_axis_tuser=output_1_axis_tuser, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tkeep=output_2_axis_tkeep, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tready=output_2_axis_tready, - output_2_axis_tlast=output_2_axis_tlast, - output_2_axis_tid=output_2_axis_tid, - output_2_axis_tdest=output_2_axis_tdest, - output_2_axis_tuser=output_2_axis_tuser, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tkeep=output_3_axis_tkeep, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tready=output_3_axis_tready, - output_3_axis_tlast=output_3_axis_tlast, - output_3_axis_tid=output_3_axis_tid, - output_3_axis_tdest=output_3_axis_tdest, - output_3_axis_tuser=output_3_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, enable=enable, + drop=drop, select=select ) @@ -271,6 +190,7 @@ def bench(): yield clk.posedge enable.next = True + drop.next = False yield clk.posedge print("test 1: select port 0") @@ -289,8 +209,8 @@ def bench(): source.send(test_frame) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame @@ -313,8 +233,8 @@ def bench(): source.send(test_frame) - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame @@ -346,13 +266,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame1 - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame2 @@ -385,17 +305,17 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid: + while s_axis_tvalid: yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -428,7 +348,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid: + while s_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -437,13 +357,13 @@ def bench(): yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -476,33 +396,90 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid: - sink_0_pause.next = True - sink_1_pause.next = True - sink_2_pause.next = True - sink_3_pause.next = True + while s_axis_tvalid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_0_pause.next = False - sink_1_pause.next = False - sink_2_pause.next = False - sink_3_pause.next = False + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 yield delay(100) + yield clk.posedge + print("test 7: enable") + current_test.next = 7 + + enable.next = False + select.next = 0 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1 + ) + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + enable.next = True + + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 8: drop") + current_test.next = 8 + + drop.next = True + select.next = 0 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=8, + dest=1 + ) + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + drop.next = False + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_demux_4.v b/tb/test_axis_demux_4.v index 99d09f115..b58507609 100644 --- a/tb/test_axis_demux_4.v +++ b/tb/test_axis_demux_4.v @@ -27,11 +27,12 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_demux_4 + * Testbench for axis_demux */ module test_axis_demux_4; // Parameters +parameter M_COUNT = 4; parameter DATA_WIDTH = 8; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); @@ -47,53 +48,30 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; +reg [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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; -reg output_0_axis_tready = 0; -reg output_1_axis_tready = 0; -reg output_2_axis_tready = 0; -reg output_3_axis_tready = 0; +reg [M_COUNT-1:0] m_axis_tready = 0; reg enable = 0; -reg [1:0] select = 0; +reg drop = 0; +reg [$clog2(M_COUNT)-1:0] select = 0; // Outputs -wire input_axis_tready; +wire s_axis_tready; -wire [DATA_WIDTH-1:0] output_0_axis_tdata; -wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; -wire output_0_axis_tvalid; -wire output_0_axis_tlast; -wire [ID_WIDTH-1:0] output_0_axis_tid; -wire [DEST_WIDTH-1:0] output_0_axis_tdest; -wire [USER_WIDTH-1:0] output_0_axis_tuser; -wire [DATA_WIDTH-1:0] output_1_axis_tdata; -wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; -wire output_1_axis_tvalid; -wire output_1_axis_tlast; -wire [ID_WIDTH-1:0] output_1_axis_tid; -wire [DEST_WIDTH-1:0] output_1_axis_tdest; -wire [USER_WIDTH-1:0] output_1_axis_tuser; -wire [DATA_WIDTH-1:0] output_2_axis_tdata; -wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; -wire output_2_axis_tvalid; -wire output_2_axis_tlast; -wire [ID_WIDTH-1:0] output_2_axis_tid; -wire [DEST_WIDTH-1:0] output_2_axis_tdest; -wire [USER_WIDTH-1:0] output_2_axis_tuser; -wire [DATA_WIDTH-1:0] output_3_axis_tdata; -wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; -wire output_3_axis_tvalid; -wire output_3_axis_tlast; -wire [ID_WIDTH-1:0] output_3_axis_tid; -wire [DEST_WIDTH-1:0] output_3_axis_tdest; -wire [USER_WIDTH-1:0] output_3_axis_tuser; +wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep; +wire [M_COUNT-1:0] m_axis_tvalid; +wire [M_COUNT-1:0] m_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -101,50 +79,27 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_0_axis_tready, - output_1_axis_tready, - output_2_axis_tready, - output_3_axis_tready, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready, enable, + drop, select ); $to_myhdl( - input_axis_tready, - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_0_axis_tid, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_1_axis_tid, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_2_axis_tid, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast, - output_3_axis_tid, - output_3_axis_tdest, - output_3_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -152,7 +107,8 @@ initial begin $dumpvars(0, test_axis_demux_4); end -axis_demux_4 #( +axis_demux #( + .M_COUNT(M_COUNT), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), @@ -167,49 +123,26 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), // AXI outputs - .output_0_axis_tdata(output_0_axis_tdata), - .output_0_axis_tkeep(output_0_axis_tkeep), - .output_0_axis_tvalid(output_0_axis_tvalid), - .output_0_axis_tready(output_0_axis_tready), - .output_0_axis_tlast(output_0_axis_tlast), - .output_0_axis_tid(output_0_axis_tid), - .output_0_axis_tdest(output_0_axis_tdest), - .output_0_axis_tuser(output_0_axis_tuser), - .output_1_axis_tdata(output_1_axis_tdata), - .output_1_axis_tkeep(output_1_axis_tkeep), - .output_1_axis_tvalid(output_1_axis_tvalid), - .output_1_axis_tready(output_1_axis_tready), - .output_1_axis_tlast(output_1_axis_tlast), - .output_1_axis_tid(output_1_axis_tid), - .output_1_axis_tdest(output_1_axis_tdest), - .output_1_axis_tuser(output_1_axis_tuser), - .output_2_axis_tdata(output_2_axis_tdata), - .output_2_axis_tkeep(output_2_axis_tkeep), - .output_2_axis_tvalid(output_2_axis_tvalid), - .output_2_axis_tready(output_2_axis_tready), - .output_2_axis_tlast(output_2_axis_tlast), - .output_2_axis_tid(output_2_axis_tid), - .output_2_axis_tdest(output_2_axis_tdest), - .output_2_axis_tuser(output_2_axis_tuser), - .output_3_axis_tdata(output_3_axis_tdata), - .output_3_axis_tkeep(output_3_axis_tkeep), - .output_3_axis_tvalid(output_3_axis_tvalid), - .output_3_axis_tready(output_3_axis_tready), - .output_3_axis_tlast(output_3_axis_tlast), - .output_3_axis_tid(output_3_axis_tid), - .output_3_axis_tdest(output_3_axis_tdest), - .output_3_axis_tuser(output_3_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Control .enable(enable), + .drop(drop), .select(select) ); diff --git a/tb/test_axis_demux_4_64.py b/tb/test_axis_demux_4_64.py index ea00eced1..5c91bc39d 100755 --- a/tb/test_axis_demux_4_64.py +++ b/tb/test_axis_demux_4_64.py @@ -27,9 +27,10 @@ from myhdl import * import os import axis_ep +import math -module = 'axis_demux_4' -testbench = 'test_%s_64' % module +module = 'axis_demux' +testbench = 'test_%s_4_64' % module srcs = [] @@ -43,6 +44,7 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + M_COUNT = 4 DATA_WIDTH = 64 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) @@ -58,145 +60,85 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_0_axis_tready = Signal(bool(0)) - output_1_axis_tready = Signal(bool(0)) - output_2_axis_tready = Signal(bool(0)) - output_3_axis_tready = Signal(bool(0)) + m_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_axis_tready = ConcatSignal(*reversed(m_axis_tready_list)) enable = Signal(bool(0)) - select = Signal(intbv(0)[2:]) + drop = Signal(bool(0)) + select = Signal(intbv(0)[math.ceil(math.log(M_COUNT, 2)):]) # Outputs - input_axis_tready = Signal(bool(0)) + s_axis_tready = Signal(bool(0)) - output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_0_axis_tvalid = Signal(bool(0)) - output_0_axis_tlast = Signal(bool(0)) - output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_1_axis_tvalid = Signal(bool(0)) - output_1_axis_tlast = Signal(bool(0)) - output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_2_axis_tvalid = Signal(bool(0)) - output_2_axis_tlast = Signal(bool(0)) - output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_3_axis_tvalid = Signal(bool(0)) - output_3_axis_tlast = Signal(bool(0)) - output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_axis_tdata_list = [m_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_axis_tkeep_list = [m_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_axis_tvalid_list = [m_axis_tvalid(i) for i in range(M_COUNT)] + m_axis_tlast_list = [m_axis_tlast(i) for i in range(M_COUNT)] + m_axis_tid_list = [m_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_axis_tdest_list = [m_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_axis_tuser_list = [m_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks source_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] source = axis_ep.AXIStreamSource() source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) - sink_0 = axis_ep.AXIStreamSink() + for k in range(M_COUNT): + s = axis_ep.AXIStreamSink() + p = Signal(bool(0)) - sink_0_logic = sink_0.create_logic( - clk, - rst, - tdata=output_0_axis_tdata, - tkeep=output_0_axis_tkeep, - tvalid=output_0_axis_tvalid, - tready=output_0_axis_tready, - tlast=output_0_axis_tlast, - tid=output_0_axis_tid, - tdest=output_0_axis_tdest, - tuser=output_0_axis_tuser, - pause=sink_0_pause, - name='sink_0' - ) + sink_list.append(s) + sink_pause_list.append(p) - sink_1 = axis_ep.AXIStreamSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - tdata=output_1_axis_tdata, - tkeep=output_1_axis_tkeep, - tvalid=output_1_axis_tvalid, - tready=output_1_axis_tready, - tlast=output_1_axis_tlast, - tid=output_1_axis_tid, - tdest=output_1_axis_tdest, - tuser=output_1_axis_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = axis_ep.AXIStreamSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - tdata=output_2_axis_tdata, - tkeep=output_2_axis_tkeep, - tvalid=output_2_axis_tvalid, - tready=output_2_axis_tready, - tlast=output_2_axis_tlast, - tid=output_2_axis_tid, - tdest=output_2_axis_tdest, - tuser=output_2_axis_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = axis_ep.AXIStreamSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - tdata=output_3_axis_tdata, - tkeep=output_3_axis_tkeep, - tvalid=output_3_axis_tvalid, - tready=output_3_axis_tready, - tlast=output_3_axis_tlast, - tid=output_3_axis_tid, - tdest=output_3_axis_tdest, - tuser=output_3_axis_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + tdata=m_axis_tdata_list[k], + tkeep=m_axis_tkeep_list[k], + tvalid=m_axis_tvalid_list[k], + tready=m_axis_tready_list[k], + tlast=m_axis_tlast_list[k], + tid=m_axis_tid_list[k], + tdest=m_axis_tdest_list[k], + tuser=m_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -208,49 +150,26 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, - output_0_axis_tdata=output_0_axis_tdata, - output_0_axis_tkeep=output_0_axis_tkeep, - output_0_axis_tvalid=output_0_axis_tvalid, - output_0_axis_tready=output_0_axis_tready, - output_0_axis_tlast=output_0_axis_tlast, - output_0_axis_tid=output_0_axis_tid, - output_0_axis_tdest=output_0_axis_tdest, - output_0_axis_tuser=output_0_axis_tuser, - output_1_axis_tdata=output_1_axis_tdata, - output_1_axis_tkeep=output_1_axis_tkeep, - output_1_axis_tvalid=output_1_axis_tvalid, - output_1_axis_tready=output_1_axis_tready, - output_1_axis_tlast=output_1_axis_tlast, - output_1_axis_tid=output_1_axis_tid, - output_1_axis_tdest=output_1_axis_tdest, - output_1_axis_tuser=output_1_axis_tuser, - output_2_axis_tdata=output_2_axis_tdata, - output_2_axis_tkeep=output_2_axis_tkeep, - output_2_axis_tvalid=output_2_axis_tvalid, - output_2_axis_tready=output_2_axis_tready, - output_2_axis_tlast=output_2_axis_tlast, - output_2_axis_tid=output_2_axis_tid, - output_2_axis_tdest=output_2_axis_tdest, - output_2_axis_tuser=output_2_axis_tuser, - output_3_axis_tdata=output_3_axis_tdata, - output_3_axis_tkeep=output_3_axis_tkeep, - output_3_axis_tvalid=output_3_axis_tvalid, - output_3_axis_tready=output_3_axis_tready, - output_3_axis_tlast=output_3_axis_tlast, - output_3_axis_tid=output_3_axis_tid, - output_3_axis_tdest=output_3_axis_tdest, - output_3_axis_tuser=output_3_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, enable=enable, + drop=drop, select=select ) @@ -271,6 +190,7 @@ def bench(): yield clk.posedge enable.next = True + drop.next = False yield clk.posedge print("test 1: select port 0") @@ -289,8 +209,8 @@ def bench(): source.send(test_frame) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame @@ -313,8 +233,8 @@ def bench(): source.send(test_frame) - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame @@ -346,13 +266,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame1 - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame2 @@ -385,17 +305,17 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid: + while s_axis_tvalid: yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -428,7 +348,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid: + while s_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -437,13 +357,13 @@ def bench(): yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -476,33 +396,90 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid: - sink_0_pause.next = True - sink_1_pause.next = True - sink_2_pause.next = True - sink_3_pause.next = True + while s_axis_tvalid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_0_pause.next = False - sink_1_pause.next = False - sink_2_pause.next = False - sink_3_pause.next = False + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 yield delay(100) + yield clk.posedge + print("test 7: enable") + current_test.next = 7 + + enable.next = False + select.next = 0 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1 + ) + + source.send(test_frame) + + yield delay(100) + + assert sink_list[0].empty() + + enable.next = True + + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 8: drop") + current_test.next = 8 + + drop.next = True + select.next = 0 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=8, + dest=1 + ) + + source.send(test_frame) + + yield delay(100) + + assert sink_list[0].empty() + + drop.next = False + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_demux_4_64.v b/tb/test_axis_demux_4_64.v index 9eb86ec0c..2fb7d8894 100644 --- a/tb/test_axis_demux_4_64.v +++ b/tb/test_axis_demux_4_64.v @@ -27,11 +27,12 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_demux_4 + * Testbench for axis_demux */ module test_axis_demux_4_64; // Parameters +parameter M_COUNT = 4; parameter DATA_WIDTH = 64; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); @@ -47,53 +48,30 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; +reg [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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; -reg output_0_axis_tready = 0; -reg output_1_axis_tready = 0; -reg output_2_axis_tready = 0; -reg output_3_axis_tready = 0; +reg [M_COUNT-1:0] m_axis_tready = 0; reg enable = 0; -reg [1:0] select = 0; +reg drop = 0; +reg [$clog2(M_COUNT)-1:0] select = 0; // Outputs -wire input_axis_tready; +wire s_axis_tready; -wire [DATA_WIDTH-1:0] output_0_axis_tdata; -wire [KEEP_WIDTH-1:0] output_0_axis_tkeep; -wire output_0_axis_tvalid; -wire output_0_axis_tlast; -wire [ID_WIDTH-1:0] output_0_axis_tid; -wire [DEST_WIDTH-1:0] output_0_axis_tdest; -wire [USER_WIDTH-1:0] output_0_axis_tuser; -wire [DATA_WIDTH-1:0] output_1_axis_tdata; -wire [KEEP_WIDTH-1:0] output_1_axis_tkeep; -wire output_1_axis_tvalid; -wire output_1_axis_tlast; -wire [ID_WIDTH-1:0] output_1_axis_tid; -wire [DEST_WIDTH-1:0] output_1_axis_tdest; -wire [USER_WIDTH-1:0] output_1_axis_tuser; -wire [DATA_WIDTH-1:0] output_2_axis_tdata; -wire [KEEP_WIDTH-1:0] output_2_axis_tkeep; -wire output_2_axis_tvalid; -wire output_2_axis_tlast; -wire [ID_WIDTH-1:0] output_2_axis_tid; -wire [DEST_WIDTH-1:0] output_2_axis_tdest; -wire [USER_WIDTH-1:0] output_2_axis_tuser; -wire [DATA_WIDTH-1:0] output_3_axis_tdata; -wire [KEEP_WIDTH-1:0] output_3_axis_tkeep; -wire output_3_axis_tvalid; -wire output_3_axis_tlast; -wire [ID_WIDTH-1:0] output_3_axis_tid; -wire [DEST_WIDTH-1:0] output_3_axis_tdest; -wire [USER_WIDTH-1:0] output_3_axis_tuser; +wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep; +wire [M_COUNT-1:0] m_axis_tvalid; +wire [M_COUNT-1:0] m_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -101,50 +79,27 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_0_axis_tready, - output_1_axis_tready, - output_2_axis_tready, - output_3_axis_tready, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready, enable, + drop, select ); $to_myhdl( - input_axis_tready, - output_0_axis_tdata, - output_0_axis_tkeep, - output_0_axis_tvalid, - output_0_axis_tlast, - output_0_axis_tid, - output_0_axis_tdest, - output_0_axis_tuser, - output_1_axis_tdata, - output_1_axis_tkeep, - output_1_axis_tvalid, - output_1_axis_tlast, - output_1_axis_tid, - output_1_axis_tdest, - output_1_axis_tuser, - output_2_axis_tdata, - output_2_axis_tkeep, - output_2_axis_tvalid, - output_2_axis_tlast, - output_2_axis_tid, - output_2_axis_tdest, - output_2_axis_tuser, - output_3_axis_tdata, - output_3_axis_tkeep, - output_3_axis_tvalid, - output_3_axis_tlast, - output_3_axis_tid, - output_3_axis_tdest, - output_3_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -152,7 +107,8 @@ initial begin $dumpvars(0, test_axis_demux_4_64); end -axis_demux_4 #( +axis_demux #( + .M_COUNT(M_COUNT), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), @@ -167,49 +123,26 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), // AXI outputs - .output_0_axis_tdata(output_0_axis_tdata), - .output_0_axis_tkeep(output_0_axis_tkeep), - .output_0_axis_tvalid(output_0_axis_tvalid), - .output_0_axis_tready(output_0_axis_tready), - .output_0_axis_tlast(output_0_axis_tlast), - .output_0_axis_tid(output_0_axis_tid), - .output_0_axis_tdest(output_0_axis_tdest), - .output_0_axis_tuser(output_0_axis_tuser), - .output_1_axis_tdata(output_1_axis_tdata), - .output_1_axis_tkeep(output_1_axis_tkeep), - .output_1_axis_tvalid(output_1_axis_tvalid), - .output_1_axis_tready(output_1_axis_tready), - .output_1_axis_tlast(output_1_axis_tlast), - .output_1_axis_tid(output_1_axis_tid), - .output_1_axis_tdest(output_1_axis_tdest), - .output_1_axis_tuser(output_1_axis_tuser), - .output_2_axis_tdata(output_2_axis_tdata), - .output_2_axis_tkeep(output_2_axis_tkeep), - .output_2_axis_tvalid(output_2_axis_tvalid), - .output_2_axis_tready(output_2_axis_tready), - .output_2_axis_tlast(output_2_axis_tlast), - .output_2_axis_tid(output_2_axis_tid), - .output_2_axis_tdest(output_2_axis_tdest), - .output_2_axis_tuser(output_2_axis_tuser), - .output_3_axis_tdata(output_3_axis_tdata), - .output_3_axis_tkeep(output_3_axis_tkeep), - .output_3_axis_tvalid(output_3_axis_tvalid), - .output_3_axis_tready(output_3_axis_tready), - .output_3_axis_tlast(output_3_axis_tlast), - .output_3_axis_tid(output_3_axis_tid), - .output_3_axis_tdest(output_3_axis_tdest), - .output_3_axis_tuser(output_3_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Control .enable(enable), + .drop(drop), .select(select) ); From 3bbf8524d67a06971d9a75c2bb01ed8b9b890eb0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 22:21:31 -0700 Subject: [PATCH 426/617] Compute DEST_WIDTH --- tb/test_axis_switch_4x4.py | 3 ++- tb/test_axis_switch_4x4.v | 2 +- tb/test_axis_switch_4x4_64.py | 20 +++++++------------- tb/test_axis_switch_4x4_64.v | 2 +- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py index f8663fbe7..6a25eb49e 100755 --- a/tb/test_axis_switch_4x4.py +++ b/tb/test_axis_switch_4x4.py @@ -27,6 +27,7 @@ from myhdl import * import os import axis_ep +import math module = 'axis_switch' testbench = 'test_%s_4x4' % module @@ -53,7 +54,7 @@ def bench(): KEEP_WIDTH = (DATA_WIDTH/8) ID_ENABLE = 1 ID_WIDTH = 8 - DEST_WIDTH = 3 + DEST_WIDTH = math.ceil(math.log(M_COUNT+1, 2)) USER_ENABLE = 1 USER_WIDTH = 1 M_BASE = [0, 1, 2, 3] diff --git a/tb/test_axis_switch_4x4.v b/tb/test_axis_switch_4x4.v index 7dad71d0d..b30419a84 100644 --- a/tb/test_axis_switch_4x4.v +++ b/tb/test_axis_switch_4x4.v @@ -39,7 +39,7 @@ parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); parameter ID_ENABLE = 1; parameter ID_WIDTH = 8; -parameter DEST_WIDTH = 3; +parameter DEST_WIDTH = $clog2(M_COUNT+1); parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; parameter M_BASE = {32'd3, 32'd2, 32'd1, 32'd0}; diff --git a/tb/test_axis_switch_4x4_64.py b/tb/test_axis_switch_4x4_64.py index 41f709699..ce53db690 100755 --- a/tb/test_axis_switch_4x4_64.py +++ b/tb/test_axis_switch_4x4_64.py @@ -27,6 +27,7 @@ from myhdl import * import os import axis_ep +import math module = 'axis_switch' testbench = 'test_%s_4x4_64' % module @@ -53,21 +54,14 @@ def bench(): KEEP_WIDTH = (DATA_WIDTH/8) ID_ENABLE = 1 ID_WIDTH = 8 - DEST_WIDTH = 3 + DEST_WIDTH = math.ceil(math.log(M_COUNT+1, 2)) USER_ENABLE = 1 USER_WIDTH = 1 - OUT_0_BASE = 0 - OUT_0_TOP = 0 - OUT_0_CONNECT = 0xf - OUT_1_BASE = 1 - OUT_1_TOP = 1 - OUT_1_CONNECT = 0xf - OUT_2_BASE = 2 - OUT_2_TOP = 2 - OUT_2_CONNECT = 0xf - OUT_3_BASE = 3 - OUT_3_TOP = 3 - OUT_3_CONNECT = 0xf + M_BASE = [0, 1, 2, 3] + M_TOP = [0, 1, 2, 3] + M_CONNECT = [0b1111]*M_COUNT + S_REG_TYPE = 0 + M_REG_TYPE = 2 ARB_TYPE = "ROUND_ROBIN" LSB_PRIORITY = "HIGH" diff --git a/tb/test_axis_switch_4x4_64.v b/tb/test_axis_switch_4x4_64.v index 7f43ac26f..b107ac7a2 100644 --- a/tb/test_axis_switch_4x4_64.v +++ b/tb/test_axis_switch_4x4_64.v @@ -39,7 +39,7 @@ parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); parameter ID_ENABLE = 1; parameter ID_WIDTH = 8; -parameter DEST_WIDTH = 3; +parameter DEST_WIDTH = $clog2(M_COUNT+1); parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; parameter M_BASE = {32'd3, 32'd2, 32'd1, 32'd0}; From 2bb9f11c9e1b5a8ca75cafb6bb05b55dd9fdefeb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 22:24:27 -0700 Subject: [PATCH 427/617] Use logical operators --- rtl/axis_arb_mux.v | 4 ++-- rtl/axis_mux.v | 4 ++-- rtl/axis_register.v | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rtl/axis_arb_mux.v b/rtl/axis_arb_mux.v index 3e2ce62b4..36434d9f3 100644 --- a/rtl/axis_arb_mux.v +++ b/rtl/axis_arb_mux.v @@ -174,7 +174,7 @@ assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign m_axis_tready_int_early = m_axis_tready | (~temp_m_axis_tvalid_reg & (~m_axis_tvalid_reg | ~m_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source @@ -187,7 +187,7 @@ always @* begin if (m_axis_tready_int_reg) begin // input is ready - if (m_axis_tready | ~m_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; diff --git a/rtl/axis_mux.v b/rtl/axis_mux.v index fcec24676..3a8a8d139 100644 --- a/rtl/axis_mux.v +++ b/rtl/axis_mux.v @@ -182,7 +182,7 @@ assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign m_axis_tready_int_early = m_axis_tready | (~temp_m_axis_tvalid_reg & (~m_axis_tvalid_reg | ~m_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source @@ -195,7 +195,7 @@ always @* begin if (m_axis_tready_int_reg) begin // input is ready - if (m_axis_tready | ~m_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; diff --git a/rtl/axis_register.v b/rtl/axis_register.v index a98441964..251bcde20 100644 --- a/rtl/axis_register.v +++ b/rtl/axis_register.v @@ -112,7 +112,7 @@ if (REG_TYPE > 1) begin assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) - wire s_axis_tready_early = m_axis_tready | (~temp_m_axis_tvalid_reg & (~m_axis_tvalid_reg | ~s_axis_tvalid)); + wire s_axis_tready_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !s_axis_tvalid)); always @* begin // transfer sink ready state to source @@ -125,7 +125,7 @@ if (REG_TYPE > 1) begin if (s_axis_tready_reg) begin // input is ready - if (m_axis_tready | ~m_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output m_axis_tvalid_next = s_axis_tvalid; store_axis_input_to_output = 1'b1; From 3d2efef93aa89b7e036afe2584a6877017e91671 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 22:25:02 -0700 Subject: [PATCH 428/617] Update readme --- README.md | 50 +++++++++++++++++++------------------------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 5c031168e..f2ea22578 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,10 @@ related by an integer multiple (e.g. 2 words and 6 words, but not 4 words and 6 words). Wait states will be inserted on the wider bus side when necessary. -### axis_arb_mux_N module +### axis_arb_mux module -Frame-aware AXI stream arbitrated muliplexer with parametrizable data width. -Supports priority and round-robin arbitration. - -Can be generated with arbitrary port counts with axis_arb_mux.py. +Frame-aware AXI stream arbitrated muliplexer with parametrizable data width +and port count. Supports priority and round-robin arbitration. ### axis_async_fifo module @@ -60,11 +58,10 @@ width. Can be generated with arbitrary port counts with axis_crosspoint.py. -### axis_demux_N module +### axis_demux module -Frame-aware AXI stream demuliplexer with parametrizable data width. - -Can be generated with arbitrary port counts with axis_demux.py. +Frame-aware AXI stream demuliplexer with parametrizable data width and port +count. ### axis_fifo module @@ -76,11 +73,10 @@ Supports power of two depths only. Basic frame-based synchronous FIFO with parametrizable data width and depth. Supports power of two depths only. -### axis_frame_join_N module +### axis_frame_join module -Frame joiner with optional tag. 8 bit data path only. - -Can be generated with arbitrary port counts with axis_frame_join.py. +Frame joiner with optional tag and parametrizable port count. 8 bit data path +only. ### axis_frame_length_adjust module @@ -101,11 +97,10 @@ Length limits are configurable at run time. AXI stream to LocalLink bridge. -### axis_mux_N module +### axis_mux module -Frame-aware AXI stream muliplexer with parametrizable data width. - -Can be generated with arbitrary port counts with axis_mux.py. +Frame-aware AXI stream muliplexer with parametrizable data width and port +count. ### axis_rate_limit module @@ -135,11 +130,9 @@ AXI stream interface. Trigger signal used to reset and dump counts out of AXI interface, along with tag value. Use with axis_frame_join_N to form a single monolithic frame from multiple monitored points with the same trigger. -### axis_switch_NxN module +### axis_switch module -Frame-aware AXI stream switch with parametrizable data width. - -Can be generated with arbitrary port counts with axis_switch.py. +Frame-aware AXI stream switch with parametrizable data width and port count. ### axis_tap module @@ -185,20 +178,16 @@ Parametrizable priority encoder. arbiter.v : General-purpose parametrizable arbiter axis_adapter.v : Parametrizable bus width adapter - axis_arb_mux.py : Arbitrated multiplexer generator - axis_arb_mux_4.v : 4 port arbitrated multiplexer + axis_arb_mux.v : Parametrizable arbitrated multiplexer axis_async_fifo.v : Asynchronous FIFO axis_async_frame_fifo.v : Asynchronous frame FIFO axis_cobs_decode.v : COBS decoder axis_cobs_encode.v : COBS encoder - axis_crosspoint.py : Crosspoint switch generator - axis_crosspoint_4x4.v : 4x4 crosspoint switch - axis_demux.py : Demultiplexer generator - axis_demux_4.v : 4 port demultiplexer + axis_crosspoint.v : Parametrizable crosspoint switch + axis_demux.v : Parametrizable demultiplexer axis_fifo.v : Synchronous FIFO axis_frame_fifo.v : Synchronous frame FIFO - axis_frame_join.py : Frame joiner generator - axis_frame_join_4.v : 4 port frame joiner + axis_frame_join.v : Parametrizable frame joiner axis_frame_length_adjust.v : Frame length adjuster axis_frame_length_adjust_fifo.v : Frame length adjuster with FIFO axis_ll_bridge.v : AXI stream to LocalLink bridge @@ -208,8 +197,7 @@ Parametrizable priority encoder. axis_register.v : AXI Stream register axis_srl_fifo.v : SRL-based FIFO axis_srl_register.v : SRL-based register - axis_switch.py : AXI stream switch generator - axis_switch_4x4.v : 4x4 port AXI stream switch + axis_switch.v : Parametrizable AXI stream switch axis_stat_counter.v : Statistics counter axis_tap.v : AXI stream tap ll_axis_bridge.v : LocalLink to AXI stream bridge From 36d0a8786f3663c7586709997d8d83db578dde5e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 24 Oct 2018 23:16:06 -0700 Subject: [PATCH 429/617] Merge axis_fifo and axis_frame_fifo, rename ports --- rtl/axis_fifo.v | 196 +++++++++++++++++------ rtl/axis_frame_fifo.v | 284 ---------------------------------- tb/test_axis_fifo.py | 105 +++++++------ tb/test_axis_fifo.v | 112 ++++++++------ tb/test_axis_fifo_64.py | 105 +++++++------ tb/test_axis_fifo_64.v | 112 ++++++++------ tb/test_axis_frame_fifo.py | 106 ++++++------- tb/test_axis_frame_fifo.v | 104 +++++++------ tb/test_axis_frame_fifo_64.py | 106 ++++++------- tb/test_axis_frame_fifo_64.v | 104 +++++++------ 10 files changed, 599 insertions(+), 735 deletions(-) delete mode 100644 rtl/axis_frame_fifo.v diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index 93e62c382..37e249f4b 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -41,7 +41,12 @@ module axis_fifo # parameter DEST_ENABLE = 0, parameter DEST_WIDTH = 8, parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1 + parameter USER_WIDTH = 1, + parameter FRAME_FIFO = 0, + parameter USER_BAD_FRAME_VALUE = 1'b1, + parameter USER_BAD_FRAME_MASK = 1'b1, + parameter DROP_BAD_FRAME = 0, + parameter DROP_WHEN_FULL = 0 ) ( input wire clk, @@ -50,28 +55,58 @@ module axis_fifo # /* * 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * Status + */ + output wire overflow, + output wire bad_frame, + output wire good_frame ); +// check configuration +initial begin + if (FRAME_FIFO && !LAST_ENABLE) begin + $error("Error: FRAME_FIFO set requires LAST_ENABLE set"); + $finish; + end + + if (DROP_BAD_FRAME && !FRAME_FIFO) begin + $error("Error: DROP_BAD_FRAME set requires FRAME_FIFO set"); + $finish; + end + + if (DROP_WHEN_FULL && !FRAME_FIFO) begin + $error("Error: DROP_WHEN_FULL set requires FRAME_FIFO set"); + $finish; + end + + if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & {USER_WIDTH{1'b1}}) == 0) begin + $error("Error: Invalid USER_BAD_FRAME_MASK value"); + $finish; + end +end + localparam KEEP_OFFSET = DATA_WIDTH; localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); localparam ID_OFFSET = LAST_OFFSET + (LAST_ENABLE ? 1 : 0); @@ -80,6 +115,7 @@ localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; @@ -88,54 +124,100 @@ reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; reg [WIDTH-1:0] mem_read_data_reg; reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; -wire [WIDTH-1:0] input_axis; +wire [WIDTH-1:0] s_axis; -reg [WIDTH-1:0] output_axis_reg; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg [WIDTH-1:0] m_axis_reg; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; // full when first MSB different but rest same wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && (wr_ptr_reg[ADDR_WIDTH-1:0] == rd_ptr_reg[ADDR_WIDTH-1:0])); // empty when pointers match exactly wire empty = wr_ptr_reg == rd_ptr_reg; +// overflow within packet +wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); // control signals reg write; reg read; reg store_output; -assign input_axis_tready = ~full; +reg drop_frame_reg = 1'b0, drop_frame_next; +reg overflow_reg = 1'b0, overflow_next; +reg bad_frame_reg = 1'b0, bad_frame_next; +reg good_frame_reg = 1'b0, good_frame_next; + +assign s_axis_tready = (!full || DROP_WHEN_FULL); generate - assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; - if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; - if (LAST_ENABLE) assign input_axis[LAST_OFFSET] = input_axis_tlast; - if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; - if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; - if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; + assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata; + if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep; + if (LAST_ENABLE) assign s_axis[LAST_OFFSET] = s_axis_tlast; + if (ID_ENABLE) assign s_axis[ID_OFFSET +: ID_WIDTH] = s_axis_tid; + if (DEST_ENABLE) assign s_axis[DEST_OFFSET +: DEST_WIDTH] = s_axis_tdest; + if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser; endgenerate -assign output_axis_tvalid = output_axis_tvalid_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; -assign output_axis_tdata = output_axis_reg[DATA_WIDTH-1:0]; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_reg[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; -assign output_axis_tlast = LAST_ENABLE ? output_axis_reg[LAST_OFFSET] : 1'b1; -assign output_axis_tid = ID_ENABLE ? output_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; +assign m_axis_tdata = m_axis_reg[DATA_WIDTH-1:0]; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_reg[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +assign m_axis_tlast = LAST_ENABLE ? m_axis_reg[LAST_OFFSET] : 1'b1; +assign m_axis_tid = ID_ENABLE ? m_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; + +assign overflow = overflow_reg; +assign bad_frame = bad_frame_reg; +assign good_frame = good_frame_reg; // Write logic always @* begin write = 1'b0; - wr_ptr_next = wr_ptr_reg; + drop_frame_next = 1'b0; + overflow_next = 1'b0; + bad_frame_next = 1'b0; + good_frame_next = 1'b0; - if (input_axis_tvalid) begin + wr_ptr_next = wr_ptr_reg; + wr_ptr_cur_next = wr_ptr_cur_reg; + + if (s_axis_tvalid) begin // input data valid - if (~full) begin + if (!full || DROP_WHEN_FULL) begin // not full, perform write - write = 1'b1; - wr_ptr_next = wr_ptr_reg + 1; + if (!FRAME_FIFO) begin + // normal FIFO mode + write = 1'b1; + wr_ptr_next = wr_ptr_reg + 1; + end else if (full || full_cur || drop_frame_reg) begin + // full, packet overflow, or currently dropping frame + // drop frame + drop_frame_next = 1'b1; + if (s_axis_tlast) begin + // end of frame, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + drop_frame_next = 1'b0; + overflow_next = 1'b1; + end + end else begin + write = 1'b1; + wr_ptr_cur_next = wr_ptr_cur_reg + 1; + if (s_axis_tlast) begin + // end of frame + if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin + // bad packet, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + bad_frame_next = 1'b1; + end else begin + // good packet, update write pointer + wr_ptr_next = wr_ptr_cur_reg + 1; + good_frame_next = 1'b1; + end + end + end end end end @@ -143,14 +225,30 @@ end always @(posedge clk) begin if (rst) begin wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; + + drop_frame_reg <= 1'b0; + overflow_reg <= 1'b0; + bad_frame_reg <= 1'b0; + good_frame_reg <= 1'b0; end else begin wr_ptr_reg <= wr_ptr_next; + wr_ptr_cur_reg <= wr_ptr_cur_next; + + drop_frame_reg <= drop_frame_next; + overflow_reg <= overflow_next; + bad_frame_reg <= bad_frame_next; + good_frame_reg <= good_frame_next; end - wr_addr_reg <= wr_ptr_next; + if (FRAME_FIFO) begin + wr_addr_reg <= wr_ptr_cur_next; + end else begin + wr_addr_reg <= wr_ptr_next; + end if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= input_axis; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= s_axis; end end @@ -162,9 +260,9 @@ always @* begin mem_read_data_valid_next = mem_read_data_valid_reg; - if (store_output | ~mem_read_data_valid_reg) begin + if (store_output || !mem_read_data_valid_reg) begin // output data not valid OR currently being transferred - if (~empty) begin + if (!empty) begin // not empty, perform read read = 1'b1; mem_read_data_valid_next = 1'b1; @@ -196,23 +294,23 @@ end always @* begin store_output = 1'b0; - output_axis_tvalid_next = output_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; - if (output_axis_tready | ~output_axis_tvalid) begin + if (m_axis_tready || !m_axis_tvalid) begin store_output = 1'b1; - output_axis_tvalid_next = mem_read_data_valid_reg; + m_axis_tvalid_next = mem_read_data_valid_reg; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; end if (store_output) begin - output_axis_reg <= mem_read_data_reg; + m_axis_reg <= mem_read_data_reg; end end diff --git a/rtl/axis_frame_fifo.v b/rtl/axis_frame_fifo.v deleted file mode 100644 index 9af6d286f..000000000 --- a/rtl/axis_frame_fifo.v +++ /dev/null @@ -1,284 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 frame FIFO - */ -module axis_frame_fifo # -( - parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1, - parameter USER_BAD_FRAME_VALUE = 1'b1, - parameter USER_BAD_FRAME_MASK = 1'b1, - parameter DROP_BAD_FRAME = 1, - parameter DROP_WHEN_FULL = 0 -) -( - 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, - - /* - * AXI output - */ - 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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser, - - /* - * Status - */ - output wire overflow, - output wire bad_frame, - output wire good_frame -); - -localparam KEEP_OFFSET = DATA_WIDTH; -localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); -localparam ID_OFFSET = LAST_OFFSET + 1; -localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0); -localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); -localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); - -reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; -reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; -reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; - -reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [WIDTH-1:0] mem_read_data_reg; -reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; - -wire [WIDTH-1:0] input_axis; - -reg [WIDTH-1:0] output_axis_reg; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; - -// full when first MSB different but rest same -wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && - (wr_ptr_reg[ADDR_WIDTH-1:0] == rd_ptr_reg[ADDR_WIDTH-1:0])); -// empty when pointers match exactly -wire empty = wr_ptr_reg == rd_ptr_reg; -// overflow within packet -wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && - (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); - -// control signals -reg write; -reg read; -reg store_output; - -reg drop_frame_reg = 1'b0, drop_frame_next; -reg overflow_reg = 1'b0, overflow_next; -reg bad_frame_reg = 1'b0, bad_frame_next; -reg good_frame_reg = 1'b0, good_frame_next; - -assign input_axis_tready = (~full | DROP_WHEN_FULL); - -generate - assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; - if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; - assign input_axis[LAST_OFFSET] = input_axis_tlast; - if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; - if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; - if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; -endgenerate - -assign output_axis_tvalid = output_axis_tvalid_reg; - -assign output_axis_tdata = output_axis_reg[DATA_WIDTH-1:0]; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_reg[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; -assign output_axis_tlast = output_axis_reg[LAST_OFFSET]; -assign output_axis_tid = ID_ENABLE ? output_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; - -assign overflow = overflow_reg; -assign bad_frame = bad_frame_reg; -assign good_frame = good_frame_reg; - -// Write logic -always @* begin - write = 1'b0; - - drop_frame_next = 1'b0; - overflow_next = 1'b0; - bad_frame_next = 1'b0; - good_frame_next = 1'b0; - - wr_ptr_next = wr_ptr_reg; - wr_ptr_cur_next = wr_ptr_cur_reg; - - if (input_axis_tvalid) begin - // input data valid - if (~full | DROP_WHEN_FULL) begin - // not full, perform write - if (full | full_cur | drop_frame_reg) begin - // full, packet overflow, or currently dropping frame - // drop frame - drop_frame_next = 1'b1; - if (input_axis_tlast) begin - // end of frame, reset write pointer - wr_ptr_cur_next = wr_ptr_reg; - drop_frame_next = 1'b0; - overflow_next = 1'b1; - end - end else begin - write = 1'b1; - wr_ptr_cur_next = wr_ptr_cur_reg + 1; - if (input_axis_tlast) begin - // end of frame - if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & input_axis_tuser == USER_BAD_FRAME_VALUE)) begin - // bad packet, reset write pointer - wr_ptr_cur_next = wr_ptr_reg; - bad_frame_next = 1'b1; - end else begin - // good packet, update write pointer - wr_ptr_next = wr_ptr_cur_reg + 1; - good_frame_next = 1'b1; - end - end - end - end - end -end - -always @(posedge clk) begin - if (rst) begin - wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; - - drop_frame_reg <= 1'b0; - overflow_reg <= 1'b0; - bad_frame_reg <= 1'b0; - good_frame_reg <= 1'b0; - end else begin - wr_ptr_reg <= wr_ptr_next; - wr_ptr_cur_reg <= wr_ptr_cur_next; - - drop_frame_reg <= drop_frame_next; - overflow_reg <= overflow_next; - bad_frame_reg <= bad_frame_next; - good_frame_reg <= good_frame_next; - end - - wr_addr_reg <= wr_ptr_cur_next; - - if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= input_axis; - end -end - -// Read logic -always @* begin - read = 1'b0; - - rd_ptr_next = rd_ptr_reg; - - mem_read_data_valid_next = mem_read_data_valid_reg; - - if (store_output | ~mem_read_data_valid_reg) begin - // output data not valid OR currently being transferred - if (~empty) begin - // not empty, perform read - read = 1'b1; - mem_read_data_valid_next = 1'b1; - rd_ptr_next = rd_ptr_reg + 1; - end else begin - // empty, invalidate - mem_read_data_valid_next = 1'b0; - end - end -end - -always @(posedge clk) begin - if (rst) begin - rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - mem_read_data_valid_reg <= 1'b0; - end else begin - rd_ptr_reg <= rd_ptr_next; - mem_read_data_valid_reg <= mem_read_data_valid_next; - end - - rd_addr_reg <= rd_ptr_next; - - if (read) begin - mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; - end -end - -// Output register -always @* begin - store_output = 1'b0; - - output_axis_tvalid_next = output_axis_tvalid_reg; - - if (output_axis_tready | ~output_axis_tvalid) begin - store_output = 1'b1; - output_axis_tvalid_next = mem_read_data_valid_reg; - end -end - -always @(posedge clk) begin - if (rst) begin - output_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - end - - if (store_output) begin - output_axis_reg <= mem_read_data_reg; - end -end - -endmodule diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index 72268f321..aa2527f9a 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -54,30 +54,35 @@ def bench(): DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + FRAME_FIFO = 0 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 0 + DROP_WHEN_FULL = 0 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -88,14 +93,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -105,14 +110,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -127,23 +132,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -303,7 +308,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -348,7 +353,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_fifo.v b/tb/test_axis_fifo.v index 2b7a76e50..042477a6b 100644 --- a/tb/test_axis_fifo.v +++ b/tb/test_axis_fifo.v @@ -43,30 +43,35 @@ parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 0; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 0; +parameter DROP_WHEN_FULL = 0; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -74,24 +79,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -110,29 +115,38 @@ axis_fifo #( .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL) ) 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), + // Status + .overflow(), + .bad_frame(), + .good_frame() ); endmodule diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index b9c6ff572..04181f7bd 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -54,30 +54,35 @@ def bench(): DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + FRAME_FIFO = 0 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 0 + DROP_WHEN_FULL = 0 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -88,14 +93,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -105,14 +110,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -127,23 +132,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -303,7 +308,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -348,7 +353,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_fifo_64.v b/tb/test_axis_fifo_64.v index d1e58c0f0..cc36f5ab6 100644 --- a/tb/test_axis_fifo_64.v +++ b/tb/test_axis_fifo_64.v @@ -43,30 +43,35 @@ parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 0; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 0; +parameter DROP_WHEN_FULL = 0; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -74,24 +79,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -110,29 +115,38 @@ axis_fifo #( .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL) ) 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), + // Status + .overflow(), + .bad_frame(), + .good_frame() ); endmodule diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index e10319e30..0beddc0fe 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_frame_fifo' -testbench = 'test_%s' % module +module = 'axis_fifo' +testbench = 'test_axis_frame_fifo' srcs = [] @@ -47,12 +47,14 @@ def bench(): DATA_WIDTH = 8 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 ID_ENABLE = 1 ID_WIDTH = 8 DEST_ENABLE = 1 DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + FRAME_FIFO = 1 USER_BAD_FRAME_VALUE = 1 USER_BAD_FRAME_MASK = 1 DROP_BAD_FRAME = 1 @@ -63,24 +65,24 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) overflow = Signal(bool(0)) bad_frame = Signal(bool(0)) good_frame = Signal(bool(0)) @@ -94,14 +96,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -111,14 +113,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -133,23 +135,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, overflow=overflow, bad_frame=bad_frame, @@ -362,7 +364,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -415,7 +417,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v index 2aaaa6c4c..41d90bd8a 100644 --- a/tb/test_axis_frame_fifo.v +++ b/tb/test_axis_frame_fifo.v @@ -27,7 +27,7 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_frame_fifo + * Testbench for axis_fifo */ module test_axis_frame_fifo; @@ -36,12 +36,14 @@ parameter ADDR_WIDTH = 9; parameter DATA_WIDTH = 8; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; parameter ID_ENABLE = 1; parameter ID_WIDTH = 8; parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 1; parameter USER_BAD_FRAME_VALUE = 1'b1; parameter USER_BAD_FRAME_MASK = 1'b1; parameter DROP_BAD_FRAME = 1; @@ -52,24 +54,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; wire overflow; wire bad_frame; wire good_frame; @@ -80,24 +82,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser, overflow, bad_frame, good_frame @@ -108,17 +110,19 @@ initial begin $dumpvars(0, test_axis_frame_fifo); end -axis_frame_fifo #( +axis_fifo #( .ADDR_WIDTH(ADDR_WIDTH), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), .ID_ENABLE(ID_ENABLE), .ID_WIDTH(ID_WIDTH), .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), .DROP_BAD_FRAME(DROP_BAD_FRAME), @@ -128,23 +132,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Status .overflow(overflow), .bad_frame(bad_frame), diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index ef500a3c2..4fc121384 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_frame_fifo' -testbench = 'test_%s_64' % module +module = 'axis_fifo' +testbench = 'test_axis_frame_fifo_64' srcs = [] @@ -47,12 +47,14 @@ def bench(): DATA_WIDTH = 64 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 ID_ENABLE = 1 ID_WIDTH = 8 DEST_ENABLE = 1 DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + FRAME_FIFO = 1 USER_BAD_FRAME_VALUE = 1 USER_BAD_FRAME_MASK = 1 DROP_BAD_FRAME = 1 @@ -63,24 +65,24 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) overflow = Signal(bool(0)) bad_frame = Signal(bool(0)) good_frame = Signal(bool(0)) @@ -94,14 +96,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -111,14 +113,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -133,23 +135,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, overflow=overflow, bad_frame=bad_frame, @@ -362,7 +364,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -415,7 +417,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v index a2e1a08fc..1f72e1056 100644 --- a/tb/test_axis_frame_fifo_64.v +++ b/tb/test_axis_frame_fifo_64.v @@ -27,7 +27,7 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_frame_fifo + * Testbench for axis_fifo */ module test_axis_frame_fifo_64; @@ -36,12 +36,14 @@ parameter ADDR_WIDTH = 6; parameter DATA_WIDTH = 64; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; parameter ID_ENABLE = 1; parameter ID_WIDTH = 8; parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 1; parameter USER_BAD_FRAME_VALUE = 1'b1; parameter USER_BAD_FRAME_MASK = 1'b1; parameter DROP_BAD_FRAME = 1; @@ -52,24 +54,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; wire overflow; wire bad_frame; wire good_frame; @@ -80,24 +82,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser, overflow, bad_frame, good_frame @@ -108,17 +110,19 @@ initial begin $dumpvars(0, test_axis_frame_fifo_64); end -axis_frame_fifo #( +axis_fifo #( .ADDR_WIDTH(ADDR_WIDTH), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), .ID_ENABLE(ID_ENABLE), .ID_WIDTH(ID_WIDTH), .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), .DROP_BAD_FRAME(DROP_BAD_FRAME), @@ -128,23 +132,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Status .overflow(overflow), .bad_frame(bad_frame), From 11d9dbe24a4f57a4f0b1d4837e5a165e5635806c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 09:53:38 -0700 Subject: [PATCH 430/617] Merge axis_async_fifo and axis_async_frame_fifo, rename ports --- rtl/axis_async_fifo.v | 315 +++++++++++++----- rtl/axis_async_frame_fifo.v | 412 ------------------------ tb/test_axis_async_fifo.py | 211 +++++++------ tb/test_axis_async_fifo.v | 127 ++++---- tb/test_axis_async_fifo_64.py | 211 +++++++------ tb/test_axis_async_fifo_64.v | 120 +++---- tb/test_axis_async_frame_fifo.py | 474 ++++++++++++++-------------- tb/test_axis_async_frame_fifo.v | 152 ++++----- tb/test_axis_async_frame_fifo_64.py | 474 ++++++++++++++-------------- tb/test_axis_async_frame_fifo_64.v | 152 ++++----- 10 files changed, 1219 insertions(+), 1429 deletions(-) delete mode 100644 rtl/axis_async_frame_fifo.v diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 8a73ba83e..dd291aa5a 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -41,7 +41,12 @@ module axis_async_fifo # parameter DEST_ENABLE = 0, parameter DEST_WIDTH = 8, parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1 + parameter USER_WIDTH = 1, + parameter FRAME_FIFO = 0, + parameter USER_BAD_FRAME_VALUE = 1'b1, + parameter USER_BAD_FRAME_MASK = 1'b1, + parameter DROP_BAD_FRAME = 0, + parameter DROP_WHEN_FULL = 0 ) ( /* @@ -52,30 +57,63 @@ module axis_async_fifo # /* * AXI input */ - input wire input_clk, - 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, + input wire s_clk, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * AXI output */ - input wire output_clk, - 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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser + input wire m_clk, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * Status + */ + output wire s_status_overflow, + output wire s_status_bad_frame, + output wire s_status_good_frame, + output wire m_status_overflow, + output wire m_status_bad_frame, + output wire m_status_good_frame ); +// check configuration +initial begin + if (FRAME_FIFO && !LAST_ENABLE) begin + $error("Error: FRAME_FIFO set requires LAST_ENABLE set"); + $finish; + end + + if (DROP_BAD_FRAME && !FRAME_FIFO) begin + $error("Error: DROP_BAD_FRAME set requires FRAME_FIFO set"); + $finish; + end + + if (DROP_WHEN_FULL && !FRAME_FIFO) begin + $error("Error: DROP_WHEN_FULL set requires FRAME_FIFO set"); + $finish; + end + + if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & {USER_WIDTH{1'b1}}) == 0) begin + $error("Error: Invalid USER_BAD_FRAME_MASK value"); + $finish; + end +end + localparam KEEP_OFFSET = DATA_WIDTH; localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); localparam ID_OFFSET = LAST_OFFSET + (LAST_ENABLE ? 1 : 0); @@ -84,6 +122,7 @@ localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; +reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; @@ -95,21 +134,21 @@ reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; -reg input_rst_sync1_reg = 1'b1; -reg input_rst_sync2_reg = 1'b1; -reg input_rst_sync3_reg = 1'b1; -reg output_rst_sync1_reg = 1'b1; -reg output_rst_sync2_reg = 1'b1; -reg output_rst_sync3_reg = 1'b1; +reg s_rst_sync1_reg = 1'b1; +reg s_rst_sync2_reg = 1'b1; +reg s_rst_sync3_reg = 1'b1; +reg m_rst_sync1_reg = 1'b1; +reg m_rst_sync2_reg = 1'b1; +reg m_rst_sync3_reg = 1'b1; reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; reg [WIDTH-1:0] mem_read_data_reg; reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; -wire [WIDTH-1:0] input_axis; +wire [WIDTH-1:0] s_axis; -reg [WIDTH-1:0] output_axis_reg; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; +reg [WIDTH-1:0] m_axis_reg; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; // full when first TWO MSBs do NOT match, but rest matches // (gray code equivalent of first MSB different but rest same) @@ -118,54 +157,83 @@ wire full = ((wr_ptr_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) (wr_ptr_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); // empty when pointers match exactly wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; +// overflow within packet +wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); // control signals reg write; reg read; reg store_output; -assign input_axis_tready = ~full & ~input_rst_sync3_reg; +reg drop_frame_reg = 1'b0, drop_frame_next; +reg overflow_reg = 1'b0, overflow_next; +reg bad_frame_reg = 1'b0, bad_frame_next; +reg good_frame_reg = 1'b0, good_frame_next; + +reg overflow_sync1_reg = 1'b0; +reg overflow_sync2_reg = 1'b0; +reg overflow_sync3_reg = 1'b0; +reg overflow_sync4_reg = 1'b0; +reg bad_frame_sync1_reg = 1'b0; +reg bad_frame_sync2_reg = 1'b0; +reg bad_frame_sync3_reg = 1'b0; +reg bad_frame_sync4_reg = 1'b0; +reg good_frame_sync1_reg = 1'b0; +reg good_frame_sync2_reg = 1'b0; +reg good_frame_sync3_reg = 1'b0; +reg good_frame_sync4_reg = 1'b0; + +assign s_axis_tready = (!full || DROP_WHEN_FULL) && !s_rst_sync3_reg; generate - assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; - if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; - if (LAST_ENABLE) assign input_axis[LAST_OFFSET] = input_axis_tlast; - if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; - if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; - if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; + assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata; + if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep; + if (LAST_ENABLE) assign s_axis[LAST_OFFSET] = s_axis_tlast; + if (ID_ENABLE) assign s_axis[ID_OFFSET +: ID_WIDTH] = s_axis_tid; + if (DEST_ENABLE) assign s_axis[DEST_OFFSET +: DEST_WIDTH] = s_axis_tdest; + if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser; endgenerate -assign output_axis_tvalid = output_axis_tvalid_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; -assign output_axis_tdata = output_axis_reg[DATA_WIDTH-1:0]; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_reg[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; -assign output_axis_tlast = LAST_ENABLE ? output_axis_reg[LAST_OFFSET] : 1'b1; -assign output_axis_tid = ID_ENABLE ? output_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; +assign m_axis_tdata = m_axis_reg[DATA_WIDTH-1:0]; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_reg[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +assign m_axis_tlast = LAST_ENABLE ? m_axis_reg[LAST_OFFSET] : 1'b1; +assign m_axis_tid = ID_ENABLE ? m_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; + +assign s_status_overflow = overflow_reg; +assign s_status_bad_frame = bad_frame_reg; +assign s_status_good_frame = good_frame_reg; + +assign m_status_overflow = overflow_sync3_reg ^ overflow_sync4_reg; +assign m_status_bad_frame = bad_frame_sync3_reg ^ bad_frame_sync4_reg; +assign m_status_good_frame = good_frame_sync3_reg ^ good_frame_sync4_reg; // reset synchronization -always @(posedge input_clk or posedge async_rst) begin +always @(posedge s_clk or posedge async_rst) begin if (async_rst) begin - input_rst_sync1_reg <= 1'b1; - input_rst_sync2_reg <= 1'b1; - input_rst_sync3_reg <= 1'b1; + s_rst_sync1_reg <= 1'b1; + s_rst_sync2_reg <= 1'b1; + s_rst_sync3_reg <= 1'b1; end else begin - input_rst_sync1_reg <= 1'b0; - input_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; - input_rst_sync3_reg <= input_rst_sync2_reg; + s_rst_sync1_reg <= 1'b0; + s_rst_sync2_reg <= s_rst_sync1_reg || m_rst_sync1_reg; + s_rst_sync3_reg <= s_rst_sync2_reg; end end -always @(posedge output_clk or posedge async_rst) begin +always @(posedge m_clk or posedge async_rst) begin if (async_rst) begin - output_rst_sync1_reg <= 1'b1; - output_rst_sync2_reg <= 1'b1; - output_rst_sync3_reg <= 1'b1; + m_rst_sync1_reg <= 1'b1; + m_rst_sync2_reg <= 1'b1; + m_rst_sync3_reg <= 1'b1; end else begin - output_rst_sync1_reg <= 1'b0; - output_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; - output_rst_sync3_reg <= output_rst_sync2_reg; + m_rst_sync1_reg <= 1'b0; + m_rst_sync2_reg <= s_rst_sync1_reg || m_rst_sync1_reg; + m_rst_sync3_reg <= m_rst_sync2_reg; end end @@ -173,39 +241,90 @@ end always @* begin write = 1'b0; + drop_frame_next = 1'b0; + overflow_next = 1'b0; + bad_frame_next = 1'b0; + good_frame_next = 1'b0; + wr_ptr_next = wr_ptr_reg; + wr_ptr_cur_next = wr_ptr_cur_reg; wr_ptr_gray_next = wr_ptr_gray_reg; - if (input_axis_tvalid) begin + if (s_axis_tvalid) begin // input data valid - if (~full) begin + if (!full || DROP_WHEN_FULL) begin // not full, perform write - write = 1'b1; - wr_ptr_next = wr_ptr_reg + 1; - wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); + if (!FRAME_FIFO) begin + // normal FIFO mode + write = 1'b1; + wr_ptr_next = wr_ptr_reg + 1; + wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); + end else if (full || full_cur || drop_frame_reg) begin + // full, packet overflow, or currently dropping frame + // drop frame + drop_frame_next = 1'b1; + if (s_axis_tlast) begin + // end of frame, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + drop_frame_next = 1'b0; + overflow_next = 1'b1; + end + end else begin + write = 1'b1; + wr_ptr_cur_next = wr_ptr_cur_reg + 1; + if (s_axis_tlast) begin + // end of frame + if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin + // bad packet, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + bad_frame_next = 1'b1; + end else begin + // good packet, update write pointer + wr_ptr_next = wr_ptr_cur_reg + 1; + wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); + good_frame_next = 1'b1; + end + end + end end end end -always @(posedge input_clk) begin - if (input_rst_sync3_reg) begin +always @(posedge s_clk) begin + if (s_rst_sync3_reg) begin wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + + drop_frame_reg <= 1'b0; + overflow_reg <= 1'b0; + bad_frame_reg <= 1'b0; + good_frame_reg <= 1'b0; end else begin wr_ptr_reg <= wr_ptr_next; + wr_ptr_cur_reg <= wr_ptr_cur_next; wr_ptr_gray_reg <= wr_ptr_gray_next; + + drop_frame_reg <= drop_frame_next; + overflow_reg <= overflow_next; + bad_frame_reg <= bad_frame_next; + good_frame_reg <= good_frame_next; end - wr_addr_reg <= wr_ptr_next; + if (FRAME_FIFO) begin + wr_addr_reg <= wr_ptr_cur_next; + end else begin + wr_addr_reg <= wr_ptr_next; + end if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= input_axis; + mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= s_axis; end end // pointer synchronization -always @(posedge input_clk) begin - if (input_rst_sync3_reg) begin +always @(posedge s_clk) begin + if (s_rst_sync3_reg) begin rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin @@ -214,8 +333,8 @@ always @(posedge input_clk) begin end end -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin +always @(posedge m_clk) begin + if (m_rst_sync3_reg) begin wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; end else begin @@ -224,6 +343,40 @@ always @(posedge output_clk) begin end end +// status synchronization +always @(posedge s_clk) begin + if (s_rst_sync3_reg) begin + overflow_sync1_reg <= 1'b0; + bad_frame_sync1_reg <= 1'b0; + good_frame_sync1_reg <= 1'b0; + end else begin + overflow_sync1_reg <= overflow_sync1_reg ^ overflow_reg; + bad_frame_sync1_reg <= bad_frame_sync1_reg ^ bad_frame_reg; + good_frame_sync1_reg <= good_frame_sync1_reg ^ good_frame_reg; + end +end + +always @(posedge m_clk) begin + if (m_rst_sync3_reg) begin + overflow_sync2_reg <= 1'b0; + overflow_sync3_reg <= 1'b0; + bad_frame_sync2_reg <= 1'b0; + bad_frame_sync3_reg <= 1'b0; + good_frame_sync2_reg <= 1'b0; + good_frame_sync3_reg <= 1'b0; + end else begin + overflow_sync2_reg <= overflow_sync1_reg; + overflow_sync3_reg <= overflow_sync2_reg; + overflow_sync4_reg <= overflow_sync3_reg; + bad_frame_sync2_reg <= bad_frame_sync1_reg; + bad_frame_sync3_reg <= bad_frame_sync2_reg; + bad_frame_sync4_reg <= bad_frame_sync3_reg; + good_frame_sync2_reg <= good_frame_sync1_reg; + good_frame_sync3_reg <= good_frame_sync2_reg; + good_frame_sync4_reg <= good_frame_sync3_reg; + end +end + // Read logic always @* begin read = 1'b0; @@ -233,9 +386,9 @@ always @* begin mem_read_data_valid_next = mem_read_data_valid_reg; - if (store_output | ~mem_read_data_valid_reg) begin + if (store_output || !mem_read_data_valid_reg) begin // output data not valid OR currently being transferred - if (~empty) begin + if (!empty) begin // not empty, perform read read = 1'b1; mem_read_data_valid_next = 1'b1; @@ -248,8 +401,8 @@ always @* begin end end -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin +always @(posedge m_clk) begin + if (m_rst_sync3_reg) begin rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; mem_read_data_valid_reg <= 1'b0; @@ -270,23 +423,23 @@ end always @* begin store_output = 1'b0; - output_axis_tvalid_next = output_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; - if (output_axis_tready | ~output_axis_tvalid) begin + if (m_axis_tready || !m_axis_tvalid) begin store_output = 1'b1; - output_axis_tvalid_next = mem_read_data_valid_reg; + m_axis_tvalid_next = mem_read_data_valid_reg; end end -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - output_axis_tvalid_reg <= 1'b0; +always @(posedge m_clk) begin + if (m_rst_sync3_reg) begin + m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; end if (store_output) begin - output_axis_reg <= mem_read_data_reg; + m_axis_reg <= mem_read_data_reg; end end diff --git a/rtl/axis_async_frame_fifo.v b/rtl/axis_async_frame_fifo.v deleted file mode 100644 index b17526018..000000000 --- a/rtl/axis_async_frame_fifo.v +++ /dev/null @@ -1,412 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 asynchronous frame FIFO - */ -module axis_async_frame_fifo # -( - parameter ADDR_WIDTH = 12, - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1, - parameter USER_BAD_FRAME_VALUE = 1'b1, - parameter USER_BAD_FRAME_MASK = 1'b1, - parameter DROP_BAD_FRAME = 1, - parameter DROP_WHEN_FULL = 0 -) -( - /* - * Common asynchronous reset - */ - input wire async_rst, - - /* - * AXI input - */ - input wire input_clk, - 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, - - /* - * AXI output - */ - input wire output_clk, - 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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser, - - /* - * Status - */ - output wire input_status_overflow, - output wire input_status_bad_frame, - output wire input_status_good_frame, - output wire output_status_overflow, - output wire output_status_bad_frame, - output wire output_status_good_frame -); - -localparam KEEP_OFFSET = DATA_WIDTH; -localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); -localparam ID_OFFSET = LAST_OFFSET + 1; -localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0); -localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); -localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); - -reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; -reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; -reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; -reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; -reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; -reg [ADDR_WIDTH:0] rd_addr_reg = {ADDR_WIDTH+1{1'b0}}; - -reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; - -reg input_rst_sync1_reg = 1'b1; -reg input_rst_sync2_reg = 1'b1; -reg input_rst_sync3_reg = 1'b1; -reg output_rst_sync1_reg = 1'b1; -reg output_rst_sync2_reg = 1'b1; -reg output_rst_sync3_reg = 1'b1; - -reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [WIDTH-1:0] mem_read_data_reg; -reg mem_read_data_valid_reg = 1'b0, mem_read_data_valid_next; - -wire [WIDTH-1:0] input_axis; - -reg [WIDTH-1:0] output_axis_reg; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; - -// full when first TWO MSBs do NOT match, but rest matches -// (gray code equivalent of first MSB different but rest same) -wire full = ((wr_ptr_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) && - (wr_ptr_gray_reg[ADDR_WIDTH-1] != rd_ptr_gray_sync2_reg[ADDR_WIDTH-1]) && - (wr_ptr_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); -// empty when pointers match exactly -wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; -// overflow within packet -wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && - (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); - -// control signals -reg write; -reg read; -reg store_output; - -reg drop_frame_reg = 1'b0, drop_frame_next; -reg overflow_reg = 1'b0, overflow_next; -reg bad_frame_reg = 1'b0, bad_frame_next; -reg good_frame_reg = 1'b0, good_frame_next; - -reg overflow_sync1_reg = 1'b0; -reg overflow_sync2_reg = 1'b0; -reg overflow_sync3_reg = 1'b0; -reg overflow_sync4_reg = 1'b0; -reg bad_frame_sync1_reg = 1'b0; -reg bad_frame_sync2_reg = 1'b0; -reg bad_frame_sync3_reg = 1'b0; -reg bad_frame_sync4_reg = 1'b0; -reg good_frame_sync1_reg = 1'b0; -reg good_frame_sync2_reg = 1'b0; -reg good_frame_sync3_reg = 1'b0; -reg good_frame_sync4_reg = 1'b0; - -assign input_axis_tready = (~full | DROP_WHEN_FULL) & ~input_rst_sync3_reg; - -generate - assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; - if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; - assign input_axis[LAST_OFFSET] = input_axis_tlast; - if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; - if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; - if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; -endgenerate - -assign output_axis_tvalid = output_axis_tvalid_reg; - -assign output_axis_tdata = output_axis_reg[DATA_WIDTH-1:0]; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_reg[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; -assign output_axis_tlast = output_axis_reg[LAST_OFFSET]; -assign output_axis_tid = ID_ENABLE ? output_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; - -assign input_status_overflow = overflow_reg; -assign input_status_bad_frame = bad_frame_reg; -assign input_status_good_frame = good_frame_reg; - -assign output_status_overflow = overflow_sync3_reg ^ overflow_sync4_reg; -assign output_status_bad_frame = bad_frame_sync3_reg ^ bad_frame_sync4_reg; -assign output_status_good_frame = good_frame_sync3_reg ^ good_frame_sync4_reg; - -// reset synchronization -always @(posedge input_clk or posedge async_rst) begin - if (async_rst) begin - input_rst_sync1_reg <= 1'b1; - input_rst_sync2_reg <= 1'b1; - input_rst_sync3_reg <= 1'b1; - end else begin - input_rst_sync1_reg <= 1'b0; - input_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; - input_rst_sync3_reg <= input_rst_sync2_reg; - end -end - -always @(posedge output_clk or posedge async_rst) begin - if (async_rst) begin - output_rst_sync1_reg <= 1'b1; - output_rst_sync2_reg <= 1'b1; - output_rst_sync3_reg <= 1'b1; - end else begin - output_rst_sync1_reg <= 1'b0; - output_rst_sync2_reg <= input_rst_sync1_reg | output_rst_sync1_reg; - output_rst_sync3_reg <= output_rst_sync2_reg; - end -end - -// Write logic -always @* begin - write = 1'b0; - - drop_frame_next = 1'b0; - overflow_next = 1'b0; - bad_frame_next = 1'b0; - good_frame_next = 1'b0; - - wr_ptr_next = wr_ptr_reg; - wr_ptr_cur_next = wr_ptr_cur_reg; - wr_ptr_gray_next = wr_ptr_gray_reg; - - if (input_axis_tvalid) begin - // input data valid - if (~full | DROP_WHEN_FULL) begin - // not full, perform write - if (full | full_cur | drop_frame_reg) begin - // full, packet overflow, or currently dropping frame - // drop frame - drop_frame_next = 1'b1; - if (input_axis_tlast) begin - // end of frame, reset write pointer - wr_ptr_cur_next = wr_ptr_reg; - drop_frame_next = 1'b0; - overflow_next = 1'b1; - end - end else begin - write = 1'b1; - wr_ptr_cur_next = wr_ptr_cur_reg + 1; - if (input_axis_tlast) begin - // end of frame - if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & input_axis_tuser == USER_BAD_FRAME_VALUE)) begin - // bad packet, reset write pointer - wr_ptr_cur_next = wr_ptr_reg; - bad_frame_next = 1'b1; - end else begin - // good packet, update write pointer - wr_ptr_next = wr_ptr_cur_reg + 1; - wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); - good_frame_next = 1'b1; - end - end - end - end - end -end - -always @(posedge input_clk) begin - if (input_rst_sync3_reg) begin - wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - - drop_frame_reg <= 1'b0; - overflow_reg <= 1'b0; - bad_frame_reg <= 1'b0; - good_frame_reg <= 1'b0; - end else begin - wr_ptr_reg <= wr_ptr_next; - wr_ptr_cur_reg <= wr_ptr_cur_next; - wr_ptr_gray_reg <= wr_ptr_gray_next; - - drop_frame_reg <= drop_frame_next; - overflow_reg <= overflow_next; - bad_frame_reg <= bad_frame_next; - good_frame_reg <= good_frame_next; - end - - wr_addr_reg <= wr_ptr_cur_next; - - if (write) begin - mem[wr_addr_reg[ADDR_WIDTH-1:0]] <= input_axis; - end -end - -// pointer synchronization -always @(posedge input_clk) begin - if (input_rst_sync3_reg) begin - rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; - rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; - end else begin - rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg; - rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg; - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; - end else begin - wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; - wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg; - end -end - -// status synchronization -always @(posedge input_clk) begin - if (input_rst_sync3_reg) begin - overflow_sync1_reg <= 1'b0; - bad_frame_sync1_reg <= 1'b0; - good_frame_sync1_reg <= 1'b0; - end else begin - overflow_sync1_reg <= overflow_sync1_reg ^ overflow_reg; - bad_frame_sync1_reg <= bad_frame_sync1_reg ^ bad_frame_reg; - good_frame_sync1_reg <= good_frame_sync1_reg ^ good_frame_reg; - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - overflow_sync2_reg <= 1'b0; - overflow_sync3_reg <= 1'b0; - bad_frame_sync2_reg <= 1'b0; - bad_frame_sync3_reg <= 1'b0; - good_frame_sync2_reg <= 1'b0; - good_frame_sync3_reg <= 1'b0; - end else begin - overflow_sync2_reg <= overflow_sync1_reg; - overflow_sync3_reg <= overflow_sync2_reg; - overflow_sync4_reg <= overflow_sync3_reg; - bad_frame_sync2_reg <= bad_frame_sync1_reg; - bad_frame_sync3_reg <= bad_frame_sync2_reg; - bad_frame_sync4_reg <= bad_frame_sync3_reg; - good_frame_sync2_reg <= good_frame_sync1_reg; - good_frame_sync3_reg <= good_frame_sync2_reg; - good_frame_sync4_reg <= good_frame_sync3_reg; - end -end - -// Read logic -always @* begin - read = 1'b0; - - rd_ptr_next = rd_ptr_reg; - rd_ptr_gray_next = rd_ptr_gray_reg; - - mem_read_data_valid_next = mem_read_data_valid_reg; - - if (store_output | ~mem_read_data_valid_reg) begin - // output data not valid OR currently being transferred - if (~empty) begin - // not empty, perform read - read = 1'b1; - mem_read_data_valid_next = 1'b1; - rd_ptr_next = rd_ptr_reg + 1; - rd_ptr_gray_next = rd_ptr_next ^ (rd_ptr_next >> 1); - end else begin - // empty, invalidate - mem_read_data_valid_next = 1'b0; - end - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - mem_read_data_valid_reg <= 1'b0; - end else begin - rd_ptr_reg <= rd_ptr_next; - rd_ptr_gray_reg <= rd_ptr_gray_next; - mem_read_data_valid_reg <= mem_read_data_valid_next; - end - - rd_addr_reg <= rd_ptr_next; - - if (read) begin - mem_read_data_reg <= mem[rd_addr_reg[ADDR_WIDTH-1:0]]; - end -end - -// Output register -always @* begin - store_output = 1'b0; - - output_axis_tvalid_next = output_axis_tvalid_reg; - - if (output_axis_tready | ~output_axis_tvalid) begin - store_output = 1'b1; - output_axis_tvalid_next = mem_read_data_valid_reg; - end -end - -always @(posedge output_clk) begin - if (output_rst_sync3_reg) begin - output_axis_tvalid_reg <= 1'b0; - end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - end - - if (store_output) begin - output_axis_reg <= mem_read_data_reg; - end -end - -endmodule diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index 0947dd1a6..0a1f842c1 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -54,31 +54,36 @@ def bench(): DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + FRAME_FIFO = 0 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 0 + DROP_WHEN_FULL = 0 # Inputs async_rst = Signal(bool(0)) - input_clk = Signal(bool(0)) - output_clk = Signal(bool(0)) + s_clk = Signal(bool(0)) + m_clk = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -87,16 +92,16 @@ def bench(): source = axis_ep.AXIStreamSource() source_logic = source.create_logic( - input_clk, + s_clk, async_rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -104,16 +109,16 @@ def bench(): sink = axis_ep.AXIStreamSink() sink_logic = sink.create_logic( - output_clk, + m_clk, async_rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -125,53 +130,53 @@ def bench(): dut = Cosimulation( "vvp -m myhdl %s.vvp -lxt2" % testbench, async_rst=async_rst, - input_clk=input_clk, - output_clk=output_clk, + s_clk=s_clk, + m_clk=m_clk, 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) - def input_clkgen(): - input_clk.next = not input_clk + def s_clkgen(): + s_clk.next = not s_clk @always(delay(5)) - def output_clkgen(): - output_clk.next = not output_clk + def m_clkgen(): + m_clk.next = not m_clk @instance def check(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge async_rst.next = 1 - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge async_rst.next = 0 - yield input_clk.posedge + yield s_clk.posedge yield delay(100) - yield input_clk.posedge + yield s_clk.posedge - yield input_clk.posedge + yield s_clk.posedge - yield input_clk.posedge + yield s_clk.posedge print("test 1: test packet") current_test.next = 1 @@ -193,7 +198,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 2: longer packet") current_test.next = 2 @@ -213,7 +218,7 @@ def bench(): assert rx_frame == test_frame - yield input_clk.posedge + yield s_clk.posedge print("test 3: test packet with pauses") current_test.next = 3 @@ -227,20 +232,20 @@ def bench(): ) source.send(test_frame) - yield input_clk.posedge + yield s_clk.posedge yield delay(64) - yield input_clk.posedge + yield s_clk.posedge source_pause.next = True yield delay(32) - yield input_clk.posedge + yield s_clk.posedge source_pause.next = False yield delay(64) - yield output_clk.posedge + yield m_clk.posedge sink_pause.next = True yield delay(32) - yield output_clk.posedge + yield m_clk.posedge sink_pause.next = False yield sink.wait() @@ -250,7 +255,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 4: back-to-back packets") current_test.next = 4 @@ -289,7 +294,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 5: alternate pause source") current_test.next = 5 @@ -312,15 +317,15 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge + yield s_clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge source_pause.next = False - yield input_clk.posedge + yield s_clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -334,7 +339,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 6: alternate pause sink") current_test.next = 6 @@ -357,15 +362,15 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge + yield s_clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge + yield m_clk.posedge + yield m_clk.posedge + yield m_clk.posedge sink_pause.next = False - yield output_clk.posedge + yield m_clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -379,7 +384,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 7: tuser assert") current_test.next = 7 @@ -403,7 +408,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 8: initial sink pause") current_test.next = 8 @@ -415,10 +420,10 @@ def bench(): sink_pause.next = 1 source.send(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge sink_pause.next = 0 yield sink.wait() @@ -428,7 +433,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 9: initial sink pause, assert reset") current_test.next = 9 @@ -440,22 +445,22 @@ def bench(): sink_pause.next = 1 source.send(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge async_rst.next = 1 - yield input_clk.posedge + yield s_clk.posedge async_rst.next = 0 sink_pause.next = 0 yield delay(100) - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge + yield m_clk.posedge + yield m_clk.posedge + yield m_clk.posedge assert sink.empty() diff --git a/tb/test_axis_async_fifo.v b/tb/test_axis_async_fifo.v index de82f79cb..9851813e7 100644 --- a/tb/test_axis_async_fifo.v +++ b/tb/test_axis_async_fifo.v @@ -43,57 +43,62 @@ parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 0; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 0; +parameter DROP_WHEN_FULL = 0; // Inputs reg async_rst = 0; -reg input_clk = 0; -reg output_clk = 0; +reg s_clk = 0; +reg m_clk = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration $from_myhdl( async_rst, - input_clk, - output_clk, + s_clk, + m_clk, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -112,31 +117,43 @@ axis_async_fifo #( .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL) ) UUT ( // Common reset .async_rst(async_rst), // AXI input - .input_clk(input_clk), - .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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_clk(s_clk), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), // AXI output - .output_clk(output_clk), - .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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_clk(m_clk), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), + // Status + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() ); endmodule diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index 35bac2361..0bd343e63 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -54,31 +54,36 @@ def bench(): DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + FRAME_FIFO = 0 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 0 + DROP_WHEN_FULL = 0 # Inputs async_rst = Signal(bool(0)) - input_clk = Signal(bool(0)) - output_clk = Signal(bool(0)) + s_clk = Signal(bool(0)) + m_clk = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -87,16 +92,16 @@ def bench(): source = axis_ep.AXIStreamSource() source_logic = source.create_logic( - input_clk, + s_clk, async_rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -104,16 +109,16 @@ def bench(): sink = axis_ep.AXIStreamSink() sink_logic = sink.create_logic( - output_clk, + m_clk, async_rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -125,53 +130,53 @@ def bench(): dut = Cosimulation( "vvp -m myhdl %s.vvp -lxt2" % testbench, async_rst=async_rst, - input_clk=input_clk, - output_clk=output_clk, + s_clk=s_clk, + m_clk=m_clk, 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) - def input_clkgen(): - input_clk.next = not input_clk + def s_clkgen(): + s_clk.next = not s_clk @always(delay(5)) - def output_clkgen(): - output_clk.next = not output_clk + def m_clkgen(): + m_clk.next = not m_clk @instance def check(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge async_rst.next = 1 - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge async_rst.next = 0 - yield input_clk.posedge + yield s_clk.posedge yield delay(100) - yield input_clk.posedge + yield s_clk.posedge - yield input_clk.posedge + yield s_clk.posedge - yield input_clk.posedge + yield s_clk.posedge print("test 1: test packet") current_test.next = 1 @@ -193,7 +198,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 2: longer packet") current_test.next = 2 @@ -213,7 +218,7 @@ def bench(): assert rx_frame == test_frame - yield input_clk.posedge + yield s_clk.posedge print("test 3: test packet with pauses") current_test.next = 3 @@ -227,20 +232,20 @@ def bench(): ) source.send(test_frame) - yield input_clk.posedge + yield s_clk.posedge yield delay(64) - yield input_clk.posedge + yield s_clk.posedge source_pause.next = True yield delay(32) - yield input_clk.posedge + yield s_clk.posedge source_pause.next = False yield delay(64) - yield output_clk.posedge + yield m_clk.posedge sink_pause.next = True yield delay(32) - yield output_clk.posedge + yield m_clk.posedge sink_pause.next = False yield sink.wait() @@ -250,7 +255,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 4: back-to-back packets") current_test.next = 4 @@ -289,7 +294,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 5: alternate pause source") current_test.next = 5 @@ -312,15 +317,15 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge + yield s_clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge source_pause.next = False - yield input_clk.posedge + yield s_clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -334,7 +339,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 6: alternate pause sink") current_test.next = 6 @@ -357,15 +362,15 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge + yield s_clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge + yield m_clk.posedge + yield m_clk.posedge + yield m_clk.posedge sink_pause.next = False - yield output_clk.posedge + yield m_clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -379,7 +384,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 7: tuser assert") current_test.next = 7 @@ -403,7 +408,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 8: initial sink pause") current_test.next = 8 @@ -415,10 +420,10 @@ def bench(): sink_pause.next = 1 source.send(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge sink_pause.next = 0 yield sink.wait() @@ -428,7 +433,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 9: initial sink pause, assert reset") current_test.next = 9 @@ -440,22 +445,22 @@ def bench(): sink_pause.next = 1 source.send(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge async_rst.next = 1 - yield input_clk.posedge + yield s_clk.posedge async_rst.next = 0 sink_pause.next = 0 yield delay(100) - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge + yield m_clk.posedge + yield m_clk.posedge + yield m_clk.posedge assert sink.empty() diff --git a/tb/test_axis_async_fifo_64.v b/tb/test_axis_async_fifo_64.v index 4d590df1b..5605f7ab8 100644 --- a/tb/test_axis_async_fifo_64.v +++ b/tb/test_axis_async_fifo_64.v @@ -43,57 +43,62 @@ parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 0; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 0; +parameter DROP_WHEN_FULL = 0; // Inputs reg async_rst = 0; -reg input_clk = 0; -reg output_clk = 0; +reg s_clk = 0; +reg m_clk = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration $from_myhdl( async_rst, - input_clk, - output_clk, + s_clk, + m_clk, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -112,31 +117,36 @@ axis_async_fifo #( .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL) ) UUT ( // Common reset .async_rst(async_rst), // AXI input - .input_clk(input_clk), - .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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_clk(s_clk), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), // AXI output - .output_clk(output_clk), - .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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_clk(m_clk), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index 90ea9fe6f..dba018b1e 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_async_frame_fifo' -testbench = 'test_%s' % module +module = 'axis_async_fifo' +testbench = 'test_axis_async_frame_fifo' srcs = [] @@ -47,12 +47,14 @@ def bench(): DATA_WIDTH = 8 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 ID_ENABLE = 1 ID_WIDTH = 8 DEST_ENABLE = 1 DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + FRAME_FIFO = 1 USER_BAD_FRAME_VALUE = 1 USER_BAD_FRAME_MASK = 1 DROP_BAD_FRAME = 1 @@ -60,34 +62,34 @@ def bench(): # Inputs async_rst = Signal(bool(0)) - input_clk = Signal(bool(0)) - output_clk = Signal(bool(0)) + s_clk = Signal(bool(0)) + m_clk = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_status_overflow = Signal(bool(0)) - input_status_bad_frame = Signal(bool(0)) - input_status_good_frame = Signal(bool(0)) - output_status_overflow = Signal(bool(0)) - output_status_bad_frame = Signal(bool(0)) - output_status_good_frame = Signal(bool(0)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_status_overflow = Signal(bool(0)) + s_status_bad_frame = Signal(bool(0)) + s_status_good_frame = Signal(bool(0)) + m_status_overflow = Signal(bool(0)) + m_status_bad_frame = Signal(bool(0)) + m_status_good_frame = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -96,16 +98,16 @@ def bench(): source = axis_ep.AXIStreamSource() source_logic = source.create_logic( - input_clk, + s_clk, async_rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -113,16 +115,16 @@ def bench(): sink = axis_ep.AXIStreamSink() sink_logic = sink.create_logic( - output_clk, + m_clk, async_rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -134,85 +136,85 @@ def bench(): dut = Cosimulation( "vvp -m myhdl %s.vvp -lxt2" % testbench, async_rst=async_rst, - input_clk=input_clk, - output_clk=output_clk, + s_clk=s_clk, + m_clk=m_clk, 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, - input_status_overflow=input_status_overflow, - input_status_bad_frame=input_status_bad_frame, - input_status_good_frame=input_status_good_frame, - output_status_overflow=output_status_overflow, - output_status_bad_frame=output_status_bad_frame, - output_status_good_frame=output_status_good_frame + s_status_overflow=s_status_overflow, + s_status_bad_frame=s_status_bad_frame, + s_status_good_frame=s_status_good_frame, + m_status_overflow=m_status_overflow, + m_status_bad_frame=m_status_bad_frame, + m_status_good_frame=m_status_good_frame ) @always(delay(4)) - def input_clkgen(): - input_clk.next = not input_clk + def s_clkgen(): + s_clk.next = not s_clk @always(delay(5)) - def output_clkgen(): - output_clk.next = not output_clk + def m_clkgen(): + m_clk.next = not m_clk - input_status_overflow_asserted = Signal(bool(0)) - input_status_bad_frame_asserted = Signal(bool(0)) - input_status_good_frame_asserted = Signal(bool(0)) - output_status_overflow_asserted = Signal(bool(0)) - output_status_bad_frame_asserted = Signal(bool(0)) - output_status_good_frame_asserted = Signal(bool(0)) + s_status_overflow_asserted = Signal(bool(0)) + s_status_bad_frame_asserted = Signal(bool(0)) + s_status_good_frame_asserted = Signal(bool(0)) + m_status_overflow_asserted = Signal(bool(0)) + m_status_bad_frame_asserted = Signal(bool(0)) + m_status_good_frame_asserted = Signal(bool(0)) - @always(input_clk.posedge) + @always(s_clk.posedge) def monitor_1(): - if (input_status_overflow): - input_status_overflow_asserted.next = 1 - if (input_status_bad_frame): - input_status_bad_frame_asserted.next = 1 - if (input_status_good_frame): - input_status_good_frame_asserted.next = 1 + if (s_status_overflow): + s_status_overflow_asserted.next = 1 + if (s_status_bad_frame): + s_status_bad_frame_asserted.next = 1 + if (s_status_good_frame): + s_status_good_frame_asserted.next = 1 - @always(output_clk.posedge) + @always(m_clk.posedge) def monitor_2(): - if (output_status_overflow): - output_status_overflow_asserted.next = 1 - if (output_status_bad_frame): - output_status_bad_frame_asserted.next = 1 - if (output_status_good_frame): - output_status_good_frame_asserted.next = 1 + if (m_status_overflow): + m_status_overflow_asserted.next = 1 + if (m_status_bad_frame): + m_status_bad_frame_asserted.next = 1 + if (m_status_good_frame): + m_status_good_frame_asserted.next = 1 @instance def check(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge async_rst.next = 1 - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge async_rst.next = 0 - yield input_clk.posedge + yield s_clk.posedge yield delay(100) - yield input_clk.posedge + yield s_clk.posedge - yield input_clk.posedge + yield s_clk.posedge - yield input_clk.posedge + yield s_clk.posedge print("test 1: test packet") current_test.next = 1 @@ -225,12 +227,12 @@ def bench(): dest=1 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame) @@ -239,16 +241,16 @@ def bench(): assert rx_frame == test_frame - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 2: longer packet") current_test.next = 2 @@ -261,12 +263,12 @@ def bench(): dest=1 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame) @@ -275,14 +277,14 @@ def bench(): assert rx_frame == test_frame - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted - yield input_clk.posedge + yield s_clk.posedge print("test 3: test packet with pauses") current_test.next = 3 @@ -295,28 +297,28 @@ def bench(): dest=1 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame) - yield input_clk.posedge + yield s_clk.posedge yield delay(64) - yield input_clk.posedge + yield s_clk.posedge source_pause.next = True yield delay(32) - yield input_clk.posedge + yield s_clk.posedge source_pause.next = False yield delay(64) - yield output_clk.posedge + yield m_clk.posedge sink_pause.next = True yield delay(32) - yield output_clk.posedge + yield m_clk.posedge sink_pause.next = False yield sink.wait() @@ -324,16 +326,16 @@ def bench(): assert rx_frame == test_frame - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 4: back-to-back packets") current_test.next = 4 @@ -354,12 +356,12 @@ def bench(): dest=2 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) @@ -374,16 +376,16 @@ def bench(): assert rx_frame == test_frame2 - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 5: alternate pause source") current_test.next = 5 @@ -404,24 +406,24 @@ def bench(): dest=2 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge + yield s_clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge source_pause.next = False - yield input_clk.posedge + yield s_clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -433,16 +435,16 @@ def bench(): assert rx_frame == test_frame2 - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 6: alternate pause sink") current_test.next = 6 @@ -463,24 +465,24 @@ def bench(): dest=2 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge + yield s_clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge + yield m_clk.posedge + yield m_clk.posedge + yield m_clk.posedge sink_pause.next = False - yield output_clk.posedge + yield m_clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -492,16 +494,16 @@ def bench(): assert rx_frame == test_frame2 - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 7: tuser assert") current_test.next = 7 @@ -515,30 +517,30 @@ def bench(): last_cycle_user=1 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame) - yield input_clk.posedge + yield s_clk.posedge yield delay(1000) assert sink.empty() - assert not input_status_overflow_asserted - assert input_status_bad_frame_asserted - assert not input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert output_status_bad_frame_asserted - assert not output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert s_status_bad_frame_asserted + assert not s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert m_status_bad_frame_asserted + assert not m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 8: single packet overflow") current_test.next = 8 @@ -551,30 +553,30 @@ def bench(): dest=1 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame) - yield input_clk.posedge + yield s_clk.posedge yield delay(10000) assert sink.empty() - assert input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert not input_status_good_frame_asserted - assert output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert not output_status_good_frame_asserted + assert s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert not s_status_good_frame_asserted + assert m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert not m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 9: initial sink pause") current_test.next = 9 @@ -586,10 +588,10 @@ def bench(): sink_pause.next = 1 source.send(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge sink_pause.next = 0 yield sink.wait() @@ -599,7 +601,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 10: initial sink pause, assert reset") current_test.next = 10 @@ -611,22 +613,22 @@ def bench(): sink_pause.next = 1 source.send(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge async_rst.next = 1 - yield input_clk.posedge + yield s_clk.posedge async_rst.next = 0 sink_pause.next = 0 yield delay(100) - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge + yield m_clk.posedge + yield m_clk.posedge + yield m_clk.posedge assert sink.empty() diff --git a/tb/test_axis_async_frame_fifo.v b/tb/test_axis_async_frame_fifo.v index da9498117..4f8e7829e 100644 --- a/tb/test_axis_async_frame_fifo.v +++ b/tb/test_axis_async_frame_fifo.v @@ -27,7 +27,7 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_async_frame_fifo + * Testbench for axis_async_fifo */ module test_axis_async_frame_fifo; @@ -36,12 +36,14 @@ parameter ADDR_WIDTH = 9; parameter DATA_WIDTH = 8; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; parameter ID_ENABLE = 1; parameter ID_WIDTH = 8; parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 1; parameter USER_BAD_FRAME_VALUE = 1'b1; parameter USER_BAD_FRAME_MASK = 1'b1; parameter DROP_BAD_FRAME = 1; @@ -49,66 +51,66 @@ parameter DROP_WHEN_FULL = 0; // Inputs reg async_rst = 0; -reg input_clk = 0; -reg output_clk = 0; +reg s_clk = 0; +reg m_clk = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; -wire input_status_overflow; -wire input_status_bad_frame; -wire input_status_good_frame; -wire output_status_overflow; -wire output_status_bad_frame; -wire output_status_good_frame; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; +wire s_status_overflow; +wire s_status_bad_frame; +wire s_status_good_frame; +wire m_status_overflow; +wire m_status_bad_frame; +wire m_status_good_frame; initial begin // myhdl integration $from_myhdl( async_rst, - input_clk, - output_clk, + s_clk, + m_clk, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser, - input_status_overflow, - input_status_bad_frame, - input_status_good_frame, - output_status_overflow, - output_status_bad_frame, - output_status_good_frame + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser, + s_status_overflow, + s_status_bad_frame, + s_status_good_frame, + m_status_overflow, + m_status_bad_frame, + m_status_good_frame ); // dump file @@ -116,17 +118,19 @@ initial begin $dumpvars(0, test_axis_async_frame_fifo); end -axis_async_frame_fifo #( +axis_async_fifo #( .ADDR_WIDTH(ADDR_WIDTH), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), .ID_ENABLE(ID_ENABLE), .ID_WIDTH(ID_WIDTH), .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), .DROP_BAD_FRAME(DROP_BAD_FRAME), @@ -136,32 +140,32 @@ UUT ( // Common reset .async_rst(async_rst), // AXI input - .input_clk(input_clk), - .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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_clk(s_clk), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), // AXI output - .output_clk(output_clk), - .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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_clk(m_clk), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Status - .input_status_overflow(input_status_overflow), - .input_status_bad_frame(input_status_bad_frame), - .input_status_good_frame(input_status_good_frame), - .output_status_overflow(output_status_overflow), - .output_status_bad_frame(output_status_bad_frame), - .output_status_good_frame(output_status_good_frame) + .s_status_overflow(s_status_overflow), + .s_status_bad_frame(s_status_bad_frame), + .s_status_good_frame(s_status_good_frame), + .m_status_overflow(m_status_overflow), + .m_status_bad_frame(m_status_bad_frame), + .m_status_good_frame(m_status_good_frame) ); endmodule diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index a30818649..9d9ca5f39 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -28,8 +28,8 @@ import os import axis_ep -module = 'axis_async_frame_fifo' -testbench = 'test_%s_64' % module +module = 'axis_async_fifo' +testbench = 'test_axis_async_frame_fifo_64' srcs = [] @@ -47,12 +47,14 @@ def bench(): DATA_WIDTH = 64 KEEP_ENABLE = (DATA_WIDTH>8) KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 ID_ENABLE = 1 ID_WIDTH = 8 DEST_ENABLE = 1 DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + FRAME_FIFO = 1 USER_BAD_FRAME_VALUE = 1 USER_BAD_FRAME_MASK = 1 DROP_BAD_FRAME = 1 @@ -60,34 +62,34 @@ def bench(): # Inputs async_rst = Signal(bool(0)) - input_clk = Signal(bool(0)) - output_clk = Signal(bool(0)) + s_clk = Signal(bool(0)) + m_clk = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - input_status_overflow = Signal(bool(0)) - input_status_bad_frame = Signal(bool(0)) - input_status_good_frame = Signal(bool(0)) - output_status_overflow = Signal(bool(0)) - output_status_bad_frame = Signal(bool(0)) - output_status_good_frame = Signal(bool(0)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_status_overflow = Signal(bool(0)) + s_status_bad_frame = Signal(bool(0)) + s_status_good_frame = Signal(bool(0)) + m_status_overflow = Signal(bool(0)) + m_status_bad_frame = Signal(bool(0)) + m_status_good_frame = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -96,16 +98,16 @@ def bench(): source = axis_ep.AXIStreamSource() source_logic = source.create_logic( - input_clk, + s_clk, async_rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -113,16 +115,16 @@ def bench(): sink = axis_ep.AXIStreamSink() sink_logic = sink.create_logic( - output_clk, + m_clk, async_rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -134,85 +136,85 @@ def bench(): dut = Cosimulation( "vvp -m myhdl %s.vvp -lxt2" % testbench, async_rst=async_rst, - input_clk=input_clk, - output_clk=output_clk, + s_clk=s_clk, + m_clk=m_clk, 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, - input_status_overflow=input_status_overflow, - input_status_bad_frame=input_status_bad_frame, - input_status_good_frame=input_status_good_frame, - output_status_overflow=output_status_overflow, - output_status_bad_frame=output_status_bad_frame, - output_status_good_frame=output_status_good_frame + s_status_overflow=s_status_overflow, + s_status_bad_frame=s_status_bad_frame, + s_status_good_frame=s_status_good_frame, + m_status_overflow=m_status_overflow, + m_status_bad_frame=m_status_bad_frame, + m_status_good_frame=m_status_good_frame ) @always(delay(4)) - def input_clkgen(): - input_clk.next = not input_clk + def s_clkgen(): + s_clk.next = not s_clk @always(delay(5)) - def output_clkgen(): - output_clk.next = not output_clk + def m_clkgen(): + m_clk.next = not m_clk - input_status_overflow_asserted = Signal(bool(0)) - input_status_bad_frame_asserted = Signal(bool(0)) - input_status_good_frame_asserted = Signal(bool(0)) - output_status_overflow_asserted = Signal(bool(0)) - output_status_bad_frame_asserted = Signal(bool(0)) - output_status_good_frame_asserted = Signal(bool(0)) + s_status_overflow_asserted = Signal(bool(0)) + s_status_bad_frame_asserted = Signal(bool(0)) + s_status_good_frame_asserted = Signal(bool(0)) + m_status_overflow_asserted = Signal(bool(0)) + m_status_bad_frame_asserted = Signal(bool(0)) + m_status_good_frame_asserted = Signal(bool(0)) - @always(input_clk.posedge) + @always(s_clk.posedge) def monitor_1(): - if (input_status_overflow): - input_status_overflow_asserted.next = 1 - if (input_status_bad_frame): - input_status_bad_frame_asserted.next = 1 - if (input_status_good_frame): - input_status_good_frame_asserted.next = 1 + if (s_status_overflow): + s_status_overflow_asserted.next = 1 + if (s_status_bad_frame): + s_status_bad_frame_asserted.next = 1 + if (s_status_good_frame): + s_status_good_frame_asserted.next = 1 - @always(output_clk.posedge) + @always(m_clk.posedge) def monitor_2(): - if (output_status_overflow): - output_status_overflow_asserted.next = 1 - if (output_status_bad_frame): - output_status_bad_frame_asserted.next = 1 - if (output_status_good_frame): - output_status_good_frame_asserted.next = 1 + if (m_status_overflow): + m_status_overflow_asserted.next = 1 + if (m_status_bad_frame): + m_status_bad_frame_asserted.next = 1 + if (m_status_good_frame): + m_status_good_frame_asserted.next = 1 @instance def check(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge async_rst.next = 1 - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge async_rst.next = 0 - yield input_clk.posedge + yield s_clk.posedge yield delay(100) - yield input_clk.posedge + yield s_clk.posedge - yield input_clk.posedge + yield s_clk.posedge - yield input_clk.posedge + yield s_clk.posedge print("test 1: test packet") current_test.next = 1 @@ -225,12 +227,12 @@ def bench(): dest=1 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame) @@ -239,16 +241,16 @@ def bench(): assert rx_frame == test_frame - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 2: longer packet") current_test.next = 2 @@ -261,12 +263,12 @@ def bench(): dest=1 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame) @@ -275,14 +277,14 @@ def bench(): assert rx_frame == test_frame - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted - yield input_clk.posedge + yield s_clk.posedge print("test 3: test packet with pauses") current_test.next = 3 @@ -295,28 +297,28 @@ def bench(): dest=1 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame) - yield input_clk.posedge + yield s_clk.posedge yield delay(64) - yield input_clk.posedge + yield s_clk.posedge source_pause.next = True yield delay(32) - yield input_clk.posedge + yield s_clk.posedge source_pause.next = False yield delay(64) - yield output_clk.posedge + yield m_clk.posedge sink_pause.next = True yield delay(32) - yield output_clk.posedge + yield m_clk.posedge sink_pause.next = False yield sink.wait() @@ -324,16 +326,16 @@ def bench(): assert rx_frame == test_frame - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 4: back-to-back packets") current_test.next = 4 @@ -354,12 +356,12 @@ def bench(): dest=2 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) @@ -374,16 +376,16 @@ def bench(): assert rx_frame == test_frame2 - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 5: alternate pause source") current_test.next = 5 @@ -404,24 +406,24 @@ def bench(): dest=2 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge + yield s_clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge source_pause.next = False - yield input_clk.posedge + yield s_clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -433,16 +435,16 @@ def bench(): assert rx_frame == test_frame2 - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 6: alternate pause sink") current_test.next = 6 @@ -463,24 +465,24 @@ def bench(): dest=2 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) - yield input_clk.posedge + yield s_clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge + yield m_clk.posedge + yield m_clk.posedge + yield m_clk.posedge sink_pause.next = False - yield output_clk.posedge + yield m_clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -492,16 +494,16 @@ def bench(): assert rx_frame == test_frame2 - assert not input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 7: tuser assert") current_test.next = 7 @@ -515,30 +517,30 @@ def bench(): last_cycle_user=1 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame) - yield input_clk.posedge + yield s_clk.posedge yield delay(1000) assert sink.empty() - assert not input_status_overflow_asserted - assert input_status_bad_frame_asserted - assert not input_status_good_frame_asserted - assert not output_status_overflow_asserted - assert output_status_bad_frame_asserted - assert not output_status_good_frame_asserted + assert not s_status_overflow_asserted + assert s_status_bad_frame_asserted + assert not s_status_good_frame_asserted + assert not m_status_overflow_asserted + assert m_status_bad_frame_asserted + assert not m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 8: single packet overflow") current_test.next = 8 @@ -551,30 +553,30 @@ def bench(): dest=1 ) - input_status_overflow_asserted.next = 0 - input_status_bad_frame_asserted.next = 0 - input_status_good_frame_asserted.next = 0 - output_status_overflow_asserted.next = 0 - output_status_bad_frame_asserted.next = 0 - output_status_good_frame_asserted.next = 0 + s_status_overflow_asserted.next = 0 + s_status_bad_frame_asserted.next = 0 + s_status_good_frame_asserted.next = 0 + m_status_overflow_asserted.next = 0 + m_status_bad_frame_asserted.next = 0 + m_status_good_frame_asserted.next = 0 source.send(test_frame) - yield input_clk.posedge + yield s_clk.posedge yield delay(10000) assert sink.empty() - assert input_status_overflow_asserted - assert not input_status_bad_frame_asserted - assert not input_status_good_frame_asserted - assert output_status_overflow_asserted - assert not output_status_bad_frame_asserted - assert not output_status_good_frame_asserted + assert s_status_overflow_asserted + assert not s_status_bad_frame_asserted + assert not s_status_good_frame_asserted + assert m_status_overflow_asserted + assert not m_status_bad_frame_asserted + assert not m_status_good_frame_asserted yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 9: initial sink pause") current_test.next = 9 @@ -586,10 +588,10 @@ def bench(): sink_pause.next = 1 source.send(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge sink_pause.next = 0 yield sink.wait() @@ -599,7 +601,7 @@ def bench(): yield delay(100) - yield input_clk.posedge + yield s_clk.posedge print("test 10: initial sink pause, assert reset") current_test.next = 10 @@ -611,22 +613,22 @@ def bench(): sink_pause.next = 1 source.send(test_frame) - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge - yield input_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge async_rst.next = 1 - yield input_clk.posedge + yield s_clk.posedge async_rst.next = 0 sink_pause.next = 0 yield delay(100) - yield output_clk.posedge - yield output_clk.posedge - yield output_clk.posedge + yield m_clk.posedge + yield m_clk.posedge + yield m_clk.posedge assert sink.empty() diff --git a/tb/test_axis_async_frame_fifo_64.v b/tb/test_axis_async_frame_fifo_64.v index 60446b89a..ada5bc5cb 100644 --- a/tb/test_axis_async_frame_fifo_64.v +++ b/tb/test_axis_async_frame_fifo_64.v @@ -27,7 +27,7 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for axis_async_frame_fifo + * Testbench for axis_async_fifo */ module test_axis_async_frame_fifo_64; @@ -36,12 +36,14 @@ parameter ADDR_WIDTH = 6; parameter DATA_WIDTH = 64; parameter KEEP_ENABLE = (DATA_WIDTH>8); parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; parameter ID_ENABLE = 1; parameter ID_WIDTH = 8; parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 1; parameter USER_BAD_FRAME_VALUE = 1'b1; parameter USER_BAD_FRAME_MASK = 1'b1; parameter DROP_BAD_FRAME = 1; @@ -49,66 +51,66 @@ parameter DROP_WHEN_FULL = 0; // Inputs reg async_rst = 0; -reg input_clk = 0; -reg output_clk = 0; +reg s_clk = 0; +reg m_clk = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; -wire input_status_overflow; -wire input_status_bad_frame; -wire input_status_good_frame; -wire output_status_overflow; -wire output_status_bad_frame; -wire output_status_good_frame; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; +wire s_status_overflow; +wire s_status_bad_frame; +wire s_status_good_frame; +wire m_status_overflow; +wire m_status_bad_frame; +wire m_status_good_frame; initial begin // myhdl integration $from_myhdl( async_rst, - input_clk, - output_clk, + s_clk, + m_clk, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser, - input_status_overflow, - input_status_bad_frame, - input_status_good_frame, - output_status_overflow, - output_status_bad_frame, - output_status_good_frame + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser, + s_status_overflow, + s_status_bad_frame, + s_status_good_frame, + m_status_overflow, + m_status_bad_frame, + m_status_good_frame ); // dump file @@ -116,17 +118,19 @@ initial begin $dumpvars(0, test_axis_async_frame_fifo_64); end -axis_async_frame_fifo #( +axis_async_fifo #( .ADDR_WIDTH(ADDR_WIDTH), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), .ID_ENABLE(ID_ENABLE), .ID_WIDTH(ID_WIDTH), .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), .DROP_BAD_FRAME(DROP_BAD_FRAME), @@ -136,32 +140,32 @@ UUT ( // Common reset .async_rst(async_rst), // AXI input - .input_clk(input_clk), - .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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_clk(s_clk), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), // AXI output - .output_clk(output_clk), - .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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_clk(m_clk), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Status - .input_status_overflow(input_status_overflow), - .input_status_bad_frame(input_status_bad_frame), - .input_status_good_frame(input_status_good_frame), - .output_status_overflow(output_status_overflow), - .output_status_bad_frame(output_status_bad_frame), - .output_status_good_frame(output_status_good_frame) + .s_status_overflow(s_status_overflow), + .s_status_bad_frame(s_status_bad_frame), + .s_status_good_frame(s_status_good_frame), + .m_status_overflow(m_status_overflow), + .m_status_bad_frame(m_status_bad_frame), + .m_status_good_frame(m_status_good_frame) ); endmodule From d1ed1528b57ea9f2a8faecb1aa5f3f1200de3a8f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 10:15:16 -0700 Subject: [PATCH 431/617] Update FIFO instance, rename ports --- rtl/axis_frame_length_adjust.v | 328 ++++++++++---------- rtl/axis_frame_length_adjust_fifo.v | 154 ++++----- tb/test_axis_frame_length_adjust_64.py | 102 +++--- tb/test_axis_frame_length_adjust_64.v | 96 +++--- tb/test_axis_frame_length_adjust_8.py | 102 +++--- tb/test_axis_frame_length_adjust_8.v | 96 +++--- tb/test_axis_frame_length_adjust_fifo.py | 128 ++++---- tb/test_axis_frame_length_adjust_fifo.v | 132 ++++---- tb/test_axis_frame_length_adjust_fifo_64.py | 128 ++++---- tb/test_axis_frame_length_adjust_fifo_64.v | 132 ++++---- 10 files changed, 704 insertions(+), 694 deletions(-) diff --git a/rtl/axis_frame_length_adjust.v b/rtl/axis_frame_length_adjust.v index 88297cb18..f1182a049 100644 --- a/rtl/axis_frame_length_adjust.v +++ b/rtl/axis_frame_length_adjust.v @@ -48,26 +48,26 @@ module axis_frame_length_adjust # /* * 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, /* * Status @@ -128,18 +128,18 @@ reg [15:0] status_frame_length_reg = 16'd0, status_frame_length_next; reg [15:0] status_frame_original_length_reg = 16'd0, status_frame_original_length_next; // internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg [ID_WIDTH-1:0] output_axis_tid_int; -reg [DEST_WIDTH-1:0] output_axis_tdest_int; -reg [USER_WIDTH-1:0] output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg [ID_WIDTH-1:0] m_axis_tid_int; +reg [DEST_WIDTH-1:0] m_axis_tdest_int; +reg [USER_WIDTH-1:0] m_axis_tuser_int; +wire m_axis_tready_int_early; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; -assign input_axis_tready = input_axis_tready_reg; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +assign s_axis_tready = s_axis_tready_reg; assign status_valid = status_valid_reg; assign status_frame_pad = status_frame_pad_reg; @@ -159,17 +159,17 @@ always @* begin short_counter_next = short_counter_reg; long_counter_next = long_counter_reg; - output_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tid_int = {ID_WIDTH{1'b0}}; - output_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_axis_tuser_int = {USER_WIDTH{1'b0}}; + m_axis_tdata_int = {DATA_WIDTH{1'b0}}; + m_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tid_int = {ID_WIDTH{1'b0}}; + m_axis_tdest_int = {DEST_WIDTH{1'b0}}; + m_axis_tuser_int = {USER_WIDTH{1'b0}}; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - status_valid_next = status_valid_reg & ~status_ready; + status_valid_next = status_valid_reg && !status_ready; status_frame_pad_next = status_frame_pad_reg; status_frame_truncate_next = status_frame_truncate_reg; status_frame_length_next = status_frame_length_reg; @@ -179,25 +179,25 @@ always @* begin STATE_IDLE: begin // idle state // accept data next cycle if output register ready next cycle - input_axis_tready_next = output_axis_tready_int_early & (~status_valid_reg | status_ready); + s_axis_tready_next = m_axis_tready_int_early && (!status_valid_reg || status_ready); - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = input_axis_tlast; - output_axis_tid_int = input_axis_tid; - output_axis_tdest_int = input_axis_tdest; - output_axis_tuser_int = input_axis_tuser; + m_axis_tdata_int = s_axis_tdata; + m_axis_tkeep_int = s_axis_tkeep; + m_axis_tvalid_int = s_axis_tvalid; + m_axis_tlast_int = s_axis_tlast; + m_axis_tid_int = s_axis_tid; + m_axis_tdest_int = s_axis_tdest; + m_axis_tuser_int = s_axis_tuser; short_counter_next = length_min; long_counter_next = length_max; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // transfer through word_cnt = 0; for (i = 0; i <= KEEP_WIDTH; i = i + 1) begin //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; - if (input_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; + if (s_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; end frame_ptr_next = frame_ptr_reg+KEEP_WIDTH; @@ -214,32 +214,32 @@ always @* begin end if (long_counter_reg <= word_cnt) begin - output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-long_counter_reg); - if (input_axis_tlast) begin + m_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-long_counter_reg); + if (s_axis_tlast) begin status_valid_next = 1'b1; status_frame_pad_next = 1'b0; status_frame_truncate_next = word_cnt > long_counter_reg; status_frame_length_next = length_max; status_frame_original_length_next = frame_ptr_reg+word_cnt; - input_axis_tready_next = output_axis_tready_int_early & status_ready; + s_axis_tready_next = m_axis_tready_int_early && status_ready; frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; state_next = STATE_IDLE; end else begin - output_axis_tvalid_int = 1'b0; + m_axis_tvalid_int = 1'b0; store_last_word = 1'b1; state_next = STATE_TRUNCATE; end end else begin - if (input_axis_tlast) begin + if (s_axis_tlast) begin status_frame_original_length_next = frame_ptr_reg+word_cnt; if (short_counter_reg > word_cnt) begin if (short_counter_reg > KEEP_WIDTH) begin frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; - input_axis_tready_next = 1'b0; - output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; - output_axis_tlast_int = 1'b0; + s_axis_tready_next = 1'b0; + m_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; + m_axis_tlast_int = 1'b0; store_last_word = 1'b1; state_next = STATE_PAD; end else begin @@ -247,8 +247,8 @@ always @* begin status_frame_pad_next = 1'b1; status_frame_truncate_next = 1'b0; status_frame_length_next = length_min; - input_axis_tready_next = output_axis_tready_int_early & status_ready; - output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_min - frame_ptr_reg)); + s_axis_tready_next = m_axis_tready_int_early && status_ready; + m_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-(length_min - frame_ptr_reg)); frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; @@ -260,7 +260,7 @@ always @* begin status_frame_truncate_next = 1'b0; status_frame_length_next = frame_ptr_reg+word_cnt; status_frame_original_length_next = frame_ptr_reg+word_cnt; - input_axis_tready_next = output_axis_tready_int_early & status_ready; + s_axis_tready_next = m_axis_tready_int_early && status_ready; frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; @@ -277,22 +277,22 @@ always @* begin STATE_TRANSFER: begin // transfer data // accept data next cycle if output register ready next cycle - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = input_axis_tlast; - output_axis_tid_int = input_axis_tid; - output_axis_tdest_int = input_axis_tdest; - output_axis_tuser_int = input_axis_tuser; + m_axis_tdata_int = s_axis_tdata; + m_axis_tkeep_int = s_axis_tkeep; + m_axis_tvalid_int = s_axis_tvalid; + m_axis_tlast_int = s_axis_tlast; + m_axis_tid_int = s_axis_tid; + m_axis_tdest_int = s_axis_tdest; + m_axis_tuser_int = s_axis_tuser; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // transfer through word_cnt = 1; for (i = 1; i <= KEEP_WIDTH; i = i + 1) begin //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; - if (input_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; + if (s_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; end frame_ptr_next = frame_ptr_reg+KEEP_WIDTH; @@ -309,32 +309,32 @@ always @* begin end if (long_counter_reg <= word_cnt) begin - output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-long_counter_reg); - if (input_axis_tlast) begin + m_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-long_counter_reg); + if (s_axis_tlast) begin status_valid_next = 1'b1; status_frame_pad_next = 1'b0; status_frame_truncate_next = word_cnt > long_counter_reg; status_frame_length_next = length_max; status_frame_original_length_next = frame_ptr_reg+word_cnt; - input_axis_tready_next = output_axis_tready_int_early & status_ready; + s_axis_tready_next = m_axis_tready_int_early && status_ready; frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; state_next = STATE_IDLE; end else begin - output_axis_tvalid_int = 1'b0; + m_axis_tvalid_int = 1'b0; store_last_word = 1'b1; state_next = STATE_TRUNCATE; end end else begin - if (input_axis_tlast) begin + if (s_axis_tlast) begin status_frame_original_length_next = frame_ptr_reg+word_cnt; if (short_counter_reg > word_cnt) begin if (short_counter_reg > KEEP_WIDTH) begin frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; - input_axis_tready_next = 1'b0; - output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; - output_axis_tlast_int = 1'b0; + s_axis_tready_next = 1'b0; + m_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; + m_axis_tlast_int = 1'b0; store_last_word = 1'b1; state_next = STATE_PAD; end else begin @@ -342,8 +342,8 @@ always @* begin status_frame_pad_next = 1'b1; status_frame_truncate_next = 1'b0; status_frame_length_next = length_min; - input_axis_tready_next = output_axis_tready_int_early & status_ready; - output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-short_counter_reg); + s_axis_tready_next = m_axis_tready_int_early && status_ready; + m_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-short_counter_reg); frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; @@ -355,7 +355,7 @@ always @* begin status_frame_truncate_next = 1'b0; status_frame_length_next = frame_ptr_reg+word_cnt; status_frame_original_length_next = frame_ptr_reg+word_cnt; - input_axis_tready_next = output_axis_tready_int_early & status_ready; + s_axis_tready_next = m_axis_tready_int_early && status_ready; frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; @@ -371,17 +371,17 @@ always @* begin end STATE_PAD: begin // pad to minimum length - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - output_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; - output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = 1'b0; - output_axis_tid_int = last_word_id_reg; - output_axis_tdest_int = last_word_dest_reg; - output_axis_tuser_int = last_word_user_reg; + m_axis_tdata_int = {DATA_WIDTH{1'b0}}; + m_axis_tkeep_int = {KEEP_WIDTH{1'b1}}; + m_axis_tvalid_int = 1'b1; + m_axis_tlast_int = 1'b0; + m_axis_tid_int = last_word_id_reg; + m_axis_tdest_int = last_word_dest_reg; + m_axis_tuser_int = last_word_user_reg; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin frame_ptr_next = frame_ptr_reg + KEEP_WIDTH; if (short_counter_reg > KEEP_WIDTH) begin @@ -401,9 +401,9 @@ always @* begin status_frame_pad_next = 1'b1; status_frame_truncate_next = 1'b0; status_frame_length_next = length_min; - input_axis_tready_next = output_axis_tready_int_early & status_ready; - output_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-short_counter_reg); - output_axis_tlast_int = 1'b1; + s_axis_tready_next = m_axis_tready_int_early && status_ready; + m_axis_tkeep_int = ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-short_counter_reg); + m_axis_tlast_int = 1'b1; frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; @@ -417,31 +417,31 @@ always @* begin end STATE_TRUNCATE: begin // drop after maximum length - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; - output_axis_tdata_int = last_word_data_reg; - output_axis_tkeep_int = last_word_keep_reg; - output_axis_tvalid_int = input_axis_tvalid & input_axis_tlast; - output_axis_tlast_int = input_axis_tlast; - output_axis_tid_int = last_word_id_reg; - output_axis_tdest_int = last_word_dest_reg; - output_axis_tuser_int = input_axis_tuser; + m_axis_tdata_int = last_word_data_reg; + m_axis_tkeep_int = last_word_keep_reg; + m_axis_tvalid_int = s_axis_tvalid && s_axis_tlast; + m_axis_tlast_int = s_axis_tlast; + m_axis_tid_int = last_word_id_reg; + m_axis_tdest_int = last_word_dest_reg; + m_axis_tuser_int = s_axis_tuser; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin word_cnt = 0; for (i = 0; i <= KEEP_WIDTH; i = i + 1) begin //bit_cnt = bit_cnt + monitor_axis_tkeep[i]; - if (input_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; + if (s_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) word_cnt = i; end frame_ptr_next = frame_ptr_reg+KEEP_WIDTH; - if (input_axis_tlast) begin + if (s_axis_tlast) begin status_valid_next = 1'b1; status_frame_pad_next = 1'b0; status_frame_truncate_next = 1'b1; status_frame_length_next = length_max; status_frame_original_length_next = frame_ptr_reg+word_cnt; - input_axis_tready_next = output_axis_tready_int_early & status_ready; + s_axis_tready_next = m_axis_tready_int_early && status_ready; frame_ptr_next = 16'd0; short_counter_next = length_min; long_counter_next = length_max; @@ -462,7 +462,7 @@ always @(posedge clk) begin frame_ptr_reg <= 16'd0; short_counter_reg <= 16'd0; long_counter_reg <= 16'd0; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; status_valid_reg <= 1'b0; end else begin state_reg <= state_next; @@ -472,7 +472,7 @@ always @(posedge clk) begin short_counter_reg <= short_counter_next; long_counter_reg <= long_counter_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; status_valid_reg <= status_valid_next; end @@ -483,110 +483,110 @@ always @(posedge clk) begin status_frame_original_length_reg <= status_frame_original_length_next; if (store_last_word) begin - last_word_data_reg <= output_axis_tdata_int; - last_word_keep_reg <= output_axis_tkeep_int; - last_word_id_reg <= output_axis_tid_int; - last_word_dest_reg <= output_axis_tdest_int; - last_word_user_reg <= output_axis_tuser_int; + last_word_data_reg <= m_axis_tdata_int; + last_word_keep_reg <= m_axis_tkeep_int; + last_word_id_reg <= m_axis_tid_int; + last_word_dest_reg <= m_axis_tdest_int; + last_word_user_reg <= m_axis_tuser_int; end end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tid_reg <= output_axis_tid_int; - output_axis_tdest_reg <= output_axis_tdest_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tid_reg <= m_axis_tid_int; + m_axis_tdest_reg <= m_axis_tdest_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tid_reg <= output_axis_tid_int; - temp_axis_tdest_reg <= output_axis_tdest_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tid_reg <= m_axis_tid_int; + temp_m_axis_tdest_reg <= m_axis_tdest_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/rtl/axis_frame_length_adjust_fifo.v b/rtl/axis_frame_length_adjust_fifo.v index c1ae3edb8..d82e804e1 100644 --- a/rtl/axis_frame_length_adjust_fifo.v +++ b/rtl/axis_frame_length_adjust_fifo.v @@ -50,32 +50,32 @@ module axis_frame_length_adjust_fifo # /* * 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * AXI output */ - output wire output_axis_hdr_valid, - input wire output_axis_hdr_ready, - output wire output_axis_hdr_pad, - output wire output_axis_hdr_truncate, - output wire [15:0] output_axis_hdr_length, - output wire [15:0] output_axis_hdr_original_length, - 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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser, + output wire m_axis_hdr_valid, + input wire m_axis_hdr_ready, + output wire m_axis_hdr_pad, + output wire m_axis_hdr_truncate, + output wire [15:0] m_axis_hdr_length, + output wire [15:0] m_axis_hdr_original_length, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, /* * Configuration @@ -115,23 +115,23 @@ axis_frame_length_adjust_inst ( .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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), // AXI output - .output_axis_tdata(fifo_axis_tdata), - .output_axis_tkeep(fifo_axis_tkeep), - .output_axis_tvalid(fifo_axis_tvalid), - .output_axis_tready(fifo_axis_tready), - .output_axis_tlast(fifo_axis_tlast), - .output_axis_tid(fifo_axis_tid), - .output_axis_tdest(fifo_axis_tdest), - .output_axis_tuser(fifo_axis_tuser), + .m_axis_tdata(fifo_axis_tdata), + .m_axis_tkeep(fifo_axis_tkeep), + .m_axis_tvalid(fifo_axis_tvalid), + .m_axis_tready(fifo_axis_tready), + .m_axis_tlast(fifo_axis_tlast), + .m_axis_tid(fifo_axis_tid), + .m_axis_tdest(fifo_axis_tdest), + .m_axis_tuser(fifo_axis_tuser), // Status .status_valid(status_valid), .status_ready(status_ready), @@ -155,29 +155,34 @@ axis_fifo #( .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(0) ) frame_fifo_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(fifo_axis_tdata), - .input_axis_tkeep(fifo_axis_tkeep), - .input_axis_tvalid(fifo_axis_tvalid), - .input_axis_tready(fifo_axis_tready), - .input_axis_tlast(fifo_axis_tlast), - .input_axis_tid(fifo_axis_tid), - .input_axis_tdest(fifo_axis_tdest), - .input_axis_tuser(fifo_axis_tuser), + .s_axis_tdata(fifo_axis_tdata), + .s_axis_tkeep(fifo_axis_tkeep), + .s_axis_tvalid(fifo_axis_tvalid), + .s_axis_tready(fifo_axis_tready), + .s_axis_tlast(fifo_axis_tlast), + .s_axis_tid(fifo_axis_tid), + .s_axis_tdest(fifo_axis_tdest), + .s_axis_tuser(fifo_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), + // Status + .overflow(), + .bad_frame(), + .good_frame() ); axis_fifo #( @@ -187,29 +192,34 @@ axis_fifo #( .LAST_ENABLE(0), .ID_ENABLE(0), .DEST_ENABLE(0), - .USER_ENABLE(0) + .USER_ENABLE(0), + .FRAME_FIFO(0) ) header_fifo_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata({status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length}), - .input_axis_tkeep(0), - .input_axis_tvalid(status_valid), - .input_axis_tready(status_ready), - .input_axis_tlast(0), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(0), + .s_axis_tdata({status_frame_pad, status_frame_truncate, status_frame_length, status_frame_original_length}), + .s_axis_tkeep(0), + .s_axis_tvalid(status_valid), + .s_axis_tready(status_ready), + .s_axis_tlast(0), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(0), // AXI output - .output_axis_tdata({output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length}), - .output_axis_tkeep(), - .output_axis_tvalid(output_axis_hdr_valid), - .output_axis_tready(output_axis_hdr_ready), - .output_axis_tlast(), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser() + .m_axis_tdata({m_axis_hdr_pad, m_axis_hdr_truncate, m_axis_hdr_length, m_axis_hdr_original_length}), + .m_axis_tkeep(), + .m_axis_tvalid(m_axis_hdr_valid), + .m_axis_tready(m_axis_hdr_ready), + .m_axis_tlast(), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(), + // Status + .overflow(), + .bad_frame(), + .good_frame() ); endmodule diff --git a/tb/test_axis_frame_length_adjust_64.py b/tb/test_axis_frame_length_adjust_64.py index d864a2910..c2dc03188 100755 --- a/tb/test_axis_frame_length_adjust_64.py +++ b/tb/test_axis_frame_length_adjust_64.py @@ -58,27 +58,27 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) status_ready = Signal(bool(0)) length_min = Signal(intbv(0)[16:]) length_max = Signal(intbv(0)[16:]) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) status_valid = Signal(bool(0)) status_frame_pad = Signal(bool(0)) status_frame_truncate = Signal(bool(0)) @@ -95,14 +95,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -112,14 +112,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -146,23 +146,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, status_valid=status_valid, status_ready=status_ready, @@ -180,11 +180,11 @@ def bench(): clk.next = not clk def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -193,7 +193,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_frame_length_adjust_64.v b/tb/test_axis_frame_length_adjust_64.v index b02e7611e..0f6a31014 100644 --- a/tb/test_axis_frame_length_adjust_64.v +++ b/tb/test_axis_frame_length_adjust_64.v @@ -47,27 +47,27 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; reg status_ready = 0; reg [15:0] length_min = 0; reg [15:0] length_max = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; wire status_valid; wire status_frame_pad; wire status_frame_truncate; @@ -80,27 +80,27 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready, status_ready, length_min, length_max ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser, status_valid, status_frame_pad, status_frame_truncate, @@ -128,23 +128,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Status .status_valid(status_valid), .status_ready(status_ready), diff --git a/tb/test_axis_frame_length_adjust_8.py b/tb/test_axis_frame_length_adjust_8.py index 86235c487..cf7177225 100755 --- a/tb/test_axis_frame_length_adjust_8.py +++ b/tb/test_axis_frame_length_adjust_8.py @@ -58,27 +58,27 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) status_ready = Signal(bool(0)) length_min = Signal(intbv(0)[16:]) length_max = Signal(intbv(0)[16:]) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) status_valid = Signal(bool(0)) status_frame_pad = Signal(bool(0)) status_frame_truncate = Signal(bool(0)) @@ -95,14 +95,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -112,14 +112,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -146,23 +146,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, status_valid=status_valid, status_ready=status_ready, @@ -180,11 +180,11 @@ def bench(): clk.next = not clk def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -193,7 +193,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_frame_length_adjust_8.v b/tb/test_axis_frame_length_adjust_8.v index 93cc4f1ab..ea65c815d 100644 --- a/tb/test_axis_frame_length_adjust_8.v +++ b/tb/test_axis_frame_length_adjust_8.v @@ -47,27 +47,27 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; reg status_ready = 0; reg [15:0] length_min = 0; reg [15:0] length_max = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; wire status_valid; wire status_frame_pad; wire status_frame_truncate; @@ -80,27 +80,27 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready, status_ready, length_min, length_max ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser, status_valid, status_frame_pad, status_frame_truncate, @@ -128,23 +128,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Status .status_valid(status_valid), .status_ready(status_ready), diff --git a/tb/test_axis_frame_length_adjust_fifo.py b/tb/test_axis_frame_length_adjust_fifo.py index f01edada1..7cf95db9c 100755 --- a/tb/test_axis_frame_length_adjust_fifo.py +++ b/tb/test_axis_frame_length_adjust_fifo.py @@ -62,32 +62,32 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_hdr_ready = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_hdr_ready = Signal(bool(0)) + m_axis_tready = Signal(bool(0)) length_min = Signal(intbv(0)[16:]) length_max = Signal(intbv(0)[16:]) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_hdr_valid = Signal(bool(0)) - output_axis_hdr_pad = Signal(bool(0)) - output_axis_hdr_truncate = Signal(bool(0)) - output_axis_hdr_length = Signal(intbv(0)[16:]) - output_axis_hdr_original_length = Signal(intbv(0)[16:]) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_hdr_valid = Signal(bool(0)) + m_axis_hdr_pad = Signal(bool(0)) + m_axis_hdr_truncate = Signal(bool(0)) + m_axis_hdr_length = Signal(intbv(0)[16:]) + m_axis_hdr_original_length = Signal(intbv(0)[16:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -99,14 +99,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -116,14 +116,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -133,9 +133,9 @@ def bench(): hdr_sink_logic = hdr_sink.create_logic( clk, rst, - tdata=(output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length), - tvalid=output_axis_hdr_valid, - tready=output_axis_hdr_ready, + tdata=(m_axis_hdr_pad, m_axis_hdr_truncate, m_axis_hdr_length, m_axis_hdr_original_length), + tvalid=m_axis_hdr_valid, + tready=m_axis_hdr_ready, pause=hdr_sink_pause, name='hdr_sink' ) @@ -150,29 +150,29 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, - output_axis_hdr_valid=output_axis_hdr_valid, - output_axis_hdr_ready=output_axis_hdr_ready, - output_axis_hdr_pad=output_axis_hdr_pad, - output_axis_hdr_truncate=output_axis_hdr_truncate, - output_axis_hdr_length=output_axis_hdr_length, - output_axis_hdr_original_length=output_axis_hdr_original_length, - 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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_hdr_valid=m_axis_hdr_valid, + m_axis_hdr_ready=m_axis_hdr_ready, + m_axis_hdr_pad=m_axis_hdr_pad, + m_axis_hdr_truncate=m_axis_hdr_truncate, + m_axis_hdr_length=m_axis_hdr_length, + m_axis_hdr_original_length=m_axis_hdr_original_length, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, length_min=length_min, length_max=length_max @@ -183,7 +183,7 @@ def bench(): clk.next = not clk def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge @instance diff --git a/tb/test_axis_frame_length_adjust_fifo.v b/tb/test_axis_frame_length_adjust_fifo.v index c5a2715aa..c8ae07b8f 100644 --- a/tb/test_axis_frame_length_adjust_fifo.v +++ b/tb/test_axis_frame_length_adjust_fifo.v @@ -49,32 +49,32 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_hdr_ready = 0; -reg output_axis_tready = 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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_hdr_ready = 0; +reg m_axis_tready = 0; reg [15:0] length_min = 0; reg [15:0] length_max = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; -wire output_axis_hdr_valid; -wire output_axis_hdr_pad; -wire output_axis_hdr_truncate; -wire [15:0] output_axis_hdr_length; -wire [15:0] output_axis_hdr_original_length; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; +wire m_axis_hdr_valid; +wire m_axis_hdr_pad; +wire m_axis_hdr_truncate; +wire [15:0] m_axis_hdr_length; +wire [15:0] m_axis_hdr_original_length; initial begin // myhdl integration @@ -82,32 +82,32 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_hdr_ready, - output_axis_tready, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_hdr_ready, + m_axis_tready, length_min, length_max ); $to_myhdl( - input_axis_tready, - output_axis_hdr_valid, - output_axis_hdr_pad, - output_axis_hdr_truncate, - output_axis_hdr_length, - output_axis_hdr_original_length, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_hdr_valid, + m_axis_hdr_pad, + m_axis_hdr_truncate, + m_axis_hdr_length, + m_axis_hdr_original_length, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -132,29 +132,29 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), // AXI output - .output_axis_hdr_valid(output_axis_hdr_valid), - .output_axis_hdr_ready(output_axis_hdr_ready), - .output_axis_hdr_pad(output_axis_hdr_pad), - .output_axis_hdr_truncate(output_axis_hdr_truncate), - .output_axis_hdr_length(output_axis_hdr_length), - .output_axis_hdr_original_length(output_axis_hdr_original_length), - .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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_hdr_valid(m_axis_hdr_valid), + .m_axis_hdr_ready(m_axis_hdr_ready), + .m_axis_hdr_pad(m_axis_hdr_pad), + .m_axis_hdr_truncate(m_axis_hdr_truncate), + .m_axis_hdr_length(m_axis_hdr_length), + .m_axis_hdr_original_length(m_axis_hdr_original_length), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Configuration .length_min(length_min), .length_max(length_max) diff --git a/tb/test_axis_frame_length_adjust_fifo_64.py b/tb/test_axis_frame_length_adjust_fifo_64.py index c816c0661..cb7d0163c 100755 --- a/tb/test_axis_frame_length_adjust_fifo_64.py +++ b/tb/test_axis_frame_length_adjust_fifo_64.py @@ -62,32 +62,32 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_hdr_ready = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_hdr_ready = Signal(bool(0)) + m_axis_tready = Signal(bool(0)) length_min = Signal(intbv(0)[16:]) length_max = Signal(intbv(0)[16:]) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_hdr_valid = Signal(bool(0)) - output_axis_hdr_pad = Signal(bool(0)) - output_axis_hdr_truncate = Signal(bool(0)) - output_axis_hdr_length = Signal(intbv(0)[16:]) - output_axis_hdr_original_length = Signal(intbv(0)[16:]) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_hdr_valid = Signal(bool(0)) + m_axis_hdr_pad = Signal(bool(0)) + m_axis_hdr_truncate = Signal(bool(0)) + m_axis_hdr_length = Signal(intbv(0)[16:]) + m_axis_hdr_original_length = Signal(intbv(0)[16:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -99,14 +99,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -116,14 +116,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -133,9 +133,9 @@ def bench(): hdr_sink_logic = hdr_sink.create_logic( clk, rst, - tdata=(output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length), - tvalid=output_axis_hdr_valid, - tready=output_axis_hdr_ready, + tdata=(m_axis_hdr_pad, m_axis_hdr_truncate, m_axis_hdr_length, m_axis_hdr_original_length), + tvalid=m_axis_hdr_valid, + tready=m_axis_hdr_ready, pause=hdr_sink_pause, name='hdr_sink' ) @@ -150,29 +150,29 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, - output_axis_hdr_valid=output_axis_hdr_valid, - output_axis_hdr_ready=output_axis_hdr_ready, - output_axis_hdr_pad=output_axis_hdr_pad, - output_axis_hdr_truncate=output_axis_hdr_truncate, - output_axis_hdr_length=output_axis_hdr_length, - output_axis_hdr_original_length=output_axis_hdr_original_length, - 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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_hdr_valid=m_axis_hdr_valid, + m_axis_hdr_ready=m_axis_hdr_ready, + m_axis_hdr_pad=m_axis_hdr_pad, + m_axis_hdr_truncate=m_axis_hdr_truncate, + m_axis_hdr_length=m_axis_hdr_length, + m_axis_hdr_original_length=m_axis_hdr_original_length, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, length_min=length_min, length_max=length_max @@ -183,7 +183,7 @@ def bench(): clk.next = not clk def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge @instance diff --git a/tb/test_axis_frame_length_adjust_fifo_64.v b/tb/test_axis_frame_length_adjust_fifo_64.v index 169efa5ae..f5fdc6d61 100644 --- a/tb/test_axis_frame_length_adjust_fifo_64.v +++ b/tb/test_axis_frame_length_adjust_fifo_64.v @@ -49,32 +49,32 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_hdr_ready = 0; -reg output_axis_tready = 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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_hdr_ready = 0; +reg m_axis_tready = 0; reg [15:0] length_min = 0; reg [15:0] length_max = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; -wire output_axis_hdr_valid; -wire output_axis_hdr_pad; -wire output_axis_hdr_truncate; -wire [15:0] output_axis_hdr_length; -wire [15:0] output_axis_hdr_original_length; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; +wire m_axis_hdr_valid; +wire m_axis_hdr_pad; +wire m_axis_hdr_truncate; +wire [15:0] m_axis_hdr_length; +wire [15:0] m_axis_hdr_original_length; initial begin // myhdl integration @@ -82,32 +82,32 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_hdr_ready, - output_axis_tready, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_hdr_ready, + m_axis_tready, length_min, length_max ); $to_myhdl( - input_axis_tready, - output_axis_hdr_valid, - output_axis_hdr_pad, - output_axis_hdr_truncate, - output_axis_hdr_length, - output_axis_hdr_original_length, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_hdr_valid, + m_axis_hdr_pad, + m_axis_hdr_truncate, + m_axis_hdr_length, + m_axis_hdr_original_length, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -132,29 +132,29 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), // AXI output - .output_axis_hdr_valid(output_axis_hdr_valid), - .output_axis_hdr_ready(output_axis_hdr_ready), - .output_axis_hdr_pad(output_axis_hdr_pad), - .output_axis_hdr_truncate(output_axis_hdr_truncate), - .output_axis_hdr_length(output_axis_hdr_length), - .output_axis_hdr_original_length(output_axis_hdr_original_length), - .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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_hdr_valid(m_axis_hdr_valid), + .m_axis_hdr_ready(m_axis_hdr_ready), + .m_axis_hdr_pad(m_axis_hdr_pad), + .m_axis_hdr_truncate(m_axis_hdr_truncate), + .m_axis_hdr_length(m_axis_hdr_length), + .m_axis_hdr_original_length(m_axis_hdr_original_length), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Configuration .length_min(length_min), .length_max(length_max) From c47f3ea03d53219d26467cf88f8537444e0c10a8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 10:17:58 -0700 Subject: [PATCH 432/617] Update FIFO instance, rename ports --- rtl/axis_cobs_decode.v | 216 ++++++++++----------- rtl/axis_cobs_encode.v | 250 +++++++++++++------------ tb/test_axis_cobs_decode.py | 66 +++---- tb/test_axis_cobs_decode.v | 60 +++--- tb/test_axis_cobs_encode.py | 66 +++---- tb/test_axis_cobs_encode.v | 60 +++--- tb/test_axis_cobs_encode_zero_frame.py | 66 +++---- tb/test_axis_cobs_encode_zero_frame.v | 60 +++--- 8 files changed, 427 insertions(+), 417 deletions(-) diff --git a/rtl/axis_cobs_decode.v b/rtl/axis_cobs_decode.v index a6cff3d09..aed0b1ef7 100644 --- a/rtl/axis_cobs_decode.v +++ b/rtl/axis_cobs_decode.v @@ -37,20 +37,20 @@ module axis_cobs_decode /* * AXI input */ - input wire [7:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [7:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * AXI output */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser + output wire [7:0] m_axis_tdata, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser ); // state register @@ -68,16 +68,16 @@ reg [7:0] temp_tdata_reg = 8'd0, temp_tdata_next; reg temp_tvalid_reg = 1'b0, temp_tvalid_next; // internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [7:0] m_axis_tdata_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; always @* begin state_next = STATE_IDLE; @@ -88,33 +88,33 @@ always @* begin temp_tdata_next = temp_tdata_reg; temp_tvalid_next = temp_tvalid_reg; - output_axis_tdata_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 8'd0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - input_axis_tready_next = output_axis_tready_int_early | ~temp_tvalid_reg; + s_axis_tready_next = m_axis_tready_int_early || !temp_tvalid_reg; // output final word - output_axis_tdata_int = temp_tdata_reg; - output_axis_tvalid_int = temp_tvalid_reg; - output_axis_tlast_int = temp_tvalid_reg; - temp_tvalid_next = temp_tvalid_reg & ~output_axis_tready_int_reg; + m_axis_tdata_int = temp_tdata_reg; + m_axis_tvalid_int = temp_tvalid_reg; + m_axis_tlast_int = temp_tvalid_reg; + temp_tvalid_next = temp_tvalid_reg && !m_axis_tready_int_reg; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // valid input data // skip any leading zeros - if (input_axis_tdata != 8'd0) begin + if (s_axis_tdata != 8'd0) begin // store count value and zero suppress - count_next = input_axis_tdata-1; - suppress_zero_next = (input_axis_tdata == 8'd255); - input_axis_tready_next = output_axis_tready_int_early; - if (input_axis_tdata == 8'd1) begin + count_next = s_axis_tdata-1; + suppress_zero_next = (s_axis_tdata == 8'd255); + s_axis_tready_next = m_axis_tready_int_early; + if (s_axis_tdata == 8'd1) begin // next byte will be count value state_next = STATE_NEXT_SEGMENT; end else begin @@ -130,38 +130,38 @@ always @* begin end STATE_SEGMENT: begin // receive segment - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // valid input data // store in temp register - temp_tdata_next = input_axis_tdata; + temp_tdata_next = s_axis_tdata; temp_tvalid_next = 1'b1; // move temp to output - output_axis_tdata_int = temp_tdata_reg; - output_axis_tvalid_int = temp_tvalid_reg; + m_axis_tdata_int = temp_tdata_reg; + m_axis_tvalid_int = temp_tvalid_reg; // decrement count count_next = count_reg - 1; - if (input_axis_tdata == 8'd0) begin + if (s_axis_tdata == 8'd0) begin // got a zero byte in a frame - mark it as an error and re-sync temp_tvalid_next = 1'b0; - output_axis_tvalid_int = 1'b1; - output_axis_tuser_int = 1'b1; - output_axis_tlast_int = 1'b1; - input_axis_tready_next = 1'b1; + m_axis_tvalid_int = 1'b1; + m_axis_tuser_int = 1'b1; + m_axis_tlast_int = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; - end else if (input_axis_tlast) begin + end else if (s_axis_tlast) begin // end of frame - if (count_reg == 8'd1 && ~input_axis_tuser) begin + if (count_reg == 8'd1 && !s_axis_tuser) begin // end of frame indication at correct time, go to idle to output final byte state_next = STATE_IDLE; end else begin // end of frame indication at invalid time or tuser assert, so mark as an error and re-sync temp_tvalid_next = 1'b0; - output_axis_tvalid_int = 1'b1; - output_axis_tuser_int = 1'b1; - output_axis_tlast_int = 1'b1; - input_axis_tready_next = 1'b1; + m_axis_tvalid_int = 1'b1; + m_axis_tuser_int = 1'b1; + m_axis_tlast_int = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else if (count_reg == 8'd1) begin @@ -177,42 +177,42 @@ always @* begin end STATE_NEXT_SEGMENT: begin // next segment - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // valid input data // store zero in temp if not suppressed temp_tdata_next = 8'd0; - temp_tvalid_next = ~suppress_zero_reg; + temp_tvalid_next = !suppress_zero_reg; // move temp to output - output_axis_tdata_int = temp_tdata_reg; - output_axis_tvalid_int = temp_tvalid_reg; - if (input_axis_tdata == 8'd0) begin + m_axis_tdata_int = temp_tdata_reg; + m_axis_tvalid_int = temp_tvalid_reg; + if (s_axis_tdata == 8'd0) begin // got a zero byte delineating the end of the frame, so mark as such and re-sync temp_tvalid_next = 1'b0; - output_axis_tuser_int = input_axis_tuser; - output_axis_tlast_int = 1'b1; - input_axis_tready_next = 1'b1; + m_axis_tuser_int = s_axis_tuser; + m_axis_tlast_int = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; - end else if (input_axis_tlast) begin - if (input_axis_tdata == 8'd1 && ~input_axis_tuser) begin + end else if (s_axis_tlast) begin + if (s_axis_tdata == 8'd1 && !s_axis_tuser) begin // end of frame indication at correct time, go to idle to output final byte state_next = STATE_IDLE; end else begin // end of frame indication at invalid time or tuser assert, so mark as an error and re-sync temp_tvalid_next = 1'b0; - output_axis_tvalid_int = 1'b1; - output_axis_tuser_int = 1'b1; - output_axis_tlast_int = 1'b1; - input_axis_tready_next = 1'b1; + m_axis_tvalid_int = 1'b1; + m_axis_tuser_int = 1'b1; + m_axis_tlast_int = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else begin // otherwise, store count value and zero suppress - count_next = input_axis_tdata-1; - suppress_zero_next = (input_axis_tdata == 8'd255); - input_axis_tready_next = output_axis_tready_int_early; - if (input_axis_tdata == 8'd1) begin + count_next = s_axis_tdata-1; + suppress_zero_next = (s_axis_tdata == 8'd255); + s_axis_tready_next = m_axis_tready_int_early; + if (s_axis_tdata == 8'd1) begin // next byte will be count value state_next = STATE_NEXT_SEGMENT; end else begin @@ -231,11 +231,11 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; temp_tvalid_reg <= 1'b0; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; end else begin state_reg <= state_next; temp_tvalid_reg <= temp_tvalid_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; end temp_tdata_reg <= temp_tdata_next; @@ -245,83 +245,83 @@ always @(posedge clk) begin end // output datapath logic -reg [7:0] output_axis_tdata_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg [7:0] m_axis_tdata_reg = 8'd0; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg [7:0] temp_m_axis_tdata_reg = 8'd0; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/rtl/axis_cobs_encode.v b/rtl/axis_cobs_encode.v index eaa1e76a8..79a7d07b3 100644 --- a/rtl/axis_cobs_encode.v +++ b/rtl/axis_cobs_encode.v @@ -41,20 +41,20 @@ module axis_cobs_encode # /* * AXI input */ - input wire [7:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [7:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * AXI output */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser + output wire [7:0] m_axis_tdata, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser ); // state register @@ -77,16 +77,16 @@ reg [7:0] output_count_reg = 8'd0, output_count_next; reg fail_frame_reg = 1'b0, fail_frame_next; // internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [7:0] m_axis_tdata_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; -reg input_axis_tready_mask; +reg s_axis_tready_mask; -assign input_axis_tready = code_fifo_in_tready & data_fifo_in_tready & input_axis_tready_mask; +assign s_axis_tready = code_fifo_in_tready && data_fifo_in_tready && s_axis_tready_mask; reg [7:0] code_fifo_in_tdata; reg code_fifo_in_tvalid; @@ -108,29 +108,34 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) code_fifo_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(code_fifo_in_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(code_fifo_in_tvalid), - .input_axis_tready(code_fifo_in_tready), - .input_axis_tlast(code_fifo_in_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(code_fifo_in_tuser), + .s_axis_tdata(code_fifo_in_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(code_fifo_in_tvalid), + .s_axis_tready(code_fifo_in_tready), + .s_axis_tlast(code_fifo_in_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(code_fifo_in_tuser), // AXI output - .output_axis_tdata(code_fifo_out_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(code_fifo_out_tvalid), - .output_axis_tready(code_fifo_out_tready), - .output_axis_tlast(code_fifo_out_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(code_fifo_out_tuser) + .m_axis_tdata(code_fifo_out_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(code_fifo_out_tvalid), + .m_axis_tready(code_fifo_out_tready), + .m_axis_tlast(code_fifo_out_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(code_fifo_out_tuser), + // Status + .overflow(), + .bad_frame(), + .good_frame() ); reg [7:0] data_fifo_in_tdata; @@ -150,29 +155,34 @@ axis_fifo #( .LAST_ENABLE(1), .ID_ENABLE(0), .DEST_ENABLE(0), - .USER_ENABLE(0) + .USER_ENABLE(0), + .FRAME_FIFO(0) ) data_fifo_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(data_fifo_in_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(data_fifo_in_tvalid), - .input_axis_tready(data_fifo_in_tready), - .input_axis_tlast(data_fifo_in_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(0), + .s_axis_tdata(data_fifo_in_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(data_fifo_in_tvalid), + .s_axis_tready(data_fifo_in_tready), + .s_axis_tlast(data_fifo_in_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(0), // AXI output - .output_axis_tdata(data_fifo_out_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(data_fifo_out_tvalid), - .output_axis_tready(data_fifo_out_tready), - .output_axis_tlast(data_fifo_out_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser() + .m_axis_tdata(data_fifo_out_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(data_fifo_out_tvalid), + .m_axis_tready(data_fifo_out_tready), + .m_axis_tlast(data_fifo_out_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(), + // Status + .overflow(), + .bad_frame(), + .good_frame() ); always @* begin @@ -182,33 +192,33 @@ always @* begin fail_frame_next = fail_frame_reg; - input_axis_tready_mask = 1'b0; + s_axis_tready_mask = 1'b0; code_fifo_in_tdata = 8'd0; code_fifo_in_tvalid = 1'b0; code_fifo_in_tlast = 1'b0; code_fifo_in_tuser = 1'b0; - data_fifo_in_tdata = input_axis_tdata; + data_fifo_in_tdata = s_axis_tdata; data_fifo_in_tvalid = 1'b0; data_fifo_in_tlast = 1'b0; case (input_state_reg) INPUT_STATE_IDLE: begin // idle state - input_axis_tready_mask = 1'b1; + s_axis_tready_mask = 1'b1; fail_frame_next = 1'b0; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // valid input data - if (input_axis_tdata == 8'd0 || (input_axis_tlast & input_axis_tuser)) begin + if (s_axis_tdata == 8'd0 || (s_axis_tlast && s_axis_tuser)) begin // got a zero or propagated error, so store a zero code code_fifo_in_tdata = 8'd1; code_fifo_in_tvalid = 1'b1; - if (input_axis_tlast) begin + if (s_axis_tlast) begin // last byte, so close out the frame - fail_frame_next = input_axis_tuser; + fail_frame_next = s_axis_tuser; input_state_next = INPUT_STATE_FINAL_ZERO; end else begin // return to idle to await next segment @@ -217,9 +227,9 @@ always @* begin end else begin // got something other than a zero, so store it and init the segment counter input_count_next = 8'd2; - data_fifo_in_tdata = input_axis_tdata; + data_fifo_in_tdata = s_axis_tdata; data_fifo_in_tvalid = 1'b1; - if (input_axis_tlast) begin + if (s_axis_tlast) begin // last byte, so store the code and close out the frame code_fifo_in_tdata = 8'd2; code_fifo_in_tvalid = 1'b1; @@ -242,19 +252,19 @@ always @* begin end INPUT_STATE_SEGMENT: begin // encode segment - input_axis_tready_mask = 1'b1; + s_axis_tready_mask = 1'b1; fail_frame_next = 1'b0; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // valid input data - if (input_axis_tdata == 8'd0 || (input_axis_tlast & input_axis_tuser)) begin + if (s_axis_tdata == 8'd0 || (s_axis_tlast && s_axis_tuser)) begin // got a zero or propagated error, so store the code code_fifo_in_tdata = input_count_reg; code_fifo_in_tvalid = 1'b1; - if (input_axis_tlast) begin + if (s_axis_tlast) begin // last byte, so close out the frame - fail_frame_next = input_axis_tuser; + fail_frame_next = s_axis_tuser; input_state_next = INPUT_STATE_FINAL_ZERO; end else begin // return to idle to await next segment @@ -263,7 +273,7 @@ always @* begin end else begin // got something other than a zero, so store it and increment the segment counter input_count_next = input_count_reg+1; - data_fifo_in_tdata = input_axis_tdata; + data_fifo_in_tdata = s_axis_tdata; data_fifo_in_tvalid = 1'b1; if (input_count_reg == 8'd254) begin // 254 bytes in frame, so dump and reset counter @@ -271,7 +281,7 @@ always @* begin code_fifo_in_tvalid = 1'b1; input_count_next = 8'd1; end - if (input_axis_tlast) begin + if (s_axis_tlast) begin // last byte, so store the code and close out the frame code_fifo_in_tdata = input_count_reg+1; code_fifo_in_tvalid = 1'b1; @@ -294,7 +304,7 @@ always @* begin end INPUT_STATE_FINAL_ZERO: begin // final zero code required - input_axis_tready_mask = 1'b0; + s_axis_tready_mask = 1'b0; if (code_fifo_in_tready) begin // push a zero code and close out frame @@ -320,7 +330,7 @@ always @* begin end INPUT_STATE_APPEND_ZERO: begin // append zero for zero framing - input_axis_tready_mask = 1'b0; + s_axis_tready_mask = 1'b0; if (code_fifo_in_tready) begin // push frame termination code and close out frame @@ -342,10 +352,10 @@ always @* begin output_count_next = output_count_reg; - output_axis_tdata_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 8'd0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; code_fifo_out_tready = 1'b0; @@ -355,13 +365,13 @@ always @* begin OUTPUT_STATE_IDLE: begin // idle state - if (output_axis_tready_int_reg & code_fifo_out_tvalid) begin + if (m_axis_tready_int_reg && code_fifo_out_tvalid) begin // transfer out code byte and load counter - output_axis_tdata_int = code_fifo_out_tdata; - output_axis_tlast_int = code_fifo_out_tlast; - output_axis_tuser_int = code_fifo_out_tuser & code_fifo_out_tlast; + m_axis_tdata_int = code_fifo_out_tdata; + m_axis_tlast_int = code_fifo_out_tlast; + m_axis_tuser_int = code_fifo_out_tuser && code_fifo_out_tlast; output_count_next = code_fifo_out_tdata-1; - output_axis_tvalid_int = 1'b1; + m_axis_tvalid_int = 1'b1; code_fifo_out_tready = 1'b1; if (code_fifo_out_tdata == 8'd0 || code_fifo_out_tdata == 8'd1 || code_fifo_out_tuser) begin // frame termination and zero codes will be followed by codes @@ -377,12 +387,12 @@ always @* begin OUTPUT_STATE_SEGMENT: begin // segment output - if (output_axis_tready_int_reg & data_fifo_out_tvalid) begin + if (m_axis_tready_int_reg && data_fifo_out_tvalid) begin // transfer out data byte and decrement counter - output_axis_tdata_int = data_fifo_out_tdata; - output_axis_tlast_int = data_fifo_out_tlast; + m_axis_tdata_int = data_fifo_out_tdata; + m_axis_tlast_int = data_fifo_out_tlast; output_count_next = output_count_reg - 1; - output_axis_tvalid_int = 1'b1; + m_axis_tvalid_int = 1'b1; data_fifo_out_tready = 1'b1; if (output_count_reg == 1'b1) begin // done with segment, get a code byte next @@ -413,83 +423,83 @@ always @(posedge clk) begin end // output datapath logic -reg [7:0] output_axis_tdata_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg [7:0] m_axis_tdata_reg = 8'd0; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg [7:0] temp_m_axis_tdata_reg = 8'd0; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py index ea2da0fdc..160a96bd9 100755 --- a/tb/test_axis_cobs_decode.py +++ b/tb/test_axis_cobs_decode.py @@ -116,18 +116,18 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_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)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -138,11 +138,11 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -152,11 +152,11 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -171,17 +171,17 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_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 + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -192,7 +192,7 @@ def bench(): i = 4 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source.empty(): + if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 4 yield clk.posedge @@ -200,7 +200,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source.empty(): + if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 2 source_pause.next = True yield clk.posedge @@ -213,7 +213,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source.empty(): + if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 2 sink_pause.next = True yield clk.posedge diff --git a/tb/test_axis_cobs_decode.v b/tb/test_axis_cobs_decode.v index f5841f43a..e4fe6aba4 100644 --- a/tb/test_axis_cobs_decode.v +++ b/tb/test_axis_cobs_decode.v @@ -38,18 +38,18 @@ 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; +reg [7:0] s_axis_tdata = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_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 s_axis_tready; +wire [7:0] m_axis_tdata; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; initial begin // myhdl integration @@ -57,18 +57,18 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser ); // dump file @@ -80,16 +80,16 @@ axis_cobs_decode UUT ( .clk(clk), .rst(rst), - .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) + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser) ); endmodule diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py index da5b7eefd..370407afe 100755 --- a/tb/test_axis_cobs_encode.py +++ b/tb/test_axis_cobs_encode.py @@ -117,18 +117,18 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_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)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -139,11 +139,11 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -153,11 +153,11 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -172,17 +172,17 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_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 + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -193,7 +193,7 @@ def bench(): i = 4 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source.empty(): + if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 4 yield clk.posedge @@ -201,7 +201,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source.empty(): + if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 2 source_pause.next = True yield clk.posedge @@ -214,7 +214,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source.empty(): + if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 2 sink_pause.next = True yield clk.posedge diff --git a/tb/test_axis_cobs_encode.v b/tb/test_axis_cobs_encode.v index 6a14bb203..5da466ede 100644 --- a/tb/test_axis_cobs_encode.v +++ b/tb/test_axis_cobs_encode.v @@ -39,18 +39,18 @@ 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; +reg [7:0] s_axis_tdata = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_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 s_axis_tready; +wire [7:0] m_axis_tdata; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; initial begin // myhdl integration @@ -58,18 +58,18 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser ); // dump file @@ -83,16 +83,16 @@ axis_cobs_encode #( UUT ( .clk(clk), .rst(rst), - .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) + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser) ); endmodule diff --git a/tb/test_axis_cobs_encode_zero_frame.py b/tb/test_axis_cobs_encode_zero_frame.py index 0fbc15422..c957e51e4 100755 --- a/tb/test_axis_cobs_encode_zero_frame.py +++ b/tb/test_axis_cobs_encode_zero_frame.py @@ -118,18 +118,18 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_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)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -140,11 +140,11 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -154,11 +154,11 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -173,17 +173,17 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_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 + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -194,7 +194,7 @@ def bench(): i = 4 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source.empty(): + if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 4 yield clk.posedge @@ -202,7 +202,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source.empty(): + if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 2 source_pause.next = True yield clk.posedge @@ -215,7 +215,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_axis_tvalid or output_axis_tvalid or not source.empty(): + if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 2 sink_pause.next = True yield clk.posedge diff --git a/tb/test_axis_cobs_encode_zero_frame.v b/tb/test_axis_cobs_encode_zero_frame.v index e1af31f8d..931e0fef0 100644 --- a/tb/test_axis_cobs_encode_zero_frame.v +++ b/tb/test_axis_cobs_encode_zero_frame.v @@ -39,18 +39,18 @@ 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; +reg [7:0] s_axis_tdata = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_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 s_axis_tready; +wire [7:0] m_axis_tdata; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; initial begin // myhdl integration @@ -58,18 +58,18 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser ); // dump file @@ -83,16 +83,16 @@ axis_cobs_encode #( UUT ( .clk(clk), .rst(rst), - .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) + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser) ); endmodule From 09a8fa51b62d1f39348cdbfcf26fe70ecda3baa4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 10:19:32 -0700 Subject: [PATCH 433/617] Rename ports --- rtl/axis_adapter.v | 382 +++++++++++++++++------------------ tb/test_axis_adapter_64_8.py | 114 +++++------ tb/test_axis_adapter_64_8.v | 120 +++++------ tb/test_axis_adapter_8_64.py | 114 +++++------ tb/test_axis_adapter_8_64.v | 120 +++++------ 5 files changed, 425 insertions(+), 425 deletions(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index 487bfdd65..bf227bbfc 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -31,12 +31,12 @@ THE SOFTWARE. */ module axis_adapter # ( - parameter INPUT_DATA_WIDTH = 8, - parameter INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8), - parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8), - parameter OUTPUT_DATA_WIDTH = 8, - parameter OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8), - parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8), + parameter S_DATA_WIDTH = 8, + parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8), + parameter S_KEEP_WIDTH = (S_DATA_WIDTH/8), + parameter M_DATA_WIDTH = 8, + parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8), + parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8), parameter ID_ENABLE = 0, parameter ID_WIDTH = 8, parameter DEST_ENABLE = 0, @@ -45,65 +45,65 @@ module axis_adapter # parameter USER_WIDTH = 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI input */ - input wire [INPUT_DATA_WIDTH-1:0] input_axis_tdata, - input wire [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, + input wire [S_DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * AXI output */ - output wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata, - output wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser + output wire [M_DATA_WIDTH-1:0] m_axis_tdata, + output wire [M_KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser ); // force keep width to 1 when disabled -localparam INPUT_KEEP_WIDTH_INT = INPUT_KEEP_ENABLE ? INPUT_KEEP_WIDTH : 1; -localparam OUTPUT_KEEP_WIDTH_INT = OUTPUT_KEEP_ENABLE ? OUTPUT_KEEP_WIDTH : 1; +localparam S_KEEP_WIDTH_INT = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1; +localparam M_KEEP_WIDTH_INT = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1; // bus word sizes (must be identical) -localparam INPUT_DATA_WORD_SIZE = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH_INT; -localparam OUTPUT_DATA_WORD_SIZE = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH_INT; +localparam S_DATA_WORD_SIZE = S_DATA_WIDTH / S_KEEP_WIDTH_INT; +localparam M_DATA_WORD_SIZE = M_DATA_WIDTH / M_KEEP_WIDTH_INT; // output bus is wider -localparam EXPAND_BUS = OUTPUT_KEEP_WIDTH_INT > INPUT_KEEP_WIDTH_INT; +localparam EXPAND_BUS = M_KEEP_WIDTH_INT > S_KEEP_WIDTH_INT; // total data and keep widths -localparam DATA_WIDTH = EXPAND_BUS ? OUTPUT_DATA_WIDTH : INPUT_DATA_WIDTH; -localparam KEEP_WIDTH = EXPAND_BUS ? OUTPUT_KEEP_WIDTH_INT : INPUT_KEEP_WIDTH_INT; +localparam DATA_WIDTH = EXPAND_BUS ? M_DATA_WIDTH : S_DATA_WIDTH; +localparam KEEP_WIDTH = EXPAND_BUS ? M_KEEP_WIDTH_INT : S_KEEP_WIDTH_INT; // required number of cycles to match widths -localparam CYCLE_COUNT = EXPAND_BUS ? (OUTPUT_KEEP_WIDTH_INT / INPUT_KEEP_WIDTH_INT) : (INPUT_KEEP_WIDTH_INT / OUTPUT_KEEP_WIDTH_INT); +localparam CYCLE_COUNT = EXPAND_BUS ? (M_KEEP_WIDTH_INT / S_KEEP_WIDTH_INT) : (S_KEEP_WIDTH_INT / M_KEEP_WIDTH_INT); // data width and keep width per cycle localparam CYCLE_DATA_WIDTH = DATA_WIDTH / CYCLE_COUNT; localparam CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT; // bus width assertions initial begin - if (INPUT_DATA_WORD_SIZE * INPUT_KEEP_WIDTH_INT != INPUT_DATA_WIDTH) begin + if (S_DATA_WORD_SIZE * S_KEEP_WIDTH_INT != S_DATA_WIDTH) begin $error("Error: input data width not evenly divisble"); $finish; end - if (OUTPUT_DATA_WORD_SIZE * OUTPUT_KEEP_WIDTH_INT != OUTPUT_DATA_WIDTH) begin + if (M_DATA_WORD_SIZE * M_KEEP_WIDTH_INT != M_DATA_WIDTH) begin $error("Error: output data width not evenly divisble"); $finish; end - if (INPUT_DATA_WORD_SIZE != OUTPUT_DATA_WORD_SIZE) begin + if (S_DATA_WORD_SIZE != M_DATA_WORD_SIZE) begin $error("Error: word size mismatch"); $finish; end @@ -129,19 +129,19 @@ reg [DEST_WIDTH-1:0] temp_tdest_reg = {DEST_WIDTH{1'b0}}, temp_tdest_next; reg [USER_WIDTH-1:0] temp_tuser_reg = {USER_WIDTH{1'b0}}, temp_tuser_next; // internal datapath -reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_int; -reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg [ID_WIDTH-1:0] output_axis_tid_int; -reg [DEST_WIDTH-1:0] output_axis_tdest_int; -reg [USER_WIDTH-1:0] output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [M_DATA_WIDTH-1:0] m_axis_tdata_int; +reg [M_KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg [ID_WIDTH-1:0] m_axis_tid_int; +reg [DEST_WIDTH-1:0] m_axis_tdest_int; +reg [USER_WIDTH-1:0] m_axis_tuser_int; +wire m_axis_tready_int_early; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; always @* begin state_next = STATE_IDLE; @@ -155,15 +155,15 @@ always @* begin temp_tdest_next = temp_tdest_reg; temp_tuser_next = temp_tuser_reg; - output_axis_tdata_int = {OUTPUT_DATA_WIDTH{1'b0}}; - output_axis_tkeep_int = {OUTPUT_KEEP_WIDTH{1'b0}}; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tid_int = {ID_WIDTH{1'b0}}; - output_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_axis_tuser_int = {USER_WIDTH{1'b0}}; + m_axis_tdata_int = {M_DATA_WIDTH{1'b0}}; + m_axis_tkeep_int = {M_KEEP_WIDTH{1'b0}}; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tid_int = {ID_WIDTH{1'b0}}; + m_axis_tdest_int = {DEST_WIDTH{1'b0}}; + m_axis_tuser_int = {USER_WIDTH{1'b0}}; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; case (state_reg) STATE_IDLE: begin @@ -172,45 +172,45 @@ always @* begin // output and input same width - just act like a register // accept data next cycle if output register ready next cycle - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; // transfer through - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1; - output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = input_axis_tlast; - output_axis_tid_int = input_axis_tid; - output_axis_tdest_int = input_axis_tdest; - output_axis_tuser_int = input_axis_tuser; + m_axis_tdata_int = s_axis_tdata; + m_axis_tkeep_int = S_KEEP_ENABLE ? s_axis_tkeep : 1'b1; + m_axis_tvalid_int = s_axis_tvalid; + m_axis_tlast_int = s_axis_tlast; + m_axis_tid_int = s_axis_tid; + m_axis_tdest_int = s_axis_tdest; + m_axis_tuser_int = s_axis_tuser; state_next = STATE_IDLE; end else if (EXPAND_BUS) begin // output bus is wider // accept new data - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // word transfer in - store it in data register // pass complete input word, zero-extended to temp register - temp_tdata_next = input_axis_tdata; - temp_tkeep_next = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1; - temp_tlast_next = input_axis_tlast; - temp_tid_next = input_axis_tid; - temp_tdest_next = input_axis_tdest; - temp_tuser_next = input_axis_tuser; + temp_tdata_next = s_axis_tdata; + temp_tkeep_next = S_KEEP_ENABLE ? s_axis_tkeep : 1'b1; + temp_tlast_next = s_axis_tlast; + temp_tid_next = s_axis_tid; + temp_tdest_next = s_axis_tdest; + temp_tuser_next = s_axis_tuser; // first input cycle complete cycle_count_next = 8'd1; - if (input_axis_tlast) begin + if (s_axis_tlast) begin // got last signal on first cycle, so output it - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; state_next = STATE_TRANSFER_OUT; end else begin // otherwise, transfer in the rest of the words - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_TRANSFER_IN; end end else begin @@ -220,9 +220,9 @@ always @* begin // output bus is narrower // accept new data - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // word transfer in - store it in data register cycle_count_next = 8'd0; @@ -230,10 +230,10 @@ always @* begin if (CYCLE_COUNT == 1) begin // last cycle by counter value last_cycle = 1'b1; - end else if (INPUT_KEEP_ENABLE && input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}) begin + end else if (S_KEEP_ENABLE && s_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}) begin // last cycle by tkeep fall in current cycle last_cycle = 1'b1; - end else if (INPUT_KEEP_ENABLE && input_axis_tkeep[(CYCLE_KEEP_WIDTH*2)-1:CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin + end else if (S_KEEP_ENABLE && s_axis_tkeep[(CYCLE_KEEP_WIDTH*2)-1:CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin // last cycle by tkeep fall at end of current cycle last_cycle = 1'b1; end else begin @@ -241,30 +241,30 @@ always @* begin end // pass complete input word, zero-extended to temp register - temp_tdata_next = input_axis_tdata; - temp_tkeep_next = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1; - temp_tlast_next = input_axis_tlast; - temp_tid_next = input_axis_tid; - temp_tdest_next = input_axis_tdest; - temp_tuser_next = input_axis_tuser; + temp_tdata_next = s_axis_tdata; + temp_tkeep_next = S_KEEP_ENABLE ? s_axis_tkeep : 1'b1; + temp_tlast_next = s_axis_tlast; + temp_tid_next = s_axis_tid; + temp_tdest_next = s_axis_tdest; + temp_tuser_next = s_axis_tuser; // short-circuit and get first word out the door - output_axis_tdata_int = input_axis_tdata[CYCLE_DATA_WIDTH-1:0]; - output_axis_tkeep_int = input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0]; - output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = input_axis_tlast & last_cycle; - output_axis_tid_int = input_axis_tid; - output_axis_tdest_int = input_axis_tdest; - output_axis_tuser_int = input_axis_tuser; + m_axis_tdata_int = s_axis_tdata[CYCLE_DATA_WIDTH-1:0]; + m_axis_tkeep_int = s_axis_tkeep[CYCLE_KEEP_WIDTH-1:0]; + m_axis_tvalid_int = 1'b1; + m_axis_tlast_int = s_axis_tlast & last_cycle; + m_axis_tid_int = s_axis_tid; + m_axis_tdest_int = s_axis_tdest; + m_axis_tuser_int = s_axis_tuser; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // if output register is ready for first word, then move on to the next one cycle_count_next = 8'd1; end - if (!last_cycle || !output_axis_tready_int_reg) begin + if (!last_cycle || !m_axis_tready_int_reg) begin // continue outputting words - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; state_next = STATE_TRANSFER_OUT; end else begin state_next = STATE_IDLE; @@ -279,28 +279,28 @@ always @* begin // only used when output is wider // accept new data - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // word transfer in - store in data register - temp_tdata_next[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH] = input_axis_tdata; - temp_tkeep_next[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1; - temp_tlast_next = input_axis_tlast; - temp_tid_next = input_axis_tid; - temp_tdest_next = input_axis_tdest; - temp_tuser_next = input_axis_tuser; + temp_tdata_next[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH] = s_axis_tdata; + temp_tkeep_next[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] = S_KEEP_ENABLE ? s_axis_tkeep : 1'b1; + temp_tlast_next = s_axis_tlast; + temp_tid_next = s_axis_tid; + temp_tdest_next = s_axis_tdest; + temp_tuser_next = s_axis_tuser; cycle_count_next = cycle_count_reg + 1; - if ((cycle_count_reg == CYCLE_COUNT-1) | input_axis_tlast) begin + if ((cycle_count_reg == CYCLE_COUNT-1) || s_axis_tlast) begin // terminated by counter or tlast signal, output complete word // read input word next cycle if output will be ready - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; state_next = STATE_TRANSFER_OUT; end else begin // more words to read - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_TRANSFER_IN; end end else begin @@ -314,45 +314,45 @@ always @* begin // output bus is wider // do not accept new data - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; // single-cycle output of entire stored word (output wider) - output_axis_tdata_int = temp_tdata_reg; - output_axis_tkeep_int = temp_tkeep_reg; - output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = temp_tlast_reg; - output_axis_tid_int = temp_tid_reg; - output_axis_tdest_int = temp_tdest_reg; - output_axis_tuser_int = temp_tuser_reg; + m_axis_tdata_int = temp_tdata_reg; + m_axis_tkeep_int = temp_tkeep_reg; + m_axis_tvalid_int = 1'b1; + m_axis_tlast_int = temp_tlast_reg; + m_axis_tid_int = temp_tid_reg; + m_axis_tdest_int = temp_tdest_reg; + m_axis_tuser_int = temp_tuser_reg; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // word transfer out - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // word transfer in // pass complete input word, zero-extended to temp register - temp_tdata_next = input_axis_tdata; - temp_tkeep_next = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1; - temp_tlast_next = input_axis_tlast; - temp_tid_next = input_axis_tid; - temp_tdest_next = input_axis_tdest; - temp_tuser_next = input_axis_tuser; + temp_tdata_next = s_axis_tdata; + temp_tkeep_next = S_KEEP_ENABLE ? s_axis_tkeep : 1'b1; + temp_tlast_next = s_axis_tlast; + temp_tid_next = s_axis_tid; + temp_tdest_next = s_axis_tdest; + temp_tuser_next = s_axis_tuser; // first input cycle complete cycle_count_next = 8'd1; - if (input_axis_tlast) begin + if (s_axis_tlast) begin // got last signal on first cycle, so output it - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; state_next = STATE_TRANSFER_OUT; end else begin // otherwise, transfer in the rest of the words - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_TRANSFER_IN; end end else begin - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else begin @@ -362,7 +362,7 @@ always @* begin // output bus is narrower // do not accept new data - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; // is this the last cycle? if (cycle_count_reg == CYCLE_COUNT-1) begin @@ -379,15 +379,15 @@ always @* begin end // output current part of stored word (output narrower) - output_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH]; - output_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH]; - output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = temp_tlast_reg & last_cycle; - output_axis_tid_int = temp_tid_reg; - output_axis_tdest_int = temp_tdest_reg; - output_axis_tuser_int = temp_tuser_reg; + m_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH]; + m_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH]; + m_axis_tvalid_int = 1'b1; + m_axis_tlast_int = temp_tlast_reg && last_cycle; + m_axis_tid_int = temp_tid_reg; + m_axis_tdest_int = temp_tdest_reg; + m_axis_tuser_int = temp_tuser_reg; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // word transfer out cycle_count_next = cycle_count_reg + 1; @@ -395,7 +395,7 @@ always @* begin if (last_cycle) begin // terminated by counter or tlast signal - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end else begin // more words to write @@ -413,11 +413,11 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; cycle_count_reg <= 8'd0; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; end else begin state_reg <= state_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; cycle_count_reg <= cycle_count_next; end @@ -431,101 +431,101 @@ always @(posedge clk) begin end // output datapath logic -reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}}; -reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; +reg [M_DATA_WIDTH-1:0] m_axis_tdata_reg = {M_DATA_WIDTH{1'b0}}; +reg [M_KEEP_WIDTH-1:0] m_axis_tkeep_reg = {M_KEEP_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}}; -reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; +reg [M_DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {M_DATA_WIDTH{1'b0}}; +reg [M_KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {M_KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = OUTPUT_KEEP_ENABLE ? output_axis_tkeep_reg : {OUTPUT_KEEP_WIDTH{1'b1}}; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = M_KEEP_ENABLE ? m_axis_tkeep_reg : {M_KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tid_reg <= output_axis_tid_int; - output_axis_tdest_reg <= output_axis_tdest_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tid_reg <= m_axis_tid_int; + m_axis_tdest_reg <= m_axis_tdest_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tid_reg <= output_axis_tid_int; - temp_axis_tdest_reg <= output_axis_tdest_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tid_reg <= m_axis_tid_int; + temp_m_axis_tdest_reg <= m_axis_tdest_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index cba5c29b7..42f4a0003 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -43,12 +43,12 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters - INPUT_DATA_WIDTH = 64 - INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8) - INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8) - OUTPUT_DATA_WIDTH = 8 - OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8) - OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8) + S_DATA_WIDTH = 64 + S_KEEP_ENABLE = (S_DATA_WIDTH>8) + S_KEEP_WIDTH = (S_DATA_WIDTH/8) + M_DATA_WIDTH = 8 + M_KEEP_ENABLE = (M_DATA_WIDTH>8) + M_KEEP_WIDTH = (M_DATA_WIDTH/8) ID_ENABLE = 1 ID_WIDTH = 8 DEST_ENABLE = 1 @@ -61,24 +61,24 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[INPUT_DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[INPUT_KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[S_DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[S_KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[OUTPUT_DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[OUTPUT_KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[M_DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[M_KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -89,14 +89,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -106,14 +106,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -128,23 +128,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -152,11 +152,11 @@ def bench(): clk.next = not clk def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -165,7 +165,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_adapter_64_8.v b/tb/test_axis_adapter_64_8.v index b48214a02..3afe0ef07 100644 --- a/tb/test_axis_adapter_64_8.v +++ b/tb/test_axis_adapter_64_8.v @@ -32,12 +32,12 @@ THE SOFTWARE. module test_axis_adapter_64_8; // Parameters -parameter INPUT_DATA_WIDTH = 64; -parameter INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8); -parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); -parameter OUTPUT_DATA_WIDTH = 8; -parameter OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8); -parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); +parameter S_DATA_WIDTH = 64; +parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8); +parameter S_KEEP_WIDTH = (S_DATA_WIDTH/8); +parameter M_DATA_WIDTH = 8; +parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8); +parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8); parameter ID_ENABLE = 1; parameter ID_WIDTH = 8; parameter DEST_ENABLE = 1; @@ -50,24 +50,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +reg [S_DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata; -wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [M_DATA_WIDTH-1:0] m_axis_tdata; +wire [M_KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -75,24 +75,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -101,12 +101,12 @@ initial begin end axis_adapter #( - .INPUT_DATA_WIDTH(INPUT_DATA_WIDTH), - .INPUT_KEEP_ENABLE(INPUT_KEEP_ENABLE), - .INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH), - .OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH), - .OUTPUT_KEEP_ENABLE(OUTPUT_KEEP_ENABLE), - .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH), + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), .ID_ENABLE(ID_ENABLE), .ID_WIDTH(ID_WIDTH), .DEST_ENABLE(DEST_ENABLE), @@ -118,23 +118,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index a51464b3b..8307bf940 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -43,12 +43,12 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters - INPUT_DATA_WIDTH = 8 - INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8) - INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8) - OUTPUT_DATA_WIDTH = 64 - OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8) - OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8) + S_DATA_WIDTH = 8 + S_KEEP_ENABLE = (S_DATA_WIDTH>8) + S_KEEP_WIDTH = (S_DATA_WIDTH/8) + M_DATA_WIDTH = 64 + M_KEEP_ENABLE = (M_DATA_WIDTH>8) + M_KEEP_WIDTH = (M_DATA_WIDTH/8) ID_ENABLE = 1 ID_WIDTH = 8 DEST_ENABLE = 1 @@ -61,24 +61,24 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[INPUT_DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[INPUT_KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[S_DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[S_KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[OUTPUT_DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[OUTPUT_KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[M_DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[M_KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -89,14 +89,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -106,14 +106,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -128,23 +128,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -152,11 +152,11 @@ def bench(): clk.next = not clk def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -165,7 +165,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_adapter_8_64.v b/tb/test_axis_adapter_8_64.v index b3d1fb090..dc01a0ae0 100644 --- a/tb/test_axis_adapter_8_64.v +++ b/tb/test_axis_adapter_8_64.v @@ -32,12 +32,12 @@ THE SOFTWARE. module test_axis_adapter_8_64; // Parameters -parameter INPUT_DATA_WIDTH = 8; -parameter INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8); -parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8); -parameter OUTPUT_DATA_WIDTH = 64; -parameter OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8); -parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8); +parameter S_DATA_WIDTH = 8; +parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8); +parameter S_KEEP_WIDTH = (S_DATA_WIDTH/8); +parameter M_DATA_WIDTH = 64; +parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8); +parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8); parameter ID_ENABLE = 1; parameter ID_WIDTH = 8; parameter DEST_ENABLE = 1; @@ -50,24 +50,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +reg [S_DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata; -wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [M_DATA_WIDTH-1:0] m_axis_tdata; +wire [M_KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -75,24 +75,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -101,12 +101,12 @@ initial begin end axis_adapter #( - .INPUT_DATA_WIDTH(INPUT_DATA_WIDTH), - .INPUT_KEEP_ENABLE(INPUT_KEEP_ENABLE), - .INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH), - .OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH), - .OUTPUT_KEEP_ENABLE(OUTPUT_KEEP_ENABLE), - .OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH), + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), .ID_ENABLE(ID_ENABLE), .ID_WIDTH(ID_WIDTH), .DEST_ENABLE(DEST_ENABLE), @@ -118,23 +118,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule From cb9f2132a44ba466bb9b8d8f7e589ea15288aa94 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 10:20:17 -0700 Subject: [PATCH 434/617] Update parameter ordering --- rtl/axis_frame_join.v | 2 +- tb/test_axis_frame_join_4.py | 2 +- tb/test_axis_frame_join_4.v | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtl/axis_frame_join.v b/rtl/axis_frame_join.v index e5cd29f44..a79ded93c 100644 --- a/rtl/axis_frame_join.v +++ b/rtl/axis_frame_join.v @@ -31,8 +31,8 @@ THE SOFTWARE. */ module axis_frame_join # ( - parameter DATA_WIDTH = 8, parameter S_COUNT = 4, + parameter DATA_WIDTH = 8, parameter TAG_ENABLE = 1, parameter TAG_WIDTH = 16 ) diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index 31a0a1f34..1b0a1a03f 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -44,8 +44,8 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters - DATA_WIDTH = 8 S_COUNT = 4 + DATA_WIDTH = 8 TAG_ENABLE = 1 TAG_WIDTH = 16 diff --git a/tb/test_axis_frame_join_4.v b/tb/test_axis_frame_join_4.v index 6b5af358a..693e13629 100644 --- a/tb/test_axis_frame_join_4.v +++ b/tb/test_axis_frame_join_4.v @@ -32,8 +32,8 @@ THE SOFTWARE. module test_axis_frame_join_4; // Parameters -parameter DATA_WIDTH = 8; parameter S_COUNT = 4; +parameter DATA_WIDTH = 8; parameter TAG_ENABLE = 1; parameter TAG_WIDTH = 16; @@ -85,8 +85,8 @@ initial begin end axis_frame_join #( - .DATA_WIDTH(DATA_WIDTH), .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), .TAG_ENABLE(TAG_ENABLE), .TAG_WIDTH(TAG_WIDTH) ) From e926daabaf1963a7aafe31cf44d0adcb8d17c3da Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 10:24:42 -0700 Subject: [PATCH 435/617] Update readme --- README.md | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index f2ea22578..ead09ec8f 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,9 @@ and port count. Supports priority and round-robin arbitration. ### axis_async_fifo module -Basic word-based asynchronous FIFO with parametrizable data width and depth. -Supports power of two depths only. - -### axis_async_frame_fifo module - -Basic frame-based asynchronous FIFO with parametrizable data width and depth. -Supports power of two depths only. +Configurable word-based or frame-based asynchronous FIFO with parametrizable +data width, depth, type, and bad frame detection. Supports power of two +depths only. ### axis_cobs_decode @@ -65,13 +61,9 @@ count. ### axis_fifo module -Basic word-based synchronous FIFO with parametrizable data width and depth. -Supports power of two depths only. - -### axis_frame_fifo module - -Basic frame-based synchronous FIFO with parametrizable data width and depth. -Supports power of two depths only. +Configurable word-based or frame-based synchronous FIFO with parametrizable +data width, depth, type, and bad frame detection. Supports power of two +depths only. ### axis_frame_join module @@ -111,7 +103,8 @@ Parametrizable data width. Rate and mode are configurable at run time. ### axis_register module -Datapath register. Use to improve timing for long routes. +Datapath register with parameter to select between skid buffer, simple buffer, +and bypass. Use to improve timing for long routes. ### axis_srl_fifo module @@ -138,7 +131,7 @@ Frame-aware AXI stream switch with parametrizable data width and port count. AXI stream tap module. Used to make a copy of an AXI stream bus without affecting the bus. Back-pressure on the output results in truncated frames -with tuser set. +with tuser set. ### ll_axis_bridge module @@ -179,20 +172,17 @@ Parametrizable priority encoder. arbiter.v : General-purpose parametrizable arbiter axis_adapter.v : Parametrizable bus width adapter axis_arb_mux.v : Parametrizable arbitrated multiplexer - axis_async_fifo.v : Asynchronous FIFO - axis_async_frame_fifo.v : Asynchronous frame FIFO + axis_async_fifo.v : Parametrizable asynchronous FIFO axis_cobs_decode.v : COBS decoder axis_cobs_encode.v : COBS encoder axis_crosspoint.v : Parametrizable crosspoint switch axis_demux.v : Parametrizable demultiplexer - axis_fifo.v : Synchronous FIFO - axis_frame_fifo.v : Synchronous frame FIFO + axis_fifo.v : Parametrizable synchronous FIFO axis_frame_join.v : Parametrizable frame joiner axis_frame_length_adjust.v : Frame length adjuster axis_frame_length_adjust_fifo.v : Frame length adjuster with FIFO axis_ll_bridge.v : AXI stream to LocalLink bridge - axis_mux.py : Multiplexer generator - axis_mux_4.v : 4 port multiplexer + axis_mux.v : Multiplexer generator axis_rate_limit.v : Fractional rate limiter axis_register.v : AXI Stream register axis_srl_fifo.v : SRL-based FIFO From 8d9da455cdf917710219549a77d4e8afd00aa834 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 10:29:31 -0700 Subject: [PATCH 436/617] Minor optimizations --- rtl/axis_adapter.v | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index bf227bbfc..896008efa 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -87,6 +87,7 @@ localparam DATA_WIDTH = EXPAND_BUS ? M_DATA_WIDTH : S_DATA_WIDTH; localparam KEEP_WIDTH = EXPAND_BUS ? M_KEEP_WIDTH_INT : S_KEEP_WIDTH_INT; // required number of cycles to match widths localparam CYCLE_COUNT = EXPAND_BUS ? (M_KEEP_WIDTH_INT / S_KEEP_WIDTH_INT) : (S_KEEP_WIDTH_INT / M_KEEP_WIDTH_INT); +localparam CYCLE_COUNT_WIDTH = CYCLE_COUNT == 1 ? 1 : $clog2(CYCLE_COUNT); // data width and keep width per cycle localparam CYCLE_DATA_WIDTH = DATA_WIDTH / CYCLE_COUNT; localparam CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT; @@ -117,7 +118,7 @@ localparam [2:0] reg [2:0] state_reg = STATE_IDLE, state_next; -reg [7:0] cycle_count_reg = 8'd0, cycle_count_next; +reg [CYCLE_COUNT_WIDTH-1:0] cycle_count_reg = 0, cycle_count_next; reg last_cycle; @@ -148,6 +149,8 @@ always @* begin cycle_count_next = cycle_count_reg; + last_cycle = 0; + temp_tdata_next = temp_tdata_reg; temp_tkeep_next = temp_tkeep_reg; temp_tlast_next = temp_tlast_reg; @@ -155,13 +158,19 @@ always @* begin temp_tdest_next = temp_tdest_reg; temp_tuser_next = temp_tuser_reg; - m_axis_tdata_int = {M_DATA_WIDTH{1'b0}}; - m_axis_tkeep_int = {M_KEEP_WIDTH{1'b0}}; + if (EXPAND_BUS) begin + m_axis_tdata_int = temp_tdata_reg; + m_axis_tkeep_int = temp_tkeep_reg; + m_axis_tlast_int = temp_tlast_reg; + end else begin + m_axis_tdata_int = {M_DATA_WIDTH{1'b0}}; + m_axis_tkeep_int = {M_KEEP_WIDTH{1'b0}}; + m_axis_tlast_int = 1'b0; + end m_axis_tvalid_int = 1'b0; - m_axis_tlast_int = 1'b0; - m_axis_tid_int = {ID_WIDTH{1'b0}}; - m_axis_tdest_int = {DEST_WIDTH{1'b0}}; - m_axis_tuser_int = {USER_WIDTH{1'b0}}; + m_axis_tid_int = temp_tid_reg; + m_axis_tdest_int = temp_tdest_reg; + m_axis_tuser_int = temp_tuser_reg; s_axis_tready_next = 1'b0; @@ -202,7 +211,7 @@ always @* begin temp_tuser_next = s_axis_tuser; // first input cycle complete - cycle_count_next = 8'd1; + cycle_count_next = 1; if (s_axis_tlast) begin // got last signal on first cycle, so output it @@ -224,7 +233,7 @@ always @* begin if (s_axis_tready && s_axis_tvalid) begin // word transfer in - store it in data register - cycle_count_next = 8'd0; + cycle_count_next = 0; // is this the last cycle? if (CYCLE_COUNT == 1) begin @@ -259,7 +268,7 @@ always @* begin if (m_axis_tready_int_reg) begin // if output register is ready for first word, then move on to the next one - cycle_count_next = 8'd1; + cycle_count_next = 1; end if (!last_cycle || !m_axis_tready_int_reg) begin @@ -340,7 +349,7 @@ always @* begin temp_tuser_next = s_axis_tuser; // first input cycle complete - cycle_count_next = 8'd1; + cycle_count_next = 1; if (s_axis_tlast) begin // got last signal on first cycle, so output it @@ -412,16 +421,15 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - cycle_count_reg <= 8'd0; s_axis_tready_reg <= 1'b0; end else begin state_reg <= state_next; s_axis_tready_reg <= s_axis_tready_next; - - cycle_count_reg <= cycle_count_next; end + cycle_count_reg <= cycle_count_next; + temp_tdata_reg <= temp_tdata_next; temp_tkeep_reg <= temp_tkeep_next; temp_tlast_reg <= temp_tlast_next; From 7997a4a844661b91fc524973b5b8feaa4b32a421 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 11:19:28 -0700 Subject: [PATCH 437/617] Rename ports --- rtl/axis_ll_bridge.v | 22 +++++++++++----------- rtl/ll_axis_bridge.v | 16 ++++++++-------- tb/test_axis_ll_bridge.py | 24 ++++++++++++------------ tb/test_axis_ll_bridge.v | 24 ++++++++++++------------ tb/test_ll_axis_bridge.py | 24 ++++++++++++------------ tb/test_ll_axis_bridge.v | 24 ++++++++++++------------ 6 files changed, 67 insertions(+), 67 deletions(-) diff --git a/rtl/axis_ll_bridge.v b/rtl/axis_ll_bridge.v index 5e83e3de0..ad0e00216 100644 --- a/rtl/axis_ll_bridge.v +++ b/rtl/axis_ll_bridge.v @@ -40,10 +40,10 @@ module axis_ll_bridge # /* * AXI input */ - input wire [DATA_WIDTH-1:0] axis_tdata, - input wire axis_tvalid, - output wire axis_tready, - input wire axis_tlast, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, /* * LocalLink output @@ -61,19 +61,19 @@ always @(posedge clk) begin if (rst) begin last_tlast = 1'b1; end else begin - if (axis_tvalid & axis_tready) last_tlast = axis_tlast; + if (s_axis_tvalid && s_axis_tready) last_tlast = s_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; +wire invalid = s_axis_tvalid && s_axis_tlast && last_tlast; -assign axis_tready = ~ll_dst_rdy_in_n; +assign s_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); +assign ll_data_out = s_axis_tdata; +assign ll_sof_out_n = !(last_tlast && s_axis_tvalid && !invalid); +assign ll_eof_out_n = !(s_axis_tlast && !invalid); +assign ll_src_rdy_out_n = !(s_axis_tvalid && !invalid); endmodule diff --git a/rtl/ll_axis_bridge.v b/rtl/ll_axis_bridge.v index 5ddd6bc2a..ab2aeab01 100644 --- a/rtl/ll_axis_bridge.v +++ b/rtl/ll_axis_bridge.v @@ -49,16 +49,16 @@ module ll_axis_bridge # /* * AXI output */ - output wire [DATA_WIDTH-1:0] axis_tdata, - output wire axis_tvalid, - input wire axis_tready, - output wire axis_tlast + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast ); -assign axis_tdata = ll_data_in; -assign axis_tvalid = ~ll_src_rdy_in_n; -assign axis_tlast = ~ll_eof_in_n; +assign m_axis_tdata = ll_data_in; +assign m_axis_tvalid = !ll_src_rdy_in_n; +assign m_axis_tlast = !ll_eof_in_n; -assign ll_dst_rdy_out_n = ~axis_tready; +assign ll_dst_rdy_out_n = !m_axis_tready; endmodule diff --git a/tb/test_axis_ll_bridge.py b/tb/test_axis_ll_bridge.py index 9b4989c46..1343eefef 100755 --- a/tb/test_axis_ll_bridge.py +++ b/tb/test_axis_ll_bridge.py @@ -51,9 +51,9 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - axis_tvalid = Signal(bool(0)) - axis_tlast = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) ll_dst_rdy_in_n = Signal(bool(1)) # Outputs @@ -61,7 +61,7 @@ def bench(): 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)) + s_axis_tready = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -72,10 +72,10 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=axis_tdata, - tvalid=axis_tvalid, - tready=axis_tready, - tlast=axis_tlast, + tdata=s_axis_tdata, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, pause=source_pause, name='source' ) @@ -104,10 +104,10 @@ def bench(): rst=rst, current_test=current_test, - axis_tdata=axis_tdata, - axis_tvalid=axis_tvalid, - axis_tready=axis_tready, - axis_tlast=axis_tlast, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, ll_data_out=ll_data_out, ll_sof_out_n=ll_sof_out_n, diff --git a/tb/test_axis_ll_bridge.v b/tb/test_axis_ll_bridge.v index 05d4d6cd1..b0ce6f29c 100644 --- a/tb/test_axis_ll_bridge.v +++ b/tb/test_axis_ll_bridge.v @@ -39,9 +39,9 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] axis_tdata = 0; -reg axis_tvalid = 0; -reg axis_tlast = 0; +reg [DATA_WIDTH-1:0] s_axis_tdata = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; reg ll_dst_rdy_in_n = 1; // Outputs @@ -49,7 +49,7 @@ wire [DATA_WIDTH-1:0] ll_data_out; wire ll_sof_out_n; wire ll_eof_out_n; wire ll_src_rdy_out_n; -wire axis_tready; +wire s_axis_tready; initial begin // myhdl integration @@ -57,9 +57,9 @@ initial begin clk, rst, current_test, - axis_tdata, - axis_tvalid, - axis_tlast, + s_axis_tdata, + s_axis_tvalid, + s_axis_tlast, ll_dst_rdy_in_n ); $to_myhdl( @@ -67,7 +67,7 @@ initial begin ll_sof_out_n, ll_eof_out_n, ll_src_rdy_out_n, - axis_tready + s_axis_tready ); // dump file @@ -82,10 +82,10 @@ UUT ( .clk(clk), .rst(rst), // axi input - .axis_tdata(axis_tdata), - .axis_tvalid(axis_tvalid), - .axis_tready(axis_tready), - .axis_tlast(axis_tlast), + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), // locallink output .ll_data_out(ll_data_out), .ll_sof_out_n(ll_sof_out_n), diff --git a/tb/test_ll_axis_bridge.py b/tb/test_ll_axis_bridge.py index 3bbd356bd..38df65cd9 100755 --- a/tb/test_ll_axis_bridge.py +++ b/tb/test_ll_axis_bridge.py @@ -55,12 +55,12 @@ def bench(): 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)) + m_axis_tready = Signal(bool(0)) # Outputs - axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - axis_tvalid = Signal(bool(0)) - axis_tlast = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) ll_dst_rdy_out_n = Signal(bool(1)) # sources and sinks @@ -86,10 +86,10 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=axis_tdata, - tvalid=axis_tvalid, - tready=axis_tready, - tlast=axis_tlast, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, pause=sink_pause, name='sink' ) @@ -110,10 +110,10 @@ def bench(): 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 + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast ) @always(delay(4)) diff --git a/tb/test_ll_axis_bridge.v b/tb/test_ll_axis_bridge.v index c6a9bbb36..ba2572af4 100644 --- a/tb/test_ll_axis_bridge.v +++ b/tb/test_ll_axis_bridge.v @@ -43,13 +43,13 @@ reg [DATA_WIDTH-1: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; +reg m_axis_tready = 0; // Outputs wire ll_dst_rdy_out_n; -wire [DATA_WIDTH-1:0] axis_tdata; -wire axis_tvalid; -wire axis_tlast; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire m_axis_tvalid; +wire m_axis_tlast; initial begin // myhdl integration @@ -61,12 +61,12 @@ initial begin ll_sof_in_n, ll_eof_in_n, ll_src_rdy_in_n, - axis_tready + m_axis_tready ); $to_myhdl( - axis_tdata, - axis_tvalid, - axis_tlast, + m_axis_tdata, + m_axis_tvalid, + m_axis_tlast, ll_dst_rdy_out_n ); @@ -88,10 +88,10 @@ UUT ( .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) + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast) ); endmodule From fd28040c4057ecc14b77d064f6ff6ef0e654015a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 11:30:35 -0700 Subject: [PATCH 438/617] Rename ports --- rtl/axis_rate_limit.v | 190 +++++++++++++++++----------------- tb/test_axis_rate_limit.py | 112 ++++++++++---------- tb/test_axis_rate_limit.v | 96 ++++++++--------- tb/test_axis_rate_limit_64.py | 112 ++++++++++---------- tb/test_axis_rate_limit_64.v | 96 ++++++++--------- 5 files changed, 303 insertions(+), 303 deletions(-) diff --git a/rtl/axis_rate_limit.v b/rtl/axis_rate_limit.v index 240644da6..a497f54a0 100644 --- a/rtl/axis_rate_limit.v +++ b/rtl/axis_rate_limit.v @@ -49,26 +49,26 @@ module axis_rate_limit # /* * 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, /* * Configuration @@ -79,23 +79,23 @@ module axis_rate_limit # ); // internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg [ID_WIDTH-1:0] output_axis_tid_int; -reg [DEST_WIDTH-1:0] output_axis_tdest_int; -reg [USER_WIDTH-1:0] output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg [ID_WIDTH-1:0] m_axis_tid_int; +reg [DEST_WIDTH-1:0] m_axis_tdest_int; +reg [USER_WIDTH-1:0] m_axis_tuser_int; +wire m_axis_tready_int_early; reg [23:0] acc_reg = 24'd0, acc_next; reg pause; reg frame_reg = 1'b0, frame_next; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; always @* begin acc_next = acc_reg; @@ -106,139 +106,139 @@ always @* begin acc_next = acc_reg - rate_num; end - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // read input - frame_next = ~input_axis_tlast; + frame_next = !s_axis_tlast; acc_next = acc_reg + (rate_denom - rate_num); end if (acc_next >= rate_num) begin if (LAST_ENABLE && rate_by_frame) begin - pause = ~frame_next; + pause = !frame_next; end else begin pause = 1'b1; end end - input_axis_tready_next = output_axis_tready_int_early & ~pause; + s_axis_tready_next = m_axis_tready_int_early && !pause; - output_axis_tdata_int = input_axis_tdata; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid & input_axis_tready; - output_axis_tlast_int = input_axis_tlast; - output_axis_tid_int = input_axis_tid; - output_axis_tdest_int = input_axis_tdest; - output_axis_tuser_int = input_axis_tuser; + m_axis_tdata_int = s_axis_tdata; + m_axis_tkeep_int = s_axis_tkeep; + m_axis_tvalid_int = s_axis_tvalid && s_axis_tready; + m_axis_tlast_int = s_axis_tlast; + m_axis_tid_int = s_axis_tid; + m_axis_tdest_int = s_axis_tdest; + m_axis_tuser_int = s_axis_tuser; end always @(posedge clk) begin if (rst) begin acc_reg <= 24'd0; frame_reg <= 1'b0; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; end else begin acc_reg <= acc_next; frame_reg <= frame_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; end end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = LAST_ENABLE ? output_axis_tlast_reg : 1'b1; -assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1; +assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tid_reg <= output_axis_tid_int; - output_axis_tdest_reg <= output_axis_tdest_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tid_reg <= m_axis_tid_int; + m_axis_tdest_reg <= m_axis_tdest_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tid_reg <= output_axis_tid_int; - temp_axis_tdest_reg <= output_axis_tdest_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tid_reg <= m_axis_tid_int; + temp_m_axis_tdest_reg <= m_axis_tdest_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index c8a6aeed4..7c3ef6e3a 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -59,28 +59,28 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) rate_num = Signal(intbv(0)[8:]) rate_denom = Signal(intbv(0)[8:]) rate_by_frame = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -91,14 +91,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -108,14 +108,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -130,23 +130,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, rate_num=rate_num, rate_denom=rate_denom, @@ -173,10 +173,10 @@ def bench(): cbc = 0 cfc = 0 reset_stats.next = 0 - ctc += len(output_axis_tkeep) - if output_axis_tready and output_axis_tvalid: - cbc += bin(output_axis_tkeep).count('1') - if output_axis_tlast: + ctc += len(m_axis_tkeep) + if m_axis_tready and m_axis_tvalid: + cbc += bin(m_axis_tkeep).count('1') + if m_axis_tlast: cur_frame.next = False elif not cur_frame: cfc += 1 @@ -348,7 +348,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -393,7 +393,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -476,7 +476,7 @@ def bench(): yield clk.posedge - while not input_axis_tready: + while not s_axis_tready: yield clk.posedge stop_time = now() @@ -493,7 +493,7 @@ def bench(): print("byte count %d" % byte_count) print("frame count %d" % frame_count) - assert tick_count == cycle*len(output_axis_tkeep) + assert tick_count == cycle*len(m_axis_tkeep) assert byte_count == sum(len(f.data) for f in test_frame) assert frame_count == len(test_frame) diff --git a/tb/test_axis_rate_limit.v b/tb/test_axis_rate_limit.v index 699c05268..79f37ecda 100644 --- a/tb/test_axis_rate_limit.v +++ b/tb/test_axis_rate_limit.v @@ -48,27 +48,27 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; reg [7:0] rate_num = 0; reg [7:0] rate_denom = 0; reg rate_by_frame = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -76,27 +76,27 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready, rate_num, rate_denom, rate_by_frame ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -120,23 +120,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Configuration .rate_num(rate_num), .rate_denom(rate_denom), diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index 0a72785c0..a4ff8105c 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -59,28 +59,28 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) rate_num = Signal(intbv(0)[8:]) rate_denom = Signal(intbv(0)[8:]) rate_by_frame = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -91,14 +91,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -108,14 +108,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -130,23 +130,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, rate_num=rate_num, rate_denom=rate_denom, @@ -173,10 +173,10 @@ def bench(): cbc = 0 cfc = 0 reset_stats.next = 0 - ctc += len(output_axis_tkeep) - if output_axis_tready and output_axis_tvalid: - cbc += bin(output_axis_tkeep).count('1') - if output_axis_tlast: + ctc += len(m_axis_tkeep) + if m_axis_tready and m_axis_tvalid: + cbc += bin(m_axis_tkeep).count('1') + if m_axis_tlast: cur_frame.next = False elif not cur_frame: cfc += 1 @@ -348,7 +348,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -393,7 +393,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -476,7 +476,7 @@ def bench(): yield clk.posedge - while not input_axis_tready: + while not s_axis_tready: yield clk.posedge stop_time = now() @@ -493,7 +493,7 @@ def bench(): print("byte count %d" % byte_count) print("frame count %d" % frame_count) - assert tick_count == cycle*len(output_axis_tkeep) + assert tick_count == cycle*len(m_axis_tkeep) assert byte_count == sum(len(f.data) for f in test_frame) assert frame_count == len(test_frame) diff --git a/tb/test_axis_rate_limit_64.v b/tb/test_axis_rate_limit_64.v index 6ed64cd59..1688d88d2 100644 --- a/tb/test_axis_rate_limit_64.v +++ b/tb/test_axis_rate_limit_64.v @@ -48,27 +48,27 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; reg [7:0] rate_num = 0; reg [7:0] rate_denom = 0; reg rate_by_frame = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -76,27 +76,27 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready, rate_num, rate_denom, rate_by_frame ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -120,23 +120,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Configuration .rate_num(rate_num), .rate_denom(rate_denom), From 6c1ea89a66b15156c6172143990c8437f8933863 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 11:52:08 -0700 Subject: [PATCH 439/617] Rename ports --- rtl/axis_srl_fifo.v | 100 ++++++++++++++++++------------------ tb/test_axis_srl_fifo.py | 100 ++++++++++++++++++------------------ tb/test_axis_srl_fifo.v | 96 +++++++++++++++++----------------- tb/test_axis_srl_fifo_64.py | 100 ++++++++++++++++++------------------ tb/test_axis_srl_fifo_64.v | 96 +++++++++++++++++----------------- 5 files changed, 246 insertions(+), 246 deletions(-) diff --git a/rtl/axis_srl_fifo.v b/rtl/axis_srl_fifo.v index af965854e..3a57c2043 100644 --- a/rtl/axis_srl_fifo.v +++ b/rtl/axis_srl_fifo.v @@ -50,26 +50,26 @@ module axis_srl_fifo # /* * 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, /* * Status @@ -86,32 +86,32 @@ localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); reg [WIDTH-1:0] data_reg[DEPTH-1:0]; reg [$clog2(DEPTH+1)-1:0] ptr_reg = 0; -reg full_reg = 0, full_next; -reg empty_reg = 1, empty_next; +reg full_reg = 1'b0, full_next; +reg empty_reg = 1'b1, empty_next; -wire [WIDTH-1:0] input_axis; +wire [WIDTH-1:0] s_axis; -wire [WIDTH-1:0] output_axis = data_reg[ptr_reg-1]; +wire [WIDTH-1:0] m_axis = data_reg[ptr_reg-1]; -assign input_axis_tready = ~full_reg; +assign s_axis_tready = !full_reg; generate - assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; - if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; - if (LAST_ENABLE) assign input_axis[LAST_OFFSET] = input_axis_tlast; - if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; - if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; - if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; + assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata; + if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep; + if (LAST_ENABLE) assign s_axis[LAST_OFFSET] = s_axis_tlast; + if (ID_ENABLE) assign s_axis[ID_OFFSET +: ID_WIDTH] = s_axis_tid; + if (DEST_ENABLE) assign s_axis[DEST_OFFSET +: DEST_WIDTH] = s_axis_tdest; + if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser; endgenerate -assign output_axis_tvalid = ~empty_reg; +assign m_axis_tvalid = !empty_reg; -assign output_axis_tdata = output_axis[DATA_WIDTH-1:0]; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; -assign output_axis_tlast = LAST_ENABLE ? output_axis[LAST_OFFSET] : 1'b1; -assign output_axis_tid = ID_ENABLE ? output_axis[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; +assign m_axis_tdata = m_axis[DATA_WIDTH-1:0]; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +assign m_axis_tlast = LAST_ENABLE ? m_axis[LAST_OFFSET] : 1'b1; +assign m_axis_tid = ID_ENABLE ? m_axis[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; assign count = ptr_reg; @@ -133,33 +133,33 @@ initial begin end always @* begin - shift = 0; - inc = 0; - dec = 0; + shift = 1'b0; + inc = 1'b0; + dec = 1'b0; full_next = full_reg; empty_next = empty_reg; - if (output_axis_tready & input_axis_tvalid & ~full_reg) begin - shift = 1; + if (m_axis_tready && s_axis_tvalid && s_axis_tready) begin + shift = 1'b1; inc = ptr_empty; - empty_next = 0; - end else if (output_axis_tready & output_axis_tvalid) begin - dec = 1; - full_next = 0; + empty_next = 1'b0; + end else if (m_axis_tready && m_axis_tvalid) begin + dec = 1'b1; + full_next = 1'b0; empty_next = ptr_empty1; - end else if (input_axis_tvalid & input_axis_tready) begin - shift = 1; - inc = 1; + end else if (s_axis_tvalid && s_axis_tready) begin + shift = 1'b1; + inc = 1'b1; full_next = ptr_full1; - empty_next = 0; + empty_next = 1'b0; end end always @(posedge clk) begin if (rst) begin ptr_reg <= 0; - full_reg <= 0; - empty_reg <= 1; + full_reg <= 1'b0; + empty_reg <= 1'b1; end else begin if (inc) begin ptr_reg <= ptr_reg + 1; @@ -174,7 +174,7 @@ always @(posedge clk) begin end if (shift) begin - data_reg[0] <= input_axis; + data_reg[0] <= s_axis; for (i = 0; i < DEPTH-1; i = i + 1) begin data_reg[i+1] <= data_reg[i]; end diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py index e9d5a7865..4178d8e8a 100755 --- a/tb/test_axis_srl_fifo.py +++ b/tb/test_axis_srl_fifo.py @@ -60,24 +60,24 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(1)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) count = Signal(intbv(0)[3:]) # sources and sinks @@ -89,14 +89,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -106,14 +106,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -128,23 +128,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, count=count ) @@ -305,7 +305,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -350,7 +350,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_srl_fifo.v b/tb/test_axis_srl_fifo.v index b556386ce..7b76f852c 100644 --- a/tb/test_axis_srl_fifo.v +++ b/tb/test_axis_srl_fifo.v @@ -49,24 +49,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; wire [2:0] count; @@ -76,24 +76,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser, count ); @@ -119,23 +119,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Status .count(count) ); diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py index 18d0929b6..f788c2103 100755 --- a/tb/test_axis_srl_fifo_64.py +++ b/tb/test_axis_srl_fifo_64.py @@ -60,24 +60,24 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(1)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) count = Signal(intbv(0)[3:]) # sources and sinks @@ -89,14 +89,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -106,14 +106,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -128,23 +128,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser, count=count ) @@ -305,7 +305,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -350,7 +350,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_srl_fifo_64.v b/tb/test_axis_srl_fifo_64.v index c11280dfa..33bf0fb78 100644 --- a/tb/test_axis_srl_fifo_64.v +++ b/tb/test_axis_srl_fifo_64.v @@ -49,24 +49,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; wire [2:0] count; @@ -76,24 +76,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser, count ); @@ -119,23 +119,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), // Status .count(count) ); From 84a758f1003dc75f5795a666d2659e0c4d7f0354 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 11:56:52 -0700 Subject: [PATCH 440/617] Rename ports --- rtl/axis_srl_register.v | 78 ++++++++++++------------- tb/test_axis_srl_register.py | 100 ++++++++++++++++---------------- tb/test_axis_srl_register.v | 96 +++++++++++++++--------------- tb/test_axis_srl_register_64.py | 100 ++++++++++++++++---------------- tb/test_axis_srl_register_64.v | 96 +++++++++++++++--------------- 5 files changed, 235 insertions(+), 235 deletions(-) diff --git a/rtl/axis_srl_register.v b/rtl/axis_srl_register.v index f8eba0ab5..e9735a811 100644 --- a/rtl/axis_srl_register.v +++ b/rtl/axis_srl_register.v @@ -43,32 +43,32 @@ module axis_srl_register # parameter USER_WIDTH = 1 ) ( - input wire clk, - input wire rst, + 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 [ID_WIDTH-1:0] input_axis_tid, - input wire [DEST_WIDTH-1:0] input_axis_tdest, - input wire [USER_WIDTH-1:0] input_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser ); localparam KEEP_OFFSET = DATA_WIDTH; @@ -83,29 +83,29 @@ reg valid_reg[1:0]; reg ptr_reg = 0; reg full_reg = 0; -wire [WIDTH-1:0] input_axis; +wire [WIDTH-1:0] s_axis; -wire [WIDTH-1:0] output_axis = data_reg[ptr_reg]; +wire [WIDTH-1:0] m_axis = data_reg[ptr_reg]; -assign input_axis_tready = ~full_reg; +assign s_axis_tready = !full_reg; generate - assign input_axis[DATA_WIDTH-1:0] = input_axis_tdata; - if (KEEP_ENABLE) assign input_axis[KEEP_OFFSET +: KEEP_WIDTH] = input_axis_tkeep; - if (LAST_ENABLE) assign input_axis[LAST_OFFSET] = input_axis_tlast; - if (ID_ENABLE) assign input_axis[ID_OFFSET +: ID_WIDTH] = input_axis_tid; - if (DEST_ENABLE) assign input_axis[DEST_OFFSET +: DEST_WIDTH] = input_axis_tdest; - if (USER_ENABLE) assign input_axis[USER_OFFSET +: USER_WIDTH] = input_axis_tuser; + assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata; + if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep; + if (LAST_ENABLE) assign s_axis[LAST_OFFSET] = s_axis_tlast; + if (ID_ENABLE) assign s_axis[ID_OFFSET +: ID_WIDTH] = s_axis_tid; + if (DEST_ENABLE) assign s_axis[DEST_OFFSET +: DEST_WIDTH] = s_axis_tdest; + if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser; endgenerate -assign output_axis_tvalid = valid_reg[ptr_reg]; +assign m_axis_tvalid = valid_reg[ptr_reg]; -assign output_axis_tdata = output_axis[DATA_WIDTH-1:0]; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; -assign output_axis_tlast = LAST_ENABLE ? output_axis[LAST_OFFSET] : 1'b1; -assign output_axis_tid = ID_ENABLE ? output_axis[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; +assign m_axis_tdata = m_axis[DATA_WIDTH-1:0]; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +assign m_axis_tlast = LAST_ENABLE ? m_axis[LAST_OFFSET] : 1'b1; +assign m_axis_tid = ID_ENABLE ? m_axis[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; integer i; @@ -122,12 +122,12 @@ always @(posedge clk) begin full_reg <= 0; end else begin // transfer empty to full - full_reg <= ~output_axis_tready & output_axis_tvalid; + full_reg <= !m_axis_tready && m_axis_tvalid; // transfer in if not full - if (input_axis_tready) begin - data_reg[0] <= input_axis; - valid_reg[0] <= input_axis_tvalid; + if (s_axis_tready) begin + data_reg[0] <= s_axis; + valid_reg[0] <= s_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]; @@ -135,7 +135,7 @@ always @(posedge clk) begin ptr_reg <= valid_reg[0]; end - if (output_axis_tready) begin + if (m_axis_tready) begin ptr_reg <= 0; end end diff --git a/tb/test_axis_srl_register.py b/tb/test_axis_srl_register.py index 3cb547840..25b6c1aab 100755 --- a/tb/test_axis_srl_register.py +++ b/tb/test_axis_srl_register.py @@ -59,24 +59,24 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(1)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -87,14 +87,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -104,14 +104,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -126,23 +126,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -302,7 +302,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -347,7 +347,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_srl_register.v b/tb/test_axis_srl_register.v index f45d3fd9b..93f9c1f4f 100644 --- a/tb/test_axis_srl_register.v +++ b/tb/test_axis_srl_register.v @@ -48,24 +48,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -73,24 +73,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -114,23 +114,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule diff --git a/tb/test_axis_srl_register_64.py b/tb/test_axis_srl_register_64.py index 4122e72ea..6763ed335 100755 --- a/tb/test_axis_srl_register_64.py +++ b/tb/test_axis_srl_register_64.py @@ -59,24 +59,24 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - input_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + s_axis_tready = Signal(bool(1)) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -87,14 +87,14 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tkeep=input_axis_tkeep, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tid=input_axis_tid, - tdest=input_axis_tdest, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -104,14 +104,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -126,23 +126,23 @@ def bench(): 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_tid=input_axis_tid, - input_axis_tdest=input_axis_tdest, - input_axis_tuser=input_axis_tuser, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -302,7 +302,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -347,7 +347,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_srl_register_64.v b/tb/test_axis_srl_register_64.v index e9c510138..eb58dbfd3 100644 --- a/tb/test_axis_srl_register_64.v +++ b/tb/test_axis_srl_register_64.v @@ -48,24 +48,24 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [DATA_WIDTH-1:0] input_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg [ID_WIDTH-1:0] input_axis_tid = 0; -reg [DEST_WIDTH-1:0] input_axis_tdest = 0; -reg [USER_WIDTH-1:0] input_axis_tuser = 0; -reg output_axis_tready = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_axis_tready; -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire s_axis_tready; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -73,24 +73,24 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tid, - input_axis_tdest, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -114,23 +114,23 @@ 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_tid(input_axis_tid), - .input_axis_tdest(input_axis_tdest), - .input_axis_tuser(input_axis_tuser), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule From 6f4ab8f1804985482f32174c23e8b29a6ceac2af Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 11:59:13 -0700 Subject: [PATCH 441/617] Rename ports --- rtl/axis_stat_counter.v | 135 +++++++++++++++++------------------ tb/test_axis_stat_counter.py | 66 ++++++++--------- tb/test_axis_stat_counter.v | 30 ++++---- 3 files changed, 115 insertions(+), 116 deletions(-) diff --git a/rtl/axis_stat_counter.v b/rtl/axis_stat_counter.v index abc5530be..f20a9bf7f 100644 --- a/rtl/axis_stat_counter.v +++ b/rtl/axis_stat_counter.v @@ -58,11 +58,11 @@ module axis_stat_counter # /* * AXI status data output */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [7:0] m_axis_tdata, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Configuration @@ -104,12 +104,12 @@ reg [FRAME_COUNT_WIDTH-1:0] frame_count_output_reg = 0; reg busy_reg = 1'b0; // internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [7:0] m_axis_tdata_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; assign busy = busy_reg; @@ -123,10 +123,10 @@ always @* begin frame_count_next = frame_count_reg; frame_next = frame_reg; - output_axis_tdata_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 8'd0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; store_output = 1'b0; @@ -143,18 +143,18 @@ always @* begin frame_count_next = 0; frame_ptr_next = 0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin frame_ptr_next = 1; if (TAG_ENABLE) begin - output_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; + m_axis_tdata_int = tag[(TAG_BYTE_WIDTH-1)*8 +: 8]; end else if (TICK_COUNT_ENABLE) begin - output_axis_tdata_int = tick_count_reg[(TICK_COUNT_BYTE_WIDTH-1)*8 +: 8]; + m_axis_tdata_int = tick_count_reg[(TICK_COUNT_BYTE_WIDTH-1)*8 +: 8]; end else if (BYTE_COUNT_ENABLE) begin - output_axis_tdata_int = byte_count_reg[(BYTE_COUNT_BYTE_WIDTH-1)*8 +: 8]; + m_axis_tdata_int = byte_count_reg[(BYTE_COUNT_BYTE_WIDTH-1)*8 +: 8]; end else if (FRAME_COUNT_ENABLE) begin - output_axis_tdata_int = frame_count_reg[(FRAME_COUNT_BYTE_WIDTH-1)*8 +: 8]; + m_axis_tdata_int = frame_count_reg[(FRAME_COUNT_BYTE_WIDTH-1)*8 +: 8]; end - output_axis_tvalid_int = 1'b1; + m_axis_tvalid_int = 1'b1; end state_next = STATE_OUTPUT_DATA; @@ -163,16 +163,16 @@ always @* begin end end STATE_OUTPUT_DATA: begin - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin state_next = STATE_OUTPUT_DATA; frame_ptr_next = frame_ptr_reg + 1; - output_axis_tvalid_int = 1'b1; + m_axis_tvalid_int = 1'b1; offset = 0; if (TAG_ENABLE) begin for (i = TAG_BYTE_WIDTH-1; i >= 0; i = i - 1) begin if (frame_ptr_reg == offset) begin - output_axis_tdata_int = tag[i*8 +: 8]; + m_axis_tdata_int = tag[i*8 +: 8]; end offset = offset + 1; end @@ -180,7 +180,7 @@ always @* begin if (TICK_COUNT_ENABLE) begin for (i = TICK_COUNT_BYTE_WIDTH-1; i >= 0; i = i - 1) begin if (frame_ptr_reg == offset) begin - output_axis_tdata_int = tick_count_output_reg[i*8 +: 8]; + m_axis_tdata_int = tick_count_output_reg[i*8 +: 8]; end offset = offset + 1; end @@ -188,7 +188,7 @@ always @* begin if (BYTE_COUNT_ENABLE) begin for (i = BYTE_COUNT_BYTE_WIDTH-1; i >= 0; i = i - 1) begin if (frame_ptr_reg == offset) begin - output_axis_tdata_int = byte_count_output_reg[i*8 +: 8]; + m_axis_tdata_int = byte_count_output_reg[i*8 +: 8]; end offset = offset + 1; end @@ -196,13 +196,13 @@ always @* begin if (FRAME_COUNT_ENABLE) begin for (i = FRAME_COUNT_BYTE_WIDTH-1; i >= 0; i = i - 1) begin if (frame_ptr_reg == offset) begin - output_axis_tdata_int = frame_count_output_reg[i*8 +: 8]; + m_axis_tdata_int = frame_count_output_reg[i*8 +: 8]; end offset = offset + 1; end end if (frame_ptr_reg == offset-1) begin - output_axis_tlast_int = 1'b1; + m_axis_tlast_int = 1'b1; state_next = STATE_IDLE; end end else begin @@ -216,7 +216,7 @@ always @* begin // increment tick count by number of words that can be transferred per cycle tick_count_next = tick_count_next + (KEEP_ENABLE ? KEEP_WIDTH : 1); - if (monitor_axis_tready & monitor_axis_tvalid) begin + if (monitor_axis_tready && monitor_axis_tvalid) begin // valid transfer cycle // increment byte count by number of words transferred @@ -235,7 +235,7 @@ always @* begin if (monitor_axis_tlast) begin // end of frame frame_next = 1'b0; - end else if (~frame_reg) begin + end else if (!frame_reg) begin // first word after end of frame frame_count_next = frame_count_next + 1; frame_next = 1'b1; @@ -261,7 +261,6 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; busy_reg <= state_next != STATE_IDLE; - end if (store_output) begin @@ -272,83 +271,83 @@ always @(posedge clk) begin end // output datapath logic -reg [7:0] output_axis_tdata_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg [7:0] m_axis_tdata_reg = 8'd0; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg [7:0] temp_m_axis_tdata_reg = 8'd0; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index 528287c0f..238d58604 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -66,16 +66,16 @@ def bench(): monitor_axis_tready = Signal(bool(0)) monitor_axis_tlast = Signal(bool(0)) monitor_axis_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) + m_axis_tready = Signal(bool(0)) tag = Signal(intbv(16)[TAG_WIDTH:]) trigger = Signal(bool(0)) # Outputs - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) # sources and sinks @@ -118,11 +118,11 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -144,11 +144,11 @@ def bench(): monitor_axis_tlast=monitor_axis_tlast, monitor_axis_tuser=monitor_axis_tuser, - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tready=output_axis_tready, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, tag=tag, trigger=trigger, @@ -192,7 +192,7 @@ def bench(): trigger.next = 0 yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge @@ -231,7 +231,7 @@ def bench(): yield clk.posedge trigger.next = 0 - while trigger or output_axis_tvalid: + while trigger or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -281,7 +281,7 @@ def bench(): while monitor_axis_tvalid: yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge @@ -291,7 +291,7 @@ def bench(): trigger.next = 0 yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge @@ -336,7 +336,7 @@ def bench(): while monitor_axis_tvalid: yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge @@ -346,7 +346,7 @@ def bench(): trigger.next = 0 yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge @@ -405,7 +405,7 @@ def bench(): while monitor_axis_tvalid: yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge @@ -415,7 +415,7 @@ def bench(): trigger.next = 0 yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge @@ -467,7 +467,7 @@ def bench(): while monitor_axis_tvalid: yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge @@ -477,7 +477,7 @@ def bench(): trigger.next = 0 yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge @@ -529,7 +529,7 @@ def bench(): while monitor_axis_tvalid: yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge @@ -539,7 +539,7 @@ def bench(): trigger.next = 0 yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge @@ -591,7 +591,7 @@ def bench(): while monitor_axis_tvalid: yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge @@ -601,7 +601,7 @@ def bench(): trigger.next = 0 yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge @@ -651,7 +651,7 @@ def bench(): while monitor_axis_tvalid: yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge @@ -661,7 +661,7 @@ def bench(): trigger.next = 0 yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge @@ -720,7 +720,7 @@ def bench(): while monitor_axis_tvalid: yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge @@ -730,7 +730,7 @@ def bench(): trigger.next = 0 yield clk.posedge - while output_axis_tvalid: + while m_axis_tvalid: yield clk.posedge yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_stat_counter.v b/tb/test_axis_stat_counter.v index 2fb6fa312..7b1d3765f 100644 --- a/tb/test_axis_stat_counter.v +++ b/tb/test_axis_stat_counter.v @@ -54,15 +54,15 @@ reg monitor_axis_tvalid = 0; reg monitor_axis_tready = 0; reg monitor_axis_tlast = 0; reg monitor_axis_tuser = 0; -reg output_axis_tready = 0; +reg m_axis_tready = 0; reg [TAG_WIDTH-1:0] tag = 0; reg trigger = 0; // Outputs -wire [7:0] output_axis_tdata; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; +wire [7:0] m_axis_tdata; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire busy; initial begin @@ -77,15 +77,15 @@ initial begin monitor_axis_tready, monitor_axis_tlast, monitor_axis_tuser, - output_axis_tready, + m_axis_tready, tag, trigger ); $to_myhdl( - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + m_axis_tdata, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, busy ); @@ -115,11 +115,11 @@ UUT ( .monitor_axis_tready(monitor_axis_tready), .monitor_axis_tlast(monitor_axis_tlast), // axi output - .output_axis_tdata(output_axis_tdata), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tready(output_axis_tready), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), // configuration .tag(tag), .trigger(trigger), From e9d9f32150f4925d56140f2fc436b69e86662d53 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 12:00:34 -0700 Subject: [PATCH 442/617] Rename ports --- rtl/axis_tap.v | 216 ++++++++++++++++++++--------------------- tb/test_axis_tap.py | 52 +++++----- tb/test_axis_tap.v | 48 ++++----- tb/test_axis_tap_64.py | 52 +++++----- tb/test_axis_tap_64.v | 48 ++++----- 5 files changed, 208 insertions(+), 208 deletions(-) diff --git a/rtl/axis_tap.v b/rtl/axis_tap.v index 3cd1f9ed2..bc9ceb088 100644 --- a/rtl/axis_tap.v +++ b/rtl/axis_tap.v @@ -62,14 +62,14 @@ module axis_tap # /* * 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 [ID_WIDTH-1:0] output_axis_tid, - output wire [DEST_WIDTH-1:0] output_axis_tdest, - output wire [USER_WIDTH-1:0] output_axis_tuser + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser ); // datapath control signals @@ -80,15 +80,15 @@ reg [DEST_WIDTH-1:0] last_word_dest_reg = {DEST_WIDTH{1'b0}}; reg [USER_WIDTH-1:0] last_word_user_reg = {USER_WIDTH{1'b0}}; // internal datapath -reg [DATA_WIDTH-1:0] output_axis_tdata_int; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg [ID_WIDTH-1:0] output_axis_tid_int; -reg [DEST_WIDTH-1:0] output_axis_tdest_int; -reg [USER_WIDTH-1:0] output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg [ID_WIDTH-1:0] m_axis_tid_int; +reg [DEST_WIDTH-1:0] m_axis_tdest_int; +reg [USER_WIDTH-1:0] m_axis_tuser_int; +wire m_axis_tready_int_early; localparam [1:0] STATE_IDLE = 2'd0, @@ -107,30 +107,30 @@ always @* begin frame_next = frame_reg; - output_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tid_int = {ID_WIDTH{1'b0}}; - output_axis_tdest_int = {DEST_WIDTH{1'b0}}; - output_axis_tuser_int = {USER_WIDTH{1'b0}}; + m_axis_tdata_int = {DATA_WIDTH{1'b0}}; + m_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tid_int = {ID_WIDTH{1'b0}}; + m_axis_tdest_int = {DEST_WIDTH{1'b0}}; + m_axis_tuser_int = {USER_WIDTH{1'b0}}; - if (tap_axis_tready & tap_axis_tvalid) begin - frame_next = ~tap_axis_tlast; + if (tap_axis_tready && tap_axis_tvalid) begin + frame_next = !tap_axis_tlast; end case (state_reg) STATE_IDLE: begin - if (tap_axis_tready & tap_axis_tvalid) begin + if (tap_axis_tready && tap_axis_tvalid) begin // start of frame - if (output_axis_tready_int_reg) begin - output_axis_tdata_int = tap_axis_tdata; - output_axis_tkeep_int = tap_axis_tkeep; - output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; - output_axis_tlast_int = tap_axis_tlast; - output_axis_tid_int = tap_axis_tid; - output_axis_tdest_int = tap_axis_tdest; - output_axis_tuser_int = tap_axis_tuser; + if (m_axis_tready_int_reg) begin + m_axis_tdata_int = tap_axis_tdata; + m_axis_tkeep_int = tap_axis_tkeep; + m_axis_tvalid_int = tap_axis_tvalid && tap_axis_tready; + m_axis_tlast_int = tap_axis_tlast; + m_axis_tid_int = tap_axis_tid; + m_axis_tdest_int = tap_axis_tdest; + m_axis_tuser_int = tap_axis_tuser; if (tap_axis_tlast) begin state_next = STATE_IDLE; end else begin @@ -144,16 +144,16 @@ always @* begin end end STATE_TRANSFER: begin - if (tap_axis_tready & tap_axis_tvalid) begin + if (tap_axis_tready && tap_axis_tvalid) begin // transfer data - if (output_axis_tready_int_reg) begin - output_axis_tdata_int = tap_axis_tdata; - output_axis_tkeep_int = tap_axis_tkeep; - output_axis_tvalid_int = tap_axis_tvalid & tap_axis_tready; - output_axis_tlast_int = tap_axis_tlast; - output_axis_tid_int = tap_axis_tid; - output_axis_tdest_int = tap_axis_tdest; - output_axis_tuser_int = tap_axis_tuser; + if (m_axis_tready_int_reg) begin + m_axis_tdata_int = tap_axis_tdata; + m_axis_tkeep_int = tap_axis_tkeep; + m_axis_tvalid_int = tap_axis_tvalid && tap_axis_tready; + m_axis_tlast_int = tap_axis_tlast; + m_axis_tid_int = tap_axis_tid; + m_axis_tdest_int = tap_axis_tdest; + m_axis_tuser_int = tap_axis_tuser; if (tap_axis_tlast) begin state_next = STATE_IDLE; end else begin @@ -168,14 +168,14 @@ always @* begin end end STATE_TRUNCATE: begin - if (output_axis_tready_int_reg) begin - output_axis_tdata_int = {DATA_WIDTH{1'b0}}; - output_axis_tkeep_int = {{KEEP_WIDTH-1{1'b0}}, 1'b1}; - output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = 1'b1; - output_axis_tid_int = last_word_id_reg; - output_axis_tdest_int = last_word_dest_reg; - output_axis_tuser_int = (last_word_user_reg & ~USER_BAD_FRAME_MASK) | (USER_BAD_FRAME_VALUE & USER_BAD_FRAME_MASK); + if (m_axis_tready_int_reg) begin + m_axis_tdata_int = {DATA_WIDTH{1'b0}}; + m_axis_tkeep_int = {{KEEP_WIDTH-1{1'b0}}, 1'b1}; + m_axis_tvalid_int = 1'b1; + m_axis_tlast_int = 1'b1; + m_axis_tid_int = last_word_id_reg; + m_axis_tdest_int = last_word_dest_reg; + m_axis_tuser_int = (last_word_user_reg & ~USER_BAD_FRAME_MASK) | (USER_BAD_FRAME_VALUE & USER_BAD_FRAME_MASK); if (frame_next) begin state_next = STATE_WAIT; end else begin @@ -186,7 +186,7 @@ always @* begin end end STATE_WAIT: begin - if (tap_axis_tready & tap_axis_tvalid) begin + if (tap_axis_tready && tap_axis_tvalid) begin if (tap_axis_tlast) begin state_next = STATE_IDLE; end else begin @@ -216,101 +216,101 @@ always @(posedge clk) begin end // output datapath logic -reg [DATA_WIDTH-1:0] output_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = KEEP_ENABLE ? output_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {USER_WIDTH{1'b0}}; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tid_reg <= output_axis_tid_int; - output_axis_tdest_reg <= output_axis_tdest_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tid_reg <= m_axis_tid_int; + m_axis_tdest_reg <= m_axis_tdest_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tid_reg <= temp_axis_tid_reg; - output_axis_tdest_reg <= temp_axis_tdest_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tid_reg <= output_axis_tid_int; - temp_axis_tdest_reg <= output_axis_tdest_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tid_reg <= m_axis_tid_int; + temp_m_axis_tdest_reg <= m_axis_tdest_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/tb/test_axis_tap.py b/tb/test_axis_tap.py index 5f7f94416..02bc578cf 100755 --- a/tb/test_axis_tap.py +++ b/tb/test_axis_tap.py @@ -68,16 +68,16 @@ def bench(): tap_axis_tid = Signal(intbv(0)[ID_WIDTH:]) tap_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) tap_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + m_axis_tready = Signal(bool(0)) # Outputs - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -105,14 +105,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -136,14 +136,14 @@ def bench(): tap_axis_tdest=tap_axis_tdest, tap_axis_tuser=tap_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -328,7 +328,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while tap_axis_tvalid or output_axis_tvalid: + while tap_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -373,7 +373,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while tap_axis_tvalid or output_axis_tvalid: + while tap_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_tap.v b/tb/test_axis_tap.v index 4d38c7c8e..2bb2516aa 100644 --- a/tb/test_axis_tap.v +++ b/tb/test_axis_tap.v @@ -57,16 +57,16 @@ reg tap_axis_tlast = 0; reg [ID_WIDTH-1:0] tap_axis_tid = 0; reg [DEST_WIDTH-1:0] tap_axis_tdest = 0; reg [USER_WIDTH-1:0] tap_axis_tuser = 0; -reg output_axis_tready = 0; +reg m_axis_tready = 0; // Outputs -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -82,16 +82,16 @@ initial begin tap_axis_tid, tap_axis_tdest, tap_axis_tuser, - output_axis_tready + m_axis_tready ); $to_myhdl( - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -125,14 +125,14 @@ UUT ( .tap_axis_tdest(tap_axis_tdest), .tap_axis_tuser(tap_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule diff --git a/tb/test_axis_tap_64.py b/tb/test_axis_tap_64.py index 9937d9c9e..b35cc8f28 100755 --- a/tb/test_axis_tap_64.py +++ b/tb/test_axis_tap_64.py @@ -68,16 +68,16 @@ def bench(): tap_axis_tid = Signal(intbv(0)[ID_WIDTH:]) tap_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) tap_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_axis_tready = Signal(bool(0)) + m_axis_tready = Signal(bool(0)) # Outputs - output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - output_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks source_pause = Signal(bool(0)) @@ -105,14 +105,14 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tid=output_axis_tid, - tdest=output_axis_tdest, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -136,14 +136,14 @@ def bench(): tap_axis_tdest=tap_axis_tdest, tap_axis_tuser=tap_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_tid=output_axis_tid, - output_axis_tdest=output_axis_tdest, - output_axis_tuser=output_axis_tuser + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser ) @always(delay(4)) @@ -328,7 +328,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while tap_axis_tvalid or output_axis_tvalid: + while tap_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -373,7 +373,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while tap_axis_tvalid or output_axis_tvalid: + while tap_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_tap_64.v b/tb/test_axis_tap_64.v index 5a8dbdf23..d4a93b1a9 100644 --- a/tb/test_axis_tap_64.v +++ b/tb/test_axis_tap_64.v @@ -57,16 +57,16 @@ reg tap_axis_tlast = 0; reg [ID_WIDTH-1:0] tap_axis_tid = 0; reg [DEST_WIDTH-1:0] tap_axis_tdest = 0; reg [USER_WIDTH-1:0] tap_axis_tuser = 0; -reg output_axis_tready = 0; +reg m_axis_tready = 0; // Outputs -wire [DATA_WIDTH-1:0] output_axis_tdata; -wire [KEEP_WIDTH-1:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire [ID_WIDTH-1:0] output_axis_tid; -wire [DEST_WIDTH-1:0] output_axis_tdest; -wire [USER_WIDTH-1:0] output_axis_tuser; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; initial begin // myhdl integration @@ -82,16 +82,16 @@ initial begin tap_axis_tid, tap_axis_tdest, tap_axis_tuser, - output_axis_tready + m_axis_tready ); $to_myhdl( - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tid, - output_axis_tdest, - output_axis_tuser + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser ); // dump file @@ -125,14 +125,14 @@ UUT ( .tap_axis_tdest(tap_axis_tdest), .tap_axis_tuser(tap_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_tid(output_axis_tid), - .output_axis_tdest(output_axis_tdest), - .output_axis_tuser(output_axis_tuser) + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) ); endmodule From 49d415d59f459c013f65c54fe0623b040b55be08 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 12:14:12 -0700 Subject: [PATCH 443/617] Disable dump file output under travis-ci --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 15f9a3c31..a3a8fd49c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,5 +11,5 @@ before_install: - cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/x86_64-linux-gnu/ivl/myhdl.vpi - cd $d script: - - cd tb && py.test + - cd tb && IVERILOG_DUMPER=none py.test From 312d90addb46b3229dc8918f3b03769022b3cab5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 14:23:00 -0700 Subject: [PATCH 444/617] Add wrapper generators --- rtl/axis_arb_mux_wrap.py | 171 ++++++++++++++++++++++++++++++++++ rtl/axis_crosspoint_wrap.py | 172 +++++++++++++++++++++++++++++++++++ rtl/axis_demux_wrap.py | 177 ++++++++++++++++++++++++++++++++++++ rtl/axis_frame_join_wrap.py | 155 +++++++++++++++++++++++++++++++ rtl/axis_mux_wrap.py | 174 +++++++++++++++++++++++++++++++++++ 5 files changed, 849 insertions(+) create mode 100755 rtl/axis_arb_mux_wrap.py create mode 100755 rtl/axis_crosspoint_wrap.py create mode 100755 rtl/axis_demux_wrap.py create mode 100755 rtl/axis_frame_join_wrap.py create mode 100755 rtl/axis_mux_wrap.py diff --git a/rtl/axis_arb_mux_wrap.py b/rtl/axis_arb_mux_wrap.py new file mode 100755 index 000000000..292dcc326 --- /dev/null +++ b/rtl/axis_arb_mux_wrap.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +""" +Generates an AXI Stream arbitrated mux wrapper with the specified number of ports +""" + +from __future__ import print_function + +import argparse +import math +from jinja2 import Template + +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() + + try: + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) + +def generate(ports=4, name=None, output=None): + n = ports + + if name is None: + name = "axis_arb_mux_wrap_{0}".format(n) + + if output is None: + output = name + ".v" + + print("Opening file '{0}'...".format(output)) + + output_file = open(output, 'w') + + print("Generating {0} port AXI stream arbitrated mux wrapper {1}...".format(n, name)) + + cn = int(math.ceil(math.log(n, 2))) + + t = Template(u"""/* + +Copyright (c) 2018 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port arbitrated mux (wrapper) + */ +module {{name}} # +( + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ +{%- for p in range(n) %} + input wire [DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] s{{'%02d'%p}}_axis_tkeep, + input wire s{{'%02d'%p}}_axis_tvalid, + output wire s{{'%02d'%p}}_axis_tready, + input wire s{{'%02d'%p}}_axis_tlast, + input wire [ID_WIDTH-1:0] s{{'%02d'%p}}_axis_tid, + input wire [DEST_WIDTH-1:0] s{{'%02d'%p}}_axis_tdest, + input wire [USER_WIDTH-1:0] s{{'%02d'%p}}_axis_tuser, +{% endfor %} + /* + * AXI Stream output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser +); + +axis_arb_mux #( + .S_COUNT({{n}}), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) +) +axis_arb_mux_inst ( + .clk(clk), + .rst(rst), + // AXI inputs + .s_axis_tdata({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tdata{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tkeep({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tkeep{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tvalid({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tvalid{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tready({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tready{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tlast({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tlast{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tid({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tid{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tdest({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tdest{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tuser({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tuser{% if not loop.last %}, {% endif %}{% endfor %} }), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) +); + +endmodule + +""") + + output_file.write(t.render( + n=n, + cn=cn, + name=name + )) + + print("Done") + +if __name__ == "__main__": + main() + diff --git a/rtl/axis_crosspoint_wrap.py b/rtl/axis_crosspoint_wrap.py new file mode 100755 index 000000000..7f2dcba99 --- /dev/null +++ b/rtl/axis_crosspoint_wrap.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +""" +Generates an AXI Stream crosspoint wrapper with the specified number of ports +""" + +from __future__ import print_function + +import argparse +import math +from jinja2 import Template + +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=[4], nargs='+', help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() + + try: + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) + +def generate(ports=4, name=None, output=None): + if type(ports) is int: + m = n = ports + elif len(ports) == 1: + m = n = ports[0] + else: + m, n = ports + + if name is None: + name = "axis_crosspoint_wrap_{0}x{1}".format(m, n) + + if output is None: + output = name + ".v" + + print("Opening file '{0}'...".format(output)) + + output_file = open(output, 'w') + + print("Generating {0}x{1} port AXI stream crosspoint wrapper {2}...".format(m, n, name)) + + cm = int(math.ceil(math.log(m, 2))) + cn = int(math.ceil(math.log(n, 2))) + + t = Template(u"""/* + +Copyright (c) 2018 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 {{m}}x{{n}} crosspoint (wrapper) + */ +module {{name}} # +( + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_WIDTH = {{cm}}, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ +{%- for p in range(m) %} + input wire [DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] s{{'%02d'%p}}_axis_tkeep, + input wire s{{'%02d'%p}}_axis_tvalid, + input wire s{{'%02d'%p}}_axis_tlast, + input wire [ID_WIDTH-1:0] s{{'%02d'%p}}_axis_tid, + input wire [DEST_WIDTH-1:0] s{{'%02d'%p}}_axis_tdest, + input wire [USER_WIDTH-1:0] s{{'%02d'%p}}_axis_tuser, +{% endfor %} + /* + * AXI Stream outputs + */ +{%- for p in range(n) %} + output wire [DATA_WIDTH-1:0] m{{'%02d'%p}}_axis_tdata, + output wire [KEEP_WIDTH-1:0] m{{'%02d'%p}}_axis_tkeep, + output wire m{{'%02d'%p}}_axis_tvalid, + output wire m{{'%02d'%p}}_axis_tlast, + output wire [ID_WIDTH-1:0] m{{'%02d'%p}}_axis_tid, + output wire [DEST_WIDTH-1:0] m{{'%02d'%p}}_axis_tdest, + output wire [USER_WIDTH-1:0] m{{'%02d'%p}}_axis_tuser{% if not loop.last %},{% endif %} +{% endfor -%} +); + +axis_crosspoint #( + .S_COUNT({{m}}), + .M_COUNT({{n}}), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) +axis_crosspoint_inst ( + .clk(clk), + .rst(rst), + // AXI inputs + .s_axis_tdata({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tdata{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tkeep({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tkeep{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tvalid({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tvalid{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tlast({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tlast{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tid({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tid{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tdest({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tdest{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tuser({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tuser{% if not loop.last %}, {% endif %}{% endfor %} }), + // AXI output + .m_axis_tdata({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tdata{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tkeep({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tkeep{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tvalid({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tvalid{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tlast({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tlast{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tid({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tid{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tdest({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tdest{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tuser({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tuser{% if not loop.last %}, {% endif %}{% endfor %} }) +); + +endmodule + +""") + + output_file.write(t.render( + m=m, + n=n, + cm=cm, + cn=cn, + name=name + )) + + print("Done") + +if __name__ == "__main__": + main() + diff --git a/rtl/axis_demux_wrap.py b/rtl/axis_demux_wrap.py new file mode 100755 index 000000000..c0554afb5 --- /dev/null +++ b/rtl/axis_demux_wrap.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +""" +Generates an AXI Stream demux wrapper with the specified number of ports +""" + +from __future__ import print_function + +import argparse +import math +from jinja2 import Template + +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() + + try: + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) + +def generate(ports=4, name=None, output=None): + n = ports + + if name is None: + name = "axis_demux_wrap_{0}".format(n) + + if output is None: + output = name + ".v" + + print("Opening file '{0}'...".format(output)) + + output_file = open(output, 'w') + + print("Generating {0} port AXI stream demux wrapper {1}...".format(n, name)) + + cn = int(math.ceil(math.log(n, 2))) + + t = Template(u"""/* + +Copyright (c) 2018 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port demux (wrapper) + */ +module {{name}} # +( + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream input + */ + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI Stream outputs + */ +{%- for p in range(n) %} + output wire [DATA_WIDTH-1:0] m{{'%02d'%p}}_axis_tdata, + output wire [KEEP_WIDTH-1:0] m{{'%02d'%p}}_axis_tkeep, + output wire m{{'%02d'%p}}_axis_tvalid, + input wire m{{'%02d'%p}}_axis_tready, + output wire m{{'%02d'%p}}_axis_tlast, + output wire [ID_WIDTH-1:0] m{{'%02d'%p}}_axis_tid, + output wire [DEST_WIDTH-1:0] m{{'%02d'%p}}_axis_tdest, + output wire [USER_WIDTH-1:0] m{{'%02d'%p}}_axis_tuser, +{% endfor -%} + + /* + * Control + */ + input wire enable, + input wire drop, + input wire [{{cn-1}}:0] select +); + +axis_demux #( + .M_COUNT({{n}}), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) +axis_demux_inst ( + .clk(clk), + .rst(rst), + // AXI inputs + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_axis_tdata({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tdata{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tkeep({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tkeep{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tvalid({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tvalid{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tready({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tready{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tlast({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tlast{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tid({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tid{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tdest({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tdest{% if not loop.last %}, {% endif %}{% endfor %} }), + .m_axis_tuser({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tuser{% if not loop.last %}, {% endif %}{% endfor %} }), + // Control + .enable(enable), + .drop(drop), + .select(select) +); + +endmodule + +""") + + output_file.write(t.render( + n=n, + cn=cn, + name=name + )) + + print("Done") + +if __name__ == "__main__": + main() + diff --git a/rtl/axis_frame_join_wrap.py b/rtl/axis_frame_join_wrap.py new file mode 100755 index 000000000..5a9b9b66f --- /dev/null +++ b/rtl/axis_frame_join_wrap.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python +""" +Generates an AXI Stream frame joiner wrapper with the specified number of ports +""" + +from __future__ import print_function + +import argparse +import math +from jinja2 import Template + +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() + + try: + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) + +def generate(ports=4, name=None, output=None): + n = ports + + if name is None: + name = "axis_frame_join_wrap_{0}".format(n) + + if output is None: + output = name + ".v" + + print("Opening file '{0}'...".format(output)) + + output_file = open(output, 'w') + + print("Generating {0} port AXI stream frame joiner wrapper {1}...".format(n, name)) + + cn = int(math.ceil(math.log(n, 2))) + + t = Template(u"""/* + +Copyright (c) 2018 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port frame joiner (wrapper) + */ +module {{name}} # +( + parameter DATA_WIDTH = 8, + parameter TAG_ENABLE = 1, + parameter TAG_WIDTH = 16 +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ +{%- for p in range(n) %} + input wire [DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata, + input wire s{{'%02d'%p}}_axis_tvalid, + output wire s{{'%02d'%p}}_axis_tready, + input wire s{{'%02d'%p}}_axis_tlast, + input wire s{{'%02d'%p}}_axis_tuser, +{% endfor %} + /* + * AXI Stream output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, + + /* + * Configuration + */ + input wire [TAG_WIDTH-1:0] tag, + + /* + * Status signals + */ + output wire busy +); + +axis_frame_join #( + .S_COUNT({{n}}), + .DATA_WIDTH(DATA_WIDTH), + .TAG_ENABLE(TAG_ENABLE), + .TAG_WIDTH(TAG_WIDTH) +) +axis_frame_join_inst ( + .clk(clk), + .rst(rst), + // AXI inputs + .s_axis_tdata({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tdata{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tvalid({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tvalid{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tready({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tready{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tlast({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tlast{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tuser({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tuser{% if not loop.last %}, {% endif %}{% endfor %} }), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), + // Configuration + .tag(tag), + // Status + .busy(busy) +); + +endmodule + +""") + + output_file.write(t.render( + n=n, + cn=cn, + name=name + )) + + print("Done") + +if __name__ == "__main__": + main() + diff --git a/rtl/axis_mux_wrap.py b/rtl/axis_mux_wrap.py new file mode 100755 index 000000000..2274de981 --- /dev/null +++ b/rtl/axis_mux_wrap.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python +""" +Generates an AXI Stream mux wrapper with the specified number of ports +""" + +from __future__ import print_function + +import argparse +import math +from jinja2 import Template + +def main(): + parser = argparse.ArgumentParser(description=__doc__.strip()) + parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") + parser.add_argument('-n', '--name', type=str, help="module name") + parser.add_argument('-o', '--output', type=str, help="output file name") + + args = parser.parse_args() + + try: + generate(**args.__dict__) + except IOError as ex: + print(ex) + exit(1) + +def generate(ports=4, name=None, output=None): + n = ports + + if name is None: + name = "axis_mux_wrap_{0}".format(n) + + if output is None: + output = name + ".v" + + print("Opening file '{0}'...".format(output)) + + output_file = open(output, 'w') + + print("Generating {0} port AXI stream mux wrapper {1}...".format(n, name)) + + cn = int(math.ceil(math.log(n, 2))) + + t = Template(u"""/* + +Copyright (c) 2018 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream {{n}} port mux (wrapper) + */ +module {{name}} # +( + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI Stream inputs + */ +{%- for p in range(n) %} + input wire [DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata, + input wire [KEEP_WIDTH-1:0] s{{'%02d'%p}}_axis_tkeep, + input wire s{{'%02d'%p}}_axis_tvalid, + output wire s{{'%02d'%p}}_axis_tready, + input wire s{{'%02d'%p}}_axis_tlast, + input wire [ID_WIDTH-1:0] s{{'%02d'%p}}_axis_tid, + input wire [DEST_WIDTH-1:0] s{{'%02d'%p}}_axis_tdest, + input wire [USER_WIDTH-1:0] s{{'%02d'%p}}_axis_tuser, +{% endfor %} + /* + * AXI Stream output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * Control + */ + input wire enable, + input wire [{{cn-1}}:0] select +); + +axis_mux #( + .S_COUNT({{n}}), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) +axis_mux_inst ( + .clk(clk), + .rst(rst), + // AXI inputs + .s_axis_tdata({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tdata{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tkeep({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tkeep{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tvalid({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tvalid{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tready({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tready{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tlast({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tlast{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tid({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tid{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tdest({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tdest{% if not loop.last %}, {% endif %}{% endfor %} }), + .s_axis_tuser({ {% for p in range(n-1,-1,-1) %}s{{'%02d'%p}}_axis_tuser{% if not loop.last %}, {% endif %}{% endfor %} }), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), + // Control + .enable(enable), + .select(select) +); + +endmodule + +""") + + output_file.write(t.render( + n=n, + cn=cn, + name=name + )) + + print("Done") + +if __name__ == "__main__": + main() + From ceedd0f8f5ccbaef45dac301c9c40379e84f109e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 14:27:24 -0700 Subject: [PATCH 445/617] Update readme --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ead09ec8f..03dbb6427 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ necessary. Frame-aware AXI stream arbitrated muliplexer with parametrizable data width and port count. Supports priority and round-robin arbitration. +Wrappers can generated with axis_arb_mux_wrap.py. + ### axis_async_fifo module Configurable word-based or frame-based asynchronous FIFO with parametrizable @@ -52,7 +54,7 @@ Configurable zero insertion. Basic crosspoint switch. tready signal not supported. Parametrizable data width. -Can be generated with arbitrary port counts with axis_crosspoint.py. +Wrappers can generated with axis_crosspoint_wrap.py. ### axis_demux module @@ -70,6 +72,8 @@ depths only. Frame joiner with optional tag and parametrizable port count. 8 bit data path only. +Wrappers can generated with axis_frame_join_wrap.py. + ### axis_frame_length_adjust module Frame length adjuster module. Truncates or pads frames as necessary to meet @@ -94,6 +98,8 @@ AXI stream to LocalLink bridge. Frame-aware AXI stream muliplexer with parametrizable data width and port count. +Wrappers can generated with axis_mux_wrap.py. + ### axis_rate_limit module Fractional rate limiter, supports word and frame modes. Inserts wait states @@ -127,6 +133,8 @@ monolithic frame from multiple monitored points with the same trigger. Frame-aware AXI stream switch with parametrizable data width and port count. +Wrappers can generated with axis_switch_wrap.py. + ### axis_tap module AXI stream tap module. Used to make a copy of an AXI stream bus without From ed4a2d73c2f3851928f14313eb08cc99fab467cd Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 14:29:35 -0700 Subject: [PATCH 446/617] Add axis_pipeline_register module --- rtl/axis_pipeline_register.v | 145 +++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 rtl/axis_pipeline_register.v diff --git a/rtl/axis_pipeline_register.v b/rtl/axis_pipeline_register.v new file mode 100644 index 000000000..9608c8819 --- /dev/null +++ b/rtl/axis_pipeline_register.v @@ -0,0 +1,145 @@ +/* + +Copyright (c) 2018 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 pipeline register + */ +module axis_pipeline_register # +( + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + parameter REG_TYPE = 2, + parameter LENGTH = 2 +) +( + 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, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser +); + +wire [DATA_WIDTH-1:0] axis_tdata[0:LENGTH]; +wire [KEEP_WIDTH-1:0] axis_tkeep[0:LENGTH]; +wire axis_tvalid[0:LENGTH]; +wire axis_tready[0:LENGTH]; +wire axis_tlast[0:LENGTH]; +wire [ID_WIDTH-1:0] axis_tid[0:LENGTH]; +wire [DEST_WIDTH-1:0] axis_tdest[0:LENGTH]; +wire [USER_WIDTH-1:0] axis_tuser[0:LENGTH]; + +assign axis_tdata[0] = s_axis_tdata; +assign axis_tkeep[0] = s_axis_tkeep; +assign axis_tvalid[0] = s_axis_tvalid; +assign s_axis_tready = axis_tready[0]; +assign axis_tlast[0] = s_axis_tlast; +assign axis_tid[0] = s_axis_tid; +assign axis_tdest[0] = s_axis_tdest; +assign axis_tuser[0] = s_axis_tuser; + +assign m_axis_tdata = axis_tdata[LENGTH]; +assign m_axis_tkeep = axis_tkeep[LENGTH]; +assign m_axis_tvalid = axis_tvalid[LENGTH]; +assign axis_tready[LENGTH] = m_axis_tready; +assign m_axis_tlast = axis_tlast[LENGTH]; +assign m_axis_tid = axis_tid[LENGTH]; +assign m_axis_tdest = axis_tdest[LENGTH]; +assign m_axis_tuser = axis_tuser[LENGTH]; + +integer i; + +generate + for (i = 0; i < LENGTH; i = i + 1) begin : reg + axis_register #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .REG_TYPE(REG_TYPE) + ) + reg_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(axis_tdata[i]), + .s_axis_tkeep(axis_tkeep[i]), + .s_axis_tvalid(axis_tvalid[i]), + .s_axis_tready(axis_tready[i]), + .s_axis_tlast(axis_tlast[i]), + .s_axis_tid(axis_tid[i]), + .s_axis_tdest(axis_tdest[i]), + .s_axis_tuser(axis_tuser[i]), + // AXI output + .m_axis_tdata(axis_tdata[i+1]), + .m_axis_tkeep(axis_tkeep[i+1]), + .m_axis_tvalid(axis_tvalid[i+1]), + .m_axis_tready(axis_tready[i+1]), + .m_axis_tlast(axis_tlast[i+1]), + .m_axis_tid(axis_tid[i+1]), + .m_axis_tdest(axis_tdest[i+1]), + .m_axis_tuser(axis_tuser[i+1]) + ); + end +endgenerate + +endmodule From ebe9d17bd529252e351f75cdd87c18b6835bfd09 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 14:30:42 -0700 Subject: [PATCH 447/617] Update readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 03dbb6427..a4de85a25 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,11 @@ count. Wrappers can generated with axis_mux_wrap.py. +### axis_pipeline_register module + +Parametrizable register pipeline. LENGTH parameter determines number of +register stages. + ### axis_rate_limit module Fractional rate limiter, supports word and frame modes. Inserts wait states From ded363b471659ec93e3cba6f86f401ffdde33d96 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 15:36:34 -0700 Subject: [PATCH 448/617] Rename status outputs --- rtl/axis_fifo.v | 12 ++-- tb/axis_ep.py | 27 ++++++-- tb/test_axis_fifo.v | 6 +- tb/test_axis_fifo_64.v | 6 +- tb/test_axis_frame_fifo.py | 126 +++++++++++++++++----------------- tb/test_axis_frame_fifo.v | 18 ++--- tb/test_axis_frame_fifo_64.py | 126 +++++++++++++++++----------------- tb/test_axis_frame_fifo_64.v | 18 ++--- 8 files changed, 177 insertions(+), 162 deletions(-) diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index 37e249f4b..de2e90c1e 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -79,9 +79,9 @@ module axis_fifo # /* * Status */ - output wire overflow, - output wire bad_frame, - output wire good_frame + output wire status_overflow, + output wire status_bad_frame, + output wire status_good_frame ); // check configuration @@ -168,9 +168,9 @@ assign m_axis_tid = ID_ENABLE ? m_axis_reg[ID_OFFSET +: ID_WIDTH] : {ID_ assign m_axis_tdest = DEST_ENABLE ? m_axis_reg[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; assign m_axis_tuser = USER_ENABLE ? m_axis_reg[USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; -assign overflow = overflow_reg; -assign bad_frame = bad_frame_reg; -assign good_frame = good_frame_reg; +assign status_overflow = overflow_reg; +assign status_bad_frame = bad_frame_reg; +assign status_good_frame = good_frame_reg; // Write logic always @* begin diff --git a/tb/axis_ep.py b/tb/axis_ep.py index 67417520e..d794cc4a9 100644 --- a/tb/axis_ep.py +++ b/tb/axis_ep.py @@ -248,6 +248,7 @@ class AXIStreamFrame(object): class AXIStreamSource(object): def __init__(self): + self.active = False self.has_logic = False self.queue = [] @@ -263,6 +264,13 @@ class AXIStreamSource(object): def empty(self): return not self.queue + def idle(self): + return not self.queue and not self.active + + def wait(self): + while not self.idle(): + yield self.clk.posedge + def create_logic(self, clk, rst, @@ -289,7 +297,7 @@ class AXIStreamSource(object): id = [] dest = [] user = [] - valid = False + self.active = False B = 0 N = len(tdata) M = len(tkeep) @@ -311,7 +319,7 @@ class AXIStreamSource(object): id = [] dest = [] user = [] - valid = False + self.active = False if B > 0: for s in tdata: s.next = 0 @@ -324,7 +332,7 @@ class AXIStreamSource(object): tvalid.next = False tlast.next = False else: - tvalid.next = valid and (tvalid or not pause) + tvalid.next = self.active and (tvalid or not pause) if tready and tvalid: if len(data) > 0: if B > 0: @@ -342,8 +350,8 @@ class AXIStreamSource(object): else: tvalid.next = False tlast.next = False - valid = False - if not valid and self.queue: + self.active = False + if not self.active and self.queue: frame = self.queue.pop(0) frame.B = B frame.N = N @@ -364,13 +372,14 @@ class AXIStreamSource(object): tuser.next = user.pop(0) tvalid.next = not pause tlast.next = len(data) == 0 - valid = True + self.active = True return instances() class AXIStreamSink(object): def __init__(self): + self.active = False self.has_logic = False self.queue = [] self.read_queue = [] @@ -396,6 +405,9 @@ class AXIStreamSink(object): def empty(self): return not self.queue + def idle(self): + return not self.active + def wait(self, timeout=0): if self.queue: return @@ -462,6 +474,7 @@ class AXIStreamSink(object): dest = [] user = [] first = True + self.active = False else: tready_int.next = True @@ -498,6 +511,7 @@ class AXIStreamSink(object): dest.append(int(tdest)) user.append(int(tuser)) first = False + self.active = True if tlast: frame = AXIStreamFrame() frame.B = B @@ -507,6 +521,7 @@ class AXIStreamSink(object): frame.parse(data, keep, id, dest, user) self.queue.append(frame) self.sync.next = not self.sync + self.active = False if name is not None: print("[%s] Got frame %s" % (name, repr(frame))) data = [] diff --git a/tb/test_axis_fifo.v b/tb/test_axis_fifo.v index 042477a6b..6a8d4ee77 100644 --- a/tb/test_axis_fifo.v +++ b/tb/test_axis_fifo.v @@ -144,9 +144,9 @@ UUT ( .m_axis_tdest(m_axis_tdest), .m_axis_tuser(m_axis_tuser), // Status - .overflow(), - .bad_frame(), - .good_frame() + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/tb/test_axis_fifo_64.v b/tb/test_axis_fifo_64.v index cc36f5ab6..e1ea50f6a 100644 --- a/tb/test_axis_fifo_64.v +++ b/tb/test_axis_fifo_64.v @@ -144,9 +144,9 @@ UUT ( .m_axis_tdest(m_axis_tdest), .m_axis_tuser(m_axis_tuser), // Status - .overflow(), - .bad_frame(), - .good_frame() + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index 0beddc0fe..2bcc89f38 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -83,9 +83,9 @@ def bench(): m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - overflow = Signal(bool(0)) - bad_frame = Signal(bool(0)) - good_frame = Signal(bool(0)) + status_overflow = Signal(bool(0)) + status_bad_frame = Signal(bool(0)) + status_good_frame = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -153,27 +153,27 @@ def bench(): m_axis_tdest=m_axis_tdest, m_axis_tuser=m_axis_tuser, - overflow=overflow, - bad_frame=bad_frame, - good_frame=good_frame + status_overflow=status_overflow, + status_bad_frame=status_bad_frame, + status_good_frame=status_good_frame ) @always(delay(4)) def clkgen(): clk.next = not clk - overflow_asserted = Signal(bool(0)) - bad_frame_asserted = Signal(bool(0)) - good_frame_asserted = Signal(bool(0)) + status_overflow_asserted = Signal(bool(0)) + status_bad_frame_asserted = Signal(bool(0)) + status_good_frame_asserted = Signal(bool(0)) @always(clk.posedge) def monitor(): - if (overflow): - overflow_asserted.next = 1 - if (bad_frame): - bad_frame_asserted.next = 1 - if (good_frame): - good_frame_asserted.next = 1 + if (status_overflow): + status_overflow_asserted.next = 1 + if (status_bad_frame): + status_bad_frame_asserted.next = 1 + if (status_good_frame): + status_good_frame_asserted.next = 1 @instance def check(): @@ -201,9 +201,9 @@ def bench(): dest=1 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame) @@ -212,9 +212,9 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield delay(100) @@ -231,9 +231,9 @@ def bench(): dest=1 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame) @@ -242,9 +242,9 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield clk.posedge print("test 3: test packet with pauses") @@ -259,9 +259,9 @@ def bench(): dest=1 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame) yield clk.posedge @@ -285,9 +285,9 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield delay(100) @@ -312,9 +312,9 @@ def bench(): dest=2 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) @@ -329,9 +329,9 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield delay(100) @@ -356,9 +356,9 @@ def bench(): dest=2 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) @@ -382,9 +382,9 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield delay(100) @@ -409,9 +409,9 @@ def bench(): dest=2 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) @@ -435,9 +435,9 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield delay(100) @@ -455,9 +455,9 @@ def bench(): last_cycle_user=1 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame) yield clk.posedge @@ -466,9 +466,9 @@ def bench(): assert sink.empty() - assert not overflow_asserted - assert bad_frame_asserted - assert not good_frame_asserted + assert not status_overflow_asserted + assert status_bad_frame_asserted + assert not status_good_frame_asserted yield delay(100) @@ -485,9 +485,9 @@ def bench(): dest=1 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame) yield clk.posedge @@ -496,9 +496,9 @@ def bench(): assert sink.empty() - assert overflow_asserted - assert not bad_frame_asserted - assert not good_frame_asserted + assert status_overflow_asserted + assert not status_bad_frame_asserted + assert not status_good_frame_asserted yield delay(100) diff --git a/tb/test_axis_frame_fifo.v b/tb/test_axis_frame_fifo.v index 41d90bd8a..8ba096c22 100644 --- a/tb/test_axis_frame_fifo.v +++ b/tb/test_axis_frame_fifo.v @@ -72,9 +72,9 @@ wire m_axis_tlast; wire [ID_WIDTH-1:0] m_axis_tid; wire [DEST_WIDTH-1:0] m_axis_tdest; wire [USER_WIDTH-1:0] m_axis_tuser; -wire overflow; -wire bad_frame; -wire good_frame; +wire status_overflow; +wire status_bad_frame; +wire status_good_frame; initial begin // myhdl integration @@ -100,9 +100,9 @@ initial begin m_axis_tid, m_axis_tdest, m_axis_tuser, - overflow, - bad_frame, - good_frame + status_overflow, + status_bad_frame, + status_good_frame ); // dump file @@ -150,9 +150,9 @@ UUT ( .m_axis_tdest(m_axis_tdest), .m_axis_tuser(m_axis_tuser), // Status - .overflow(overflow), - .bad_frame(bad_frame), - .good_frame(good_frame) + .status_overflow(status_overflow), + .status_bad_frame(status_bad_frame), + .status_good_frame(status_good_frame) ); endmodule diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index 4fc121384..0d541dd3e 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -83,9 +83,9 @@ def bench(): m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - overflow = Signal(bool(0)) - bad_frame = Signal(bool(0)) - good_frame = Signal(bool(0)) + status_overflow = Signal(bool(0)) + status_bad_frame = Signal(bool(0)) + status_good_frame = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -153,27 +153,27 @@ def bench(): m_axis_tdest=m_axis_tdest, m_axis_tuser=m_axis_tuser, - overflow=overflow, - bad_frame=bad_frame, - good_frame=good_frame + status_overflow=status_overflow, + status_bad_frame=status_bad_frame, + status_good_frame=status_good_frame ) @always(delay(4)) def clkgen(): clk.next = not clk - overflow_asserted = Signal(bool(0)) - bad_frame_asserted = Signal(bool(0)) - good_frame_asserted = Signal(bool(0)) + status_overflow_asserted = Signal(bool(0)) + status_bad_frame_asserted = Signal(bool(0)) + status_good_frame_asserted = Signal(bool(0)) @always(clk.posedge) def monitor(): - if (overflow): - overflow_asserted.next = 1 - if (bad_frame): - bad_frame_asserted.next = 1 - if (good_frame): - good_frame_asserted.next = 1 + if (status_overflow): + status_overflow_asserted.next = 1 + if (status_bad_frame): + status_bad_frame_asserted.next = 1 + if (status_good_frame): + status_good_frame_asserted.next = 1 @instance def check(): @@ -201,9 +201,9 @@ def bench(): dest=1 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame) @@ -212,9 +212,9 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield delay(100) @@ -231,9 +231,9 @@ def bench(): dest=1 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame) @@ -242,9 +242,9 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield clk.posedge print("test 3: test packet with pauses") @@ -259,9 +259,9 @@ def bench(): dest=1 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame) yield clk.posedge @@ -285,9 +285,9 @@ def bench(): assert rx_frame == test_frame - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield delay(100) @@ -312,9 +312,9 @@ def bench(): dest=2 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) @@ -329,9 +329,9 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield delay(100) @@ -356,9 +356,9 @@ def bench(): dest=2 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) @@ -382,9 +382,9 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield delay(100) @@ -409,9 +409,9 @@ def bench(): dest=2 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame1) source.send(test_frame2) @@ -435,9 +435,9 @@ def bench(): assert rx_frame == test_frame2 - assert not overflow_asserted - assert not bad_frame_asserted - assert good_frame_asserted + assert not status_overflow_asserted + assert not status_bad_frame_asserted + assert status_good_frame_asserted yield delay(100) @@ -455,9 +455,9 @@ def bench(): last_cycle_user=1 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame) yield clk.posedge @@ -466,9 +466,9 @@ def bench(): assert sink.empty() - assert not overflow_asserted - assert bad_frame_asserted - assert not good_frame_asserted + assert not status_overflow_asserted + assert status_bad_frame_asserted + assert not status_good_frame_asserted yield delay(100) @@ -485,9 +485,9 @@ def bench(): dest=1 ) - overflow_asserted.next = 0 - bad_frame_asserted.next = 0 - good_frame_asserted.next = 0 + status_overflow_asserted.next = 0 + status_bad_frame_asserted.next = 0 + status_good_frame_asserted.next = 0 source.send(test_frame) yield clk.posedge @@ -496,9 +496,9 @@ def bench(): assert sink.empty() - assert overflow_asserted - assert not bad_frame_asserted - assert not good_frame_asserted + assert status_overflow_asserted + assert not status_bad_frame_asserted + assert not status_good_frame_asserted yield delay(100) diff --git a/tb/test_axis_frame_fifo_64.v b/tb/test_axis_frame_fifo_64.v index 1f72e1056..94e858918 100644 --- a/tb/test_axis_frame_fifo_64.v +++ b/tb/test_axis_frame_fifo_64.v @@ -72,9 +72,9 @@ wire m_axis_tlast; wire [ID_WIDTH-1:0] m_axis_tid; wire [DEST_WIDTH-1:0] m_axis_tdest; wire [USER_WIDTH-1:0] m_axis_tuser; -wire overflow; -wire bad_frame; -wire good_frame; +wire status_overflow; +wire status_bad_frame; +wire status_good_frame; initial begin // myhdl integration @@ -100,9 +100,9 @@ initial begin m_axis_tid, m_axis_tdest, m_axis_tuser, - overflow, - bad_frame, - good_frame + status_overflow, + status_bad_frame, + status_good_frame ); // dump file @@ -150,9 +150,9 @@ UUT ( .m_axis_tdest(m_axis_tdest), .m_axis_tuser(m_axis_tuser), // Status - .overflow(overflow), - .bad_frame(bad_frame), - .good_frame(good_frame) + .status_overflow(status_overflow), + .status_bad_frame(status_bad_frame), + .status_good_frame(status_good_frame) ); endmodule From be51f2b472a54a58948797e4b7c1920cbe44b7d6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 25 Oct 2018 16:06:32 -0700 Subject: [PATCH 449/617] Update FIFO instantiations --- rtl/axis_cobs_encode.v | 12 ++++++------ rtl/axis_frame_length_adjust_fifo.v | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/rtl/axis_cobs_encode.v b/rtl/axis_cobs_encode.v index 79a7d07b3..00a8e4ccb 100644 --- a/rtl/axis_cobs_encode.v +++ b/rtl/axis_cobs_encode.v @@ -133,9 +133,9 @@ code_fifo_inst ( .m_axis_tdest(), .m_axis_tuser(code_fifo_out_tuser), // Status - .overflow(), - .bad_frame(), - .good_frame() + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); reg [7:0] data_fifo_in_tdata; @@ -180,9 +180,9 @@ data_fifo_inst ( .m_axis_tdest(), .m_axis_tuser(), // Status - .overflow(), - .bad_frame(), - .good_frame() + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); always @* begin diff --git a/rtl/axis_frame_length_adjust_fifo.v b/rtl/axis_frame_length_adjust_fifo.v index d82e804e1..0bcb9f3d1 100644 --- a/rtl/axis_frame_length_adjust_fifo.v +++ b/rtl/axis_frame_length_adjust_fifo.v @@ -180,9 +180,9 @@ frame_fifo_inst ( .m_axis_tdest(m_axis_tdest), .m_axis_tuser(m_axis_tuser), // Status - .overflow(), - .bad_frame(), - .good_frame() + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); axis_fifo #( @@ -217,9 +217,9 @@ header_fifo_inst ( .m_axis_tdest(), .m_axis_tuser(), // Status - .overflow(), - .bad_frame(), - .good_frame() + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule From ad8828d5b7a0470f338a017ba81fa42ffd1fa691 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 30 Oct 2018 11:58:06 -0700 Subject: [PATCH 450/617] Update FIFO instances --- rtl/eth_mac_10g_fifo.v | 124 ++++++++++++++++--------------- rtl/eth_mac_1g_fifo.v | 124 ++++++++++++++++--------------- rtl/eth_mac_1g_gmii_fifo.v | 124 ++++++++++++++++--------------- rtl/eth_mac_1g_rgmii_fifo.v | 124 ++++++++++++++++--------------- rtl/udp_checksum_gen.v | 39 +++++----- rtl/udp_checksum_gen_64.v | 39 +++++----- tb/test_eth_mac_10g_fifo_32.py | 2 +- tb/test_eth_mac_10g_fifo_64.py | 2 +- tb/test_eth_mac_1g_fifo.py | 2 +- tb/test_eth_mac_1g_gmii_fifo.py | 2 +- tb/test_eth_mac_1g_rgmii_fifo.py | 2 +- 11 files changed, 309 insertions(+), 275 deletions(-) diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 1f5e278df..207aad38b 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -38,7 +38,13 @@ module eth_mac_10g_fifo # parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, parameter TX_FIFO_ADDR_WIDTH = 9, - parameter RX_FIFO_ADDR_WIDTH = 9 + parameter TX_FRAME_FIFO = 1, + parameter TX_DROP_BAD_FRAME = TX_FRAME_FIFO, + parameter TX_DROP_WHEN_FULL = 0, + parameter RX_FIFO_ADDR_WIDTH = 9, + parameter RX_FRAME_FIFO = 1, + parameter RX_DROP_BAD_FRAME = RX_FRAME_FIFO, + parameter RX_DROP_WHEN_FULL = RX_FRAME_FIFO ) ( input wire rx_clk, @@ -172,100 +178,100 @@ eth_mac_10g_inst ( .ifg_delay(ifg_delay) ); -axis_async_frame_fifo #( +axis_async_fifo #( .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(1), .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(1), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), .USER_WIDTH(1), + .FRAME_FIFO(TX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), - .DROP_BAD_FRAME(1), - .DROP_WHEN_FULL(0) + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) ) tx_fifo ( // Common reset .async_rst(logic_rst | tx_rst), // AXI input - .input_clk(logic_clk), - .input_axis_tdata(tx_axis_tdata), - .input_axis_tkeep(tx_axis_tkeep), - .input_axis_tvalid(tx_axis_tvalid), - .input_axis_tready(tx_axis_tready), - .input_axis_tlast(tx_axis_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(tx_axis_tuser), + .s_clk(logic_clk), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(tx_axis_tkeep), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(tx_axis_tuser), // AXI output - .output_clk(tx_clk), - .output_axis_tdata(tx_fifo_axis_tdata), - .output_axis_tkeep(tx_fifo_axis_tkeep), - .output_axis_tvalid(tx_fifo_axis_tvalid), - .output_axis_tready(tx_fifo_axis_tready), - .output_axis_tlast(tx_fifo_axis_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(), + .m_clk(tx_clk), + .m_axis_tdata(tx_fifo_axis_tdata), + .m_axis_tkeep(tx_fifo_axis_tkeep), + .m_axis_tvalid(tx_fifo_axis_tvalid), + .m_axis_tready(tx_fifo_axis_tready), + .m_axis_tlast(tx_fifo_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_axis_tuser), // Status - .input_status_overflow(tx_fifo_overflow), - .input_status_bad_frame(tx_fifo_bad_frame), - .input_status_good_frame(tx_fifo_good_frame), - .output_status_overflow(), - .output_status_bad_frame(), - .output_status_good_frame() + .s_status_overflow(tx_fifo_overflow), + .s_status_bad_frame(tx_fifo_bad_frame), + .s_status_good_frame(tx_fifo_good_frame), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() ); -assign tx_fifo_axis_tuser = 1'b0; - -axis_async_frame_fifo #( +axis_async_fifo #( .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(1), .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(1), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), .USER_WIDTH(1), + .FRAME_FIFO(RX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), - .DROP_BAD_FRAME(1), - .DROP_WHEN_FULL(1) + .DROP_BAD_FRAME(RX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(RX_DROP_WHEN_FULL) ) rx_fifo ( // Common reset .async_rst(rx_rst | logic_rst), // AXI input - .input_clk(rx_clk), - .input_axis_tdata(rx_fifo_axis_tdata), - .input_axis_tkeep(rx_fifo_axis_tkeep), - .input_axis_tvalid(rx_fifo_axis_tvalid), - .input_axis_tready(), - .input_axis_tlast(rx_fifo_axis_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_axis_tuser), + .s_clk(rx_clk), + .s_axis_tdata(rx_fifo_axis_tdata), + .s_axis_tkeep(rx_fifo_axis_tkeep), + .s_axis_tvalid(rx_fifo_axis_tvalid), + .s_axis_tready(), + .s_axis_tlast(rx_fifo_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_axis_tuser), // AXI output - .output_clk(logic_clk), - .output_axis_tdata(rx_axis_tdata), - .output_axis_tkeep(rx_axis_tkeep), - .output_axis_tvalid(rx_axis_tvalid), - .output_axis_tready(rx_axis_tready), - .output_axis_tlast(rx_axis_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(), + .m_clk(logic_clk), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(rx_axis_tkeep), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tready(rx_axis_tready), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(rx_axis_tuser), // Status - .input_status_overflow(), - .input_status_bad_frame(), - .input_status_good_frame(), - .output_status_overflow(rx_fifo_overflow), - .output_status_bad_frame(rx_fifo_bad_frame), - .output_status_good_frame(rx_fifo_good_frame) + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(rx_fifo_overflow), + .m_status_bad_frame(rx_fifo_bad_frame), + .m_status_good_frame(rx_fifo_good_frame) ); -assign rx_axis_tuser = 1'b0; - endmodule diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index 4abdf4560..b80fd95f1 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -34,7 +34,13 @@ module eth_mac_1g_fifo # parameter ENABLE_PADDING = 1, parameter MIN_FRAME_LENGTH = 64, parameter TX_FIFO_ADDR_WIDTH = 12, - parameter RX_FIFO_ADDR_WIDTH = 12 + parameter TX_FRAME_FIFO = 1, + parameter TX_DROP_BAD_FRAME = TX_FRAME_FIFO, + parameter TX_DROP_WHEN_FULL = 0, + parameter RX_FIFO_ADDR_WIDTH = 12, + parameter RX_FRAME_FIFO = 1, + parameter RX_DROP_BAD_FRAME = RX_FRAME_FIFO, + parameter RX_DROP_WHEN_FULL = RX_FRAME_FIFO ) ( input wire rx_clk, @@ -174,98 +180,98 @@ eth_mac_1g_inst ( .ifg_delay(ifg_delay) ); -axis_async_frame_fifo #( +axis_async_fifo #( .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), .KEEP_ENABLE(0), + .LAST_ENABLE(1), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), .USER_WIDTH(1), + .FRAME_FIFO(TX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), - .DROP_BAD_FRAME(1), - .DROP_WHEN_FULL(0) + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) ) tx_fifo ( // Common reset .async_rst(logic_rst | tx_rst), // AXI input - .input_clk(logic_clk), - .input_axis_tdata(tx_axis_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(tx_axis_tvalid), - .input_axis_tready(tx_axis_tready), - .input_axis_tlast(tx_axis_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(tx_axis_tuser), + .s_clk(logic_clk), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(tx_axis_tuser), // AXI output - .output_clk(tx_clk), - .output_axis_tdata(tx_fifo_axis_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(tx_fifo_axis_tvalid), - .output_axis_tready(tx_fifo_axis_tready), - .output_axis_tlast(tx_fifo_axis_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(), + .m_clk(tx_clk), + .m_axis_tdata(tx_fifo_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_axis_tvalid), + .m_axis_tready(tx_fifo_axis_tready), + .m_axis_tlast(tx_fifo_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_axis_tuser), // Status - .input_status_overflow(tx_fifo_overflow), - .input_status_bad_frame(tx_fifo_bad_frame), - .input_status_good_frame(tx_fifo_good_frame), - .output_status_overflow(), - .output_status_bad_frame(), - .output_status_good_frame() + .s_status_overflow(tx_fifo_overflow), + .s_status_bad_frame(tx_fifo_bad_frame), + .s_status_good_frame(tx_fifo_good_frame), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() ); -assign tx_fifo_axis_tuser = 1'b0; - -axis_async_frame_fifo #( +axis_async_fifo #( .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), .KEEP_ENABLE(0), + .LAST_ENABLE(1), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), .USER_WIDTH(1), + .FRAME_FIFO(TX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), - .DROP_BAD_FRAME(1), - .DROP_WHEN_FULL(1) + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) ) rx_fifo ( // Common reset .async_rst(rx_rst | logic_rst), // AXI input - .input_clk(rx_clk), - .input_axis_tdata(rx_fifo_axis_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(rx_fifo_axis_tvalid), - .input_axis_tready(), - .input_axis_tlast(rx_fifo_axis_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_axis_tuser), + .s_clk(rx_clk), + .s_axis_tdata(rx_fifo_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_axis_tvalid), + .s_axis_tready(), + .s_axis_tlast(rx_fifo_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_axis_tuser), // AXI output - .output_clk(logic_clk), - .output_axis_tdata(rx_axis_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(rx_axis_tvalid), - .output_axis_tready(rx_axis_tready), - .output_axis_tlast(rx_axis_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(), + .m_clk(logic_clk), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tready(rx_axis_tready), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(rx_axis_tuser), // Status - .input_status_overflow(), - .input_status_bad_frame(), - .input_status_good_frame(), - .output_status_overflow(rx_fifo_overflow), - .output_status_bad_frame(rx_fifo_bad_frame), - .output_status_good_frame(rx_fifo_good_frame) + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(rx_fifo_overflow), + .m_status_bad_frame(rx_fifo_bad_frame), + .m_status_good_frame(rx_fifo_good_frame) ); -assign rx_axis_tuser = 1'b0; - endmodule diff --git a/rtl/eth_mac_1g_gmii_fifo.v b/rtl/eth_mac_1g_gmii_fifo.v index 885359d71..17d4ae35b 100644 --- a/rtl/eth_mac_1g_gmii_fifo.v +++ b/rtl/eth_mac_1g_gmii_fifo.v @@ -45,7 +45,13 @@ module eth_mac_1g_gmii_fifo # parameter ENABLE_PADDING = 1, parameter MIN_FRAME_LENGTH = 64, parameter TX_FIFO_ADDR_WIDTH = 12, - parameter RX_FIFO_ADDR_WIDTH = 12 + parameter TX_FRAME_FIFO = 1, + parameter TX_DROP_BAD_FRAME = TX_FRAME_FIFO, + parameter TX_DROP_WHEN_FULL = 0, + parameter RX_FIFO_ADDR_WIDTH = 12, + parameter RX_FRAME_FIFO = 1, + parameter RX_DROP_BAD_FRAME = RX_FRAME_FIFO, + parameter RX_DROP_WHEN_FULL = RX_FRAME_FIFO ) ( input wire gtx_clk, @@ -201,98 +207,98 @@ eth_mac_1g_gmii_inst ( .ifg_delay(ifg_delay) ); -axis_async_frame_fifo #( +axis_async_fifo #( .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), .KEEP_ENABLE(0), + .LAST_ENABLE(1), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), .USER_WIDTH(1), + .FRAME_FIFO(TX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), - .DROP_BAD_FRAME(1), - .DROP_WHEN_FULL(0) + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) ) tx_fifo ( // Common reset .async_rst(logic_rst | tx_rst), // AXI input - .input_clk(logic_clk), - .input_axis_tdata(tx_axis_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(tx_axis_tvalid), - .input_axis_tready(tx_axis_tready), - .input_axis_tlast(tx_axis_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(tx_axis_tuser), + .s_clk(logic_clk), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(tx_axis_tuser), // AXI output - .output_clk(tx_clk), - .output_axis_tdata(tx_fifo_axis_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(tx_fifo_axis_tvalid), - .output_axis_tready(tx_fifo_axis_tready), - .output_axis_tlast(tx_fifo_axis_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(), + .m_clk(tx_clk), + .m_axis_tdata(tx_fifo_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_axis_tvalid), + .m_axis_tready(tx_fifo_axis_tready), + .m_axis_tlast(tx_fifo_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_axis_tuser), // Status - .input_status_overflow(tx_fifo_overflow), - .input_status_bad_frame(tx_fifo_bad_frame), - .input_status_good_frame(tx_fifo_good_frame), - .output_status_overflow(), - .output_status_bad_frame(), - .output_status_good_frame() + .s_status_overflow(tx_fifo_overflow), + .s_status_bad_frame(tx_fifo_bad_frame), + .s_status_good_frame(tx_fifo_good_frame), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() ); -assign tx_fifo_axis_tuser = 1'b0; - -axis_async_frame_fifo #( +axis_async_fifo #( .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), .KEEP_ENABLE(0), + .LAST_ENABLE(1), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), .USER_WIDTH(1), + .FRAME_FIFO(TX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), - .DROP_BAD_FRAME(1), - .DROP_WHEN_FULL(1) + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) ) rx_fifo ( // Common reset .async_rst(rx_rst | logic_rst), // AXI input - .input_clk(rx_clk), - .input_axis_tdata(rx_fifo_axis_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(rx_fifo_axis_tvalid), - .input_axis_tready(), - .input_axis_tlast(rx_fifo_axis_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_axis_tuser), + .s_clk(rx_clk), + .s_axis_tdata(rx_fifo_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_axis_tvalid), + .s_axis_tready(), + .s_axis_tlast(rx_fifo_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_axis_tuser), // AXI output - .output_clk(logic_clk), - .output_axis_tdata(rx_axis_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(rx_axis_tvalid), - .output_axis_tready(rx_axis_tready), - .output_axis_tlast(rx_axis_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(), + .m_clk(logic_clk), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tready(rx_axis_tready), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(rx_axis_tuser), // Status - .input_status_overflow(), - .input_status_bad_frame(), - .input_status_good_frame(), - .output_status_overflow(rx_fifo_overflow), - .output_status_bad_frame(rx_fifo_bad_frame), - .output_status_good_frame(rx_fifo_good_frame) + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(rx_fifo_overflow), + .m_status_bad_frame(rx_fifo_bad_frame), + .m_status_good_frame(rx_fifo_good_frame) ); -assign rx_axis_tuser = 1'b0; - endmodule diff --git a/rtl/eth_mac_1g_rgmii_fifo.v b/rtl/eth_mac_1g_rgmii_fifo.v index 27a3676d9..2298d52d5 100644 --- a/rtl/eth_mac_1g_rgmii_fifo.v +++ b/rtl/eth_mac_1g_rgmii_fifo.v @@ -47,7 +47,13 @@ module eth_mac_1g_rgmii_fifo # parameter ENABLE_PADDING = 1, parameter MIN_FRAME_LENGTH = 64, parameter TX_FIFO_ADDR_WIDTH = 12, - parameter RX_FIFO_ADDR_WIDTH = 12 + parameter TX_FRAME_FIFO = 1, + parameter TX_DROP_BAD_FRAME = TX_FRAME_FIFO, + parameter TX_DROP_WHEN_FULL = 0, + parameter RX_FIFO_ADDR_WIDTH = 12, + parameter RX_FRAME_FIFO = 1, + parameter RX_DROP_BAD_FRAME = RX_FRAME_FIFO, + parameter RX_DROP_WHEN_FULL = RX_FRAME_FIFO ) ( input wire gtx_clk, @@ -200,98 +206,98 @@ eth_mac_1g_rgmii_inst ( .ifg_delay(ifg_delay) ); -axis_async_frame_fifo #( +axis_async_fifo #( .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), .KEEP_ENABLE(0), + .LAST_ENABLE(1), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), .USER_WIDTH(1), + .FRAME_FIFO(TX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), - .DROP_BAD_FRAME(1), - .DROP_WHEN_FULL(0) + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) ) tx_fifo ( // Common reset .async_rst(logic_rst | tx_rst), // AXI input - .input_clk(logic_clk), - .input_axis_tdata(tx_axis_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(tx_axis_tvalid), - .input_axis_tready(tx_axis_tready), - .input_axis_tlast(tx_axis_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(tx_axis_tuser), + .s_clk(logic_clk), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(tx_axis_tuser), // AXI output - .output_clk(tx_clk), - .output_axis_tdata(tx_fifo_axis_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(tx_fifo_axis_tvalid), - .output_axis_tready(tx_fifo_axis_tready), - .output_axis_tlast(tx_fifo_axis_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(), + .m_clk(tx_clk), + .m_axis_tdata(tx_fifo_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_axis_tvalid), + .m_axis_tready(tx_fifo_axis_tready), + .m_axis_tlast(tx_fifo_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_axis_tuser), // Status - .input_status_overflow(tx_fifo_overflow), - .input_status_bad_frame(tx_fifo_bad_frame), - .input_status_good_frame(tx_fifo_good_frame), - .output_status_overflow(), - .output_status_bad_frame(), - .output_status_good_frame() + .s_status_overflow(tx_fifo_overflow), + .s_status_bad_frame(tx_fifo_bad_frame), + .s_status_good_frame(tx_fifo_good_frame), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() ); -assign tx_fifo_axis_tuser = 1'b0; - -axis_async_frame_fifo #( +axis_async_fifo #( .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), .DATA_WIDTH(8), .KEEP_ENABLE(0), + .LAST_ENABLE(1), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), .USER_WIDTH(1), + .FRAME_FIFO(TX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), - .DROP_BAD_FRAME(1), - .DROP_WHEN_FULL(1) + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) ) rx_fifo ( // Common reset .async_rst(rx_rst | logic_rst), // AXI input - .input_clk(rx_clk), - .input_axis_tdata(rx_fifo_axis_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(rx_fifo_axis_tvalid), - .input_axis_tready(), - .input_axis_tlast(rx_fifo_axis_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_axis_tuser), + .s_clk(rx_clk), + .s_axis_tdata(rx_fifo_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_axis_tvalid), + .s_axis_tready(), + .s_axis_tlast(rx_fifo_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_axis_tuser), // AXI output - .output_clk(logic_clk), - .output_axis_tdata(rx_axis_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(rx_axis_tvalid), - .output_axis_tready(rx_axis_tready), - .output_axis_tlast(rx_axis_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(), + .m_clk(logic_clk), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tready(rx_axis_tready), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(rx_axis_tuser), // Status - .input_status_overflow(), - .input_status_bad_frame(), - .input_status_good_frame(), - .output_status_overflow(rx_fifo_overflow), - .output_status_bad_frame(rx_fifo_bad_frame), - .output_status_good_frame(rx_fifo_good_frame) + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(rx_fifo_overflow), + .m_status_bad_frame(rx_fifo_bad_frame), + .m_status_good_frame(rx_fifo_good_frame) ); -assign rx_axis_tuser = 1'b0; - endmodule diff --git a/rtl/udp_checksum_gen.v b/rtl/udp_checksum_gen.v index 8f63e78bb..0e2f788dd 100644 --- a/rtl/udp_checksum_gen.v +++ b/rtl/udp_checksum_gen.v @@ -204,29 +204,34 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) payload_fifo ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(input_udp_payload_fifo_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(input_udp_payload_fifo_tvalid), - .input_axis_tready(input_udp_payload_fifo_tready), - .input_axis_tlast(input_udp_payload_fifo_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(input_udp_payload_fifo_tuser), + .s_axis_tdata(input_udp_payload_fifo_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(input_udp_payload_fifo_tvalid), + .s_axis_tready(input_udp_payload_fifo_tready), + .s_axis_tlast(input_udp_payload_fifo_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(input_udp_payload_fifo_tuser), // AXI output - .output_axis_tdata(output_udp_payload_fifo_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(output_udp_payload_fifo_tvalid), - .output_axis_tready(output_udp_payload_fifo_tready), - .output_axis_tlast(output_udp_payload_fifo_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(output_udp_payload_fifo_tuser) + .m_axis_tdata(output_udp_payload_fifo_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(output_udp_payload_fifo_tvalid), + .m_axis_tready(output_udp_payload_fifo_tready), + .m_axis_tlast(output_udp_payload_fifo_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(output_udp_payload_fifo_tuser), + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); assign input_udp_payload_fifo_tdata = input_udp_payload_tdata; diff --git a/rtl/udp_checksum_gen_64.v b/rtl/udp_checksum_gen_64.v index 69b8ae3e8..ce07a3560 100644 --- a/rtl/udp_checksum_gen_64.v +++ b/rtl/udp_checksum_gen_64.v @@ -210,29 +210,34 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) payload_fifo ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(input_udp_payload_fifo_tdata), - .input_axis_tkeep(input_udp_payload_fifo_tkeep), - .input_axis_tvalid(input_udp_payload_fifo_tvalid), - .input_axis_tready(input_udp_payload_fifo_tready), - .input_axis_tlast(input_udp_payload_fifo_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(input_udp_payload_fifo_tuser), + .s_axis_tdata(input_udp_payload_fifo_tdata), + .s_axis_tkeep(input_udp_payload_fifo_tkeep), + .s_axis_tvalid(input_udp_payload_fifo_tvalid), + .s_axis_tready(input_udp_payload_fifo_tready), + .s_axis_tlast(input_udp_payload_fifo_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(input_udp_payload_fifo_tuser), // AXI output - .output_axis_tdata(output_udp_payload_fifo_tdata), - .output_axis_tkeep(output_udp_payload_fifo_tkeep), - .output_axis_tvalid(output_udp_payload_fifo_tvalid), - .output_axis_tready(output_udp_payload_fifo_tready), - .output_axis_tlast(output_udp_payload_fifo_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(output_udp_payload_fifo_tuser) + .m_axis_tdata(output_udp_payload_fifo_tdata), + .m_axis_tkeep(output_udp_payload_fifo_tkeep), + .m_axis_tvalid(output_udp_payload_fifo_tvalid), + .m_axis_tready(output_udp_payload_fifo_tready), + .m_axis_tlast(output_udp_payload_fifo_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(output_udp_payload_fifo_tuser), + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); assign input_udp_payload_fifo_tdata = input_udp_payload_tdata; diff --git a/tb/test_eth_mac_10g_fifo_32.py b/tb/test_eth_mac_10g_fifo_32.py index 78a20dbc9..c68537a69 100755 --- a/tb/test_eth_mac_10g_fifo_32.py +++ b/tb/test_eth_mac_10g_fifo_32.py @@ -40,7 +40,7 @@ srcs.append("../rtl/lfsr.v") srcs.append("../rtl/axis_xgmii_rx_32.v") srcs.append("../rtl/axis_xgmii_tx_32.v") srcs.append("../rtl/eth_mac_10g.v") -srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/tb/test_eth_mac_10g_fifo_64.py b/tb/test_eth_mac_10g_fifo_64.py index 349bda134..6d954097e 100755 --- a/tb/test_eth_mac_10g_fifo_64.py +++ b/tb/test_eth_mac_10g_fifo_64.py @@ -40,7 +40,7 @@ srcs.append("../rtl/lfsr.v") srcs.append("../rtl/axis_xgmii_rx_64.v") srcs.append("../rtl/axis_xgmii_tx_64.v") srcs.append("../rtl/eth_mac_10g.v") -srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py index 7c7a5f6b8..bd3f6da08 100755 --- a/tb/test_eth_mac_1g_fifo.py +++ b/tb/test_eth_mac_1g_fifo.py @@ -40,7 +40,7 @@ srcs.append("../rtl/lfsr.v") srcs.append("../rtl/axis_gmii_rx.v") srcs.append("../rtl/axis_gmii_tx.v") srcs.append("../rtl/eth_mac_1g.v") -srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/tb/test_eth_mac_1g_gmii_fifo.py b/tb/test_eth_mac_1g_gmii_fifo.py index a66886a51..b62c5ed6f 100755 --- a/tb/test_eth_mac_1g_gmii_fifo.py +++ b/tb/test_eth_mac_1g_gmii_fifo.py @@ -45,7 +45,7 @@ srcs.append("../rtl/gmii_phy_if.v") srcs.append("../rtl/oddr.v") srcs.append("../rtl/ssio_sdr_in.v") srcs.append("../rtl/ssio_sdr_out.v") -srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/tb/test_eth_mac_1g_rgmii_fifo.py b/tb/test_eth_mac_1g_rgmii_fifo.py index 24ea0cf48..764e49b95 100755 --- a/tb/test_eth_mac_1g_rgmii_fifo.py +++ b/tb/test_eth_mac_1g_rgmii_fifo.py @@ -46,7 +46,7 @@ srcs.append("../rtl/iddr.v") srcs.append("../rtl/oddr.v") srcs.append("../rtl/ssio_ddr_in.v") srcs.append("../rtl/ssio_ddr_out.v") -srcs.append("../lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) From 20017c04b93a907a059eb8793d2b80451ffc466f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 30 Oct 2018 11:58:53 -0700 Subject: [PATCH 451/617] Work around MyHDL cosimulation race condition --- tb/test_eth_mac_1g_gmii.py | 2 +- tb/test_eth_mac_1g_rgmii.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tb/test_eth_mac_1g_gmii.py b/tb/test_eth_mac_1g_gmii.py index ac887843c..0949654a2 100755 --- a/tb/test_eth_mac_1g_gmii.py +++ b/tb/test_eth_mac_1g_gmii.py @@ -127,7 +127,7 @@ def bench(): axis_source = axis_ep.AXIStreamSource() axis_source_logic = axis_source.create_logic( - tx_clk, + gmii_rx_clk, #tx_clk, tx_rst, tdata=tx_axis_tdata, tvalid=tx_axis_tvalid, diff --git a/tb/test_eth_mac_1g_rgmii.py b/tb/test_eth_mac_1g_rgmii.py index b439e4860..ba777e133 100755 --- a/tb/test_eth_mac_1g_rgmii.py +++ b/tb/test_eth_mac_1g_rgmii.py @@ -125,7 +125,7 @@ def bench(): axis_source = axis_ep.AXIStreamSource() axis_source_logic = axis_source.create_logic( - tx_clk, + gtx_clk, #tx_clk, tx_rst, tdata=tx_axis_tdata, tvalid=tx_axis_tvalid, From 733044b0df9320999b2e74db110164998819ed24 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 30 Oct 2018 11:59:09 -0700 Subject: [PATCH 452/617] Work around MyHDL sync race condition --- tb/test_eth_axis_rx_64.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index 32439a894..0ae6ebff4 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -206,6 +206,7 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -241,11 +242,13 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -283,12 +286,14 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -329,6 +334,7 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() From 8d564b107462e131cc8698e3c7ee34bf1241eee5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 30 Oct 2018 17:35:38 -0700 Subject: [PATCH 453/617] Convert localparam to parameter as Vivado does not like clog2 in localparams --- rtl/axis_adapter.v | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index 896008efa..bb6ed92cc 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -74,23 +74,23 @@ module axis_adapter # ); // force keep width to 1 when disabled -localparam S_KEEP_WIDTH_INT = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1; -localparam M_KEEP_WIDTH_INT = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1; +parameter S_KEEP_WIDTH_INT = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1; +parameter M_KEEP_WIDTH_INT = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1; // bus word sizes (must be identical) -localparam S_DATA_WORD_SIZE = S_DATA_WIDTH / S_KEEP_WIDTH_INT; -localparam M_DATA_WORD_SIZE = M_DATA_WIDTH / M_KEEP_WIDTH_INT; +parameter S_DATA_WORD_SIZE = S_DATA_WIDTH / S_KEEP_WIDTH_INT; +parameter M_DATA_WORD_SIZE = M_DATA_WIDTH / M_KEEP_WIDTH_INT; // output bus is wider -localparam EXPAND_BUS = M_KEEP_WIDTH_INT > S_KEEP_WIDTH_INT; +parameter EXPAND_BUS = M_KEEP_WIDTH_INT > S_KEEP_WIDTH_INT; // total data and keep widths -localparam DATA_WIDTH = EXPAND_BUS ? M_DATA_WIDTH : S_DATA_WIDTH; -localparam KEEP_WIDTH = EXPAND_BUS ? M_KEEP_WIDTH_INT : S_KEEP_WIDTH_INT; +parameter DATA_WIDTH = EXPAND_BUS ? M_DATA_WIDTH : S_DATA_WIDTH; +parameter KEEP_WIDTH = EXPAND_BUS ? M_KEEP_WIDTH_INT : S_KEEP_WIDTH_INT; // required number of cycles to match widths -localparam CYCLE_COUNT = EXPAND_BUS ? (M_KEEP_WIDTH_INT / S_KEEP_WIDTH_INT) : (S_KEEP_WIDTH_INT / M_KEEP_WIDTH_INT); -localparam CYCLE_COUNT_WIDTH = CYCLE_COUNT == 1 ? 1 : $clog2(CYCLE_COUNT); +parameter CYCLE_COUNT = EXPAND_BUS ? (M_KEEP_WIDTH_INT / S_KEEP_WIDTH_INT) : (S_KEEP_WIDTH_INT / M_KEEP_WIDTH_INT); +parameter CYCLE_COUNT_WIDTH = CYCLE_COUNT == 1 ? 1 : $clog2(CYCLE_COUNT); // data width and keep width per cycle -localparam CYCLE_DATA_WIDTH = DATA_WIDTH / CYCLE_COUNT; -localparam CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT; +parameter CYCLE_DATA_WIDTH = DATA_WIDTH / CYCLE_COUNT; +parameter CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT; // bus width assertions initial begin From 7d6889add67cf934da23def01a778da4072e8dad Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 30 Oct 2018 21:32:32 -0700 Subject: [PATCH 454/617] Update example designs --- example/ATLYS/fpga/fpga/Makefile | 2 +- example/ATLYS/fpga/rtl/fpga_core.v | 44 +- example/ATLYS/fpga/tb/test_fpga_core.py | 2 +- example/DE5-Net/fpga/fpga/Makefile | 2 +- example/DE5-Net/fpga/rtl/fpga_core.v | 44 +- example/DE5-Net/fpga/tb/test_fpga_core.py | 2 +- example/HXT100G/fpga/fpga/Makefile | 2 +- example/HXT100G/fpga/rtl/fpga_core.v | 44 +- example/HXT100G/fpga/tb/test_fpga_core.py | 2 +- example/HXT100G/fpga_cxpt16/fpga/Makefile | 4 +- .../fpga_cxpt16/rtl/axis_crosspoint_16x16.v | 3334 ----------------- example/HXT100G/fpga_cxpt16/rtl/fpga_core.v | 137 +- .../HXT100G/fpga_cxpt16/tb/test_fpga_core.py | 4 +- example/ML605/fpga_gmii/fpga_130t/Makefile | 2 +- example/ML605/fpga_gmii/fpga_240t/Makefile | 2 +- example/ML605/fpga_gmii/rtl/fpga_core.v | 44 +- example/ML605/fpga_gmii/tb/test_fpga_core.py | 2 +- example/ML605/fpga_rgmii/fpga_130t/Makefile | 2 +- example/ML605/fpga_rgmii/fpga_240t/Makefile | 2 +- example/ML605/fpga_rgmii/rtl/fpga_core.v | 44 +- example/ML605/fpga_rgmii/tb/test_fpga_core.py | 2 +- example/ML605/fpga_sgmii/fpga_130t/Makefile | 2 +- example/ML605/fpga_sgmii/fpga_240t/Makefile | 2 +- example/ML605/fpga_sgmii/rtl/fpga_core.v | 44 +- example/ML605/fpga_sgmii/tb/test_fpga_core.py | 2 +- example/NexysVideo/fpga/fpga/Makefile | 2 +- example/NexysVideo/fpga/rtl/fpga_core.v | 44 +- example/NexysVideo/fpga/tb/test_fpga_core.py | 2 +- example/VCU108/fpga_10g/fpga/Makefile | 5 +- example/VCU108/fpga_10g/rtl/fpga_core.v | 205 +- example/VCU108/fpga_10g/tb/test_fpga_core.py | 5 +- example/VCU108/fpga_1g/fpga/Makefile | 2 +- example/VCU108/fpga_1g/rtl/fpga_core.v | 44 +- example/VCU108/fpga_1g/tb/test_fpga_core.py | 2 +- example/VCU118/fpga_10g/fpga/Makefile | 5 +- example/VCU118/fpga_10g/rtl/fpga_core.v | 205 +- example/VCU118/fpga_10g/tb/test_fpga_core.py | 5 +- example/VCU118/fpga_1g/fpga/Makefile | 2 +- example/VCU118/fpga_1g/rtl/fpga_core.v | 44 +- example/VCU118/fpga_1g/tb/test_fpga_core.py | 2 +- 40 files changed, 456 insertions(+), 3891 deletions(-) delete mode 100644 example/HXT100G/fpga_cxpt16/rtl/axis_crosspoint_16x16.v diff --git a/example/ATLYS/fpga/fpga/Makefile b/example/ATLYS/fpga/fpga/Makefile index ce0381e91..ca2f8954a 100644 --- a/example/ATLYS/fpga/fpga/Makefile +++ b/example/ATLYS/fpga/fpga/Makefile @@ -47,7 +47,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v #SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v # UCF files diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index b55dae1c5..ad68f8006 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -317,7 +317,9 @@ eth_mac_1g_gmii_fifo #( .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), - .RX_FIFO_ADDR_WIDTH(12) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) ) eth_mac_inst ( .gtx_clk(clk), @@ -550,31 +552,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index 9a4eaa413..e0f9fcefc 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -70,7 +70,7 @@ srcs.append("../lib/eth/rtl/eth_mux_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/DE5-Net/fpga/fpga/Makefile b/example/DE5-Net/fpga/fpga/Makefile index fba61fa3a..44641f6fc 100644 --- a/example/DE5-Net/fpga/fpga/Makefile +++ b/example/DE5-Net/fpga/fpga/Makefile @@ -41,7 +41,7 @@ SYN_FILES += lib/eth/rtl/xgmii_deinterleave.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v SYN_FILES += cores/phy/phy.qip SYN_FILES += cores/phy_reconfig/phy_reconfig.qip diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index c97f87dd9..3a8604c17 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -336,7 +336,9 @@ eth_mac_10g_fifo #( .ENABLE_DIC(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(9), - .RX_FIFO_ADDR_WIDTH(9) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(9), + .RX_FRAME_FIFO(1) ) eth_mac_10g_fifo_inst ( .rx_clk(clk), @@ -578,31 +580,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(rx_fifo_udp_payload_tkeep), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(tx_fifo_udp_payload_tkeep), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index 0fd1a8b1b..129b3e0ab 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -64,7 +64,7 @@ srcs.append("../lib/eth/rtl/eth_mux_64_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/HXT100G/fpga/fpga/Makefile b/example/HXT100G/fpga/fpga/Makefile index 06c1a6e4a..23454c522 100644 --- a/example/HXT100G/fpga/fpga/Makefile +++ b/example/HXT100G/fpga/fpga/Makefile @@ -44,7 +44,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_64_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6.v SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6/example_design/ten_gig_eth_pcs_pma_v2_6_management_arbiter.v SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_quad.v diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v index 56fee2161..16c386580 100644 --- a/example/HXT100G/fpga/rtl/fpga_core.v +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -480,7 +480,9 @@ eth_mac_10g_fifo #( .ENABLE_DIC(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(9), - .RX_FIFO_ADDR_WIDTH(9) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(9), + .RX_FRAME_FIFO(1) ) eth_mac_10g_fifo_inst ( .rx_clk(clk), @@ -722,31 +724,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(rx_fifo_udp_payload_tkeep), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(tx_fifo_udp_payload_tkeep), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index baf1c7b17..f78bccea3 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -64,7 +64,7 @@ srcs.append("../lib/eth/rtl/eth_mux_64_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/HXT100G/fpga_cxpt16/fpga/Makefile b/example/HXT100G/fpga_cxpt16/fpga/Makefile index 721af3e0e..d2771adf9 100644 --- a/example/HXT100G/fpga_cxpt16/fpga/Makefile +++ b/example/HXT100G/fpga_cxpt16/fpga/Makefile @@ -17,7 +17,6 @@ SYN_FILES += rtl/sync_signal.v SYN_FILES += rtl/i2c_master.v SYN_FILES += rtl/gth_i2c_init.v SYN_FILES += rtl/eth_gth_phy_quad.v -SYN_FILES += rtl/axis_crosspoint_16x16.v SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v @@ -25,7 +24,8 @@ SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_crosspoint.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6.v SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6/example_design/ten_gig_eth_pcs_pma_v2_6_management_arbiter.v SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_quad.v diff --git a/example/HXT100G/fpga_cxpt16/rtl/axis_crosspoint_16x16.v b/example/HXT100G/fpga_cxpt16/rtl/axis_crosspoint_16x16.v deleted file mode 100644 index 25fa61576..000000000 --- a/example/HXT100G/fpga_cxpt16/rtl/axis_crosspoint_16x16.v +++ /dev/null @@ -1,3334 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 16x16 crosspoint - */ -module axis_crosspoint_16x16 # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = (DATA_WIDTH>8), - parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter LAST_ENABLE = 1, - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1 -) -( - input wire clk, - input wire rst, - - /* - * AXI Stream inputs - */ - input wire [DATA_WIDTH-1:0] input_0_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_0_axis_tkeep, - input wire input_0_axis_tvalid, - input wire input_0_axis_tlast, - input wire [ID_WIDTH-1:0] input_0_axis_tid, - input wire [DEST_WIDTH-1:0] input_0_axis_tdest, - input wire [USER_WIDTH-1:0] input_0_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_1_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_1_axis_tkeep, - input wire input_1_axis_tvalid, - input wire input_1_axis_tlast, - input wire [ID_WIDTH-1:0] input_1_axis_tid, - input wire [DEST_WIDTH-1:0] input_1_axis_tdest, - input wire [USER_WIDTH-1:0] input_1_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_2_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_2_axis_tkeep, - input wire input_2_axis_tvalid, - input wire input_2_axis_tlast, - input wire [ID_WIDTH-1:0] input_2_axis_tid, - input wire [DEST_WIDTH-1:0] input_2_axis_tdest, - input wire [USER_WIDTH-1:0] input_2_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_3_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_3_axis_tkeep, - input wire input_3_axis_tvalid, - input wire input_3_axis_tlast, - input wire [ID_WIDTH-1:0] input_3_axis_tid, - input wire [DEST_WIDTH-1:0] input_3_axis_tdest, - input wire [USER_WIDTH-1:0] input_3_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_4_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_4_axis_tkeep, - input wire input_4_axis_tvalid, - input wire input_4_axis_tlast, - input wire [ID_WIDTH-1:0] input_4_axis_tid, - input wire [DEST_WIDTH-1:0] input_4_axis_tdest, - input wire [USER_WIDTH-1:0] input_4_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_5_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_5_axis_tkeep, - input wire input_5_axis_tvalid, - input wire input_5_axis_tlast, - input wire [ID_WIDTH-1:0] input_5_axis_tid, - input wire [DEST_WIDTH-1:0] input_5_axis_tdest, - input wire [USER_WIDTH-1:0] input_5_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_6_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_6_axis_tkeep, - input wire input_6_axis_tvalid, - input wire input_6_axis_tlast, - input wire [ID_WIDTH-1:0] input_6_axis_tid, - input wire [DEST_WIDTH-1:0] input_6_axis_tdest, - input wire [USER_WIDTH-1:0] input_6_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_7_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_7_axis_tkeep, - input wire input_7_axis_tvalid, - input wire input_7_axis_tlast, - input wire [ID_WIDTH-1:0] input_7_axis_tid, - input wire [DEST_WIDTH-1:0] input_7_axis_tdest, - input wire [USER_WIDTH-1:0] input_7_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_8_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_8_axis_tkeep, - input wire input_8_axis_tvalid, - input wire input_8_axis_tlast, - input wire [ID_WIDTH-1:0] input_8_axis_tid, - input wire [DEST_WIDTH-1:0] input_8_axis_tdest, - input wire [USER_WIDTH-1:0] input_8_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_9_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_9_axis_tkeep, - input wire input_9_axis_tvalid, - input wire input_9_axis_tlast, - input wire [ID_WIDTH-1:0] input_9_axis_tid, - input wire [DEST_WIDTH-1:0] input_9_axis_tdest, - input wire [USER_WIDTH-1:0] input_9_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_10_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_10_axis_tkeep, - input wire input_10_axis_tvalid, - input wire input_10_axis_tlast, - input wire [ID_WIDTH-1:0] input_10_axis_tid, - input wire [DEST_WIDTH-1:0] input_10_axis_tdest, - input wire [USER_WIDTH-1:0] input_10_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_11_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_11_axis_tkeep, - input wire input_11_axis_tvalid, - input wire input_11_axis_tlast, - input wire [ID_WIDTH-1:0] input_11_axis_tid, - input wire [DEST_WIDTH-1:0] input_11_axis_tdest, - input wire [USER_WIDTH-1:0] input_11_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_12_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_12_axis_tkeep, - input wire input_12_axis_tvalid, - input wire input_12_axis_tlast, - input wire [ID_WIDTH-1:0] input_12_axis_tid, - input wire [DEST_WIDTH-1:0] input_12_axis_tdest, - input wire [USER_WIDTH-1:0] input_12_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_13_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_13_axis_tkeep, - input wire input_13_axis_tvalid, - input wire input_13_axis_tlast, - input wire [ID_WIDTH-1:0] input_13_axis_tid, - input wire [DEST_WIDTH-1:0] input_13_axis_tdest, - input wire [USER_WIDTH-1:0] input_13_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_14_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_14_axis_tkeep, - input wire input_14_axis_tvalid, - input wire input_14_axis_tlast, - input wire [ID_WIDTH-1:0] input_14_axis_tid, - input wire [DEST_WIDTH-1:0] input_14_axis_tdest, - input wire [USER_WIDTH-1:0] input_14_axis_tuser, - - input wire [DATA_WIDTH-1:0] input_15_axis_tdata, - input wire [KEEP_WIDTH-1:0] input_15_axis_tkeep, - input wire input_15_axis_tvalid, - input wire input_15_axis_tlast, - input wire [ID_WIDTH-1:0] input_15_axis_tid, - input wire [DEST_WIDTH-1:0] input_15_axis_tdest, - input wire [USER_WIDTH-1:0] input_15_axis_tuser, - - /* - * AXI Stream outputs - */ - output wire [DATA_WIDTH-1:0] output_0_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_0_axis_tkeep, - output wire output_0_axis_tvalid, - output wire output_0_axis_tlast, - output wire [ID_WIDTH-1:0] output_0_axis_tid, - output wire [DEST_WIDTH-1:0] output_0_axis_tdest, - output wire [USER_WIDTH-1:0] output_0_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_1_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_1_axis_tkeep, - output wire output_1_axis_tvalid, - output wire output_1_axis_tlast, - output wire [ID_WIDTH-1:0] output_1_axis_tid, - output wire [DEST_WIDTH-1:0] output_1_axis_tdest, - output wire [USER_WIDTH-1:0] output_1_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_2_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_2_axis_tkeep, - output wire output_2_axis_tvalid, - output wire output_2_axis_tlast, - output wire [ID_WIDTH-1:0] output_2_axis_tid, - output wire [DEST_WIDTH-1:0] output_2_axis_tdest, - output wire [USER_WIDTH-1:0] output_2_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_3_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_3_axis_tkeep, - output wire output_3_axis_tvalid, - output wire output_3_axis_tlast, - output wire [ID_WIDTH-1:0] output_3_axis_tid, - output wire [DEST_WIDTH-1:0] output_3_axis_tdest, - output wire [USER_WIDTH-1:0] output_3_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_4_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_4_axis_tkeep, - output wire output_4_axis_tvalid, - output wire output_4_axis_tlast, - output wire [ID_WIDTH-1:0] output_4_axis_tid, - output wire [DEST_WIDTH-1:0] output_4_axis_tdest, - output wire [USER_WIDTH-1:0] output_4_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_5_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_5_axis_tkeep, - output wire output_5_axis_tvalid, - output wire output_5_axis_tlast, - output wire [ID_WIDTH-1:0] output_5_axis_tid, - output wire [DEST_WIDTH-1:0] output_5_axis_tdest, - output wire [USER_WIDTH-1:0] output_5_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_6_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_6_axis_tkeep, - output wire output_6_axis_tvalid, - output wire output_6_axis_tlast, - output wire [ID_WIDTH-1:0] output_6_axis_tid, - output wire [DEST_WIDTH-1:0] output_6_axis_tdest, - output wire [USER_WIDTH-1:0] output_6_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_7_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_7_axis_tkeep, - output wire output_7_axis_tvalid, - output wire output_7_axis_tlast, - output wire [ID_WIDTH-1:0] output_7_axis_tid, - output wire [DEST_WIDTH-1:0] output_7_axis_tdest, - output wire [USER_WIDTH-1:0] output_7_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_8_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_8_axis_tkeep, - output wire output_8_axis_tvalid, - output wire output_8_axis_tlast, - output wire [ID_WIDTH-1:0] output_8_axis_tid, - output wire [DEST_WIDTH-1:0] output_8_axis_tdest, - output wire [USER_WIDTH-1:0] output_8_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_9_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_9_axis_tkeep, - output wire output_9_axis_tvalid, - output wire output_9_axis_tlast, - output wire [ID_WIDTH-1:0] output_9_axis_tid, - output wire [DEST_WIDTH-1:0] output_9_axis_tdest, - output wire [USER_WIDTH-1:0] output_9_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_10_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_10_axis_tkeep, - output wire output_10_axis_tvalid, - output wire output_10_axis_tlast, - output wire [ID_WIDTH-1:0] output_10_axis_tid, - output wire [DEST_WIDTH-1:0] output_10_axis_tdest, - output wire [USER_WIDTH-1:0] output_10_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_11_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_11_axis_tkeep, - output wire output_11_axis_tvalid, - output wire output_11_axis_tlast, - output wire [ID_WIDTH-1:0] output_11_axis_tid, - output wire [DEST_WIDTH-1:0] output_11_axis_tdest, - output wire [USER_WIDTH-1:0] output_11_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_12_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_12_axis_tkeep, - output wire output_12_axis_tvalid, - output wire output_12_axis_tlast, - output wire [ID_WIDTH-1:0] output_12_axis_tid, - output wire [DEST_WIDTH-1:0] output_12_axis_tdest, - output wire [USER_WIDTH-1:0] output_12_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_13_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_13_axis_tkeep, - output wire output_13_axis_tvalid, - output wire output_13_axis_tlast, - output wire [ID_WIDTH-1:0] output_13_axis_tid, - output wire [DEST_WIDTH-1:0] output_13_axis_tdest, - output wire [USER_WIDTH-1:0] output_13_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_14_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_14_axis_tkeep, - output wire output_14_axis_tvalid, - output wire output_14_axis_tlast, - output wire [ID_WIDTH-1:0] output_14_axis_tid, - output wire [DEST_WIDTH-1:0] output_14_axis_tdest, - output wire [USER_WIDTH-1:0] output_14_axis_tuser, - - output wire [DATA_WIDTH-1:0] output_15_axis_tdata, - output wire [KEEP_WIDTH-1:0] output_15_axis_tkeep, - output wire output_15_axis_tvalid, - output wire output_15_axis_tlast, - output wire [ID_WIDTH-1:0] output_15_axis_tid, - output wire [DEST_WIDTH-1:0] output_15_axis_tdest, - output wire [USER_WIDTH-1:0] output_15_axis_tuser, - - /* - * Control - */ - input wire [3:0] output_0_select, - input wire [3:0] output_1_select, - input wire [3:0] output_2_select, - input wire [3:0] output_3_select, - input wire [3:0] output_4_select, - input wire [3:0] output_5_select, - input wire [3:0] output_6_select, - input wire [3:0] output_7_select, - input wire [3:0] output_8_select, - input wire [3:0] output_9_select, - input wire [3:0] output_10_select, - input wire [3:0] output_11_select, - input wire [3:0] output_12_select, - input wire [3:0] output_13_select, - input wire [3:0] output_14_select, - input wire [3:0] output_15_select -); - -reg [DATA_WIDTH-1:0] input_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_0_axis_tvalid_reg = 1'b0; -reg input_0_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_0_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_0_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_1_axis_tvalid_reg = 1'b0; -reg input_1_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_1_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_1_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_2_axis_tvalid_reg = 1'b0; -reg input_2_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_2_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_2_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_3_axis_tvalid_reg = 1'b0; -reg input_3_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_3_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_3_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_4_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_4_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_4_axis_tvalid_reg = 1'b0; -reg input_4_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_4_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_4_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_4_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_5_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_5_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_5_axis_tvalid_reg = 1'b0; -reg input_5_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_5_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_5_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_5_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_6_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_6_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_6_axis_tvalid_reg = 1'b0; -reg input_6_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_6_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_6_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_6_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_7_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_7_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_7_axis_tvalid_reg = 1'b0; -reg input_7_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_7_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_7_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_7_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_8_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_8_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_8_axis_tvalid_reg = 1'b0; -reg input_8_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_8_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_8_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_8_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_9_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_9_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_9_axis_tvalid_reg = 1'b0; -reg input_9_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_9_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_9_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_9_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_10_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_10_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_10_axis_tvalid_reg = 1'b0; -reg input_10_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_10_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_10_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_10_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_11_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_11_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_11_axis_tvalid_reg = 1'b0; -reg input_11_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_11_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_11_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_11_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_12_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_12_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_12_axis_tvalid_reg = 1'b0; -reg input_12_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_12_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_12_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_12_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_13_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_13_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_13_axis_tvalid_reg = 1'b0; -reg input_13_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_13_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_13_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_13_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_14_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_14_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_14_axis_tvalid_reg = 1'b0; -reg input_14_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_14_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_14_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_14_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] input_15_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] input_15_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg input_15_axis_tvalid_reg = 1'b0; -reg input_15_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] input_15_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] input_15_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] input_15_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_0_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_0_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_0_axis_tvalid_reg = 1'b0; -reg output_0_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_0_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_0_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_0_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_1_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_1_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_1_axis_tvalid_reg = 1'b0; -reg output_1_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_1_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_1_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_1_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_2_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_2_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_2_axis_tvalid_reg = 1'b0; -reg output_2_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_2_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_2_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_2_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_3_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_3_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_3_axis_tvalid_reg = 1'b0; -reg output_3_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_3_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_3_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_3_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_4_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_4_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_4_axis_tvalid_reg = 1'b0; -reg output_4_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_4_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_4_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_4_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_5_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_5_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_5_axis_tvalid_reg = 1'b0; -reg output_5_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_5_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_5_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_5_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_6_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_6_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_6_axis_tvalid_reg = 1'b0; -reg output_6_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_6_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_6_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_6_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_7_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_7_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_7_axis_tvalid_reg = 1'b0; -reg output_7_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_7_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_7_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_7_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_8_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_8_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_8_axis_tvalid_reg = 1'b0; -reg output_8_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_8_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_8_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_8_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_9_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_9_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_9_axis_tvalid_reg = 1'b0; -reg output_9_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_9_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_9_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_9_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_10_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_10_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_10_axis_tvalid_reg = 1'b0; -reg output_10_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_10_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_10_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_10_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_11_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_11_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_11_axis_tvalid_reg = 1'b0; -reg output_11_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_11_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_11_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_11_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_12_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_12_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_12_axis_tvalid_reg = 1'b0; -reg output_12_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_12_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_12_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_12_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_13_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_13_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_13_axis_tvalid_reg = 1'b0; -reg output_13_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_13_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_13_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_13_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_14_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_14_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_14_axis_tvalid_reg = 1'b0; -reg output_14_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_14_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_14_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_14_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] output_15_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] output_15_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg output_15_axis_tvalid_reg = 1'b0; -reg output_15_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] output_15_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] output_15_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] output_15_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [3:0] output_0_select_reg = 4'd0; -reg [3:0] output_1_select_reg = 4'd0; -reg [3:0] output_2_select_reg = 4'd0; -reg [3:0] output_3_select_reg = 4'd0; -reg [3:0] output_4_select_reg = 4'd0; -reg [3:0] output_5_select_reg = 4'd0; -reg [3:0] output_6_select_reg = 4'd0; -reg [3:0] output_7_select_reg = 4'd0; -reg [3:0] output_8_select_reg = 4'd0; -reg [3:0] output_9_select_reg = 4'd0; -reg [3:0] output_10_select_reg = 4'd0; -reg [3:0] output_11_select_reg = 4'd0; -reg [3:0] output_12_select_reg = 4'd0; -reg [3:0] output_13_select_reg = 4'd0; -reg [3:0] output_14_select_reg = 4'd0; -reg [3:0] output_15_select_reg = 4'd0; - -assign output_0_axis_tdata = output_0_axis_tdata_reg; -assign output_0_axis_tkeep = KEEP_ENABLE ? output_0_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_0_axis_tvalid = output_0_axis_tvalid_reg; -assign output_0_axis_tlast = LAST_ENABLE ? output_0_axis_tlast_reg : 1'b1; -assign output_0_axis_tid = ID_ENABLE ? output_0_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_0_axis_tdest = DEST_ENABLE ? output_0_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_0_axis_tuser = USER_ENABLE ? output_0_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_1_axis_tdata = output_1_axis_tdata_reg; -assign output_1_axis_tkeep = KEEP_ENABLE ? output_1_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_1_axis_tvalid = output_1_axis_tvalid_reg; -assign output_1_axis_tlast = LAST_ENABLE ? output_1_axis_tlast_reg : 1'b1; -assign output_1_axis_tid = ID_ENABLE ? output_1_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_1_axis_tdest = DEST_ENABLE ? output_1_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_1_axis_tuser = USER_ENABLE ? output_1_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_2_axis_tdata = output_2_axis_tdata_reg; -assign output_2_axis_tkeep = KEEP_ENABLE ? output_2_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_2_axis_tvalid = output_2_axis_tvalid_reg; -assign output_2_axis_tlast = LAST_ENABLE ? output_2_axis_tlast_reg : 1'b1; -assign output_2_axis_tid = ID_ENABLE ? output_2_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_2_axis_tdest = DEST_ENABLE ? output_2_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_2_axis_tuser = USER_ENABLE ? output_2_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_3_axis_tdata = output_3_axis_tdata_reg; -assign output_3_axis_tkeep = KEEP_ENABLE ? output_3_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_3_axis_tvalid = output_3_axis_tvalid_reg; -assign output_3_axis_tlast = LAST_ENABLE ? output_3_axis_tlast_reg : 1'b1; -assign output_3_axis_tid = ID_ENABLE ? output_3_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_3_axis_tdest = DEST_ENABLE ? output_3_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_3_axis_tuser = USER_ENABLE ? output_3_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_4_axis_tdata = output_4_axis_tdata_reg; -assign output_4_axis_tkeep = KEEP_ENABLE ? output_4_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_4_axis_tvalid = output_4_axis_tvalid_reg; -assign output_4_axis_tlast = LAST_ENABLE ? output_4_axis_tlast_reg : 1'b1; -assign output_4_axis_tid = ID_ENABLE ? output_4_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_4_axis_tdest = DEST_ENABLE ? output_4_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_4_axis_tuser = USER_ENABLE ? output_4_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_5_axis_tdata = output_5_axis_tdata_reg; -assign output_5_axis_tkeep = KEEP_ENABLE ? output_5_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_5_axis_tvalid = output_5_axis_tvalid_reg; -assign output_5_axis_tlast = LAST_ENABLE ? output_5_axis_tlast_reg : 1'b1; -assign output_5_axis_tid = ID_ENABLE ? output_5_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_5_axis_tdest = DEST_ENABLE ? output_5_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_5_axis_tuser = USER_ENABLE ? output_5_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_6_axis_tdata = output_6_axis_tdata_reg; -assign output_6_axis_tkeep = KEEP_ENABLE ? output_6_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_6_axis_tvalid = output_6_axis_tvalid_reg; -assign output_6_axis_tlast = LAST_ENABLE ? output_6_axis_tlast_reg : 1'b1; -assign output_6_axis_tid = ID_ENABLE ? output_6_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_6_axis_tdest = DEST_ENABLE ? output_6_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_6_axis_tuser = USER_ENABLE ? output_6_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_7_axis_tdata = output_7_axis_tdata_reg; -assign output_7_axis_tkeep = KEEP_ENABLE ? output_7_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_7_axis_tvalid = output_7_axis_tvalid_reg; -assign output_7_axis_tlast = LAST_ENABLE ? output_7_axis_tlast_reg : 1'b1; -assign output_7_axis_tid = ID_ENABLE ? output_7_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_7_axis_tdest = DEST_ENABLE ? output_7_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_7_axis_tuser = USER_ENABLE ? output_7_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_8_axis_tdata = output_8_axis_tdata_reg; -assign output_8_axis_tkeep = KEEP_ENABLE ? output_8_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_8_axis_tvalid = output_8_axis_tvalid_reg; -assign output_8_axis_tlast = LAST_ENABLE ? output_8_axis_tlast_reg : 1'b1; -assign output_8_axis_tid = ID_ENABLE ? output_8_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_8_axis_tdest = DEST_ENABLE ? output_8_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_8_axis_tuser = USER_ENABLE ? output_8_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_9_axis_tdata = output_9_axis_tdata_reg; -assign output_9_axis_tkeep = KEEP_ENABLE ? output_9_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_9_axis_tvalid = output_9_axis_tvalid_reg; -assign output_9_axis_tlast = LAST_ENABLE ? output_9_axis_tlast_reg : 1'b1; -assign output_9_axis_tid = ID_ENABLE ? output_9_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_9_axis_tdest = DEST_ENABLE ? output_9_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_9_axis_tuser = USER_ENABLE ? output_9_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_10_axis_tdata = output_10_axis_tdata_reg; -assign output_10_axis_tkeep = KEEP_ENABLE ? output_10_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_10_axis_tvalid = output_10_axis_tvalid_reg; -assign output_10_axis_tlast = LAST_ENABLE ? output_10_axis_tlast_reg : 1'b1; -assign output_10_axis_tid = ID_ENABLE ? output_10_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_10_axis_tdest = DEST_ENABLE ? output_10_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_10_axis_tuser = USER_ENABLE ? output_10_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_11_axis_tdata = output_11_axis_tdata_reg; -assign output_11_axis_tkeep = KEEP_ENABLE ? output_11_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_11_axis_tvalid = output_11_axis_tvalid_reg; -assign output_11_axis_tlast = LAST_ENABLE ? output_11_axis_tlast_reg : 1'b1; -assign output_11_axis_tid = ID_ENABLE ? output_11_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_11_axis_tdest = DEST_ENABLE ? output_11_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_11_axis_tuser = USER_ENABLE ? output_11_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_12_axis_tdata = output_12_axis_tdata_reg; -assign output_12_axis_tkeep = KEEP_ENABLE ? output_12_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_12_axis_tvalid = output_12_axis_tvalid_reg; -assign output_12_axis_tlast = LAST_ENABLE ? output_12_axis_tlast_reg : 1'b1; -assign output_12_axis_tid = ID_ENABLE ? output_12_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_12_axis_tdest = DEST_ENABLE ? output_12_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_12_axis_tuser = USER_ENABLE ? output_12_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_13_axis_tdata = output_13_axis_tdata_reg; -assign output_13_axis_tkeep = KEEP_ENABLE ? output_13_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_13_axis_tvalid = output_13_axis_tvalid_reg; -assign output_13_axis_tlast = LAST_ENABLE ? output_13_axis_tlast_reg : 1'b1; -assign output_13_axis_tid = ID_ENABLE ? output_13_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_13_axis_tdest = DEST_ENABLE ? output_13_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_13_axis_tuser = USER_ENABLE ? output_13_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_14_axis_tdata = output_14_axis_tdata_reg; -assign output_14_axis_tkeep = KEEP_ENABLE ? output_14_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_14_axis_tvalid = output_14_axis_tvalid_reg; -assign output_14_axis_tlast = LAST_ENABLE ? output_14_axis_tlast_reg : 1'b1; -assign output_14_axis_tid = ID_ENABLE ? output_14_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_14_axis_tdest = DEST_ENABLE ? output_14_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_14_axis_tuser = USER_ENABLE ? output_14_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -assign output_15_axis_tdata = output_15_axis_tdata_reg; -assign output_15_axis_tkeep = KEEP_ENABLE ? output_15_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign output_15_axis_tvalid = output_15_axis_tvalid_reg; -assign output_15_axis_tlast = LAST_ENABLE ? output_15_axis_tlast_reg : 1'b1; -assign output_15_axis_tid = ID_ENABLE ? output_15_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign output_15_axis_tdest = DEST_ENABLE ? output_15_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign output_15_axis_tuser = USER_ENABLE ? output_15_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -always @(posedge clk) begin - if (rst) begin - output_0_select_reg <= 4'd0; - output_1_select_reg <= 4'd0; - output_2_select_reg <= 4'd0; - output_3_select_reg <= 4'd0; - output_4_select_reg <= 4'd0; - output_5_select_reg <= 4'd0; - output_6_select_reg <= 4'd0; - output_7_select_reg <= 4'd0; - output_8_select_reg <= 4'd0; - output_9_select_reg <= 4'd0; - output_10_select_reg <= 4'd0; - output_11_select_reg <= 4'd0; - output_12_select_reg <= 4'd0; - output_13_select_reg <= 4'd0; - output_14_select_reg <= 4'd0; - output_15_select_reg <= 4'd0; - - input_0_axis_tvalid_reg <= 1'b0; - input_1_axis_tvalid_reg <= 1'b0; - input_2_axis_tvalid_reg <= 1'b0; - input_3_axis_tvalid_reg <= 1'b0; - input_4_axis_tvalid_reg <= 1'b0; - input_5_axis_tvalid_reg <= 1'b0; - input_6_axis_tvalid_reg <= 1'b0; - input_7_axis_tvalid_reg <= 1'b0; - input_8_axis_tvalid_reg <= 1'b0; - input_9_axis_tvalid_reg <= 1'b0; - input_10_axis_tvalid_reg <= 1'b0; - input_11_axis_tvalid_reg <= 1'b0; - input_12_axis_tvalid_reg <= 1'b0; - input_13_axis_tvalid_reg <= 1'b0; - input_14_axis_tvalid_reg <= 1'b0; - input_15_axis_tvalid_reg <= 1'b0; - - output_0_axis_tvalid_reg <= 1'b0; - output_1_axis_tvalid_reg <= 1'b0; - output_2_axis_tvalid_reg <= 1'b0; - output_3_axis_tvalid_reg <= 1'b0; - output_4_axis_tvalid_reg <= 1'b0; - output_5_axis_tvalid_reg <= 1'b0; - output_6_axis_tvalid_reg <= 1'b0; - output_7_axis_tvalid_reg <= 1'b0; - output_8_axis_tvalid_reg <= 1'b0; - output_9_axis_tvalid_reg <= 1'b0; - output_10_axis_tvalid_reg <= 1'b0; - output_11_axis_tvalid_reg <= 1'b0; - output_12_axis_tvalid_reg <= 1'b0; - output_13_axis_tvalid_reg <= 1'b0; - output_14_axis_tvalid_reg <= 1'b0; - output_15_axis_tvalid_reg <= 1'b0; - end else begin - input_0_axis_tvalid_reg <= input_0_axis_tvalid; - input_1_axis_tvalid_reg <= input_1_axis_tvalid; - input_2_axis_tvalid_reg <= input_2_axis_tvalid; - input_3_axis_tvalid_reg <= input_3_axis_tvalid; - input_4_axis_tvalid_reg <= input_4_axis_tvalid; - input_5_axis_tvalid_reg <= input_5_axis_tvalid; - input_6_axis_tvalid_reg <= input_6_axis_tvalid; - input_7_axis_tvalid_reg <= input_7_axis_tvalid; - input_8_axis_tvalid_reg <= input_8_axis_tvalid; - input_9_axis_tvalid_reg <= input_9_axis_tvalid; - input_10_axis_tvalid_reg <= input_10_axis_tvalid; - input_11_axis_tvalid_reg <= input_11_axis_tvalid; - input_12_axis_tvalid_reg <= input_12_axis_tvalid; - input_13_axis_tvalid_reg <= input_13_axis_tvalid; - input_14_axis_tvalid_reg <= input_14_axis_tvalid; - input_15_axis_tvalid_reg <= input_15_axis_tvalid; - - output_0_select_reg <= output_0_select; - output_1_select_reg <= output_1_select; - output_2_select_reg <= output_2_select; - output_3_select_reg <= output_3_select; - output_4_select_reg <= output_4_select; - output_5_select_reg <= output_5_select; - output_6_select_reg <= output_6_select; - output_7_select_reg <= output_7_select; - output_8_select_reg <= output_8_select; - output_9_select_reg <= output_9_select; - output_10_select_reg <= output_10_select; - output_11_select_reg <= output_11_select; - output_12_select_reg <= output_12_select; - output_13_select_reg <= output_13_select; - output_14_select_reg <= output_14_select; - output_15_select_reg <= output_15_select; - - case (output_0_select_reg) - 4'd0: output_0_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_0_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_0_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_0_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_0_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_0_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_0_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_0_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_0_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_0_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_0_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_0_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_0_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_0_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_0_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_0_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_1_select_reg) - 4'd0: output_1_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_1_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_1_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_1_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_1_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_1_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_1_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_1_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_1_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_1_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_1_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_1_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_1_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_1_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_1_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_1_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_2_select_reg) - 4'd0: output_2_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_2_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_2_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_2_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_2_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_2_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_2_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_2_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_2_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_2_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_2_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_2_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_2_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_2_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_2_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_2_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_3_select_reg) - 4'd0: output_3_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_3_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_3_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_3_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_3_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_3_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_3_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_3_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_3_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_3_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_3_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_3_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_3_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_3_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_3_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_3_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_4_select_reg) - 4'd0: output_4_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_4_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_4_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_4_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_4_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_4_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_4_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_4_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_4_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_4_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_4_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_4_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_4_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_4_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_4_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_4_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_5_select_reg) - 4'd0: output_5_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_5_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_5_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_5_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_5_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_5_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_5_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_5_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_5_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_5_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_5_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_5_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_5_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_5_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_5_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_5_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_6_select_reg) - 4'd0: output_6_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_6_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_6_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_6_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_6_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_6_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_6_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_6_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_6_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_6_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_6_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_6_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_6_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_6_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_6_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_6_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_7_select_reg) - 4'd0: output_7_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_7_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_7_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_7_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_7_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_7_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_7_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_7_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_7_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_7_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_7_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_7_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_7_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_7_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_7_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_7_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_8_select_reg) - 4'd0: output_8_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_8_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_8_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_8_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_8_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_8_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_8_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_8_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_8_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_8_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_8_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_8_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_8_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_8_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_8_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_8_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_9_select_reg) - 4'd0: output_9_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_9_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_9_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_9_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_9_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_9_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_9_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_9_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_9_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_9_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_9_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_9_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_9_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_9_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_9_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_9_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_10_select_reg) - 4'd0: output_10_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_10_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_10_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_10_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_10_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_10_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_10_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_10_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_10_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_10_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_10_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_10_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_10_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_10_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_10_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_10_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_11_select_reg) - 4'd0: output_11_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_11_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_11_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_11_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_11_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_11_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_11_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_11_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_11_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_11_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_11_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_11_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_11_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_11_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_11_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_11_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_12_select_reg) - 4'd0: output_12_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_12_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_12_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_12_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_12_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_12_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_12_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_12_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_12_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_12_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_12_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_12_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_12_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_12_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_12_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_12_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_13_select_reg) - 4'd0: output_13_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_13_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_13_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_13_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_13_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_13_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_13_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_13_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_13_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_13_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_13_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_13_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_13_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_13_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_13_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_13_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_14_select_reg) - 4'd0: output_14_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_14_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_14_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_14_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_14_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_14_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_14_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_14_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_14_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_14_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_14_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_14_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_14_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_14_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_14_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_14_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - - case (output_15_select_reg) - 4'd0: output_15_axis_tvalid_reg <= input_0_axis_tvalid_reg; - 4'd1: output_15_axis_tvalid_reg <= input_1_axis_tvalid_reg; - 4'd2: output_15_axis_tvalid_reg <= input_2_axis_tvalid_reg; - 4'd3: output_15_axis_tvalid_reg <= input_3_axis_tvalid_reg; - 4'd4: output_15_axis_tvalid_reg <= input_4_axis_tvalid_reg; - 4'd5: output_15_axis_tvalid_reg <= input_5_axis_tvalid_reg; - 4'd6: output_15_axis_tvalid_reg <= input_6_axis_tvalid_reg; - 4'd7: output_15_axis_tvalid_reg <= input_7_axis_tvalid_reg; - 4'd8: output_15_axis_tvalid_reg <= input_8_axis_tvalid_reg; - 4'd9: output_15_axis_tvalid_reg <= input_9_axis_tvalid_reg; - 4'd10: output_15_axis_tvalid_reg <= input_10_axis_tvalid_reg; - 4'd11: output_15_axis_tvalid_reg <= input_11_axis_tvalid_reg; - 4'd12: output_15_axis_tvalid_reg <= input_12_axis_tvalid_reg; - 4'd13: output_15_axis_tvalid_reg <= input_13_axis_tvalid_reg; - 4'd14: output_15_axis_tvalid_reg <= input_14_axis_tvalid_reg; - 4'd15: output_15_axis_tvalid_reg <= input_15_axis_tvalid_reg; - endcase - end - - input_0_axis_tdata_reg <= input_0_axis_tdata; - input_0_axis_tkeep_reg <= input_0_axis_tkeep; - input_0_axis_tlast_reg <= input_0_axis_tlast; - input_0_axis_tid_reg <= input_0_axis_tid; - input_0_axis_tdest_reg <= input_0_axis_tdest; - input_0_axis_tuser_reg <= input_0_axis_tuser; - - input_1_axis_tdata_reg <= input_1_axis_tdata; - input_1_axis_tkeep_reg <= input_1_axis_tkeep; - input_1_axis_tlast_reg <= input_1_axis_tlast; - input_1_axis_tid_reg <= input_1_axis_tid; - input_1_axis_tdest_reg <= input_1_axis_tdest; - input_1_axis_tuser_reg <= input_1_axis_tuser; - - input_2_axis_tdata_reg <= input_2_axis_tdata; - input_2_axis_tkeep_reg <= input_2_axis_tkeep; - input_2_axis_tlast_reg <= input_2_axis_tlast; - input_2_axis_tid_reg <= input_2_axis_tid; - input_2_axis_tdest_reg <= input_2_axis_tdest; - input_2_axis_tuser_reg <= input_2_axis_tuser; - - input_3_axis_tdata_reg <= input_3_axis_tdata; - input_3_axis_tkeep_reg <= input_3_axis_tkeep; - input_3_axis_tlast_reg <= input_3_axis_tlast; - input_3_axis_tid_reg <= input_3_axis_tid; - input_3_axis_tdest_reg <= input_3_axis_tdest; - input_3_axis_tuser_reg <= input_3_axis_tuser; - - input_4_axis_tdata_reg <= input_4_axis_tdata; - input_4_axis_tkeep_reg <= input_4_axis_tkeep; - input_4_axis_tlast_reg <= input_4_axis_tlast; - input_4_axis_tid_reg <= input_4_axis_tid; - input_4_axis_tdest_reg <= input_4_axis_tdest; - input_4_axis_tuser_reg <= input_4_axis_tuser; - - input_5_axis_tdata_reg <= input_5_axis_tdata; - input_5_axis_tkeep_reg <= input_5_axis_tkeep; - input_5_axis_tlast_reg <= input_5_axis_tlast; - input_5_axis_tid_reg <= input_5_axis_tid; - input_5_axis_tdest_reg <= input_5_axis_tdest; - input_5_axis_tuser_reg <= input_5_axis_tuser; - - input_6_axis_tdata_reg <= input_6_axis_tdata; - input_6_axis_tkeep_reg <= input_6_axis_tkeep; - input_6_axis_tlast_reg <= input_6_axis_tlast; - input_6_axis_tid_reg <= input_6_axis_tid; - input_6_axis_tdest_reg <= input_6_axis_tdest; - input_6_axis_tuser_reg <= input_6_axis_tuser; - - input_7_axis_tdata_reg <= input_7_axis_tdata; - input_7_axis_tkeep_reg <= input_7_axis_tkeep; - input_7_axis_tlast_reg <= input_7_axis_tlast; - input_7_axis_tid_reg <= input_7_axis_tid; - input_7_axis_tdest_reg <= input_7_axis_tdest; - input_7_axis_tuser_reg <= input_7_axis_tuser; - - input_8_axis_tdata_reg <= input_8_axis_tdata; - input_8_axis_tkeep_reg <= input_8_axis_tkeep; - input_8_axis_tlast_reg <= input_8_axis_tlast; - input_8_axis_tid_reg <= input_8_axis_tid; - input_8_axis_tdest_reg <= input_8_axis_tdest; - input_8_axis_tuser_reg <= input_8_axis_tuser; - - input_9_axis_tdata_reg <= input_9_axis_tdata; - input_9_axis_tkeep_reg <= input_9_axis_tkeep; - input_9_axis_tlast_reg <= input_9_axis_tlast; - input_9_axis_tid_reg <= input_9_axis_tid; - input_9_axis_tdest_reg <= input_9_axis_tdest; - input_9_axis_tuser_reg <= input_9_axis_tuser; - - input_10_axis_tdata_reg <= input_10_axis_tdata; - input_10_axis_tkeep_reg <= input_10_axis_tkeep; - input_10_axis_tlast_reg <= input_10_axis_tlast; - input_10_axis_tid_reg <= input_10_axis_tid; - input_10_axis_tdest_reg <= input_10_axis_tdest; - input_10_axis_tuser_reg <= input_10_axis_tuser; - - input_11_axis_tdata_reg <= input_11_axis_tdata; - input_11_axis_tkeep_reg <= input_11_axis_tkeep; - input_11_axis_tlast_reg <= input_11_axis_tlast; - input_11_axis_tid_reg <= input_11_axis_tid; - input_11_axis_tdest_reg <= input_11_axis_tdest; - input_11_axis_tuser_reg <= input_11_axis_tuser; - - input_12_axis_tdata_reg <= input_12_axis_tdata; - input_12_axis_tkeep_reg <= input_12_axis_tkeep; - input_12_axis_tlast_reg <= input_12_axis_tlast; - input_12_axis_tid_reg <= input_12_axis_tid; - input_12_axis_tdest_reg <= input_12_axis_tdest; - input_12_axis_tuser_reg <= input_12_axis_tuser; - - input_13_axis_tdata_reg <= input_13_axis_tdata; - input_13_axis_tkeep_reg <= input_13_axis_tkeep; - input_13_axis_tlast_reg <= input_13_axis_tlast; - input_13_axis_tid_reg <= input_13_axis_tid; - input_13_axis_tdest_reg <= input_13_axis_tdest; - input_13_axis_tuser_reg <= input_13_axis_tuser; - - input_14_axis_tdata_reg <= input_14_axis_tdata; - input_14_axis_tkeep_reg <= input_14_axis_tkeep; - input_14_axis_tlast_reg <= input_14_axis_tlast; - input_14_axis_tid_reg <= input_14_axis_tid; - input_14_axis_tdest_reg <= input_14_axis_tdest; - input_14_axis_tuser_reg <= input_14_axis_tuser; - - input_15_axis_tdata_reg <= input_15_axis_tdata; - input_15_axis_tkeep_reg <= input_15_axis_tkeep; - input_15_axis_tlast_reg <= input_15_axis_tlast; - input_15_axis_tid_reg <= input_15_axis_tid; - input_15_axis_tdest_reg <= input_15_axis_tdest; - input_15_axis_tuser_reg <= input_15_axis_tuser; - - case (output_0_select_reg) - 4'd0: begin - output_0_axis_tdata_reg <= input_0_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_0_axis_tlast_reg; - output_0_axis_tid_reg <= input_0_axis_tid_reg; - output_0_axis_tdest_reg <= input_0_axis_tdest_reg; - output_0_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_0_axis_tdata_reg <= input_1_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_1_axis_tlast_reg; - output_0_axis_tid_reg <= input_1_axis_tid_reg; - output_0_axis_tdest_reg <= input_1_axis_tdest_reg; - output_0_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_0_axis_tdata_reg <= input_2_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_2_axis_tlast_reg; - output_0_axis_tid_reg <= input_2_axis_tid_reg; - output_0_axis_tdest_reg <= input_2_axis_tdest_reg; - output_0_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_0_axis_tdata_reg <= input_3_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_3_axis_tlast_reg; - output_0_axis_tid_reg <= input_3_axis_tid_reg; - output_0_axis_tdest_reg <= input_3_axis_tdest_reg; - output_0_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_0_axis_tdata_reg <= input_4_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_4_axis_tlast_reg; - output_0_axis_tid_reg <= input_4_axis_tid_reg; - output_0_axis_tdest_reg <= input_4_axis_tdest_reg; - output_0_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_0_axis_tdata_reg <= input_5_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_5_axis_tlast_reg; - output_0_axis_tid_reg <= input_5_axis_tid_reg; - output_0_axis_tdest_reg <= input_5_axis_tdest_reg; - output_0_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_0_axis_tdata_reg <= input_6_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_6_axis_tlast_reg; - output_0_axis_tid_reg <= input_6_axis_tid_reg; - output_0_axis_tdest_reg <= input_6_axis_tdest_reg; - output_0_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_0_axis_tdata_reg <= input_7_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_7_axis_tlast_reg; - output_0_axis_tid_reg <= input_7_axis_tid_reg; - output_0_axis_tdest_reg <= input_7_axis_tdest_reg; - output_0_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_0_axis_tdata_reg <= input_8_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_8_axis_tlast_reg; - output_0_axis_tid_reg <= input_8_axis_tid_reg; - output_0_axis_tdest_reg <= input_8_axis_tdest_reg; - output_0_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_0_axis_tdata_reg <= input_9_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_9_axis_tlast_reg; - output_0_axis_tid_reg <= input_9_axis_tid_reg; - output_0_axis_tdest_reg <= input_9_axis_tdest_reg; - output_0_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_0_axis_tdata_reg <= input_10_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_10_axis_tlast_reg; - output_0_axis_tid_reg <= input_10_axis_tid_reg; - output_0_axis_tdest_reg <= input_10_axis_tdest_reg; - output_0_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_0_axis_tdata_reg <= input_11_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_11_axis_tlast_reg; - output_0_axis_tid_reg <= input_11_axis_tid_reg; - output_0_axis_tdest_reg <= input_11_axis_tdest_reg; - output_0_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_0_axis_tdata_reg <= input_12_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_12_axis_tlast_reg; - output_0_axis_tid_reg <= input_12_axis_tid_reg; - output_0_axis_tdest_reg <= input_12_axis_tdest_reg; - output_0_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_0_axis_tdata_reg <= input_13_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_13_axis_tlast_reg; - output_0_axis_tid_reg <= input_13_axis_tid_reg; - output_0_axis_tdest_reg <= input_13_axis_tdest_reg; - output_0_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_0_axis_tdata_reg <= input_14_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_14_axis_tlast_reg; - output_0_axis_tid_reg <= input_14_axis_tid_reg; - output_0_axis_tdest_reg <= input_14_axis_tdest_reg; - output_0_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_0_axis_tdata_reg <= input_15_axis_tdata_reg; - output_0_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_0_axis_tlast_reg <= input_15_axis_tlast_reg; - output_0_axis_tid_reg <= input_15_axis_tid_reg; - output_0_axis_tdest_reg <= input_15_axis_tdest_reg; - output_0_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_1_select_reg) - 4'd0: begin - output_1_axis_tdata_reg <= input_0_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_0_axis_tlast_reg; - output_1_axis_tid_reg <= input_0_axis_tid_reg; - output_1_axis_tdest_reg <= input_0_axis_tdest_reg; - output_1_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_1_axis_tdata_reg <= input_1_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_1_axis_tlast_reg; - output_1_axis_tid_reg <= input_1_axis_tid_reg; - output_1_axis_tdest_reg <= input_1_axis_tdest_reg; - output_1_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_1_axis_tdata_reg <= input_2_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_2_axis_tlast_reg; - output_1_axis_tid_reg <= input_2_axis_tid_reg; - output_1_axis_tdest_reg <= input_2_axis_tdest_reg; - output_1_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_1_axis_tdata_reg <= input_3_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_3_axis_tlast_reg; - output_1_axis_tid_reg <= input_3_axis_tid_reg; - output_1_axis_tdest_reg <= input_3_axis_tdest_reg; - output_1_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_1_axis_tdata_reg <= input_4_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_4_axis_tlast_reg; - output_1_axis_tid_reg <= input_4_axis_tid_reg; - output_1_axis_tdest_reg <= input_4_axis_tdest_reg; - output_1_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_1_axis_tdata_reg <= input_5_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_5_axis_tlast_reg; - output_1_axis_tid_reg <= input_5_axis_tid_reg; - output_1_axis_tdest_reg <= input_5_axis_tdest_reg; - output_1_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_1_axis_tdata_reg <= input_6_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_6_axis_tlast_reg; - output_1_axis_tid_reg <= input_6_axis_tid_reg; - output_1_axis_tdest_reg <= input_6_axis_tdest_reg; - output_1_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_1_axis_tdata_reg <= input_7_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_7_axis_tlast_reg; - output_1_axis_tid_reg <= input_7_axis_tid_reg; - output_1_axis_tdest_reg <= input_7_axis_tdest_reg; - output_1_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_1_axis_tdata_reg <= input_8_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_8_axis_tlast_reg; - output_1_axis_tid_reg <= input_8_axis_tid_reg; - output_1_axis_tdest_reg <= input_8_axis_tdest_reg; - output_1_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_1_axis_tdata_reg <= input_9_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_9_axis_tlast_reg; - output_1_axis_tid_reg <= input_9_axis_tid_reg; - output_1_axis_tdest_reg <= input_9_axis_tdest_reg; - output_1_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_1_axis_tdata_reg <= input_10_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_10_axis_tlast_reg; - output_1_axis_tid_reg <= input_10_axis_tid_reg; - output_1_axis_tdest_reg <= input_10_axis_tdest_reg; - output_1_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_1_axis_tdata_reg <= input_11_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_11_axis_tlast_reg; - output_1_axis_tid_reg <= input_11_axis_tid_reg; - output_1_axis_tdest_reg <= input_11_axis_tdest_reg; - output_1_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_1_axis_tdata_reg <= input_12_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_12_axis_tlast_reg; - output_1_axis_tid_reg <= input_12_axis_tid_reg; - output_1_axis_tdest_reg <= input_12_axis_tdest_reg; - output_1_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_1_axis_tdata_reg <= input_13_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_13_axis_tlast_reg; - output_1_axis_tid_reg <= input_13_axis_tid_reg; - output_1_axis_tdest_reg <= input_13_axis_tdest_reg; - output_1_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_1_axis_tdata_reg <= input_14_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_14_axis_tlast_reg; - output_1_axis_tid_reg <= input_14_axis_tid_reg; - output_1_axis_tdest_reg <= input_14_axis_tdest_reg; - output_1_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_1_axis_tdata_reg <= input_15_axis_tdata_reg; - output_1_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_1_axis_tlast_reg <= input_15_axis_tlast_reg; - output_1_axis_tid_reg <= input_15_axis_tid_reg; - output_1_axis_tdest_reg <= input_15_axis_tdest_reg; - output_1_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_2_select_reg) - 4'd0: begin - output_2_axis_tdata_reg <= input_0_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_0_axis_tlast_reg; - output_2_axis_tid_reg <= input_0_axis_tid_reg; - output_2_axis_tdest_reg <= input_0_axis_tdest_reg; - output_2_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_2_axis_tdata_reg <= input_1_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_1_axis_tlast_reg; - output_2_axis_tid_reg <= input_1_axis_tid_reg; - output_2_axis_tdest_reg <= input_1_axis_tdest_reg; - output_2_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_2_axis_tdata_reg <= input_2_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_2_axis_tlast_reg; - output_2_axis_tid_reg <= input_2_axis_tid_reg; - output_2_axis_tdest_reg <= input_2_axis_tdest_reg; - output_2_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_2_axis_tdata_reg <= input_3_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_3_axis_tlast_reg; - output_2_axis_tid_reg <= input_3_axis_tid_reg; - output_2_axis_tdest_reg <= input_3_axis_tdest_reg; - output_2_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_2_axis_tdata_reg <= input_4_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_4_axis_tlast_reg; - output_2_axis_tid_reg <= input_4_axis_tid_reg; - output_2_axis_tdest_reg <= input_4_axis_tdest_reg; - output_2_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_2_axis_tdata_reg <= input_5_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_5_axis_tlast_reg; - output_2_axis_tid_reg <= input_5_axis_tid_reg; - output_2_axis_tdest_reg <= input_5_axis_tdest_reg; - output_2_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_2_axis_tdata_reg <= input_6_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_6_axis_tlast_reg; - output_2_axis_tid_reg <= input_6_axis_tid_reg; - output_2_axis_tdest_reg <= input_6_axis_tdest_reg; - output_2_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_2_axis_tdata_reg <= input_7_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_7_axis_tlast_reg; - output_2_axis_tid_reg <= input_7_axis_tid_reg; - output_2_axis_tdest_reg <= input_7_axis_tdest_reg; - output_2_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_2_axis_tdata_reg <= input_8_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_8_axis_tlast_reg; - output_2_axis_tid_reg <= input_8_axis_tid_reg; - output_2_axis_tdest_reg <= input_8_axis_tdest_reg; - output_2_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_2_axis_tdata_reg <= input_9_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_9_axis_tlast_reg; - output_2_axis_tid_reg <= input_9_axis_tid_reg; - output_2_axis_tdest_reg <= input_9_axis_tdest_reg; - output_2_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_2_axis_tdata_reg <= input_10_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_10_axis_tlast_reg; - output_2_axis_tid_reg <= input_10_axis_tid_reg; - output_2_axis_tdest_reg <= input_10_axis_tdest_reg; - output_2_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_2_axis_tdata_reg <= input_11_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_11_axis_tlast_reg; - output_2_axis_tid_reg <= input_11_axis_tid_reg; - output_2_axis_tdest_reg <= input_11_axis_tdest_reg; - output_2_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_2_axis_tdata_reg <= input_12_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_12_axis_tlast_reg; - output_2_axis_tid_reg <= input_12_axis_tid_reg; - output_2_axis_tdest_reg <= input_12_axis_tdest_reg; - output_2_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_2_axis_tdata_reg <= input_13_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_13_axis_tlast_reg; - output_2_axis_tid_reg <= input_13_axis_tid_reg; - output_2_axis_tdest_reg <= input_13_axis_tdest_reg; - output_2_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_2_axis_tdata_reg <= input_14_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_14_axis_tlast_reg; - output_2_axis_tid_reg <= input_14_axis_tid_reg; - output_2_axis_tdest_reg <= input_14_axis_tdest_reg; - output_2_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_2_axis_tdata_reg <= input_15_axis_tdata_reg; - output_2_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_2_axis_tlast_reg <= input_15_axis_tlast_reg; - output_2_axis_tid_reg <= input_15_axis_tid_reg; - output_2_axis_tdest_reg <= input_15_axis_tdest_reg; - output_2_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_3_select_reg) - 4'd0: begin - output_3_axis_tdata_reg <= input_0_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_0_axis_tlast_reg; - output_3_axis_tid_reg <= input_0_axis_tid_reg; - output_3_axis_tdest_reg <= input_0_axis_tdest_reg; - output_3_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_3_axis_tdata_reg <= input_1_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_1_axis_tlast_reg; - output_3_axis_tid_reg <= input_1_axis_tid_reg; - output_3_axis_tdest_reg <= input_1_axis_tdest_reg; - output_3_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_3_axis_tdata_reg <= input_2_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_2_axis_tlast_reg; - output_3_axis_tid_reg <= input_2_axis_tid_reg; - output_3_axis_tdest_reg <= input_2_axis_tdest_reg; - output_3_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_3_axis_tdata_reg <= input_3_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_3_axis_tlast_reg; - output_3_axis_tid_reg <= input_3_axis_tid_reg; - output_3_axis_tdest_reg <= input_3_axis_tdest_reg; - output_3_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_3_axis_tdata_reg <= input_4_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_4_axis_tlast_reg; - output_3_axis_tid_reg <= input_4_axis_tid_reg; - output_3_axis_tdest_reg <= input_4_axis_tdest_reg; - output_3_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_3_axis_tdata_reg <= input_5_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_5_axis_tlast_reg; - output_3_axis_tid_reg <= input_5_axis_tid_reg; - output_3_axis_tdest_reg <= input_5_axis_tdest_reg; - output_3_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_3_axis_tdata_reg <= input_6_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_6_axis_tlast_reg; - output_3_axis_tid_reg <= input_6_axis_tid_reg; - output_3_axis_tdest_reg <= input_6_axis_tdest_reg; - output_3_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_3_axis_tdata_reg <= input_7_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_7_axis_tlast_reg; - output_3_axis_tid_reg <= input_7_axis_tid_reg; - output_3_axis_tdest_reg <= input_7_axis_tdest_reg; - output_3_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_3_axis_tdata_reg <= input_8_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_8_axis_tlast_reg; - output_3_axis_tid_reg <= input_8_axis_tid_reg; - output_3_axis_tdest_reg <= input_8_axis_tdest_reg; - output_3_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_3_axis_tdata_reg <= input_9_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_9_axis_tlast_reg; - output_3_axis_tid_reg <= input_9_axis_tid_reg; - output_3_axis_tdest_reg <= input_9_axis_tdest_reg; - output_3_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_3_axis_tdata_reg <= input_10_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_10_axis_tlast_reg; - output_3_axis_tid_reg <= input_10_axis_tid_reg; - output_3_axis_tdest_reg <= input_10_axis_tdest_reg; - output_3_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_3_axis_tdata_reg <= input_11_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_11_axis_tlast_reg; - output_3_axis_tid_reg <= input_11_axis_tid_reg; - output_3_axis_tdest_reg <= input_11_axis_tdest_reg; - output_3_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_3_axis_tdata_reg <= input_12_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_12_axis_tlast_reg; - output_3_axis_tid_reg <= input_12_axis_tid_reg; - output_3_axis_tdest_reg <= input_12_axis_tdest_reg; - output_3_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_3_axis_tdata_reg <= input_13_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_13_axis_tlast_reg; - output_3_axis_tid_reg <= input_13_axis_tid_reg; - output_3_axis_tdest_reg <= input_13_axis_tdest_reg; - output_3_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_3_axis_tdata_reg <= input_14_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_14_axis_tlast_reg; - output_3_axis_tid_reg <= input_14_axis_tid_reg; - output_3_axis_tdest_reg <= input_14_axis_tdest_reg; - output_3_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_3_axis_tdata_reg <= input_15_axis_tdata_reg; - output_3_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_3_axis_tlast_reg <= input_15_axis_tlast_reg; - output_3_axis_tid_reg <= input_15_axis_tid_reg; - output_3_axis_tdest_reg <= input_15_axis_tdest_reg; - output_3_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_4_select_reg) - 4'd0: begin - output_4_axis_tdata_reg <= input_0_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_0_axis_tlast_reg; - output_4_axis_tid_reg <= input_0_axis_tid_reg; - output_4_axis_tdest_reg <= input_0_axis_tdest_reg; - output_4_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_4_axis_tdata_reg <= input_1_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_1_axis_tlast_reg; - output_4_axis_tid_reg <= input_1_axis_tid_reg; - output_4_axis_tdest_reg <= input_1_axis_tdest_reg; - output_4_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_4_axis_tdata_reg <= input_2_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_2_axis_tlast_reg; - output_4_axis_tid_reg <= input_2_axis_tid_reg; - output_4_axis_tdest_reg <= input_2_axis_tdest_reg; - output_4_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_4_axis_tdata_reg <= input_3_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_3_axis_tlast_reg; - output_4_axis_tid_reg <= input_3_axis_tid_reg; - output_4_axis_tdest_reg <= input_3_axis_tdest_reg; - output_4_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_4_axis_tdata_reg <= input_4_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_4_axis_tlast_reg; - output_4_axis_tid_reg <= input_4_axis_tid_reg; - output_4_axis_tdest_reg <= input_4_axis_tdest_reg; - output_4_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_4_axis_tdata_reg <= input_5_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_5_axis_tlast_reg; - output_4_axis_tid_reg <= input_5_axis_tid_reg; - output_4_axis_tdest_reg <= input_5_axis_tdest_reg; - output_4_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_4_axis_tdata_reg <= input_6_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_6_axis_tlast_reg; - output_4_axis_tid_reg <= input_6_axis_tid_reg; - output_4_axis_tdest_reg <= input_6_axis_tdest_reg; - output_4_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_4_axis_tdata_reg <= input_7_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_7_axis_tlast_reg; - output_4_axis_tid_reg <= input_7_axis_tid_reg; - output_4_axis_tdest_reg <= input_7_axis_tdest_reg; - output_4_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_4_axis_tdata_reg <= input_8_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_8_axis_tlast_reg; - output_4_axis_tid_reg <= input_8_axis_tid_reg; - output_4_axis_tdest_reg <= input_8_axis_tdest_reg; - output_4_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_4_axis_tdata_reg <= input_9_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_9_axis_tlast_reg; - output_4_axis_tid_reg <= input_9_axis_tid_reg; - output_4_axis_tdest_reg <= input_9_axis_tdest_reg; - output_4_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_4_axis_tdata_reg <= input_10_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_10_axis_tlast_reg; - output_4_axis_tid_reg <= input_10_axis_tid_reg; - output_4_axis_tdest_reg <= input_10_axis_tdest_reg; - output_4_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_4_axis_tdata_reg <= input_11_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_11_axis_tlast_reg; - output_4_axis_tid_reg <= input_11_axis_tid_reg; - output_4_axis_tdest_reg <= input_11_axis_tdest_reg; - output_4_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_4_axis_tdata_reg <= input_12_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_12_axis_tlast_reg; - output_4_axis_tid_reg <= input_12_axis_tid_reg; - output_4_axis_tdest_reg <= input_12_axis_tdest_reg; - output_4_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_4_axis_tdata_reg <= input_13_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_13_axis_tlast_reg; - output_4_axis_tid_reg <= input_13_axis_tid_reg; - output_4_axis_tdest_reg <= input_13_axis_tdest_reg; - output_4_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_4_axis_tdata_reg <= input_14_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_14_axis_tlast_reg; - output_4_axis_tid_reg <= input_14_axis_tid_reg; - output_4_axis_tdest_reg <= input_14_axis_tdest_reg; - output_4_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_4_axis_tdata_reg <= input_15_axis_tdata_reg; - output_4_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_4_axis_tlast_reg <= input_15_axis_tlast_reg; - output_4_axis_tid_reg <= input_15_axis_tid_reg; - output_4_axis_tdest_reg <= input_15_axis_tdest_reg; - output_4_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_5_select_reg) - 4'd0: begin - output_5_axis_tdata_reg <= input_0_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_0_axis_tlast_reg; - output_5_axis_tid_reg <= input_0_axis_tid_reg; - output_5_axis_tdest_reg <= input_0_axis_tdest_reg; - output_5_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_5_axis_tdata_reg <= input_1_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_1_axis_tlast_reg; - output_5_axis_tid_reg <= input_1_axis_tid_reg; - output_5_axis_tdest_reg <= input_1_axis_tdest_reg; - output_5_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_5_axis_tdata_reg <= input_2_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_2_axis_tlast_reg; - output_5_axis_tid_reg <= input_2_axis_tid_reg; - output_5_axis_tdest_reg <= input_2_axis_tdest_reg; - output_5_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_5_axis_tdata_reg <= input_3_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_3_axis_tlast_reg; - output_5_axis_tid_reg <= input_3_axis_tid_reg; - output_5_axis_tdest_reg <= input_3_axis_tdest_reg; - output_5_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_5_axis_tdata_reg <= input_4_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_4_axis_tlast_reg; - output_5_axis_tid_reg <= input_4_axis_tid_reg; - output_5_axis_tdest_reg <= input_4_axis_tdest_reg; - output_5_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_5_axis_tdata_reg <= input_5_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_5_axis_tlast_reg; - output_5_axis_tid_reg <= input_5_axis_tid_reg; - output_5_axis_tdest_reg <= input_5_axis_tdest_reg; - output_5_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_5_axis_tdata_reg <= input_6_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_6_axis_tlast_reg; - output_5_axis_tid_reg <= input_6_axis_tid_reg; - output_5_axis_tdest_reg <= input_6_axis_tdest_reg; - output_5_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_5_axis_tdata_reg <= input_7_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_7_axis_tlast_reg; - output_5_axis_tid_reg <= input_7_axis_tid_reg; - output_5_axis_tdest_reg <= input_7_axis_tdest_reg; - output_5_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_5_axis_tdata_reg <= input_8_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_8_axis_tlast_reg; - output_5_axis_tid_reg <= input_8_axis_tid_reg; - output_5_axis_tdest_reg <= input_8_axis_tdest_reg; - output_5_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_5_axis_tdata_reg <= input_9_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_9_axis_tlast_reg; - output_5_axis_tid_reg <= input_9_axis_tid_reg; - output_5_axis_tdest_reg <= input_9_axis_tdest_reg; - output_5_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_5_axis_tdata_reg <= input_10_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_10_axis_tlast_reg; - output_5_axis_tid_reg <= input_10_axis_tid_reg; - output_5_axis_tdest_reg <= input_10_axis_tdest_reg; - output_5_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_5_axis_tdata_reg <= input_11_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_11_axis_tlast_reg; - output_5_axis_tid_reg <= input_11_axis_tid_reg; - output_5_axis_tdest_reg <= input_11_axis_tdest_reg; - output_5_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_5_axis_tdata_reg <= input_12_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_12_axis_tlast_reg; - output_5_axis_tid_reg <= input_12_axis_tid_reg; - output_5_axis_tdest_reg <= input_12_axis_tdest_reg; - output_5_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_5_axis_tdata_reg <= input_13_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_13_axis_tlast_reg; - output_5_axis_tid_reg <= input_13_axis_tid_reg; - output_5_axis_tdest_reg <= input_13_axis_tdest_reg; - output_5_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_5_axis_tdata_reg <= input_14_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_14_axis_tlast_reg; - output_5_axis_tid_reg <= input_14_axis_tid_reg; - output_5_axis_tdest_reg <= input_14_axis_tdest_reg; - output_5_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_5_axis_tdata_reg <= input_15_axis_tdata_reg; - output_5_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_5_axis_tlast_reg <= input_15_axis_tlast_reg; - output_5_axis_tid_reg <= input_15_axis_tid_reg; - output_5_axis_tdest_reg <= input_15_axis_tdest_reg; - output_5_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_6_select_reg) - 4'd0: begin - output_6_axis_tdata_reg <= input_0_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_0_axis_tlast_reg; - output_6_axis_tid_reg <= input_0_axis_tid_reg; - output_6_axis_tdest_reg <= input_0_axis_tdest_reg; - output_6_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_6_axis_tdata_reg <= input_1_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_1_axis_tlast_reg; - output_6_axis_tid_reg <= input_1_axis_tid_reg; - output_6_axis_tdest_reg <= input_1_axis_tdest_reg; - output_6_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_6_axis_tdata_reg <= input_2_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_2_axis_tlast_reg; - output_6_axis_tid_reg <= input_2_axis_tid_reg; - output_6_axis_tdest_reg <= input_2_axis_tdest_reg; - output_6_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_6_axis_tdata_reg <= input_3_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_3_axis_tlast_reg; - output_6_axis_tid_reg <= input_3_axis_tid_reg; - output_6_axis_tdest_reg <= input_3_axis_tdest_reg; - output_6_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_6_axis_tdata_reg <= input_4_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_4_axis_tlast_reg; - output_6_axis_tid_reg <= input_4_axis_tid_reg; - output_6_axis_tdest_reg <= input_4_axis_tdest_reg; - output_6_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_6_axis_tdata_reg <= input_5_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_5_axis_tlast_reg; - output_6_axis_tid_reg <= input_5_axis_tid_reg; - output_6_axis_tdest_reg <= input_5_axis_tdest_reg; - output_6_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_6_axis_tdata_reg <= input_6_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_6_axis_tlast_reg; - output_6_axis_tid_reg <= input_6_axis_tid_reg; - output_6_axis_tdest_reg <= input_6_axis_tdest_reg; - output_6_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_6_axis_tdata_reg <= input_7_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_7_axis_tlast_reg; - output_6_axis_tid_reg <= input_7_axis_tid_reg; - output_6_axis_tdest_reg <= input_7_axis_tdest_reg; - output_6_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_6_axis_tdata_reg <= input_8_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_8_axis_tlast_reg; - output_6_axis_tid_reg <= input_8_axis_tid_reg; - output_6_axis_tdest_reg <= input_8_axis_tdest_reg; - output_6_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_6_axis_tdata_reg <= input_9_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_9_axis_tlast_reg; - output_6_axis_tid_reg <= input_9_axis_tid_reg; - output_6_axis_tdest_reg <= input_9_axis_tdest_reg; - output_6_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_6_axis_tdata_reg <= input_10_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_10_axis_tlast_reg; - output_6_axis_tid_reg <= input_10_axis_tid_reg; - output_6_axis_tdest_reg <= input_10_axis_tdest_reg; - output_6_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_6_axis_tdata_reg <= input_11_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_11_axis_tlast_reg; - output_6_axis_tid_reg <= input_11_axis_tid_reg; - output_6_axis_tdest_reg <= input_11_axis_tdest_reg; - output_6_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_6_axis_tdata_reg <= input_12_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_12_axis_tlast_reg; - output_6_axis_tid_reg <= input_12_axis_tid_reg; - output_6_axis_tdest_reg <= input_12_axis_tdest_reg; - output_6_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_6_axis_tdata_reg <= input_13_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_13_axis_tlast_reg; - output_6_axis_tid_reg <= input_13_axis_tid_reg; - output_6_axis_tdest_reg <= input_13_axis_tdest_reg; - output_6_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_6_axis_tdata_reg <= input_14_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_14_axis_tlast_reg; - output_6_axis_tid_reg <= input_14_axis_tid_reg; - output_6_axis_tdest_reg <= input_14_axis_tdest_reg; - output_6_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_6_axis_tdata_reg <= input_15_axis_tdata_reg; - output_6_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_6_axis_tlast_reg <= input_15_axis_tlast_reg; - output_6_axis_tid_reg <= input_15_axis_tid_reg; - output_6_axis_tdest_reg <= input_15_axis_tdest_reg; - output_6_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_7_select_reg) - 4'd0: begin - output_7_axis_tdata_reg <= input_0_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_0_axis_tlast_reg; - output_7_axis_tid_reg <= input_0_axis_tid_reg; - output_7_axis_tdest_reg <= input_0_axis_tdest_reg; - output_7_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_7_axis_tdata_reg <= input_1_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_1_axis_tlast_reg; - output_7_axis_tid_reg <= input_1_axis_tid_reg; - output_7_axis_tdest_reg <= input_1_axis_tdest_reg; - output_7_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_7_axis_tdata_reg <= input_2_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_2_axis_tlast_reg; - output_7_axis_tid_reg <= input_2_axis_tid_reg; - output_7_axis_tdest_reg <= input_2_axis_tdest_reg; - output_7_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_7_axis_tdata_reg <= input_3_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_3_axis_tlast_reg; - output_7_axis_tid_reg <= input_3_axis_tid_reg; - output_7_axis_tdest_reg <= input_3_axis_tdest_reg; - output_7_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_7_axis_tdata_reg <= input_4_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_4_axis_tlast_reg; - output_7_axis_tid_reg <= input_4_axis_tid_reg; - output_7_axis_tdest_reg <= input_4_axis_tdest_reg; - output_7_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_7_axis_tdata_reg <= input_5_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_5_axis_tlast_reg; - output_7_axis_tid_reg <= input_5_axis_tid_reg; - output_7_axis_tdest_reg <= input_5_axis_tdest_reg; - output_7_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_7_axis_tdata_reg <= input_6_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_6_axis_tlast_reg; - output_7_axis_tid_reg <= input_6_axis_tid_reg; - output_7_axis_tdest_reg <= input_6_axis_tdest_reg; - output_7_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_7_axis_tdata_reg <= input_7_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_7_axis_tlast_reg; - output_7_axis_tid_reg <= input_7_axis_tid_reg; - output_7_axis_tdest_reg <= input_7_axis_tdest_reg; - output_7_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_7_axis_tdata_reg <= input_8_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_8_axis_tlast_reg; - output_7_axis_tid_reg <= input_8_axis_tid_reg; - output_7_axis_tdest_reg <= input_8_axis_tdest_reg; - output_7_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_7_axis_tdata_reg <= input_9_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_9_axis_tlast_reg; - output_7_axis_tid_reg <= input_9_axis_tid_reg; - output_7_axis_tdest_reg <= input_9_axis_tdest_reg; - output_7_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_7_axis_tdata_reg <= input_10_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_10_axis_tlast_reg; - output_7_axis_tid_reg <= input_10_axis_tid_reg; - output_7_axis_tdest_reg <= input_10_axis_tdest_reg; - output_7_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_7_axis_tdata_reg <= input_11_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_11_axis_tlast_reg; - output_7_axis_tid_reg <= input_11_axis_tid_reg; - output_7_axis_tdest_reg <= input_11_axis_tdest_reg; - output_7_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_7_axis_tdata_reg <= input_12_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_12_axis_tlast_reg; - output_7_axis_tid_reg <= input_12_axis_tid_reg; - output_7_axis_tdest_reg <= input_12_axis_tdest_reg; - output_7_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_7_axis_tdata_reg <= input_13_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_13_axis_tlast_reg; - output_7_axis_tid_reg <= input_13_axis_tid_reg; - output_7_axis_tdest_reg <= input_13_axis_tdest_reg; - output_7_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_7_axis_tdata_reg <= input_14_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_14_axis_tlast_reg; - output_7_axis_tid_reg <= input_14_axis_tid_reg; - output_7_axis_tdest_reg <= input_14_axis_tdest_reg; - output_7_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_7_axis_tdata_reg <= input_15_axis_tdata_reg; - output_7_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_7_axis_tlast_reg <= input_15_axis_tlast_reg; - output_7_axis_tid_reg <= input_15_axis_tid_reg; - output_7_axis_tdest_reg <= input_15_axis_tdest_reg; - output_7_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_8_select_reg) - 4'd0: begin - output_8_axis_tdata_reg <= input_0_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_0_axis_tlast_reg; - output_8_axis_tid_reg <= input_0_axis_tid_reg; - output_8_axis_tdest_reg <= input_0_axis_tdest_reg; - output_8_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_8_axis_tdata_reg <= input_1_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_1_axis_tlast_reg; - output_8_axis_tid_reg <= input_1_axis_tid_reg; - output_8_axis_tdest_reg <= input_1_axis_tdest_reg; - output_8_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_8_axis_tdata_reg <= input_2_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_2_axis_tlast_reg; - output_8_axis_tid_reg <= input_2_axis_tid_reg; - output_8_axis_tdest_reg <= input_2_axis_tdest_reg; - output_8_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_8_axis_tdata_reg <= input_3_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_3_axis_tlast_reg; - output_8_axis_tid_reg <= input_3_axis_tid_reg; - output_8_axis_tdest_reg <= input_3_axis_tdest_reg; - output_8_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_8_axis_tdata_reg <= input_4_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_4_axis_tlast_reg; - output_8_axis_tid_reg <= input_4_axis_tid_reg; - output_8_axis_tdest_reg <= input_4_axis_tdest_reg; - output_8_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_8_axis_tdata_reg <= input_5_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_5_axis_tlast_reg; - output_8_axis_tid_reg <= input_5_axis_tid_reg; - output_8_axis_tdest_reg <= input_5_axis_tdest_reg; - output_8_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_8_axis_tdata_reg <= input_6_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_6_axis_tlast_reg; - output_8_axis_tid_reg <= input_6_axis_tid_reg; - output_8_axis_tdest_reg <= input_6_axis_tdest_reg; - output_8_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_8_axis_tdata_reg <= input_7_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_7_axis_tlast_reg; - output_8_axis_tid_reg <= input_7_axis_tid_reg; - output_8_axis_tdest_reg <= input_7_axis_tdest_reg; - output_8_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_8_axis_tdata_reg <= input_8_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_8_axis_tlast_reg; - output_8_axis_tid_reg <= input_8_axis_tid_reg; - output_8_axis_tdest_reg <= input_8_axis_tdest_reg; - output_8_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_8_axis_tdata_reg <= input_9_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_9_axis_tlast_reg; - output_8_axis_tid_reg <= input_9_axis_tid_reg; - output_8_axis_tdest_reg <= input_9_axis_tdest_reg; - output_8_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_8_axis_tdata_reg <= input_10_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_10_axis_tlast_reg; - output_8_axis_tid_reg <= input_10_axis_tid_reg; - output_8_axis_tdest_reg <= input_10_axis_tdest_reg; - output_8_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_8_axis_tdata_reg <= input_11_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_11_axis_tlast_reg; - output_8_axis_tid_reg <= input_11_axis_tid_reg; - output_8_axis_tdest_reg <= input_11_axis_tdest_reg; - output_8_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_8_axis_tdata_reg <= input_12_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_12_axis_tlast_reg; - output_8_axis_tid_reg <= input_12_axis_tid_reg; - output_8_axis_tdest_reg <= input_12_axis_tdest_reg; - output_8_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_8_axis_tdata_reg <= input_13_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_13_axis_tlast_reg; - output_8_axis_tid_reg <= input_13_axis_tid_reg; - output_8_axis_tdest_reg <= input_13_axis_tdest_reg; - output_8_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_8_axis_tdata_reg <= input_14_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_14_axis_tlast_reg; - output_8_axis_tid_reg <= input_14_axis_tid_reg; - output_8_axis_tdest_reg <= input_14_axis_tdest_reg; - output_8_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_8_axis_tdata_reg <= input_15_axis_tdata_reg; - output_8_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_8_axis_tlast_reg <= input_15_axis_tlast_reg; - output_8_axis_tid_reg <= input_15_axis_tid_reg; - output_8_axis_tdest_reg <= input_15_axis_tdest_reg; - output_8_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_9_select_reg) - 4'd0: begin - output_9_axis_tdata_reg <= input_0_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_0_axis_tlast_reg; - output_9_axis_tid_reg <= input_0_axis_tid_reg; - output_9_axis_tdest_reg <= input_0_axis_tdest_reg; - output_9_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_9_axis_tdata_reg <= input_1_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_1_axis_tlast_reg; - output_9_axis_tid_reg <= input_1_axis_tid_reg; - output_9_axis_tdest_reg <= input_1_axis_tdest_reg; - output_9_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_9_axis_tdata_reg <= input_2_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_2_axis_tlast_reg; - output_9_axis_tid_reg <= input_2_axis_tid_reg; - output_9_axis_tdest_reg <= input_2_axis_tdest_reg; - output_9_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_9_axis_tdata_reg <= input_3_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_3_axis_tlast_reg; - output_9_axis_tid_reg <= input_3_axis_tid_reg; - output_9_axis_tdest_reg <= input_3_axis_tdest_reg; - output_9_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_9_axis_tdata_reg <= input_4_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_4_axis_tlast_reg; - output_9_axis_tid_reg <= input_4_axis_tid_reg; - output_9_axis_tdest_reg <= input_4_axis_tdest_reg; - output_9_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_9_axis_tdata_reg <= input_5_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_5_axis_tlast_reg; - output_9_axis_tid_reg <= input_5_axis_tid_reg; - output_9_axis_tdest_reg <= input_5_axis_tdest_reg; - output_9_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_9_axis_tdata_reg <= input_6_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_6_axis_tlast_reg; - output_9_axis_tid_reg <= input_6_axis_tid_reg; - output_9_axis_tdest_reg <= input_6_axis_tdest_reg; - output_9_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_9_axis_tdata_reg <= input_7_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_7_axis_tlast_reg; - output_9_axis_tid_reg <= input_7_axis_tid_reg; - output_9_axis_tdest_reg <= input_7_axis_tdest_reg; - output_9_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_9_axis_tdata_reg <= input_8_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_8_axis_tlast_reg; - output_9_axis_tid_reg <= input_8_axis_tid_reg; - output_9_axis_tdest_reg <= input_8_axis_tdest_reg; - output_9_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_9_axis_tdata_reg <= input_9_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_9_axis_tlast_reg; - output_9_axis_tid_reg <= input_9_axis_tid_reg; - output_9_axis_tdest_reg <= input_9_axis_tdest_reg; - output_9_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_9_axis_tdata_reg <= input_10_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_10_axis_tlast_reg; - output_9_axis_tid_reg <= input_10_axis_tid_reg; - output_9_axis_tdest_reg <= input_10_axis_tdest_reg; - output_9_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_9_axis_tdata_reg <= input_11_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_11_axis_tlast_reg; - output_9_axis_tid_reg <= input_11_axis_tid_reg; - output_9_axis_tdest_reg <= input_11_axis_tdest_reg; - output_9_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_9_axis_tdata_reg <= input_12_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_12_axis_tlast_reg; - output_9_axis_tid_reg <= input_12_axis_tid_reg; - output_9_axis_tdest_reg <= input_12_axis_tdest_reg; - output_9_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_9_axis_tdata_reg <= input_13_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_13_axis_tlast_reg; - output_9_axis_tid_reg <= input_13_axis_tid_reg; - output_9_axis_tdest_reg <= input_13_axis_tdest_reg; - output_9_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_9_axis_tdata_reg <= input_14_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_14_axis_tlast_reg; - output_9_axis_tid_reg <= input_14_axis_tid_reg; - output_9_axis_tdest_reg <= input_14_axis_tdest_reg; - output_9_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_9_axis_tdata_reg <= input_15_axis_tdata_reg; - output_9_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_9_axis_tlast_reg <= input_15_axis_tlast_reg; - output_9_axis_tid_reg <= input_15_axis_tid_reg; - output_9_axis_tdest_reg <= input_15_axis_tdest_reg; - output_9_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_10_select_reg) - 4'd0: begin - output_10_axis_tdata_reg <= input_0_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_0_axis_tlast_reg; - output_10_axis_tid_reg <= input_0_axis_tid_reg; - output_10_axis_tdest_reg <= input_0_axis_tdest_reg; - output_10_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_10_axis_tdata_reg <= input_1_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_1_axis_tlast_reg; - output_10_axis_tid_reg <= input_1_axis_tid_reg; - output_10_axis_tdest_reg <= input_1_axis_tdest_reg; - output_10_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_10_axis_tdata_reg <= input_2_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_2_axis_tlast_reg; - output_10_axis_tid_reg <= input_2_axis_tid_reg; - output_10_axis_tdest_reg <= input_2_axis_tdest_reg; - output_10_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_10_axis_tdata_reg <= input_3_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_3_axis_tlast_reg; - output_10_axis_tid_reg <= input_3_axis_tid_reg; - output_10_axis_tdest_reg <= input_3_axis_tdest_reg; - output_10_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_10_axis_tdata_reg <= input_4_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_4_axis_tlast_reg; - output_10_axis_tid_reg <= input_4_axis_tid_reg; - output_10_axis_tdest_reg <= input_4_axis_tdest_reg; - output_10_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_10_axis_tdata_reg <= input_5_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_5_axis_tlast_reg; - output_10_axis_tid_reg <= input_5_axis_tid_reg; - output_10_axis_tdest_reg <= input_5_axis_tdest_reg; - output_10_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_10_axis_tdata_reg <= input_6_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_6_axis_tlast_reg; - output_10_axis_tid_reg <= input_6_axis_tid_reg; - output_10_axis_tdest_reg <= input_6_axis_tdest_reg; - output_10_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_10_axis_tdata_reg <= input_7_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_7_axis_tlast_reg; - output_10_axis_tid_reg <= input_7_axis_tid_reg; - output_10_axis_tdest_reg <= input_7_axis_tdest_reg; - output_10_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_10_axis_tdata_reg <= input_8_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_8_axis_tlast_reg; - output_10_axis_tid_reg <= input_8_axis_tid_reg; - output_10_axis_tdest_reg <= input_8_axis_tdest_reg; - output_10_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_10_axis_tdata_reg <= input_9_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_9_axis_tlast_reg; - output_10_axis_tid_reg <= input_9_axis_tid_reg; - output_10_axis_tdest_reg <= input_9_axis_tdest_reg; - output_10_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_10_axis_tdata_reg <= input_10_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_10_axis_tlast_reg; - output_10_axis_tid_reg <= input_10_axis_tid_reg; - output_10_axis_tdest_reg <= input_10_axis_tdest_reg; - output_10_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_10_axis_tdata_reg <= input_11_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_11_axis_tlast_reg; - output_10_axis_tid_reg <= input_11_axis_tid_reg; - output_10_axis_tdest_reg <= input_11_axis_tdest_reg; - output_10_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_10_axis_tdata_reg <= input_12_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_12_axis_tlast_reg; - output_10_axis_tid_reg <= input_12_axis_tid_reg; - output_10_axis_tdest_reg <= input_12_axis_tdest_reg; - output_10_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_10_axis_tdata_reg <= input_13_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_13_axis_tlast_reg; - output_10_axis_tid_reg <= input_13_axis_tid_reg; - output_10_axis_tdest_reg <= input_13_axis_tdest_reg; - output_10_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_10_axis_tdata_reg <= input_14_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_14_axis_tlast_reg; - output_10_axis_tid_reg <= input_14_axis_tid_reg; - output_10_axis_tdest_reg <= input_14_axis_tdest_reg; - output_10_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_10_axis_tdata_reg <= input_15_axis_tdata_reg; - output_10_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_10_axis_tlast_reg <= input_15_axis_tlast_reg; - output_10_axis_tid_reg <= input_15_axis_tid_reg; - output_10_axis_tdest_reg <= input_15_axis_tdest_reg; - output_10_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_11_select_reg) - 4'd0: begin - output_11_axis_tdata_reg <= input_0_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_0_axis_tlast_reg; - output_11_axis_tid_reg <= input_0_axis_tid_reg; - output_11_axis_tdest_reg <= input_0_axis_tdest_reg; - output_11_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_11_axis_tdata_reg <= input_1_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_1_axis_tlast_reg; - output_11_axis_tid_reg <= input_1_axis_tid_reg; - output_11_axis_tdest_reg <= input_1_axis_tdest_reg; - output_11_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_11_axis_tdata_reg <= input_2_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_2_axis_tlast_reg; - output_11_axis_tid_reg <= input_2_axis_tid_reg; - output_11_axis_tdest_reg <= input_2_axis_tdest_reg; - output_11_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_11_axis_tdata_reg <= input_3_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_3_axis_tlast_reg; - output_11_axis_tid_reg <= input_3_axis_tid_reg; - output_11_axis_tdest_reg <= input_3_axis_tdest_reg; - output_11_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_11_axis_tdata_reg <= input_4_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_4_axis_tlast_reg; - output_11_axis_tid_reg <= input_4_axis_tid_reg; - output_11_axis_tdest_reg <= input_4_axis_tdest_reg; - output_11_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_11_axis_tdata_reg <= input_5_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_5_axis_tlast_reg; - output_11_axis_tid_reg <= input_5_axis_tid_reg; - output_11_axis_tdest_reg <= input_5_axis_tdest_reg; - output_11_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_11_axis_tdata_reg <= input_6_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_6_axis_tlast_reg; - output_11_axis_tid_reg <= input_6_axis_tid_reg; - output_11_axis_tdest_reg <= input_6_axis_tdest_reg; - output_11_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_11_axis_tdata_reg <= input_7_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_7_axis_tlast_reg; - output_11_axis_tid_reg <= input_7_axis_tid_reg; - output_11_axis_tdest_reg <= input_7_axis_tdest_reg; - output_11_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_11_axis_tdata_reg <= input_8_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_8_axis_tlast_reg; - output_11_axis_tid_reg <= input_8_axis_tid_reg; - output_11_axis_tdest_reg <= input_8_axis_tdest_reg; - output_11_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_11_axis_tdata_reg <= input_9_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_9_axis_tlast_reg; - output_11_axis_tid_reg <= input_9_axis_tid_reg; - output_11_axis_tdest_reg <= input_9_axis_tdest_reg; - output_11_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_11_axis_tdata_reg <= input_10_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_10_axis_tlast_reg; - output_11_axis_tid_reg <= input_10_axis_tid_reg; - output_11_axis_tdest_reg <= input_10_axis_tdest_reg; - output_11_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_11_axis_tdata_reg <= input_11_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_11_axis_tlast_reg; - output_11_axis_tid_reg <= input_11_axis_tid_reg; - output_11_axis_tdest_reg <= input_11_axis_tdest_reg; - output_11_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_11_axis_tdata_reg <= input_12_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_12_axis_tlast_reg; - output_11_axis_tid_reg <= input_12_axis_tid_reg; - output_11_axis_tdest_reg <= input_12_axis_tdest_reg; - output_11_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_11_axis_tdata_reg <= input_13_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_13_axis_tlast_reg; - output_11_axis_tid_reg <= input_13_axis_tid_reg; - output_11_axis_tdest_reg <= input_13_axis_tdest_reg; - output_11_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_11_axis_tdata_reg <= input_14_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_14_axis_tlast_reg; - output_11_axis_tid_reg <= input_14_axis_tid_reg; - output_11_axis_tdest_reg <= input_14_axis_tdest_reg; - output_11_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_11_axis_tdata_reg <= input_15_axis_tdata_reg; - output_11_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_11_axis_tlast_reg <= input_15_axis_tlast_reg; - output_11_axis_tid_reg <= input_15_axis_tid_reg; - output_11_axis_tdest_reg <= input_15_axis_tdest_reg; - output_11_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_12_select_reg) - 4'd0: begin - output_12_axis_tdata_reg <= input_0_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_0_axis_tlast_reg; - output_12_axis_tid_reg <= input_0_axis_tid_reg; - output_12_axis_tdest_reg <= input_0_axis_tdest_reg; - output_12_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_12_axis_tdata_reg <= input_1_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_1_axis_tlast_reg; - output_12_axis_tid_reg <= input_1_axis_tid_reg; - output_12_axis_tdest_reg <= input_1_axis_tdest_reg; - output_12_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_12_axis_tdata_reg <= input_2_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_2_axis_tlast_reg; - output_12_axis_tid_reg <= input_2_axis_tid_reg; - output_12_axis_tdest_reg <= input_2_axis_tdest_reg; - output_12_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_12_axis_tdata_reg <= input_3_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_3_axis_tlast_reg; - output_12_axis_tid_reg <= input_3_axis_tid_reg; - output_12_axis_tdest_reg <= input_3_axis_tdest_reg; - output_12_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_12_axis_tdata_reg <= input_4_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_4_axis_tlast_reg; - output_12_axis_tid_reg <= input_4_axis_tid_reg; - output_12_axis_tdest_reg <= input_4_axis_tdest_reg; - output_12_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_12_axis_tdata_reg <= input_5_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_5_axis_tlast_reg; - output_12_axis_tid_reg <= input_5_axis_tid_reg; - output_12_axis_tdest_reg <= input_5_axis_tdest_reg; - output_12_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_12_axis_tdata_reg <= input_6_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_6_axis_tlast_reg; - output_12_axis_tid_reg <= input_6_axis_tid_reg; - output_12_axis_tdest_reg <= input_6_axis_tdest_reg; - output_12_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_12_axis_tdata_reg <= input_7_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_7_axis_tlast_reg; - output_12_axis_tid_reg <= input_7_axis_tid_reg; - output_12_axis_tdest_reg <= input_7_axis_tdest_reg; - output_12_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_12_axis_tdata_reg <= input_8_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_8_axis_tlast_reg; - output_12_axis_tid_reg <= input_8_axis_tid_reg; - output_12_axis_tdest_reg <= input_8_axis_tdest_reg; - output_12_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_12_axis_tdata_reg <= input_9_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_9_axis_tlast_reg; - output_12_axis_tid_reg <= input_9_axis_tid_reg; - output_12_axis_tdest_reg <= input_9_axis_tdest_reg; - output_12_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_12_axis_tdata_reg <= input_10_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_10_axis_tlast_reg; - output_12_axis_tid_reg <= input_10_axis_tid_reg; - output_12_axis_tdest_reg <= input_10_axis_tdest_reg; - output_12_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_12_axis_tdata_reg <= input_11_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_11_axis_tlast_reg; - output_12_axis_tid_reg <= input_11_axis_tid_reg; - output_12_axis_tdest_reg <= input_11_axis_tdest_reg; - output_12_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_12_axis_tdata_reg <= input_12_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_12_axis_tlast_reg; - output_12_axis_tid_reg <= input_12_axis_tid_reg; - output_12_axis_tdest_reg <= input_12_axis_tdest_reg; - output_12_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_12_axis_tdata_reg <= input_13_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_13_axis_tlast_reg; - output_12_axis_tid_reg <= input_13_axis_tid_reg; - output_12_axis_tdest_reg <= input_13_axis_tdest_reg; - output_12_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_12_axis_tdata_reg <= input_14_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_14_axis_tlast_reg; - output_12_axis_tid_reg <= input_14_axis_tid_reg; - output_12_axis_tdest_reg <= input_14_axis_tdest_reg; - output_12_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_12_axis_tdata_reg <= input_15_axis_tdata_reg; - output_12_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_12_axis_tlast_reg <= input_15_axis_tlast_reg; - output_12_axis_tid_reg <= input_15_axis_tid_reg; - output_12_axis_tdest_reg <= input_15_axis_tdest_reg; - output_12_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_13_select_reg) - 4'd0: begin - output_13_axis_tdata_reg <= input_0_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_0_axis_tlast_reg; - output_13_axis_tid_reg <= input_0_axis_tid_reg; - output_13_axis_tdest_reg <= input_0_axis_tdest_reg; - output_13_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_13_axis_tdata_reg <= input_1_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_1_axis_tlast_reg; - output_13_axis_tid_reg <= input_1_axis_tid_reg; - output_13_axis_tdest_reg <= input_1_axis_tdest_reg; - output_13_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_13_axis_tdata_reg <= input_2_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_2_axis_tlast_reg; - output_13_axis_tid_reg <= input_2_axis_tid_reg; - output_13_axis_tdest_reg <= input_2_axis_tdest_reg; - output_13_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_13_axis_tdata_reg <= input_3_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_3_axis_tlast_reg; - output_13_axis_tid_reg <= input_3_axis_tid_reg; - output_13_axis_tdest_reg <= input_3_axis_tdest_reg; - output_13_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_13_axis_tdata_reg <= input_4_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_4_axis_tlast_reg; - output_13_axis_tid_reg <= input_4_axis_tid_reg; - output_13_axis_tdest_reg <= input_4_axis_tdest_reg; - output_13_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_13_axis_tdata_reg <= input_5_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_5_axis_tlast_reg; - output_13_axis_tid_reg <= input_5_axis_tid_reg; - output_13_axis_tdest_reg <= input_5_axis_tdest_reg; - output_13_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_13_axis_tdata_reg <= input_6_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_6_axis_tlast_reg; - output_13_axis_tid_reg <= input_6_axis_tid_reg; - output_13_axis_tdest_reg <= input_6_axis_tdest_reg; - output_13_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_13_axis_tdata_reg <= input_7_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_7_axis_tlast_reg; - output_13_axis_tid_reg <= input_7_axis_tid_reg; - output_13_axis_tdest_reg <= input_7_axis_tdest_reg; - output_13_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_13_axis_tdata_reg <= input_8_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_8_axis_tlast_reg; - output_13_axis_tid_reg <= input_8_axis_tid_reg; - output_13_axis_tdest_reg <= input_8_axis_tdest_reg; - output_13_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_13_axis_tdata_reg <= input_9_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_9_axis_tlast_reg; - output_13_axis_tid_reg <= input_9_axis_tid_reg; - output_13_axis_tdest_reg <= input_9_axis_tdest_reg; - output_13_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_13_axis_tdata_reg <= input_10_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_10_axis_tlast_reg; - output_13_axis_tid_reg <= input_10_axis_tid_reg; - output_13_axis_tdest_reg <= input_10_axis_tdest_reg; - output_13_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_13_axis_tdata_reg <= input_11_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_11_axis_tlast_reg; - output_13_axis_tid_reg <= input_11_axis_tid_reg; - output_13_axis_tdest_reg <= input_11_axis_tdest_reg; - output_13_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_13_axis_tdata_reg <= input_12_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_12_axis_tlast_reg; - output_13_axis_tid_reg <= input_12_axis_tid_reg; - output_13_axis_tdest_reg <= input_12_axis_tdest_reg; - output_13_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_13_axis_tdata_reg <= input_13_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_13_axis_tlast_reg; - output_13_axis_tid_reg <= input_13_axis_tid_reg; - output_13_axis_tdest_reg <= input_13_axis_tdest_reg; - output_13_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_13_axis_tdata_reg <= input_14_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_14_axis_tlast_reg; - output_13_axis_tid_reg <= input_14_axis_tid_reg; - output_13_axis_tdest_reg <= input_14_axis_tdest_reg; - output_13_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_13_axis_tdata_reg <= input_15_axis_tdata_reg; - output_13_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_13_axis_tlast_reg <= input_15_axis_tlast_reg; - output_13_axis_tid_reg <= input_15_axis_tid_reg; - output_13_axis_tdest_reg <= input_15_axis_tdest_reg; - output_13_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_14_select_reg) - 4'd0: begin - output_14_axis_tdata_reg <= input_0_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_0_axis_tlast_reg; - output_14_axis_tid_reg <= input_0_axis_tid_reg; - output_14_axis_tdest_reg <= input_0_axis_tdest_reg; - output_14_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_14_axis_tdata_reg <= input_1_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_1_axis_tlast_reg; - output_14_axis_tid_reg <= input_1_axis_tid_reg; - output_14_axis_tdest_reg <= input_1_axis_tdest_reg; - output_14_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_14_axis_tdata_reg <= input_2_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_2_axis_tlast_reg; - output_14_axis_tid_reg <= input_2_axis_tid_reg; - output_14_axis_tdest_reg <= input_2_axis_tdest_reg; - output_14_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_14_axis_tdata_reg <= input_3_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_3_axis_tlast_reg; - output_14_axis_tid_reg <= input_3_axis_tid_reg; - output_14_axis_tdest_reg <= input_3_axis_tdest_reg; - output_14_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_14_axis_tdata_reg <= input_4_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_4_axis_tlast_reg; - output_14_axis_tid_reg <= input_4_axis_tid_reg; - output_14_axis_tdest_reg <= input_4_axis_tdest_reg; - output_14_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_14_axis_tdata_reg <= input_5_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_5_axis_tlast_reg; - output_14_axis_tid_reg <= input_5_axis_tid_reg; - output_14_axis_tdest_reg <= input_5_axis_tdest_reg; - output_14_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_14_axis_tdata_reg <= input_6_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_6_axis_tlast_reg; - output_14_axis_tid_reg <= input_6_axis_tid_reg; - output_14_axis_tdest_reg <= input_6_axis_tdest_reg; - output_14_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_14_axis_tdata_reg <= input_7_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_7_axis_tlast_reg; - output_14_axis_tid_reg <= input_7_axis_tid_reg; - output_14_axis_tdest_reg <= input_7_axis_tdest_reg; - output_14_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_14_axis_tdata_reg <= input_8_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_8_axis_tlast_reg; - output_14_axis_tid_reg <= input_8_axis_tid_reg; - output_14_axis_tdest_reg <= input_8_axis_tdest_reg; - output_14_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_14_axis_tdata_reg <= input_9_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_9_axis_tlast_reg; - output_14_axis_tid_reg <= input_9_axis_tid_reg; - output_14_axis_tdest_reg <= input_9_axis_tdest_reg; - output_14_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_14_axis_tdata_reg <= input_10_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_10_axis_tlast_reg; - output_14_axis_tid_reg <= input_10_axis_tid_reg; - output_14_axis_tdest_reg <= input_10_axis_tdest_reg; - output_14_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_14_axis_tdata_reg <= input_11_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_11_axis_tlast_reg; - output_14_axis_tid_reg <= input_11_axis_tid_reg; - output_14_axis_tdest_reg <= input_11_axis_tdest_reg; - output_14_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_14_axis_tdata_reg <= input_12_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_12_axis_tlast_reg; - output_14_axis_tid_reg <= input_12_axis_tid_reg; - output_14_axis_tdest_reg <= input_12_axis_tdest_reg; - output_14_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_14_axis_tdata_reg <= input_13_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_13_axis_tlast_reg; - output_14_axis_tid_reg <= input_13_axis_tid_reg; - output_14_axis_tdest_reg <= input_13_axis_tdest_reg; - output_14_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_14_axis_tdata_reg <= input_14_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_14_axis_tlast_reg; - output_14_axis_tid_reg <= input_14_axis_tid_reg; - output_14_axis_tdest_reg <= input_14_axis_tdest_reg; - output_14_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_14_axis_tdata_reg <= input_15_axis_tdata_reg; - output_14_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_14_axis_tlast_reg <= input_15_axis_tlast_reg; - output_14_axis_tid_reg <= input_15_axis_tid_reg; - output_14_axis_tdest_reg <= input_15_axis_tdest_reg; - output_14_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase - - case (output_15_select_reg) - 4'd0: begin - output_15_axis_tdata_reg <= input_0_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_0_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_0_axis_tlast_reg; - output_15_axis_tid_reg <= input_0_axis_tid_reg; - output_15_axis_tdest_reg <= input_0_axis_tdest_reg; - output_15_axis_tuser_reg <= input_0_axis_tuser_reg; - end - 4'd1: begin - output_15_axis_tdata_reg <= input_1_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_1_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_1_axis_tlast_reg; - output_15_axis_tid_reg <= input_1_axis_tid_reg; - output_15_axis_tdest_reg <= input_1_axis_tdest_reg; - output_15_axis_tuser_reg <= input_1_axis_tuser_reg; - end - 4'd2: begin - output_15_axis_tdata_reg <= input_2_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_2_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_2_axis_tlast_reg; - output_15_axis_tid_reg <= input_2_axis_tid_reg; - output_15_axis_tdest_reg <= input_2_axis_tdest_reg; - output_15_axis_tuser_reg <= input_2_axis_tuser_reg; - end - 4'd3: begin - output_15_axis_tdata_reg <= input_3_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_3_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_3_axis_tlast_reg; - output_15_axis_tid_reg <= input_3_axis_tid_reg; - output_15_axis_tdest_reg <= input_3_axis_tdest_reg; - output_15_axis_tuser_reg <= input_3_axis_tuser_reg; - end - 4'd4: begin - output_15_axis_tdata_reg <= input_4_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_4_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_4_axis_tlast_reg; - output_15_axis_tid_reg <= input_4_axis_tid_reg; - output_15_axis_tdest_reg <= input_4_axis_tdest_reg; - output_15_axis_tuser_reg <= input_4_axis_tuser_reg; - end - 4'd5: begin - output_15_axis_tdata_reg <= input_5_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_5_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_5_axis_tlast_reg; - output_15_axis_tid_reg <= input_5_axis_tid_reg; - output_15_axis_tdest_reg <= input_5_axis_tdest_reg; - output_15_axis_tuser_reg <= input_5_axis_tuser_reg; - end - 4'd6: begin - output_15_axis_tdata_reg <= input_6_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_6_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_6_axis_tlast_reg; - output_15_axis_tid_reg <= input_6_axis_tid_reg; - output_15_axis_tdest_reg <= input_6_axis_tdest_reg; - output_15_axis_tuser_reg <= input_6_axis_tuser_reg; - end - 4'd7: begin - output_15_axis_tdata_reg <= input_7_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_7_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_7_axis_tlast_reg; - output_15_axis_tid_reg <= input_7_axis_tid_reg; - output_15_axis_tdest_reg <= input_7_axis_tdest_reg; - output_15_axis_tuser_reg <= input_7_axis_tuser_reg; - end - 4'd8: begin - output_15_axis_tdata_reg <= input_8_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_8_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_8_axis_tlast_reg; - output_15_axis_tid_reg <= input_8_axis_tid_reg; - output_15_axis_tdest_reg <= input_8_axis_tdest_reg; - output_15_axis_tuser_reg <= input_8_axis_tuser_reg; - end - 4'd9: begin - output_15_axis_tdata_reg <= input_9_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_9_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_9_axis_tlast_reg; - output_15_axis_tid_reg <= input_9_axis_tid_reg; - output_15_axis_tdest_reg <= input_9_axis_tdest_reg; - output_15_axis_tuser_reg <= input_9_axis_tuser_reg; - end - 4'd10: begin - output_15_axis_tdata_reg <= input_10_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_10_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_10_axis_tlast_reg; - output_15_axis_tid_reg <= input_10_axis_tid_reg; - output_15_axis_tdest_reg <= input_10_axis_tdest_reg; - output_15_axis_tuser_reg <= input_10_axis_tuser_reg; - end - 4'd11: begin - output_15_axis_tdata_reg <= input_11_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_11_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_11_axis_tlast_reg; - output_15_axis_tid_reg <= input_11_axis_tid_reg; - output_15_axis_tdest_reg <= input_11_axis_tdest_reg; - output_15_axis_tuser_reg <= input_11_axis_tuser_reg; - end - 4'd12: begin - output_15_axis_tdata_reg <= input_12_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_12_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_12_axis_tlast_reg; - output_15_axis_tid_reg <= input_12_axis_tid_reg; - output_15_axis_tdest_reg <= input_12_axis_tdest_reg; - output_15_axis_tuser_reg <= input_12_axis_tuser_reg; - end - 4'd13: begin - output_15_axis_tdata_reg <= input_13_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_13_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_13_axis_tlast_reg; - output_15_axis_tid_reg <= input_13_axis_tid_reg; - output_15_axis_tdest_reg <= input_13_axis_tdest_reg; - output_15_axis_tuser_reg <= input_13_axis_tuser_reg; - end - 4'd14: begin - output_15_axis_tdata_reg <= input_14_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_14_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_14_axis_tlast_reg; - output_15_axis_tid_reg <= input_14_axis_tid_reg; - output_15_axis_tdest_reg <= input_14_axis_tdest_reg; - output_15_axis_tuser_reg <= input_14_axis_tuser_reg; - end - 4'd15: begin - output_15_axis_tdata_reg <= input_15_axis_tdata_reg; - output_15_axis_tkeep_reg <= input_15_axis_tkeep_reg; - output_15_axis_tlast_reg <= input_15_axis_tlast_reg; - output_15_axis_tid_reg <= input_15_axis_tid_reg; - output_15_axis_tdest_reg <= input_15_axis_tdest_reg; - output_15_axis_tuser_reg <= input_15_axis_tuser_reg; - end - endcase -end - -endmodule diff --git a/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v b/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v index 661271db5..489938126 100644 --- a/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v +++ b/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v @@ -213,7 +213,9 @@ reg [7:0] select_reg_14 = 14; reg [7:0] select_reg_15 = 15; -axis_crosspoint_16x16 #( +axis_crosspoint #( + .S_COUNT(16), + .M_COUNT(16), .DATA_WIDTH(64), .KEEP_ENABLE(1), .KEEP_WIDTH(8), @@ -226,120 +228,23 @@ axis_crosspoint_inst ( .clk(clk), .rst(rst), - .input_0_axis_tdata(eth_l0_rxd), - .input_0_axis_tkeep(eth_l0_rxc), - .input_0_axis_tvalid(1'b1), - .input_1_axis_tdata(eth_l1_rxd), - .input_1_axis_tkeep(eth_l1_rxc), - .input_1_axis_tvalid(1'b1), - .input_2_axis_tdata(eth_l2_rxd), - .input_2_axis_tkeep(eth_l2_rxc), - .input_2_axis_tvalid(1'b1), - .input_3_axis_tdata(eth_l3_rxd), - .input_3_axis_tkeep(eth_l3_rxc), - .input_3_axis_tvalid(1'b1), - .input_4_axis_tdata(eth_l4_rxd), - .input_4_axis_tkeep(eth_l4_rxc), - .input_4_axis_tvalid(1'b1), - .input_5_axis_tdata(eth_l5_rxd), - .input_5_axis_tkeep(eth_l5_rxc), - .input_5_axis_tvalid(1'b1), - .input_6_axis_tdata(eth_l6_rxd), - .input_6_axis_tkeep(eth_l6_rxc), - .input_6_axis_tvalid(1'b1), - .input_7_axis_tdata(eth_l7_rxd), - .input_7_axis_tkeep(eth_l7_rxc), - .input_7_axis_tvalid(1'b1), - .input_8_axis_tdata(eth_r0_rxd), - .input_8_axis_tkeep(eth_r0_rxc), - .input_8_axis_tvalid(1'b1), - .input_9_axis_tdata(eth_r1_rxd), - .input_9_axis_tkeep(eth_r1_rxc), - .input_9_axis_tvalid(1'b1), - .input_10_axis_tdata(eth_r2_rxd), - .input_10_axis_tkeep(eth_r2_rxc), - .input_10_axis_tvalid(1'b1), - .input_11_axis_tdata(eth_r3_rxd), - .input_11_axis_tkeep(eth_r3_rxc), - .input_11_axis_tvalid(1'b1), - .input_12_axis_tdata(eth_r4_rxd), - .input_12_axis_tkeep(eth_r4_rxc), - .input_12_axis_tvalid(1'b1), - .input_13_axis_tdata(eth_r5_rxd), - .input_13_axis_tkeep(eth_r5_rxc), - .input_13_axis_tvalid(1'b1), - .input_14_axis_tdata(eth_r6_rxd), - .input_14_axis_tkeep(eth_r6_rxc), - .input_14_axis_tvalid(1'b1), - .input_15_axis_tdata(eth_r7_rxd), - .input_15_axis_tkeep(eth_r7_rxc), - .input_15_axis_tvalid(1'b1), + .s_axis_tdata({eth_r7_rxd, eth_r6_rxd, eth_r5_rxd, eth_r4_rxd, eth_r3_rxd, eth_r2_rxd, eth_r1_rxd, eth_r0_rxd, eth_l7_rxd, eth_l6_rxd, eth_l5_rxd, eth_l4_rxd, eth_l3_rxd, eth_l2_rxd, eth_l1_rxd, eth_l0_rxd}), + .s_axis_tkeep({eth_r7_rxc, eth_r6_rxc, eth_r5_rxc, eth_r4_rxc, eth_r3_rxc, eth_r2_rxc, eth_r1_rxc, eth_r0_rxc, eth_l7_rxc, eth_l6_rxc, eth_l5_rxc, eth_l4_rxc, eth_l3_rxc, eth_l2_rxc, eth_l1_rxc, eth_l0_rxc}), + .s_axis_tvalid(16'hffff), + .s_axis_tlast(0), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(0), - .output_0_axis_tdata(eth_l0_txd), - .output_0_axis_tkeep(eth_l0_txc), - .output_0_axis_tvalid(), - .output_1_axis_tdata(eth_l1_txd), - .output_1_axis_tkeep(eth_l1_txc), - .output_1_axis_tvalid(), - .output_2_axis_tdata(eth_l2_txd), - .output_2_axis_tkeep(eth_l2_txc), - .output_2_axis_tvalid(), - .output_3_axis_tdata(eth_l3_txd), - .output_3_axis_tkeep(eth_l3_txc), - .output_3_axis_tvalid(), - .output_4_axis_tdata(eth_l4_txd), - .output_4_axis_tkeep(eth_l4_txc), - .output_4_axis_tvalid(), - .output_5_axis_tdata(eth_l5_txd), - .output_5_axis_tkeep(eth_l5_txc), - .output_5_axis_tvalid(), - .output_6_axis_tdata(eth_l6_txd), - .output_6_axis_tkeep(eth_l6_txc), - .output_6_axis_tvalid(), - .output_7_axis_tdata(eth_l7_txd), - .output_7_axis_tkeep(eth_l7_txc), - .output_7_axis_tvalid(), - .output_8_axis_tdata(eth_r0_txd), - .output_8_axis_tkeep(eth_r0_txc), - .output_8_axis_tvalid(), - .output_9_axis_tdata(eth_r1_txd), - .output_9_axis_tkeep(eth_r1_txc), - .output_9_axis_tvalid(), - .output_10_axis_tdata(eth_r2_txd), - .output_10_axis_tkeep(eth_r2_txc), - .output_10_axis_tvalid(), - .output_11_axis_tdata(eth_r3_txd), - .output_11_axis_tkeep(eth_r3_txc), - .output_11_axis_tvalid(), - .output_12_axis_tdata(eth_r4_txd), - .output_12_axis_tkeep(eth_r4_txc), - .output_12_axis_tvalid(), - .output_13_axis_tdata(eth_r5_txd), - .output_13_axis_tkeep(eth_r5_txc), - .output_13_axis_tvalid(), - .output_14_axis_tdata(eth_r6_txd), - .output_14_axis_tkeep(eth_r6_txc), - .output_14_axis_tvalid(), - .output_15_axis_tdata(eth_r7_txd), - .output_15_axis_tkeep(eth_r7_txc), - .output_15_axis_tvalid(), + .m_axis_tdata({eth_r7_txd, eth_r6_txd, eth_r5_txd, eth_r4_txd, eth_r3_txd, eth_r2_txd, eth_r1_txd, eth_r0_txd, eth_l7_txd, eth_l6_txd, eth_l5_txd, eth_l4_txd, eth_l3_txd, eth_l2_txd, eth_l1_txd, eth_l0_txd}), + .m_axis_tkeep({eth_r7_txc, eth_r6_txc, eth_r5_txc, eth_r4_txc, eth_r3_txc, eth_r2_txc, eth_r1_txc, eth_r0_txc, eth_l7_txc, eth_l6_txc, eth_l5_txc, eth_l4_txc, eth_l3_txc, eth_l2_txc, eth_l1_txc, eth_l0_txc}), + .m_axis_tvalid(), + .m_axis_tlast(), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(), - .output_0_select(select_reg_0), - .output_1_select(select_reg_1), - .output_2_select(select_reg_2), - .output_3_select(select_reg_3), - .output_4_select(select_reg_4), - .output_5_select(select_reg_5), - .output_6_select(select_reg_6), - .output_7_select(select_reg_7), - .output_8_select(select_reg_8), - .output_9_select(select_reg_9), - .output_10_select(select_reg_10), - .output_11_select(select_reg_11), - .output_12_select(select_reg_12), - .output_13_select(select_reg_13), - .output_14_select(select_reg_14), - .output_15_select(select_reg_15) + .select({select_reg_15[3:0], select_reg_14[3:0], select_reg_13[3:0], select_reg_12[3:0], select_reg_11[3:0], select_reg_10[3:0], select_reg_9[3:0], select_reg_8[3:0], select_reg_7[3:0], select_reg_6[3:0], select_reg_5[3:0], select_reg_4[3:0], select_reg_3[3:0], select_reg_2[3:0], select_reg_1[3:0], select_reg_0[3:0]}) ); wire [63:0] eth_rx_axis_tdata; @@ -364,7 +269,11 @@ wire eth_rx_payload_tuser; eth_mac_10g_fifo #( .ENABLE_PADDING(1), .ENABLE_DIC(1), - .MIN_FRAME_LENGTH(64) + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(9), + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(9), + .RX_FRAME_FIFO(1) ) eth_mac_fifo_inst ( .rx_clk(clk), diff --git a/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py b/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py index b2ac78167..5957dc951 100755 --- a/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py +++ b/example/HXT100G/fpga_cxpt16/tb/test_fpga_core.py @@ -35,7 +35,6 @@ testbench = 'test_%s' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axis_crosspoint_16x16.v") srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") srcs.append("../lib/eth/rtl/eth_mac_10g.v") srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") @@ -43,7 +42,8 @@ srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_crosspoint.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/ML605/fpga_gmii/fpga_130t/Makefile b/example/ML605/fpga_gmii/fpga_130t/Makefile index 3fb95b4da..887f1c88a 100644 --- a/example/ML605/fpga_gmii/fpga_130t/Makefile +++ b/example/ML605/fpga_gmii/fpga_130t/Makefile @@ -47,7 +47,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v #SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v # UCF files diff --git a/example/ML605/fpga_gmii/fpga_240t/Makefile b/example/ML605/fpga_gmii/fpga_240t/Makefile index ab73d9bbf..a7afe00c5 100644 --- a/example/ML605/fpga_gmii/fpga_240t/Makefile +++ b/example/ML605/fpga_gmii/fpga_240t/Makefile @@ -47,7 +47,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v #SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v # UCF files diff --git a/example/ML605/fpga_gmii/rtl/fpga_core.v b/example/ML605/fpga_gmii/rtl/fpga_core.v index 401a36595..40e262819 100644 --- a/example/ML605/fpga_gmii/rtl/fpga_core.v +++ b/example/ML605/fpga_gmii/rtl/fpga_core.v @@ -330,7 +330,9 @@ eth_mac_1g_gmii_fifo #( .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), - .RX_FIFO_ADDR_WIDTH(12) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) ) eth_mac_inst ( .gtx_clk(clk_125mhz), @@ -563,31 +565,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk_125mhz), .rst(rst_125mhz), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/ML605/fpga_gmii/tb/test_fpga_core.py b/example/ML605/fpga_gmii/tb/test_fpga_core.py index b4c0cf27b..7eb64d5fc 100755 --- a/example/ML605/fpga_gmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_gmii/tb/test_fpga_core.py @@ -70,7 +70,7 @@ srcs.append("../lib/eth/rtl/eth_mux_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/ML605/fpga_rgmii/fpga_130t/Makefile b/example/ML605/fpga_rgmii/fpga_130t/Makefile index a601f5990..7213586b0 100644 --- a/example/ML605/fpga_rgmii/fpga_130t/Makefile +++ b/example/ML605/fpga_rgmii/fpga_130t/Makefile @@ -47,7 +47,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v #SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v # UCF files diff --git a/example/ML605/fpga_rgmii/fpga_240t/Makefile b/example/ML605/fpga_rgmii/fpga_240t/Makefile index e46f861a8..09396893e 100644 --- a/example/ML605/fpga_rgmii/fpga_240t/Makefile +++ b/example/ML605/fpga_rgmii/fpga_240t/Makefile @@ -47,7 +47,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v #SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v # UCF files diff --git a/example/ML605/fpga_rgmii/rtl/fpga_core.v b/example/ML605/fpga_rgmii/rtl/fpga_core.v index 107b83052..daf922d50 100644 --- a/example/ML605/fpga_rgmii/rtl/fpga_core.v +++ b/example/ML605/fpga_rgmii/rtl/fpga_core.v @@ -329,7 +329,9 @@ eth_mac_1g_rgmii_fifo #( .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), - .RX_FIFO_ADDR_WIDTH(12) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) ) eth_mac_inst ( .gtx_clk(clk_125mhz), @@ -560,31 +562,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk_125mhz), .rst(rst_125mhz), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/ML605/fpga_rgmii/tb/test_fpga_core.py b/example/ML605/fpga_rgmii/tb/test_fpga_core.py index 4847fe10e..d5d531aae 100755 --- a/example/ML605/fpga_rgmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_rgmii/tb/test_fpga_core.py @@ -70,7 +70,7 @@ srcs.append("../lib/eth/rtl/eth_mux_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/ML605/fpga_sgmii/fpga_130t/Makefile b/example/ML605/fpga_sgmii/fpga_130t/Makefile index dc4fb229e..904197fa3 100644 --- a/example/ML605/fpga_sgmii/fpga_130t/Makefile +++ b/example/ML605/fpga_sgmii/fpga_130t/Makefile @@ -41,7 +41,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_clk_gen.v SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_johnson_cntr.v SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_rx_rate_adapt.v diff --git a/example/ML605/fpga_sgmii/fpga_240t/Makefile b/example/ML605/fpga_sgmii/fpga_240t/Makefile index ac9178695..07d08b056 100644 --- a/example/ML605/fpga_sgmii/fpga_240t/Makefile +++ b/example/ML605/fpga_sgmii/fpga_240t/Makefile @@ -41,7 +41,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_clk_gen.v SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_johnson_cntr.v SYN_FILES += coregen/gig_eth_pcs_pma_v11_5/gig_eth_pcs_pma_v11_5/example_design/sgmii_adapt/gig_eth_pcs_pma_v11_5_rx_rate_adapt.v diff --git a/example/ML605/fpga_sgmii/rtl/fpga_core.v b/example/ML605/fpga_sgmii/rtl/fpga_core.v index ef00064ca..57285c5ee 100644 --- a/example/ML605/fpga_sgmii/rtl/fpga_core.v +++ b/example/ML605/fpga_sgmii/rtl/fpga_core.v @@ -324,7 +324,9 @@ eth_mac_1g_fifo #( .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), - .RX_FIFO_ADDR_WIDTH(12) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) ) eth_mac_inst ( .rx_clk(phy_gmii_clk), @@ -560,31 +562,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk_125mhz), .rst(rst_125mhz), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/ML605/fpga_sgmii/tb/test_fpga_core.py b/example/ML605/fpga_sgmii/tb/test_fpga_core.py index 32db62f37..ddf35e258 100755 --- a/example/ML605/fpga_sgmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_sgmii/tb/test_fpga_core.py @@ -64,7 +64,7 @@ srcs.append("../lib/eth/rtl/eth_mux_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/NexysVideo/fpga/fpga/Makefile b/example/NexysVideo/fpga/fpga/Makefile index 3c4d634dd..7fc84a388 100644 --- a/example/NexysVideo/fpga/fpga/Makefile +++ b/example/NexysVideo/fpga/fpga/Makefile @@ -43,7 +43,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc diff --git a/example/NexysVideo/fpga/rtl/fpga_core.v b/example/NexysVideo/fpga/rtl/fpga_core.v index 06a6bdb5a..029b5a39c 100644 --- a/example/NexysVideo/fpga/rtl/fpga_core.v +++ b/example/NexysVideo/fpga/rtl/fpga_core.v @@ -318,7 +318,9 @@ eth_mac_1g_rgmii_fifo #( .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), - .RX_FIFO_ADDR_WIDTH(12) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) ) eth_mac_inst ( .gtx_clk(clk), @@ -549,31 +551,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.py b/example/NexysVideo/fpga/tb/test_fpga_core.py index b42e78d2f..a4569af8b 100755 --- a/example/NexysVideo/fpga/tb/test_fpga_core.py +++ b/example/NexysVideo/fpga/tb/test_fpga_core.py @@ -70,7 +70,7 @@ srcs.append("../lib/eth/rtl/eth_mux_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 8715ba573..998fb7f8f 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -44,8 +44,9 @@ SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_adapter.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_switch_4x4.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_switch.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_register.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index 667ddabb4..aad908db8 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -366,7 +366,9 @@ eth_mac_10g_fifo #( .ENABLE_DIC(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(9), - .RX_FIFO_ADDR_WIDTH(9) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(9), + .RX_FRAME_FIFO(1) ) eth_mac_10g_fifo_inst ( .rx_clk(clk), @@ -438,7 +440,9 @@ eth_mac_1g_fifo #( .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), - .RX_FIFO_ADDR_WIDTH(12) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) ) eth_mac_1g_inst ( .rx_clk(phy_gmii_clk), @@ -485,8 +489,8 @@ eth_mac_1g_inst ( ); axis_adapter #( - .INPUT_DATA_WIDTH(8), - .OUTPUT_DATA_WIDTH(64), + .S_DATA_WIDTH(8), + .M_DATA_WIDTH(64), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), @@ -496,24 +500,24 @@ gig_rx_axis_adapter_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(gig_rx_axis_tdata), - .input_axis_tkeep(1'b1), - .input_axis_tvalid(gig_rx_axis_tvalid), - .input_axis_tready(gig_rx_axis_tready), - .input_axis_tlast(gig_rx_axis_tlast), - .input_axis_tuser(gig_rx_axis_tuser), + .s_axis_tdata(gig_rx_axis_tdata), + .s_axis_tkeep(1'b1), + .s_axis_tvalid(gig_rx_axis_tvalid), + .s_axis_tready(gig_rx_axis_tready), + .s_axis_tlast(gig_rx_axis_tlast), + .s_axis_tuser(gig_rx_axis_tuser), // AXI output - .output_axis_tdata(gig_rx_axis_tdata_64), - .output_axis_tkeep(gig_rx_axis_tkeep_64), - .output_axis_tvalid(gig_rx_axis_tvalid_64), - .output_axis_tready(gig_rx_axis_tready_64), - .output_axis_tlast(gig_rx_axis_tlast_64), - .output_axis_tuser(gig_rx_axis_tuser_64) + .m_axis_tdata(gig_rx_axis_tdata_64), + .m_axis_tkeep(gig_rx_axis_tkeep_64), + .m_axis_tvalid(gig_rx_axis_tvalid_64), + .m_axis_tready(gig_rx_axis_tready_64), + .m_axis_tlast(gig_rx_axis_tlast_64), + .m_axis_tuser(gig_rx_axis_tuser_64) ); axis_adapter #( - .INPUT_DATA_WIDTH(64), - .OUTPUT_DATA_WIDTH(8), + .S_DATA_WIDTH(64), + .M_DATA_WIDTH(8), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), @@ -523,19 +527,19 @@ gig_tx_axis_adapter_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(gig_tx_axis_tdata_64), - .input_axis_tkeep(gig_tx_axis_tkeep_64), - .input_axis_tvalid(gig_tx_axis_tvalid_64), - .input_axis_tready(gig_tx_axis_tready_64), - .input_axis_tlast(gig_tx_axis_tlast_64), - .input_axis_tuser(gig_tx_axis_tuser_64), + .s_axis_tdata(gig_tx_axis_tdata_64), + .s_axis_tkeep(gig_tx_axis_tkeep_64), + .s_axis_tvalid(gig_tx_axis_tvalid_64), + .s_axis_tready(gig_tx_axis_tready_64), + .s_axis_tlast(gig_tx_axis_tlast_64), + .s_axis_tuser(gig_tx_axis_tuser_64), // AXI output - .output_axis_tdata(gig_tx_axis_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(gig_tx_axis_tvalid), - .output_axis_tready(gig_tx_axis_tready), - .output_axis_tlast(gig_tx_axis_tlast), - .output_axis_tuser(gig_tx_axis_tuser) + .m_axis_tdata(gig_tx_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(gig_tx_axis_tvalid), + .m_axis_tready(gig_tx_axis_tready), + .m_axis_tlast(gig_tx_axis_tlast), + .m_axis_tuser(gig_tx_axis_tuser) ); // tap port mux logic @@ -576,25 +580,20 @@ always @* begin end end -axis_switch_4x4 #( +axis_switch #( + .S_COUNT(3), + .M_COUNT(3), .DATA_WIDTH(64), .KEEP_WIDTH(8), .ID_ENABLE(0), .DEST_WIDTH(2), .USER_ENABLE(1), .USER_WIDTH(1), - .OUT_0_BASE(0), - .OUT_0_TOP(0), - .OUT_0_CONNECT(4'b1111), - .OUT_1_BASE(1), - .OUT_1_TOP(1), - .OUT_1_CONNECT(4'b1111), - .OUT_2_BASE(2), - .OUT_2_TOP(2), - .OUT_2_CONNECT(4'b1111), - .OUT_3_BASE(3), - .OUT_3_TOP(3), - .OUT_3_CONNECT(4'b1111), + .M_BASE({32'd2, 32'd1, 32'd0}), + .M_TOP({32'd2, 32'd1, 32'd0}), + .M_CONNECT({3{3'b111}}), + .S_REG_TYPE(0), + .M_REG_TYPE(1), .ARB_TYPE("PRIORITY"), .LSB_PRIORITY("HIGH") ) @@ -602,71 +601,23 @@ axis_switch_inst ( .clk(clk), .rst(rst), // AXI inputs - .input_0_axis_tdata(mac_rx_axis_tdata), - .input_0_axis_tkeep(mac_rx_axis_tkeep), - .input_0_axis_tvalid(mac_rx_axis_tvalid), - .input_0_axis_tready(mac_rx_axis_tready), - .input_0_axis_tlast(mac_rx_axis_tlast), - .input_0_axis_tid(0), - .input_0_axis_tdest(mac_rx_tdest), - .input_0_axis_tuser(mac_rx_axis_tuser), - .input_1_axis_tdata(tx_axis_tdata), - .input_1_axis_tkeep(tx_axis_tkeep), - .input_1_axis_tvalid(tx_axis_tvalid), - .input_1_axis_tready(tx_axis_tready), - .input_1_axis_tlast(tx_axis_tlast), - .input_1_axis_tid(0), - .input_1_axis_tdest(tx_tdest), - .input_1_axis_tuser(tx_axis_tuser), - .input_2_axis_tdata(gig_rx_axis_tdata_64), - .input_2_axis_tkeep(gig_rx_axis_tkeep_64), - .input_2_axis_tvalid(gig_rx_axis_tvalid_64), - .input_2_axis_tready(gig_rx_axis_tready_64), - .input_2_axis_tlast(gig_rx_axis_tlast_64), - .input_2_axis_tid(0), - .input_2_axis_tdest(gig_rx_tdest), - .input_2_axis_tuser(gig_rx_axis_tuser_64), - .input_3_axis_tdata(64'd0), - .input_3_axis_tkeep(8'd0), - .input_3_axis_tvalid(1'b0), - .input_3_axis_tready(), - .input_3_axis_tlast(1'b0), - .input_3_axis_tid(0), - .input_3_axis_tdest(2'd0), - .input_3_axis_tuser(1'b0), + .s_axis_tdata({ gig_rx_axis_tdata_64, tx_axis_tdata, mac_rx_axis_tdata}), + .s_axis_tkeep({ gig_rx_axis_tkeep_64, tx_axis_tkeep, mac_rx_axis_tkeep}), + .s_axis_tvalid({gig_rx_axis_tvalid_64, tx_axis_tvalid, mac_rx_axis_tvalid}), + .s_axis_tready({gig_rx_axis_tready_64, tx_axis_tready, mac_rx_axis_tready}), + .s_axis_tlast({ gig_rx_axis_tlast_64, tx_axis_tlast, mac_rx_axis_tlast}), + .s_axis_tid(0), + .s_axis_tdest({ gig_rx_tdest, tx_tdest, mac_rx_tdest}), + .s_axis_tuser({ gig_rx_axis_tuser_64, tx_axis_tuser, mac_rx_axis_tuser}), // AXI outputs - .output_0_axis_tdata(mac_tx_axis_tdata), - .output_0_axis_tkeep(mac_tx_axis_tkeep), - .output_0_axis_tvalid(mac_tx_axis_tvalid), - .output_0_axis_tready(mac_tx_axis_tready), - .output_0_axis_tlast(mac_tx_axis_tlast), - .output_0_axis_tid(), - .output_0_axis_tdest(), - .output_0_axis_tuser(mac_tx_axis_tuser), - .output_1_axis_tdata(rx_axis_tdata), - .output_1_axis_tkeep(rx_axis_tkeep), - .output_1_axis_tvalid(rx_axis_tvalid), - .output_1_axis_tready(rx_axis_tready), - .output_1_axis_tlast(rx_axis_tlast), - .output_1_axis_tid(), - .output_1_axis_tdest(), - .output_1_axis_tuser(rx_axis_tuser), - .output_2_axis_tdata(gig_tx_axis_tdata_64), - .output_2_axis_tkeep(gig_tx_axis_tkeep_64), - .output_2_axis_tvalid(gig_tx_axis_tvalid_64), - .output_2_axis_tready(gig_tx_axis_tready_64), - .output_2_axis_tlast(gig_tx_axis_tlast_64), - .output_2_axis_tid(), - .output_2_axis_tdest(), - .output_2_axis_tuser(gig_tx_axis_tuser_64), - .output_3_axis_tdata(), - .output_3_axis_tkeep(), - .output_3_axis_tvalid(), - .output_3_axis_tready(1'b1), - .output_3_axis_tlast(), - .output_3_axis_tid(), - .output_3_axis_tdest(), - .output_3_axis_tuser() + .m_axis_tdata({ gig_tx_axis_tdata_64, rx_axis_tdata, mac_tx_axis_tdata}), + .m_axis_tkeep({ gig_tx_axis_tkeep_64, rx_axis_tkeep, mac_tx_axis_tkeep}), + .m_axis_tvalid({gig_tx_axis_tvalid_64, rx_axis_tvalid, mac_tx_axis_tvalid}), + .m_axis_tready({gig_tx_axis_tready_64, rx_axis_tready, mac_tx_axis_tready}), + .m_axis_tlast({ gig_tx_axis_tlast_64, rx_axis_tlast, mac_tx_axis_tlast}), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser({ gig_tx_axis_tuser_64, rx_axis_tuser, mac_tx_axis_tuser}) ); eth_axis_rx_64 @@ -870,31 +821,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(rx_fifo_udp_payload_tkeep), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(tx_fifo_udp_payload_tkeep), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index b1dc4cfef..329c744a4 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -72,8 +72,9 @@ srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_adapter.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_switch_4x4.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_switch.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_register.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index 06fa804e2..0813b174f 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -37,7 +37,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v index f43f65acf..a04cf559f 100644 --- a/example/VCU108/fpga_1g/rtl/fpga_core.v +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -315,7 +315,9 @@ eth_mac_1g_fifo #( .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), - .RX_FIFO_ADDR_WIDTH(12) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) ) eth_mac_inst ( .rx_clk(phy_gmii_clk), @@ -551,31 +553,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py index 91a778681..11e9347d0 100755 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -64,7 +64,7 @@ srcs.append("../lib/eth/rtl/eth_mux_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile index ffd94c3b9..e3519532f 100644 --- a/example/VCU118/fpga_10g/fpga/Makefile +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -43,8 +43,9 @@ SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_adapter.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_switch_4x4.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_switch.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_register.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc diff --git a/example/VCU118/fpga_10g/rtl/fpga_core.v b/example/VCU118/fpga_10g/rtl/fpga_core.v index ec0e84300..21bca8105 100644 --- a/example/VCU118/fpga_10g/rtl/fpga_core.v +++ b/example/VCU118/fpga_10g/rtl/fpga_core.v @@ -423,7 +423,9 @@ eth_mac_10g_fifo #( .ENABLE_DIC(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(9), - .RX_FIFO_ADDR_WIDTH(9) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(9), + .RX_FRAME_FIFO(1) ) eth_mac_10g_fifo_inst ( .rx_clk(qsfp1_rx_clk_1), @@ -495,7 +497,9 @@ eth_mac_1g_fifo #( .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), - .RX_FIFO_ADDR_WIDTH(12) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) ) eth_mac_1g_inst ( .rx_clk(phy_gmii_clk), @@ -542,8 +546,8 @@ eth_mac_1g_inst ( ); axis_adapter #( - .INPUT_DATA_WIDTH(8), - .OUTPUT_DATA_WIDTH(64), + .S_DATA_WIDTH(8), + .M_DATA_WIDTH(64), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), @@ -553,24 +557,24 @@ gig_rx_axis_adapter_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(gig_rx_axis_tdata), - .input_axis_tkeep(1'b1), - .input_axis_tvalid(gig_rx_axis_tvalid), - .input_axis_tready(gig_rx_axis_tready), - .input_axis_tlast(gig_rx_axis_tlast), - .input_axis_tuser(gig_rx_axis_tuser), + .s_axis_tdata(gig_rx_axis_tdata), + .s_axis_tkeep(1'b1), + .s_axis_tvalid(gig_rx_axis_tvalid), + .s_axis_tready(gig_rx_axis_tready), + .s_axis_tlast(gig_rx_axis_tlast), + .s_axis_tuser(gig_rx_axis_tuser), // AXI output - .output_axis_tdata(gig_rx_axis_tdata_64), - .output_axis_tkeep(gig_rx_axis_tkeep_64), - .output_axis_tvalid(gig_rx_axis_tvalid_64), - .output_axis_tready(gig_rx_axis_tready_64), - .output_axis_tlast(gig_rx_axis_tlast_64), - .output_axis_tuser(gig_rx_axis_tuser_64) + .m_axis_tdata(gig_rx_axis_tdata_64), + .m_axis_tkeep(gig_rx_axis_tkeep_64), + .m_axis_tvalid(gig_rx_axis_tvalid_64), + .m_axis_tready(gig_rx_axis_tready_64), + .m_axis_tlast(gig_rx_axis_tlast_64), + .m_axis_tuser(gig_rx_axis_tuser_64) ); axis_adapter #( - .INPUT_DATA_WIDTH(64), - .OUTPUT_DATA_WIDTH(8), + .S_DATA_WIDTH(64), + .M_DATA_WIDTH(8), .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), @@ -580,19 +584,19 @@ gig_tx_axis_adapter_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(gig_tx_axis_tdata_64), - .input_axis_tkeep(gig_tx_axis_tkeep_64), - .input_axis_tvalid(gig_tx_axis_tvalid_64), - .input_axis_tready(gig_tx_axis_tready_64), - .input_axis_tlast(gig_tx_axis_tlast_64), - .input_axis_tuser(gig_tx_axis_tuser_64), + .s_axis_tdata(gig_tx_axis_tdata_64), + .s_axis_tkeep(gig_tx_axis_tkeep_64), + .s_axis_tvalid(gig_tx_axis_tvalid_64), + .s_axis_tready(gig_tx_axis_tready_64), + .s_axis_tlast(gig_tx_axis_tlast_64), + .s_axis_tuser(gig_tx_axis_tuser_64), // AXI output - .output_axis_tdata(gig_tx_axis_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(gig_tx_axis_tvalid), - .output_axis_tready(gig_tx_axis_tready), - .output_axis_tlast(gig_tx_axis_tlast), - .output_axis_tuser(gig_tx_axis_tuser) + .m_axis_tdata(gig_tx_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(gig_tx_axis_tvalid), + .m_axis_tready(gig_tx_axis_tready), + .m_axis_tlast(gig_tx_axis_tlast), + .m_axis_tuser(gig_tx_axis_tuser) ); // tap port mux logic @@ -633,25 +637,20 @@ always @* begin end end -axis_switch_4x4 #( +axis_switch #( + .S_COUNT(3), + .M_COUNT(3), .DATA_WIDTH(64), .KEEP_WIDTH(8), .ID_ENABLE(0), .DEST_WIDTH(2), .USER_ENABLE(1), .USER_WIDTH(1), - .OUT_0_BASE(0), - .OUT_0_TOP(0), - .OUT_0_CONNECT(4'b1111), - .OUT_1_BASE(1), - .OUT_1_TOP(1), - .OUT_1_CONNECT(4'b1111), - .OUT_2_BASE(2), - .OUT_2_TOP(2), - .OUT_2_CONNECT(4'b1111), - .OUT_3_BASE(3), - .OUT_3_TOP(3), - .OUT_3_CONNECT(4'b1111), + .M_BASE({32'd2, 32'd1, 32'd0}), + .M_TOP({32'd2, 32'd1, 32'd0}), + .M_CONNECT({3{3'b111}}), + .S_REG_TYPE(0), + .M_REG_TYPE(1), .ARB_TYPE("PRIORITY"), .LSB_PRIORITY("HIGH") ) @@ -659,71 +658,23 @@ axis_switch_inst ( .clk(clk), .rst(rst), // AXI inputs - .input_0_axis_tdata(mac_rx_axis_tdata), - .input_0_axis_tkeep(mac_rx_axis_tkeep), - .input_0_axis_tvalid(mac_rx_axis_tvalid), - .input_0_axis_tready(mac_rx_axis_tready), - .input_0_axis_tlast(mac_rx_axis_tlast), - .input_0_axis_tid(0), - .input_0_axis_tdest(mac_rx_tdest), - .input_0_axis_tuser(mac_rx_axis_tuser), - .input_1_axis_tdata(tx_axis_tdata), - .input_1_axis_tkeep(tx_axis_tkeep), - .input_1_axis_tvalid(tx_axis_tvalid), - .input_1_axis_tready(tx_axis_tready), - .input_1_axis_tlast(tx_axis_tlast), - .input_1_axis_tid(0), - .input_1_axis_tdest(tx_tdest), - .input_1_axis_tuser(tx_axis_tuser), - .input_2_axis_tdata(gig_rx_axis_tdata_64), - .input_2_axis_tkeep(gig_rx_axis_tkeep_64), - .input_2_axis_tvalid(gig_rx_axis_tvalid_64), - .input_2_axis_tready(gig_rx_axis_tready_64), - .input_2_axis_tlast(gig_rx_axis_tlast_64), - .input_2_axis_tid(0), - .input_2_axis_tdest(gig_rx_tdest), - .input_2_axis_tuser(gig_rx_axis_tuser_64), - .input_3_axis_tdata(64'd0), - .input_3_axis_tkeep(8'd0), - .input_3_axis_tvalid(1'b0), - .input_3_axis_tready(), - .input_3_axis_tlast(1'b0), - .input_3_axis_tid(0), - .input_3_axis_tdest(2'd0), - .input_3_axis_tuser(1'b0), + .s_axis_tdata({ gig_rx_axis_tdata_64, tx_axis_tdata, mac_rx_axis_tdata}), + .s_axis_tkeep({ gig_rx_axis_tkeep_64, tx_axis_tkeep, mac_rx_axis_tkeep}), + .s_axis_tvalid({gig_rx_axis_tvalid_64, tx_axis_tvalid, mac_rx_axis_tvalid}), + .s_axis_tready({gig_rx_axis_tready_64, tx_axis_tready, mac_rx_axis_tready}), + .s_axis_tlast({ gig_rx_axis_tlast_64, tx_axis_tlast, mac_rx_axis_tlast}), + .s_axis_tid(0), + .s_axis_tdest({ gig_rx_tdest, tx_tdest, mac_rx_tdest}), + .s_axis_tuser({ gig_rx_axis_tuser_64, tx_axis_tuser, mac_rx_axis_tuser}), // AXI outputs - .output_0_axis_tdata(mac_tx_axis_tdata), - .output_0_axis_tkeep(mac_tx_axis_tkeep), - .output_0_axis_tvalid(mac_tx_axis_tvalid), - .output_0_axis_tready(mac_tx_axis_tready), - .output_0_axis_tlast(mac_tx_axis_tlast), - .output_0_axis_tid(), - .output_0_axis_tdest(), - .output_0_axis_tuser(mac_tx_axis_tuser), - .output_1_axis_tdata(rx_axis_tdata), - .output_1_axis_tkeep(rx_axis_tkeep), - .output_1_axis_tvalid(rx_axis_tvalid), - .output_1_axis_tready(rx_axis_tready), - .output_1_axis_tlast(rx_axis_tlast), - .output_1_axis_tid(), - .output_1_axis_tdest(), - .output_1_axis_tuser(rx_axis_tuser), - .output_2_axis_tdata(gig_tx_axis_tdata_64), - .output_2_axis_tkeep(gig_tx_axis_tkeep_64), - .output_2_axis_tvalid(gig_tx_axis_tvalid_64), - .output_2_axis_tready(gig_tx_axis_tready_64), - .output_2_axis_tlast(gig_tx_axis_tlast_64), - .output_2_axis_tid(), - .output_2_axis_tdest(), - .output_2_axis_tuser(gig_tx_axis_tuser_64), - .output_3_axis_tdata(), - .output_3_axis_tkeep(), - .output_3_axis_tvalid(), - .output_3_axis_tready(1'b1), - .output_3_axis_tlast(), - .output_3_axis_tid(), - .output_3_axis_tdest(), - .output_3_axis_tuser() + .m_axis_tdata({ gig_tx_axis_tdata_64, rx_axis_tdata, mac_tx_axis_tdata}), + .m_axis_tkeep({ gig_tx_axis_tkeep_64, rx_axis_tkeep, mac_tx_axis_tkeep}), + .m_axis_tvalid({gig_tx_axis_tvalid_64, rx_axis_tvalid, mac_tx_axis_tvalid}), + .m_axis_tready({gig_tx_axis_tready_64, rx_axis_tready, mac_tx_axis_tready}), + .m_axis_tlast({ gig_tx_axis_tlast_64, rx_axis_tlast, mac_tx_axis_tlast}), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser({ gig_tx_axis_tuser_64, rx_axis_tuser, mac_tx_axis_tuser}) ); eth_axis_rx_64 @@ -927,31 +878,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(rx_fifo_udp_payload_tkeep), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(tx_fifo_udp_payload_tkeep), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/VCU118/fpga_10g/tb/test_fpga_core.py b/example/VCU118/fpga_10g/tb/test_fpga_core.py index 87f8c3db5..b692d2b32 100755 --- a/example/VCU118/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU118/fpga_10g/tb/test_fpga_core.py @@ -72,8 +72,9 @@ srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_adapter.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_switch_4x4.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_switch.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_register.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) diff --git a/example/VCU118/fpga_1g/fpga/Makefile b/example/VCU118/fpga_1g/fpga/Makefile index d97bfee7a..ce1fcc41f 100644 --- a/example/VCU118/fpga_1g/fpga/Makefile +++ b/example/VCU118/fpga_1g/fpga/Makefile @@ -38,7 +38,7 @@ SYN_FILES += lib/eth/rtl/eth_mux_2.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v -SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc diff --git a/example/VCU118/fpga_1g/rtl/fpga_core.v b/example/VCU118/fpga_1g/rtl/fpga_core.v index f43f65acf..a04cf559f 100644 --- a/example/VCU118/fpga_1g/rtl/fpga_core.v +++ b/example/VCU118/fpga_1g/rtl/fpga_core.v @@ -315,7 +315,9 @@ eth_mac_1g_fifo #( .ENABLE_PADDING(1), .MIN_FRAME_LENGTH(64), .TX_FIFO_ADDR_WIDTH(12), - .RX_FIFO_ADDR_WIDTH(12) + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) ) eth_mac_inst ( .rx_clk(phy_gmii_clk), @@ -551,31 +553,37 @@ axis_fifo #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .USER_WIDTH(1) + .USER_WIDTH(1), + .FRAME_FIFO(0) ) udp_payload_fifo ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_fifo_udp_payload_tdata), - .input_axis_tkeep(0), - .input_axis_tvalid(rx_fifo_udp_payload_tvalid), - .input_axis_tready(rx_fifo_udp_payload_tready), - .input_axis_tlast(rx_fifo_udp_payload_tlast), - .input_axis_tid(0), - .input_axis_tdest(0), - .input_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_udp_payload_tvalid), + .s_axis_tready(rx_fifo_udp_payload_tready), + .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_tuser), // AXI output - .output_axis_tdata(tx_fifo_udp_payload_tdata), - .output_axis_tkeep(), - .output_axis_tvalid(tx_fifo_udp_payload_tvalid), - .output_axis_tready(tx_fifo_udp_payload_tready), - .output_axis_tlast(tx_fifo_udp_payload_tlast), - .output_axis_tid(), - .output_axis_tdest(), - .output_axis_tuser(tx_fifo_udp_payload_tuser) + .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_udp_payload_tvalid), + .m_axis_tready(tx_fifo_udp_payload_tready), + .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() ); endmodule diff --git a/example/VCU118/fpga_1g/tb/test_fpga_core.py b/example/VCU118/fpga_1g/tb/test_fpga_core.py index 91a778681..11e9347d0 100755 --- a/example/VCU118/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU118/fpga_1g/tb/test_fpga_core.py @@ -64,7 +64,7 @@ srcs.append("../lib/eth/rtl/eth_mux_2.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") srcs.append("%s.v" % testbench) src = ' '.join(srcs) From c08026277e78815c827e857f2defeb414e4968ee Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 Oct 2018 13:42:08 -0700 Subject: [PATCH 455/617] Fix source pause logic --- tb/arp_ep.py | 62 ++++++++++++++++++++------------------ tb/eth_ep.py | 48 ++++++++++++++++-------------- tb/ip_ep.py | 76 +++++++++++++++++++++++++---------------------- tb/udp_ep.py | 84 +++++++++++++++++++++++++++------------------------- 4 files changed, 144 insertions(+), 126 deletions(-) diff --git a/tb/arp_ep.py b/tb/arp_ep.py index 22a4197e4..977cf1411 100644 --- a/tb/arp_ep.py +++ b/tb/arp_ep.py @@ -158,8 +158,10 @@ class ARPFrame(object): class ARPFrameSource(): def __init__(self): + self.active = False self.has_logic = False self.queue = [] + self.clk = Signal(bool(0)) def send(self, frame): self.queue.append(ARPFrame(frame)) @@ -170,6 +172,13 @@ class ARPFrameSource(): def empty(self): return not self.queue + def idle(self): + return not self.queue and not self.active + + def wait(self): + while not self.idle(): + yield self.clk.posedge + def create_logic(self, clk, rst, @@ -195,13 +204,7 @@ class ARPFrameSource(): self.has_logic = True - frame_ready_int = Signal(bool(False)) - frame_valid_int = Signal(bool(False)) - - @always_comb - def pause_logic(): - frame_ready_int.next = frame_ready and not pause - frame_valid.next = frame_valid_int and not pause + self.clk = clk @instance def logic(): @@ -211,30 +214,33 @@ class ARPFrameSource(): yield clk.posedge, rst.posedge if rst: - frame_valid_int.next = False + frame_valid.next = False + self.active = False else: - if frame_ready_int: - frame_valid_int.next = False - if (frame_ready_int and frame_valid) or not frame_valid_int: - if self.queue: - frame = self.queue.pop(0) - eth_dest_mac.next = frame.eth_dest_mac - eth_src_mac.next = frame.eth_src_mac - eth_type.next = frame.eth_type - arp_htype.next = frame.arp_htype - arp_ptype.next = frame.arp_ptype - arp_hlen.next = frame.arp_hlen - arp_plen.next = frame.arp_plen - arp_oper.next = frame.arp_oper - arp_sha.next = frame.arp_sha - arp_spa.next = frame.arp_spa - arp_tha.next = frame.arp_tha - arp_tpa.next = frame.arp_tpa + frame_valid.next = self.active and (frame_valid or not pause) + if frame_ready and frame_valid: + frame_valid.next = False + self.active = False + if not self.active and self.queue: + frame = self.queue.pop(0) + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + arp_htype.next = frame.arp_htype + arp_ptype.next = frame.arp_ptype + arp_hlen.next = frame.arp_hlen + arp_plen.next = frame.arp_plen + arp_oper.next = frame.arp_oper + arp_sha.next = frame.arp_sha + arp_spa.next = frame.arp_spa + arp_tha.next = frame.arp_tha + arp_tpa.next = frame.arp_tpa - if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) - frame_valid_int.next = True + frame_valid.next = not pause + self.active = True return instances() diff --git a/tb/eth_ep.py b/tb/eth_ep.py index 431c09958..f7dd3f1a3 100644 --- a/tb/eth_ep.py +++ b/tb/eth_ep.py @@ -122,10 +122,12 @@ class EthFrame(object): class EthFrameSource(): def __init__(self): + self.active = False self.has_logic = False self.queue = [] self.payload_source = axis_ep.AXIStreamSource() self.header_queue = [] + self.clk = Signal(bool(0)) def send(self, frame): frame = EthFrame(frame) @@ -141,6 +143,13 @@ class EthFrameSource(): def empty(self): return not self.queue + def idle(self): + return not self.queue and not self.active and self.payload_source.idle() + + def wait(self): + while not self.idle(): + yield self.clk.posedge + def create_logic(self, clk, rst, @@ -163,9 +172,7 @@ class EthFrameSource(): self.has_logic = True - eth_hdr_ready_int = Signal(bool(False)) - eth_hdr_valid_int = Signal(bool(False)) - eth_payload_pause = Signal(bool(False)) + self.clk = clk eth_payload_source = self.payload_source.create_logic( clk=clk, @@ -176,15 +183,9 @@ class EthFrameSource(): tready=eth_payload_tready, tlast=eth_payload_tlast, tuser=eth_payload_tuser, - pause=eth_payload_pause, + pause=pause, ) - @always_comb - def pause_logic(): - eth_hdr_ready_int.next = eth_hdr_ready and not pause - eth_hdr_valid.next = eth_hdr_valid_int and not pause - eth_payload_pause.next = pause # or eth_hdr_valid_int - @instance def logic(): frame = EthFrame() @@ -193,21 +194,24 @@ class EthFrameSource(): yield clk.posedge, rst.posedge if rst: - eth_hdr_valid_int.next = False + eth_hdr_valid.next = False + self.active = False else: - if eth_hdr_ready_int: - eth_hdr_valid_int.next = False - if (eth_hdr_ready_int and eth_hdr_valid) or not eth_hdr_valid_int: - if self.header_queue: - frame = self.header_queue.pop(0) - eth_dest_mac.next = frame.eth_dest_mac - eth_src_mac.next = frame.eth_src_mac - eth_type.next = frame.eth_type + eth_hdr_valid.next = self.active and (eth_hdr_valid or not pause) + if eth_hdr_ready and eth_hdr_valid: + eth_hdr_valid.next = False + self.active = False + if not self.active and self.header_queue: + frame = self.header_queue.pop(0) + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type - if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) - eth_hdr_valid_int.next = True + eth_hdr_valid.next = not pause + self.active = True if self.queue and not self.header_queue: frame = self.queue.pop(0) diff --git a/tb/ip_ep.py b/tb/ip_ep.py index 46b0e30ed..4afcaea26 100644 --- a/tb/ip_ep.py +++ b/tb/ip_ep.py @@ -239,10 +239,12 @@ class IPFrame(object): class IPFrameSource(): def __init__(self): + self.active = False self.has_logic = False self.queue = [] self.payload_source = axis_ep.AXIStreamSource() self.header_queue = [] + self.clk = Signal(bool(0)) def send(self, frame): frame = IPFrame(frame) @@ -258,6 +260,13 @@ class IPFrameSource(): def empty(self): return not self.queue + def idle(self): + return not self.queue and not self.active and self.payload_source.idle() + + def wait(self): + while not self.idle(): + yield self.clk.posedge + def create_logic(self, clk, rst, @@ -293,9 +302,7 @@ class IPFrameSource(): self.has_logic = True - ip_hdr_ready_int = Signal(bool(False)) - ip_hdr_valid_int = Signal(bool(False)) - ip_payload_pause = Signal(bool(False)) + self.clk = clk ip_payload_source = self.payload_source.create_logic( clk=clk, @@ -306,50 +313,47 @@ class IPFrameSource(): tready=ip_payload_tready, tlast=ip_payload_tlast, tuser=ip_payload_tuser, - pause=ip_payload_pause, + pause=pause, ) - @always_comb - def pause_logic(): - ip_hdr_ready_int.next = ip_hdr_ready and not pause - ip_hdr_valid.next = ip_hdr_valid_int and not pause - ip_payload_pause.next = pause - @instance def logic(): while True: yield clk.posedge, rst.posedge if rst: - ip_hdr_valid_int.next = False + ip_hdr_valid.next = False + self.active = False else: - if ip_hdr_ready_int: - ip_hdr_valid_int.next = False - if (ip_hdr_ready_int and ip_hdr_valid) or not ip_hdr_valid_int: - if self.header_queue: - frame = self.header_queue.pop(0) - frame.build() - eth_dest_mac.next = frame.eth_dest_mac - eth_src_mac.next = frame.eth_src_mac - eth_type.next = frame.eth_type - ip_version.next = frame.ip_version - ip_ihl.next = frame.ip_ihl - ip_dscp.next = frame.ip_dscp - ip_ecn.next = frame.ip_ecn - ip_length.next = frame.ip_length - ip_identification.next = frame.ip_identification - ip_flags.next = frame.ip_flags - ip_fragment_offset.next = frame.ip_fragment_offset - ip_ttl.next = frame.ip_ttl - ip_protocol.next = frame.ip_protocol - ip_header_checksum.next = frame.ip_header_checksum - ip_source_ip.next = frame.ip_source_ip - ip_dest_ip.next = frame.ip_dest_ip + ip_hdr_valid.next = self.active and (ip_hdr_valid or not pause) + if ip_hdr_ready and ip_hdr_valid: + ip_hdr_valid.next = False + self.active = False + if not self.active and self.header_queue: + frame = self.header_queue.pop(0) + frame.build() + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + ip_version.next = frame.ip_version + ip_ihl.next = frame.ip_ihl + ip_dscp.next = frame.ip_dscp + ip_ecn.next = frame.ip_ecn + ip_length.next = frame.ip_length + ip_identification.next = frame.ip_identification + ip_flags.next = frame.ip_flags + ip_fragment_offset.next = frame.ip_fragment_offset + ip_ttl.next = frame.ip_ttl + ip_protocol.next = frame.ip_protocol + ip_header_checksum.next = frame.ip_header_checksum + ip_source_ip.next = frame.ip_source_ip + ip_dest_ip.next = frame.ip_dest_ip - if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) - ip_hdr_valid_int.next = True + ip_hdr_valid.next = not pause + self.active = True if self.queue and not self.header_queue: frame = self.queue.pop(0) diff --git a/tb/udp_ep.py b/tb/udp_ep.py index 1edaaf3f4..0a3d156c5 100644 --- a/tb/udp_ep.py +++ b/tb/udp_ep.py @@ -324,10 +324,12 @@ class UDPFrame(object): class UDPFrameSource(): def __init__(self): + self.active = False self.has_logic = False self.queue = [] self.payload_source = axis_ep.AXIStreamSource() self.header_queue = [] + self.clk = Signal(bool(0)) def send(self, frame): frame = UDPFrame(frame) @@ -343,6 +345,13 @@ class UDPFrameSource(): def empty(self): return not self.queue + def idle(self): + return not self.queue and not self.active and self.payload_source.idle() + + def wait(self): + while not self.idle(): + yield self.clk.posedge + def create_logic(self, clk, rst, @@ -382,9 +391,7 @@ class UDPFrameSource(): self.has_logic = True - udp_hdr_ready_int = Signal(bool(False)) - udp_hdr_valid_int = Signal(bool(False)) - udp_payload_pause = Signal(bool(False)) + self.clk = clk udp_payload_source = self.payload_source.create_logic( clk=clk, @@ -395,54 +402,51 @@ class UDPFrameSource(): tready=udp_payload_tready, tlast=udp_payload_tlast, tuser=udp_payload_tuser, - pause=udp_payload_pause, + pause=pause, ) - @always_comb - def pause_logic(): - udp_hdr_ready_int.next = udp_hdr_ready and not pause - udp_hdr_valid.next = udp_hdr_valid_int and not pause - udp_payload_pause.next = pause - @instance def logic(): while True: yield clk.posedge, rst.posedge if rst: - udp_hdr_valid_int.next = False + udp_hdr_valid.next = False + self.active = False else: - if udp_hdr_ready_int: - udp_hdr_valid_int.next = False - if (udp_hdr_ready_int and udp_hdr_valid) or not udp_hdr_valid_int: - if self.header_queue: - frame = self.header_queue.pop(0) - frame.build() - eth_dest_mac.next = frame.eth_dest_mac - eth_src_mac.next = frame.eth_src_mac - eth_type.next = frame.eth_type - ip_version.next = frame.ip_version - ip_ihl.next = frame.ip_ihl - ip_dscp.next = frame.ip_dscp - ip_ecn.next = frame.ip_ecn - ip_length.next = frame.ip_length - ip_identification.next = frame.ip_identification - ip_flags.next = frame.ip_flags - ip_fragment_offset.next = frame.ip_fragment_offset - ip_ttl.next = frame.ip_ttl - ip_protocol.next = frame.ip_protocol - ip_header_checksum.next = frame.ip_header_checksum - ip_source_ip.next = frame.ip_source_ip - ip_dest_ip.next = frame.ip_dest_ip - udp_source_port.next = frame.udp_source_port - udp_dest_port.next = frame.udp_dest_port - udp_length.next = frame.udp_length - udp_checksum.next = frame.udp_checksum + udp_hdr_valid.next = self.active and (udp_hdr_valid or not pause) + if udp_hdr_ready and udp_hdr_valid: + udp_hdr_valid.next = False + self.active = False + if not self.active and self.header_queue: + frame = self.header_queue.pop(0) + frame.build() + eth_dest_mac.next = frame.eth_dest_mac + eth_src_mac.next = frame.eth_src_mac + eth_type.next = frame.eth_type + ip_version.next = frame.ip_version + ip_ihl.next = frame.ip_ihl + ip_dscp.next = frame.ip_dscp + ip_ecn.next = frame.ip_ecn + ip_length.next = frame.ip_length + ip_identification.next = frame.ip_identification + ip_flags.next = frame.ip_flags + ip_fragment_offset.next = frame.ip_fragment_offset + ip_ttl.next = frame.ip_ttl + ip_protocol.next = frame.ip_protocol + ip_header_checksum.next = frame.ip_header_checksum + ip_source_ip.next = frame.ip_source_ip + ip_dest_ip.next = frame.ip_dest_ip + udp_source_port.next = frame.udp_source_port + udp_dest_port.next = frame.udp_dest_port + udp_length.next = frame.udp_length + udp_checksum.next = frame.udp_checksum - if name is not None: - print("[%s] Sending frame %s" % (name, repr(frame))) + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) - udp_hdr_valid_int.next = True + udp_hdr_valid.next = not pause + self.active = True if self.queue and not self.header_queue: frame = self.queue.pop(0) From 68abccd0a1312ef2f69049503a83c37770d2d65c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 Oct 2018 13:42:33 -0700 Subject: [PATCH 456/617] Workaround for MyHDL race condition --- tb/test_ip_eth_rx_64.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py index f12b0ae38..94efbcee4 100755 --- a/tb/test_ip_eth_rx_64.py +++ b/tb/test_ip_eth_rx_64.py @@ -286,6 +286,7 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -345,11 +346,13 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -411,12 +414,14 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -478,11 +483,13 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -544,11 +551,13 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -611,12 +620,14 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -679,12 +690,14 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -748,12 +761,14 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -817,12 +832,14 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame.payload.user[-1] assert error_payload_early_termination_asserted + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -884,6 +901,7 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -947,6 +965,7 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -1013,6 +1032,7 @@ def bench(): yield wait() + yield clk.posedge yield sink.wait() rx_frame = sink.recv() From d28d459d7048378acc57caceb8e6a0657fd09969 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 Oct 2018 15:48:12 -0700 Subject: [PATCH 457/617] Convert generated eth_mux to verilog parametrized module --- rtl/eth_mux.py | 374 ----------------------------------- rtl/eth_mux.v | 299 ++++++++++++++++++++++++++++ rtl/eth_mux_2.v | 332 ------------------------------- rtl/eth_mux_4.v | 404 -------------------------------------- rtl/eth_mux_64.py | 387 ------------------------------------ rtl/eth_mux_64_2.v | 347 -------------------------------- rtl/eth_mux_64_4.v | 423 ---------------------------------------- tb/test_eth_mux_4.py | 348 +++++++++++++-------------------- tb/test_eth_mux_4.v | 255 ++++++++++-------------- tb/test_eth_mux_64_4.py | 363 +++++++++++++--------------------- tb/test_eth_mux_64_4.v | 270 ++++++++++--------------- 11 files changed, 781 insertions(+), 3021 deletions(-) delete mode 100755 rtl/eth_mux.py create mode 100644 rtl/eth_mux.v delete mode 100644 rtl/eth_mux_2.v delete mode 100644 rtl/eth_mux_4.v delete mode 100755 rtl/eth_mux_64.py delete mode 100644 rtl/eth_mux_64_2.v delete mode 100644 rtl/eth_mux_64_4.v diff --git a/rtl/eth_mux.py b/rtl/eth_mux.py deleted file mode 100755 index 204c1d068..000000000 --- a/rtl/eth_mux.py +++ /dev/null @@ -1,374 +0,0 @@ -#!/usr/bin/env python -""" -Generates an Ethernet mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "eth_mux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port Ethernet mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet {{n}} port multiplexer - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_eth_hdr_valid, - output wire input_{{p}}_eth_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [7:0] input_{{p}}_eth_payload_tdata, - input wire input_{{p}}_eth_payload_tvalid, - output wire input_{{p}}_eth_payload_tready, - input wire input_{{p}}_eth_payload_tlast, - input wire input_{{p}}_eth_payload_tuser, -{% endfor %} - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; -{% for p in ports %} -reg input_{{p}}_eth_hdr_ready_reg = 1'b0, input_{{p}}_eth_hdr_ready_next; -{%- endfor %} -{% for p in ports %} -reg input_{{p}}_eth_payload_tready_reg = 1'b0, input_{{p}}_eth_payload_tready_next; -{%- endfor %} - -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; - -// internal datapath -reg [7:0] output_eth_payload_tdata_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; -{% for p in ports %} -assign input_{{p}}_eth_hdr_ready = input_{{p}}_eth_hdr_ready_reg; -{%- endfor %} -{% for p in ports %} -assign input_{{p}}_eth_payload_tready = input_{{p}}_eth_payload_tready_reg; -{%- endfor %} - -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; - -// mux for start of packet detection -reg selected_input_eth_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -always @* begin - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: begin - selected_input_eth_hdr_valid = input_{{p}}_eth_hdr_valid; - selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; - selected_input_eth_src_mac = input_{{p}}_eth_src_mac; - selected_input_eth_type = input_{{p}}_eth_type; - end -{%- endfor %} - default: begin - selected_input_eth_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - end - endcase -end - -// mux for incoming packet -reg [7:0] current_input_tdata; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_input_tdata = input_{{p}}_eth_payload_tdata; - current_input_tvalid = input_{{p}}_eth_payload_tvalid; - current_input_tready = input_{{p}}_eth_payload_tready; - current_input_tlast = input_{{p}}_eth_payload_tlast; - current_input_tuser = input_{{p}}_eth_payload_tuser; - end -{%- endfor %} - default: begin - current_input_tdata = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; -{% for p in ports %} - input_{{p}}_eth_hdr_ready_next = input_{{p}}_eth_hdr_ready_reg & ~input_{{p}}_eth_hdr_valid; -{%- endfor %} -{% for p in ports %} - input_{{p}}_eth_payload_tready_next = 1'b0; -{%- endfor %} - - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_eth_hdr_ready_next = 1'b1; -{%- endfor %} - endcase - - output_eth_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - end - - // generate ready signal on selected port - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; -{%- endfor %} - endcase - - // pass through selected packet data - output_eth_payload_tdata_int = current_input_tdata; - output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_eth_payload_tlast_int = current_input_tlast; - output_eth_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; -{%- for p in ports %} - input_{{p}}_eth_hdr_ready_reg <= 1'b0; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_eth_payload_tready_reg <= 1'b0; -{%- endfor %} - output_eth_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; -{%- for p in ports %} - input_{{p}}_eth_hdr_ready_reg <= input_{{p}}_eth_hdr_ready_next; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_eth_payload_tready_reg <= input_{{p}}_eth_payload_tready_next; -{%- endfor %} - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; -end - -// output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; - -reg [7:0] temp_eth_payload_tdata_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; - -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; - - if (output_eth_payload_tready_int_reg) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; - end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/eth_mux.v b/rtl/eth_mux.v new file mode 100644 index 000000000..4fe32659d --- /dev/null +++ b/rtl/eth_mux.v @@ -0,0 +1,299 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Ethernet multiplexer + */ +module eth_mux # +( + parameter S_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ + input wire [S_COUNT-1:0] s_eth_hdr_valid, + output wire [S_COUNT-1:0] s_eth_hdr_ready, + input wire [S_COUNT*48-1:0] s_eth_dest_mac, + input wire [S_COUNT*48-1:0] s_eth_src_mac, + input wire [S_COUNT*16-1:0] s_eth_type, + input wire [S_COUNT*DATA_WIDTH-1:0] s_eth_payload_axis_tdata, + input wire [S_COUNT*KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep, + input wire [S_COUNT-1:0] s_eth_payload_axis_tvalid, + output wire [S_COUNT-1:0] s_eth_payload_axis_tready, + input wire [S_COUNT-1:0] s_eth_payload_axis_tlast, + input wire [S_COUNT*ID_WIDTH-1:0] s_eth_payload_axis_tid, + input wire [S_COUNT*DEST_WIDTH-1:0] s_eth_payload_axis_tdest, + input wire [S_COUNT*USER_WIDTH-1:0] s_eth_payload_axis_tuser, + + /* + * Ethernet frame output + */ + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [DATA_WIDTH-1:0] m_eth_payload_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire [ID_WIDTH-1:0] m_eth_payload_axis_tid, + output wire [DEST_WIDTH-1:0] m_eth_payload_axis_tdest, + output wire [USER_WIDTH-1:0] m_eth_payload_axis_tuser, + + /* + * Control + */ + input wire enable, + input wire [$clog2(S_COUNT)-1:0] select +); + +parameter CL_S_COUNT = $clog2(S_COUNT); + +reg [CL_S_COUNT-1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; + +reg [S_COUNT-1:0] s_eth_hdr_ready_reg = 0, s_eth_hdr_ready_next; + +reg [S_COUNT-1:0] s_eth_payload_axis_tready_reg = 0, s_eth_payload_axis_tready_next; + +reg m_eth_hdr_valid_reg = 1'b0, m_eth_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0, m_eth_dest_mac_next; +reg [47:0] m_eth_src_mac_reg = 48'd0, m_eth_src_mac_next; +reg [15:0] m_eth_type_reg = 16'd0, m_eth_type_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_eth_payload_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep_int; +reg m_eth_payload_axis_tvalid_int; +reg m_eth_payload_axis_tready_int_reg = 1'b0; +reg m_eth_payload_axis_tlast_int; +reg [ID_WIDTH-1:0] m_eth_payload_axis_tid_int; +reg [DEST_WIDTH-1:0] m_eth_payload_axis_tdest_int; +reg [USER_WIDTH-1:0] m_eth_payload_axis_tuser_int; +wire m_eth_payload_axis_tready_int_early; + +assign s_eth_hdr_ready = s_eth_hdr_ready_reg; + +assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; + +assign m_eth_hdr_valid = m_eth_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; + +// mux for incoming packet +wire [DATA_WIDTH-1:0] current_s_tdata = s_eth_payload_axis_tdata[select_reg*DATA_WIDTH +: DATA_WIDTH]; +wire [KEEP_WIDTH-1:0] current_s_tkeep = s_eth_payload_axis_tkeep[select_reg*KEEP_WIDTH +: KEEP_WIDTH]; +wire current_s_tvalid = s_eth_payload_axis_tvalid[select_reg]; +wire current_s_tready = s_eth_payload_axis_tready[select_reg]; +wire current_s_tlast = s_eth_payload_axis_tlast[select_reg]; +wire [ID_WIDTH-1:0] current_s_tid = s_eth_payload_axis_tid[select_reg*ID_WIDTH +: ID_WIDTH]; +wire [DEST_WIDTH-1:0] current_s_tdest = s_eth_payload_axis_tdest[select_reg*DEST_WIDTH +: DEST_WIDTH]; +wire [USER_WIDTH-1:0] current_s_tuser = s_eth_payload_axis_tuser[select_reg*USER_WIDTH +: USER_WIDTH]; + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + s_eth_hdr_ready_next = 0; + + s_eth_payload_axis_tready_next = 0; + + m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; + m_eth_dest_mac_next = m_eth_dest_mac_reg; + m_eth_src_mac_next = m_eth_src_mac_reg; + m_eth_type_next = m_eth_type_reg; + + if (current_s_tvalid & current_s_tready) begin + // end of frame detection + if (current_s_tlast) begin + frame_next = 1'b0; + end + end + + if (!frame_reg && enable && !m_eth_hdr_valid && (s_eth_hdr_valid & (1 << select))) begin + // start of frame, grab select value + frame_next = 1'b1; + select_next = select; + + s_eth_hdr_ready_next = (1 << select); + + m_eth_hdr_valid_next = 1'b1; + m_eth_dest_mac_next = s_eth_dest_mac[select*48 +: 48]; + m_eth_src_mac_next = s_eth_src_mac[select*48 +: 48]; + m_eth_type_next = s_eth_type[select*16 +: 16]; + end + + // generate ready signal on selected port + s_eth_payload_axis_tready_next = (m_eth_payload_axis_tready_int_early && frame_next) << select_next; + + // pass through selected packet data + m_eth_payload_axis_tdata_int = current_s_tdata; + m_eth_payload_axis_tkeep_int = current_s_tkeep; + m_eth_payload_axis_tvalid_int = current_s_tvalid && current_s_tready && frame_reg; + m_eth_payload_axis_tlast_int = current_s_tlast; + m_eth_payload_axis_tid_int = current_s_tid; + m_eth_payload_axis_tdest_int = current_s_tdest; + m_eth_payload_axis_tuser_int = current_s_tuser; +end + +always @(posedge clk) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 1'b0; + s_eth_hdr_ready_reg <= 0; + s_eth_payload_axis_tready_reg <= 0; + m_eth_hdr_valid_reg <= 1'b0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; + s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; + m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; + end + + m_eth_dest_mac_reg <= m_eth_dest_mac_next; + m_eth_src_mac_reg <= m_eth_src_mac_next; + m_eth_type_reg <= m_eth_type_next; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; +reg m_eth_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_eth_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_eth_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_eth_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; +reg temp_m_eth_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_eth_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_eth_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_eth_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign m_eth_payload_axis_tdata = m_eth_payload_axis_tdata_reg; +assign m_eth_payload_axis_tkeep = KEEP_ENABLE ? m_eth_payload_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; +assign m_eth_payload_axis_tlast = m_eth_payload_axis_tlast_reg; +assign m_eth_payload_axis_tid = ID_ENABLE ? m_eth_payload_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_eth_payload_axis_tdest = DEST_ENABLE ? m_eth_payload_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_eth_payload_axis_tuser = USER_ENABLE ? m_eth_payload_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_eth_payload_axis_tready_int_early = m_eth_payload_axis_tready || (!temp_m_eth_payload_axis_tvalid_reg && (!m_eth_payload_axis_tvalid_reg || !m_eth_payload_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (m_eth_payload_axis_tready_int_reg) begin + // input is ready + if (m_eth_payload_axis_tready || !m_eth_payload_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_eth_payload_axis_tready) begin + // input is not ready, but output is ready + m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_eth_payload_axis_tvalid_reg <= 1'b0; + m_eth_payload_axis_tready_int_reg <= 1'b0; + temp_m_eth_payload_axis_tvalid_reg <= 1'b0; + end else begin + m_eth_payload_axis_tvalid_reg <= m_eth_payload_axis_tvalid_next; + m_eth_payload_axis_tready_int_reg <= m_eth_payload_axis_tready_int_early; + temp_m_eth_payload_axis_tvalid_reg <= temp_m_eth_payload_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + m_eth_payload_axis_tid_reg <= m_eth_payload_axis_tid_int; + m_eth_payload_axis_tdest_reg <= m_eth_payload_axis_tdest_int; + m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; + m_eth_payload_axis_tkeep_reg <= temp_m_eth_payload_axis_tkeep_reg; + m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; + m_eth_payload_axis_tid_reg <= temp_m_eth_payload_axis_tid_reg; + m_eth_payload_axis_tdest_reg <= temp_m_eth_payload_axis_tdest_reg; + m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + temp_m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + temp_m_eth_payload_axis_tid_reg <= m_eth_payload_axis_tid_int; + temp_m_eth_payload_axis_tdest_reg <= m_eth_payload_axis_tdest_int; + temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/eth_mux_2.v b/rtl/eth_mux_2.v deleted file mode 100644 index d7e2677a4..000000000 --- a/rtl/eth_mux_2.v +++ /dev/null @@ -1,332 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet 2 port multiplexer - */ -module eth_mux_2 -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ - input wire input_0_eth_hdr_valid, - output wire input_0_eth_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [7:0] input_0_eth_payload_tdata, - input wire input_0_eth_payload_tvalid, - output wire input_0_eth_payload_tready, - input wire input_0_eth_payload_tlast, - input wire input_0_eth_payload_tuser, - - input wire input_1_eth_hdr_valid, - output wire input_1_eth_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [7:0] input_1_eth_payload_tdata, - input wire input_1_eth_payload_tvalid, - output wire input_1_eth_payload_tready, - input wire input_1_eth_payload_tlast, - input wire input_1_eth_payload_tuser, - - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [0:0] select -); - -reg [0:0] select_reg = 1'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_eth_hdr_ready_reg = 1'b0, input_0_eth_hdr_ready_next; -reg input_1_eth_hdr_ready_reg = 1'b0, input_1_eth_hdr_ready_next; - -reg input_0_eth_payload_tready_reg = 1'b0, input_0_eth_payload_tready_next; -reg input_1_eth_payload_tready_reg = 1'b0, input_1_eth_payload_tready_next; - -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; - -// internal datapath -reg [7:0] output_eth_payload_tdata_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; - -assign input_0_eth_hdr_ready = input_0_eth_hdr_ready_reg; -assign input_1_eth_hdr_ready = input_1_eth_hdr_ready_reg; - -assign input_0_eth_payload_tready = input_0_eth_payload_tready_reg; -assign input_1_eth_payload_tready = input_1_eth_payload_tready_reg; - -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; - -// mux for start of packet detection -reg selected_input_eth_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -always @* begin - case (select) - 1'd0: begin - selected_input_eth_hdr_valid = input_0_eth_hdr_valid; - selected_input_eth_dest_mac = input_0_eth_dest_mac; - selected_input_eth_src_mac = input_0_eth_src_mac; - selected_input_eth_type = input_0_eth_type; - end - 1'd1: begin - selected_input_eth_hdr_valid = input_1_eth_hdr_valid; - selected_input_eth_dest_mac = input_1_eth_dest_mac; - selected_input_eth_src_mac = input_1_eth_src_mac; - selected_input_eth_type = input_1_eth_type; - end - default: begin - selected_input_eth_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - end - endcase -end - -// mux for incoming packet -reg [7:0] current_input_tdata; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 1'd0: begin - current_input_tdata = input_0_eth_payload_tdata; - current_input_tvalid = input_0_eth_payload_tvalid; - current_input_tready = input_0_eth_payload_tready; - current_input_tlast = input_0_eth_payload_tlast; - current_input_tuser = input_0_eth_payload_tuser; - end - 1'd1: begin - current_input_tdata = input_1_eth_payload_tdata; - current_input_tvalid = input_1_eth_payload_tvalid; - current_input_tready = input_1_eth_payload_tready; - current_input_tlast = input_1_eth_payload_tlast; - current_input_tuser = input_1_eth_payload_tuser; - end - default: begin - current_input_tdata = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_reg & ~input_0_eth_hdr_valid; - input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_reg & ~input_1_eth_hdr_valid; - - input_0_eth_payload_tready_next = 1'b0; - input_1_eth_payload_tready_next = 1'b0; - - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) - 1'd0: input_0_eth_hdr_ready_next = 1'b1; - 1'd1: input_1_eth_hdr_ready_next = 1'b1; - endcase - - output_eth_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - end - - // generate ready signal on selected port - case (select_next) - 1'd0: input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - 1'd1: input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_eth_payload_tdata_int = current_input_tdata; - output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_eth_payload_tlast_int = current_input_tlast; - output_eth_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 1'd0; - frame_reg <= 1'b0; - input_0_eth_hdr_ready_reg <= 1'b0; - input_1_eth_hdr_ready_reg <= 1'b0; - input_0_eth_payload_tready_reg <= 1'b0; - input_1_eth_payload_tready_reg <= 1'b0; - output_eth_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_eth_hdr_ready_reg <= input_0_eth_hdr_ready_next; - input_1_eth_hdr_ready_reg <= input_1_eth_hdr_ready_next; - input_0_eth_payload_tready_reg <= input_0_eth_payload_tready_next; - input_1_eth_payload_tready_reg <= input_1_eth_payload_tready_next; - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; -end - -// output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; - -reg [7:0] temp_eth_payload_tdata_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; - -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; - - if (output_eth_payload_tready_int_reg) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; - end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end -end - -endmodule diff --git a/rtl/eth_mux_4.v b/rtl/eth_mux_4.v deleted file mode 100644 index 7ae3eca90..000000000 --- a/rtl/eth_mux_4.v +++ /dev/null @@ -1,404 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet 4 port multiplexer - */ -module eth_mux_4 -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ - input wire input_0_eth_hdr_valid, - output wire input_0_eth_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [7:0] input_0_eth_payload_tdata, - input wire input_0_eth_payload_tvalid, - output wire input_0_eth_payload_tready, - input wire input_0_eth_payload_tlast, - input wire input_0_eth_payload_tuser, - - input wire input_1_eth_hdr_valid, - output wire input_1_eth_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [7:0] input_1_eth_payload_tdata, - input wire input_1_eth_payload_tvalid, - output wire input_1_eth_payload_tready, - input wire input_1_eth_payload_tlast, - input wire input_1_eth_payload_tuser, - - input wire input_2_eth_hdr_valid, - output wire input_2_eth_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [7:0] input_2_eth_payload_tdata, - input wire input_2_eth_payload_tvalid, - output wire input_2_eth_payload_tready, - input wire input_2_eth_payload_tlast, - input wire input_2_eth_payload_tuser, - - input wire input_3_eth_hdr_valid, - output wire input_3_eth_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [7:0] input_3_eth_payload_tdata, - input wire input_3_eth_payload_tvalid, - output wire input_3_eth_payload_tready, - input wire input_3_eth_payload_tlast, - input wire input_3_eth_payload_tuser, - - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_eth_hdr_ready_reg = 1'b0, input_0_eth_hdr_ready_next; -reg input_1_eth_hdr_ready_reg = 1'b0, input_1_eth_hdr_ready_next; -reg input_2_eth_hdr_ready_reg = 1'b0, input_2_eth_hdr_ready_next; -reg input_3_eth_hdr_ready_reg = 1'b0, input_3_eth_hdr_ready_next; - -reg input_0_eth_payload_tready_reg = 1'b0, input_0_eth_payload_tready_next; -reg input_1_eth_payload_tready_reg = 1'b0, input_1_eth_payload_tready_next; -reg input_2_eth_payload_tready_reg = 1'b0, input_2_eth_payload_tready_next; -reg input_3_eth_payload_tready_reg = 1'b0, input_3_eth_payload_tready_next; - -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; - -// internal datapath -reg [7:0] output_eth_payload_tdata_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; - -assign input_0_eth_hdr_ready = input_0_eth_hdr_ready_reg; -assign input_1_eth_hdr_ready = input_1_eth_hdr_ready_reg; -assign input_2_eth_hdr_ready = input_2_eth_hdr_ready_reg; -assign input_3_eth_hdr_ready = input_3_eth_hdr_ready_reg; - -assign input_0_eth_payload_tready = input_0_eth_payload_tready_reg; -assign input_1_eth_payload_tready = input_1_eth_payload_tready_reg; -assign input_2_eth_payload_tready = input_2_eth_payload_tready_reg; -assign input_3_eth_payload_tready = input_3_eth_payload_tready_reg; - -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; - -// mux for start of packet detection -reg selected_input_eth_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -always @* begin - case (select) - 2'd0: begin - selected_input_eth_hdr_valid = input_0_eth_hdr_valid; - selected_input_eth_dest_mac = input_0_eth_dest_mac; - selected_input_eth_src_mac = input_0_eth_src_mac; - selected_input_eth_type = input_0_eth_type; - end - 2'd1: begin - selected_input_eth_hdr_valid = input_1_eth_hdr_valid; - selected_input_eth_dest_mac = input_1_eth_dest_mac; - selected_input_eth_src_mac = input_1_eth_src_mac; - selected_input_eth_type = input_1_eth_type; - end - 2'd2: begin - selected_input_eth_hdr_valid = input_2_eth_hdr_valid; - selected_input_eth_dest_mac = input_2_eth_dest_mac; - selected_input_eth_src_mac = input_2_eth_src_mac; - selected_input_eth_type = input_2_eth_type; - end - 2'd3: begin - selected_input_eth_hdr_valid = input_3_eth_hdr_valid; - selected_input_eth_dest_mac = input_3_eth_dest_mac; - selected_input_eth_src_mac = input_3_eth_src_mac; - selected_input_eth_type = input_3_eth_type; - end - default: begin - selected_input_eth_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - end - endcase -end - -// mux for incoming packet -reg [7:0] current_input_tdata; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 2'd0: begin - current_input_tdata = input_0_eth_payload_tdata; - current_input_tvalid = input_0_eth_payload_tvalid; - current_input_tready = input_0_eth_payload_tready; - current_input_tlast = input_0_eth_payload_tlast; - current_input_tuser = input_0_eth_payload_tuser; - end - 2'd1: begin - current_input_tdata = input_1_eth_payload_tdata; - current_input_tvalid = input_1_eth_payload_tvalid; - current_input_tready = input_1_eth_payload_tready; - current_input_tlast = input_1_eth_payload_tlast; - current_input_tuser = input_1_eth_payload_tuser; - end - 2'd2: begin - current_input_tdata = input_2_eth_payload_tdata; - current_input_tvalid = input_2_eth_payload_tvalid; - current_input_tready = input_2_eth_payload_tready; - current_input_tlast = input_2_eth_payload_tlast; - current_input_tuser = input_2_eth_payload_tuser; - end - 2'd3: begin - current_input_tdata = input_3_eth_payload_tdata; - current_input_tvalid = input_3_eth_payload_tvalid; - current_input_tready = input_3_eth_payload_tready; - current_input_tlast = input_3_eth_payload_tlast; - current_input_tuser = input_3_eth_payload_tuser; - end - default: begin - current_input_tdata = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_reg & ~input_0_eth_hdr_valid; - input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_reg & ~input_1_eth_hdr_valid; - input_2_eth_hdr_ready_next = input_2_eth_hdr_ready_reg & ~input_2_eth_hdr_valid; - input_3_eth_hdr_ready_next = input_3_eth_hdr_ready_reg & ~input_3_eth_hdr_valid; - - input_0_eth_payload_tready_next = 1'b0; - input_1_eth_payload_tready_next = 1'b0; - input_2_eth_payload_tready_next = 1'b0; - input_3_eth_payload_tready_next = 1'b0; - - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) - 2'd0: input_0_eth_hdr_ready_next = 1'b1; - 2'd1: input_1_eth_hdr_ready_next = 1'b1; - 2'd2: input_2_eth_hdr_ready_next = 1'b1; - 2'd3: input_3_eth_hdr_ready_next = 1'b1; - endcase - - output_eth_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - end - - // generate ready signal on selected port - case (select_next) - 2'd0: input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - 2'd1: input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - 2'd2: input_2_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - 2'd3: input_3_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_eth_payload_tdata_int = current_input_tdata; - output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_eth_payload_tlast_int = current_input_tlast; - output_eth_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_0_eth_hdr_ready_reg <= 1'b0; - input_1_eth_hdr_ready_reg <= 1'b0; - input_2_eth_hdr_ready_reg <= 1'b0; - input_3_eth_hdr_ready_reg <= 1'b0; - input_0_eth_payload_tready_reg <= 1'b0; - input_1_eth_payload_tready_reg <= 1'b0; - input_2_eth_payload_tready_reg <= 1'b0; - input_3_eth_payload_tready_reg <= 1'b0; - output_eth_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_eth_hdr_ready_reg <= input_0_eth_hdr_ready_next; - input_1_eth_hdr_ready_reg <= input_1_eth_hdr_ready_next; - input_2_eth_hdr_ready_reg <= input_2_eth_hdr_ready_next; - input_3_eth_hdr_ready_reg <= input_3_eth_hdr_ready_next; - input_0_eth_payload_tready_reg <= input_0_eth_payload_tready_next; - input_1_eth_payload_tready_reg <= input_1_eth_payload_tready_next; - input_2_eth_payload_tready_reg <= input_2_eth_payload_tready_next; - input_3_eth_payload_tready_reg <= input_3_eth_payload_tready_next; - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; -end - -// output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; - -reg [7:0] temp_eth_payload_tdata_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; - -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; - - if (output_eth_payload_tready_int_reg) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; - end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end -end - -endmodule diff --git a/rtl/eth_mux_64.py b/rtl/eth_mux_64.py deleted file mode 100755 index 479f825c0..000000000 --- a/rtl/eth_mux_64.py +++ /dev/null @@ -1,387 +0,0 @@ -#!/usr/bin/env python -""" -Generates an Ethernet mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "eth_mux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port Ethernet mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet {{n}} port multiplexer (64 bit datapath) - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_eth_hdr_valid, - output wire input_{{p}}_eth_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [63:0] input_{{p}}_eth_payload_tdata, - input wire [7:0] input_{{p}}_eth_payload_tkeep, - input wire input_{{p}}_eth_payload_tvalid, - output wire input_{{p}}_eth_payload_tready, - input wire input_{{p}}_eth_payload_tlast, - input wire input_{{p}}_eth_payload_tuser, -{% endfor %} - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; -{% for p in ports %} -reg input_{{p}}_eth_hdr_ready_reg = 1'b0, input_{{p}}_eth_hdr_ready_next; -{%- endfor %} -{% for p in ports %} -reg input_{{p}}_eth_payload_tready_reg = 1'b0, input_{{p}}_eth_payload_tready_next; -{%- endfor %} - -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; - -// internal datapath -reg [63:0] output_eth_payload_tdata_int; -reg [7:0] output_eth_payload_tkeep_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; -{% for p in ports %} -assign input_{{p}}_eth_hdr_ready = input_{{p}}_eth_hdr_ready_reg; -{%- endfor %} -{% for p in ports %} -assign input_{{p}}_eth_payload_tready = input_{{p}}_eth_payload_tready_reg; -{%- endfor %} - -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; - -// mux for start of packet detection -reg selected_input_eth_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -always @* begin - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: begin - selected_input_eth_hdr_valid = input_{{p}}_eth_hdr_valid; - selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; - selected_input_eth_src_mac = input_{{p}}_eth_src_mac; - selected_input_eth_type = input_{{p}}_eth_type; - end -{%- endfor %} - default: begin - selected_input_eth_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - end - endcase -end - -// mux for incoming packet -reg [63:0] current_input_tdata; -reg [7:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_input_tdata = input_{{p}}_eth_payload_tdata; - current_input_tkeep = input_{{p}}_eth_payload_tkeep; - current_input_tvalid = input_{{p}}_eth_payload_tvalid; - current_input_tready = input_{{p}}_eth_payload_tready; - current_input_tlast = input_{{p}}_eth_payload_tlast; - current_input_tuser = input_{{p}}_eth_payload_tuser; - end -{%- endfor %} - default: begin - current_input_tdata = 64'd0; - current_input_tkeep = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; -{% for p in ports %} - input_{{p}}_eth_hdr_ready_next = input_{{p}}_eth_hdr_ready_reg & ~input_{{p}}_eth_hdr_valid; -{%- endfor %} -{% for p in ports %} - input_{{p}}_eth_payload_tready_next = 1'b0; -{%- endfor %} - - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_eth_hdr_ready_next = 1'b1; -{%- endfor %} - endcase - - output_eth_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - end - - // generate ready signal on selected port - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; -{%- endfor %} - endcase - - // pass through selected packet data - output_eth_payload_tdata_int = current_input_tdata; - output_eth_payload_tkeep_int = current_input_tkeep; - output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_eth_payload_tlast_int = current_input_tlast; - output_eth_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; -{%- for p in ports %} - input_{{p}}_eth_hdr_ready_reg <= 1'b0; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_eth_payload_tready_reg <= 1'b0; -{%- endfor %} - output_eth_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; -{%- for p in ports %} - input_{{p}}_eth_hdr_ready_reg <= input_{{p}}_eth_hdr_ready_next; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_eth_payload_tready_reg <= input_{{p}}_eth_payload_tready_next; -{%- endfor %} - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; -end - -// output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 64'd0; -reg [7:0] output_eth_payload_tkeep_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; - -reg [63:0] temp_eth_payload_tdata_reg = 64'd0; -reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; - -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; - - if (output_eth_payload_tready_int_reg) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; - end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/eth_mux_64_2.v b/rtl/eth_mux_64_2.v deleted file mode 100644 index 114820c7a..000000000 --- a/rtl/eth_mux_64_2.v +++ /dev/null @@ -1,347 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet 2 port multiplexer (64 bit datapath) - */ -module eth_mux_64_2 -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ - input wire input_0_eth_hdr_valid, - output wire input_0_eth_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [63:0] input_0_eth_payload_tdata, - input wire [7:0] input_0_eth_payload_tkeep, - input wire input_0_eth_payload_tvalid, - output wire input_0_eth_payload_tready, - input wire input_0_eth_payload_tlast, - input wire input_0_eth_payload_tuser, - - input wire input_1_eth_hdr_valid, - output wire input_1_eth_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [63:0] input_1_eth_payload_tdata, - input wire [7:0] input_1_eth_payload_tkeep, - input wire input_1_eth_payload_tvalid, - output wire input_1_eth_payload_tready, - input wire input_1_eth_payload_tlast, - input wire input_1_eth_payload_tuser, - - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [0:0] select -); - -reg [0:0] select_reg = 1'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_eth_hdr_ready_reg = 1'b0, input_0_eth_hdr_ready_next; -reg input_1_eth_hdr_ready_reg = 1'b0, input_1_eth_hdr_ready_next; - -reg input_0_eth_payload_tready_reg = 1'b0, input_0_eth_payload_tready_next; -reg input_1_eth_payload_tready_reg = 1'b0, input_1_eth_payload_tready_next; - -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; - -// internal datapath -reg [63:0] output_eth_payload_tdata_int; -reg [7:0] output_eth_payload_tkeep_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; - -assign input_0_eth_hdr_ready = input_0_eth_hdr_ready_reg; -assign input_1_eth_hdr_ready = input_1_eth_hdr_ready_reg; - -assign input_0_eth_payload_tready = input_0_eth_payload_tready_reg; -assign input_1_eth_payload_tready = input_1_eth_payload_tready_reg; - -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; - -// mux for start of packet detection -reg selected_input_eth_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -always @* begin - case (select) - 1'd0: begin - selected_input_eth_hdr_valid = input_0_eth_hdr_valid; - selected_input_eth_dest_mac = input_0_eth_dest_mac; - selected_input_eth_src_mac = input_0_eth_src_mac; - selected_input_eth_type = input_0_eth_type; - end - 1'd1: begin - selected_input_eth_hdr_valid = input_1_eth_hdr_valid; - selected_input_eth_dest_mac = input_1_eth_dest_mac; - selected_input_eth_src_mac = input_1_eth_src_mac; - selected_input_eth_type = input_1_eth_type; - end - default: begin - selected_input_eth_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - end - endcase -end - -// mux for incoming packet -reg [63:0] current_input_tdata; -reg [7:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 1'd0: begin - current_input_tdata = input_0_eth_payload_tdata; - current_input_tkeep = input_0_eth_payload_tkeep; - current_input_tvalid = input_0_eth_payload_tvalid; - current_input_tready = input_0_eth_payload_tready; - current_input_tlast = input_0_eth_payload_tlast; - current_input_tuser = input_0_eth_payload_tuser; - end - 1'd1: begin - current_input_tdata = input_1_eth_payload_tdata; - current_input_tkeep = input_1_eth_payload_tkeep; - current_input_tvalid = input_1_eth_payload_tvalid; - current_input_tready = input_1_eth_payload_tready; - current_input_tlast = input_1_eth_payload_tlast; - current_input_tuser = input_1_eth_payload_tuser; - end - default: begin - current_input_tdata = 64'd0; - current_input_tkeep = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_reg & ~input_0_eth_hdr_valid; - input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_reg & ~input_1_eth_hdr_valid; - - input_0_eth_payload_tready_next = 1'b0; - input_1_eth_payload_tready_next = 1'b0; - - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) - 1'd0: input_0_eth_hdr_ready_next = 1'b1; - 1'd1: input_1_eth_hdr_ready_next = 1'b1; - endcase - - output_eth_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - end - - // generate ready signal on selected port - case (select_next) - 1'd0: input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - 1'd1: input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_eth_payload_tdata_int = current_input_tdata; - output_eth_payload_tkeep_int = current_input_tkeep; - output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_eth_payload_tlast_int = current_input_tlast; - output_eth_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 1'd0; - frame_reg <= 1'b0; - input_0_eth_hdr_ready_reg <= 1'b0; - input_1_eth_hdr_ready_reg <= 1'b0; - input_0_eth_payload_tready_reg <= 1'b0; - input_1_eth_payload_tready_reg <= 1'b0; - output_eth_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_eth_hdr_ready_reg <= input_0_eth_hdr_ready_next; - input_1_eth_hdr_ready_reg <= input_1_eth_hdr_ready_next; - input_0_eth_payload_tready_reg <= input_0_eth_payload_tready_next; - input_1_eth_payload_tready_reg <= input_1_eth_payload_tready_next; - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; -end - -// output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 64'd0; -reg [7:0] output_eth_payload_tkeep_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; - -reg [63:0] temp_eth_payload_tdata_reg = 64'd0; -reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; - -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; - - if (output_eth_payload_tready_int_reg) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; - end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end -end - -endmodule diff --git a/rtl/eth_mux_64_4.v b/rtl/eth_mux_64_4.v deleted file mode 100644 index 6145efc55..000000000 --- a/rtl/eth_mux_64_4.v +++ /dev/null @@ -1,423 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet 4 port multiplexer (64 bit datapath) - */ -module eth_mux_64_4 -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ - input wire input_0_eth_hdr_valid, - output wire input_0_eth_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [63:0] input_0_eth_payload_tdata, - input wire [7:0] input_0_eth_payload_tkeep, - input wire input_0_eth_payload_tvalid, - output wire input_0_eth_payload_tready, - input wire input_0_eth_payload_tlast, - input wire input_0_eth_payload_tuser, - - input wire input_1_eth_hdr_valid, - output wire input_1_eth_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [63:0] input_1_eth_payload_tdata, - input wire [7:0] input_1_eth_payload_tkeep, - input wire input_1_eth_payload_tvalid, - output wire input_1_eth_payload_tready, - input wire input_1_eth_payload_tlast, - input wire input_1_eth_payload_tuser, - - input wire input_2_eth_hdr_valid, - output wire input_2_eth_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [63:0] input_2_eth_payload_tdata, - input wire [7:0] input_2_eth_payload_tkeep, - input wire input_2_eth_payload_tvalid, - output wire input_2_eth_payload_tready, - input wire input_2_eth_payload_tlast, - input wire input_2_eth_payload_tuser, - - input wire input_3_eth_hdr_valid, - output wire input_3_eth_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [63:0] input_3_eth_payload_tdata, - input wire [7:0] input_3_eth_payload_tkeep, - input wire input_3_eth_payload_tvalid, - output wire input_3_eth_payload_tready, - input wire input_3_eth_payload_tlast, - input wire input_3_eth_payload_tuser, - - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_eth_hdr_ready_reg = 1'b0, input_0_eth_hdr_ready_next; -reg input_1_eth_hdr_ready_reg = 1'b0, input_1_eth_hdr_ready_next; -reg input_2_eth_hdr_ready_reg = 1'b0, input_2_eth_hdr_ready_next; -reg input_3_eth_hdr_ready_reg = 1'b0, input_3_eth_hdr_ready_next; - -reg input_0_eth_payload_tready_reg = 1'b0, input_0_eth_payload_tready_next; -reg input_1_eth_payload_tready_reg = 1'b0, input_1_eth_payload_tready_next; -reg input_2_eth_payload_tready_reg = 1'b0, input_2_eth_payload_tready_next; -reg input_3_eth_payload_tready_reg = 1'b0, input_3_eth_payload_tready_next; - -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; - -// internal datapath -reg [63:0] output_eth_payload_tdata_int; -reg [7:0] output_eth_payload_tkeep_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; - -assign input_0_eth_hdr_ready = input_0_eth_hdr_ready_reg; -assign input_1_eth_hdr_ready = input_1_eth_hdr_ready_reg; -assign input_2_eth_hdr_ready = input_2_eth_hdr_ready_reg; -assign input_3_eth_hdr_ready = input_3_eth_hdr_ready_reg; - -assign input_0_eth_payload_tready = input_0_eth_payload_tready_reg; -assign input_1_eth_payload_tready = input_1_eth_payload_tready_reg; -assign input_2_eth_payload_tready = input_2_eth_payload_tready_reg; -assign input_3_eth_payload_tready = input_3_eth_payload_tready_reg; - -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; - -// mux for start of packet detection -reg selected_input_eth_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -always @* begin - case (select) - 2'd0: begin - selected_input_eth_hdr_valid = input_0_eth_hdr_valid; - selected_input_eth_dest_mac = input_0_eth_dest_mac; - selected_input_eth_src_mac = input_0_eth_src_mac; - selected_input_eth_type = input_0_eth_type; - end - 2'd1: begin - selected_input_eth_hdr_valid = input_1_eth_hdr_valid; - selected_input_eth_dest_mac = input_1_eth_dest_mac; - selected_input_eth_src_mac = input_1_eth_src_mac; - selected_input_eth_type = input_1_eth_type; - end - 2'd2: begin - selected_input_eth_hdr_valid = input_2_eth_hdr_valid; - selected_input_eth_dest_mac = input_2_eth_dest_mac; - selected_input_eth_src_mac = input_2_eth_src_mac; - selected_input_eth_type = input_2_eth_type; - end - 2'd3: begin - selected_input_eth_hdr_valid = input_3_eth_hdr_valid; - selected_input_eth_dest_mac = input_3_eth_dest_mac; - selected_input_eth_src_mac = input_3_eth_src_mac; - selected_input_eth_type = input_3_eth_type; - end - default: begin - selected_input_eth_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - end - endcase -end - -// mux for incoming packet -reg [63:0] current_input_tdata; -reg [7:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 2'd0: begin - current_input_tdata = input_0_eth_payload_tdata; - current_input_tkeep = input_0_eth_payload_tkeep; - current_input_tvalid = input_0_eth_payload_tvalid; - current_input_tready = input_0_eth_payload_tready; - current_input_tlast = input_0_eth_payload_tlast; - current_input_tuser = input_0_eth_payload_tuser; - end - 2'd1: begin - current_input_tdata = input_1_eth_payload_tdata; - current_input_tkeep = input_1_eth_payload_tkeep; - current_input_tvalid = input_1_eth_payload_tvalid; - current_input_tready = input_1_eth_payload_tready; - current_input_tlast = input_1_eth_payload_tlast; - current_input_tuser = input_1_eth_payload_tuser; - end - 2'd2: begin - current_input_tdata = input_2_eth_payload_tdata; - current_input_tkeep = input_2_eth_payload_tkeep; - current_input_tvalid = input_2_eth_payload_tvalid; - current_input_tready = input_2_eth_payload_tready; - current_input_tlast = input_2_eth_payload_tlast; - current_input_tuser = input_2_eth_payload_tuser; - end - 2'd3: begin - current_input_tdata = input_3_eth_payload_tdata; - current_input_tkeep = input_3_eth_payload_tkeep; - current_input_tvalid = input_3_eth_payload_tvalid; - current_input_tready = input_3_eth_payload_tready; - current_input_tlast = input_3_eth_payload_tlast; - current_input_tuser = input_3_eth_payload_tuser; - end - default: begin - current_input_tdata = 64'd0; - current_input_tkeep = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_eth_hdr_ready_next = input_0_eth_hdr_ready_reg & ~input_0_eth_hdr_valid; - input_1_eth_hdr_ready_next = input_1_eth_hdr_ready_reg & ~input_1_eth_hdr_valid; - input_2_eth_hdr_ready_next = input_2_eth_hdr_ready_reg & ~input_2_eth_hdr_valid; - input_3_eth_hdr_ready_next = input_3_eth_hdr_ready_reg & ~input_3_eth_hdr_valid; - - input_0_eth_payload_tready_next = 1'b0; - input_1_eth_payload_tready_next = 1'b0; - input_2_eth_payload_tready_next = 1'b0; - input_3_eth_payload_tready_next = 1'b0; - - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_eth_hdr_valid & selected_input_eth_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) - 2'd0: input_0_eth_hdr_ready_next = 1'b1; - 2'd1: input_1_eth_hdr_ready_next = 1'b1; - 2'd2: input_2_eth_hdr_ready_next = 1'b1; - 2'd3: input_3_eth_hdr_ready_next = 1'b1; - endcase - - output_eth_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - end - - // generate ready signal on selected port - case (select_next) - 2'd0: input_0_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - 2'd1: input_1_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - 2'd2: input_2_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - 2'd3: input_3_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_eth_payload_tdata_int = current_input_tdata; - output_eth_payload_tkeep_int = current_input_tkeep; - output_eth_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_eth_payload_tlast_int = current_input_tlast; - output_eth_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_0_eth_hdr_ready_reg <= 1'b0; - input_1_eth_hdr_ready_reg <= 1'b0; - input_2_eth_hdr_ready_reg <= 1'b0; - input_3_eth_hdr_ready_reg <= 1'b0; - input_0_eth_payload_tready_reg <= 1'b0; - input_1_eth_payload_tready_reg <= 1'b0; - input_2_eth_payload_tready_reg <= 1'b0; - input_3_eth_payload_tready_reg <= 1'b0; - output_eth_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_eth_hdr_ready_reg <= input_0_eth_hdr_ready_next; - input_1_eth_hdr_ready_reg <= input_1_eth_hdr_ready_next; - input_2_eth_hdr_ready_reg <= input_2_eth_hdr_ready_next; - input_3_eth_hdr_ready_reg <= input_3_eth_hdr_ready_next; - input_0_eth_payload_tready_reg <= input_0_eth_payload_tready_next; - input_1_eth_payload_tready_reg <= input_1_eth_payload_tready_next; - input_2_eth_payload_tready_reg <= input_2_eth_payload_tready_next; - input_3_eth_payload_tready_reg <= input_3_eth_payload_tready_next; - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; -end - -// output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 64'd0; -reg [7:0] output_eth_payload_tkeep_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; - -reg [63:0] temp_eth_payload_tdata_reg = 64'd0; -reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; - -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; - - if (output_eth_payload_tready_int_reg) begin - // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (output_eth_payload_tready) begin - // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; - end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end -end - -endmodule diff --git a/tb/test_eth_mux_4.py b/tb/test_eth_mux_4.py index 92b25d34b..7a7ef02f4 100755 --- a/tb/test_eth_mux_4.py +++ b/tb/test_eth_mux_4.py @@ -28,8 +28,8 @@ import os import eth_ep -module = 'eth_mux_4' -testbench = 'test_%s' % module +module = 'eth_mux' +testbench = 'test_%s_4' % module srcs = [] @@ -42,167 +42,119 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_eth_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_eth_payload_tdata = Signal(intbv(0)[8:]) - input_0_eth_payload_tvalid = Signal(bool(0)) - input_0_eth_payload_tlast = Signal(bool(0)) - input_0_eth_payload_tuser = Signal(bool(0)) - input_1_eth_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_eth_payload_tdata = Signal(intbv(0)[8:]) - input_1_eth_payload_tvalid = Signal(bool(0)) - input_1_eth_payload_tlast = Signal(bool(0)) - input_1_eth_payload_tuser = Signal(bool(0)) - input_2_eth_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_eth_payload_tdata = Signal(intbv(0)[8:]) - input_2_eth_payload_tvalid = Signal(bool(0)) - input_2_eth_payload_tlast = Signal(bool(0)) - input_2_eth_payload_tuser = Signal(bool(0)) - input_3_eth_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_eth_payload_tdata = Signal(intbv(0)[8:]) - input_3_eth_payload_tvalid = Signal(bool(0)) - input_3_eth_payload_tlast = Signal(bool(0)) - input_3_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_eth_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + s_eth_hdr_valid = ConcatSignal(*reversed(s_eth_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_eth_payload_axis_tdata = ConcatSignal(*reversed(s_eth_payload_axis_tdata_list)) + s_eth_payload_axis_tkeep = ConcatSignal(*reversed(s_eth_payload_axis_tkeep_list)) + s_eth_payload_axis_tvalid = ConcatSignal(*reversed(s_eth_payload_axis_tvalid_list)) + s_eth_payload_axis_tlast = ConcatSignal(*reversed(s_eth_payload_axis_tlast_list)) + s_eth_payload_axis_tid = ConcatSignal(*reversed(s_eth_payload_axis_tid_list)) + s_eth_payload_axis_tdest = ConcatSignal(*reversed(s_eth_payload_axis_tdest_list)) + s_eth_payload_axis_tuser = ConcatSignal(*reversed(s_eth_payload_axis_tuser_list)) + + m_eth_hdr_ready = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_0_eth_hdr_ready = Signal(bool(0)) - input_0_eth_payload_tready = Signal(bool(0)) - input_1_eth_hdr_ready = Signal(bool(0)) - input_1_eth_payload_tready = Signal(bool(0)) - input_2_eth_hdr_ready = Signal(bool(0)) - input_2_eth_payload_tready = Signal(bool(0)) - input_3_eth_hdr_ready = Signal(bool(0)) - input_3_eth_payload_tready = Signal(bool(0)) + s_eth_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_eth_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready_list = [s_eth_hdr_ready(i) for i in range(S_COUNT)] + s_eth_payload_axis_tready_list = [s_eth_payload_axis_tready(i) for i in range(S_COUNT)] + + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_eth_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_eth_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_eth_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = eth_ep.EthFrameSource() + for k in range(S_COUNT): + s = eth_ep.EthFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - eth_hdr_ready=input_0_eth_hdr_ready, - eth_hdr_valid=input_0_eth_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - eth_type=input_0_eth_type, - eth_payload_tdata=input_0_eth_payload_tdata, - eth_payload_tvalid=input_0_eth_payload_tvalid, - eth_payload_tready=input_0_eth_payload_tready, - eth_payload_tlast=input_0_eth_payload_tlast, - eth_payload_tuser=input_0_eth_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = eth_ep.EthFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - eth_hdr_ready=input_1_eth_hdr_ready, - eth_hdr_valid=input_1_eth_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - eth_type=input_1_eth_type, - eth_payload_tdata=input_1_eth_payload_tdata, - eth_payload_tvalid=input_1_eth_payload_tvalid, - eth_payload_tready=input_1_eth_payload_tready, - eth_payload_tlast=input_1_eth_payload_tlast, - eth_payload_tuser=input_1_eth_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = eth_ep.EthFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - eth_hdr_ready=input_2_eth_hdr_ready, - eth_hdr_valid=input_2_eth_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - eth_payload_tdata=input_2_eth_payload_tdata, - eth_payload_tvalid=input_2_eth_payload_tvalid, - eth_payload_tready=input_2_eth_payload_tready, - eth_payload_tlast=input_2_eth_payload_tlast, - eth_payload_tuser=input_2_eth_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = eth_ep.EthFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - eth_hdr_ready=input_3_eth_hdr_ready, - eth_hdr_valid=input_3_eth_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - eth_payload_tdata=input_3_eth_payload_tdata, - eth_payload_tvalid=input_3_eth_payload_tvalid, - eth_payload_tready=input_3_eth_payload_tready, - eth_payload_tlast=input_3_eth_payload_tlast, - eth_payload_tuser=input_3_eth_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + eth_hdr_ready=s_eth_hdr_ready_list[k], + eth_hdr_valid=s_eth_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + eth_payload_tdata=s_eth_payload_axis_tdata_list[k], + eth_payload_tkeep=s_eth_payload_axis_tkeep_list[k], + eth_payload_tvalid=s_eth_payload_axis_tvalid_list[k], + eth_payload_tready=s_eth_payload_axis_tready_list[k], + eth_payload_tlast=s_eth_payload_axis_tlast_list[k], + eth_payload_tuser=s_eth_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = eth_ep.EthFrameSink() sink_logic = sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -217,57 +169,33 @@ def bench(): rst=rst, current_test=current_test, - input_0_eth_hdr_valid=input_0_eth_hdr_valid, - input_0_eth_hdr_ready=input_0_eth_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_eth_payload_tdata=input_0_eth_payload_tdata, - input_0_eth_payload_tvalid=input_0_eth_payload_tvalid, - input_0_eth_payload_tready=input_0_eth_payload_tready, - input_0_eth_payload_tlast=input_0_eth_payload_tlast, - input_0_eth_payload_tuser=input_0_eth_payload_tuser, - input_1_eth_hdr_valid=input_1_eth_hdr_valid, - input_1_eth_hdr_ready=input_1_eth_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_eth_payload_tdata=input_1_eth_payload_tdata, - input_1_eth_payload_tvalid=input_1_eth_payload_tvalid, - input_1_eth_payload_tready=input_1_eth_payload_tready, - input_1_eth_payload_tlast=input_1_eth_payload_tlast, - input_1_eth_payload_tuser=input_1_eth_payload_tuser, - input_2_eth_hdr_valid=input_2_eth_hdr_valid, - input_2_eth_hdr_ready=input_2_eth_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_eth_payload_tdata=input_2_eth_payload_tdata, - input_2_eth_payload_tvalid=input_2_eth_payload_tvalid, - input_2_eth_payload_tready=input_2_eth_payload_tready, - input_2_eth_payload_tlast=input_2_eth_payload_tlast, - input_2_eth_payload_tuser=input_2_eth_payload_tuser, - input_3_eth_hdr_valid=input_3_eth_hdr_valid, - input_3_eth_hdr_ready=input_3_eth_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_eth_payload_tdata=input_3_eth_payload_tdata, - input_3_eth_payload_tvalid=input_3_eth_payload_tvalid, - input_3_eth_payload_tready=input_3_eth_payload_tready, - input_3_eth_payload_tlast=input_3_eth_payload_tlast, - input_3_eth_payload_tuser=input_3_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tid=s_eth_payload_axis_tid, + s_eth_payload_axis_tdest=s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tid=m_eth_payload_axis_tid, + m_eth_payload_axis_tdest=m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, enable=enable, select=select @@ -303,7 +231,7 @@ def bench(): test_frame.eth_type = 0x8000 test_frame.payload = bytearray(range(32)) - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -324,7 +252,7 @@ def bench(): test_frame.eth_type = 0x8000 test_frame.payload = bytearray(range(32)) - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -350,8 +278,8 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -382,12 +310,12 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + while s_eth_payload_axis_tvalid: yield clk.posedge select.next = 2 @@ -420,23 +348,23 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_eth_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge select.next = 2 @@ -469,12 +397,12 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + while s_eth_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_eth_mux_4.v b/tb/test_eth_mux_4.v index 637ef1200..243903a3f 100644 --- a/tb/test_eth_mux_4.v +++ b/tb/test_eth_mux_4.v @@ -27,72 +27,60 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for eth_mux_4 + * Testbench for eth_mux */ module test_eth_mux_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_eth_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [7:0] input_0_eth_payload_tdata = 0; -reg input_0_eth_payload_tvalid = 0; -reg input_0_eth_payload_tlast = 0; -reg input_0_eth_payload_tuser = 0; -reg input_1_eth_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [7:0] input_1_eth_payload_tdata = 0; -reg input_1_eth_payload_tvalid = 0; -reg input_1_eth_payload_tlast = 0; -reg input_1_eth_payload_tuser = 0; -reg input_2_eth_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [7:0] input_2_eth_payload_tdata = 0; -reg input_2_eth_payload_tvalid = 0; -reg input_2_eth_payload_tlast = 0; -reg input_2_eth_payload_tuser = 0; -reg input_3_eth_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [7:0] input_3_eth_payload_tdata = 0; -reg input_3_eth_payload_tvalid = 0; -reg input_3_eth_payload_tlast = 0; -reg input_3_eth_payload_tuser = 0; +reg [S_COUNT-1:0] s_eth_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_eth_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_eth_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_eth_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_eth_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_eth_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_eth_payload_axis_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; reg enable = 0; reg [1:0] select = 0; // Outputs -wire input_0_eth_payload_tready; -wire input_0_eth_hdr_ready; -wire input_1_eth_payload_tready; -wire input_1_eth_hdr_ready; -wire input_2_eth_payload_tready; -wire input_2_eth_hdr_ready; -wire input_3_eth_payload_tready; -wire input_3_eth_hdr_ready; +wire [S_COUNT-1:0] s_eth_hdr_ready; +wire [S_COUNT-1:0] s_eth_payload_axis_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [7:0] output_eth_payload_tdata; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [DATA_WIDTH-1:0] m_eth_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_eth_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_eth_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_eth_payload_axis_tuser; initial begin // myhdl integration @@ -100,60 +88,36 @@ initial begin clk, rst, current_test, - input_0_eth_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_eth_payload_tdata, - input_0_eth_payload_tvalid, - input_0_eth_payload_tlast, - input_0_eth_payload_tuser, - input_1_eth_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_eth_payload_tdata, - input_1_eth_payload_tvalid, - input_1_eth_payload_tlast, - input_1_eth_payload_tuser, - input_2_eth_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_eth_payload_tdata, - input_2_eth_payload_tvalid, - input_2_eth_payload_tlast, - input_2_eth_payload_tuser, - input_3_eth_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_eth_payload_tdata, - input_3_eth_payload_tvalid, - input_3_eth_payload_tlast, - input_3_eth_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tid, + s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, enable, select ); $to_myhdl( - input_0_eth_hdr_ready, - input_0_eth_payload_tready, - input_1_eth_hdr_ready, - input_1_eth_payload_tready, - input_2_eth_hdr_ready, - input_2_eth_payload_tready, - input_3_eth_hdr_ready, - input_3_eth_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tid, + m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser ); // dump file @@ -161,62 +125,49 @@ initial begin $dumpvars(0, test_eth_mux_4); end -eth_mux_4 +eth_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), // Ethernet frame inputs - .input_0_eth_hdr_valid(input_0_eth_hdr_valid), - .input_0_eth_hdr_ready(input_0_eth_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_eth_payload_tdata(input_0_eth_payload_tdata), - .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid), - .input_0_eth_payload_tready(input_0_eth_payload_tready), - .input_0_eth_payload_tlast(input_0_eth_payload_tlast), - .input_0_eth_payload_tuser(input_0_eth_payload_tuser), - .input_1_eth_hdr_valid(input_1_eth_hdr_valid), - .input_1_eth_hdr_ready(input_1_eth_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_eth_payload_tdata(input_1_eth_payload_tdata), - .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid), - .input_1_eth_payload_tready(input_1_eth_payload_tready), - .input_1_eth_payload_tlast(input_1_eth_payload_tlast), - .input_1_eth_payload_tuser(input_1_eth_payload_tuser), - .input_2_eth_hdr_valid(input_2_eth_hdr_valid), - .input_2_eth_hdr_ready(input_2_eth_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_eth_payload_tdata(input_2_eth_payload_tdata), - .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid), - .input_2_eth_payload_tready(input_2_eth_payload_tready), - .input_2_eth_payload_tlast(input_2_eth_payload_tlast), - .input_2_eth_payload_tuser(input_2_eth_payload_tuser), - .input_3_eth_hdr_valid(input_3_eth_hdr_valid), - .input_3_eth_hdr_ready(input_3_eth_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_eth_payload_tdata(input_3_eth_payload_tdata), - .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid), - .input_3_eth_payload_tready(input_3_eth_payload_tready), - .input_3_eth_payload_tlast(input_3_eth_payload_tlast), - .input_3_eth_payload_tuser(input_3_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tid(s_eth_payload_axis_tid), + .s_eth_payload_axis_tdest(s_eth_payload_axis_tdest), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tid(m_eth_payload_axis_tid), + .m_eth_payload_axis_tdest(m_eth_payload_axis_tdest), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Control .enable(enable), .select(select) diff --git a/tb/test_eth_mux_64_4.py b/tb/test_eth_mux_64_4.py index e629e3f1f..8beb729eb 100755 --- a/tb/test_eth_mux_64_4.py +++ b/tb/test_eth_mux_64_4.py @@ -28,8 +28,8 @@ import os import eth_ep -module = 'eth_mux_64_4' -testbench = 'test_%s' % module +module = 'eth_mux' +testbench = 'test_%s_64_4' % module srcs = [] @@ -42,177 +42,119 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_eth_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_eth_payload_tdata = Signal(intbv(0)[64:]) - input_0_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_0_eth_payload_tvalid = Signal(bool(0)) - input_0_eth_payload_tlast = Signal(bool(0)) - input_0_eth_payload_tuser = Signal(bool(0)) - input_1_eth_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_eth_payload_tdata = Signal(intbv(0)[64:]) - input_1_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_1_eth_payload_tvalid = Signal(bool(0)) - input_1_eth_payload_tlast = Signal(bool(0)) - input_1_eth_payload_tuser = Signal(bool(0)) - input_2_eth_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_eth_payload_tdata = Signal(intbv(0)[64:]) - input_2_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_2_eth_payload_tvalid = Signal(bool(0)) - input_2_eth_payload_tlast = Signal(bool(0)) - input_2_eth_payload_tuser = Signal(bool(0)) - input_3_eth_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_eth_payload_tdata = Signal(intbv(0)[64:]) - input_3_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_3_eth_payload_tvalid = Signal(bool(0)) - input_3_eth_payload_tlast = Signal(bool(0)) - input_3_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_eth_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + s_eth_hdr_valid = ConcatSignal(*reversed(s_eth_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_eth_payload_axis_tdata = ConcatSignal(*reversed(s_eth_payload_axis_tdata_list)) + s_eth_payload_axis_tkeep = ConcatSignal(*reversed(s_eth_payload_axis_tkeep_list)) + s_eth_payload_axis_tvalid = ConcatSignal(*reversed(s_eth_payload_axis_tvalid_list)) + s_eth_payload_axis_tlast = ConcatSignal(*reversed(s_eth_payload_axis_tlast_list)) + s_eth_payload_axis_tid = ConcatSignal(*reversed(s_eth_payload_axis_tid_list)) + s_eth_payload_axis_tdest = ConcatSignal(*reversed(s_eth_payload_axis_tdest_list)) + s_eth_payload_axis_tuser = ConcatSignal(*reversed(s_eth_payload_axis_tuser_list)) + + m_eth_hdr_ready = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_0_eth_hdr_ready = Signal(bool(0)) - input_0_eth_payload_tready = Signal(bool(0)) - input_1_eth_hdr_ready = Signal(bool(0)) - input_1_eth_payload_tready = Signal(bool(0)) - input_2_eth_hdr_ready = Signal(bool(0)) - input_2_eth_payload_tready = Signal(bool(0)) - input_3_eth_hdr_ready = Signal(bool(0)) - input_3_eth_payload_tready = Signal(bool(0)) + s_eth_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_eth_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[64:]) - output_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready_list = [s_eth_hdr_ready(i) for i in range(S_COUNT)] + s_eth_payload_axis_tready_list = [s_eth_payload_axis_tready(i) for i in range(S_COUNT)] + + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_eth_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_eth_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_eth_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = eth_ep.EthFrameSource() + for k in range(S_COUNT): + s = eth_ep.EthFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - eth_hdr_ready=input_0_eth_hdr_ready, - eth_hdr_valid=input_0_eth_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - eth_type=input_0_eth_type, - eth_payload_tdata=input_0_eth_payload_tdata, - eth_payload_tkeep=input_0_eth_payload_tkeep, - eth_payload_tvalid=input_0_eth_payload_tvalid, - eth_payload_tready=input_0_eth_payload_tready, - eth_payload_tlast=input_0_eth_payload_tlast, - eth_payload_tuser=input_0_eth_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = eth_ep.EthFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - eth_hdr_ready=input_1_eth_hdr_ready, - eth_hdr_valid=input_1_eth_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - eth_type=input_1_eth_type, - eth_payload_tdata=input_1_eth_payload_tdata, - eth_payload_tkeep=input_1_eth_payload_tkeep, - eth_payload_tvalid=input_1_eth_payload_tvalid, - eth_payload_tready=input_1_eth_payload_tready, - eth_payload_tlast=input_1_eth_payload_tlast, - eth_payload_tuser=input_1_eth_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = eth_ep.EthFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - eth_hdr_ready=input_2_eth_hdr_ready, - eth_hdr_valid=input_2_eth_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - eth_payload_tdata=input_2_eth_payload_tdata, - eth_payload_tkeep=input_2_eth_payload_tkeep, - eth_payload_tvalid=input_2_eth_payload_tvalid, - eth_payload_tready=input_2_eth_payload_tready, - eth_payload_tlast=input_2_eth_payload_tlast, - eth_payload_tuser=input_2_eth_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = eth_ep.EthFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - eth_hdr_ready=input_3_eth_hdr_ready, - eth_hdr_valid=input_3_eth_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - eth_payload_tdata=input_3_eth_payload_tdata, - eth_payload_tkeep=input_3_eth_payload_tkeep, - eth_payload_tvalid=input_3_eth_payload_tvalid, - eth_payload_tready=input_3_eth_payload_tready, - eth_payload_tlast=input_3_eth_payload_tlast, - eth_payload_tuser=input_3_eth_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + eth_hdr_ready=s_eth_hdr_ready_list[k], + eth_hdr_valid=s_eth_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + eth_payload_tdata=s_eth_payload_axis_tdata_list[k], + eth_payload_tkeep=s_eth_payload_axis_tkeep_list[k], + eth_payload_tvalid=s_eth_payload_axis_tvalid_list[k], + eth_payload_tready=s_eth_payload_axis_tready_list[k], + eth_payload_tlast=s_eth_payload_axis_tlast_list[k], + eth_payload_tuser=s_eth_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = eth_ep.EthFrameSink() sink_logic = sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -227,62 +169,33 @@ def bench(): rst=rst, current_test=current_test, - input_0_eth_hdr_valid=input_0_eth_hdr_valid, - input_0_eth_hdr_ready=input_0_eth_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_eth_payload_tdata=input_0_eth_payload_tdata, - input_0_eth_payload_tkeep=input_0_eth_payload_tkeep, - input_0_eth_payload_tvalid=input_0_eth_payload_tvalid, - input_0_eth_payload_tready=input_0_eth_payload_tready, - input_0_eth_payload_tlast=input_0_eth_payload_tlast, - input_0_eth_payload_tuser=input_0_eth_payload_tuser, - input_1_eth_hdr_valid=input_1_eth_hdr_valid, - input_1_eth_hdr_ready=input_1_eth_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_eth_payload_tdata=input_1_eth_payload_tdata, - input_1_eth_payload_tkeep=input_1_eth_payload_tkeep, - input_1_eth_payload_tvalid=input_1_eth_payload_tvalid, - input_1_eth_payload_tready=input_1_eth_payload_tready, - input_1_eth_payload_tlast=input_1_eth_payload_tlast, - input_1_eth_payload_tuser=input_1_eth_payload_tuser, - input_2_eth_hdr_valid=input_2_eth_hdr_valid, - input_2_eth_hdr_ready=input_2_eth_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_eth_payload_tdata=input_2_eth_payload_tdata, - input_2_eth_payload_tkeep=input_2_eth_payload_tkeep, - input_2_eth_payload_tvalid=input_2_eth_payload_tvalid, - input_2_eth_payload_tready=input_2_eth_payload_tready, - input_2_eth_payload_tlast=input_2_eth_payload_tlast, - input_2_eth_payload_tuser=input_2_eth_payload_tuser, - input_3_eth_hdr_valid=input_3_eth_hdr_valid, - input_3_eth_hdr_ready=input_3_eth_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_eth_payload_tdata=input_3_eth_payload_tdata, - input_3_eth_payload_tkeep=input_3_eth_payload_tkeep, - input_3_eth_payload_tvalid=input_3_eth_payload_tvalid, - input_3_eth_payload_tready=input_3_eth_payload_tready, - input_3_eth_payload_tlast=input_3_eth_payload_tlast, - input_3_eth_payload_tuser=input_3_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tid=s_eth_payload_axis_tid, + s_eth_payload_axis_tdest=s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tid=m_eth_payload_axis_tid, + m_eth_payload_axis_tdest=m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, enable=enable, select=select @@ -318,7 +231,7 @@ def bench(): test_frame.eth_type = 0x8000 test_frame.payload = bytearray(range(32)) - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -339,7 +252,7 @@ def bench(): test_frame.eth_type = 0x8000 test_frame.payload = bytearray(range(32)) - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -365,8 +278,8 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -397,12 +310,12 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + while s_eth_payload_axis_tvalid: yield clk.posedge select.next = 2 @@ -435,23 +348,23 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_eth_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge select.next = 2 @@ -484,12 +397,12 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + while s_eth_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_eth_mux_64_4.v b/tb/test_eth_mux_64_4.v index 46d9110b5..3353806a4 100644 --- a/tb/test_eth_mux_64_4.v +++ b/tb/test_eth_mux_64_4.v @@ -27,77 +27,60 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for eth_mux_64_4 + * Testbench for eth_mux */ module test_eth_mux_64_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_eth_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [63:0] input_0_eth_payload_tdata = 0; -reg [7:0] input_0_eth_payload_tkeep = 0; -reg input_0_eth_payload_tvalid = 0; -reg input_0_eth_payload_tlast = 0; -reg input_0_eth_payload_tuser = 0; -reg input_1_eth_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [63:0] input_1_eth_payload_tdata = 0; -reg [7:0] input_1_eth_payload_tkeep = 0; -reg input_1_eth_payload_tvalid = 0; -reg input_1_eth_payload_tlast = 0; -reg input_1_eth_payload_tuser = 0; -reg input_2_eth_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [63:0] input_2_eth_payload_tdata = 0; -reg [7:0] input_2_eth_payload_tkeep = 0; -reg input_2_eth_payload_tvalid = 0; -reg input_2_eth_payload_tlast = 0; -reg input_2_eth_payload_tuser = 0; -reg input_3_eth_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [63:0] input_3_eth_payload_tdata = 0; -reg [7:0] input_3_eth_payload_tkeep = 0; -reg input_3_eth_payload_tvalid = 0; -reg input_3_eth_payload_tlast = 0; -reg input_3_eth_payload_tuser = 0; +reg [S_COUNT-1:0] s_eth_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_eth_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_eth_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_eth_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_eth_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_eth_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_eth_payload_axis_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; reg enable = 0; reg [1:0] select = 0; // Outputs -wire input_0_eth_payload_tready; -wire input_0_eth_hdr_ready; -wire input_1_eth_payload_tready; -wire input_1_eth_hdr_ready; -wire input_2_eth_payload_tready; -wire input_2_eth_hdr_ready; -wire input_3_eth_payload_tready; -wire input_3_eth_hdr_ready; +wire [S_COUNT-1:0] s_eth_hdr_ready; +wire [S_COUNT-1:0] s_eth_payload_axis_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [63:0] output_eth_payload_tdata; -wire [7:0] output_eth_payload_tkeep; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [DATA_WIDTH-1:0] m_eth_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_eth_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_eth_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_eth_payload_axis_tuser; initial begin // myhdl integration @@ -105,65 +88,36 @@ initial begin clk, rst, current_test, - input_0_eth_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_eth_payload_tdata, - input_0_eth_payload_tkeep, - input_0_eth_payload_tvalid, - input_0_eth_payload_tlast, - input_0_eth_payload_tuser, - input_1_eth_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_eth_payload_tdata, - input_1_eth_payload_tkeep, - input_1_eth_payload_tvalid, - input_1_eth_payload_tlast, - input_1_eth_payload_tuser, - input_2_eth_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_eth_payload_tdata, - input_2_eth_payload_tkeep, - input_2_eth_payload_tvalid, - input_2_eth_payload_tlast, - input_2_eth_payload_tuser, - input_3_eth_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_eth_payload_tdata, - input_3_eth_payload_tkeep, - input_3_eth_payload_tvalid, - input_3_eth_payload_tlast, - input_3_eth_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tid, + s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, enable, select ); $to_myhdl( - input_0_eth_hdr_ready, - input_0_eth_payload_tready, - input_1_eth_hdr_ready, - input_1_eth_payload_tready, - input_2_eth_hdr_ready, - input_2_eth_payload_tready, - input_3_eth_hdr_ready, - input_3_eth_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tid, + m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser ); // dump file @@ -171,67 +125,49 @@ initial begin $dumpvars(0, test_eth_mux_64_4); end -eth_mux_64_4 +eth_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), // Ethernet frame inputs - .input_0_eth_hdr_valid(input_0_eth_hdr_valid), - .input_0_eth_hdr_ready(input_0_eth_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_eth_payload_tdata(input_0_eth_payload_tdata), - .input_0_eth_payload_tkeep(input_0_eth_payload_tkeep), - .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid), - .input_0_eth_payload_tready(input_0_eth_payload_tready), - .input_0_eth_payload_tlast(input_0_eth_payload_tlast), - .input_0_eth_payload_tuser(input_0_eth_payload_tuser), - .input_1_eth_hdr_valid(input_1_eth_hdr_valid), - .input_1_eth_hdr_ready(input_1_eth_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_eth_payload_tdata(input_1_eth_payload_tdata), - .input_1_eth_payload_tkeep(input_1_eth_payload_tkeep), - .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid), - .input_1_eth_payload_tready(input_1_eth_payload_tready), - .input_1_eth_payload_tlast(input_1_eth_payload_tlast), - .input_1_eth_payload_tuser(input_1_eth_payload_tuser), - .input_2_eth_hdr_valid(input_2_eth_hdr_valid), - .input_2_eth_hdr_ready(input_2_eth_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_eth_payload_tdata(input_2_eth_payload_tdata), - .input_2_eth_payload_tkeep(input_2_eth_payload_tkeep), - .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid), - .input_2_eth_payload_tready(input_2_eth_payload_tready), - .input_2_eth_payload_tlast(input_2_eth_payload_tlast), - .input_2_eth_payload_tuser(input_2_eth_payload_tuser), - .input_3_eth_hdr_valid(input_3_eth_hdr_valid), - .input_3_eth_hdr_ready(input_3_eth_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_eth_payload_tdata(input_3_eth_payload_tdata), - .input_3_eth_payload_tkeep(input_3_eth_payload_tkeep), - .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid), - .input_3_eth_payload_tready(input_3_eth_payload_tready), - .input_3_eth_payload_tlast(input_3_eth_payload_tlast), - .input_3_eth_payload_tuser(input_3_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tid(s_eth_payload_axis_tid), + .s_eth_payload_axis_tdest(s_eth_payload_axis_tdest), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tid(m_eth_payload_axis_tid), + .m_eth_payload_axis_tdest(m_eth_payload_axis_tdest), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Control .enable(enable), .select(select) From f20312b1997f517bc6126793f1b147bedddd2b24 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 Oct 2018 18:08:39 -0700 Subject: [PATCH 458/617] Convert generated ip_mux to verilog parametrized module --- rtl/ip_mux.py | 504 -------------------------------- rtl/ip_mux.v | 390 +++++++++++++++++++++++++ rtl/ip_mux_2.v | 488 ------------------------------- rtl/ip_mux_4.v | 612 -------------------------------------- rtl/ip_mux_64.py | 517 -------------------------------- rtl/ip_mux_64_2.v | 503 -------------------------------- rtl/ip_mux_64_4.v | 631 --------------------------------------- tb/test_ip_mux_4.py | 634 +++++++++++++++------------------------- tb/test_ip_mux_4.v | 532 ++++++++++++--------------------- tb/test_ip_mux_64_4.py | 649 +++++++++++++++-------------------------- tb/test_ip_mux_64_4.v | 547 ++++++++++++---------------------- 11 files changed, 1214 insertions(+), 4793 deletions(-) delete mode 100755 rtl/ip_mux.py create mode 100644 rtl/ip_mux.v delete mode 100644 rtl/ip_mux_2.v delete mode 100644 rtl/ip_mux_4.v delete mode 100755 rtl/ip_mux_64.py delete mode 100644 rtl/ip_mux_64_2.v delete mode 100644 rtl/ip_mux_64_4.v diff --git a/rtl/ip_mux.py b/rtl/ip_mux.py deleted file mode 100755 index 20c053979..000000000 --- a/rtl/ip_mux.py +++ /dev/null @@ -1,504 +0,0 @@ -#!/usr/bin/env python -""" -Generates an IP mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "ip_mux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port IP mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * IP {{n}} port multiplexer - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_ip_hdr_valid, - output wire input_{{p}}_ip_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [3:0] input_{{p}}_ip_version, - input wire [3:0] input_{{p}}_ip_ihl, - input wire [5:0] input_{{p}}_ip_dscp, - input wire [1:0] input_{{p}}_ip_ecn, - input wire [15:0] input_{{p}}_ip_length, - input wire [15:0] input_{{p}}_ip_identification, - input wire [2:0] input_{{p}}_ip_flags, - input wire [12:0] input_{{p}}_ip_fragment_offset, - input wire [7:0] input_{{p}}_ip_ttl, - input wire [7:0] input_{{p}}_ip_protocol, - input wire [15:0] input_{{p}}_ip_header_checksum, - input wire [31:0] input_{{p}}_ip_source_ip, - input wire [31:0] input_{{p}}_ip_dest_ip, - input wire [7:0] input_{{p}}_ip_payload_tdata, - input wire input_{{p}}_ip_payload_tvalid, - output wire input_{{p}}_ip_payload_tready, - input wire input_{{p}}_ip_payload_tlast, - input wire input_{{p}}_ip_payload_tuser, -{% endfor %} - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; -{% for p in ports %} -reg input_{{p}}_ip_hdr_ready_reg = 1'b0, input_{{p}}_ip_hdr_ready_next; -{%- endfor %} -{% for p in ports %} -reg input_{{p}}_ip_payload_tready_reg = 1'b0, input_{{p}}_ip_payload_tready_next; -{%- endfor %} - -reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; - -// internal datapath -reg [7:0] output_ip_payload_tdata_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; -{% for p in ports %} -assign input_{{p}}_ip_hdr_ready = input_{{p}}_ip_hdr_ready_reg; -{%- endfor %} -{% for p in ports %} -assign input_{{p}}_ip_payload_tready = input_{{p}}_ip_payload_tready_reg; -{%- endfor %} - -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; - -// mux for start of packet detection -reg selected_input_ip_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -reg [3:0] selected_input_ip_version; -reg [3:0] selected_input_ip_ihl; -reg [5:0] selected_input_ip_dscp; -reg [1:0] selected_input_ip_ecn; -reg [15:0] selected_input_ip_length; -reg [15:0] selected_input_ip_identification; -reg [2:0] selected_input_ip_flags; -reg [12:0] selected_input_ip_fragment_offset; -reg [7:0] selected_input_ip_ttl; -reg [7:0] selected_input_ip_protocol; -reg [15:0] selected_input_ip_header_checksum; -reg [31:0] selected_input_ip_source_ip; -reg [31:0] selected_input_ip_dest_ip; -always @* begin - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: begin - selected_input_ip_hdr_valid = input_{{p}}_ip_hdr_valid; - selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; - selected_input_eth_src_mac = input_{{p}}_eth_src_mac; - selected_input_eth_type = input_{{p}}_eth_type; - selected_input_ip_version = input_{{p}}_ip_version; - selected_input_ip_ihl = input_{{p}}_ip_ihl; - selected_input_ip_dscp = input_{{p}}_ip_dscp; - selected_input_ip_ecn = input_{{p}}_ip_ecn; - selected_input_ip_length = input_{{p}}_ip_length; - selected_input_ip_identification = input_{{p}}_ip_identification; - selected_input_ip_flags = input_{{p}}_ip_flags; - selected_input_ip_fragment_offset = input_{{p}}_ip_fragment_offset; - selected_input_ip_ttl = input_{{p}}_ip_ttl; - selected_input_ip_protocol = input_{{p}}_ip_protocol; - selected_input_ip_header_checksum = input_{{p}}_ip_header_checksum; - selected_input_ip_source_ip = input_{{p}}_ip_source_ip; - selected_input_ip_dest_ip = input_{{p}}_ip_dest_ip; - end -{%- endfor %} - default: begin - selected_input_ip_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - selected_input_ip_version = 4'd0; - selected_input_ip_ihl = 4'd0; - selected_input_ip_dscp = 6'd0; - selected_input_ip_ecn = 2'd0; - selected_input_ip_length = 16'd0; - selected_input_ip_identification = 16'd0; - selected_input_ip_flags = 3'd0; - selected_input_ip_fragment_offset = 13'd0; - selected_input_ip_ttl = 8'd0; - selected_input_ip_protocol = 8'd0; - selected_input_ip_header_checksum = 16'd0; - selected_input_ip_source_ip = 32'd0; - selected_input_ip_dest_ip = 32'd0; - end - endcase -end - -// mux for incoming packet -reg [7:0] current_input_tdata; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_input_tdata = input_{{p}}_ip_payload_tdata; - current_input_tvalid = input_{{p}}_ip_payload_tvalid; - current_input_tready = input_{{p}}_ip_payload_tready; - current_input_tlast = input_{{p}}_ip_payload_tlast; - current_input_tuser = input_{{p}}_ip_payload_tuser; - end -{%- endfor %} - default: begin - current_input_tdata = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; -{% for p in ports %} - input_{{p}}_ip_hdr_ready_next = input_{{p}}_ip_hdr_ready_reg & ~input_{{p}}_ip_hdr_valid; -{%- endfor %} -{% for p in ports %} - input_{{p}}_ip_payload_tready_next = 1'b0; -{%- endfor %} - - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_ip_hdr_ready_next = 1'b1; -{%- endfor %} - endcase - - output_ip_hdr_valid_next = 1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - output_ip_version_next = selected_input_ip_version; - output_ip_ihl_next = selected_input_ip_ihl; - output_ip_dscp_next = selected_input_ip_dscp; - output_ip_ecn_next = selected_input_ip_ecn; - output_ip_length_next = selected_input_ip_length; - output_ip_identification_next = selected_input_ip_identification; - output_ip_flags_next = selected_input_ip_flags; - output_ip_fragment_offset_next = selected_input_ip_fragment_offset; - output_ip_ttl_next = selected_input_ip_ttl; - output_ip_protocol_next = selected_input_ip_protocol; - output_ip_header_checksum_next = selected_input_ip_header_checksum; - output_ip_source_ip_next = selected_input_ip_source_ip; - output_ip_dest_ip_next = selected_input_ip_dest_ip; - end - - // generate ready signal on selected port - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; -{%- endfor %} - endcase - - // pass through selected packet data - output_ip_payload_tdata_int = current_input_tdata; - output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_ip_payload_tlast_int = current_input_tlast; - output_ip_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; -{%- for p in ports %} - input_{{p}}_ip_hdr_ready_reg <= 1'b0; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_ip_payload_tready_reg <= 1'b0; -{%- endfor %} - output_ip_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; -{%- for p in ports %} - input_{{p}}_ip_hdr_ready_reg <= input_{{p}}_ip_hdr_ready_next; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_ip_payload_tready_reg <= input_{{p}}_ip_payload_tready_next; -{%- endfor %} - output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; -end - -// output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 8'd0; -reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; - -reg [7:0] temp_ip_payload_tdata_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; - -// datapath control -reg store_ip_payload_int_to_output; -reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; - -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - - store_ip_payload_int_to_output = 1'b0; - store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; - - if (output_ip_payload_tready_int_reg) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_temp = 1'b1; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; - end else begin - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; - end - - // datapath - if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - - if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/ip_mux.v b/rtl/ip_mux.v new file mode 100644 index 000000000..f05edf6b3 --- /dev/null +++ b/rtl/ip_mux.v @@ -0,0 +1,390 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * IP multiplexer + */ +module ip_mux # +( + parameter S_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ + input wire [S_COUNT-1:0] s_ip_hdr_valid, + output wire [S_COUNT-1:0] s_ip_hdr_ready, + input wire [S_COUNT*48-1:0] s_eth_dest_mac, + input wire [S_COUNT*48-1:0] s_eth_src_mac, + input wire [S_COUNT*16-1:0] s_eth_type, + input wire [S_COUNT*4-1:0] s_ip_version, + input wire [S_COUNT*4-1:0] s_ip_ihl, + input wire [S_COUNT*6-1:0] s_ip_dscp, + input wire [S_COUNT*2-1:0] s_ip_ecn, + input wire [S_COUNT*16-1:0] s_ip_length, + input wire [S_COUNT*16-1:0] s_ip_identification, + input wire [S_COUNT*3-1:0] s_ip_flags, + input wire [S_COUNT*13-1:0] s_ip_fragment_offset, + input wire [S_COUNT*8-1:0] s_ip_ttl, + input wire [S_COUNT*8-1:0] s_ip_protocol, + input wire [S_COUNT*16-1:0] s_ip_header_checksum, + input wire [S_COUNT*32-1:0] s_ip_source_ip, + input wire [S_COUNT*32-1:0] s_ip_dest_ip, + input wire [S_COUNT*DATA_WIDTH-1:0] s_ip_payload_axis_tdata, + input wire [S_COUNT*KEEP_WIDTH-1:0] s_ip_payload_axis_tkeep, + input wire [S_COUNT-1:0] s_ip_payload_axis_tvalid, + output wire [S_COUNT-1:0] s_ip_payload_axis_tready, + input wire [S_COUNT-1:0] s_ip_payload_axis_tlast, + input wire [S_COUNT*ID_WIDTH-1:0] s_ip_payload_axis_tid, + input wire [S_COUNT*DEST_WIDTH-1:0] s_ip_payload_axis_tdest, + input wire [S_COUNT*USER_WIDTH-1:0] s_ip_payload_axis_tuser, + + /* + * IP frame output + */ + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [DATA_WIDTH-1:0] m_ip_payload_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire [ID_WIDTH-1:0] m_ip_payload_axis_tid, + output wire [DEST_WIDTH-1:0] m_ip_payload_axis_tdest, + output wire [USER_WIDTH-1:0] m_ip_payload_axis_tuser, + + /* + * Control + */ + input wire enable, + input wire [$clog2(S_COUNT)-1:0] select +); + +parameter CL_S_COUNT = $clog2(S_COUNT); + +reg [CL_S_COUNT-1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; + +reg [S_COUNT-1:0] s_ip_hdr_ready_reg = 0, s_ip_hdr_ready_next; + +reg [S_COUNT-1:0] s_ip_payload_axis_tready_reg = 0, s_ip_payload_axis_tready_next; + +reg m_ip_hdr_valid_reg = 1'b0, m_ip_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0, m_eth_dest_mac_next; +reg [47:0] m_eth_src_mac_reg = 48'd0, m_eth_src_mac_next; +reg [15:0] m_eth_type_reg = 16'd0, m_eth_type_next; +reg [3:0] m_ip_version_reg = 4'd0, m_ip_version_next; +reg [3:0] m_ip_ihl_reg = 4'd0, m_ip_ihl_next; +reg [5:0] m_ip_dscp_reg = 6'd0, m_ip_dscp_next; +reg [1:0] m_ip_ecn_reg = 2'd0, m_ip_ecn_next; +reg [15:0] m_ip_length_reg = 16'd0, m_ip_length_next; +reg [15:0] m_ip_identification_reg = 16'd0, m_ip_identification_next; +reg [2:0] m_ip_flags_reg = 3'd0, m_ip_flags_next; +reg [12:0] m_ip_fragment_offset_reg = 13'd0, m_ip_fragment_offset_next; +reg [7:0] m_ip_ttl_reg = 8'd0, m_ip_ttl_next; +reg [7:0] m_ip_protocol_reg = 8'd0, m_ip_protocol_next; +reg [15:0] m_ip_header_checksum_reg = 16'd0, m_ip_header_checksum_next; +reg [31:0] m_ip_source_ip_reg = 32'd0, m_ip_source_ip_next; +reg [31:0] m_ip_dest_ip_reg = 32'd0, m_ip_dest_ip_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_ip_payload_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep_int; +reg m_ip_payload_axis_tvalid_int; +reg m_ip_payload_axis_tready_int_reg = 1'b0; +reg m_ip_payload_axis_tlast_int; +reg [ID_WIDTH-1:0] m_ip_payload_axis_tid_int; +reg [DEST_WIDTH-1:0] m_ip_payload_axis_tdest_int; +reg [USER_WIDTH-1:0] m_ip_payload_axis_tuser_int; +wire m_ip_payload_axis_tready_int_early; + +assign s_ip_hdr_ready = s_ip_hdr_ready_reg; + +assign s_ip_payload_axis_tready = s_ip_payload_axis_tready_reg; + +assign m_ip_hdr_valid = m_ip_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_ip_length_reg; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = m_ip_protocol_reg; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; + +// mux for incoming packet +wire [DATA_WIDTH-1:0] current_s_tdata = s_ip_payload_axis_tdata[select_reg*DATA_WIDTH +: DATA_WIDTH]; +wire [KEEP_WIDTH-1:0] current_s_tkeep = s_ip_payload_axis_tkeep[select_reg*KEEP_WIDTH +: KEEP_WIDTH]; +wire current_s_tvalid = s_ip_payload_axis_tvalid[select_reg]; +wire current_s_tready = s_ip_payload_axis_tready[select_reg]; +wire current_s_tlast = s_ip_payload_axis_tlast[select_reg]; +wire [ID_WIDTH-1:0] current_s_tid = s_ip_payload_axis_tid[select_reg*ID_WIDTH +: ID_WIDTH]; +wire [DEST_WIDTH-1:0] current_s_tdest = s_ip_payload_axis_tdest[select_reg*DEST_WIDTH +: DEST_WIDTH]; +wire [USER_WIDTH-1:0] current_s_tuser = s_ip_payload_axis_tuser[select_reg*USER_WIDTH +: USER_WIDTH]; + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + s_ip_hdr_ready_next = 0; + + s_ip_payload_axis_tready_next = 0; + + m_ip_hdr_valid_next = m_ip_hdr_valid_reg && !m_ip_hdr_ready; + m_eth_dest_mac_next = m_eth_dest_mac_reg; + m_eth_src_mac_next = m_eth_src_mac_reg; + m_eth_type_next = m_eth_type_reg; + m_ip_version_next = m_ip_version_reg; + m_ip_ihl_next = m_ip_ihl_reg; + m_ip_dscp_next = m_ip_dscp_reg; + m_ip_ecn_next = m_ip_ecn_reg; + m_ip_length_next = m_ip_length_reg; + m_ip_identification_next = m_ip_identification_reg; + m_ip_flags_next = m_ip_flags_reg; + m_ip_fragment_offset_next = m_ip_fragment_offset_reg; + m_ip_ttl_next = m_ip_ttl_reg; + m_ip_protocol_next = m_ip_protocol_reg; + m_ip_header_checksum_next = m_ip_header_checksum_reg; + m_ip_source_ip_next = m_ip_source_ip_reg; + m_ip_dest_ip_next = m_ip_dest_ip_reg; + + if (current_s_tvalid & current_s_tready) begin + // end of frame detection + if (current_s_tlast) begin + frame_next = 1'b0; + end + end + + if (!frame_reg && enable && !m_ip_hdr_valid && (s_ip_hdr_valid & (1 << select))) begin + // start of frame, grab select value + frame_next = 1'b1; + select_next = select; + + s_ip_hdr_ready_next = (1 << select); + + m_ip_hdr_valid_next = 1'b1; + m_eth_dest_mac_next = s_eth_dest_mac[select*48 +: 48]; + m_eth_src_mac_next = s_eth_src_mac[select*48 +: 48]; + m_eth_type_next = s_eth_type[select*16 +: 16]; + m_ip_version_next = s_ip_version[select*4 +: 4]; + m_ip_ihl_next = s_ip_ihl[select*4 +: 4]; + m_ip_dscp_next = s_ip_dscp[select*6 +: 6]; + m_ip_ecn_next = s_ip_ecn[select*2 +: 2]; + m_ip_length_next = s_ip_length[select*16 +: 16]; + m_ip_identification_next = s_ip_identification[select*16 +: 16]; + m_ip_flags_next = s_ip_flags[select*3 +: 3]; + m_ip_fragment_offset_next = s_ip_fragment_offset[select*13 +: 13]; + m_ip_ttl_next = s_ip_ttl[select*8 +: 8]; + m_ip_protocol_next = s_ip_protocol[select*8 +: 8]; + m_ip_header_checksum_next = s_ip_header_checksum[select*16 +: 16]; + m_ip_source_ip_next = s_ip_source_ip[select*32 +: 32]; + m_ip_dest_ip_next = s_ip_dest_ip[select*32 +: 32]; + end + + // generate ready signal on selected port + s_ip_payload_axis_tready_next = (m_ip_payload_axis_tready_int_early && frame_next) << select_next; + + // pass through selected packet data + m_ip_payload_axis_tdata_int = current_s_tdata; + m_ip_payload_axis_tkeep_int = current_s_tkeep; + m_ip_payload_axis_tvalid_int = current_s_tvalid && current_s_tready && frame_reg; + m_ip_payload_axis_tlast_int = current_s_tlast; + m_ip_payload_axis_tid_int = current_s_tid; + m_ip_payload_axis_tdest_int = current_s_tdest; + m_ip_payload_axis_tuser_int = current_s_tuser; +end + +always @(posedge clk) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 1'b0; + s_ip_hdr_ready_reg <= 0; + s_ip_payload_axis_tready_reg <= 0; + m_ip_hdr_valid_reg <= 1'b0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; + s_ip_payload_axis_tready_reg <= s_ip_payload_axis_tready_next; + m_ip_hdr_valid_reg <= m_ip_hdr_valid_next; + end + + m_eth_dest_mac_reg <= m_eth_dest_mac_next; + m_eth_src_mac_reg <= m_eth_src_mac_next; + m_eth_type_reg <= m_eth_type_next; + m_ip_version_reg <= m_ip_version_next; + m_ip_ihl_reg <= m_ip_ihl_next; + m_ip_dscp_reg <= m_ip_dscp_next; + m_ip_ecn_reg <= m_ip_ecn_next; + m_ip_length_reg <= m_ip_length_next; + m_ip_identification_reg <= m_ip_identification_next; + m_ip_flags_reg <= m_ip_flags_next; + m_ip_fragment_offset_reg <= m_ip_fragment_offset_next; + m_ip_ttl_reg <= m_ip_ttl_next; + m_ip_protocol_reg <= m_ip_protocol_next; + m_ip_header_checksum_reg <= m_ip_header_checksum_next; + m_ip_source_ip_reg <= m_ip_source_ip_next; + m_ip_dest_ip_reg <= m_ip_dest_ip_next; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_ip_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_ip_payload_axis_tvalid_reg = 1'b0, m_ip_payload_axis_tvalid_next; +reg m_ip_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_ip_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_ip_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_ip_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_ip_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_ip_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_ip_payload_axis_tvalid_reg = 1'b0, temp_m_ip_payload_axis_tvalid_next; +reg temp_m_ip_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_ip_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_ip_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_ip_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign m_ip_payload_axis_tdata = m_ip_payload_axis_tdata_reg; +assign m_ip_payload_axis_tkeep = KEEP_ENABLE ? m_ip_payload_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_ip_payload_axis_tvalid = m_ip_payload_axis_tvalid_reg; +assign m_ip_payload_axis_tlast = m_ip_payload_axis_tlast_reg; +assign m_ip_payload_axis_tid = ID_ENABLE ? m_ip_payload_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_ip_payload_axis_tdest = DEST_ENABLE ? m_ip_payload_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_ip_payload_axis_tuser = USER_ENABLE ? m_ip_payload_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_ip_payload_axis_tready_int_early = m_ip_payload_axis_tready || (!temp_m_ip_payload_axis_tvalid_reg && (!m_ip_payload_axis_tvalid_reg || !m_ip_payload_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (m_ip_payload_axis_tready_int_reg) begin + // input is ready + if (m_ip_payload_axis_tready || !m_ip_payload_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_ip_payload_axis_tready) begin + // input is not ready, but output is ready + m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_ip_payload_axis_tvalid_reg <= 1'b0; + m_ip_payload_axis_tready_int_reg <= 1'b0; + temp_m_ip_payload_axis_tvalid_reg <= 1'b0; + end else begin + m_ip_payload_axis_tvalid_reg <= m_ip_payload_axis_tvalid_next; + m_ip_payload_axis_tready_int_reg <= m_ip_payload_axis_tready_int_early; + temp_m_ip_payload_axis_tvalid_reg <= temp_m_ip_payload_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + m_ip_payload_axis_tkeep_reg <= m_ip_payload_axis_tkeep_int; + m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + m_ip_payload_axis_tid_reg <= m_ip_payload_axis_tid_int; + m_ip_payload_axis_tdest_reg <= m_ip_payload_axis_tdest_int; + m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + m_ip_payload_axis_tdata_reg <= temp_m_ip_payload_axis_tdata_reg; + m_ip_payload_axis_tkeep_reg <= temp_m_ip_payload_axis_tkeep_reg; + m_ip_payload_axis_tlast_reg <= temp_m_ip_payload_axis_tlast_reg; + m_ip_payload_axis_tid_reg <= temp_m_ip_payload_axis_tid_reg; + m_ip_payload_axis_tdest_reg <= temp_m_ip_payload_axis_tdest_reg; + m_ip_payload_axis_tuser_reg <= temp_m_ip_payload_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + temp_m_ip_payload_axis_tkeep_reg <= m_ip_payload_axis_tkeep_int; + temp_m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + temp_m_ip_payload_axis_tid_reg <= m_ip_payload_axis_tid_int; + temp_m_ip_payload_axis_tdest_reg <= m_ip_payload_axis_tdest_int; + temp_m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/ip_mux_2.v b/rtl/ip_mux_2.v deleted file mode 100644 index 5a41c2675..000000000 --- a/rtl/ip_mux_2.v +++ /dev/null @@ -1,488 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * IP 2 port multiplexer - */ -module ip_mux_2 -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ - input wire input_0_ip_hdr_valid, - output wire input_0_ip_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [7:0] input_0_ip_payload_tdata, - input wire input_0_ip_payload_tvalid, - output wire input_0_ip_payload_tready, - input wire input_0_ip_payload_tlast, - input wire input_0_ip_payload_tuser, - - input wire input_1_ip_hdr_valid, - output wire input_1_ip_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [7:0] input_1_ip_payload_tdata, - input wire input_1_ip_payload_tvalid, - output wire input_1_ip_payload_tready, - input wire input_1_ip_payload_tlast, - input wire input_1_ip_payload_tuser, - - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [0:0] select -); - -reg [0:0] select_reg = 1'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_ip_hdr_ready_reg = 1'b0, input_0_ip_hdr_ready_next; -reg input_1_ip_hdr_ready_reg = 1'b0, input_1_ip_hdr_ready_next; - -reg input_0_ip_payload_tready_reg = 1'b0, input_0_ip_payload_tready_next; -reg input_1_ip_payload_tready_reg = 1'b0, input_1_ip_payload_tready_next; - -reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; - -// internal datapath -reg [7:0] output_ip_payload_tdata_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; - -assign input_0_ip_hdr_ready = input_0_ip_hdr_ready_reg; -assign input_1_ip_hdr_ready = input_1_ip_hdr_ready_reg; - -assign input_0_ip_payload_tready = input_0_ip_payload_tready_reg; -assign input_1_ip_payload_tready = input_1_ip_payload_tready_reg; - -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; - -// mux for start of packet detection -reg selected_input_ip_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -reg [3:0] selected_input_ip_version; -reg [3:0] selected_input_ip_ihl; -reg [5:0] selected_input_ip_dscp; -reg [1:0] selected_input_ip_ecn; -reg [15:0] selected_input_ip_length; -reg [15:0] selected_input_ip_identification; -reg [2:0] selected_input_ip_flags; -reg [12:0] selected_input_ip_fragment_offset; -reg [7:0] selected_input_ip_ttl; -reg [7:0] selected_input_ip_protocol; -reg [15:0] selected_input_ip_header_checksum; -reg [31:0] selected_input_ip_source_ip; -reg [31:0] selected_input_ip_dest_ip; -always @* begin - case (select) - 1'd0: begin - selected_input_ip_hdr_valid = input_0_ip_hdr_valid; - selected_input_eth_dest_mac = input_0_eth_dest_mac; - selected_input_eth_src_mac = input_0_eth_src_mac; - selected_input_eth_type = input_0_eth_type; - selected_input_ip_version = input_0_ip_version; - selected_input_ip_ihl = input_0_ip_ihl; - selected_input_ip_dscp = input_0_ip_dscp; - selected_input_ip_ecn = input_0_ip_ecn; - selected_input_ip_length = input_0_ip_length; - selected_input_ip_identification = input_0_ip_identification; - selected_input_ip_flags = input_0_ip_flags; - selected_input_ip_fragment_offset = input_0_ip_fragment_offset; - selected_input_ip_ttl = input_0_ip_ttl; - selected_input_ip_protocol = input_0_ip_protocol; - selected_input_ip_header_checksum = input_0_ip_header_checksum; - selected_input_ip_source_ip = input_0_ip_source_ip; - selected_input_ip_dest_ip = input_0_ip_dest_ip; - end - 1'd1: begin - selected_input_ip_hdr_valid = input_1_ip_hdr_valid; - selected_input_eth_dest_mac = input_1_eth_dest_mac; - selected_input_eth_src_mac = input_1_eth_src_mac; - selected_input_eth_type = input_1_eth_type; - selected_input_ip_version = input_1_ip_version; - selected_input_ip_ihl = input_1_ip_ihl; - selected_input_ip_dscp = input_1_ip_dscp; - selected_input_ip_ecn = input_1_ip_ecn; - selected_input_ip_length = input_1_ip_length; - selected_input_ip_identification = input_1_ip_identification; - selected_input_ip_flags = input_1_ip_flags; - selected_input_ip_fragment_offset = input_1_ip_fragment_offset; - selected_input_ip_ttl = input_1_ip_ttl; - selected_input_ip_protocol = input_1_ip_protocol; - selected_input_ip_header_checksum = input_1_ip_header_checksum; - selected_input_ip_source_ip = input_1_ip_source_ip; - selected_input_ip_dest_ip = input_1_ip_dest_ip; - end - default: begin - selected_input_ip_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - selected_input_ip_version = 4'd0; - selected_input_ip_ihl = 4'd0; - selected_input_ip_dscp = 6'd0; - selected_input_ip_ecn = 2'd0; - selected_input_ip_length = 16'd0; - selected_input_ip_identification = 16'd0; - selected_input_ip_flags = 3'd0; - selected_input_ip_fragment_offset = 13'd0; - selected_input_ip_ttl = 8'd0; - selected_input_ip_protocol = 8'd0; - selected_input_ip_header_checksum = 16'd0; - selected_input_ip_source_ip = 32'd0; - selected_input_ip_dest_ip = 32'd0; - end - endcase -end - -// mux for incoming packet -reg [7:0] current_input_tdata; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 1'd0: begin - current_input_tdata = input_0_ip_payload_tdata; - current_input_tvalid = input_0_ip_payload_tvalid; - current_input_tready = input_0_ip_payload_tready; - current_input_tlast = input_0_ip_payload_tlast; - current_input_tuser = input_0_ip_payload_tuser; - end - 1'd1: begin - current_input_tdata = input_1_ip_payload_tdata; - current_input_tvalid = input_1_ip_payload_tvalid; - current_input_tready = input_1_ip_payload_tready; - current_input_tlast = input_1_ip_payload_tlast; - current_input_tuser = input_1_ip_payload_tuser; - end - default: begin - current_input_tdata = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_ip_hdr_ready_next = input_0_ip_hdr_ready_reg & ~input_0_ip_hdr_valid; - input_1_ip_hdr_ready_next = input_1_ip_hdr_ready_reg & ~input_1_ip_hdr_valid; - - input_0_ip_payload_tready_next = 1'b0; - input_1_ip_payload_tready_next = 1'b0; - - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) - 1'd0: input_0_ip_hdr_ready_next = 1'b1; - 1'd1: input_1_ip_hdr_ready_next = 1'b1; - endcase - - output_ip_hdr_valid_next = 1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - output_ip_version_next = selected_input_ip_version; - output_ip_ihl_next = selected_input_ip_ihl; - output_ip_dscp_next = selected_input_ip_dscp; - output_ip_ecn_next = selected_input_ip_ecn; - output_ip_length_next = selected_input_ip_length; - output_ip_identification_next = selected_input_ip_identification; - output_ip_flags_next = selected_input_ip_flags; - output_ip_fragment_offset_next = selected_input_ip_fragment_offset; - output_ip_ttl_next = selected_input_ip_ttl; - output_ip_protocol_next = selected_input_ip_protocol; - output_ip_header_checksum_next = selected_input_ip_header_checksum; - output_ip_source_ip_next = selected_input_ip_source_ip; - output_ip_dest_ip_next = selected_input_ip_dest_ip; - end - - // generate ready signal on selected port - case (select_next) - 1'd0: input_0_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - 1'd1: input_1_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_ip_payload_tdata_int = current_input_tdata; - output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_ip_payload_tlast_int = current_input_tlast; - output_ip_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 1'd0; - frame_reg <= 1'b0; - input_0_ip_hdr_ready_reg <= 1'b0; - input_1_ip_hdr_ready_reg <= 1'b0; - input_0_ip_payload_tready_reg <= 1'b0; - input_1_ip_payload_tready_reg <= 1'b0; - output_ip_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_ip_hdr_ready_reg <= input_0_ip_hdr_ready_next; - input_1_ip_hdr_ready_reg <= input_1_ip_hdr_ready_next; - input_0_ip_payload_tready_reg <= input_0_ip_payload_tready_next; - input_1_ip_payload_tready_reg <= input_1_ip_payload_tready_next; - output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; -end - -// output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 8'd0; -reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; - -reg [7:0] temp_ip_payload_tdata_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; - -// datapath control -reg store_ip_payload_int_to_output; -reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; - -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - - store_ip_payload_int_to_output = 1'b0; - store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; - - if (output_ip_payload_tready_int_reg) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_temp = 1'b1; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; - end else begin - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; - end - - // datapath - if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - - if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end -end - -endmodule diff --git a/rtl/ip_mux_4.v b/rtl/ip_mux_4.v deleted file mode 100644 index 0e7cdfb14..000000000 --- a/rtl/ip_mux_4.v +++ /dev/null @@ -1,612 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * IP 4 port multiplexer - */ -module ip_mux_4 -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ - input wire input_0_ip_hdr_valid, - output wire input_0_ip_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [7:0] input_0_ip_payload_tdata, - input wire input_0_ip_payload_tvalid, - output wire input_0_ip_payload_tready, - input wire input_0_ip_payload_tlast, - input wire input_0_ip_payload_tuser, - - input wire input_1_ip_hdr_valid, - output wire input_1_ip_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [7:0] input_1_ip_payload_tdata, - input wire input_1_ip_payload_tvalid, - output wire input_1_ip_payload_tready, - input wire input_1_ip_payload_tlast, - input wire input_1_ip_payload_tuser, - - input wire input_2_ip_hdr_valid, - output wire input_2_ip_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [3:0] input_2_ip_version, - input wire [3:0] input_2_ip_ihl, - input wire [5:0] input_2_ip_dscp, - input wire [1:0] input_2_ip_ecn, - input wire [15:0] input_2_ip_length, - input wire [15:0] input_2_ip_identification, - input wire [2:0] input_2_ip_flags, - input wire [12:0] input_2_ip_fragment_offset, - input wire [7:0] input_2_ip_ttl, - input wire [7:0] input_2_ip_protocol, - input wire [15:0] input_2_ip_header_checksum, - input wire [31:0] input_2_ip_source_ip, - input wire [31:0] input_2_ip_dest_ip, - input wire [7:0] input_2_ip_payload_tdata, - input wire input_2_ip_payload_tvalid, - output wire input_2_ip_payload_tready, - input wire input_2_ip_payload_tlast, - input wire input_2_ip_payload_tuser, - - input wire input_3_ip_hdr_valid, - output wire input_3_ip_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [3:0] input_3_ip_version, - input wire [3:0] input_3_ip_ihl, - input wire [5:0] input_3_ip_dscp, - input wire [1:0] input_3_ip_ecn, - input wire [15:0] input_3_ip_length, - input wire [15:0] input_3_ip_identification, - input wire [2:0] input_3_ip_flags, - input wire [12:0] input_3_ip_fragment_offset, - input wire [7:0] input_3_ip_ttl, - input wire [7:0] input_3_ip_protocol, - input wire [15:0] input_3_ip_header_checksum, - input wire [31:0] input_3_ip_source_ip, - input wire [31:0] input_3_ip_dest_ip, - input wire [7:0] input_3_ip_payload_tdata, - input wire input_3_ip_payload_tvalid, - output wire input_3_ip_payload_tready, - input wire input_3_ip_payload_tlast, - input wire input_3_ip_payload_tuser, - - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_ip_hdr_ready_reg = 1'b0, input_0_ip_hdr_ready_next; -reg input_1_ip_hdr_ready_reg = 1'b0, input_1_ip_hdr_ready_next; -reg input_2_ip_hdr_ready_reg = 1'b0, input_2_ip_hdr_ready_next; -reg input_3_ip_hdr_ready_reg = 1'b0, input_3_ip_hdr_ready_next; - -reg input_0_ip_payload_tready_reg = 1'b0, input_0_ip_payload_tready_next; -reg input_1_ip_payload_tready_reg = 1'b0, input_1_ip_payload_tready_next; -reg input_2_ip_payload_tready_reg = 1'b0, input_2_ip_payload_tready_next; -reg input_3_ip_payload_tready_reg = 1'b0, input_3_ip_payload_tready_next; - -reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; - -// internal datapath -reg [7:0] output_ip_payload_tdata_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; - -assign input_0_ip_hdr_ready = input_0_ip_hdr_ready_reg; -assign input_1_ip_hdr_ready = input_1_ip_hdr_ready_reg; -assign input_2_ip_hdr_ready = input_2_ip_hdr_ready_reg; -assign input_3_ip_hdr_ready = input_3_ip_hdr_ready_reg; - -assign input_0_ip_payload_tready = input_0_ip_payload_tready_reg; -assign input_1_ip_payload_tready = input_1_ip_payload_tready_reg; -assign input_2_ip_payload_tready = input_2_ip_payload_tready_reg; -assign input_3_ip_payload_tready = input_3_ip_payload_tready_reg; - -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; - -// mux for start of packet detection -reg selected_input_ip_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -reg [3:0] selected_input_ip_version; -reg [3:0] selected_input_ip_ihl; -reg [5:0] selected_input_ip_dscp; -reg [1:0] selected_input_ip_ecn; -reg [15:0] selected_input_ip_length; -reg [15:0] selected_input_ip_identification; -reg [2:0] selected_input_ip_flags; -reg [12:0] selected_input_ip_fragment_offset; -reg [7:0] selected_input_ip_ttl; -reg [7:0] selected_input_ip_protocol; -reg [15:0] selected_input_ip_header_checksum; -reg [31:0] selected_input_ip_source_ip; -reg [31:0] selected_input_ip_dest_ip; -always @* begin - case (select) - 2'd0: begin - selected_input_ip_hdr_valid = input_0_ip_hdr_valid; - selected_input_eth_dest_mac = input_0_eth_dest_mac; - selected_input_eth_src_mac = input_0_eth_src_mac; - selected_input_eth_type = input_0_eth_type; - selected_input_ip_version = input_0_ip_version; - selected_input_ip_ihl = input_0_ip_ihl; - selected_input_ip_dscp = input_0_ip_dscp; - selected_input_ip_ecn = input_0_ip_ecn; - selected_input_ip_length = input_0_ip_length; - selected_input_ip_identification = input_0_ip_identification; - selected_input_ip_flags = input_0_ip_flags; - selected_input_ip_fragment_offset = input_0_ip_fragment_offset; - selected_input_ip_ttl = input_0_ip_ttl; - selected_input_ip_protocol = input_0_ip_protocol; - selected_input_ip_header_checksum = input_0_ip_header_checksum; - selected_input_ip_source_ip = input_0_ip_source_ip; - selected_input_ip_dest_ip = input_0_ip_dest_ip; - end - 2'd1: begin - selected_input_ip_hdr_valid = input_1_ip_hdr_valid; - selected_input_eth_dest_mac = input_1_eth_dest_mac; - selected_input_eth_src_mac = input_1_eth_src_mac; - selected_input_eth_type = input_1_eth_type; - selected_input_ip_version = input_1_ip_version; - selected_input_ip_ihl = input_1_ip_ihl; - selected_input_ip_dscp = input_1_ip_dscp; - selected_input_ip_ecn = input_1_ip_ecn; - selected_input_ip_length = input_1_ip_length; - selected_input_ip_identification = input_1_ip_identification; - selected_input_ip_flags = input_1_ip_flags; - selected_input_ip_fragment_offset = input_1_ip_fragment_offset; - selected_input_ip_ttl = input_1_ip_ttl; - selected_input_ip_protocol = input_1_ip_protocol; - selected_input_ip_header_checksum = input_1_ip_header_checksum; - selected_input_ip_source_ip = input_1_ip_source_ip; - selected_input_ip_dest_ip = input_1_ip_dest_ip; - end - 2'd2: begin - selected_input_ip_hdr_valid = input_2_ip_hdr_valid; - selected_input_eth_dest_mac = input_2_eth_dest_mac; - selected_input_eth_src_mac = input_2_eth_src_mac; - selected_input_eth_type = input_2_eth_type; - selected_input_ip_version = input_2_ip_version; - selected_input_ip_ihl = input_2_ip_ihl; - selected_input_ip_dscp = input_2_ip_dscp; - selected_input_ip_ecn = input_2_ip_ecn; - selected_input_ip_length = input_2_ip_length; - selected_input_ip_identification = input_2_ip_identification; - selected_input_ip_flags = input_2_ip_flags; - selected_input_ip_fragment_offset = input_2_ip_fragment_offset; - selected_input_ip_ttl = input_2_ip_ttl; - selected_input_ip_protocol = input_2_ip_protocol; - selected_input_ip_header_checksum = input_2_ip_header_checksum; - selected_input_ip_source_ip = input_2_ip_source_ip; - selected_input_ip_dest_ip = input_2_ip_dest_ip; - end - 2'd3: begin - selected_input_ip_hdr_valid = input_3_ip_hdr_valid; - selected_input_eth_dest_mac = input_3_eth_dest_mac; - selected_input_eth_src_mac = input_3_eth_src_mac; - selected_input_eth_type = input_3_eth_type; - selected_input_ip_version = input_3_ip_version; - selected_input_ip_ihl = input_3_ip_ihl; - selected_input_ip_dscp = input_3_ip_dscp; - selected_input_ip_ecn = input_3_ip_ecn; - selected_input_ip_length = input_3_ip_length; - selected_input_ip_identification = input_3_ip_identification; - selected_input_ip_flags = input_3_ip_flags; - selected_input_ip_fragment_offset = input_3_ip_fragment_offset; - selected_input_ip_ttl = input_3_ip_ttl; - selected_input_ip_protocol = input_3_ip_protocol; - selected_input_ip_header_checksum = input_3_ip_header_checksum; - selected_input_ip_source_ip = input_3_ip_source_ip; - selected_input_ip_dest_ip = input_3_ip_dest_ip; - end - default: begin - selected_input_ip_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - selected_input_ip_version = 4'd0; - selected_input_ip_ihl = 4'd0; - selected_input_ip_dscp = 6'd0; - selected_input_ip_ecn = 2'd0; - selected_input_ip_length = 16'd0; - selected_input_ip_identification = 16'd0; - selected_input_ip_flags = 3'd0; - selected_input_ip_fragment_offset = 13'd0; - selected_input_ip_ttl = 8'd0; - selected_input_ip_protocol = 8'd0; - selected_input_ip_header_checksum = 16'd0; - selected_input_ip_source_ip = 32'd0; - selected_input_ip_dest_ip = 32'd0; - end - endcase -end - -// mux for incoming packet -reg [7:0] current_input_tdata; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 2'd0: begin - current_input_tdata = input_0_ip_payload_tdata; - current_input_tvalid = input_0_ip_payload_tvalid; - current_input_tready = input_0_ip_payload_tready; - current_input_tlast = input_0_ip_payload_tlast; - current_input_tuser = input_0_ip_payload_tuser; - end - 2'd1: begin - current_input_tdata = input_1_ip_payload_tdata; - current_input_tvalid = input_1_ip_payload_tvalid; - current_input_tready = input_1_ip_payload_tready; - current_input_tlast = input_1_ip_payload_tlast; - current_input_tuser = input_1_ip_payload_tuser; - end - 2'd2: begin - current_input_tdata = input_2_ip_payload_tdata; - current_input_tvalid = input_2_ip_payload_tvalid; - current_input_tready = input_2_ip_payload_tready; - current_input_tlast = input_2_ip_payload_tlast; - current_input_tuser = input_2_ip_payload_tuser; - end - 2'd3: begin - current_input_tdata = input_3_ip_payload_tdata; - current_input_tvalid = input_3_ip_payload_tvalid; - current_input_tready = input_3_ip_payload_tready; - current_input_tlast = input_3_ip_payload_tlast; - current_input_tuser = input_3_ip_payload_tuser; - end - default: begin - current_input_tdata = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_ip_hdr_ready_next = input_0_ip_hdr_ready_reg & ~input_0_ip_hdr_valid; - input_1_ip_hdr_ready_next = input_1_ip_hdr_ready_reg & ~input_1_ip_hdr_valid; - input_2_ip_hdr_ready_next = input_2_ip_hdr_ready_reg & ~input_2_ip_hdr_valid; - input_3_ip_hdr_ready_next = input_3_ip_hdr_ready_reg & ~input_3_ip_hdr_valid; - - input_0_ip_payload_tready_next = 1'b0; - input_1_ip_payload_tready_next = 1'b0; - input_2_ip_payload_tready_next = 1'b0; - input_3_ip_payload_tready_next = 1'b0; - - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) - 2'd0: input_0_ip_hdr_ready_next = 1'b1; - 2'd1: input_1_ip_hdr_ready_next = 1'b1; - 2'd2: input_2_ip_hdr_ready_next = 1'b1; - 2'd3: input_3_ip_hdr_ready_next = 1'b1; - endcase - - output_ip_hdr_valid_next = 1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - output_ip_version_next = selected_input_ip_version; - output_ip_ihl_next = selected_input_ip_ihl; - output_ip_dscp_next = selected_input_ip_dscp; - output_ip_ecn_next = selected_input_ip_ecn; - output_ip_length_next = selected_input_ip_length; - output_ip_identification_next = selected_input_ip_identification; - output_ip_flags_next = selected_input_ip_flags; - output_ip_fragment_offset_next = selected_input_ip_fragment_offset; - output_ip_ttl_next = selected_input_ip_ttl; - output_ip_protocol_next = selected_input_ip_protocol; - output_ip_header_checksum_next = selected_input_ip_header_checksum; - output_ip_source_ip_next = selected_input_ip_source_ip; - output_ip_dest_ip_next = selected_input_ip_dest_ip; - end - - // generate ready signal on selected port - case (select_next) - 2'd0: input_0_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - 2'd1: input_1_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - 2'd2: input_2_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - 2'd3: input_3_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_ip_payload_tdata_int = current_input_tdata; - output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_ip_payload_tlast_int = current_input_tlast; - output_ip_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_0_ip_hdr_ready_reg <= 1'b0; - input_1_ip_hdr_ready_reg <= 1'b0; - input_2_ip_hdr_ready_reg <= 1'b0; - input_3_ip_hdr_ready_reg <= 1'b0; - input_0_ip_payload_tready_reg <= 1'b0; - input_1_ip_payload_tready_reg <= 1'b0; - input_2_ip_payload_tready_reg <= 1'b0; - input_3_ip_payload_tready_reg <= 1'b0; - output_ip_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_ip_hdr_ready_reg <= input_0_ip_hdr_ready_next; - input_1_ip_hdr_ready_reg <= input_1_ip_hdr_ready_next; - input_2_ip_hdr_ready_reg <= input_2_ip_hdr_ready_next; - input_3_ip_hdr_ready_reg <= input_3_ip_hdr_ready_next; - input_0_ip_payload_tready_reg <= input_0_ip_payload_tready_next; - input_1_ip_payload_tready_reg <= input_1_ip_payload_tready_next; - input_2_ip_payload_tready_reg <= input_2_ip_payload_tready_next; - input_3_ip_payload_tready_reg <= input_3_ip_payload_tready_next; - output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; -end - -// output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 8'd0; -reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; - -reg [7:0] temp_ip_payload_tdata_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; - -// datapath control -reg store_ip_payload_int_to_output; -reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; - -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - - store_ip_payload_int_to_output = 1'b0; - store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; - - if (output_ip_payload_tready_int_reg) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_temp = 1'b1; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; - end else begin - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; - end - - // datapath - if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - - if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end -end - -endmodule diff --git a/rtl/ip_mux_64.py b/rtl/ip_mux_64.py deleted file mode 100755 index c7c503a53..000000000 --- a/rtl/ip_mux_64.py +++ /dev/null @@ -1,517 +0,0 @@ -#!/usr/bin/env python -""" -Generates an IP mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "ip_mux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port IP mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * IP {{n}} port multiplexer (64 bit datapath) - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_ip_hdr_valid, - output wire input_{{p}}_ip_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [3:0] input_{{p}}_ip_version, - input wire [3:0] input_{{p}}_ip_ihl, - input wire [5:0] input_{{p}}_ip_dscp, - input wire [1:0] input_{{p}}_ip_ecn, - input wire [15:0] input_{{p}}_ip_length, - input wire [15:0] input_{{p}}_ip_identification, - input wire [2:0] input_{{p}}_ip_flags, - input wire [12:0] input_{{p}}_ip_fragment_offset, - input wire [7:0] input_{{p}}_ip_ttl, - input wire [7:0] input_{{p}}_ip_protocol, - input wire [15:0] input_{{p}}_ip_header_checksum, - input wire [31:0] input_{{p}}_ip_source_ip, - input wire [31:0] input_{{p}}_ip_dest_ip, - input wire [63:0] input_{{p}}_ip_payload_tdata, - input wire [7:0] input_{{p}}_ip_payload_tkeep, - input wire input_{{p}}_ip_payload_tvalid, - output wire input_{{p}}_ip_payload_tready, - input wire input_{{p}}_ip_payload_tlast, - input wire input_{{p}}_ip_payload_tuser, -{% endfor %} - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; -{% for p in ports %} -reg input_{{p}}_ip_hdr_ready_reg = 1'b0, input_{{p}}_ip_hdr_ready_next; -{%- endfor %} -{% for p in ports %} -reg input_{{p}}_ip_payload_tready_reg = 1'b0, input_{{p}}_ip_payload_tready_next; -{%- endfor %} - -reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; - -// internal datapath -reg [63:0] output_ip_payload_tdata_int; -reg [7:0] output_ip_payload_tkeep_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; -{% for p in ports %} -assign input_{{p}}_ip_hdr_ready = input_{{p}}_ip_hdr_ready_reg; -{%- endfor %} -{% for p in ports %} -assign input_{{p}}_ip_payload_tready = input_{{p}}_ip_payload_tready_reg; -{%- endfor %} - -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; - -// mux for start of packet detection -reg selected_input_ip_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -reg [3:0] selected_input_ip_version; -reg [3:0] selected_input_ip_ihl; -reg [5:0] selected_input_ip_dscp; -reg [1:0] selected_input_ip_ecn; -reg [15:0] selected_input_ip_length; -reg [15:0] selected_input_ip_identification; -reg [2:0] selected_input_ip_flags; -reg [12:0] selected_input_ip_fragment_offset; -reg [7:0] selected_input_ip_ttl; -reg [7:0] selected_input_ip_protocol; -reg [15:0] selected_input_ip_header_checksum; -reg [31:0] selected_input_ip_source_ip; -reg [31:0] selected_input_ip_dest_ip; -always @* begin - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: begin - selected_input_ip_hdr_valid = input_{{p}}_ip_hdr_valid; - selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; - selected_input_eth_src_mac = input_{{p}}_eth_src_mac; - selected_input_eth_type = input_{{p}}_eth_type; - selected_input_ip_version = input_{{p}}_ip_version; - selected_input_ip_ihl = input_{{p}}_ip_ihl; - selected_input_ip_dscp = input_{{p}}_ip_dscp; - selected_input_ip_ecn = input_{{p}}_ip_ecn; - selected_input_ip_length = input_{{p}}_ip_length; - selected_input_ip_identification = input_{{p}}_ip_identification; - selected_input_ip_flags = input_{{p}}_ip_flags; - selected_input_ip_fragment_offset = input_{{p}}_ip_fragment_offset; - selected_input_ip_ttl = input_{{p}}_ip_ttl; - selected_input_ip_protocol = input_{{p}}_ip_protocol; - selected_input_ip_header_checksum = input_{{p}}_ip_header_checksum; - selected_input_ip_source_ip = input_{{p}}_ip_source_ip; - selected_input_ip_dest_ip = input_{{p}}_ip_dest_ip; - end -{%- endfor %} - default: begin - selected_input_ip_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - selected_input_ip_version = 4'd0; - selected_input_ip_ihl = 4'd0; - selected_input_ip_dscp = 6'd0; - selected_input_ip_ecn = 2'd0; - selected_input_ip_length = 16'd0; - selected_input_ip_identification = 16'd0; - selected_input_ip_flags = 3'd0; - selected_input_ip_fragment_offset = 13'd0; - selected_input_ip_ttl = 8'd0; - selected_input_ip_protocol = 8'd0; - selected_input_ip_header_checksum = 16'd0; - selected_input_ip_source_ip = 32'd0; - selected_input_ip_dest_ip = 32'd0; - end - endcase -end - -// mux for incoming packet -reg [63:0] current_input_tdata; -reg [7:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_input_tdata = input_{{p}}_ip_payload_tdata; - current_input_tkeep = input_{{p}}_ip_payload_tkeep; - current_input_tvalid = input_{{p}}_ip_payload_tvalid; - current_input_tready = input_{{p}}_ip_payload_tready; - current_input_tlast = input_{{p}}_ip_payload_tlast; - current_input_tuser = input_{{p}}_ip_payload_tuser; - end -{%- endfor %} - default: begin - current_input_tdata = 64'd0; - current_input_tkeep = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; -{% for p in ports %} - input_{{p}}_ip_hdr_ready_next = input_{{p}}_ip_hdr_ready_reg & ~input_{{p}}_ip_hdr_valid; -{%- endfor %} -{% for p in ports %} - input_{{p}}_ip_payload_tready_next = 1'b0; -{%- endfor %} - - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_ip_hdr_ready_next = 1'b1; -{%- endfor %} - endcase - - output_ip_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - output_ip_version_next = selected_input_ip_version; - output_ip_ihl_next = selected_input_ip_ihl; - output_ip_dscp_next = selected_input_ip_dscp; - output_ip_ecn_next = selected_input_ip_ecn; - output_ip_length_next = selected_input_ip_length; - output_ip_identification_next = selected_input_ip_identification; - output_ip_flags_next = selected_input_ip_flags; - output_ip_fragment_offset_next = selected_input_ip_fragment_offset; - output_ip_ttl_next = selected_input_ip_ttl; - output_ip_protocol_next = selected_input_ip_protocol; - output_ip_header_checksum_next = selected_input_ip_header_checksum; - output_ip_source_ip_next = selected_input_ip_source_ip; - output_ip_dest_ip_next = selected_input_ip_dest_ip; - end - - // generate ready signal on selected port - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; -{%- endfor %} - endcase - - // pass through selected packet data - output_ip_payload_tdata_int = current_input_tdata; - output_ip_payload_tkeep_int = current_input_tkeep; - output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_ip_payload_tlast_int = current_input_tlast; - output_ip_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; -{%- for p in ports %} - input_{{p}}_ip_hdr_ready_reg <= 1'b0; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_ip_payload_tready_reg <= 1'b0; -{%- endfor %} - output_ip_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; -{%- for p in ports %} - input_{{p}}_ip_hdr_ready_reg <= input_{{p}}_ip_hdr_ready_next; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_ip_payload_tready_reg <= input_{{p}}_ip_payload_tready_next; -{%- endfor %} - output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; -end - -// output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 64'd0; -reg [7:0] output_ip_payload_tkeep_reg = 8'd0; -reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; - -reg [63:0] temp_ip_payload_tdata_reg = 64'd0; -reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; - -// datapath control -reg store_ip_payload_int_to_output; -reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; - -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - - store_ip_payload_int_to_output = 1'b0; - store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; - - if (output_ip_payload_tready_int_reg) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_temp = 1'b1; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; - end else begin - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; - end - - // datapath - if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - - if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/ip_mux_64_2.v b/rtl/ip_mux_64_2.v deleted file mode 100644 index ae7465a1d..000000000 --- a/rtl/ip_mux_64_2.v +++ /dev/null @@ -1,503 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * IP 2 port multiplexer (64 bit datapath) - */ -module ip_mux_64_2 -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ - input wire input_0_ip_hdr_valid, - output wire input_0_ip_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [63:0] input_0_ip_payload_tdata, - input wire [7:0] input_0_ip_payload_tkeep, - input wire input_0_ip_payload_tvalid, - output wire input_0_ip_payload_tready, - input wire input_0_ip_payload_tlast, - input wire input_0_ip_payload_tuser, - - input wire input_1_ip_hdr_valid, - output wire input_1_ip_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [63:0] input_1_ip_payload_tdata, - input wire [7:0] input_1_ip_payload_tkeep, - input wire input_1_ip_payload_tvalid, - output wire input_1_ip_payload_tready, - input wire input_1_ip_payload_tlast, - input wire input_1_ip_payload_tuser, - - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [0:0] select -); - -reg [0:0] select_reg = 1'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_ip_hdr_ready_reg = 1'b0, input_0_ip_hdr_ready_next; -reg input_1_ip_hdr_ready_reg = 1'b0, input_1_ip_hdr_ready_next; - -reg input_0_ip_payload_tready_reg = 1'b0, input_0_ip_payload_tready_next; -reg input_1_ip_payload_tready_reg = 1'b0, input_1_ip_payload_tready_next; - -reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; - -// internal datapath -reg [63:0] output_ip_payload_tdata_int; -reg [7:0] output_ip_payload_tkeep_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; - -assign input_0_ip_hdr_ready = input_0_ip_hdr_ready_reg; -assign input_1_ip_hdr_ready = input_1_ip_hdr_ready_reg; - -assign input_0_ip_payload_tready = input_0_ip_payload_tready_reg; -assign input_1_ip_payload_tready = input_1_ip_payload_tready_reg; - -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; - -// mux for start of packet detection -reg selected_input_ip_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -reg [3:0] selected_input_ip_version; -reg [3:0] selected_input_ip_ihl; -reg [5:0] selected_input_ip_dscp; -reg [1:0] selected_input_ip_ecn; -reg [15:0] selected_input_ip_length; -reg [15:0] selected_input_ip_identification; -reg [2:0] selected_input_ip_flags; -reg [12:0] selected_input_ip_fragment_offset; -reg [7:0] selected_input_ip_ttl; -reg [7:0] selected_input_ip_protocol; -reg [15:0] selected_input_ip_header_checksum; -reg [31:0] selected_input_ip_source_ip; -reg [31:0] selected_input_ip_dest_ip; -always @* begin - case (select) - 1'd0: begin - selected_input_ip_hdr_valid = input_0_ip_hdr_valid; - selected_input_eth_dest_mac = input_0_eth_dest_mac; - selected_input_eth_src_mac = input_0_eth_src_mac; - selected_input_eth_type = input_0_eth_type; - selected_input_ip_version = input_0_ip_version; - selected_input_ip_ihl = input_0_ip_ihl; - selected_input_ip_dscp = input_0_ip_dscp; - selected_input_ip_ecn = input_0_ip_ecn; - selected_input_ip_length = input_0_ip_length; - selected_input_ip_identification = input_0_ip_identification; - selected_input_ip_flags = input_0_ip_flags; - selected_input_ip_fragment_offset = input_0_ip_fragment_offset; - selected_input_ip_ttl = input_0_ip_ttl; - selected_input_ip_protocol = input_0_ip_protocol; - selected_input_ip_header_checksum = input_0_ip_header_checksum; - selected_input_ip_source_ip = input_0_ip_source_ip; - selected_input_ip_dest_ip = input_0_ip_dest_ip; - end - 1'd1: begin - selected_input_ip_hdr_valid = input_1_ip_hdr_valid; - selected_input_eth_dest_mac = input_1_eth_dest_mac; - selected_input_eth_src_mac = input_1_eth_src_mac; - selected_input_eth_type = input_1_eth_type; - selected_input_ip_version = input_1_ip_version; - selected_input_ip_ihl = input_1_ip_ihl; - selected_input_ip_dscp = input_1_ip_dscp; - selected_input_ip_ecn = input_1_ip_ecn; - selected_input_ip_length = input_1_ip_length; - selected_input_ip_identification = input_1_ip_identification; - selected_input_ip_flags = input_1_ip_flags; - selected_input_ip_fragment_offset = input_1_ip_fragment_offset; - selected_input_ip_ttl = input_1_ip_ttl; - selected_input_ip_protocol = input_1_ip_protocol; - selected_input_ip_header_checksum = input_1_ip_header_checksum; - selected_input_ip_source_ip = input_1_ip_source_ip; - selected_input_ip_dest_ip = input_1_ip_dest_ip; - end - default: begin - selected_input_ip_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - selected_input_ip_version = 4'd0; - selected_input_ip_ihl = 4'd0; - selected_input_ip_dscp = 6'd0; - selected_input_ip_ecn = 2'd0; - selected_input_ip_length = 16'd0; - selected_input_ip_identification = 16'd0; - selected_input_ip_flags = 3'd0; - selected_input_ip_fragment_offset = 13'd0; - selected_input_ip_ttl = 8'd0; - selected_input_ip_protocol = 8'd0; - selected_input_ip_header_checksum = 16'd0; - selected_input_ip_source_ip = 32'd0; - selected_input_ip_dest_ip = 32'd0; - end - endcase -end - -// mux for incoming packet -reg [63:0] current_input_tdata; -reg [7:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 1'd0: begin - current_input_tdata = input_0_ip_payload_tdata; - current_input_tkeep = input_0_ip_payload_tkeep; - current_input_tvalid = input_0_ip_payload_tvalid; - current_input_tready = input_0_ip_payload_tready; - current_input_tlast = input_0_ip_payload_tlast; - current_input_tuser = input_0_ip_payload_tuser; - end - 1'd1: begin - current_input_tdata = input_1_ip_payload_tdata; - current_input_tkeep = input_1_ip_payload_tkeep; - current_input_tvalid = input_1_ip_payload_tvalid; - current_input_tready = input_1_ip_payload_tready; - current_input_tlast = input_1_ip_payload_tlast; - current_input_tuser = input_1_ip_payload_tuser; - end - default: begin - current_input_tdata = 64'd0; - current_input_tkeep = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_ip_hdr_ready_next = input_0_ip_hdr_ready_reg & ~input_0_ip_hdr_valid; - input_1_ip_hdr_ready_next = input_1_ip_hdr_ready_reg & ~input_1_ip_hdr_valid; - - input_0_ip_payload_tready_next = 1'b0; - input_1_ip_payload_tready_next = 1'b0; - - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) - 1'd0: input_0_ip_hdr_ready_next = 1'b1; - 1'd1: input_1_ip_hdr_ready_next = 1'b1; - endcase - - output_ip_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - output_ip_version_next = selected_input_ip_version; - output_ip_ihl_next = selected_input_ip_ihl; - output_ip_dscp_next = selected_input_ip_dscp; - output_ip_ecn_next = selected_input_ip_ecn; - output_ip_length_next = selected_input_ip_length; - output_ip_identification_next = selected_input_ip_identification; - output_ip_flags_next = selected_input_ip_flags; - output_ip_fragment_offset_next = selected_input_ip_fragment_offset; - output_ip_ttl_next = selected_input_ip_ttl; - output_ip_protocol_next = selected_input_ip_protocol; - output_ip_header_checksum_next = selected_input_ip_header_checksum; - output_ip_source_ip_next = selected_input_ip_source_ip; - output_ip_dest_ip_next = selected_input_ip_dest_ip; - end - - // generate ready signal on selected port - case (select_next) - 1'd0: input_0_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - 1'd1: input_1_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_ip_payload_tdata_int = current_input_tdata; - output_ip_payload_tkeep_int = current_input_tkeep; - output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_ip_payload_tlast_int = current_input_tlast; - output_ip_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 1'd0; - frame_reg <= 1'b0; - input_0_ip_hdr_ready_reg <= 1'b0; - input_1_ip_hdr_ready_reg <= 1'b0; - input_0_ip_payload_tready_reg <= 1'b0; - input_1_ip_payload_tready_reg <= 1'b0; - output_ip_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_ip_hdr_ready_reg <= input_0_ip_hdr_ready_next; - input_1_ip_hdr_ready_reg <= input_1_ip_hdr_ready_next; - input_0_ip_payload_tready_reg <= input_0_ip_payload_tready_next; - input_1_ip_payload_tready_reg <= input_1_ip_payload_tready_next; - output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; -end - -// output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 64'd0; -reg [7:0] output_ip_payload_tkeep_reg = 8'd0; -reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; - -reg [63:0] temp_ip_payload_tdata_reg = 64'd0; -reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; - -// datapath control -reg store_ip_payload_int_to_output; -reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; - -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - - store_ip_payload_int_to_output = 1'b0; - store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; - - if (output_ip_payload_tready_int_reg) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_temp = 1'b1; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; - end else begin - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; - end - - // datapath - if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - - if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end -end - -endmodule diff --git a/rtl/ip_mux_64_4.v b/rtl/ip_mux_64_4.v deleted file mode 100644 index 53fab6513..000000000 --- a/rtl/ip_mux_64_4.v +++ /dev/null @@ -1,631 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * IP 4 port multiplexer (64 bit datapath) - */ -module ip_mux_64_4 -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ - input wire input_0_ip_hdr_valid, - output wire input_0_ip_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [63:0] input_0_ip_payload_tdata, - input wire [7:0] input_0_ip_payload_tkeep, - input wire input_0_ip_payload_tvalid, - output wire input_0_ip_payload_tready, - input wire input_0_ip_payload_tlast, - input wire input_0_ip_payload_tuser, - - input wire input_1_ip_hdr_valid, - output wire input_1_ip_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [63:0] input_1_ip_payload_tdata, - input wire [7:0] input_1_ip_payload_tkeep, - input wire input_1_ip_payload_tvalid, - output wire input_1_ip_payload_tready, - input wire input_1_ip_payload_tlast, - input wire input_1_ip_payload_tuser, - - input wire input_2_ip_hdr_valid, - output wire input_2_ip_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [3:0] input_2_ip_version, - input wire [3:0] input_2_ip_ihl, - input wire [5:0] input_2_ip_dscp, - input wire [1:0] input_2_ip_ecn, - input wire [15:0] input_2_ip_length, - input wire [15:0] input_2_ip_identification, - input wire [2:0] input_2_ip_flags, - input wire [12:0] input_2_ip_fragment_offset, - input wire [7:0] input_2_ip_ttl, - input wire [7:0] input_2_ip_protocol, - input wire [15:0] input_2_ip_header_checksum, - input wire [31:0] input_2_ip_source_ip, - input wire [31:0] input_2_ip_dest_ip, - input wire [63:0] input_2_ip_payload_tdata, - input wire [7:0] input_2_ip_payload_tkeep, - input wire input_2_ip_payload_tvalid, - output wire input_2_ip_payload_tready, - input wire input_2_ip_payload_tlast, - input wire input_2_ip_payload_tuser, - - input wire input_3_ip_hdr_valid, - output wire input_3_ip_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [3:0] input_3_ip_version, - input wire [3:0] input_3_ip_ihl, - input wire [5:0] input_3_ip_dscp, - input wire [1:0] input_3_ip_ecn, - input wire [15:0] input_3_ip_length, - input wire [15:0] input_3_ip_identification, - input wire [2:0] input_3_ip_flags, - input wire [12:0] input_3_ip_fragment_offset, - input wire [7:0] input_3_ip_ttl, - input wire [7:0] input_3_ip_protocol, - input wire [15:0] input_3_ip_header_checksum, - input wire [31:0] input_3_ip_source_ip, - input wire [31:0] input_3_ip_dest_ip, - input wire [63:0] input_3_ip_payload_tdata, - input wire [7:0] input_3_ip_payload_tkeep, - input wire input_3_ip_payload_tvalid, - output wire input_3_ip_payload_tready, - input wire input_3_ip_payload_tlast, - input wire input_3_ip_payload_tuser, - - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_ip_hdr_ready_reg = 1'b0, input_0_ip_hdr_ready_next; -reg input_1_ip_hdr_ready_reg = 1'b0, input_1_ip_hdr_ready_next; -reg input_2_ip_hdr_ready_reg = 1'b0, input_2_ip_hdr_ready_next; -reg input_3_ip_hdr_ready_reg = 1'b0, input_3_ip_hdr_ready_next; - -reg input_0_ip_payload_tready_reg = 1'b0, input_0_ip_payload_tready_next; -reg input_1_ip_payload_tready_reg = 1'b0, input_1_ip_payload_tready_next; -reg input_2_ip_payload_tready_reg = 1'b0, input_2_ip_payload_tready_next; -reg input_3_ip_payload_tready_reg = 1'b0, input_3_ip_payload_tready_next; - -reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; - -// internal datapath -reg [63:0] output_ip_payload_tdata_int; -reg [7:0] output_ip_payload_tkeep_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; - -assign input_0_ip_hdr_ready = input_0_ip_hdr_ready_reg; -assign input_1_ip_hdr_ready = input_1_ip_hdr_ready_reg; -assign input_2_ip_hdr_ready = input_2_ip_hdr_ready_reg; -assign input_3_ip_hdr_ready = input_3_ip_hdr_ready_reg; - -assign input_0_ip_payload_tready = input_0_ip_payload_tready_reg; -assign input_1_ip_payload_tready = input_1_ip_payload_tready_reg; -assign input_2_ip_payload_tready = input_2_ip_payload_tready_reg; -assign input_3_ip_payload_tready = input_3_ip_payload_tready_reg; - -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; - -// mux for start of packet detection -reg selected_input_ip_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -reg [3:0] selected_input_ip_version; -reg [3:0] selected_input_ip_ihl; -reg [5:0] selected_input_ip_dscp; -reg [1:0] selected_input_ip_ecn; -reg [15:0] selected_input_ip_length; -reg [15:0] selected_input_ip_identification; -reg [2:0] selected_input_ip_flags; -reg [12:0] selected_input_ip_fragment_offset; -reg [7:0] selected_input_ip_ttl; -reg [7:0] selected_input_ip_protocol; -reg [15:0] selected_input_ip_header_checksum; -reg [31:0] selected_input_ip_source_ip; -reg [31:0] selected_input_ip_dest_ip; -always @* begin - case (select) - 2'd0: begin - selected_input_ip_hdr_valid = input_0_ip_hdr_valid; - selected_input_eth_dest_mac = input_0_eth_dest_mac; - selected_input_eth_src_mac = input_0_eth_src_mac; - selected_input_eth_type = input_0_eth_type; - selected_input_ip_version = input_0_ip_version; - selected_input_ip_ihl = input_0_ip_ihl; - selected_input_ip_dscp = input_0_ip_dscp; - selected_input_ip_ecn = input_0_ip_ecn; - selected_input_ip_length = input_0_ip_length; - selected_input_ip_identification = input_0_ip_identification; - selected_input_ip_flags = input_0_ip_flags; - selected_input_ip_fragment_offset = input_0_ip_fragment_offset; - selected_input_ip_ttl = input_0_ip_ttl; - selected_input_ip_protocol = input_0_ip_protocol; - selected_input_ip_header_checksum = input_0_ip_header_checksum; - selected_input_ip_source_ip = input_0_ip_source_ip; - selected_input_ip_dest_ip = input_0_ip_dest_ip; - end - 2'd1: begin - selected_input_ip_hdr_valid = input_1_ip_hdr_valid; - selected_input_eth_dest_mac = input_1_eth_dest_mac; - selected_input_eth_src_mac = input_1_eth_src_mac; - selected_input_eth_type = input_1_eth_type; - selected_input_ip_version = input_1_ip_version; - selected_input_ip_ihl = input_1_ip_ihl; - selected_input_ip_dscp = input_1_ip_dscp; - selected_input_ip_ecn = input_1_ip_ecn; - selected_input_ip_length = input_1_ip_length; - selected_input_ip_identification = input_1_ip_identification; - selected_input_ip_flags = input_1_ip_flags; - selected_input_ip_fragment_offset = input_1_ip_fragment_offset; - selected_input_ip_ttl = input_1_ip_ttl; - selected_input_ip_protocol = input_1_ip_protocol; - selected_input_ip_header_checksum = input_1_ip_header_checksum; - selected_input_ip_source_ip = input_1_ip_source_ip; - selected_input_ip_dest_ip = input_1_ip_dest_ip; - end - 2'd2: begin - selected_input_ip_hdr_valid = input_2_ip_hdr_valid; - selected_input_eth_dest_mac = input_2_eth_dest_mac; - selected_input_eth_src_mac = input_2_eth_src_mac; - selected_input_eth_type = input_2_eth_type; - selected_input_ip_version = input_2_ip_version; - selected_input_ip_ihl = input_2_ip_ihl; - selected_input_ip_dscp = input_2_ip_dscp; - selected_input_ip_ecn = input_2_ip_ecn; - selected_input_ip_length = input_2_ip_length; - selected_input_ip_identification = input_2_ip_identification; - selected_input_ip_flags = input_2_ip_flags; - selected_input_ip_fragment_offset = input_2_ip_fragment_offset; - selected_input_ip_ttl = input_2_ip_ttl; - selected_input_ip_protocol = input_2_ip_protocol; - selected_input_ip_header_checksum = input_2_ip_header_checksum; - selected_input_ip_source_ip = input_2_ip_source_ip; - selected_input_ip_dest_ip = input_2_ip_dest_ip; - end - 2'd3: begin - selected_input_ip_hdr_valid = input_3_ip_hdr_valid; - selected_input_eth_dest_mac = input_3_eth_dest_mac; - selected_input_eth_src_mac = input_3_eth_src_mac; - selected_input_eth_type = input_3_eth_type; - selected_input_ip_version = input_3_ip_version; - selected_input_ip_ihl = input_3_ip_ihl; - selected_input_ip_dscp = input_3_ip_dscp; - selected_input_ip_ecn = input_3_ip_ecn; - selected_input_ip_length = input_3_ip_length; - selected_input_ip_identification = input_3_ip_identification; - selected_input_ip_flags = input_3_ip_flags; - selected_input_ip_fragment_offset = input_3_ip_fragment_offset; - selected_input_ip_ttl = input_3_ip_ttl; - selected_input_ip_protocol = input_3_ip_protocol; - selected_input_ip_header_checksum = input_3_ip_header_checksum; - selected_input_ip_source_ip = input_3_ip_source_ip; - selected_input_ip_dest_ip = input_3_ip_dest_ip; - end - default: begin - selected_input_ip_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - selected_input_ip_version = 4'd0; - selected_input_ip_ihl = 4'd0; - selected_input_ip_dscp = 6'd0; - selected_input_ip_ecn = 2'd0; - selected_input_ip_length = 16'd0; - selected_input_ip_identification = 16'd0; - selected_input_ip_flags = 3'd0; - selected_input_ip_fragment_offset = 13'd0; - selected_input_ip_ttl = 8'd0; - selected_input_ip_protocol = 8'd0; - selected_input_ip_header_checksum = 16'd0; - selected_input_ip_source_ip = 32'd0; - selected_input_ip_dest_ip = 32'd0; - end - endcase -end - -// mux for incoming packet -reg [63:0] current_input_tdata; -reg [7:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 2'd0: begin - current_input_tdata = input_0_ip_payload_tdata; - current_input_tkeep = input_0_ip_payload_tkeep; - current_input_tvalid = input_0_ip_payload_tvalid; - current_input_tready = input_0_ip_payload_tready; - current_input_tlast = input_0_ip_payload_tlast; - current_input_tuser = input_0_ip_payload_tuser; - end - 2'd1: begin - current_input_tdata = input_1_ip_payload_tdata; - current_input_tkeep = input_1_ip_payload_tkeep; - current_input_tvalid = input_1_ip_payload_tvalid; - current_input_tready = input_1_ip_payload_tready; - current_input_tlast = input_1_ip_payload_tlast; - current_input_tuser = input_1_ip_payload_tuser; - end - 2'd2: begin - current_input_tdata = input_2_ip_payload_tdata; - current_input_tkeep = input_2_ip_payload_tkeep; - current_input_tvalid = input_2_ip_payload_tvalid; - current_input_tready = input_2_ip_payload_tready; - current_input_tlast = input_2_ip_payload_tlast; - current_input_tuser = input_2_ip_payload_tuser; - end - 2'd3: begin - current_input_tdata = input_3_ip_payload_tdata; - current_input_tkeep = input_3_ip_payload_tkeep; - current_input_tvalid = input_3_ip_payload_tvalid; - current_input_tready = input_3_ip_payload_tready; - current_input_tlast = input_3_ip_payload_tlast; - current_input_tuser = input_3_ip_payload_tuser; - end - default: begin - current_input_tdata = 64'd0; - current_input_tkeep = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_ip_hdr_ready_next = input_0_ip_hdr_ready_reg & ~input_0_ip_hdr_valid; - input_1_ip_hdr_ready_next = input_1_ip_hdr_ready_reg & ~input_1_ip_hdr_valid; - input_2_ip_hdr_ready_next = input_2_ip_hdr_ready_reg & ~input_2_ip_hdr_valid; - input_3_ip_hdr_ready_next = input_3_ip_hdr_ready_reg & ~input_3_ip_hdr_valid; - - input_0_ip_payload_tready_next = 1'b0; - input_1_ip_payload_tready_next = 1'b0; - input_2_ip_payload_tready_next = 1'b0; - input_3_ip_payload_tready_next = 1'b0; - - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_ip_hdr_valid & selected_input_ip_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) - 2'd0: input_0_ip_hdr_ready_next = 1'b1; - 2'd1: input_1_ip_hdr_ready_next = 1'b1; - 2'd2: input_2_ip_hdr_ready_next = 1'b1; - 2'd3: input_3_ip_hdr_ready_next = 1'b1; - endcase - - output_ip_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - output_ip_version_next = selected_input_ip_version; - output_ip_ihl_next = selected_input_ip_ihl; - output_ip_dscp_next = selected_input_ip_dscp; - output_ip_ecn_next = selected_input_ip_ecn; - output_ip_length_next = selected_input_ip_length; - output_ip_identification_next = selected_input_ip_identification; - output_ip_flags_next = selected_input_ip_flags; - output_ip_fragment_offset_next = selected_input_ip_fragment_offset; - output_ip_ttl_next = selected_input_ip_ttl; - output_ip_protocol_next = selected_input_ip_protocol; - output_ip_header_checksum_next = selected_input_ip_header_checksum; - output_ip_source_ip_next = selected_input_ip_source_ip; - output_ip_dest_ip_next = selected_input_ip_dest_ip; - end - - // generate ready signal on selected port - case (select_next) - 2'd0: input_0_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - 2'd1: input_1_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - 2'd2: input_2_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - 2'd3: input_3_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_ip_payload_tdata_int = current_input_tdata; - output_ip_payload_tkeep_int = current_input_tkeep; - output_ip_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_ip_payload_tlast_int = current_input_tlast; - output_ip_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_0_ip_hdr_ready_reg <= 1'b0; - input_1_ip_hdr_ready_reg <= 1'b0; - input_2_ip_hdr_ready_reg <= 1'b0; - input_3_ip_hdr_ready_reg <= 1'b0; - input_0_ip_payload_tready_reg <= 1'b0; - input_1_ip_payload_tready_reg <= 1'b0; - input_2_ip_payload_tready_reg <= 1'b0; - input_3_ip_payload_tready_reg <= 1'b0; - output_ip_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_ip_hdr_ready_reg <= input_0_ip_hdr_ready_next; - input_1_ip_hdr_ready_reg <= input_1_ip_hdr_ready_next; - input_2_ip_hdr_ready_reg <= input_2_ip_hdr_ready_next; - input_3_ip_hdr_ready_reg <= input_3_ip_hdr_ready_next; - input_0_ip_payload_tready_reg <= input_0_ip_payload_tready_next; - input_1_ip_payload_tready_reg <= input_1_ip_payload_tready_next; - input_2_ip_payload_tready_reg <= input_2_ip_payload_tready_next; - input_3_ip_payload_tready_reg <= input_3_ip_payload_tready_next; - output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; -end - -// output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 64'd0; -reg [7:0] output_ip_payload_tkeep_reg = 8'd0; -reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; - -reg [63:0] temp_ip_payload_tdata_reg = 64'd0; -reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; - -// datapath control -reg store_ip_payload_int_to_output; -reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; - -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - - store_ip_payload_int_to_output = 1'b0; - store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; - - if (output_ip_payload_tready_int_reg) begin - // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_temp = 1'b1; - end - end else if (output_ip_payload_tready) begin - // input is not ready, but output is ready - output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; - end else begin - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; - end - - // datapath - if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - - if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end -end - -endmodule diff --git a/tb/test_ip_mux_4.py b/tb/test_ip_mux_4.py index 6e61369b3..178589b0e 100755 --- a/tb/test_ip_mux_4.py +++ b/tb/test_ip_mux_4.py @@ -28,8 +28,8 @@ import os import ip_ep -module = 'ip_mux_4' -testbench = 'test_%s' % module +module = 'ip_mux' +testbench = 'test_%s_4' % module srcs = [] @@ -42,297 +42,184 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_ip_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_ip_version = Signal(intbv(0)[4:]) - input_0_ip_ihl = Signal(intbv(0)[4:]) - input_0_ip_dscp = Signal(intbv(0)[6:]) - input_0_ip_ecn = Signal(intbv(0)[2:]) - input_0_ip_length = Signal(intbv(0)[16:]) - input_0_ip_identification = Signal(intbv(0)[16:]) - input_0_ip_flags = Signal(intbv(0)[3:]) - input_0_ip_fragment_offset = Signal(intbv(0)[13:]) - input_0_ip_ttl = Signal(intbv(0)[8:]) - input_0_ip_protocol = Signal(intbv(0)[8:]) - input_0_ip_header_checksum = Signal(intbv(0)[16:]) - input_0_ip_source_ip = Signal(intbv(0)[32:]) - input_0_ip_dest_ip = Signal(intbv(0)[32:]) - input_0_ip_payload_tdata = Signal(intbv(0)[8:]) - input_0_ip_payload_tvalid = Signal(bool(0)) - input_0_ip_payload_tlast = Signal(bool(0)) - input_0_ip_payload_tuser = Signal(bool(0)) - input_1_ip_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_ip_version = Signal(intbv(0)[4:]) - input_1_ip_ihl = Signal(intbv(0)[4:]) - input_1_ip_dscp = Signal(intbv(0)[6:]) - input_1_ip_ecn = Signal(intbv(0)[2:]) - input_1_ip_length = Signal(intbv(0)[16:]) - input_1_ip_identification = Signal(intbv(0)[16:]) - input_1_ip_flags = Signal(intbv(0)[3:]) - input_1_ip_fragment_offset = Signal(intbv(0)[13:]) - input_1_ip_ttl = Signal(intbv(0)[8:]) - input_1_ip_protocol = Signal(intbv(0)[8:]) - input_1_ip_header_checksum = Signal(intbv(0)[16:]) - input_1_ip_source_ip = Signal(intbv(0)[32:]) - input_1_ip_dest_ip = Signal(intbv(0)[32:]) - input_1_ip_payload_tdata = Signal(intbv(0)[8:]) - input_1_ip_payload_tvalid = Signal(bool(0)) - input_1_ip_payload_tlast = Signal(bool(0)) - input_1_ip_payload_tuser = Signal(bool(0)) - input_2_ip_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_ip_version = Signal(intbv(0)[4:]) - input_2_ip_ihl = Signal(intbv(0)[4:]) - input_2_ip_dscp = Signal(intbv(0)[6:]) - input_2_ip_ecn = Signal(intbv(0)[2:]) - input_2_ip_length = Signal(intbv(0)[16:]) - input_2_ip_identification = Signal(intbv(0)[16:]) - input_2_ip_flags = Signal(intbv(0)[3:]) - input_2_ip_fragment_offset = Signal(intbv(0)[13:]) - input_2_ip_ttl = Signal(intbv(0)[8:]) - input_2_ip_protocol = Signal(intbv(0)[8:]) - input_2_ip_header_checksum = Signal(intbv(0)[16:]) - input_2_ip_source_ip = Signal(intbv(0)[32:]) - input_2_ip_dest_ip = Signal(intbv(0)[32:]) - input_2_ip_payload_tdata = Signal(intbv(0)[8:]) - input_2_ip_payload_tvalid = Signal(bool(0)) - input_2_ip_payload_tlast = Signal(bool(0)) - input_2_ip_payload_tuser = Signal(bool(0)) - input_3_ip_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_ip_version = Signal(intbv(0)[4:]) - input_3_ip_ihl = Signal(intbv(0)[4:]) - input_3_ip_dscp = Signal(intbv(0)[6:]) - input_3_ip_ecn = Signal(intbv(0)[2:]) - input_3_ip_length = Signal(intbv(0)[16:]) - input_3_ip_identification = Signal(intbv(0)[16:]) - input_3_ip_flags = Signal(intbv(0)[3:]) - input_3_ip_fragment_offset = Signal(intbv(0)[13:]) - input_3_ip_ttl = Signal(intbv(0)[8:]) - input_3_ip_protocol = Signal(intbv(0)[8:]) - input_3_ip_header_checksum = Signal(intbv(0)[16:]) - input_3_ip_source_ip = Signal(intbv(0)[32:]) - input_3_ip_dest_ip = Signal(intbv(0)[32:]) - input_3_ip_payload_tdata = Signal(intbv(0)[8:]) - input_3_ip_payload_tvalid = Signal(bool(0)) - input_3_ip_payload_tlast = Signal(bool(0)) - input_3_ip_payload_tuser = Signal(bool(0)) + s_ip_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_version_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_ihl_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_dscp_list = [Signal(intbv(0)[6:]) for i in range(S_COUNT)] + s_ip_ecn_list = [Signal(intbv(0)[2:]) for i in range(S_COUNT)] + s_ip_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_identification_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_flags_list = [Signal(intbv(0)[3:]) for i in range(S_COUNT)] + s_ip_fragment_offset_list = [Signal(intbv(0)[13:]) for i in range(S_COUNT)] + s_ip_ttl_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_protocol_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_header_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_source_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_dest_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_ip_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_ip_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_ip_payload_tready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) + s_ip_hdr_valid = ConcatSignal(*reversed(s_ip_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_ip_version = ConcatSignal(*reversed(s_ip_version_list)) + s_ip_ihl = ConcatSignal(*reversed(s_ip_ihl_list)) + s_ip_dscp = ConcatSignal(*reversed(s_ip_dscp_list)) + s_ip_ecn = ConcatSignal(*reversed(s_ip_ecn_list)) + s_ip_length = ConcatSignal(*reversed(s_ip_length_list)) + s_ip_identification = ConcatSignal(*reversed(s_ip_identification_list)) + s_ip_flags = ConcatSignal(*reversed(s_ip_flags_list)) + s_ip_fragment_offset = ConcatSignal(*reversed(s_ip_fragment_offset_list)) + s_ip_ttl = ConcatSignal(*reversed(s_ip_ttl_list)) + s_ip_protocol = ConcatSignal(*reversed(s_ip_protocol_list)) + s_ip_header_checksum = ConcatSignal(*reversed(s_ip_header_checksum_list)) + s_ip_source_ip = ConcatSignal(*reversed(s_ip_source_ip_list)) + s_ip_dest_ip = ConcatSignal(*reversed(s_ip_dest_ip_list)) + s_ip_payload_axis_tdata = ConcatSignal(*reversed(s_ip_payload_axis_tdata_list)) + s_ip_payload_axis_tkeep = ConcatSignal(*reversed(s_ip_payload_axis_tkeep_list)) + s_ip_payload_axis_tvalid = ConcatSignal(*reversed(s_ip_payload_axis_tvalid_list)) + s_ip_payload_axis_tlast = ConcatSignal(*reversed(s_ip_payload_axis_tlast_list)) + s_ip_payload_axis_tid = ConcatSignal(*reversed(s_ip_payload_axis_tid_list)) + s_ip_payload_axis_tdest = ConcatSignal(*reversed(s_ip_payload_axis_tdest_list)) + s_ip_payload_axis_tuser = ConcatSignal(*reversed(s_ip_payload_axis_tuser_list)) + + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_0_ip_hdr_ready = Signal(bool(0)) - input_0_ip_payload_tready = Signal(bool(0)) - input_1_ip_hdr_ready = Signal(bool(0)) - input_1_ip_payload_tready = Signal(bool(0)) - input_2_ip_hdr_ready = Signal(bool(0)) - input_2_ip_payload_tready = Signal(bool(0)) - input_3_ip_hdr_ready = Signal(bool(0)) - input_3_ip_payload_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_ip_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_ip_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + s_ip_hdr_ready_list = [s_ip_hdr_ready(i) for i in range(S_COUNT)] + s_ip_payload_axis_tready_list = [s_ip_payload_axis_tready(i) for i in range(S_COUNT)] + + m_ip_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_ip_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_ip_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_ip_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = ip_ep.IPFrameSource() + for k in range(S_COUNT): + s = ip_ep.IPFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - ip_hdr_ready=input_0_ip_hdr_ready, - ip_hdr_valid=input_0_ip_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - ip_version=input_0_ip_version, - ip_ihl=input_0_ip_ihl, - eth_type=input_0_eth_type, - ip_dscp=input_0_ip_dscp, - ip_ecn=input_0_ip_ecn, - ip_length=input_0_ip_length, - ip_identification=input_0_ip_identification, - ip_flags=input_0_ip_flags, - ip_fragment_offset=input_0_ip_fragment_offset, - ip_ttl=input_0_ip_ttl, - ip_protocol=input_0_ip_protocol, - ip_header_checksum=input_0_ip_header_checksum, - ip_source_ip=input_0_ip_source_ip, - ip_dest_ip=input_0_ip_dest_ip, - ip_payload_tdata=input_0_ip_payload_tdata, - ip_payload_tvalid=input_0_ip_payload_tvalid, - ip_payload_tready=input_0_ip_payload_tready, - ip_payload_tlast=input_0_ip_payload_tlast, - ip_payload_tuser=input_0_ip_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = ip_ep.IPFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - ip_hdr_ready=input_1_ip_hdr_ready, - ip_hdr_valid=input_1_ip_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - ip_version=input_1_ip_version, - ip_ihl=input_1_ip_ihl, - eth_type=input_1_eth_type, - ip_dscp=input_1_ip_dscp, - ip_ecn=input_1_ip_ecn, - ip_length=input_1_ip_length, - ip_identification=input_1_ip_identification, - ip_flags=input_1_ip_flags, - ip_fragment_offset=input_1_ip_fragment_offset, - ip_ttl=input_1_ip_ttl, - ip_protocol=input_1_ip_protocol, - ip_header_checksum=input_1_ip_header_checksum, - ip_source_ip=input_1_ip_source_ip, - ip_dest_ip=input_1_ip_dest_ip, - ip_payload_tdata=input_1_ip_payload_tdata, - ip_payload_tvalid=input_1_ip_payload_tvalid, - ip_payload_tready=input_1_ip_payload_tready, - ip_payload_tlast=input_1_ip_payload_tlast, - ip_payload_tuser=input_1_ip_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = ip_ep.IPFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - ip_hdr_ready=input_2_ip_hdr_ready, - ip_hdr_valid=input_2_ip_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - ip_version=input_2_ip_version, - ip_ihl=input_2_ip_ihl, - ip_dscp=input_2_ip_dscp, - ip_ecn=input_2_ip_ecn, - ip_length=input_2_ip_length, - ip_identification=input_2_ip_identification, - ip_flags=input_2_ip_flags, - ip_fragment_offset=input_2_ip_fragment_offset, - ip_ttl=input_2_ip_ttl, - ip_protocol=input_2_ip_protocol, - ip_header_checksum=input_2_ip_header_checksum, - ip_source_ip=input_2_ip_source_ip, - ip_dest_ip=input_2_ip_dest_ip, - ip_payload_tdata=input_2_ip_payload_tdata, - ip_payload_tvalid=input_2_ip_payload_tvalid, - ip_payload_tready=input_2_ip_payload_tready, - ip_payload_tlast=input_2_ip_payload_tlast, - ip_payload_tuser=input_2_ip_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = ip_ep.IPFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - ip_hdr_ready=input_3_ip_hdr_ready, - ip_hdr_valid=input_3_ip_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - ip_version=input_3_ip_version, - ip_ihl=input_3_ip_ihl, - ip_dscp=input_3_ip_dscp, - ip_ecn=input_3_ip_ecn, - ip_length=input_3_ip_length, - ip_identification=input_3_ip_identification, - ip_flags=input_3_ip_flags, - ip_fragment_offset=input_3_ip_fragment_offset, - ip_ttl=input_3_ip_ttl, - ip_protocol=input_3_ip_protocol, - ip_header_checksum=input_3_ip_header_checksum, - ip_source_ip=input_3_ip_source_ip, - ip_dest_ip=input_3_ip_dest_ip, - ip_payload_tdata=input_3_ip_payload_tdata, - ip_payload_tvalid=input_3_ip_payload_tvalid, - ip_payload_tready=input_3_ip_payload_tready, - ip_payload_tlast=input_3_ip_payload_tlast, - ip_payload_tuser=input_3_ip_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + ip_hdr_ready=s_ip_hdr_ready_list[k], + ip_hdr_valid=s_ip_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + ip_version=s_ip_version_list[k], + ip_ihl=s_ip_ihl_list[k], + ip_dscp=s_ip_dscp_list[k], + ip_ecn=s_ip_ecn_list[k], + ip_length=s_ip_length_list[k], + ip_identification=s_ip_identification_list[k], + ip_flags=s_ip_flags_list[k], + ip_fragment_offset=s_ip_fragment_offset_list[k], + ip_ttl=s_ip_ttl_list[k], + ip_protocol=s_ip_protocol_list[k], + ip_header_checksum=s_ip_header_checksum_list[k], + ip_source_ip=s_ip_source_ip_list[k], + ip_dest_ip=s_ip_dest_ip_list[k], + ip_payload_tdata=s_ip_payload_axis_tdata_list[k], + ip_payload_tkeep=s_ip_payload_axis_tkeep_list[k], + ip_payload_tvalid=s_ip_payload_axis_tvalid_list[k], + ip_payload_tready=s_ip_payload_axis_tready_list[k], + ip_payload_tlast=s_ip_payload_axis_tlast_list[k], + ip_payload_tuser=s_ip_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = ip_ep.IPFrameSink() sink_logic = sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tkeep=m_ip_payload_axis_tkeep, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -347,122 +234,59 @@ def bench(): rst=rst, current_test=current_test, - input_0_ip_hdr_valid=input_0_ip_hdr_valid, - input_0_ip_hdr_ready=input_0_ip_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_ip_version=input_0_ip_version, - input_0_ip_ihl=input_0_ip_ihl, - input_0_ip_dscp=input_0_ip_dscp, - input_0_ip_ecn=input_0_ip_ecn, - input_0_ip_length=input_0_ip_length, - input_0_ip_identification=input_0_ip_identification, - input_0_ip_flags=input_0_ip_flags, - input_0_ip_fragment_offset=input_0_ip_fragment_offset, - input_0_ip_ttl=input_0_ip_ttl, - input_0_ip_protocol=input_0_ip_protocol, - input_0_ip_header_checksum=input_0_ip_header_checksum, - input_0_ip_source_ip=input_0_ip_source_ip, - input_0_ip_dest_ip=input_0_ip_dest_ip, - input_0_ip_payload_tdata=input_0_ip_payload_tdata, - input_0_ip_payload_tvalid=input_0_ip_payload_tvalid, - input_0_ip_payload_tready=input_0_ip_payload_tready, - input_0_ip_payload_tlast=input_0_ip_payload_tlast, - input_0_ip_payload_tuser=input_0_ip_payload_tuser, - input_1_ip_hdr_valid=input_1_ip_hdr_valid, - input_1_ip_hdr_ready=input_1_ip_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_ip_version=input_1_ip_version, - input_1_ip_ihl=input_1_ip_ihl, - input_1_ip_dscp=input_1_ip_dscp, - input_1_ip_ecn=input_1_ip_ecn, - input_1_ip_length=input_1_ip_length, - input_1_ip_identification=input_1_ip_identification, - input_1_ip_flags=input_1_ip_flags, - input_1_ip_fragment_offset=input_1_ip_fragment_offset, - input_1_ip_ttl=input_1_ip_ttl, - input_1_ip_protocol=input_1_ip_protocol, - input_1_ip_header_checksum=input_1_ip_header_checksum, - input_1_ip_source_ip=input_1_ip_source_ip, - input_1_ip_dest_ip=input_1_ip_dest_ip, - input_1_ip_payload_tdata=input_1_ip_payload_tdata, - input_1_ip_payload_tvalid=input_1_ip_payload_tvalid, - input_1_ip_payload_tready=input_1_ip_payload_tready, - input_1_ip_payload_tlast=input_1_ip_payload_tlast, - input_1_ip_payload_tuser=input_1_ip_payload_tuser, - input_2_ip_hdr_valid=input_2_ip_hdr_valid, - input_2_ip_hdr_ready=input_2_ip_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_ip_version=input_2_ip_version, - input_2_ip_ihl=input_2_ip_ihl, - input_2_ip_dscp=input_2_ip_dscp, - input_2_ip_ecn=input_2_ip_ecn, - input_2_ip_length=input_2_ip_length, - input_2_ip_identification=input_2_ip_identification, - input_2_ip_flags=input_2_ip_flags, - input_2_ip_fragment_offset=input_2_ip_fragment_offset, - input_2_ip_ttl=input_2_ip_ttl, - input_2_ip_protocol=input_2_ip_protocol, - input_2_ip_header_checksum=input_2_ip_header_checksum, - input_2_ip_source_ip=input_2_ip_source_ip, - input_2_ip_dest_ip=input_2_ip_dest_ip, - input_2_ip_payload_tdata=input_2_ip_payload_tdata, - input_2_ip_payload_tvalid=input_2_ip_payload_tvalid, - input_2_ip_payload_tready=input_2_ip_payload_tready, - input_2_ip_payload_tlast=input_2_ip_payload_tlast, - input_2_ip_payload_tuser=input_2_ip_payload_tuser, - input_3_ip_hdr_valid=input_3_ip_hdr_valid, - input_3_ip_hdr_ready=input_3_ip_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_ip_version=input_3_ip_version, - input_3_ip_ihl=input_3_ip_ihl, - input_3_ip_dscp=input_3_ip_dscp, - input_3_ip_ecn=input_3_ip_ecn, - input_3_ip_length=input_3_ip_length, - input_3_ip_identification=input_3_ip_identification, - input_3_ip_flags=input_3_ip_flags, - input_3_ip_fragment_offset=input_3_ip_fragment_offset, - input_3_ip_ttl=input_3_ip_ttl, - input_3_ip_protocol=input_3_ip_protocol, - input_3_ip_header_checksum=input_3_ip_header_checksum, - input_3_ip_source_ip=input_3_ip_source_ip, - input_3_ip_dest_ip=input_3_ip_dest_ip, - input_3_ip_payload_tdata=input_3_ip_payload_tdata, - input_3_ip_payload_tvalid=input_3_ip_payload_tvalid, - input_3_ip_payload_tready=input_3_ip_payload_tready, - input_3_ip_payload_tlast=input_3_ip_payload_tlast, - input_3_ip_payload_tuser=input_3_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tid=s_ip_payload_axis_tid, + s_ip_payload_axis_tdest=s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tid=m_ip_payload_axis_tid, + m_ip_payload_axis_tdest=m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, enable=enable, select=select @@ -512,7 +336,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -547,7 +371,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -601,8 +425,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -661,12 +485,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + while s_ip_payload_axis_tvalid: yield clk.posedge select.next = 2 @@ -727,23 +551,23 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_ip_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge select.next = 2 @@ -804,12 +628,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + while s_ip_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_ip_mux_4.v b/tb/test_ip_mux_4.v index 0d4516825..ce0c97915 100644 --- a/tb/test_ip_mux_4.v +++ b/tb/test_ip_mux_4.v @@ -27,137 +27,86 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for ip_eth_mux_4 + * Testbench for ip_mux */ module test_ip_mux_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_ip_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [3:0] input_0_ip_version = 0; -reg [3:0] input_0_ip_ihl = 0; -reg [5:0] input_0_ip_dscp = 0; -reg [1:0] input_0_ip_ecn = 0; -reg [15:0] input_0_ip_length = 0; -reg [15:0] input_0_ip_identification = 0; -reg [2:0] input_0_ip_flags = 0; -reg [12:0] input_0_ip_fragment_offset = 0; -reg [7:0] input_0_ip_ttl = 0; -reg [7:0] input_0_ip_protocol = 0; -reg [15:0] input_0_ip_header_checksum = 0; -reg [31:0] input_0_ip_source_ip = 0; -reg [31:0] input_0_ip_dest_ip = 0; -reg [7:0] input_0_ip_payload_tdata = 0; -reg input_0_ip_payload_tvalid = 0; -reg input_0_ip_payload_tlast = 0; -reg input_0_ip_payload_tuser = 0; -reg input_1_ip_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [3:0] input_1_ip_version = 0; -reg [3:0] input_1_ip_ihl = 0; -reg [5:0] input_1_ip_dscp = 0; -reg [1:0] input_1_ip_ecn = 0; -reg [15:0] input_1_ip_length = 0; -reg [15:0] input_1_ip_identification = 0; -reg [2:0] input_1_ip_flags = 0; -reg [12:0] input_1_ip_fragment_offset = 0; -reg [7:0] input_1_ip_ttl = 0; -reg [7:0] input_1_ip_protocol = 0; -reg [15:0] input_1_ip_header_checksum = 0; -reg [31:0] input_1_ip_source_ip = 0; -reg [31:0] input_1_ip_dest_ip = 0; -reg [7:0] input_1_ip_payload_tdata = 0; -reg input_1_ip_payload_tvalid = 0; -reg input_1_ip_payload_tlast = 0; -reg input_1_ip_payload_tuser = 0; -reg input_2_ip_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [3:0] input_2_ip_version = 0; -reg [3:0] input_2_ip_ihl = 0; -reg [5:0] input_2_ip_dscp = 0; -reg [1:0] input_2_ip_ecn = 0; -reg [15:0] input_2_ip_length = 0; -reg [15:0] input_2_ip_identification = 0; -reg [2:0] input_2_ip_flags = 0; -reg [12:0] input_2_ip_fragment_offset = 0; -reg [7:0] input_2_ip_ttl = 0; -reg [7:0] input_2_ip_protocol = 0; -reg [15:0] input_2_ip_header_checksum = 0; -reg [31:0] input_2_ip_source_ip = 0; -reg [31:0] input_2_ip_dest_ip = 0; -reg [7:0] input_2_ip_payload_tdata = 0; -reg input_2_ip_payload_tvalid = 0; -reg input_2_ip_payload_tlast = 0; -reg input_2_ip_payload_tuser = 0; -reg input_3_ip_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [3:0] input_3_ip_version = 0; -reg [3:0] input_3_ip_ihl = 0; -reg [5:0] input_3_ip_dscp = 0; -reg [1:0] input_3_ip_ecn = 0; -reg [15:0] input_3_ip_length = 0; -reg [15:0] input_3_ip_identification = 0; -reg [2:0] input_3_ip_flags = 0; -reg [12:0] input_3_ip_fragment_offset = 0; -reg [7:0] input_3_ip_ttl = 0; -reg [7:0] input_3_ip_protocol = 0; -reg [15:0] input_3_ip_header_checksum = 0; -reg [31:0] input_3_ip_source_ip = 0; -reg [31:0] input_3_ip_dest_ip = 0; -reg [7:0] input_3_ip_payload_tdata = 0; -reg input_3_ip_payload_tvalid = 0; -reg input_3_ip_payload_tlast = 0; -reg input_3_ip_payload_tuser = 0; +reg [S_COUNT-1:0] s_ip_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*4-1:0] s_ip_version = 0; +reg [S_COUNT*4-1:0] s_ip_ihl = 0; +reg [S_COUNT*6-1:0] s_ip_dscp = 0; +reg [S_COUNT*2-1:0] s_ip_ecn = 0; +reg [S_COUNT*16-1:0] s_ip_length = 0; +reg [S_COUNT*16-1:0] s_ip_identification = 0; +reg [S_COUNT*3-1:0] s_ip_flags = 0; +reg [S_COUNT*13-1:0] s_ip_fragment_offset = 0; +reg [S_COUNT*8-1:0] s_ip_ttl = 0; +reg [S_COUNT*8-1:0] s_ip_protocol = 0; +reg [S_COUNT*16-1:0] s_ip_header_checksum = 0; +reg [S_COUNT*32-1:0] s_ip_source_ip = 0; +reg [S_COUNT*32-1:0] s_ip_dest_ip = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_ip_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_ip_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_ip_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_ip_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_ip_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_ip_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_ip_payload_axis_tuser = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; reg enable = 0; reg [1:0] select = 0; // Outputs -wire input_0_ip_payload_tready; -wire input_0_ip_hdr_ready; -wire input_1_ip_payload_tready; -wire input_1_ip_hdr_ready; -wire input_2_ip_payload_tready; -wire input_2_ip_hdr_ready; -wire input_3_ip_payload_tready; -wire input_3_ip_hdr_ready; +wire [S_COUNT-1:0] s_ip_hdr_ready; +wire [S_COUNT-1:0] s_ip_payload_axis_tready; -wire output_ip_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [7:0] output_ip_payload_tdata; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire m_ip_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [DATA_WIDTH-1:0] m_ip_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_ip_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_ip_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_ip_payload_axis_tuser; initial begin // myhdl integration @@ -165,125 +114,62 @@ initial begin clk, rst, current_test, - input_0_ip_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_ip_version, - input_0_ip_ihl, - input_0_ip_dscp, - input_0_ip_ecn, - input_0_ip_length, - input_0_ip_identification, - input_0_ip_flags, - input_0_ip_fragment_offset, - input_0_ip_ttl, - input_0_ip_protocol, - input_0_ip_header_checksum, - input_0_ip_source_ip, - input_0_ip_dest_ip, - input_0_ip_payload_tdata, - input_0_ip_payload_tvalid, - input_0_ip_payload_tlast, - input_0_ip_payload_tuser, - input_1_ip_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_ip_version, - input_1_ip_ihl, - input_1_ip_dscp, - input_1_ip_ecn, - input_1_ip_length, - input_1_ip_identification, - input_1_ip_flags, - input_1_ip_fragment_offset, - input_1_ip_ttl, - input_1_ip_protocol, - input_1_ip_header_checksum, - input_1_ip_source_ip, - input_1_ip_dest_ip, - input_1_ip_payload_tdata, - input_1_ip_payload_tvalid, - input_1_ip_payload_tlast, - input_1_ip_payload_tuser, - input_2_ip_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_ip_version, - input_2_ip_ihl, - input_2_ip_dscp, - input_2_ip_ecn, - input_2_ip_length, - input_2_ip_identification, - input_2_ip_flags, - input_2_ip_fragment_offset, - input_2_ip_ttl, - input_2_ip_protocol, - input_2_ip_header_checksum, - input_2_ip_source_ip, - input_2_ip_dest_ip, - input_2_ip_payload_tdata, - input_2_ip_payload_tvalid, - input_2_ip_payload_tlast, - input_2_ip_payload_tuser, - input_3_ip_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_ip_version, - input_3_ip_ihl, - input_3_ip_dscp, - input_3_ip_ecn, - input_3_ip_length, - input_3_ip_identification, - input_3_ip_flags, - input_3_ip_fragment_offset, - input_3_ip_ttl, - input_3_ip_protocol, - input_3_ip_header_checksum, - input_3_ip_source_ip, - input_3_ip_dest_ip, - input_3_ip_payload_tdata, - input_3_ip_payload_tvalid, - input_3_ip_payload_tlast, - input_3_ip_payload_tuser, - output_ip_hdr_ready, - output_ip_payload_tready, + s_ip_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tid, + s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready, enable, select ); $to_myhdl( - input_0_ip_hdr_ready, - input_0_ip_payload_tready, - input_1_ip_hdr_ready, - input_1_ip_payload_tready, - input_2_ip_hdr_ready, - input_2_ip_payload_tready, - input_3_ip_hdr_ready, - input_3_ip_payload_tready, - output_ip_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_ip_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tid, + m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser ); // dump file @@ -291,127 +177,75 @@ initial begin $dumpvars(0, test_ip_mux_4); end -ip_mux_4 +ip_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), - // IP frame inputs - .input_0_ip_hdr_valid(input_0_ip_hdr_valid), - .input_0_ip_hdr_ready(input_0_ip_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_ip_payload_tdata(input_0_ip_payload_tdata), - .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid), - .input_0_ip_payload_tready(input_0_ip_payload_tready), - .input_0_ip_payload_tlast(input_0_ip_payload_tlast), - .input_0_ip_payload_tuser(input_0_ip_payload_tuser), - .input_1_ip_hdr_valid(input_1_ip_hdr_valid), - .input_1_ip_hdr_ready(input_1_ip_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_ip_payload_tdata(input_1_ip_payload_tdata), - .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid), - .input_1_ip_payload_tready(input_1_ip_payload_tready), - .input_1_ip_payload_tlast(input_1_ip_payload_tlast), - .input_1_ip_payload_tuser(input_1_ip_payload_tuser), - .input_2_ip_hdr_valid(input_2_ip_hdr_valid), - .input_2_ip_hdr_ready(input_2_ip_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_ip_payload_tdata(input_2_ip_payload_tdata), - .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid), - .input_2_ip_payload_tready(input_2_ip_payload_tready), - .input_2_ip_payload_tlast(input_2_ip_payload_tlast), - .input_2_ip_payload_tuser(input_2_ip_payload_tuser), - .input_3_ip_hdr_valid(input_3_ip_hdr_valid), - .input_3_ip_hdr_ready(input_3_ip_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_ip_payload_tdata(input_3_ip_payload_tdata), - .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid), - .input_3_ip_payload_tready(input_3_ip_payload_tready), - .input_3_ip_payload_tlast(input_3_ip_payload_tlast), - .input_3_ip_payload_tuser(input_3_ip_payload_tuser), - // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + // Ethernet frame inputs + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tid(s_ip_payload_axis_tid), + .s_ip_payload_axis_tdest(s_ip_payload_axis_tdest), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), + // Ethernet frame output + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tid(m_ip_payload_axis_tid), + .m_ip_payload_axis_tdest(m_ip_payload_axis_tdest), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Control .enable(enable), .select(select) diff --git a/tb/test_ip_mux_64_4.py b/tb/test_ip_mux_64_4.py index ae09a00da..b1920fdfd 100755 --- a/tb/test_ip_mux_64_4.py +++ b/tb/test_ip_mux_64_4.py @@ -28,8 +28,8 @@ import os import ip_ep -module = 'ip_mux_64_4' -testbench = 'test_%s' % module +module = 'ip_mux' +testbench = 'test_%s_64_4' % module srcs = [] @@ -42,307 +42,184 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_ip_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_ip_version = Signal(intbv(0)[4:]) - input_0_ip_ihl = Signal(intbv(0)[4:]) - input_0_ip_dscp = Signal(intbv(0)[6:]) - input_0_ip_ecn = Signal(intbv(0)[2:]) - input_0_ip_length = Signal(intbv(0)[16:]) - input_0_ip_identification = Signal(intbv(0)[16:]) - input_0_ip_flags = Signal(intbv(0)[3:]) - input_0_ip_fragment_offset = Signal(intbv(0)[13:]) - input_0_ip_ttl = Signal(intbv(0)[8:]) - input_0_ip_protocol = Signal(intbv(0)[8:]) - input_0_ip_header_checksum = Signal(intbv(0)[16:]) - input_0_ip_source_ip = Signal(intbv(0)[32:]) - input_0_ip_dest_ip = Signal(intbv(0)[32:]) - input_0_ip_payload_tdata = Signal(intbv(0)[64:]) - input_0_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_0_ip_payload_tvalid = Signal(bool(0)) - input_0_ip_payload_tlast = Signal(bool(0)) - input_0_ip_payload_tuser = Signal(bool(0)) - input_1_ip_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_ip_version = Signal(intbv(0)[4:]) - input_1_ip_ihl = Signal(intbv(0)[4:]) - input_1_ip_dscp = Signal(intbv(0)[6:]) - input_1_ip_ecn = Signal(intbv(0)[2:]) - input_1_ip_length = Signal(intbv(0)[16:]) - input_1_ip_identification = Signal(intbv(0)[16:]) - input_1_ip_flags = Signal(intbv(0)[3:]) - input_1_ip_fragment_offset = Signal(intbv(0)[13:]) - input_1_ip_ttl = Signal(intbv(0)[8:]) - input_1_ip_protocol = Signal(intbv(0)[8:]) - input_1_ip_header_checksum = Signal(intbv(0)[16:]) - input_1_ip_source_ip = Signal(intbv(0)[32:]) - input_1_ip_dest_ip = Signal(intbv(0)[32:]) - input_1_ip_payload_tdata = Signal(intbv(0)[64:]) - input_1_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_1_ip_payload_tvalid = Signal(bool(0)) - input_1_ip_payload_tlast = Signal(bool(0)) - input_1_ip_payload_tuser = Signal(bool(0)) - input_2_ip_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_ip_version = Signal(intbv(0)[4:]) - input_2_ip_ihl = Signal(intbv(0)[4:]) - input_2_ip_dscp = Signal(intbv(0)[6:]) - input_2_ip_ecn = Signal(intbv(0)[2:]) - input_2_ip_length = Signal(intbv(0)[16:]) - input_2_ip_identification = Signal(intbv(0)[16:]) - input_2_ip_flags = Signal(intbv(0)[3:]) - input_2_ip_fragment_offset = Signal(intbv(0)[13:]) - input_2_ip_ttl = Signal(intbv(0)[8:]) - input_2_ip_protocol = Signal(intbv(0)[8:]) - input_2_ip_header_checksum = Signal(intbv(0)[16:]) - input_2_ip_source_ip = Signal(intbv(0)[32:]) - input_2_ip_dest_ip = Signal(intbv(0)[32:]) - input_2_ip_payload_tdata = Signal(intbv(0)[64:]) - input_2_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_2_ip_payload_tvalid = Signal(bool(0)) - input_2_ip_payload_tlast = Signal(bool(0)) - input_2_ip_payload_tuser = Signal(bool(0)) - input_3_ip_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_ip_version = Signal(intbv(0)[4:]) - input_3_ip_ihl = Signal(intbv(0)[4:]) - input_3_ip_dscp = Signal(intbv(0)[6:]) - input_3_ip_ecn = Signal(intbv(0)[2:]) - input_3_ip_length = Signal(intbv(0)[16:]) - input_3_ip_identification = Signal(intbv(0)[16:]) - input_3_ip_flags = Signal(intbv(0)[3:]) - input_3_ip_fragment_offset = Signal(intbv(0)[13:]) - input_3_ip_ttl = Signal(intbv(0)[8:]) - input_3_ip_protocol = Signal(intbv(0)[8:]) - input_3_ip_header_checksum = Signal(intbv(0)[16:]) - input_3_ip_source_ip = Signal(intbv(0)[32:]) - input_3_ip_dest_ip = Signal(intbv(0)[32:]) - input_3_ip_payload_tdata = Signal(intbv(0)[64:]) - input_3_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_3_ip_payload_tvalid = Signal(bool(0)) - input_3_ip_payload_tlast = Signal(bool(0)) - input_3_ip_payload_tuser = Signal(bool(0)) + s_ip_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_version_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_ihl_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_dscp_list = [Signal(intbv(0)[6:]) for i in range(S_COUNT)] + s_ip_ecn_list = [Signal(intbv(0)[2:]) for i in range(S_COUNT)] + s_ip_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_identification_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_flags_list = [Signal(intbv(0)[3:]) for i in range(S_COUNT)] + s_ip_fragment_offset_list = [Signal(intbv(0)[13:]) for i in range(S_COUNT)] + s_ip_ttl_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_protocol_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_header_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_source_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_dest_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_ip_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_ip_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_ip_payload_tready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) + s_ip_hdr_valid = ConcatSignal(*reversed(s_ip_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_ip_version = ConcatSignal(*reversed(s_ip_version_list)) + s_ip_ihl = ConcatSignal(*reversed(s_ip_ihl_list)) + s_ip_dscp = ConcatSignal(*reversed(s_ip_dscp_list)) + s_ip_ecn = ConcatSignal(*reversed(s_ip_ecn_list)) + s_ip_length = ConcatSignal(*reversed(s_ip_length_list)) + s_ip_identification = ConcatSignal(*reversed(s_ip_identification_list)) + s_ip_flags = ConcatSignal(*reversed(s_ip_flags_list)) + s_ip_fragment_offset = ConcatSignal(*reversed(s_ip_fragment_offset_list)) + s_ip_ttl = ConcatSignal(*reversed(s_ip_ttl_list)) + s_ip_protocol = ConcatSignal(*reversed(s_ip_protocol_list)) + s_ip_header_checksum = ConcatSignal(*reversed(s_ip_header_checksum_list)) + s_ip_source_ip = ConcatSignal(*reversed(s_ip_source_ip_list)) + s_ip_dest_ip = ConcatSignal(*reversed(s_ip_dest_ip_list)) + s_ip_payload_axis_tdata = ConcatSignal(*reversed(s_ip_payload_axis_tdata_list)) + s_ip_payload_axis_tkeep = ConcatSignal(*reversed(s_ip_payload_axis_tkeep_list)) + s_ip_payload_axis_tvalid = ConcatSignal(*reversed(s_ip_payload_axis_tvalid_list)) + s_ip_payload_axis_tlast = ConcatSignal(*reversed(s_ip_payload_axis_tlast_list)) + s_ip_payload_axis_tid = ConcatSignal(*reversed(s_ip_payload_axis_tid_list)) + s_ip_payload_axis_tdest = ConcatSignal(*reversed(s_ip_payload_axis_tdest_list)) + s_ip_payload_axis_tuser = ConcatSignal(*reversed(s_ip_payload_axis_tuser_list)) + + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_0_ip_hdr_ready = Signal(bool(0)) - input_0_ip_payload_tready = Signal(bool(0)) - input_1_ip_hdr_ready = Signal(bool(0)) - input_1_ip_payload_tready = Signal(bool(0)) - input_2_ip_hdr_ready = Signal(bool(0)) - input_2_ip_payload_tready = Signal(bool(0)) - input_3_ip_hdr_ready = Signal(bool(0)) - input_3_ip_payload_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_ip_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_ip_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[64:]) - output_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + s_ip_hdr_ready_list = [s_ip_hdr_ready(i) for i in range(S_COUNT)] + s_ip_payload_axis_tready_list = [s_ip_payload_axis_tready(i) for i in range(S_COUNT)] + + m_ip_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_ip_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_ip_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_ip_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = ip_ep.IPFrameSource() + for k in range(S_COUNT): + s = ip_ep.IPFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - ip_hdr_ready=input_0_ip_hdr_ready, - ip_hdr_valid=input_0_ip_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - ip_version=input_0_ip_version, - ip_ihl=input_0_ip_ihl, - eth_type=input_0_eth_type, - ip_dscp=input_0_ip_dscp, - ip_ecn=input_0_ip_ecn, - ip_length=input_0_ip_length, - ip_identification=input_0_ip_identification, - ip_flags=input_0_ip_flags, - ip_fragment_offset=input_0_ip_fragment_offset, - ip_ttl=input_0_ip_ttl, - ip_protocol=input_0_ip_protocol, - ip_header_checksum=input_0_ip_header_checksum, - ip_source_ip=input_0_ip_source_ip, - ip_dest_ip=input_0_ip_dest_ip, - ip_payload_tdata=input_0_ip_payload_tdata, - ip_payload_tkeep=input_0_ip_payload_tkeep, - ip_payload_tvalid=input_0_ip_payload_tvalid, - ip_payload_tready=input_0_ip_payload_tready, - ip_payload_tlast=input_0_ip_payload_tlast, - ip_payload_tuser=input_0_ip_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = ip_ep.IPFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - ip_hdr_ready=input_1_ip_hdr_ready, - ip_hdr_valid=input_1_ip_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - ip_version=input_1_ip_version, - ip_ihl=input_1_ip_ihl, - eth_type=input_1_eth_type, - ip_dscp=input_1_ip_dscp, - ip_ecn=input_1_ip_ecn, - ip_length=input_1_ip_length, - ip_identification=input_1_ip_identification, - ip_flags=input_1_ip_flags, - ip_fragment_offset=input_1_ip_fragment_offset, - ip_ttl=input_1_ip_ttl, - ip_protocol=input_1_ip_protocol, - ip_header_checksum=input_1_ip_header_checksum, - ip_source_ip=input_1_ip_source_ip, - ip_dest_ip=input_1_ip_dest_ip, - ip_payload_tdata=input_1_ip_payload_tdata, - ip_payload_tkeep=input_1_ip_payload_tkeep, - ip_payload_tvalid=input_1_ip_payload_tvalid, - ip_payload_tready=input_1_ip_payload_tready, - ip_payload_tlast=input_1_ip_payload_tlast, - ip_payload_tuser=input_1_ip_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = ip_ep.IPFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - ip_hdr_ready=input_2_ip_hdr_ready, - ip_hdr_valid=input_2_ip_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - ip_version=input_2_ip_version, - ip_ihl=input_2_ip_ihl, - ip_dscp=input_2_ip_dscp, - ip_ecn=input_2_ip_ecn, - ip_length=input_2_ip_length, - ip_identification=input_2_ip_identification, - ip_flags=input_2_ip_flags, - ip_fragment_offset=input_2_ip_fragment_offset, - ip_ttl=input_2_ip_ttl, - ip_protocol=input_2_ip_protocol, - ip_header_checksum=input_2_ip_header_checksum, - ip_source_ip=input_2_ip_source_ip, - ip_dest_ip=input_2_ip_dest_ip, - ip_payload_tdata=input_2_ip_payload_tdata, - ip_payload_tkeep=input_2_ip_payload_tkeep, - ip_payload_tvalid=input_2_ip_payload_tvalid, - ip_payload_tready=input_2_ip_payload_tready, - ip_payload_tlast=input_2_ip_payload_tlast, - ip_payload_tuser=input_2_ip_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = ip_ep.IPFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - ip_hdr_ready=input_3_ip_hdr_ready, - ip_hdr_valid=input_3_ip_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - ip_version=input_3_ip_version, - ip_ihl=input_3_ip_ihl, - ip_dscp=input_3_ip_dscp, - ip_ecn=input_3_ip_ecn, - ip_length=input_3_ip_length, - ip_identification=input_3_ip_identification, - ip_flags=input_3_ip_flags, - ip_fragment_offset=input_3_ip_fragment_offset, - ip_ttl=input_3_ip_ttl, - ip_protocol=input_3_ip_protocol, - ip_header_checksum=input_3_ip_header_checksum, - ip_source_ip=input_3_ip_source_ip, - ip_dest_ip=input_3_ip_dest_ip, - ip_payload_tdata=input_3_ip_payload_tdata, - ip_payload_tkeep=input_3_ip_payload_tkeep, - ip_payload_tvalid=input_3_ip_payload_tvalid, - ip_payload_tready=input_3_ip_payload_tready, - ip_payload_tlast=input_3_ip_payload_tlast, - ip_payload_tuser=input_3_ip_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + ip_hdr_ready=s_ip_hdr_ready_list[k], + ip_hdr_valid=s_ip_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + ip_version=s_ip_version_list[k], + ip_ihl=s_ip_ihl_list[k], + ip_dscp=s_ip_dscp_list[k], + ip_ecn=s_ip_ecn_list[k], + ip_length=s_ip_length_list[k], + ip_identification=s_ip_identification_list[k], + ip_flags=s_ip_flags_list[k], + ip_fragment_offset=s_ip_fragment_offset_list[k], + ip_ttl=s_ip_ttl_list[k], + ip_protocol=s_ip_protocol_list[k], + ip_header_checksum=s_ip_header_checksum_list[k], + ip_source_ip=s_ip_source_ip_list[k], + ip_dest_ip=s_ip_dest_ip_list[k], + ip_payload_tdata=s_ip_payload_axis_tdata_list[k], + ip_payload_tkeep=s_ip_payload_axis_tkeep_list[k], + ip_payload_tvalid=s_ip_payload_axis_tvalid_list[k], + ip_payload_tready=s_ip_payload_axis_tready_list[k], + ip_payload_tlast=s_ip_payload_axis_tlast_list[k], + ip_payload_tuser=s_ip_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = ip_ep.IPFrameSink() sink_logic = sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tkeep=output_ip_payload_tkeep, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tkeep=m_ip_payload_axis_tkeep, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -357,127 +234,59 @@ def bench(): rst=rst, current_test=current_test, - input_0_ip_hdr_valid=input_0_ip_hdr_valid, - input_0_ip_hdr_ready=input_0_ip_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_ip_version=input_0_ip_version, - input_0_ip_ihl=input_0_ip_ihl, - input_0_ip_dscp=input_0_ip_dscp, - input_0_ip_ecn=input_0_ip_ecn, - input_0_ip_length=input_0_ip_length, - input_0_ip_identification=input_0_ip_identification, - input_0_ip_flags=input_0_ip_flags, - input_0_ip_fragment_offset=input_0_ip_fragment_offset, - input_0_ip_ttl=input_0_ip_ttl, - input_0_ip_protocol=input_0_ip_protocol, - input_0_ip_header_checksum=input_0_ip_header_checksum, - input_0_ip_source_ip=input_0_ip_source_ip, - input_0_ip_dest_ip=input_0_ip_dest_ip, - input_0_ip_payload_tdata=input_0_ip_payload_tdata, - input_0_ip_payload_tkeep=input_0_ip_payload_tkeep, - input_0_ip_payload_tvalid=input_0_ip_payload_tvalid, - input_0_ip_payload_tready=input_0_ip_payload_tready, - input_0_ip_payload_tlast=input_0_ip_payload_tlast, - input_0_ip_payload_tuser=input_0_ip_payload_tuser, - input_1_ip_hdr_valid=input_1_ip_hdr_valid, - input_1_ip_hdr_ready=input_1_ip_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_ip_version=input_1_ip_version, - input_1_ip_ihl=input_1_ip_ihl, - input_1_ip_dscp=input_1_ip_dscp, - input_1_ip_ecn=input_1_ip_ecn, - input_1_ip_length=input_1_ip_length, - input_1_ip_identification=input_1_ip_identification, - input_1_ip_flags=input_1_ip_flags, - input_1_ip_fragment_offset=input_1_ip_fragment_offset, - input_1_ip_ttl=input_1_ip_ttl, - input_1_ip_protocol=input_1_ip_protocol, - input_1_ip_header_checksum=input_1_ip_header_checksum, - input_1_ip_source_ip=input_1_ip_source_ip, - input_1_ip_dest_ip=input_1_ip_dest_ip, - input_1_ip_payload_tdata=input_1_ip_payload_tdata, - input_1_ip_payload_tkeep=input_1_ip_payload_tkeep, - input_1_ip_payload_tvalid=input_1_ip_payload_tvalid, - input_1_ip_payload_tready=input_1_ip_payload_tready, - input_1_ip_payload_tlast=input_1_ip_payload_tlast, - input_1_ip_payload_tuser=input_1_ip_payload_tuser, - input_2_ip_hdr_valid=input_2_ip_hdr_valid, - input_2_ip_hdr_ready=input_2_ip_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_ip_version=input_2_ip_version, - input_2_ip_ihl=input_2_ip_ihl, - input_2_ip_dscp=input_2_ip_dscp, - input_2_ip_ecn=input_2_ip_ecn, - input_2_ip_length=input_2_ip_length, - input_2_ip_identification=input_2_ip_identification, - input_2_ip_flags=input_2_ip_flags, - input_2_ip_fragment_offset=input_2_ip_fragment_offset, - input_2_ip_ttl=input_2_ip_ttl, - input_2_ip_protocol=input_2_ip_protocol, - input_2_ip_header_checksum=input_2_ip_header_checksum, - input_2_ip_source_ip=input_2_ip_source_ip, - input_2_ip_dest_ip=input_2_ip_dest_ip, - input_2_ip_payload_tdata=input_2_ip_payload_tdata, - input_2_ip_payload_tkeep=input_2_ip_payload_tkeep, - input_2_ip_payload_tvalid=input_2_ip_payload_tvalid, - input_2_ip_payload_tready=input_2_ip_payload_tready, - input_2_ip_payload_tlast=input_2_ip_payload_tlast, - input_2_ip_payload_tuser=input_2_ip_payload_tuser, - input_3_ip_hdr_valid=input_3_ip_hdr_valid, - input_3_ip_hdr_ready=input_3_ip_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_ip_version=input_3_ip_version, - input_3_ip_ihl=input_3_ip_ihl, - input_3_ip_dscp=input_3_ip_dscp, - input_3_ip_ecn=input_3_ip_ecn, - input_3_ip_length=input_3_ip_length, - input_3_ip_identification=input_3_ip_identification, - input_3_ip_flags=input_3_ip_flags, - input_3_ip_fragment_offset=input_3_ip_fragment_offset, - input_3_ip_ttl=input_3_ip_ttl, - input_3_ip_protocol=input_3_ip_protocol, - input_3_ip_header_checksum=input_3_ip_header_checksum, - input_3_ip_source_ip=input_3_ip_source_ip, - input_3_ip_dest_ip=input_3_ip_dest_ip, - input_3_ip_payload_tdata=input_3_ip_payload_tdata, - input_3_ip_payload_tkeep=input_3_ip_payload_tkeep, - input_3_ip_payload_tvalid=input_3_ip_payload_tvalid, - input_3_ip_payload_tready=input_3_ip_payload_tready, - input_3_ip_payload_tlast=input_3_ip_payload_tlast, - input_3_ip_payload_tuser=input_3_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tid=s_ip_payload_axis_tid, + s_ip_payload_axis_tdest=s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tkeep=output_ip_payload_tkeep, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tid=m_ip_payload_axis_tid, + m_ip_payload_axis_tdest=m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, enable=enable, select=select @@ -527,7 +336,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -562,7 +371,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -616,8 +425,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -676,12 +485,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + while s_ip_payload_axis_tvalid: yield clk.posedge select.next = 2 @@ -742,23 +551,23 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_ip_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge select.next = 2 @@ -819,12 +628,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + while s_ip_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_ip_mux_64_4.v b/tb/test_ip_mux_64_4.v index 53fe1f6a6..4bf3e0161 100644 --- a/tb/test_ip_mux_64_4.v +++ b/tb/test_ip_mux_64_4.v @@ -27,142 +27,86 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for ip_eth_mux_64_4 + * Testbench for ip_mux */ module test_ip_mux_64_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_ip_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [3:0] input_0_ip_version = 0; -reg [3:0] input_0_ip_ihl = 0; -reg [5:0] input_0_ip_dscp = 0; -reg [1:0] input_0_ip_ecn = 0; -reg [15:0] input_0_ip_length = 0; -reg [15:0] input_0_ip_identification = 0; -reg [2:0] input_0_ip_flags = 0; -reg [12:0] input_0_ip_fragment_offset = 0; -reg [7:0] input_0_ip_ttl = 0; -reg [7:0] input_0_ip_protocol = 0; -reg [15:0] input_0_ip_header_checksum = 0; -reg [31:0] input_0_ip_source_ip = 0; -reg [31:0] input_0_ip_dest_ip = 0; -reg [63:0] input_0_ip_payload_tdata = 0; -reg [7:0] input_0_ip_payload_tkeep = 0; -reg input_0_ip_payload_tvalid = 0; -reg input_0_ip_payload_tlast = 0; -reg input_0_ip_payload_tuser = 0; -reg input_1_ip_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [3:0] input_1_ip_version = 0; -reg [3:0] input_1_ip_ihl = 0; -reg [5:0] input_1_ip_dscp = 0; -reg [1:0] input_1_ip_ecn = 0; -reg [15:0] input_1_ip_length = 0; -reg [15:0] input_1_ip_identification = 0; -reg [2:0] input_1_ip_flags = 0; -reg [12:0] input_1_ip_fragment_offset = 0; -reg [7:0] input_1_ip_ttl = 0; -reg [7:0] input_1_ip_protocol = 0; -reg [15:0] input_1_ip_header_checksum = 0; -reg [31:0] input_1_ip_source_ip = 0; -reg [31:0] input_1_ip_dest_ip = 0; -reg [63:0] input_1_ip_payload_tdata = 0; -reg [7:0] input_1_ip_payload_tkeep = 0; -reg input_1_ip_payload_tvalid = 0; -reg input_1_ip_payload_tlast = 0; -reg input_1_ip_payload_tuser = 0; -reg input_2_ip_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [3:0] input_2_ip_version = 0; -reg [3:0] input_2_ip_ihl = 0; -reg [5:0] input_2_ip_dscp = 0; -reg [1:0] input_2_ip_ecn = 0; -reg [15:0] input_2_ip_length = 0; -reg [15:0] input_2_ip_identification = 0; -reg [2:0] input_2_ip_flags = 0; -reg [12:0] input_2_ip_fragment_offset = 0; -reg [7:0] input_2_ip_ttl = 0; -reg [7:0] input_2_ip_protocol = 0; -reg [15:0] input_2_ip_header_checksum = 0; -reg [31:0] input_2_ip_source_ip = 0; -reg [31:0] input_2_ip_dest_ip = 0; -reg [63:0] input_2_ip_payload_tdata = 0; -reg [7:0] input_2_ip_payload_tkeep = 0; -reg input_2_ip_payload_tvalid = 0; -reg input_2_ip_payload_tlast = 0; -reg input_2_ip_payload_tuser = 0; -reg input_3_ip_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [3:0] input_3_ip_version = 0; -reg [3:0] input_3_ip_ihl = 0; -reg [5:0] input_3_ip_dscp = 0; -reg [1:0] input_3_ip_ecn = 0; -reg [15:0] input_3_ip_length = 0; -reg [15:0] input_3_ip_identification = 0; -reg [2:0] input_3_ip_flags = 0; -reg [12:0] input_3_ip_fragment_offset = 0; -reg [7:0] input_3_ip_ttl = 0; -reg [7:0] input_3_ip_protocol = 0; -reg [15:0] input_3_ip_header_checksum = 0; -reg [31:0] input_3_ip_source_ip = 0; -reg [31:0] input_3_ip_dest_ip = 0; -reg [63:0] input_3_ip_payload_tdata = 0; -reg [7:0] input_3_ip_payload_tkeep = 0; -reg input_3_ip_payload_tvalid = 0; -reg input_3_ip_payload_tlast = 0; -reg input_3_ip_payload_tuser = 0; +reg [S_COUNT-1:0] s_ip_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*4-1:0] s_ip_version = 0; +reg [S_COUNT*4-1:0] s_ip_ihl = 0; +reg [S_COUNT*6-1:0] s_ip_dscp = 0; +reg [S_COUNT*2-1:0] s_ip_ecn = 0; +reg [S_COUNT*16-1:0] s_ip_length = 0; +reg [S_COUNT*16-1:0] s_ip_identification = 0; +reg [S_COUNT*3-1:0] s_ip_flags = 0; +reg [S_COUNT*13-1:0] s_ip_fragment_offset = 0; +reg [S_COUNT*8-1:0] s_ip_ttl = 0; +reg [S_COUNT*8-1:0] s_ip_protocol = 0; +reg [S_COUNT*16-1:0] s_ip_header_checksum = 0; +reg [S_COUNT*32-1:0] s_ip_source_ip = 0; +reg [S_COUNT*32-1:0] s_ip_dest_ip = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_ip_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_ip_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_ip_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_ip_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_ip_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_ip_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_ip_payload_axis_tuser = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; reg enable = 0; reg [1:0] select = 0; // Outputs -wire input_0_ip_payload_tready; -wire input_0_ip_hdr_ready; -wire input_1_ip_payload_tready; -wire input_1_ip_hdr_ready; -wire input_2_ip_payload_tready; -wire input_2_ip_hdr_ready; -wire input_3_ip_payload_tready; -wire input_3_ip_hdr_ready; +wire [S_COUNT-1:0] s_ip_hdr_ready; +wire [S_COUNT-1:0] s_ip_payload_axis_tready; -wire output_ip_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [63:0] output_ip_payload_tdata; -wire [7:0] output_ip_payload_tkeep; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire m_ip_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [DATA_WIDTH-1:0] m_ip_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_ip_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_ip_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_ip_payload_axis_tuser; initial begin // myhdl integration @@ -170,130 +114,62 @@ initial begin clk, rst, current_test, - input_0_ip_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_ip_version, - input_0_ip_ihl, - input_0_ip_dscp, - input_0_ip_ecn, - input_0_ip_length, - input_0_ip_identification, - input_0_ip_flags, - input_0_ip_fragment_offset, - input_0_ip_ttl, - input_0_ip_protocol, - input_0_ip_header_checksum, - input_0_ip_source_ip, - input_0_ip_dest_ip, - input_0_ip_payload_tdata, - input_0_ip_payload_tkeep, - input_0_ip_payload_tvalid, - input_0_ip_payload_tlast, - input_0_ip_payload_tuser, - input_1_ip_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_ip_version, - input_1_ip_ihl, - input_1_ip_dscp, - input_1_ip_ecn, - input_1_ip_length, - input_1_ip_identification, - input_1_ip_flags, - input_1_ip_fragment_offset, - input_1_ip_ttl, - input_1_ip_protocol, - input_1_ip_header_checksum, - input_1_ip_source_ip, - input_1_ip_dest_ip, - input_1_ip_payload_tdata, - input_1_ip_payload_tkeep, - input_1_ip_payload_tvalid, - input_1_ip_payload_tlast, - input_1_ip_payload_tuser, - input_2_ip_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_ip_version, - input_2_ip_ihl, - input_2_ip_dscp, - input_2_ip_ecn, - input_2_ip_length, - input_2_ip_identification, - input_2_ip_flags, - input_2_ip_fragment_offset, - input_2_ip_ttl, - input_2_ip_protocol, - input_2_ip_header_checksum, - input_2_ip_source_ip, - input_2_ip_dest_ip, - input_2_ip_payload_tdata, - input_2_ip_payload_tkeep, - input_2_ip_payload_tvalid, - input_2_ip_payload_tlast, - input_2_ip_payload_tuser, - input_3_ip_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_ip_version, - input_3_ip_ihl, - input_3_ip_dscp, - input_3_ip_ecn, - input_3_ip_length, - input_3_ip_identification, - input_3_ip_flags, - input_3_ip_fragment_offset, - input_3_ip_ttl, - input_3_ip_protocol, - input_3_ip_header_checksum, - input_3_ip_source_ip, - input_3_ip_dest_ip, - input_3_ip_payload_tdata, - input_3_ip_payload_tkeep, - input_3_ip_payload_tvalid, - input_3_ip_payload_tlast, - input_3_ip_payload_tuser, - output_ip_hdr_ready, - output_ip_payload_tready, + s_ip_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tid, + s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready, enable, select ); $to_myhdl( - input_0_ip_hdr_ready, - input_0_ip_payload_tready, - input_1_ip_hdr_ready, - input_1_ip_payload_tready, - input_2_ip_hdr_ready, - input_2_ip_payload_tready, - input_3_ip_hdr_ready, - input_3_ip_payload_tready, - output_ip_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tkeep, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_ip_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tid, + m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser ); // dump file @@ -301,132 +177,75 @@ initial begin $dumpvars(0, test_ip_mux_64_4); end -ip_mux_64_4 +ip_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), - // IP frame inputs - .input_0_ip_hdr_valid(input_0_ip_hdr_valid), - .input_0_ip_hdr_ready(input_0_ip_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_ip_payload_tdata(input_0_ip_payload_tdata), - .input_0_ip_payload_tkeep(input_0_ip_payload_tkeep), - .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid), - .input_0_ip_payload_tready(input_0_ip_payload_tready), - .input_0_ip_payload_tlast(input_0_ip_payload_tlast), - .input_0_ip_payload_tuser(input_0_ip_payload_tuser), - .input_1_ip_hdr_valid(input_1_ip_hdr_valid), - .input_1_ip_hdr_ready(input_1_ip_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_ip_payload_tdata(input_1_ip_payload_tdata), - .input_1_ip_payload_tkeep(input_1_ip_payload_tkeep), - .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid), - .input_1_ip_payload_tready(input_1_ip_payload_tready), - .input_1_ip_payload_tlast(input_1_ip_payload_tlast), - .input_1_ip_payload_tuser(input_1_ip_payload_tuser), - .input_2_ip_hdr_valid(input_2_ip_hdr_valid), - .input_2_ip_hdr_ready(input_2_ip_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_ip_payload_tdata(input_2_ip_payload_tdata), - .input_2_ip_payload_tkeep(input_2_ip_payload_tkeep), - .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid), - .input_2_ip_payload_tready(input_2_ip_payload_tready), - .input_2_ip_payload_tlast(input_2_ip_payload_tlast), - .input_2_ip_payload_tuser(input_2_ip_payload_tuser), - .input_3_ip_hdr_valid(input_3_ip_hdr_valid), - .input_3_ip_hdr_ready(input_3_ip_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_ip_payload_tdata(input_3_ip_payload_tdata), - .input_3_ip_payload_tkeep(input_3_ip_payload_tkeep), - .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid), - .input_3_ip_payload_tready(input_3_ip_payload_tready), - .input_3_ip_payload_tlast(input_3_ip_payload_tlast), - .input_3_ip_payload_tuser(input_3_ip_payload_tuser), - // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + // Ethernet frame inputs + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tid(s_ip_payload_axis_tid), + .s_ip_payload_axis_tdest(s_ip_payload_axis_tdest), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), + // Ethernet frame output + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tid(m_ip_payload_axis_tid), + .m_ip_payload_axis_tdest(m_ip_payload_axis_tdest), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Control .enable(enable), .select(select) From 67025121ab3e4a57f64a0a5c42da07f165fd67c9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 Oct 2018 18:09:44 -0700 Subject: [PATCH 459/617] Convert generated udp_mux to verilog parametrized module --- rtl/udp_mux.py | 544 ----------------------------- rtl/udp_mux.v | 418 +++++++++++++++++++++++ rtl/udp_mux_4.v | 676 ------------------------------------ rtl/udp_mux_64.py | 557 ------------------------------ rtl/udp_mux_64_4.v | 695 ------------------------------------- tb/test_udp_mux_4.py | 722 ++++++++++++++------------------------- tb/test_udp_mux_4.v | 616 +++++++++++---------------------- tb/test_udp_mux_64_4.py | 737 ++++++++++++++-------------------------- tb/test_udp_mux_64_4.v | 634 ++++++++++++---------------------- 9 files changed, 1348 insertions(+), 4251 deletions(-) delete mode 100755 rtl/udp_mux.py create mode 100644 rtl/udp_mux.v delete mode 100644 rtl/udp_mux_4.v delete mode 100755 rtl/udp_mux_64.py delete mode 100644 rtl/udp_mux_64_4.v diff --git a/rtl/udp_mux.py b/rtl/udp_mux.py deleted file mode 100755 index 2a4d1e910..000000000 --- a/rtl/udp_mux.py +++ /dev/null @@ -1,544 +0,0 @@ -#!/usr/bin/env python -""" -Generates a UDP mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "udp_mux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port UDP mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * UDP {{n}} port multiplexer - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * UDP frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_udp_hdr_valid, - output wire input_{{p}}_udp_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [3:0] input_{{p}}_ip_version, - input wire [3:0] input_{{p}}_ip_ihl, - input wire [5:0] input_{{p}}_ip_dscp, - input wire [1:0] input_{{p}}_ip_ecn, - input wire [15:0] input_{{p}}_ip_length, - input wire [15:0] input_{{p}}_ip_identification, - input wire [2:0] input_{{p}}_ip_flags, - input wire [12:0] input_{{p}}_ip_fragment_offset, - input wire [7:0] input_{{p}}_ip_ttl, - input wire [7:0] input_{{p}}_ip_protocol, - input wire [15:0] input_{{p}}_ip_header_checksum, - input wire [31:0] input_{{p}}_ip_source_ip, - input wire [31:0] input_{{p}}_ip_dest_ip, - input wire [15:0] input_{{p}}_udp_source_port, - input wire [15:0] input_{{p}}_udp_dest_port, - input wire [15:0] input_{{p}}_udp_length, - input wire [15:0] input_{{p}}_udp_checksum, - input wire [7:0] input_{{p}}_udp_payload_tdata, - input wire input_{{p}}_udp_payload_tvalid, - output wire input_{{p}}_udp_payload_tready, - input wire input_{{p}}_udp_payload_tlast, - input wire input_{{p}}_udp_payload_tuser, -{% endfor %} - /* - * UDP frame output - */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [7:0] output_udp_payload_tdata, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; -{% for p in ports %} -reg input_{{p}}_udp_hdr_ready_reg = 1'b0, input_{{p}}_udp_hdr_ready_next; -{%- endfor %} -{% for p in ports %} -reg input_{{p}}_udp_payload_tready_reg = 1'b0, input_{{p}}_udp_payload_tready_next; -{%- endfor %} - -reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; - -// internal datapath -reg [7:0] output_udp_payload_tdata_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int_reg = 1'b0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; -{% for p in ports %} -assign input_{{p}}_udp_hdr_ready = input_{{p}}_udp_hdr_ready_reg; -{%- endfor %} -{% for p in ports %} -assign input_{{p}}_udp_payload_tready = input_{{p}}_udp_payload_tready_reg; -{%- endfor %} - -assign output_udp_hdr_valid = output_udp_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_udp_source_port = output_udp_source_port_reg; -assign output_udp_dest_port = output_udp_dest_port_reg; -assign output_udp_length = output_udp_length_reg; -assign output_udp_checksum = output_udp_checksum_reg; - -// mux for start of packet detection -reg selected_input_udp_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -reg [3:0] selected_input_ip_version; -reg [3:0] selected_input_ip_ihl; -reg [5:0] selected_input_ip_dscp; -reg [1:0] selected_input_ip_ecn; -reg [15:0] selected_input_ip_length; -reg [15:0] selected_input_ip_identification; -reg [2:0] selected_input_ip_flags; -reg [12:0] selected_input_ip_fragment_offset; -reg [7:0] selected_input_ip_ttl; -reg [7:0] selected_input_ip_protocol; -reg [15:0] selected_input_ip_header_checksum; -reg [31:0] selected_input_ip_source_ip; -reg [31:0] selected_input_ip_dest_ip; -reg [15:0] selected_input_udp_source_port; -reg [15:0] selected_input_udp_dest_port; -reg [15:0] selected_input_udp_length; -reg [15:0] selected_input_udp_checksum; -always @* begin - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: begin - selected_input_udp_hdr_valid = input_{{p}}_udp_hdr_valid; - selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; - selected_input_eth_src_mac = input_{{p}}_eth_src_mac; - selected_input_eth_type = input_{{p}}_eth_type; - selected_input_ip_version = input_{{p}}_ip_version; - selected_input_ip_ihl = input_{{p}}_ip_ihl; - selected_input_ip_dscp = input_{{p}}_ip_dscp; - selected_input_ip_ecn = input_{{p}}_ip_ecn; - selected_input_ip_length = input_{{p}}_ip_length; - selected_input_ip_identification = input_{{p}}_ip_identification; - selected_input_ip_flags = input_{{p}}_ip_flags; - selected_input_ip_fragment_offset = input_{{p}}_ip_fragment_offset; - selected_input_ip_ttl = input_{{p}}_ip_ttl; - selected_input_ip_protocol = input_{{p}}_ip_protocol; - selected_input_ip_header_checksum = input_{{p}}_ip_header_checksum; - selected_input_ip_source_ip = input_{{p}}_ip_source_ip; - selected_input_ip_dest_ip = input_{{p}}_ip_dest_ip; - selected_input_udp_source_port = input_{{p}}_udp_source_port; - selected_input_udp_dest_port = input_{{p}}_udp_dest_port; - selected_input_udp_length = input_{{p}}_udp_length; - selected_input_udp_checksum = input_{{p}}_udp_checksum; - end -{%- endfor %} - default: begin - selected_input_udp_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - selected_input_ip_version = 4'd0; - selected_input_ip_ihl = 4'd0; - selected_input_ip_dscp = 6'd0; - selected_input_ip_ecn = 2'd0; - selected_input_ip_length = 16'd0; - selected_input_ip_identification = 16'd0; - selected_input_ip_flags = 3'd0; - selected_input_ip_fragment_offset = 13'd0; - selected_input_ip_ttl = 8'd0; - selected_input_ip_protocol = 8'd0; - selected_input_ip_header_checksum = 16'd0; - selected_input_ip_source_ip = 32'd0; - selected_input_ip_dest_ip = 32'd0; - selected_input_udp_source_port = 16'd0; - selected_input_udp_dest_port = 16'd0; - selected_input_udp_length = 16'd0; - selected_input_udp_checksum = 16'd0; - end - endcase -end - -// mux for incoming packet -reg [7:0] current_input_tdata; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_input_tdata = input_{{p}}_udp_payload_tdata; - current_input_tvalid = input_{{p}}_udp_payload_tvalid; - current_input_tready = input_{{p}}_udp_payload_tready; - current_input_tlast = input_{{p}}_udp_payload_tlast; - current_input_tuser = input_{{p}}_udp_payload_tuser; - end -{%- endfor %} - default: begin - current_input_tdata = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; -{% for p in ports %} - input_{{p}}_udp_hdr_ready_next = input_{{p}}_udp_hdr_ready_reg & ~input_{{p}}_udp_hdr_valid; -{%- endfor %} -{% for p in ports %} - input_{{p}}_udp_payload_tready_next = 1'b0; -{%- endfor %} - - output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - output_udp_source_port_next = output_udp_source_port_reg; - output_udp_dest_port_next = output_udp_dest_port_reg; - output_udp_length_next = output_udp_length_reg; - output_udp_checksum_next = output_udp_checksum_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin - // start of frame, grab select value - frame_next = 1; - select_next = select; - - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_udp_hdr_ready_next = 1'b1; -{%- endfor %} - endcase - - output_udp_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - output_ip_version_next = selected_input_ip_version; - output_ip_ihl_next = selected_input_ip_ihl; - output_ip_dscp_next = selected_input_ip_dscp; - output_ip_ecn_next = selected_input_ip_ecn; - output_ip_length_next = selected_input_ip_length; - output_ip_identification_next = selected_input_ip_identification; - output_ip_flags_next = selected_input_ip_flags; - output_ip_fragment_offset_next = selected_input_ip_fragment_offset; - output_ip_ttl_next = selected_input_ip_ttl; - output_ip_protocol_next = selected_input_ip_protocol; - output_ip_header_checksum_next = selected_input_ip_header_checksum; - output_ip_source_ip_next = selected_input_ip_source_ip; - output_ip_dest_ip_next = selected_input_ip_dest_ip; - output_udp_source_port_next = selected_input_udp_source_port; - output_udp_dest_port_next = selected_input_udp_dest_port; - output_udp_length_next = selected_input_udp_length; - output_udp_checksum_next = selected_input_udp_checksum; - end - - // generate ready signal on selected port - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; -{%- endfor %} - endcase - - // pass through selected packet data - output_udp_payload_tdata_int = current_input_tdata; - output_udp_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_udp_payload_tlast_int = current_input_tlast; - output_udp_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; -{%- for p in ports %} - input_{{p}}_udp_hdr_ready_reg <= 1'b0; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_udp_payload_tready_reg <= 1'b0; -{%- endfor %} - output_udp_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; -{%- for p in ports %} - input_{{p}}_udp_hdr_ready_reg <= input_{{p}}_udp_hdr_ready_next; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_udp_payload_tready_reg <= input_{{p}}_udp_payload_tready_next; -{%- endfor %} - output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; -end - -// output datapath logic -reg [7:0] output_udp_payload_tdata_reg = 8'd0; -reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; -reg output_udp_payload_tlast_reg = 1'b0; -reg output_udp_payload_tuser_reg = 1'b0; - -reg [7:0] temp_udp_payload_tdata_reg = 8'd0; -reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; -reg temp_udp_payload_tlast_reg = 1'b0; -reg temp_udp_payload_tuser_reg = 1'b0; - -// datapath control -reg store_udp_payload_int_to_output; -reg store_udp_payload_int_to_temp; -reg store_udp_payload_temp_to_output; - -assign output_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; -assign output_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_udp_payload_tuser = output_udp_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - - store_udp_payload_int_to_output = 1'b0; - store_udp_payload_int_to_temp = 1'b0; - store_udp_payload_temp_to_output = 1'b0; - - if (output_udp_payload_tready_int_reg) begin - // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_temp = 1'b1; - end - end else if (output_udp_payload_tready) begin - // input is not ready, but output is ready - output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = 1'b0; - store_udp_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_udp_payload_tvalid_reg <= 1'b0; - output_udp_payload_tready_int_reg <= 1'b0; - temp_udp_payload_tvalid_reg <= 1'b0; - end else begin - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; - output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; - temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; - end - - // datapath - if (store_udp_payload_int_to_output) begin - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else if (store_udp_payload_temp_to_output) begin - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - end - - if (store_udp_payload_int_to_temp) begin - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/udp_mux.v b/rtl/udp_mux.v new file mode 100644 index 000000000..7d33cedbb --- /dev/null +++ b/rtl/udp_mux.v @@ -0,0 +1,418 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * UDP multiplexer + */ +module udp_mux # +( + parameter S_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * UDP frame inputs + */ + input wire [S_COUNT-1:0] s_udp_hdr_valid, + output wire [S_COUNT-1:0] s_udp_hdr_ready, + input wire [S_COUNT*48-1:0] s_eth_dest_mac, + input wire [S_COUNT*48-1:0] s_eth_src_mac, + input wire [S_COUNT*16-1:0] s_eth_type, + input wire [S_COUNT*4-1:0] s_ip_version, + input wire [S_COUNT*4-1:0] s_ip_ihl, + input wire [S_COUNT*6-1:0] s_ip_dscp, + input wire [S_COUNT*2-1:0] s_ip_ecn, + input wire [S_COUNT*16-1:0] s_ip_length, + input wire [S_COUNT*16-1:0] s_ip_identification, + input wire [S_COUNT*3-1:0] s_ip_flags, + input wire [S_COUNT*13-1:0] s_ip_fragment_offset, + input wire [S_COUNT*8-1:0] s_ip_ttl, + input wire [S_COUNT*8-1:0] s_ip_protocol, + input wire [S_COUNT*16-1:0] s_ip_header_checksum, + input wire [S_COUNT*32-1:0] s_ip_source_ip, + input wire [S_COUNT*32-1:0] s_ip_dest_ip, + input wire [S_COUNT*16-1:0] s_udp_source_port, + input wire [S_COUNT*16-1:0] s_udp_dest_port, + input wire [S_COUNT*16-1:0] s_udp_length, + input wire [S_COUNT*16-1:0] s_udp_checksum, + input wire [S_COUNT*DATA_WIDTH-1:0] s_udp_payload_axis_tdata, + input wire [S_COUNT*KEEP_WIDTH-1:0] s_udp_payload_axis_tkeep, + input wire [S_COUNT-1:0] s_udp_payload_axis_tvalid, + output wire [S_COUNT-1:0] s_udp_payload_axis_tready, + input wire [S_COUNT-1:0] s_udp_payload_axis_tlast, + input wire [S_COUNT*ID_WIDTH-1:0] s_udp_payload_axis_tid, + input wire [S_COUNT*DEST_WIDTH-1:0] s_udp_payload_axis_tdest, + input wire [S_COUNT*USER_WIDTH-1:0] s_udp_payload_axis_tuser, + + /* + * UDP frame output + */ + output wire m_udp_hdr_valid, + input wire m_udp_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [15:0] m_udp_source_port, + output wire [15:0] m_udp_dest_port, + output wire [15:0] m_udp_length, + output wire [15:0] m_udp_checksum, + output wire [DATA_WIDTH-1:0] m_udp_payload_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep, + output wire m_udp_payload_axis_tvalid, + input wire m_udp_payload_axis_tready, + output wire m_udp_payload_axis_tlast, + output wire [ID_WIDTH-1:0] m_udp_payload_axis_tid, + output wire [DEST_WIDTH-1:0] m_udp_payload_axis_tdest, + output wire [USER_WIDTH-1:0] m_udp_payload_axis_tuser, + + /* + * Control + */ + input wire enable, + input wire [$clog2(S_COUNT)-1:0] select +); + +parameter CL_S_COUNT = $clog2(S_COUNT); + +reg [CL_S_COUNT-1:0] select_reg = 2'd0, select_next; +reg frame_reg = 1'b0, frame_next; + +reg [S_COUNT-1:0] s_udp_hdr_ready_reg = 0, s_udp_hdr_ready_next; + +reg [S_COUNT-1:0] s_udp_payload_axis_tready_reg = 0, s_udp_payload_axis_tready_next; + +reg m_udp_hdr_valid_reg = 1'b0, m_udp_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0, m_eth_dest_mac_next; +reg [47:0] m_eth_src_mac_reg = 48'd0, m_eth_src_mac_next; +reg [15:0] m_eth_type_reg = 16'd0, m_eth_type_next; +reg [3:0] m_ip_version_reg = 4'd0, m_ip_version_next; +reg [3:0] m_ip_ihl_reg = 4'd0, m_ip_ihl_next; +reg [5:0] m_ip_dscp_reg = 6'd0, m_ip_dscp_next; +reg [1:0] m_ip_ecn_reg = 2'd0, m_ip_ecn_next; +reg [15:0] m_ip_length_reg = 16'd0, m_ip_length_next; +reg [15:0] m_ip_identification_reg = 16'd0, m_ip_identification_next; +reg [2:0] m_ip_flags_reg = 3'd0, m_ip_flags_next; +reg [12:0] m_ip_fragment_offset_reg = 13'd0, m_ip_fragment_offset_next; +reg [7:0] m_ip_ttl_reg = 8'd0, m_ip_ttl_next; +reg [7:0] m_ip_protocol_reg = 8'd0, m_ip_protocol_next; +reg [15:0] m_ip_header_checksum_reg = 16'd0, m_ip_header_checksum_next; +reg [31:0] m_ip_source_ip_reg = 32'd0, m_ip_source_ip_next; +reg [31:0] m_ip_dest_ip_reg = 32'd0, m_ip_dest_ip_next; +reg [15:0] m_udp_source_port_reg = 16'd0, m_udp_source_port_next; +reg [15:0] m_udp_dest_port_reg = 16'd0, m_udp_dest_port_next; +reg [15:0] m_udp_length_reg = 16'd0, m_udp_length_next; +reg [15:0] m_udp_checksum_reg = 16'd0, m_udp_checksum_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_udp_payload_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep_int; +reg m_udp_payload_axis_tvalid_int; +reg m_udp_payload_axis_tready_int_reg = 1'b0; +reg m_udp_payload_axis_tlast_int; +reg [ID_WIDTH-1:0] m_udp_payload_axis_tid_int; +reg [DEST_WIDTH-1:0] m_udp_payload_axis_tdest_int; +reg [USER_WIDTH-1:0] m_udp_payload_axis_tuser_int; +wire m_udp_payload_axis_tready_int_early; + +assign s_udp_hdr_ready = s_udp_hdr_ready_reg; + +assign s_udp_payload_axis_tready = s_udp_payload_axis_tready_reg; + +assign m_udp_hdr_valid = m_udp_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_ip_length_reg; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = m_ip_protocol_reg; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; +assign m_udp_source_port = m_udp_source_port_reg; +assign m_udp_dest_port = m_udp_dest_port_reg; +assign m_udp_length = m_udp_length_reg; +assign m_udp_checksum = m_udp_checksum_reg; + +// mux for incoming packet +wire [DATA_WIDTH-1:0] current_s_tdata = s_udp_payload_axis_tdata[select_reg*DATA_WIDTH +: DATA_WIDTH]; +wire [KEEP_WIDTH-1:0] current_s_tkeep = s_udp_payload_axis_tkeep[select_reg*KEEP_WIDTH +: KEEP_WIDTH]; +wire current_s_tvalid = s_udp_payload_axis_tvalid[select_reg]; +wire current_s_tready = s_udp_payload_axis_tready[select_reg]; +wire current_s_tlast = s_udp_payload_axis_tlast[select_reg]; +wire [ID_WIDTH-1:0] current_s_tid = s_udp_payload_axis_tid[select_reg*ID_WIDTH +: ID_WIDTH]; +wire [DEST_WIDTH-1:0] current_s_tdest = s_udp_payload_axis_tdest[select_reg*DEST_WIDTH +: DEST_WIDTH]; +wire [USER_WIDTH-1:0] current_s_tuser = s_udp_payload_axis_tuser[select_reg*USER_WIDTH +: USER_WIDTH]; + +always @* begin + select_next = select_reg; + frame_next = frame_reg; + + s_udp_hdr_ready_next = 0; + + s_udp_payload_axis_tready_next = 0; + + m_udp_hdr_valid_next = m_udp_hdr_valid_reg && !m_udp_hdr_ready; + m_eth_dest_mac_next = m_eth_dest_mac_reg; + m_eth_src_mac_next = m_eth_src_mac_reg; + m_eth_type_next = m_eth_type_reg; + m_ip_version_next = m_ip_version_reg; + m_ip_ihl_next = m_ip_ihl_reg; + m_ip_dscp_next = m_ip_dscp_reg; + m_ip_ecn_next = m_ip_ecn_reg; + m_ip_length_next = m_ip_length_reg; + m_ip_identification_next = m_ip_identification_reg; + m_ip_flags_next = m_ip_flags_reg; + m_ip_fragment_offset_next = m_ip_fragment_offset_reg; + m_ip_ttl_next = m_ip_ttl_reg; + m_ip_protocol_next = m_ip_protocol_reg; + m_ip_header_checksum_next = m_ip_header_checksum_reg; + m_ip_source_ip_next = m_ip_source_ip_reg; + m_ip_dest_ip_next = m_ip_dest_ip_reg; + m_udp_source_port_next = m_udp_source_port_reg; + m_udp_dest_port_next = m_udp_dest_port_reg; + m_udp_length_next = m_udp_length_reg; + m_udp_checksum_next = m_udp_checksum_reg; + + if (current_s_tvalid & current_s_tready) begin + // end of frame detection + if (current_s_tlast) begin + frame_next = 1'b0; + end + end + + if (!frame_reg && enable && !m_udp_hdr_valid && (s_udp_hdr_valid & (1 << select))) begin + // start of frame, grab select value + frame_next = 1'b1; + select_next = select; + + s_udp_hdr_ready_next = (1 << select); + + m_udp_hdr_valid_next = 1'b1; + m_eth_dest_mac_next = s_eth_dest_mac[select*48 +: 48]; + m_eth_src_mac_next = s_eth_src_mac[select*48 +: 48]; + m_eth_type_next = s_eth_type[select*16 +: 16]; + m_ip_version_next = s_ip_version[select*4 +: 4]; + m_ip_ihl_next = s_ip_ihl[select*4 +: 4]; + m_ip_dscp_next = s_ip_dscp[select*6 +: 6]; + m_ip_ecn_next = s_ip_ecn[select*2 +: 2]; + m_ip_length_next = s_ip_length[select*16 +: 16]; + m_ip_identification_next = s_ip_identification[select*16 +: 16]; + m_ip_flags_next = s_ip_flags[select*3 +: 3]; + m_ip_fragment_offset_next = s_ip_fragment_offset[select*13 +: 13]; + m_ip_ttl_next = s_ip_ttl[select*8 +: 8]; + m_ip_protocol_next = s_ip_protocol[select*8 +: 8]; + m_ip_header_checksum_next = s_ip_header_checksum[select*16 +: 16]; + m_ip_source_ip_next = s_ip_source_ip[select*32 +: 32]; + m_ip_dest_ip_next = s_ip_dest_ip[select*32 +: 32]; + m_udp_source_port_next = s_udp_source_port[select*16 +: 16]; + m_udp_dest_port_next = s_udp_dest_port[select*16 +: 16]; + m_udp_length_next = s_udp_length[select*16 +: 16]; + m_udp_checksum_next = s_udp_checksum[select*16 +: 16]; + end + + // generate ready signal on selected port + s_udp_payload_axis_tready_next = (m_udp_payload_axis_tready_int_early && frame_next) << select_next; + + // pass through selected packet data + m_udp_payload_axis_tdata_int = current_s_tdata; + m_udp_payload_axis_tkeep_int = current_s_tkeep; + m_udp_payload_axis_tvalid_int = current_s_tvalid && current_s_tready && frame_reg; + m_udp_payload_axis_tlast_int = current_s_tlast; + m_udp_payload_axis_tid_int = current_s_tid; + m_udp_payload_axis_tdest_int = current_s_tdest; + m_udp_payload_axis_tuser_int = current_s_tuser; +end + +always @(posedge clk) begin + if (rst) begin + select_reg <= 0; + frame_reg <= 1'b0; + s_udp_hdr_ready_reg <= 0; + s_udp_payload_axis_tready_reg <= 0; + m_udp_hdr_valid_reg <= 1'b0; + end else begin + select_reg <= select_next; + frame_reg <= frame_next; + s_udp_hdr_ready_reg <= s_udp_hdr_ready_next; + s_udp_payload_axis_tready_reg <= s_udp_payload_axis_tready_next; + m_udp_hdr_valid_reg <= m_udp_hdr_valid_next; + end + + m_eth_dest_mac_reg <= m_eth_dest_mac_next; + m_eth_src_mac_reg <= m_eth_src_mac_next; + m_eth_type_reg <= m_eth_type_next; + m_ip_version_reg <= m_ip_version_next; + m_ip_ihl_reg <= m_ip_ihl_next; + m_ip_dscp_reg <= m_ip_dscp_next; + m_ip_ecn_reg <= m_ip_ecn_next; + m_ip_length_reg <= m_ip_length_next; + m_ip_identification_reg <= m_ip_identification_next; + m_ip_flags_reg <= m_ip_flags_next; + m_ip_fragment_offset_reg <= m_ip_fragment_offset_next; + m_ip_ttl_reg <= m_ip_ttl_next; + m_ip_protocol_reg <= m_ip_protocol_next; + m_ip_header_checksum_reg <= m_ip_header_checksum_next; + m_ip_source_ip_reg <= m_ip_source_ip_next; + m_ip_dest_ip_reg <= m_ip_dest_ip_next; + m_udp_source_port_reg <= m_udp_source_port_next; + m_udp_dest_port_reg <= m_udp_dest_port_next; + m_udp_length_reg <= m_udp_length_next; + m_udp_checksum_reg <= m_udp_checksum_next; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_udp_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_udp_payload_axis_tvalid_reg = 1'b0, m_udp_payload_axis_tvalid_next; +reg m_udp_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_udp_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_udp_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_udp_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_udp_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_udp_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_udp_payload_axis_tvalid_reg = 1'b0, temp_m_udp_payload_axis_tvalid_next; +reg temp_m_udp_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_udp_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_udp_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_udp_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign m_udp_payload_axis_tdata = m_udp_payload_axis_tdata_reg; +assign m_udp_payload_axis_tkeep = KEEP_ENABLE ? m_udp_payload_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_udp_payload_axis_tvalid = m_udp_payload_axis_tvalid_reg; +assign m_udp_payload_axis_tlast = m_udp_payload_axis_tlast_reg; +assign m_udp_payload_axis_tid = ID_ENABLE ? m_udp_payload_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_udp_payload_axis_tdest = DEST_ENABLE ? m_udp_payload_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_udp_payload_axis_tuser = USER_ENABLE ? m_udp_payload_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_udp_payload_axis_tready_int_early = m_udp_payload_axis_tready || (!temp_m_udp_payload_axis_tvalid_reg && (!m_udp_payload_axis_tvalid_reg || !m_udp_payload_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_reg; + temp_m_udp_payload_axis_tvalid_next = temp_m_udp_payload_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (m_udp_payload_axis_tready_int_reg) begin + // input is ready + if (m_udp_payload_axis_tready || !m_udp_payload_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_udp_payload_axis_tready) begin + // input is not ready, but output is ready + m_udp_payload_axis_tvalid_next = temp_m_udp_payload_axis_tvalid_reg; + temp_m_udp_payload_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_udp_payload_axis_tvalid_reg <= 1'b0; + m_udp_payload_axis_tready_int_reg <= 1'b0; + temp_m_udp_payload_axis_tvalid_reg <= 1'b0; + end else begin + m_udp_payload_axis_tvalid_reg <= m_udp_payload_axis_tvalid_next; + m_udp_payload_axis_tready_int_reg <= m_udp_payload_axis_tready_int_early; + temp_m_udp_payload_axis_tvalid_reg <= temp_m_udp_payload_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_udp_payload_axis_tdata_reg <= m_udp_payload_axis_tdata_int; + m_udp_payload_axis_tkeep_reg <= m_udp_payload_axis_tkeep_int; + m_udp_payload_axis_tlast_reg <= m_udp_payload_axis_tlast_int; + m_udp_payload_axis_tid_reg <= m_udp_payload_axis_tid_int; + m_udp_payload_axis_tdest_reg <= m_udp_payload_axis_tdest_int; + m_udp_payload_axis_tuser_reg <= m_udp_payload_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + m_udp_payload_axis_tdata_reg <= temp_m_udp_payload_axis_tdata_reg; + m_udp_payload_axis_tkeep_reg <= temp_m_udp_payload_axis_tkeep_reg; + m_udp_payload_axis_tlast_reg <= temp_m_udp_payload_axis_tlast_reg; + m_udp_payload_axis_tid_reg <= temp_m_udp_payload_axis_tid_reg; + m_udp_payload_axis_tdest_reg <= temp_m_udp_payload_axis_tdest_reg; + m_udp_payload_axis_tuser_reg <= temp_m_udp_payload_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_udp_payload_axis_tdata_reg <= m_udp_payload_axis_tdata_int; + temp_m_udp_payload_axis_tkeep_reg <= m_udp_payload_axis_tkeep_int; + temp_m_udp_payload_axis_tlast_reg <= m_udp_payload_axis_tlast_int; + temp_m_udp_payload_axis_tid_reg <= m_udp_payload_axis_tid_int; + temp_m_udp_payload_axis_tdest_reg <= m_udp_payload_axis_tdest_int; + temp_m_udp_payload_axis_tuser_reg <= m_udp_payload_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/udp_mux_4.v b/rtl/udp_mux_4.v deleted file mode 100644 index 2e6c31871..000000000 --- a/rtl/udp_mux_4.v +++ /dev/null @@ -1,676 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * UDP 4 port multiplexer - */ -module udp_mux_4 -( - input wire clk, - input wire rst, - - /* - * UDP frame inputs - */ - input wire input_0_udp_hdr_valid, - output wire input_0_udp_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [15:0] input_0_udp_source_port, - input wire [15:0] input_0_udp_dest_port, - input wire [15:0] input_0_udp_length, - input wire [15:0] input_0_udp_checksum, - input wire [7:0] input_0_udp_payload_tdata, - input wire input_0_udp_payload_tvalid, - output wire input_0_udp_payload_tready, - input wire input_0_udp_payload_tlast, - input wire input_0_udp_payload_tuser, - - input wire input_1_udp_hdr_valid, - output wire input_1_udp_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [15:0] input_1_udp_source_port, - input wire [15:0] input_1_udp_dest_port, - input wire [15:0] input_1_udp_length, - input wire [15:0] input_1_udp_checksum, - input wire [7:0] input_1_udp_payload_tdata, - input wire input_1_udp_payload_tvalid, - output wire input_1_udp_payload_tready, - input wire input_1_udp_payload_tlast, - input wire input_1_udp_payload_tuser, - - input wire input_2_udp_hdr_valid, - output wire input_2_udp_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [3:0] input_2_ip_version, - input wire [3:0] input_2_ip_ihl, - input wire [5:0] input_2_ip_dscp, - input wire [1:0] input_2_ip_ecn, - input wire [15:0] input_2_ip_length, - input wire [15:0] input_2_ip_identification, - input wire [2:0] input_2_ip_flags, - input wire [12:0] input_2_ip_fragment_offset, - input wire [7:0] input_2_ip_ttl, - input wire [7:0] input_2_ip_protocol, - input wire [15:0] input_2_ip_header_checksum, - input wire [31:0] input_2_ip_source_ip, - input wire [31:0] input_2_ip_dest_ip, - input wire [15:0] input_2_udp_source_port, - input wire [15:0] input_2_udp_dest_port, - input wire [15:0] input_2_udp_length, - input wire [15:0] input_2_udp_checksum, - input wire [7:0] input_2_udp_payload_tdata, - input wire input_2_udp_payload_tvalid, - output wire input_2_udp_payload_tready, - input wire input_2_udp_payload_tlast, - input wire input_2_udp_payload_tuser, - - input wire input_3_udp_hdr_valid, - output wire input_3_udp_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [3:0] input_3_ip_version, - input wire [3:0] input_3_ip_ihl, - input wire [5:0] input_3_ip_dscp, - input wire [1:0] input_3_ip_ecn, - input wire [15:0] input_3_ip_length, - input wire [15:0] input_3_ip_identification, - input wire [2:0] input_3_ip_flags, - input wire [12:0] input_3_ip_fragment_offset, - input wire [7:0] input_3_ip_ttl, - input wire [7:0] input_3_ip_protocol, - input wire [15:0] input_3_ip_header_checksum, - input wire [31:0] input_3_ip_source_ip, - input wire [31:0] input_3_ip_dest_ip, - input wire [15:0] input_3_udp_source_port, - input wire [15:0] input_3_udp_dest_port, - input wire [15:0] input_3_udp_length, - input wire [15:0] input_3_udp_checksum, - input wire [7:0] input_3_udp_payload_tdata, - input wire input_3_udp_payload_tvalid, - output wire input_3_udp_payload_tready, - input wire input_3_udp_payload_tlast, - input wire input_3_udp_payload_tuser, - - /* - * UDP frame output - */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [7:0] output_udp_payload_tdata, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_udp_hdr_ready_reg = 1'b0, input_0_udp_hdr_ready_next; -reg input_1_udp_hdr_ready_reg = 1'b0, input_1_udp_hdr_ready_next; -reg input_2_udp_hdr_ready_reg = 1'b0, input_2_udp_hdr_ready_next; -reg input_3_udp_hdr_ready_reg = 1'b0, input_3_udp_hdr_ready_next; - -reg input_0_udp_payload_tready_reg = 1'b0, input_0_udp_payload_tready_next; -reg input_1_udp_payload_tready_reg = 1'b0, input_1_udp_payload_tready_next; -reg input_2_udp_payload_tready_reg = 1'b0, input_2_udp_payload_tready_next; -reg input_3_udp_payload_tready_reg = 1'b0, input_3_udp_payload_tready_next; - -reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; - -// internal datapath -reg [7:0] output_udp_payload_tdata_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int_reg = 1'b0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; - -assign input_0_udp_hdr_ready = input_0_udp_hdr_ready_reg; -assign input_1_udp_hdr_ready = input_1_udp_hdr_ready_reg; -assign input_2_udp_hdr_ready = input_2_udp_hdr_ready_reg; -assign input_3_udp_hdr_ready = input_3_udp_hdr_ready_reg; - -assign input_0_udp_payload_tready = input_0_udp_payload_tready_reg; -assign input_1_udp_payload_tready = input_1_udp_payload_tready_reg; -assign input_2_udp_payload_tready = input_2_udp_payload_tready_reg; -assign input_3_udp_payload_tready = input_3_udp_payload_tready_reg; - -assign output_udp_hdr_valid = output_udp_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_udp_source_port = output_udp_source_port_reg; -assign output_udp_dest_port = output_udp_dest_port_reg; -assign output_udp_length = output_udp_length_reg; -assign output_udp_checksum = output_udp_checksum_reg; - -// mux for start of packet detection -reg selected_input_udp_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -reg [3:0] selected_input_ip_version; -reg [3:0] selected_input_ip_ihl; -reg [5:0] selected_input_ip_dscp; -reg [1:0] selected_input_ip_ecn; -reg [15:0] selected_input_ip_length; -reg [15:0] selected_input_ip_identification; -reg [2:0] selected_input_ip_flags; -reg [12:0] selected_input_ip_fragment_offset; -reg [7:0] selected_input_ip_ttl; -reg [7:0] selected_input_ip_protocol; -reg [15:0] selected_input_ip_header_checksum; -reg [31:0] selected_input_ip_source_ip; -reg [31:0] selected_input_ip_dest_ip; -reg [15:0] selected_input_udp_source_port; -reg [15:0] selected_input_udp_dest_port; -reg [15:0] selected_input_udp_length; -reg [15:0] selected_input_udp_checksum; -always @* begin - case (select) - 2'd0: begin - selected_input_udp_hdr_valid = input_0_udp_hdr_valid; - selected_input_eth_dest_mac = input_0_eth_dest_mac; - selected_input_eth_src_mac = input_0_eth_src_mac; - selected_input_eth_type = input_0_eth_type; - selected_input_ip_version = input_0_ip_version; - selected_input_ip_ihl = input_0_ip_ihl; - selected_input_ip_dscp = input_0_ip_dscp; - selected_input_ip_ecn = input_0_ip_ecn; - selected_input_ip_length = input_0_ip_length; - selected_input_ip_identification = input_0_ip_identification; - selected_input_ip_flags = input_0_ip_flags; - selected_input_ip_fragment_offset = input_0_ip_fragment_offset; - selected_input_ip_ttl = input_0_ip_ttl; - selected_input_ip_protocol = input_0_ip_protocol; - selected_input_ip_header_checksum = input_0_ip_header_checksum; - selected_input_ip_source_ip = input_0_ip_source_ip; - selected_input_ip_dest_ip = input_0_ip_dest_ip; - selected_input_udp_source_port = input_0_udp_source_port; - selected_input_udp_dest_port = input_0_udp_dest_port; - selected_input_udp_length = input_0_udp_length; - selected_input_udp_checksum = input_0_udp_checksum; - end - 2'd1: begin - selected_input_udp_hdr_valid = input_1_udp_hdr_valid; - selected_input_eth_dest_mac = input_1_eth_dest_mac; - selected_input_eth_src_mac = input_1_eth_src_mac; - selected_input_eth_type = input_1_eth_type; - selected_input_ip_version = input_1_ip_version; - selected_input_ip_ihl = input_1_ip_ihl; - selected_input_ip_dscp = input_1_ip_dscp; - selected_input_ip_ecn = input_1_ip_ecn; - selected_input_ip_length = input_1_ip_length; - selected_input_ip_identification = input_1_ip_identification; - selected_input_ip_flags = input_1_ip_flags; - selected_input_ip_fragment_offset = input_1_ip_fragment_offset; - selected_input_ip_ttl = input_1_ip_ttl; - selected_input_ip_protocol = input_1_ip_protocol; - selected_input_ip_header_checksum = input_1_ip_header_checksum; - selected_input_ip_source_ip = input_1_ip_source_ip; - selected_input_ip_dest_ip = input_1_ip_dest_ip; - selected_input_udp_source_port = input_1_udp_source_port; - selected_input_udp_dest_port = input_1_udp_dest_port; - selected_input_udp_length = input_1_udp_length; - selected_input_udp_checksum = input_1_udp_checksum; - end - 2'd2: begin - selected_input_udp_hdr_valid = input_2_udp_hdr_valid; - selected_input_eth_dest_mac = input_2_eth_dest_mac; - selected_input_eth_src_mac = input_2_eth_src_mac; - selected_input_eth_type = input_2_eth_type; - selected_input_ip_version = input_2_ip_version; - selected_input_ip_ihl = input_2_ip_ihl; - selected_input_ip_dscp = input_2_ip_dscp; - selected_input_ip_ecn = input_2_ip_ecn; - selected_input_ip_length = input_2_ip_length; - selected_input_ip_identification = input_2_ip_identification; - selected_input_ip_flags = input_2_ip_flags; - selected_input_ip_fragment_offset = input_2_ip_fragment_offset; - selected_input_ip_ttl = input_2_ip_ttl; - selected_input_ip_protocol = input_2_ip_protocol; - selected_input_ip_header_checksum = input_2_ip_header_checksum; - selected_input_ip_source_ip = input_2_ip_source_ip; - selected_input_ip_dest_ip = input_2_ip_dest_ip; - selected_input_udp_source_port = input_2_udp_source_port; - selected_input_udp_dest_port = input_2_udp_dest_port; - selected_input_udp_length = input_2_udp_length; - selected_input_udp_checksum = input_2_udp_checksum; - end - 2'd3: begin - selected_input_udp_hdr_valid = input_3_udp_hdr_valid; - selected_input_eth_dest_mac = input_3_eth_dest_mac; - selected_input_eth_src_mac = input_3_eth_src_mac; - selected_input_eth_type = input_3_eth_type; - selected_input_ip_version = input_3_ip_version; - selected_input_ip_ihl = input_3_ip_ihl; - selected_input_ip_dscp = input_3_ip_dscp; - selected_input_ip_ecn = input_3_ip_ecn; - selected_input_ip_length = input_3_ip_length; - selected_input_ip_identification = input_3_ip_identification; - selected_input_ip_flags = input_3_ip_flags; - selected_input_ip_fragment_offset = input_3_ip_fragment_offset; - selected_input_ip_ttl = input_3_ip_ttl; - selected_input_ip_protocol = input_3_ip_protocol; - selected_input_ip_header_checksum = input_3_ip_header_checksum; - selected_input_ip_source_ip = input_3_ip_source_ip; - selected_input_ip_dest_ip = input_3_ip_dest_ip; - selected_input_udp_source_port = input_3_udp_source_port; - selected_input_udp_dest_port = input_3_udp_dest_port; - selected_input_udp_length = input_3_udp_length; - selected_input_udp_checksum = input_3_udp_checksum; - end - default: begin - selected_input_udp_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - selected_input_ip_version = 4'd0; - selected_input_ip_ihl = 4'd0; - selected_input_ip_dscp = 6'd0; - selected_input_ip_ecn = 2'd0; - selected_input_ip_length = 16'd0; - selected_input_ip_identification = 16'd0; - selected_input_ip_flags = 3'd0; - selected_input_ip_fragment_offset = 13'd0; - selected_input_ip_ttl = 8'd0; - selected_input_ip_protocol = 8'd0; - selected_input_ip_header_checksum = 16'd0; - selected_input_ip_source_ip = 32'd0; - selected_input_ip_dest_ip = 32'd0; - selected_input_udp_source_port = 16'd0; - selected_input_udp_dest_port = 16'd0; - selected_input_udp_length = 16'd0; - selected_input_udp_checksum = 16'd0; - end - endcase -end - -// mux for incoming packet -reg [7:0] current_input_tdata; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 2'd0: begin - current_input_tdata = input_0_udp_payload_tdata; - current_input_tvalid = input_0_udp_payload_tvalid; - current_input_tready = input_0_udp_payload_tready; - current_input_tlast = input_0_udp_payload_tlast; - current_input_tuser = input_0_udp_payload_tuser; - end - 2'd1: begin - current_input_tdata = input_1_udp_payload_tdata; - current_input_tvalid = input_1_udp_payload_tvalid; - current_input_tready = input_1_udp_payload_tready; - current_input_tlast = input_1_udp_payload_tlast; - current_input_tuser = input_1_udp_payload_tuser; - end - 2'd2: begin - current_input_tdata = input_2_udp_payload_tdata; - current_input_tvalid = input_2_udp_payload_tvalid; - current_input_tready = input_2_udp_payload_tready; - current_input_tlast = input_2_udp_payload_tlast; - current_input_tuser = input_2_udp_payload_tuser; - end - 2'd3: begin - current_input_tdata = input_3_udp_payload_tdata; - current_input_tvalid = input_3_udp_payload_tvalid; - current_input_tready = input_3_udp_payload_tready; - current_input_tlast = input_3_udp_payload_tlast; - current_input_tuser = input_3_udp_payload_tuser; - end - default: begin - current_input_tdata = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_udp_hdr_ready_next = input_0_udp_hdr_ready_reg & ~input_0_udp_hdr_valid; - input_1_udp_hdr_ready_next = input_1_udp_hdr_ready_reg & ~input_1_udp_hdr_valid; - input_2_udp_hdr_ready_next = input_2_udp_hdr_ready_reg & ~input_2_udp_hdr_valid; - input_3_udp_hdr_ready_next = input_3_udp_hdr_ready_reg & ~input_3_udp_hdr_valid; - - input_0_udp_payload_tready_next = 1'b0; - input_1_udp_payload_tready_next = 1'b0; - input_2_udp_payload_tready_next = 1'b0; - input_3_udp_payload_tready_next = 1'b0; - - output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - output_udp_source_port_next = output_udp_source_port_reg; - output_udp_dest_port_next = output_udp_dest_port_reg; - output_udp_length_next = output_udp_length_reg; - output_udp_checksum_next = output_udp_checksum_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin - // start of frame, grab select value - frame_next = 1; - select_next = select; - - case (select_next) - 2'd0: input_0_udp_hdr_ready_next = 1'b1; - 2'd1: input_1_udp_hdr_ready_next = 1'b1; - 2'd2: input_2_udp_hdr_ready_next = 1'b1; - 2'd3: input_3_udp_hdr_ready_next = 1'b1; - endcase - - output_udp_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - output_ip_version_next = selected_input_ip_version; - output_ip_ihl_next = selected_input_ip_ihl; - output_ip_dscp_next = selected_input_ip_dscp; - output_ip_ecn_next = selected_input_ip_ecn; - output_ip_length_next = selected_input_ip_length; - output_ip_identification_next = selected_input_ip_identification; - output_ip_flags_next = selected_input_ip_flags; - output_ip_fragment_offset_next = selected_input_ip_fragment_offset; - output_ip_ttl_next = selected_input_ip_ttl; - output_ip_protocol_next = selected_input_ip_protocol; - output_ip_header_checksum_next = selected_input_ip_header_checksum; - output_ip_source_ip_next = selected_input_ip_source_ip; - output_ip_dest_ip_next = selected_input_ip_dest_ip; - output_udp_source_port_next = selected_input_udp_source_port; - output_udp_dest_port_next = selected_input_udp_dest_port; - output_udp_length_next = selected_input_udp_length; - output_udp_checksum_next = selected_input_udp_checksum; - end - - // generate ready signal on selected port - case (select_next) - 2'd0: input_0_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - 2'd1: input_1_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - 2'd2: input_2_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - 2'd3: input_3_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_udp_payload_tdata_int = current_input_tdata; - output_udp_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_udp_payload_tlast_int = current_input_tlast; - output_udp_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_0_udp_hdr_ready_reg <= 1'b0; - input_1_udp_hdr_ready_reg <= 1'b0; - input_2_udp_hdr_ready_reg <= 1'b0; - input_3_udp_hdr_ready_reg <= 1'b0; - input_0_udp_payload_tready_reg <= 1'b0; - input_1_udp_payload_tready_reg <= 1'b0; - input_2_udp_payload_tready_reg <= 1'b0; - input_3_udp_payload_tready_reg <= 1'b0; - output_udp_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_udp_hdr_ready_reg <= input_0_udp_hdr_ready_next; - input_1_udp_hdr_ready_reg <= input_1_udp_hdr_ready_next; - input_2_udp_hdr_ready_reg <= input_2_udp_hdr_ready_next; - input_3_udp_hdr_ready_reg <= input_3_udp_hdr_ready_next; - input_0_udp_payload_tready_reg <= input_0_udp_payload_tready_next; - input_1_udp_payload_tready_reg <= input_1_udp_payload_tready_next; - input_2_udp_payload_tready_reg <= input_2_udp_payload_tready_next; - input_3_udp_payload_tready_reg <= input_3_udp_payload_tready_next; - output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; -end - -// output datapath logic -reg [7:0] output_udp_payload_tdata_reg = 8'd0; -reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; -reg output_udp_payload_tlast_reg = 1'b0; -reg output_udp_payload_tuser_reg = 1'b0; - -reg [7:0] temp_udp_payload_tdata_reg = 8'd0; -reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; -reg temp_udp_payload_tlast_reg = 1'b0; -reg temp_udp_payload_tuser_reg = 1'b0; - -// datapath control -reg store_udp_payload_int_to_output; -reg store_udp_payload_int_to_temp; -reg store_udp_payload_temp_to_output; - -assign output_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; -assign output_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_udp_payload_tuser = output_udp_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - - store_udp_payload_int_to_output = 1'b0; - store_udp_payload_int_to_temp = 1'b0; - store_udp_payload_temp_to_output = 1'b0; - - if (output_udp_payload_tready_int_reg) begin - // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_temp = 1'b1; - end - end else if (output_udp_payload_tready) begin - // input is not ready, but output is ready - output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = 1'b0; - store_udp_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_udp_payload_tvalid_reg <= 1'b0; - output_udp_payload_tready_int_reg <= 1'b0; - temp_udp_payload_tvalid_reg <= 1'b0; - end else begin - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; - output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; - temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; - end - - // datapath - if (store_udp_payload_int_to_output) begin - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else if (store_udp_payload_temp_to_output) begin - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - end - - if (store_udp_payload_int_to_temp) begin - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end -end - -endmodule diff --git a/rtl/udp_mux_64.py b/rtl/udp_mux_64.py deleted file mode 100755 index 8436306a1..000000000 --- a/rtl/udp_mux_64.py +++ /dev/null @@ -1,557 +0,0 @@ -#!/usr/bin/env python -""" -Generates a UDP mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "udp_mux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port UDP mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * UDP {{n}} port multiplexer (64 bit datapath) - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * UDP frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_udp_hdr_valid, - output wire input_{{p}}_udp_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [3:0] input_{{p}}_ip_version, - input wire [3:0] input_{{p}}_ip_ihl, - input wire [5:0] input_{{p}}_ip_dscp, - input wire [1:0] input_{{p}}_ip_ecn, - input wire [15:0] input_{{p}}_ip_length, - input wire [15:0] input_{{p}}_ip_identification, - input wire [2:0] input_{{p}}_ip_flags, - input wire [12:0] input_{{p}}_ip_fragment_offset, - input wire [7:0] input_{{p}}_ip_ttl, - input wire [7:0] input_{{p}}_ip_protocol, - input wire [15:0] input_{{p}}_ip_header_checksum, - input wire [31:0] input_{{p}}_ip_source_ip, - input wire [31:0] input_{{p}}_ip_dest_ip, - input wire [15:0] input_{{p}}_udp_source_port, - input wire [15:0] input_{{p}}_udp_dest_port, - input wire [15:0] input_{{p}}_udp_length, - input wire [15:0] input_{{p}}_udp_checksum, - input wire [63:0] input_{{p}}_udp_payload_tdata, - input wire [7:0] input_{{p}}_udp_payload_tkeep, - input wire input_{{p}}_udp_payload_tvalid, - output wire input_{{p}}_udp_payload_tready, - input wire input_{{p}}_udp_payload_tlast, - input wire input_{{p}}_udp_payload_tuser, -{% endfor %} - /* - * UDP frame output - */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [63:0] output_udp_payload_tdata, - output wire [7:0] output_udp_payload_tkeep, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; -{% for p in ports %} -reg input_{{p}}_udp_hdr_ready_reg = 1'b0, input_{{p}}_udp_hdr_ready_next; -{%- endfor %} -{% for p in ports %} -reg input_{{p}}_udp_payload_tready_reg = 1'b0, input_{{p}}_udp_payload_tready_next; -{%- endfor %} - -reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; - -// internal datapath -reg [63:0] output_udp_payload_tdata_int; -reg [7:0] output_udp_payload_tkeep_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int_reg = 1'b0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; -{% for p in ports %} -assign input_{{p}}_udp_hdr_ready = input_{{p}}_udp_hdr_ready_reg; -{%- endfor %} -{% for p in ports %} -assign input_{{p}}_udp_payload_tready = input_{{p}}_udp_payload_tready_reg; -{%- endfor %} - -assign output_udp_hdr_valid = output_udp_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_udp_source_port = output_udp_source_port_reg; -assign output_udp_dest_port = output_udp_dest_port_reg; -assign output_udp_length = output_udp_length_reg; -assign output_udp_checksum = output_udp_checksum_reg; - -// mux for start of packet detection -reg selected_input_udp_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -reg [3:0] selected_input_ip_version; -reg [3:0] selected_input_ip_ihl; -reg [5:0] selected_input_ip_dscp; -reg [1:0] selected_input_ip_ecn; -reg [15:0] selected_input_ip_length; -reg [15:0] selected_input_ip_identification; -reg [2:0] selected_input_ip_flags; -reg [12:0] selected_input_ip_fragment_offset; -reg [7:0] selected_input_ip_ttl; -reg [7:0] selected_input_ip_protocol; -reg [15:0] selected_input_ip_header_checksum; -reg [31:0] selected_input_ip_source_ip; -reg [31:0] selected_input_ip_dest_ip; -reg [15:0] selected_input_udp_source_port; -reg [15:0] selected_input_udp_dest_port; -reg [15:0] selected_input_udp_length; -reg [15:0] selected_input_udp_checksum; -always @* begin - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: begin - selected_input_udp_hdr_valid = input_{{p}}_udp_hdr_valid; - selected_input_eth_dest_mac = input_{{p}}_eth_dest_mac; - selected_input_eth_src_mac = input_{{p}}_eth_src_mac; - selected_input_eth_type = input_{{p}}_eth_type; - selected_input_ip_version = input_{{p}}_ip_version; - selected_input_ip_ihl = input_{{p}}_ip_ihl; - selected_input_ip_dscp = input_{{p}}_ip_dscp; - selected_input_ip_ecn = input_{{p}}_ip_ecn; - selected_input_ip_length = input_{{p}}_ip_length; - selected_input_ip_identification = input_{{p}}_ip_identification; - selected_input_ip_flags = input_{{p}}_ip_flags; - selected_input_ip_fragment_offset = input_{{p}}_ip_fragment_offset; - selected_input_ip_ttl = input_{{p}}_ip_ttl; - selected_input_ip_protocol = input_{{p}}_ip_protocol; - selected_input_ip_header_checksum = input_{{p}}_ip_header_checksum; - selected_input_ip_source_ip = input_{{p}}_ip_source_ip; - selected_input_ip_dest_ip = input_{{p}}_ip_dest_ip; - selected_input_udp_source_port = input_{{p}}_udp_source_port; - selected_input_udp_dest_port = input_{{p}}_udp_dest_port; - selected_input_udp_length = input_{{p}}_udp_length; - selected_input_udp_checksum = input_{{p}}_udp_checksum; - end -{%- endfor %} - default: begin - selected_input_udp_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - selected_input_ip_version = 4'd0; - selected_input_ip_ihl = 4'd0; - selected_input_ip_dscp = 6'd0; - selected_input_ip_ecn = 2'd0; - selected_input_ip_length = 16'd0; - selected_input_ip_identification = 16'd0; - selected_input_ip_flags = 3'd0; - selected_input_ip_fragment_offset = 13'd0; - selected_input_ip_ttl = 8'd0; - selected_input_ip_protocol = 8'd0; - selected_input_ip_header_checksum = 16'd0; - selected_input_ip_source_ip = 32'd0; - selected_input_ip_dest_ip = 32'd0; - selected_input_udp_source_port = 16'd0; - selected_input_udp_dest_port = 16'd0; - selected_input_udp_length = 16'd0; - selected_input_udp_checksum = 16'd0; - end - endcase -end - -// mux for incoming packet -reg [63:0] current_input_tdata; -reg [7:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_input_tdata = input_{{p}}_udp_payload_tdata; - current_input_tkeep = input_{{p}}_udp_payload_tkeep; - current_input_tvalid = input_{{p}}_udp_payload_tvalid; - current_input_tready = input_{{p}}_udp_payload_tready; - current_input_tlast = input_{{p}}_udp_payload_tlast; - current_input_tuser = input_{{p}}_udp_payload_tuser; - end -{%- endfor %} - default: begin - current_input_tdata = 64'd0; - current_input_tkeep = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; -{% for p in ports %} - input_{{p}}_udp_hdr_ready_next = input_{{p}}_udp_hdr_ready_reg & ~input_{{p}}_udp_hdr_valid; -{%- endfor %} -{% for p in ports %} - input_{{p}}_udp_payload_tready_next = 1'b0; -{%- endfor %} - - output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - output_udp_source_port_next = output_udp_source_port_reg; - output_udp_dest_port_next = output_udp_dest_port_reg; - output_udp_length_next = output_udp_length_reg; - output_udp_checksum_next = output_udp_checksum_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_udp_hdr_ready_next = 1'b1; -{%- endfor %} - endcase - - output_udp_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - output_ip_version_next = selected_input_ip_version; - output_ip_ihl_next = selected_input_ip_ihl; - output_ip_dscp_next = selected_input_ip_dscp; - output_ip_ecn_next = selected_input_ip_ecn; - output_ip_length_next = selected_input_ip_length; - output_ip_identification_next = selected_input_ip_identification; - output_ip_flags_next = selected_input_ip_flags; - output_ip_fragment_offset_next = selected_input_ip_fragment_offset; - output_ip_ttl_next = selected_input_ip_ttl; - output_ip_protocol_next = selected_input_ip_protocol; - output_ip_header_checksum_next = selected_input_ip_header_checksum; - output_ip_source_ip_next = selected_input_ip_source_ip; - output_ip_dest_ip_next = selected_input_ip_dest_ip; - output_udp_source_port_next = selected_input_udp_source_port; - output_udp_dest_port_next = selected_input_udp_dest_port; - output_udp_length_next = selected_input_udp_length; - output_udp_checksum_next = selected_input_udp_checksum; - end - - // generate ready signal on selected port - case (select_next) -{%- for p in ports %} - {{w}}'d{{p}}: input_{{p}}_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; -{%- endfor %} - endcase - - // pass through selected packet data - output_udp_payload_tdata_int = current_input_tdata; - output_udp_payload_tkeep_int = current_input_tkeep; - output_udp_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_udp_payload_tlast_int = current_input_tlast; - output_udp_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; -{%- for p in ports %} - input_{{p}}_udp_hdr_ready_reg <= 1'b0; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_udp_payload_tready_reg <= 1'b0; -{%- endfor %} - output_udp_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; -{%- for p in ports %} - input_{{p}}_udp_hdr_ready_reg <= input_{{p}}_udp_hdr_ready_next; -{%- endfor %} -{%- for p in ports %} - input_{{p}}_udp_payload_tready_reg <= input_{{p}}_udp_payload_tready_next; -{%- endfor %} - output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; -end - -// output datapath logic -reg [63:0] output_udp_payload_tdata_reg = 64'd0; -reg [7:0] output_udp_payload_tkeep_reg = 8'd0; -reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; -reg output_udp_payload_tlast_reg = 1'b0; -reg output_udp_payload_tuser_reg = 1'b0; - -reg [63:0] temp_udp_payload_tdata_reg = 64'd0; -reg [7:0] temp_udp_payload_tkeep_reg = 8'd0; -reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; -reg temp_udp_payload_tlast_reg = 1'b0; -reg temp_udp_payload_tuser_reg = 1'b0; - -// datapath control -reg store_udp_payload_int_to_output; -reg store_udp_payload_int_to_temp; -reg store_udp_payload_temp_to_output; - -assign output_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; -assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; -assign output_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_udp_payload_tuser = output_udp_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - - store_udp_payload_int_to_output = 1'b0; - store_udp_payload_int_to_temp = 1'b0; - store_udp_payload_temp_to_output = 1'b0; - - if (output_udp_payload_tready_int_reg) begin - // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_temp = 1'b1; - end - end else if (output_udp_payload_tready) begin - // input is not ready, but output is ready - output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = 1'b0; - store_udp_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_udp_payload_tvalid_reg <= 1'b0; - output_udp_payload_tready_int_reg <= 1'b0; - temp_udp_payload_tvalid_reg <= 1'b0; - end else begin - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; - output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; - temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; - end - - // datapath - if (store_udp_payload_int_to_output) begin - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else if (store_udp_payload_temp_to_output) begin - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - end - - if (store_udp_payload_int_to_temp) begin - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/udp_mux_64_4.v b/rtl/udp_mux_64_4.v deleted file mode 100644 index e336b226a..000000000 --- a/rtl/udp_mux_64_4.v +++ /dev/null @@ -1,695 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * UDP 4 port multiplexer (64 bit datapath) - */ -module udp_mux_64_4 -( - input wire clk, - input wire rst, - - /* - * UDP frame inputs - */ - input wire input_0_udp_hdr_valid, - output wire input_0_udp_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [15:0] input_0_udp_source_port, - input wire [15:0] input_0_udp_dest_port, - input wire [15:0] input_0_udp_length, - input wire [15:0] input_0_udp_checksum, - input wire [63:0] input_0_udp_payload_tdata, - input wire [7:0] input_0_udp_payload_tkeep, - input wire input_0_udp_payload_tvalid, - output wire input_0_udp_payload_tready, - input wire input_0_udp_payload_tlast, - input wire input_0_udp_payload_tuser, - - input wire input_1_udp_hdr_valid, - output wire input_1_udp_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [15:0] input_1_udp_source_port, - input wire [15:0] input_1_udp_dest_port, - input wire [15:0] input_1_udp_length, - input wire [15:0] input_1_udp_checksum, - input wire [63:0] input_1_udp_payload_tdata, - input wire [7:0] input_1_udp_payload_tkeep, - input wire input_1_udp_payload_tvalid, - output wire input_1_udp_payload_tready, - input wire input_1_udp_payload_tlast, - input wire input_1_udp_payload_tuser, - - input wire input_2_udp_hdr_valid, - output wire input_2_udp_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [3:0] input_2_ip_version, - input wire [3:0] input_2_ip_ihl, - input wire [5:0] input_2_ip_dscp, - input wire [1:0] input_2_ip_ecn, - input wire [15:0] input_2_ip_length, - input wire [15:0] input_2_ip_identification, - input wire [2:0] input_2_ip_flags, - input wire [12:0] input_2_ip_fragment_offset, - input wire [7:0] input_2_ip_ttl, - input wire [7:0] input_2_ip_protocol, - input wire [15:0] input_2_ip_header_checksum, - input wire [31:0] input_2_ip_source_ip, - input wire [31:0] input_2_ip_dest_ip, - input wire [15:0] input_2_udp_source_port, - input wire [15:0] input_2_udp_dest_port, - input wire [15:0] input_2_udp_length, - input wire [15:0] input_2_udp_checksum, - input wire [63:0] input_2_udp_payload_tdata, - input wire [7:0] input_2_udp_payload_tkeep, - input wire input_2_udp_payload_tvalid, - output wire input_2_udp_payload_tready, - input wire input_2_udp_payload_tlast, - input wire input_2_udp_payload_tuser, - - input wire input_3_udp_hdr_valid, - output wire input_3_udp_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [3:0] input_3_ip_version, - input wire [3:0] input_3_ip_ihl, - input wire [5:0] input_3_ip_dscp, - input wire [1:0] input_3_ip_ecn, - input wire [15:0] input_3_ip_length, - input wire [15:0] input_3_ip_identification, - input wire [2:0] input_3_ip_flags, - input wire [12:0] input_3_ip_fragment_offset, - input wire [7:0] input_3_ip_ttl, - input wire [7:0] input_3_ip_protocol, - input wire [15:0] input_3_ip_header_checksum, - input wire [31:0] input_3_ip_source_ip, - input wire [31:0] input_3_ip_dest_ip, - input wire [15:0] input_3_udp_source_port, - input wire [15:0] input_3_udp_dest_port, - input wire [15:0] input_3_udp_length, - input wire [15:0] input_3_udp_checksum, - input wire [63:0] input_3_udp_payload_tdata, - input wire [7:0] input_3_udp_payload_tkeep, - input wire input_3_udp_payload_tvalid, - output wire input_3_udp_payload_tready, - input wire input_3_udp_payload_tlast, - input wire input_3_udp_payload_tuser, - - /* - * UDP frame output - */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [63:0] output_udp_payload_tdata, - output wire [7:0] output_udp_payload_tkeep, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_0_udp_hdr_ready_reg = 1'b0, input_0_udp_hdr_ready_next; -reg input_1_udp_hdr_ready_reg = 1'b0, input_1_udp_hdr_ready_next; -reg input_2_udp_hdr_ready_reg = 1'b0, input_2_udp_hdr_ready_next; -reg input_3_udp_hdr_ready_reg = 1'b0, input_3_udp_hdr_ready_next; - -reg input_0_udp_payload_tready_reg = 1'b0, input_0_udp_payload_tready_next; -reg input_1_udp_payload_tready_reg = 1'b0, input_1_udp_payload_tready_next; -reg input_2_udp_payload_tready_reg = 1'b0, input_2_udp_payload_tready_next; -reg input_3_udp_payload_tready_reg = 1'b0, input_3_udp_payload_tready_next; - -reg output_udp_hdr_valid_reg = 0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; - -// internal datapath -reg [63:0] output_udp_payload_tdata_int; -reg [7:0] output_udp_payload_tkeep_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int_reg = 1'b0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; - -assign input_0_udp_hdr_ready = input_0_udp_hdr_ready_reg; -assign input_1_udp_hdr_ready = input_1_udp_hdr_ready_reg; -assign input_2_udp_hdr_ready = input_2_udp_hdr_ready_reg; -assign input_3_udp_hdr_ready = input_3_udp_hdr_ready_reg; - -assign input_0_udp_payload_tready = input_0_udp_payload_tready_reg; -assign input_1_udp_payload_tready = input_1_udp_payload_tready_reg; -assign input_2_udp_payload_tready = input_2_udp_payload_tready_reg; -assign input_3_udp_payload_tready = input_3_udp_payload_tready_reg; - -assign output_udp_hdr_valid = output_udp_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_udp_source_port = output_udp_source_port_reg; -assign output_udp_dest_port = output_udp_dest_port_reg; -assign output_udp_length = output_udp_length_reg; -assign output_udp_checksum = output_udp_checksum_reg; - -// mux for start of packet detection -reg selected_input_udp_hdr_valid; -reg [47:0] selected_input_eth_dest_mac; -reg [47:0] selected_input_eth_src_mac; -reg [15:0] selected_input_eth_type; -reg [3:0] selected_input_ip_version; -reg [3:0] selected_input_ip_ihl; -reg [5:0] selected_input_ip_dscp; -reg [1:0] selected_input_ip_ecn; -reg [15:0] selected_input_ip_length; -reg [15:0] selected_input_ip_identification; -reg [2:0] selected_input_ip_flags; -reg [12:0] selected_input_ip_fragment_offset; -reg [7:0] selected_input_ip_ttl; -reg [7:0] selected_input_ip_protocol; -reg [15:0] selected_input_ip_header_checksum; -reg [31:0] selected_input_ip_source_ip; -reg [31:0] selected_input_ip_dest_ip; -reg [15:0] selected_input_udp_source_port; -reg [15:0] selected_input_udp_dest_port; -reg [15:0] selected_input_udp_length; -reg [15:0] selected_input_udp_checksum; -always @* begin - case (select) - 2'd0: begin - selected_input_udp_hdr_valid = input_0_udp_hdr_valid; - selected_input_eth_dest_mac = input_0_eth_dest_mac; - selected_input_eth_src_mac = input_0_eth_src_mac; - selected_input_eth_type = input_0_eth_type; - selected_input_ip_version = input_0_ip_version; - selected_input_ip_ihl = input_0_ip_ihl; - selected_input_ip_dscp = input_0_ip_dscp; - selected_input_ip_ecn = input_0_ip_ecn; - selected_input_ip_length = input_0_ip_length; - selected_input_ip_identification = input_0_ip_identification; - selected_input_ip_flags = input_0_ip_flags; - selected_input_ip_fragment_offset = input_0_ip_fragment_offset; - selected_input_ip_ttl = input_0_ip_ttl; - selected_input_ip_protocol = input_0_ip_protocol; - selected_input_ip_header_checksum = input_0_ip_header_checksum; - selected_input_ip_source_ip = input_0_ip_source_ip; - selected_input_ip_dest_ip = input_0_ip_dest_ip; - selected_input_udp_source_port = input_0_udp_source_port; - selected_input_udp_dest_port = input_0_udp_dest_port; - selected_input_udp_length = input_0_udp_length; - selected_input_udp_checksum = input_0_udp_checksum; - end - 2'd1: begin - selected_input_udp_hdr_valid = input_1_udp_hdr_valid; - selected_input_eth_dest_mac = input_1_eth_dest_mac; - selected_input_eth_src_mac = input_1_eth_src_mac; - selected_input_eth_type = input_1_eth_type; - selected_input_ip_version = input_1_ip_version; - selected_input_ip_ihl = input_1_ip_ihl; - selected_input_ip_dscp = input_1_ip_dscp; - selected_input_ip_ecn = input_1_ip_ecn; - selected_input_ip_length = input_1_ip_length; - selected_input_ip_identification = input_1_ip_identification; - selected_input_ip_flags = input_1_ip_flags; - selected_input_ip_fragment_offset = input_1_ip_fragment_offset; - selected_input_ip_ttl = input_1_ip_ttl; - selected_input_ip_protocol = input_1_ip_protocol; - selected_input_ip_header_checksum = input_1_ip_header_checksum; - selected_input_ip_source_ip = input_1_ip_source_ip; - selected_input_ip_dest_ip = input_1_ip_dest_ip; - selected_input_udp_source_port = input_1_udp_source_port; - selected_input_udp_dest_port = input_1_udp_dest_port; - selected_input_udp_length = input_1_udp_length; - selected_input_udp_checksum = input_1_udp_checksum; - end - 2'd2: begin - selected_input_udp_hdr_valid = input_2_udp_hdr_valid; - selected_input_eth_dest_mac = input_2_eth_dest_mac; - selected_input_eth_src_mac = input_2_eth_src_mac; - selected_input_eth_type = input_2_eth_type; - selected_input_ip_version = input_2_ip_version; - selected_input_ip_ihl = input_2_ip_ihl; - selected_input_ip_dscp = input_2_ip_dscp; - selected_input_ip_ecn = input_2_ip_ecn; - selected_input_ip_length = input_2_ip_length; - selected_input_ip_identification = input_2_ip_identification; - selected_input_ip_flags = input_2_ip_flags; - selected_input_ip_fragment_offset = input_2_ip_fragment_offset; - selected_input_ip_ttl = input_2_ip_ttl; - selected_input_ip_protocol = input_2_ip_protocol; - selected_input_ip_header_checksum = input_2_ip_header_checksum; - selected_input_ip_source_ip = input_2_ip_source_ip; - selected_input_ip_dest_ip = input_2_ip_dest_ip; - selected_input_udp_source_port = input_2_udp_source_port; - selected_input_udp_dest_port = input_2_udp_dest_port; - selected_input_udp_length = input_2_udp_length; - selected_input_udp_checksum = input_2_udp_checksum; - end - 2'd3: begin - selected_input_udp_hdr_valid = input_3_udp_hdr_valid; - selected_input_eth_dest_mac = input_3_eth_dest_mac; - selected_input_eth_src_mac = input_3_eth_src_mac; - selected_input_eth_type = input_3_eth_type; - selected_input_ip_version = input_3_ip_version; - selected_input_ip_ihl = input_3_ip_ihl; - selected_input_ip_dscp = input_3_ip_dscp; - selected_input_ip_ecn = input_3_ip_ecn; - selected_input_ip_length = input_3_ip_length; - selected_input_ip_identification = input_3_ip_identification; - selected_input_ip_flags = input_3_ip_flags; - selected_input_ip_fragment_offset = input_3_ip_fragment_offset; - selected_input_ip_ttl = input_3_ip_ttl; - selected_input_ip_protocol = input_3_ip_protocol; - selected_input_ip_header_checksum = input_3_ip_header_checksum; - selected_input_ip_source_ip = input_3_ip_source_ip; - selected_input_ip_dest_ip = input_3_ip_dest_ip; - selected_input_udp_source_port = input_3_udp_source_port; - selected_input_udp_dest_port = input_3_udp_dest_port; - selected_input_udp_length = input_3_udp_length; - selected_input_udp_checksum = input_3_udp_checksum; - end - default: begin - selected_input_udp_hdr_valid = 1'b0; - selected_input_eth_dest_mac = 48'd0; - selected_input_eth_src_mac = 48'd0; - selected_input_eth_type = 16'd0; - selected_input_ip_version = 4'd0; - selected_input_ip_ihl = 4'd0; - selected_input_ip_dscp = 6'd0; - selected_input_ip_ecn = 2'd0; - selected_input_ip_length = 16'd0; - selected_input_ip_identification = 16'd0; - selected_input_ip_flags = 3'd0; - selected_input_ip_fragment_offset = 13'd0; - selected_input_ip_ttl = 8'd0; - selected_input_ip_protocol = 8'd0; - selected_input_ip_header_checksum = 16'd0; - selected_input_ip_source_ip = 32'd0; - selected_input_ip_dest_ip = 32'd0; - selected_input_udp_source_port = 16'd0; - selected_input_udp_dest_port = 16'd0; - selected_input_udp_length = 16'd0; - selected_input_udp_checksum = 16'd0; - end - endcase -end - -// mux for incoming packet -reg [63:0] current_input_tdata; -reg [7:0] current_input_tkeep; -reg current_input_tvalid; -reg current_input_tready; -reg current_input_tlast; -reg current_input_tuser; -always @* begin - case (select_reg) - 2'd0: begin - current_input_tdata = input_0_udp_payload_tdata; - current_input_tkeep = input_0_udp_payload_tkeep; - current_input_tvalid = input_0_udp_payload_tvalid; - current_input_tready = input_0_udp_payload_tready; - current_input_tlast = input_0_udp_payload_tlast; - current_input_tuser = input_0_udp_payload_tuser; - end - 2'd1: begin - current_input_tdata = input_1_udp_payload_tdata; - current_input_tkeep = input_1_udp_payload_tkeep; - current_input_tvalid = input_1_udp_payload_tvalid; - current_input_tready = input_1_udp_payload_tready; - current_input_tlast = input_1_udp_payload_tlast; - current_input_tuser = input_1_udp_payload_tuser; - end - 2'd2: begin - current_input_tdata = input_2_udp_payload_tdata; - current_input_tkeep = input_2_udp_payload_tkeep; - current_input_tvalid = input_2_udp_payload_tvalid; - current_input_tready = input_2_udp_payload_tready; - current_input_tlast = input_2_udp_payload_tlast; - current_input_tuser = input_2_udp_payload_tuser; - end - 2'd3: begin - current_input_tdata = input_3_udp_payload_tdata; - current_input_tkeep = input_3_udp_payload_tkeep; - current_input_tvalid = input_3_udp_payload_tvalid; - current_input_tready = input_3_udp_payload_tready; - current_input_tlast = input_3_udp_payload_tlast; - current_input_tuser = input_3_udp_payload_tuser; - end - default: begin - current_input_tdata = 64'd0; - current_input_tkeep = 8'd0; - current_input_tvalid = 1'b0; - current_input_tready = 1'b0; - current_input_tlast = 1'b0; - current_input_tuser = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_0_udp_hdr_ready_next = input_0_udp_hdr_ready_reg & ~input_0_udp_hdr_valid; - input_1_udp_hdr_ready_next = input_1_udp_hdr_ready_reg & ~input_1_udp_hdr_valid; - input_2_udp_hdr_ready_next = input_2_udp_hdr_ready_reg & ~input_2_udp_hdr_valid; - input_3_udp_hdr_ready_next = input_3_udp_hdr_ready_reg & ~input_3_udp_hdr_valid; - - input_0_udp_payload_tready_next = 1'b0; - input_1_udp_payload_tready_next = 1'b0; - input_2_udp_payload_tready_next = 1'b0; - input_3_udp_payload_tready_next = 1'b0; - - output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - output_udp_source_port_next = output_udp_source_port_reg; - output_udp_dest_port_next = output_udp_dest_port_reg; - output_udp_length_next = output_udp_length_reg; - output_udp_checksum_next = output_udp_checksum_reg; - - if (current_input_tvalid & current_input_tready) begin - // end of frame detection - if (current_input_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & ~output_udp_hdr_valid & selected_input_udp_hdr_valid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - case (select_next) - 2'd0: input_0_udp_hdr_ready_next = 1'b1; - 2'd1: input_1_udp_hdr_ready_next = 1'b1; - 2'd2: input_2_udp_hdr_ready_next = 1'b1; - 2'd3: input_3_udp_hdr_ready_next = 1'b1; - endcase - - output_udp_hdr_valid_next = 1'b1; - output_eth_dest_mac_next = selected_input_eth_dest_mac; - output_eth_src_mac_next = selected_input_eth_src_mac; - output_eth_type_next = selected_input_eth_type; - output_ip_version_next = selected_input_ip_version; - output_ip_ihl_next = selected_input_ip_ihl; - output_ip_dscp_next = selected_input_ip_dscp; - output_ip_ecn_next = selected_input_ip_ecn; - output_ip_length_next = selected_input_ip_length; - output_ip_identification_next = selected_input_ip_identification; - output_ip_flags_next = selected_input_ip_flags; - output_ip_fragment_offset_next = selected_input_ip_fragment_offset; - output_ip_ttl_next = selected_input_ip_ttl; - output_ip_protocol_next = selected_input_ip_protocol; - output_ip_header_checksum_next = selected_input_ip_header_checksum; - output_ip_source_ip_next = selected_input_ip_source_ip; - output_ip_dest_ip_next = selected_input_ip_dest_ip; - output_udp_source_port_next = selected_input_udp_source_port; - output_udp_dest_port_next = selected_input_udp_dest_port; - output_udp_length_next = selected_input_udp_length; - output_udp_checksum_next = selected_input_udp_checksum; - end - - // generate ready signal on selected port - case (select_next) - 2'd0: input_0_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - 2'd1: input_1_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - 2'd2: input_2_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - 2'd3: input_3_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - endcase - - // pass through selected packet data - output_udp_payload_tdata_int = current_input_tdata; - output_udp_payload_tkeep_int = current_input_tkeep; - output_udp_payload_tvalid_int = current_input_tvalid & current_input_tready & frame_reg; - output_udp_payload_tlast_int = current_input_tlast; - output_udp_payload_tuser_int = current_input_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_0_udp_hdr_ready_reg <= 1'b0; - input_1_udp_hdr_ready_reg <= 1'b0; - input_2_udp_hdr_ready_reg <= 1'b0; - input_3_udp_hdr_ready_reg <= 1'b0; - input_0_udp_payload_tready_reg <= 1'b0; - input_1_udp_payload_tready_reg <= 1'b0; - input_2_udp_payload_tready_reg <= 1'b0; - input_3_udp_payload_tready_reg <= 1'b0; - output_udp_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_0_udp_hdr_ready_reg <= input_0_udp_hdr_ready_next; - input_1_udp_hdr_ready_reg <= input_1_udp_hdr_ready_next; - input_2_udp_hdr_ready_reg <= input_2_udp_hdr_ready_next; - input_3_udp_hdr_ready_reg <= input_3_udp_hdr_ready_next; - input_0_udp_payload_tready_reg <= input_0_udp_payload_tready_next; - input_1_udp_payload_tready_reg <= input_1_udp_payload_tready_next; - input_2_udp_payload_tready_reg <= input_2_udp_payload_tready_next; - input_3_udp_payload_tready_reg <= input_3_udp_payload_tready_next; - output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; -end - -// output datapath logic -reg [63:0] output_udp_payload_tdata_reg = 64'd0; -reg [7:0] output_udp_payload_tkeep_reg = 8'd0; -reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; -reg output_udp_payload_tlast_reg = 1'b0; -reg output_udp_payload_tuser_reg = 1'b0; - -reg [63:0] temp_udp_payload_tdata_reg = 64'd0; -reg [7:0] temp_udp_payload_tkeep_reg = 8'd0; -reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; -reg temp_udp_payload_tlast_reg = 1'b0; -reg temp_udp_payload_tuser_reg = 1'b0; - -// datapath control -reg store_udp_payload_int_to_output; -reg store_udp_payload_int_to_temp; -reg store_udp_payload_temp_to_output; - -assign output_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; -assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; -assign output_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_udp_payload_tuser = output_udp_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - - store_udp_payload_int_to_output = 1'b0; - store_udp_payload_int_to_temp = 1'b0; - store_udp_payload_temp_to_output = 1'b0; - - if (output_udp_payload_tready_int_reg) begin - // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_temp = 1'b1; - end - end else if (output_udp_payload_tready) begin - // input is not ready, but output is ready - output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = 1'b0; - store_udp_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_udp_payload_tvalid_reg <= 1'b0; - output_udp_payload_tready_int_reg <= 1'b0; - temp_udp_payload_tvalid_reg <= 1'b0; - end else begin - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; - output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; - temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; - end - - // datapath - if (store_udp_payload_int_to_output) begin - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else if (store_udp_payload_temp_to_output) begin - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - end - - if (store_udp_payload_int_to_temp) begin - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end -end - -endmodule diff --git a/tb/test_udp_mux_4.py b/tb/test_udp_mux_4.py index 848f62193..1399c50af 100755 --- a/tb/test_udp_mux_4.py +++ b/tb/test_udp_mux_4.py @@ -28,8 +28,8 @@ import os import udp_ep -module = 'udp_mux_4' -testbench = 'test_%s' % module +module = 'udp_mux' +testbench = 'test_%s_4' % module srcs = [] @@ -42,337 +42,204 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_udp_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_ip_version = Signal(intbv(0)[4:]) - input_0_ip_ihl = Signal(intbv(0)[4:]) - input_0_ip_dscp = Signal(intbv(0)[6:]) - input_0_ip_ecn = Signal(intbv(0)[2:]) - input_0_ip_length = Signal(intbv(0)[16:]) - input_0_ip_identification = Signal(intbv(0)[16:]) - input_0_ip_flags = Signal(intbv(0)[3:]) - input_0_ip_fragment_offset = Signal(intbv(0)[13:]) - input_0_ip_ttl = Signal(intbv(0)[8:]) - input_0_ip_protocol = Signal(intbv(0)[8:]) - input_0_ip_header_checksum = Signal(intbv(0)[16:]) - input_0_ip_source_ip = Signal(intbv(0)[32:]) - input_0_ip_dest_ip = Signal(intbv(0)[32:]) - input_0_udp_source_port = Signal(intbv(0)[16:]) - input_0_udp_dest_port = Signal(intbv(0)[16:]) - input_0_udp_length = Signal(intbv(0)[16:]) - input_0_udp_checksum = Signal(intbv(0)[16:]) - input_0_udp_payload_tdata = Signal(intbv(0)[8:]) - input_0_udp_payload_tvalid = Signal(bool(0)) - input_0_udp_payload_tlast = Signal(bool(0)) - input_0_udp_payload_tuser = Signal(bool(0)) - input_1_udp_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_ip_version = Signal(intbv(0)[4:]) - input_1_ip_ihl = Signal(intbv(0)[4:]) - input_1_ip_dscp = Signal(intbv(0)[6:]) - input_1_ip_ecn = Signal(intbv(0)[2:]) - input_1_ip_length = Signal(intbv(0)[16:]) - input_1_ip_identification = Signal(intbv(0)[16:]) - input_1_ip_flags = Signal(intbv(0)[3:]) - input_1_ip_fragment_offset = Signal(intbv(0)[13:]) - input_1_ip_ttl = Signal(intbv(0)[8:]) - input_1_ip_protocol = Signal(intbv(0)[8:]) - input_1_ip_header_checksum = Signal(intbv(0)[16:]) - input_1_ip_source_ip = Signal(intbv(0)[32:]) - input_1_ip_dest_ip = Signal(intbv(0)[32:]) - input_1_udp_source_port = Signal(intbv(0)[16:]) - input_1_udp_dest_port = Signal(intbv(0)[16:]) - input_1_udp_length = Signal(intbv(0)[16:]) - input_1_udp_checksum = Signal(intbv(0)[16:]) - input_1_udp_payload_tdata = Signal(intbv(0)[8:]) - input_1_udp_payload_tvalid = Signal(bool(0)) - input_1_udp_payload_tlast = Signal(bool(0)) - input_1_udp_payload_tuser = Signal(bool(0)) - input_2_udp_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_ip_version = Signal(intbv(0)[4:]) - input_2_ip_ihl = Signal(intbv(0)[4:]) - input_2_ip_dscp = Signal(intbv(0)[6:]) - input_2_ip_ecn = Signal(intbv(0)[2:]) - input_2_ip_length = Signal(intbv(0)[16:]) - input_2_ip_identification = Signal(intbv(0)[16:]) - input_2_ip_flags = Signal(intbv(0)[3:]) - input_2_ip_fragment_offset = Signal(intbv(0)[13:]) - input_2_ip_ttl = Signal(intbv(0)[8:]) - input_2_ip_protocol = Signal(intbv(0)[8:]) - input_2_ip_header_checksum = Signal(intbv(0)[16:]) - input_2_ip_source_ip = Signal(intbv(0)[32:]) - input_2_ip_dest_ip = Signal(intbv(0)[32:]) - input_2_udp_source_port = Signal(intbv(0)[16:]) - input_2_udp_dest_port = Signal(intbv(0)[16:]) - input_2_udp_length = Signal(intbv(0)[16:]) - input_2_udp_checksum = Signal(intbv(0)[16:]) - input_2_udp_payload_tdata = Signal(intbv(0)[8:]) - input_2_udp_payload_tvalid = Signal(bool(0)) - input_2_udp_payload_tlast = Signal(bool(0)) - input_2_udp_payload_tuser = Signal(bool(0)) - input_3_udp_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_ip_version = Signal(intbv(0)[4:]) - input_3_ip_ihl = Signal(intbv(0)[4:]) - input_3_ip_dscp = Signal(intbv(0)[6:]) - input_3_ip_ecn = Signal(intbv(0)[2:]) - input_3_ip_length = Signal(intbv(0)[16:]) - input_3_ip_identification = Signal(intbv(0)[16:]) - input_3_ip_flags = Signal(intbv(0)[3:]) - input_3_ip_fragment_offset = Signal(intbv(0)[13:]) - input_3_ip_ttl = Signal(intbv(0)[8:]) - input_3_ip_protocol = Signal(intbv(0)[8:]) - input_3_ip_header_checksum = Signal(intbv(0)[16:]) - input_3_ip_source_ip = Signal(intbv(0)[32:]) - input_3_ip_dest_ip = Signal(intbv(0)[32:]) - input_3_udp_source_port = Signal(intbv(0)[16:]) - input_3_udp_dest_port = Signal(intbv(0)[16:]) - input_3_udp_length = Signal(intbv(0)[16:]) - input_3_udp_checksum = Signal(intbv(0)[16:]) - input_3_udp_payload_tdata = Signal(intbv(0)[8:]) - input_3_udp_payload_tvalid = Signal(bool(0)) - input_3_udp_payload_tlast = Signal(bool(0)) - input_3_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_version_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_ihl_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_dscp_list = [Signal(intbv(0)[6:]) for i in range(S_COUNT)] + s_ip_ecn_list = [Signal(intbv(0)[2:]) for i in range(S_COUNT)] + s_ip_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_identification_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_flags_list = [Signal(intbv(0)[3:]) for i in range(S_COUNT)] + s_ip_fragment_offset_list = [Signal(intbv(0)[13:]) for i in range(S_COUNT)] + s_ip_ttl_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_protocol_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_header_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_source_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_dest_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_udp_source_port_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_dest_port_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_udp_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_udp_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_udp_payload_tready = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) + s_udp_hdr_valid = ConcatSignal(*reversed(s_udp_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_ip_version = ConcatSignal(*reversed(s_ip_version_list)) + s_ip_ihl = ConcatSignal(*reversed(s_ip_ihl_list)) + s_ip_dscp = ConcatSignal(*reversed(s_ip_dscp_list)) + s_ip_ecn = ConcatSignal(*reversed(s_ip_ecn_list)) + s_ip_length = ConcatSignal(*reversed(s_ip_length_list)) + s_ip_identification = ConcatSignal(*reversed(s_ip_identification_list)) + s_ip_flags = ConcatSignal(*reversed(s_ip_flags_list)) + s_ip_fragment_offset = ConcatSignal(*reversed(s_ip_fragment_offset_list)) + s_ip_ttl = ConcatSignal(*reversed(s_ip_ttl_list)) + s_ip_protocol = ConcatSignal(*reversed(s_ip_protocol_list)) + s_ip_header_checksum = ConcatSignal(*reversed(s_ip_header_checksum_list)) + s_ip_source_ip = ConcatSignal(*reversed(s_ip_source_ip_list)) + s_ip_dest_ip = ConcatSignal(*reversed(s_ip_dest_ip_list)) + s_udp_source_port = ConcatSignal(*reversed(s_udp_source_port_list)) + s_udp_dest_port = ConcatSignal(*reversed(s_udp_dest_port_list)) + s_udp_length = ConcatSignal(*reversed(s_udp_length_list)) + s_udp_checksum = ConcatSignal(*reversed(s_udp_checksum_list)) + s_udp_payload_axis_tdata = ConcatSignal(*reversed(s_udp_payload_axis_tdata_list)) + s_udp_payload_axis_tkeep = ConcatSignal(*reversed(s_udp_payload_axis_tkeep_list)) + s_udp_payload_axis_tvalid = ConcatSignal(*reversed(s_udp_payload_axis_tvalid_list)) + s_udp_payload_axis_tlast = ConcatSignal(*reversed(s_udp_payload_axis_tlast_list)) + s_udp_payload_axis_tid = ConcatSignal(*reversed(s_udp_payload_axis_tid_list)) + s_udp_payload_axis_tdest = ConcatSignal(*reversed(s_udp_payload_axis_tdest_list)) + s_udp_payload_axis_tuser = ConcatSignal(*reversed(s_udp_payload_axis_tuser_list)) + + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_0_udp_hdr_ready = Signal(bool(0)) - input_0_udp_payload_tready = Signal(bool(0)) - input_1_udp_hdr_ready = Signal(bool(0)) - input_1_udp_payload_tready = Signal(bool(0)) - input_2_udp_hdr_ready = Signal(bool(0)) - input_2_udp_payload_tready = Signal(bool(0)) - input_3_udp_hdr_ready = Signal(bool(0)) - input_3_udp_payload_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_udp_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_udp_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_ready_list = [s_udp_hdr_ready(i) for i in range(S_COUNT)] + s_udp_payload_axis_tready_list = [s_udp_payload_axis_tready(i) for i in range(S_COUNT)] + + m_udp_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_udp_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_udp_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_udp_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = udp_ep.UDPFrameSource() + for k in range(S_COUNT): + s = udp_ep.UDPFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - udp_hdr_ready=input_0_udp_hdr_ready, - udp_hdr_valid=input_0_udp_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - eth_type=input_0_eth_type, - ip_version=input_0_ip_version, - ip_ihl=input_0_ip_ihl, - ip_dscp=input_0_ip_dscp, - ip_ecn=input_0_ip_ecn, - ip_length=input_0_ip_length, - ip_identification=input_0_ip_identification, - ip_flags=input_0_ip_flags, - ip_fragment_offset=input_0_ip_fragment_offset, - ip_ttl=input_0_ip_ttl, - ip_protocol=input_0_ip_protocol, - ip_header_checksum=input_0_ip_header_checksum, - ip_source_ip=input_0_ip_source_ip, - ip_dest_ip=input_0_ip_dest_ip, - udp_source_port=input_0_udp_source_port, - udp_dest_port=input_0_udp_dest_port, - udp_length=input_0_udp_length, - udp_checksum=input_0_udp_checksum, - udp_payload_tdata=input_0_udp_payload_tdata, - udp_payload_tvalid=input_0_udp_payload_tvalid, - udp_payload_tready=input_0_udp_payload_tready, - udp_payload_tlast=input_0_udp_payload_tlast, - udp_payload_tuser=input_0_udp_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = udp_ep.UDPFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - udp_hdr_ready=input_1_udp_hdr_ready, - udp_hdr_valid=input_1_udp_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - eth_type=input_1_eth_type, - ip_version=input_1_ip_version, - ip_ihl=input_1_ip_ihl, - ip_dscp=input_1_ip_dscp, - ip_ecn=input_1_ip_ecn, - ip_length=input_1_ip_length, - ip_identification=input_1_ip_identification, - ip_flags=input_1_ip_flags, - ip_fragment_offset=input_1_ip_fragment_offset, - ip_ttl=input_1_ip_ttl, - ip_protocol=input_1_ip_protocol, - ip_header_checksum=input_1_ip_header_checksum, - ip_source_ip=input_1_ip_source_ip, - ip_dest_ip=input_1_ip_dest_ip, - udp_source_port=input_1_udp_source_port, - udp_dest_port=input_1_udp_dest_port, - udp_length=input_1_udp_length, - udp_checksum=input_1_udp_checksum, - udp_payload_tdata=input_1_udp_payload_tdata, - udp_payload_tvalid=input_1_udp_payload_tvalid, - udp_payload_tready=input_1_udp_payload_tready, - udp_payload_tlast=input_1_udp_payload_tlast, - udp_payload_tuser=input_1_udp_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = udp_ep.UDPFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - udp_hdr_ready=input_2_udp_hdr_ready, - udp_hdr_valid=input_2_udp_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - ip_version=input_2_ip_version, - ip_ihl=input_2_ip_ihl, - ip_dscp=input_2_ip_dscp, - ip_ecn=input_2_ip_ecn, - ip_length=input_2_ip_length, - ip_identification=input_2_ip_identification, - ip_flags=input_2_ip_flags, - ip_fragment_offset=input_2_ip_fragment_offset, - ip_ttl=input_2_ip_ttl, - ip_protocol=input_2_ip_protocol, - ip_header_checksum=input_2_ip_header_checksum, - ip_source_ip=input_2_ip_source_ip, - ip_dest_ip=input_2_ip_dest_ip, - udp_source_port=input_2_udp_source_port, - udp_dest_port=input_2_udp_dest_port, - udp_length=input_2_udp_length, - udp_checksum=input_2_udp_checksum, - udp_payload_tdata=input_2_udp_payload_tdata, - udp_payload_tvalid=input_2_udp_payload_tvalid, - udp_payload_tready=input_2_udp_payload_tready, - udp_payload_tlast=input_2_udp_payload_tlast, - udp_payload_tuser=input_2_udp_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = udp_ep.UDPFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - udp_hdr_ready=input_3_udp_hdr_ready, - udp_hdr_valid=input_3_udp_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - ip_version=input_3_ip_version, - ip_ihl=input_3_ip_ihl, - ip_dscp=input_3_ip_dscp, - ip_ecn=input_3_ip_ecn, - ip_length=input_3_ip_length, - ip_identification=input_3_ip_identification, - ip_flags=input_3_ip_flags, - ip_fragment_offset=input_3_ip_fragment_offset, - ip_ttl=input_3_ip_ttl, - ip_protocol=input_3_ip_protocol, - ip_header_checksum=input_3_ip_header_checksum, - ip_source_ip=input_3_ip_source_ip, - ip_dest_ip=input_3_ip_dest_ip, - udp_source_port=input_3_udp_source_port, - udp_dest_port=input_3_udp_dest_port, - udp_length=input_3_udp_length, - udp_checksum=input_3_udp_checksum, - udp_payload_tdata=input_3_udp_payload_tdata, - udp_payload_tvalid=input_3_udp_payload_tvalid, - udp_payload_tready=input_3_udp_payload_tready, - udp_payload_tlast=input_3_udp_payload_tlast, - udp_payload_tuser=input_3_udp_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + udp_hdr_ready=s_udp_hdr_ready_list[k], + udp_hdr_valid=s_udp_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + ip_version=s_ip_version_list[k], + ip_ihl=s_ip_ihl_list[k], + ip_dscp=s_ip_dscp_list[k], + ip_ecn=s_ip_ecn_list[k], + ip_length=s_ip_length_list[k], + ip_identification=s_ip_identification_list[k], + ip_flags=s_ip_flags_list[k], + ip_fragment_offset=s_ip_fragment_offset_list[k], + ip_ttl=s_ip_ttl_list[k], + ip_protocol=s_ip_protocol_list[k], + ip_header_checksum=s_ip_header_checksum_list[k], + ip_source_ip=s_ip_source_ip_list[k], + ip_dest_ip=s_ip_dest_ip_list[k], + udp_source_port=s_udp_source_port_list[k], + udp_dest_port=s_udp_dest_port_list[k], + udp_length=s_udp_length_list[k], + udp_checksum=s_udp_checksum_list[k], + udp_payload_tdata=s_udp_payload_axis_tdata_list[k], + udp_payload_tkeep=s_udp_payload_axis_tkeep_list[k], + udp_payload_tvalid=s_udp_payload_axis_tvalid_list[k], + udp_payload_tready=s_udp_payload_axis_tready_list[k], + udp_payload_tlast=s_udp_payload_axis_tlast_list[k], + udp_payload_tuser=s_udp_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = udp_ep.UDPFrameSink() sink_logic = sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tkeep=m_udp_payload_axis_tkeep, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -387,142 +254,67 @@ def bench(): rst=rst, current_test=current_test, - input_0_udp_hdr_valid=input_0_udp_hdr_valid, - input_0_udp_hdr_ready=input_0_udp_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_ip_version=input_0_ip_version, - input_0_ip_ihl=input_0_ip_ihl, - input_0_ip_dscp=input_0_ip_dscp, - input_0_ip_ecn=input_0_ip_ecn, - input_0_ip_length=input_0_ip_length, - input_0_ip_identification=input_0_ip_identification, - input_0_ip_flags=input_0_ip_flags, - input_0_ip_fragment_offset=input_0_ip_fragment_offset, - input_0_ip_ttl=input_0_ip_ttl, - input_0_ip_protocol=input_0_ip_protocol, - input_0_ip_header_checksum=input_0_ip_header_checksum, - input_0_ip_source_ip=input_0_ip_source_ip, - input_0_ip_dest_ip=input_0_ip_dest_ip, - input_0_udp_source_port=input_0_udp_source_port, - input_0_udp_dest_port=input_0_udp_dest_port, - input_0_udp_length=input_0_udp_length, - input_0_udp_checksum=input_0_udp_checksum, - input_0_udp_payload_tdata=input_0_udp_payload_tdata, - input_0_udp_payload_tvalid=input_0_udp_payload_tvalid, - input_0_udp_payload_tready=input_0_udp_payload_tready, - input_0_udp_payload_tlast=input_0_udp_payload_tlast, - input_0_udp_payload_tuser=input_0_udp_payload_tuser, - input_1_udp_hdr_valid=input_1_udp_hdr_valid, - input_1_udp_hdr_ready=input_1_udp_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_ip_version=input_1_ip_version, - input_1_ip_ihl=input_1_ip_ihl, - input_1_ip_dscp=input_1_ip_dscp, - input_1_ip_ecn=input_1_ip_ecn, - input_1_ip_length=input_1_ip_length, - input_1_ip_identification=input_1_ip_identification, - input_1_ip_flags=input_1_ip_flags, - input_1_ip_fragment_offset=input_1_ip_fragment_offset, - input_1_ip_ttl=input_1_ip_ttl, - input_1_ip_protocol=input_1_ip_protocol, - input_1_ip_header_checksum=input_1_ip_header_checksum, - input_1_ip_source_ip=input_1_ip_source_ip, - input_1_ip_dest_ip=input_1_ip_dest_ip, - input_1_udp_source_port=input_1_udp_source_port, - input_1_udp_dest_port=input_1_udp_dest_port, - input_1_udp_length=input_1_udp_length, - input_1_udp_checksum=input_1_udp_checksum, - input_1_udp_payload_tdata=input_1_udp_payload_tdata, - input_1_udp_payload_tvalid=input_1_udp_payload_tvalid, - input_1_udp_payload_tready=input_1_udp_payload_tready, - input_1_udp_payload_tlast=input_1_udp_payload_tlast, - input_1_udp_payload_tuser=input_1_udp_payload_tuser, - input_2_udp_hdr_valid=input_2_udp_hdr_valid, - input_2_udp_hdr_ready=input_2_udp_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_ip_version=input_2_ip_version, - input_2_ip_ihl=input_2_ip_ihl, - input_2_ip_dscp=input_2_ip_dscp, - input_2_ip_ecn=input_2_ip_ecn, - input_2_ip_length=input_2_ip_length, - input_2_ip_identification=input_2_ip_identification, - input_2_ip_flags=input_2_ip_flags, - input_2_ip_fragment_offset=input_2_ip_fragment_offset, - input_2_ip_ttl=input_2_ip_ttl, - input_2_ip_protocol=input_2_ip_protocol, - input_2_ip_header_checksum=input_2_ip_header_checksum, - input_2_ip_source_ip=input_2_ip_source_ip, - input_2_ip_dest_ip=input_2_ip_dest_ip, - input_2_udp_source_port=input_2_udp_source_port, - input_2_udp_dest_port=input_2_udp_dest_port, - input_2_udp_length=input_2_udp_length, - input_2_udp_checksum=input_2_udp_checksum, - input_2_udp_payload_tdata=input_2_udp_payload_tdata, - input_2_udp_payload_tvalid=input_2_udp_payload_tvalid, - input_2_udp_payload_tready=input_2_udp_payload_tready, - input_2_udp_payload_tlast=input_2_udp_payload_tlast, - input_2_udp_payload_tuser=input_2_udp_payload_tuser, - input_3_udp_hdr_valid=input_3_udp_hdr_valid, - input_3_udp_hdr_ready=input_3_udp_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_ip_version=input_3_ip_version, - input_3_ip_ihl=input_3_ip_ihl, - input_3_ip_dscp=input_3_ip_dscp, - input_3_ip_ecn=input_3_ip_ecn, - input_3_ip_length=input_3_ip_length, - input_3_ip_identification=input_3_ip_identification, - input_3_ip_flags=input_3_ip_flags, - input_3_ip_fragment_offset=input_3_ip_fragment_offset, - input_3_ip_ttl=input_3_ip_ttl, - input_3_ip_protocol=input_3_ip_protocol, - input_3_ip_header_checksum=input_3_ip_header_checksum, - input_3_ip_source_ip=input_3_ip_source_ip, - input_3_ip_dest_ip=input_3_ip_dest_ip, - input_3_udp_source_port=input_3_udp_source_port, - input_3_udp_dest_port=input_3_udp_dest_port, - input_3_udp_length=input_3_udp_length, - input_3_udp_checksum=input_3_udp_checksum, - input_3_udp_payload_tdata=input_3_udp_payload_tdata, - input_3_udp_payload_tvalid=input_3_udp_payload_tvalid, - input_3_udp_payload_tready=input_3_udp_payload_tready, - input_3_udp_payload_tlast=input_3_udp_payload_tlast, - input_3_udp_payload_tuser=input_3_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep=s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tid=s_udp_payload_axis_tid, + s_udp_payload_axis_tdest=s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep=m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tid=m_udp_payload_axis_tid, + m_udp_payload_axis_tdest=m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, enable=enable, select=select @@ -576,7 +368,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -615,7 +407,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -677,8 +469,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -745,12 +537,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + while s_udp_payload_axis_tvalid: yield clk.posedge select.next = 2 @@ -819,23 +611,23 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_udp_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge select.next = 2 @@ -904,12 +696,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + while s_udp_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_udp_mux_4.v b/tb/test_udp_mux_4.v index ed2fee733..51af5c014 100644 --- a/tb/test_udp_mux_4.v +++ b/tb/test_udp_mux_4.v @@ -27,157 +27,94 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for udp_mux_4 + * Testbench for udp_mux */ module test_udp_mux_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_udp_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [3:0] input_0_ip_version = 0; -reg [3:0] input_0_ip_ihl = 0; -reg [5:0] input_0_ip_dscp = 0; -reg [1:0] input_0_ip_ecn = 0; -reg [15:0] input_0_ip_length = 0; -reg [15:0] input_0_ip_identification = 0; -reg [2:0] input_0_ip_flags = 0; -reg [12:0] input_0_ip_fragment_offset = 0; -reg [7:0] input_0_ip_ttl = 0; -reg [7:0] input_0_ip_protocol = 0; -reg [15:0] input_0_ip_header_checksum = 0; -reg [31:0] input_0_ip_source_ip = 0; -reg [31:0] input_0_ip_dest_ip = 0; -reg [15:0] input_0_udp_source_port = 0; -reg [15:0] input_0_udp_dest_port = 0; -reg [15:0] input_0_udp_length = 0; -reg [15:0] input_0_udp_checksum = 0; -reg [7:0] input_0_udp_payload_tdata = 0; -reg input_0_udp_payload_tvalid = 0; -reg input_0_udp_payload_tlast = 0; -reg input_0_udp_payload_tuser = 0; -reg input_1_udp_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [3:0] input_1_ip_version = 0; -reg [3:0] input_1_ip_ihl = 0; -reg [5:0] input_1_ip_dscp = 0; -reg [1:0] input_1_ip_ecn = 0; -reg [15:0] input_1_ip_length = 0; -reg [15:0] input_1_ip_identification = 0; -reg [2:0] input_1_ip_flags = 0; -reg [12:0] input_1_ip_fragment_offset = 0; -reg [7:0] input_1_ip_ttl = 0; -reg [7:0] input_1_ip_protocol = 0; -reg [15:0] input_1_ip_header_checksum = 0; -reg [31:0] input_1_ip_source_ip = 0; -reg [31:0] input_1_ip_dest_ip = 0; -reg [15:0] input_1_udp_source_port = 0; -reg [15:0] input_1_udp_dest_port = 0; -reg [15:0] input_1_udp_length = 0; -reg [15:0] input_1_udp_checksum = 0; -reg [7:0] input_1_udp_payload_tdata = 0; -reg input_1_udp_payload_tvalid = 0; -reg input_1_udp_payload_tlast = 0; -reg input_1_udp_payload_tuser = 0; -reg input_2_udp_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [3:0] input_2_ip_version = 0; -reg [3:0] input_2_ip_ihl = 0; -reg [5:0] input_2_ip_dscp = 0; -reg [1:0] input_2_ip_ecn = 0; -reg [15:0] input_2_ip_length = 0; -reg [15:0] input_2_ip_identification = 0; -reg [2:0] input_2_ip_flags = 0; -reg [12:0] input_2_ip_fragment_offset = 0; -reg [7:0] input_2_ip_ttl = 0; -reg [7:0] input_2_ip_protocol = 0; -reg [15:0] input_2_ip_header_checksum = 0; -reg [31:0] input_2_ip_source_ip = 0; -reg [31:0] input_2_ip_dest_ip = 0; -reg [15:0] input_2_udp_source_port = 0; -reg [15:0] input_2_udp_dest_port = 0; -reg [15:0] input_2_udp_length = 0; -reg [15:0] input_2_udp_checksum = 0; -reg [7:0] input_2_udp_payload_tdata = 0; -reg input_2_udp_payload_tvalid = 0; -reg input_2_udp_payload_tlast = 0; -reg input_2_udp_payload_tuser = 0; -reg input_3_udp_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [3:0] input_3_ip_version = 0; -reg [3:0] input_3_ip_ihl = 0; -reg [5:0] input_3_ip_dscp = 0; -reg [1:0] input_3_ip_ecn = 0; -reg [15:0] input_3_ip_length = 0; -reg [15:0] input_3_ip_identification = 0; -reg [2:0] input_3_ip_flags = 0; -reg [12:0] input_3_ip_fragment_offset = 0; -reg [7:0] input_3_ip_ttl = 0; -reg [7:0] input_3_ip_protocol = 0; -reg [15:0] input_3_ip_header_checksum = 0; -reg [31:0] input_3_ip_source_ip = 0; -reg [31:0] input_3_ip_dest_ip = 0; -reg [15:0] input_3_udp_source_port = 0; -reg [15:0] input_3_udp_dest_port = 0; -reg [15:0] input_3_udp_length = 0; -reg [15:0] input_3_udp_checksum = 0; -reg [7:0] input_3_udp_payload_tdata = 0; -reg input_3_udp_payload_tvalid = 0; -reg input_3_udp_payload_tlast = 0; -reg input_3_udp_payload_tuser = 0; +reg [S_COUNT-1:0] s_udp_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*4-1:0] s_ip_version = 0; +reg [S_COUNT*4-1:0] s_ip_ihl = 0; +reg [S_COUNT*6-1:0] s_ip_dscp = 0; +reg [S_COUNT*2-1:0] s_ip_ecn = 0; +reg [S_COUNT*16-1:0] s_ip_length = 0; +reg [S_COUNT*16-1:0] s_ip_identification = 0; +reg [S_COUNT*3-1:0] s_ip_flags = 0; +reg [S_COUNT*13-1:0] s_ip_fragment_offset = 0; +reg [S_COUNT*8-1:0] s_ip_ttl = 0; +reg [S_COUNT*8-1:0] s_ip_protocol = 0; +reg [S_COUNT*16-1:0] s_ip_header_checksum = 0; +reg [S_COUNT*32-1:0] s_ip_source_ip = 0; +reg [S_COUNT*32-1:0] s_ip_dest_ip = 0; +reg [S_COUNT*16-1:0] s_udp_source_port = 0; +reg [S_COUNT*16-1:0] s_udp_dest_port = 0; +reg [S_COUNT*16-1:0] s_udp_length = 0; +reg [S_COUNT*16-1:0] s_udp_checksum = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_udp_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_udp_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_udp_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_udp_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_udp_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_udp_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_udp_payload_axis_tuser = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; reg enable = 0; reg [1:0] select = 0; // Outputs -wire input_0_udp_payload_tready; -wire input_0_udp_hdr_ready; -wire input_1_udp_payload_tready; -wire input_1_udp_hdr_ready; -wire input_2_udp_payload_tready; -wire input_2_udp_hdr_ready; -wire input_3_udp_payload_tready; -wire input_3_udp_hdr_ready; +wire [S_COUNT-1:0] s_udp_hdr_ready; +wire [S_COUNT-1:0] s_udp_payload_axis_tready; -wire output_udp_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [7:0] output_udp_payload_tdata; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire m_udp_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [DATA_WIDTH-1:0] m_udp_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_udp_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_udp_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_udp_payload_axis_tuser; initial begin // myhdl integration @@ -185,145 +122,70 @@ initial begin clk, rst, current_test, - input_0_udp_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_ip_version, - input_0_ip_ihl, - input_0_ip_dscp, - input_0_ip_ecn, - input_0_ip_length, - input_0_ip_identification, - input_0_ip_flags, - input_0_ip_fragment_offset, - input_0_ip_ttl, - input_0_ip_protocol, - input_0_ip_header_checksum, - input_0_ip_source_ip, - input_0_ip_dest_ip, - input_0_udp_source_port, - input_0_udp_dest_port, - input_0_udp_length, - input_0_udp_checksum, - input_0_udp_payload_tdata, - input_0_udp_payload_tvalid, - input_0_udp_payload_tlast, - input_0_udp_payload_tuser, - input_1_udp_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_ip_version, - input_1_ip_ihl, - input_1_ip_dscp, - input_1_ip_ecn, - input_1_ip_length, - input_1_ip_identification, - input_1_ip_flags, - input_1_ip_fragment_offset, - input_1_ip_ttl, - input_1_ip_protocol, - input_1_ip_header_checksum, - input_1_ip_source_ip, - input_1_ip_dest_ip, - input_1_udp_source_port, - input_1_udp_dest_port, - input_1_udp_length, - input_1_udp_checksum, - input_1_udp_payload_tdata, - input_1_udp_payload_tvalid, - input_1_udp_payload_tlast, - input_1_udp_payload_tuser, - input_2_udp_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_ip_version, - input_2_ip_ihl, - input_2_ip_dscp, - input_2_ip_ecn, - input_2_ip_length, - input_2_ip_identification, - input_2_ip_flags, - input_2_ip_fragment_offset, - input_2_ip_ttl, - input_2_ip_protocol, - input_2_ip_header_checksum, - input_2_ip_source_ip, - input_2_ip_dest_ip, - input_2_udp_source_port, - input_2_udp_dest_port, - input_2_udp_length, - input_2_udp_checksum, - input_2_udp_payload_tdata, - input_2_udp_payload_tvalid, - input_2_udp_payload_tlast, - input_2_udp_payload_tuser, - input_3_udp_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_ip_version, - input_3_ip_ihl, - input_3_ip_dscp, - input_3_ip_ecn, - input_3_ip_length, - input_3_ip_identification, - input_3_ip_flags, - input_3_ip_fragment_offset, - input_3_ip_ttl, - input_3_ip_protocol, - input_3_ip_header_checksum, - input_3_ip_source_ip, - input_3_ip_dest_ip, - input_3_udp_source_port, - input_3_udp_dest_port, - input_3_udp_length, - input_3_udp_checksum, - input_3_udp_payload_tdata, - input_3_udp_payload_tvalid, - input_3_udp_payload_tlast, - input_3_udp_payload_tuser, - output_udp_hdr_ready, - output_udp_payload_tready, + s_udp_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tid, + s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser, + m_udp_hdr_ready, + m_udp_payload_axis_tready, enable, select ); $to_myhdl( - input_0_udp_hdr_ready, - input_0_udp_payload_tready, - input_1_udp_hdr_ready, - input_1_udp_payload_tready, - input_2_udp_hdr_ready, - input_2_udp_payload_tready, - input_3_udp_hdr_ready, - input_3_udp_payload_tready, - output_udp_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_udp_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tid, + m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser ); // dump file @@ -331,147 +193,83 @@ initial begin $dumpvars(0, test_udp_mux_4); end -udp_mux_4 +udp_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), - // UDP frame inputs - .input_0_udp_hdr_valid(input_0_udp_hdr_valid), - .input_0_udp_hdr_ready(input_0_udp_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_udp_source_port(input_0_udp_source_port), - .input_0_udp_dest_port(input_0_udp_dest_port), - .input_0_udp_length(input_0_udp_length), - .input_0_udp_checksum(input_0_udp_checksum), - .input_0_udp_payload_tdata(input_0_udp_payload_tdata), - .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid), - .input_0_udp_payload_tready(input_0_udp_payload_tready), - .input_0_udp_payload_tlast(input_0_udp_payload_tlast), - .input_0_udp_payload_tuser(input_0_udp_payload_tuser), - .input_1_udp_hdr_valid(input_1_udp_hdr_valid), - .input_1_udp_hdr_ready(input_1_udp_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_udp_source_port(input_1_udp_source_port), - .input_1_udp_dest_port(input_1_udp_dest_port), - .input_1_udp_length(input_1_udp_length), - .input_1_udp_checksum(input_1_udp_checksum), - .input_1_udp_payload_tdata(input_1_udp_payload_tdata), - .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid), - .input_1_udp_payload_tready(input_1_udp_payload_tready), - .input_1_udp_payload_tlast(input_1_udp_payload_tlast), - .input_1_udp_payload_tuser(input_1_udp_payload_tuser), - .input_2_udp_hdr_valid(input_2_udp_hdr_valid), - .input_2_udp_hdr_ready(input_2_udp_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_udp_source_port(input_2_udp_source_port), - .input_2_udp_dest_port(input_2_udp_dest_port), - .input_2_udp_length(input_2_udp_length), - .input_2_udp_checksum(input_2_udp_checksum), - .input_2_udp_payload_tdata(input_2_udp_payload_tdata), - .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid), - .input_2_udp_payload_tready(input_2_udp_payload_tready), - .input_2_udp_payload_tlast(input_2_udp_payload_tlast), - .input_2_udp_payload_tuser(input_2_udp_payload_tuser), - .input_3_udp_hdr_valid(input_3_udp_hdr_valid), - .input_3_udp_hdr_ready(input_3_udp_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_udp_source_port(input_3_udp_source_port), - .input_3_udp_dest_port(input_3_udp_dest_port), - .input_3_udp_length(input_3_udp_length), - .input_3_udp_checksum(input_3_udp_checksum), - .input_3_udp_payload_tdata(input_3_udp_payload_tdata), - .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid), - .input_3_udp_payload_tready(input_3_udp_payload_tready), - .input_3_udp_payload_tlast(input_3_udp_payload_tlast), - .input_3_udp_payload_tuser(input_3_udp_payload_tuser), - // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + // Ethernet frame inputs + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tid(s_udp_payload_axis_tid), + .s_udp_payload_axis_tdest(s_udp_payload_axis_tdest), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), + // Ethernet frame output + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tid(m_udp_payload_axis_tid), + .m_udp_payload_axis_tdest(m_udp_payload_axis_tdest), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Control .enable(enable), .select(select) diff --git a/tb/test_udp_mux_64_4.py b/tb/test_udp_mux_64_4.py index 521598330..162f658ce 100755 --- a/tb/test_udp_mux_64_4.py +++ b/tb/test_udp_mux_64_4.py @@ -28,8 +28,8 @@ import os import udp_ep -module = 'udp_mux_64_4' -testbench = 'test_%s' % module +module = 'udp_mux' +testbench = 'test_%s_64_4' % module srcs = [] @@ -42,347 +42,204 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_udp_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_ip_version = Signal(intbv(0)[4:]) - input_0_ip_ihl = Signal(intbv(0)[4:]) - input_0_ip_dscp = Signal(intbv(0)[6:]) - input_0_ip_ecn = Signal(intbv(0)[2:]) - input_0_ip_length = Signal(intbv(0)[16:]) - input_0_ip_identification = Signal(intbv(0)[16:]) - input_0_ip_flags = Signal(intbv(0)[3:]) - input_0_ip_fragment_offset = Signal(intbv(0)[13:]) - input_0_ip_ttl = Signal(intbv(0)[8:]) - input_0_ip_protocol = Signal(intbv(0)[8:]) - input_0_ip_header_checksum = Signal(intbv(0)[16:]) - input_0_ip_source_ip = Signal(intbv(0)[32:]) - input_0_ip_dest_ip = Signal(intbv(0)[32:]) - input_0_udp_source_port = Signal(intbv(0)[16:]) - input_0_udp_dest_port = Signal(intbv(0)[16:]) - input_0_udp_length = Signal(intbv(0)[16:]) - input_0_udp_checksum = Signal(intbv(0)[16:]) - input_0_udp_payload_tdata = Signal(intbv(0)[64:]) - input_0_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_0_udp_payload_tvalid = Signal(bool(0)) - input_0_udp_payload_tlast = Signal(bool(0)) - input_0_udp_payload_tuser = Signal(bool(0)) - input_1_udp_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_ip_version = Signal(intbv(0)[4:]) - input_1_ip_ihl = Signal(intbv(0)[4:]) - input_1_ip_dscp = Signal(intbv(0)[6:]) - input_1_ip_ecn = Signal(intbv(0)[2:]) - input_1_ip_length = Signal(intbv(0)[16:]) - input_1_ip_identification = Signal(intbv(0)[16:]) - input_1_ip_flags = Signal(intbv(0)[3:]) - input_1_ip_fragment_offset = Signal(intbv(0)[13:]) - input_1_ip_ttl = Signal(intbv(0)[8:]) - input_1_ip_protocol = Signal(intbv(0)[8:]) - input_1_ip_header_checksum = Signal(intbv(0)[16:]) - input_1_ip_source_ip = Signal(intbv(0)[32:]) - input_1_ip_dest_ip = Signal(intbv(0)[32:]) - input_1_udp_source_port = Signal(intbv(0)[16:]) - input_1_udp_dest_port = Signal(intbv(0)[16:]) - input_1_udp_length = Signal(intbv(0)[16:]) - input_1_udp_checksum = Signal(intbv(0)[16:]) - input_1_udp_payload_tdata = Signal(intbv(0)[64:]) - input_1_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_1_udp_payload_tvalid = Signal(bool(0)) - input_1_udp_payload_tlast = Signal(bool(0)) - input_1_udp_payload_tuser = Signal(bool(0)) - input_2_udp_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_ip_version = Signal(intbv(0)[4:]) - input_2_ip_ihl = Signal(intbv(0)[4:]) - input_2_ip_dscp = Signal(intbv(0)[6:]) - input_2_ip_ecn = Signal(intbv(0)[2:]) - input_2_ip_length = Signal(intbv(0)[16:]) - input_2_ip_identification = Signal(intbv(0)[16:]) - input_2_ip_flags = Signal(intbv(0)[3:]) - input_2_ip_fragment_offset = Signal(intbv(0)[13:]) - input_2_ip_ttl = Signal(intbv(0)[8:]) - input_2_ip_protocol = Signal(intbv(0)[8:]) - input_2_ip_header_checksum = Signal(intbv(0)[16:]) - input_2_ip_source_ip = Signal(intbv(0)[32:]) - input_2_ip_dest_ip = Signal(intbv(0)[32:]) - input_2_udp_source_port = Signal(intbv(0)[16:]) - input_2_udp_dest_port = Signal(intbv(0)[16:]) - input_2_udp_length = Signal(intbv(0)[16:]) - input_2_udp_checksum = Signal(intbv(0)[16:]) - input_2_udp_payload_tdata = Signal(intbv(0)[64:]) - input_2_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_2_udp_payload_tvalid = Signal(bool(0)) - input_2_udp_payload_tlast = Signal(bool(0)) - input_2_udp_payload_tuser = Signal(bool(0)) - input_3_udp_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_ip_version = Signal(intbv(0)[4:]) - input_3_ip_ihl = Signal(intbv(0)[4:]) - input_3_ip_dscp = Signal(intbv(0)[6:]) - input_3_ip_ecn = Signal(intbv(0)[2:]) - input_3_ip_length = Signal(intbv(0)[16:]) - input_3_ip_identification = Signal(intbv(0)[16:]) - input_3_ip_flags = Signal(intbv(0)[3:]) - input_3_ip_fragment_offset = Signal(intbv(0)[13:]) - input_3_ip_ttl = Signal(intbv(0)[8:]) - input_3_ip_protocol = Signal(intbv(0)[8:]) - input_3_ip_header_checksum = Signal(intbv(0)[16:]) - input_3_ip_source_ip = Signal(intbv(0)[32:]) - input_3_ip_dest_ip = Signal(intbv(0)[32:]) - input_3_udp_source_port = Signal(intbv(0)[16:]) - input_3_udp_dest_port = Signal(intbv(0)[16:]) - input_3_udp_length = Signal(intbv(0)[16:]) - input_3_udp_checksum = Signal(intbv(0)[16:]) - input_3_udp_payload_tdata = Signal(intbv(0)[64:]) - input_3_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_3_udp_payload_tvalid = Signal(bool(0)) - input_3_udp_payload_tlast = Signal(bool(0)) - input_3_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_version_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_ihl_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_dscp_list = [Signal(intbv(0)[6:]) for i in range(S_COUNT)] + s_ip_ecn_list = [Signal(intbv(0)[2:]) for i in range(S_COUNT)] + s_ip_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_identification_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_flags_list = [Signal(intbv(0)[3:]) for i in range(S_COUNT)] + s_ip_fragment_offset_list = [Signal(intbv(0)[13:]) for i in range(S_COUNT)] + s_ip_ttl_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_protocol_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_header_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_source_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_dest_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_udp_source_port_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_dest_port_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_udp_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_udp_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_udp_payload_tready = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) + s_udp_hdr_valid = ConcatSignal(*reversed(s_udp_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_ip_version = ConcatSignal(*reversed(s_ip_version_list)) + s_ip_ihl = ConcatSignal(*reversed(s_ip_ihl_list)) + s_ip_dscp = ConcatSignal(*reversed(s_ip_dscp_list)) + s_ip_ecn = ConcatSignal(*reversed(s_ip_ecn_list)) + s_ip_length = ConcatSignal(*reversed(s_ip_length_list)) + s_ip_identification = ConcatSignal(*reversed(s_ip_identification_list)) + s_ip_flags = ConcatSignal(*reversed(s_ip_flags_list)) + s_ip_fragment_offset = ConcatSignal(*reversed(s_ip_fragment_offset_list)) + s_ip_ttl = ConcatSignal(*reversed(s_ip_ttl_list)) + s_ip_protocol = ConcatSignal(*reversed(s_ip_protocol_list)) + s_ip_header_checksum = ConcatSignal(*reversed(s_ip_header_checksum_list)) + s_ip_source_ip = ConcatSignal(*reversed(s_ip_source_ip_list)) + s_ip_dest_ip = ConcatSignal(*reversed(s_ip_dest_ip_list)) + s_udp_source_port = ConcatSignal(*reversed(s_udp_source_port_list)) + s_udp_dest_port = ConcatSignal(*reversed(s_udp_dest_port_list)) + s_udp_length = ConcatSignal(*reversed(s_udp_length_list)) + s_udp_checksum = ConcatSignal(*reversed(s_udp_checksum_list)) + s_udp_payload_axis_tdata = ConcatSignal(*reversed(s_udp_payload_axis_tdata_list)) + s_udp_payload_axis_tkeep = ConcatSignal(*reversed(s_udp_payload_axis_tkeep_list)) + s_udp_payload_axis_tvalid = ConcatSignal(*reversed(s_udp_payload_axis_tvalid_list)) + s_udp_payload_axis_tlast = ConcatSignal(*reversed(s_udp_payload_axis_tlast_list)) + s_udp_payload_axis_tid = ConcatSignal(*reversed(s_udp_payload_axis_tid_list)) + s_udp_payload_axis_tdest = ConcatSignal(*reversed(s_udp_payload_axis_tdest_list)) + s_udp_payload_axis_tuser = ConcatSignal(*reversed(s_udp_payload_axis_tuser_list)) + + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) enable = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_0_udp_hdr_ready = Signal(bool(0)) - input_0_udp_payload_tready = Signal(bool(0)) - input_1_udp_hdr_ready = Signal(bool(0)) - input_1_udp_payload_tready = Signal(bool(0)) - input_2_udp_hdr_ready = Signal(bool(0)) - input_2_udp_payload_tready = Signal(bool(0)) - input_3_udp_hdr_ready = Signal(bool(0)) - input_3_udp_payload_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_udp_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_udp_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[64:]) - output_udp_payload_tkeep = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_ready_list = [s_udp_hdr_ready(i) for i in range(S_COUNT)] + s_udp_payload_axis_tready_list = [s_udp_payload_axis_tready(i) for i in range(S_COUNT)] + + m_udp_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_udp_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_udp_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_udp_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = udp_ep.UDPFrameSource() + for k in range(S_COUNT): + s = udp_ep.UDPFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - udp_hdr_ready=input_0_udp_hdr_ready, - udp_hdr_valid=input_0_udp_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - eth_type=input_0_eth_type, - ip_version=input_0_ip_version, - ip_ihl=input_0_ip_ihl, - ip_dscp=input_0_ip_dscp, - ip_ecn=input_0_ip_ecn, - ip_length=input_0_ip_length, - ip_identification=input_0_ip_identification, - ip_flags=input_0_ip_flags, - ip_fragment_offset=input_0_ip_fragment_offset, - ip_ttl=input_0_ip_ttl, - ip_protocol=input_0_ip_protocol, - ip_header_checksum=input_0_ip_header_checksum, - ip_source_ip=input_0_ip_source_ip, - ip_dest_ip=input_0_ip_dest_ip, - udp_source_port=input_0_udp_source_port, - udp_dest_port=input_0_udp_dest_port, - udp_length=input_0_udp_length, - udp_checksum=input_0_udp_checksum, - udp_payload_tdata=input_0_udp_payload_tdata, - udp_payload_tkeep=input_0_udp_payload_tkeep, - udp_payload_tvalid=input_0_udp_payload_tvalid, - udp_payload_tready=input_0_udp_payload_tready, - udp_payload_tlast=input_0_udp_payload_tlast, - udp_payload_tuser=input_0_udp_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = udp_ep.UDPFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - udp_hdr_ready=input_1_udp_hdr_ready, - udp_hdr_valid=input_1_udp_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - eth_type=input_1_eth_type, - ip_version=input_1_ip_version, - ip_ihl=input_1_ip_ihl, - ip_dscp=input_1_ip_dscp, - ip_ecn=input_1_ip_ecn, - ip_length=input_1_ip_length, - ip_identification=input_1_ip_identification, - ip_flags=input_1_ip_flags, - ip_fragment_offset=input_1_ip_fragment_offset, - ip_ttl=input_1_ip_ttl, - ip_protocol=input_1_ip_protocol, - ip_header_checksum=input_1_ip_header_checksum, - ip_source_ip=input_1_ip_source_ip, - ip_dest_ip=input_1_ip_dest_ip, - udp_source_port=input_1_udp_source_port, - udp_dest_port=input_1_udp_dest_port, - udp_length=input_1_udp_length, - udp_checksum=input_1_udp_checksum, - udp_payload_tdata=input_1_udp_payload_tdata, - udp_payload_tkeep=input_1_udp_payload_tkeep, - udp_payload_tvalid=input_1_udp_payload_tvalid, - udp_payload_tready=input_1_udp_payload_tready, - udp_payload_tlast=input_1_udp_payload_tlast, - udp_payload_tuser=input_1_udp_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = udp_ep.UDPFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - udp_hdr_ready=input_2_udp_hdr_ready, - udp_hdr_valid=input_2_udp_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - ip_version=input_2_ip_version, - ip_ihl=input_2_ip_ihl, - ip_dscp=input_2_ip_dscp, - ip_ecn=input_2_ip_ecn, - ip_length=input_2_ip_length, - ip_identification=input_2_ip_identification, - ip_flags=input_2_ip_flags, - ip_fragment_offset=input_2_ip_fragment_offset, - ip_ttl=input_2_ip_ttl, - ip_protocol=input_2_ip_protocol, - ip_header_checksum=input_2_ip_header_checksum, - ip_source_ip=input_2_ip_source_ip, - ip_dest_ip=input_2_ip_dest_ip, - udp_source_port=input_2_udp_source_port, - udp_dest_port=input_2_udp_dest_port, - udp_length=input_2_udp_length, - udp_checksum=input_2_udp_checksum, - udp_payload_tdata=input_2_udp_payload_tdata, - udp_payload_tkeep=input_2_udp_payload_tkeep, - udp_payload_tvalid=input_2_udp_payload_tvalid, - udp_payload_tready=input_2_udp_payload_tready, - udp_payload_tlast=input_2_udp_payload_tlast, - udp_payload_tuser=input_2_udp_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = udp_ep.UDPFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - udp_hdr_ready=input_3_udp_hdr_ready, - udp_hdr_valid=input_3_udp_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - ip_version=input_3_ip_version, - ip_ihl=input_3_ip_ihl, - ip_dscp=input_3_ip_dscp, - ip_ecn=input_3_ip_ecn, - ip_length=input_3_ip_length, - ip_identification=input_3_ip_identification, - ip_flags=input_3_ip_flags, - ip_fragment_offset=input_3_ip_fragment_offset, - ip_ttl=input_3_ip_ttl, - ip_protocol=input_3_ip_protocol, - ip_header_checksum=input_3_ip_header_checksum, - ip_source_ip=input_3_ip_source_ip, - ip_dest_ip=input_3_ip_dest_ip, - udp_source_port=input_3_udp_source_port, - udp_dest_port=input_3_udp_dest_port, - udp_length=input_3_udp_length, - udp_checksum=input_3_udp_checksum, - udp_payload_tdata=input_3_udp_payload_tdata, - udp_payload_tkeep=input_3_udp_payload_tkeep, - udp_payload_tvalid=input_3_udp_payload_tvalid, - udp_payload_tready=input_3_udp_payload_tready, - udp_payload_tlast=input_3_udp_payload_tlast, - udp_payload_tuser=input_3_udp_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + udp_hdr_ready=s_udp_hdr_ready_list[k], + udp_hdr_valid=s_udp_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + ip_version=s_ip_version_list[k], + ip_ihl=s_ip_ihl_list[k], + ip_dscp=s_ip_dscp_list[k], + ip_ecn=s_ip_ecn_list[k], + ip_length=s_ip_length_list[k], + ip_identification=s_ip_identification_list[k], + ip_flags=s_ip_flags_list[k], + ip_fragment_offset=s_ip_fragment_offset_list[k], + ip_ttl=s_ip_ttl_list[k], + ip_protocol=s_ip_protocol_list[k], + ip_header_checksum=s_ip_header_checksum_list[k], + ip_source_ip=s_ip_source_ip_list[k], + ip_dest_ip=s_ip_dest_ip_list[k], + udp_source_port=s_udp_source_port_list[k], + udp_dest_port=s_udp_dest_port_list[k], + udp_length=s_udp_length_list[k], + udp_checksum=s_udp_checksum_list[k], + udp_payload_tdata=s_udp_payload_axis_tdata_list[k], + udp_payload_tkeep=s_udp_payload_axis_tkeep_list[k], + udp_payload_tvalid=s_udp_payload_axis_tvalid_list[k], + udp_payload_tready=s_udp_payload_axis_tready_list[k], + udp_payload_tlast=s_udp_payload_axis_tlast_list[k], + udp_payload_tuser=s_udp_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = udp_ep.UDPFrameSink() sink_logic = sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tkeep=output_udp_payload_tkeep, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tkeep=m_udp_payload_axis_tkeep, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -397,147 +254,67 @@ def bench(): rst=rst, current_test=current_test, - input_0_udp_hdr_valid=input_0_udp_hdr_valid, - input_0_udp_hdr_ready=input_0_udp_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_ip_version=input_0_ip_version, - input_0_ip_ihl=input_0_ip_ihl, - input_0_ip_dscp=input_0_ip_dscp, - input_0_ip_ecn=input_0_ip_ecn, - input_0_ip_length=input_0_ip_length, - input_0_ip_identification=input_0_ip_identification, - input_0_ip_flags=input_0_ip_flags, - input_0_ip_fragment_offset=input_0_ip_fragment_offset, - input_0_ip_ttl=input_0_ip_ttl, - input_0_ip_protocol=input_0_ip_protocol, - input_0_ip_header_checksum=input_0_ip_header_checksum, - input_0_ip_source_ip=input_0_ip_source_ip, - input_0_ip_dest_ip=input_0_ip_dest_ip, - input_0_udp_source_port=input_0_udp_source_port, - input_0_udp_dest_port=input_0_udp_dest_port, - input_0_udp_length=input_0_udp_length, - input_0_udp_checksum=input_0_udp_checksum, - input_0_udp_payload_tdata=input_0_udp_payload_tdata, - input_0_udp_payload_tkeep=input_0_udp_payload_tkeep, - input_0_udp_payload_tvalid=input_0_udp_payload_tvalid, - input_0_udp_payload_tready=input_0_udp_payload_tready, - input_0_udp_payload_tlast=input_0_udp_payload_tlast, - input_0_udp_payload_tuser=input_0_udp_payload_tuser, - input_1_udp_hdr_valid=input_1_udp_hdr_valid, - input_1_udp_hdr_ready=input_1_udp_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_ip_version=input_1_ip_version, - input_1_ip_ihl=input_1_ip_ihl, - input_1_ip_dscp=input_1_ip_dscp, - input_1_ip_ecn=input_1_ip_ecn, - input_1_ip_length=input_1_ip_length, - input_1_ip_identification=input_1_ip_identification, - input_1_ip_flags=input_1_ip_flags, - input_1_ip_fragment_offset=input_1_ip_fragment_offset, - input_1_ip_ttl=input_1_ip_ttl, - input_1_ip_protocol=input_1_ip_protocol, - input_1_ip_header_checksum=input_1_ip_header_checksum, - input_1_ip_source_ip=input_1_ip_source_ip, - input_1_ip_dest_ip=input_1_ip_dest_ip, - input_1_udp_source_port=input_1_udp_source_port, - input_1_udp_dest_port=input_1_udp_dest_port, - input_1_udp_length=input_1_udp_length, - input_1_udp_checksum=input_1_udp_checksum, - input_1_udp_payload_tdata=input_1_udp_payload_tdata, - input_1_udp_payload_tkeep=input_1_udp_payload_tkeep, - input_1_udp_payload_tvalid=input_1_udp_payload_tvalid, - input_1_udp_payload_tready=input_1_udp_payload_tready, - input_1_udp_payload_tlast=input_1_udp_payload_tlast, - input_1_udp_payload_tuser=input_1_udp_payload_tuser, - input_2_udp_hdr_valid=input_2_udp_hdr_valid, - input_2_udp_hdr_ready=input_2_udp_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_ip_version=input_2_ip_version, - input_2_ip_ihl=input_2_ip_ihl, - input_2_ip_dscp=input_2_ip_dscp, - input_2_ip_ecn=input_2_ip_ecn, - input_2_ip_length=input_2_ip_length, - input_2_ip_identification=input_2_ip_identification, - input_2_ip_flags=input_2_ip_flags, - input_2_ip_fragment_offset=input_2_ip_fragment_offset, - input_2_ip_ttl=input_2_ip_ttl, - input_2_ip_protocol=input_2_ip_protocol, - input_2_ip_header_checksum=input_2_ip_header_checksum, - input_2_ip_source_ip=input_2_ip_source_ip, - input_2_ip_dest_ip=input_2_ip_dest_ip, - input_2_udp_source_port=input_2_udp_source_port, - input_2_udp_dest_port=input_2_udp_dest_port, - input_2_udp_length=input_2_udp_length, - input_2_udp_checksum=input_2_udp_checksum, - input_2_udp_payload_tdata=input_2_udp_payload_tdata, - input_2_udp_payload_tkeep=input_2_udp_payload_tkeep, - input_2_udp_payload_tvalid=input_2_udp_payload_tvalid, - input_2_udp_payload_tready=input_2_udp_payload_tready, - input_2_udp_payload_tlast=input_2_udp_payload_tlast, - input_2_udp_payload_tuser=input_2_udp_payload_tuser, - input_3_udp_hdr_valid=input_3_udp_hdr_valid, - input_3_udp_hdr_ready=input_3_udp_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_ip_version=input_3_ip_version, - input_3_ip_ihl=input_3_ip_ihl, - input_3_ip_dscp=input_3_ip_dscp, - input_3_ip_ecn=input_3_ip_ecn, - input_3_ip_length=input_3_ip_length, - input_3_ip_identification=input_3_ip_identification, - input_3_ip_flags=input_3_ip_flags, - input_3_ip_fragment_offset=input_3_ip_fragment_offset, - input_3_ip_ttl=input_3_ip_ttl, - input_3_ip_protocol=input_3_ip_protocol, - input_3_ip_header_checksum=input_3_ip_header_checksum, - input_3_ip_source_ip=input_3_ip_source_ip, - input_3_ip_dest_ip=input_3_ip_dest_ip, - input_3_udp_source_port=input_3_udp_source_port, - input_3_udp_dest_port=input_3_udp_dest_port, - input_3_udp_length=input_3_udp_length, - input_3_udp_checksum=input_3_udp_checksum, - input_3_udp_payload_tdata=input_3_udp_payload_tdata, - input_3_udp_payload_tkeep=input_3_udp_payload_tkeep, - input_3_udp_payload_tvalid=input_3_udp_payload_tvalid, - input_3_udp_payload_tready=input_3_udp_payload_tready, - input_3_udp_payload_tlast=input_3_udp_payload_tlast, - input_3_udp_payload_tuser=input_3_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep=s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tid=s_udp_payload_axis_tid, + s_udp_payload_axis_tdest=s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tkeep=output_udp_payload_tkeep, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep=m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tid=m_udp_payload_axis_tid, + m_udp_payload_axis_tdest=m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, enable=enable, select=select @@ -591,7 +368,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -630,7 +407,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -692,8 +469,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -760,12 +537,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + while s_udp_payload_axis_tvalid: yield clk.posedge select.next = 2 @@ -834,23 +611,23 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_udp_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge select.next = 2 @@ -919,12 +696,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + while s_udp_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_udp_mux_64_4.v b/tb/test_udp_mux_64_4.v index f72555650..27ea342ed 100644 --- a/tb/test_udp_mux_64_4.v +++ b/tb/test_udp_mux_64_4.v @@ -27,162 +27,94 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for udp_mux_64_4 + * Testbench for udp_mux */ module test_udp_mux_64_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_udp_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [3:0] input_0_ip_version = 0; -reg [3:0] input_0_ip_ihl = 0; -reg [5:0] input_0_ip_dscp = 0; -reg [1:0] input_0_ip_ecn = 0; -reg [15:0] input_0_ip_length = 0; -reg [15:0] input_0_ip_identification = 0; -reg [2:0] input_0_ip_flags = 0; -reg [12:0] input_0_ip_fragment_offset = 0; -reg [7:0] input_0_ip_ttl = 0; -reg [7:0] input_0_ip_protocol = 0; -reg [15:0] input_0_ip_header_checksum = 0; -reg [31:0] input_0_ip_source_ip = 0; -reg [31:0] input_0_ip_dest_ip = 0; -reg [15:0] input_0_udp_source_port = 0; -reg [15:0] input_0_udp_dest_port = 0; -reg [15:0] input_0_udp_length = 0; -reg [15:0] input_0_udp_checksum = 0; -reg [63:0] input_0_udp_payload_tdata = 0; -reg [7:0] input_0_udp_payload_tkeep = 0; -reg input_0_udp_payload_tvalid = 0; -reg input_0_udp_payload_tlast = 0; -reg input_0_udp_payload_tuser = 0; -reg input_1_udp_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [3:0] input_1_ip_version = 0; -reg [3:0] input_1_ip_ihl = 0; -reg [5:0] input_1_ip_dscp = 0; -reg [1:0] input_1_ip_ecn = 0; -reg [15:0] input_1_ip_length = 0; -reg [15:0] input_1_ip_identification = 0; -reg [2:0] input_1_ip_flags = 0; -reg [12:0] input_1_ip_fragment_offset = 0; -reg [7:0] input_1_ip_ttl = 0; -reg [7:0] input_1_ip_protocol = 0; -reg [15:0] input_1_ip_header_checksum = 0; -reg [31:0] input_1_ip_source_ip = 0; -reg [31:0] input_1_ip_dest_ip = 0; -reg [15:0] input_1_udp_source_port = 0; -reg [15:0] input_1_udp_dest_port = 0; -reg [15:0] input_1_udp_length = 0; -reg [15:0] input_1_udp_checksum = 0; -reg [63:0] input_1_udp_payload_tdata = 0; -reg [7:0] input_1_udp_payload_tkeep = 0; -reg input_1_udp_payload_tvalid = 0; -reg input_1_udp_payload_tlast = 0; -reg input_1_udp_payload_tuser = 0; -reg input_2_udp_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [3:0] input_2_ip_version = 0; -reg [3:0] input_2_ip_ihl = 0; -reg [5:0] input_2_ip_dscp = 0; -reg [1:0] input_2_ip_ecn = 0; -reg [15:0] input_2_ip_length = 0; -reg [15:0] input_2_ip_identification = 0; -reg [2:0] input_2_ip_flags = 0; -reg [12:0] input_2_ip_fragment_offset = 0; -reg [7:0] input_2_ip_ttl = 0; -reg [7:0] input_2_ip_protocol = 0; -reg [15:0] input_2_ip_header_checksum = 0; -reg [31:0] input_2_ip_source_ip = 0; -reg [31:0] input_2_ip_dest_ip = 0; -reg [15:0] input_2_udp_source_port = 0; -reg [15:0] input_2_udp_dest_port = 0; -reg [15:0] input_2_udp_length = 0; -reg [15:0] input_2_udp_checksum = 0; -reg [63:0] input_2_udp_payload_tdata = 0; -reg [7:0] input_2_udp_payload_tkeep = 0; -reg input_2_udp_payload_tvalid = 0; -reg input_2_udp_payload_tlast = 0; -reg input_2_udp_payload_tuser = 0; -reg input_3_udp_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [3:0] input_3_ip_version = 0; -reg [3:0] input_3_ip_ihl = 0; -reg [5:0] input_3_ip_dscp = 0; -reg [1:0] input_3_ip_ecn = 0; -reg [15:0] input_3_ip_length = 0; -reg [15:0] input_3_ip_identification = 0; -reg [2:0] input_3_ip_flags = 0; -reg [12:0] input_3_ip_fragment_offset = 0; -reg [7:0] input_3_ip_ttl = 0; -reg [7:0] input_3_ip_protocol = 0; -reg [15:0] input_3_ip_header_checksum = 0; -reg [31:0] input_3_ip_source_ip = 0; -reg [31:0] input_3_ip_dest_ip = 0; -reg [15:0] input_3_udp_source_port = 0; -reg [15:0] input_3_udp_dest_port = 0; -reg [15:0] input_3_udp_length = 0; -reg [15:0] input_3_udp_checksum = 0; -reg [63:0] input_3_udp_payload_tdata = 0; -reg [7:0] input_3_udp_payload_tkeep = 0; -reg input_3_udp_payload_tvalid = 0; -reg input_3_udp_payload_tlast = 0; -reg input_3_udp_payload_tuser = 0; +reg [S_COUNT-1:0] s_udp_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*4-1:0] s_ip_version = 0; +reg [S_COUNT*4-1:0] s_ip_ihl = 0; +reg [S_COUNT*6-1:0] s_ip_dscp = 0; +reg [S_COUNT*2-1:0] s_ip_ecn = 0; +reg [S_COUNT*16-1:0] s_ip_length = 0; +reg [S_COUNT*16-1:0] s_ip_identification = 0; +reg [S_COUNT*3-1:0] s_ip_flags = 0; +reg [S_COUNT*13-1:0] s_ip_fragment_offset = 0; +reg [S_COUNT*8-1:0] s_ip_ttl = 0; +reg [S_COUNT*8-1:0] s_ip_protocol = 0; +reg [S_COUNT*16-1:0] s_ip_header_checksum = 0; +reg [S_COUNT*32-1:0] s_ip_source_ip = 0; +reg [S_COUNT*32-1:0] s_ip_dest_ip = 0; +reg [S_COUNT*16-1:0] s_udp_source_port = 0; +reg [S_COUNT*16-1:0] s_udp_dest_port = 0; +reg [S_COUNT*16-1:0] s_udp_length = 0; +reg [S_COUNT*16-1:0] s_udp_checksum = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_udp_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_udp_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_udp_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_udp_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_udp_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_udp_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_udp_payload_axis_tuser = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; reg enable = 0; reg [1:0] select = 0; // Outputs -wire input_0_udp_payload_tready; -wire input_0_udp_hdr_ready; -wire input_1_udp_payload_tready; -wire input_1_udp_hdr_ready; -wire input_2_udp_payload_tready; -wire input_2_udp_hdr_ready; -wire input_3_udp_payload_tready; -wire input_3_udp_hdr_ready; +wire [S_COUNT-1:0] s_udp_hdr_ready; +wire [S_COUNT-1:0] s_udp_payload_axis_tready; -wire output_udp_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [63:0] output_udp_payload_tdata; -wire [7:0] output_udp_payload_tkeep; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire m_udp_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [DATA_WIDTH-1:0] m_udp_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_udp_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_udp_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_udp_payload_axis_tuser; initial begin // myhdl integration @@ -190,149 +122,70 @@ initial begin clk, rst, current_test, - input_0_udp_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_ip_version, - input_0_ip_ihl, - input_0_ip_dscp, - input_0_ip_ecn, - input_0_ip_length, - input_0_ip_identification, - input_0_ip_flags, - input_0_ip_fragment_offset, - input_0_ip_ttl, - input_0_ip_protocol, - input_0_ip_header_checksum, - input_0_ip_source_ip, - input_0_ip_dest_ip, - input_0_udp_source_port, - input_0_udp_dest_port, - input_0_udp_length, - input_0_udp_checksum, - input_0_udp_payload_tdata, - input_0_udp_payload_tkeep, - input_0_udp_payload_tvalid, - input_0_udp_payload_tlast, - input_0_udp_payload_tuser, - input_1_udp_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_ip_version, - input_1_ip_ihl, - input_1_ip_dscp, - input_1_ip_ecn, - input_1_ip_length, - input_1_ip_identification, - input_1_ip_flags, - input_1_ip_fragment_offset, - input_1_ip_ttl, - input_1_ip_protocol, - input_1_ip_header_checksum, - input_1_ip_source_ip, - input_1_ip_dest_ip, - input_1_udp_source_port, - input_1_udp_dest_port, - input_1_udp_length, - input_1_udp_checksum, - input_1_udp_payload_tdata, - input_1_udp_payload_tkeep, - input_1_udp_payload_tvalid, - input_1_udp_payload_tlast, - input_1_udp_payload_tuser, - input_2_udp_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_ip_version, - input_2_ip_ihl, - input_2_ip_dscp, - input_2_ip_ecn, - input_2_ip_length, - input_2_ip_identification, - input_2_ip_flags, - input_2_ip_fragment_offset, - input_2_ip_ttl, - input_2_ip_protocol, - input_2_ip_header_checksum, - input_2_ip_source_ip, - input_2_ip_dest_ip, - input_2_udp_source_port, - input_2_udp_dest_port, - input_2_udp_length, - input_2_udp_checksum, - input_2_udp_payload_tdata, - input_2_udp_payload_tkeep, - input_2_udp_payload_tvalid, - input_2_udp_payload_tlast, - input_2_udp_payload_tuser, - input_3_udp_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_ip_version, - input_3_ip_ihl, - input_3_ip_dscp, - input_3_ip_ecn, - input_3_ip_length, - input_3_ip_identification, - input_3_ip_flags, - input_3_ip_fragment_offset, - input_3_ip_ttl, - input_3_ip_protocol, - input_3_ip_header_checksum, - input_3_ip_source_ip, - input_3_ip_dest_ip, - input_3_udp_source_port, - input_3_udp_dest_port, - input_3_udp_length, - input_3_udp_checksum, - input_3_udp_payload_tdata, - input_3_udp_payload_tkeep, - input_3_udp_payload_tvalid, - input_3_udp_payload_tlast, - input_3_udp_payload_tuser, - output_udp_hdr_ready, - output_udp_payload_tready, + s_udp_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tid, + s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser, + m_udp_hdr_ready, + m_udp_payload_axis_tready, enable, - select); + select + ); $to_myhdl( - input_0_udp_hdr_ready, - input_0_udp_payload_tready, - input_1_udp_hdr_ready, - input_1_udp_payload_tready, - input_2_udp_hdr_ready, - input_2_udp_payload_tready, - input_3_udp_hdr_ready, - input_3_udp_payload_tready, - output_udp_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tkeep, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_udp_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tid, + m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser ); // dump file @@ -340,152 +193,83 @@ initial begin $dumpvars(0, test_udp_mux_64_4); end -udp_mux_64_4 +udp_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), - // UDP frame inputs - .input_0_udp_hdr_valid(input_0_udp_hdr_valid), - .input_0_udp_hdr_ready(input_0_udp_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_udp_source_port(input_0_udp_source_port), - .input_0_udp_dest_port(input_0_udp_dest_port), - .input_0_udp_length(input_0_udp_length), - .input_0_udp_checksum(input_0_udp_checksum), - .input_0_udp_payload_tdata(input_0_udp_payload_tdata), - .input_0_udp_payload_tkeep(input_0_udp_payload_tkeep), - .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid), - .input_0_udp_payload_tready(input_0_udp_payload_tready), - .input_0_udp_payload_tlast(input_0_udp_payload_tlast), - .input_0_udp_payload_tuser(input_0_udp_payload_tuser), - .input_1_udp_hdr_valid(input_1_udp_hdr_valid), - .input_1_udp_hdr_ready(input_1_udp_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_udp_source_port(input_1_udp_source_port), - .input_1_udp_dest_port(input_1_udp_dest_port), - .input_1_udp_length(input_1_udp_length), - .input_1_udp_checksum(input_1_udp_checksum), - .input_1_udp_payload_tdata(input_1_udp_payload_tdata), - .input_1_udp_payload_tkeep(input_1_udp_payload_tkeep), - .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid), - .input_1_udp_payload_tready(input_1_udp_payload_tready), - .input_1_udp_payload_tlast(input_1_udp_payload_tlast), - .input_1_udp_payload_tuser(input_1_udp_payload_tuser), - .input_2_udp_hdr_valid(input_2_udp_hdr_valid), - .input_2_udp_hdr_ready(input_2_udp_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_udp_source_port(input_2_udp_source_port), - .input_2_udp_dest_port(input_2_udp_dest_port), - .input_2_udp_length(input_2_udp_length), - .input_2_udp_checksum(input_2_udp_checksum), - .input_2_udp_payload_tdata(input_2_udp_payload_tdata), - .input_2_udp_payload_tkeep(input_2_udp_payload_tkeep), - .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid), - .input_2_udp_payload_tready(input_2_udp_payload_tready), - .input_2_udp_payload_tlast(input_2_udp_payload_tlast), - .input_2_udp_payload_tuser(input_2_udp_payload_tuser), - .input_3_udp_hdr_valid(input_3_udp_hdr_valid), - .input_3_udp_hdr_ready(input_3_udp_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_udp_source_port(input_3_udp_source_port), - .input_3_udp_dest_port(input_3_udp_dest_port), - .input_3_udp_length(input_3_udp_length), - .input_3_udp_checksum(input_3_udp_checksum), - .input_3_udp_payload_tdata(input_3_udp_payload_tdata), - .input_3_udp_payload_tkeep(input_3_udp_payload_tkeep), - .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid), - .input_3_udp_payload_tready(input_3_udp_payload_tready), - .input_3_udp_payload_tlast(input_3_udp_payload_tlast), - .input_3_udp_payload_tuser(input_3_udp_payload_tuser), - // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tkeep(output_udp_payload_tkeep), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + // Ethernet frame inputs + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tid(s_udp_payload_axis_tid), + .s_udp_payload_axis_tdest(s_udp_payload_axis_tdest), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), + // Ethernet frame output + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tid(m_udp_payload_axis_tid), + .m_udp_payload_axis_tdest(m_udp_payload_axis_tdest), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Control .enable(enable), .select(select) From 96cefbe0c188fdad9fe8fdec41623c416e9ba719 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 31 Oct 2018 21:42:28 -0700 Subject: [PATCH 460/617] Convert generated eth_arb_mux to verilog parametrized module --- rtl/eth_arb_mux.py | 186 ------------------ rtl/eth_arb_mux.v | 316 ++++++++++++++++++++++++++++++ rtl/eth_arb_mux_2.v | 150 -------------- rtl/eth_arb_mux_4.v | 196 ------------------- rtl/eth_arb_mux_64.py | 190 ------------------ rtl/eth_arb_mux_64_2.v | 156 --------------- rtl/eth_arb_mux_64_4.v | 206 ------------------- tb/test_eth_arb_mux_4.py | 363 ++++++++++++++-------------------- tb/test_eth_arb_mux_4.v | 261 ++++++++++--------------- tb/test_eth_arb_mux_64_4.py | 380 ++++++++++++++---------------------- tb/test_eth_arb_mux_64_4.v | 276 ++++++++++---------------- 11 files changed, 825 insertions(+), 1855 deletions(-) delete mode 100755 rtl/eth_arb_mux.py create mode 100644 rtl/eth_arb_mux.v delete mode 100644 rtl/eth_arb_mux_2.v delete mode 100644 rtl/eth_arb_mux_4.v delete mode 100755 rtl/eth_arb_mux_64.py delete mode 100644 rtl/eth_arb_mux_64_2.v delete mode 100644 rtl/eth_arb_mux_64_4.v diff --git a/rtl/eth_arb_mux.py b/rtl/eth_arb_mux.py deleted file mode 100755 index 0e35ec61b..000000000 --- a/rtl/eth_arb_mux.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python -""" -Generates an arbitrated Ethernet mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "eth_arb_mux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port Ethernet arbitrated mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet {{n}} port arbitrated multiplexer - */ -module {{name}} # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_eth_hdr_valid, - output wire input_{{p}}_eth_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [7:0] input_{{p}}_eth_payload_tdata, - input wire input_{{p}}_eth_payload_tvalid, - output wire input_{{p}}_eth_payload_tready, - input wire input_{{p}}_eth_payload_tlast, - input wire input_{{p}}_eth_payload_tuser, -{% endfor %} - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser -); - -wire [{{n-1}}:0] request; -wire [{{n-1}}:0] acknowledge; -wire [{{n-1}}:0] grant; -wire grant_valid; -wire [{{w-1}}:0] grant_encoded; -{% for p in ports %} -assign acknowledge[{{p}}] = input_{{p}}_eth_payload_tvalid & input_{{p}}_eth_payload_tready & input_{{p}}_eth_payload_tlast; -assign request[{{p}}] = input_{{p}}_eth_hdr_valid; -{%- endfor %} - -// mux instance -eth_mux_{{n}} -mux_inst ( - .clk(clk), - .rst(rst), -{%- for p in ports %} - .input_{{p}}_eth_hdr_valid(input_{{p}}_eth_hdr_valid & grant[{{p}}]), - .input_{{p}}_eth_hdr_ready(input_{{p}}_eth_hdr_ready), - .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), - .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), - .input_{{p}}_eth_type(input_{{p}}_eth_type), - .input_{{p}}_eth_payload_tdata(input_{{p}}_eth_payload_tdata), - .input_{{p}}_eth_payload_tvalid(input_{{p}}_eth_payload_tvalid & grant[{{p}}]), - .input_{{p}}_eth_payload_tready(input_{{p}}_eth_payload_tready), - .input_{{p}}_eth_payload_tlast(input_{{p}}_eth_payload_tlast), - .input_{{p}}_eth_payload_tuser(input_{{p}}_eth_payload_tuser), -{%- endfor %} - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS({{n}}), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/eth_arb_mux.v b/rtl/eth_arb_mux.v new file mode 100644 index 000000000..a4d6d7cf9 --- /dev/null +++ b/rtl/eth_arb_mux.v @@ -0,0 +1,316 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Ethernet arbitrated multiplexer + */ +module eth_arb_mux # +( + parameter S_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame inputs + */ + input wire [S_COUNT-1:0] s_eth_hdr_valid, + output wire [S_COUNT-1:0] s_eth_hdr_ready, + input wire [S_COUNT*48-1:0] s_eth_dest_mac, + input wire [S_COUNT*48-1:0] s_eth_src_mac, + input wire [S_COUNT*16-1:0] s_eth_type, + input wire [S_COUNT*DATA_WIDTH-1:0] s_eth_payload_axis_tdata, + input wire [S_COUNT*KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep, + input wire [S_COUNT-1:0] s_eth_payload_axis_tvalid, + output wire [S_COUNT-1:0] s_eth_payload_axis_tready, + input wire [S_COUNT-1:0] s_eth_payload_axis_tlast, + input wire [S_COUNT*ID_WIDTH-1:0] s_eth_payload_axis_tid, + input wire [S_COUNT*DEST_WIDTH-1:0] s_eth_payload_axis_tdest, + input wire [S_COUNT*USER_WIDTH-1:0] s_eth_payload_axis_tuser, + + /* + * Ethernet frame output + */ + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [DATA_WIDTH-1:0] m_eth_payload_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire [ID_WIDTH-1:0] m_eth_payload_axis_tid, + output wire [DEST_WIDTH-1:0] m_eth_payload_axis_tdest, + output wire [USER_WIDTH-1:0] m_eth_payload_axis_tuser +); + +parameter CL_S_COUNT = $clog2(S_COUNT); + +reg frame_reg = 1'b0, frame_next; + +reg s_eth_hdr_ready_mask_reg = 1'b0, s_eth_hdr_ready_mask_next; + +reg m_eth_hdr_valid_reg = 1'b0, m_eth_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0, m_eth_dest_mac_next; +reg [47:0] m_eth_src_mac_reg = 48'd0, m_eth_src_mac_next; +reg [15:0] m_eth_type_reg = 16'd0, m_eth_type_next; + +wire [S_COUNT-1:0] request; +wire [S_COUNT-1:0] acknowledge; +wire [S_COUNT-1:0] grant; +wire grant_valid; +wire [CL_S_COUNT-1:0] grant_encoded; + +// internal datapath +reg [DATA_WIDTH-1:0] m_eth_payload_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep_int; +reg m_eth_payload_axis_tvalid_int; +reg m_eth_payload_axis_tready_int_reg = 1'b0; +reg m_eth_payload_axis_tlast_int; +reg [ID_WIDTH-1:0] m_eth_payload_axis_tid_int; +reg [DEST_WIDTH-1:0] m_eth_payload_axis_tdest_int; +reg [USER_WIDTH-1:0] m_eth_payload_axis_tuser_int; +wire m_eth_payload_axis_tready_int_early; + +assign s_eth_hdr_ready = (!s_eth_hdr_ready_mask_reg && grant_valid) << grant_encoded; + +assign s_eth_payload_axis_tready = (m_eth_payload_axis_tready_int_reg && grant_valid) << grant_encoded; + +assign m_eth_hdr_valid = m_eth_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; + +// mux for incoming packet +wire [DATA_WIDTH-1:0] current_s_tdata = s_eth_payload_axis_tdata[grant_encoded*DATA_WIDTH +: DATA_WIDTH]; +wire [KEEP_WIDTH-1:0] current_s_tkeep = s_eth_payload_axis_tkeep[grant_encoded*KEEP_WIDTH +: KEEP_WIDTH]; +wire current_s_tvalid = s_eth_payload_axis_tvalid[grant_encoded]; +wire current_s_tready = s_eth_payload_axis_tready[grant_encoded]; +wire current_s_tlast = s_eth_payload_axis_tlast[grant_encoded]; +wire [ID_WIDTH-1:0] current_s_tid = s_eth_payload_axis_tid[grant_encoded*ID_WIDTH +: ID_WIDTH]; +wire [DEST_WIDTH-1:0] current_s_tdest = s_eth_payload_axis_tdest[grant_encoded*DEST_WIDTH +: DEST_WIDTH]; +wire [USER_WIDTH-1:0] current_s_tuser = s_eth_payload_axis_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH]; + +// arbiter instance +arbiter #( + .PORTS(S_COUNT), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +generate + genvar n; + + for (n = 0; n < S_COUNT; n = n + 1) begin + assign request[n] = s_eth_hdr_valid[n] && !grant[n]; + assign acknowledge[n] = grant[n] && s_eth_payload_axis_tvalid[n] && s_eth_payload_axis_tready[n] && s_eth_payload_axis_tlast[n]; + end +endgenerate + +always @* begin + frame_next = frame_reg; + + s_eth_hdr_ready_mask_next = s_eth_hdr_ready_mask_reg; + + m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; + m_eth_dest_mac_next = m_eth_dest_mac_reg; + m_eth_src_mac_next = m_eth_src_mac_reg; + m_eth_type_next = m_eth_type_reg; + + if (s_eth_payload_axis_tvalid[grant_encoded] && s_eth_payload_axis_tready[grant_encoded]) begin + // end of frame detection + if (s_eth_payload_axis_tlast[grant_encoded]) begin + frame_next = 1'b0; + s_eth_hdr_ready_mask_next = 1'b0; + end + end + + if (!frame_reg && grant_valid) begin + // start of frame + frame_next = 1'b1; + + s_eth_hdr_ready_mask_next = 1'b1; + + m_eth_hdr_valid_next = 1'b1; + m_eth_dest_mac_next = s_eth_dest_mac[grant_encoded*48 +: 48]; + m_eth_src_mac_next = s_eth_src_mac[grant_encoded*48 +: 48]; + m_eth_type_next = s_eth_type[grant_encoded*16 +: 16]; + end + + // pass through selected packet data + m_eth_payload_axis_tdata_int = current_s_tdata; + m_eth_payload_axis_tkeep_int = current_s_tkeep; + m_eth_payload_axis_tvalid_int = current_s_tvalid && m_eth_payload_axis_tready_int_reg && grant_valid; + m_eth_payload_axis_tlast_int = current_s_tlast; + m_eth_payload_axis_tid_int = current_s_tid; + m_eth_payload_axis_tdest_int = current_s_tdest; + m_eth_payload_axis_tuser_int = current_s_tuser; +end + +always @(posedge clk) begin + if (rst) begin + frame_reg <= 1'b0; + s_eth_hdr_ready_mask_reg <= 1'b0; + m_eth_hdr_valid_reg <= 1'b0; + end else begin + frame_reg <= frame_next; + s_eth_hdr_ready_mask_reg <= s_eth_hdr_ready_mask_next; + m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; + end + + m_eth_dest_mac_reg <= m_eth_dest_mac_next; + m_eth_src_mac_reg <= m_eth_src_mac_next; + m_eth_type_reg <= m_eth_type_next; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; +reg m_eth_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_eth_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_eth_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_eth_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; +reg temp_m_eth_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_eth_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_eth_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_eth_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_eth_payload_axis_temp_to_output; + +assign m_eth_payload_axis_tdata = m_eth_payload_axis_tdata_reg; +assign m_eth_payload_axis_tkeep = KEEP_ENABLE ? m_eth_payload_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; +assign m_eth_payload_axis_tlast = m_eth_payload_axis_tlast_reg; +assign m_eth_payload_axis_tid = ID_ENABLE ? m_eth_payload_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_eth_payload_axis_tdest = DEST_ENABLE ? m_eth_payload_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_eth_payload_axis_tuser = USER_ENABLE ? m_eth_payload_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_eth_payload_axis_tready_int_early = m_eth_payload_axis_tready || (!temp_m_eth_payload_axis_tvalid_reg && (!m_eth_payload_axis_tvalid_reg || !m_eth_payload_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b0; + + if (m_eth_payload_axis_tready_int_reg) begin + // input is ready + if (m_eth_payload_axis_tready || !m_eth_payload_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_eth_payload_axis_tready) begin + // input is not ready, but output is ready + m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_eth_payload_axis_tvalid_reg <= 1'b0; + m_eth_payload_axis_tready_int_reg <= 1'b0; + temp_m_eth_payload_axis_tvalid_reg <= 1'b0; + end else begin + m_eth_payload_axis_tvalid_reg <= m_eth_payload_axis_tvalid_next; + m_eth_payload_axis_tready_int_reg <= m_eth_payload_axis_tready_int_early; + temp_m_eth_payload_axis_tvalid_reg <= temp_m_eth_payload_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + m_eth_payload_axis_tid_reg <= m_eth_payload_axis_tid_int; + m_eth_payload_axis_tdest_reg <= m_eth_payload_axis_tdest_int; + m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end else if (store_eth_payload_axis_temp_to_output) begin + m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; + m_eth_payload_axis_tkeep_reg <= temp_m_eth_payload_axis_tkeep_reg; + m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; + m_eth_payload_axis_tid_reg <= temp_m_eth_payload_axis_tid_reg; + m_eth_payload_axis_tdest_reg <= temp_m_eth_payload_axis_tdest_reg; + m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + temp_m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + temp_m_eth_payload_axis_tid_reg <= m_eth_payload_axis_tid_int; + temp_m_eth_payload_axis_tdest_reg <= m_eth_payload_axis_tdest_int; + temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/eth_arb_mux_2.v b/rtl/eth_arb_mux_2.v deleted file mode 100644 index 705830b81..000000000 --- a/rtl/eth_arb_mux_2.v +++ /dev/null @@ -1,150 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet 2 port arbitrated multiplexer - */ -module eth_arb_mux_2 # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ - input wire input_0_eth_hdr_valid, - output wire input_0_eth_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [7:0] input_0_eth_payload_tdata, - input wire input_0_eth_payload_tvalid, - output wire input_0_eth_payload_tready, - input wire input_0_eth_payload_tlast, - input wire input_0_eth_payload_tuser, - - input wire input_1_eth_hdr_valid, - output wire input_1_eth_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [7:0] input_1_eth_payload_tdata, - input wire input_1_eth_payload_tvalid, - output wire input_1_eth_payload_tready, - input wire input_1_eth_payload_tlast, - input wire input_1_eth_payload_tuser, - - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser -); - -wire [1:0] request; -wire [1:0] acknowledge; -wire [1:0] grant; -wire grant_valid; -wire [0:0] grant_encoded; - -assign acknowledge[0] = input_0_eth_payload_tvalid & input_0_eth_payload_tready & input_0_eth_payload_tlast; -assign request[0] = input_0_eth_hdr_valid; -assign acknowledge[1] = input_1_eth_payload_tvalid & input_1_eth_payload_tready & input_1_eth_payload_tlast; -assign request[1] = input_1_eth_hdr_valid; - -// mux instance -eth_mux_2 -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_eth_hdr_valid(input_0_eth_hdr_valid & grant[0]), - .input_0_eth_hdr_ready(input_0_eth_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_eth_payload_tdata(input_0_eth_payload_tdata), - .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid & grant[0]), - .input_0_eth_payload_tready(input_0_eth_payload_tready), - .input_0_eth_payload_tlast(input_0_eth_payload_tlast), - .input_0_eth_payload_tuser(input_0_eth_payload_tuser), - .input_1_eth_hdr_valid(input_1_eth_hdr_valid & grant[1]), - .input_1_eth_hdr_ready(input_1_eth_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_eth_payload_tdata(input_1_eth_payload_tdata), - .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid & grant[1]), - .input_1_eth_payload_tready(input_1_eth_payload_tready), - .input_1_eth_payload_tlast(input_1_eth_payload_tlast), - .input_1_eth_payload_tuser(input_1_eth_payload_tuser), - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(2), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/rtl/eth_arb_mux_4.v b/rtl/eth_arb_mux_4.v deleted file mode 100644 index 3a8c1e6e0..000000000 --- a/rtl/eth_arb_mux_4.v +++ /dev/null @@ -1,196 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet 4 port arbitrated multiplexer - */ -module eth_arb_mux_4 # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ - input wire input_0_eth_hdr_valid, - output wire input_0_eth_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [7:0] input_0_eth_payload_tdata, - input wire input_0_eth_payload_tvalid, - output wire input_0_eth_payload_tready, - input wire input_0_eth_payload_tlast, - input wire input_0_eth_payload_tuser, - - input wire input_1_eth_hdr_valid, - output wire input_1_eth_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [7:0] input_1_eth_payload_tdata, - input wire input_1_eth_payload_tvalid, - output wire input_1_eth_payload_tready, - input wire input_1_eth_payload_tlast, - input wire input_1_eth_payload_tuser, - - input wire input_2_eth_hdr_valid, - output wire input_2_eth_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [7:0] input_2_eth_payload_tdata, - input wire input_2_eth_payload_tvalid, - output wire input_2_eth_payload_tready, - input wire input_2_eth_payload_tlast, - input wire input_2_eth_payload_tuser, - - input wire input_3_eth_hdr_valid, - output wire input_3_eth_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [7:0] input_3_eth_payload_tdata, - input wire input_3_eth_payload_tvalid, - output wire input_3_eth_payload_tready, - input wire input_3_eth_payload_tlast, - input wire input_3_eth_payload_tuser, - - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser -); - -wire [3:0] request; -wire [3:0] acknowledge; -wire [3:0] grant; -wire grant_valid; -wire [1:0] grant_encoded; - -assign acknowledge[0] = input_0_eth_payload_tvalid & input_0_eth_payload_tready & input_0_eth_payload_tlast; -assign request[0] = input_0_eth_hdr_valid; -assign acknowledge[1] = input_1_eth_payload_tvalid & input_1_eth_payload_tready & input_1_eth_payload_tlast; -assign request[1] = input_1_eth_hdr_valid; -assign acknowledge[2] = input_2_eth_payload_tvalid & input_2_eth_payload_tready & input_2_eth_payload_tlast; -assign request[2] = input_2_eth_hdr_valid; -assign acknowledge[3] = input_3_eth_payload_tvalid & input_3_eth_payload_tready & input_3_eth_payload_tlast; -assign request[3] = input_3_eth_hdr_valid; - -// mux instance -eth_mux_4 -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_eth_hdr_valid(input_0_eth_hdr_valid & grant[0]), - .input_0_eth_hdr_ready(input_0_eth_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_eth_payload_tdata(input_0_eth_payload_tdata), - .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid & grant[0]), - .input_0_eth_payload_tready(input_0_eth_payload_tready), - .input_0_eth_payload_tlast(input_0_eth_payload_tlast), - .input_0_eth_payload_tuser(input_0_eth_payload_tuser), - .input_1_eth_hdr_valid(input_1_eth_hdr_valid & grant[1]), - .input_1_eth_hdr_ready(input_1_eth_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_eth_payload_tdata(input_1_eth_payload_tdata), - .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid & grant[1]), - .input_1_eth_payload_tready(input_1_eth_payload_tready), - .input_1_eth_payload_tlast(input_1_eth_payload_tlast), - .input_1_eth_payload_tuser(input_1_eth_payload_tuser), - .input_2_eth_hdr_valid(input_2_eth_hdr_valid & grant[2]), - .input_2_eth_hdr_ready(input_2_eth_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_eth_payload_tdata(input_2_eth_payload_tdata), - .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid & grant[2]), - .input_2_eth_payload_tready(input_2_eth_payload_tready), - .input_2_eth_payload_tlast(input_2_eth_payload_tlast), - .input_2_eth_payload_tuser(input_2_eth_payload_tuser), - .input_3_eth_hdr_valid(input_3_eth_hdr_valid & grant[3]), - .input_3_eth_hdr_ready(input_3_eth_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_eth_payload_tdata(input_3_eth_payload_tdata), - .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid & grant[3]), - .input_3_eth_payload_tready(input_3_eth_payload_tready), - .input_3_eth_payload_tlast(input_3_eth_payload_tlast), - .input_3_eth_payload_tuser(input_3_eth_payload_tuser), - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/rtl/eth_arb_mux_64.py b/rtl/eth_arb_mux_64.py deleted file mode 100755 index 7ed719d01..000000000 --- a/rtl/eth_arb_mux_64.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python -""" -Generates an arbitrated Ethernet mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "eth_arb_mux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port Ethernet arbitrated mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet {{n}} port arbitrated multiplexer (64 bit datapath) - */ -module {{name}} # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_eth_hdr_valid, - output wire input_{{p}}_eth_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [63:0] input_{{p}}_eth_payload_tdata, - input wire [7:0] input_{{p}}_eth_payload_tkeep, - input wire input_{{p}}_eth_payload_tvalid, - output wire input_{{p}}_eth_payload_tready, - input wire input_{{p}}_eth_payload_tlast, - input wire input_{{p}}_eth_payload_tuser, -{% endfor %} - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser -); - -wire [{{n-1}}:0] request; -wire [{{n-1}}:0] acknowledge; -wire [{{n-1}}:0] grant; -wire grant_valid; -wire [{{w-1}}:0] grant_encoded; -{% for p in ports %} -assign acknowledge[{{p}}] = input_{{p}}_eth_payload_tvalid & input_{{p}}_eth_payload_tready & input_{{p}}_eth_payload_tlast; -assign request[{{p}}] = input_{{p}}_eth_hdr_valid; -{%- endfor %} - -// mux instance -eth_mux_64_{{n}} -mux_inst ( - .clk(clk), - .rst(rst), -{%- for p in ports %} - .input_{{p}}_eth_hdr_valid(input_{{p}}_eth_hdr_valid & grant[{{p}}]), - .input_{{p}}_eth_hdr_ready(input_{{p}}_eth_hdr_ready), - .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), - .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), - .input_{{p}}_eth_type(input_{{p}}_eth_type), - .input_{{p}}_eth_payload_tdata(input_{{p}}_eth_payload_tdata), - .input_{{p}}_eth_payload_tkeep(input_{{p}}_eth_payload_tkeep), - .input_{{p}}_eth_payload_tvalid(input_{{p}}_eth_payload_tvalid & grant[{{p}}]), - .input_{{p}}_eth_payload_tready(input_{{p}}_eth_payload_tready), - .input_{{p}}_eth_payload_tlast(input_{{p}}_eth_payload_tlast), - .input_{{p}}_eth_payload_tuser(input_{{p}}_eth_payload_tuser), -{%- endfor %} - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS({{n}}), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/eth_arb_mux_64_2.v b/rtl/eth_arb_mux_64_2.v deleted file mode 100644 index 7e8553be4..000000000 --- a/rtl/eth_arb_mux_64_2.v +++ /dev/null @@ -1,156 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet 2 port arbitrated multiplexer (64 bit datapath) - */ -module eth_arb_mux_64_2 # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ - input wire input_0_eth_hdr_valid, - output wire input_0_eth_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [63:0] input_0_eth_payload_tdata, - input wire [7:0] input_0_eth_payload_tkeep, - input wire input_0_eth_payload_tvalid, - output wire input_0_eth_payload_tready, - input wire input_0_eth_payload_tlast, - input wire input_0_eth_payload_tuser, - - input wire input_1_eth_hdr_valid, - output wire input_1_eth_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [63:0] input_1_eth_payload_tdata, - input wire [7:0] input_1_eth_payload_tkeep, - input wire input_1_eth_payload_tvalid, - output wire input_1_eth_payload_tready, - input wire input_1_eth_payload_tlast, - input wire input_1_eth_payload_tuser, - - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser -); - -wire [1:0] request; -wire [1:0] acknowledge; -wire [1:0] grant; -wire grant_valid; -wire [0:0] grant_encoded; - -assign acknowledge[0] = input_0_eth_payload_tvalid & input_0_eth_payload_tready & input_0_eth_payload_tlast; -assign request[0] = input_0_eth_hdr_valid; -assign acknowledge[1] = input_1_eth_payload_tvalid & input_1_eth_payload_tready & input_1_eth_payload_tlast; -assign request[1] = input_1_eth_hdr_valid; - -// mux instance -eth_mux_64_2 -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_eth_hdr_valid(input_0_eth_hdr_valid & grant[0]), - .input_0_eth_hdr_ready(input_0_eth_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_eth_payload_tdata(input_0_eth_payload_tdata), - .input_0_eth_payload_tkeep(input_0_eth_payload_tkeep), - .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid & grant[0]), - .input_0_eth_payload_tready(input_0_eth_payload_tready), - .input_0_eth_payload_tlast(input_0_eth_payload_tlast), - .input_0_eth_payload_tuser(input_0_eth_payload_tuser), - .input_1_eth_hdr_valid(input_1_eth_hdr_valid & grant[1]), - .input_1_eth_hdr_ready(input_1_eth_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_eth_payload_tdata(input_1_eth_payload_tdata), - .input_1_eth_payload_tkeep(input_1_eth_payload_tkeep), - .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid & grant[1]), - .input_1_eth_payload_tready(input_1_eth_payload_tready), - .input_1_eth_payload_tlast(input_1_eth_payload_tlast), - .input_1_eth_payload_tuser(input_1_eth_payload_tuser), - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(2), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/rtl/eth_arb_mux_64_4.v b/rtl/eth_arb_mux_64_4.v deleted file mode 100644 index b46b088c4..000000000 --- a/rtl/eth_arb_mux_64_4.v +++ /dev/null @@ -1,206 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet 4 port arbitrated multiplexer (64 bit datapath) - */ -module eth_arb_mux_64_4 # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * Ethernet frame inputs - */ - input wire input_0_eth_hdr_valid, - output wire input_0_eth_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [63:0] input_0_eth_payload_tdata, - input wire [7:0] input_0_eth_payload_tkeep, - input wire input_0_eth_payload_tvalid, - output wire input_0_eth_payload_tready, - input wire input_0_eth_payload_tlast, - input wire input_0_eth_payload_tuser, - - input wire input_1_eth_hdr_valid, - output wire input_1_eth_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [63:0] input_1_eth_payload_tdata, - input wire [7:0] input_1_eth_payload_tkeep, - input wire input_1_eth_payload_tvalid, - output wire input_1_eth_payload_tready, - input wire input_1_eth_payload_tlast, - input wire input_1_eth_payload_tuser, - - input wire input_2_eth_hdr_valid, - output wire input_2_eth_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [63:0] input_2_eth_payload_tdata, - input wire [7:0] input_2_eth_payload_tkeep, - input wire input_2_eth_payload_tvalid, - output wire input_2_eth_payload_tready, - input wire input_2_eth_payload_tlast, - input wire input_2_eth_payload_tuser, - - input wire input_3_eth_hdr_valid, - output wire input_3_eth_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [63:0] input_3_eth_payload_tdata, - input wire [7:0] input_3_eth_payload_tkeep, - input wire input_3_eth_payload_tvalid, - output wire input_3_eth_payload_tready, - input wire input_3_eth_payload_tlast, - input wire input_3_eth_payload_tuser, - - /* - * Ethernet frame output - */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser -); - -wire [3:0] request; -wire [3:0] acknowledge; -wire [3:0] grant; -wire grant_valid; -wire [1:0] grant_encoded; - -assign acknowledge[0] = input_0_eth_payload_tvalid & input_0_eth_payload_tready & input_0_eth_payload_tlast; -assign request[0] = input_0_eth_hdr_valid; -assign acknowledge[1] = input_1_eth_payload_tvalid & input_1_eth_payload_tready & input_1_eth_payload_tlast; -assign request[1] = input_1_eth_hdr_valid; -assign acknowledge[2] = input_2_eth_payload_tvalid & input_2_eth_payload_tready & input_2_eth_payload_tlast; -assign request[2] = input_2_eth_hdr_valid; -assign acknowledge[3] = input_3_eth_payload_tvalid & input_3_eth_payload_tready & input_3_eth_payload_tlast; -assign request[3] = input_3_eth_hdr_valid; - -// mux instance -eth_mux_64_4 -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_eth_hdr_valid(input_0_eth_hdr_valid & grant[0]), - .input_0_eth_hdr_ready(input_0_eth_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_eth_payload_tdata(input_0_eth_payload_tdata), - .input_0_eth_payload_tkeep(input_0_eth_payload_tkeep), - .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid & grant[0]), - .input_0_eth_payload_tready(input_0_eth_payload_tready), - .input_0_eth_payload_tlast(input_0_eth_payload_tlast), - .input_0_eth_payload_tuser(input_0_eth_payload_tuser), - .input_1_eth_hdr_valid(input_1_eth_hdr_valid & grant[1]), - .input_1_eth_hdr_ready(input_1_eth_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_eth_payload_tdata(input_1_eth_payload_tdata), - .input_1_eth_payload_tkeep(input_1_eth_payload_tkeep), - .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid & grant[1]), - .input_1_eth_payload_tready(input_1_eth_payload_tready), - .input_1_eth_payload_tlast(input_1_eth_payload_tlast), - .input_1_eth_payload_tuser(input_1_eth_payload_tuser), - .input_2_eth_hdr_valid(input_2_eth_hdr_valid & grant[2]), - .input_2_eth_hdr_ready(input_2_eth_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_eth_payload_tdata(input_2_eth_payload_tdata), - .input_2_eth_payload_tkeep(input_2_eth_payload_tkeep), - .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid & grant[2]), - .input_2_eth_payload_tready(input_2_eth_payload_tready), - .input_2_eth_payload_tlast(input_2_eth_payload_tlast), - .input_2_eth_payload_tuser(input_2_eth_payload_tuser), - .input_3_eth_hdr_valid(input_3_eth_hdr_valid & grant[3]), - .input_3_eth_hdr_ready(input_3_eth_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_eth_payload_tdata(input_3_eth_payload_tdata), - .input_3_eth_payload_tkeep(input_3_eth_payload_tkeep), - .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid & grant[3]), - .input_3_eth_payload_tready(input_3_eth_payload_tready), - .input_3_eth_payload_tlast(input_3_eth_payload_tlast), - .input_3_eth_payload_tuser(input_3_eth_payload_tuser), - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/tb/test_eth_arb_mux_4.py b/tb/test_eth_arb_mux_4.py index 55f2308e8..bd4c62c4b 100755 --- a/tb/test_eth_arb_mux_4.py +++ b/tb/test_eth_arb_mux_4.py @@ -28,13 +28,12 @@ import os import eth_ep -module = 'eth_arb_mux_4' -testbench = 'test_%s' % module +module = 'eth_arb_mux' +testbench = 'test_%s_4' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_mux_4.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -45,164 +44,118 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + ARB_TYPE = "PRIORITY" + LSB_PRIORITY = "HIGH" + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_eth_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_eth_payload_tdata = Signal(intbv(0)[8:]) - input_0_eth_payload_tvalid = Signal(bool(0)) - input_0_eth_payload_tlast = Signal(bool(0)) - input_0_eth_payload_tuser = Signal(bool(0)) - input_1_eth_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_eth_payload_tdata = Signal(intbv(0)[8:]) - input_1_eth_payload_tvalid = Signal(bool(0)) - input_1_eth_payload_tlast = Signal(bool(0)) - input_1_eth_payload_tuser = Signal(bool(0)) - input_2_eth_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_eth_payload_tdata = Signal(intbv(0)[8:]) - input_2_eth_payload_tvalid = Signal(bool(0)) - input_2_eth_payload_tlast = Signal(bool(0)) - input_2_eth_payload_tuser = Signal(bool(0)) - input_3_eth_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_eth_payload_tdata = Signal(intbv(0)[8:]) - input_3_eth_payload_tvalid = Signal(bool(0)) - input_3_eth_payload_tlast = Signal(bool(0)) - input_3_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_eth_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + s_eth_hdr_valid = ConcatSignal(*reversed(s_eth_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_eth_payload_axis_tdata = ConcatSignal(*reversed(s_eth_payload_axis_tdata_list)) + s_eth_payload_axis_tkeep = ConcatSignal(*reversed(s_eth_payload_axis_tkeep_list)) + s_eth_payload_axis_tvalid = ConcatSignal(*reversed(s_eth_payload_axis_tvalid_list)) + s_eth_payload_axis_tlast = ConcatSignal(*reversed(s_eth_payload_axis_tlast_list)) + s_eth_payload_axis_tid = ConcatSignal(*reversed(s_eth_payload_axis_tid_list)) + s_eth_payload_axis_tdest = ConcatSignal(*reversed(s_eth_payload_axis_tdest_list)) + s_eth_payload_axis_tuser = ConcatSignal(*reversed(s_eth_payload_axis_tuser_list)) + + m_eth_hdr_ready = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) # Outputs - input_0_eth_hdr_ready = Signal(bool(0)) - input_0_eth_payload_tready = Signal(bool(0)) - input_1_eth_hdr_ready = Signal(bool(0)) - input_1_eth_payload_tready = Signal(bool(0)) - input_2_eth_hdr_ready = Signal(bool(0)) - input_2_eth_payload_tready = Signal(bool(0)) - input_3_eth_hdr_ready = Signal(bool(0)) - input_3_eth_payload_tready = Signal(bool(0)) + s_eth_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_eth_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready_list = [s_eth_hdr_ready(i) for i in range(S_COUNT)] + s_eth_payload_axis_tready_list = [s_eth_payload_axis_tready(i) for i in range(S_COUNT)] + + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_eth_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_eth_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_eth_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = eth_ep.EthFrameSource() + for k in range(S_COUNT): + s = eth_ep.EthFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - eth_hdr_ready=input_0_eth_hdr_ready, - eth_hdr_valid=input_0_eth_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - eth_type=input_0_eth_type, - eth_payload_tdata=input_0_eth_payload_tdata, - eth_payload_tvalid=input_0_eth_payload_tvalid, - eth_payload_tready=input_0_eth_payload_tready, - eth_payload_tlast=input_0_eth_payload_tlast, - eth_payload_tuser=input_0_eth_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = eth_ep.EthFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - eth_hdr_ready=input_1_eth_hdr_ready, - eth_hdr_valid=input_1_eth_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - eth_type=input_1_eth_type, - eth_payload_tdata=input_1_eth_payload_tdata, - eth_payload_tvalid=input_1_eth_payload_tvalid, - eth_payload_tready=input_1_eth_payload_tready, - eth_payload_tlast=input_1_eth_payload_tlast, - eth_payload_tuser=input_1_eth_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = eth_ep.EthFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - eth_hdr_ready=input_2_eth_hdr_ready, - eth_hdr_valid=input_2_eth_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - eth_payload_tdata=input_2_eth_payload_tdata, - eth_payload_tvalid=input_2_eth_payload_tvalid, - eth_payload_tready=input_2_eth_payload_tready, - eth_payload_tlast=input_2_eth_payload_tlast, - eth_payload_tuser=input_2_eth_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = eth_ep.EthFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - eth_hdr_ready=input_3_eth_hdr_ready, - eth_hdr_valid=input_3_eth_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - eth_payload_tdata=input_3_eth_payload_tdata, - eth_payload_tvalid=input_3_eth_payload_tvalid, - eth_payload_tready=input_3_eth_payload_tready, - eth_payload_tlast=input_3_eth_payload_tlast, - eth_payload_tuser=input_3_eth_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + eth_hdr_ready=s_eth_hdr_ready_list[k], + eth_hdr_valid=s_eth_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + eth_payload_tdata=s_eth_payload_axis_tdata_list[k], + eth_payload_tkeep=s_eth_payload_axis_tkeep_list[k], + eth_payload_tvalid=s_eth_payload_axis_tvalid_list[k], + eth_payload_tready=s_eth_payload_axis_tready_list[k], + eth_payload_tlast=s_eth_payload_axis_tlast_list[k], + eth_payload_tuser=s_eth_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = eth_ep.EthFrameSink() sink_logic = sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -217,57 +170,33 @@ def bench(): rst=rst, current_test=current_test, - input_0_eth_hdr_valid=input_0_eth_hdr_valid, - input_0_eth_hdr_ready=input_0_eth_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_eth_payload_tdata=input_0_eth_payload_tdata, - input_0_eth_payload_tvalid=input_0_eth_payload_tvalid, - input_0_eth_payload_tready=input_0_eth_payload_tready, - input_0_eth_payload_tlast=input_0_eth_payload_tlast, - input_0_eth_payload_tuser=input_0_eth_payload_tuser, - input_1_eth_hdr_valid=input_1_eth_hdr_valid, - input_1_eth_hdr_ready=input_1_eth_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_eth_payload_tdata=input_1_eth_payload_tdata, - input_1_eth_payload_tvalid=input_1_eth_payload_tvalid, - input_1_eth_payload_tready=input_1_eth_payload_tready, - input_1_eth_payload_tlast=input_1_eth_payload_tlast, - input_1_eth_payload_tuser=input_1_eth_payload_tuser, - input_2_eth_hdr_valid=input_2_eth_hdr_valid, - input_2_eth_hdr_ready=input_2_eth_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_eth_payload_tdata=input_2_eth_payload_tdata, - input_2_eth_payload_tvalid=input_2_eth_payload_tvalid, - input_2_eth_payload_tready=input_2_eth_payload_tready, - input_2_eth_payload_tlast=input_2_eth_payload_tlast, - input_2_eth_payload_tuser=input_2_eth_payload_tuser, - input_3_eth_hdr_valid=input_3_eth_hdr_valid, - input_3_eth_hdr_ready=input_3_eth_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_eth_payload_tdata=input_3_eth_payload_tdata, - input_3_eth_payload_tvalid=input_3_eth_payload_tvalid, - input_3_eth_payload_tready=input_3_eth_payload_tready, - input_3_eth_payload_tlast=input_3_eth_payload_tlast, - input_3_eth_payload_tuser=input_3_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tid=s_eth_payload_axis_tid, + s_eth_payload_axis_tdest=s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tid=m_eth_payload_axis_tid, + m_eth_payload_axis_tdest=m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser ) @always(delay(4)) @@ -297,7 +226,7 @@ def bench(): test_frame.eth_type = 0x8000 test_frame.payload = bytearray(range(32)) - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -316,7 +245,7 @@ def bench(): test_frame.eth_type = 0x8000 test_frame.payload = bytearray(range(32)) - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -340,8 +269,8 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -370,8 +299,8 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -400,23 +329,23 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_eth_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge yield sink.wait() @@ -446,12 +375,12 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + while s_eth_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -486,17 +415,17 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) yield clk.posedge yield delay(800) yield clk.posedge - source_1.send(test_frame1) + source_list[1].send(test_frame1) yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_eth_arb_mux_4.v b/tb/test_eth_arb_mux_4.v index 55e8bb8dd..6c98fb762 100644 --- a/tb/test_eth_arb_mux_4.v +++ b/tb/test_eth_arb_mux_4.v @@ -27,69 +27,59 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for eth_arb_mux_4 + * Testbench for eth_arb_mux */ module test_eth_arb_mux_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter ARB_TYPE = "PRIORITY"; +parameter LSB_PRIORITY = "HIGH"; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_eth_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [7:0] input_0_eth_payload_tdata = 0; -reg input_0_eth_payload_tvalid = 0; -reg input_0_eth_payload_tlast = 0; -reg input_0_eth_payload_tuser = 0; -reg input_1_eth_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [7:0] input_1_eth_payload_tdata = 0; -reg input_1_eth_payload_tvalid = 0; -reg input_1_eth_payload_tlast = 0; -reg input_1_eth_payload_tuser = 0; -reg input_2_eth_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [7:0] input_2_eth_payload_tdata = 0; -reg input_2_eth_payload_tvalid = 0; -reg input_2_eth_payload_tlast = 0; -reg input_2_eth_payload_tuser = 0; -reg input_3_eth_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [7:0] input_3_eth_payload_tdata = 0; -reg input_3_eth_payload_tvalid = 0; -reg input_3_eth_payload_tlast = 0; -reg input_3_eth_payload_tuser = 0; +reg [S_COUNT-1:0] s_eth_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_eth_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_eth_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_eth_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_eth_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_eth_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_eth_payload_axis_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; // Outputs -wire input_0_eth_payload_tready; -wire input_0_eth_hdr_ready; -wire input_1_eth_payload_tready; -wire input_1_eth_hdr_ready; -wire input_2_eth_payload_tready; -wire input_2_eth_hdr_ready; -wire input_3_eth_payload_tready; -wire input_3_eth_hdr_ready; +wire [S_COUNT-1:0] s_eth_hdr_ready; +wire [S_COUNT-1:0] s_eth_payload_axis_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [7:0] output_eth_payload_tdata; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [DATA_WIDTH-1:0] m_eth_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_eth_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_eth_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_eth_payload_axis_tuser; initial begin // myhdl integration @@ -97,58 +87,34 @@ initial begin clk, rst, current_test, - input_0_eth_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_eth_payload_tdata, - input_0_eth_payload_tvalid, - input_0_eth_payload_tlast, - input_0_eth_payload_tuser, - input_1_eth_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_eth_payload_tdata, - input_1_eth_payload_tvalid, - input_1_eth_payload_tlast, - input_1_eth_payload_tuser, - input_2_eth_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_eth_payload_tdata, - input_2_eth_payload_tvalid, - input_2_eth_payload_tlast, - input_2_eth_payload_tuser, - input_3_eth_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_eth_payload_tdata, - input_3_eth_payload_tvalid, - input_3_eth_payload_tlast, - input_3_eth_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tid, + s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready ); $to_myhdl( - input_0_eth_hdr_ready, - input_0_eth_payload_tready, - input_1_eth_hdr_ready, - input_1_eth_payload_tready, - input_2_eth_hdr_ready, - input_2_eth_payload_tready, - input_3_eth_hdr_ready, - input_3_eth_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tid, + m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser ); // dump file @@ -156,62 +122,51 @@ initial begin $dumpvars(0, test_eth_arb_mux_4); end -eth_arb_mux_4 +eth_arb_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) +) UUT ( .clk(clk), .rst(rst), // Ethernet frame inputs - .input_0_eth_hdr_valid(input_0_eth_hdr_valid), - .input_0_eth_hdr_ready(input_0_eth_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_eth_payload_tdata(input_0_eth_payload_tdata), - .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid), - .input_0_eth_payload_tready(input_0_eth_payload_tready), - .input_0_eth_payload_tlast(input_0_eth_payload_tlast), - .input_0_eth_payload_tuser(input_0_eth_payload_tuser), - .input_1_eth_hdr_valid(input_1_eth_hdr_valid), - .input_1_eth_hdr_ready(input_1_eth_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_eth_payload_tdata(input_1_eth_payload_tdata), - .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid), - .input_1_eth_payload_tready(input_1_eth_payload_tready), - .input_1_eth_payload_tlast(input_1_eth_payload_tlast), - .input_1_eth_payload_tuser(input_1_eth_payload_tuser), - .input_2_eth_hdr_valid(input_2_eth_hdr_valid), - .input_2_eth_hdr_ready(input_2_eth_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_eth_payload_tdata(input_2_eth_payload_tdata), - .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid), - .input_2_eth_payload_tready(input_2_eth_payload_tready), - .input_2_eth_payload_tlast(input_2_eth_payload_tlast), - .input_2_eth_payload_tuser(input_2_eth_payload_tuser), - .input_3_eth_hdr_valid(input_3_eth_hdr_valid), - .input_3_eth_hdr_ready(input_3_eth_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_eth_payload_tdata(input_3_eth_payload_tdata), - .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid), - .input_3_eth_payload_tready(input_3_eth_payload_tready), - .input_3_eth_payload_tlast(input_3_eth_payload_tlast), - .input_3_eth_payload_tuser(input_3_eth_payload_tuser), - // Eth frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser) + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tid(s_eth_payload_axis_tid), + .s_eth_payload_axis_tdest(s_eth_payload_axis_tdest), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tid(m_eth_payload_axis_tid), + .m_eth_payload_axis_tdest(m_eth_payload_axis_tdest), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser) ); endmodule diff --git a/tb/test_eth_arb_mux_64_4.py b/tb/test_eth_arb_mux_64_4.py index e90d9208c..86104b6d6 100755 --- a/tb/test_eth_arb_mux_64_4.py +++ b/tb/test_eth_arb_mux_64_4.py @@ -28,13 +28,12 @@ import os import eth_ep -module = 'eth_arb_mux_64_4' -testbench = 'test_%s' % module +module = 'eth_arb_mux' +testbench = 'test_%s_64_4' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/eth_mux_64_4.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -45,174 +44,118 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + ARB_TYPE = "PRIORITY" + LSB_PRIORITY = "HIGH" + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_eth_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_eth_payload_tdata = Signal(intbv(0)[64:]) - input_0_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_0_eth_payload_tvalid = Signal(bool(0)) - input_0_eth_payload_tlast = Signal(bool(0)) - input_0_eth_payload_tuser = Signal(bool(0)) - input_1_eth_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_eth_payload_tdata = Signal(intbv(0)[64:]) - input_1_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_1_eth_payload_tvalid = Signal(bool(0)) - input_1_eth_payload_tlast = Signal(bool(0)) - input_1_eth_payload_tuser = Signal(bool(0)) - input_2_eth_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_eth_payload_tdata = Signal(intbv(0)[64:]) - input_2_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_2_eth_payload_tvalid = Signal(bool(0)) - input_2_eth_payload_tlast = Signal(bool(0)) - input_2_eth_payload_tuser = Signal(bool(0)) - input_3_eth_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_eth_payload_tdata = Signal(intbv(0)[64:]) - input_3_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_3_eth_payload_tvalid = Signal(bool(0)) - input_3_eth_payload_tlast = Signal(bool(0)) - input_3_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_eth_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_eth_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + s_eth_hdr_valid = ConcatSignal(*reversed(s_eth_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_eth_payload_axis_tdata = ConcatSignal(*reversed(s_eth_payload_axis_tdata_list)) + s_eth_payload_axis_tkeep = ConcatSignal(*reversed(s_eth_payload_axis_tkeep_list)) + s_eth_payload_axis_tvalid = ConcatSignal(*reversed(s_eth_payload_axis_tvalid_list)) + s_eth_payload_axis_tlast = ConcatSignal(*reversed(s_eth_payload_axis_tlast_list)) + s_eth_payload_axis_tid = ConcatSignal(*reversed(s_eth_payload_axis_tid_list)) + s_eth_payload_axis_tdest = ConcatSignal(*reversed(s_eth_payload_axis_tdest_list)) + s_eth_payload_axis_tuser = ConcatSignal(*reversed(s_eth_payload_axis_tuser_list)) + + m_eth_hdr_ready = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) # Outputs - input_0_eth_hdr_ready = Signal(bool(0)) - input_0_eth_payload_tready = Signal(bool(0)) - input_1_eth_hdr_ready = Signal(bool(0)) - input_1_eth_payload_tready = Signal(bool(0)) - input_2_eth_hdr_ready = Signal(bool(0)) - input_2_eth_payload_tready = Signal(bool(0)) - input_3_eth_hdr_ready = Signal(bool(0)) - input_3_eth_payload_tready = Signal(bool(0)) + s_eth_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_eth_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[64:]) - output_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready_list = [s_eth_hdr_ready(i) for i in range(S_COUNT)] + s_eth_payload_axis_tready_list = [s_eth_payload_axis_tready(i) for i in range(S_COUNT)] + + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_eth_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_eth_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_eth_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = eth_ep.EthFrameSource() + for k in range(S_COUNT): + s = eth_ep.EthFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - eth_hdr_ready=input_0_eth_hdr_ready, - eth_hdr_valid=input_0_eth_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - eth_type=input_0_eth_type, - eth_payload_tdata=input_0_eth_payload_tdata, - eth_payload_tkeep=input_0_eth_payload_tkeep, - eth_payload_tvalid=input_0_eth_payload_tvalid, - eth_payload_tready=input_0_eth_payload_tready, - eth_payload_tlast=input_0_eth_payload_tlast, - eth_payload_tuser=input_0_eth_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = eth_ep.EthFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - eth_hdr_ready=input_1_eth_hdr_ready, - eth_hdr_valid=input_1_eth_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - eth_type=input_1_eth_type, - eth_payload_tdata=input_1_eth_payload_tdata, - eth_payload_tkeep=input_1_eth_payload_tkeep, - eth_payload_tvalid=input_1_eth_payload_tvalid, - eth_payload_tready=input_1_eth_payload_tready, - eth_payload_tlast=input_1_eth_payload_tlast, - eth_payload_tuser=input_1_eth_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = eth_ep.EthFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - eth_hdr_ready=input_2_eth_hdr_ready, - eth_hdr_valid=input_2_eth_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - eth_payload_tdata=input_2_eth_payload_tdata, - eth_payload_tkeep=input_2_eth_payload_tkeep, - eth_payload_tvalid=input_2_eth_payload_tvalid, - eth_payload_tready=input_2_eth_payload_tready, - eth_payload_tlast=input_2_eth_payload_tlast, - eth_payload_tuser=input_2_eth_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = eth_ep.EthFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - eth_hdr_ready=input_3_eth_hdr_ready, - eth_hdr_valid=input_3_eth_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - eth_payload_tdata=input_3_eth_payload_tdata, - eth_payload_tkeep=input_3_eth_payload_tkeep, - eth_payload_tvalid=input_3_eth_payload_tvalid, - eth_payload_tready=input_3_eth_payload_tready, - eth_payload_tlast=input_3_eth_payload_tlast, - eth_payload_tuser=input_3_eth_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + eth_hdr_ready=s_eth_hdr_ready_list[k], + eth_hdr_valid=s_eth_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + eth_payload_tdata=s_eth_payload_axis_tdata_list[k], + eth_payload_tkeep=s_eth_payload_axis_tkeep_list[k], + eth_payload_tvalid=s_eth_payload_axis_tvalid_list[k], + eth_payload_tready=s_eth_payload_axis_tready_list[k], + eth_payload_tlast=s_eth_payload_axis_tlast_list[k], + eth_payload_tuser=s_eth_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = eth_ep.EthFrameSink() sink_logic = sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -227,62 +170,33 @@ def bench(): rst=rst, current_test=current_test, - input_0_eth_hdr_valid=input_0_eth_hdr_valid, - input_0_eth_hdr_ready=input_0_eth_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_eth_payload_tdata=input_0_eth_payload_tdata, - input_0_eth_payload_tkeep=input_0_eth_payload_tkeep, - input_0_eth_payload_tvalid=input_0_eth_payload_tvalid, - input_0_eth_payload_tready=input_0_eth_payload_tready, - input_0_eth_payload_tlast=input_0_eth_payload_tlast, - input_0_eth_payload_tuser=input_0_eth_payload_tuser, - input_1_eth_hdr_valid=input_1_eth_hdr_valid, - input_1_eth_hdr_ready=input_1_eth_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_eth_payload_tdata=input_1_eth_payload_tdata, - input_1_eth_payload_tkeep=input_1_eth_payload_tkeep, - input_1_eth_payload_tvalid=input_1_eth_payload_tvalid, - input_1_eth_payload_tready=input_1_eth_payload_tready, - input_1_eth_payload_tlast=input_1_eth_payload_tlast, - input_1_eth_payload_tuser=input_1_eth_payload_tuser, - input_2_eth_hdr_valid=input_2_eth_hdr_valid, - input_2_eth_hdr_ready=input_2_eth_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_eth_payload_tdata=input_2_eth_payload_tdata, - input_2_eth_payload_tkeep=input_2_eth_payload_tkeep, - input_2_eth_payload_tvalid=input_2_eth_payload_tvalid, - input_2_eth_payload_tready=input_2_eth_payload_tready, - input_2_eth_payload_tlast=input_2_eth_payload_tlast, - input_2_eth_payload_tuser=input_2_eth_payload_tuser, - input_3_eth_hdr_valid=input_3_eth_hdr_valid, - input_3_eth_hdr_ready=input_3_eth_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_eth_payload_tdata=input_3_eth_payload_tdata, - input_3_eth_payload_tkeep=input_3_eth_payload_tkeep, - input_3_eth_payload_tvalid=input_3_eth_payload_tvalid, - input_3_eth_payload_tready=input_3_eth_payload_tready, - input_3_eth_payload_tlast=input_3_eth_payload_tlast, - input_3_eth_payload_tuser=input_3_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tid=s_eth_payload_axis_tid, + s_eth_payload_axis_tdest=s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tid=m_eth_payload_axis_tid, + m_eth_payload_axis_tdest=m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser ) @always(delay(4)) @@ -312,7 +226,7 @@ def bench(): test_frame.eth_type = 0x8000 test_frame.payload = bytearray(range(32)) - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -331,7 +245,7 @@ def bench(): test_frame.eth_type = 0x8000 test_frame.payload = bytearray(range(32)) - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -355,8 +269,8 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -385,8 +299,8 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -415,23 +329,23 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_eth_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge yield sink.wait() @@ -461,12 +375,12 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_eth_payload_tvalid or input_1_eth_payload_tvalid or input_2_eth_payload_tvalid or input_3_eth_payload_tvalid: + while s_eth_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -501,17 +415,17 @@ def bench(): test_frame2.eth_type = 0x8000 test_frame2.payload = bytearray(range(32)) - source_1.send(test_frame1) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) yield clk.posedge - yield delay(150) + yield delay(120) yield clk.posedge - source_1.send(test_frame1) + source_list[1].send(test_frame1) yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_eth_arb_mux_64_4.v b/tb/test_eth_arb_mux_64_4.v index 3a8c30d77..ed74367ab 100644 --- a/tb/test_eth_arb_mux_64_4.v +++ b/tb/test_eth_arb_mux_64_4.v @@ -27,74 +27,59 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for eth_arb_mux_64_4 + * Testbench for eth_arb_mux */ module test_eth_arb_mux_64_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter ARB_TYPE = "PRIORITY"; +parameter LSB_PRIORITY = "HIGH"; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_eth_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [63:0] input_0_eth_payload_tdata = 0; -reg [7:0] input_0_eth_payload_tkeep = 0; -reg input_0_eth_payload_tvalid = 0; -reg input_0_eth_payload_tlast = 0; -reg input_0_eth_payload_tuser = 0; -reg input_1_eth_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [63:0] input_1_eth_payload_tdata = 0; -reg [7:0] input_1_eth_payload_tkeep = 0; -reg input_1_eth_payload_tvalid = 0; -reg input_1_eth_payload_tlast = 0; -reg input_1_eth_payload_tuser = 0; -reg input_2_eth_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [63:0] input_2_eth_payload_tdata = 0; -reg [7:0] input_2_eth_payload_tkeep = 0; -reg input_2_eth_payload_tvalid = 0; -reg input_2_eth_payload_tlast = 0; -reg input_2_eth_payload_tuser = 0; -reg input_3_eth_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [63:0] input_3_eth_payload_tdata = 0; -reg [7:0] input_3_eth_payload_tkeep = 0; -reg input_3_eth_payload_tvalid = 0; -reg input_3_eth_payload_tlast = 0; -reg input_3_eth_payload_tuser = 0; +reg [S_COUNT-1:0] s_eth_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_eth_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_eth_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_eth_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_eth_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_eth_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_eth_payload_axis_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; // Outputs -wire input_0_eth_payload_tready; -wire input_0_eth_hdr_ready; -wire input_1_eth_payload_tready; -wire input_1_eth_hdr_ready; -wire input_2_eth_payload_tready; -wire input_2_eth_hdr_ready; -wire input_3_eth_payload_tready; -wire input_3_eth_hdr_ready; +wire [S_COUNT-1:0] s_eth_hdr_ready; +wire [S_COUNT-1:0] s_eth_payload_axis_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [63:0] output_eth_payload_tdata; -wire [7:0] output_eth_payload_tkeep; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [DATA_WIDTH-1:0] m_eth_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_eth_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_eth_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_eth_payload_axis_tuser; initial begin // myhdl integration @@ -102,63 +87,34 @@ initial begin clk, rst, current_test, - input_0_eth_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_eth_payload_tdata, - input_0_eth_payload_tkeep, - input_0_eth_payload_tvalid, - input_0_eth_payload_tlast, - input_0_eth_payload_tuser, - input_1_eth_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_eth_payload_tdata, - input_1_eth_payload_tkeep, - input_1_eth_payload_tvalid, - input_1_eth_payload_tlast, - input_1_eth_payload_tuser, - input_2_eth_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_eth_payload_tdata, - input_2_eth_payload_tkeep, - input_2_eth_payload_tvalid, - input_2_eth_payload_tlast, - input_2_eth_payload_tuser, - input_3_eth_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_eth_payload_tdata, - input_3_eth_payload_tkeep, - input_3_eth_payload_tvalid, - input_3_eth_payload_tlast, - input_3_eth_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tid, + s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready ); $to_myhdl( - input_0_eth_hdr_ready, - input_0_eth_payload_tready, - input_1_eth_hdr_ready, - input_1_eth_payload_tready, - input_2_eth_hdr_ready, - input_2_eth_payload_tready, - input_3_eth_hdr_ready, - input_3_eth_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tid, + m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser ); // dump file @@ -166,67 +122,51 @@ initial begin $dumpvars(0, test_eth_arb_mux_64_4); end -eth_arb_mux_64_4 +eth_arb_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) +) UUT ( .clk(clk), .rst(rst), // Ethernet frame inputs - .input_0_eth_hdr_valid(input_0_eth_hdr_valid), - .input_0_eth_hdr_ready(input_0_eth_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_eth_payload_tdata(input_0_eth_payload_tdata), - .input_0_eth_payload_tkeep(input_0_eth_payload_tkeep), - .input_0_eth_payload_tvalid(input_0_eth_payload_tvalid), - .input_0_eth_payload_tready(input_0_eth_payload_tready), - .input_0_eth_payload_tlast(input_0_eth_payload_tlast), - .input_0_eth_payload_tuser(input_0_eth_payload_tuser), - .input_1_eth_hdr_valid(input_1_eth_hdr_valid), - .input_1_eth_hdr_ready(input_1_eth_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_eth_payload_tdata(input_1_eth_payload_tdata), - .input_1_eth_payload_tkeep(input_1_eth_payload_tkeep), - .input_1_eth_payload_tvalid(input_1_eth_payload_tvalid), - .input_1_eth_payload_tready(input_1_eth_payload_tready), - .input_1_eth_payload_tlast(input_1_eth_payload_tlast), - .input_1_eth_payload_tuser(input_1_eth_payload_tuser), - .input_2_eth_hdr_valid(input_2_eth_hdr_valid), - .input_2_eth_hdr_ready(input_2_eth_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_eth_payload_tdata(input_2_eth_payload_tdata), - .input_2_eth_payload_tkeep(input_2_eth_payload_tkeep), - .input_2_eth_payload_tvalid(input_2_eth_payload_tvalid), - .input_2_eth_payload_tready(input_2_eth_payload_tready), - .input_2_eth_payload_tlast(input_2_eth_payload_tlast), - .input_2_eth_payload_tuser(input_2_eth_payload_tuser), - .input_3_eth_hdr_valid(input_3_eth_hdr_valid), - .input_3_eth_hdr_ready(input_3_eth_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_eth_payload_tdata(input_3_eth_payload_tdata), - .input_3_eth_payload_tkeep(input_3_eth_payload_tkeep), - .input_3_eth_payload_tvalid(input_3_eth_payload_tvalid), - .input_3_eth_payload_tready(input_3_eth_payload_tready), - .input_3_eth_payload_tlast(input_3_eth_payload_tlast), - .input_3_eth_payload_tuser(input_3_eth_payload_tuser), - // Eth frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser) + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tid(s_eth_payload_axis_tid), + .s_eth_payload_axis_tdest(s_eth_payload_axis_tdest), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tid(m_eth_payload_axis_tid), + .m_eth_payload_axis_tdest(m_eth_payload_axis_tdest), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser) ); endmodule From 554e0a538040c3d56d47f4fed7bc60fb3c2af3a0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 1 Nov 2018 00:40:09 -0700 Subject: [PATCH 461/617] Convert generated ip_arb_mux to verilog parametrized module --- rtl/ip_arb_mux.py | 238 ------------- rtl/ip_arb_mux.v | 407 +++++++++++++++++++++++ rtl/ip_arb_mux_2.v | 228 ------------- rtl/ip_arb_mux_4.v | 326 ------------------ rtl/ip_arb_mux_64.py | 242 -------------- rtl/ip_arb_mux_64_2.v | 234 ------------- rtl/ip_arb_mux_64_4.v | 336 ------------------- tb/test_ip_arb_mux_4.py | 649 +++++++++++++----------------------- tb/test_ip_arb_mux_4.v | 536 +++++++++++------------------ tb/test_ip_arb_mux_64_4.py | 666 +++++++++++++------------------------ tb/test_ip_arb_mux_64_4.v | 551 +++++++++++------------------- 11 files changed, 1256 insertions(+), 3157 deletions(-) delete mode 100755 rtl/ip_arb_mux.py create mode 100644 rtl/ip_arb_mux.v delete mode 100644 rtl/ip_arb_mux_2.v delete mode 100644 rtl/ip_arb_mux_4.v delete mode 100755 rtl/ip_arb_mux_64.py delete mode 100644 rtl/ip_arb_mux_64_2.v delete mode 100644 rtl/ip_arb_mux_64_4.v diff --git a/rtl/ip_arb_mux.py b/rtl/ip_arb_mux.py deleted file mode 100755 index 81d22b6cc..000000000 --- a/rtl/ip_arb_mux.py +++ /dev/null @@ -1,238 +0,0 @@ -#!/usr/bin/env python -""" -Generates an arbitrated IP mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "ip_arb_mux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port IP arbitrated mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * IP {{n}} port arbitrated multiplexer - */ -module {{name}} # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_ip_hdr_valid, - output wire input_{{p}}_ip_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [3:0] input_{{p}}_ip_version, - input wire [3:0] input_{{p}}_ip_ihl, - input wire [5:0] input_{{p}}_ip_dscp, - input wire [1:0] input_{{p}}_ip_ecn, - input wire [15:0] input_{{p}}_ip_length, - input wire [15:0] input_{{p}}_ip_identification, - input wire [2:0] input_{{p}}_ip_flags, - input wire [12:0] input_{{p}}_ip_fragment_offset, - input wire [7:0] input_{{p}}_ip_ttl, - input wire [7:0] input_{{p}}_ip_protocol, - input wire [15:0] input_{{p}}_ip_header_checksum, - input wire [31:0] input_{{p}}_ip_source_ip, - input wire [31:0] input_{{p}}_ip_dest_ip, - input wire [7:0] input_{{p}}_ip_payload_tdata, - input wire input_{{p}}_ip_payload_tvalid, - output wire input_{{p}}_ip_payload_tready, - input wire input_{{p}}_ip_payload_tlast, - input wire input_{{p}}_ip_payload_tuser, -{% endfor %} - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser -); - -wire [{{n-1}}:0] request; -wire [{{n-1}}:0] acknowledge; -wire [{{n-1}}:0] grant; -wire grant_valid; -wire [{{w-1}}:0] grant_encoded; -{% for p in ports %} -assign acknowledge[{{p}}] = input_{{p}}_ip_payload_tvalid & input_{{p}}_ip_payload_tready & input_{{p}}_ip_payload_tlast; -assign request[{{p}}] = input_{{p}}_ip_hdr_valid; -{%- endfor %} - -// mux instance -ip_mux_{{n}} -mux_inst ( - .clk(clk), - .rst(rst), -{%- for p in ports %} - .input_{{p}}_ip_hdr_valid(input_{{p}}_ip_hdr_valid & grant[{{p}}]), - .input_{{p}}_ip_hdr_ready(input_{{p}}_ip_hdr_ready), - .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), - .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), - .input_{{p}}_eth_type(input_{{p}}_eth_type), - .input_{{p}}_ip_version(input_{{p}}_ip_version), - .input_{{p}}_ip_ihl(input_{{p}}_ip_ihl), - .input_{{p}}_ip_dscp(input_{{p}}_ip_dscp), - .input_{{p}}_ip_ecn(input_{{p}}_ip_ecn), - .input_{{p}}_ip_length(input_{{p}}_ip_length), - .input_{{p}}_ip_identification(input_{{p}}_ip_identification), - .input_{{p}}_ip_flags(input_{{p}}_ip_flags), - .input_{{p}}_ip_fragment_offset(input_{{p}}_ip_fragment_offset), - .input_{{p}}_ip_ttl(input_{{p}}_ip_ttl), - .input_{{p}}_ip_protocol(input_{{p}}_ip_protocol), - .input_{{p}}_ip_header_checksum(input_{{p}}_ip_header_checksum), - .input_{{p}}_ip_source_ip(input_{{p}}_ip_source_ip), - .input_{{p}}_ip_dest_ip(input_{{p}}_ip_dest_ip), - .input_{{p}}_ip_payload_tdata(input_{{p}}_ip_payload_tdata), - .input_{{p}}_ip_payload_tvalid(input_{{p}}_ip_payload_tvalid & grant[{{p}}]), - .input_{{p}}_ip_payload_tready(input_{{p}}_ip_payload_tready), - .input_{{p}}_ip_payload_tlast(input_{{p}}_ip_payload_tlast), - .input_{{p}}_ip_payload_tuser(input_{{p}}_ip_payload_tuser), -{%- endfor %} - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS({{n}}), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/ip_arb_mux.v b/rtl/ip_arb_mux.v new file mode 100644 index 000000000..13211bf3d --- /dev/null +++ b/rtl/ip_arb_mux.v @@ -0,0 +1,407 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * IP arbitrated multiplexer + */ +module ip_arb_mux # +( + parameter S_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * IP frame inputs + */ + input wire [S_COUNT-1:0] s_ip_hdr_valid, + output wire [S_COUNT-1:0] s_ip_hdr_ready, + input wire [S_COUNT*48-1:0] s_eth_dest_mac, + input wire [S_COUNT*48-1:0] s_eth_src_mac, + input wire [S_COUNT*16-1:0] s_eth_type, + input wire [S_COUNT*4-1:0] s_ip_version, + input wire [S_COUNT*4-1:0] s_ip_ihl, + input wire [S_COUNT*6-1:0] s_ip_dscp, + input wire [S_COUNT*2-1:0] s_ip_ecn, + input wire [S_COUNT*16-1:0] s_ip_length, + input wire [S_COUNT*16-1:0] s_ip_identification, + input wire [S_COUNT*3-1:0] s_ip_flags, + input wire [S_COUNT*13-1:0] s_ip_fragment_offset, + input wire [S_COUNT*8-1:0] s_ip_ttl, + input wire [S_COUNT*8-1:0] s_ip_protocol, + input wire [S_COUNT*16-1:0] s_ip_header_checksum, + input wire [S_COUNT*32-1:0] s_ip_source_ip, + input wire [S_COUNT*32-1:0] s_ip_dest_ip, + input wire [S_COUNT*DATA_WIDTH-1:0] s_ip_payload_axis_tdata, + input wire [S_COUNT*KEEP_WIDTH-1:0] s_ip_payload_axis_tkeep, + input wire [S_COUNT-1:0] s_ip_payload_axis_tvalid, + output wire [S_COUNT-1:0] s_ip_payload_axis_tready, + input wire [S_COUNT-1:0] s_ip_payload_axis_tlast, + input wire [S_COUNT*ID_WIDTH-1:0] s_ip_payload_axis_tid, + input wire [S_COUNT*DEST_WIDTH-1:0] s_ip_payload_axis_tdest, + input wire [S_COUNT*USER_WIDTH-1:0] s_ip_payload_axis_tuser, + + /* + * IP frame output + */ + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [DATA_WIDTH-1:0] m_ip_payload_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire [ID_WIDTH-1:0] m_ip_payload_axis_tid, + output wire [DEST_WIDTH-1:0] m_ip_payload_axis_tdest, + output wire [USER_WIDTH-1:0] m_ip_payload_axis_tuser +); + +parameter CL_S_COUNT = $clog2(S_COUNT); + +reg frame_reg = 1'b0, frame_next; + +reg s_ip_hdr_ready_mask_reg = 1'b0, s_ip_hdr_ready_mask_next; + +reg m_ip_hdr_valid_reg = 1'b0, m_ip_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0, m_eth_dest_mac_next; +reg [47:0] m_eth_src_mac_reg = 48'd0, m_eth_src_mac_next; +reg [15:0] m_eth_type_reg = 16'd0, m_eth_type_next; +reg [3:0] m_ip_version_reg = 4'd0, m_ip_version_next; +reg [3:0] m_ip_ihl_reg = 4'd0, m_ip_ihl_next; +reg [5:0] m_ip_dscp_reg = 6'd0, m_ip_dscp_next; +reg [1:0] m_ip_ecn_reg = 2'd0, m_ip_ecn_next; +reg [15:0] m_ip_length_reg = 16'd0, m_ip_length_next; +reg [15:0] m_ip_identification_reg = 16'd0, m_ip_identification_next; +reg [2:0] m_ip_flags_reg = 3'd0, m_ip_flags_next; +reg [12:0] m_ip_fragment_offset_reg = 13'd0, m_ip_fragment_offset_next; +reg [7:0] m_ip_ttl_reg = 8'd0, m_ip_ttl_next; +reg [7:0] m_ip_protocol_reg = 8'd0, m_ip_protocol_next; +reg [15:0] m_ip_header_checksum_reg = 16'd0, m_ip_header_checksum_next; +reg [31:0] m_ip_source_ip_reg = 32'd0, m_ip_source_ip_next; +reg [31:0] m_ip_dest_ip_reg = 32'd0, m_ip_dest_ip_next; + +wire [S_COUNT-1:0] request; +wire [S_COUNT-1:0] acknowledge; +wire [S_COUNT-1:0] grant; +wire grant_valid; +wire [CL_S_COUNT-1:0] grant_encoded; + +// internal datapath +reg [DATA_WIDTH-1:0] m_ip_payload_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep_int; +reg m_ip_payload_axis_tvalid_int; +reg m_ip_payload_axis_tready_int_reg = 1'b0; +reg m_ip_payload_axis_tlast_int; +reg [ID_WIDTH-1:0] m_ip_payload_axis_tid_int; +reg [DEST_WIDTH-1:0] m_ip_payload_axis_tdest_int; +reg [USER_WIDTH-1:0] m_ip_payload_axis_tuser_int; +wire m_ip_payload_axis_tready_int_early; + +assign s_ip_hdr_ready = (!s_ip_hdr_ready_mask_reg && grant_valid) << grant_encoded; + +assign s_ip_payload_axis_tready = (m_ip_payload_axis_tready_int_reg && grant_valid) << grant_encoded; + +assign m_ip_hdr_valid = m_ip_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_ip_length_reg; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = m_ip_protocol_reg; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; + +// mux for incoming packet +wire [DATA_WIDTH-1:0] current_s_tdata = s_ip_payload_axis_tdata[grant_encoded*DATA_WIDTH +: DATA_WIDTH]; +wire [KEEP_WIDTH-1:0] current_s_tkeep = s_ip_payload_axis_tkeep[grant_encoded*KEEP_WIDTH +: KEEP_WIDTH]; +wire current_s_tvalid = s_ip_payload_axis_tvalid[grant_encoded]; +wire current_s_tready = s_ip_payload_axis_tready[grant_encoded]; +wire current_s_tlast = s_ip_payload_axis_tlast[grant_encoded]; +wire [ID_WIDTH-1:0] current_s_tid = s_ip_payload_axis_tid[grant_encoded*ID_WIDTH +: ID_WIDTH]; +wire [DEST_WIDTH-1:0] current_s_tdest = s_ip_payload_axis_tdest[grant_encoded*DEST_WIDTH +: DEST_WIDTH]; +wire [USER_WIDTH-1:0] current_s_tuser = s_ip_payload_axis_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH]; + +// arbiter instance +arbiter #( + .PORTS(S_COUNT), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +generate + genvar n; + + for (n = 0; n < S_COUNT; n = n + 1) begin + assign request[n] = s_ip_hdr_valid[n] && !grant[n]; + assign acknowledge[n] = grant[n] && s_ip_payload_axis_tvalid[n] && s_ip_payload_axis_tready[n] && s_ip_payload_axis_tlast[n]; + end +endgenerate + +always @* begin + frame_next = frame_reg; + + s_ip_hdr_ready_mask_next = s_ip_hdr_ready_mask_reg; + + m_ip_hdr_valid_next = m_ip_hdr_valid_reg && !m_ip_hdr_ready; + m_eth_dest_mac_next = m_eth_dest_mac_reg; + m_eth_src_mac_next = m_eth_src_mac_reg; + m_eth_type_next = m_eth_type_reg; + m_ip_version_next = m_ip_version_reg; + m_ip_ihl_next = m_ip_ihl_reg; + m_ip_dscp_next = m_ip_dscp_reg; + m_ip_ecn_next = m_ip_ecn_reg; + m_ip_length_next = m_ip_length_reg; + m_ip_identification_next = m_ip_identification_reg; + m_ip_flags_next = m_ip_flags_reg; + m_ip_fragment_offset_next = m_ip_fragment_offset_reg; + m_ip_ttl_next = m_ip_ttl_reg; + m_ip_protocol_next = m_ip_protocol_reg; + m_ip_header_checksum_next = m_ip_header_checksum_reg; + m_ip_source_ip_next = m_ip_source_ip_reg; + m_ip_dest_ip_next = m_ip_dest_ip_reg; + + if (s_ip_payload_axis_tvalid[grant_encoded] && s_ip_payload_axis_tready[grant_encoded]) begin + // end of frame detection + if (s_ip_payload_axis_tlast[grant_encoded]) begin + frame_next = 1'b0; + s_ip_hdr_ready_mask_next = 1'b0; + end + end + + if (!frame_reg && grant_valid) begin + // start of frame + frame_next = 1'b1; + + s_ip_hdr_ready_mask_next = 1'b1; + + m_ip_hdr_valid_next = 1'b1; + m_eth_dest_mac_next = s_eth_dest_mac[grant_encoded*48 +: 48]; + m_eth_src_mac_next = s_eth_src_mac[grant_encoded*48 +: 48]; + m_eth_type_next = s_eth_type[grant_encoded*16 +: 16]; + m_ip_version_next = s_ip_version[grant_encoded*4 +: 4]; + m_ip_ihl_next = s_ip_ihl[grant_encoded*4 +: 4]; + m_ip_dscp_next = s_ip_dscp[grant_encoded*6 +: 6]; + m_ip_ecn_next = s_ip_ecn[grant_encoded*2 +: 2]; + m_ip_length_next = s_ip_length[grant_encoded*16 +: 16]; + m_ip_identification_next = s_ip_identification[grant_encoded*16 +: 16]; + m_ip_flags_next = s_ip_flags[grant_encoded*3 +: 3]; + m_ip_fragment_offset_next = s_ip_fragment_offset[grant_encoded*13 +: 13]; + m_ip_ttl_next = s_ip_ttl[grant_encoded*8 +: 8]; + m_ip_protocol_next = s_ip_protocol[grant_encoded*8 +: 8]; + m_ip_header_checksum_next = s_ip_header_checksum[grant_encoded*16 +: 16]; + m_ip_source_ip_next = s_ip_source_ip[grant_encoded*32 +: 32]; + m_ip_dest_ip_next = s_ip_dest_ip[grant_encoded*32 +: 32]; + end + + // pass through selected packet data + m_ip_payload_axis_tdata_int = current_s_tdata; + m_ip_payload_axis_tkeep_int = current_s_tkeep; + m_ip_payload_axis_tvalid_int = current_s_tvalid && m_ip_payload_axis_tready_int_reg && grant_valid; + m_ip_payload_axis_tlast_int = current_s_tlast; + m_ip_payload_axis_tid_int = current_s_tid; + m_ip_payload_axis_tdest_int = current_s_tdest; + m_ip_payload_axis_tuser_int = current_s_tuser; +end + +always @(posedge clk) begin + if (rst) begin + frame_reg <= 1'b0; + s_ip_hdr_ready_mask_reg <= 1'b0; + m_ip_hdr_valid_reg <= 1'b0; + end else begin + frame_reg <= frame_next; + s_ip_hdr_ready_mask_reg <= s_ip_hdr_ready_mask_next; + m_ip_hdr_valid_reg <= m_ip_hdr_valid_next; + end + + m_eth_dest_mac_reg <= m_eth_dest_mac_next; + m_eth_src_mac_reg <= m_eth_src_mac_next; + m_eth_type_reg <= m_eth_type_next; + m_ip_version_reg <= m_ip_version_next; + m_ip_ihl_reg <= m_ip_ihl_next; + m_ip_dscp_reg <= m_ip_dscp_next; + m_ip_ecn_reg <= m_ip_ecn_next; + m_ip_length_reg <= m_ip_length_next; + m_ip_identification_reg <= m_ip_identification_next; + m_ip_flags_reg <= m_ip_flags_next; + m_ip_fragment_offset_reg <= m_ip_fragment_offset_next; + m_ip_ttl_reg <= m_ip_ttl_next; + m_ip_protocol_reg <= m_ip_protocol_next; + m_ip_header_checksum_reg <= m_ip_header_checksum_next; + m_ip_source_ip_reg <= m_ip_source_ip_next; + m_ip_dest_ip_reg <= m_ip_dest_ip_next; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_ip_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_ip_payload_axis_tvalid_reg = 1'b0, m_ip_payload_axis_tvalid_next; +reg m_ip_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_ip_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_ip_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_ip_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_ip_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_ip_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_ip_payload_axis_tvalid_reg = 1'b0, temp_m_ip_payload_axis_tvalid_next; +reg temp_m_ip_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_ip_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_ip_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_ip_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_ip_payload_axis_temp_to_output; + +assign m_ip_payload_axis_tdata = m_ip_payload_axis_tdata_reg; +assign m_ip_payload_axis_tkeep = KEEP_ENABLE ? m_ip_payload_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_ip_payload_axis_tvalid = m_ip_payload_axis_tvalid_reg; +assign m_ip_payload_axis_tlast = m_ip_payload_axis_tlast_reg; +assign m_ip_payload_axis_tid = ID_ENABLE ? m_ip_payload_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_ip_payload_axis_tdest = DEST_ENABLE ? m_ip_payload_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_ip_payload_axis_tuser = USER_ENABLE ? m_ip_payload_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_ip_payload_axis_tready_int_early = m_ip_payload_axis_tready || (!temp_m_ip_payload_axis_tvalid_reg && (!m_ip_payload_axis_tvalid_reg || !m_ip_payload_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b0; + + if (m_ip_payload_axis_tready_int_reg) begin + // input is ready + if (m_ip_payload_axis_tready || !m_ip_payload_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_ip_payload_axis_tready) begin + // input is not ready, but output is ready + m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_ip_payload_axis_tvalid_reg <= 1'b0; + m_ip_payload_axis_tready_int_reg <= 1'b0; + temp_m_ip_payload_axis_tvalid_reg <= 1'b0; + end else begin + m_ip_payload_axis_tvalid_reg <= m_ip_payload_axis_tvalid_next; + m_ip_payload_axis_tready_int_reg <= m_ip_payload_axis_tready_int_early; + temp_m_ip_payload_axis_tvalid_reg <= temp_m_ip_payload_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + m_ip_payload_axis_tkeep_reg <= m_ip_payload_axis_tkeep_int; + m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + m_ip_payload_axis_tid_reg <= m_ip_payload_axis_tid_int; + m_ip_payload_axis_tdest_reg <= m_ip_payload_axis_tdest_int; + m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; + end else if (store_ip_payload_axis_temp_to_output) begin + m_ip_payload_axis_tdata_reg <= temp_m_ip_payload_axis_tdata_reg; + m_ip_payload_axis_tkeep_reg <= temp_m_ip_payload_axis_tkeep_reg; + m_ip_payload_axis_tlast_reg <= temp_m_ip_payload_axis_tlast_reg; + m_ip_payload_axis_tid_reg <= temp_m_ip_payload_axis_tid_reg; + m_ip_payload_axis_tdest_reg <= temp_m_ip_payload_axis_tdest_reg; + m_ip_payload_axis_tuser_reg <= temp_m_ip_payload_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + temp_m_ip_payload_axis_tkeep_reg <= m_ip_payload_axis_tkeep_int; + temp_m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + temp_m_ip_payload_axis_tid_reg <= m_ip_payload_axis_tid_int; + temp_m_ip_payload_axis_tdest_reg <= m_ip_payload_axis_tdest_int; + temp_m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/ip_arb_mux_2.v b/rtl/ip_arb_mux_2.v deleted file mode 100644 index 95aad55db..000000000 --- a/rtl/ip_arb_mux_2.v +++ /dev/null @@ -1,228 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * IP 2 port arbitrated multiplexer - */ -module ip_arb_mux_2 # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ - input wire input_0_ip_hdr_valid, - output wire input_0_ip_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [7:0] input_0_ip_payload_tdata, - input wire input_0_ip_payload_tvalid, - output wire input_0_ip_payload_tready, - input wire input_0_ip_payload_tlast, - input wire input_0_ip_payload_tuser, - - input wire input_1_ip_hdr_valid, - output wire input_1_ip_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [7:0] input_1_ip_payload_tdata, - input wire input_1_ip_payload_tvalid, - output wire input_1_ip_payload_tready, - input wire input_1_ip_payload_tlast, - input wire input_1_ip_payload_tuser, - - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser -); - -wire [1:0] request; -wire [1:0] acknowledge; -wire [1:0] grant; -wire grant_valid; -wire [0:0] grant_encoded; - -assign acknowledge[0] = input_0_ip_payload_tvalid & input_0_ip_payload_tready & input_0_ip_payload_tlast; -assign request[0] = input_0_ip_hdr_valid; -assign acknowledge[1] = input_1_ip_payload_tvalid & input_1_ip_payload_tready & input_1_ip_payload_tlast; -assign request[1] = input_1_ip_hdr_valid; - -// mux instance -ip_mux_2 -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_ip_hdr_valid(input_0_ip_hdr_valid & grant[0]), - .input_0_ip_hdr_ready(input_0_ip_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_ip_payload_tdata(input_0_ip_payload_tdata), - .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid & grant[0]), - .input_0_ip_payload_tready(input_0_ip_payload_tready), - .input_0_ip_payload_tlast(input_0_ip_payload_tlast), - .input_0_ip_payload_tuser(input_0_ip_payload_tuser), - .input_1_ip_hdr_valid(input_1_ip_hdr_valid & grant[1]), - .input_1_ip_hdr_ready(input_1_ip_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_ip_payload_tdata(input_1_ip_payload_tdata), - .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid & grant[1]), - .input_1_ip_payload_tready(input_1_ip_payload_tready), - .input_1_ip_payload_tlast(input_1_ip_payload_tlast), - .input_1_ip_payload_tuser(input_1_ip_payload_tuser), - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(2), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/rtl/ip_arb_mux_4.v b/rtl/ip_arb_mux_4.v deleted file mode 100644 index db9797dfc..000000000 --- a/rtl/ip_arb_mux_4.v +++ /dev/null @@ -1,326 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * IP 4 port arbitrated multiplexer - */ -module ip_arb_mux_4 # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ - input wire input_0_ip_hdr_valid, - output wire input_0_ip_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [7:0] input_0_ip_payload_tdata, - input wire input_0_ip_payload_tvalid, - output wire input_0_ip_payload_tready, - input wire input_0_ip_payload_tlast, - input wire input_0_ip_payload_tuser, - - input wire input_1_ip_hdr_valid, - output wire input_1_ip_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [7:0] input_1_ip_payload_tdata, - input wire input_1_ip_payload_tvalid, - output wire input_1_ip_payload_tready, - input wire input_1_ip_payload_tlast, - input wire input_1_ip_payload_tuser, - - input wire input_2_ip_hdr_valid, - output wire input_2_ip_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [3:0] input_2_ip_version, - input wire [3:0] input_2_ip_ihl, - input wire [5:0] input_2_ip_dscp, - input wire [1:0] input_2_ip_ecn, - input wire [15:0] input_2_ip_length, - input wire [15:0] input_2_ip_identification, - input wire [2:0] input_2_ip_flags, - input wire [12:0] input_2_ip_fragment_offset, - input wire [7:0] input_2_ip_ttl, - input wire [7:0] input_2_ip_protocol, - input wire [15:0] input_2_ip_header_checksum, - input wire [31:0] input_2_ip_source_ip, - input wire [31:0] input_2_ip_dest_ip, - input wire [7:0] input_2_ip_payload_tdata, - input wire input_2_ip_payload_tvalid, - output wire input_2_ip_payload_tready, - input wire input_2_ip_payload_tlast, - input wire input_2_ip_payload_tuser, - - input wire input_3_ip_hdr_valid, - output wire input_3_ip_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [3:0] input_3_ip_version, - input wire [3:0] input_3_ip_ihl, - input wire [5:0] input_3_ip_dscp, - input wire [1:0] input_3_ip_ecn, - input wire [15:0] input_3_ip_length, - input wire [15:0] input_3_ip_identification, - input wire [2:0] input_3_ip_flags, - input wire [12:0] input_3_ip_fragment_offset, - input wire [7:0] input_3_ip_ttl, - input wire [7:0] input_3_ip_protocol, - input wire [15:0] input_3_ip_header_checksum, - input wire [31:0] input_3_ip_source_ip, - input wire [31:0] input_3_ip_dest_ip, - input wire [7:0] input_3_ip_payload_tdata, - input wire input_3_ip_payload_tvalid, - output wire input_3_ip_payload_tready, - input wire input_3_ip_payload_tlast, - input wire input_3_ip_payload_tuser, - - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser -); - -wire [3:0] request; -wire [3:0] acknowledge; -wire [3:0] grant; -wire grant_valid; -wire [1:0] grant_encoded; - -assign acknowledge[0] = input_0_ip_payload_tvalid & input_0_ip_payload_tready & input_0_ip_payload_tlast; -assign request[0] = input_0_ip_hdr_valid; -assign acknowledge[1] = input_1_ip_payload_tvalid & input_1_ip_payload_tready & input_1_ip_payload_tlast; -assign request[1] = input_1_ip_hdr_valid; -assign acknowledge[2] = input_2_ip_payload_tvalid & input_2_ip_payload_tready & input_2_ip_payload_tlast; -assign request[2] = input_2_ip_hdr_valid; -assign acknowledge[3] = input_3_ip_payload_tvalid & input_3_ip_payload_tready & input_3_ip_payload_tlast; -assign request[3] = input_3_ip_hdr_valid; - -// mux instance -ip_mux_4 -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_ip_hdr_valid(input_0_ip_hdr_valid & grant[0]), - .input_0_ip_hdr_ready(input_0_ip_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_ip_payload_tdata(input_0_ip_payload_tdata), - .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid & grant[0]), - .input_0_ip_payload_tready(input_0_ip_payload_tready), - .input_0_ip_payload_tlast(input_0_ip_payload_tlast), - .input_0_ip_payload_tuser(input_0_ip_payload_tuser), - .input_1_ip_hdr_valid(input_1_ip_hdr_valid & grant[1]), - .input_1_ip_hdr_ready(input_1_ip_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_ip_payload_tdata(input_1_ip_payload_tdata), - .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid & grant[1]), - .input_1_ip_payload_tready(input_1_ip_payload_tready), - .input_1_ip_payload_tlast(input_1_ip_payload_tlast), - .input_1_ip_payload_tuser(input_1_ip_payload_tuser), - .input_2_ip_hdr_valid(input_2_ip_hdr_valid & grant[2]), - .input_2_ip_hdr_ready(input_2_ip_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_ip_payload_tdata(input_2_ip_payload_tdata), - .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid & grant[2]), - .input_2_ip_payload_tready(input_2_ip_payload_tready), - .input_2_ip_payload_tlast(input_2_ip_payload_tlast), - .input_2_ip_payload_tuser(input_2_ip_payload_tuser), - .input_3_ip_hdr_valid(input_3_ip_hdr_valid & grant[3]), - .input_3_ip_hdr_ready(input_3_ip_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_ip_payload_tdata(input_3_ip_payload_tdata), - .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid & grant[3]), - .input_3_ip_payload_tready(input_3_ip_payload_tready), - .input_3_ip_payload_tlast(input_3_ip_payload_tlast), - .input_3_ip_payload_tuser(input_3_ip_payload_tuser), - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/rtl/ip_arb_mux_64.py b/rtl/ip_arb_mux_64.py deleted file mode 100755 index 0845cfc6b..000000000 --- a/rtl/ip_arb_mux_64.py +++ /dev/null @@ -1,242 +0,0 @@ -#!/usr/bin/env python -""" -Generates an arbitrated IP mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "ip_arb_mux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port IP arbitrated mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * IP {{n}} port arbitrated multiplexer (64 bit datapath) - */ -module {{name}} # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_ip_hdr_valid, - output wire input_{{p}}_ip_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [3:0] input_{{p}}_ip_version, - input wire [3:0] input_{{p}}_ip_ihl, - input wire [5:0] input_{{p}}_ip_dscp, - input wire [1:0] input_{{p}}_ip_ecn, - input wire [15:0] input_{{p}}_ip_length, - input wire [15:0] input_{{p}}_ip_identification, - input wire [2:0] input_{{p}}_ip_flags, - input wire [12:0] input_{{p}}_ip_fragment_offset, - input wire [7:0] input_{{p}}_ip_ttl, - input wire [7:0] input_{{p}}_ip_protocol, - input wire [15:0] input_{{p}}_ip_header_checksum, - input wire [31:0] input_{{p}}_ip_source_ip, - input wire [31:0] input_{{p}}_ip_dest_ip, - input wire [63:0] input_{{p}}_ip_payload_tdata, - input wire [7:0] input_{{p}}_ip_payload_tkeep, - input wire input_{{p}}_ip_payload_tvalid, - output wire input_{{p}}_ip_payload_tready, - input wire input_{{p}}_ip_payload_tlast, - input wire input_{{p}}_ip_payload_tuser, -{% endfor %} - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser -); - -wire [{{n-1}}:0] request; -wire [{{n-1}}:0] acknowledge; -wire [{{n-1}}:0] grant; -wire grant_valid; -wire [{{w-1}}:0] grant_encoded; -{% for p in ports %} -assign acknowledge[{{p}}] = input_{{p}}_ip_payload_tvalid & input_{{p}}_ip_payload_tready & input_{{p}}_ip_payload_tlast; -assign request[{{p}}] = input_{{p}}_ip_hdr_valid; -{%- endfor %} - -// mux instance -ip_mux_64_{{n}} -mux_inst ( - .clk(clk), - .rst(rst), -{%- for p in ports %} - .input_{{p}}_ip_hdr_valid(input_{{p}}_ip_hdr_valid & grant[{{p}}]), - .input_{{p}}_ip_hdr_ready(input_{{p}}_ip_hdr_ready), - .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), - .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), - .input_{{p}}_eth_type(input_{{p}}_eth_type), - .input_{{p}}_ip_version(input_{{p}}_ip_version), - .input_{{p}}_ip_ihl(input_{{p}}_ip_ihl), - .input_{{p}}_ip_dscp(input_{{p}}_ip_dscp), - .input_{{p}}_ip_ecn(input_{{p}}_ip_ecn), - .input_{{p}}_ip_length(input_{{p}}_ip_length), - .input_{{p}}_ip_identification(input_{{p}}_ip_identification), - .input_{{p}}_ip_flags(input_{{p}}_ip_flags), - .input_{{p}}_ip_fragment_offset(input_{{p}}_ip_fragment_offset), - .input_{{p}}_ip_ttl(input_{{p}}_ip_ttl), - .input_{{p}}_ip_protocol(input_{{p}}_ip_protocol), - .input_{{p}}_ip_header_checksum(input_{{p}}_ip_header_checksum), - .input_{{p}}_ip_source_ip(input_{{p}}_ip_source_ip), - .input_{{p}}_ip_dest_ip(input_{{p}}_ip_dest_ip), - .input_{{p}}_ip_payload_tdata(input_{{p}}_ip_payload_tdata), - .input_{{p}}_ip_payload_tkeep(input_{{p}}_ip_payload_tkeep), - .input_{{p}}_ip_payload_tvalid(input_{{p}}_ip_payload_tvalid & grant[{{p}}]), - .input_{{p}}_ip_payload_tready(input_{{p}}_ip_payload_tready), - .input_{{p}}_ip_payload_tlast(input_{{p}}_ip_payload_tlast), - .input_{{p}}_ip_payload_tuser(input_{{p}}_ip_payload_tuser), -{%- endfor %} - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS({{n}}), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/ip_arb_mux_64_2.v b/rtl/ip_arb_mux_64_2.v deleted file mode 100644 index ce509bd76..000000000 --- a/rtl/ip_arb_mux_64_2.v +++ /dev/null @@ -1,234 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * IP 2 port arbitrated multiplexer (64 bit datapath) - */ -module ip_arb_mux_64_2 # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ - input wire input_0_ip_hdr_valid, - output wire input_0_ip_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [63:0] input_0_ip_payload_tdata, - input wire [7:0] input_0_ip_payload_tkeep, - input wire input_0_ip_payload_tvalid, - output wire input_0_ip_payload_tready, - input wire input_0_ip_payload_tlast, - input wire input_0_ip_payload_tuser, - - input wire input_1_ip_hdr_valid, - output wire input_1_ip_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [63:0] input_1_ip_payload_tdata, - input wire [7:0] input_1_ip_payload_tkeep, - input wire input_1_ip_payload_tvalid, - output wire input_1_ip_payload_tready, - input wire input_1_ip_payload_tlast, - input wire input_1_ip_payload_tuser, - - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser -); - -wire [1:0] request; -wire [1:0] acknowledge; -wire [1:0] grant; -wire grant_valid; -wire [0:0] grant_encoded; - -assign acknowledge[0] = input_0_ip_payload_tvalid & input_0_ip_payload_tready & input_0_ip_payload_tlast; -assign request[0] = input_0_ip_hdr_valid; -assign acknowledge[1] = input_1_ip_payload_tvalid & input_1_ip_payload_tready & input_1_ip_payload_tlast; -assign request[1] = input_1_ip_hdr_valid; - -// mux instance -ip_mux_64_2 -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_ip_hdr_valid(input_0_ip_hdr_valid & grant[0]), - .input_0_ip_hdr_ready(input_0_ip_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_ip_payload_tdata(input_0_ip_payload_tdata), - .input_0_ip_payload_tkeep(input_0_ip_payload_tkeep), - .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid & grant[0]), - .input_0_ip_payload_tready(input_0_ip_payload_tready), - .input_0_ip_payload_tlast(input_0_ip_payload_tlast), - .input_0_ip_payload_tuser(input_0_ip_payload_tuser), - .input_1_ip_hdr_valid(input_1_ip_hdr_valid & grant[1]), - .input_1_ip_hdr_ready(input_1_ip_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_ip_payload_tdata(input_1_ip_payload_tdata), - .input_1_ip_payload_tkeep(input_1_ip_payload_tkeep), - .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid & grant[1]), - .input_1_ip_payload_tready(input_1_ip_payload_tready), - .input_1_ip_payload_tlast(input_1_ip_payload_tlast), - .input_1_ip_payload_tuser(input_1_ip_payload_tuser), - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(2), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/rtl/ip_arb_mux_64_4.v b/rtl/ip_arb_mux_64_4.v deleted file mode 100644 index 611ae431c..000000000 --- a/rtl/ip_arb_mux_64_4.v +++ /dev/null @@ -1,336 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * IP 4 port arbitrated multiplexer (64 bit datapath) - */ -module ip_arb_mux_64_4 # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * IP frame inputs - */ - input wire input_0_ip_hdr_valid, - output wire input_0_ip_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [63:0] input_0_ip_payload_tdata, - input wire [7:0] input_0_ip_payload_tkeep, - input wire input_0_ip_payload_tvalid, - output wire input_0_ip_payload_tready, - input wire input_0_ip_payload_tlast, - input wire input_0_ip_payload_tuser, - - input wire input_1_ip_hdr_valid, - output wire input_1_ip_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [63:0] input_1_ip_payload_tdata, - input wire [7:0] input_1_ip_payload_tkeep, - input wire input_1_ip_payload_tvalid, - output wire input_1_ip_payload_tready, - input wire input_1_ip_payload_tlast, - input wire input_1_ip_payload_tuser, - - input wire input_2_ip_hdr_valid, - output wire input_2_ip_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [3:0] input_2_ip_version, - input wire [3:0] input_2_ip_ihl, - input wire [5:0] input_2_ip_dscp, - input wire [1:0] input_2_ip_ecn, - input wire [15:0] input_2_ip_length, - input wire [15:0] input_2_ip_identification, - input wire [2:0] input_2_ip_flags, - input wire [12:0] input_2_ip_fragment_offset, - input wire [7:0] input_2_ip_ttl, - input wire [7:0] input_2_ip_protocol, - input wire [15:0] input_2_ip_header_checksum, - input wire [31:0] input_2_ip_source_ip, - input wire [31:0] input_2_ip_dest_ip, - input wire [63:0] input_2_ip_payload_tdata, - input wire [7:0] input_2_ip_payload_tkeep, - input wire input_2_ip_payload_tvalid, - output wire input_2_ip_payload_tready, - input wire input_2_ip_payload_tlast, - input wire input_2_ip_payload_tuser, - - input wire input_3_ip_hdr_valid, - output wire input_3_ip_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [3:0] input_3_ip_version, - input wire [3:0] input_3_ip_ihl, - input wire [5:0] input_3_ip_dscp, - input wire [1:0] input_3_ip_ecn, - input wire [15:0] input_3_ip_length, - input wire [15:0] input_3_ip_identification, - input wire [2:0] input_3_ip_flags, - input wire [12:0] input_3_ip_fragment_offset, - input wire [7:0] input_3_ip_ttl, - input wire [7:0] input_3_ip_protocol, - input wire [15:0] input_3_ip_header_checksum, - input wire [31:0] input_3_ip_source_ip, - input wire [31:0] input_3_ip_dest_ip, - input wire [63:0] input_3_ip_payload_tdata, - input wire [7:0] input_3_ip_payload_tkeep, - input wire input_3_ip_payload_tvalid, - output wire input_3_ip_payload_tready, - input wire input_3_ip_payload_tlast, - input wire input_3_ip_payload_tuser, - - /* - * IP frame output - */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser -); - -wire [3:0] request; -wire [3:0] acknowledge; -wire [3:0] grant; -wire grant_valid; -wire [1:0] grant_encoded; - -assign acknowledge[0] = input_0_ip_payload_tvalid & input_0_ip_payload_tready & input_0_ip_payload_tlast; -assign request[0] = input_0_ip_hdr_valid; -assign acknowledge[1] = input_1_ip_payload_tvalid & input_1_ip_payload_tready & input_1_ip_payload_tlast; -assign request[1] = input_1_ip_hdr_valid; -assign acknowledge[2] = input_2_ip_payload_tvalid & input_2_ip_payload_tready & input_2_ip_payload_tlast; -assign request[2] = input_2_ip_hdr_valid; -assign acknowledge[3] = input_3_ip_payload_tvalid & input_3_ip_payload_tready & input_3_ip_payload_tlast; -assign request[3] = input_3_ip_hdr_valid; - -// mux instance -ip_mux_64_4 -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_ip_hdr_valid(input_0_ip_hdr_valid & grant[0]), - .input_0_ip_hdr_ready(input_0_ip_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_ip_payload_tdata(input_0_ip_payload_tdata), - .input_0_ip_payload_tkeep(input_0_ip_payload_tkeep), - .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid & grant[0]), - .input_0_ip_payload_tready(input_0_ip_payload_tready), - .input_0_ip_payload_tlast(input_0_ip_payload_tlast), - .input_0_ip_payload_tuser(input_0_ip_payload_tuser), - .input_1_ip_hdr_valid(input_1_ip_hdr_valid & grant[1]), - .input_1_ip_hdr_ready(input_1_ip_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_ip_payload_tdata(input_1_ip_payload_tdata), - .input_1_ip_payload_tkeep(input_1_ip_payload_tkeep), - .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid & grant[1]), - .input_1_ip_payload_tready(input_1_ip_payload_tready), - .input_1_ip_payload_tlast(input_1_ip_payload_tlast), - .input_1_ip_payload_tuser(input_1_ip_payload_tuser), - .input_2_ip_hdr_valid(input_2_ip_hdr_valid & grant[2]), - .input_2_ip_hdr_ready(input_2_ip_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_ip_payload_tdata(input_2_ip_payload_tdata), - .input_2_ip_payload_tkeep(input_2_ip_payload_tkeep), - .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid & grant[2]), - .input_2_ip_payload_tready(input_2_ip_payload_tready), - .input_2_ip_payload_tlast(input_2_ip_payload_tlast), - .input_2_ip_payload_tuser(input_2_ip_payload_tuser), - .input_3_ip_hdr_valid(input_3_ip_hdr_valid & grant[3]), - .input_3_ip_hdr_ready(input_3_ip_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_ip_payload_tdata(input_3_ip_payload_tdata), - .input_3_ip_payload_tkeep(input_3_ip_payload_tkeep), - .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid & grant[3]), - .input_3_ip_payload_tready(input_3_ip_payload_tready), - .input_3_ip_payload_tlast(input_3_ip_payload_tlast), - .input_3_ip_payload_tuser(input_3_ip_payload_tuser), - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/tb/test_ip_arb_mux_4.py b/tb/test_ip_arb_mux_4.py index 6e11001f9..ad3c3885a 100755 --- a/tb/test_ip_arb_mux_4.py +++ b/tb/test_ip_arb_mux_4.py @@ -28,13 +28,12 @@ import os import ip_ep -module = 'ip_arb_mux_4' -testbench = 'test_%s' % module +module = 'ip_arb_mux' +testbench = 'test_%s_4' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/ip_mux_4.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -45,294 +44,183 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + ARB_TYPE = "PRIORITY" + LSB_PRIORITY = "HIGH" + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_ip_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_ip_version = Signal(intbv(0)[4:]) - input_0_ip_ihl = Signal(intbv(0)[4:]) - input_0_ip_dscp = Signal(intbv(0)[6:]) - input_0_ip_ecn = Signal(intbv(0)[2:]) - input_0_ip_length = Signal(intbv(0)[16:]) - input_0_ip_identification = Signal(intbv(0)[16:]) - input_0_ip_flags = Signal(intbv(0)[3:]) - input_0_ip_fragment_offset = Signal(intbv(0)[13:]) - input_0_ip_ttl = Signal(intbv(0)[8:]) - input_0_ip_protocol = Signal(intbv(0)[8:]) - input_0_ip_header_checksum = Signal(intbv(0)[16:]) - input_0_ip_source_ip = Signal(intbv(0)[32:]) - input_0_ip_dest_ip = Signal(intbv(0)[32:]) - input_0_ip_payload_tdata = Signal(intbv(0)[8:]) - input_0_ip_payload_tvalid = Signal(bool(0)) - input_0_ip_payload_tlast = Signal(bool(0)) - input_0_ip_payload_tuser = Signal(bool(0)) - input_1_ip_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_ip_version = Signal(intbv(0)[4:]) - input_1_ip_ihl = Signal(intbv(0)[4:]) - input_1_ip_dscp = Signal(intbv(0)[6:]) - input_1_ip_ecn = Signal(intbv(0)[2:]) - input_1_ip_length = Signal(intbv(0)[16:]) - input_1_ip_identification = Signal(intbv(0)[16:]) - input_1_ip_flags = Signal(intbv(0)[3:]) - input_1_ip_fragment_offset = Signal(intbv(0)[13:]) - input_1_ip_ttl = Signal(intbv(0)[8:]) - input_1_ip_protocol = Signal(intbv(0)[8:]) - input_1_ip_header_checksum = Signal(intbv(0)[16:]) - input_1_ip_source_ip = Signal(intbv(0)[32:]) - input_1_ip_dest_ip = Signal(intbv(0)[32:]) - input_1_ip_payload_tdata = Signal(intbv(0)[8:]) - input_1_ip_payload_tvalid = Signal(bool(0)) - input_1_ip_payload_tlast = Signal(bool(0)) - input_1_ip_payload_tuser = Signal(bool(0)) - input_2_ip_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_ip_version = Signal(intbv(0)[4:]) - input_2_ip_ihl = Signal(intbv(0)[4:]) - input_2_ip_dscp = Signal(intbv(0)[6:]) - input_2_ip_ecn = Signal(intbv(0)[2:]) - input_2_ip_length = Signal(intbv(0)[16:]) - input_2_ip_identification = Signal(intbv(0)[16:]) - input_2_ip_flags = Signal(intbv(0)[3:]) - input_2_ip_fragment_offset = Signal(intbv(0)[13:]) - input_2_ip_ttl = Signal(intbv(0)[8:]) - input_2_ip_protocol = Signal(intbv(0)[8:]) - input_2_ip_header_checksum = Signal(intbv(0)[16:]) - input_2_ip_source_ip = Signal(intbv(0)[32:]) - input_2_ip_dest_ip = Signal(intbv(0)[32:]) - input_2_ip_payload_tdata = Signal(intbv(0)[8:]) - input_2_ip_payload_tvalid = Signal(bool(0)) - input_2_ip_payload_tlast = Signal(bool(0)) - input_2_ip_payload_tuser = Signal(bool(0)) - input_3_ip_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_ip_version = Signal(intbv(0)[4:]) - input_3_ip_ihl = Signal(intbv(0)[4:]) - input_3_ip_dscp = Signal(intbv(0)[6:]) - input_3_ip_ecn = Signal(intbv(0)[2:]) - input_3_ip_length = Signal(intbv(0)[16:]) - input_3_ip_identification = Signal(intbv(0)[16:]) - input_3_ip_flags = Signal(intbv(0)[3:]) - input_3_ip_fragment_offset = Signal(intbv(0)[13:]) - input_3_ip_ttl = Signal(intbv(0)[8:]) - input_3_ip_protocol = Signal(intbv(0)[8:]) - input_3_ip_header_checksum = Signal(intbv(0)[16:]) - input_3_ip_source_ip = Signal(intbv(0)[32:]) - input_3_ip_dest_ip = Signal(intbv(0)[32:]) - input_3_ip_payload_tdata = Signal(intbv(0)[8:]) - input_3_ip_payload_tvalid = Signal(bool(0)) - input_3_ip_payload_tlast = Signal(bool(0)) - input_3_ip_payload_tuser = Signal(bool(0)) + s_ip_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_version_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_ihl_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_dscp_list = [Signal(intbv(0)[6:]) for i in range(S_COUNT)] + s_ip_ecn_list = [Signal(intbv(0)[2:]) for i in range(S_COUNT)] + s_ip_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_identification_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_flags_list = [Signal(intbv(0)[3:]) for i in range(S_COUNT)] + s_ip_fragment_offset_list = [Signal(intbv(0)[13:]) for i in range(S_COUNT)] + s_ip_ttl_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_protocol_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_header_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_source_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_dest_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_ip_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_ip_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_ip_payload_tready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) + s_ip_hdr_valid = ConcatSignal(*reversed(s_ip_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_ip_version = ConcatSignal(*reversed(s_ip_version_list)) + s_ip_ihl = ConcatSignal(*reversed(s_ip_ihl_list)) + s_ip_dscp = ConcatSignal(*reversed(s_ip_dscp_list)) + s_ip_ecn = ConcatSignal(*reversed(s_ip_ecn_list)) + s_ip_length = ConcatSignal(*reversed(s_ip_length_list)) + s_ip_identification = ConcatSignal(*reversed(s_ip_identification_list)) + s_ip_flags = ConcatSignal(*reversed(s_ip_flags_list)) + s_ip_fragment_offset = ConcatSignal(*reversed(s_ip_fragment_offset_list)) + s_ip_ttl = ConcatSignal(*reversed(s_ip_ttl_list)) + s_ip_protocol = ConcatSignal(*reversed(s_ip_protocol_list)) + s_ip_header_checksum = ConcatSignal(*reversed(s_ip_header_checksum_list)) + s_ip_source_ip = ConcatSignal(*reversed(s_ip_source_ip_list)) + s_ip_dest_ip = ConcatSignal(*reversed(s_ip_dest_ip_list)) + s_ip_payload_axis_tdata = ConcatSignal(*reversed(s_ip_payload_axis_tdata_list)) + s_ip_payload_axis_tkeep = ConcatSignal(*reversed(s_ip_payload_axis_tkeep_list)) + s_ip_payload_axis_tvalid = ConcatSignal(*reversed(s_ip_payload_axis_tvalid_list)) + s_ip_payload_axis_tlast = ConcatSignal(*reversed(s_ip_payload_axis_tlast_list)) + s_ip_payload_axis_tid = ConcatSignal(*reversed(s_ip_payload_axis_tid_list)) + s_ip_payload_axis_tdest = ConcatSignal(*reversed(s_ip_payload_axis_tdest_list)) + s_ip_payload_axis_tuser = ConcatSignal(*reversed(s_ip_payload_axis_tuser_list)) + + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) # Outputs - input_0_ip_hdr_ready = Signal(bool(0)) - input_0_ip_payload_tready = Signal(bool(0)) - input_1_ip_hdr_ready = Signal(bool(0)) - input_1_ip_payload_tready = Signal(bool(0)) - input_2_ip_hdr_ready = Signal(bool(0)) - input_2_ip_payload_tready = Signal(bool(0)) - input_3_ip_hdr_ready = Signal(bool(0)) - input_3_ip_payload_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_ip_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_ip_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + s_ip_hdr_ready_list = [s_ip_hdr_ready(i) for i in range(S_COUNT)] + s_ip_payload_axis_tready_list = [s_ip_payload_axis_tready(i) for i in range(S_COUNT)] + + m_ip_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_ip_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_ip_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_ip_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = ip_ep.IPFrameSource() + for k in range(S_COUNT): + s = ip_ep.IPFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - ip_hdr_ready=input_0_ip_hdr_ready, - ip_hdr_valid=input_0_ip_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - eth_type=input_0_eth_type, - ip_version=input_0_ip_version, - ip_ihl=input_0_ip_ihl, - ip_dscp=input_0_ip_dscp, - ip_ecn=input_0_ip_ecn, - ip_length=input_0_ip_length, - ip_identification=input_0_ip_identification, - ip_flags=input_0_ip_flags, - ip_fragment_offset=input_0_ip_fragment_offset, - ip_ttl=input_0_ip_ttl, - ip_protocol=input_0_ip_protocol, - ip_header_checksum=input_0_ip_header_checksum, - ip_source_ip=input_0_ip_source_ip, - ip_dest_ip=input_0_ip_dest_ip, - ip_payload_tdata=input_0_ip_payload_tdata, - ip_payload_tvalid=input_0_ip_payload_tvalid, - ip_payload_tready=input_0_ip_payload_tready, - ip_payload_tlast=input_0_ip_payload_tlast, - ip_payload_tuser=input_0_ip_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = ip_ep.IPFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - ip_hdr_ready=input_1_ip_hdr_ready, - ip_hdr_valid=input_1_ip_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - eth_type=input_1_eth_type, - ip_version=input_1_ip_version, - ip_ihl=input_1_ip_ihl, - ip_dscp=input_1_ip_dscp, - ip_ecn=input_1_ip_ecn, - ip_length=input_1_ip_length, - ip_identification=input_1_ip_identification, - ip_flags=input_1_ip_flags, - ip_fragment_offset=input_1_ip_fragment_offset, - ip_ttl=input_1_ip_ttl, - ip_protocol=input_1_ip_protocol, - ip_header_checksum=input_1_ip_header_checksum, - ip_source_ip=input_1_ip_source_ip, - ip_dest_ip=input_1_ip_dest_ip, - ip_payload_tdata=input_1_ip_payload_tdata, - ip_payload_tvalid=input_1_ip_payload_tvalid, - ip_payload_tready=input_1_ip_payload_tready, - ip_payload_tlast=input_1_ip_payload_tlast, - ip_payload_tuser=input_1_ip_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = ip_ep.IPFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - ip_hdr_ready=input_2_ip_hdr_ready, - ip_hdr_valid=input_2_ip_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - ip_version=input_2_ip_version, - ip_ihl=input_2_ip_ihl, - ip_dscp=input_2_ip_dscp, - ip_ecn=input_2_ip_ecn, - ip_length=input_2_ip_length, - ip_identification=input_2_ip_identification, - ip_flags=input_2_ip_flags, - ip_fragment_offset=input_2_ip_fragment_offset, - ip_ttl=input_2_ip_ttl, - ip_protocol=input_2_ip_protocol, - ip_header_checksum=input_2_ip_header_checksum, - ip_source_ip=input_2_ip_source_ip, - ip_dest_ip=input_2_ip_dest_ip, - ip_payload_tdata=input_2_ip_payload_tdata, - ip_payload_tvalid=input_2_ip_payload_tvalid, - ip_payload_tready=input_2_ip_payload_tready, - ip_payload_tlast=input_2_ip_payload_tlast, - ip_payload_tuser=input_2_ip_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = ip_ep.IPFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - ip_hdr_ready=input_3_ip_hdr_ready, - ip_hdr_valid=input_3_ip_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - ip_version=input_3_ip_version, - ip_ihl=input_3_ip_ihl, - ip_dscp=input_3_ip_dscp, - ip_ecn=input_3_ip_ecn, - ip_length=input_3_ip_length, - ip_identification=input_3_ip_identification, - ip_flags=input_3_ip_flags, - ip_fragment_offset=input_3_ip_fragment_offset, - ip_ttl=input_3_ip_ttl, - ip_protocol=input_3_ip_protocol, - ip_header_checksum=input_3_ip_header_checksum, - ip_source_ip=input_3_ip_source_ip, - ip_dest_ip=input_3_ip_dest_ip, - ip_payload_tdata=input_3_ip_payload_tdata, - ip_payload_tvalid=input_3_ip_payload_tvalid, - ip_payload_tready=input_3_ip_payload_tready, - ip_payload_tlast=input_3_ip_payload_tlast, - ip_payload_tuser=input_3_ip_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + ip_hdr_ready=s_ip_hdr_ready_list[k], + ip_hdr_valid=s_ip_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + ip_version=s_ip_version_list[k], + ip_ihl=s_ip_ihl_list[k], + ip_dscp=s_ip_dscp_list[k], + ip_ecn=s_ip_ecn_list[k], + ip_length=s_ip_length_list[k], + ip_identification=s_ip_identification_list[k], + ip_flags=s_ip_flags_list[k], + ip_fragment_offset=s_ip_fragment_offset_list[k], + ip_ttl=s_ip_ttl_list[k], + ip_protocol=s_ip_protocol_list[k], + ip_header_checksum=s_ip_header_checksum_list[k], + ip_source_ip=s_ip_source_ip_list[k], + ip_dest_ip=s_ip_dest_ip_list[k], + ip_payload_tdata=s_ip_payload_axis_tdata_list[k], + ip_payload_tkeep=s_ip_payload_axis_tkeep_list[k], + ip_payload_tvalid=s_ip_payload_axis_tvalid_list[k], + ip_payload_tready=s_ip_payload_axis_tready_list[k], + ip_payload_tlast=s_ip_payload_axis_tlast_list[k], + ip_payload_tuser=s_ip_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = ip_ep.IPFrameSink() sink_logic = sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tkeep=m_ip_payload_axis_tkeep, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -347,122 +235,59 @@ def bench(): rst=rst, current_test=current_test, - input_0_ip_hdr_valid=input_0_ip_hdr_valid, - input_0_ip_hdr_ready=input_0_ip_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_ip_version=input_0_ip_version, - input_0_ip_ihl=input_0_ip_ihl, - input_0_ip_dscp=input_0_ip_dscp, - input_0_ip_ecn=input_0_ip_ecn, - input_0_ip_length=input_0_ip_length, - input_0_ip_identification=input_0_ip_identification, - input_0_ip_flags=input_0_ip_flags, - input_0_ip_fragment_offset=input_0_ip_fragment_offset, - input_0_ip_ttl=input_0_ip_ttl, - input_0_ip_protocol=input_0_ip_protocol, - input_0_ip_header_checksum=input_0_ip_header_checksum, - input_0_ip_source_ip=input_0_ip_source_ip, - input_0_ip_dest_ip=input_0_ip_dest_ip, - input_0_ip_payload_tdata=input_0_ip_payload_tdata, - input_0_ip_payload_tvalid=input_0_ip_payload_tvalid, - input_0_ip_payload_tready=input_0_ip_payload_tready, - input_0_ip_payload_tlast=input_0_ip_payload_tlast, - input_0_ip_payload_tuser=input_0_ip_payload_tuser, - input_1_ip_hdr_valid=input_1_ip_hdr_valid, - input_1_ip_hdr_ready=input_1_ip_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_ip_version=input_1_ip_version, - input_1_ip_ihl=input_1_ip_ihl, - input_1_ip_dscp=input_1_ip_dscp, - input_1_ip_ecn=input_1_ip_ecn, - input_1_ip_length=input_1_ip_length, - input_1_ip_identification=input_1_ip_identification, - input_1_ip_flags=input_1_ip_flags, - input_1_ip_fragment_offset=input_1_ip_fragment_offset, - input_1_ip_ttl=input_1_ip_ttl, - input_1_ip_protocol=input_1_ip_protocol, - input_1_ip_header_checksum=input_1_ip_header_checksum, - input_1_ip_source_ip=input_1_ip_source_ip, - input_1_ip_dest_ip=input_1_ip_dest_ip, - input_1_ip_payload_tdata=input_1_ip_payload_tdata, - input_1_ip_payload_tvalid=input_1_ip_payload_tvalid, - input_1_ip_payload_tready=input_1_ip_payload_tready, - input_1_ip_payload_tlast=input_1_ip_payload_tlast, - input_1_ip_payload_tuser=input_1_ip_payload_tuser, - input_2_ip_hdr_valid=input_2_ip_hdr_valid, - input_2_ip_hdr_ready=input_2_ip_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_ip_version=input_2_ip_version, - input_2_ip_ihl=input_2_ip_ihl, - input_2_ip_dscp=input_2_ip_dscp, - input_2_ip_ecn=input_2_ip_ecn, - input_2_ip_length=input_2_ip_length, - input_2_ip_identification=input_2_ip_identification, - input_2_ip_flags=input_2_ip_flags, - input_2_ip_fragment_offset=input_2_ip_fragment_offset, - input_2_ip_ttl=input_2_ip_ttl, - input_2_ip_protocol=input_2_ip_protocol, - input_2_ip_header_checksum=input_2_ip_header_checksum, - input_2_ip_source_ip=input_2_ip_source_ip, - input_2_ip_dest_ip=input_2_ip_dest_ip, - input_2_ip_payload_tdata=input_2_ip_payload_tdata, - input_2_ip_payload_tvalid=input_2_ip_payload_tvalid, - input_2_ip_payload_tready=input_2_ip_payload_tready, - input_2_ip_payload_tlast=input_2_ip_payload_tlast, - input_2_ip_payload_tuser=input_2_ip_payload_tuser, - input_3_ip_hdr_valid=input_3_ip_hdr_valid, - input_3_ip_hdr_ready=input_3_ip_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_ip_version=input_3_ip_version, - input_3_ip_ihl=input_3_ip_ihl, - input_3_ip_dscp=input_3_ip_dscp, - input_3_ip_ecn=input_3_ip_ecn, - input_3_ip_length=input_3_ip_length, - input_3_ip_identification=input_3_ip_identification, - input_3_ip_flags=input_3_ip_flags, - input_3_ip_fragment_offset=input_3_ip_fragment_offset, - input_3_ip_ttl=input_3_ip_ttl, - input_3_ip_protocol=input_3_ip_protocol, - input_3_ip_header_checksum=input_3_ip_header_checksum, - input_3_ip_source_ip=input_3_ip_source_ip, - input_3_ip_dest_ip=input_3_ip_dest_ip, - input_3_ip_payload_tdata=input_3_ip_payload_tdata, - input_3_ip_payload_tvalid=input_3_ip_payload_tvalid, - input_3_ip_payload_tready=input_3_ip_payload_tready, - input_3_ip_payload_tlast=input_3_ip_payload_tlast, - input_3_ip_payload_tuser=input_3_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tid=s_ip_payload_axis_tid, + s_ip_payload_axis_tdest=s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tid=m_ip_payload_axis_tid, + m_ip_payload_axis_tdest=m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser ) @always(delay(4)) @@ -506,7 +331,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -539,7 +364,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -591,8 +416,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -649,8 +474,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -707,23 +532,23 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_ip_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge yield sink.wait() @@ -781,12 +606,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + while s_ip_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -849,17 +674,17 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) yield clk.posedge yield delay(800) yield clk.posedge - source_1.send(test_frame1) + source_list[1].send(test_frame1) yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_ip_arb_mux_4.v b/tb/test_ip_arb_mux_4.v index 5a14131b7..400c0bb1c 100644 --- a/tb/test_ip_arb_mux_4.v +++ b/tb/test_ip_arb_mux_4.v @@ -27,134 +27,85 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for ip_arb_mux_4 + * Testbench for ip_arb_mux */ module test_ip_arb_mux_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter ARB_TYPE = "PRIORITY"; +parameter LSB_PRIORITY = "HIGH"; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_ip_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [3:0] input_0_ip_version = 0; -reg [3:0] input_0_ip_ihl = 0; -reg [5:0] input_0_ip_dscp = 0; -reg [1:0] input_0_ip_ecn = 0; -reg [15:0] input_0_ip_length = 0; -reg [15:0] input_0_ip_identification = 0; -reg [2:0] input_0_ip_flags = 0; -reg [12:0] input_0_ip_fragment_offset = 0; -reg [7:0] input_0_ip_ttl = 0; -reg [7:0] input_0_ip_protocol = 0; -reg [15:0] input_0_ip_header_checksum = 0; -reg [31:0] input_0_ip_source_ip = 0; -reg [31:0] input_0_ip_dest_ip = 0; -reg [7:0] input_0_ip_payload_tdata = 0; -reg input_0_ip_payload_tvalid = 0; -reg input_0_ip_payload_tlast = 0; -reg input_0_ip_payload_tuser = 0; -reg input_1_ip_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [3:0] input_1_ip_version = 0; -reg [3:0] input_1_ip_ihl = 0; -reg [5:0] input_1_ip_dscp = 0; -reg [1:0] input_1_ip_ecn = 0; -reg [15:0] input_1_ip_length = 0; -reg [15:0] input_1_ip_identification = 0; -reg [2:0] input_1_ip_flags = 0; -reg [12:0] input_1_ip_fragment_offset = 0; -reg [7:0] input_1_ip_ttl = 0; -reg [7:0] input_1_ip_protocol = 0; -reg [15:0] input_1_ip_header_checksum = 0; -reg [31:0] input_1_ip_source_ip = 0; -reg [31:0] input_1_ip_dest_ip = 0; -reg [7:0] input_1_ip_payload_tdata = 0; -reg input_1_ip_payload_tvalid = 0; -reg input_1_ip_payload_tlast = 0; -reg input_1_ip_payload_tuser = 0; -reg input_2_ip_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [3:0] input_2_ip_version = 0; -reg [3:0] input_2_ip_ihl = 0; -reg [5:0] input_2_ip_dscp = 0; -reg [1:0] input_2_ip_ecn = 0; -reg [15:0] input_2_ip_length = 0; -reg [15:0] input_2_ip_identification = 0; -reg [2:0] input_2_ip_flags = 0; -reg [12:0] input_2_ip_fragment_offset = 0; -reg [7:0] input_2_ip_ttl = 0; -reg [7:0] input_2_ip_protocol = 0; -reg [15:0] input_2_ip_header_checksum = 0; -reg [31:0] input_2_ip_source_ip = 0; -reg [31:0] input_2_ip_dest_ip = 0; -reg [7:0] input_2_ip_payload_tdata = 0; -reg input_2_ip_payload_tvalid = 0; -reg input_2_ip_payload_tlast = 0; -reg input_2_ip_payload_tuser = 0; -reg input_3_ip_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [3:0] input_3_ip_version = 0; -reg [3:0] input_3_ip_ihl = 0; -reg [5:0] input_3_ip_dscp = 0; -reg [1:0] input_3_ip_ecn = 0; -reg [15:0] input_3_ip_length = 0; -reg [15:0] input_3_ip_identification = 0; -reg [2:0] input_3_ip_flags = 0; -reg [12:0] input_3_ip_fragment_offset = 0; -reg [7:0] input_3_ip_ttl = 0; -reg [7:0] input_3_ip_protocol = 0; -reg [15:0] input_3_ip_header_checksum = 0; -reg [31:0] input_3_ip_source_ip = 0; -reg [31:0] input_3_ip_dest_ip = 0; -reg [7:0] input_3_ip_payload_tdata = 0; -reg input_3_ip_payload_tvalid = 0; -reg input_3_ip_payload_tlast = 0; -reg input_3_ip_payload_tuser = 0; +reg [S_COUNT-1:0] s_ip_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*4-1:0] s_ip_version = 0; +reg [S_COUNT*4-1:0] s_ip_ihl = 0; +reg [S_COUNT*6-1:0] s_ip_dscp = 0; +reg [S_COUNT*2-1:0] s_ip_ecn = 0; +reg [S_COUNT*16-1:0] s_ip_length = 0; +reg [S_COUNT*16-1:0] s_ip_identification = 0; +reg [S_COUNT*3-1:0] s_ip_flags = 0; +reg [S_COUNT*13-1:0] s_ip_fragment_offset = 0; +reg [S_COUNT*8-1:0] s_ip_ttl = 0; +reg [S_COUNT*8-1:0] s_ip_protocol = 0; +reg [S_COUNT*16-1:0] s_ip_header_checksum = 0; +reg [S_COUNT*32-1:0] s_ip_source_ip = 0; +reg [S_COUNT*32-1:0] s_ip_dest_ip = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_ip_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_ip_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_ip_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_ip_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_ip_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_ip_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_ip_payload_axis_tuser = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; // Outputs -wire input_0_ip_payload_tready; -wire input_0_ip_hdr_ready; -wire input_1_ip_payload_tready; -wire input_1_ip_hdr_ready; -wire input_2_ip_payload_tready; -wire input_2_ip_hdr_ready; -wire input_3_ip_payload_tready; -wire input_3_ip_hdr_ready; +wire [S_COUNT-1:0] s_ip_hdr_ready; +wire [S_COUNT-1:0] s_ip_payload_axis_tready; -wire output_ip_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [7:0] output_ip_payload_tdata; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire m_ip_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [DATA_WIDTH-1:0] m_ip_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_ip_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_ip_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_ip_payload_axis_tuser; initial begin // myhdl integration @@ -162,123 +113,60 @@ initial begin clk, rst, current_test, - input_0_ip_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_ip_version, - input_0_ip_ihl, - input_0_ip_dscp, - input_0_ip_ecn, - input_0_ip_length, - input_0_ip_identification, - input_0_ip_flags, - input_0_ip_fragment_offset, - input_0_ip_ttl, - input_0_ip_protocol, - input_0_ip_header_checksum, - input_0_ip_source_ip, - input_0_ip_dest_ip, - input_0_ip_payload_tdata, - input_0_ip_payload_tvalid, - input_0_ip_payload_tlast, - input_0_ip_payload_tuser, - input_1_ip_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_ip_version, - input_1_ip_ihl, - input_1_ip_dscp, - input_1_ip_ecn, - input_1_ip_length, - input_1_ip_identification, - input_1_ip_flags, - input_1_ip_fragment_offset, - input_1_ip_ttl, - input_1_ip_protocol, - input_1_ip_header_checksum, - input_1_ip_source_ip, - input_1_ip_dest_ip, - input_1_ip_payload_tdata, - input_1_ip_payload_tvalid, - input_1_ip_payload_tlast, - input_1_ip_payload_tuser, - input_2_ip_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_ip_version, - input_2_ip_ihl, - input_2_ip_dscp, - input_2_ip_ecn, - input_2_ip_length, - input_2_ip_identification, - input_2_ip_flags, - input_2_ip_fragment_offset, - input_2_ip_ttl, - input_2_ip_protocol, - input_2_ip_header_checksum, - input_2_ip_source_ip, - input_2_ip_dest_ip, - input_2_ip_payload_tdata, - input_2_ip_payload_tvalid, - input_2_ip_payload_tlast, - input_2_ip_payload_tuser, - input_3_ip_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_ip_version, - input_3_ip_ihl, - input_3_ip_dscp, - input_3_ip_ecn, - input_3_ip_length, - input_3_ip_identification, - input_3_ip_flags, - input_3_ip_fragment_offset, - input_3_ip_ttl, - input_3_ip_protocol, - input_3_ip_header_checksum, - input_3_ip_source_ip, - input_3_ip_dest_ip, - input_3_ip_payload_tdata, - input_3_ip_payload_tvalid, - input_3_ip_payload_tlast, - input_3_ip_payload_tuser, - output_ip_hdr_ready, - output_ip_payload_tready + s_ip_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tid, + s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready ); $to_myhdl( - input_0_ip_hdr_ready, - input_0_ip_payload_tready, - input_1_ip_hdr_ready, - input_1_ip_payload_tready, - input_2_ip_hdr_ready, - input_2_ip_payload_tready, - input_3_ip_hdr_ready, - input_3_ip_payload_tready, - output_ip_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_ip_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tid, + m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser ); // dump file @@ -286,127 +174,77 @@ initial begin $dumpvars(0, test_ip_arb_mux_4); end -ip_arb_mux_4 +ip_arb_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) +) UUT ( .clk(clk), .rst(rst), - // IP frame inputs - .input_0_ip_hdr_valid(input_0_ip_hdr_valid), - .input_0_ip_hdr_ready(input_0_ip_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_ip_payload_tdata(input_0_ip_payload_tdata), - .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid), - .input_0_ip_payload_tready(input_0_ip_payload_tready), - .input_0_ip_payload_tlast(input_0_ip_payload_tlast), - .input_0_ip_payload_tuser(input_0_ip_payload_tuser), - .input_1_ip_hdr_valid(input_1_ip_hdr_valid), - .input_1_ip_hdr_ready(input_1_ip_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_ip_payload_tdata(input_1_ip_payload_tdata), - .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid), - .input_1_ip_payload_tready(input_1_ip_payload_tready), - .input_1_ip_payload_tlast(input_1_ip_payload_tlast), - .input_1_ip_payload_tuser(input_1_ip_payload_tuser), - .input_2_ip_hdr_valid(input_2_ip_hdr_valid), - .input_2_ip_hdr_ready(input_2_ip_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_ip_payload_tdata(input_2_ip_payload_tdata), - .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid), - .input_2_ip_payload_tready(input_2_ip_payload_tready), - .input_2_ip_payload_tlast(input_2_ip_payload_tlast), - .input_2_ip_payload_tuser(input_2_ip_payload_tuser), - .input_3_ip_hdr_valid(input_3_ip_hdr_valid), - .input_3_ip_hdr_ready(input_3_ip_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_ip_payload_tdata(input_3_ip_payload_tdata), - .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid), - .input_3_ip_payload_tready(input_3_ip_payload_tready), - .input_3_ip_payload_tlast(input_3_ip_payload_tlast), - .input_3_ip_payload_tuser(input_3_ip_payload_tuser), - // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser) + // Ethernet frame inputs + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tid(s_ip_payload_axis_tid), + .s_ip_payload_axis_tdest(s_ip_payload_axis_tdest), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), + // Ethernet frame output + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tid(m_ip_payload_axis_tid), + .m_ip_payload_axis_tdest(m_ip_payload_axis_tdest), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser) ); endmodule diff --git a/tb/test_ip_arb_mux_64_4.py b/tb/test_ip_arb_mux_64_4.py index 44cc9ac04..cf17d9654 100755 --- a/tb/test_ip_arb_mux_64_4.py +++ b/tb/test_ip_arb_mux_64_4.py @@ -28,13 +28,12 @@ import os import ip_ep -module = 'ip_arb_mux_64_4' -testbench = 'test_%s' % module +module = 'ip_arb_mux' +testbench = 'test_%s_64_4' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/ip_mux_64_4.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -45,304 +44,183 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + ARB_TYPE = "PRIORITY" + LSB_PRIORITY = "HIGH" + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_ip_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_ip_version = Signal(intbv(0)[4:]) - input_0_ip_ihl = Signal(intbv(0)[4:]) - input_0_ip_dscp = Signal(intbv(0)[6:]) - input_0_ip_ecn = Signal(intbv(0)[2:]) - input_0_ip_length = Signal(intbv(0)[16:]) - input_0_ip_identification = Signal(intbv(0)[16:]) - input_0_ip_flags = Signal(intbv(0)[3:]) - input_0_ip_fragment_offset = Signal(intbv(0)[13:]) - input_0_ip_ttl = Signal(intbv(0)[8:]) - input_0_ip_protocol = Signal(intbv(0)[8:]) - input_0_ip_header_checksum = Signal(intbv(0)[16:]) - input_0_ip_source_ip = Signal(intbv(0)[32:]) - input_0_ip_dest_ip = Signal(intbv(0)[32:]) - input_0_ip_payload_tdata = Signal(intbv(0)[64:]) - input_0_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_0_ip_payload_tvalid = Signal(bool(0)) - input_0_ip_payload_tlast = Signal(bool(0)) - input_0_ip_payload_tuser = Signal(bool(0)) - input_1_ip_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_ip_version = Signal(intbv(0)[4:]) - input_1_ip_ihl = Signal(intbv(0)[4:]) - input_1_ip_dscp = Signal(intbv(0)[6:]) - input_1_ip_ecn = Signal(intbv(0)[2:]) - input_1_ip_length = Signal(intbv(0)[16:]) - input_1_ip_identification = Signal(intbv(0)[16:]) - input_1_ip_flags = Signal(intbv(0)[3:]) - input_1_ip_fragment_offset = Signal(intbv(0)[13:]) - input_1_ip_ttl = Signal(intbv(0)[8:]) - input_1_ip_protocol = Signal(intbv(0)[8:]) - input_1_ip_header_checksum = Signal(intbv(0)[16:]) - input_1_ip_source_ip = Signal(intbv(0)[32:]) - input_1_ip_dest_ip = Signal(intbv(0)[32:]) - input_1_ip_payload_tdata = Signal(intbv(0)[64:]) - input_1_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_1_ip_payload_tvalid = Signal(bool(0)) - input_1_ip_payload_tlast = Signal(bool(0)) - input_1_ip_payload_tuser = Signal(bool(0)) - input_2_ip_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_ip_version = Signal(intbv(0)[4:]) - input_2_ip_ihl = Signal(intbv(0)[4:]) - input_2_ip_dscp = Signal(intbv(0)[6:]) - input_2_ip_ecn = Signal(intbv(0)[2:]) - input_2_ip_length = Signal(intbv(0)[16:]) - input_2_ip_identification = Signal(intbv(0)[16:]) - input_2_ip_flags = Signal(intbv(0)[3:]) - input_2_ip_fragment_offset = Signal(intbv(0)[13:]) - input_2_ip_ttl = Signal(intbv(0)[8:]) - input_2_ip_protocol = Signal(intbv(0)[8:]) - input_2_ip_header_checksum = Signal(intbv(0)[16:]) - input_2_ip_source_ip = Signal(intbv(0)[32:]) - input_2_ip_dest_ip = Signal(intbv(0)[32:]) - input_2_ip_payload_tdata = Signal(intbv(0)[64:]) - input_2_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_2_ip_payload_tvalid = Signal(bool(0)) - input_2_ip_payload_tlast = Signal(bool(0)) - input_2_ip_payload_tuser = Signal(bool(0)) - input_3_ip_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_ip_version = Signal(intbv(0)[4:]) - input_3_ip_ihl = Signal(intbv(0)[4:]) - input_3_ip_dscp = Signal(intbv(0)[6:]) - input_3_ip_ecn = Signal(intbv(0)[2:]) - input_3_ip_length = Signal(intbv(0)[16:]) - input_3_ip_identification = Signal(intbv(0)[16:]) - input_3_ip_flags = Signal(intbv(0)[3:]) - input_3_ip_fragment_offset = Signal(intbv(0)[13:]) - input_3_ip_ttl = Signal(intbv(0)[8:]) - input_3_ip_protocol = Signal(intbv(0)[8:]) - input_3_ip_header_checksum = Signal(intbv(0)[16:]) - input_3_ip_source_ip = Signal(intbv(0)[32:]) - input_3_ip_dest_ip = Signal(intbv(0)[32:]) - input_3_ip_payload_tdata = Signal(intbv(0)[64:]) - input_3_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_3_ip_payload_tvalid = Signal(bool(0)) - input_3_ip_payload_tlast = Signal(bool(0)) - input_3_ip_payload_tuser = Signal(bool(0)) + s_ip_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_version_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_ihl_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_dscp_list = [Signal(intbv(0)[6:]) for i in range(S_COUNT)] + s_ip_ecn_list = [Signal(intbv(0)[2:]) for i in range(S_COUNT)] + s_ip_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_identification_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_flags_list = [Signal(intbv(0)[3:]) for i in range(S_COUNT)] + s_ip_fragment_offset_list = [Signal(intbv(0)[13:]) for i in range(S_COUNT)] + s_ip_ttl_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_protocol_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_header_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_source_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_dest_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_ip_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_ip_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_ip_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_ip_payload_tready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) + s_ip_hdr_valid = ConcatSignal(*reversed(s_ip_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_ip_version = ConcatSignal(*reversed(s_ip_version_list)) + s_ip_ihl = ConcatSignal(*reversed(s_ip_ihl_list)) + s_ip_dscp = ConcatSignal(*reversed(s_ip_dscp_list)) + s_ip_ecn = ConcatSignal(*reversed(s_ip_ecn_list)) + s_ip_length = ConcatSignal(*reversed(s_ip_length_list)) + s_ip_identification = ConcatSignal(*reversed(s_ip_identification_list)) + s_ip_flags = ConcatSignal(*reversed(s_ip_flags_list)) + s_ip_fragment_offset = ConcatSignal(*reversed(s_ip_fragment_offset_list)) + s_ip_ttl = ConcatSignal(*reversed(s_ip_ttl_list)) + s_ip_protocol = ConcatSignal(*reversed(s_ip_protocol_list)) + s_ip_header_checksum = ConcatSignal(*reversed(s_ip_header_checksum_list)) + s_ip_source_ip = ConcatSignal(*reversed(s_ip_source_ip_list)) + s_ip_dest_ip = ConcatSignal(*reversed(s_ip_dest_ip_list)) + s_ip_payload_axis_tdata = ConcatSignal(*reversed(s_ip_payload_axis_tdata_list)) + s_ip_payload_axis_tkeep = ConcatSignal(*reversed(s_ip_payload_axis_tkeep_list)) + s_ip_payload_axis_tvalid = ConcatSignal(*reversed(s_ip_payload_axis_tvalid_list)) + s_ip_payload_axis_tlast = ConcatSignal(*reversed(s_ip_payload_axis_tlast_list)) + s_ip_payload_axis_tid = ConcatSignal(*reversed(s_ip_payload_axis_tid_list)) + s_ip_payload_axis_tdest = ConcatSignal(*reversed(s_ip_payload_axis_tdest_list)) + s_ip_payload_axis_tuser = ConcatSignal(*reversed(s_ip_payload_axis_tuser_list)) + + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) # Outputs - input_0_ip_hdr_ready = Signal(bool(0)) - input_0_ip_payload_tready = Signal(bool(0)) - input_1_ip_hdr_ready = Signal(bool(0)) - input_1_ip_payload_tready = Signal(bool(0)) - input_2_ip_hdr_ready = Signal(bool(0)) - input_2_ip_payload_tready = Signal(bool(0)) - input_3_ip_hdr_ready = Signal(bool(0)) - input_3_ip_payload_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_ip_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_ip_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[64:]) - output_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + s_ip_hdr_ready_list = [s_ip_hdr_ready(i) for i in range(S_COUNT)] + s_ip_payload_axis_tready_list = [s_ip_payload_axis_tready(i) for i in range(S_COUNT)] + + m_ip_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_ip_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_ip_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_ip_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = ip_ep.IPFrameSource() + for k in range(S_COUNT): + s = ip_ep.IPFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - ip_hdr_ready=input_0_ip_hdr_ready, - ip_hdr_valid=input_0_ip_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - eth_type=input_0_eth_type, - ip_version=input_0_ip_version, - ip_ihl=input_0_ip_ihl, - ip_dscp=input_0_ip_dscp, - ip_ecn=input_0_ip_ecn, - ip_length=input_0_ip_length, - ip_identification=input_0_ip_identification, - ip_flags=input_0_ip_flags, - ip_fragment_offset=input_0_ip_fragment_offset, - ip_ttl=input_0_ip_ttl, - ip_protocol=input_0_ip_protocol, - ip_header_checksum=input_0_ip_header_checksum, - ip_source_ip=input_0_ip_source_ip, - ip_dest_ip=input_0_ip_dest_ip, - ip_payload_tdata=input_0_ip_payload_tdata, - ip_payload_tkeep=input_0_ip_payload_tkeep, - ip_payload_tvalid=input_0_ip_payload_tvalid, - ip_payload_tready=input_0_ip_payload_tready, - ip_payload_tlast=input_0_ip_payload_tlast, - ip_payload_tuser=input_0_ip_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = ip_ep.IPFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - ip_hdr_ready=input_1_ip_hdr_ready, - ip_hdr_valid=input_1_ip_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - eth_type=input_1_eth_type, - ip_version=input_1_ip_version, - ip_ihl=input_1_ip_ihl, - ip_dscp=input_1_ip_dscp, - ip_ecn=input_1_ip_ecn, - ip_length=input_1_ip_length, - ip_identification=input_1_ip_identification, - ip_flags=input_1_ip_flags, - ip_fragment_offset=input_1_ip_fragment_offset, - ip_ttl=input_1_ip_ttl, - ip_protocol=input_1_ip_protocol, - ip_header_checksum=input_1_ip_header_checksum, - ip_source_ip=input_1_ip_source_ip, - ip_dest_ip=input_1_ip_dest_ip, - ip_payload_tdata=input_1_ip_payload_tdata, - ip_payload_tkeep=input_1_ip_payload_tkeep, - ip_payload_tvalid=input_1_ip_payload_tvalid, - ip_payload_tready=input_1_ip_payload_tready, - ip_payload_tlast=input_1_ip_payload_tlast, - ip_payload_tuser=input_1_ip_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = ip_ep.IPFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - ip_hdr_ready=input_2_ip_hdr_ready, - ip_hdr_valid=input_2_ip_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - ip_version=input_2_ip_version, - ip_ihl=input_2_ip_ihl, - ip_dscp=input_2_ip_dscp, - ip_ecn=input_2_ip_ecn, - ip_length=input_2_ip_length, - ip_identification=input_2_ip_identification, - ip_flags=input_2_ip_flags, - ip_fragment_offset=input_2_ip_fragment_offset, - ip_ttl=input_2_ip_ttl, - ip_protocol=input_2_ip_protocol, - ip_header_checksum=input_2_ip_header_checksum, - ip_source_ip=input_2_ip_source_ip, - ip_dest_ip=input_2_ip_dest_ip, - ip_payload_tdata=input_2_ip_payload_tdata, - ip_payload_tkeep=input_2_ip_payload_tkeep, - ip_payload_tvalid=input_2_ip_payload_tvalid, - ip_payload_tready=input_2_ip_payload_tready, - ip_payload_tlast=input_2_ip_payload_tlast, - ip_payload_tuser=input_2_ip_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = ip_ep.IPFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - ip_hdr_ready=input_3_ip_hdr_ready, - ip_hdr_valid=input_3_ip_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - ip_version=input_3_ip_version, - ip_ihl=input_3_ip_ihl, - ip_dscp=input_3_ip_dscp, - ip_ecn=input_3_ip_ecn, - ip_length=input_3_ip_length, - ip_identification=input_3_ip_identification, - ip_flags=input_3_ip_flags, - ip_fragment_offset=input_3_ip_fragment_offset, - ip_ttl=input_3_ip_ttl, - ip_protocol=input_3_ip_protocol, - ip_header_checksum=input_3_ip_header_checksum, - ip_source_ip=input_3_ip_source_ip, - ip_dest_ip=input_3_ip_dest_ip, - ip_payload_tdata=input_3_ip_payload_tdata, - ip_payload_tkeep=input_3_ip_payload_tkeep, - ip_payload_tvalid=input_3_ip_payload_tvalid, - ip_payload_tready=input_3_ip_payload_tready, - ip_payload_tlast=input_3_ip_payload_tlast, - ip_payload_tuser=input_3_ip_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + ip_hdr_ready=s_ip_hdr_ready_list[k], + ip_hdr_valid=s_ip_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + ip_version=s_ip_version_list[k], + ip_ihl=s_ip_ihl_list[k], + ip_dscp=s_ip_dscp_list[k], + ip_ecn=s_ip_ecn_list[k], + ip_length=s_ip_length_list[k], + ip_identification=s_ip_identification_list[k], + ip_flags=s_ip_flags_list[k], + ip_fragment_offset=s_ip_fragment_offset_list[k], + ip_ttl=s_ip_ttl_list[k], + ip_protocol=s_ip_protocol_list[k], + ip_header_checksum=s_ip_header_checksum_list[k], + ip_source_ip=s_ip_source_ip_list[k], + ip_dest_ip=s_ip_dest_ip_list[k], + ip_payload_tdata=s_ip_payload_axis_tdata_list[k], + ip_payload_tkeep=s_ip_payload_axis_tkeep_list[k], + ip_payload_tvalid=s_ip_payload_axis_tvalid_list[k], + ip_payload_tready=s_ip_payload_axis_tready_list[k], + ip_payload_tlast=s_ip_payload_axis_tlast_list[k], + ip_payload_tuser=s_ip_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = ip_ep.IPFrameSink() sink_logic = sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tkeep=output_ip_payload_tkeep, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tkeep=m_ip_payload_axis_tkeep, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -357,127 +235,59 @@ def bench(): rst=rst, current_test=current_test, - input_0_ip_hdr_valid=input_0_ip_hdr_valid, - input_0_ip_hdr_ready=input_0_ip_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_ip_version=input_0_ip_version, - input_0_ip_ihl=input_0_ip_ihl, - input_0_ip_dscp=input_0_ip_dscp, - input_0_ip_ecn=input_0_ip_ecn, - input_0_ip_length=input_0_ip_length, - input_0_ip_identification=input_0_ip_identification, - input_0_ip_flags=input_0_ip_flags, - input_0_ip_fragment_offset=input_0_ip_fragment_offset, - input_0_ip_ttl=input_0_ip_ttl, - input_0_ip_protocol=input_0_ip_protocol, - input_0_ip_header_checksum=input_0_ip_header_checksum, - input_0_ip_source_ip=input_0_ip_source_ip, - input_0_ip_dest_ip=input_0_ip_dest_ip, - input_0_ip_payload_tdata=input_0_ip_payload_tdata, - input_0_ip_payload_tkeep=input_0_ip_payload_tkeep, - input_0_ip_payload_tvalid=input_0_ip_payload_tvalid, - input_0_ip_payload_tready=input_0_ip_payload_tready, - input_0_ip_payload_tlast=input_0_ip_payload_tlast, - input_0_ip_payload_tuser=input_0_ip_payload_tuser, - input_1_ip_hdr_valid=input_1_ip_hdr_valid, - input_1_ip_hdr_ready=input_1_ip_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_ip_version=input_1_ip_version, - input_1_ip_ihl=input_1_ip_ihl, - input_1_ip_dscp=input_1_ip_dscp, - input_1_ip_ecn=input_1_ip_ecn, - input_1_ip_length=input_1_ip_length, - input_1_ip_identification=input_1_ip_identification, - input_1_ip_flags=input_1_ip_flags, - input_1_ip_fragment_offset=input_1_ip_fragment_offset, - input_1_ip_ttl=input_1_ip_ttl, - input_1_ip_protocol=input_1_ip_protocol, - input_1_ip_header_checksum=input_1_ip_header_checksum, - input_1_ip_source_ip=input_1_ip_source_ip, - input_1_ip_dest_ip=input_1_ip_dest_ip, - input_1_ip_payload_tdata=input_1_ip_payload_tdata, - input_1_ip_payload_tkeep=input_1_ip_payload_tkeep, - input_1_ip_payload_tvalid=input_1_ip_payload_tvalid, - input_1_ip_payload_tready=input_1_ip_payload_tready, - input_1_ip_payload_tlast=input_1_ip_payload_tlast, - input_1_ip_payload_tuser=input_1_ip_payload_tuser, - input_2_ip_hdr_valid=input_2_ip_hdr_valid, - input_2_ip_hdr_ready=input_2_ip_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_ip_version=input_2_ip_version, - input_2_ip_ihl=input_2_ip_ihl, - input_2_ip_dscp=input_2_ip_dscp, - input_2_ip_ecn=input_2_ip_ecn, - input_2_ip_length=input_2_ip_length, - input_2_ip_identification=input_2_ip_identification, - input_2_ip_flags=input_2_ip_flags, - input_2_ip_fragment_offset=input_2_ip_fragment_offset, - input_2_ip_ttl=input_2_ip_ttl, - input_2_ip_protocol=input_2_ip_protocol, - input_2_ip_header_checksum=input_2_ip_header_checksum, - input_2_ip_source_ip=input_2_ip_source_ip, - input_2_ip_dest_ip=input_2_ip_dest_ip, - input_2_ip_payload_tdata=input_2_ip_payload_tdata, - input_2_ip_payload_tkeep=input_2_ip_payload_tkeep, - input_2_ip_payload_tvalid=input_2_ip_payload_tvalid, - input_2_ip_payload_tready=input_2_ip_payload_tready, - input_2_ip_payload_tlast=input_2_ip_payload_tlast, - input_2_ip_payload_tuser=input_2_ip_payload_tuser, - input_3_ip_hdr_valid=input_3_ip_hdr_valid, - input_3_ip_hdr_ready=input_3_ip_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_ip_version=input_3_ip_version, - input_3_ip_ihl=input_3_ip_ihl, - input_3_ip_dscp=input_3_ip_dscp, - input_3_ip_ecn=input_3_ip_ecn, - input_3_ip_length=input_3_ip_length, - input_3_ip_identification=input_3_ip_identification, - input_3_ip_flags=input_3_ip_flags, - input_3_ip_fragment_offset=input_3_ip_fragment_offset, - input_3_ip_ttl=input_3_ip_ttl, - input_3_ip_protocol=input_3_ip_protocol, - input_3_ip_header_checksum=input_3_ip_header_checksum, - input_3_ip_source_ip=input_3_ip_source_ip, - input_3_ip_dest_ip=input_3_ip_dest_ip, - input_3_ip_payload_tdata=input_3_ip_payload_tdata, - input_3_ip_payload_tkeep=input_3_ip_payload_tkeep, - input_3_ip_payload_tvalid=input_3_ip_payload_tvalid, - input_3_ip_payload_tready=input_3_ip_payload_tready, - input_3_ip_payload_tlast=input_3_ip_payload_tlast, - input_3_ip_payload_tuser=input_3_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tid=s_ip_payload_axis_tid, + s_ip_payload_axis_tdest=s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tkeep=output_ip_payload_tkeep, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tid=m_ip_payload_axis_tid, + m_ip_payload_axis_tdest=m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser ) @always(delay(4)) @@ -521,7 +331,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -554,7 +364,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -606,8 +416,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -664,8 +474,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -722,23 +532,23 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_ip_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge yield sink.wait() @@ -796,12 +606,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_ip_payload_tvalid or input_1_ip_payload_tvalid or input_2_ip_payload_tvalid or input_3_ip_payload_tvalid: + while s_ip_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -864,17 +674,17 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) yield clk.posedge - yield delay(150) + yield delay(120) yield clk.posedge - source_1.send(test_frame1) + source_list[1].send(test_frame1) yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_ip_arb_mux_64_4.v b/tb/test_ip_arb_mux_64_4.v index a8ef17a9c..5559ebb12 100644 --- a/tb/test_ip_arb_mux_64_4.v +++ b/tb/test_ip_arb_mux_64_4.v @@ -27,139 +27,85 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for ip_arb_mux_64_4 + * Testbench for ip_arb_mux */ module test_ip_arb_mux_64_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter ARB_TYPE = "PRIORITY"; +parameter LSB_PRIORITY = "HIGH"; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_ip_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [3:0] input_0_ip_version = 0; -reg [3:0] input_0_ip_ihl = 0; -reg [5:0] input_0_ip_dscp = 0; -reg [1:0] input_0_ip_ecn = 0; -reg [15:0] input_0_ip_length = 0; -reg [15:0] input_0_ip_identification = 0; -reg [2:0] input_0_ip_flags = 0; -reg [12:0] input_0_ip_fragment_offset = 0; -reg [7:0] input_0_ip_ttl = 0; -reg [7:0] input_0_ip_protocol = 0; -reg [15:0] input_0_ip_header_checksum = 0; -reg [31:0] input_0_ip_source_ip = 0; -reg [31:0] input_0_ip_dest_ip = 0; -reg [63:0] input_0_ip_payload_tdata = 0; -reg [7:0] input_0_ip_payload_tkeep = 0; -reg input_0_ip_payload_tvalid = 0; -reg input_0_ip_payload_tlast = 0; -reg input_0_ip_payload_tuser = 0; -reg input_1_ip_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [3:0] input_1_ip_version = 0; -reg [3:0] input_1_ip_ihl = 0; -reg [5:0] input_1_ip_dscp = 0; -reg [1:0] input_1_ip_ecn = 0; -reg [15:0] input_1_ip_length = 0; -reg [15:0] input_1_ip_identification = 0; -reg [2:0] input_1_ip_flags = 0; -reg [12:0] input_1_ip_fragment_offset = 0; -reg [7:0] input_1_ip_ttl = 0; -reg [7:0] input_1_ip_protocol = 0; -reg [15:0] input_1_ip_header_checksum = 0; -reg [31:0] input_1_ip_source_ip = 0; -reg [31:0] input_1_ip_dest_ip = 0; -reg [63:0] input_1_ip_payload_tdata = 0; -reg [7:0] input_1_ip_payload_tkeep = 0; -reg input_1_ip_payload_tvalid = 0; -reg input_1_ip_payload_tlast = 0; -reg input_1_ip_payload_tuser = 0; -reg input_2_ip_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [3:0] input_2_ip_version = 0; -reg [3:0] input_2_ip_ihl = 0; -reg [5:0] input_2_ip_dscp = 0; -reg [1:0] input_2_ip_ecn = 0; -reg [15:0] input_2_ip_length = 0; -reg [15:0] input_2_ip_identification = 0; -reg [2:0] input_2_ip_flags = 0; -reg [12:0] input_2_ip_fragment_offset = 0; -reg [7:0] input_2_ip_ttl = 0; -reg [7:0] input_2_ip_protocol = 0; -reg [15:0] input_2_ip_header_checksum = 0; -reg [31:0] input_2_ip_source_ip = 0; -reg [31:0] input_2_ip_dest_ip = 0; -reg [63:0] input_2_ip_payload_tdata = 0; -reg [7:0] input_2_ip_payload_tkeep = 0; -reg input_2_ip_payload_tvalid = 0; -reg input_2_ip_payload_tlast = 0; -reg input_2_ip_payload_tuser = 0; -reg input_3_ip_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [3:0] input_3_ip_version = 0; -reg [3:0] input_3_ip_ihl = 0; -reg [5:0] input_3_ip_dscp = 0; -reg [1:0] input_3_ip_ecn = 0; -reg [15:0] input_3_ip_length = 0; -reg [15:0] input_3_ip_identification = 0; -reg [2:0] input_3_ip_flags = 0; -reg [12:0] input_3_ip_fragment_offset = 0; -reg [7:0] input_3_ip_ttl = 0; -reg [7:0] input_3_ip_protocol = 0; -reg [15:0] input_3_ip_header_checksum = 0; -reg [31:0] input_3_ip_source_ip = 0; -reg [31:0] input_3_ip_dest_ip = 0; -reg [63:0] input_3_ip_payload_tdata = 0; -reg [7:0] input_3_ip_payload_tkeep = 0; -reg input_3_ip_payload_tvalid = 0; -reg input_3_ip_payload_tlast = 0; -reg input_3_ip_payload_tuser = 0; +reg [S_COUNT-1:0] s_ip_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*4-1:0] s_ip_version = 0; +reg [S_COUNT*4-1:0] s_ip_ihl = 0; +reg [S_COUNT*6-1:0] s_ip_dscp = 0; +reg [S_COUNT*2-1:0] s_ip_ecn = 0; +reg [S_COUNT*16-1:0] s_ip_length = 0; +reg [S_COUNT*16-1:0] s_ip_identification = 0; +reg [S_COUNT*3-1:0] s_ip_flags = 0; +reg [S_COUNT*13-1:0] s_ip_fragment_offset = 0; +reg [S_COUNT*8-1:0] s_ip_ttl = 0; +reg [S_COUNT*8-1:0] s_ip_protocol = 0; +reg [S_COUNT*16-1:0] s_ip_header_checksum = 0; +reg [S_COUNT*32-1:0] s_ip_source_ip = 0; +reg [S_COUNT*32-1:0] s_ip_dest_ip = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_ip_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_ip_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_ip_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_ip_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_ip_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_ip_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_ip_payload_axis_tuser = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; // Outputs -wire input_0_ip_payload_tready; -wire input_0_ip_hdr_ready; -wire input_1_ip_payload_tready; -wire input_1_ip_hdr_ready; -wire input_2_ip_payload_tready; -wire input_2_ip_hdr_ready; -wire input_3_ip_payload_tready; -wire input_3_ip_hdr_ready; +wire [S_COUNT-1:0] s_ip_hdr_ready; +wire [S_COUNT-1:0] s_ip_payload_axis_tready; -wire output_ip_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [63:0] output_ip_payload_tdata; -wire [7:0] output_ip_payload_tkeep; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire m_ip_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [DATA_WIDTH-1:0] m_ip_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_ip_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_ip_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_ip_payload_axis_tuser; initial begin // myhdl integration @@ -167,128 +113,60 @@ initial begin clk, rst, current_test, - input_0_ip_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_ip_version, - input_0_ip_ihl, - input_0_ip_dscp, - input_0_ip_ecn, - input_0_ip_length, - input_0_ip_identification, - input_0_ip_flags, - input_0_ip_fragment_offset, - input_0_ip_ttl, - input_0_ip_protocol, - input_0_ip_header_checksum, - input_0_ip_source_ip, - input_0_ip_dest_ip, - input_0_ip_payload_tdata, - input_0_ip_payload_tkeep, - input_0_ip_payload_tvalid, - input_0_ip_payload_tlast, - input_0_ip_payload_tuser, - input_1_ip_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_ip_version, - input_1_ip_ihl, - input_1_ip_dscp, - input_1_ip_ecn, - input_1_ip_length, - input_1_ip_identification, - input_1_ip_flags, - input_1_ip_fragment_offset, - input_1_ip_ttl, - input_1_ip_protocol, - input_1_ip_header_checksum, - input_1_ip_source_ip, - input_1_ip_dest_ip, - input_1_ip_payload_tdata, - input_1_ip_payload_tkeep, - input_1_ip_payload_tvalid, - input_1_ip_payload_tlast, - input_1_ip_payload_tuser, - input_2_ip_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_ip_version, - input_2_ip_ihl, - input_2_ip_dscp, - input_2_ip_ecn, - input_2_ip_length, - input_2_ip_identification, - input_2_ip_flags, - input_2_ip_fragment_offset, - input_2_ip_ttl, - input_2_ip_protocol, - input_2_ip_header_checksum, - input_2_ip_source_ip, - input_2_ip_dest_ip, - input_2_ip_payload_tdata, - input_2_ip_payload_tkeep, - input_2_ip_payload_tvalid, - input_2_ip_payload_tlast, - input_2_ip_payload_tuser, - input_3_ip_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_ip_version, - input_3_ip_ihl, - input_3_ip_dscp, - input_3_ip_ecn, - input_3_ip_length, - input_3_ip_identification, - input_3_ip_flags, - input_3_ip_fragment_offset, - input_3_ip_ttl, - input_3_ip_protocol, - input_3_ip_header_checksum, - input_3_ip_source_ip, - input_3_ip_dest_ip, - input_3_ip_payload_tdata, - input_3_ip_payload_tkeep, - input_3_ip_payload_tvalid, - input_3_ip_payload_tlast, - input_3_ip_payload_tuser, - output_ip_hdr_ready, - output_ip_payload_tready + s_ip_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tid, + s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready ); $to_myhdl( - input_0_ip_hdr_ready, - input_0_ip_payload_tready, - input_1_ip_hdr_ready, - input_1_ip_payload_tready, - input_2_ip_hdr_ready, - input_2_ip_payload_tready, - input_3_ip_hdr_ready, - input_3_ip_payload_tready, - output_ip_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tkeep, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_ip_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tid, + m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser ); // dump file @@ -296,132 +174,77 @@ initial begin $dumpvars(0, test_ip_arb_mux_64_4); end -ip_arb_mux_64_4 +ip_arb_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) +) UUT ( .clk(clk), .rst(rst), - // IP frame inputs - .input_0_ip_hdr_valid(input_0_ip_hdr_valid), - .input_0_ip_hdr_ready(input_0_ip_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_ip_payload_tdata(input_0_ip_payload_tdata), - .input_0_ip_payload_tkeep(input_0_ip_payload_tkeep), - .input_0_ip_payload_tvalid(input_0_ip_payload_tvalid), - .input_0_ip_payload_tready(input_0_ip_payload_tready), - .input_0_ip_payload_tlast(input_0_ip_payload_tlast), - .input_0_ip_payload_tuser(input_0_ip_payload_tuser), - .input_1_ip_hdr_valid(input_1_ip_hdr_valid), - .input_1_ip_hdr_ready(input_1_ip_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_ip_payload_tdata(input_1_ip_payload_tdata), - .input_1_ip_payload_tkeep(input_1_ip_payload_tkeep), - .input_1_ip_payload_tvalid(input_1_ip_payload_tvalid), - .input_1_ip_payload_tready(input_1_ip_payload_tready), - .input_1_ip_payload_tlast(input_1_ip_payload_tlast), - .input_1_ip_payload_tuser(input_1_ip_payload_tuser), - .input_2_ip_hdr_valid(input_2_ip_hdr_valid), - .input_2_ip_hdr_ready(input_2_ip_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_ip_payload_tdata(input_2_ip_payload_tdata), - .input_2_ip_payload_tkeep(input_2_ip_payload_tkeep), - .input_2_ip_payload_tvalid(input_2_ip_payload_tvalid), - .input_2_ip_payload_tready(input_2_ip_payload_tready), - .input_2_ip_payload_tlast(input_2_ip_payload_tlast), - .input_2_ip_payload_tuser(input_2_ip_payload_tuser), - .input_3_ip_hdr_valid(input_3_ip_hdr_valid), - .input_3_ip_hdr_ready(input_3_ip_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_ip_payload_tdata(input_3_ip_payload_tdata), - .input_3_ip_payload_tkeep(input_3_ip_payload_tkeep), - .input_3_ip_payload_tvalid(input_3_ip_payload_tvalid), - .input_3_ip_payload_tready(input_3_ip_payload_tready), - .input_3_ip_payload_tlast(input_3_ip_payload_tlast), - .input_3_ip_payload_tuser(input_3_ip_payload_tuser), - // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser) + // Ethernet frame inputs + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tid(s_ip_payload_axis_tid), + .s_ip_payload_axis_tdest(s_ip_payload_axis_tdest), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), + // Ethernet frame output + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tid(m_ip_payload_axis_tid), + .m_ip_payload_axis_tdest(m_ip_payload_axis_tdest), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser) ); endmodule From fea1186f5771d8abd8964bd1106a55a6d9eb8683 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 1 Nov 2018 00:48:26 -0700 Subject: [PATCH 462/617] Convert generated udp_arb_mux to verilog parametrized module --- rtl/udp_arb_mux.py | 254 ------------ rtl/udp_arb_mux.v | 435 +++++++++++++++++++++ rtl/udp_arb_mux_4.v | 366 ----------------- rtl/udp_arb_mux_64.py | 258 ------------ rtl/udp_arb_mux_64_4.v | 376 ------------------ tb/test_udp_arb_mux_4.py | 737 +++++++++++++---------------------- tb/test_udp_arb_mux_4.v | 620 ++++++++++------------------- tb/test_udp_arb_mux_64_4.py | 754 +++++++++++++----------------------- tb/test_udp_arb_mux_64_4.v | 635 ++++++++++-------------------- 9 files changed, 1388 insertions(+), 3047 deletions(-) delete mode 100755 rtl/udp_arb_mux.py create mode 100644 rtl/udp_arb_mux.v delete mode 100644 rtl/udp_arb_mux_4.v delete mode 100755 rtl/udp_arb_mux_64.py delete mode 100644 rtl/udp_arb_mux_64_4.v diff --git a/rtl/udp_arb_mux.py b/rtl/udp_arb_mux.py deleted file mode 100755 index 4024993fa..000000000 --- a/rtl/udp_arb_mux.py +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/env python -""" -Generates an arbitrated UDP mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "udp_arb_mux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port UDP arbitrated mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * UDP {{n}} port arbitrated multiplexer - */ -module {{name}} # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * UDP frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_udp_hdr_valid, - output wire input_{{p}}_udp_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [3:0] input_{{p}}_ip_version, - input wire [3:0] input_{{p}}_ip_ihl, - input wire [5:0] input_{{p}}_ip_dscp, - input wire [1:0] input_{{p}}_ip_ecn, - input wire [15:0] input_{{p}}_ip_length, - input wire [15:0] input_{{p}}_ip_identification, - input wire [2:0] input_{{p}}_ip_flags, - input wire [12:0] input_{{p}}_ip_fragment_offset, - input wire [7:0] input_{{p}}_ip_ttl, - input wire [7:0] input_{{p}}_ip_protocol, - input wire [15:0] input_{{p}}_ip_header_checksum, - input wire [31:0] input_{{p}}_ip_source_ip, - input wire [31:0] input_{{p}}_ip_dest_ip, - input wire [15:0] input_{{p}}_udp_source_port, - input wire [15:0] input_{{p}}_udp_dest_port, - input wire [15:0] input_{{p}}_udp_length, - input wire [15:0] input_{{p}}_udp_checksum, - input wire [7:0] input_{{p}}_udp_payload_tdata, - input wire input_{{p}}_udp_payload_tvalid, - output wire input_{{p}}_udp_payload_tready, - input wire input_{{p}}_udp_payload_tlast, - input wire input_{{p}}_udp_payload_tuser, -{% endfor %} - /* - * UDP frame output - */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [7:0] output_udp_payload_tdata, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser -); - -wire [{{n-1}}:0] request; -wire [{{n-1}}:0] acknowledge; -wire [{{n-1}}:0] grant; -wire grant_valid; -wire [{{w-1}}:0] grant_encoded; -{% for p in ports %} -assign acknowledge[{{p}}] = input_{{p}}_udp_payload_tvalid & input_{{p}}_udp_payload_tready & input_{{p}}_udp_payload_tlast; -assign request[{{p}}] = input_{{p}}_udp_hdr_valid; -{%- endfor %} - -// mux instance -udp_mux_{{n}} -mux_inst ( - .clk(clk), - .rst(rst), -{%- for p in ports %} - .input_{{p}}_udp_hdr_valid(input_{{p}}_udp_hdr_valid & grant[{{p}}]), - .input_{{p}}_udp_hdr_ready(input_{{p}}_udp_hdr_ready), - .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), - .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), - .input_{{p}}_eth_type(input_{{p}}_eth_type), - .input_{{p}}_ip_version(input_{{p}}_ip_version), - .input_{{p}}_ip_ihl(input_{{p}}_ip_ihl), - .input_{{p}}_ip_dscp(input_{{p}}_ip_dscp), - .input_{{p}}_ip_ecn(input_{{p}}_ip_ecn), - .input_{{p}}_ip_length(input_{{p}}_ip_length), - .input_{{p}}_ip_identification(input_{{p}}_ip_identification), - .input_{{p}}_ip_flags(input_{{p}}_ip_flags), - .input_{{p}}_ip_fragment_offset(input_{{p}}_ip_fragment_offset), - .input_{{p}}_ip_ttl(input_{{p}}_ip_ttl), - .input_{{p}}_ip_protocol(input_{{p}}_ip_protocol), - .input_{{p}}_ip_header_checksum(input_{{p}}_ip_header_checksum), - .input_{{p}}_ip_source_ip(input_{{p}}_ip_source_ip), - .input_{{p}}_ip_dest_ip(input_{{p}}_ip_dest_ip), - .input_{{p}}_udp_source_port(input_{{p}}_udp_source_port), - .input_{{p}}_udp_dest_port(input_{{p}}_udp_dest_port), - .input_{{p}}_udp_length(input_{{p}}_udp_length), - .input_{{p}}_udp_checksum(input_{{p}}_udp_checksum), - .input_{{p}}_udp_payload_tdata(input_{{p}}_udp_payload_tdata), - .input_{{p}}_udp_payload_tvalid(input_{{p}}_udp_payload_tvalid & grant[{{p}}]), - .input_{{p}}_udp_payload_tready(input_{{p}}_udp_payload_tready), - .input_{{p}}_udp_payload_tlast(input_{{p}}_udp_payload_tlast), - .input_{{p}}_udp_payload_tuser(input_{{p}}_udp_payload_tuser), -{%- endfor %} - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS({{n}}), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/udp_arb_mux.v b/rtl/udp_arb_mux.v new file mode 100644 index 000000000..abe2a1e10 --- /dev/null +++ b/rtl/udp_arb_mux.v @@ -0,0 +1,435 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * UDP arbitrated multiplexer + */ +module udp_arb_mux # +( + parameter S_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + // arbitration type: "PRIORITY" or "ROUND_ROBIN" + parameter ARB_TYPE = "PRIORITY", + // LSB priority: "LOW", "HIGH" + parameter LSB_PRIORITY = "HIGH" +) +( + input wire clk, + input wire rst, + + /* + * UDP frame inputs + */ + input wire [S_COUNT-1:0] s_udp_hdr_valid, + output wire [S_COUNT-1:0] s_udp_hdr_ready, + input wire [S_COUNT*48-1:0] s_eth_dest_mac, + input wire [S_COUNT*48-1:0] s_eth_src_mac, + input wire [S_COUNT*16-1:0] s_eth_type, + input wire [S_COUNT*4-1:0] s_ip_version, + input wire [S_COUNT*4-1:0] s_ip_ihl, + input wire [S_COUNT*6-1:0] s_ip_dscp, + input wire [S_COUNT*2-1:0] s_ip_ecn, + input wire [S_COUNT*16-1:0] s_ip_length, + input wire [S_COUNT*16-1:0] s_ip_identification, + input wire [S_COUNT*3-1:0] s_ip_flags, + input wire [S_COUNT*13-1:0] s_ip_fragment_offset, + input wire [S_COUNT*8-1:0] s_ip_ttl, + input wire [S_COUNT*8-1:0] s_ip_protocol, + input wire [S_COUNT*16-1:0] s_ip_header_checksum, + input wire [S_COUNT*32-1:0] s_ip_source_ip, + input wire [S_COUNT*32-1:0] s_ip_dest_ip, + input wire [S_COUNT*16-1:0] s_udp_source_port, + input wire [S_COUNT*16-1:0] s_udp_dest_port, + input wire [S_COUNT*16-1:0] s_udp_length, + input wire [S_COUNT*16-1:0] s_udp_checksum, + input wire [S_COUNT*DATA_WIDTH-1:0] s_udp_payload_axis_tdata, + input wire [S_COUNT*KEEP_WIDTH-1:0] s_udp_payload_axis_tkeep, + input wire [S_COUNT-1:0] s_udp_payload_axis_tvalid, + output wire [S_COUNT-1:0] s_udp_payload_axis_tready, + input wire [S_COUNT-1:0] s_udp_payload_axis_tlast, + input wire [S_COUNT*ID_WIDTH-1:0] s_udp_payload_axis_tid, + input wire [S_COUNT*DEST_WIDTH-1:0] s_udp_payload_axis_tdest, + input wire [S_COUNT*USER_WIDTH-1:0] s_udp_payload_axis_tuser, + + /* + * UDP frame output + */ + output wire m_udp_hdr_valid, + input wire m_udp_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [15:0] m_udp_source_port, + output wire [15:0] m_udp_dest_port, + output wire [15:0] m_udp_length, + output wire [15:0] m_udp_checksum, + output wire [DATA_WIDTH-1:0] m_udp_payload_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep, + output wire m_udp_payload_axis_tvalid, + input wire m_udp_payload_axis_tready, + output wire m_udp_payload_axis_tlast, + output wire [ID_WIDTH-1:0] m_udp_payload_axis_tid, + output wire [DEST_WIDTH-1:0] m_udp_payload_axis_tdest, + output wire [USER_WIDTH-1:0] m_udp_payload_axis_tuser +); + +parameter CL_S_COUNT = $clog2(S_COUNT); + +reg frame_reg = 1'b0, frame_next; + +reg s_udp_hdr_ready_mask_reg = 1'b0, s_udp_hdr_ready_mask_next; + +reg m_udp_hdr_valid_reg = 1'b0, m_udp_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0, m_eth_dest_mac_next; +reg [47:0] m_eth_src_mac_reg = 48'd0, m_eth_src_mac_next; +reg [15:0] m_eth_type_reg = 16'd0, m_eth_type_next; +reg [3:0] m_ip_version_reg = 4'd0, m_ip_version_next; +reg [3:0] m_ip_ihl_reg = 4'd0, m_ip_ihl_next; +reg [5:0] m_ip_dscp_reg = 6'd0, m_ip_dscp_next; +reg [1:0] m_ip_ecn_reg = 2'd0, m_ip_ecn_next; +reg [15:0] m_ip_length_reg = 16'd0, m_ip_length_next; +reg [15:0] m_ip_identification_reg = 16'd0, m_ip_identification_next; +reg [2:0] m_ip_flags_reg = 3'd0, m_ip_flags_next; +reg [12:0] m_ip_fragment_offset_reg = 13'd0, m_ip_fragment_offset_next; +reg [7:0] m_ip_ttl_reg = 8'd0, m_ip_ttl_next; +reg [7:0] m_ip_protocol_reg = 8'd0, m_ip_protocol_next; +reg [15:0] m_ip_header_checksum_reg = 16'd0, m_ip_header_checksum_next; +reg [31:0] m_ip_source_ip_reg = 32'd0, m_ip_source_ip_next; +reg [31:0] m_ip_dest_ip_reg = 32'd0, m_ip_dest_ip_next; +reg [15:0] m_udp_source_port_reg = 16'd0, m_udp_source_port_next; +reg [15:0] m_udp_dest_port_reg = 16'd0, m_udp_dest_port_next; +reg [15:0] m_udp_length_reg = 16'd0, m_udp_length_next; +reg [15:0] m_udp_checksum_reg = 16'd0, m_udp_checksum_next; + +wire [S_COUNT-1:0] request; +wire [S_COUNT-1:0] acknowledge; +wire [S_COUNT-1:0] grant; +wire grant_valid; +wire [CL_S_COUNT-1:0] grant_encoded; + +// internal datapath +reg [DATA_WIDTH-1:0] m_udp_payload_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep_int; +reg m_udp_payload_axis_tvalid_int; +reg m_udp_payload_axis_tready_int_reg = 1'b0; +reg m_udp_payload_axis_tlast_int; +reg [ID_WIDTH-1:0] m_udp_payload_axis_tid_int; +reg [DEST_WIDTH-1:0] m_udp_payload_axis_tdest_int; +reg [USER_WIDTH-1:0] m_udp_payload_axis_tuser_int; +wire m_udp_payload_axis_tready_int_early; + +assign s_udp_hdr_ready = (!s_udp_hdr_ready_mask_reg && grant_valid) << grant_encoded; + +assign s_udp_payload_axis_tready = (m_udp_payload_axis_tready_int_reg && grant_valid) << grant_encoded; + +assign m_udp_hdr_valid = m_udp_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_ip_length_reg; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = m_ip_protocol_reg; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; +assign m_udp_source_port = m_udp_source_port_reg; +assign m_udp_dest_port = m_udp_dest_port_reg; +assign m_udp_length = m_udp_length_reg; +assign m_udp_checksum = m_udp_checksum_reg; + +// mux for incoming packet +wire [DATA_WIDTH-1:0] current_s_tdata = s_udp_payload_axis_tdata[grant_encoded*DATA_WIDTH +: DATA_WIDTH]; +wire [KEEP_WIDTH-1:0] current_s_tkeep = s_udp_payload_axis_tkeep[grant_encoded*KEEP_WIDTH +: KEEP_WIDTH]; +wire current_s_tvalid = s_udp_payload_axis_tvalid[grant_encoded]; +wire current_s_tready = s_udp_payload_axis_tready[grant_encoded]; +wire current_s_tlast = s_udp_payload_axis_tlast[grant_encoded]; +wire [ID_WIDTH-1:0] current_s_tid = s_udp_payload_axis_tid[grant_encoded*ID_WIDTH +: ID_WIDTH]; +wire [DEST_WIDTH-1:0] current_s_tdest = s_udp_payload_axis_tdest[grant_encoded*DEST_WIDTH +: DEST_WIDTH]; +wire [USER_WIDTH-1:0] current_s_tuser = s_udp_payload_axis_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH]; + +// arbiter instance +arbiter #( + .PORTS(S_COUNT), + .TYPE(ARB_TYPE), + .BLOCK("ACKNOWLEDGE"), + .LSB_PRIORITY(LSB_PRIORITY) +) +arb_inst ( + .clk(clk), + .rst(rst), + .request(request), + .acknowledge(acknowledge), + .grant(grant), + .grant_valid(grant_valid), + .grant_encoded(grant_encoded) +); + +generate + genvar n; + + for (n = 0; n < S_COUNT; n = n + 1) begin + assign request[n] = s_udp_hdr_valid[n] && !grant[n]; + assign acknowledge[n] = grant[n] && s_udp_payload_axis_tvalid[n] && s_udp_payload_axis_tready[n] && s_udp_payload_axis_tlast[n]; + end +endgenerate + +always @* begin + frame_next = frame_reg; + + s_udp_hdr_ready_mask_next = s_udp_hdr_ready_mask_reg; + + m_udp_hdr_valid_next = m_udp_hdr_valid_reg && !m_udp_hdr_ready; + m_eth_dest_mac_next = m_eth_dest_mac_reg; + m_eth_src_mac_next = m_eth_src_mac_reg; + m_eth_type_next = m_eth_type_reg; + m_ip_version_next = m_ip_version_reg; + m_ip_ihl_next = m_ip_ihl_reg; + m_ip_dscp_next = m_ip_dscp_reg; + m_ip_ecn_next = m_ip_ecn_reg; + m_ip_length_next = m_ip_length_reg; + m_ip_identification_next = m_ip_identification_reg; + m_ip_flags_next = m_ip_flags_reg; + m_ip_fragment_offset_next = m_ip_fragment_offset_reg; + m_ip_ttl_next = m_ip_ttl_reg; + m_ip_protocol_next = m_ip_protocol_reg; + m_ip_header_checksum_next = m_ip_header_checksum_reg; + m_ip_source_ip_next = m_ip_source_ip_reg; + m_ip_dest_ip_next = m_ip_dest_ip_reg; + m_udp_source_port_next = m_udp_source_port_reg; + m_udp_dest_port_next = m_udp_dest_port_reg; + m_udp_length_next = m_udp_length_reg; + m_udp_checksum_next = m_udp_checksum_reg; + + if (s_udp_payload_axis_tvalid[grant_encoded] && s_udp_payload_axis_tready[grant_encoded]) begin + // end of frame detection + if (s_udp_payload_axis_tlast[grant_encoded]) begin + frame_next = 1'b0; + s_udp_hdr_ready_mask_next = 1'b0; + end + end + + if (!frame_reg && grant_valid) begin + // start of frame + frame_next = 1'b1; + + s_udp_hdr_ready_mask_next = 1'b1; + + m_udp_hdr_valid_next = 1'b1; + m_eth_dest_mac_next = s_eth_dest_mac[grant_encoded*48 +: 48]; + m_eth_src_mac_next = s_eth_src_mac[grant_encoded*48 +: 48]; + m_eth_type_next = s_eth_type[grant_encoded*16 +: 16]; + m_ip_version_next = s_ip_version[grant_encoded*4 +: 4]; + m_ip_ihl_next = s_ip_ihl[grant_encoded*4 +: 4]; + m_ip_dscp_next = s_ip_dscp[grant_encoded*6 +: 6]; + m_ip_ecn_next = s_ip_ecn[grant_encoded*2 +: 2]; + m_ip_length_next = s_ip_length[grant_encoded*16 +: 16]; + m_ip_identification_next = s_ip_identification[grant_encoded*16 +: 16]; + m_ip_flags_next = s_ip_flags[grant_encoded*3 +: 3]; + m_ip_fragment_offset_next = s_ip_fragment_offset[grant_encoded*13 +: 13]; + m_ip_ttl_next = s_ip_ttl[grant_encoded*8 +: 8]; + m_ip_protocol_next = s_ip_protocol[grant_encoded*8 +: 8]; + m_ip_header_checksum_next = s_ip_header_checksum[grant_encoded*16 +: 16]; + m_ip_source_ip_next = s_ip_source_ip[grant_encoded*32 +: 32]; + m_ip_dest_ip_next = s_ip_dest_ip[grant_encoded*32 +: 32]; + m_udp_source_port_next = s_udp_source_port[grant_encoded*16 +: 16]; + m_udp_dest_port_next = s_udp_dest_port[grant_encoded*16 +: 16]; + m_udp_length_next = s_udp_length[grant_encoded*16 +: 16]; + m_udp_checksum_next = s_udp_checksum[grant_encoded*16 +: 16]; + end + + // pass through selected packet data + m_udp_payload_axis_tdata_int = current_s_tdata; + m_udp_payload_axis_tkeep_int = current_s_tkeep; + m_udp_payload_axis_tvalid_int = current_s_tvalid && m_udp_payload_axis_tready_int_reg && grant_valid; + m_udp_payload_axis_tlast_int = current_s_tlast; + m_udp_payload_axis_tid_int = current_s_tid; + m_udp_payload_axis_tdest_int = current_s_tdest; + m_udp_payload_axis_tuser_int = current_s_tuser; +end + +always @(posedge clk) begin + if (rst) begin + frame_reg <= 1'b0; + s_udp_hdr_ready_mask_reg <= 1'b0; + m_udp_hdr_valid_reg <= 1'b0; + end else begin + frame_reg <= frame_next; + s_udp_hdr_ready_mask_reg <= s_udp_hdr_ready_mask_next; + m_udp_hdr_valid_reg <= m_udp_hdr_valid_next; + end + + m_eth_dest_mac_reg <= m_eth_dest_mac_next; + m_eth_src_mac_reg <= m_eth_src_mac_next; + m_eth_type_reg <= m_eth_type_next; + m_ip_version_reg <= m_ip_version_next; + m_ip_ihl_reg <= m_ip_ihl_next; + m_ip_dscp_reg <= m_ip_dscp_next; + m_ip_ecn_reg <= m_ip_ecn_next; + m_ip_length_reg <= m_ip_length_next; + m_ip_identification_reg <= m_ip_identification_next; + m_ip_flags_reg <= m_ip_flags_next; + m_ip_fragment_offset_reg <= m_ip_fragment_offset_next; + m_ip_ttl_reg <= m_ip_ttl_next; + m_ip_protocol_reg <= m_ip_protocol_next; + m_ip_header_checksum_reg <= m_ip_header_checksum_next; + m_ip_source_ip_reg <= m_ip_source_ip_next; + m_ip_dest_ip_reg <= m_ip_dest_ip_next; + m_udp_source_port_reg <= m_udp_source_port_next; + m_udp_dest_port_reg <= m_udp_dest_port_next; + m_udp_length_reg <= m_udp_length_next; + m_udp_checksum_reg <= m_udp_checksum_next; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_udp_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_udp_payload_axis_tvalid_reg = 1'b0, m_udp_payload_axis_tvalid_next; +reg m_udp_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_udp_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_udp_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_udp_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_udp_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_udp_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_udp_payload_axis_tvalid_reg = 1'b0, temp_m_udp_payload_axis_tvalid_next; +reg temp_m_udp_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_udp_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_udp_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_udp_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_udp_payload_axis_temp_to_output; + +assign m_udp_payload_axis_tdata = m_udp_payload_axis_tdata_reg; +assign m_udp_payload_axis_tkeep = KEEP_ENABLE ? m_udp_payload_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_udp_payload_axis_tvalid = m_udp_payload_axis_tvalid_reg; +assign m_udp_payload_axis_tlast = m_udp_payload_axis_tlast_reg; +assign m_udp_payload_axis_tid = ID_ENABLE ? m_udp_payload_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_udp_payload_axis_tdest = DEST_ENABLE ? m_udp_payload_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_udp_payload_axis_tuser = USER_ENABLE ? m_udp_payload_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_udp_payload_axis_tready_int_early = m_udp_payload_axis_tready || (!temp_m_udp_payload_axis_tvalid_reg && (!m_udp_payload_axis_tvalid_reg || !m_udp_payload_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_reg; + temp_m_udp_payload_axis_tvalid_next = temp_m_udp_payload_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_udp_payload_axis_temp_to_output = 1'b0; + + if (m_udp_payload_axis_tready_int_reg) begin + // input is ready + if (m_udp_payload_axis_tready || !m_udp_payload_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_udp_payload_axis_tready) begin + // input is not ready, but output is ready + m_udp_payload_axis_tvalid_next = temp_m_udp_payload_axis_tvalid_reg; + temp_m_udp_payload_axis_tvalid_next = 1'b0; + store_udp_payload_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_udp_payload_axis_tvalid_reg <= 1'b0; + m_udp_payload_axis_tready_int_reg <= 1'b0; + temp_m_udp_payload_axis_tvalid_reg <= 1'b0; + end else begin + m_udp_payload_axis_tvalid_reg <= m_udp_payload_axis_tvalid_next; + m_udp_payload_axis_tready_int_reg <= m_udp_payload_axis_tready_int_early; + temp_m_udp_payload_axis_tvalid_reg <= temp_m_udp_payload_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_udp_payload_axis_tdata_reg <= m_udp_payload_axis_tdata_int; + m_udp_payload_axis_tkeep_reg <= m_udp_payload_axis_tkeep_int; + m_udp_payload_axis_tlast_reg <= m_udp_payload_axis_tlast_int; + m_udp_payload_axis_tid_reg <= m_udp_payload_axis_tid_int; + m_udp_payload_axis_tdest_reg <= m_udp_payload_axis_tdest_int; + m_udp_payload_axis_tuser_reg <= m_udp_payload_axis_tuser_int; + end else if (store_udp_payload_axis_temp_to_output) begin + m_udp_payload_axis_tdata_reg <= temp_m_udp_payload_axis_tdata_reg; + m_udp_payload_axis_tkeep_reg <= temp_m_udp_payload_axis_tkeep_reg; + m_udp_payload_axis_tlast_reg <= temp_m_udp_payload_axis_tlast_reg; + m_udp_payload_axis_tid_reg <= temp_m_udp_payload_axis_tid_reg; + m_udp_payload_axis_tdest_reg <= temp_m_udp_payload_axis_tdest_reg; + m_udp_payload_axis_tuser_reg <= temp_m_udp_payload_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_udp_payload_axis_tdata_reg <= m_udp_payload_axis_tdata_int; + temp_m_udp_payload_axis_tkeep_reg <= m_udp_payload_axis_tkeep_int; + temp_m_udp_payload_axis_tlast_reg <= m_udp_payload_axis_tlast_int; + temp_m_udp_payload_axis_tid_reg <= m_udp_payload_axis_tid_int; + temp_m_udp_payload_axis_tdest_reg <= m_udp_payload_axis_tdest_int; + temp_m_udp_payload_axis_tuser_reg <= m_udp_payload_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/udp_arb_mux_4.v b/rtl/udp_arb_mux_4.v deleted file mode 100644 index 3c2a1b292..000000000 --- a/rtl/udp_arb_mux_4.v +++ /dev/null @@ -1,366 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * UDP 4 port arbitrated multiplexer - */ -module udp_arb_mux_4 # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * UDP frame inputs - */ - input wire input_0_udp_hdr_valid, - output wire input_0_udp_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [15:0] input_0_udp_source_port, - input wire [15:0] input_0_udp_dest_port, - input wire [15:0] input_0_udp_length, - input wire [15:0] input_0_udp_checksum, - input wire [7:0] input_0_udp_payload_tdata, - input wire input_0_udp_payload_tvalid, - output wire input_0_udp_payload_tready, - input wire input_0_udp_payload_tlast, - input wire input_0_udp_payload_tuser, - - input wire input_1_udp_hdr_valid, - output wire input_1_udp_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [15:0] input_1_udp_source_port, - input wire [15:0] input_1_udp_dest_port, - input wire [15:0] input_1_udp_length, - input wire [15:0] input_1_udp_checksum, - input wire [7:0] input_1_udp_payload_tdata, - input wire input_1_udp_payload_tvalid, - output wire input_1_udp_payload_tready, - input wire input_1_udp_payload_tlast, - input wire input_1_udp_payload_tuser, - - input wire input_2_udp_hdr_valid, - output wire input_2_udp_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [3:0] input_2_ip_version, - input wire [3:0] input_2_ip_ihl, - input wire [5:0] input_2_ip_dscp, - input wire [1:0] input_2_ip_ecn, - input wire [15:0] input_2_ip_length, - input wire [15:0] input_2_ip_identification, - input wire [2:0] input_2_ip_flags, - input wire [12:0] input_2_ip_fragment_offset, - input wire [7:0] input_2_ip_ttl, - input wire [7:0] input_2_ip_protocol, - input wire [15:0] input_2_ip_header_checksum, - input wire [31:0] input_2_ip_source_ip, - input wire [31:0] input_2_ip_dest_ip, - input wire [15:0] input_2_udp_source_port, - input wire [15:0] input_2_udp_dest_port, - input wire [15:0] input_2_udp_length, - input wire [15:0] input_2_udp_checksum, - input wire [7:0] input_2_udp_payload_tdata, - input wire input_2_udp_payload_tvalid, - output wire input_2_udp_payload_tready, - input wire input_2_udp_payload_tlast, - input wire input_2_udp_payload_tuser, - - input wire input_3_udp_hdr_valid, - output wire input_3_udp_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [3:0] input_3_ip_version, - input wire [3:0] input_3_ip_ihl, - input wire [5:0] input_3_ip_dscp, - input wire [1:0] input_3_ip_ecn, - input wire [15:0] input_3_ip_length, - input wire [15:0] input_3_ip_identification, - input wire [2:0] input_3_ip_flags, - input wire [12:0] input_3_ip_fragment_offset, - input wire [7:0] input_3_ip_ttl, - input wire [7:0] input_3_ip_protocol, - input wire [15:0] input_3_ip_header_checksum, - input wire [31:0] input_3_ip_source_ip, - input wire [31:0] input_3_ip_dest_ip, - input wire [15:0] input_3_udp_source_port, - input wire [15:0] input_3_udp_dest_port, - input wire [15:0] input_3_udp_length, - input wire [15:0] input_3_udp_checksum, - input wire [7:0] input_3_udp_payload_tdata, - input wire input_3_udp_payload_tvalid, - output wire input_3_udp_payload_tready, - input wire input_3_udp_payload_tlast, - input wire input_3_udp_payload_tuser, - - /* - * UDP frame output - */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [7:0] output_udp_payload_tdata, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser -); - -wire [3:0] request; -wire [3:0] acknowledge; -wire [3:0] grant; -wire grant_valid; -wire [1:0] grant_encoded; - -assign acknowledge[0] = input_0_udp_payload_tvalid & input_0_udp_payload_tready & input_0_udp_payload_tlast; -assign request[0] = input_0_udp_hdr_valid; -assign acknowledge[1] = input_1_udp_payload_tvalid & input_1_udp_payload_tready & input_1_udp_payload_tlast; -assign request[1] = input_1_udp_hdr_valid; -assign acknowledge[2] = input_2_udp_payload_tvalid & input_2_udp_payload_tready & input_2_udp_payload_tlast; -assign request[2] = input_2_udp_hdr_valid; -assign acknowledge[3] = input_3_udp_payload_tvalid & input_3_udp_payload_tready & input_3_udp_payload_tlast; -assign request[3] = input_3_udp_hdr_valid; - -// mux instance -udp_mux_4 -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_udp_hdr_valid(input_0_udp_hdr_valid & grant[0]), - .input_0_udp_hdr_ready(input_0_udp_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_udp_source_port(input_0_udp_source_port), - .input_0_udp_dest_port(input_0_udp_dest_port), - .input_0_udp_length(input_0_udp_length), - .input_0_udp_checksum(input_0_udp_checksum), - .input_0_udp_payload_tdata(input_0_udp_payload_tdata), - .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid & grant[0]), - .input_0_udp_payload_tready(input_0_udp_payload_tready), - .input_0_udp_payload_tlast(input_0_udp_payload_tlast), - .input_0_udp_payload_tuser(input_0_udp_payload_tuser), - .input_1_udp_hdr_valid(input_1_udp_hdr_valid & grant[1]), - .input_1_udp_hdr_ready(input_1_udp_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_udp_source_port(input_1_udp_source_port), - .input_1_udp_dest_port(input_1_udp_dest_port), - .input_1_udp_length(input_1_udp_length), - .input_1_udp_checksum(input_1_udp_checksum), - .input_1_udp_payload_tdata(input_1_udp_payload_tdata), - .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid & grant[1]), - .input_1_udp_payload_tready(input_1_udp_payload_tready), - .input_1_udp_payload_tlast(input_1_udp_payload_tlast), - .input_1_udp_payload_tuser(input_1_udp_payload_tuser), - .input_2_udp_hdr_valid(input_2_udp_hdr_valid & grant[2]), - .input_2_udp_hdr_ready(input_2_udp_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_udp_source_port(input_2_udp_source_port), - .input_2_udp_dest_port(input_2_udp_dest_port), - .input_2_udp_length(input_2_udp_length), - .input_2_udp_checksum(input_2_udp_checksum), - .input_2_udp_payload_tdata(input_2_udp_payload_tdata), - .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid & grant[2]), - .input_2_udp_payload_tready(input_2_udp_payload_tready), - .input_2_udp_payload_tlast(input_2_udp_payload_tlast), - .input_2_udp_payload_tuser(input_2_udp_payload_tuser), - .input_3_udp_hdr_valid(input_3_udp_hdr_valid & grant[3]), - .input_3_udp_hdr_ready(input_3_udp_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_udp_source_port(input_3_udp_source_port), - .input_3_udp_dest_port(input_3_udp_dest_port), - .input_3_udp_length(input_3_udp_length), - .input_3_udp_checksum(input_3_udp_checksum), - .input_3_udp_payload_tdata(input_3_udp_payload_tdata), - .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid & grant[3]), - .input_3_udp_payload_tready(input_3_udp_payload_tready), - .input_3_udp_payload_tlast(input_3_udp_payload_tlast), - .input_3_udp_payload_tuser(input_3_udp_payload_tuser), - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/rtl/udp_arb_mux_64.py b/rtl/udp_arb_mux_64.py deleted file mode 100755 index b4094cde3..000000000 --- a/rtl/udp_arb_mux_64.py +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env python -""" -Generates an arbitrated UDP mux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "udp_arb_mux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port UDP arbitrated mux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * UDP {{n}} port arbitrated multiplexer (64 bit datapath) - */ -module {{name}} # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * UDP frame inputs - */ -{%- for p in ports %} - input wire input_{{p}}_udp_hdr_valid, - output wire input_{{p}}_udp_hdr_ready, - input wire [47:0] input_{{p}}_eth_dest_mac, - input wire [47:0] input_{{p}}_eth_src_mac, - input wire [15:0] input_{{p}}_eth_type, - input wire [3:0] input_{{p}}_ip_version, - input wire [3:0] input_{{p}}_ip_ihl, - input wire [5:0] input_{{p}}_ip_dscp, - input wire [1:0] input_{{p}}_ip_ecn, - input wire [15:0] input_{{p}}_ip_length, - input wire [15:0] input_{{p}}_ip_identification, - input wire [2:0] input_{{p}}_ip_flags, - input wire [12:0] input_{{p}}_ip_fragment_offset, - input wire [7:0] input_{{p}}_ip_ttl, - input wire [7:0] input_{{p}}_ip_protocol, - input wire [15:0] input_{{p}}_ip_header_checksum, - input wire [31:0] input_{{p}}_ip_source_ip, - input wire [31:0] input_{{p}}_ip_dest_ip, - input wire [15:0] input_{{p}}_udp_source_port, - input wire [15:0] input_{{p}}_udp_dest_port, - input wire [15:0] input_{{p}}_udp_length, - input wire [15:0] input_{{p}}_udp_checksum, - input wire [63:0] input_{{p}}_udp_payload_tdata, - input wire [7:0] input_{{p}}_udp_payload_tkeep, - input wire input_{{p}}_udp_payload_tvalid, - output wire input_{{p}}_udp_payload_tready, - input wire input_{{p}}_udp_payload_tlast, - input wire input_{{p}}_udp_payload_tuser, -{% endfor %} - /* - * UDP frame output - */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [63:0] output_udp_payload_tdata, - output wire [7:0] output_udp_payload_tkeep, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser -); - -wire [{{n-1}}:0] request; -wire [{{n-1}}:0] acknowledge; -wire [{{n-1}}:0] grant; -wire grant_valid; -wire [{{w-1}}:0] grant_encoded; -{% for p in ports %} -assign acknowledge[{{p}}] = input_{{p}}_udp_payload_tvalid & input_{{p}}_udp_payload_tready & input_{{p}}_udp_payload_tlast; -assign request[{{p}}] = input_{{p}}_udp_hdr_valid; -{%- endfor %} - -// mux instance -udp_mux_64_{{n}} -mux_inst ( - .clk(clk), - .rst(rst), -{%- for p in ports %} - .input_{{p}}_udp_hdr_valid(input_{{p}}_udp_hdr_valid & grant[{{p}}]), - .input_{{p}}_udp_hdr_ready(input_{{p}}_udp_hdr_ready), - .input_{{p}}_eth_dest_mac(input_{{p}}_eth_dest_mac), - .input_{{p}}_eth_src_mac(input_{{p}}_eth_src_mac), - .input_{{p}}_eth_type(input_{{p}}_eth_type), - .input_{{p}}_ip_version(input_{{p}}_ip_version), - .input_{{p}}_ip_ihl(input_{{p}}_ip_ihl), - .input_{{p}}_ip_dscp(input_{{p}}_ip_dscp), - .input_{{p}}_ip_ecn(input_{{p}}_ip_ecn), - .input_{{p}}_ip_length(input_{{p}}_ip_length), - .input_{{p}}_ip_identification(input_{{p}}_ip_identification), - .input_{{p}}_ip_flags(input_{{p}}_ip_flags), - .input_{{p}}_ip_fragment_offset(input_{{p}}_ip_fragment_offset), - .input_{{p}}_ip_ttl(input_{{p}}_ip_ttl), - .input_{{p}}_ip_protocol(input_{{p}}_ip_protocol), - .input_{{p}}_ip_header_checksum(input_{{p}}_ip_header_checksum), - .input_{{p}}_ip_source_ip(input_{{p}}_ip_source_ip), - .input_{{p}}_ip_dest_ip(input_{{p}}_ip_dest_ip), - .input_{{p}}_udp_source_port(input_{{p}}_udp_source_port), - .input_{{p}}_udp_dest_port(input_{{p}}_udp_dest_port), - .input_{{p}}_udp_length(input_{{p}}_udp_length), - .input_{{p}}_udp_checksum(input_{{p}}_udp_checksum), - .input_{{p}}_udp_payload_tdata(input_{{p}}_udp_payload_tdata), - .input_{{p}}_udp_payload_tkeep(input_{{p}}_udp_payload_tkeep), - .input_{{p}}_udp_payload_tvalid(input_{{p}}_udp_payload_tvalid & grant[{{p}}]), - .input_{{p}}_udp_payload_tready(input_{{p}}_udp_payload_tready), - .input_{{p}}_udp_payload_tlast(input_{{p}}_udp_payload_tlast), - .input_{{p}}_udp_payload_tuser(input_{{p}}_udp_payload_tuser), -{%- endfor %} - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tkeep(output_udp_payload_tkeep), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS({{n}}), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/udp_arb_mux_64_4.v b/rtl/udp_arb_mux_64_4.v deleted file mode 100644 index 93c6ae9a0..000000000 --- a/rtl/udp_arb_mux_64_4.v +++ /dev/null @@ -1,376 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * UDP 4 port arbitrated multiplexer (64 bit datapath) - */ -module udp_arb_mux_64_4 # -( - // arbitration type: "PRIORITY" or "ROUND_ROBIN" - parameter ARB_TYPE = "PRIORITY", - // LSB priority: "LOW", "HIGH" - parameter LSB_PRIORITY = "HIGH" -) -( - input wire clk, - input wire rst, - - /* - * UDP frame inputs - */ - input wire input_0_udp_hdr_valid, - output wire input_0_udp_hdr_ready, - input wire [47:0] input_0_eth_dest_mac, - input wire [47:0] input_0_eth_src_mac, - input wire [15:0] input_0_eth_type, - input wire [3:0] input_0_ip_version, - input wire [3:0] input_0_ip_ihl, - input wire [5:0] input_0_ip_dscp, - input wire [1:0] input_0_ip_ecn, - input wire [15:0] input_0_ip_length, - input wire [15:0] input_0_ip_identification, - input wire [2:0] input_0_ip_flags, - input wire [12:0] input_0_ip_fragment_offset, - input wire [7:0] input_0_ip_ttl, - input wire [7:0] input_0_ip_protocol, - input wire [15:0] input_0_ip_header_checksum, - input wire [31:0] input_0_ip_source_ip, - input wire [31:0] input_0_ip_dest_ip, - input wire [15:0] input_0_udp_source_port, - input wire [15:0] input_0_udp_dest_port, - input wire [15:0] input_0_udp_length, - input wire [15:0] input_0_udp_checksum, - input wire [63:0] input_0_udp_payload_tdata, - input wire [7:0] input_0_udp_payload_tkeep, - input wire input_0_udp_payload_tvalid, - output wire input_0_udp_payload_tready, - input wire input_0_udp_payload_tlast, - input wire input_0_udp_payload_tuser, - - input wire input_1_udp_hdr_valid, - output wire input_1_udp_hdr_ready, - input wire [47:0] input_1_eth_dest_mac, - input wire [47:0] input_1_eth_src_mac, - input wire [15:0] input_1_eth_type, - input wire [3:0] input_1_ip_version, - input wire [3:0] input_1_ip_ihl, - input wire [5:0] input_1_ip_dscp, - input wire [1:0] input_1_ip_ecn, - input wire [15:0] input_1_ip_length, - input wire [15:0] input_1_ip_identification, - input wire [2:0] input_1_ip_flags, - input wire [12:0] input_1_ip_fragment_offset, - input wire [7:0] input_1_ip_ttl, - input wire [7:0] input_1_ip_protocol, - input wire [15:0] input_1_ip_header_checksum, - input wire [31:0] input_1_ip_source_ip, - input wire [31:0] input_1_ip_dest_ip, - input wire [15:0] input_1_udp_source_port, - input wire [15:0] input_1_udp_dest_port, - input wire [15:0] input_1_udp_length, - input wire [15:0] input_1_udp_checksum, - input wire [63:0] input_1_udp_payload_tdata, - input wire [7:0] input_1_udp_payload_tkeep, - input wire input_1_udp_payload_tvalid, - output wire input_1_udp_payload_tready, - input wire input_1_udp_payload_tlast, - input wire input_1_udp_payload_tuser, - - input wire input_2_udp_hdr_valid, - output wire input_2_udp_hdr_ready, - input wire [47:0] input_2_eth_dest_mac, - input wire [47:0] input_2_eth_src_mac, - input wire [15:0] input_2_eth_type, - input wire [3:0] input_2_ip_version, - input wire [3:0] input_2_ip_ihl, - input wire [5:0] input_2_ip_dscp, - input wire [1:0] input_2_ip_ecn, - input wire [15:0] input_2_ip_length, - input wire [15:0] input_2_ip_identification, - input wire [2:0] input_2_ip_flags, - input wire [12:0] input_2_ip_fragment_offset, - input wire [7:0] input_2_ip_ttl, - input wire [7:0] input_2_ip_protocol, - input wire [15:0] input_2_ip_header_checksum, - input wire [31:0] input_2_ip_source_ip, - input wire [31:0] input_2_ip_dest_ip, - input wire [15:0] input_2_udp_source_port, - input wire [15:0] input_2_udp_dest_port, - input wire [15:0] input_2_udp_length, - input wire [15:0] input_2_udp_checksum, - input wire [63:0] input_2_udp_payload_tdata, - input wire [7:0] input_2_udp_payload_tkeep, - input wire input_2_udp_payload_tvalid, - output wire input_2_udp_payload_tready, - input wire input_2_udp_payload_tlast, - input wire input_2_udp_payload_tuser, - - input wire input_3_udp_hdr_valid, - output wire input_3_udp_hdr_ready, - input wire [47:0] input_3_eth_dest_mac, - input wire [47:0] input_3_eth_src_mac, - input wire [15:0] input_3_eth_type, - input wire [3:0] input_3_ip_version, - input wire [3:0] input_3_ip_ihl, - input wire [5:0] input_3_ip_dscp, - input wire [1:0] input_3_ip_ecn, - input wire [15:0] input_3_ip_length, - input wire [15:0] input_3_ip_identification, - input wire [2:0] input_3_ip_flags, - input wire [12:0] input_3_ip_fragment_offset, - input wire [7:0] input_3_ip_ttl, - input wire [7:0] input_3_ip_protocol, - input wire [15:0] input_3_ip_header_checksum, - input wire [31:0] input_3_ip_source_ip, - input wire [31:0] input_3_ip_dest_ip, - input wire [15:0] input_3_udp_source_port, - input wire [15:0] input_3_udp_dest_port, - input wire [15:0] input_3_udp_length, - input wire [15:0] input_3_udp_checksum, - input wire [63:0] input_3_udp_payload_tdata, - input wire [7:0] input_3_udp_payload_tkeep, - input wire input_3_udp_payload_tvalid, - output wire input_3_udp_payload_tready, - input wire input_3_udp_payload_tlast, - input wire input_3_udp_payload_tuser, - - /* - * UDP frame output - */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [63:0] output_udp_payload_tdata, - output wire [7:0] output_udp_payload_tkeep, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser -); - -wire [3:0] request; -wire [3:0] acknowledge; -wire [3:0] grant; -wire grant_valid; -wire [1:0] grant_encoded; - -assign acknowledge[0] = input_0_udp_payload_tvalid & input_0_udp_payload_tready & input_0_udp_payload_tlast; -assign request[0] = input_0_udp_hdr_valid; -assign acknowledge[1] = input_1_udp_payload_tvalid & input_1_udp_payload_tready & input_1_udp_payload_tlast; -assign request[1] = input_1_udp_hdr_valid; -assign acknowledge[2] = input_2_udp_payload_tvalid & input_2_udp_payload_tready & input_2_udp_payload_tlast; -assign request[2] = input_2_udp_hdr_valid; -assign acknowledge[3] = input_3_udp_payload_tvalid & input_3_udp_payload_tready & input_3_udp_payload_tlast; -assign request[3] = input_3_udp_hdr_valid; - -// mux instance -udp_mux_64_4 -mux_inst ( - .clk(clk), - .rst(rst), - .input_0_udp_hdr_valid(input_0_udp_hdr_valid & grant[0]), - .input_0_udp_hdr_ready(input_0_udp_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_udp_source_port(input_0_udp_source_port), - .input_0_udp_dest_port(input_0_udp_dest_port), - .input_0_udp_length(input_0_udp_length), - .input_0_udp_checksum(input_0_udp_checksum), - .input_0_udp_payload_tdata(input_0_udp_payload_tdata), - .input_0_udp_payload_tkeep(input_0_udp_payload_tkeep), - .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid & grant[0]), - .input_0_udp_payload_tready(input_0_udp_payload_tready), - .input_0_udp_payload_tlast(input_0_udp_payload_tlast), - .input_0_udp_payload_tuser(input_0_udp_payload_tuser), - .input_1_udp_hdr_valid(input_1_udp_hdr_valid & grant[1]), - .input_1_udp_hdr_ready(input_1_udp_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_udp_source_port(input_1_udp_source_port), - .input_1_udp_dest_port(input_1_udp_dest_port), - .input_1_udp_length(input_1_udp_length), - .input_1_udp_checksum(input_1_udp_checksum), - .input_1_udp_payload_tdata(input_1_udp_payload_tdata), - .input_1_udp_payload_tkeep(input_1_udp_payload_tkeep), - .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid & grant[1]), - .input_1_udp_payload_tready(input_1_udp_payload_tready), - .input_1_udp_payload_tlast(input_1_udp_payload_tlast), - .input_1_udp_payload_tuser(input_1_udp_payload_tuser), - .input_2_udp_hdr_valid(input_2_udp_hdr_valid & grant[2]), - .input_2_udp_hdr_ready(input_2_udp_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_udp_source_port(input_2_udp_source_port), - .input_2_udp_dest_port(input_2_udp_dest_port), - .input_2_udp_length(input_2_udp_length), - .input_2_udp_checksum(input_2_udp_checksum), - .input_2_udp_payload_tdata(input_2_udp_payload_tdata), - .input_2_udp_payload_tkeep(input_2_udp_payload_tkeep), - .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid & grant[2]), - .input_2_udp_payload_tready(input_2_udp_payload_tready), - .input_2_udp_payload_tlast(input_2_udp_payload_tlast), - .input_2_udp_payload_tuser(input_2_udp_payload_tuser), - .input_3_udp_hdr_valid(input_3_udp_hdr_valid & grant[3]), - .input_3_udp_hdr_ready(input_3_udp_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_udp_source_port(input_3_udp_source_port), - .input_3_udp_dest_port(input_3_udp_dest_port), - .input_3_udp_length(input_3_udp_length), - .input_3_udp_checksum(input_3_udp_checksum), - .input_3_udp_payload_tdata(input_3_udp_payload_tdata), - .input_3_udp_payload_tkeep(input_3_udp_payload_tkeep), - .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid & grant[3]), - .input_3_udp_payload_tready(input_3_udp_payload_tready), - .input_3_udp_payload_tlast(input_3_udp_payload_tlast), - .input_3_udp_payload_tuser(input_3_udp_payload_tuser), - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tkeep(output_udp_payload_tkeep), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), - .enable(grant_valid), - .select(grant_encoded) -); - -// arbiter instance -arbiter #( - .PORTS(4), - .TYPE(ARB_TYPE), - .BLOCK("ACKNOWLEDGE"), - .LSB_PRIORITY(LSB_PRIORITY) -) -arb_inst ( - .clk(clk), - .rst(rst), - .request(request), - .acknowledge(acknowledge), - .grant(grant), - .grant_valid(grant_valid), - .grant_encoded(grant_encoded) -); - -endmodule diff --git a/tb/test_udp_arb_mux_4.py b/tb/test_udp_arb_mux_4.py index 1c8f2bea9..6b98097e0 100755 --- a/tb/test_udp_arb_mux_4.py +++ b/tb/test_udp_arb_mux_4.py @@ -28,13 +28,12 @@ import os import udp_ep -module = 'udp_arb_mux_4' -testbench = 'test_%s' % module +module = 'udp_arb_mux' +testbench = 'test_%s_4' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/udp_mux_4.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -45,334 +44,203 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + ARB_TYPE = "PRIORITY" + LSB_PRIORITY = "HIGH" + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_udp_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_ip_version = Signal(intbv(0)[4:]) - input_0_ip_ihl = Signal(intbv(0)[4:]) - input_0_ip_dscp = Signal(intbv(0)[6:]) - input_0_ip_ecn = Signal(intbv(0)[2:]) - input_0_ip_length = Signal(intbv(0)[16:]) - input_0_ip_identification = Signal(intbv(0)[16:]) - input_0_ip_flags = Signal(intbv(0)[3:]) - input_0_ip_fragment_offset = Signal(intbv(0)[13:]) - input_0_ip_ttl = Signal(intbv(0)[8:]) - input_0_ip_protocol = Signal(intbv(0)[8:]) - input_0_ip_header_checksum = Signal(intbv(0)[16:]) - input_0_ip_source_ip = Signal(intbv(0)[32:]) - input_0_ip_dest_ip = Signal(intbv(0)[32:]) - input_0_udp_source_port = Signal(intbv(0)[16:]) - input_0_udp_dest_port = Signal(intbv(0)[16:]) - input_0_udp_length = Signal(intbv(0)[16:]) - input_0_udp_checksum = Signal(intbv(0)[16:]) - input_0_udp_payload_tdata = Signal(intbv(0)[8:]) - input_0_udp_payload_tvalid = Signal(bool(0)) - input_0_udp_payload_tlast = Signal(bool(0)) - input_0_udp_payload_tuser = Signal(bool(0)) - input_1_udp_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_ip_version = Signal(intbv(0)[4:]) - input_1_ip_ihl = Signal(intbv(0)[4:]) - input_1_ip_dscp = Signal(intbv(0)[6:]) - input_1_ip_ecn = Signal(intbv(0)[2:]) - input_1_ip_length = Signal(intbv(0)[16:]) - input_1_ip_identification = Signal(intbv(0)[16:]) - input_1_ip_flags = Signal(intbv(0)[3:]) - input_1_ip_fragment_offset = Signal(intbv(0)[13:]) - input_1_ip_ttl = Signal(intbv(0)[8:]) - input_1_ip_protocol = Signal(intbv(0)[8:]) - input_1_ip_header_checksum = Signal(intbv(0)[16:]) - input_1_ip_source_ip = Signal(intbv(0)[32:]) - input_1_ip_dest_ip = Signal(intbv(0)[32:]) - input_1_udp_source_port = Signal(intbv(0)[16:]) - input_1_udp_dest_port = Signal(intbv(0)[16:]) - input_1_udp_length = Signal(intbv(0)[16:]) - input_1_udp_checksum = Signal(intbv(0)[16:]) - input_1_udp_payload_tdata = Signal(intbv(0)[8:]) - input_1_udp_payload_tvalid = Signal(bool(0)) - input_1_udp_payload_tlast = Signal(bool(0)) - input_1_udp_payload_tuser = Signal(bool(0)) - input_2_udp_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_ip_version = Signal(intbv(0)[4:]) - input_2_ip_ihl = Signal(intbv(0)[4:]) - input_2_ip_dscp = Signal(intbv(0)[6:]) - input_2_ip_ecn = Signal(intbv(0)[2:]) - input_2_ip_length = Signal(intbv(0)[16:]) - input_2_ip_identification = Signal(intbv(0)[16:]) - input_2_ip_flags = Signal(intbv(0)[3:]) - input_2_ip_fragment_offset = Signal(intbv(0)[13:]) - input_2_ip_ttl = Signal(intbv(0)[8:]) - input_2_ip_protocol = Signal(intbv(0)[8:]) - input_2_ip_header_checksum = Signal(intbv(0)[16:]) - input_2_ip_source_ip = Signal(intbv(0)[32:]) - input_2_ip_dest_ip = Signal(intbv(0)[32:]) - input_2_udp_source_port = Signal(intbv(0)[16:]) - input_2_udp_dest_port = Signal(intbv(0)[16:]) - input_2_udp_length = Signal(intbv(0)[16:]) - input_2_udp_checksum = Signal(intbv(0)[16:]) - input_2_udp_payload_tdata = Signal(intbv(0)[8:]) - input_2_udp_payload_tvalid = Signal(bool(0)) - input_2_udp_payload_tlast = Signal(bool(0)) - input_2_udp_payload_tuser = Signal(bool(0)) - input_3_udp_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_ip_version = Signal(intbv(0)[4:]) - input_3_ip_ihl = Signal(intbv(0)[4:]) - input_3_ip_dscp = Signal(intbv(0)[6:]) - input_3_ip_ecn = Signal(intbv(0)[2:]) - input_3_ip_length = Signal(intbv(0)[16:]) - input_3_ip_identification = Signal(intbv(0)[16:]) - input_3_ip_flags = Signal(intbv(0)[3:]) - input_3_ip_fragment_offset = Signal(intbv(0)[13:]) - input_3_ip_ttl = Signal(intbv(0)[8:]) - input_3_ip_protocol = Signal(intbv(0)[8:]) - input_3_ip_header_checksum = Signal(intbv(0)[16:]) - input_3_ip_source_ip = Signal(intbv(0)[32:]) - input_3_ip_dest_ip = Signal(intbv(0)[32:]) - input_3_udp_source_port = Signal(intbv(0)[16:]) - input_3_udp_dest_port = Signal(intbv(0)[16:]) - input_3_udp_length = Signal(intbv(0)[16:]) - input_3_udp_checksum = Signal(intbv(0)[16:]) - input_3_udp_payload_tdata = Signal(intbv(0)[8:]) - input_3_udp_payload_tvalid = Signal(bool(0)) - input_3_udp_payload_tlast = Signal(bool(0)) - input_3_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_version_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_ihl_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_dscp_list = [Signal(intbv(0)[6:]) for i in range(S_COUNT)] + s_ip_ecn_list = [Signal(intbv(0)[2:]) for i in range(S_COUNT)] + s_ip_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_identification_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_flags_list = [Signal(intbv(0)[3:]) for i in range(S_COUNT)] + s_ip_fragment_offset_list = [Signal(intbv(0)[13:]) for i in range(S_COUNT)] + s_ip_ttl_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_protocol_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_header_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_source_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_dest_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_udp_source_port_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_dest_port_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_udp_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_udp_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_udp_payload_tready = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) + s_udp_hdr_valid = ConcatSignal(*reversed(s_udp_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_ip_version = ConcatSignal(*reversed(s_ip_version_list)) + s_ip_ihl = ConcatSignal(*reversed(s_ip_ihl_list)) + s_ip_dscp = ConcatSignal(*reversed(s_ip_dscp_list)) + s_ip_ecn = ConcatSignal(*reversed(s_ip_ecn_list)) + s_ip_length = ConcatSignal(*reversed(s_ip_length_list)) + s_ip_identification = ConcatSignal(*reversed(s_ip_identification_list)) + s_ip_flags = ConcatSignal(*reversed(s_ip_flags_list)) + s_ip_fragment_offset = ConcatSignal(*reversed(s_ip_fragment_offset_list)) + s_ip_ttl = ConcatSignal(*reversed(s_ip_ttl_list)) + s_ip_protocol = ConcatSignal(*reversed(s_ip_protocol_list)) + s_ip_header_checksum = ConcatSignal(*reversed(s_ip_header_checksum_list)) + s_ip_source_ip = ConcatSignal(*reversed(s_ip_source_ip_list)) + s_ip_dest_ip = ConcatSignal(*reversed(s_ip_dest_ip_list)) + s_udp_source_port = ConcatSignal(*reversed(s_udp_source_port_list)) + s_udp_dest_port = ConcatSignal(*reversed(s_udp_dest_port_list)) + s_udp_length = ConcatSignal(*reversed(s_udp_length_list)) + s_udp_checksum = ConcatSignal(*reversed(s_udp_checksum_list)) + s_udp_payload_axis_tdata = ConcatSignal(*reversed(s_udp_payload_axis_tdata_list)) + s_udp_payload_axis_tkeep = ConcatSignal(*reversed(s_udp_payload_axis_tkeep_list)) + s_udp_payload_axis_tvalid = ConcatSignal(*reversed(s_udp_payload_axis_tvalid_list)) + s_udp_payload_axis_tlast = ConcatSignal(*reversed(s_udp_payload_axis_tlast_list)) + s_udp_payload_axis_tid = ConcatSignal(*reversed(s_udp_payload_axis_tid_list)) + s_udp_payload_axis_tdest = ConcatSignal(*reversed(s_udp_payload_axis_tdest_list)) + s_udp_payload_axis_tuser = ConcatSignal(*reversed(s_udp_payload_axis_tuser_list)) + + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) # Outputs - input_0_udp_hdr_ready = Signal(bool(0)) - input_0_udp_payload_tready = Signal(bool(0)) - input_1_udp_hdr_ready = Signal(bool(0)) - input_1_udp_payload_tready = Signal(bool(0)) - input_2_udp_hdr_ready = Signal(bool(0)) - input_2_udp_payload_tready = Signal(bool(0)) - input_3_udp_hdr_ready = Signal(bool(0)) - input_3_udp_payload_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_udp_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_udp_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_ready_list = [s_udp_hdr_ready(i) for i in range(S_COUNT)] + s_udp_payload_axis_tready_list = [s_udp_payload_axis_tready(i) for i in range(S_COUNT)] + + m_udp_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_udp_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_udp_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_udp_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = udp_ep.UDPFrameSource() + for k in range(S_COUNT): + s = udp_ep.UDPFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - udp_hdr_ready=input_0_udp_hdr_ready, - udp_hdr_valid=input_0_udp_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - eth_type=input_0_eth_type, - ip_version=input_0_ip_version, - ip_ihl=input_0_ip_ihl, - ip_dscp=input_0_ip_dscp, - ip_ecn=input_0_ip_ecn, - ip_length=input_0_ip_length, - ip_identification=input_0_ip_identification, - ip_flags=input_0_ip_flags, - ip_fragment_offset=input_0_ip_fragment_offset, - ip_ttl=input_0_ip_ttl, - ip_protocol=input_0_ip_protocol, - ip_header_checksum=input_0_ip_header_checksum, - ip_source_ip=input_0_ip_source_ip, - ip_dest_ip=input_0_ip_dest_ip, - udp_source_port=input_0_udp_source_port, - udp_dest_port=input_0_udp_dest_port, - udp_length=input_0_udp_length, - udp_checksum=input_0_udp_checksum, - udp_payload_tdata=input_0_udp_payload_tdata, - udp_payload_tvalid=input_0_udp_payload_tvalid, - udp_payload_tready=input_0_udp_payload_tready, - udp_payload_tlast=input_0_udp_payload_tlast, - udp_payload_tuser=input_0_udp_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = udp_ep.UDPFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - udp_hdr_ready=input_1_udp_hdr_ready, - udp_hdr_valid=input_1_udp_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - eth_type=input_1_eth_type, - ip_version=input_1_ip_version, - ip_ihl=input_1_ip_ihl, - ip_dscp=input_1_ip_dscp, - ip_ecn=input_1_ip_ecn, - ip_length=input_1_ip_length, - ip_identification=input_1_ip_identification, - ip_flags=input_1_ip_flags, - ip_fragment_offset=input_1_ip_fragment_offset, - ip_ttl=input_1_ip_ttl, - ip_protocol=input_1_ip_protocol, - ip_header_checksum=input_1_ip_header_checksum, - ip_source_ip=input_1_ip_source_ip, - ip_dest_ip=input_1_ip_dest_ip, - udp_source_port=input_1_udp_source_port, - udp_dest_port=input_1_udp_dest_port, - udp_length=input_1_udp_length, - udp_checksum=input_1_udp_checksum, - udp_payload_tdata=input_1_udp_payload_tdata, - udp_payload_tvalid=input_1_udp_payload_tvalid, - udp_payload_tready=input_1_udp_payload_tready, - udp_payload_tlast=input_1_udp_payload_tlast, - udp_payload_tuser=input_1_udp_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = udp_ep.UDPFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - udp_hdr_ready=input_2_udp_hdr_ready, - udp_hdr_valid=input_2_udp_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - ip_version=input_2_ip_version, - ip_ihl=input_2_ip_ihl, - ip_dscp=input_2_ip_dscp, - ip_ecn=input_2_ip_ecn, - ip_length=input_2_ip_length, - ip_identification=input_2_ip_identification, - ip_flags=input_2_ip_flags, - ip_fragment_offset=input_2_ip_fragment_offset, - ip_ttl=input_2_ip_ttl, - ip_protocol=input_2_ip_protocol, - ip_header_checksum=input_2_ip_header_checksum, - ip_source_ip=input_2_ip_source_ip, - ip_dest_ip=input_2_ip_dest_ip, - udp_source_port=input_2_udp_source_port, - udp_dest_port=input_2_udp_dest_port, - udp_length=input_2_udp_length, - udp_checksum=input_2_udp_checksum, - udp_payload_tdata=input_2_udp_payload_tdata, - udp_payload_tvalid=input_2_udp_payload_tvalid, - udp_payload_tready=input_2_udp_payload_tready, - udp_payload_tlast=input_2_udp_payload_tlast, - udp_payload_tuser=input_2_udp_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = udp_ep.UDPFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - udp_hdr_ready=input_3_udp_hdr_ready, - udp_hdr_valid=input_3_udp_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - ip_version=input_3_ip_version, - ip_ihl=input_3_ip_ihl, - ip_dscp=input_3_ip_dscp, - ip_ecn=input_3_ip_ecn, - ip_length=input_3_ip_length, - ip_identification=input_3_ip_identification, - ip_flags=input_3_ip_flags, - ip_fragment_offset=input_3_ip_fragment_offset, - ip_ttl=input_3_ip_ttl, - ip_protocol=input_3_ip_protocol, - ip_header_checksum=input_3_ip_header_checksum, - ip_source_ip=input_3_ip_source_ip, - ip_dest_ip=input_3_ip_dest_ip, - udp_source_port=input_3_udp_source_port, - udp_dest_port=input_3_udp_dest_port, - udp_length=input_3_udp_length, - udp_checksum=input_3_udp_checksum, - udp_payload_tdata=input_3_udp_payload_tdata, - udp_payload_tvalid=input_3_udp_payload_tvalid, - udp_payload_tready=input_3_udp_payload_tready, - udp_payload_tlast=input_3_udp_payload_tlast, - udp_payload_tuser=input_3_udp_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + udp_hdr_ready=s_udp_hdr_ready_list[k], + udp_hdr_valid=s_udp_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + ip_version=s_ip_version_list[k], + ip_ihl=s_ip_ihl_list[k], + ip_dscp=s_ip_dscp_list[k], + ip_ecn=s_ip_ecn_list[k], + ip_length=s_ip_length_list[k], + ip_identification=s_ip_identification_list[k], + ip_flags=s_ip_flags_list[k], + ip_fragment_offset=s_ip_fragment_offset_list[k], + ip_ttl=s_ip_ttl_list[k], + ip_protocol=s_ip_protocol_list[k], + ip_header_checksum=s_ip_header_checksum_list[k], + ip_source_ip=s_ip_source_ip_list[k], + ip_dest_ip=s_ip_dest_ip_list[k], + udp_source_port=s_udp_source_port_list[k], + udp_dest_port=s_udp_dest_port_list[k], + udp_length=s_udp_length_list[k], + udp_checksum=s_udp_checksum_list[k], + udp_payload_tdata=s_udp_payload_axis_tdata_list[k], + udp_payload_tkeep=s_udp_payload_axis_tkeep_list[k], + udp_payload_tvalid=s_udp_payload_axis_tvalid_list[k], + udp_payload_tready=s_udp_payload_axis_tready_list[k], + udp_payload_tlast=s_udp_payload_axis_tlast_list[k], + udp_payload_tuser=s_udp_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = udp_ep.UDPFrameSink() sink_logic = sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tkeep=m_udp_payload_axis_tkeep, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -387,142 +255,67 @@ def bench(): rst=rst, current_test=current_test, - input_0_udp_hdr_valid=input_0_udp_hdr_valid, - input_0_udp_hdr_ready=input_0_udp_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_ip_version=input_0_ip_version, - input_0_ip_ihl=input_0_ip_ihl, - input_0_ip_dscp=input_0_ip_dscp, - input_0_ip_ecn=input_0_ip_ecn, - input_0_ip_length=input_0_ip_length, - input_0_ip_identification=input_0_ip_identification, - input_0_ip_flags=input_0_ip_flags, - input_0_ip_fragment_offset=input_0_ip_fragment_offset, - input_0_ip_ttl=input_0_ip_ttl, - input_0_ip_protocol=input_0_ip_protocol, - input_0_ip_header_checksum=input_0_ip_header_checksum, - input_0_ip_source_ip=input_0_ip_source_ip, - input_0_ip_dest_ip=input_0_ip_dest_ip, - input_0_udp_source_port=input_0_udp_source_port, - input_0_udp_dest_port=input_0_udp_dest_port, - input_0_udp_length=input_0_udp_length, - input_0_udp_checksum=input_0_udp_checksum, - input_0_udp_payload_tdata=input_0_udp_payload_tdata, - input_0_udp_payload_tvalid=input_0_udp_payload_tvalid, - input_0_udp_payload_tready=input_0_udp_payload_tready, - input_0_udp_payload_tlast=input_0_udp_payload_tlast, - input_0_udp_payload_tuser=input_0_udp_payload_tuser, - input_1_udp_hdr_valid=input_1_udp_hdr_valid, - input_1_udp_hdr_ready=input_1_udp_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_ip_version=input_1_ip_version, - input_1_ip_ihl=input_1_ip_ihl, - input_1_ip_dscp=input_1_ip_dscp, - input_1_ip_ecn=input_1_ip_ecn, - input_1_ip_length=input_1_ip_length, - input_1_ip_identification=input_1_ip_identification, - input_1_ip_flags=input_1_ip_flags, - input_1_ip_fragment_offset=input_1_ip_fragment_offset, - input_1_ip_ttl=input_1_ip_ttl, - input_1_ip_protocol=input_1_ip_protocol, - input_1_ip_header_checksum=input_1_ip_header_checksum, - input_1_ip_source_ip=input_1_ip_source_ip, - input_1_ip_dest_ip=input_1_ip_dest_ip, - input_1_udp_source_port=input_1_udp_source_port, - input_1_udp_dest_port=input_1_udp_dest_port, - input_1_udp_length=input_1_udp_length, - input_1_udp_checksum=input_1_udp_checksum, - input_1_udp_payload_tdata=input_1_udp_payload_tdata, - input_1_udp_payload_tvalid=input_1_udp_payload_tvalid, - input_1_udp_payload_tready=input_1_udp_payload_tready, - input_1_udp_payload_tlast=input_1_udp_payload_tlast, - input_1_udp_payload_tuser=input_1_udp_payload_tuser, - input_2_udp_hdr_valid=input_2_udp_hdr_valid, - input_2_udp_hdr_ready=input_2_udp_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_ip_version=input_2_ip_version, - input_2_ip_ihl=input_2_ip_ihl, - input_2_ip_dscp=input_2_ip_dscp, - input_2_ip_ecn=input_2_ip_ecn, - input_2_ip_length=input_2_ip_length, - input_2_ip_identification=input_2_ip_identification, - input_2_ip_flags=input_2_ip_flags, - input_2_ip_fragment_offset=input_2_ip_fragment_offset, - input_2_ip_ttl=input_2_ip_ttl, - input_2_ip_protocol=input_2_ip_protocol, - input_2_ip_header_checksum=input_2_ip_header_checksum, - input_2_ip_source_ip=input_2_ip_source_ip, - input_2_ip_dest_ip=input_2_ip_dest_ip, - input_2_udp_source_port=input_2_udp_source_port, - input_2_udp_dest_port=input_2_udp_dest_port, - input_2_udp_length=input_2_udp_length, - input_2_udp_checksum=input_2_udp_checksum, - input_2_udp_payload_tdata=input_2_udp_payload_tdata, - input_2_udp_payload_tvalid=input_2_udp_payload_tvalid, - input_2_udp_payload_tready=input_2_udp_payload_tready, - input_2_udp_payload_tlast=input_2_udp_payload_tlast, - input_2_udp_payload_tuser=input_2_udp_payload_tuser, - input_3_udp_hdr_valid=input_3_udp_hdr_valid, - input_3_udp_hdr_ready=input_3_udp_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_ip_version=input_3_ip_version, - input_3_ip_ihl=input_3_ip_ihl, - input_3_ip_dscp=input_3_ip_dscp, - input_3_ip_ecn=input_3_ip_ecn, - input_3_ip_length=input_3_ip_length, - input_3_ip_identification=input_3_ip_identification, - input_3_ip_flags=input_3_ip_flags, - input_3_ip_fragment_offset=input_3_ip_fragment_offset, - input_3_ip_ttl=input_3_ip_ttl, - input_3_ip_protocol=input_3_ip_protocol, - input_3_ip_header_checksum=input_3_ip_header_checksum, - input_3_ip_source_ip=input_3_ip_source_ip, - input_3_ip_dest_ip=input_3_ip_dest_ip, - input_3_udp_source_port=input_3_udp_source_port, - input_3_udp_dest_port=input_3_udp_dest_port, - input_3_udp_length=input_3_udp_length, - input_3_udp_checksum=input_3_udp_checksum, - input_3_udp_payload_tdata=input_3_udp_payload_tdata, - input_3_udp_payload_tvalid=input_3_udp_payload_tvalid, - input_3_udp_payload_tready=input_3_udp_payload_tready, - input_3_udp_payload_tlast=input_3_udp_payload_tlast, - input_3_udp_payload_tuser=input_3_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep=s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tid=s_udp_payload_axis_tid, + s_udp_payload_axis_tdest=s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep=m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tid=m_udp_payload_axis_tid, + m_udp_payload_axis_tdest=m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser ) @always(delay(4)) @@ -570,7 +363,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -607,7 +400,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -667,8 +460,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -733,8 +526,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -799,23 +592,23 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_udp_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge yield sink.wait() @@ -881,12 +674,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + while s_udp_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -957,17 +750,17 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) yield clk.posedge yield delay(800) yield clk.posedge - source_1.send(test_frame1) + source_list[1].send(test_frame1) yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_udp_arb_mux_4.v b/tb/test_udp_arb_mux_4.v index 922bf798d..4072e624e 100644 --- a/tb/test_udp_arb_mux_4.v +++ b/tb/test_udp_arb_mux_4.v @@ -27,154 +27,93 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for udp_arb_mux_4 + * Testbench for udp_arb_mux */ module test_udp_arb_mux_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter ARB_TYPE = "PRIORITY"; +parameter LSB_PRIORITY = "HIGH"; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_udp_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [3:0] input_0_ip_version = 0; -reg [3:0] input_0_ip_ihl = 0; -reg [5:0] input_0_ip_dscp = 0; -reg [1:0] input_0_ip_ecn = 0; -reg [15:0] input_0_ip_length = 0; -reg [15:0] input_0_ip_identification = 0; -reg [2:0] input_0_ip_flags = 0; -reg [12:0] input_0_ip_fragment_offset = 0; -reg [7:0] input_0_ip_ttl = 0; -reg [7:0] input_0_ip_protocol = 0; -reg [15:0] input_0_ip_header_checksum = 0; -reg [31:0] input_0_ip_source_ip = 0; -reg [31:0] input_0_ip_dest_ip = 0; -reg [15:0] input_0_udp_source_port = 0; -reg [15:0] input_0_udp_dest_port = 0; -reg [15:0] input_0_udp_length = 0; -reg [15:0] input_0_udp_checksum = 0; -reg [7:0] input_0_udp_payload_tdata = 0; -reg input_0_udp_payload_tvalid = 0; -reg input_0_udp_payload_tlast = 0; -reg input_0_udp_payload_tuser = 0; -reg input_1_udp_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [3:0] input_1_ip_version = 0; -reg [3:0] input_1_ip_ihl = 0; -reg [5:0] input_1_ip_dscp = 0; -reg [1:0] input_1_ip_ecn = 0; -reg [15:0] input_1_ip_length = 0; -reg [15:0] input_1_ip_identification = 0; -reg [2:0] input_1_ip_flags = 0; -reg [12:0] input_1_ip_fragment_offset = 0; -reg [7:0] input_1_ip_ttl = 0; -reg [7:0] input_1_ip_protocol = 0; -reg [15:0] input_1_ip_header_checksum = 0; -reg [31:0] input_1_ip_source_ip = 0; -reg [31:0] input_1_ip_dest_ip = 0; -reg [15:0] input_1_udp_source_port = 0; -reg [15:0] input_1_udp_dest_port = 0; -reg [15:0] input_1_udp_length = 0; -reg [15:0] input_1_udp_checksum = 0; -reg [7:0] input_1_udp_payload_tdata = 0; -reg input_1_udp_payload_tvalid = 0; -reg input_1_udp_payload_tlast = 0; -reg input_1_udp_payload_tuser = 0; -reg input_2_udp_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [3:0] input_2_ip_version = 0; -reg [3:0] input_2_ip_ihl = 0; -reg [5:0] input_2_ip_dscp = 0; -reg [1:0] input_2_ip_ecn = 0; -reg [15:0] input_2_ip_length = 0; -reg [15:0] input_2_ip_identification = 0; -reg [2:0] input_2_ip_flags = 0; -reg [12:0] input_2_ip_fragment_offset = 0; -reg [7:0] input_2_ip_ttl = 0; -reg [7:0] input_2_ip_protocol = 0; -reg [15:0] input_2_ip_header_checksum = 0; -reg [31:0] input_2_ip_source_ip = 0; -reg [31:0] input_2_ip_dest_ip = 0; -reg [15:0] input_2_udp_source_port = 0; -reg [15:0] input_2_udp_dest_port = 0; -reg [15:0] input_2_udp_length = 0; -reg [15:0] input_2_udp_checksum = 0; -reg [7:0] input_2_udp_payload_tdata = 0; -reg input_2_udp_payload_tvalid = 0; -reg input_2_udp_payload_tlast = 0; -reg input_2_udp_payload_tuser = 0; -reg input_3_udp_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [3:0] input_3_ip_version = 0; -reg [3:0] input_3_ip_ihl = 0; -reg [5:0] input_3_ip_dscp = 0; -reg [1:0] input_3_ip_ecn = 0; -reg [15:0] input_3_ip_length = 0; -reg [15:0] input_3_ip_identification = 0; -reg [2:0] input_3_ip_flags = 0; -reg [12:0] input_3_ip_fragment_offset = 0; -reg [7:0] input_3_ip_ttl = 0; -reg [7:0] input_3_ip_protocol = 0; -reg [15:0] input_3_ip_header_checksum = 0; -reg [31:0] input_3_ip_source_ip = 0; -reg [31:0] input_3_ip_dest_ip = 0; -reg [15:0] input_3_udp_source_port = 0; -reg [15:0] input_3_udp_dest_port = 0; -reg [15:0] input_3_udp_length = 0; -reg [15:0] input_3_udp_checksum = 0; -reg [7:0] input_3_udp_payload_tdata = 0; -reg input_3_udp_payload_tvalid = 0; -reg input_3_udp_payload_tlast = 0; -reg input_3_udp_payload_tuser = 0; +reg [S_COUNT-1:0] s_udp_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*4-1:0] s_ip_version = 0; +reg [S_COUNT*4-1:0] s_ip_ihl = 0; +reg [S_COUNT*6-1:0] s_ip_dscp = 0; +reg [S_COUNT*2-1:0] s_ip_ecn = 0; +reg [S_COUNT*16-1:0] s_ip_length = 0; +reg [S_COUNT*16-1:0] s_ip_identification = 0; +reg [S_COUNT*3-1:0] s_ip_flags = 0; +reg [S_COUNT*13-1:0] s_ip_fragment_offset = 0; +reg [S_COUNT*8-1:0] s_ip_ttl = 0; +reg [S_COUNT*8-1:0] s_ip_protocol = 0; +reg [S_COUNT*16-1:0] s_ip_header_checksum = 0; +reg [S_COUNT*32-1:0] s_ip_source_ip = 0; +reg [S_COUNT*32-1:0] s_ip_dest_ip = 0; +reg [S_COUNT*16-1:0] s_udp_source_port = 0; +reg [S_COUNT*16-1:0] s_udp_dest_port = 0; +reg [S_COUNT*16-1:0] s_udp_length = 0; +reg [S_COUNT*16-1:0] s_udp_checksum = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_udp_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_udp_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_udp_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_udp_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_udp_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_udp_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_udp_payload_axis_tuser = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; // Outputs -wire input_0_udp_payload_tready; -wire input_0_udp_hdr_ready; -wire input_1_udp_payload_tready; -wire input_1_udp_hdr_ready; -wire input_2_udp_payload_tready; -wire input_2_udp_hdr_ready; -wire input_3_udp_payload_tready; -wire input_3_udp_hdr_ready; +wire [S_COUNT-1:0] s_udp_hdr_ready; +wire [S_COUNT-1:0] s_udp_payload_axis_tready; -wire output_udp_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [7:0] output_udp_payload_tdata; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire m_udp_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [DATA_WIDTH-1:0] m_udp_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_udp_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_udp_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_udp_payload_axis_tuser; initial begin // myhdl integration @@ -182,143 +121,68 @@ initial begin clk, rst, current_test, - input_0_udp_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_ip_version, - input_0_ip_ihl, - input_0_ip_dscp, - input_0_ip_ecn, - input_0_ip_length, - input_0_ip_identification, - input_0_ip_flags, - input_0_ip_fragment_offset, - input_0_ip_ttl, - input_0_ip_protocol, - input_0_ip_header_checksum, - input_0_ip_source_ip, - input_0_ip_dest_ip, - input_0_udp_source_port, - input_0_udp_dest_port, - input_0_udp_length, - input_0_udp_checksum, - input_0_udp_payload_tdata, - input_0_udp_payload_tvalid, - input_0_udp_payload_tlast, - input_0_udp_payload_tuser, - input_1_udp_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_ip_version, - input_1_ip_ihl, - input_1_ip_dscp, - input_1_ip_ecn, - input_1_ip_length, - input_1_ip_identification, - input_1_ip_flags, - input_1_ip_fragment_offset, - input_1_ip_ttl, - input_1_ip_protocol, - input_1_ip_header_checksum, - input_1_ip_source_ip, - input_1_ip_dest_ip, - input_1_udp_source_port, - input_1_udp_dest_port, - input_1_udp_length, - input_1_udp_checksum, - input_1_udp_payload_tdata, - input_1_udp_payload_tvalid, - input_1_udp_payload_tlast, - input_1_udp_payload_tuser, - input_2_udp_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_ip_version, - input_2_ip_ihl, - input_2_ip_dscp, - input_2_ip_ecn, - input_2_ip_length, - input_2_ip_identification, - input_2_ip_flags, - input_2_ip_fragment_offset, - input_2_ip_ttl, - input_2_ip_protocol, - input_2_ip_header_checksum, - input_2_ip_source_ip, - input_2_ip_dest_ip, - input_2_udp_source_port, - input_2_udp_dest_port, - input_2_udp_length, - input_2_udp_checksum, - input_2_udp_payload_tdata, - input_2_udp_payload_tvalid, - input_2_udp_payload_tlast, - input_2_udp_payload_tuser, - input_3_udp_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_ip_version, - input_3_ip_ihl, - input_3_ip_dscp, - input_3_ip_ecn, - input_3_ip_length, - input_3_ip_identification, - input_3_ip_flags, - input_3_ip_fragment_offset, - input_3_ip_ttl, - input_3_ip_protocol, - input_3_ip_header_checksum, - input_3_ip_source_ip, - input_3_ip_dest_ip, - input_3_udp_source_port, - input_3_udp_dest_port, - input_3_udp_length, - input_3_udp_checksum, - input_3_udp_payload_tdata, - input_3_udp_payload_tvalid, - input_3_udp_payload_tlast, - input_3_udp_payload_tuser, - output_udp_hdr_ready, - output_udp_payload_tready + s_udp_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tid, + s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser, + m_udp_hdr_ready, + m_udp_payload_axis_tready ); $to_myhdl( - input_0_udp_hdr_ready, - input_0_udp_payload_tready, - input_1_udp_hdr_ready, - input_1_udp_payload_tready, - input_2_udp_hdr_ready, - input_2_udp_payload_tready, - input_3_udp_hdr_ready, - input_3_udp_payload_tready, - output_udp_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_udp_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tid, + m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser ); // dump file @@ -326,147 +190,85 @@ initial begin $dumpvars(0, test_udp_arb_mux_4); end -udp_arb_mux_4 +udp_arb_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) +) UUT ( .clk(clk), .rst(rst), - // UDP frame inputs - .input_0_udp_hdr_valid(input_0_udp_hdr_valid), - .input_0_udp_hdr_ready(input_0_udp_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_udp_source_port(input_0_udp_source_port), - .input_0_udp_dest_port(input_0_udp_dest_port), - .input_0_udp_length(input_0_udp_length), - .input_0_udp_checksum(input_0_udp_checksum), - .input_0_udp_payload_tdata(input_0_udp_payload_tdata), - .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid), - .input_0_udp_payload_tready(input_0_udp_payload_tready), - .input_0_udp_payload_tlast(input_0_udp_payload_tlast), - .input_0_udp_payload_tuser(input_0_udp_payload_tuser), - .input_1_udp_hdr_valid(input_1_udp_hdr_valid), - .input_1_udp_hdr_ready(input_1_udp_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_udp_source_port(input_1_udp_source_port), - .input_1_udp_dest_port(input_1_udp_dest_port), - .input_1_udp_length(input_1_udp_length), - .input_1_udp_checksum(input_1_udp_checksum), - .input_1_udp_payload_tdata(input_1_udp_payload_tdata), - .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid), - .input_1_udp_payload_tready(input_1_udp_payload_tready), - .input_1_udp_payload_tlast(input_1_udp_payload_tlast), - .input_1_udp_payload_tuser(input_1_udp_payload_tuser), - .input_2_udp_hdr_valid(input_2_udp_hdr_valid), - .input_2_udp_hdr_ready(input_2_udp_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_udp_source_port(input_2_udp_source_port), - .input_2_udp_dest_port(input_2_udp_dest_port), - .input_2_udp_length(input_2_udp_length), - .input_2_udp_checksum(input_2_udp_checksum), - .input_2_udp_payload_tdata(input_2_udp_payload_tdata), - .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid), - .input_2_udp_payload_tready(input_2_udp_payload_tready), - .input_2_udp_payload_tlast(input_2_udp_payload_tlast), - .input_2_udp_payload_tuser(input_2_udp_payload_tuser), - .input_3_udp_hdr_valid(input_3_udp_hdr_valid), - .input_3_udp_hdr_ready(input_3_udp_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_udp_source_port(input_3_udp_source_port), - .input_3_udp_dest_port(input_3_udp_dest_port), - .input_3_udp_length(input_3_udp_length), - .input_3_udp_checksum(input_3_udp_checksum), - .input_3_udp_payload_tdata(input_3_udp_payload_tdata), - .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid), - .input_3_udp_payload_tready(input_3_udp_payload_tready), - .input_3_udp_payload_tlast(input_3_udp_payload_tlast), - .input_3_udp_payload_tuser(input_3_udp_payload_tuser), - // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser) + // Ethernet frame inputs + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tid(s_udp_payload_axis_tid), + .s_udp_payload_axis_tdest(s_udp_payload_axis_tdest), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), + // Ethernet frame output + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tid(m_udp_payload_axis_tid), + .m_udp_payload_axis_tdest(m_udp_payload_axis_tdest), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser) ); endmodule diff --git a/tb/test_udp_arb_mux_64_4.py b/tb/test_udp_arb_mux_64_4.py index 867b3af5a..c28ac25c4 100755 --- a/tb/test_udp_arb_mux_64_4.py +++ b/tb/test_udp_arb_mux_64_4.py @@ -28,13 +28,12 @@ import os import udp_ep -module = 'udp_arb_mux_64_4' -testbench = 'test_%s' % module +module = 'udp_arb_mux' +testbench = 'test_%s_64_4' % module srcs = [] srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/udp_mux_64_4.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") srcs.append("%s.v" % testbench) @@ -45,344 +44,203 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + S_COUNT = 4 + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + ARB_TYPE = "PRIORITY" + LSB_PRIORITY = "HIGH" + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_0_udp_hdr_valid = Signal(bool(0)) - input_0_eth_dest_mac = Signal(intbv(0)[48:]) - input_0_eth_src_mac = Signal(intbv(0)[48:]) - input_0_eth_type = Signal(intbv(0)[16:]) - input_0_ip_version = Signal(intbv(0)[4:]) - input_0_ip_ihl = Signal(intbv(0)[4:]) - input_0_ip_dscp = Signal(intbv(0)[6:]) - input_0_ip_ecn = Signal(intbv(0)[2:]) - input_0_ip_length = Signal(intbv(0)[16:]) - input_0_ip_identification = Signal(intbv(0)[16:]) - input_0_ip_flags = Signal(intbv(0)[3:]) - input_0_ip_fragment_offset = Signal(intbv(0)[13:]) - input_0_ip_ttl = Signal(intbv(0)[8:]) - input_0_ip_protocol = Signal(intbv(0)[8:]) - input_0_ip_header_checksum = Signal(intbv(0)[16:]) - input_0_ip_source_ip = Signal(intbv(0)[32:]) - input_0_ip_dest_ip = Signal(intbv(0)[32:]) - input_0_udp_source_port = Signal(intbv(0)[16:]) - input_0_udp_dest_port = Signal(intbv(0)[16:]) - input_0_udp_length = Signal(intbv(0)[16:]) - input_0_udp_checksum = Signal(intbv(0)[16:]) - input_0_udp_payload_tdata = Signal(intbv(0)[64:]) - input_0_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_0_udp_payload_tvalid = Signal(bool(0)) - input_0_udp_payload_tlast = Signal(bool(0)) - input_0_udp_payload_tuser = Signal(bool(0)) - input_1_udp_hdr_valid = Signal(bool(0)) - input_1_eth_dest_mac = Signal(intbv(0)[48:]) - input_1_eth_src_mac = Signal(intbv(0)[48:]) - input_1_eth_type = Signal(intbv(0)[16:]) - input_1_ip_version = Signal(intbv(0)[4:]) - input_1_ip_ihl = Signal(intbv(0)[4:]) - input_1_ip_dscp = Signal(intbv(0)[6:]) - input_1_ip_ecn = Signal(intbv(0)[2:]) - input_1_ip_length = Signal(intbv(0)[16:]) - input_1_ip_identification = Signal(intbv(0)[16:]) - input_1_ip_flags = Signal(intbv(0)[3:]) - input_1_ip_fragment_offset = Signal(intbv(0)[13:]) - input_1_ip_ttl = Signal(intbv(0)[8:]) - input_1_ip_protocol = Signal(intbv(0)[8:]) - input_1_ip_header_checksum = Signal(intbv(0)[16:]) - input_1_ip_source_ip = Signal(intbv(0)[32:]) - input_1_ip_dest_ip = Signal(intbv(0)[32:]) - input_1_udp_source_port = Signal(intbv(0)[16:]) - input_1_udp_dest_port = Signal(intbv(0)[16:]) - input_1_udp_length = Signal(intbv(0)[16:]) - input_1_udp_checksum = Signal(intbv(0)[16:]) - input_1_udp_payload_tdata = Signal(intbv(0)[64:]) - input_1_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_1_udp_payload_tvalid = Signal(bool(0)) - input_1_udp_payload_tlast = Signal(bool(0)) - input_1_udp_payload_tuser = Signal(bool(0)) - input_2_udp_hdr_valid = Signal(bool(0)) - input_2_eth_dest_mac = Signal(intbv(0)[48:]) - input_2_eth_src_mac = Signal(intbv(0)[48:]) - input_2_eth_type = Signal(intbv(0)[16:]) - input_2_ip_version = Signal(intbv(0)[4:]) - input_2_ip_ihl = Signal(intbv(0)[4:]) - input_2_ip_dscp = Signal(intbv(0)[6:]) - input_2_ip_ecn = Signal(intbv(0)[2:]) - input_2_ip_length = Signal(intbv(0)[16:]) - input_2_ip_identification = Signal(intbv(0)[16:]) - input_2_ip_flags = Signal(intbv(0)[3:]) - input_2_ip_fragment_offset = Signal(intbv(0)[13:]) - input_2_ip_ttl = Signal(intbv(0)[8:]) - input_2_ip_protocol = Signal(intbv(0)[8:]) - input_2_ip_header_checksum = Signal(intbv(0)[16:]) - input_2_ip_source_ip = Signal(intbv(0)[32:]) - input_2_ip_dest_ip = Signal(intbv(0)[32:]) - input_2_udp_source_port = Signal(intbv(0)[16:]) - input_2_udp_dest_port = Signal(intbv(0)[16:]) - input_2_udp_length = Signal(intbv(0)[16:]) - input_2_udp_checksum = Signal(intbv(0)[16:]) - input_2_udp_payload_tdata = Signal(intbv(0)[64:]) - input_2_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_2_udp_payload_tvalid = Signal(bool(0)) - input_2_udp_payload_tlast = Signal(bool(0)) - input_2_udp_payload_tuser = Signal(bool(0)) - input_3_udp_hdr_valid = Signal(bool(0)) - input_3_eth_dest_mac = Signal(intbv(0)[48:]) - input_3_eth_src_mac = Signal(intbv(0)[48:]) - input_3_eth_type = Signal(intbv(0)[16:]) - input_3_ip_version = Signal(intbv(0)[4:]) - input_3_ip_ihl = Signal(intbv(0)[4:]) - input_3_ip_dscp = Signal(intbv(0)[6:]) - input_3_ip_ecn = Signal(intbv(0)[2:]) - input_3_ip_length = Signal(intbv(0)[16:]) - input_3_ip_identification = Signal(intbv(0)[16:]) - input_3_ip_flags = Signal(intbv(0)[3:]) - input_3_ip_fragment_offset = Signal(intbv(0)[13:]) - input_3_ip_ttl = Signal(intbv(0)[8:]) - input_3_ip_protocol = Signal(intbv(0)[8:]) - input_3_ip_header_checksum = Signal(intbv(0)[16:]) - input_3_ip_source_ip = Signal(intbv(0)[32:]) - input_3_ip_dest_ip = Signal(intbv(0)[32:]) - input_3_udp_source_port = Signal(intbv(0)[16:]) - input_3_udp_dest_port = Signal(intbv(0)[16:]) - input_3_udp_length = Signal(intbv(0)[16:]) - input_3_udp_checksum = Signal(intbv(0)[16:]) - input_3_udp_payload_tdata = Signal(intbv(0)[64:]) - input_3_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_3_udp_payload_tvalid = Signal(bool(0)) - input_3_udp_payload_tlast = Signal(bool(0)) - input_3_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_valid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_eth_dest_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_src_mac_list = [Signal(intbv(0)[48:]) for i in range(S_COUNT)] + s_eth_type_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_version_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_ihl_list = [Signal(intbv(0)[4:]) for i in range(S_COUNT)] + s_ip_dscp_list = [Signal(intbv(0)[6:]) for i in range(S_COUNT)] + s_ip_ecn_list = [Signal(intbv(0)[2:]) for i in range(S_COUNT)] + s_ip_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_identification_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_flags_list = [Signal(intbv(0)[3:]) for i in range(S_COUNT)] + s_ip_fragment_offset_list = [Signal(intbv(0)[13:]) for i in range(S_COUNT)] + s_ip_ttl_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_protocol_list = [Signal(intbv(0)[8:]) for i in range(S_COUNT)] + s_ip_header_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_ip_source_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_ip_dest_ip_list = [Signal(intbv(0)[32:]) for i in range(S_COUNT)] + s_udp_source_port_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_dest_port_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_length_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_checksum_list = [Signal(intbv(0)[16:]) for i in range(S_COUNT)] + s_udp_payload_axis_tdata_list = [Signal(intbv(0)[DATA_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tkeep_list = [Signal(intbv(1)[KEEP_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_udp_payload_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)] + s_udp_payload_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)] + s_udp_payload_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)] - output_udp_payload_tready = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) + s_udp_hdr_valid = ConcatSignal(*reversed(s_udp_hdr_valid_list)) + s_eth_dest_mac = ConcatSignal(*reversed(s_eth_dest_mac_list)) + s_eth_src_mac = ConcatSignal(*reversed(s_eth_src_mac_list)) + s_eth_type = ConcatSignal(*reversed(s_eth_type_list)) + s_ip_version = ConcatSignal(*reversed(s_ip_version_list)) + s_ip_ihl = ConcatSignal(*reversed(s_ip_ihl_list)) + s_ip_dscp = ConcatSignal(*reversed(s_ip_dscp_list)) + s_ip_ecn = ConcatSignal(*reversed(s_ip_ecn_list)) + s_ip_length = ConcatSignal(*reversed(s_ip_length_list)) + s_ip_identification = ConcatSignal(*reversed(s_ip_identification_list)) + s_ip_flags = ConcatSignal(*reversed(s_ip_flags_list)) + s_ip_fragment_offset = ConcatSignal(*reversed(s_ip_fragment_offset_list)) + s_ip_ttl = ConcatSignal(*reversed(s_ip_ttl_list)) + s_ip_protocol = ConcatSignal(*reversed(s_ip_protocol_list)) + s_ip_header_checksum = ConcatSignal(*reversed(s_ip_header_checksum_list)) + s_ip_source_ip = ConcatSignal(*reversed(s_ip_source_ip_list)) + s_ip_dest_ip = ConcatSignal(*reversed(s_ip_dest_ip_list)) + s_udp_source_port = ConcatSignal(*reversed(s_udp_source_port_list)) + s_udp_dest_port = ConcatSignal(*reversed(s_udp_dest_port_list)) + s_udp_length = ConcatSignal(*reversed(s_udp_length_list)) + s_udp_checksum = ConcatSignal(*reversed(s_udp_checksum_list)) + s_udp_payload_axis_tdata = ConcatSignal(*reversed(s_udp_payload_axis_tdata_list)) + s_udp_payload_axis_tkeep = ConcatSignal(*reversed(s_udp_payload_axis_tkeep_list)) + s_udp_payload_axis_tvalid = ConcatSignal(*reversed(s_udp_payload_axis_tvalid_list)) + s_udp_payload_axis_tlast = ConcatSignal(*reversed(s_udp_payload_axis_tlast_list)) + s_udp_payload_axis_tid = ConcatSignal(*reversed(s_udp_payload_axis_tid_list)) + s_udp_payload_axis_tdest = ConcatSignal(*reversed(s_udp_payload_axis_tdest_list)) + s_udp_payload_axis_tuser = ConcatSignal(*reversed(s_udp_payload_axis_tuser_list)) + + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) # Outputs - input_0_udp_hdr_ready = Signal(bool(0)) - input_0_udp_payload_tready = Signal(bool(0)) - input_1_udp_hdr_ready = Signal(bool(0)) - input_1_udp_payload_tready = Signal(bool(0)) - input_2_udp_hdr_ready = Signal(bool(0)) - input_2_udp_payload_tready = Signal(bool(0)) - input_3_udp_hdr_ready = Signal(bool(0)) - input_3_udp_payload_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(intbv(0)[S_COUNT:]) + s_udp_payload_axis_tready = Signal(intbv(0)[S_COUNT:]) - output_udp_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[64:]) - output_udp_payload_tkeep = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_ready_list = [s_udp_hdr_ready(i) for i in range(S_COUNT)] + s_udp_payload_axis_tready_list = [s_udp_payload_axis_tready(i) for i in range(S_COUNT)] + + m_udp_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_udp_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_udp_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_udp_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) # sources and sinks - source_0_pause = Signal(bool(0)) - source_1_pause = Signal(bool(0)) - source_2_pause = Signal(bool(0)) - source_3_pause = Signal(bool(0)) + source_pause_list = [] + source_list = [] + source_logic_list = [] sink_pause = Signal(bool(0)) - source_0 = udp_ep.UDPFrameSource() + for k in range(S_COUNT): + s = udp_ep.UDPFrameSource() + p = Signal(bool(0)) - source_0_logic = source_0.create_logic( - clk, - rst, - udp_hdr_ready=input_0_udp_hdr_ready, - udp_hdr_valid=input_0_udp_hdr_valid, - eth_dest_mac=input_0_eth_dest_mac, - eth_src_mac=input_0_eth_src_mac, - eth_type=input_0_eth_type, - ip_version=input_0_ip_version, - ip_ihl=input_0_ip_ihl, - ip_dscp=input_0_ip_dscp, - ip_ecn=input_0_ip_ecn, - ip_length=input_0_ip_length, - ip_identification=input_0_ip_identification, - ip_flags=input_0_ip_flags, - ip_fragment_offset=input_0_ip_fragment_offset, - ip_ttl=input_0_ip_ttl, - ip_protocol=input_0_ip_protocol, - ip_header_checksum=input_0_ip_header_checksum, - ip_source_ip=input_0_ip_source_ip, - ip_dest_ip=input_0_ip_dest_ip, - udp_source_port=input_0_udp_source_port, - udp_dest_port=input_0_udp_dest_port, - udp_length=input_0_udp_length, - udp_checksum=input_0_udp_checksum, - udp_payload_tdata=input_0_udp_payload_tdata, - udp_payload_tkeep=input_0_udp_payload_tkeep, - udp_payload_tvalid=input_0_udp_payload_tvalid, - udp_payload_tready=input_0_udp_payload_tready, - udp_payload_tlast=input_0_udp_payload_tlast, - udp_payload_tuser=input_0_udp_payload_tuser, - pause=source_0_pause, - name='source_0' - ) + source_list.append(s) + source_pause_list.append(p) - source_1 = udp_ep.UDPFrameSource() - - source_1_logic = source_1.create_logic( - clk, - rst, - udp_hdr_ready=input_1_udp_hdr_ready, - udp_hdr_valid=input_1_udp_hdr_valid, - eth_dest_mac=input_1_eth_dest_mac, - eth_src_mac=input_1_eth_src_mac, - eth_type=input_1_eth_type, - ip_version=input_1_ip_version, - ip_ihl=input_1_ip_ihl, - ip_dscp=input_1_ip_dscp, - ip_ecn=input_1_ip_ecn, - ip_length=input_1_ip_length, - ip_identification=input_1_ip_identification, - ip_flags=input_1_ip_flags, - ip_fragment_offset=input_1_ip_fragment_offset, - ip_ttl=input_1_ip_ttl, - ip_protocol=input_1_ip_protocol, - ip_header_checksum=input_1_ip_header_checksum, - ip_source_ip=input_1_ip_source_ip, - ip_dest_ip=input_1_ip_dest_ip, - udp_source_port=input_1_udp_source_port, - udp_dest_port=input_1_udp_dest_port, - udp_length=input_1_udp_length, - udp_checksum=input_1_udp_checksum, - udp_payload_tdata=input_1_udp_payload_tdata, - udp_payload_tkeep=input_1_udp_payload_tkeep, - udp_payload_tvalid=input_1_udp_payload_tvalid, - udp_payload_tready=input_1_udp_payload_tready, - udp_payload_tlast=input_1_udp_payload_tlast, - udp_payload_tuser=input_1_udp_payload_tuser, - pause=source_1_pause, - name='source_1' - ) - - source_2 = udp_ep.UDPFrameSource() - - source_2_logic = source_2.create_logic( - clk, - rst, - udp_hdr_ready=input_2_udp_hdr_ready, - udp_hdr_valid=input_2_udp_hdr_valid, - eth_dest_mac=input_2_eth_dest_mac, - eth_src_mac=input_2_eth_src_mac, - eth_type=input_2_eth_type, - ip_version=input_2_ip_version, - ip_ihl=input_2_ip_ihl, - ip_dscp=input_2_ip_dscp, - ip_ecn=input_2_ip_ecn, - ip_length=input_2_ip_length, - ip_identification=input_2_ip_identification, - ip_flags=input_2_ip_flags, - ip_fragment_offset=input_2_ip_fragment_offset, - ip_ttl=input_2_ip_ttl, - ip_protocol=input_2_ip_protocol, - ip_header_checksum=input_2_ip_header_checksum, - ip_source_ip=input_2_ip_source_ip, - ip_dest_ip=input_2_ip_dest_ip, - udp_source_port=input_2_udp_source_port, - udp_dest_port=input_2_udp_dest_port, - udp_length=input_2_udp_length, - udp_checksum=input_2_udp_checksum, - udp_payload_tdata=input_2_udp_payload_tdata, - udp_payload_tkeep=input_2_udp_payload_tkeep, - udp_payload_tvalid=input_2_udp_payload_tvalid, - udp_payload_tready=input_2_udp_payload_tready, - udp_payload_tlast=input_2_udp_payload_tlast, - udp_payload_tuser=input_2_udp_payload_tuser, - pause=source_2_pause, - name='source_2' - ) - - source_3 = udp_ep.UDPFrameSource() - - source_3_logic = source_3.create_logic( - clk, - rst, - udp_hdr_ready=input_3_udp_hdr_ready, - udp_hdr_valid=input_3_udp_hdr_valid, - eth_dest_mac=input_3_eth_dest_mac, - eth_src_mac=input_3_eth_src_mac, - eth_type=input_3_eth_type, - ip_version=input_3_ip_version, - ip_ihl=input_3_ip_ihl, - ip_dscp=input_3_ip_dscp, - ip_ecn=input_3_ip_ecn, - ip_length=input_3_ip_length, - ip_identification=input_3_ip_identification, - ip_flags=input_3_ip_flags, - ip_fragment_offset=input_3_ip_fragment_offset, - ip_ttl=input_3_ip_ttl, - ip_protocol=input_3_ip_protocol, - ip_header_checksum=input_3_ip_header_checksum, - ip_source_ip=input_3_ip_source_ip, - ip_dest_ip=input_3_ip_dest_ip, - udp_source_port=input_3_udp_source_port, - udp_dest_port=input_3_udp_dest_port, - udp_length=input_3_udp_length, - udp_checksum=input_3_udp_checksum, - udp_payload_tdata=input_3_udp_payload_tdata, - udp_payload_tkeep=input_3_udp_payload_tkeep, - udp_payload_tvalid=input_3_udp_payload_tvalid, - udp_payload_tready=input_3_udp_payload_tready, - udp_payload_tlast=input_3_udp_payload_tlast, - udp_payload_tuser=input_3_udp_payload_tuser, - pause=source_3_pause, - name='source_3' - ) + source_logic_list.append(s.create_logic( + clk, + rst, + udp_hdr_ready=s_udp_hdr_ready_list[k], + udp_hdr_valid=s_udp_hdr_valid_list[k], + eth_dest_mac=s_eth_dest_mac_list[k], + eth_src_mac=s_eth_src_mac_list[k], + eth_type=s_eth_type_list[k], + ip_version=s_ip_version_list[k], + ip_ihl=s_ip_ihl_list[k], + ip_dscp=s_ip_dscp_list[k], + ip_ecn=s_ip_ecn_list[k], + ip_length=s_ip_length_list[k], + ip_identification=s_ip_identification_list[k], + ip_flags=s_ip_flags_list[k], + ip_fragment_offset=s_ip_fragment_offset_list[k], + ip_ttl=s_ip_ttl_list[k], + ip_protocol=s_ip_protocol_list[k], + ip_header_checksum=s_ip_header_checksum_list[k], + ip_source_ip=s_ip_source_ip_list[k], + ip_dest_ip=s_ip_dest_ip_list[k], + udp_source_port=s_udp_source_port_list[k], + udp_dest_port=s_udp_dest_port_list[k], + udp_length=s_udp_length_list[k], + udp_checksum=s_udp_checksum_list[k], + udp_payload_tdata=s_udp_payload_axis_tdata_list[k], + udp_payload_tkeep=s_udp_payload_axis_tkeep_list[k], + udp_payload_tvalid=s_udp_payload_axis_tvalid_list[k], + udp_payload_tready=s_udp_payload_axis_tready_list[k], + udp_payload_tlast=s_udp_payload_axis_tlast_list[k], + udp_payload_tuser=s_udp_payload_axis_tuser_list[k], + pause=p, + name='source_%d' % k + )) sink = udp_ep.UDPFrameSink() sink_logic = sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tkeep=output_udp_payload_tkeep, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tkeep=m_udp_payload_axis_tkeep, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -397,147 +255,67 @@ def bench(): rst=rst, current_test=current_test, - input_0_udp_hdr_valid=input_0_udp_hdr_valid, - input_0_udp_hdr_ready=input_0_udp_hdr_ready, - input_0_eth_dest_mac=input_0_eth_dest_mac, - input_0_eth_src_mac=input_0_eth_src_mac, - input_0_eth_type=input_0_eth_type, - input_0_ip_version=input_0_ip_version, - input_0_ip_ihl=input_0_ip_ihl, - input_0_ip_dscp=input_0_ip_dscp, - input_0_ip_ecn=input_0_ip_ecn, - input_0_ip_length=input_0_ip_length, - input_0_ip_identification=input_0_ip_identification, - input_0_ip_flags=input_0_ip_flags, - input_0_ip_fragment_offset=input_0_ip_fragment_offset, - input_0_ip_ttl=input_0_ip_ttl, - input_0_ip_protocol=input_0_ip_protocol, - input_0_ip_header_checksum=input_0_ip_header_checksum, - input_0_ip_source_ip=input_0_ip_source_ip, - input_0_ip_dest_ip=input_0_ip_dest_ip, - input_0_udp_source_port=input_0_udp_source_port, - input_0_udp_dest_port=input_0_udp_dest_port, - input_0_udp_length=input_0_udp_length, - input_0_udp_checksum=input_0_udp_checksum, - input_0_udp_payload_tdata=input_0_udp_payload_tdata, - input_0_udp_payload_tkeep=input_0_udp_payload_tkeep, - input_0_udp_payload_tvalid=input_0_udp_payload_tvalid, - input_0_udp_payload_tready=input_0_udp_payload_tready, - input_0_udp_payload_tlast=input_0_udp_payload_tlast, - input_0_udp_payload_tuser=input_0_udp_payload_tuser, - input_1_udp_hdr_valid=input_1_udp_hdr_valid, - input_1_udp_hdr_ready=input_1_udp_hdr_ready, - input_1_eth_dest_mac=input_1_eth_dest_mac, - input_1_eth_src_mac=input_1_eth_src_mac, - input_1_eth_type=input_1_eth_type, - input_1_ip_version=input_1_ip_version, - input_1_ip_ihl=input_1_ip_ihl, - input_1_ip_dscp=input_1_ip_dscp, - input_1_ip_ecn=input_1_ip_ecn, - input_1_ip_length=input_1_ip_length, - input_1_ip_identification=input_1_ip_identification, - input_1_ip_flags=input_1_ip_flags, - input_1_ip_fragment_offset=input_1_ip_fragment_offset, - input_1_ip_ttl=input_1_ip_ttl, - input_1_ip_protocol=input_1_ip_protocol, - input_1_ip_header_checksum=input_1_ip_header_checksum, - input_1_ip_source_ip=input_1_ip_source_ip, - input_1_ip_dest_ip=input_1_ip_dest_ip, - input_1_udp_source_port=input_1_udp_source_port, - input_1_udp_dest_port=input_1_udp_dest_port, - input_1_udp_length=input_1_udp_length, - input_1_udp_checksum=input_1_udp_checksum, - input_1_udp_payload_tdata=input_1_udp_payload_tdata, - input_1_udp_payload_tkeep=input_1_udp_payload_tkeep, - input_1_udp_payload_tvalid=input_1_udp_payload_tvalid, - input_1_udp_payload_tready=input_1_udp_payload_tready, - input_1_udp_payload_tlast=input_1_udp_payload_tlast, - input_1_udp_payload_tuser=input_1_udp_payload_tuser, - input_2_udp_hdr_valid=input_2_udp_hdr_valid, - input_2_udp_hdr_ready=input_2_udp_hdr_ready, - input_2_eth_dest_mac=input_2_eth_dest_mac, - input_2_eth_src_mac=input_2_eth_src_mac, - input_2_eth_type=input_2_eth_type, - input_2_ip_version=input_2_ip_version, - input_2_ip_ihl=input_2_ip_ihl, - input_2_ip_dscp=input_2_ip_dscp, - input_2_ip_ecn=input_2_ip_ecn, - input_2_ip_length=input_2_ip_length, - input_2_ip_identification=input_2_ip_identification, - input_2_ip_flags=input_2_ip_flags, - input_2_ip_fragment_offset=input_2_ip_fragment_offset, - input_2_ip_ttl=input_2_ip_ttl, - input_2_ip_protocol=input_2_ip_protocol, - input_2_ip_header_checksum=input_2_ip_header_checksum, - input_2_ip_source_ip=input_2_ip_source_ip, - input_2_ip_dest_ip=input_2_ip_dest_ip, - input_2_udp_source_port=input_2_udp_source_port, - input_2_udp_dest_port=input_2_udp_dest_port, - input_2_udp_length=input_2_udp_length, - input_2_udp_checksum=input_2_udp_checksum, - input_2_udp_payload_tdata=input_2_udp_payload_tdata, - input_2_udp_payload_tkeep=input_2_udp_payload_tkeep, - input_2_udp_payload_tvalid=input_2_udp_payload_tvalid, - input_2_udp_payload_tready=input_2_udp_payload_tready, - input_2_udp_payload_tlast=input_2_udp_payload_tlast, - input_2_udp_payload_tuser=input_2_udp_payload_tuser, - input_3_udp_hdr_valid=input_3_udp_hdr_valid, - input_3_udp_hdr_ready=input_3_udp_hdr_ready, - input_3_eth_dest_mac=input_3_eth_dest_mac, - input_3_eth_src_mac=input_3_eth_src_mac, - input_3_eth_type=input_3_eth_type, - input_3_ip_version=input_3_ip_version, - input_3_ip_ihl=input_3_ip_ihl, - input_3_ip_dscp=input_3_ip_dscp, - input_3_ip_ecn=input_3_ip_ecn, - input_3_ip_length=input_3_ip_length, - input_3_ip_identification=input_3_ip_identification, - input_3_ip_flags=input_3_ip_flags, - input_3_ip_fragment_offset=input_3_ip_fragment_offset, - input_3_ip_ttl=input_3_ip_ttl, - input_3_ip_protocol=input_3_ip_protocol, - input_3_ip_header_checksum=input_3_ip_header_checksum, - input_3_ip_source_ip=input_3_ip_source_ip, - input_3_ip_dest_ip=input_3_ip_dest_ip, - input_3_udp_source_port=input_3_udp_source_port, - input_3_udp_dest_port=input_3_udp_dest_port, - input_3_udp_length=input_3_udp_length, - input_3_udp_checksum=input_3_udp_checksum, - input_3_udp_payload_tdata=input_3_udp_payload_tdata, - input_3_udp_payload_tkeep=input_3_udp_payload_tkeep, - input_3_udp_payload_tvalid=input_3_udp_payload_tvalid, - input_3_udp_payload_tready=input_3_udp_payload_tready, - input_3_udp_payload_tlast=input_3_udp_payload_tlast, - input_3_udp_payload_tuser=input_3_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep=s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tid=s_udp_payload_axis_tid, + s_udp_payload_axis_tdest=s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tkeep=output_udp_payload_tkeep, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep=m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tid=m_udp_payload_axis_tid, + m_udp_payload_axis_tdest=m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser ) @always(delay(4)) @@ -585,7 +363,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_0.send(test_frame) + source_list[0].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -622,7 +400,7 @@ def bench(): test_frame.payload = bytearray(range(32)) test_frame.build() - source_1.send(test_frame) + source_list[1].send(test_frame) yield sink.wait() rx_frame = sink.recv() @@ -682,8 +460,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_0.send(test_frame1) - source_0.send(test_frame2) + source_list[0].send(test_frame1) + source_list[0].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -748,8 +526,8 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield sink.wait() rx_frame = sink.recv() @@ -814,23 +592,23 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: - source_0_pause.next = True - source_1_pause.next = True - source_2_pause.next = True - source_3_pause.next = True + while s_udp_payload_axis_tvalid: + source_pause_list[0].next = True + source_pause_list[1].next = True + source_pause_list[2].next = True + source_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - source_0_pause.next = False - source_1_pause.next = False - source_2_pause.next = False - source_3_pause.next = False + source_pause_list[0].next = False + source_pause_list[1].next = False + source_pause_list[2].next = False + source_pause_list[3].next = False yield clk.posedge yield sink.wait() @@ -896,12 +674,12 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) yield clk.posedge yield clk.posedge - while input_0_udp_payload_tvalid or input_1_udp_payload_tvalid or input_2_udp_payload_tvalid or input_3_udp_payload_tvalid: + while s_udp_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -972,17 +750,17 @@ def bench(): test_frame2.payload = bytearray(range(32)) test_frame2.build() - source_1.send(test_frame1) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) - source_2.send(test_frame2) + source_list[1].send(test_frame1) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) + source_list[2].send(test_frame2) yield clk.posedge - yield delay(150) + yield delay(120) yield clk.posedge - source_1.send(test_frame1) + source_list[1].send(test_frame1) yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_udp_arb_mux_64_4.v b/tb/test_udp_arb_mux_64_4.v index 88765489c..db33c2352 100644 --- a/tb/test_udp_arb_mux_64_4.v +++ b/tb/test_udp_arb_mux_64_4.v @@ -27,159 +27,93 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for udp_arb_mux_64_4 + * Testbench for udp_arb_mux */ module test_udp_arb_mux_64_4; +// Parameters +parameter S_COUNT = 4; +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter ARB_TYPE = "PRIORITY"; +parameter LSB_PRIORITY = "HIGH"; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_0_udp_hdr_valid = 0; -reg [47:0] input_0_eth_dest_mac = 0; -reg [47:0] input_0_eth_src_mac = 0; -reg [15:0] input_0_eth_type = 0; -reg [3:0] input_0_ip_version = 0; -reg [3:0] input_0_ip_ihl = 0; -reg [5:0] input_0_ip_dscp = 0; -reg [1:0] input_0_ip_ecn = 0; -reg [15:0] input_0_ip_length = 0; -reg [15:0] input_0_ip_identification = 0; -reg [2:0] input_0_ip_flags = 0; -reg [12:0] input_0_ip_fragment_offset = 0; -reg [7:0] input_0_ip_ttl = 0; -reg [7:0] input_0_ip_protocol = 0; -reg [15:0] input_0_ip_header_checksum = 0; -reg [31:0] input_0_ip_source_ip = 0; -reg [31:0] input_0_ip_dest_ip = 0; -reg [15:0] input_0_udp_source_port = 0; -reg [15:0] input_0_udp_dest_port = 0; -reg [15:0] input_0_udp_length = 0; -reg [15:0] input_0_udp_checksum = 0; -reg [63:0] input_0_udp_payload_tdata = 0; -reg [7:0] input_0_udp_payload_tkeep = 0; -reg input_0_udp_payload_tvalid = 0; -reg input_0_udp_payload_tlast = 0; -reg input_0_udp_payload_tuser = 0; -reg input_1_udp_hdr_valid = 0; -reg [47:0] input_1_eth_dest_mac = 0; -reg [47:0] input_1_eth_src_mac = 0; -reg [15:0] input_1_eth_type = 0; -reg [3:0] input_1_ip_version = 0; -reg [3:0] input_1_ip_ihl = 0; -reg [5:0] input_1_ip_dscp = 0; -reg [1:0] input_1_ip_ecn = 0; -reg [15:0] input_1_ip_length = 0; -reg [15:0] input_1_ip_identification = 0; -reg [2:0] input_1_ip_flags = 0; -reg [12:0] input_1_ip_fragment_offset = 0; -reg [7:0] input_1_ip_ttl = 0; -reg [7:0] input_1_ip_protocol = 0; -reg [15:0] input_1_ip_header_checksum = 0; -reg [31:0] input_1_ip_source_ip = 0; -reg [31:0] input_1_ip_dest_ip = 0; -reg [15:0] input_1_udp_source_port = 0; -reg [15:0] input_1_udp_dest_port = 0; -reg [15:0] input_1_udp_length = 0; -reg [15:0] input_1_udp_checksum = 0; -reg [63:0] input_1_udp_payload_tdata = 0; -reg [7:0] input_1_udp_payload_tkeep = 0; -reg input_1_udp_payload_tvalid = 0; -reg input_1_udp_payload_tlast = 0; -reg input_1_udp_payload_tuser = 0; -reg input_2_udp_hdr_valid = 0; -reg [47:0] input_2_eth_dest_mac = 0; -reg [47:0] input_2_eth_src_mac = 0; -reg [15:0] input_2_eth_type = 0; -reg [3:0] input_2_ip_version = 0; -reg [3:0] input_2_ip_ihl = 0; -reg [5:0] input_2_ip_dscp = 0; -reg [1:0] input_2_ip_ecn = 0; -reg [15:0] input_2_ip_length = 0; -reg [15:0] input_2_ip_identification = 0; -reg [2:0] input_2_ip_flags = 0; -reg [12:0] input_2_ip_fragment_offset = 0; -reg [7:0] input_2_ip_ttl = 0; -reg [7:0] input_2_ip_protocol = 0; -reg [15:0] input_2_ip_header_checksum = 0; -reg [31:0] input_2_ip_source_ip = 0; -reg [31:0] input_2_ip_dest_ip = 0; -reg [15:0] input_2_udp_source_port = 0; -reg [15:0] input_2_udp_dest_port = 0; -reg [15:0] input_2_udp_length = 0; -reg [15:0] input_2_udp_checksum = 0; -reg [63:0] input_2_udp_payload_tdata = 0; -reg [7:0] input_2_udp_payload_tkeep = 0; -reg input_2_udp_payload_tvalid = 0; -reg input_2_udp_payload_tlast = 0; -reg input_2_udp_payload_tuser = 0; -reg input_3_udp_hdr_valid = 0; -reg [47:0] input_3_eth_dest_mac = 0; -reg [47:0] input_3_eth_src_mac = 0; -reg [15:0] input_3_eth_type = 0; -reg [3:0] input_3_ip_version = 0; -reg [3:0] input_3_ip_ihl = 0; -reg [5:0] input_3_ip_dscp = 0; -reg [1:0] input_3_ip_ecn = 0; -reg [15:0] input_3_ip_length = 0; -reg [15:0] input_3_ip_identification = 0; -reg [2:0] input_3_ip_flags = 0; -reg [12:0] input_3_ip_fragment_offset = 0; -reg [7:0] input_3_ip_ttl = 0; -reg [7:0] input_3_ip_protocol = 0; -reg [15:0] input_3_ip_header_checksum = 0; -reg [31:0] input_3_ip_source_ip = 0; -reg [31:0] input_3_ip_dest_ip = 0; -reg [15:0] input_3_udp_source_port = 0; -reg [15:0] input_3_udp_dest_port = 0; -reg [15:0] input_3_udp_length = 0; -reg [15:0] input_3_udp_checksum = 0; -reg [63:0] input_3_udp_payload_tdata = 0; -reg [7:0] input_3_udp_payload_tkeep = 0; -reg input_3_udp_payload_tvalid = 0; -reg input_3_udp_payload_tlast = 0; -reg input_3_udp_payload_tuser = 0; +reg [S_COUNT-1:0] s_udp_hdr_valid = 0; +reg [S_COUNT*48-1:0] s_eth_dest_mac = 0; +reg [S_COUNT*48-1:0] s_eth_src_mac = 0; +reg [S_COUNT*16-1:0] s_eth_type = 0; +reg [S_COUNT*4-1:0] s_ip_version = 0; +reg [S_COUNT*4-1:0] s_ip_ihl = 0; +reg [S_COUNT*6-1:0] s_ip_dscp = 0; +reg [S_COUNT*2-1:0] s_ip_ecn = 0; +reg [S_COUNT*16-1:0] s_ip_length = 0; +reg [S_COUNT*16-1:0] s_ip_identification = 0; +reg [S_COUNT*3-1:0] s_ip_flags = 0; +reg [S_COUNT*13-1:0] s_ip_fragment_offset = 0; +reg [S_COUNT*8-1:0] s_ip_ttl = 0; +reg [S_COUNT*8-1:0] s_ip_protocol = 0; +reg [S_COUNT*16-1:0] s_ip_header_checksum = 0; +reg [S_COUNT*32-1:0] s_ip_source_ip = 0; +reg [S_COUNT*32-1:0] s_ip_dest_ip = 0; +reg [S_COUNT*16-1:0] s_udp_source_port = 0; +reg [S_COUNT*16-1:0] s_udp_dest_port = 0; +reg [S_COUNT*16-1:0] s_udp_length = 0; +reg [S_COUNT*16-1:0] s_udp_checksum = 0; +reg [S_COUNT*DATA_WIDTH-1:0] s_udp_payload_axis_tdata = 0; +reg [S_COUNT*KEEP_WIDTH-1:0] s_udp_payload_axis_tkeep = 0; +reg [S_COUNT-1:0] s_udp_payload_axis_tvalid = 0; +reg [S_COUNT-1:0] s_udp_payload_axis_tlast = 0; +reg [S_COUNT*ID_WIDTH-1:0] s_udp_payload_axis_tid = 0; +reg [S_COUNT*DEST_WIDTH-1:0] s_udp_payload_axis_tdest = 0; +reg [S_COUNT*USER_WIDTH-1:0] s_udp_payload_axis_tuser = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; // Outputs -wire input_0_udp_payload_tready; -wire input_0_udp_hdr_ready; -wire input_1_udp_payload_tready; -wire input_1_udp_hdr_ready; -wire input_2_udp_payload_tready; -wire input_2_udp_hdr_ready; -wire input_3_udp_payload_tready; -wire input_3_udp_hdr_ready; +wire [S_COUNT-1:0] s_udp_hdr_ready; +wire [S_COUNT-1:0] s_udp_payload_axis_tready; -wire output_udp_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [63:0] output_udp_payload_tdata; -wire [7:0] output_udp_payload_tkeep; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire m_udp_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [DATA_WIDTH-1:0] m_udp_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire [ID_WIDTH-1:0] m_udp_payload_axis_tid; +wire [DEST_WIDTH-1:0] m_udp_payload_axis_tdest; +wire [USER_WIDTH-1:0] m_udp_payload_axis_tuser; initial begin // myhdl integration @@ -187,148 +121,68 @@ initial begin clk, rst, current_test, - input_0_udp_hdr_valid, - input_0_eth_dest_mac, - input_0_eth_src_mac, - input_0_eth_type, - input_0_ip_version, - input_0_ip_ihl, - input_0_ip_dscp, - input_0_ip_ecn, - input_0_ip_length, - input_0_ip_identification, - input_0_ip_flags, - input_0_ip_fragment_offset, - input_0_ip_ttl, - input_0_ip_protocol, - input_0_ip_header_checksum, - input_0_ip_source_ip, - input_0_ip_dest_ip, - input_0_udp_source_port, - input_0_udp_dest_port, - input_0_udp_length, - input_0_udp_checksum, - input_0_udp_payload_tdata, - input_0_udp_payload_tkeep, - input_0_udp_payload_tvalid, - input_0_udp_payload_tlast, - input_0_udp_payload_tuser, - input_1_udp_hdr_valid, - input_1_eth_dest_mac, - input_1_eth_src_mac, - input_1_eth_type, - input_1_ip_version, - input_1_ip_ihl, - input_1_ip_dscp, - input_1_ip_ecn, - input_1_ip_length, - input_1_ip_identification, - input_1_ip_flags, - input_1_ip_fragment_offset, - input_1_ip_ttl, - input_1_ip_protocol, - input_1_ip_header_checksum, - input_1_ip_source_ip, - input_1_ip_dest_ip, - input_1_udp_source_port, - input_1_udp_dest_port, - input_1_udp_length, - input_1_udp_checksum, - input_1_udp_payload_tdata, - input_1_udp_payload_tkeep, - input_1_udp_payload_tvalid, - input_1_udp_payload_tlast, - input_1_udp_payload_tuser, - input_2_udp_hdr_valid, - input_2_eth_dest_mac, - input_2_eth_src_mac, - input_2_eth_type, - input_2_ip_version, - input_2_ip_ihl, - input_2_ip_dscp, - input_2_ip_ecn, - input_2_ip_length, - input_2_ip_identification, - input_2_ip_flags, - input_2_ip_fragment_offset, - input_2_ip_ttl, - input_2_ip_protocol, - input_2_ip_header_checksum, - input_2_ip_source_ip, - input_2_ip_dest_ip, - input_2_udp_source_port, - input_2_udp_dest_port, - input_2_udp_length, - input_2_udp_checksum, - input_2_udp_payload_tdata, - input_2_udp_payload_tkeep, - input_2_udp_payload_tvalid, - input_2_udp_payload_tlast, - input_2_udp_payload_tuser, - input_3_udp_hdr_valid, - input_3_eth_dest_mac, - input_3_eth_src_mac, - input_3_eth_type, - input_3_ip_version, - input_3_ip_ihl, - input_3_ip_dscp, - input_3_ip_ecn, - input_3_ip_length, - input_3_ip_identification, - input_3_ip_flags, - input_3_ip_fragment_offset, - input_3_ip_ttl, - input_3_ip_protocol, - input_3_ip_header_checksum, - input_3_ip_source_ip, - input_3_ip_dest_ip, - input_3_udp_source_port, - input_3_udp_dest_port, - input_3_udp_length, - input_3_udp_checksum, - input_3_udp_payload_tdata, - input_3_udp_payload_tkeep, - input_3_udp_payload_tvalid, - input_3_udp_payload_tlast, - input_3_udp_payload_tuser, - output_udp_hdr_ready, - output_udp_payload_tready + s_udp_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tid, + s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser, + m_udp_hdr_ready, + m_udp_payload_axis_tready ); $to_myhdl( - input_0_udp_hdr_ready, - input_0_udp_payload_tready, - input_1_udp_hdr_ready, - input_1_udp_payload_tready, - input_2_udp_hdr_ready, - input_2_udp_payload_tready, - input_3_udp_hdr_ready, - input_3_udp_payload_tready, - output_udp_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tkeep, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_udp_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tid, + m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser ); // dump file @@ -336,152 +190,85 @@ initial begin $dumpvars(0, test_udp_arb_mux_64_4); end -udp_arb_mux_64_4 +udp_arb_mux #( + .S_COUNT(S_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) +) UUT ( .clk(clk), .rst(rst), - // UDP frame inputs - .input_0_udp_hdr_valid(input_0_udp_hdr_valid), - .input_0_udp_hdr_ready(input_0_udp_hdr_ready), - .input_0_eth_dest_mac(input_0_eth_dest_mac), - .input_0_eth_src_mac(input_0_eth_src_mac), - .input_0_eth_type(input_0_eth_type), - .input_0_ip_version(input_0_ip_version), - .input_0_ip_ihl(input_0_ip_ihl), - .input_0_ip_dscp(input_0_ip_dscp), - .input_0_ip_ecn(input_0_ip_ecn), - .input_0_ip_length(input_0_ip_length), - .input_0_ip_identification(input_0_ip_identification), - .input_0_ip_flags(input_0_ip_flags), - .input_0_ip_fragment_offset(input_0_ip_fragment_offset), - .input_0_ip_ttl(input_0_ip_ttl), - .input_0_ip_protocol(input_0_ip_protocol), - .input_0_ip_header_checksum(input_0_ip_header_checksum), - .input_0_ip_source_ip(input_0_ip_source_ip), - .input_0_ip_dest_ip(input_0_ip_dest_ip), - .input_0_udp_source_port(input_0_udp_source_port), - .input_0_udp_dest_port(input_0_udp_dest_port), - .input_0_udp_length(input_0_udp_length), - .input_0_udp_checksum(input_0_udp_checksum), - .input_0_udp_payload_tdata(input_0_udp_payload_tdata), - .input_0_udp_payload_tkeep(input_0_udp_payload_tkeep), - .input_0_udp_payload_tvalid(input_0_udp_payload_tvalid), - .input_0_udp_payload_tready(input_0_udp_payload_tready), - .input_0_udp_payload_tlast(input_0_udp_payload_tlast), - .input_0_udp_payload_tuser(input_0_udp_payload_tuser), - .input_1_udp_hdr_valid(input_1_udp_hdr_valid), - .input_1_udp_hdr_ready(input_1_udp_hdr_ready), - .input_1_eth_dest_mac(input_1_eth_dest_mac), - .input_1_eth_src_mac(input_1_eth_src_mac), - .input_1_eth_type(input_1_eth_type), - .input_1_ip_version(input_1_ip_version), - .input_1_ip_ihl(input_1_ip_ihl), - .input_1_ip_dscp(input_1_ip_dscp), - .input_1_ip_ecn(input_1_ip_ecn), - .input_1_ip_length(input_1_ip_length), - .input_1_ip_identification(input_1_ip_identification), - .input_1_ip_flags(input_1_ip_flags), - .input_1_ip_fragment_offset(input_1_ip_fragment_offset), - .input_1_ip_ttl(input_1_ip_ttl), - .input_1_ip_protocol(input_1_ip_protocol), - .input_1_ip_header_checksum(input_1_ip_header_checksum), - .input_1_ip_source_ip(input_1_ip_source_ip), - .input_1_ip_dest_ip(input_1_ip_dest_ip), - .input_1_udp_source_port(input_1_udp_source_port), - .input_1_udp_dest_port(input_1_udp_dest_port), - .input_1_udp_length(input_1_udp_length), - .input_1_udp_checksum(input_1_udp_checksum), - .input_1_udp_payload_tdata(input_1_udp_payload_tdata), - .input_1_udp_payload_tkeep(input_1_udp_payload_tkeep), - .input_1_udp_payload_tvalid(input_1_udp_payload_tvalid), - .input_1_udp_payload_tready(input_1_udp_payload_tready), - .input_1_udp_payload_tlast(input_1_udp_payload_tlast), - .input_1_udp_payload_tuser(input_1_udp_payload_tuser), - .input_2_udp_hdr_valid(input_2_udp_hdr_valid), - .input_2_udp_hdr_ready(input_2_udp_hdr_ready), - .input_2_eth_dest_mac(input_2_eth_dest_mac), - .input_2_eth_src_mac(input_2_eth_src_mac), - .input_2_eth_type(input_2_eth_type), - .input_2_ip_version(input_2_ip_version), - .input_2_ip_ihl(input_2_ip_ihl), - .input_2_ip_dscp(input_2_ip_dscp), - .input_2_ip_ecn(input_2_ip_ecn), - .input_2_ip_length(input_2_ip_length), - .input_2_ip_identification(input_2_ip_identification), - .input_2_ip_flags(input_2_ip_flags), - .input_2_ip_fragment_offset(input_2_ip_fragment_offset), - .input_2_ip_ttl(input_2_ip_ttl), - .input_2_ip_protocol(input_2_ip_protocol), - .input_2_ip_header_checksum(input_2_ip_header_checksum), - .input_2_ip_source_ip(input_2_ip_source_ip), - .input_2_ip_dest_ip(input_2_ip_dest_ip), - .input_2_udp_source_port(input_2_udp_source_port), - .input_2_udp_dest_port(input_2_udp_dest_port), - .input_2_udp_length(input_2_udp_length), - .input_2_udp_checksum(input_2_udp_checksum), - .input_2_udp_payload_tdata(input_2_udp_payload_tdata), - .input_2_udp_payload_tkeep(input_2_udp_payload_tkeep), - .input_2_udp_payload_tvalid(input_2_udp_payload_tvalid), - .input_2_udp_payload_tready(input_2_udp_payload_tready), - .input_2_udp_payload_tlast(input_2_udp_payload_tlast), - .input_2_udp_payload_tuser(input_2_udp_payload_tuser), - .input_3_udp_hdr_valid(input_3_udp_hdr_valid), - .input_3_udp_hdr_ready(input_3_udp_hdr_ready), - .input_3_eth_dest_mac(input_3_eth_dest_mac), - .input_3_eth_src_mac(input_3_eth_src_mac), - .input_3_eth_type(input_3_eth_type), - .input_3_ip_version(input_3_ip_version), - .input_3_ip_ihl(input_3_ip_ihl), - .input_3_ip_dscp(input_3_ip_dscp), - .input_3_ip_ecn(input_3_ip_ecn), - .input_3_ip_length(input_3_ip_length), - .input_3_ip_identification(input_3_ip_identification), - .input_3_ip_flags(input_3_ip_flags), - .input_3_ip_fragment_offset(input_3_ip_fragment_offset), - .input_3_ip_ttl(input_3_ip_ttl), - .input_3_ip_protocol(input_3_ip_protocol), - .input_3_ip_header_checksum(input_3_ip_header_checksum), - .input_3_ip_source_ip(input_3_ip_source_ip), - .input_3_ip_dest_ip(input_3_ip_dest_ip), - .input_3_udp_source_port(input_3_udp_source_port), - .input_3_udp_dest_port(input_3_udp_dest_port), - .input_3_udp_length(input_3_udp_length), - .input_3_udp_checksum(input_3_udp_checksum), - .input_3_udp_payload_tdata(input_3_udp_payload_tdata), - .input_3_udp_payload_tkeep(input_3_udp_payload_tkeep), - .input_3_udp_payload_tvalid(input_3_udp_payload_tvalid), - .input_3_udp_payload_tready(input_3_udp_payload_tready), - .input_3_udp_payload_tlast(input_3_udp_payload_tlast), - .input_3_udp_payload_tuser(input_3_udp_payload_tuser), - // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tkeep(output_udp_payload_tkeep), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser) + // Ethernet frame inputs + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tid(s_udp_payload_axis_tid), + .s_udp_payload_axis_tdest(s_udp_payload_axis_tdest), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), + // Ethernet frame output + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tid(m_udp_payload_axis_tid), + .m_udp_payload_axis_tdest(m_udp_payload_axis_tdest), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser) ); endmodule From 470ab887d9a78ec9a2fcc18d29e2f803ec35b624 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 1 Nov 2018 00:59:14 -0700 Subject: [PATCH 463/617] Update mux instances --- rtl/ip_complete.v | 72 ++++++++++--------- rtl/ip_complete_64.v | 75 +++++++++---------- rtl/udp_complete.v | 140 +++++++++++++++++------------------- rtl/udp_complete_64.v | 143 +++++++++++++++++-------------------- tb/test_ip_complete.py | 3 +- tb/test_ip_complete_64.py | 3 +- tb/test_udp_complete.py | 6 +- tb/test_udp_complete_64.py | 6 +- 8 files changed, 214 insertions(+), 234 deletions(-) diff --git a/rtl/ip_complete.v b/rtl/ip_complete.v index c5ddc67bc..ed8db178c 100644 --- a/rtl/ip_complete.v +++ b/rtl/ip_complete.v @@ -253,44 +253,48 @@ assign input_eth_payload_tready = (input_select_ip_reg & ip_rx_eth_payload_tread /* * Output arbiter */ -eth_arb_mux_2 -eth_arb_mux_2_inst ( +eth_arb_mux #( + .S_COUNT(2), + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .ARB_TYPE("PRIORITY"), + .LSB_PRIORITY("HIGH") +) +eth_arb_mux_inst ( .clk(clk), .rst(rst), // Ethernet frame inputs - // ARP input (highest priority) - .input_0_eth_hdr_valid(arp_tx_eth_hdr_valid), - .input_0_eth_hdr_ready(arp_tx_eth_hdr_ready), - .input_0_eth_dest_mac(arp_tx_eth_dest_mac), - .input_0_eth_src_mac(arp_tx_eth_src_mac), - .input_0_eth_type(arp_tx_eth_type), - .input_0_eth_payload_tdata(arp_tx_eth_payload_tdata), - .input_0_eth_payload_tvalid(arp_tx_eth_payload_tvalid), - .input_0_eth_payload_tready(arp_tx_eth_payload_tready), - .input_0_eth_payload_tlast(arp_tx_eth_payload_tlast), - .input_0_eth_payload_tuser(arp_tx_eth_payload_tuser), - // IP input (lowest priority) - .input_1_eth_hdr_valid(ip_tx_eth_hdr_valid), - .input_1_eth_hdr_ready(ip_tx_eth_hdr_ready), - .input_1_eth_dest_mac(ip_tx_eth_dest_mac), - .input_1_eth_src_mac(ip_tx_eth_src_mac), - .input_1_eth_type(ip_tx_eth_type), - .input_1_eth_payload_tdata(ip_tx_eth_payload_tdata), - .input_1_eth_payload_tvalid(ip_tx_eth_payload_tvalid), - .input_1_eth_payload_tready(ip_tx_eth_payload_tready), - .input_1_eth_payload_tlast(ip_tx_eth_payload_tlast), - .input_1_eth_payload_tuser(ip_tx_eth_payload_tuser), + .s_eth_hdr_valid({ip_tx_eth_hdr_valid, arp_tx_eth_hdr_valid}), + .s_eth_hdr_ready({ip_tx_eth_hdr_ready, arp_tx_eth_hdr_ready}), + .s_eth_dest_mac({ip_tx_eth_dest_mac, arp_tx_eth_dest_mac}), + .s_eth_src_mac({ip_tx_eth_src_mac, arp_tx_eth_src_mac}), + .s_eth_type({ip_tx_eth_type, arp_tx_eth_type}), + .s_eth_payload_axis_tdata({ip_tx_eth_payload_tdata, arp_tx_eth_payload_tdata}), + .s_eth_payload_axis_tkeep(0), + .s_eth_payload_axis_tvalid({ip_tx_eth_payload_tvalid, arp_tx_eth_payload_tvalid}), + .s_eth_payload_axis_tready({ip_tx_eth_payload_tready, arp_tx_eth_payload_tready}), + .s_eth_payload_axis_tlast({ip_tx_eth_payload_tlast, arp_tx_eth_payload_tlast}), + .s_eth_payload_axis_tid(0), + .s_eth_payload_axis_tdest(0), + .s_eth_payload_axis_tuser({ip_tx_eth_payload_tuser, arp_tx_eth_payload_tuser}), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser) + .m_eth_hdr_valid(output_eth_hdr_valid), + .m_eth_hdr_ready(output_eth_hdr_ready), + .m_eth_dest_mac(output_eth_dest_mac), + .m_eth_src_mac(output_eth_src_mac), + .m_eth_type(output_eth_type), + .m_eth_payload_axis_tdata(output_eth_payload_tdata), + .m_eth_payload_axis_tkeep(), + .m_eth_payload_axis_tvalid(output_eth_payload_tvalid), + .m_eth_payload_axis_tready(output_eth_payload_tready), + .m_eth_payload_axis_tlast(output_eth_payload_tlast), + .m_eth_payload_axis_tid(), + .m_eth_payload_axis_tdest(), + .m_eth_payload_axis_tuser(output_eth_payload_tuser) ); /* diff --git a/rtl/ip_complete_64.v b/rtl/ip_complete_64.v index 14271670e..7d9949892 100644 --- a/rtl/ip_complete_64.v +++ b/rtl/ip_complete_64.v @@ -263,47 +263,48 @@ assign input_eth_payload_tready = (input_select_ip_reg & ip_rx_eth_payload_tread /* * Output arbiter */ -eth_arb_mux_64_2 -eth_arb_mux_2_inst ( +eth_arb_mux #( + .S_COUNT(2), + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .ARB_TYPE("PRIORITY"), + .LSB_PRIORITY("HIGH") +) +eth_arb_mux_inst ( .clk(clk), .rst(rst), // Ethernet frame inputs - // ARP input (highest priority) - .input_0_eth_hdr_valid(arp_tx_eth_hdr_valid), - .input_0_eth_hdr_ready(arp_tx_eth_hdr_ready), - .input_0_eth_dest_mac(arp_tx_eth_dest_mac), - .input_0_eth_src_mac(arp_tx_eth_src_mac), - .input_0_eth_type(arp_tx_eth_type), - .input_0_eth_payload_tdata(arp_tx_eth_payload_tdata), - .input_0_eth_payload_tkeep(arp_tx_eth_payload_tkeep), - .input_0_eth_payload_tvalid(arp_tx_eth_payload_tvalid), - .input_0_eth_payload_tready(arp_tx_eth_payload_tready), - .input_0_eth_payload_tlast(arp_tx_eth_payload_tlast), - .input_0_eth_payload_tuser(arp_tx_eth_payload_tuser), - // IP input (lowest priority) - .input_1_eth_hdr_valid(ip_tx_eth_hdr_valid), - .input_1_eth_hdr_ready(ip_tx_eth_hdr_ready), - .input_1_eth_dest_mac(ip_tx_eth_dest_mac), - .input_1_eth_src_mac(ip_tx_eth_src_mac), - .input_1_eth_type(ip_tx_eth_type), - .input_1_eth_payload_tdata(ip_tx_eth_payload_tdata), - .input_1_eth_payload_tkeep(ip_tx_eth_payload_tkeep), - .input_1_eth_payload_tvalid(ip_tx_eth_payload_tvalid), - .input_1_eth_payload_tready(ip_tx_eth_payload_tready), - .input_1_eth_payload_tlast(ip_tx_eth_payload_tlast), - .input_1_eth_payload_tuser(ip_tx_eth_payload_tuser), + .s_eth_hdr_valid({ip_tx_eth_hdr_valid, arp_tx_eth_hdr_valid}), + .s_eth_hdr_ready({ip_tx_eth_hdr_ready, arp_tx_eth_hdr_ready}), + .s_eth_dest_mac({ip_tx_eth_dest_mac, arp_tx_eth_dest_mac}), + .s_eth_src_mac({ip_tx_eth_src_mac, arp_tx_eth_src_mac}), + .s_eth_type({ip_tx_eth_type, arp_tx_eth_type}), + .s_eth_payload_axis_tdata({ip_tx_eth_payload_tdata, arp_tx_eth_payload_tdata}), + .s_eth_payload_axis_tkeep({ip_tx_eth_payload_tkeep, arp_tx_eth_payload_tkeep}), + .s_eth_payload_axis_tvalid({ip_tx_eth_payload_tvalid, arp_tx_eth_payload_tvalid}), + .s_eth_payload_axis_tready({ip_tx_eth_payload_tready, arp_tx_eth_payload_tready}), + .s_eth_payload_axis_tlast({ip_tx_eth_payload_tlast, arp_tx_eth_payload_tlast}), + .s_eth_payload_axis_tid(0), + .s_eth_payload_axis_tdest(0), + .s_eth_payload_axis_tuser({ip_tx_eth_payload_tuser, arp_tx_eth_payload_tuser}), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser) + .m_eth_hdr_valid(output_eth_hdr_valid), + .m_eth_hdr_ready(output_eth_hdr_ready), + .m_eth_dest_mac(output_eth_dest_mac), + .m_eth_src_mac(output_eth_src_mac), + .m_eth_type(output_eth_type), + .m_eth_payload_axis_tdata(output_eth_payload_tdata), + .m_eth_payload_axis_tkeep(output_eth_payload_tkeep), + .m_eth_payload_axis_tvalid(output_eth_payload_tvalid), + .m_eth_payload_axis_tready(output_eth_payload_tready), + .m_eth_payload_axis_tlast(output_eth_payload_tlast), + .m_eth_payload_axis_tid(), + .m_eth_payload_axis_tdest(), + .m_eth_payload_axis_tuser(output_eth_payload_tuser) ); /* diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v index 7593b3acd..497a4a5d3 100644 --- a/rtl/udp_complete.v +++ b/rtl/udp_complete.v @@ -353,82 +353,74 @@ assign ip_rx_ip_payload_tready = (input_select_udp_reg & udp_rx_ip_payload_tread /* * Output arbiter */ -ip_arb_mux_2 -ip_arb_mux_2_inst ( +ip_arb_mux #( + .S_COUNT(2), + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .ARB_TYPE("PRIORITY"), + .LSB_PRIORITY("HIGH") +) +ip_arb_mux_inst ( .clk(clk), .rst(rst), - // IP frame input from UDP module - .input_0_ip_hdr_valid(udp_tx_ip_hdr_valid), - .input_0_ip_hdr_ready(udp_tx_ip_hdr_ready), - .input_0_eth_dest_mac(48'd0), - .input_0_eth_src_mac(48'd0), - .input_0_eth_type(16'd0), - .input_0_ip_version(4'd0), - .input_0_ip_ihl(4'd0), - .input_0_ip_dscp(udp_tx_ip_dscp), - .input_0_ip_ecn(udp_tx_ip_ecn), - .input_0_ip_length(udp_tx_ip_length), - .input_0_ip_identification(16'd0), - .input_0_ip_flags(3'd0), - .input_0_ip_fragment_offset(13'd0), - .input_0_ip_ttl(udp_tx_ip_ttl), - .input_0_ip_protocol(udp_tx_ip_protocol), - .input_0_ip_header_checksum(16'd0), - .input_0_ip_source_ip(udp_tx_ip_source_ip), - .input_0_ip_dest_ip(udp_tx_ip_dest_ip), - .input_0_ip_payload_tdata(udp_tx_ip_payload_tdata), - .input_0_ip_payload_tvalid(udp_tx_ip_payload_tvalid), - .input_0_ip_payload_tready(udp_tx_ip_payload_tready), - .input_0_ip_payload_tlast(udp_tx_ip_payload_tlast), - .input_0_ip_payload_tuser(udp_tx_ip_payload_tuser), - // External IP frame input - .input_1_ip_hdr_valid(input_ip_hdr_valid), - .input_1_ip_hdr_ready(input_ip_hdr_ready), - .input_1_eth_dest_mac(48'd0), - .input_1_eth_src_mac(48'd0), - .input_1_eth_type(16'd0), - .input_1_ip_version(4'd0), - .input_1_ip_ihl(4'd0), - .input_1_ip_dscp(input_ip_dscp), - .input_1_ip_ecn(input_ip_ecn), - .input_1_ip_length(input_ip_length), - .input_1_ip_identification(16'd0), - .input_1_ip_flags(3'd0), - .input_1_ip_fragment_offset(13'd0), - .input_1_ip_ttl(input_ip_ttl), - .input_1_ip_protocol(input_ip_protocol), - .input_1_ip_header_checksum(16'd0), - .input_1_ip_source_ip(input_ip_source_ip), - .input_1_ip_dest_ip(input_ip_dest_ip), - .input_1_ip_payload_tdata(input_ip_payload_tdata), - .input_1_ip_payload_tvalid(input_ip_payload_tvalid), - .input_1_ip_payload_tready(input_ip_payload_tready), - .input_1_ip_payload_tlast(input_ip_payload_tlast), - .input_1_ip_payload_tuser(input_ip_payload_tuser), - // IP frame output to IP stack - .output_ip_hdr_valid(ip_tx_ip_hdr_valid), - .output_ip_hdr_ready(ip_tx_ip_hdr_ready), - .output_eth_dest_mac(), - .output_eth_src_mac(), - .output_eth_type(), - .output_ip_version(), - .output_ip_ihl(), - .output_ip_dscp(ip_tx_ip_dscp), - .output_ip_ecn(ip_tx_ip_ecn), - .output_ip_length(ip_tx_ip_length), - .output_ip_identification(), - .output_ip_flags(), - .output_ip_fragment_offset(), - .output_ip_ttl(ip_tx_ip_ttl), - .output_ip_protocol(ip_tx_ip_protocol), - .output_ip_header_checksum(), - .output_ip_source_ip(ip_tx_ip_source_ip), - .output_ip_dest_ip(ip_tx_ip_dest_ip), - .output_ip_payload_tdata(ip_tx_ip_payload_tdata), - .output_ip_payload_tvalid(ip_tx_ip_payload_tvalid), - .output_ip_payload_tready(ip_tx_ip_payload_tready), - .output_ip_payload_tlast(ip_tx_ip_payload_tlast), - .output_ip_payload_tuser(ip_tx_ip_payload_tuser) + // IP frame inputs + .s_ip_hdr_valid({input_ip_hdr_valid, udp_tx_ip_hdr_valid}), + .s_ip_hdr_ready({input_ip_hdr_ready, udp_tx_ip_hdr_ready}), + .s_eth_dest_mac(0), + .s_eth_src_mac(0), + .s_eth_type(0), + .s_ip_version(0), + .s_ip_ihl(0), + .s_ip_dscp({input_ip_dscp, udp_tx_ip_dscp}), + .s_ip_ecn({input_ip_ecn, udp_tx_ip_ecn}), + .s_ip_length({input_ip_length, udp_tx_ip_length}), + .s_ip_identification(0), + .s_ip_flags(0), + .s_ip_fragment_offset(0), + .s_ip_ttl({input_ip_ttl, udp_tx_ip_ttl}), + .s_ip_protocol({input_ip_protocol, udp_tx_ip_protocol}), + .s_ip_header_checksum(0), + .s_ip_source_ip({input_ip_source_ip, udp_tx_ip_source_ip}), + .s_ip_dest_ip({input_ip_dest_ip, udp_tx_ip_dest_ip}), + .s_ip_payload_axis_tdata({input_ip_payload_tdata, udp_tx_ip_payload_tdata}), + .s_ip_payload_axis_tkeep(0), + .s_ip_payload_axis_tvalid({input_ip_payload_tvalid, udp_tx_ip_payload_tvalid}), + .s_ip_payload_axis_tready({input_ip_payload_tready, udp_tx_ip_payload_tready}), + .s_ip_payload_axis_tlast({input_ip_payload_tlast, udp_tx_ip_payload_tlast}), + .s_ip_payload_axis_tid(0), + .s_ip_payload_axis_tdest(0), + .s_ip_payload_axis_tuser({input_ip_payload_tuser, udp_tx_ip_payload_tuser}), + // IP frame output + .m_ip_hdr_valid(ip_tx_ip_hdr_valid), + .m_ip_hdr_ready(ip_tx_ip_hdr_ready), + .m_eth_dest_mac(), + .m_eth_src_mac(), + .m_eth_type(), + .m_ip_version(), + .m_ip_ihl(), + .m_ip_dscp(ip_tx_ip_dscp), + .m_ip_ecn(ip_tx_ip_ecn), + .m_ip_length(ip_tx_ip_length), + .m_ip_identification(), + .m_ip_flags(), + .m_ip_fragment_offset(), + .m_ip_ttl(ip_tx_ip_ttl), + .m_ip_protocol(ip_tx_ip_protocol), + .m_ip_header_checksum(), + .m_ip_source_ip(ip_tx_ip_source_ip), + .m_ip_dest_ip(ip_tx_ip_dest_ip), + .m_ip_payload_axis_tdata(ip_tx_ip_payload_tdata), + .m_ip_payload_axis_tkeep(), + .m_ip_payload_axis_tvalid(ip_tx_ip_payload_tvalid), + .m_ip_payload_axis_tready(ip_tx_ip_payload_tready), + .m_ip_payload_axis_tlast(ip_tx_ip_payload_tlast), + .m_ip_payload_axis_tid(), + .m_ip_payload_axis_tdest(), + .m_ip_payload_axis_tuser(ip_tx_ip_payload_tuser) ); /* diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v index 041519876..8cbd26cc0 100644 --- a/rtl/udp_complete_64.v +++ b/rtl/udp_complete_64.v @@ -365,85 +365,74 @@ assign ip_rx_ip_payload_tready = (input_select_udp_reg & udp_rx_ip_payload_tread /* * Output arbiter */ -ip_arb_mux_64_2 -ip_arb_mux_64_2_inst ( +ip_arb_mux #( + .S_COUNT(2), + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .ARB_TYPE("PRIORITY"), + .LSB_PRIORITY("HIGH") +) +ip_arb_mux_inst ( .clk(clk), .rst(rst), - // IP frame input from UDP module - .input_0_ip_hdr_valid(udp_tx_ip_hdr_valid), - .input_0_ip_hdr_ready(udp_tx_ip_hdr_ready), - .input_0_eth_dest_mac(48'd0), - .input_0_eth_src_mac(48'd0), - .input_0_eth_type(16'd0), - .input_0_ip_version(4'd0), - .input_0_ip_ihl(4'd0), - .input_0_ip_dscp(udp_tx_ip_dscp), - .input_0_ip_ecn(udp_tx_ip_ecn), - .input_0_ip_length(udp_tx_ip_length), - .input_0_ip_identification(16'd0), - .input_0_ip_flags(3'd0), - .input_0_ip_fragment_offset(13'd0), - .input_0_ip_ttl(udp_tx_ip_ttl), - .input_0_ip_protocol(udp_tx_ip_protocol), - .input_0_ip_header_checksum(16'd0), - .input_0_ip_source_ip(udp_tx_ip_source_ip), - .input_0_ip_dest_ip(udp_tx_ip_dest_ip), - .input_0_ip_payload_tdata(udp_tx_ip_payload_tdata), - .input_0_ip_payload_tkeep(udp_tx_ip_payload_tkeep), - .input_0_ip_payload_tvalid(udp_tx_ip_payload_tvalid), - .input_0_ip_payload_tready(udp_tx_ip_payload_tready), - .input_0_ip_payload_tlast(udp_tx_ip_payload_tlast), - .input_0_ip_payload_tuser(udp_tx_ip_payload_tuser), - // External IP frame input - .input_1_ip_hdr_valid(input_ip_hdr_valid), - .input_1_ip_hdr_ready(input_ip_hdr_ready), - .input_1_eth_dest_mac(48'd0), - .input_1_eth_src_mac(48'd0), - .input_1_eth_type(16'd0), - .input_1_ip_version(4'd0), - .input_1_ip_ihl(4'd0), - .input_1_ip_dscp(input_ip_dscp), - .input_1_ip_ecn(input_ip_ecn), - .input_1_ip_length(input_ip_length), - .input_1_ip_identification(16'd0), - .input_1_ip_flags(3'd0), - .input_1_ip_fragment_offset(13'd0), - .input_1_ip_ttl(input_ip_ttl), - .input_1_ip_protocol(input_ip_protocol), - .input_1_ip_header_checksum(16'd0), - .input_1_ip_source_ip(input_ip_source_ip), - .input_1_ip_dest_ip(input_ip_dest_ip), - .input_1_ip_payload_tdata(input_ip_payload_tdata), - .input_1_ip_payload_tkeep(input_ip_payload_tkeep), - .input_1_ip_payload_tvalid(input_ip_payload_tvalid), - .input_1_ip_payload_tready(input_ip_payload_tready), - .input_1_ip_payload_tlast(input_ip_payload_tlast), - .input_1_ip_payload_tuser(input_ip_payload_tuser), - // IP frame output to IP stack - .output_ip_hdr_valid(ip_tx_ip_hdr_valid), - .output_ip_hdr_ready(ip_tx_ip_hdr_ready), - .output_eth_dest_mac(), - .output_eth_src_mac(), - .output_eth_type(), - .output_ip_version(), - .output_ip_ihl(), - .output_ip_dscp(ip_tx_ip_dscp), - .output_ip_ecn(ip_tx_ip_ecn), - .output_ip_length(ip_tx_ip_length), - .output_ip_identification(), - .output_ip_flags(), - .output_ip_fragment_offset(), - .output_ip_ttl(ip_tx_ip_ttl), - .output_ip_protocol(ip_tx_ip_protocol), - .output_ip_header_checksum(), - .output_ip_source_ip(ip_tx_ip_source_ip), - .output_ip_dest_ip(ip_tx_ip_dest_ip), - .output_ip_payload_tdata(ip_tx_ip_payload_tdata), - .output_ip_payload_tkeep(ip_tx_ip_payload_tkeep), - .output_ip_payload_tvalid(ip_tx_ip_payload_tvalid), - .output_ip_payload_tready(ip_tx_ip_payload_tready), - .output_ip_payload_tlast(ip_tx_ip_payload_tlast), - .output_ip_payload_tuser(ip_tx_ip_payload_tuser) + // IP frame inputs + .s_ip_hdr_valid({input_ip_hdr_valid, udp_tx_ip_hdr_valid}), + .s_ip_hdr_ready({input_ip_hdr_ready, udp_tx_ip_hdr_ready}), + .s_eth_dest_mac(0), + .s_eth_src_mac(0), + .s_eth_type(0), + .s_ip_version(0), + .s_ip_ihl(0), + .s_ip_dscp({input_ip_dscp, udp_tx_ip_dscp}), + .s_ip_ecn({input_ip_ecn, udp_tx_ip_ecn}), + .s_ip_length({input_ip_length, udp_tx_ip_length}), + .s_ip_identification(0), + .s_ip_flags(0), + .s_ip_fragment_offset(0), + .s_ip_ttl({input_ip_ttl, udp_tx_ip_ttl}), + .s_ip_protocol({input_ip_protocol, udp_tx_ip_protocol}), + .s_ip_header_checksum(0), + .s_ip_source_ip({input_ip_source_ip, udp_tx_ip_source_ip}), + .s_ip_dest_ip({input_ip_dest_ip, udp_tx_ip_dest_ip}), + .s_ip_payload_axis_tdata({input_ip_payload_tdata, udp_tx_ip_payload_tdata}), + .s_ip_payload_axis_tkeep({input_ip_payload_tkeep, udp_tx_ip_payload_tkeep}), + .s_ip_payload_axis_tvalid({input_ip_payload_tvalid, udp_tx_ip_payload_tvalid}), + .s_ip_payload_axis_tready({input_ip_payload_tready, udp_tx_ip_payload_tready}), + .s_ip_payload_axis_tlast({input_ip_payload_tlast, udp_tx_ip_payload_tlast}), + .s_ip_payload_axis_tid(0), + .s_ip_payload_axis_tdest(0), + .s_ip_payload_axis_tuser({input_ip_payload_tuser, udp_tx_ip_payload_tuser}), + // IP frame output + .m_ip_hdr_valid(ip_tx_ip_hdr_valid), + .m_ip_hdr_ready(ip_tx_ip_hdr_ready), + .m_eth_dest_mac(), + .m_eth_src_mac(), + .m_eth_type(), + .m_ip_version(), + .m_ip_ihl(), + .m_ip_dscp(ip_tx_ip_dscp), + .m_ip_ecn(ip_tx_ip_ecn), + .m_ip_length(ip_tx_ip_length), + .m_ip_identification(), + .m_ip_flags(), + .m_ip_fragment_offset(), + .m_ip_ttl(ip_tx_ip_ttl), + .m_ip_protocol(ip_tx_ip_protocol), + .m_ip_header_checksum(), + .m_ip_source_ip(ip_tx_ip_source_ip), + .m_ip_dest_ip(ip_tx_ip_dest_ip), + .m_ip_payload_axis_tdata(ip_tx_ip_payload_tdata), + .m_ip_payload_axis_tkeep(ip_tx_ip_payload_tkeep), + .m_ip_payload_axis_tvalid(ip_tx_ip_payload_tvalid), + .m_ip_payload_axis_tready(ip_tx_ip_payload_tready), + .m_ip_payload_axis_tlast(ip_tx_ip_payload_tlast), + .m_ip_payload_axis_tid(), + .m_ip_payload_axis_tdest(), + .m_ip_payload_axis_tuser(ip_tx_ip_payload_tuser) ); /* diff --git a/tb/test_ip_complete.py b/tb/test_ip_complete.py index 020cefdda..bf6ec2924 100755 --- a/tb/test_ip_complete.py +++ b/tb/test_ip_complete.py @@ -43,8 +43,7 @@ srcs.append("../rtl/arp.v") srcs.append("../rtl/arp_cache.v") srcs.append("../rtl/arp_eth_rx.v") srcs.append("../rtl/arp_eth_tx.v") -srcs.append("../rtl/eth_arb_mux_2.v") -srcs.append("../rtl/eth_mux_2.v") +srcs.append("../rtl/eth_arb_mux.v") srcs.append("../rtl/lfsr.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") diff --git a/tb/test_ip_complete_64.py b/tb/test_ip_complete_64.py index 9749f02af..6e32525d2 100755 --- a/tb/test_ip_complete_64.py +++ b/tb/test_ip_complete_64.py @@ -43,8 +43,7 @@ srcs.append("../rtl/arp_64.v") srcs.append("../rtl/arp_cache.v") srcs.append("../rtl/arp_eth_rx_64.v") srcs.append("../rtl/arp_eth_tx_64.v") -srcs.append("../rtl/eth_arb_mux_64_2.v") -srcs.append("../rtl/eth_mux_64_2.v") +srcs.append("../rtl/eth_arb_mux.v") srcs.append("../rtl/lfsr.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py index fa99ce034..734bcf53e 100755 --- a/tb/test_udp_complete.py +++ b/tb/test_udp_complete.py @@ -45,14 +45,12 @@ srcs.append("../rtl/ip_complete.v") srcs.append("../rtl/ip.v") srcs.append("../rtl/ip_eth_rx.v") srcs.append("../rtl/ip_eth_tx.v") -srcs.append("../rtl/ip_arb_mux_2.v") -srcs.append("../rtl/ip_mux_2.v") +srcs.append("../rtl/ip_arb_mux.v") srcs.append("../rtl/arp.v") srcs.append("../rtl/arp_cache.v") srcs.append("../rtl/arp_eth_rx.v") srcs.append("../rtl/arp_eth_tx.v") -srcs.append("../rtl/eth_arb_mux_2.v") -srcs.append("../rtl/eth_mux_2.v") +srcs.append("../rtl/eth_arb_mux.v") srcs.append("../rtl/lfsr.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index 3ee61fd6f..a78366d8f 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -45,14 +45,12 @@ srcs.append("../rtl/ip_complete_64.v") srcs.append("../rtl/ip_64.v") srcs.append("../rtl/ip_eth_rx_64.v") srcs.append("../rtl/ip_eth_tx_64.v") -srcs.append("../rtl/ip_arb_mux_64_2.v") -srcs.append("../rtl/ip_mux_64_2.v") +srcs.append("../rtl/ip_arb_mux.v") srcs.append("../rtl/arp_64.v") srcs.append("../rtl/arp_cache.v") srcs.append("../rtl/arp_eth_rx_64.v") srcs.append("../rtl/arp_eth_tx_64.v") -srcs.append("../rtl/eth_arb_mux_64_2.v") -srcs.append("../rtl/eth_mux_64_2.v") +srcs.append("../rtl/eth_arb_mux.v") srcs.append("../rtl/lfsr.v") srcs.append("../lib/axis/rtl/arbiter.v") srcs.append("../lib/axis/rtl/priority_encoder.v") From 18c4214edb23fecd3da57373e00073a2f7571619 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 2 Nov 2018 00:23:31 -0700 Subject: [PATCH 464/617] Convert generated eth_demux to verilog parametrized module --- rtl/eth_demux.py | 343 ------------------------------ rtl/eth_demux.v | 305 ++++++++++++++++++++++++++ rtl/eth_demux_4.v | 377 -------------------------------- rtl/eth_demux_64.py | 353 ------------------------------ rtl/eth_demux_64_4.v | 393 ---------------------------------- tb/test_eth_demux_4.py | 421 ++++++++++++++++++------------------ tb/test_eth_demux_4.v | 258 +++++++++------------- tb/test_eth_demux_64_4.py | 436 ++++++++++++++++++-------------------- tb/test_eth_demux_64_4.v | 273 +++++++++--------------- 9 files changed, 919 insertions(+), 2240 deletions(-) delete mode 100755 rtl/eth_demux.py create mode 100644 rtl/eth_demux.v delete mode 100644 rtl/eth_demux_4.v delete mode 100755 rtl/eth_demux_64.py delete mode 100644 rtl/eth_demux_64_4.v diff --git a/rtl/eth_demux.py b/rtl/eth_demux.py deleted file mode 100755 index 047410925..000000000 --- a/rtl/eth_demux.py +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/env python -""" -Generates an Ethernet demux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "eth_demux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port Ethernet demux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet {{n}} port demultiplexer - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * Ethernet frame input - */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [7:0] input_eth_payload_tdata, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, - - /* - * Ethernet frame outputs - */ -{%- for p in ports %} - output wire output_{{p}}_eth_hdr_valid, - input wire output_{{p}}_eth_hdr_ready, - output wire [47:0] output_{{p}}_eth_dest_mac, - output wire [47:0] output_{{p}}_eth_src_mac, - output wire [15:0] output_{{p}}_eth_type, - output wire [7:0] output_{{p}}_eth_payload_tdata, - output wire output_{{p}}_eth_payload_tvalid, - input wire output_{{p}}_eth_payload_tready, - output wire output_{{p}}_eth_payload_tlast, - output wire output_{{p}}_eth_payload_tuser, -{% endfor %} - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; -{% for p in ports %} -reg output_{{p}}_eth_hdr_valid_reg = 1'b0, output_{{p}}_eth_hdr_valid_next; -{%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; - -// internal datapath -reg [7:0] output_eth_payload_tdata_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; - -assign input_eth_hdr_ready = input_eth_hdr_ready_reg; -assign input_eth_payload_tready = input_eth_payload_tready_reg; -{% for p in ports %} -assign output_{{p}}_eth_hdr_valid = output_{{p}}_eth_hdr_valid_reg; -assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; -assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; -assign output_{{p}}_eth_type = output_eth_type_reg; -{% endfor %} -// mux for output control signals -reg current_output_eth_hdr_valid; -reg current_output_eth_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_output_eth_hdr_valid = output_{{p}}_eth_hdr_valid; - current_output_eth_hdr_ready = output_{{p}}_eth_hdr_ready; - current_output_tvalid = output_{{p}}_eth_payload_tvalid; - current_output_tready = output_{{p}}_eth_payload_tready; - end -{%- endfor %} - default: begin - current_output_eth_hdr_valid = 1'b0; - current_output_eth_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; - input_eth_payload_tready_next = 1'b0; - -{%- for p in ports %} - output_{{p}}_eth_hdr_valid_next = output_{{p}}_eth_hdr_valid_reg & ~output_{{p}}_eth_hdr_ready; -{%- endfor %} - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - - if (input_eth_payload_tvalid & input_eth_payload_tready) begin - // end of frame detection - if (input_eth_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_eth_hdr_ready_next = 1'b1; - - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_eth_hdr_valid_next = 1'b1; -{%- endfor %} - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - end - - input_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - - output_eth_payload_tdata_int = input_eth_payload_tdata; - output_eth_payload_tvalid_int = input_eth_payload_tvalid & input_eth_payload_tready; - output_eth_payload_tlast_int = input_eth_payload_tlast; - output_eth_payload_tuser_int = input_eth_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; - input_eth_hdr_ready_reg <= 1'b0; - input_eth_payload_tready_reg <= 1'b0; -{%- for p in ports %} - output_{{p}}_eth_hdr_valid_reg <= 1'b0; -{%- endfor %} - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; - input_eth_payload_tready_reg <= input_eth_payload_tready_next; -{%- for p in ports %} - output_{{p}}_eth_hdr_valid_reg <= output_{{p}}_eth_hdr_valid_next; -{%- endfor %} - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; -end - -// output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 8'd0; -{%- for p in ports %} -reg output_{{p}}_eth_payload_tvalid_reg = 1'b0, output_{{p}}_eth_payload_tvalid_next; -{%- endfor %} -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; - -reg [7:0] temp_eth_payload_tdata_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; -{% for p in ports %} -assign output_{{p}}_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_{{p}}_eth_payload_tvalid = output_{{p}}_eth_payload_tvalid_reg; -assign output_{{p}}_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_{{p}}_eth_payload_tuser = output_eth_payload_tuser_reg; -{% endfor %} -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & (~current_output_tvalid | ~output_eth_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source -{%- for p in ports %} - output_{{p}}_eth_payload_tvalid_next = output_{{p}}_eth_payload_tvalid_reg; -{%- endfor %} - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; - - if (output_eth_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output -{%- for p in ports %} - output_{{p}}_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready -{%- for p in ports %} - output_{{p}}_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin -{%- for p in ports %} - output_{{p}}_eth_payload_tvalid_reg <= 1'b0; -{%- endfor %} - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; - end else begin -{%- for p in ports %} - output_{{p}}_eth_payload_tvalid_reg <= output_{{p}}_eth_payload_tvalid_next; -{%- endfor %} - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/eth_demux.v b/rtl/eth_demux.v new file mode 100644 index 000000000..0433b9ef6 --- /dev/null +++ b/rtl/eth_demux.v @@ -0,0 +1,305 @@ +/* + +Copyright (c) 2018 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 + +/* + * Ethernet demultiplexer + */ +module eth_demux # +( + parameter M_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [DATA_WIDTH-1:0] s_eth_payload_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire [ID_WIDTH-1:0] s_eth_payload_axis_tid, + input wire [DEST_WIDTH-1:0] s_eth_payload_axis_tdest, + input wire [USER_WIDTH-1:0] s_eth_payload_axis_tuser, + + /* + * Ethernet frame outputs + */ + output wire [M_COUNT-1:0] m_eth_hdr_valid, + input wire [M_COUNT-1:0] m_eth_hdr_ready, + output wire [M_COUNT*48-1:0] m_eth_dest_mac, + output wire [M_COUNT*48-1:0] m_eth_src_mac, + output wire [M_COUNT*16-1:0] m_eth_type, + output wire [M_COUNT*DATA_WIDTH-1:0] m_eth_payload_axis_tdata, + output wire [M_COUNT*KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep, + output wire [M_COUNT-1:0] m_eth_payload_axis_tvalid, + input wire [M_COUNT-1:0] m_eth_payload_axis_tready, + output wire [M_COUNT-1:0] m_eth_payload_axis_tlast, + output wire [M_COUNT*ID_WIDTH-1:0] m_eth_payload_axis_tid, + output wire [M_COUNT*DEST_WIDTH-1:0] m_eth_payload_axis_tdest, + output wire [M_COUNT*USER_WIDTH-1:0] m_eth_payload_axis_tuser, + + /* + * Control + */ + input wire enable, + input wire drop, + input wire [$clog2(M_COUNT)-1:0] select +); + +parameter CL_M_COUNT = $clog2(M_COUNT); + +reg [CL_M_COUNT-1:0] select_reg = {CL_M_COUNT{1'b0}}, select_ctl, select_next; +reg drop_reg = 1'b0, drop_ctl, drop_next; +reg frame_reg = 1'b0, frame_ctl, frame_next; + +reg s_eth_hdr_ready_reg = 1'b0, s_eth_hdr_ready_next; + +reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; + +reg [M_COUNT-1:0] m_eth_hdr_valid_reg = 0, m_eth_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0, m_eth_dest_mac_next; +reg [47:0] m_eth_src_mac_reg = 48'd0, m_eth_src_mac_next; +reg [15:0] m_eth_type_reg = 16'd0, m_eth_type_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_eth_payload_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep_int; +reg [M_COUNT-1:0] m_eth_payload_axis_tvalid_int; +reg m_eth_payload_axis_tready_int_reg = 1'b0; +reg m_eth_payload_axis_tlast_int; +reg [ID_WIDTH-1:0] m_eth_payload_axis_tid_int; +reg [DEST_WIDTH-1:0] m_eth_payload_axis_tdest_int; +reg [USER_WIDTH-1:0] m_eth_payload_axis_tuser_int; +wire m_eth_payload_axis_tready_int_early; + +assign s_eth_hdr_ready = s_eth_hdr_ready_reg && enable; + +assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg && enable; + +assign m_eth_hdr_valid = m_eth_hdr_valid_reg; +assign m_eth_dest_mac = {M_COUNT{m_eth_dest_mac_reg}}; +assign m_eth_src_mac = {M_COUNT{m_eth_src_mac_reg}}; +assign m_eth_type = {M_COUNT{m_eth_type_reg}}; + +integer i; + +always @* begin + select_next = select_reg; + select_ctl = select_reg; + drop_next = drop_reg; + drop_ctl = drop_reg; + frame_next = frame_reg; + frame_ctl = frame_reg; + + s_eth_hdr_ready_next = 1'b0; + + s_eth_payload_axis_tready_next = 1'b0; + + m_eth_hdr_valid_next = m_eth_hdr_valid_reg & ~m_eth_hdr_ready; + m_eth_dest_mac_next = m_eth_dest_mac_reg; + m_eth_src_mac_next = m_eth_src_mac_reg; + m_eth_type_next = m_eth_type_reg; + + if (s_eth_payload_axis_tvalid && s_eth_payload_axis_tready) begin + // end of frame detection + if (s_eth_payload_axis_tlast) begin + frame_next = 1'b0; + drop_next = 1'b0; + end + end + + if (!frame_reg && s_eth_hdr_valid && s_eth_hdr_ready) begin + // start of frame, grab select value + select_ctl = select; + drop_ctl = drop; + frame_ctl = 1'b1; + + select_next = select_ctl; + drop_next = drop_ctl; + frame_next = frame_ctl; + + s_eth_hdr_ready_next = 1'b0; + + m_eth_hdr_valid_next = (!drop_ctl) << select_ctl; + m_eth_dest_mac_next = s_eth_dest_mac; + m_eth_src_mac_next = s_eth_src_mac; + m_eth_type_next = s_eth_type; + end + + s_eth_hdr_ready_next = !frame_next && !m_eth_hdr_valid_next; + + s_eth_payload_axis_tready_next = (m_eth_payload_axis_tready_int_early || drop_ctl) && frame_ctl; + + m_eth_payload_axis_tdata_int = s_eth_payload_axis_tdata; + m_eth_payload_axis_tkeep_int = s_eth_payload_axis_tkeep; + m_eth_payload_axis_tvalid_int = (s_eth_payload_axis_tvalid && s_eth_payload_axis_tready && !drop_ctl) << select_ctl; + m_eth_payload_axis_tlast_int = s_eth_payload_axis_tlast; + m_eth_payload_axis_tid_int = s_eth_payload_axis_tid; + m_eth_payload_axis_tdest_int = s_eth_payload_axis_tdest; + m_eth_payload_axis_tuser_int = s_eth_payload_axis_tuser; +end + +always @(posedge clk) begin + if (rst) begin + select_reg <= 2'd0; + drop_reg <= 1'b0; + frame_reg <= 1'b0; + s_eth_hdr_ready_reg <= 1'b0; + s_eth_payload_axis_tready_reg <= 1'b0; + m_eth_hdr_valid_reg <= 0; + end else begin + select_reg <= select_next; + drop_reg <= drop_next; + frame_reg <= frame_next; + s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; + s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; + m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; + end + + m_eth_dest_mac_reg <= m_eth_dest_mac_next; + m_eth_src_mac_reg <= m_eth_src_mac_next; + m_eth_type_reg <= m_eth_type_next; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [M_COUNT-1:0] m_eth_payload_axis_tvalid_reg = {M_COUNT{1'b0}}, m_eth_payload_axis_tvalid_next; +reg m_eth_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_eth_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_eth_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_eth_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [M_COUNT-1:0] temp_m_eth_payload_axis_tvalid_reg = {M_COUNT{1'b0}}, temp_m_eth_payload_axis_tvalid_next; +reg temp_m_eth_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_eth_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_eth_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_eth_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_eth_payload_axis_temp_to_output; + +assign m_eth_payload_axis_tdata = {M_COUNT{m_eth_payload_axis_tdata_reg}}; +assign m_eth_payload_axis_tkeep = KEEP_ENABLE ? {M_COUNT{m_eth_payload_axis_tkeep_reg}} : {M_COUNT*KEEP_WIDTH{1'b1}}; +assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; +assign m_eth_payload_axis_tlast = {M_COUNT{m_eth_payload_axis_tlast_reg}}; +assign m_eth_payload_axis_tid = ID_ENABLE ? {M_COUNT{m_eth_payload_axis_tid_reg}} : {M_COUNT*ID_WIDTH{1'b0}}; +assign m_eth_payload_axis_tdest = DEST_ENABLE ? {M_COUNT{m_eth_payload_axis_tdest_reg}} : {M_COUNT*DEST_WIDTH{1'b0}}; +assign m_eth_payload_axis_tuser = USER_ENABLE ? {M_COUNT{m_eth_payload_axis_tuser_reg}} : {M_COUNT*USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_eth_payload_axis_tready_int_early = (m_eth_payload_axis_tready & m_eth_payload_axis_tvalid) || (!temp_m_eth_payload_axis_tvalid_reg && (!m_eth_payload_axis_tvalid || !m_eth_payload_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b0; + + if (m_eth_payload_axis_tready_int_reg) begin + // input is ready + if ((m_eth_payload_axis_tready & m_eth_payload_axis_tvalid) || !m_eth_payload_axis_tvalid) begin + // output is ready or currently not valid, transfer data to output + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_eth_payload_axis_tready & m_eth_payload_axis_tvalid) begin + // input is not ready, but output is ready + m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_eth_payload_axis_tvalid_reg <= {M_COUNT{1'b0}}; + m_eth_payload_axis_tready_int_reg <= 1'b0; + temp_m_eth_payload_axis_tvalid_reg <= 1'b0; + end else begin + m_eth_payload_axis_tvalid_reg <= m_eth_payload_axis_tvalid_next; + m_eth_payload_axis_tready_int_reg <= m_eth_payload_axis_tready_int_early; + temp_m_eth_payload_axis_tvalid_reg <= temp_m_eth_payload_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + m_eth_payload_axis_tid_reg <= m_eth_payload_axis_tid_int; + m_eth_payload_axis_tdest_reg <= m_eth_payload_axis_tdest_int; + m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end else if (store_eth_payload_axis_temp_to_output) begin + m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; + m_eth_payload_axis_tkeep_reg <= temp_m_eth_payload_axis_tkeep_reg; + m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; + m_eth_payload_axis_tid_reg <= temp_m_eth_payload_axis_tid_reg; + m_eth_payload_axis_tdest_reg <= temp_m_eth_payload_axis_tdest_reg; + m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + temp_m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + temp_m_eth_payload_axis_tid_reg <= m_eth_payload_axis_tid_int; + temp_m_eth_payload_axis_tdest_reg <= m_eth_payload_axis_tdest_int; + temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/eth_demux_4.v b/rtl/eth_demux_4.v deleted file mode 100644 index 3f1758eae..000000000 --- a/rtl/eth_demux_4.v +++ /dev/null @@ -1,377 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet 4 port demultiplexer - */ -module eth_demux_4 -( - input wire clk, - input wire rst, - - /* - * Ethernet frame input - */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [7:0] input_eth_payload_tdata, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, - - /* - * Ethernet frame outputs - */ - output wire output_0_eth_hdr_valid, - input wire output_0_eth_hdr_ready, - output wire [47:0] output_0_eth_dest_mac, - output wire [47:0] output_0_eth_src_mac, - output wire [15:0] output_0_eth_type, - output wire [7:0] output_0_eth_payload_tdata, - output wire output_0_eth_payload_tvalid, - input wire output_0_eth_payload_tready, - output wire output_0_eth_payload_tlast, - output wire output_0_eth_payload_tuser, - - output wire output_1_eth_hdr_valid, - input wire output_1_eth_hdr_ready, - output wire [47:0] output_1_eth_dest_mac, - output wire [47:0] output_1_eth_src_mac, - output wire [15:0] output_1_eth_type, - output wire [7:0] output_1_eth_payload_tdata, - output wire output_1_eth_payload_tvalid, - input wire output_1_eth_payload_tready, - output wire output_1_eth_payload_tlast, - output wire output_1_eth_payload_tuser, - - output wire output_2_eth_hdr_valid, - input wire output_2_eth_hdr_ready, - output wire [47:0] output_2_eth_dest_mac, - output wire [47:0] output_2_eth_src_mac, - output wire [15:0] output_2_eth_type, - output wire [7:0] output_2_eth_payload_tdata, - output wire output_2_eth_payload_tvalid, - input wire output_2_eth_payload_tready, - output wire output_2_eth_payload_tlast, - output wire output_2_eth_payload_tuser, - - output wire output_3_eth_hdr_valid, - input wire output_3_eth_hdr_ready, - output wire [47:0] output_3_eth_dest_mac, - output wire [47:0] output_3_eth_src_mac, - output wire [15:0] output_3_eth_type, - output wire [7:0] output_3_eth_payload_tdata, - output wire output_3_eth_payload_tvalid, - input wire output_3_eth_payload_tready, - output wire output_3_eth_payload_tlast, - output wire output_3_eth_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; - -reg output_0_eth_hdr_valid_reg = 1'b0, output_0_eth_hdr_valid_next; -reg output_1_eth_hdr_valid_reg = 1'b0, output_1_eth_hdr_valid_next; -reg output_2_eth_hdr_valid_reg = 1'b0, output_2_eth_hdr_valid_next; -reg output_3_eth_hdr_valid_reg = 1'b0, output_3_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; - -// internal datapath -reg [7:0] output_eth_payload_tdata_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; - -assign input_eth_hdr_ready = input_eth_hdr_ready_reg; -assign input_eth_payload_tready = input_eth_payload_tready_reg; - -assign output_0_eth_hdr_valid = output_0_eth_hdr_valid_reg; -assign output_0_eth_dest_mac = output_eth_dest_mac_reg; -assign output_0_eth_src_mac = output_eth_src_mac_reg; -assign output_0_eth_type = output_eth_type_reg; - -assign output_1_eth_hdr_valid = output_1_eth_hdr_valid_reg; -assign output_1_eth_dest_mac = output_eth_dest_mac_reg; -assign output_1_eth_src_mac = output_eth_src_mac_reg; -assign output_1_eth_type = output_eth_type_reg; - -assign output_2_eth_hdr_valid = output_2_eth_hdr_valid_reg; -assign output_2_eth_dest_mac = output_eth_dest_mac_reg; -assign output_2_eth_src_mac = output_eth_src_mac_reg; -assign output_2_eth_type = output_eth_type_reg; - -assign output_3_eth_hdr_valid = output_3_eth_hdr_valid_reg; -assign output_3_eth_dest_mac = output_eth_dest_mac_reg; -assign output_3_eth_src_mac = output_eth_src_mac_reg; -assign output_3_eth_type = output_eth_type_reg; - -// mux for output control signals -reg current_output_eth_hdr_valid; -reg current_output_eth_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) - 2'd0: begin - current_output_eth_hdr_valid = output_0_eth_hdr_valid; - current_output_eth_hdr_ready = output_0_eth_hdr_ready; - current_output_tvalid = output_0_eth_payload_tvalid; - current_output_tready = output_0_eth_payload_tready; - end - 2'd1: begin - current_output_eth_hdr_valid = output_1_eth_hdr_valid; - current_output_eth_hdr_ready = output_1_eth_hdr_ready; - current_output_tvalid = output_1_eth_payload_tvalid; - current_output_tready = output_1_eth_payload_tready; - end - 2'd2: begin - current_output_eth_hdr_valid = output_2_eth_hdr_valid; - current_output_eth_hdr_ready = output_2_eth_hdr_ready; - current_output_tvalid = output_2_eth_payload_tvalid; - current_output_tready = output_2_eth_payload_tready; - end - 2'd3: begin - current_output_eth_hdr_valid = output_3_eth_hdr_valid; - current_output_eth_hdr_ready = output_3_eth_hdr_ready; - current_output_tvalid = output_3_eth_payload_tvalid; - current_output_tready = output_3_eth_payload_tready; - end - default: begin - current_output_eth_hdr_valid = 1'b0; - current_output_eth_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; - input_eth_payload_tready_next = 1'b0; - output_0_eth_hdr_valid_next = output_0_eth_hdr_valid_reg & ~output_0_eth_hdr_ready; - output_1_eth_hdr_valid_next = output_1_eth_hdr_valid_reg & ~output_1_eth_hdr_ready; - output_2_eth_hdr_valid_next = output_2_eth_hdr_valid_reg & ~output_2_eth_hdr_ready; - output_3_eth_hdr_valid_next = output_3_eth_hdr_valid_reg & ~output_3_eth_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - - if (input_eth_payload_tvalid & input_eth_payload_tready) begin - // end of frame detection - if (input_eth_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_eth_hdr_ready_next = 1'b1; - - case (select) - 2'd0: output_0_eth_hdr_valid_next = 1'b1; - 2'd1: output_1_eth_hdr_valid_next = 1'b1; - 2'd2: output_2_eth_hdr_valid_next = 1'b1; - 2'd3: output_3_eth_hdr_valid_next = 1'b1; - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - end - - input_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - - output_eth_payload_tdata_int = input_eth_payload_tdata; - output_eth_payload_tvalid_int = input_eth_payload_tvalid & input_eth_payload_tready; - output_eth_payload_tlast_int = input_eth_payload_tlast; - output_eth_payload_tuser_int = input_eth_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_eth_hdr_ready_reg <= 1'b0; - input_eth_payload_tready_reg <= 1'b0; - output_0_eth_hdr_valid_reg <= 1'b0; - output_1_eth_hdr_valid_reg <= 1'b0; - output_2_eth_hdr_valid_reg <= 1'b0; - output_3_eth_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; - input_eth_payload_tready_reg <= input_eth_payload_tready_next; - output_0_eth_hdr_valid_reg <= output_0_eth_hdr_valid_next; - output_1_eth_hdr_valid_reg <= output_1_eth_hdr_valid_next; - output_2_eth_hdr_valid_reg <= output_2_eth_hdr_valid_next; - output_3_eth_hdr_valid_reg <= output_3_eth_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; -end - -// output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 8'd0; -reg output_0_eth_payload_tvalid_reg = 1'b0, output_0_eth_payload_tvalid_next; -reg output_1_eth_payload_tvalid_reg = 1'b0, output_1_eth_payload_tvalid_next; -reg output_2_eth_payload_tvalid_reg = 1'b0, output_2_eth_payload_tvalid_next; -reg output_3_eth_payload_tvalid_reg = 1'b0, output_3_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; - -reg [7:0] temp_eth_payload_tdata_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; - -assign output_0_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_0_eth_payload_tvalid = output_0_eth_payload_tvalid_reg; -assign output_0_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_0_eth_payload_tuser = output_eth_payload_tuser_reg; - -assign output_1_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_1_eth_payload_tvalid = output_1_eth_payload_tvalid_reg; -assign output_1_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_1_eth_payload_tuser = output_eth_payload_tuser_reg; - -assign output_2_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_2_eth_payload_tvalid = output_2_eth_payload_tvalid_reg; -assign output_2_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_2_eth_payload_tuser = output_eth_payload_tuser_reg; - -assign output_3_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_3_eth_payload_tvalid = output_3_eth_payload_tvalid_reg; -assign output_3_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_3_eth_payload_tuser = output_eth_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & (~current_output_tvalid | ~output_eth_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_0_eth_payload_tvalid_next = output_0_eth_payload_tvalid_reg; - output_1_eth_payload_tvalid_next = output_1_eth_payload_tvalid_reg; - output_2_eth_payload_tvalid_next = output_2_eth_payload_tvalid_reg; - output_3_eth_payload_tvalid_next = output_3_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; - - if (output_eth_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_0_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd0); - output_1_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd1); - output_2_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd2); - output_3_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd3); - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_0_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd0); - output_1_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd1); - output_2_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd2); - output_3_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd3); - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_0_eth_payload_tvalid_reg <= 1'b0; - output_1_eth_payload_tvalid_reg <= 1'b0; - output_2_eth_payload_tvalid_reg <= 1'b0; - output_3_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; - end else begin - output_0_eth_payload_tvalid_reg <= output_0_eth_payload_tvalid_next; - output_1_eth_payload_tvalid_reg <= output_1_eth_payload_tvalid_next; - output_2_eth_payload_tvalid_reg <= output_2_eth_payload_tvalid_next; - output_3_eth_payload_tvalid_reg <= output_3_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end -end - -endmodule diff --git a/rtl/eth_demux_64.py b/rtl/eth_demux_64.py deleted file mode 100755 index 97986a3b6..000000000 --- a/rtl/eth_demux_64.py +++ /dev/null @@ -1,353 +0,0 @@ -#!/usr/bin/env python -""" -Generates an Ethernet demux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "eth_demux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port Ethernet demux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet {{n}} port demultiplexer (64 bit datapath) - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * Ethernet frame input - */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [63:0] input_eth_payload_tdata, - input wire [7:0] input_eth_payload_tkeep, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, - - /* - * Ethernet frame outputs - */ -{%- for p in ports %} - output wire output_{{p}}_eth_hdr_valid, - input wire output_{{p}}_eth_hdr_ready, - output wire [47:0] output_{{p}}_eth_dest_mac, - output wire [47:0] output_{{p}}_eth_src_mac, - output wire [15:0] output_{{p}}_eth_type, - output wire [63:0] output_{{p}}_eth_payload_tdata, - output wire [7:0] output_{{p}}_eth_payload_tkeep, - output wire output_{{p}}_eth_payload_tvalid, - input wire output_{{p}}_eth_payload_tready, - output wire output_{{p}}_eth_payload_tlast, - output wire output_{{p}}_eth_payload_tuser, -{% endfor %} - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; -{% for p in ports %} -reg output_{{p}}_eth_hdr_valid_reg = 1'b0, output_{{p}}_eth_hdr_valid_next; -{%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; - -// internal datapath -reg [63:0] output_eth_payload_tdata_int; -reg [7:0] output_eth_payload_tkeep_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; - -assign input_eth_hdr_ready = input_eth_hdr_ready_reg; -assign input_eth_payload_tready = input_eth_payload_tready_reg; -{% for p in ports %} -assign output_{{p}}_eth_hdr_valid = output_{{p}}_eth_hdr_valid_reg; -assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; -assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; -assign output_{{p}}_eth_type = output_eth_type_reg; -{% endfor %} -// mux for output control signals -reg current_output_eth_hdr_valid; -reg current_output_eth_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_output_eth_hdr_valid = output_{{p}}_eth_hdr_valid; - current_output_eth_hdr_ready = output_{{p}}_eth_hdr_ready; - current_output_tvalid = output_{{p}}_eth_payload_tvalid; - current_output_tready = output_{{p}}_eth_payload_tready; - end -{%- endfor %} - default: begin - current_output_eth_hdr_valid = 1'b0; - current_output_eth_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; - input_eth_payload_tready_next = 1'b0; - -{%- for p in ports %} - output_{{p}}_eth_hdr_valid_next = output_{{p}}_eth_hdr_valid_reg & ~output_{{p}}_eth_hdr_ready; -{%- endfor %} - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - - if (input_eth_payload_tvalid & input_eth_payload_tready) begin - // end of frame detection - if (input_eth_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_eth_hdr_ready_next = 1'b1; - - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_eth_hdr_valid_next = 1'b1; -{%- endfor %} - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - end - - input_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - - output_eth_payload_tdata_int = input_eth_payload_tdata; - output_eth_payload_tkeep_int = input_eth_payload_tkeep; - output_eth_payload_tvalid_int = input_eth_payload_tvalid & input_eth_payload_tready; - output_eth_payload_tlast_int = input_eth_payload_tlast; - output_eth_payload_tuser_int = input_eth_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; - input_eth_hdr_ready_reg <= 1'b0; - input_eth_payload_tready_reg <= 1'b0; -{%- for p in ports %} - output_{{p}}_eth_hdr_valid_reg <= 1'b0; -{%- endfor %} - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; - input_eth_payload_tready_reg <= input_eth_payload_tready_next; -{%- for p in ports %} - output_{{p}}_eth_hdr_valid_reg <= output_{{p}}_eth_hdr_valid_next; -{%- endfor %} - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; -end - -// output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 64'd0; -reg [7:0] output_eth_payload_tkeep_reg = 8'd0; -{%- for p in ports %} -reg output_{{p}}_eth_payload_tvalid_reg = 1'b0, output_{{p}}_eth_payload_tvalid_next; -{%- endfor %} -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; - -reg [63:0] temp_eth_payload_tdata_reg = 64'd0; -reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; -{% for p in ports %} -assign output_{{p}}_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_{{p}}_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_{{p}}_eth_payload_tvalid = output_{{p}}_eth_payload_tvalid_reg; -assign output_{{p}}_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_{{p}}_eth_payload_tuser = output_eth_payload_tuser_reg; -{% endfor %} -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & (~current_output_tvalid | ~output_eth_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source -{%- for p in ports %} - output_{{p}}_eth_payload_tvalid_next = output_{{p}}_eth_payload_tvalid_reg; -{%- endfor %} - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; - - if (output_eth_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output -{%- for p in ports %} - output_{{p}}_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready -{%- for p in ports %} - output_{{p}}_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin -{%- for p in ports %} - output_{{p}}_eth_payload_tvalid_reg <= 1'b0; -{%- endfor %} - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; - end else begin -{%- for p in ports %} - output_{{p}}_eth_payload_tvalid_reg <= output_{{p}}_eth_payload_tvalid_next; -{%- endfor %} - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/eth_demux_64_4.v b/rtl/eth_demux_64_4.v deleted file mode 100644 index 96105ccef..000000000 --- a/rtl/eth_demux_64_4.v +++ /dev/null @@ -1,393 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * Ethernet 4 port demultiplexer (64 bit datapath) - */ -module eth_demux_64_4 -( - input wire clk, - input wire rst, - - /* - * Ethernet frame input - */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [63:0] input_eth_payload_tdata, - input wire [7:0] input_eth_payload_tkeep, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, - - /* - * Ethernet frame outputs - */ - output wire output_0_eth_hdr_valid, - input wire output_0_eth_hdr_ready, - output wire [47:0] output_0_eth_dest_mac, - output wire [47:0] output_0_eth_src_mac, - output wire [15:0] output_0_eth_type, - output wire [63:0] output_0_eth_payload_tdata, - output wire [7:0] output_0_eth_payload_tkeep, - output wire output_0_eth_payload_tvalid, - input wire output_0_eth_payload_tready, - output wire output_0_eth_payload_tlast, - output wire output_0_eth_payload_tuser, - - output wire output_1_eth_hdr_valid, - input wire output_1_eth_hdr_ready, - output wire [47:0] output_1_eth_dest_mac, - output wire [47:0] output_1_eth_src_mac, - output wire [15:0] output_1_eth_type, - output wire [63:0] output_1_eth_payload_tdata, - output wire [7:0] output_1_eth_payload_tkeep, - output wire output_1_eth_payload_tvalid, - input wire output_1_eth_payload_tready, - output wire output_1_eth_payload_tlast, - output wire output_1_eth_payload_tuser, - - output wire output_2_eth_hdr_valid, - input wire output_2_eth_hdr_ready, - output wire [47:0] output_2_eth_dest_mac, - output wire [47:0] output_2_eth_src_mac, - output wire [15:0] output_2_eth_type, - output wire [63:0] output_2_eth_payload_tdata, - output wire [7:0] output_2_eth_payload_tkeep, - output wire output_2_eth_payload_tvalid, - input wire output_2_eth_payload_tready, - output wire output_2_eth_payload_tlast, - output wire output_2_eth_payload_tuser, - - output wire output_3_eth_hdr_valid, - input wire output_3_eth_hdr_ready, - output wire [47:0] output_3_eth_dest_mac, - output wire [47:0] output_3_eth_src_mac, - output wire [15:0] output_3_eth_type, - output wire [63:0] output_3_eth_payload_tdata, - output wire [7:0] output_3_eth_payload_tkeep, - output wire output_3_eth_payload_tvalid, - input wire output_3_eth_payload_tready, - output wire output_3_eth_payload_tlast, - output wire output_3_eth_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; - -reg output_0_eth_hdr_valid_reg = 1'b0, output_0_eth_hdr_valid_next; -reg output_1_eth_hdr_valid_reg = 1'b0, output_1_eth_hdr_valid_next; -reg output_2_eth_hdr_valid_reg = 1'b0, output_2_eth_hdr_valid_next; -reg output_3_eth_hdr_valid_reg = 1'b0, output_3_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; - -// internal datapath -reg [63:0] output_eth_payload_tdata_int; -reg [7:0] output_eth_payload_tkeep_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; - -assign input_eth_hdr_ready = input_eth_hdr_ready_reg; -assign input_eth_payload_tready = input_eth_payload_tready_reg; - -assign output_0_eth_hdr_valid = output_0_eth_hdr_valid_reg; -assign output_0_eth_dest_mac = output_eth_dest_mac_reg; -assign output_0_eth_src_mac = output_eth_src_mac_reg; -assign output_0_eth_type = output_eth_type_reg; - -assign output_1_eth_hdr_valid = output_1_eth_hdr_valid_reg; -assign output_1_eth_dest_mac = output_eth_dest_mac_reg; -assign output_1_eth_src_mac = output_eth_src_mac_reg; -assign output_1_eth_type = output_eth_type_reg; - -assign output_2_eth_hdr_valid = output_2_eth_hdr_valid_reg; -assign output_2_eth_dest_mac = output_eth_dest_mac_reg; -assign output_2_eth_src_mac = output_eth_src_mac_reg; -assign output_2_eth_type = output_eth_type_reg; - -assign output_3_eth_hdr_valid = output_3_eth_hdr_valid_reg; -assign output_3_eth_dest_mac = output_eth_dest_mac_reg; -assign output_3_eth_src_mac = output_eth_src_mac_reg; -assign output_3_eth_type = output_eth_type_reg; - -// mux for output control signals -reg current_output_eth_hdr_valid; -reg current_output_eth_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) - 2'd0: begin - current_output_eth_hdr_valid = output_0_eth_hdr_valid; - current_output_eth_hdr_ready = output_0_eth_hdr_ready; - current_output_tvalid = output_0_eth_payload_tvalid; - current_output_tready = output_0_eth_payload_tready; - end - 2'd1: begin - current_output_eth_hdr_valid = output_1_eth_hdr_valid; - current_output_eth_hdr_ready = output_1_eth_hdr_ready; - current_output_tvalid = output_1_eth_payload_tvalid; - current_output_tready = output_1_eth_payload_tready; - end - 2'd2: begin - current_output_eth_hdr_valid = output_2_eth_hdr_valid; - current_output_eth_hdr_ready = output_2_eth_hdr_ready; - current_output_tvalid = output_2_eth_payload_tvalid; - current_output_tready = output_2_eth_payload_tready; - end - 2'd3: begin - current_output_eth_hdr_valid = output_3_eth_hdr_valid; - current_output_eth_hdr_ready = output_3_eth_hdr_ready; - current_output_tvalid = output_3_eth_payload_tvalid; - current_output_tready = output_3_eth_payload_tready; - end - default: begin - current_output_eth_hdr_valid = 1'b0; - current_output_eth_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_eth_hdr_ready_next = input_eth_hdr_ready_reg & ~input_eth_hdr_valid; - input_eth_payload_tready_next = 1'b0; - output_0_eth_hdr_valid_next = output_0_eth_hdr_valid_reg & ~output_0_eth_hdr_ready; - output_1_eth_hdr_valid_next = output_1_eth_hdr_valid_reg & ~output_1_eth_hdr_ready; - output_2_eth_hdr_valid_next = output_2_eth_hdr_valid_reg & ~output_2_eth_hdr_ready; - output_3_eth_hdr_valid_next = output_3_eth_hdr_valid_reg & ~output_3_eth_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - - if (input_eth_payload_tvalid & input_eth_payload_tready) begin - // end of frame detection - if (input_eth_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_eth_hdr_valid & ~current_output_eth_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_eth_hdr_ready_next = 1'b1; - - case (select) - 2'd0: output_0_eth_hdr_valid_next = 1'b1; - 2'd1: output_1_eth_hdr_valid_next = 1'b1; - 2'd2: output_2_eth_hdr_valid_next = 1'b1; - 2'd3: output_3_eth_hdr_valid_next = 1'b1; - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - end - - input_eth_payload_tready_next = output_eth_payload_tready_int_early & frame_next; - - output_eth_payload_tdata_int = input_eth_payload_tdata; - output_eth_payload_tkeep_int = input_eth_payload_tkeep; - output_eth_payload_tvalid_int = input_eth_payload_tvalid & input_eth_payload_tready; - output_eth_payload_tlast_int = input_eth_payload_tlast; - output_eth_payload_tuser_int = input_eth_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_eth_hdr_ready_reg <= 1'b0; - input_eth_payload_tready_reg <= 1'b0; - output_0_eth_hdr_valid_reg <= 1'b0; - output_1_eth_hdr_valid_reg <= 1'b0; - output_2_eth_hdr_valid_reg <= 1'b0; - output_3_eth_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; - input_eth_payload_tready_reg <= input_eth_payload_tready_next; - output_0_eth_hdr_valid_reg <= output_0_eth_hdr_valid_next; - output_1_eth_hdr_valid_reg <= output_1_eth_hdr_valid_next; - output_2_eth_hdr_valid_reg <= output_2_eth_hdr_valid_next; - output_3_eth_hdr_valid_reg <= output_3_eth_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; -end - -// output datapath logic -reg [63:0] output_eth_payload_tdata_reg = 64'd0; -reg [7:0] output_eth_payload_tkeep_reg = 8'd0; -reg output_0_eth_payload_tvalid_reg = 1'b0, output_0_eth_payload_tvalid_next; -reg output_1_eth_payload_tvalid_reg = 1'b0, output_1_eth_payload_tvalid_next; -reg output_2_eth_payload_tvalid_reg = 1'b0, output_2_eth_payload_tvalid_next; -reg output_3_eth_payload_tvalid_reg = 1'b0, output_3_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; - -reg [63:0] temp_eth_payload_tdata_reg = 64'd0; -reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; - -assign output_0_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_0_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_0_eth_payload_tvalid = output_0_eth_payload_tvalid_reg; -assign output_0_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_0_eth_payload_tuser = output_eth_payload_tuser_reg; - -assign output_1_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_1_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_1_eth_payload_tvalid = output_1_eth_payload_tvalid_reg; -assign output_1_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_1_eth_payload_tuser = output_eth_payload_tuser_reg; - -assign output_2_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_2_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_2_eth_payload_tvalid = output_2_eth_payload_tvalid_reg; -assign output_2_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_2_eth_payload_tuser = output_eth_payload_tuser_reg; - -assign output_3_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_3_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_3_eth_payload_tvalid = output_3_eth_payload_tvalid_reg; -assign output_3_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_3_eth_payload_tuser = output_eth_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = current_output_tready | (~temp_eth_payload_tvalid_reg & (~current_output_tvalid | ~output_eth_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_0_eth_payload_tvalid_next = output_0_eth_payload_tvalid_reg; - output_1_eth_payload_tvalid_next = output_1_eth_payload_tvalid_reg; - output_2_eth_payload_tvalid_next = output_2_eth_payload_tvalid_reg; - output_3_eth_payload_tvalid_next = output_3_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; - - if (output_eth_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_0_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd0); - output_1_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd1); - output_2_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd2); - output_3_eth_payload_tvalid_next = output_eth_payload_tvalid_int & (select_reg == 2'd3); - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_0_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd0); - output_1_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd1); - output_2_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd2); - output_3_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg & (select_reg == 2'd3); - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_0_eth_payload_tvalid_reg <= 1'b0; - output_1_eth_payload_tvalid_reg <= 1'b0; - output_2_eth_payload_tvalid_reg <= 1'b0; - output_3_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; - end else begin - output_0_eth_payload_tvalid_reg <= output_0_eth_payload_tvalid_next; - output_1_eth_payload_tvalid_reg <= output_1_eth_payload_tvalid_next; - output_2_eth_payload_tvalid_reg <= output_2_eth_payload_tvalid_next; - output_3_eth_payload_tvalid_reg <= output_3_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end -end - -endmodule diff --git a/tb/test_eth_demux_4.py b/tb/test_eth_demux_4.py index 7a0f10777..16a1adb23 100755 --- a/tb/test_eth_demux_4.py +++ b/tb/test_eth_demux_4.py @@ -28,8 +28,8 @@ import os import eth_ep -module = 'eth_demux_4' -testbench = 'test_%s' % module +module = 'eth_demux' +testbench = 'test_%s_4' % module srcs = [] @@ -42,170 +42,123 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + M_COUNT = 4 + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_eth_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_eth_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_eth_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_0_eth_hdr_ready = Signal(bool(0)) - output_0_eth_payload_tready = Signal(bool(0)) - output_1_eth_hdr_ready = Signal(bool(0)) - output_1_eth_payload_tready = Signal(bool(0)) - output_2_eth_hdr_ready = Signal(bool(0)) - output_2_eth_payload_tready = Signal(bool(0)) - output_3_eth_hdr_ready = Signal(bool(0)) - output_3_eth_payload_tready = Signal(bool(0)) + m_eth_hdr_ready_list = [Signal(bool(0)) for i in range(M_COUNT)] + m_eth_payload_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_eth_hdr_ready = ConcatSignal(*reversed(m_eth_hdr_ready_list)) + m_eth_payload_axis_tready = ConcatSignal(*reversed(m_eth_payload_axis_tready_list)) enable = Signal(bool(0)) + drop = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) - output_0_eth_hdr_valid = Signal(bool(0)) - output_0_eth_dest_mac = Signal(intbv(0)[48:]) - output_0_eth_src_mac = Signal(intbv(0)[48:]) - output_0_eth_type = Signal(intbv(0)[16:]) - output_0_eth_payload_tdata = Signal(intbv(0)[8:]) - output_0_eth_payload_tvalid = Signal(bool(0)) - output_0_eth_payload_tlast = Signal(bool(0)) - output_0_eth_payload_tuser = Signal(bool(0)) - output_1_eth_hdr_valid = Signal(bool(0)) - output_1_eth_dest_mac = Signal(intbv(0)[48:]) - output_1_eth_src_mac = Signal(intbv(0)[48:]) - output_1_eth_type = Signal(intbv(0)[16:]) - output_1_eth_payload_tdata = Signal(intbv(0)[8:]) - output_1_eth_payload_tvalid = Signal(bool(0)) - output_1_eth_payload_tlast = Signal(bool(0)) - output_1_eth_payload_tuser = Signal(bool(0)) - output_2_eth_hdr_valid = Signal(bool(0)) - output_2_eth_dest_mac = Signal(intbv(0)[48:]) - output_2_eth_src_mac = Signal(intbv(0)[48:]) - output_2_eth_type = Signal(intbv(0)[16:]) - output_2_eth_payload_tdata = Signal(intbv(0)[8:]) - output_2_eth_payload_tvalid = Signal(bool(0)) - output_2_eth_payload_tlast = Signal(bool(0)) - output_2_eth_payload_tuser = Signal(bool(0)) - output_3_eth_hdr_valid = Signal(bool(0)) - output_3_eth_dest_mac = Signal(intbv(0)[48:]) - output_3_eth_src_mac = Signal(intbv(0)[48:]) - output_3_eth_type = Signal(intbv(0)[16:]) - output_3_eth_payload_tdata = Signal(intbv(0)[8:]) - output_3_eth_payload_tvalid = Signal(bool(0)) - output_3_eth_payload_tlast = Signal(bool(0)) - output_3_eth_payload_tuser = Signal(bool(0)) + m_eth_hdr_valid = Signal(intbv(0)[M_COUNT:]) + m_eth_dest_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_src_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_type = Signal(intbv(0)[M_COUNT*16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_eth_payload_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_eth_payload_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_eth_payload_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_eth_payload_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_eth_payload_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_eth_payload_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_eth_hdr_valid_list = [m_eth_hdr_valid(i) for i in range(M_COUNT)] + m_eth_dest_mac_list = [m_eth_dest_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_src_mac_list = [m_eth_src_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_type_list = [m_eth_type((i+1)*16, i*16) for i in range(M_COUNT)] + m_eth_payload_axis_tdata_list = [m_eth_payload_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_eth_payload_axis_tkeep_list = [m_eth_payload_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_eth_payload_axis_tvalid_list = [m_eth_payload_axis_tvalid(i) for i in range(M_COUNT)] + m_eth_payload_axis_tlast_list = [m_eth_payload_axis_tlast(i) for i in range(M_COUNT)] + m_eth_payload_axis_tid_list = [m_eth_payload_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_eth_payload_axis_tdest_list = [m_eth_payload_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_eth_payload_axis_tuser_list = [m_eth_payload_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks source_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] source = eth_ep.EthFrameSource() source_logic = source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tkeep=s_eth_payload_axis_tkeep, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=source_pause, name='source' ) - sink_0 = eth_ep.EthFrameSink() + for k in range(M_COUNT): + s = eth_ep.EthFrameSink() + p = Signal(bool(0)) - sink_0_logic = sink_0.create_logic( - clk, - rst, - eth_hdr_ready=output_0_eth_hdr_ready, - eth_hdr_valid=output_0_eth_hdr_valid, - eth_dest_mac=output_0_eth_dest_mac, - eth_src_mac=output_0_eth_src_mac, - eth_type=output_0_eth_type, - eth_payload_tdata=output_0_eth_payload_tdata, - eth_payload_tvalid=output_0_eth_payload_tvalid, - eth_payload_tready=output_0_eth_payload_tready, - eth_payload_tlast=output_0_eth_payload_tlast, - eth_payload_tuser=output_0_eth_payload_tuser, - pause=sink_0_pause, - name='sink_0' - ) + sink_list.append(s) + sink_pause_list.append(p) - sink_1 = eth_ep.EthFrameSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - eth_hdr_ready=output_1_eth_hdr_ready, - eth_hdr_valid=output_1_eth_hdr_valid, - eth_dest_mac=output_1_eth_dest_mac, - eth_src_mac=output_1_eth_src_mac, - eth_type=output_1_eth_type, - eth_payload_tdata=output_1_eth_payload_tdata, - eth_payload_tvalid=output_1_eth_payload_tvalid, - eth_payload_tready=output_1_eth_payload_tready, - eth_payload_tlast=output_1_eth_payload_tlast, - eth_payload_tuser=output_1_eth_payload_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = eth_ep.EthFrameSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - eth_hdr_ready=output_2_eth_hdr_ready, - eth_hdr_valid=output_2_eth_hdr_valid, - eth_dest_mac=output_2_eth_dest_mac, - eth_src_mac=output_2_eth_src_mac, - eth_type=output_2_eth_type, - eth_payload_tdata=output_2_eth_payload_tdata, - eth_payload_tvalid=output_2_eth_payload_tvalid, - eth_payload_tready=output_2_eth_payload_tready, - eth_payload_tlast=output_2_eth_payload_tlast, - eth_payload_tuser=output_2_eth_payload_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = eth_ep.EthFrameSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - eth_hdr_ready=output_3_eth_hdr_ready, - eth_hdr_valid=output_3_eth_hdr_valid, - eth_dest_mac=output_3_eth_dest_mac, - eth_src_mac=output_3_eth_src_mac, - eth_type=output_3_eth_type, - eth_payload_tdata=output_3_eth_payload_tdata, - eth_payload_tvalid=output_3_eth_payload_tvalid, - eth_payload_tready=output_3_eth_payload_tready, - eth_payload_tlast=output_3_eth_payload_tlast, - eth_payload_tuser=output_3_eth_payload_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + eth_hdr_ready=m_eth_hdr_ready_list[k], + eth_hdr_valid=m_eth_hdr_valid_list[k], + eth_dest_mac=m_eth_dest_mac_list[k], + eth_src_mac=m_eth_src_mac_list[k], + eth_type=m_eth_type_list[k], + eth_payload_tdata=m_eth_payload_axis_tdata_list[k], + eth_payload_tkeep=m_eth_payload_axis_tkeep_list[k], + eth_payload_tvalid=m_eth_payload_axis_tvalid_list[k], + eth_payload_tready=m_eth_payload_axis_tready_list[k], + eth_payload_tlast=m_eth_payload_axis_tlast_list[k], + eth_payload_tuser=m_eth_payload_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -217,59 +170,36 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tid=s_eth_payload_axis_tid, + s_eth_payload_axis_tdest=s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_0_eth_hdr_valid=output_0_eth_hdr_valid, - output_0_eth_hdr_ready=output_0_eth_hdr_ready, - output_0_eth_dest_mac=output_0_eth_dest_mac, - output_0_eth_src_mac=output_0_eth_src_mac, - output_0_eth_type=output_0_eth_type, - output_0_eth_payload_tdata=output_0_eth_payload_tdata, - output_0_eth_payload_tvalid=output_0_eth_payload_tvalid, - output_0_eth_payload_tready=output_0_eth_payload_tready, - output_0_eth_payload_tlast=output_0_eth_payload_tlast, - output_0_eth_payload_tuser=output_0_eth_payload_tuser, - output_1_eth_hdr_valid=output_1_eth_hdr_valid, - output_1_eth_hdr_ready=output_1_eth_hdr_ready, - output_1_eth_dest_mac=output_1_eth_dest_mac, - output_1_eth_src_mac=output_1_eth_src_mac, - output_1_eth_type=output_1_eth_type, - output_1_eth_payload_tdata=output_1_eth_payload_tdata, - output_1_eth_payload_tvalid=output_1_eth_payload_tvalid, - output_1_eth_payload_tready=output_1_eth_payload_tready, - output_1_eth_payload_tlast=output_1_eth_payload_tlast, - output_1_eth_payload_tuser=output_1_eth_payload_tuser, - output_2_eth_hdr_valid=output_2_eth_hdr_valid, - output_2_eth_hdr_ready=output_2_eth_hdr_ready, - output_2_eth_dest_mac=output_2_eth_dest_mac, - output_2_eth_src_mac=output_2_eth_src_mac, - output_2_eth_type=output_2_eth_type, - output_2_eth_payload_tdata=output_2_eth_payload_tdata, - output_2_eth_payload_tvalid=output_2_eth_payload_tvalid, - output_2_eth_payload_tready=output_2_eth_payload_tready, - output_2_eth_payload_tlast=output_2_eth_payload_tlast, - output_2_eth_payload_tuser=output_2_eth_payload_tuser, - output_3_eth_hdr_valid=output_3_eth_hdr_valid, - output_3_eth_hdr_ready=output_3_eth_hdr_ready, - output_3_eth_dest_mac=output_3_eth_dest_mac, - output_3_eth_src_mac=output_3_eth_src_mac, - output_3_eth_type=output_3_eth_type, - output_3_eth_payload_tdata=output_3_eth_payload_tdata, - output_3_eth_payload_tvalid=output_3_eth_payload_tvalid, - output_3_eth_payload_tready=output_3_eth_payload_tready, - output_3_eth_payload_tlast=output_3_eth_payload_tlast, - output_3_eth_payload_tuser=output_3_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tid=m_eth_payload_axis_tid, + m_eth_payload_axis_tdest=m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, enable=enable, + drop=drop, select=select ) @@ -305,8 +235,8 @@ def bench(): source.send(test_frame) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame @@ -326,8 +256,8 @@ def bench(): source.send(test_frame) - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame @@ -353,13 +283,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame1 - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame2 @@ -386,17 +316,17 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_eth_payload_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or s_eth_hdr_valid: yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -423,7 +353,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_eth_payload_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or s_eth_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -432,13 +362,13 @@ def bench(): yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -465,33 +395,84 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_eth_payload_tvalid or input_eth_hdr_valid: - sink_0_pause.next = True - sink_1_pause.next = True - sink_2_pause.next = True - sink_3_pause.next = True + while s_eth_payload_axis_tvalid or s_eth_hdr_valid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_0_pause.next = False - sink_1_pause.next = False - sink_2_pause.next = False - sink_3_pause.next = False + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 yield delay(100) + yield clk.posedge + print("test 7: enable") + current_test.next = 7 + + enable.next = False + select.next = 0 + + 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(range(32)) + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + enable.next = True + + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 8: drop") + current_test.next = 8 + + drop.next = True + select.next = 0 + + 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(range(32)) + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + drop.next = False + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_eth_demux_4.v b/tb/test_eth_demux_4.v index e6f00489a..82d901a6a 100644 --- a/tb/test_eth_demux_4.v +++ b/tb/test_eth_demux_4.v @@ -27,72 +27,61 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for eth_demux_4 + * Testbench for eth_demux */ module test_eth_demux_4; +// Parameters +parameter M_COUNT = 4; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [7:0] input_eth_payload_tdata = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [DATA_WIDTH-1:0] s_eth_payload_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_eth_payload_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_eth_payload_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_eth_payload_axis_tuser = 0; -reg output_0_eth_hdr_ready = 0; -reg output_0_eth_payload_tready = 0; -reg output_1_eth_hdr_ready = 0; -reg output_1_eth_payload_tready = 0; -reg output_2_eth_hdr_ready = 0; -reg output_2_eth_payload_tready = 0; -reg output_3_eth_hdr_ready = 0; -reg output_3_eth_payload_tready = 0; +reg [M_COUNT-1:0] m_eth_hdr_ready = 0; +reg [M_COUNT-1:0] m_eth_payload_axis_tready = 0; reg enable = 0; +reg drop = 0; reg [1:0] select = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; -wire output_0_eth_hdr_valid; -wire [47:0] output_0_eth_dest_mac; -wire [47:0] output_0_eth_src_mac; -wire [15:0] output_0_eth_type; -wire [7:0] output_0_eth_payload_tdata; -wire output_0_eth_payload_tvalid; -wire output_0_eth_payload_tlast; -wire output_0_eth_payload_tuser; -wire output_1_eth_hdr_valid; -wire [47:0] output_1_eth_dest_mac; -wire [47:0] output_1_eth_src_mac; -wire [15:0] output_1_eth_type; -wire [7:0] output_1_eth_payload_tdata; -wire output_1_eth_payload_tvalid; -wire output_1_eth_payload_tlast; -wire output_1_eth_payload_tuser; -wire output_2_eth_hdr_valid; -wire [47:0] output_2_eth_dest_mac; -wire [47:0] output_2_eth_src_mac; -wire [15:0] output_2_eth_type; -wire [7:0] output_2_eth_payload_tdata; -wire output_2_eth_payload_tvalid; -wire output_2_eth_payload_tlast; -wire output_2_eth_payload_tuser; -wire output_3_eth_hdr_valid; -wire [47:0] output_3_eth_dest_mac; -wire [47:0] output_3_eth_src_mac; -wire [15:0] output_3_eth_type; -wire [7:0] output_3_eth_payload_tdata; -wire output_3_eth_payload_tvalid; -wire output_3_eth_payload_tlast; -wire output_3_eth_payload_tuser; +wire [M_COUNT-1:0] m_eth_hdr_valid; +wire [M_COUNT*48-1:0] m_eth_dest_mac; +wire [M_COUNT*48-1:0] m_eth_src_mac; +wire [M_COUNT*16-1:0] m_eth_type; +wire [M_COUNT*DATA_WIDTH-1:0] m_eth_payload_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep; +wire [M_COUNT-1:0] m_eth_payload_axis_tvalid; +wire [M_COUNT-1:0] m_eth_payload_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_eth_payload_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_eth_payload_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_eth_payload_axis_tuser; initial begin // myhdl integration @@ -100,60 +89,37 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_0_eth_hdr_ready, - output_0_eth_payload_tready, - output_1_eth_hdr_ready, - output_1_eth_payload_tready, - output_2_eth_hdr_ready, - output_2_eth_payload_tready, - output_3_eth_hdr_ready, - output_3_eth_payload_tready, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tid, + s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, enable, + drop, select ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - output_0_eth_hdr_valid, - output_0_eth_dest_mac, - output_0_eth_src_mac, - output_0_eth_type, - output_0_eth_payload_tdata, - output_0_eth_payload_tvalid, - output_0_eth_payload_tlast, - output_0_eth_payload_tuser, - output_1_eth_hdr_valid, - output_1_eth_dest_mac, - output_1_eth_src_mac, - output_1_eth_type, - output_1_eth_payload_tdata, - output_1_eth_payload_tvalid, - output_1_eth_payload_tlast, - output_1_eth_payload_tuser, - output_2_eth_hdr_valid, - output_2_eth_dest_mac, - output_2_eth_src_mac, - output_2_eth_type, - output_2_eth_payload_tdata, - output_2_eth_payload_tvalid, - output_2_eth_payload_tlast, - output_2_eth_payload_tuser, - output_3_eth_hdr_valid, - output_3_eth_dest_mac, - output_3_eth_src_mac, - output_3_eth_type, - output_3_eth_payload_tdata, - output_3_eth_payload_tvalid, - output_3_eth_payload_tlast, - output_3_eth_payload_tuser + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tid, + m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser ); // dump file @@ -161,64 +127,52 @@ initial begin $dumpvars(0, test_eth_demux_4); end -eth_demux_4 +eth_demux #( + .M_COUNT(M_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tid(s_eth_payload_axis_tid), + .s_eth_payload_axis_tdest(s_eth_payload_axis_tdest), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame outputs - .output_0_eth_hdr_valid(output_0_eth_hdr_valid), - .output_0_eth_hdr_ready(output_0_eth_hdr_ready), - .output_0_eth_dest_mac(output_0_eth_dest_mac), - .output_0_eth_src_mac(output_0_eth_src_mac), - .output_0_eth_type(output_0_eth_type), - .output_0_eth_payload_tdata(output_0_eth_payload_tdata), - .output_0_eth_payload_tvalid(output_0_eth_payload_tvalid), - .output_0_eth_payload_tready(output_0_eth_payload_tready), - .output_0_eth_payload_tlast(output_0_eth_payload_tlast), - .output_0_eth_payload_tuser(output_0_eth_payload_tuser), - .output_1_eth_hdr_valid(output_1_eth_hdr_valid), - .output_1_eth_hdr_ready(output_1_eth_hdr_ready), - .output_1_eth_dest_mac(output_1_eth_dest_mac), - .output_1_eth_src_mac(output_1_eth_src_mac), - .output_1_eth_type(output_1_eth_type), - .output_1_eth_payload_tdata(output_1_eth_payload_tdata), - .output_1_eth_payload_tvalid(output_1_eth_payload_tvalid), - .output_1_eth_payload_tready(output_1_eth_payload_tready), - .output_1_eth_payload_tlast(output_1_eth_payload_tlast), - .output_1_eth_payload_tuser(output_1_eth_payload_tuser), - .output_2_eth_hdr_valid(output_2_eth_hdr_valid), - .output_2_eth_hdr_ready(output_2_eth_hdr_ready), - .output_2_eth_dest_mac(output_2_eth_dest_mac), - .output_2_eth_src_mac(output_2_eth_src_mac), - .output_2_eth_type(output_2_eth_type), - .output_2_eth_payload_tdata(output_2_eth_payload_tdata), - .output_2_eth_payload_tvalid(output_2_eth_payload_tvalid), - .output_2_eth_payload_tready(output_2_eth_payload_tready), - .output_2_eth_payload_tlast(output_2_eth_payload_tlast), - .output_2_eth_payload_tuser(output_2_eth_payload_tuser), - .output_3_eth_hdr_valid(output_3_eth_hdr_valid), - .output_3_eth_hdr_ready(output_3_eth_hdr_ready), - .output_3_eth_dest_mac(output_3_eth_dest_mac), - .output_3_eth_src_mac(output_3_eth_src_mac), - .output_3_eth_type(output_3_eth_type), - .output_3_eth_payload_tdata(output_3_eth_payload_tdata), - .output_3_eth_payload_tvalid(output_3_eth_payload_tvalid), - .output_3_eth_payload_tready(output_3_eth_payload_tready), - .output_3_eth_payload_tlast(output_3_eth_payload_tlast), - .output_3_eth_payload_tuser(output_3_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tid(m_eth_payload_axis_tid), + .m_eth_payload_axis_tdest(m_eth_payload_axis_tdest), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Control .enable(enable), + .drop(drop), .select(select) ); diff --git a/tb/test_eth_demux_64_4.py b/tb/test_eth_demux_64_4.py index 67f57315c..1071089d3 100755 --- a/tb/test_eth_demux_64_4.py +++ b/tb/test_eth_demux_64_4.py @@ -28,8 +28,8 @@ import os import eth_ep -module = 'eth_demux_64_4' -testbench = 'test_%s' % module +module = 'eth_demux' +testbench = 'test_%s_64_4' % module srcs = [] @@ -42,180 +42,123 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + M_COUNT = 4 + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[64:]) - input_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_eth_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_eth_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_eth_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_0_eth_hdr_ready = Signal(bool(0)) - output_0_eth_payload_tready = Signal(bool(0)) - output_1_eth_hdr_ready = Signal(bool(0)) - output_1_eth_payload_tready = Signal(bool(0)) - output_2_eth_hdr_ready = Signal(bool(0)) - output_2_eth_payload_tready = Signal(bool(0)) - output_3_eth_hdr_ready = Signal(bool(0)) - output_3_eth_payload_tready = Signal(bool(0)) + m_eth_hdr_ready_list = [Signal(bool(0)) for i in range(M_COUNT)] + m_eth_payload_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_eth_hdr_ready = ConcatSignal(*reversed(m_eth_hdr_ready_list)) + m_eth_payload_axis_tready = ConcatSignal(*reversed(m_eth_payload_axis_tready_list)) enable = Signal(bool(0)) + drop = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) - output_0_eth_hdr_valid = Signal(bool(0)) - output_0_eth_dest_mac = Signal(intbv(0)[48:]) - output_0_eth_src_mac = Signal(intbv(0)[48:]) - output_0_eth_type = Signal(intbv(0)[16:]) - output_0_eth_payload_tdata = Signal(intbv(0)[64:]) - output_0_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_0_eth_payload_tvalid = Signal(bool(0)) - output_0_eth_payload_tlast = Signal(bool(0)) - output_0_eth_payload_tuser = Signal(bool(0)) - output_1_eth_hdr_valid = Signal(bool(0)) - output_1_eth_dest_mac = Signal(intbv(0)[48:]) - output_1_eth_src_mac = Signal(intbv(0)[48:]) - output_1_eth_type = Signal(intbv(0)[16:]) - output_1_eth_payload_tdata = Signal(intbv(0)[64:]) - output_1_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_1_eth_payload_tvalid = Signal(bool(0)) - output_1_eth_payload_tlast = Signal(bool(0)) - output_1_eth_payload_tuser = Signal(bool(0)) - output_2_eth_hdr_valid = Signal(bool(0)) - output_2_eth_dest_mac = Signal(intbv(0)[48:]) - output_2_eth_src_mac = Signal(intbv(0)[48:]) - output_2_eth_type = Signal(intbv(0)[16:]) - output_2_eth_payload_tdata = Signal(intbv(0)[64:]) - output_2_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_2_eth_payload_tvalid = Signal(bool(0)) - output_2_eth_payload_tlast = Signal(bool(0)) - output_2_eth_payload_tuser = Signal(bool(0)) - output_3_eth_hdr_valid = Signal(bool(0)) - output_3_eth_dest_mac = Signal(intbv(0)[48:]) - output_3_eth_src_mac = Signal(intbv(0)[48:]) - output_3_eth_type = Signal(intbv(0)[16:]) - output_3_eth_payload_tdata = Signal(intbv(0)[64:]) - output_3_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_3_eth_payload_tvalid = Signal(bool(0)) - output_3_eth_payload_tlast = Signal(bool(0)) - output_3_eth_payload_tuser = Signal(bool(0)) + m_eth_hdr_valid = Signal(intbv(0)[M_COUNT:]) + m_eth_dest_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_src_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_type = Signal(intbv(0)[M_COUNT*16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_eth_payload_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_eth_payload_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_eth_payload_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_eth_payload_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_eth_payload_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_eth_payload_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_eth_hdr_valid_list = [m_eth_hdr_valid(i) for i in range(M_COUNT)] + m_eth_dest_mac_list = [m_eth_dest_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_src_mac_list = [m_eth_src_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_type_list = [m_eth_type((i+1)*16, i*16) for i in range(M_COUNT)] + m_eth_payload_axis_tdata_list = [m_eth_payload_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_eth_payload_axis_tkeep_list = [m_eth_payload_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_eth_payload_axis_tvalid_list = [m_eth_payload_axis_tvalid(i) for i in range(M_COUNT)] + m_eth_payload_axis_tlast_list = [m_eth_payload_axis_tlast(i) for i in range(M_COUNT)] + m_eth_payload_axis_tid_list = [m_eth_payload_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_eth_payload_axis_tdest_list = [m_eth_payload_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_eth_payload_axis_tuser_list = [m_eth_payload_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks source_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] source = eth_ep.EthFrameSource() source_logic = source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tkeep=input_eth_payload_tkeep, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tkeep=s_eth_payload_axis_tkeep, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=source_pause, name='source' ) - sink_0 = eth_ep.EthFrameSink() + for k in range(M_COUNT): + s = eth_ep.EthFrameSink() + p = Signal(bool(0)) - sink_0_logic = sink_0.create_logic( - clk, - rst, - eth_hdr_ready=output_0_eth_hdr_ready, - eth_hdr_valid=output_0_eth_hdr_valid, - eth_dest_mac=output_0_eth_dest_mac, - eth_src_mac=output_0_eth_src_mac, - eth_type=output_0_eth_type, - eth_payload_tdata=output_0_eth_payload_tdata, - eth_payload_tkeep=output_0_eth_payload_tkeep, - eth_payload_tvalid=output_0_eth_payload_tvalid, - eth_payload_tready=output_0_eth_payload_tready, - eth_payload_tlast=output_0_eth_payload_tlast, - eth_payload_tuser=output_0_eth_payload_tuser, - pause=sink_0_pause, - name='sink_0' - ) + sink_list.append(s) + sink_pause_list.append(p) - sink_1 = eth_ep.EthFrameSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - eth_hdr_ready=output_1_eth_hdr_ready, - eth_hdr_valid=output_1_eth_hdr_valid, - eth_dest_mac=output_1_eth_dest_mac, - eth_src_mac=output_1_eth_src_mac, - eth_type=output_1_eth_type, - eth_payload_tdata=output_1_eth_payload_tdata, - eth_payload_tkeep=output_1_eth_payload_tkeep, - eth_payload_tvalid=output_1_eth_payload_tvalid, - eth_payload_tready=output_1_eth_payload_tready, - eth_payload_tlast=output_1_eth_payload_tlast, - eth_payload_tuser=output_1_eth_payload_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = eth_ep.EthFrameSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - eth_hdr_ready=output_2_eth_hdr_ready, - eth_hdr_valid=output_2_eth_hdr_valid, - eth_dest_mac=output_2_eth_dest_mac, - eth_src_mac=output_2_eth_src_mac, - eth_type=output_2_eth_type, - eth_payload_tdata=output_2_eth_payload_tdata, - eth_payload_tkeep=output_2_eth_payload_tkeep, - eth_payload_tvalid=output_2_eth_payload_tvalid, - eth_payload_tready=output_2_eth_payload_tready, - eth_payload_tlast=output_2_eth_payload_tlast, - eth_payload_tuser=output_2_eth_payload_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = eth_ep.EthFrameSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - eth_hdr_ready=output_3_eth_hdr_ready, - eth_hdr_valid=output_3_eth_hdr_valid, - eth_dest_mac=output_3_eth_dest_mac, - eth_src_mac=output_3_eth_src_mac, - eth_type=output_3_eth_type, - eth_payload_tdata=output_3_eth_payload_tdata, - eth_payload_tkeep=output_3_eth_payload_tkeep, - eth_payload_tvalid=output_3_eth_payload_tvalid, - eth_payload_tready=output_3_eth_payload_tready, - eth_payload_tlast=output_3_eth_payload_tlast, - eth_payload_tuser=output_3_eth_payload_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + eth_hdr_ready=m_eth_hdr_ready_list[k], + eth_hdr_valid=m_eth_hdr_valid_list[k], + eth_dest_mac=m_eth_dest_mac_list[k], + eth_src_mac=m_eth_src_mac_list[k], + eth_type=m_eth_type_list[k], + eth_payload_tdata=m_eth_payload_axis_tdata_list[k], + eth_payload_tkeep=m_eth_payload_axis_tkeep_list[k], + eth_payload_tvalid=m_eth_payload_axis_tvalid_list[k], + eth_payload_tready=m_eth_payload_axis_tready_list[k], + eth_payload_tlast=m_eth_payload_axis_tlast_list[k], + eth_payload_tuser=m_eth_payload_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -227,64 +170,36 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tkeep=input_eth_payload_tkeep, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tid=s_eth_payload_axis_tid, + s_eth_payload_axis_tdest=s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_0_eth_hdr_valid=output_0_eth_hdr_valid, - output_0_eth_hdr_ready=output_0_eth_hdr_ready, - output_0_eth_dest_mac=output_0_eth_dest_mac, - output_0_eth_src_mac=output_0_eth_src_mac, - output_0_eth_type=output_0_eth_type, - output_0_eth_payload_tdata=output_0_eth_payload_tdata, - output_0_eth_payload_tkeep=output_0_eth_payload_tkeep, - output_0_eth_payload_tvalid=output_0_eth_payload_tvalid, - output_0_eth_payload_tready=output_0_eth_payload_tready, - output_0_eth_payload_tlast=output_0_eth_payload_tlast, - output_0_eth_payload_tuser=output_0_eth_payload_tuser, - output_1_eth_hdr_valid=output_1_eth_hdr_valid, - output_1_eth_hdr_ready=output_1_eth_hdr_ready, - output_1_eth_dest_mac=output_1_eth_dest_mac, - output_1_eth_src_mac=output_1_eth_src_mac, - output_1_eth_type=output_1_eth_type, - output_1_eth_payload_tdata=output_1_eth_payload_tdata, - output_1_eth_payload_tkeep=output_1_eth_payload_tkeep, - output_1_eth_payload_tvalid=output_1_eth_payload_tvalid, - output_1_eth_payload_tready=output_1_eth_payload_tready, - output_1_eth_payload_tlast=output_1_eth_payload_tlast, - output_1_eth_payload_tuser=output_1_eth_payload_tuser, - output_2_eth_hdr_valid=output_2_eth_hdr_valid, - output_2_eth_hdr_ready=output_2_eth_hdr_ready, - output_2_eth_dest_mac=output_2_eth_dest_mac, - output_2_eth_src_mac=output_2_eth_src_mac, - output_2_eth_type=output_2_eth_type, - output_2_eth_payload_tdata=output_2_eth_payload_tdata, - output_2_eth_payload_tkeep=output_2_eth_payload_tkeep, - output_2_eth_payload_tvalid=output_2_eth_payload_tvalid, - output_2_eth_payload_tready=output_2_eth_payload_tready, - output_2_eth_payload_tlast=output_2_eth_payload_tlast, - output_2_eth_payload_tuser=output_2_eth_payload_tuser, - output_3_eth_hdr_valid=output_3_eth_hdr_valid, - output_3_eth_hdr_ready=output_3_eth_hdr_ready, - output_3_eth_dest_mac=output_3_eth_dest_mac, - output_3_eth_src_mac=output_3_eth_src_mac, - output_3_eth_type=output_3_eth_type, - output_3_eth_payload_tdata=output_3_eth_payload_tdata, - output_3_eth_payload_tkeep=output_3_eth_payload_tkeep, - output_3_eth_payload_tvalid=output_3_eth_payload_tvalid, - output_3_eth_payload_tready=output_3_eth_payload_tready, - output_3_eth_payload_tlast=output_3_eth_payload_tlast, - output_3_eth_payload_tuser=output_3_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tid=m_eth_payload_axis_tid, + m_eth_payload_axis_tdest=m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, enable=enable, + drop=drop, select=select ) @@ -320,8 +235,8 @@ def bench(): source.send(test_frame) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame @@ -341,8 +256,8 @@ def bench(): source.send(test_frame) - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame @@ -368,13 +283,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame1 - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame2 @@ -401,17 +316,17 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_eth_payload_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or s_eth_hdr_valid: yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -438,7 +353,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_eth_payload_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or s_eth_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -447,13 +362,13 @@ def bench(): yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -480,33 +395,84 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_eth_payload_tvalid or input_eth_hdr_valid: - sink_0_pause.next = True - sink_1_pause.next = True - sink_2_pause.next = True - sink_3_pause.next = True + while s_eth_payload_axis_tvalid or s_eth_hdr_valid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_0_pause.next = False - sink_1_pause.next = False - sink_2_pause.next = False - sink_3_pause.next = False + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 yield delay(100) + yield clk.posedge + print("test 7: enable") + current_test.next = 7 + + enable.next = False + select.next = 0 + + 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(range(32)) + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + enable.next = True + + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 8: drop") + current_test.next = 8 + + drop.next = True + select.next = 0 + + 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(range(32)) + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + drop.next = False + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_eth_demux_64_4.v b/tb/test_eth_demux_64_4.v index b809b93a1..b7c998feb 100644 --- a/tb/test_eth_demux_64_4.v +++ b/tb/test_eth_demux_64_4.v @@ -27,77 +27,61 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for eth_demux_64_4 + * Testbench for eth_demux */ module test_eth_demux_64_4; +// Parameters +parameter M_COUNT = 4; +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [63:0] input_eth_payload_tdata = 0; -reg [7:0] input_eth_payload_tkeep = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [DATA_WIDTH-1:0] s_eth_payload_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_eth_payload_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_eth_payload_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_eth_payload_axis_tuser = 0; -reg output_0_eth_hdr_ready = 0; -reg output_0_eth_payload_tready = 0; -reg output_1_eth_hdr_ready = 0; -reg output_1_eth_payload_tready = 0; -reg output_2_eth_hdr_ready = 0; -reg output_2_eth_payload_tready = 0; -reg output_3_eth_hdr_ready = 0; -reg output_3_eth_payload_tready = 0; +reg [M_COUNT-1:0] m_eth_hdr_ready = 0; +reg [M_COUNT-1:0] m_eth_payload_axis_tready = 0; reg enable = 0; +reg drop = 0; reg [1:0] select = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; -wire output_0_eth_hdr_valid; -wire [47:0] output_0_eth_dest_mac; -wire [47:0] output_0_eth_src_mac; -wire [15:0] output_0_eth_type; -wire [63:0] output_0_eth_payload_tdata; -wire [7:0] output_0_eth_payload_tkeep; -wire output_0_eth_payload_tvalid; -wire output_0_eth_payload_tlast; -wire output_0_eth_payload_tuser; -wire output_1_eth_hdr_valid; -wire [47:0] output_1_eth_dest_mac; -wire [47:0] output_1_eth_src_mac; -wire [15:0] output_1_eth_type; -wire [63:0] output_1_eth_payload_tdata; -wire [7:0] output_1_eth_payload_tkeep; -wire output_1_eth_payload_tvalid; -wire output_1_eth_payload_tlast; -wire output_1_eth_payload_tuser; -wire output_2_eth_hdr_valid; -wire [47:0] output_2_eth_dest_mac; -wire [47:0] output_2_eth_src_mac; -wire [15:0] output_2_eth_type; -wire [63:0] output_2_eth_payload_tdata; -wire [7:0] output_2_eth_payload_tkeep; -wire output_2_eth_payload_tvalid; -wire output_2_eth_payload_tlast; -wire output_2_eth_payload_tuser; -wire output_3_eth_hdr_valid; -wire [47:0] output_3_eth_dest_mac; -wire [47:0] output_3_eth_src_mac; -wire [15:0] output_3_eth_type; -wire [63:0] output_3_eth_payload_tdata; -wire [7:0] output_3_eth_payload_tkeep; -wire output_3_eth_payload_tvalid; -wire output_3_eth_payload_tlast; -wire output_3_eth_payload_tuser; +wire [M_COUNT-1:0] m_eth_hdr_valid; +wire [M_COUNT*48-1:0] m_eth_dest_mac; +wire [M_COUNT*48-1:0] m_eth_src_mac; +wire [M_COUNT*16-1:0] m_eth_type; +wire [M_COUNT*DATA_WIDTH-1:0] m_eth_payload_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep; +wire [M_COUNT-1:0] m_eth_payload_axis_tvalid; +wire [M_COUNT-1:0] m_eth_payload_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_eth_payload_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_eth_payload_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_eth_payload_axis_tuser; initial begin // myhdl integration @@ -105,65 +89,37 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_0_eth_hdr_ready, - output_0_eth_payload_tready, - output_1_eth_hdr_ready, - output_1_eth_payload_tready, - output_2_eth_hdr_ready, - output_2_eth_payload_tready, - output_3_eth_hdr_ready, - output_3_eth_payload_tready, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tid, + s_eth_payload_axis_tdest, + s_eth_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, enable, + drop, select ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - output_0_eth_hdr_valid, - output_0_eth_dest_mac, - output_0_eth_src_mac, - output_0_eth_type, - output_0_eth_payload_tdata, - output_0_eth_payload_tkeep, - output_0_eth_payload_tvalid, - output_0_eth_payload_tlast, - output_0_eth_payload_tuser, - output_1_eth_hdr_valid, - output_1_eth_dest_mac, - output_1_eth_src_mac, - output_1_eth_type, - output_1_eth_payload_tdata, - output_1_eth_payload_tkeep, - output_1_eth_payload_tvalid, - output_1_eth_payload_tlast, - output_1_eth_payload_tuser, - output_2_eth_hdr_valid, - output_2_eth_dest_mac, - output_2_eth_src_mac, - output_2_eth_type, - output_2_eth_payload_tdata, - output_2_eth_payload_tkeep, - output_2_eth_payload_tvalid, - output_2_eth_payload_tlast, - output_2_eth_payload_tuser, - output_3_eth_hdr_valid, - output_3_eth_dest_mac, - output_3_eth_src_mac, - output_3_eth_type, - output_3_eth_payload_tdata, - output_3_eth_payload_tkeep, - output_3_eth_payload_tvalid, - output_3_eth_payload_tlast, - output_3_eth_payload_tuser + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tid, + m_eth_payload_axis_tdest, + m_eth_payload_axis_tuser ); // dump file @@ -171,69 +127,52 @@ initial begin $dumpvars(0, test_eth_demux_64_4); end -eth_demux_64_4 +eth_demux #( + .M_COUNT(M_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tid(s_eth_payload_axis_tid), + .s_eth_payload_axis_tdest(s_eth_payload_axis_tdest), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame outputs - .output_0_eth_hdr_valid(output_0_eth_hdr_valid), - .output_0_eth_hdr_ready(output_0_eth_hdr_ready), - .output_0_eth_dest_mac(output_0_eth_dest_mac), - .output_0_eth_src_mac(output_0_eth_src_mac), - .output_0_eth_type(output_0_eth_type), - .output_0_eth_payload_tdata(output_0_eth_payload_tdata), - .output_0_eth_payload_tkeep(output_0_eth_payload_tkeep), - .output_0_eth_payload_tvalid(output_0_eth_payload_tvalid), - .output_0_eth_payload_tready(output_0_eth_payload_tready), - .output_0_eth_payload_tlast(output_0_eth_payload_tlast), - .output_0_eth_payload_tuser(output_0_eth_payload_tuser), - .output_1_eth_hdr_valid(output_1_eth_hdr_valid), - .output_1_eth_hdr_ready(output_1_eth_hdr_ready), - .output_1_eth_dest_mac(output_1_eth_dest_mac), - .output_1_eth_src_mac(output_1_eth_src_mac), - .output_1_eth_type(output_1_eth_type), - .output_1_eth_payload_tdata(output_1_eth_payload_tdata), - .output_1_eth_payload_tkeep(output_1_eth_payload_tkeep), - .output_1_eth_payload_tvalid(output_1_eth_payload_tvalid), - .output_1_eth_payload_tready(output_1_eth_payload_tready), - .output_1_eth_payload_tlast(output_1_eth_payload_tlast), - .output_1_eth_payload_tuser(output_1_eth_payload_tuser), - .output_2_eth_hdr_valid(output_2_eth_hdr_valid), - .output_2_eth_hdr_ready(output_2_eth_hdr_ready), - .output_2_eth_dest_mac(output_2_eth_dest_mac), - .output_2_eth_src_mac(output_2_eth_src_mac), - .output_2_eth_type(output_2_eth_type), - .output_2_eth_payload_tdata(output_2_eth_payload_tdata), - .output_2_eth_payload_tkeep(output_2_eth_payload_tkeep), - .output_2_eth_payload_tvalid(output_2_eth_payload_tvalid), - .output_2_eth_payload_tready(output_2_eth_payload_tready), - .output_2_eth_payload_tlast(output_2_eth_payload_tlast), - .output_2_eth_payload_tuser(output_2_eth_payload_tuser), - .output_3_eth_hdr_valid(output_3_eth_hdr_valid), - .output_3_eth_hdr_ready(output_3_eth_hdr_ready), - .output_3_eth_dest_mac(output_3_eth_dest_mac), - .output_3_eth_src_mac(output_3_eth_src_mac), - .output_3_eth_type(output_3_eth_type), - .output_3_eth_payload_tdata(output_3_eth_payload_tdata), - .output_3_eth_payload_tkeep(output_3_eth_payload_tkeep), - .output_3_eth_payload_tvalid(output_3_eth_payload_tvalid), - .output_3_eth_payload_tready(output_3_eth_payload_tready), - .output_3_eth_payload_tlast(output_3_eth_payload_tlast), - .output_3_eth_payload_tuser(output_3_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tid(m_eth_payload_axis_tid), + .m_eth_payload_axis_tdest(m_eth_payload_axis_tdest), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Control .enable(enable), + .drop(drop), .select(select) ); From 81e9aa0c771fcfd33245eb637e14e5acb9d91620 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 2 Nov 2018 00:25:23 -0700 Subject: [PATCH 465/617] Convert generated ip_demux to verilog parametrized module --- rtl/ip_demux.py | 434 ---------------------- rtl/ip_demux.v | 396 +++++++++++++++++++++ rtl/ip_demux_4.v | 546 ---------------------------- rtl/ip_demux_64.py | 444 ----------------------- rtl/ip_demux_64_4.v | 562 ----------------------------- tb/test_ip_demux_4.py | 735 +++++++++++++++++--------------------- tb/test_ip_demux_4.v | 531 ++++++++++----------------- tb/test_ip_demux_64_4.py | 750 +++++++++++++++++---------------------- tb/test_ip_demux_64_4.v | 546 ++++++++++------------------ 9 files changed, 1404 insertions(+), 3540 deletions(-) delete mode 100755 rtl/ip_demux.py create mode 100644 rtl/ip_demux.v delete mode 100644 rtl/ip_demux_4.v delete mode 100755 rtl/ip_demux_64.py delete mode 100644 rtl/ip_demux_64_4.v diff --git a/rtl/ip_demux.py b/rtl/ip_demux.py deleted file mode 100755 index 5fb2fb292..000000000 --- a/rtl/ip_demux.py +++ /dev/null @@ -1,434 +0,0 @@ -#!/usr/bin/env python -""" -Generates an IP demux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "ip_demux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port IP demux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * IP {{n}} port demultiplexer - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * IP frame input - */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [7:0] input_ip_payload_tdata, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, - - /* - * IP frame outputs - */ -{%- for p in ports %} - output wire output_{{p}}_ip_hdr_valid, - input wire output_{{p}}_ip_hdr_ready, - output wire [47:0] output_{{p}}_eth_dest_mac, - output wire [47:0] output_{{p}}_eth_src_mac, - output wire [15:0] output_{{p}}_eth_type, - output wire [3:0] output_{{p}}_ip_version, - output wire [3:0] output_{{p}}_ip_ihl, - output wire [5:0] output_{{p}}_ip_dscp, - output wire [1:0] output_{{p}}_ip_ecn, - output wire [15:0] output_{{p}}_ip_length, - output wire [15:0] output_{{p}}_ip_identification, - output wire [2:0] output_{{p}}_ip_flags, - output wire [12:0] output_{{p}}_ip_fragment_offset, - output wire [7:0] output_{{p}}_ip_ttl, - output wire [7:0] output_{{p}}_ip_protocol, - output wire [15:0] output_{{p}}_ip_header_checksum, - output wire [31:0] output_{{p}}_ip_source_ip, - output wire [31:0] output_{{p}}_ip_dest_ip, - output wire [7:0] output_{{p}}_ip_payload_tdata, - output wire output_{{p}}_ip_payload_tvalid, - input wire output_{{p}}_ip_payload_tready, - output wire output_{{p}}_ip_payload_tlast, - output wire output_{{p}}_ip_payload_tuser, -{% endfor %} - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; -{% for p in ports %} -reg output_{{p}}_ip_hdr_valid_reg = 1'b0, output_{{p}}_ip_hdr_valid_next; -{%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; - -// internal datapath -reg [7:0] output_ip_payload_tdata_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; - -assign input_ip_hdr_ready = input_ip_hdr_ready_reg; -assign input_ip_payload_tready = input_ip_payload_tready_reg; -{% for p in ports %} -assign output_{{p}}_ip_hdr_valid = output_{{p}}_ip_hdr_valid_reg; -assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; -assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; -assign output_{{p}}_eth_type = output_eth_type_reg; -assign output_{{p}}_ip_version = output_ip_version_reg; -assign output_{{p}}_ip_ihl = output_ip_ihl_reg; -assign output_{{p}}_ip_dscp = output_ip_dscp_reg; -assign output_{{p}}_ip_ecn = output_ip_ecn_reg; -assign output_{{p}}_ip_length = output_ip_length_reg; -assign output_{{p}}_ip_identification = output_ip_identification_reg; -assign output_{{p}}_ip_flags = output_ip_flags_reg; -assign output_{{p}}_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_{{p}}_ip_ttl = output_ip_ttl_reg; -assign output_{{p}}_ip_protocol = output_ip_protocol_reg; -assign output_{{p}}_ip_header_checksum = output_ip_header_checksum_reg; -assign output_{{p}}_ip_source_ip = output_ip_source_ip_reg; -assign output_{{p}}_ip_dest_ip = output_ip_dest_ip_reg; -{% endfor %} -// mux for output control signals -reg current_output_ip_hdr_valid; -reg current_output_ip_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_output_ip_hdr_valid = output_{{p}}_ip_hdr_valid; - current_output_ip_hdr_ready = output_{{p}}_ip_hdr_ready; - current_output_tvalid = output_{{p}}_ip_payload_tvalid; - current_output_tready = output_{{p}}_ip_payload_tready; - end -{%- endfor %} - default: begin - current_output_ip_hdr_valid = 1'b0; - current_output_ip_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; - input_ip_payload_tready_next = 1'b0; - -{%- for p in ports %} - output_{{p}}_ip_hdr_valid_next = output_{{p}}_ip_hdr_valid_reg & ~output_{{p}}_ip_hdr_ready; -{%- endfor %} - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - - if (input_ip_payload_tvalid & input_ip_payload_tready) begin - // end of frame detection - if (input_ip_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_ip_hdr_ready_next = 1'b1; - - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_ip_hdr_valid_next = 1'b1; -{%- endfor %} - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - output_ip_version_next = input_ip_version; - output_ip_ihl_next = input_ip_ihl; - output_ip_dscp_next = input_ip_dscp; - output_ip_ecn_next = input_ip_ecn; - output_ip_length_next = input_ip_length; - output_ip_identification_next = input_ip_identification; - output_ip_flags_next = input_ip_flags; - output_ip_fragment_offset_next = input_ip_fragment_offset; - output_ip_ttl_next = input_ip_ttl; - output_ip_protocol_next = input_ip_protocol; - output_ip_header_checksum_next = input_ip_header_checksum; - output_ip_source_ip_next = input_ip_source_ip; - output_ip_dest_ip_next = input_ip_dest_ip; - end - - input_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - - output_ip_payload_tdata_int = input_ip_payload_tdata; - output_ip_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tready; - output_ip_payload_tlast_int = input_ip_payload_tlast; - output_ip_payload_tuser_int = input_ip_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; - input_ip_hdr_ready_reg <= 1'b0; - input_ip_payload_tready_reg <= 1'b0; -{%- for p in ports %} - output_{{p}}_ip_hdr_valid_reg <= 1'b0; -{%- endfor %} - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; - input_ip_payload_tready_reg <= input_ip_payload_tready_next; -{%- for p in ports %} - output_{{p}}_ip_hdr_valid_reg <= output_{{p}}_ip_hdr_valid_next; -{%- endfor %} - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; -end - -// output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 8'd0; -{%- for p in ports %} -reg output_{{p}}_ip_payload_tvalid_reg = 1'b0, output_{{p}}_ip_payload_tvalid_next; -{%- endfor %} -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; - -reg [7:0] temp_ip_payload_tdata_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; - -// datapath control -reg store_ip_payload_int_to_output; -reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; -{% for p in ports %} -assign output_{{p}}_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_{{p}}_ip_payload_tvalid = output_{{p}}_ip_payload_tvalid_reg; -assign output_{{p}}_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_{{p}}_ip_payload_tuser = output_ip_payload_tuser_reg; -{% endfor %} -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & (~current_output_tvalid | ~output_ip_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source -{%- for p in ports %} - output_{{p}}_ip_payload_tvalid_next = output_{{p}}_ip_payload_tvalid_reg; -{%- endfor %} - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - - store_ip_payload_int_to_output = 1'b0; - store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; - - if (output_ip_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output -{%- for p in ports %} - output_{{p}}_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - store_ip_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready -{%- for p in ports %} - output_{{p}}_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin -{%- for p in ports %} - output_{{p}}_ip_payload_tvalid_reg <= 1'b0; -{%- endfor %} - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; - end else begin -{%- for p in ports %} - output_{{p}}_ip_payload_tvalid_reg <= output_{{p}}_ip_payload_tvalid_next; -{%- endfor %} - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; - end - - // datapath - if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - - if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/ip_demux.v b/rtl/ip_demux.v new file mode 100644 index 000000000..b86e60bd9 --- /dev/null +++ b/rtl/ip_demux.v @@ -0,0 +1,396 @@ +/* + +Copyright (c) 2018 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 + +/* + * IP demultiplexer + */ +module ip_demux # +( + parameter M_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * IP frame input + */ + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [3:0] s_ip_version, + input wire [3:0] s_ip_ihl, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [15:0] s_ip_header_checksum, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [DATA_WIDTH-1:0] s_ip_payload_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_ip_payload_axis_tkeep, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire [ID_WIDTH-1:0] s_ip_payload_axis_tid, + input wire [DEST_WIDTH-1:0] s_ip_payload_axis_tdest, + input wire [USER_WIDTH-1:0] s_ip_payload_axis_tuser, + + /* + * IP frame outputs + */ + output wire [M_COUNT-1:0] m_ip_hdr_valid, + input wire [M_COUNT-1:0] m_ip_hdr_ready, + output wire [M_COUNT*48-1:0] m_eth_dest_mac, + output wire [M_COUNT*48-1:0] m_eth_src_mac, + output wire [M_COUNT*16-1:0] m_eth_type, + output wire [M_COUNT*4-1:0] m_ip_version, + output wire [M_COUNT*4-1:0] m_ip_ihl, + output wire [M_COUNT*6-1:0] m_ip_dscp, + output wire [M_COUNT*2-1:0] m_ip_ecn, + output wire [M_COUNT*16-1:0] m_ip_length, + output wire [M_COUNT*16-1:0] m_ip_identification, + output wire [M_COUNT*3-1:0] m_ip_flags, + output wire [M_COUNT*13-1:0] m_ip_fragment_offset, + output wire [M_COUNT*8-1:0] m_ip_ttl, + output wire [M_COUNT*8-1:0] m_ip_protocol, + output wire [M_COUNT*16-1:0] m_ip_header_checksum, + output wire [M_COUNT*32-1:0] m_ip_source_ip, + output wire [M_COUNT*32-1:0] m_ip_dest_ip, + output wire [M_COUNT*DATA_WIDTH-1:0] m_ip_payload_axis_tdata, + output wire [M_COUNT*KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep, + output wire [M_COUNT-1:0] m_ip_payload_axis_tvalid, + input wire [M_COUNT-1:0] m_ip_payload_axis_tready, + output wire [M_COUNT-1:0] m_ip_payload_axis_tlast, + output wire [M_COUNT*ID_WIDTH-1:0] m_ip_payload_axis_tid, + output wire [M_COUNT*DEST_WIDTH-1:0] m_ip_payload_axis_tdest, + output wire [M_COUNT*USER_WIDTH-1:0] m_ip_payload_axis_tuser, + + /* + * Control + */ + input wire enable, + input wire drop, + input wire [$clog2(M_COUNT)-1:0] select +); + +parameter CL_M_COUNT = $clog2(M_COUNT); + +reg [CL_M_COUNT-1:0] select_reg = {CL_M_COUNT{1'b0}}, select_ctl, select_next; +reg drop_reg = 1'b0, drop_ctl, drop_next; +reg frame_reg = 1'b0, frame_ctl, frame_next; + +reg s_ip_hdr_ready_reg = 1'b0, s_ip_hdr_ready_next; + +reg s_ip_payload_axis_tready_reg = 1'b0, s_ip_payload_axis_tready_next; + +reg [M_COUNT-1:0] m_ip_hdr_valid_reg = 0, m_ip_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0, m_eth_dest_mac_next; +reg [47:0] m_eth_src_mac_reg = 48'd0, m_eth_src_mac_next; +reg [15:0] m_eth_type_reg = 16'd0, m_eth_type_next; +reg [3:0] m_ip_version_reg = 4'd0, m_ip_version_next; +reg [3:0] m_ip_ihl_reg = 4'd0, m_ip_ihl_next; +reg [5:0] m_ip_dscp_reg = 6'd0, m_ip_dscp_next; +reg [1:0] m_ip_ecn_reg = 2'd0, m_ip_ecn_next; +reg [15:0] m_ip_length_reg = 16'd0, m_ip_length_next; +reg [15:0] m_ip_identification_reg = 16'd0, m_ip_identification_next; +reg [2:0] m_ip_flags_reg = 3'd0, m_ip_flags_next; +reg [12:0] m_ip_fragment_offset_reg = 13'd0, m_ip_fragment_offset_next; +reg [7:0] m_ip_ttl_reg = 8'd0, m_ip_ttl_next; +reg [7:0] m_ip_protocol_reg = 8'd0, m_ip_protocol_next; +reg [15:0] m_ip_header_checksum_reg = 16'd0, m_ip_header_checksum_next; +reg [31:0] m_ip_source_ip_reg = 32'd0, m_ip_source_ip_next; +reg [31:0] m_ip_dest_ip_reg = 32'd0, m_ip_dest_ip_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_ip_payload_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep_int; +reg [M_COUNT-1:0] m_ip_payload_axis_tvalid_int; +reg m_ip_payload_axis_tready_int_reg = 1'b0; +reg m_ip_payload_axis_tlast_int; +reg [ID_WIDTH-1:0] m_ip_payload_axis_tid_int; +reg [DEST_WIDTH-1:0] m_ip_payload_axis_tdest_int; +reg [USER_WIDTH-1:0] m_ip_payload_axis_tuser_int; +wire m_ip_payload_axis_tready_int_early; + +assign s_ip_hdr_ready = s_ip_hdr_ready_reg && enable; + +assign s_ip_payload_axis_tready = s_ip_payload_axis_tready_reg && enable; + +assign m_ip_hdr_valid = m_ip_hdr_valid_reg; +assign m_eth_dest_mac = {M_COUNT{m_eth_dest_mac_reg}}; +assign m_eth_src_mac = {M_COUNT{m_eth_src_mac_reg}}; +assign m_eth_type = {M_COUNT{m_eth_type_reg}}; +assign m_ip_version = {M_COUNT{m_ip_version_reg}}; +assign m_ip_ihl = {M_COUNT{m_ip_ihl_reg}}; +assign m_ip_dscp = {M_COUNT{m_ip_dscp_reg}}; +assign m_ip_ecn = {M_COUNT{m_ip_ecn_reg}}; +assign m_ip_length = {M_COUNT{m_ip_length_reg}}; +assign m_ip_identification = {M_COUNT{m_ip_identification_reg}}; +assign m_ip_flags = {M_COUNT{m_ip_flags_reg}}; +assign m_ip_fragment_offset = {M_COUNT{m_ip_fragment_offset_reg}}; +assign m_ip_ttl = {M_COUNT{m_ip_ttl_reg}}; +assign m_ip_protocol = {M_COUNT{m_ip_protocol_reg}}; +assign m_ip_header_checksum = {M_COUNT{m_ip_header_checksum_reg}}; +assign m_ip_source_ip = {M_COUNT{m_ip_source_ip_reg}}; +assign m_ip_dest_ip = {M_COUNT{m_ip_dest_ip_reg}}; + +integer i; + +always @* begin + select_next = select_reg; + select_ctl = select_reg; + drop_next = drop_reg; + drop_ctl = drop_reg; + frame_next = frame_reg; + frame_ctl = frame_reg; + + s_ip_hdr_ready_next = 1'b0; + + s_ip_payload_axis_tready_next = 1'b0; + + m_ip_hdr_valid_next = m_ip_hdr_valid_reg & ~m_ip_hdr_ready; + m_eth_dest_mac_next = m_eth_dest_mac_reg; + m_eth_src_mac_next = m_eth_src_mac_reg; + m_eth_type_next = m_eth_type_reg; + m_ip_version_next = m_ip_version_reg; + m_ip_ihl_next = m_ip_ihl_reg; + m_ip_dscp_next = m_ip_dscp_reg; + m_ip_ecn_next = m_ip_ecn_reg; + m_ip_length_next = m_ip_length_reg; + m_ip_identification_next = m_ip_identification_reg; + m_ip_flags_next = m_ip_flags_reg; + m_ip_fragment_offset_next = m_ip_fragment_offset_reg; + m_ip_ttl_next = m_ip_ttl_reg; + m_ip_protocol_next = m_ip_protocol_reg; + m_ip_header_checksum_next = m_ip_header_checksum_reg; + m_ip_source_ip_next = m_ip_source_ip_reg; + m_ip_dest_ip_next = m_ip_dest_ip_reg; + + if (s_ip_payload_axis_tvalid && s_ip_payload_axis_tready) begin + // end of frame detection + if (s_ip_payload_axis_tlast) begin + frame_next = 1'b0; + drop_next = 1'b0; + end + end + + if (!frame_reg && s_ip_hdr_valid && s_ip_hdr_ready) begin + // start of frame, grab select value + select_ctl = select; + drop_ctl = drop; + frame_ctl = 1'b1; + + select_next = select_ctl; + drop_next = drop_ctl; + frame_next = frame_ctl; + + s_ip_hdr_ready_next = 1'b0; + + m_ip_hdr_valid_next = (!drop_ctl) << select_ctl; + m_eth_dest_mac_next = s_eth_dest_mac; + m_eth_src_mac_next = s_eth_src_mac; + m_eth_type_next = s_eth_type; + m_ip_version_next = s_ip_version; + m_ip_ihl_next = s_ip_ihl; + m_ip_dscp_next = s_ip_dscp; + m_ip_ecn_next = s_ip_ecn; + m_ip_length_next = s_ip_length; + m_ip_identification_next = s_ip_identification; + m_ip_flags_next = s_ip_flags; + m_ip_fragment_offset_next = s_ip_fragment_offset; + m_ip_ttl_next = s_ip_ttl; + m_ip_protocol_next = s_ip_protocol; + m_ip_header_checksum_next = s_ip_header_checksum; + m_ip_source_ip_next = s_ip_source_ip; + m_ip_dest_ip_next = s_ip_dest_ip; + end + + s_ip_hdr_ready_next = !frame_next && !m_ip_hdr_valid_next; + + s_ip_payload_axis_tready_next = (m_ip_payload_axis_tready_int_early || drop_ctl) && frame_ctl; + + m_ip_payload_axis_tdata_int = s_ip_payload_axis_tdata; + m_ip_payload_axis_tkeep_int = s_ip_payload_axis_tkeep; + m_ip_payload_axis_tvalid_int = (s_ip_payload_axis_tvalid && s_ip_payload_axis_tready && !drop_ctl) << select_ctl; + m_ip_payload_axis_tlast_int = s_ip_payload_axis_tlast; + m_ip_payload_axis_tid_int = s_ip_payload_axis_tid; + m_ip_payload_axis_tdest_int = s_ip_payload_axis_tdest; + m_ip_payload_axis_tuser_int = s_ip_payload_axis_tuser; +end + +always @(posedge clk) begin + if (rst) begin + select_reg <= 2'd0; + drop_reg <= 1'b0; + frame_reg <= 1'b0; + s_ip_hdr_ready_reg <= 1'b0; + s_ip_payload_axis_tready_reg <= 1'b0; + m_ip_hdr_valid_reg <= 0; + end else begin + select_reg <= select_next; + drop_reg <= drop_next; + frame_reg <= frame_next; + s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; + s_ip_payload_axis_tready_reg <= s_ip_payload_axis_tready_next; + m_ip_hdr_valid_reg <= m_ip_hdr_valid_next; + end + + m_eth_dest_mac_reg <= m_eth_dest_mac_next; + m_eth_src_mac_reg <= m_eth_src_mac_next; + m_eth_type_reg <= m_eth_type_next; + m_ip_version_reg <= m_ip_version_next; + m_ip_ihl_reg <= m_ip_ihl_next; + m_ip_dscp_reg <= m_ip_dscp_next; + m_ip_ecn_reg <= m_ip_ecn_next; + m_ip_length_reg <= m_ip_length_next; + m_ip_identification_reg <= m_ip_identification_next; + m_ip_flags_reg <= m_ip_flags_next; + m_ip_fragment_offset_reg <= m_ip_fragment_offset_next; + m_ip_ttl_reg <= m_ip_ttl_next; + m_ip_protocol_reg <= m_ip_protocol_next; + m_ip_header_checksum_reg <= m_ip_header_checksum_next; + m_ip_source_ip_reg <= m_ip_source_ip_next; + m_ip_dest_ip_reg <= m_ip_dest_ip_next; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_ip_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [M_COUNT-1:0] m_ip_payload_axis_tvalid_reg = {M_COUNT{1'b0}}, m_ip_payload_axis_tvalid_next; +reg m_ip_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_ip_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_ip_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_ip_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_ip_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_ip_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [M_COUNT-1:0] temp_m_ip_payload_axis_tvalid_reg = {M_COUNT{1'b0}}, temp_m_ip_payload_axis_tvalid_next; +reg temp_m_ip_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_ip_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_ip_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_ip_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_ip_payload_axis_temp_to_output; + +assign m_ip_payload_axis_tdata = {M_COUNT{m_ip_payload_axis_tdata_reg}}; +assign m_ip_payload_axis_tkeep = KEEP_ENABLE ? {M_COUNT{m_ip_payload_axis_tkeep_reg}} : {M_COUNT*KEEP_WIDTH{1'b1}}; +assign m_ip_payload_axis_tvalid = m_ip_payload_axis_tvalid_reg; +assign m_ip_payload_axis_tlast = {M_COUNT{m_ip_payload_axis_tlast_reg}}; +assign m_ip_payload_axis_tid = ID_ENABLE ? {M_COUNT{m_ip_payload_axis_tid_reg}} : {M_COUNT*ID_WIDTH{1'b0}}; +assign m_ip_payload_axis_tdest = DEST_ENABLE ? {M_COUNT{m_ip_payload_axis_tdest_reg}} : {M_COUNT*DEST_WIDTH{1'b0}}; +assign m_ip_payload_axis_tuser = USER_ENABLE ? {M_COUNT{m_ip_payload_axis_tuser_reg}} : {M_COUNT*USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_ip_payload_axis_tready_int_early = (m_ip_payload_axis_tready & m_ip_payload_axis_tvalid) || (!temp_m_ip_payload_axis_tvalid_reg && (!m_ip_payload_axis_tvalid || !m_ip_payload_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b0; + + if (m_ip_payload_axis_tready_int_reg) begin + // input is ready + if ((m_ip_payload_axis_tready & m_ip_payload_axis_tvalid) || !m_ip_payload_axis_tvalid) begin + // output is ready or currently not valid, transfer data to output + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_ip_payload_axis_tready & m_ip_payload_axis_tvalid) begin + // input is not ready, but output is ready + m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_ip_payload_axis_tvalid_reg <= {M_COUNT{1'b0}}; + m_ip_payload_axis_tready_int_reg <= 1'b0; + temp_m_ip_payload_axis_tvalid_reg <= 1'b0; + end else begin + m_ip_payload_axis_tvalid_reg <= m_ip_payload_axis_tvalid_next; + m_ip_payload_axis_tready_int_reg <= m_ip_payload_axis_tready_int_early; + temp_m_ip_payload_axis_tvalid_reg <= temp_m_ip_payload_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + m_ip_payload_axis_tkeep_reg <= m_ip_payload_axis_tkeep_int; + m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + m_ip_payload_axis_tid_reg <= m_ip_payload_axis_tid_int; + m_ip_payload_axis_tdest_reg <= m_ip_payload_axis_tdest_int; + m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; + end else if (store_ip_payload_axis_temp_to_output) begin + m_ip_payload_axis_tdata_reg <= temp_m_ip_payload_axis_tdata_reg; + m_ip_payload_axis_tkeep_reg <= temp_m_ip_payload_axis_tkeep_reg; + m_ip_payload_axis_tlast_reg <= temp_m_ip_payload_axis_tlast_reg; + m_ip_payload_axis_tid_reg <= temp_m_ip_payload_axis_tid_reg; + m_ip_payload_axis_tdest_reg <= temp_m_ip_payload_axis_tdest_reg; + m_ip_payload_axis_tuser_reg <= temp_m_ip_payload_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + temp_m_ip_payload_axis_tkeep_reg <= m_ip_payload_axis_tkeep_int; + temp_m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + temp_m_ip_payload_axis_tid_reg <= m_ip_payload_axis_tid_int; + temp_m_ip_payload_axis_tdest_reg <= m_ip_payload_axis_tdest_int; + temp_m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/ip_demux_4.v b/rtl/ip_demux_4.v deleted file mode 100644 index e45a196e1..000000000 --- a/rtl/ip_demux_4.v +++ /dev/null @@ -1,546 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * IP 4 port demultiplexer - */ -module ip_demux_4 -( - input wire clk, - input wire rst, - - /* - * IP frame input - */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [7:0] input_ip_payload_tdata, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, - - /* - * IP frame outputs - */ - output wire output_0_ip_hdr_valid, - input wire output_0_ip_hdr_ready, - output wire [47:0] output_0_eth_dest_mac, - output wire [47:0] output_0_eth_src_mac, - output wire [15:0] output_0_eth_type, - output wire [3:0] output_0_ip_version, - output wire [3:0] output_0_ip_ihl, - output wire [5:0] output_0_ip_dscp, - output wire [1:0] output_0_ip_ecn, - output wire [15:0] output_0_ip_length, - output wire [15:0] output_0_ip_identification, - output wire [2:0] output_0_ip_flags, - output wire [12:0] output_0_ip_fragment_offset, - output wire [7:0] output_0_ip_ttl, - output wire [7:0] output_0_ip_protocol, - output wire [15:0] output_0_ip_header_checksum, - output wire [31:0] output_0_ip_source_ip, - output wire [31:0] output_0_ip_dest_ip, - output wire [7:0] output_0_ip_payload_tdata, - output wire output_0_ip_payload_tvalid, - input wire output_0_ip_payload_tready, - output wire output_0_ip_payload_tlast, - output wire output_0_ip_payload_tuser, - - output wire output_1_ip_hdr_valid, - input wire output_1_ip_hdr_ready, - output wire [47:0] output_1_eth_dest_mac, - output wire [47:0] output_1_eth_src_mac, - output wire [15:0] output_1_eth_type, - output wire [3:0] output_1_ip_version, - output wire [3:0] output_1_ip_ihl, - output wire [5:0] output_1_ip_dscp, - output wire [1:0] output_1_ip_ecn, - output wire [15:0] output_1_ip_length, - output wire [15:0] output_1_ip_identification, - output wire [2:0] output_1_ip_flags, - output wire [12:0] output_1_ip_fragment_offset, - output wire [7:0] output_1_ip_ttl, - output wire [7:0] output_1_ip_protocol, - output wire [15:0] output_1_ip_header_checksum, - output wire [31:0] output_1_ip_source_ip, - output wire [31:0] output_1_ip_dest_ip, - output wire [7:0] output_1_ip_payload_tdata, - output wire output_1_ip_payload_tvalid, - input wire output_1_ip_payload_tready, - output wire output_1_ip_payload_tlast, - output wire output_1_ip_payload_tuser, - - output wire output_2_ip_hdr_valid, - input wire output_2_ip_hdr_ready, - output wire [47:0] output_2_eth_dest_mac, - output wire [47:0] output_2_eth_src_mac, - output wire [15:0] output_2_eth_type, - output wire [3:0] output_2_ip_version, - output wire [3:0] output_2_ip_ihl, - output wire [5:0] output_2_ip_dscp, - output wire [1:0] output_2_ip_ecn, - output wire [15:0] output_2_ip_length, - output wire [15:0] output_2_ip_identification, - output wire [2:0] output_2_ip_flags, - output wire [12:0] output_2_ip_fragment_offset, - output wire [7:0] output_2_ip_ttl, - output wire [7:0] output_2_ip_protocol, - output wire [15:0] output_2_ip_header_checksum, - output wire [31:0] output_2_ip_source_ip, - output wire [31:0] output_2_ip_dest_ip, - output wire [7:0] output_2_ip_payload_tdata, - output wire output_2_ip_payload_tvalid, - input wire output_2_ip_payload_tready, - output wire output_2_ip_payload_tlast, - output wire output_2_ip_payload_tuser, - - output wire output_3_ip_hdr_valid, - input wire output_3_ip_hdr_ready, - output wire [47:0] output_3_eth_dest_mac, - output wire [47:0] output_3_eth_src_mac, - output wire [15:0] output_3_eth_type, - output wire [3:0] output_3_ip_version, - output wire [3:0] output_3_ip_ihl, - output wire [5:0] output_3_ip_dscp, - output wire [1:0] output_3_ip_ecn, - output wire [15:0] output_3_ip_length, - output wire [15:0] output_3_ip_identification, - output wire [2:0] output_3_ip_flags, - output wire [12:0] output_3_ip_fragment_offset, - output wire [7:0] output_3_ip_ttl, - output wire [7:0] output_3_ip_protocol, - output wire [15:0] output_3_ip_header_checksum, - output wire [31:0] output_3_ip_source_ip, - output wire [31:0] output_3_ip_dest_ip, - output wire [7:0] output_3_ip_payload_tdata, - output wire output_3_ip_payload_tvalid, - input wire output_3_ip_payload_tready, - output wire output_3_ip_payload_tlast, - output wire output_3_ip_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; - -reg output_0_ip_hdr_valid_reg = 1'b0, output_0_ip_hdr_valid_next; -reg output_1_ip_hdr_valid_reg = 1'b0, output_1_ip_hdr_valid_next; -reg output_2_ip_hdr_valid_reg = 1'b0, output_2_ip_hdr_valid_next; -reg output_3_ip_hdr_valid_reg = 1'b0, output_3_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; - -// internal datapath -reg [7:0] output_ip_payload_tdata_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; - -assign input_ip_hdr_ready = input_ip_hdr_ready_reg; -assign input_ip_payload_tready = input_ip_payload_tready_reg; - -assign output_0_ip_hdr_valid = output_0_ip_hdr_valid_reg; -assign output_0_eth_dest_mac = output_eth_dest_mac_reg; -assign output_0_eth_src_mac = output_eth_src_mac_reg; -assign output_0_eth_type = output_eth_type_reg; -assign output_0_ip_version = output_ip_version_reg; -assign output_0_ip_ihl = output_ip_ihl_reg; -assign output_0_ip_dscp = output_ip_dscp_reg; -assign output_0_ip_ecn = output_ip_ecn_reg; -assign output_0_ip_length = output_ip_length_reg; -assign output_0_ip_identification = output_ip_identification_reg; -assign output_0_ip_flags = output_ip_flags_reg; -assign output_0_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_0_ip_ttl = output_ip_ttl_reg; -assign output_0_ip_protocol = output_ip_protocol_reg; -assign output_0_ip_header_checksum = output_ip_header_checksum_reg; -assign output_0_ip_source_ip = output_ip_source_ip_reg; -assign output_0_ip_dest_ip = output_ip_dest_ip_reg; - -assign output_1_ip_hdr_valid = output_1_ip_hdr_valid_reg; -assign output_1_eth_dest_mac = output_eth_dest_mac_reg; -assign output_1_eth_src_mac = output_eth_src_mac_reg; -assign output_1_eth_type = output_eth_type_reg; -assign output_1_ip_version = output_ip_version_reg; -assign output_1_ip_ihl = output_ip_ihl_reg; -assign output_1_ip_dscp = output_ip_dscp_reg; -assign output_1_ip_ecn = output_ip_ecn_reg; -assign output_1_ip_length = output_ip_length_reg; -assign output_1_ip_identification = output_ip_identification_reg; -assign output_1_ip_flags = output_ip_flags_reg; -assign output_1_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_1_ip_ttl = output_ip_ttl_reg; -assign output_1_ip_protocol = output_ip_protocol_reg; -assign output_1_ip_header_checksum = output_ip_header_checksum_reg; -assign output_1_ip_source_ip = output_ip_source_ip_reg; -assign output_1_ip_dest_ip = output_ip_dest_ip_reg; - -assign output_2_ip_hdr_valid = output_2_ip_hdr_valid_reg; -assign output_2_eth_dest_mac = output_eth_dest_mac_reg; -assign output_2_eth_src_mac = output_eth_src_mac_reg; -assign output_2_eth_type = output_eth_type_reg; -assign output_2_ip_version = output_ip_version_reg; -assign output_2_ip_ihl = output_ip_ihl_reg; -assign output_2_ip_dscp = output_ip_dscp_reg; -assign output_2_ip_ecn = output_ip_ecn_reg; -assign output_2_ip_length = output_ip_length_reg; -assign output_2_ip_identification = output_ip_identification_reg; -assign output_2_ip_flags = output_ip_flags_reg; -assign output_2_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_2_ip_ttl = output_ip_ttl_reg; -assign output_2_ip_protocol = output_ip_protocol_reg; -assign output_2_ip_header_checksum = output_ip_header_checksum_reg; -assign output_2_ip_source_ip = output_ip_source_ip_reg; -assign output_2_ip_dest_ip = output_ip_dest_ip_reg; - -assign output_3_ip_hdr_valid = output_3_ip_hdr_valid_reg; -assign output_3_eth_dest_mac = output_eth_dest_mac_reg; -assign output_3_eth_src_mac = output_eth_src_mac_reg; -assign output_3_eth_type = output_eth_type_reg; -assign output_3_ip_version = output_ip_version_reg; -assign output_3_ip_ihl = output_ip_ihl_reg; -assign output_3_ip_dscp = output_ip_dscp_reg; -assign output_3_ip_ecn = output_ip_ecn_reg; -assign output_3_ip_length = output_ip_length_reg; -assign output_3_ip_identification = output_ip_identification_reg; -assign output_3_ip_flags = output_ip_flags_reg; -assign output_3_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_3_ip_ttl = output_ip_ttl_reg; -assign output_3_ip_protocol = output_ip_protocol_reg; -assign output_3_ip_header_checksum = output_ip_header_checksum_reg; -assign output_3_ip_source_ip = output_ip_source_ip_reg; -assign output_3_ip_dest_ip = output_ip_dest_ip_reg; - -// mux for output control signals -reg current_output_ip_hdr_valid; -reg current_output_ip_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) - 2'd0: begin - current_output_ip_hdr_valid = output_0_ip_hdr_valid; - current_output_ip_hdr_ready = output_0_ip_hdr_ready; - current_output_tvalid = output_0_ip_payload_tvalid; - current_output_tready = output_0_ip_payload_tready; - end - 2'd1: begin - current_output_ip_hdr_valid = output_1_ip_hdr_valid; - current_output_ip_hdr_ready = output_1_ip_hdr_ready; - current_output_tvalid = output_1_ip_payload_tvalid; - current_output_tready = output_1_ip_payload_tready; - end - 2'd2: begin - current_output_ip_hdr_valid = output_2_ip_hdr_valid; - current_output_ip_hdr_ready = output_2_ip_hdr_ready; - current_output_tvalid = output_2_ip_payload_tvalid; - current_output_tready = output_2_ip_payload_tready; - end - 2'd3: begin - current_output_ip_hdr_valid = output_3_ip_hdr_valid; - current_output_ip_hdr_ready = output_3_ip_hdr_ready; - current_output_tvalid = output_3_ip_payload_tvalid; - current_output_tready = output_3_ip_payload_tready; - end - default: begin - current_output_ip_hdr_valid = 1'b0; - current_output_ip_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; - input_ip_payload_tready_next = 1'b0; - output_0_ip_hdr_valid_next = output_0_ip_hdr_valid_reg & ~output_0_ip_hdr_ready; - output_1_ip_hdr_valid_next = output_1_ip_hdr_valid_reg & ~output_1_ip_hdr_ready; - output_2_ip_hdr_valid_next = output_2_ip_hdr_valid_reg & ~output_2_ip_hdr_ready; - output_3_ip_hdr_valid_next = output_3_ip_hdr_valid_reg & ~output_3_ip_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - - if (input_ip_payload_tvalid & input_ip_payload_tready) begin - // end of frame detection - if (input_ip_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_ip_hdr_ready_next = 1'b1; - - case (select) - 2'd0: output_0_ip_hdr_valid_next = 1'b1; - 2'd1: output_1_ip_hdr_valid_next = 1'b1; - 2'd2: output_2_ip_hdr_valid_next = 1'b1; - 2'd3: output_3_ip_hdr_valid_next = 1'b1; - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - output_ip_version_next = input_ip_version; - output_ip_ihl_next = input_ip_ihl; - output_ip_dscp_next = input_ip_dscp; - output_ip_ecn_next = input_ip_ecn; - output_ip_length_next = input_ip_length; - output_ip_identification_next = input_ip_identification; - output_ip_flags_next = input_ip_flags; - output_ip_fragment_offset_next = input_ip_fragment_offset; - output_ip_ttl_next = input_ip_ttl; - output_ip_protocol_next = input_ip_protocol; - output_ip_header_checksum_next = input_ip_header_checksum; - output_ip_source_ip_next = input_ip_source_ip; - output_ip_dest_ip_next = input_ip_dest_ip; - end - - input_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - - output_ip_payload_tdata_int = input_ip_payload_tdata; - output_ip_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tready; - output_ip_payload_tlast_int = input_ip_payload_tlast; - output_ip_payload_tuser_int = input_ip_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_ip_hdr_ready_reg <= 1'b0; - input_ip_payload_tready_reg <= 1'b0; - output_0_ip_hdr_valid_reg <= 1'b0; - output_1_ip_hdr_valid_reg <= 1'b0; - output_2_ip_hdr_valid_reg <= 1'b0; - output_3_ip_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; - input_ip_payload_tready_reg <= input_ip_payload_tready_next; - output_0_ip_hdr_valid_reg <= output_0_ip_hdr_valid_next; - output_1_ip_hdr_valid_reg <= output_1_ip_hdr_valid_next; - output_2_ip_hdr_valid_reg <= output_2_ip_hdr_valid_next; - output_3_ip_hdr_valid_reg <= output_3_ip_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; -end - -// output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 8'd0; -reg output_0_ip_payload_tvalid_reg = 1'b0, output_0_ip_payload_tvalid_next; -reg output_1_ip_payload_tvalid_reg = 1'b0, output_1_ip_payload_tvalid_next; -reg output_2_ip_payload_tvalid_reg = 1'b0, output_2_ip_payload_tvalid_next; -reg output_3_ip_payload_tvalid_reg = 1'b0, output_3_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; - -reg [7:0] temp_ip_payload_tdata_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; - -// datapath control -reg store_ip_payload_int_to_output; -reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; - -assign output_0_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_0_ip_payload_tvalid = output_0_ip_payload_tvalid_reg; -assign output_0_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_0_ip_payload_tuser = output_ip_payload_tuser_reg; - -assign output_1_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_1_ip_payload_tvalid = output_1_ip_payload_tvalid_reg; -assign output_1_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_1_ip_payload_tuser = output_ip_payload_tuser_reg; - -assign output_2_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_2_ip_payload_tvalid = output_2_ip_payload_tvalid_reg; -assign output_2_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_2_ip_payload_tuser = output_ip_payload_tuser_reg; - -assign output_3_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_3_ip_payload_tvalid = output_3_ip_payload_tvalid_reg; -assign output_3_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_3_ip_payload_tuser = output_ip_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & (~current_output_tvalid | ~output_ip_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_0_ip_payload_tvalid_next = output_0_ip_payload_tvalid_reg; - output_1_ip_payload_tvalid_next = output_1_ip_payload_tvalid_reg; - output_2_ip_payload_tvalid_next = output_2_ip_payload_tvalid_reg; - output_3_ip_payload_tvalid_next = output_3_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - - store_ip_payload_int_to_output = 1'b0; - store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; - - if (output_ip_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_0_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd0); - output_1_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd1); - output_2_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd2); - output_3_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd3); - store_ip_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_0_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd0); - output_1_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd1); - output_2_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd2); - output_3_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd3); - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_0_ip_payload_tvalid_reg <= 1'b0; - output_1_ip_payload_tvalid_reg <= 1'b0; - output_2_ip_payload_tvalid_reg <= 1'b0; - output_3_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; - end else begin - output_0_ip_payload_tvalid_reg <= output_0_ip_payload_tvalid_next; - output_1_ip_payload_tvalid_reg <= output_1_ip_payload_tvalid_next; - output_2_ip_payload_tvalid_reg <= output_2_ip_payload_tvalid_next; - output_3_ip_payload_tvalid_reg <= output_3_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; - end - - // datapath - if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - - if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end -end - -endmodule diff --git a/rtl/ip_demux_64.py b/rtl/ip_demux_64.py deleted file mode 100755 index f3ed25e88..000000000 --- a/rtl/ip_demux_64.py +++ /dev/null @@ -1,444 +0,0 @@ -#!/usr/bin/env python -""" -Generates an IP demux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "ip_demux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port IP demux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * IP {{n}} port demultiplexer (64 bit datapath) - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * IP frame input - */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [63:0] input_ip_payload_tdata, - input wire [7:0] input_ip_payload_tkeep, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, - - /* - * IP frame outputs - */ -{%- for p in ports %} - output wire output_{{p}}_ip_hdr_valid, - input wire output_{{p}}_ip_hdr_ready, - output wire [47:0] output_{{p}}_eth_dest_mac, - output wire [47:0] output_{{p}}_eth_src_mac, - output wire [15:0] output_{{p}}_eth_type, - output wire [3:0] output_{{p}}_ip_version, - output wire [3:0] output_{{p}}_ip_ihl, - output wire [5:0] output_{{p}}_ip_dscp, - output wire [1:0] output_{{p}}_ip_ecn, - output wire [15:0] output_{{p}}_ip_length, - output wire [15:0] output_{{p}}_ip_identification, - output wire [2:0] output_{{p}}_ip_flags, - output wire [12:0] output_{{p}}_ip_fragment_offset, - output wire [7:0] output_{{p}}_ip_ttl, - output wire [7:0] output_{{p}}_ip_protocol, - output wire [15:0] output_{{p}}_ip_header_checksum, - output wire [31:0] output_{{p}}_ip_source_ip, - output wire [31:0] output_{{p}}_ip_dest_ip, - output wire [63:0] output_{{p}}_ip_payload_tdata, - output wire [7:0] output_{{p}}_ip_payload_tkeep, - output wire output_{{p}}_ip_payload_tvalid, - input wire output_{{p}}_ip_payload_tready, - output wire output_{{p}}_ip_payload_tlast, - output wire output_{{p}}_ip_payload_tuser, -{% endfor %} - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; -{% for p in ports %} -reg output_{{p}}_ip_hdr_valid_reg = 1'b0, output_{{p}}_ip_hdr_valid_next; -{%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; - -// internal datapath -reg [63:0] output_ip_payload_tdata_int; -reg [7:0] output_ip_payload_tkeep_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; - -assign input_ip_hdr_ready = input_ip_hdr_ready_reg; -assign input_ip_payload_tready = input_ip_payload_tready_reg; -{% for p in ports %} -assign output_{{p}}_ip_hdr_valid = output_{{p}}_ip_hdr_valid_reg; -assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; -assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; -assign output_{{p}}_eth_type = output_eth_type_reg; -assign output_{{p}}_ip_version = output_ip_version_reg; -assign output_{{p}}_ip_ihl = output_ip_ihl_reg; -assign output_{{p}}_ip_dscp = output_ip_dscp_reg; -assign output_{{p}}_ip_ecn = output_ip_ecn_reg; -assign output_{{p}}_ip_length = output_ip_length_reg; -assign output_{{p}}_ip_identification = output_ip_identification_reg; -assign output_{{p}}_ip_flags = output_ip_flags_reg; -assign output_{{p}}_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_{{p}}_ip_ttl = output_ip_ttl_reg; -assign output_{{p}}_ip_protocol = output_ip_protocol_reg; -assign output_{{p}}_ip_header_checksum = output_ip_header_checksum_reg; -assign output_{{p}}_ip_source_ip = output_ip_source_ip_reg; -assign output_{{p}}_ip_dest_ip = output_ip_dest_ip_reg; -{% endfor %} -// mux for output control signals -reg current_output_ip_hdr_valid; -reg current_output_ip_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_output_ip_hdr_valid = output_{{p}}_ip_hdr_valid; - current_output_ip_hdr_ready = output_{{p}}_ip_hdr_ready; - current_output_tvalid = output_{{p}}_ip_payload_tvalid; - current_output_tready = output_{{p}}_ip_payload_tready; - end -{%- endfor %} - default: begin - current_output_ip_hdr_valid = 1'b0; - current_output_ip_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; - input_ip_payload_tready_next = 1'b0; - -{%- for p in ports %} - output_{{p}}_ip_hdr_valid_next = output_{{p}}_ip_hdr_valid_reg & ~output_{{p}}_ip_hdr_ready; -{%- endfor %} - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - - if (input_ip_payload_tvalid & input_ip_payload_tready) begin - // end of frame detection - if (input_ip_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_ip_hdr_ready_next = 1'b1; - - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_ip_hdr_valid_next = 1'b1; -{%- endfor %} - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - output_ip_version_next = input_ip_version; - output_ip_ihl_next = input_ip_ihl; - output_ip_dscp_next = input_ip_dscp; - output_ip_ecn_next = input_ip_ecn; - output_ip_length_next = input_ip_length; - output_ip_identification_next = input_ip_identification; - output_ip_flags_next = input_ip_flags; - output_ip_fragment_offset_next = input_ip_fragment_offset; - output_ip_ttl_next = input_ip_ttl; - output_ip_protocol_next = input_ip_protocol; - output_ip_header_checksum_next = input_ip_header_checksum; - output_ip_source_ip_next = input_ip_source_ip; - output_ip_dest_ip_next = input_ip_dest_ip; - end - - input_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - - output_ip_payload_tdata_int = input_ip_payload_tdata; - output_ip_payload_tkeep_int = input_ip_payload_tkeep; - output_ip_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tready; - output_ip_payload_tlast_int = input_ip_payload_tlast; - output_ip_payload_tuser_int = input_ip_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; - input_ip_hdr_ready_reg <= 1'b0; - input_ip_payload_tready_reg <= 1'b0; -{%- for p in ports %} - output_{{p}}_ip_hdr_valid_reg <= 1'b0; -{%- endfor %} - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; - input_ip_payload_tready_reg <= input_ip_payload_tready_next; -{%- for p in ports %} - output_{{p}}_ip_hdr_valid_reg <= output_{{p}}_ip_hdr_valid_next; -{%- endfor %} - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; -end - -// output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 64'd0; -reg [7:0] output_ip_payload_tkeep_reg = 8'd0; -{%- for p in ports %} -reg output_{{p}}_ip_payload_tvalid_reg = 1'b0, output_{{p}}_ip_payload_tvalid_next; -{%- endfor %} -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; - -reg [63:0] temp_ip_payload_tdata_reg = 64'd0; -reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; - -// datapath control -reg store_ip_payload_int_to_output; -reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; -{% for p in ports %} -assign output_{{p}}_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_{{p}}_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_{{p}}_ip_payload_tvalid = output_{{p}}_ip_payload_tvalid_reg; -assign output_{{p}}_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_{{p}}_ip_payload_tuser = output_ip_payload_tuser_reg; -{% endfor %} -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & (~current_output_tvalid | ~output_ip_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source -{%- for p in ports %} - output_{{p}}_ip_payload_tvalid_next = output_{{p}}_ip_payload_tvalid_reg; -{%- endfor %} - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - - store_ip_payload_int_to_output = 1'b0; - store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; - - if (output_ip_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output -{%- for p in ports %} - output_{{p}}_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - store_ip_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready -{%- for p in ports %} - output_{{p}}_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin -{%- for p in ports %} - output_{{p}}_ip_payload_tvalid_reg <= 1'b0; -{%- endfor %} - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; - end else begin -{%- for p in ports %} - output_{{p}}_ip_payload_tvalid_reg <= output_{{p}}_ip_payload_tvalid_next; -{%- endfor %} - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; - end - - // datapath - if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - - if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/ip_demux_64_4.v b/rtl/ip_demux_64_4.v deleted file mode 100644 index b48f10e53..000000000 --- a/rtl/ip_demux_64_4.v +++ /dev/null @@ -1,562 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * IP 4 port demultiplexer (64 bit datapath) - */ -module ip_demux_64_4 -( - input wire clk, - input wire rst, - - /* - * IP frame input - */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [63:0] input_ip_payload_tdata, - input wire [7:0] input_ip_payload_tkeep, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, - - /* - * IP frame outputs - */ - output wire output_0_ip_hdr_valid, - input wire output_0_ip_hdr_ready, - output wire [47:0] output_0_eth_dest_mac, - output wire [47:0] output_0_eth_src_mac, - output wire [15:0] output_0_eth_type, - output wire [3:0] output_0_ip_version, - output wire [3:0] output_0_ip_ihl, - output wire [5:0] output_0_ip_dscp, - output wire [1:0] output_0_ip_ecn, - output wire [15:0] output_0_ip_length, - output wire [15:0] output_0_ip_identification, - output wire [2:0] output_0_ip_flags, - output wire [12:0] output_0_ip_fragment_offset, - output wire [7:0] output_0_ip_ttl, - output wire [7:0] output_0_ip_protocol, - output wire [15:0] output_0_ip_header_checksum, - output wire [31:0] output_0_ip_source_ip, - output wire [31:0] output_0_ip_dest_ip, - output wire [63:0] output_0_ip_payload_tdata, - output wire [7:0] output_0_ip_payload_tkeep, - output wire output_0_ip_payload_tvalid, - input wire output_0_ip_payload_tready, - output wire output_0_ip_payload_tlast, - output wire output_0_ip_payload_tuser, - - output wire output_1_ip_hdr_valid, - input wire output_1_ip_hdr_ready, - output wire [47:0] output_1_eth_dest_mac, - output wire [47:0] output_1_eth_src_mac, - output wire [15:0] output_1_eth_type, - output wire [3:0] output_1_ip_version, - output wire [3:0] output_1_ip_ihl, - output wire [5:0] output_1_ip_dscp, - output wire [1:0] output_1_ip_ecn, - output wire [15:0] output_1_ip_length, - output wire [15:0] output_1_ip_identification, - output wire [2:0] output_1_ip_flags, - output wire [12:0] output_1_ip_fragment_offset, - output wire [7:0] output_1_ip_ttl, - output wire [7:0] output_1_ip_protocol, - output wire [15:0] output_1_ip_header_checksum, - output wire [31:0] output_1_ip_source_ip, - output wire [31:0] output_1_ip_dest_ip, - output wire [63:0] output_1_ip_payload_tdata, - output wire [7:0] output_1_ip_payload_tkeep, - output wire output_1_ip_payload_tvalid, - input wire output_1_ip_payload_tready, - output wire output_1_ip_payload_tlast, - output wire output_1_ip_payload_tuser, - - output wire output_2_ip_hdr_valid, - input wire output_2_ip_hdr_ready, - output wire [47:0] output_2_eth_dest_mac, - output wire [47:0] output_2_eth_src_mac, - output wire [15:0] output_2_eth_type, - output wire [3:0] output_2_ip_version, - output wire [3:0] output_2_ip_ihl, - output wire [5:0] output_2_ip_dscp, - output wire [1:0] output_2_ip_ecn, - output wire [15:0] output_2_ip_length, - output wire [15:0] output_2_ip_identification, - output wire [2:0] output_2_ip_flags, - output wire [12:0] output_2_ip_fragment_offset, - output wire [7:0] output_2_ip_ttl, - output wire [7:0] output_2_ip_protocol, - output wire [15:0] output_2_ip_header_checksum, - output wire [31:0] output_2_ip_source_ip, - output wire [31:0] output_2_ip_dest_ip, - output wire [63:0] output_2_ip_payload_tdata, - output wire [7:0] output_2_ip_payload_tkeep, - output wire output_2_ip_payload_tvalid, - input wire output_2_ip_payload_tready, - output wire output_2_ip_payload_tlast, - output wire output_2_ip_payload_tuser, - - output wire output_3_ip_hdr_valid, - input wire output_3_ip_hdr_ready, - output wire [47:0] output_3_eth_dest_mac, - output wire [47:0] output_3_eth_src_mac, - output wire [15:0] output_3_eth_type, - output wire [3:0] output_3_ip_version, - output wire [3:0] output_3_ip_ihl, - output wire [5:0] output_3_ip_dscp, - output wire [1:0] output_3_ip_ecn, - output wire [15:0] output_3_ip_length, - output wire [15:0] output_3_ip_identification, - output wire [2:0] output_3_ip_flags, - output wire [12:0] output_3_ip_fragment_offset, - output wire [7:0] output_3_ip_ttl, - output wire [7:0] output_3_ip_protocol, - output wire [15:0] output_3_ip_header_checksum, - output wire [31:0] output_3_ip_source_ip, - output wire [31:0] output_3_ip_dest_ip, - output wire [63:0] output_3_ip_payload_tdata, - output wire [7:0] output_3_ip_payload_tkeep, - output wire output_3_ip_payload_tvalid, - input wire output_3_ip_payload_tready, - output wire output_3_ip_payload_tlast, - output wire output_3_ip_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; - -reg output_0_ip_hdr_valid_reg = 1'b0, output_0_ip_hdr_valid_next; -reg output_1_ip_hdr_valid_reg = 1'b0, output_1_ip_hdr_valid_next; -reg output_2_ip_hdr_valid_reg = 1'b0, output_2_ip_hdr_valid_next; -reg output_3_ip_hdr_valid_reg = 1'b0, output_3_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; - -// internal datapath -reg [63:0] output_ip_payload_tdata_int; -reg [7:0] output_ip_payload_tkeep_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; - -assign input_ip_hdr_ready = input_ip_hdr_ready_reg; -assign input_ip_payload_tready = input_ip_payload_tready_reg; - -assign output_0_ip_hdr_valid = output_0_ip_hdr_valid_reg; -assign output_0_eth_dest_mac = output_eth_dest_mac_reg; -assign output_0_eth_src_mac = output_eth_src_mac_reg; -assign output_0_eth_type = output_eth_type_reg; -assign output_0_ip_version = output_ip_version_reg; -assign output_0_ip_ihl = output_ip_ihl_reg; -assign output_0_ip_dscp = output_ip_dscp_reg; -assign output_0_ip_ecn = output_ip_ecn_reg; -assign output_0_ip_length = output_ip_length_reg; -assign output_0_ip_identification = output_ip_identification_reg; -assign output_0_ip_flags = output_ip_flags_reg; -assign output_0_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_0_ip_ttl = output_ip_ttl_reg; -assign output_0_ip_protocol = output_ip_protocol_reg; -assign output_0_ip_header_checksum = output_ip_header_checksum_reg; -assign output_0_ip_source_ip = output_ip_source_ip_reg; -assign output_0_ip_dest_ip = output_ip_dest_ip_reg; - -assign output_1_ip_hdr_valid = output_1_ip_hdr_valid_reg; -assign output_1_eth_dest_mac = output_eth_dest_mac_reg; -assign output_1_eth_src_mac = output_eth_src_mac_reg; -assign output_1_eth_type = output_eth_type_reg; -assign output_1_ip_version = output_ip_version_reg; -assign output_1_ip_ihl = output_ip_ihl_reg; -assign output_1_ip_dscp = output_ip_dscp_reg; -assign output_1_ip_ecn = output_ip_ecn_reg; -assign output_1_ip_length = output_ip_length_reg; -assign output_1_ip_identification = output_ip_identification_reg; -assign output_1_ip_flags = output_ip_flags_reg; -assign output_1_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_1_ip_ttl = output_ip_ttl_reg; -assign output_1_ip_protocol = output_ip_protocol_reg; -assign output_1_ip_header_checksum = output_ip_header_checksum_reg; -assign output_1_ip_source_ip = output_ip_source_ip_reg; -assign output_1_ip_dest_ip = output_ip_dest_ip_reg; - -assign output_2_ip_hdr_valid = output_2_ip_hdr_valid_reg; -assign output_2_eth_dest_mac = output_eth_dest_mac_reg; -assign output_2_eth_src_mac = output_eth_src_mac_reg; -assign output_2_eth_type = output_eth_type_reg; -assign output_2_ip_version = output_ip_version_reg; -assign output_2_ip_ihl = output_ip_ihl_reg; -assign output_2_ip_dscp = output_ip_dscp_reg; -assign output_2_ip_ecn = output_ip_ecn_reg; -assign output_2_ip_length = output_ip_length_reg; -assign output_2_ip_identification = output_ip_identification_reg; -assign output_2_ip_flags = output_ip_flags_reg; -assign output_2_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_2_ip_ttl = output_ip_ttl_reg; -assign output_2_ip_protocol = output_ip_protocol_reg; -assign output_2_ip_header_checksum = output_ip_header_checksum_reg; -assign output_2_ip_source_ip = output_ip_source_ip_reg; -assign output_2_ip_dest_ip = output_ip_dest_ip_reg; - -assign output_3_ip_hdr_valid = output_3_ip_hdr_valid_reg; -assign output_3_eth_dest_mac = output_eth_dest_mac_reg; -assign output_3_eth_src_mac = output_eth_src_mac_reg; -assign output_3_eth_type = output_eth_type_reg; -assign output_3_ip_version = output_ip_version_reg; -assign output_3_ip_ihl = output_ip_ihl_reg; -assign output_3_ip_dscp = output_ip_dscp_reg; -assign output_3_ip_ecn = output_ip_ecn_reg; -assign output_3_ip_length = output_ip_length_reg; -assign output_3_ip_identification = output_ip_identification_reg; -assign output_3_ip_flags = output_ip_flags_reg; -assign output_3_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_3_ip_ttl = output_ip_ttl_reg; -assign output_3_ip_protocol = output_ip_protocol_reg; -assign output_3_ip_header_checksum = output_ip_header_checksum_reg; -assign output_3_ip_source_ip = output_ip_source_ip_reg; -assign output_3_ip_dest_ip = output_ip_dest_ip_reg; - -// mux for output control signals -reg current_output_ip_hdr_valid; -reg current_output_ip_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) - 2'd0: begin - current_output_ip_hdr_valid = output_0_ip_hdr_valid; - current_output_ip_hdr_ready = output_0_ip_hdr_ready; - current_output_tvalid = output_0_ip_payload_tvalid; - current_output_tready = output_0_ip_payload_tready; - end - 2'd1: begin - current_output_ip_hdr_valid = output_1_ip_hdr_valid; - current_output_ip_hdr_ready = output_1_ip_hdr_ready; - current_output_tvalid = output_1_ip_payload_tvalid; - current_output_tready = output_1_ip_payload_tready; - end - 2'd2: begin - current_output_ip_hdr_valid = output_2_ip_hdr_valid; - current_output_ip_hdr_ready = output_2_ip_hdr_ready; - current_output_tvalid = output_2_ip_payload_tvalid; - current_output_tready = output_2_ip_payload_tready; - end - 2'd3: begin - current_output_ip_hdr_valid = output_3_ip_hdr_valid; - current_output_ip_hdr_ready = output_3_ip_hdr_ready; - current_output_tvalid = output_3_ip_payload_tvalid; - current_output_tready = output_3_ip_payload_tready; - end - default: begin - current_output_ip_hdr_valid = 1'b0; - current_output_ip_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_ip_hdr_ready_next = input_ip_hdr_ready_reg & ~input_ip_hdr_valid; - input_ip_payload_tready_next = 1'b0; - output_0_ip_hdr_valid_next = output_0_ip_hdr_valid_reg & ~output_0_ip_hdr_ready; - output_1_ip_hdr_valid_next = output_1_ip_hdr_valid_reg & ~output_1_ip_hdr_ready; - output_2_ip_hdr_valid_next = output_2_ip_hdr_valid_reg & ~output_2_ip_hdr_ready; - output_3_ip_hdr_valid_next = output_3_ip_hdr_valid_reg & ~output_3_ip_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - - if (input_ip_payload_tvalid & input_ip_payload_tready) begin - // end of frame detection - if (input_ip_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_ip_hdr_valid & ~current_output_ip_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_ip_hdr_ready_next = 1'b1; - - case (select) - 2'd0: output_0_ip_hdr_valid_next = 1'b1; - 2'd1: output_1_ip_hdr_valid_next = 1'b1; - 2'd2: output_2_ip_hdr_valid_next = 1'b1; - 2'd3: output_3_ip_hdr_valid_next = 1'b1; - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - output_ip_version_next = input_ip_version; - output_ip_ihl_next = input_ip_ihl; - output_ip_dscp_next = input_ip_dscp; - output_ip_ecn_next = input_ip_ecn; - output_ip_length_next = input_ip_length; - output_ip_identification_next = input_ip_identification; - output_ip_flags_next = input_ip_flags; - output_ip_fragment_offset_next = input_ip_fragment_offset; - output_ip_ttl_next = input_ip_ttl; - output_ip_protocol_next = input_ip_protocol; - output_ip_header_checksum_next = input_ip_header_checksum; - output_ip_source_ip_next = input_ip_source_ip; - output_ip_dest_ip_next = input_ip_dest_ip; - end - - input_ip_payload_tready_next = output_ip_payload_tready_int_early & frame_next; - - output_ip_payload_tdata_int = input_ip_payload_tdata; - output_ip_payload_tkeep_int = input_ip_payload_tkeep; - output_ip_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tready; - output_ip_payload_tlast_int = input_ip_payload_tlast; - output_ip_payload_tuser_int = input_ip_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_ip_hdr_ready_reg <= 1'b0; - input_ip_payload_tready_reg <= 1'b0; - output_0_ip_hdr_valid_reg <= 1'b0; - output_1_ip_hdr_valid_reg <= 1'b0; - output_2_ip_hdr_valid_reg <= 1'b0; - output_3_ip_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; - input_ip_payload_tready_reg <= input_ip_payload_tready_next; - output_0_ip_hdr_valid_reg <= output_0_ip_hdr_valid_next; - output_1_ip_hdr_valid_reg <= output_1_ip_hdr_valid_next; - output_2_ip_hdr_valid_reg <= output_2_ip_hdr_valid_next; - output_3_ip_hdr_valid_reg <= output_3_ip_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; -end - -// output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 64'd0; -reg [7:0] output_ip_payload_tkeep_reg = 8'd0; -reg output_0_ip_payload_tvalid_reg = 1'b0, output_0_ip_payload_tvalid_next; -reg output_1_ip_payload_tvalid_reg = 1'b0, output_1_ip_payload_tvalid_next; -reg output_2_ip_payload_tvalid_reg = 1'b0, output_2_ip_payload_tvalid_next; -reg output_3_ip_payload_tvalid_reg = 1'b0, output_3_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; - -reg [63:0] temp_ip_payload_tdata_reg = 64'd0; -reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; - -// datapath control -reg store_ip_payload_int_to_output; -reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; - -assign output_0_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_0_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_0_ip_payload_tvalid = output_0_ip_payload_tvalid_reg; -assign output_0_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_0_ip_payload_tuser = output_ip_payload_tuser_reg; - -assign output_1_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_1_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_1_ip_payload_tvalid = output_1_ip_payload_tvalid_reg; -assign output_1_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_1_ip_payload_tuser = output_ip_payload_tuser_reg; - -assign output_2_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_2_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_2_ip_payload_tvalid = output_2_ip_payload_tvalid_reg; -assign output_2_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_2_ip_payload_tuser = output_ip_payload_tuser_reg; - -assign output_3_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_3_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_3_ip_payload_tvalid = output_3_ip_payload_tvalid_reg; -assign output_3_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_3_ip_payload_tuser = output_ip_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = current_output_tready | (~temp_ip_payload_tvalid_reg & (~current_output_tvalid | ~output_ip_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_0_ip_payload_tvalid_next = output_0_ip_payload_tvalid_reg; - output_1_ip_payload_tvalid_next = output_1_ip_payload_tvalid_reg; - output_2_ip_payload_tvalid_next = output_2_ip_payload_tvalid_reg; - output_3_ip_payload_tvalid_next = output_3_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - - store_ip_payload_int_to_output = 1'b0; - store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; - - if (output_ip_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_0_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd0); - output_1_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd1); - output_2_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd2); - output_3_ip_payload_tvalid_next = output_ip_payload_tvalid_int & (select_reg == 2'd3); - store_ip_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; - store_ip_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_0_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd0); - output_1_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd1); - output_2_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd2); - output_3_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg & (select_reg == 2'd3); - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_0_ip_payload_tvalid_reg <= 1'b0; - output_1_ip_payload_tvalid_reg <= 1'b0; - output_2_ip_payload_tvalid_reg <= 1'b0; - output_3_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; - end else begin - output_0_ip_payload_tvalid_reg <= output_0_ip_payload_tvalid_next; - output_1_ip_payload_tvalid_reg <= output_1_ip_payload_tvalid_next; - output_2_ip_payload_tvalid_reg <= output_2_ip_payload_tvalid_next; - output_3_ip_payload_tvalid_reg <= output_3_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; - end - - // datapath - if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; - end - - if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end -end - -endmodule diff --git a/tb/test_ip_demux_4.py b/tb/test_ip_demux_4.py index 06c1dddcd..d4a51a1fd 100755 --- a/tb/test_ip_demux_4.py +++ b/tb/test_ip_demux_4.py @@ -28,8 +28,8 @@ import os import ip_ep -module = 'ip_demux_4' -testbench = 'test_%s' % module +module = 'ip_demux' +testbench = 'test_%s_4' % module srcs = [] @@ -42,300 +42,188 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + M_COUNT = 4 + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_ip_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_ip_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_ip_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_ip_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_0_ip_hdr_ready = Signal(bool(0)) - output_0_ip_payload_tready = Signal(bool(0)) - output_1_ip_hdr_ready = Signal(bool(0)) - output_1_ip_payload_tready = Signal(bool(0)) - output_2_ip_hdr_ready = Signal(bool(0)) - output_2_ip_payload_tready = Signal(bool(0)) - output_3_ip_hdr_ready = Signal(bool(0)) - output_3_ip_payload_tready = Signal(bool(0)) + m_ip_hdr_ready_list = [Signal(bool(0)) for i in range(M_COUNT)] + m_ip_payload_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_ip_hdr_ready = ConcatSignal(*reversed(m_ip_hdr_ready_list)) + m_ip_payload_axis_tready = ConcatSignal(*reversed(m_ip_payload_axis_tready_list)) enable = Signal(bool(0)) + drop = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) - output_0_ip_hdr_valid = Signal(bool(0)) - output_0_eth_dest_mac = Signal(intbv(0)[48:]) - output_0_eth_src_mac = Signal(intbv(0)[48:]) - output_0_eth_type = Signal(intbv(0)[16:]) - output_0_ip_version = Signal(intbv(0)[4:]) - output_0_ip_ihl = Signal(intbv(0)[4:]) - output_0_ip_dscp = Signal(intbv(0)[6:]) - output_0_ip_ecn = Signal(intbv(0)[2:]) - output_0_ip_length = Signal(intbv(0)[16:]) - output_0_ip_identification = Signal(intbv(0)[16:]) - output_0_ip_flags = Signal(intbv(0)[3:]) - output_0_ip_fragment_offset = Signal(intbv(0)[13:]) - output_0_ip_ttl = Signal(intbv(0)[8:]) - output_0_ip_protocol = Signal(intbv(0)[8:]) - output_0_ip_header_checksum = Signal(intbv(0)[16:]) - output_0_ip_source_ip = Signal(intbv(0)[32:]) - output_0_ip_dest_ip = Signal(intbv(0)[32:]) - output_0_ip_payload_tdata = Signal(intbv(0)[8:]) - output_0_ip_payload_tvalid = Signal(bool(0)) - output_0_ip_payload_tlast = Signal(bool(0)) - output_0_ip_payload_tuser = Signal(bool(0)) - output_1_ip_hdr_valid = Signal(bool(0)) - output_1_eth_dest_mac = Signal(intbv(0)[48:]) - output_1_eth_src_mac = Signal(intbv(0)[48:]) - output_1_eth_type = Signal(intbv(0)[16:]) - output_1_ip_version = Signal(intbv(0)[4:]) - output_1_ip_ihl = Signal(intbv(0)[4:]) - output_1_ip_dscp = Signal(intbv(0)[6:]) - output_1_ip_ecn = Signal(intbv(0)[2:]) - output_1_ip_length = Signal(intbv(0)[16:]) - output_1_ip_identification = Signal(intbv(0)[16:]) - output_1_ip_flags = Signal(intbv(0)[3:]) - output_1_ip_fragment_offset = Signal(intbv(0)[13:]) - output_1_ip_ttl = Signal(intbv(0)[8:]) - output_1_ip_protocol = Signal(intbv(0)[8:]) - output_1_ip_header_checksum = Signal(intbv(0)[16:]) - output_1_ip_source_ip = Signal(intbv(0)[32:]) - output_1_ip_dest_ip = Signal(intbv(0)[32:]) - output_1_ip_payload_tdata = Signal(intbv(0)[8:]) - output_1_ip_payload_tvalid = Signal(bool(0)) - output_1_ip_payload_tlast = Signal(bool(0)) - output_1_ip_payload_tuser = Signal(bool(0)) - output_2_ip_hdr_valid = Signal(bool(0)) - output_2_eth_dest_mac = Signal(intbv(0)[48:]) - output_2_eth_src_mac = Signal(intbv(0)[48:]) - output_2_eth_type = Signal(intbv(0)[16:]) - output_2_ip_version = Signal(intbv(0)[4:]) - output_2_ip_ihl = Signal(intbv(0)[4:]) - output_2_ip_dscp = Signal(intbv(0)[6:]) - output_2_ip_ecn = Signal(intbv(0)[2:]) - output_2_ip_length = Signal(intbv(0)[16:]) - output_2_ip_identification = Signal(intbv(0)[16:]) - output_2_ip_flags = Signal(intbv(0)[3:]) - output_2_ip_fragment_offset = Signal(intbv(0)[13:]) - output_2_ip_ttl = Signal(intbv(0)[8:]) - output_2_ip_protocol = Signal(intbv(0)[8:]) - output_2_ip_header_checksum = Signal(intbv(0)[16:]) - output_2_ip_source_ip = Signal(intbv(0)[32:]) - output_2_ip_dest_ip = Signal(intbv(0)[32:]) - output_2_ip_payload_tdata = Signal(intbv(0)[8:]) - output_2_ip_payload_tvalid = Signal(bool(0)) - output_2_ip_payload_tlast = Signal(bool(0)) - output_2_ip_payload_tuser = Signal(bool(0)) - output_3_ip_hdr_valid = Signal(bool(0)) - output_3_eth_dest_mac = Signal(intbv(0)[48:]) - output_3_eth_src_mac = Signal(intbv(0)[48:]) - output_3_eth_type = Signal(intbv(0)[16:]) - output_3_ip_version = Signal(intbv(0)[4:]) - output_3_ip_ihl = Signal(intbv(0)[4:]) - output_3_ip_dscp = Signal(intbv(0)[6:]) - output_3_ip_ecn = Signal(intbv(0)[2:]) - output_3_ip_length = Signal(intbv(0)[16:]) - output_3_ip_identification = Signal(intbv(0)[16:]) - output_3_ip_flags = Signal(intbv(0)[3:]) - output_3_ip_fragment_offset = Signal(intbv(0)[13:]) - output_3_ip_ttl = Signal(intbv(0)[8:]) - output_3_ip_protocol = Signal(intbv(0)[8:]) - output_3_ip_header_checksum = Signal(intbv(0)[16:]) - output_3_ip_source_ip = Signal(intbv(0)[32:]) - output_3_ip_dest_ip = Signal(intbv(0)[32:]) - output_3_ip_payload_tdata = Signal(intbv(0)[8:]) - output_3_ip_payload_tvalid = Signal(bool(0)) - output_3_ip_payload_tlast = Signal(bool(0)) - output_3_ip_payload_tuser = Signal(bool(0)) + m_ip_hdr_valid = Signal(intbv(0)[M_COUNT:]) + m_eth_dest_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_src_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_type = Signal(intbv(0)[M_COUNT*16:]) + m_ip_version = Signal(intbv(0)[M_COUNT*4:]) + m_ip_ihl = Signal(intbv(0)[M_COUNT*4:]) + m_ip_dscp = Signal(intbv(0)[M_COUNT*6:]) + m_ip_ecn = Signal(intbv(0)[M_COUNT*2:]) + m_ip_length = Signal(intbv(0)[M_COUNT*16:]) + m_ip_identification = Signal(intbv(0)[M_COUNT*16:]) + m_ip_flags = Signal(intbv(0)[M_COUNT*3:]) + m_ip_fragment_offset = Signal(intbv(0)[M_COUNT*13:]) + m_ip_ttl = Signal(intbv(0)[M_COUNT*8:]) + m_ip_protocol = Signal(intbv(0)[M_COUNT*8:]) + m_ip_header_checksum = Signal(intbv(0)[M_COUNT*16:]) + m_ip_source_ip = Signal(intbv(0)[M_COUNT*32:]) + m_ip_dest_ip = Signal(intbv(0)[M_COUNT*32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_ip_payload_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_ip_payload_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_ip_payload_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_ip_payload_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_ip_payload_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_ip_payload_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_ip_hdr_valid_list = [m_ip_hdr_valid(i) for i in range(M_COUNT)] + m_eth_dest_mac_list = [m_eth_dest_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_src_mac_list = [m_eth_src_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_type_list = [m_eth_type((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_version_list = [m_ip_version((i+1)*4, i*4) for i in range(M_COUNT)] + m_ip_ihl_list = [m_ip_ihl((i+1)*4, i*4) for i in range(M_COUNT)] + m_ip_dscp_list = [m_ip_dscp((i+1)*6, i*6) for i in range(M_COUNT)] + m_ip_ecn_list = [m_ip_ecn((i+1)*2, i*2) for i in range(M_COUNT)] + m_ip_length_list = [m_ip_length((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_identification_list = [m_ip_identification((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_flags_list = [m_ip_flags((i+1)*3, i*3) for i in range(M_COUNT)] + m_ip_fragment_offset_list = [m_ip_fragment_offset((i+1)*13, i*13) for i in range(M_COUNT)] + m_ip_ttl_list = [m_ip_ttl((i+1)*8, i*8) for i in range(M_COUNT)] + m_ip_protocol_list = [m_ip_protocol((i+1)*8, i*8) for i in range(M_COUNT)] + m_ip_header_checksum_list = [m_ip_header_checksum((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_source_ip_list = [m_ip_source_ip((i+1)*32, i*32) for i in range(M_COUNT)] + m_ip_dest_ip_list = [m_ip_dest_ip((i+1)*32, i*32) for i in range(M_COUNT)] + m_ip_payload_axis_tdata_list = [m_ip_payload_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_ip_payload_axis_tkeep_list = [m_ip_payload_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_ip_payload_axis_tvalid_list = [m_ip_payload_axis_tvalid(i) for i in range(M_COUNT)] + m_ip_payload_axis_tlast_list = [m_ip_payload_axis_tlast(i) for i in range(M_COUNT)] + m_ip_payload_axis_tid_list = [m_ip_payload_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_ip_payload_axis_tdest_list = [m_ip_payload_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_ip_payload_axis_tuser_list = [m_ip_payload_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks source_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] source = ip_ep.IPFrameSource() source_logic = source.create_logic( clk, rst, - ip_hdr_ready=input_ip_hdr_ready, - ip_hdr_valid=input_ip_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_ready=s_ip_hdr_ready, + ip_hdr_valid=s_ip_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tkeep=s_ip_payload_axis_tkeep, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=source_pause, name='source' ) - sink_0 = ip_ep.IPFrameSink() + for k in range(M_COUNT): + s = ip_ep.IPFrameSink() + p = Signal(bool(0)) - sink_0_logic = sink_0.create_logic( - clk, - rst, - ip_hdr_ready=output_0_ip_hdr_ready, - ip_hdr_valid=output_0_ip_hdr_valid, - eth_dest_mac=output_0_eth_dest_mac, - eth_src_mac=output_0_eth_src_mac, - eth_type=output_0_eth_type, - ip_version=output_0_ip_version, - ip_ihl=output_0_ip_ihl, - ip_dscp=output_0_ip_dscp, - ip_ecn=output_0_ip_ecn, - ip_length=output_0_ip_length, - ip_identification=output_0_ip_identification, - ip_flags=output_0_ip_flags, - ip_fragment_offset=output_0_ip_fragment_offset, - ip_ttl=output_0_ip_ttl, - ip_protocol=output_0_ip_protocol, - ip_header_checksum=output_0_ip_header_checksum, - ip_source_ip=output_0_ip_source_ip, - ip_dest_ip=output_0_ip_dest_ip, - ip_payload_tdata=output_0_ip_payload_tdata, - ip_payload_tvalid=output_0_ip_payload_tvalid, - ip_payload_tready=output_0_ip_payload_tready, - ip_payload_tlast=output_0_ip_payload_tlast, - ip_payload_tuser=output_0_ip_payload_tuser, - pause=sink_0_pause, - name='sink_0' - ) + sink_list.append(s) + sink_pause_list.append(p) - sink_1 = ip_ep.IPFrameSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - ip_hdr_ready=output_1_ip_hdr_ready, - ip_hdr_valid=output_1_ip_hdr_valid, - eth_dest_mac=output_1_eth_dest_mac, - eth_src_mac=output_1_eth_src_mac, - eth_type=output_1_eth_type, - ip_version=output_1_ip_version, - ip_ihl=output_1_ip_ihl, - ip_dscp=output_1_ip_dscp, - ip_ecn=output_1_ip_ecn, - ip_length=output_1_ip_length, - ip_identification=output_1_ip_identification, - ip_flags=output_1_ip_flags, - ip_fragment_offset=output_1_ip_fragment_offset, - ip_ttl=output_1_ip_ttl, - ip_protocol=output_1_ip_protocol, - ip_header_checksum=output_1_ip_header_checksum, - ip_source_ip=output_1_ip_source_ip, - ip_dest_ip=output_1_ip_dest_ip, - ip_payload_tdata=output_1_ip_payload_tdata, - ip_payload_tvalid=output_1_ip_payload_tvalid, - ip_payload_tready=output_1_ip_payload_tready, - ip_payload_tlast=output_1_ip_payload_tlast, - ip_payload_tuser=output_1_ip_payload_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = ip_ep.IPFrameSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - ip_hdr_ready=output_2_ip_hdr_ready, - ip_hdr_valid=output_2_ip_hdr_valid, - eth_dest_mac=output_2_eth_dest_mac, - eth_src_mac=output_2_eth_src_mac, - eth_type=output_2_eth_type, - ip_version=output_2_ip_version, - ip_ihl=output_2_ip_ihl, - ip_dscp=output_2_ip_dscp, - ip_ecn=output_2_ip_ecn, - ip_length=output_2_ip_length, - ip_identification=output_2_ip_identification, - ip_flags=output_2_ip_flags, - ip_fragment_offset=output_2_ip_fragment_offset, - ip_ttl=output_2_ip_ttl, - ip_protocol=output_2_ip_protocol, - ip_header_checksum=output_2_ip_header_checksum, - ip_source_ip=output_2_ip_source_ip, - ip_dest_ip=output_2_ip_dest_ip, - ip_payload_tdata=output_2_ip_payload_tdata, - ip_payload_tvalid=output_2_ip_payload_tvalid, - ip_payload_tready=output_2_ip_payload_tready, - ip_payload_tlast=output_2_ip_payload_tlast, - ip_payload_tuser=output_2_ip_payload_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = ip_ep.IPFrameSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - ip_hdr_ready=output_3_ip_hdr_ready, - ip_hdr_valid=output_3_ip_hdr_valid, - eth_dest_mac=output_3_eth_dest_mac, - eth_src_mac=output_3_eth_src_mac, - eth_type=output_3_eth_type, - ip_version=output_3_ip_version, - ip_ihl=output_3_ip_ihl, - ip_dscp=output_3_ip_dscp, - ip_ecn=output_3_ip_ecn, - ip_length=output_3_ip_length, - ip_identification=output_3_ip_identification, - ip_flags=output_3_ip_flags, - ip_fragment_offset=output_3_ip_fragment_offset, - ip_ttl=output_3_ip_ttl, - ip_protocol=output_3_ip_protocol, - ip_header_checksum=output_3_ip_header_checksum, - ip_source_ip=output_3_ip_source_ip, - ip_dest_ip=output_3_ip_dest_ip, - ip_payload_tdata=output_3_ip_payload_tdata, - ip_payload_tvalid=output_3_ip_payload_tvalid, - ip_payload_tready=output_3_ip_payload_tready, - ip_payload_tlast=output_3_ip_payload_tlast, - ip_payload_tuser=output_3_ip_payload_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + ip_hdr_ready=m_ip_hdr_ready_list[k], + ip_hdr_valid=m_ip_hdr_valid_list[k], + eth_dest_mac=m_eth_dest_mac_list[k], + eth_src_mac=m_eth_src_mac_list[k], + eth_type=m_eth_type_list[k], + ip_version=m_ip_version_list[k], + ip_ihl=m_ip_ihl_list[k], + ip_dscp=m_ip_dscp_list[k], + ip_ecn=m_ip_ecn_list[k], + ip_length=m_ip_length_list[k], + ip_identification=m_ip_identification_list[k], + ip_flags=m_ip_flags_list[k], + ip_fragment_offset=m_ip_fragment_offset_list[k], + ip_ttl=m_ip_ttl_list[k], + ip_protocol=m_ip_protocol_list[k], + ip_header_checksum=m_ip_header_checksum_list[k], + ip_source_ip=m_ip_source_ip_list[k], + ip_dest_ip=m_ip_dest_ip_list[k], + ip_payload_tdata=m_ip_payload_axis_tdata_list[k], + ip_payload_tkeep=m_ip_payload_axis_tkeep_list[k], + ip_payload_tvalid=m_ip_payload_axis_tvalid_list[k], + ip_payload_tready=m_ip_payload_axis_tready_list[k], + ip_payload_tlast=m_ip_payload_axis_tlast_list[k], + ip_payload_tuser=m_ip_payload_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -347,124 +235,62 @@ def bench(): rst=rst, current_test=current_test, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tid=s_ip_payload_axis_tid, + s_ip_payload_axis_tdest=s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_0_ip_hdr_valid=output_0_ip_hdr_valid, - output_0_ip_hdr_ready=output_0_ip_hdr_ready, - output_0_eth_dest_mac=output_0_eth_dest_mac, - output_0_eth_src_mac=output_0_eth_src_mac, - output_0_eth_type=output_0_eth_type, - output_0_ip_version=output_0_ip_version, - output_0_ip_ihl=output_0_ip_ihl, - output_0_ip_dscp=output_0_ip_dscp, - output_0_ip_ecn=output_0_ip_ecn, - output_0_ip_length=output_0_ip_length, - output_0_ip_identification=output_0_ip_identification, - output_0_ip_flags=output_0_ip_flags, - output_0_ip_fragment_offset=output_0_ip_fragment_offset, - output_0_ip_ttl=output_0_ip_ttl, - output_0_ip_protocol=output_0_ip_protocol, - output_0_ip_header_checksum=output_0_ip_header_checksum, - output_0_ip_source_ip=output_0_ip_source_ip, - output_0_ip_dest_ip=output_0_ip_dest_ip, - output_0_ip_payload_tdata=output_0_ip_payload_tdata, - output_0_ip_payload_tvalid=output_0_ip_payload_tvalid, - output_0_ip_payload_tready=output_0_ip_payload_tready, - output_0_ip_payload_tlast=output_0_ip_payload_tlast, - output_0_ip_payload_tuser=output_0_ip_payload_tuser, - output_1_ip_hdr_valid=output_1_ip_hdr_valid, - output_1_ip_hdr_ready=output_1_ip_hdr_ready, - output_1_eth_dest_mac=output_1_eth_dest_mac, - output_1_eth_src_mac=output_1_eth_src_mac, - output_1_eth_type=output_1_eth_type, - output_1_ip_version=output_1_ip_version, - output_1_ip_ihl=output_1_ip_ihl, - output_1_ip_dscp=output_1_ip_dscp, - output_1_ip_ecn=output_1_ip_ecn, - output_1_ip_length=output_1_ip_length, - output_1_ip_identification=output_1_ip_identification, - output_1_ip_flags=output_1_ip_flags, - output_1_ip_fragment_offset=output_1_ip_fragment_offset, - output_1_ip_ttl=output_1_ip_ttl, - output_1_ip_protocol=output_1_ip_protocol, - output_1_ip_header_checksum=output_1_ip_header_checksum, - output_1_ip_source_ip=output_1_ip_source_ip, - output_1_ip_dest_ip=output_1_ip_dest_ip, - output_1_ip_payload_tdata=output_1_ip_payload_tdata, - output_1_ip_payload_tvalid=output_1_ip_payload_tvalid, - output_1_ip_payload_tready=output_1_ip_payload_tready, - output_1_ip_payload_tlast=output_1_ip_payload_tlast, - output_1_ip_payload_tuser=output_1_ip_payload_tuser, - output_2_ip_hdr_valid=output_2_ip_hdr_valid, - output_2_ip_hdr_ready=output_2_ip_hdr_ready, - output_2_eth_dest_mac=output_2_eth_dest_mac, - output_2_eth_src_mac=output_2_eth_src_mac, - output_2_eth_type=output_2_eth_type, - output_2_ip_version=output_2_ip_version, - output_2_ip_ihl=output_2_ip_ihl, - output_2_ip_dscp=output_2_ip_dscp, - output_2_ip_ecn=output_2_ip_ecn, - output_2_ip_length=output_2_ip_length, - output_2_ip_identification=output_2_ip_identification, - output_2_ip_flags=output_2_ip_flags, - output_2_ip_fragment_offset=output_2_ip_fragment_offset, - output_2_ip_ttl=output_2_ip_ttl, - output_2_ip_protocol=output_2_ip_protocol, - output_2_ip_header_checksum=output_2_ip_header_checksum, - output_2_ip_source_ip=output_2_ip_source_ip, - output_2_ip_dest_ip=output_2_ip_dest_ip, - output_2_ip_payload_tdata=output_2_ip_payload_tdata, - output_2_ip_payload_tvalid=output_2_ip_payload_tvalid, - output_2_ip_payload_tready=output_2_ip_payload_tready, - output_2_ip_payload_tlast=output_2_ip_payload_tlast, - output_2_ip_payload_tuser=output_2_ip_payload_tuser, - output_3_ip_hdr_valid=output_3_ip_hdr_valid, - output_3_ip_hdr_ready=output_3_ip_hdr_ready, - output_3_eth_dest_mac=output_3_eth_dest_mac, - output_3_eth_src_mac=output_3_eth_src_mac, - output_3_eth_type=output_3_eth_type, - output_3_ip_version=output_3_ip_version, - output_3_ip_ihl=output_3_ip_ihl, - output_3_ip_dscp=output_3_ip_dscp, - output_3_ip_ecn=output_3_ip_ecn, - output_3_ip_length=output_3_ip_length, - output_3_ip_identification=output_3_ip_identification, - output_3_ip_flags=output_3_ip_flags, - output_3_ip_fragment_offset=output_3_ip_fragment_offset, - output_3_ip_ttl=output_3_ip_ttl, - output_3_ip_protocol=output_3_ip_protocol, - output_3_ip_header_checksum=output_3_ip_header_checksum, - output_3_ip_source_ip=output_3_ip_source_ip, - output_3_ip_dest_ip=output_3_ip_dest_ip, - output_3_ip_payload_tdata=output_3_ip_payload_tdata, - output_3_ip_payload_tvalid=output_3_ip_payload_tvalid, - output_3_ip_payload_tready=output_3_ip_payload_tready, - output_3_ip_payload_tlast=output_3_ip_payload_tlast, - output_3_ip_payload_tuser=output_3_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tid=m_ip_payload_axis_tid, + m_ip_payload_axis_tdest=m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, enable=enable, + drop=drop, select=select ) @@ -514,8 +340,8 @@ def bench(): source.send(test_frame) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame @@ -549,8 +375,8 @@ def bench(): source.send(test_frame) - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame @@ -604,13 +430,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame1 - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame2 @@ -665,17 +491,17 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_ip_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or s_ip_hdr_valid: yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -730,7 +556,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_ip_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or s_ip_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -739,13 +565,13 @@ def bench(): yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -800,33 +626,112 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_ip_payload_tvalid or input_ip_hdr_valid: - sink_0_pause.next = True - sink_1_pause.next = True - sink_2_pause.next = True - sink_3_pause.next = True + while s_ip_payload_axis_tvalid or s_ip_hdr_valid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_0_pause.next = False - sink_1_pause.next = False - sink_2_pause.next = False - sink_3_pause.next = False + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 yield delay(100) + yield clk.posedge + print("test 7: enable") + current_test.next = 7 + + enable.next = False + select.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + enable.next = True + + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 8: drop") + current_test.next = 8 + + drop.next = True + select.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + drop.next = False + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_ip_demux_4.v b/tb/test_ip_demux_4.v index 9f997e9bd..f5f789db1 100644 --- a/tb/test_ip_demux_4.v +++ b/tb/test_ip_demux_4.v @@ -27,137 +27,87 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for ip_demux_4 + * Testbench for ip_demux */ module test_ip_demux_4; +// Parameters +parameter M_COUNT = 4; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_ip_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [7:0] input_ip_payload_tdata = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; +reg s_ip_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [DATA_WIDTH-1:0] s_ip_payload_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_ip_payload_axis_tkeep = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_ip_payload_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_ip_payload_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_ip_payload_axis_tuser = 0; -reg output_0_ip_hdr_ready = 0; -reg output_0_ip_payload_tready = 0; -reg output_1_ip_hdr_ready = 0; -reg output_1_ip_payload_tready = 0; -reg output_2_ip_hdr_ready = 0; -reg output_2_ip_payload_tready = 0; -reg output_3_ip_hdr_ready = 0; -reg output_3_ip_payload_tready = 0; +reg [M_COUNT-1:0] m_ip_hdr_ready = 0; +reg [M_COUNT-1:0] m_ip_payload_axis_tready = 0; reg enable = 0; +reg drop = 0; reg [1:0] select = 0; // Outputs -wire input_ip_hdr_ready; -wire input_ip_payload_tready; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; -wire output_0_ip_hdr_valid; -wire [47:0] output_0_eth_dest_mac; -wire [47:0] output_0_eth_src_mac; -wire [15:0] output_0_eth_type; -wire [3:0] output_0_ip_version; -wire [3:0] output_0_ip_ihl; -wire [5:0] output_0_ip_dscp; -wire [1:0] output_0_ip_ecn; -wire [15:0] output_0_ip_length; -wire [15:0] output_0_ip_identification; -wire [2:0] output_0_ip_flags; -wire [12:0] output_0_ip_fragment_offset; -wire [7:0] output_0_ip_ttl; -wire [7:0] output_0_ip_protocol; -wire [15:0] output_0_ip_header_checksum; -wire [31:0] output_0_ip_source_ip; -wire [31:0] output_0_ip_dest_ip; -wire [7:0] output_0_ip_payload_tdata; -wire output_0_ip_payload_tvalid; -wire output_0_ip_payload_tlast; -wire output_0_ip_payload_tuser; -wire output_1_ip_hdr_valid; -wire [47:0] output_1_eth_dest_mac; -wire [47:0] output_1_eth_src_mac; -wire [15:0] output_1_eth_type; -wire [3:0] output_1_ip_version; -wire [3:0] output_1_ip_ihl; -wire [5:0] output_1_ip_dscp; -wire [1:0] output_1_ip_ecn; -wire [15:0] output_1_ip_length; -wire [15:0] output_1_ip_identification; -wire [2:0] output_1_ip_flags; -wire [12:0] output_1_ip_fragment_offset; -wire [7:0] output_1_ip_ttl; -wire [7:0] output_1_ip_protocol; -wire [15:0] output_1_ip_header_checksum; -wire [31:0] output_1_ip_source_ip; -wire [31:0] output_1_ip_dest_ip; -wire [7:0] output_1_ip_payload_tdata; -wire output_1_ip_payload_tvalid; -wire output_1_ip_payload_tlast; -wire output_1_ip_payload_tuser; -wire output_2_ip_hdr_valid; -wire [47:0] output_2_eth_dest_mac; -wire [47:0] output_2_eth_src_mac; -wire [15:0] output_2_eth_type; -wire [3:0] output_2_ip_version; -wire [3:0] output_2_ip_ihl; -wire [5:0] output_2_ip_dscp; -wire [1:0] output_2_ip_ecn; -wire [15:0] output_2_ip_length; -wire [15:0] output_2_ip_identification; -wire [2:0] output_2_ip_flags; -wire [12:0] output_2_ip_fragment_offset; -wire [7:0] output_2_ip_ttl; -wire [7:0] output_2_ip_protocol; -wire [15:0] output_2_ip_header_checksum; -wire [31:0] output_2_ip_source_ip; -wire [31:0] output_2_ip_dest_ip; -wire [7:0] output_2_ip_payload_tdata; -wire output_2_ip_payload_tvalid; -wire output_2_ip_payload_tlast; -wire output_2_ip_payload_tuser; -wire output_3_ip_hdr_valid; -wire [47:0] output_3_eth_dest_mac; -wire [47:0] output_3_eth_src_mac; -wire [15:0] output_3_eth_type; -wire [3:0] output_3_ip_version; -wire [3:0] output_3_ip_ihl; -wire [5:0] output_3_ip_dscp; -wire [1:0] output_3_ip_ecn; -wire [15:0] output_3_ip_length; -wire [15:0] output_3_ip_identification; -wire [2:0] output_3_ip_flags; -wire [12:0] output_3_ip_fragment_offset; -wire [7:0] output_3_ip_ttl; -wire [7:0] output_3_ip_protocol; -wire [15:0] output_3_ip_header_checksum; -wire [31:0] output_3_ip_source_ip; -wire [31:0] output_3_ip_dest_ip; -wire [7:0] output_3_ip_payload_tdata; -wire output_3_ip_payload_tvalid; -wire output_3_ip_payload_tlast; -wire output_3_ip_payload_tuser; +wire [M_COUNT-1:0] m_ip_hdr_valid; +wire [M_COUNT*48-1:0] m_eth_dest_mac; +wire [M_COUNT*48-1:0] m_eth_src_mac; +wire [M_COUNT*16-1:0] m_eth_type; +wire [M_COUNT*4-1:0] m_ip_version; +wire [M_COUNT*4-1:0] m_ip_ihl; +wire [M_COUNT*6-1:0] m_ip_dscp; +wire [M_COUNT*2-1:0] m_ip_ecn; +wire [M_COUNT*16-1:0] m_ip_length; +wire [M_COUNT*16-1:0] m_ip_identification; +wire [M_COUNT*3-1:0] m_ip_flags; +wire [M_COUNT*13-1:0] m_ip_fragment_offset; +wire [M_COUNT*8-1:0] m_ip_ttl; +wire [M_COUNT*8-1:0] m_ip_protocol; +wire [M_COUNT*16-1:0] m_ip_header_checksum; +wire [M_COUNT*32-1:0] m_ip_source_ip; +wire [M_COUNT*32-1:0] m_ip_dest_ip; +wire [M_COUNT*DATA_WIDTH-1:0] m_ip_payload_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep; +wire [M_COUNT-1:0] m_ip_payload_axis_tvalid; +wire [M_COUNT-1:0] m_ip_payload_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_ip_payload_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_ip_payload_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_ip_payload_axis_tuser; initial begin // myhdl integration @@ -165,125 +115,63 @@ initial begin clk, rst, current_test, - input_ip_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - output_0_ip_hdr_ready, - output_0_ip_payload_tready, - output_1_ip_hdr_ready, - output_1_ip_payload_tready, - output_2_ip_hdr_ready, - output_2_ip_payload_tready, - output_3_ip_hdr_ready, - output_3_ip_payload_tready, + s_ip_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tid, + s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready, enable, + drop, select ); $to_myhdl( - input_ip_hdr_ready, - input_ip_payload_tready, - output_0_ip_hdr_valid, - output_0_eth_dest_mac, - output_0_eth_src_mac, - output_0_eth_type, - output_0_ip_version, - output_0_ip_ihl, - output_0_ip_dscp, - output_0_ip_ecn, - output_0_ip_length, - output_0_ip_identification, - output_0_ip_flags, - output_0_ip_fragment_offset, - output_0_ip_ttl, - output_0_ip_protocol, - output_0_ip_header_checksum, - output_0_ip_source_ip, - output_0_ip_dest_ip, - output_0_ip_payload_tdata, - output_0_ip_payload_tvalid, - output_0_ip_payload_tlast, - output_0_ip_payload_tuser, - output_1_ip_hdr_valid, - output_1_eth_dest_mac, - output_1_eth_src_mac, - output_1_eth_type, - output_1_ip_version, - output_1_ip_ihl, - output_1_ip_dscp, - output_1_ip_ecn, - output_1_ip_length, - output_1_ip_identification, - output_1_ip_flags, - output_1_ip_fragment_offset, - output_1_ip_ttl, - output_1_ip_protocol, - output_1_ip_header_checksum, - output_1_ip_source_ip, - output_1_ip_dest_ip, - output_1_ip_payload_tdata, - output_1_ip_payload_tvalid, - output_1_ip_payload_tlast, - output_1_ip_payload_tuser, - output_2_ip_hdr_valid, - output_2_eth_dest_mac, - output_2_eth_src_mac, - output_2_eth_type, - output_2_ip_version, - output_2_ip_ihl, - output_2_ip_dscp, - output_2_ip_ecn, - output_2_ip_length, - output_2_ip_identification, - output_2_ip_flags, - output_2_ip_fragment_offset, - output_2_ip_ttl, - output_2_ip_protocol, - output_2_ip_header_checksum, - output_2_ip_source_ip, - output_2_ip_dest_ip, - output_2_ip_payload_tdata, - output_2_ip_payload_tvalid, - output_2_ip_payload_tlast, - output_2_ip_payload_tuser, - output_3_ip_hdr_valid, - output_3_eth_dest_mac, - output_3_eth_src_mac, - output_3_eth_type, - output_3_ip_version, - output_3_ip_ihl, - output_3_ip_dscp, - output_3_ip_ecn, - output_3_ip_length, - output_3_ip_identification, - output_3_ip_flags, - output_3_ip_fragment_offset, - output_3_ip_ttl, - output_3_ip_protocol, - output_3_ip_header_checksum, - output_3_ip_source_ip, - output_3_ip_dest_ip, - output_3_ip_payload_tdata, - output_3_ip_payload_tvalid, - output_3_ip_payload_tlast, - output_3_ip_payload_tuser + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_ip_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tid, + m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser ); // dump file @@ -291,129 +179,78 @@ initial begin $dumpvars(0, test_ip_demux_4); end -ip_demux_4 +ip_demux #( + .M_COUNT(M_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tid(s_ip_payload_axis_tid), + .s_ip_payload_axis_tdest(s_ip_payload_axis_tdest), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // IP frame outputs - .output_0_ip_hdr_valid(output_0_ip_hdr_valid), - .output_0_ip_hdr_ready(output_0_ip_hdr_ready), - .output_0_eth_dest_mac(output_0_eth_dest_mac), - .output_0_eth_src_mac(output_0_eth_src_mac), - .output_0_eth_type(output_0_eth_type), - .output_0_ip_version(output_0_ip_version), - .output_0_ip_ihl(output_0_ip_ihl), - .output_0_ip_dscp(output_0_ip_dscp), - .output_0_ip_ecn(output_0_ip_ecn), - .output_0_ip_length(output_0_ip_length), - .output_0_ip_identification(output_0_ip_identification), - .output_0_ip_flags(output_0_ip_flags), - .output_0_ip_fragment_offset(output_0_ip_fragment_offset), - .output_0_ip_ttl(output_0_ip_ttl), - .output_0_ip_protocol(output_0_ip_protocol), - .output_0_ip_header_checksum(output_0_ip_header_checksum), - .output_0_ip_source_ip(output_0_ip_source_ip), - .output_0_ip_dest_ip(output_0_ip_dest_ip), - .output_0_ip_payload_tdata(output_0_ip_payload_tdata), - .output_0_ip_payload_tvalid(output_0_ip_payload_tvalid), - .output_0_ip_payload_tready(output_0_ip_payload_tready), - .output_0_ip_payload_tlast(output_0_ip_payload_tlast), - .output_0_ip_payload_tuser(output_0_ip_payload_tuser), - .output_1_ip_hdr_valid(output_1_ip_hdr_valid), - .output_1_ip_hdr_ready(output_1_ip_hdr_ready), - .output_1_eth_dest_mac(output_1_eth_dest_mac), - .output_1_eth_src_mac(output_1_eth_src_mac), - .output_1_eth_type(output_1_eth_type), - .output_1_ip_version(output_1_ip_version), - .output_1_ip_ihl(output_1_ip_ihl), - .output_1_ip_dscp(output_1_ip_dscp), - .output_1_ip_ecn(output_1_ip_ecn), - .output_1_ip_length(output_1_ip_length), - .output_1_ip_identification(output_1_ip_identification), - .output_1_ip_flags(output_1_ip_flags), - .output_1_ip_fragment_offset(output_1_ip_fragment_offset), - .output_1_ip_ttl(output_1_ip_ttl), - .output_1_ip_protocol(output_1_ip_protocol), - .output_1_ip_header_checksum(output_1_ip_header_checksum), - .output_1_ip_source_ip(output_1_ip_source_ip), - .output_1_ip_dest_ip(output_1_ip_dest_ip), - .output_1_ip_payload_tdata(output_1_ip_payload_tdata), - .output_1_ip_payload_tvalid(output_1_ip_payload_tvalid), - .output_1_ip_payload_tready(output_1_ip_payload_tready), - .output_1_ip_payload_tlast(output_1_ip_payload_tlast), - .output_1_ip_payload_tuser(output_1_ip_payload_tuser), - .output_2_ip_hdr_valid(output_2_ip_hdr_valid), - .output_2_ip_hdr_ready(output_2_ip_hdr_ready), - .output_2_eth_dest_mac(output_2_eth_dest_mac), - .output_2_eth_src_mac(output_2_eth_src_mac), - .output_2_eth_type(output_2_eth_type), - .output_2_ip_version(output_2_ip_version), - .output_2_ip_ihl(output_2_ip_ihl), - .output_2_ip_dscp(output_2_ip_dscp), - .output_2_ip_ecn(output_2_ip_ecn), - .output_2_ip_length(output_2_ip_length), - .output_2_ip_identification(output_2_ip_identification), - .output_2_ip_flags(output_2_ip_flags), - .output_2_ip_fragment_offset(output_2_ip_fragment_offset), - .output_2_ip_ttl(output_2_ip_ttl), - .output_2_ip_protocol(output_2_ip_protocol), - .output_2_ip_header_checksum(output_2_ip_header_checksum), - .output_2_ip_source_ip(output_2_ip_source_ip), - .output_2_ip_dest_ip(output_2_ip_dest_ip), - .output_2_ip_payload_tdata(output_2_ip_payload_tdata), - .output_2_ip_payload_tvalid(output_2_ip_payload_tvalid), - .output_2_ip_payload_tready(output_2_ip_payload_tready), - .output_2_ip_payload_tlast(output_2_ip_payload_tlast), - .output_2_ip_payload_tuser(output_2_ip_payload_tuser), - .output_3_ip_hdr_valid(output_3_ip_hdr_valid), - .output_3_ip_hdr_ready(output_3_ip_hdr_ready), - .output_3_eth_dest_mac(output_3_eth_dest_mac), - .output_3_eth_src_mac(output_3_eth_src_mac), - .output_3_eth_type(output_3_eth_type), - .output_3_ip_version(output_3_ip_version), - .output_3_ip_ihl(output_3_ip_ihl), - .output_3_ip_dscp(output_3_ip_dscp), - .output_3_ip_ecn(output_3_ip_ecn), - .output_3_ip_length(output_3_ip_length), - .output_3_ip_identification(output_3_ip_identification), - .output_3_ip_flags(output_3_ip_flags), - .output_3_ip_fragment_offset(output_3_ip_fragment_offset), - .output_3_ip_ttl(output_3_ip_ttl), - .output_3_ip_protocol(output_3_ip_protocol), - .output_3_ip_header_checksum(output_3_ip_header_checksum), - .output_3_ip_source_ip(output_3_ip_source_ip), - .output_3_ip_dest_ip(output_3_ip_dest_ip), - .output_3_ip_payload_tdata(output_3_ip_payload_tdata), - .output_3_ip_payload_tvalid(output_3_ip_payload_tvalid), - .output_3_ip_payload_tready(output_3_ip_payload_tready), - .output_3_ip_payload_tlast(output_3_ip_payload_tlast), - .output_3_ip_payload_tuser(output_3_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tid(m_ip_payload_axis_tid), + .m_ip_payload_axis_tdest(m_ip_payload_axis_tdest), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Control .enable(enable), + .drop(drop), .select(select) ); diff --git a/tb/test_ip_demux_64_4.py b/tb/test_ip_demux_64_4.py index 547e7a389..166ad0fce 100755 --- a/tb/test_ip_demux_64_4.py +++ b/tb/test_ip_demux_64_4.py @@ -28,8 +28,8 @@ import os import ip_ep -module = 'ip_demux_64_4' -testbench = 'test_%s' % module +module = 'ip_demux' +testbench = 'test_%s_64_4' % module srcs = [] @@ -42,310 +42,188 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + M_COUNT = 4 + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_ip_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[64:]) - input_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_ip_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_ip_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_ip_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_0_ip_hdr_ready = Signal(bool(0)) - output_0_ip_payload_tready = Signal(bool(0)) - output_1_ip_hdr_ready = Signal(bool(0)) - output_1_ip_payload_tready = Signal(bool(0)) - output_2_ip_hdr_ready = Signal(bool(0)) - output_2_ip_payload_tready = Signal(bool(0)) - output_3_ip_hdr_ready = Signal(bool(0)) - output_3_ip_payload_tready = Signal(bool(0)) + m_ip_hdr_ready_list = [Signal(bool(0)) for i in range(M_COUNT)] + m_ip_payload_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_ip_hdr_ready = ConcatSignal(*reversed(m_ip_hdr_ready_list)) + m_ip_payload_axis_tready = ConcatSignal(*reversed(m_ip_payload_axis_tready_list)) enable = Signal(bool(0)) + drop = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) - output_0_ip_hdr_valid = Signal(bool(0)) - output_0_eth_dest_mac = Signal(intbv(0)[48:]) - output_0_eth_src_mac = Signal(intbv(0)[48:]) - output_0_eth_type = Signal(intbv(0)[16:]) - output_0_ip_version = Signal(intbv(0)[4:]) - output_0_ip_ihl = Signal(intbv(0)[4:]) - output_0_ip_dscp = Signal(intbv(0)[6:]) - output_0_ip_ecn = Signal(intbv(0)[2:]) - output_0_ip_length = Signal(intbv(0)[16:]) - output_0_ip_identification = Signal(intbv(0)[16:]) - output_0_ip_flags = Signal(intbv(0)[3:]) - output_0_ip_fragment_offset = Signal(intbv(0)[13:]) - output_0_ip_ttl = Signal(intbv(0)[8:]) - output_0_ip_protocol = Signal(intbv(0)[8:]) - output_0_ip_header_checksum = Signal(intbv(0)[16:]) - output_0_ip_source_ip = Signal(intbv(0)[32:]) - output_0_ip_dest_ip = Signal(intbv(0)[32:]) - output_0_ip_payload_tdata = Signal(intbv(0)[64:]) - output_0_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_0_ip_payload_tvalid = Signal(bool(0)) - output_0_ip_payload_tlast = Signal(bool(0)) - output_0_ip_payload_tuser = Signal(bool(0)) - output_1_ip_hdr_valid = Signal(bool(0)) - output_1_eth_dest_mac = Signal(intbv(0)[48:]) - output_1_eth_src_mac = Signal(intbv(0)[48:]) - output_1_eth_type = Signal(intbv(0)[16:]) - output_1_ip_version = Signal(intbv(0)[4:]) - output_1_ip_ihl = Signal(intbv(0)[4:]) - output_1_ip_dscp = Signal(intbv(0)[6:]) - output_1_ip_ecn = Signal(intbv(0)[2:]) - output_1_ip_length = Signal(intbv(0)[16:]) - output_1_ip_identification = Signal(intbv(0)[16:]) - output_1_ip_flags = Signal(intbv(0)[3:]) - output_1_ip_fragment_offset = Signal(intbv(0)[13:]) - output_1_ip_ttl = Signal(intbv(0)[8:]) - output_1_ip_protocol = Signal(intbv(0)[8:]) - output_1_ip_header_checksum = Signal(intbv(0)[16:]) - output_1_ip_source_ip = Signal(intbv(0)[32:]) - output_1_ip_dest_ip = Signal(intbv(0)[32:]) - output_1_ip_payload_tdata = Signal(intbv(0)[64:]) - output_1_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_1_ip_payload_tvalid = Signal(bool(0)) - output_1_ip_payload_tlast = Signal(bool(0)) - output_1_ip_payload_tuser = Signal(bool(0)) - output_2_ip_hdr_valid = Signal(bool(0)) - output_2_eth_dest_mac = Signal(intbv(0)[48:]) - output_2_eth_src_mac = Signal(intbv(0)[48:]) - output_2_eth_type = Signal(intbv(0)[16:]) - output_2_ip_version = Signal(intbv(0)[4:]) - output_2_ip_ihl = Signal(intbv(0)[4:]) - output_2_ip_dscp = Signal(intbv(0)[6:]) - output_2_ip_ecn = Signal(intbv(0)[2:]) - output_2_ip_length = Signal(intbv(0)[16:]) - output_2_ip_identification = Signal(intbv(0)[16:]) - output_2_ip_flags = Signal(intbv(0)[3:]) - output_2_ip_fragment_offset = Signal(intbv(0)[13:]) - output_2_ip_ttl = Signal(intbv(0)[8:]) - output_2_ip_protocol = Signal(intbv(0)[8:]) - output_2_ip_header_checksum = Signal(intbv(0)[16:]) - output_2_ip_source_ip = Signal(intbv(0)[32:]) - output_2_ip_dest_ip = Signal(intbv(0)[32:]) - output_2_ip_payload_tdata = Signal(intbv(0)[64:]) - output_2_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_2_ip_payload_tvalid = Signal(bool(0)) - output_2_ip_payload_tlast = Signal(bool(0)) - output_2_ip_payload_tuser = Signal(bool(0)) - output_3_ip_hdr_valid = Signal(bool(0)) - output_3_eth_dest_mac = Signal(intbv(0)[48:]) - output_3_eth_src_mac = Signal(intbv(0)[48:]) - output_3_eth_type = Signal(intbv(0)[16:]) - output_3_ip_version = Signal(intbv(0)[4:]) - output_3_ip_ihl = Signal(intbv(0)[4:]) - output_3_ip_dscp = Signal(intbv(0)[6:]) - output_3_ip_ecn = Signal(intbv(0)[2:]) - output_3_ip_length = Signal(intbv(0)[16:]) - output_3_ip_identification = Signal(intbv(0)[16:]) - output_3_ip_flags = Signal(intbv(0)[3:]) - output_3_ip_fragment_offset = Signal(intbv(0)[13:]) - output_3_ip_ttl = Signal(intbv(0)[8:]) - output_3_ip_protocol = Signal(intbv(0)[8:]) - output_3_ip_header_checksum = Signal(intbv(0)[16:]) - output_3_ip_source_ip = Signal(intbv(0)[32:]) - output_3_ip_dest_ip = Signal(intbv(0)[32:]) - output_3_ip_payload_tdata = Signal(intbv(0)[64:]) - output_3_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_3_ip_payload_tvalid = Signal(bool(0)) - output_3_ip_payload_tlast = Signal(bool(0)) - output_3_ip_payload_tuser = Signal(bool(0)) + m_ip_hdr_valid = Signal(intbv(0)[M_COUNT:]) + m_eth_dest_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_src_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_type = Signal(intbv(0)[M_COUNT*16:]) + m_ip_version = Signal(intbv(0)[M_COUNT*4:]) + m_ip_ihl = Signal(intbv(0)[M_COUNT*4:]) + m_ip_dscp = Signal(intbv(0)[M_COUNT*6:]) + m_ip_ecn = Signal(intbv(0)[M_COUNT*2:]) + m_ip_length = Signal(intbv(0)[M_COUNT*16:]) + m_ip_identification = Signal(intbv(0)[M_COUNT*16:]) + m_ip_flags = Signal(intbv(0)[M_COUNT*3:]) + m_ip_fragment_offset = Signal(intbv(0)[M_COUNT*13:]) + m_ip_ttl = Signal(intbv(0)[M_COUNT*8:]) + m_ip_protocol = Signal(intbv(0)[M_COUNT*8:]) + m_ip_header_checksum = Signal(intbv(0)[M_COUNT*16:]) + m_ip_source_ip = Signal(intbv(0)[M_COUNT*32:]) + m_ip_dest_ip = Signal(intbv(0)[M_COUNT*32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_ip_payload_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_ip_payload_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_ip_payload_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_ip_payload_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_ip_payload_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_ip_payload_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_ip_hdr_valid_list = [m_ip_hdr_valid(i) for i in range(M_COUNT)] + m_eth_dest_mac_list = [m_eth_dest_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_src_mac_list = [m_eth_src_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_type_list = [m_eth_type((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_version_list = [m_ip_version((i+1)*4, i*4) for i in range(M_COUNT)] + m_ip_ihl_list = [m_ip_ihl((i+1)*4, i*4) for i in range(M_COUNT)] + m_ip_dscp_list = [m_ip_dscp((i+1)*6, i*6) for i in range(M_COUNT)] + m_ip_ecn_list = [m_ip_ecn((i+1)*2, i*2) for i in range(M_COUNT)] + m_ip_length_list = [m_ip_length((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_identification_list = [m_ip_identification((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_flags_list = [m_ip_flags((i+1)*3, i*3) for i in range(M_COUNT)] + m_ip_fragment_offset_list = [m_ip_fragment_offset((i+1)*13, i*13) for i in range(M_COUNT)] + m_ip_ttl_list = [m_ip_ttl((i+1)*8, i*8) for i in range(M_COUNT)] + m_ip_protocol_list = [m_ip_protocol((i+1)*8, i*8) for i in range(M_COUNT)] + m_ip_header_checksum_list = [m_ip_header_checksum((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_source_ip_list = [m_ip_source_ip((i+1)*32, i*32) for i in range(M_COUNT)] + m_ip_dest_ip_list = [m_ip_dest_ip((i+1)*32, i*32) for i in range(M_COUNT)] + m_ip_payload_axis_tdata_list = [m_ip_payload_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_ip_payload_axis_tkeep_list = [m_ip_payload_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_ip_payload_axis_tvalid_list = [m_ip_payload_axis_tvalid(i) for i in range(M_COUNT)] + m_ip_payload_axis_tlast_list = [m_ip_payload_axis_tlast(i) for i in range(M_COUNT)] + m_ip_payload_axis_tid_list = [m_ip_payload_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_ip_payload_axis_tdest_list = [m_ip_payload_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_ip_payload_axis_tuser_list = [m_ip_payload_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks source_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] source = ip_ep.IPFrameSource() source_logic = source.create_logic( clk, rst, - ip_hdr_ready=input_ip_hdr_ready, - ip_hdr_valid=input_ip_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tkeep=input_ip_payload_tkeep, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_ready=s_ip_hdr_ready, + ip_hdr_valid=s_ip_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tkeep=s_ip_payload_axis_tkeep, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=source_pause, name='source' ) - sink_0 = ip_ep.IPFrameSink() + for k in range(M_COUNT): + s = ip_ep.IPFrameSink() + p = Signal(bool(0)) - sink_0_logic = sink_0.create_logic( - clk, - rst, - ip_hdr_ready=output_0_ip_hdr_ready, - ip_hdr_valid=output_0_ip_hdr_valid, - eth_dest_mac=output_0_eth_dest_mac, - eth_src_mac=output_0_eth_src_mac, - eth_type=output_0_eth_type, - ip_version=output_0_ip_version, - ip_ihl=output_0_ip_ihl, - ip_dscp=output_0_ip_dscp, - ip_ecn=output_0_ip_ecn, - ip_length=output_0_ip_length, - ip_identification=output_0_ip_identification, - ip_flags=output_0_ip_flags, - ip_fragment_offset=output_0_ip_fragment_offset, - ip_ttl=output_0_ip_ttl, - ip_protocol=output_0_ip_protocol, - ip_header_checksum=output_0_ip_header_checksum, - ip_source_ip=output_0_ip_source_ip, - ip_dest_ip=output_0_ip_dest_ip, - ip_payload_tdata=output_0_ip_payload_tdata, - ip_payload_tkeep=output_0_ip_payload_tkeep, - ip_payload_tvalid=output_0_ip_payload_tvalid, - ip_payload_tready=output_0_ip_payload_tready, - ip_payload_tlast=output_0_ip_payload_tlast, - ip_payload_tuser=output_0_ip_payload_tuser, - pause=sink_0_pause, - name='sink_0' - ) + sink_list.append(s) + sink_pause_list.append(p) - sink_1 = ip_ep.IPFrameSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - ip_hdr_ready=output_1_ip_hdr_ready, - ip_hdr_valid=output_1_ip_hdr_valid, - eth_dest_mac=output_1_eth_dest_mac, - eth_src_mac=output_1_eth_src_mac, - eth_type=output_1_eth_type, - ip_version=output_1_ip_version, - ip_ihl=output_1_ip_ihl, - ip_dscp=output_1_ip_dscp, - ip_ecn=output_1_ip_ecn, - ip_length=output_1_ip_length, - ip_identification=output_1_ip_identification, - ip_flags=output_1_ip_flags, - ip_fragment_offset=output_1_ip_fragment_offset, - ip_ttl=output_1_ip_ttl, - ip_protocol=output_1_ip_protocol, - ip_header_checksum=output_1_ip_header_checksum, - ip_source_ip=output_1_ip_source_ip, - ip_dest_ip=output_1_ip_dest_ip, - ip_payload_tdata=output_1_ip_payload_tdata, - ip_payload_tkeep=output_1_ip_payload_tkeep, - ip_payload_tvalid=output_1_ip_payload_tvalid, - ip_payload_tready=output_1_ip_payload_tready, - ip_payload_tlast=output_1_ip_payload_tlast, - ip_payload_tuser=output_1_ip_payload_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = ip_ep.IPFrameSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - ip_hdr_ready=output_2_ip_hdr_ready, - ip_hdr_valid=output_2_ip_hdr_valid, - eth_dest_mac=output_2_eth_dest_mac, - eth_src_mac=output_2_eth_src_mac, - eth_type=output_2_eth_type, - ip_version=output_2_ip_version, - ip_ihl=output_2_ip_ihl, - ip_dscp=output_2_ip_dscp, - ip_ecn=output_2_ip_ecn, - ip_length=output_2_ip_length, - ip_identification=output_2_ip_identification, - ip_flags=output_2_ip_flags, - ip_fragment_offset=output_2_ip_fragment_offset, - ip_ttl=output_2_ip_ttl, - ip_protocol=output_2_ip_protocol, - ip_header_checksum=output_2_ip_header_checksum, - ip_source_ip=output_2_ip_source_ip, - ip_dest_ip=output_2_ip_dest_ip, - ip_payload_tdata=output_2_ip_payload_tdata, - ip_payload_tkeep=output_2_ip_payload_tkeep, - ip_payload_tvalid=output_2_ip_payload_tvalid, - ip_payload_tready=output_2_ip_payload_tready, - ip_payload_tlast=output_2_ip_payload_tlast, - ip_payload_tuser=output_2_ip_payload_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = ip_ep.IPFrameSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - ip_hdr_ready=output_3_ip_hdr_ready, - ip_hdr_valid=output_3_ip_hdr_valid, - eth_dest_mac=output_3_eth_dest_mac, - eth_src_mac=output_3_eth_src_mac, - eth_type=output_3_eth_type, - ip_version=output_3_ip_version, - ip_ihl=output_3_ip_ihl, - ip_dscp=output_3_ip_dscp, - ip_ecn=output_3_ip_ecn, - ip_length=output_3_ip_length, - ip_identification=output_3_ip_identification, - ip_flags=output_3_ip_flags, - ip_fragment_offset=output_3_ip_fragment_offset, - ip_ttl=output_3_ip_ttl, - ip_protocol=output_3_ip_protocol, - ip_header_checksum=output_3_ip_header_checksum, - ip_source_ip=output_3_ip_source_ip, - ip_dest_ip=output_3_ip_dest_ip, - ip_payload_tdata=output_3_ip_payload_tdata, - ip_payload_tkeep=output_3_ip_payload_tkeep, - ip_payload_tvalid=output_3_ip_payload_tvalid, - ip_payload_tready=output_3_ip_payload_tready, - ip_payload_tlast=output_3_ip_payload_tlast, - ip_payload_tuser=output_3_ip_payload_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + ip_hdr_ready=m_ip_hdr_ready_list[k], + ip_hdr_valid=m_ip_hdr_valid_list[k], + eth_dest_mac=m_eth_dest_mac_list[k], + eth_src_mac=m_eth_src_mac_list[k], + eth_type=m_eth_type_list[k], + ip_version=m_ip_version_list[k], + ip_ihl=m_ip_ihl_list[k], + ip_dscp=m_ip_dscp_list[k], + ip_ecn=m_ip_ecn_list[k], + ip_length=m_ip_length_list[k], + ip_identification=m_ip_identification_list[k], + ip_flags=m_ip_flags_list[k], + ip_fragment_offset=m_ip_fragment_offset_list[k], + ip_ttl=m_ip_ttl_list[k], + ip_protocol=m_ip_protocol_list[k], + ip_header_checksum=m_ip_header_checksum_list[k], + ip_source_ip=m_ip_source_ip_list[k], + ip_dest_ip=m_ip_dest_ip_list[k], + ip_payload_tdata=m_ip_payload_axis_tdata_list[k], + ip_payload_tkeep=m_ip_payload_axis_tkeep_list[k], + ip_payload_tvalid=m_ip_payload_axis_tvalid_list[k], + ip_payload_tready=m_ip_payload_axis_tready_list[k], + ip_payload_tlast=m_ip_payload_axis_tlast_list[k], + ip_payload_tuser=m_ip_payload_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -357,129 +235,62 @@ def bench(): rst=rst, current_test=current_test, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tkeep=input_ip_payload_tkeep, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tid=s_ip_payload_axis_tid, + s_ip_payload_axis_tdest=s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_0_ip_hdr_valid=output_0_ip_hdr_valid, - output_0_ip_hdr_ready=output_0_ip_hdr_ready, - output_0_eth_dest_mac=output_0_eth_dest_mac, - output_0_eth_src_mac=output_0_eth_src_mac, - output_0_eth_type=output_0_eth_type, - output_0_ip_version=output_0_ip_version, - output_0_ip_ihl=output_0_ip_ihl, - output_0_ip_dscp=output_0_ip_dscp, - output_0_ip_ecn=output_0_ip_ecn, - output_0_ip_length=output_0_ip_length, - output_0_ip_identification=output_0_ip_identification, - output_0_ip_flags=output_0_ip_flags, - output_0_ip_fragment_offset=output_0_ip_fragment_offset, - output_0_ip_ttl=output_0_ip_ttl, - output_0_ip_protocol=output_0_ip_protocol, - output_0_ip_header_checksum=output_0_ip_header_checksum, - output_0_ip_source_ip=output_0_ip_source_ip, - output_0_ip_dest_ip=output_0_ip_dest_ip, - output_0_ip_payload_tdata=output_0_ip_payload_tdata, - output_0_ip_payload_tkeep=output_0_ip_payload_tkeep, - output_0_ip_payload_tvalid=output_0_ip_payload_tvalid, - output_0_ip_payload_tready=output_0_ip_payload_tready, - output_0_ip_payload_tlast=output_0_ip_payload_tlast, - output_0_ip_payload_tuser=output_0_ip_payload_tuser, - output_1_ip_hdr_valid=output_1_ip_hdr_valid, - output_1_ip_hdr_ready=output_1_ip_hdr_ready, - output_1_eth_dest_mac=output_1_eth_dest_mac, - output_1_eth_src_mac=output_1_eth_src_mac, - output_1_eth_type=output_1_eth_type, - output_1_ip_version=output_1_ip_version, - output_1_ip_ihl=output_1_ip_ihl, - output_1_ip_dscp=output_1_ip_dscp, - output_1_ip_ecn=output_1_ip_ecn, - output_1_ip_length=output_1_ip_length, - output_1_ip_identification=output_1_ip_identification, - output_1_ip_flags=output_1_ip_flags, - output_1_ip_fragment_offset=output_1_ip_fragment_offset, - output_1_ip_ttl=output_1_ip_ttl, - output_1_ip_protocol=output_1_ip_protocol, - output_1_ip_header_checksum=output_1_ip_header_checksum, - output_1_ip_source_ip=output_1_ip_source_ip, - output_1_ip_dest_ip=output_1_ip_dest_ip, - output_1_ip_payload_tdata=output_1_ip_payload_tdata, - output_1_ip_payload_tkeep=output_1_ip_payload_tkeep, - output_1_ip_payload_tvalid=output_1_ip_payload_tvalid, - output_1_ip_payload_tready=output_1_ip_payload_tready, - output_1_ip_payload_tlast=output_1_ip_payload_tlast, - output_1_ip_payload_tuser=output_1_ip_payload_tuser, - output_2_ip_hdr_valid=output_2_ip_hdr_valid, - output_2_ip_hdr_ready=output_2_ip_hdr_ready, - output_2_eth_dest_mac=output_2_eth_dest_mac, - output_2_eth_src_mac=output_2_eth_src_mac, - output_2_eth_type=output_2_eth_type, - output_2_ip_version=output_2_ip_version, - output_2_ip_ihl=output_2_ip_ihl, - output_2_ip_dscp=output_2_ip_dscp, - output_2_ip_ecn=output_2_ip_ecn, - output_2_ip_length=output_2_ip_length, - output_2_ip_identification=output_2_ip_identification, - output_2_ip_flags=output_2_ip_flags, - output_2_ip_fragment_offset=output_2_ip_fragment_offset, - output_2_ip_ttl=output_2_ip_ttl, - output_2_ip_protocol=output_2_ip_protocol, - output_2_ip_header_checksum=output_2_ip_header_checksum, - output_2_ip_source_ip=output_2_ip_source_ip, - output_2_ip_dest_ip=output_2_ip_dest_ip, - output_2_ip_payload_tdata=output_2_ip_payload_tdata, - output_2_ip_payload_tkeep=output_2_ip_payload_tkeep, - output_2_ip_payload_tvalid=output_2_ip_payload_tvalid, - output_2_ip_payload_tready=output_2_ip_payload_tready, - output_2_ip_payload_tlast=output_2_ip_payload_tlast, - output_2_ip_payload_tuser=output_2_ip_payload_tuser, - output_3_ip_hdr_valid=output_3_ip_hdr_valid, - output_3_ip_hdr_ready=output_3_ip_hdr_ready, - output_3_eth_dest_mac=output_3_eth_dest_mac, - output_3_eth_src_mac=output_3_eth_src_mac, - output_3_eth_type=output_3_eth_type, - output_3_ip_version=output_3_ip_version, - output_3_ip_ihl=output_3_ip_ihl, - output_3_ip_dscp=output_3_ip_dscp, - output_3_ip_ecn=output_3_ip_ecn, - output_3_ip_length=output_3_ip_length, - output_3_ip_identification=output_3_ip_identification, - output_3_ip_flags=output_3_ip_flags, - output_3_ip_fragment_offset=output_3_ip_fragment_offset, - output_3_ip_ttl=output_3_ip_ttl, - output_3_ip_protocol=output_3_ip_protocol, - output_3_ip_header_checksum=output_3_ip_header_checksum, - output_3_ip_source_ip=output_3_ip_source_ip, - output_3_ip_dest_ip=output_3_ip_dest_ip, - output_3_ip_payload_tdata=output_3_ip_payload_tdata, - output_3_ip_payload_tkeep=output_3_ip_payload_tkeep, - output_3_ip_payload_tvalid=output_3_ip_payload_tvalid, - output_3_ip_payload_tready=output_3_ip_payload_tready, - output_3_ip_payload_tlast=output_3_ip_payload_tlast, - output_3_ip_payload_tuser=output_3_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tid=m_ip_payload_axis_tid, + m_ip_payload_axis_tdest=m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, enable=enable, + drop=drop, select=select ) @@ -529,8 +340,8 @@ def bench(): source.send(test_frame) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame @@ -564,8 +375,8 @@ def bench(): source.send(test_frame) - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame @@ -619,13 +430,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame1 - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame2 @@ -680,17 +491,17 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_ip_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or s_ip_hdr_valid: yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -745,7 +556,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_ip_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or s_ip_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -754,13 +565,13 @@ def bench(): yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -815,33 +626,112 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_ip_payload_tvalid or input_ip_hdr_valid: - sink_0_pause.next = True - sink_1_pause.next = True - sink_2_pause.next = True - sink_3_pause.next = True + while s_ip_payload_axis_tvalid or s_ip_hdr_valid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_0_pause.next = False - sink_1_pause.next = False - sink_2_pause.next = False - sink_3_pause.next = False + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 yield delay(100) + yield clk.posedge + print("test 7: enable") + current_test.next = 7 + + enable.next = False + select.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + enable.next = True + + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 8: drop") + current_test.next = 8 + + drop.next = True + select.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + drop.next = False + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_ip_demux_64_4.v b/tb/test_ip_demux_64_4.v index af66e4573..eba7dfdd7 100644 --- a/tb/test_ip_demux_64_4.v +++ b/tb/test_ip_demux_64_4.v @@ -27,142 +27,87 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for ip_demux_64_4 + * Testbench for ip_demux */ module test_ip_demux_64_4; +// Parameters +parameter M_COUNT = 4; +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_ip_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [63:0] input_ip_payload_tdata = 0; -reg [7:0] input_ip_payload_tkeep = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; +reg s_ip_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [DATA_WIDTH-1:0] s_ip_payload_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_ip_payload_axis_tkeep = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_ip_payload_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_ip_payload_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_ip_payload_axis_tuser = 0; -reg output_0_ip_hdr_ready = 0; -reg output_0_ip_payload_tready = 0; -reg output_1_ip_hdr_ready = 0; -reg output_1_ip_payload_tready = 0; -reg output_2_ip_hdr_ready = 0; -reg output_2_ip_payload_tready = 0; -reg output_3_ip_hdr_ready = 0; -reg output_3_ip_payload_tready = 0; +reg [M_COUNT-1:0] m_ip_hdr_ready = 0; +reg [M_COUNT-1:0] m_ip_payload_axis_tready = 0; reg enable = 0; +reg drop = 0; reg [1:0] select = 0; // Outputs -wire input_ip_hdr_ready; -wire input_ip_payload_tready; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; -wire output_0_ip_hdr_valid; -wire [47:0] output_0_eth_dest_mac; -wire [47:0] output_0_eth_src_mac; -wire [15:0] output_0_eth_type; -wire [3:0] output_0_ip_version; -wire [3:0] output_0_ip_ihl; -wire [5:0] output_0_ip_dscp; -wire [1:0] output_0_ip_ecn; -wire [15:0] output_0_ip_length; -wire [15:0] output_0_ip_identification; -wire [2:0] output_0_ip_flags; -wire [12:0] output_0_ip_fragment_offset; -wire [7:0] output_0_ip_ttl; -wire [7:0] output_0_ip_protocol; -wire [15:0] output_0_ip_header_checksum; -wire [31:0] output_0_ip_source_ip; -wire [31:0] output_0_ip_dest_ip; -wire [63:0] output_0_ip_payload_tdata; -wire [7:0] output_0_ip_payload_tkeep; -wire output_0_ip_payload_tvalid; -wire output_0_ip_payload_tlast; -wire output_0_ip_payload_tuser; -wire output_1_ip_hdr_valid; -wire [47:0] output_1_eth_dest_mac; -wire [47:0] output_1_eth_src_mac; -wire [15:0] output_1_eth_type; -wire [3:0] output_1_ip_version; -wire [3:0] output_1_ip_ihl; -wire [5:0] output_1_ip_dscp; -wire [1:0] output_1_ip_ecn; -wire [15:0] output_1_ip_length; -wire [15:0] output_1_ip_identification; -wire [2:0] output_1_ip_flags; -wire [12:0] output_1_ip_fragment_offset; -wire [7:0] output_1_ip_ttl; -wire [7:0] output_1_ip_protocol; -wire [15:0] output_1_ip_header_checksum; -wire [31:0] output_1_ip_source_ip; -wire [31:0] output_1_ip_dest_ip; -wire [63:0] output_1_ip_payload_tdata; -wire [7:0] output_1_ip_payload_tkeep; -wire output_1_ip_payload_tvalid; -wire output_1_ip_payload_tlast; -wire output_1_ip_payload_tuser; -wire output_2_ip_hdr_valid; -wire [47:0] output_2_eth_dest_mac; -wire [47:0] output_2_eth_src_mac; -wire [15:0] output_2_eth_type; -wire [3:0] output_2_ip_version; -wire [3:0] output_2_ip_ihl; -wire [5:0] output_2_ip_dscp; -wire [1:0] output_2_ip_ecn; -wire [15:0] output_2_ip_length; -wire [15:0] output_2_ip_identification; -wire [2:0] output_2_ip_flags; -wire [12:0] output_2_ip_fragment_offset; -wire [7:0] output_2_ip_ttl; -wire [7:0] output_2_ip_protocol; -wire [15:0] output_2_ip_header_checksum; -wire [31:0] output_2_ip_source_ip; -wire [31:0] output_2_ip_dest_ip; -wire [63:0] output_2_ip_payload_tdata; -wire [7:0] output_2_ip_payload_tkeep; -wire output_2_ip_payload_tvalid; -wire output_2_ip_payload_tlast; -wire output_2_ip_payload_tuser; -wire output_3_ip_hdr_valid; -wire [47:0] output_3_eth_dest_mac; -wire [47:0] output_3_eth_src_mac; -wire [15:0] output_3_eth_type; -wire [3:0] output_3_ip_version; -wire [3:0] output_3_ip_ihl; -wire [5:0] output_3_ip_dscp; -wire [1:0] output_3_ip_ecn; -wire [15:0] output_3_ip_length; -wire [15:0] output_3_ip_identification; -wire [2:0] output_3_ip_flags; -wire [12:0] output_3_ip_fragment_offset; -wire [7:0] output_3_ip_ttl; -wire [7:0] output_3_ip_protocol; -wire [15:0] output_3_ip_header_checksum; -wire [31:0] output_3_ip_source_ip; -wire [31:0] output_3_ip_dest_ip; -wire [63:0] output_3_ip_payload_tdata; -wire [7:0] output_3_ip_payload_tkeep; -wire output_3_ip_payload_tvalid; -wire output_3_ip_payload_tlast; -wire output_3_ip_payload_tuser; +wire [M_COUNT-1:0] m_ip_hdr_valid; +wire [M_COUNT*48-1:0] m_eth_dest_mac; +wire [M_COUNT*48-1:0] m_eth_src_mac; +wire [M_COUNT*16-1:0] m_eth_type; +wire [M_COUNT*4-1:0] m_ip_version; +wire [M_COUNT*4-1:0] m_ip_ihl; +wire [M_COUNT*6-1:0] m_ip_dscp; +wire [M_COUNT*2-1:0] m_ip_ecn; +wire [M_COUNT*16-1:0] m_ip_length; +wire [M_COUNT*16-1:0] m_ip_identification; +wire [M_COUNT*3-1:0] m_ip_flags; +wire [M_COUNT*13-1:0] m_ip_fragment_offset; +wire [M_COUNT*8-1:0] m_ip_ttl; +wire [M_COUNT*8-1:0] m_ip_protocol; +wire [M_COUNT*16-1:0] m_ip_header_checksum; +wire [M_COUNT*32-1:0] m_ip_source_ip; +wire [M_COUNT*32-1:0] m_ip_dest_ip; +wire [M_COUNT*DATA_WIDTH-1:0] m_ip_payload_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_ip_payload_axis_tkeep; +wire [M_COUNT-1:0] m_ip_payload_axis_tvalid; +wire [M_COUNT-1:0] m_ip_payload_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_ip_payload_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_ip_payload_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_ip_payload_axis_tuser; initial begin // myhdl integration @@ -170,130 +115,63 @@ initial begin clk, rst, current_test, - input_ip_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tkeep, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - output_0_ip_hdr_ready, - output_0_ip_payload_tready, - output_1_ip_hdr_ready, - output_1_ip_payload_tready, - output_2_ip_hdr_ready, - output_2_ip_payload_tready, - output_3_ip_hdr_ready, - output_3_ip_payload_tready, + s_ip_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tid, + s_ip_payload_axis_tdest, + s_ip_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready, enable, + drop, select ); $to_myhdl( - input_ip_hdr_ready, - input_ip_payload_tready, - output_0_ip_hdr_valid, - output_0_eth_dest_mac, - output_0_eth_src_mac, - output_0_eth_type, - output_0_ip_version, - output_0_ip_ihl, - output_0_ip_dscp, - output_0_ip_ecn, - output_0_ip_length, - output_0_ip_identification, - output_0_ip_flags, - output_0_ip_fragment_offset, - output_0_ip_ttl, - output_0_ip_protocol, - output_0_ip_header_checksum, - output_0_ip_source_ip, - output_0_ip_dest_ip, - output_0_ip_payload_tdata, - output_0_ip_payload_tkeep, - output_0_ip_payload_tvalid, - output_0_ip_payload_tlast, - output_0_ip_payload_tuser, - output_1_ip_hdr_valid, - output_1_eth_dest_mac, - output_1_eth_src_mac, - output_1_eth_type, - output_1_ip_version, - output_1_ip_ihl, - output_1_ip_dscp, - output_1_ip_ecn, - output_1_ip_length, - output_1_ip_identification, - output_1_ip_flags, - output_1_ip_fragment_offset, - output_1_ip_ttl, - output_1_ip_protocol, - output_1_ip_header_checksum, - output_1_ip_source_ip, - output_1_ip_dest_ip, - output_1_ip_payload_tdata, - output_1_ip_payload_tkeep, - output_1_ip_payload_tvalid, - output_1_ip_payload_tlast, - output_1_ip_payload_tuser, - output_2_ip_hdr_valid, - output_2_eth_dest_mac, - output_2_eth_src_mac, - output_2_eth_type, - output_2_ip_version, - output_2_ip_ihl, - output_2_ip_dscp, - output_2_ip_ecn, - output_2_ip_length, - output_2_ip_identification, - output_2_ip_flags, - output_2_ip_fragment_offset, - output_2_ip_ttl, - output_2_ip_protocol, - output_2_ip_header_checksum, - output_2_ip_source_ip, - output_2_ip_dest_ip, - output_2_ip_payload_tdata, - output_2_ip_payload_tkeep, - output_2_ip_payload_tvalid, - output_2_ip_payload_tlast, - output_2_ip_payload_tuser, - output_3_ip_hdr_valid, - output_3_eth_dest_mac, - output_3_eth_src_mac, - output_3_eth_type, - output_3_ip_version, - output_3_ip_ihl, - output_3_ip_dscp, - output_3_ip_ecn, - output_3_ip_length, - output_3_ip_identification, - output_3_ip_flags, - output_3_ip_fragment_offset, - output_3_ip_ttl, - output_3_ip_protocol, - output_3_ip_header_checksum, - output_3_ip_source_ip, - output_3_ip_dest_ip, - output_3_ip_payload_tdata, - output_3_ip_payload_tkeep, - output_3_ip_payload_tvalid, - output_3_ip_payload_tlast, - output_3_ip_payload_tuser + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_ip_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tid, + m_ip_payload_axis_tdest, + m_ip_payload_axis_tuser ); // dump file @@ -301,134 +179,78 @@ initial begin $dumpvars(0, test_ip_demux_64_4); end -ip_demux_64_4 +ip_demux #( + .M_COUNT(M_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tkeep(input_ip_payload_tkeep), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tid(s_ip_payload_axis_tid), + .s_ip_payload_axis_tdest(s_ip_payload_axis_tdest), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // IP frame outputs - .output_0_ip_hdr_valid(output_0_ip_hdr_valid), - .output_0_ip_hdr_ready(output_0_ip_hdr_ready), - .output_0_eth_dest_mac(output_0_eth_dest_mac), - .output_0_eth_src_mac(output_0_eth_src_mac), - .output_0_eth_type(output_0_eth_type), - .output_0_ip_version(output_0_ip_version), - .output_0_ip_ihl(output_0_ip_ihl), - .output_0_ip_dscp(output_0_ip_dscp), - .output_0_ip_ecn(output_0_ip_ecn), - .output_0_ip_length(output_0_ip_length), - .output_0_ip_identification(output_0_ip_identification), - .output_0_ip_flags(output_0_ip_flags), - .output_0_ip_fragment_offset(output_0_ip_fragment_offset), - .output_0_ip_ttl(output_0_ip_ttl), - .output_0_ip_protocol(output_0_ip_protocol), - .output_0_ip_header_checksum(output_0_ip_header_checksum), - .output_0_ip_source_ip(output_0_ip_source_ip), - .output_0_ip_dest_ip(output_0_ip_dest_ip), - .output_0_ip_payload_tdata(output_0_ip_payload_tdata), - .output_0_ip_payload_tkeep(output_0_ip_payload_tkeep), - .output_0_ip_payload_tvalid(output_0_ip_payload_tvalid), - .output_0_ip_payload_tready(output_0_ip_payload_tready), - .output_0_ip_payload_tlast(output_0_ip_payload_tlast), - .output_0_ip_payload_tuser(output_0_ip_payload_tuser), - .output_1_ip_hdr_valid(output_1_ip_hdr_valid), - .output_1_ip_hdr_ready(output_1_ip_hdr_ready), - .output_1_eth_dest_mac(output_1_eth_dest_mac), - .output_1_eth_src_mac(output_1_eth_src_mac), - .output_1_eth_type(output_1_eth_type), - .output_1_ip_version(output_1_ip_version), - .output_1_ip_ihl(output_1_ip_ihl), - .output_1_ip_dscp(output_1_ip_dscp), - .output_1_ip_ecn(output_1_ip_ecn), - .output_1_ip_length(output_1_ip_length), - .output_1_ip_identification(output_1_ip_identification), - .output_1_ip_flags(output_1_ip_flags), - .output_1_ip_fragment_offset(output_1_ip_fragment_offset), - .output_1_ip_ttl(output_1_ip_ttl), - .output_1_ip_protocol(output_1_ip_protocol), - .output_1_ip_header_checksum(output_1_ip_header_checksum), - .output_1_ip_source_ip(output_1_ip_source_ip), - .output_1_ip_dest_ip(output_1_ip_dest_ip), - .output_1_ip_payload_tdata(output_1_ip_payload_tdata), - .output_1_ip_payload_tkeep(output_1_ip_payload_tkeep), - .output_1_ip_payload_tvalid(output_1_ip_payload_tvalid), - .output_1_ip_payload_tready(output_1_ip_payload_tready), - .output_1_ip_payload_tlast(output_1_ip_payload_tlast), - .output_1_ip_payload_tuser(output_1_ip_payload_tuser), - .output_2_ip_hdr_valid(output_2_ip_hdr_valid), - .output_2_ip_hdr_ready(output_2_ip_hdr_ready), - .output_2_eth_dest_mac(output_2_eth_dest_mac), - .output_2_eth_src_mac(output_2_eth_src_mac), - .output_2_eth_type(output_2_eth_type), - .output_2_ip_version(output_2_ip_version), - .output_2_ip_ihl(output_2_ip_ihl), - .output_2_ip_dscp(output_2_ip_dscp), - .output_2_ip_ecn(output_2_ip_ecn), - .output_2_ip_length(output_2_ip_length), - .output_2_ip_identification(output_2_ip_identification), - .output_2_ip_flags(output_2_ip_flags), - .output_2_ip_fragment_offset(output_2_ip_fragment_offset), - .output_2_ip_ttl(output_2_ip_ttl), - .output_2_ip_protocol(output_2_ip_protocol), - .output_2_ip_header_checksum(output_2_ip_header_checksum), - .output_2_ip_source_ip(output_2_ip_source_ip), - .output_2_ip_dest_ip(output_2_ip_dest_ip), - .output_2_ip_payload_tdata(output_2_ip_payload_tdata), - .output_2_ip_payload_tkeep(output_2_ip_payload_tkeep), - .output_2_ip_payload_tvalid(output_2_ip_payload_tvalid), - .output_2_ip_payload_tready(output_2_ip_payload_tready), - .output_2_ip_payload_tlast(output_2_ip_payload_tlast), - .output_2_ip_payload_tuser(output_2_ip_payload_tuser), - .output_3_ip_hdr_valid(output_3_ip_hdr_valid), - .output_3_ip_hdr_ready(output_3_ip_hdr_ready), - .output_3_eth_dest_mac(output_3_eth_dest_mac), - .output_3_eth_src_mac(output_3_eth_src_mac), - .output_3_eth_type(output_3_eth_type), - .output_3_ip_version(output_3_ip_version), - .output_3_ip_ihl(output_3_ip_ihl), - .output_3_ip_dscp(output_3_ip_dscp), - .output_3_ip_ecn(output_3_ip_ecn), - .output_3_ip_length(output_3_ip_length), - .output_3_ip_identification(output_3_ip_identification), - .output_3_ip_flags(output_3_ip_flags), - .output_3_ip_fragment_offset(output_3_ip_fragment_offset), - .output_3_ip_ttl(output_3_ip_ttl), - .output_3_ip_protocol(output_3_ip_protocol), - .output_3_ip_header_checksum(output_3_ip_header_checksum), - .output_3_ip_source_ip(output_3_ip_source_ip), - .output_3_ip_dest_ip(output_3_ip_dest_ip), - .output_3_ip_payload_tdata(output_3_ip_payload_tdata), - .output_3_ip_payload_tkeep(output_3_ip_payload_tkeep), - .output_3_ip_payload_tvalid(output_3_ip_payload_tvalid), - .output_3_ip_payload_tready(output_3_ip_payload_tready), - .output_3_ip_payload_tlast(output_3_ip_payload_tlast), - .output_3_ip_payload_tuser(output_3_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tid(m_ip_payload_axis_tid), + .m_ip_payload_axis_tdest(m_ip_payload_axis_tdest), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Control .enable(enable), + .drop(drop), .select(select) ); From 98fc042489beab19978b7bb0d80ed36594cb634c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 2 Nov 2018 00:39:52 -0700 Subject: [PATCH 466/617] Convert generated udp_demux to verilog parametrized module --- rtl/udp_demux.py | 462 --------------------- rtl/udp_demux.v | 424 +++++++++++++++++++ rtl/udp_demux_4.v | 598 --------------------------- rtl/udp_demux_64.py | 472 --------------------- rtl/udp_demux_64_4.v | 614 --------------------------- tb/test_udp_demux_4.py | 831 ++++++++++++++++--------------------- tb/test_udp_demux_4.v | 615 ++++++++++----------------- tb/test_udp_demux_64_4.py | 846 ++++++++++++++++---------------------- tb/test_udp_demux_64_4.v | 630 ++++++++++------------------ 9 files changed, 1552 insertions(+), 3940 deletions(-) delete mode 100755 rtl/udp_demux.py create mode 100644 rtl/udp_demux.v delete mode 100644 rtl/udp_demux_4.v delete mode 100755 rtl/udp_demux_64.py delete mode 100644 rtl/udp_demux_64_4.v diff --git a/rtl/udp_demux.py b/rtl/udp_demux.py deleted file mode 100755 index f5684dcd0..000000000 --- a/rtl/udp_demux.py +++ /dev/null @@ -1,462 +0,0 @@ -#!/usr/bin/env python -""" -Generates a UDP demux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "udp_demux_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port UDP demux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * UDP {{n}} port demultiplexer - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * UDP frame input - */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [15:0] input_udp_length, - input wire [15:0] input_udp_checksum, - input wire [7:0] input_udp_payload_tdata, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, - - /* - * UDP frame outputs - */ -{%- for p in ports %} - output wire output_{{p}}_udp_hdr_valid, - input wire output_{{p}}_udp_hdr_ready, - output wire [47:0] output_{{p}}_eth_dest_mac, - output wire [47:0] output_{{p}}_eth_src_mac, - output wire [15:0] output_{{p}}_eth_type, - output wire [3:0] output_{{p}}_ip_version, - output wire [3:0] output_{{p}}_ip_ihl, - output wire [5:0] output_{{p}}_ip_dscp, - output wire [1:0] output_{{p}}_ip_ecn, - output wire [15:0] output_{{p}}_ip_length, - output wire [15:0] output_{{p}}_ip_identification, - output wire [2:0] output_{{p}}_ip_flags, - output wire [12:0] output_{{p}}_ip_fragment_offset, - output wire [7:0] output_{{p}}_ip_ttl, - output wire [7:0] output_{{p}}_ip_protocol, - output wire [15:0] output_{{p}}_ip_header_checksum, - output wire [31:0] output_{{p}}_ip_source_ip, - output wire [31:0] output_{{p}}_ip_dest_ip, - output wire [15:0] output_{{p}}_udp_source_port, - output wire [15:0] output_{{p}}_udp_dest_port, - output wire [15:0] output_{{p}}_udp_length, - output wire [15:0] output_{{p}}_udp_checksum, - output wire [7:0] output_{{p}}_udp_payload_tdata, - output wire output_{{p}}_udp_payload_tvalid, - input wire output_{{p}}_udp_payload_tready, - output wire output_{{p}}_udp_payload_tlast, - output wire output_{{p}}_udp_payload_tuser, -{% endfor %} - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; -{% for p in ports %} -reg output_{{p}}_udp_hdr_valid_reg = 1'b0, output_{{p}}_udp_hdr_valid_next; -{%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; - -// internal datapath -reg [7:0] output_udp_payload_tdata_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int_reg = 1'b0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; - -assign input_udp_hdr_ready = input_udp_hdr_ready_reg; -assign input_udp_payload_tready = input_udp_payload_tready_reg; -{% for p in ports %} -assign output_{{p}}_udp_hdr_valid = output_{{p}}_udp_hdr_valid_reg; -assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; -assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; -assign output_{{p}}_eth_type = output_eth_type_reg; -assign output_{{p}}_ip_version = output_ip_version_reg; -assign output_{{p}}_ip_ihl = output_ip_ihl_reg; -assign output_{{p}}_ip_dscp = output_ip_dscp_reg; -assign output_{{p}}_ip_ecn = output_ip_ecn_reg; -assign output_{{p}}_ip_length = output_ip_length_reg; -assign output_{{p}}_ip_identification = output_ip_identification_reg; -assign output_{{p}}_ip_flags = output_ip_flags_reg; -assign output_{{p}}_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_{{p}}_ip_ttl = output_ip_ttl_reg; -assign output_{{p}}_ip_protocol = output_ip_protocol_reg; -assign output_{{p}}_ip_header_checksum = output_ip_header_checksum_reg; -assign output_{{p}}_ip_source_ip = output_ip_source_ip_reg; -assign output_{{p}}_ip_dest_ip = output_ip_dest_ip_reg; -assign output_{{p}}_udp_source_port = output_udp_source_port_reg; -assign output_{{p}}_udp_dest_port = output_udp_dest_port_reg; -assign output_{{p}}_udp_length = output_udp_length_reg; -assign output_{{p}}_udp_checksum = output_udp_checksum_reg; -{% endfor %} -// mux for output control signals -reg current_output_udp_hdr_valid; -reg current_output_udp_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_output_udp_hdr_valid = output_{{p}}_udp_hdr_valid; - current_output_udp_hdr_ready = output_{{p}}_udp_hdr_ready; - current_output_tvalid = output_{{p}}_udp_payload_tvalid; - current_output_tready = output_{{p}}_udp_payload_tready; - end -{%- endfor %} - default: begin - current_output_udp_hdr_valid = 1'b0; - current_output_udp_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; - input_udp_payload_tready_next = 1'b0; - -{%- for p in ports %} - output_{{p}}_udp_hdr_valid_next = output_{{p}}_udp_hdr_valid_reg & ~output_{{p}}_udp_hdr_ready; -{%- endfor %} - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - output_udp_source_port_next = output_udp_source_port_reg; - output_udp_dest_port_next = output_udp_dest_port_reg; - output_udp_length_next = output_udp_length_reg; - output_udp_checksum_next = output_udp_checksum_reg; - - if (input_udp_payload_tvalid & input_udp_payload_tready) begin - // end of frame detection - if (input_udp_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_udp_hdr_ready_next = 1'b1; - - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_udp_hdr_valid_next = 1'b1; -{%- endfor %} - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - output_ip_version_next = input_ip_version; - output_ip_ihl_next = input_ip_ihl; - output_ip_dscp_next = input_ip_dscp; - output_ip_ecn_next = input_ip_ecn; - output_ip_length_next = input_ip_length; - output_ip_identification_next = input_ip_identification; - output_ip_flags_next = input_ip_flags; - output_ip_fragment_offset_next = input_ip_fragment_offset; - output_ip_ttl_next = input_ip_ttl; - output_ip_protocol_next = input_ip_protocol; - output_ip_header_checksum_next = input_ip_header_checksum; - output_ip_source_ip_next = input_ip_source_ip; - output_ip_dest_ip_next = input_ip_dest_ip; - output_udp_source_port_next = input_udp_source_port; - output_udp_dest_port_next = input_udp_dest_port; - output_udp_length_next = input_udp_length; - output_udp_checksum_next = input_udp_checksum; - end - - input_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - - output_udp_payload_tdata_int = input_udp_payload_tdata; - output_udp_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tready; - output_udp_payload_tlast_int = input_udp_payload_tlast; - output_udp_payload_tuser_int = input_udp_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; - input_udp_hdr_ready_reg <= 1'b0; - input_udp_payload_tready_reg <= 1'b0; -{%- for p in ports %} - output_{{p}}_udp_hdr_valid_reg <= 1'b0; -{%- endfor %} - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; - input_udp_payload_tready_reg <= input_udp_payload_tready_next; -{%- for p in ports %} - output_{{p}}_udp_hdr_valid_reg <= output_{{p}}_udp_hdr_valid_next; -{%- endfor %} - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; -end - -// output datapath logic -reg [7:0] output_udp_payload_tdata_reg = 8'd0; -{%- for p in ports %} -reg output_{{p}}_udp_payload_tvalid_reg = 1'b0, output_{{p}}_udp_payload_tvalid_next; -{%- endfor %} -reg output_udp_payload_tlast_reg = 1'b0; -reg output_udp_payload_tuser_reg = 1'b0; - -reg [7:0] temp_udp_payload_tdata_reg = 8'd0; -reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; -reg temp_udp_payload_tlast_reg = 1'b0; -reg temp_udp_payload_tuser_reg = 1'b0; - -// datapath control -reg store_udp_payload_int_to_output; -reg store_udp_payload_int_to_temp; -reg store_udp_payload_temp_to_output; -{% for p in ports %} -assign output_{{p}}_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_{{p}}_udp_payload_tvalid = output_{{p}}_udp_payload_tvalid_reg; -assign output_{{p}}_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_{{p}}_udp_payload_tuser = output_udp_payload_tuser_reg; -{% endfor %} -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & (~current_output_tvalid | ~output_udp_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source -{%- for p in ports %} - output_{{p}}_udp_payload_tvalid_next = output_{{p}}_udp_payload_tvalid_reg; -{%- endfor %} - temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - - store_udp_payload_int_to_output = 1'b0; - store_udp_payload_int_to_temp = 1'b0; - store_udp_payload_temp_to_output = 1'b0; - - if (output_udp_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output -{%- for p in ports %} - output_{{p}}_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - store_udp_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready -{%- for p in ports %} - output_{{p}}_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - temp_udp_payload_tvalid_next = 1'b0; - store_udp_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin -{%- for p in ports %} - output_{{p}}_udp_payload_tvalid_reg <= 1'b0; -{%- endfor %} - output_udp_payload_tready_int_reg <= 1'b0; - temp_udp_payload_tvalid_reg <= 1'b0; - end else begin -{%- for p in ports %} - output_{{p}}_udp_payload_tvalid_reg <= output_{{p}}_udp_payload_tvalid_next; -{%- endfor %} - output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; - temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; - end - - // datapath - if (store_udp_payload_int_to_output) begin - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else if (store_udp_payload_temp_to_output) begin - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - end - - if (store_udp_payload_int_to_temp) begin - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/udp_demux.v b/rtl/udp_demux.v new file mode 100644 index 000000000..f4dfb8cc9 --- /dev/null +++ b/rtl/udp_demux.v @@ -0,0 +1,424 @@ +/* + +Copyright (c) 2018 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 + +/* + * UDP demultiplexer + */ +module udp_demux # +( + parameter M_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * UDP frame input + */ + input wire s_udp_hdr_valid, + output wire s_udp_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [3:0] s_ip_version, + input wire [3:0] s_ip_ihl, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [15:0] s_ip_header_checksum, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [15:0] s_udp_source_port, + input wire [15:0] s_udp_dest_port, + input wire [15:0] s_udp_length, + input wire [15:0] s_udp_checksum, + input wire [DATA_WIDTH-1:0] s_udp_payload_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_udp_payload_axis_tkeep, + input wire s_udp_payload_axis_tvalid, + output wire s_udp_payload_axis_tready, + input wire s_udp_payload_axis_tlast, + input wire [ID_WIDTH-1:0] s_udp_payload_axis_tid, + input wire [DEST_WIDTH-1:0] s_udp_payload_axis_tdest, + input wire [USER_WIDTH-1:0] s_udp_payload_axis_tuser, + + /* + * UDP frame outputs + */ + output wire [M_COUNT-1:0] m_udp_hdr_valid, + input wire [M_COUNT-1:0] m_udp_hdr_ready, + output wire [M_COUNT*48-1:0] m_eth_dest_mac, + output wire [M_COUNT*48-1:0] m_eth_src_mac, + output wire [M_COUNT*16-1:0] m_eth_type, + output wire [M_COUNT*4-1:0] m_ip_version, + output wire [M_COUNT*4-1:0] m_ip_ihl, + output wire [M_COUNT*6-1:0] m_ip_dscp, + output wire [M_COUNT*2-1:0] m_ip_ecn, + output wire [M_COUNT*16-1:0] m_ip_length, + output wire [M_COUNT*16-1:0] m_ip_identification, + output wire [M_COUNT*3-1:0] m_ip_flags, + output wire [M_COUNT*13-1:0] m_ip_fragment_offset, + output wire [M_COUNT*8-1:0] m_ip_ttl, + output wire [M_COUNT*8-1:0] m_ip_protocol, + output wire [M_COUNT*16-1:0] m_ip_header_checksum, + output wire [M_COUNT*32-1:0] m_ip_source_ip, + output wire [M_COUNT*32-1:0] m_ip_dest_ip, + output wire [M_COUNT*16-1:0] m_udp_source_port, + output wire [M_COUNT*16-1:0] m_udp_dest_port, + output wire [M_COUNT*16-1:0] m_udp_length, + output wire [M_COUNT*16-1:0] m_udp_checksum, + output wire [M_COUNT*DATA_WIDTH-1:0] m_udp_payload_axis_tdata, + output wire [M_COUNT*KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep, + output wire [M_COUNT-1:0] m_udp_payload_axis_tvalid, + input wire [M_COUNT-1:0] m_udp_payload_axis_tready, + output wire [M_COUNT-1:0] m_udp_payload_axis_tlast, + output wire [M_COUNT*ID_WIDTH-1:0] m_udp_payload_axis_tid, + output wire [M_COUNT*DEST_WIDTH-1:0] m_udp_payload_axis_tdest, + output wire [M_COUNT*USER_WIDTH-1:0] m_udp_payload_axis_tuser, + + /* + * Control + */ + input wire enable, + input wire drop, + input wire [$clog2(M_COUNT)-1:0] select +); + +parameter CL_M_COUNT = $clog2(M_COUNT); + +reg [CL_M_COUNT-1:0] select_reg = {CL_M_COUNT{1'b0}}, select_ctl, select_next; +reg drop_reg = 1'b0, drop_ctl, drop_next; +reg frame_reg = 1'b0, frame_ctl, frame_next; + +reg s_udp_hdr_ready_reg = 1'b0, s_udp_hdr_ready_next; + +reg s_udp_payload_axis_tready_reg = 1'b0, s_udp_payload_axis_tready_next; + +reg [M_COUNT-1:0] m_udp_hdr_valid_reg = 0, m_udp_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0, m_eth_dest_mac_next; +reg [47:0] m_eth_src_mac_reg = 48'd0, m_eth_src_mac_next; +reg [15:0] m_eth_type_reg = 16'd0, m_eth_type_next; +reg [3:0] m_ip_version_reg = 4'd0, m_ip_version_next; +reg [3:0] m_ip_ihl_reg = 4'd0, m_ip_ihl_next; +reg [5:0] m_ip_dscp_reg = 6'd0, m_ip_dscp_next; +reg [1:0] m_ip_ecn_reg = 2'd0, m_ip_ecn_next; +reg [15:0] m_ip_length_reg = 16'd0, m_ip_length_next; +reg [15:0] m_ip_identification_reg = 16'd0, m_ip_identification_next; +reg [2:0] m_ip_flags_reg = 3'd0, m_ip_flags_next; +reg [12:0] m_ip_fragment_offset_reg = 13'd0, m_ip_fragment_offset_next; +reg [7:0] m_ip_ttl_reg = 8'd0, m_ip_ttl_next; +reg [7:0] m_ip_protocol_reg = 8'd0, m_ip_protocol_next; +reg [15:0] m_ip_header_checksum_reg = 16'd0, m_ip_header_checksum_next; +reg [31:0] m_ip_source_ip_reg = 32'd0, m_ip_source_ip_next; +reg [31:0] m_ip_dest_ip_reg = 32'd0, m_ip_dest_ip_next; +reg [15:0] m_udp_source_port_reg = 16'd0, m_udp_source_port_next; +reg [15:0] m_udp_dest_port_reg = 16'd0, m_udp_dest_port_next; +reg [15:0] m_udp_length_reg = 16'd0, m_udp_length_next; +reg [15:0] m_udp_checksum_reg = 16'd0, m_udp_checksum_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_udp_payload_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep_int; +reg [M_COUNT-1:0] m_udp_payload_axis_tvalid_int; +reg m_udp_payload_axis_tready_int_reg = 1'b0; +reg m_udp_payload_axis_tlast_int; +reg [ID_WIDTH-1:0] m_udp_payload_axis_tid_int; +reg [DEST_WIDTH-1:0] m_udp_payload_axis_tdest_int; +reg [USER_WIDTH-1:0] m_udp_payload_axis_tuser_int; +wire m_udp_payload_axis_tready_int_early; + +assign s_udp_hdr_ready = s_udp_hdr_ready_reg && enable; + +assign s_udp_payload_axis_tready = s_udp_payload_axis_tready_reg && enable; + +assign m_udp_hdr_valid = m_udp_hdr_valid_reg; +assign m_eth_dest_mac = {M_COUNT{m_eth_dest_mac_reg}}; +assign m_eth_src_mac = {M_COUNT{m_eth_src_mac_reg}}; +assign m_eth_type = {M_COUNT{m_eth_type_reg}}; +assign m_ip_version = {M_COUNT{m_ip_version_reg}}; +assign m_ip_ihl = {M_COUNT{m_ip_ihl_reg}}; +assign m_ip_dscp = {M_COUNT{m_ip_dscp_reg}}; +assign m_ip_ecn = {M_COUNT{m_ip_ecn_reg}}; +assign m_ip_length = {M_COUNT{m_ip_length_reg}}; +assign m_ip_identification = {M_COUNT{m_ip_identification_reg}}; +assign m_ip_flags = {M_COUNT{m_ip_flags_reg}}; +assign m_ip_fragment_offset = {M_COUNT{m_ip_fragment_offset_reg}}; +assign m_ip_ttl = {M_COUNT{m_ip_ttl_reg}}; +assign m_ip_protocol = {M_COUNT{m_ip_protocol_reg}}; +assign m_ip_header_checksum = {M_COUNT{m_ip_header_checksum_reg}}; +assign m_ip_source_ip = {M_COUNT{m_ip_source_ip_reg}}; +assign m_ip_dest_ip = {M_COUNT{m_ip_dest_ip_reg}}; +assign m_udp_source_port = {M_COUNT{m_udp_source_port_reg}}; +assign m_udp_dest_port = {M_COUNT{m_udp_dest_port_reg}}; +assign m_udp_length = {M_COUNT{m_udp_length_reg}}; +assign m_udp_checksum = {M_COUNT{m_udp_checksum_reg}}; + +integer i; + +always @* begin + select_next = select_reg; + select_ctl = select_reg; + drop_next = drop_reg; + drop_ctl = drop_reg; + frame_next = frame_reg; + frame_ctl = frame_reg; + + s_udp_hdr_ready_next = 1'b0; + + s_udp_payload_axis_tready_next = 1'b0; + + m_udp_hdr_valid_next = m_udp_hdr_valid_reg & ~m_udp_hdr_ready; + m_eth_dest_mac_next = m_eth_dest_mac_reg; + m_eth_src_mac_next = m_eth_src_mac_reg; + m_eth_type_next = m_eth_type_reg; + m_ip_version_next = m_ip_version_reg; + m_ip_ihl_next = m_ip_ihl_reg; + m_ip_dscp_next = m_ip_dscp_reg; + m_ip_ecn_next = m_ip_ecn_reg; + m_ip_length_next = m_ip_length_reg; + m_ip_identification_next = m_ip_identification_reg; + m_ip_flags_next = m_ip_flags_reg; + m_ip_fragment_offset_next = m_ip_fragment_offset_reg; + m_ip_ttl_next = m_ip_ttl_reg; + m_ip_protocol_next = m_ip_protocol_reg; + m_ip_header_checksum_next = m_ip_header_checksum_reg; + m_ip_source_ip_next = m_ip_source_ip_reg; + m_ip_dest_ip_next = m_ip_dest_ip_reg; + m_udp_source_port_next = m_udp_source_port_reg; + m_udp_dest_port_next = m_udp_dest_port_reg; + m_udp_length_next = m_udp_length_reg; + m_udp_checksum_next = m_udp_checksum_reg; + + if (s_udp_payload_axis_tvalid && s_udp_payload_axis_tready) begin + // end of frame detection + if (s_udp_payload_axis_tlast) begin + frame_next = 1'b0; + drop_next = 1'b0; + end + end + + if (!frame_reg && s_udp_hdr_valid && s_udp_hdr_ready) begin + // start of frame, grab select value + select_ctl = select; + drop_ctl = drop; + frame_ctl = 1'b1; + + select_next = select_ctl; + drop_next = drop_ctl; + frame_next = frame_ctl; + + s_udp_hdr_ready_next = 1'b0; + + m_udp_hdr_valid_next = (!drop_ctl) << select_ctl; + m_eth_dest_mac_next = s_eth_dest_mac; + m_eth_src_mac_next = s_eth_src_mac; + m_eth_type_next = s_eth_type; + m_ip_version_next = s_ip_version; + m_ip_ihl_next = s_ip_ihl; + m_ip_dscp_next = s_ip_dscp; + m_ip_ecn_next = s_ip_ecn; + m_ip_length_next = s_ip_length; + m_ip_identification_next = s_ip_identification; + m_ip_flags_next = s_ip_flags; + m_ip_fragment_offset_next = s_ip_fragment_offset; + m_ip_ttl_next = s_ip_ttl; + m_ip_protocol_next = s_ip_protocol; + m_ip_header_checksum_next = s_ip_header_checksum; + m_ip_source_ip_next = s_ip_source_ip; + m_ip_dest_ip_next = s_ip_dest_ip; + m_udp_source_port_next = s_udp_source_port; + m_udp_dest_port_next = s_udp_dest_port; + m_udp_length_next = s_udp_length; + m_udp_checksum_next = s_udp_checksum; + end + + s_udp_hdr_ready_next = !frame_next && !m_udp_hdr_valid_next; + + s_udp_payload_axis_tready_next = (m_udp_payload_axis_tready_int_early || drop_ctl) && frame_ctl; + + m_udp_payload_axis_tdata_int = s_udp_payload_axis_tdata; + m_udp_payload_axis_tkeep_int = s_udp_payload_axis_tkeep; + m_udp_payload_axis_tvalid_int = (s_udp_payload_axis_tvalid && s_udp_payload_axis_tready && !drop_ctl) << select_ctl; + m_udp_payload_axis_tlast_int = s_udp_payload_axis_tlast; + m_udp_payload_axis_tid_int = s_udp_payload_axis_tid; + m_udp_payload_axis_tdest_int = s_udp_payload_axis_tdest; + m_udp_payload_axis_tuser_int = s_udp_payload_axis_tuser; +end + +always @(posedge clk) begin + if (rst) begin + select_reg <= 2'd0; + drop_reg <= 1'b0; + frame_reg <= 1'b0; + s_udp_hdr_ready_reg <= 1'b0; + s_udp_payload_axis_tready_reg <= 1'b0; + m_udp_hdr_valid_reg <= 0; + end else begin + select_reg <= select_next; + drop_reg <= drop_next; + frame_reg <= frame_next; + s_udp_hdr_ready_reg <= s_udp_hdr_ready_next; + s_udp_payload_axis_tready_reg <= s_udp_payload_axis_tready_next; + m_udp_hdr_valid_reg <= m_udp_hdr_valid_next; + end + + m_eth_dest_mac_reg <= m_eth_dest_mac_next; + m_eth_src_mac_reg <= m_eth_src_mac_next; + m_eth_type_reg <= m_eth_type_next; + m_ip_version_reg <= m_ip_version_next; + m_ip_ihl_reg <= m_ip_ihl_next; + m_ip_dscp_reg <= m_ip_dscp_next; + m_ip_ecn_reg <= m_ip_ecn_next; + m_ip_length_reg <= m_ip_length_next; + m_ip_identification_reg <= m_ip_identification_next; + m_ip_flags_reg <= m_ip_flags_next; + m_ip_fragment_offset_reg <= m_ip_fragment_offset_next; + m_ip_ttl_reg <= m_ip_ttl_next; + m_ip_protocol_reg <= m_ip_protocol_next; + m_ip_header_checksum_reg <= m_ip_header_checksum_next; + m_ip_source_ip_reg <= m_ip_source_ip_next; + m_ip_dest_ip_reg <= m_ip_dest_ip_next; + m_udp_source_port_reg <= m_udp_source_port_next; + m_udp_dest_port_reg <= m_udp_dest_port_next; + m_udp_length_reg <= m_udp_length_next; + m_udp_checksum_reg <= m_udp_checksum_next; +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_udp_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [M_COUNT-1:0] m_udp_payload_axis_tvalid_reg = {M_COUNT{1'b0}}, m_udp_payload_axis_tvalid_next; +reg m_udp_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_udp_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_udp_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_udp_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_udp_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_udp_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [M_COUNT-1:0] temp_m_udp_payload_axis_tvalid_reg = {M_COUNT{1'b0}}, temp_m_udp_payload_axis_tvalid_next; +reg temp_m_udp_payload_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_udp_payload_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_udp_payload_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_udp_payload_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_udp_payload_axis_temp_to_output; + +assign m_udp_payload_axis_tdata = {M_COUNT{m_udp_payload_axis_tdata_reg}}; +assign m_udp_payload_axis_tkeep = KEEP_ENABLE ? {M_COUNT{m_udp_payload_axis_tkeep_reg}} : {M_COUNT*KEEP_WIDTH{1'b1}}; +assign m_udp_payload_axis_tvalid = m_udp_payload_axis_tvalid_reg; +assign m_udp_payload_axis_tlast = {M_COUNT{m_udp_payload_axis_tlast_reg}}; +assign m_udp_payload_axis_tid = ID_ENABLE ? {M_COUNT{m_udp_payload_axis_tid_reg}} : {M_COUNT*ID_WIDTH{1'b0}}; +assign m_udp_payload_axis_tdest = DEST_ENABLE ? {M_COUNT{m_udp_payload_axis_tdest_reg}} : {M_COUNT*DEST_WIDTH{1'b0}}; +assign m_udp_payload_axis_tuser = USER_ENABLE ? {M_COUNT{m_udp_payload_axis_tuser_reg}} : {M_COUNT*USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_udp_payload_axis_tready_int_early = (m_udp_payload_axis_tready & m_udp_payload_axis_tvalid) || (!temp_m_udp_payload_axis_tvalid_reg && (!m_udp_payload_axis_tvalid || !m_udp_payload_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_reg; + temp_m_udp_payload_axis_tvalid_next = temp_m_udp_payload_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_udp_payload_axis_temp_to_output = 1'b0; + + if (m_udp_payload_axis_tready_int_reg) begin + // input is ready + if ((m_udp_payload_axis_tready & m_udp_payload_axis_tvalid) || !m_udp_payload_axis_tvalid) begin + // output is ready or currently not valid, transfer data to output + m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_udp_payload_axis_tready & m_udp_payload_axis_tvalid) begin + // input is not ready, but output is ready + m_udp_payload_axis_tvalid_next = temp_m_udp_payload_axis_tvalid_reg; + temp_m_udp_payload_axis_tvalid_next = 1'b0; + store_udp_payload_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + m_udp_payload_axis_tvalid_reg <= {M_COUNT{1'b0}}; + m_udp_payload_axis_tready_int_reg <= 1'b0; + temp_m_udp_payload_axis_tvalid_reg <= 1'b0; + end else begin + m_udp_payload_axis_tvalid_reg <= m_udp_payload_axis_tvalid_next; + m_udp_payload_axis_tready_int_reg <= m_udp_payload_axis_tready_int_early; + temp_m_udp_payload_axis_tvalid_reg <= temp_m_udp_payload_axis_tvalid_next; + end + + // datapath + if (store_axis_int_to_output) begin + m_udp_payload_axis_tdata_reg <= m_udp_payload_axis_tdata_int; + m_udp_payload_axis_tkeep_reg <= m_udp_payload_axis_tkeep_int; + m_udp_payload_axis_tlast_reg <= m_udp_payload_axis_tlast_int; + m_udp_payload_axis_tid_reg <= m_udp_payload_axis_tid_int; + m_udp_payload_axis_tdest_reg <= m_udp_payload_axis_tdest_int; + m_udp_payload_axis_tuser_reg <= m_udp_payload_axis_tuser_int; + end else if (store_udp_payload_axis_temp_to_output) begin + m_udp_payload_axis_tdata_reg <= temp_m_udp_payload_axis_tdata_reg; + m_udp_payload_axis_tkeep_reg <= temp_m_udp_payload_axis_tkeep_reg; + m_udp_payload_axis_tlast_reg <= temp_m_udp_payload_axis_tlast_reg; + m_udp_payload_axis_tid_reg <= temp_m_udp_payload_axis_tid_reg; + m_udp_payload_axis_tdest_reg <= temp_m_udp_payload_axis_tdest_reg; + m_udp_payload_axis_tuser_reg <= temp_m_udp_payload_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_udp_payload_axis_tdata_reg <= m_udp_payload_axis_tdata_int; + temp_m_udp_payload_axis_tkeep_reg <= m_udp_payload_axis_tkeep_int; + temp_m_udp_payload_axis_tlast_reg <= m_udp_payload_axis_tlast_int; + temp_m_udp_payload_axis_tid_reg <= m_udp_payload_axis_tid_int; + temp_m_udp_payload_axis_tdest_reg <= m_udp_payload_axis_tdest_int; + temp_m_udp_payload_axis_tuser_reg <= m_udp_payload_axis_tuser_int; + end +end + +endmodule diff --git a/rtl/udp_demux_4.v b/rtl/udp_demux_4.v deleted file mode 100644 index a97ec4965..000000000 --- a/rtl/udp_demux_4.v +++ /dev/null @@ -1,598 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * UDP 4 port demultiplexer - */ -module udp_demux_4 -( - input wire clk, - input wire rst, - - /* - * UDP frame input - */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [15:0] input_udp_length, - input wire [15:0] input_udp_checksum, - input wire [7:0] input_udp_payload_tdata, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, - - /* - * UDP frame outputs - */ - output wire output_0_udp_hdr_valid, - input wire output_0_udp_hdr_ready, - output wire [47:0] output_0_eth_dest_mac, - output wire [47:0] output_0_eth_src_mac, - output wire [15:0] output_0_eth_type, - output wire [3:0] output_0_ip_version, - output wire [3:0] output_0_ip_ihl, - output wire [5:0] output_0_ip_dscp, - output wire [1:0] output_0_ip_ecn, - output wire [15:0] output_0_ip_length, - output wire [15:0] output_0_ip_identification, - output wire [2:0] output_0_ip_flags, - output wire [12:0] output_0_ip_fragment_offset, - output wire [7:0] output_0_ip_ttl, - output wire [7:0] output_0_ip_protocol, - output wire [15:0] output_0_ip_header_checksum, - output wire [31:0] output_0_ip_source_ip, - output wire [31:0] output_0_ip_dest_ip, - output wire [15:0] output_0_udp_source_port, - output wire [15:0] output_0_udp_dest_port, - output wire [15:0] output_0_udp_length, - output wire [15:0] output_0_udp_checksum, - output wire [7:0] output_0_udp_payload_tdata, - output wire output_0_udp_payload_tvalid, - input wire output_0_udp_payload_tready, - output wire output_0_udp_payload_tlast, - output wire output_0_udp_payload_tuser, - - output wire output_1_udp_hdr_valid, - input wire output_1_udp_hdr_ready, - output wire [47:0] output_1_eth_dest_mac, - output wire [47:0] output_1_eth_src_mac, - output wire [15:0] output_1_eth_type, - output wire [3:0] output_1_ip_version, - output wire [3:0] output_1_ip_ihl, - output wire [5:0] output_1_ip_dscp, - output wire [1:0] output_1_ip_ecn, - output wire [15:0] output_1_ip_length, - output wire [15:0] output_1_ip_identification, - output wire [2:0] output_1_ip_flags, - output wire [12:0] output_1_ip_fragment_offset, - output wire [7:0] output_1_ip_ttl, - output wire [7:0] output_1_ip_protocol, - output wire [15:0] output_1_ip_header_checksum, - output wire [31:0] output_1_ip_source_ip, - output wire [31:0] output_1_ip_dest_ip, - output wire [15:0] output_1_udp_source_port, - output wire [15:0] output_1_udp_dest_port, - output wire [15:0] output_1_udp_length, - output wire [15:0] output_1_udp_checksum, - output wire [7:0] output_1_udp_payload_tdata, - output wire output_1_udp_payload_tvalid, - input wire output_1_udp_payload_tready, - output wire output_1_udp_payload_tlast, - output wire output_1_udp_payload_tuser, - - output wire output_2_udp_hdr_valid, - input wire output_2_udp_hdr_ready, - output wire [47:0] output_2_eth_dest_mac, - output wire [47:0] output_2_eth_src_mac, - output wire [15:0] output_2_eth_type, - output wire [3:0] output_2_ip_version, - output wire [3:0] output_2_ip_ihl, - output wire [5:0] output_2_ip_dscp, - output wire [1:0] output_2_ip_ecn, - output wire [15:0] output_2_ip_length, - output wire [15:0] output_2_ip_identification, - output wire [2:0] output_2_ip_flags, - output wire [12:0] output_2_ip_fragment_offset, - output wire [7:0] output_2_ip_ttl, - output wire [7:0] output_2_ip_protocol, - output wire [15:0] output_2_ip_header_checksum, - output wire [31:0] output_2_ip_source_ip, - output wire [31:0] output_2_ip_dest_ip, - output wire [15:0] output_2_udp_source_port, - output wire [15:0] output_2_udp_dest_port, - output wire [15:0] output_2_udp_length, - output wire [15:0] output_2_udp_checksum, - output wire [7:0] output_2_udp_payload_tdata, - output wire output_2_udp_payload_tvalid, - input wire output_2_udp_payload_tready, - output wire output_2_udp_payload_tlast, - output wire output_2_udp_payload_tuser, - - output wire output_3_udp_hdr_valid, - input wire output_3_udp_hdr_ready, - output wire [47:0] output_3_eth_dest_mac, - output wire [47:0] output_3_eth_src_mac, - output wire [15:0] output_3_eth_type, - output wire [3:0] output_3_ip_version, - output wire [3:0] output_3_ip_ihl, - output wire [5:0] output_3_ip_dscp, - output wire [1:0] output_3_ip_ecn, - output wire [15:0] output_3_ip_length, - output wire [15:0] output_3_ip_identification, - output wire [2:0] output_3_ip_flags, - output wire [12:0] output_3_ip_fragment_offset, - output wire [7:0] output_3_ip_ttl, - output wire [7:0] output_3_ip_protocol, - output wire [15:0] output_3_ip_header_checksum, - output wire [31:0] output_3_ip_source_ip, - output wire [31:0] output_3_ip_dest_ip, - output wire [15:0] output_3_udp_source_port, - output wire [15:0] output_3_udp_dest_port, - output wire [15:0] output_3_udp_length, - output wire [15:0] output_3_udp_checksum, - output wire [7:0] output_3_udp_payload_tdata, - output wire output_3_udp_payload_tvalid, - input wire output_3_udp_payload_tready, - output wire output_3_udp_payload_tlast, - output wire output_3_udp_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; - -reg output_0_udp_hdr_valid_reg = 1'b0, output_0_udp_hdr_valid_next; -reg output_1_udp_hdr_valid_reg = 1'b0, output_1_udp_hdr_valid_next; -reg output_2_udp_hdr_valid_reg = 1'b0, output_2_udp_hdr_valid_next; -reg output_3_udp_hdr_valid_reg = 1'b0, output_3_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; - -// internal datapath -reg [7:0] output_udp_payload_tdata_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int_reg = 1'b0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; - -assign input_udp_hdr_ready = input_udp_hdr_ready_reg; -assign input_udp_payload_tready = input_udp_payload_tready_reg; - -assign output_0_udp_hdr_valid = output_0_udp_hdr_valid_reg; -assign output_0_eth_dest_mac = output_eth_dest_mac_reg; -assign output_0_eth_src_mac = output_eth_src_mac_reg; -assign output_0_eth_type = output_eth_type_reg; -assign output_0_ip_version = output_ip_version_reg; -assign output_0_ip_ihl = output_ip_ihl_reg; -assign output_0_ip_dscp = output_ip_dscp_reg; -assign output_0_ip_ecn = output_ip_ecn_reg; -assign output_0_ip_length = output_ip_length_reg; -assign output_0_ip_identification = output_ip_identification_reg; -assign output_0_ip_flags = output_ip_flags_reg; -assign output_0_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_0_ip_ttl = output_ip_ttl_reg; -assign output_0_ip_protocol = output_ip_protocol_reg; -assign output_0_ip_header_checksum = output_ip_header_checksum_reg; -assign output_0_ip_source_ip = output_ip_source_ip_reg; -assign output_0_ip_dest_ip = output_ip_dest_ip_reg; -assign output_0_udp_source_port = output_udp_source_port_reg; -assign output_0_udp_dest_port = output_udp_dest_port_reg; -assign output_0_udp_length = output_udp_length_reg; -assign output_0_udp_checksum = output_udp_checksum_reg; - -assign output_1_udp_hdr_valid = output_1_udp_hdr_valid_reg; -assign output_1_eth_dest_mac = output_eth_dest_mac_reg; -assign output_1_eth_src_mac = output_eth_src_mac_reg; -assign output_1_eth_type = output_eth_type_reg; -assign output_1_ip_version = output_ip_version_reg; -assign output_1_ip_ihl = output_ip_ihl_reg; -assign output_1_ip_dscp = output_ip_dscp_reg; -assign output_1_ip_ecn = output_ip_ecn_reg; -assign output_1_ip_length = output_ip_length_reg; -assign output_1_ip_identification = output_ip_identification_reg; -assign output_1_ip_flags = output_ip_flags_reg; -assign output_1_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_1_ip_ttl = output_ip_ttl_reg; -assign output_1_ip_protocol = output_ip_protocol_reg; -assign output_1_ip_header_checksum = output_ip_header_checksum_reg; -assign output_1_ip_source_ip = output_ip_source_ip_reg; -assign output_1_ip_dest_ip = output_ip_dest_ip_reg; -assign output_1_udp_source_port = output_udp_source_port_reg; -assign output_1_udp_dest_port = output_udp_dest_port_reg; -assign output_1_udp_length = output_udp_length_reg; -assign output_1_udp_checksum = output_udp_checksum_reg; - -assign output_2_udp_hdr_valid = output_2_udp_hdr_valid_reg; -assign output_2_eth_dest_mac = output_eth_dest_mac_reg; -assign output_2_eth_src_mac = output_eth_src_mac_reg; -assign output_2_eth_type = output_eth_type_reg; -assign output_2_ip_version = output_ip_version_reg; -assign output_2_ip_ihl = output_ip_ihl_reg; -assign output_2_ip_dscp = output_ip_dscp_reg; -assign output_2_ip_ecn = output_ip_ecn_reg; -assign output_2_ip_length = output_ip_length_reg; -assign output_2_ip_identification = output_ip_identification_reg; -assign output_2_ip_flags = output_ip_flags_reg; -assign output_2_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_2_ip_ttl = output_ip_ttl_reg; -assign output_2_ip_protocol = output_ip_protocol_reg; -assign output_2_ip_header_checksum = output_ip_header_checksum_reg; -assign output_2_ip_source_ip = output_ip_source_ip_reg; -assign output_2_ip_dest_ip = output_ip_dest_ip_reg; -assign output_2_udp_source_port = output_udp_source_port_reg; -assign output_2_udp_dest_port = output_udp_dest_port_reg; -assign output_2_udp_length = output_udp_length_reg; -assign output_2_udp_checksum = output_udp_checksum_reg; - -assign output_3_udp_hdr_valid = output_3_udp_hdr_valid_reg; -assign output_3_eth_dest_mac = output_eth_dest_mac_reg; -assign output_3_eth_src_mac = output_eth_src_mac_reg; -assign output_3_eth_type = output_eth_type_reg; -assign output_3_ip_version = output_ip_version_reg; -assign output_3_ip_ihl = output_ip_ihl_reg; -assign output_3_ip_dscp = output_ip_dscp_reg; -assign output_3_ip_ecn = output_ip_ecn_reg; -assign output_3_ip_length = output_ip_length_reg; -assign output_3_ip_identification = output_ip_identification_reg; -assign output_3_ip_flags = output_ip_flags_reg; -assign output_3_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_3_ip_ttl = output_ip_ttl_reg; -assign output_3_ip_protocol = output_ip_protocol_reg; -assign output_3_ip_header_checksum = output_ip_header_checksum_reg; -assign output_3_ip_source_ip = output_ip_source_ip_reg; -assign output_3_ip_dest_ip = output_ip_dest_ip_reg; -assign output_3_udp_source_port = output_udp_source_port_reg; -assign output_3_udp_dest_port = output_udp_dest_port_reg; -assign output_3_udp_length = output_udp_length_reg; -assign output_3_udp_checksum = output_udp_checksum_reg; - -// mux for output control signals -reg current_output_udp_hdr_valid; -reg current_output_udp_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) - 2'd0: begin - current_output_udp_hdr_valid = output_0_udp_hdr_valid; - current_output_udp_hdr_ready = output_0_udp_hdr_ready; - current_output_tvalid = output_0_udp_payload_tvalid; - current_output_tready = output_0_udp_payload_tready; - end - 2'd1: begin - current_output_udp_hdr_valid = output_1_udp_hdr_valid; - current_output_udp_hdr_ready = output_1_udp_hdr_ready; - current_output_tvalid = output_1_udp_payload_tvalid; - current_output_tready = output_1_udp_payload_tready; - end - 2'd2: begin - current_output_udp_hdr_valid = output_2_udp_hdr_valid; - current_output_udp_hdr_ready = output_2_udp_hdr_ready; - current_output_tvalid = output_2_udp_payload_tvalid; - current_output_tready = output_2_udp_payload_tready; - end - 2'd3: begin - current_output_udp_hdr_valid = output_3_udp_hdr_valid; - current_output_udp_hdr_ready = output_3_udp_hdr_ready; - current_output_tvalid = output_3_udp_payload_tvalid; - current_output_tready = output_3_udp_payload_tready; - end - default: begin - current_output_udp_hdr_valid = 1'b0; - current_output_udp_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; - input_udp_payload_tready_next = 1'b0; - output_0_udp_hdr_valid_next = output_0_udp_hdr_valid_reg & ~output_0_udp_hdr_ready; - output_1_udp_hdr_valid_next = output_1_udp_hdr_valid_reg & ~output_1_udp_hdr_ready; - output_2_udp_hdr_valid_next = output_2_udp_hdr_valid_reg & ~output_2_udp_hdr_ready; - output_3_udp_hdr_valid_next = output_3_udp_hdr_valid_reg & ~output_3_udp_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - output_udp_source_port_next = output_udp_source_port_reg; - output_udp_dest_port_next = output_udp_dest_port_reg; - output_udp_length_next = output_udp_length_reg; - output_udp_checksum_next = output_udp_checksum_reg; - - if (input_udp_payload_tvalid & input_udp_payload_tready) begin - // end of frame detection - if (input_udp_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_udp_hdr_ready_next = 1'b1; - - case (select) - 2'd0: output_0_udp_hdr_valid_next = 1'b1; - 2'd1: output_1_udp_hdr_valid_next = 1'b1; - 2'd2: output_2_udp_hdr_valid_next = 1'b1; - 2'd3: output_3_udp_hdr_valid_next = 1'b1; - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - output_ip_version_next = input_ip_version; - output_ip_ihl_next = input_ip_ihl; - output_ip_dscp_next = input_ip_dscp; - output_ip_ecn_next = input_ip_ecn; - output_ip_length_next = input_ip_length; - output_ip_identification_next = input_ip_identification; - output_ip_flags_next = input_ip_flags; - output_ip_fragment_offset_next = input_ip_fragment_offset; - output_ip_ttl_next = input_ip_ttl; - output_ip_protocol_next = input_ip_protocol; - output_ip_header_checksum_next = input_ip_header_checksum; - output_ip_source_ip_next = input_ip_source_ip; - output_ip_dest_ip_next = input_ip_dest_ip; - output_udp_source_port_next = input_udp_source_port; - output_udp_dest_port_next = input_udp_dest_port; - output_udp_length_next = input_udp_length; - output_udp_checksum_next = input_udp_checksum; - end - - input_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - - output_udp_payload_tdata_int = input_udp_payload_tdata; - output_udp_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tready; - output_udp_payload_tlast_int = input_udp_payload_tlast; - output_udp_payload_tuser_int = input_udp_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_udp_hdr_ready_reg <= 1'b0; - input_udp_payload_tready_reg <= 1'b0; - output_0_udp_hdr_valid_reg <= 1'b0; - output_1_udp_hdr_valid_reg <= 1'b0; - output_2_udp_hdr_valid_reg <= 1'b0; - output_3_udp_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; - input_udp_payload_tready_reg <= input_udp_payload_tready_next; - output_0_udp_hdr_valid_reg <= output_0_udp_hdr_valid_next; - output_1_udp_hdr_valid_reg <= output_1_udp_hdr_valid_next; - output_2_udp_hdr_valid_reg <= output_2_udp_hdr_valid_next; - output_3_udp_hdr_valid_reg <= output_3_udp_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; -end - -// output datapath logic -reg [7:0] output_udp_payload_tdata_reg = 8'd0; -reg output_0_udp_payload_tvalid_reg = 1'b0, output_0_udp_payload_tvalid_next; -reg output_1_udp_payload_tvalid_reg = 1'b0, output_1_udp_payload_tvalid_next; -reg output_2_udp_payload_tvalid_reg = 1'b0, output_2_udp_payload_tvalid_next; -reg output_3_udp_payload_tvalid_reg = 1'b0, output_3_udp_payload_tvalid_next; -reg output_udp_payload_tlast_reg = 1'b0; -reg output_udp_payload_tuser_reg = 1'b0; - -reg [7:0] temp_udp_payload_tdata_reg = 8'd0; -reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; -reg temp_udp_payload_tlast_reg = 1'b0; -reg temp_udp_payload_tuser_reg = 1'b0; - -// datapath control -reg store_udp_payload_int_to_output; -reg store_udp_payload_int_to_temp; -reg store_udp_payload_temp_to_output; - -assign output_0_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_0_udp_payload_tvalid = output_0_udp_payload_tvalid_reg; -assign output_0_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_0_udp_payload_tuser = output_udp_payload_tuser_reg; - -assign output_1_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_1_udp_payload_tvalid = output_1_udp_payload_tvalid_reg; -assign output_1_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_1_udp_payload_tuser = output_udp_payload_tuser_reg; - -assign output_2_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_2_udp_payload_tvalid = output_2_udp_payload_tvalid_reg; -assign output_2_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_2_udp_payload_tuser = output_udp_payload_tuser_reg; - -assign output_3_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_3_udp_payload_tvalid = output_3_udp_payload_tvalid_reg; -assign output_3_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_3_udp_payload_tuser = output_udp_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & (~current_output_tvalid | ~output_udp_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_0_udp_payload_tvalid_next = output_0_udp_payload_tvalid_reg; - output_1_udp_payload_tvalid_next = output_1_udp_payload_tvalid_reg; - output_2_udp_payload_tvalid_next = output_2_udp_payload_tvalid_reg; - output_3_udp_payload_tvalid_next = output_3_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - - store_udp_payload_int_to_output = 1'b0; - store_udp_payload_int_to_temp = 1'b0; - store_udp_payload_temp_to_output = 1'b0; - - if (output_udp_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_0_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd0); - output_1_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd1); - output_2_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd2); - output_3_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd3); - store_udp_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_0_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd0); - output_1_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd1); - output_2_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd2); - output_3_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd3); - temp_udp_payload_tvalid_next = 1'b0; - store_udp_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_0_udp_payload_tvalid_reg <= 1'b0; - output_1_udp_payload_tvalid_reg <= 1'b0; - output_2_udp_payload_tvalid_reg <= 1'b0; - output_3_udp_payload_tvalid_reg <= 1'b0; - output_udp_payload_tready_int_reg <= 1'b0; - temp_udp_payload_tvalid_reg <= 1'b0; - end else begin - output_0_udp_payload_tvalid_reg <= output_0_udp_payload_tvalid_next; - output_1_udp_payload_tvalid_reg <= output_1_udp_payload_tvalid_next; - output_2_udp_payload_tvalid_reg <= output_2_udp_payload_tvalid_next; - output_3_udp_payload_tvalid_reg <= output_3_udp_payload_tvalid_next; - output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; - temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; - end - - // datapath - if (store_udp_payload_int_to_output) begin - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else if (store_udp_payload_temp_to_output) begin - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - end - - if (store_udp_payload_int_to_temp) begin - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end -end - -endmodule diff --git a/rtl/udp_demux_64.py b/rtl/udp_demux_64.py deleted file mode 100755 index 158135a96..000000000 --- a/rtl/udp_demux_64.py +++ /dev/null @@ -1,472 +0,0 @@ -#!/usr/bin/env python -""" -Generates a UDP demux with the specified number of ports -""" - -from __future__ import print_function - -import argparse -import math -from jinja2 import Template - -def main(): - parser = argparse.ArgumentParser(description=__doc__.strip()) - parser.add_argument('-p', '--ports', type=int, default=4, help="number of ports") - parser.add_argument('-n', '--name', type=str, help="module name") - parser.add_argument('-o', '--output', type=str, help="output file name") - - args = parser.parse_args() - - try: - generate(**args.__dict__) - except IOError as ex: - print(ex) - exit(1) - -def generate(ports=4, name=None, output=None): - if name is None: - name = "udp_demux_64_{0}".format(ports) - - if output is None: - output = name + ".v" - - print("Opening file '{0}'...".format(output)) - - output_file = open(output, 'w') - - print("Generating {0} port UDP demux {1}...".format(ports, name)) - - select_width = int(math.ceil(math.log(ports, 2))) - - t = Template(u"""/* - -Copyright (c) 2014-2018 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 - -/* - * UDP {{n}} port demultiplexer (64 bit datapath) - */ -module {{name}} -( - input wire clk, - input wire rst, - - /* - * UDP frame input - */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [15:0] input_udp_length, - input wire [15:0] input_udp_checksum, - input wire [63:0] input_udp_payload_tdata, - input wire [7:0] input_udp_payload_tkeep, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, - - /* - * UDP frame outputs - */ -{%- for p in ports %} - output wire output_{{p}}_udp_hdr_valid, - input wire output_{{p}}_udp_hdr_ready, - output wire [47:0] output_{{p}}_eth_dest_mac, - output wire [47:0] output_{{p}}_eth_src_mac, - output wire [15:0] output_{{p}}_eth_type, - output wire [3:0] output_{{p}}_ip_version, - output wire [3:0] output_{{p}}_ip_ihl, - output wire [5:0] output_{{p}}_ip_dscp, - output wire [1:0] output_{{p}}_ip_ecn, - output wire [15:0] output_{{p}}_ip_length, - output wire [15:0] output_{{p}}_ip_identification, - output wire [2:0] output_{{p}}_ip_flags, - output wire [12:0] output_{{p}}_ip_fragment_offset, - output wire [7:0] output_{{p}}_ip_ttl, - output wire [7:0] output_{{p}}_ip_protocol, - output wire [15:0] output_{{p}}_ip_header_checksum, - output wire [31:0] output_{{p}}_ip_source_ip, - output wire [31:0] output_{{p}}_ip_dest_ip, - output wire [15:0] output_{{p}}_udp_source_port, - output wire [15:0] output_{{p}}_udp_dest_port, - output wire [15:0] output_{{p}}_udp_length, - output wire [15:0] output_{{p}}_udp_checksum, - output wire [63:0] output_{{p}}_udp_payload_tdata, - output wire [7:0] output_{{p}}_udp_payload_tkeep, - output wire output_{{p}}_udp_payload_tvalid, - input wire output_{{p}}_udp_payload_tready, - output wire output_{{p}}_udp_payload_tlast, - output wire output_{{p}}_udp_payload_tuser, -{% endfor %} - /* - * Control - */ - input wire enable, - input wire [{{w-1}}:0] select -); - -reg [{{w-1}}:0] select_reg = {{w}}'d0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; -{% for p in ports %} -reg output_{{p}}_udp_hdr_valid_reg = 1'b0, output_{{p}}_udp_hdr_valid_next; -{%- endfor %} -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; - -// internal datapath -reg [63:0] output_udp_payload_tdata_int; -reg [7:0] output_udp_payload_tkeep_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int_reg = 1'b0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; - -assign input_udp_hdr_ready = input_udp_hdr_ready_reg; -assign input_udp_payload_tready = input_udp_payload_tready_reg; -{% for p in ports %} -assign output_{{p}}_udp_hdr_valid = output_{{p}}_udp_hdr_valid_reg; -assign output_{{p}}_eth_dest_mac = output_eth_dest_mac_reg; -assign output_{{p}}_eth_src_mac = output_eth_src_mac_reg; -assign output_{{p}}_eth_type = output_eth_type_reg; -assign output_{{p}}_ip_version = output_ip_version_reg; -assign output_{{p}}_ip_ihl = output_ip_ihl_reg; -assign output_{{p}}_ip_dscp = output_ip_dscp_reg; -assign output_{{p}}_ip_ecn = output_ip_ecn_reg; -assign output_{{p}}_ip_length = output_ip_length_reg; -assign output_{{p}}_ip_identification = output_ip_identification_reg; -assign output_{{p}}_ip_flags = output_ip_flags_reg; -assign output_{{p}}_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_{{p}}_ip_ttl = output_ip_ttl_reg; -assign output_{{p}}_ip_protocol = output_ip_protocol_reg; -assign output_{{p}}_ip_header_checksum = output_ip_header_checksum_reg; -assign output_{{p}}_ip_source_ip = output_ip_source_ip_reg; -assign output_{{p}}_ip_dest_ip = output_ip_dest_ip_reg; -assign output_{{p}}_udp_source_port = output_udp_source_port_reg; -assign output_{{p}}_udp_dest_port = output_udp_dest_port_reg; -assign output_{{p}}_udp_length = output_udp_length_reg; -assign output_{{p}}_udp_checksum = output_udp_checksum_reg; -{% endfor %} -// mux for output control signals -reg current_output_udp_hdr_valid; -reg current_output_udp_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) -{%- for p in ports %} - {{w}}'d{{p}}: begin - current_output_udp_hdr_valid = output_{{p}}_udp_hdr_valid; - current_output_udp_hdr_ready = output_{{p}}_udp_hdr_ready; - current_output_tvalid = output_{{p}}_udp_payload_tvalid; - current_output_tready = output_{{p}}_udp_payload_tready; - end -{%- endfor %} - default: begin - current_output_udp_hdr_valid = 1'b0; - current_output_udp_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; - input_udp_payload_tready_next = 1'b0; - -{%- for p in ports %} - output_{{p}}_udp_hdr_valid_next = output_{{p}}_udp_hdr_valid_reg & ~output_{{p}}_udp_hdr_ready; -{%- endfor %} - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - output_udp_source_port_next = output_udp_source_port_reg; - output_udp_dest_port_next = output_udp_dest_port_reg; - output_udp_length_next = output_udp_length_reg; - output_udp_checksum_next = output_udp_checksum_reg; - - if (input_udp_payload_tvalid & input_udp_payload_tready) begin - // end of frame detection - if (input_udp_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_udp_hdr_ready_next = 1'b1; - - case (select) -{%- for p in ports %} - {{w}}'d{{p}}: output_{{p}}_udp_hdr_valid_next = 1'b1; -{%- endfor %} - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - output_ip_version_next = input_ip_version; - output_ip_ihl_next = input_ip_ihl; - output_ip_dscp_next = input_ip_dscp; - output_ip_ecn_next = input_ip_ecn; - output_ip_length_next = input_ip_length; - output_ip_identification_next = input_ip_identification; - output_ip_flags_next = input_ip_flags; - output_ip_fragment_offset_next = input_ip_fragment_offset; - output_ip_ttl_next = input_ip_ttl; - output_ip_protocol_next = input_ip_protocol; - output_ip_header_checksum_next = input_ip_header_checksum; - output_ip_source_ip_next = input_ip_source_ip; - output_ip_dest_ip_next = input_ip_dest_ip; - output_udp_source_port_next = input_udp_source_port; - output_udp_dest_port_next = input_udp_dest_port; - output_udp_length_next = input_udp_length; - output_udp_checksum_next = input_udp_checksum; - end - - input_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - - output_udp_payload_tdata_int = input_udp_payload_tdata; - output_udp_payload_tkeep_int = input_udp_payload_tkeep; - output_udp_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tready; - output_udp_payload_tlast_int = input_udp_payload_tlast; - output_udp_payload_tuser_int = input_udp_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= {{w}}'d0; - frame_reg <= 1'b0; - input_udp_hdr_ready_reg <= 1'b0; - input_udp_payload_tready_reg <= 1'b0; -{%- for p in ports %} - output_{{p}}_udp_hdr_valid_reg <= 1'b0; -{%- endfor %} - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; - input_udp_payload_tready_reg <= input_udp_payload_tready_next; -{%- for p in ports %} - output_{{p}}_udp_hdr_valid_reg <= output_{{p}}_udp_hdr_valid_next; -{%- endfor %} - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; -end - -// output datapath logic -reg [63:0] output_udp_payload_tdata_reg = 64'd0; -reg [7:0] output_udp_payload_tkeep_reg = 8'd0; -{%- for p in ports %} -reg output_{{p}}_udp_payload_tvalid_reg = 1'b0, output_{{p}}_udp_payload_tvalid_next; -{%- endfor %} -reg output_udp_payload_tlast_reg = 1'b0; -reg output_udp_payload_tuser_reg = 1'b0; - -reg [63:0] temp_udp_payload_tdata_reg = 64'd0; -reg [7:0] temp_udp_payload_tkeep_reg = 8'd0; -reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; -reg temp_udp_payload_tlast_reg = 1'b0; -reg temp_udp_payload_tuser_reg = 1'b0; - -// datapath control -reg store_udp_payload_int_to_output; -reg store_udp_payload_int_to_temp; -reg store_udp_payload_temp_to_output; -{% for p in ports %} -assign output_{{p}}_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_{{p}}_udp_payload_tkeep = output_udp_payload_tkeep_reg; -assign output_{{p}}_udp_payload_tvalid = output_{{p}}_udp_payload_tvalid_reg; -assign output_{{p}}_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_{{p}}_udp_payload_tuser = output_udp_payload_tuser_reg; -{% endfor %} -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & (~current_output_tvalid | ~output_udp_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source -{%- for p in ports %} - output_{{p}}_udp_payload_tvalid_next = output_{{p}}_udp_payload_tvalid_reg; -{%- endfor %} - temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - - store_udp_payload_int_to_output = 1'b0; - store_udp_payload_int_to_temp = 1'b0; - store_udp_payload_temp_to_output = 1'b0; - - if (output_udp_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output -{%- for p in ports %} - output_{{p}}_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - store_udp_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready -{%- for p in ports %} - output_{{p}}_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == {{w}}'d{{p}}); -{%- endfor %} - temp_udp_payload_tvalid_next = 1'b0; - store_udp_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin -{%- for p in ports %} - output_{{p}}_udp_payload_tvalid_reg <= 1'b0; -{%- endfor %} - output_udp_payload_tready_int_reg <= 1'b0; - temp_udp_payload_tvalid_reg <= 1'b0; - end else begin -{%- for p in ports %} - output_{{p}}_udp_payload_tvalid_reg <= output_{{p}}_udp_payload_tvalid_next; -{%- endfor %} - output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; - temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; - end - - // datapath - if (store_udp_payload_int_to_output) begin - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else if (store_udp_payload_temp_to_output) begin - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - end - - if (store_udp_payload_int_to_temp) begin - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end -end - -endmodule - -""") - - output_file.write(t.render( - n=ports, - w=select_width, - name=name, - ports=range(ports) - )) - - print("Done") - -if __name__ == "__main__": - main() - diff --git a/rtl/udp_demux_64_4.v b/rtl/udp_demux_64_4.v deleted file mode 100644 index 8817a2097..000000000 --- a/rtl/udp_demux_64_4.v +++ /dev/null @@ -1,614 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * UDP 4 port demultiplexer (64 bit datapath) - */ -module udp_demux_64_4 -( - input wire clk, - input wire rst, - - /* - * UDP frame input - */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [15:0] input_udp_length, - input wire [15:0] input_udp_checksum, - input wire [63:0] input_udp_payload_tdata, - input wire [7:0] input_udp_payload_tkeep, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, - - /* - * UDP frame outputs - */ - output wire output_0_udp_hdr_valid, - input wire output_0_udp_hdr_ready, - output wire [47:0] output_0_eth_dest_mac, - output wire [47:0] output_0_eth_src_mac, - output wire [15:0] output_0_eth_type, - output wire [3:0] output_0_ip_version, - output wire [3:0] output_0_ip_ihl, - output wire [5:0] output_0_ip_dscp, - output wire [1:0] output_0_ip_ecn, - output wire [15:0] output_0_ip_length, - output wire [15:0] output_0_ip_identification, - output wire [2:0] output_0_ip_flags, - output wire [12:0] output_0_ip_fragment_offset, - output wire [7:0] output_0_ip_ttl, - output wire [7:0] output_0_ip_protocol, - output wire [15:0] output_0_ip_header_checksum, - output wire [31:0] output_0_ip_source_ip, - output wire [31:0] output_0_ip_dest_ip, - output wire [15:0] output_0_udp_source_port, - output wire [15:0] output_0_udp_dest_port, - output wire [15:0] output_0_udp_length, - output wire [15:0] output_0_udp_checksum, - output wire [63:0] output_0_udp_payload_tdata, - output wire [7:0] output_0_udp_payload_tkeep, - output wire output_0_udp_payload_tvalid, - input wire output_0_udp_payload_tready, - output wire output_0_udp_payload_tlast, - output wire output_0_udp_payload_tuser, - - output wire output_1_udp_hdr_valid, - input wire output_1_udp_hdr_ready, - output wire [47:0] output_1_eth_dest_mac, - output wire [47:0] output_1_eth_src_mac, - output wire [15:0] output_1_eth_type, - output wire [3:0] output_1_ip_version, - output wire [3:0] output_1_ip_ihl, - output wire [5:0] output_1_ip_dscp, - output wire [1:0] output_1_ip_ecn, - output wire [15:0] output_1_ip_length, - output wire [15:0] output_1_ip_identification, - output wire [2:0] output_1_ip_flags, - output wire [12:0] output_1_ip_fragment_offset, - output wire [7:0] output_1_ip_ttl, - output wire [7:0] output_1_ip_protocol, - output wire [15:0] output_1_ip_header_checksum, - output wire [31:0] output_1_ip_source_ip, - output wire [31:0] output_1_ip_dest_ip, - output wire [15:0] output_1_udp_source_port, - output wire [15:0] output_1_udp_dest_port, - output wire [15:0] output_1_udp_length, - output wire [15:0] output_1_udp_checksum, - output wire [63:0] output_1_udp_payload_tdata, - output wire [7:0] output_1_udp_payload_tkeep, - output wire output_1_udp_payload_tvalid, - input wire output_1_udp_payload_tready, - output wire output_1_udp_payload_tlast, - output wire output_1_udp_payload_tuser, - - output wire output_2_udp_hdr_valid, - input wire output_2_udp_hdr_ready, - output wire [47:0] output_2_eth_dest_mac, - output wire [47:0] output_2_eth_src_mac, - output wire [15:0] output_2_eth_type, - output wire [3:0] output_2_ip_version, - output wire [3:0] output_2_ip_ihl, - output wire [5:0] output_2_ip_dscp, - output wire [1:0] output_2_ip_ecn, - output wire [15:0] output_2_ip_length, - output wire [15:0] output_2_ip_identification, - output wire [2:0] output_2_ip_flags, - output wire [12:0] output_2_ip_fragment_offset, - output wire [7:0] output_2_ip_ttl, - output wire [7:0] output_2_ip_protocol, - output wire [15:0] output_2_ip_header_checksum, - output wire [31:0] output_2_ip_source_ip, - output wire [31:0] output_2_ip_dest_ip, - output wire [15:0] output_2_udp_source_port, - output wire [15:0] output_2_udp_dest_port, - output wire [15:0] output_2_udp_length, - output wire [15:0] output_2_udp_checksum, - output wire [63:0] output_2_udp_payload_tdata, - output wire [7:0] output_2_udp_payload_tkeep, - output wire output_2_udp_payload_tvalid, - input wire output_2_udp_payload_tready, - output wire output_2_udp_payload_tlast, - output wire output_2_udp_payload_tuser, - - output wire output_3_udp_hdr_valid, - input wire output_3_udp_hdr_ready, - output wire [47:0] output_3_eth_dest_mac, - output wire [47:0] output_3_eth_src_mac, - output wire [15:0] output_3_eth_type, - output wire [3:0] output_3_ip_version, - output wire [3:0] output_3_ip_ihl, - output wire [5:0] output_3_ip_dscp, - output wire [1:0] output_3_ip_ecn, - output wire [15:0] output_3_ip_length, - output wire [15:0] output_3_ip_identification, - output wire [2:0] output_3_ip_flags, - output wire [12:0] output_3_ip_fragment_offset, - output wire [7:0] output_3_ip_ttl, - output wire [7:0] output_3_ip_protocol, - output wire [15:0] output_3_ip_header_checksum, - output wire [31:0] output_3_ip_source_ip, - output wire [31:0] output_3_ip_dest_ip, - output wire [15:0] output_3_udp_source_port, - output wire [15:0] output_3_udp_dest_port, - output wire [15:0] output_3_udp_length, - output wire [15:0] output_3_udp_checksum, - output wire [63:0] output_3_udp_payload_tdata, - output wire [7:0] output_3_udp_payload_tkeep, - output wire output_3_udp_payload_tvalid, - input wire output_3_udp_payload_tready, - output wire output_3_udp_payload_tlast, - output wire output_3_udp_payload_tuser, - - /* - * Control - */ - input wire enable, - input wire [1:0] select -); - -reg [1:0] select_reg = 2'd0, select_next; -reg frame_reg = 1'b0, frame_next; - -reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; - -reg output_0_udp_hdr_valid_reg = 1'b0, output_0_udp_hdr_valid_next; -reg output_1_udp_hdr_valid_reg = 1'b0, output_1_udp_hdr_valid_next; -reg output_2_udp_hdr_valid_reg = 1'b0, output_2_udp_hdr_valid_next; -reg output_3_udp_hdr_valid_reg = 1'b0, output_3_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0, output_eth_dest_mac_next; -reg [47:0] output_eth_src_mac_reg = 48'd0, output_eth_src_mac_next; -reg [15:0] output_eth_type_reg = 16'd0, output_eth_type_next; -reg [3:0] output_ip_version_reg = 4'd0, output_ip_version_next; -reg [3:0] output_ip_ihl_reg = 4'd0, output_ip_ihl_next; -reg [5:0] output_ip_dscp_reg = 6'd0, output_ip_dscp_next; -reg [1:0] output_ip_ecn_reg = 2'd0, output_ip_ecn_next; -reg [15:0] output_ip_length_reg = 16'd0, output_ip_length_next; -reg [15:0] output_ip_identification_reg = 16'd0, output_ip_identification_next; -reg [2:0] output_ip_flags_reg = 3'd0, output_ip_flags_next; -reg [12:0] output_ip_fragment_offset_reg = 13'd0, output_ip_fragment_offset_next; -reg [7:0] output_ip_ttl_reg = 8'd0, output_ip_ttl_next; -reg [7:0] output_ip_protocol_reg = 8'd0, output_ip_protocol_next; -reg [15:0] output_ip_header_checksum_reg = 16'd0, output_ip_header_checksum_next; -reg [31:0] output_ip_source_ip_reg = 32'd0, output_ip_source_ip_next; -reg [31:0] output_ip_dest_ip_reg = 32'd0, output_ip_dest_ip_next; -reg [15:0] output_udp_source_port_reg = 16'd0, output_udp_source_port_next; -reg [15:0] output_udp_dest_port_reg = 16'd0, output_udp_dest_port_next; -reg [15:0] output_udp_length_reg = 16'd0, output_udp_length_next; -reg [15:0] output_udp_checksum_reg = 16'd0, output_udp_checksum_next; - -// internal datapath -reg [63:0] output_udp_payload_tdata_int; -reg [7:0] output_udp_payload_tkeep_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int_reg = 1'b0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; - -assign input_udp_hdr_ready = input_udp_hdr_ready_reg; -assign input_udp_payload_tready = input_udp_payload_tready_reg; - -assign output_0_udp_hdr_valid = output_0_udp_hdr_valid_reg; -assign output_0_eth_dest_mac = output_eth_dest_mac_reg; -assign output_0_eth_src_mac = output_eth_src_mac_reg; -assign output_0_eth_type = output_eth_type_reg; -assign output_0_ip_version = output_ip_version_reg; -assign output_0_ip_ihl = output_ip_ihl_reg; -assign output_0_ip_dscp = output_ip_dscp_reg; -assign output_0_ip_ecn = output_ip_ecn_reg; -assign output_0_ip_length = output_ip_length_reg; -assign output_0_ip_identification = output_ip_identification_reg; -assign output_0_ip_flags = output_ip_flags_reg; -assign output_0_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_0_ip_ttl = output_ip_ttl_reg; -assign output_0_ip_protocol = output_ip_protocol_reg; -assign output_0_ip_header_checksum = output_ip_header_checksum_reg; -assign output_0_ip_source_ip = output_ip_source_ip_reg; -assign output_0_ip_dest_ip = output_ip_dest_ip_reg; -assign output_0_udp_source_port = output_udp_source_port_reg; -assign output_0_udp_dest_port = output_udp_dest_port_reg; -assign output_0_udp_length = output_udp_length_reg; -assign output_0_udp_checksum = output_udp_checksum_reg; - -assign output_1_udp_hdr_valid = output_1_udp_hdr_valid_reg; -assign output_1_eth_dest_mac = output_eth_dest_mac_reg; -assign output_1_eth_src_mac = output_eth_src_mac_reg; -assign output_1_eth_type = output_eth_type_reg; -assign output_1_ip_version = output_ip_version_reg; -assign output_1_ip_ihl = output_ip_ihl_reg; -assign output_1_ip_dscp = output_ip_dscp_reg; -assign output_1_ip_ecn = output_ip_ecn_reg; -assign output_1_ip_length = output_ip_length_reg; -assign output_1_ip_identification = output_ip_identification_reg; -assign output_1_ip_flags = output_ip_flags_reg; -assign output_1_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_1_ip_ttl = output_ip_ttl_reg; -assign output_1_ip_protocol = output_ip_protocol_reg; -assign output_1_ip_header_checksum = output_ip_header_checksum_reg; -assign output_1_ip_source_ip = output_ip_source_ip_reg; -assign output_1_ip_dest_ip = output_ip_dest_ip_reg; -assign output_1_udp_source_port = output_udp_source_port_reg; -assign output_1_udp_dest_port = output_udp_dest_port_reg; -assign output_1_udp_length = output_udp_length_reg; -assign output_1_udp_checksum = output_udp_checksum_reg; - -assign output_2_udp_hdr_valid = output_2_udp_hdr_valid_reg; -assign output_2_eth_dest_mac = output_eth_dest_mac_reg; -assign output_2_eth_src_mac = output_eth_src_mac_reg; -assign output_2_eth_type = output_eth_type_reg; -assign output_2_ip_version = output_ip_version_reg; -assign output_2_ip_ihl = output_ip_ihl_reg; -assign output_2_ip_dscp = output_ip_dscp_reg; -assign output_2_ip_ecn = output_ip_ecn_reg; -assign output_2_ip_length = output_ip_length_reg; -assign output_2_ip_identification = output_ip_identification_reg; -assign output_2_ip_flags = output_ip_flags_reg; -assign output_2_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_2_ip_ttl = output_ip_ttl_reg; -assign output_2_ip_protocol = output_ip_protocol_reg; -assign output_2_ip_header_checksum = output_ip_header_checksum_reg; -assign output_2_ip_source_ip = output_ip_source_ip_reg; -assign output_2_ip_dest_ip = output_ip_dest_ip_reg; -assign output_2_udp_source_port = output_udp_source_port_reg; -assign output_2_udp_dest_port = output_udp_dest_port_reg; -assign output_2_udp_length = output_udp_length_reg; -assign output_2_udp_checksum = output_udp_checksum_reg; - -assign output_3_udp_hdr_valid = output_3_udp_hdr_valid_reg; -assign output_3_eth_dest_mac = output_eth_dest_mac_reg; -assign output_3_eth_src_mac = output_eth_src_mac_reg; -assign output_3_eth_type = output_eth_type_reg; -assign output_3_ip_version = output_ip_version_reg; -assign output_3_ip_ihl = output_ip_ihl_reg; -assign output_3_ip_dscp = output_ip_dscp_reg; -assign output_3_ip_ecn = output_ip_ecn_reg; -assign output_3_ip_length = output_ip_length_reg; -assign output_3_ip_identification = output_ip_identification_reg; -assign output_3_ip_flags = output_ip_flags_reg; -assign output_3_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_3_ip_ttl = output_ip_ttl_reg; -assign output_3_ip_protocol = output_ip_protocol_reg; -assign output_3_ip_header_checksum = output_ip_header_checksum_reg; -assign output_3_ip_source_ip = output_ip_source_ip_reg; -assign output_3_ip_dest_ip = output_ip_dest_ip_reg; -assign output_3_udp_source_port = output_udp_source_port_reg; -assign output_3_udp_dest_port = output_udp_dest_port_reg; -assign output_3_udp_length = output_udp_length_reg; -assign output_3_udp_checksum = output_udp_checksum_reg; - -// mux for output control signals -reg current_output_udp_hdr_valid; -reg current_output_udp_hdr_ready; -reg current_output_tvalid; -reg current_output_tready; -always @* begin - case (select_reg) - 2'd0: begin - current_output_udp_hdr_valid = output_0_udp_hdr_valid; - current_output_udp_hdr_ready = output_0_udp_hdr_ready; - current_output_tvalid = output_0_udp_payload_tvalid; - current_output_tready = output_0_udp_payload_tready; - end - 2'd1: begin - current_output_udp_hdr_valid = output_1_udp_hdr_valid; - current_output_udp_hdr_ready = output_1_udp_hdr_ready; - current_output_tvalid = output_1_udp_payload_tvalid; - current_output_tready = output_1_udp_payload_tready; - end - 2'd2: begin - current_output_udp_hdr_valid = output_2_udp_hdr_valid; - current_output_udp_hdr_ready = output_2_udp_hdr_ready; - current_output_tvalid = output_2_udp_payload_tvalid; - current_output_tready = output_2_udp_payload_tready; - end - 2'd3: begin - current_output_udp_hdr_valid = output_3_udp_hdr_valid; - current_output_udp_hdr_ready = output_3_udp_hdr_ready; - current_output_tvalid = output_3_udp_payload_tvalid; - current_output_tready = output_3_udp_payload_tready; - end - default: begin - current_output_udp_hdr_valid = 1'b0; - current_output_udp_hdr_ready = 1'b0; - current_output_tvalid = 1'b0; - current_output_tready = 1'b0; - end - endcase -end - -always @* begin - select_next = select_reg; - frame_next = frame_reg; - - input_udp_hdr_ready_next = input_udp_hdr_ready_reg & ~input_udp_hdr_valid; - input_udp_payload_tready_next = 1'b0; - output_0_udp_hdr_valid_next = output_0_udp_hdr_valid_reg & ~output_0_udp_hdr_ready; - output_1_udp_hdr_valid_next = output_1_udp_hdr_valid_reg & ~output_1_udp_hdr_ready; - output_2_udp_hdr_valid_next = output_2_udp_hdr_valid_reg & ~output_2_udp_hdr_ready; - output_3_udp_hdr_valid_next = output_3_udp_hdr_valid_reg & ~output_3_udp_hdr_ready; - output_eth_dest_mac_next = output_eth_dest_mac_reg; - output_eth_src_mac_next = output_eth_src_mac_reg; - output_eth_type_next = output_eth_type_reg; - output_ip_version_next = output_ip_version_reg; - output_ip_ihl_next = output_ip_ihl_reg; - output_ip_dscp_next = output_ip_dscp_reg; - output_ip_ecn_next = output_ip_ecn_reg; - output_ip_length_next = output_ip_length_reg; - output_ip_identification_next = output_ip_identification_reg; - output_ip_flags_next = output_ip_flags_reg; - output_ip_fragment_offset_next = output_ip_fragment_offset_reg; - output_ip_ttl_next = output_ip_ttl_reg; - output_ip_protocol_next = output_ip_protocol_reg; - output_ip_header_checksum_next = output_ip_header_checksum_reg; - output_ip_source_ip_next = output_ip_source_ip_reg; - output_ip_dest_ip_next = output_ip_dest_ip_reg; - output_udp_source_port_next = output_udp_source_port_reg; - output_udp_dest_port_next = output_udp_dest_port_reg; - output_udp_length_next = output_udp_length_reg; - output_udp_checksum_next = output_udp_checksum_reg; - - if (input_udp_payload_tvalid & input_udp_payload_tready) begin - // end of frame detection - if (input_udp_payload_tlast) begin - frame_next = 1'b0; - end - end - - if (~frame_reg & enable & input_udp_hdr_valid & ~current_output_udp_hdr_valid & ~current_output_tvalid) begin - // start of frame, grab select value - frame_next = 1'b1; - select_next = select; - - input_udp_hdr_ready_next = 1'b1; - - case (select) - 2'd0: output_0_udp_hdr_valid_next = 1'b1; - 2'd1: output_1_udp_hdr_valid_next = 1'b1; - 2'd2: output_2_udp_hdr_valid_next = 1'b1; - 2'd3: output_3_udp_hdr_valid_next = 1'b1; - endcase - output_eth_dest_mac_next = input_eth_dest_mac; - output_eth_src_mac_next = input_eth_src_mac; - output_eth_type_next = input_eth_type; - output_ip_version_next = input_ip_version; - output_ip_ihl_next = input_ip_ihl; - output_ip_dscp_next = input_ip_dscp; - output_ip_ecn_next = input_ip_ecn; - output_ip_length_next = input_ip_length; - output_ip_identification_next = input_ip_identification; - output_ip_flags_next = input_ip_flags; - output_ip_fragment_offset_next = input_ip_fragment_offset; - output_ip_ttl_next = input_ip_ttl; - output_ip_protocol_next = input_ip_protocol; - output_ip_header_checksum_next = input_ip_header_checksum; - output_ip_source_ip_next = input_ip_source_ip; - output_ip_dest_ip_next = input_ip_dest_ip; - output_udp_source_port_next = input_udp_source_port; - output_udp_dest_port_next = input_udp_dest_port; - output_udp_length_next = input_udp_length; - output_udp_checksum_next = input_udp_checksum; - end - - input_udp_payload_tready_next = output_udp_payload_tready_int_early & frame_next; - - output_udp_payload_tdata_int = input_udp_payload_tdata; - output_udp_payload_tkeep_int = input_udp_payload_tkeep; - output_udp_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tready; - output_udp_payload_tlast_int = input_udp_payload_tlast; - output_udp_payload_tuser_int = input_udp_payload_tuser; -end - -always @(posedge clk) begin - if (rst) begin - select_reg <= 2'd0; - frame_reg <= 1'b0; - input_udp_hdr_ready_reg <= 1'b0; - input_udp_payload_tready_reg <= 1'b0; - output_0_udp_hdr_valid_reg <= 1'b0; - output_1_udp_hdr_valid_reg <= 1'b0; - output_2_udp_hdr_valid_reg <= 1'b0; - output_3_udp_hdr_valid_reg <= 1'b0; - end else begin - select_reg <= select_next; - frame_reg <= frame_next; - input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; - input_udp_payload_tready_reg <= input_udp_payload_tready_next; - output_0_udp_hdr_valid_reg <= output_0_udp_hdr_valid_next; - output_1_udp_hdr_valid_reg <= output_1_udp_hdr_valid_next; - output_2_udp_hdr_valid_reg <= output_2_udp_hdr_valid_next; - output_3_udp_hdr_valid_reg <= output_3_udp_hdr_valid_next; - end - - output_eth_dest_mac_reg <= output_eth_dest_mac_next; - output_eth_src_mac_reg <= output_eth_src_mac_next; - output_eth_type_reg <= output_eth_type_next; - output_ip_version_reg <= output_ip_version_next; - output_ip_ihl_reg <= output_ip_ihl_next; - output_ip_dscp_reg <= output_ip_dscp_next; - output_ip_ecn_reg <= output_ip_ecn_next; - output_ip_length_reg <= output_ip_length_next; - output_ip_identification_reg <= output_ip_identification_next; - output_ip_flags_reg <= output_ip_flags_next; - output_ip_fragment_offset_reg <= output_ip_fragment_offset_next; - output_ip_ttl_reg <= output_ip_ttl_next; - output_ip_protocol_reg <= output_ip_protocol_next; - output_ip_header_checksum_reg <= output_ip_header_checksum_next; - output_ip_source_ip_reg <= output_ip_source_ip_next; - output_ip_dest_ip_reg <= output_ip_dest_ip_next; - output_udp_source_port_reg <= output_udp_source_port_next; - output_udp_dest_port_reg <= output_udp_dest_port_next; - output_udp_length_reg <= output_udp_length_next; - output_udp_checksum_reg <= output_udp_checksum_next; -end - -// output datapath logic -reg [63:0] output_udp_payload_tdata_reg = 64'd0; -reg [7:0] output_udp_payload_tkeep_reg = 8'd0; -reg output_0_udp_payload_tvalid_reg = 1'b0, output_0_udp_payload_tvalid_next; -reg output_1_udp_payload_tvalid_reg = 1'b0, output_1_udp_payload_tvalid_next; -reg output_2_udp_payload_tvalid_reg = 1'b0, output_2_udp_payload_tvalid_next; -reg output_3_udp_payload_tvalid_reg = 1'b0, output_3_udp_payload_tvalid_next; -reg output_udp_payload_tlast_reg = 1'b0; -reg output_udp_payload_tuser_reg = 1'b0; - -reg [63:0] temp_udp_payload_tdata_reg = 64'd0; -reg [7:0] temp_udp_payload_tkeep_reg = 8'd0; -reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; -reg temp_udp_payload_tlast_reg = 1'b0; -reg temp_udp_payload_tuser_reg = 1'b0; - -// datapath control -reg store_udp_payload_int_to_output; -reg store_udp_payload_int_to_temp; -reg store_udp_payload_temp_to_output; - -assign output_0_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_0_udp_payload_tkeep = output_udp_payload_tkeep_reg; -assign output_0_udp_payload_tvalid = output_0_udp_payload_tvalid_reg; -assign output_0_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_0_udp_payload_tuser = output_udp_payload_tuser_reg; - -assign output_1_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_1_udp_payload_tkeep = output_udp_payload_tkeep_reg; -assign output_1_udp_payload_tvalid = output_1_udp_payload_tvalid_reg; -assign output_1_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_1_udp_payload_tuser = output_udp_payload_tuser_reg; - -assign output_2_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_2_udp_payload_tkeep = output_udp_payload_tkeep_reg; -assign output_2_udp_payload_tvalid = output_2_udp_payload_tvalid_reg; -assign output_2_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_2_udp_payload_tuser = output_udp_payload_tuser_reg; - -assign output_3_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_3_udp_payload_tkeep = output_udp_payload_tkeep_reg; -assign output_3_udp_payload_tvalid = output_3_udp_payload_tvalid_reg; -assign output_3_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_3_udp_payload_tuser = output_udp_payload_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_udp_payload_tready_int_early = current_output_tready | (~temp_udp_payload_tvalid_reg & (~current_output_tvalid | ~output_udp_payload_tvalid_int)); - -always @* begin - // transfer sink ready state to source - output_0_udp_payload_tvalid_next = output_0_udp_payload_tvalid_reg; - output_1_udp_payload_tvalid_next = output_1_udp_payload_tvalid_reg; - output_2_udp_payload_tvalid_next = output_2_udp_payload_tvalid_reg; - output_3_udp_payload_tvalid_next = output_3_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - - store_udp_payload_int_to_output = 1'b0; - store_udp_payload_int_to_temp = 1'b0; - store_udp_payload_temp_to_output = 1'b0; - - if (output_udp_payload_tready_int_reg) begin - // input is ready - if (current_output_tready | ~current_output_tvalid) begin - // output is ready or currently not valid, transfer data to output - output_0_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd0); - output_1_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd1); - output_2_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd2); - output_3_udp_payload_tvalid_next = output_udp_payload_tvalid_int & (select_reg == 2'd3); - store_udp_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; - store_udp_payload_int_to_temp = 1'b1; - end - end else if (current_output_tready) begin - // input is not ready, but output is ready - output_0_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd0); - output_1_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd1); - output_2_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd2); - output_3_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg & (select_reg == 2'd3); - temp_udp_payload_tvalid_next = 1'b0; - store_udp_payload_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - output_0_udp_payload_tvalid_reg <= 1'b0; - output_1_udp_payload_tvalid_reg <= 1'b0; - output_2_udp_payload_tvalid_reg <= 1'b0; - output_3_udp_payload_tvalid_reg <= 1'b0; - output_udp_payload_tready_int_reg <= 1'b0; - temp_udp_payload_tvalid_reg <= 1'b0; - end else begin - output_0_udp_payload_tvalid_reg <= output_0_udp_payload_tvalid_next; - output_1_udp_payload_tvalid_reg <= output_1_udp_payload_tvalid_next; - output_2_udp_payload_tvalid_reg <= output_2_udp_payload_tvalid_next; - output_3_udp_payload_tvalid_reg <= output_3_udp_payload_tvalid_next; - output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; - temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; - end - - // datapath - if (store_udp_payload_int_to_output) begin - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else if (store_udp_payload_temp_to_output) begin - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; - end - - if (store_udp_payload_int_to_temp) begin - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end -end - -endmodule diff --git a/tb/test_udp_demux_4.py b/tb/test_udp_demux_4.py index f35b3b1a3..45a2c0b1b 100755 --- a/tb/test_udp_demux_4.py +++ b/tb/test_udp_demux_4.py @@ -28,8 +28,8 @@ import os import udp_ep -module = 'udp_demux_4' -testbench = 'test_%s' % module +module = 'udp_demux' +testbench = 'test_%s_4' % module srcs = [] @@ -42,340 +42,208 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + M_COUNT = 4 + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_udp_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_udp_source_port = Signal(intbv(0)[16:]) - input_udp_dest_port = Signal(intbv(0)[16:]) - input_udp_length = Signal(intbv(0)[16:]) - input_udp_checksum = Signal(intbv(0)[16:]) - input_udp_payload_tdata = Signal(intbv(0)[8:]) - input_udp_payload_tvalid = Signal(bool(0)) - input_udp_payload_tlast = Signal(bool(0)) - input_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_udp_source_port = Signal(intbv(0)[16:]) + s_udp_dest_port = Signal(intbv(0)[16:]) + s_udp_length = Signal(intbv(0)[16:]) + s_udp_checksum = Signal(intbv(0)[16:]) + s_udp_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_udp_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_udp_payload_axis_tvalid = Signal(bool(0)) + s_udp_payload_axis_tlast = Signal(bool(0)) + s_udp_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_udp_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_udp_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_0_udp_hdr_ready = Signal(bool(0)) - output_0_udp_payload_tready = Signal(bool(0)) - output_1_udp_hdr_ready = Signal(bool(0)) - output_1_udp_payload_tready = Signal(bool(0)) - output_2_udp_hdr_ready = Signal(bool(0)) - output_2_udp_payload_tready = Signal(bool(0)) - output_3_udp_hdr_ready = Signal(bool(0)) - output_3_udp_payload_tready = Signal(bool(0)) + m_udp_hdr_ready_list = [Signal(bool(0)) for i in range(M_COUNT)] + m_udp_payload_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_udp_hdr_ready = ConcatSignal(*reversed(m_udp_hdr_ready_list)) + m_udp_payload_axis_tready = ConcatSignal(*reversed(m_udp_payload_axis_tready_list)) enable = Signal(bool(0)) + drop = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_udp_hdr_ready = Signal(bool(0)) - input_udp_payload_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(bool(0)) + s_udp_payload_axis_tready = Signal(bool(0)) - output_0_udp_hdr_valid = Signal(bool(0)) - output_0_eth_dest_mac = Signal(intbv(0)[48:]) - output_0_eth_src_mac = Signal(intbv(0)[48:]) - output_0_eth_type = Signal(intbv(0)[16:]) - output_0_ip_version = Signal(intbv(0)[4:]) - output_0_ip_ihl = Signal(intbv(0)[4:]) - output_0_ip_dscp = Signal(intbv(0)[6:]) - output_0_ip_ecn = Signal(intbv(0)[2:]) - output_0_ip_length = Signal(intbv(0)[16:]) - output_0_ip_identification = Signal(intbv(0)[16:]) - output_0_ip_flags = Signal(intbv(0)[3:]) - output_0_ip_fragment_offset = Signal(intbv(0)[13:]) - output_0_ip_ttl = Signal(intbv(0)[8:]) - output_0_ip_protocol = Signal(intbv(0)[8:]) - output_0_ip_header_checksum = Signal(intbv(0)[16:]) - output_0_ip_source_ip = Signal(intbv(0)[32:]) - output_0_ip_dest_ip = Signal(intbv(0)[32:]) - output_0_udp_source_port = Signal(intbv(0)[16:]) - output_0_udp_dest_port = Signal(intbv(0)[16:]) - output_0_udp_length = Signal(intbv(0)[16:]) - output_0_udp_checksum = Signal(intbv(0)[16:]) - output_0_udp_payload_tdata = Signal(intbv(0)[8:]) - output_0_udp_payload_tvalid = Signal(bool(0)) - output_0_udp_payload_tlast = Signal(bool(0)) - output_0_udp_payload_tuser = Signal(bool(0)) - output_1_udp_hdr_valid = Signal(bool(0)) - output_1_eth_dest_mac = Signal(intbv(0)[48:]) - output_1_eth_src_mac = Signal(intbv(0)[48:]) - output_1_eth_type = Signal(intbv(0)[16:]) - output_1_ip_version = Signal(intbv(0)[4:]) - output_1_ip_ihl = Signal(intbv(0)[4:]) - output_1_ip_dscp = Signal(intbv(0)[6:]) - output_1_ip_ecn = Signal(intbv(0)[2:]) - output_1_ip_length = Signal(intbv(0)[16:]) - output_1_ip_identification = Signal(intbv(0)[16:]) - output_1_ip_flags = Signal(intbv(0)[3:]) - output_1_ip_fragment_offset = Signal(intbv(0)[13:]) - output_1_ip_ttl = Signal(intbv(0)[8:]) - output_1_ip_protocol = Signal(intbv(0)[8:]) - output_1_ip_header_checksum = Signal(intbv(0)[16:]) - output_1_ip_source_ip = Signal(intbv(0)[32:]) - output_1_ip_dest_ip = Signal(intbv(0)[32:]) - output_1_udp_source_port = Signal(intbv(0)[16:]) - output_1_udp_dest_port = Signal(intbv(0)[16:]) - output_1_udp_length = Signal(intbv(0)[16:]) - output_1_udp_checksum = Signal(intbv(0)[16:]) - output_1_udp_payload_tdata = Signal(intbv(0)[8:]) - output_1_udp_payload_tvalid = Signal(bool(0)) - output_1_udp_payload_tlast = Signal(bool(0)) - output_1_udp_payload_tuser = Signal(bool(0)) - output_2_udp_hdr_valid = Signal(bool(0)) - output_2_eth_dest_mac = Signal(intbv(0)[48:]) - output_2_eth_src_mac = Signal(intbv(0)[48:]) - output_2_eth_type = Signal(intbv(0)[16:]) - output_2_ip_version = Signal(intbv(0)[4:]) - output_2_ip_ihl = Signal(intbv(0)[4:]) - output_2_ip_dscp = Signal(intbv(0)[6:]) - output_2_ip_ecn = Signal(intbv(0)[2:]) - output_2_ip_length = Signal(intbv(0)[16:]) - output_2_ip_identification = Signal(intbv(0)[16:]) - output_2_ip_flags = Signal(intbv(0)[3:]) - output_2_ip_fragment_offset = Signal(intbv(0)[13:]) - output_2_ip_ttl = Signal(intbv(0)[8:]) - output_2_ip_protocol = Signal(intbv(0)[8:]) - output_2_ip_header_checksum = Signal(intbv(0)[16:]) - output_2_ip_source_ip = Signal(intbv(0)[32:]) - output_2_ip_dest_ip = Signal(intbv(0)[32:]) - output_2_udp_source_port = Signal(intbv(0)[16:]) - output_2_udp_dest_port = Signal(intbv(0)[16:]) - output_2_udp_length = Signal(intbv(0)[16:]) - output_2_udp_checksum = Signal(intbv(0)[16:]) - output_2_udp_payload_tdata = Signal(intbv(0)[8:]) - output_2_udp_payload_tvalid = Signal(bool(0)) - output_2_udp_payload_tlast = Signal(bool(0)) - output_2_udp_payload_tuser = Signal(bool(0)) - output_3_udp_hdr_valid = Signal(bool(0)) - output_3_eth_dest_mac = Signal(intbv(0)[48:]) - output_3_eth_src_mac = Signal(intbv(0)[48:]) - output_3_eth_type = Signal(intbv(0)[16:]) - output_3_ip_version = Signal(intbv(0)[4:]) - output_3_ip_ihl = Signal(intbv(0)[4:]) - output_3_ip_dscp = Signal(intbv(0)[6:]) - output_3_ip_ecn = Signal(intbv(0)[2:]) - output_3_ip_length = Signal(intbv(0)[16:]) - output_3_ip_identification = Signal(intbv(0)[16:]) - output_3_ip_flags = Signal(intbv(0)[3:]) - output_3_ip_fragment_offset = Signal(intbv(0)[13:]) - output_3_ip_ttl = Signal(intbv(0)[8:]) - output_3_ip_protocol = Signal(intbv(0)[8:]) - output_3_ip_header_checksum = Signal(intbv(0)[16:]) - output_3_ip_source_ip = Signal(intbv(0)[32:]) - output_3_ip_dest_ip = Signal(intbv(0)[32:]) - output_3_udp_source_port = Signal(intbv(0)[16:]) - output_3_udp_dest_port = Signal(intbv(0)[16:]) - output_3_udp_length = Signal(intbv(0)[16:]) - output_3_udp_checksum = Signal(intbv(0)[16:]) - output_3_udp_payload_tdata = Signal(intbv(0)[8:]) - output_3_udp_payload_tvalid = Signal(bool(0)) - output_3_udp_payload_tlast = Signal(bool(0)) - output_3_udp_payload_tuser = Signal(bool(0)) + m_udp_hdr_valid = Signal(intbv(0)[M_COUNT:]) + m_eth_dest_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_src_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_type = Signal(intbv(0)[M_COUNT*16:]) + m_ip_version = Signal(intbv(0)[M_COUNT*4:]) + m_ip_ihl = Signal(intbv(0)[M_COUNT*4:]) + m_ip_dscp = Signal(intbv(0)[M_COUNT*6:]) + m_ip_ecn = Signal(intbv(0)[M_COUNT*2:]) + m_ip_length = Signal(intbv(0)[M_COUNT*16:]) + m_ip_identification = Signal(intbv(0)[M_COUNT*16:]) + m_ip_flags = Signal(intbv(0)[M_COUNT*3:]) + m_ip_fragment_offset = Signal(intbv(0)[M_COUNT*13:]) + m_ip_ttl = Signal(intbv(0)[M_COUNT*8:]) + m_ip_protocol = Signal(intbv(0)[M_COUNT*8:]) + m_ip_header_checksum = Signal(intbv(0)[M_COUNT*16:]) + m_ip_source_ip = Signal(intbv(0)[M_COUNT*32:]) + m_ip_dest_ip = Signal(intbv(0)[M_COUNT*32:]) + m_udp_source_port = Signal(intbv(0)[M_COUNT*16:]) + m_udp_dest_port = Signal(intbv(0)[M_COUNT*16:]) + m_udp_length = Signal(intbv(0)[M_COUNT*16:]) + m_udp_checksum = Signal(intbv(0)[M_COUNT*16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_udp_payload_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_udp_payload_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_udp_payload_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_udp_payload_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_udp_payload_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_udp_payload_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_udp_hdr_valid_list = [m_udp_hdr_valid(i) for i in range(M_COUNT)] + m_eth_dest_mac_list = [m_eth_dest_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_src_mac_list = [m_eth_src_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_type_list = [m_eth_type((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_version_list = [m_ip_version((i+1)*4, i*4) for i in range(M_COUNT)] + m_ip_ihl_list = [m_ip_ihl((i+1)*4, i*4) for i in range(M_COUNT)] + m_ip_dscp_list = [m_ip_dscp((i+1)*6, i*6) for i in range(M_COUNT)] + m_ip_ecn_list = [m_ip_ecn((i+1)*2, i*2) for i in range(M_COUNT)] + m_ip_length_list = [m_ip_length((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_identification_list = [m_ip_identification((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_flags_list = [m_ip_flags((i+1)*3, i*3) for i in range(M_COUNT)] + m_ip_fragment_offset_list = [m_ip_fragment_offset((i+1)*13, i*13) for i in range(M_COUNT)] + m_ip_ttl_list = [m_ip_ttl((i+1)*8, i*8) for i in range(M_COUNT)] + m_ip_protocol_list = [m_ip_protocol((i+1)*8, i*8) for i in range(M_COUNT)] + m_ip_header_checksum_list = [m_ip_header_checksum((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_source_ip_list = [m_ip_source_ip((i+1)*32, i*32) for i in range(M_COUNT)] + m_ip_dest_ip_list = [m_ip_dest_ip((i+1)*32, i*32) for i in range(M_COUNT)] + m_udp_source_port_list = [m_udp_source_port((i+1)*16, i*16) for i in range(M_COUNT)] + m_udp_dest_port_list = [m_udp_dest_port((i+1)*16, i*16) for i in range(M_COUNT)] + m_udp_length_list = [m_udp_length((i+1)*16, i*16) for i in range(M_COUNT)] + m_udp_checksum_list = [m_udp_checksum((i+1)*16, i*16) for i in range(M_COUNT)] + m_udp_payload_axis_tdata_list = [m_udp_payload_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_udp_payload_axis_tkeep_list = [m_udp_payload_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_udp_payload_axis_tvalid_list = [m_udp_payload_axis_tvalid(i) for i in range(M_COUNT)] + m_udp_payload_axis_tlast_list = [m_udp_payload_axis_tlast(i) for i in range(M_COUNT)] + m_udp_payload_axis_tid_list = [m_udp_payload_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_udp_payload_axis_tdest_list = [m_udp_payload_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_udp_payload_axis_tuser_list = [m_udp_payload_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks source_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] source = udp_ep.UDPFrameSource() source_logic = source.create_logic( clk, rst, - udp_hdr_ready=input_udp_hdr_ready, - udp_hdr_valid=input_udp_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - udp_source_port=input_udp_source_port, - udp_dest_port=input_udp_dest_port, - udp_length=input_udp_length, - udp_checksum=input_udp_checksum, - udp_payload_tdata=input_udp_payload_tdata, - udp_payload_tvalid=input_udp_payload_tvalid, - udp_payload_tready=input_udp_payload_tready, - udp_payload_tlast=input_udp_payload_tlast, - udp_payload_tuser=input_udp_payload_tuser, + udp_hdr_ready=s_udp_hdr_ready, + udp_hdr_valid=s_udp_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + udp_source_port=s_udp_source_port, + udp_dest_port=s_udp_dest_port, + udp_length=s_udp_length, + udp_checksum=s_udp_checksum, + udp_payload_tdata=s_udp_payload_axis_tdata, + udp_payload_tkeep=s_udp_payload_axis_tkeep, + udp_payload_tvalid=s_udp_payload_axis_tvalid, + udp_payload_tready=s_udp_payload_axis_tready, + udp_payload_tlast=s_udp_payload_axis_tlast, + udp_payload_tuser=s_udp_payload_axis_tuser, pause=source_pause, name='source' ) - sink_0 = udp_ep.UDPFrameSink() + for k in range(M_COUNT): + s = udp_ep.UDPFrameSink() + p = Signal(bool(0)) - sink_0_logic = sink_0.create_logic( - clk, - rst, - udp_hdr_ready=output_0_udp_hdr_ready, - udp_hdr_valid=output_0_udp_hdr_valid, - eth_dest_mac=output_0_eth_dest_mac, - eth_src_mac=output_0_eth_src_mac, - eth_type=output_0_eth_type, - ip_version=output_0_ip_version, - ip_ihl=output_0_ip_ihl, - ip_dscp=output_0_ip_dscp, - ip_ecn=output_0_ip_ecn, - ip_length=output_0_ip_length, - ip_identification=output_0_ip_identification, - ip_flags=output_0_ip_flags, - ip_fragment_offset=output_0_ip_fragment_offset, - ip_ttl=output_0_ip_ttl, - ip_protocol=output_0_ip_protocol, - ip_header_checksum=output_0_ip_header_checksum, - ip_source_ip=output_0_ip_source_ip, - ip_dest_ip=output_0_ip_dest_ip, - udp_source_port=output_0_udp_source_port, - udp_dest_port=output_0_udp_dest_port, - udp_length=output_0_udp_length, - udp_checksum=output_0_udp_checksum, - udp_payload_tdata=output_0_udp_payload_tdata, - udp_payload_tvalid=output_0_udp_payload_tvalid, - udp_payload_tready=output_0_udp_payload_tready, - udp_payload_tlast=output_0_udp_payload_tlast, - udp_payload_tuser=output_0_udp_payload_tuser, - pause=sink_0_pause, - name='sink_0' - ) + sink_list.append(s) + sink_pause_list.append(p) - sink_1 = udp_ep.UDPFrameSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - udp_hdr_ready=output_1_udp_hdr_ready, - udp_hdr_valid=output_1_udp_hdr_valid, - eth_dest_mac=output_1_eth_dest_mac, - eth_src_mac=output_1_eth_src_mac, - eth_type=output_1_eth_type, - ip_version=output_1_ip_version, - ip_ihl=output_1_ip_ihl, - ip_dscp=output_1_ip_dscp, - ip_ecn=output_1_ip_ecn, - ip_length=output_1_ip_length, - ip_identification=output_1_ip_identification, - ip_flags=output_1_ip_flags, - ip_fragment_offset=output_1_ip_fragment_offset, - ip_ttl=output_1_ip_ttl, - ip_protocol=output_1_ip_protocol, - ip_header_checksum=output_1_ip_header_checksum, - ip_source_ip=output_1_ip_source_ip, - ip_dest_ip=output_1_ip_dest_ip, - udp_source_port=output_1_udp_source_port, - udp_dest_port=output_1_udp_dest_port, - udp_length=output_1_udp_length, - udp_checksum=output_1_udp_checksum, - udp_payload_tdata=output_1_udp_payload_tdata, - udp_payload_tvalid=output_1_udp_payload_tvalid, - udp_payload_tready=output_1_udp_payload_tready, - udp_payload_tlast=output_1_udp_payload_tlast, - udp_payload_tuser=output_1_udp_payload_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = udp_ep.UDPFrameSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - udp_hdr_ready=output_2_udp_hdr_ready, - udp_hdr_valid=output_2_udp_hdr_valid, - eth_dest_mac=output_2_eth_dest_mac, - eth_src_mac=output_2_eth_src_mac, - eth_type=output_2_eth_type, - ip_version=output_2_ip_version, - ip_ihl=output_2_ip_ihl, - ip_dscp=output_2_ip_dscp, - ip_ecn=output_2_ip_ecn, - ip_length=output_2_ip_length, - ip_identification=output_2_ip_identification, - ip_flags=output_2_ip_flags, - ip_fragment_offset=output_2_ip_fragment_offset, - ip_ttl=output_2_ip_ttl, - ip_protocol=output_2_ip_protocol, - ip_header_checksum=output_2_ip_header_checksum, - ip_source_ip=output_2_ip_source_ip, - ip_dest_ip=output_2_ip_dest_ip, - udp_source_port=output_2_udp_source_port, - udp_dest_port=output_2_udp_dest_port, - udp_length=output_2_udp_length, - udp_checksum=output_2_udp_checksum, - udp_payload_tdata=output_2_udp_payload_tdata, - udp_payload_tvalid=output_2_udp_payload_tvalid, - udp_payload_tready=output_2_udp_payload_tready, - udp_payload_tlast=output_2_udp_payload_tlast, - udp_payload_tuser=output_2_udp_payload_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = udp_ep.UDPFrameSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - udp_hdr_ready=output_3_udp_hdr_ready, - udp_hdr_valid=output_3_udp_hdr_valid, - eth_dest_mac=output_3_eth_dest_mac, - eth_src_mac=output_3_eth_src_mac, - eth_type=output_3_eth_type, - ip_version=output_3_ip_version, - ip_ihl=output_3_ip_ihl, - ip_dscp=output_3_ip_dscp, - ip_ecn=output_3_ip_ecn, - ip_length=output_3_ip_length, - ip_identification=output_3_ip_identification, - ip_flags=output_3_ip_flags, - ip_fragment_offset=output_3_ip_fragment_offset, - ip_ttl=output_3_ip_ttl, - ip_protocol=output_3_ip_protocol, - ip_header_checksum=output_3_ip_header_checksum, - ip_source_ip=output_3_ip_source_ip, - ip_dest_ip=output_3_ip_dest_ip, - udp_source_port=output_3_udp_source_port, - udp_dest_port=output_3_udp_dest_port, - udp_length=output_3_udp_length, - udp_checksum=output_3_udp_checksum, - udp_payload_tdata=output_3_udp_payload_tdata, - udp_payload_tvalid=output_3_udp_payload_tvalid, - udp_payload_tready=output_3_udp_payload_tready, - udp_payload_tlast=output_3_udp_payload_tlast, - udp_payload_tuser=output_3_udp_payload_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + udp_hdr_ready=m_udp_hdr_ready_list[k], + udp_hdr_valid=m_udp_hdr_valid_list[k], + eth_dest_mac=m_eth_dest_mac_list[k], + eth_src_mac=m_eth_src_mac_list[k], + eth_type=m_eth_type_list[k], + ip_version=m_ip_version_list[k], + ip_ihl=m_ip_ihl_list[k], + ip_dscp=m_ip_dscp_list[k], + ip_ecn=m_ip_ecn_list[k], + ip_length=m_ip_length_list[k], + ip_identification=m_ip_identification_list[k], + ip_flags=m_ip_flags_list[k], + ip_fragment_offset=m_ip_fragment_offset_list[k], + ip_ttl=m_ip_ttl_list[k], + ip_protocol=m_ip_protocol_list[k], + ip_header_checksum=m_ip_header_checksum_list[k], + ip_source_ip=m_ip_source_ip_list[k], + ip_dest_ip=m_ip_dest_ip_list[k], + udp_source_port=m_udp_source_port_list[k], + udp_dest_port=m_udp_dest_port_list[k], + udp_length=m_udp_length_list[k], + udp_checksum=m_udp_checksum_list[k], + udp_payload_tdata=m_udp_payload_axis_tdata_list[k], + udp_payload_tkeep=m_udp_payload_axis_tkeep_list[k], + udp_payload_tvalid=m_udp_payload_axis_tvalid_list[k], + udp_payload_tready=m_udp_payload_axis_tready_list[k], + udp_payload_tlast=m_udp_payload_axis_tlast_list[k], + udp_payload_tuser=m_udp_payload_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -387,144 +255,70 @@ def bench(): rst=rst, current_test=current_test, - input_udp_hdr_valid=input_udp_hdr_valid, - input_udp_hdr_ready=input_udp_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_udp_source_port=input_udp_source_port, - input_udp_dest_port=input_udp_dest_port, - input_udp_length=input_udp_length, - input_udp_checksum=input_udp_checksum, - input_udp_payload_tdata=input_udp_payload_tdata, - input_udp_payload_tvalid=input_udp_payload_tvalid, - input_udp_payload_tready=input_udp_payload_tready, - input_udp_payload_tlast=input_udp_payload_tlast, - input_udp_payload_tuser=input_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep=s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tid=s_udp_payload_axis_tid, + s_udp_payload_axis_tdest=s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_0_udp_hdr_valid=output_0_udp_hdr_valid, - output_0_udp_hdr_ready=output_0_udp_hdr_ready, - output_0_eth_dest_mac=output_0_eth_dest_mac, - output_0_eth_src_mac=output_0_eth_src_mac, - output_0_eth_type=output_0_eth_type, - output_0_ip_version=output_0_ip_version, - output_0_ip_ihl=output_0_ip_ihl, - output_0_ip_dscp=output_0_ip_dscp, - output_0_ip_ecn=output_0_ip_ecn, - output_0_ip_length=output_0_ip_length, - output_0_ip_identification=output_0_ip_identification, - output_0_ip_flags=output_0_ip_flags, - output_0_ip_fragment_offset=output_0_ip_fragment_offset, - output_0_ip_ttl=output_0_ip_ttl, - output_0_ip_protocol=output_0_ip_protocol, - output_0_ip_header_checksum=output_0_ip_header_checksum, - output_0_ip_source_ip=output_0_ip_source_ip, - output_0_ip_dest_ip=output_0_ip_dest_ip, - output_0_udp_source_port=output_0_udp_source_port, - output_0_udp_dest_port=output_0_udp_dest_port, - output_0_udp_length=output_0_udp_length, - output_0_udp_checksum=output_0_udp_checksum, - output_0_udp_payload_tdata=output_0_udp_payload_tdata, - output_0_udp_payload_tvalid=output_0_udp_payload_tvalid, - output_0_udp_payload_tready=output_0_udp_payload_tready, - output_0_udp_payload_tlast=output_0_udp_payload_tlast, - output_0_udp_payload_tuser=output_0_udp_payload_tuser, - output_1_udp_hdr_valid=output_1_udp_hdr_valid, - output_1_udp_hdr_ready=output_1_udp_hdr_ready, - output_1_eth_dest_mac=output_1_eth_dest_mac, - output_1_eth_src_mac=output_1_eth_src_mac, - output_1_eth_type=output_1_eth_type, - output_1_ip_version=output_1_ip_version, - output_1_ip_ihl=output_1_ip_ihl, - output_1_ip_dscp=output_1_ip_dscp, - output_1_ip_ecn=output_1_ip_ecn, - output_1_ip_length=output_1_ip_length, - output_1_ip_identification=output_1_ip_identification, - output_1_ip_flags=output_1_ip_flags, - output_1_ip_fragment_offset=output_1_ip_fragment_offset, - output_1_ip_ttl=output_1_ip_ttl, - output_1_ip_protocol=output_1_ip_protocol, - output_1_ip_header_checksum=output_1_ip_header_checksum, - output_1_ip_source_ip=output_1_ip_source_ip, - output_1_ip_dest_ip=output_1_ip_dest_ip, - output_1_udp_source_port=output_1_udp_source_port, - output_1_udp_dest_port=output_1_udp_dest_port, - output_1_udp_length=output_1_udp_length, - output_1_udp_checksum=output_1_udp_checksum, - output_1_udp_payload_tdata=output_1_udp_payload_tdata, - output_1_udp_payload_tvalid=output_1_udp_payload_tvalid, - output_1_udp_payload_tready=output_1_udp_payload_tready, - output_1_udp_payload_tlast=output_1_udp_payload_tlast, - output_1_udp_payload_tuser=output_1_udp_payload_tuser, - output_2_udp_hdr_valid=output_2_udp_hdr_valid, - output_2_udp_hdr_ready=output_2_udp_hdr_ready, - output_2_eth_dest_mac=output_2_eth_dest_mac, - output_2_eth_src_mac=output_2_eth_src_mac, - output_2_eth_type=output_2_eth_type, - output_2_ip_version=output_2_ip_version, - output_2_ip_ihl=output_2_ip_ihl, - output_2_ip_dscp=output_2_ip_dscp, - output_2_ip_ecn=output_2_ip_ecn, - output_2_ip_length=output_2_ip_length, - output_2_ip_identification=output_2_ip_identification, - output_2_ip_flags=output_2_ip_flags, - output_2_ip_fragment_offset=output_2_ip_fragment_offset, - output_2_ip_ttl=output_2_ip_ttl, - output_2_ip_protocol=output_2_ip_protocol, - output_2_ip_header_checksum=output_2_ip_header_checksum, - output_2_ip_source_ip=output_2_ip_source_ip, - output_2_ip_dest_ip=output_2_ip_dest_ip, - output_2_udp_source_port=output_2_udp_source_port, - output_2_udp_dest_port=output_2_udp_dest_port, - output_2_udp_length=output_2_udp_length, - output_2_udp_checksum=output_2_udp_checksum, - output_2_udp_payload_tdata=output_2_udp_payload_tdata, - output_2_udp_payload_tvalid=output_2_udp_payload_tvalid, - output_2_udp_payload_tready=output_2_udp_payload_tready, - output_2_udp_payload_tlast=output_2_udp_payload_tlast, - output_2_udp_payload_tuser=output_2_udp_payload_tuser, - output_3_udp_hdr_valid=output_3_udp_hdr_valid, - output_3_udp_hdr_ready=output_3_udp_hdr_ready, - output_3_eth_dest_mac=output_3_eth_dest_mac, - output_3_eth_src_mac=output_3_eth_src_mac, - output_3_eth_type=output_3_eth_type, - output_3_ip_version=output_3_ip_version, - output_3_ip_ihl=output_3_ip_ihl, - output_3_ip_dscp=output_3_ip_dscp, - output_3_ip_ecn=output_3_ip_ecn, - output_3_ip_length=output_3_ip_length, - output_3_ip_identification=output_3_ip_identification, - output_3_ip_flags=output_3_ip_flags, - output_3_ip_fragment_offset=output_3_ip_fragment_offset, - output_3_ip_ttl=output_3_ip_ttl, - output_3_ip_protocol=output_3_ip_protocol, - output_3_ip_header_checksum=output_3_ip_header_checksum, - output_3_ip_source_ip=output_3_ip_source_ip, - output_3_ip_dest_ip=output_3_ip_dest_ip, - output_3_udp_source_port=output_3_udp_source_port, - output_3_udp_dest_port=output_3_udp_dest_port, - output_3_udp_length=output_3_udp_length, - output_3_udp_checksum=output_3_udp_checksum, - output_3_udp_payload_tdata=output_3_udp_payload_tdata, - output_3_udp_payload_tvalid=output_3_udp_payload_tvalid, - output_3_udp_payload_tready=output_3_udp_payload_tready, - output_3_udp_payload_tlast=output_3_udp_payload_tlast, - output_3_udp_payload_tuser=output_3_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep=m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tid=m_udp_payload_axis_tid, + m_udp_payload_axis_tdest=m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, enable=enable, + drop=drop, select=select ) @@ -578,8 +372,8 @@ def bench(): source.send(test_frame) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame @@ -617,8 +411,8 @@ def bench(): source.send(test_frame) - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame @@ -680,13 +474,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame1 - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame2 @@ -749,17 +543,17 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_udp_payload_tvalid or input_udp_hdr_valid: + while s_udp_payload_axis_tvalid or s_udp_hdr_valid: yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -822,7 +616,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_udp_payload_tvalid or input_udp_hdr_valid: + while s_udp_payload_axis_tvalid or s_udp_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -831,13 +625,13 @@ def bench(): yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -900,33 +694,120 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_udp_payload_tvalid or input_udp_hdr_valid: - sink_0_pause.next = True - sink_1_pause.next = True - sink_2_pause.next = True - sink_3_pause.next = True + while s_udp_payload_axis_tvalid or s_udp_hdr_valid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_0_pause.next = False - sink_1_pause.next = False - sink_2_pause.next = False - sink_3_pause.next = False + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 yield delay(100) + yield clk.posedge + print("test 7: enable") + current_test.next = 7 + + enable.next = False + select.next = 0 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + enable.next = True + + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 8: drop") + current_test.next = 8 + + drop.next = True + select.next = 0 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + drop.next = False + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_udp_demux_4.v b/tb/test_udp_demux_4.v index d64513111..1540f51c6 100644 --- a/tb/test_udp_demux_4.v +++ b/tb/test_udp_demux_4.v @@ -27,157 +27,95 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for udp_demux_4 + * Testbench for udp_demux */ module test_udp_demux_4; +// Parameters +parameter M_COUNT = 4; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_udp_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [15:0] input_udp_source_port = 0; -reg [15:0] input_udp_dest_port = 0; -reg [15:0] input_udp_length = 0; -reg [15:0] input_udp_checksum = 0; -reg [7:0] input_udp_payload_tdata = 0; -reg input_udp_payload_tvalid = 0; -reg input_udp_payload_tlast = 0; -reg input_udp_payload_tuser = 0; +reg s_udp_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [15:0] s_udp_source_port = 0; +reg [15:0] s_udp_dest_port = 0; +reg [15:0] s_udp_length = 0; +reg [15:0] s_udp_checksum = 0; +reg [DATA_WIDTH-1:0] s_udp_payload_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_udp_payload_axis_tkeep = 0; +reg s_udp_payload_axis_tvalid = 0; +reg s_udp_payload_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_udp_payload_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_udp_payload_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_udp_payload_axis_tuser = 0; -reg output_0_udp_hdr_ready = 0; -reg output_0_udp_payload_tready = 0; -reg output_1_udp_hdr_ready = 0; -reg output_1_udp_payload_tready = 0; -reg output_2_udp_hdr_ready = 0; -reg output_2_udp_payload_tready = 0; -reg output_3_udp_hdr_ready = 0; -reg output_3_udp_payload_tready = 0; +reg [M_COUNT-1:0] m_udp_hdr_ready = 0; +reg [M_COUNT-1:0] m_udp_payload_axis_tready = 0; reg enable = 0; +reg drop = 0; reg [1:0] select = 0; // Outputs -wire input_udp_hdr_ready; -wire input_udp_payload_tready; +wire s_udp_hdr_ready; +wire s_udp_payload_axis_tready; -wire output_0_udp_hdr_valid; -wire [47:0] output_0_eth_dest_mac; -wire [47:0] output_0_eth_src_mac; -wire [15:0] output_0_eth_type; -wire [3:0] output_0_ip_version; -wire [3:0] output_0_ip_ihl; -wire [5:0] output_0_ip_dscp; -wire [1:0] output_0_ip_ecn; -wire [15:0] output_0_ip_length; -wire [15:0] output_0_ip_identification; -wire [2:0] output_0_ip_flags; -wire [12:0] output_0_ip_fragment_offset; -wire [7:0] output_0_ip_ttl; -wire [7:0] output_0_ip_protocol; -wire [15:0] output_0_ip_header_checksum; -wire [31:0] output_0_ip_source_ip; -wire [31:0] output_0_ip_dest_ip; -wire [15:0] output_0_udp_source_port; -wire [15:0] output_0_udp_dest_port; -wire [15:0] output_0_udp_length; -wire [15:0] output_0_udp_checksum; -wire [7:0] output_0_udp_payload_tdata; -wire output_0_udp_payload_tvalid; -wire output_0_udp_payload_tlast; -wire output_0_udp_payload_tuser; -wire output_1_udp_hdr_valid; -wire [47:0] output_1_eth_dest_mac; -wire [47:0] output_1_eth_src_mac; -wire [15:0] output_1_eth_type; -wire [3:0] output_1_ip_version; -wire [3:0] output_1_ip_ihl; -wire [5:0] output_1_ip_dscp; -wire [1:0] output_1_ip_ecn; -wire [15:0] output_1_ip_length; -wire [15:0] output_1_ip_identification; -wire [2:0] output_1_ip_flags; -wire [12:0] output_1_ip_fragment_offset; -wire [7:0] output_1_ip_ttl; -wire [7:0] output_1_ip_protocol; -wire [15:0] output_1_ip_header_checksum; -wire [31:0] output_1_ip_source_ip; -wire [31:0] output_1_ip_dest_ip; -wire [15:0] output_1_udp_source_port; -wire [15:0] output_1_udp_dest_port; -wire [15:0] output_1_udp_length; -wire [15:0] output_1_udp_checksum; -wire [7:0] output_1_udp_payload_tdata; -wire output_1_udp_payload_tvalid; -wire output_1_udp_payload_tlast; -wire output_1_udp_payload_tuser; -wire output_2_udp_hdr_valid; -wire [47:0] output_2_eth_dest_mac; -wire [47:0] output_2_eth_src_mac; -wire [15:0] output_2_eth_type; -wire [3:0] output_2_ip_version; -wire [3:0] output_2_ip_ihl; -wire [5:0] output_2_ip_dscp; -wire [1:0] output_2_ip_ecn; -wire [15:0] output_2_ip_length; -wire [15:0] output_2_ip_identification; -wire [2:0] output_2_ip_flags; -wire [12:0] output_2_ip_fragment_offset; -wire [7:0] output_2_ip_ttl; -wire [7:0] output_2_ip_protocol; -wire [15:0] output_2_ip_header_checksum; -wire [31:0] output_2_ip_source_ip; -wire [31:0] output_2_ip_dest_ip; -wire [15:0] output_2_udp_source_port; -wire [15:0] output_2_udp_dest_port; -wire [15:0] output_2_udp_length; -wire [15:0] output_2_udp_checksum; -wire [7:0] output_2_udp_payload_tdata; -wire output_2_udp_payload_tvalid; -wire output_2_udp_payload_tlast; -wire output_2_udp_payload_tuser; -wire output_3_udp_hdr_valid; -wire [47:0] output_3_eth_dest_mac; -wire [47:0] output_3_eth_src_mac; -wire [15:0] output_3_eth_type; -wire [3:0] output_3_ip_version; -wire [3:0] output_3_ip_ihl; -wire [5:0] output_3_ip_dscp; -wire [1:0] output_3_ip_ecn; -wire [15:0] output_3_ip_length; -wire [15:0] output_3_ip_identification; -wire [2:0] output_3_ip_flags; -wire [12:0] output_3_ip_fragment_offset; -wire [7:0] output_3_ip_ttl; -wire [7:0] output_3_ip_protocol; -wire [15:0] output_3_ip_header_checksum; -wire [31:0] output_3_ip_source_ip; -wire [31:0] output_3_ip_dest_ip; -wire [15:0] output_3_udp_source_port; -wire [15:0] output_3_udp_dest_port; -wire [15:0] output_3_udp_length; -wire [15:0] output_3_udp_checksum; -wire [7:0] output_3_udp_payload_tdata; -wire output_3_udp_payload_tvalid; -wire output_3_udp_payload_tlast; -wire output_3_udp_payload_tuser; +wire [M_COUNT-1:0] m_udp_hdr_valid; +wire [M_COUNT*48-1:0] m_eth_dest_mac; +wire [M_COUNT*48-1:0] m_eth_src_mac; +wire [M_COUNT*16-1:0] m_eth_type; +wire [M_COUNT*4-1:0] m_ip_version; +wire [M_COUNT*4-1:0] m_ip_ihl; +wire [M_COUNT*6-1:0] m_ip_dscp; +wire [M_COUNT*2-1:0] m_ip_ecn; +wire [M_COUNT*16-1:0] m_ip_length; +wire [M_COUNT*16-1:0] m_ip_identification; +wire [M_COUNT*3-1:0] m_ip_flags; +wire [M_COUNT*13-1:0] m_ip_fragment_offset; +wire [M_COUNT*8-1:0] m_ip_ttl; +wire [M_COUNT*8-1:0] m_ip_protocol; +wire [M_COUNT*16-1:0] m_ip_header_checksum; +wire [M_COUNT*32-1:0] m_ip_source_ip; +wire [M_COUNT*32-1:0] m_ip_dest_ip; +wire [M_COUNT*16-1:0] m_udp_source_port; +wire [M_COUNT*16-1:0] m_udp_dest_port; +wire [M_COUNT*16-1:0] m_udp_length; +wire [M_COUNT*16-1:0] m_udp_checksum; +wire [M_COUNT*DATA_WIDTH-1:0] m_udp_payload_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep; +wire [M_COUNT-1:0] m_udp_payload_axis_tvalid; +wire [M_COUNT-1:0] m_udp_payload_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_udp_payload_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_udp_payload_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_udp_payload_axis_tuser; initial begin // myhdl integration @@ -185,145 +123,71 @@ initial begin clk, rst, current_test, - input_udp_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_udp_source_port, - input_udp_dest_port, - input_udp_length, - input_udp_checksum, - input_udp_payload_tdata, - input_udp_payload_tvalid, - input_udp_payload_tlast, - input_udp_payload_tuser, - output_0_udp_hdr_ready, - output_0_udp_payload_tready, - output_1_udp_hdr_ready, - output_1_udp_payload_tready, - output_2_udp_hdr_ready, - output_2_udp_payload_tready, - output_3_udp_hdr_ready, - output_3_udp_payload_tready, + s_udp_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tid, + s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser, + m_udp_hdr_ready, + m_udp_payload_axis_tready, enable, + drop, select ); $to_myhdl( - input_udp_hdr_ready, - input_udp_payload_tready, - output_0_udp_hdr_valid, - output_0_eth_dest_mac, - output_0_eth_src_mac, - output_0_eth_type, - output_0_ip_version, - output_0_ip_ihl, - output_0_ip_dscp, - output_0_ip_ecn, - output_0_ip_length, - output_0_ip_identification, - output_0_ip_flags, - output_0_ip_fragment_offset, - output_0_ip_ttl, - output_0_ip_protocol, - output_0_ip_header_checksum, - output_0_ip_source_ip, - output_0_ip_dest_ip, - output_0_udp_source_port, - output_0_udp_dest_port, - output_0_udp_length, - output_0_udp_checksum, - output_0_udp_payload_tdata, - output_0_udp_payload_tvalid, - output_0_udp_payload_tlast, - output_0_udp_payload_tuser, - output_1_udp_hdr_valid, - output_1_eth_dest_mac, - output_1_eth_src_mac, - output_1_eth_type, - output_1_ip_version, - output_1_ip_ihl, - output_1_ip_dscp, - output_1_ip_ecn, - output_1_ip_length, - output_1_ip_identification, - output_1_ip_flags, - output_1_ip_fragment_offset, - output_1_ip_ttl, - output_1_ip_protocol, - output_1_ip_header_checksum, - output_1_ip_source_ip, - output_1_ip_dest_ip, - output_1_udp_source_port, - output_1_udp_dest_port, - output_1_udp_length, - output_1_udp_checksum, - output_1_udp_payload_tdata, - output_1_udp_payload_tvalid, - output_1_udp_payload_tlast, - output_1_udp_payload_tuser, - output_2_udp_hdr_valid, - output_2_eth_dest_mac, - output_2_eth_src_mac, - output_2_eth_type, - output_2_ip_version, - output_2_ip_ihl, - output_2_ip_dscp, - output_2_ip_ecn, - output_2_ip_length, - output_2_ip_identification, - output_2_ip_flags, - output_2_ip_fragment_offset, - output_2_ip_ttl, - output_2_ip_protocol, - output_2_ip_header_checksum, - output_2_ip_source_ip, - output_2_ip_dest_ip, - output_2_udp_source_port, - output_2_udp_dest_port, - output_2_udp_length, - output_2_udp_checksum, - output_2_udp_payload_tdata, - output_2_udp_payload_tvalid, - output_2_udp_payload_tlast, - output_2_udp_payload_tuser, - output_3_udp_hdr_valid, - output_3_eth_dest_mac, - output_3_eth_src_mac, - output_3_eth_type, - output_3_ip_version, - output_3_ip_ihl, - output_3_ip_dscp, - output_3_ip_ecn, - output_3_ip_length, - output_3_ip_identification, - output_3_ip_flags, - output_3_ip_fragment_offset, - output_3_ip_ttl, - output_3_ip_protocol, - output_3_ip_header_checksum, - output_3_ip_source_ip, - output_3_ip_dest_ip, - output_3_udp_source_port, - output_3_udp_dest_port, - output_3_udp_length, - output_3_udp_checksum, - output_3_udp_payload_tdata, - output_3_udp_payload_tvalid, - output_3_udp_payload_tlast, - output_3_udp_payload_tuser + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_udp_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tid, + m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser ); // dump file @@ -331,149 +195,86 @@ initial begin $dumpvars(0, test_udp_demux_4); end -udp_demux_4 +udp_demux #( + .M_COUNT(M_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), - .input_udp_checksum(input_udp_checksum), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tid(s_udp_payload_axis_tid), + .s_udp_payload_axis_tdest(s_udp_payload_axis_tdest), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // UDP frame outputs - .output_0_udp_hdr_valid(output_0_udp_hdr_valid), - .output_0_udp_hdr_ready(output_0_udp_hdr_ready), - .output_0_eth_dest_mac(output_0_eth_dest_mac), - .output_0_eth_src_mac(output_0_eth_src_mac), - .output_0_eth_type(output_0_eth_type), - .output_0_ip_version(output_0_ip_version), - .output_0_ip_ihl(output_0_ip_ihl), - .output_0_ip_dscp(output_0_ip_dscp), - .output_0_ip_ecn(output_0_ip_ecn), - .output_0_ip_length(output_0_ip_length), - .output_0_ip_identification(output_0_ip_identification), - .output_0_ip_flags(output_0_ip_flags), - .output_0_ip_fragment_offset(output_0_ip_fragment_offset), - .output_0_ip_ttl(output_0_ip_ttl), - .output_0_ip_protocol(output_0_ip_protocol), - .output_0_ip_header_checksum(output_0_ip_header_checksum), - .output_0_ip_source_ip(output_0_ip_source_ip), - .output_0_ip_dest_ip(output_0_ip_dest_ip), - .output_0_udp_source_port(output_0_udp_source_port), - .output_0_udp_dest_port(output_0_udp_dest_port), - .output_0_udp_length(output_0_udp_length), - .output_0_udp_checksum(output_0_udp_checksum), - .output_0_udp_payload_tdata(output_0_udp_payload_tdata), - .output_0_udp_payload_tvalid(output_0_udp_payload_tvalid), - .output_0_udp_payload_tready(output_0_udp_payload_tready), - .output_0_udp_payload_tlast(output_0_udp_payload_tlast), - .output_0_udp_payload_tuser(output_0_udp_payload_tuser), - .output_1_udp_hdr_valid(output_1_udp_hdr_valid), - .output_1_udp_hdr_ready(output_1_udp_hdr_ready), - .output_1_eth_dest_mac(output_1_eth_dest_mac), - .output_1_eth_src_mac(output_1_eth_src_mac), - .output_1_eth_type(output_1_eth_type), - .output_1_ip_version(output_1_ip_version), - .output_1_ip_ihl(output_1_ip_ihl), - .output_1_ip_dscp(output_1_ip_dscp), - .output_1_ip_ecn(output_1_ip_ecn), - .output_1_ip_length(output_1_ip_length), - .output_1_ip_identification(output_1_ip_identification), - .output_1_ip_flags(output_1_ip_flags), - .output_1_ip_fragment_offset(output_1_ip_fragment_offset), - .output_1_ip_ttl(output_1_ip_ttl), - .output_1_ip_protocol(output_1_ip_protocol), - .output_1_ip_header_checksum(output_1_ip_header_checksum), - .output_1_ip_source_ip(output_1_ip_source_ip), - .output_1_ip_dest_ip(output_1_ip_dest_ip), - .output_1_udp_source_port(output_1_udp_source_port), - .output_1_udp_dest_port(output_1_udp_dest_port), - .output_1_udp_length(output_1_udp_length), - .output_1_udp_checksum(output_1_udp_checksum), - .output_1_udp_payload_tdata(output_1_udp_payload_tdata), - .output_1_udp_payload_tvalid(output_1_udp_payload_tvalid), - .output_1_udp_payload_tready(output_1_udp_payload_tready), - .output_1_udp_payload_tlast(output_1_udp_payload_tlast), - .output_1_udp_payload_tuser(output_1_udp_payload_tuser), - .output_2_udp_hdr_valid(output_2_udp_hdr_valid), - .output_2_udp_hdr_ready(output_2_udp_hdr_ready), - .output_2_eth_dest_mac(output_2_eth_dest_mac), - .output_2_eth_src_mac(output_2_eth_src_mac), - .output_2_eth_type(output_2_eth_type), - .output_2_ip_version(output_2_ip_version), - .output_2_ip_ihl(output_2_ip_ihl), - .output_2_ip_dscp(output_2_ip_dscp), - .output_2_ip_ecn(output_2_ip_ecn), - .output_2_ip_length(output_2_ip_length), - .output_2_ip_identification(output_2_ip_identification), - .output_2_ip_flags(output_2_ip_flags), - .output_2_ip_fragment_offset(output_2_ip_fragment_offset), - .output_2_ip_ttl(output_2_ip_ttl), - .output_2_ip_protocol(output_2_ip_protocol), - .output_2_ip_header_checksum(output_2_ip_header_checksum), - .output_2_ip_source_ip(output_2_ip_source_ip), - .output_2_ip_dest_ip(output_2_ip_dest_ip), - .output_2_udp_source_port(output_2_udp_source_port), - .output_2_udp_dest_port(output_2_udp_dest_port), - .output_2_udp_length(output_2_udp_length), - .output_2_udp_checksum(output_2_udp_checksum), - .output_2_udp_payload_tdata(output_2_udp_payload_tdata), - .output_2_udp_payload_tvalid(output_2_udp_payload_tvalid), - .output_2_udp_payload_tready(output_2_udp_payload_tready), - .output_2_udp_payload_tlast(output_2_udp_payload_tlast), - .output_2_udp_payload_tuser(output_2_udp_payload_tuser), - .output_3_udp_hdr_valid(output_3_udp_hdr_valid), - .output_3_udp_hdr_ready(output_3_udp_hdr_ready), - .output_3_eth_dest_mac(output_3_eth_dest_mac), - .output_3_eth_src_mac(output_3_eth_src_mac), - .output_3_eth_type(output_3_eth_type), - .output_3_ip_version(output_3_ip_version), - .output_3_ip_ihl(output_3_ip_ihl), - .output_3_ip_dscp(output_3_ip_dscp), - .output_3_ip_ecn(output_3_ip_ecn), - .output_3_ip_length(output_3_ip_length), - .output_3_ip_identification(output_3_ip_identification), - .output_3_ip_flags(output_3_ip_flags), - .output_3_ip_fragment_offset(output_3_ip_fragment_offset), - .output_3_ip_ttl(output_3_ip_ttl), - .output_3_ip_protocol(output_3_ip_protocol), - .output_3_ip_header_checksum(output_3_ip_header_checksum), - .output_3_ip_source_ip(output_3_ip_source_ip), - .output_3_ip_dest_ip(output_3_ip_dest_ip), - .output_3_udp_source_port(output_3_udp_source_port), - .output_3_udp_dest_port(output_3_udp_dest_port), - .output_3_udp_length(output_3_udp_length), - .output_3_udp_checksum(output_3_udp_checksum), - .output_3_udp_payload_tdata(output_3_udp_payload_tdata), - .output_3_udp_payload_tvalid(output_3_udp_payload_tvalid), - .output_3_udp_payload_tready(output_3_udp_payload_tready), - .output_3_udp_payload_tlast(output_3_udp_payload_tlast), - .output_3_udp_payload_tuser(output_3_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tid(m_udp_payload_axis_tid), + .m_udp_payload_axis_tdest(m_udp_payload_axis_tdest), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Control .enable(enable), + .drop(drop), .select(select) ); diff --git a/tb/test_udp_demux_64_4.py b/tb/test_udp_demux_64_4.py index cf8b5185e..f99169b75 100755 --- a/tb/test_udp_demux_64_4.py +++ b/tb/test_udp_demux_64_4.py @@ -28,8 +28,8 @@ import os import udp_ep -module = 'udp_demux_64_4' -testbench = 'test_%s' % module +module = 'udp_demux' +testbench = 'test_%s_64_4' % module srcs = [] @@ -42,350 +42,208 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + M_COUNT = 4 + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_udp_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_udp_source_port = Signal(intbv(0)[16:]) - input_udp_dest_port = Signal(intbv(0)[16:]) - input_udp_length = Signal(intbv(0)[16:]) - input_udp_checksum = Signal(intbv(0)[16:]) - input_udp_payload_tdata = Signal(intbv(0)[64:]) - input_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_udp_payload_tvalid = Signal(bool(0)) - input_udp_payload_tlast = Signal(bool(0)) - input_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_udp_source_port = Signal(intbv(0)[16:]) + s_udp_dest_port = Signal(intbv(0)[16:]) + s_udp_length = Signal(intbv(0)[16:]) + s_udp_checksum = Signal(intbv(0)[16:]) + s_udp_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_udp_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + s_udp_payload_axis_tvalid = Signal(bool(0)) + s_udp_payload_axis_tlast = Signal(bool(0)) + s_udp_payload_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_udp_payload_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_udp_payload_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - output_0_udp_hdr_ready = Signal(bool(0)) - output_0_udp_payload_tready = Signal(bool(0)) - output_1_udp_hdr_ready = Signal(bool(0)) - output_1_udp_payload_tready = Signal(bool(0)) - output_2_udp_hdr_ready = Signal(bool(0)) - output_2_udp_payload_tready = Signal(bool(0)) - output_3_udp_hdr_ready = Signal(bool(0)) - output_3_udp_payload_tready = Signal(bool(0)) + m_udp_hdr_ready_list = [Signal(bool(0)) for i in range(M_COUNT)] + m_udp_payload_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_udp_hdr_ready = ConcatSignal(*reversed(m_udp_hdr_ready_list)) + m_udp_payload_axis_tready = ConcatSignal(*reversed(m_udp_payload_axis_tready_list)) enable = Signal(bool(0)) + drop = Signal(bool(0)) select = Signal(intbv(0)[2:]) # Outputs - input_udp_hdr_ready = Signal(bool(0)) - input_udp_payload_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(bool(0)) + s_udp_payload_axis_tready = Signal(bool(0)) - output_0_udp_hdr_valid = Signal(bool(0)) - output_0_eth_dest_mac = Signal(intbv(0)[48:]) - output_0_eth_src_mac = Signal(intbv(0)[48:]) - output_0_eth_type = Signal(intbv(0)[16:]) - output_0_ip_version = Signal(intbv(0)[4:]) - output_0_ip_ihl = Signal(intbv(0)[4:]) - output_0_ip_dscp = Signal(intbv(0)[6:]) - output_0_ip_ecn = Signal(intbv(0)[2:]) - output_0_ip_length = Signal(intbv(0)[16:]) - output_0_ip_identification = Signal(intbv(0)[16:]) - output_0_ip_flags = Signal(intbv(0)[3:]) - output_0_ip_fragment_offset = Signal(intbv(0)[13:]) - output_0_ip_ttl = Signal(intbv(0)[8:]) - output_0_ip_protocol = Signal(intbv(0)[8:]) - output_0_ip_header_checksum = Signal(intbv(0)[16:]) - output_0_ip_source_ip = Signal(intbv(0)[32:]) - output_0_ip_dest_ip = Signal(intbv(0)[32:]) - output_0_udp_source_port = Signal(intbv(0)[16:]) - output_0_udp_dest_port = Signal(intbv(0)[16:]) - output_0_udp_length = Signal(intbv(0)[16:]) - output_0_udp_checksum = Signal(intbv(0)[16:]) - output_0_udp_payload_tdata = Signal(intbv(0)[64:]) - output_0_udp_payload_tkeep = Signal(intbv(0)[8:]) - output_0_udp_payload_tvalid = Signal(bool(0)) - output_0_udp_payload_tlast = Signal(bool(0)) - output_0_udp_payload_tuser = Signal(bool(0)) - output_1_udp_hdr_valid = Signal(bool(0)) - output_1_eth_dest_mac = Signal(intbv(0)[48:]) - output_1_eth_src_mac = Signal(intbv(0)[48:]) - output_1_eth_type = Signal(intbv(0)[16:]) - output_1_ip_version = Signal(intbv(0)[4:]) - output_1_ip_ihl = Signal(intbv(0)[4:]) - output_1_ip_dscp = Signal(intbv(0)[6:]) - output_1_ip_ecn = Signal(intbv(0)[2:]) - output_1_ip_length = Signal(intbv(0)[16:]) - output_1_ip_identification = Signal(intbv(0)[16:]) - output_1_ip_flags = Signal(intbv(0)[3:]) - output_1_ip_fragment_offset = Signal(intbv(0)[13:]) - output_1_ip_ttl = Signal(intbv(0)[8:]) - output_1_ip_protocol = Signal(intbv(0)[8:]) - output_1_ip_header_checksum = Signal(intbv(0)[16:]) - output_1_ip_source_ip = Signal(intbv(0)[32:]) - output_1_ip_dest_ip = Signal(intbv(0)[32:]) - output_1_udp_source_port = Signal(intbv(0)[16:]) - output_1_udp_dest_port = Signal(intbv(0)[16:]) - output_1_udp_length = Signal(intbv(0)[16:]) - output_1_udp_checksum = Signal(intbv(0)[16:]) - output_1_udp_payload_tdata = Signal(intbv(0)[64:]) - output_1_udp_payload_tkeep = Signal(intbv(0)[8:]) - output_1_udp_payload_tvalid = Signal(bool(0)) - output_1_udp_payload_tlast = Signal(bool(0)) - output_1_udp_payload_tuser = Signal(bool(0)) - output_2_udp_hdr_valid = Signal(bool(0)) - output_2_eth_dest_mac = Signal(intbv(0)[48:]) - output_2_eth_src_mac = Signal(intbv(0)[48:]) - output_2_eth_type = Signal(intbv(0)[16:]) - output_2_ip_version = Signal(intbv(0)[4:]) - output_2_ip_ihl = Signal(intbv(0)[4:]) - output_2_ip_dscp = Signal(intbv(0)[6:]) - output_2_ip_ecn = Signal(intbv(0)[2:]) - output_2_ip_length = Signal(intbv(0)[16:]) - output_2_ip_identification = Signal(intbv(0)[16:]) - output_2_ip_flags = Signal(intbv(0)[3:]) - output_2_ip_fragment_offset = Signal(intbv(0)[13:]) - output_2_ip_ttl = Signal(intbv(0)[8:]) - output_2_ip_protocol = Signal(intbv(0)[8:]) - output_2_ip_header_checksum = Signal(intbv(0)[16:]) - output_2_ip_source_ip = Signal(intbv(0)[32:]) - output_2_ip_dest_ip = Signal(intbv(0)[32:]) - output_2_udp_source_port = Signal(intbv(0)[16:]) - output_2_udp_dest_port = Signal(intbv(0)[16:]) - output_2_udp_length = Signal(intbv(0)[16:]) - output_2_udp_checksum = Signal(intbv(0)[16:]) - output_2_udp_payload_tdata = Signal(intbv(0)[64:]) - output_2_udp_payload_tkeep = Signal(intbv(0)[8:]) - output_2_udp_payload_tvalid = Signal(bool(0)) - output_2_udp_payload_tlast = Signal(bool(0)) - output_2_udp_payload_tuser = Signal(bool(0)) - output_3_udp_hdr_valid = Signal(bool(0)) - output_3_eth_dest_mac = Signal(intbv(0)[48:]) - output_3_eth_src_mac = Signal(intbv(0)[48:]) - output_3_eth_type = Signal(intbv(0)[16:]) - output_3_ip_version = Signal(intbv(0)[4:]) - output_3_ip_ihl = Signal(intbv(0)[4:]) - output_3_ip_dscp = Signal(intbv(0)[6:]) - output_3_ip_ecn = Signal(intbv(0)[2:]) - output_3_ip_length = Signal(intbv(0)[16:]) - output_3_ip_identification = Signal(intbv(0)[16:]) - output_3_ip_flags = Signal(intbv(0)[3:]) - output_3_ip_fragment_offset = Signal(intbv(0)[13:]) - output_3_ip_ttl = Signal(intbv(0)[8:]) - output_3_ip_protocol = Signal(intbv(0)[8:]) - output_3_ip_header_checksum = Signal(intbv(0)[16:]) - output_3_ip_source_ip = Signal(intbv(0)[32:]) - output_3_ip_dest_ip = Signal(intbv(0)[32:]) - output_3_udp_source_port = Signal(intbv(0)[16:]) - output_3_udp_dest_port = Signal(intbv(0)[16:]) - output_3_udp_length = Signal(intbv(0)[16:]) - output_3_udp_checksum = Signal(intbv(0)[16:]) - output_3_udp_payload_tdata = Signal(intbv(0)[64:]) - output_3_udp_payload_tkeep = Signal(intbv(0)[8:]) - output_3_udp_payload_tvalid = Signal(bool(0)) - output_3_udp_payload_tlast = Signal(bool(0)) - output_3_udp_payload_tuser = Signal(bool(0)) + m_udp_hdr_valid = Signal(intbv(0)[M_COUNT:]) + m_eth_dest_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_src_mac = Signal(intbv(0)[M_COUNT*48:]) + m_eth_type = Signal(intbv(0)[M_COUNT*16:]) + m_ip_version = Signal(intbv(0)[M_COUNT*4:]) + m_ip_ihl = Signal(intbv(0)[M_COUNT*4:]) + m_ip_dscp = Signal(intbv(0)[M_COUNT*6:]) + m_ip_ecn = Signal(intbv(0)[M_COUNT*2:]) + m_ip_length = Signal(intbv(0)[M_COUNT*16:]) + m_ip_identification = Signal(intbv(0)[M_COUNT*16:]) + m_ip_flags = Signal(intbv(0)[M_COUNT*3:]) + m_ip_fragment_offset = Signal(intbv(0)[M_COUNT*13:]) + m_ip_ttl = Signal(intbv(0)[M_COUNT*8:]) + m_ip_protocol = Signal(intbv(0)[M_COUNT*8:]) + m_ip_header_checksum = Signal(intbv(0)[M_COUNT*16:]) + m_ip_source_ip = Signal(intbv(0)[M_COUNT*32:]) + m_ip_dest_ip = Signal(intbv(0)[M_COUNT*32:]) + m_udp_source_port = Signal(intbv(0)[M_COUNT*16:]) + m_udp_dest_port = Signal(intbv(0)[M_COUNT*16:]) + m_udp_length = Signal(intbv(0)[M_COUNT*16:]) + m_udp_checksum = Signal(intbv(0)[M_COUNT*16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_udp_payload_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_udp_payload_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_udp_payload_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_udp_payload_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_udp_payload_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_udp_payload_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_udp_hdr_valid_list = [m_udp_hdr_valid(i) for i in range(M_COUNT)] + m_eth_dest_mac_list = [m_eth_dest_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_src_mac_list = [m_eth_src_mac((i+1)*48, i*48) for i in range(M_COUNT)] + m_eth_type_list = [m_eth_type((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_version_list = [m_ip_version((i+1)*4, i*4) for i in range(M_COUNT)] + m_ip_ihl_list = [m_ip_ihl((i+1)*4, i*4) for i in range(M_COUNT)] + m_ip_dscp_list = [m_ip_dscp((i+1)*6, i*6) for i in range(M_COUNT)] + m_ip_ecn_list = [m_ip_ecn((i+1)*2, i*2) for i in range(M_COUNT)] + m_ip_length_list = [m_ip_length((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_identification_list = [m_ip_identification((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_flags_list = [m_ip_flags((i+1)*3, i*3) for i in range(M_COUNT)] + m_ip_fragment_offset_list = [m_ip_fragment_offset((i+1)*13, i*13) for i in range(M_COUNT)] + m_ip_ttl_list = [m_ip_ttl((i+1)*8, i*8) for i in range(M_COUNT)] + m_ip_protocol_list = [m_ip_protocol((i+1)*8, i*8) for i in range(M_COUNT)] + m_ip_header_checksum_list = [m_ip_header_checksum((i+1)*16, i*16) for i in range(M_COUNT)] + m_ip_source_ip_list = [m_ip_source_ip((i+1)*32, i*32) for i in range(M_COUNT)] + m_ip_dest_ip_list = [m_ip_dest_ip((i+1)*32, i*32) for i in range(M_COUNT)] + m_udp_source_port_list = [m_udp_source_port((i+1)*16, i*16) for i in range(M_COUNT)] + m_udp_dest_port_list = [m_udp_dest_port((i+1)*16, i*16) for i in range(M_COUNT)] + m_udp_length_list = [m_udp_length((i+1)*16, i*16) for i in range(M_COUNT)] + m_udp_checksum_list = [m_udp_checksum((i+1)*16, i*16) for i in range(M_COUNT)] + m_udp_payload_axis_tdata_list = [m_udp_payload_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_udp_payload_axis_tkeep_list = [m_udp_payload_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_udp_payload_axis_tvalid_list = [m_udp_payload_axis_tvalid(i) for i in range(M_COUNT)] + m_udp_payload_axis_tlast_list = [m_udp_payload_axis_tlast(i) for i in range(M_COUNT)] + m_udp_payload_axis_tid_list = [m_udp_payload_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_udp_payload_axis_tdest_list = [m_udp_payload_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_udp_payload_axis_tuser_list = [m_udp_payload_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] # sources and sinks source_pause = Signal(bool(0)) - sink_0_pause = Signal(bool(0)) - sink_1_pause = Signal(bool(0)) - sink_2_pause = Signal(bool(0)) - sink_3_pause = Signal(bool(0)) + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] source = udp_ep.UDPFrameSource() source_logic = source.create_logic( clk, rst, - udp_hdr_ready=input_udp_hdr_ready, - udp_hdr_valid=input_udp_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - udp_source_port=input_udp_source_port, - udp_dest_port=input_udp_dest_port, - udp_length=input_udp_length, - udp_checksum=input_udp_checksum, - udp_payload_tdata=input_udp_payload_tdata, - udp_payload_tkeep=input_udp_payload_tkeep, - udp_payload_tvalid=input_udp_payload_tvalid, - udp_payload_tready=input_udp_payload_tready, - udp_payload_tlast=input_udp_payload_tlast, - udp_payload_tuser=input_udp_payload_tuser, + udp_hdr_ready=s_udp_hdr_ready, + udp_hdr_valid=s_udp_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + udp_source_port=s_udp_source_port, + udp_dest_port=s_udp_dest_port, + udp_length=s_udp_length, + udp_checksum=s_udp_checksum, + udp_payload_tdata=s_udp_payload_axis_tdata, + udp_payload_tkeep=s_udp_payload_axis_tkeep, + udp_payload_tvalid=s_udp_payload_axis_tvalid, + udp_payload_tready=s_udp_payload_axis_tready, + udp_payload_tlast=s_udp_payload_axis_tlast, + udp_payload_tuser=s_udp_payload_axis_tuser, pause=source_pause, name='source' ) - sink_0 = udp_ep.UDPFrameSink() + for k in range(M_COUNT): + s = udp_ep.UDPFrameSink() + p = Signal(bool(0)) - sink_0_logic = sink_0.create_logic( - clk, - rst, - udp_hdr_ready=output_0_udp_hdr_ready, - udp_hdr_valid=output_0_udp_hdr_valid, - eth_dest_mac=output_0_eth_dest_mac, - eth_src_mac=output_0_eth_src_mac, - eth_type=output_0_eth_type, - ip_version=output_0_ip_version, - ip_ihl=output_0_ip_ihl, - ip_dscp=output_0_ip_dscp, - ip_ecn=output_0_ip_ecn, - ip_length=output_0_ip_length, - ip_identification=output_0_ip_identification, - ip_flags=output_0_ip_flags, - ip_fragment_offset=output_0_ip_fragment_offset, - ip_ttl=output_0_ip_ttl, - ip_protocol=output_0_ip_protocol, - ip_header_checksum=output_0_ip_header_checksum, - ip_source_ip=output_0_ip_source_ip, - ip_dest_ip=output_0_ip_dest_ip, - udp_source_port=output_0_udp_source_port, - udp_dest_port=output_0_udp_dest_port, - udp_length=output_0_udp_length, - udp_checksum=output_0_udp_checksum, - udp_payload_tdata=output_0_udp_payload_tdata, - udp_payload_tkeep=output_0_udp_payload_tkeep, - udp_payload_tvalid=output_0_udp_payload_tvalid, - udp_payload_tready=output_0_udp_payload_tready, - udp_payload_tlast=output_0_udp_payload_tlast, - udp_payload_tuser=output_0_udp_payload_tuser, - pause=sink_0_pause, - name='sink_0' - ) + sink_list.append(s) + sink_pause_list.append(p) - sink_1 = udp_ep.UDPFrameSink() - - sink_1_logic = sink_1.create_logic( - clk, - rst, - udp_hdr_ready=output_1_udp_hdr_ready, - udp_hdr_valid=output_1_udp_hdr_valid, - eth_dest_mac=output_1_eth_dest_mac, - eth_src_mac=output_1_eth_src_mac, - eth_type=output_1_eth_type, - ip_version=output_1_ip_version, - ip_ihl=output_1_ip_ihl, - ip_dscp=output_1_ip_dscp, - ip_ecn=output_1_ip_ecn, - ip_length=output_1_ip_length, - ip_identification=output_1_ip_identification, - ip_flags=output_1_ip_flags, - ip_fragment_offset=output_1_ip_fragment_offset, - ip_ttl=output_1_ip_ttl, - ip_protocol=output_1_ip_protocol, - ip_header_checksum=output_1_ip_header_checksum, - ip_source_ip=output_1_ip_source_ip, - ip_dest_ip=output_1_ip_dest_ip, - udp_source_port=output_1_udp_source_port, - udp_dest_port=output_1_udp_dest_port, - udp_length=output_1_udp_length, - udp_checksum=output_1_udp_checksum, - udp_payload_tdata=output_1_udp_payload_tdata, - udp_payload_tkeep=output_1_udp_payload_tkeep, - udp_payload_tvalid=output_1_udp_payload_tvalid, - udp_payload_tready=output_1_udp_payload_tready, - udp_payload_tlast=output_1_udp_payload_tlast, - udp_payload_tuser=output_1_udp_payload_tuser, - pause=sink_1_pause, - name='sink_1' - ) - - sink_2 = udp_ep.UDPFrameSink() - - sink_2_logic = sink_2.create_logic( - clk, - rst, - udp_hdr_ready=output_2_udp_hdr_ready, - udp_hdr_valid=output_2_udp_hdr_valid, - eth_dest_mac=output_2_eth_dest_mac, - eth_src_mac=output_2_eth_src_mac, - eth_type=output_2_eth_type, - ip_version=output_2_ip_version, - ip_ihl=output_2_ip_ihl, - ip_dscp=output_2_ip_dscp, - ip_ecn=output_2_ip_ecn, - ip_length=output_2_ip_length, - ip_identification=output_2_ip_identification, - ip_flags=output_2_ip_flags, - ip_fragment_offset=output_2_ip_fragment_offset, - ip_ttl=output_2_ip_ttl, - ip_protocol=output_2_ip_protocol, - ip_header_checksum=output_2_ip_header_checksum, - ip_source_ip=output_2_ip_source_ip, - ip_dest_ip=output_2_ip_dest_ip, - udp_source_port=output_2_udp_source_port, - udp_dest_port=output_2_udp_dest_port, - udp_length=output_2_udp_length, - udp_checksum=output_2_udp_checksum, - udp_payload_tdata=output_2_udp_payload_tdata, - udp_payload_tkeep=output_2_udp_payload_tkeep, - udp_payload_tvalid=output_2_udp_payload_tvalid, - udp_payload_tready=output_2_udp_payload_tready, - udp_payload_tlast=output_2_udp_payload_tlast, - udp_payload_tuser=output_2_udp_payload_tuser, - pause=sink_2_pause, - name='sink_2' - ) - - sink_3 = udp_ep.UDPFrameSink() - - sink_3_logic = sink_3.create_logic( - clk, - rst, - udp_hdr_ready=output_3_udp_hdr_ready, - udp_hdr_valid=output_3_udp_hdr_valid, - eth_dest_mac=output_3_eth_dest_mac, - eth_src_mac=output_3_eth_src_mac, - eth_type=output_3_eth_type, - ip_version=output_3_ip_version, - ip_ihl=output_3_ip_ihl, - ip_dscp=output_3_ip_dscp, - ip_ecn=output_3_ip_ecn, - ip_length=output_3_ip_length, - ip_identification=output_3_ip_identification, - ip_flags=output_3_ip_flags, - ip_fragment_offset=output_3_ip_fragment_offset, - ip_ttl=output_3_ip_ttl, - ip_protocol=output_3_ip_protocol, - ip_header_checksum=output_3_ip_header_checksum, - ip_source_ip=output_3_ip_source_ip, - ip_dest_ip=output_3_ip_dest_ip, - udp_source_port=output_3_udp_source_port, - udp_dest_port=output_3_udp_dest_port, - udp_length=output_3_udp_length, - udp_checksum=output_3_udp_checksum, - udp_payload_tdata=output_3_udp_payload_tdata, - udp_payload_tkeep=output_3_udp_payload_tkeep, - udp_payload_tvalid=output_3_udp_payload_tvalid, - udp_payload_tready=output_3_udp_payload_tready, - udp_payload_tlast=output_3_udp_payload_tlast, - udp_payload_tuser=output_3_udp_payload_tuser, - pause=sink_3_pause, - name='sink_3' - ) + sink_logic_list.append(s.create_logic( + clk, + rst, + udp_hdr_ready=m_udp_hdr_ready_list[k], + udp_hdr_valid=m_udp_hdr_valid_list[k], + eth_dest_mac=m_eth_dest_mac_list[k], + eth_src_mac=m_eth_src_mac_list[k], + eth_type=m_eth_type_list[k], + ip_version=m_ip_version_list[k], + ip_ihl=m_ip_ihl_list[k], + ip_dscp=m_ip_dscp_list[k], + ip_ecn=m_ip_ecn_list[k], + ip_length=m_ip_length_list[k], + ip_identification=m_ip_identification_list[k], + ip_flags=m_ip_flags_list[k], + ip_fragment_offset=m_ip_fragment_offset_list[k], + ip_ttl=m_ip_ttl_list[k], + ip_protocol=m_ip_protocol_list[k], + ip_header_checksum=m_ip_header_checksum_list[k], + ip_source_ip=m_ip_source_ip_list[k], + ip_dest_ip=m_ip_dest_ip_list[k], + udp_source_port=m_udp_source_port_list[k], + udp_dest_port=m_udp_dest_port_list[k], + udp_length=m_udp_length_list[k], + udp_checksum=m_udp_checksum_list[k], + udp_payload_tdata=m_udp_payload_axis_tdata_list[k], + udp_payload_tkeep=m_udp_payload_axis_tkeep_list[k], + udp_payload_tvalid=m_udp_payload_axis_tvalid_list[k], + udp_payload_tready=m_udp_payload_axis_tready_list[k], + udp_payload_tlast=m_udp_payload_axis_tlast_list[k], + udp_payload_tuser=m_udp_payload_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) # DUT if os.system(build_cmd): @@ -397,149 +255,70 @@ def bench(): rst=rst, current_test=current_test, - input_udp_hdr_valid=input_udp_hdr_valid, - input_udp_hdr_ready=input_udp_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_udp_source_port=input_udp_source_port, - input_udp_dest_port=input_udp_dest_port, - input_udp_length=input_udp_length, - input_udp_checksum=input_udp_checksum, - input_udp_payload_tdata=input_udp_payload_tdata, - input_udp_payload_tkeep=input_udp_payload_tkeep, - input_udp_payload_tvalid=input_udp_payload_tvalid, - input_udp_payload_tready=input_udp_payload_tready, - input_udp_payload_tlast=input_udp_payload_tlast, - input_udp_payload_tuser=input_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep=s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tid=s_udp_payload_axis_tid, + s_udp_payload_axis_tdest=s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_0_udp_hdr_valid=output_0_udp_hdr_valid, - output_0_udp_hdr_ready=output_0_udp_hdr_ready, - output_0_eth_dest_mac=output_0_eth_dest_mac, - output_0_eth_src_mac=output_0_eth_src_mac, - output_0_eth_type=output_0_eth_type, - output_0_ip_version=output_0_ip_version, - output_0_ip_ihl=output_0_ip_ihl, - output_0_ip_dscp=output_0_ip_dscp, - output_0_ip_ecn=output_0_ip_ecn, - output_0_ip_length=output_0_ip_length, - output_0_ip_identification=output_0_ip_identification, - output_0_ip_flags=output_0_ip_flags, - output_0_ip_fragment_offset=output_0_ip_fragment_offset, - output_0_ip_ttl=output_0_ip_ttl, - output_0_ip_protocol=output_0_ip_protocol, - output_0_ip_header_checksum=output_0_ip_header_checksum, - output_0_ip_source_ip=output_0_ip_source_ip, - output_0_ip_dest_ip=output_0_ip_dest_ip, - output_0_udp_source_port=output_0_udp_source_port, - output_0_udp_dest_port=output_0_udp_dest_port, - output_0_udp_length=output_0_udp_length, - output_0_udp_checksum=output_0_udp_checksum, - output_0_udp_payload_tdata=output_0_udp_payload_tdata, - output_0_udp_payload_tkeep=output_0_udp_payload_tkeep, - output_0_udp_payload_tvalid=output_0_udp_payload_tvalid, - output_0_udp_payload_tready=output_0_udp_payload_tready, - output_0_udp_payload_tlast=output_0_udp_payload_tlast, - output_0_udp_payload_tuser=output_0_udp_payload_tuser, - output_1_udp_hdr_valid=output_1_udp_hdr_valid, - output_1_udp_hdr_ready=output_1_udp_hdr_ready, - output_1_eth_dest_mac=output_1_eth_dest_mac, - output_1_eth_src_mac=output_1_eth_src_mac, - output_1_eth_type=output_1_eth_type, - output_1_ip_version=output_1_ip_version, - output_1_ip_ihl=output_1_ip_ihl, - output_1_ip_dscp=output_1_ip_dscp, - output_1_ip_ecn=output_1_ip_ecn, - output_1_ip_length=output_1_ip_length, - output_1_ip_identification=output_1_ip_identification, - output_1_ip_flags=output_1_ip_flags, - output_1_ip_fragment_offset=output_1_ip_fragment_offset, - output_1_ip_ttl=output_1_ip_ttl, - output_1_ip_protocol=output_1_ip_protocol, - output_1_ip_header_checksum=output_1_ip_header_checksum, - output_1_ip_source_ip=output_1_ip_source_ip, - output_1_ip_dest_ip=output_1_ip_dest_ip, - output_1_udp_source_port=output_1_udp_source_port, - output_1_udp_dest_port=output_1_udp_dest_port, - output_1_udp_length=output_1_udp_length, - output_1_udp_checksum=output_1_udp_checksum, - output_1_udp_payload_tdata=output_1_udp_payload_tdata, - output_1_udp_payload_tkeep=output_1_udp_payload_tkeep, - output_1_udp_payload_tvalid=output_1_udp_payload_tvalid, - output_1_udp_payload_tready=output_1_udp_payload_tready, - output_1_udp_payload_tlast=output_1_udp_payload_tlast, - output_1_udp_payload_tuser=output_1_udp_payload_tuser, - output_2_udp_hdr_valid=output_2_udp_hdr_valid, - output_2_udp_hdr_ready=output_2_udp_hdr_ready, - output_2_eth_dest_mac=output_2_eth_dest_mac, - output_2_eth_src_mac=output_2_eth_src_mac, - output_2_eth_type=output_2_eth_type, - output_2_ip_version=output_2_ip_version, - output_2_ip_ihl=output_2_ip_ihl, - output_2_ip_dscp=output_2_ip_dscp, - output_2_ip_ecn=output_2_ip_ecn, - output_2_ip_length=output_2_ip_length, - output_2_ip_identification=output_2_ip_identification, - output_2_ip_flags=output_2_ip_flags, - output_2_ip_fragment_offset=output_2_ip_fragment_offset, - output_2_ip_ttl=output_2_ip_ttl, - output_2_ip_protocol=output_2_ip_protocol, - output_2_ip_header_checksum=output_2_ip_header_checksum, - output_2_ip_source_ip=output_2_ip_source_ip, - output_2_ip_dest_ip=output_2_ip_dest_ip, - output_2_udp_source_port=output_2_udp_source_port, - output_2_udp_dest_port=output_2_udp_dest_port, - output_2_udp_length=output_2_udp_length, - output_2_udp_checksum=output_2_udp_checksum, - output_2_udp_payload_tdata=output_2_udp_payload_tdata, - output_2_udp_payload_tkeep=output_2_udp_payload_tkeep, - output_2_udp_payload_tvalid=output_2_udp_payload_tvalid, - output_2_udp_payload_tready=output_2_udp_payload_tready, - output_2_udp_payload_tlast=output_2_udp_payload_tlast, - output_2_udp_payload_tuser=output_2_udp_payload_tuser, - output_3_udp_hdr_valid=output_3_udp_hdr_valid, - output_3_udp_hdr_ready=output_3_udp_hdr_ready, - output_3_eth_dest_mac=output_3_eth_dest_mac, - output_3_eth_src_mac=output_3_eth_src_mac, - output_3_eth_type=output_3_eth_type, - output_3_ip_version=output_3_ip_version, - output_3_ip_ihl=output_3_ip_ihl, - output_3_ip_dscp=output_3_ip_dscp, - output_3_ip_ecn=output_3_ip_ecn, - output_3_ip_length=output_3_ip_length, - output_3_ip_identification=output_3_ip_identification, - output_3_ip_flags=output_3_ip_flags, - output_3_ip_fragment_offset=output_3_ip_fragment_offset, - output_3_ip_ttl=output_3_ip_ttl, - output_3_ip_protocol=output_3_ip_protocol, - output_3_ip_header_checksum=output_3_ip_header_checksum, - output_3_ip_source_ip=output_3_ip_source_ip, - output_3_ip_dest_ip=output_3_ip_dest_ip, - output_3_udp_source_port=output_3_udp_source_port, - output_3_udp_dest_port=output_3_udp_dest_port, - output_3_udp_length=output_3_udp_length, - output_3_udp_checksum=output_3_udp_checksum, - output_3_udp_payload_tdata=output_3_udp_payload_tdata, - output_3_udp_payload_tkeep=output_3_udp_payload_tkeep, - output_3_udp_payload_tvalid=output_3_udp_payload_tvalid, - output_3_udp_payload_tready=output_3_udp_payload_tready, - output_3_udp_payload_tlast=output_3_udp_payload_tlast, - output_3_udp_payload_tuser=output_3_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep=m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tid=m_udp_payload_axis_tid, + m_udp_payload_axis_tdest=m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, enable=enable, + drop=drop, select=select ) @@ -593,8 +372,8 @@ def bench(): source.send(test_frame) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame @@ -632,8 +411,8 @@ def bench(): source.send(test_frame) - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame @@ -695,13 +474,13 @@ def bench(): source.send(test_frame1) source.send(test_frame2) - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame1 - yield sink_0.wait() - rx_frame = sink_0.recv() + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() assert rx_frame == test_frame2 @@ -764,17 +543,17 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_udp_payload_tvalid or input_udp_hdr_valid: + while s_udp_payload_axis_tvalid or s_udp_hdr_valid: yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -837,7 +616,7 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_udp_payload_tvalid or input_udp_hdr_valid: + while s_udp_payload_axis_tvalid or s_udp_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -846,13 +625,13 @@ def bench(): yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 @@ -915,33 +694,120 @@ def bench(): source.send(test_frame2) yield clk.posedge - while input_udp_payload_tvalid or input_udp_hdr_valid: - sink_0_pause.next = True - sink_1_pause.next = True - sink_2_pause.next = True - sink_3_pause.next = True + while s_udp_payload_axis_tvalid or s_udp_hdr_valid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_0_pause.next = False - sink_1_pause.next = False - sink_2_pause.next = False - sink_3_pause.next = False + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False yield clk.posedge select.next = 2 - yield sink_1.wait() - rx_frame = sink_1.recv() + yield sink_list[1].wait() + rx_frame = sink_list[1].recv() assert rx_frame == test_frame1 - yield sink_2.wait() - rx_frame = sink_2.recv() + yield sink_list[2].wait() + rx_frame = sink_list[2].recv() assert rx_frame == test_frame2 yield delay(100) + yield clk.posedge + print("test 7: enable") + current_test.next = 7 + + enable.next = False + select.next = 0 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + enable.next = True + + yield sink_list[0].wait() + rx_frame = sink_list[0].recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 8: drop") + current_test.next = 8 + + drop.next = True + select.next = 0 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x8000 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1 + test_frame.udp_dest_port = 2 + test_frame.udp_length = None + test_frame.udp_checksum = None + test_frame.payload = bytearray(range(32)) + test_frame.build() + + source.send(test_frame) + + yield delay(500) + + assert sink_list[0].empty() + + drop.next = False + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_udp_demux_64_4.v b/tb/test_udp_demux_64_4.v index 5dacdc1fd..dfab33290 100644 --- a/tb/test_udp_demux_64_4.v +++ b/tb/test_udp_demux_64_4.v @@ -27,162 +27,95 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for udp_demux_64_4 + * Testbench for udp_demux */ module test_udp_demux_64_4; +// Parameters +parameter M_COUNT = 4; +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_udp_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [15:0] input_udp_source_port = 0; -reg [15:0] input_udp_dest_port = 0; -reg [15:0] input_udp_length = 0; -reg [15:0] input_udp_checksum = 0; -reg [63:0] input_udp_payload_tdata = 0; -reg [7:0] input_udp_payload_tkeep = 0; -reg input_udp_payload_tvalid = 0; -reg input_udp_payload_tlast = 0; -reg input_udp_payload_tuser = 0; +reg s_udp_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [15:0] s_udp_source_port = 0; +reg [15:0] s_udp_dest_port = 0; +reg [15:0] s_udp_length = 0; +reg [15:0] s_udp_checksum = 0; +reg [DATA_WIDTH-1:0] s_udp_payload_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_udp_payload_axis_tkeep = 0; +reg s_udp_payload_axis_tvalid = 0; +reg s_udp_payload_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_udp_payload_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_udp_payload_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_udp_payload_axis_tuser = 0; -reg output_0_udp_hdr_ready = 0; -reg output_0_udp_payload_tready = 0; -reg output_1_udp_hdr_ready = 0; -reg output_1_udp_payload_tready = 0; -reg output_2_udp_hdr_ready = 0; -reg output_2_udp_payload_tready = 0; -reg output_3_udp_hdr_ready = 0; -reg output_3_udp_payload_tready = 0; +reg [M_COUNT-1:0] m_udp_hdr_ready = 0; +reg [M_COUNT-1:0] m_udp_payload_axis_tready = 0; reg enable = 0; +reg drop = 0; reg [1:0] select = 0; // Outputs -wire input_udp_hdr_ready; -wire input_udp_payload_tready; +wire s_udp_hdr_ready; +wire s_udp_payload_axis_tready; -wire output_0_udp_hdr_valid; -wire [47:0] output_0_eth_dest_mac; -wire [47:0] output_0_eth_src_mac; -wire [15:0] output_0_eth_type; -wire [3:0] output_0_ip_version; -wire [3:0] output_0_ip_ihl; -wire [5:0] output_0_ip_dscp; -wire [1:0] output_0_ip_ecn; -wire [15:0] output_0_ip_length; -wire [15:0] output_0_ip_identification; -wire [2:0] output_0_ip_flags; -wire [12:0] output_0_ip_fragment_offset; -wire [7:0] output_0_ip_ttl; -wire [7:0] output_0_ip_protocol; -wire [15:0] output_0_ip_header_checksum; -wire [31:0] output_0_ip_source_ip; -wire [31:0] output_0_ip_dest_ip; -wire [15:0] output_0_udp_source_port; -wire [15:0] output_0_udp_dest_port; -wire [15:0] output_0_udp_length; -wire [15:0] output_0_udp_checksum; -wire [63:0] output_0_udp_payload_tdata; -wire [7:0] output_0_udp_payload_tkeep; -wire output_0_udp_payload_tvalid; -wire output_0_udp_payload_tlast; -wire output_0_udp_payload_tuser; -wire output_1_udp_hdr_valid; -wire [47:0] output_1_eth_dest_mac; -wire [47:0] output_1_eth_src_mac; -wire [15:0] output_1_eth_type; -wire [3:0] output_1_ip_version; -wire [3:0] output_1_ip_ihl; -wire [5:0] output_1_ip_dscp; -wire [1:0] output_1_ip_ecn; -wire [15:0] output_1_ip_length; -wire [15:0] output_1_ip_identification; -wire [2:0] output_1_ip_flags; -wire [12:0] output_1_ip_fragment_offset; -wire [7:0] output_1_ip_ttl; -wire [7:0] output_1_ip_protocol; -wire [15:0] output_1_ip_header_checksum; -wire [31:0] output_1_ip_source_ip; -wire [31:0] output_1_ip_dest_ip; -wire [15:0] output_1_udp_source_port; -wire [15:0] output_1_udp_dest_port; -wire [15:0] output_1_udp_length; -wire [15:0] output_1_udp_checksum; -wire [63:0] output_1_udp_payload_tdata; -wire [7:0] output_1_udp_payload_tkeep; -wire output_1_udp_payload_tvalid; -wire output_1_udp_payload_tlast; -wire output_1_udp_payload_tuser; -wire output_2_udp_hdr_valid; -wire [47:0] output_2_eth_dest_mac; -wire [47:0] output_2_eth_src_mac; -wire [15:0] output_2_eth_type; -wire [3:0] output_2_ip_version; -wire [3:0] output_2_ip_ihl; -wire [5:0] output_2_ip_dscp; -wire [1:0] output_2_ip_ecn; -wire [15:0] output_2_ip_length; -wire [15:0] output_2_ip_identification; -wire [2:0] output_2_ip_flags; -wire [12:0] output_2_ip_fragment_offset; -wire [7:0] output_2_ip_ttl; -wire [7:0] output_2_ip_protocol; -wire [15:0] output_2_ip_header_checksum; -wire [31:0] output_2_ip_source_ip; -wire [31:0] output_2_ip_dest_ip; -wire [15:0] output_2_udp_source_port; -wire [15:0] output_2_udp_dest_port; -wire [15:0] output_2_udp_length; -wire [15:0] output_2_udp_checksum; -wire [63:0] output_2_udp_payload_tdata; -wire [7:0] output_2_udp_payload_tkeep; -wire output_2_udp_payload_tvalid; -wire output_2_udp_payload_tlast; -wire output_2_udp_payload_tuser; -wire output_3_udp_hdr_valid; -wire [47:0] output_3_eth_dest_mac; -wire [47:0] output_3_eth_src_mac; -wire [15:0] output_3_eth_type; -wire [3:0] output_3_ip_version; -wire [3:0] output_3_ip_ihl; -wire [5:0] output_3_ip_dscp; -wire [1:0] output_3_ip_ecn; -wire [15:0] output_3_ip_length; -wire [15:0] output_3_ip_identification; -wire [2:0] output_3_ip_flags; -wire [12:0] output_3_ip_fragment_offset; -wire [7:0] output_3_ip_ttl; -wire [7:0] output_3_ip_protocol; -wire [15:0] output_3_ip_header_checksum; -wire [31:0] output_3_ip_source_ip; -wire [31:0] output_3_ip_dest_ip; -wire [15:0] output_3_udp_source_port; -wire [15:0] output_3_udp_dest_port; -wire [15:0] output_3_udp_length; -wire [15:0] output_3_udp_checksum; -wire [63:0] output_3_udp_payload_tdata; -wire [7:0] output_3_udp_payload_tkeep; -wire output_3_udp_payload_tvalid; -wire output_3_udp_payload_tlast; -wire output_3_udp_payload_tuser; +wire [M_COUNT-1:0] m_udp_hdr_valid; +wire [M_COUNT*48-1:0] m_eth_dest_mac; +wire [M_COUNT*48-1:0] m_eth_src_mac; +wire [M_COUNT*16-1:0] m_eth_type; +wire [M_COUNT*4-1:0] m_ip_version; +wire [M_COUNT*4-1:0] m_ip_ihl; +wire [M_COUNT*6-1:0] m_ip_dscp; +wire [M_COUNT*2-1:0] m_ip_ecn; +wire [M_COUNT*16-1:0] m_ip_length; +wire [M_COUNT*16-1:0] m_ip_identification; +wire [M_COUNT*3-1:0] m_ip_flags; +wire [M_COUNT*13-1:0] m_ip_fragment_offset; +wire [M_COUNT*8-1:0] m_ip_ttl; +wire [M_COUNT*8-1:0] m_ip_protocol; +wire [M_COUNT*16-1:0] m_ip_header_checksum; +wire [M_COUNT*32-1:0] m_ip_source_ip; +wire [M_COUNT*32-1:0] m_ip_dest_ip; +wire [M_COUNT*16-1:0] m_udp_source_port; +wire [M_COUNT*16-1:0] m_udp_dest_port; +wire [M_COUNT*16-1:0] m_udp_length; +wire [M_COUNT*16-1:0] m_udp_checksum; +wire [M_COUNT*DATA_WIDTH-1:0] m_udp_payload_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_udp_payload_axis_tkeep; +wire [M_COUNT-1:0] m_udp_payload_axis_tvalid; +wire [M_COUNT-1:0] m_udp_payload_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_udp_payload_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_udp_payload_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_udp_payload_axis_tuser; initial begin // myhdl integration @@ -190,150 +123,71 @@ initial begin clk, rst, current_test, - input_udp_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_udp_source_port, - input_udp_dest_port, - input_udp_length, - input_udp_checksum, - input_udp_payload_tdata, - input_udp_payload_tkeep, - input_udp_payload_tvalid, - input_udp_payload_tlast, - input_udp_payload_tuser, - output_0_udp_hdr_ready, - output_0_udp_payload_tready, - output_1_udp_hdr_ready, - output_1_udp_payload_tready, - output_2_udp_hdr_ready, - output_2_udp_payload_tready, - output_3_udp_hdr_ready, - output_3_udp_payload_tready, + s_udp_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tid, + s_udp_payload_axis_tdest, + s_udp_payload_axis_tuser, + m_udp_hdr_ready, + m_udp_payload_axis_tready, enable, + drop, select ); $to_myhdl( - input_udp_hdr_ready, - input_udp_payload_tready, - output_0_udp_hdr_valid, - output_0_eth_dest_mac, - output_0_eth_src_mac, - output_0_eth_type, - output_0_ip_version, - output_0_ip_ihl, - output_0_ip_dscp, - output_0_ip_ecn, - output_0_ip_length, - output_0_ip_identification, - output_0_ip_flags, - output_0_ip_fragment_offset, - output_0_ip_ttl, - output_0_ip_protocol, - output_0_ip_header_checksum, - output_0_ip_source_ip, - output_0_ip_dest_ip, - output_0_udp_source_port, - output_0_udp_dest_port, - output_0_udp_length, - output_0_udp_checksum, - output_0_udp_payload_tdata, - output_0_udp_payload_tkeep, - output_0_udp_payload_tvalid, - output_0_udp_payload_tlast, - output_0_udp_payload_tuser, - output_1_udp_hdr_valid, - output_1_eth_dest_mac, - output_1_eth_src_mac, - output_1_eth_type, - output_1_ip_version, - output_1_ip_ihl, - output_1_ip_dscp, - output_1_ip_ecn, - output_1_ip_length, - output_1_ip_identification, - output_1_ip_flags, - output_1_ip_fragment_offset, - output_1_ip_ttl, - output_1_ip_protocol, - output_1_ip_header_checksum, - output_1_ip_source_ip, - output_1_ip_dest_ip, - output_1_udp_source_port, - output_1_udp_dest_port, - output_1_udp_length, - output_1_udp_checksum, - output_1_udp_payload_tdata, - output_1_udp_payload_tkeep, - output_1_udp_payload_tvalid, - output_1_udp_payload_tlast, - output_1_udp_payload_tuser, - output_2_udp_hdr_valid, - output_2_eth_dest_mac, - output_2_eth_src_mac, - output_2_eth_type, - output_2_ip_version, - output_2_ip_ihl, - output_2_ip_dscp, - output_2_ip_ecn, - output_2_ip_length, - output_2_ip_identification, - output_2_ip_flags, - output_2_ip_fragment_offset, - output_2_ip_ttl, - output_2_ip_protocol, - output_2_ip_header_checksum, - output_2_ip_source_ip, - output_2_ip_dest_ip, - output_2_udp_source_port, - output_2_udp_dest_port, - output_2_udp_length, - output_2_udp_checksum, - output_2_udp_payload_tdata, - output_2_udp_payload_tkeep, - output_2_udp_payload_tvalid, - output_2_udp_payload_tlast, - output_2_udp_payload_tuser, - output_3_udp_hdr_valid, - output_3_eth_dest_mac, - output_3_eth_src_mac, - output_3_eth_type, - output_3_ip_version, - output_3_ip_ihl, - output_3_ip_dscp, - output_3_ip_ecn, - output_3_ip_length, - output_3_ip_identification, - output_3_ip_flags, - output_3_ip_fragment_offset, - output_3_ip_ttl, - output_3_ip_protocol, - output_3_ip_header_checksum, - output_3_ip_source_ip, - output_3_ip_dest_ip, - output_3_udp_source_port, - output_3_udp_dest_port, - output_3_udp_length, - output_3_udp_checksum, - output_3_udp_payload_tdata, - output_3_udp_payload_tkeep, - output_3_udp_payload_tvalid, - output_3_udp_payload_tlast, - output_3_udp_payload_tuser + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_udp_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tid, + m_udp_payload_axis_tdest, + m_udp_payload_axis_tuser ); // dump file @@ -341,154 +195,86 @@ initial begin $dumpvars(0, test_udp_demux_64_4); end -udp_demux_64_4 +udp_demux #( + .M_COUNT(M_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), - .input_udp_checksum(input_udp_checksum), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tkeep(input_udp_payload_tkeep), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tid(s_udp_payload_axis_tid), + .s_udp_payload_axis_tdest(s_udp_payload_axis_tdest), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // UDP frame outputs - .output_0_udp_hdr_valid(output_0_udp_hdr_valid), - .output_0_udp_hdr_ready(output_0_udp_hdr_ready), - .output_0_eth_dest_mac(output_0_eth_dest_mac), - .output_0_eth_src_mac(output_0_eth_src_mac), - .output_0_eth_type(output_0_eth_type), - .output_0_ip_version(output_0_ip_version), - .output_0_ip_ihl(output_0_ip_ihl), - .output_0_ip_dscp(output_0_ip_dscp), - .output_0_ip_ecn(output_0_ip_ecn), - .output_0_ip_length(output_0_ip_length), - .output_0_ip_identification(output_0_ip_identification), - .output_0_ip_flags(output_0_ip_flags), - .output_0_ip_fragment_offset(output_0_ip_fragment_offset), - .output_0_ip_ttl(output_0_ip_ttl), - .output_0_ip_protocol(output_0_ip_protocol), - .output_0_ip_header_checksum(output_0_ip_header_checksum), - .output_0_ip_source_ip(output_0_ip_source_ip), - .output_0_ip_dest_ip(output_0_ip_dest_ip), - .output_0_udp_source_port(output_0_udp_source_port), - .output_0_udp_dest_port(output_0_udp_dest_port), - .output_0_udp_length(output_0_udp_length), - .output_0_udp_checksum(output_0_udp_checksum), - .output_0_udp_payload_tdata(output_0_udp_payload_tdata), - .output_0_udp_payload_tkeep(output_0_udp_payload_tkeep), - .output_0_udp_payload_tvalid(output_0_udp_payload_tvalid), - .output_0_udp_payload_tready(output_0_udp_payload_tready), - .output_0_udp_payload_tlast(output_0_udp_payload_tlast), - .output_0_udp_payload_tuser(output_0_udp_payload_tuser), - .output_1_udp_hdr_valid(output_1_udp_hdr_valid), - .output_1_udp_hdr_ready(output_1_udp_hdr_ready), - .output_1_eth_dest_mac(output_1_eth_dest_mac), - .output_1_eth_src_mac(output_1_eth_src_mac), - .output_1_eth_type(output_1_eth_type), - .output_1_ip_version(output_1_ip_version), - .output_1_ip_ihl(output_1_ip_ihl), - .output_1_ip_dscp(output_1_ip_dscp), - .output_1_ip_ecn(output_1_ip_ecn), - .output_1_ip_length(output_1_ip_length), - .output_1_ip_identification(output_1_ip_identification), - .output_1_ip_flags(output_1_ip_flags), - .output_1_ip_fragment_offset(output_1_ip_fragment_offset), - .output_1_ip_ttl(output_1_ip_ttl), - .output_1_ip_protocol(output_1_ip_protocol), - .output_1_ip_header_checksum(output_1_ip_header_checksum), - .output_1_ip_source_ip(output_1_ip_source_ip), - .output_1_ip_dest_ip(output_1_ip_dest_ip), - .output_1_udp_source_port(output_1_udp_source_port), - .output_1_udp_dest_port(output_1_udp_dest_port), - .output_1_udp_length(output_1_udp_length), - .output_1_udp_checksum(output_1_udp_checksum), - .output_1_udp_payload_tdata(output_1_udp_payload_tdata), - .output_1_udp_payload_tkeep(output_1_udp_payload_tkeep), - .output_1_udp_payload_tvalid(output_1_udp_payload_tvalid), - .output_1_udp_payload_tready(output_1_udp_payload_tready), - .output_1_udp_payload_tlast(output_1_udp_payload_tlast), - .output_1_udp_payload_tuser(output_1_udp_payload_tuser), - .output_2_udp_hdr_valid(output_2_udp_hdr_valid), - .output_2_udp_hdr_ready(output_2_udp_hdr_ready), - .output_2_eth_dest_mac(output_2_eth_dest_mac), - .output_2_eth_src_mac(output_2_eth_src_mac), - .output_2_eth_type(output_2_eth_type), - .output_2_ip_version(output_2_ip_version), - .output_2_ip_ihl(output_2_ip_ihl), - .output_2_ip_dscp(output_2_ip_dscp), - .output_2_ip_ecn(output_2_ip_ecn), - .output_2_ip_length(output_2_ip_length), - .output_2_ip_identification(output_2_ip_identification), - .output_2_ip_flags(output_2_ip_flags), - .output_2_ip_fragment_offset(output_2_ip_fragment_offset), - .output_2_ip_ttl(output_2_ip_ttl), - .output_2_ip_protocol(output_2_ip_protocol), - .output_2_ip_header_checksum(output_2_ip_header_checksum), - .output_2_ip_source_ip(output_2_ip_source_ip), - .output_2_ip_dest_ip(output_2_ip_dest_ip), - .output_2_udp_source_port(output_2_udp_source_port), - .output_2_udp_dest_port(output_2_udp_dest_port), - .output_2_udp_length(output_2_udp_length), - .output_2_udp_checksum(output_2_udp_checksum), - .output_2_udp_payload_tdata(output_2_udp_payload_tdata), - .output_2_udp_payload_tkeep(output_2_udp_payload_tkeep), - .output_2_udp_payload_tvalid(output_2_udp_payload_tvalid), - .output_2_udp_payload_tready(output_2_udp_payload_tready), - .output_2_udp_payload_tlast(output_2_udp_payload_tlast), - .output_2_udp_payload_tuser(output_2_udp_payload_tuser), - .output_3_udp_hdr_valid(output_3_udp_hdr_valid), - .output_3_udp_hdr_ready(output_3_udp_hdr_ready), - .output_3_eth_dest_mac(output_3_eth_dest_mac), - .output_3_eth_src_mac(output_3_eth_src_mac), - .output_3_eth_type(output_3_eth_type), - .output_3_ip_version(output_3_ip_version), - .output_3_ip_ihl(output_3_ip_ihl), - .output_3_ip_dscp(output_3_ip_dscp), - .output_3_ip_ecn(output_3_ip_ecn), - .output_3_ip_length(output_3_ip_length), - .output_3_ip_identification(output_3_ip_identification), - .output_3_ip_flags(output_3_ip_flags), - .output_3_ip_fragment_offset(output_3_ip_fragment_offset), - .output_3_ip_ttl(output_3_ip_ttl), - .output_3_ip_protocol(output_3_ip_protocol), - .output_3_ip_header_checksum(output_3_ip_header_checksum), - .output_3_ip_source_ip(output_3_ip_source_ip), - .output_3_ip_dest_ip(output_3_ip_dest_ip), - .output_3_udp_source_port(output_3_udp_source_port), - .output_3_udp_dest_port(output_3_udp_dest_port), - .output_3_udp_length(output_3_udp_length), - .output_3_udp_checksum(output_3_udp_checksum), - .output_3_udp_payload_tdata(output_3_udp_payload_tdata), - .output_3_udp_payload_tkeep(output_3_udp_payload_tkeep), - .output_3_udp_payload_tvalid(output_3_udp_payload_tvalid), - .output_3_udp_payload_tready(output_3_udp_payload_tready), - .output_3_udp_payload_tlast(output_3_udp_payload_tlast), - .output_3_udp_payload_tuser(output_3_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tid(m_udp_payload_axis_tid), + .m_udp_payload_axis_tdest(m_udp_payload_axis_tdest), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Control .enable(enable), + .drop(drop), .select(select) ); From b3f50ac2c724763c1c30ed9c33a3489517b7d457 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 2 Nov 2018 00:40:15 -0700 Subject: [PATCH 467/617] Fix comments --- tb/test_ip_mux_4.v | 4 ++-- tb/test_ip_mux_64_4.v | 4 ++-- tb/test_udp_mux_4.v | 4 ++-- tb/test_udp_mux_64_4.v | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tb/test_ip_mux_4.v b/tb/test_ip_mux_4.v index ce0c97915..100426023 100644 --- a/tb/test_ip_mux_4.v +++ b/tb/test_ip_mux_4.v @@ -192,7 +192,7 @@ ip_mux #( UUT ( .clk(clk), .rst(rst), - // Ethernet frame inputs + // IP frame inputs .s_ip_hdr_valid(s_ip_hdr_valid), .s_ip_hdr_ready(s_ip_hdr_ready), .s_eth_dest_mac(s_eth_dest_mac), @@ -219,7 +219,7 @@ UUT ( .s_ip_payload_axis_tid(s_ip_payload_axis_tid), .s_ip_payload_axis_tdest(s_ip_payload_axis_tdest), .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), - // Ethernet frame output + // IP frame output .m_ip_hdr_valid(m_ip_hdr_valid), .m_ip_hdr_ready(m_ip_hdr_ready), .m_eth_dest_mac(m_eth_dest_mac), diff --git a/tb/test_ip_mux_64_4.v b/tb/test_ip_mux_64_4.v index 4bf3e0161..e03664a81 100644 --- a/tb/test_ip_mux_64_4.v +++ b/tb/test_ip_mux_64_4.v @@ -192,7 +192,7 @@ ip_mux #( UUT ( .clk(clk), .rst(rst), - // Ethernet frame inputs + // IP frame inputs .s_ip_hdr_valid(s_ip_hdr_valid), .s_ip_hdr_ready(s_ip_hdr_ready), .s_eth_dest_mac(s_eth_dest_mac), @@ -219,7 +219,7 @@ UUT ( .s_ip_payload_axis_tid(s_ip_payload_axis_tid), .s_ip_payload_axis_tdest(s_ip_payload_axis_tdest), .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), - // Ethernet frame output + // IP frame output .m_ip_hdr_valid(m_ip_hdr_valid), .m_ip_hdr_ready(m_ip_hdr_ready), .m_eth_dest_mac(m_eth_dest_mac), diff --git a/tb/test_udp_mux_4.v b/tb/test_udp_mux_4.v index 51af5c014..3b655374f 100644 --- a/tb/test_udp_mux_4.v +++ b/tb/test_udp_mux_4.v @@ -208,7 +208,7 @@ udp_mux #( UUT ( .clk(clk), .rst(rst), - // Ethernet frame inputs + // UDP frame inputs .s_udp_hdr_valid(s_udp_hdr_valid), .s_udp_hdr_ready(s_udp_hdr_ready), .s_eth_dest_mac(s_eth_dest_mac), @@ -239,7 +239,7 @@ UUT ( .s_udp_payload_axis_tid(s_udp_payload_axis_tid), .s_udp_payload_axis_tdest(s_udp_payload_axis_tdest), .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), - // Ethernet frame output + // UDP frame output .m_udp_hdr_valid(m_udp_hdr_valid), .m_udp_hdr_ready(m_udp_hdr_ready), .m_eth_dest_mac(m_eth_dest_mac), diff --git a/tb/test_udp_mux_64_4.v b/tb/test_udp_mux_64_4.v index 27ea342ed..710b765db 100644 --- a/tb/test_udp_mux_64_4.v +++ b/tb/test_udp_mux_64_4.v @@ -208,7 +208,7 @@ udp_mux #( UUT ( .clk(clk), .rst(rst), - // Ethernet frame inputs + // UDP frame inputs .s_udp_hdr_valid(s_udp_hdr_valid), .s_udp_hdr_ready(s_udp_hdr_ready), .s_eth_dest_mac(s_eth_dest_mac), @@ -239,7 +239,7 @@ UUT ( .s_udp_payload_axis_tid(s_udp_payload_axis_tid), .s_udp_payload_axis_tdest(s_udp_payload_axis_tdest), .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), - // Ethernet frame output + // UDP frame output .m_udp_hdr_valid(m_udp_hdr_valid), .m_udp_hdr_ready(m_udp_hdr_ready), .m_eth_dest_mac(m_eth_dest_mac), From d2fedc413461655614c5b40c16aebdf5e66c1023 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 7 Nov 2018 22:35:06 -0800 Subject: [PATCH 468/617] Rename ports --- rtl/arp.v | 144 +++--- rtl/arp_64.v | 152 +++--- rtl/arp_eth_rx.v | 222 ++++---- rtl/arp_eth_rx_64.v | 226 ++++---- rtl/arp_eth_tx.v | 274 +++++----- rtl/arp_eth_tx_64.v | 326 ++++++------ rtl/axis_eth_fcs.v | 18 +- rtl/axis_eth_fcs_64.v | 36 +- rtl/axis_eth_fcs_check.v | 224 ++++---- rtl/axis_eth_fcs_check_64.v | 284 +++++----- rtl/axis_eth_fcs_insert.v | 204 ++++---- rtl/axis_eth_fcs_insert_64.v | 448 ++++++++-------- rtl/axis_gmii_rx.v | 72 +-- rtl/axis_gmii_tx.v | 70 +-- rtl/axis_xgmii_rx_32.v | 102 ++-- rtl/axis_xgmii_rx_64.v | 110 ++-- rtl/axis_xgmii_tx_32.v | 118 ++--- rtl/axis_xgmii_tx_64.v | 138 ++--- rtl/eth_axis_rx.v | 226 ++++---- rtl/eth_axis_rx_64.v | 278 +++++----- rtl/eth_axis_tx.v | 214 ++++---- rtl/eth_axis_tx_64.v | 346 ++++++------- rtl/eth_mac_10g.v | 44 +- rtl/eth_mac_1g.v | 18 +- rtl/ip.v | 268 +++++----- rtl/ip_64.v | 284 +++++----- rtl/ip_complete.v | 414 +++++++-------- rtl/ip_complete_64.v | 450 ++++++++-------- rtl/ip_eth_rx.v | 394 +++++++------- rtl/ip_eth_rx_64.v | 518 +++++++++---------- rtl/ip_eth_tx.v | 342 ++++++------ rtl/ip_eth_tx_64.v | 518 +++++++++---------- rtl/udp.v | 554 ++++++++++---------- rtl/udp_64.v | 576 ++++++++++----------- rtl/udp_checksum_gen.v | 356 ++++++------- rtl/udp_checksum_gen_64.v | 386 +++++++------- rtl/udp_complete.v | 674 ++++++++++++------------ rtl/udp_complete_64.v | 718 +++++++++++++------------- rtl/udp_ip_rx.v | 440 ++++++++-------- rtl/udp_ip_rx_64.v | 476 ++++++++--------- rtl/udp_ip_tx.v | 422 +++++++-------- rtl/udp_ip_tx_64.v | 478 ++++++++--------- tb/test_arp.py | 120 ++--- tb/test_arp.v | 120 ++--- tb/test_arp_64.py | 132 ++--- tb/test_arp_64.v | 132 ++--- tb/test_arp_eth_rx.py | 154 +++--- tb/test_arp_eth_rx.v | 144 +++--- tb/test_arp_eth_rx_64.py | 160 +++--- tb/test_arp_eth_rx_64.v | 150 +++--- tb/test_arp_eth_tx.py | 134 ++--- tb/test_arp_eth_tx.v | 132 ++--- tb/test_arp_eth_tx_64.py | 140 ++--- tb/test_arp_eth_tx_64.v | 138 ++--- tb/test_axis_eth_fcs.py | 30 +- tb/test_axis_eth_fcs.v | 30 +- tb/test_axis_eth_fcs_64.py | 36 +- tb/test_axis_eth_fcs_64.v | 36 +- tb/test_axis_eth_fcs_check.py | 66 +-- tb/test_axis_eth_fcs_check.v | 60 +-- tb/test_axis_eth_fcs_check_64.py | 78 +-- tb/test_axis_eth_fcs_check_64.v | 72 +-- tb/test_axis_eth_fcs_insert.py | 66 +-- tb/test_axis_eth_fcs_insert.v | 60 +-- tb/test_axis_eth_fcs_insert_64.py | 78 +-- tb/test_axis_eth_fcs_insert_64.v | 72 +-- tb/test_axis_eth_fcs_insert_64_pad.py | 78 +-- tb/test_axis_eth_fcs_insert_64_pad.v | 72 +-- tb/test_axis_eth_fcs_insert_pad.py | 66 +-- tb/test_axis_eth_fcs_insert_pad.v | 60 +-- tb/test_axis_gmii_rx.py | 24 +- tb/test_axis_gmii_rx.v | 24 +- tb/test_axis_gmii_tx.py | 30 +- tb/test_axis_gmii_tx.v | 30 +- tb/test_axis_xgmii_rx_32.py | 30 +- tb/test_axis_xgmii_rx_32.v | 30 +- tb/test_axis_xgmii_rx_64.py | 30 +- tb/test_axis_xgmii_rx_64.v | 30 +- tb/test_axis_xgmii_tx_32.py | 36 +- tb/test_axis_xgmii_tx_32.v | 36 +- tb/test_axis_xgmii_tx_64.py | 36 +- tb/test_axis_xgmii_tx_64.v | 36 +- tb/test_eth_axis_rx.py | 96 ++-- tb/test_eth_axis_rx.v | 90 ++-- tb/test_eth_axis_rx_64.py | 108 ++-- tb/test_eth_axis_rx_64.v | 102 ++-- tb/test_eth_axis_tx.py | 96 ++-- tb/test_eth_axis_tx.v | 90 ++-- tb/test_eth_axis_tx_64.py | 108 ++-- tb/test_eth_axis_tx_64.v | 102 ++-- tb/test_ip.py | 348 ++++++------- tb/test_ip.v | 342 ++++++------ tb/test_ip_64.py | 372 ++++++------- tb/test_ip_64.v | 366 ++++++------- tb/test_ip_complete.py | 348 ++++++------- tb/test_ip_complete.v | 344 ++++++------ tb/test_ip_complete_64.py | 372 ++++++------- tb/test_ip_complete_64.v | 368 ++++++------- tb/test_ip_eth_rx.py | 204 ++++---- tb/test_ip_eth_rx.v | 198 +++---- tb/test_ip_eth_rx_64.py | 216 ++++---- tb/test_ip_eth_rx_64.v | 210 ++++---- tb/test_ip_eth_tx.py | 186 +++---- tb/test_ip_eth_tx.v | 180 +++---- tb/test_ip_eth_tx_64.py | 198 +++---- tb/test_ip_eth_tx_64.v | 192 +++---- tb/test_udp.py | 588 ++++++++++----------- tb/test_udp.v | 588 ++++++++++----------- tb/test_udp_64.py | 612 +++++++++++----------- tb/test_udp_64.v | 612 +++++++++++----------- tb/test_udp_checksum_gen.py | 306 +++++------ tb/test_udp_checksum_gen.v | 300 +++++------ tb/test_udp_checksum_gen_64.py | 318 ++++++------ tb/test_udp_checksum_gen_64.v | 312 +++++------ tb/test_udp_complete.py | 606 +++++++++++----------- tb/test_udp_complete.v | 600 ++++++++++----------- tb/test_udp_complete_64.py | 642 +++++++++++------------ tb/test_udp_complete_64.v | 636 +++++++++++------------ tb/test_udp_ip_rx.py | 306 +++++------ tb/test_udp_ip_rx.v | 300 +++++------ tb/test_udp_ip_rx_64.py | 318 ++++++------ tb/test_udp_ip_rx_64.v | 312 +++++------ tb/test_udp_ip_tx.py | 300 +++++------ tb/test_udp_ip_tx.v | 294 +++++------ tb/test_udp_ip_tx_64.py | 312 +++++------ tb/test_udp_ip_tx_64.v | 306 +++++------ 126 files changed, 14677 insertions(+), 14677 deletions(-) diff --git a/rtl/arp.v b/rtl/arp.v index fdf6b87e9..7ebe5c5cb 100644 --- a/rtl/arp.v +++ b/rtl/arp.v @@ -42,30 +42,30 @@ module arp #( /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [7:0] input_eth_payload_tdata, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [7:0] s_eth_payload_axis_tdata, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [7:0] m_eth_payload_axis_tdata, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * ARP requests @@ -117,31 +117,31 @@ arp_eth_rx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // ARP frame output - .output_frame_valid(incoming_frame_valid), - .output_frame_ready(incoming_frame_ready), - .output_eth_dest_mac(incoming_eth_dest_mac), - .output_eth_src_mac(incoming_eth_src_mac), - .output_eth_type(incoming_eth_type), - .output_arp_htype(incoming_arp_htype), - .output_arp_ptype(incoming_arp_ptype), - .output_arp_hlen(incoming_arp_hlen), - .output_arp_plen(incoming_arp_plen), - .output_arp_oper(incoming_arp_oper), - .output_arp_sha(incoming_arp_sha), - .output_arp_spa(incoming_arp_spa), - .output_arp_tha(incoming_arp_tha), - .output_arp_tpa(incoming_arp_tpa), + .m_frame_valid(incoming_frame_valid), + .m_frame_ready(incoming_frame_ready), + .m_eth_dest_mac(incoming_eth_dest_mac), + .m_eth_src_mac(incoming_eth_src_mac), + .m_eth_type(incoming_eth_type), + .m_arp_htype(incoming_arp_htype), + .m_arp_ptype(incoming_arp_ptype), + .m_arp_hlen(incoming_arp_hlen), + .m_arp_plen(incoming_arp_plen), + .m_arp_oper(incoming_arp_oper), + .m_arp_sha(incoming_arp_sha), + .m_arp_spa(incoming_arp_spa), + .m_arp_tha(incoming_arp_tha), + .m_arp_tpa(incoming_arp_tpa), // Status signals .busy(), .error_header_early_termination(), @@ -160,29 +160,29 @@ arp_eth_tx_inst ( .clk(clk), .rst(rst), // ARP frame input - .input_frame_valid(outgoing_frame_valid_reg), - .input_frame_ready(outgoing_frame_ready), - .input_eth_dest_mac(outgoing_eth_dest_mac_reg), - .input_eth_src_mac(local_mac), - .input_eth_type(16'h0806), - .input_arp_htype(16'h0001), - .input_arp_ptype(16'h0800), - .input_arp_oper(outgoing_arp_oper_reg), - .input_arp_sha(local_mac), - .input_arp_spa(local_ip), - .input_arp_tha(outgoing_arp_tha_reg), - .input_arp_tpa(outgoing_arp_tpa_reg), + .s_frame_valid(outgoing_frame_valid_reg), + .s_frame_ready(outgoing_frame_ready), + .s_eth_dest_mac(outgoing_eth_dest_mac_reg), + .s_eth_src_mac(local_mac), + .s_eth_type(16'h0806), + .s_arp_htype(16'h0001), + .s_arp_ptype(16'h0800), + .s_arp_oper(outgoing_arp_oper_reg), + .s_arp_sha(local_mac), + .s_arp_spa(local_ip), + .s_arp_tha(outgoing_arp_tha_reg), + .s_arp_tpa(outgoing_arp_tpa_reg), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Status signals .busy() ); @@ -244,7 +244,7 @@ assign arp_response_mac = arp_response_mac_reg; always @* begin incoming_frame_ready = 1'b0; - outgoing_frame_valid_next = outgoing_frame_valid_reg & ~outgoing_frame_ready; + outgoing_frame_valid_next = outgoing_frame_valid_reg && !outgoing_frame_ready; outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; outgoing_arp_oper_next = outgoing_arp_oper_reg; outgoing_arp_tha_next = outgoing_arp_tha_reg; @@ -262,13 +262,13 @@ always @* begin arp_request_operation_next = arp_request_operation_reg; arp_request_retry_cnt_next = arp_request_retry_cnt_reg; arp_request_timer_next = arp_request_timer_reg; - arp_response_valid_next = arp_response_valid_reg & ~arp_response_ready; + arp_response_valid_next = arp_response_valid_reg && !arp_response_ready; arp_response_error_next = 1'b0; arp_response_mac_next = 48'd0; // manage incoming frames incoming_frame_ready = outgoing_frame_ready; - if (incoming_frame_valid & incoming_frame_ready) begin + if (incoming_frame_valid && incoming_frame_ready) begin if (incoming_eth_type == 16'h0806 && incoming_arp_htype == 16'h0001 && incoming_arp_ptype == 16'h0800) begin // store sender addresses in cache cache_write_request_valid_next = 1'b1; @@ -304,7 +304,7 @@ always @* begin cache_query_request_valid_next = 1'b1; arp_request_timer_next = arp_request_timer_reg - 1; // if we got a response, it will go in the cache, so when the query succeds, we're done - if (cache_query_response_valid & ~cache_query_response_error) begin + if (cache_query_response_valid && !cache_query_response_error) begin arp_request_operation_next = 1'b0; cache_query_request_valid_next = 1'b0; arp_response_valid_next = 1'b1; @@ -336,7 +336,7 @@ always @* begin end end end else begin - arp_request_ready_next = ~arp_response_valid_next; + arp_request_ready_next = !arp_response_valid_next; if (cache_query_request_valid_reg) begin cache_query_request_valid_next = 1'b1; if (cache_query_response_valid) begin @@ -357,7 +357,7 @@ always @* begin arp_response_mac_next = cache_query_response_mac; end end - end else if (arp_request_valid & arp_request_ready) begin + end else if (arp_request_valid && arp_request_ready) begin if (~(arp_request_ip | subnet_mask) == 0) begin // broadcast address // (all bits in request IP set where subnet mask is clear) diff --git a/rtl/arp_64.v b/rtl/arp_64.v index 28de11a5e..086b579be 100644 --- a/rtl/arp_64.v +++ b/rtl/arp_64.v @@ -42,32 +42,32 @@ module arp_64 #( /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [63:0] input_eth_payload_tdata, - input wire [7:0] input_eth_payload_tkeep, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [63:0] s_eth_payload_axis_tdata, + input wire [7:0] s_eth_payload_axis_tkeep, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [63:0] m_eth_payload_axis_tdata, + output wire [7:0] m_eth_payload_axis_tkeep, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * ARP requests @@ -119,32 +119,32 @@ arp_eth_rx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // ARP frame output - .output_frame_valid(incoming_frame_valid), - .output_frame_ready(incoming_frame_ready), - .output_eth_dest_mac(incoming_eth_dest_mac), - .output_eth_src_mac(incoming_eth_src_mac), - .output_eth_type(incoming_eth_type), - .output_arp_htype(incoming_arp_htype), - .output_arp_ptype(incoming_arp_ptype), - .output_arp_hlen(incoming_arp_hlen), - .output_arp_plen(incoming_arp_plen), - .output_arp_oper(incoming_arp_oper), - .output_arp_sha(incoming_arp_sha), - .output_arp_spa(incoming_arp_spa), - .output_arp_tha(incoming_arp_tha), - .output_arp_tpa(incoming_arp_tpa), + .m_frame_valid(incoming_frame_valid), + .m_frame_ready(incoming_frame_ready), + .m_eth_dest_mac(incoming_eth_dest_mac), + .m_eth_src_mac(incoming_eth_src_mac), + .m_eth_type(incoming_eth_type), + .m_arp_htype(incoming_arp_htype), + .m_arp_ptype(incoming_arp_ptype), + .m_arp_hlen(incoming_arp_hlen), + .m_arp_plen(incoming_arp_plen), + .m_arp_oper(incoming_arp_oper), + .m_arp_sha(incoming_arp_sha), + .m_arp_spa(incoming_arp_spa), + .m_arp_tha(incoming_arp_tha), + .m_arp_tpa(incoming_arp_tpa), // Status signals .busy(), .error_header_early_termination(), @@ -163,30 +163,30 @@ arp_eth_tx_inst ( .clk(clk), .rst(rst), // ARP frame input - .input_frame_valid(outgoing_frame_valid_reg), - .input_frame_ready(outgoing_frame_ready), - .input_eth_dest_mac(outgoing_eth_dest_mac_reg), - .input_eth_src_mac(local_mac), - .input_eth_type(16'h0806), - .input_arp_htype(16'h0001), - .input_arp_ptype(16'h0800), - .input_arp_oper(outgoing_arp_oper_reg), - .input_arp_sha(local_mac), - .input_arp_spa(local_ip), - .input_arp_tha(outgoing_arp_tha_reg), - .input_arp_tpa(outgoing_arp_tpa_reg), + .s_frame_valid(outgoing_frame_valid_reg), + .s_frame_ready(outgoing_frame_ready), + .s_eth_dest_mac(outgoing_eth_dest_mac_reg), + .s_eth_src_mac(local_mac), + .s_eth_type(16'h0806), + .s_arp_htype(16'h0001), + .s_arp_ptype(16'h0800), + .s_arp_oper(outgoing_arp_oper_reg), + .s_arp_sha(local_mac), + .s_arp_spa(local_ip), + .s_arp_tha(outgoing_arp_tha_reg), + .s_arp_tpa(outgoing_arp_tpa_reg), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Status signals .busy() ); @@ -248,7 +248,7 @@ assign arp_response_mac = arp_response_mac_reg; always @* begin incoming_frame_ready = 1'b0; - outgoing_frame_valid_next = outgoing_frame_valid_reg & ~outgoing_frame_ready; + outgoing_frame_valid_next = outgoing_frame_valid_reg && !outgoing_frame_ready; outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; outgoing_arp_oper_next = outgoing_arp_oper_reg; outgoing_arp_tha_next = outgoing_arp_tha_reg; @@ -266,13 +266,13 @@ always @* begin arp_request_operation_next = arp_request_operation_reg; arp_request_retry_cnt_next = arp_request_retry_cnt_reg; arp_request_timer_next = arp_request_timer_reg; - arp_response_valid_next = arp_response_valid_reg & ~arp_response_ready; + arp_response_valid_next = arp_response_valid_reg && !arp_response_ready; arp_response_error_next = 1'b0; arp_response_mac_next = 48'd0; // manage incoming frames incoming_frame_ready = outgoing_frame_ready; - if (incoming_frame_valid & incoming_frame_ready) begin + if (incoming_frame_valid && incoming_frame_ready) begin if (incoming_eth_type == 16'h0806 && incoming_arp_htype == 16'h0001 && incoming_arp_ptype == 16'h0800) begin // store sender addresses in cache cache_write_request_valid_next = 1'b1; @@ -308,7 +308,7 @@ always @* begin cache_query_request_valid_next = 1'b1; arp_request_timer_next = arp_request_timer_reg - 1; // if we got a response, it will go in the cache, so when the query succeds, we're done - if (cache_query_response_valid & ~cache_query_response_error) begin + if (cache_query_response_valid && !cache_query_response_error) begin arp_request_operation_next = 1'b0; cache_query_request_valid_next = 1'b0; arp_response_valid_next = 1'b1; @@ -340,7 +340,7 @@ always @* begin end end end else begin - arp_request_ready_next = ~arp_response_valid_next; + arp_request_ready_next = !arp_response_valid_next; if (cache_query_request_valid_reg) begin cache_query_request_valid_next = 1'b1; if (cache_query_response_valid) begin @@ -361,7 +361,7 @@ always @* begin arp_response_mac_next = cache_query_response_mac; end end - end else if (arp_request_valid & arp_request_ready) begin + end else if (arp_request_valid && arp_request_ready) begin if (~(arp_request_ip | subnet_mask) == 0) begin // broadcast address // (all bits in request IP set where subnet mask is clear) diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index 63782d2e2..5a81690ba 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -37,34 +37,34 @@ module arp_eth_rx /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [7:0] input_eth_payload_tdata, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [7:0] s_eth_payload_axis_tdata, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * ARP frame output */ - output wire output_frame_valid, - input wire output_frame_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [15:0] output_arp_htype, - output wire [15:0] output_arp_ptype, - output wire [7:0] output_arp_hlen, - output wire [7:0] output_arp_plen, - output wire [15:0] output_arp_oper, - output wire [47:0] output_arp_sha, - output wire [31:0] output_arp_spa, - output wire [47:0] output_arp_tha, - output wire [31:0] output_arp_tpa, + output wire m_frame_valid, + input wire m_frame_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [15:0] m_arp_htype, + output wire [15:0] m_arp_ptype, + output wire [7:0] m_arp_hlen, + output wire [7:0] m_arp_plen, + output wire [15:0] m_arp_oper, + output wire [47:0] m_arp_sha, + output wire [31:0] m_arp_spa, + output wire [47:0] m_arp_tha, + output wire [31:0] m_arp_tpa, /* * Status signals @@ -138,43 +138,43 @@ reg store_arp_tpa_3; reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; +reg s_eth_hdr_ready_reg = 1'b0, s_eth_hdr_ready_next; +reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; -reg output_frame_valid_reg = 1'b0, output_frame_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; -reg [15:0] output_arp_htype_reg = 16'd0; -reg [15:0] output_arp_ptype_reg = 16'd0; -reg [7:0] output_arp_hlen_reg = 8'd0; -reg [7:0] output_arp_plen_reg = 8'd0; -reg [15:0] output_arp_oper_reg = 16'd0; -reg [47:0] output_arp_sha_reg = 48'd0; -reg [31:0] output_arp_spa_reg = 32'd0; -reg [47:0] output_arp_tha_reg = 48'd0; -reg [31:0] output_arp_tpa_reg = 32'd0; +reg m_frame_valid_reg = 1'b0, m_frame_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; +reg [15:0] m_arp_htype_reg = 16'd0; +reg [15:0] m_arp_ptype_reg = 16'd0; +reg [7:0] m_arp_hlen_reg = 8'd0; +reg [7:0] m_arp_plen_reg = 8'd0; +reg [15:0] m_arp_oper_reg = 16'd0; +reg [47:0] m_arp_sha_reg = 48'd0; +reg [31:0] m_arp_spa_reg = 32'd0; +reg [47:0] m_arp_tha_reg = 48'd0; +reg [31:0] m_arp_tpa_reg = 32'd0; reg busy_reg = 1'b0; reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; reg error_invalid_header_reg = 1'b0, error_invalid_header_next; -assign input_eth_hdr_ready = input_eth_hdr_ready_reg; -assign input_eth_payload_tready = input_eth_payload_tready_reg; +assign s_eth_hdr_ready = s_eth_hdr_ready_reg; +assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; -assign output_frame_valid = output_frame_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_arp_htype = output_arp_htype_reg; -assign output_arp_ptype = output_arp_ptype_reg; -assign output_arp_hlen = output_arp_hlen_reg; -assign output_arp_plen = output_arp_plen_reg; -assign output_arp_oper = output_arp_oper_reg; -assign output_arp_sha = output_arp_sha_reg; -assign output_arp_spa = output_arp_spa_reg; -assign output_arp_tha = output_arp_tha_reg; -assign output_arp_tpa = output_arp_tpa_reg; +assign m_frame_valid = m_frame_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_arp_htype = m_arp_htype_reg; +assign m_arp_ptype = m_arp_ptype_reg; +assign m_arp_hlen = m_arp_hlen_reg; +assign m_arp_plen = m_arp_plen_reg; +assign m_arp_oper = m_arp_oper_reg; +assign m_arp_sha = m_arp_sha_reg; +assign m_arp_spa = m_arp_spa_reg; +assign m_arp_tha = m_arp_tha_reg; +assign m_arp_tpa = m_arp_tpa_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -183,8 +183,8 @@ assign error_invalid_header = error_invalid_header_reg; always @* begin state_next = STATE_IDLE; - input_eth_hdr_ready_next = 1'b0; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b0; store_eth_hdr = 1'b0; store_arp_htype_0 = 1'b0; @@ -218,7 +218,7 @@ always @* begin frame_ptr_next = frame_ptr_reg; - output_frame_valid_next = output_frame_valid_reg & ~output_frame_ready; + m_frame_valid_next = m_frame_valid_reg && !m_frame_ready; error_header_early_termination_next = 1'b0; error_invalid_header_next = 1'b0; @@ -227,11 +227,11 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; - input_eth_hdr_ready_next = ~output_frame_valid_reg; + s_eth_hdr_ready_next = !m_frame_valid_reg; - if (input_eth_hdr_ready & input_eth_hdr_valid) begin - input_eth_hdr_ready_next = 1'b0; - input_eth_payload_tready_next = 1'b1; + if (s_eth_hdr_ready && s_eth_hdr_valid) begin + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b1; store_eth_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin @@ -240,9 +240,9 @@ always @* begin end STATE_READ_HEADER: begin // read header state - input_eth_payload_tready_next = 1'b1; + s_eth_payload_axis_tready_next = 1'b1; - if (input_eth_payload_tvalid) begin + if (s_eth_payload_axis_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg + 8'd1; state_next = STATE_READ_HEADER; @@ -279,20 +279,20 @@ always @* begin state_next = STATE_WAIT_LAST; end endcase - if (input_eth_payload_tlast) begin + if (s_eth_payload_axis_tlast) begin // end of frame if (frame_ptr_reg != 8'h1B) begin // don't have the whole header error_header_early_termination_next = 1'b1; - end else if (output_arp_hlen != 4'd6 || output_arp_plen != 4'd4) begin + end else if (m_arp_hlen != 4'd6 || m_arp_plen != 4'd4) begin // lengths not valid error_invalid_header_next = 1'b1; end else begin // otherwise, transfer tuser - output_frame_valid_next = ~input_eth_payload_tuser; + m_frame_valid_next = !s_eth_payload_axis_tuser; end - input_eth_hdr_ready_next = ~output_frame_valid_reg; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = !m_frame_valid_reg; + s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end end else begin @@ -301,19 +301,19 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_eth_payload_tready_next = 1'b1; + s_eth_payload_axis_tready_next = 1'b1; - if (input_eth_payload_tvalid) begin - if (input_eth_payload_tlast) begin - if (output_arp_hlen != 4'd6 || output_arp_plen != 4'd4) begin + if (s_eth_payload_axis_tvalid) begin + if (s_eth_payload_axis_tlast) begin + if (m_arp_hlen != 4'd6 || m_arp_plen != 4'd4) begin // lengths not valid error_invalid_header_next = 1'b1; end else begin // otherwise, transfer tuser - output_frame_valid_next = ~input_eth_payload_tuser; + m_frame_valid_next = !s_eth_payload_axis_tuser; end - input_eth_hdr_ready_next = ~output_frame_valid_reg; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = !m_frame_valid_reg; + s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -330,20 +330,20 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 8'd0; - input_eth_payload_tready_reg <= 1'b0; - output_frame_valid_reg <= 1'b0; + s_eth_payload_axis_tready_reg <= 1'b0; + m_frame_valid_reg <= 1'b0; busy_reg <= 1'b0; error_header_early_termination_reg <= 1'b0; error_invalid_header_reg <= 1'b0; end else begin state_reg <= state_next; - input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; - input_eth_payload_tready_reg <= input_eth_payload_tready_next; + s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; + s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; frame_ptr_reg <= frame_ptr_next; - output_frame_valid_reg <= output_frame_valid_next; + m_frame_valid_reg <= m_frame_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; error_invalid_header_reg <= error_invalid_header_next; @@ -353,39 +353,39 @@ always @(posedge clk) begin // datapath if (store_eth_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; end - if (store_arp_htype_0) output_arp_htype_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_htype_1) output_arp_htype_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_ptype_0) output_arp_ptype_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_ptype_1) output_arp_ptype_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_hlen) output_arp_hlen_reg <= input_eth_payload_tdata; - if (store_arp_plen) output_arp_plen_reg <= input_eth_payload_tdata; - if (store_arp_oper_0) output_arp_oper_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_oper_1) output_arp_oper_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_sha_0) output_arp_sha_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_sha_1) output_arp_sha_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_sha_2) output_arp_sha_reg[23:16] <= input_eth_payload_tdata; - if (store_arp_sha_3) output_arp_sha_reg[31:24] <= input_eth_payload_tdata; - if (store_arp_sha_4) output_arp_sha_reg[39:32] <= input_eth_payload_tdata; - if (store_arp_sha_5) output_arp_sha_reg[47:40] <= input_eth_payload_tdata; - if (store_arp_spa_0) output_arp_spa_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_spa_1) output_arp_spa_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_spa_2) output_arp_spa_reg[23:16] <= input_eth_payload_tdata; - if (store_arp_spa_3) output_arp_spa_reg[31:24] <= input_eth_payload_tdata; - if (store_arp_tha_0) output_arp_tha_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_tha_1) output_arp_tha_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_tha_2) output_arp_tha_reg[23:16] <= input_eth_payload_tdata; - if (store_arp_tha_3) output_arp_tha_reg[31:24] <= input_eth_payload_tdata; - if (store_arp_tha_4) output_arp_tha_reg[39:32] <= input_eth_payload_tdata; - if (store_arp_tha_5) output_arp_tha_reg[47:40] <= input_eth_payload_tdata; - if (store_arp_tpa_0) output_arp_tpa_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_arp_tpa_1) output_arp_tpa_reg[15: 8] <= input_eth_payload_tdata; - if (store_arp_tpa_2) output_arp_tpa_reg[23:16] <= input_eth_payload_tdata; - if (store_arp_tpa_3) output_arp_tpa_reg[31:24] <= input_eth_payload_tdata; + if (store_arp_htype_0) m_arp_htype_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_arp_htype_1) m_arp_htype_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_arp_ptype_0) m_arp_ptype_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_arp_ptype_1) m_arp_ptype_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_arp_hlen) m_arp_hlen_reg <= s_eth_payload_axis_tdata; + if (store_arp_plen) m_arp_plen_reg <= s_eth_payload_axis_tdata; + if (store_arp_oper_0) m_arp_oper_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_arp_oper_1) m_arp_oper_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_arp_sha_0) m_arp_sha_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_arp_sha_1) m_arp_sha_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_arp_sha_2) m_arp_sha_reg[23:16] <= s_eth_payload_axis_tdata; + if (store_arp_sha_3) m_arp_sha_reg[31:24] <= s_eth_payload_axis_tdata; + if (store_arp_sha_4) m_arp_sha_reg[39:32] <= s_eth_payload_axis_tdata; + if (store_arp_sha_5) m_arp_sha_reg[47:40] <= s_eth_payload_axis_tdata; + if (store_arp_spa_0) m_arp_spa_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_arp_spa_1) m_arp_spa_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_arp_spa_2) m_arp_spa_reg[23:16] <= s_eth_payload_axis_tdata; + if (store_arp_spa_3) m_arp_spa_reg[31:24] <= s_eth_payload_axis_tdata; + if (store_arp_tha_0) m_arp_tha_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_arp_tha_1) m_arp_tha_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_arp_tha_2) m_arp_tha_reg[23:16] <= s_eth_payload_axis_tdata; + if (store_arp_tha_3) m_arp_tha_reg[31:24] <= s_eth_payload_axis_tdata; + if (store_arp_tha_4) m_arp_tha_reg[39:32] <= s_eth_payload_axis_tdata; + if (store_arp_tha_5) m_arp_tha_reg[47:40] <= s_eth_payload_axis_tdata; + if (store_arp_tpa_0) m_arp_tpa_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_arp_tpa_1) m_arp_tpa_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_arp_tpa_2) m_arp_tpa_reg[23:16] <= s_eth_payload_axis_tdata; + if (store_arp_tpa_3) m_arp_tpa_reg[31:24] <= s_eth_payload_axis_tdata; end endmodule diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index b5e57ad8f..61b24fab8 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -37,35 +37,35 @@ module arp_eth_rx_64 /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [63:0] input_eth_payload_tdata, - input wire [7:0] input_eth_payload_tkeep, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [63:0] s_eth_payload_axis_tdata, + input wire [7:0] s_eth_payload_axis_tkeep, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * ARP frame output */ - output wire output_frame_valid, - input wire output_frame_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [15:0] output_arp_htype, - output wire [15:0] output_arp_ptype, - output wire [7:0] output_arp_hlen, - output wire [7:0] output_arp_plen, - output wire [15:0] output_arp_oper, - output wire [47:0] output_arp_sha, - output wire [31:0] output_arp_spa, - output wire [47:0] output_arp_tha, - output wire [31:0] output_arp_tpa, + output wire m_frame_valid, + input wire m_frame_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [15:0] m_arp_htype, + output wire [15:0] m_arp_ptype, + output wire [7:0] m_arp_hlen, + output wire [7:0] m_arp_plen, + output wire [15:0] m_arp_oper, + output wire [47:0] m_arp_sha, + output wire [31:0] m_arp_spa, + output wire [47:0] m_arp_tha, + output wire [31:0] m_arp_tpa, /* * Status signals @@ -115,43 +115,43 @@ reg store_arp_hdr_word_3; reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; +reg s_eth_hdr_ready_reg = 1'b0, s_eth_hdr_ready_next; +reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; -reg output_frame_valid_reg = 1'b0, output_frame_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; -reg [15:0] output_arp_htype_reg = 16'd0; -reg [15:0] output_arp_ptype_reg = 16'd0; -reg [7:0] output_arp_hlen_reg = 8'd0; -reg [7:0] output_arp_plen_reg = 8'd0; -reg [15:0] output_arp_oper_reg = 16'd0; -reg [47:0] output_arp_sha_reg = 48'd0; -reg [31:0] output_arp_spa_reg = 32'd0; -reg [47:0] output_arp_tha_reg = 48'd0; -reg [31:0] output_arp_tpa_reg = 32'd0; +reg m_frame_valid_reg = 1'b0, m_frame_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; +reg [15:0] m_arp_htype_reg = 16'd0; +reg [15:0] m_arp_ptype_reg = 16'd0; +reg [7:0] m_arp_hlen_reg = 8'd0; +reg [7:0] m_arp_plen_reg = 8'd0; +reg [15:0] m_arp_oper_reg = 16'd0; +reg [47:0] m_arp_sha_reg = 48'd0; +reg [31:0] m_arp_spa_reg = 32'd0; +reg [47:0] m_arp_tha_reg = 48'd0; +reg [31:0] m_arp_tpa_reg = 32'd0; reg busy_reg = 1'b0; reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; reg error_invalid_header_reg = 1'b0, error_invalid_header_next; -assign input_eth_hdr_ready = input_eth_hdr_ready_reg; -assign input_eth_payload_tready = input_eth_payload_tready_reg; +assign s_eth_hdr_ready = s_eth_hdr_ready_reg; +assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; -assign output_frame_valid = output_frame_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_arp_htype = output_arp_htype_reg; -assign output_arp_ptype = output_arp_ptype_reg; -assign output_arp_hlen = output_arp_hlen_reg; -assign output_arp_plen = output_arp_plen_reg; -assign output_arp_oper = output_arp_oper_reg; -assign output_arp_sha = output_arp_sha_reg; -assign output_arp_spa = output_arp_spa_reg; -assign output_arp_tha = output_arp_tha_reg; -assign output_arp_tpa = output_arp_tpa_reg; +assign m_frame_valid = m_frame_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_arp_htype = m_arp_htype_reg; +assign m_arp_ptype = m_arp_ptype_reg; +assign m_arp_hlen = m_arp_hlen_reg; +assign m_arp_plen = m_arp_plen_reg; +assign m_arp_oper = m_arp_oper_reg; +assign m_arp_sha = m_arp_sha_reg; +assign m_arp_spa = m_arp_spa_reg; +assign m_arp_tha = m_arp_tha_reg; +assign m_arp_tpa = m_arp_tpa_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -160,8 +160,8 @@ assign error_invalid_header = error_invalid_header_reg; always @* begin state_next = STATE_IDLE; - input_eth_hdr_ready_next = 1'b0; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b0; store_eth_hdr = 1'b0; store_arp_hdr_word_0 = 1'b0; @@ -171,7 +171,7 @@ always @* begin frame_ptr_next = frame_ptr_reg; - output_frame_valid_next = output_frame_valid_reg & ~output_frame_ready; + m_frame_valid_next = m_frame_valid_reg && !m_frame_ready; error_header_early_termination_next = 1'b0; error_invalid_header_next = 1'b0; @@ -180,11 +180,11 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; - input_eth_hdr_ready_next = ~output_frame_valid_reg; + s_eth_hdr_ready_next = !m_frame_valid_reg; - if (input_eth_hdr_ready & input_eth_hdr_valid) begin - input_eth_hdr_ready_next = 1'b0; - input_eth_payload_tready_next = 1'b1; + if (s_eth_hdr_ready && s_eth_hdr_valid) begin + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b1; store_eth_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin @@ -193,9 +193,9 @@ always @* begin end STATE_READ_HEADER: begin // read header state - input_eth_payload_tready_next = 1'b1; + s_eth_payload_axis_tready_next = 1'b1; - if (input_eth_payload_tvalid) begin + if (s_eth_payload_axis_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg + 8'd1; state_next = STATE_READ_HEADER; @@ -208,16 +208,16 @@ always @* begin state_next = STATE_WAIT_LAST; end endcase - if (input_eth_payload_tlast) begin - if (frame_ptr_reg != 8'h03 | (input_eth_payload_tkeep & 8'h0F) != 8'h0F) begin + if (s_eth_payload_axis_tlast) begin + if (frame_ptr_reg != 8'h03 || (s_eth_payload_axis_tkeep & 8'h0F) != 8'h0F) begin error_header_early_termination_next = 1'b1; - end else if (output_arp_hlen != 4'd6 || output_arp_plen != 4'd4) begin + end else if (m_arp_hlen != 4'd6 || m_arp_plen != 4'd4) begin error_invalid_header_next = 1'b1; end else begin - output_frame_valid_next = ~input_eth_payload_tuser; + m_frame_valid_next = !s_eth_payload_axis_tuser; end - input_eth_hdr_ready_next = ~output_frame_valid_reg; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = !m_frame_valid_reg; + s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end end else begin @@ -226,19 +226,19 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_eth_payload_tready_next = 1'b1; + s_eth_payload_axis_tready_next = 1'b1; - if (input_eth_payload_tvalid) begin - if (input_eth_payload_tlast) begin - if (output_arp_hlen != 4'd6 || output_arp_plen != 4'd4) begin + if (s_eth_payload_axis_tvalid) begin + if (s_eth_payload_axis_tlast) begin + if (m_arp_hlen != 4'd6 || m_arp_plen != 4'd4) begin // lengths not valid error_invalid_header_next = 1'b1; end else begin // otherwise, transfer tuser - output_frame_valid_next = ~input_eth_payload_tuser; + m_frame_valid_next = !s_eth_payload_axis_tuser; end - input_eth_hdr_ready_next = ~output_frame_valid_reg; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = !m_frame_valid_reg; + s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -255,20 +255,20 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 8'd0; - input_eth_payload_tready_reg <= 1'b0; - output_frame_valid_reg <= 1'b0; + s_eth_payload_axis_tready_reg <= 1'b0; + m_frame_valid_reg <= 1'b0; busy_reg <= 1'b0; error_header_early_termination_reg <= 1'b0; error_invalid_header_reg <= 1'b0; end else begin state_reg <= state_next; - input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; - input_eth_payload_tready_reg <= input_eth_payload_tready_next; + s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; + s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; frame_ptr_reg <= frame_ptr_next; - output_frame_valid_reg <= output_frame_valid_next; + m_frame_valid_reg <= m_frame_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; error_invalid_header_reg <= error_invalid_header_next; @@ -278,46 +278,46 @@ always @(posedge clk) begin // datapath if (store_eth_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; end if (store_arp_hdr_word_0) begin - output_arp_htype_reg[15: 8] <= input_eth_payload_tdata[ 7: 0]; - output_arp_htype_reg[ 7: 0] <= input_eth_payload_tdata[15: 8]; - output_arp_ptype_reg[15: 8] <= input_eth_payload_tdata[23:16]; - output_arp_ptype_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; - output_arp_hlen_reg <= input_eth_payload_tdata[39:32]; - output_arp_plen_reg <= input_eth_payload_tdata[47:40]; - output_arp_oper_reg[15: 8] <= input_eth_payload_tdata[55:48]; - output_arp_oper_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; + m_arp_htype_reg[15: 8] <= s_eth_payload_axis_tdata[ 7: 0]; + m_arp_htype_reg[ 7: 0] <= s_eth_payload_axis_tdata[15: 8]; + m_arp_ptype_reg[15: 8] <= s_eth_payload_axis_tdata[23:16]; + m_arp_ptype_reg[ 7: 0] <= s_eth_payload_axis_tdata[31:24]; + m_arp_hlen_reg <= s_eth_payload_axis_tdata[39:32]; + m_arp_plen_reg <= s_eth_payload_axis_tdata[47:40]; + m_arp_oper_reg[15: 8] <= s_eth_payload_axis_tdata[55:48]; + m_arp_oper_reg[ 7: 0] <= s_eth_payload_axis_tdata[63:56]; end if (store_arp_hdr_word_1) begin - output_arp_sha_reg[47:40] <= input_eth_payload_tdata[ 7: 0]; - output_arp_sha_reg[39:32] <= input_eth_payload_tdata[15: 8]; - output_arp_sha_reg[31:24] <= input_eth_payload_tdata[23:16]; - output_arp_sha_reg[23:16] <= input_eth_payload_tdata[31:24]; - output_arp_sha_reg[15: 8] <= input_eth_payload_tdata[39:32]; - output_arp_sha_reg[ 7: 0] <= input_eth_payload_tdata[47:40]; - output_arp_spa_reg[31:24] <= input_eth_payload_tdata[55:48]; - output_arp_spa_reg[23:16] <= input_eth_payload_tdata[63:56]; + m_arp_sha_reg[47:40] <= s_eth_payload_axis_tdata[ 7: 0]; + m_arp_sha_reg[39:32] <= s_eth_payload_axis_tdata[15: 8]; + m_arp_sha_reg[31:24] <= s_eth_payload_axis_tdata[23:16]; + m_arp_sha_reg[23:16] <= s_eth_payload_axis_tdata[31:24]; + m_arp_sha_reg[15: 8] <= s_eth_payload_axis_tdata[39:32]; + m_arp_sha_reg[ 7: 0] <= s_eth_payload_axis_tdata[47:40]; + m_arp_spa_reg[31:24] <= s_eth_payload_axis_tdata[55:48]; + m_arp_spa_reg[23:16] <= s_eth_payload_axis_tdata[63:56]; end if (store_arp_hdr_word_2) begin - output_arp_spa_reg[15: 8] <= input_eth_payload_tdata[ 7: 0]; - output_arp_spa_reg[ 7: 0] <= input_eth_payload_tdata[15: 8]; - output_arp_tha_reg[47:40] <= input_eth_payload_tdata[23:16]; - output_arp_tha_reg[39:32] <= input_eth_payload_tdata[31:24]; - output_arp_tha_reg[31:24] <= input_eth_payload_tdata[39:32]; - output_arp_tha_reg[23:16] <= input_eth_payload_tdata[47:40]; - output_arp_tha_reg[15: 8] <= input_eth_payload_tdata[55:48]; - output_arp_tha_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; + m_arp_spa_reg[15: 8] <= s_eth_payload_axis_tdata[ 7: 0]; + m_arp_spa_reg[ 7: 0] <= s_eth_payload_axis_tdata[15: 8]; + m_arp_tha_reg[47:40] <= s_eth_payload_axis_tdata[23:16]; + m_arp_tha_reg[39:32] <= s_eth_payload_axis_tdata[31:24]; + m_arp_tha_reg[31:24] <= s_eth_payload_axis_tdata[39:32]; + m_arp_tha_reg[23:16] <= s_eth_payload_axis_tdata[47:40]; + m_arp_tha_reg[15: 8] <= s_eth_payload_axis_tdata[55:48]; + m_arp_tha_reg[ 7: 0] <= s_eth_payload_axis_tdata[63:56]; end if (store_arp_hdr_word_3) begin - output_arp_tpa_reg[31:24] <= input_eth_payload_tdata[ 7: 0]; - output_arp_tpa_reg[23:16] <= input_eth_payload_tdata[15: 8]; - output_arp_tpa_reg[15: 8] <= input_eth_payload_tdata[23:16]; - output_arp_tpa_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + m_arp_tpa_reg[31:24] <= s_eth_payload_axis_tdata[ 7: 0]; + m_arp_tpa_reg[23:16] <= s_eth_payload_axis_tdata[15: 8]; + m_arp_tpa_reg[15: 8] <= s_eth_payload_axis_tdata[23:16]; + m_arp_tpa_reg[ 7: 0] <= s_eth_payload_axis_tdata[31:24]; end end diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index c3c40b13d..08a909980 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -37,32 +37,32 @@ module arp_eth_tx /* * ARP frame input */ - input wire input_frame_valid, - output wire input_frame_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [15:0] input_arp_htype, - input wire [15:0] input_arp_ptype, - input wire [15:0] input_arp_oper, - input wire [47:0] input_arp_sha, - input wire [31:0] input_arp_spa, - input wire [47:0] input_arp_tha, - input wire [31:0] input_arp_tpa, + input wire s_frame_valid, + output wire s_frame_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [15:0] s_arp_htype, + input wire [15:0] s_arp_ptype, + input wire [15:0] s_arp_oper, + input wire [47:0] s_arp_sha, + input wire [31:0] s_arp_spa, + input wire [47:0] s_arp_tha, + input wire [31:0] s_arp_tpa, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [7:0] m_eth_payload_axis_tdata, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * Status signals @@ -112,61 +112,61 @@ reg [31:0] arp_spa_reg = 32'd0; reg [47:0] arp_tha_reg = 48'd0; reg [31:0] arp_tpa_reg = 32'd0; -reg input_frame_ready_reg = 1'b0, input_frame_ready_next; +reg s_frame_ready_reg = 1'b0, s_frame_ready_next; -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; +reg m_eth_hdr_valid_reg = 1'b0, m_eth_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; reg busy_reg = 1'b0; // internal datapath -reg [7:0] output_eth_payload_tdata_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; +reg [7:0] m_eth_payload_axis_tdata_int; +reg m_eth_payload_axis_tvalid_int; +reg m_eth_payload_axis_tready_int_reg = 1'b0; +reg m_eth_payload_axis_tlast_int; +reg m_eth_payload_axis_tuser_int; +wire m_eth_payload_axis_tready_int_early; -assign input_frame_ready = input_frame_ready_reg; +assign s_frame_ready = s_frame_ready_reg; -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; +assign m_eth_hdr_valid = m_eth_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; assign busy = busy_reg; always @* begin state_next = STATE_IDLE; - input_frame_ready_next = 1'b0; + s_frame_ready_next = 1'b0; store_frame = 1'b0; frame_ptr_next = frame_ptr_reg; - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; - output_eth_payload_tdata_int = 8'd0; - output_eth_payload_tvalid_int = 1'b0; - output_eth_payload_tlast_int = 1'b0; - output_eth_payload_tuser_int = 1'b0; + m_eth_payload_axis_tdata_int = 8'd0; + m_eth_payload_axis_tvalid_int = 1'b0; + m_eth_payload_axis_tlast_int = 1'b0; + m_eth_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; - input_frame_ready_next = ~output_eth_hdr_valid_reg; + s_frame_ready_next = !m_eth_hdr_valid_reg; - if (input_frame_ready & input_frame_valid) begin + if (s_frame_ready && s_frame_valid) begin store_frame = 1'b1; - input_frame_ready_next = 1'b0; - output_eth_hdr_valid_next = 1'b1; - if (output_eth_payload_tready_int_reg) begin - output_eth_payload_tvalid_int = 1'b1; - output_eth_payload_tdata_int = input_arp_htype[15: 8]; + s_frame_ready_next = 1'b0; + m_eth_hdr_valid_next = 1'b1; + if (m_eth_payload_axis_tready_int_reg) begin + m_eth_payload_axis_tvalid_int = 1'b1; + m_eth_payload_axis_tdata_int = s_arp_htype[15: 8]; frame_ptr_next = 8'd1; end state_next = STATE_WRITE_HEADER; @@ -176,42 +176,42 @@ always @* begin end STATE_WRITE_HEADER: begin // read header state - if (output_eth_payload_tready_int_reg) begin + if (m_eth_payload_axis_tready_int_reg) begin // word transfer out frame_ptr_next = frame_ptr_reg + 8'd1; - output_eth_payload_tvalid_int = 1'b1; + m_eth_payload_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) - 8'h01: output_eth_payload_tdata_int = arp_htype_reg[ 7: 0]; - 8'h02: output_eth_payload_tdata_int = arp_ptype_reg[15: 8]; - 8'h03: output_eth_payload_tdata_int = arp_ptype_reg[ 7: 0]; - 8'h04: output_eth_payload_tdata_int = 8'd6; // hlen - 8'h05: output_eth_payload_tdata_int = 8'd4; // plen - 8'h06: output_eth_payload_tdata_int = arp_oper_reg[15: 8]; - 8'h07: output_eth_payload_tdata_int = arp_oper_reg[ 7: 0]; - 8'h08: output_eth_payload_tdata_int = arp_sha_reg[47:40]; - 8'h09: output_eth_payload_tdata_int = arp_sha_reg[39:32]; - 8'h0A: output_eth_payload_tdata_int = arp_sha_reg[31:24]; - 8'h0B: output_eth_payload_tdata_int = arp_sha_reg[23:16]; - 8'h0C: output_eth_payload_tdata_int = arp_sha_reg[15: 8]; - 8'h0D: output_eth_payload_tdata_int = arp_sha_reg[ 7: 0]; - 8'h0E: output_eth_payload_tdata_int = arp_spa_reg[31:24]; - 8'h0F: output_eth_payload_tdata_int = arp_spa_reg[23:16]; - 8'h10: output_eth_payload_tdata_int = arp_spa_reg[15: 8]; - 8'h11: output_eth_payload_tdata_int = arp_spa_reg[ 7: 0]; - 8'h12: output_eth_payload_tdata_int = arp_tha_reg[47:40]; - 8'h13: output_eth_payload_tdata_int = arp_tha_reg[39:32]; - 8'h14: output_eth_payload_tdata_int = arp_tha_reg[31:24]; - 8'h15: output_eth_payload_tdata_int = arp_tha_reg[23:16]; - 8'h16: output_eth_payload_tdata_int = arp_tha_reg[15: 8]; - 8'h17: output_eth_payload_tdata_int = arp_tha_reg[ 7: 0]; - 8'h18: output_eth_payload_tdata_int = arp_tpa_reg[31:24]; - 8'h19: output_eth_payload_tdata_int = arp_tpa_reg[23:16]; - 8'h1A: output_eth_payload_tdata_int = arp_tpa_reg[15: 8]; + 8'h01: m_eth_payload_axis_tdata_int = arp_htype_reg[ 7: 0]; + 8'h02: m_eth_payload_axis_tdata_int = arp_ptype_reg[15: 8]; + 8'h03: m_eth_payload_axis_tdata_int = arp_ptype_reg[ 7: 0]; + 8'h04: m_eth_payload_axis_tdata_int = 8'd6; // hlen + 8'h05: m_eth_payload_axis_tdata_int = 8'd4; // plen + 8'h06: m_eth_payload_axis_tdata_int = arp_oper_reg[15: 8]; + 8'h07: m_eth_payload_axis_tdata_int = arp_oper_reg[ 7: 0]; + 8'h08: m_eth_payload_axis_tdata_int = arp_sha_reg[47:40]; + 8'h09: m_eth_payload_axis_tdata_int = arp_sha_reg[39:32]; + 8'h0A: m_eth_payload_axis_tdata_int = arp_sha_reg[31:24]; + 8'h0B: m_eth_payload_axis_tdata_int = arp_sha_reg[23:16]; + 8'h0C: m_eth_payload_axis_tdata_int = arp_sha_reg[15: 8]; + 8'h0D: m_eth_payload_axis_tdata_int = arp_sha_reg[ 7: 0]; + 8'h0E: m_eth_payload_axis_tdata_int = arp_spa_reg[31:24]; + 8'h0F: m_eth_payload_axis_tdata_int = arp_spa_reg[23:16]; + 8'h10: m_eth_payload_axis_tdata_int = arp_spa_reg[15: 8]; + 8'h11: m_eth_payload_axis_tdata_int = arp_spa_reg[ 7: 0]; + 8'h12: m_eth_payload_axis_tdata_int = arp_tha_reg[47:40]; + 8'h13: m_eth_payload_axis_tdata_int = arp_tha_reg[39:32]; + 8'h14: m_eth_payload_axis_tdata_int = arp_tha_reg[31:24]; + 8'h15: m_eth_payload_axis_tdata_int = arp_tha_reg[23:16]; + 8'h16: m_eth_payload_axis_tdata_int = arp_tha_reg[15: 8]; + 8'h17: m_eth_payload_axis_tdata_int = arp_tha_reg[ 7: 0]; + 8'h18: m_eth_payload_axis_tdata_int = arp_tpa_reg[31:24]; + 8'h19: m_eth_payload_axis_tdata_int = arp_tpa_reg[23:16]; + 8'h1A: m_eth_payload_axis_tdata_int = arp_tpa_reg[15: 8]; 8'h1B: begin - output_eth_payload_tdata_int = arp_tpa_reg[ 7: 0]; - output_eth_payload_tlast_int = 1'b1; - input_frame_ready_next = ~output_eth_hdr_valid_reg; + m_eth_payload_axis_tdata_int = arp_tpa_reg[ 7: 0]; + m_eth_payload_axis_tlast_int = 1'b1; + s_frame_ready_next = !m_eth_hdr_valid_reg; state_next = STATE_IDLE; end endcase @@ -226,113 +226,113 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 8'd0; - input_frame_ready_reg <= 1'b0; - output_eth_hdr_valid_reg <= 1'b0; + s_frame_ready_reg <= 1'b0; + m_eth_hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; end else begin state_reg <= state_next; frame_ptr_reg <= frame_ptr_next; - input_frame_ready_reg <= input_frame_ready_next; + s_frame_ready_reg <= s_frame_ready_next; - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; end if (store_frame) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - arp_htype_reg <= input_arp_htype; - arp_ptype_reg <= input_arp_ptype; - arp_oper_reg <= input_arp_oper; - arp_sha_reg <= input_arp_sha; - arp_spa_reg <= input_arp_spa; - arp_tha_reg <= input_arp_tha; - arp_tpa_reg <= input_arp_tpa; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; + arp_htype_reg <= s_arp_htype; + arp_ptype_reg <= s_arp_ptype; + arp_oper_reg <= s_arp_oper; + arp_sha_reg <= s_arp_sha; + arp_spa_reg <= s_arp_spa; + arp_tha_reg <= s_arp_tha; + arp_tpa_reg <= s_arp_tpa; end end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; +reg [7:0] m_eth_payload_axis_tdata_reg = 8'd0; +reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; +reg m_eth_payload_axis_tlast_reg = 1'b0; +reg m_eth_payload_axis_tuser_reg = 1'b0; -reg [7:0] temp_eth_payload_tdata_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; +reg [7:0] temp_m_eth_payload_axis_tdata_reg = 8'd0; +reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; +reg temp_m_eth_payload_axis_tlast_reg = 1'b0; +reg temp_m_eth_payload_axis_tuser_reg = 1'b0; // datapath control reg store_eth_payload_int_to_output; reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; +reg store_eth_payload_axis_temp_to_output; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; +assign m_eth_payload_axis_tdata = m_eth_payload_axis_tdata_reg; +assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; +assign m_eth_payload_axis_tlast = m_eth_payload_axis_tlast_reg; +assign m_eth_payload_axis_tuser = m_eth_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); +assign m_eth_payload_axis_tready_int_early = m_eth_payload_axis_tready || (!temp_m_eth_payload_axis_tvalid_reg && (!m_eth_payload_axis_tvalid_reg || !m_eth_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; store_eth_payload_int_to_output = 1'b0; store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b0; - if (output_eth_payload_tready_int_reg) begin + if (m_eth_payload_axis_tready_int_reg) begin // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + if (m_eth_payload_axis_tready || !m_eth_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + temp_m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_temp = 1'b1; end - end else if (output_eth_payload_tready) begin + end else if (m_eth_payload_axis_tready) begin // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; + m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; + m_eth_payload_axis_tvalid_reg <= 1'b0; + m_eth_payload_axis_tready_int_reg <= 1'b0; + temp_m_eth_payload_axis_tvalid_reg <= 1'b0; end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + m_eth_payload_axis_tvalid_reg <= m_eth_payload_axis_tvalid_next; + m_eth_payload_axis_tready_int_reg <= m_eth_payload_axis_tready_int_early; + temp_m_eth_payload_axis_tvalid_reg <= temp_m_eth_payload_axis_tvalid_next; end // datapath if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end else if (store_eth_payload_axis_temp_to_output) begin + m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; + m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; + m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; end if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; end end diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index 1b89651c4..b32e46286 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -37,33 +37,33 @@ module arp_eth_tx_64 /* * ARP frame input */ - input wire input_frame_valid, - output wire input_frame_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [15:0] input_arp_htype, - input wire [15:0] input_arp_ptype, - input wire [15:0] input_arp_oper, - input wire [47:0] input_arp_sha, - input wire [31:0] input_arp_spa, - input wire [47:0] input_arp_tha, - input wire [31:0] input_arp_tpa, + input wire s_frame_valid, + output wire s_frame_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [15:0] s_arp_htype, + input wire [15:0] s_arp_ptype, + input wire [15:0] s_arp_oper, + input wire [47:0] s_arp_sha, + input wire [31:0] s_arp_spa, + input wire [47:0] s_arp_tha, + input wire [31:0] s_arp_tpa, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [63:0] m_eth_payload_axis_tdata, + output wire [7:0] m_eth_payload_axis_tkeep, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * Status signals @@ -113,71 +113,71 @@ reg [31:0] arp_spa_reg = 32'd0; reg [47:0] arp_tha_reg = 48'd0; reg [31:0] arp_tpa_reg = 32'd0; -reg input_frame_ready_reg = 1'b0, input_frame_ready_next; +reg s_frame_ready_reg = 1'b0, s_frame_ready_next; -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; +reg m_eth_hdr_valid_reg = 1'b0, m_eth_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; reg busy_reg = 1'b0; // internal datapath -reg [63:0] output_eth_payload_tdata_int; -reg [7:0] output_eth_payload_tkeep_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; +reg [63:0] m_eth_payload_axis_tdata_int; +reg [7:0] m_eth_payload_axis_tkeep_int; +reg m_eth_payload_axis_tvalid_int; +reg m_eth_payload_axis_tready_int_reg = 1'b0; +reg m_eth_payload_axis_tlast_int; +reg m_eth_payload_axis_tuser_int; +wire m_eth_payload_axis_tready_int_early; -assign input_frame_ready = input_frame_ready_reg; +assign s_frame_ready = s_frame_ready_reg; -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; +assign m_eth_hdr_valid = m_eth_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; assign busy = busy_reg; always @* begin state_next = STATE_IDLE; - input_frame_ready_next = 1'b0; + s_frame_ready_next = 1'b0; store_frame = 1'b0; frame_ptr_next = frame_ptr_reg; - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; - output_eth_payload_tdata_int = 64'd0; - output_eth_payload_tkeep_int = 8'd0; - output_eth_payload_tvalid_int = 1'b0; - output_eth_payload_tlast_int = 1'b0; - output_eth_payload_tuser_int = 1'b0; + m_eth_payload_axis_tdata_int = 64'd0; + m_eth_payload_axis_tkeep_int = 8'd0; + m_eth_payload_axis_tvalid_int = 1'b0; + m_eth_payload_axis_tlast_int = 1'b0; + m_eth_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; - input_frame_ready_next = ~output_eth_hdr_valid_reg; + s_frame_ready_next = !m_eth_hdr_valid_reg; - if (input_frame_ready & input_frame_valid) begin + if (s_frame_ready && s_frame_valid) begin store_frame = 1'b1; - input_frame_ready_next = 1'b0; - output_eth_hdr_valid_next = 1'b1; - if (output_eth_payload_tready_int_reg) begin - output_eth_payload_tvalid_int = 1'b1; - output_eth_payload_tdata_int[ 7: 0] = input_arp_htype[15: 8]; - output_eth_payload_tdata_int[15: 8] = input_arp_htype[ 7: 0]; - output_eth_payload_tdata_int[23:16] = input_arp_ptype[15: 8]; - output_eth_payload_tdata_int[31:24] = input_arp_ptype[ 7: 0]; - output_eth_payload_tdata_int[39:32] = 8'd6; // hlen - output_eth_payload_tdata_int[47:40] = 8'd4; // plen - output_eth_payload_tdata_int[55:48] = input_arp_oper[15: 8]; - output_eth_payload_tdata_int[63:56] = input_arp_oper[ 7: 0]; - output_eth_payload_tkeep_int = 8'hff; + s_frame_ready_next = 1'b0; + m_eth_hdr_valid_next = 1'b1; + if (m_eth_payload_axis_tready_int_reg) begin + m_eth_payload_axis_tvalid_int = 1'b1; + m_eth_payload_axis_tdata_int[ 7: 0] = s_arp_htype[15: 8]; + m_eth_payload_axis_tdata_int[15: 8] = s_arp_htype[ 7: 0]; + m_eth_payload_axis_tdata_int[23:16] = s_arp_ptype[15: 8]; + m_eth_payload_axis_tdata_int[31:24] = s_arp_ptype[ 7: 0]; + m_eth_payload_axis_tdata_int[39:32] = 8'd6; // hlen + m_eth_payload_axis_tdata_int[47:40] = 8'd4; // plen + m_eth_payload_axis_tdata_int[55:48] = s_arp_oper[15: 8]; + m_eth_payload_axis_tdata_int[63:56] = s_arp_oper[ 7: 0]; + m_eth_payload_axis_tkeep_int = 8'hff; frame_ptr_next = 8'd8; end state_next = STATE_WRITE_HEADER; @@ -187,57 +187,57 @@ always @* begin end STATE_WRITE_HEADER: begin // read header state - if (output_eth_payload_tready_int_reg) begin + if (m_eth_payload_axis_tready_int_reg) begin // word transfer out frame_ptr_next = frame_ptr_reg + 8'd8; - output_eth_payload_tvalid_int = 1'b1; + m_eth_payload_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: begin - output_eth_payload_tdata_int[ 7: 0] = input_arp_htype[15: 8]; - output_eth_payload_tdata_int[15: 8] = input_arp_htype[ 7: 0]; - output_eth_payload_tdata_int[23:16] = input_arp_ptype[15: 8]; - output_eth_payload_tdata_int[31:24] = input_arp_ptype[ 7: 0]; - output_eth_payload_tdata_int[39:32] = 8'd6; // hlen - output_eth_payload_tdata_int[47:40] = 8'd4; // plen - output_eth_payload_tdata_int[55:48] = input_arp_oper[15: 8]; - output_eth_payload_tdata_int[63:56] = input_arp_oper[ 7: 0]; - output_eth_payload_tkeep_int = 8'hff; + m_eth_payload_axis_tdata_int[ 7: 0] = s_arp_htype[15: 8]; + m_eth_payload_axis_tdata_int[15: 8] = s_arp_htype[ 7: 0]; + m_eth_payload_axis_tdata_int[23:16] = s_arp_ptype[15: 8]; + m_eth_payload_axis_tdata_int[31:24] = s_arp_ptype[ 7: 0]; + m_eth_payload_axis_tdata_int[39:32] = 8'd6; // hlen + m_eth_payload_axis_tdata_int[47:40] = 8'd4; // plen + m_eth_payload_axis_tdata_int[55:48] = s_arp_oper[15: 8]; + m_eth_payload_axis_tdata_int[63:56] = s_arp_oper[ 7: 0]; + m_eth_payload_axis_tkeep_int = 8'hff; end 8'h08: begin - output_eth_payload_tdata_int[ 7: 0] = arp_sha_reg[47:40]; - output_eth_payload_tdata_int[15: 8] = arp_sha_reg[39:32]; - output_eth_payload_tdata_int[23:16] = arp_sha_reg[31:24]; - output_eth_payload_tdata_int[31:24] = arp_sha_reg[23:16]; - output_eth_payload_tdata_int[39:32] = arp_sha_reg[15: 8]; - output_eth_payload_tdata_int[47:40] = arp_sha_reg[ 7: 0]; - output_eth_payload_tdata_int[55:48] = arp_spa_reg[31:24]; - output_eth_payload_tdata_int[63:56] = arp_spa_reg[23:16]; - output_eth_payload_tkeep_int = 8'hff; + m_eth_payload_axis_tdata_int[ 7: 0] = arp_sha_reg[47:40]; + m_eth_payload_axis_tdata_int[15: 8] = arp_sha_reg[39:32]; + m_eth_payload_axis_tdata_int[23:16] = arp_sha_reg[31:24]; + m_eth_payload_axis_tdata_int[31:24] = arp_sha_reg[23:16]; + m_eth_payload_axis_tdata_int[39:32] = arp_sha_reg[15: 8]; + m_eth_payload_axis_tdata_int[47:40] = arp_sha_reg[ 7: 0]; + m_eth_payload_axis_tdata_int[55:48] = arp_spa_reg[31:24]; + m_eth_payload_axis_tdata_int[63:56] = arp_spa_reg[23:16]; + m_eth_payload_axis_tkeep_int = 8'hff; end 8'h10: begin - output_eth_payload_tdata_int[ 7: 0] = arp_spa_reg[15: 8]; - output_eth_payload_tdata_int[15: 8] = arp_spa_reg[ 7: 0]; - output_eth_payload_tdata_int[23:16] = arp_tha_reg[47:40]; - output_eth_payload_tdata_int[31:24] = arp_tha_reg[39:32]; - output_eth_payload_tdata_int[39:32] = arp_tha_reg[31:24]; - output_eth_payload_tdata_int[47:40] = arp_tha_reg[23:16]; - output_eth_payload_tdata_int[55:48] = arp_tha_reg[15: 8]; - output_eth_payload_tdata_int[63:56] = arp_tha_reg[ 7: 0]; - output_eth_payload_tkeep_int = 8'hff; + m_eth_payload_axis_tdata_int[ 7: 0] = arp_spa_reg[15: 8]; + m_eth_payload_axis_tdata_int[15: 8] = arp_spa_reg[ 7: 0]; + m_eth_payload_axis_tdata_int[23:16] = arp_tha_reg[47:40]; + m_eth_payload_axis_tdata_int[31:24] = arp_tha_reg[39:32]; + m_eth_payload_axis_tdata_int[39:32] = arp_tha_reg[31:24]; + m_eth_payload_axis_tdata_int[47:40] = arp_tha_reg[23:16]; + m_eth_payload_axis_tdata_int[55:48] = arp_tha_reg[15: 8]; + m_eth_payload_axis_tdata_int[63:56] = arp_tha_reg[ 7: 0]; + m_eth_payload_axis_tkeep_int = 8'hff; end 8'h18: begin - output_eth_payload_tdata_int[ 7: 0] = arp_tpa_reg[31:24]; - output_eth_payload_tdata_int[15: 8] = arp_tpa_reg[23:16]; - output_eth_payload_tdata_int[23:16] = arp_tpa_reg[15: 8]; - output_eth_payload_tdata_int[31:24] = arp_tpa_reg[ 7: 0]; - output_eth_payload_tdata_int[39:32] = 0; - output_eth_payload_tdata_int[47:40] = 0; - output_eth_payload_tdata_int[55:48] = 0; - output_eth_payload_tdata_int[63:56] = 0; - output_eth_payload_tkeep_int = 8'h0f; - output_eth_payload_tlast_int = 1'b1; - input_frame_ready_next = ~output_eth_hdr_valid_reg; + m_eth_payload_axis_tdata_int[ 7: 0] = arp_tpa_reg[31:24]; + m_eth_payload_axis_tdata_int[15: 8] = arp_tpa_reg[23:16]; + m_eth_payload_axis_tdata_int[23:16] = arp_tpa_reg[15: 8]; + m_eth_payload_axis_tdata_int[31:24] = arp_tpa_reg[ 7: 0]; + m_eth_payload_axis_tdata_int[39:32] = 0; + m_eth_payload_axis_tdata_int[47:40] = 0; + m_eth_payload_axis_tdata_int[55:48] = 0; + m_eth_payload_axis_tdata_int[63:56] = 0; + m_eth_payload_axis_tkeep_int = 8'h0f; + m_eth_payload_axis_tlast_int = 1'b1; + s_frame_ready_next = !m_eth_hdr_valid_reg; state_next = STATE_IDLE; end endcase @@ -252,119 +252,119 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 8'd0; - input_frame_ready_reg <= 1'b0; - output_eth_hdr_valid_reg <= 1'b0; + s_frame_ready_reg <= 1'b0; + m_eth_hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; end else begin state_reg <= state_next; frame_ptr_reg <= frame_ptr_next; - input_frame_ready_reg <= input_frame_ready_next; + s_frame_ready_reg <= s_frame_ready_next; - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; end if (store_frame) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - arp_htype_reg <= input_arp_htype; - arp_ptype_reg <= input_arp_ptype; - arp_oper_reg <= input_arp_oper; - arp_sha_reg <= input_arp_sha; - arp_spa_reg <= input_arp_spa; - arp_tha_reg <= input_arp_tha; - arp_tpa_reg <= input_arp_tpa; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; + arp_htype_reg <= s_arp_htype; + arp_ptype_reg <= s_arp_ptype; + arp_oper_reg <= s_arp_oper; + arp_sha_reg <= s_arp_sha; + arp_spa_reg <= s_arp_spa; + arp_tha_reg <= s_arp_tha; + arp_tpa_reg <= s_arp_tpa; end end // output datapath logic -reg [64:0] output_eth_payload_tdata_reg = 64'd0; -reg [7:0] output_eth_payload_tkeep_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; +reg [64:0] m_eth_payload_axis_tdata_reg = 64'd0; +reg [7:0] m_eth_payload_axis_tkeep_reg = 8'd0; +reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; +reg m_eth_payload_axis_tlast_reg = 1'b0; +reg m_eth_payload_axis_tuser_reg = 1'b0; -reg [64:0] temp_eth_payload_tdata_reg = 64'd0; -reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; +reg [64:0] temp_m_eth_payload_axis_tdata_reg = 64'd0; +reg [7:0] temp_m_eth_payload_axis_tkeep_reg = 8'd0; +reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; +reg temp_m_eth_payload_axis_tlast_reg = 1'b0; +reg temp_m_eth_payload_axis_tuser_reg = 1'b0; // datapath control reg store_eth_payload_int_to_output; reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; +reg store_eth_payload_axis_temp_to_output; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; +assign m_eth_payload_axis_tdata = m_eth_payload_axis_tdata_reg; +assign m_eth_payload_axis_tkeep = m_eth_payload_axis_tkeep_reg; +assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; +assign m_eth_payload_axis_tlast = m_eth_payload_axis_tlast_reg; +assign m_eth_payload_axis_tuser = m_eth_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); +assign m_eth_payload_axis_tready_int_early = m_eth_payload_axis_tready || (!temp_m_eth_payload_axis_tvalid_reg && (!m_eth_payload_axis_tvalid_reg || !m_eth_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; store_eth_payload_int_to_output = 1'b0; store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b0; - if (output_eth_payload_tready_int_reg) begin + if (m_eth_payload_axis_tready_int_reg) begin // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + if (m_eth_payload_axis_tready || !m_eth_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + temp_m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_temp = 1'b1; end - end else if (output_eth_payload_tready) begin + end else if (m_eth_payload_axis_tready) begin // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; + m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; + m_eth_payload_axis_tvalid_reg <= 1'b0; + m_eth_payload_axis_tready_int_reg <= 1'b0; + temp_m_eth_payload_axis_tvalid_reg <= 1'b0; end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + m_eth_payload_axis_tvalid_reg <= m_eth_payload_axis_tvalid_next; + m_eth_payload_axis_tready_int_reg <= m_eth_payload_axis_tready_int_early; + temp_m_eth_payload_axis_tvalid_reg <= temp_m_eth_payload_axis_tvalid_next; end // datapath if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end else if (store_eth_payload_axis_temp_to_output) begin + m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; + m_eth_payload_axis_tkeep_reg <= temp_m_eth_payload_axis_tkeep_reg; + m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; + m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; end if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + temp_m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; end end diff --git a/rtl/axis_eth_fcs.v b/rtl/axis_eth_fcs.v index b9bb8172f..16e6a193f 100644 --- a/rtl/axis_eth_fcs.v +++ b/rtl/axis_eth_fcs.v @@ -37,11 +37,11 @@ module axis_eth_fcs /* * AXI input */ - input wire [7:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [7:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * FCS output @@ -56,7 +56,7 @@ reg fcs_valid_reg = 1'b0; wire [31:0] crc_next; -assign input_axis_tready = 1; +assign s_axis_tready = 1; assign output_fcs = fcs_reg; assign output_fcs_valid = fcs_valid_reg; @@ -70,7 +70,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(input_axis_tdata), + .data_in(s_axis_tdata), .state_in(crc_state), .data_out(), .state_out(crc_next) @@ -83,8 +83,8 @@ always @(posedge clk) begin fcs_valid_reg <= 1'b0; end else begin fcs_valid_reg <= 1'b0; - if (input_axis_tvalid) begin - if (input_axis_tlast) begin + if (s_axis_tvalid) begin + if (s_axis_tlast) begin crc_state <= 32'hFFFFFFFF; fcs_reg <= ~crc_next; fcs_valid_reg <= 1'b1; diff --git a/rtl/axis_eth_fcs_64.v b/rtl/axis_eth_fcs_64.v index dfc489645..e2fa4e371 100644 --- a/rtl/axis_eth_fcs_64.v +++ b/rtl/axis_eth_fcs_64.v @@ -37,12 +37,12 @@ module axis_eth_fcs_64 /* * AXI input */ - input wire [63:0] input_axis_tdata, - input wire [7:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [63:0] s_axis_tdata, + input wire [7:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * FCS output @@ -64,7 +64,7 @@ wire [31:0] crc_next5; wire [31:0] crc_next6; wire [31:0] crc_next7; -assign input_axis_tready = 1'b1; +assign s_axis_tready = 1'b1; assign output_fcs = fcs_reg; assign output_fcs_valid = fcs_valid_reg; @@ -78,7 +78,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(input_axis_tdata[7:0]), + .data_in(s_axis_tdata[7:0]), .state_in(crc_state), .data_out(), .state_out(crc_next0) @@ -94,7 +94,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_16 ( - .data_in(input_axis_tdata[15:0]), + .data_in(s_axis_tdata[15:0]), .state_in(crc_state), .data_out(), .state_out(crc_next1) @@ -110,7 +110,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_24 ( - .data_in(input_axis_tdata[23:0]), + .data_in(s_axis_tdata[23:0]), .state_in(crc_state), .data_out(), .state_out(crc_next2) @@ -126,7 +126,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_32 ( - .data_in(input_axis_tdata[31:0]), + .data_in(s_axis_tdata[31:0]), .state_in(crc_state), .data_out(), .state_out(crc_next3) @@ -142,7 +142,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_40 ( - .data_in(input_axis_tdata[39:0]), + .data_in(s_axis_tdata[39:0]), .state_in(crc_state), .data_out(), .state_out(crc_next4) @@ -158,7 +158,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_48 ( - .data_in(input_axis_tdata[47:0]), + .data_in(s_axis_tdata[47:0]), .state_in(crc_state), .data_out(), .state_out(crc_next5) @@ -174,7 +174,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_56 ( - .data_in(input_axis_tdata[55:0]), + .data_in(s_axis_tdata[55:0]), .state_in(crc_state), .data_out(), .state_out(crc_next6) @@ -190,7 +190,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_64 ( - .data_in(input_axis_tdata[63:0]), + .data_in(s_axis_tdata[63:0]), .state_in(crc_state), .data_out(), .state_out(crc_next7) @@ -203,10 +203,10 @@ always @(posedge clk) begin fcs_valid_reg <= 1'b0; end else begin fcs_valid_reg <= 1'b0; - if (input_axis_tvalid) begin - if (input_axis_tlast) begin + if (s_axis_tvalid) begin + if (s_axis_tlast) begin crc_state <= 32'hFFFFFFFF; - case (input_axis_tkeep) + case (s_axis_tkeep) 8'b00000001: fcs_reg <= ~crc_next0; 8'b00000011: fcs_reg <= ~crc_next1; 8'b00000111: fcs_reg <= ~crc_next2; diff --git a/rtl/axis_eth_fcs_check.v b/rtl/axis_eth_fcs_check.v index c7b18a137..00625238e 100644 --- a/rtl/axis_eth_fcs_check.v +++ b/rtl/axis_eth_fcs_check.v @@ -37,20 +37,20 @@ module axis_eth_fcs_check /* * AXI input */ - input wire [7:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [7:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * AXI output */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [7:0] m_axis_tdata, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Status @@ -71,33 +71,33 @@ reg update_crc; reg shift_in; reg shift_reset; -reg [7:0] input_axis_tdata_d0 = 8'd0; -reg [7:0] input_axis_tdata_d1 = 8'd0; -reg [7:0] input_axis_tdata_d2 = 8'd0; -reg [7:0] input_axis_tdata_d3 = 8'd0; +reg [7:0] s_axis_tdata_d0 = 8'd0; +reg [7:0] s_axis_tdata_d1 = 8'd0; +reg [7:0] s_axis_tdata_d2 = 8'd0; +reg [7:0] s_axis_tdata_d3 = 8'd0; -reg input_axis_tvalid_d0 = 1'b0; -reg input_axis_tvalid_d1 = 1'b0; -reg input_axis_tvalid_d2 = 1'b0; -reg input_axis_tvalid_d3 = 1'b0; +reg s_axis_tvalid_d0 = 1'b0; +reg s_axis_tvalid_d1 = 1'b0; +reg s_axis_tvalid_d2 = 1'b0; +reg s_axis_tvalid_d3 = 1'b0; reg busy_reg = 1'b0; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; // internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [7:0] m_axis_tdata_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; assign busy = busy_reg; assign error_bad_fcs = error_bad_fcs_reg; @@ -112,7 +112,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(input_axis_tdata_d3), + .data_in(s_axis_tdata_d3), .state_in(crc_state), .data_out(), .state_out(crc_next) @@ -126,42 +126,42 @@ always @* begin shift_in = 1'b0; shift_reset = 1'b0; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - output_axis_tdata_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 8'd0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; error_bad_fcs_next = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; reset_crc = 1'b1; - output_axis_tdata_int = input_axis_tdata_d3; - output_axis_tvalid_int = input_axis_tvalid_d3 & input_axis_tvalid; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = s_axis_tdata_d3; + m_axis_tvalid_int = s_axis_tvalid_d3 && s_axis_tvalid; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin shift_in = 1'b1; - if (input_axis_tvalid_d3) begin + if (s_axis_tvalid_d3) begin reset_crc = 1'b0; update_crc = 1'b1; - if (input_axis_tlast) begin + if (s_axis_tlast) begin shift_reset = 1'b1; reset_crc = 1'b1; - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = input_axis_tuser; - if ({input_axis_tdata, input_axis_tdata_d0, input_axis_tdata_d1, input_axis_tdata_d2} != ~crc_next) begin - output_axis_tuser_int = 1'b1; + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = s_axis_tuser; + if ({s_axis_tdata, s_axis_tdata_d0, s_axis_tdata_d1, s_axis_tdata_d2} != ~crc_next) begin + m_axis_tuser_int = 1'b1; error_bad_fcs_next = 1'b1; end - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; state_next = STATE_IDLE; end else begin state_next = STATE_PAYLOAD; @@ -175,26 +175,26 @@ always @* begin end STATE_PAYLOAD: begin // transfer payload - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; - output_axis_tdata_int = input_axis_tdata_d3; - output_axis_tvalid_int = input_axis_tvalid_d3 & input_axis_tvalid; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = s_axis_tdata_d3; + m_axis_tvalid_int = s_axis_tvalid_d3 && s_axis_tvalid; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin shift_in = 1'b1; update_crc = 1'b1; - if (input_axis_tlast) begin + if (s_axis_tlast) begin shift_reset = 1'b1; reset_crc = 1'b1; - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = input_axis_tuser; - if ({input_axis_tdata, input_axis_tdata_d0, input_axis_tdata_d1, input_axis_tdata_d2} != ~crc_next) begin - output_axis_tuser_int = 1'b1; + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = s_axis_tuser; + if ({s_axis_tdata, s_axis_tdata_d0, s_axis_tdata_d1, s_axis_tdata_d2} != ~crc_next) begin + m_axis_tuser_int = 1'b1; error_bad_fcs_next = 1'b1; end - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; state_next = STATE_IDLE; end else begin state_next = STATE_PAYLOAD; @@ -210,21 +210,21 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; busy_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; - input_axis_tvalid_d0 <= 1'b0; - input_axis_tvalid_d1 <= 1'b0; - input_axis_tvalid_d2 <= 1'b0; - input_axis_tvalid_d3 <= 1'b0; + s_axis_tvalid_d0 <= 1'b0; + s_axis_tvalid_d1 <= 1'b0; + s_axis_tvalid_d2 <= 1'b0; + s_axis_tvalid_d3 <= 1'b0; crc_state <= 32'hFFFFFFFF; end else begin state_reg <= state_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; busy_reg <= state_next != STATE_IDLE; error_bad_fcs_reg <= error_bad_fcs_next; @@ -237,104 +237,104 @@ always @(posedge clk) begin end if (shift_reset) begin - input_axis_tvalid_d0 <= 1'b0; - input_axis_tvalid_d1 <= 1'b0; - input_axis_tvalid_d2 <= 1'b0; - input_axis_tvalid_d3 <= 1'b0; + s_axis_tvalid_d0 <= 1'b0; + s_axis_tvalid_d1 <= 1'b0; + s_axis_tvalid_d2 <= 1'b0; + s_axis_tvalid_d3 <= 1'b0; end else if (shift_in) begin - input_axis_tvalid_d0 <= input_axis_tvalid; - input_axis_tvalid_d1 <= input_axis_tvalid_d0; - input_axis_tvalid_d2 <= input_axis_tvalid_d1; - input_axis_tvalid_d3 <= input_axis_tvalid_d2; + s_axis_tvalid_d0 <= s_axis_tvalid; + s_axis_tvalid_d1 <= s_axis_tvalid_d0; + s_axis_tvalid_d2 <= s_axis_tvalid_d1; + s_axis_tvalid_d3 <= s_axis_tvalid_d2; end end if (shift_in) begin - input_axis_tdata_d0 <= input_axis_tdata; - input_axis_tdata_d1 <= input_axis_tdata_d0; - input_axis_tdata_d2 <= input_axis_tdata_d1; - input_axis_tdata_d3 <= input_axis_tdata_d2; + s_axis_tdata_d0 <= s_axis_tdata; + s_axis_tdata_d1 <= s_axis_tdata_d0; + s_axis_tdata_d2 <= s_axis_tdata_d1; + s_axis_tdata_d3 <= s_axis_tdata_d2; end end // output datapath logic -reg [7:0] output_axis_tdata_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg [7:0] m_axis_tdata_reg = 8'd0; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg [7:0] temp_m_axis_tdata_reg = 8'd0; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/rtl/axis_eth_fcs_check_64.v b/rtl/axis_eth_fcs_check_64.v index fb8104b1a..1fd172066 100644 --- a/rtl/axis_eth_fcs_check_64.v +++ b/rtl/axis_eth_fcs_check_64.v @@ -37,22 +37,22 @@ module axis_eth_fcs_check_64 /* * AXI input */ - input wire [63:0] input_axis_tdata, - input wire [7:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [63:0] s_axis_tdata, + input wire [7:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * AXI output */ - output wire [63:0] output_axis_tdata, - output wire [7:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [63:0] m_axis_tdata, + output wire [7:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Status @@ -77,15 +77,15 @@ reg shift_reset; reg [7:0] last_cycle_tkeep_reg = 8'd0, last_cycle_tkeep_next; reg last_cycle_tuser_reg = 1'b0, last_cycle_tuser_next; -reg [63:0] input_axis_tdata_d0 = 64'd0; -reg [7:0] input_axis_tkeep_d0 = 8'd0; -reg input_axis_tvalid_d0 = 1'b0; -reg input_axis_tuser_d0 = 1'b0; +reg [63:0] s_axis_tdata_d0 = 64'd0; +reg [7:0] s_axis_tkeep_d0 = 8'd0; +reg s_axis_tvalid_d0 = 1'b0; +reg s_axis_tuser_d0 = 1'b0; reg busy_reg = 1'b0; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state3 = 32'hFFFFFFFF; @@ -102,15 +102,15 @@ wire crc_valid2 = crc_next2 == ~32'h2144df1c; wire crc_valid3 = crc_next3 == ~32'h2144df1c; // internal datapath -reg [63:0] output_axis_tdata_int; -reg [7:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [63:0] m_axis_tdata_int; +reg [7:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; assign busy = busy_reg; assign error_bad_fcs = error_bad_fcs_reg; @@ -127,7 +127,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(last_cycle ? input_axis_tdata_d0[39:32] : input_axis_tdata[7:0]), + .data_in(last_cycle ? s_axis_tdata_d0[39:32] : s_axis_tdata[7:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next0) @@ -143,7 +143,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_16 ( - .data_in(last_cycle ? input_axis_tdata_d0[47:32] : input_axis_tdata[15:0]), + .data_in(last_cycle ? s_axis_tdata_d0[47:32] : s_axis_tdata[15:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next1) @@ -159,7 +159,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_24 ( - .data_in(last_cycle ? input_axis_tdata_d0[55:32] : input_axis_tdata[23:0]), + .data_in(last_cycle ? s_axis_tdata_d0[55:32] : s_axis_tdata[23:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next2) @@ -175,7 +175,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_32 ( - .data_in(last_cycle ? input_axis_tdata_d0[63:32] : input_axis_tdata[31:0]), + .data_in(last_cycle ? s_axis_tdata_d0[63:32] : s_axis_tdata[31:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next3) @@ -191,7 +191,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_64 ( - .data_in(input_axis_tdata[63:0]), + .data_in(s_axis_tdata[63:0]), .state_in(crc_state), .data_out(), .state_out(crc_next7) @@ -208,54 +208,54 @@ always @* begin last_cycle_tkeep_next = last_cycle_tkeep_reg; last_cycle_tuser_next = last_cycle_tuser_reg; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - output_axis_tdata_int = 64'd0; - output_axis_tkeep_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 64'd0; + m_axis_tkeep_int = 8'd0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; error_bad_fcs_next = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; reset_crc = 1'b1; - output_axis_tdata_int = input_axis_tdata_d0; - output_axis_tkeep_int = input_axis_tkeep_d0; - output_axis_tvalid_int = input_axis_tvalid_d0 & input_axis_tvalid; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = s_axis_tdata_d0; + m_axis_tkeep_int = s_axis_tkeep_d0; + m_axis_tvalid_int = s_axis_tvalid_d0 && s_axis_tvalid; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin shift_in = 1'b1; reset_crc = 1'b0; update_crc = 1'b1; - if (input_axis_tlast) begin - if (input_axis_tkeep[7:4] == 0) begin + if (s_axis_tlast) begin + if (s_axis_tkeep[7:4] == 0) begin shift_reset = 1'b1; reset_crc = 1'b1; - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = input_axis_tuser; - output_axis_tkeep_int = {input_axis_tkeep[3:0], 4'b1111}; - if ((input_axis_tkeep[3:0] == 4'b0001 & crc_valid0) || - (input_axis_tkeep[3:0] == 4'b0011 & crc_valid1) || - (input_axis_tkeep[3:0] == 4'b0111 & crc_valid2) || - (input_axis_tkeep[3:0] == 4'b1111 & crc_valid3)) begin + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = s_axis_tuser; + m_axis_tkeep_int = {s_axis_tkeep[3:0], 4'b1111}; + if ((s_axis_tkeep[3:0] == 4'b0001 && crc_valid0) || + (s_axis_tkeep[3:0] == 4'b0011 && crc_valid1) || + (s_axis_tkeep[3:0] == 4'b0111 && crc_valid2) || + (s_axis_tkeep[3:0] == 4'b1111 && crc_valid3)) begin // CRC valid end else begin - output_axis_tuser_int = 1'b1; + m_axis_tuser_int = 1'b1; error_bad_fcs_next = 1'b1; end - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; state_next = STATE_IDLE; end else begin - last_cycle_tkeep_next = {4'b0000, input_axis_tkeep[7:4]}; - last_cycle_tuser_next = input_axis_tuser; - input_axis_tready_next = 1'b0; + last_cycle_tkeep_next = {4'b0000, s_axis_tkeep[7:4]}; + last_cycle_tuser_next = s_axis_tuser; + s_axis_tready_next = 1'b0; state_next = STATE_LAST; end end else begin @@ -267,39 +267,39 @@ always @* begin end STATE_PAYLOAD: begin // transfer payload - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; - output_axis_tdata_int = input_axis_tdata_d0; - output_axis_tkeep_int = input_axis_tkeep_d0; - output_axis_tvalid_int = input_axis_tvalid_d0 & input_axis_tvalid; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = s_axis_tdata_d0; + m_axis_tkeep_int = s_axis_tkeep_d0; + m_axis_tvalid_int = s_axis_tvalid_d0 && s_axis_tvalid; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin shift_in = 1'b1; update_crc = 1'b1; - if (input_axis_tlast) begin - if (input_axis_tkeep[7:4] == 0) begin + if (s_axis_tlast) begin + if (s_axis_tkeep[7:4] == 0) begin shift_reset = 1'b1; reset_crc = 1'b1; - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = input_axis_tuser; - output_axis_tkeep_int = {input_axis_tkeep[3:0], 4'b1111}; - if ((input_axis_tkeep[3:0] == 4'b0001 & crc_valid0) || - (input_axis_tkeep[3:0] == 4'b0011 & crc_valid1) || - (input_axis_tkeep[3:0] == 4'b0111 & crc_valid2) || - (input_axis_tkeep[3:0] == 4'b1111 & crc_valid3)) begin + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = s_axis_tuser; + m_axis_tkeep_int = {s_axis_tkeep[3:0], 4'b1111}; + if ((s_axis_tkeep[3:0] == 4'b0001 && crc_valid0) || + (s_axis_tkeep[3:0] == 4'b0011 && crc_valid1) || + (s_axis_tkeep[3:0] == 4'b0111 && crc_valid2) || + (s_axis_tkeep[3:0] == 4'b1111 && crc_valid3)) begin // CRC valid end else begin - output_axis_tuser_int = 1'b1; + m_axis_tuser_int = 1'b1; error_bad_fcs_next = 1'b1; end - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; state_next = STATE_IDLE; end else begin - last_cycle_tkeep_next = {4'b0000, input_axis_tkeep[7:4]}; - last_cycle_tuser_next = input_axis_tuser; - input_axis_tready_next = 1'b0; + last_cycle_tkeep_next = {4'b0000, s_axis_tkeep[7:4]}; + last_cycle_tuser_next = s_axis_tuser; + s_axis_tready_next = 1'b0; state_next = STATE_LAST; end end else begin @@ -311,28 +311,28 @@ always @* begin end STATE_LAST: begin // last cycle - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - output_axis_tdata_int = input_axis_tdata_d0; - output_axis_tkeep_int = last_cycle_tkeep_reg; - output_axis_tvalid_int = input_axis_tvalid_d0; - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = last_cycle_tuser_reg; + m_axis_tdata_int = s_axis_tdata_d0; + m_axis_tkeep_int = last_cycle_tkeep_reg; + m_axis_tvalid_int = s_axis_tvalid_d0; + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = last_cycle_tuser_reg; - if ((input_axis_tkeep_d0[7:4] == 4'b0001 & crc_valid0) || - (input_axis_tkeep_d0[7:4] == 4'b0011 & crc_valid1) || - (input_axis_tkeep_d0[7:4] == 4'b0111 & crc_valid2) || - (input_axis_tkeep_d0[7:4] == 4'b1111 & crc_valid3)) begin + if ((s_axis_tkeep_d0[7:4] == 4'b0001 && crc_valid0) || + (s_axis_tkeep_d0[7:4] == 4'b0011 && crc_valid1) || + (s_axis_tkeep_d0[7:4] == 4'b0111 && crc_valid2) || + (s_axis_tkeep_d0[7:4] == 4'b1111 && crc_valid3)) begin // CRC valid end else begin - output_axis_tuser_int = 1'b1; + m_axis_tuser_int = 1'b1; error_bad_fcs_next = 1'b1; end - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin shift_reset = 1'b1; reset_crc = 1'b1; - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; state_next = STATE_IDLE; end else begin state_next = STATE_LAST; @@ -345,19 +345,19 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; busy_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; - input_axis_tvalid_d0 <= 1'b0; + s_axis_tvalid_d0 <= 1'b0; crc_state <= 32'hFFFFFFFF; crc_state3 <= 32'hFFFFFFFF; end else begin state_reg <= state_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; busy_reg <= state_next != STATE_IDLE; error_bad_fcs_reg <= error_bad_fcs_next; @@ -372,9 +372,9 @@ always @(posedge clk) begin end if (shift_reset) begin - input_axis_tvalid_d0 <= 1'b0; + s_axis_tvalid_d0 <= 1'b0; end else if (shift_in) begin - input_axis_tvalid_d0 <= input_axis_tvalid; + s_axis_tvalid_d0 <= s_axis_tvalid; end end @@ -382,96 +382,96 @@ always @(posedge clk) begin last_cycle_tuser_reg <= last_cycle_tuser_next; if (shift_in) begin - input_axis_tdata_d0 <= input_axis_tdata; - input_axis_tkeep_d0 <= input_axis_tkeep; - input_axis_tuser_d0 <= input_axis_tuser; + s_axis_tdata_d0 <= s_axis_tdata; + s_axis_tkeep_d0 <= s_axis_tkeep; + s_axis_tuser_d0 <= s_axis_tuser; end end // output datapath logic -reg [63:0] output_axis_tdata_reg = 64'd0; -reg [7:0] output_axis_tkeep_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg [63:0] m_axis_tdata_reg = 64'd0; +reg [7:0] m_axis_tkeep_reg = 8'd0; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; -reg [63:0] temp_axis_tdata_reg = 64'd0; -reg [7:0] temp_axis_tkeep_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg [63:0] temp_m_axis_tdata_reg = 64'd0; +reg [7:0] temp_m_axis_tkeep_reg = 8'd0; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = m_axis_tkeep_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/rtl/axis_eth_fcs_insert.v b/rtl/axis_eth_fcs_insert.v index ab5083d0b..a73baab0b 100644 --- a/rtl/axis_eth_fcs_insert.v +++ b/rtl/axis_eth_fcs_insert.v @@ -41,20 +41,20 @@ module axis_eth_fcs_insert # /* * AXI input */ - input wire [7:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [7:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * AXI output */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [7:0] m_axis_tdata, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Status @@ -78,20 +78,20 @@ reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; reg busy_reg = 1'b0; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; // internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [7:0] m_axis_tdata_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; assign busy = busy_reg; @@ -105,7 +105,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(output_axis_tdata_int), + .data_in(m_axis_tdata_int), .state_in(crc_state), .data_out(), .state_out(crc_next) @@ -119,38 +119,38 @@ always @* begin frame_ptr_next = frame_ptr_reg; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - output_axis_tdata_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 8'd0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; frame_ptr_next = 16'd0; reset_crc = 1'b1; - output_axis_tdata_int = input_axis_tdata; - output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = s_axis_tdata; + m_axis_tvalid_int = s_axis_tvalid; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin frame_ptr_next = 16'd1; reset_crc = 1'b0; update_crc = 1'b1; - if (input_axis_tlast) begin - if (input_axis_tuser) begin - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = 1'b1; + if (s_axis_tlast) begin + if (s_axis_tuser) begin + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = 1'b1; reset_crc = 1'b1; frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin state_next = STATE_PAD; end else begin @@ -167,25 +167,25 @@ always @* begin end STATE_PAYLOAD: begin // transfer payload - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; - output_axis_tdata_int = input_axis_tdata; - output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = s_axis_tdata; + m_axis_tvalid_int = s_axis_tvalid; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin frame_ptr_next = frame_ptr_reg + 16'd1; update_crc = 1'b1; - if (input_axis_tlast) begin - if (input_axis_tuser) begin - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = 1'b1; + if (s_axis_tlast) begin + if (s_axis_tuser) begin + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = 1'b1; reset_crc = 1'b1; frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin state_next = STATE_PAD; end else begin @@ -202,14 +202,14 @@ always @* begin end STATE_PAD: begin // insert padding - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - output_axis_tdata_int = 8'd0; - output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 8'd0; + m_axis_tvalid_int = 1'b1; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin frame_ptr_next = frame_ptr_reg + 16'd1; update_crc = 1'b1; if (frame_ptr_reg < MIN_FRAME_LENGTH-5) begin @@ -224,19 +224,19 @@ always @* begin end STATE_FCS: begin // send FCS - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; case (frame_ptr_reg) - 2'd0: output_axis_tdata_int = ~crc_state[7:0]; - 2'd1: output_axis_tdata_int = ~crc_state[15:8]; - 2'd2: output_axis_tdata_int = ~crc_state[23:16]; - 2'd3: output_axis_tdata_int = ~crc_state[31:24]; + 2'd0: m_axis_tdata_int = ~crc_state[7:0]; + 2'd1: m_axis_tdata_int = ~crc_state[15:8]; + 2'd2: m_axis_tdata_int = ~crc_state[23:16]; + 2'd3: m_axis_tdata_int = ~crc_state[31:24]; endcase - output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tvalid_int = 1'b1; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin frame_ptr_next = frame_ptr_reg + 16'd1; if (frame_ptr_reg < 16'd3) begin @@ -244,8 +244,8 @@ always @* begin end else begin reset_crc = 1'b1; frame_ptr_next = 16'd0; - output_axis_tlast_int = 1'b1; - input_axis_tready_next = output_axis_tready_int_early; + m_axis_tlast_int = 1'b1; + s_axis_tready_next = m_axis_tready_int_early; state_next = STATE_IDLE; end end else begin @@ -261,7 +261,7 @@ always @(posedge clk) begin frame_ptr_reg <= 1'b0; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; busy_reg <= 1'b0; @@ -271,7 +271,7 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; busy_reg <= state_next != STATE_IDLE; @@ -285,83 +285,83 @@ always @(posedge clk) begin end // output datapath logic -reg [7:0] output_axis_tdata_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg [7:0] m_axis_tdata_reg = 8'd0; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg [7:0] temp_m_axis_tdata_reg = 8'd0; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/rtl/axis_eth_fcs_insert_64.v b/rtl/axis_eth_fcs_insert_64.v index 23242beea..887cc4315 100644 --- a/rtl/axis_eth_fcs_insert_64.v +++ b/rtl/axis_eth_fcs_insert_64.v @@ -41,22 +41,22 @@ module axis_eth_fcs_insert_64 # /* * AXI input */ - input wire [63:0] input_axis_tdata, - input wire [7:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [63:0] s_axis_tdata, + input wire [7:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * AXI output */ - output wire [63:0] output_axis_tdata, - output wire [7:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [63:0] m_axis_tdata, + output wire [7:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Status @@ -76,15 +76,15 @@ reg [1:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [63:0] input_axis_tdata_masked; +reg [63:0] s_axis_tdata_masked; -reg [63:0] fcs_input_tdata; -reg [7:0] fcs_input_tkeep; +reg [63:0] fcs_s_tdata; +reg [7:0] fcs_s_tkeep; -reg [63:0] fcs_output_tdata_0; -reg [63:0] fcs_output_tdata_1; -reg [7:0] fcs_output_tkeep_0; -reg [7:0] fcs_output_tkeep_1; +reg [63:0] fcs_m_tdata_0; +reg [63:0] fcs_m_tdata_1; +reg [7:0] fcs_m_tkeep_0; +reg [7:0] fcs_m_tkeep_1; reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; @@ -93,7 +93,7 @@ reg [7:0] last_cycle_tkeep_reg = 8'd0, last_cycle_tkeep_next; reg busy_reg = 1'b0; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; @@ -107,15 +107,15 @@ wire [31:0] crc_next6; wire [31:0] crc_next7; // internal datapath -reg [63:0] output_axis_tdata_int; -reg [7:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [63:0] m_axis_tdata_int; +reg [7:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; assign busy = busy_reg; @@ -129,7 +129,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(fcs_input_tdata[7:0]), + .data_in(fcs_s_tdata[7:0]), .state_in(crc_state), .data_out(), .state_out(crc_next0) @@ -145,7 +145,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_16 ( - .data_in(fcs_input_tdata[15:0]), + .data_in(fcs_s_tdata[15:0]), .state_in(crc_state), .data_out(), .state_out(crc_next1) @@ -161,7 +161,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_24 ( - .data_in(fcs_input_tdata[23:0]), + .data_in(fcs_s_tdata[23:0]), .state_in(crc_state), .data_out(), .state_out(crc_next2) @@ -177,7 +177,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_32 ( - .data_in(fcs_input_tdata[31:0]), + .data_in(fcs_s_tdata[31:0]), .state_in(crc_state), .data_out(), .state_out(crc_next3) @@ -193,7 +193,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_40 ( - .data_in(fcs_input_tdata[39:0]), + .data_in(fcs_s_tdata[39:0]), .state_in(crc_state), .data_out(), .state_out(crc_next4) @@ -209,7 +209,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_48 ( - .data_in(fcs_input_tdata[47:0]), + .data_in(fcs_s_tdata[47:0]), .state_in(crc_state), .data_out(), .state_out(crc_next5) @@ -225,7 +225,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_56 ( - .data_in(fcs_input_tdata[55:0]), + .data_in(fcs_s_tdata[55:0]), .state_in(crc_state), .data_out(), .state_out(crc_next6) @@ -241,7 +241,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_64 ( - .data_in(fcs_input_tdata[63:0]), + .data_in(fcs_s_tdata[63:0]), .state_in(crc_state), .data_out(), .state_out(crc_next7) @@ -282,66 +282,66 @@ integer j; always @* begin for (j = 0; j < 8; j = j + 1) begin - input_axis_tdata_masked[j*8 +: 8] = input_axis_tkeep[j] ? input_axis_tdata[j*8 +: 8] : 8'd0; + s_axis_tdata_masked[j*8 +: 8] = s_axis_tkeep[j] ? s_axis_tdata[j*8 +: 8] : 8'd0; end end // FCS cycle calculation always @* begin - casez (fcs_input_tkeep) + casez (fcs_s_tkeep) 8'bzzzzzz01: begin - fcs_output_tdata_0 = {24'd0, ~crc_next0[31:0], fcs_input_tdata[7:0]}; - fcs_output_tdata_1 = 64'd0; - fcs_output_tkeep_0 = 8'b00011111; - fcs_output_tkeep_1 = 8'b00000000; + fcs_m_tdata_0 = {24'd0, ~crc_next0[31:0], fcs_s_tdata[7:0]}; + fcs_m_tdata_1 = 64'd0; + fcs_m_tkeep_0 = 8'b00011111; + fcs_m_tkeep_1 = 8'b00000000; end 8'bzzzzz011: begin - fcs_output_tdata_0 = {16'd0, ~crc_next1[31:0], fcs_input_tdata[15:0]}; - fcs_output_tdata_1 = 64'd0; - fcs_output_tkeep_0 = 8'b00111111; - fcs_output_tkeep_1 = 8'b00000000; + fcs_m_tdata_0 = {16'd0, ~crc_next1[31:0], fcs_s_tdata[15:0]}; + fcs_m_tdata_1 = 64'd0; + fcs_m_tkeep_0 = 8'b00111111; + fcs_m_tkeep_1 = 8'b00000000; end 8'bzzzz0111: begin - fcs_output_tdata_0 = {8'd0, ~crc_next2[31:0], fcs_input_tdata[23:0]}; - fcs_output_tdata_1 = 64'd0; - fcs_output_tkeep_0 = 8'b01111111; - fcs_output_tkeep_1 = 8'b00000000; + fcs_m_tdata_0 = {8'd0, ~crc_next2[31:0], fcs_s_tdata[23:0]}; + fcs_m_tdata_1 = 64'd0; + fcs_m_tkeep_0 = 8'b01111111; + fcs_m_tkeep_1 = 8'b00000000; end 8'bzzz01111: begin - fcs_output_tdata_0 = {~crc_next3[31:0], fcs_input_tdata[31:0]}; - fcs_output_tdata_1 = 64'd0; - fcs_output_tkeep_0 = 8'b11111111; - fcs_output_tkeep_1 = 8'b00000000; + fcs_m_tdata_0 = {~crc_next3[31:0], fcs_s_tdata[31:0]}; + fcs_m_tdata_1 = 64'd0; + fcs_m_tkeep_0 = 8'b11111111; + fcs_m_tkeep_1 = 8'b00000000; end 8'bzz011111: begin - fcs_output_tdata_0 = {~crc_next4[23:0], fcs_input_tdata[39:0]}; - fcs_output_tdata_1 = {56'd0, ~crc_next4[31:24]}; - fcs_output_tkeep_0 = 8'b11111111; - fcs_output_tkeep_1 = 8'b00000001; + fcs_m_tdata_0 = {~crc_next4[23:0], fcs_s_tdata[39:0]}; + fcs_m_tdata_1 = {56'd0, ~crc_next4[31:24]}; + fcs_m_tkeep_0 = 8'b11111111; + fcs_m_tkeep_1 = 8'b00000001; end 8'bz0111111: begin - fcs_output_tdata_0 = {~crc_next5[15:0], fcs_input_tdata[47:0]}; - fcs_output_tdata_1 = {48'd0, ~crc_next5[31:16]}; - fcs_output_tkeep_0 = 8'b11111111; - fcs_output_tkeep_1 = 8'b00000011; + fcs_m_tdata_0 = {~crc_next5[15:0], fcs_s_tdata[47:0]}; + fcs_m_tdata_1 = {48'd0, ~crc_next5[31:16]}; + fcs_m_tkeep_0 = 8'b11111111; + fcs_m_tkeep_1 = 8'b00000011; end 8'b01111111: begin - fcs_output_tdata_0 = {~crc_next6[7:0], fcs_input_tdata[55:0]}; - fcs_output_tdata_1 = {40'd0, ~crc_next6[31:8]}; - fcs_output_tkeep_0 = 8'b11111111; - fcs_output_tkeep_1 = 8'b00000111; + fcs_m_tdata_0 = {~crc_next6[7:0], fcs_s_tdata[55:0]}; + fcs_m_tdata_1 = {40'd0, ~crc_next6[31:8]}; + fcs_m_tkeep_0 = 8'b11111111; + fcs_m_tkeep_1 = 8'b00000111; end 8'b11111111: begin - fcs_output_tdata_0 = fcs_input_tdata; - fcs_output_tdata_1 = {32'd0, ~crc_next7[31:0]}; - fcs_output_tkeep_0 = 8'b11111111; - fcs_output_tkeep_1 = 8'b00001111; + fcs_m_tdata_0 = fcs_s_tdata; + fcs_m_tdata_1 = {32'd0, ~crc_next7[31:0]}; + fcs_m_tkeep_0 = 8'b11111111; + fcs_m_tkeep_1 = 8'b00001111; end default: begin - fcs_output_tdata_0 = 64'd0; - fcs_output_tdata_1 = 64'd0; - fcs_output_tkeep_0 = 8'd0; - fcs_output_tkeep_1 = 8'd0; + fcs_m_tdata_0 = 64'd0; + fcs_m_tdata_1 = 64'd0; + fcs_m_tkeep_0 = 8'd0; + fcs_m_tkeep_1 = 8'd0; end endcase end @@ -357,89 +357,89 @@ always @* begin last_cycle_tdata_next = last_cycle_tdata_reg; last_cycle_tkeep_next = last_cycle_tkeep_reg; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - fcs_input_tdata = 64'd0; - fcs_input_tkeep = 8'd0; + fcs_s_tdata = 64'd0; + fcs_s_tkeep = 8'd0; - output_axis_tdata_int = 64'd0; - output_axis_tkeep_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 64'd0; + m_axis_tkeep_int = 8'd0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; frame_ptr_next = 16'd0; reset_crc = 1'b1; - output_axis_tdata_int = input_axis_tdata_masked; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = s_axis_tdata_masked; + m_axis_tkeep_int = s_axis_tkeep; + m_axis_tvalid_int = s_axis_tvalid; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - fcs_input_tdata = input_axis_tdata_masked; - fcs_input_tkeep = input_axis_tkeep; + fcs_s_tdata = s_axis_tdata_masked; + fcs_s_tkeep = s_axis_tkeep; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin reset_crc = 1'b0; update_crc = 1'b1; - frame_ptr_next = keep2count(input_axis_tkeep); - if (input_axis_tlast) begin - if (input_axis_tuser) begin - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = 1'b1; + frame_ptr_next = keep2count(s_axis_tkeep); + if (s_axis_tlast) begin + if (s_axis_tuser) begin + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = 1'b1; reset_crc = 1'b1; frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-4) begin - output_axis_tkeep_int = 8'hff; - fcs_input_tkeep = 8'hff; + m_axis_tkeep_int = 8'hff; + fcs_s_tkeep = 8'hff; frame_ptr_next = frame_ptr_reg + 16'd8; if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; state_next = STATE_PAD; end else begin - output_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); - fcs_input_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + m_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + fcs_s_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); - output_axis_tdata_int = fcs_output_tdata_0; - last_cycle_tdata_next = fcs_output_tdata_1; - output_axis_tkeep_int = fcs_output_tkeep_0; - last_cycle_tkeep_next = fcs_output_tkeep_1; + m_axis_tdata_int = fcs_m_tdata_0; + last_cycle_tdata_next = fcs_m_tdata_1; + m_axis_tkeep_int = fcs_m_tkeep_0; + last_cycle_tkeep_next = fcs_m_tkeep_1; reset_crc = 1'b1; - if (fcs_output_tkeep_1 == 8'd0) begin - output_axis_tlast_int = 1'b1; - input_axis_tready_next = output_axis_tready_int_early; + if (fcs_m_tkeep_1 == 8'd0) begin + m_axis_tlast_int = 1'b1; + s_axis_tready_next = m_axis_tready_int_early; frame_ptr_next = 1'b0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; state_next = STATE_FCS; end end end else begin - output_axis_tdata_int = fcs_output_tdata_0; - last_cycle_tdata_next = fcs_output_tdata_1; - output_axis_tkeep_int = fcs_output_tkeep_0; - last_cycle_tkeep_next = fcs_output_tkeep_1; + m_axis_tdata_int = fcs_m_tdata_0; + last_cycle_tdata_next = fcs_m_tdata_1; + m_axis_tkeep_int = fcs_m_tkeep_0; + last_cycle_tkeep_next = fcs_m_tkeep_1; reset_crc = 1'b1; - if (fcs_output_tkeep_1 == 8'd0) begin - output_axis_tlast_int = 1'b1; - input_axis_tready_next = output_axis_tready_int_early; + if (fcs_m_tkeep_1 == 8'd0) begin + m_axis_tlast_int = 1'b1; + s_axis_tready_next = m_axis_tready_int_early; frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; state_next = STATE_FCS; end end @@ -453,72 +453,72 @@ always @* begin end STATE_PAYLOAD: begin // transfer payload - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; - output_axis_tdata_int = input_axis_tdata_masked; - output_axis_tkeep_int = input_axis_tkeep; - output_axis_tvalid_int = input_axis_tvalid; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = s_axis_tdata_masked; + m_axis_tkeep_int = s_axis_tkeep; + m_axis_tvalid_int = s_axis_tvalid; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - fcs_input_tdata = input_axis_tdata_masked; - fcs_input_tkeep = input_axis_tkeep; + fcs_s_tdata = s_axis_tdata_masked; + fcs_s_tkeep = s_axis_tkeep; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin update_crc = 1'b1; - frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); - if (input_axis_tlast) begin - if (input_axis_tuser) begin - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = 1'b1; + frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); + if (s_axis_tlast) begin + if (s_axis_tuser) begin + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = 1'b1; reset_crc = 1'b1; frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin if (ENABLE_PADDING && frame_ptr_next < MIN_FRAME_LENGTH-4) begin - output_axis_tkeep_int = 8'hff; - fcs_input_tkeep = 8'hff; + m_axis_tkeep_int = 8'hff; + fcs_s_tkeep = 8'hff; frame_ptr_next = frame_ptr_reg + 16'd8; if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; state_next = STATE_PAD; end else begin - output_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); - fcs_input_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + m_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + fcs_s_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); - output_axis_tdata_int = fcs_output_tdata_0; - last_cycle_tdata_next = fcs_output_tdata_1; - output_axis_tkeep_int = fcs_output_tkeep_0; - last_cycle_tkeep_next = fcs_output_tkeep_1; + m_axis_tdata_int = fcs_m_tdata_0; + last_cycle_tdata_next = fcs_m_tdata_1; + m_axis_tkeep_int = fcs_m_tkeep_0; + last_cycle_tkeep_next = fcs_m_tkeep_1; reset_crc = 1'b1; - if (fcs_output_tkeep_1 == 8'd0) begin - output_axis_tlast_int = 1'b1; - input_axis_tready_next = output_axis_tready_int_early; + if (fcs_m_tkeep_1 == 8'd0) begin + m_axis_tlast_int = 1'b1; + s_axis_tready_next = m_axis_tready_int_early; frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; state_next = STATE_FCS; end end end else begin - output_axis_tdata_int = fcs_output_tdata_0; - last_cycle_tdata_next = fcs_output_tdata_1; - output_axis_tkeep_int = fcs_output_tkeep_0; - last_cycle_tkeep_next = fcs_output_tkeep_1; + m_axis_tdata_int = fcs_m_tdata_0; + last_cycle_tdata_next = fcs_m_tdata_1; + m_axis_tkeep_int = fcs_m_tkeep_0; + last_cycle_tkeep_next = fcs_m_tkeep_1; reset_crc = 1'b1; - if (fcs_output_tkeep_1 == 8'd0) begin - output_axis_tlast_int = 1'b1; - input_axis_tready_next = output_axis_tready_int_early; + if (fcs_m_tkeep_1 == 8'd0) begin + m_axis_tlast_int = 1'b1; + s_axis_tready_next = m_axis_tready_int_early; frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; state_next = STATE_FCS; end end @@ -531,41 +531,41 @@ always @* begin end end STATE_PAD: begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - output_axis_tdata_int = 64'd0; - output_axis_tkeep_int = 8'hff; - output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 64'd0; + m_axis_tkeep_int = 8'hff; + m_axis_tvalid_int = 1'b1; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; - fcs_input_tdata = 64'd0; - fcs_input_tkeep = 8'hff; + fcs_s_tdata = 64'd0; + fcs_s_tkeep = 8'hff; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin update_crc = 1'b1; frame_ptr_next = frame_ptr_reg + 16'd8; if (frame_ptr_next < MIN_FRAME_LENGTH-4) begin state_next = STATE_PAD; end else begin - output_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); - fcs_input_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + m_axis_tkeep_int = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); + fcs_s_tkeep = 8'hff >> (8-((MIN_FRAME_LENGTH-4) & 7)); - output_axis_tdata_int = fcs_output_tdata_0; - last_cycle_tdata_next = fcs_output_tdata_1; - output_axis_tkeep_int = fcs_output_tkeep_0; - last_cycle_tkeep_next = fcs_output_tkeep_1; + m_axis_tdata_int = fcs_m_tdata_0; + last_cycle_tdata_next = fcs_m_tdata_1; + m_axis_tkeep_int = fcs_m_tkeep_0; + last_cycle_tkeep_next = fcs_m_tkeep_1; reset_crc = 1'b1; - if (fcs_output_tkeep_1 == 8'd0) begin - output_axis_tlast_int = 1'b1; - input_axis_tready_next = output_axis_tready_int_early; + if (fcs_m_tkeep_1 == 8'd0) begin + m_axis_tlast_int = 1'b1; + s_axis_tready_next = m_axis_tready_int_early; frame_ptr_next = 16'd0; state_next = STATE_IDLE; end else begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; state_next = STATE_FCS; end end @@ -575,17 +575,17 @@ always @* begin end STATE_FCS: begin // last cycle - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - output_axis_tdata_int = last_cycle_tdata_reg; - output_axis_tkeep_int = last_cycle_tkeep_reg; - output_axis_tvalid_int = 1'b1; - output_axis_tlast_int = 1'b1; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = last_cycle_tdata_reg; + m_axis_tkeep_int = last_cycle_tkeep_reg; + m_axis_tvalid_int = 1'b1; + m_axis_tlast_int = 1'b1; + m_axis_tuser_int = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin reset_crc = 1'b1; - input_axis_tready_next = output_axis_tready_int_early; + s_axis_tready_next = m_axis_tready_int_early; frame_ptr_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -601,7 +601,7 @@ always @(posedge clk) begin frame_ptr_reg <= 1'b0; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; busy_reg <= 1'b0; @@ -611,7 +611,7 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; busy_reg <= state_next != STATE_IDLE; @@ -628,89 +628,89 @@ always @(posedge clk) begin end // output datapath logic -reg [63:0] output_axis_tdata_reg = 64'd0; -reg [7:0] output_axis_tkeep_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg [63:0] m_axis_tdata_reg = 64'd0; +reg [7:0] m_axis_tkeep_reg = 8'd0; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; -reg [63:0] temp_axis_tdata_reg = 64'd0; -reg [7:0] temp_axis_tkeep_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg [63:0] temp_m_axis_tdata_reg = 64'd0; +reg [7:0] temp_m_axis_tkeep_reg = 8'd0; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = m_axis_tkeep_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/rtl/axis_gmii_rx.v b/rtl/axis_gmii_rx.v index 0a5c0c04c..5e7aede2a 100644 --- a/rtl/axis_gmii_rx.v +++ b/rtl/axis_gmii_rx.v @@ -44,10 +44,10 @@ module axis_gmii_rx /* * AXI output */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [7:0] m_axis_tdata, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Control @@ -94,10 +94,10 @@ reg gmii_rx_er_d2 = 1'b0; reg gmii_rx_er_d3 = 1'b0; reg gmii_rx_er_d4 = 1'b0; -reg [7:0] output_axis_tdata_reg = 8'd0, output_axis_tdata_next; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0, output_axis_tlast_next; -reg output_axis_tuser_reg = 1'b0, output_axis_tuser_next; +reg [7:0] m_axis_tdata_reg = 8'd0, m_axis_tdata_next; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; +reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; @@ -105,10 +105,10 @@ reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; @@ -135,10 +135,10 @@ always @* begin reset_crc = 1'b0; update_crc = 1'b0; - output_axis_tdata_next = 8'd0; - output_axis_tvalid_next = 1'b0; - output_axis_tlast_next = 1'b0; - output_axis_tuser_next = 1'b0; + m_axis_tdata_next = 8'd0; + m_axis_tvalid_next = 1'b0; + m_axis_tlast_next = 1'b0; + m_axis_tuser_next = 1'b0; error_bad_frame_next = 1'b0; error_bad_fcs_next = 1'b0; @@ -146,7 +146,7 @@ always @* begin if (!clk_enable) begin // clock disabled - hold state state_next = state_reg; - end else if (mii_select & ~mii_odd) begin + end else if (mii_select && !mii_odd) begin // MII even cycle - hold state state_next = state_reg; end else begin @@ -155,7 +155,7 @@ always @* begin // idle state - wait for packet reset_crc = 1'b1; - if (gmii_rx_dv_d4 && ~gmii_rx_er_d4 && gmii_rxd_d4 == 8'hD5) begin + if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == 8'hD5) begin state_next = STATE_PAYLOAD; end else begin state_next = STATE_IDLE; @@ -165,28 +165,28 @@ always @* begin // read payload update_crc = 1'b1; - output_axis_tdata_next = gmii_rxd_d4; - output_axis_tvalid_next = 1'b1; + m_axis_tdata_next = gmii_rxd_d4; + m_axis_tvalid_next = 1'b1; - if (gmii_rx_dv_d4 & gmii_rx_er_d4) begin + if (gmii_rx_dv_d4 && gmii_rx_er_d4) begin // error - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b1; + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; state_next = STATE_WAIT_LAST; - end else if (~gmii_rx_dv) begin + end else if (!gmii_rx_dv) begin // end of packet - output_axis_tlast_next = 1'b1; - if (gmii_rx_er_d0 | gmii_rx_er_d1 | gmii_rx_er_d2 | gmii_rx_er_d3) begin + m_axis_tlast_next = 1'b1; + if (gmii_rx_er_d0 || gmii_rx_er_d1 || gmii_rx_er_d2 || gmii_rx_er_d3) begin // error received in FCS bytes - output_axis_tuser_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; end else if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin // FCS good - output_axis_tuser_next = 1'b0; + m_axis_tuser_next = 1'b0; end else begin // FCS bad - output_axis_tuser_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; error_bad_fcs_next = 1'b1; end @@ -212,7 +212,7 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - output_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; error_bad_frame_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; @@ -230,7 +230,7 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; @@ -244,11 +244,11 @@ always @(posedge clk) begin if (clk_enable) begin if (mii_select) begin - mii_odd <= ~mii_odd; + mii_odd <= !mii_odd; if (mii_locked) begin mii_locked <= gmii_rx_dv; - end else if (gmii_rx_dv & {gmii_rxd[3:0], gmii_rxd_d0[7:4]} == 8'hD5) begin + end else if (gmii_rx_dv && {gmii_rxd[3:0], gmii_rxd_d0[7:4]} == 8'hD5) begin mii_locked <= 1'b1; mii_odd <= 1'b1; end @@ -272,9 +272,9 @@ always @(posedge clk) begin end end - output_axis_tdata_reg <= output_axis_tdata_next; - output_axis_tlast_reg <= output_axis_tlast_next; - output_axis_tuser_reg <= output_axis_tuser_next; + m_axis_tdata_reg <= m_axis_tdata_next; + m_axis_tlast_reg <= m_axis_tlast_next; + m_axis_tuser_reg <= m_axis_tuser_next; // delay input if (clk_enable) begin diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index 06cc6f5f3..73cc95311 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -41,11 +41,11 @@ module axis_gmii_tx # /* * AXI input */ - input wire [7:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [7:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * GMII output @@ -82,7 +82,7 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [7:0] input_tdata_reg = 8'd0, input_tdata_next; +reg [7:0] s_tdata_reg = 8'd0, s_tdata_next; reg mii_odd_reg = 1'b0, mii_odd_next; reg [3:0] mii_msn_reg = 4'b0, mii_msn_next; @@ -93,12 +93,12 @@ reg [7:0] gmii_txd_reg = 8'd0, gmii_txd_next; reg gmii_tx_en_reg = 1'b0, gmii_tx_en_next; reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; assign gmii_txd = gmii_txd_reg; assign gmii_tx_en = gmii_tx_en_reg; @@ -114,7 +114,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(input_tdata_reg), + .data_in(s_tdata_reg), .state_in(crc_state), .data_out(), .state_out(crc_next) @@ -131,9 +131,9 @@ always @* begin frame_ptr_next = frame_ptr_reg; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - input_tdata_next = input_tdata_reg; + s_tdata_next = s_tdata_reg; gmii_txd_next = 8'd0; gmii_tx_en_next = 1'b0; @@ -145,7 +145,7 @@ always @* begin gmii_tx_en_next = gmii_tx_en_reg; gmii_tx_er_next = gmii_tx_er_reg; state_next = state_reg; - end else if (mii_select & mii_odd_reg) begin + end else if (mii_select && mii_odd_reg) begin // MII odd cycle - hold state, output MSN mii_odd_next = 1'b0; gmii_txd_next = {4'd0, mii_msn_reg}; @@ -159,7 +159,7 @@ always @* begin reset_crc = 1'b1; mii_odd_next = 1'b0; - if (input_axis_tvalid) begin + if (s_axis_tvalid) begin mii_odd_next = 1'b1; frame_ptr_next = 16'd1; gmii_txd_next = 8'h55; // Preamble @@ -180,15 +180,15 @@ always @* begin gmii_tx_en_next = 1'b1; if (frame_ptr_reg == 16'd6) begin - input_axis_tready_next = 1'b1; - input_tdata_next = input_axis_tdata; + s_axis_tready_next = 1'b1; + s_tdata_next = s_axis_tdata; state_next = STATE_PREAMBLE; end else if (frame_ptr_reg == 16'd7) begin // end of preamble; start payload frame_ptr_next = 16'd0; - if (input_axis_tready_reg) begin - input_axis_tready_next = 1'b1; - input_tdata_next = input_axis_tdata; + if (s_axis_tready_reg) begin + s_axis_tready_next = 1'b1; + s_tdata_next = s_axis_tdata; end gmii_txd_next = 8'hD5; // SFD state_next = STATE_PAYLOAD; @@ -200,20 +200,20 @@ always @* begin // send payload update_crc = 1'b1; - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; mii_odd_next = 1'b1; frame_ptr_next = frame_ptr_reg + 16'd1; - gmii_txd_next = input_tdata_reg; + gmii_txd_next = s_tdata_reg; gmii_tx_en_next = 1'b1; - input_tdata_next = input_axis_tdata; + s_tdata_next = s_axis_tdata; - if (input_axis_tvalid) begin - if (input_axis_tlast) begin - input_axis_tready_next = ~input_axis_tready_reg; - if (input_axis_tuser) begin + if (s_axis_tvalid) begin + if (s_axis_tlast) begin + s_axis_tready_next = !s_axis_tready_reg; + if (s_axis_tuser) begin gmii_tx_er_next = 1'b1; frame_ptr_next = 1'b0; state_next = STATE_IFG; @@ -238,11 +238,11 @@ always @* begin mii_odd_next = 1'b1; frame_ptr_next = frame_ptr_reg + 16'd1; - gmii_txd_next = input_tdata_reg; + gmii_txd_next = s_tdata_reg; gmii_tx_en_next = 1'b1; if (ENABLE_PADDING && frame_ptr_reg < MIN_FRAME_LENGTH-5) begin - input_tdata_next = 8'd0; + s_tdata_next = 8'd0; state_next = STATE_PAD; end else begin frame_ptr_next = 16'd0; @@ -259,7 +259,7 @@ always @* begin gmii_txd_next = 8'd0; gmii_tx_en_next = 1'b1; - input_tdata_next = 8'd0; + s_tdata_next = 8'd0; if (frame_ptr_reg < MIN_FRAME_LENGTH-5) begin state_next = STATE_PAD; @@ -296,11 +296,11 @@ always @* begin mii_odd_next = 1'b1; frame_ptr_next = frame_ptr_reg + 16'd1; - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; - if (input_axis_tvalid) begin - if (input_axis_tlast) begin - input_axis_tready_next = 1'b0; + if (s_axis_tvalid) begin + if (s_axis_tlast) begin + s_axis_tready_next = 1'b0; if (frame_ptr_reg < ifg_delay-1) begin state_next = STATE_IFG; end else begin @@ -342,7 +342,7 @@ always @(posedge clk) begin frame_ptr_reg <= 16'd0; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; gmii_tx_en_reg <= 1'b0; gmii_tx_er_reg <= 1'b0; @@ -353,7 +353,7 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; gmii_tx_en_reg <= gmii_tx_en_next; gmii_tx_er_reg <= gmii_tx_er_next; @@ -369,7 +369,7 @@ always @(posedge clk) begin mii_odd_reg <= mii_odd_next; mii_msn_reg <= mii_msn_next; - input_tdata_reg <= input_tdata_next; + s_tdata_reg <= s_tdata_next; gmii_txd_reg <= gmii_txd_next; end diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index aa8f4a9c3..94e4858ea 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -43,11 +43,11 @@ module axis_xgmii_rx_32 /* * AXI output */ - output wire [31:0] output_axis_tdata, - output wire [3:0] output_axis_tkeep, - output wire output_axis_tvalid, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [31:0] m_axis_tdata, + output wire [3:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Status @@ -78,11 +78,11 @@ reg [3:0] xgmii_rxc_d0 = 4'd0; reg [3:0] xgmii_rxc_d1 = 4'd0; reg [3:0] xgmii_rxc_d2 = 4'd0; -reg [31:0] output_axis_tdata_reg = 32'd0, output_axis_tdata_next; -reg [3:0] output_axis_tkeep_reg = 4'd0, output_axis_tkeep_next; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0, output_axis_tlast_next; -reg output_axis_tuser_reg = 1'b0, output_axis_tuser_next; +reg [31:0] m_axis_tdata_reg = 32'd0, m_axis_tdata_next; +reg [3:0] m_axis_tkeep_reg = 4'd0, m_axis_tkeep_next; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; +reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; @@ -104,11 +104,11 @@ reg crc_valid1_save = 1'b0; reg crc_valid2_save = 1'b0; reg crc_valid3_save = 1'b0; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = m_axis_tkeep_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; @@ -244,11 +244,11 @@ always @* begin last_cycle_tkeep_next = last_cycle_tkeep_reg; - output_axis_tdata_next = 32'd0; - output_axis_tkeep_next = 4'd0; - output_axis_tvalid_next = 1'b0; - output_axis_tlast_next = 1'b0; - output_axis_tuser_next = 1'b0; + m_axis_tdata_next = 32'd0; + m_axis_tkeep_next = 4'd0; + m_axis_tvalid_next = 1'b0; + m_axis_tlast_next = 1'b0; + m_axis_tuser_next = 1'b0; error_bad_frame_next = 1'b0; error_bad_fcs_next = 1'b0; @@ -262,11 +262,11 @@ always @* begin // start condition if (detect_error_masked) begin // error in first data word - output_axis_tdata_next = 32'd0; - output_axis_tkeep_next = 4'h1; - output_axis_tvalid_next = 1'b1; - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b1; + m_axis_tdata_next = 32'd0; + m_axis_tkeep_next = 4'h1; + m_axis_tvalid_next = 1'b1; + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; state_next = STATE_IDLE; end else begin @@ -287,16 +287,16 @@ always @* begin // read payload update_crc = 1'b1; - output_axis_tdata_next = xgmii_rxd_d2; - output_axis_tkeep_next = ~xgmii_rxc_d2; - output_axis_tvalid_next = 1'b1; - output_axis_tlast_next = 1'b0; - output_axis_tuser_next = 1'b0; + m_axis_tdata_next = xgmii_rxd_d2; + m_axis_tkeep_next = ~xgmii_rxc_d2; + m_axis_tvalid_next = 1'b1; + m_axis_tlast_next = 1'b0; + m_axis_tuser_next = 1'b0; if (control_masked) begin // control or error characters in packet - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b1; + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; reset_crc = 1'b1; state_next = STATE_IDLE; @@ -304,12 +304,12 @@ always @* begin if (detect_term[0]) begin // end this cycle reset_crc = 1'b1; - output_axis_tkeep_next = 4'b1111; - output_axis_tlast_next = 1'b1; - if (detect_term[0] & crc_valid3_save) begin + m_axis_tkeep_next = 4'b1111; + m_axis_tlast_next = 1'b1; + if (detect_term[0] && crc_valid3_save) begin // CRC valid end else begin - output_axis_tuser_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; error_bad_fcs_next = 1'b1; end @@ -325,20 +325,20 @@ always @* begin end STATE_LAST: begin // last cycle of packet - output_axis_tdata_next = xgmii_rxd_d2; - output_axis_tkeep_next = last_cycle_tkeep_reg; - output_axis_tvalid_next = 1'b1; - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b0; + m_axis_tdata_next = xgmii_rxd_d2; + m_axis_tkeep_next = last_cycle_tkeep_reg; + m_axis_tvalid_next = 1'b1; + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b0; reset_crc = 1'b1; - if ((detect_term_save[1] & crc_valid0_save) || - (detect_term_save[2] & crc_valid1_save) || - (detect_term_save[3] & crc_valid2_save)) begin + if ((detect_term_save[1] && crc_valid0_save) || + (detect_term_save[2] && crc_valid1_save) || + (detect_term_save[3] && crc_valid2_save)) begin // CRC valid end else begin - output_axis_tuser_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; error_bad_fcs_next = 1'b1; end @@ -357,7 +357,7 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - output_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; error_bad_frame_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; @@ -373,7 +373,7 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; @@ -398,10 +398,10 @@ always @(posedge clk) begin end end - output_axis_tdata_reg <= output_axis_tdata_next; - output_axis_tkeep_reg <= output_axis_tkeep_next; - output_axis_tlast_reg <= output_axis_tlast_next; - output_axis_tuser_reg <= output_axis_tuser_next; + m_axis_tdata_reg <= m_axis_tdata_next; + m_axis_tkeep_reg <= m_axis_tkeep_next; + m_axis_tlast_reg <= m_axis_tlast_next; + m_axis_tuser_reg <= m_axis_tuser_next; last_cycle_tkeep_reg <= last_cycle_tkeep_next; diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index dd4e138ce..5beb150ca 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -43,11 +43,11 @@ module axis_xgmii_rx_64 /* * AXI output */ - output wire [63:0] output_axis_tdata, - output wire [7:0] output_axis_tkeep, - output wire output_axis_tvalid, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [63:0] m_axis_tdata, + output wire [7:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Status @@ -79,11 +79,11 @@ reg [63:0] xgmii_rxd_d1 = 32'd0; reg [7:0] xgmii_rxc_d0 = 8'd0; reg [7:0] xgmii_rxc_d1 = 8'd0; -reg [63:0] output_axis_tdata_reg = 64'd0, output_axis_tdata_next; -reg [7:0] output_axis_tkeep_reg = 8'd0, output_axis_tkeep_next; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0, output_axis_tlast_next; -reg output_axis_tuser_reg = 1'b0, output_axis_tuser_next; +reg [63:0] m_axis_tdata_reg = 64'd0, m_axis_tdata_next; +reg [7:0] m_axis_tkeep_reg = 8'd0, m_axis_tkeep_next; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; +reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; @@ -105,11 +105,11 @@ wire crc_valid7 = crc_next7 == ~32'h2144df1c; reg crc_valid7_save = 1'b0; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = m_axis_tkeep_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; @@ -281,11 +281,11 @@ always @* begin last_cycle_tkeep_next = last_cycle_tkeep_reg; - output_axis_tdata_next = 64'd0; - output_axis_tkeep_next = 8'd0; - output_axis_tvalid_next = 1'b0; - output_axis_tlast_next = 1'b0; - output_axis_tuser_next = 1'b0; + m_axis_tdata_next = 64'd0; + m_axis_tkeep_next = 8'd0; + m_axis_tvalid_next = 1'b0; + m_axis_tlast_next = 1'b0; + m_axis_tuser_next = 1'b0; error_bad_frame_next = 1'b0; error_bad_fcs_next = 1'b0; @@ -299,11 +299,11 @@ always @* begin // start condition if (detect_error_masked) begin // error in first data word - output_axis_tdata_next = 64'd0; - output_axis_tkeep_next = 8'h01; - output_axis_tvalid_next = 1'b1; - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b1; + m_axis_tdata_next = 64'd0; + m_axis_tkeep_next = 8'h01; + m_axis_tvalid_next = 1'b1; + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; state_next = STATE_IDLE; end else begin @@ -319,16 +319,16 @@ always @* begin // read payload update_crc = 1'b1; - output_axis_tdata_next = xgmii_rxd_d1; - output_axis_tkeep_next = ~xgmii_rxc_d1; - output_axis_tvalid_next = 1'b1; - output_axis_tlast_next = 1'b0; - output_axis_tuser_next = 1'b0; + m_axis_tdata_next = xgmii_rxd_d1; + m_axis_tkeep_next = ~xgmii_rxc_d1; + m_axis_tvalid_next = 1'b1; + m_axis_tlast_next = 1'b0; + m_axis_tuser_next = 1'b0; if (control_masked) begin // control or error characters in packet - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b1; + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; reset_crc = 1'b1; state_next = STATE_IDLE; @@ -336,16 +336,16 @@ always @* begin if (detect_term[4:0]) begin // end this cycle reset_crc = 1'b1; - output_axis_tkeep_next = {tkeep_mask[3:0], 4'b1111}; - output_axis_tlast_next = 1'b1; - if ((detect_term[0] & crc_valid7_save) || - (detect_term[1] & crc_valid0) || - (detect_term[2] & crc_valid1) || - (detect_term[3] & crc_valid2) || - (detect_term[4] & crc_valid3)) begin + m_axis_tkeep_next = {tkeep_mask[3:0], 4'b1111}; + m_axis_tlast_next = 1'b1; + if ((detect_term[0] && crc_valid7_save) || + (detect_term[1] && crc_valid0) || + (detect_term[2] && crc_valid1) || + (detect_term[3] && crc_valid2) || + (detect_term[4] && crc_valid3)) begin // CRC valid end else begin - output_axis_tuser_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; error_bad_fcs_next = 1'b1; end @@ -361,20 +361,20 @@ always @* begin end STATE_LAST: begin // last cycle of packet - output_axis_tdata_next = xgmii_rxd_d1; - output_axis_tkeep_next = last_cycle_tkeep_reg; - output_axis_tvalid_next = 1'b1; - output_axis_tlast_next = 1'b1; - output_axis_tuser_next = 1'b0; + m_axis_tdata_next = xgmii_rxd_d1; + m_axis_tkeep_next = last_cycle_tkeep_reg; + m_axis_tvalid_next = 1'b1; + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b0; reset_crc = 1'b1; - if ((detect_term_save[5] & crc_valid0) || - (detect_term_save[6] & crc_valid1) || - (detect_term_save[7] & crc_valid2)) begin + if ((detect_term_save[5] && crc_valid0) || + (detect_term_save[6] && crc_valid1) || + (detect_term_save[7] && crc_valid2)) begin // CRC valid end else begin - output_axis_tuser_next = 1'b1; + m_axis_tuser_next = 1'b1; error_bad_frame_next = 1'b1; error_bad_fcs_next = 1'b1; end @@ -393,7 +393,7 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - output_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; error_bad_frame_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; @@ -409,7 +409,7 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - output_axis_tvalid_reg <= output_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; @@ -444,10 +444,10 @@ always @(posedge clk) begin end end - output_axis_tdata_reg <= output_axis_tdata_next; - output_axis_tkeep_reg <= output_axis_tkeep_next; - output_axis_tlast_reg <= output_axis_tlast_next; - output_axis_tuser_reg <= output_axis_tuser_next; + m_axis_tdata_reg <= m_axis_tdata_next; + m_axis_tkeep_reg <= m_axis_tkeep_next; + m_axis_tlast_reg <= m_axis_tlast_next; + m_axis_tuser_reg <= m_axis_tuser_next; last_cycle_tkeep_reg <= last_cycle_tkeep_next; diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index 7761b8581..e0e6c7c68 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -42,12 +42,12 @@ module axis_xgmii_tx_32 # /* * AXI input */ - input wire [31:0] input_axis_tdata, - input wire [3:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [31:0] s_axis_tdata, + input wire [3:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * XGMII output @@ -82,10 +82,10 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [31:0] input_axis_tdata_masked; +reg [31:0] s_axis_tdata_masked; -reg [31:0] input_tdata_reg = 64'd0, input_tdata_next; -reg [3:0] input_tkeep_reg = 8'd0, input_tkeep_next; +reg [31:0] s_tdata_reg = 64'd0, s_tdata_next; +reg [3:0] s_tkeep_reg = 8'd0, s_tkeep_next; reg [31:0] fcs_output_txd_0; reg [31:0] fcs_output_txd_1; @@ -101,7 +101,7 @@ reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; reg [7:0] ifg_count_reg = 8'd0, ifg_count_next; reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; @@ -113,7 +113,7 @@ wire [31:0] crc_next3; reg [31:0] xgmii_txd_reg = 32'h07070707, xgmii_txd_next; reg [3:0] xgmii_txc_reg = 4'b1111, xgmii_txc_next; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; @@ -128,7 +128,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(input_tdata_reg[7:0]), + .data_in(s_tdata_reg[7:0]), .state_in(crc_state), .data_out(), .state_out(crc_next0) @@ -144,7 +144,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_16 ( - .data_in(input_tdata_reg[15:0]), + .data_in(s_tdata_reg[15:0]), .state_in(crc_state), .data_out(), .state_out(crc_next1) @@ -160,7 +160,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_24 ( - .data_in(input_tdata_reg[23:0]), + .data_in(s_tdata_reg[23:0]), .state_in(crc_state), .data_out(), .state_out(crc_next2) @@ -176,7 +176,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_32 ( - .data_in(input_tdata_reg[31:0]), + .data_in(s_tdata_reg[31:0]), .state_in(crc_state), .data_out(), .state_out(crc_next3) @@ -209,15 +209,15 @@ integer j; always @* begin for (j = 0; j < 4; j = j + 1) begin - input_axis_tdata_masked[j*8 +: 8] = input_axis_tkeep[j] ? input_axis_tdata[j*8 +: 8] : 8'd0; + s_axis_tdata_masked[j*8 +: 8] = s_axis_tkeep[j] ? s_axis_tdata[j*8 +: 8] : 8'd0; end end // FCS cycle calculation always @* begin - casez (input_tkeep_reg) + casez (s_tkeep_reg) 4'bzz01: begin - fcs_output_txd_0 = {~crc_next0[23:0], input_tdata_reg[7:0]}; + fcs_output_txd_0 = {~crc_next0[23:0], s_tdata_reg[7:0]}; fcs_output_txd_1 = {24'h0707fd, ~crc_next0[31:24]}; fcs_output_txc_0 = 4'b0000; fcs_output_txc_1 = 4'b1110; @@ -225,7 +225,7 @@ always @* begin extra_cycle = 1'b0; end 4'bz011: begin - fcs_output_txd_0 = {~crc_next1[15:0], input_tdata_reg[15:0]}; + fcs_output_txd_0 = {~crc_next1[15:0], s_tdata_reg[15:0]}; fcs_output_txd_1 = {16'h07fd, ~crc_next1[31:16]}; fcs_output_txc_0 = 4'b0000; fcs_output_txc_1 = 4'b1100; @@ -233,7 +233,7 @@ always @* begin extra_cycle = 1'b0; end 4'b0111: begin - fcs_output_txd_0 = {~crc_next2[7:0], input_tdata_reg[23:0]}; + fcs_output_txd_0 = {~crc_next2[7:0], s_tdata_reg[23:0]}; fcs_output_txd_1 = {16'hfd, ~crc_next2[31:8]}; fcs_output_txc_0 = 4'b0000; fcs_output_txc_1 = 4'b1000; @@ -241,7 +241,7 @@ always @* begin extra_cycle = 1'b0; end 4'b1111: begin - fcs_output_txd_0 = input_tdata_reg; + fcs_output_txd_0 = s_tdata_reg; fcs_output_txd_1 = ~crc_next3; fcs_output_txc_0 = 4'b0000; fcs_output_txc_1 = 4'b0000; @@ -270,10 +270,10 @@ always @* begin ifg_count_next = ifg_count_reg; deficit_idle_count_next = deficit_idle_count_reg; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - input_tdata_next = input_tdata_reg; - input_tkeep_next = input_tkeep_reg; + s_tdata_next = s_tdata_reg; + s_tkeep_next = s_tkeep_reg; // XGMII idle xgmii_txd_next = 32'h07070707; @@ -289,14 +289,14 @@ always @* begin xgmii_txd_next = 32'h07070707; xgmii_txc_next = 4'b1111; - input_tdata_next = input_axis_tdata_masked; - input_tkeep_next = input_axis_tkeep; + s_tdata_next = s_axis_tdata_masked; + s_tkeep_next = s_axis_tkeep; - if (input_axis_tvalid) begin + if (s_axis_tvalid) begin // XGMII start and preamble xgmii_txd_next = 32'h555555fb; xgmii_txc_next = 4'b0001; - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_PREAMBLE; end else begin ifg_count_next = 8'd0; @@ -307,48 +307,48 @@ always @* begin STATE_PREAMBLE: begin // send preamble - input_tdata_next = input_axis_tdata_masked; - input_tkeep_next = input_axis_tkeep; + s_tdata_next = s_axis_tdata_masked; + s_tkeep_next = s_axis_tkeep; xgmii_txd_next = 32'hd5555555; xgmii_txc_next = 4'b0000; - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_PAYLOAD; end STATE_PAYLOAD: begin // transfer payload update_crc = 1'b1; - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; frame_ptr_next = frame_ptr_reg + 16'd4; - xgmii_txd_next = input_tdata_reg; + xgmii_txd_next = s_tdata_reg; xgmii_txc_next = 4'b0000; - input_tdata_next = input_axis_tdata_masked; - input_tkeep_next = input_axis_tkeep; + s_tdata_next = s_axis_tdata_masked; + s_tkeep_next = s_axis_tkeep; - if (input_axis_tvalid) begin - if (input_axis_tlast) begin - frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); - input_axis_tready_next = 1'b0; - if (input_axis_tuser) begin + if (s_axis_tvalid) begin + if (s_axis_tlast) begin + frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); + s_axis_tready_next = 1'b0; + if (s_axis_tuser) begin xgmii_txd_next = 32'h07fdfefe; xgmii_txc_next = 4'b1111; frame_ptr_next = 16'd0; ifg_count_next = 8'd10; state_next = STATE_IFG; end else begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(input_axis_tkeep) < MIN_FL_NOCRC_LS))) begin - input_tkeep_next = 4'hf; + if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(s_axis_tkeep) < MIN_FL_NOCRC_LS))) begin + s_tkeep_next = 4'hf; frame_ptr_next = frame_ptr_reg + 16'd4; if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-4)) begin state_next = STATE_PAD; end else begin - input_tkeep_next = 4'hf >> ((4-MIN_FL_NOCRC_LS) % 4); + s_tkeep_next = 4'hf >> ((4-MIN_FL_NOCRC_LS) % 4); state_next = STATE_FCS_1; end @@ -370,13 +370,13 @@ always @* begin end STATE_PAD: begin // pad frame to MIN_FRAME_LENGTH - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - xgmii_txd_next = input_tdata_reg; + xgmii_txd_next = s_tdata_reg; xgmii_txc_next = 4'b0000; - input_tdata_next = 32'd0; - input_tkeep_next = 4'hf; + s_tdata_next = 32'd0; + s_tkeep_next = 4'hf; update_crc = 1'b1; frame_ptr_next = frame_ptr_reg + 16'd4; @@ -384,14 +384,14 @@ always @* begin if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-4)) begin state_next = STATE_PAD; end else begin - input_tkeep_next = 4'hf >> ((4-MIN_FL_NOCRC_LS) % 4); + s_tkeep_next = 4'hf >> ((4-MIN_FL_NOCRC_LS) % 4); state_next = STATE_FCS_1; end end STATE_FCS_1: begin // last cycle - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; xgmii_txd_next = fcs_output_txd_0; xgmii_txc_next = fcs_output_txc_0; @@ -403,7 +403,7 @@ always @* begin end STATE_FCS_2: begin // last cycle - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; xgmii_txd_next = fcs_output_txd_1; xgmii_txc_next = fcs_output_txc_1; @@ -418,7 +418,7 @@ always @* begin end STATE_FCS_3: begin // last cycle - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; xgmii_txd_next = 32'h070707fd; xgmii_txc_next = 4'b1111; @@ -432,7 +432,7 @@ always @* begin end else begin deficit_idle_count_next = ifg_count_next; ifg_count_next = 8'd0; - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else begin @@ -479,8 +479,8 @@ always @* begin reset_crc = 1'b1; - if (input_axis_tvalid) begin - if (input_axis_tlast) begin + if (s_axis_tvalid) begin + if (s_axis_tlast) begin if (ENABLE_DIC) begin if (ifg_count_next > 8'd3) begin state_next = STATE_IFG; @@ -515,7 +515,7 @@ always @(posedge clk) begin ifg_count_reg <= 8'd0; deficit_idle_count_reg <= 2'd0; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; xgmii_txd_reg <= 32'h07070707; xgmii_txc_reg <= 4'b1111; @@ -529,7 +529,7 @@ always @(posedge clk) begin ifg_count_reg <= ifg_count_next; deficit_idle_count_reg <= deficit_idle_count_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; xgmii_txd_reg <= xgmii_txd_next; xgmii_txc_reg <= xgmii_txc_next; @@ -542,8 +542,8 @@ always @(posedge clk) begin end end - input_tdata_reg <= input_tdata_next; - input_tkeep_reg <= input_tkeep_next; + s_tdata_reg <= s_tdata_next; + s_tkeep_reg <= s_tkeep_next; end endmodule diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index ce118dfa9..9bdb56ba7 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -42,12 +42,12 @@ module axis_xgmii_tx_64 # /* * AXI input */ - input wire [63:0] input_axis_tdata, - input wire [7:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [63:0] s_axis_tdata, + input wire [7:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * XGMII output @@ -87,10 +87,10 @@ reg lanes_swapped = 1'b0; reg [31:0] swap_txd = 32'd0; reg [3:0] swap_txc = 4'd0; -reg [63:0] input_axis_tdata_masked; +reg [63:0] s_axis_tdata_masked; -reg [63:0] input_tdata_reg = 64'd0, input_tdata_next; -reg [7:0] input_tkeep_reg = 8'd0, input_tkeep_next; +reg [63:0] s_tdata_reg = 64'd0, s_tdata_next; +reg [7:0] s_tkeep_reg = 8'd0, s_tkeep_next; reg [63:0] fcs_output_txd_0; reg [63:0] fcs_output_txd_1; @@ -106,7 +106,7 @@ reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; reg [7:0] ifg_count_reg = 8'd0, ifg_count_next; reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg [31:0] crc_state = 32'hFFFFFFFF; @@ -122,7 +122,7 @@ wire [31:0] crc_next7; reg [63:0] xgmii_txd_reg = 64'h0707070707070707, xgmii_txd_next; reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; @@ -137,7 +137,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(input_tdata_reg[7:0]), + .data_in(s_tdata_reg[7:0]), .state_in(crc_state), .data_out(), .state_out(crc_next0) @@ -153,7 +153,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_16 ( - .data_in(input_tdata_reg[15:0]), + .data_in(s_tdata_reg[15:0]), .state_in(crc_state), .data_out(), .state_out(crc_next1) @@ -169,7 +169,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_24 ( - .data_in(input_tdata_reg[23:0]), + .data_in(s_tdata_reg[23:0]), .state_in(crc_state), .data_out(), .state_out(crc_next2) @@ -185,7 +185,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_32 ( - .data_in(input_tdata_reg[31:0]), + .data_in(s_tdata_reg[31:0]), .state_in(crc_state), .data_out(), .state_out(crc_next3) @@ -201,7 +201,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_40 ( - .data_in(input_tdata_reg[39:0]), + .data_in(s_tdata_reg[39:0]), .state_in(crc_state), .data_out(), .state_out(crc_next4) @@ -217,7 +217,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_48 ( - .data_in(input_tdata_reg[47:0]), + .data_in(s_tdata_reg[47:0]), .state_in(crc_state), .data_out(), .state_out(crc_next5) @@ -233,7 +233,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_56 ( - .data_in(input_tdata_reg[55:0]), + .data_in(s_tdata_reg[55:0]), .state_in(crc_state), .data_out(), .state_out(crc_next6) @@ -249,7 +249,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_64 ( - .data_in(input_tdata_reg[63:0]), + .data_in(s_tdata_reg[63:0]), .state_in(crc_state), .data_out(), .state_out(crc_next7) @@ -290,15 +290,15 @@ integer j; always @* begin for (j = 0; j < 8; j = j + 1) begin - input_axis_tdata_masked[j*8 +: 8] = input_axis_tkeep[j] ? input_axis_tdata[j*8 +: 8] : 8'd0; + s_axis_tdata_masked[j*8 +: 8] = s_axis_tkeep[j] ? s_axis_tdata[j*8 +: 8] : 8'd0; end end // FCS cycle calculation always @* begin - casez (input_tkeep_reg) + casez (s_tkeep_reg) 8'bzzzzzz01: begin - fcs_output_txd_0 = {24'h0707fd, ~crc_next0[31:0], input_tdata_reg[7:0]}; + fcs_output_txd_0 = {24'h0707fd, ~crc_next0[31:0], s_tdata_reg[7:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b11100000; fcs_output_txc_1 = 8'b11111111; @@ -306,7 +306,7 @@ always @* begin extra_cycle = 1'b0; end 8'bzzzzz011: begin - fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], input_tdata_reg[15:0]}; + fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], s_tdata_reg[15:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b11000000; fcs_output_txc_1 = 8'b11111111; @@ -314,7 +314,7 @@ always @* begin extra_cycle = 1'b0; end 8'bzzzz0111: begin - fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], input_tdata_reg[23:0]}; + fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], s_tdata_reg[23:0]}; fcs_output_txd_1 = {63'h0707070707070707}; fcs_output_txc_0 = 8'b10000000; fcs_output_txc_1 = 8'b11111111; @@ -322,7 +322,7 @@ always @* begin extra_cycle = 1'b0; end 8'bzzz01111: begin - fcs_output_txd_0 = {~crc_next3[31:0], input_tdata_reg[31:0]}; + fcs_output_txd_0 = {~crc_next3[31:0], s_tdata_reg[31:0]}; fcs_output_txd_1 = {63'h07070707070707fd}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111111; @@ -330,7 +330,7 @@ always @* begin extra_cycle = 1'b1; end 8'bzz011111: begin - fcs_output_txd_0 = {~crc_next4[23:0], input_tdata_reg[39:0]}; + fcs_output_txd_0 = {~crc_next4[23:0], s_tdata_reg[39:0]}; fcs_output_txd_1 = {56'h070707070707fd, ~crc_next4[31:24]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111110; @@ -338,7 +338,7 @@ always @* begin extra_cycle = 1'b1; end 8'bz0111111: begin - fcs_output_txd_0 = {~crc_next5[15:0], input_tdata_reg[47:0]}; + fcs_output_txd_0 = {~crc_next5[15:0], s_tdata_reg[47:0]}; fcs_output_txd_1 = {48'h0707070707fd, ~crc_next5[31:16]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111100; @@ -346,7 +346,7 @@ always @* begin extra_cycle = 1'b1; end 8'b01111111: begin - fcs_output_txd_0 = {~crc_next6[7:0], input_tdata_reg[55:0]}; + fcs_output_txd_0 = {~crc_next6[7:0], s_tdata_reg[55:0]}; fcs_output_txd_1 = {40'h07070707fd, ~crc_next6[31:8]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111000; @@ -354,7 +354,7 @@ always @* begin extra_cycle = 1'b1; end 8'b11111111: begin - fcs_output_txd_0 = input_tdata_reg; + fcs_output_txd_0 = s_tdata_reg; fcs_output_txd_1 = {32'h070707fd, ~crc_next7[31:0]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11110000; @@ -386,10 +386,10 @@ always @* begin ifg_count_next = ifg_count_reg; deficit_idle_count_next = deficit_idle_count_reg; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - input_tdata_next = input_tdata_reg; - input_tkeep_next = input_tkeep_reg; + s_tdata_next = s_tdata_reg; + s_tkeep_next = s_tkeep_reg; // XGMII idle xgmii_txd_next = 64'h0707070707070707; @@ -400,16 +400,16 @@ always @* begin // idle state - wait for data frame_ptr_next = 16'd8; reset_crc = 1'b1; - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; // XGMII idle xgmii_txd_next = 64'h0707070707070707; xgmii_txc_next = 8'b11111111; - input_tdata_next = input_axis_tdata_masked; - input_tkeep_next = input_axis_tkeep; + s_tdata_next = s_axis_tdata_masked; + s_tkeep_next = s_axis_tkeep; - if (input_axis_tvalid) begin + if (s_axis_tvalid) begin // XGMII start and preamble if (ifg_count_reg > 8'd0) begin // need to send more idles - swap lanes @@ -420,7 +420,7 @@ always @* begin end xgmii_txd_next = 64'hd5555555555555fb; xgmii_txc_next = 8'b00000001; - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_PAYLOAD; end else begin ifg_count_next = 8'd0; @@ -432,37 +432,37 @@ always @* begin STATE_PAYLOAD: begin // transfer payload update_crc = 1'b1; - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; frame_ptr_next = frame_ptr_reg + 16'd8; - xgmii_txd_next = input_tdata_reg; + xgmii_txd_next = s_tdata_reg; xgmii_txc_next = 8'b00000000; - input_tdata_next = input_axis_tdata_masked; - input_tkeep_next = input_axis_tkeep; + s_tdata_next = s_axis_tdata_masked; + s_tkeep_next = s_axis_tkeep; - if (input_axis_tvalid) begin - if (input_axis_tlast) begin - frame_ptr_next = frame_ptr_reg + keep2count(input_axis_tkeep); - input_axis_tready_next = 1'b0; - if (input_axis_tuser) begin + if (s_axis_tvalid) begin + if (s_axis_tlast) begin + frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); + s_axis_tready_next = 1'b0; + if (s_axis_tuser) begin xgmii_txd_next = 64'h070707fdfefefefe; xgmii_txc_next = 8'b11111111; frame_ptr_next = 16'd0; ifg_count_next = 8'd8; state_next = STATE_IFG; end else begin - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(input_axis_tkeep) < MIN_FL_NOCRC_LS))) begin - input_tkeep_next = 8'hff; + if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(s_axis_tkeep) < MIN_FL_NOCRC_LS))) begin + s_tkeep_next = 8'hff; frame_ptr_next = frame_ptr_reg + 16'd8; if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-8)) begin state_next = STATE_PAD; end else begin - input_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8); + s_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8); state_next = STATE_FCS_1; end @@ -484,13 +484,13 @@ always @* begin end STATE_PAD: begin // pad frame to MIN_FRAME_LENGTH - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; - xgmii_txd_next = input_tdata_reg; + xgmii_txd_next = s_tdata_reg; xgmii_txc_next = 8'b00000000; - input_tdata_next = 64'd0; - input_tkeep_next = 8'hff; + s_tdata_next = 64'd0; + s_tkeep_next = 8'hff; update_crc = 1'b1; frame_ptr_next = frame_ptr_reg + 16'd8; @@ -498,14 +498,14 @@ always @* begin if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-8)) begin state_next = STATE_PAD; end else begin - input_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8); + s_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8); state_next = STATE_FCS_1; end end STATE_FCS_1: begin // last cycle - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; xgmii_txd_next = fcs_output_txd_0; xgmii_txc_next = fcs_output_txc_0; @@ -521,7 +521,7 @@ always @* begin end STATE_FCS_2: begin // last cycle - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; xgmii_txd_next = fcs_output_txd_1; xgmii_txc_next = fcs_output_txc_1; @@ -539,14 +539,14 @@ always @* begin deficit_idle_count_next = ifg_count_next; ifg_count_next = 8'd0; end - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else begin if (ifg_count_next > 8'd4) begin state_next = STATE_IFG; end else begin - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end @@ -571,14 +571,14 @@ always @* begin deficit_idle_count_next = ifg_count_next; ifg_count_next = 8'd0; end - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else begin if (ifg_count_next > 8'd4) begin state_next = STATE_IFG; end else begin - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end @@ -593,8 +593,8 @@ always @* begin reset_crc = 1'b1; - if (input_axis_tvalid) begin - if (input_axis_tlast) begin + if (s_axis_tvalid) begin + if (s_axis_tlast) begin if (ENABLE_DIC) begin if (ifg_count_next > 8'd7) begin state_next = STATE_IFG; @@ -605,14 +605,14 @@ always @* begin deficit_idle_count_next = ifg_count_next; ifg_count_next = 8'd0; end - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end else begin if (ifg_count_next > 8'd4) begin state_next = STATE_IFG; end else begin - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; state_next = STATE_IDLE; end end @@ -635,7 +635,7 @@ always @(posedge clk) begin ifg_count_reg <= 8'd0; deficit_idle_count_reg <= 2'd0; - input_axis_tready_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; xgmii_txd_reg <= 64'h0707070707070707; xgmii_txc_reg <= 8'b11111111; @@ -651,7 +651,7 @@ always @(posedge clk) begin ifg_count_reg <= ifg_count_next; deficit_idle_count_reg <= deficit_idle_count_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; if (lanes_swapped) begin if (unswap_lanes) begin @@ -681,8 +681,8 @@ always @(posedge clk) begin end end - input_tdata_reg <= input_tdata_next; - input_tkeep_reg <= input_tkeep_next; + s_tdata_reg <= s_tdata_next; + s_tkeep_reg <= s_tkeep_next; swap_txd <= xgmii_txd_next[63:32]; swap_txc <= xgmii_txc_next[7:4]; diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index e036f3cf0..f2e399aaf 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -37,25 +37,25 @@ module eth_axis_rx /* * AXI input */ - input wire [7:0] input_axis_tdata, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [7:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [7:0] m_eth_payload_axis_tdata, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * Status signals @@ -104,30 +104,30 @@ reg store_eth_type_1; reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; +reg m_eth_hdr_valid_reg = 1'b0, m_eth_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; reg busy_reg = 1'b0; reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; // internal datapath -reg [7:0] output_eth_payload_tdata_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; +reg [7:0] m_eth_payload_axis_tdata_int; +reg m_eth_payload_axis_tvalid_int; +reg m_eth_payload_axis_tready_int_reg = 1'b0; +reg m_eth_payload_axis_tlast_int; +reg m_eth_payload_axis_tuser_int; +wire m_eth_payload_axis_tready_int_early; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; +assign m_eth_hdr_valid = m_eth_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -135,7 +135,7 @@ assign error_header_early_termination = error_header_early_termination_reg; always @* begin state_next = STATE_IDLE; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; store_eth_dest_mac_0 = 1'b0; store_eth_dest_mac_1 = 1'b0; @@ -154,24 +154,24 @@ always @* begin frame_ptr_next = frame_ptr_reg; - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; error_header_early_termination_next = 1'b0; - output_eth_payload_tdata_int = 8'd0; - output_eth_payload_tvalid_int = 1'b0; - output_eth_payload_tlast_int = 1'b0; - output_eth_payload_tuser_int = 1'b0; + m_eth_payload_axis_tdata_int = 8'd0; + m_eth_payload_axis_tvalid_int = 1'b0; + m_eth_payload_axis_tlast_int = 1'b0; + m_eth_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; - input_axis_tready_next = ~output_eth_hdr_valid_reg; + s_axis_tready_next = !m_eth_hdr_valid_reg; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // got first word of packet - if (input_axis_tlast) begin + if (s_axis_tlast) begin // tlast asserted on first word error_header_early_termination_next = 1'b1; state_next = STATE_IDLE; @@ -187,9 +187,9 @@ always @* begin end STATE_READ_HEADER: begin // read header - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg + 8'd1; state_next = STATE_READ_HEADER; @@ -209,14 +209,14 @@ always @* begin 8'h0C: store_eth_type_1 = 1'b1; 8'h0D: begin store_eth_type_0 = 1'b1; - output_eth_hdr_valid_next = 1'b1; - input_axis_tready_next = output_eth_payload_tready_int_early; + m_eth_hdr_valid_next = 1'b1; + s_axis_tready_next = m_eth_payload_axis_tready_int_early; state_next = STATE_READ_PAYLOAD; end endcase - if (input_axis_tlast) begin + if (s_axis_tlast) begin error_header_early_termination_next = 1'b1; - input_axis_tready_next = ~output_eth_hdr_valid_reg; + s_axis_tready_next = !m_eth_hdr_valid_reg; state_next = STATE_IDLE; end end else begin @@ -225,17 +225,17 @@ always @* begin end STATE_READ_PAYLOAD: begin // read payload - input_axis_tready_next = output_eth_payload_tready_int_early; + s_axis_tready_next = m_eth_payload_axis_tready_int_early; - output_eth_payload_tdata_int = input_axis_tdata; - output_eth_payload_tvalid_int = input_axis_tvalid; - output_eth_payload_tlast_int = input_axis_tlast; - output_eth_payload_tuser_int = input_axis_tuser; + m_eth_payload_axis_tdata_int = s_axis_tdata; + m_eth_payload_axis_tvalid_int = s_axis_tvalid; + m_eth_payload_axis_tlast_int = s_axis_tlast; + m_eth_payload_axis_tuser_int = s_axis_tuser; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // word transfer through - if (input_axis_tlast) begin - input_axis_tready_next = ~output_eth_hdr_valid_reg; + if (s_axis_tlast) begin + s_axis_tready_next = !m_eth_hdr_valid_reg; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD; @@ -251,8 +251,8 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 8'd0; - input_axis_tready_reg <= 1'b0; - output_eth_hdr_valid_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; + m_eth_hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; error_header_early_termination_reg <= 1'b0; end else begin @@ -260,9 +260,9 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; @@ -270,100 +270,100 @@ always @(posedge clk) begin end // datapath - if (store_eth_dest_mac_0) output_eth_dest_mac_reg[ 7: 0] <= input_axis_tdata; - if (store_eth_dest_mac_1) output_eth_dest_mac_reg[15: 8] <= input_axis_tdata; - if (store_eth_dest_mac_2) output_eth_dest_mac_reg[23:16] <= input_axis_tdata; - if (store_eth_dest_mac_3) output_eth_dest_mac_reg[31:24] <= input_axis_tdata; - if (store_eth_dest_mac_4) output_eth_dest_mac_reg[39:32] <= input_axis_tdata; - if (store_eth_dest_mac_5) output_eth_dest_mac_reg[47:40] <= input_axis_tdata; - if (store_eth_src_mac_0) output_eth_src_mac_reg[ 7: 0] <= input_axis_tdata; - if (store_eth_src_mac_1) output_eth_src_mac_reg[15: 8] <= input_axis_tdata; - if (store_eth_src_mac_2) output_eth_src_mac_reg[23:16] <= input_axis_tdata; - if (store_eth_src_mac_3) output_eth_src_mac_reg[31:24] <= input_axis_tdata; - if (store_eth_src_mac_4) output_eth_src_mac_reg[39:32] <= input_axis_tdata; - if (store_eth_src_mac_5) output_eth_src_mac_reg[47:40] <= input_axis_tdata; - if (store_eth_type_0) output_eth_type_reg[ 7: 0] <= input_axis_tdata; - if (store_eth_type_1) output_eth_type_reg[15: 8] <= input_axis_tdata; + if (store_eth_dest_mac_0) m_eth_dest_mac_reg[ 7: 0] <= s_axis_tdata; + if (store_eth_dest_mac_1) m_eth_dest_mac_reg[15: 8] <= s_axis_tdata; + if (store_eth_dest_mac_2) m_eth_dest_mac_reg[23:16] <= s_axis_tdata; + if (store_eth_dest_mac_3) m_eth_dest_mac_reg[31:24] <= s_axis_tdata; + if (store_eth_dest_mac_4) m_eth_dest_mac_reg[39:32] <= s_axis_tdata; + if (store_eth_dest_mac_5) m_eth_dest_mac_reg[47:40] <= s_axis_tdata; + if (store_eth_src_mac_0) m_eth_src_mac_reg[ 7: 0] <= s_axis_tdata; + if (store_eth_src_mac_1) m_eth_src_mac_reg[15: 8] <= s_axis_tdata; + if (store_eth_src_mac_2) m_eth_src_mac_reg[23:16] <= s_axis_tdata; + if (store_eth_src_mac_3) m_eth_src_mac_reg[31:24] <= s_axis_tdata; + if (store_eth_src_mac_4) m_eth_src_mac_reg[39:32] <= s_axis_tdata; + if (store_eth_src_mac_5) m_eth_src_mac_reg[47:40] <= s_axis_tdata; + if (store_eth_type_0) m_eth_type_reg[ 7: 0] <= s_axis_tdata; + if (store_eth_type_1) m_eth_type_reg[15: 8] <= s_axis_tdata; end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; +reg [7:0] m_eth_payload_axis_tdata_reg = 8'd0; +reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; +reg m_eth_payload_axis_tlast_reg = 1'b0; +reg m_eth_payload_axis_tuser_reg = 1'b0; -reg [7:0] temp_eth_payload_tdata_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; +reg [7:0] temp_m_eth_payload_axis_tdata_reg = 8'd0; +reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; +reg temp_m_eth_payload_axis_tlast_reg = 1'b0; +reg temp_m_eth_payload_axis_tuser_reg = 1'b0; // datapath control reg store_eth_payload_int_to_output; reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; +reg store_eth_payload_axis_temp_to_output; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; +assign m_eth_payload_axis_tdata = m_eth_payload_axis_tdata_reg; +assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; +assign m_eth_payload_axis_tlast = m_eth_payload_axis_tlast_reg; +assign m_eth_payload_axis_tuser = m_eth_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); +assign m_eth_payload_axis_tready_int_early = m_eth_payload_axis_tready || (!temp_m_eth_payload_axis_tvalid_reg && (!m_eth_payload_axis_tvalid_reg || !m_eth_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; store_eth_payload_int_to_output = 1'b0; store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b0; - if (output_eth_payload_tready_int_reg) begin + if (m_eth_payload_axis_tready_int_reg) begin // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + if (m_eth_payload_axis_tready || !m_eth_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + temp_m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_temp = 1'b1; end - end else if (output_eth_payload_tready) begin + end else if (m_eth_payload_axis_tready) begin // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; + m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; + m_eth_payload_axis_tvalid_reg <= 1'b0; + m_eth_payload_axis_tready_int_reg <= 1'b0; + temp_m_eth_payload_axis_tvalid_reg <= 1'b0; end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + m_eth_payload_axis_tvalid_reg <= m_eth_payload_axis_tvalid_next; + m_eth_payload_axis_tready_int_reg <= m_eth_payload_axis_tready_int_early; + temp_m_eth_payload_axis_tvalid_reg <= temp_m_eth_payload_axis_tvalid_next; end // datapath if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end else if (store_eth_payload_axis_temp_to_output) begin + m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; + m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; + m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; end if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; end end diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index 932adee76..a9928c0f8 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -37,27 +37,27 @@ module eth_axis_rx_64 /* * AXI input */ - input wire [63:0] input_axis_tdata, - input wire [7:0] input_axis_tkeep, - input wire input_axis_tvalid, - output wire input_axis_tready, - input wire input_axis_tlast, - input wire input_axis_tuser, + input wire [63:0] s_axis_tdata, + input wire [7:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [63:0] m_eth_payload_axis_tdata, + output wire [7:0] m_eth_payload_axis_tkeep, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * Status signals @@ -97,12 +97,12 @@ reg transfer_in_save; reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; -reg input_axis_tready_reg = 1'b0, input_axis_tready_next; +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; +reg m_eth_hdr_valid_reg = 1'b0, m_eth_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; reg busy_reg = 1'b0; reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; @@ -117,24 +117,24 @@ reg [7:0] shift_axis_tkeep; reg shift_axis_tvalid; reg shift_axis_tlast; reg shift_axis_tuser; -reg shift_axis_input_tready; +reg shift_axis_s_tready; reg shift_axis_extra_cycle; // internal datapath -reg [63:0] output_eth_payload_tdata_int; -reg [7:0] output_eth_payload_tkeep_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; +reg [63:0] m_eth_payload_axis_tdata_int; +reg [7:0] m_eth_payload_axis_tkeep_int; +reg m_eth_payload_axis_tvalid_int; +reg m_eth_payload_axis_tready_int_reg = 1'b0; +reg m_eth_payload_axis_tlast_int; +reg m_eth_payload_axis_tuser_int; +wire m_eth_payload_axis_tready_int_early; -assign input_axis_tready = input_axis_tready_reg; +assign s_axis_tready = s_axis_tready_reg; -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; +assign m_eth_hdr_valid = m_eth_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -142,7 +142,7 @@ assign error_header_early_termination = error_header_early_termination_reg; always @* begin shift_axis_tdata[15:0] = save_axis_tdata_reg[63:48]; shift_axis_tkeep[1:0] = save_axis_tkeep_reg[7:6]; - shift_axis_extra_cycle = save_axis_tlast_reg & (save_axis_tkeep_reg[7:6] != 0); + shift_axis_extra_cycle = save_axis_tlast_reg && (save_axis_tkeep_reg[7:6] != 0); if (shift_axis_extra_cycle) begin shift_axis_tdata[63:16] = 48'd0; @@ -150,21 +150,21 @@ always @* begin shift_axis_tvalid = 1'b1; shift_axis_tlast = save_axis_tlast_reg; shift_axis_tuser = save_axis_tuser_reg; - shift_axis_input_tready = flush_save; + shift_axis_s_tready = flush_save; end else begin - shift_axis_tdata[63:16] = input_axis_tdata[47:0]; - shift_axis_tkeep[7:2] = input_axis_tkeep[5:0]; - shift_axis_tvalid = input_axis_tvalid; - shift_axis_tlast = (input_axis_tlast & (input_axis_tkeep[7:6] == 0)); - shift_axis_tuser = (input_axis_tuser & (input_axis_tkeep[7:6] == 0)); - shift_axis_input_tready = ~(input_axis_tlast & input_axis_tvalid & transfer_in_save); + shift_axis_tdata[63:16] = s_axis_tdata[47:0]; + shift_axis_tkeep[7:2] = s_axis_tkeep[5:0]; + shift_axis_tvalid = s_axis_tvalid; + shift_axis_tlast = (s_axis_tlast && (s_axis_tkeep[7:6] == 0)); + shift_axis_tuser = (s_axis_tuser && (s_axis_tkeep[7:6] == 0)); + shift_axis_s_tready = !(s_axis_tlast && s_axis_tvalid && transfer_in_save); end end always @* begin state_next = STATE_IDLE; - input_axis_tready_next = 1'b0; + s_axis_tready_next = 1'b0; flush_save = 1'b0; transfer_in_save = 1'b0; @@ -174,26 +174,26 @@ always @* begin frame_ptr_next = frame_ptr_reg; - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; error_header_early_termination_next = 1'b0; - output_eth_payload_tdata_int = 64'd0; - output_eth_payload_tkeep_int = 8'd0; - output_eth_payload_tvalid_int = 1'b0; - output_eth_payload_tlast_int = 1'b0; - output_eth_payload_tuser_int = 1'b0; + m_eth_payload_axis_tdata_int = 64'd0; + m_eth_payload_axis_tkeep_int = 8'd0; + m_eth_payload_axis_tvalid_int = 1'b0; + m_eth_payload_axis_tlast_int = 1'b0; + m_eth_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; flush_save = 1'b1; - input_axis_tready_next = ~output_eth_hdr_valid_reg; + s_axis_tready_next = !m_eth_hdr_valid_reg; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // got first word of packet - if (input_axis_tlast) begin + if (s_axis_tlast) begin // tlast asserted on first word error_header_early_termination_next = 1'b1; state_next = STATE_IDLE; @@ -210,9 +210,9 @@ always @* begin end STATE_READ_HEADER: begin // read header state - input_axis_tready_next = 1'b1; + s_axis_tready_next = 1'b1; - if (input_axis_tready & input_axis_tvalid) begin + if (s_axis_tready && s_axis_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg + 8'd8; transfer_in_save = 1'b1; @@ -221,20 +221,20 @@ always @* begin 8'h00: store_hdr_word_0 = 1'b1; 8'h08: begin store_hdr_word_1 = 1'b1; - output_eth_hdr_valid_next = 1'b1; - input_axis_tready_next = output_eth_payload_tready_int_early; + m_eth_hdr_valid_next = 1'b1; + s_axis_tready_next = m_eth_payload_axis_tready_int_early; state_next = STATE_READ_PAYLOAD; end endcase - if (input_axis_tlast) begin - if (input_axis_tkeep[7:6] != 2'd0) begin - input_axis_tready_next = 1'b0; + if (s_axis_tlast) begin + if (s_axis_tkeep[7:6] != 2'd0) begin + s_axis_tready_next = 1'b0; state_next = STATE_READ_PAYLOAD; end else begin flush_save = 1'b1; - output_eth_hdr_valid_next = 1'b0; + m_eth_hdr_valid_next = 1'b0; error_header_early_termination_next = 1'b1; - input_axis_tready_next = ~output_eth_hdr_valid_reg; + s_axis_tready_next = !m_eth_hdr_valid_reg; state_next = STATE_IDLE; end end @@ -244,20 +244,20 @@ always @* begin end STATE_READ_PAYLOAD: begin // read payload - input_axis_tready_next = output_eth_payload_tready_int_early & shift_axis_input_tready; + s_axis_tready_next = m_eth_payload_axis_tready_int_early && shift_axis_s_tready; - output_eth_payload_tdata_int = shift_axis_tdata; - output_eth_payload_tkeep_int = shift_axis_tkeep; - output_eth_payload_tvalid_int = shift_axis_tvalid; - output_eth_payload_tlast_int = shift_axis_tlast; - output_eth_payload_tuser_int = shift_axis_tuser; + m_eth_payload_axis_tdata_int = shift_axis_tdata; + m_eth_payload_axis_tkeep_int = shift_axis_tkeep; + m_eth_payload_axis_tvalid_int = shift_axis_tvalid; + m_eth_payload_axis_tlast_int = shift_axis_tlast; + m_eth_payload_axis_tuser_int = shift_axis_tuser; - if (output_eth_payload_tready_int_reg & shift_axis_tvalid) begin + if (m_eth_payload_axis_tready_int_reg && shift_axis_tvalid) begin // word transfer through transfer_in_save = 1'b1; if (shift_axis_tlast) begin flush_save = 1'b1; - input_axis_tready_next = ~output_eth_hdr_valid_reg; + s_axis_tready_next = !m_eth_hdr_valid_reg; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD; @@ -273,8 +273,8 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 8'd0; - input_axis_tready_reg <= 1'b0; - output_eth_hdr_valid_reg <= 1'b0; + s_axis_tready_reg <= 1'b0; + m_eth_hdr_valid_reg <= 1'b0; save_axis_tlast_reg <= 1'b0; busy_reg <= 1'b0; error_header_early_termination_reg <= 1'b0; @@ -283,9 +283,9 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; - input_axis_tready_reg <= input_axis_tready_next; + s_axis_tready_reg <= s_axis_tready_next; - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; @@ -294,121 +294,121 @@ always @(posedge clk) begin if (flush_save) begin save_axis_tlast_reg <= 1'b0; end else if (transfer_in_save) begin - save_axis_tlast_reg <= input_axis_tlast; + save_axis_tlast_reg <= s_axis_tlast; end end // datapath if (store_hdr_word_0) begin - output_eth_dest_mac_reg[47:40] <= input_axis_tdata[ 7: 0]; - output_eth_dest_mac_reg[39:32] <= input_axis_tdata[15: 8]; - output_eth_dest_mac_reg[31:24] <= input_axis_tdata[23:16]; - output_eth_dest_mac_reg[23:16] <= input_axis_tdata[31:24]; - output_eth_dest_mac_reg[15: 8] <= input_axis_tdata[39:32]; - output_eth_dest_mac_reg[ 7: 0] <= input_axis_tdata[47:40]; - output_eth_src_mac_reg[47:40] <= input_axis_tdata[55:48]; - output_eth_src_mac_reg[39:32] <= input_axis_tdata[63:56]; + m_eth_dest_mac_reg[47:40] <= s_axis_tdata[ 7: 0]; + m_eth_dest_mac_reg[39:32] <= s_axis_tdata[15: 8]; + m_eth_dest_mac_reg[31:24] <= s_axis_tdata[23:16]; + m_eth_dest_mac_reg[23:16] <= s_axis_tdata[31:24]; + m_eth_dest_mac_reg[15: 8] <= s_axis_tdata[39:32]; + m_eth_dest_mac_reg[ 7: 0] <= s_axis_tdata[47:40]; + m_eth_src_mac_reg[47:40] <= s_axis_tdata[55:48]; + m_eth_src_mac_reg[39:32] <= s_axis_tdata[63:56]; end if (store_hdr_word_1) begin - output_eth_src_mac_reg[31:24] <= input_axis_tdata[ 7: 0]; - output_eth_src_mac_reg[23:16] <= input_axis_tdata[15: 8]; - output_eth_src_mac_reg[15: 8] <= input_axis_tdata[23:16]; - output_eth_src_mac_reg[ 7: 0] <= input_axis_tdata[31:24]; - output_eth_type_reg[15:8] <= input_axis_tdata[39:32]; - output_eth_type_reg[ 7:0] <= input_axis_tdata[47:40]; + m_eth_src_mac_reg[31:24] <= s_axis_tdata[ 7: 0]; + m_eth_src_mac_reg[23:16] <= s_axis_tdata[15: 8]; + m_eth_src_mac_reg[15: 8] <= s_axis_tdata[23:16]; + m_eth_src_mac_reg[ 7: 0] <= s_axis_tdata[31:24]; + m_eth_type_reg[15:8] <= s_axis_tdata[39:32]; + m_eth_type_reg[ 7:0] <= s_axis_tdata[47:40]; end if (transfer_in_save) begin - save_axis_tdata_reg <= input_axis_tdata; - save_axis_tkeep_reg <= input_axis_tkeep; - save_axis_tuser_reg <= input_axis_tuser; + save_axis_tdata_reg <= s_axis_tdata; + save_axis_tkeep_reg <= s_axis_tkeep; + save_axis_tuser_reg <= s_axis_tuser; end end // output datapath logic -reg [64:0] output_eth_payload_tdata_reg = 64'd0; -reg [7:0] output_eth_payload_tkeep_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; +reg [64:0] m_eth_payload_axis_tdata_reg = 64'd0; +reg [7:0] m_eth_payload_axis_tkeep_reg = 8'd0; +reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; +reg m_eth_payload_axis_tlast_reg = 1'b0; +reg m_eth_payload_axis_tuser_reg = 1'b0; -reg [64:0] temp_eth_payload_tdata_reg = 64'd0; -reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; +reg [64:0] temp_m_eth_payload_axis_tdata_reg = 64'd0; +reg [7:0] temp_m_eth_payload_axis_tkeep_reg = 8'd0; +reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; +reg temp_m_eth_payload_axis_tlast_reg = 1'b0; +reg temp_m_eth_payload_axis_tuser_reg = 1'b0; // datapath control reg store_eth_payload_int_to_output; reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; +reg store_eth_payload_axis_temp_to_output; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; +assign m_eth_payload_axis_tdata = m_eth_payload_axis_tdata_reg; +assign m_eth_payload_axis_tkeep = m_eth_payload_axis_tkeep_reg; +assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; +assign m_eth_payload_axis_tlast = m_eth_payload_axis_tlast_reg; +assign m_eth_payload_axis_tuser = m_eth_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); +assign m_eth_payload_axis_tready_int_early = m_eth_payload_axis_tready || (!temp_m_eth_payload_axis_tvalid_reg && (!m_eth_payload_axis_tvalid_reg || !m_eth_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; store_eth_payload_int_to_output = 1'b0; store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b0; - if (output_eth_payload_tready_int_reg) begin + if (m_eth_payload_axis_tready_int_reg) begin // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + if (m_eth_payload_axis_tready || !m_eth_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + temp_m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_temp = 1'b1; end - end else if (output_eth_payload_tready) begin + end else if (m_eth_payload_axis_tready) begin // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; + m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; + m_eth_payload_axis_tvalid_reg <= 1'b0; + m_eth_payload_axis_tready_int_reg <= 1'b0; + temp_m_eth_payload_axis_tvalid_reg <= 1'b0; end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + m_eth_payload_axis_tvalid_reg <= m_eth_payload_axis_tvalid_next; + m_eth_payload_axis_tready_int_reg <= m_eth_payload_axis_tready_int_early; + temp_m_eth_payload_axis_tvalid_reg <= temp_m_eth_payload_axis_tvalid_next; end // datapath if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end else if (store_eth_payload_axis_temp_to_output) begin + m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; + m_eth_payload_axis_tkeep_reg <= temp_m_eth_payload_axis_tkeep_reg; + m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; + m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; end if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + temp_m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; end end diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index ab09c79cd..55388f278 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -37,25 +37,25 @@ module eth_axis_tx /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [7:0] input_eth_payload_tdata, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [7:0] s_eth_payload_axis_tdata, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * AXI output */ - output wire [7:0] output_axis_tdata, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [7:0] m_axis_tdata, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Status signals @@ -94,51 +94,51 @@ reg [47:0] eth_dest_mac_reg = 48'd0; reg [47:0] eth_src_mac_reg = 48'd0; reg [15:0] eth_type_reg = 16'd0; -reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; +reg s_eth_hdr_ready_reg = 1'b0, s_eth_hdr_ready_next; +reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; reg busy_reg = 1'b0; // internal datapath -reg [7:0] output_axis_tdata_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [7:0] m_axis_tdata_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; -assign input_eth_hdr_ready = input_eth_hdr_ready_reg; -assign input_eth_payload_tready = input_eth_payload_tready_reg; +assign s_eth_hdr_ready = s_eth_hdr_ready_reg; +assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; assign busy = busy_reg; always @* begin state_next = STATE_IDLE; - input_eth_hdr_ready_next = 1'b0; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b0; store_eth_hdr = 1'b0; frame_ptr_next = frame_ptr_reg; - output_axis_tdata_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 8'd0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; - input_eth_hdr_ready_next = 1'b1; + s_eth_hdr_ready_next = 1'b1; - if (input_eth_hdr_ready & input_eth_hdr_valid) begin + if (s_eth_hdr_ready && s_eth_hdr_valid) begin store_eth_hdr = 1'b1; - input_eth_hdr_ready_next = 1'b0; - if (output_axis_tready_int_reg) begin - output_axis_tvalid_int = 1'b1; - output_axis_tdata_int = input_eth_dest_mac[47:40]; + s_eth_hdr_ready_next = 1'b0; + if (m_axis_tready_int_reg) begin + m_axis_tvalid_int = 1'b1; + m_axis_tdata_int = s_eth_dest_mac[47:40]; frame_ptr_next = 1'b1; end state_next = STATE_WRITE_HEADER; @@ -148,27 +148,27 @@ always @* begin end STATE_WRITE_HEADER: begin // write header - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin frame_ptr_next = frame_ptr_reg+1; - output_axis_tvalid_int = 1'b1; + m_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) - 8'h00: output_axis_tdata_int = eth_dest_mac_reg[47:40]; - 8'h01: output_axis_tdata_int = eth_dest_mac_reg[39:32]; - 8'h02: output_axis_tdata_int = eth_dest_mac_reg[31:24]; - 8'h03: output_axis_tdata_int = eth_dest_mac_reg[23:16]; - 8'h04: output_axis_tdata_int = eth_dest_mac_reg[15: 8]; - 8'h05: output_axis_tdata_int = eth_dest_mac_reg[ 7: 0]; - 8'h06: output_axis_tdata_int = eth_src_mac_reg[47:40]; - 8'h07: output_axis_tdata_int = eth_src_mac_reg[39:32]; - 8'h08: output_axis_tdata_int = eth_src_mac_reg[31:24]; - 8'h09: output_axis_tdata_int = eth_src_mac_reg[23:16]; - 8'h0A: output_axis_tdata_int = eth_src_mac_reg[15: 8]; - 8'h0B: output_axis_tdata_int = eth_src_mac_reg[ 7: 0]; - 8'h0C: output_axis_tdata_int = eth_type_reg[15: 8]; + 8'h00: m_axis_tdata_int = eth_dest_mac_reg[47:40]; + 8'h01: m_axis_tdata_int = eth_dest_mac_reg[39:32]; + 8'h02: m_axis_tdata_int = eth_dest_mac_reg[31:24]; + 8'h03: m_axis_tdata_int = eth_dest_mac_reg[23:16]; + 8'h04: m_axis_tdata_int = eth_dest_mac_reg[15: 8]; + 8'h05: m_axis_tdata_int = eth_dest_mac_reg[ 7: 0]; + 8'h06: m_axis_tdata_int = eth_src_mac_reg[47:40]; + 8'h07: m_axis_tdata_int = eth_src_mac_reg[39:32]; + 8'h08: m_axis_tdata_int = eth_src_mac_reg[31:24]; + 8'h09: m_axis_tdata_int = eth_src_mac_reg[23:16]; + 8'h0A: m_axis_tdata_int = eth_src_mac_reg[15: 8]; + 8'h0B: m_axis_tdata_int = eth_src_mac_reg[ 7: 0]; + 8'h0C: m_axis_tdata_int = eth_type_reg[15: 8]; 8'h0D: begin - output_axis_tdata_int = eth_type_reg[ 7: 0]; - input_eth_payload_tready_next = output_axis_tready_int_early; + m_axis_tdata_int = eth_type_reg[ 7: 0]; + s_eth_payload_axis_tready_next = m_axis_tready_int_early; state_next = STATE_WRITE_PAYLOAD; end endcase @@ -178,18 +178,18 @@ always @* begin end STATE_WRITE_PAYLOAD: begin // write payload - input_eth_payload_tready_next = output_axis_tready_int_early; + s_eth_payload_axis_tready_next = m_axis_tready_int_early; - output_axis_tdata_int = input_eth_payload_tdata; - output_axis_tvalid_int = input_eth_payload_tvalid; - output_axis_tlast_int = input_eth_payload_tlast; - output_axis_tuser_int = input_eth_payload_tuser; + m_axis_tdata_int = s_eth_payload_axis_tdata; + m_axis_tvalid_int = s_eth_payload_axis_tvalid; + m_axis_tlast_int = s_eth_payload_axis_tlast; + m_axis_tuser_int = s_eth_payload_axis_tuser; - if (input_eth_payload_tready & input_eth_payload_tvalid) begin + if (s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) begin // word transfer through - if (input_eth_payload_tlast) begin - input_eth_payload_tready_next = 1'b0; - input_eth_hdr_ready_next = 1'b1; + if (s_eth_payload_axis_tlast) begin + s_eth_payload_axis_tready_next = 1'b0; + s_eth_hdr_ready_next = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -205,107 +205,107 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 8'd0; - input_eth_hdr_ready_reg <= 1'b0; - input_eth_payload_tready_reg <= 1'b0; + s_eth_hdr_ready_reg <= 1'b0; + s_eth_payload_axis_tready_reg <= 1'b0; busy_reg <= 1'b0; end else begin state_reg <= state_next; frame_ptr_reg <= frame_ptr_next; - input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; - input_eth_payload_tready_reg <= input_eth_payload_tready_next; + s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; busy_reg <= state_next != STATE_IDLE; end // datapath if (store_eth_hdr) begin - eth_dest_mac_reg <= input_eth_dest_mac; - eth_src_mac_reg <= input_eth_src_mac; - eth_type_reg <= input_eth_type; + eth_dest_mac_reg <= s_eth_dest_mac; + eth_src_mac_reg <= s_eth_src_mac; + eth_type_reg <= s_eth_type; end end // output datapath logic -reg [7:0] output_axis_tdata_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg [7:0] m_axis_tdata_reg = 8'd0; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; -reg [7:0] temp_axis_tdata_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg [7:0] temp_m_axis_tdata_reg = 8'd0; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index a74e182eb..c9abf9a00 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -37,27 +37,27 @@ module eth_axis_tx_64 /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [63:0] input_eth_payload_tdata, - input wire [7:0] input_eth_payload_tkeep, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [63:0] s_eth_payload_axis_tdata, + input wire [7:0] s_eth_payload_axis_tkeep, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * AXI output */ - output wire [63:0] output_axis_tdata, - output wire [7:0] output_axis_tkeep, - output wire output_axis_tvalid, - input wire output_axis_tready, - output wire output_axis_tlast, - output wire output_axis_tuser, + output wire [63:0] m_axis_tdata, + output wire [7:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Status signals @@ -100,65 +100,65 @@ reg [47:0] eth_dest_mac_reg = 48'd0; reg [47:0] eth_src_mac_reg = 48'd0; reg [15:0] eth_type_reg = 16'd0; -reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; +reg s_eth_hdr_ready_reg = 1'b0, s_eth_hdr_ready_next; +reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; reg busy_reg = 1'b0; -reg [63:0] save_eth_payload_tdata_reg = 64'd0; -reg [7:0] save_eth_payload_tkeep_reg = 8'd0; -reg save_eth_payload_tlast_reg = 1'b0; -reg save_eth_payload_tuser_reg = 1'b0; +reg [63:0] save_eth_payload_axis_tdata_reg = 64'd0; +reg [7:0] save_eth_payload_axis_tkeep_reg = 8'd0; +reg save_eth_payload_axis_tlast_reg = 1'b0; +reg save_eth_payload_axis_tuser_reg = 1'b0; -reg [63:0] shift_eth_payload_tdata; -reg [7:0] shift_eth_payload_tkeep; -reg shift_eth_payload_tvalid; -reg shift_eth_payload_tlast; -reg shift_eth_payload_tuser; -reg shift_eth_payload_input_tready; +reg [63:0] shift_eth_payload_axis_tdata; +reg [7:0] shift_eth_payload_axis_tkeep; +reg shift_eth_payload_axis_tvalid; +reg shift_eth_payload_axis_tlast; +reg shift_eth_payload_axis_tuser; +reg shift_eth_payload_s_tready; reg shift_eth_payload_extra_cycle; // internal datapath -reg [63:0] output_axis_tdata_int; -reg [7:0] output_axis_tkeep_int; -reg output_axis_tvalid_int; -reg output_axis_tready_int_reg = 1'b0; -reg output_axis_tlast_int; -reg output_axis_tuser_int; -wire output_axis_tready_int_early; +reg [63:0] m_axis_tdata_int; +reg [7:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; -assign input_eth_hdr_ready = input_eth_hdr_ready_reg; -assign input_eth_payload_tready = input_eth_payload_tready_reg; +assign s_eth_hdr_ready = s_eth_hdr_ready_reg; +assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; assign busy = busy_reg; always @* begin - shift_eth_payload_tdata[47:0] = save_eth_payload_tdata_reg[63:16]; - shift_eth_payload_tkeep[5:0] = save_eth_payload_tkeep_reg[7:2]; - shift_eth_payload_extra_cycle = save_eth_payload_tlast_reg & (save_eth_payload_tkeep_reg[7:2] != 0); + shift_eth_payload_axis_tdata[47:0] = save_eth_payload_axis_tdata_reg[63:16]; + shift_eth_payload_axis_tkeep[5:0] = save_eth_payload_axis_tkeep_reg[7:2]; + shift_eth_payload_extra_cycle = save_eth_payload_axis_tlast_reg && (save_eth_payload_axis_tkeep_reg[7:2] != 0); if (shift_eth_payload_extra_cycle) begin - shift_eth_payload_tdata[63:48] = 16'd0; - shift_eth_payload_tkeep[7:6] = 2'd0; - shift_eth_payload_tvalid = 1'b1; - shift_eth_payload_tlast = save_eth_payload_tlast_reg; - shift_eth_payload_tuser = save_eth_payload_tuser_reg; - shift_eth_payload_input_tready = flush_save; + shift_eth_payload_axis_tdata[63:48] = 16'd0; + shift_eth_payload_axis_tkeep[7:6] = 2'd0; + shift_eth_payload_axis_tvalid = 1'b1; + shift_eth_payload_axis_tlast = save_eth_payload_axis_tlast_reg; + shift_eth_payload_axis_tuser = save_eth_payload_axis_tuser_reg; + shift_eth_payload_s_tready = flush_save; end else begin - shift_eth_payload_tdata[63:48] = input_eth_payload_tdata[15:0]; - shift_eth_payload_tkeep[7:6] = input_eth_payload_tkeep[1:0]; - shift_eth_payload_tvalid = input_eth_payload_tvalid; - shift_eth_payload_tlast = (input_eth_payload_tlast & (input_eth_payload_tkeep[7:2] == 0)); - shift_eth_payload_tuser = (input_eth_payload_tuser & (input_eth_payload_tkeep[7:2] == 0)); - shift_eth_payload_input_tready = ~(input_eth_payload_tlast & input_eth_payload_tvalid & transfer_in_save); + shift_eth_payload_axis_tdata[63:48] = s_eth_payload_axis_tdata[15:0]; + shift_eth_payload_axis_tkeep[7:6] = s_eth_payload_axis_tkeep[1:0]; + shift_eth_payload_axis_tvalid = s_eth_payload_axis_tvalid; + shift_eth_payload_axis_tlast = (s_eth_payload_axis_tlast && (s_eth_payload_axis_tkeep[7:2] == 0)); + shift_eth_payload_axis_tuser = (s_eth_payload_axis_tuser && (s_eth_payload_axis_tkeep[7:2] == 0)); + shift_eth_payload_s_tready = !(s_eth_payload_axis_tlast && s_eth_payload_axis_tvalid && transfer_in_save); end end always @* begin state_next = STATE_IDLE; - input_eth_hdr_ready_next = 1'b0; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b0; store_eth_hdr = 1'b0; @@ -167,36 +167,36 @@ always @* begin frame_ptr_next = frame_ptr_reg; - output_axis_tdata_int = 64'd0; - output_axis_tkeep_int = 8'd0; - output_axis_tvalid_int = 1'b0; - output_axis_tlast_int = 1'b0; - output_axis_tuser_int = 1'b0; + m_axis_tdata_int = 64'd0; + m_axis_tkeep_int = 8'd0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; flush_save = 1'b1; - input_eth_hdr_ready_next = 1'b1; + s_eth_hdr_ready_next = 1'b1; - if (input_eth_hdr_ready & input_eth_hdr_valid) begin + if (s_eth_hdr_ready && s_eth_hdr_valid) begin store_eth_hdr = 1'b1; - input_eth_hdr_ready_next = 1'b0; + s_eth_hdr_ready_next = 1'b0; state_next = STATE_WRITE_HEADER; - if (output_axis_tready_int_reg) begin - output_axis_tvalid_int = 1'b1; - output_axis_tdata_int[ 7: 0] = input_eth_dest_mac[47:40]; - output_axis_tdata_int[15: 8] = input_eth_dest_mac[39:32]; - output_axis_tdata_int[23:16] = input_eth_dest_mac[31:24]; - output_axis_tdata_int[31:24] = input_eth_dest_mac[23:16]; - output_axis_tdata_int[39:32] = input_eth_dest_mac[15: 8]; - output_axis_tdata_int[47:40] = input_eth_dest_mac[ 7: 0]; - output_axis_tdata_int[55:48] = input_eth_src_mac[47:40]; - output_axis_tdata_int[63:56] = input_eth_src_mac[39:32]; - output_axis_tkeep_int = 8'hff; + if (m_axis_tready_int_reg) begin + m_axis_tvalid_int = 1'b1; + m_axis_tdata_int[ 7: 0] = s_eth_dest_mac[47:40]; + m_axis_tdata_int[15: 8] = s_eth_dest_mac[39:32]; + m_axis_tdata_int[23:16] = s_eth_dest_mac[31:24]; + m_axis_tdata_int[31:24] = s_eth_dest_mac[23:16]; + m_axis_tdata_int[39:32] = s_eth_dest_mac[15: 8]; + m_axis_tdata_int[47:40] = s_eth_dest_mac[ 7: 0]; + m_axis_tdata_int[55:48] = s_eth_src_mac[47:40]; + m_axis_tdata_int[63:56] = s_eth_src_mac[39:32]; + m_axis_tkeep_int = 8'hff; frame_ptr_next = 8'd8; - input_eth_payload_tready_next = output_axis_tready_int_early; + s_eth_payload_axis_tready_next = m_axis_tready_int_early; state_next = STATE_WRITE_HEADER_LAST; end end else begin @@ -205,22 +205,22 @@ always @* begin end STATE_WRITE_HEADER: begin // write header - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin frame_ptr_next = frame_ptr_reg + 8'd8; - output_axis_tvalid_int = 1'b1; + m_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 5'd00: begin - output_axis_tdata_int[ 7: 0] = input_eth_dest_mac[47:40]; - output_axis_tdata_int[15: 8] = input_eth_dest_mac[39:32]; - output_axis_tdata_int[23:16] = input_eth_dest_mac[31:24]; - output_axis_tdata_int[31:24] = input_eth_dest_mac[23:16]; - output_axis_tdata_int[39:32] = input_eth_dest_mac[15: 8]; - output_axis_tdata_int[47:40] = input_eth_dest_mac[ 7: 0]; - output_axis_tdata_int[55:48] = input_eth_src_mac[47:40]; - output_axis_tdata_int[63:56] = input_eth_src_mac[39:32]; - output_axis_tkeep_int = 8'hff; - input_eth_payload_tready_next = output_axis_tready_int_early & shift_eth_payload_input_tready; + m_axis_tdata_int[ 7: 0] = s_eth_dest_mac[47:40]; + m_axis_tdata_int[15: 8] = s_eth_dest_mac[39:32]; + m_axis_tdata_int[23:16] = s_eth_dest_mac[31:24]; + m_axis_tdata_int[31:24] = s_eth_dest_mac[23:16]; + m_axis_tdata_int[39:32] = s_eth_dest_mac[15: 8]; + m_axis_tdata_int[47:40] = s_eth_dest_mac[ 7: 0]; + m_axis_tdata_int[55:48] = s_eth_src_mac[47:40]; + m_axis_tdata_int[63:56] = s_eth_src_mac[39:32]; + m_axis_tkeep_int = 8'hff; + s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_s_tready; state_next = STATE_WRITE_HEADER_LAST; end endcase @@ -230,29 +230,29 @@ always @* begin end STATE_WRITE_HEADER_LAST: begin // last header word requires first payload word; process accordingly - input_eth_payload_tready_next = output_axis_tready_int_early & shift_eth_payload_input_tready; + s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_s_tready; - if (input_eth_payload_tready & shift_eth_payload_tvalid) begin + if (s_eth_payload_axis_tready && shift_eth_payload_axis_tvalid) begin frame_ptr_next = frame_ptr_reg + 8'd8; - output_axis_tvalid_int = 1'b1; + m_axis_tvalid_int = 1'b1; transfer_in_save = 1'b1; - output_axis_tdata_int[ 7: 0] = eth_src_mac_reg[31:24]; - output_axis_tdata_int[15: 8] = eth_src_mac_reg[23:16]; - output_axis_tdata_int[23:16] = eth_src_mac_reg[15: 8]; - output_axis_tdata_int[31:24] = eth_src_mac_reg[ 7: 0]; - output_axis_tdata_int[39:32] = eth_type_reg[15: 8]; - output_axis_tdata_int[47:40] = eth_type_reg[ 7: 0]; - output_axis_tdata_int[55:48] = shift_eth_payload_tdata[55:48]; - output_axis_tdata_int[63:56] = shift_eth_payload_tdata[63:56]; - output_axis_tkeep_int = {shift_eth_payload_tkeep[7:6], 6'h3F}; - output_axis_tlast_int = shift_eth_payload_tlast; - output_axis_tuser_int = shift_eth_payload_tuser; + m_axis_tdata_int[ 7: 0] = eth_src_mac_reg[31:24]; + m_axis_tdata_int[15: 8] = eth_src_mac_reg[23:16]; + m_axis_tdata_int[23:16] = eth_src_mac_reg[15: 8]; + m_axis_tdata_int[31:24] = eth_src_mac_reg[ 7: 0]; + m_axis_tdata_int[39:32] = eth_type_reg[15: 8]; + m_axis_tdata_int[47:40] = eth_type_reg[ 7: 0]; + m_axis_tdata_int[55:48] = shift_eth_payload_axis_tdata[55:48]; + m_axis_tdata_int[63:56] = shift_eth_payload_axis_tdata[63:56]; + m_axis_tkeep_int = {shift_eth_payload_axis_tkeep[7:6], 6'h3F}; + m_axis_tlast_int = shift_eth_payload_axis_tlast; + m_axis_tuser_int = shift_eth_payload_axis_tuser; - if (shift_eth_payload_tlast) begin - input_eth_payload_tready_next = 1'b0; + if (shift_eth_payload_axis_tlast) begin + s_eth_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - input_eth_hdr_ready_next = 1'b1; + s_eth_hdr_ready_next = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -263,21 +263,21 @@ always @* begin end STATE_WRITE_PAYLOAD: begin // write payload - input_eth_payload_tready_next = output_axis_tready_int_early & shift_eth_payload_input_tready; + s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_s_tready; - output_axis_tdata_int = shift_eth_payload_tdata; - output_axis_tkeep_int = shift_eth_payload_tkeep; - output_axis_tvalid_int = shift_eth_payload_tvalid; - output_axis_tlast_int = shift_eth_payload_tlast; - output_axis_tuser_int = shift_eth_payload_tuser; + m_axis_tdata_int = shift_eth_payload_axis_tdata; + m_axis_tkeep_int = shift_eth_payload_axis_tkeep; + m_axis_tvalid_int = shift_eth_payload_axis_tvalid; + m_axis_tlast_int = shift_eth_payload_axis_tlast; + m_axis_tuser_int = shift_eth_payload_axis_tuser; - if (output_axis_tready_int_reg & shift_eth_payload_tvalid) begin + if (m_axis_tready_int_reg && shift_eth_payload_axis_tvalid) begin // word transfer through transfer_in_save = 1'b1; - if (shift_eth_payload_tlast) begin - input_eth_payload_tready_next = 1'b0; + if (shift_eth_payload_axis_tlast) begin + s_eth_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - input_eth_hdr_ready_next = 1'b1; + s_eth_hdr_ready_next = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -293,133 +293,133 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 8'd0; - input_eth_hdr_ready_reg <= 1'b0; - input_eth_payload_tready_reg <= 1'b0; - save_eth_payload_tlast_reg <= 1'b0; + s_eth_hdr_ready_reg <= 1'b0; + s_eth_payload_axis_tready_reg <= 1'b0; + save_eth_payload_axis_tlast_reg <= 1'b0; busy_reg <= 1'b0; end else begin state_reg <= state_next; frame_ptr_reg <= frame_ptr_next; - input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; + s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; - input_eth_payload_tready_reg <= input_eth_payload_tready_next; + s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; busy_reg <= state_next != STATE_IDLE; // datapath if (store_eth_hdr) begin - eth_dest_mac_reg <= input_eth_dest_mac; - eth_src_mac_reg <= input_eth_src_mac; - eth_type_reg <= input_eth_type; + eth_dest_mac_reg <= s_eth_dest_mac; + eth_src_mac_reg <= s_eth_src_mac; + eth_type_reg <= s_eth_type; end if (flush_save) begin - save_eth_payload_tlast_reg <= 1'b0; + save_eth_payload_axis_tlast_reg <= 1'b0; end else if (transfer_in_save) begin - save_eth_payload_tlast_reg <= input_eth_payload_tlast; + save_eth_payload_axis_tlast_reg <= s_eth_payload_axis_tlast; end end // datapath if (store_eth_hdr) begin - eth_dest_mac_reg <= input_eth_dest_mac; - eth_src_mac_reg <= input_eth_src_mac; - eth_type_reg <= input_eth_type; + eth_dest_mac_reg <= s_eth_dest_mac; + eth_src_mac_reg <= s_eth_src_mac; + eth_type_reg <= s_eth_type; end if (transfer_in_save) begin - save_eth_payload_tdata_reg <= input_eth_payload_tdata; - save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; - save_eth_payload_tuser_reg <= input_eth_payload_tuser; + save_eth_payload_axis_tdata_reg <= s_eth_payload_axis_tdata; + save_eth_payload_axis_tkeep_reg <= s_eth_payload_axis_tkeep; + save_eth_payload_axis_tuser_reg <= s_eth_payload_axis_tuser; end end // output datapath logic -reg [63:0] output_axis_tdata_reg = 64'd0; -reg [7:0] output_axis_tkeep_reg = 8'd0; -reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next; -reg output_axis_tlast_reg = 1'b0; -reg output_axis_tuser_reg = 1'b0; +reg [63:0] m_axis_tdata_reg = 64'd0; +reg [7:0] m_axis_tkeep_reg = 8'd0; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; -reg [63:0] temp_axis_tdata_reg = 64'd0; -reg [7:0] temp_axis_tkeep_reg = 8'd0; -reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next; -reg temp_axis_tlast_reg = 1'b0; -reg temp_axis_tuser_reg = 1'b0; +reg [63:0] temp_m_axis_tdata_reg = 64'd0; +reg [7:0] temp_m_axis_tkeep_reg = 8'd0; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; // datapath control reg store_axis_int_to_output; reg store_axis_int_to_temp; reg store_axis_temp_to_output; -assign output_axis_tdata = output_axis_tdata_reg; -assign output_axis_tkeep = output_axis_tkeep_reg; -assign output_axis_tvalid = output_axis_tvalid_reg; -assign output_axis_tlast = output_axis_tlast_reg; -assign output_axis_tuser = output_axis_tuser_reg; +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = m_axis_tkeep_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int)); +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_axis_tvalid_next = output_axis_tvalid_reg; - temp_axis_tvalid_next = temp_axis_tvalid_reg; + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; store_axis_int_to_output = 1'b0; store_axis_int_to_temp = 1'b0; store_axis_temp_to_output = 1'b0; - if (output_axis_tready_int_reg) begin + if (m_axis_tready_int_reg) begin // input is ready - if (output_axis_tready | ~output_axis_tvalid_reg) begin + if (m_axis_tready || !m_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_axis_tvalid_next = output_axis_tvalid_int; + m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_axis_tvalid_next = output_axis_tvalid_int; + temp_m_axis_tvalid_next = m_axis_tvalid_int; store_axis_int_to_temp = 1'b1; end - end else if (output_axis_tready) begin + end else if (m_axis_tready) begin // input is not ready, but output is ready - output_axis_tvalid_next = temp_axis_tvalid_reg; - temp_axis_tvalid_next = 1'b0; + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; store_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_axis_tvalid_reg <= 1'b0; - output_axis_tready_int_reg <= 1'b0; - temp_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; end else begin - output_axis_tvalid_reg <= output_axis_tvalid_next; - output_axis_tready_int_reg <= output_axis_tready_int_early; - temp_axis_tvalid_reg <= temp_axis_tvalid_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; end // datapath if (store_axis_int_to_output) begin - output_axis_tdata_reg <= output_axis_tdata_int; - output_axis_tkeep_reg <= output_axis_tkeep_int; - output_axis_tlast_reg <= output_axis_tlast_int; - output_axis_tuser_reg <= output_axis_tuser_int; + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin - output_axis_tdata_reg <= temp_axis_tdata_reg; - output_axis_tkeep_reg <= temp_axis_tkeep_reg; - output_axis_tlast_reg <= temp_axis_tlast_reg; - output_axis_tuser_reg <= temp_axis_tuser_reg; + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin - temp_axis_tdata_reg <= output_axis_tdata_int; - temp_axis_tkeep_reg <= output_axis_tkeep_int; - temp_axis_tlast_reg <= output_axis_tlast_int; - temp_axis_tuser_reg <= output_axis_tuser_int; + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; end end diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index 45c4cfe26..1d0b78515 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -106,11 +106,11 @@ axis_xgmii_rx_inst ( .rst(rx_rst), .xgmii_rxd(xgmii_rxd), .xgmii_rxc(xgmii_rxc), - .output_axis_tdata(rx_axis_tdata), - .output_axis_tkeep(rx_axis_tkeep), - .output_axis_tvalid(rx_axis_tvalid), - .output_axis_tlast(rx_axis_tlast), - .output_axis_tuser(rx_axis_tuser), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(rx_axis_tkeep), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tuser(rx_axis_tuser), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); @@ -123,12 +123,12 @@ axis_xgmii_tx_64 #( axis_xgmii_tx_inst ( .clk(tx_clk), .rst(tx_rst), - .input_axis_tdata(tx_axis_tdata), - .input_axis_tkeep(tx_axis_tkeep), - .input_axis_tvalid(tx_axis_tvalid), - .input_axis_tready(tx_axis_tready), - .input_axis_tlast(tx_axis_tlast), - .input_axis_tuser(tx_axis_tuser), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(tx_axis_tkeep), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tuser(tx_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), .ifg_delay(ifg_delay) @@ -142,11 +142,11 @@ axis_xgmii_rx_inst ( .rst(rx_rst), .xgmii_rxd(xgmii_rxd), .xgmii_rxc(xgmii_rxc), - .output_axis_tdata(rx_axis_tdata), - .output_axis_tkeep(rx_axis_tkeep), - .output_axis_tvalid(rx_axis_tvalid), - .output_axis_tlast(rx_axis_tlast), - .output_axis_tuser(rx_axis_tuser), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(rx_axis_tkeep), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tuser(rx_axis_tuser), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); @@ -159,12 +159,12 @@ axis_xgmii_tx_32 #( axis_xgmii_tx_inst ( .clk(tx_clk), .rst(tx_rst), - .input_axis_tdata(tx_axis_tdata), - .input_axis_tkeep(tx_axis_tkeep), - .input_axis_tvalid(tx_axis_tvalid), - .input_axis_tready(tx_axis_tready), - .input_axis_tlast(tx_axis_tlast), - .input_axis_tuser(tx_axis_tuser), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(tx_axis_tkeep), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tuser(tx_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), .ifg_delay(ifg_delay) diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v index 35195addb..ceb134b66 100644 --- a/rtl/eth_mac_1g.v +++ b/rtl/eth_mac_1g.v @@ -94,10 +94,10 @@ axis_gmii_rx_inst ( .gmii_rxd(gmii_rxd), .gmii_rx_dv(gmii_rx_dv), .gmii_rx_er(gmii_rx_er), - .output_axis_tdata(rx_axis_tdata), - .output_axis_tvalid(rx_axis_tvalid), - .output_axis_tlast(rx_axis_tlast), - .output_axis_tuser(rx_axis_tuser), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tuser(rx_axis_tuser), .clk_enable(rx_clk_enable), .mii_select(rx_mii_select), .error_bad_frame(rx_error_bad_frame), @@ -111,11 +111,11 @@ axis_gmii_tx #( axis_gmii_tx_inst ( .clk(tx_clk), .rst(tx_rst), - .input_axis_tdata(tx_axis_tdata), - .input_axis_tvalid(tx_axis_tvalid), - .input_axis_tready(tx_axis_tready), - .input_axis_tlast(tx_axis_tlast), - .input_axis_tuser(tx_axis_tuser), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tuser(tx_axis_tuser), .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), diff --git a/rtl/ip.v b/rtl/ip.v index 0a520f645..6c884ce35 100644 --- a/rtl/ip.v +++ b/rtl/ip.v @@ -37,30 +37,30 @@ module ip /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [7:0] input_eth_payload_tdata, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [7:0] s_eth_payload_axis_tdata, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [7:0] m_eth_payload_axis_tdata, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * ARP requests @@ -76,47 +76,47 @@ module ip /* * IP input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [7:0] input_ip_payload_tdata, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [7:0] s_ip_payload_axis_tdata, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * IP output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_ip_eth_dest_mac, - output wire [47:0] output_ip_eth_src_mac, - output wire [15:0] output_ip_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_ip_eth_dest_mac, + output wire [47:0] m_ip_eth_src_mac, + output wire [15:0] m_ip_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [7:0] m_ip_payload_axis_tdata, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * Status @@ -147,7 +147,7 @@ reg [1:0] state_reg = STATE_IDLE, state_next; reg outgoing_ip_hdr_valid_reg = 1'b0, outgoing_ip_hdr_valid_next; wire outgoing_ip_hdr_ready; reg [47:0] outgoing_eth_dest_mac_reg = 48'h000000000000, outgoing_eth_dest_mac_next; -wire outgoing_ip_payload_tready; +wire outgoing_ip_payload_axis_tready; /* * IP frame processing @@ -157,40 +157,40 @@ ip_eth_rx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_ip_eth_dest_mac), - .output_eth_src_mac(output_ip_eth_src_mac), - .output_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_ip_eth_dest_mac), + .m_eth_src_mac(m_ip_eth_src_mac), + .m_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .busy(rx_busy), .error_header_early_termination(rx_error_header_early_termination), @@ -204,43 +204,43 @@ ip_eth_tx_inst ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(outgoing_ip_hdr_valid_reg), - .input_ip_hdr_ready(outgoing_ip_hdr_ready), - .input_eth_dest_mac(outgoing_eth_dest_mac_reg), - .input_eth_src_mac(local_mac), - .input_eth_type(16'h0800), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(16'd0), - .input_ip_flags(3'b010), - .input_ip_fragment_offset(13'd0), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(outgoing_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(outgoing_ip_hdr_valid_reg), + .s_ip_hdr_ready(outgoing_ip_hdr_ready), + .s_eth_dest_mac(outgoing_eth_dest_mac_reg), + .s_eth_src_mac(local_mac), + .s_eth_type(16'h0800), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(16'd0), + .s_ip_flags(3'b010), + .s_ip_fragment_offset(13'd0), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(outgoing_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Status signals .busy(tx_busy), .error_payload_early_termination(tx_error_payload_early_termination) ); -reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; +reg s_ip_hdr_ready_reg = 1'b0, s_ip_hdr_ready_next; reg arp_request_valid_reg = 1'b0, arp_request_valid_next; @@ -248,11 +248,11 @@ reg arp_response_ready_reg = 1'b0, arp_response_ready_next; reg drop_packet_reg = 1'b0, drop_packet_next; -assign input_ip_hdr_ready = input_ip_hdr_ready_reg; -assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; +assign s_ip_hdr_ready = s_ip_hdr_ready_reg; +assign s_ip_payload_axis_tready = outgoing_ip_payload_axis_tready || drop_packet_reg; assign arp_request_valid = arp_request_valid_reg; -assign arp_request_ip = input_ip_dest_ip; +assign arp_request_ip = s_ip_dest_ip; assign arp_response_ready = arp_response_ready_reg; assign tx_error_arp_failed = arp_response_error; @@ -260,19 +260,19 @@ assign tx_error_arp_failed = arp_response_error; always @* begin state_next = STATE_IDLE; - arp_request_valid_next = arp_request_valid_reg & ~arp_request_ready; + arp_request_valid_next = arp_request_valid_reg && !arp_request_ready; arp_response_ready_next = 1'b0; drop_packet_next = 1'b0; - input_ip_hdr_ready_next = 1'b0; + s_ip_hdr_ready_next = 1'b0; - outgoing_ip_hdr_valid_next = outgoing_ip_hdr_valid_reg & ~outgoing_ip_hdr_ready; + outgoing_ip_hdr_valid_next = outgoing_ip_hdr_valid_reg && !outgoing_ip_hdr_ready; outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; case (state_reg) STATE_IDLE: begin // wait for outgoing packet - if (input_ip_hdr_valid) begin + if (s_ip_hdr_valid) begin // initiate ARP request arp_request_valid_next = 1'b1; arp_response_ready_next = 1'b1; @@ -288,12 +288,12 @@ always @* begin // wait for ARP reponse if (arp_response_error) begin // did not get MAC address; drop packet - input_ip_hdr_ready_next = 1'b1; + s_ip_hdr_ready_next = 1'b1; drop_packet_next = 1'b1; state_next = STATE_WAIT_PACKET; end else begin // got MAC address; send packet - input_ip_hdr_ready_next = 1'b1; + s_ip_hdr_ready_next = 1'b1; outgoing_ip_hdr_valid_next = 1'b1; outgoing_eth_dest_mac_next = arp_response_mac; state_next = STATE_WAIT_PACKET; @@ -306,7 +306,7 @@ always @* begin drop_packet_next = drop_packet_reg; // wait for packet transfer to complete - if (input_ip_payload_tlast & input_ip_payload_tready & input_ip_payload_tvalid) begin + if (s_ip_payload_axis_tlast && s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_PACKET; @@ -321,7 +321,7 @@ always @(posedge clk) begin arp_request_valid_reg <= 1'b0; arp_response_ready_reg <= 1'b0; drop_packet_reg <= 1'b0; - input_ip_hdr_ready_reg <= 1'b0; + s_ip_hdr_ready_reg <= 1'b0; outgoing_ip_hdr_valid_reg <= 1'b0; end else begin state_reg <= state_next; @@ -330,7 +330,7 @@ always @(posedge clk) begin arp_response_ready_reg <= arp_response_ready_next; drop_packet_reg <= drop_packet_next; - input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; outgoing_ip_hdr_valid_reg <= outgoing_ip_hdr_valid_next; end diff --git a/rtl/ip_64.v b/rtl/ip_64.v index 806f20faf..be1464f4a 100644 --- a/rtl/ip_64.v +++ b/rtl/ip_64.v @@ -37,32 +37,32 @@ module ip_64 /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [63:0] input_eth_payload_tdata, - input wire [7:0] input_eth_payload_tkeep, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [63:0] s_eth_payload_axis_tdata, + input wire [7:0] s_eth_payload_axis_tkeep, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [63:0] m_eth_payload_axis_tdata, + output wire [7:0] m_eth_payload_axis_tkeep, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * ARP requests @@ -78,49 +78,49 @@ module ip_64 /* * IP input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [63:0] input_ip_payload_tdata, - input wire [7:0] input_ip_payload_tkeep, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [63:0] s_ip_payload_axis_tdata, + input wire [7:0] s_ip_payload_axis_tkeep, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * IP output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_ip_eth_dest_mac, - output wire [47:0] output_ip_eth_src_mac, - output wire [15:0] output_ip_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_ip_eth_dest_mac, + output wire [47:0] m_ip_eth_src_mac, + output wire [15:0] m_ip_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [63:0] m_ip_payload_axis_tdata, + output wire [7:0] m_ip_payload_axis_tkeep, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * Status @@ -151,7 +151,7 @@ reg [1:0] state_reg = STATE_IDLE, state_next; reg outgoing_ip_hdr_valid_reg = 1'b0, outgoing_ip_hdr_valid_next; wire outgoing_ip_hdr_ready; reg [47:0] outgoing_eth_dest_mac_reg = 48'h000000000000, outgoing_eth_dest_mac_next; -wire outgoing_ip_payload_tready; +wire outgoing_ip_payload_axis_tready; /* * IP frame processing @@ -161,42 +161,42 @@ ip_eth_rx_64_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_ip_eth_dest_mac), - .output_eth_src_mac(output_ip_eth_src_mac), - .output_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_ip_eth_dest_mac), + .m_eth_src_mac(m_ip_eth_src_mac), + .m_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .busy(rx_busy), .error_header_early_termination(rx_error_header_early_termination), @@ -210,45 +210,45 @@ ip_eth_tx_64_inst ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(outgoing_ip_hdr_valid_reg), - .input_ip_hdr_ready(outgoing_ip_hdr_ready), - .input_eth_dest_mac(outgoing_eth_dest_mac_reg), - .input_eth_src_mac(local_mac), - .input_eth_type(16'h0800), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(16'd0), - .input_ip_flags(3'b010), - .input_ip_fragment_offset(13'd0), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tkeep(input_ip_payload_tkeep), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(outgoing_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(outgoing_ip_hdr_valid_reg), + .s_ip_hdr_ready(outgoing_ip_hdr_ready), + .s_eth_dest_mac(outgoing_eth_dest_mac_reg), + .s_eth_src_mac(local_mac), + .s_eth_type(16'h0800), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(16'd0), + .s_ip_flags(3'b010), + .s_ip_fragment_offset(13'd0), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(outgoing_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Status signals .busy(tx_busy), .error_payload_early_termination(tx_error_payload_early_termination) ); -reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; +reg s_ip_hdr_ready_reg = 1'b0, s_ip_hdr_ready_next; reg arp_request_valid_reg = 1'b0, arp_request_valid_next; @@ -256,11 +256,11 @@ reg arp_response_ready_reg = 1'b0, arp_response_ready_next; reg drop_packet_reg = 1'b0, drop_packet_next; -assign input_ip_hdr_ready = input_ip_hdr_ready_reg; -assign input_ip_payload_tready = outgoing_ip_payload_tready | drop_packet_reg; +assign s_ip_hdr_ready = s_ip_hdr_ready_reg; +assign s_ip_payload_axis_tready = outgoing_ip_payload_axis_tready || drop_packet_reg; assign arp_request_valid = arp_request_valid_reg; -assign arp_request_ip = input_ip_dest_ip; +assign arp_request_ip = s_ip_dest_ip; assign arp_response_ready = arp_response_ready_reg; assign tx_error_arp_failed = arp_response_error; @@ -268,19 +268,19 @@ assign tx_error_arp_failed = arp_response_error; always @* begin state_next = STATE_IDLE; - arp_request_valid_next = arp_request_valid_reg & ~arp_request_ready; + arp_request_valid_next = arp_request_valid_reg && !arp_request_ready; arp_response_ready_next = 1'b0; drop_packet_next = 1'b0; - input_ip_hdr_ready_next = 1'b0; + s_ip_hdr_ready_next = 1'b0; - outgoing_ip_hdr_valid_next = outgoing_ip_hdr_valid_reg & ~outgoing_ip_hdr_ready; + outgoing_ip_hdr_valid_next = outgoing_ip_hdr_valid_reg && !outgoing_ip_hdr_ready; outgoing_eth_dest_mac_next = outgoing_eth_dest_mac_reg; case (state_reg) STATE_IDLE: begin // wait for outgoing packet - if (input_ip_hdr_valid) begin + if (s_ip_hdr_valid) begin // initiate ARP request arp_request_valid_next = 1'b1; arp_response_ready_next = 1'b1; @@ -296,12 +296,12 @@ always @* begin // wait for ARP reponse if (arp_response_error) begin // did not get MAC address; drop packet - input_ip_hdr_ready_next = 1'b1; + s_ip_hdr_ready_next = 1'b1; drop_packet_next = 1'b1; state_next = STATE_WAIT_PACKET; end else begin // got MAC address; send packet - input_ip_hdr_ready_next = 1'b1; + s_ip_hdr_ready_next = 1'b1; outgoing_ip_hdr_valid_next = 1'b1; outgoing_eth_dest_mac_next = arp_response_mac; state_next = STATE_WAIT_PACKET; @@ -314,7 +314,7 @@ always @* begin drop_packet_next = drop_packet_reg; // wait for packet transfer to complete - if (input_ip_payload_tlast & input_ip_payload_tready & input_ip_payload_tvalid) begin + if (s_ip_payload_axis_tlast && s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_PACKET; @@ -329,7 +329,7 @@ always @(posedge clk) begin arp_request_valid_reg <= 1'b0; arp_response_ready_reg <= 1'b0; drop_packet_reg <= 1'b0; - input_ip_hdr_ready_reg <= 1'b0; + s_ip_hdr_ready_reg <= 1'b0; outgoing_ip_hdr_valid_reg <= 1'b0; end else begin state_reg <= state_next; @@ -338,7 +338,7 @@ always @(posedge clk) begin arp_response_ready_reg <= arp_response_ready_next; drop_packet_reg <= drop_packet_next; - input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; + s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; outgoing_ip_hdr_valid_reg <= outgoing_ip_hdr_valid_next; end diff --git a/rtl/ip_complete.v b/rtl/ip_complete.v index ed8db178c..f16d697b3 100644 --- a/rtl/ip_complete.v +++ b/rtl/ip_complete.v @@ -42,75 +42,75 @@ module ip_complete #( /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [7:0] input_eth_payload_tdata, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [7:0] s_eth_payload_axis_tdata, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [7:0] m_eth_payload_axis_tdata, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * IP input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [7:0] input_ip_payload_tdata, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [7:0] s_ip_payload_axis_tdata, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * IP output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_ip_eth_dest_mac, - output wire [47:0] output_ip_eth_src_mac, - output wire [15:0] output_ip_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_ip_eth_dest_mac, + output wire [47:0] m_ip_eth_src_mac, + output wire [15:0] m_ip_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [7:0] m_ip_payload_axis_tdata, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * Status @@ -153,102 +153,102 @@ wire ip_rx_eth_hdr_ready; wire [47:0] ip_rx_eth_dest_mac; wire [47:0] ip_rx_eth_src_mac; wire [15:0] ip_rx_eth_type; -wire [7:0] ip_rx_eth_payload_tdata; -wire ip_rx_eth_payload_tvalid; -wire ip_rx_eth_payload_tready; -wire ip_rx_eth_payload_tlast; -wire ip_rx_eth_payload_tuser; +wire [7:0] ip_rx_eth_payload_axis_tdata; +wire ip_rx_eth_payload_axis_tvalid; +wire ip_rx_eth_payload_axis_tready; +wire ip_rx_eth_payload_axis_tlast; +wire ip_rx_eth_payload_axis_tuser; wire ip_tx_eth_hdr_valid; wire ip_tx_eth_hdr_ready; wire [47:0] ip_tx_eth_dest_mac; wire [47:0] ip_tx_eth_src_mac; wire [15:0] ip_tx_eth_type; -wire [7:0] ip_tx_eth_payload_tdata; -wire ip_tx_eth_payload_tvalid; -wire ip_tx_eth_payload_tready; -wire ip_tx_eth_payload_tlast; -wire ip_tx_eth_payload_tuser; +wire [7:0] ip_tx_eth_payload_axis_tdata; +wire ip_tx_eth_payload_axis_tvalid; +wire ip_tx_eth_payload_axis_tready; +wire ip_tx_eth_payload_axis_tlast; +wire ip_tx_eth_payload_axis_tuser; wire arp_rx_eth_hdr_valid; wire arp_rx_eth_hdr_ready; wire [47:0] arp_rx_eth_dest_mac; wire [47:0] arp_rx_eth_src_mac; wire [15:0] arp_rx_eth_type; -wire [7:0] arp_rx_eth_payload_tdata; -wire arp_rx_eth_payload_tvalid; -wire arp_rx_eth_payload_tready; -wire arp_rx_eth_payload_tlast; -wire arp_rx_eth_payload_tuser; +wire [7:0] arp_rx_eth_payload_axis_tdata; +wire arp_rx_eth_payload_axis_tvalid; +wire arp_rx_eth_payload_axis_tready; +wire arp_rx_eth_payload_axis_tlast; +wire arp_rx_eth_payload_axis_tuser; wire arp_tx_eth_hdr_valid; wire arp_tx_eth_hdr_ready; wire [47:0] arp_tx_eth_dest_mac; wire [47:0] arp_tx_eth_src_mac; wire [15:0] arp_tx_eth_type; -wire [7:0] arp_tx_eth_payload_tdata; -wire arp_tx_eth_payload_tvalid; -wire arp_tx_eth_payload_tready; -wire arp_tx_eth_payload_tlast; -wire arp_tx_eth_payload_tuser; +wire [7:0] arp_tx_eth_payload_axis_tdata; +wire arp_tx_eth_payload_axis_tvalid; +wire arp_tx_eth_payload_axis_tready; +wire arp_tx_eth_payload_axis_tlast; +wire arp_tx_eth_payload_axis_tuser; /* * Input classifier (eth_type) */ -wire input_select_ip = (input_eth_type == 16'h0800); -wire input_select_arp = (input_eth_type == 16'h0806); -wire input_select_none = ~(input_select_ip | input_select_arp); +wire s_select_ip = (s_eth_type == 16'h0800); +wire s_select_arp = (s_eth_type == 16'h0806); +wire s_select_none = !(s_select_ip || s_select_arp); -reg input_select_ip_reg = 1'b0; -reg input_select_arp_reg = 1'b0; -reg input_select_none_reg = 1'b0; +reg s_select_ip_reg = 1'b0; +reg s_select_arp_reg = 1'b0; +reg s_select_none_reg = 1'b0; always @(posedge clk) begin if (rst) begin - input_select_ip_reg <= 1'b0; - input_select_arp_reg <= 1'b0; - input_select_none_reg <= 1'b0; + s_select_ip_reg <= 1'b0; + s_select_arp_reg <= 1'b0; + s_select_none_reg <= 1'b0; end else begin - if (input_eth_payload_tvalid) begin - if ((~input_select_ip_reg & ~input_select_arp_reg & ~input_select_none_reg) | - (input_eth_payload_tvalid & input_eth_payload_tready & input_eth_payload_tlast)) begin - input_select_ip_reg <= input_select_ip; - input_select_arp_reg <= input_select_arp; - input_select_none_reg <= input_select_none; + if (s_eth_payload_axis_tvalid) begin + if ((!s_select_ip_reg && !s_select_arp_reg && !s_select_none_reg) || + (s_eth_payload_axis_tvalid && s_eth_payload_axis_tready && s_eth_payload_axis_tlast)) begin + s_select_ip_reg <= s_select_ip; + s_select_arp_reg <= s_select_arp; + s_select_none_reg <= s_select_none; end end else begin - input_select_ip_reg <= 1'b0; - input_select_arp_reg <= 1'b0; - input_select_none_reg <= 1'b0; + s_select_ip_reg <= 1'b0; + s_select_arp_reg <= 1'b0; + s_select_none_reg <= 1'b0; end end end -assign ip_rx_eth_hdr_valid = input_select_ip & input_eth_hdr_valid; -assign ip_rx_eth_dest_mac = input_eth_dest_mac; -assign ip_rx_eth_src_mac = input_eth_src_mac; +assign ip_rx_eth_hdr_valid = s_select_ip && s_eth_hdr_valid; +assign ip_rx_eth_dest_mac = s_eth_dest_mac; +assign ip_rx_eth_src_mac = s_eth_src_mac; assign ip_rx_eth_type = 16'h0800; -assign ip_rx_eth_payload_tdata = input_eth_payload_tdata; -assign ip_rx_eth_payload_tvalid = input_select_ip_reg & input_eth_payload_tvalid; -assign ip_rx_eth_payload_tlast = input_eth_payload_tlast; -assign ip_rx_eth_payload_tuser = input_eth_payload_tuser; +assign ip_rx_eth_payload_axis_tdata = s_eth_payload_axis_tdata; +assign ip_rx_eth_payload_axis_tvalid = s_select_ip_reg && s_eth_payload_axis_tvalid; +assign ip_rx_eth_payload_axis_tlast = s_eth_payload_axis_tlast; +assign ip_rx_eth_payload_axis_tuser = s_eth_payload_axis_tuser; -assign arp_rx_eth_hdr_valid = input_select_arp & input_eth_hdr_valid; -assign arp_rx_eth_dest_mac = input_eth_dest_mac; -assign arp_rx_eth_src_mac = input_eth_src_mac; +assign arp_rx_eth_hdr_valid = s_select_arp && s_eth_hdr_valid; +assign arp_rx_eth_dest_mac = s_eth_dest_mac; +assign arp_rx_eth_src_mac = s_eth_src_mac; assign arp_rx_eth_type = 16'h0806; -assign arp_rx_eth_payload_tdata = input_eth_payload_tdata; -assign arp_rx_eth_payload_tvalid = input_select_arp_reg & input_eth_payload_tvalid; -assign arp_rx_eth_payload_tlast = input_eth_payload_tlast; -assign arp_rx_eth_payload_tuser = input_eth_payload_tuser; +assign arp_rx_eth_payload_axis_tdata = s_eth_payload_axis_tdata; +assign arp_rx_eth_payload_axis_tvalid = s_select_arp_reg && s_eth_payload_axis_tvalid; +assign arp_rx_eth_payload_axis_tlast = s_eth_payload_axis_tlast; +assign arp_rx_eth_payload_axis_tuser = s_eth_payload_axis_tuser; -assign input_eth_hdr_ready = (input_select_ip & ip_rx_eth_hdr_ready) | - (input_select_arp & arp_rx_eth_hdr_ready) | - (input_select_none); +assign s_eth_hdr_ready = (s_select_ip && ip_rx_eth_hdr_ready) || + (s_select_arp && arp_rx_eth_hdr_ready) || + (s_select_none); -assign input_eth_payload_tready = (input_select_ip_reg & ip_rx_eth_payload_tready) | - (input_select_arp_reg & arp_rx_eth_payload_tready) | - input_select_none_reg; +assign s_eth_payload_axis_tready = (s_select_ip_reg && ip_rx_eth_payload_axis_tready) || + (s_select_arp_reg && arp_rx_eth_payload_axis_tready) || + s_select_none_reg; /* * Output arbiter @@ -273,28 +273,28 @@ eth_arb_mux_inst ( .s_eth_dest_mac({ip_tx_eth_dest_mac, arp_tx_eth_dest_mac}), .s_eth_src_mac({ip_tx_eth_src_mac, arp_tx_eth_src_mac}), .s_eth_type({ip_tx_eth_type, arp_tx_eth_type}), - .s_eth_payload_axis_tdata({ip_tx_eth_payload_tdata, arp_tx_eth_payload_tdata}), + .s_eth_payload_axis_tdata({ip_tx_eth_payload_axis_tdata, arp_tx_eth_payload_axis_tdata}), .s_eth_payload_axis_tkeep(0), - .s_eth_payload_axis_tvalid({ip_tx_eth_payload_tvalid, arp_tx_eth_payload_tvalid}), - .s_eth_payload_axis_tready({ip_tx_eth_payload_tready, arp_tx_eth_payload_tready}), - .s_eth_payload_axis_tlast({ip_tx_eth_payload_tlast, arp_tx_eth_payload_tlast}), + .s_eth_payload_axis_tvalid({ip_tx_eth_payload_axis_tvalid, arp_tx_eth_payload_axis_tvalid}), + .s_eth_payload_axis_tready({ip_tx_eth_payload_axis_tready, arp_tx_eth_payload_axis_tready}), + .s_eth_payload_axis_tlast({ip_tx_eth_payload_axis_tlast, arp_tx_eth_payload_axis_tlast}), .s_eth_payload_axis_tid(0), .s_eth_payload_axis_tdest(0), - .s_eth_payload_axis_tuser({ip_tx_eth_payload_tuser, arp_tx_eth_payload_tuser}), + .s_eth_payload_axis_tuser({ip_tx_eth_payload_axis_tuser, arp_tx_eth_payload_axis_tuser}), // Ethernet frame output - .m_eth_hdr_valid(output_eth_hdr_valid), - .m_eth_hdr_ready(output_eth_hdr_ready), - .m_eth_dest_mac(output_eth_dest_mac), - .m_eth_src_mac(output_eth_src_mac), - .m_eth_type(output_eth_type), - .m_eth_payload_axis_tdata(output_eth_payload_tdata), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), .m_eth_payload_axis_tkeep(), - .m_eth_payload_axis_tvalid(output_eth_payload_tvalid), - .m_eth_payload_axis_tready(output_eth_payload_tready), - .m_eth_payload_axis_tlast(output_eth_payload_tlast), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), .m_eth_payload_axis_tid(), .m_eth_payload_axis_tdest(), - .m_eth_payload_axis_tuser(output_eth_payload_tuser) + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser) ); /* @@ -305,66 +305,66 @@ ip_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(ip_rx_eth_hdr_valid), - .input_eth_hdr_ready(ip_rx_eth_hdr_ready), - .input_eth_dest_mac(ip_rx_eth_dest_mac), - .input_eth_src_mac(ip_rx_eth_src_mac), - .input_eth_type(ip_rx_eth_type), - .input_eth_payload_tdata(ip_rx_eth_payload_tdata), - .input_eth_payload_tvalid(ip_rx_eth_payload_tvalid), - .input_eth_payload_tready(ip_rx_eth_payload_tready), - .input_eth_payload_tlast(ip_rx_eth_payload_tlast), - .input_eth_payload_tuser(ip_rx_eth_payload_tuser), + .s_eth_hdr_valid(ip_rx_eth_hdr_valid), + .s_eth_hdr_ready(ip_rx_eth_hdr_ready), + .s_eth_dest_mac(ip_rx_eth_dest_mac), + .s_eth_src_mac(ip_rx_eth_src_mac), + .s_eth_type(ip_rx_eth_type), + .s_eth_payload_axis_tdata(ip_rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(ip_rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(ip_rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(ip_rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(ip_rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(ip_tx_eth_hdr_valid), - .output_eth_hdr_ready(ip_tx_eth_hdr_ready), - .output_eth_dest_mac(ip_tx_eth_dest_mac), - .output_eth_src_mac(ip_tx_eth_src_mac), - .output_eth_type(ip_tx_eth_type), - .output_eth_payload_tdata(ip_tx_eth_payload_tdata), - .output_eth_payload_tvalid(ip_tx_eth_payload_tvalid), - .output_eth_payload_tready(ip_tx_eth_payload_tready), - .output_eth_payload_tlast(ip_tx_eth_payload_tlast), - .output_eth_payload_tuser(ip_tx_eth_payload_tuser), + .m_eth_hdr_valid(ip_tx_eth_hdr_valid), + .m_eth_hdr_ready(ip_tx_eth_hdr_ready), + .m_eth_dest_mac(ip_tx_eth_dest_mac), + .m_eth_src_mac(ip_tx_eth_src_mac), + .m_eth_type(ip_tx_eth_type), + .m_eth_payload_axis_tdata(ip_tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(ip_tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(ip_tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(ip_tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(ip_tx_eth_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_ip_eth_dest_mac(output_ip_eth_dest_mac), - .output_ip_eth_src_mac(output_ip_eth_src_mac), - .output_ip_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_ip_eth_dest_mac(m_ip_eth_dest_mac), + .m_ip_eth_src_mac(m_ip_eth_src_mac), + .m_ip_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // ARP requests .arp_request_valid(arp_request_valid), .arp_request_ready(arp_request_ready), @@ -400,27 +400,27 @@ arp_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(arp_rx_eth_hdr_valid), - .input_eth_hdr_ready(arp_rx_eth_hdr_ready), - .input_eth_dest_mac(arp_rx_eth_dest_mac), - .input_eth_src_mac(arp_rx_eth_src_mac), - .input_eth_type(arp_rx_eth_type), - .input_eth_payload_tdata(arp_rx_eth_payload_tdata), - .input_eth_payload_tvalid(arp_rx_eth_payload_tvalid), - .input_eth_payload_tready(arp_rx_eth_payload_tready), - .input_eth_payload_tlast(arp_rx_eth_payload_tlast), - .input_eth_payload_tuser(arp_rx_eth_payload_tuser), + .s_eth_hdr_valid(arp_rx_eth_hdr_valid), + .s_eth_hdr_ready(arp_rx_eth_hdr_ready), + .s_eth_dest_mac(arp_rx_eth_dest_mac), + .s_eth_src_mac(arp_rx_eth_src_mac), + .s_eth_type(arp_rx_eth_type), + .s_eth_payload_axis_tdata(arp_rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(arp_rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(arp_rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(arp_rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(arp_rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(arp_tx_eth_hdr_valid), - .output_eth_hdr_ready(arp_tx_eth_hdr_ready), - .output_eth_dest_mac(arp_tx_eth_dest_mac), - .output_eth_src_mac(arp_tx_eth_src_mac), - .output_eth_type(arp_tx_eth_type), - .output_eth_payload_tdata(arp_tx_eth_payload_tdata), - .output_eth_payload_tvalid(arp_tx_eth_payload_tvalid), - .output_eth_payload_tready(arp_tx_eth_payload_tready), - .output_eth_payload_tlast(arp_tx_eth_payload_tlast), - .output_eth_payload_tuser(arp_tx_eth_payload_tuser), + .m_eth_hdr_valid(arp_tx_eth_hdr_valid), + .m_eth_hdr_ready(arp_tx_eth_hdr_ready), + .m_eth_dest_mac(arp_tx_eth_dest_mac), + .m_eth_src_mac(arp_tx_eth_src_mac), + .m_eth_type(arp_tx_eth_type), + .m_eth_payload_axis_tdata(arp_tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(arp_tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(arp_tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(arp_tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(arp_tx_eth_payload_axis_tuser), // ARP requests .arp_request_valid(arp_request_valid), .arp_request_ready(arp_request_ready), diff --git a/rtl/ip_complete_64.v b/rtl/ip_complete_64.v index 7d9949892..a6fbd0e2d 100644 --- a/rtl/ip_complete_64.v +++ b/rtl/ip_complete_64.v @@ -42,79 +42,79 @@ module ip_complete_64 #( /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [63:0] input_eth_payload_tdata, - input wire [7:0] input_eth_payload_tkeep, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [63:0] s_eth_payload_axis_tdata, + input wire [7:0] s_eth_payload_axis_tkeep, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [63:0] m_eth_payload_axis_tdata, + output wire [7:0] m_eth_payload_axis_tkeep, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * IP input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [63:0] input_ip_payload_tdata, - input wire [7:0] input_ip_payload_tkeep, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [63:0] s_ip_payload_axis_tdata, + input wire [7:0] s_ip_payload_axis_tkeep, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * IP output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_ip_eth_dest_mac, - output wire [47:0] output_ip_eth_src_mac, - output wire [15:0] output_ip_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_ip_eth_dest_mac, + output wire [47:0] m_ip_eth_src_mac, + output wire [15:0] m_ip_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [63:0] m_ip_payload_axis_tdata, + output wire [7:0] m_ip_payload_axis_tkeep, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * Status @@ -157,108 +157,108 @@ wire ip_rx_eth_hdr_ready; wire [47:0] ip_rx_eth_dest_mac; wire [47:0] ip_rx_eth_src_mac; wire [15:0] ip_rx_eth_type; -wire [63:0] ip_rx_eth_payload_tdata; -wire [7:0] ip_rx_eth_payload_tkeep; -wire ip_rx_eth_payload_tvalid; -wire ip_rx_eth_payload_tready; -wire ip_rx_eth_payload_tlast; -wire ip_rx_eth_payload_tuser; +wire [63:0] ip_rx_eth_payload_axis_tdata; +wire [7:0] ip_rx_eth_payload_axis_tkeep; +wire ip_rx_eth_payload_axis_tvalid; +wire ip_rx_eth_payload_axis_tready; +wire ip_rx_eth_payload_axis_tlast; +wire ip_rx_eth_payload_axis_tuser; wire ip_tx_eth_hdr_valid; wire ip_tx_eth_hdr_ready; wire [47:0] ip_tx_eth_dest_mac; wire [47:0] ip_tx_eth_src_mac; wire [15:0] ip_tx_eth_type; -wire [63:0] ip_tx_eth_payload_tdata; -wire [7:0] ip_tx_eth_payload_tkeep; -wire ip_tx_eth_payload_tvalid; -wire ip_tx_eth_payload_tready; -wire ip_tx_eth_payload_tlast; -wire ip_tx_eth_payload_tuser; +wire [63:0] ip_tx_eth_payload_axis_tdata; +wire [7:0] ip_tx_eth_payload_axis_tkeep; +wire ip_tx_eth_payload_axis_tvalid; +wire ip_tx_eth_payload_axis_tready; +wire ip_tx_eth_payload_axis_tlast; +wire ip_tx_eth_payload_axis_tuser; wire arp_rx_eth_hdr_valid; wire arp_rx_eth_hdr_ready; wire [47:0] arp_rx_eth_dest_mac; wire [47:0] arp_rx_eth_src_mac; wire [15:0] arp_rx_eth_type; -wire [63:0] arp_rx_eth_payload_tdata; -wire [7:0] arp_rx_eth_payload_tkeep; -wire arp_rx_eth_payload_tvalid; -wire arp_rx_eth_payload_tready; -wire arp_rx_eth_payload_tlast; -wire arp_rx_eth_payload_tuser; +wire [63:0] arp_rx_eth_payload_axis_tdata; +wire [7:0] arp_rx_eth_payload_axis_tkeep; +wire arp_rx_eth_payload_axis_tvalid; +wire arp_rx_eth_payload_axis_tready; +wire arp_rx_eth_payload_axis_tlast; +wire arp_rx_eth_payload_axis_tuser; wire arp_tx_eth_hdr_valid; wire arp_tx_eth_hdr_ready; wire [47:0] arp_tx_eth_dest_mac; wire [47:0] arp_tx_eth_src_mac; wire [15:0] arp_tx_eth_type; -wire [63:0] arp_tx_eth_payload_tdata; -wire [7:0] arp_tx_eth_payload_tkeep; -wire arp_tx_eth_payload_tvalid; -wire arp_tx_eth_payload_tready; -wire arp_tx_eth_payload_tlast; -wire arp_tx_eth_payload_tuser; +wire [63:0] arp_tx_eth_payload_axis_tdata; +wire [7:0] arp_tx_eth_payload_axis_tkeep; +wire arp_tx_eth_payload_axis_tvalid; +wire arp_tx_eth_payload_axis_tready; +wire arp_tx_eth_payload_axis_tlast; +wire arp_tx_eth_payload_axis_tuser; /* * Input classifier (eth_type) */ -wire input_select_ip = (input_eth_type == 16'h0800); -wire input_select_arp = (input_eth_type == 16'h0806); -wire input_select_none = ~(input_select_ip | input_select_arp); +wire s_select_ip = (s_eth_type == 16'h0800); +wire s_select_arp = (s_eth_type == 16'h0806); +wire s_select_none = !(s_select_ip || s_select_arp); -reg input_select_ip_reg = 1'b0; -reg input_select_arp_reg = 1'b0; -reg input_select_none_reg = 1'b0; +reg s_select_ip_reg = 1'b0; +reg s_select_arp_reg = 1'b0; +reg s_select_none_reg = 1'b0; always @(posedge clk) begin if (rst) begin - input_select_ip_reg <= 1'b0; - input_select_arp_reg <= 1'b0; - input_select_none_reg <= 1'b0; + s_select_ip_reg <= 1'b0; + s_select_arp_reg <= 1'b0; + s_select_none_reg <= 1'b0; end else begin - if (input_eth_payload_tvalid) begin - if ((~input_select_ip_reg & ~input_select_arp_reg & ~input_select_none_reg) | - (input_eth_payload_tvalid & input_eth_payload_tready & input_eth_payload_tlast)) begin - input_select_ip_reg <= input_select_ip; - input_select_arp_reg <= input_select_arp; - input_select_none_reg <= input_select_none; + if (s_eth_payload_axis_tvalid) begin + if ((!s_select_ip_reg && !s_select_arp_reg && !s_select_none_reg) || + (s_eth_payload_axis_tvalid && s_eth_payload_axis_tready && s_eth_payload_axis_tlast)) begin + s_select_ip_reg <= s_select_ip; + s_select_arp_reg <= s_select_arp; + s_select_none_reg <= s_select_none; end end else begin - input_select_ip_reg <= 1'b0; - input_select_arp_reg <= 1'b0; - input_select_none_reg <= 1'b0; + s_select_ip_reg <= 1'b0; + s_select_arp_reg <= 1'b0; + s_select_none_reg <= 1'b0; end end end -assign ip_rx_eth_hdr_valid = input_select_ip & input_eth_hdr_valid; -assign ip_rx_eth_dest_mac = input_eth_dest_mac; -assign ip_rx_eth_src_mac = input_eth_src_mac; +assign ip_rx_eth_hdr_valid = s_select_ip && s_eth_hdr_valid; +assign ip_rx_eth_dest_mac = s_eth_dest_mac; +assign ip_rx_eth_src_mac = s_eth_src_mac; assign ip_rx_eth_type = 16'h0800; -assign ip_rx_eth_payload_tdata = input_eth_payload_tdata; -assign ip_rx_eth_payload_tkeep = input_eth_payload_tkeep; -assign ip_rx_eth_payload_tvalid = input_select_ip_reg & input_eth_payload_tvalid; -assign ip_rx_eth_payload_tlast = input_eth_payload_tlast; -assign ip_rx_eth_payload_tuser = input_eth_payload_tuser; +assign ip_rx_eth_payload_axis_tdata = s_eth_payload_axis_tdata; +assign ip_rx_eth_payload_axis_tkeep = s_eth_payload_axis_tkeep; +assign ip_rx_eth_payload_axis_tvalid = s_select_ip_reg && s_eth_payload_axis_tvalid; +assign ip_rx_eth_payload_axis_tlast = s_eth_payload_axis_tlast; +assign ip_rx_eth_payload_axis_tuser = s_eth_payload_axis_tuser; -assign arp_rx_eth_hdr_valid = input_select_arp & input_eth_hdr_valid; -assign arp_rx_eth_dest_mac = input_eth_dest_mac; -assign arp_rx_eth_src_mac = input_eth_src_mac; +assign arp_rx_eth_hdr_valid = s_select_arp && s_eth_hdr_valid; +assign arp_rx_eth_dest_mac = s_eth_dest_mac; +assign arp_rx_eth_src_mac = s_eth_src_mac; assign arp_rx_eth_type = 16'h0806; -assign arp_rx_eth_payload_tdata = input_eth_payload_tdata; -assign arp_rx_eth_payload_tkeep = input_eth_payload_tkeep; -assign arp_rx_eth_payload_tvalid = input_select_arp_reg & input_eth_payload_tvalid; -assign arp_rx_eth_payload_tlast = input_eth_payload_tlast; -assign arp_rx_eth_payload_tuser = input_eth_payload_tuser; +assign arp_rx_eth_payload_axis_tdata = s_eth_payload_axis_tdata; +assign arp_rx_eth_payload_axis_tkeep = s_eth_payload_axis_tkeep; +assign arp_rx_eth_payload_axis_tvalid = s_select_arp_reg && s_eth_payload_axis_tvalid; +assign arp_rx_eth_payload_axis_tlast = s_eth_payload_axis_tlast; +assign arp_rx_eth_payload_axis_tuser = s_eth_payload_axis_tuser; -assign input_eth_hdr_ready = (input_select_ip & ip_rx_eth_hdr_ready) | - (input_select_arp & arp_rx_eth_hdr_ready) | - (input_select_none); +assign s_eth_hdr_ready = (s_select_ip && ip_rx_eth_hdr_ready) || + (s_select_arp && arp_rx_eth_hdr_ready) || + (s_select_none); -assign input_eth_payload_tready = (input_select_ip_reg & ip_rx_eth_payload_tready) | - (input_select_arp_reg & arp_rx_eth_payload_tready) | - input_select_none_reg; +assign s_eth_payload_axis_tready = (s_select_ip_reg && ip_rx_eth_payload_axis_tready) || + (s_select_arp_reg && arp_rx_eth_payload_axis_tready) || + s_select_none_reg; /* * Output arbiter @@ -283,28 +283,28 @@ eth_arb_mux_inst ( .s_eth_dest_mac({ip_tx_eth_dest_mac, arp_tx_eth_dest_mac}), .s_eth_src_mac({ip_tx_eth_src_mac, arp_tx_eth_src_mac}), .s_eth_type({ip_tx_eth_type, arp_tx_eth_type}), - .s_eth_payload_axis_tdata({ip_tx_eth_payload_tdata, arp_tx_eth_payload_tdata}), - .s_eth_payload_axis_tkeep({ip_tx_eth_payload_tkeep, arp_tx_eth_payload_tkeep}), - .s_eth_payload_axis_tvalid({ip_tx_eth_payload_tvalid, arp_tx_eth_payload_tvalid}), - .s_eth_payload_axis_tready({ip_tx_eth_payload_tready, arp_tx_eth_payload_tready}), - .s_eth_payload_axis_tlast({ip_tx_eth_payload_tlast, arp_tx_eth_payload_tlast}), + .s_eth_payload_axis_tdata({ip_tx_eth_payload_axis_tdata, arp_tx_eth_payload_axis_tdata}), + .s_eth_payload_axis_tkeep({ip_tx_eth_payload_axis_tkeep, arp_tx_eth_payload_axis_tkeep}), + .s_eth_payload_axis_tvalid({ip_tx_eth_payload_axis_tvalid, arp_tx_eth_payload_axis_tvalid}), + .s_eth_payload_axis_tready({ip_tx_eth_payload_axis_tready, arp_tx_eth_payload_axis_tready}), + .s_eth_payload_axis_tlast({ip_tx_eth_payload_axis_tlast, arp_tx_eth_payload_axis_tlast}), .s_eth_payload_axis_tid(0), .s_eth_payload_axis_tdest(0), - .s_eth_payload_axis_tuser({ip_tx_eth_payload_tuser, arp_tx_eth_payload_tuser}), + .s_eth_payload_axis_tuser({ip_tx_eth_payload_axis_tuser, arp_tx_eth_payload_axis_tuser}), // Ethernet frame output - .m_eth_hdr_valid(output_eth_hdr_valid), - .m_eth_hdr_ready(output_eth_hdr_ready), - .m_eth_dest_mac(output_eth_dest_mac), - .m_eth_src_mac(output_eth_src_mac), - .m_eth_type(output_eth_type), - .m_eth_payload_axis_tdata(output_eth_payload_tdata), - .m_eth_payload_axis_tkeep(output_eth_payload_tkeep), - .m_eth_payload_axis_tvalid(output_eth_payload_tvalid), - .m_eth_payload_axis_tready(output_eth_payload_tready), - .m_eth_payload_axis_tlast(output_eth_payload_tlast), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), .m_eth_payload_axis_tid(), .m_eth_payload_axis_tdest(), - .m_eth_payload_axis_tuser(output_eth_payload_tuser) + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser) ); /* @@ -315,70 +315,70 @@ ip_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(ip_rx_eth_hdr_valid), - .input_eth_hdr_ready(ip_rx_eth_hdr_ready), - .input_eth_dest_mac(ip_rx_eth_dest_mac), - .input_eth_src_mac(ip_rx_eth_src_mac), - .input_eth_type(ip_rx_eth_type), - .input_eth_payload_tdata(ip_rx_eth_payload_tdata), - .input_eth_payload_tkeep(ip_rx_eth_payload_tkeep), - .input_eth_payload_tvalid(ip_rx_eth_payload_tvalid), - .input_eth_payload_tready(ip_rx_eth_payload_tready), - .input_eth_payload_tlast(ip_rx_eth_payload_tlast), - .input_eth_payload_tuser(ip_rx_eth_payload_tuser), + .s_eth_hdr_valid(ip_rx_eth_hdr_valid), + .s_eth_hdr_ready(ip_rx_eth_hdr_ready), + .s_eth_dest_mac(ip_rx_eth_dest_mac), + .s_eth_src_mac(ip_rx_eth_src_mac), + .s_eth_type(ip_rx_eth_type), + .s_eth_payload_axis_tdata(ip_rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(ip_rx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(ip_rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(ip_rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(ip_rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(ip_rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(ip_tx_eth_hdr_valid), - .output_eth_hdr_ready(ip_tx_eth_hdr_ready), - .output_eth_dest_mac(ip_tx_eth_dest_mac), - .output_eth_src_mac(ip_tx_eth_src_mac), - .output_eth_type(ip_tx_eth_type), - .output_eth_payload_tdata(ip_tx_eth_payload_tdata), - .output_eth_payload_tkeep(ip_tx_eth_payload_tkeep), - .output_eth_payload_tvalid(ip_tx_eth_payload_tvalid), - .output_eth_payload_tready(ip_tx_eth_payload_tready), - .output_eth_payload_tlast(ip_tx_eth_payload_tlast), - .output_eth_payload_tuser(ip_tx_eth_payload_tuser), + .m_eth_hdr_valid(ip_tx_eth_hdr_valid), + .m_eth_hdr_ready(ip_tx_eth_hdr_ready), + .m_eth_dest_mac(ip_tx_eth_dest_mac), + .m_eth_src_mac(ip_tx_eth_src_mac), + .m_eth_type(ip_tx_eth_type), + .m_eth_payload_axis_tdata(ip_tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(ip_tx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(ip_tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(ip_tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(ip_tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(ip_tx_eth_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_ip_eth_dest_mac(output_ip_eth_dest_mac), - .output_ip_eth_src_mac(output_ip_eth_src_mac), - .output_ip_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_ip_eth_dest_mac(m_ip_eth_dest_mac), + .m_ip_eth_src_mac(m_ip_eth_src_mac), + .m_ip_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tkeep(input_ip_payload_tkeep), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // ARP requests .arp_request_valid(arp_request_valid), .arp_request_ready(arp_request_ready), @@ -414,29 +414,29 @@ arp_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(arp_rx_eth_hdr_valid), - .input_eth_hdr_ready(arp_rx_eth_hdr_ready), - .input_eth_dest_mac(arp_rx_eth_dest_mac), - .input_eth_src_mac(arp_rx_eth_src_mac), - .input_eth_type(arp_rx_eth_type), - .input_eth_payload_tdata(arp_rx_eth_payload_tdata), - .input_eth_payload_tkeep(arp_rx_eth_payload_tkeep), - .input_eth_payload_tvalid(arp_rx_eth_payload_tvalid), - .input_eth_payload_tready(arp_rx_eth_payload_tready), - .input_eth_payload_tlast(arp_rx_eth_payload_tlast), - .input_eth_payload_tuser(arp_rx_eth_payload_tuser), + .s_eth_hdr_valid(arp_rx_eth_hdr_valid), + .s_eth_hdr_ready(arp_rx_eth_hdr_ready), + .s_eth_dest_mac(arp_rx_eth_dest_mac), + .s_eth_src_mac(arp_rx_eth_src_mac), + .s_eth_type(arp_rx_eth_type), + .s_eth_payload_axis_tdata(arp_rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(arp_rx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(arp_rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(arp_rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(arp_rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(arp_rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(arp_tx_eth_hdr_valid), - .output_eth_hdr_ready(arp_tx_eth_hdr_ready), - .output_eth_dest_mac(arp_tx_eth_dest_mac), - .output_eth_src_mac(arp_tx_eth_src_mac), - .output_eth_type(arp_tx_eth_type), - .output_eth_payload_tdata(arp_tx_eth_payload_tdata), - .output_eth_payload_tkeep(arp_tx_eth_payload_tkeep), - .output_eth_payload_tvalid(arp_tx_eth_payload_tvalid), - .output_eth_payload_tready(arp_tx_eth_payload_tready), - .output_eth_payload_tlast(arp_tx_eth_payload_tlast), - .output_eth_payload_tuser(arp_tx_eth_payload_tuser), + .m_eth_hdr_valid(arp_tx_eth_hdr_valid), + .m_eth_hdr_ready(arp_tx_eth_hdr_ready), + .m_eth_dest_mac(arp_tx_eth_dest_mac), + .m_eth_src_mac(arp_tx_eth_src_mac), + .m_eth_type(arp_tx_eth_type), + .m_eth_payload_axis_tdata(arp_tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(arp_tx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(arp_tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(arp_tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(arp_tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(arp_tx_eth_payload_axis_tuser), // ARP requests .arp_request_valid(arp_request_valid), .arp_request_ready(arp_request_ready), diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index 008b53537..1626f6a81 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -37,43 +37,43 @@ module ip_eth_rx /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [7:0] input_eth_payload_tdata, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [7:0] s_eth_payload_axis_tdata, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * IP frame output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [7:0] m_ip_payload_axis_tdata, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * Status signals @@ -155,26 +155,26 @@ reg [15:0] hdr_sum_reg = 16'd0, hdr_sum_next; reg [7:0] last_word_data_reg = 8'd0; -reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; +reg s_eth_hdr_ready_reg = 1'b0, s_eth_hdr_ready_next; +reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; -reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; -reg [3:0] output_ip_version_reg = 4'd0; -reg [3:0] output_ip_ihl_reg = 4'd0; -reg [5:0] output_ip_dscp_reg = 6'd0; -reg [1:0] output_ip_ecn_reg = 2'd0; -reg [15:0] output_ip_length_reg = 16'd0; -reg [15:0] output_ip_identification_reg = 16'd0; -reg [2:0] output_ip_flags_reg = 3'd0; -reg [12:0] output_ip_fragment_offset_reg = 13'd0; -reg [7:0] output_ip_ttl_reg = 8'd0; -reg [7:0] output_ip_protocol_reg = 8'd0; -reg [15:0] output_ip_header_checksum_reg = 16'd0; -reg [31:0] output_ip_source_ip_reg = 32'd0; -reg [31:0] output_ip_dest_ip_reg = 32'd0; +reg m_ip_hdr_valid_reg = 1'b0, m_ip_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; +reg [3:0] m_ip_version_reg = 4'd0; +reg [3:0] m_ip_ihl_reg = 4'd0; +reg [5:0] m_ip_dscp_reg = 6'd0; +reg [1:0] m_ip_ecn_reg = 2'd0; +reg [15:0] m_ip_length_reg = 16'd0; +reg [15:0] m_ip_identification_reg = 16'd0; +reg [2:0] m_ip_flags_reg = 3'd0; +reg [12:0] m_ip_fragment_offset_reg = 13'd0; +reg [7:0] m_ip_ttl_reg = 8'd0; +reg [7:0] m_ip_protocol_reg = 8'd0; +reg [15:0] m_ip_header_checksum_reg = 16'd0; +reg [31:0] m_ip_source_ip_reg = 32'd0; +reg [31:0] m_ip_dest_ip_reg = 32'd0; reg busy_reg = 1'b0; reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; @@ -183,33 +183,33 @@ reg error_invalid_header_reg = 1'b0, error_invalid_header_next; reg error_invalid_checksum_reg = 1'b0, error_invalid_checksum_next; // internal datapath -reg [7:0] output_ip_payload_tdata_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; +reg [7:0] m_ip_payload_axis_tdata_int; +reg m_ip_payload_axis_tvalid_int; +reg m_ip_payload_axis_tready_int_reg = 1'b0; +reg m_ip_payload_axis_tlast_int; +reg m_ip_payload_axis_tuser_int; +wire m_ip_payload_axis_tready_int_early; -assign input_eth_hdr_ready = input_eth_hdr_ready_reg; -assign input_eth_payload_tready = input_eth_payload_tready_reg; +assign s_eth_hdr_ready = s_eth_hdr_ready_reg; +assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign m_ip_hdr_valid = m_ip_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_ip_length_reg; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = m_ip_protocol_reg; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -229,8 +229,8 @@ endfunction always @* begin state_next = STATE_IDLE; - input_eth_hdr_ready_next = 1'b0; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b0; store_eth_hdr = 1'b0; store_ip_version_ihl = 1'b0; @@ -260,28 +260,28 @@ always @* begin hdr_sum_next = hdr_sum_reg; - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + m_ip_hdr_valid_next = m_ip_hdr_valid_reg && !m_ip_hdr_ready; error_header_early_termination_next = 1'b0; error_payload_early_termination_next = 1'b0; error_invalid_header_next = 1'b0; error_invalid_checksum_next = 1'b0; - output_ip_payload_tdata_int = 8'd0; - output_ip_payload_tvalid_int = 1'b0; - output_ip_payload_tlast_int = 1'b0; - output_ip_payload_tuser_int = 1'b0; + m_ip_payload_axis_tdata_int = 8'd0; + m_ip_payload_axis_tvalid_int = 1'b0; + m_ip_payload_axis_tlast_int = 1'b0; + m_ip_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for header frame_ptr_next = 16'd0; hdr_sum_next = 16'd0; - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; - if (input_eth_hdr_ready & input_eth_hdr_valid) begin - input_eth_hdr_ready_next = 1'b0; - input_eth_payload_tready_next = 1'b1; + if (s_eth_hdr_ready && s_eth_hdr_valid) begin + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b1; store_eth_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin @@ -290,17 +290,17 @@ always @* begin end STATE_READ_HEADER: begin // read header - input_eth_payload_tready_next = 1'b1; + s_eth_payload_axis_tready_next = 1'b1; - if (input_eth_payload_tready & input_eth_payload_tvalid) begin + if (s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg + 16'd1; state_next = STATE_READ_HEADER; if (frame_ptr_reg[0]) begin - hdr_sum_next = add1c16b(hdr_sum_reg, {8'd0, input_eth_payload_tdata}); + hdr_sum_next = add1c16b(hdr_sum_reg, {8'd0, s_eth_payload_axis_tdata}); end else begin - hdr_sum_next = add1c16b(hdr_sum_reg, {input_eth_payload_tdata, 8'd0}); + hdr_sum_next = add1c16b(hdr_sum_reg, {s_eth_payload_axis_tdata, 8'd0}); end case (frame_ptr_reg) @@ -325,25 +325,25 @@ always @* begin 8'h12: store_ip_dest_ip_1 = 1'b1; 8'h13: begin store_ip_dest_ip_0 = 1'b1; - if (output_ip_version_reg != 4'd4 || output_ip_ihl_reg != 4'd5) begin + if (m_ip_version_reg != 4'd4 || m_ip_ihl_reg != 4'd5) begin error_invalid_header_next = 1'b1; state_next = STATE_WAIT_LAST; end else if (hdr_sum_next != 16'hffff) begin error_invalid_checksum_next = 1'b1; state_next = STATE_WAIT_LAST; end else begin - output_ip_hdr_valid_next = 1'b1; - input_eth_payload_tready_next = output_ip_payload_tready_int_early; + m_ip_hdr_valid_next = 1'b1; + s_eth_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; state_next = STATE_READ_PAYLOAD; end end endcase - if (input_eth_payload_tlast) begin + if (s_eth_payload_axis_tlast) begin error_header_early_termination_next = 1'b1; - output_ip_hdr_valid_next = 1'b0; - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_eth_payload_tready_next = 1'b0; + m_ip_hdr_valid_next = 1'b0; + s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -353,29 +353,29 @@ always @* begin end STATE_READ_PAYLOAD: begin // read payload - input_eth_payload_tready_next = output_ip_payload_tready_int_early; + s_eth_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; - output_ip_payload_tdata_int = input_eth_payload_tdata; - output_ip_payload_tvalid_int = input_eth_payload_tvalid; - output_ip_payload_tlast_int = input_eth_payload_tlast; - output_ip_payload_tuser_int = input_eth_payload_tuser; + m_ip_payload_axis_tdata_int = s_eth_payload_axis_tdata; + m_ip_payload_axis_tvalid_int = s_eth_payload_axis_tvalid; + m_ip_payload_axis_tlast_int = s_eth_payload_axis_tlast; + m_ip_payload_axis_tuser_int = s_eth_payload_axis_tuser; - if (input_eth_payload_tready & input_eth_payload_tvalid) begin + if (s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg + 16'd1; - if (input_eth_payload_tlast) begin - if (frame_ptr_next != output_ip_length_reg) begin + if (s_eth_payload_axis_tlast) begin + if (frame_ptr_next != m_ip_length_reg) begin // end of frame, but length does not match - output_ip_payload_tuser_int = 1'b1; + m_ip_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; end - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin - if (frame_ptr_next == output_ip_length_reg) begin + if (frame_ptr_next == m_ip_length_reg) begin store_last_word = 1'b1; - output_ip_payload_tvalid_int = 1'b0; + m_ip_payload_axis_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; end else begin state_next = STATE_READ_PAYLOAD; @@ -387,17 +387,17 @@ always @* begin end STATE_READ_PAYLOAD_LAST: begin // read and discard until end of frame - input_eth_payload_tready_next = output_ip_payload_tready_int_early; + s_eth_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; - output_ip_payload_tdata_int = last_word_data_reg; - output_ip_payload_tvalid_int = input_eth_payload_tvalid & input_eth_payload_tlast; - output_ip_payload_tlast_int = input_eth_payload_tlast; - output_ip_payload_tuser_int = input_eth_payload_tuser; + m_ip_payload_axis_tdata_int = last_word_data_reg; + m_ip_payload_axis_tvalid_int = s_eth_payload_axis_tvalid && s_eth_payload_axis_tlast; + m_ip_payload_axis_tlast_int = s_eth_payload_axis_tlast; + m_ip_payload_axis_tuser_int = s_eth_payload_axis_tuser; - if (input_eth_payload_tready & input_eth_payload_tvalid) begin - if (input_eth_payload_tlast) begin - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_eth_payload_tready_next = 1'b0; + if (s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) begin + if (s_eth_payload_axis_tlast) begin + s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD_LAST; @@ -408,12 +408,12 @@ always @* begin end STATE_WAIT_LAST: begin // read and discard until end of frame - input_eth_payload_tready_next = 1'b1; + s_eth_payload_axis_tready_next = 1'b1; - if (input_eth_payload_tready & input_eth_payload_tvalid) begin - if (input_eth_payload_tlast) begin - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_eth_payload_tready_next = 1'b0; + if (s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) begin + if (s_eth_payload_axis_tlast) begin + s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -430,9 +430,9 @@ always @(posedge clk) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 16'd0; hdr_sum_reg <= 16'd0; - input_eth_hdr_ready_reg <= 1'b0; - input_eth_payload_tready_reg <= 1'b0; - output_ip_hdr_valid_reg <= 1'b0; + s_eth_hdr_ready_reg <= 1'b0; + s_eth_payload_axis_tready_reg <= 1'b0; + m_ip_hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; error_header_early_termination_reg <= 1'b0; error_payload_early_termination_reg <= 1'b0; @@ -445,10 +445,10 @@ always @(posedge clk) begin hdr_sum_reg <= hdr_sum_next; - input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; - input_eth_payload_tready_reg <= input_eth_payload_tready_next; + s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; + s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; - output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + m_ip_hdr_valid_reg <= m_ip_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; error_payload_early_termination_reg <= error_payload_early_termination_next; @@ -460,115 +460,115 @@ always @(posedge clk) begin // datapath if (store_eth_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; end if (store_last_word) begin - last_word_data_reg <= output_ip_payload_tdata_int; + last_word_data_reg <= m_ip_payload_axis_tdata_int; end - if (store_ip_version_ihl) {output_ip_version_reg, output_ip_ihl_reg} <= input_eth_payload_tdata; - if (store_ip_dscp_ecn) {output_ip_dscp_reg, output_ip_ecn_reg} <= input_eth_payload_tdata; - if (store_ip_length_0) output_ip_length_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_ip_length_1) output_ip_length_reg[15: 8] <= input_eth_payload_tdata; - if (store_ip_identification_0) output_ip_identification_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_ip_identification_1) output_ip_identification_reg[15: 8] <= input_eth_payload_tdata; - if (store_ip_flags_fragment_offset_0) output_ip_fragment_offset_reg[ 7:0] <= input_eth_payload_tdata; - if (store_ip_flags_fragment_offset_1) {output_ip_flags_reg, output_ip_fragment_offset_reg[12:8]} <= input_eth_payload_tdata; - if (store_ip_ttl) output_ip_ttl_reg <= input_eth_payload_tdata; - if (store_ip_protocol) output_ip_protocol_reg <= input_eth_payload_tdata; - if (store_ip_header_checksum_0) output_ip_header_checksum_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_ip_header_checksum_1) output_ip_header_checksum_reg[15: 8] <= input_eth_payload_tdata; - if (store_ip_source_ip_0) output_ip_source_ip_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_ip_source_ip_1) output_ip_source_ip_reg[15: 8] <= input_eth_payload_tdata; - if (store_ip_source_ip_2) output_ip_source_ip_reg[23:16] <= input_eth_payload_tdata; - if (store_ip_source_ip_3) output_ip_source_ip_reg[31:24] <= input_eth_payload_tdata; - if (store_ip_dest_ip_0) output_ip_dest_ip_reg[ 7: 0] <= input_eth_payload_tdata; - if (store_ip_dest_ip_1) output_ip_dest_ip_reg[15: 8] <= input_eth_payload_tdata; - if (store_ip_dest_ip_2) output_ip_dest_ip_reg[23:16] <= input_eth_payload_tdata; - if (store_ip_dest_ip_3) output_ip_dest_ip_reg[31:24] <= input_eth_payload_tdata; + if (store_ip_version_ihl) {m_ip_version_reg, m_ip_ihl_reg} <= s_eth_payload_axis_tdata; + if (store_ip_dscp_ecn) {m_ip_dscp_reg, m_ip_ecn_reg} <= s_eth_payload_axis_tdata; + if (store_ip_length_0) m_ip_length_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_ip_length_1) m_ip_length_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_ip_identification_0) m_ip_identification_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_ip_identification_1) m_ip_identification_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_ip_flags_fragment_offset_0) m_ip_fragment_offset_reg[ 7:0] <= s_eth_payload_axis_tdata; + if (store_ip_flags_fragment_offset_1) {m_ip_flags_reg, m_ip_fragment_offset_reg[12:8]} <= s_eth_payload_axis_tdata; + if (store_ip_ttl) m_ip_ttl_reg <= s_eth_payload_axis_tdata; + if (store_ip_protocol) m_ip_protocol_reg <= s_eth_payload_axis_tdata; + if (store_ip_header_checksum_0) m_ip_header_checksum_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_ip_header_checksum_1) m_ip_header_checksum_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_ip_source_ip_0) m_ip_source_ip_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_ip_source_ip_1) m_ip_source_ip_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_ip_source_ip_2) m_ip_source_ip_reg[23:16] <= s_eth_payload_axis_tdata; + if (store_ip_source_ip_3) m_ip_source_ip_reg[31:24] <= s_eth_payload_axis_tdata; + if (store_ip_dest_ip_0) m_ip_dest_ip_reg[ 7: 0] <= s_eth_payload_axis_tdata; + if (store_ip_dest_ip_1) m_ip_dest_ip_reg[15: 8] <= s_eth_payload_axis_tdata; + if (store_ip_dest_ip_2) m_ip_dest_ip_reg[23:16] <= s_eth_payload_axis_tdata; + if (store_ip_dest_ip_3) m_ip_dest_ip_reg[31:24] <= s_eth_payload_axis_tdata; end // output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 8'd0; -reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; +reg [7:0] m_ip_payload_axis_tdata_reg = 8'd0; +reg m_ip_payload_axis_tvalid_reg = 1'b0, m_ip_payload_axis_tvalid_next; +reg m_ip_payload_axis_tlast_reg = 1'b0; +reg m_ip_payload_axis_tuser_reg = 1'b0; -reg [7:0] temp_ip_payload_tdata_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; +reg [7:0] temp_m_ip_payload_axis_tdata_reg = 8'd0; +reg temp_m_ip_payload_axis_tvalid_reg = 1'b0, temp_m_ip_payload_axis_tvalid_next; +reg temp_m_ip_payload_axis_tlast_reg = 1'b0; +reg temp_m_ip_payload_axis_tuser_reg = 1'b0; // datapath control reg store_ip_payload_int_to_output; reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; +reg store_ip_payload_axis_temp_to_output; -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; +assign m_ip_payload_axis_tdata = m_ip_payload_axis_tdata_reg; +assign m_ip_payload_axis_tvalid = m_ip_payload_axis_tvalid_reg; +assign m_ip_payload_axis_tlast = m_ip_payload_axis_tlast_reg; +assign m_ip_payload_axis_tuser = m_ip_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); +assign m_ip_payload_axis_tready_int_early = m_ip_payload_axis_tready || (!temp_m_ip_payload_axis_tvalid_reg && (!m_ip_payload_axis_tvalid_reg || !m_ip_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; store_ip_payload_int_to_output = 1'b0; store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b0; - if (output_ip_payload_tready_int_reg) begin + if (m_ip_payload_axis_tready_int_reg) begin // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + if (m_ip_payload_axis_tready || !m_ip_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; store_ip_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + temp_m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; store_ip_payload_int_to_temp = 1'b1; end - end else if (output_ip_payload_tready) begin + end else if (m_ip_payload_axis_tready) begin // input is not ready, but output is ready - output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; + m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; + m_ip_payload_axis_tvalid_reg <= 1'b0; + m_ip_payload_axis_tready_int_reg <= 1'b0; + temp_m_ip_payload_axis_tvalid_reg <= 1'b0; end else begin - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + m_ip_payload_axis_tvalid_reg <= m_ip_payload_axis_tvalid_next; + m_ip_payload_axis_tready_int_reg <= m_ip_payload_axis_tready_int_early; + temp_m_ip_payload_axis_tvalid_reg <= temp_m_ip_payload_axis_tvalid_next; end // datapath if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; + end else if (store_ip_payload_axis_temp_to_output) begin + m_ip_payload_axis_tdata_reg <= temp_m_ip_payload_axis_tdata_reg; + m_ip_payload_axis_tlast_reg <= temp_m_ip_payload_axis_tlast_reg; + m_ip_payload_axis_tuser_reg <= temp_m_ip_payload_axis_tuser_reg; end if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + temp_m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + temp_m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + temp_m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; end end diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 0d82e4c8b..ae16f5e99 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -37,45 +37,45 @@ module ip_eth_rx_64 /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [63:0] input_eth_payload_tdata, - input wire [7:0] input_eth_payload_tkeep, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [63:0] s_eth_payload_axis_tdata, + input wire [7:0] s_eth_payload_axis_tkeep, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * IP frame output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [63:0] m_ip_payload_axis_tdata, + output wire [7:0] m_ip_payload_axis_tkeep, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * Status signals @@ -146,26 +146,26 @@ reg check_hdr_reg = 1'b0, check_hdr_next; reg [63:0] last_word_data_reg = 64'd0; reg [7:0] last_word_keep_reg = 8'd0; -reg input_eth_hdr_ready_reg = 1'b0, input_eth_hdr_ready_next; -reg input_eth_payload_tready_reg = 1'b0, input_eth_payload_tready_next; +reg s_eth_hdr_ready_reg = 1'b0, s_eth_hdr_ready_next; +reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; -reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; -reg [3:0] output_ip_version_reg = 4'd0; -reg [3:0] output_ip_ihl_reg = 4'd0; -reg [5:0] output_ip_dscp_reg = 6'd0; -reg [1:0] output_ip_ecn_reg = 2'd0; -reg [15:0] output_ip_length_reg = 16'd0; -reg [15:0] output_ip_identification_reg = 16'd0; -reg [2:0] output_ip_flags_reg = 3'd0; -reg [12:0] output_ip_fragment_offset_reg = 13'd0; -reg [7:0] output_ip_ttl_reg = 8'd0; -reg [7:0] output_ip_protocol_reg = 8'd0; -reg [15:0] output_ip_header_checksum_reg = 16'd0; -reg [31:0] output_ip_source_ip_reg = 32'd0; -reg [31:0] output_ip_dest_ip_reg = 32'd0; +reg m_ip_hdr_valid_reg = 1'b0, m_ip_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; +reg [3:0] m_ip_version_reg = 4'd0; +reg [3:0] m_ip_ihl_reg = 4'd0; +reg [5:0] m_ip_dscp_reg = 6'd0; +reg [1:0] m_ip_ecn_reg = 2'd0; +reg [15:0] m_ip_length_reg = 16'd0; +reg [15:0] m_ip_identification_reg = 16'd0; +reg [2:0] m_ip_flags_reg = 3'd0; +reg [12:0] m_ip_fragment_offset_reg = 13'd0; +reg [7:0] m_ip_ttl_reg = 8'd0; +reg [7:0] m_ip_protocol_reg = 8'd0; +reg [15:0] m_ip_header_checksum_reg = 16'd0; +reg [31:0] m_ip_source_ip_reg = 32'd0; +reg [31:0] m_ip_dest_ip_reg = 32'd0; reg busy_reg = 1'b0; reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; @@ -173,48 +173,48 @@ reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_ reg error_invalid_header_reg = 1'b0, error_invalid_header_next; reg error_invalid_checksum_reg = 1'b0, error_invalid_checksum_next; -reg [63:0] save_eth_payload_tdata_reg = 64'd0; -reg [7:0] save_eth_payload_tkeep_reg = 8'd0; -reg save_eth_payload_tlast_reg = 1'b0; -reg save_eth_payload_tuser_reg = 1'b0; +reg [63:0] save_eth_payload_axis_tdata_reg = 64'd0; +reg [7:0] save_eth_payload_axis_tkeep_reg = 8'd0; +reg save_eth_payload_axis_tlast_reg = 1'b0; +reg save_eth_payload_axis_tuser_reg = 1'b0; -reg [63:0] shift_eth_payload_tdata; -reg [7:0] shift_eth_payload_tkeep; -reg shift_eth_payload_tvalid; -reg shift_eth_payload_tlast; -reg shift_eth_payload_tuser; -reg shift_eth_payload_input_tready; +reg [63:0] shift_eth_payload_axis_tdata; +reg [7:0] shift_eth_payload_axis_tkeep; +reg shift_eth_payload_axis_tvalid; +reg shift_eth_payload_axis_tlast; +reg shift_eth_payload_axis_tuser; +reg shift_eth_payload_s_tready; reg shift_eth_payload_extra_cycle; // internal datapath -reg [63:0] output_ip_payload_tdata_int; -reg [7:0] output_ip_payload_tkeep_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; +reg [63:0] m_ip_payload_axis_tdata_int; +reg [7:0] m_ip_payload_axis_tkeep_int; +reg m_ip_payload_axis_tvalid_int; +reg m_ip_payload_axis_tready_int_reg = 1'b0; +reg m_ip_payload_axis_tlast_int; +reg m_ip_payload_axis_tuser_int; +wire m_ip_payload_axis_tready_int_early; -assign input_eth_hdr_ready = input_eth_hdr_ready_reg; -assign input_eth_payload_tready = input_eth_payload_tready_reg; +assign s_eth_hdr_ready = s_eth_hdr_ready_reg; +assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign m_ip_hdr_valid = m_ip_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_ip_length_reg; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = m_ip_protocol_reg; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -253,24 +253,24 @@ function [7:0] count2keep; endfunction always @* begin - shift_eth_payload_tdata[31:0] = save_eth_payload_tdata_reg[63:32]; - shift_eth_payload_tkeep[3:0] = save_eth_payload_tkeep_reg[7:4]; - shift_eth_payload_extra_cycle = save_eth_payload_tlast_reg & (save_eth_payload_tkeep_reg[7:4] != 0); + shift_eth_payload_axis_tdata[31:0] = save_eth_payload_axis_tdata_reg[63:32]; + shift_eth_payload_axis_tkeep[3:0] = save_eth_payload_axis_tkeep_reg[7:4]; + shift_eth_payload_extra_cycle = save_eth_payload_axis_tlast_reg && (save_eth_payload_axis_tkeep_reg[7:4] != 0); if (shift_eth_payload_extra_cycle) begin - shift_eth_payload_tdata[63:32] = 32'd0; - shift_eth_payload_tkeep[7:4] = 4'd0; - shift_eth_payload_tvalid = 1'b1; - shift_eth_payload_tlast = save_eth_payload_tlast_reg; - shift_eth_payload_tuser = save_eth_payload_tuser_reg; - shift_eth_payload_input_tready = flush_save; + shift_eth_payload_axis_tdata[63:32] = 32'd0; + shift_eth_payload_axis_tkeep[7:4] = 4'd0; + shift_eth_payload_axis_tvalid = 1'b1; + shift_eth_payload_axis_tlast = save_eth_payload_axis_tlast_reg; + shift_eth_payload_axis_tuser = save_eth_payload_axis_tuser_reg; + shift_eth_payload_s_tready = flush_save; end else begin - shift_eth_payload_tdata[63:32] = input_eth_payload_tdata[31:0]; - shift_eth_payload_tkeep[7:4] = input_eth_payload_tkeep[3:0]; - shift_eth_payload_tvalid = input_eth_payload_tvalid; - shift_eth_payload_tlast = (input_eth_payload_tlast & (input_eth_payload_tkeep[7:4] == 0)); - shift_eth_payload_tuser = (input_eth_payload_tuser & (input_eth_payload_tkeep[7:4] == 0)); - shift_eth_payload_input_tready = ~(input_eth_payload_tlast & input_eth_payload_tvalid & transfer_in_save); + shift_eth_payload_axis_tdata[63:32] = s_eth_payload_axis_tdata[31:0]; + shift_eth_payload_axis_tkeep[7:4] = s_eth_payload_axis_tkeep[3:0]; + shift_eth_payload_axis_tvalid = s_eth_payload_axis_tvalid; + shift_eth_payload_axis_tlast = (s_eth_payload_axis_tlast && (s_eth_payload_axis_tkeep[7:4] == 0)); + shift_eth_payload_axis_tuser = (s_eth_payload_axis_tuser && (s_eth_payload_axis_tkeep[7:4] == 0)); + shift_eth_payload_s_tready = !(s_eth_payload_axis_tlast && s_eth_payload_axis_tvalid && transfer_in_save); end end @@ -280,8 +280,8 @@ always @* begin flush_save = 1'b0; transfer_in_save = 1'b0; - input_eth_hdr_ready_next = 1'b0; - input_eth_payload_tready_next = 1'b0; + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b0; store_eth_hdr = 1'b0; store_hdr_word_0 = 1'b0; @@ -296,18 +296,18 @@ always @* begin hdr_sum_next = hdr_sum_reg; check_hdr_next = check_hdr_reg; - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + m_ip_hdr_valid_next = m_ip_hdr_valid_reg && !m_ip_hdr_ready; error_header_early_termination_next = 1'b0; error_payload_early_termination_next = 1'b0; error_invalid_header_next = 1'b0; error_invalid_checksum_next = 1'b0; - output_ip_payload_tdata_int = 64'd0; - output_ip_payload_tkeep_int = 8'd0; - output_ip_payload_tvalid_int = 1'b0; - output_ip_payload_tlast_int = 1'b0; - output_ip_payload_tuser_int = 1'b0; + m_ip_payload_axis_tdata_int = 64'd0; + m_ip_payload_axis_tkeep_int = 8'd0; + m_ip_payload_axis_tvalid_int = 1'b0; + m_ip_payload_axis_tlast_int = 1'b0; + m_ip_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin @@ -315,11 +315,11 @@ always @* begin frame_ptr_next = 16'd0; hdr_sum_next = 32'd0; flush_save = 1'b1; - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; - if (input_eth_hdr_ready & input_eth_hdr_valid) begin - input_eth_hdr_ready_next = 1'b0; - input_eth_payload_tready_next = 1'b1; + if (s_eth_hdr_ready && s_eth_hdr_valid) begin + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b1; store_eth_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin @@ -328,9 +328,9 @@ always @* begin end STATE_READ_HEADER: begin // read header - input_eth_payload_tready_next = shift_eth_payload_input_tready; + s_eth_payload_axis_tready_next = shift_eth_payload_s_tready; - if (input_eth_payload_tvalid) begin + if (s_eth_payload_axis_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg + 16'd8; transfer_in_save = 1'b1; @@ -339,47 +339,47 @@ always @* begin case (frame_ptr_reg) 8'h00: begin store_hdr_word_0 = 1'b1; - hdr_sum_next = input_eth_payload_tdata[15:0] + - input_eth_payload_tdata[31:16] + - input_eth_payload_tdata[47:32] + - input_eth_payload_tdata[63:48]; + hdr_sum_next = s_eth_payload_axis_tdata[15:0] + + s_eth_payload_axis_tdata[31:16] + + s_eth_payload_axis_tdata[47:32] + + s_eth_payload_axis_tdata[63:48]; end 8'h08: begin store_hdr_word_1 = 1'b1; hdr_sum_next = hdr_sum_reg + - input_eth_payload_tdata[15:0] + - input_eth_payload_tdata[31:16] + - input_eth_payload_tdata[47:32] + - input_eth_payload_tdata[63:48]; + s_eth_payload_axis_tdata[15:0] + + s_eth_payload_axis_tdata[31:16] + + s_eth_payload_axis_tdata[47:32] + + s_eth_payload_axis_tdata[63:48]; end 8'h10: begin store_hdr_word_2 = 1'b1; hdr_sum_next = hdr_sum_reg + - input_eth_payload_tdata[15:0] + - input_eth_payload_tdata[31:16]; + s_eth_payload_axis_tdata[15:0] + + s_eth_payload_axis_tdata[31:16]; frame_ptr_next = frame_ptr_reg + 16'd4; // check header checksum on next cycle for improved timing check_hdr_next = 1'b1; - if (output_ip_version_reg != 4'd4 || output_ip_ihl_reg != 4'd5) begin + if (m_ip_version_reg != 4'd4 || m_ip_ihl_reg != 4'd5) begin error_invalid_header_next = 1'b1; - input_eth_payload_tready_next = shift_eth_payload_input_tready; + s_eth_payload_axis_tready_next = shift_eth_payload_s_tready; state_next = STATE_WAIT_LAST; end else begin - input_eth_payload_tready_next = output_ip_payload_tready_int_early & shift_eth_payload_input_tready; + s_eth_payload_axis_tready_next = m_ip_payload_axis_tready_int_early && shift_eth_payload_s_tready; state_next = STATE_READ_PAYLOAD; end end endcase - if (shift_eth_payload_tlast) begin + if (shift_eth_payload_axis_tlast) begin error_header_early_termination_next = 1'b1; error_invalid_header_next = 1'b0; error_invalid_checksum_next = 1'b0; - output_ip_hdr_valid_next = 1'b0; - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_eth_payload_tready_next = 1'b0; + m_ip_hdr_valid_next = 1'b0; + s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -389,40 +389,40 @@ always @* begin end STATE_READ_PAYLOAD: begin // read payload - input_eth_payload_tready_next = output_ip_payload_tready_int_early & shift_eth_payload_input_tready; + s_eth_payload_axis_tready_next = m_ip_payload_axis_tready_int_early && shift_eth_payload_s_tready; - output_ip_payload_tdata_int = shift_eth_payload_tdata; - output_ip_payload_tkeep_int = shift_eth_payload_tkeep; - output_ip_payload_tvalid_int = shift_eth_payload_tvalid; - output_ip_payload_tlast_int = shift_eth_payload_tlast; - output_ip_payload_tuser_int = shift_eth_payload_tuser; + m_ip_payload_axis_tdata_int = shift_eth_payload_axis_tdata; + m_ip_payload_axis_tkeep_int = shift_eth_payload_axis_tkeep; + m_ip_payload_axis_tvalid_int = shift_eth_payload_axis_tvalid; + m_ip_payload_axis_tlast_int = shift_eth_payload_axis_tlast; + m_ip_payload_axis_tuser_int = shift_eth_payload_axis_tuser; - if (output_ip_payload_tready_int_reg & shift_eth_payload_tvalid) begin + if (m_ip_payload_axis_tready_int_reg && shift_eth_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_tkeep); + frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_axis_tkeep); transfer_in_save = 1'b1; - if (frame_ptr_next >= output_ip_length_reg) begin + if (frame_ptr_next >= m_ip_length_reg) begin // have entire payload - frame_ptr_next = output_ip_length_reg; - output_ip_payload_tkeep_int = shift_eth_payload_tkeep & count2keep(output_ip_length_reg - frame_ptr_reg); - if (shift_eth_payload_tlast) begin - input_eth_payload_tready_next = 1'b0; + frame_ptr_next = m_ip_length_reg; + m_ip_payload_axis_tkeep_int = shift_eth_payload_axis_tkeep & count2keep(m_ip_length_reg - frame_ptr_reg); + if (shift_eth_payload_axis_tlast) begin + s_eth_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg & ~check_hdr_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_reg && !check_hdr_reg; state_next = STATE_IDLE; end else begin store_last_word = 1'b1; - output_ip_payload_tvalid_int = 1'b0; + m_ip_payload_axis_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; end end else begin - if (shift_eth_payload_tlast) begin + if (shift_eth_payload_axis_tlast) begin // end of frame, but length does not match error_payload_early_termination_next = 1'b1; - output_ip_payload_tuser_int = 1'b1; - input_eth_payload_tready_next = 1'b0; + m_ip_payload_axis_tuser_int = 1'b1; + s_eth_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg & ~check_hdr_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_reg && !check_hdr_reg; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD; @@ -441,38 +441,38 @@ always @* begin if (hdr_sum_temp != 16'hffff) begin // bad checksum error_invalid_checksum_next = 1'b1; - output_ip_payload_tvalid_int = 1'b0; - if (shift_eth_payload_tlast & shift_eth_payload_tvalid) begin + m_ip_payload_axis_tvalid_int = 1'b0; + if (shift_eth_payload_axis_tlast && shift_eth_payload_axis_tvalid) begin // only one payload cycle; return to idle now - input_eth_hdr_ready_next = ~output_ip_hdr_valid_reg & ~check_hdr_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_reg && !check_hdr_reg; state_next = STATE_IDLE; end else begin // drop payload - input_eth_payload_tready_next = shift_eth_payload_input_tready; + s_eth_payload_axis_tready_next = shift_eth_payload_s_tready; state_next = STATE_WAIT_LAST; end end else begin // good checksum; transfer header - output_ip_hdr_valid_next = 1'b1; + m_ip_hdr_valid_next = 1'b1; end end end STATE_READ_PAYLOAD_LAST: begin // read and discard until end of frame - input_eth_payload_tready_next = output_ip_payload_tready_int_early & shift_eth_payload_input_tready; + s_eth_payload_axis_tready_next = m_ip_payload_axis_tready_int_early && shift_eth_payload_s_tready; - output_ip_payload_tdata_int = last_word_data_reg; - output_ip_payload_tkeep_int = last_word_keep_reg; - output_ip_payload_tvalid_int = shift_eth_payload_tvalid & shift_eth_payload_tlast; - output_ip_payload_tlast_int = shift_eth_payload_tlast; - output_ip_payload_tuser_int = shift_eth_payload_tuser; + m_ip_payload_axis_tdata_int = last_word_data_reg; + m_ip_payload_axis_tkeep_int = last_word_keep_reg; + m_ip_payload_axis_tvalid_int = shift_eth_payload_axis_tvalid && shift_eth_payload_axis_tlast; + m_ip_payload_axis_tlast_int = shift_eth_payload_axis_tlast; + m_ip_payload_axis_tuser_int = shift_eth_payload_axis_tuser; - if (output_ip_payload_tready_int_reg & shift_eth_payload_tvalid) begin + if (m_ip_payload_axis_tready_int_reg && shift_eth_payload_axis_tvalid) begin transfer_in_save = 1'b1; - if (shift_eth_payload_tlast) begin - input_eth_payload_tready_next = 1'b0; + if (shift_eth_payload_axis_tlast) begin + s_eth_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - input_eth_hdr_ready_next = 1'b1; + s_eth_hdr_ready_next = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD_LAST; @@ -483,14 +483,14 @@ always @* begin end STATE_WAIT_LAST: begin // read and discard until end of frame - input_eth_payload_tready_next = shift_eth_payload_input_tready; + s_eth_payload_axis_tready_next = shift_eth_payload_s_tready; - if (shift_eth_payload_tvalid) begin + if (shift_eth_payload_axis_tvalid) begin transfer_in_save = 1'b1; - if (shift_eth_payload_tlast) begin - input_eth_payload_tready_next = 1'b0; + if (shift_eth_payload_axis_tlast) begin + s_eth_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - input_eth_hdr_ready_next = 1'b1; + s_eth_hdr_ready_next = 1'b1; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -508,10 +508,10 @@ always @(posedge clk) begin frame_ptr_reg <= 16'd0; hdr_sum_reg <= 16'd0; check_hdr_reg <= 1'b0; - input_eth_hdr_ready_reg <= 1'b0; - input_eth_payload_tready_reg <= 1'b0; - output_ip_hdr_valid_reg <= 1'b0; - save_eth_payload_tlast_reg <= 1'b0; + s_eth_hdr_ready_reg <= 1'b0; + s_eth_payload_axis_tready_reg <= 1'b0; + m_ip_hdr_valid_reg <= 1'b0; + save_eth_payload_axis_tlast_reg <= 1'b0; busy_reg <= 1'b0; error_header_early_termination_reg <= 1'b0; error_payload_early_termination_reg <= 1'b0; @@ -525,10 +525,10 @@ always @(posedge clk) begin hdr_sum_reg <= hdr_sum_next; check_hdr_reg <= check_hdr_next; - input_eth_hdr_ready_reg <= input_eth_hdr_ready_next; - input_eth_payload_tready_reg <= input_eth_payload_tready_next; + s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; + s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; - output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + m_ip_hdr_valid_reg <= m_ip_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; error_payload_early_termination_reg <= error_payload_early_termination_next; @@ -539,144 +539,144 @@ always @(posedge clk) begin // datapath if (flush_save) begin - save_eth_payload_tlast_reg <= 1'b0; + save_eth_payload_axis_tlast_reg <= 1'b0; end else if (transfer_in_save) begin - save_eth_payload_tlast_reg <= input_eth_payload_tlast; + save_eth_payload_axis_tlast_reg <= s_eth_payload_axis_tlast; end end // datapath if (store_eth_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; end if (store_last_word) begin - last_word_data_reg <= output_ip_payload_tdata_int; - last_word_keep_reg <= output_ip_payload_tkeep_int; + last_word_data_reg <= m_ip_payload_axis_tdata_int; + last_word_keep_reg <= m_ip_payload_axis_tkeep_int; end if (store_hdr_word_0) begin - {output_ip_version_reg, output_ip_ihl_reg} <= input_eth_payload_tdata[ 7: 0]; - {output_ip_dscp_reg, output_ip_ecn_reg} <= input_eth_payload_tdata[15: 8]; - output_ip_length_reg[15: 8] <= input_eth_payload_tdata[23:16]; - output_ip_length_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; - output_ip_identification_reg[15: 8] <= input_eth_payload_tdata[39:32]; - output_ip_identification_reg[ 7: 0] <= input_eth_payload_tdata[47:40]; - {output_ip_flags_reg, output_ip_fragment_offset_reg[12:8]} <= input_eth_payload_tdata[55:48]; - output_ip_fragment_offset_reg[ 7:0] <= input_eth_payload_tdata[63:56]; + {m_ip_version_reg, m_ip_ihl_reg} <= s_eth_payload_axis_tdata[ 7: 0]; + {m_ip_dscp_reg, m_ip_ecn_reg} <= s_eth_payload_axis_tdata[15: 8]; + m_ip_length_reg[15: 8] <= s_eth_payload_axis_tdata[23:16]; + m_ip_length_reg[ 7: 0] <= s_eth_payload_axis_tdata[31:24]; + m_ip_identification_reg[15: 8] <= s_eth_payload_axis_tdata[39:32]; + m_ip_identification_reg[ 7: 0] <= s_eth_payload_axis_tdata[47:40]; + {m_ip_flags_reg, m_ip_fragment_offset_reg[12:8]} <= s_eth_payload_axis_tdata[55:48]; + m_ip_fragment_offset_reg[ 7:0] <= s_eth_payload_axis_tdata[63:56]; end if (store_hdr_word_1) begin - output_ip_ttl_reg <= input_eth_payload_tdata[ 7: 0]; - output_ip_protocol_reg <= input_eth_payload_tdata[15: 8]; - output_ip_header_checksum_reg[15: 8] <= input_eth_payload_tdata[23:16]; - output_ip_header_checksum_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; - output_ip_source_ip_reg[31:24] <= input_eth_payload_tdata[39:32]; - output_ip_source_ip_reg[23:16] <= input_eth_payload_tdata[47:40]; - output_ip_source_ip_reg[15: 8] <= input_eth_payload_tdata[55:48]; - output_ip_source_ip_reg[ 7: 0] <= input_eth_payload_tdata[63:56]; + m_ip_ttl_reg <= s_eth_payload_axis_tdata[ 7: 0]; + m_ip_protocol_reg <= s_eth_payload_axis_tdata[15: 8]; + m_ip_header_checksum_reg[15: 8] <= s_eth_payload_axis_tdata[23:16]; + m_ip_header_checksum_reg[ 7: 0] <= s_eth_payload_axis_tdata[31:24]; + m_ip_source_ip_reg[31:24] <= s_eth_payload_axis_tdata[39:32]; + m_ip_source_ip_reg[23:16] <= s_eth_payload_axis_tdata[47:40]; + m_ip_source_ip_reg[15: 8] <= s_eth_payload_axis_tdata[55:48]; + m_ip_source_ip_reg[ 7: 0] <= s_eth_payload_axis_tdata[63:56]; end if (store_hdr_word_2) begin - output_ip_dest_ip_reg[31:24] <= input_eth_payload_tdata[ 7: 0]; - output_ip_dest_ip_reg[23:16] <= input_eth_payload_tdata[15: 8]; - output_ip_dest_ip_reg[15: 8] <= input_eth_payload_tdata[23:16]; - output_ip_dest_ip_reg[ 7: 0] <= input_eth_payload_tdata[31:24]; + m_ip_dest_ip_reg[31:24] <= s_eth_payload_axis_tdata[ 7: 0]; + m_ip_dest_ip_reg[23:16] <= s_eth_payload_axis_tdata[15: 8]; + m_ip_dest_ip_reg[15: 8] <= s_eth_payload_axis_tdata[23:16]; + m_ip_dest_ip_reg[ 7: 0] <= s_eth_payload_axis_tdata[31:24]; end if (transfer_in_save) begin - save_eth_payload_tdata_reg <= input_eth_payload_tdata; - save_eth_payload_tkeep_reg <= input_eth_payload_tkeep; - save_eth_payload_tuser_reg <= input_eth_payload_tuser; + save_eth_payload_axis_tdata_reg <= s_eth_payload_axis_tdata; + save_eth_payload_axis_tkeep_reg <= s_eth_payload_axis_tkeep; + save_eth_payload_axis_tuser_reg <= s_eth_payload_axis_tuser; end end // output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 64'd0; -reg [7:0] output_ip_payload_tkeep_reg = 8'd0; -reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; +reg [63:0] m_ip_payload_axis_tdata_reg = 64'd0; +reg [7:0] m_ip_payload_axis_tkeep_reg = 8'd0; +reg m_ip_payload_axis_tvalid_reg = 1'b0, m_ip_payload_axis_tvalid_next; +reg m_ip_payload_axis_tlast_reg = 1'b0; +reg m_ip_payload_axis_tuser_reg = 1'b0; -reg [63:0] temp_ip_payload_tdata_reg = 64'd0; -reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; +reg [63:0] temp_m_ip_payload_axis_tdata_reg = 64'd0; +reg [7:0] temp_m_ip_payload_axis_tkeep_reg = 8'd0; +reg temp_m_ip_payload_axis_tvalid_reg = 1'b0, temp_m_ip_payload_axis_tvalid_next; +reg temp_m_ip_payload_axis_tlast_reg = 1'b0; +reg temp_m_ip_payload_axis_tuser_reg = 1'b0; // datapath control reg store_ip_payload_int_to_output; reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; +reg store_ip_payload_axis_temp_to_output; -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; +assign m_ip_payload_axis_tdata = m_ip_payload_axis_tdata_reg; +assign m_ip_payload_axis_tkeep = m_ip_payload_axis_tkeep_reg; +assign m_ip_payload_axis_tvalid = m_ip_payload_axis_tvalid_reg; +assign m_ip_payload_axis_tlast = m_ip_payload_axis_tlast_reg; +assign m_ip_payload_axis_tuser = m_ip_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); +assign m_ip_payload_axis_tready_int_early = m_ip_payload_axis_tready || (!temp_m_ip_payload_axis_tvalid_reg && (!m_ip_payload_axis_tvalid_reg || !m_ip_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; store_ip_payload_int_to_output = 1'b0; store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b0; - if (output_ip_payload_tready_int_reg) begin + if (m_ip_payload_axis_tready_int_reg) begin // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + if (m_ip_payload_axis_tready || !m_ip_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; store_ip_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + temp_m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; store_ip_payload_int_to_temp = 1'b1; end - end else if (output_ip_payload_tready) begin + end else if (m_ip_payload_axis_tready) begin // input is not ready, but output is ready - output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; + m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; + m_ip_payload_axis_tvalid_reg <= 1'b0; + m_ip_payload_axis_tready_int_reg <= 1'b0; + temp_m_ip_payload_axis_tvalid_reg <= 1'b0; end else begin - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + m_ip_payload_axis_tvalid_reg <= m_ip_payload_axis_tvalid_next; + m_ip_payload_axis_tready_int_reg <= m_ip_payload_axis_tready_int_early; + temp_m_ip_payload_axis_tvalid_reg <= temp_m_ip_payload_axis_tvalid_next; end // datapath if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + m_ip_payload_axis_tkeep_reg <= m_ip_payload_axis_tkeep_int; + m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; + end else if (store_ip_payload_axis_temp_to_output) begin + m_ip_payload_axis_tdata_reg <= temp_m_ip_payload_axis_tdata_reg; + m_ip_payload_axis_tkeep_reg <= temp_m_ip_payload_axis_tkeep_reg; + m_ip_payload_axis_tlast_reg <= temp_m_ip_payload_axis_tlast_reg; + m_ip_payload_axis_tuser_reg <= temp_m_ip_payload_axis_tuser_reg; end if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + temp_m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + temp_m_ip_payload_axis_tkeep_reg <= m_ip_payload_axis_tkeep_int; + temp_m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + temp_m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; end end diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 5a7f2da05..d48d987c8 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -37,40 +37,40 @@ module ip_eth_tx /* * IP frame input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [7:0] input_ip_payload_tdata, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [7:0] s_ip_payload_axis_tdata, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [7:0] m_eth_payload_axis_tdata, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * Status signals @@ -140,32 +140,32 @@ reg [7:0] ip_protocol_reg = 8'd0; reg [31:0] ip_source_ip_reg = 32'd0; reg [31:0] ip_dest_ip_reg = 32'd0; -reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; +reg s_ip_hdr_ready_reg = 1'b0, s_ip_hdr_ready_next; +reg s_ip_payload_axis_tready_reg = 1'b0, s_ip_payload_axis_tready_next; -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; +reg m_eth_hdr_valid_reg = 1'b0, m_eth_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; reg busy_reg = 1'b0; reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; // internal datapath -reg [7:0] output_eth_payload_tdata_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; +reg [7:0] m_eth_payload_axis_tdata_int; +reg m_eth_payload_axis_tvalid_int; +reg m_eth_payload_axis_tready_int_reg = 1'b0; +reg m_eth_payload_axis_tlast_int; +reg m_eth_payload_axis_tuser_int; +wire m_eth_payload_axis_tready_int_early; -assign input_ip_hdr_ready = input_ip_hdr_ready_reg; -assign input_ip_payload_tready = input_ip_payload_tready_reg; +assign s_ip_hdr_ready = s_ip_hdr_ready_reg; +assign s_ip_payload_axis_tready = s_ip_payload_axis_tready_reg; -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; +assign m_eth_hdr_valid = m_eth_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; assign busy = busy_reg; assign error_payload_early_termination = error_payload_early_termination_reg; @@ -182,8 +182,8 @@ endfunction always @* begin state_next = STATE_IDLE; - input_ip_hdr_ready_next = 1'b0; - input_ip_payload_tready_next = 1'b0; + s_ip_hdr_ready_next = 1'b0; + s_ip_payload_axis_tready_next = 1'b0; store_ip_hdr = 1'b0; @@ -193,28 +193,28 @@ always @* begin hdr_sum_next = hdr_sum_reg; - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; error_payload_early_termination_next = 1'b0; - output_eth_payload_tdata_int = 8'd0; - output_eth_payload_tvalid_int = 1'b0; - output_eth_payload_tlast_int = 1'b0; - output_eth_payload_tuser_int = 1'b0; + m_eth_payload_axis_tdata_int = 8'd0; + m_eth_payload_axis_tvalid_int = 1'b0; + m_eth_payload_axis_tlast_int = 1'b0; + m_eth_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 16'd0; - input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; - if (input_ip_hdr_ready & input_ip_hdr_valid) begin + if (s_ip_hdr_ready && s_ip_hdr_valid) begin store_ip_hdr = 1'b1; - input_ip_hdr_ready_next = 1'b0; - output_eth_hdr_valid_next = 1'b1; - if (output_eth_payload_tready_int_reg) begin - output_eth_payload_tvalid_int = 1'b1; - output_eth_payload_tdata_int = {4'd4, 4'd5}; // ip_version, ip_ihl + s_ip_hdr_ready_next = 1'b0; + m_eth_hdr_valid_next = 1'b1; + if (m_eth_payload_axis_tready_int_reg) begin + m_eth_payload_axis_tvalid_int = 1'b1; + m_eth_payload_axis_tdata_int = {4'd4, 4'd5}; // ip_version, ip_ihl frame_ptr_next = 16'd1; end state_next = STATE_WRITE_HEADER; @@ -224,62 +224,62 @@ always @* begin end STATE_WRITE_HEADER: begin // write header - if (output_eth_payload_tready_int_reg) begin + if (m_eth_payload_axis_tready_int_reg) begin frame_ptr_next = frame_ptr_reg + 16'd1; - output_eth_payload_tvalid_int = 1; + m_eth_payload_axis_tvalid_int = 1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: begin - output_eth_payload_tdata_int = {4'd4, 4'd5}; // ip_version, ip_ihl + m_eth_payload_axis_tdata_int = {4'd4, 4'd5}; // ip_version, ip_ihl end 8'h01: begin - output_eth_payload_tdata_int = {ip_dscp_reg, ip_ecn_reg}; + m_eth_payload_axis_tdata_int = {ip_dscp_reg, ip_ecn_reg}; hdr_sum_next = {4'd4, 4'd5, ip_dscp_reg, ip_ecn_reg}; end 8'h02: begin - output_eth_payload_tdata_int = ip_length_reg[15: 8]; + m_eth_payload_axis_tdata_int = ip_length_reg[15: 8]; hdr_sum_next = add1c16b(hdr_sum_reg, ip_length_reg); end 8'h03: begin - output_eth_payload_tdata_int = ip_length_reg[ 7: 0]; + m_eth_payload_axis_tdata_int = ip_length_reg[ 7: 0]; hdr_sum_next = add1c16b(hdr_sum_reg, ip_identification_reg); end 8'h04: begin - output_eth_payload_tdata_int = ip_identification_reg[15: 8]; + m_eth_payload_axis_tdata_int = ip_identification_reg[15: 8]; hdr_sum_next = add1c16b(hdr_sum_reg, {ip_flags_reg, ip_fragment_offset_reg}); end 8'h05: begin - output_eth_payload_tdata_int = ip_identification_reg[ 7: 0]; + m_eth_payload_axis_tdata_int = ip_identification_reg[ 7: 0]; hdr_sum_next = add1c16b(hdr_sum_reg, {ip_ttl_reg, ip_protocol_reg}); end 8'h06: begin - output_eth_payload_tdata_int = {ip_flags_reg, ip_fragment_offset_reg[12:8]}; + m_eth_payload_axis_tdata_int = {ip_flags_reg, ip_fragment_offset_reg[12:8]}; hdr_sum_next = add1c16b(hdr_sum_reg, ip_source_ip_reg[31:16]); end 8'h07: begin - output_eth_payload_tdata_int = ip_fragment_offset_reg[ 7: 0]; + m_eth_payload_axis_tdata_int = ip_fragment_offset_reg[ 7: 0]; hdr_sum_next = add1c16b(hdr_sum_reg, ip_source_ip_reg[15:0]); end 8'h08: begin - output_eth_payload_tdata_int = ip_ttl_reg; + m_eth_payload_axis_tdata_int = ip_ttl_reg; hdr_sum_next = add1c16b(hdr_sum_reg, ip_dest_ip_reg[31:16]); end 8'h09: begin - output_eth_payload_tdata_int = ip_protocol_reg; + m_eth_payload_axis_tdata_int = ip_protocol_reg; hdr_sum_next = add1c16b(hdr_sum_reg, ip_dest_ip_reg[15:0]); end - 8'h0A: output_eth_payload_tdata_int = ~hdr_sum_reg[15: 8]; - 8'h0B: output_eth_payload_tdata_int = ~hdr_sum_reg[ 7: 0]; - 8'h0C: output_eth_payload_tdata_int = ip_source_ip_reg[31:24]; - 8'h0D: output_eth_payload_tdata_int = ip_source_ip_reg[23:16]; - 8'h0E: output_eth_payload_tdata_int = ip_source_ip_reg[15: 8]; - 8'h0F: output_eth_payload_tdata_int = ip_source_ip_reg[ 7: 0]; - 8'h10: output_eth_payload_tdata_int = ip_dest_ip_reg[31:24]; - 8'h11: output_eth_payload_tdata_int = ip_dest_ip_reg[23:16]; - 8'h12: output_eth_payload_tdata_int = ip_dest_ip_reg[15: 8]; + 8'h0A: m_eth_payload_axis_tdata_int = ~hdr_sum_reg[15: 8]; + 8'h0B: m_eth_payload_axis_tdata_int = ~hdr_sum_reg[ 7: 0]; + 8'h0C: m_eth_payload_axis_tdata_int = ip_source_ip_reg[31:24]; + 8'h0D: m_eth_payload_axis_tdata_int = ip_source_ip_reg[23:16]; + 8'h0E: m_eth_payload_axis_tdata_int = ip_source_ip_reg[15: 8]; + 8'h0F: m_eth_payload_axis_tdata_int = ip_source_ip_reg[ 7: 0]; + 8'h10: m_eth_payload_axis_tdata_int = ip_dest_ip_reg[31:24]; + 8'h11: m_eth_payload_axis_tdata_int = ip_dest_ip_reg[23:16]; + 8'h12: m_eth_payload_axis_tdata_int = ip_dest_ip_reg[15: 8]; 8'h13: begin - output_eth_payload_tdata_int = ip_dest_ip_reg[ 7: 0]; - input_ip_payload_tready_next = output_eth_payload_tready_int_early; + m_eth_payload_axis_tdata_int = ip_dest_ip_reg[ 7: 0]; + s_ip_payload_axis_tready_next = m_eth_payload_axis_tready_int_early; state_next = STATE_WRITE_PAYLOAD; end endcase @@ -289,29 +289,29 @@ always @* begin end STATE_WRITE_PAYLOAD: begin // write payload - input_ip_payload_tready_next = output_eth_payload_tready_int_early; + s_ip_payload_axis_tready_next = m_eth_payload_axis_tready_int_early; - output_eth_payload_tdata_int = input_ip_payload_tdata; - output_eth_payload_tvalid_int = input_ip_payload_tvalid; - output_eth_payload_tlast_int = input_ip_payload_tlast; - output_eth_payload_tuser_int = input_ip_payload_tuser; + m_eth_payload_axis_tdata_int = s_ip_payload_axis_tdata; + m_eth_payload_axis_tvalid_int = s_ip_payload_axis_tvalid; + m_eth_payload_axis_tlast_int = s_ip_payload_axis_tlast; + m_eth_payload_axis_tuser_int = s_ip_payload_axis_tuser; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg + 16'd1; - if (input_ip_payload_tlast) begin + if (s_ip_payload_axis_tlast) begin if (frame_ptr_next != ip_length_reg) begin // end of frame, but length does not match - output_eth_payload_tuser_int = 1'b1; + m_eth_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; end - input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin if (frame_ptr_next == ip_length_reg) begin store_last_word = 1'b1; - output_eth_payload_tvalid_int = 1'b0; + m_eth_payload_axis_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -323,17 +323,17 @@ always @* begin end STATE_WRITE_PAYLOAD_LAST: begin // read and discard until end of frame - input_ip_payload_tready_next = output_eth_payload_tready_int_early; + s_ip_payload_axis_tready_next = m_eth_payload_axis_tready_int_early; - output_eth_payload_tdata_int = last_word_data_reg; - output_eth_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tlast; - output_eth_payload_tlast_int = input_ip_payload_tlast; - output_eth_payload_tuser_int = input_ip_payload_tuser; + m_eth_payload_axis_tdata_int = last_word_data_reg; + m_eth_payload_axis_tvalid_int = s_ip_payload_axis_tvalid && s_ip_payload_axis_tlast; + m_eth_payload_axis_tlast_int = s_ip_payload_axis_tlast; + m_eth_payload_axis_tuser_int = s_ip_payload_axis_tuser; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin - if (input_ip_payload_tlast) begin - input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin + if (s_ip_payload_axis_tlast) begin + s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD_LAST; @@ -344,12 +344,12 @@ always @* begin end STATE_WAIT_LAST: begin // read and discard until end of frame - input_ip_payload_tready_next = 1'b1; + s_ip_payload_axis_tready_next = 1'b1; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin - if (input_ip_payload_tlast) begin - input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin + if (s_ip_payload_axis_tlast) begin + s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -366,9 +366,9 @@ always @(posedge clk) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 16'd0; hdr_sum_reg <= 16'd0; - input_ip_hdr_ready_reg <= 1'b0; - input_ip_payload_tready_reg <= 1'b0; - output_eth_hdr_valid_reg <= 1'b0; + s_ip_hdr_ready_reg <= 1'b0; + s_ip_payload_axis_tready_reg <= 1'b0; + m_eth_hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; error_payload_early_termination_reg <= 1'b0; end else begin @@ -378,10 +378,10 @@ always @(posedge clk) begin hdr_sum_reg <= hdr_sum_next; - input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; - input_ip_payload_tready_reg <= input_ip_payload_tready_next; + s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; + s_ip_payload_axis_tready_reg <= s_ip_payload_axis_tready_next; - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; @@ -390,104 +390,104 @@ always @(posedge clk) begin // datapath if (store_ip_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - ip_dscp_reg <= input_ip_dscp; - ip_ecn_reg <= input_ip_ecn; - ip_length_reg <= input_ip_length; - ip_identification_reg <= input_ip_identification; - ip_flags_reg <= input_ip_flags; - ip_fragment_offset_reg <= input_ip_fragment_offset; - ip_ttl_reg <= input_ip_ttl; - ip_protocol_reg <= input_ip_protocol; - ip_source_ip_reg <= input_ip_source_ip; - ip_dest_ip_reg <= input_ip_dest_ip; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; + ip_dscp_reg <= s_ip_dscp; + ip_ecn_reg <= s_ip_ecn; + ip_length_reg <= s_ip_length; + ip_identification_reg <= s_ip_identification; + ip_flags_reg <= s_ip_flags; + ip_fragment_offset_reg <= s_ip_fragment_offset; + ip_ttl_reg <= s_ip_ttl; + ip_protocol_reg <= s_ip_protocol; + ip_source_ip_reg <= s_ip_source_ip; + ip_dest_ip_reg <= s_ip_dest_ip; end if (store_last_word) begin - last_word_data_reg <= output_eth_payload_tdata_int; + last_word_data_reg <= m_eth_payload_axis_tdata_int; end end // output datapath logic -reg [7:0] output_eth_payload_tdata_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; +reg [7:0] m_eth_payload_axis_tdata_reg = 8'd0; +reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; +reg m_eth_payload_axis_tlast_reg = 1'b0; +reg m_eth_payload_axis_tuser_reg = 1'b0; -reg [7:0] temp_eth_payload_tdata_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; +reg [7:0] temp_m_eth_payload_axis_tdata_reg = 8'd0; +reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; +reg temp_m_eth_payload_axis_tlast_reg = 1'b0; +reg temp_m_eth_payload_axis_tuser_reg = 1'b0; // datapath control reg store_eth_payload_int_to_output; reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; +reg store_eth_payload_axis_temp_to_output; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; +assign m_eth_payload_axis_tdata = m_eth_payload_axis_tdata_reg; +assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; +assign m_eth_payload_axis_tlast = m_eth_payload_axis_tlast_reg; +assign m_eth_payload_axis_tuser = m_eth_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); +assign m_eth_payload_axis_tready_int_early = m_eth_payload_axis_tready || (!temp_m_eth_payload_axis_tvalid_reg && (!m_eth_payload_axis_tvalid_reg || !m_eth_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; store_eth_payload_int_to_output = 1'b0; store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b0; - if (output_eth_payload_tready_int_reg) begin + if (m_eth_payload_axis_tready_int_reg) begin // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + if (m_eth_payload_axis_tready || !m_eth_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + temp_m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_temp = 1'b1; end - end else if (output_eth_payload_tready) begin + end else if (m_eth_payload_axis_tready) begin // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; + m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; + m_eth_payload_axis_tvalid_reg <= 1'b0; + m_eth_payload_axis_tready_int_reg <= 1'b0; + temp_m_eth_payload_axis_tvalid_reg <= 1'b0; end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + m_eth_payload_axis_tvalid_reg <= m_eth_payload_axis_tvalid_next; + m_eth_payload_axis_tready_int_reg <= m_eth_payload_axis_tready_int_early; + temp_m_eth_payload_axis_tvalid_reg <= temp_m_eth_payload_axis_tvalid_next; end // datapath if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end else if (store_eth_payload_axis_temp_to_output) begin + m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; + m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; + m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; end if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; end end diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 6f7b42e70..fae946d03 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -37,42 +37,42 @@ module ip_eth_tx_64 /* * IP frame input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [63:0] input_ip_payload_tdata, - input wire [7:0] input_ip_payload_tkeep, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [63:0] s_ip_payload_axis_tdata, + input wire [7:0] s_ip_payload_axis_tkeep, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [63:0] m_eth_payload_axis_tdata, + output wire [7:0] m_eth_payload_axis_tkeep, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * Status signals @@ -148,46 +148,46 @@ reg [7:0] ip_protocol_reg = 8'd0; reg [31:0] ip_source_ip_reg = 32'd0; reg [31:0] ip_dest_ip_reg = 32'd0; -reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; +reg s_ip_hdr_ready_reg = 1'b0, s_ip_hdr_ready_next; +reg s_ip_payload_axis_tready_reg = 1'b0, s_ip_payload_axis_tready_next; -reg output_eth_hdr_valid_reg = 1'b0, output_eth_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; +reg m_eth_hdr_valid_reg = 1'b0, m_eth_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; reg busy_reg = 1'b0; reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; -reg [63:0] save_ip_payload_tdata_reg = 64'd0; -reg [7:0] save_ip_payload_tkeep_reg = 8'd0; -reg save_ip_payload_tlast_reg = 1'b0; -reg save_ip_payload_tuser_reg = 1'b0; +reg [63:0] save_ip_payload_axis_tdata_reg = 64'd0; +reg [7:0] save_ip_payload_axis_tkeep_reg = 8'd0; +reg save_ip_payload_axis_tlast_reg = 1'b0; +reg save_ip_payload_axis_tuser_reg = 1'b0; -reg [63:0] shift_ip_payload_tdata; -reg [7:0] shift_ip_payload_tkeep; -reg shift_ip_payload_tvalid; -reg shift_ip_payload_tlast; -reg shift_ip_payload_tuser; -reg shift_ip_payload_input_tready; +reg [63:0] shift_ip_payload_axis_tdata; +reg [7:0] shift_ip_payload_axis_tkeep; +reg shift_ip_payload_axis_tvalid; +reg shift_ip_payload_axis_tlast; +reg shift_ip_payload_axis_tuser; +reg shift_ip_payload_s_tready; reg shift_ip_payload_extra_cycle; // internal datapath -reg [63:0] output_eth_payload_tdata_int; -reg [7:0] output_eth_payload_tkeep_int; -reg output_eth_payload_tvalid_int; -reg output_eth_payload_tready_int_reg = 1'b0; -reg output_eth_payload_tlast_int; -reg output_eth_payload_tuser_int; -wire output_eth_payload_tready_int_early; +reg [63:0] m_eth_payload_axis_tdata_int; +reg [7:0] m_eth_payload_axis_tkeep_int; +reg m_eth_payload_axis_tvalid_int; +reg m_eth_payload_axis_tready_int_reg = 1'b0; +reg m_eth_payload_axis_tlast_int; +reg m_eth_payload_axis_tuser_int; +wire m_eth_payload_axis_tready_int_early; -assign input_ip_hdr_ready = input_ip_hdr_ready_reg; -assign input_ip_payload_tready = input_ip_payload_tready_reg; +assign s_ip_hdr_ready = s_ip_hdr_ready_reg; +assign s_ip_payload_axis_tready = s_ip_payload_axis_tready_reg; -assign output_eth_hdr_valid = output_eth_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; +assign m_eth_hdr_valid = m_eth_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; assign busy = busy_reg; assign error_payload_early_termination = error_payload_early_termination_reg; @@ -223,32 +223,32 @@ function [7:0] count2keep; endfunction always @* begin - shift_ip_payload_tdata[31:0] = save_ip_payload_tdata_reg[63:32]; - shift_ip_payload_tkeep[3:0] = save_ip_payload_tkeep_reg[7:4]; - shift_ip_payload_extra_cycle = save_ip_payload_tlast_reg & (save_ip_payload_tkeep_reg[7:4] != 0); + shift_ip_payload_axis_tdata[31:0] = save_ip_payload_axis_tdata_reg[63:32]; + shift_ip_payload_axis_tkeep[3:0] = save_ip_payload_axis_tkeep_reg[7:4]; + shift_ip_payload_extra_cycle = save_ip_payload_axis_tlast_reg && (save_ip_payload_axis_tkeep_reg[7:4] != 0); if (shift_ip_payload_extra_cycle) begin - shift_ip_payload_tdata[63:32] = 32'd0; - shift_ip_payload_tkeep[7:4] = 4'd0; - shift_ip_payload_tvalid = 1'b1; - shift_ip_payload_tlast = save_ip_payload_tlast_reg; - shift_ip_payload_tuser = save_ip_payload_tuser_reg; - shift_ip_payload_input_tready = flush_save; + shift_ip_payload_axis_tdata[63:32] = 32'd0; + shift_ip_payload_axis_tkeep[7:4] = 4'd0; + shift_ip_payload_axis_tvalid = 1'b1; + shift_ip_payload_axis_tlast = save_ip_payload_axis_tlast_reg; + shift_ip_payload_axis_tuser = save_ip_payload_axis_tuser_reg; + shift_ip_payload_s_tready = flush_save; end else begin - shift_ip_payload_tdata[63:32] = input_ip_payload_tdata[31:0]; - shift_ip_payload_tkeep[7:4] = input_ip_payload_tkeep[3:0]; - shift_ip_payload_tvalid = input_ip_payload_tvalid; - shift_ip_payload_tlast = (input_ip_payload_tlast & (input_ip_payload_tkeep[7:4] == 0)); - shift_ip_payload_tuser = (input_ip_payload_tuser & (input_ip_payload_tkeep[7:4] == 0)); - shift_ip_payload_input_tready = ~(input_ip_payload_tlast & input_ip_payload_tvalid & transfer_in_save) & ~save_ip_payload_tlast_reg; + shift_ip_payload_axis_tdata[63:32] = s_ip_payload_axis_tdata[31:0]; + shift_ip_payload_axis_tkeep[7:4] = s_ip_payload_axis_tkeep[3:0]; + shift_ip_payload_axis_tvalid = s_ip_payload_axis_tvalid; + shift_ip_payload_axis_tlast = (s_ip_payload_axis_tlast && (s_ip_payload_axis_tkeep[7:4] == 0)); + shift_ip_payload_axis_tuser = (s_ip_payload_axis_tuser && (s_ip_payload_axis_tkeep[7:4] == 0)); + shift_ip_payload_s_tready = !(s_ip_payload_axis_tlast && s_ip_payload_axis_tvalid && transfer_in_save) && !save_ip_payload_axis_tlast_reg; end end always @* begin state_next = STATE_IDLE; - input_ip_hdr_ready_next = 1'b0; - input_ip_payload_tready_next = 1'b0; + s_ip_hdr_ready_next = 1'b0; + s_ip_payload_axis_tready_next = 1'b0; store_ip_hdr = 1'b0; @@ -262,47 +262,47 @@ always @* begin hdr_sum_temp = 16'd0; hdr_sum_next = hdr_sum_reg; - output_eth_hdr_valid_next = output_eth_hdr_valid_reg & ~output_eth_hdr_ready; + m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; error_payload_early_termination_next = 1'b0; - output_eth_payload_tdata_int = 1'b0; - output_eth_payload_tkeep_int = 1'b0; - output_eth_payload_tvalid_int = 1'b0; - output_eth_payload_tlast_int = 1'b0; - output_eth_payload_tuser_int = 1'b0; + m_eth_payload_axis_tdata_int = 1'b0; + m_eth_payload_axis_tkeep_int = 1'b0; + m_eth_payload_axis_tvalid_int = 1'b0; + m_eth_payload_axis_tlast_int = 1'b0; + m_eth_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 16'd0; flush_save = 1'b1; - input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; - if (input_ip_hdr_ready & input_ip_hdr_valid) begin + if (s_ip_hdr_ready && s_ip_hdr_valid) begin store_ip_hdr = 1'b1; - hdr_sum_next = {4'd4, 4'd5, input_ip_dscp, input_ip_ecn} + - input_ip_length + - input_ip_identification + - {input_ip_flags, input_ip_fragment_offset} + - {input_ip_ttl, input_ip_protocol} + - input_ip_source_ip[31:16] + - input_ip_source_ip[15: 0] + - input_ip_dest_ip[31:16] + - input_ip_dest_ip[15: 0]; - input_ip_hdr_ready_next = 1'b0; - output_eth_hdr_valid_next = 1'b1; - if (output_eth_payload_tready_int_reg) begin - output_eth_payload_tvalid_int = 1'b1; - output_eth_payload_tdata_int[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl - output_eth_payload_tdata_int[15: 8] = {input_ip_dscp, input_ip_ecn}; - output_eth_payload_tdata_int[23:16] = input_ip_length[15: 8]; - output_eth_payload_tdata_int[31:24] = input_ip_length[ 7: 0]; - output_eth_payload_tdata_int[39:32] = input_ip_identification[15: 8]; - output_eth_payload_tdata_int[47:40] = input_ip_identification[ 7: 0]; - output_eth_payload_tdata_int[55:48] = {input_ip_flags, input_ip_fragment_offset[12: 8]}; - output_eth_payload_tdata_int[63:56] = input_ip_fragment_offset[ 7: 0]; - output_eth_payload_tkeep_int = 8'hff; + hdr_sum_next = {4'd4, 4'd5, s_ip_dscp, s_ip_ecn} + + s_ip_length + + s_ip_identification + + {s_ip_flags, s_ip_fragment_offset} + + {s_ip_ttl, s_ip_protocol} + + s_ip_source_ip[31:16] + + s_ip_source_ip[15: 0] + + s_ip_dest_ip[31:16] + + s_ip_dest_ip[15: 0]; + s_ip_hdr_ready_next = 1'b0; + m_eth_hdr_valid_next = 1'b1; + if (m_eth_payload_axis_tready_int_reg) begin + m_eth_payload_axis_tvalid_int = 1'b1; + m_eth_payload_axis_tdata_int[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl + m_eth_payload_axis_tdata_int[15: 8] = {s_ip_dscp, s_ip_ecn}; + m_eth_payload_axis_tdata_int[23:16] = s_ip_length[15: 8]; + m_eth_payload_axis_tdata_int[31:24] = s_ip_length[ 7: 0]; + m_eth_payload_axis_tdata_int[39:32] = s_ip_identification[15: 8]; + m_eth_payload_axis_tdata_int[47:40] = s_ip_identification[ 7: 0]; + m_eth_payload_axis_tdata_int[55:48] = {s_ip_flags, s_ip_fragment_offset[12: 8]}; + m_eth_payload_axis_tdata_int[63:56] = s_ip_fragment_offset[ 7: 0]; + m_eth_payload_axis_tkeep_int = 8'hff; frame_ptr_next = 16'd8; end state_next = STATE_WRITE_HEADER; @@ -312,35 +312,35 @@ always @* begin end STATE_WRITE_HEADER: begin // write header - if (output_eth_payload_tready_int_reg) begin + if (m_eth_payload_axis_tready_int_reg) begin frame_ptr_next = frame_ptr_reg + 16'd8; - output_eth_payload_tvalid_int = 1'b1; + m_eth_payload_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: begin - output_eth_payload_tdata_int[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl - output_eth_payload_tdata_int[15: 8] = {input_ip_dscp, input_ip_ecn}; - output_eth_payload_tdata_int[23:16] = input_ip_length[15: 8]; - output_eth_payload_tdata_int[31:24] = input_ip_length[ 7: 0]; - output_eth_payload_tdata_int[39:32] = input_ip_identification[15: 8]; - output_eth_payload_tdata_int[47:40] = input_ip_identification[ 7: 0]; - output_eth_payload_tdata_int[55:48] = {input_ip_flags, input_ip_fragment_offset[12: 8]}; - output_eth_payload_tdata_int[63:56] = input_ip_fragment_offset[ 7: 0]; - output_eth_payload_tkeep_int = 8'hff; + m_eth_payload_axis_tdata_int[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl + m_eth_payload_axis_tdata_int[15: 8] = {s_ip_dscp, s_ip_ecn}; + m_eth_payload_axis_tdata_int[23:16] = s_ip_length[15: 8]; + m_eth_payload_axis_tdata_int[31:24] = s_ip_length[ 7: 0]; + m_eth_payload_axis_tdata_int[39:32] = s_ip_identification[15: 8]; + m_eth_payload_axis_tdata_int[47:40] = s_ip_identification[ 7: 0]; + m_eth_payload_axis_tdata_int[55:48] = {s_ip_flags, s_ip_fragment_offset[12: 8]}; + m_eth_payload_axis_tdata_int[63:56] = s_ip_fragment_offset[ 7: 0]; + m_eth_payload_axis_tkeep_int = 8'hff; end 8'h08: begin hdr_sum_temp = hdr_sum_reg[15:0] + hdr_sum_reg[31:16]; hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[16]; - output_eth_payload_tdata_int[ 7: 0] = ip_ttl_reg; - output_eth_payload_tdata_int[15: 8] = ip_protocol_reg; - output_eth_payload_tdata_int[23:16] = ~hdr_sum_temp[15: 8]; - output_eth_payload_tdata_int[31:24] = ~hdr_sum_temp[ 7: 0]; - output_eth_payload_tdata_int[39:32] = ip_source_ip_reg[31:24]; - output_eth_payload_tdata_int[47:40] = ip_source_ip_reg[23:16]; - output_eth_payload_tdata_int[55:48] = ip_source_ip_reg[15: 8]; - output_eth_payload_tdata_int[63:56] = ip_source_ip_reg[ 7: 0]; - output_eth_payload_tkeep_int = 8'hff; - input_ip_payload_tready_next = output_eth_payload_tready_int_early; + m_eth_payload_axis_tdata_int[ 7: 0] = ip_ttl_reg; + m_eth_payload_axis_tdata_int[15: 8] = ip_protocol_reg; + m_eth_payload_axis_tdata_int[23:16] = ~hdr_sum_temp[15: 8]; + m_eth_payload_axis_tdata_int[31:24] = ~hdr_sum_temp[ 7: 0]; + m_eth_payload_axis_tdata_int[39:32] = ip_source_ip_reg[31:24]; + m_eth_payload_axis_tdata_int[47:40] = ip_source_ip_reg[23:16]; + m_eth_payload_axis_tdata_int[55:48] = ip_source_ip_reg[15: 8]; + m_eth_payload_axis_tdata_int[63:56] = ip_source_ip_reg[ 7: 0]; + m_eth_payload_axis_tkeep_int = 8'hff; + s_ip_payload_axis_tready_next = m_eth_payload_axis_tready_int_early; state_next = STATE_WRITE_HEADER_LAST; end endcase @@ -350,45 +350,45 @@ always @* begin end STATE_WRITE_HEADER_LAST: begin // last header word requires first payload word; process accordingly - input_ip_payload_tready_next = output_eth_payload_tready_int_early & shift_ip_payload_input_tready; + s_ip_payload_axis_tready_next = m_eth_payload_axis_tready_int_early && shift_ip_payload_s_tready; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin - output_eth_payload_tvalid_int = 1'b1; + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin + m_eth_payload_axis_tvalid_int = 1'b1; transfer_in_save = 1'b1; - output_eth_payload_tdata_int[ 7: 0] = ip_dest_ip_reg[31:24]; - output_eth_payload_tdata_int[15: 8] = ip_dest_ip_reg[23:16]; - output_eth_payload_tdata_int[23:16] = ip_dest_ip_reg[15: 8]; - output_eth_payload_tdata_int[31:24] = ip_dest_ip_reg[ 7: 0]; - output_eth_payload_tdata_int[39:32] = shift_ip_payload_tdata[39:32]; - output_eth_payload_tdata_int[47:40] = shift_ip_payload_tdata[47:40]; - output_eth_payload_tdata_int[55:48] = shift_ip_payload_tdata[55:48]; - output_eth_payload_tdata_int[63:56] = shift_ip_payload_tdata[63:56]; - output_eth_payload_tkeep_int = {shift_ip_payload_tkeep[7:4], 4'hF}; - output_eth_payload_tlast_int = shift_ip_payload_tlast; - output_eth_payload_tuser_int = shift_ip_payload_tuser; - frame_ptr_next = frame_ptr_reg+keep2count(output_eth_payload_tkeep_int); + m_eth_payload_axis_tdata_int[ 7: 0] = ip_dest_ip_reg[31:24]; + m_eth_payload_axis_tdata_int[15: 8] = ip_dest_ip_reg[23:16]; + m_eth_payload_axis_tdata_int[23:16] = ip_dest_ip_reg[15: 8]; + m_eth_payload_axis_tdata_int[31:24] = ip_dest_ip_reg[ 7: 0]; + m_eth_payload_axis_tdata_int[39:32] = shift_ip_payload_axis_tdata[39:32]; + m_eth_payload_axis_tdata_int[47:40] = shift_ip_payload_axis_tdata[47:40]; + m_eth_payload_axis_tdata_int[55:48] = shift_ip_payload_axis_tdata[55:48]; + m_eth_payload_axis_tdata_int[63:56] = shift_ip_payload_axis_tdata[63:56]; + m_eth_payload_axis_tkeep_int = {shift_ip_payload_axis_tkeep[7:4], 4'hF}; + m_eth_payload_axis_tlast_int = shift_ip_payload_axis_tlast; + m_eth_payload_axis_tuser_int = shift_ip_payload_axis_tuser; + frame_ptr_next = frame_ptr_reg+keep2count(m_eth_payload_axis_tkeep_int); if (frame_ptr_next >= ip_length_reg) begin // have entire payload frame_ptr_next = ip_length_reg; - output_eth_payload_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); - if (shift_ip_payload_tlast) begin - input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + m_eth_payload_axis_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); + if (shift_ip_payload_axis_tlast) begin + s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin store_last_word = 1'b1; - input_ip_payload_tready_next = shift_ip_payload_input_tready; - output_eth_payload_tvalid_int = 1'b0; + s_ip_payload_axis_tready_next = shift_ip_payload_s_tready; + m_eth_payload_axis_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin - if (shift_ip_payload_tlast) begin + if (shift_ip_payload_axis_tlast) begin // end of frame, but length does not match error_payload_early_termination_next = 1'b1; - input_ip_payload_tready_next = shift_ip_payload_input_tready; - output_eth_payload_tuser_int = 1'b1; + s_ip_payload_axis_tready_next = shift_ip_payload_s_tready; + m_eth_payload_axis_tuser_int = 1'b1; state_next = STATE_WAIT_LAST; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -400,40 +400,40 @@ always @* begin end STATE_WRITE_PAYLOAD: begin // write payload - input_ip_payload_tready_next = output_eth_payload_tready_int_early & shift_ip_payload_input_tready; + s_ip_payload_axis_tready_next = m_eth_payload_axis_tready_int_early && shift_ip_payload_s_tready; - output_eth_payload_tdata_int = shift_ip_payload_tdata; - output_eth_payload_tkeep_int = shift_ip_payload_tkeep; - output_eth_payload_tvalid_int = shift_ip_payload_tvalid; - output_eth_payload_tlast_int = shift_ip_payload_tlast; - output_eth_payload_tuser_int = shift_ip_payload_tuser; + m_eth_payload_axis_tdata_int = shift_ip_payload_axis_tdata; + m_eth_payload_axis_tkeep_int = shift_ip_payload_axis_tkeep; + m_eth_payload_axis_tvalid_int = shift_ip_payload_axis_tvalid; + m_eth_payload_axis_tlast_int = shift_ip_payload_axis_tlast; + m_eth_payload_axis_tuser_int = shift_ip_payload_axis_tuser; - if (output_eth_payload_tready_int_reg & shift_ip_payload_tvalid) begin + if (m_eth_payload_axis_tready_int_reg && shift_ip_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_tkeep); + frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_axis_tkeep); transfer_in_save = 1'b1; if (frame_ptr_next >= ip_length_reg) begin // have entire payload frame_ptr_next = ip_length_reg; - output_eth_payload_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); - if (shift_ip_payload_tlast) begin - input_ip_payload_tready_next = 1'b0; + m_eth_payload_axis_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); + if (shift_ip_payload_axis_tlast) begin + s_ip_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; state_next = STATE_IDLE; end else begin store_last_word = 1'b1; - output_eth_payload_tvalid_int = 1'b0; + m_eth_payload_axis_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin - if (shift_ip_payload_tlast) begin + if (shift_ip_payload_axis_tlast) begin // end of frame, but length does not match error_payload_early_termination_next = 1'b1; - output_eth_payload_tuser_int = 1'b1; - input_ip_payload_tready_next = 1'b0; + m_eth_payload_axis_tuser_int = 1'b1; + s_ip_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -445,19 +445,19 @@ always @* begin end STATE_WRITE_PAYLOAD_LAST: begin // read and discard until end of frame - input_ip_payload_tready_next = output_eth_payload_tready_int_early & shift_ip_payload_input_tready; + s_ip_payload_axis_tready_next = m_eth_payload_axis_tready_int_early && shift_ip_payload_s_tready; - output_eth_payload_tdata_int = last_word_data_reg; - output_eth_payload_tkeep_int = last_word_keep_reg; - output_eth_payload_tvalid_int = shift_ip_payload_tvalid & shift_ip_payload_tlast; - output_eth_payload_tlast_int = shift_ip_payload_tlast; - output_eth_payload_tuser_int = shift_ip_payload_tuser; + m_eth_payload_axis_tdata_int = last_word_data_reg; + m_eth_payload_axis_tkeep_int = last_word_keep_reg; + m_eth_payload_axis_tvalid_int = shift_ip_payload_axis_tvalid && shift_ip_payload_axis_tlast; + m_eth_payload_axis_tlast_int = shift_ip_payload_axis_tlast; + m_eth_payload_axis_tuser_int = shift_ip_payload_axis_tuser; - if (output_eth_payload_tready_int_reg & shift_ip_payload_tvalid) begin + if (m_eth_payload_axis_tready_int_reg && shift_ip_payload_axis_tvalid) begin transfer_in_save = 1'b1; - if (shift_ip_payload_tlast) begin - input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + if (shift_ip_payload_axis_tlast) begin + s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD_LAST; @@ -468,13 +468,13 @@ always @* begin end STATE_WAIT_LAST: begin // read and discard until end of frame - input_ip_payload_tready_next = shift_ip_payload_input_tready; + s_ip_payload_axis_tready_next = shift_ip_payload_s_tready; - if (shift_ip_payload_tvalid) begin + if (shift_ip_payload_axis_tvalid) begin transfer_in_save = 1'b1; - if (shift_ip_payload_tlast) begin - input_ip_hdr_ready_next = ~output_eth_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + if (shift_ip_payload_axis_tlast) begin + s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -491,10 +491,10 @@ always @(posedge clk) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 16'd0; hdr_sum_reg <= 16'd0; - input_ip_hdr_ready_reg <= 1'b0; - input_ip_payload_tready_reg <= 1'b0; - output_eth_hdr_valid_reg <= 1'b0; - save_ip_payload_tlast_reg <= 1'b0; + s_ip_hdr_ready_reg <= 1'b0; + s_ip_payload_axis_tready_reg <= 1'b0; + m_eth_hdr_valid_reg <= 1'b0; + save_ip_payload_axis_tlast_reg <= 1'b0; busy_reg <= 1'b0; error_payload_early_termination_reg <= 1'b0; end else begin @@ -504,135 +504,135 @@ always @(posedge clk) begin hdr_sum_reg <= hdr_sum_next; - input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; - input_ip_payload_tready_reg <= input_ip_payload_tready_next; + s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; + s_ip_payload_axis_tready_reg <= s_ip_payload_axis_tready_next; - output_eth_hdr_valid_reg <= output_eth_hdr_valid_next; + m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; error_payload_early_termination_reg <= error_payload_early_termination_next; if (flush_save) begin - save_ip_payload_tlast_reg <= 1'b0; + save_ip_payload_axis_tlast_reg <= 1'b0; end else if (transfer_in_save) begin - save_ip_payload_tlast_reg <= input_ip_payload_tlast; + save_ip_payload_axis_tlast_reg <= s_ip_payload_axis_tlast; end end // datapath if (store_ip_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - ip_dscp_reg <= input_ip_dscp; - ip_ecn_reg <= input_ip_ecn; - ip_length_reg <= input_ip_length; - ip_identification_reg <= input_ip_identification; - ip_flags_reg <= input_ip_flags; - ip_fragment_offset_reg <= input_ip_fragment_offset; - ip_ttl_reg <= input_ip_ttl; - ip_protocol_reg <= input_ip_protocol; - ip_source_ip_reg <= input_ip_source_ip; - ip_dest_ip_reg <= input_ip_dest_ip; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; + ip_dscp_reg <= s_ip_dscp; + ip_ecn_reg <= s_ip_ecn; + ip_length_reg <= s_ip_length; + ip_identification_reg <= s_ip_identification; + ip_flags_reg <= s_ip_flags; + ip_fragment_offset_reg <= s_ip_fragment_offset; + ip_ttl_reg <= s_ip_ttl; + ip_protocol_reg <= s_ip_protocol; + ip_source_ip_reg <= s_ip_source_ip; + ip_dest_ip_reg <= s_ip_dest_ip; end if (store_last_word) begin - last_word_data_reg <= output_eth_payload_tdata_int; - last_word_keep_reg <= output_eth_payload_tkeep_int; + last_word_data_reg <= m_eth_payload_axis_tdata_int; + last_word_keep_reg <= m_eth_payload_axis_tkeep_int; end if (transfer_in_save) begin - save_ip_payload_tdata_reg <= input_ip_payload_tdata; - save_ip_payload_tkeep_reg <= input_ip_payload_tkeep; - save_ip_payload_tuser_reg <= input_ip_payload_tuser; + save_ip_payload_axis_tdata_reg <= s_ip_payload_axis_tdata; + save_ip_payload_axis_tkeep_reg <= s_ip_payload_axis_tkeep; + save_ip_payload_axis_tuser_reg <= s_ip_payload_axis_tuser; end end // output datapath logic -reg [64:0] output_eth_payload_tdata_reg = 64'd0; -reg [7:0] output_eth_payload_tkeep_reg = 8'd0; -reg output_eth_payload_tvalid_reg = 1'b0, output_eth_payload_tvalid_next; -reg output_eth_payload_tlast_reg = 1'b0; -reg output_eth_payload_tuser_reg = 1'b0; +reg [64:0] m_eth_payload_axis_tdata_reg = 64'd0; +reg [7:0] m_eth_payload_axis_tkeep_reg = 8'd0; +reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; +reg m_eth_payload_axis_tlast_reg = 1'b0; +reg m_eth_payload_axis_tuser_reg = 1'b0; -reg [64:0] temp_eth_payload_tdata_reg = 64'd0; -reg [7:0] temp_eth_payload_tkeep_reg = 8'd0; -reg temp_eth_payload_tvalid_reg = 1'b0, temp_eth_payload_tvalid_next; -reg temp_eth_payload_tlast_reg = 1'b0; -reg temp_eth_payload_tuser_reg = 1'b0; +reg [64:0] temp_m_eth_payload_axis_tdata_reg = 64'd0; +reg [7:0] temp_m_eth_payload_axis_tkeep_reg = 8'd0; +reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; +reg temp_m_eth_payload_axis_tlast_reg = 1'b0; +reg temp_m_eth_payload_axis_tuser_reg = 1'b0; // datapath control reg store_eth_payload_int_to_output; reg store_eth_payload_int_to_temp; -reg store_eth_payload_temp_to_output; +reg store_eth_payload_axis_temp_to_output; -assign output_eth_payload_tdata = output_eth_payload_tdata_reg; -assign output_eth_payload_tkeep = output_eth_payload_tkeep_reg; -assign output_eth_payload_tvalid = output_eth_payload_tvalid_reg; -assign output_eth_payload_tlast = output_eth_payload_tlast_reg; -assign output_eth_payload_tuser = output_eth_payload_tuser_reg; +assign m_eth_payload_axis_tdata = m_eth_payload_axis_tdata_reg; +assign m_eth_payload_axis_tkeep = m_eth_payload_axis_tkeep_reg; +assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; +assign m_eth_payload_axis_tlast = m_eth_payload_axis_tlast_reg; +assign m_eth_payload_axis_tuser = m_eth_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_eth_payload_tready_int_early = output_eth_payload_tready | (~temp_eth_payload_tvalid_reg & (~output_eth_payload_tvalid_reg | ~output_eth_payload_tvalid_int)); +assign m_eth_payload_axis_tready_int_early = m_eth_payload_axis_tready | (!temp_m_eth_payload_axis_tvalid_reg && (!m_eth_payload_axis_tvalid_reg | !m_eth_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_eth_payload_tvalid_next = output_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; store_eth_payload_int_to_output = 1'b0; store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_temp_to_output = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b0; - if (output_eth_payload_tready_int_reg) begin + if (m_eth_payload_axis_tready_int_reg) begin // input is ready - if (output_eth_payload_tready | ~output_eth_payload_tvalid_reg) begin + if (m_eth_payload_axis_tready | !m_eth_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_eth_payload_tvalid_next = output_eth_payload_tvalid_int; + temp_m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; store_eth_payload_int_to_temp = 1'b1; end - end else if (output_eth_payload_tready) begin + end else if (m_eth_payload_axis_tready) begin // input is not ready, but output is ready - output_eth_payload_tvalid_next = temp_eth_payload_tvalid_reg; - temp_eth_payload_tvalid_next = 1'b0; - store_eth_payload_temp_to_output = 1'b1; + m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; + temp_m_eth_payload_axis_tvalid_next = 1'b0; + store_eth_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_eth_payload_tvalid_reg <= 1'b0; - output_eth_payload_tready_int_reg <= 1'b0; - temp_eth_payload_tvalid_reg <= 1'b0; + m_eth_payload_axis_tvalid_reg <= 1'b0; + m_eth_payload_axis_tready_int_reg <= 1'b0; + temp_m_eth_payload_axis_tvalid_reg <= 1'b0; end else begin - output_eth_payload_tvalid_reg <= output_eth_payload_tvalid_next; - output_eth_payload_tready_int_reg <= output_eth_payload_tready_int_early; - temp_eth_payload_tvalid_reg <= temp_eth_payload_tvalid_next; + m_eth_payload_axis_tvalid_reg <= m_eth_payload_axis_tvalid_next; + m_eth_payload_axis_tready_int_reg <= m_eth_payload_axis_tready_int_early; + temp_m_eth_payload_axis_tvalid_reg <= temp_m_eth_payload_axis_tvalid_next; end // datapath if (store_eth_payload_int_to_output) begin - output_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - output_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - output_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - output_eth_payload_tuser_reg <= output_eth_payload_tuser_int; - end else if (store_eth_payload_temp_to_output) begin - output_eth_payload_tdata_reg <= temp_eth_payload_tdata_reg; - output_eth_payload_tkeep_reg <= temp_eth_payload_tkeep_reg; - output_eth_payload_tlast_reg <= temp_eth_payload_tlast_reg; - output_eth_payload_tuser_reg <= temp_eth_payload_tuser_reg; + m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; + end else if (store_eth_payload_axis_temp_to_output) begin + m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; + m_eth_payload_axis_tkeep_reg <= temp_m_eth_payload_axis_tkeep_reg; + m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; + m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; end if (store_eth_payload_int_to_temp) begin - temp_eth_payload_tdata_reg <= output_eth_payload_tdata_int; - temp_eth_payload_tkeep_reg <= output_eth_payload_tkeep_int; - temp_eth_payload_tlast_reg <= output_eth_payload_tlast_int; - temp_eth_payload_tuser_reg <= output_eth_payload_tuser_int; + temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + temp_m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; + temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; + temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; end end diff --git a/rtl/udp.v b/rtl/udp.v index aba9740ff..94e6ad614 100644 --- a/rtl/udp.v +++ b/rtl/udp.v @@ -42,116 +42,116 @@ module udp # /* * IP frame input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [47:0] input_ip_eth_dest_mac, - input wire [47:0] input_ip_eth_src_mac, - input wire [15:0] input_ip_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [7:0] input_ip_payload_tdata, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [47:0] s_ip_eth_dest_mac, + input wire [47:0] s_ip_eth_src_mac, + input wire [15:0] s_ip_eth_type, + input wire [3:0] s_ip_version, + input wire [3:0] s_ip_ihl, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [15:0] s_ip_header_checksum, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [7:0] s_ip_payload_axis_tdata, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * IP frame output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_ip_eth_dest_mac, - output wire [47:0] output_ip_eth_src_mac, - output wire [15:0] output_ip_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_ip_eth_dest_mac, + output wire [47:0] m_ip_eth_src_mac, + output wire [15:0] m_ip_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [7:0] m_ip_payload_axis_tdata, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * UDP frame input */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [47:0] input_udp_eth_dest_mac, - input wire [47:0] input_udp_eth_src_mac, - input wire [15:0] input_udp_eth_type, - input wire [3:0] input_udp_ip_version, - input wire [3:0] input_udp_ip_ihl, - input wire [5:0] input_udp_ip_dscp, - input wire [1:0] input_udp_ip_ecn, - input wire [15:0] input_udp_ip_identification, - input wire [2:0] input_udp_ip_flags, - input wire [12:0] input_udp_ip_fragment_offset, - input wire [7:0] input_udp_ip_ttl, - input wire [15:0] input_udp_ip_header_checksum, - input wire [31:0] input_udp_ip_source_ip, - input wire [31:0] input_udp_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [15:0] input_udp_length, - input wire [15:0] input_udp_checksum, - input wire [7:0] input_udp_payload_tdata, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, + input wire s_udp_hdr_valid, + output wire s_udp_hdr_ready, + input wire [47:0] s_udp_eth_dest_mac, + input wire [47:0] s_udp_eth_src_mac, + input wire [15:0] s_udp_eth_type, + input wire [3:0] s_udp_ip_version, + input wire [3:0] s_udp_ip_ihl, + input wire [5:0] s_udp_ip_dscp, + input wire [1:0] s_udp_ip_ecn, + input wire [15:0] s_udp_ip_identification, + input wire [2:0] s_udp_ip_flags, + input wire [12:0] s_udp_ip_fragment_offset, + input wire [7:0] s_udp_ip_ttl, + input wire [15:0] s_udp_ip_header_checksum, + input wire [31:0] s_udp_ip_source_ip, + input wire [31:0] s_udp_ip_dest_ip, + input wire [15:0] s_udp_source_port, + input wire [15:0] s_udp_dest_port, + input wire [15:0] s_udp_length, + input wire [15:0] s_udp_checksum, + input wire [7:0] s_udp_payload_axis_tdata, + input wire s_udp_payload_axis_tvalid, + output wire s_udp_payload_axis_tready, + input wire s_udp_payload_axis_tlast, + input wire s_udp_payload_axis_tuser, /* * UDP frame output */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_udp_eth_dest_mac, - output wire [47:0] output_udp_eth_src_mac, - output wire [15:0] output_udp_eth_type, - output wire [3:0] output_udp_ip_version, - output wire [3:0] output_udp_ip_ihl, - output wire [5:0] output_udp_ip_dscp, - output wire [1:0] output_udp_ip_ecn, - output wire [15:0] output_udp_ip_length, - output wire [15:0] output_udp_ip_identification, - output wire [2:0] output_udp_ip_flags, - output wire [12:0] output_udp_ip_fragment_offset, - output wire [7:0] output_udp_ip_ttl, - output wire [7:0] output_udp_ip_protocol, - output wire [15:0] output_udp_ip_header_checksum, - output wire [31:0] output_udp_ip_source_ip, - output wire [31:0] output_udp_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [7:0] output_udp_payload_tdata, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, + output wire m_udp_hdr_valid, + input wire m_udp_hdr_ready, + output wire [47:0] m_udp_eth_dest_mac, + output wire [47:0] m_udp_eth_src_mac, + output wire [15:0] m_udp_eth_type, + output wire [3:0] m_udp_ip_version, + output wire [3:0] m_udp_ip_ihl, + output wire [5:0] m_udp_ip_dscp, + output wire [1:0] m_udp_ip_ecn, + output wire [15:0] m_udp_ip_length, + output wire [15:0] m_udp_ip_identification, + output wire [2:0] m_udp_ip_flags, + output wire [12:0] m_udp_ip_fragment_offset, + output wire [7:0] m_udp_ip_ttl, + output wire [7:0] m_udp_ip_protocol, + output wire [15:0] m_udp_ip_header_checksum, + output wire [31:0] m_udp_ip_source_ip, + output wire [31:0] m_udp_ip_dest_ip, + output wire [15:0] m_udp_source_port, + output wire [15:0] m_udp_dest_port, + output wire [15:0] m_udp_length, + output wire [15:0] m_udp_checksum, + output wire [7:0] m_udp_payload_axis_tdata, + output wire m_udp_payload_axis_tvalid, + input wire m_udp_payload_axis_tready, + output wire m_udp_payload_axis_tlast, + output wire m_udp_payload_axis_tuser, /* * Status signals @@ -183,68 +183,68 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [7:0] tx_udp_payload_tdata; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; udp_ip_rx udp_ip_rx_inst ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_eth_dest_mac(input_ip_eth_dest_mac), - .input_eth_src_mac(input_ip_eth_src_mac), - .input_eth_type(input_ip_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_ip_eth_dest_mac), + .s_eth_src_mac(s_ip_eth_src_mac), + .s_eth_type(s_ip_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_udp_eth_dest_mac), - .output_eth_src_mac(output_udp_eth_src_mac), - .output_eth_type(output_udp_eth_type), - .output_ip_version(output_udp_ip_version), - .output_ip_ihl(output_udp_ip_ihl), - .output_ip_dscp(output_udp_ip_dscp), - .output_ip_ecn(output_udp_ip_ecn), - .output_ip_length(output_udp_ip_length), - .output_ip_identification(output_udp_ip_identification), - .output_ip_flags(output_udp_ip_flags), - .output_ip_fragment_offset(output_udp_ip_fragment_offset), - .output_ip_ttl(output_udp_ip_ttl), - .output_ip_protocol(output_udp_ip_protocol), - .output_ip_header_checksum(output_udp_ip_header_checksum), - .output_ip_source_ip(output_udp_ip_source_ip), - .output_ip_dest_ip(output_udp_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_udp_eth_dest_mac), + .m_eth_src_mac(m_udp_eth_src_mac), + .m_eth_type(m_udp_eth_type), + .m_ip_version(m_udp_ip_version), + .m_ip_ihl(m_udp_ip_ihl), + .m_ip_dscp(m_udp_ip_dscp), + .m_ip_ecn(m_udp_ip_ecn), + .m_ip_length(m_udp_ip_length), + .m_ip_identification(m_udp_ip_identification), + .m_ip_flags(m_udp_ip_flags), + .m_ip_fragment_offset(m_udp_ip_fragment_offset), + .m_ip_ttl(m_udp_ip_ttl), + .m_ip_protocol(m_udp_ip_protocol), + .m_ip_header_checksum(m_udp_ip_header_checksum), + .m_ip_source_ip(m_udp_ip_source_ip), + .m_ip_dest_ip(m_udp_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Status signals .busy(rx_busy), .error_header_early_termination(rx_error_header_early_termination), @@ -263,88 +263,88 @@ if (CHECKSUM_GEN_ENABLE) begin .clk(clk), .rst(rst), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_eth_dest_mac(input_udp_eth_dest_mac), - .input_eth_src_mac(input_udp_eth_src_mac), - .input_eth_type(input_udp_eth_type), - .input_ip_version(input_udp_ip_version), - .input_ip_ihl(input_udp_ip_ihl), - .input_ip_dscp(input_udp_ip_dscp), - .input_ip_ecn(input_udp_ip_ecn), - .input_ip_identification(input_udp_ip_identification), - .input_ip_flags(input_udp_ip_flags), - .input_ip_fragment_offset(input_udp_ip_fragment_offset), - .input_ip_ttl(input_udp_ip_ttl), - .input_ip_header_checksum(input_udp_ip_header_checksum), - .input_ip_source_ip(input_udp_ip_source_ip), - .input_ip_dest_ip(input_udp_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_udp_eth_dest_mac), + .s_eth_src_mac(s_udp_eth_src_mac), + .s_eth_type(s_udp_eth_type), + .s_ip_version(s_udp_ip_version), + .s_ip_ihl(s_udp_ip_ihl), + .s_ip_dscp(s_udp_ip_dscp), + .s_ip_ecn(s_udp_ip_ecn), + .s_ip_identification(s_udp_ip_identification), + .s_ip_flags(s_udp_ip_flags), + .s_ip_fragment_offset(s_udp_ip_fragment_offset), + .s_ip_ttl(s_udp_ip_ttl), + .s_ip_header_checksum(s_udp_ip_header_checksum), + .s_ip_source_ip(s_udp_ip_source_ip), + .s_ip_dest_ip(s_udp_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(tx_udp_hdr_valid), - .output_udp_hdr_ready(tx_udp_hdr_ready), - .output_eth_dest_mac(tx_udp_eth_dest_mac), - .output_eth_src_mac(tx_udp_eth_src_mac), - .output_eth_type(tx_udp_eth_type), - .output_ip_version(tx_udp_ip_version), - .output_ip_ihl(tx_udp_ip_ihl), - .output_ip_dscp(tx_udp_ip_dscp), - .output_ip_ecn(tx_udp_ip_ecn), - .output_ip_length(), - .output_ip_identification(tx_udp_ip_identification), - .output_ip_flags(tx_udp_ip_flags), - .output_ip_fragment_offset(tx_udp_ip_fragment_offset), - .output_ip_ttl(tx_udp_ip_ttl), - .output_ip_protocol(), - .output_ip_header_checksum(tx_udp_ip_header_checksum), - .output_ip_source_ip(tx_udp_ip_source_ip), - .output_ip_dest_ip(tx_udp_ip_dest_ip), - .output_udp_source_port(tx_udp_source_port), - .output_udp_dest_port(tx_udp_dest_port), - .output_udp_length(tx_udp_length), - .output_udp_checksum(tx_udp_checksum), - .output_udp_payload_tdata(tx_udp_payload_tdata), - .output_udp_payload_tvalid(tx_udp_payload_tvalid), - .output_udp_payload_tready(tx_udp_payload_tready), - .output_udp_payload_tlast(tx_udp_payload_tlast), - .output_udp_payload_tuser(tx_udp_payload_tuser), + .m_udp_hdr_valid(tx_udp_hdr_valid), + .m_udp_hdr_ready(tx_udp_hdr_ready), + .m_eth_dest_mac(tx_udp_eth_dest_mac), + .m_eth_src_mac(tx_udp_eth_src_mac), + .m_eth_type(tx_udp_eth_type), + .m_ip_version(tx_udp_ip_version), + .m_ip_ihl(tx_udp_ip_ihl), + .m_ip_dscp(tx_udp_ip_dscp), + .m_ip_ecn(tx_udp_ip_ecn), + .m_ip_length(), + .m_ip_identification(tx_udp_ip_identification), + .m_ip_flags(tx_udp_ip_flags), + .m_ip_fragment_offset(tx_udp_ip_fragment_offset), + .m_ip_ttl(tx_udp_ip_ttl), + .m_ip_protocol(), + .m_ip_header_checksum(tx_udp_ip_header_checksum), + .m_ip_source_ip(tx_udp_ip_source_ip), + .m_ip_dest_ip(tx_udp_ip_dest_ip), + .m_udp_source_port(tx_udp_source_port), + .m_udp_dest_port(tx_udp_dest_port), + .m_udp_length(tx_udp_length), + .m_udp_checksum(tx_udp_checksum), + .m_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // Status signals .busy() ); end else begin - assign tx_udp_hdr_valid = input_udp_hdr_valid; - assign input_udp_hdr_ready = tx_udp_hdr_ready; - assign tx_udp_eth_dest_mac = input_udp_eth_dest_mac; - assign tx_udp_eth_src_mac = input_udp_eth_src_mac; - assign tx_udp_eth_type = input_udp_eth_type; - assign tx_udp_ip_version = input_udp_ip_version; - assign tx_udp_ip_ihl = input_udp_ip_ihl; - assign tx_udp_ip_dscp = input_udp_ip_dscp; - assign tx_udp_ip_ecn = input_udp_ip_ecn; - assign tx_udp_ip_identification = input_udp_ip_identification; - assign tx_udp_ip_flags = input_udp_ip_flags; - assign tx_udp_ip_fragment_offset = input_udp_ip_fragment_offset; - assign tx_udp_ip_ttl = input_udp_ip_ttl; - assign tx_udp_ip_header_checksum = input_udp_ip_header_checksum; - assign tx_udp_ip_source_ip = input_udp_ip_source_ip; - assign tx_udp_ip_dest_ip = input_udp_ip_dest_ip; - assign tx_udp_source_port = input_udp_source_port; - assign tx_udp_dest_port = input_udp_dest_port; - assign tx_udp_length = input_udp_length; - assign tx_udp_checksum = input_udp_checksum; - assign tx_udp_payload_tdata = input_udp_payload_tdata; - assign tx_udp_payload_tvalid = input_udp_payload_tvalid; - assign input_udp_payload_tready = tx_udp_payload_tready; - assign tx_udp_payload_tlast = input_udp_payload_tlast; - assign tx_udp_payload_tuser = input_udp_payload_tuser; + assign tx_udp_hdr_valid = s_udp_hdr_valid; + assign s_udp_hdr_ready = tx_udp_hdr_ready; + assign tx_udp_eth_dest_mac = s_udp_eth_dest_mac; + assign tx_udp_eth_src_mac = s_udp_eth_src_mac; + assign tx_udp_eth_type = s_udp_eth_type; + assign tx_udp_ip_version = s_udp_ip_version; + assign tx_udp_ip_ihl = s_udp_ip_ihl; + assign tx_udp_ip_dscp = s_udp_ip_dscp; + assign tx_udp_ip_ecn = s_udp_ip_ecn; + assign tx_udp_ip_identification = s_udp_ip_identification; + assign tx_udp_ip_flags = s_udp_ip_flags; + assign tx_udp_ip_fragment_offset = s_udp_ip_fragment_offset; + assign tx_udp_ip_ttl = s_udp_ip_ttl; + assign tx_udp_ip_header_checksum = s_udp_ip_header_checksum; + assign tx_udp_ip_source_ip = s_udp_ip_source_ip; + assign tx_udp_ip_dest_ip = s_udp_ip_dest_ip; + assign tx_udp_source_port = s_udp_source_port; + assign tx_udp_dest_port = s_udp_dest_port; + assign tx_udp_length = s_udp_length; + assign tx_udp_checksum = s_udp_checksum; + assign tx_udp_payload_axis_tdata = s_udp_payload_axis_tdata; + assign tx_udp_payload_axis_tvalid = s_udp_payload_axis_tvalid; + assign s_udp_payload_axis_tready = tx_udp_payload_axis_tready; + assign tx_udp_payload_axis_tlast = s_udp_payload_axis_tlast; + assign tx_udp_payload_axis_tuser = s_udp_payload_axis_tuser; end @@ -355,56 +355,56 @@ udp_ip_tx_inst ( .clk(clk), .rst(rst), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_eth_dest_mac(tx_udp_eth_dest_mac), - .input_eth_src_mac(tx_udp_eth_src_mac), - .input_eth_type(tx_udp_eth_type), - .input_ip_version(tx_udp_ip_version), - .input_ip_ihl(tx_udp_ip_ihl), - .input_ip_dscp(tx_udp_ip_dscp), - .input_ip_ecn(tx_udp_ip_ecn), - .input_ip_identification(tx_udp_ip_identification), - .input_ip_flags(tx_udp_ip_flags), - .input_ip_fragment_offset(tx_udp_ip_fragment_offset), - .input_ip_ttl(tx_udp_ip_ttl), - .input_ip_protocol(8'h11), - .input_ip_header_checksum(tx_udp_ip_header_checksum), - .input_ip_source_ip(tx_udp_ip_source_ip), - .input_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_eth_dest_mac(tx_udp_eth_dest_mac), + .s_eth_src_mac(tx_udp_eth_src_mac), + .s_eth_type(tx_udp_eth_type), + .s_ip_version(tx_udp_ip_version), + .s_ip_ihl(tx_udp_ip_ihl), + .s_ip_dscp(tx_udp_ip_dscp), + .s_ip_ecn(tx_udp_ip_ecn), + .s_ip_identification(tx_udp_ip_identification), + .s_ip_flags(tx_udp_ip_flags), + .s_ip_fragment_offset(tx_udp_ip_fragment_offset), + .s_ip_ttl(tx_udp_ip_ttl), + .s_ip_protocol(8'h11), + .s_ip_header_checksum(tx_udp_ip_header_checksum), + .s_ip_source_ip(tx_udp_ip_source_ip), + .s_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_ip_eth_dest_mac), - .output_eth_src_mac(output_ip_eth_src_mac), - .output_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_ip_eth_dest_mac), + .m_eth_src_mac(m_ip_eth_src_mac), + .m_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .busy(tx_busy), .error_payload_early_termination(tx_error_payload_early_termination) diff --git a/rtl/udp_64.v b/rtl/udp_64.v index 26c40ae09..2feaff945 100644 --- a/rtl/udp_64.v +++ b/rtl/udp_64.v @@ -42,120 +42,120 @@ module udp_64 # /* * IP frame input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [47:0] input_ip_eth_dest_mac, - input wire [47:0] input_ip_eth_src_mac, - input wire [15:0] input_ip_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [63:0] input_ip_payload_tdata, - input wire [7:0] input_ip_payload_tkeep, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [47:0] s_ip_eth_dest_mac, + input wire [47:0] s_ip_eth_src_mac, + input wire [15:0] s_ip_eth_type, + input wire [3:0] s_ip_version, + input wire [3:0] s_ip_ihl, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [15:0] s_ip_header_checksum, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [63:0] s_ip_payload_axis_tdata, + input wire [7:0] s_ip_payload_axis_tkeep, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * IP frame output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_ip_eth_dest_mac, - output wire [47:0] output_ip_eth_src_mac, - output wire [15:0] output_ip_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_ip_eth_dest_mac, + output wire [47:0] m_ip_eth_src_mac, + output wire [15:0] m_ip_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [63:0] m_ip_payload_axis_tdata, + output wire [7:0] m_ip_payload_axis_tkeep, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * UDP frame input */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [47:0] input_udp_eth_dest_mac, - input wire [47:0] input_udp_eth_src_mac, - input wire [15:0] input_udp_eth_type, - input wire [3:0] input_udp_ip_version, - input wire [3:0] input_udp_ip_ihl, - input wire [5:0] input_udp_ip_dscp, - input wire [1:0] input_udp_ip_ecn, - input wire [15:0] input_udp_ip_identification, - input wire [2:0] input_udp_ip_flags, - input wire [12:0] input_udp_ip_fragment_offset, - input wire [7:0] input_udp_ip_ttl, - input wire [15:0] input_udp_ip_header_checksum, - input wire [31:0] input_udp_ip_source_ip, - input wire [31:0] input_udp_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [15:0] input_udp_length, - input wire [15:0] input_udp_checksum, - input wire [63:0] input_udp_payload_tdata, - input wire [7:0] input_udp_payload_tkeep, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, + input wire s_udp_hdr_valid, + output wire s_udp_hdr_ready, + input wire [47:0] s_udp_eth_dest_mac, + input wire [47:0] s_udp_eth_src_mac, + input wire [15:0] s_udp_eth_type, + input wire [3:0] s_udp_ip_version, + input wire [3:0] s_udp_ip_ihl, + input wire [5:0] s_udp_ip_dscp, + input wire [1:0] s_udp_ip_ecn, + input wire [15:0] s_udp_ip_identification, + input wire [2:0] s_udp_ip_flags, + input wire [12:0] s_udp_ip_fragment_offset, + input wire [7:0] s_udp_ip_ttl, + input wire [15:0] s_udp_ip_header_checksum, + input wire [31:0] s_udp_ip_source_ip, + input wire [31:0] s_udp_ip_dest_ip, + input wire [15:0] s_udp_source_port, + input wire [15:0] s_udp_dest_port, + input wire [15:0] s_udp_length, + input wire [15:0] s_udp_checksum, + input wire [63:0] s_udp_payload_axis_tdata, + input wire [7:0] s_udp_payload_axis_tkeep, + input wire s_udp_payload_axis_tvalid, + output wire s_udp_payload_axis_tready, + input wire s_udp_payload_axis_tlast, + input wire s_udp_payload_axis_tuser, /* * UDP frame output */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_udp_eth_dest_mac, - output wire [47:0] output_udp_eth_src_mac, - output wire [15:0] output_udp_eth_type, - output wire [3:0] output_udp_ip_version, - output wire [3:0] output_udp_ip_ihl, - output wire [5:0] output_udp_ip_dscp, - output wire [1:0] output_udp_ip_ecn, - output wire [15:0] output_udp_ip_length, - output wire [15:0] output_udp_ip_identification, - output wire [2:0] output_udp_ip_flags, - output wire [12:0] output_udp_ip_fragment_offset, - output wire [7:0] output_udp_ip_ttl, - output wire [7:0] output_udp_ip_protocol, - output wire [15:0] output_udp_ip_header_checksum, - output wire [31:0] output_udp_ip_source_ip, - output wire [31:0] output_udp_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [63:0] output_udp_payload_tdata, - output wire [7:0] output_udp_payload_tkeep, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, + output wire m_udp_hdr_valid, + input wire m_udp_hdr_ready, + output wire [47:0] m_udp_eth_dest_mac, + output wire [47:0] m_udp_eth_src_mac, + output wire [15:0] m_udp_eth_type, + output wire [3:0] m_udp_ip_version, + output wire [3:0] m_udp_ip_ihl, + output wire [5:0] m_udp_ip_dscp, + output wire [1:0] m_udp_ip_ecn, + output wire [15:0] m_udp_ip_length, + output wire [15:0] m_udp_ip_identification, + output wire [2:0] m_udp_ip_flags, + output wire [12:0] m_udp_ip_fragment_offset, + output wire [7:0] m_udp_ip_ttl, + output wire [7:0] m_udp_ip_protocol, + output wire [15:0] m_udp_ip_header_checksum, + output wire [31:0] m_udp_ip_source_ip, + output wire [31:0] m_udp_ip_dest_ip, + output wire [15:0] m_udp_source_port, + output wire [15:0] m_udp_dest_port, + output wire [15:0] m_udp_length, + output wire [15:0] m_udp_checksum, + output wire [63:0] m_udp_payload_axis_tdata, + output wire [7:0] m_udp_payload_axis_tkeep, + output wire m_udp_payload_axis_tvalid, + input wire m_udp_payload_axis_tready, + output wire m_udp_payload_axis_tlast, + output wire m_udp_payload_axis_tuser, /* * Status signals @@ -187,71 +187,71 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [63:0] tx_udp_payload_tdata; -wire [7:0] tx_udp_payload_tkeep; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [63:0] tx_udp_payload_axis_tdata; +wire [7:0] tx_udp_payload_axis_tkeep; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; udp_ip_rx_64 udp_ip_rx_64_inst ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_eth_dest_mac(input_ip_eth_dest_mac), - .input_eth_src_mac(input_ip_eth_src_mac), - .input_eth_type(input_ip_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tkeep(input_ip_payload_tkeep), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_ip_eth_dest_mac), + .s_eth_src_mac(s_ip_eth_src_mac), + .s_eth_type(s_ip_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_udp_eth_dest_mac), - .output_eth_src_mac(output_udp_eth_src_mac), - .output_eth_type(output_udp_eth_type), - .output_ip_version(output_udp_ip_version), - .output_ip_ihl(output_udp_ip_ihl), - .output_ip_dscp(output_udp_ip_dscp), - .output_ip_ecn(output_udp_ip_ecn), - .output_ip_length(output_udp_ip_length), - .output_ip_identification(output_udp_ip_identification), - .output_ip_flags(output_udp_ip_flags), - .output_ip_fragment_offset(output_udp_ip_fragment_offset), - .output_ip_ttl(output_udp_ip_ttl), - .output_ip_protocol(output_udp_ip_protocol), - .output_ip_header_checksum(output_udp_ip_header_checksum), - .output_ip_source_ip(output_udp_ip_source_ip), - .output_ip_dest_ip(output_udp_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tkeep(output_udp_payload_tkeep), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_udp_eth_dest_mac), + .m_eth_src_mac(m_udp_eth_src_mac), + .m_eth_type(m_udp_eth_type), + .m_ip_version(m_udp_ip_version), + .m_ip_ihl(m_udp_ip_ihl), + .m_ip_dscp(m_udp_ip_dscp), + .m_ip_ecn(m_udp_ip_ecn), + .m_ip_length(m_udp_ip_length), + .m_ip_identification(m_udp_ip_identification), + .m_ip_flags(m_udp_ip_flags), + .m_ip_fragment_offset(m_udp_ip_fragment_offset), + .m_ip_ttl(m_udp_ip_ttl), + .m_ip_protocol(m_udp_ip_protocol), + .m_ip_header_checksum(m_udp_ip_header_checksum), + .m_ip_source_ip(m_udp_ip_source_ip), + .m_ip_dest_ip(m_udp_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Status signals .busy(rx_busy), .error_header_early_termination(rx_error_header_early_termination), @@ -270,90 +270,90 @@ if (CHECKSUM_GEN_ENABLE) begin .clk(clk), .rst(rst), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_eth_dest_mac(input_udp_eth_dest_mac), - .input_eth_src_mac(input_udp_eth_src_mac), - .input_eth_type(input_udp_eth_type), - .input_ip_version(input_udp_ip_version), - .input_ip_ihl(input_udp_ip_ihl), - .input_ip_dscp(input_udp_ip_dscp), - .input_ip_ecn(input_udp_ip_ecn), - .input_ip_identification(input_udp_ip_identification), - .input_ip_flags(input_udp_ip_flags), - .input_ip_fragment_offset(input_udp_ip_fragment_offset), - .input_ip_ttl(input_udp_ip_ttl), - .input_ip_header_checksum(input_udp_ip_header_checksum), - .input_ip_source_ip(input_udp_ip_source_ip), - .input_ip_dest_ip(input_udp_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tkeep(input_udp_payload_tkeep), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_udp_eth_dest_mac), + .s_eth_src_mac(s_udp_eth_src_mac), + .s_eth_type(s_udp_eth_type), + .s_ip_version(s_udp_ip_version), + .s_ip_ihl(s_udp_ip_ihl), + .s_ip_dscp(s_udp_ip_dscp), + .s_ip_ecn(s_udp_ip_ecn), + .s_ip_identification(s_udp_ip_identification), + .s_ip_flags(s_udp_ip_flags), + .s_ip_fragment_offset(s_udp_ip_fragment_offset), + .s_ip_ttl(s_udp_ip_ttl), + .s_ip_header_checksum(s_udp_ip_header_checksum), + .s_ip_source_ip(s_udp_ip_source_ip), + .s_ip_dest_ip(s_udp_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(tx_udp_hdr_valid), - .output_udp_hdr_ready(tx_udp_hdr_ready), - .output_eth_dest_mac(tx_udp_eth_dest_mac), - .output_eth_src_mac(tx_udp_eth_src_mac), - .output_eth_type(tx_udp_eth_type), - .output_ip_version(tx_udp_ip_version), - .output_ip_ihl(tx_udp_ip_ihl), - .output_ip_dscp(tx_udp_ip_dscp), - .output_ip_ecn(tx_udp_ip_ecn), - .output_ip_length(), - .output_ip_identification(tx_udp_ip_identification), - .output_ip_flags(tx_udp_ip_flags), - .output_ip_fragment_offset(tx_udp_ip_fragment_offset), - .output_ip_ttl(tx_udp_ip_ttl), - .output_ip_header_checksum(tx_udp_ip_header_checksum), - .output_ip_source_ip(tx_udp_ip_source_ip), - .output_ip_dest_ip(tx_udp_ip_dest_ip), - .output_udp_source_port(tx_udp_source_port), - .output_udp_dest_port(tx_udp_dest_port), - .output_udp_length(tx_udp_length), - .output_udp_checksum(tx_udp_checksum), - .output_udp_payload_tdata(tx_udp_payload_tdata), - .output_udp_payload_tkeep(tx_udp_payload_tkeep), - .output_udp_payload_tvalid(tx_udp_payload_tvalid), - .output_udp_payload_tready(tx_udp_payload_tready), - .output_udp_payload_tlast(tx_udp_payload_tlast), - .output_udp_payload_tuser(tx_udp_payload_tuser), + .m_udp_hdr_valid(tx_udp_hdr_valid), + .m_udp_hdr_ready(tx_udp_hdr_ready), + .m_eth_dest_mac(tx_udp_eth_dest_mac), + .m_eth_src_mac(tx_udp_eth_src_mac), + .m_eth_type(tx_udp_eth_type), + .m_ip_version(tx_udp_ip_version), + .m_ip_ihl(tx_udp_ip_ihl), + .m_ip_dscp(tx_udp_ip_dscp), + .m_ip_ecn(tx_udp_ip_ecn), + .m_ip_length(), + .m_ip_identification(tx_udp_ip_identification), + .m_ip_flags(tx_udp_ip_flags), + .m_ip_fragment_offset(tx_udp_ip_fragment_offset), + .m_ip_ttl(tx_udp_ip_ttl), + .m_ip_header_checksum(tx_udp_ip_header_checksum), + .m_ip_source_ip(tx_udp_ip_source_ip), + .m_ip_dest_ip(tx_udp_ip_dest_ip), + .m_udp_source_port(tx_udp_source_port), + .m_udp_dest_port(tx_udp_dest_port), + .m_udp_length(tx_udp_length), + .m_udp_checksum(tx_udp_checksum), + .m_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // Status signals .busy() ); end else begin - assign tx_udp_hdr_valid = input_udp_hdr_valid; - assign input_udp_hdr_ready = tx_udp_hdr_ready; - assign tx_udp_eth_dest_mac = input_udp_eth_dest_mac; - assign tx_udp_eth_src_mac = input_udp_eth_src_mac; - assign tx_udp_eth_type = input_udp_eth_type; - assign tx_udp_ip_version = input_udp_ip_version; - assign tx_udp_ip_ihl = input_udp_ip_ihl; - assign tx_udp_ip_dscp = input_udp_ip_dscp; - assign tx_udp_ip_ecn = input_udp_ip_ecn; - assign tx_udp_ip_identification = input_udp_ip_identification; - assign tx_udp_ip_flags = input_udp_ip_flags; - assign tx_udp_ip_fragment_offset = input_udp_ip_fragment_offset; - assign tx_udp_ip_ttl = input_udp_ip_ttl; - assign tx_udp_ip_header_checksum = input_udp_ip_header_checksum; - assign tx_udp_ip_source_ip = input_udp_ip_source_ip; - assign tx_udp_ip_dest_ip = input_udp_ip_dest_ip; - assign tx_udp_source_port = input_udp_source_port; - assign tx_udp_dest_port = input_udp_dest_port; - assign tx_udp_length = input_udp_length; - assign tx_udp_checksum = input_udp_checksum; - assign tx_udp_payload_tdata = input_udp_payload_tdata; - assign tx_udp_payload_tkeep = input_udp_payload_tkeep; - assign tx_udp_payload_tvalid = input_udp_payload_tvalid; - assign input_udp_payload_tready = tx_udp_payload_tready; - assign tx_udp_payload_tlast = input_udp_payload_tlast; - assign tx_udp_payload_tuser = input_udp_payload_tuser; + assign tx_udp_hdr_valid = s_udp_hdr_valid; + assign s_udp_hdr_ready = tx_udp_hdr_ready; + assign tx_udp_eth_dest_mac = s_udp_eth_dest_mac; + assign tx_udp_eth_src_mac = s_udp_eth_src_mac; + assign tx_udp_eth_type = s_udp_eth_type; + assign tx_udp_ip_version = s_udp_ip_version; + assign tx_udp_ip_ihl = s_udp_ip_ihl; + assign tx_udp_ip_dscp = s_udp_ip_dscp; + assign tx_udp_ip_ecn = s_udp_ip_ecn; + assign tx_udp_ip_identification = s_udp_ip_identification; + assign tx_udp_ip_flags = s_udp_ip_flags; + assign tx_udp_ip_fragment_offset = s_udp_ip_fragment_offset; + assign tx_udp_ip_ttl = s_udp_ip_ttl; + assign tx_udp_ip_header_checksum = s_udp_ip_header_checksum; + assign tx_udp_ip_source_ip = s_udp_ip_source_ip; + assign tx_udp_ip_dest_ip = s_udp_ip_dest_ip; + assign tx_udp_source_port = s_udp_source_port; + assign tx_udp_dest_port = s_udp_dest_port; + assign tx_udp_length = s_udp_length; + assign tx_udp_checksum = s_udp_checksum; + assign tx_udp_payload_axis_tdata = s_udp_payload_axis_tdata; + assign tx_udp_payload_axis_tkeep = s_udp_payload_axis_tkeep; + assign tx_udp_payload_axis_tvalid = s_udp_payload_axis_tvalid; + assign s_udp_payload_axis_tready = tx_udp_payload_axis_tready; + assign tx_udp_payload_axis_tlast = s_udp_payload_axis_tlast; + assign tx_udp_payload_axis_tuser = s_udp_payload_axis_tuser; end @@ -364,58 +364,58 @@ udp_ip_tx_64_inst ( .clk(clk), .rst(rst), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_eth_dest_mac(tx_udp_eth_dest_mac), - .input_eth_src_mac(tx_udp_eth_src_mac), - .input_eth_type(tx_udp_eth_type), - .input_ip_version(tx_udp_ip_version), - .input_ip_ihl(tx_udp_ip_ihl), - .input_ip_dscp(tx_udp_ip_dscp), - .input_ip_ecn(tx_udp_ip_ecn), - .input_ip_identification(tx_udp_ip_identification), - .input_ip_flags(tx_udp_ip_flags), - .input_ip_fragment_offset(tx_udp_ip_fragment_offset), - .input_ip_ttl(tx_udp_ip_ttl), - .input_ip_protocol(8'h11), - .input_ip_header_checksum(tx_udp_ip_header_checksum), - .input_ip_source_ip(tx_udp_ip_source_ip), - .input_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tkeep(tx_udp_payload_tkeep), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_eth_dest_mac(tx_udp_eth_dest_mac), + .s_eth_src_mac(tx_udp_eth_src_mac), + .s_eth_type(tx_udp_eth_type), + .s_ip_version(tx_udp_ip_version), + .s_ip_ihl(tx_udp_ip_ihl), + .s_ip_dscp(tx_udp_ip_dscp), + .s_ip_ecn(tx_udp_ip_ecn), + .s_ip_identification(tx_udp_ip_identification), + .s_ip_flags(tx_udp_ip_flags), + .s_ip_fragment_offset(tx_udp_ip_fragment_offset), + .s_ip_ttl(tx_udp_ip_ttl), + .s_ip_protocol(8'h11), + .s_ip_header_checksum(tx_udp_ip_header_checksum), + .s_ip_source_ip(tx_udp_ip_source_ip), + .s_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_ip_eth_dest_mac), - .output_eth_src_mac(output_ip_eth_src_mac), - .output_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_ip_eth_dest_mac), + .m_eth_src_mac(m_ip_eth_src_mac), + .m_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .busy(tx_busy), .error_payload_early_termination(tx_error_payload_early_termination) diff --git a/rtl/udp_checksum_gen.v b/rtl/udp_checksum_gen.v index 0e2f788dd..41c5f1591 100644 --- a/rtl/udp_checksum_gen.v +++ b/rtl/udp_checksum_gen.v @@ -41,60 +41,60 @@ module udp_checksum_gen # /* * UDP frame input */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [7:0] input_udp_payload_tdata, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, + input wire s_udp_hdr_valid, + output wire s_udp_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [3:0] s_ip_version, + input wire [3:0] s_ip_ihl, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [15:0] s_ip_header_checksum, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [15:0] s_udp_source_port, + input wire [15:0] s_udp_dest_port, + input wire [7:0] s_udp_payload_axis_tdata, + input wire s_udp_payload_axis_tvalid, + output wire s_udp_payload_axis_tready, + input wire s_udp_payload_axis_tlast, + input wire s_udp_payload_axis_tuser, /* * UDP frame output */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [7:0] output_udp_payload_tdata, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, + output wire m_udp_hdr_valid, + input wire m_udp_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [15:0] m_udp_source_port, + output wire [15:0] m_udp_dest_port, + output wire [15:0] m_udp_length, + output wire [15:0] m_udp_checksum, + output wire [7:0] m_udp_payload_axis_tdata, + output wire m_udp_payload_axis_tvalid, + input wire m_udp_payload_axis_tready, + output wire m_udp_payload_axis_tlast, + output wire m_udp_payload_axis_tuser, /* * Status signals @@ -176,25 +176,25 @@ reg [15:0] udp_dest_port_reg = 16'd0; reg hdr_valid_reg = 0, hdr_valid_next; -reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; +reg s_udp_hdr_ready_reg = 1'b0, s_udp_hdr_ready_next; +reg s_udp_payload_axis_tready_reg = 1'b0, s_udp_payload_axis_tready_next; reg busy_reg = 1'b0; /* * UDP Payload FIFO */ -wire [7:0] input_udp_payload_fifo_tdata; -wire input_udp_payload_fifo_tvalid; -wire input_udp_payload_fifo_tready; -wire input_udp_payload_fifo_tlast; -wire input_udp_payload_fifo_tuser; +wire [7:0] s_udp_payload_fifo_tdata; +wire s_udp_payload_fifo_tvalid; +wire s_udp_payload_fifo_tready; +wire s_udp_payload_fifo_tlast; +wire s_udp_payload_fifo_tuser; -wire [7:0] output_udp_payload_fifo_tdata; -wire output_udp_payload_fifo_tvalid; -wire output_udp_payload_fifo_tready; -wire output_udp_payload_fifo_tlast; -wire output_udp_payload_fifo_tuser; +wire [7:0] m_udp_payload_fifo_tdata; +wire m_udp_payload_fifo_tvalid; +wire m_udp_payload_fifo_tready; +wire m_udp_payload_fifo_tlast; +wire m_udp_payload_fifo_tuser; axis_fifo #( .ADDR_WIDTH(PAYLOAD_FIFO_ADDR_WIDTH), @@ -211,40 +211,40 @@ payload_fifo ( .clk(clk), .rst(rst), // AXI input - .s_axis_tdata(input_udp_payload_fifo_tdata), + .s_axis_tdata(s_udp_payload_fifo_tdata), .s_axis_tkeep(0), - .s_axis_tvalid(input_udp_payload_fifo_tvalid), - .s_axis_tready(input_udp_payload_fifo_tready), - .s_axis_tlast(input_udp_payload_fifo_tlast), + .s_axis_tvalid(s_udp_payload_fifo_tvalid), + .s_axis_tready(s_udp_payload_fifo_tready), + .s_axis_tlast(s_udp_payload_fifo_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(input_udp_payload_fifo_tuser), + .s_axis_tuser(s_udp_payload_fifo_tuser), // AXI output - .m_axis_tdata(output_udp_payload_fifo_tdata), + .m_axis_tdata(m_udp_payload_fifo_tdata), .m_axis_tkeep(), - .m_axis_tvalid(output_udp_payload_fifo_tvalid), - .m_axis_tready(output_udp_payload_fifo_tready), - .m_axis_tlast(output_udp_payload_fifo_tlast), + .m_axis_tvalid(m_udp_payload_fifo_tvalid), + .m_axis_tready(m_udp_payload_fifo_tready), + .m_axis_tlast(m_udp_payload_fifo_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(output_udp_payload_fifo_tuser), + .m_axis_tuser(m_udp_payload_fifo_tuser), // Status .status_overflow(), .status_bad_frame(), .status_good_frame() ); -assign input_udp_payload_fifo_tdata = input_udp_payload_tdata; -assign input_udp_payload_fifo_tvalid = input_udp_payload_tvalid & shift_payload_in; -assign input_udp_payload_tready = input_udp_payload_fifo_tready & shift_payload_in; -assign input_udp_payload_fifo_tlast = input_udp_payload_tlast; -assign input_udp_payload_fifo_tuser = input_udp_payload_tuser; +assign s_udp_payload_fifo_tdata = s_udp_payload_axis_tdata; +assign s_udp_payload_fifo_tvalid = s_udp_payload_axis_tvalid && shift_payload_in; +assign s_udp_payload_axis_tready = s_udp_payload_fifo_tready && shift_payload_in; +assign s_udp_payload_fifo_tlast = s_udp_payload_axis_tlast; +assign s_udp_payload_fifo_tuser = s_udp_payload_axis_tuser; -assign output_udp_payload_tdata = output_udp_payload_fifo_tdata; -assign output_udp_payload_tvalid = output_udp_payload_fifo_tvalid; -assign output_udp_payload_fifo_tready = output_udp_payload_tready; -assign output_udp_payload_tlast = output_udp_payload_fifo_tlast; -assign output_udp_payload_tuser = output_udp_payload_fifo_tuser; +assign m_udp_payload_axis_tdata = m_udp_payload_fifo_tdata; +assign m_udp_payload_axis_tvalid = m_udp_payload_fifo_tvalid; +assign m_udp_payload_fifo_tready = m_udp_payload_axis_tready; +assign m_udp_payload_axis_tlast = m_udp_payload_fifo_tlast; +assign m_udp_payload_axis_tuser = m_udp_payload_fifo_tuser; /* * UDP Header FIFO @@ -271,26 +271,26 @@ reg [15:0] udp_dest_port_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; reg [15:0] udp_length_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; reg [15:0] udp_checksum_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; -reg [3:0] output_ip_version_reg = 4'd0; -reg [3:0] output_ip_ihl_reg = 4'd0; -reg [5:0] output_ip_dscp_reg = 6'd0; -reg [1:0] output_ip_ecn_reg = 2'd0; -reg [15:0] output_ip_identification_reg = 16'd0; -reg [2:0] output_ip_flags_reg = 3'd0; -reg [12:0] output_ip_fragment_offset_reg = 13'd0; -reg [7:0] output_ip_ttl_reg = 8'd0; -reg [15:0] output_ip_header_checksum_reg = 16'd0; -reg [31:0] output_ip_source_ip_reg = 32'd0; -reg [31:0] output_ip_dest_ip_reg = 32'd0; -reg [15:0] output_udp_source_port_reg = 16'd0; -reg [15:0] output_udp_dest_port_reg = 16'd0; -reg [15:0] output_udp_length_reg = 16'd0; -reg [15:0] output_udp_checksum_reg = 16'd0; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; +reg [3:0] m_ip_version_reg = 4'd0; +reg [3:0] m_ip_ihl_reg = 4'd0; +reg [5:0] m_ip_dscp_reg = 6'd0; +reg [1:0] m_ip_ecn_reg = 2'd0; +reg [15:0] m_ip_identification_reg = 16'd0; +reg [2:0] m_ip_flags_reg = 3'd0; +reg [12:0] m_ip_fragment_offset_reg = 13'd0; +reg [7:0] m_ip_ttl_reg = 8'd0; +reg [15:0] m_ip_header_checksum_reg = 16'd0; +reg [31:0] m_ip_source_ip_reg = 32'd0; +reg [31:0] m_ip_dest_ip_reg = 32'd0; +reg [15:0] m_udp_source_port_reg = 16'd0; +reg [15:0] m_udp_dest_port_reg = 16'd0; +reg [15:0] m_udp_length_reg = 16'd0; +reg [15:0] m_udp_checksum_reg = 16'd0; -reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; +reg m_udp_hdr_valid_reg = 1'b0, m_udp_hdr_valid_next; // full when first MSB different but rest same wire header_fifo_full = ((header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH] != header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH]) && @@ -302,30 +302,30 @@ wire header_fifo_empty = header_fifo_wr_ptr_reg == header_fifo_rd_ptr_reg; reg header_fifo_write; reg header_fifo_read; -wire header_fifo_ready = ~header_fifo_full; +wire header_fifo_ready = !header_fifo_full; -assign output_udp_hdr_valid = output_udp_hdr_valid_reg; +assign m_udp_hdr_valid = m_udp_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_udp_length_reg + 16'd20; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = 8'h11; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_udp_source_port = output_udp_source_port_reg; -assign output_udp_dest_port = output_udp_dest_port_reg; -assign output_udp_length = output_udp_length_reg; -assign output_udp_checksum = output_udp_checksum_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_udp_length_reg + 16'd20; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = 8'h11; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; +assign m_udp_source_port = m_udp_source_port_reg; +assign m_udp_dest_port = m_udp_dest_port_reg; +assign m_udp_length = m_udp_length_reg; +assign m_udp_checksum = m_udp_checksum_reg; // Write logic always @* begin @@ -378,18 +378,18 @@ always @* begin header_fifo_rd_ptr_next = header_fifo_rd_ptr_reg; - output_udp_hdr_valid_next = output_udp_hdr_valid_reg; + m_udp_hdr_valid_next = m_udp_hdr_valid_reg; - if (output_udp_hdr_ready | ~output_udp_hdr_valid) begin + if (m_udp_hdr_ready || !m_udp_hdr_valid) begin // output data not valid OR currently being transferred - if (~header_fifo_empty) begin + if (!header_fifo_empty) begin // not empty, perform read header_fifo_read = 1'b1; - output_udp_hdr_valid_next = 1'b1; + m_udp_hdr_valid_next = 1'b1; header_fifo_rd_ptr_next = header_fifo_rd_ptr_reg + 1; end else begin // empty, invalidate - output_udp_hdr_valid_next = 1'b0; + m_udp_hdr_valid_next = 1'b0; end end end @@ -397,43 +397,43 @@ end always @(posedge clk) begin if (rst) begin header_fifo_rd_ptr_reg <= {HEADER_FIFO_ADDR_WIDTH+1{1'b0}}; - output_udp_hdr_valid_reg <= 1'b0; + m_udp_hdr_valid_reg <= 1'b0; end else begin header_fifo_rd_ptr_reg <= header_fifo_rd_ptr_next; - output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + m_udp_hdr_valid_reg <= m_udp_hdr_valid_next; end if (header_fifo_read) begin - output_eth_dest_mac_reg <= eth_dest_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_eth_src_mac_reg <= eth_src_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_eth_type_reg <= eth_type_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_version_reg <= ip_version_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_ihl_reg <= ip_ihl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_dscp_reg <= ip_dscp_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_ecn_reg <= ip_ecn_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_identification_reg <= ip_identification_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_flags_reg <= ip_flags_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_fragment_offset_reg <= ip_fragment_offset_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_ttl_reg <= ip_ttl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_header_checksum_reg <= ip_header_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_source_ip_reg <= ip_source_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_dest_ip_reg <= ip_dest_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_udp_source_port_reg <= udp_source_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_udp_dest_port_reg <= udp_dest_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_udp_length_reg <= udp_length_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_udp_checksum_reg <= udp_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_eth_dest_mac_reg <= eth_dest_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_eth_src_mac_reg <= eth_src_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_eth_type_reg <= eth_type_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_version_reg <= ip_version_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_ihl_reg <= ip_ihl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_dscp_reg <= ip_dscp_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_ecn_reg <= ip_ecn_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_identification_reg <= ip_identification_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_flags_reg <= ip_flags_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_fragment_offset_reg <= ip_fragment_offset_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_ttl_reg <= ip_ttl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_header_checksum_reg <= ip_header_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_source_ip_reg <= ip_source_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_dest_ip_reg <= ip_dest_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_udp_source_port_reg <= udp_source_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_udp_dest_port_reg <= udp_dest_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_udp_length_reg <= udp_length_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_udp_checksum_reg <= udp_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; end end -assign input_udp_hdr_ready = input_udp_hdr_ready_reg; +assign s_udp_hdr_ready = s_udp_hdr_ready_reg; assign busy = busy_reg; always @* begin state_next = STATE_IDLE; - input_udp_hdr_ready_next = 1'b0; - input_udp_payload_tready_next = 1'b0; + s_udp_hdr_ready_next = 1'b0; + s_udp_payload_axis_tready_next = 1'b0; store_udp_hdr = 1'b0; shift_payload_in = 1'b0; @@ -446,15 +446,15 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - input_udp_hdr_ready_next = header_fifo_ready; + s_udp_hdr_ready_next = header_fifo_ready; - if (input_udp_hdr_ready & input_udp_hdr_valid) begin + if (s_udp_hdr_ready && s_udp_hdr_valid) begin store_udp_hdr = 1'b1; frame_ptr_next = 0; // 16'h0011 = zero padded type field // 16'h0010 = header length times two checksum_next = 16'h0011 + 16'h0010; - input_udp_hdr_ready_next = 1'b0; + s_udp_hdr_ready_next = 1'b0; state_next = STATE_SUM_HEADER_1; end else begin state_next = STATE_IDLE; @@ -480,18 +480,18 @@ always @* begin // sum payload shift_payload_in = 1'b1; - if (input_udp_payload_tready & input_udp_payload_tvalid) begin + if (s_udp_payload_axis_tready && s_udp_payload_axis_tvalid) begin // checksum computation for payload - alternately store and accumulate // add 2 for length calculation (two length fields in pseudo header) if (frame_ptr_reg[0]) begin - checksum_next = checksum_reg + {8'h00, input_udp_payload_tdata} + 2; + checksum_next = checksum_reg + {8'h00, s_udp_payload_axis_tdata} + 2; end else begin - checksum_next = checksum_reg + {input_udp_payload_tdata, 8'h00} + 2; + checksum_next = checksum_reg + {s_udp_payload_axis_tdata, 8'h00} + 2; end frame_ptr_next = frame_ptr_reg + 1; - if (input_udp_payload_tlast) begin + if (s_udp_payload_axis_tlast) begin state_next = STATE_FINISH_SUM; end else begin state_next = STATE_SUM_PAYLOAD; @@ -513,15 +513,15 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - input_udp_hdr_ready_reg <= 1'b0; - input_udp_payload_tready_reg <= 1'b0; + s_udp_hdr_ready_reg <= 1'b0; + s_udp_payload_axis_tready_reg <= 1'b0; hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; end else begin state_reg <= state_next; - input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; - input_udp_payload_tready_reg <= input_udp_payload_tready_next; + s_udp_hdr_ready_reg <= s_udp_hdr_ready_next; + s_udp_payload_axis_tready_reg <= s_udp_payload_axis_tready_next; hdr_valid_reg <= hdr_valid_next; @@ -533,22 +533,22 @@ always @(posedge clk) begin // datapath if (store_udp_hdr) begin - eth_dest_mac_reg <= input_eth_dest_mac; - eth_src_mac_reg <= input_eth_src_mac; - eth_type_reg <= input_eth_type; - ip_version_reg <= input_ip_version; - ip_ihl_reg <= input_ip_ihl; - ip_dscp_reg <= input_ip_dscp; - ip_ecn_reg <= input_ip_ecn; - ip_identification_reg <= input_ip_identification; - ip_flags_reg <= input_ip_flags; - ip_fragment_offset_reg <= input_ip_fragment_offset; - ip_ttl_reg <= input_ip_ttl; - ip_header_checksum_reg <= input_ip_header_checksum; - ip_source_ip_reg <= input_ip_source_ip; - ip_dest_ip_reg <= input_ip_dest_ip; - udp_source_port_reg <= input_udp_source_port; - udp_dest_port_reg <= input_udp_dest_port; + eth_dest_mac_reg <= s_eth_dest_mac; + eth_src_mac_reg <= s_eth_src_mac; + eth_type_reg <= s_eth_type; + ip_version_reg <= s_ip_version; + ip_ihl_reg <= s_ip_ihl; + ip_dscp_reg <= s_ip_dscp; + ip_ecn_reg <= s_ip_ecn; + ip_identification_reg <= s_ip_identification; + ip_flags_reg <= s_ip_flags; + ip_fragment_offset_reg <= s_ip_fragment_offset; + ip_ttl_reg <= s_ip_ttl; + ip_header_checksum_reg <= s_ip_header_checksum; + ip_source_ip_reg <= s_ip_source_ip; + ip_dest_ip_reg <= s_ip_dest_ip; + udp_source_port_reg <= s_udp_source_port; + udp_dest_port_reg <= s_udp_dest_port; end end diff --git a/rtl/udp_checksum_gen_64.v b/rtl/udp_checksum_gen_64.v index ce07a3560..756c60309 100644 --- a/rtl/udp_checksum_gen_64.v +++ b/rtl/udp_checksum_gen_64.v @@ -41,62 +41,62 @@ module udp_checksum_gen_64 # /* * UDP frame input */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [63:0] input_udp_payload_tdata, - input wire [7:0] input_udp_payload_tkeep, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, + input wire s_udp_hdr_valid, + output wire s_udp_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [3:0] s_ip_version, + input wire [3:0] s_ip_ihl, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [15:0] s_ip_header_checksum, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [15:0] s_udp_source_port, + input wire [15:0] s_udp_dest_port, + input wire [63:0] s_udp_payload_axis_tdata, + input wire [7:0] s_udp_payload_axis_tkeep, + input wire s_udp_payload_axis_tvalid, + output wire s_udp_payload_axis_tready, + input wire s_udp_payload_axis_tlast, + input wire s_udp_payload_axis_tuser, /* * UDP frame output */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [63:0] output_udp_payload_tdata, - output wire [7:0] output_udp_payload_tkeep, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, + output wire m_udp_hdr_valid, + input wire m_udp_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [15:0] m_udp_source_port, + output wire [15:0] m_udp_dest_port, + output wire [15:0] m_udp_length, + output wire [15:0] m_udp_checksum, + output wire [63:0] m_udp_payload_axis_tdata, + output wire [7:0] m_udp_payload_axis_tkeep, + output wire m_udp_payload_axis_tvalid, + input wire m_udp_payload_axis_tready, + output wire m_udp_payload_axis_tlast, + output wire m_udp_payload_axis_tuser, /* * Status signals @@ -179,27 +179,27 @@ reg [15:0] udp_dest_port_reg = 16'd0; reg hdr_valid_reg = 0, hdr_valid_next; -reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; +reg s_udp_hdr_ready_reg = 1'b0, s_udp_hdr_ready_next; +reg s_udp_payload_axis_tready_reg = 1'b0, s_udp_payload_axis_tready_next; reg busy_reg = 1'b0; /* * UDP Payload FIFO */ -wire [63:0] input_udp_payload_fifo_tdata; -wire [7:0] input_udp_payload_fifo_tkeep; -wire input_udp_payload_fifo_tvalid; -wire input_udp_payload_fifo_tready; -wire input_udp_payload_fifo_tlast; -wire input_udp_payload_fifo_tuser; +wire [63:0] s_udp_payload_fifo_tdata; +wire [7:0] s_udp_payload_fifo_tkeep; +wire s_udp_payload_fifo_tvalid; +wire s_udp_payload_fifo_tready; +wire s_udp_payload_fifo_tlast; +wire s_udp_payload_fifo_tuser; -wire [63:0] output_udp_payload_fifo_tdata; -wire [7:0] output_udp_payload_fifo_tkeep; -wire output_udp_payload_fifo_tvalid; -wire output_udp_payload_fifo_tready; -wire output_udp_payload_fifo_tlast; -wire output_udp_payload_fifo_tuser; +wire [63:0] m_udp_payload_fifo_tdata; +wire [7:0] m_udp_payload_fifo_tkeep; +wire m_udp_payload_fifo_tvalid; +wire m_udp_payload_fifo_tready; +wire m_udp_payload_fifo_tlast; +wire m_udp_payload_fifo_tuser; axis_fifo #( .ADDR_WIDTH(PAYLOAD_FIFO_ADDR_WIDTH), @@ -217,42 +217,42 @@ payload_fifo ( .clk(clk), .rst(rst), // AXI input - .s_axis_tdata(input_udp_payload_fifo_tdata), - .s_axis_tkeep(input_udp_payload_fifo_tkeep), - .s_axis_tvalid(input_udp_payload_fifo_tvalid), - .s_axis_tready(input_udp_payload_fifo_tready), - .s_axis_tlast(input_udp_payload_fifo_tlast), + .s_axis_tdata(s_udp_payload_fifo_tdata), + .s_axis_tkeep(s_udp_payload_fifo_tkeep), + .s_axis_tvalid(s_udp_payload_fifo_tvalid), + .s_axis_tready(s_udp_payload_fifo_tready), + .s_axis_tlast(s_udp_payload_fifo_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(input_udp_payload_fifo_tuser), + .s_axis_tuser(s_udp_payload_fifo_tuser), // AXI output - .m_axis_tdata(output_udp_payload_fifo_tdata), - .m_axis_tkeep(output_udp_payload_fifo_tkeep), - .m_axis_tvalid(output_udp_payload_fifo_tvalid), - .m_axis_tready(output_udp_payload_fifo_tready), - .m_axis_tlast(output_udp_payload_fifo_tlast), + .m_axis_tdata(m_udp_payload_fifo_tdata), + .m_axis_tkeep(m_udp_payload_fifo_tkeep), + .m_axis_tvalid(m_udp_payload_fifo_tvalid), + .m_axis_tready(m_udp_payload_fifo_tready), + .m_axis_tlast(m_udp_payload_fifo_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(output_udp_payload_fifo_tuser), + .m_axis_tuser(m_udp_payload_fifo_tuser), // Status .status_overflow(), .status_bad_frame(), .status_good_frame() ); -assign input_udp_payload_fifo_tdata = input_udp_payload_tdata; -assign input_udp_payload_fifo_tkeep = input_udp_payload_tkeep; -assign input_udp_payload_fifo_tvalid = input_udp_payload_tvalid & shift_payload_in; -assign input_udp_payload_tready = input_udp_payload_fifo_tready & shift_payload_in; -assign input_udp_payload_fifo_tlast = input_udp_payload_tlast; -assign input_udp_payload_fifo_tuser = input_udp_payload_tuser; +assign s_udp_payload_fifo_tdata = s_udp_payload_axis_tdata; +assign s_udp_payload_fifo_tkeep = s_udp_payload_axis_tkeep; +assign s_udp_payload_fifo_tvalid = s_udp_payload_axis_tvalid && shift_payload_in; +assign s_udp_payload_axis_tready = s_udp_payload_fifo_tready && shift_payload_in; +assign s_udp_payload_fifo_tlast = s_udp_payload_axis_tlast; +assign s_udp_payload_fifo_tuser = s_udp_payload_axis_tuser; -assign output_udp_payload_tdata = output_udp_payload_fifo_tdata; -assign output_udp_payload_tkeep = output_udp_payload_fifo_tkeep; -assign output_udp_payload_tvalid = output_udp_payload_fifo_tvalid; -assign output_udp_payload_fifo_tready = output_udp_payload_tready; -assign output_udp_payload_tlast = output_udp_payload_fifo_tlast; -assign output_udp_payload_tuser = output_udp_payload_fifo_tuser; +assign m_udp_payload_axis_tdata = m_udp_payload_fifo_tdata; +assign m_udp_payload_axis_tkeep = m_udp_payload_fifo_tkeep; +assign m_udp_payload_axis_tvalid = m_udp_payload_fifo_tvalid; +assign m_udp_payload_fifo_tready = m_udp_payload_axis_tready; +assign m_udp_payload_axis_tlast = m_udp_payload_fifo_tlast; +assign m_udp_payload_axis_tuser = m_udp_payload_fifo_tuser; /* * UDP Header FIFO @@ -279,26 +279,26 @@ reg [15:0] udp_dest_port_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; reg [15:0] udp_length_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; reg [15:0] udp_checksum_mem[(2**HEADER_FIFO_ADDR_WIDTH)-1:0]; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; -reg [3:0] output_ip_version_reg = 4'd0; -reg [3:0] output_ip_ihl_reg = 4'd0; -reg [5:0] output_ip_dscp_reg = 6'd0; -reg [1:0] output_ip_ecn_reg = 2'd0; -reg [15:0] output_ip_identification_reg = 16'd0; -reg [2:0] output_ip_flags_reg = 3'd0; -reg [12:0] output_ip_fragment_offset_reg = 13'd0; -reg [7:0] output_ip_ttl_reg = 8'd0; -reg [15:0] output_ip_header_checksum_reg = 16'd0; -reg [31:0] output_ip_source_ip_reg = 32'd0; -reg [31:0] output_ip_dest_ip_reg = 32'd0; -reg [15:0] output_udp_source_port_reg = 16'd0; -reg [15:0] output_udp_dest_port_reg = 16'd0; -reg [15:0] output_udp_length_reg = 16'd0; -reg [15:0] output_udp_checksum_reg = 16'd0; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; +reg [3:0] m_ip_version_reg = 4'd0; +reg [3:0] m_ip_ihl_reg = 4'd0; +reg [5:0] m_ip_dscp_reg = 6'd0; +reg [1:0] m_ip_ecn_reg = 2'd0; +reg [15:0] m_ip_identification_reg = 16'd0; +reg [2:0] m_ip_flags_reg = 3'd0; +reg [12:0] m_ip_fragment_offset_reg = 13'd0; +reg [7:0] m_ip_ttl_reg = 8'd0; +reg [15:0] m_ip_header_checksum_reg = 16'd0; +reg [31:0] m_ip_source_ip_reg = 32'd0; +reg [31:0] m_ip_dest_ip_reg = 32'd0; +reg [15:0] m_udp_source_port_reg = 16'd0; +reg [15:0] m_udp_dest_port_reg = 16'd0; +reg [15:0] m_udp_length_reg = 16'd0; +reg [15:0] m_udp_checksum_reg = 16'd0; -reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; +reg m_udp_hdr_valid_reg = 1'b0, m_udp_hdr_valid_next; // full when first MSB different but rest same wire header_fifo_full = ((header_fifo_wr_ptr_reg[HEADER_FIFO_ADDR_WIDTH] != header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH]) && @@ -310,30 +310,30 @@ wire header_fifo_empty = header_fifo_wr_ptr_reg == header_fifo_rd_ptr_reg; reg header_fifo_write; reg header_fifo_read; -wire header_fifo_ready = ~header_fifo_full; +wire header_fifo_ready = !header_fifo_full; -assign output_udp_hdr_valid = output_udp_hdr_valid_reg; +assign m_udp_hdr_valid = m_udp_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_udp_length_reg + 16'd20; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = 8'h11; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_udp_source_port = output_udp_source_port_reg; -assign output_udp_dest_port = output_udp_dest_port_reg; -assign output_udp_length = output_udp_length_reg; -assign output_udp_checksum = output_udp_checksum_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_udp_length_reg + 16'd20; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = 8'h11; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; +assign m_udp_source_port = m_udp_source_port_reg; +assign m_udp_dest_port = m_udp_dest_port_reg; +assign m_udp_length = m_udp_length_reg; +assign m_udp_checksum = m_udp_checksum_reg; // Write logic always @* begin @@ -386,18 +386,18 @@ always @* begin header_fifo_rd_ptr_next = header_fifo_rd_ptr_reg; - output_udp_hdr_valid_next = output_udp_hdr_valid_reg; + m_udp_hdr_valid_next = m_udp_hdr_valid_reg; - if (output_udp_hdr_ready | ~output_udp_hdr_valid) begin + if (m_udp_hdr_ready || !m_udp_hdr_valid) begin // output data not valid OR currently being transferred - if (~header_fifo_empty) begin + if (!header_fifo_empty) begin // not empty, perform read header_fifo_read = 1'b1; - output_udp_hdr_valid_next = 1'b1; + m_udp_hdr_valid_next = 1'b1; header_fifo_rd_ptr_next = header_fifo_rd_ptr_reg + 1; end else begin // empty, invalidate - output_udp_hdr_valid_next = 1'b0; + m_udp_hdr_valid_next = 1'b0; end end end @@ -405,35 +405,35 @@ end always @(posedge clk) begin if (rst) begin header_fifo_rd_ptr_reg <= {HEADER_FIFO_ADDR_WIDTH+1{1'b0}}; - output_udp_hdr_valid_reg <= 1'b0; + m_udp_hdr_valid_reg <= 1'b0; end else begin header_fifo_rd_ptr_reg <= header_fifo_rd_ptr_next; - output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + m_udp_hdr_valid_reg <= m_udp_hdr_valid_next; end if (header_fifo_read) begin - output_eth_dest_mac_reg <= eth_dest_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_eth_src_mac_reg <= eth_src_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_eth_type_reg <= eth_type_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_version_reg <= ip_version_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_ihl_reg <= ip_ihl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_dscp_reg <= ip_dscp_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_ecn_reg <= ip_ecn_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_identification_reg <= ip_identification_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_flags_reg <= ip_flags_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_fragment_offset_reg <= ip_fragment_offset_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_ttl_reg <= ip_ttl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_header_checksum_reg <= ip_header_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_source_ip_reg <= ip_source_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_ip_dest_ip_reg <= ip_dest_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_udp_source_port_reg <= udp_source_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_udp_dest_port_reg <= udp_dest_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_udp_length_reg <= udp_length_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; - output_udp_checksum_reg <= udp_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_eth_dest_mac_reg <= eth_dest_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_eth_src_mac_reg <= eth_src_mac_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_eth_type_reg <= eth_type_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_version_reg <= ip_version_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_ihl_reg <= ip_ihl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_dscp_reg <= ip_dscp_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_ecn_reg <= ip_ecn_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_identification_reg <= ip_identification_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_flags_reg <= ip_flags_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_fragment_offset_reg <= ip_fragment_offset_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_ttl_reg <= ip_ttl_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_header_checksum_reg <= ip_header_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_source_ip_reg <= ip_source_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_ip_dest_ip_reg <= ip_dest_ip_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_udp_source_port_reg <= udp_source_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_udp_dest_port_reg <= udp_dest_port_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_udp_length_reg <= udp_length_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; + m_udp_checksum_reg <= udp_checksum_mem[header_fifo_rd_ptr_reg[HEADER_FIFO_ADDR_WIDTH-1:0]]; end end -assign input_udp_hdr_ready = input_udp_hdr_ready_reg; +assign s_udp_hdr_ready = s_udp_hdr_ready_reg; assign busy = busy_reg; @@ -442,8 +442,8 @@ integer i, word_cnt; always @* begin state_next = STATE_IDLE; - input_udp_hdr_ready_next = 1'b0; - input_udp_payload_tready_next = 1'b0; + s_udp_hdr_ready_next = 1'b0; + s_udp_payload_axis_tready_next = 1'b0; store_udp_hdr = 1'b0; shift_payload_in = 1'b0; @@ -458,17 +458,17 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - input_udp_hdr_ready_next = header_fifo_ready; + s_udp_hdr_ready_next = header_fifo_ready; - if (input_udp_hdr_ready & input_udp_hdr_valid) begin + if (s_udp_hdr_ready && s_udp_hdr_valid) begin store_udp_hdr = 1'b1; frame_ptr_next = 0; // 16'h0011 = zero padded type field // 16'h0010 = header length times two checksum_next = 16'h0011 + 16'h0010; - checksum_temp1_next = input_ip_source_ip[31:16]; - checksum_temp2_next = input_ip_source_ip[15:0]; - input_udp_hdr_ready_next = 1'b0; + checksum_temp1_next = s_ip_source_ip[31:16]; + checksum_temp2_next = s_ip_source_ip[15:0]; + s_udp_hdr_ready_next = 1'b0; state_next = STATE_SUM_HEADER; end else begin state_next = STATE_IDLE; @@ -486,31 +486,31 @@ always @* begin // sum payload shift_payload_in = 1'b1; - if (input_udp_payload_tready & input_udp_payload_tvalid) begin + if (s_udp_payload_axis_tready && s_udp_payload_axis_tvalid) begin word_cnt = 1; for (i = 1; i <= 8; i = i + 1) begin - if (input_udp_payload_tkeep == 8'hff >> (8-i)) word_cnt = i; + if (s_udp_payload_axis_tkeep == 8'hff >> (8-i)) word_cnt = i; end checksum_temp1_next = 0; checksum_temp2_next = 0; for (i = 0; i < 4; i = i + 1) begin - if (input_udp_payload_tkeep[i]) begin + if (s_udp_payload_axis_tkeep[i]) begin if (i & 1) begin - checksum_temp1_next = checksum_temp1_next + {8'h00, input_udp_payload_tdata[i*8 +: 8]}; + checksum_temp1_next = checksum_temp1_next + {8'h00, s_udp_payload_axis_tdata[i*8 +: 8]}; end else begin - checksum_temp1_next = checksum_temp1_next + {input_udp_payload_tdata[i*8 +: 8], 8'h00}; + checksum_temp1_next = checksum_temp1_next + {s_udp_payload_axis_tdata[i*8 +: 8], 8'h00}; end end end for (i = 4; i < 8; i = i + 1) begin - if (input_udp_payload_tkeep[i]) begin + if (s_udp_payload_axis_tkeep[i]) begin if (i & 1) begin - checksum_temp2_next = checksum_temp2_next + {8'h00, input_udp_payload_tdata[i*8 +: 8]}; + checksum_temp2_next = checksum_temp2_next + {8'h00, s_udp_payload_axis_tdata[i*8 +: 8]}; end else begin - checksum_temp2_next = checksum_temp2_next + {input_udp_payload_tdata[i*8 +: 8], 8'h00}; + checksum_temp2_next = checksum_temp2_next + {s_udp_payload_axis_tdata[i*8 +: 8], 8'h00}; end end end @@ -520,7 +520,7 @@ always @* begin frame_ptr_next = frame_ptr_reg + word_cnt; - if (input_udp_payload_tlast) begin + if (s_udp_payload_axis_tlast) begin state_next = STATE_FINISH_SUM_1; end else begin state_next = STATE_SUM_PAYLOAD; @@ -547,15 +547,15 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - input_udp_hdr_ready_reg <= 1'b0; - input_udp_payload_tready_reg <= 1'b0; + s_udp_hdr_ready_reg <= 1'b0; + s_udp_payload_axis_tready_reg <= 1'b0; hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; end else begin state_reg <= state_next; - input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; - input_udp_payload_tready_reg <= input_udp_payload_tready_next; + s_udp_hdr_ready_reg <= s_udp_hdr_ready_next; + s_udp_payload_axis_tready_reg <= s_udp_payload_axis_tready_next; hdr_valid_reg <= hdr_valid_next; @@ -569,22 +569,22 @@ always @(posedge clk) begin // datapath if (store_udp_hdr) begin - eth_dest_mac_reg <= input_eth_dest_mac; - eth_src_mac_reg <= input_eth_src_mac; - eth_type_reg <= input_eth_type; - ip_version_reg <= input_ip_version; - ip_ihl_reg <= input_ip_ihl; - ip_dscp_reg <= input_ip_dscp; - ip_ecn_reg <= input_ip_ecn; - ip_identification_reg <= input_ip_identification; - ip_flags_reg <= input_ip_flags; - ip_fragment_offset_reg <= input_ip_fragment_offset; - ip_ttl_reg <= input_ip_ttl; - ip_header_checksum_reg <= input_ip_header_checksum; - ip_source_ip_reg <= input_ip_source_ip; - ip_dest_ip_reg <= input_ip_dest_ip; - udp_source_port_reg <= input_udp_source_port; - udp_dest_port_reg <= input_udp_dest_port; + eth_dest_mac_reg <= s_eth_dest_mac; + eth_src_mac_reg <= s_eth_src_mac; + eth_type_reg <= s_eth_type; + ip_version_reg <= s_ip_version; + ip_ihl_reg <= s_ip_ihl; + ip_dscp_reg <= s_ip_dscp; + ip_ecn_reg <= s_ip_ecn; + ip_identification_reg <= s_ip_identification; + ip_flags_reg <= s_ip_flags; + ip_fragment_offset_reg <= s_ip_fragment_offset; + ip_ttl_reg <= s_ip_ttl; + ip_header_checksum_reg <= s_ip_header_checksum; + ip_source_ip_reg <= s_ip_source_ip; + ip_dest_ip_reg <= s_ip_dest_ip; + udp_source_port_reg <= s_udp_source_port; + udp_dest_port_reg <= s_udp_dest_port; end end diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v index 497a4a5d3..3ff5816cf 100644 --- a/rtl/udp_complete.v +++ b/rtl/udp_complete.v @@ -45,126 +45,126 @@ module udp_complete #( /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [7:0] input_eth_payload_tdata, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [7:0] s_eth_payload_axis_tdata, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [7:0] output_eth_payload_tdata, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [7:0] m_eth_payload_axis_tdata, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * IP input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [7:0] input_ip_payload_tdata, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [7:0] s_ip_payload_axis_tdata, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * IP output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_ip_eth_dest_mac, - output wire [47:0] output_ip_eth_src_mac, - output wire [15:0] output_ip_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_ip_eth_dest_mac, + output wire [47:0] m_ip_eth_src_mac, + output wire [15:0] m_ip_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [7:0] m_ip_payload_axis_tdata, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * UDP input */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [5:0] input_udp_ip_dscp, - input wire [1:0] input_udp_ip_ecn, - input wire [7:0] input_udp_ip_ttl, - input wire [31:0] input_udp_ip_source_ip, - input wire [31:0] input_udp_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [15:0] input_udp_length, - input wire [15:0] input_udp_checksum, - input wire [7:0] input_udp_payload_tdata, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, + input wire s_udp_hdr_valid, + output wire s_udp_hdr_ready, + input wire [5:0] s_udp_ip_dscp, + input wire [1:0] s_udp_ip_ecn, + input wire [7:0] s_udp_ip_ttl, + input wire [31:0] s_udp_ip_source_ip, + input wire [31:0] s_udp_ip_dest_ip, + input wire [15:0] s_udp_source_port, + input wire [15:0] s_udp_dest_port, + input wire [15:0] s_udp_length, + input wire [15:0] s_udp_checksum, + input wire [7:0] s_udp_payload_axis_tdata, + input wire s_udp_payload_axis_tvalid, + output wire s_udp_payload_axis_tready, + input wire s_udp_payload_axis_tlast, + input wire s_udp_payload_axis_tuser, /* * UDP output */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_udp_eth_dest_mac, - output wire [47:0] output_udp_eth_src_mac, - output wire [15:0] output_udp_eth_type, - output wire [3:0] output_udp_ip_version, - output wire [3:0] output_udp_ip_ihl, - output wire [5:0] output_udp_ip_dscp, - output wire [1:0] output_udp_ip_ecn, - output wire [15:0] output_udp_ip_length, - output wire [15:0] output_udp_ip_identification, - output wire [2:0] output_udp_ip_flags, - output wire [12:0] output_udp_ip_fragment_offset, - output wire [7:0] output_udp_ip_ttl, - output wire [7:0] output_udp_ip_protocol, - output wire [15:0] output_udp_ip_header_checksum, - output wire [31:0] output_udp_ip_source_ip, - output wire [31:0] output_udp_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [7:0] output_udp_payload_tdata, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, + output wire m_udp_hdr_valid, + input wire m_udp_hdr_ready, + output wire [47:0] m_udp_eth_dest_mac, + output wire [47:0] m_udp_eth_src_mac, + output wire [15:0] m_udp_eth_type, + output wire [3:0] m_udp_ip_version, + output wire [3:0] m_udp_ip_ihl, + output wire [5:0] m_udp_ip_dscp, + output wire [1:0] m_udp_ip_ecn, + output wire [15:0] m_udp_ip_length, + output wire [15:0] m_udp_ip_identification, + output wire [2:0] m_udp_ip_flags, + output wire [12:0] m_udp_ip_fragment_offset, + output wire [7:0] m_udp_ip_ttl, + output wire [7:0] m_udp_ip_protocol, + output wire [15:0] m_udp_ip_header_checksum, + output wire [31:0] m_udp_ip_source_ip, + output wire [31:0] m_udp_ip_dest_ip, + output wire [15:0] m_udp_source_port, + output wire [15:0] m_udp_dest_port, + output wire [15:0] m_udp_length, + output wire [15:0] m_udp_checksum, + output wire [7:0] m_udp_payload_axis_tdata, + output wire m_udp_payload_axis_tvalid, + input wire m_udp_payload_axis_tready, + output wire m_udp_payload_axis_tlast, + output wire m_udp_payload_axis_tuser, /* * Status @@ -211,11 +211,11 @@ wire [7:0] ip_rx_ip_protocol; wire [15:0] ip_rx_ip_header_checksum; wire [31:0] ip_rx_ip_source_ip; wire [31:0] ip_rx_ip_dest_ip; -wire [7:0] ip_rx_ip_payload_tdata; -wire ip_rx_ip_payload_tvalid; -wire ip_rx_ip_payload_tlast; -wire ip_rx_ip_payload_tuser; -wire ip_rx_ip_payload_tready; +wire [7:0] ip_rx_ip_payload_axis_tdata; +wire ip_rx_ip_payload_axis_tvalid; +wire ip_rx_ip_payload_axis_tlast; +wire ip_rx_ip_payload_axis_tuser; +wire ip_rx_ip_payload_axis_tready; wire ip_tx_ip_hdr_valid; wire ip_tx_ip_hdr_ready; @@ -226,11 +226,11 @@ wire [7:0] ip_tx_ip_ttl; wire [7:0] ip_tx_ip_protocol; wire [31:0] ip_tx_ip_source_ip; wire [31:0] ip_tx_ip_dest_ip; -wire [7:0] ip_tx_ip_payload_tdata; -wire ip_tx_ip_payload_tvalid; -wire ip_tx_ip_payload_tlast; -wire ip_tx_ip_payload_tuser; -wire ip_tx_ip_payload_tready; +wire [7:0] ip_tx_ip_payload_axis_tdata; +wire ip_tx_ip_payload_axis_tvalid; +wire ip_tx_ip_payload_axis_tlast; +wire ip_tx_ip_payload_axis_tuser; +wire ip_tx_ip_payload_axis_tready; wire udp_rx_ip_hdr_valid; wire udp_rx_ip_hdr_ready; @@ -250,11 +250,11 @@ wire [7:0] udp_rx_ip_protocol; wire [15:0] udp_rx_ip_header_checksum; wire [31:0] udp_rx_ip_source_ip; wire [31:0] udp_rx_ip_dest_ip; -wire [7:0] udp_rx_ip_payload_tdata; -wire udp_rx_ip_payload_tvalid; -wire udp_rx_ip_payload_tlast; -wire udp_rx_ip_payload_tuser; -wire udp_rx_ip_payload_tready; +wire [7:0] udp_rx_ip_payload_axis_tdata; +wire udp_rx_ip_payload_axis_tvalid; +wire udp_rx_ip_payload_axis_tlast; +wire udp_rx_ip_payload_axis_tuser; +wire udp_rx_ip_payload_axis_tready; wire udp_tx_ip_hdr_valid; wire udp_tx_ip_hdr_ready; @@ -265,41 +265,41 @@ wire [7:0] udp_tx_ip_ttl; wire [7:0] udp_tx_ip_protocol; wire [31:0] udp_tx_ip_source_ip; wire [31:0] udp_tx_ip_dest_ip; -wire [7:0] udp_tx_ip_payload_tdata; -wire udp_tx_ip_payload_tvalid; -wire udp_tx_ip_payload_tlast; -wire udp_tx_ip_payload_tuser; -wire udp_tx_ip_payload_tready; +wire [7:0] udp_tx_ip_payload_axis_tdata; +wire udp_tx_ip_payload_axis_tvalid; +wire udp_tx_ip_payload_axis_tlast; +wire udp_tx_ip_payload_axis_tuser; +wire udp_tx_ip_payload_axis_tready; /* * Input classifier (ip_protocol) */ -wire input_select_udp = (ip_rx_ip_protocol == 8'h11); -wire input_select_ip = ~input_select_udp; +wire s_select_udp = (ip_rx_ip_protocol == 8'h11); +wire s_select_ip = !s_select_udp; -reg input_select_udp_reg = 1'b0; -reg input_select_ip_reg = 1'b0; +reg s_select_udp_reg = 1'b0; +reg s_select_ip_reg = 1'b0; always @(posedge clk) begin if (rst) begin - input_select_udp_reg <= 1'b0; - input_select_ip_reg <= 1'b0; + s_select_udp_reg <= 1'b0; + s_select_ip_reg <= 1'b0; end else begin - if (ip_rx_ip_payload_tvalid) begin - if ((~input_select_udp_reg & ~input_select_ip_reg) | - (ip_rx_ip_payload_tvalid & ip_rx_ip_payload_tready & ip_rx_ip_payload_tlast)) begin - input_select_udp_reg <= input_select_udp; - input_select_ip_reg <= input_select_ip; + if (ip_rx_ip_payload_axis_tvalid) begin + if ((!s_select_udp_reg && !s_select_ip_reg) || + (ip_rx_ip_payload_axis_tvalid && ip_rx_ip_payload_axis_tready && ip_rx_ip_payload_axis_tlast)) begin + s_select_udp_reg <= s_select_udp; + s_select_ip_reg <= s_select_ip; end end else begin - input_select_udp_reg <= 1'b0; - input_select_ip_reg <= 1'b0; + s_select_udp_reg <= 1'b0; + s_select_ip_reg <= 1'b0; end end end // IP frame to UDP module -assign udp_rx_ip_hdr_valid = input_select_udp & ip_rx_ip_hdr_valid; +assign udp_rx_ip_hdr_valid = s_select_udp && ip_rx_ip_hdr_valid; assign udp_rx_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; assign udp_rx_ip_eth_src_mac = ip_rx_ip_eth_src_mac; assign udp_rx_ip_eth_type = ip_rx_ip_eth_type; @@ -316,39 +316,39 @@ assign udp_rx_ip_protocol = 8'h11; assign udp_rx_ip_header_checksum = ip_rx_ip_header_checksum; assign udp_rx_ip_source_ip = ip_rx_ip_source_ip; assign udp_rx_ip_dest_ip = ip_rx_ip_dest_ip; -assign udp_rx_ip_payload_tdata = ip_rx_ip_payload_tdata; -assign udp_rx_ip_payload_tvalid = input_select_udp_reg & ip_rx_ip_payload_tvalid; -assign udp_rx_ip_payload_tlast = ip_rx_ip_payload_tlast; -assign udp_rx_ip_payload_tuser = ip_rx_ip_payload_tuser; +assign udp_rx_ip_payload_axis_tdata = ip_rx_ip_payload_axis_tdata; +assign udp_rx_ip_payload_axis_tvalid = s_select_udp_reg && ip_rx_ip_payload_axis_tvalid; +assign udp_rx_ip_payload_axis_tlast = ip_rx_ip_payload_axis_tlast; +assign udp_rx_ip_payload_axis_tuser = ip_rx_ip_payload_axis_tuser; // External IP frame output -assign output_ip_hdr_valid = input_select_ip & ip_rx_ip_hdr_valid; -assign output_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; -assign output_ip_eth_src_mac = ip_rx_ip_eth_src_mac; -assign output_ip_eth_type = ip_rx_ip_eth_type; -assign output_ip_version = ip_rx_ip_version; -assign output_ip_ihl = ip_rx_ip_ihl; -assign output_ip_dscp = ip_rx_ip_dscp; -assign output_ip_ecn = ip_rx_ip_ecn; -assign output_ip_length = ip_rx_ip_length; -assign output_ip_identification = ip_rx_ip_identification; -assign output_ip_flags = ip_rx_ip_flags; -assign output_ip_fragment_offset = ip_rx_ip_fragment_offset; -assign output_ip_ttl = ip_rx_ip_ttl; -assign output_ip_protocol = ip_rx_ip_protocol; -assign output_ip_header_checksum = ip_rx_ip_header_checksum; -assign output_ip_source_ip = ip_rx_ip_source_ip; -assign output_ip_dest_ip = ip_rx_ip_dest_ip; -assign output_ip_payload_tdata = ip_rx_ip_payload_tdata; -assign output_ip_payload_tvalid = input_select_ip_reg & ip_rx_ip_payload_tvalid; -assign output_ip_payload_tlast = ip_rx_ip_payload_tlast; -assign output_ip_payload_tuser = ip_rx_ip_payload_tuser; +assign m_ip_hdr_valid = s_select_ip && ip_rx_ip_hdr_valid; +assign m_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; +assign m_ip_eth_src_mac = ip_rx_ip_eth_src_mac; +assign m_ip_eth_type = ip_rx_ip_eth_type; +assign m_ip_version = ip_rx_ip_version; +assign m_ip_ihl = ip_rx_ip_ihl; +assign m_ip_dscp = ip_rx_ip_dscp; +assign m_ip_ecn = ip_rx_ip_ecn; +assign m_ip_length = ip_rx_ip_length; +assign m_ip_identification = ip_rx_ip_identification; +assign m_ip_flags = ip_rx_ip_flags; +assign m_ip_fragment_offset = ip_rx_ip_fragment_offset; +assign m_ip_ttl = ip_rx_ip_ttl; +assign m_ip_protocol = ip_rx_ip_protocol; +assign m_ip_header_checksum = ip_rx_ip_header_checksum; +assign m_ip_source_ip = ip_rx_ip_source_ip; +assign m_ip_dest_ip = ip_rx_ip_dest_ip; +assign m_ip_payload_axis_tdata = ip_rx_ip_payload_axis_tdata; +assign m_ip_payload_axis_tvalid = s_select_ip_reg && ip_rx_ip_payload_axis_tvalid; +assign m_ip_payload_axis_tlast = ip_rx_ip_payload_axis_tlast; +assign m_ip_payload_axis_tuser = ip_rx_ip_payload_axis_tuser; -assign ip_rx_ip_hdr_ready = (input_select_udp & udp_rx_ip_hdr_ready) | - (input_select_ip & output_ip_hdr_ready); +assign ip_rx_ip_hdr_ready = (s_select_udp && udp_rx_ip_hdr_ready) || + (s_select_ip && m_ip_hdr_ready); -assign ip_rx_ip_payload_tready = (input_select_udp_reg & udp_rx_ip_payload_tready) | - (input_select_ip_reg & output_ip_payload_tready); +assign ip_rx_ip_payload_axis_tready = (s_select_udp_reg && udp_rx_ip_payload_axis_tready) || + (s_select_ip_reg && m_ip_payload_axis_tready); /* * Output arbiter @@ -368,32 +368,32 @@ ip_arb_mux_inst ( .clk(clk), .rst(rst), // IP frame inputs - .s_ip_hdr_valid({input_ip_hdr_valid, udp_tx_ip_hdr_valid}), - .s_ip_hdr_ready({input_ip_hdr_ready, udp_tx_ip_hdr_ready}), + .s_ip_hdr_valid({s_ip_hdr_valid, udp_tx_ip_hdr_valid}), + .s_ip_hdr_ready({s_ip_hdr_ready, udp_tx_ip_hdr_ready}), .s_eth_dest_mac(0), .s_eth_src_mac(0), .s_eth_type(0), .s_ip_version(0), .s_ip_ihl(0), - .s_ip_dscp({input_ip_dscp, udp_tx_ip_dscp}), - .s_ip_ecn({input_ip_ecn, udp_tx_ip_ecn}), - .s_ip_length({input_ip_length, udp_tx_ip_length}), + .s_ip_dscp({s_ip_dscp, udp_tx_ip_dscp}), + .s_ip_ecn({s_ip_ecn, udp_tx_ip_ecn}), + .s_ip_length({s_ip_length, udp_tx_ip_length}), .s_ip_identification(0), .s_ip_flags(0), .s_ip_fragment_offset(0), - .s_ip_ttl({input_ip_ttl, udp_tx_ip_ttl}), - .s_ip_protocol({input_ip_protocol, udp_tx_ip_protocol}), + .s_ip_ttl({s_ip_ttl, udp_tx_ip_ttl}), + .s_ip_protocol({s_ip_protocol, udp_tx_ip_protocol}), .s_ip_header_checksum(0), - .s_ip_source_ip({input_ip_source_ip, udp_tx_ip_source_ip}), - .s_ip_dest_ip({input_ip_dest_ip, udp_tx_ip_dest_ip}), - .s_ip_payload_axis_tdata({input_ip_payload_tdata, udp_tx_ip_payload_tdata}), + .s_ip_source_ip({s_ip_source_ip, udp_tx_ip_source_ip}), + .s_ip_dest_ip({s_ip_dest_ip, udp_tx_ip_dest_ip}), + .s_ip_payload_axis_tdata({s_ip_payload_axis_tdata, udp_tx_ip_payload_axis_tdata}), .s_ip_payload_axis_tkeep(0), - .s_ip_payload_axis_tvalid({input_ip_payload_tvalid, udp_tx_ip_payload_tvalid}), - .s_ip_payload_axis_tready({input_ip_payload_tready, udp_tx_ip_payload_tready}), - .s_ip_payload_axis_tlast({input_ip_payload_tlast, udp_tx_ip_payload_tlast}), + .s_ip_payload_axis_tvalid({s_ip_payload_axis_tvalid, udp_tx_ip_payload_axis_tvalid}), + .s_ip_payload_axis_tready({s_ip_payload_axis_tready, udp_tx_ip_payload_axis_tready}), + .s_ip_payload_axis_tlast({s_ip_payload_axis_tlast, udp_tx_ip_payload_axis_tlast}), .s_ip_payload_axis_tid(0), .s_ip_payload_axis_tdest(0), - .s_ip_payload_axis_tuser({input_ip_payload_tuser, udp_tx_ip_payload_tuser}), + .s_ip_payload_axis_tuser({s_ip_payload_axis_tuser, udp_tx_ip_payload_axis_tuser}), // IP frame output .m_ip_hdr_valid(ip_tx_ip_hdr_valid), .m_ip_hdr_ready(ip_tx_ip_hdr_ready), @@ -413,14 +413,14 @@ ip_arb_mux_inst ( .m_ip_header_checksum(), .m_ip_source_ip(ip_tx_ip_source_ip), .m_ip_dest_ip(ip_tx_ip_dest_ip), - .m_ip_payload_axis_tdata(ip_tx_ip_payload_tdata), + .m_ip_payload_axis_tdata(ip_tx_ip_payload_axis_tdata), .m_ip_payload_axis_tkeep(), - .m_ip_payload_axis_tvalid(ip_tx_ip_payload_tvalid), - .m_ip_payload_axis_tready(ip_tx_ip_payload_tready), - .m_ip_payload_axis_tlast(ip_tx_ip_payload_tlast), + .m_ip_payload_axis_tvalid(ip_tx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(ip_tx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(ip_tx_ip_payload_axis_tlast), .m_ip_payload_axis_tid(), .m_ip_payload_axis_tdest(), - .m_ip_payload_axis_tuser(ip_tx_ip_payload_tuser) + .m_ip_payload_axis_tuser(ip_tx_ip_payload_axis_tuser) ); /* @@ -436,66 +436,66 @@ ip_complete_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(ip_tx_ip_hdr_valid), - .input_ip_hdr_ready(ip_tx_ip_hdr_ready), - .input_ip_dscp(ip_tx_ip_dscp), - .input_ip_ecn(ip_tx_ip_ecn), - .input_ip_length(ip_tx_ip_length), - .input_ip_ttl(ip_tx_ip_ttl), - .input_ip_protocol(ip_tx_ip_protocol), - .input_ip_source_ip(ip_tx_ip_source_ip), - .input_ip_dest_ip(ip_tx_ip_dest_ip), - .input_ip_payload_tdata(ip_tx_ip_payload_tdata), - .input_ip_payload_tvalid(ip_tx_ip_payload_tvalid), - .input_ip_payload_tready(ip_tx_ip_payload_tready), - .input_ip_payload_tlast(ip_tx_ip_payload_tlast), - .input_ip_payload_tuser(ip_tx_ip_payload_tuser), + .s_ip_hdr_valid(ip_tx_ip_hdr_valid), + .s_ip_hdr_ready(ip_tx_ip_hdr_ready), + .s_ip_dscp(ip_tx_ip_dscp), + .s_ip_ecn(ip_tx_ip_ecn), + .s_ip_length(ip_tx_ip_length), + .s_ip_ttl(ip_tx_ip_ttl), + .s_ip_protocol(ip_tx_ip_protocol), + .s_ip_source_ip(ip_tx_ip_source_ip), + .s_ip_dest_ip(ip_tx_ip_dest_ip), + .s_ip_payload_axis_tdata(ip_tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(ip_tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(ip_tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(ip_tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(ip_tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(ip_rx_ip_hdr_valid), - .output_ip_hdr_ready(ip_rx_ip_hdr_ready), - .output_ip_eth_dest_mac(ip_rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(ip_rx_ip_eth_src_mac), - .output_ip_eth_type(ip_rx_ip_eth_type), - .output_ip_version(ip_rx_ip_version), - .output_ip_ihl(ip_rx_ip_ihl), - .output_ip_dscp(ip_rx_ip_dscp), - .output_ip_ecn(ip_rx_ip_ecn), - .output_ip_length(ip_rx_ip_length), - .output_ip_identification(ip_rx_ip_identification), - .output_ip_flags(ip_rx_ip_flags), - .output_ip_fragment_offset(ip_rx_ip_fragment_offset), - .output_ip_ttl(ip_rx_ip_ttl), - .output_ip_protocol(ip_rx_ip_protocol), - .output_ip_header_checksum(ip_rx_ip_header_checksum), - .output_ip_source_ip(ip_rx_ip_source_ip), - .output_ip_dest_ip(ip_rx_ip_dest_ip), - .output_ip_payload_tdata(ip_rx_ip_payload_tdata), - .output_ip_payload_tvalid(ip_rx_ip_payload_tvalid), - .output_ip_payload_tready(ip_rx_ip_payload_tready), - .output_ip_payload_tlast(ip_rx_ip_payload_tlast), - .output_ip_payload_tuser(ip_rx_ip_payload_tuser), + .m_ip_hdr_valid(ip_rx_ip_hdr_valid), + .m_ip_hdr_ready(ip_rx_ip_hdr_ready), + .m_ip_eth_dest_mac(ip_rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(ip_rx_ip_eth_src_mac), + .m_ip_eth_type(ip_rx_ip_eth_type), + .m_ip_version(ip_rx_ip_version), + .m_ip_ihl(ip_rx_ip_ihl), + .m_ip_dscp(ip_rx_ip_dscp), + .m_ip_ecn(ip_rx_ip_ecn), + .m_ip_length(ip_rx_ip_length), + .m_ip_identification(ip_rx_ip_identification), + .m_ip_flags(ip_rx_ip_flags), + .m_ip_fragment_offset(ip_rx_ip_fragment_offset), + .m_ip_ttl(ip_rx_ip_ttl), + .m_ip_protocol(ip_rx_ip_protocol), + .m_ip_header_checksum(ip_rx_ip_header_checksum), + .m_ip_source_ip(ip_rx_ip_source_ip), + .m_ip_dest_ip(ip_rx_ip_dest_ip), + .m_ip_payload_axis_tdata(ip_rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(ip_rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(ip_rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(ip_rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(ip_rx_ip_payload_axis_tuser), // Status .rx_busy(ip_rx_busy), .tx_busy(ip_tx_busy), @@ -525,107 +525,107 @@ udp_inst ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(udp_rx_ip_hdr_valid), - .input_ip_hdr_ready(udp_rx_ip_hdr_ready), - .input_ip_eth_dest_mac(udp_rx_ip_eth_dest_mac), - .input_ip_eth_src_mac(udp_rx_ip_eth_src_mac), - .input_ip_eth_type(udp_rx_ip_eth_type), - .input_ip_version(udp_rx_ip_version), - .input_ip_ihl(udp_rx_ip_ihl), - .input_ip_dscp(udp_rx_ip_dscp), - .input_ip_ecn(udp_rx_ip_ecn), - .input_ip_length(udp_rx_ip_length), - .input_ip_identification(udp_rx_ip_identification), - .input_ip_flags(udp_rx_ip_flags), - .input_ip_fragment_offset(udp_rx_ip_fragment_offset), - .input_ip_ttl(udp_rx_ip_ttl), - .input_ip_protocol(udp_rx_ip_protocol), - .input_ip_header_checksum(udp_rx_ip_header_checksum), - .input_ip_source_ip(udp_rx_ip_source_ip), - .input_ip_dest_ip(udp_rx_ip_dest_ip), - .input_ip_payload_tdata(udp_rx_ip_payload_tdata), - .input_ip_payload_tvalid(udp_rx_ip_payload_tvalid), - .input_ip_payload_tready(udp_rx_ip_payload_tready), - .input_ip_payload_tlast(udp_rx_ip_payload_tlast), - .input_ip_payload_tuser(udp_rx_ip_payload_tuser), + .s_ip_hdr_valid(udp_rx_ip_hdr_valid), + .s_ip_hdr_ready(udp_rx_ip_hdr_ready), + .s_ip_eth_dest_mac(udp_rx_ip_eth_dest_mac), + .s_ip_eth_src_mac(udp_rx_ip_eth_src_mac), + .s_ip_eth_type(udp_rx_ip_eth_type), + .s_ip_version(udp_rx_ip_version), + .s_ip_ihl(udp_rx_ip_ihl), + .s_ip_dscp(udp_rx_ip_dscp), + .s_ip_ecn(udp_rx_ip_ecn), + .s_ip_length(udp_rx_ip_length), + .s_ip_identification(udp_rx_ip_identification), + .s_ip_flags(udp_rx_ip_flags), + .s_ip_fragment_offset(udp_rx_ip_fragment_offset), + .s_ip_ttl(udp_rx_ip_ttl), + .s_ip_protocol(udp_rx_ip_protocol), + .s_ip_header_checksum(udp_rx_ip_header_checksum), + .s_ip_source_ip(udp_rx_ip_source_ip), + .s_ip_dest_ip(udp_rx_ip_dest_ip), + .s_ip_payload_axis_tdata(udp_rx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(udp_rx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(udp_rx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(udp_rx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(udp_rx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(udp_tx_ip_hdr_valid), - .output_ip_hdr_ready(udp_tx_ip_hdr_ready), - .output_ip_eth_dest_mac(), - .output_ip_eth_src_mac(), - .output_ip_eth_type(), - .output_ip_version(), - .output_ip_ihl(), - .output_ip_dscp(udp_tx_ip_dscp), - .output_ip_ecn(udp_tx_ip_ecn), - .output_ip_length(udp_tx_ip_length), - .output_ip_identification(), - .output_ip_flags(), - .output_ip_fragment_offset(), - .output_ip_ttl(udp_tx_ip_ttl), - .output_ip_protocol(udp_tx_ip_protocol), - .output_ip_header_checksum(), - .output_ip_source_ip(udp_tx_ip_source_ip), - .output_ip_dest_ip(udp_tx_ip_dest_ip), - .output_ip_payload_tdata(udp_tx_ip_payload_tdata), - .output_ip_payload_tvalid(udp_tx_ip_payload_tvalid), - .output_ip_payload_tready(udp_tx_ip_payload_tready), - .output_ip_payload_tlast(udp_tx_ip_payload_tlast), - .output_ip_payload_tuser(udp_tx_ip_payload_tuser), + .m_ip_hdr_valid(udp_tx_ip_hdr_valid), + .m_ip_hdr_ready(udp_tx_ip_hdr_ready), + .m_ip_eth_dest_mac(), + .m_ip_eth_src_mac(), + .m_ip_eth_type(), + .m_ip_version(), + .m_ip_ihl(), + .m_ip_dscp(udp_tx_ip_dscp), + .m_ip_ecn(udp_tx_ip_ecn), + .m_ip_length(udp_tx_ip_length), + .m_ip_identification(), + .m_ip_flags(), + .m_ip_fragment_offset(), + .m_ip_ttl(udp_tx_ip_ttl), + .m_ip_protocol(udp_tx_ip_protocol), + .m_ip_header_checksum(), + .m_ip_source_ip(udp_tx_ip_source_ip), + .m_ip_dest_ip(udp_tx_ip_dest_ip), + .m_ip_payload_axis_tdata(udp_tx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(udp_tx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(udp_tx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(udp_tx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(udp_tx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_udp_eth_dest_mac(48'd0), - .input_udp_eth_src_mac(48'd0), - .input_udp_eth_type(16'd0), - .input_udp_ip_version(4'd0), - .input_udp_ip_ihl(4'd0), - .input_udp_ip_dscp(input_udp_ip_dscp), - .input_udp_ip_ecn(input_udp_ip_ecn), - .input_udp_ip_identification(16'd0), - .input_udp_ip_flags(3'd0), - .input_udp_ip_fragment_offset(13'd0), - .input_udp_ip_ttl(input_udp_ip_ttl), - .input_udp_ip_header_checksum(16'd0), - .input_udp_ip_source_ip(input_udp_ip_source_ip), - .input_udp_ip_dest_ip(input_udp_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), - .input_udp_checksum(input_udp_checksum), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_udp_eth_dest_mac(48'd0), + .s_udp_eth_src_mac(48'd0), + .s_udp_eth_type(16'd0), + .s_udp_ip_version(4'd0), + .s_udp_ip_ihl(4'd0), + .s_udp_ip_dscp(s_udp_ip_dscp), + .s_udp_ip_ecn(s_udp_ip_ecn), + .s_udp_ip_identification(16'd0), + .s_udp_ip_flags(3'd0), + .s_udp_ip_fragment_offset(13'd0), + .s_udp_ip_ttl(s_udp_ip_ttl), + .s_udp_ip_header_checksum(16'd0), + .s_udp_ip_source_ip(s_udp_ip_source_ip), + .s_udp_ip_dest_ip(s_udp_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_udp_eth_dest_mac(output_udp_eth_dest_mac), - .output_udp_eth_src_mac(output_udp_eth_src_mac), - .output_udp_eth_type(output_udp_eth_type), - .output_udp_ip_version(output_udp_ip_version), - .output_udp_ip_ihl(output_udp_ip_ihl), - .output_udp_ip_dscp(output_udp_ip_dscp), - .output_udp_ip_ecn(output_udp_ip_ecn), - .output_udp_ip_length(output_udp_ip_length), - .output_udp_ip_identification(output_udp_ip_identification), - .output_udp_ip_flags(output_udp_ip_flags), - .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), - .output_udp_ip_ttl(output_udp_ip_ttl), - .output_udp_ip_protocol(output_udp_ip_protocol), - .output_udp_ip_header_checksum(output_udp_ip_header_checksum), - .output_udp_ip_source_ip(output_udp_ip_source_ip), - .output_udp_ip_dest_ip(output_udp_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_udp_eth_dest_mac(m_udp_eth_dest_mac), + .m_udp_eth_src_mac(m_udp_eth_src_mac), + .m_udp_eth_type(m_udp_eth_type), + .m_udp_ip_version(m_udp_ip_version), + .m_udp_ip_ihl(m_udp_ip_ihl), + .m_udp_ip_dscp(m_udp_ip_dscp), + .m_udp_ip_ecn(m_udp_ip_ecn), + .m_udp_ip_length(m_udp_ip_length), + .m_udp_ip_identification(m_udp_ip_identification), + .m_udp_ip_flags(m_udp_ip_flags), + .m_udp_ip_fragment_offset(m_udp_ip_fragment_offset), + .m_udp_ip_ttl(m_udp_ip_ttl), + .m_udp_ip_protocol(m_udp_ip_protocol), + .m_udp_ip_header_checksum(m_udp_ip_header_checksum), + .m_udp_ip_source_ip(m_udp_ip_source_ip), + .m_udp_ip_dest_ip(m_udp_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Status .rx_busy(udp_rx_busy), .tx_busy(udp_tx_busy), diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v index 8cbd26cc0..c31e225a1 100644 --- a/rtl/udp_complete_64.v +++ b/rtl/udp_complete_64.v @@ -45,132 +45,132 @@ module udp_complete_64 #( /* * Ethernet frame input */ - input wire input_eth_hdr_valid, - output wire input_eth_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [63:0] input_eth_payload_tdata, - input wire [7:0] input_eth_payload_tkeep, - input wire input_eth_payload_tvalid, - output wire input_eth_payload_tready, - input wire input_eth_payload_tlast, - input wire input_eth_payload_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [63:0] s_eth_payload_axis_tdata, + input wire [7:0] s_eth_payload_axis_tkeep, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * Ethernet frame output */ - output wire output_eth_hdr_valid, - input wire output_eth_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [63:0] output_eth_payload_tdata, - output wire [7:0] output_eth_payload_tkeep, - output wire output_eth_payload_tvalid, - input wire output_eth_payload_tready, - output wire output_eth_payload_tlast, - output wire output_eth_payload_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [63:0] m_eth_payload_axis_tdata, + output wire [7:0] m_eth_payload_axis_tkeep, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * IP input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [63:0] input_ip_payload_tdata, - input wire [7:0] input_ip_payload_tkeep, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [63:0] s_ip_payload_axis_tdata, + input wire [7:0] s_ip_payload_axis_tkeep, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * IP output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_ip_eth_dest_mac, - output wire [47:0] output_ip_eth_src_mac, - output wire [15:0] output_ip_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_ip_eth_dest_mac, + output wire [47:0] m_ip_eth_src_mac, + output wire [15:0] m_ip_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [63:0] m_ip_payload_axis_tdata, + output wire [7:0] m_ip_payload_axis_tkeep, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * UDP input */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [5:0] input_udp_ip_dscp, - input wire [1:0] input_udp_ip_ecn, - input wire [7:0] input_udp_ip_ttl, - input wire [31:0] input_udp_ip_source_ip, - input wire [31:0] input_udp_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [15:0] input_udp_length, - input wire [15:0] input_udp_checksum, - input wire [63:0] input_udp_payload_tdata, - input wire [7:0] input_udp_payload_tkeep, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, + input wire s_udp_hdr_valid, + output wire s_udp_hdr_ready, + input wire [5:0] s_udp_ip_dscp, + input wire [1:0] s_udp_ip_ecn, + input wire [7:0] s_udp_ip_ttl, + input wire [31:0] s_udp_ip_source_ip, + input wire [31:0] s_udp_ip_dest_ip, + input wire [15:0] s_udp_source_port, + input wire [15:0] s_udp_dest_port, + input wire [15:0] s_udp_length, + input wire [15:0] s_udp_checksum, + input wire [63:0] s_udp_payload_axis_tdata, + input wire [7:0] s_udp_payload_axis_tkeep, + input wire s_udp_payload_axis_tvalid, + output wire s_udp_payload_axis_tready, + input wire s_udp_payload_axis_tlast, + input wire s_udp_payload_axis_tuser, /* * UDP output */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_udp_eth_dest_mac, - output wire [47:0] output_udp_eth_src_mac, - output wire [15:0] output_udp_eth_type, - output wire [3:0] output_udp_ip_version, - output wire [3:0] output_udp_ip_ihl, - output wire [5:0] output_udp_ip_dscp, - output wire [1:0] output_udp_ip_ecn, - output wire [15:0] output_udp_ip_length, - output wire [15:0] output_udp_ip_identification, - output wire [2:0] output_udp_ip_flags, - output wire [12:0] output_udp_ip_fragment_offset, - output wire [7:0] output_udp_ip_ttl, - output wire [7:0] output_udp_ip_protocol, - output wire [15:0] output_udp_ip_header_checksum, - output wire [31:0] output_udp_ip_source_ip, - output wire [31:0] output_udp_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [63:0] output_udp_payload_tdata, - output wire [7:0] output_udp_payload_tkeep, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, + output wire m_udp_hdr_valid, + input wire m_udp_hdr_ready, + output wire [47:0] m_udp_eth_dest_mac, + output wire [47:0] m_udp_eth_src_mac, + output wire [15:0] m_udp_eth_type, + output wire [3:0] m_udp_ip_version, + output wire [3:0] m_udp_ip_ihl, + output wire [5:0] m_udp_ip_dscp, + output wire [1:0] m_udp_ip_ecn, + output wire [15:0] m_udp_ip_length, + output wire [15:0] m_udp_ip_identification, + output wire [2:0] m_udp_ip_flags, + output wire [12:0] m_udp_ip_fragment_offset, + output wire [7:0] m_udp_ip_ttl, + output wire [7:0] m_udp_ip_protocol, + output wire [15:0] m_udp_ip_header_checksum, + output wire [31:0] m_udp_ip_source_ip, + output wire [31:0] m_udp_ip_dest_ip, + output wire [15:0] m_udp_source_port, + output wire [15:0] m_udp_dest_port, + output wire [15:0] m_udp_length, + output wire [15:0] m_udp_checksum, + output wire [63:0] m_udp_payload_axis_tdata, + output wire [7:0] m_udp_payload_axis_tkeep, + output wire m_udp_payload_axis_tvalid, + input wire m_udp_payload_axis_tready, + output wire m_udp_payload_axis_tlast, + output wire m_udp_payload_axis_tuser, /* * Status @@ -217,12 +217,12 @@ wire [7:0] ip_rx_ip_protocol; wire [15:0] ip_rx_ip_header_checksum; wire [31:0] ip_rx_ip_source_ip; wire [31:0] ip_rx_ip_dest_ip; -wire [63:0] ip_rx_ip_payload_tdata; -wire [7:0] ip_rx_ip_payload_tkeep; -wire ip_rx_ip_payload_tvalid; -wire ip_rx_ip_payload_tlast; -wire ip_rx_ip_payload_tuser; -wire ip_rx_ip_payload_tready; +wire [63:0] ip_rx_ip_payload_axis_tdata; +wire [7:0] ip_rx_ip_payload_axis_tkeep; +wire ip_rx_ip_payload_axis_tvalid; +wire ip_rx_ip_payload_axis_tlast; +wire ip_rx_ip_payload_axis_tuser; +wire ip_rx_ip_payload_axis_tready; wire ip_tx_ip_hdr_valid; wire ip_tx_ip_hdr_ready; @@ -233,12 +233,12 @@ wire [7:0] ip_tx_ip_ttl; wire [7:0] ip_tx_ip_protocol; wire [31:0] ip_tx_ip_source_ip; wire [31:0] ip_tx_ip_dest_ip; -wire [63:0] ip_tx_ip_payload_tdata; -wire [7:0] ip_tx_ip_payload_tkeep; -wire ip_tx_ip_payload_tvalid; -wire ip_tx_ip_payload_tlast; -wire ip_tx_ip_payload_tuser; -wire ip_tx_ip_payload_tready; +wire [63:0] ip_tx_ip_payload_axis_tdata; +wire [7:0] ip_tx_ip_payload_axis_tkeep; +wire ip_tx_ip_payload_axis_tvalid; +wire ip_tx_ip_payload_axis_tlast; +wire ip_tx_ip_payload_axis_tuser; +wire ip_tx_ip_payload_axis_tready; wire udp_rx_ip_hdr_valid; wire udp_rx_ip_hdr_ready; @@ -258,12 +258,12 @@ wire [7:0] udp_rx_ip_protocol; wire [15:0] udp_rx_ip_header_checksum; wire [31:0] udp_rx_ip_source_ip; wire [31:0] udp_rx_ip_dest_ip; -wire [63:0] udp_rx_ip_payload_tdata; -wire [7:0] udp_rx_ip_payload_tkeep; -wire udp_rx_ip_payload_tvalid; -wire udp_rx_ip_payload_tlast; -wire udp_rx_ip_payload_tuser; -wire udp_rx_ip_payload_tready; +wire [63:0] udp_rx_ip_payload_axis_tdata; +wire [7:0] udp_rx_ip_payload_axis_tkeep; +wire udp_rx_ip_payload_axis_tvalid; +wire udp_rx_ip_payload_axis_tlast; +wire udp_rx_ip_payload_axis_tuser; +wire udp_rx_ip_payload_axis_tready; wire udp_tx_ip_hdr_valid; wire udp_tx_ip_hdr_ready; @@ -274,42 +274,42 @@ wire [7:0] udp_tx_ip_ttl; wire [7:0] udp_tx_ip_protocol; wire [31:0] udp_tx_ip_source_ip; wire [31:0] udp_tx_ip_dest_ip; -wire [63:0] udp_tx_ip_payload_tdata; -wire [7:0] udp_tx_ip_payload_tkeep; -wire udp_tx_ip_payload_tvalid; -wire udp_tx_ip_payload_tlast; -wire udp_tx_ip_payload_tuser; -wire udp_tx_ip_payload_tready; +wire [63:0] udp_tx_ip_payload_axis_tdata; +wire [7:0] udp_tx_ip_payload_axis_tkeep; +wire udp_tx_ip_payload_axis_tvalid; +wire udp_tx_ip_payload_axis_tlast; +wire udp_tx_ip_payload_axis_tuser; +wire udp_tx_ip_payload_axis_tready; /* * Input classifier (ip_protocol) */ -wire input_select_udp = (ip_rx_ip_protocol == 8'h11); -wire input_select_ip = ~input_select_udp; +wire s_select_udp = (ip_rx_ip_protocol == 8'h11); +wire s_select_ip = !s_select_udp; -reg input_select_udp_reg = 1'b0; -reg input_select_ip_reg = 1'b0; +reg s_select_udp_reg = 1'b0; +reg s_select_ip_reg = 1'b0; always @(posedge clk) begin if (rst) begin - input_select_udp_reg <= 1'b0; - input_select_ip_reg <= 1'b0; + s_select_udp_reg <= 1'b0; + s_select_ip_reg <= 1'b0; end else begin - if (ip_rx_ip_payload_tvalid) begin - if ((~input_select_udp_reg & ~input_select_ip_reg) | - (ip_rx_ip_payload_tvalid & ip_rx_ip_payload_tready & ip_rx_ip_payload_tlast)) begin - input_select_udp_reg <= input_select_udp; - input_select_ip_reg <= input_select_ip; + if (ip_rx_ip_payload_axis_tvalid) begin + if ((!s_select_udp_reg && !s_select_ip_reg) || + (ip_rx_ip_payload_axis_tvalid && ip_rx_ip_payload_axis_tready && ip_rx_ip_payload_axis_tlast)) begin + s_select_udp_reg <= s_select_udp; + s_select_ip_reg <= s_select_ip; end end else begin - input_select_udp_reg <= 1'b0; - input_select_ip_reg <= 1'b0; + s_select_udp_reg <= 1'b0; + s_select_ip_reg <= 1'b0; end end end // IP frame to UDP module -assign udp_rx_ip_hdr_valid = input_select_udp & ip_rx_ip_hdr_valid; +assign udp_rx_ip_hdr_valid = s_select_udp && ip_rx_ip_hdr_valid; assign udp_rx_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; assign udp_rx_ip_eth_src_mac = ip_rx_ip_eth_src_mac; assign udp_rx_ip_eth_type = ip_rx_ip_eth_type; @@ -326,41 +326,41 @@ assign udp_rx_ip_protocol = 8'h11; assign udp_rx_ip_header_checksum = ip_rx_ip_header_checksum; assign udp_rx_ip_source_ip = ip_rx_ip_source_ip; assign udp_rx_ip_dest_ip = ip_rx_ip_dest_ip; -assign udp_rx_ip_payload_tdata = ip_rx_ip_payload_tdata; -assign udp_rx_ip_payload_tkeep = ip_rx_ip_payload_tkeep; -assign udp_rx_ip_payload_tvalid = input_select_udp_reg & ip_rx_ip_payload_tvalid; -assign udp_rx_ip_payload_tlast = ip_rx_ip_payload_tlast; -assign udp_rx_ip_payload_tuser = ip_rx_ip_payload_tuser; +assign udp_rx_ip_payload_axis_tdata = ip_rx_ip_payload_axis_tdata; +assign udp_rx_ip_payload_axis_tkeep = ip_rx_ip_payload_axis_tkeep; +assign udp_rx_ip_payload_axis_tvalid = s_select_udp_reg && ip_rx_ip_payload_axis_tvalid; +assign udp_rx_ip_payload_axis_tlast = ip_rx_ip_payload_axis_tlast; +assign udp_rx_ip_payload_axis_tuser = ip_rx_ip_payload_axis_tuser; // External IP frame output -assign output_ip_hdr_valid = input_select_ip & ip_rx_ip_hdr_valid; -assign output_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; -assign output_ip_eth_src_mac = ip_rx_ip_eth_src_mac; -assign output_ip_eth_type = ip_rx_ip_eth_type; -assign output_ip_version = ip_rx_ip_version; -assign output_ip_ihl = ip_rx_ip_ihl; -assign output_ip_dscp = ip_rx_ip_dscp; -assign output_ip_ecn = ip_rx_ip_ecn; -assign output_ip_length = ip_rx_ip_length; -assign output_ip_identification = ip_rx_ip_identification; -assign output_ip_flags = ip_rx_ip_flags; -assign output_ip_fragment_offset = ip_rx_ip_fragment_offset; -assign output_ip_ttl = ip_rx_ip_ttl; -assign output_ip_protocol = ip_rx_ip_protocol; -assign output_ip_header_checksum = ip_rx_ip_header_checksum; -assign output_ip_source_ip = ip_rx_ip_source_ip; -assign output_ip_dest_ip = ip_rx_ip_dest_ip; -assign output_ip_payload_tdata = ip_rx_ip_payload_tdata; -assign output_ip_payload_tkeep = ip_rx_ip_payload_tkeep; -assign output_ip_payload_tvalid = input_select_ip_reg & ip_rx_ip_payload_tvalid; -assign output_ip_payload_tlast = ip_rx_ip_payload_tlast; -assign output_ip_payload_tuser = ip_rx_ip_payload_tuser; +assign m_ip_hdr_valid = s_select_ip && ip_rx_ip_hdr_valid; +assign m_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; +assign m_ip_eth_src_mac = ip_rx_ip_eth_src_mac; +assign m_ip_eth_type = ip_rx_ip_eth_type; +assign m_ip_version = ip_rx_ip_version; +assign m_ip_ihl = ip_rx_ip_ihl; +assign m_ip_dscp = ip_rx_ip_dscp; +assign m_ip_ecn = ip_rx_ip_ecn; +assign m_ip_length = ip_rx_ip_length; +assign m_ip_identification = ip_rx_ip_identification; +assign m_ip_flags = ip_rx_ip_flags; +assign m_ip_fragment_offset = ip_rx_ip_fragment_offset; +assign m_ip_ttl = ip_rx_ip_ttl; +assign m_ip_protocol = ip_rx_ip_protocol; +assign m_ip_header_checksum = ip_rx_ip_header_checksum; +assign m_ip_source_ip = ip_rx_ip_source_ip; +assign m_ip_dest_ip = ip_rx_ip_dest_ip; +assign m_ip_payload_axis_tdata = ip_rx_ip_payload_axis_tdata; +assign m_ip_payload_axis_tkeep = ip_rx_ip_payload_axis_tkeep; +assign m_ip_payload_axis_tvalid = s_select_ip_reg && ip_rx_ip_payload_axis_tvalid; +assign m_ip_payload_axis_tlast = ip_rx_ip_payload_axis_tlast; +assign m_ip_payload_axis_tuser = ip_rx_ip_payload_axis_tuser; -assign ip_rx_ip_hdr_ready = (input_select_udp & udp_rx_ip_hdr_ready) | - (input_select_ip & output_ip_hdr_ready); +assign ip_rx_ip_hdr_ready = (s_select_udp && udp_rx_ip_hdr_ready) || + (s_select_ip && m_ip_hdr_ready); -assign ip_rx_ip_payload_tready = (input_select_udp_reg & udp_rx_ip_payload_tready) | - (input_select_ip_reg & output_ip_payload_tready); +assign ip_rx_ip_payload_axis_tready = (s_select_udp_reg && udp_rx_ip_payload_axis_tready) || + (s_select_ip_reg && m_ip_payload_axis_tready); /* * Output arbiter @@ -380,32 +380,32 @@ ip_arb_mux_inst ( .clk(clk), .rst(rst), // IP frame inputs - .s_ip_hdr_valid({input_ip_hdr_valid, udp_tx_ip_hdr_valid}), - .s_ip_hdr_ready({input_ip_hdr_ready, udp_tx_ip_hdr_ready}), + .s_ip_hdr_valid({s_ip_hdr_valid, udp_tx_ip_hdr_valid}), + .s_ip_hdr_ready({s_ip_hdr_ready, udp_tx_ip_hdr_ready}), .s_eth_dest_mac(0), .s_eth_src_mac(0), .s_eth_type(0), .s_ip_version(0), .s_ip_ihl(0), - .s_ip_dscp({input_ip_dscp, udp_tx_ip_dscp}), - .s_ip_ecn({input_ip_ecn, udp_tx_ip_ecn}), - .s_ip_length({input_ip_length, udp_tx_ip_length}), + .s_ip_dscp({s_ip_dscp, udp_tx_ip_dscp}), + .s_ip_ecn({s_ip_ecn, udp_tx_ip_ecn}), + .s_ip_length({s_ip_length, udp_tx_ip_length}), .s_ip_identification(0), .s_ip_flags(0), .s_ip_fragment_offset(0), - .s_ip_ttl({input_ip_ttl, udp_tx_ip_ttl}), - .s_ip_protocol({input_ip_protocol, udp_tx_ip_protocol}), + .s_ip_ttl({s_ip_ttl, udp_tx_ip_ttl}), + .s_ip_protocol({s_ip_protocol, udp_tx_ip_protocol}), .s_ip_header_checksum(0), - .s_ip_source_ip({input_ip_source_ip, udp_tx_ip_source_ip}), - .s_ip_dest_ip({input_ip_dest_ip, udp_tx_ip_dest_ip}), - .s_ip_payload_axis_tdata({input_ip_payload_tdata, udp_tx_ip_payload_tdata}), - .s_ip_payload_axis_tkeep({input_ip_payload_tkeep, udp_tx_ip_payload_tkeep}), - .s_ip_payload_axis_tvalid({input_ip_payload_tvalid, udp_tx_ip_payload_tvalid}), - .s_ip_payload_axis_tready({input_ip_payload_tready, udp_tx_ip_payload_tready}), - .s_ip_payload_axis_tlast({input_ip_payload_tlast, udp_tx_ip_payload_tlast}), + .s_ip_source_ip({s_ip_source_ip, udp_tx_ip_source_ip}), + .s_ip_dest_ip({s_ip_dest_ip, udp_tx_ip_dest_ip}), + .s_ip_payload_axis_tdata({s_ip_payload_axis_tdata, udp_tx_ip_payload_axis_tdata}), + .s_ip_payload_axis_tkeep({s_ip_payload_axis_tkeep, udp_tx_ip_payload_axis_tkeep}), + .s_ip_payload_axis_tvalid({s_ip_payload_axis_tvalid, udp_tx_ip_payload_axis_tvalid}), + .s_ip_payload_axis_tready({s_ip_payload_axis_tready, udp_tx_ip_payload_axis_tready}), + .s_ip_payload_axis_tlast({s_ip_payload_axis_tlast, udp_tx_ip_payload_axis_tlast}), .s_ip_payload_axis_tid(0), .s_ip_payload_axis_tdest(0), - .s_ip_payload_axis_tuser({input_ip_payload_tuser, udp_tx_ip_payload_tuser}), + .s_ip_payload_axis_tuser({s_ip_payload_axis_tuser, udp_tx_ip_payload_axis_tuser}), // IP frame output .m_ip_hdr_valid(ip_tx_ip_hdr_valid), .m_ip_hdr_ready(ip_tx_ip_hdr_ready), @@ -425,14 +425,14 @@ ip_arb_mux_inst ( .m_ip_header_checksum(), .m_ip_source_ip(ip_tx_ip_source_ip), .m_ip_dest_ip(ip_tx_ip_dest_ip), - .m_ip_payload_axis_tdata(ip_tx_ip_payload_tdata), - .m_ip_payload_axis_tkeep(ip_tx_ip_payload_tkeep), - .m_ip_payload_axis_tvalid(ip_tx_ip_payload_tvalid), - .m_ip_payload_axis_tready(ip_tx_ip_payload_tready), - .m_ip_payload_axis_tlast(ip_tx_ip_payload_tlast), + .m_ip_payload_axis_tdata(ip_tx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(ip_tx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(ip_tx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(ip_tx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(ip_tx_ip_payload_axis_tlast), .m_ip_payload_axis_tid(), .m_ip_payload_axis_tdest(), - .m_ip_payload_axis_tuser(ip_tx_ip_payload_tuser) + .m_ip_payload_axis_tuser(ip_tx_ip_payload_axis_tuser) ); /* @@ -448,70 +448,70 @@ ip_complete_64_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(ip_tx_ip_hdr_valid), - .input_ip_hdr_ready(ip_tx_ip_hdr_ready), - .input_ip_dscp(ip_tx_ip_dscp), - .input_ip_ecn(ip_tx_ip_ecn), - .input_ip_length(ip_tx_ip_length), - .input_ip_ttl(ip_tx_ip_ttl), - .input_ip_protocol(ip_tx_ip_protocol), - .input_ip_source_ip(ip_tx_ip_source_ip), - .input_ip_dest_ip(ip_tx_ip_dest_ip), - .input_ip_payload_tdata(ip_tx_ip_payload_tdata), - .input_ip_payload_tkeep(ip_tx_ip_payload_tkeep), - .input_ip_payload_tvalid(ip_tx_ip_payload_tvalid), - .input_ip_payload_tready(ip_tx_ip_payload_tready), - .input_ip_payload_tlast(ip_tx_ip_payload_tlast), - .input_ip_payload_tuser(ip_tx_ip_payload_tuser), + .s_ip_hdr_valid(ip_tx_ip_hdr_valid), + .s_ip_hdr_ready(ip_tx_ip_hdr_ready), + .s_ip_dscp(ip_tx_ip_dscp), + .s_ip_ecn(ip_tx_ip_ecn), + .s_ip_length(ip_tx_ip_length), + .s_ip_ttl(ip_tx_ip_ttl), + .s_ip_protocol(ip_tx_ip_protocol), + .s_ip_source_ip(ip_tx_ip_source_ip), + .s_ip_dest_ip(ip_tx_ip_dest_ip), + .s_ip_payload_axis_tdata(ip_tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(ip_tx_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(ip_tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(ip_tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(ip_tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(ip_tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(ip_rx_ip_hdr_valid), - .output_ip_hdr_ready(ip_rx_ip_hdr_ready), - .output_ip_eth_dest_mac(ip_rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(ip_rx_ip_eth_src_mac), - .output_ip_eth_type(ip_rx_ip_eth_type), - .output_ip_version(ip_rx_ip_version), - .output_ip_ihl(ip_rx_ip_ihl), - .output_ip_dscp(ip_rx_ip_dscp), - .output_ip_ecn(ip_rx_ip_ecn), - .output_ip_length(ip_rx_ip_length), - .output_ip_identification(ip_rx_ip_identification), - .output_ip_flags(ip_rx_ip_flags), - .output_ip_fragment_offset(ip_rx_ip_fragment_offset), - .output_ip_ttl(ip_rx_ip_ttl), - .output_ip_protocol(ip_rx_ip_protocol), - .output_ip_header_checksum(ip_rx_ip_header_checksum), - .output_ip_source_ip(ip_rx_ip_source_ip), - .output_ip_dest_ip(ip_rx_ip_dest_ip), - .output_ip_payload_tdata(ip_rx_ip_payload_tdata), - .output_ip_payload_tkeep(ip_rx_ip_payload_tkeep), - .output_ip_payload_tvalid(ip_rx_ip_payload_tvalid), - .output_ip_payload_tready(ip_rx_ip_payload_tready), - .output_ip_payload_tlast(ip_rx_ip_payload_tlast), - .output_ip_payload_tuser(ip_rx_ip_payload_tuser), + .m_ip_hdr_valid(ip_rx_ip_hdr_valid), + .m_ip_hdr_ready(ip_rx_ip_hdr_ready), + .m_ip_eth_dest_mac(ip_rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(ip_rx_ip_eth_src_mac), + .m_ip_eth_type(ip_rx_ip_eth_type), + .m_ip_version(ip_rx_ip_version), + .m_ip_ihl(ip_rx_ip_ihl), + .m_ip_dscp(ip_rx_ip_dscp), + .m_ip_ecn(ip_rx_ip_ecn), + .m_ip_length(ip_rx_ip_length), + .m_ip_identification(ip_rx_ip_identification), + .m_ip_flags(ip_rx_ip_flags), + .m_ip_fragment_offset(ip_rx_ip_fragment_offset), + .m_ip_ttl(ip_rx_ip_ttl), + .m_ip_protocol(ip_rx_ip_protocol), + .m_ip_header_checksum(ip_rx_ip_header_checksum), + .m_ip_source_ip(ip_rx_ip_source_ip), + .m_ip_dest_ip(ip_rx_ip_dest_ip), + .m_ip_payload_axis_tdata(ip_rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(ip_rx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(ip_rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(ip_rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(ip_rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(ip_rx_ip_payload_axis_tuser), // Status .rx_busy(ip_rx_busy), .tx_busy(ip_tx_busy), @@ -541,111 +541,111 @@ udp_64_inst ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(udp_rx_ip_hdr_valid), - .input_ip_hdr_ready(udp_rx_ip_hdr_ready), - .input_ip_eth_dest_mac(udp_rx_ip_eth_dest_mac), - .input_ip_eth_src_mac(udp_rx_ip_eth_src_mac), - .input_ip_eth_type(udp_rx_ip_eth_type), - .input_ip_version(udp_rx_ip_version), - .input_ip_ihl(udp_rx_ip_ihl), - .input_ip_dscp(udp_rx_ip_dscp), - .input_ip_ecn(udp_rx_ip_ecn), - .input_ip_length(udp_rx_ip_length), - .input_ip_identification(udp_rx_ip_identification), - .input_ip_flags(udp_rx_ip_flags), - .input_ip_fragment_offset(udp_rx_ip_fragment_offset), - .input_ip_ttl(udp_rx_ip_ttl), - .input_ip_protocol(udp_rx_ip_protocol), - .input_ip_header_checksum(udp_rx_ip_header_checksum), - .input_ip_source_ip(udp_rx_ip_source_ip), - .input_ip_dest_ip(udp_rx_ip_dest_ip), - .input_ip_payload_tdata(udp_rx_ip_payload_tdata), - .input_ip_payload_tkeep(udp_rx_ip_payload_tkeep), - .input_ip_payload_tvalid(udp_rx_ip_payload_tvalid), - .input_ip_payload_tready(udp_rx_ip_payload_tready), - .input_ip_payload_tlast(udp_rx_ip_payload_tlast), - .input_ip_payload_tuser(udp_rx_ip_payload_tuser), + .s_ip_hdr_valid(udp_rx_ip_hdr_valid), + .s_ip_hdr_ready(udp_rx_ip_hdr_ready), + .s_ip_eth_dest_mac(udp_rx_ip_eth_dest_mac), + .s_ip_eth_src_mac(udp_rx_ip_eth_src_mac), + .s_ip_eth_type(udp_rx_ip_eth_type), + .s_ip_version(udp_rx_ip_version), + .s_ip_ihl(udp_rx_ip_ihl), + .s_ip_dscp(udp_rx_ip_dscp), + .s_ip_ecn(udp_rx_ip_ecn), + .s_ip_length(udp_rx_ip_length), + .s_ip_identification(udp_rx_ip_identification), + .s_ip_flags(udp_rx_ip_flags), + .s_ip_fragment_offset(udp_rx_ip_fragment_offset), + .s_ip_ttl(udp_rx_ip_ttl), + .s_ip_protocol(udp_rx_ip_protocol), + .s_ip_header_checksum(udp_rx_ip_header_checksum), + .s_ip_source_ip(udp_rx_ip_source_ip), + .s_ip_dest_ip(udp_rx_ip_dest_ip), + .s_ip_payload_axis_tdata(udp_rx_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(udp_rx_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(udp_rx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(udp_rx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(udp_rx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(udp_rx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(udp_tx_ip_hdr_valid), - .output_ip_hdr_ready(udp_tx_ip_hdr_ready), - .output_ip_eth_dest_mac(), - .output_ip_eth_src_mac(), - .output_ip_eth_type(), - .output_ip_version(), - .output_ip_ihl(), - .output_ip_dscp(udp_tx_ip_dscp), - .output_ip_ecn(udp_tx_ip_ecn), - .output_ip_length(udp_tx_ip_length), - .output_ip_identification(), - .output_ip_flags(), - .output_ip_fragment_offset(), - .output_ip_ttl(udp_tx_ip_ttl), - .output_ip_protocol(udp_tx_ip_protocol), - .output_ip_header_checksum(), - .output_ip_source_ip(udp_tx_ip_source_ip), - .output_ip_dest_ip(udp_tx_ip_dest_ip), - .output_ip_payload_tdata(udp_tx_ip_payload_tdata), - .output_ip_payload_tkeep(udp_tx_ip_payload_tkeep), - .output_ip_payload_tvalid(udp_tx_ip_payload_tvalid), - .output_ip_payload_tready(udp_tx_ip_payload_tready), - .output_ip_payload_tlast(udp_tx_ip_payload_tlast), - .output_ip_payload_tuser(udp_tx_ip_payload_tuser), + .m_ip_hdr_valid(udp_tx_ip_hdr_valid), + .m_ip_hdr_ready(udp_tx_ip_hdr_ready), + .m_ip_eth_dest_mac(), + .m_ip_eth_src_mac(), + .m_ip_eth_type(), + .m_ip_version(), + .m_ip_ihl(), + .m_ip_dscp(udp_tx_ip_dscp), + .m_ip_ecn(udp_tx_ip_ecn), + .m_ip_length(udp_tx_ip_length), + .m_ip_identification(), + .m_ip_flags(), + .m_ip_fragment_offset(), + .m_ip_ttl(udp_tx_ip_ttl), + .m_ip_protocol(udp_tx_ip_protocol), + .m_ip_header_checksum(), + .m_ip_source_ip(udp_tx_ip_source_ip), + .m_ip_dest_ip(udp_tx_ip_dest_ip), + .m_ip_payload_axis_tdata(udp_tx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(udp_tx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(udp_tx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(udp_tx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(udp_tx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(udp_tx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_udp_eth_dest_mac(48'd0), - .input_udp_eth_src_mac(48'd0), - .input_udp_eth_type(16'd0), - .input_udp_ip_version(4'd0), - .input_udp_ip_ihl(4'd0), - .input_udp_ip_dscp(input_udp_ip_dscp), - .input_udp_ip_ecn(input_udp_ip_ecn), - .input_udp_ip_identification(16'd0), - .input_udp_ip_flags(3'd0), - .input_udp_ip_fragment_offset(13'd0), - .input_udp_ip_ttl(input_udp_ip_ttl), - .input_udp_ip_header_checksum(16'd0), - .input_udp_ip_source_ip(input_udp_ip_source_ip), - .input_udp_ip_dest_ip(input_udp_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), - .input_udp_checksum(input_udp_checksum), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tkeep(input_udp_payload_tkeep), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_udp_eth_dest_mac(48'd0), + .s_udp_eth_src_mac(48'd0), + .s_udp_eth_type(16'd0), + .s_udp_ip_version(4'd0), + .s_udp_ip_ihl(4'd0), + .s_udp_ip_dscp(s_udp_ip_dscp), + .s_udp_ip_ecn(s_udp_ip_ecn), + .s_udp_ip_identification(16'd0), + .s_udp_ip_flags(3'd0), + .s_udp_ip_fragment_offset(13'd0), + .s_udp_ip_ttl(s_udp_ip_ttl), + .s_udp_ip_header_checksum(16'd0), + .s_udp_ip_source_ip(s_udp_ip_source_ip), + .s_udp_ip_dest_ip(s_udp_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_udp_eth_dest_mac(output_udp_eth_dest_mac), - .output_udp_eth_src_mac(output_udp_eth_src_mac), - .output_udp_eth_type(output_udp_eth_type), - .output_udp_ip_version(output_udp_ip_version), - .output_udp_ip_ihl(output_udp_ip_ihl), - .output_udp_ip_dscp(output_udp_ip_dscp), - .output_udp_ip_ecn(output_udp_ip_ecn), - .output_udp_ip_length(output_udp_ip_length), - .output_udp_ip_identification(output_udp_ip_identification), - .output_udp_ip_flags(output_udp_ip_flags), - .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), - .output_udp_ip_ttl(output_udp_ip_ttl), - .output_udp_ip_protocol(output_udp_ip_protocol), - .output_udp_ip_header_checksum(output_udp_ip_header_checksum), - .output_udp_ip_source_ip(output_udp_ip_source_ip), - .output_udp_ip_dest_ip(output_udp_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tkeep(output_udp_payload_tkeep), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_udp_eth_dest_mac(m_udp_eth_dest_mac), + .m_udp_eth_src_mac(m_udp_eth_src_mac), + .m_udp_eth_type(m_udp_eth_type), + .m_udp_ip_version(m_udp_ip_version), + .m_udp_ip_ihl(m_udp_ip_ihl), + .m_udp_ip_dscp(m_udp_ip_dscp), + .m_udp_ip_ecn(m_udp_ip_ecn), + .m_udp_ip_length(m_udp_ip_length), + .m_udp_ip_identification(m_udp_ip_identification), + .m_udp_ip_flags(m_udp_ip_flags), + .m_udp_ip_fragment_offset(m_udp_ip_fragment_offset), + .m_udp_ip_ttl(m_udp_ip_ttl), + .m_udp_ip_protocol(m_udp_ip_protocol), + .m_udp_ip_header_checksum(m_udp_ip_header_checksum), + .m_udp_ip_source_ip(m_udp_ip_source_ip), + .m_udp_ip_dest_ip(m_udp_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Status .rx_busy(udp_rx_busy), .tx_busy(udp_tx_busy), diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v index 5410905fe..c3920f113 100644 --- a/rtl/udp_ip_rx.v +++ b/rtl/udp_ip_rx.v @@ -37,60 +37,60 @@ module udp_ip_rx /* * IP frame input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [7:0] input_ip_payload_tdata, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [3:0] s_ip_version, + input wire [3:0] s_ip_ihl, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [15:0] s_ip_header_checksum, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [7:0] s_ip_payload_axis_tdata, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * UDP frame output */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [7:0] output_udp_payload_tdata, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, + output wire m_udp_hdr_valid, + input wire m_udp_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [15:0] m_udp_source_port, + output wire [15:0] m_udp_dest_port, + output wire [15:0] m_udp_length, + output wire [15:0] m_udp_checksum, + output wire [7:0] m_udp_payload_axis_tdata, + output wire m_udp_payload_axis_tvalid, + input wire m_udp_payload_axis_tready, + output wire m_udp_payload_axis_tlast, + output wire m_udp_payload_axis_tuser, /* * Status signals @@ -162,67 +162,67 @@ reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; reg [7:0] last_word_data_reg = 8'd0; -reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; -reg [3:0] output_ip_version_reg = 4'd0; -reg [3:0] output_ip_ihl_reg = 4'd0; -reg [5:0] output_ip_dscp_reg = 6'd0; -reg [1:0] output_ip_ecn_reg = 2'd0; -reg [15:0] output_ip_length_reg = 16'd0; -reg [15:0] output_ip_identification_reg = 16'd0; -reg [2:0] output_ip_flags_reg = 3'd0; -reg [12:0] output_ip_fragment_offset_reg = 13'd0; -reg [7:0] output_ip_ttl_reg = 8'd0; -reg [7:0] output_ip_protocol_reg = 8'd0; -reg [15:0] output_ip_header_checksum_reg = 16'd0; -reg [31:0] output_ip_source_ip_reg = 32'd0; -reg [31:0] output_ip_dest_ip_reg = 32'd0; -reg [15:0] output_udp_source_port_reg = 16'd0; -reg [15:0] output_udp_dest_port_reg = 16'd0; -reg [15:0] output_udp_length_reg = 16'd0; -reg [15:0] output_udp_checksum_reg = 16'd0; +reg m_udp_hdr_valid_reg = 1'b0, m_udp_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; +reg [3:0] m_ip_version_reg = 4'd0; +reg [3:0] m_ip_ihl_reg = 4'd0; +reg [5:0] m_ip_dscp_reg = 6'd0; +reg [1:0] m_ip_ecn_reg = 2'd0; +reg [15:0] m_ip_length_reg = 16'd0; +reg [15:0] m_ip_identification_reg = 16'd0; +reg [2:0] m_ip_flags_reg = 3'd0; +reg [12:0] m_ip_fragment_offset_reg = 13'd0; +reg [7:0] m_ip_ttl_reg = 8'd0; +reg [7:0] m_ip_protocol_reg = 8'd0; +reg [15:0] m_ip_header_checksum_reg = 16'd0; +reg [31:0] m_ip_source_ip_reg = 32'd0; +reg [31:0] m_ip_dest_ip_reg = 32'd0; +reg [15:0] m_udp_source_port_reg = 16'd0; +reg [15:0] m_udp_dest_port_reg = 16'd0; +reg [15:0] m_udp_length_reg = 16'd0; +reg [15:0] m_udp_checksum_reg = 16'd0; -reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; +reg s_ip_hdr_ready_reg = 1'b0, s_ip_hdr_ready_next; +reg s_ip_payload_axis_tready_reg = 1'b0, s_ip_payload_axis_tready_next; reg busy_reg = 1'b0; reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; // internal datapath -reg [7:0] output_udp_payload_tdata_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int_reg = 1'b0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; +reg [7:0] m_udp_payload_axis_tdata_int; +reg m_udp_payload_axis_tvalid_int; +reg m_udp_payload_axis_tready_int_reg = 1'b0; +reg m_udp_payload_axis_tlast_int; +reg m_udp_payload_axis_tuser_int; +wire m_udp_payload_axis_tready_int_early; -assign input_ip_hdr_ready = input_ip_hdr_ready_reg; -assign input_ip_payload_tready = input_ip_payload_tready_reg; +assign s_ip_hdr_ready = s_ip_hdr_ready_reg; +assign s_ip_payload_axis_tready = s_ip_payload_axis_tready_reg; -assign output_udp_hdr_valid = output_udp_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_udp_source_port = output_udp_source_port_reg; -assign output_udp_dest_port = output_udp_dest_port_reg; -assign output_udp_length = output_udp_length_reg; -assign output_udp_checksum = output_udp_checksum_reg; +assign m_udp_hdr_valid = m_udp_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_ip_length_reg; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = m_ip_protocol_reg; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; +assign m_udp_source_port = m_udp_source_port_reg; +assign m_udp_dest_port = m_udp_dest_port_reg; +assign m_udp_length = m_udp_length_reg; +assign m_udp_checksum = m_udp_checksum_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -231,8 +231,8 @@ assign error_payload_early_termination = error_payload_early_termination_reg; always @* begin state_next = STATE_IDLE; - input_ip_hdr_ready_next = 1'b0; - input_ip_payload_tready_next = 1'b0; + s_ip_hdr_ready_next = 1'b0; + s_ip_payload_axis_tready_next = 1'b0; store_ip_hdr = 1'b0; store_udp_source_port_0 = 1'b0; @@ -248,25 +248,25 @@ always @* begin frame_ptr_next = frame_ptr_reg; - output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; + m_udp_hdr_valid_next = m_udp_hdr_valid_reg && !m_udp_hdr_ready; error_header_early_termination_next = 1'b0; error_payload_early_termination_next = 1'b0; - output_udp_payload_tdata_int = 8'd0; - output_udp_payload_tvalid_int = 1'b0; - output_udp_payload_tlast_int = 1'b0; - output_udp_payload_tuser_int = 1'b0; + m_udp_payload_axis_tdata_int = 8'd0; + m_udp_payload_axis_tvalid_int = 1'b0; + m_udp_payload_axis_tlast_int = 1'b0; + m_udp_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for header frame_ptr_next = 16'd0; - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; - if (input_ip_hdr_ready & input_ip_hdr_valid) begin - input_ip_hdr_ready_next = 1'b0; - input_ip_payload_tready_next = 1'b1; + if (s_ip_hdr_ready && s_ip_hdr_valid) begin + s_ip_hdr_ready_next = 1'b0; + s_ip_payload_axis_tready_next = 1'b1; store_ip_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin @@ -275,9 +275,9 @@ always @* begin end STATE_READ_HEADER: begin // read header state - input_ip_payload_tready_next = 1'b1; + s_ip_payload_axis_tready_next = 1'b1; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg + 16'd1; state_next = STATE_READ_HEADER; @@ -292,17 +292,17 @@ always @* begin 8'h06: store_udp_checksum_1 = 1'b1; 8'h07: begin store_udp_checksum_0 = 1'b1; - output_udp_hdr_valid_next = 1'b1; - input_ip_payload_tready_next = output_udp_payload_tready_int_early; + m_udp_hdr_valid_next = 1'b1; + s_ip_payload_axis_tready_next = m_udp_payload_axis_tready_int_early; state_next = STATE_READ_PAYLOAD; end endcase - if (input_ip_payload_tlast) begin + if (s_ip_payload_axis_tlast) begin error_header_early_termination_next = 1'b1; - output_udp_hdr_valid_next = 1'b0; - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + m_udp_hdr_valid_next = 1'b0; + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -312,29 +312,29 @@ always @* begin end STATE_READ_PAYLOAD: begin // read payload - input_ip_payload_tready_next = output_udp_payload_tready_int_early; + s_ip_payload_axis_tready_next = m_udp_payload_axis_tready_int_early; - output_udp_payload_tdata_int = input_ip_payload_tdata; - output_udp_payload_tvalid_int = input_ip_payload_tvalid; - output_udp_payload_tlast_int = input_ip_payload_tlast; - output_udp_payload_tuser_int = input_ip_payload_tuser; + m_udp_payload_axis_tdata_int = s_ip_payload_axis_tdata; + m_udp_payload_axis_tvalid_int = s_ip_payload_axis_tvalid; + m_udp_payload_axis_tlast_int = s_ip_payload_axis_tlast; + m_udp_payload_axis_tuser_int = s_ip_payload_axis_tuser; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg + 16'd1; - if (input_ip_payload_tlast) begin - if (frame_ptr_next != output_udp_length_reg) begin + if (s_ip_payload_axis_tlast) begin + if (frame_ptr_next != m_udp_length_reg) begin // end of frame, but length does not match - output_udp_payload_tuser_int = 1'b1; + m_udp_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; end - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin - if (frame_ptr_next == output_udp_length_reg) begin + if (frame_ptr_next == m_udp_length_reg) begin store_last_word = 1'b1; - output_udp_payload_tvalid_int = 1'b0; + m_udp_payload_axis_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; end else begin state_next = STATE_READ_PAYLOAD; @@ -346,17 +346,17 @@ always @* begin end STATE_READ_PAYLOAD_LAST: begin // read and discard until end of frame - input_ip_payload_tready_next = output_udp_payload_tready_int_early; + s_ip_payload_axis_tready_next = m_udp_payload_axis_tready_int_early; - output_udp_payload_tdata_int = last_word_data_reg; - output_udp_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tlast; - output_udp_payload_tlast_int = input_ip_payload_tlast; - output_udp_payload_tuser_int = input_ip_payload_tuser; + m_udp_payload_axis_tdata_int = last_word_data_reg; + m_udp_payload_axis_tvalid_int = s_ip_payload_axis_tvalid && s_ip_payload_axis_tlast; + m_udp_payload_axis_tlast_int = s_ip_payload_axis_tlast; + m_udp_payload_axis_tuser_int = s_ip_payload_axis_tuser; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin - if (input_ip_payload_tlast) begin - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin + if (s_ip_payload_axis_tlast) begin + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD_LAST; @@ -367,12 +367,12 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_ip_payload_tready_next = 1'b1; + s_ip_payload_axis_tready_next = 1'b1; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin - if (input_ip_payload_tlast) begin - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin + if (s_ip_payload_axis_tlast) begin + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -388,9 +388,9 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 16'd0; - input_ip_hdr_ready_reg <= 1'b0; - input_ip_payload_tready_reg <= 1'b0; - output_udp_hdr_valid_reg <= 1'b0; + s_ip_hdr_ready_reg <= 1'b0; + s_ip_payload_axis_tready_reg <= 1'b0; + m_udp_hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; error_header_early_termination_reg <= 1'b0; error_payload_early_termination_reg <= 1'b0; @@ -399,10 +399,10 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; - input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; - input_ip_payload_tready_reg <= input_ip_payload_tready_next; + s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; + s_ip_payload_axis_tready_reg <= s_ip_payload_axis_tready_next; - output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + m_udp_hdr_valid_reg <= m_udp_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; error_payload_early_termination_reg <= error_payload_early_termination_next; @@ -412,116 +412,116 @@ always @(posedge clk) begin // datapath if (store_ip_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - output_ip_version_reg <= input_ip_version; - output_ip_ihl_reg <= input_ip_ihl; - output_ip_dscp_reg <= input_ip_dscp; - output_ip_ecn_reg <= input_ip_ecn; - output_ip_length_reg <= input_ip_length; - output_ip_identification_reg <= input_ip_identification; - output_ip_flags_reg <= input_ip_flags; - output_ip_fragment_offset_reg <= input_ip_fragment_offset; - output_ip_ttl_reg <= input_ip_ttl; - output_ip_protocol_reg <= input_ip_protocol; - output_ip_header_checksum_reg <= input_ip_header_checksum; - output_ip_source_ip_reg <= input_ip_source_ip; - output_ip_dest_ip_reg <= input_ip_dest_ip; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; + m_ip_version_reg <= s_ip_version; + m_ip_ihl_reg <= s_ip_ihl; + m_ip_dscp_reg <= s_ip_dscp; + m_ip_ecn_reg <= s_ip_ecn; + m_ip_length_reg <= s_ip_length; + m_ip_identification_reg <= s_ip_identification; + m_ip_flags_reg <= s_ip_flags; + m_ip_fragment_offset_reg <= s_ip_fragment_offset; + m_ip_ttl_reg <= s_ip_ttl; + m_ip_protocol_reg <= s_ip_protocol; + m_ip_header_checksum_reg <= s_ip_header_checksum; + m_ip_source_ip_reg <= s_ip_source_ip; + m_ip_dest_ip_reg <= s_ip_dest_ip; end if (store_last_word) begin - last_word_data_reg <= output_udp_payload_tdata_int; + last_word_data_reg <= m_udp_payload_axis_tdata_int; end - if (store_udp_source_port_0) output_udp_source_port_reg[ 7: 0] <= input_ip_payload_tdata; - if (store_udp_source_port_1) output_udp_source_port_reg[15: 8] <= input_ip_payload_tdata; - if (store_udp_dest_port_0) output_udp_dest_port_reg[ 7: 0] <= input_ip_payload_tdata; - if (store_udp_dest_port_1) output_udp_dest_port_reg[15: 8] <= input_ip_payload_tdata; - if (store_udp_length_0) output_udp_length_reg[ 7: 0] <= input_ip_payload_tdata; - if (store_udp_length_1) output_udp_length_reg[15: 8] <= input_ip_payload_tdata; - if (store_udp_checksum_0) output_udp_checksum_reg[ 7: 0] <= input_ip_payload_tdata; - if (store_udp_checksum_1) output_udp_checksum_reg[15: 8] <= input_ip_payload_tdata; + if (store_udp_source_port_0) m_udp_source_port_reg[ 7: 0] <= s_ip_payload_axis_tdata; + if (store_udp_source_port_1) m_udp_source_port_reg[15: 8] <= s_ip_payload_axis_tdata; + if (store_udp_dest_port_0) m_udp_dest_port_reg[ 7: 0] <= s_ip_payload_axis_tdata; + if (store_udp_dest_port_1) m_udp_dest_port_reg[15: 8] <= s_ip_payload_axis_tdata; + if (store_udp_length_0) m_udp_length_reg[ 7: 0] <= s_ip_payload_axis_tdata; + if (store_udp_length_1) m_udp_length_reg[15: 8] <= s_ip_payload_axis_tdata; + if (store_udp_checksum_0) m_udp_checksum_reg[ 7: 0] <= s_ip_payload_axis_tdata; + if (store_udp_checksum_1) m_udp_checksum_reg[15: 8] <= s_ip_payload_axis_tdata; end // output datapath logic -reg [7:0] output_udp_payload_tdata_reg = 8'd0; -reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; -reg output_udp_payload_tlast_reg = 1'b0; -reg output_udp_payload_tuser_reg = 1'b0; +reg [7:0] m_udp_payload_axis_tdata_reg = 8'd0; +reg m_udp_payload_axis_tvalid_reg = 1'b0, m_udp_payload_axis_tvalid_next; +reg m_udp_payload_axis_tlast_reg = 1'b0; +reg m_udp_payload_axis_tuser_reg = 1'b0; -reg [7:0] temp_udp_payload_tdata_reg = 8'd0; -reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; -reg temp_udp_payload_tlast_reg = 1'b0; -reg temp_udp_payload_tuser_reg = 1'b0; +reg [7:0] temp_m_udp_payload_axis_tdata_reg = 8'd0; +reg temp_m_udp_payload_axis_tvalid_reg = 1'b0, temp_m_udp_payload_axis_tvalid_next; +reg temp_m_udp_payload_axis_tlast_reg = 1'b0; +reg temp_m_udp_payload_axis_tuser_reg = 1'b0; // datapath control reg store_udp_payload_int_to_output; reg store_udp_payload_int_to_temp; -reg store_udp_payload_temp_to_output; +reg store_udp_payload_axis_temp_to_output; -assign output_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; -assign output_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_udp_payload_tuser = output_udp_payload_tuser_reg; +assign m_udp_payload_axis_tdata = m_udp_payload_axis_tdata_reg; +assign m_udp_payload_axis_tvalid = m_udp_payload_axis_tvalid_reg; +assign m_udp_payload_axis_tlast = m_udp_payload_axis_tlast_reg; +assign m_udp_payload_axis_tuser = m_udp_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); +assign m_udp_payload_axis_tready_int_early = m_udp_payload_axis_tready || (!temp_m_udp_payload_axis_tvalid_reg && (!m_udp_payload_axis_tvalid_reg || !m_udp_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_reg; + temp_m_udp_payload_axis_tvalid_next = temp_m_udp_payload_axis_tvalid_reg; store_udp_payload_int_to_output = 1'b0; store_udp_payload_int_to_temp = 1'b0; - store_udp_payload_temp_to_output = 1'b0; + store_udp_payload_axis_temp_to_output = 1'b0; - if (output_udp_payload_tready_int_reg) begin + if (m_udp_payload_axis_tready_int_reg) begin // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + if (m_udp_payload_axis_tready || !m_udp_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_int; store_udp_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + temp_m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_int; store_udp_payload_int_to_temp = 1'b1; end - end else if (output_udp_payload_tready) begin + end else if (m_udp_payload_axis_tready) begin // input is not ready, but output is ready - output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = 1'b0; - store_udp_payload_temp_to_output = 1'b1; + m_udp_payload_axis_tvalid_next = temp_m_udp_payload_axis_tvalid_reg; + temp_m_udp_payload_axis_tvalid_next = 1'b0; + store_udp_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_udp_payload_tvalid_reg <= 1'b0; - output_udp_payload_tready_int_reg <= 1'b0; - temp_udp_payload_tvalid_reg <= 1'b0; + m_udp_payload_axis_tvalid_reg <= 1'b0; + m_udp_payload_axis_tready_int_reg <= 1'b0; + temp_m_udp_payload_axis_tvalid_reg <= 1'b0; end else begin - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; - output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; - temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + m_udp_payload_axis_tvalid_reg <= m_udp_payload_axis_tvalid_next; + m_udp_payload_axis_tready_int_reg <= m_udp_payload_axis_tready_int_early; + temp_m_udp_payload_axis_tvalid_reg <= temp_m_udp_payload_axis_tvalid_next; end // datapath if (store_udp_payload_int_to_output) begin - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else if (store_udp_payload_temp_to_output) begin - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + m_udp_payload_axis_tdata_reg <= m_udp_payload_axis_tdata_int; + m_udp_payload_axis_tlast_reg <= m_udp_payload_axis_tlast_int; + m_udp_payload_axis_tuser_reg <= m_udp_payload_axis_tuser_int; + end else if (store_udp_payload_axis_temp_to_output) begin + m_udp_payload_axis_tdata_reg <= temp_m_udp_payload_axis_tdata_reg; + m_udp_payload_axis_tlast_reg <= temp_m_udp_payload_axis_tlast_reg; + m_udp_payload_axis_tuser_reg <= temp_m_udp_payload_axis_tuser_reg; end if (store_udp_payload_int_to_temp) begin - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + temp_m_udp_payload_axis_tdata_reg <= m_udp_payload_axis_tdata_int; + temp_m_udp_payload_axis_tlast_reg <= m_udp_payload_axis_tlast_int; + temp_m_udp_payload_axis_tuser_reg <= m_udp_payload_axis_tuser_int; end end diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index f9afeda74..a57028972 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -37,62 +37,62 @@ module udp_ip_rx_64 /* * IP frame input */ - input wire input_ip_hdr_valid, - output wire input_ip_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_length, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [63:0] input_ip_payload_tdata, - input wire [7:0] input_ip_payload_tkeep, - input wire input_ip_payload_tvalid, - output wire input_ip_payload_tready, - input wire input_ip_payload_tlast, - input wire input_ip_payload_tuser, + input wire s_ip_hdr_valid, + output wire s_ip_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [3:0] s_ip_version, + input wire [3:0] s_ip_ihl, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_length, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [15:0] s_ip_header_checksum, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [63:0] s_ip_payload_axis_tdata, + input wire [7:0] s_ip_payload_axis_tkeep, + input wire s_ip_payload_axis_tvalid, + output wire s_ip_payload_axis_tready, + input wire s_ip_payload_axis_tlast, + input wire s_ip_payload_axis_tuser, /* * UDP frame output */ - output wire output_udp_hdr_valid, - input wire output_udp_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [15:0] output_udp_source_port, - output wire [15:0] output_udp_dest_port, - output wire [15:0] output_udp_length, - output wire [15:0] output_udp_checksum, - output wire [63:0] output_udp_payload_tdata, - output wire [7:0] output_udp_payload_tkeep, - output wire output_udp_payload_tvalid, - input wire output_udp_payload_tready, - output wire output_udp_payload_tlast, - output wire output_udp_payload_tuser, + output wire m_udp_hdr_valid, + input wire m_udp_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [15:0] m_udp_source_port, + output wire [15:0] m_udp_dest_port, + output wire [15:0] m_udp_length, + output wire [15:0] m_udp_checksum, + output wire [63:0] m_udp_payload_axis_tdata, + output wire [7:0] m_udp_payload_axis_tkeep, + output wire m_udp_payload_axis_tvalid, + input wire m_udp_payload_axis_tready, + output wire m_udp_payload_axis_tlast, + output wire m_udp_payload_axis_tuser, /* * Status signals @@ -158,68 +158,68 @@ reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; reg [63:0] last_word_data_reg = 64'd0; reg [7:0] last_word_keep_reg = 8'd0; -reg output_udp_hdr_valid_reg = 1'b0, output_udp_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; -reg [3:0] output_ip_version_reg = 4'd0; -reg [3:0] output_ip_ihl_reg = 4'd0; -reg [5:0] output_ip_dscp_reg = 6'd0; -reg [1:0] output_ip_ecn_reg = 2'd0; -reg [15:0] output_ip_length_reg = 16'd0; -reg [15:0] output_ip_identification_reg = 16'd0; -reg [2:0] output_ip_flags_reg = 3'd0; -reg [12:0] output_ip_fragment_offset_reg = 13'd0; -reg [7:0] output_ip_ttl_reg = 8'd0; -reg [7:0] output_ip_protocol_reg = 8'd0; -reg [15:0] output_ip_header_checksum_reg = 16'd0; -reg [31:0] output_ip_source_ip_reg = 32'd0; -reg [31:0] output_ip_dest_ip_reg = 32'd0; -reg [15:0] output_udp_source_port_reg = 16'd0; -reg [15:0] output_udp_dest_port_reg = 16'd0; -reg [15:0] output_udp_length_reg = 16'd0; -reg [15:0] output_udp_checksum_reg = 16'd0; +reg m_udp_hdr_valid_reg = 1'b0, m_udp_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; +reg [3:0] m_ip_version_reg = 4'd0; +reg [3:0] m_ip_ihl_reg = 4'd0; +reg [5:0] m_ip_dscp_reg = 6'd0; +reg [1:0] m_ip_ecn_reg = 2'd0; +reg [15:0] m_ip_length_reg = 16'd0; +reg [15:0] m_ip_identification_reg = 16'd0; +reg [2:0] m_ip_flags_reg = 3'd0; +reg [12:0] m_ip_fragment_offset_reg = 13'd0; +reg [7:0] m_ip_ttl_reg = 8'd0; +reg [7:0] m_ip_protocol_reg = 8'd0; +reg [15:0] m_ip_header_checksum_reg = 16'd0; +reg [31:0] m_ip_source_ip_reg = 32'd0; +reg [31:0] m_ip_dest_ip_reg = 32'd0; +reg [15:0] m_udp_source_port_reg = 16'd0; +reg [15:0] m_udp_dest_port_reg = 16'd0; +reg [15:0] m_udp_length_reg = 16'd0; +reg [15:0] m_udp_checksum_reg = 16'd0; -reg input_ip_hdr_ready_reg = 1'b0, input_ip_hdr_ready_next; -reg input_ip_payload_tready_reg = 1'b0, input_ip_payload_tready_next; +reg s_ip_hdr_ready_reg = 1'b0, s_ip_hdr_ready_next; +reg s_ip_payload_axis_tready_reg = 1'b0, s_ip_payload_axis_tready_next; reg busy_reg = 1'b0; reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; // internal datapath -reg [63:0] output_udp_payload_tdata_int; -reg [7:0] output_udp_payload_tkeep_int; -reg output_udp_payload_tvalid_int; -reg output_udp_payload_tready_int_reg = 1'b0; -reg output_udp_payload_tlast_int; -reg output_udp_payload_tuser_int; -wire output_udp_payload_tready_int_early; +reg [63:0] m_udp_payload_axis_tdata_int; +reg [7:0] m_udp_payload_axis_tkeep_int; +reg m_udp_payload_axis_tvalid_int; +reg m_udp_payload_axis_tready_int_reg = 1'b0; +reg m_udp_payload_axis_tlast_int; +reg m_udp_payload_axis_tuser_int; +wire m_udp_payload_axis_tready_int_early; -assign input_ip_hdr_ready = input_ip_hdr_ready_reg; -assign input_ip_payload_tready = input_ip_payload_tready_reg; +assign s_ip_hdr_ready = s_ip_hdr_ready_reg; +assign s_ip_payload_axis_tready = s_ip_payload_axis_tready_reg; -assign output_udp_hdr_valid = output_udp_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; -assign output_udp_source_port = output_udp_source_port_reg; -assign output_udp_dest_port = output_udp_dest_port_reg; -assign output_udp_length = output_udp_length_reg; -assign output_udp_checksum = output_udp_checksum_reg; +assign m_udp_hdr_valid = m_udp_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_ip_length_reg; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = m_ip_protocol_reg; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; +assign m_udp_source_port = m_udp_source_port_reg; +assign m_udp_dest_port = m_udp_dest_port_reg; +assign m_udp_length = m_udp_length_reg; +assign m_udp_checksum = m_udp_checksum_reg; assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; @@ -258,8 +258,8 @@ endfunction always @* begin state_next = STATE_IDLE; - input_ip_hdr_ready_next = 1'b0; - input_ip_payload_tready_next = 1'b0; + s_ip_hdr_ready_next = 1'b0; + s_ip_payload_axis_tready_next = 1'b0; store_ip_hdr = 1'b0; store_hdr_word_0 = 1'b0; @@ -268,26 +268,26 @@ always @* begin frame_ptr_next = frame_ptr_reg; - output_udp_hdr_valid_next = output_udp_hdr_valid_reg & ~output_udp_hdr_ready; + m_udp_hdr_valid_next = m_udp_hdr_valid_reg && !m_udp_hdr_ready; error_header_early_termination_next = 1'b0; error_payload_early_termination_next = 1'b0; - output_udp_payload_tdata_int = 64'd0; - output_udp_payload_tkeep_int = 8'd0; - output_udp_payload_tvalid_int = 1'b0; - output_udp_payload_tlast_int = 1'b0; - output_udp_payload_tuser_int = 1'b0; + m_udp_payload_axis_tdata_int = 64'd0; + m_udp_payload_axis_tkeep_int = 8'd0; + m_udp_payload_axis_tvalid_int = 1'b0; + m_udp_payload_axis_tlast_int = 1'b0; + m_udp_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for header frame_ptr_next = 16'd0; - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; - if (input_ip_hdr_ready & input_ip_hdr_valid) begin - input_ip_hdr_ready_next = 1'b0; - input_ip_payload_tready_next = 1'b1; + if (s_ip_hdr_ready && s_ip_hdr_valid) begin + s_ip_hdr_ready_next = 1'b0; + s_ip_payload_axis_tready_next = 1'b1; store_ip_hdr = 1'b1; state_next = STATE_READ_HEADER; end else begin @@ -296,9 +296,9 @@ always @* begin end STATE_READ_HEADER: begin // read header state - input_ip_payload_tready_next = 1'b1; + s_ip_payload_axis_tready_next = 1'b1; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer in - store it frame_ptr_next = frame_ptr_reg + 16'd8; state_next = STATE_READ_HEADER; @@ -306,17 +306,17 @@ always @* begin case (frame_ptr_reg) 8'h00: begin store_hdr_word_0 = 1'b1; - output_udp_hdr_valid_next = 1'b1; - input_ip_payload_tready_next = output_udp_payload_tready_int_early; + m_udp_hdr_valid_next = 1'b1; + s_ip_payload_axis_tready_next = m_udp_payload_axis_tready_int_early; state_next = STATE_READ_PAYLOAD; end endcase - if (input_ip_payload_tlast) begin + if (s_ip_payload_axis_tlast) begin error_header_early_termination_next = 1'b1; - output_udp_hdr_valid_next = 1'b0; - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + m_udp_hdr_valid_next = 1'b0; + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -326,37 +326,37 @@ always @* begin end STATE_READ_PAYLOAD: begin // read payload - input_ip_payload_tready_next = output_udp_payload_tready_int_early; + s_ip_payload_axis_tready_next = m_udp_payload_axis_tready_int_early; - output_udp_payload_tdata_int = input_ip_payload_tdata; - output_udp_payload_tkeep_int = input_ip_payload_tkeep; - output_udp_payload_tvalid_int = input_ip_payload_tvalid; - output_udp_payload_tlast_int = input_ip_payload_tlast; - output_udp_payload_tuser_int = input_ip_payload_tuser; + m_udp_payload_axis_tdata_int = s_ip_payload_axis_tdata; + m_udp_payload_axis_tkeep_int = s_ip_payload_axis_tkeep; + m_udp_payload_axis_tvalid_int = s_ip_payload_axis_tvalid; + m_udp_payload_axis_tlast_int = s_ip_payload_axis_tlast; + m_udp_payload_axis_tuser_int = s_ip_payload_axis_tuser; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+keep2count(input_ip_payload_tkeep); - if (frame_ptr_next >= output_udp_length_reg) begin + frame_ptr_next = frame_ptr_reg+keep2count(s_ip_payload_axis_tkeep); + if (frame_ptr_next >= m_udp_length_reg) begin // have entire payload - frame_ptr_next = output_udp_length_reg; - output_udp_payload_tkeep_int = input_ip_payload_tkeep & count2keep(output_udp_length_reg - frame_ptr_reg); - if (input_ip_payload_tlast) begin - input_ip_payload_tready_next = 1'b0; - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + frame_ptr_next = m_udp_length_reg; + m_udp_payload_axis_tkeep_int = s_ip_payload_axis_tkeep & count2keep(m_udp_length_reg - frame_ptr_reg); + if (s_ip_payload_axis_tlast) begin + s_ip_payload_axis_tready_next = 1'b0; + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; state_next = STATE_IDLE; end else begin store_last_word = 1'b1; - output_udp_payload_tvalid_int = 1'b0; + m_udp_payload_axis_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; end end else begin - if (input_ip_payload_tlast) begin + if (s_ip_payload_axis_tlast) begin // end of frame, but length does not match error_payload_early_termination_next = 1'b1; - output_udp_payload_tuser_int = 1'b1; - input_ip_payload_tready_next = 1'b0; - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; + m_udp_payload_axis_tuser_int = 1'b1; + s_ip_payload_axis_tready_next = 1'b0; + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD; @@ -368,18 +368,18 @@ always @* begin end STATE_READ_PAYLOAD_LAST: begin // read and discard until end of frame - input_ip_payload_tready_next = output_udp_payload_tready_int_early; + s_ip_payload_axis_tready_next = m_udp_payload_axis_tready_int_early; - output_udp_payload_tdata_int = last_word_data_reg; - output_udp_payload_tkeep_int = last_word_keep_reg; - output_udp_payload_tvalid_int = input_ip_payload_tvalid & input_ip_payload_tlast; - output_udp_payload_tlast_int = input_ip_payload_tlast; - output_udp_payload_tuser_int = input_ip_payload_tuser; + m_udp_payload_axis_tdata_int = last_word_data_reg; + m_udp_payload_axis_tkeep_int = last_word_keep_reg; + m_udp_payload_axis_tvalid_int = s_ip_payload_axis_tvalid && s_ip_payload_axis_tlast; + m_udp_payload_axis_tlast_int = s_ip_payload_axis_tlast; + m_udp_payload_axis_tuser_int = s_ip_payload_axis_tuser; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin - if (input_ip_payload_tlast) begin - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin + if (s_ip_payload_axis_tlast) begin + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD_LAST; @@ -390,12 +390,12 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_ip_payload_tready_next = 1'b1; + s_ip_payload_axis_tready_next = 1'b1; - if (input_ip_payload_tready & input_ip_payload_tvalid) begin - if (input_ip_payload_tlast) begin - input_ip_hdr_ready_next = ~output_udp_hdr_valid_reg; - input_ip_payload_tready_next = 1'b0; + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin + if (s_ip_payload_axis_tlast) begin + s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -411,9 +411,9 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 16'd0; - input_ip_hdr_ready_reg <= 1'b0; - input_ip_payload_tready_reg <= 1'b0; - output_udp_hdr_valid_reg <= 1'b0; + s_ip_hdr_ready_reg <= 1'b0; + s_ip_payload_axis_tready_reg <= 1'b0; + m_udp_hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; error_header_early_termination_reg <= 1'b0; error_payload_early_termination_reg <= 1'b0; @@ -422,10 +422,10 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; - input_ip_hdr_ready_reg <= input_ip_hdr_ready_next; - input_ip_payload_tready_reg <= input_ip_payload_tready_next; + s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; + s_ip_payload_axis_tready_reg <= s_ip_payload_axis_tready_next; - output_udp_hdr_valid_reg <= output_udp_hdr_valid_next; + m_udp_hdr_valid_reg <= m_udp_hdr_valid_next; error_header_early_termination_reg <= error_header_early_termination_next; error_payload_early_termination_reg <= error_payload_early_termination_next; @@ -435,125 +435,125 @@ always @(posedge clk) begin // datapath if (store_ip_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - output_ip_version_reg <= input_ip_version; - output_ip_ihl_reg <= input_ip_ihl; - output_ip_dscp_reg <= input_ip_dscp; - output_ip_ecn_reg <= input_ip_ecn; - output_ip_length_reg <= input_ip_length; - output_ip_identification_reg <= input_ip_identification; - output_ip_flags_reg <= input_ip_flags; - output_ip_fragment_offset_reg <= input_ip_fragment_offset; - output_ip_ttl_reg <= input_ip_ttl; - output_ip_protocol_reg <= input_ip_protocol; - output_ip_header_checksum_reg <= input_ip_header_checksum; - output_ip_source_ip_reg <= input_ip_source_ip; - output_ip_dest_ip_reg <= input_ip_dest_ip; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; + m_ip_version_reg <= s_ip_version; + m_ip_ihl_reg <= s_ip_ihl; + m_ip_dscp_reg <= s_ip_dscp; + m_ip_ecn_reg <= s_ip_ecn; + m_ip_length_reg <= s_ip_length; + m_ip_identification_reg <= s_ip_identification; + m_ip_flags_reg <= s_ip_flags; + m_ip_fragment_offset_reg <= s_ip_fragment_offset; + m_ip_ttl_reg <= s_ip_ttl; + m_ip_protocol_reg <= s_ip_protocol; + m_ip_header_checksum_reg <= s_ip_header_checksum; + m_ip_source_ip_reg <= s_ip_source_ip; + m_ip_dest_ip_reg <= s_ip_dest_ip; end if (store_last_word) begin - last_word_data_reg <= output_udp_payload_tdata_int; - last_word_keep_reg <= output_udp_payload_tkeep_int; + last_word_data_reg <= m_udp_payload_axis_tdata_int; + last_word_keep_reg <= m_udp_payload_axis_tkeep_int; end if (store_hdr_word_0) begin - output_udp_source_port_reg[15: 8] <= input_ip_payload_tdata[ 7: 0]; - output_udp_source_port_reg[ 7: 0] <= input_ip_payload_tdata[15: 8]; - output_udp_dest_port_reg[15: 8] <= input_ip_payload_tdata[23:16]; - output_udp_dest_port_reg[ 7: 0] <= input_ip_payload_tdata[31:24]; - output_udp_length_reg[15: 8] <= input_ip_payload_tdata[39:32]; - output_udp_length_reg[ 7: 0] <= input_ip_payload_tdata[47:40]; - output_udp_checksum_reg[15: 8] <= input_ip_payload_tdata[55:48]; - output_udp_checksum_reg[ 7: 0] <= input_ip_payload_tdata[63:56]; + m_udp_source_port_reg[15: 8] <= s_ip_payload_axis_tdata[ 7: 0]; + m_udp_source_port_reg[ 7: 0] <= s_ip_payload_axis_tdata[15: 8]; + m_udp_dest_port_reg[15: 8] <= s_ip_payload_axis_tdata[23:16]; + m_udp_dest_port_reg[ 7: 0] <= s_ip_payload_axis_tdata[31:24]; + m_udp_length_reg[15: 8] <= s_ip_payload_axis_tdata[39:32]; + m_udp_length_reg[ 7: 0] <= s_ip_payload_axis_tdata[47:40]; + m_udp_checksum_reg[15: 8] <= s_ip_payload_axis_tdata[55:48]; + m_udp_checksum_reg[ 7: 0] <= s_ip_payload_axis_tdata[63:56]; end end // output datapath logic -reg [63:0] output_udp_payload_tdata_reg = 64'd0; -reg [7:0] output_udp_payload_tkeep_reg = 8'd0; -reg output_udp_payload_tvalid_reg = 1'b0, output_udp_payload_tvalid_next; -reg output_udp_payload_tlast_reg = 1'b0; -reg output_udp_payload_tuser_reg = 1'b0; +reg [63:0] m_udp_payload_axis_tdata_reg = 64'd0; +reg [7:0] m_udp_payload_axis_tkeep_reg = 8'd0; +reg m_udp_payload_axis_tvalid_reg = 1'b0, m_udp_payload_axis_tvalid_next; +reg m_udp_payload_axis_tlast_reg = 1'b0; +reg m_udp_payload_axis_tuser_reg = 1'b0; -reg [63:0] temp_udp_payload_tdata_reg = 64'd0; -reg [7:0] temp_udp_payload_tkeep_reg = 8'd0; -reg temp_udp_payload_tvalid_reg = 1'b0, temp_udp_payload_tvalid_next; -reg temp_udp_payload_tlast_reg = 1'b0; -reg temp_udp_payload_tuser_reg = 1'b0; +reg [63:0] temp_m_udp_payload_axis_tdata_reg = 64'd0; +reg [7:0] temp_m_udp_payload_axis_tkeep_reg = 8'd0; +reg temp_m_udp_payload_axis_tvalid_reg = 1'b0, temp_m_udp_payload_axis_tvalid_next; +reg temp_m_udp_payload_axis_tlast_reg = 1'b0; +reg temp_m_udp_payload_axis_tuser_reg = 1'b0; // datapath control reg store_udp_payload_int_to_output; reg store_udp_payload_int_to_temp; -reg store_udp_payload_temp_to_output; +reg store_udp_payload_axis_temp_to_output; -assign output_udp_payload_tdata = output_udp_payload_tdata_reg; -assign output_udp_payload_tkeep = output_udp_payload_tkeep_reg; -assign output_udp_payload_tvalid = output_udp_payload_tvalid_reg; -assign output_udp_payload_tlast = output_udp_payload_tlast_reg; -assign output_udp_payload_tuser = output_udp_payload_tuser_reg; +assign m_udp_payload_axis_tdata = m_udp_payload_axis_tdata_reg; +assign m_udp_payload_axis_tkeep = m_udp_payload_axis_tkeep_reg; +assign m_udp_payload_axis_tvalid = m_udp_payload_axis_tvalid_reg; +assign m_udp_payload_axis_tlast = m_udp_payload_axis_tlast_reg; +assign m_udp_payload_axis_tuser = m_udp_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_udp_payload_tready_int_early = output_udp_payload_tready | (~temp_udp_payload_tvalid_reg & (~output_udp_payload_tvalid_reg | ~output_udp_payload_tvalid_int)); +assign m_udp_payload_axis_tready_int_early = m_udp_payload_axis_tready || (!temp_m_udp_payload_axis_tvalid_reg && (!m_udp_payload_axis_tvalid_reg || !m_udp_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_udp_payload_tvalid_next = output_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; + m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_reg; + temp_m_udp_payload_axis_tvalid_next = temp_m_udp_payload_axis_tvalid_reg; store_udp_payload_int_to_output = 1'b0; store_udp_payload_int_to_temp = 1'b0; - store_udp_payload_temp_to_output = 1'b0; + store_udp_payload_axis_temp_to_output = 1'b0; - if (output_udp_payload_tready_int_reg) begin + if (m_udp_payload_axis_tready_int_reg) begin // input is ready - if (output_udp_payload_tready | ~output_udp_payload_tvalid_reg) begin + if (m_udp_payload_axis_tready || !m_udp_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_int; store_udp_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_udp_payload_tvalid_next = output_udp_payload_tvalid_int; + temp_m_udp_payload_axis_tvalid_next = m_udp_payload_axis_tvalid_int; store_udp_payload_int_to_temp = 1'b1; end - end else if (output_udp_payload_tready) begin + end else if (m_udp_payload_axis_tready) begin // input is not ready, but output is ready - output_udp_payload_tvalid_next = temp_udp_payload_tvalid_reg; - temp_udp_payload_tvalid_next = 1'b0; - store_udp_payload_temp_to_output = 1'b1; + m_udp_payload_axis_tvalid_next = temp_m_udp_payload_axis_tvalid_reg; + temp_m_udp_payload_axis_tvalid_next = 1'b0; + store_udp_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_udp_payload_tvalid_reg <= 1'b0; - output_udp_payload_tready_int_reg <= 1'b0; - temp_udp_payload_tvalid_reg <= 1'b0; + m_udp_payload_axis_tvalid_reg <= 1'b0; + m_udp_payload_axis_tready_int_reg <= 1'b0; + temp_m_udp_payload_axis_tvalid_reg <= 1'b0; end else begin - output_udp_payload_tvalid_reg <= output_udp_payload_tvalid_next; - output_udp_payload_tready_int_reg <= output_udp_payload_tready_int_early; - temp_udp_payload_tvalid_reg <= temp_udp_payload_tvalid_next; + m_udp_payload_axis_tvalid_reg <= m_udp_payload_axis_tvalid_next; + m_udp_payload_axis_tready_int_reg <= m_udp_payload_axis_tready_int_early; + temp_m_udp_payload_axis_tvalid_reg <= temp_m_udp_payload_axis_tvalid_next; end // datapath if (store_udp_payload_int_to_output) begin - output_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - output_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - output_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - output_udp_payload_tuser_reg <= output_udp_payload_tuser_int; - end else if (store_udp_payload_temp_to_output) begin - output_udp_payload_tdata_reg <= temp_udp_payload_tdata_reg; - output_udp_payload_tkeep_reg <= temp_udp_payload_tkeep_reg; - output_udp_payload_tlast_reg <= temp_udp_payload_tlast_reg; - output_udp_payload_tuser_reg <= temp_udp_payload_tuser_reg; + m_udp_payload_axis_tdata_reg <= m_udp_payload_axis_tdata_int; + m_udp_payload_axis_tkeep_reg <= m_udp_payload_axis_tkeep_int; + m_udp_payload_axis_tlast_reg <= m_udp_payload_axis_tlast_int; + m_udp_payload_axis_tuser_reg <= m_udp_payload_axis_tuser_int; + end else if (store_udp_payload_axis_temp_to_output) begin + m_udp_payload_axis_tdata_reg <= temp_m_udp_payload_axis_tdata_reg; + m_udp_payload_axis_tkeep_reg <= temp_m_udp_payload_axis_tkeep_reg; + m_udp_payload_axis_tlast_reg <= temp_m_udp_payload_axis_tlast_reg; + m_udp_payload_axis_tuser_reg <= temp_m_udp_payload_axis_tuser_reg; end if (store_udp_payload_int_to_temp) begin - temp_udp_payload_tdata_reg <= output_udp_payload_tdata_int; - temp_udp_payload_tkeep_reg <= output_udp_payload_tkeep_int; - temp_udp_payload_tlast_reg <= output_udp_payload_tlast_int; - temp_udp_payload_tuser_reg <= output_udp_payload_tuser_int; + temp_m_udp_payload_axis_tdata_reg <= m_udp_payload_axis_tdata_int; + temp_m_udp_payload_axis_tkeep_reg <= m_udp_payload_axis_tkeep_int; + temp_m_udp_payload_axis_tlast_reg <= m_udp_payload_axis_tlast_int; + temp_m_udp_payload_axis_tuser_reg <= m_udp_payload_axis_tuser_int; end end diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index 5de078593..469becb68 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -37,59 +37,59 @@ module udp_ip_tx /* * UDP frame input */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [15:0] input_udp_length, - input wire [15:0] input_udp_checksum, - input wire [7:0] input_udp_payload_tdata, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, + input wire s_udp_hdr_valid, + output wire s_udp_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [3:0] s_ip_version, + input wire [3:0] s_ip_ihl, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [15:0] s_ip_header_checksum, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [15:0] s_udp_source_port, + input wire [15:0] s_udp_dest_port, + input wire [15:0] s_udp_length, + input wire [15:0] s_udp_checksum, + input wire [7:0] s_udp_payload_axis_tdata, + input wire s_udp_payload_axis_tvalid, + output wire s_udp_payload_axis_tready, + input wire s_udp_payload_axis_tlast, + input wire s_udp_payload_axis_tuser, /* * IP frame output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [7:0] output_ip_payload_tdata, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [7:0] m_ip_payload_axis_tdata, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * Status signals @@ -156,58 +156,58 @@ reg [15:0] udp_dest_port_reg = 16'd0; reg [15:0] udp_length_reg = 16'd0; reg [15:0] udp_checksum_reg = 16'd0; -reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; +reg s_udp_hdr_ready_reg = 1'b0, s_udp_hdr_ready_next; +reg s_udp_payload_axis_tready_reg = 1'b0, s_udp_payload_axis_tready_next; -reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; -reg [3:0] output_ip_version_reg = 4'd0; -reg [3:0] output_ip_ihl_reg = 4'd0; -reg [5:0] output_ip_dscp_reg = 6'd0; -reg [1:0] output_ip_ecn_reg = 2'd0; -reg [15:0] output_ip_length_reg = 16'd0; -reg [15:0] output_ip_identification_reg = 16'd0; -reg [2:0] output_ip_flags_reg = 3'd0; -reg [12:0] output_ip_fragment_offset_reg = 13'd0; -reg [7:0] output_ip_ttl_reg = 8'd0; -reg [7:0] output_ip_protocol_reg = 8'd0; -reg [15:0] output_ip_header_checksum_reg = 16'd0; -reg [31:0] output_ip_source_ip_reg = 32'd0; -reg [31:0] output_ip_dest_ip_reg = 32'd0; +reg m_ip_hdr_valid_reg = 1'b0, m_ip_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; +reg [3:0] m_ip_version_reg = 4'd0; +reg [3:0] m_ip_ihl_reg = 4'd0; +reg [5:0] m_ip_dscp_reg = 6'd0; +reg [1:0] m_ip_ecn_reg = 2'd0; +reg [15:0] m_ip_length_reg = 16'd0; +reg [15:0] m_ip_identification_reg = 16'd0; +reg [2:0] m_ip_flags_reg = 3'd0; +reg [12:0] m_ip_fragment_offset_reg = 13'd0; +reg [7:0] m_ip_ttl_reg = 8'd0; +reg [7:0] m_ip_protocol_reg = 8'd0; +reg [15:0] m_ip_header_checksum_reg = 16'd0; +reg [31:0] m_ip_source_ip_reg = 32'd0; +reg [31:0] m_ip_dest_ip_reg = 32'd0; reg busy_reg = 1'b0; reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; // internal datapath -reg [7:0] output_ip_payload_tdata_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; +reg [7:0] m_ip_payload_axis_tdata_int; +reg m_ip_payload_axis_tvalid_int; +reg m_ip_payload_axis_tready_int_reg = 1'b0; +reg m_ip_payload_axis_tlast_int; +reg m_ip_payload_axis_tuser_int; +wire m_ip_payload_axis_tready_int_early; -assign input_udp_hdr_ready = input_udp_hdr_ready_reg; -assign input_udp_payload_tready = input_udp_payload_tready_reg; +assign s_udp_hdr_ready = s_udp_hdr_ready_reg; +assign s_udp_payload_axis_tready = s_udp_payload_axis_tready_reg; -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign m_ip_hdr_valid = m_ip_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_ip_length_reg; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = m_ip_protocol_reg; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; assign busy = busy_reg; assign error_payload_early_termination = error_payload_early_termination_reg; @@ -215,8 +215,8 @@ assign error_payload_early_termination = error_payload_early_termination_reg; always @* begin state_next = STATE_IDLE; - input_udp_hdr_ready_next = 1'b0; - input_udp_payload_tready_next = 1'b0; + s_udp_hdr_ready_next = 1'b0; + s_udp_payload_axis_tready_next = 1'b0; store_udp_hdr = 1'b0; @@ -224,28 +224,28 @@ always @* begin frame_ptr_next = frame_ptr_reg; - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + m_ip_hdr_valid_next = m_ip_hdr_valid_reg && !m_ip_hdr_ready; error_payload_early_termination_next = 1'b0; - output_ip_payload_tdata_int = 8'd0; - output_ip_payload_tvalid_int = 1'b0; - output_ip_payload_tlast_int = 1'b0; - output_ip_payload_tuser_int = 1'b0; + m_ip_payload_axis_tdata_int = 8'd0; + m_ip_payload_axis_tvalid_int = 1'b0; + m_ip_payload_axis_tlast_int = 1'b0; + m_ip_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 16'd0; - input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; - if (input_udp_hdr_ready & input_udp_hdr_valid) begin + if (s_udp_hdr_ready && s_udp_hdr_valid) begin store_udp_hdr = 1'b1; - input_udp_hdr_ready_next = 1'b0; - output_ip_hdr_valid_next = 1'b1; - if (output_ip_payload_tready_int_reg) begin - output_ip_payload_tvalid_int = 1'b1; - output_ip_payload_tdata_int = input_udp_source_port[15: 8]; + s_udp_hdr_ready_next = 1'b0; + m_ip_hdr_valid_next = 1'b1; + if (m_ip_payload_axis_tready_int_reg) begin + m_ip_payload_axis_tvalid_int = 1'b1; + m_ip_payload_axis_tdata_int = s_udp_source_port[15: 8]; frame_ptr_next = 1'b1; end state_next = STATE_WRITE_HEADER; @@ -255,22 +255,22 @@ always @* begin end STATE_WRITE_HEADER: begin // write header state - if (output_ip_payload_tready_int_reg) begin + if (m_ip_payload_axis_tready_int_reg) begin // word transfer out frame_ptr_next = frame_ptr_reg + 16'd1; - output_ip_payload_tvalid_int = 1'b1; + m_ip_payload_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) - 8'h00: output_ip_payload_tdata_int = input_udp_source_port[15: 8]; - 8'h01: output_ip_payload_tdata_int = udp_source_port_reg[ 7: 0]; - 8'h02: output_ip_payload_tdata_int = udp_dest_port_reg[15: 8]; - 8'h03: output_ip_payload_tdata_int = udp_dest_port_reg[ 7: 0]; - 8'h04: output_ip_payload_tdata_int = udp_length_reg[15: 8]; - 8'h05: output_ip_payload_tdata_int = udp_length_reg[ 7: 0]; - 8'h06: output_ip_payload_tdata_int = udp_checksum_reg[15: 8]; + 8'h00: m_ip_payload_axis_tdata_int = s_udp_source_port[15: 8]; + 8'h01: m_ip_payload_axis_tdata_int = udp_source_port_reg[ 7: 0]; + 8'h02: m_ip_payload_axis_tdata_int = udp_dest_port_reg[15: 8]; + 8'h03: m_ip_payload_axis_tdata_int = udp_dest_port_reg[ 7: 0]; + 8'h04: m_ip_payload_axis_tdata_int = udp_length_reg[15: 8]; + 8'h05: m_ip_payload_axis_tdata_int = udp_length_reg[ 7: 0]; + 8'h06: m_ip_payload_axis_tdata_int = udp_checksum_reg[15: 8]; 8'h07: begin - output_ip_payload_tdata_int = udp_checksum_reg[ 7: 0]; - input_udp_payload_tready_next = output_ip_payload_tready_int_early; + m_ip_payload_axis_tdata_int = udp_checksum_reg[ 7: 0]; + s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; state_next = STATE_WRITE_PAYLOAD; end endcase @@ -280,29 +280,29 @@ always @* begin end STATE_WRITE_PAYLOAD: begin // write payload - input_udp_payload_tready_next = output_ip_payload_tready_int_early; + s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; - output_ip_payload_tdata_int = input_udp_payload_tdata; - output_ip_payload_tvalid_int = input_udp_payload_tvalid; - output_ip_payload_tlast_int = input_udp_payload_tlast; - output_ip_payload_tuser_int = input_udp_payload_tuser; + m_ip_payload_axis_tdata_int = s_udp_payload_axis_tdata; + m_ip_payload_axis_tvalid_int = s_udp_payload_axis_tvalid; + m_ip_payload_axis_tlast_int = s_udp_payload_axis_tlast; + m_ip_payload_axis_tuser_int = s_udp_payload_axis_tuser; - if (input_udp_payload_tready & input_udp_payload_tvalid) begin + if (s_udp_payload_axis_tready && s_udp_payload_axis_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg + 16'd1; - if (input_udp_payload_tlast) begin + if (s_udp_payload_axis_tlast) begin if (frame_ptr_next != udp_length_reg) begin // end of frame, but length does not match - output_ip_payload_tuser_int = 1'b1; + m_ip_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; end - input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_udp_payload_tready_next = 1'b0; + s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin if (frame_ptr_next == udp_length_reg) begin store_last_word = 1'b1; - output_ip_payload_tvalid_int = 1'b0; + m_ip_payload_axis_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -314,17 +314,17 @@ always @* begin end STATE_WRITE_PAYLOAD_LAST: begin // read and discard until end of frame - input_udp_payload_tready_next = output_ip_payload_tready_int_early; + s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; - output_ip_payload_tdata_int = last_word_data_reg; - output_ip_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tlast; - output_ip_payload_tlast_int = input_udp_payload_tlast; - output_ip_payload_tuser_int = input_udp_payload_tuser; + m_ip_payload_axis_tdata_int = last_word_data_reg; + m_ip_payload_axis_tvalid_int = s_udp_payload_axis_tvalid && s_udp_payload_axis_tlast; + m_ip_payload_axis_tlast_int = s_udp_payload_axis_tlast; + m_ip_payload_axis_tuser_int = s_udp_payload_axis_tuser; - if (input_udp_payload_tready & input_udp_payload_tvalid) begin - if (input_udp_payload_tlast) begin - input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_udp_payload_tready_next = 1'b0; + if (s_udp_payload_axis_tready && s_udp_payload_axis_tvalid) begin + if (s_udp_payload_axis_tlast) begin + s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD_LAST; @@ -335,12 +335,12 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_udp_payload_tready_next = 1'b1; + s_udp_payload_axis_tready_next = 1'b1; - if (input_udp_payload_tvalid) begin - if (input_udp_payload_tlast) begin - input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_udp_payload_tready_next = 1'b0; + if (s_udp_payload_axis_tvalid) begin + if (s_udp_payload_axis_tlast) begin + s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -356,9 +356,9 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 16'd0; - input_udp_hdr_ready_reg <= 1'b0; - input_udp_payload_tready_reg <= 1'b0; - output_ip_hdr_valid_reg <= 1'b0; + s_udp_hdr_ready_reg <= 1'b0; + s_udp_payload_axis_tready_reg <= 1'b0; + m_ip_hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; error_payload_early_termination_reg <= 1'b0; end else begin @@ -366,10 +366,10 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; - input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; - input_udp_payload_tready_reg <= input_udp_payload_tready_next; + s_udp_hdr_ready_reg <= s_udp_hdr_ready_next; + s_udp_payload_axis_tready_reg <= s_udp_payload_axis_tready_next; - output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + m_ip_hdr_valid_reg <= m_ip_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; @@ -378,111 +378,111 @@ always @(posedge clk) begin // datapath if (store_udp_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - output_ip_version_reg <= input_ip_version; - output_ip_ihl_reg <= input_ip_ihl; - output_ip_dscp_reg <= input_ip_dscp; - output_ip_ecn_reg <= input_ip_ecn; - output_ip_length_reg <= input_udp_length + 20; - output_ip_identification_reg <= input_ip_identification; - output_ip_flags_reg <= input_ip_flags; - output_ip_fragment_offset_reg <= input_ip_fragment_offset; - output_ip_ttl_reg <= input_ip_ttl; - output_ip_protocol_reg <= input_ip_protocol; - output_ip_header_checksum_reg <= input_ip_header_checksum; - output_ip_source_ip_reg <= input_ip_source_ip; - output_ip_dest_ip_reg <= input_ip_dest_ip; - udp_source_port_reg <= input_udp_source_port; - udp_dest_port_reg <= input_udp_dest_port; - udp_length_reg <= input_udp_length; - udp_checksum_reg <= input_udp_checksum; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; + m_ip_version_reg <= s_ip_version; + m_ip_ihl_reg <= s_ip_ihl; + m_ip_dscp_reg <= s_ip_dscp; + m_ip_ecn_reg <= s_ip_ecn; + m_ip_length_reg <= s_udp_length + 20; + m_ip_identification_reg <= s_ip_identification; + m_ip_flags_reg <= s_ip_flags; + m_ip_fragment_offset_reg <= s_ip_fragment_offset; + m_ip_ttl_reg <= s_ip_ttl; + m_ip_protocol_reg <= s_ip_protocol; + m_ip_header_checksum_reg <= s_ip_header_checksum; + m_ip_source_ip_reg <= s_ip_source_ip; + m_ip_dest_ip_reg <= s_ip_dest_ip; + udp_source_port_reg <= s_udp_source_port; + udp_dest_port_reg <= s_udp_dest_port; + udp_length_reg <= s_udp_length; + udp_checksum_reg <= s_udp_checksum; end if (store_last_word) begin - last_word_data_reg <= output_ip_payload_tdata_int; + last_word_data_reg <= m_ip_payload_axis_tdata_int; end end // output datapath logic -reg [7:0] output_ip_payload_tdata_reg = 8'd0; -reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; +reg [7:0] m_ip_payload_axis_tdata_reg = 8'd0; +reg m_ip_payload_axis_tvalid_reg = 1'b0, m_ip_payload_axis_tvalid_next; +reg m_ip_payload_axis_tlast_reg = 1'b0; +reg m_ip_payload_axis_tuser_reg = 1'b0; -reg [7:0] temp_ip_payload_tdata_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; +reg [7:0] temp_m_ip_payload_axis_tdata_reg = 8'd0; +reg temp_m_ip_payload_axis_tvalid_reg = 1'b0, temp_m_ip_payload_axis_tvalid_next; +reg temp_m_ip_payload_axis_tlast_reg = 1'b0; +reg temp_m_ip_payload_axis_tuser_reg = 1'b0; // datapath control reg store_ip_payload_int_to_output; reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; +reg store_ip_payload_axis_temp_to_output; -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; +assign m_ip_payload_axis_tdata = m_ip_payload_axis_tdata_reg; +assign m_ip_payload_axis_tvalid = m_ip_payload_axis_tvalid_reg; +assign m_ip_payload_axis_tlast = m_ip_payload_axis_tlast_reg; +assign m_ip_payload_axis_tuser = m_ip_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); +assign m_ip_payload_axis_tready_int_early = m_ip_payload_axis_tready || (!temp_m_ip_payload_axis_tvalid_reg && (!m_ip_payload_axis_tvalid_reg || !m_ip_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; store_ip_payload_int_to_output = 1'b0; store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b0; - if (output_ip_payload_tready_int_reg) begin + if (m_ip_payload_axis_tready_int_reg) begin // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + if (m_ip_payload_axis_tready || !m_ip_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; store_ip_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + temp_m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; store_ip_payload_int_to_temp = 1'b1; end - end else if (output_ip_payload_tready) begin + end else if (m_ip_payload_axis_tready) begin // input is not ready, but output is ready - output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; + m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; + m_ip_payload_axis_tvalid_reg <= 1'b0; + m_ip_payload_axis_tready_int_reg <= 1'b0; + temp_m_ip_payload_axis_tvalid_reg <= 1'b0; end else begin - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + m_ip_payload_axis_tvalid_reg <= m_ip_payload_axis_tvalid_next; + m_ip_payload_axis_tready_int_reg <= m_ip_payload_axis_tready_int_early; + temp_m_ip_payload_axis_tvalid_reg <= temp_m_ip_payload_axis_tvalid_next; end // datapath if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; + end else if (store_ip_payload_axis_temp_to_output) begin + m_ip_payload_axis_tdata_reg <= temp_m_ip_payload_axis_tdata_reg; + m_ip_payload_axis_tlast_reg <= temp_m_ip_payload_axis_tlast_reg; + m_ip_payload_axis_tuser_reg <= temp_m_ip_payload_axis_tuser_reg; end if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + temp_m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + temp_m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + temp_m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; end end diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index 4012eb157..daa9579de 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -37,61 +37,61 @@ module udp_ip_tx_64 /* * UDP frame input */ - input wire input_udp_hdr_valid, - output wire input_udp_hdr_ready, - input wire [47:0] input_eth_dest_mac, - input wire [47:0] input_eth_src_mac, - input wire [15:0] input_eth_type, - input wire [3:0] input_ip_version, - input wire [3:0] input_ip_ihl, - input wire [5:0] input_ip_dscp, - input wire [1:0] input_ip_ecn, - input wire [15:0] input_ip_identification, - input wire [2:0] input_ip_flags, - input wire [12:0] input_ip_fragment_offset, - input wire [7:0] input_ip_ttl, - input wire [7:0] input_ip_protocol, - input wire [15:0] input_ip_header_checksum, - input wire [31:0] input_ip_source_ip, - input wire [31:0] input_ip_dest_ip, - input wire [15:0] input_udp_source_port, - input wire [15:0] input_udp_dest_port, - input wire [15:0] input_udp_length, - input wire [15:0] input_udp_checksum, - input wire [63:0] input_udp_payload_tdata, - input wire [7:0] input_udp_payload_tkeep, - input wire input_udp_payload_tvalid, - output wire input_udp_payload_tready, - input wire input_udp_payload_tlast, - input wire input_udp_payload_tuser, + input wire s_udp_hdr_valid, + output wire s_udp_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [3:0] s_ip_version, + input wire [3:0] s_ip_ihl, + input wire [5:0] s_ip_dscp, + input wire [1:0] s_ip_ecn, + input wire [15:0] s_ip_identification, + input wire [2:0] s_ip_flags, + input wire [12:0] s_ip_fragment_offset, + input wire [7:0] s_ip_ttl, + input wire [7:0] s_ip_protocol, + input wire [15:0] s_ip_header_checksum, + input wire [31:0] s_ip_source_ip, + input wire [31:0] s_ip_dest_ip, + input wire [15:0] s_udp_source_port, + input wire [15:0] s_udp_dest_port, + input wire [15:0] s_udp_length, + input wire [15:0] s_udp_checksum, + input wire [63:0] s_udp_payload_axis_tdata, + input wire [7:0] s_udp_payload_axis_tkeep, + input wire s_udp_payload_axis_tvalid, + output wire s_udp_payload_axis_tready, + input wire s_udp_payload_axis_tlast, + input wire s_udp_payload_axis_tuser, /* * IP frame output */ - output wire output_ip_hdr_valid, - input wire output_ip_hdr_ready, - output wire [47:0] output_eth_dest_mac, - output wire [47:0] output_eth_src_mac, - output wire [15:0] output_eth_type, - output wire [3:0] output_ip_version, - output wire [3:0] output_ip_ihl, - output wire [5:0] output_ip_dscp, - output wire [1:0] output_ip_ecn, - output wire [15:0] output_ip_length, - output wire [15:0] output_ip_identification, - output wire [2:0] output_ip_flags, - output wire [12:0] output_ip_fragment_offset, - output wire [7:0] output_ip_ttl, - output wire [7:0] output_ip_protocol, - output wire [15:0] output_ip_header_checksum, - output wire [31:0] output_ip_source_ip, - output wire [31:0] output_ip_dest_ip, - output wire [63:0] output_ip_payload_tdata, - output wire [7:0] output_ip_payload_tkeep, - output wire output_ip_payload_tvalid, - input wire output_ip_payload_tready, - output wire output_ip_payload_tlast, - output wire output_ip_payload_tuser, + output wire m_ip_hdr_valid, + input wire m_ip_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [3:0] m_ip_version, + output wire [3:0] m_ip_ihl, + output wire [5:0] m_ip_dscp, + output wire [1:0] m_ip_ecn, + output wire [15:0] m_ip_length, + output wire [15:0] m_ip_identification, + output wire [2:0] m_ip_flags, + output wire [12:0] m_ip_fragment_offset, + output wire [7:0] m_ip_ttl, + output wire [7:0] m_ip_protocol, + output wire [15:0] m_ip_header_checksum, + output wire [31:0] m_ip_source_ip, + output wire [31:0] m_ip_dest_ip, + output wire [63:0] m_ip_payload_axis_tdata, + output wire [7:0] m_ip_payload_axis_tkeep, + output wire m_ip_payload_axis_tvalid, + input wire m_ip_payload_axis_tready, + output wire m_ip_payload_axis_tlast, + output wire m_ip_payload_axis_tuser, /* * Status signals @@ -159,59 +159,59 @@ reg [15:0] udp_dest_port_reg = 16'd0; reg [15:0] udp_length_reg = 16'd0; reg [15:0] udp_checksum_reg = 16'd0; -reg input_udp_hdr_ready_reg = 1'b0, input_udp_hdr_ready_next; -reg input_udp_payload_tready_reg = 1'b0, input_udp_payload_tready_next; +reg s_udp_hdr_ready_reg = 1'b0, s_udp_hdr_ready_next; +reg s_udp_payload_axis_tready_reg = 1'b0, s_udp_payload_axis_tready_next; -reg output_ip_hdr_valid_reg = 1'b0, output_ip_hdr_valid_next; -reg [47:0] output_eth_dest_mac_reg = 48'd0; -reg [47:0] output_eth_src_mac_reg = 48'd0; -reg [15:0] output_eth_type_reg = 16'd0; -reg [3:0] output_ip_version_reg = 4'd0; -reg [3:0] output_ip_ihl_reg = 4'd0; -reg [5:0] output_ip_dscp_reg = 6'd0; -reg [1:0] output_ip_ecn_reg = 2'd0; -reg [15:0] output_ip_length_reg = 16'd0; -reg [15:0] output_ip_identification_reg = 16'd0; -reg [2:0] output_ip_flags_reg = 3'd0; -reg [12:0] output_ip_fragment_offset_reg = 13'd0; -reg [7:0] output_ip_ttl_reg = 8'd0; -reg [7:0] output_ip_protocol_reg = 8'd0; -reg [15:0] output_ip_header_checksum_reg = 16'd0; -reg [31:0] output_ip_source_ip_reg = 32'd0; -reg [31:0] output_ip_dest_ip_reg = 32'd0; +reg m_ip_hdr_valid_reg = 1'b0, m_ip_hdr_valid_next; +reg [47:0] m_eth_dest_mac_reg = 48'd0; +reg [47:0] m_eth_src_mac_reg = 48'd0; +reg [15:0] m_eth_type_reg = 16'd0; +reg [3:0] m_ip_version_reg = 4'd0; +reg [3:0] m_ip_ihl_reg = 4'd0; +reg [5:0] m_ip_dscp_reg = 6'd0; +reg [1:0] m_ip_ecn_reg = 2'd0; +reg [15:0] m_ip_length_reg = 16'd0; +reg [15:0] m_ip_identification_reg = 16'd0; +reg [2:0] m_ip_flags_reg = 3'd0; +reg [12:0] m_ip_fragment_offset_reg = 13'd0; +reg [7:0] m_ip_ttl_reg = 8'd0; +reg [7:0] m_ip_protocol_reg = 8'd0; +reg [15:0] m_ip_header_checksum_reg = 16'd0; +reg [31:0] m_ip_source_ip_reg = 32'd0; +reg [31:0] m_ip_dest_ip_reg = 32'd0; reg busy_reg = 1'b0; reg error_payload_early_termination_reg = 1'b0, error_payload_early_termination_next; // internal datapath -reg [63:0] output_ip_payload_tdata_int; -reg [7:0] output_ip_payload_tkeep_int; -reg output_ip_payload_tvalid_int; -reg output_ip_payload_tready_int_reg = 1'b0; -reg output_ip_payload_tlast_int; -reg output_ip_payload_tuser_int; -wire output_ip_payload_tready_int_early; +reg [63:0] m_ip_payload_axis_tdata_int; +reg [7:0] m_ip_payload_axis_tkeep_int; +reg m_ip_payload_axis_tvalid_int; +reg m_ip_payload_axis_tready_int_reg = 1'b0; +reg m_ip_payload_axis_tlast_int; +reg m_ip_payload_axis_tuser_int; +wire m_ip_payload_axis_tready_int_early; -assign input_udp_hdr_ready = input_udp_hdr_ready_reg; -assign input_udp_payload_tready = input_udp_payload_tready_reg; +assign s_udp_hdr_ready = s_udp_hdr_ready_reg; +assign s_udp_payload_axis_tready = s_udp_payload_axis_tready_reg; -assign output_ip_hdr_valid = output_ip_hdr_valid_reg; -assign output_eth_dest_mac = output_eth_dest_mac_reg; -assign output_eth_src_mac = output_eth_src_mac_reg; -assign output_eth_type = output_eth_type_reg; -assign output_ip_version = output_ip_version_reg; -assign output_ip_ihl = output_ip_ihl_reg; -assign output_ip_dscp = output_ip_dscp_reg; -assign output_ip_ecn = output_ip_ecn_reg; -assign output_ip_length = output_ip_length_reg; -assign output_ip_identification = output_ip_identification_reg; -assign output_ip_flags = output_ip_flags_reg; -assign output_ip_fragment_offset = output_ip_fragment_offset_reg; -assign output_ip_ttl = output_ip_ttl_reg; -assign output_ip_protocol = output_ip_protocol_reg; -assign output_ip_header_checksum = output_ip_header_checksum_reg; -assign output_ip_source_ip = output_ip_source_ip_reg; -assign output_ip_dest_ip = output_ip_dest_ip_reg; +assign m_ip_hdr_valid = m_ip_hdr_valid_reg; +assign m_eth_dest_mac = m_eth_dest_mac_reg; +assign m_eth_src_mac = m_eth_src_mac_reg; +assign m_eth_type = m_eth_type_reg; +assign m_ip_version = m_ip_version_reg; +assign m_ip_ihl = m_ip_ihl_reg; +assign m_ip_dscp = m_ip_dscp_reg; +assign m_ip_ecn = m_ip_ecn_reg; +assign m_ip_length = m_ip_length_reg; +assign m_ip_identification = m_ip_identification_reg; +assign m_ip_flags = m_ip_flags_reg; +assign m_ip_fragment_offset = m_ip_fragment_offset_reg; +assign m_ip_ttl = m_ip_ttl_reg; +assign m_ip_protocol = m_ip_protocol_reg; +assign m_ip_header_checksum = m_ip_header_checksum_reg; +assign m_ip_source_ip = m_ip_source_ip_reg; +assign m_ip_dest_ip = m_ip_dest_ip_reg; assign busy = busy_reg; assign error_payload_early_termination = error_payload_early_termination_reg; @@ -249,8 +249,8 @@ endfunction always @* begin state_next = STATE_IDLE; - input_udp_hdr_ready_next = 1'b0; - input_udp_payload_tready_next = 1'b0; + s_udp_hdr_ready_next = 1'b0; + s_udp_payload_axis_tready_next = 1'b0; store_udp_hdr = 1'b0; @@ -258,40 +258,40 @@ always @* begin frame_ptr_next = frame_ptr_reg; - output_ip_hdr_valid_next = output_ip_hdr_valid_reg & ~output_ip_hdr_ready; + m_ip_hdr_valid_next = m_ip_hdr_valid_reg && !m_ip_hdr_ready; error_payload_early_termination_next = 1'b0; - output_ip_payload_tdata_int = 64'd0; - output_ip_payload_tkeep_int = 8'd0; - output_ip_payload_tvalid_int = 1'b0; - output_ip_payload_tlast_int = 1'b0; - output_ip_payload_tuser_int = 1'b0; + m_ip_payload_axis_tdata_int = 64'd0; + m_ip_payload_axis_tkeep_int = 8'd0; + m_ip_payload_axis_tvalid_int = 1'b0; + m_ip_payload_axis_tlast_int = 1'b0; + m_ip_payload_axis_tuser_int = 1'b0; case (state_reg) STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 16'd0; - input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; - if (input_udp_hdr_ready & input_udp_hdr_valid) begin + if (s_udp_hdr_ready && s_udp_hdr_valid) begin store_udp_hdr = 1'b1; - input_udp_hdr_ready_next = 1'b0; - output_ip_hdr_valid_next = 1'b1; + s_udp_hdr_ready_next = 1'b0; + m_ip_hdr_valid_next = 1'b1; state_next = STATE_WRITE_HEADER; - if (output_ip_payload_tready_int_reg) begin - output_ip_payload_tvalid_int = 1'b1; - output_ip_payload_tdata_int[ 7: 0] = input_udp_source_port[15: 8]; - output_ip_payload_tdata_int[15: 8] = input_udp_source_port[ 7: 0]; - output_ip_payload_tdata_int[23:16] = input_udp_dest_port[15: 8]; - output_ip_payload_tdata_int[31:24] = input_udp_dest_port[ 7: 0]; - output_ip_payload_tdata_int[39:32] = input_udp_length[15: 8]; - output_ip_payload_tdata_int[47:40] = input_udp_length[ 7: 0]; - output_ip_payload_tdata_int[55:48] = input_udp_checksum[15: 8]; - output_ip_payload_tdata_int[63:56] = input_udp_checksum[ 7: 0]; - output_ip_payload_tkeep_int = 8'hff; + if (m_ip_payload_axis_tready_int_reg) begin + m_ip_payload_axis_tvalid_int = 1'b1; + m_ip_payload_axis_tdata_int[ 7: 0] = s_udp_source_port[15: 8]; + m_ip_payload_axis_tdata_int[15: 8] = s_udp_source_port[ 7: 0]; + m_ip_payload_axis_tdata_int[23:16] = s_udp_dest_port[15: 8]; + m_ip_payload_axis_tdata_int[31:24] = s_udp_dest_port[ 7: 0]; + m_ip_payload_axis_tdata_int[39:32] = s_udp_length[15: 8]; + m_ip_payload_axis_tdata_int[47:40] = s_udp_length[ 7: 0]; + m_ip_payload_axis_tdata_int[55:48] = s_udp_checksum[15: 8]; + m_ip_payload_axis_tdata_int[63:56] = s_udp_checksum[ 7: 0]; + m_ip_payload_axis_tkeep_int = 8'hff; frame_ptr_next = 16'd8; - input_udp_payload_tready_next = output_ip_payload_tready_int_early; + s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; state_next = STATE_WRITE_PAYLOAD; end end else begin @@ -300,23 +300,23 @@ always @* begin end STATE_WRITE_HEADER: begin // write header state - if (output_ip_payload_tready_int_reg) begin + if (m_ip_payload_axis_tready_int_reg) begin // word transfer out frame_ptr_next = frame_ptr_reg + 16'd8; - output_ip_payload_tvalid_int = 1'b1; + m_ip_payload_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: begin - output_ip_payload_tdata_int[ 7: 0] = input_udp_source_port[15: 8]; - output_ip_payload_tdata_int[15: 8] = input_udp_source_port[ 7: 0]; - output_ip_payload_tdata_int[23:16] = input_udp_dest_port[15: 8]; - output_ip_payload_tdata_int[31:24] = input_udp_dest_port[ 7: 0]; - output_ip_payload_tdata_int[39:32] = input_udp_length[15: 8]; - output_ip_payload_tdata_int[47:40] = input_udp_length[ 7: 0]; - output_ip_payload_tdata_int[55:48] = input_udp_checksum[15: 8]; - output_ip_payload_tdata_int[63:56] = input_udp_checksum[ 7: 0]; - output_ip_payload_tkeep_int = 8'hff; - input_udp_payload_tready_next = output_ip_payload_tready_int_early; + m_ip_payload_axis_tdata_int[ 7: 0] = s_udp_source_port[15: 8]; + m_ip_payload_axis_tdata_int[15: 8] = s_udp_source_port[ 7: 0]; + m_ip_payload_axis_tdata_int[23:16] = s_udp_dest_port[15: 8]; + m_ip_payload_axis_tdata_int[31:24] = s_udp_dest_port[ 7: 0]; + m_ip_payload_axis_tdata_int[39:32] = s_udp_length[15: 8]; + m_ip_payload_axis_tdata_int[47:40] = s_udp_length[ 7: 0]; + m_ip_payload_axis_tdata_int[55:48] = s_udp_checksum[15: 8]; + m_ip_payload_axis_tdata_int[63:56] = s_udp_checksum[ 7: 0]; + m_ip_payload_axis_tkeep_int = 8'hff; + s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; state_next = STATE_WRITE_PAYLOAD; end endcase @@ -326,37 +326,37 @@ always @* begin end STATE_WRITE_PAYLOAD: begin // write payload - input_udp_payload_tready_next = output_ip_payload_tready_int_early; + s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; - output_ip_payload_tdata_int = input_udp_payload_tdata; - output_ip_payload_tkeep_int = input_udp_payload_tkeep; - output_ip_payload_tvalid_int = input_udp_payload_tvalid; - output_ip_payload_tlast_int = input_udp_payload_tlast; - output_ip_payload_tuser_int = input_udp_payload_tuser; + m_ip_payload_axis_tdata_int = s_udp_payload_axis_tdata; + m_ip_payload_axis_tkeep_int = s_udp_payload_axis_tkeep; + m_ip_payload_axis_tvalid_int = s_udp_payload_axis_tvalid; + m_ip_payload_axis_tlast_int = s_udp_payload_axis_tlast; + m_ip_payload_axis_tuser_int = s_udp_payload_axis_tuser; - if (output_ip_payload_tready_int_reg & input_udp_payload_tvalid) begin + if (m_ip_payload_axis_tready_int_reg && s_udp_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+keep2count(input_udp_payload_tkeep); + frame_ptr_next = frame_ptr_reg+keep2count(s_udp_payload_axis_tkeep); if (frame_ptr_next >= udp_length_reg) begin // have entire payload frame_ptr_next = udp_length_reg; - output_ip_payload_tkeep_int = count2keep(udp_length_reg - frame_ptr_reg); - if (input_udp_payload_tlast) begin - input_udp_payload_tready_next = 1'b0; - input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + m_ip_payload_axis_tkeep_int = count2keep(udp_length_reg - frame_ptr_reg); + if (s_udp_payload_axis_tlast) begin + s_udp_payload_axis_tready_next = 1'b0; + s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; state_next = STATE_IDLE; end else begin store_last_word = 1'b1; - output_ip_payload_tvalid_int = 1'b0; + m_ip_payload_axis_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end end else begin - if (input_udp_payload_tlast) begin + if (s_udp_payload_axis_tlast) begin // end of frame, but length does not match error_payload_early_termination_next = 1'b1; - output_ip_payload_tuser_int = 1'b1; - input_udp_payload_tready_next = 1'b0; - input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; + m_ip_payload_axis_tuser_int = 1'b1; + s_udp_payload_axis_tready_next = 1'b0; + s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -368,18 +368,18 @@ always @* begin end STATE_WRITE_PAYLOAD_LAST: begin // read and discard until end of frame - input_udp_payload_tready_next = output_ip_payload_tready_int_early; + s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; - output_ip_payload_tdata_int = last_word_data_reg; - output_ip_payload_tkeep_int = last_word_keep_reg; - output_ip_payload_tvalid_int = input_udp_payload_tvalid & input_udp_payload_tlast; - output_ip_payload_tlast_int = input_udp_payload_tlast; - output_ip_payload_tuser_int = input_udp_payload_tuser; + m_ip_payload_axis_tdata_int = last_word_data_reg; + m_ip_payload_axis_tkeep_int = last_word_keep_reg; + m_ip_payload_axis_tvalid_int = s_udp_payload_axis_tvalid && s_udp_payload_axis_tlast; + m_ip_payload_axis_tlast_int = s_udp_payload_axis_tlast; + m_ip_payload_axis_tuser_int = s_udp_payload_axis_tuser; - if (input_udp_payload_tready & input_udp_payload_tvalid) begin - if (input_udp_payload_tlast) begin - input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_udp_payload_tready_next = 1'b0; + if (s_udp_payload_axis_tready && s_udp_payload_axis_tvalid) begin + if (s_udp_payload_axis_tlast) begin + s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD_LAST; @@ -390,12 +390,12 @@ always @* begin end STATE_WAIT_LAST: begin // wait for end of frame; read and discard - input_udp_payload_tready_next = 1'b1; + s_udp_payload_axis_tready_next = 1'b1; - if (input_udp_payload_tvalid) begin - if (input_udp_payload_tlast) begin - input_udp_hdr_ready_next = ~output_ip_hdr_valid_reg; - input_udp_payload_tready_next = 1'b0; + if (s_udp_payload_axis_tvalid) begin + if (s_udp_payload_axis_tlast) begin + s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; @@ -411,9 +411,9 @@ always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; frame_ptr_reg <= 16'd0; - input_udp_hdr_ready_reg <= 1'b0; - input_udp_payload_tready_reg <= 1'b0; - output_ip_hdr_valid_reg <= 1'b0; + s_udp_hdr_ready_reg <= 1'b0; + s_udp_payload_axis_tready_reg <= 1'b0; + m_ip_hdr_valid_reg <= 1'b0; busy_reg <= 1'b0; error_payload_early_termination_reg <= 1'b0; end else begin @@ -421,10 +421,10 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; - input_udp_hdr_ready_reg <= input_udp_hdr_ready_next; - input_udp_payload_tready_reg <= input_udp_payload_tready_next; + s_udp_hdr_ready_reg <= s_udp_hdr_ready_next; + s_udp_payload_axis_tready_reg <= s_udp_payload_axis_tready_next; - output_ip_hdr_valid_reg <= output_ip_hdr_valid_next; + m_ip_hdr_valid_reg <= m_ip_hdr_valid_next; busy_reg <= state_next != STATE_IDLE; @@ -433,118 +433,118 @@ always @(posedge clk) begin // datapath if (store_udp_hdr) begin - output_eth_dest_mac_reg <= input_eth_dest_mac; - output_eth_src_mac_reg <= input_eth_src_mac; - output_eth_type_reg <= input_eth_type; - output_ip_version_reg <= input_ip_version; - output_ip_ihl_reg <= input_ip_ihl; - output_ip_dscp_reg <= input_ip_dscp; - output_ip_ecn_reg <= input_ip_ecn; - output_ip_length_reg <= input_udp_length + 20; - output_ip_identification_reg <= input_ip_identification; - output_ip_flags_reg <= input_ip_flags; - output_ip_fragment_offset_reg <= input_ip_fragment_offset; - output_ip_ttl_reg <= input_ip_ttl; - output_ip_protocol_reg <= input_ip_protocol; - output_ip_header_checksum_reg <= input_ip_header_checksum; - output_ip_source_ip_reg <= input_ip_source_ip; - output_ip_dest_ip_reg <= input_ip_dest_ip; - udp_source_port_reg <= input_udp_source_port; - udp_dest_port_reg <= input_udp_dest_port; - udp_length_reg <= input_udp_length; - udp_checksum_reg <= input_udp_checksum; + m_eth_dest_mac_reg <= s_eth_dest_mac; + m_eth_src_mac_reg <= s_eth_src_mac; + m_eth_type_reg <= s_eth_type; + m_ip_version_reg <= s_ip_version; + m_ip_ihl_reg <= s_ip_ihl; + m_ip_dscp_reg <= s_ip_dscp; + m_ip_ecn_reg <= s_ip_ecn; + m_ip_length_reg <= s_udp_length + 20; + m_ip_identification_reg <= s_ip_identification; + m_ip_flags_reg <= s_ip_flags; + m_ip_fragment_offset_reg <= s_ip_fragment_offset; + m_ip_ttl_reg <= s_ip_ttl; + m_ip_protocol_reg <= s_ip_protocol; + m_ip_header_checksum_reg <= s_ip_header_checksum; + m_ip_source_ip_reg <= s_ip_source_ip; + m_ip_dest_ip_reg <= s_ip_dest_ip; + udp_source_port_reg <= s_udp_source_port; + udp_dest_port_reg <= s_udp_dest_port; + udp_length_reg <= s_udp_length; + udp_checksum_reg <= s_udp_checksum; end if (store_last_word) begin - last_word_data_reg <= output_ip_payload_tdata_int; - last_word_keep_reg <= output_ip_payload_tkeep_int; + last_word_data_reg <= m_ip_payload_axis_tdata_int; + last_word_keep_reg <= m_ip_payload_axis_tkeep_int; end end // output datapath logic -reg [63:0] output_ip_payload_tdata_reg = 64'd0; -reg [7:0] output_ip_payload_tkeep_reg = 8'd0; -reg output_ip_payload_tvalid_reg = 1'b0, output_ip_payload_tvalid_next; -reg output_ip_payload_tlast_reg = 1'b0; -reg output_ip_payload_tuser_reg = 1'b0; +reg [63:0] m_ip_payload_axis_tdata_reg = 64'd0; +reg [7:0] m_ip_payload_axis_tkeep_reg = 8'd0; +reg m_ip_payload_axis_tvalid_reg = 1'b0, m_ip_payload_axis_tvalid_next; +reg m_ip_payload_axis_tlast_reg = 1'b0; +reg m_ip_payload_axis_tuser_reg = 1'b0; -reg [63:0] temp_ip_payload_tdata_reg = 64'd0; -reg [7:0] temp_ip_payload_tkeep_reg = 8'd0; -reg temp_ip_payload_tvalid_reg = 1'b0, temp_ip_payload_tvalid_next; -reg temp_ip_payload_tlast_reg = 1'b0; -reg temp_ip_payload_tuser_reg = 1'b0; +reg [63:0] temp_m_ip_payload_axis_tdata_reg = 64'd0; +reg [7:0] temp_m_ip_payload_axis_tkeep_reg = 8'd0; +reg temp_m_ip_payload_axis_tvalid_reg = 1'b0, temp_m_ip_payload_axis_tvalid_next; +reg temp_m_ip_payload_axis_tlast_reg = 1'b0; +reg temp_m_ip_payload_axis_tuser_reg = 1'b0; // datapath control reg store_ip_payload_int_to_output; reg store_ip_payload_int_to_temp; -reg store_ip_payload_temp_to_output; +reg store_ip_payload_axis_temp_to_output; -assign output_ip_payload_tdata = output_ip_payload_tdata_reg; -assign output_ip_payload_tkeep = output_ip_payload_tkeep_reg; -assign output_ip_payload_tvalid = output_ip_payload_tvalid_reg; -assign output_ip_payload_tlast = output_ip_payload_tlast_reg; -assign output_ip_payload_tuser = output_ip_payload_tuser_reg; +assign m_ip_payload_axis_tdata = m_ip_payload_axis_tdata_reg; +assign m_ip_payload_axis_tkeep = m_ip_payload_axis_tkeep_reg; +assign m_ip_payload_axis_tvalid = m_ip_payload_axis_tvalid_reg; +assign m_ip_payload_axis_tlast = m_ip_payload_axis_tlast_reg; +assign m_ip_payload_axis_tuser = m_ip_payload_axis_tuser_reg; // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign output_ip_payload_tready_int_early = output_ip_payload_tready | (~temp_ip_payload_tvalid_reg & (~output_ip_payload_tvalid_reg | ~output_ip_payload_tvalid_int)); +assign m_ip_payload_axis_tready_int_early = m_ip_payload_axis_tready || (!temp_m_ip_payload_axis_tvalid_reg && (!m_ip_payload_axis_tvalid_reg || !m_ip_payload_axis_tvalid_int)); always @* begin // transfer sink ready state to source - output_ip_payload_tvalid_next = output_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; store_ip_payload_int_to_output = 1'b0; store_ip_payload_int_to_temp = 1'b0; - store_ip_payload_temp_to_output = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b0; - if (output_ip_payload_tready_int_reg) begin + if (m_ip_payload_axis_tready_int_reg) begin // input is ready - if (output_ip_payload_tready | ~output_ip_payload_tvalid_reg) begin + if (m_ip_payload_axis_tready || !m_ip_payload_axis_tvalid_reg) begin // output is ready or currently not valid, transfer data to output - output_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; store_ip_payload_int_to_output = 1'b1; end else begin // output is not ready, store input in temp - temp_ip_payload_tvalid_next = output_ip_payload_tvalid_int; + temp_m_ip_payload_axis_tvalid_next = m_ip_payload_axis_tvalid_int; store_ip_payload_int_to_temp = 1'b1; end - end else if (output_ip_payload_tready) begin + end else if (m_ip_payload_axis_tready) begin // input is not ready, but output is ready - output_ip_payload_tvalid_next = temp_ip_payload_tvalid_reg; - temp_ip_payload_tvalid_next = 1'b0; - store_ip_payload_temp_to_output = 1'b1; + m_ip_payload_axis_tvalid_next = temp_m_ip_payload_axis_tvalid_reg; + temp_m_ip_payload_axis_tvalid_next = 1'b0; + store_ip_payload_axis_temp_to_output = 1'b1; end end always @(posedge clk) begin if (rst) begin - output_ip_payload_tvalid_reg <= 1'b0; - output_ip_payload_tready_int_reg <= 1'b0; - temp_ip_payload_tvalid_reg <= 1'b0; + m_ip_payload_axis_tvalid_reg <= 1'b0; + m_ip_payload_axis_tready_int_reg <= 1'b0; + temp_m_ip_payload_axis_tvalid_reg <= 1'b0; end else begin - output_ip_payload_tvalid_reg <= output_ip_payload_tvalid_next; - output_ip_payload_tready_int_reg <= output_ip_payload_tready_int_early; - temp_ip_payload_tvalid_reg <= temp_ip_payload_tvalid_next; + m_ip_payload_axis_tvalid_reg <= m_ip_payload_axis_tvalid_next; + m_ip_payload_axis_tready_int_reg <= m_ip_payload_axis_tready_int_early; + temp_m_ip_payload_axis_tvalid_reg <= temp_m_ip_payload_axis_tvalid_next; end // datapath if (store_ip_payload_int_to_output) begin - output_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - output_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - output_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - output_ip_payload_tuser_reg <= output_ip_payload_tuser_int; - end else if (store_ip_payload_temp_to_output) begin - output_ip_payload_tdata_reg <= temp_ip_payload_tdata_reg; - output_ip_payload_tkeep_reg <= temp_ip_payload_tkeep_reg; - output_ip_payload_tlast_reg <= temp_ip_payload_tlast_reg; - output_ip_payload_tuser_reg <= temp_ip_payload_tuser_reg; + m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + m_ip_payload_axis_tkeep_reg <= m_ip_payload_axis_tkeep_int; + m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; + end else if (store_ip_payload_axis_temp_to_output) begin + m_ip_payload_axis_tdata_reg <= temp_m_ip_payload_axis_tdata_reg; + m_ip_payload_axis_tkeep_reg <= temp_m_ip_payload_axis_tkeep_reg; + m_ip_payload_axis_tlast_reg <= temp_m_ip_payload_axis_tlast_reg; + m_ip_payload_axis_tuser_reg <= temp_m_ip_payload_axis_tuser_reg; end if (store_ip_payload_int_to_temp) begin - temp_ip_payload_tdata_reg <= output_ip_payload_tdata_int; - temp_ip_payload_tkeep_reg <= output_ip_payload_tkeep_int; - temp_ip_payload_tlast_reg <= output_ip_payload_tlast_int; - temp_ip_payload_tuser_reg <= output_ip_payload_tuser_int; + temp_m_ip_payload_axis_tdata_reg <= m_ip_payload_axis_tdata_int; + temp_m_ip_payload_axis_tkeep_reg <= m_ip_payload_axis_tkeep_int; + temp_m_ip_payload_axis_tlast_reg <= m_ip_payload_axis_tlast_int; + temp_m_ip_payload_axis_tuser_reg <= m_ip_payload_axis_tuser_int; end end diff --git a/tb/test_arp.py b/tb/test_arp.py index 798b1cae9..ff1cde6ac 100755 --- a/tb/test_arp.py +++ b/tb/test_arp.py @@ -53,17 +53,17 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) arp_request_valid = Signal(bool(0)) arp_request_ip = Signal(intbv(0)[32:]) @@ -76,17 +76,17 @@ def bench(): clear_cache = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) arp_request_ready = Signal(bool(0)) arp_response_valid = Signal(bool(0)) @@ -102,16 +102,16 @@ def bench(): eth_source_logic = eth_source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=eth_source_pause, name='eth_source' ) @@ -121,16 +121,16 @@ def bench(): eth_sink_logic = eth_sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=eth_sink_pause, name='eth_sink' ) @@ -167,27 +167,27 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, arp_request_valid=arp_request_valid, arp_request_ready=arp_request_ready, diff --git a/tb/test_arp.v b/tb/test_arp.v index 416a2b332..463fb53ae 100644 --- a/tb/test_arp.v +++ b/tb/test_arp.v @@ -36,17 +36,17 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [7:0] input_eth_payload_tdata = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [7:0] s_eth_payload_axis_tdata = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; reg arp_request_valid = 0; reg [31:0] arp_request_ip = 0; @@ -59,17 +59,17 @@ reg [31:0] subnet_mask = 0; reg clear_cache = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [7:0] output_eth_payload_tdata; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [7:0] m_eth_payload_axis_tdata; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire arp_request_ready; wire arp_response_valid; @@ -82,16 +82,16 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, arp_request_valid, arp_request_ip, arp_response_ready, @@ -102,16 +102,16 @@ initial begin clear_cache ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, arp_request_ready, arp_response_valid, arp_response_error, @@ -133,27 +133,27 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // ARP requests .arp_request_valid(arp_request_valid), .arp_request_ready(arp_request_ready), diff --git a/tb/test_arp_64.py b/tb/test_arp_64.py index 01d964cf5..4a43a63b0 100755 --- a/tb/test_arp_64.py +++ b/tb/test_arp_64.py @@ -53,18 +53,18 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[64:]) - input_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + s_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) arp_request_valid = Signal(bool(0)) arp_request_ip = Signal(intbv(0)[32:]) @@ -77,18 +77,18 @@ def bench(): clear_cache = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[64:]) - output_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + m_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) arp_request_ready = Signal(bool(0)) arp_response_valid = Signal(bool(0)) @@ -104,17 +104,17 @@ def bench(): eth_source_logic = eth_source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tkeep=input_eth_payload_tkeep, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tkeep=s_eth_payload_axis_tkeep, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=eth_source_pause, name='eth_source' ) @@ -124,17 +124,17 @@ def bench(): eth_sink_logic = eth_sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=eth_sink_pause, name='eth_sink' ) @@ -171,29 +171,29 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tkeep=input_eth_payload_tkeep, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, arp_request_valid=arp_request_valid, arp_request_ready=arp_request_ready, diff --git a/tb/test_arp_64.v b/tb/test_arp_64.v index f1d79721a..1565185f0 100644 --- a/tb/test_arp_64.v +++ b/tb/test_arp_64.v @@ -36,18 +36,18 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [63:0] input_eth_payload_tdata = 0; -reg [7:0] input_eth_payload_tkeep = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [63:0] s_eth_payload_axis_tdata = 0; +reg [7:0] s_eth_payload_axis_tkeep = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; reg arp_request_valid = 0; reg [31:0] arp_request_ip = 0; @@ -60,18 +60,18 @@ reg [31:0] subnet_mask = 0; reg clear_cache = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [63:0] output_eth_payload_tdata; -wire [7:0] output_eth_payload_tkeep; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [63:0] m_eth_payload_axis_tdata; +wire [7:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire arp_request_ready; wire arp_response_valid; @@ -84,17 +84,17 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, arp_request_valid, arp_request_ip, arp_response_ready, @@ -105,17 +105,17 @@ initial begin clear_cache ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, arp_request_ready, arp_response_valid, arp_response_error, @@ -137,29 +137,29 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // ARP requests .arp_request_valid(arp_request_valid), .arp_request_ready(arp_request_ready), diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index e0d8c02a8..e793ef506 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -48,32 +48,32 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) - output_frame_ready = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) + m_frame_ready = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) - output_frame_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_arp_htype = Signal(intbv(0)[16:]) - output_arp_ptype = Signal(intbv(0)[16:]) - output_arp_hlen = Signal(intbv(0)[8:]) - output_arp_plen = Signal(intbv(0)[8:]) - output_arp_oper = Signal(intbv(0)[16:]) - output_arp_sha = Signal(intbv(0)[48:]) - output_arp_spa = Signal(intbv(0)[32:]) - output_arp_tha = Signal(intbv(0)[48:]) - output_arp_tpa = Signal(intbv(0)[32:]) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) + m_frame_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_arp_htype = Signal(intbv(0)[16:]) + m_arp_ptype = Signal(intbv(0)[16:]) + m_arp_hlen = Signal(intbv(0)[8:]) + m_arp_plen = Signal(intbv(0)[8:]) + m_arp_oper = Signal(intbv(0)[16:]) + m_arp_sha = Signal(intbv(0)[48:]) + m_arp_spa = Signal(intbv(0)[32:]) + m_arp_tha = Signal(intbv(0)[48:]) + m_arp_tpa = Signal(intbv(0)[32:]) busy = Signal(bool(0)) error_header_early_termination = Signal(bool(0)) error_invalid_header = Signal(bool(0)) @@ -87,16 +87,16 @@ def bench(): source_logic = source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=source_pause, name='source' ) @@ -106,20 +106,20 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - frame_ready=output_frame_ready, - frame_valid=output_frame_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - arp_htype=output_arp_htype, - arp_ptype=output_arp_ptype, - arp_hlen=output_arp_hlen, - arp_plen=output_arp_plen, - arp_oper=output_arp_oper, - arp_sha=output_arp_sha, - arp_spa=output_arp_spa, - arp_tha=output_arp_tha, - arp_tpa=output_arp_tpa, + frame_ready=m_frame_ready, + frame_valid=m_frame_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + arp_htype=m_arp_htype, + arp_ptype=m_arp_ptype, + arp_hlen=m_arp_hlen, + arp_plen=m_arp_plen, + arp_oper=m_arp_oper, + arp_sha=m_arp_sha, + arp_spa=m_arp_spa, + arp_tha=m_arp_tha, + arp_tpa=m_arp_tpa, pause=sink_pause, name='sink' ) @@ -134,31 +134,31 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_frame_valid=output_frame_valid, - output_frame_ready=output_frame_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_arp_htype=output_arp_htype, - output_arp_ptype=output_arp_ptype, - output_arp_hlen=output_arp_hlen, - output_arp_plen=output_arp_plen, - output_arp_oper=output_arp_oper, - output_arp_sha=output_arp_sha, - output_arp_spa=output_arp_spa, - output_arp_tha=output_arp_tha, - output_arp_tpa=output_arp_tpa, + m_frame_valid=m_frame_valid, + m_frame_ready=m_frame_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_arp_htype=m_arp_htype, + m_arp_ptype=m_arp_ptype, + m_arp_hlen=m_arp_hlen, + m_arp_plen=m_arp_plen, + m_arp_oper=m_arp_oper, + m_arp_sha=m_arp_sha, + m_arp_spa=m_arp_spa, + m_arp_tha=m_arp_tha, + m_arp_tpa=m_arp_tpa, busy=busy, error_header_early_termination=error_header_early_termination, @@ -357,7 +357,7 @@ def bench(): yield clk.posedge yield clk.posedge - while input_eth_payload_tvalid: + while s_eth_payload_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -412,7 +412,7 @@ def bench(): yield clk.posedge yield clk.posedge - while input_eth_payload_tvalid: + while s_eth_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -454,7 +454,7 @@ def bench(): source.send(eth_frame) yield clk.posedge - yield input_eth_payload_tlast.posedge + yield s_eth_payload_axis_tlast.posedge yield clk.posedge yield clk.posedge assert error_header_early_termination @@ -481,7 +481,7 @@ def bench(): source.send(test_frame.build_eth()) yield clk.posedge - yield input_eth_payload_tlast.posedge + yield s_eth_payload_axis_tlast.posedge yield clk.posedge yield clk.posedge assert error_invalid_header @@ -510,7 +510,7 @@ def bench(): source.send(eth_frame) yield clk.posedge - yield input_eth_payload_tlast.posedge + yield s_eth_payload_axis_tlast.posedge yield clk.posedge yield clk.posedge assert sink.empty() diff --git a/tb/test_arp_eth_rx.v b/tb/test_arp_eth_rx.v index 4f2fa860d..dea6e2ff9 100644 --- a/tb/test_arp_eth_rx.v +++ b/tb/test_arp_eth_rx.v @@ -36,32 +36,32 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [7:0] input_eth_payload_tdata = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; -reg output_frame_ready = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [7:0] s_eth_payload_axis_tdata = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; +reg m_frame_ready = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; -wire output_frame_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [15:0] output_arp_htype; -wire [15:0] output_arp_ptype; -wire [7:0] output_arp_hlen; -wire [7:0] output_arp_plen; -wire [15:0] output_arp_oper; -wire [47:0] output_arp_sha; -wire [31:0] output_arp_spa; -wire [47:0] output_arp_tha; -wire [31:0] output_arp_tpa; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; +wire m_frame_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [15:0] m_arp_htype; +wire [15:0] m_arp_ptype; +wire [7:0] m_arp_hlen; +wire [7:0] m_arp_plen; +wire [15:0] m_arp_oper; +wire [47:0] m_arp_sha; +wire [31:0] m_arp_spa; +wire [47:0] m_arp_tha; +wire [31:0] m_arp_tpa; wire busy; wire error_header_early_termination; wire error_invalid_header; @@ -72,32 +72,32 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_frame_ready + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + m_frame_ready ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - output_frame_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_arp_htype, - output_arp_ptype, - output_arp_hlen, - output_arp_plen, - output_arp_oper, - output_arp_sha, - output_arp_spa, - output_arp_tha, - output_arp_tpa, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_frame_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_arp_htype, + m_arp_ptype, + m_arp_hlen, + m_arp_plen, + m_arp_oper, + m_arp_sha, + m_arp_spa, + m_arp_tha, + m_arp_tpa, busy, error_header_early_termination, error_invalid_header @@ -113,31 +113,31 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // ARP frame output - .output_frame_valid(output_frame_valid), - .output_frame_ready(output_frame_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_arp_htype(output_arp_htype), - .output_arp_ptype(output_arp_ptype), - .output_arp_hlen(output_arp_hlen), - .output_arp_plen(output_arp_plen), - .output_arp_oper(output_arp_oper), - .output_arp_sha(output_arp_sha), - .output_arp_spa(output_arp_spa), - .output_arp_tha(output_arp_tha), - .output_arp_tpa(output_arp_tpa), + .m_frame_valid(m_frame_valid), + .m_frame_ready(m_frame_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_arp_htype(m_arp_htype), + .m_arp_ptype(m_arp_ptype), + .m_arp_hlen(m_arp_hlen), + .m_arp_plen(m_arp_plen), + .m_arp_oper(m_arp_oper), + .m_arp_sha(m_arp_sha), + .m_arp_spa(m_arp_spa), + .m_arp_tha(m_arp_tha), + .m_arp_tpa(m_arp_tpa), // Status signals .busy(busy), .error_header_early_termination(error_header_early_termination), diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index 17e5ec51e..998a6f007 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -48,33 +48,33 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[64:]) - input_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) - output_frame_ready = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + s_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) + m_frame_ready = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) - output_frame_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_arp_htype = Signal(intbv(0)[16:]) - output_arp_ptype = Signal(intbv(0)[16:]) - output_arp_hlen = Signal(intbv(0)[8:]) - output_arp_plen = Signal(intbv(0)[8:]) - output_arp_oper = Signal(intbv(0)[16:]) - output_arp_sha = Signal(intbv(0)[48:]) - output_arp_spa = Signal(intbv(0)[32:]) - output_arp_tha = Signal(intbv(0)[48:]) - output_arp_tpa = Signal(intbv(0)[32:]) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) + m_frame_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_arp_htype = Signal(intbv(0)[16:]) + m_arp_ptype = Signal(intbv(0)[16:]) + m_arp_hlen = Signal(intbv(0)[8:]) + m_arp_plen = Signal(intbv(0)[8:]) + m_arp_oper = Signal(intbv(0)[16:]) + m_arp_sha = Signal(intbv(0)[48:]) + m_arp_spa = Signal(intbv(0)[32:]) + m_arp_tha = Signal(intbv(0)[48:]) + m_arp_tpa = Signal(intbv(0)[32:]) busy = Signal(bool(0)) error_header_early_termination = Signal(bool(0)) error_invalid_header = Signal(bool(0)) @@ -88,17 +88,17 @@ def bench(): source_logic = source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tkeep=input_eth_payload_tkeep, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tkeep=s_eth_payload_axis_tkeep, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=source_pause, name='source' ) @@ -108,20 +108,20 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - frame_ready=output_frame_ready, - frame_valid=output_frame_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - arp_htype=output_arp_htype, - arp_ptype=output_arp_ptype, - arp_hlen=output_arp_hlen, - arp_plen=output_arp_plen, - arp_oper=output_arp_oper, - arp_sha=output_arp_sha, - arp_spa=output_arp_spa, - arp_tha=output_arp_tha, - arp_tpa=output_arp_tpa, + frame_ready=m_frame_ready, + frame_valid=m_frame_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + arp_htype=m_arp_htype, + arp_ptype=m_arp_ptype, + arp_hlen=m_arp_hlen, + arp_plen=m_arp_plen, + arp_oper=m_arp_oper, + arp_sha=m_arp_sha, + arp_spa=m_arp_spa, + arp_tha=m_arp_tha, + arp_tpa=m_arp_tpa, pause=sink_pause, name='sink' ) @@ -136,32 +136,32 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tkeep=input_eth_payload_tkeep, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_frame_valid=output_frame_valid, - output_frame_ready=output_frame_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_arp_htype=output_arp_htype, - output_arp_ptype=output_arp_ptype, - output_arp_hlen=output_arp_hlen, - output_arp_plen=output_arp_plen, - output_arp_oper=output_arp_oper, - output_arp_sha=output_arp_sha, - output_arp_spa=output_arp_spa, - output_arp_tha=output_arp_tha, - output_arp_tpa=output_arp_tpa, + m_frame_valid=m_frame_valid, + m_frame_ready=m_frame_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_arp_htype=m_arp_htype, + m_arp_ptype=m_arp_ptype, + m_arp_hlen=m_arp_hlen, + m_arp_plen=m_arp_plen, + m_arp_oper=m_arp_oper, + m_arp_sha=m_arp_sha, + m_arp_spa=m_arp_spa, + m_arp_tha=m_arp_tha, + m_arp_tpa=m_arp_tpa, busy=busy, error_header_early_termination=error_header_early_termination, @@ -360,7 +360,7 @@ def bench(): yield clk.posedge yield clk.posedge - while input_eth_payload_tvalid: + while s_eth_payload_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -415,7 +415,7 @@ def bench(): yield clk.posedge yield clk.posedge - while input_eth_payload_tvalid: + while s_eth_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge @@ -457,7 +457,7 @@ def bench(): source.send(eth_frame) yield clk.posedge - yield input_eth_payload_tlast.posedge + yield s_eth_payload_axis_tlast.posedge yield clk.posedge yield clk.posedge assert error_header_early_termination @@ -484,7 +484,7 @@ def bench(): source.send(test_frame.build_eth()) yield clk.posedge - yield input_eth_payload_tlast.posedge + yield s_eth_payload_axis_tlast.posedge yield clk.posedge yield clk.posedge assert error_invalid_header @@ -513,7 +513,7 @@ def bench(): source.send(eth_frame) yield clk.posedge - yield input_eth_payload_tlast.posedge + yield s_eth_payload_axis_tlast.posedge yield clk.posedge yield clk.posedge assert sink.empty() diff --git a/tb/test_arp_eth_rx_64.v b/tb/test_arp_eth_rx_64.v index 5e9194654..00b4b6a79 100644 --- a/tb/test_arp_eth_rx_64.v +++ b/tb/test_arp_eth_rx_64.v @@ -36,33 +36,33 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [63:0] input_eth_payload_tdata = 0; -reg [7:0] input_eth_payload_tkeep = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; -reg output_frame_ready = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [63:0] s_eth_payload_axis_tdata = 0; +reg [7:0] s_eth_payload_axis_tkeep = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; +reg m_frame_ready = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; -wire output_frame_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [15:0] output_arp_htype; -wire [15:0] output_arp_ptype; -wire [7:0] output_arp_hlen; -wire [7:0] output_arp_plen; -wire [15:0] output_arp_oper; -wire [47:0] output_arp_sha; -wire [31:0] output_arp_spa; -wire [47:0] output_arp_tha; -wire [31:0] output_arp_tpa; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; +wire m_frame_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [15:0] m_arp_htype; +wire [15:0] m_arp_ptype; +wire [7:0] m_arp_hlen; +wire [7:0] m_arp_plen; +wire [15:0] m_arp_oper; +wire [47:0] m_arp_sha; +wire [31:0] m_arp_spa; +wire [47:0] m_arp_tha; +wire [31:0] m_arp_tpa; wire busy; wire error_header_early_termination; wire error_invalid_header; @@ -73,33 +73,33 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_frame_ready + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + m_frame_ready ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - output_frame_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_arp_htype, - output_arp_ptype, - output_arp_hlen, - output_arp_plen, - output_arp_oper, - output_arp_sha, - output_arp_spa, - output_arp_tha, - output_arp_tpa, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_frame_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_arp_htype, + m_arp_ptype, + m_arp_hlen, + m_arp_plen, + m_arp_oper, + m_arp_sha, + m_arp_spa, + m_arp_tha, + m_arp_tpa, busy, error_header_early_termination, error_invalid_header @@ -115,32 +115,32 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // ARP frame output - .output_frame_valid(output_frame_valid), - .output_frame_ready(output_frame_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_arp_htype(output_arp_htype), - .output_arp_ptype(output_arp_ptype), - .output_arp_hlen(output_arp_hlen), - .output_arp_plen(output_arp_plen), - .output_arp_oper(output_arp_oper), - .output_arp_sha(output_arp_sha), - .output_arp_spa(output_arp_spa), - .output_arp_tha(output_arp_tha), - .output_arp_tpa(output_arp_tpa), + .m_frame_valid(m_frame_valid), + .m_frame_ready(m_frame_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_arp_htype(m_arp_htype), + .m_arp_ptype(m_arp_ptype), + .m_arp_hlen(m_arp_hlen), + .m_arp_plen(m_arp_plen), + .m_arp_oper(m_arp_oper), + .m_arp_sha(m_arp_sha), + .m_arp_spa(m_arp_spa), + .m_arp_tha(m_arp_tha), + .m_arp_tpa(m_arp_tpa), // Status signals .busy(busy), .error_header_early_termination(error_header_early_termination), diff --git a/tb/test_arp_eth_tx.py b/tb/test_arp_eth_tx.py index ddf0a8504..02ac9cf17 100755 --- a/tb/test_arp_eth_tx.py +++ b/tb/test_arp_eth_tx.py @@ -48,30 +48,30 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_frame_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_arp_htype = Signal(intbv(0)[16:]) - input_arp_ptype = Signal(intbv(0)[16:]) - input_arp_oper = Signal(intbv(0)[16:]) - input_arp_sha = Signal(intbv(0)[48:]) - input_arp_spa = Signal(intbv(0)[32:]) - input_arp_tha = Signal(intbv(0)[48:]) - input_arp_tpa = Signal(intbv(0)[32:]) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + s_frame_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_arp_htype = Signal(intbv(0)[16:]) + s_arp_ptype = Signal(intbv(0)[16:]) + s_arp_oper = Signal(intbv(0)[16:]) + s_arp_sha = Signal(intbv(0)[48:]) + s_arp_spa = Signal(intbv(0)[32:]) + s_arp_tha = Signal(intbv(0)[48:]) + s_arp_tpa = Signal(intbv(0)[32:]) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) # Outputs - input_frame_ready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_frame_ready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) # sources and sinks @@ -83,18 +83,18 @@ def bench(): source_logic = source.create_logic( clk, rst, - frame_ready=input_frame_ready, - frame_valid=input_frame_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - arp_htype=input_arp_htype, - arp_ptype=input_arp_ptype, - arp_oper=input_arp_oper, - arp_sha=input_arp_sha, - arp_spa=input_arp_spa, - arp_tha=input_arp_tha, - arp_tpa=input_arp_tpa, + frame_ready=s_frame_ready, + frame_valid=s_frame_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + arp_htype=s_arp_htype, + arp_ptype=s_arp_ptype, + arp_oper=s_arp_oper, + arp_sha=s_arp_sha, + arp_spa=s_arp_spa, + arp_tha=s_arp_tha, + arp_tpa=s_arp_tpa, pause=source_pause, name='source' ) @@ -104,16 +104,16 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -128,29 +128,29 @@ def bench(): rst=rst, current_test=current_test, - input_frame_valid=input_frame_valid, - input_frame_ready=input_frame_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_arp_htype=input_arp_htype, - input_arp_ptype=input_arp_ptype, - input_arp_oper=input_arp_oper, - input_arp_sha=input_arp_sha, - input_arp_spa=input_arp_spa, - input_arp_tha=input_arp_tha, - input_arp_tpa=input_arp_tpa, + s_frame_valid=s_frame_valid, + s_frame_ready=s_frame_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_arp_htype=s_arp_htype, + s_arp_ptype=s_arp_ptype, + s_arp_oper=s_arp_oper, + s_arp_sha=s_arp_sha, + s_arp_spa=s_arp_spa, + s_arp_tha=s_arp_tha, + s_arp_tpa=s_arp_tpa, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, busy=busy ) @@ -318,7 +318,7 @@ def bench(): yield clk.posedge yield clk.posedge - while output_eth_payload_tvalid: + while m_eth_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_arp_eth_tx.v b/tb/test_arp_eth_tx.v index 30ea9c595..c112d25eb 100644 --- a/tb/test_arp_eth_tx.v +++ b/tb/test_arp_eth_tx.v @@ -36,30 +36,30 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_frame_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [15:0] input_arp_htype = 0; -reg [15:0] input_arp_ptype = 0; -reg [15:0] input_arp_oper = 0; -reg [47:0] input_arp_sha = 0; -reg [31:0] input_arp_spa = 0; -reg [47:0] input_arp_tha = 0; -reg [31:0] input_arp_tpa = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg s_frame_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [15:0] s_arp_htype = 0; +reg [15:0] s_arp_ptype = 0; +reg [15:0] s_arp_oper = 0; +reg [47:0] s_arp_sha = 0; +reg [31:0] s_arp_spa = 0; +reg [47:0] s_arp_tha = 0; +reg [31:0] s_arp_tpa = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; // Outputs -wire input_frame_ready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [7:0] output_eth_payload_tdata; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_frame_ready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [7:0] m_eth_payload_axis_tdata; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire busy; initial begin @@ -68,30 +68,30 @@ initial begin clk, rst, current_test, - input_frame_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_arp_htype, - input_arp_ptype, - input_arp_oper, - input_arp_sha, - input_arp_spa, - input_arp_tha, - input_arp_tpa, - output_eth_hdr_ready, - output_eth_payload_tready + s_frame_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_arp_htype, + s_arp_ptype, + s_arp_oper, + s_arp_sha, + s_arp_spa, + s_arp_tha, + s_arp_tpa, + m_eth_hdr_ready, + m_eth_payload_axis_tready ); $to_myhdl( - input_frame_ready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, + s_frame_ready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, busy ); @@ -105,29 +105,29 @@ UUT ( .clk(clk), .rst(rst), // ARP frame input - .input_frame_valid(input_frame_valid), - .input_frame_ready(input_frame_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_arp_htype(input_arp_htype), - .input_arp_ptype(input_arp_ptype), - .input_arp_oper(input_arp_oper), - .input_arp_sha(input_arp_sha), - .input_arp_spa(input_arp_spa), - .input_arp_tha(input_arp_tha), - .input_arp_tpa(input_arp_tpa), + .s_frame_valid(s_frame_valid), + .s_frame_ready(s_frame_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_arp_htype(s_arp_htype), + .s_arp_ptype(s_arp_ptype), + .s_arp_oper(s_arp_oper), + .s_arp_sha(s_arp_sha), + .s_arp_spa(s_arp_spa), + .s_arp_tha(s_arp_tha), + .s_arp_tpa(s_arp_tpa), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Status signals .busy(busy) ); diff --git a/tb/test_arp_eth_tx_64.py b/tb/test_arp_eth_tx_64.py index c26fbae2f..d6120f343 100755 --- a/tb/test_arp_eth_tx_64.py +++ b/tb/test_arp_eth_tx_64.py @@ -48,31 +48,31 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_frame_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_arp_htype = Signal(intbv(0)[16:]) - input_arp_ptype = Signal(intbv(0)[16:]) - input_arp_oper = Signal(intbv(0)[16:]) - input_arp_sha = Signal(intbv(0)[48:]) - input_arp_spa = Signal(intbv(0)[32:]) - input_arp_tha = Signal(intbv(0)[48:]) - input_arp_tpa = Signal(intbv(0)[32:]) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + s_frame_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_arp_htype = Signal(intbv(0)[16:]) + s_arp_ptype = Signal(intbv(0)[16:]) + s_arp_oper = Signal(intbv(0)[16:]) + s_arp_sha = Signal(intbv(0)[48:]) + s_arp_spa = Signal(intbv(0)[32:]) + s_arp_tha = Signal(intbv(0)[48:]) + s_arp_tpa = Signal(intbv(0)[32:]) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) # Outputs - input_frame_ready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[64:]) - output_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_frame_ready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + m_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) # sources and sinks @@ -84,18 +84,18 @@ def bench(): source_logic = source.create_logic( clk, rst, - frame_ready=input_frame_ready, - frame_valid=input_frame_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - arp_htype=input_arp_htype, - arp_ptype=input_arp_ptype, - arp_oper=input_arp_oper, - arp_sha=input_arp_sha, - arp_spa=input_arp_spa, - arp_tha=input_arp_tha, - arp_tpa=input_arp_tpa, + frame_ready=s_frame_ready, + frame_valid=s_frame_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + arp_htype=s_arp_htype, + arp_ptype=s_arp_ptype, + arp_oper=s_arp_oper, + arp_sha=s_arp_sha, + arp_spa=s_arp_spa, + arp_tha=s_arp_tha, + arp_tpa=s_arp_tpa, pause=source_pause, name='source' ) @@ -105,17 +105,17 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -130,30 +130,30 @@ def bench(): rst=rst, current_test=current_test, - input_frame_valid=input_frame_valid, - input_frame_ready=input_frame_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_arp_htype=input_arp_htype, - input_arp_ptype=input_arp_ptype, - input_arp_oper=input_arp_oper, - input_arp_sha=input_arp_sha, - input_arp_spa=input_arp_spa, - input_arp_tha=input_arp_tha, - input_arp_tpa=input_arp_tpa, + s_frame_valid=s_frame_valid, + s_frame_ready=s_frame_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_arp_htype=s_arp_htype, + s_arp_ptype=s_arp_ptype, + s_arp_oper=s_arp_oper, + s_arp_sha=s_arp_sha, + s_arp_spa=s_arp_spa, + s_arp_tha=s_arp_tha, + s_arp_tpa=s_arp_tpa, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, busy=busy ) @@ -321,7 +321,7 @@ def bench(): yield clk.posedge yield clk.posedge - while output_eth_payload_tvalid: + while m_eth_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_arp_eth_tx_64.v b/tb/test_arp_eth_tx_64.v index 37e3bbb0b..4b639585c 100644 --- a/tb/test_arp_eth_tx_64.v +++ b/tb/test_arp_eth_tx_64.v @@ -36,31 +36,31 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_frame_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [15:0] input_arp_htype = 0; -reg [15:0] input_arp_ptype = 0; -reg [15:0] input_arp_oper = 0; -reg [47:0] input_arp_sha = 0; -reg [31:0] input_arp_spa = 0; -reg [47:0] input_arp_tha = 0; -reg [31:0] input_arp_tpa = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg s_frame_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [15:0] s_arp_htype = 0; +reg [15:0] s_arp_ptype = 0; +reg [15:0] s_arp_oper = 0; +reg [47:0] s_arp_sha = 0; +reg [31:0] s_arp_spa = 0; +reg [47:0] s_arp_tha = 0; +reg [31:0] s_arp_tpa = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; // Outputs -wire input_frame_ready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [63:0] output_eth_payload_tdata; -wire [7:0] output_eth_payload_tkeep; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_frame_ready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [63:0] m_eth_payload_axis_tdata; +wire [7:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire busy; initial begin @@ -69,31 +69,31 @@ initial begin clk, rst, current_test, - input_frame_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_arp_htype, - input_arp_ptype, - input_arp_oper, - input_arp_sha, - input_arp_spa, - input_arp_tha, - input_arp_tpa, - output_eth_hdr_ready, - output_eth_payload_tready + s_frame_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_arp_htype, + s_arp_ptype, + s_arp_oper, + s_arp_sha, + s_arp_spa, + s_arp_tha, + s_arp_tpa, + m_eth_hdr_ready, + m_eth_payload_axis_tready ); $to_myhdl( - input_frame_ready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, + s_frame_ready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, busy ); @@ -107,30 +107,30 @@ UUT ( .clk(clk), .rst(rst), // ARP frame input - .input_frame_valid(input_frame_valid), - .input_frame_ready(input_frame_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_arp_htype(input_arp_htype), - .input_arp_ptype(input_arp_ptype), - .input_arp_oper(input_arp_oper), - .input_arp_sha(input_arp_sha), - .input_arp_spa(input_arp_spa), - .input_arp_tha(input_arp_tha), - .input_arp_tpa(input_arp_tpa), + .s_frame_valid(s_frame_valid), + .s_frame_ready(s_frame_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_arp_htype(s_arp_htype), + .s_arp_ptype(s_arp_ptype), + .s_arp_oper(s_arp_oper), + .s_arp_sha(s_arp_sha), + .s_arp_spa(s_arp_spa), + .s_arp_tha(s_arp_tha), + .s_arp_tpa(s_arp_tpa), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Status signals .busy(busy) ); diff --git a/tb/test_axis_eth_fcs.py b/tb/test_axis_eth_fcs.py index 906a3fb49..15fe19ba8 100755 --- a/tb/test_axis_eth_fcs.py +++ b/tb/test_axis_eth_fcs.py @@ -52,13 +52,13 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(1)) + s_axis_tready = Signal(bool(1)) output_fcs = Signal(intbv(0)[32:]) output_fcs_valid = Signal(bool(0)) @@ -70,11 +70,11 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -89,11 +89,11 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_axis_tuser, output_fcs=output_fcs, output_fcs_valid=output_fcs_valid diff --git a/tb/test_axis_eth_fcs.v b/tb/test_axis_eth_fcs.v index c22034af1..785ab4e3f 100644 --- a/tb/test_axis_eth_fcs.v +++ b/tb/test_axis_eth_fcs.v @@ -38,13 +38,13 @@ 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 [7:0] s_axis_tdata = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; // Outputs -wire input_axis_tready; +wire s_axis_tready; wire [31:0] output_fcs; wire output_fcs_valid; @@ -54,13 +54,13 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser + s_axis_tdata, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser ); $to_myhdl( - input_axis_tready, + s_axis_tready, output_fcs, output_fcs_valid ); @@ -74,11 +74,11 @@ axis_eth_fcs UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), .output_fcs(output_fcs), .output_fcs_valid(output_fcs_valid) ); diff --git a/tb/test_axis_eth_fcs_64.py b/tb/test_axis_eth_fcs_64.py index c89e5c9c9..c592dab04 100755 --- a/tb/test_axis_eth_fcs_64.py +++ b/tb/test_axis_eth_fcs_64.py @@ -52,14 +52,14 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[64:]) + s_axis_tkeep = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(1)) + s_axis_tready = Signal(bool(1)) output_fcs = Signal(intbv(0)[32:]) output_fcs_valid = Signal(bool(0)) @@ -71,12 +71,12 @@ def bench(): source_logic = source.create_logic( 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, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -91,12 +91,12 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_axis_tuser, output_fcs=output_fcs, output_fcs_valid=output_fcs_valid diff --git a/tb/test_axis_eth_fcs_64.v b/tb/test_axis_eth_fcs_64.v index cd84cec27..1d137b1fe 100644 --- a/tb/test_axis_eth_fcs_64.v +++ b/tb/test_axis_eth_fcs_64.v @@ -38,14 +38,14 @@ 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 [63:0] s_axis_tdata = 0; +reg [7:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; // Outputs -wire input_axis_tready; +wire s_axis_tready; wire [31:0] output_fcs; wire output_fcs_valid; @@ -55,14 +55,14 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser ); $to_myhdl( - input_axis_tready, + s_axis_tready, output_fcs, output_fcs_valid ); @@ -76,12 +76,12 @@ axis_eth_fcs_64 UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), .output_fcs(output_fcs), .output_fcs_valid(output_fcs_valid) ); diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index 6fac8ebbb..55b2729e2 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -54,18 +54,18 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_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)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -78,11 +78,11 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -92,11 +92,11 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -111,17 +111,17 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_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, + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, busy=busy, error_bad_fcs=error_bad_fcs @@ -139,11 +139,11 @@ def bench(): error_bad_fcs_asserted.next = 1 def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -152,7 +152,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_eth_fcs_check.v b/tb/test_axis_eth_fcs_check.v index effe04d08..526ed44e2 100644 --- a/tb/test_axis_eth_fcs_check.v +++ b/tb/test_axis_eth_fcs_check.v @@ -38,18 +38,18 @@ 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; +reg [7:0] s_axis_tdata = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_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 s_axis_tready; +wire [7:0] m_axis_tdata; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire busy; wire error_bad_fcs; @@ -59,18 +59,18 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, busy, error_bad_fcs ); @@ -84,16 +84,16 @@ axis_eth_fcs_check UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), .busy(busy), .error_bad_fcs(error_bad_fcs) ); diff --git a/tb/test_axis_eth_fcs_check_64.py b/tb/test_axis_eth_fcs_check_64.py index f05d1d677..5c021ef67 100755 --- a/tb/test_axis_eth_fcs_check_64.py +++ b/tb/test_axis_eth_fcs_check_64.py @@ -54,20 +54,20 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[64:]) + s_axis_tkeep = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_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)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[64:]) + m_axis_tkeep = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -80,12 +80,12 @@ def bench(): source_logic = source.create_logic( 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, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -95,12 +95,12 @@ def bench(): sink_logic = sink.create_logic( 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, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -115,19 +115,19 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_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, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, busy=busy, error_bad_fcs=error_bad_fcs @@ -145,11 +145,11 @@ def bench(): error_bad_fcs_asserted.next = 1 def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -158,7 +158,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_eth_fcs_check_64.v b/tb/test_axis_eth_fcs_check_64.v index 8e360893b..8c98ee657 100644 --- a/tb/test_axis_eth_fcs_check_64.v +++ b/tb/test_axis_eth_fcs_check_64.v @@ -38,20 +38,20 @@ 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; +reg [63:0] s_axis_tdata = 0; +reg [7:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_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 s_axis_tready; +wire [63:0] m_axis_tdata; +wire [7:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire busy; wire error_bad_fcs; @@ -61,20 +61,20 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, busy, error_bad_fcs ); @@ -88,18 +88,18 @@ axis_eth_fcs_check_64 UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), .busy(busy), .error_bad_fcs(error_bad_fcs) ); diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index 566f184b2..8a5ee2477 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -55,18 +55,18 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_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)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) # sources and sinks @@ -78,11 +78,11 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -92,11 +92,11 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -111,17 +111,17 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_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, + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, busy=busy ) @@ -131,11 +131,11 @@ def bench(): clk.next = not clk def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -144,7 +144,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_eth_fcs_insert.v b/tb/test_axis_eth_fcs_insert.v index e64a6a913..bb6c39b92 100644 --- a/tb/test_axis_eth_fcs_insert.v +++ b/tb/test_axis_eth_fcs_insert.v @@ -40,18 +40,18 @@ 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; +reg [7:0] s_axis_tdata = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_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 s_axis_tready; +wire [7:0] m_axis_tdata; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire busy; initial begin @@ -60,18 +60,18 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, busy ); @@ -87,16 +87,16 @@ axis_eth_fcs_insert #( UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), .busy(busy) ); diff --git a/tb/test_axis_eth_fcs_insert_64.py b/tb/test_axis_eth_fcs_insert_64.py index 6b81a516a..d2bfb7583 100755 --- a/tb/test_axis_eth_fcs_insert_64.py +++ b/tb/test_axis_eth_fcs_insert_64.py @@ -55,20 +55,20 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[64:]) + s_axis_tkeep = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_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)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[64:]) + m_axis_tkeep = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) # sources and sinks @@ -80,12 +80,12 @@ def bench(): source_logic = source.create_logic( 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, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -95,12 +95,12 @@ def bench(): sink_logic = sink.create_logic( 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, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -115,19 +115,19 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_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, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, busy=busy ) @@ -137,11 +137,11 @@ def bench(): clk.next = not clk def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -150,7 +150,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_eth_fcs_insert_64.v b/tb/test_axis_eth_fcs_insert_64.v index 143f3ae3d..48c8d133d 100644 --- a/tb/test_axis_eth_fcs_insert_64.v +++ b/tb/test_axis_eth_fcs_insert_64.v @@ -40,20 +40,20 @@ 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; +reg [63:0] s_axis_tdata = 0; +reg [7:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_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 s_axis_tready; +wire [63:0] m_axis_tdata; +wire [7:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire busy; initial begin @@ -62,20 +62,20 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, busy ); @@ -91,18 +91,18 @@ axis_eth_fcs_insert_64 #( UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), .busy(busy) ); diff --git a/tb/test_axis_eth_fcs_insert_64_pad.py b/tb/test_axis_eth_fcs_insert_64_pad.py index 9b7a95ddb..af81dcade 100755 --- a/tb/test_axis_eth_fcs_insert_64_pad.py +++ b/tb/test_axis_eth_fcs_insert_64_pad.py @@ -55,20 +55,20 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[64:]) + s_axis_tkeep = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_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)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[64:]) + m_axis_tkeep = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) # sources and sinks @@ -80,12 +80,12 @@ def bench(): source_logic = source.create_logic( 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, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -95,12 +95,12 @@ def bench(): sink_logic = sink.create_logic( 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, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -115,19 +115,19 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_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, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, busy=busy ) @@ -137,11 +137,11 @@ def bench(): clk.next = not clk def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -150,7 +150,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_eth_fcs_insert_64_pad.v b/tb/test_axis_eth_fcs_insert_64_pad.v index 53b073cb2..323f0d554 100644 --- a/tb/test_axis_eth_fcs_insert_64_pad.v +++ b/tb/test_axis_eth_fcs_insert_64_pad.v @@ -40,20 +40,20 @@ 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; +reg [63:0] s_axis_tdata = 0; +reg [7:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_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 s_axis_tready; +wire [63:0] m_axis_tdata; +wire [7:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire busy; initial begin @@ -62,20 +62,20 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, busy ); @@ -91,18 +91,18 @@ axis_eth_fcs_insert_64 #( UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), .busy(busy) ); diff --git a/tb/test_axis_eth_fcs_insert_pad.py b/tb/test_axis_eth_fcs_insert_pad.py index fe753d57c..e9133c3b8 100755 --- a/tb/test_axis_eth_fcs_insert_pad.py +++ b/tb/test_axis_eth_fcs_insert_pad.py @@ -55,18 +55,18 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_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)) + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) # sources and sinks @@ -78,11 +78,11 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -92,11 +92,11 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -111,17 +111,17 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_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, + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, busy=busy ) @@ -131,11 +131,11 @@ def bench(): clk.next = not clk def wait_normal(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -144,7 +144,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_axis_tvalid: + while s_axis_tvalid or m_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_axis_eth_fcs_insert_pad.v b/tb/test_axis_eth_fcs_insert_pad.v index f82b780b0..d48e9ab5c 100644 --- a/tb/test_axis_eth_fcs_insert_pad.v +++ b/tb/test_axis_eth_fcs_insert_pad.v @@ -40,18 +40,18 @@ 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; +reg [7:0] s_axis_tdata = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_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 s_axis_tready; +wire [7:0] m_axis_tdata; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire busy; initial begin @@ -60,18 +60,18 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_axis_tready + s_axis_tdata, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_axis_tready ); $to_myhdl( - input_axis_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + s_axis_tready, + m_axis_tdata, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, busy ); @@ -87,16 +87,16 @@ axis_eth_fcs_insert #( UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), .busy(busy) ); diff --git a/tb/test_axis_gmii_rx.py b/tb/test_axis_gmii_rx.py index ccf9f9d33..4c2c52af4 100755 --- a/tb/test_axis_gmii_rx.py +++ b/tb/test_axis_gmii_rx.py @@ -60,10 +60,10 @@ def bench(): mii_select = Signal(bool(0)) # Outputs - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -86,10 +86,10 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tlast=m_axis_tlast, + tuser=m_axis_tuser, name='sink' ) @@ -107,10 +107,10 @@ def bench(): gmii_rx_dv=gmii_rx_dv, gmii_rx_er=gmii_rx_er, - output_axis_tdata=output_axis_tdata, - output_axis_tvalid=output_axis_tvalid, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, clk_enable=clk_enable, mii_select=mii_select, diff --git a/tb/test_axis_gmii_rx.v b/tb/test_axis_gmii_rx.v index 67f13d400..60ec7d29f 100644 --- a/tb/test_axis_gmii_rx.v +++ b/tb/test_axis_gmii_rx.v @@ -46,10 +46,10 @@ reg clk_enable = 1; reg mii_select = 0; // Outputs -wire [7:0] output_axis_tdata; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; +wire [7:0] m_axis_tdata; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire error_bad_frame; wire error_bad_fcs; @@ -66,10 +66,10 @@ initial begin mii_select ); $to_myhdl( - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + m_axis_tdata, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, error_bad_frame, error_bad_fcs ); @@ -86,10 +86,10 @@ UUT ( .gmii_rxd(gmii_rxd), .gmii_rx_dv(gmii_rx_dv), .gmii_rx_er(gmii_rx_er), - .output_axis_tdata(output_axis_tdata), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), .clk_enable(clk_enable), .mii_select(mii_select), .error_bad_frame(error_bad_frame), diff --git a/tb/test_axis_gmii_tx.py b/tb/test_axis_gmii_tx.py index 562403b68..ab0e62597 100755 --- a/tb/test_axis_gmii_tx.py +++ b/tb/test_axis_gmii_tx.py @@ -54,16 +54,16 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) clk_enable = Signal(bool(1)) mii_select = Signal(bool(0)) ifg_delay = Signal(intbv(0)[8:]) # Outputs - input_axis_tready = Signal(bool(0)) + s_axis_tready = Signal(bool(0)) gmii_txd = Signal(intbv(0)[8:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) @@ -76,11 +76,11 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -108,11 +108,11 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_axis_tuser, gmii_txd=gmii_txd, gmii_tx_en=gmii_tx_en, diff --git a/tb/test_axis_gmii_tx.v b/tb/test_axis_gmii_tx.v index 86d33168b..8224d7971 100644 --- a/tb/test_axis_gmii_tx.v +++ b/tb/test_axis_gmii_tx.v @@ -40,16 +40,16 @@ 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 [7:0] s_axis_tdata = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; reg clk_enable = 1; reg mii_select = 0; reg [7:0] ifg_delay = 0; // Outputs -wire input_axis_tready; +wire s_axis_tready; wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; @@ -60,16 +60,16 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, + s_axis_tdata, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, clk_enable, mii_select, ifg_delay ); $to_myhdl( - input_axis_tready, + s_axis_tready, gmii_txd, gmii_tx_en, gmii_tx_er @@ -87,11 +87,11 @@ axis_gmii_tx #( UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), diff --git a/tb/test_axis_xgmii_rx_32.py b/tb/test_axis_xgmii_rx_32.py index 9f340f703..0828b7131 100755 --- a/tb/test_axis_xgmii_rx_32.py +++ b/tb/test_axis_xgmii_rx_32.py @@ -57,11 +57,11 @@ def bench(): xgmii_rxc = Signal(intbv(0xf)[4:]) # Outputs - output_axis_tdata = Signal(intbv(0)[32:]) - output_axis_tkeep = Signal(intbv(0)[4:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[32:]) + m_axis_tkeep = Signal(intbv(0)[4:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -81,11 +81,11 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tlast=m_axis_tlast, + tuser=m_axis_tuser, name='sink' ) @@ -102,11 +102,11 @@ def bench(): xgmii_rxd=xgmii_rxd, xgmii_rxc=xgmii_rxc, - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs diff --git a/tb/test_axis_xgmii_rx_32.v b/tb/test_axis_xgmii_rx_32.v index 838fc41a8..12681e6ca 100644 --- a/tb/test_axis_xgmii_rx_32.v +++ b/tb/test_axis_xgmii_rx_32.v @@ -42,11 +42,11 @@ reg [31:0] xgmii_rxd = 32'h07070707; reg [3:0] xgmii_rxc = 4'hf; // Outputs -wire [31:0] output_axis_tdata; -wire [3:0] output_axis_tkeep; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; +wire [31:0] m_axis_tdata; +wire [3:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire error_bad_frame; wire error_bad_fcs; @@ -60,11 +60,11 @@ initial begin xgmii_rxc ); $to_myhdl( - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, error_bad_frame, error_bad_fcs ); @@ -80,11 +80,11 @@ UUT ( .rst(rst), .xgmii_rxd(xgmii_rxd), .xgmii_rxc(xgmii_rxc), - .output_axis_tdata(output_axis_tdata), - .output_axis_tkeep(output_axis_tkeep), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs) ); diff --git a/tb/test_axis_xgmii_rx_64.py b/tb/test_axis_xgmii_rx_64.py index c62c022f5..59b2a2198 100755 --- a/tb/test_axis_xgmii_rx_64.py +++ b/tb/test_axis_xgmii_rx_64.py @@ -57,11 +57,11 @@ def bench(): xgmii_rxc = Signal(intbv(0xff)[8:]) # Outputs - 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)) + m_axis_tdata = Signal(intbv(0)[64:]) + m_axis_tkeep = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -81,11 +81,11 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tkeep=output_axis_tkeep, - tvalid=output_axis_tvalid, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tlast=m_axis_tlast, + tuser=m_axis_tuser, name='sink' ) @@ -102,11 +102,11 @@ def bench(): xgmii_rxd=xgmii_rxd, xgmii_rxc=xgmii_rxc, - output_axis_tdata=output_axis_tdata, - output_axis_tkeep=output_axis_tkeep, - output_axis_tvalid=output_axis_tvalid, - output_axis_tlast=output_axis_tlast, - output_axis_tuser=output_axis_tuser, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs diff --git a/tb/test_axis_xgmii_rx_64.v b/tb/test_axis_xgmii_rx_64.v index e18adcb6a..700660a65 100644 --- a/tb/test_axis_xgmii_rx_64.v +++ b/tb/test_axis_xgmii_rx_64.v @@ -42,11 +42,11 @@ reg [63:0] xgmii_rxd = 64'h0707070707070707; reg [7:0] xgmii_rxc = 8'hff; // Outputs -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 [63:0] m_axis_tdata; +wire [7:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire error_bad_frame; wire error_bad_fcs; @@ -60,11 +60,11 @@ initial begin xgmii_rxc ); $to_myhdl( - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, error_bad_frame, error_bad_fcs ); @@ -80,11 +80,11 @@ UUT ( .rst(rst), .xgmii_rxd(xgmii_rxd), .xgmii_rxc(xgmii_rxc), - .output_axis_tdata(output_axis_tdata), - .output_axis_tkeep(output_axis_tkeep), - .output_axis_tvalid(output_axis_tvalid), - .output_axis_tlast(output_axis_tlast), - .output_axis_tuser(output_axis_tuser), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs) ); diff --git a/tb/test_axis_xgmii_tx_32.py b/tb/test_axis_xgmii_tx_32.py index 241b2f6ac..f0f480148 100755 --- a/tb/test_axis_xgmii_tx_32.py +++ b/tb/test_axis_xgmii_tx_32.py @@ -54,15 +54,15 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[4:]) - input_axis_tdata = Signal(intbv(0)[32:]) - input_axis_tkeep = Signal(intbv(0)[4:]) - input_axis_tvalid = Signal(bool(0)) - input_axis_tlast = Signal(bool(0)) - input_axis_tuser = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[32:]) + s_axis_tkeep = Signal(intbv(0)[4:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) ifg_delay = Signal(intbv(0)[8:]) # Outputs - input_axis_tready = Signal(bool(0)) + s_axis_tready = Signal(bool(0)) xgmii_txd = Signal(intbv(0x07070707)[32:]) xgmii_txc = Signal(intbv(0xf)[4:]) @@ -74,12 +74,12 @@ def bench(): source_logic = source.create_logic( 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, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -104,12 +104,12 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_axis_tuser, xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, diff --git a/tb/test_axis_xgmii_tx_32.v b/tb/test_axis_xgmii_tx_32.v index 883a0ed6f..c59c69425 100644 --- a/tb/test_axis_xgmii_tx_32.v +++ b/tb/test_axis_xgmii_tx_32.v @@ -40,15 +40,15 @@ reg clk = 0; reg rst = 0; reg [3:0] current_test = 0; -reg [31:0] input_axis_tdata = 0; -reg [3:0] input_axis_tkeep = 0; -reg input_axis_tvalid = 0; -reg input_axis_tlast = 0; -reg input_axis_tuser = 0; +reg [31:0] s_axis_tdata = 0; +reg [3:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; reg [7:0] ifg_delay = 0; // Outputs -wire input_axis_tready; +wire s_axis_tready; wire [31:0] xgmii_txd; wire [3:0] xgmii_txc; @@ -58,15 +58,15 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, ifg_delay ); $to_myhdl( - input_axis_tready, + s_axis_tready, xgmii_txd, xgmii_txc ); @@ -83,12 +83,12 @@ axis_xgmii_tx_32 #( UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), .ifg_delay(ifg_delay) diff --git a/tb/test_axis_xgmii_tx_64.py b/tb/test_axis_xgmii_tx_64.py index 370336fbb..58918b240 100755 --- a/tb/test_axis_xgmii_tx_64.py +++ b/tb/test_axis_xgmii_tx_64.py @@ -54,15 +54,15 @@ def bench(): 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)) + s_axis_tdata = Signal(intbv(0)[64:]) + s_axis_tkeep = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) ifg_delay = Signal(intbv(0)[8:]) # Outputs - input_axis_tready = Signal(bool(0)) + s_axis_tready = Signal(bool(0)) xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) xgmii_txc = Signal(intbv(0xff)[8:]) @@ -74,12 +74,12 @@ def bench(): source_logic = source.create_logic( 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, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -104,12 +104,12 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_axis_tuser, xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, diff --git a/tb/test_axis_xgmii_tx_64.v b/tb/test_axis_xgmii_tx_64.v index e7a480703..6a46d8cae 100644 --- a/tb/test_axis_xgmii_tx_64.v +++ b/tb/test_axis_xgmii_tx_64.v @@ -40,15 +40,15 @@ 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 [63:0] s_axis_tdata = 0; +reg [7:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; reg [7:0] ifg_delay = 0; // Outputs -wire input_axis_tready; +wire s_axis_tready; wire [63:0] xgmii_txd; wire [7:0] xgmii_txc; @@ -58,15 +58,15 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, ifg_delay ); $to_myhdl( - input_axis_tready, + s_axis_tready, xgmii_txd, xgmii_txc ); @@ -83,12 +83,12 @@ axis_xgmii_tx_64 #( UUT ( .clk(clk), .rst(rst), - .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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), .ifg_delay(ifg_delay) diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index 0667e16eb..fe6467aaf 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -48,23 +48,23 @@ def bench(): 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_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_axis_tready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_header_early_termination = Signal(bool(0)) @@ -77,11 +77,11 @@ def bench(): source_logic = source.create_logic( clk, rst, - tdata=input_axis_tdata, - tvalid=input_axis_tvalid, - tready=input_axis_tready, - tlast=input_axis_tlast, - tuser=input_axis_tuser, + tdata=s_axis_tdata, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -91,16 +91,16 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -115,22 +115,22 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, busy=busy, error_header_early_termination=error_header_early_termination @@ -148,11 +148,11 @@ def bench(): error_header_early_termination_asserted.next = 1 def wait_normal(): - while input_axis_tvalid or output_eth_payload_tvalid: + while s_axis_tvalid or m_eth_payload_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_eth_payload_tvalid: + while s_axis_tvalid or m_eth_payload_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -161,7 +161,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_eth_payload_tvalid: + while s_axis_tvalid or m_eth_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_eth_axis_rx.v b/tb/test_eth_axis_rx.v index f83624752..bacd0ddf5 100644 --- a/tb/test_eth_axis_rx.v +++ b/tb/test_eth_axis_rx.v @@ -36,23 +36,23 @@ 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_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg [7:0] s_axis_tdata = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; // Outputs -wire input_axis_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [7:0] output_eth_payload_tdata; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_axis_tready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [7:0] m_eth_payload_axis_tdata; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire busy; wire error_header_early_termination; @@ -62,23 +62,23 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_eth_hdr_ready, - output_eth_payload_tready + s_axis_tdata, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready ); $to_myhdl( - input_axis_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, + s_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, busy, error_header_early_termination ); @@ -93,22 +93,22 @@ 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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Status signals .busy(busy), .error_header_early_termination(error_header_early_termination) diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index 0ae6ebff4..f39d730b9 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -48,25 +48,25 @@ def bench(): 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_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + s_axis_tdata = Signal(intbv(0)[64:]) + s_axis_tkeep = Signal(intbv(0)[8:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tuser = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) # Outputs - input_axis_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[64:]) - output_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_axis_tready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + m_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_header_early_termination = Signal(bool(0)) @@ -79,12 +79,12 @@ def bench(): source_logic = source.create_logic( 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, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, pause=source_pause, name='source' ) @@ -94,17 +94,17 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -119,24 +119,24 @@ def bench(): 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, + s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, + s_axis_tvalid=s_axis_tvalid, + s_axis_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, busy=busy, error_header_early_termination=error_header_early_termination @@ -154,11 +154,11 @@ def bench(): error_header_early_termination_asserted.next = 1 def wait_normal(): - while input_axis_tvalid or output_eth_payload_tvalid: + while s_axis_tvalid or m_eth_payload_axis_tvalid: yield clk.posedge def wait_pause_source(): - while input_axis_tvalid or output_eth_payload_tvalid: + while s_axis_tvalid or m_eth_payload_axis_tvalid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -167,7 +167,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_axis_tvalid or output_eth_payload_tvalid: + while s_axis_tvalid or m_eth_payload_axis_tvalid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_eth_axis_rx_64.v b/tb/test_eth_axis_rx_64.v index fcd5dabde..985e2e561 100644 --- a/tb/test_eth_axis_rx_64.v +++ b/tb/test_eth_axis_rx_64.v @@ -36,25 +36,25 @@ 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_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg [63:0] s_axis_tdata = 0; +reg [7:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg s_axis_tuser = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; // Outputs -wire input_axis_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [63:0] output_eth_payload_tdata; -wire [7:0] output_eth_payload_tkeep; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_axis_tready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [63:0] m_eth_payload_axis_tdata; +wire [7:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire busy; wire error_header_early_termination; @@ -64,25 +64,25 @@ initial begin clk, rst, current_test, - input_axis_tdata, - input_axis_tkeep, - input_axis_tvalid, - input_axis_tlast, - input_axis_tuser, - output_eth_hdr_ready, - output_eth_payload_tready + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready ); $to_myhdl( - input_axis_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, + s_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, busy, error_header_early_termination ); @@ -97,24 +97,24 @@ 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), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Status signals .busy(busy), .error_header_early_termination(error_header_early_termination) diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py index 6e26d459a..a5031ae0a 100755 --- a/tb/test_eth_axis_tx.py +++ b/tb/test_eth_axis_tx.py @@ -48,23 +48,23 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:0]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) + m_axis_tready = Signal(bool(0)) # Outputs - output_axis_tdata = Signal(intbv(0)[8:]) - output_axis_tvalid = Signal(bool(0)) - output_axis_tlast = Signal(bool(0)) - output_axis_tuser = Signal(bool(0)) - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) busy = Signal(bool(0)) # sources and sinks @@ -76,16 +76,16 @@ def bench(): source_logic = source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=source_pause, name='source' ) @@ -95,11 +95,11 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - tdata=output_axis_tdata, - tvalid=output_axis_tvalid, - tready=output_axis_tready, - tlast=output_axis_tlast, - tuser=output_axis_tuser, + tdata=m_axis_tdata, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -114,22 +114,22 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_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, + m_axis_tdata=m_axis_tdata, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, busy=busy ) @@ -139,11 +139,11 @@ def bench(): clk.next = not clk def wait_normal(): - while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_axis_tvalid or s_eth_hdr_valid: yield clk.posedge def wait_pause_source(): - while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_axis_tvalid or s_eth_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -152,7 +152,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_axis_tvalid or s_eth_hdr_valid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_eth_axis_tx.v b/tb/test_eth_axis_tx.v index 3ce6b672c..f72a57235 100644 --- a/tb/test_eth_axis_tx.v +++ b/tb/test_eth_axis_tx.v @@ -36,23 +36,23 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [7:0] input_eth_payload_tdata = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; -reg output_axis_tready = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [7:0] s_eth_payload_axis_tdata = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_eth_payload_tready; -wire input_eth_hdr_ready; -wire [7:0] output_axis_tdata; -wire output_axis_tvalid; -wire output_axis_tlast; -wire output_axis_tuser; +wire s_eth_payload_axis_tready; +wire s_eth_hdr_ready; +wire [7:0] m_axis_tdata; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire busy; initial begin @@ -61,23 +61,23 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_axis_tready + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + m_axis_tready ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - output_axis_tdata, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_axis_tdata, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, busy ); @@ -91,22 +91,22 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_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), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), // Status signals .busy(busy) ); diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py index 8a366edd6..105c24cba 100755 --- a/tb/test_eth_axis_tx_64.py +++ b/tb/test_eth_axis_tx_64.py @@ -48,25 +48,25 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:0]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[64:]) - input_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) - output_axis_tready = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + s_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) + m_axis_tready = Signal(bool(0)) # Outputs - 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)) - input_eth_hdr_ready = Signal(bool(1)) - input_eth_payload_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[64:]) + m_axis_tkeep = Signal(intbv(0)[8:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(1)) + s_eth_payload_axis_tready = Signal(bool(0)) busy = Signal(bool(0)) # sources and sinks @@ -78,17 +78,17 @@ def bench(): source_logic = source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tkeep=input_eth_payload_tkeep, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tkeep=s_eth_payload_axis_tkeep, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=source_pause, name='source' ) @@ -98,12 +98,12 @@ def bench(): sink_logic = sink.create_logic( 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, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tuser=m_axis_tuser, pause=sink_pause, name='sink' ) @@ -118,24 +118,24 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tkeep=input_eth_payload_tkeep, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_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, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, busy=busy ) @@ -145,11 +145,11 @@ def bench(): clk.next = not clk def wait_normal(): - while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_axis_tvalid or s_eth_hdr_valid: yield clk.posedge def wait_pause_source(): - while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_axis_tvalid or s_eth_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -158,7 +158,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_axis_tvalid or s_eth_hdr_valid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_eth_axis_tx_64.v b/tb/test_eth_axis_tx_64.v index 045d13ddb..3f16b14e6 100644 --- a/tb/test_eth_axis_tx_64.v +++ b/tb/test_eth_axis_tx_64.v @@ -36,25 +36,25 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [63:0] input_eth_payload_tdata = 0; -reg [7:0] input_eth_payload_tkeep = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; -reg output_axis_tready = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [63:0] s_eth_payload_axis_tdata = 0; +reg [7:0] s_eth_payload_axis_tkeep = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; +reg m_axis_tready = 0; // Outputs -wire input_eth_payload_tready; -wire input_eth_hdr_ready; -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 s_eth_payload_axis_tready; +wire s_eth_hdr_ready; +wire [63:0] m_axis_tdata; +wire [7:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; wire busy; initial begin @@ -63,25 +63,25 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_axis_tready + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + m_axis_tready ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - output_axis_tdata, - output_axis_tkeep, - output_axis_tvalid, - output_axis_tlast, - output_axis_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, busy ); @@ -95,24 +95,24 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_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), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), // Status signals .busy(busy) ); diff --git a/tb/test_ip.py b/tb/test_ip.py index d0bd2c72a..354c8632c 100755 --- a/tb/test_ip.py +++ b/tb/test_ip.py @@ -51,72 +51,72 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) arp_request_ready = Signal(bool(0)) arp_response_valid = Signal(bool(0)) arp_response_error = Signal(bool(0)) arp_response_mac = Signal(intbv(0)[48:]) - input_ip_hdr_valid = Signal(bool(0)) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) arp_request_valid = Signal(bool(0)) arp_request_ip = Signal(intbv(0)[32:]) arp_response_ready = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_ip_eth_dest_mac = Signal(intbv(0)[48:]) - output_ip_eth_src_mac = Signal(intbv(0)[48:]) - output_ip_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_ip_eth_dest_mac = Signal(intbv(0)[48:]) + m_ip_eth_src_mac = Signal(intbv(0)[48:]) + m_ip_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) rx_busy = Signal(bool(0)) tx_busy = Signal(bool(0)) rx_error_header_early_termination = Signal(bool(0)) @@ -139,16 +139,16 @@ def bench(): eth_source_logic = eth_source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=eth_source_pause, name='eth_source' ) @@ -158,16 +158,16 @@ def bench(): eth_sink_logic = eth_sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=eth_sink_pause, name='eth_sink' ) @@ -177,20 +177,20 @@ def bench(): ip_source_logic = ip_source.create_logic( clk, rst, - ip_hdr_valid=input_ip_hdr_valid, - ip_hdr_ready=input_ip_hdr_ready, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_valid=s_ip_hdr_valid, + ip_hdr_ready=s_ip_hdr_ready, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=ip_source_pause, name='ip_source' ) @@ -200,29 +200,29 @@ def bench(): ip_sink_logic = ip_sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_ip_eth_dest_mac, - eth_src_mac=output_ip_eth_src_mac, - eth_type=output_ip_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_ip_eth_dest_mac, + eth_src_mac=m_ip_eth_src_mac, + eth_type=m_ip_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=ip_sink_pause, name='ip_sink' ) @@ -259,27 +259,27 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, arp_request_valid=arp_request_valid, arp_request_ready=arp_request_ready, @@ -289,44 +289,44 @@ def bench(): arp_response_error=arp_response_error, arp_response_mac=arp_response_mac, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_ip_eth_dest_mac=output_ip_eth_dest_mac, - output_ip_eth_src_mac=output_ip_eth_src_mac, - output_ip_eth_type=output_ip_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_ip_eth_dest_mac=m_ip_eth_dest_mac, + m_ip_eth_src_mac=m_ip_eth_src_mac, + m_ip_eth_type=m_ip_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, rx_busy=rx_busy, tx_busy=tx_busy, @@ -383,9 +383,9 @@ def bench(): tx_error_arp_failed_asserted.next = 1 def wait_normal(): - while (input_eth_payload_tvalid or input_ip_payload_tvalid or - output_eth_payload_tvalid or output_ip_payload_tvalid or - input_eth_hdr_valid or input_ip_hdr_valid): + while (s_eth_payload_axis_tvalid or s_ip_payload_axis_tvalid or + m_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or + s_eth_hdr_valid or s_ip_hdr_valid): yield clk.posedge @instance diff --git a/tb/test_ip.v b/tb/test_ip.v index cf29178ec..68ca311d9 100644 --- a/tb/test_ip.v +++ b/tb/test_ip.v @@ -36,74 +36,74 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [7:0] input_eth_payload_tdata = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [7:0] s_eth_payload_axis_tdata = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; reg arp_request_ready = 0; reg arp_response_valid = 0; reg arp_response_error = 0; reg [47:0] arp_response_mac = 0; -reg input_ip_hdr_valid = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [7:0] input_ip_payload_tdata = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [7:0] s_ip_payload_axis_tdata = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; reg [47:0] local_mac = 0; reg [31:0] local_ip = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [7:0] output_eth_payload_tdata; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [7:0] m_eth_payload_axis_tdata; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire arp_request_valid; wire [31:0] arp_request_ip; wire arp_response_ready; -wire output_ip_hdr_valid; -wire [47:0] output_ip_eth_dest_mac; -wire [47:0] output_ip_eth_src_mac; -wire [15:0] output_ip_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [7:0] output_ip_payload_tdata; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire m_ip_hdr_valid; +wire [47:0] m_ip_eth_dest_mac; +wire [47:0] m_ip_eth_src_mac; +wire [15:0] m_ip_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [7:0] m_ip_payload_axis_tdata; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; wire rx_busy; wire tx_busy; wire rx_error_header_early_termination; @@ -119,74 +119,74 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, arp_request_ready, arp_response_valid, arp_response_error, arp_response_mac, - input_ip_hdr_valid, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_ttl, - input_ip_protocol, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, - output_ip_hdr_ready, - output_ip_payload_tready, + s_ip_hdr_valid, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_ttl, + s_ip_protocol, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, + m_ip_hdr_ready, + m_ip_payload_axis_tready, local_mac, local_ip ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - input_ip_hdr_ready, - input_ip_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, arp_request_valid, arp_request_ip, arp_response_ready, - output_ip_hdr_valid, - output_ip_eth_dest_mac, - output_ip_eth_src_mac, - output_ip_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, + m_ip_hdr_valid, + m_ip_eth_dest_mac, + m_ip_eth_src_mac, + m_ip_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, rx_busy, tx_busy, rx_error_header_early_termination, @@ -207,27 +207,27 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // ARP requests .arp_request_valid(arp_request_valid), .arp_request_ready(arp_request_ready), @@ -237,44 +237,44 @@ UUT ( .arp_response_error(arp_response_error), .arp_response_mac(arp_response_mac), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_ip_eth_dest_mac(output_ip_eth_dest_mac), - .output_ip_eth_src_mac(output_ip_eth_src_mac), - .output_ip_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_ip_eth_dest_mac(m_ip_eth_dest_mac), + .m_ip_eth_src_mac(m_ip_eth_src_mac), + .m_ip_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .rx_busy(rx_busy), .tx_busy(tx_busy), diff --git a/tb/test_ip_64.py b/tb/test_ip_64.py index 112c0ab04..e46b77e25 100755 --- a/tb/test_ip_64.py +++ b/tb/test_ip_64.py @@ -51,76 +51,76 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[64:]) - input_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + s_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) arp_request_ready = Signal(bool(0)) arp_response_valid = Signal(bool(0)) arp_response_error = Signal(bool(0)) arp_response_mac = Signal(intbv(0)[48:]) - input_ip_hdr_valid = Signal(bool(0)) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[64:]) - input_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + s_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[64:]) - output_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + m_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) arp_request_valid = Signal(bool(0)) arp_request_ip = Signal(intbv(0)[32:]) arp_response_ready = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_ip_eth_dest_mac = Signal(intbv(0)[48:]) - output_ip_eth_src_mac = Signal(intbv(0)[48:]) - output_ip_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[64:]) - output_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_ip_eth_dest_mac = Signal(intbv(0)[48:]) + m_ip_eth_src_mac = Signal(intbv(0)[48:]) + m_ip_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + m_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) rx_busy = Signal(bool(0)) tx_busy = Signal(bool(0)) rx_error_header_early_termination = Signal(bool(0)) @@ -143,17 +143,17 @@ def bench(): eth_source_logic = eth_source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tkeep=input_eth_payload_tkeep, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tkeep=s_eth_payload_axis_tkeep, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=eth_source_pause, name='eth_source' ) @@ -163,17 +163,17 @@ def bench(): eth_sink_logic = eth_sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=eth_sink_pause, name='eth_sink' ) @@ -183,21 +183,21 @@ def bench(): ip_source_logic = ip_source.create_logic( clk, rst, - ip_hdr_valid=input_ip_hdr_valid, - ip_hdr_ready=input_ip_hdr_ready, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tkeep=input_ip_payload_tkeep, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_valid=s_ip_hdr_valid, + ip_hdr_ready=s_ip_hdr_ready, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tkeep=s_ip_payload_axis_tkeep, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=ip_source_pause, name='ip_source' ) @@ -207,30 +207,30 @@ def bench(): ip_sink_logic = ip_sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_ip_eth_dest_mac, - eth_src_mac=output_ip_eth_src_mac, - eth_type=output_ip_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tkeep=output_ip_payload_tkeep, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_ip_eth_dest_mac, + eth_src_mac=m_ip_eth_src_mac, + eth_type=m_ip_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tkeep=m_ip_payload_axis_tkeep, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=ip_sink_pause, name='ip_sink' ) @@ -267,29 +267,29 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tkeep=input_eth_payload_tkeep, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, arp_request_valid=arp_request_valid, arp_request_ready=arp_request_ready, @@ -299,46 +299,46 @@ def bench(): arp_response_error=arp_response_error, arp_response_mac=arp_response_mac, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tkeep=input_ip_payload_tkeep, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_ip_eth_dest_mac=output_ip_eth_dest_mac, - output_ip_eth_src_mac=output_ip_eth_src_mac, - output_ip_eth_type=output_ip_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tkeep=output_ip_payload_tkeep, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_ip_eth_dest_mac=m_ip_eth_dest_mac, + m_ip_eth_src_mac=m_ip_eth_src_mac, + m_ip_eth_type=m_ip_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, rx_busy=rx_busy, tx_busy=tx_busy, @@ -395,9 +395,9 @@ def bench(): tx_error_arp_failed_asserted.next = 1 def wait_normal(): - while (input_eth_payload_tvalid or input_ip_payload_tvalid or - output_eth_payload_tvalid or output_ip_payload_tvalid or - input_eth_hdr_valid or input_ip_hdr_valid): + while (s_eth_payload_axis_tvalid or s_ip_payload_axis_tvalid or + m_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or + s_eth_hdr_valid or s_ip_hdr_valid): yield clk.posedge @instance diff --git a/tb/test_ip_64.v b/tb/test_ip_64.v index 421bffdf8..a444ec362 100644 --- a/tb/test_ip_64.v +++ b/tb/test_ip_64.v @@ -35,78 +35,78 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [63:0] input_eth_payload_tdata = 0; -reg [7:0] input_eth_payload_tkeep = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [63:0] s_eth_payload_axis_tdata = 0; +reg [7:0] s_eth_payload_axis_tkeep = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; reg arp_request_ready = 0; reg arp_response_valid = 0; reg arp_response_error = 0; reg [47:0] arp_response_mac = 0; -reg input_ip_hdr_valid = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [63:0] input_ip_payload_tdata = 0; -reg [7:0] input_ip_payload_tkeep = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [63:0] s_ip_payload_axis_tdata = 0; +reg [7:0] s_ip_payload_axis_tkeep = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; reg [47:0] local_mac = 0; reg [31:0] local_ip = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [63:0] output_eth_payload_tdata; -wire [7:0] output_eth_payload_tkeep; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [63:0] m_eth_payload_axis_tdata; +wire [7:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire arp_request_valid; wire [31:0] arp_request_ip; wire arp_response_ready; -wire output_ip_hdr_valid; -wire [47:0] output_ip_eth_dest_mac; -wire [47:0] output_ip_eth_src_mac; -wire [15:0] output_ip_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [63:0] output_ip_payload_tdata; -wire [7:0] output_ip_payload_tkeep; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire m_ip_hdr_valid; +wire [47:0] m_ip_eth_dest_mac; +wire [47:0] m_ip_eth_src_mac; +wire [15:0] m_ip_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [63:0] m_ip_payload_axis_tdata; +wire [7:0] m_ip_payload_axis_tkeep; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; wire rx_busy; wire tx_busy; wire rx_error_header_early_termination; @@ -122,78 +122,78 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, arp_request_ready, arp_response_valid, arp_response_error, arp_response_mac, - input_ip_hdr_valid, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_ttl, - input_ip_protocol, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tkeep, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, - output_ip_hdr_ready, - output_ip_payload_tready, + s_ip_hdr_valid, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_ttl, + s_ip_protocol, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, + m_ip_hdr_ready, + m_ip_payload_axis_tready, local_mac, local_ip ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - input_ip_hdr_ready, - input_ip_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, arp_request_valid, arp_request_ip, arp_response_ready, - output_ip_hdr_valid, - output_ip_eth_dest_mac, - output_ip_eth_src_mac, - output_ip_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tkeep, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, + m_ip_hdr_valid, + m_ip_eth_dest_mac, + m_ip_eth_src_mac, + m_ip_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, rx_busy, tx_busy, rx_error_header_early_termination, @@ -214,29 +214,29 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // ARP requests .arp_request_valid(arp_request_valid), .arp_request_ready(arp_request_ready), @@ -246,46 +246,46 @@ UUT ( .arp_response_error(arp_response_error), .arp_response_mac(arp_response_mac), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tkeep(input_ip_payload_tkeep), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_ip_eth_dest_mac(output_ip_eth_dest_mac), - .output_ip_eth_src_mac(output_ip_eth_src_mac), - .output_ip_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_ip_eth_dest_mac(m_ip_eth_dest_mac), + .m_ip_eth_src_mac(m_ip_eth_src_mac), + .m_ip_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .rx_busy(rx_busy), .tx_busy(tx_busy), diff --git a/tb/test_ip_complete.py b/tb/test_ip_complete.py index bf6ec2924..f8a100b70 100755 --- a/tb/test_ip_complete.py +++ b/tb/test_ip_complete.py @@ -60,65 +60,65 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) - input_ip_hdr_valid = Signal(bool(0)) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_ip_eth_dest_mac = Signal(intbv(0)[48:]) - output_ip_eth_src_mac = Signal(intbv(0)[48:]) - output_ip_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_ip_eth_dest_mac = Signal(intbv(0)[48:]) + m_ip_eth_src_mac = Signal(intbv(0)[48:]) + m_ip_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) rx_busy = Signal(bool(0)) tx_busy = Signal(bool(0)) rx_error_header_early_termination = Signal(bool(0)) @@ -144,16 +144,16 @@ def bench(): eth_source_logic = eth_source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=eth_source_pause, name='eth_source' ) @@ -163,16 +163,16 @@ def bench(): eth_sink_logic = eth_sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=eth_sink_pause, name='eth_sink' ) @@ -182,20 +182,20 @@ def bench(): ip_source_logic = ip_source.create_logic( clk, rst, - ip_hdr_valid=input_ip_hdr_valid, - ip_hdr_ready=input_ip_hdr_ready, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_valid=s_ip_hdr_valid, + ip_hdr_ready=s_ip_hdr_ready, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=ip_source_pause, name='ip_source' ) @@ -205,29 +205,29 @@ def bench(): ip_sink_logic = ip_sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_ip_eth_dest_mac, - eth_src_mac=output_ip_eth_src_mac, - eth_type=output_ip_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_ip_eth_dest_mac, + eth_src_mac=m_ip_eth_src_mac, + eth_type=m_ip_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=ip_sink_pause, name='ip_sink' ) @@ -242,66 +242,66 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_ip_eth_dest_mac=output_ip_eth_dest_mac, - output_ip_eth_src_mac=output_ip_eth_src_mac, - output_ip_eth_type=output_ip_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_ip_eth_dest_mac=m_ip_eth_dest_mac, + m_ip_eth_src_mac=m_ip_eth_src_mac, + m_ip_eth_type=m_ip_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, rx_busy=rx_busy, tx_busy=tx_busy, @@ -346,9 +346,9 @@ def bench(): tx_error_arp_failed_asserted.next = 1 def wait_normal(): - while (input_eth_payload_tvalid or input_ip_payload_tvalid or - output_eth_payload_tvalid or output_ip_payload_tvalid or - input_eth_hdr_valid or input_ip_hdr_valid): + while (s_eth_payload_axis_tvalid or s_ip_payload_axis_tvalid or + m_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or + s_eth_hdr_valid or s_ip_hdr_valid): yield clk.posedge @instance diff --git a/tb/test_ip_complete.v b/tb/test_ip_complete.v index 6710822e4..758841649 100644 --- a/tb/test_ip_complete.v +++ b/tb/test_ip_complete.v @@ -42,75 +42,75 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [7:0] input_eth_payload_tdata = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [7:0] s_eth_payload_axis_tdata = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; reg arp_response_valid = 0; reg arp_response_error = 0; reg [47:0] arp_response_mac = 0; -reg input_ip_hdr_valid = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [7:0] input_ip_payload_tdata = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [7:0] s_ip_payload_axis_tdata = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; reg [47:0] local_mac = 0; reg [31:0] local_ip = 0; reg [31:0] gateway_ip = 0; reg [31:0] subnet_mask = 0; -reg clear_arp_cache = 0; +reg clear_arp_cache = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [7:0] output_eth_payload_tdata; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [7:0] m_eth_payload_axis_tdata; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire arp_request_valid; wire [31:0] arp_request_ip; -wire output_ip_hdr_valid; -wire [47:0] output_ip_eth_dest_mac; -wire [47:0] output_ip_eth_src_mac; -wire [15:0] output_ip_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [7:0] output_ip_payload_tdata; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire m_ip_hdr_valid; +wire [47:0] m_ip_eth_dest_mac; +wire [47:0] m_ip_eth_src_mac; +wire [15:0] m_ip_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [7:0] m_ip_payload_axis_tdata; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; wire rx_busy; wire tx_busy; wire rx_error_header_early_termination; @@ -126,30 +126,30 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - input_ip_hdr_valid, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_ttl, - input_ip_protocol, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, - output_ip_hdr_ready, - output_ip_payload_tready, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + s_ip_hdr_valid, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_ttl, + s_ip_protocol, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, + m_ip_hdr_ready, + m_ip_payload_axis_tready, local_mac, local_ip, gateway_ip, @@ -157,39 +157,39 @@ initial begin clear_arp_cache ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - input_ip_hdr_ready, - input_ip_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, - output_ip_hdr_valid, - output_ip_eth_dest_mac, - output_ip_eth_src_mac, - output_ip_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, + m_ip_hdr_valid, + m_ip_eth_dest_mac, + m_ip_eth_src_mac, + m_ip_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, rx_busy, tx_busy, rx_error_header_early_termination, @@ -215,66 +215,66 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_ip_eth_dest_mac(output_ip_eth_dest_mac), - .output_ip_eth_src_mac(output_ip_eth_src_mac), - .output_ip_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_ip_eth_dest_mac(m_ip_eth_dest_mac), + .m_ip_eth_src_mac(m_ip_eth_src_mac), + .m_ip_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .rx_busy(rx_busy), .tx_busy(tx_busy), diff --git a/tb/test_ip_complete_64.py b/tb/test_ip_complete_64.py index 6e32525d2..bdf0f6da5 100755 --- a/tb/test_ip_complete_64.py +++ b/tb/test_ip_complete_64.py @@ -60,69 +60,69 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[64:]) - input_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) - input_ip_hdr_valid = Signal(bool(0)) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[64:]) - input_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + s_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + s_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[64:]) - output_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_ip_eth_dest_mac = Signal(intbv(0)[48:]) - output_ip_eth_src_mac = Signal(intbv(0)[48:]) - output_ip_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[64:]) - output_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + m_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_ip_eth_dest_mac = Signal(intbv(0)[48:]) + m_ip_eth_src_mac = Signal(intbv(0)[48:]) + m_ip_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + m_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) rx_busy = Signal(bool(0)) tx_busy = Signal(bool(0)) rx_error_header_early_termination = Signal(bool(0)) @@ -148,17 +148,17 @@ def bench(): eth_source_logic = eth_source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tkeep=input_eth_payload_tkeep, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tkeep=s_eth_payload_axis_tkeep, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=eth_source_pause, name='eth_source' ) @@ -168,17 +168,17 @@ def bench(): eth_sink_logic = eth_sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=eth_sink_pause, name='eth_sink' ) @@ -188,21 +188,21 @@ def bench(): ip_source_logic = ip_source.create_logic( clk, rst, - ip_hdr_valid=input_ip_hdr_valid, - ip_hdr_ready=input_ip_hdr_ready, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tkeep=input_ip_payload_tkeep, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_valid=s_ip_hdr_valid, + ip_hdr_ready=s_ip_hdr_ready, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tkeep=s_ip_payload_axis_tkeep, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=ip_source_pause, name='ip_source' ) @@ -212,30 +212,30 @@ def bench(): ip_sink_logic = ip_sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_ip_eth_dest_mac, - eth_src_mac=output_ip_eth_src_mac, - eth_type=output_ip_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tkeep=output_ip_payload_tkeep, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_ip_eth_dest_mac, + eth_src_mac=m_ip_eth_src_mac, + eth_type=m_ip_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tkeep=m_ip_payload_axis_tkeep, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=ip_sink_pause, name='ip_sink' ) @@ -250,70 +250,70 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tkeep=input_eth_payload_tkeep, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tkeep=input_ip_payload_tkeep, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_ip_eth_dest_mac=output_ip_eth_dest_mac, - output_ip_eth_src_mac=output_ip_eth_src_mac, - output_ip_eth_type=output_ip_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tkeep=output_ip_payload_tkeep, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_ip_eth_dest_mac=m_ip_eth_dest_mac, + m_ip_eth_src_mac=m_ip_eth_src_mac, + m_ip_eth_type=m_ip_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, rx_busy=rx_busy, tx_busy=tx_busy, @@ -358,9 +358,9 @@ def bench(): tx_error_arp_failed_asserted.next = 1 def wait_normal(): - while (input_eth_payload_tvalid or input_ip_payload_tvalid or - output_eth_payload_tvalid or output_ip_payload_tvalid or - input_eth_hdr_valid or input_ip_hdr_valid): + while (s_eth_payload_axis_tvalid or s_ip_payload_axis_tvalid or + m_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or + s_eth_hdr_valid or s_ip_hdr_valid): yield clk.posedge @instance diff --git a/tb/test_ip_complete_64.v b/tb/test_ip_complete_64.v index 58db828da..f58bff6a7 100644 --- a/tb/test_ip_complete_64.v +++ b/tb/test_ip_complete_64.v @@ -42,79 +42,79 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [63:0] input_eth_payload_tdata = 0; -reg [7:0] input_eth_payload_tkeep = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [63:0] s_eth_payload_axis_tdata = 0; +reg [7:0] s_eth_payload_axis_tkeep = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; reg arp_response_valid = 0; reg arp_response_error = 0; reg [47:0] arp_response_mac = 0; -reg input_ip_hdr_valid = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [63:0] input_ip_payload_tdata = 0; -reg [7:0] input_ip_payload_tkeep = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [63:0] s_ip_payload_axis_tdata = 0; +reg [7:0] s_ip_payload_axis_tkeep = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; reg [47:0] local_mac = 0; reg [31:0] local_ip = 0; reg [31:0] gateway_ip = 0; reg [31:0] subnet_mask = 0; -reg clear_arp_cache = 0; +reg clear_arp_cache = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [63:0] output_eth_payload_tdata; -wire [7:0] output_eth_payload_tkeep; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [63:0] m_eth_payload_axis_tdata; +wire [7:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire arp_request_valid; wire [31:0] arp_request_ip; -wire output_ip_hdr_valid; -wire [47:0] output_ip_eth_dest_mac; -wire [47:0] output_ip_eth_src_mac; -wire [15:0] output_ip_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [63:0] output_ip_payload_tdata; -wire [7:0] output_ip_payload_tkeep; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire m_ip_hdr_valid; +wire [47:0] m_ip_eth_dest_mac; +wire [47:0] m_ip_eth_src_mac; +wire [15:0] m_ip_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [63:0] m_ip_payload_axis_tdata; +wire [7:0] m_ip_payload_axis_tkeep; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; wire rx_busy; wire tx_busy; wire rx_error_header_early_termination; @@ -130,32 +130,32 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - input_ip_hdr_valid, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_ttl, - input_ip_protocol, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tkeep, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, - output_ip_hdr_ready, - output_ip_payload_tready, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + s_ip_hdr_valid, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_ttl, + s_ip_protocol, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, + m_ip_hdr_ready, + m_ip_payload_axis_tready, local_mac, local_ip, gateway_ip, @@ -163,41 +163,41 @@ initial begin clear_arp_cache ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - input_ip_hdr_ready, - input_ip_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, - output_ip_hdr_valid, - output_ip_eth_dest_mac, - output_ip_eth_src_mac, - output_ip_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tkeep, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, + m_ip_hdr_valid, + m_ip_eth_dest_mac, + m_ip_eth_src_mac, + m_ip_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, rx_busy, tx_busy, rx_error_header_early_termination, @@ -223,70 +223,70 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tkeep(input_ip_payload_tkeep), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_ip_eth_dest_mac(output_ip_eth_dest_mac), - .output_ip_eth_src_mac(output_ip_eth_src_mac), - .output_ip_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_ip_eth_dest_mac(m_ip_eth_dest_mac), + .m_ip_eth_src_mac(m_ip_eth_src_mac), + .m_ip_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .rx_busy(rx_busy), .tx_busy(tx_busy), diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index eb964e039..69fa513bf 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -48,41 +48,41 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_header_early_termination = Signal(bool(0)) error_payload_early_termination = Signal(bool(0)) @@ -98,16 +98,16 @@ def bench(): source_logic = source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=source_pause, name='source' ) @@ -117,29 +117,29 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -154,40 +154,40 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, busy=busy, error_header_early_termination=error_header_early_termination, @@ -217,11 +217,11 @@ def bench(): error_invalid_checksum_asserted.next = 1 def wait_normal(): - while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_eth_hdr_valid: yield clk.posedge def wait_pause_source(): - while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_eth_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -230,7 +230,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_eth_hdr_valid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_ip_eth_rx.v b/tb/test_ip_eth_rx.v index b4f4c5e60..7c3b5d34b 100644 --- a/tb/test_ip_eth_rx.v +++ b/tb/test_ip_eth_rx.v @@ -36,41 +36,41 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [7:0] input_eth_payload_tdata = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [7:0] s_eth_payload_axis_tdata = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; -wire output_ip_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [7:0] output_ip_payload_tdata; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; +wire m_ip_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [7:0] m_ip_payload_axis_tdata; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; wire busy; wire error_header_early_termination; wire error_payload_early_termination; @@ -83,41 +83,41 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_ip_hdr_ready, - output_ip_payload_tready + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - output_ip_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_ip_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, busy, error_header_early_termination, error_payload_early_termination, @@ -135,40 +135,40 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .busy(busy), .error_header_early_termination(error_header_early_termination), diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py index 94efbcee4..62b349566 100755 --- a/tb/test_ip_eth_rx_64.py +++ b/tb/test_ip_eth_rx_64.py @@ -48,43 +48,43 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[64:]) - input_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + s_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[64:]) - output_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + m_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_header_early_termination = Signal(bool(0)) error_payload_early_termination = Signal(bool(0)) @@ -100,17 +100,17 @@ def bench(): source_logic = source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tkeep=input_eth_payload_tkeep, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tkeep=s_eth_payload_axis_tkeep, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=source_pause, name='source' ) @@ -120,30 +120,30 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tkeep=output_ip_payload_tkeep, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tkeep=m_ip_payload_axis_tkeep, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -158,42 +158,42 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tkeep=input_eth_payload_tkeep, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tkeep=output_ip_payload_tkeep, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, busy=busy, error_header_early_termination=error_header_early_termination, @@ -223,11 +223,11 @@ def bench(): error_invalid_checksum_asserted.next = 1 def wait_normal(): - while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_eth_hdr_valid: yield clk.posedge def wait_pause_source(): - while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_eth_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -236,7 +236,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_eth_payload_tvalid or output_ip_payload_tvalid or input_eth_hdr_valid: + while s_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_eth_hdr_valid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_ip_eth_rx_64.v b/tb/test_ip_eth_rx_64.v index cb3d62cc9..0293a2b02 100644 --- a/tb/test_ip_eth_rx_64.v +++ b/tb/test_ip_eth_rx_64.v @@ -36,43 +36,43 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [63:0] input_eth_payload_tdata = 0; -reg [7:0] input_eth_payload_tkeep = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [63:0] s_eth_payload_axis_tdata = 0; +reg [7:0] s_eth_payload_axis_tkeep = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; -wire output_ip_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [63:0] output_ip_payload_tdata; -wire [7:0] output_ip_payload_tkeep; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; +wire m_ip_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [63:0] m_ip_payload_axis_tdata; +wire [7:0] m_ip_payload_axis_tkeep; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; wire busy; wire error_header_early_termination; wire error_payload_early_termination; @@ -85,43 +85,43 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - output_ip_hdr_ready, - output_ip_payload_tready + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - output_ip_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tkeep, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + m_ip_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, busy, error_header_early_termination, error_payload_early_termination, @@ -139,42 +139,42 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .busy(busy), .error_header_early_termination(error_header_early_termination), diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py index 2fea6d751..50cbaaba1 100755 --- a/tb/test_ip_eth_tx.py +++ b/tb/test_ip_eth_tx.py @@ -48,38 +48,38 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_ip_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) # Outputs - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_payload_early_termination = Signal(bool(0)) @@ -92,26 +92,26 @@ def bench(): source_logic = source.create_logic( clk, rst, - ip_hdr_ready=input_ip_hdr_ready, - ip_hdr_valid=input_ip_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_ready=s_ip_hdr_ready, + ip_hdr_valid=s_ip_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=source_pause, name='source' ) @@ -121,16 +121,16 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -145,37 +145,37 @@ def bench(): rst=rst, current_test=current_test, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, busy=busy, error_payload_early_termination=error_payload_early_termination @@ -193,11 +193,11 @@ def bench(): error_payload_early_termination_asserted.next = 1 def wait_normal(): - while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_eth_payload_axis_tvalid or s_ip_hdr_valid: yield clk.posedge def wait_pause_source(): - while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_eth_payload_axis_tvalid or s_ip_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -206,7 +206,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_eth_payload_axis_tvalid or s_ip_hdr_valid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_ip_eth_tx.v b/tb/test_ip_eth_tx.v index 08e96f1ed..5a2a289f2 100644 --- a/tb/test_ip_eth_tx.v +++ b/tb/test_ip_eth_tx.v @@ -36,38 +36,38 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_ip_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [7:0] input_ip_payload_tdata = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [7:0] s_ip_payload_axis_tdata = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; // Outputs -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [7:0] output_eth_payload_tdata; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [7:0] m_eth_payload_axis_tdata; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire busy; wire error_payload_early_termination; @@ -77,38 +77,38 @@ initial begin clk, rst, current_test, - input_ip_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready + s_ip_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready ); $to_myhdl( - input_ip_hdr_ready, - input_ip_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, busy, error_payload_early_termination ); @@ -123,37 +123,37 @@ UUT ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Status signals .busy(busy), .error_payload_early_termination(error_payload_early_termination) diff --git a/tb/test_ip_eth_tx_64.py b/tb/test_ip_eth_tx_64.py index dde510986..d528db9a3 100755 --- a/tb/test_ip_eth_tx_64.py +++ b/tb/test_ip_eth_tx_64.py @@ -48,40 +48,40 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_ip_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[64:]) - input_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + s_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) # Outputs - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[64:]) - output_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + m_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_payload_early_termination = Signal(bool(0)) @@ -94,27 +94,27 @@ def bench(): source_logic = source.create_logic( clk, rst, - ip_hdr_ready=input_ip_hdr_ready, - ip_hdr_valid=input_ip_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tkeep=input_ip_payload_tkeep, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_ready=s_ip_hdr_ready, + ip_hdr_valid=s_ip_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tkeep=s_ip_payload_axis_tkeep, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=source_pause, name='source' ) @@ -124,17 +124,17 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -149,39 +149,39 @@ def bench(): rst=rst, current_test=current_test, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tkeep=input_ip_payload_tkeep, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, busy=busy, error_payload_early_termination=error_payload_early_termination @@ -199,11 +199,11 @@ def bench(): error_payload_early_termination_asserted.next = 1 def wait_normal(): - while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_eth_payload_axis_tvalid or s_ip_hdr_valid: yield clk.posedge def wait_pause_source(): - while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_eth_payload_axis_tvalid or s_ip_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -212,7 +212,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_ip_payload_tvalid or output_eth_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_eth_payload_axis_tvalid or s_ip_hdr_valid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_ip_eth_tx_64.v b/tb/test_ip_eth_tx_64.v index ea576f799..7d52d554d 100644 --- a/tb/test_ip_eth_tx_64.v +++ b/tb/test_ip_eth_tx_64.v @@ -36,40 +36,40 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_ip_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [63:0] input_ip_payload_tdata = 0; -reg [7:0] input_ip_payload_tkeep = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [63:0] s_ip_payload_axis_tdata = 0; +reg [7:0] s_ip_payload_axis_tkeep = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; // Outputs -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [63:0] output_eth_payload_tdata; -wire [7:0] output_eth_payload_tkeep; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [63:0] m_eth_payload_axis_tdata; +wire [7:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire busy; wire error_payload_early_termination; @@ -79,40 +79,40 @@ initial begin clk, rst, current_test, - input_ip_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tkeep, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready + s_ip_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready ); $to_myhdl( - input_ip_hdr_ready, - input_ip_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, busy, error_payload_early_termination ); @@ -127,39 +127,39 @@ UUT ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tkeep(input_ip_payload_tkeep), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // Status signals .busy(busy), .error_payload_early_termination(error_payload_early_termination) diff --git a/tb/test_udp.py b/tb/test_udp.py index a4a5c4033..a1e2da1a8 100755 --- a/tb/test_udp.py +++ b/tb/test_udp.py @@ -53,106 +53,106 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_ip_hdr_valid = Signal(bool(0)) - input_ip_eth_dest_mac = Signal(intbv(0)[48:]) - input_ip_eth_src_mac = Signal(intbv(0)[48:]) - input_ip_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - input_udp_hdr_valid = Signal(bool(0)) - input_udp_eth_dest_mac = Signal(intbv(0)[48:]) - input_udp_eth_src_mac = Signal(intbv(0)[48:]) - input_udp_eth_type = Signal(intbv(0)[16:]) - input_udp_ip_version = Signal(intbv(0)[4:]) - input_udp_ip_ihl = Signal(intbv(0)[4:]) - input_udp_ip_dscp = Signal(intbv(0)[6:]) - input_udp_ip_ecn = Signal(intbv(0)[2:]) - input_udp_ip_identification = Signal(intbv(0)[16:]) - input_udp_ip_flags = Signal(intbv(0)[3:]) - input_udp_ip_fragment_offset = Signal(intbv(0)[13:]) - input_udp_ip_ttl = Signal(intbv(0)[8:]) - input_udp_ip_header_checksum = Signal(intbv(0)[16:]) - input_udp_ip_source_ip = Signal(intbv(0)[32:]) - input_udp_ip_dest_ip = Signal(intbv(0)[32:]) - input_udp_source_port = Signal(intbv(0)[16:]) - input_udp_dest_port = Signal(intbv(0)[16:]) - input_udp_length = Signal(intbv(0)[16:]) - input_udp_checksum = Signal(intbv(0)[16:]) - input_udp_payload_tdata = Signal(intbv(0)[8:]) - input_udp_payload_tvalid = Signal(bool(0)) - input_udp_payload_tlast = Signal(bool(0)) - input_udp_payload_tuser = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) - output_udp_payload_tready = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_ip_eth_dest_mac = Signal(intbv(0)[48:]) + s_ip_eth_src_mac = Signal(intbv(0)[48:]) + s_ip_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + s_udp_hdr_valid = Signal(bool(0)) + s_udp_eth_dest_mac = Signal(intbv(0)[48:]) + s_udp_eth_src_mac = Signal(intbv(0)[48:]) + s_udp_eth_type = Signal(intbv(0)[16:]) + s_udp_ip_version = Signal(intbv(0)[4:]) + s_udp_ip_ihl = Signal(intbv(0)[4:]) + s_udp_ip_dscp = Signal(intbv(0)[6:]) + s_udp_ip_ecn = Signal(intbv(0)[2:]) + s_udp_ip_identification = Signal(intbv(0)[16:]) + s_udp_ip_flags = Signal(intbv(0)[3:]) + s_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + s_udp_ip_ttl = Signal(intbv(0)[8:]) + s_udp_ip_header_checksum = Signal(intbv(0)[16:]) + s_udp_ip_source_ip = Signal(intbv(0)[32:]) + s_udp_ip_dest_ip = Signal(intbv(0)[32:]) + s_udp_source_port = Signal(intbv(0)[16:]) + s_udp_dest_port = Signal(intbv(0)[16:]) + s_udp_length = Signal(intbv(0)[16:]) + s_udp_checksum = Signal(intbv(0)[16:]) + s_udp_payload_axis_tdata = Signal(intbv(0)[8:]) + s_udp_payload_axis_tvalid = Signal(bool(0)) + s_udp_payload_axis_tlast = Signal(bool(0)) + s_udp_payload_axis_tuser = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) # Outputs - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - input_udp_hdr_ready = Signal(bool(0)) - input_udp_payload_tready = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_ip_eth_dest_mac = Signal(intbv(0)[48:]) - output_ip_eth_src_mac = Signal(intbv(0)[48:]) - output_ip_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) - output_udp_hdr_valid = Signal(bool(0)) - output_udp_eth_dest_mac = Signal(intbv(0)[48:]) - output_udp_eth_src_mac = Signal(intbv(0)[48:]) - output_udp_eth_type = Signal(intbv(0)[16:]) - output_udp_ip_version = Signal(intbv(0)[4:]) - output_udp_ip_ihl = Signal(intbv(0)[4:]) - output_udp_ip_dscp = Signal(intbv(0)[6:]) - output_udp_ip_ecn = Signal(intbv(0)[2:]) - output_udp_ip_length = Signal(intbv(0)[16:]) - output_udp_ip_identification = Signal(intbv(0)[16:]) - output_udp_ip_flags = Signal(intbv(0)[3:]) - output_udp_ip_fragment_offset = Signal(intbv(0)[13:]) - output_udp_ip_ttl = Signal(intbv(0)[8:]) - output_udp_ip_protocol = Signal(intbv(0)[8:]) - output_udp_ip_header_checksum = Signal(intbv(0)[16:]) - output_udp_ip_source_ip = Signal(intbv(0)[32:]) - output_udp_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(bool(0)) + s_udp_payload_axis_tready = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_ip_eth_dest_mac = Signal(intbv(0)[48:]) + m_ip_eth_src_mac = Signal(intbv(0)[48:]) + m_ip_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) + m_udp_hdr_valid = Signal(bool(0)) + m_udp_eth_dest_mac = Signal(intbv(0)[48:]) + m_udp_eth_src_mac = Signal(intbv(0)[48:]) + m_udp_eth_type = Signal(intbv(0)[16:]) + m_udp_ip_version = Signal(intbv(0)[4:]) + m_udp_ip_ihl = Signal(intbv(0)[4:]) + m_udp_ip_dscp = Signal(intbv(0)[6:]) + m_udp_ip_ecn = Signal(intbv(0)[2:]) + m_udp_ip_length = Signal(intbv(0)[16:]) + m_udp_ip_identification = Signal(intbv(0)[16:]) + m_udp_ip_flags = Signal(intbv(0)[3:]) + m_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + m_udp_ip_ttl = Signal(intbv(0)[8:]) + m_udp_ip_protocol = Signal(intbv(0)[8:]) + m_udp_ip_header_checksum = Signal(intbv(0)[16:]) + m_udp_ip_source_ip = Signal(intbv(0)[32:]) + m_udp_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[8:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tuser = Signal(bool(0)) rx_busy = Signal(bool(0)) tx_busy = Signal(bool(0)) rx_error_header_early_termination = Signal(bool(0)) @@ -170,29 +170,29 @@ def bench(): ip_source_logic = ip_source.create_logic( clk, rst, - ip_hdr_ready=input_ip_hdr_ready, - ip_hdr_valid=input_ip_hdr_valid, - eth_dest_mac=input_ip_eth_dest_mac, - eth_src_mac=input_ip_eth_src_mac, - eth_type=input_ip_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_ready=s_ip_hdr_ready, + ip_hdr_valid=s_ip_hdr_valid, + eth_dest_mac=s_ip_eth_dest_mac, + eth_src_mac=s_ip_eth_src_mac, + eth_type=s_ip_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=ip_source_pause, name='ip_source' ) @@ -202,29 +202,29 @@ def bench(): ip_sink_logic = ip_sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_ip_eth_dest_mac, - eth_src_mac=output_ip_eth_src_mac, - eth_type=output_ip_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_ip_eth_dest_mac, + eth_src_mac=m_ip_eth_src_mac, + eth_type=m_ip_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=ip_sink_pause, name='ip_sink' ) @@ -234,31 +234,31 @@ def bench(): udp_source_logic = udp_source.create_logic( clk, rst, - udp_hdr_ready=input_udp_hdr_ready, - udp_hdr_valid=input_udp_hdr_valid, - eth_dest_mac=input_udp_eth_dest_mac, - eth_src_mac=input_udp_eth_src_mac, - eth_type=input_udp_eth_type, - ip_version=input_udp_ip_version, - ip_ihl=input_udp_ip_ihl, - ip_dscp=input_udp_ip_dscp, - ip_ecn=input_udp_ip_ecn, - ip_identification=input_udp_ip_identification, - ip_flags=input_udp_ip_flags, - ip_fragment_offset=input_udp_ip_fragment_offset, - ip_ttl=input_udp_ip_ttl, - ip_header_checksum=input_udp_ip_header_checksum, - ip_source_ip=input_udp_ip_source_ip, - ip_dest_ip=input_udp_ip_dest_ip, - udp_source_port=input_udp_source_port, - udp_dest_port=input_udp_dest_port, - udp_length=input_udp_length, - udp_checksum=input_udp_checksum, - udp_payload_tdata=input_udp_payload_tdata, - udp_payload_tvalid=input_udp_payload_tvalid, - udp_payload_tready=input_udp_payload_tready, - udp_payload_tlast=input_udp_payload_tlast, - udp_payload_tuser=input_udp_payload_tuser, + udp_hdr_ready=s_udp_hdr_ready, + udp_hdr_valid=s_udp_hdr_valid, + eth_dest_mac=s_udp_eth_dest_mac, + eth_src_mac=s_udp_eth_src_mac, + eth_type=s_udp_eth_type, + ip_version=s_udp_ip_version, + ip_ihl=s_udp_ip_ihl, + ip_dscp=s_udp_ip_dscp, + ip_ecn=s_udp_ip_ecn, + ip_identification=s_udp_ip_identification, + ip_flags=s_udp_ip_flags, + ip_fragment_offset=s_udp_ip_fragment_offset, + ip_ttl=s_udp_ip_ttl, + ip_header_checksum=s_udp_ip_header_checksum, + ip_source_ip=s_udp_ip_source_ip, + ip_dest_ip=s_udp_ip_dest_ip, + udp_source_port=s_udp_source_port, + udp_dest_port=s_udp_dest_port, + udp_length=s_udp_length, + udp_checksum=s_udp_checksum, + udp_payload_tdata=s_udp_payload_axis_tdata, + udp_payload_tvalid=s_udp_payload_axis_tvalid, + udp_payload_tready=s_udp_payload_axis_tready, + udp_payload_tlast=s_udp_payload_axis_tlast, + udp_payload_tuser=s_udp_payload_axis_tuser, pause=udp_source_pause, name='udp_source' ) @@ -268,33 +268,33 @@ def bench(): udp_sink_logic = udp_sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_udp_eth_dest_mac, - eth_src_mac=output_udp_eth_src_mac, - eth_type=output_udp_eth_type, - ip_version=output_udp_ip_version, - ip_ihl=output_udp_ip_ihl, - ip_dscp=output_udp_ip_dscp, - ip_ecn=output_udp_ip_ecn, - ip_length=output_udp_ip_length, - ip_identification=output_udp_ip_identification, - ip_flags=output_udp_ip_flags, - ip_fragment_offset=output_udp_ip_fragment_offset, - ip_ttl=output_udp_ip_ttl, - ip_protocol=output_udp_ip_protocol, - ip_header_checksum=output_udp_ip_header_checksum, - ip_source_ip=output_udp_ip_source_ip, - ip_dest_ip=output_udp_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_udp_eth_dest_mac, + eth_src_mac=m_udp_eth_src_mac, + eth_type=m_udp_eth_type, + ip_version=m_udp_ip_version, + ip_ihl=m_udp_ip_ihl, + ip_dscp=m_udp_ip_dscp, + ip_ecn=m_udp_ip_ecn, + ip_length=m_udp_ip_length, + ip_identification=m_udp_ip_identification, + ip_flags=m_udp_ip_flags, + ip_fragment_offset=m_udp_ip_fragment_offset, + ip_ttl=m_udp_ip_ttl, + ip_protocol=m_udp_ip_protocol, + ip_header_checksum=m_udp_ip_header_checksum, + ip_source_ip=m_udp_ip_source_ip, + ip_dest_ip=m_udp_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=udp_sink_pause, name='udp_sink' ) @@ -309,107 +309,107 @@ def bench(): rst=rst, current_test=current_test, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_ip_eth_dest_mac=input_ip_eth_dest_mac, - input_ip_eth_src_mac=input_ip_eth_src_mac, - input_ip_eth_type=input_ip_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_ip_eth_dest_mac=s_ip_eth_dest_mac, + s_ip_eth_src_mac=s_ip_eth_src_mac, + s_ip_eth_type=s_ip_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_ip_eth_dest_mac=output_ip_eth_dest_mac, - output_ip_eth_src_mac=output_ip_eth_src_mac, - output_ip_eth_type=output_ip_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_ip_eth_dest_mac=m_ip_eth_dest_mac, + m_ip_eth_src_mac=m_ip_eth_src_mac, + m_ip_eth_type=m_ip_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, - input_udp_hdr_valid=input_udp_hdr_valid, - input_udp_hdr_ready=input_udp_hdr_ready, - input_udp_eth_dest_mac=input_udp_eth_dest_mac, - input_udp_eth_src_mac=input_udp_eth_src_mac, - input_udp_eth_type=input_udp_eth_type, - input_udp_ip_version=input_udp_ip_version, - input_udp_ip_ihl=input_udp_ip_ihl, - input_udp_ip_dscp=input_udp_ip_dscp, - input_udp_ip_ecn=input_udp_ip_ecn, - input_udp_ip_identification=input_udp_ip_identification, - input_udp_ip_flags=input_udp_ip_flags, - input_udp_ip_fragment_offset=input_udp_ip_fragment_offset, - input_udp_ip_ttl=input_udp_ip_ttl, - input_udp_ip_header_checksum=input_udp_ip_header_checksum, - input_udp_ip_source_ip=input_udp_ip_source_ip, - input_udp_ip_dest_ip=input_udp_ip_dest_ip, - input_udp_source_port=input_udp_source_port, - input_udp_dest_port=input_udp_dest_port, - input_udp_length=input_udp_length, - input_udp_checksum=input_udp_checksum, - input_udp_payload_tdata=input_udp_payload_tdata, - input_udp_payload_tvalid=input_udp_payload_tvalid, - input_udp_payload_tready=input_udp_payload_tready, - input_udp_payload_tlast=input_udp_payload_tlast, - input_udp_payload_tuser=input_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_udp_eth_dest_mac=s_udp_eth_dest_mac, + s_udp_eth_src_mac=s_udp_eth_src_mac, + s_udp_eth_type=s_udp_eth_type, + s_udp_ip_version=s_udp_ip_version, + s_udp_ip_ihl=s_udp_ip_ihl, + s_udp_ip_dscp=s_udp_ip_dscp, + s_udp_ip_ecn=s_udp_ip_ecn, + s_udp_ip_identification=s_udp_ip_identification, + s_udp_ip_flags=s_udp_ip_flags, + s_udp_ip_fragment_offset=s_udp_ip_fragment_offset, + s_udp_ip_ttl=s_udp_ip_ttl, + s_udp_ip_header_checksum=s_udp_ip_header_checksum, + s_udp_ip_source_ip=s_udp_ip_source_ip, + s_udp_ip_dest_ip=s_udp_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_udp_eth_dest_mac=output_udp_eth_dest_mac, - output_udp_eth_src_mac=output_udp_eth_src_mac, - output_udp_eth_type=output_udp_eth_type, - output_udp_ip_version=output_udp_ip_version, - output_udp_ip_ihl=output_udp_ip_ihl, - output_udp_ip_dscp=output_udp_ip_dscp, - output_udp_ip_ecn=output_udp_ip_ecn, - output_udp_ip_length=output_udp_ip_length, - output_udp_ip_identification=output_udp_ip_identification, - output_udp_ip_flags=output_udp_ip_flags, - output_udp_ip_fragment_offset=output_udp_ip_fragment_offset, - output_udp_ip_ttl=output_udp_ip_ttl, - output_udp_ip_protocol=output_udp_ip_protocol, - output_udp_ip_header_checksum=output_udp_ip_header_checksum, - output_udp_ip_source_ip=output_udp_ip_source_ip, - output_udp_ip_dest_ip=output_udp_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_udp_eth_dest_mac=m_udp_eth_dest_mac, + m_udp_eth_src_mac=m_udp_eth_src_mac, + m_udp_eth_type=m_udp_eth_type, + m_udp_ip_version=m_udp_ip_version, + m_udp_ip_ihl=m_udp_ip_ihl, + m_udp_ip_dscp=m_udp_ip_dscp, + m_udp_ip_ecn=m_udp_ip_ecn, + m_udp_ip_length=m_udp_ip_length, + m_udp_ip_identification=m_udp_ip_identification, + m_udp_ip_flags=m_udp_ip_flags, + m_udp_ip_fragment_offset=m_udp_ip_fragment_offset, + m_udp_ip_ttl=m_udp_ip_ttl, + m_udp_ip_protocol=m_udp_ip_protocol, + m_udp_ip_header_checksum=m_udp_ip_header_checksum, + m_udp_ip_source_ip=m_udp_ip_source_ip, + m_udp_ip_dest_ip=m_udp_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, rx_busy=rx_busy, tx_busy=tx_busy, diff --git a/tb/test_udp.v b/tb/test_udp.v index 39f425bf8..aa0c71b40 100644 --- a/tb/test_udp.v +++ b/tb/test_udp.v @@ -41,106 +41,106 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_ip_hdr_valid = 0; -reg [47:0] input_ip_eth_dest_mac = 0; -reg [47:0] input_ip_eth_src_mac = 0; -reg [15:0] input_ip_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [7:0] input_ip_payload_tdata = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg input_udp_hdr_valid = 0; -reg [47:0] input_udp_eth_dest_mac = 0; -reg [47:0] input_udp_eth_src_mac = 0; -reg [15:0] input_udp_eth_type = 0; -reg [3:0] input_udp_ip_version = 0; -reg [3:0] input_udp_ip_ihl = 0; -reg [5:0] input_udp_ip_dscp = 0; -reg [1:0] input_udp_ip_ecn = 0; -reg [15:0] input_udp_ip_identification = 0; -reg [2:0] input_udp_ip_flags = 0; -reg [12:0] input_udp_ip_fragment_offset = 0; -reg [7:0] input_udp_ip_ttl = 0; -reg [15:0] input_udp_ip_header_checksum = 0; -reg [31:0] input_udp_ip_source_ip = 0; -reg [31:0] input_udp_ip_dest_ip = 0; -reg [15:0] input_udp_source_port = 0; -reg [15:0] input_udp_dest_port = 0; -reg [15:0] input_udp_length = 0; -reg [15:0] input_udp_checksum = 0; -reg [7:0] input_udp_payload_tdata = 0; -reg input_udp_payload_tvalid = 0; -reg input_udp_payload_tlast = 0; -reg input_udp_payload_tuser = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [47:0] s_ip_eth_dest_mac = 0; +reg [47:0] s_ip_eth_src_mac = 0; +reg [15:0] s_ip_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [7:0] s_ip_payload_axis_tdata = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg s_udp_hdr_valid = 0; +reg [47:0] s_udp_eth_dest_mac = 0; +reg [47:0] s_udp_eth_src_mac = 0; +reg [15:0] s_udp_eth_type = 0; +reg [3:0] s_udp_ip_version = 0; +reg [3:0] s_udp_ip_ihl = 0; +reg [5:0] s_udp_ip_dscp = 0; +reg [1:0] s_udp_ip_ecn = 0; +reg [15:0] s_udp_ip_identification = 0; +reg [2:0] s_udp_ip_flags = 0; +reg [12:0] s_udp_ip_fragment_offset = 0; +reg [7:0] s_udp_ip_ttl = 0; +reg [15:0] s_udp_ip_header_checksum = 0; +reg [31:0] s_udp_ip_source_ip = 0; +reg [31:0] s_udp_ip_dest_ip = 0; +reg [15:0] s_udp_source_port = 0; +reg [15:0] s_udp_dest_port = 0; +reg [15:0] s_udp_length = 0; +reg [15:0] s_udp_checksum = 0; +reg [7:0] s_udp_payload_axis_tdata = 0; +reg s_udp_payload_axis_tvalid = 0; +reg s_udp_payload_axis_tlast = 0; +reg s_udp_payload_axis_tuser = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; // Outputs -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire input_udp_hdr_ready; -wire input_udp_payload_tready; -wire output_ip_hdr_valid; -wire [47:0] output_ip_eth_dest_mac; -wire [47:0] output_ip_eth_src_mac; -wire [15:0] output_ip_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [7:0] output_ip_payload_tdata; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; -wire output_udp_hdr_valid; -wire [47:0] output_udp_eth_dest_mac; -wire [47:0] output_udp_eth_src_mac; -wire [15:0] output_udp_eth_type; -wire [3:0] output_udp_ip_version; -wire [3:0] output_udp_ip_ihl; -wire [5:0] output_udp_ip_dscp; -wire [1:0] output_udp_ip_ecn; -wire [15:0] output_udp_ip_length; -wire [15:0] output_udp_ip_identification; -wire [2:0] output_udp_ip_flags; -wire [12:0] output_udp_ip_fragment_offset; -wire [7:0] output_udp_ip_ttl; -wire [7:0] output_udp_ip_protocol; -wire [15:0] output_udp_ip_header_checksum; -wire [31:0] output_udp_ip_source_ip; -wire [31:0] output_udp_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [7:0] output_udp_payload_tdata; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire s_udp_hdr_ready; +wire s_udp_payload_axis_tready; +wire m_ip_hdr_valid; +wire [47:0] m_ip_eth_dest_mac; +wire [47:0] m_ip_eth_src_mac; +wire [15:0] m_ip_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [7:0] m_ip_payload_axis_tdata; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; +wire m_udp_hdr_valid; +wire [47:0] m_udp_eth_dest_mac; +wire [47:0] m_udp_eth_src_mac; +wire [15:0] m_udp_eth_type; +wire [3:0] m_udp_ip_version; +wire [3:0] m_udp_ip_ihl; +wire [5:0] m_udp_ip_dscp; +wire [1:0] m_udp_ip_ecn; +wire [15:0] m_udp_ip_length; +wire [15:0] m_udp_ip_identification; +wire [2:0] m_udp_ip_flags; +wire [12:0] m_udp_ip_fragment_offset; +wire [7:0] m_udp_ip_ttl; +wire [7:0] m_udp_ip_protocol; +wire [15:0] m_udp_ip_header_checksum; +wire [31:0] m_udp_ip_source_ip; +wire [31:0] m_udp_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [7:0] m_udp_payload_axis_tdata; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire m_udp_payload_axis_tuser; wire rx_busy; wire tx_busy; wire rx_error_header_early_termination; @@ -153,106 +153,106 @@ initial begin clk, rst, current_test, - input_ip_hdr_valid, - input_ip_eth_dest_mac, - input_ip_eth_src_mac, - input_ip_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - input_udp_hdr_valid, - input_udp_eth_dest_mac, - input_udp_eth_src_mac, - input_udp_eth_type, - input_udp_ip_version, - input_udp_ip_ihl, - input_udp_ip_dscp, - input_udp_ip_ecn, - input_udp_ip_identification, - input_udp_ip_flags, - input_udp_ip_fragment_offset, - input_udp_ip_ttl, - input_udp_ip_header_checksum, - input_udp_ip_source_ip, - input_udp_ip_dest_ip, - input_udp_source_port, - input_udp_dest_port, - input_udp_length, - input_udp_checksum, - input_udp_payload_tdata, - input_udp_payload_tvalid, - input_udp_payload_tlast, - input_udp_payload_tuser, - output_ip_hdr_ready, - output_ip_payload_tready, - output_udp_hdr_ready, - output_udp_payload_tready + s_ip_hdr_valid, + s_ip_eth_dest_mac, + s_ip_eth_src_mac, + s_ip_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + s_udp_hdr_valid, + s_udp_eth_dest_mac, + s_udp_eth_src_mac, + s_udp_eth_type, + s_udp_ip_version, + s_udp_ip_ihl, + s_udp_ip_dscp, + s_udp_ip_ecn, + s_udp_ip_identification, + s_udp_ip_flags, + s_udp_ip_fragment_offset, + s_udp_ip_ttl, + s_udp_ip_header_checksum, + s_udp_ip_source_ip, + s_udp_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready, + m_udp_hdr_ready, + m_udp_payload_axis_tready ); $to_myhdl( - input_ip_hdr_ready, - input_ip_payload_tready, - input_udp_hdr_ready, - input_udp_payload_tready, - output_ip_hdr_valid, - output_ip_eth_dest_mac, - output_ip_eth_src_mac, - output_ip_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, - output_udp_hdr_valid, - output_udp_eth_dest_mac, - output_udp_eth_src_mac, - output_udp_eth_type, - output_udp_ip_version, - output_udp_ip_ihl, - output_udp_ip_dscp, - output_udp_ip_ecn, - output_udp_ip_length, - output_udp_ip_identification, - output_udp_ip_flags, - output_udp_ip_fragment_offset, - output_udp_ip_ttl, - output_udp_ip_protocol, - output_udp_ip_header_checksum, - output_udp_ip_source_ip, - output_udp_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_ip_hdr_valid, + m_ip_eth_dest_mac, + m_ip_eth_src_mac, + m_ip_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, + m_udp_hdr_valid, + m_udp_eth_dest_mac, + m_udp_eth_src_mac, + m_udp_eth_type, + m_udp_ip_version, + m_udp_ip_ihl, + m_udp_ip_dscp, + m_udp_ip_ecn, + m_udp_ip_length, + m_udp_ip_identification, + m_udp_ip_flags, + m_udp_ip_fragment_offset, + m_udp_ip_ttl, + m_udp_ip_protocol, + m_udp_ip_header_checksum, + m_udp_ip_source_ip, + m_udp_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser, rx_busy, tx_busy, rx_error_header_early_termination, @@ -274,107 +274,107 @@ UUT ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_ip_eth_dest_mac(input_ip_eth_dest_mac), - .input_ip_eth_src_mac(input_ip_eth_src_mac), - .input_ip_eth_type(input_ip_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_ip_eth_dest_mac(s_ip_eth_dest_mac), + .s_ip_eth_src_mac(s_ip_eth_src_mac), + .s_ip_eth_type(s_ip_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_ip_eth_dest_mac(output_ip_eth_dest_mac), - .output_ip_eth_src_mac(output_ip_eth_src_mac), - .output_ip_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_ip_eth_dest_mac(m_ip_eth_dest_mac), + .m_ip_eth_src_mac(m_ip_eth_src_mac), + .m_ip_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_udp_eth_dest_mac(input_udp_eth_dest_mac), - .input_udp_eth_src_mac(input_udp_eth_src_mac), - .input_udp_eth_type(input_udp_eth_type), - .input_udp_ip_version(input_udp_ip_version), - .input_udp_ip_ihl(input_udp_ip_ihl), - .input_udp_ip_dscp(input_udp_ip_dscp), - .input_udp_ip_ecn(input_udp_ip_ecn), - .input_udp_ip_identification(input_udp_ip_identification), - .input_udp_ip_flags(input_udp_ip_flags), - .input_udp_ip_fragment_offset(input_udp_ip_fragment_offset), - .input_udp_ip_ttl(input_udp_ip_ttl), - .input_udp_ip_header_checksum(input_udp_ip_header_checksum), - .input_udp_ip_source_ip(input_udp_ip_source_ip), - .input_udp_ip_dest_ip(input_udp_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), - .input_udp_checksum(input_udp_checksum), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_udp_eth_dest_mac(s_udp_eth_dest_mac), + .s_udp_eth_src_mac(s_udp_eth_src_mac), + .s_udp_eth_type(s_udp_eth_type), + .s_udp_ip_version(s_udp_ip_version), + .s_udp_ip_ihl(s_udp_ip_ihl), + .s_udp_ip_dscp(s_udp_ip_dscp), + .s_udp_ip_ecn(s_udp_ip_ecn), + .s_udp_ip_identification(s_udp_ip_identification), + .s_udp_ip_flags(s_udp_ip_flags), + .s_udp_ip_fragment_offset(s_udp_ip_fragment_offset), + .s_udp_ip_ttl(s_udp_ip_ttl), + .s_udp_ip_header_checksum(s_udp_ip_header_checksum), + .s_udp_ip_source_ip(s_udp_ip_source_ip), + .s_udp_ip_dest_ip(s_udp_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_udp_eth_dest_mac(output_udp_eth_dest_mac), - .output_udp_eth_src_mac(output_udp_eth_src_mac), - .output_udp_eth_type(output_udp_eth_type), - .output_udp_ip_version(output_udp_ip_version), - .output_udp_ip_ihl(output_udp_ip_ihl), - .output_udp_ip_dscp(output_udp_ip_dscp), - .output_udp_ip_ecn(output_udp_ip_ecn), - .output_udp_ip_length(output_udp_ip_length), - .output_udp_ip_identification(output_udp_ip_identification), - .output_udp_ip_flags(output_udp_ip_flags), - .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), - .output_udp_ip_ttl(output_udp_ip_ttl), - .output_udp_ip_protocol(output_udp_ip_protocol), - .output_udp_ip_header_checksum(output_udp_ip_header_checksum), - .output_udp_ip_source_ip(output_udp_ip_source_ip), - .output_udp_ip_dest_ip(output_udp_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_udp_eth_dest_mac(m_udp_eth_dest_mac), + .m_udp_eth_src_mac(m_udp_eth_src_mac), + .m_udp_eth_type(m_udp_eth_type), + .m_udp_ip_version(m_udp_ip_version), + .m_udp_ip_ihl(m_udp_ip_ihl), + .m_udp_ip_dscp(m_udp_ip_dscp), + .m_udp_ip_ecn(m_udp_ip_ecn), + .m_udp_ip_length(m_udp_ip_length), + .m_udp_ip_identification(m_udp_ip_identification), + .m_udp_ip_flags(m_udp_ip_flags), + .m_udp_ip_fragment_offset(m_udp_ip_fragment_offset), + .m_udp_ip_ttl(m_udp_ip_ttl), + .m_udp_ip_protocol(m_udp_ip_protocol), + .m_udp_ip_header_checksum(m_udp_ip_header_checksum), + .m_udp_ip_source_ip(m_udp_ip_source_ip), + .m_udp_ip_dest_ip(m_udp_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Status signals .rx_busy(rx_busy), .tx_busy(tx_busy), diff --git a/tb/test_udp_64.py b/tb/test_udp_64.py index b11939f10..941f3dcf8 100755 --- a/tb/test_udp_64.py +++ b/tb/test_udp_64.py @@ -53,110 +53,110 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_ip_hdr_valid = Signal(bool(0)) - input_ip_eth_dest_mac = Signal(intbv(0)[48:]) - input_ip_eth_src_mac = Signal(intbv(0)[48:]) - input_ip_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[64:]) - input_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - input_udp_hdr_valid = Signal(bool(0)) - input_udp_eth_dest_mac = Signal(intbv(0)[48:]) - input_udp_eth_src_mac = Signal(intbv(0)[48:]) - input_udp_eth_type = Signal(intbv(0)[16:]) - input_udp_ip_version = Signal(intbv(0)[4:]) - input_udp_ip_ihl = Signal(intbv(0)[4:]) - input_udp_ip_dscp = Signal(intbv(0)[6:]) - input_udp_ip_ecn = Signal(intbv(0)[2:]) - input_udp_ip_identification = Signal(intbv(0)[16:]) - input_udp_ip_flags = Signal(intbv(0)[3:]) - input_udp_ip_fragment_offset = Signal(intbv(0)[13:]) - input_udp_ip_ttl = Signal(intbv(0)[8:]) - input_udp_ip_header_checksum = Signal(intbv(0)[16:]) - input_udp_ip_source_ip = Signal(intbv(0)[32:]) - input_udp_ip_dest_ip = Signal(intbv(0)[32:]) - input_udp_source_port = Signal(intbv(0)[16:]) - input_udp_dest_port = Signal(intbv(0)[16:]) - input_udp_length = Signal(intbv(0)[16:]) - input_udp_checksum = Signal(intbv(0)[16:]) - input_udp_payload_tdata = Signal(intbv(0)[64:]) - input_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_udp_payload_tvalid = Signal(bool(0)) - input_udp_payload_tlast = Signal(bool(0)) - input_udp_payload_tuser = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) - output_udp_payload_tready = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_ip_eth_dest_mac = Signal(intbv(0)[48:]) + s_ip_eth_src_mac = Signal(intbv(0)[48:]) + s_ip_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + s_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + s_udp_hdr_valid = Signal(bool(0)) + s_udp_eth_dest_mac = Signal(intbv(0)[48:]) + s_udp_eth_src_mac = Signal(intbv(0)[48:]) + s_udp_eth_type = Signal(intbv(0)[16:]) + s_udp_ip_version = Signal(intbv(0)[4:]) + s_udp_ip_ihl = Signal(intbv(0)[4:]) + s_udp_ip_dscp = Signal(intbv(0)[6:]) + s_udp_ip_ecn = Signal(intbv(0)[2:]) + s_udp_ip_identification = Signal(intbv(0)[16:]) + s_udp_ip_flags = Signal(intbv(0)[3:]) + s_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + s_udp_ip_ttl = Signal(intbv(0)[8:]) + s_udp_ip_header_checksum = Signal(intbv(0)[16:]) + s_udp_ip_source_ip = Signal(intbv(0)[32:]) + s_udp_ip_dest_ip = Signal(intbv(0)[32:]) + s_udp_source_port = Signal(intbv(0)[16:]) + s_udp_dest_port = Signal(intbv(0)[16:]) + s_udp_length = Signal(intbv(0)[16:]) + s_udp_checksum = Signal(intbv(0)[16:]) + s_udp_payload_axis_tdata = Signal(intbv(0)[64:]) + s_udp_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_udp_payload_axis_tvalid = Signal(bool(0)) + s_udp_payload_axis_tlast = Signal(bool(0)) + s_udp_payload_axis_tuser = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) # Outputs - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - input_udp_hdr_ready = Signal(bool(0)) - input_udp_payload_tready = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_ip_eth_dest_mac = Signal(intbv(0)[48:]) - output_ip_eth_src_mac = Signal(intbv(0)[48:]) - output_ip_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[64:]) - output_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) - output_udp_hdr_valid = Signal(bool(0)) - output_udp_eth_dest_mac = Signal(intbv(0)[48:]) - output_udp_eth_src_mac = Signal(intbv(0)[48:]) - output_udp_eth_type = Signal(intbv(0)[16:]) - output_udp_ip_version = Signal(intbv(0)[4:]) - output_udp_ip_ihl = Signal(intbv(0)[4:]) - output_udp_ip_dscp = Signal(intbv(0)[6:]) - output_udp_ip_ecn = Signal(intbv(0)[2:]) - output_udp_ip_length = Signal(intbv(0)[16:]) - output_udp_ip_identification = Signal(intbv(0)[16:]) - output_udp_ip_flags = Signal(intbv(0)[3:]) - output_udp_ip_fragment_offset = Signal(intbv(0)[13:]) - output_udp_ip_ttl = Signal(intbv(0)[8:]) - output_udp_ip_protocol = Signal(intbv(0)[8:]) - output_udp_ip_header_checksum = Signal(intbv(0)[16:]) - output_udp_ip_source_ip = Signal(intbv(0)[32:]) - output_udp_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[64:]) - output_udp_payload_tkeep = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(bool(0)) + s_udp_payload_axis_tready = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_ip_eth_dest_mac = Signal(intbv(0)[48:]) + m_ip_eth_src_mac = Signal(intbv(0)[48:]) + m_ip_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + m_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) + m_udp_hdr_valid = Signal(bool(0)) + m_udp_eth_dest_mac = Signal(intbv(0)[48:]) + m_udp_eth_src_mac = Signal(intbv(0)[48:]) + m_udp_eth_type = Signal(intbv(0)[16:]) + m_udp_ip_version = Signal(intbv(0)[4:]) + m_udp_ip_ihl = Signal(intbv(0)[4:]) + m_udp_ip_dscp = Signal(intbv(0)[6:]) + m_udp_ip_ecn = Signal(intbv(0)[2:]) + m_udp_ip_length = Signal(intbv(0)[16:]) + m_udp_ip_identification = Signal(intbv(0)[16:]) + m_udp_ip_flags = Signal(intbv(0)[3:]) + m_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + m_udp_ip_ttl = Signal(intbv(0)[8:]) + m_udp_ip_protocol = Signal(intbv(0)[8:]) + m_udp_ip_header_checksum = Signal(intbv(0)[16:]) + m_udp_ip_source_ip = Signal(intbv(0)[32:]) + m_udp_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[64:]) + m_udp_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tuser = Signal(bool(0)) rx_busy = Signal(bool(0)) tx_busy = Signal(bool(0)) rx_error_header_early_termination = Signal(bool(0)) @@ -174,30 +174,30 @@ def bench(): ip_source_logic = ip_source.create_logic( clk, rst, - ip_hdr_ready=input_ip_hdr_ready, - ip_hdr_valid=input_ip_hdr_valid, - eth_dest_mac=input_ip_eth_dest_mac, - eth_src_mac=input_ip_eth_src_mac, - eth_type=input_ip_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tkeep=input_ip_payload_tkeep, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_ready=s_ip_hdr_ready, + ip_hdr_valid=s_ip_hdr_valid, + eth_dest_mac=s_ip_eth_dest_mac, + eth_src_mac=s_ip_eth_src_mac, + eth_type=s_ip_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tkeep=s_ip_payload_axis_tkeep, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=ip_source_pause, name='ip_source' ) @@ -207,30 +207,30 @@ def bench(): ip_sink_logic = ip_sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_ip_eth_dest_mac, - eth_src_mac=output_ip_eth_src_mac, - eth_type=output_ip_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tkeep=output_ip_payload_tkeep, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_ip_eth_dest_mac, + eth_src_mac=m_ip_eth_src_mac, + eth_type=m_ip_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tkeep=m_ip_payload_axis_tkeep, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=ip_sink_pause, name='ip_sink' ) @@ -240,32 +240,32 @@ def bench(): udp_source_logic = udp_source.create_logic( clk, rst, - udp_hdr_ready=input_udp_hdr_ready, - udp_hdr_valid=input_udp_hdr_valid, - eth_dest_mac=input_udp_eth_dest_mac, - eth_src_mac=input_udp_eth_src_mac, - eth_type=input_udp_eth_type, - ip_version=input_udp_ip_version, - ip_ihl=input_udp_ip_ihl, - ip_dscp=input_udp_ip_dscp, - ip_ecn=input_udp_ip_ecn, - ip_identification=input_udp_ip_identification, - ip_flags=input_udp_ip_flags, - ip_fragment_offset=input_udp_ip_fragment_offset, - ip_ttl=input_udp_ip_ttl, - ip_header_checksum=input_udp_ip_header_checksum, - ip_source_ip=input_udp_ip_source_ip, - ip_dest_ip=input_udp_ip_dest_ip, - udp_source_port=input_udp_source_port, - udp_dest_port=input_udp_dest_port, - udp_length=input_udp_length, - udp_checksum=input_udp_checksum, - udp_payload_tdata=input_udp_payload_tdata, - udp_payload_tkeep=input_udp_payload_tkeep, - udp_payload_tvalid=input_udp_payload_tvalid, - udp_payload_tready=input_udp_payload_tready, - udp_payload_tlast=input_udp_payload_tlast, - udp_payload_tuser=input_udp_payload_tuser, + udp_hdr_ready=s_udp_hdr_ready, + udp_hdr_valid=s_udp_hdr_valid, + eth_dest_mac=s_udp_eth_dest_mac, + eth_src_mac=s_udp_eth_src_mac, + eth_type=s_udp_eth_type, + ip_version=s_udp_ip_version, + ip_ihl=s_udp_ip_ihl, + ip_dscp=s_udp_ip_dscp, + ip_ecn=s_udp_ip_ecn, + ip_identification=s_udp_ip_identification, + ip_flags=s_udp_ip_flags, + ip_fragment_offset=s_udp_ip_fragment_offset, + ip_ttl=s_udp_ip_ttl, + ip_header_checksum=s_udp_ip_header_checksum, + ip_source_ip=s_udp_ip_source_ip, + ip_dest_ip=s_udp_ip_dest_ip, + udp_source_port=s_udp_source_port, + udp_dest_port=s_udp_dest_port, + udp_length=s_udp_length, + udp_checksum=s_udp_checksum, + udp_payload_tdata=s_udp_payload_axis_tdata, + udp_payload_tkeep=s_udp_payload_axis_tkeep, + udp_payload_tvalid=s_udp_payload_axis_tvalid, + udp_payload_tready=s_udp_payload_axis_tready, + udp_payload_tlast=s_udp_payload_axis_tlast, + udp_payload_tuser=s_udp_payload_axis_tuser, pause=udp_source_pause, name='udp_source' ) @@ -275,34 +275,34 @@ def bench(): udp_sink_logic = udp_sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_udp_eth_dest_mac, - eth_src_mac=output_udp_eth_src_mac, - eth_type=output_udp_eth_type, - ip_version=output_udp_ip_version, - ip_ihl=output_udp_ip_ihl, - ip_dscp=output_udp_ip_dscp, - ip_ecn=output_udp_ip_ecn, - ip_length=output_udp_ip_length, - ip_identification=output_udp_ip_identification, - ip_flags=output_udp_ip_flags, - ip_fragment_offset=output_udp_ip_fragment_offset, - ip_ttl=output_udp_ip_ttl, - ip_protocol=output_udp_ip_protocol, - ip_header_checksum=output_udp_ip_header_checksum, - ip_source_ip=output_udp_ip_source_ip, - ip_dest_ip=output_udp_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tkeep=output_udp_payload_tkeep, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_udp_eth_dest_mac, + eth_src_mac=m_udp_eth_src_mac, + eth_type=m_udp_eth_type, + ip_version=m_udp_ip_version, + ip_ihl=m_udp_ip_ihl, + ip_dscp=m_udp_ip_dscp, + ip_ecn=m_udp_ip_ecn, + ip_length=m_udp_ip_length, + ip_identification=m_udp_ip_identification, + ip_flags=m_udp_ip_flags, + ip_fragment_offset=m_udp_ip_fragment_offset, + ip_ttl=m_udp_ip_ttl, + ip_protocol=m_udp_ip_protocol, + ip_header_checksum=m_udp_ip_header_checksum, + ip_source_ip=m_udp_ip_source_ip, + ip_dest_ip=m_udp_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tkeep=m_udp_payload_axis_tkeep, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=udp_sink_pause, name='udp_sink' ) @@ -317,111 +317,111 @@ def bench(): rst=rst, current_test=current_test, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_ip_eth_dest_mac=input_ip_eth_dest_mac, - input_ip_eth_src_mac=input_ip_eth_src_mac, - input_ip_eth_type=input_ip_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tkeep=input_ip_payload_tkeep, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_ip_eth_dest_mac=s_ip_eth_dest_mac, + s_ip_eth_src_mac=s_ip_eth_src_mac, + s_ip_eth_type=s_ip_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_ip_eth_dest_mac=output_ip_eth_dest_mac, - output_ip_eth_src_mac=output_ip_eth_src_mac, - output_ip_eth_type=output_ip_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tkeep=output_ip_payload_tkeep, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_ip_eth_dest_mac=m_ip_eth_dest_mac, + m_ip_eth_src_mac=m_ip_eth_src_mac, + m_ip_eth_type=m_ip_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, - input_udp_hdr_valid=input_udp_hdr_valid, - input_udp_hdr_ready=input_udp_hdr_ready, - input_udp_eth_dest_mac=input_udp_eth_dest_mac, - input_udp_eth_src_mac=input_udp_eth_src_mac, - input_udp_eth_type=input_udp_eth_type, - input_udp_ip_version=input_udp_ip_version, - input_udp_ip_ihl=input_udp_ip_ihl, - input_udp_ip_dscp=input_udp_ip_dscp, - input_udp_ip_ecn=input_udp_ip_ecn, - input_udp_ip_identification=input_udp_ip_identification, - input_udp_ip_flags=input_udp_ip_flags, - input_udp_ip_fragment_offset=input_udp_ip_fragment_offset, - input_udp_ip_ttl=input_udp_ip_ttl, - input_udp_ip_header_checksum=input_udp_ip_header_checksum, - input_udp_ip_source_ip=input_udp_ip_source_ip, - input_udp_ip_dest_ip=input_udp_ip_dest_ip, - input_udp_source_port=input_udp_source_port, - input_udp_dest_port=input_udp_dest_port, - input_udp_length=input_udp_length, - input_udp_checksum=input_udp_checksum, - input_udp_payload_tdata=input_udp_payload_tdata, - input_udp_payload_tkeep=input_udp_payload_tkeep, - input_udp_payload_tvalid=input_udp_payload_tvalid, - input_udp_payload_tready=input_udp_payload_tready, - input_udp_payload_tlast=input_udp_payload_tlast, - input_udp_payload_tuser=input_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_udp_eth_dest_mac=s_udp_eth_dest_mac, + s_udp_eth_src_mac=s_udp_eth_src_mac, + s_udp_eth_type=s_udp_eth_type, + s_udp_ip_version=s_udp_ip_version, + s_udp_ip_ihl=s_udp_ip_ihl, + s_udp_ip_dscp=s_udp_ip_dscp, + s_udp_ip_ecn=s_udp_ip_ecn, + s_udp_ip_identification=s_udp_ip_identification, + s_udp_ip_flags=s_udp_ip_flags, + s_udp_ip_fragment_offset=s_udp_ip_fragment_offset, + s_udp_ip_ttl=s_udp_ip_ttl, + s_udp_ip_header_checksum=s_udp_ip_header_checksum, + s_udp_ip_source_ip=s_udp_ip_source_ip, + s_udp_ip_dest_ip=s_udp_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep=s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_udp_eth_dest_mac=output_udp_eth_dest_mac, - output_udp_eth_src_mac=output_udp_eth_src_mac, - output_udp_eth_type=output_udp_eth_type, - output_udp_ip_version=output_udp_ip_version, - output_udp_ip_ihl=output_udp_ip_ihl, - output_udp_ip_dscp=output_udp_ip_dscp, - output_udp_ip_ecn=output_udp_ip_ecn, - output_udp_ip_length=output_udp_ip_length, - output_udp_ip_identification=output_udp_ip_identification, - output_udp_ip_flags=output_udp_ip_flags, - output_udp_ip_fragment_offset=output_udp_ip_fragment_offset, - output_udp_ip_ttl=output_udp_ip_ttl, - output_udp_ip_protocol=output_udp_ip_protocol, - output_udp_ip_header_checksum=output_udp_ip_header_checksum, - output_udp_ip_source_ip=output_udp_ip_source_ip, - output_udp_ip_dest_ip=output_udp_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tkeep=output_udp_payload_tkeep, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_udp_eth_dest_mac=m_udp_eth_dest_mac, + m_udp_eth_src_mac=m_udp_eth_src_mac, + m_udp_eth_type=m_udp_eth_type, + m_udp_ip_version=m_udp_ip_version, + m_udp_ip_ihl=m_udp_ip_ihl, + m_udp_ip_dscp=m_udp_ip_dscp, + m_udp_ip_ecn=m_udp_ip_ecn, + m_udp_ip_length=m_udp_ip_length, + m_udp_ip_identification=m_udp_ip_identification, + m_udp_ip_flags=m_udp_ip_flags, + m_udp_ip_fragment_offset=m_udp_ip_fragment_offset, + m_udp_ip_ttl=m_udp_ip_ttl, + m_udp_ip_protocol=m_udp_ip_protocol, + m_udp_ip_header_checksum=m_udp_ip_header_checksum, + m_udp_ip_source_ip=m_udp_ip_source_ip, + m_udp_ip_dest_ip=m_udp_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep=m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, rx_busy=rx_busy, tx_busy=tx_busy, diff --git a/tb/test_udp_64.v b/tb/test_udp_64.v index ce9904367..96623cde2 100644 --- a/tb/test_udp_64.v +++ b/tb/test_udp_64.v @@ -41,110 +41,110 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_ip_hdr_valid = 0; -reg [47:0] input_ip_eth_dest_mac = 0; -reg [47:0] input_ip_eth_src_mac = 0; -reg [15:0] input_ip_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [63:0] input_ip_payload_tdata = 0; -reg [7:0] input_ip_payload_tkeep = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg input_udp_hdr_valid = 0; -reg [47:0] input_udp_eth_dest_mac = 0; -reg [47:0] input_udp_eth_src_mac = 0; -reg [15:0] input_udp_eth_type = 0; -reg [3:0] input_udp_ip_version = 0; -reg [3:0] input_udp_ip_ihl = 0; -reg [5:0] input_udp_ip_dscp = 0; -reg [1:0] input_udp_ip_ecn = 0; -reg [15:0] input_udp_ip_identification = 0; -reg [2:0] input_udp_ip_flags = 0; -reg [12:0] input_udp_ip_fragment_offset = 0; -reg [7:0] input_udp_ip_ttl = 0; -reg [15:0] input_udp_ip_header_checksum = 0; -reg [31:0] input_udp_ip_source_ip = 0; -reg [31:0] input_udp_ip_dest_ip = 0; -reg [15:0] input_udp_source_port = 0; -reg [15:0] input_udp_dest_port = 0; -reg [15:0] input_udp_length = 0; -reg [15:0] input_udp_checksum = 0; -reg [63:0] input_udp_payload_tdata = 0; -reg [7:0] input_udp_payload_tkeep = 0; -reg input_udp_payload_tvalid = 0; -reg input_udp_payload_tlast = 0; -reg input_udp_payload_tuser = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [47:0] s_ip_eth_dest_mac = 0; +reg [47:0] s_ip_eth_src_mac = 0; +reg [15:0] s_ip_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [63:0] s_ip_payload_axis_tdata = 0; +reg [7:0] s_ip_payload_axis_tkeep = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg s_udp_hdr_valid = 0; +reg [47:0] s_udp_eth_dest_mac = 0; +reg [47:0] s_udp_eth_src_mac = 0; +reg [15:0] s_udp_eth_type = 0; +reg [3:0] s_udp_ip_version = 0; +reg [3:0] s_udp_ip_ihl = 0; +reg [5:0] s_udp_ip_dscp = 0; +reg [1:0] s_udp_ip_ecn = 0; +reg [15:0] s_udp_ip_identification = 0; +reg [2:0] s_udp_ip_flags = 0; +reg [12:0] s_udp_ip_fragment_offset = 0; +reg [7:0] s_udp_ip_ttl = 0; +reg [15:0] s_udp_ip_header_checksum = 0; +reg [31:0] s_udp_ip_source_ip = 0; +reg [31:0] s_udp_ip_dest_ip = 0; +reg [15:0] s_udp_source_port = 0; +reg [15:0] s_udp_dest_port = 0; +reg [15:0] s_udp_length = 0; +reg [15:0] s_udp_checksum = 0; +reg [63:0] s_udp_payload_axis_tdata = 0; +reg [7:0] s_udp_payload_axis_tkeep = 0; +reg s_udp_payload_axis_tvalid = 0; +reg s_udp_payload_axis_tlast = 0; +reg s_udp_payload_axis_tuser = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; // Outputs -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire input_udp_hdr_ready; -wire input_udp_payload_tready; -wire output_ip_hdr_valid; -wire [47:0] output_ip_eth_dest_mac; -wire [47:0] output_ip_eth_src_mac; -wire [15:0] output_ip_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [63:0] output_ip_payload_tdata; -wire [7:0] output_ip_payload_tkeep; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; -wire output_udp_hdr_valid; -wire [47:0] output_udp_eth_dest_mac; -wire [47:0] output_udp_eth_src_mac; -wire [15:0] output_udp_eth_type; -wire [3:0] output_udp_ip_version; -wire [3:0] output_udp_ip_ihl; -wire [5:0] output_udp_ip_dscp; -wire [1:0] output_udp_ip_ecn; -wire [15:0] output_udp_ip_length; -wire [15:0] output_udp_ip_identification; -wire [2:0] output_udp_ip_flags; -wire [12:0] output_udp_ip_fragment_offset; -wire [7:0] output_udp_ip_ttl; -wire [7:0] output_udp_ip_protocol; -wire [15:0] output_udp_ip_header_checksum; -wire [31:0] output_udp_ip_source_ip; -wire [31:0] output_udp_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [63:0] output_udp_payload_tdata; -wire [7:0] output_udp_payload_tkeep; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire s_udp_hdr_ready; +wire s_udp_payload_axis_tready; +wire m_ip_hdr_valid; +wire [47:0] m_ip_eth_dest_mac; +wire [47:0] m_ip_eth_src_mac; +wire [15:0] m_ip_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [63:0] m_ip_payload_axis_tdata; +wire [7:0] m_ip_payload_axis_tkeep; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; +wire m_udp_hdr_valid; +wire [47:0] m_udp_eth_dest_mac; +wire [47:0] m_udp_eth_src_mac; +wire [15:0] m_udp_eth_type; +wire [3:0] m_udp_ip_version; +wire [3:0] m_udp_ip_ihl; +wire [5:0] m_udp_ip_dscp; +wire [1:0] m_udp_ip_ecn; +wire [15:0] m_udp_ip_length; +wire [15:0] m_udp_ip_identification; +wire [2:0] m_udp_ip_flags; +wire [12:0] m_udp_ip_fragment_offset; +wire [7:0] m_udp_ip_ttl; +wire [7:0] m_udp_ip_protocol; +wire [15:0] m_udp_ip_header_checksum; +wire [31:0] m_udp_ip_source_ip; +wire [31:0] m_udp_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [63:0] m_udp_payload_axis_tdata; +wire [7:0] m_udp_payload_axis_tkeep; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire m_udp_payload_axis_tuser; wire rx_busy; wire tx_busy; wire rx_error_header_early_termination; @@ -157,110 +157,110 @@ initial begin clk, rst, current_test, - input_ip_hdr_valid, - input_ip_eth_dest_mac, - input_ip_eth_src_mac, - input_ip_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tkeep, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - input_udp_hdr_valid, - input_udp_eth_dest_mac, - input_udp_eth_src_mac, - input_udp_eth_type, - input_udp_ip_version, - input_udp_ip_ihl, - input_udp_ip_dscp, - input_udp_ip_ecn, - input_udp_ip_identification, - input_udp_ip_flags, - input_udp_ip_fragment_offset, - input_udp_ip_ttl, - input_udp_ip_header_checksum, - input_udp_ip_source_ip, - input_udp_ip_dest_ip, - input_udp_source_port, - input_udp_dest_port, - input_udp_length, - input_udp_checksum, - input_udp_payload_tdata, - input_udp_payload_tkeep, - input_udp_payload_tvalid, - input_udp_payload_tlast, - input_udp_payload_tuser, - output_ip_hdr_ready, - output_ip_payload_tready, - output_udp_hdr_ready, - output_udp_payload_tready + s_ip_hdr_valid, + s_ip_eth_dest_mac, + s_ip_eth_src_mac, + s_ip_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + s_udp_hdr_valid, + s_udp_eth_dest_mac, + s_udp_eth_src_mac, + s_udp_eth_type, + s_udp_ip_version, + s_udp_ip_ihl, + s_udp_ip_dscp, + s_udp_ip_ecn, + s_udp_ip_identification, + s_udp_ip_flags, + s_udp_ip_fragment_offset, + s_udp_ip_ttl, + s_udp_ip_header_checksum, + s_udp_ip_source_ip, + s_udp_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready, + m_udp_hdr_ready, + m_udp_payload_axis_tready ); $to_myhdl( - input_ip_hdr_ready, - input_ip_payload_tready, - input_udp_hdr_ready, - input_udp_payload_tready, - output_ip_hdr_valid, - output_ip_eth_dest_mac, - output_ip_eth_src_mac, - output_ip_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tkeep, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, - output_udp_hdr_valid, - output_udp_eth_dest_mac, - output_udp_eth_src_mac, - output_udp_eth_type, - output_udp_ip_version, - output_udp_ip_ihl, - output_udp_ip_dscp, - output_udp_ip_ecn, - output_udp_ip_length, - output_udp_ip_identification, - output_udp_ip_flags, - output_udp_ip_fragment_offset, - output_udp_ip_ttl, - output_udp_ip_protocol, - output_udp_ip_header_checksum, - output_udp_ip_source_ip, - output_udp_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tkeep, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_ip_hdr_valid, + m_ip_eth_dest_mac, + m_ip_eth_src_mac, + m_ip_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, + m_udp_hdr_valid, + m_udp_eth_dest_mac, + m_udp_eth_src_mac, + m_udp_eth_type, + m_udp_ip_version, + m_udp_ip_ihl, + m_udp_ip_dscp, + m_udp_ip_ecn, + m_udp_ip_length, + m_udp_ip_identification, + m_udp_ip_flags, + m_udp_ip_fragment_offset, + m_udp_ip_ttl, + m_udp_ip_protocol, + m_udp_ip_header_checksum, + m_udp_ip_source_ip, + m_udp_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser, rx_busy, tx_busy, rx_error_header_early_termination, @@ -282,111 +282,111 @@ UUT ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_ip_eth_dest_mac(input_ip_eth_dest_mac), - .input_ip_eth_src_mac(input_ip_eth_src_mac), - .input_ip_eth_type(input_ip_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tkeep(input_ip_payload_tkeep), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_ip_eth_dest_mac(s_ip_eth_dest_mac), + .s_ip_eth_src_mac(s_ip_eth_src_mac), + .s_ip_eth_type(s_ip_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_ip_eth_dest_mac(output_ip_eth_dest_mac), - .output_ip_eth_src_mac(output_ip_eth_src_mac), - .output_ip_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_ip_eth_dest_mac(m_ip_eth_dest_mac), + .m_ip_eth_src_mac(m_ip_eth_src_mac), + .m_ip_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_udp_eth_dest_mac(input_udp_eth_dest_mac), - .input_udp_eth_src_mac(input_udp_eth_src_mac), - .input_udp_eth_type(input_udp_eth_type), - .input_udp_ip_version(input_udp_ip_version), - .input_udp_ip_ihl(input_udp_ip_ihl), - .input_udp_ip_dscp(input_udp_ip_dscp), - .input_udp_ip_ecn(input_udp_ip_ecn), - .input_udp_ip_identification(input_udp_ip_identification), - .input_udp_ip_flags(input_udp_ip_flags), - .input_udp_ip_fragment_offset(input_udp_ip_fragment_offset), - .input_udp_ip_ttl(input_udp_ip_ttl), - .input_udp_ip_header_checksum(input_udp_ip_header_checksum), - .input_udp_ip_source_ip(input_udp_ip_source_ip), - .input_udp_ip_dest_ip(input_udp_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), - .input_udp_checksum(input_udp_checksum), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tkeep(input_udp_payload_tkeep), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_udp_eth_dest_mac(s_udp_eth_dest_mac), + .s_udp_eth_src_mac(s_udp_eth_src_mac), + .s_udp_eth_type(s_udp_eth_type), + .s_udp_ip_version(s_udp_ip_version), + .s_udp_ip_ihl(s_udp_ip_ihl), + .s_udp_ip_dscp(s_udp_ip_dscp), + .s_udp_ip_ecn(s_udp_ip_ecn), + .s_udp_ip_identification(s_udp_ip_identification), + .s_udp_ip_flags(s_udp_ip_flags), + .s_udp_ip_fragment_offset(s_udp_ip_fragment_offset), + .s_udp_ip_ttl(s_udp_ip_ttl), + .s_udp_ip_header_checksum(s_udp_ip_header_checksum), + .s_udp_ip_source_ip(s_udp_ip_source_ip), + .s_udp_ip_dest_ip(s_udp_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_udp_eth_dest_mac(output_udp_eth_dest_mac), - .output_udp_eth_src_mac(output_udp_eth_src_mac), - .output_udp_eth_type(output_udp_eth_type), - .output_udp_ip_version(output_udp_ip_version), - .output_udp_ip_ihl(output_udp_ip_ihl), - .output_udp_ip_dscp(output_udp_ip_dscp), - .output_udp_ip_ecn(output_udp_ip_ecn), - .output_udp_ip_length(output_udp_ip_length), - .output_udp_ip_identification(output_udp_ip_identification), - .output_udp_ip_flags(output_udp_ip_flags), - .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), - .output_udp_ip_ttl(output_udp_ip_ttl), - .output_udp_ip_protocol(output_udp_ip_protocol), - .output_udp_ip_header_checksum(output_udp_ip_header_checksum), - .output_udp_ip_source_ip(output_udp_ip_source_ip), - .output_udp_ip_dest_ip(output_udp_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tkeep(output_udp_payload_tkeep), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_udp_eth_dest_mac(m_udp_eth_dest_mac), + .m_udp_eth_src_mac(m_udp_eth_src_mac), + .m_udp_eth_type(m_udp_eth_type), + .m_udp_ip_version(m_udp_ip_version), + .m_udp_ip_ihl(m_udp_ip_ihl), + .m_udp_ip_dscp(m_udp_ip_dscp), + .m_udp_ip_ecn(m_udp_ip_ecn), + .m_udp_ip_length(m_udp_ip_length), + .m_udp_ip_identification(m_udp_ip_identification), + .m_udp_ip_flags(m_udp_ip_flags), + .m_udp_ip_fragment_offset(m_udp_ip_fragment_offset), + .m_udp_ip_ttl(m_udp_ip_ttl), + .m_udp_ip_protocol(m_udp_ip_protocol), + .m_udp_ip_header_checksum(m_udp_ip_header_checksum), + .m_udp_ip_source_ip(m_udp_ip_source_ip), + .m_udp_ip_dest_ip(m_udp_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Status signals .rx_busy(rx_busy), .tx_busy(tx_busy), diff --git a/tb/test_udp_checksum_gen.py b/tb/test_udp_checksum_gen.py index b1564fda2..25eb3ec14 100755 --- a/tb/test_udp_checksum_gen.py +++ b/tb/test_udp_checksum_gen.py @@ -55,60 +55,60 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_udp_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_udp_source_port = Signal(intbv(0)[16:]) - input_udp_dest_port = Signal(intbv(0)[16:]) - input_udp_payload_tdata = Signal(intbv(0)[8:]) - input_udp_payload_tvalid = Signal(bool(0)) - input_udp_payload_tlast = Signal(bool(0)) - input_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_udp_source_port = Signal(intbv(0)[16:]) + s_udp_dest_port = Signal(intbv(0)[16:]) + s_udp_payload_axis_tdata = Signal(intbv(0)[8:]) + s_udp_payload_axis_tvalid = Signal(bool(0)) + s_udp_payload_axis_tlast = Signal(bool(0)) + s_udp_payload_axis_tuser = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) - output_udp_payload_tready = Signal(bool(0)) + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) # Outputs - input_udp_hdr_ready = Signal(bool(0)) - input_udp_payload_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(bool(0)) + s_udp_payload_axis_tready = Signal(bool(0)) - output_udp_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0x11)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + m_udp_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0x11)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[8:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) @@ -121,29 +121,29 @@ def bench(): source_logic = source.create_logic( clk, rst, - udp_hdr_ready=input_udp_hdr_ready, - udp_hdr_valid=input_udp_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - udp_source_port=input_udp_source_port, - udp_dest_port=input_udp_dest_port, - udp_payload_tdata=input_udp_payload_tdata, - udp_payload_tvalid=input_udp_payload_tvalid, - udp_payload_tready=input_udp_payload_tready, - udp_payload_tlast=input_udp_payload_tlast, - udp_payload_tuser=input_udp_payload_tuser, + udp_hdr_ready=s_udp_hdr_ready, + udp_hdr_valid=s_udp_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + udp_source_port=s_udp_source_port, + udp_dest_port=s_udp_dest_port, + udp_payload_tdata=s_udp_payload_axis_tdata, + udp_payload_tvalid=s_udp_payload_axis_tvalid, + udp_payload_tready=s_udp_payload_axis_tready, + udp_payload_tlast=s_udp_payload_axis_tlast, + udp_payload_tuser=s_udp_payload_axis_tuser, pause=source_pause, name='source' ) @@ -153,33 +153,33 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -194,57 +194,57 @@ def bench(): rst=rst, current_test=current_test, - input_udp_hdr_valid=input_udp_hdr_valid, - input_udp_hdr_ready=input_udp_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_udp_source_port=input_udp_source_port, - input_udp_dest_port=input_udp_dest_port, - input_udp_payload_tdata=input_udp_payload_tdata, - input_udp_payload_tvalid=input_udp_payload_tvalid, - input_udp_payload_tready=input_udp_payload_tready, - input_udp_payload_tlast=input_udp_payload_tlast, - input_udp_payload_tuser=input_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, busy=busy ) @@ -257,7 +257,7 @@ def bench(): i = 4 while i > 0: i = max(0, i-1) - if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + if s_udp_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_udp_hdr_valid or not source.empty(): i = 4 yield clk.posedge @@ -265,7 +265,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + if s_udp_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_udp_hdr_valid or not source.empty(): i = 2 source_pause.next = True yield clk.posedge @@ -278,7 +278,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + if s_udp_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_udp_hdr_valid or not source.empty(): i = 2 sink_pause.next = True yield clk.posedge diff --git a/tb/test_udp_checksum_gen.v b/tb/test_udp_checksum_gen.v index 94f2e2543..82410420c 100644 --- a/tb/test_udp_checksum_gen.v +++ b/tb/test_udp_checksum_gen.v @@ -40,58 +40,58 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_udp_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [15:0] input_udp_source_port = 0; -reg [15:0] input_udp_dest_port = 0; -reg [7:0] input_udp_payload_tdata = 0; -reg input_udp_payload_tvalid = 0; -reg input_udp_payload_tlast = 0; -reg input_udp_payload_tuser = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg s_udp_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [15:0] s_udp_source_port = 0; +reg [15:0] s_udp_dest_port = 0; +reg [7:0] s_udp_payload_axis_tdata = 0; +reg s_udp_payload_axis_tvalid = 0; +reg s_udp_payload_axis_tlast = 0; +reg s_udp_payload_axis_tuser = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; // Outputs -wire input_udp_hdr_ready; -wire input_udp_payload_tready; -wire output_udp_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [7:0] output_udp_payload_tdata; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire s_udp_hdr_ready; +wire s_udp_payload_axis_tready; +wire m_udp_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [7:0] m_udp_payload_axis_tdata; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire m_udp_payload_axis_tuser; wire busy; initial begin @@ -100,58 +100,58 @@ initial begin clk, rst, current_test, - input_udp_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_udp_source_port, - input_udp_dest_port, - input_udp_payload_tdata, - input_udp_payload_tvalid, - input_udp_payload_tlast, - input_udp_payload_tuser, - output_udp_hdr_ready, - output_udp_payload_tready + s_udp_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser, + m_udp_hdr_ready, + m_udp_payload_axis_tready ); $to_myhdl( - input_udp_hdr_ready, - input_udp_payload_tready, - output_udp_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser, + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_udp_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser, busy ); @@ -167,56 +167,56 @@ udp_checksum_gen #( UUT ( .clk(clk), .rst(rst), - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), .busy(busy) ); diff --git a/tb/test_udp_checksum_gen_64.py b/tb/test_udp_checksum_gen_64.py index 8f4adb485..1202d29f6 100755 --- a/tb/test_udp_checksum_gen_64.py +++ b/tb/test_udp_checksum_gen_64.py @@ -55,62 +55,62 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_udp_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_udp_source_port = Signal(intbv(0)[16:]) - input_udp_dest_port = Signal(intbv(0)[16:]) - input_udp_payload_tdata = Signal(intbv(0)[64:]) - input_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_udp_payload_tvalid = Signal(bool(0)) - input_udp_payload_tlast = Signal(bool(0)) - input_udp_payload_tuser = Signal(bool(0)) + s_udp_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_udp_source_port = Signal(intbv(0)[16:]) + s_udp_dest_port = Signal(intbv(0)[16:]) + s_udp_payload_axis_tdata = Signal(intbv(0)[64:]) + s_udp_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_udp_payload_axis_tvalid = Signal(bool(0)) + s_udp_payload_axis_tlast = Signal(bool(0)) + s_udp_payload_axis_tuser = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) - output_udp_payload_tready = Signal(bool(0)) + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) # Outputs - input_udp_hdr_ready = Signal(bool(0)) - input_udp_payload_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(bool(0)) + s_udp_payload_axis_tready = Signal(bool(0)) - output_udp_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0x11)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[64:]) - output_udp_payload_tkeep = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + m_udp_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0x11)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[64:]) + m_udp_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) @@ -123,30 +123,30 @@ def bench(): source_logic = source.create_logic( clk, rst, - udp_hdr_ready=input_udp_hdr_ready, - udp_hdr_valid=input_udp_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - udp_source_port=input_udp_source_port, - udp_dest_port=input_udp_dest_port, - udp_payload_tdata=input_udp_payload_tdata, - udp_payload_tkeep=input_udp_payload_tkeep, - udp_payload_tvalid=input_udp_payload_tvalid, - udp_payload_tready=input_udp_payload_tready, - udp_payload_tlast=input_udp_payload_tlast, - udp_payload_tuser=input_udp_payload_tuser, + udp_hdr_ready=s_udp_hdr_ready, + udp_hdr_valid=s_udp_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + udp_source_port=s_udp_source_port, + udp_dest_port=s_udp_dest_port, + udp_payload_tdata=s_udp_payload_axis_tdata, + udp_payload_tkeep=s_udp_payload_axis_tkeep, + udp_payload_tvalid=s_udp_payload_axis_tvalid, + udp_payload_tready=s_udp_payload_axis_tready, + udp_payload_tlast=s_udp_payload_axis_tlast, + udp_payload_tuser=s_udp_payload_axis_tuser, pause=source_pause, name='source' ) @@ -156,34 +156,34 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tkeep=output_udp_payload_tkeep, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tkeep=m_udp_payload_axis_tkeep, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -198,59 +198,59 @@ def bench(): rst=rst, current_test=current_test, - input_udp_hdr_valid=input_udp_hdr_valid, - input_udp_hdr_ready=input_udp_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_udp_source_port=input_udp_source_port, - input_udp_dest_port=input_udp_dest_port, - input_udp_payload_tdata=input_udp_payload_tdata, - input_udp_payload_tkeep=input_udp_payload_tkeep, - input_udp_payload_tvalid=input_udp_payload_tvalid, - input_udp_payload_tready=input_udp_payload_tready, - input_udp_payload_tlast=input_udp_payload_tlast, - input_udp_payload_tuser=input_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep=s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tkeep=output_udp_payload_tkeep, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep=m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, busy=busy ) @@ -263,7 +263,7 @@ def bench(): i = 4 while i > 0: i = max(0, i-1) - if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + if s_udp_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_udp_hdr_valid or not source.empty(): i = 4 yield clk.posedge @@ -271,7 +271,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + if s_udp_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_udp_hdr_valid or not source.empty(): i = 2 source_pause.next = True yield clk.posedge @@ -284,7 +284,7 @@ def bench(): i = 2 while i > 0: i = max(0, i-1) - if input_udp_payload_tvalid or output_udp_payload_tvalid or input_udp_hdr_valid or not source.empty(): + if s_udp_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_udp_hdr_valid or not source.empty(): i = 2 sink_pause.next = True yield clk.posedge diff --git a/tb/test_udp_checksum_gen_64.v b/tb/test_udp_checksum_gen_64.v index 434ed3a09..79afa8512 100644 --- a/tb/test_udp_checksum_gen_64.v +++ b/tb/test_udp_checksum_gen_64.v @@ -40,60 +40,60 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_udp_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [15:0] input_udp_source_port = 0; -reg [15:0] input_udp_dest_port = 0; -reg [63:0] input_udp_payload_tdata = 0; -reg [7:0] input_udp_payload_tkeep = 0; -reg input_udp_payload_tvalid = 0; -reg input_udp_payload_tlast = 0; -reg input_udp_payload_tuser = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg s_udp_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [15:0] s_udp_source_port = 0; +reg [15:0] s_udp_dest_port = 0; +reg [63:0] s_udp_payload_axis_tdata = 0; +reg [7:0] s_udp_payload_axis_tkeep = 0; +reg s_udp_payload_axis_tvalid = 0; +reg s_udp_payload_axis_tlast = 0; +reg s_udp_payload_axis_tuser = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; // Outputs -wire input_udp_hdr_ready; -wire input_udp_payload_tready; -wire output_udp_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [63:0] output_udp_payload_tdata; -wire [7:0] output_udp_payload_tkeep; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire s_udp_hdr_ready; +wire s_udp_payload_axis_tready; +wire m_udp_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [63:0] m_udp_payload_axis_tdata; +wire [7:0] m_udp_payload_axis_tkeep; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire m_udp_payload_axis_tuser; wire busy; initial begin @@ -102,60 +102,60 @@ initial begin clk, rst, current_test, - input_udp_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_udp_source_port, - input_udp_dest_port, - input_udp_payload_tdata, - input_udp_payload_tkeep, - input_udp_payload_tvalid, - input_udp_payload_tlast, - input_udp_payload_tuser, - output_udp_hdr_ready, - output_udp_payload_tready + s_udp_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser, + m_udp_hdr_ready, + m_udp_payload_axis_tready ); $to_myhdl( - input_udp_hdr_ready, - input_udp_payload_tready, - output_udp_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tkeep, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser, + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_udp_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser, busy ); @@ -171,58 +171,58 @@ udp_checksum_gen_64 #( UUT ( .clk(clk), .rst(rst), - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tkeep(input_udp_payload_tkeep), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tkeep(output_udp_payload_tkeep), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), .busy(busy) ); diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py index 734bcf53e..7ebd4ba57 100755 --- a/tb/test_udp_complete.py +++ b/tb/test_udp_complete.py @@ -68,108 +68,108 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) - input_ip_hdr_valid = Signal(bool(0)) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - input_udp_hdr_valid = Signal(bool(0)) - input_udp_ip_dscp = Signal(intbv(0)[6:]) - input_udp_ip_ecn = Signal(intbv(0)[2:]) - input_udp_ip_ttl = Signal(intbv(0)[8:]) - input_udp_ip_source_ip = Signal(intbv(0)[32:]) - input_udp_ip_dest_ip = Signal(intbv(0)[32:]) - input_udp_source_port = Signal(intbv(0)[16:]) - input_udp_dest_port = Signal(intbv(0)[16:]) - input_udp_length = Signal(intbv(0)[16:]) - input_udp_checksum = Signal(intbv(0)[16:]) - input_udp_payload_tdata = Signal(intbv(0)[8:]) - input_udp_payload_tvalid = Signal(bool(0)) - input_udp_payload_tlast = Signal(bool(0)) - input_udp_payload_tuser = Signal(bool(0)) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) - output_udp_payload_tready = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + s_udp_hdr_valid = Signal(bool(0)) + s_udp_ip_dscp = Signal(intbv(0)[6:]) + s_udp_ip_ecn = Signal(intbv(0)[2:]) + s_udp_ip_ttl = Signal(intbv(0)[8:]) + s_udp_ip_source_ip = Signal(intbv(0)[32:]) + s_udp_ip_dest_ip = Signal(intbv(0)[32:]) + s_udp_source_port = Signal(intbv(0)[16:]) + s_udp_dest_port = Signal(intbv(0)[16:]) + s_udp_length = Signal(intbv(0)[16:]) + s_udp_checksum = Signal(intbv(0)[16:]) + s_udp_payload_axis_tdata = Signal(intbv(0)[8:]) + s_udp_payload_axis_tvalid = Signal(bool(0)) + s_udp_payload_axis_tlast = Signal(bool(0)) + s_udp_payload_axis_tuser = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - input_udp_hdr_ready = Signal(bool(0)) - input_udp_payload_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_ip_eth_dest_mac = Signal(intbv(0)[48:]) - output_ip_eth_src_mac = Signal(intbv(0)[48:]) - output_ip_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) - output_udp_hdr_valid = Signal(bool(0)) - output_udp_eth_dest_mac = Signal(intbv(0)[48:]) - output_udp_eth_src_mac = Signal(intbv(0)[48:]) - output_udp_eth_type = Signal(intbv(0)[16:]) - output_udp_ip_version = Signal(intbv(0)[4:]) - output_udp_ip_ihl = Signal(intbv(0)[4:]) - output_udp_ip_dscp = Signal(intbv(0)[6:]) - output_udp_ip_ecn = Signal(intbv(0)[2:]) - output_udp_ip_length = Signal(intbv(0)[16:]) - output_udp_ip_identification = Signal(intbv(0)[16:]) - output_udp_ip_flags = Signal(intbv(0)[3:]) - output_udp_ip_fragment_offset = Signal(intbv(0)[13:]) - output_udp_ip_ttl = Signal(intbv(0)[8:]) - output_udp_ip_protocol = Signal(intbv(0)[8:]) - output_udp_ip_header_checksum = Signal(intbv(0)[16:]) - output_udp_ip_source_ip = Signal(intbv(0)[32:]) - output_udp_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(bool(0)) + s_udp_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_ip_eth_dest_mac = Signal(intbv(0)[48:]) + m_ip_eth_src_mac = Signal(intbv(0)[48:]) + m_ip_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) + m_udp_hdr_valid = Signal(bool(0)) + m_udp_eth_dest_mac = Signal(intbv(0)[48:]) + m_udp_eth_src_mac = Signal(intbv(0)[48:]) + m_udp_eth_type = Signal(intbv(0)[16:]) + m_udp_ip_version = Signal(intbv(0)[4:]) + m_udp_ip_ihl = Signal(intbv(0)[4:]) + m_udp_ip_dscp = Signal(intbv(0)[6:]) + m_udp_ip_ecn = Signal(intbv(0)[2:]) + m_udp_ip_length = Signal(intbv(0)[16:]) + m_udp_ip_identification = Signal(intbv(0)[16:]) + m_udp_ip_flags = Signal(intbv(0)[3:]) + m_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + m_udp_ip_ttl = Signal(intbv(0)[8:]) + m_udp_ip_protocol = Signal(intbv(0)[8:]) + m_udp_ip_header_checksum = Signal(intbv(0)[16:]) + m_udp_ip_source_ip = Signal(intbv(0)[32:]) + m_udp_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[8:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tuser = Signal(bool(0)) ip_rx_busy = Signal(bool(0)) ip_tx_busy = Signal(bool(0)) udp_rx_busy = Signal(bool(0)) @@ -202,16 +202,16 @@ def bench(): eth_source_logic = eth_source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=eth_source_pause, name='eth_source' ) @@ -221,16 +221,16 @@ def bench(): eth_sink_logic = eth_sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=eth_sink_pause, name='eth_sink' ) @@ -240,20 +240,20 @@ def bench(): ip_source_logic = ip_source.create_logic( clk, rst, - ip_hdr_valid=input_ip_hdr_valid, - ip_hdr_ready=input_ip_hdr_ready, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_valid=s_ip_hdr_valid, + ip_hdr_ready=s_ip_hdr_ready, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=ip_source_pause, name='ip_source' ) @@ -263,29 +263,29 @@ def bench(): ip_sink_logic = ip_sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_ip_eth_dest_mac, - eth_src_mac=output_ip_eth_src_mac, - eth_type=output_ip_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_ip_eth_dest_mac, + eth_src_mac=m_ip_eth_src_mac, + eth_type=m_ip_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=ip_sink_pause, name='ip_sink' ) @@ -295,22 +295,22 @@ def bench(): udp_source_logic = udp_source.create_logic( clk, rst, - udp_hdr_ready=input_udp_hdr_ready, - udp_hdr_valid=input_udp_hdr_valid, - ip_dscp=input_udp_ip_dscp, - ip_ecn=input_udp_ip_ecn, - ip_ttl=input_udp_ip_ttl, - ip_source_ip=input_udp_ip_source_ip, - ip_dest_ip=input_udp_ip_dest_ip, - udp_source_port=input_udp_source_port, - udp_dest_port=input_udp_dest_port, - udp_length=input_udp_length, - udp_checksum=input_udp_checksum, - udp_payload_tdata=input_udp_payload_tdata, - udp_payload_tvalid=input_udp_payload_tvalid, - udp_payload_tready=input_udp_payload_tready, - udp_payload_tlast=input_udp_payload_tlast, - udp_payload_tuser=input_udp_payload_tuser, + udp_hdr_ready=s_udp_hdr_ready, + udp_hdr_valid=s_udp_hdr_valid, + ip_dscp=s_udp_ip_dscp, + ip_ecn=s_udp_ip_ecn, + ip_ttl=s_udp_ip_ttl, + ip_source_ip=s_udp_ip_source_ip, + ip_dest_ip=s_udp_ip_dest_ip, + udp_source_port=s_udp_source_port, + udp_dest_port=s_udp_dest_port, + udp_length=s_udp_length, + udp_checksum=s_udp_checksum, + udp_payload_tdata=s_udp_payload_axis_tdata, + udp_payload_tvalid=s_udp_payload_axis_tvalid, + udp_payload_tready=s_udp_payload_axis_tready, + udp_payload_tlast=s_udp_payload_axis_tlast, + udp_payload_tuser=s_udp_payload_axis_tuser, pause=udp_source_pause, name='udp_source' ) @@ -320,33 +320,33 @@ def bench(): udp_sink_logic = udp_sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_udp_eth_dest_mac, - eth_src_mac=output_udp_eth_src_mac, - eth_type=output_udp_eth_type, - ip_version=output_udp_ip_version, - ip_ihl=output_udp_ip_ihl, - ip_dscp=output_udp_ip_dscp, - ip_ecn=output_udp_ip_ecn, - ip_length=output_udp_ip_length, - ip_identification=output_udp_ip_identification, - ip_flags=output_udp_ip_flags, - ip_fragment_offset=output_udp_ip_fragment_offset, - ip_ttl=output_udp_ip_ttl, - ip_protocol=output_udp_ip_protocol, - ip_header_checksum=output_udp_ip_header_checksum, - ip_source_ip=output_udp_ip_source_ip, - ip_dest_ip=output_udp_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_udp_eth_dest_mac, + eth_src_mac=m_udp_eth_src_mac, + eth_type=m_udp_eth_type, + ip_version=m_udp_ip_version, + ip_ihl=m_udp_ip_ihl, + ip_dscp=m_udp_ip_dscp, + ip_ecn=m_udp_ip_ecn, + ip_length=m_udp_ip_length, + ip_identification=m_udp_ip_identification, + ip_flags=m_udp_ip_flags, + ip_fragment_offset=m_udp_ip_fragment_offset, + ip_ttl=m_udp_ip_ttl, + ip_protocol=m_udp_ip_protocol, + ip_header_checksum=m_udp_ip_header_checksum, + ip_source_ip=m_udp_ip_source_ip, + ip_dest_ip=m_udp_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=udp_sink_pause, name='udp_sink' ) @@ -361,111 +361,111 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_ip_eth_dest_mac=output_ip_eth_dest_mac, - output_ip_eth_src_mac=output_ip_eth_src_mac, - output_ip_eth_type=output_ip_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_ip_eth_dest_mac=m_ip_eth_dest_mac, + m_ip_eth_src_mac=m_ip_eth_src_mac, + m_ip_eth_type=m_ip_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, - input_udp_hdr_valid=input_udp_hdr_valid, - input_udp_hdr_ready=input_udp_hdr_ready, - input_udp_ip_dscp=input_udp_ip_dscp, - input_udp_ip_ecn=input_udp_ip_ecn, - input_udp_ip_ttl=input_udp_ip_ttl, - input_udp_ip_source_ip=input_udp_ip_source_ip, - input_udp_ip_dest_ip=input_udp_ip_dest_ip, - input_udp_source_port=input_udp_source_port, - input_udp_dest_port=input_udp_dest_port, - input_udp_length=input_udp_length, - input_udp_checksum=input_udp_checksum, - input_udp_payload_tdata=input_udp_payload_tdata, - input_udp_payload_tvalid=input_udp_payload_tvalid, - input_udp_payload_tready=input_udp_payload_tready, - input_udp_payload_tlast=input_udp_payload_tlast, - input_udp_payload_tuser=input_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_udp_ip_dscp=s_udp_ip_dscp, + s_udp_ip_ecn=s_udp_ip_ecn, + s_udp_ip_ttl=s_udp_ip_ttl, + s_udp_ip_source_ip=s_udp_ip_source_ip, + s_udp_ip_dest_ip=s_udp_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_udp_eth_dest_mac=output_udp_eth_dest_mac, - output_udp_eth_src_mac=output_udp_eth_src_mac, - output_udp_eth_type=output_udp_eth_type, - output_udp_ip_version=output_udp_ip_version, - output_udp_ip_ihl=output_udp_ip_ihl, - output_udp_ip_dscp=output_udp_ip_dscp, - output_udp_ip_ecn=output_udp_ip_ecn, - output_udp_ip_length=output_udp_ip_length, - output_udp_ip_identification=output_udp_ip_identification, - output_udp_ip_flags=output_udp_ip_flags, - output_udp_ip_fragment_offset=output_udp_ip_fragment_offset, - output_udp_ip_ttl=output_udp_ip_ttl, - output_udp_ip_protocol=output_udp_ip_protocol, - output_udp_ip_header_checksum=output_udp_ip_header_checksum, - output_udp_ip_source_ip=output_udp_ip_source_ip, - output_udp_ip_dest_ip=output_udp_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_udp_eth_dest_mac=m_udp_eth_dest_mac, + m_udp_eth_src_mac=m_udp_eth_src_mac, + m_udp_eth_type=m_udp_eth_type, + m_udp_ip_version=m_udp_ip_version, + m_udp_ip_ihl=m_udp_ip_ihl, + m_udp_ip_dscp=m_udp_ip_dscp, + m_udp_ip_ecn=m_udp_ip_ecn, + m_udp_ip_length=m_udp_ip_length, + m_udp_ip_identification=m_udp_ip_identification, + m_udp_ip_flags=m_udp_ip_flags, + m_udp_ip_fragment_offset=m_udp_ip_fragment_offset, + m_udp_ip_ttl=m_udp_ip_ttl, + m_udp_ip_protocol=m_udp_ip_protocol, + m_udp_ip_header_checksum=m_udp_ip_header_checksum, + m_udp_ip_source_ip=m_udp_ip_source_ip, + m_udp_ip_dest_ip=m_udp_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, ip_rx_busy=ip_rx_busy, ip_tx_busy=ip_tx_busy, @@ -527,9 +527,9 @@ def bench(): i = 20 while i > 0: i = max(0, i-1) - if (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or - output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or - input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): + if (s_eth_payload_axis_tvalid or s_ip_payload_axis_tvalid or s_udp_payload_axis_tvalid or + m_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or + s_eth_hdr_valid or s_ip_hdr_valid or s_udp_hdr_valid): i = 20 yield clk.posedge diff --git a/tb/test_udp_complete.v b/tb/test_udp_complete.v index 5707fed57..8f89a3f6d 100644 --- a/tb/test_udp_complete.v +++ b/tb/test_udp_complete.v @@ -45,49 +45,49 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [7:0] input_eth_payload_tdata = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [7:0] s_eth_payload_axis_tdata = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; reg arp_response_valid = 0; reg arp_response_error = 0; reg [47:0] arp_response_mac = 0; -reg input_ip_hdr_valid = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [7:0] input_ip_payload_tdata = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg input_udp_hdr_valid = 0; -reg [5:0] input_udp_ip_dscp = 0; -reg [1:0] input_udp_ip_ecn = 0; -reg [7:0] input_udp_ip_ttl = 0; -reg [31:0] input_udp_ip_source_ip = 0; -reg [31:0] input_udp_ip_dest_ip = 0; -reg [15:0] input_udp_source_port = 0; -reg [15:0] input_udp_dest_port = 0; -reg [15:0] input_udp_length = 0; -reg [15:0] input_udp_checksum = 0; -reg [7:0] input_udp_payload_tdata = 0; -reg input_udp_payload_tvalid = 0; -reg input_udp_payload_tlast = 0; -reg input_udp_payload_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [7:0] s_ip_payload_axis_tdata = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg s_udp_hdr_valid = 0; +reg [5:0] s_udp_ip_dscp = 0; +reg [1:0] s_udp_ip_ecn = 0; +reg [7:0] s_udp_ip_ttl = 0; +reg [31:0] s_udp_ip_source_ip = 0; +reg [31:0] s_udp_ip_dest_ip = 0; +reg [15:0] s_udp_source_port = 0; +reg [15:0] s_udp_dest_port = 0; +reg [15:0] s_udp_length = 0; +reg [15:0] s_udp_checksum = 0; +reg [7:0] s_udp_payload_axis_tdata = 0; +reg s_udp_payload_axis_tvalid = 0; +reg s_udp_payload_axis_tlast = 0; +reg s_udp_payload_axis_tuser = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; reg [47:0] local_mac = 0; reg [31:0] local_ip = 0; reg [31:0] gateway_ip = 0; @@ -95,68 +95,68 @@ reg [31:0] subnet_mask = 0; reg clear_arp_cache = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire input_udp_hdr_ready; -wire input_udp_payload_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [7:0] output_eth_payload_tdata; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire s_udp_hdr_ready; +wire s_udp_payload_axis_tready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [7:0] m_eth_payload_axis_tdata; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire arp_request_valid; wire [31:0] arp_request_ip; -wire output_ip_hdr_valid; -wire [47:0] output_ip_eth_dest_mac; -wire [47:0] output_ip_eth_src_mac; -wire [15:0] output_ip_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [7:0] output_ip_payload_tdata; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; -wire output_udp_hdr_valid; -wire [47:0] output_udp_eth_dest_mac; -wire [47:0] output_udp_eth_src_mac; -wire [15:0] output_udp_eth_type; -wire [3:0] output_udp_ip_version; -wire [3:0] output_udp_ip_ihl; -wire [5:0] output_udp_ip_dscp; -wire [1:0] output_udp_ip_ecn; -wire [15:0] output_udp_ip_length; -wire [15:0] output_udp_ip_identification; -wire [2:0] output_udp_ip_flags; -wire [12:0] output_udp_ip_fragment_offset; -wire [7:0] output_udp_ip_ttl; -wire [7:0] output_udp_ip_protocol; -wire [15:0] output_udp_ip_header_checksum; -wire [31:0] output_udp_ip_source_ip; -wire [31:0] output_udp_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [7:0] output_udp_payload_tdata; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire m_ip_hdr_valid; +wire [47:0] m_ip_eth_dest_mac; +wire [47:0] m_ip_eth_src_mac; +wire [15:0] m_ip_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [7:0] m_ip_payload_axis_tdata; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; +wire m_udp_hdr_valid; +wire [47:0] m_udp_eth_dest_mac; +wire [47:0] m_udp_eth_src_mac; +wire [15:0] m_udp_eth_type; +wire [3:0] m_udp_ip_version; +wire [3:0] m_udp_ip_ihl; +wire [5:0] m_udp_ip_dscp; +wire [1:0] m_udp_ip_ecn; +wire [15:0] m_udp_ip_length; +wire [15:0] m_udp_ip_identification; +wire [2:0] m_udp_ip_flags; +wire [12:0] m_udp_ip_fragment_offset; +wire [7:0] m_udp_ip_ttl; +wire [7:0] m_udp_ip_protocol; +wire [15:0] m_udp_ip_header_checksum; +wire [31:0] m_udp_ip_source_ip; +wire [31:0] m_udp_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [7:0] m_udp_payload_axis_tdata; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire m_udp_payload_axis_tuser; wire ip_rx_busy; wire ip_tx_busy; wire udp_rx_busy; @@ -177,46 +177,46 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - input_ip_hdr_valid, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_ttl, - input_ip_protocol, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - input_udp_hdr_valid, - input_udp_ip_dscp, - input_udp_ip_ecn, - input_udp_ip_ttl, - input_udp_ip_source_ip, - input_udp_ip_dest_ip, - input_udp_source_port, - input_udp_dest_port, - input_udp_length, - input_udp_checksum, - input_udp_payload_tdata, - input_udp_payload_tvalid, - input_udp_payload_tlast, - input_udp_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, - output_ip_hdr_ready, - output_ip_payload_tready, - output_udp_hdr_ready, - output_udp_payload_tready, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + s_ip_hdr_valid, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_ttl, + s_ip_protocol, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + s_udp_hdr_valid, + s_udp_ip_dscp, + s_udp_ip_ecn, + s_udp_ip_ttl, + s_udp_ip_source_ip, + s_udp_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, + m_ip_hdr_ready, + m_ip_payload_axis_tready, + m_udp_hdr_ready, + m_udp_payload_axis_tready, local_mac, local_ip, gateway_ip, @@ -224,66 +224,66 @@ initial begin clear_arp_cache ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - input_ip_hdr_ready, - input_ip_payload_tready, - input_udp_hdr_ready, - input_udp_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, - output_ip_hdr_valid, - output_ip_eth_dest_mac, - output_ip_eth_src_mac, - output_ip_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, - output_udp_hdr_valid, - output_udp_eth_dest_mac, - output_udp_eth_src_mac, - output_udp_eth_type, - output_udp_ip_version, - output_udp_ip_ihl, - output_udp_ip_dscp, - output_udp_ip_ecn, - output_udp_ip_length, - output_udp_ip_identification, - output_udp_ip_flags, - output_udp_ip_fragment_offset, - output_udp_ip_ttl, - output_udp_ip_protocol, - output_udp_ip_header_checksum, - output_udp_ip_source_ip, - output_udp_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, + m_ip_hdr_valid, + m_ip_eth_dest_mac, + m_ip_eth_src_mac, + m_ip_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, + m_udp_hdr_valid, + m_udp_eth_dest_mac, + m_udp_eth_src_mac, + m_udp_eth_type, + m_udp_ip_version, + m_udp_ip_ihl, + m_udp_ip_dscp, + m_udp_ip_ecn, + m_udp_ip_length, + m_udp_ip_identification, + m_udp_ip_flags, + m_udp_ip_fragment_offset, + m_udp_ip_ttl, + m_udp_ip_protocol, + m_udp_ip_header_checksum, + m_udp_ip_source_ip, + m_udp_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser, ip_rx_busy, ip_tx_busy, udp_rx_busy, @@ -317,111 +317,111 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_ip_eth_dest_mac(output_ip_eth_dest_mac), - .output_ip_eth_src_mac(output_ip_eth_src_mac), - .output_ip_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_ip_eth_dest_mac(m_ip_eth_dest_mac), + .m_ip_eth_src_mac(m_ip_eth_src_mac), + .m_ip_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_udp_ip_dscp(input_udp_ip_dscp), - .input_udp_ip_ecn(input_udp_ip_ecn), - .input_udp_ip_ttl(input_udp_ip_ttl), - .input_udp_ip_source_ip(input_udp_ip_source_ip), - .input_udp_ip_dest_ip(input_udp_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), - .input_udp_checksum(input_udp_checksum), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_udp_ip_dscp(s_udp_ip_dscp), + .s_udp_ip_ecn(s_udp_ip_ecn), + .s_udp_ip_ttl(s_udp_ip_ttl), + .s_udp_ip_source_ip(s_udp_ip_source_ip), + .s_udp_ip_dest_ip(s_udp_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_udp_eth_dest_mac(output_udp_eth_dest_mac), - .output_udp_eth_src_mac(output_udp_eth_src_mac), - .output_udp_eth_type(output_udp_eth_type), - .output_udp_ip_version(output_udp_ip_version), - .output_udp_ip_ihl(output_udp_ip_ihl), - .output_udp_ip_dscp(output_udp_ip_dscp), - .output_udp_ip_ecn(output_udp_ip_ecn), - .output_udp_ip_length(output_udp_ip_length), - .output_udp_ip_identification(output_udp_ip_identification), - .output_udp_ip_flags(output_udp_ip_flags), - .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), - .output_udp_ip_ttl(output_udp_ip_ttl), - .output_udp_ip_protocol(output_udp_ip_protocol), - .output_udp_ip_header_checksum(output_udp_ip_header_checksum), - .output_udp_ip_source_ip(output_udp_ip_source_ip), - .output_udp_ip_dest_ip(output_udp_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_udp_eth_dest_mac(m_udp_eth_dest_mac), + .m_udp_eth_src_mac(m_udp_eth_src_mac), + .m_udp_eth_type(m_udp_eth_type), + .m_udp_ip_version(m_udp_ip_version), + .m_udp_ip_ihl(m_udp_ip_ihl), + .m_udp_ip_dscp(m_udp_ip_dscp), + .m_udp_ip_ecn(m_udp_ip_ecn), + .m_udp_ip_length(m_udp_ip_length), + .m_udp_ip_identification(m_udp_ip_identification), + .m_udp_ip_flags(m_udp_ip_flags), + .m_udp_ip_fragment_offset(m_udp_ip_fragment_offset), + .m_udp_ip_ttl(m_udp_ip_ttl), + .m_udp_ip_protocol(m_udp_ip_protocol), + .m_udp_ip_header_checksum(m_udp_ip_header_checksum), + .m_udp_ip_source_ip(m_udp_ip_source_ip), + .m_udp_ip_dest_ip(m_udp_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Status signals .ip_rx_busy(ip_rx_busy), .ip_tx_busy(ip_tx_busy), diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py index a78366d8f..c285a4b92 100755 --- a/tb/test_udp_complete_64.py +++ b/tb/test_udp_complete_64.py @@ -68,114 +68,114 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_eth_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_eth_payload_tdata = Signal(intbv(0)[64:]) - input_eth_payload_tkeep = Signal(intbv(0)[8:]) - input_eth_payload_tvalid = Signal(bool(0)) - input_eth_payload_tlast = Signal(bool(0)) - input_eth_payload_tuser = Signal(bool(0)) - input_ip_hdr_valid = Signal(bool(0)) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[64:]) - input_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - input_udp_hdr_valid = Signal(bool(0)) - input_udp_ip_dscp = Signal(intbv(0)[6:]) - input_udp_ip_ecn = Signal(intbv(0)[2:]) - input_udp_ip_ttl = Signal(intbv(0)[8:]) - input_udp_ip_source_ip = Signal(intbv(0)[32:]) - input_udp_ip_dest_ip = Signal(intbv(0)[32:]) - input_udp_source_port = Signal(intbv(0)[16:]) - input_udp_dest_port = Signal(intbv(0)[16:]) - input_udp_length = Signal(intbv(0)[16:]) - input_udp_checksum = Signal(intbv(0)[16:]) - input_udp_payload_tdata = Signal(intbv(0)[64:]) - input_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_udp_payload_tvalid = Signal(bool(0)) - input_udp_payload_tlast = Signal(bool(0)) - input_udp_payload_tuser = Signal(bool(0)) - output_eth_payload_tready = Signal(bool(0)) - output_eth_hdr_ready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) - output_udp_payload_tready = Signal(bool(0)) + s_eth_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + s_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_eth_payload_axis_tvalid = Signal(bool(0)) + s_eth_payload_axis_tlast = Signal(bool(0)) + s_eth_payload_axis_tuser = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + s_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + s_udp_hdr_valid = Signal(bool(0)) + s_udp_ip_dscp = Signal(intbv(0)[6:]) + s_udp_ip_ecn = Signal(intbv(0)[2:]) + s_udp_ip_ttl = Signal(intbv(0)[8:]) + s_udp_ip_source_ip = Signal(intbv(0)[32:]) + s_udp_ip_dest_ip = Signal(intbv(0)[32:]) + s_udp_source_port = Signal(intbv(0)[16:]) + s_udp_dest_port = Signal(intbv(0)[16:]) + s_udp_length = Signal(intbv(0)[16:]) + s_udp_checksum = Signal(intbv(0)[16:]) + s_udp_payload_axis_tdata = Signal(intbv(0)[64:]) + s_udp_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_udp_payload_axis_tvalid = Signal(bool(0)) + s_udp_payload_axis_tlast = Signal(bool(0)) + s_udp_payload_axis_tuser = Signal(bool(0)) + m_eth_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_ready = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) # Outputs - input_eth_hdr_ready = Signal(bool(0)) - input_eth_payload_tready = Signal(bool(0)) - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - input_udp_hdr_ready = Signal(bool(0)) - input_udp_payload_tready = Signal(bool(0)) - output_eth_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_eth_payload_tdata = Signal(intbv(0)[64:]) - output_eth_payload_tkeep = Signal(intbv(0)[8:]) - output_eth_payload_tvalid = Signal(bool(0)) - output_eth_payload_tlast = Signal(bool(0)) - output_eth_payload_tuser = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_ip_eth_dest_mac = Signal(intbv(0)[48:]) - output_ip_eth_src_mac = Signal(intbv(0)[48:]) - output_ip_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[64:]) - output_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) - output_udp_hdr_valid = Signal(bool(0)) - output_udp_eth_dest_mac = Signal(intbv(0)[48:]) - output_udp_eth_src_mac = Signal(intbv(0)[48:]) - output_udp_eth_type = Signal(intbv(0)[16:]) - output_udp_ip_version = Signal(intbv(0)[4:]) - output_udp_ip_ihl = Signal(intbv(0)[4:]) - output_udp_ip_dscp = Signal(intbv(0)[6:]) - output_udp_ip_ecn = Signal(intbv(0)[2:]) - output_udp_ip_length = Signal(intbv(0)[16:]) - output_udp_ip_identification = Signal(intbv(0)[16:]) - output_udp_ip_flags = Signal(intbv(0)[3:]) - output_udp_ip_fragment_offset = Signal(intbv(0)[13:]) - output_udp_ip_ttl = Signal(intbv(0)[8:]) - output_udp_ip_protocol = Signal(intbv(0)[8:]) - output_udp_ip_header_checksum = Signal(intbv(0)[16:]) - output_udp_ip_source_ip = Signal(intbv(0)[32:]) - output_udp_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[64:]) - output_udp_payload_tkeep = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + s_eth_hdr_ready = Signal(bool(0)) + s_eth_payload_axis_tready = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + s_udp_hdr_ready = Signal(bool(0)) + s_udp_payload_axis_tready = Signal(bool(0)) + m_eth_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[64:]) + m_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_eth_payload_axis_tvalid = Signal(bool(0)) + m_eth_payload_axis_tlast = Signal(bool(0)) + m_eth_payload_axis_tuser = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_ip_eth_dest_mac = Signal(intbv(0)[48:]) + m_ip_eth_src_mac = Signal(intbv(0)[48:]) + m_ip_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + m_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) + m_udp_hdr_valid = Signal(bool(0)) + m_udp_eth_dest_mac = Signal(intbv(0)[48:]) + m_udp_eth_src_mac = Signal(intbv(0)[48:]) + m_udp_eth_type = Signal(intbv(0)[16:]) + m_udp_ip_version = Signal(intbv(0)[4:]) + m_udp_ip_ihl = Signal(intbv(0)[4:]) + m_udp_ip_dscp = Signal(intbv(0)[6:]) + m_udp_ip_ecn = Signal(intbv(0)[2:]) + m_udp_ip_length = Signal(intbv(0)[16:]) + m_udp_ip_identification = Signal(intbv(0)[16:]) + m_udp_ip_flags = Signal(intbv(0)[3:]) + m_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + m_udp_ip_ttl = Signal(intbv(0)[8:]) + m_udp_ip_protocol = Signal(intbv(0)[8:]) + m_udp_ip_header_checksum = Signal(intbv(0)[16:]) + m_udp_ip_source_ip = Signal(intbv(0)[32:]) + m_udp_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[64:]) + m_udp_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tuser = Signal(bool(0)) ip_rx_busy = Signal(bool(0)) ip_tx_busy = Signal(bool(0)) udp_rx_busy = Signal(bool(0)) @@ -208,17 +208,17 @@ def bench(): eth_source_logic = eth_source.create_logic( clk, rst, - eth_hdr_ready=input_eth_hdr_ready, - eth_hdr_valid=input_eth_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - eth_payload_tdata=input_eth_payload_tdata, - eth_payload_tkeep=input_eth_payload_tkeep, - eth_payload_tvalid=input_eth_payload_tvalid, - eth_payload_tready=input_eth_payload_tready, - eth_payload_tlast=input_eth_payload_tlast, - eth_payload_tuser=input_eth_payload_tuser, + eth_hdr_ready=s_eth_hdr_ready, + eth_hdr_valid=s_eth_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tkeep=s_eth_payload_axis_tkeep, + eth_payload_tvalid=s_eth_payload_axis_tvalid, + eth_payload_tready=s_eth_payload_axis_tready, + eth_payload_tlast=s_eth_payload_axis_tlast, + eth_payload_tuser=s_eth_payload_axis_tuser, pause=eth_source_pause, name='eth_source' ) @@ -228,17 +228,17 @@ def bench(): eth_sink_logic = eth_sink.create_logic( clk, rst, - eth_hdr_ready=output_eth_hdr_ready, - eth_hdr_valid=output_eth_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - eth_payload_tdata=output_eth_payload_tdata, - eth_payload_tkeep=output_eth_payload_tkeep, - eth_payload_tvalid=output_eth_payload_tvalid, - eth_payload_tready=output_eth_payload_tready, - eth_payload_tlast=output_eth_payload_tlast, - eth_payload_tuser=output_eth_payload_tuser, + eth_hdr_ready=m_eth_hdr_ready, + eth_hdr_valid=m_eth_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, + eth_payload_tvalid=m_eth_payload_axis_tvalid, + eth_payload_tready=m_eth_payload_axis_tready, + eth_payload_tlast=m_eth_payload_axis_tlast, + eth_payload_tuser=m_eth_payload_axis_tuser, pause=eth_sink_pause, name='eth_sink' ) @@ -248,21 +248,21 @@ def bench(): ip_source_logic = ip_source.create_logic( clk, rst, - ip_hdr_valid=input_ip_hdr_valid, - ip_hdr_ready=input_ip_hdr_ready, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tkeep=input_ip_payload_tkeep, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_valid=s_ip_hdr_valid, + ip_hdr_ready=s_ip_hdr_ready, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tkeep=s_ip_payload_axis_tkeep, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=ip_source_pause, name='ip_source' ) @@ -272,30 +272,30 @@ def bench(): ip_sink_logic = ip_sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_ip_eth_dest_mac, - eth_src_mac=output_ip_eth_src_mac, - eth_type=output_ip_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tkeep=output_ip_payload_tkeep, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_ip_eth_dest_mac, + eth_src_mac=m_ip_eth_src_mac, + eth_type=m_ip_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tkeep=m_ip_payload_axis_tkeep, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=ip_sink_pause, name='ip_sink' ) @@ -305,23 +305,23 @@ def bench(): udp_source_logic = udp_source.create_logic( clk, rst, - udp_hdr_ready=input_udp_hdr_ready, - udp_hdr_valid=input_udp_hdr_valid, - ip_dscp=input_udp_ip_dscp, - ip_ecn=input_udp_ip_ecn, - ip_ttl=input_udp_ip_ttl, - ip_source_ip=input_udp_ip_source_ip, - ip_dest_ip=input_udp_ip_dest_ip, - udp_source_port=input_udp_source_port, - udp_dest_port=input_udp_dest_port, - udp_length=input_udp_length, - udp_checksum=input_udp_checksum, - udp_payload_tdata=input_udp_payload_tdata, - udp_payload_tkeep=input_udp_payload_tkeep, - udp_payload_tvalid=input_udp_payload_tvalid, - udp_payload_tready=input_udp_payload_tready, - udp_payload_tlast=input_udp_payload_tlast, - udp_payload_tuser=input_udp_payload_tuser, + udp_hdr_ready=s_udp_hdr_ready, + udp_hdr_valid=s_udp_hdr_valid, + ip_dscp=s_udp_ip_dscp, + ip_ecn=s_udp_ip_ecn, + ip_ttl=s_udp_ip_ttl, + ip_source_ip=s_udp_ip_source_ip, + ip_dest_ip=s_udp_ip_dest_ip, + udp_source_port=s_udp_source_port, + udp_dest_port=s_udp_dest_port, + udp_length=s_udp_length, + udp_checksum=s_udp_checksum, + udp_payload_tdata=s_udp_payload_axis_tdata, + udp_payload_tkeep=s_udp_payload_axis_tkeep, + udp_payload_tvalid=s_udp_payload_axis_tvalid, + udp_payload_tready=s_udp_payload_axis_tready, + udp_payload_tlast=s_udp_payload_axis_tlast, + udp_payload_tuser=s_udp_payload_axis_tuser, pause=udp_source_pause, name='udp_source' ) @@ -331,34 +331,34 @@ def bench(): udp_sink_logic = udp_sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_udp_eth_dest_mac, - eth_src_mac=output_udp_eth_src_mac, - eth_type=output_udp_eth_type, - ip_version=output_udp_ip_version, - ip_ihl=output_udp_ip_ihl, - ip_dscp=output_udp_ip_dscp, - ip_ecn=output_udp_ip_ecn, - ip_length=output_udp_ip_length, - ip_identification=output_udp_ip_identification, - ip_flags=output_udp_ip_flags, - ip_fragment_offset=output_udp_ip_fragment_offset, - ip_ttl=output_udp_ip_ttl, - ip_protocol=output_udp_ip_protocol, - ip_header_checksum=output_udp_ip_header_checksum, - ip_source_ip=output_udp_ip_source_ip, - ip_dest_ip=output_udp_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tkeep=output_udp_payload_tkeep, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_udp_eth_dest_mac, + eth_src_mac=m_udp_eth_src_mac, + eth_type=m_udp_eth_type, + ip_version=m_udp_ip_version, + ip_ihl=m_udp_ip_ihl, + ip_dscp=m_udp_ip_dscp, + ip_ecn=m_udp_ip_ecn, + ip_length=m_udp_ip_length, + ip_identification=m_udp_ip_identification, + ip_flags=m_udp_ip_flags, + ip_fragment_offset=m_udp_ip_fragment_offset, + ip_ttl=m_udp_ip_ttl, + ip_protocol=m_udp_ip_protocol, + ip_header_checksum=m_udp_ip_header_checksum, + ip_source_ip=m_udp_ip_source_ip, + ip_dest_ip=m_udp_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tkeep=m_udp_payload_axis_tkeep, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=udp_sink_pause, name='udp_sink' ) @@ -373,117 +373,117 @@ def bench(): rst=rst, current_test=current_test, - input_eth_hdr_valid=input_eth_hdr_valid, - input_eth_hdr_ready=input_eth_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_eth_payload_tdata=input_eth_payload_tdata, - input_eth_payload_tkeep=input_eth_payload_tkeep, - input_eth_payload_tvalid=input_eth_payload_tvalid, - input_eth_payload_tready=input_eth_payload_tready, - input_eth_payload_tlast=input_eth_payload_tlast, - input_eth_payload_tuser=input_eth_payload_tuser, + s_eth_hdr_valid=s_eth_hdr_valid, + s_eth_hdr_ready=s_eth_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, + s_eth_payload_axis_tready=s_eth_payload_axis_tready, + s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, - output_eth_hdr_valid=output_eth_hdr_valid, - output_eth_hdr_ready=output_eth_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_eth_payload_tdata=output_eth_payload_tdata, - output_eth_payload_tkeep=output_eth_payload_tkeep, - output_eth_payload_tvalid=output_eth_payload_tvalid, - output_eth_payload_tready=output_eth_payload_tready, - output_eth_payload_tlast=output_eth_payload_tlast, - output_eth_payload_tuser=output_eth_payload_tuser, + m_eth_hdr_valid=m_eth_hdr_valid, + m_eth_hdr_ready=m_eth_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, + m_eth_payload_axis_tready=m_eth_payload_axis_tready, + m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser=m_eth_payload_axis_tuser, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tkeep=input_ip_payload_tkeep, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_ip_eth_dest_mac=output_ip_eth_dest_mac, - output_ip_eth_src_mac=output_ip_eth_src_mac, - output_ip_eth_type=output_ip_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tkeep=output_ip_payload_tkeep, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_ip_eth_dest_mac=m_ip_eth_dest_mac, + m_ip_eth_src_mac=m_ip_eth_src_mac, + m_ip_eth_type=m_ip_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, - input_udp_hdr_valid=input_udp_hdr_valid, - input_udp_hdr_ready=input_udp_hdr_ready, - input_udp_ip_dscp=input_udp_ip_dscp, - input_udp_ip_ecn=input_udp_ip_ecn, - input_udp_ip_ttl=input_udp_ip_ttl, - input_udp_ip_source_ip=input_udp_ip_source_ip, - input_udp_ip_dest_ip=input_udp_ip_dest_ip, - input_udp_source_port=input_udp_source_port, - input_udp_dest_port=input_udp_dest_port, - input_udp_length=input_udp_length, - input_udp_checksum=input_udp_checksum, - input_udp_payload_tdata=input_udp_payload_tdata, - input_udp_payload_tkeep=input_udp_payload_tkeep, - input_udp_payload_tvalid=input_udp_payload_tvalid, - input_udp_payload_tready=input_udp_payload_tready, - input_udp_payload_tlast=input_udp_payload_tlast, - input_udp_payload_tuser=input_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_udp_ip_dscp=s_udp_ip_dscp, + s_udp_ip_ecn=s_udp_ip_ecn, + s_udp_ip_ttl=s_udp_ip_ttl, + s_udp_ip_source_ip=s_udp_ip_source_ip, + s_udp_ip_dest_ip=s_udp_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep=s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_udp_eth_dest_mac=output_udp_eth_dest_mac, - output_udp_eth_src_mac=output_udp_eth_src_mac, - output_udp_eth_type=output_udp_eth_type, - output_udp_ip_version=output_udp_ip_version, - output_udp_ip_ihl=output_udp_ip_ihl, - output_udp_ip_dscp=output_udp_ip_dscp, - output_udp_ip_ecn=output_udp_ip_ecn, - output_udp_ip_length=output_udp_ip_length, - output_udp_ip_identification=output_udp_ip_identification, - output_udp_ip_flags=output_udp_ip_flags, - output_udp_ip_fragment_offset=output_udp_ip_fragment_offset, - output_udp_ip_ttl=output_udp_ip_ttl, - output_udp_ip_protocol=output_udp_ip_protocol, - output_udp_ip_header_checksum=output_udp_ip_header_checksum, - output_udp_ip_source_ip=output_udp_ip_source_ip, - output_udp_ip_dest_ip=output_udp_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tkeep=output_udp_payload_tkeep, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_udp_eth_dest_mac=m_udp_eth_dest_mac, + m_udp_eth_src_mac=m_udp_eth_src_mac, + m_udp_eth_type=m_udp_eth_type, + m_udp_ip_version=m_udp_ip_version, + m_udp_ip_ihl=m_udp_ip_ihl, + m_udp_ip_dscp=m_udp_ip_dscp, + m_udp_ip_ecn=m_udp_ip_ecn, + m_udp_ip_length=m_udp_ip_length, + m_udp_ip_identification=m_udp_ip_identification, + m_udp_ip_flags=m_udp_ip_flags, + m_udp_ip_fragment_offset=m_udp_ip_fragment_offset, + m_udp_ip_ttl=m_udp_ip_ttl, + m_udp_ip_protocol=m_udp_ip_protocol, + m_udp_ip_header_checksum=m_udp_ip_header_checksum, + m_udp_ip_source_ip=m_udp_ip_source_ip, + m_udp_ip_dest_ip=m_udp_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep=m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, ip_rx_busy=ip_rx_busy, ip_tx_busy=ip_tx_busy, @@ -545,9 +545,9 @@ def bench(): i = 20 while i > 0: i = max(0, i-1) - if (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or - output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or - input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): + if (s_eth_payload_axis_tvalid or s_ip_payload_axis_tvalid or s_udp_payload_axis_tvalid or + m_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or + s_eth_hdr_valid or s_ip_hdr_valid or s_udp_hdr_valid): i = 20 yield clk.posedge diff --git a/tb/test_udp_complete_64.v b/tb/test_udp_complete_64.v index 348a0de26..7822a6841 100644 --- a/tb/test_udp_complete_64.v +++ b/tb/test_udp_complete_64.v @@ -45,52 +45,52 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_eth_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [63:0] input_eth_payload_tdata = 0; -reg [7:0] input_eth_payload_tkeep = 0; -reg input_eth_payload_tvalid = 0; -reg input_eth_payload_tlast = 0; -reg input_eth_payload_tuser = 0; +reg s_eth_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [63:0] s_eth_payload_axis_tdata = 0; +reg [7:0] s_eth_payload_axis_tkeep = 0; +reg s_eth_payload_axis_tvalid = 0; +reg s_eth_payload_axis_tlast = 0; +reg s_eth_payload_axis_tuser = 0; reg arp_response_valid = 0; reg arp_response_error = 0; reg [47:0] arp_response_mac = 0; -reg input_ip_hdr_valid = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [63:0] input_ip_payload_tdata = 0; -reg [7:0] input_ip_payload_tkeep = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg input_udp_hdr_valid = 0; -reg [5:0] input_udp_ip_dscp = 0; -reg [1:0] input_udp_ip_ecn = 0; -reg [7:0] input_udp_ip_ttl = 0; -reg [31:0] input_udp_ip_source_ip = 0; -reg [31:0] input_udp_ip_dest_ip = 0; -reg [15:0] input_udp_source_port = 0; -reg [15:0] input_udp_dest_port = 0; -reg [15:0] input_udp_length = 0; -reg [15:0] input_udp_checksum = 0; -reg [63:0] input_udp_payload_tdata = 0; -reg [7:0] input_udp_payload_tkeep = 0; -reg input_udp_payload_tvalid = 0; -reg input_udp_payload_tlast = 0; -reg input_udp_payload_tuser = 0; -reg output_eth_hdr_ready = 0; -reg output_eth_payload_tready = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [63:0] s_ip_payload_axis_tdata = 0; +reg [7:0] s_ip_payload_axis_tkeep = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg s_udp_hdr_valid = 0; +reg [5:0] s_udp_ip_dscp = 0; +reg [1:0] s_udp_ip_ecn = 0; +reg [7:0] s_udp_ip_ttl = 0; +reg [31:0] s_udp_ip_source_ip = 0; +reg [31:0] s_udp_ip_dest_ip = 0; +reg [15:0] s_udp_source_port = 0; +reg [15:0] s_udp_dest_port = 0; +reg [15:0] s_udp_length = 0; +reg [15:0] s_udp_checksum = 0; +reg [63:0] s_udp_payload_axis_tdata = 0; +reg [7:0] s_udp_payload_axis_tkeep = 0; +reg s_udp_payload_axis_tvalid = 0; +reg s_udp_payload_axis_tlast = 0; +reg s_udp_payload_axis_tuser = 0; +reg m_eth_hdr_ready = 0; +reg m_eth_payload_axis_tready = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; reg [47:0] local_mac = 0; reg [31:0] local_ip = 0; reg [31:0] gateway_ip = 0; @@ -98,71 +98,71 @@ reg [31:0] subnet_mask = 0; reg clear_arp_cache = 0; // Outputs -wire input_eth_hdr_ready; -wire input_eth_payload_tready; -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire input_udp_hdr_ready; -wire input_udp_payload_tready; -wire output_eth_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [63:0] output_eth_payload_tdata; -wire [7:0] output_eth_payload_tkeep; -wire output_eth_payload_tvalid; -wire output_eth_payload_tlast; -wire output_eth_payload_tuser; +wire s_eth_hdr_ready; +wire s_eth_payload_axis_tready; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire s_udp_hdr_ready; +wire s_udp_payload_axis_tready; +wire m_eth_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [63:0] m_eth_payload_axis_tdata; +wire [7:0] m_eth_payload_axis_tkeep; +wire m_eth_payload_axis_tvalid; +wire m_eth_payload_axis_tlast; +wire m_eth_payload_axis_tuser; wire arp_request_valid; wire [31:0] arp_request_ip; -wire output_ip_hdr_valid; -wire [47:0] output_ip_eth_dest_mac; -wire [47:0] output_ip_eth_src_mac; -wire [15:0] output_ip_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [63:0] output_ip_payload_tdata; -wire [7:0] output_ip_payload_tkeep; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; -wire output_udp_hdr_valid; -wire [47:0] output_udp_eth_dest_mac; -wire [47:0] output_udp_eth_src_mac; -wire [15:0] output_udp_eth_type; -wire [3:0] output_udp_ip_version; -wire [3:0] output_udp_ip_ihl; -wire [5:0] output_udp_ip_dscp; -wire [1:0] output_udp_ip_ecn; -wire [15:0] output_udp_ip_length; -wire [15:0] output_udp_ip_identification; -wire [2:0] output_udp_ip_flags; -wire [12:0] output_udp_ip_fragment_offset; -wire [7:0] output_udp_ip_ttl; -wire [7:0] output_udp_ip_protocol; -wire [15:0] output_udp_ip_header_checksum; -wire [31:0] output_udp_ip_source_ip; -wire [31:0] output_udp_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [63:0] output_udp_payload_tdata; -wire [7:0] output_udp_payload_tkeep; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire m_ip_hdr_valid; +wire [47:0] m_ip_eth_dest_mac; +wire [47:0] m_ip_eth_src_mac; +wire [15:0] m_ip_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [63:0] m_ip_payload_axis_tdata; +wire [7:0] m_ip_payload_axis_tkeep; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; +wire m_udp_hdr_valid; +wire [47:0] m_udp_eth_dest_mac; +wire [47:0] m_udp_eth_src_mac; +wire [15:0] m_udp_eth_type; +wire [3:0] m_udp_ip_version; +wire [3:0] m_udp_ip_ihl; +wire [5:0] m_udp_ip_dscp; +wire [1:0] m_udp_ip_ecn; +wire [15:0] m_udp_ip_length; +wire [15:0] m_udp_ip_identification; +wire [2:0] m_udp_ip_flags; +wire [12:0] m_udp_ip_fragment_offset; +wire [7:0] m_udp_ip_ttl; +wire [7:0] m_udp_ip_protocol; +wire [15:0] m_udp_ip_header_checksum; +wire [31:0] m_udp_ip_source_ip; +wire [31:0] m_udp_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [63:0] m_udp_payload_axis_tdata; +wire [7:0] m_udp_payload_axis_tkeep; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire m_udp_payload_axis_tuser; wire ip_rx_busy; wire ip_tx_busy; wire udp_rx_busy; @@ -183,49 +183,49 @@ initial begin clk, rst, current_test, - input_eth_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_eth_payload_tdata, - input_eth_payload_tkeep, - input_eth_payload_tvalid, - input_eth_payload_tlast, - input_eth_payload_tuser, - input_ip_hdr_valid, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_ttl, - input_ip_protocol, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tkeep, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - input_udp_hdr_valid, - input_udp_ip_dscp, - input_udp_ip_ecn, - input_udp_ip_ttl, - input_udp_ip_source_ip, - input_udp_ip_dest_ip, - input_udp_source_port, - input_udp_dest_port, - input_udp_length, - input_udp_checksum, - input_udp_payload_tdata, - input_udp_payload_tkeep, - input_udp_payload_tvalid, - input_udp_payload_tlast, - input_udp_payload_tuser, - output_eth_hdr_ready, - output_eth_payload_tready, - output_ip_hdr_ready, - output_ip_payload_tready, - output_udp_hdr_ready, - output_udp_payload_tready, + s_eth_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, + s_eth_payload_axis_tvalid, + s_eth_payload_axis_tlast, + s_eth_payload_axis_tuser, + s_ip_hdr_valid, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_ttl, + s_ip_protocol, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + s_udp_hdr_valid, + s_udp_ip_dscp, + s_udp_ip_ecn, + s_udp_ip_ttl, + s_udp_ip_source_ip, + s_udp_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser, + m_eth_hdr_ready, + m_eth_payload_axis_tready, + m_ip_hdr_ready, + m_ip_payload_axis_tready, + m_udp_hdr_ready, + m_udp_payload_axis_tready, local_mac, local_ip, gateway_ip, @@ -233,69 +233,69 @@ initial begin clear_arp_cache ); $to_myhdl( - input_eth_hdr_ready, - input_eth_payload_tready, - input_ip_hdr_ready, - input_ip_payload_tready, - input_udp_hdr_ready, - input_udp_payload_tready, - output_eth_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_eth_payload_tdata, - output_eth_payload_tkeep, - output_eth_payload_tvalid, - output_eth_payload_tlast, - output_eth_payload_tuser, - output_ip_hdr_valid, - output_ip_eth_dest_mac, - output_ip_eth_src_mac, - output_ip_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tkeep, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, - output_udp_hdr_valid, - output_udp_eth_dest_mac, - output_udp_eth_src_mac, - output_udp_eth_type, - output_udp_ip_version, - output_udp_ip_ihl, - output_udp_ip_dscp, - output_udp_ip_ecn, - output_udp_ip_length, - output_udp_ip_identification, - output_udp_ip_flags, - output_udp_ip_fragment_offset, - output_udp_ip_ttl, - output_udp_ip_protocol, - output_udp_ip_header_checksum, - output_udp_ip_source_ip, - output_udp_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tkeep, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser, + s_eth_hdr_ready, + s_eth_payload_axis_tready, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_eth_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, + m_eth_payload_axis_tvalid, + m_eth_payload_axis_tlast, + m_eth_payload_axis_tuser, + m_ip_hdr_valid, + m_ip_eth_dest_mac, + m_ip_eth_src_mac, + m_ip_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, + m_udp_hdr_valid, + m_udp_eth_dest_mac, + m_udp_eth_src_mac, + m_udp_eth_type, + m_udp_ip_version, + m_udp_ip_ihl, + m_udp_ip_dscp, + m_udp_ip_ecn, + m_udp_ip_length, + m_udp_ip_identification, + m_udp_ip_flags, + m_udp_ip_fragment_offset, + m_udp_ip_ttl, + m_udp_ip_protocol, + m_udp_ip_header_checksum, + m_udp_ip_source_ip, + m_udp_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser, ip_rx_busy, ip_tx_busy, udp_rx_busy, @@ -329,117 +329,117 @@ UUT ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(input_eth_hdr_valid), - .input_eth_hdr_ready(input_eth_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_eth_payload_tdata(input_eth_payload_tdata), - .input_eth_payload_tkeep(input_eth_payload_tkeep), - .input_eth_payload_tvalid(input_eth_payload_tvalid), - .input_eth_payload_tready(input_eth_payload_tready), - .input_eth_payload_tlast(input_eth_payload_tlast), - .input_eth_payload_tuser(input_eth_payload_tuser), + .s_eth_hdr_valid(s_eth_hdr_valid), + .s_eth_hdr_ready(s_eth_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(s_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(output_eth_hdr_valid), - .output_eth_hdr_ready(output_eth_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_eth_payload_tdata(output_eth_payload_tdata), - .output_eth_payload_tkeep(output_eth_payload_tkeep), - .output_eth_payload_tvalid(output_eth_payload_tvalid), - .output_eth_payload_tready(output_eth_payload_tready), - .output_eth_payload_tlast(output_eth_payload_tlast), - .output_eth_payload_tuser(output_eth_payload_tuser), + .m_eth_hdr_valid(m_eth_hdr_valid), + .m_eth_hdr_ready(m_eth_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(m_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(m_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tkeep(input_ip_payload_tkeep), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_ip_eth_dest_mac(output_ip_eth_dest_mac), - .output_ip_eth_src_mac(output_ip_eth_src_mac), - .output_ip_eth_type(output_ip_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_ip_eth_dest_mac(m_ip_eth_dest_mac), + .m_ip_eth_src_mac(m_ip_eth_src_mac), + .m_ip_eth_type(m_ip_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_udp_ip_dscp(input_udp_ip_dscp), - .input_udp_ip_ecn(input_udp_ip_ecn), - .input_udp_ip_ttl(input_udp_ip_ttl), - .input_udp_ip_source_ip(input_udp_ip_source_ip), - .input_udp_ip_dest_ip(input_udp_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), - .input_udp_checksum(input_udp_checksum), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tkeep(input_udp_payload_tkeep), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_udp_ip_dscp(s_udp_ip_dscp), + .s_udp_ip_ecn(s_udp_ip_ecn), + .s_udp_ip_ttl(s_udp_ip_ttl), + .s_udp_ip_source_ip(s_udp_ip_source_ip), + .s_udp_ip_dest_ip(s_udp_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_udp_eth_dest_mac(output_udp_eth_dest_mac), - .output_udp_eth_src_mac(output_udp_eth_src_mac), - .output_udp_eth_type(output_udp_eth_type), - .output_udp_ip_version(output_udp_ip_version), - .output_udp_ip_ihl(output_udp_ip_ihl), - .output_udp_ip_dscp(output_udp_ip_dscp), - .output_udp_ip_ecn(output_udp_ip_ecn), - .output_udp_ip_length(output_udp_ip_length), - .output_udp_ip_identification(output_udp_ip_identification), - .output_udp_ip_flags(output_udp_ip_flags), - .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), - .output_udp_ip_ttl(output_udp_ip_ttl), - .output_udp_ip_protocol(output_udp_ip_protocol), - .output_udp_ip_header_checksum(output_udp_ip_header_checksum), - .output_udp_ip_source_ip(output_udp_ip_source_ip), - .output_udp_ip_dest_ip(output_udp_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tkeep(output_udp_payload_tkeep), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_udp_eth_dest_mac(m_udp_eth_dest_mac), + .m_udp_eth_src_mac(m_udp_eth_src_mac), + .m_udp_eth_type(m_udp_eth_type), + .m_udp_ip_version(m_udp_ip_version), + .m_udp_ip_ihl(m_udp_ip_ihl), + .m_udp_ip_dscp(m_udp_ip_dscp), + .m_udp_ip_ecn(m_udp_ip_ecn), + .m_udp_ip_length(m_udp_ip_length), + .m_udp_ip_identification(m_udp_ip_identification), + .m_udp_ip_flags(m_udp_ip_flags), + .m_udp_ip_fragment_offset(m_udp_ip_fragment_offset), + .m_udp_ip_ttl(m_udp_ip_ttl), + .m_udp_ip_protocol(m_udp_ip_protocol), + .m_udp_ip_header_checksum(m_udp_ip_header_checksum), + .m_udp_ip_source_ip(m_udp_ip_source_ip), + .m_udp_ip_dest_ip(m_udp_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Status signals .ip_rx_busy(ip_rx_busy), .ip_tx_busy(ip_tx_busy), diff --git a/tb/test_udp_ip_rx.py b/tb/test_udp_ip_rx.py index 4e20a029e..69c43a3bc 100755 --- a/tb/test_udp_ip_rx.py +++ b/tb/test_udp_ip_rx.py @@ -49,58 +49,58 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_ip_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) - output_udp_payload_tready = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) # Outputs - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - output_udp_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + m_udp_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[8:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_header_early_termination = Signal(bool(0)) error_payload_early_termination = Signal(bool(0)) @@ -114,29 +114,29 @@ def bench(): source_logic = source.create_logic( clk, rst, - ip_hdr_ready=input_ip_hdr_ready, - ip_hdr_valid=input_ip_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_ready=s_ip_hdr_ready, + ip_hdr_valid=s_ip_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=source_pause, name='source' ) @@ -146,33 +146,33 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -187,57 +187,57 @@ def bench(): rst=rst, current_test=current_test, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, busy=busy, error_header_early_termination=error_header_early_termination, @@ -259,11 +259,11 @@ def bench(): error_payload_early_termination_asserted.next = 1 def wait_normal(): - while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_ip_hdr_valid: yield clk.posedge def wait_pause_source(): - while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_ip_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -272,7 +272,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_ip_hdr_valid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_udp_ip_rx.v b/tb/test_udp_ip_rx.v index f05f23a47..cad10e133 100644 --- a/tb/test_udp_ip_rx.v +++ b/tb/test_udp_ip_rx.v @@ -36,58 +36,58 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_ip_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [7:0] input_ip_payload_tdata = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [7:0] s_ip_payload_axis_tdata = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; // Outputs -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire output_udp_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [7:0] output_udp_payload_tdata; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire m_udp_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [7:0] m_udp_payload_axis_tdata; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire m_udp_payload_axis_tuser; wire busy; wire error_header_early_termination; wire error_payload_early_termination; @@ -98,58 +98,58 @@ initial begin clk, rst, current_test, - input_ip_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - output_udp_hdr_ready, - output_udp_payload_tready + s_ip_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + m_udp_hdr_ready, + m_udp_payload_axis_tready ); $to_myhdl( - input_ip_hdr_ready, - input_ip_payload_tready, - output_udp_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_udp_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser, busy, error_header_early_termination, error_payload_early_termination @@ -165,57 +165,57 @@ UUT ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Status signals .busy(busy), .error_header_early_termination(error_header_early_termination), diff --git a/tb/test_udp_ip_rx_64.py b/tb/test_udp_ip_rx_64.py index 62357cc21..763fba805 100755 --- a/tb/test_udp_ip_rx_64.py +++ b/tb/test_udp_ip_rx_64.py @@ -49,60 +49,60 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_ip_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_length = Signal(intbv(0)[16:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_ip_payload_tdata = Signal(intbv(0)[64:]) - input_ip_payload_tkeep = Signal(intbv(0)[8:]) - input_ip_payload_tvalid = Signal(bool(0)) - input_ip_payload_tlast = Signal(bool(0)) - input_ip_payload_tuser = Signal(bool(0)) - output_udp_hdr_ready = Signal(bool(0)) - output_udp_payload_tready = Signal(bool(0)) + s_ip_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_length = Signal(intbv(0)[16:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + s_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_ip_payload_axis_tvalid = Signal(bool(0)) + s_ip_payload_axis_tlast = Signal(bool(0)) + s_ip_payload_axis_tuser = Signal(bool(0)) + m_udp_hdr_ready = Signal(bool(0)) + m_udp_payload_axis_tready = Signal(bool(0)) # Outputs - input_ip_hdr_ready = Signal(bool(0)) - input_ip_payload_tready = Signal(bool(0)) - output_udp_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_udp_source_port = Signal(intbv(0)[16:]) - output_udp_dest_port = Signal(intbv(0)[16:]) - output_udp_length = Signal(intbv(0)[16:]) - output_udp_checksum = Signal(intbv(0)[16:]) - output_udp_payload_tdata = Signal(intbv(0)[64:]) - output_udp_payload_tkeep = Signal(intbv(0)[8:]) - output_udp_payload_tvalid = Signal(bool(0)) - output_udp_payload_tlast = Signal(bool(0)) - output_udp_payload_tuser = Signal(bool(0)) + s_ip_hdr_ready = Signal(bool(0)) + s_ip_payload_axis_tready = Signal(bool(0)) + m_udp_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_udp_source_port = Signal(intbv(0)[16:]) + m_udp_dest_port = Signal(intbv(0)[16:]) + m_udp_length = Signal(intbv(0)[16:]) + m_udp_checksum = Signal(intbv(0)[16:]) + m_udp_payload_axis_tdata = Signal(intbv(0)[64:]) + m_udp_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_udp_payload_axis_tvalid = Signal(bool(0)) + m_udp_payload_axis_tlast = Signal(bool(0)) + m_udp_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_header_early_termination = Signal(bool(0)) error_payload_early_termination = Signal(bool(0)) @@ -116,30 +116,30 @@ def bench(): source_logic = source.create_logic( clk, rst, - ip_hdr_ready=input_ip_hdr_ready, - ip_hdr_valid=input_ip_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_length=input_ip_length, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - ip_payload_tdata=input_ip_payload_tdata, - ip_payload_tkeep=input_ip_payload_tkeep, - ip_payload_tvalid=input_ip_payload_tvalid, - ip_payload_tready=input_ip_payload_tready, - ip_payload_tlast=input_ip_payload_tlast, - ip_payload_tuser=input_ip_payload_tuser, + ip_hdr_ready=s_ip_hdr_ready, + ip_hdr_valid=s_ip_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_length=s_ip_length, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + ip_payload_tdata=s_ip_payload_axis_tdata, + ip_payload_tkeep=s_ip_payload_axis_tkeep, + ip_payload_tvalid=s_ip_payload_axis_tvalid, + ip_payload_tready=s_ip_payload_axis_tready, + ip_payload_tlast=s_ip_payload_axis_tlast, + ip_payload_tuser=s_ip_payload_axis_tuser, pause=source_pause, name='source' ) @@ -149,34 +149,34 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - udp_hdr_ready=output_udp_hdr_ready, - udp_hdr_valid=output_udp_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - udp_source_port=output_udp_source_port, - udp_dest_port=output_udp_dest_port, - udp_length=output_udp_length, - udp_checksum=output_udp_checksum, - udp_payload_tdata=output_udp_payload_tdata, - udp_payload_tkeep=output_udp_payload_tkeep, - udp_payload_tvalid=output_udp_payload_tvalid, - udp_payload_tready=output_udp_payload_tready, - udp_payload_tlast=output_udp_payload_tlast, - udp_payload_tuser=output_udp_payload_tuser, + udp_hdr_ready=m_udp_hdr_ready, + udp_hdr_valid=m_udp_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + udp_source_port=m_udp_source_port, + udp_dest_port=m_udp_dest_port, + udp_length=m_udp_length, + udp_checksum=m_udp_checksum, + udp_payload_tdata=m_udp_payload_axis_tdata, + udp_payload_tkeep=m_udp_payload_axis_tkeep, + udp_payload_tvalid=m_udp_payload_axis_tvalid, + udp_payload_tready=m_udp_payload_axis_tready, + udp_payload_tlast=m_udp_payload_axis_tlast, + udp_payload_tuser=m_udp_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -191,59 +191,59 @@ def bench(): rst=rst, current_test=current_test, - input_ip_hdr_valid=input_ip_hdr_valid, - input_ip_hdr_ready=input_ip_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_length=input_ip_length, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_ip_payload_tdata=input_ip_payload_tdata, - input_ip_payload_tkeep=input_ip_payload_tkeep, - input_ip_payload_tvalid=input_ip_payload_tvalid, - input_ip_payload_tready=input_ip_payload_tready, - input_ip_payload_tlast=input_ip_payload_tlast, - input_ip_payload_tuser=input_ip_payload_tuser, + s_ip_hdr_valid=s_ip_hdr_valid, + s_ip_hdr_ready=s_ip_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_length=s_ip_length, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_ip_payload_axis_tdata=s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep=s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid=s_ip_payload_axis_tvalid, + s_ip_payload_axis_tready=s_ip_payload_axis_tready, + s_ip_payload_axis_tlast=s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser=s_ip_payload_axis_tuser, - output_udp_hdr_valid=output_udp_hdr_valid, - output_udp_hdr_ready=output_udp_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_udp_source_port=output_udp_source_port, - output_udp_dest_port=output_udp_dest_port, - output_udp_length=output_udp_length, - output_udp_checksum=output_udp_checksum, - output_udp_payload_tdata=output_udp_payload_tdata, - output_udp_payload_tkeep=output_udp_payload_tkeep, - output_udp_payload_tvalid=output_udp_payload_tvalid, - output_udp_payload_tready=output_udp_payload_tready, - output_udp_payload_tlast=output_udp_payload_tlast, - output_udp_payload_tuser=output_udp_payload_tuser, + m_udp_hdr_valid=m_udp_hdr_valid, + m_udp_hdr_ready=m_udp_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_udp_source_port=m_udp_source_port, + m_udp_dest_port=m_udp_dest_port, + m_udp_length=m_udp_length, + m_udp_checksum=m_udp_checksum, + m_udp_payload_axis_tdata=m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep=m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid=m_udp_payload_axis_tvalid, + m_udp_payload_axis_tready=m_udp_payload_axis_tready, + m_udp_payload_axis_tlast=m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser=m_udp_payload_axis_tuser, busy=busy, error_header_early_termination=error_header_early_termination, @@ -265,11 +265,11 @@ def bench(): error_payload_early_termination_asserted.next = 1 def wait_normal(): - while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_ip_hdr_valid: yield clk.posedge def wait_pause_source(): - while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_ip_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -278,7 +278,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_ip_payload_tvalid or output_udp_payload_tvalid or input_ip_hdr_valid: + while s_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_ip_hdr_valid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_udp_ip_rx_64.v b/tb/test_udp_ip_rx_64.v index 48911aefb..663989b89 100644 --- a/tb/test_udp_ip_rx_64.v +++ b/tb/test_udp_ip_rx_64.v @@ -36,60 +36,60 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_ip_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_length = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [63:0] input_ip_payload_tdata = 0; -reg [7:0] input_ip_payload_tkeep = 0; -reg input_ip_payload_tvalid = 0; -reg input_ip_payload_tlast = 0; -reg input_ip_payload_tuser = 0; -reg output_udp_hdr_ready = 0; -reg output_udp_payload_tready = 0; +reg s_ip_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_length = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [63:0] s_ip_payload_axis_tdata = 0; +reg [7:0] s_ip_payload_axis_tkeep = 0; +reg s_ip_payload_axis_tvalid = 0; +reg s_ip_payload_axis_tlast = 0; +reg s_ip_payload_axis_tuser = 0; +reg m_udp_hdr_ready = 0; +reg m_udp_payload_axis_tready = 0; // Outputs -wire input_ip_hdr_ready; -wire input_ip_payload_tready; -wire output_udp_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [15:0] output_udp_source_port; -wire [15:0] output_udp_dest_port; -wire [15:0] output_udp_length; -wire [15:0] output_udp_checksum; -wire [63:0] output_udp_payload_tdata; -wire [7:0] output_udp_payload_tkeep; -wire output_udp_payload_tvalid; -wire output_udp_payload_tlast; -wire output_udp_payload_tuser; +wire s_ip_hdr_ready; +wire s_ip_payload_axis_tready; +wire m_udp_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [15:0] m_udp_source_port; +wire [15:0] m_udp_dest_port; +wire [15:0] m_udp_length; +wire [15:0] m_udp_checksum; +wire [63:0] m_udp_payload_axis_tdata; +wire [7:0] m_udp_payload_axis_tkeep; +wire m_udp_payload_axis_tvalid; +wire m_udp_payload_axis_tlast; +wire m_udp_payload_axis_tuser; wire busy; wire error_header_early_termination; wire error_payload_early_termination; @@ -100,60 +100,60 @@ initial begin clk, rst, current_test, - input_ip_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_length, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_ip_payload_tdata, - input_ip_payload_tkeep, - input_ip_payload_tvalid, - input_ip_payload_tlast, - input_ip_payload_tuser, - output_udp_hdr_ready, - output_udp_payload_tready + s_ip_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_length, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_ip_payload_axis_tdata, + s_ip_payload_axis_tkeep, + s_ip_payload_axis_tvalid, + s_ip_payload_axis_tlast, + s_ip_payload_axis_tuser, + m_udp_hdr_ready, + m_udp_payload_axis_tready ); $to_myhdl( - input_ip_hdr_ready, - input_ip_payload_tready, - output_udp_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_udp_source_port, - output_udp_dest_port, - output_udp_length, - output_udp_checksum, - output_udp_payload_tdata, - output_udp_payload_tkeep, - output_udp_payload_tvalid, - output_udp_payload_tlast, - output_udp_payload_tuser, + s_ip_hdr_ready, + s_ip_payload_axis_tready, + m_udp_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_udp_source_port, + m_udp_dest_port, + m_udp_length, + m_udp_checksum, + m_udp_payload_axis_tdata, + m_udp_payload_axis_tkeep, + m_udp_payload_axis_tvalid, + m_udp_payload_axis_tlast, + m_udp_payload_axis_tuser, busy, error_header_early_termination, error_payload_early_termination @@ -169,59 +169,59 @@ UUT ( .clk(clk), .rst(rst), // IP frame input - .input_ip_hdr_valid(input_ip_hdr_valid), - .input_ip_hdr_ready(input_ip_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_length(input_ip_length), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_ip_payload_tdata(input_ip_payload_tdata), - .input_ip_payload_tkeep(input_ip_payload_tkeep), - .input_ip_payload_tvalid(input_ip_payload_tvalid), - .input_ip_payload_tready(input_ip_payload_tready), - .input_ip_payload_tlast(input_ip_payload_tlast), - .input_ip_payload_tuser(input_ip_payload_tuser), + .s_ip_hdr_valid(s_ip_hdr_valid), + .s_ip_hdr_ready(s_ip_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_length(s_ip_length), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_ip_payload_axis_tdata(s_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(s_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(s_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(s_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(s_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(s_ip_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(output_udp_hdr_valid), - .output_udp_hdr_ready(output_udp_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_udp_source_port(output_udp_source_port), - .output_udp_dest_port(output_udp_dest_port), - .output_udp_length(output_udp_length), - .output_udp_checksum(output_udp_checksum), - .output_udp_payload_tdata(output_udp_payload_tdata), - .output_udp_payload_tkeep(output_udp_payload_tkeep), - .output_udp_payload_tvalid(output_udp_payload_tvalid), - .output_udp_payload_tready(output_udp_payload_tready), - .output_udp_payload_tlast(output_udp_payload_tlast), - .output_udp_payload_tuser(output_udp_payload_tuser), + .m_udp_hdr_valid(m_udp_hdr_valid), + .m_udp_hdr_ready(m_udp_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_udp_source_port(m_udp_source_port), + .m_udp_dest_port(m_udp_dest_port), + .m_udp_length(m_udp_length), + .m_udp_checksum(m_udp_checksum), + .m_udp_payload_axis_tdata(m_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(m_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(m_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(m_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(m_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(m_udp_payload_axis_tuser), // Status signals .busy(busy), .error_header_early_termination(error_header_early_termination), diff --git a/tb/test_udp_ip_tx.py b/tb/test_udp_ip_tx.py index deb3c3a5c..2197ab41d 100755 --- a/tb/test_udp_ip_tx.py +++ b/tb/test_udp_ip_tx.py @@ -49,57 +49,57 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_udp_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_udp_source_port = Signal(intbv(0)[16:]) - input_udp_dest_port = Signal(intbv(0)[16:]) - input_udp_length = Signal(intbv(0)[16:]) - input_udp_checksum = Signal(intbv(0)[16:]) - input_udp_payload_tdata = Signal(intbv(0)[8:]) - input_udp_payload_tvalid = Signal(bool(0)) - input_udp_payload_tlast = Signal(bool(0)) - input_udp_payload_tuser = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) + s_udp_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_udp_source_port = Signal(intbv(0)[16:]) + s_udp_dest_port = Signal(intbv(0)[16:]) + s_udp_length = Signal(intbv(0)[16:]) + s_udp_checksum = Signal(intbv(0)[16:]) + s_udp_payload_axis_tdata = Signal(intbv(0)[8:]) + s_udp_payload_axis_tvalid = Signal(bool(0)) + s_udp_payload_axis_tlast = Signal(bool(0)) + s_udp_payload_axis_tuser = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) # Outputs - input_udp_hdr_ready = Signal(bool(0)) - input_udp_payload_tready = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + s_udp_hdr_ready = Signal(bool(0)) + s_udp_payload_axis_tready = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_payload_early_termination = Signal(bool(0)) @@ -112,32 +112,32 @@ def bench(): source_logic = source.create_logic( clk, rst, - udp_hdr_ready=input_udp_hdr_ready, - udp_hdr_valid=input_udp_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - udp_source_port=input_udp_source_port, - udp_dest_port=input_udp_dest_port, - udp_length=input_udp_length, - udp_checksum=input_udp_checksum, - udp_payload_tdata=input_udp_payload_tdata, - udp_payload_tvalid=input_udp_payload_tvalid, - udp_payload_tready=input_udp_payload_tready, - udp_payload_tlast=input_udp_payload_tlast, - udp_payload_tuser=input_udp_payload_tuser, + udp_hdr_ready=s_udp_hdr_ready, + udp_hdr_valid=s_udp_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + udp_source_port=s_udp_source_port, + udp_dest_port=s_udp_dest_port, + udp_length=s_udp_length, + udp_checksum=s_udp_checksum, + udp_payload_tdata=s_udp_payload_axis_tdata, + udp_payload_tvalid=s_udp_payload_axis_tvalid, + udp_payload_tready=s_udp_payload_axis_tready, + udp_payload_tlast=s_udp_payload_axis_tlast, + udp_payload_tuser=s_udp_payload_axis_tuser, pause=source_pause, name='source' ) @@ -147,29 +147,29 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -184,56 +184,56 @@ def bench(): rst=rst, current_test=current_test, - input_udp_hdr_valid=input_udp_hdr_valid, - input_udp_hdr_ready=input_udp_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_udp_source_port=input_udp_source_port, - input_udp_dest_port=input_udp_dest_port, - input_udp_length=input_udp_length, - input_udp_checksum=input_udp_checksum, - input_udp_payload_tdata=input_udp_payload_tdata, - input_udp_payload_tvalid=input_udp_payload_tvalid, - input_udp_payload_tready=input_udp_payload_tready, - input_udp_payload_tlast=input_udp_payload_tlast, - input_udp_payload_tuser=input_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, busy=busy, error_payload_early_termination=error_payload_early_termination @@ -251,11 +251,11 @@ def bench(): error_payload_early_termination_asserted.next = 1 def wait_normal(): - while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + while s_udp_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_udp_hdr_valid: yield clk.posedge def wait_pause_source(): - while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + while s_udp_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_udp_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -264,7 +264,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + while s_udp_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_udp_hdr_valid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_udp_ip_tx.v b/tb/test_udp_ip_tx.v index 5bba007e6..76cf90e39 100644 --- a/tb/test_udp_ip_tx.v +++ b/tb/test_udp_ip_tx.v @@ -36,57 +36,57 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_udp_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [15:0] input_udp_source_port = 0; -reg [15:0] input_udp_dest_port = 0; -reg [15:0] input_udp_length = 0; -reg [15:0] input_udp_checksum = 0; -reg [7:0] input_udp_payload_tdata = 0; -reg input_udp_payload_tvalid = 0; -reg input_udp_payload_tlast = 0; -reg input_udp_payload_tuser = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg s_udp_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [15:0] s_udp_source_port = 0; +reg [15:0] s_udp_dest_port = 0; +reg [15:0] s_udp_length = 0; +reg [15:0] s_udp_checksum = 0; +reg [7:0] s_udp_payload_axis_tdata = 0; +reg s_udp_payload_axis_tvalid = 0; +reg s_udp_payload_axis_tlast = 0; +reg s_udp_payload_axis_tuser = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; // Outputs -wire input_udp_hdr_ready; -wire input_udp_payload_tready; -wire output_ip_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [7:0] output_ip_payload_tdata; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire s_udp_hdr_ready; +wire s_udp_payload_axis_tready; +wire m_ip_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [7:0] m_ip_payload_axis_tdata; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; wire busy; wire error_payload_early_termination; @@ -96,57 +96,57 @@ initial begin clk, rst, current_test, - input_udp_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_udp_source_port, - input_udp_dest_port, - input_udp_length, - input_udp_checksum, - input_udp_payload_tdata, - input_udp_payload_tvalid, - input_udp_payload_tlast, - input_udp_payload_tuser, - output_ip_hdr_ready, - output_ip_payload_tready + s_udp_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready ); $to_myhdl( - input_udp_hdr_ready, - input_udp_payload_tready, - output_ip_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_ip_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, busy, error_payload_early_termination ); @@ -161,56 +161,56 @@ UUT ( .clk(clk), .rst(rst), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), - .input_udp_checksum(input_udp_checksum), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .busy(busy), .error_payload_early_termination(error_payload_early_termination) diff --git a/tb/test_udp_ip_tx_64.py b/tb/test_udp_ip_tx_64.py index 4043e589a..ee6562acf 100755 --- a/tb/test_udp_ip_tx_64.py +++ b/tb/test_udp_ip_tx_64.py @@ -49,59 +49,59 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - input_udp_hdr_valid = Signal(bool(0)) - input_eth_dest_mac = Signal(intbv(0)[48:]) - input_eth_src_mac = Signal(intbv(0)[48:]) - input_eth_type = Signal(intbv(0)[16:]) - input_ip_version = Signal(intbv(0)[4:]) - input_ip_ihl = Signal(intbv(0)[4:]) - input_ip_dscp = Signal(intbv(0)[6:]) - input_ip_ecn = Signal(intbv(0)[2:]) - input_ip_identification = Signal(intbv(0)[16:]) - input_ip_flags = Signal(intbv(0)[3:]) - input_ip_fragment_offset = Signal(intbv(0)[13:]) - input_ip_ttl = Signal(intbv(0)[8:]) - input_ip_protocol = Signal(intbv(0)[8:]) - input_ip_header_checksum = Signal(intbv(0)[16:]) - input_ip_source_ip = Signal(intbv(0)[32:]) - input_ip_dest_ip = Signal(intbv(0)[32:]) - input_udp_source_port = Signal(intbv(0)[16:]) - input_udp_dest_port = Signal(intbv(0)[16:]) - input_udp_length = Signal(intbv(0)[16:]) - input_udp_checksum = Signal(intbv(0)[16:]) - input_udp_payload_tdata = Signal(intbv(0)[64:]) - input_udp_payload_tkeep = Signal(intbv(0)[8:]) - input_udp_payload_tvalid = Signal(bool(0)) - input_udp_payload_tlast = Signal(bool(0)) - input_udp_payload_tuser = Signal(bool(0)) - output_ip_payload_tready = Signal(bool(0)) - output_ip_hdr_ready = Signal(bool(0)) + s_udp_hdr_valid = Signal(bool(0)) + s_eth_dest_mac = Signal(intbv(0)[48:]) + s_eth_src_mac = Signal(intbv(0)[48:]) + s_eth_type = Signal(intbv(0)[16:]) + s_ip_version = Signal(intbv(0)[4:]) + s_ip_ihl = Signal(intbv(0)[4:]) + s_ip_dscp = Signal(intbv(0)[6:]) + s_ip_ecn = Signal(intbv(0)[2:]) + s_ip_identification = Signal(intbv(0)[16:]) + s_ip_flags = Signal(intbv(0)[3:]) + s_ip_fragment_offset = Signal(intbv(0)[13:]) + s_ip_ttl = Signal(intbv(0)[8:]) + s_ip_protocol = Signal(intbv(0)[8:]) + s_ip_header_checksum = Signal(intbv(0)[16:]) + s_ip_source_ip = Signal(intbv(0)[32:]) + s_ip_dest_ip = Signal(intbv(0)[32:]) + s_udp_source_port = Signal(intbv(0)[16:]) + s_udp_dest_port = Signal(intbv(0)[16:]) + s_udp_length = Signal(intbv(0)[16:]) + s_udp_checksum = Signal(intbv(0)[16:]) + s_udp_payload_axis_tdata = Signal(intbv(0)[64:]) + s_udp_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_udp_payload_axis_tvalid = Signal(bool(0)) + s_udp_payload_axis_tlast = Signal(bool(0)) + s_udp_payload_axis_tuser = Signal(bool(0)) + m_ip_payload_axis_tready = Signal(bool(0)) + m_ip_hdr_ready = Signal(bool(0)) # Outputs - input_udp_hdr_ready = Signal(bool(0)) - input_udp_payload_tready = Signal(bool(0)) - output_ip_hdr_valid = Signal(bool(0)) - output_eth_dest_mac = Signal(intbv(0)[48:]) - output_eth_src_mac = Signal(intbv(0)[48:]) - output_eth_type = Signal(intbv(0)[16:]) - output_ip_version = Signal(intbv(0)[4:]) - output_ip_ihl = Signal(intbv(0)[4:]) - output_ip_dscp = Signal(intbv(0)[6:]) - output_ip_ecn = Signal(intbv(0)[2:]) - output_ip_length = Signal(intbv(0)[16:]) - output_ip_identification = Signal(intbv(0)[16:]) - output_ip_flags = Signal(intbv(0)[3:]) - output_ip_fragment_offset = Signal(intbv(0)[13:]) - output_ip_ttl = Signal(intbv(0)[8:]) - output_ip_protocol = Signal(intbv(0)[8:]) - output_ip_header_checksum = Signal(intbv(0)[16:]) - output_ip_source_ip = Signal(intbv(0)[32:]) - output_ip_dest_ip = Signal(intbv(0)[32:]) - output_ip_payload_tdata = Signal(intbv(0)[64:]) - output_ip_payload_tkeep = Signal(intbv(0)[8:]) - output_ip_payload_tvalid = Signal(bool(0)) - output_ip_payload_tlast = Signal(bool(0)) - output_ip_payload_tuser = Signal(bool(0)) + s_udp_hdr_ready = Signal(bool(0)) + s_udp_payload_axis_tready = Signal(bool(0)) + m_ip_hdr_valid = Signal(bool(0)) + m_eth_dest_mac = Signal(intbv(0)[48:]) + m_eth_src_mac = Signal(intbv(0)[48:]) + m_eth_type = Signal(intbv(0)[16:]) + m_ip_version = Signal(intbv(0)[4:]) + m_ip_ihl = Signal(intbv(0)[4:]) + m_ip_dscp = Signal(intbv(0)[6:]) + m_ip_ecn = Signal(intbv(0)[2:]) + m_ip_length = Signal(intbv(0)[16:]) + m_ip_identification = Signal(intbv(0)[16:]) + m_ip_flags = Signal(intbv(0)[3:]) + m_ip_fragment_offset = Signal(intbv(0)[13:]) + m_ip_ttl = Signal(intbv(0)[8:]) + m_ip_protocol = Signal(intbv(0)[8:]) + m_ip_header_checksum = Signal(intbv(0)[16:]) + m_ip_source_ip = Signal(intbv(0)[32:]) + m_ip_dest_ip = Signal(intbv(0)[32:]) + m_ip_payload_axis_tdata = Signal(intbv(0)[64:]) + m_ip_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_ip_payload_axis_tvalid = Signal(bool(0)) + m_ip_payload_axis_tlast = Signal(bool(0)) + m_ip_payload_axis_tuser = Signal(bool(0)) busy = Signal(bool(0)) error_payload_early_termination = Signal(bool(0)) @@ -114,33 +114,33 @@ def bench(): source_logic = source.create_logic( clk, rst, - udp_hdr_ready=input_udp_hdr_ready, - udp_hdr_valid=input_udp_hdr_valid, - eth_dest_mac=input_eth_dest_mac, - eth_src_mac=input_eth_src_mac, - eth_type=input_eth_type, - ip_version=input_ip_version, - ip_ihl=input_ip_ihl, - ip_dscp=input_ip_dscp, - ip_ecn=input_ip_ecn, - ip_identification=input_ip_identification, - ip_flags=input_ip_flags, - ip_fragment_offset=input_ip_fragment_offset, - ip_ttl=input_ip_ttl, - ip_protocol=input_ip_protocol, - ip_header_checksum=input_ip_header_checksum, - ip_source_ip=input_ip_source_ip, - ip_dest_ip=input_ip_dest_ip, - udp_source_port=input_udp_source_port, - udp_dest_port=input_udp_dest_port, - udp_length=input_udp_length, - udp_checksum=input_udp_checksum, - udp_payload_tdata=input_udp_payload_tdata, - udp_payload_tkeep=input_udp_payload_tkeep, - udp_payload_tvalid=input_udp_payload_tvalid, - udp_payload_tready=input_udp_payload_tready, - udp_payload_tlast=input_udp_payload_tlast, - udp_payload_tuser=input_udp_payload_tuser, + udp_hdr_ready=s_udp_hdr_ready, + udp_hdr_valid=s_udp_hdr_valid, + eth_dest_mac=s_eth_dest_mac, + eth_src_mac=s_eth_src_mac, + eth_type=s_eth_type, + ip_version=s_ip_version, + ip_ihl=s_ip_ihl, + ip_dscp=s_ip_dscp, + ip_ecn=s_ip_ecn, + ip_identification=s_ip_identification, + ip_flags=s_ip_flags, + ip_fragment_offset=s_ip_fragment_offset, + ip_ttl=s_ip_ttl, + ip_protocol=s_ip_protocol, + ip_header_checksum=s_ip_header_checksum, + ip_source_ip=s_ip_source_ip, + ip_dest_ip=s_ip_dest_ip, + udp_source_port=s_udp_source_port, + udp_dest_port=s_udp_dest_port, + udp_length=s_udp_length, + udp_checksum=s_udp_checksum, + udp_payload_tdata=s_udp_payload_axis_tdata, + udp_payload_tkeep=s_udp_payload_axis_tkeep, + udp_payload_tvalid=s_udp_payload_axis_tvalid, + udp_payload_tready=s_udp_payload_axis_tready, + udp_payload_tlast=s_udp_payload_axis_tlast, + udp_payload_tuser=s_udp_payload_axis_tuser, pause=source_pause, name='source' ) @@ -150,30 +150,30 @@ def bench(): sink_logic = sink.create_logic( clk, rst, - ip_hdr_ready=output_ip_hdr_ready, - ip_hdr_valid=output_ip_hdr_valid, - eth_dest_mac=output_eth_dest_mac, - eth_src_mac=output_eth_src_mac, - eth_type=output_eth_type, - ip_version=output_ip_version, - ip_ihl=output_ip_ihl, - ip_dscp=output_ip_dscp, - ip_ecn=output_ip_ecn, - ip_length=output_ip_length, - ip_identification=output_ip_identification, - ip_flags=output_ip_flags, - ip_fragment_offset=output_ip_fragment_offset, - ip_ttl=output_ip_ttl, - ip_protocol=output_ip_protocol, - ip_header_checksum=output_ip_header_checksum, - ip_source_ip=output_ip_source_ip, - ip_dest_ip=output_ip_dest_ip, - ip_payload_tdata=output_ip_payload_tdata, - ip_payload_tkeep=output_ip_payload_tkeep, - ip_payload_tvalid=output_ip_payload_tvalid, - ip_payload_tready=output_ip_payload_tready, - ip_payload_tlast=output_ip_payload_tlast, - ip_payload_tuser=output_ip_payload_tuser, + ip_hdr_ready=m_ip_hdr_ready, + ip_hdr_valid=m_ip_hdr_valid, + eth_dest_mac=m_eth_dest_mac, + eth_src_mac=m_eth_src_mac, + eth_type=m_eth_type, + ip_version=m_ip_version, + ip_ihl=m_ip_ihl, + ip_dscp=m_ip_dscp, + ip_ecn=m_ip_ecn, + ip_length=m_ip_length, + ip_identification=m_ip_identification, + ip_flags=m_ip_flags, + ip_fragment_offset=m_ip_fragment_offset, + ip_ttl=m_ip_ttl, + ip_protocol=m_ip_protocol, + ip_header_checksum=m_ip_header_checksum, + ip_source_ip=m_ip_source_ip, + ip_dest_ip=m_ip_dest_ip, + ip_payload_tdata=m_ip_payload_axis_tdata, + ip_payload_tkeep=m_ip_payload_axis_tkeep, + ip_payload_tvalid=m_ip_payload_axis_tvalid, + ip_payload_tready=m_ip_payload_axis_tready, + ip_payload_tlast=m_ip_payload_axis_tlast, + ip_payload_tuser=m_ip_payload_axis_tuser, pause=sink_pause, name='sink' ) @@ -188,58 +188,58 @@ def bench(): rst=rst, current_test=current_test, - input_udp_hdr_valid=input_udp_hdr_valid, - input_udp_hdr_ready=input_udp_hdr_ready, - input_eth_dest_mac=input_eth_dest_mac, - input_eth_src_mac=input_eth_src_mac, - input_eth_type=input_eth_type, - input_ip_version=input_ip_version, - input_ip_ihl=input_ip_ihl, - input_ip_dscp=input_ip_dscp, - input_ip_ecn=input_ip_ecn, - input_ip_identification=input_ip_identification, - input_ip_flags=input_ip_flags, - input_ip_fragment_offset=input_ip_fragment_offset, - input_ip_ttl=input_ip_ttl, - input_ip_protocol=input_ip_protocol, - input_ip_header_checksum=input_ip_header_checksum, - input_ip_source_ip=input_ip_source_ip, - input_ip_dest_ip=input_ip_dest_ip, - input_udp_source_port=input_udp_source_port, - input_udp_dest_port=input_udp_dest_port, - input_udp_length=input_udp_length, - input_udp_checksum=input_udp_checksum, - input_udp_payload_tdata=input_udp_payload_tdata, - input_udp_payload_tkeep=input_udp_payload_tkeep, - input_udp_payload_tvalid=input_udp_payload_tvalid, - input_udp_payload_tready=input_udp_payload_tready, - input_udp_payload_tlast=input_udp_payload_tlast, - input_udp_payload_tuser=input_udp_payload_tuser, + s_udp_hdr_valid=s_udp_hdr_valid, + s_udp_hdr_ready=s_udp_hdr_ready, + s_eth_dest_mac=s_eth_dest_mac, + s_eth_src_mac=s_eth_src_mac, + s_eth_type=s_eth_type, + s_ip_version=s_ip_version, + s_ip_ihl=s_ip_ihl, + s_ip_dscp=s_ip_dscp, + s_ip_ecn=s_ip_ecn, + s_ip_identification=s_ip_identification, + s_ip_flags=s_ip_flags, + s_ip_fragment_offset=s_ip_fragment_offset, + s_ip_ttl=s_ip_ttl, + s_ip_protocol=s_ip_protocol, + s_ip_header_checksum=s_ip_header_checksum, + s_ip_source_ip=s_ip_source_ip, + s_ip_dest_ip=s_ip_dest_ip, + s_udp_source_port=s_udp_source_port, + s_udp_dest_port=s_udp_dest_port, + s_udp_length=s_udp_length, + s_udp_checksum=s_udp_checksum, + s_udp_payload_axis_tdata=s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep=s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid=s_udp_payload_axis_tvalid, + s_udp_payload_axis_tready=s_udp_payload_axis_tready, + s_udp_payload_axis_tlast=s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser=s_udp_payload_axis_tuser, - output_ip_hdr_valid=output_ip_hdr_valid, - output_ip_hdr_ready=output_ip_hdr_ready, - output_eth_dest_mac=output_eth_dest_mac, - output_eth_src_mac=output_eth_src_mac, - output_eth_type=output_eth_type, - output_ip_version=output_ip_version, - output_ip_ihl=output_ip_ihl, - output_ip_dscp=output_ip_dscp, - output_ip_ecn=output_ip_ecn, - output_ip_length=output_ip_length, - output_ip_identification=output_ip_identification, - output_ip_flags=output_ip_flags, - output_ip_fragment_offset=output_ip_fragment_offset, - output_ip_ttl=output_ip_ttl, - output_ip_protocol=output_ip_protocol, - output_ip_header_checksum=output_ip_header_checksum, - output_ip_source_ip=output_ip_source_ip, - output_ip_dest_ip=output_ip_dest_ip, - output_ip_payload_tdata=output_ip_payload_tdata, - output_ip_payload_tkeep=output_ip_payload_tkeep, - output_ip_payload_tvalid=output_ip_payload_tvalid, - output_ip_payload_tready=output_ip_payload_tready, - output_ip_payload_tlast=output_ip_payload_tlast, - output_ip_payload_tuser=output_ip_payload_tuser, + m_ip_hdr_valid=m_ip_hdr_valid, + m_ip_hdr_ready=m_ip_hdr_ready, + m_eth_dest_mac=m_eth_dest_mac, + m_eth_src_mac=m_eth_src_mac, + m_eth_type=m_eth_type, + m_ip_version=m_ip_version, + m_ip_ihl=m_ip_ihl, + m_ip_dscp=m_ip_dscp, + m_ip_ecn=m_ip_ecn, + m_ip_length=m_ip_length, + m_ip_identification=m_ip_identification, + m_ip_flags=m_ip_flags, + m_ip_fragment_offset=m_ip_fragment_offset, + m_ip_ttl=m_ip_ttl, + m_ip_protocol=m_ip_protocol, + m_ip_header_checksum=m_ip_header_checksum, + m_ip_source_ip=m_ip_source_ip, + m_ip_dest_ip=m_ip_dest_ip, + m_ip_payload_axis_tdata=m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep=m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid=m_ip_payload_axis_tvalid, + m_ip_payload_axis_tready=m_ip_payload_axis_tready, + m_ip_payload_axis_tlast=m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser=m_ip_payload_axis_tuser, busy=busy, error_payload_early_termination=error_payload_early_termination @@ -257,11 +257,11 @@ def bench(): error_payload_early_termination_asserted.next = 1 def wait_normal(): - while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + while s_udp_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_udp_hdr_valid: yield clk.posedge def wait_pause_source(): - while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + while s_udp_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_udp_hdr_valid: source_pause.next = True yield clk.posedge yield clk.posedge @@ -270,7 +270,7 @@ def bench(): yield clk.posedge def wait_pause_sink(): - while input_udp_payload_tvalid or output_ip_payload_tvalid or input_udp_hdr_valid: + while s_udp_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_udp_hdr_valid: sink_pause.next = True yield clk.posedge yield clk.posedge diff --git a/tb/test_udp_ip_tx_64.v b/tb/test_udp_ip_tx_64.v index 398da6bdd..5f475b425 100644 --- a/tb/test_udp_ip_tx_64.v +++ b/tb/test_udp_ip_tx_64.v @@ -36,59 +36,59 @@ reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg input_udp_hdr_valid = 0; -reg [47:0] input_eth_dest_mac = 0; -reg [47:0] input_eth_src_mac = 0; -reg [15:0] input_eth_type = 0; -reg [3:0] input_ip_version = 0; -reg [3:0] input_ip_ihl = 0; -reg [5:0] input_ip_dscp = 0; -reg [1:0] input_ip_ecn = 0; -reg [15:0] input_ip_identification = 0; -reg [2:0] input_ip_flags = 0; -reg [12:0] input_ip_fragment_offset = 0; -reg [7:0] input_ip_ttl = 0; -reg [7:0] input_ip_protocol = 0; -reg [15:0] input_ip_header_checksum = 0; -reg [31:0] input_ip_source_ip = 0; -reg [31:0] input_ip_dest_ip = 0; -reg [15:0] input_udp_source_port = 0; -reg [15:0] input_udp_dest_port = 0; -reg [15:0] input_udp_length = 0; -reg [15:0] input_udp_checksum = 0; -reg [63:0] input_udp_payload_tdata = 0; -reg [7:0] input_udp_payload_tkeep = 0; -reg input_udp_payload_tvalid = 0; -reg input_udp_payload_tlast = 0; -reg input_udp_payload_tuser = 0; -reg output_ip_hdr_ready = 0; -reg output_ip_payload_tready = 0; +reg s_udp_hdr_valid = 0; +reg [47:0] s_eth_dest_mac = 0; +reg [47:0] s_eth_src_mac = 0; +reg [15:0] s_eth_type = 0; +reg [3:0] s_ip_version = 0; +reg [3:0] s_ip_ihl = 0; +reg [5:0] s_ip_dscp = 0; +reg [1:0] s_ip_ecn = 0; +reg [15:0] s_ip_identification = 0; +reg [2:0] s_ip_flags = 0; +reg [12:0] s_ip_fragment_offset = 0; +reg [7:0] s_ip_ttl = 0; +reg [7:0] s_ip_protocol = 0; +reg [15:0] s_ip_header_checksum = 0; +reg [31:0] s_ip_source_ip = 0; +reg [31:0] s_ip_dest_ip = 0; +reg [15:0] s_udp_source_port = 0; +reg [15:0] s_udp_dest_port = 0; +reg [15:0] s_udp_length = 0; +reg [15:0] s_udp_checksum = 0; +reg [63:0] s_udp_payload_axis_tdata = 0; +reg [7:0] s_udp_payload_axis_tkeep = 0; +reg s_udp_payload_axis_tvalid = 0; +reg s_udp_payload_axis_tlast = 0; +reg s_udp_payload_axis_tuser = 0; +reg m_ip_hdr_ready = 0; +reg m_ip_payload_axis_tready = 0; // Outputs -wire input_udp_hdr_ready; -wire input_udp_payload_tready; -wire output_ip_hdr_valid; -wire [47:0] output_eth_dest_mac; -wire [47:0] output_eth_src_mac; -wire [15:0] output_eth_type; -wire [3:0] output_ip_version; -wire [3:0] output_ip_ihl; -wire [5:0] output_ip_dscp; -wire [1:0] output_ip_ecn; -wire [15:0] output_ip_length; -wire [15:0] output_ip_identification; -wire [2:0] output_ip_flags; -wire [12:0] output_ip_fragment_offset; -wire [7:0] output_ip_ttl; -wire [7:0] output_ip_protocol; -wire [15:0] output_ip_header_checksum; -wire [31:0] output_ip_source_ip; -wire [31:0] output_ip_dest_ip; -wire [63:0] output_ip_payload_tdata; -wire [7:0] output_ip_payload_tkeep; -wire output_ip_payload_tvalid; -wire output_ip_payload_tlast; -wire output_ip_payload_tuser; +wire s_udp_hdr_ready; +wire s_udp_payload_axis_tready; +wire m_ip_hdr_valid; +wire [47:0] m_eth_dest_mac; +wire [47:0] m_eth_src_mac; +wire [15:0] m_eth_type; +wire [3:0] m_ip_version; +wire [3:0] m_ip_ihl; +wire [5:0] m_ip_dscp; +wire [1:0] m_ip_ecn; +wire [15:0] m_ip_length; +wire [15:0] m_ip_identification; +wire [2:0] m_ip_flags; +wire [12:0] m_ip_fragment_offset; +wire [7:0] m_ip_ttl; +wire [7:0] m_ip_protocol; +wire [15:0] m_ip_header_checksum; +wire [31:0] m_ip_source_ip; +wire [31:0] m_ip_dest_ip; +wire [63:0] m_ip_payload_axis_tdata; +wire [7:0] m_ip_payload_axis_tkeep; +wire m_ip_payload_axis_tvalid; +wire m_ip_payload_axis_tlast; +wire m_ip_payload_axis_tuser; wire busy; wire error_payload_early_termination; @@ -98,59 +98,59 @@ initial begin clk, rst, current_test, - input_udp_hdr_valid, - input_eth_dest_mac, - input_eth_src_mac, - input_eth_type, - input_ip_version, - input_ip_ihl, - input_ip_dscp, - input_ip_ecn, - input_ip_identification, - input_ip_flags, - input_ip_fragment_offset, - input_ip_ttl, - input_ip_protocol, - input_ip_header_checksum, - input_ip_source_ip, - input_ip_dest_ip, - input_udp_source_port, - input_udp_dest_port, - input_udp_length, - input_udp_checksum, - input_udp_payload_tdata, - input_udp_payload_tkeep, - input_udp_payload_tvalid, - input_udp_payload_tlast, - input_udp_payload_tuser, - output_ip_hdr_ready, - output_ip_payload_tready + s_udp_hdr_valid, + s_eth_dest_mac, + s_eth_src_mac, + s_eth_type, + s_ip_version, + s_ip_ihl, + s_ip_dscp, + s_ip_ecn, + s_ip_identification, + s_ip_flags, + s_ip_fragment_offset, + s_ip_ttl, + s_ip_protocol, + s_ip_header_checksum, + s_ip_source_ip, + s_ip_dest_ip, + s_udp_source_port, + s_udp_dest_port, + s_udp_length, + s_udp_checksum, + s_udp_payload_axis_tdata, + s_udp_payload_axis_tkeep, + s_udp_payload_axis_tvalid, + s_udp_payload_axis_tlast, + s_udp_payload_axis_tuser, + m_ip_hdr_ready, + m_ip_payload_axis_tready ); $to_myhdl( - input_udp_hdr_ready, - input_udp_payload_tready, - output_ip_hdr_valid, - output_eth_dest_mac, - output_eth_src_mac, - output_eth_type, - output_ip_version, - output_ip_ihl, - output_ip_dscp, - output_ip_ecn, - output_ip_length, - output_ip_identification, - output_ip_flags, - output_ip_fragment_offset, - output_ip_ttl, - output_ip_protocol, - output_ip_header_checksum, - output_ip_source_ip, - output_ip_dest_ip, - output_ip_payload_tdata, - output_ip_payload_tkeep, - output_ip_payload_tvalid, - output_ip_payload_tlast, - output_ip_payload_tuser, + s_udp_hdr_ready, + s_udp_payload_axis_tready, + m_ip_hdr_valid, + m_eth_dest_mac, + m_eth_src_mac, + m_eth_type, + m_ip_version, + m_ip_ihl, + m_ip_dscp, + m_ip_ecn, + m_ip_length, + m_ip_identification, + m_ip_flags, + m_ip_fragment_offset, + m_ip_ttl, + m_ip_protocol, + m_ip_header_checksum, + m_ip_source_ip, + m_ip_dest_ip, + m_ip_payload_axis_tdata, + m_ip_payload_axis_tkeep, + m_ip_payload_axis_tvalid, + m_ip_payload_axis_tlast, + m_ip_payload_axis_tuser, busy, error_payload_early_termination ); @@ -165,58 +165,58 @@ UUT ( .clk(clk), .rst(rst), // UDP frame input - .input_udp_hdr_valid(input_udp_hdr_valid), - .input_udp_hdr_ready(input_udp_hdr_ready), - .input_eth_dest_mac(input_eth_dest_mac), - .input_eth_src_mac(input_eth_src_mac), - .input_eth_type(input_eth_type), - .input_ip_version(input_ip_version), - .input_ip_ihl(input_ip_ihl), - .input_ip_dscp(input_ip_dscp), - .input_ip_ecn(input_ip_ecn), - .input_ip_identification(input_ip_identification), - .input_ip_flags(input_ip_flags), - .input_ip_fragment_offset(input_ip_fragment_offset), - .input_ip_ttl(input_ip_ttl), - .input_ip_protocol(input_ip_protocol), - .input_ip_header_checksum(input_ip_header_checksum), - .input_ip_source_ip(input_ip_source_ip), - .input_ip_dest_ip(input_ip_dest_ip), - .input_udp_source_port(input_udp_source_port), - .input_udp_dest_port(input_udp_dest_port), - .input_udp_length(input_udp_length), - .input_udp_checksum(input_udp_checksum), - .input_udp_payload_tdata(input_udp_payload_tdata), - .input_udp_payload_tkeep(input_udp_payload_tkeep), - .input_udp_payload_tvalid(input_udp_payload_tvalid), - .input_udp_payload_tready(input_udp_payload_tready), - .input_udp_payload_tlast(input_udp_payload_tlast), - .input_udp_payload_tuser(input_udp_payload_tuser), + .s_udp_hdr_valid(s_udp_hdr_valid), + .s_udp_hdr_ready(s_udp_hdr_ready), + .s_eth_dest_mac(s_eth_dest_mac), + .s_eth_src_mac(s_eth_src_mac), + .s_eth_type(s_eth_type), + .s_ip_version(s_ip_version), + .s_ip_ihl(s_ip_ihl), + .s_ip_dscp(s_ip_dscp), + .s_ip_ecn(s_ip_ecn), + .s_ip_identification(s_ip_identification), + .s_ip_flags(s_ip_flags), + .s_ip_fragment_offset(s_ip_fragment_offset), + .s_ip_ttl(s_ip_ttl), + .s_ip_protocol(s_ip_protocol), + .s_ip_header_checksum(s_ip_header_checksum), + .s_ip_source_ip(s_ip_source_ip), + .s_ip_dest_ip(s_ip_dest_ip), + .s_udp_source_port(s_udp_source_port), + .s_udp_dest_port(s_udp_dest_port), + .s_udp_length(s_udp_length), + .s_udp_checksum(s_udp_checksum), + .s_udp_payload_axis_tdata(s_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(s_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(s_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(s_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(s_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(s_udp_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(output_ip_hdr_valid), - .output_ip_hdr_ready(output_ip_hdr_ready), - .output_eth_dest_mac(output_eth_dest_mac), - .output_eth_src_mac(output_eth_src_mac), - .output_eth_type(output_eth_type), - .output_ip_version(output_ip_version), - .output_ip_ihl(output_ip_ihl), - .output_ip_dscp(output_ip_dscp), - .output_ip_ecn(output_ip_ecn), - .output_ip_length(output_ip_length), - .output_ip_identification(output_ip_identification), - .output_ip_flags(output_ip_flags), - .output_ip_fragment_offset(output_ip_fragment_offset), - .output_ip_ttl(output_ip_ttl), - .output_ip_protocol(output_ip_protocol), - .output_ip_header_checksum(output_ip_header_checksum), - .output_ip_source_ip(output_ip_source_ip), - .output_ip_dest_ip(output_ip_dest_ip), - .output_ip_payload_tdata(output_ip_payload_tdata), - .output_ip_payload_tkeep(output_ip_payload_tkeep), - .output_ip_payload_tvalid(output_ip_payload_tvalid), - .output_ip_payload_tready(output_ip_payload_tready), - .output_ip_payload_tlast(output_ip_payload_tlast), - .output_ip_payload_tuser(output_ip_payload_tuser), + .m_ip_hdr_valid(m_ip_hdr_valid), + .m_ip_hdr_ready(m_ip_hdr_ready), + .m_eth_dest_mac(m_eth_dest_mac), + .m_eth_src_mac(m_eth_src_mac), + .m_eth_type(m_eth_type), + .m_ip_version(m_ip_version), + .m_ip_ihl(m_ip_ihl), + .m_ip_dscp(m_ip_dscp), + .m_ip_ecn(m_ip_ecn), + .m_ip_length(m_ip_length), + .m_ip_identification(m_ip_identification), + .m_ip_flags(m_ip_flags), + .m_ip_fragment_offset(m_ip_fragment_offset), + .m_ip_ttl(m_ip_ttl), + .m_ip_protocol(m_ip_protocol), + .m_ip_header_checksum(m_ip_header_checksum), + .m_ip_source_ip(m_ip_source_ip), + .m_ip_dest_ip(m_ip_dest_ip), + .m_ip_payload_axis_tdata(m_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(m_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(m_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(m_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(m_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(m_ip_payload_axis_tuser), // Status signals .busy(busy), .error_payload_early_termination(error_payload_early_termination) From b223c94adbb9302e262faa7060040d7ab977ab0c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 7 Nov 2018 23:08:40 -0800 Subject: [PATCH 469/617] Use registered header --- rtl/arp_eth_tx.v | 1 + rtl/arp_eth_tx_64.v | 12 ++++++------ rtl/eth_axis_tx_64.v | 16 ++++++++-------- rtl/ip_eth_tx_64.v | 14 +++++++------- rtl/udp_ip_tx.v | 2 +- rtl/udp_ip_tx_64.v | 16 ++++++++-------- 6 files changed, 31 insertions(+), 30 deletions(-) diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index 08a909980..b79681d82 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -182,6 +182,7 @@ always @* begin m_eth_payload_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) + 8'h00: m_eth_payload_axis_tdata_int = arp_htype_reg[15: 8]; 8'h01: m_eth_payload_axis_tdata_int = arp_htype_reg[ 7: 0]; 8'h02: m_eth_payload_axis_tdata_int = arp_ptype_reg[15: 8]; 8'h03: m_eth_payload_axis_tdata_int = arp_ptype_reg[ 7: 0]; diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index b32e46286..5f193d8bd 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -194,14 +194,14 @@ always @* begin state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: begin - m_eth_payload_axis_tdata_int[ 7: 0] = s_arp_htype[15: 8]; - m_eth_payload_axis_tdata_int[15: 8] = s_arp_htype[ 7: 0]; - m_eth_payload_axis_tdata_int[23:16] = s_arp_ptype[15: 8]; - m_eth_payload_axis_tdata_int[31:24] = s_arp_ptype[ 7: 0]; + m_eth_payload_axis_tdata_int[ 7: 0] = arp_htype_reg[15: 8]; + m_eth_payload_axis_tdata_int[15: 8] = arp_htype_reg[ 7: 0]; + m_eth_payload_axis_tdata_int[23:16] = arp_ptype_reg[15: 8]; + m_eth_payload_axis_tdata_int[31:24] = arp_ptype_reg[ 7: 0]; m_eth_payload_axis_tdata_int[39:32] = 8'd6; // hlen m_eth_payload_axis_tdata_int[47:40] = 8'd4; // plen - m_eth_payload_axis_tdata_int[55:48] = s_arp_oper[15: 8]; - m_eth_payload_axis_tdata_int[63:56] = s_arp_oper[ 7: 0]; + m_eth_payload_axis_tdata_int[55:48] = arp_oper_reg[15: 8]; + m_eth_payload_axis_tdata_int[63:56] = arp_oper_reg[ 7: 0]; m_eth_payload_axis_tkeep_int = 8'hff; end 8'h08: begin diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index c9abf9a00..cae7dd473 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -211,14 +211,14 @@ always @* begin state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 5'd00: begin - m_axis_tdata_int[ 7: 0] = s_eth_dest_mac[47:40]; - m_axis_tdata_int[15: 8] = s_eth_dest_mac[39:32]; - m_axis_tdata_int[23:16] = s_eth_dest_mac[31:24]; - m_axis_tdata_int[31:24] = s_eth_dest_mac[23:16]; - m_axis_tdata_int[39:32] = s_eth_dest_mac[15: 8]; - m_axis_tdata_int[47:40] = s_eth_dest_mac[ 7: 0]; - m_axis_tdata_int[55:48] = s_eth_src_mac[47:40]; - m_axis_tdata_int[63:56] = s_eth_src_mac[39:32]; + m_axis_tdata_int[ 7: 0] = eth_dest_mac_reg[47:40]; + m_axis_tdata_int[15: 8] = eth_dest_mac_reg[39:32]; + m_axis_tdata_int[23:16] = eth_dest_mac_reg[31:24]; + m_axis_tdata_int[31:24] = eth_dest_mac_reg[23:16]; + m_axis_tdata_int[39:32] = eth_dest_mac_reg[15: 8]; + m_axis_tdata_int[47:40] = eth_dest_mac_reg[ 7: 0]; + m_axis_tdata_int[55:48] = eth_src_mac_reg[47:40]; + m_axis_tdata_int[63:56] = eth_src_mac_reg[39:32]; m_axis_tkeep_int = 8'hff; s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_s_tready; state_next = STATE_WRITE_HEADER_LAST; diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index fae946d03..cd16ec7d2 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -319,13 +319,13 @@ always @* begin case (frame_ptr_reg) 8'h00: begin m_eth_payload_axis_tdata_int[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl - m_eth_payload_axis_tdata_int[15: 8] = {s_ip_dscp, s_ip_ecn}; - m_eth_payload_axis_tdata_int[23:16] = s_ip_length[15: 8]; - m_eth_payload_axis_tdata_int[31:24] = s_ip_length[ 7: 0]; - m_eth_payload_axis_tdata_int[39:32] = s_ip_identification[15: 8]; - m_eth_payload_axis_tdata_int[47:40] = s_ip_identification[ 7: 0]; - m_eth_payload_axis_tdata_int[55:48] = {s_ip_flags, s_ip_fragment_offset[12: 8]}; - m_eth_payload_axis_tdata_int[63:56] = s_ip_fragment_offset[ 7: 0]; + m_eth_payload_axis_tdata_int[15: 8] = {ip_dscp_reg, ip_ecn_reg}; + m_eth_payload_axis_tdata_int[23:16] = ip_length_reg[15: 8]; + m_eth_payload_axis_tdata_int[31:24] = ip_length_reg[ 7: 0]; + m_eth_payload_axis_tdata_int[39:32] = ip_identification_reg[15: 8]; + m_eth_payload_axis_tdata_int[47:40] = ip_identification_reg[ 7: 0]; + m_eth_payload_axis_tdata_int[55:48] = {ip_flags_reg, ip_fragment_offset_reg[12: 8]}; + m_eth_payload_axis_tdata_int[63:56] = ip_fragment_offset_reg[ 7: 0]; m_eth_payload_axis_tkeep_int = 8'hff; end 8'h08: begin diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index 469becb68..60de26cdc 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -261,7 +261,7 @@ always @* begin m_ip_payload_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) - 8'h00: m_ip_payload_axis_tdata_int = s_udp_source_port[15: 8]; + 8'h00: m_ip_payload_axis_tdata_int = udp_source_port_reg[15: 8]; 8'h01: m_ip_payload_axis_tdata_int = udp_source_port_reg[ 7: 0]; 8'h02: m_ip_payload_axis_tdata_int = udp_dest_port_reg[15: 8]; 8'h03: m_ip_payload_axis_tdata_int = udp_dest_port_reg[ 7: 0]; diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index daa9579de..3ba7bfb08 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -307,14 +307,14 @@ always @* begin state_next = STATE_WRITE_HEADER; case (frame_ptr_reg) 8'h00: begin - m_ip_payload_axis_tdata_int[ 7: 0] = s_udp_source_port[15: 8]; - m_ip_payload_axis_tdata_int[15: 8] = s_udp_source_port[ 7: 0]; - m_ip_payload_axis_tdata_int[23:16] = s_udp_dest_port[15: 8]; - m_ip_payload_axis_tdata_int[31:24] = s_udp_dest_port[ 7: 0]; - m_ip_payload_axis_tdata_int[39:32] = s_udp_length[15: 8]; - m_ip_payload_axis_tdata_int[47:40] = s_udp_length[ 7: 0]; - m_ip_payload_axis_tdata_int[55:48] = s_udp_checksum[15: 8]; - m_ip_payload_axis_tdata_int[63:56] = s_udp_checksum[ 7: 0]; + m_ip_payload_axis_tdata_int[ 7: 0] = udp_source_port_reg[15: 8]; + m_ip_payload_axis_tdata_int[15: 8] = udp_source_port_reg[ 7: 0]; + m_ip_payload_axis_tdata_int[23:16] = udp_dest_port_reg[15: 8]; + m_ip_payload_axis_tdata_int[31:24] = udp_dest_port_reg[ 7: 0]; + m_ip_payload_axis_tdata_int[39:32] = udp_length_reg[15: 8]; + m_ip_payload_axis_tdata_int[47:40] = udp_length_reg[ 7: 0]; + m_ip_payload_axis_tdata_int[55:48] = udp_checksum_reg[15: 8]; + m_ip_payload_axis_tdata_int[63:56] = udp_checksum_reg[ 7: 0]; m_ip_payload_axis_tkeep_int = 8'hff; s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; state_next = STATE_WRITE_PAYLOAD; From 6b1b36ded6c14ae428f79ba8b2073ee04b757dd2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 7 Nov 2018 23:10:07 -0800 Subject: [PATCH 470/617] Assert header ready earlier if possible --- rtl/arp_eth_rx.v | 6 +++--- rtl/arp_eth_rx_64.v | 6 +++--- rtl/arp_eth_tx.v | 4 ++-- rtl/arp_eth_tx_64.v | 4 ++-- rtl/ip_eth_rx.v | 10 +++++----- rtl/ip_eth_rx_64.v | 8 ++++---- rtl/ip_eth_tx.v | 8 ++++---- rtl/ip_eth_tx_64.v | 12 ++++++------ rtl/udp_ip_rx.v | 10 +++++----- rtl/udp_ip_rx_64.v | 12 ++++++------ rtl/udp_ip_tx.v | 8 ++++---- rtl/udp_ip_tx_64.v | 10 +++++----- 12 files changed, 49 insertions(+), 49 deletions(-) diff --git a/rtl/arp_eth_rx.v b/rtl/arp_eth_rx.v index 5a81690ba..381098e87 100644 --- a/rtl/arp_eth_rx.v +++ b/rtl/arp_eth_rx.v @@ -227,7 +227,7 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; - s_eth_hdr_ready_next = !m_frame_valid_reg; + s_eth_hdr_ready_next = !m_frame_valid_next; if (s_eth_hdr_ready && s_eth_hdr_valid) begin s_eth_hdr_ready_next = 1'b0; @@ -291,7 +291,7 @@ always @* begin // otherwise, transfer tuser m_frame_valid_next = !s_eth_payload_axis_tuser; end - s_eth_hdr_ready_next = !m_frame_valid_reg; + s_eth_hdr_ready_next = !m_frame_valid_next; s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -312,7 +312,7 @@ always @* begin // otherwise, transfer tuser m_frame_valid_next = !s_eth_payload_axis_tuser; end - s_eth_hdr_ready_next = !m_frame_valid_reg; + s_eth_hdr_ready_next = !m_frame_valid_next; s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin diff --git a/rtl/arp_eth_rx_64.v b/rtl/arp_eth_rx_64.v index 61b24fab8..4568349aa 100644 --- a/rtl/arp_eth_rx_64.v +++ b/rtl/arp_eth_rx_64.v @@ -180,7 +180,7 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; - s_eth_hdr_ready_next = !m_frame_valid_reg; + s_eth_hdr_ready_next = !m_frame_valid_next; if (s_eth_hdr_ready && s_eth_hdr_valid) begin s_eth_hdr_ready_next = 1'b0; @@ -216,7 +216,7 @@ always @* begin end else begin m_frame_valid_next = !s_eth_payload_axis_tuser; end - s_eth_hdr_ready_next = !m_frame_valid_reg; + s_eth_hdr_ready_next = !m_frame_valid_next; s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -237,7 +237,7 @@ always @* begin // otherwise, transfer tuser m_frame_valid_next = !s_eth_payload_axis_tuser; end - s_eth_hdr_ready_next = !m_frame_valid_reg; + s_eth_hdr_ready_next = !m_frame_valid_next; s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin diff --git a/rtl/arp_eth_tx.v b/rtl/arp_eth_tx.v index b79681d82..888f3cf62 100644 --- a/rtl/arp_eth_tx.v +++ b/rtl/arp_eth_tx.v @@ -158,7 +158,7 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; - s_frame_ready_next = !m_eth_hdr_valid_reg; + s_frame_ready_next = !m_eth_hdr_valid_next; if (s_frame_ready && s_frame_valid) begin store_frame = 1'b1; @@ -212,7 +212,7 @@ always @* begin 8'h1B: begin m_eth_payload_axis_tdata_int = arp_tpa_reg[ 7: 0]; m_eth_payload_axis_tlast_int = 1'b1; - s_frame_ready_next = !m_eth_hdr_valid_reg; + s_frame_ready_next = !m_eth_hdr_valid_next; state_next = STATE_IDLE; end endcase diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index 5f193d8bd..52a499492 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -161,7 +161,7 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 8'd0; - s_frame_ready_next = !m_eth_hdr_valid_reg; + s_frame_ready_next = !m_eth_hdr_valid_next; if (s_frame_ready && s_frame_valid) begin store_frame = 1'b1; @@ -237,7 +237,7 @@ always @* begin m_eth_payload_axis_tdata_int[63:56] = 0; m_eth_payload_axis_tkeep_int = 8'h0f; m_eth_payload_axis_tlast_int = 1'b1; - s_frame_ready_next = !m_eth_hdr_valid_reg; + s_frame_ready_next = !m_eth_hdr_valid_next; state_next = STATE_IDLE; end endcase diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index 1626f6a81..93fce01a2 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -277,7 +277,7 @@ always @* begin // idle state - wait for header frame_ptr_next = 16'd0; hdr_sum_next = 16'd0; - s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_next; if (s_eth_hdr_ready && s_eth_hdr_valid) begin s_eth_hdr_ready_next = 1'b0; @@ -342,7 +342,7 @@ always @* begin if (s_eth_payload_axis_tlast) begin error_header_early_termination_next = 1'b1; m_ip_hdr_valid_next = 1'b0; - s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_next; s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -369,7 +369,7 @@ always @* begin m_ip_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; end - s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_next; s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -396,7 +396,7 @@ always @* begin if (s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) begin if (s_eth_payload_axis_tlast) begin - s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_next; s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -412,7 +412,7 @@ always @* begin if (s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) begin if (s_eth_payload_axis_tlast) begin - s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_next; s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index ae16f5e99..e798a0d58 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -315,7 +315,7 @@ always @* begin frame_ptr_next = 16'd0; hdr_sum_next = 32'd0; flush_save = 1'b1; - s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_next; if (s_eth_hdr_ready && s_eth_hdr_valid) begin s_eth_hdr_ready_next = 1'b0; @@ -378,7 +378,7 @@ always @* begin error_invalid_header_next = 1'b0; error_invalid_checksum_next = 1'b0; m_ip_hdr_valid_next = 1'b0; - s_eth_hdr_ready_next = !m_ip_hdr_valid_reg; + s_eth_hdr_ready_next = !m_ip_hdr_valid_next; s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -472,7 +472,7 @@ always @* begin if (shift_eth_payload_axis_tlast) begin s_eth_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - s_eth_hdr_ready_next = 1'b1; + s_eth_hdr_ready_next = !m_ip_hdr_valid_next; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD_LAST; @@ -490,7 +490,7 @@ always @* begin if (shift_eth_payload_axis_tlast) begin s_eth_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - s_eth_hdr_ready_next = 1'b1; + s_eth_hdr_ready_next = !m_ip_hdr_valid_next; state_next = STATE_IDLE; end else begin state_next = STATE_WAIT_LAST; diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index d48d987c8..010eed35c 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -206,7 +206,7 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 16'd0; - s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_next; if (s_ip_hdr_ready && s_ip_hdr_valid) begin store_ip_hdr = 1'b1; @@ -305,7 +305,7 @@ always @* begin m_eth_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; end - s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -332,7 +332,7 @@ always @* begin if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin if (s_ip_payload_axis_tlast) begin - s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -348,7 +348,7 @@ always @* begin if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin if (s_ip_payload_axis_tlast) begin - s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index cd16ec7d2..c19a2f008 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -277,7 +277,7 @@ always @* begin // idle state - wait for data frame_ptr_next = 16'd0; flush_save = 1'b1; - s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_next; if (s_ip_hdr_ready && s_ip_hdr_valid) begin store_ip_hdr = 1'b1; @@ -374,7 +374,7 @@ always @* begin frame_ptr_next = ip_length_reg; m_eth_payload_axis_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); if (shift_ip_payload_axis_tlast) begin - s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -419,7 +419,7 @@ always @* begin if (shift_ip_payload_axis_tlast) begin s_ip_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_next; state_next = STATE_IDLE; end else begin store_last_word = 1'b1; @@ -433,7 +433,7 @@ always @* begin m_eth_payload_axis_tuser_int = 1'b1; s_ip_payload_axis_tready_next = 1'b0; flush_save = 1'b1; - s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_next; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -456,7 +456,7 @@ always @* begin if (m_eth_payload_axis_tready_int_reg && shift_ip_payload_axis_tvalid) begin transfer_in_save = 1'b1; if (shift_ip_payload_axis_tlast) begin - s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -473,7 +473,7 @@ always @* begin if (shift_ip_payload_axis_tvalid) begin transfer_in_save = 1'b1; if (shift_ip_payload_axis_tlast) begin - s_ip_hdr_ready_next = !m_eth_hdr_valid_reg; + s_ip_hdr_ready_next = !m_eth_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v index c3920f113..c143d4d8b 100644 --- a/rtl/udp_ip_rx.v +++ b/rtl/udp_ip_rx.v @@ -262,7 +262,7 @@ always @* begin STATE_IDLE: begin // idle state - wait for header frame_ptr_next = 16'd0; - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; if (s_ip_hdr_ready && s_ip_hdr_valid) begin s_ip_hdr_ready_next = 1'b0; @@ -301,7 +301,7 @@ always @* begin if (s_ip_payload_axis_tlast) begin error_header_early_termination_next = 1'b1; m_udp_hdr_valid_next = 1'b0; - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -328,7 +328,7 @@ always @* begin m_udp_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; end - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -355,7 +355,7 @@ always @* begin if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin if (s_ip_payload_axis_tlast) begin - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -371,7 +371,7 @@ always @* begin if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin if (s_ip_payload_axis_tlast) begin - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index a57028972..b51b64cf9 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -283,7 +283,7 @@ always @* begin STATE_IDLE: begin // idle state - wait for header frame_ptr_next = 16'd0; - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; if (s_ip_hdr_ready && s_ip_hdr_valid) begin s_ip_hdr_ready_next = 1'b0; @@ -315,7 +315,7 @@ always @* begin if (s_ip_payload_axis_tlast) begin error_header_early_termination_next = 1'b1; m_udp_hdr_valid_next = 1'b0; - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end @@ -343,7 +343,7 @@ always @* begin m_udp_payload_axis_tkeep_int = s_ip_payload_axis_tkeep & count2keep(m_udp_length_reg - frame_ptr_reg); if (s_ip_payload_axis_tlast) begin s_ip_payload_axis_tready_next = 1'b0; - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; state_next = STATE_IDLE; end else begin store_last_word = 1'b1; @@ -356,7 +356,7 @@ always @* begin error_payload_early_termination_next = 1'b1; m_udp_payload_axis_tuser_int = 1'b1; s_ip_payload_axis_tready_next = 1'b0; - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; state_next = STATE_IDLE; end else begin state_next = STATE_READ_PAYLOAD; @@ -378,7 +378,7 @@ always @* begin if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin if (s_ip_payload_axis_tlast) begin - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -394,7 +394,7 @@ always @* begin if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin if (s_ip_payload_axis_tlast) begin - s_ip_hdr_ready_next = !m_udp_hdr_valid_reg; + s_ip_hdr_ready_next = !m_udp_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index 60de26cdc..096e9444c 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -237,7 +237,7 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 16'd0; - s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_next; if (s_udp_hdr_ready && s_udp_hdr_valid) begin store_udp_hdr = 1'b1; @@ -296,7 +296,7 @@ always @* begin m_ip_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; end - s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_next; s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -323,7 +323,7 @@ always @* begin if (s_udp_payload_axis_tready && s_udp_payload_axis_tvalid) begin if (s_udp_payload_axis_tlast) begin - s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_next; s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -339,7 +339,7 @@ always @* begin if (s_udp_payload_axis_tvalid) begin if (s_udp_payload_axis_tlast) begin - s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_next; s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index 3ba7bfb08..967f0a506 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -272,7 +272,7 @@ always @* begin STATE_IDLE: begin // idle state - wait for data frame_ptr_next = 16'd0; - s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_next; if (s_udp_hdr_ready && s_udp_hdr_valid) begin store_udp_hdr = 1'b1; @@ -343,7 +343,7 @@ always @* begin m_ip_payload_axis_tkeep_int = count2keep(udp_length_reg - frame_ptr_reg); if (s_udp_payload_axis_tlast) begin s_udp_payload_axis_tready_next = 1'b0; - s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_next; state_next = STATE_IDLE; end else begin store_last_word = 1'b1; @@ -356,7 +356,7 @@ always @* begin error_payload_early_termination_next = 1'b1; m_ip_payload_axis_tuser_int = 1'b1; s_udp_payload_axis_tready_next = 1'b0; - s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_next; state_next = STATE_IDLE; end else begin state_next = STATE_WRITE_PAYLOAD; @@ -378,7 +378,7 @@ always @* begin if (s_udp_payload_axis_tready && s_udp_payload_axis_tvalid) begin if (s_udp_payload_axis_tlast) begin - s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_next; s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin @@ -394,7 +394,7 @@ always @* begin if (s_udp_payload_axis_tvalid) begin if (s_udp_payload_axis_tlast) begin - s_udp_hdr_ready_next = !m_ip_hdr_valid_reg; + s_udp_hdr_ready_next = !m_ip_hdr_valid_next; s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin From 29eccbc2902cd2d6586f45deac62924649bef963 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 7 Nov 2018 23:26:11 -0800 Subject: [PATCH 471/617] Update readme --- README.md | 189 +++++++++++++----------------------------------------- 1 file changed, 45 insertions(+), 144 deletions(-) diff --git a/README.md b/README.md index ad19f9367..5d5c60404 100644 --- a/README.md +++ b/README.md @@ -87,19 +87,10 @@ AXI stream XGMII frame transmitter with 32 bit datapath. AXI stream XGMII frame transmitter with 64 bit datapath. -### eth_arb_mux_N module +### eth_arb_mux module -Ethernet frame arbitrated muliplexer with 8 bit data width for gigabit -Ethernet. Supports priority and round-robin arbitration. - -Can be generated with arbitrary port counts with eth_arb_mux.py. - -### eth_arb_mux_64_N module - -Ethernet frame arbitrated muliplexer with 8 bit data width for 10G Ethernet. -Supports priority and round-robin arbitration. - -Can be generated with arbitrary port counts with eth_arb_mux_64.py. +Ethernet frame arbitrated muliplexer with parametrizable data width and port +count. Supports priority and round-robin arbitration. ### eth_axis_rx module @@ -117,20 +108,11 @@ Ethernet frame transmitter. Ethernet frame transmitter with 64 bit datapath for 10G Ethernet. -### eth_demux_N module +### eth_demux module -Ethernet frame demuliplexer with 8 bit data width for gigabit Ethernet. +Ethernet frame demuliplexer with parametrizable data width and port count. Supports priority and round-robin arbitration. -Can be generated with arbitrary port counts with eth_demux.py. - -### eth_demux_64_N module - -Ethernet frame demuliplexer with 64 bit data width for 10G Ethernet. Supports -priority and round-robin arbitration. - -Can be generated with arbitrary port counts with eth_demux_64.py. - ### eth_mac_1g module Gigabit Ethernet MAC with GMII interface. @@ -161,26 +143,19 @@ adaptation logic. ### eth_mac_10g module -10G Ethernet MAC with XGMII interface. +10G Ethernet MAC with XGMII interface. Datapath selectable between 32 and 64 +bits. ### eth_mac_10g_fifo module -10G Ethernet MAC with XGMII interface and FIFOs. +10G Ethernet MAC with XGMII interface and FIFOs. Datapath selectable between +32 and 64 bits. -### eth_mux_N module +### eth_mux module -Ethernet frame muliplexer with 8 bit data width for gigabit Ethernet. +Ethernet frame muliplexer with parametrizable data width and port count. Supports priority and round-robin arbitration. -Can be generated with arbitrary port counts with eth_mux.py. - -### eth_mux_64_N module - -Ethernet frame muliplexer with 64 bit data width for 10G Ethernet. Supports -priority and round-robin arbitration. - -Can be generated with arbitrary port counts with eth_mux_64.py. - ### gmii_phy_if GMII/MII PHY interface and clocking logic. @@ -195,20 +170,11 @@ transmssion and reception. Interfaces with ARP module for MAC address lookup. IPv4 block with 64 bit data width for 10G Ethernet. Manages IPv4 packet transmssion and reception. Interfaces with ARP module for MAC address lookup. -### ip_arb_mux_N module +### ip_arb_mux module -IP frame arbitrated muliplexer with 8 bit data width for gigabit -Ethernet. Supports priority and round-robin arbitration. - -Can be generated with arbitrary port counts with ip_arb_mux.py. - -### ip_arb_mux_64_N module - -IP frame arbitrated muliplexer with 8 bit data width for 10G Ethernet. +IP frame arbitrated muliplexer with parametrizable data width and port count. Supports priority and round-robin arbitration. -Can be generated with arbitrary port counts with ip_arb_mux_64.py. - ### ip_complete module IPv4 module with ARP integration. @@ -221,6 +187,11 @@ IPv4 module with ARP integration and 64 bit data width for 10G Ethernet. Top level for 10G IP stack. +### ip_demux module + +IP frame demuliplexer with parametrizable data width and port count. +Supports priority and round-robin arbitration. + ### ip_eth_rx module IP frame receiver. @@ -237,34 +208,11 @@ IP frame transmitter. IP frame transmitter with 64 bit datapath for 10G Ethernet. -### ip_demux_N module +### ip_mux module -IP frame demuliplexer with 8 bit data width for gigabit Ethernet. +IP frame muliplexer with parametrizable data width and port count. Supports priority and round-robin arbitration. -Can be generated with arbitrary port counts with ip_demux.py. - -### ip_demux_64_N module - -IP frame demuliplexer with 64 bit data width for 10G Ethernet. Supports -priority and round-robin arbitration. - -Can be generated with arbitrary port counts with ip_demux_64.py. - -### ip_mux_N module - -IP frame muliplexer with 8 bit data width for gigabit Ethernet. -Supports priority and round-robin arbitration. - -Can be generated with arbitrary port counts with ip_mux.py. - -### ip_mux_64_N module - -IP frame muliplexer with 64 bit data width for 10G Ethernet. Supports -priority and round-robin arbitration. - -Can be generated with arbitrary port counts with ip_mux_64.py. - ### lfsr module Fully parametrizable combinatorial parallel LFSR/CRC module. @@ -283,19 +231,10 @@ transmssion and reception. UDP block with 64 bit data width for 10G Ethernet. Manages UDP packet transmssion and reception. -### udp_arb_mux_N module +### udp_arb_mux module -UDP frame arbitrated muliplexer with 8 bit data width for gigabit -Ethernet. Supports priority and round-robin arbitration. - -Can be generated with arbitrary port counts with udp_arb_mux.py. - -### udp_arb_mux_64_N module - -UDP frame arbitrated muliplexer with 8 bit data width for 10G Ethernet. -Supports priority and round-robin arbitration. - -Can be generated with arbitrary port counts with udp_arb_mux_64.py. +UDP frame arbitrated muliplexer with parametrizable data width and port +count. Supports priority and round-robin arbitration. ### udp_checksum_gen module @@ -320,6 +259,11 @@ Ethernet. Top level for 10G UDP stack. +### udp_demux module + +UDP frame demuliplexer with parametrizable data width and port count. +Supports priority and round-robin arbitration. + ### udp_ip_rx module UDP frame receiver. @@ -336,33 +280,20 @@ UDP frame transmitter. UDP frame transmitter with 64 bit datapath for 10G Ethernet. -### udp_demux_N module +### udp_mux module -UDP frame demuliplexer with 8 bit data width for gigabit Ethernet. +UDP frame muliplexer with parametrizable data width and port count. Supports priority and round-robin arbitration. -Can be generated with arbitrary port counts with udp_demux.py. +### xgmii_deinterleave.v -### udp_demux_64_N module +XGMII de-interleaver for interfacing with PHY cores that interleave the +control and data lines. -UDP frame demuliplexer with 64 bit data width for 10G Ethernet. Supports -priority and round-robin arbitration. +### xgmii_interleave.v -Can be generated with arbitrary port counts with udp_demux_64.py. - -### udp_mux_N module - -UDP frame muliplexer with 8 bit data width for gigabit Ethernet. -Supports priority and round-robin arbitration. - -Can be generated with arbitrary port counts with udp_mux.py. - -### udp_mux_64_N module - -UDP frame muliplexer with 64 bit data width for 10G Ethernet. Supports -priority and round-robin arbitration. - -Can be generated with arbitrary port counts with udp_mux_64.py. +XGMII interleaver for interfacing with PHY cores that interleave the control +and data lines. ### Common signals @@ -393,19 +324,12 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/axis_xgmii_rx_64.v : AXI stream XGMII receiver (64 bit) rtl/axis_xgmii_tx_32.v : AXI stream XGMII transmitter (32 bit) rtl/axis_xgmii_tx_64.v : AXI stream XGMII transmitter (64 bit) - rtl/eth_arb_mux_2.v : 2 port Ethernet frame arbitrated multiplexer - rtl/eth_arb_mux_4.v : 4 port Ethernet frame arbitrated multiplexer - rtl/eth_arb_mux_64.py : Ethernet frame arbitrated multiplexer generator (64 bit) - rtl/eth_arb_mux_64_2.v : 2 port Ethernet frame arbitrated multiplexer (64 bit) - rtl/eth_arb_mux_64_4.v : 4 port Ethernet frame arbitrated multiplexer (64 bit) + rtl/eth_arb_mux.v : Ethernet frame arbitrated multiplexer rtl/eth_axis_rx.v : Ethernet frame receiver rtl/eth_axis_rx_64.v : Ethernet frame receiver (64 bit) rtl/eth_axis_tx.v : Ethernet frame transmitter rtl/eth_axis_tx_64.v : Ethernet frame transmitter (64 bit) - rtl/eth_demux.py : Ethernet frame demultiplexer generator - rtl/eth_demux_4.v : 4 port Ethernet frame demultiplexer - rtl/eth_demux_64.py : Ethernet frame demultiplexer generator (64 bit) - rtl/eth_demux_64_4.v : 4 port Ethernet frame demultiplexer (64 bit) + rtl/eth_demux.v : Ethernet frame demultiplexer rtl/eth_mac_1g.v : Gigabit Etherent GMII MAC rtl/eth_mac_1g_fifo.v : Gigabit Etherent GMII MAC with FIFO rtl/eth_mac_1g_gmii.v : Tri-mode Ethernet GMII/MII MAC @@ -414,34 +338,20 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/eth_mac_1g_rgmii_fifo.v : Tri-mode Ethernet RGMII MAC with FIFO rtl/eth_mac_10g.v : 10G Etherent XGMII MAC rtl/eth_mac_10g_fifo.v : 10G Etherent XGMII MAC with FIFO - rtl/eth_mux.py : Ethernet frame multiplexer generator - rtl/eth_mux_2.v : 4 port Ethernet frame multiplexer - rtl/eth_mux_4.v : 4 port Ethernet frame multiplexer - rtl/eth_mux_64.py : Ethernet frame multiplexer generator (64 bit) - rtl/eth_mux_64_2.v : 4 port Ethernet frame multiplexer (64 bit) - rtl/eth_mux_64_4.v : 4 port Ethernet frame multiplexer (64 bit) + rtl/eth_mux.v : Ethernet frame multiplexer rtl/gmii_phy_if.v : GMII PHY interface rtl/iddr.v : Generic DDR input register rtl/ip.v : IPv4 block rtl/ip_64.v : IPv4 block (64 bit) - rtl/ip_arb_mux.py : IP frame arbitrated multiplexer generator - rtl/ip_arb_mux_4.v : 4 port IP frame arbitrated multiplexer - rtl/ip_arb_mux_64.py : IP frame arbitrated multiplexer generator (64 bit) - rtl/ip_arb_mux_64_4.v : 4 port IP frame arbitrated multiplexer (64 bit) + rtl/ip_arb_mux.v : IP frame arbitrated multiplexer rtl/ip_complete.v : IPv4 stack (IP-ARP integration) rtl/ip_complete_64.v : IPv4 stack (IP-ARP integration) (64 bit) + rtl/ip_demux.v : IP frame demultiplexer rtl/ip_eth_rx.v : IPv4 frame receiver rtl/ip_eth_rx_64.v : IPv4 frame receiver (64 bit) rtl/ip_eth_tx.v : IPv4 frame transmitter rtl/ip_eth_tx_64.v : IPv4 frame transmitter (64 bit) - rtl/ip_demux.py : IP frame demultiplexer generator - rtl/ip_demux_4.v : 4 port IP frame demultiplexer - rtl/ip_demux_64.py : IP frame demultiplexer generator (64 bit) - rtl/ip_demux_64_4.v : 4 port IP frame demultiplexer (64 bit) - rtl/ip_mux.py : IP frame multiplexer generator - rtl/ip_mux_4.v : 4 port IP frame multiplexer - rtl/ip_mux_64.py : IP frame multiplexer generator (64 bit) - rtl/ip_mux_64_4.v : 4 port IP frame multiplexer (64 bit) + rtl/ip_mux.v : IP frame multiplexer rtl/lfsr.v : Generic LFSR/CRC module rtl/oddr.v : Generic DDR output register rtl/rgmii_phy_if.v : RGMII PHY interface @@ -455,26 +365,17 @@ Can be generated with arbitrary port counts with udp_mux_64.py. rtl/ssio_sdr_out_diff.v : Generic source synchronous IO SDR differential output module rtl/udp.v : UDP block rtl/udp_64.v : UDP block (64 bit) - rtl/udp_arb_mux.py : UDP frame arbitrated multiplexer generator - rtl/udp_arb_mux_4.v : 4 port UDP frame arbitrated multiplexer - rtl/udp_arb_mux_64.py : UDP frame arbitrated multiplexer generator (64 bit) - rtl/udp_arb_mux_64_4.v : 4 port UDP frame arbitrated multiplexer (64 bit) + rtl/udp_arb_mux.v : UDP frame arbitrated multiplexer rtl/udp_checksum_gen.v : UDP checksum generator rtl/udp_checksum_gen_64.v : UDP checksum generator (64 bit) rtl/udp_complete.v : UDP stack (IP-ARP-UDP) rtl/udp_complete_64.v : UDP stack (IP-ARP-UDP) (64 bit) + rtl/udp_demux.v : UDP frame demultiplexer rtl/udp_ip_rx.v : UDP frame receiver rtl/udp_ip_rx_64.v : UDP frame receiver (64 bit) rtl/udp_ip_tx.v : UDP frame transmitter rtl/udp_ip_tx_64.v : UDP frame transmitter (64 bit) - rtl/udp_demux.py : UDP frame demultiplexer generator - rtl/udp_demux_4.v : 4 port UDP frame demultiplexer - rtl/udp_demux_64.py : UDP frame demultiplexer generator (64 bit) - rtl/udp_demux_64_4.v : 4 port UDP frame demultiplexer (64 bit) - rtl/udp_mux.py : UDP frame multiplexer generator - rtl/udp_mux_4.v : 4 port UDP frame multiplexer - rtl/udp_mux_64.py : UDP frame multiplexer generator (64 bit) - rtl/udp_mux_64_4.v : 4 port UDP frame multiplexer (64 bit) + rtl/udp_mux.v : UDP frame multiplexer ### AXI Stream Interface Example From 0a6bee6d69061c7abb7d23558fd9b39f0a4b4e27 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 8 Nov 2018 09:17:29 -0800 Subject: [PATCH 472/617] Update example designs --- example/ATLYS/fpga/fpga/Makefile | 6 +- example/ATLYS/fpga/rtl/fpga_core.v | 417 ++++++++-------- example/ATLYS/fpga/tb/test_fpga_core.py | 6 +- example/DE5-Net/fpga/fpga/Makefile | 6 +- example/DE5-Net/fpga/rtl/fpga_core.v | 462 +++++++++--------- example/DE5-Net/fpga/tb/test_fpga_core.py | 6 +- example/HXT100G/fpga/fpga/Makefile | 6 +- example/HXT100G/fpga/rtl/fpga_core.v | 462 +++++++++--------- example/HXT100G/fpga/tb/test_fpga_core.py | 6 +- example/HXT100G/fpga_cxpt16/rtl/fpga_core.v | 122 ++--- example/ML605/fpga_gmii/fpga_130t/Makefile | 6 +- example/ML605/fpga_gmii/fpga_240t/Makefile | 6 +- example/ML605/fpga_gmii/rtl/fpga_core.v | 417 ++++++++-------- example/ML605/fpga_gmii/tb/test_fpga_core.py | 6 +- example/ML605/fpga_rgmii/fpga_130t/Makefile | 6 +- example/ML605/fpga_rgmii/fpga_240t/Makefile | 6 +- example/ML605/fpga_rgmii/rtl/fpga_core.v | 417 ++++++++-------- example/ML605/fpga_rgmii/tb/test_fpga_core.py | 6 +- example/ML605/fpga_sgmii/fpga_130t/Makefile | 6 +- example/ML605/fpga_sgmii/fpga_240t/Makefile | 6 +- example/ML605/fpga_sgmii/rtl/fpga_core.v | 417 ++++++++-------- example/ML605/fpga_sgmii/tb/test_fpga_core.py | 6 +- example/NexysVideo/fpga/fpga/Makefile | 6 +- example/NexysVideo/fpga/rtl/fpga_core.v | 417 ++++++++-------- example/NexysVideo/fpga/tb/test_fpga_core.py | 6 +- example/VCU108/fpga_10g/fpga/Makefile | 6 +- example/VCU108/fpga_10g/rtl/fpga_core.v | 462 +++++++++--------- example/VCU108/fpga_10g/tb/test_fpga_core.py | 6 +- example/VCU108/fpga_1g/fpga/Makefile | 6 +- example/VCU108/fpga_1g/rtl/fpga_core.v | 419 ++++++++-------- example/VCU108/fpga_1g/tb/test_fpga_core.py | 6 +- example/VCU118/fpga_10g/fpga/Makefile | 6 +- example/VCU118/fpga_10g/rtl/fpga_core.v | 462 +++++++++--------- example/VCU118/fpga_10g/tb/test_fpga_core.py | 6 +- example/VCU118/fpga_1g/fpga/Makefile | 6 +- example/VCU118/fpga_1g/rtl/fpga_core.v | 419 ++++++++-------- example/VCU118/fpga_1g/tb/test_fpga_core.py | 6 +- example/VCU118/fpga_1g/tb/test_fpga_core.v | 1 - 38 files changed, 2467 insertions(+), 2577 deletions(-) diff --git a/example/ATLYS/fpga/fpga/Makefile b/example/ATLYS/fpga/fpga/Makefile index ca2f8954a..956dac9d9 100644 --- a/example/ATLYS/fpga/fpga/Makefile +++ b/example/ATLYS/fpga/fpga/Makefile @@ -36,14 +36,12 @@ SYN_FILES += lib/eth/rtl/ip_complete.v SYN_FILES += lib/eth/rtl/ip.v SYN_FILES += lib/eth/rtl/ip_eth_rx.v SYN_FILES += lib/eth/rtl/ip_eth_tx.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v -SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx.v SYN_FILES += lib/eth/rtl/arp_eth_tx.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v -SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/ATLYS/fpga/rtl/fpga_core.v b/example/ATLYS/fpga/rtl/fpga_core.v index ad68f8006..2fb71402a 100644 --- a/example/ATLYS/fpga/rtl/fpga_core.v +++ b/example/ATLYS/fpga/rtl/fpga_core.v @@ -92,22 +92,22 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [7:0] rx_eth_payload_tdata; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [7:0] rx_eth_payload_axis_tdata; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [7:0] tx_eth_payload_tdata; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [7:0] tx_eth_payload_axis_tdata; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -128,11 +128,11 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [7:0] rx_ip_payload_tdata; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [7:0] rx_ip_payload_axis_tdata; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -143,11 +143,11 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [7:0] tx_ip_payload_tdata; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [7:0] tx_ip_payload_axis_tdata; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -172,11 +172,11 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [7:0] rx_udp_payload_tdata; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [7:0] rx_udp_payload_axis_tdata; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -189,23 +189,23 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [7:0] tx_udp_payload_tdata; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [7:0] rx_fifo_udp_payload_tdata; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [7:0] rx_fifo_udp_payload_axis_tdata; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [7:0] tx_fifo_udp_payload_tdata; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [7:0] tx_fifo_udp_payload_axis_tdata; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -215,7 +215,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -225,14 +225,14 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -242,9 +242,9 @@ always @(posedge clk) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -255,8 +255,8 @@ always @(posedge clk) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -266,23 +266,18 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -292,12 +287,12 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - if (tx_udp_payload_tvalid) begin - if (~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; valid_last <= 1'b1; end - if (tx_udp_payload_tlast) begin + if (tx_udp_payload_axis_tlast) begin valid_last <= 1'b0; end end @@ -306,7 +301,7 @@ end //assign led = sw; assign led = led_reg; -assign phy_reset_n = ~rst; +assign phy_reset_n = !rst; assign uart_txd = 0; @@ -367,22 +362,22 @@ eth_axis_rx_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -393,22 +388,22 @@ eth_axis_tx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -418,111 +413,111 @@ udp_complete_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -560,24 +555,24 @@ udp_payload_fifo ( .rst(rst), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), .s_axis_tkeep(0), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), .m_axis_tkeep(), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/ATLYS/fpga/tb/test_fpga_core.py b/example/ATLYS/fpga/tb/test_fpga_core.py index e0f9fcefc..081281ea2 100755 --- a/example/ATLYS/fpga/tb/test_fpga_core.py +++ b/example/ATLYS/fpga/tb/test_fpga_core.py @@ -59,14 +59,12 @@ srcs.append("../lib/eth/rtl/ip_complete.v") srcs.append("../lib/eth/rtl/ip.v") srcs.append("../lib/eth/rtl/ip_eth_rx.v") srcs.append("../lib/eth/rtl/ip_eth_tx.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") -srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx.v") srcs.append("../lib/eth/rtl/arp_eth_tx.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") -srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") diff --git a/example/DE5-Net/fpga/fpga/Makefile b/example/DE5-Net/fpga/fpga/Makefile index 44641f6fc..4f8808924 100644 --- a/example/DE5-Net/fpga/fpga/Makefile +++ b/example/DE5-Net/fpga/fpga/Makefile @@ -28,14 +28,12 @@ SYN_FILES += lib/eth/rtl/ip_complete_64.v SYN_FILES += lib/eth/rtl/ip_64.v SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_64_2.v -SYN_FILES += lib/eth/rtl/ip_mux_64_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp_64.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_64_2.v -SYN_FILES += lib/eth/rtl/eth_mux_64_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/rtl/xgmii_interleave.v SYN_FILES += lib/eth/rtl/xgmii_deinterleave.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index 3a8604c17..56a15431d 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -92,24 +92,24 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [63:0] rx_eth_payload_tdata; -wire [7:0] rx_eth_payload_tkeep; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [63:0] rx_eth_payload_axis_tdata; +wire [7:0] rx_eth_payload_axis_tkeep; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [63:0] tx_eth_payload_tdata; -wire [7:0] tx_eth_payload_tkeep; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [63:0] tx_eth_payload_axis_tdata; +wire [7:0] tx_eth_payload_axis_tkeep; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -130,12 +130,12 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [63:0] rx_ip_payload_tdata; -wire [7:0] rx_ip_payload_tkeep; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [63:0] rx_ip_payload_axis_tdata; +wire [7:0] rx_ip_payload_axis_tkeep; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -146,12 +146,12 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [63:0] tx_ip_payload_tdata; -wire [7:0] tx_ip_payload_tkeep; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [63:0] tx_ip_payload_axis_tdata; +wire [7:0] tx_ip_payload_axis_tkeep; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -176,12 +176,12 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [63:0] rx_udp_payload_tdata; -wire [7:0] rx_udp_payload_tkeep; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [63:0] rx_udp_payload_axis_tdata; +wire [7:0] rx_udp_payload_axis_tkeep; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -194,26 +194,26 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [63:0] tx_udp_payload_tdata; -wire [7:0] tx_udp_payload_tkeep; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [63:0] tx_udp_payload_axis_tdata; +wire [7:0] tx_udp_payload_axis_tkeep; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [63:0] rx_fifo_udp_payload_tdata; -wire [7:0] rx_fifo_udp_payload_tkeep; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [63:0] rx_fifo_udp_payload_axis_tdata; +wire [7:0] rx_fifo_udp_payload_axis_tkeep; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [63:0] tx_fifo_udp_payload_tdata; -wire [7:0] tx_fifo_udp_payload_tkeep; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [63:0] tx_fifo_udp_payload_axis_tdata; +wire [7:0] tx_fifo_udp_payload_axis_tkeep; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -223,7 +223,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -233,15 +233,15 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tkeep = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tkeep = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -251,9 +251,9 @@ always @(posedge clk) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -264,8 +264,8 @@ always @(posedge clk) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -275,26 +275,20 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tkeep = rx_udp_payload_tkeep; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tkeep = tx_fifo_udp_payload_tkeep; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tkeep = rx_udp_payload_tkeep; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -304,12 +298,12 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - if (tx_udp_payload_tvalid) begin - if (~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; valid_last <= 1'b1; end - if (tx_udp_payload_tlast) begin + if (tx_udp_payload_axis_tlast) begin valid_last <= 1'b0; end end @@ -384,24 +378,24 @@ eth_axis_rx_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tkeep(rx_axis_tkeep), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tkeep(rx_axis_tkeep), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tkeep(rx_eth_payload_tkeep), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -412,24 +406,24 @@ eth_axis_tx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tkeep(tx_eth_payload_tkeep), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tkeep(tx_axis_tkeep), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tkeep(tx_axis_tkeep), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -439,117 +433,117 @@ udp_complete_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tkeep(rx_eth_payload_tkeep), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tkeep(tx_eth_payload_tkeep), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tkeep(tx_ip_payload_tkeep), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tkeep(rx_ip_payload_tkeep), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tkeep(tx_udp_payload_tkeep), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tkeep(rx_udp_payload_tkeep), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -588,24 +582,24 @@ udp_payload_fifo ( .rst(rst), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), - .s_axis_tkeep(rx_fifo_udp_payload_tkeep), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), - .m_axis_tkeep(tx_fifo_udp_payload_tkeep), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index 129b3e0ab..5a4a121d7 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -53,14 +53,12 @@ srcs.append("../lib/eth/rtl/ip_complete_64.v") srcs.append("../lib/eth/rtl/ip_64.v") srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_64_2.v") -srcs.append("../lib/eth/rtl/ip_mux_64_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp_64.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") -srcs.append("../lib/eth/rtl/eth_mux_64_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") diff --git a/example/HXT100G/fpga/fpga/Makefile b/example/HXT100G/fpga/fpga/Makefile index 23454c522..d1c3e8b5a 100644 --- a/example/HXT100G/fpga/fpga/Makefile +++ b/example/HXT100G/fpga/fpga/Makefile @@ -33,14 +33,12 @@ SYN_FILES += lib/eth/rtl/ip_complete_64.v SYN_FILES += lib/eth/rtl/ip_64.v SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_64_2.v -SYN_FILES += lib/eth/rtl/ip_mux_64_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp_64.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_64_2.v -SYN_FILES += lib/eth/rtl/eth_mux_64_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v index 16c386580..4efe34132 100644 --- a/example/HXT100G/fpga/rtl/fpga_core.v +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -198,24 +198,24 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [63:0] rx_eth_payload_tdata; -wire [7:0] rx_eth_payload_tkeep; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [63:0] rx_eth_payload_axis_tdata; +wire [7:0] rx_eth_payload_axis_tkeep; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [63:0] tx_eth_payload_tdata; -wire [7:0] tx_eth_payload_tkeep; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [63:0] tx_eth_payload_axis_tdata; +wire [7:0] tx_eth_payload_axis_tkeep; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -236,12 +236,12 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [63:0] rx_ip_payload_tdata; -wire [7:0] rx_ip_payload_tkeep; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [63:0] rx_ip_payload_axis_tdata; +wire [7:0] rx_ip_payload_axis_tkeep; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -252,12 +252,12 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [63:0] tx_ip_payload_tdata; -wire [7:0] tx_ip_payload_tkeep; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [63:0] tx_ip_payload_axis_tdata; +wire [7:0] tx_ip_payload_axis_tkeep; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -282,12 +282,12 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [63:0] rx_udp_payload_tdata; -wire [7:0] rx_udp_payload_tkeep; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [63:0] rx_udp_payload_axis_tdata; +wire [7:0] rx_udp_payload_axis_tkeep; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -300,26 +300,26 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [63:0] tx_udp_payload_tdata; -wire [7:0] tx_udp_payload_tkeep; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [63:0] tx_udp_payload_axis_tdata; +wire [7:0] tx_udp_payload_axis_tkeep; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [63:0] rx_fifo_udp_payload_tdata; -wire [7:0] rx_fifo_udp_payload_tkeep; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [63:0] rx_fifo_udp_payload_axis_tdata; +wire [7:0] rx_fifo_udp_payload_axis_tkeep; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [63:0] tx_fifo_udp_payload_tdata; -wire [7:0] tx_fifo_udp_payload_tkeep; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [63:0] tx_fifo_udp_payload_axis_tdata; +wire [7:0] tx_fifo_udp_payload_axis_tkeep; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -329,7 +329,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -339,15 +339,15 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tkeep = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tkeep = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -357,9 +357,9 @@ always @(posedge clk) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -370,8 +370,8 @@ always @(posedge clk) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -381,26 +381,20 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tkeep = rx_udp_payload_tkeep; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tkeep = tx_fifo_udp_payload_tkeep; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tkeep = rx_udp_payload_tkeep; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -410,12 +404,12 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - if (tx_udp_payload_tvalid) begin - if (~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; valid_last <= 1'b1; end - if (tx_udp_payload_tlast) begin + if (tx_udp_payload_axis_tlast) begin valid_last <= 1'b0; end end @@ -528,24 +522,24 @@ eth_axis_rx_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tkeep(rx_axis_tkeep), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tkeep(rx_axis_tkeep), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tkeep(rx_eth_payload_tkeep), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -556,24 +550,24 @@ eth_axis_tx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tkeep(tx_eth_payload_tkeep), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tkeep(tx_axis_tkeep), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tkeep(tx_axis_tkeep), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -583,117 +577,117 @@ udp_complete_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tkeep(rx_eth_payload_tkeep), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tkeep(tx_eth_payload_tkeep), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tkeep(tx_ip_payload_tkeep), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tkeep(rx_ip_payload_tkeep), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tkeep(tx_udp_payload_tkeep), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tkeep(rx_udp_payload_tkeep), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -732,24 +726,24 @@ udp_payload_fifo ( .rst(rst), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), - .s_axis_tkeep(rx_fifo_udp_payload_tkeep), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), - .m_axis_tkeep(tx_fifo_udp_payload_tkeep), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index f78bccea3..dac66e783 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -53,14 +53,12 @@ srcs.append("../lib/eth/rtl/ip_complete_64.v") srcs.append("../lib/eth/rtl/ip_64.v") srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_64_2.v") -srcs.append("../lib/eth/rtl/ip_mux_64_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp_64.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") -srcs.append("../lib/eth/rtl/eth_mux_64_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") diff --git a/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v b/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v index 489938126..ccf2b23b7 100644 --- a/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v +++ b/example/HXT100G/fpga_cxpt16/rtl/fpga_core.v @@ -259,12 +259,12 @@ wire eth_rx_hdr_ready; wire [47:0] eth_rx_dest_mac; wire [47:0] eth_rx_src_mac; wire [15:0] eth_rx_type; -wire [63:0] eth_rx_payload_tdata; -wire [7:0] eth_rx_payload_tkeep; -wire eth_rx_payload_tvalid; -wire eth_rx_payload_tready; -wire eth_rx_payload_tlast; -wire eth_rx_payload_tuser; +wire [63:0] eth_rx_payload_axis_tdata; +wire [7:0] eth_rx_payload_axis_tkeep; +wire eth_rx_payload_axis_tvalid; +wire eth_rx_payload_axis_tready; +wire eth_rx_payload_axis_tlast; +wire eth_rx_payload_axis_tuser; eth_mac_10g_fifo #( .ENABLE_PADDING(1), @@ -314,24 +314,24 @@ eth_axis_rx_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(eth_rx_axis_tdata), - .input_axis_tkeep(eth_rx_axis_tkeep), - .input_axis_tvalid(eth_rx_axis_tvalid), - .input_axis_tready(eth_rx_axis_tready), - .input_axis_tlast(eth_rx_axis_tlast), - .input_axis_tuser(eth_rx_axis_tuser), + .s_axis_tdata(eth_rx_axis_tdata), + .s_axis_tkeep(eth_rx_axis_tkeep), + .s_axis_tvalid(eth_rx_axis_tvalid), + .s_axis_tready(eth_rx_axis_tready), + .s_axis_tlast(eth_rx_axis_tlast), + .s_axis_tuser(eth_rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(eth_rx_hdr_valid), - .output_eth_hdr_ready(eth_rx_hdr_ready), - .output_eth_dest_mac(eth_rx_dest_mac), - .output_eth_src_mac(eth_rx_src_mac), - .output_eth_type(eth_rx_type), - .output_eth_payload_tdata(eth_rx_payload_tdata), - .output_eth_payload_tkeep(eth_rx_payload_tkeep), - .output_eth_payload_tvalid(eth_rx_payload_tvalid), - .output_eth_payload_tready(eth_rx_payload_tready), - .output_eth_payload_tlast(eth_rx_payload_tlast), - .output_eth_payload_tuser(eth_rx_payload_tuser), + .m_eth_hdr_valid(eth_rx_hdr_valid), + .m_eth_hdr_ready(eth_rx_hdr_ready), + .m_eth_dest_mac(eth_rx_dest_mac), + .m_eth_src_mac(eth_rx_src_mac), + .m_eth_type(eth_rx_type), + .m_eth_payload_axis_tdata(eth_rx_payload_axis_tdata), + .m_eth_payload_axis_tkeep(eth_rx_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(eth_rx_payload_axis_tvalid), + .m_eth_payload_axis_tready(eth_rx_payload_axis_tready), + .m_eth_payload_axis_tlast(eth_rx_payload_axis_tlast), + .m_eth_payload_axis_tuser(eth_rx_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -347,16 +347,16 @@ localparam [2:0] reg [2:0] state_reg = STATE_IDLE; reg eth_rx_hdr_ready_reg = 0; -reg eth_rx_payload_tready_reg = 0; +reg eth_rx_payload_axis_tready_reg = 0; assign eth_rx_hdr_ready = eth_rx_hdr_ready_reg; -assign eth_rx_payload_tready = eth_rx_payload_tready_reg; +assign eth_rx_payload_axis_tready = eth_rx_payload_axis_tready_reg; always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; eth_rx_hdr_ready_reg <= 0; - eth_rx_payload_tready_reg <= 0; + eth_rx_payload_axis_tready_reg <= 0; select_reg_0 <= 0; select_reg_1 <= 1; select_reg_2 <= 2; @@ -377,77 +377,77 @@ always @(posedge clk) begin case (state_reg) STATE_IDLE: begin eth_rx_hdr_ready_reg <= 1; - eth_rx_payload_tready_reg <= 0; - if (eth_rx_hdr_ready & eth_rx_hdr_valid) begin + eth_rx_payload_axis_tready_reg <= 0; + if (eth_rx_hdr_ready && eth_rx_hdr_valid) begin if (eth_rx_type == 16'h8099) begin state_reg <= STATE_WORD_0; eth_rx_hdr_ready_reg <= 0; - eth_rx_payload_tready_reg <= 1; + eth_rx_payload_axis_tready_reg <= 1; end else begin state_reg <= STATE_WAIT; eth_rx_hdr_ready_reg <= 0; - eth_rx_payload_tready_reg <= 1; + eth_rx_payload_axis_tready_reg <= 1; end end end STATE_WORD_0: begin eth_rx_hdr_ready_reg <= 0; - eth_rx_payload_tready_reg <= 1; - if (eth_rx_payload_tready & eth_rx_payload_tvalid) begin - if (eth_rx_payload_tlast) begin + eth_rx_payload_axis_tready_reg <= 1; + if (eth_rx_payload_axis_tready && eth_rx_payload_axis_tvalid) begin + if (eth_rx_payload_axis_tlast) begin state_reg <= STATE_IDLE; eth_rx_hdr_ready_reg <= 1; - eth_rx_payload_tready_reg <= 0; + eth_rx_payload_axis_tready_reg <= 0; end else begin - select_reg_0 <= eth_rx_payload_tdata[7:0]; - select_reg_1 <= eth_rx_payload_tdata[15:8]; - select_reg_2 <= eth_rx_payload_tdata[23:16]; - select_reg_3 <= eth_rx_payload_tdata[31:24]; - select_reg_4 <= eth_rx_payload_tdata[39:32]; - select_reg_5 <= eth_rx_payload_tdata[47:40]; - select_reg_6 <= eth_rx_payload_tdata[55:48]; - select_reg_7 <= eth_rx_payload_tdata[63:56]; + select_reg_0 <= eth_rx_payload_axis_tdata[7:0]; + select_reg_1 <= eth_rx_payload_axis_tdata[15:8]; + select_reg_2 <= eth_rx_payload_axis_tdata[23:16]; + select_reg_3 <= eth_rx_payload_axis_tdata[31:24]; + select_reg_4 <= eth_rx_payload_axis_tdata[39:32]; + select_reg_5 <= eth_rx_payload_axis_tdata[47:40]; + select_reg_6 <= eth_rx_payload_axis_tdata[55:48]; + select_reg_7 <= eth_rx_payload_axis_tdata[63:56]; state_reg <= STATE_WORD_1; eth_rx_hdr_ready_reg <= 0; - eth_rx_payload_tready_reg <= 1; + eth_rx_payload_axis_tready_reg <= 1; end end end STATE_WORD_1: begin eth_rx_hdr_ready_reg <= 0; - eth_rx_payload_tready_reg <= 1; - if (eth_rx_payload_tready & eth_rx_payload_tvalid) begin - if (eth_rx_payload_tlast) begin + eth_rx_payload_axis_tready_reg <= 1; + if (eth_rx_payload_axis_tready && eth_rx_payload_axis_tvalid) begin + if (eth_rx_payload_axis_tlast) begin state_reg <= STATE_IDLE; eth_rx_hdr_ready_reg <= 1; - eth_rx_payload_tready_reg <= 0; + eth_rx_payload_axis_tready_reg <= 0; end else begin - select_reg_8 <= eth_rx_payload_tdata[7:0]; - select_reg_9 <= eth_rx_payload_tdata[15:8]; - select_reg_10 <= eth_rx_payload_tdata[23:16]; - select_reg_11 <= eth_rx_payload_tdata[31:24]; - select_reg_12 <= eth_rx_payload_tdata[39:32]; - select_reg_13 <= eth_rx_payload_tdata[47:40]; - select_reg_14 <= eth_rx_payload_tdata[55:48]; - select_reg_15 <= eth_rx_payload_tdata[63:56]; + select_reg_8 <= eth_rx_payload_axis_tdata[7:0]; + select_reg_9 <= eth_rx_payload_axis_tdata[15:8]; + select_reg_10 <= eth_rx_payload_axis_tdata[23:16]; + select_reg_11 <= eth_rx_payload_axis_tdata[31:24]; + select_reg_12 <= eth_rx_payload_axis_tdata[39:32]; + select_reg_13 <= eth_rx_payload_axis_tdata[47:40]; + select_reg_14 <= eth_rx_payload_axis_tdata[55:48]; + select_reg_15 <= eth_rx_payload_axis_tdata[63:56]; state_reg <= STATE_WAIT; eth_rx_hdr_ready_reg <= 0; - eth_rx_payload_tready_reg <= 1; + eth_rx_payload_axis_tready_reg <= 1; end end end STATE_WAIT: begin eth_rx_hdr_ready_reg <= 0; - eth_rx_payload_tready_reg <= 1; - if (eth_rx_payload_tready & eth_rx_payload_tvalid) begin - if (eth_rx_payload_tlast) begin + eth_rx_payload_axis_tready_reg <= 1; + if (eth_rx_payload_axis_tready && eth_rx_payload_axis_tvalid) begin + if (eth_rx_payload_axis_tlast) begin state_reg <= STATE_IDLE; eth_rx_hdr_ready_reg <= 1; - eth_rx_payload_tready_reg <= 0; + eth_rx_payload_axis_tready_reg <= 0; end else begin state_reg <= STATE_WAIT; eth_rx_hdr_ready_reg <= 0; - eth_rx_payload_tready_reg <= 1; + eth_rx_payload_axis_tready_reg <= 1; end end end diff --git a/example/ML605/fpga_gmii/fpga_130t/Makefile b/example/ML605/fpga_gmii/fpga_130t/Makefile index 887f1c88a..cdecade0c 100644 --- a/example/ML605/fpga_gmii/fpga_130t/Makefile +++ b/example/ML605/fpga_gmii/fpga_130t/Makefile @@ -36,14 +36,12 @@ SYN_FILES += lib/eth/rtl/ip_complete.v SYN_FILES += lib/eth/rtl/ip.v SYN_FILES += lib/eth/rtl/ip_eth_rx.v SYN_FILES += lib/eth/rtl/ip_eth_tx.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v -SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx.v SYN_FILES += lib/eth/rtl/arp_eth_tx.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v -SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/ML605/fpga_gmii/fpga_240t/Makefile b/example/ML605/fpga_gmii/fpga_240t/Makefile index a7afe00c5..54a553c06 100644 --- a/example/ML605/fpga_gmii/fpga_240t/Makefile +++ b/example/ML605/fpga_gmii/fpga_240t/Makefile @@ -36,14 +36,12 @@ SYN_FILES += lib/eth/rtl/ip_complete.v SYN_FILES += lib/eth/rtl/ip.v SYN_FILES += lib/eth/rtl/ip_eth_rx.v SYN_FILES += lib/eth/rtl/ip_eth_tx.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v -SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx.v SYN_FILES += lib/eth/rtl/arp_eth_tx.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v -SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/ML605/fpga_gmii/rtl/fpga_core.v b/example/ML605/fpga_gmii/rtl/fpga_core.v index 40e262819..9db205054 100644 --- a/example/ML605/fpga_gmii/rtl/fpga_core.v +++ b/example/ML605/fpga_gmii/rtl/fpga_core.v @@ -99,22 +99,22 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [7:0] rx_eth_payload_tdata; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [7:0] rx_eth_payload_axis_tdata; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [7:0] tx_eth_payload_tdata; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [7:0] tx_eth_payload_axis_tdata; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -135,11 +135,11 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [7:0] rx_ip_payload_tdata; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [7:0] rx_ip_payload_axis_tdata; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -150,11 +150,11 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [7:0] tx_ip_payload_tdata; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [7:0] tx_ip_payload_axis_tdata; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -179,11 +179,11 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [7:0] rx_udp_payload_tdata; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [7:0] rx_udp_payload_axis_tdata; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -196,23 +196,23 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [7:0] tx_udp_payload_tdata; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [7:0] rx_fifo_udp_payload_tdata; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [7:0] rx_fifo_udp_payload_axis_tdata; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [7:0] tx_fifo_udp_payload_tdata; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [7:0] tx_fifo_udp_payload_axis_tdata; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -222,7 +222,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -232,14 +232,14 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -249,9 +249,9 @@ always @(posedge clk_125mhz) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -262,8 +262,8 @@ always @(posedge clk_125mhz) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -273,23 +273,18 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -299,12 +294,12 @@ always @(posedge clk_125mhz) begin if (rst_125mhz) begin led_reg <= 0; end else begin - if (tx_udp_payload_tvalid) begin - if (~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; valid_last <= 1'b1; end - if (tx_udp_payload_tlast) begin + if (tx_udp_payload_axis_tlast) begin valid_last <= 1'b0; end end @@ -318,7 +313,7 @@ assign ledd = 0; assign ledr = 0; assign ledc = 0; assign led = led_reg; -assign phy_reset_n = ~rst_125mhz; +assign phy_reset_n = !rst_125mhz; assign uart_rxd = 0; assign uart_cts = 0; @@ -380,22 +375,22 @@ eth_axis_rx_inst ( .clk(clk_125mhz), .rst(rst_125mhz), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -406,22 +401,22 @@ eth_axis_tx_inst ( .clk(clk_125mhz), .rst(rst_125mhz), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -431,111 +426,111 @@ udp_complete_inst ( .clk(clk_125mhz), .rst(rst_125mhz), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -573,24 +568,24 @@ udp_payload_fifo ( .rst(rst_125mhz), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), .s_axis_tkeep(0), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), .m_axis_tkeep(), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/ML605/fpga_gmii/tb/test_fpga_core.py b/example/ML605/fpga_gmii/tb/test_fpga_core.py index 7eb64d5fc..f52a00a56 100755 --- a/example/ML605/fpga_gmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_gmii/tb/test_fpga_core.py @@ -59,14 +59,12 @@ srcs.append("../lib/eth/rtl/ip_complete.v") srcs.append("../lib/eth/rtl/ip.v") srcs.append("../lib/eth/rtl/ip_eth_rx.v") srcs.append("../lib/eth/rtl/ip_eth_tx.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") -srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx.v") srcs.append("../lib/eth/rtl/arp_eth_tx.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") -srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") diff --git a/example/ML605/fpga_rgmii/fpga_130t/Makefile b/example/ML605/fpga_rgmii/fpga_130t/Makefile index 7213586b0..b315b1c06 100644 --- a/example/ML605/fpga_rgmii/fpga_130t/Makefile +++ b/example/ML605/fpga_rgmii/fpga_130t/Makefile @@ -36,14 +36,12 @@ SYN_FILES += lib/eth/rtl/ip_complete.v SYN_FILES += lib/eth/rtl/ip.v SYN_FILES += lib/eth/rtl/ip_eth_rx.v SYN_FILES += lib/eth/rtl/ip_eth_tx.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v -SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx.v SYN_FILES += lib/eth/rtl/arp_eth_tx.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v -SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/ML605/fpga_rgmii/fpga_240t/Makefile b/example/ML605/fpga_rgmii/fpga_240t/Makefile index 09396893e..4d46cec26 100644 --- a/example/ML605/fpga_rgmii/fpga_240t/Makefile +++ b/example/ML605/fpga_rgmii/fpga_240t/Makefile @@ -36,14 +36,12 @@ SYN_FILES += lib/eth/rtl/ip_complete.v SYN_FILES += lib/eth/rtl/ip.v SYN_FILES += lib/eth/rtl/ip_eth_rx.v SYN_FILES += lib/eth/rtl/ip_eth_tx.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v -SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx.v SYN_FILES += lib/eth/rtl/arp_eth_tx.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v -SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/ML605/fpga_rgmii/rtl/fpga_core.v b/example/ML605/fpga_rgmii/rtl/fpga_core.v index daf922d50..d01a4034c 100644 --- a/example/ML605/fpga_rgmii/rtl/fpga_core.v +++ b/example/ML605/fpga_rgmii/rtl/fpga_core.v @@ -97,22 +97,22 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [7:0] rx_eth_payload_tdata; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [7:0] rx_eth_payload_axis_tdata; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [7:0] tx_eth_payload_tdata; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [7:0] tx_eth_payload_axis_tdata; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -133,11 +133,11 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [7:0] rx_ip_payload_tdata; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [7:0] rx_ip_payload_axis_tdata; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -148,11 +148,11 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [7:0] tx_ip_payload_tdata; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [7:0] tx_ip_payload_axis_tdata; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -177,11 +177,11 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [7:0] rx_udp_payload_tdata; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [7:0] rx_udp_payload_axis_tdata; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -194,23 +194,23 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [7:0] tx_udp_payload_tdata; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [7:0] rx_fifo_udp_payload_tdata; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [7:0] rx_fifo_udp_payload_axis_tdata; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [7:0] tx_fifo_udp_payload_tdata; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [7:0] tx_fifo_udp_payload_axis_tdata; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -220,7 +220,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -230,14 +230,14 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -247,9 +247,9 @@ always @(posedge clk_125mhz) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -260,8 +260,8 @@ always @(posedge clk_125mhz) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -271,23 +271,18 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -297,12 +292,12 @@ always @(posedge clk_125mhz) begin if (rst_125mhz) begin led_reg <= 0; end else begin - if (tx_udp_payload_tvalid) begin - if (~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; valid_last <= 1'b1; end - if (tx_udp_payload_tlast) begin + if (tx_udp_payload_axis_tlast) begin valid_last <= 1'b0; end end @@ -316,7 +311,7 @@ assign ledd = 0; assign ledr = 0; assign ledc = 0; assign led = led_reg; -assign phy_reset_n = ~rst_125mhz; +assign phy_reset_n = !rst_125mhz; assign uart_rxd = 0; assign uart_cts = 0; @@ -377,22 +372,22 @@ eth_axis_rx_inst ( .clk(clk_125mhz), .rst(rst_125mhz), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -403,22 +398,22 @@ eth_axis_tx_inst ( .clk(clk_125mhz), .rst(rst_125mhz), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -428,111 +423,111 @@ udp_complete_inst ( .clk(clk_125mhz), .rst(rst_125mhz), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -570,24 +565,24 @@ udp_payload_fifo ( .rst(rst_125mhz), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), .s_axis_tkeep(0), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), .m_axis_tkeep(), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/ML605/fpga_rgmii/tb/test_fpga_core.py b/example/ML605/fpga_rgmii/tb/test_fpga_core.py index d5d531aae..5b03aa9ae 100755 --- a/example/ML605/fpga_rgmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_rgmii/tb/test_fpga_core.py @@ -59,14 +59,12 @@ srcs.append("../lib/eth/rtl/ip_complete.v") srcs.append("../lib/eth/rtl/ip.v") srcs.append("../lib/eth/rtl/ip_eth_rx.v") srcs.append("../lib/eth/rtl/ip_eth_tx.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") -srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx.v") srcs.append("../lib/eth/rtl/arp_eth_tx.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") -srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") diff --git a/example/ML605/fpga_sgmii/fpga_130t/Makefile b/example/ML605/fpga_sgmii/fpga_130t/Makefile index 904197fa3..74718cc8a 100644 --- a/example/ML605/fpga_sgmii/fpga_130t/Makefile +++ b/example/ML605/fpga_sgmii/fpga_130t/Makefile @@ -30,14 +30,12 @@ SYN_FILES += lib/eth/rtl/ip_complete.v SYN_FILES += lib/eth/rtl/ip.v SYN_FILES += lib/eth/rtl/ip_eth_rx.v SYN_FILES += lib/eth/rtl/ip_eth_tx.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v -SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx.v SYN_FILES += lib/eth/rtl/arp_eth_tx.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v -SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/ML605/fpga_sgmii/fpga_240t/Makefile b/example/ML605/fpga_sgmii/fpga_240t/Makefile index 07d08b056..4fe5d60e5 100644 --- a/example/ML605/fpga_sgmii/fpga_240t/Makefile +++ b/example/ML605/fpga_sgmii/fpga_240t/Makefile @@ -30,14 +30,12 @@ SYN_FILES += lib/eth/rtl/ip_complete.v SYN_FILES += lib/eth/rtl/ip.v SYN_FILES += lib/eth/rtl/ip_eth_rx.v SYN_FILES += lib/eth/rtl/ip_eth_tx.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v -SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx.v SYN_FILES += lib/eth/rtl/arp_eth_tx.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v -SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/ML605/fpga_sgmii/rtl/fpga_core.v b/example/ML605/fpga_sgmii/rtl/fpga_core.v index 57285c5ee..f699350d9 100644 --- a/example/ML605/fpga_sgmii/rtl/fpga_core.v +++ b/example/ML605/fpga_sgmii/rtl/fpga_core.v @@ -96,22 +96,22 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [7:0] rx_eth_payload_tdata; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [7:0] rx_eth_payload_axis_tdata; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [7:0] tx_eth_payload_tdata; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [7:0] tx_eth_payload_axis_tdata; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -132,11 +132,11 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [7:0] rx_ip_payload_tdata; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [7:0] rx_ip_payload_axis_tdata; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -147,11 +147,11 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [7:0] tx_ip_payload_tdata; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [7:0] tx_ip_payload_axis_tdata; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -176,11 +176,11 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [7:0] rx_udp_payload_tdata; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [7:0] rx_udp_payload_axis_tdata; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -193,23 +193,23 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [7:0] tx_udp_payload_tdata; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [7:0] rx_fifo_udp_payload_tdata; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [7:0] rx_fifo_udp_payload_axis_tdata; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [7:0] tx_fifo_udp_payload_tdata; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [7:0] tx_fifo_udp_payload_axis_tdata; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -219,7 +219,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -229,14 +229,14 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -246,9 +246,9 @@ always @(posedge clk_125mhz) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -259,8 +259,8 @@ always @(posedge clk_125mhz) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -270,23 +270,18 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -296,12 +291,12 @@ always @(posedge clk_125mhz) begin if (rst_125mhz) begin led_reg <= 0; end else begin - if (tx_udp_payload_tvalid) begin - if (~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; valid_last <= 1'b1; end - if (tx_udp_payload_tlast) begin + if (tx_udp_payload_axis_tlast) begin valid_last <= 1'b0; end end @@ -315,7 +310,7 @@ assign ledd = 0; assign ledr = 0; assign ledc = 0; assign led = led_reg; -assign phy_reset_n = ~rst_125mhz; +assign phy_reset_n = !rst_125mhz; assign uart_rxd = 0; assign uart_cts = 0; @@ -377,22 +372,22 @@ eth_axis_rx_inst ( .clk(clk_125mhz), .rst(rst_125mhz), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -403,22 +398,22 @@ eth_axis_tx_inst ( .clk(clk_125mhz), .rst(rst_125mhz), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -428,111 +423,111 @@ udp_complete_inst ( .clk(clk_125mhz), .rst(rst_125mhz), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -570,24 +565,24 @@ udp_payload_fifo ( .rst(rst_125mhz), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), .s_axis_tkeep(0), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), .m_axis_tkeep(), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/ML605/fpga_sgmii/tb/test_fpga_core.py b/example/ML605/fpga_sgmii/tb/test_fpga_core.py index ddf35e258..259f76a41 100755 --- a/example/ML605/fpga_sgmii/tb/test_fpga_core.py +++ b/example/ML605/fpga_sgmii/tb/test_fpga_core.py @@ -53,14 +53,12 @@ srcs.append("../lib/eth/rtl/ip_complete.v") srcs.append("../lib/eth/rtl/ip.v") srcs.append("../lib/eth/rtl/ip_eth_rx.v") srcs.append("../lib/eth/rtl/ip_eth_tx.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") -srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx.v") srcs.append("../lib/eth/rtl/arp_eth_tx.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") -srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") diff --git a/example/NexysVideo/fpga/fpga/Makefile b/example/NexysVideo/fpga/fpga/Makefile index 7fc84a388..744125aca 100644 --- a/example/NexysVideo/fpga/fpga/Makefile +++ b/example/NexysVideo/fpga/fpga/Makefile @@ -32,14 +32,12 @@ SYN_FILES += lib/eth/rtl/ip_complete.v SYN_FILES += lib/eth/rtl/ip.v SYN_FILES += lib/eth/rtl/ip_eth_rx.v SYN_FILES += lib/eth/rtl/ip_eth_tx.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v -SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx.v SYN_FILES += lib/eth/rtl/arp_eth_tx.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v -SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/NexysVideo/fpga/rtl/fpga_core.v b/example/NexysVideo/fpga/rtl/fpga_core.v index 029b5a39c..96e4a83a0 100644 --- a/example/NexysVideo/fpga/rtl/fpga_core.v +++ b/example/NexysVideo/fpga/rtl/fpga_core.v @@ -92,22 +92,22 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [7:0] rx_eth_payload_tdata; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [7:0] rx_eth_payload_axis_tdata; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [7:0] tx_eth_payload_tdata; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [7:0] tx_eth_payload_axis_tdata; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -128,11 +128,11 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [7:0] rx_ip_payload_tdata; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [7:0] rx_ip_payload_axis_tdata; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -143,11 +143,11 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [7:0] tx_ip_payload_tdata; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [7:0] tx_ip_payload_axis_tdata; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -172,11 +172,11 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [7:0] rx_udp_payload_tdata; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [7:0] rx_udp_payload_axis_tdata; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -189,23 +189,23 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [7:0] tx_udp_payload_tdata; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [7:0] rx_fifo_udp_payload_tdata; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [7:0] rx_fifo_udp_payload_axis_tdata; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [7:0] tx_fifo_udp_payload_tdata; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [7:0] tx_fifo_udp_payload_axis_tdata; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -215,7 +215,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -225,14 +225,14 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -242,9 +242,9 @@ always @(posedge clk) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -255,8 +255,8 @@ always @(posedge clk) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -266,23 +266,18 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -292,12 +287,12 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - if (tx_udp_payload_tvalid) begin - if (~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; valid_last <= 1'b1; end - if (tx_udp_payload_tlast) begin + if (tx_udp_payload_axis_tlast) begin valid_last <= 1'b0; end end @@ -306,7 +301,7 @@ end //assign led = sw; assign led = led_reg; -assign phy_reset_n = ~rst; +assign phy_reset_n = !rst; assign uart_txd = 0; @@ -366,22 +361,22 @@ eth_axis_rx_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -392,22 +387,22 @@ eth_axis_tx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -417,111 +412,111 @@ udp_complete_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -559,24 +554,24 @@ udp_payload_fifo ( .rst(rst), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), .s_axis_tkeep(0), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), .m_axis_tkeep(), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/NexysVideo/fpga/tb/test_fpga_core.py b/example/NexysVideo/fpga/tb/test_fpga_core.py index a4569af8b..c320ac269 100755 --- a/example/NexysVideo/fpga/tb/test_fpga_core.py +++ b/example/NexysVideo/fpga/tb/test_fpga_core.py @@ -59,14 +59,12 @@ srcs.append("../lib/eth/rtl/ip_complete.v") srcs.append("../lib/eth/rtl/ip.v") srcs.append("../lib/eth/rtl/ip_eth_rx.v") srcs.append("../lib/eth/rtl/ip_eth_tx.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") -srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx.v") srcs.append("../lib/eth/rtl/arp_eth_tx.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") -srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 998fb7f8f..189ef49bb 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -32,14 +32,12 @@ SYN_FILES += lib/eth/rtl/ip_complete_64.v SYN_FILES += lib/eth/rtl/ip_64.v SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_64_2.v -SYN_FILES += lib/eth/rtl/ip_mux_64_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp_64.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_64_2.v -SYN_FILES += lib/eth/rtl/eth_mux_64_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_adapter.v diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index aad908db8..29b444e70 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -131,24 +131,24 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [63:0] rx_eth_payload_tdata; -wire [7:0] rx_eth_payload_tkeep; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [63:0] rx_eth_payload_axis_tdata; +wire [7:0] rx_eth_payload_axis_tkeep; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [63:0] tx_eth_payload_tdata; -wire [7:0] tx_eth_payload_tkeep; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [63:0] tx_eth_payload_axis_tdata; +wire [7:0] tx_eth_payload_axis_tkeep; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -169,12 +169,12 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [63:0] rx_ip_payload_tdata; -wire [7:0] rx_ip_payload_tkeep; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [63:0] rx_ip_payload_axis_tdata; +wire [7:0] rx_ip_payload_axis_tkeep; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -185,12 +185,12 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [63:0] tx_ip_payload_tdata; -wire [7:0] tx_ip_payload_tkeep; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [63:0] tx_ip_payload_axis_tdata; +wire [7:0] tx_ip_payload_axis_tkeep; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -215,12 +215,12 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [63:0] rx_udp_payload_tdata; -wire [7:0] rx_udp_payload_tkeep; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [63:0] rx_udp_payload_axis_tdata; +wire [7:0] rx_udp_payload_axis_tkeep; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -233,26 +233,26 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [63:0] tx_udp_payload_tdata; -wire [7:0] tx_udp_payload_tkeep; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [63:0] tx_udp_payload_axis_tdata; +wire [7:0] tx_udp_payload_axis_tkeep; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [63:0] rx_fifo_udp_payload_tdata; -wire [7:0] rx_fifo_udp_payload_tkeep; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [63:0] rx_fifo_udp_payload_axis_tdata; +wire [7:0] rx_fifo_udp_payload_axis_tkeep; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [63:0] tx_fifo_udp_payload_tdata; -wire [7:0] tx_fifo_udp_payload_tkeep; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [63:0] tx_fifo_udp_payload_axis_tdata; +wire [7:0] tx_fifo_udp_payload_axis_tkeep; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -262,7 +262,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -272,15 +272,15 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tkeep = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tkeep = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -290,9 +290,9 @@ always @(posedge clk) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -303,8 +303,8 @@ always @(posedge clk) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -314,26 +314,20 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tkeep = rx_udp_payload_tkeep; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tkeep = tx_fifo_udp_payload_tkeep; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tkeep = rx_udp_payload_tkeep; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -343,16 +337,16 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - valid_last <= tx_udp_payload_tvalid; - if (tx_udp_payload_tvalid & ~valid_last) begin - led_reg <= tx_udp_payload_tdata; + valid_last <= tx_udp_payload_axis_tvalid; + if (tx_udp_payload_axis_tvalid && !valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; end end end //assign led = sw; assign led = led_reg; -assign phy_reset_n = ~rst; +assign phy_reset_n = !rst; assign qsfp_txd_2 = 64'h0707070707070707; assign qsfp_txc_2 = 8'hff; @@ -625,24 +619,24 @@ eth_axis_rx_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tkeep(rx_axis_tkeep), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tkeep(rx_axis_tkeep), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tkeep(rx_eth_payload_tkeep), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -653,24 +647,24 @@ eth_axis_tx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tkeep(tx_eth_payload_tkeep), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tkeep(tx_axis_tkeep), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tkeep(tx_axis_tkeep), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -680,117 +674,117 @@ udp_complete_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tkeep(rx_eth_payload_tkeep), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tkeep(tx_eth_payload_tkeep), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tkeep(tx_ip_payload_tkeep), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tkeep(rx_ip_payload_tkeep), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tkeep(tx_udp_payload_tkeep), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tkeep(rx_udp_payload_tkeep), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -829,24 +823,24 @@ udp_payload_fifo ( .rst(rst), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), - .s_axis_tkeep(rx_fifo_udp_payload_tkeep), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), - .m_axis_tkeep(tx_fifo_udp_payload_tkeep), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index 329c744a4..ada6a5e36 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -60,14 +60,12 @@ srcs.append("../lib/eth/rtl/ip_complete_64.v") srcs.append("../lib/eth/rtl/ip_64.v") srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_64_2.v") -srcs.append("../lib/eth/rtl/ip_mux_64_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp_64.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") -srcs.append("../lib/eth/rtl/eth_mux_64_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_adapter.v") diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index 0813b174f..299cf00d4 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -26,14 +26,12 @@ SYN_FILES += lib/eth/rtl/ip_complete.v SYN_FILES += lib/eth/rtl/ip.v SYN_FILES += lib/eth/rtl/ip_eth_rx.v SYN_FILES += lib/eth/rtl/ip_eth_tx.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v -SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx.v SYN_FILES += lib/eth/rtl/arp_eth_tx.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v -SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/VCU108/fpga_1g/rtl/fpga_core.v b/example/VCU108/fpga_1g/rtl/fpga_core.v index a04cf559f..f2cf9cc56 100644 --- a/example/VCU108/fpga_1g/rtl/fpga_core.v +++ b/example/VCU108/fpga_1g/rtl/fpga_core.v @@ -70,7 +70,7 @@ module fpga_core input wire uart_rxd, output wire uart_txd, output wire uart_rts, - input wire uart_cts + input wire uart_cts ); // AXI between MAC and Ethernet modules @@ -92,22 +92,22 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [7:0] rx_eth_payload_tdata; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [7:0] rx_eth_payload_axis_tdata; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [7:0] tx_eth_payload_tdata; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [7:0] tx_eth_payload_axis_tdata; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -128,11 +128,11 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [7:0] rx_ip_payload_tdata; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [7:0] rx_ip_payload_axis_tdata; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -143,11 +143,11 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [7:0] tx_ip_payload_tdata; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [7:0] tx_ip_payload_axis_tdata; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -172,11 +172,11 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [7:0] rx_udp_payload_tdata; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [7:0] rx_udp_payload_axis_tdata; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -189,23 +189,23 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [7:0] tx_udp_payload_tdata; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [7:0] rx_fifo_udp_payload_tdata; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [7:0] rx_fifo_udp_payload_axis_tdata; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [7:0] tx_fifo_udp_payload_tdata; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [7:0] tx_fifo_udp_payload_axis_tdata; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -215,7 +215,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -225,14 +225,14 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -242,9 +242,9 @@ always @(posedge clk) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -255,8 +255,8 @@ always @(posedge clk) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -266,23 +266,18 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -292,12 +287,12 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - if (tx_udp_payload_tvalid) begin - if (~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; valid_last <= 1'b1; end - if (tx_udp_payload_tlast) begin + if (tx_udp_payload_axis_tlast) begin valid_last <= 1'b0; end end @@ -306,7 +301,7 @@ end //assign led = sw; assign led = led_reg; -assign phy_reset_n = ~rst; +assign phy_reset_n = !rst; assign uart_txd = 0; assign uart_rts = 0; @@ -368,22 +363,22 @@ eth_axis_rx_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -394,22 +389,22 @@ eth_axis_tx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -419,111 +414,111 @@ udp_complete_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -561,24 +556,24 @@ udp_payload_fifo ( .rst(rst), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), .s_axis_tkeep(0), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), .m_axis_tkeep(), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.py b/example/VCU108/fpga_1g/tb/test_fpga_core.py index 11e9347d0..97523fc5a 100755 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.py @@ -53,14 +53,12 @@ srcs.append("../lib/eth/rtl/ip_complete.v") srcs.append("../lib/eth/rtl/ip.v") srcs.append("../lib/eth/rtl/ip_eth_rx.v") srcs.append("../lib/eth/rtl/ip_eth_tx.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") -srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx.v") srcs.append("../lib/eth/rtl/arp_eth_tx.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") -srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile index e3519532f..82fc9d2b3 100644 --- a/example/VCU118/fpga_10g/fpga/Makefile +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -31,14 +31,12 @@ SYN_FILES += lib/eth/rtl/ip_complete_64.v SYN_FILES += lib/eth/rtl/ip_64.v SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_64_2.v -SYN_FILES += lib/eth/rtl/ip_mux_64_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp_64.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_64_2.v -SYN_FILES += lib/eth/rtl/eth_mux_64_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_adapter.v diff --git a/example/VCU118/fpga_10g/rtl/fpga_core.v b/example/VCU118/fpga_10g/rtl/fpga_core.v index 21bca8105..f25b16d22 100644 --- a/example/VCU118/fpga_10g/rtl/fpga_core.v +++ b/example/VCU118/fpga_10g/rtl/fpga_core.v @@ -179,24 +179,24 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [63:0] rx_eth_payload_tdata; -wire [7:0] rx_eth_payload_tkeep; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [63:0] rx_eth_payload_axis_tdata; +wire [7:0] rx_eth_payload_axis_tkeep; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [63:0] tx_eth_payload_tdata; -wire [7:0] tx_eth_payload_tkeep; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [63:0] tx_eth_payload_axis_tdata; +wire [7:0] tx_eth_payload_axis_tkeep; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -217,12 +217,12 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [63:0] rx_ip_payload_tdata; -wire [7:0] rx_ip_payload_tkeep; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [63:0] rx_ip_payload_axis_tdata; +wire [7:0] rx_ip_payload_axis_tkeep; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -233,12 +233,12 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [63:0] tx_ip_payload_tdata; -wire [7:0] tx_ip_payload_tkeep; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [63:0] tx_ip_payload_axis_tdata; +wire [7:0] tx_ip_payload_axis_tkeep; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -263,12 +263,12 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [63:0] rx_udp_payload_tdata; -wire [7:0] rx_udp_payload_tkeep; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [63:0] rx_udp_payload_axis_tdata; +wire [7:0] rx_udp_payload_axis_tkeep; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -281,26 +281,26 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [63:0] tx_udp_payload_tdata; -wire [7:0] tx_udp_payload_tkeep; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [63:0] tx_udp_payload_axis_tdata; +wire [7:0] tx_udp_payload_axis_tkeep; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [63:0] rx_fifo_udp_payload_tdata; -wire [7:0] rx_fifo_udp_payload_tkeep; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [63:0] rx_fifo_udp_payload_axis_tdata; +wire [7:0] rx_fifo_udp_payload_axis_tkeep; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [63:0] tx_fifo_udp_payload_tdata; -wire [7:0] tx_fifo_udp_payload_tkeep; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [63:0] tx_fifo_udp_payload_axis_tdata; +wire [7:0] tx_fifo_udp_payload_axis_tkeep; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -310,7 +310,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -320,15 +320,15 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tkeep = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tkeep = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -338,9 +338,9 @@ always @(posedge clk) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -351,8 +351,8 @@ always @(posedge clk) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -362,26 +362,20 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tkeep = rx_udp_payload_tkeep; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tkeep = tx_fifo_udp_payload_tkeep; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tkeep = rx_udp_payload_tkeep; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -391,16 +385,16 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - valid_last <= tx_udp_payload_tvalid; - if (tx_udp_payload_tvalid & ~valid_last) begin - led_reg <= tx_udp_payload_tdata; + valid_last <= tx_udp_payload_axis_tvalid; + if (tx_udp_payload_axis_tvalid && !valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; end end end //assign led = sw; assign led = led_reg; -assign phy_reset_n = ~rst; +assign phy_reset_n = !rst; assign qsfp1_txd_2 = 64'h0707070707070707; assign qsfp1_txc_2 = 8'hff; @@ -682,24 +676,24 @@ eth_axis_rx_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tkeep(rx_axis_tkeep), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tkeep(rx_axis_tkeep), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tkeep(rx_eth_payload_tkeep), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -710,24 +704,24 @@ eth_axis_tx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tkeep(tx_eth_payload_tkeep), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tkeep(tx_axis_tkeep), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tkeep(tx_axis_tkeep), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -737,117 +731,117 @@ udp_complete_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tkeep(rx_eth_payload_tkeep), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tkeep(tx_eth_payload_tkeep), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tkeep(tx_ip_payload_tkeep), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tkeep(rx_ip_payload_tkeep), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tkeep(tx_udp_payload_tkeep), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tkeep(rx_udp_payload_tkeep), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -886,24 +880,24 @@ udp_payload_fifo ( .rst(rst), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), - .s_axis_tkeep(rx_fifo_udp_payload_tkeep), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), - .m_axis_tkeep(tx_fifo_udp_payload_tkeep), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/VCU118/fpga_10g/tb/test_fpga_core.py b/example/VCU118/fpga_10g/tb/test_fpga_core.py index b692d2b32..00ed0dd0c 100755 --- a/example/VCU118/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU118/fpga_10g/tb/test_fpga_core.py @@ -60,14 +60,12 @@ srcs.append("../lib/eth/rtl/ip_complete_64.v") srcs.append("../lib/eth/rtl/ip_64.v") srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_64_2.v") -srcs.append("../lib/eth/rtl/ip_mux_64_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp_64.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") -srcs.append("../lib/eth/rtl/eth_mux_64_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_adapter.v") diff --git a/example/VCU118/fpga_1g/fpga/Makefile b/example/VCU118/fpga_1g/fpga/Makefile index ce1fcc41f..834f771ba 100644 --- a/example/VCU118/fpga_1g/fpga/Makefile +++ b/example/VCU118/fpga_1g/fpga/Makefile @@ -27,14 +27,12 @@ SYN_FILES += lib/eth/rtl/ip_complete.v SYN_FILES += lib/eth/rtl/ip.v SYN_FILES += lib/eth/rtl/ip_eth_rx.v SYN_FILES += lib/eth/rtl/ip_eth_tx.v -SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v -SYN_FILES += lib/eth/rtl/ip_mux_2.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v SYN_FILES += lib/eth/rtl/arp.v SYN_FILES += lib/eth/rtl/arp_cache.v SYN_FILES += lib/eth/rtl/arp_eth_rx.v SYN_FILES += lib/eth/rtl/arp_eth_tx.v -SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v -SYN_FILES += lib/eth/rtl/eth_mux_2.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v diff --git a/example/VCU118/fpga_1g/rtl/fpga_core.v b/example/VCU118/fpga_1g/rtl/fpga_core.v index a04cf559f..f2cf9cc56 100644 --- a/example/VCU118/fpga_1g/rtl/fpga_core.v +++ b/example/VCU118/fpga_1g/rtl/fpga_core.v @@ -70,7 +70,7 @@ module fpga_core input wire uart_rxd, output wire uart_txd, output wire uart_rts, - input wire uart_cts + input wire uart_cts ); // AXI between MAC and Ethernet modules @@ -92,22 +92,22 @@ wire rx_eth_hdr_valid; wire [47:0] rx_eth_dest_mac; wire [47:0] rx_eth_src_mac; wire [15:0] rx_eth_type; -wire [7:0] rx_eth_payload_tdata; -wire rx_eth_payload_tvalid; -wire rx_eth_payload_tready; -wire rx_eth_payload_tlast; -wire rx_eth_payload_tuser; +wire [7:0] rx_eth_payload_axis_tdata; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; wire tx_eth_hdr_ready; wire tx_eth_hdr_valid; wire [47:0] tx_eth_dest_mac; wire [47:0] tx_eth_src_mac; wire [15:0] tx_eth_type; -wire [7:0] tx_eth_payload_tdata; -wire tx_eth_payload_tvalid; -wire tx_eth_payload_tready; -wire tx_eth_payload_tlast; -wire tx_eth_payload_tuser; +wire [7:0] tx_eth_payload_axis_tdata; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; // IP frame connections wire rx_ip_hdr_valid; @@ -128,11 +128,11 @@ wire [7:0] rx_ip_protocol; wire [15:0] rx_ip_header_checksum; wire [31:0] rx_ip_source_ip; wire [31:0] rx_ip_dest_ip; -wire [7:0] rx_ip_payload_tdata; -wire rx_ip_payload_tvalid; -wire rx_ip_payload_tready; -wire rx_ip_payload_tlast; -wire rx_ip_payload_tuser; +wire [7:0] rx_ip_payload_axis_tdata; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; wire tx_ip_hdr_valid; wire tx_ip_hdr_ready; @@ -143,11 +143,11 @@ wire [7:0] tx_ip_ttl; wire [7:0] tx_ip_protocol; wire [31:0] tx_ip_source_ip; wire [31:0] tx_ip_dest_ip; -wire [7:0] tx_ip_payload_tdata; -wire tx_ip_payload_tvalid; -wire tx_ip_payload_tready; -wire tx_ip_payload_tlast; -wire tx_ip_payload_tuser; +wire [7:0] tx_ip_payload_axis_tdata; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; // UDP frame connections wire rx_udp_hdr_valid; @@ -172,11 +172,11 @@ wire [15:0] rx_udp_source_port; wire [15:0] rx_udp_dest_port; wire [15:0] rx_udp_length; wire [15:0] rx_udp_checksum; -wire [7:0] rx_udp_payload_tdata; -wire rx_udp_payload_tvalid; -wire rx_udp_payload_tready; -wire rx_udp_payload_tlast; -wire rx_udp_payload_tuser; +wire [7:0] rx_udp_payload_axis_tdata; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; wire tx_udp_hdr_valid; wire tx_udp_hdr_ready; @@ -189,23 +189,23 @@ wire [15:0] tx_udp_source_port; wire [15:0] tx_udp_dest_port; wire [15:0] tx_udp_length; wire [15:0] tx_udp_checksum; -wire [7:0] tx_udp_payload_tdata; -wire tx_udp_payload_tvalid; -wire tx_udp_payload_tready; -wire tx_udp_payload_tlast; -wire tx_udp_payload_tuser; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; -wire [7:0] rx_fifo_udp_payload_tdata; -wire rx_fifo_udp_payload_tvalid; -wire rx_fifo_udp_payload_tready; -wire rx_fifo_udp_payload_tlast; -wire rx_fifo_udp_payload_tuser; +wire [7:0] rx_fifo_udp_payload_axis_tdata; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; -wire [7:0] tx_fifo_udp_payload_tdata; -wire tx_fifo_udp_payload_tvalid; -wire tx_fifo_udp_payload_tready; -wire tx_fifo_udp_payload_tlast; -wire tx_fifo_udp_payload_tuser; +wire [7:0] tx_fifo_udp_payload_axis_tdata; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; // Configuration wire [47:0] local_mac = 48'h02_00_00_00_00_00; @@ -215,7 +215,7 @@ wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; // IP ports not used assign rx_ip_hdr_ready = 1; -assign rx_ip_payload_tready = 1; +assign rx_ip_payload_axis_tready = 1; assign tx_ip_hdr_valid = 0; assign tx_ip_dscp = 0; @@ -225,14 +225,14 @@ assign tx_ip_ttl = 0; assign tx_ip_protocol = 0; assign tx_ip_source_ip = 0; assign tx_ip_dest_ip = 0; -assign tx_ip_payload_tdata = 0; -assign tx_ip_payload_tvalid = 0; -assign tx_ip_payload_tlast = 0; -assign tx_ip_payload_tuser = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; // Loop back UDP wire match_cond = rx_udp_dest_port == 1234; -wire no_match = ~match_cond; +wire no_match = !match_cond; reg match_cond_reg = 0; reg no_match_reg = 0; @@ -242,9 +242,9 @@ always @(posedge clk) begin match_cond_reg <= 0; no_match_reg <= 0; end else begin - if (rx_udp_payload_tvalid) begin - if ((~match_cond_reg & ~no_match_reg) | - (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_tlast)) begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin match_cond_reg <= match_cond; no_match_reg <= no_match; end @@ -255,8 +255,8 @@ always @(posedge clk) begin end end -assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; -assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; assign tx_udp_ip_dscp = 0; assign tx_udp_ip_ecn = 0; assign tx_udp_ip_ttl = 64; @@ -266,23 +266,18 @@ assign tx_udp_source_port = rx_udp_dest_port; assign tx_udp_dest_port = rx_udp_source_port; assign tx_udp_length = rx_udp_length; assign tx_udp_checksum = 0; -//assign tx_udp_payload_tdata = rx_udp_payload_tdata; -//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; -//assign rx_udp_payload_tready = tx_udp_payload_tready; -//assign tx_udp_payload_tlast = rx_udp_payload_tlast; -//assign tx_udp_payload_tuser = rx_udp_payload_tuser; -assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; -assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; -assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; -assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; -assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; -assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; -assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; -assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; -assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; -assign rx_fifo_udp_payload_tuser = rx_udp_payload_tuser; +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; // Place first payload byte onto LEDs reg valid_last = 0; @@ -292,12 +287,12 @@ always @(posedge clk) begin if (rst) begin led_reg <= 0; end else begin - if (tx_udp_payload_tvalid) begin - if (~valid_last) begin - led_reg <= tx_udp_payload_tdata; + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; valid_last <= 1'b1; end - if (tx_udp_payload_tlast) begin + if (tx_udp_payload_axis_tlast) begin valid_last <= 1'b0; end end @@ -306,7 +301,7 @@ end //assign led = sw; assign led = led_reg; -assign phy_reset_n = ~rst; +assign phy_reset_n = !rst; assign uart_txd = 0; assign uart_rts = 0; @@ -368,22 +363,22 @@ eth_axis_rx_inst ( .clk(clk), .rst(rst), // AXI input - .input_axis_tdata(rx_axis_tdata), - .input_axis_tvalid(rx_axis_tvalid), - .input_axis_tready(rx_axis_tready), - .input_axis_tlast(rx_axis_tlast), - .input_axis_tuser(rx_axis_tuser), + .s_axis_tdata(rx_axis_tdata), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(rx_eth_hdr_valid), - .output_eth_hdr_ready(rx_eth_hdr_ready), - .output_eth_dest_mac(rx_eth_dest_mac), - .output_eth_src_mac(rx_eth_src_mac), - .output_eth_type(rx_eth_type), - .output_eth_payload_tdata(rx_eth_payload_tdata), - .output_eth_payload_tvalid(rx_eth_payload_tvalid), - .output_eth_payload_tready(rx_eth_payload_tready), - .output_eth_payload_tlast(rx_eth_payload_tlast), - .output_eth_payload_tuser(rx_eth_payload_tuser), + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Status signals .busy(), .error_header_early_termination() @@ -394,22 +389,22 @@ eth_axis_tx_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(tx_eth_hdr_valid), - .input_eth_hdr_ready(tx_eth_hdr_ready), - .input_eth_dest_mac(tx_eth_dest_mac), - .input_eth_src_mac(tx_eth_src_mac), - .input_eth_type(tx_eth_type), - .input_eth_payload_tdata(tx_eth_payload_tdata), - .input_eth_payload_tvalid(tx_eth_payload_tvalid), - .input_eth_payload_tready(tx_eth_payload_tready), - .input_eth_payload_tlast(tx_eth_payload_tlast), - .input_eth_payload_tuser(tx_eth_payload_tuser), + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // AXI output - .output_axis_tdata(tx_axis_tdata), - .output_axis_tvalid(tx_axis_tvalid), - .output_axis_tready(tx_axis_tready), - .output_axis_tlast(tx_axis_tlast), - .output_axis_tuser(tx_axis_tuser), + .m_axis_tdata(tx_axis_tdata), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), // Status signals .busy() ); @@ -419,111 +414,111 @@ udp_complete_inst ( .clk(clk), .rst(rst), // Ethernet frame input - .input_eth_hdr_valid(rx_eth_hdr_valid), - .input_eth_hdr_ready(rx_eth_hdr_ready), - .input_eth_dest_mac(rx_eth_dest_mac), - .input_eth_src_mac(rx_eth_src_mac), - .input_eth_type(rx_eth_type), - .input_eth_payload_tdata(rx_eth_payload_tdata), - .input_eth_payload_tvalid(rx_eth_payload_tvalid), - .input_eth_payload_tready(rx_eth_payload_tready), - .input_eth_payload_tlast(rx_eth_payload_tlast), - .input_eth_payload_tuser(rx_eth_payload_tuser), + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), // Ethernet frame output - .output_eth_hdr_valid(tx_eth_hdr_valid), - .output_eth_hdr_ready(tx_eth_hdr_ready), - .output_eth_dest_mac(tx_eth_dest_mac), - .output_eth_src_mac(tx_eth_src_mac), - .output_eth_type(tx_eth_type), - .output_eth_payload_tdata(tx_eth_payload_tdata), - .output_eth_payload_tvalid(tx_eth_payload_tvalid), - .output_eth_payload_tready(tx_eth_payload_tready), - .output_eth_payload_tlast(tx_eth_payload_tlast), - .output_eth_payload_tuser(tx_eth_payload_tuser), + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), // IP frame input - .input_ip_hdr_valid(tx_ip_hdr_valid), - .input_ip_hdr_ready(tx_ip_hdr_ready), - .input_ip_dscp(tx_ip_dscp), - .input_ip_ecn(tx_ip_ecn), - .input_ip_length(tx_ip_length), - .input_ip_ttl(tx_ip_ttl), - .input_ip_protocol(tx_ip_protocol), - .input_ip_source_ip(tx_ip_source_ip), - .input_ip_dest_ip(tx_ip_dest_ip), - .input_ip_payload_tdata(tx_ip_payload_tdata), - .input_ip_payload_tvalid(tx_ip_payload_tvalid), - .input_ip_payload_tready(tx_ip_payload_tready), - .input_ip_payload_tlast(tx_ip_payload_tlast), - .input_ip_payload_tuser(tx_ip_payload_tuser), + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), // IP frame output - .output_ip_hdr_valid(rx_ip_hdr_valid), - .output_ip_hdr_ready(rx_ip_hdr_ready), - .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), - .output_ip_eth_src_mac(rx_ip_eth_src_mac), - .output_ip_eth_type(rx_ip_eth_type), - .output_ip_version(rx_ip_version), - .output_ip_ihl(rx_ip_ihl), - .output_ip_dscp(rx_ip_dscp), - .output_ip_ecn(rx_ip_ecn), - .output_ip_length(rx_ip_length), - .output_ip_identification(rx_ip_identification), - .output_ip_flags(rx_ip_flags), - .output_ip_fragment_offset(rx_ip_fragment_offset), - .output_ip_ttl(rx_ip_ttl), - .output_ip_protocol(rx_ip_protocol), - .output_ip_header_checksum(rx_ip_header_checksum), - .output_ip_source_ip(rx_ip_source_ip), - .output_ip_dest_ip(rx_ip_dest_ip), - .output_ip_payload_tdata(rx_ip_payload_tdata), - .output_ip_payload_tvalid(rx_ip_payload_tvalid), - .output_ip_payload_tready(rx_ip_payload_tready), - .output_ip_payload_tlast(rx_ip_payload_tlast), - .output_ip_payload_tuser(rx_ip_payload_tuser), + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), // UDP frame input - .input_udp_hdr_valid(tx_udp_hdr_valid), - .input_udp_hdr_ready(tx_udp_hdr_ready), - .input_udp_ip_dscp(tx_udp_ip_dscp), - .input_udp_ip_ecn(tx_udp_ip_ecn), - .input_udp_ip_ttl(tx_udp_ip_ttl), - .input_udp_ip_source_ip(tx_udp_ip_source_ip), - .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), - .input_udp_source_port(tx_udp_source_port), - .input_udp_dest_port(tx_udp_dest_port), - .input_udp_length(tx_udp_length), - .input_udp_checksum(tx_udp_checksum), - .input_udp_payload_tdata(tx_udp_payload_tdata), - .input_udp_payload_tvalid(tx_udp_payload_tvalid), - .input_udp_payload_tready(tx_udp_payload_tready), - .input_udp_payload_tlast(tx_udp_payload_tlast), - .input_udp_payload_tuser(tx_udp_payload_tuser), + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), // UDP frame output - .output_udp_hdr_valid(rx_udp_hdr_valid), - .output_udp_hdr_ready(rx_udp_hdr_ready), - .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), - .output_udp_eth_src_mac(rx_udp_eth_src_mac), - .output_udp_eth_type(rx_udp_eth_type), - .output_udp_ip_version(rx_udp_ip_version), - .output_udp_ip_ihl(rx_udp_ip_ihl), - .output_udp_ip_dscp(rx_udp_ip_dscp), - .output_udp_ip_ecn(rx_udp_ip_ecn), - .output_udp_ip_length(rx_udp_ip_length), - .output_udp_ip_identification(rx_udp_ip_identification), - .output_udp_ip_flags(rx_udp_ip_flags), - .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), - .output_udp_ip_ttl(rx_udp_ip_ttl), - .output_udp_ip_protocol(rx_udp_ip_protocol), - .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), - .output_udp_ip_source_ip(rx_udp_ip_source_ip), - .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), - .output_udp_source_port(rx_udp_source_port), - .output_udp_dest_port(rx_udp_dest_port), - .output_udp_length(rx_udp_length), - .output_udp_checksum(rx_udp_checksum), - .output_udp_payload_tdata(rx_udp_payload_tdata), - .output_udp_payload_tvalid(rx_udp_payload_tvalid), - .output_udp_payload_tready(rx_udp_payload_tready), - .output_udp_payload_tlast(rx_udp_payload_tlast), - .output_udp_payload_tuser(rx_udp_payload_tuser), + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), // Status signals .ip_rx_busy(), .ip_tx_busy(), @@ -561,24 +556,24 @@ udp_payload_fifo ( .rst(rst), // AXI input - .s_axis_tdata(rx_fifo_udp_payload_tdata), + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), .s_axis_tkeep(0), - .s_axis_tvalid(rx_fifo_udp_payload_tvalid), - .s_axis_tready(rx_fifo_udp_payload_tready), - .s_axis_tlast(rx_fifo_udp_payload_tlast), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_udp_payload_tuser), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), // AXI output - .m_axis_tdata(tx_fifo_udp_payload_tdata), + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), .m_axis_tkeep(), - .m_axis_tvalid(tx_fifo_udp_payload_tvalid), - .m_axis_tready(tx_fifo_udp_payload_tready), - .m_axis_tlast(tx_fifo_udp_payload_tlast), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(tx_fifo_udp_payload_tuser), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), // Status .status_overflow(), diff --git a/example/VCU118/fpga_1g/tb/test_fpga_core.py b/example/VCU118/fpga_1g/tb/test_fpga_core.py index 11e9347d0..97523fc5a 100755 --- a/example/VCU118/fpga_1g/tb/test_fpga_core.py +++ b/example/VCU118/fpga_1g/tb/test_fpga_core.py @@ -53,14 +53,12 @@ srcs.append("../lib/eth/rtl/ip_complete.v") srcs.append("../lib/eth/rtl/ip.v") srcs.append("../lib/eth/rtl/ip_eth_rx.v") srcs.append("../lib/eth/rtl/ip_eth_tx.v") -srcs.append("../lib/eth/rtl/ip_arb_mux_2.v") -srcs.append("../lib/eth/rtl/ip_mux_2.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") srcs.append("../lib/eth/rtl/arp.v") srcs.append("../lib/eth/rtl/arp_cache.v") srcs.append("../lib/eth/rtl/arp_eth_rx.v") srcs.append("../lib/eth/rtl/arp_eth_tx.v") -srcs.append("../lib/eth/rtl/eth_arb_mux_2.v") -srcs.append("../lib/eth/rtl/eth_mux_2.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") diff --git a/example/VCU118/fpga_1g/tb/test_fpga_core.v b/example/VCU118/fpga_1g/tb/test_fpga_core.v index aa29c4011..e3de43465 100644 --- a/example/VCU118/fpga_1g/tb/test_fpga_core.v +++ b/example/VCU118/fpga_1g/tb/test_fpga_core.v @@ -56,7 +56,6 @@ reg uart_cts = 0; // Outputs wire [7:0] led; -wire phy_tx_clk; wire [7:0] phy_gmii_txd; wire phy_gmii_tx_en; wire phy_gmii_tx_er; From e882ed143fd2f73ce215c9ac4137d2e2d88f78ca Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 8 Nov 2018 09:20:33 -0800 Subject: [PATCH 473/617] Update example designs --- example/VCU108/fpga_1g/tb/test_fpga_core.v | 1 - example/VCU118/fpga_10g/rtl/fpga_core.v | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/example/VCU108/fpga_1g/tb/test_fpga_core.v b/example/VCU108/fpga_1g/tb/test_fpga_core.v index aa29c4011..e3de43465 100644 --- a/example/VCU108/fpga_1g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_1g/tb/test_fpga_core.v @@ -56,7 +56,6 @@ reg uart_cts = 0; // Outputs wire [7:0] led; -wire phy_tx_clk; wire [7:0] phy_gmii_txd; wire phy_gmii_tx_en; wire phy_gmii_tx_er; diff --git a/example/VCU118/fpga_10g/rtl/fpga_core.v b/example/VCU118/fpga_10g/rtl/fpga_core.v index f25b16d22..9fa9a0707 100644 --- a/example/VCU118/fpga_10g/rtl/fpga_core.v +++ b/example/VCU118/fpga_10g/rtl/fpga_core.v @@ -141,7 +141,7 @@ module fpga_core # input wire uart_rxd, output wire uart_txd, output wire uart_rts, - input wire uart_cts + input wire uart_cts ); // AXI between MAC and Ethernet modules From ebe31e811cee9db615a7d5ec8472f972f3368b90 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 8 Nov 2018 13:15:47 -0800 Subject: [PATCH 474/617] Use parameters for control characters --- rtl/axis_gmii_rx.v | 8 ++++++-- rtl/axis_gmii_tx.v | 10 ++++++--- rtl/axis_xgmii_rx_32.v | 20 +++++++++++++----- rtl/axis_xgmii_rx_64.v | 28 ++++++++++++++++--------- rtl/axis_xgmii_tx_32.v | 34 ++++++++++++++++++++----------- rtl/axis_xgmii_tx_64.v | 46 +++++++++++++++++++++++++----------------- 6 files changed, 97 insertions(+), 49 deletions(-) diff --git a/rtl/axis_gmii_rx.v b/rtl/axis_gmii_rx.v index 5e7aede2a..37c11be7e 100644 --- a/rtl/axis_gmii_rx.v +++ b/rtl/axis_gmii_rx.v @@ -62,6 +62,10 @@ module axis_gmii_rx output wire error_bad_fcs ); +localparam [7:0] + ETH_PRE = 8'h55, + ETH_SFD = 8'hD5; + localparam [2:0] STATE_IDLE = 3'd0, STATE_PAYLOAD = 3'd1, @@ -155,7 +159,7 @@ always @* begin // idle state - wait for packet reset_crc = 1'b1; - if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == 8'hD5) begin + if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == ETH_SFD) begin state_next = STATE_PAYLOAD; end else begin state_next = STATE_IDLE; @@ -248,7 +252,7 @@ always @(posedge clk) begin if (mii_locked) begin mii_locked <= gmii_rx_dv; - end else if (gmii_rx_dv && {gmii_rxd[3:0], gmii_rxd_d0[7:4]} == 8'hD5) begin + end else if (gmii_rx_dv && {gmii_rxd[3:0], gmii_rxd_d0[7:4]} == ETH_SFD) begin mii_locked <= 1'b1; mii_odd <= 1'b1; end diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index 73cc95311..7fa2d7ed0 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -66,6 +66,10 @@ module axis_gmii_tx # input wire [7:0] ifg_delay ); +localparam [7:0] + ETH_PRE = 8'h55, + ETH_SFD = 8'hD5; + localparam [2:0] STATE_IDLE = 3'd0, STATE_PREAMBLE = 3'd1, @@ -162,7 +166,7 @@ always @* begin if (s_axis_tvalid) begin mii_odd_next = 1'b1; frame_ptr_next = 16'd1; - gmii_txd_next = 8'h55; // Preamble + gmii_txd_next = ETH_PRE; gmii_tx_en_next = 1'b1; state_next = STATE_PREAMBLE; end else begin @@ -176,7 +180,7 @@ always @* begin mii_odd_next = 1'b1; frame_ptr_next = frame_ptr_reg + 16'd1; - gmii_txd_next = 8'h55; // Preamble + gmii_txd_next = ETH_PRE; gmii_tx_en_next = 1'b1; if (frame_ptr_reg == 16'd6) begin @@ -190,7 +194,7 @@ always @* begin s_axis_tready_next = 1'b1; s_tdata_next = s_axis_tdata; end - gmii_txd_next = 8'hD5; // SFD + gmii_txd_next = ETH_SFD; state_next = STATE_PAYLOAD; end else begin state_next = STATE_PREAMBLE; diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index 94e4858ea..8928a6edc 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -56,6 +56,16 @@ module axis_xgmii_rx_32 output wire error_bad_fcs ); +localparam [7:0] + ETH_PRE = 8'h55, + ETH_SFD = 8'hD5; + +localparam [7:0] + XGMII_IDLE = 8'h07, + XGMII_START = 8'hfb, + XGMII_TERM = 8'hfd, + XGMII_ERROR = 8'hfe; + localparam [2:0] STATE_IDLE = 3'd0, STATE_PREAMBLE = 3'd1, @@ -190,9 +200,9 @@ integer i; always @* begin for (i = 0; i < 4; i = i + 1) begin - detect_start[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfb); - detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfd); - detect_error[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfe); + detect_start[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_START); + detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_TERM); + detect_error[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_ERROR); end end @@ -258,7 +268,7 @@ always @* begin // idle state - wait for packet reset_crc = 1'b1; - if (xgmii_rxc_d2[0] && xgmii_rxd_d2[7:0] == 8'hfb) begin + if (xgmii_rxc_d2[0] && xgmii_rxd_d2[7:0] == XGMII_START) begin // start condition if (detect_error_masked) begin // error in first data word @@ -343,7 +353,7 @@ always @* begin error_bad_fcs_next = 1'b1; end - if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin + if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == XGMII_START) begin // start condition state_next = STATE_PAYLOAD; end else begin diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index 5beb150ca..212aa53ab 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -56,6 +56,16 @@ module axis_xgmii_rx_64 output wire error_bad_fcs ); +localparam [7:0] + ETH_PRE = 8'h55, + ETH_SFD = 8'hD5; + +localparam [7:0] + XGMII_IDLE = 8'h07, + XGMII_START = 8'hfb, + XGMII_TERM = 8'hfd, + XGMII_ERROR = 8'hfe; + localparam [2:0] STATE_IDLE = 3'd0, STATE_PAYLOAD = 3'd1, @@ -207,9 +217,9 @@ integer i; always @* begin for (i = 0; i < 8; i = i + 1) begin - detect_start[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfb); - detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfd); - detect_error[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == 8'hfe); + detect_start[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_START); + detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_TERM); + detect_error[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_ERROR); end end @@ -295,7 +305,7 @@ always @* begin // idle state - wait for packet reset_crc = 1'b1; - if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin + if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == XGMII_START) begin // start condition if (detect_error_masked) begin // error in first data word @@ -379,7 +389,7 @@ always @* begin error_bad_fcs_next = 1'b1; end - if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == 8'hfb) begin + if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == XGMII_START) begin // start condition state_next = STATE_PAYLOAD; end else begin @@ -414,10 +424,10 @@ always @(posedge clk) begin error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; - if (xgmii_rxc[0] && xgmii_rxd[7:0] == 8'hfb) begin + if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin lanes_swapped <= 1'b0; xgmii_rxc_d0 <= xgmii_rxc; - end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == 8'hfb) begin + end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin lanes_swapped <= 1'b1; xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; end else if (lanes_swapped) begin @@ -456,9 +466,9 @@ always @(posedge clk) begin swap_rxd <= xgmii_rxd[63:32]; swap_rxc <= xgmii_rxc[7:4]; - if (xgmii_rxc[0] && xgmii_rxd[7:0] == 8'hfb) begin + if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin xgmii_rxd_d0 <= xgmii_rxd; - end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == 8'hfb) begin + end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; end else if (lanes_swapped) begin xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index e0e6c7c68..3e9cc8762 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -65,6 +65,16 @@ localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfffc; localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0003; +localparam [7:0] + ETH_PRE = 8'h55, + ETH_SFD = 8'hD5; + +localparam [7:0] + XGMII_IDLE = 8'h07, + XGMII_START = 8'hfb, + XGMII_TERM = 8'hfd, + XGMII_ERROR = 8'hfe; + localparam [3:0] STATE_IDLE = 4'd0, STATE_PREAMBLE = 4'd1, @@ -110,7 +120,7 @@ wire [31:0] crc_next1; wire [31:0] crc_next2; wire [31:0] crc_next3; -reg [31:0] xgmii_txd_reg = 32'h07070707, xgmii_txd_next; +reg [31:0] xgmii_txd_reg = {4{XGMII_IDLE}}, xgmii_txd_next; reg [3:0] xgmii_txc_reg = 4'b1111, xgmii_txc_next; assign s_axis_tready = s_axis_tready_reg; @@ -218,7 +228,7 @@ always @* begin casez (s_tkeep_reg) 4'bzz01: begin fcs_output_txd_0 = {~crc_next0[23:0], s_tdata_reg[7:0]}; - fcs_output_txd_1 = {24'h0707fd, ~crc_next0[31:24]}; + fcs_output_txd_1 = {{2{XGMII_IDLE}}, XGMII_TERM, ~crc_next0[31:24]}; fcs_output_txc_0 = 4'b0000; fcs_output_txc_1 = 4'b1110; ifg_offset = 8'd3; @@ -226,7 +236,7 @@ always @* begin end 4'bz011: begin fcs_output_txd_0 = {~crc_next1[15:0], s_tdata_reg[15:0]}; - fcs_output_txd_1 = {16'h07fd, ~crc_next1[31:16]}; + fcs_output_txd_1 = {XGMII_IDLE, XGMII_TERM, ~crc_next1[31:16]}; fcs_output_txc_0 = 4'b0000; fcs_output_txc_1 = 4'b1100; ifg_offset = 8'd2; @@ -234,7 +244,7 @@ always @* begin end 4'b0111: begin fcs_output_txd_0 = {~crc_next2[7:0], s_tdata_reg[23:0]}; - fcs_output_txd_1 = {16'hfd, ~crc_next2[31:8]}; + fcs_output_txd_1 = {XGMII_TERM, ~crc_next2[31:8]}; fcs_output_txc_0 = 4'b0000; fcs_output_txc_1 = 4'b1000; ifg_offset = 8'd1; @@ -276,7 +286,7 @@ always @* begin s_tkeep_next = s_tkeep_reg; // XGMII idle - xgmii_txd_next = 32'h07070707; + xgmii_txd_next = {4{XGMII_IDLE}}; xgmii_txc_next = 4'b1111; case (state_reg) @@ -286,7 +296,7 @@ always @* begin reset_crc = 1'b1; // XGMII idle - xgmii_txd_next = 32'h07070707; + xgmii_txd_next = {4{XGMII_IDLE}}; xgmii_txc_next = 4'b1111; s_tdata_next = s_axis_tdata_masked; @@ -294,7 +304,7 @@ always @* begin if (s_axis_tvalid) begin // XGMII start and preamble - xgmii_txd_next = 32'h555555fb; + xgmii_txd_next = {{3{ETH_PRE}}, XGMII_START}; xgmii_txc_next = 4'b0001; s_axis_tready_next = 1'b1; state_next = STATE_PREAMBLE; @@ -310,7 +320,7 @@ always @* begin s_tdata_next = s_axis_tdata_masked; s_tkeep_next = s_axis_tkeep; - xgmii_txd_next = 32'hd5555555; + xgmii_txd_next = {ETH_SFD, {3{ETH_PRE}}}; xgmii_txc_next = 4'b0000; s_axis_tready_next = 1'b1; state_next = STATE_PAYLOAD; @@ -333,7 +343,7 @@ always @* begin frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); s_axis_tready_next = 1'b0; if (s_axis_tuser) begin - xgmii_txd_next = 32'h07fdfefe; + xgmii_txd_next = {XGMII_TERM, {3{XGMII_ERROR}}}; xgmii_txc_next = 4'b1111; frame_ptr_next = 16'd0; ifg_count_next = 8'd10; @@ -361,7 +371,7 @@ always @* begin end end else begin // tvalid deassert, fail frame - xgmii_txd_next = 32'h07fdfefe; + xgmii_txd_next = {XGMII_TERM, {3{XGMII_ERROR}}}; xgmii_txc_next = 4'b1111; frame_ptr_next = 16'd0; ifg_count_next = 8'd10; @@ -420,7 +430,7 @@ always @* begin // last cycle s_axis_tready_next = 1'b0; - xgmii_txd_next = 32'h070707fd; + xgmii_txd_next = {{3{XGMII_IDLE}}, XGMII_TERM}; xgmii_txc_next = 4'b1111; reset_crc = 1'b1; @@ -517,7 +527,7 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; - xgmii_txd_reg <= 32'h07070707; + xgmii_txd_reg <= {4{XGMII_IDLE}}; xgmii_txc_reg <= 4'b1111; crc_state <= 32'hFFFFFFFF; diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index 9bdb56ba7..361e3900a 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -65,6 +65,16 @@ localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8; localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007; +localparam [7:0] + ETH_PRE = 8'h55, + ETH_SFD = 8'hD5; + +localparam [7:0] + XGMII_IDLE = 8'h07, + XGMII_START = 8'hfb, + XGMII_TERM = 8'hfd, + XGMII_ERROR = 8'hfe; + localparam [2:0] STATE_IDLE = 3'd0, STATE_PAYLOAD = 3'd1, @@ -119,7 +129,7 @@ wire [31:0] crc_next5; wire [31:0] crc_next6; wire [31:0] crc_next7; -reg [63:0] xgmii_txd_reg = 64'h0707070707070707, xgmii_txd_next; +reg [63:0] xgmii_txd_reg = {8{XGMII_IDLE}}, xgmii_txd_next; reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; assign s_axis_tready = s_axis_tready_reg; @@ -298,24 +308,24 @@ end always @* begin casez (s_tkeep_reg) 8'bzzzzzz01: begin - fcs_output_txd_0 = {24'h0707fd, ~crc_next0[31:0], s_tdata_reg[7:0]}; - fcs_output_txd_1 = {63'h0707070707070707}; + fcs_output_txd_0 = {{2{XGMII_IDLE}}, XGMII_TERM, ~crc_next0[31:0], s_tdata_reg[7:0]}; + fcs_output_txd_1 = {8{XGMII_IDLE}}; fcs_output_txc_0 = 8'b11100000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd3; extra_cycle = 1'b0; end 8'bzzzzz011: begin - fcs_output_txd_0 = {16'h07fd, ~crc_next1[31:0], s_tdata_reg[15:0]}; - fcs_output_txd_1 = {63'h0707070707070707}; + fcs_output_txd_0 = {XGMII_IDLE, XGMII_TERM, ~crc_next1[31:0], s_tdata_reg[15:0]}; + fcs_output_txd_1 = {8{XGMII_IDLE}}; fcs_output_txc_0 = 8'b11000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd2; extra_cycle = 1'b0; end 8'bzzzz0111: begin - fcs_output_txd_0 = {8'hfd, ~crc_next2[31:0], s_tdata_reg[23:0]}; - fcs_output_txd_1 = {63'h0707070707070707}; + fcs_output_txd_0 = {XGMII_TERM, ~crc_next2[31:0], s_tdata_reg[23:0]}; + fcs_output_txd_1 = {8{XGMII_IDLE}}; fcs_output_txc_0 = 8'b10000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd1; @@ -323,7 +333,7 @@ always @* begin end 8'bzzz01111: begin fcs_output_txd_0 = {~crc_next3[31:0], s_tdata_reg[31:0]}; - fcs_output_txd_1 = {63'h07070707070707fd}; + fcs_output_txd_1 = {{7{XGMII_IDLE}}, XGMII_TERM}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd8; @@ -331,7 +341,7 @@ always @* begin end 8'bzz011111: begin fcs_output_txd_0 = {~crc_next4[23:0], s_tdata_reg[39:0]}; - fcs_output_txd_1 = {56'h070707070707fd, ~crc_next4[31:24]}; + fcs_output_txd_1 = {{6{XGMII_IDLE}}, XGMII_TERM, ~crc_next4[31:24]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111110; ifg_offset = 8'd7; @@ -339,7 +349,7 @@ always @* begin end 8'bz0111111: begin fcs_output_txd_0 = {~crc_next5[15:0], s_tdata_reg[47:0]}; - fcs_output_txd_1 = {48'h0707070707fd, ~crc_next5[31:16]}; + fcs_output_txd_1 = {{5{XGMII_IDLE}}, XGMII_TERM, ~crc_next5[31:16]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111100; ifg_offset = 8'd6; @@ -347,7 +357,7 @@ always @* begin end 8'b01111111: begin fcs_output_txd_0 = {~crc_next6[7:0], s_tdata_reg[55:0]}; - fcs_output_txd_1 = {40'h07070707fd, ~crc_next6[31:8]}; + fcs_output_txd_1 = {{4{XGMII_IDLE}}, XGMII_TERM, ~crc_next6[31:8]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11111000; ifg_offset = 8'd5; @@ -355,7 +365,7 @@ always @* begin end 8'b11111111: begin fcs_output_txd_0 = s_tdata_reg; - fcs_output_txd_1 = {32'h070707fd, ~crc_next7[31:0]}; + fcs_output_txd_1 = {{3{XGMII_IDLE}}, XGMII_TERM, ~crc_next7[31:0]}; fcs_output_txc_0 = 8'b00000000; fcs_output_txc_1 = 8'b11110000; ifg_offset = 8'd4; @@ -392,7 +402,7 @@ always @* begin s_tkeep_next = s_tkeep_reg; // XGMII idle - xgmii_txd_next = 64'h0707070707070707; + xgmii_txd_next = {8{XGMII_IDLE}}; xgmii_txc_next = 8'b11111111; case (state_reg) @@ -403,7 +413,7 @@ always @* begin s_axis_tready_next = 1'b1; // XGMII idle - xgmii_txd_next = 64'h0707070707070707; + xgmii_txd_next = {8{XGMII_IDLE}}; xgmii_txc_next = 8'b11111111; s_tdata_next = s_axis_tdata_masked; @@ -418,7 +428,7 @@ always @* begin // no more idles - unswap unswap_lanes = 1'b1; end - xgmii_txd_next = 64'hd5555555555555fb; + xgmii_txd_next = {ETH_SFD, {6{ETH_PRE}}, XGMII_START}; xgmii_txc_next = 8'b00000001; s_axis_tready_next = 1'b1; state_next = STATE_PAYLOAD; @@ -447,7 +457,7 @@ always @* begin frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); s_axis_tready_next = 1'b0; if (s_axis_tuser) begin - xgmii_txd_next = 64'h070707fdfefefefe; + xgmii_txd_next = {{3{XGMII_IDLE}}, XGMII_TERM, {4{XGMII_ERROR}}}; xgmii_txc_next = 8'b11111111; frame_ptr_next = 16'd0; ifg_count_next = 8'd8; @@ -475,7 +485,7 @@ always @* begin end end else begin // tvalid deassert, fail frame - xgmii_txd_next = 64'h070707fdfefefefe; + xgmii_txd_next = {{3{XGMII_IDLE}}, XGMII_TERM, {4{XGMII_ERROR}}}; xgmii_txc_next = 8'b11111111; frame_ptr_next = 16'd0; ifg_count_next = 8'd8; @@ -637,7 +647,7 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; - xgmii_txd_reg <= 64'h0707070707070707; + xgmii_txd_reg <= {8{XGMII_IDLE}}; xgmii_txc_reg <= 8'b11111111; crc_state <= 32'hFFFFFFFF; From 6b85aed564a7a3667e630d2c6eac84ea9f54f3d7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 8 Nov 2018 13:34:32 -0800 Subject: [PATCH 475/617] Any control characters in packet considered an error --- rtl/axis_xgmii_rx_32.v | 4 ++-- rtl/axis_xgmii_rx_64.v | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index 8928a6edc..5e6e2012e 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -270,8 +270,8 @@ always @* begin if (xgmii_rxc_d2[0] && xgmii_rxd_d2[7:0] == XGMII_START) begin // start condition - if (detect_error_masked) begin - // error in first data word + if (control_masked) begin + // control or error characters in first data word m_axis_tdata_next = 32'd0; m_axis_tkeep_next = 4'h1; m_axis_tvalid_next = 1'b1; diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index 212aa53ab..3d50af09c 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -307,8 +307,8 @@ always @* begin if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == XGMII_START) begin // start condition - if (detect_error_masked) begin - // error in first data word + if (control_masked) begin + // control or error characters in first data word m_axis_tdata_next = 64'd0; m_axis_tkeep_next = 8'h01; m_axis_tvalid_next = 1'b1; From 261ad46a8a642e4535264a57c497eccd9fe10984 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 9 Nov 2018 16:47:19 -0800 Subject: [PATCH 476/617] Add enable signals to xgmii model --- tb/xgmii_ep.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 4c1b733ed..22131e937 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -122,6 +122,7 @@ class XGMIISource(object): rst, txd, txc, + enable=True, name=None ): @@ -154,7 +155,7 @@ class XGMIISource(object): ifg_cnt = 0 deficit_idle_cnt = 0 nt = False - else: + elif enable: if ifg_cnt > bw-1: ifg_cnt -= bw txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 @@ -258,6 +259,7 @@ class XGMIISink(object): rst, rxd, rxc, + enable=True, name=None ): @@ -282,7 +284,7 @@ class XGMIISink(object): frame = None d = [] c = [] - else: + elif enable: if frame is None: if rxc & 1 and rxd & 0xff == 0xfb: # start in lane 0 From d59a0553bd8e450720cbcf8a2e943778d923066c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 9 Nov 2018 16:51:54 -0800 Subject: [PATCH 477/617] Change start character handling --- tb/xgmii_ep.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 22131e937..741544a31 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -193,17 +193,18 @@ class XGMIISource(object): ifg_cnt = 0 assert len(dl) > 0 - assert dl.pop(0) == 0x55 - cl.pop(0) + assert dl[0] == 0x55 + dl[0] = 0xfb + cl[0] = 1 - k = 1 - d = 0xfb - c = 1 + k = 0 + d = 0 + c = 0 if ifg_cnt > 0: - k = 5 - d = 0xfb07070707 - c = 0x1f + k = 4 + d = 0x07070707 + c = 0xf for i in range(k,bw): if len(dl) > 0: From 0159376cda9c03cac63dbccbca3ad02d9516f8e7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 10 Nov 2018 17:35:31 -0800 Subject: [PATCH 478/617] Simplify IFG count handling --- tb/xgmii_ep.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 741544a31..7ec9585a3 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -186,12 +186,6 @@ class XGMIISource(object): if name is not None: print("[%s] Sending frame %s" % (name, repr(frame))) - if ifg_cnt >= 4: - deficit_idle_cnt = ifg_cnt - 4 - else: - deficit_idle_cnt = ifg_cnt - ifg_cnt = 0 - assert len(dl) > 0 assert dl[0] == 0x55 dl[0] = 0xfb @@ -201,11 +195,15 @@ class XGMIISource(object): d = 0 c = 0 - if ifg_cnt > 0: + if bw == 8 and ifg_cnt >= 4: + ifg_cnt = max(ifg_cnt-4, 0) k = 4 d = 0x07070707 c = 0xf + deficit_idle_cnt = ifg_cnt + ifg_cnt = 0 + for i in range(k,bw): if len(dl) > 0: d |= dl.pop(0) << (8*i) From b6c8cc71253edb73d5f1f9abe9228041f0a4165a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 10 Nov 2018 18:16:30 -0800 Subject: [PATCH 479/617] Append termination control character --- tb/xgmii_ep.py | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 7ec9585a3..2ce3fccba 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -141,7 +141,6 @@ class XGMIISource(object): cl = [] ifg_cnt = 0 deficit_idle_cnt = 0 - nt = False while True: yield clk.posedge, rst.posedge @@ -154,28 +153,23 @@ class XGMIISource(object): cl = [] ifg_cnt = 0 deficit_idle_cnt = 0 - nt = False elif enable: if ifg_cnt > bw-1: ifg_cnt -= bw txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 txc.next = 0xff if bw == 8 else 0xf - elif len(dl) > 0 or nt: + elif dl: d = 0 c = 0 for i in range(bw): - if len(dl) > 0: + if dl: d |= dl.pop(0) << (8*i) c |= cl.pop(0) << i - nt = True - else: - if nt: - d |= 0xfd << (8*i) - nt = False + if not dl: ifg_cnt = 12 - (bw-i) + deficit_idle_cnt - else: - d |= 0x07 << (8*i) + else: + d |= 0x07 << (8*i) c |= 1 << i txd.next = d @@ -190,6 +184,8 @@ class XGMIISource(object): assert dl[0] == 0x55 dl[0] = 0xfb cl[0] = 1 + dl.append(0xfd) + cl.append(1) k = 0 d = 0 @@ -205,17 +201,9 @@ class XGMIISource(object): ifg_cnt = 0 for i in range(k,bw): - if len(dl) > 0: + if dl: d |= dl.pop(0) << (8*i) c |= cl.pop(0) << i - nt = True - else: - if nt: - d |= 0xfd << (8*i) - nt = False - else: - d |= 0x07 << (8*i) - c |= 1 << i txd.next = d txc.next = c From a49b78b3c3209fbcfeecd7c9d82964edd0fd4c89 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 10 Nov 2018 18:23:31 -0800 Subject: [PATCH 480/617] Add width asserts --- tb/xgmii_ep.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 2ce3fccba..b5cb41fc8 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -131,6 +131,7 @@ class XGMIISource(object): self.has_logic = True assert len(txd) in [32, 64] + assert len(txd) == len(txc)*8 bw = int(len(txd)/8) @@ -255,6 +256,7 @@ class XGMIISink(object): self.has_logic = True assert len(rxd) in [32, 64] + assert len(rxd) == len(rxc)*8 bw = int(len(rxd)/8) From b195c6450b170683b985f99dd5897c2de1068a77 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 10 Nov 2018 18:23:44 -0800 Subject: [PATCH 481/617] Add IFG parameter --- tb/xgmii_ep.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index b5cb41fc8..c35f0a597 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -123,6 +123,7 @@ class XGMIISource(object): txd, txc, enable=True, + ifg=12, name=None ): @@ -168,7 +169,7 @@ class XGMIISource(object): d |= dl.pop(0) << (8*i) c |= cl.pop(0) << i if not dl: - ifg_cnt = 12 - (bw-i) + deficit_idle_cnt + ifg_cnt = max(ifg, 12) - (bw-i) + deficit_idle_cnt else: d |= 0x07 << (8*i) c |= 1 << i From 25e196e18b57c92be2761df1e2876c6bcdca2d40 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 10 Nov 2018 18:56:50 -0800 Subject: [PATCH 482/617] Insert idle characters --- tb/xgmii_ep.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index c35f0a597..f39327562 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -189,23 +189,26 @@ class XGMIISource(object): dl.append(0xfd) cl.append(1) - k = 0 - d = 0 - c = 0 - if bw == 8 and ifg_cnt >= 4: ifg_cnt = max(ifg_cnt-4, 0) - k = 4 - d = 0x07070707 - c = 0xf + dl = [0x07]*4+dl + cl = [1]*4+cl deficit_idle_cnt = ifg_cnt ifg_cnt = 0 - for i in range(k,bw): + d = 0 + c = 0 + + for i in range(0,bw): if dl: d |= dl.pop(0) << (8*i) c |= cl.pop(0) << i + if not dl: + ifg_cnt = max(ifg, 12) - (bw-i) + deficit_idle_cnt + else: + d |= 0x07 << (8*i) + c |= 1 << i txd.next = d txc.next = c From 6a4b2699ea2c2081460d3745f58f6a217b39acb9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 11 Nov 2018 00:11:27 -0800 Subject: [PATCH 483/617] End frame reception on any control character --- tb/xgmii_ep.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index f39327562..5a37d7399 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -297,8 +297,12 @@ class XGMIISink(object): c.append((int(rxc) >> i) & 1) else: for i in range(bw): - if (rxc >> i) & 1 and (rxd >> (8*i)) & 0xff == 0xfd: - # terminate + if (rxc >> i) & 1: + # got a control character; terminate frame reception + if (rxd >> (8*i)) & 0xff != 0xfd: + # store control character if it's not a termination + d.append((int(rxd) >> (8*i)) & 0xff) + c.append((int(rxc) >> i) & 1) frame.parse(d, c) self.queue.append(frame) self.sync.next = not self.sync From fe8a4f9df362f3300a4b9e5b8a9540bebadee99f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 11 Nov 2018 00:18:32 -0800 Subject: [PATCH 484/617] Use constants for control characters --- tb/xgmii_ep.py | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 5a37d7399..b0f2b42f0 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -24,6 +24,23 @@ THE SOFTWARE. from myhdl import * +ETH_PRE = 0x55 +ETH_SFD = 0xD5 + +XGMII_IDLE = 0x07 +XGMII_LPI = 0x06 +XGMII_START = 0xfb +XGMII_TERM = 0xfd +XGMII_ERROR = 0xfe +XGMII_SEQ_OS = 0x9c +XGMII_RES0 = 0x1c +XGMII_RES1 = 0x3c +XGMII_RES2 = 0x7c +XGMII_RES3 = 0xbc +XGMII_RES4 = 0xdc +XGMII_RES5 = 0xf7 +XGMII_SIG_OS = 0x5c + class XGMIIFrame(object): def __init__(self, data=b'', error=None, ctrl=None): self.data = b'' @@ -68,7 +85,7 @@ class XGMIIFrame(object): for i in range(len(f)): if error[i]: - f[i] = 0xfe + f[i] = XGMII_ERROR ctrl[i] = 1 i = 0 @@ -89,7 +106,7 @@ class XGMIIFrame(object): self.error = [0]*len(self.data) for i in range(len(self.data)): - if c[i] and d[i] == 0xfe: + if c[i] and d[i] == XGMII_ERROR: self.error[i] = 1 def __eq__(self, other): @@ -171,7 +188,7 @@ class XGMIISource(object): if not dl: ifg_cnt = max(ifg, 12) - (bw-i) + deficit_idle_cnt else: - d |= 0x07 << (8*i) + d |= XGMII_IDLE << (8*i) c |= 1 << i txd.next = d @@ -183,15 +200,15 @@ class XGMIISource(object): print("[%s] Sending frame %s" % (name, repr(frame))) assert len(dl) > 0 - assert dl[0] == 0x55 - dl[0] = 0xfb + assert dl[0] == ETH_PRE + dl[0] = XGMII_START cl[0] = 1 - dl.append(0xfd) + dl.append(XGMII_TERM) cl.append(1) if bw == 8 and ifg_cnt >= 4: ifg_cnt = max(ifg_cnt-4, 0) - dl = [0x07]*4+dl + dl = [XGMII_IDLE]*4+dl cl = [1]*4+cl deficit_idle_cnt = ifg_cnt @@ -207,7 +224,7 @@ class XGMIISource(object): if not dl: ifg_cnt = max(ifg, 12) - (bw-i) + deficit_idle_cnt else: - d |= 0x07 << (8*i) + d |= XGMII_IDLE << (8*i) c |= 1 << i txd.next = d @@ -279,27 +296,27 @@ class XGMIISink(object): c = [] elif enable: if frame is None: - if rxc & 1 and rxd & 0xff == 0xfb: + if rxc & 1 and rxd & 0xff == XGMII_START: # start in lane 0 frame = XGMIIFrame() - d = [0x55] + d = [ETH_PRE] c = [0] for i in range(1,bw): d.append((int(rxd) >> (8*i)) & 0xff) c.append((int(rxc) >> i) & 1) - elif bw == 8 and (rxc >> 4) & 1 and (rxd >> 32) & 0xff == 0xfb: + elif bw == 8 and (rxc >> 4) & 1 and (rxd >> 32) & 0xff == XGMII_START: # start in lane 4 frame = XGMIIFrame() - d = [0x55] + d = [ETH_PRE] c = [0] - for i in range(5,8): + for i in range(5,bw): d.append((int(rxd) >> (8*i)) & 0xff) c.append((int(rxc) >> i) & 1) else: for i in range(bw): if (rxc >> i) & 1: # got a control character; terminate frame reception - if (rxd >> (8*i)) & 0xff != 0xfd: + if (rxd >> (8*i)) & 0xff != XGMII_TERM: # store control character if it's not a termination d.append((int(rxd) >> (8*i)) & 0xff) c.append((int(rxc) >> i) & 1) From a72d7bd260ffbe391060ee962f713c20ea29137d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 28 Nov 2018 14:18:09 -0800 Subject: [PATCH 485/617] Fix generate statement --- rtl/axis_pipeline_register.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtl/axis_pipeline_register.v b/rtl/axis_pipeline_register.v index 9608c8819..c7a8623c3 100644 --- a/rtl/axis_pipeline_register.v +++ b/rtl/axis_pipeline_register.v @@ -100,10 +100,10 @@ assign m_axis_tid = axis_tid[LENGTH]; assign m_axis_tdest = axis_tdest[LENGTH]; assign m_axis_tuser = axis_tuser[LENGTH]; -integer i; - generate - for (i = 0; i < LENGTH; i = i + 1) begin : reg + genvar i; + + for (i = 0; i < LENGTH; i = i + 1) begin : pipe_reg axis_register #( .DATA_WIDTH(DATA_WIDTH), .KEEP_ENABLE(KEEP_ENABLE), From f45a3ef5e03d5b69f0d68aad30e2a06462cc7519 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 3 Dec 2018 12:40:06 -0800 Subject: [PATCH 486/617] Change cycle to segment --- rtl/axis_adapter.v | 110 ++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/rtl/axis_adapter.v b/rtl/axis_adapter.v index bb6ed92cc..da31f4b32 100644 --- a/rtl/axis_adapter.v +++ b/rtl/axis_adapter.v @@ -85,12 +85,12 @@ parameter EXPAND_BUS = M_KEEP_WIDTH_INT > S_KEEP_WIDTH_INT; // total data and keep widths parameter DATA_WIDTH = EXPAND_BUS ? M_DATA_WIDTH : S_DATA_WIDTH; parameter KEEP_WIDTH = EXPAND_BUS ? M_KEEP_WIDTH_INT : S_KEEP_WIDTH_INT; -// required number of cycles to match widths -parameter CYCLE_COUNT = EXPAND_BUS ? (M_KEEP_WIDTH_INT / S_KEEP_WIDTH_INT) : (S_KEEP_WIDTH_INT / M_KEEP_WIDTH_INT); -parameter CYCLE_COUNT_WIDTH = CYCLE_COUNT == 1 ? 1 : $clog2(CYCLE_COUNT); -// data width and keep width per cycle -parameter CYCLE_DATA_WIDTH = DATA_WIDTH / CYCLE_COUNT; -parameter CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT; +// required number of segments in wider bus +parameter SEGMENT_COUNT = EXPAND_BUS ? (M_KEEP_WIDTH_INT / S_KEEP_WIDTH_INT) : (S_KEEP_WIDTH_INT / M_KEEP_WIDTH_INT); +parameter SEGMENT_COUNT_WIDTH = SEGMENT_COUNT == 1 ? 1 : $clog2(SEGMENT_COUNT); +// data width and keep width per segment +parameter SEGMENT_DATA_WIDTH = DATA_WIDTH / SEGMENT_COUNT; +parameter SEGMENT_KEEP_WIDTH = KEEP_WIDTH / SEGMENT_COUNT; // bus width assertions initial begin @@ -118,9 +118,9 @@ localparam [2:0] reg [2:0] state_reg = STATE_IDLE, state_next; -reg [CYCLE_COUNT_WIDTH-1:0] cycle_count_reg = 0, cycle_count_next; +reg [SEGMENT_COUNT_WIDTH-1:0] segment_count_reg = 0, segment_count_next; -reg last_cycle; +reg last_segment; reg [DATA_WIDTH-1:0] temp_tdata_reg = {DATA_WIDTH{1'b0}}, temp_tdata_next; reg [KEEP_WIDTH-1:0] temp_tkeep_reg = {KEEP_WIDTH{1'b0}}, temp_tkeep_next; @@ -147,9 +147,9 @@ assign s_axis_tready = s_axis_tready_reg; always @* begin state_next = STATE_IDLE; - cycle_count_next = cycle_count_reg; + segment_count_next = segment_count_reg; - last_cycle = 0; + last_segment = 0; temp_tdata_next = temp_tdata_reg; temp_tkeep_next = temp_tkeep_reg; @@ -177,7 +177,7 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - no data in registers - if (CYCLE_COUNT == 1) begin + if (SEGMENT_COUNT == 1) begin // output and input same width - just act like a register // accept data next cycle if output register ready next cycle @@ -210,11 +210,11 @@ always @* begin temp_tdest_next = s_axis_tdest; temp_tuser_next = s_axis_tuser; - // first input cycle complete - cycle_count_next = 1; + // first input segment complete + segment_count_next = 1; if (s_axis_tlast) begin - // got last signal on first cycle, so output it + // got last signal on first segment, so output it s_axis_tready_next = 1'b0; state_next = STATE_TRANSFER_OUT; end else begin @@ -233,20 +233,20 @@ always @* begin if (s_axis_tready && s_axis_tvalid) begin // word transfer in - store it in data register - cycle_count_next = 0; + segment_count_next = 0; - // is this the last cycle? - if (CYCLE_COUNT == 1) begin - // last cycle by counter value - last_cycle = 1'b1; - end else if (S_KEEP_ENABLE && s_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}) begin - // last cycle by tkeep fall in current cycle - last_cycle = 1'b1; - end else if (S_KEEP_ENABLE && s_axis_tkeep[(CYCLE_KEEP_WIDTH*2)-1:CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin - // last cycle by tkeep fall at end of current cycle - last_cycle = 1'b1; + // is this the last segment? + if (SEGMENT_COUNT == 1) begin + // last segment by counter value + last_segment = 1'b1; + end else if (S_KEEP_ENABLE && s_axis_tkeep[SEGMENT_KEEP_WIDTH-1:0] != {SEGMENT_KEEP_WIDTH{1'b1}}) begin + // last segment by tkeep fall in current segment + last_segment = 1'b1; + end else if (S_KEEP_ENABLE && s_axis_tkeep[(SEGMENT_KEEP_WIDTH*2)-1:SEGMENT_KEEP_WIDTH] == {SEGMENT_KEEP_WIDTH{1'b0}}) begin + // last segment by tkeep fall at end of current segment + last_segment = 1'b1; end else begin - last_cycle = 1'b0; + last_segment = 1'b0; end // pass complete input word, zero-extended to temp register @@ -258,20 +258,20 @@ always @* begin temp_tuser_next = s_axis_tuser; // short-circuit and get first word out the door - m_axis_tdata_int = s_axis_tdata[CYCLE_DATA_WIDTH-1:0]; - m_axis_tkeep_int = s_axis_tkeep[CYCLE_KEEP_WIDTH-1:0]; + m_axis_tdata_int = s_axis_tdata[SEGMENT_DATA_WIDTH-1:0]; + m_axis_tkeep_int = s_axis_tkeep[SEGMENT_KEEP_WIDTH-1:0]; m_axis_tvalid_int = 1'b1; - m_axis_tlast_int = s_axis_tlast & last_cycle; + m_axis_tlast_int = s_axis_tlast & last_segment; m_axis_tid_int = s_axis_tid; m_axis_tdest_int = s_axis_tdest; m_axis_tuser_int = s_axis_tuser; if (m_axis_tready_int_reg) begin // if output register is ready for first word, then move on to the next one - cycle_count_next = 1; + segment_count_next = 1; end - if (!last_cycle || !m_axis_tready_int_reg) begin + if (!last_segment || !m_axis_tready_int_reg) begin // continue outputting words s_axis_tready_next = 1'b0; state_next = STATE_TRANSFER_OUT; @@ -293,16 +293,16 @@ always @* begin if (s_axis_tready && s_axis_tvalid) begin // word transfer in - store in data register - temp_tdata_next[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH] = s_axis_tdata; - temp_tkeep_next[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] = S_KEEP_ENABLE ? s_axis_tkeep : 1'b1; + temp_tdata_next[segment_count_reg*SEGMENT_DATA_WIDTH +: SEGMENT_DATA_WIDTH] = s_axis_tdata; + temp_tkeep_next[segment_count_reg*SEGMENT_KEEP_WIDTH +: SEGMENT_KEEP_WIDTH] = S_KEEP_ENABLE ? s_axis_tkeep : 1'b1; temp_tlast_next = s_axis_tlast; temp_tid_next = s_axis_tid; temp_tdest_next = s_axis_tdest; temp_tuser_next = s_axis_tuser; - cycle_count_next = cycle_count_reg + 1; + segment_count_next = segment_count_reg + 1; - if ((cycle_count_reg == CYCLE_COUNT-1) || s_axis_tlast) begin + if ((segment_count_reg == SEGMENT_COUNT-1) || s_axis_tlast) begin // terminated by counter or tlast signal, output complete word // read input word next cycle if output will be ready s_axis_tready_next = m_axis_tready_int_early; @@ -348,11 +348,11 @@ always @* begin temp_tdest_next = s_axis_tdest; temp_tuser_next = s_axis_tuser; - // first input cycle complete - cycle_count_next = 1; + // first input segment complete + segment_count_next = 1; if (s_axis_tlast) begin - // got last signal on first cycle, so output it + // got last signal on first segment, so output it s_axis_tready_next = 1'b0; state_next = STATE_TRANSFER_OUT; end else begin @@ -373,25 +373,25 @@ always @* begin // do not accept new data s_axis_tready_next = 1'b0; - // is this the last cycle? - if (cycle_count_reg == CYCLE_COUNT-1) begin - // last cycle by counter value - last_cycle = 1'b1; - end else if (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}}) begin - // last cycle by tkeep fall in current cycle - last_cycle = 1'b1; - end else if (temp_tkeep_reg[(cycle_count_reg+1)*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin - // last cycle by tkeep fall at end of current cycle - last_cycle = 1'b1; + // is this the last segment? + if (segment_count_reg == SEGMENT_COUNT-1) begin + // last segment by counter value + last_segment = 1'b1; + end else if (temp_tkeep_reg[segment_count_reg*SEGMENT_KEEP_WIDTH +: SEGMENT_KEEP_WIDTH] != {SEGMENT_KEEP_WIDTH{1'b1}}) begin + // last segment by tkeep fall in current segment + last_segment = 1'b1; + end else if (temp_tkeep_reg[(segment_count_reg+1)*SEGMENT_KEEP_WIDTH +: SEGMENT_KEEP_WIDTH] == {SEGMENT_KEEP_WIDTH{1'b0}}) begin + // last segment by tkeep fall at end of current segment + last_segment = 1'b1; end else begin - last_cycle = 1'b0; + last_segment = 1'b0; end // output current part of stored word (output narrower) - m_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH]; - m_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH]; + m_axis_tdata_int = temp_tdata_reg[segment_count_reg*SEGMENT_DATA_WIDTH +: SEGMENT_DATA_WIDTH]; + m_axis_tkeep_int = temp_tkeep_reg[segment_count_reg*SEGMENT_KEEP_WIDTH +: SEGMENT_KEEP_WIDTH]; m_axis_tvalid_int = 1'b1; - m_axis_tlast_int = temp_tlast_reg && last_cycle; + m_axis_tlast_int = temp_tlast_reg && last_segment; m_axis_tid_int = temp_tid_reg; m_axis_tdest_int = temp_tdest_reg; m_axis_tuser_int = temp_tuser_reg; @@ -399,9 +399,9 @@ always @* begin if (m_axis_tready_int_reg) begin // word transfer out - cycle_count_next = cycle_count_reg + 1; + segment_count_next = segment_count_reg + 1; - if (last_cycle) begin + if (last_segment) begin // terminated by counter or tlast signal s_axis_tready_next = 1'b1; @@ -428,7 +428,7 @@ always @(posedge clk) begin s_axis_tready_reg <= s_axis_tready_next; end - cycle_count_reg <= cycle_count_next; + segment_count_reg <= segment_count_next; temp_tdata_reg <= temp_tdata_next; temp_tkeep_reg <= temp_tkeep_next; From f9a5e6803b7cc963681896d2b2069c042719968f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 8 Dec 2018 23:59:57 -0800 Subject: [PATCH 487/617] Add backpressure tests --- tb/test_axis_async_fifo.py | 32 +++++++++++++++++++++++++++++ tb/test_axis_async_fifo_64.py | 32 +++++++++++++++++++++++++++++ tb/test_axis_async_frame_fifo.py | 32 +++++++++++++++++++++++++++++ tb/test_axis_async_frame_fifo_64.py | 32 +++++++++++++++++++++++++++++ tb/test_axis_fifo.py | 32 +++++++++++++++++++++++++++++ tb/test_axis_fifo_64.py | 32 +++++++++++++++++++++++++++++ tb/test_axis_frame_fifo.py | 32 +++++++++++++++++++++++++++++ tb/test_axis_frame_fifo_64.py | 32 +++++++++++++++++++++++++++++ 8 files changed, 256 insertions(+) diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index 0a1f842c1..50f836591 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -466,6 +466,38 @@ def bench(): yield delay(100) + yield s_clk.posedge + print("test 10: backpressure test") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=10, + dest=1 + ) + + sink_pause.next = 1 + source.send(test_frame) + source.send(test_frame) + yield delay(5000) + yield s_clk.posedge + sink_pause.next = 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index 0bd343e63..9af357fe2 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -466,6 +466,38 @@ def bench(): yield delay(100) + yield s_clk.posedge + print("test 10: backpressure test") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=10, + dest=1 + ) + + sink_pause.next = 1 + source.send(test_frame) + source.send(test_frame) + yield delay(1000) + yield s_clk.posedge + sink_pause.next = 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index dba018b1e..96d0d6956 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -634,6 +634,38 @@ def bench(): yield delay(100) + yield s_clk.posedge + print("test 11: backpressure test") + current_test.next = 11 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=11, + dest=1 + ) + + sink_pause.next = 1 + source.send(test_frame) + source.send(test_frame) + yield delay(5000) + yield s_clk.posedge + sink_pause.next = 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index 9d9ca5f39..699833f26 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -634,6 +634,38 @@ def bench(): yield delay(100) + yield s_clk.posedge + print("test 11: backpressure test") + current_test.next = 11 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=11, + dest=1 + ) + + sink_pause.next = 1 + source.send(test_frame) + source.send(test_frame) + yield delay(1000) + yield s_clk.posedge + sink_pause.next = 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index aa2527f9a..0ffd1c001 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -455,6 +455,38 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 10: backpressure test") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=10, + dest=1 + ) + + sink_pause.next = 1 + source.send(test_frame) + source.send(test_frame) + yield delay(5000) + yield clk.posedge + sink_pause.next = 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index 04181f7bd..d09739bfb 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -455,6 +455,38 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 10: backpressure test") + current_test.next = 10 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=10, + dest=1 + ) + + sink_pause.next = 1 + source.send(test_frame) + source.send(test_frame) + yield delay(1000) + yield clk.posedge + sink_pause.next = 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index 2bcc89f38..9280f2c5a 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -560,6 +560,38 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 11: backpressure test") + current_test.next = 11 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=11, + dest=1 + ) + + sink_pause.next = 1 + source.send(test_frame) + source.send(test_frame) + yield delay(5000) + yield clk.posedge + sink_pause.next = 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index 0d541dd3e..2987b275c 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -560,6 +560,38 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 11: backpressure test") + current_test.next = 11 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=11, + dest=1 + ) + + sink_pause.next = 1 + source.send(test_frame) + source.send(test_frame) + yield delay(1000) + yield clk.posedge + sink_pause.next = 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() From 3d90e80da8e60daf5727e003d3b059e9b21b41da Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 9 Dec 2018 00:01:38 -0800 Subject: [PATCH 488/617] Fix frame FIFO full logic bug --- rtl/axis_async_fifo.v | 79 +++++++++++++++++++++++-------------------- rtl/axis_fifo.v | 67 ++++++++++++++++++------------------ 2 files changed, 76 insertions(+), 70 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index dd291aa5a..697223aa8 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -124,6 +124,7 @@ localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; +reg [ADDR_WIDTH:0] wr_ptr_cur_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_gray_next; reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_gray_next; @@ -155,11 +156,14 @@ reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; wire full = ((wr_ptr_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) && (wr_ptr_gray_reg[ADDR_WIDTH-1] != rd_ptr_gray_sync2_reg[ADDR_WIDTH-1]) && (wr_ptr_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); +wire full_cur = ((wr_ptr_cur_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_WIDTH]) && + (wr_ptr_cur_gray_reg[ADDR_WIDTH-1] != rd_ptr_gray_sync2_reg[ADDR_WIDTH-1]) && + (wr_ptr_cur_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); // empty when pointers match exactly wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; // overflow within packet -wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && - (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); +wire full_wr = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); // control signals reg write; @@ -184,7 +188,7 @@ reg good_frame_sync2_reg = 1'b0; reg good_frame_sync3_reg = 1'b0; reg good_frame_sync4_reg = 1'b0; -assign s_axis_tready = (!full || DROP_WHEN_FULL) && !s_rst_sync3_reg; +assign s_axis_tready = (FRAME_FIFO ? (!full_cur || full_wr || DROP_WHEN_FULL) : !full) && !s_rst_sync3_reg; generate assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata; @@ -249,41 +253,42 @@ always @* begin wr_ptr_next = wr_ptr_reg; wr_ptr_cur_next = wr_ptr_cur_reg; wr_ptr_gray_next = wr_ptr_gray_reg; + wr_ptr_cur_gray_next = wr_ptr_cur_gray_reg; - if (s_axis_tvalid) begin - // input data valid - if (!full || DROP_WHEN_FULL) begin - // not full, perform write - if (!FRAME_FIFO) begin - // normal FIFO mode - write = 1'b1; - wr_ptr_next = wr_ptr_reg + 1; - wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); - end else if (full || full_cur || drop_frame_reg) begin - // full, packet overflow, or currently dropping frame - // drop frame - drop_frame_next = 1'b1; - if (s_axis_tlast) begin - // end of frame, reset write pointer + if (s_axis_tready && s_axis_tvalid) begin + // transfer in + if (!FRAME_FIFO) begin + // normal FIFO mode + write = 1'b1; + wr_ptr_next = wr_ptr_reg + 1; + wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); + end else if (full_cur || full_wr || drop_frame_reg) begin + // full, packet overflow, or currently dropping frame + // drop frame + drop_frame_next = 1'b1; + if (s_axis_tlast) begin + // end of frame, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + wr_ptr_cur_gray_next = wr_ptr_cur_next ^ (wr_ptr_cur_next >> 1); + drop_frame_next = 1'b0; + overflow_next = 1'b1; + end + end else begin + write = 1'b1; + wr_ptr_cur_next = wr_ptr_cur_reg + 1; + wr_ptr_cur_gray_next = wr_ptr_cur_next ^ (wr_ptr_cur_next >> 1); + if (s_axis_tlast) begin + // end of frame + if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin + // bad packet, reset write pointer wr_ptr_cur_next = wr_ptr_reg; - drop_frame_next = 1'b0; - overflow_next = 1'b1; - end - end else begin - write = 1'b1; - wr_ptr_cur_next = wr_ptr_cur_reg + 1; - if (s_axis_tlast) begin - // end of frame - if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin - // bad packet, reset write pointer - wr_ptr_cur_next = wr_ptr_reg; - bad_frame_next = 1'b1; - end else begin - // good packet, update write pointer - wr_ptr_next = wr_ptr_cur_reg + 1; - wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); - good_frame_next = 1'b1; - end + wr_ptr_cur_gray_next = wr_ptr_cur_next ^ (wr_ptr_cur_next >> 1); + bad_frame_next = 1'b1; + end else begin + // good packet, update write pointer + wr_ptr_next = wr_ptr_cur_reg + 1; + wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); + good_frame_next = 1'b1; end end end @@ -295,6 +300,7 @@ always @(posedge s_clk) begin wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_cur_gray_reg <= {ADDR_WIDTH+1{1'b0}}; drop_frame_reg <= 1'b0; overflow_reg <= 1'b0; @@ -304,6 +310,7 @@ always @(posedge s_clk) begin wr_ptr_reg <= wr_ptr_next; wr_ptr_cur_reg <= wr_ptr_cur_next; wr_ptr_gray_reg <= wr_ptr_gray_next; + wr_ptr_cur_gray_reg <= wr_ptr_cur_gray_next; drop_frame_reg <= drop_frame_next; overflow_reg <= overflow_next; diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index de2e90c1e..83d89900d 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -132,11 +132,13 @@ reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; // full when first MSB different but rest same wire full = ((wr_ptr_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && (wr_ptr_reg[ADDR_WIDTH-1:0] == rd_ptr_reg[ADDR_WIDTH-1:0])); +wire full_cur = ((wr_ptr_cur_reg[ADDR_WIDTH] != rd_ptr_reg[ADDR_WIDTH]) && + (wr_ptr_cur_reg[ADDR_WIDTH-1:0] == rd_ptr_reg[ADDR_WIDTH-1:0])); // empty when pointers match exactly wire empty = wr_ptr_reg == rd_ptr_reg; // overflow within packet -wire full_cur = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && - (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); +wire full_wr = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && + (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); // control signals reg write; @@ -148,7 +150,7 @@ reg overflow_reg = 1'b0, overflow_next; reg bad_frame_reg = 1'b0, bad_frame_next; reg good_frame_reg = 1'b0, good_frame_next; -assign s_axis_tready = (!full || DROP_WHEN_FULL); +assign s_axis_tready = FRAME_FIFO ? (!full_cur || full_wr || DROP_WHEN_FULL) : !full; generate assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata; @@ -184,38 +186,35 @@ always @* begin wr_ptr_next = wr_ptr_reg; wr_ptr_cur_next = wr_ptr_cur_reg; - if (s_axis_tvalid) begin - // input data valid - if (!full || DROP_WHEN_FULL) begin - // not full, perform write - if (!FRAME_FIFO) begin - // normal FIFO mode - write = 1'b1; - wr_ptr_next = wr_ptr_reg + 1; - end else if (full || full_cur || drop_frame_reg) begin - // full, packet overflow, or currently dropping frame - // drop frame - drop_frame_next = 1'b1; - if (s_axis_tlast) begin - // end of frame, reset write pointer + if (s_axis_tready && s_axis_tvalid) begin + // transfer in + if (!FRAME_FIFO) begin + // normal FIFO mode + write = 1'b1; + wr_ptr_next = wr_ptr_reg + 1; + end else if (full_cur || full_wr || drop_frame_reg) begin + // full, packet overflow, or currently dropping frame + // drop frame + drop_frame_next = 1'b1; + if (s_axis_tlast) begin + // end of frame, reset write pointer + wr_ptr_cur_next = wr_ptr_reg; + drop_frame_next = 1'b0; + overflow_next = 1'b1; + end + end else begin + write = 1'b1; + wr_ptr_cur_next = wr_ptr_cur_reg + 1; + if (s_axis_tlast) begin + // end of frame + if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin + // bad packet, reset write pointer wr_ptr_cur_next = wr_ptr_reg; - drop_frame_next = 1'b0; - overflow_next = 1'b1; - end - end else begin - write = 1'b1; - wr_ptr_cur_next = wr_ptr_cur_reg + 1; - if (s_axis_tlast) begin - // end of frame - if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin - // bad packet, reset write pointer - wr_ptr_cur_next = wr_ptr_reg; - bad_frame_next = 1'b1; - end else begin - // good packet, update write pointer - wr_ptr_next = wr_ptr_cur_reg + 1; - good_frame_next = 1'b1; - end + bad_frame_next = 1'b1; + end else begin + // good packet, update write pointer + wr_ptr_next = wr_ptr_cur_reg + 1; + good_frame_next = 1'b1; end end end From aa6991a4a58749b7ef89481004e88d3b6743052f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 9 Dec 2018 00:03:09 -0800 Subject: [PATCH 489/617] Bitwise operators instead of generate --- rtl/axis_arb_mux.v | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/rtl/axis_arb_mux.v b/rtl/axis_arb_mux.v index 36434d9f3..a23c6a5ed 100644 --- a/rtl/axis_arb_mux.v +++ b/rtl/axis_arb_mux.v @@ -123,14 +123,8 @@ arb_inst ( .grant_encoded(grant_encoded) ); -generate - genvar n; - - for (n = 0; n < S_COUNT; n = n + 1) begin - assign request[n] = s_axis_tvalid[n] && !grant[n]; - assign acknowledge[n] = grant[n] && s_axis_tvalid[n] && s_axis_tready[n] && s_axis_tlast[n]; - end -endgenerate +assign request = s_axis_tvalid & ~grant; +assign acknowledge = grant & s_axis_tvalid & s_axis_tready & s_axis_tlast; always @* begin // pass through selected packet data From cadd1bcb50a346d97823f4dc5ba8230ebbb42d94 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 9 Dec 2018 00:04:30 -0800 Subject: [PATCH 490/617] Match width --- rtl/axis_demux.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/axis_demux.v b/rtl/axis_demux.v index 6edff1eec..ed661e76e 100644 --- a/rtl/axis_demux.v +++ b/rtl/axis_demux.v @@ -212,7 +212,7 @@ always @* begin end else if (m_axis_tready & m_axis_tvalid) begin // input is not ready, but output is ready m_axis_tvalid_next = temp_m_axis_tvalid_reg; - temp_m_axis_tvalid_next = 1'b0; + temp_m_axis_tvalid_next = {M_COUNT{1'b0}}; store_axis_temp_to_output = 1'b1; end end @@ -221,7 +221,7 @@ always @(posedge clk) begin if (rst) begin m_axis_tvalid_reg <= {M_COUNT{1'b0}}; m_axis_tready_int_reg <= 1'b0; - temp_m_axis_tvalid_reg <= 1'b0; + temp_m_axis_tvalid_reg <= {M_COUNT{1'b0}}; end else begin m_axis_tvalid_reg <= m_axis_tvalid_next; m_axis_tready_int_reg <= m_axis_tready_int_early; From 8d9ed665d7a07a078571822152ac6ab4f26e5946 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 9 Dec 2018 00:04:56 -0800 Subject: [PATCH 491/617] Use logical operator instead of bitwise --- rtl/axis_mux.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/axis_mux.v b/rtl/axis_mux.v index 3a8a8d139..9d1e45f6e 100644 --- a/rtl/axis_mux.v +++ b/rtl/axis_mux.v @@ -120,7 +120,7 @@ always @* begin end end - if (~frame_reg && enable && (s_axis_tvalid & (1 << select))) begin + if (!frame_reg && enable && (s_axis_tvalid & (1 << select))) begin // start of frame, grab select value frame_next = 1'b1; select_next = select; From 59a979aedae1452f057a826c38006af84fee7c9b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 9 Dec 2018 00:05:38 -0800 Subject: [PATCH 492/617] Add parameters to testbench --- tb/test_axis_arb_mux_4.py | 2 ++ tb/test_axis_arb_mux_4.v | 6 +++++- tb/test_axis_arb_mux_4_64.py | 2 ++ tb/test_axis_arb_mux_4_64.v | 6 +++++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index 77e52d35e..cd5489475 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -55,6 +55,8 @@ def bench(): DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + ARB_TYPE = "PRIORITY" + LSB_PRIORITY = "HIGH" # Inputs clk = Signal(bool(0)) diff --git a/tb/test_axis_arb_mux_4.v b/tb/test_axis_arb_mux_4.v index 79c4f2736..ae929053d 100644 --- a/tb/test_axis_arb_mux_4.v +++ b/tb/test_axis_arb_mux_4.v @@ -42,6 +42,8 @@ parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter ARB_TYPE = "PRIORITY"; +parameter LSB_PRIORITY = "HIGH"; // Inputs reg clk = 0; @@ -110,7 +112,9 @@ axis_arb_mux #( .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) + .USER_WIDTH(USER_WIDTH), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) ) UUT ( .clk(clk), diff --git a/tb/test_axis_arb_mux_4_64.py b/tb/test_axis_arb_mux_4_64.py index f17ba4ec2..b462ce9f1 100755 --- a/tb/test_axis_arb_mux_4_64.py +++ b/tb/test_axis_arb_mux_4_64.py @@ -55,6 +55,8 @@ def bench(): DEST_WIDTH = 8 USER_ENABLE = 1 USER_WIDTH = 1 + ARB_TYPE = "PRIORITY" + LSB_PRIORITY = "HIGH" # Inputs clk = Signal(bool(0)) diff --git a/tb/test_axis_arb_mux_4_64.v b/tb/test_axis_arb_mux_4_64.v index eaa9c96d8..107a4de12 100644 --- a/tb/test_axis_arb_mux_4_64.v +++ b/tb/test_axis_arb_mux_4_64.v @@ -42,6 +42,8 @@ parameter DEST_ENABLE = 1; parameter DEST_WIDTH = 8; parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; +parameter ARB_TYPE = "PRIORITY"; +parameter LSB_PRIORITY = "HIGH"; // Inputs reg clk = 0; @@ -110,7 +112,9 @@ axis_arb_mux #( .DEST_ENABLE(DEST_ENABLE), .DEST_WIDTH(DEST_WIDTH), .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) + .USER_WIDTH(USER_WIDTH), + .ARB_TYPE(ARB_TYPE), + .LSB_PRIORITY(LSB_PRIORITY) ) UUT ( .clk(clk), From 82454e4ae1b4b375a88f53a762037a338b914a50 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 8 Jan 2019 17:22:01 -0800 Subject: [PATCH 493/617] Add ExaNIC X10 example design --- example/ExaNIC_X10/fpga/Makefile | 25 + example/ExaNIC_X10/fpga/README.md | 26 + example/ExaNIC_X10/fpga/common/vivado.mk | 118 ++ example/ExaNIC_X10/fpga/fpga.xdc | 155 ++ example/ExaNIC_X10/fpga/fpga/Makefile | 58 + .../fpga/ip/gtwizard_ultrascale_0.xci | 1401 +++++++++++++++++ .../fpga/ip/ten_gig_eth_pcs_pma_0.xci | 132 ++ example/ExaNIC_X10/fpga/lib/eth | 1 + example/ExaNIC_X10/fpga/rtl/fpga.v | 553 +++++++ example/ExaNIC_X10/fpga/rtl/fpga_core.v | 588 +++++++ example/ExaNIC_X10/fpga/rtl/sync_reset.v | 52 + example/ExaNIC_X10/fpga/rtl/sync_signal.v | 58 + example/ExaNIC_X10/fpga/tb/arp_ep.py | 1 + example/ExaNIC_X10/fpga/tb/axis_ep.py | 1 + example/ExaNIC_X10/fpga/tb/eth_ep.py | 1 + example/ExaNIC_X10/fpga/tb/gmii_ep.py | 1 + example/ExaNIC_X10/fpga/tb/ip_ep.py | 1 + example/ExaNIC_X10/fpga/tb/test_fpga_core.py | 294 ++++ example/ExaNIC_X10/fpga/tb/test_fpga_core.v | 122 ++ example/ExaNIC_X10/fpga/tb/udp_ep.py | 1 + example/ExaNIC_X10/fpga/tb/xgmii_ep.py | 1 + 21 files changed, 3590 insertions(+) create mode 100644 example/ExaNIC_X10/fpga/Makefile create mode 100644 example/ExaNIC_X10/fpga/README.md create mode 100644 example/ExaNIC_X10/fpga/common/vivado.mk create mode 100644 example/ExaNIC_X10/fpga/fpga.xdc create mode 100644 example/ExaNIC_X10/fpga/fpga/Makefile create mode 100644 example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci create mode 100644 example/ExaNIC_X10/fpga/ip/ten_gig_eth_pcs_pma_0.xci create mode 120000 example/ExaNIC_X10/fpga/lib/eth create mode 100644 example/ExaNIC_X10/fpga/rtl/fpga.v create mode 100644 example/ExaNIC_X10/fpga/rtl/fpga_core.v create mode 100644 example/ExaNIC_X10/fpga/rtl/sync_reset.v create mode 100644 example/ExaNIC_X10/fpga/rtl/sync_signal.v create mode 120000 example/ExaNIC_X10/fpga/tb/arp_ep.py create mode 120000 example/ExaNIC_X10/fpga/tb/axis_ep.py create mode 120000 example/ExaNIC_X10/fpga/tb/eth_ep.py create mode 120000 example/ExaNIC_X10/fpga/tb/gmii_ep.py create mode 120000 example/ExaNIC_X10/fpga/tb/ip_ep.py create mode 100755 example/ExaNIC_X10/fpga/tb/test_fpga_core.py create mode 100644 example/ExaNIC_X10/fpga/tb/test_fpga_core.v create mode 120000 example/ExaNIC_X10/fpga/tb/udp_ep.py create mode 120000 example/ExaNIC_X10/fpga/tb/xgmii_ep.py diff --git a/example/ExaNIC_X10/fpga/Makefile b/example/ExaNIC_X10/fpga/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/ExaNIC_X10/fpga/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/ExaNIC_X10/fpga/README.md b/example/ExaNIC_X10/fpga/README.md new file mode 100644 index 000000000..f2d77ef10 --- /dev/null +++ b/example/ExaNIC_X10/fpga/README.md @@ -0,0 +1,26 @@ +# Verilog Ethernet ExaNIC X10 Example Design + +## Introduction + +This example design targets the Exablaze ExaNIC X10 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. The design also enables the gigabit Ethernet interface for +testing with a QSFP loopback adapter. + +FPGA: xcku035-fbva676-2-c +PHY: 10G BASE-R PHY IP core and internal GTH transceiver + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the ExaNIC X10 board with Vivado. Then run +netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any text +entered into netcat will be echoed back after pressing enter. + + diff --git a/example/ExaNIC_X10/fpga/common/vivado.mk b/example/ExaNIC_X10/fpga/common/vivado.mk new file mode 100644 index 000000000..a54b530f6 --- /dev/null +++ b/example/ExaNIC_X10/fpga/common/vivado.mk @@ -0,0 +1,118 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile $(XCI_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/ExaNIC_X10/fpga/fpga.xdc b/example/ExaNIC_X10/fpga/fpga.xdc new file mode 100644 index 000000000..1f14f4575 --- /dev/null +++ b/example/ExaNIC_X10/fpga/fpga.xdc @@ -0,0 +1,155 @@ +# XDC constraints for the ExaNIC X10 +# part: xcku035-fbva676-2-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.UNUSEDPIN Pullup [current_design] +set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design] +set_property BITSTREAM.CONFIG.BPI_SYNC_MODE Type2 [current_design] +set_property CONFIG_MODE BPI16 [current_design] + +# 100 MHz system clock +set_property -dict {LOC D18 IOSTANDARD LVDS} [get_ports clk_100mhz_p] +set_property -dict {LOC C18 IOSTANDARD LVDS} [get_ports clk_100mhz_n] +create_clock -period 10 -name clk_100mhz [get_ports clk_100mhz_p] +set_clock_groups -asynchronous -group [get_clocks clk_100mhz -include_generated_clocks] + +# LEDs +set_property -dict {LOC A25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_1_led[0]}] +set_property -dict {LOC A24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_1_led[1]}] +set_property -dict {LOC E23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_2_led[0]}] +set_property -dict {LOC D26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_2_led[1]}] +set_property -dict {LOC C23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sma_led[0]}] +set_property -dict {LOC D23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sma_led[1]}] + +# GPIO +#set_property -dict {LOC W26 IOSTANDARD LVCMOS18} [get_ports gpio[0]] +#set_property -dict {LOC Y26 IOSTANDARD LVCMOS18} [get_ports gpio[1]] +#set_property -dict {LOC AB26 IOSTANDARD LVCMOS18} [get_ports gpio[2]] +#set_property -dict {LOC AC26 IOSTANDARD LVCMOS18} [get_ports gpio[3]] + +# SMA +#set_property -dict {LOC B17 IOSTANDARD LVCMOS18} [get_ports sma_in] +#set_property -dict {LOC B16 IOSTANDARD LVCMOS18} [get_ports sma_out] +#set_property -dict {LOC B19 IOSTANDARD LVCMOS18} [get_ports sma_out_en] +#set_property -dict {LOC C16 IOSTANDARD LVCMOS18} [get_ports sma_term_en] + +# SFP+ Interface +set_property -dict {LOC D2 } [get_ports sfp_1_rx_p] ;# MGTHTXN0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC D1 } [get_ports sfp_1_rx_n] ;# MGTHTXP0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3 +set_property -dict {LOC E4 } [get_ports sfp_1_tx_p] ;# MGTHTXN0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC E3 } [get_ports sfp_1_tx_n] ;# MGTHTXP0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3 +set_property -dict {LOC C4 } [get_ports sfp_2_rx_p] ;# MGTHTXN1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC C3 } [get_ports sfp_2_rx_n] ;# MGTHTXP1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3 +set_property -dict {LOC D6 } [get_ports sfp_2_tx_p] ;# MGTHTXN1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3 +#set_property -dict {LOC D5 } [get_ports sfp_2_tx_n] ;# MGTHTXP1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3 +set_property -dict {LOC H6 } [get_ports sfp_mgt_refclk_p] ;# MGTREFCLK0P_227 from X2 +#set_property -dict {LOC H5 } [get_ports sfp_mgt_refclk_n] ;# MGTREFCLK0N_227 from X2 +set_property -dict {LOC AA12 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sfp_1_tx_disable] +set_property -dict {LOC W14 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sfp_2_tx_disable] +set_property -dict {LOC C24 IOSTANDARD LVCMOS18 PULLUP true} [get_ports sfp_1_npres] +set_property -dict {LOC D24 IOSTANDARD LVCMOS18 PULLUP true} [get_ports sfp_2_npres] +set_property -dict {LOC W13 IOSTANDARD LVCMOS18 PULLUP true} [get_ports sfp_1_los] +set_property -dict {LOC AB12 IOSTANDARD LVCMOS18 PULLUP true} [get_ports sfp_2_los] +set_property -dict {LOC B25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sfp_1_rs] +set_property -dict {LOC D25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sfp_2_rs] +#set_property -dict {LOC W11 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports sfp_i2c_scl] +#set_property -dict {LOC Y11 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports sfp_1_i2c_sda] +#set_property -dict {LOC Y13 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports sfp_2_i2c_sda] + +# 161.1328125 MHz MGT reference clock +create_clock -period 6.206 -name sfp_mgt_refclk [get_ports sfp_mgt_refclk_p] +set_clock_groups -asynchronous -group [get_clocks sfp_mgt_refclk -include_generated_clocks] + +# I2C interface +#set_property -dict {LOC B26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_scl] +#set_property -dict {LOC C26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_sda] + +# PCIe Interface +#set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[7]}] ;# MGTHTXN0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[7]}] ;# MGTHTXP0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AF6 } [get_ports {pcie_tx_p[7]}] ;# MGTHTXN0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AF5 } [get_ports {pcie_tx_n[7]}] ;# MGTHTXP0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AE4 } [get_ports {pcie_rx_p[6]}] ;# MGTHTXN1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AE3 } [get_ports {pcie_rx_n[6]}] ;# MGTHTXP1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AD6 } [get_ports {pcie_tx_p[6]}] ;# MGTHTXN1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AD5 } [get_ports {pcie_tx_n[6]}] ;# MGTHTXP1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AD2 } [get_ports {pcie_rx_p[5]}] ;# MGTHTXN2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AD1 } [get_ports {pcie_rx_n[5]}] ;# MGTHTXP2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AC4 } [get_ports {pcie_tx_p[5]}] ;# MGTHTXN2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AC3 } [get_ports {pcie_tx_n[5]}] ;# MGTHTXP2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AB2 } [get_ports {pcie_rx_p[4]}] ;# MGTHTXN3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AB1 } [get_ports {pcie_rx_n[4]}] ;# MGTHTXP3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AB6 } [get_ports {pcie_tx_p[4]}] ;# MGTHTXN3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC AB5 } [get_ports {pcie_tx_n[4]}] ;# MGTHTXP3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0 +#set_property -dict {LOC Y2 } [get_ports {pcie_rx_p[3]}] ;# MGTHTXN0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC Y1 } [get_ports {pcie_rx_n[3]}] ;# MGTHTXP0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC AA4 } [get_ports {pcie_tx_p[3]}] ;# MGTHTXN0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC AA3 } [get_ports {pcie_tx_n[3]}] ;# MGTHTXP0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC V2 } [get_ports {pcie_rx_p[2]}] ;# MGTHTXN1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC V1 } [get_ports {pcie_rx_n[2]}] ;# MGTHTXP1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC W4 } [get_ports {pcie_tx_p[2]}] ;# MGTHTXN1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC W3 } [get_ports {pcie_tx_n[2]}] ;# MGTHTXP1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC T2 } [get_ports {pcie_rx_p[1]}] ;# MGTHTXN2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC T1 } [get_ports {pcie_rx_n[1]}] ;# MGTHTXP2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC U4 } [get_ports {pcie_tx_p[1]}] ;# MGTHTXN2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC U3 } [get_ports {pcie_tx_n[1]}] ;# MGTHTXP2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC P2 } [get_ports {pcie_rx_p[0]}] ;# MGTHTXN3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC P1 } [get_ports {pcie_rx_n[0]}] ;# MGTHTXP3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC R4 } [get_ports {pcie_tx_p[0]}] ;# MGTHTXN3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC R3 } [get_ports {pcie_tx_n[0]}] ;# MGTHTXP3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1 +#set_property -dict {LOC T6 } [get_ports pcie_mgt_refclk_p] ;# MGTREFCLK0P_225 +#set_property -dict {LOC T5 } [get_ports pcie_mgt_refclk_n] ;# MGTREFCLK0N_225 +#set_property -dict {LOC AC22 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n] + +# 100 MHz MGT reference clock +#create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_mgt_refclk_p] +#set_clock_groups -asynchronous -group [get_clocks pcie_mgt_refclk -include_generated_clocks] + +# Flash +#set_property -dict {LOC AE10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[0]}] +#set_property -dict {LOC AC8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[1]}] +#set_property -dict {LOC AD10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[2]}] +#set_property -dict {LOC AD9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[3]}] +#set_property -dict {LOC AC11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[4]}] +#set_property -dict {LOC AF10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[5]}] +#set_property -dict {LOC AF14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[6]}] +#set_property -dict {LOC AE12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[7]}] +#set_property -dict {LOC AD14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[8]}] +#set_property -dict {LOC AF13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[9]}] +#set_property -dict {LOC AE13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[10]}] +#set_property -dict {LOC AD8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[11]}] +#set_property -dict {LOC AC13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[12]}] +#set_property -dict {LOC AD13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[13]}] +#set_property -dict {LOC AA14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[14]}] +#set_property -dict {LOC AB15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[15]}] +#set_property -dict {LOC AD11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[0]}] +#set_property -dict {LOC AE11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[1]}] +#set_property -dict {LOC AF12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[2]}] +#set_property -dict {LOC AB11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[3]}] +#set_property -dict {LOC AB9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[4]}] +#set_property -dict {LOC AB14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[5]}] +#set_property -dict {LOC AA10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[6]}] +#set_property -dict {LOC AA9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[7]}] +#set_property -dict {LOC W10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[8]}] +#set_property -dict {LOC AA13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[9]}] +#set_property -dict {LOC Y15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[10]}] +#set_property -dict {LOC AC12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[11]}] +#set_property -dict {LOC V12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[12]}] +#set_property -dict {LOC V11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[13]}] +#set_property -dict {LOC Y12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[14]}] +#set_property -dict {LOC W9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[15]}] +#set_property -dict {LOC Y8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[16]}] +#set_property -dict {LOC W8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[17]}] +#set_property -dict {LOC W15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[18]}] +#set_property -dict {LOC AA15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[19]}] +#set_property -dict {LOC AE16 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[20]}] +#set_property -dict {LOC AF15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[21]}] +#set_property -dict {LOC AE15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[22]}] +#set_property -dict {LOC AD15 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {flash_region}] +#set_property -dict {LOC AC9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_ce_n}] +#set_property -dict {LOC AC14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_oe_n}] +#set_property -dict {LOC AB10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_we_n}] +#set_property -dict {LOC Y10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_adv_n}] diff --git a/example/ExaNIC_X10/fpga/fpga/Makefile b/example/ExaNIC_X10/fpga/fpga/Makefile new file mode 100644 index 000000000..fa241dffd --- /dev/null +++ b/example/ExaNIC_X10/fpga/fpga/Makefile @@ -0,0 +1,58 @@ + +# FPGA settings +FPGA_PART = xcku035-fbva676-2-e +FPGA_TOP = fpga +FPGA_ARCH = kintexu + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp_64.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v +SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v + +# XDC files +XDC_FILES = fpga.xdc + +# IP +XCI_FILES = ip/gtwizard_ultrascale_0.xci +XCI_FILES += ip/ten_gig_eth_pcs_pma_0.xci + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl + echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "exit" >> program.tcl + vivado -mode batch -source program.tcl + diff --git a/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci b/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci new file mode 100644 index 000000000..4de2bbe20 --- /dev/null +++ b/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci @@ -0,0 +1,1401 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gtwizard_ultrascale_0 + + + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000000" + 1 + 2578.125 + 0 + 125 + 17 + 0 + 2 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 1 + 250 + 0 + 0 + 0 + 0 + 0 + 1 + "00000000" + "00000000" + 1 + 1 + 0 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000" + 0 + "00000000" + 1 + 0 + 5000 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + 0 + "1010000011" + 0 + "0101111100" + 4 + 1 + 32 + 10.3125 + 12 + 1 + 312.5000000 + 4 + 0 + 0x000000000000000000000000000000000000000000000000 + 161.1328125 + 0 + 0 + 0 + 1 + 2 + 0 + 64 + 156.25 + 312.5000000 + 0 + 257.8125 + "0" + 2 + 1 + 0 + 0 + 0 + 312.5 + 0 + 0 + 1 + 4 + 1 + 32 + 10.3125 + 12 + 1 + 312.5000000 + 4 + 0 + 161.1328125 + 0 + 0 + 1 + 2 + 0 + 64 + 156.25 + 312.5000000 + 0 + X0Y13 X0Y12 + gtwizard_ultrascale_0 + 0 + rxpolarity_in txpolarity_in + 125 + BOTH + 0 + GTH + 2 + 20 + 96 + 1 + gthe3 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + -1 + -1 + -1 + -1 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + -1 + 0 + -1 + -1 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + -1 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + -1 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + 1 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + 1 + 1 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 0 + 0 + -1 + -1 + -1 + 0 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 13 + 0 + 10GBASE-R + 3 + 312.5000000 + 2 + 1 + 312.5000000 + false + CORE + NONE + CORE + CORE + EXAMPLE_DESIGN + CORE + EXAMPLE_DESIGN + EXAMPLE_DESIGN + false + NAME + false + 250 + false + false + 250 + GTH-10GBASE-R + 0 + MULTI + 1 + ENABLE + DISABLE + ENABLE + 00000000 + false + false + false + false + false + false + false + false + 00000000 + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 1 + 1 + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + false + false + false + false + false + false + false + false + 00000000 + DISABLE + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 0 + 5000 + ENABLE + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 1 + false + 0000000000 + false + 1010000011 + NONE + false + 0101111100 + true + 0 + AC + 64B66B_ASYNC + true + AUTO + 32 + 6.1862627 + -20 + 10.3125 + X0Y12 + RXPROGDIVCLK + QPLL0 + 200 + 0 + + 161.1328125 + + OFF + 0 + PROGRAMMABLE + 800 + 64 + 15 + false + 0 + 10.3125 + 257.8125 + 0 + false + QPLL0 + 312.5 + 1 + ENABLE + 64B66B_ASYNC + CUSTOM + true + 32 + 10.3125 + X0Y12 + TXPROGDIVCLK + QPLL0 + 0 + 161.1328125 + + 64 + false + 1 + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + true + true + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + true + true + false + true + true + true + false + true + true + true + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + kintexu + + xcku035 + fbva676 + VERILOG + + MIXED + -2 + E + TRUE + TRUE + IP_Flow + 0 + TRUE + . + + . + 2017.2.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ExaNIC_X10/fpga/ip/ten_gig_eth_pcs_pma_0.xci b/example/ExaNIC_X10/fpga/ip/ten_gig_eth_pcs_pma_0.xci new file mode 100644 index 000000000..fc00bdafe --- /dev/null +++ b/example/ExaNIC_X10/fpga/ip/ten_gig_eth_pcs_pma_0.xci @@ -0,0 +1,132 @@ + + + xilinx.com + xci + unknown + 1.0 + + + ten_gig_eth_pcs_pma_0 + + + 1 + 75 + 64 + 7 + BASE-R + Asynchronous + Ethernet PCS/PMA 64-bit + MII + 0 + 0 + 0 + 0 + 0 + kintexu + 0 + 125 + Quad X0Y0 + 0 + 161.1328125 + GTH + None + 0 + 0 + 0 + 0 + 0 + X0Y12 + NA + NA + NA + 10 + 1 + 0 + 2 + 0 + 0 + 4 + 1 + 0 + 1 + 100 + BASE-R + Asynchronous + Ethernet PCS/PMA 64-bit + ten_gig_eth_pcs_pma_0 + MII + Custom + 0 + 0 + 0 + 0 + 0 + Custom + 0 + 125 + Quad_X0Y3 + 0 + 161.1328125 + GTH + None + 0 + 0 + 0 + 0 + 0 + X0Y12 + NA + NA + NA + 10 + 1 + 0 + 2 + 0 + 0 + false + 1 + kintexu + + xcku035 + fbva676 + VERILOG + + MIXED + -2 + E + TRUE + TRUE + IP_Flow + 0 + TRUE + . + + . + 2017.2.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ExaNIC_X10/fpga/lib/eth b/example/ExaNIC_X10/fpga/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/ExaNIC_X10/fpga/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga/rtl/fpga.v b/example/ExaNIC_X10/fpga/rtl/fpga.v new file mode 100644 index 000000000..893e837dc --- /dev/null +++ b/example/ExaNIC_X10/fpga/rtl/fpga.v @@ -0,0 +1,553 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 100MHz LVDS + */ + input wire clk_100mhz_p, + input wire clk_100mhz_n, + + /* + * GPIO + */ + output wire [1:0] sfp_1_led, + output wire [1:0] sfp_2_led, + output wire [1:0] sma_led, + + /* + * Ethernet: SFP+ + */ + input wire sfp_1_rx_p, + input wire sfp_1_rx_n, + output wire sfp_1_tx_p, + output wire sfp_1_tx_n, + input wire sfp_2_rx_p, + input wire sfp_2_rx_n, + output wire sfp_2_tx_p, + output wire sfp_2_tx_n, + input wire sfp_mgt_refclk_p, + input wire sfp_mgt_refclk_n, + output wire sfp_1_tx_disable, + output wire sfp_2_tx_disable, + input wire sfp_1_npres, + input wire sfp_2_npres, + input wire sfp_1_los, + input wire sfp_2_los, + output wire sfp_1_rs, + output wire sfp_2_rs +); + +// Clock and reset + +wire clk_100mhz_ibufg; +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +// Internal 156.25 MHz clock +wire clk_156mhz_int; +wire rst_156mhz_int; + +wire mmcm_rst = 1'b0; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS #( + .DIFF_TERM("FALSE"), + .IBUF_LOW_PWR("FALSE") +) +clk_100mhz_ibufg_inst ( + .O (clk_100mhz_ibufg), + .I (clk_100mhz_p), + .IB (clk_100mhz_n) +); + +// MMCM instance +// 100 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 600 MHz to 1440 MHz +// M = 10, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCME3_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(10), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(8.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_100mhz_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire [1:0] sfp_1_led_int; +wire [1:0] sfp_2_led_int; +wire [1:0] sma_led_int; + +// XGMII 10G PHY + +assign sfp_1_tx_disable = 1'b0; +assign sfp_2_tx_disable = 1'b0; +assign sfp_1_rs = 1'b1; +assign sfp_2_rs = 1'b1; + +wire sfp_1_tx_clk_int = clk_156mhz_int; +wire sfp_1_tx_rst_int = rst_156mhz_int; +wire [63:0] sfp_1_txd_int; +wire [7:0] sfp_1_txc_int; +wire sfp_1_rx_clk_int = clk_156mhz_int; +wire sfp_1_rx_rst_int = rst_156mhz_int; +wire [63:0] sfp_1_rxd_int; +wire [7:0] sfp_1_rxc_int; +wire sfp_2_tx_clk_int = clk_156mhz_int; +wire sfp_2_tx_rst_int = rst_156mhz_int; +wire [63:0] sfp_2_txd_int; +wire [7:0] sfp_2_txc_int; +wire sfp_2_rx_clk_int = clk_156mhz_int; +wire sfp_2_rx_rst_int = rst_156mhz_int; +wire [63:0] sfp_2_rxd_int; +wire [7:0] sfp_2_rxc_int; + +wire sfp_1_rx_block_lock; +wire sfp_2_rx_block_lock; + +wire sfp_mgt_refclk; + +wire [1:0] gt_txclkout; +wire gt_txusrclk; +wire gt_txusrclk2; + +wire [1:0] gt_rxclkout; +wire [1:0] gt_rxusrclk; +wire [1:0] gt_rxusrclk2; + +wire gt_reset_tx_done; +wire gt_reset_rx_done; + +wire [1:0] gt_txprgdivresetdone; +wire [1:0] gt_txpmaresetdone; +wire [1:0] gt_rxprgdivresetdone; +wire [1:0] gt_rxpmaresetdone; + +wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); +wire gt_rx_reset = ~>_rxpmaresetdone; + +reg gt_userclk_tx_active = 1'b0; +reg [1:0] gt_userclk_rx_active = 1'b0; + +IBUFDS_GTE3 ibufds_gte3_sfp_mgt_refclk_inst ( + .I (sfp_mgt_refclk_p), + .IB (sfp_mgt_refclk_n), + .CEB (1'b0), + .O (sfp_mgt_refclk), + .ODIV2 () +); + +BUFG_GT bufg_gt_tx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txclkout[0]), + .O (gt_txusrclk) +); + +BUFG_GT bufg_gt_tx_usrclk2_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd1), + .I (gt_txclkout[0]), + .O (gt_txusrclk2) +); + +assign clk_156mhz_int = gt_txusrclk2; + +always @(posedge gt_txusrclk, posedge gt_tx_reset) begin + if (gt_tx_reset) begin + gt_userclk_tx_active <= 1'b0; + end else begin + gt_userclk_tx_active <= 1'b1; + end +end + +genvar n; + +generate + +for (n = 0 ; n < 2; n = n + 1) begin + + BUFG_GT bufg_gt_rx_usrclk_0_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk[n]) + ); + + BUFG_GT bufg_gt_rx_usrclk2_0_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd1), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk2[n]) + ); + + always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin + if (gt_rx_reset) begin + gt_userclk_rx_active[n] <= 1'b0; + end else begin + gt_userclk_rx_active[n] <= 1'b1; + end + end + +end + +endgenerate + +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz_int), + .rst(~gt_reset_tx_done), + .sync_reset_out(rst_156mhz_int) +); + +wire [5:0] sfp_1_gt_txheader; +wire [127:0] sfp_1_gt_txdata; +wire sfp_1_gt_rxgearboxslip; +wire [5:0] sfp_1_gt_rxheader; +wire [1:0] sfp_1_gt_rxheadervalid; +wire [127:0] sfp_1_gt_rxdata; +wire [1:0] sfp_1_gt_rxdatavalid; + +wire [5:0] sfp_2_gt_txheader; +wire [127:0] sfp_2_gt_txdata; +wire sfp_2_gt_rxgearboxslip; +wire [5:0] sfp_2_gt_rxheader; +wire [1:0] sfp_2_gt_rxheadervalid; +wire [127:0] sfp_2_gt_rxdata; +wire [1:0] sfp_2_gt_rxdatavalid; + +gtwizard_ultrascale_0 +sfp_gth_inst ( + .gtwiz_userclk_tx_active_in(>_userclk_tx_active), + .gtwiz_userclk_rx_active_in(>_userclk_rx_active), + + .gtwiz_reset_clk_freerun_in(clk_125mhz_int), + .gtwiz_reset_all_in(rst_125mhz_int), + + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(1'b0), + + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(1'b0), + + .gtwiz_reset_rx_cdr_stable_out(), + + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + + .gtrefclk00_in(sfp_mgt_refclk), + + .qpll0outclk_out(), + .qpll0outrefclk_out(), + + .gthrxn_in({sfp_2_rx_n, sfp_1_rx_n}), + .gthrxp_in({sfp_2_rx_p, sfp_1_rx_p}), + + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk2), + + .txdata_in({sfp_2_gt_txdata, sfp_1_gt_txdata}), + .txheader_in({sfp_2_gt_txheader, sfp_1_gt_txheader}), + .txsequence_in({2{7'b0}}), + + .txusrclk_in({2{gt_txusrclk}}), + .txusrclk2_in({2{gt_txusrclk2}}), + + .gtpowergood_out(), + + .gthtxn_out({sfp_2_tx_n, sfp_1_tx_n}), + .gthtxp_out({sfp_2_tx_p, sfp_1_tx_p}), + + .txpolarity_in(2'b11), + .rxpolarity_in(2'b00), + + .rxgearboxslip_in({sfp_2_gt_rxgearboxslip, sfp_1_gt_rxgearboxslip}), + .rxdata_out({sfp_2_gt_rxdata, sfp_1_gt_rxdata}), + .rxdatavalid_out({sfp_2_gt_rxdatavalid, sfp_1_gt_rxdatavalid}), + .rxheader_out({sfp_2_gt_rxheader, sfp_1_gt_rxheader}), + .rxheadervalid_out({sfp_2_gt_rxheadervalid, sfp_1_gt_rxheadervalid}), + .rxoutclk_out(gt_rxclkout), + .rxpmaresetdone_out(gt_rxpmaresetdone), + .rxprgdivresetdone_out(gt_rxprgdivresetdone), + .rxstartofseq_out(), + + .txoutclk_out(gt_txclkout), + .txpmaresetdone_out(gt_txpmaresetdone), + .txprgdivresetdone_out(gt_txprgdivresetdone) +); + +wire sfp_1_serdes_reset; + +sync_reset #( + .N(4) +) +sfp_1_pcs_pma_rx_serdes_reset_sync_inst ( + .clk(gt_rxusrclk[0]), + .rst(~gt_reset_rx_done), + .sync_reset_out(sfp_1_serdes_reset) +); + +ten_gig_eth_pcs_pma_0 +sfp_pcs_pma_1 ( + .rx_reset_0(rst_156mhz_int), + .rx_mii_d_0(sfp_1_rxd_int), + .rx_mii_c_0(sfp_1_rxc_int), + + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + .stat_rx_block_lock_0(sfp_1_rx_block_lock), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + .tx_reset_0(rst_156mhz_int), + .tx_mii_d_0(sfp_1_txd_int), + .tx_mii_c_0(sfp_1_txc_int), + + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + .stat_tx_local_fault_0(), + + // GTH interface + .tx_core_clk_0(clk_156mhz_int), + .rx_core_clk_0(clk_156mhz_int), + .rx_serdes_clk_0(gt_rxusrclk2[0]), + .rx_serdes_reset_0(sfp_1_serdes_reset), + .rxgearboxslip_in_0(sfp_1_gt_rxgearboxslip), + .rxdatavalid_out_0(sfp_1_gt_rxdatavalid), + .rxheader_out_0(sfp_1_gt_rxheader), + .rxheadervalid_out_0(sfp_1_gt_rxheadervalid), + .rx_serdes_data_out_0(sfp_1_gt_rxdata), + .tx_serdes_data_in_0(sfp_1_gt_txdata), + .txheader_in_0(sfp_1_gt_txheader) +); + +wire sfp_2_serdes_reset; + +sync_reset #( + .N(4) +) +sfp_2_pcs_pma_rx_serdes_reset_sync_inst ( + .clk(gt_rxusrclk[1]), + .rst(~gt_reset_rx_done), + .sync_reset_out(sfp_2_serdes_reset) +); + +ten_gig_eth_pcs_pma_0 +sfp_pcs_pma_2 ( + .rx_reset_0(rst_156mhz_int), + .rx_mii_d_0(sfp_2_rxd_int), + .rx_mii_c_0(sfp_2_rxc_int), + + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + .stat_rx_block_lock_0(sfp_2_rx_block_lock), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + .tx_reset_0(rst_156mhz_int), + .tx_mii_d_0(sfp_2_txd_int), + .tx_mii_c_0(sfp_2_txc_int), + + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + .stat_tx_local_fault_0(), + + // GTH interface + .tx_core_clk_0(clk_156mhz_int), + .rx_core_clk_0(clk_156mhz_int), + .rx_serdes_clk_0(gt_rxusrclk2[1]), + .rx_serdes_reset_0(sfp_2_serdes_reset), + .rxgearboxslip_in_0(sfp_2_gt_rxgearboxslip), + .rxdatavalid_out_0(sfp_2_gt_rxdatavalid), + .rxheader_out_0(sfp_2_gt_rxheader), + .rxheadervalid_out_0(sfp_2_gt_rxheadervalid), + .rx_serdes_data_out_0(sfp_2_gt_rxdata), + .tx_serdes_data_in_0(sfp_2_gt_txdata), + .txheader_in_0(sfp_2_gt_txheader) +); + +assign sfp_1_led[0] = sfp_1_rx_block_lock; +assign sfp_1_led[1] = 1'b0; +assign sfp_2_led[0] = sfp_2_rx_block_lock; +assign sfp_2_led[1] = 1'b0; +assign sma_led = sma_led_int; + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + /* + * GPIO + */ + .sfp_1_led(sfp_1_led_int), + .sfp_2_led(sfp_2_led_int), + .sma_led(sma_led_int), + /* + * Ethernet: SFP+ + */ + .sfp_1_tx_clk(sfp_1_tx_clk_int), + .sfp_1_tx_rst(sfp_1_tx_rst_int), + .sfp_1_txd(sfp_1_txd_int), + .sfp_1_txc(sfp_1_txc_int), + .sfp_1_rx_clk(sfp_1_rx_clk_int), + .sfp_1_rx_rst(sfp_1_rx_rst_int), + .sfp_1_rxd(sfp_1_rxd_int), + .sfp_1_rxc(sfp_1_rxc_int), + .sfp_2_tx_clk(sfp_2_tx_clk_int), + .sfp_2_tx_rst(sfp_2_tx_rst_int), + .sfp_2_txd(sfp_2_txd_int), + .sfp_2_txc(sfp_2_txc_int), + .sfp_2_rx_clk(sfp_2_rx_clk_int), + .sfp_2_rx_rst(sfp_2_rx_rst_int), + .sfp_2_rxd(sfp_2_rxd_int), + .sfp_2_rxc(sfp_2_rxc_int) +); + +endmodule diff --git a/example/ExaNIC_X10/fpga/rtl/fpga_core.v b/example/ExaNIC_X10/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..b710b1de5 --- /dev/null +++ b/example/ExaNIC_X10/fpga/rtl/fpga_core.v @@ -0,0 +1,588 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA core logic + */ +module fpga_core +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + output wire [1:0] sfp_1_led, + output wire [1:0] sfp_2_led, + output wire [1:0] sma_led, + + /* + * Ethernet: QSFP28 + */ + input wire sfp_1_tx_clk, + input wire sfp_1_tx_rst, + output wire [63:0] sfp_1_txd, + output wire [7:0] sfp_1_txc, + input wire sfp_1_rx_clk, + input wire sfp_1_rx_rst, + input wire [63:0] sfp_1_rxd, + input wire [7:0] sfp_1_rxc, + input wire sfp_2_tx_clk, + input wire sfp_2_tx_rst, + output wire [63:0] sfp_2_txd, + output wire [7:0] sfp_2_txc, + input wire sfp_2_rx_clk, + input wire sfp_2_rx_rst, + input wire [63:0] sfp_2_rxd, + input wire [7:0] sfp_2_rxc +); + +// AXI between MAC and Ethernet modules +wire [63:0] rx_axis_tdata; +wire [7:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [63:0] tx_axis_tdata; +wire [7:0] tx_axis_tkeep; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [63:0] rx_eth_payload_axis_tdata; +wire [7:0] rx_eth_payload_axis_tkeep; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [63:0] tx_eth_payload_axis_tdata; +wire [7:0] tx_eth_payload_axis_tkeep; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [63:0] rx_ip_payload_axis_tdata; +wire [7:0] rx_ip_payload_axis_tkeep; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [63:0] tx_ip_payload_axis_tdata; +wire [7:0] tx_ip_payload_axis_tkeep; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [63:0] rx_udp_payload_axis_tdata; +wire [7:0] rx_udp_payload_axis_tkeep; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [63:0] tx_udp_payload_axis_tdata; +wire [7:0] tx_udp_payload_axis_tkeep; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; + +wire [63:0] rx_fifo_udp_payload_axis_tdata; +wire [7:0] rx_fifo_udp_payload_axis_tkeep; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; + +wire [63:0] tx_fifo_udp_payload_axis_tdata; +wire [7:0] tx_fifo_udp_payload_axis_tkeep; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_axis_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tkeep = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = ~match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_axis_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_axis_tvalid & rx_udp_payload_axis_tready & rx_udp_payload_axis_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid & match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready & match_cond) | no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; + +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; + +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid & match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_axis_tvalid; + if (tx_udp_payload_axis_tvalid & ~valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; + end + end +end + +assign led = led_reg; + +assign sfp_2_txd = 64'h0707070707070707; +assign sfp_2_txc = 8'hff; + +eth_mac_10g_fifo #( + .ENABLE_PADDING(1), + .ENABLE_DIC(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(9), + .RX_FIFO_ADDR_WIDTH(9) +) +eth_mac_10g_fifo_inst ( + .rx_clk(sfp_1_rx_clk), + .rx_rst(sfp_1_rx_rst), + .tx_clk(sfp_1_tx_clk), + .tx_rst(sfp_1_tx_rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .xgmii_rxd(sfp_1_rxd), + .xgmii_rxc(sfp_1_rxc), + .xgmii_txd(sfp_1_txd), + .xgmii_txc(sfp_1_txc), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + .ifg_delay(8'd12) +); + +eth_axis_rx_64 +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(rx_axis_tdata), + .s_axis_tkeep(rx_axis_tkeep), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx_64 +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // AXI output + .m_axis_tdata(tx_axis_tdata), + .m_axis_tkeep(tx_axis_tkeep), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete_64 +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // IP frame input + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), + // IP frame output + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), + // UDP frame input + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), + // UDP frame output + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(1'b0) +); + +axis_fifo #( + .ADDR_WIDTH(10), + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(8), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(0) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), + + // AXI output + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() +); + +endmodule diff --git a/example/ExaNIC_X10/fpga/rtl/sync_reset.v b/example/ExaNIC_X10/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..acbcf1c6e --- /dev/null +++ b/example/ExaNIC_X10/fpga/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/ExaNIC_X10/fpga/rtl/sync_signal.v b/example/ExaNIC_X10/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/example/ExaNIC_X10/fpga/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/ExaNIC_X10/fpga/tb/arp_ep.py b/example/ExaNIC_X10/fpga/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/ExaNIC_X10/fpga/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga/tb/axis_ep.py b/example/ExaNIC_X10/fpga/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/ExaNIC_X10/fpga/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga/tb/eth_ep.py b/example/ExaNIC_X10/fpga/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/ExaNIC_X10/fpga/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga/tb/gmii_ep.py b/example/ExaNIC_X10/fpga/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/ExaNIC_X10/fpga/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga/tb/ip_ep.py b/example/ExaNIC_X10/fpga/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/ExaNIC_X10/fpga/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga/tb/test_fpga_core.py b/example/ExaNIC_X10/fpga/tb/test_fpga_core.py new file mode 100755 index 000000000..773a2ff3b --- /dev/null +++ b/example/ExaNIC_X10/fpga/tb/test_fpga_core.py @@ -0,0 +1,294 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016-2018 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 + +import eth_ep +import arp_ep +import udp_ep +import gmii_ep +import xgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") +srcs.append("../lib/eth/rtl/arp_64.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") +srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + sfp_1_txd = Signal(intbv(0)[64:]) + sfp_1_txc = Signal(intbv(0)[8:]) + sfp_2_txd = Signal(intbv(0)[64:]) + sfp_2_txc = Signal(intbv(0)[8:]) + + # Outputs + sfp_1_led = Signal(intbv(0)[2:]) + sfp_2_led = Signal(intbv(0)[2:]) + sma_led = Signal(intbv(0)[2:]) + sfp_1_tx_clk = Signal(bool(0)) + sfp_1_tx_rst = Signal(bool(0)) + sfp_1_rx_clk = Signal(bool(0)) + sfp_1_rx_rst = Signal(bool(0)) + sfp_1_rxd = Signal(intbv(0)[64:]) + sfp_1_rxc = Signal(intbv(0)[8:]) + sfp_2_tx_clk = Signal(bool(0)) + sfp_2_tx_rst = Signal(bool(0)) + sfp_2_rx_clk = Signal(bool(0)) + sfp_2_rx_rst = Signal(bool(0)) + sfp_2_rxd = Signal(intbv(0)[64:]) + sfp_2_rxc = Signal(intbv(0)[8:]) + + # sources and sinks + sfp_1_source = xgmii_ep.XGMIISource() + sfp_1_source_logic = sfp_1_source.create_logic(sfp_1_tx_clk, sfp_1_tx_rst, txd=sfp_1_rxd, txc=sfp_1_rxc, name='sfp_1_source') + + sfp_1_sink = xgmii_ep.XGMIISink() + sfp_1_sink_logic = sfp_1_sink.create_logic(sfp_1_rx_clk, sfp_1_rx_rst, rxd=sfp_1_txd, rxc=sfp_1_txc, name='sfp_1_sink') + + sfp_2_source = xgmii_ep.XGMIISource() + sfp_2_source_logic = sfp_2_source.create_logic(sfp_2_tx_clk, sfp_2_tx_rst, txd=sfp_2_rxd, txc=sfp_2_rxc, name='sfp_2_source') + + sfp_2_sink = xgmii_ep.XGMIISink() + sfp_2_sink_logic = sfp_2_sink.create_logic(sfp_2_rx_clk, sfp_2_rx_rst, rxd=sfp_2_txd, rxc=sfp_2_txc, name='sfp_2_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, + + sfp_1_led=sfp_1_led, + sfp_2_led=sfp_2_led, + sma_led=sma_led, + + sfp_1_tx_clk=sfp_1_tx_clk, + sfp_1_tx_rst=sfp_1_tx_rst, + sfp_1_txd=sfp_1_txd, + sfp_1_txc=sfp_1_txc, + sfp_1_rx_clk=sfp_1_rx_clk, + sfp_1_rx_rst=sfp_1_rx_rst, + sfp_1_rxd=sfp_1_rxd, + sfp_1_rxc=sfp_1_rxc, + sfp_2_tx_clk=sfp_2_tx_clk, + sfp_2_tx_rst=sfp_2_tx_rst, + sfp_2_txd=sfp_2_txd, + sfp_2_txc=sfp_2_txc, + sfp_2_rx_clk=sfp_2_rx_clk, + sfp_2_rx_rst=sfp_2_rx_rst, + sfp_2_rxd=sfp_2_rxd, + sfp_2_rxc=sfp_2_rxc + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @always_comb + def clk_logic(): + sfp_1_tx_clk.next = clk + sfp_1_tx_rst.next = rst + sfp_1_rx_clk.next = clk + sfp_1_rx_rst.next = rst + sfp_2_tx_clk.next = clk + sfp_2_tx_rst.next = rst + sfp_2_rx_clk.next = clk + sfp_2_rx_rst.next = rst + + @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 + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + sfp_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while sfp_1_sink.empty(): + yield clk.posedge + + rx_frame = sfp_1_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + sfp_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while sfp_1_sink.empty(): + yield clk.posedge + + rx_frame = sfp_1_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert sfp_1_source.empty() + assert sfp_1_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() diff --git a/example/ExaNIC_X10/fpga/tb/test_fpga_core.v b/example/ExaNIC_X10/fpga/tb/test_fpga_core.v new file mode 100644 index 000000000..790c5ced7 --- /dev/null +++ b/example/ExaNIC_X10/fpga/tb/test_fpga_core.v @@ -0,0 +1,122 @@ +/* + +Copyright (c) 2016-2018 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg sfp_1_tx_clk = 0; +reg sfp_1_tx_rst = 0; +reg sfp_1_rx_clk = 0; +reg sfp_1_rx_rst = 0; +reg [63:0] sfp_1_rxd = 0; +reg [7:0] sfp_1_rxc = 0; +reg sfp_2_tx_clk = 0; +reg sfp_2_tx_rst = 0; +reg sfp_2_rx_clk = 0; +reg sfp_2_rx_rst = 0; +reg [63:0] sfp_2_rxd = 0; +reg [7:0] sfp_2_rxc = 0; + +// Outputs +wire [1:0] sfp_1_led; +wire [1:0] sfp_2_led; +wire [1:0] sma_led; +wire [63:0] sfp_1_txd; +wire [7:0] sfp_1_txc; +wire [63:0] sfp_2_txd; +wire [7:0] sfp_2_txc; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + sfp_1_tx_clk, + sfp_1_tx_rst, + sfp_1_rx_clk, + sfp_1_rx_rst, + sfp_1_rxd, + sfp_1_rxc, + sfp_2_tx_clk, + sfp_2_tx_rst, + sfp_2_rx_clk, + sfp_2_rx_rst, + sfp_2_rxd, + sfp_2_rxc + ); + $to_myhdl( + sfp_1_led, + sfp_2_led, + sma_led, + sfp_1_txd, + sfp_1_txc, + sfp_2_txd, + sfp_2_txc + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .sfp_1_led(sfp_1_led), + .sfp_2_led(sfp_2_led), + .sma_led(sma_led), + .sfp_1_tx_clk(sfp_1_tx_clk), + .sfp_1_tx_rst(sfp_1_tx_rst), + .sfp_1_txd(sfp_1_txd), + .sfp_1_txc(sfp_1_txc), + .sfp_1_rx_clk(sfp_1_rx_clk), + .sfp_1_rx_rst(sfp_1_rx_rst), + .sfp_1_rxd(sfp_1_rxd), + .sfp_1_rxc(sfp_1_rxc), + .sfp_2_tx_clk(sfp_2_tx_clk), + .sfp_2_tx_rst(sfp_2_tx_rst), + .sfp_2_txd(sfp_2_txd), + .sfp_2_txc(sfp_2_txc), + .sfp_2_rx_clk(sfp_2_rx_clk), + .sfp_2_rx_rst(sfp_2_rx_rst), + .sfp_2_rxd(sfp_2_rxd), + .sfp_2_rxc(sfp_2_rxc) +); + +endmodule diff --git a/example/ExaNIC_X10/fpga/tb/udp_ep.py b/example/ExaNIC_X10/fpga/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/ExaNIC_X10/fpga/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga/tb/xgmii_ep.py b/example/ExaNIC_X10/fpga/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/example/ExaNIC_X10/fpga/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file From 1f793fa7d02543e63681fbcb2647cafd5843daa6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 8 Jan 2019 17:24:22 -0800 Subject: [PATCH 494/617] Update readme --- example/ExaNIC_X10/fpga/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example/ExaNIC_X10/fpga/README.md b/example/ExaNIC_X10/fpga/README.md index f2d77ef10..c11efb3d7 100644 --- a/example/ExaNIC_X10/fpga/README.md +++ b/example/ExaNIC_X10/fpga/README.md @@ -6,8 +6,7 @@ This example design targets the Exablaze ExaNIC X10 FPGA board. The design by default listens to UDP port 1234 at IP address 192.168.1.128 and will echo back any packets received. The design will also respond correctly -to ARP requests. The design also enables the gigabit Ethernet interface for -testing with a QSFP loopback adapter. +to ARP requests. FPGA: xcku035-fbva676-2-c PHY: 10G BASE-R PHY IP core and internal GTH transceiver From 2628249059aa9bbd7e84ca578ccbf1d0e783e57c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 8 Jan 2019 17:27:21 -0800 Subject: [PATCH 495/617] Add ADM-PCIE-9V3 example design --- example/ADM_PCIE_9V3/fpga_10g/Makefile | 25 + example/ADM_PCIE_9V3/fpga_10g/README.md | 24 + .../ADM_PCIE_9V3/fpga_10g/common/vivado.mk | 118 ++ example/ADM_PCIE_9V3/fpga_10g/fpga.xdc | 181 +++ example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile | 59 + .../fpga_10g/ip/gtwizard_ultrascale_0.xci | 1396 +++++++++++++++++ .../fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci | 127 ++ example/ADM_PCIE_9V3/fpga_10g/lib/eth | 1 + .../fpga_10g/rtl/debounce_switch.v | 89 ++ example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v | 1104 +++++++++++++ example/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v | 659 ++++++++ .../ADM_PCIE_9V3/fpga_10g/rtl/sync_reset.v | 52 + .../ADM_PCIE_9V3/fpga_10g/rtl/sync_signal.v | 58 + example/ADM_PCIE_9V3/fpga_10g/tb/arp_ep.py | 1 + example/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py | 1 + example/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py | 1 + example/ADM_PCIE_9V3/fpga_10g/tb/gmii_ep.py | 1 + example/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py | 1 + .../fpga_10g/tb/test_fpga_core.py | 462 ++++++ .../ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v | 269 ++++ example/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py | 1 + example/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py | 1 + 22 files changed, 4631 insertions(+) create mode 100644 example/ADM_PCIE_9V3/fpga_10g/Makefile create mode 100644 example/ADM_PCIE_9V3/fpga_10g/README.md create mode 100644 example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk create mode 100644 example/ADM_PCIE_9V3/fpga_10g/fpga.xdc create mode 100644 example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile create mode 100644 example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci create mode 100644 example/ADM_PCIE_9V3/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci create mode 120000 example/ADM_PCIE_9V3/fpga_10g/lib/eth create mode 100644 example/ADM_PCIE_9V3/fpga_10g/rtl/debounce_switch.v create mode 100644 example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v create mode 100644 example/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v create mode 100644 example/ADM_PCIE_9V3/fpga_10g/rtl/sync_reset.v create mode 100644 example/ADM_PCIE_9V3/fpga_10g/rtl/sync_signal.v create mode 120000 example/ADM_PCIE_9V3/fpga_10g/tb/arp_ep.py create mode 120000 example/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py create mode 120000 example/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py create mode 120000 example/ADM_PCIE_9V3/fpga_10g/tb/gmii_ep.py create mode 120000 example/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py create mode 100755 example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py create mode 100644 example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v create mode 120000 example/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py create mode 120000 example/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py diff --git a/example/ADM_PCIE_9V3/fpga_10g/Makefile b/example/ADM_PCIE_9V3/fpga_10g/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/ADM_PCIE_9V3/fpga_10g/README.md b/example/ADM_PCIE_9V3/fpga_10g/README.md new file mode 100644 index 000000000..89881d19c --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/README.md @@ -0,0 +1,24 @@ +# Verilog Ethernet ADM-PCIE-9V3 Example Design + +## Introduction + +This example design targets the Alpha Data ADM-PCIE-9V3 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +FPGA: xcvu3p-ffvc1517-2-i +PHY: 10G BASE-R PHY IP core and internal GTY transceiver + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the ADM-PCIE-9V3 board with Vivado. Then run +netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any text +entered into netcat will be echoed back after pressing enter. + diff --git a/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk b/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk new file mode 100644 index 000000000..a54b530f6 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk @@ -0,0 +1,118 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile $(XCI_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga.xdc b/example/ADM_PCIE_9V3/fpga_10g/fpga.xdc new file mode 100644 index 000000000..e5783955a --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga.xdc @@ -0,0 +1,181 @@ +# XDC constraints for the ADM-PCIE-9V3 +# part: xcvu3p-ffvc1517-2-i + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN {DIV-1} [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 8 [current_design] +set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] +set_property BITSTREAM.CONFIG.UNUSEDPIN {Pullnone} [current_design] +set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design] + +# 300 MHz system clock +set_property -dict {LOC AP26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_p] +set_property -dict {LOC AP27 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_n] +create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p] +set_clock_groups -asynchronous -group [get_clocks clk_300mhz -include_generated_clocks] + +# LEDs +set_property -dict {LOC AT27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[0]}] +set_property -dict {LOC AU27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[1]}] +set_property -dict {LOC AU23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_r}] +set_property -dict {LOC AH24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[0]}] +set_property -dict {LOC AJ23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[1]}] + +# Switches +set_property -dict {LOC AV27 IOSTANDARD LVCMOS18} [get_ports {user_sw[0]}] +set_property -dict {LOC AW27 IOSTANDARD LVCMOS18} [get_ports {user_sw[1]}] + +# GPIO +#set_property -dict {LOC G30 IOSTANDARD LVCMOS18} [get_ports gpio_p[0]] +#set_property -dict {LOC F30 IOSTANDARD LVCMOS18} [get_ports gpio_n[0]] +#set_property -dict {LOC J31 IOSTANDARD LVCMOS18} [get_ports gpio_p[1]] +#set_property -dict {LOC H31 IOSTANDARD LVCMOS18} [get_ports gpio_n[1]] + +# QSFP28 Interfaces +set_property -dict {LOC G38 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXN0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC G39 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXP0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC E38 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXN1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC E39 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXP1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC C38 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXN2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC C39 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXP2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC B36 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXN3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC B37 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXP3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC F35 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXN0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC F36 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXP0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC D35 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXN1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC D36 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXP1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC C33 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXN2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC C34 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXP2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC A33 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXN3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC A34 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXP3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC N33 } [get_ports qsfp_0_mgt_refclk_p] ;# MGTREFCLK0P_128 from ? +#set_property -dict {LOC N34 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_128 from ? +set_property -dict {LOC F29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_0_modprs_l] +set_property -dict {LOC D31 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_0_sel_l] + +# 161.1328125 MHz MGT reference clock +create_clock -period 6.206 -name qsfp_0_mgt_refclk [get_ports qsfp_0_mgt_refclk_p] +set_clock_groups -asynchronous -group [get_clocks qsfp_0_mgt_refclk -include_generated_clocks] + +set_property -dict {LOC R38 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC R39 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC N38 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC N39 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC L38 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC L39 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC J38 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC J39 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC P35 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC P36 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC M35 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC M36 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC K35 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC K36 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC H35 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC H36 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC U33 } [get_ports qsfp_1_mgt_refclk_p] ;# MGTREFCLK0P_127 from ? +#set_property -dict {LOC U34 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_127 from ? +set_property -dict {LOC F33 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_1_modprs_l] +set_property -dict {LOC D30 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_1_sel_l] + +# 161.1328125 MHz MGT reference clock +create_clock -period 6.206 -name qsfp_1_mgt_refclk [get_ports qsfp_1_mgt_refclk_p] +set_clock_groups -asynchronous -group [get_clocks qsfp_1_mgt_refclk -include_generated_clocks] + +set_property -dict {LOC B29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_reset_l] +set_property -dict {LOC C29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_int_l] +#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_i2c_scl] +#set_property -dict {LOC A29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_i2c_sda] + +# PCIe Interface +#set_property -dict {LOC J2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC J1 } [get_ports {pcie_rx_n[0]}] ;# MGTYTXP3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC H5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXN3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC H4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXP3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC L2 } [get_ports {pcie_rx_p[1]}] ;# MGTYTXN2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC L1 } [get_ports {pcie_rx_n[1]}] ;# MGTYTXP2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC K5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXN2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC K4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXP2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC N2 } [get_ports {pcie_rx_p[2]}] ;# MGTYTXN1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC N1 } [get_ports {pcie_rx_n[2]}] ;# MGTYTXP1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC M5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXN1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC M4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXP1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC R2 } [get_ports {pcie_rx_p[3]}] ;# MGTYTXN0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC R1 } [get_ports {pcie_rx_n[3]}] ;# MGTYTXP0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC P5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXN0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC P4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXP0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC U2 } [get_ports {pcie_rx_p[4]}] ;# MGTYTXN3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC U1 } [get_ports {pcie_rx_n[4]}] ;# MGTYTXP3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC T5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXN3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC T4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXP3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC W2 } [get_ports {pcie_rx_p[5]}] ;# MGTYTXN2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC W1 } [get_ports {pcie_rx_n[5]}] ;# MGTYTXP2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC V5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXN2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC V4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXP2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AA2 } [get_ports {pcie_rx_p[6]}] ;# MGTYTXN1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AA1 } [get_ports {pcie_rx_n[6]}] ;# MGTYTXP1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXN1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXP1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AC2 } [get_ports {pcie_rx_p[7]}] ;# MGTYTXN0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AC1 } [get_ports {pcie_rx_n[7]}] ;# MGTYTXP0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXN0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXP0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AE2 } [get_ports {pcie_rx_p[8]}] ;# MGTYTXN3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AE1 } [get_ports {pcie_rx_n[8]}] ;# MGTYTXP3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXN3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXP3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[9]}] ;# MGTYTXN2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[9]}] ;# MGTYTXP2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXN2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXP2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[10]}] ;# MGTYTXN1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[10]}] ;# MGTYTXP1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AK5 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXN1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AK4 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXP1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[11]}] ;# MGTYTXN0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[11]}] ;# MGTYTXP0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AM5 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXN0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AM4 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXP0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[12]}] ;# MGTYTXN3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[12]}] ;# MGTYTXP3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AP5 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXN3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AP4 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXP3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[13]}] ;# MGTYTXN2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[13]}] ;# MGTYTXP2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AT5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXN2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AT4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXP2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[14]}] ;# MGTYTXN1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[14]}] ;# MGTYTXP1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXN1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXP1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[15]}] ;# MGTYTXN0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[15]}] ;# MGTYTXP0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AW7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXN0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AW6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXP0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AA7 } [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_226 +#set_property -dict {LOC AA6 } [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_226 +#set_property -dict {LOC AJ7 } [get_ports pcie_refclk_2_p] ;# MGTREFCLK0P_224 +#set_property -dict {LOC AJ6 } [get_ports pcie_refclk_2_n] ;# MGTREFCLK0N_224 +#set_property -dict {LOC AJ31 IOSTANDARD LVCMOS18 PULLUP true} [get_ports perst_0] +#set_property -dict {LOC AH29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports perst_1] + +# 100 MHz MGT reference clock +#create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_1_p] +#set_clock_groups -asynchronous -group [get_clocks pcie_mgt_refclk_1 -include_generated_clocks] +#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p] +#set_clock_groups -asynchronous -group [get_clocks pcie_mgt_refclk_2 -include_generated_clocks] + +# QSPI flash +#set_property -dict {LOC AB10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi_clk}] +#set_property -dict {LOC AB8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[0]}] +#set_property -dict {LOC AD8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[1]}] +#set_property -dict {LOC Y8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[2]}] +#set_property -dict {LOC AC8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[3]}] +#set_property -dict {LOC AF30 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[0]}] +#set_property -dict {LOC AG30 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[1]}] +#set_property -dict {LOC AF28 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[2]}] +#set_property -dict {LOC AG28 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[3]}] diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile new file mode 100644 index 000000000..87ab18cad --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -0,0 +1,59 @@ + +# FPGA settings +FPGA_PART = xcvu3p-ffvc1517-2-i +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp_64.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v +SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v + +# XDC files +XDC_FILES = fpga.xdc + +# IP +XCI_FILES += ip/gtwizard_ultrascale_0.xci +XCI_FILES += ip/ten_gig_eth_pcs_pma_0.xci + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl + echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "exit" >> program.tcl + vivado -mode batch -source program.tcl + diff --git a/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci b/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci new file mode 100644 index 000000000..996e812b5 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci @@ -0,0 +1,1396 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gtwizard_ultrascale_0 + + + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111000000000000" + 2 + 2578.125 + 0 + 125 + 67 + 3 + 2 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 0 + 250 + 0 + 0 + 0 + 0 + 0 + 1 + "00000000" + "00000000" + 1 + 4 + 0 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000" + 0 + "00000000" + 1 + 0 + 5000 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + 0 + "1010000011" + 0 + "0101111100" + 4 + 1 + 64 + 10.3125 + 15 + 1 + 156.2500000 + 4 + 0 + 0x000000000000000000000000000000000000000000000000 + 161.1328125 + 0 + 0 + 0 + 1 + 1 + 0 + 64 + 156.2500000 + 156.2500000 + 0 + 257.8125 + 0 + 8 + 2 + 0 + 0 + 0 + 156.25 + 0 + 0 + 1 + 4 + 1 + 64 + 10.3125 + 15 + 1 + 156.2500000 + 4 + 0 + 161.1328125 + 0 + 0 + 1 + 1 + 0 + 64 + 156.2500000 + 156.2500000 + 1 + X0Y19 X0Y18 X0Y17 X0Y16 X0Y15 X0Y14 X0Y13 X0Y12 + gtwizard_ultrascale_0 + 0 + + 125 + BOTH + 0 + GTY + 2 + 20 + 96 + 1 + gtye4 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + -1 + -1 + -1 + -1 + 1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + -1 + 0 + 0 + 0 + -1 + 0 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 33 + 0 + 10GBASE-R + 3 + 156.2500000 + 8 + 2 + 156.2500000 + false + CORE + NONE + CORE + CORE + EXAMPLE_DESIGN + CORE + EXAMPLE_DESIGN + CORE + false + NAME + false + 250 + false + false + 250 + GTY-10GBASE-R + 0 + MULTI + 1 + ENABLE + DISABLE + ENABLE + 00000000 + false + false + false + false + false + false + false + false + 00000000 + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 4 + 1 + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + false + false + false + false + false + false + false + false + 00000000 + DISABLE + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 0 + 5000 + ENABLE + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 1 + false + 0000000000 + false + 1010000011 + NONE + false + 0101111100 + true + 0 + AC + 64B66B_ASYNC + true + AUTO + 64 + 6.1862627 + -20 + 10.3125 + X0Y15 + RXPROGDIVCLK + QPLL0 + 200 + 0 + + 161.1328125 + + OFF + 0 + PROGRAMMABLE + 800 + 64 + 15 + false + 0 + 10.3125 + 257.8125 + 0 + false + QPLL0 + 156.25 + 1 + ENABLE + 64B66B_ASYNC + CUSTOM + true + 64 + 10.3125 + X0Y15 + TXPROGDIVCLK + QPLL0 + 0 + 161.1328125 + + 64 + false + 1 + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + true + true + false + true + true + true + false + true + true + true + false + false + false + false + false + true + false + false + false + false + false + true + true + true + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + virtexuplus + + xcvu3p + ffvc1517 + VERILOG + + MIXED + -2 + I + TRUE + TRUE + IP_Flow + 0 + TRUE + . + + . + 2017.2.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ADM_PCIE_9V3/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci b/example/ADM_PCIE_9V3/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci new file mode 100644 index 000000000..8014504dc --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci @@ -0,0 +1,127 @@ + + + xilinx.com + xci + unknown + 1.0 + + + ten_gig_eth_pcs_pma_0 + + + 1 + 75 + 64 + 7 + BASE-R + Asynchronous + Ethernet PCS/PMA 64-bit + MII + 0 + 0 + 0 + 0 + 0 + virtexuplus + 0 + 100.00 + Quad X0Y0 + 0 + 156.25 + GTY + None + 0 + 0 + 0 + 0 + 0 + X0Y0 + NA + NA + NA + 10 + 1 + 0 + 2 + 0 + 0 + 4 + 1 + 0 + 1 + 100 + BASE-R + Asynchronous + Ethernet PCS/PMA 64-bit + ten_gig_eth_pcs_pma_0 + MII + Custom + 0 + 0 + 0 + 0 + 0 + Custom + 0 + 100.00 + Quad_X0Y0 + 0 + 156.25 + GTY + None + 0 + 0 + 0 + 0 + 0 + X0Y0 + NA + NA + NA + 10 + 1 + 0 + 2 + 0 + 0 + false + 1 + virtexuplus + + xcvu3p + ffvc1517 + VERILOG + + MIXED + -2 + I + TRUE + TRUE + IP_Flow + 0 + TRUE + . + + . + 2017.2.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + diff --git a/example/ADM_PCIE_9V3/fpga_10g/lib/eth b/example/ADM_PCIE_9V3/fpga_10g/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_10g/rtl/debounce_switch.v b/example/ADM_PCIE_9V3/fpga_10g/rtl/debounce_switch.v new file mode 100644 index 000000000..bb631cc35 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v new file mode 100644 index 000000000..58cc9ea4f --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v @@ -0,0 +1,1104 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 300MHz LVDS + */ + input wire clk_300mhz_p, + input wire clk_300mhz_n, + + /* + * GPIO + */ + output wire [1:0] user_led_g, + output wire user_led_r, + output wire [1:0] front_led, + input wire [1:0] user_sw, + + /* + * Ethernet: QSFP28 + */ + output wire qsfp_0_tx_0_p, + output wire qsfp_0_tx_0_n, + input wire qsfp_0_rx_0_p, + input wire qsfp_0_rx_0_n, + output wire qsfp_0_tx_1_p, + output wire qsfp_0_tx_1_n, + input wire qsfp_0_rx_1_p, + input wire qsfp_0_rx_1_n, + output wire qsfp_0_tx_2_p, + output wire qsfp_0_tx_2_n, + input wire qsfp_0_rx_2_p, + input wire qsfp_0_rx_2_n, + output wire qsfp_0_tx_3_p, + output wire qsfp_0_tx_3_n, + input wire qsfp_0_rx_3_p, + input wire qsfp_0_rx_3_n, + input wire qsfp_0_mgt_refclk_p, + input wire qsfp_0_mgt_refclk_n, + input wire qsfp_0_modprs_l, + output wire qsfp_0_sel_l, + + output wire qsfp_1_tx_0_p, + output wire qsfp_1_tx_0_n, + input wire qsfp_1_rx_0_p, + input wire qsfp_1_rx_0_n, + output wire qsfp_1_tx_1_p, + output wire qsfp_1_tx_1_n, + input wire qsfp_1_rx_1_p, + input wire qsfp_1_rx_1_n, + output wire qsfp_1_tx_2_p, + output wire qsfp_1_tx_2_n, + input wire qsfp_1_rx_2_p, + input wire qsfp_1_rx_2_n, + output wire qsfp_1_tx_3_p, + output wire qsfp_1_tx_3_n, + input wire qsfp_1_rx_3_p, + input wire qsfp_1_rx_3_n, + input wire qsfp_1_mgt_refclk_p, + input wire qsfp_1_mgt_refclk_n, + input wire qsfp_1_modprs_l, + output wire qsfp_1_sel_l, + + output wire qsfp_reset_l, + input wire qsfp_int_l +); + +// Clock and reset + +wire clk_300mhz_ibufg; +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +// Internal 156.25 MHz clock +wire clk_156mhz_int; +wire rst_156mhz_int; + +wire mmcm_rst = 1'b0; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS #( + .DIFF_TERM("FALSE"), + .IBUF_LOW_PWR("FALSE") +) +clk_300mhz_ibufg_inst ( + .O (clk_300mhz_ibufg), + .I (clk_300mhz_p), + .IB (clk_300mhz_n) +); + +// MMCM instance +// 300 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 10, D = 3 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCME3_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(10), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(3), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(8.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_300mhz_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire [1:0] user_sw_int; + +debounce_switch #( + .WIDTH(2), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .in({user_sw}), + .out({user_sw_int}) +); + +// XGMII 10G PHY +assign qsfp_0_sel_l = 1'b0; + +wire qsfp_0_tx_clk_0_int = clk_156mhz_int; +wire qsfp_0_tx_rst_0_int = rst_156mhz_int; +wire [63:0] qsfp_0_txd_0_int; +wire [7:0] qsfp_0_txc_0_int; +wire qsfp_0_rx_clk_0_int = clk_156mhz_int; +wire qsfp_0_rx_rst_0_int = rst_156mhz_int; +wire [63:0] qsfp_0_rxd_0_int; +wire [7:0] qsfp_0_rxc_0_int; +wire qsfp_0_tx_clk_1_int = clk_156mhz_int; +wire qsfp_0_tx_rst_1_int = rst_156mhz_int; +wire [63:0] qsfp_0_txd_1_int; +wire [7:0] qsfp_0_txc_1_int; +wire qsfp_0_rx_clk_1_int = clk_156mhz_int; +wire qsfp_0_rx_rst_1_int = rst_156mhz_int; +wire [63:0] qsfp_0_rxd_1_int; +wire [7:0] qsfp_0_rxc_1_int; +wire qsfp_0_tx_clk_2_int = clk_156mhz_int; +wire qsfp_0_tx_rst_2_int = rst_156mhz_int; +wire [63:0] qsfp_0_txd_2_int; +wire [7:0] qsfp_0_txc_2_int; +wire qsfp_0_rx_clk_2_int = clk_156mhz_int; +wire qsfp_0_rx_rst_2_int = rst_156mhz_int; +wire [63:0] qsfp_0_rxd_2_int; +wire [7:0] qsfp_0_rxc_2_int; +wire qsfp_0_tx_clk_3_int = clk_156mhz_int; +wire qsfp_0_tx_rst_3_int = rst_156mhz_int; +wire [63:0] qsfp_0_txd_3_int; +wire [7:0] qsfp_0_txc_3_int; +wire qsfp_0_rx_clk_3_int = clk_156mhz_int; +wire qsfp_0_rx_rst_3_int = rst_156mhz_int; +wire [63:0] qsfp_0_rxd_3_int; +wire [7:0] qsfp_0_rxc_3_int; + +assign qsfp_1_sel_l = 1'b0; + +wire qsfp_1_tx_clk_0_int = clk_156mhz_int; +wire qsfp_1_tx_rst_0_int = rst_156mhz_int; +wire [63:0] qsfp_1_txd_0_int; +wire [7:0] qsfp_1_txc_0_int; +wire qsfp_1_rx_clk_0_int = clk_156mhz_int; +wire qsfp_1_rx_rst_0_int = rst_156mhz_int; +wire [63:0] qsfp_1_rxd_0_int; +wire [7:0] qsfp_1_rxc_0_int; +wire qsfp_1_tx_clk_1_int = clk_156mhz_int; +wire qsfp_1_tx_rst_1_int = rst_156mhz_int; +wire [63:0] qsfp_1_txd_1_int; +wire [7:0] qsfp_1_txc_1_int; +wire qsfp_1_rx_clk_1_int = clk_156mhz_int; +wire qsfp_1_rx_rst_1_int = rst_156mhz_int; +wire [63:0] qsfp_1_rxd_1_int; +wire [7:0] qsfp_1_rxc_1_int; +wire qsfp_1_tx_clk_2_int = clk_156mhz_int; +wire qsfp_1_tx_rst_2_int = rst_156mhz_int; +wire [63:0] qsfp_1_txd_2_int; +wire [7:0] qsfp_1_txc_2_int; +wire qsfp_1_rx_clk_2_int = clk_156mhz_int; +wire qsfp_1_rx_rst_2_int = rst_156mhz_int; +wire [63:0] qsfp_1_rxd_2_int; +wire [7:0] qsfp_1_rxc_2_int; +wire qsfp_1_tx_clk_3_int = clk_156mhz_int; +wire qsfp_1_tx_rst_3_int = rst_156mhz_int; +wire [63:0] qsfp_1_txd_3_int; +wire [7:0] qsfp_1_txc_3_int; +wire qsfp_1_rx_clk_3_int = clk_156mhz_int; +wire qsfp_1_rx_rst_3_int = rst_156mhz_int; +wire [63:0] qsfp_1_rxd_3_int; +wire [7:0] qsfp_1_rxc_3_int; + +assign qsfp_reset_l = 1'b1; + +wire qsfp_0_rx_block_lock_0; +wire qsfp_0_rx_block_lock_1; +wire qsfp_0_rx_block_lock_2; +wire qsfp_0_rx_block_lock_3; + +wire qsfp_1_rx_block_lock_0; +wire qsfp_1_rx_block_lock_1; +wire qsfp_1_rx_block_lock_2; +wire qsfp_1_rx_block_lock_3; + +wire qsfp_0_mgt_refclk; +wire qsfp_1_mgt_refclk; + +wire [7:0] gt_txclkout; +wire gt_txusrclk; + +wire [7:0] gt_rxclkout; +wire [7:0] gt_rxusrclk; + +wire gt_reset_tx_done; +wire gt_reset_rx_done; + +wire [7:0] gt_txprgdivresetdone; +wire [7:0] gt_txpmaresetdone; +wire [7:0] gt_rxprgdivresetdone; +wire [7:0] gt_rxpmaresetdone; + +wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); +wire gt_rx_reset = ~>_rxpmaresetdone; + +reg gt_userclk_tx_active = 1'b0; +reg [7:0] gt_userclk_rx_active = 1'b0; + +IBUFDS_GTE4 ibufds_gte4_qsfp_0_mgt_refclk_inst ( + .I (qsfp_0_mgt_refclk_p), + .IB (qsfp_0_mgt_refclk_n), + .CEB (1'b0), + .O (qsfp_0_mgt_refclk), + .ODIV2 () +); + +IBUFDS_GTE4 ibufds_gte4_qsfp_1_mgt_refclk_inst ( + .I (qsfp_1_mgt_refclk_p), + .IB (qsfp_1_mgt_refclk_n), + .CEB (1'b0), + .O (qsfp_1_mgt_refclk), + .ODIV2 () +); + + +BUFG_GT bufg_gt_tx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txclkout[0]), + .O (gt_txusrclk) +); + +assign clk_156mhz_int = gt_txusrclk; + +always @(posedge gt_txusrclk, posedge gt_tx_reset) begin + if (gt_tx_reset) begin + gt_userclk_tx_active <= 1'b0; + end else begin + gt_userclk_tx_active <= 1'b1; + end +end + +genvar n; + +generate + +for (n = 0; n < 8; n = n + 1) begin + + BUFG_GT bufg_gt_rx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk[n]) + ); + + always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin + if (gt_rx_reset) begin + gt_userclk_rx_active[n] <= 1'b0; + end else begin + gt_userclk_rx_active[n] <= 1'b1; + end + end + +end + +endgenerate + +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz_int), + .rst(~gt_reset_tx_done), + .sync_reset_out(rst_156mhz_int) +); + +wire [5:0] qsfp_0_gt_txheader_0; +wire [63:0] qsfp_0_gt_txdata_0; +wire qsfp_0_gt_rxgearboxslip_0; +wire [5:0] qsfp_0_gt_rxheader_0; +wire [1:0] qsfp_0_gt_rxheadervalid_0; +wire [63:0] qsfp_0_gt_rxdata_0; +wire [1:0] qsfp_0_gt_rxdatavalid_0; + +wire [5:0] qsfp_0_gt_txheader_1; +wire [63:0] qsfp_0_gt_txdata_1; +wire qsfp_0_gt_rxgearboxslip_1; +wire [5:0] qsfp_0_gt_rxheader_1; +wire [1:0] qsfp_0_gt_rxheadervalid_1; +wire [63:0] qsfp_0_gt_rxdata_1; +wire [1:0] qsfp_0_gt_rxdatavalid_1; + +wire [5:0] qsfp_0_gt_txheader_2; +wire [63:0] qsfp_0_gt_txdata_2; +wire qsfp_0_gt_rxgearboxslip_2; +wire [5:0] qsfp_0_gt_rxheader_2; +wire [1:0] qsfp_0_gt_rxheadervalid_2; +wire [63:0] qsfp_0_gt_rxdata_2; +wire [1:0] qsfp_0_gt_rxdatavalid_2; + +wire [5:0] qsfp_0_gt_txheader_3; +wire [63:0] qsfp_0_gt_txdata_3; +wire qsfp_0_gt_rxgearboxslip_3; +wire [5:0] qsfp_0_gt_rxheader_3; +wire [1:0] qsfp_0_gt_rxheadervalid_3; +wire [63:0] qsfp_0_gt_rxdata_3; +wire [1:0] qsfp_0_gt_rxdatavalid_3; + +wire [5:0] qsfp_1_gt_txheader_0; +wire [63:0] qsfp_1_gt_txdata_0; +wire qsfp_1_gt_rxgearboxslip_0; +wire [5:0] qsfp_1_gt_rxheader_0; +wire [1:0] qsfp_1_gt_rxheadervalid_0; +wire [63:0] qsfp_1_gt_rxdata_0; +wire [1:0] qsfp_1_gt_rxdatavalid_0; + +wire [5:0] qsfp_1_gt_txheader_1; +wire [63:0] qsfp_1_gt_txdata_1; +wire qsfp_1_gt_rxgearboxslip_1; +wire [5:0] qsfp_1_gt_rxheader_1; +wire [1:0] qsfp_1_gt_rxheadervalid_1; +wire [63:0] qsfp_1_gt_rxdata_1; +wire [1:0] qsfp_1_gt_rxdatavalid_1; + +wire [5:0] qsfp_1_gt_txheader_2; +wire [63:0] qsfp_1_gt_txdata_2; +wire qsfp_1_gt_rxgearboxslip_2; +wire [5:0] qsfp_1_gt_rxheader_2; +wire [1:0] qsfp_1_gt_rxheadervalid_2; +wire [63:0] qsfp_1_gt_rxdata_2; +wire [1:0] qsfp_1_gt_rxdatavalid_2; + +wire [5:0] qsfp_1_gt_txheader_3; +wire [63:0] qsfp_1_gt_txdata_3; +wire qsfp_1_gt_rxgearboxslip_3; +wire [5:0] qsfp_1_gt_rxheader_3; +wire [1:0] qsfp_1_gt_rxheadervalid_3; +wire [63:0] qsfp_1_gt_rxdata_3; +wire [1:0] qsfp_1_gt_rxdatavalid_3; + +gtwizard_ultrascale_0 +qsfp_gty_inst ( + .gtwiz_userclk_tx_active_in(>_userclk_tx_active), + .gtwiz_userclk_rx_active_in(>_userclk_rx_active), + + .gtwiz_reset_clk_freerun_in(clk_125mhz_int), + .gtwiz_reset_all_in(rst_125mhz_int), + + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(1'b0), + + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(1'b0), + + .gtwiz_reset_rx_cdr_stable_out(), + + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + + .gtrefclk00_in({qsfp_0_mgt_refclk, qsfp_1_mgt_refclk}), + + .qpll0outclk_out(), + .qpll0outrefclk_out(), + + .gtyrxn_in({qsfp_0_rx_3_n, qsfp_0_rx_2_n, qsfp_0_rx_1_n, qsfp_0_rx_0_n, qsfp_1_rx_3_n, qsfp_1_rx_2_n, qsfp_1_rx_1_n, qsfp_1_rx_0_n}), + .gtyrxp_in({qsfp_0_rx_3_p, qsfp_0_rx_2_p, qsfp_0_rx_1_p, qsfp_0_rx_0_p, qsfp_1_rx_3_p, qsfp_1_rx_2_p, qsfp_1_rx_1_p, qsfp_1_rx_0_p}), + + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk), + + .gtwiz_userdata_tx_in({qsfp_0_gt_txdata_3, qsfp_0_gt_txdata_2, qsfp_0_gt_txdata_1, qsfp_0_gt_txdata_0, qsfp_1_gt_txdata_3, qsfp_1_gt_txdata_2, qsfp_1_gt_txdata_1, qsfp_1_gt_txdata_0}), + .txheader_in({qsfp_0_gt_txheader_3, qsfp_0_gt_txheader_2, qsfp_0_gt_txheader_1, qsfp_0_gt_txheader_0, qsfp_1_gt_txheader_3, qsfp_1_gt_txheader_2, qsfp_1_gt_txheader_1, qsfp_1_gt_txheader_0}), + .txsequence_in({8{1'b0}}), + + .txusrclk_in({8{gt_txusrclk}}), + .txusrclk2_in({8{gt_txusrclk}}), + + .gtpowergood_out(), + + .gtytxn_out({qsfp_0_tx_3_n, qsfp_0_tx_2_n, qsfp_0_tx_1_n, qsfp_0_tx_0_n, qsfp_1_tx_3_n, qsfp_1_tx_2_n, qsfp_1_tx_1_n, qsfp_1_tx_0_n}), + .gtytxp_out({qsfp_0_tx_3_p, qsfp_0_tx_2_p, qsfp_0_tx_1_p, qsfp_0_tx_0_p, qsfp_1_tx_3_p, qsfp_1_tx_2_p, qsfp_1_tx_1_p, qsfp_1_tx_0_p}), + + .rxgearboxslip_in({qsfp_0_gt_rxgearboxslip_3, qsfp_0_gt_rxgearboxslip_2, qsfp_0_gt_rxgearboxslip_1, qsfp_0_gt_rxgearboxslip_0, qsfp_1_gt_rxgearboxslip_3, qsfp_1_gt_rxgearboxslip_2, qsfp_1_gt_rxgearboxslip_1, qsfp_1_gt_rxgearboxslip_0}), + .gtwiz_userdata_rx_out({qsfp_0_gt_rxdata_3, qsfp_0_gt_rxdata_2, qsfp_0_gt_rxdata_1, qsfp_0_gt_rxdata_0, qsfp_1_gt_rxdata_3, qsfp_1_gt_rxdata_2, qsfp_1_gt_rxdata_1, qsfp_1_gt_rxdata_0}), + .rxdatavalid_out({qsfp_0_gt_rxdatavalid_3, qsfp_0_gt_rxdatavalid_2, qsfp_0_gt_rxdatavalid_1, qsfp_0_gt_rxdatavalid_0, qsfp_1_gt_rxdatavalid_3, qsfp_1_gt_rxdatavalid_2, qsfp_1_gt_rxdatavalid_1, qsfp_1_gt_rxdatavalid_0}), + .rxheader_out({qsfp_0_gt_rxheader_3, qsfp_0_gt_rxheader_2, qsfp_0_gt_rxheader_1, qsfp_0_gt_rxheader_0, qsfp_1_gt_rxheader_3, qsfp_1_gt_rxheader_2, qsfp_1_gt_rxheader_1, qsfp_1_gt_rxheader_0}), + .rxheadervalid_out({qsfp_0_gt_rxheadervalid_3, qsfp_0_gt_rxheadervalid_2, qsfp_0_gt_rxheadervalid_1, qsfp_0_gt_rxheadervalid_0, qsfp_1_gt_rxheadervalid_3, qsfp_1_gt_rxheadervalid_2, qsfp_1_gt_rxheadervalid_1, qsfp_1_gt_rxheadervalid_0}), + .rxoutclk_out(gt_rxclkout), + .rxpmaresetdone_out(gt_rxpmaresetdone), + .rxprgdivresetdone_out(gt_rxprgdivresetdone), + .rxstartofseq_out(), + + .txoutclk_out(gt_txclkout), + .txpmaresetdone_out(gt_txpmaresetdone), + .txprgdivresetdone_out(gt_txprgdivresetdone) +); + +wire qsfp_0_serdes_reset_0; + +sync_reset #( + .N(4) +) +qsfp_0_pcs_pma_0_rx_serdes_reset_sync_inst ( + .clk(gt_rxusrclk[0]), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_0_serdes_reset_0) +); + +ten_gig_eth_pcs_pma_0 +qsfp_0_pcs_pma_0 ( + .rx_reset_0(rst_156mhz_int), + .rx_mii_d_0(qsfp_0_rxd_0_int), + .rx_mii_c_0(qsfp_0_rxc_0_int), + + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + .stat_rx_block_lock_0(qsfp_0_rx_block_lock_0), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + .tx_reset_0(rst_156mhz_int), + .tx_mii_d_0(qsfp_0_txd_0_int), + .tx_mii_c_0(qsfp_0_txc_0_int), + + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + .stat_tx_local_fault_0(), + + // GTY interface + .tx_core_clk_0(clk_156mhz_int), + .rx_core_clk_0(clk_156mhz_int), + .rx_serdes_clk_0(gt_rxusrclk[0]), + .rx_serdes_reset_0(qsfp_0_serdes_reset_0), + .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_0), + .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_0), + .rxheader_out_0(qsfp_0_gt_rxheader_0), + .rxheadervalid_out_0(qsfp_0_gt_rxheadervalid_0), + .rx_serdes_data_out_0(qsfp_0_gt_rxdata_0), + .tx_serdes_data_in_0(qsfp_0_gt_txdata_0), + .txheader_in_0(qsfp_0_gt_txheader_0) +); + +wire qsfp_0_serdes_reset_1; + +sync_reset #( + .N(4) +) +qsfp_0_pcs_pma_1_rx_serdes_reset_sync_inst ( + .clk(gt_rxusrclk[1]), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_0_serdes_reset_1) +); + +ten_gig_eth_pcs_pma_0 +qsfp_0_pcs_pma_1 ( + .rx_reset_0(rst_156mhz_int), + .rx_mii_d_0(qsfp_0_rxd_1_int), + .rx_mii_c_0(qsfp_0_rxc_1_int), + + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + .stat_rx_block_lock_0(qsfp_0_rx_block_lock_1), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + .tx_reset_0(rst_156mhz_int), + .tx_mii_d_0(qsfp_0_txd_1_int), + .tx_mii_c_0(qsfp_0_txc_1_int), + + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + .stat_tx_local_fault_0(), + + // GTY interface + .tx_core_clk_0(clk_156mhz_int), + .rx_core_clk_0(clk_156mhz_int), + .rx_serdes_clk_0(gt_rxusrclk[1]), + .rx_serdes_reset_0(qsfp_0_serdes_reset_1), + .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_1), + .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_1), + .rxheader_out_0(qsfp_0_gt_rxheader_1), + .rxheadervalid_out_0(qsfp_0_gt_rxheadervalid_1), + .rx_serdes_data_out_0(qsfp_0_gt_rxdata_1), + .tx_serdes_data_in_0(qsfp_0_gt_txdata_1), + .txheader_in_0(qsfp_0_gt_txheader_1) +); + +wire qsfp_0_serdes_reset_2; + +sync_reset #( + .N(4) +) +qsfp_0_pcs_pma_2_rx_serdes_reset_sync_inst ( + .clk(gt_rxusrclk[2]), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_0_serdes_reset_2) +); + +ten_gig_eth_pcs_pma_0 +qsfp_0_pcs_pma_2 ( + .rx_reset_0(rst_156mhz_int), + .rx_mii_d_0(qsfp_0_rxd_2_int), + .rx_mii_c_0(qsfp_0_rxc_2_int), + + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + .stat_rx_block_lock_0(qsfp_0_rx_block_lock_2), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + .tx_reset_0(rst_156mhz_int), + .tx_mii_d_0(qsfp_0_txd_2_int), + .tx_mii_c_0(qsfp_0_txc_2_int), + + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + .stat_tx_local_fault_0(), + + // GTY interface + .tx_core_clk_0(clk_156mhz_int), + .rx_core_clk_0(clk_156mhz_int), + .rx_serdes_clk_0(gt_rxusrclk[2]), + .rx_serdes_reset_0(qsfp_0_serdes_reset_2), + .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_2), + .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_2), + .rxheader_out_0(qsfp_0_gt_rxheader_2), + .rxheadervalid_out_0(qsfp_0_gt_rxheadervalid_2), + .rx_serdes_data_out_0(qsfp_0_gt_rxdata_2), + .tx_serdes_data_in_0(qsfp_0_gt_txdata_2), + .txheader_in_0(qsfp_0_gt_txheader_2) +); + +wire qsfp_0_serdes_reset_3; + +sync_reset #( + .N(4) +) +qsfp_0_pcs_pma_3_rx_serdes_reset_sync_inst ( + .clk(gt_rxusrclk[3]), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_0_serdes_reset_3) +); + +ten_gig_eth_pcs_pma_0 +qsfp_0_pcs_pma_3 ( + .rx_reset_0(rst_156mhz_int), + .rx_mii_d_0(qsfp_0_rxd_3_int), + .rx_mii_c_0(qsfp_0_rxc_3_int), + + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + .stat_rx_block_lock_0(qsfp_0_rx_block_lock_3), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + .tx_reset_0(rst_156mhz_int), + .tx_mii_d_0(qsfp_0_txd_3_int), + .tx_mii_c_0(qsfp_0_txc_3_int), + + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + .stat_tx_local_fault_0(), + + // GTY interface + .tx_core_clk_0(clk_156mhz_int), + .rx_core_clk_0(clk_156mhz_int), + .rx_serdes_clk_0(gt_rxusrclk[3]), + .rx_serdes_reset_0(qsfp_0_serdes_reset_3), + .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_3), + .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_3), + .rxheader_out_0(qsfp_0_gt_rxheader_3), + .rxheadervalid_out_0(qsfp_0_gt_rxheadervalid_3), + .rx_serdes_data_out_0(qsfp_0_gt_rxdata_3), + .tx_serdes_data_in_0(qsfp_0_gt_txdata_3), + .txheader_in_0(qsfp_0_gt_txheader_3) +); + +wire qsfp_1_serdes_reset_0; + +sync_reset #( + .N(4) +) +qsfp_1_pcs_pma_0_rx_serdes_reset_sync_inst ( + .clk(gt_rxusrclk[4]), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_1_serdes_reset_0) +); + +ten_gig_eth_pcs_pma_0 +qsfp_1_pcs_pma_0 ( + .rx_reset_0(rst_156mhz_int), + .rx_mii_d_0(qsfp_1_rxd_0_int), + .rx_mii_c_0(qsfp_1_rxc_0_int), + + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + .stat_rx_block_lock_0(qsfp_1_rx_block_lock_0), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + .tx_reset_0(rst_156mhz_int), + .tx_mii_d_0(qsfp_1_txd_0_int), + .tx_mii_c_0(qsfp_1_txc_0_int), + + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + .stat_tx_local_fault_0(), + + // GTY interface + .tx_core_clk_0(clk_156mhz_int), + .rx_core_clk_0(clk_156mhz_int), + .rx_serdes_clk_0(gt_rxusrclk[4]), + .rx_serdes_reset_0(qsfp_1_serdes_reset_0), + .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_0), + .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_0), + .rxheader_out_0(qsfp_1_gt_rxheader_0), + .rxheadervalid_out_0(qsfp_1_gt_rxheadervalid_0), + .rx_serdes_data_out_0(qsfp_1_gt_rxdata_0), + .tx_serdes_data_in_0(qsfp_1_gt_txdata_0), + .txheader_in_0(qsfp_1_gt_txheader_0) +); + +wire qsfp_1_serdes_reset_1; + +sync_reset #( + .N(4) +) +qsfp_1_pcs_pma_1_rx_serdes_reset_sync_inst ( + .clk(gt_rxusrclk[5]), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_1_serdes_reset_1) +); + +ten_gig_eth_pcs_pma_0 +qsfp_1_pcs_pma_1 ( + .rx_reset_0(rst_156mhz_int), + .rx_mii_d_0(qsfp_1_rxd_1_int), + .rx_mii_c_0(qsfp_1_rxc_1_int), + + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + .stat_rx_block_lock_0(qsfp_1_rx_block_lock_1), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + .tx_reset_0(rst_156mhz_int), + .tx_mii_d_0(qsfp_1_txd_1_int), + .tx_mii_c_0(qsfp_1_txc_1_int), + + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + .stat_tx_local_fault_0(), + + // GTY interface + .tx_core_clk_0(clk_156mhz_int), + .rx_core_clk_0(clk_156mhz_int), + .rx_serdes_clk_0(gt_rxusrclk[5]), + .rx_serdes_reset_0(qsfp_1_serdes_reset_1), + .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_1), + .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_1), + .rxheader_out_0(qsfp_1_gt_rxheader_1), + .rxheadervalid_out_0(qsfp_1_gt_rxheadervalid_1), + .rx_serdes_data_out_0(qsfp_1_gt_rxdata_1), + .tx_serdes_data_in_0(qsfp_1_gt_txdata_1), + .txheader_in_0(qsfp_1_gt_txheader_1) +); + +wire qsfp_1_serdes_reset_2; + +sync_reset #( + .N(4) +) +qsfp_1_pcs_pma_2_rx_serdes_reset_sync_inst ( + .clk(gt_rxusrclk[6]), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_1_serdes_reset_2) +); + +ten_gig_eth_pcs_pma_0 +qsfp_1_pcs_pma_2 ( + .rx_reset_0(rst_156mhz_int), + .rx_mii_d_0(qsfp_1_rxd_2_int), + .rx_mii_c_0(qsfp_1_rxc_2_int), + + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + .stat_rx_block_lock_0(qsfp_1_rx_block_lock_2), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + .tx_reset_0(rst_156mhz_int), + .tx_mii_d_0(qsfp_1_txd_2_int), + .tx_mii_c_0(qsfp_1_txc_2_int), + + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + .stat_tx_local_fault_0(), + + // GTY interface + .tx_core_clk_0(clk_156mhz_int), + .rx_core_clk_0(clk_156mhz_int), + .rx_serdes_clk_0(gt_rxusrclk[6]), + .rx_serdes_reset_0(qsfp_1_serdes_reset_2), + .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_2), + .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_2), + .rxheader_out_0(qsfp_1_gt_rxheader_2), + .rxheadervalid_out_0(qsfp_1_gt_rxheadervalid_2), + .rx_serdes_data_out_0(qsfp_1_gt_rxdata_2), + .tx_serdes_data_in_0(qsfp_1_gt_txdata_2), + .txheader_in_0(qsfp_1_gt_txheader_2) +); + +wire qsfp_1_serdes_reset_3; + +sync_reset #( + .N(4) +) +qsfp_1_pcs_pma_3_rx_serdes_reset_sync_inst ( + .clk(gt_rxusrclk[7]), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_1_serdes_reset_3) +); + +ten_gig_eth_pcs_pma_0 +qsfp_1_pcs_pma_3 ( + .rx_reset_0(rst_156mhz_int), + .rx_mii_d_0(qsfp_1_rxd_3_int), + .rx_mii_c_0(qsfp_1_rxc_3_int), + + .ctl_rx_test_pattern_0(1'b0), + .ctl_rx_test_pattern_enable_0(1'b0), + .ctl_rx_data_pattern_select_0(1'b0), + .ctl_rx_prbs31_test_pattern_enable_0(1'b0), + + .stat_rx_block_lock_0(qsfp_1_rx_block_lock_3), + .stat_rx_framing_err_valid_0(), + .stat_rx_framing_err_0(), + .stat_rx_hi_ber_0(), + .stat_rx_valid_ctrl_code_0(), + .stat_rx_bad_code_0(), + .stat_rx_bad_code_valid_0(), + .stat_rx_error_valid_0(), + .stat_rx_error_0(), + .stat_rx_fifo_error_0(), + .stat_rx_local_fault_0(), + .stat_rx_status_0(), + + .tx_reset_0(rst_156mhz_int), + .tx_mii_d_0(qsfp_1_txd_3_int), + .tx_mii_c_0(qsfp_1_txc_3_int), + + .ctl_tx_test_pattern_0(1'b0), + .ctl_tx_test_pattern_enable_0(1'b0), + .ctl_tx_test_pattern_select_0(1'b0), + .ctl_tx_data_pattern_select_0(1'b0), + .ctl_tx_test_pattern_seed_a_0(58'd0), + .ctl_tx_test_pattern_seed_b_0(58'd0), + .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + + .stat_tx_local_fault_0(), + + // GTY interface + .tx_core_clk_0(clk_156mhz_int), + .rx_core_clk_0(clk_156mhz_int), + .rx_serdes_clk_0(gt_rxusrclk[7]), + .rx_serdes_reset_0(qsfp_1_serdes_reset_3), + .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_3), + .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_3), + .rxheader_out_0(qsfp_1_gt_rxheader_3), + .rxheadervalid_out_0(qsfp_1_gt_rxheadervalid_3), + .rx_serdes_data_out_0(qsfp_1_gt_rxdata_3), + .tx_serdes_data_in_0(qsfp_1_gt_txdata_3), + .txheader_in_0(qsfp_1_gt_txheader_3) +); + +//assign led = sw[0] ? {qsfp_1_rx_block_lock_4, qsfp_1_rx_block_lock_3, qsfp_1_rx_block_lock_2, qsfp_1_rx_block_lock_1, qsfp_0_rx_block_lock_4, qsfp_0_rx_block_lock_3, qsfp_0_rx_block_lock_2, qsfp_0_rx_block_lock_1} : led_int; +assign front_led = {1'b0, qsfp_0_rx_block_lock_0}; + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + /* + * GPIO + */ + .user_led_g(user_led_g), + .user_led_r(user_led_r), + //.front_led(front_led), + .user_sw(user_sw_int), + + /* + * Ethernet: QSFP28 + */ + .qsfp_0_tx_clk_0(qsfp_0_tx_clk_0_int), + .qsfp_0_tx_rst_0(qsfp_0_tx_rst_0_int), + .qsfp_0_txd_0(qsfp_0_txd_0_int), + .qsfp_0_txc_0(qsfp_0_txc_0_int), + .qsfp_0_rx_clk_0(qsfp_0_rx_clk_0_int), + .qsfp_0_rx_rst_0(qsfp_0_rx_rst_0_int), + .qsfp_0_rxd_0(qsfp_0_rxd_0_int), + .qsfp_0_rxc_0(qsfp_0_rxc_0_int), + .qsfp_0_tx_clk_1(qsfp_0_tx_clk_1_int), + .qsfp_0_tx_rst_1(qsfp_0_tx_rst_1_int), + .qsfp_0_txd_1(qsfp_0_txd_1_int), + .qsfp_0_txc_1(qsfp_0_txc_1_int), + .qsfp_0_rx_clk_1(qsfp_0_rx_clk_1_int), + .qsfp_0_rx_rst_1(qsfp_0_rx_rst_1_int), + .qsfp_0_rxd_1(qsfp_0_rxd_1_int), + .qsfp_0_rxc_1(qsfp_0_rxc_1_int), + .qsfp_0_tx_clk_2(qsfp_0_tx_clk_2_int), + .qsfp_0_tx_rst_2(qsfp_0_tx_rst_2_int), + .qsfp_0_txd_2(qsfp_0_txd_2_int), + .qsfp_0_txc_2(qsfp_0_txc_2_int), + .qsfp_0_rx_clk_2(qsfp_0_rx_clk_2_int), + .qsfp_0_rx_rst_2(qsfp_0_rx_rst_2_int), + .qsfp_0_rxd_2(qsfp_0_rxd_2_int), + .qsfp_0_rxc_2(qsfp_0_rxc_2_int), + .qsfp_0_tx_clk_3(qsfp_0_tx_clk_3_int), + .qsfp_0_tx_rst_3(qsfp_0_tx_rst_3_int), + .qsfp_0_txd_3(qsfp_0_txd_3_int), + .qsfp_0_txc_3(qsfp_0_txc_3_int), + .qsfp_0_rx_clk_3(qsfp_0_rx_clk_3_int), + .qsfp_0_rx_rst_3(qsfp_0_rx_rst_3_int), + .qsfp_0_rxd_3(qsfp_0_rxd_3_int), + .qsfp_0_rxc_3(qsfp_0_rxc_3_int), + .qsfp_1_tx_clk_0(qsfp_1_tx_clk_0_int), + .qsfp_1_tx_rst_0(qsfp_1_tx_rst_0_int), + .qsfp_1_txd_0(qsfp_1_txd_0_int), + .qsfp_1_txc_0(qsfp_1_txc_0_int), + .qsfp_1_rx_clk_0(qsfp_1_rx_clk_0_int), + .qsfp_1_rx_rst_0(qsfp_1_rx_rst_0_int), + .qsfp_1_rxd_0(qsfp_1_rxd_0_int), + .qsfp_1_rxc_0(qsfp_1_rxc_0_int), + .qsfp_1_tx_clk_1(qsfp_1_tx_clk_1_int), + .qsfp_1_tx_rst_1(qsfp_1_tx_rst_1_int), + .qsfp_1_txd_1(qsfp_1_txd_1_int), + .qsfp_1_txc_1(qsfp_1_txc_1_int), + .qsfp_1_rx_clk_1(qsfp_1_rx_clk_1_int), + .qsfp_1_rx_rst_1(qsfp_1_rx_rst_1_int), + .qsfp_1_rxd_1(qsfp_1_rxd_1_int), + .qsfp_1_rxc_1(qsfp_1_rxc_1_int), + .qsfp_1_tx_clk_2(qsfp_1_tx_clk_2_int), + .qsfp_1_tx_rst_2(qsfp_1_tx_rst_2_int), + .qsfp_1_txd_2(qsfp_1_txd_2_int), + .qsfp_1_txc_2(qsfp_1_txc_2_int), + .qsfp_1_rx_clk_2(qsfp_1_rx_clk_2_int), + .qsfp_1_rx_rst_2(qsfp_1_rx_rst_2_int), + .qsfp_1_rxd_2(qsfp_1_rxd_2_int), + .qsfp_1_rxc_2(qsfp_1_rxc_2_int), + .qsfp_1_tx_clk_3(qsfp_1_tx_clk_3_int), + .qsfp_1_tx_rst_3(qsfp_1_tx_rst_3_int), + .qsfp_1_txd_3(qsfp_1_txd_3_int), + .qsfp_1_txc_3(qsfp_1_txc_3_int), + .qsfp_1_rx_clk_3(qsfp_1_rx_clk_3_int), + .qsfp_1_rx_rst_3(qsfp_1_rx_rst_3_int), + .qsfp_1_rxd_3(qsfp_1_rxd_3_int), + .qsfp_1_rxc_3(qsfp_1_rxc_3_int) +); + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v new file mode 100644 index 000000000..93f5ddc41 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v @@ -0,0 +1,659 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + output wire [1:0] user_led_g, + output wire user_led_r, + output wire [1:0] front_led, + input wire [1:0] user_sw, + + /* + * Ethernet: QSFP28 + */ + input wire qsfp_0_tx_clk_0, + input wire qsfp_0_tx_rst_0, + output wire [63:0] qsfp_0_txd_0, + output wire [7:0] qsfp_0_txc_0, + input wire qsfp_0_rx_clk_0, + input wire qsfp_0_rx_rst_0, + input wire [63:0] qsfp_0_rxd_0, + input wire [7:0] qsfp_0_rxc_0, + input wire qsfp_0_tx_clk_1, + input wire qsfp_0_tx_rst_1, + output wire [63:0] qsfp_0_txd_1, + output wire [7:0] qsfp_0_txc_1, + input wire qsfp_0_rx_clk_1, + input wire qsfp_0_rx_rst_1, + input wire [63:0] qsfp_0_rxd_1, + input wire [7:0] qsfp_0_rxc_1, + input wire qsfp_0_tx_clk_2, + input wire qsfp_0_tx_rst_2, + output wire [63:0] qsfp_0_txd_2, + output wire [7:0] qsfp_0_txc_2, + input wire qsfp_0_rx_clk_2, + input wire qsfp_0_rx_rst_2, + input wire [63:0] qsfp_0_rxd_2, + input wire [7:0] qsfp_0_rxc_2, + input wire qsfp_0_tx_clk_3, + input wire qsfp_0_tx_rst_3, + output wire [63:0] qsfp_0_txd_3, + output wire [7:0] qsfp_0_txc_3, + input wire qsfp_0_rx_clk_3, + input wire qsfp_0_rx_rst_3, + input wire [63:0] qsfp_0_rxd_3, + input wire [7:0] qsfp_0_rxc_3, + input wire qsfp_1_tx_clk_0, + input wire qsfp_1_tx_rst_0, + output wire [63:0] qsfp_1_txd_0, + output wire [7:0] qsfp_1_txc_0, + input wire qsfp_1_rx_clk_0, + input wire qsfp_1_rx_rst_0, + input wire [63:0] qsfp_1_rxd_0, + input wire [7:0] qsfp_1_rxc_0, + input wire qsfp_1_tx_clk_1, + input wire qsfp_1_tx_rst_1, + output wire [63:0] qsfp_1_txd_1, + output wire [7:0] qsfp_1_txc_1, + input wire qsfp_1_rx_clk_1, + input wire qsfp_1_rx_rst_1, + input wire [63:0] qsfp_1_rxd_1, + input wire [7:0] qsfp_1_rxc_1, + input wire qsfp_1_tx_clk_2, + input wire qsfp_1_tx_rst_2, + output wire [63:0] qsfp_1_txd_2, + output wire [7:0] qsfp_1_txc_2, + input wire qsfp_1_rx_clk_2, + input wire qsfp_1_rx_rst_2, + input wire [63:0] qsfp_1_rxd_2, + input wire [7:0] qsfp_1_rxc_2, + input wire qsfp_1_tx_clk_3, + input wire qsfp_1_tx_rst_3, + output wire [63:0] qsfp_1_txd_3, + output wire [7:0] qsfp_1_txc_3, + input wire qsfp_1_rx_clk_3, + input wire qsfp_1_rx_rst_3, + input wire [63:0] qsfp_1_rxd_3, + input wire [7:0] qsfp_1_rxc_3 +); + +// AXI between MAC and Ethernet modules +wire [63:0] rx_axis_tdata; +wire [7:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [63:0] tx_axis_tdata; +wire [7:0] tx_axis_tkeep; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [63:0] rx_eth_payload_axis_tdata; +wire [7:0] rx_eth_payload_axis_tkeep; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [63:0] tx_eth_payload_axis_tdata; +wire [7:0] tx_eth_payload_axis_tkeep; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [63:0] rx_ip_payload_axis_tdata; +wire [7:0] rx_ip_payload_axis_tkeep; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [63:0] tx_ip_payload_axis_tdata; +wire [7:0] tx_ip_payload_axis_tkeep; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [63:0] rx_udp_payload_axis_tdata; +wire [7:0] rx_udp_payload_axis_tkeep; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [63:0] tx_udp_payload_axis_tdata; +wire [7:0] tx_udp_payload_axis_tkeep; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; + +wire [63:0] rx_fifo_udp_payload_axis_tdata; +wire [7:0] rx_fifo_udp_payload_axis_tkeep; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; + +wire [63:0] tx_fifo_udp_payload_axis_tdata; +wire [7:0] tx_fifo_udp_payload_axis_tkeep; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_axis_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tkeep = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = !match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; + +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; + +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_axis_tvalid; + if (tx_udp_payload_axis_tvalid && !valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; + end + end +end + +assign user_led_g = ~led_reg[1:0]; +assign user_led_r = 1'b1; +assign front_led = 2'b00; + +assign phy_reset_n = !rst; + +assign qsfp_0_txd_1 = 64'h0707070707070707; +assign qsfp_0_txc_1 = 8'hff; +assign qsfp_0_txd_2 = 64'h0707070707070707; +assign qsfp_0_txc_2 = 8'hff; +assign qsfp_0_txd_3 = 64'h0707070707070707; +assign qsfp_0_txc_3 = 8'hff; + +assign qsfp_1_txd_0 = 64'h0707070707070707; +assign qsfp_1_txc_0 = 8'hff; +assign qsfp_1_txd_1 = 64'h0707070707070707; +assign qsfp_1_txc_1 = 8'hff; +assign qsfp_1_txd_2 = 64'h0707070707070707; +assign qsfp_1_txc_2 = 8'hff; +assign qsfp_1_txd_3 = 64'h0707070707070707; +assign qsfp_1_txc_3 = 8'hff; + +eth_mac_10g_fifo #( + .ENABLE_PADDING(1), + .ENABLE_DIC(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(9), + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(9), + .RX_FRAME_FIFO(1) +) +eth_mac_10g_fifo_inst ( + .rx_clk(qsfp_0_rx_clk_0), + .rx_rst(qsfp_0_rx_rst_0), + .tx_clk(qsfp_0_tx_clk_0), + .tx_rst(qsfp_0_tx_rst_0), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .xgmii_rxd(qsfp_0_rxd_0), + .xgmii_rxc(qsfp_0_rxc_0), + .xgmii_txd(qsfp_0_txd_0), + .xgmii_txc(qsfp_0_txc_0), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + .ifg_delay(8'd12) +); + +eth_axis_rx_64 +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(rx_axis_tdata), + .s_axis_tkeep(rx_axis_tkeep), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx_64 +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // AXI output + .m_axis_tdata(tx_axis_tdata), + .m_axis_tkeep(tx_axis_tkeep), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete_64 +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // IP frame input + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), + // IP frame output + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), + // UDP frame input + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), + // UDP frame output + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(1'b0) +); + +axis_fifo #( + .ADDR_WIDTH(10), + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(8), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(0) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), + + // AXI output + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() +); + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_10g/rtl/sync_reset.v b/example/ADM_PCIE_9V3/fpga_10g/rtl/sync_reset.v new file mode 100644 index 000000000..acbcf1c6e --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_10g/rtl/sync_signal.v b/example/ADM_PCIE_9V3/fpga_10g/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/arp_ep.py b/example/ADM_PCIE_9V3/fpga_10g/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py b/example/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py b/example/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/gmii_ep.py b/example/ADM_PCIE_9V3/fpga_10g/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py b/example/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py b/example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py new file mode 100755 index 000000000..35b21e22b --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py @@ -0,0 +1,462 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016-2018 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 + +import eth_ep +import arp_ep +import udp_ep +import xgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") +srcs.append("../lib/eth/rtl/arp_64.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") +srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + user_sw = Signal(intbv(0)[2:]) + qsfp_0_tx_clk_0 = Signal(bool(0)) + qsfp_0_tx_rst_0 = Signal(bool(0)) + qsfp_0_rx_clk_0 = Signal(bool(0)) + qsfp_0_rx_rst_0 = Signal(bool(0)) + qsfp_0_rxd_0 = Signal(intbv(0)[64:]) + qsfp_0_rxc_0 = Signal(intbv(0)[8:]) + qsfp_0_tx_clk_1 = Signal(bool(0)) + qsfp_0_tx_rst_1 = Signal(bool(0)) + qsfp_0_rx_clk_1 = Signal(bool(0)) + qsfp_0_rx_rst_1 = Signal(bool(0)) + qsfp_0_rxd_1 = Signal(intbv(0)[64:]) + qsfp_0_rxc_1 = Signal(intbv(0)[8:]) + qsfp_0_tx_clk_2 = Signal(bool(0)) + qsfp_0_tx_rst_2 = Signal(bool(0)) + qsfp_0_rx_clk_2 = Signal(bool(0)) + qsfp_0_rx_rst_2 = Signal(bool(0)) + qsfp_0_rxd_2 = Signal(intbv(0)[64:]) + qsfp_0_rxc_2 = Signal(intbv(0)[8:]) + qsfp_0_tx_clk_3 = Signal(bool(0)) + qsfp_0_tx_rst_3 = Signal(bool(0)) + qsfp_0_rx_clk_3 = Signal(bool(0)) + qsfp_0_rx_rst_3 = Signal(bool(0)) + qsfp_0_rxd_3 = Signal(intbv(0)[64:]) + qsfp_0_rxc_3 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_0 = Signal(bool(0)) + qsfp_1_tx_rst_0 = Signal(bool(0)) + qsfp_1_rx_clk_0 = Signal(bool(0)) + qsfp_1_rx_rst_0 = Signal(bool(0)) + qsfp_1_rxd_0 = Signal(intbv(0)[64:]) + qsfp_1_rxc_0 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_1 = Signal(bool(0)) + qsfp_1_tx_rst_1 = Signal(bool(0)) + qsfp_1_rx_clk_1 = Signal(bool(0)) + qsfp_1_rx_rst_1 = Signal(bool(0)) + qsfp_1_rxd_1 = Signal(intbv(0)[64:]) + qsfp_1_rxc_1 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_2 = Signal(bool(0)) + qsfp_1_tx_rst_2 = Signal(bool(0)) + qsfp_1_rx_clk_2 = Signal(bool(0)) + qsfp_1_rx_rst_2 = Signal(bool(0)) + qsfp_1_rxd_2 = Signal(intbv(0)[64:]) + qsfp_1_rxc_2 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_3 = Signal(bool(0)) + qsfp_1_tx_rst_3 = Signal(bool(0)) + qsfp_1_rx_clk_3 = Signal(bool(0)) + qsfp_1_rx_rst_3 = Signal(bool(0)) + qsfp_1_rxd_3 = Signal(intbv(0)[64:]) + qsfp_1_rxc_3 = Signal(intbv(0)[8:]) + + # Outputs + user_led_g = Signal(intbv(0)[2:]) + user_led_r = Signal(bool(0)) + front_led = Signal(intbv(0)[2:]) + qsfp_0_txd_0 = Signal(intbv(0)[64:]) + qsfp_0_txc_0 = Signal(intbv(0)[8:]) + qsfp_0_txd_1 = Signal(intbv(0)[64:]) + qsfp_0_txc_1 = Signal(intbv(0)[8:]) + qsfp_0_txd_2 = Signal(intbv(0)[64:]) + qsfp_0_txc_2 = Signal(intbv(0)[8:]) + qsfp_0_txd_3 = Signal(intbv(0)[64:]) + qsfp_0_txc_3 = Signal(intbv(0)[8:]) + qsfp_1_txd_0 = Signal(intbv(0)[64:]) + qsfp_1_txc_0 = Signal(intbv(0)[8:]) + qsfp_1_txd_1 = Signal(intbv(0)[64:]) + qsfp_1_txc_1 = Signal(intbv(0)[8:]) + qsfp_1_txd_2 = Signal(intbv(0)[64:]) + qsfp_1_txc_2 = Signal(intbv(0)[8:]) + qsfp_1_txd_3 = Signal(intbv(0)[64:]) + qsfp_1_txc_3 = Signal(intbv(0)[8:]) + + # sources and sinks + qsfp_0_0_source = xgmii_ep.XGMIISource() + qsfp_0_0_source_logic = qsfp_0_0_source.create_logic(qsfp_0_rx_clk_0, qsfp_0_rx_rst_0, txd=qsfp_0_rxd_0, txc=qsfp_0_rxc_0, name='qsfp_0_0_source') + + qsfp_0_0_sink = xgmii_ep.XGMIISink() + qsfp_0_0_sink_logic = qsfp_0_0_sink.create_logic(qsfp_0_tx_clk_0, qsfp_0_tx_rst_0, rxd=qsfp_0_txd_0, rxc=qsfp_0_txc_0, name='qsfp_0_0_sink') + + qsfp_0_1_source = xgmii_ep.XGMIISource() + qsfp_0_1_source_logic = qsfp_0_1_source.create_logic(qsfp_0_rx_clk_1, qsfp_0_rx_rst_1, txd=qsfp_0_rxd_1, txc=qsfp_0_rxc_1, name='qsfp_0_1_source') + + qsfp_0_1_sink = xgmii_ep.XGMIISink() + qsfp_0_1_sink_logic = qsfp_0_1_sink.create_logic(qsfp_0_tx_clk_1, qsfp_0_tx_rst_1, rxd=qsfp_0_txd_1, rxc=qsfp_0_txc_1, name='qsfp_0_1_sink') + + qsfp_0_2_source = xgmii_ep.XGMIISource() + qsfp_0_2_source_logic = qsfp_0_2_source.create_logic(qsfp_0_rx_clk_2, qsfp_0_rx_rst_2, txd=qsfp_0_rxd_2, txc=qsfp_0_rxc_2, name='qsfp_0_2_source') + + qsfp_0_2_sink = xgmii_ep.XGMIISink() + qsfp_0_2_sink_logic = qsfp_0_2_sink.create_logic(qsfp_0_tx_clk_2, qsfp_0_tx_rst_2, rxd=qsfp_0_txd_2, rxc=qsfp_0_txc_2, name='qsfp_0_2_sink') + + qsfp_0_3_source = xgmii_ep.XGMIISource() + qsfp_0_3_source_logic = qsfp_0_3_source.create_logic(qsfp_0_rx_clk_3, qsfp_0_rx_rst_3, txd=qsfp_0_rxd_3, txc=qsfp_0_rxc_3, name='qsfp_0_3_source') + + qsfp_0_3_sink = xgmii_ep.XGMIISink() + qsfp_0_3_sink_logic = qsfp_0_3_sink.create_logic(qsfp_0_tx_clk_3, qsfp_0_tx_rst_3, rxd=qsfp_0_txd_3, rxc=qsfp_0_txc_3, name='qsfp_0_3_sink') + + qsfp_1_0_source = xgmii_ep.XGMIISource() + qsfp_1_0_source_logic = qsfp_1_0_source.create_logic(qsfp_1_rx_clk_0, qsfp_1_rx_rst_0, txd=qsfp_1_rxd_0, txc=qsfp_1_rxc_0, name='qsfp_1_0_source') + + qsfp_1_0_sink = xgmii_ep.XGMIISink() + qsfp_1_0_sink_logic = qsfp_1_0_sink.create_logic(qsfp_1_tx_clk_0, qsfp_1_tx_rst_0, rxd=qsfp_1_txd_0, rxc=qsfp_1_txc_0, name='qsfp_1_0_sink') + + qsfp_1_1_source = xgmii_ep.XGMIISource() + qsfp_1_1_source_logic = qsfp_1_1_source.create_logic(qsfp_1_rx_clk_1, qsfp_1_rx_rst_1, txd=qsfp_1_rxd_1, txc=qsfp_1_rxc_1, name='qsfp_1_1_source') + + qsfp_1_1_sink = xgmii_ep.XGMIISink() + qsfp_1_1_sink_logic = qsfp_1_1_sink.create_logic(qsfp_1_tx_clk_1, qsfp_1_tx_rst_1, rxd=qsfp_1_txd_1, rxc=qsfp_1_txc_1, name='qsfp_1_1_sink') + + qsfp_1_2_source = xgmii_ep.XGMIISource() + qsfp_1_2_source_logic = qsfp_1_2_source.create_logic(qsfp_1_rx_clk_2, qsfp_1_rx_rst_2, txd=qsfp_1_rxd_2, txc=qsfp_1_rxc_2, name='qsfp_1_2_source') + + qsfp_1_2_sink = xgmii_ep.XGMIISink() + qsfp_1_2_sink_logic = qsfp_1_2_sink.create_logic(qsfp_1_tx_clk_2, qsfp_1_tx_rst_2, rxd=qsfp_1_txd_2, rxc=qsfp_1_txc_2, name='qsfp_1_2_sink') + + qsfp_1_3_source = xgmii_ep.XGMIISource() + qsfp_1_3_source_logic = qsfp_1_3_source.create_logic(qsfp_1_rx_clk_3, qsfp_1_rx_rst_3, txd=qsfp_1_rxd_3, txc=qsfp_1_rxc_3, name='qsfp_1_3_source') + + qsfp_1_3_sink = xgmii_ep.XGMIISink() + qsfp_1_3_sink_logic = qsfp_1_3_sink.create_logic(qsfp_1_tx_clk_3, qsfp_1_tx_rst_3, rxd=qsfp_1_txd_3, rxc=qsfp_1_txc_3, name='qsfp_1_3_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, + + user_led_g=user_led_g, + user_led_r=user_led_r, + front_led=front_led, + user_sw=user_sw, + + qsfp_0_tx_clk_0=qsfp_0_tx_clk_0, + qsfp_0_tx_rst_0=qsfp_0_tx_rst_0, + qsfp_0_txd_0=qsfp_0_txd_0, + qsfp_0_txc_0=qsfp_0_txc_0, + qsfp_0_rx_clk_0=qsfp_0_rx_clk_0, + qsfp_0_rx_rst_0=qsfp_0_rx_rst_0, + qsfp_0_rxd_0=qsfp_0_rxd_0, + qsfp_0_rxc_0=qsfp_0_rxc_0, + qsfp_0_tx_clk_1=qsfp_0_tx_clk_1, + qsfp_0_tx_rst_1=qsfp_0_tx_rst_1, + qsfp_0_txd_1=qsfp_0_txd_1, + qsfp_0_txc_1=qsfp_0_txc_1, + qsfp_0_rx_clk_1=qsfp_0_rx_clk_1, + qsfp_0_rx_rst_1=qsfp_0_rx_rst_1, + qsfp_0_rxd_1=qsfp_0_rxd_1, + qsfp_0_rxc_1=qsfp_0_rxc_1, + qsfp_0_tx_clk_2=qsfp_0_tx_clk_2, + qsfp_0_tx_rst_2=qsfp_0_tx_rst_2, + qsfp_0_txd_2=qsfp_0_txd_2, + qsfp_0_txc_2=qsfp_0_txc_2, + qsfp_0_rx_clk_2=qsfp_0_rx_clk_2, + qsfp_0_rx_rst_2=qsfp_0_rx_rst_2, + qsfp_0_rxd_2=qsfp_0_rxd_2, + qsfp_0_rxc_2=qsfp_0_rxc_2, + qsfp_0_tx_clk_3=qsfp_0_tx_clk_3, + qsfp_0_tx_rst_3=qsfp_0_tx_rst_3, + qsfp_0_txd_3=qsfp_0_txd_3, + qsfp_0_txc_3=qsfp_0_txc_3, + qsfp_0_rx_clk_3=qsfp_0_rx_clk_3, + qsfp_0_rx_rst_3=qsfp_0_rx_rst_3, + qsfp_0_rxd_3=qsfp_0_rxd_3, + qsfp_0_rxc_3=qsfp_0_rxc_3, + qsfp_1_tx_clk_0=qsfp_1_tx_clk_0, + qsfp_1_tx_rst_0=qsfp_1_tx_rst_0, + qsfp_1_txd_0=qsfp_1_txd_0, + qsfp_1_txc_0=qsfp_1_txc_0, + qsfp_1_rx_clk_0=qsfp_1_rx_clk_0, + qsfp_1_rx_rst_0=qsfp_1_rx_rst_0, + qsfp_1_rxd_0=qsfp_1_rxd_0, + qsfp_1_rxc_0=qsfp_1_rxc_0, + qsfp_1_tx_clk_1=qsfp_1_tx_clk_1, + qsfp_1_tx_rst_1=qsfp_1_tx_rst_1, + qsfp_1_txd_1=qsfp_1_txd_1, + qsfp_1_txc_1=qsfp_1_txc_1, + qsfp_1_rx_clk_1=qsfp_1_rx_clk_1, + qsfp_1_rx_rst_1=qsfp_1_rx_rst_1, + qsfp_1_rxd_1=qsfp_1_rxd_1, + qsfp_1_rxc_1=qsfp_1_rxc_1, + qsfp_1_tx_clk_2=qsfp_1_tx_clk_2, + qsfp_1_tx_rst_2=qsfp_1_tx_rst_2, + qsfp_1_txd_2=qsfp_1_txd_2, + qsfp_1_txc_2=qsfp_1_txc_2, + qsfp_1_rx_clk_2=qsfp_1_rx_clk_2, + qsfp_1_rx_rst_2=qsfp_1_rx_rst_2, + qsfp_1_rxd_2=qsfp_1_rxd_2, + qsfp_1_rxc_2=qsfp_1_rxc_2, + qsfp_1_tx_clk_3=qsfp_1_tx_clk_3, + qsfp_1_tx_rst_3=qsfp_1_tx_rst_3, + qsfp_1_txd_3=qsfp_1_txd_3, + qsfp_1_txc_3=qsfp_1_txc_3, + qsfp_1_rx_clk_3=qsfp_1_rx_clk_3, + qsfp_1_rx_rst_3=qsfp_1_rx_rst_3, + qsfp_1_rxd_3=qsfp_1_rxd_3, + qsfp_1_rxc_3=qsfp_1_rxc_3 + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + qsfp_0_tx_clk_0.next = not qsfp_0_tx_clk_0 + qsfp_0_rx_clk_0.next = not qsfp_0_rx_clk_0 + qsfp_0_tx_clk_1.next = not qsfp_0_tx_clk_1 + qsfp_0_rx_clk_1.next = not qsfp_0_rx_clk_1 + qsfp_0_tx_clk_2.next = not qsfp_0_tx_clk_2 + qsfp_0_rx_clk_2.next = not qsfp_0_rx_clk_2 + qsfp_0_tx_clk_3.next = not qsfp_0_tx_clk_3 + qsfp_0_rx_clk_3.next = not qsfp_0_rx_clk_3 + qsfp_1_tx_clk_0.next = not qsfp_1_tx_clk_0 + qsfp_1_rx_clk_0.next = not qsfp_1_rx_clk_0 + qsfp_1_tx_clk_1.next = not qsfp_1_tx_clk_1 + qsfp_1_rx_clk_1.next = not qsfp_1_rx_clk_1 + qsfp_1_tx_clk_2.next = not qsfp_1_tx_clk_2 + qsfp_1_rx_clk_2.next = not qsfp_1_rx_clk_2 + qsfp_1_tx_clk_3.next = not qsfp_1_tx_clk_3 + qsfp_1_rx_clk_3.next = not qsfp_1_rx_clk_3 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + qsfp_0_tx_rst_1.next = 1 + qsfp_0_rx_rst_1.next = 1 + qsfp_0_tx_rst_2.next = 1 + qsfp_0_rx_rst_2.next = 1 + qsfp_0_tx_rst_3.next = 1 + qsfp_0_rx_rst_3.next = 1 + qsfp_0_tx_rst_0.next = 1 + qsfp_0_rx_rst_0.next = 1 + qsfp_1_tx_rst_1.next = 1 + qsfp_1_rx_rst_1.next = 1 + qsfp_1_tx_rst_2.next = 1 + qsfp_1_rx_rst_2.next = 1 + qsfp_1_tx_rst_3.next = 1 + qsfp_1_rx_rst_3.next = 1 + qsfp_1_tx_rst_0.next = 1 + qsfp_1_rx_rst_0.next = 1 + yield clk.posedge + rst.next = 0 + qsfp_0_tx_rst_1.next = 0 + qsfp_0_rx_rst_1.next = 0 + qsfp_0_tx_rst_2.next = 0 + qsfp_0_rx_rst_2.next = 0 + qsfp_0_tx_rst_3.next = 0 + qsfp_0_rx_rst_3.next = 0 + qsfp_0_tx_rst_0.next = 0 + qsfp_0_rx_rst_0.next = 0 + qsfp_1_tx_rst_1.next = 0 + qsfp_1_rx_rst_1.next = 0 + qsfp_1_tx_rst_2.next = 0 + qsfp_1_rx_rst_2.next = 0 + qsfp_1_tx_rst_3.next = 0 + qsfp_1_rx_rst_3.next = 0 + qsfp_1_tx_rst_0.next = 0 + qsfp_1_rx_rst_0.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while qsfp_0_0_sink.empty(): + yield clk.posedge + + rx_frame = qsfp_0_0_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while qsfp_0_0_sink.empty(): + yield clk.posedge + + rx_frame = qsfp_0_0_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert qsfp_0_0_source.empty() + assert qsfp_0_0_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() diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v b/example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v new file mode 100644 index 000000000..003072a91 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v @@ -0,0 +1,269 @@ +/* + +Copyright (c) 2016-2018 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [1:0] user_sw = 0; +reg qsfp_0_tx_clk_0 = 0; +reg qsfp_0_tx_rst_0 = 0; +reg qsfp_0_rx_clk_0 = 0; +reg qsfp_0_rx_rst_0 = 0; +reg [63:0] qsfp_0_rxd_0 = 0; +reg [7:0] qsfp_0_rxc_0 = 0; +reg qsfp_0_tx_clk_1 = 0; +reg qsfp_0_tx_rst_1 = 0; +reg qsfp_0_rx_clk_1 = 0; +reg qsfp_0_rx_rst_1 = 0; +reg [63:0] qsfp_0_rxd_1 = 0; +reg [7:0] qsfp_0_rxc_1 = 0; +reg qsfp_0_tx_clk_2 = 0; +reg qsfp_0_tx_rst_2 = 0; +reg qsfp_0_rx_clk_2 = 0; +reg qsfp_0_rx_rst_2 = 0; +reg [63:0] qsfp_0_rxd_2 = 0; +reg [7:0] qsfp_0_rxc_2 = 0; +reg qsfp_0_tx_clk_3 = 0; +reg qsfp_0_tx_rst_3 = 0; +reg qsfp_0_rx_clk_3 = 0; +reg qsfp_0_rx_rst_3 = 0; +reg [63:0] qsfp_0_rxd_3 = 0; +reg [7:0] qsfp_0_rxc_3 = 0; +reg qsfp_1_tx_clk_0 = 0; +reg qsfp_1_tx_rst_0 = 0; +reg qsfp_1_rx_clk_0 = 0; +reg qsfp_1_rx_rst_0 = 0; +reg [63:0] qsfp_1_rxd_0 = 0; +reg [7:0] qsfp_1_rxc_0 = 0; +reg qsfp_1_tx_clk_1 = 0; +reg qsfp_1_tx_rst_1 = 0; +reg qsfp_1_rx_clk_1 = 0; +reg qsfp_1_rx_rst_1 = 0; +reg [63:0] qsfp_1_rxd_1 = 0; +reg [7:0] qsfp_1_rxc_1 = 0; +reg qsfp_1_tx_clk_2 = 0; +reg qsfp_1_tx_rst_2 = 0; +reg qsfp_1_rx_clk_2 = 0; +reg qsfp_1_rx_rst_2 = 0; +reg [63:0] qsfp_1_rxd_2 = 0; +reg [7:0] qsfp_1_rxc_2 = 0; +reg qsfp_1_tx_clk_3 = 0; +reg qsfp_1_tx_rst_3 = 0; +reg qsfp_1_rx_clk_3 = 0; +reg qsfp_1_rx_rst_3 = 0; +reg [63:0] qsfp_1_rxd_3 = 0; +reg [7:0] qsfp_1_rxc_3 = 0; + +// Outputs +wire [1:0] user_led_g; +wire user_led_r; +wire [1:0] front_led; +wire [63:0] qsfp_0_txd_0; +wire [7:0] qsfp_0_txc_0; +wire [63:0] qsfp_0_txd_1; +wire [7:0] qsfp_0_txc_1; +wire [63:0] qsfp_0_txd_2; +wire [7:0] qsfp_0_txc_2; +wire [63:0] qsfp_0_txd_3; +wire [7:0] qsfp_0_txc_3; +wire [63:0] qsfp_1_txd_0; +wire [7:0] qsfp_1_txc_0; +wire [63:0] qsfp_1_txd_1; +wire [7:0] qsfp_1_txc_1; +wire [63:0] qsfp_1_txd_2; +wire [7:0] qsfp_1_txc_2; +wire [63:0] qsfp_1_txd_3; +wire [7:0] qsfp_1_txc_3; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + user_sw, + qsfp_0_tx_clk_0, + qsfp_0_tx_rst_0, + qsfp_0_rx_clk_0, + qsfp_0_rx_rst_0, + qsfp_0_rxd_0, + qsfp_0_rxc_0, + qsfp_0_tx_clk_1, + qsfp_0_tx_rst_1, + qsfp_0_rx_clk_1, + qsfp_0_rx_rst_1, + qsfp_0_rxd_1, + qsfp_0_rxc_1, + qsfp_0_tx_clk_2, + qsfp_0_tx_rst_2, + qsfp_0_rx_clk_2, + qsfp_0_rx_rst_2, + qsfp_0_rxd_2, + qsfp_0_rxc_2, + qsfp_0_tx_clk_3, + qsfp_0_tx_rst_3, + qsfp_0_rx_clk_3, + qsfp_0_rx_rst_3, + qsfp_0_rxd_3, + qsfp_0_rxc_3, + qsfp_1_tx_clk_0, + qsfp_1_tx_rst_0, + qsfp_1_rx_clk_0, + qsfp_1_rx_rst_0, + qsfp_1_rxd_0, + qsfp_1_rxc_0, + qsfp_1_tx_clk_1, + qsfp_1_tx_rst_1, + qsfp_1_rx_clk_1, + qsfp_1_rx_rst_1, + qsfp_1_rxd_1, + qsfp_1_rxc_1, + qsfp_1_tx_clk_2, + qsfp_1_tx_rst_2, + qsfp_1_rx_clk_2, + qsfp_1_rx_rst_2, + qsfp_1_rxd_2, + qsfp_1_rxc_2, + qsfp_1_tx_clk_3, + qsfp_1_tx_rst_3, + qsfp_1_rx_clk_3, + qsfp_1_rx_rst_3, + qsfp_1_rxd_3, + qsfp_1_rxc_3 + ); + $to_myhdl( + user_led_g, + user_led_r, + front_led, + qsfp_0_txd_0, + qsfp_0_txc_0, + qsfp_0_txd_1, + qsfp_0_txc_1, + qsfp_0_txd_2, + qsfp_0_txc_2, + qsfp_0_txd_3, + qsfp_0_txc_3, + qsfp_1_txd_0, + qsfp_1_txc_0, + qsfp_1_txd_1, + qsfp_1_txc_1, + qsfp_1_txd_2, + qsfp_1_txc_2, + qsfp_1_txd_3, + qsfp_1_txc_3 + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .user_led_g(user_led_g), + .user_led_r(user_led_r), + .front_led(front_led), + .user_sw(user_sw), + .qsfp_0_tx_clk_0(qsfp_0_tx_clk_0), + .qsfp_0_tx_rst_0(qsfp_0_tx_rst_0), + .qsfp_0_txd_0(qsfp_0_txd_0), + .qsfp_0_txc_0(qsfp_0_txc_0), + .qsfp_0_rx_clk_0(qsfp_0_rx_clk_0), + .qsfp_0_rx_rst_0(qsfp_0_rx_rst_0), + .qsfp_0_rxd_0(qsfp_0_rxd_0), + .qsfp_0_rxc_0(qsfp_0_rxc_0), + .qsfp_0_tx_clk_1(qsfp_0_tx_clk_1), + .qsfp_0_tx_rst_1(qsfp_0_tx_rst_1), + .qsfp_0_txd_1(qsfp_0_txd_1), + .qsfp_0_txc_1(qsfp_0_txc_1), + .qsfp_0_rx_clk_1(qsfp_0_rx_clk_1), + .qsfp_0_rx_rst_1(qsfp_0_rx_rst_1), + .qsfp_0_rxd_1(qsfp_0_rxd_1), + .qsfp_0_rxc_1(qsfp_0_rxc_1), + .qsfp_0_tx_clk_2(qsfp_0_tx_clk_2), + .qsfp_0_tx_rst_2(qsfp_0_tx_rst_2), + .qsfp_0_txd_2(qsfp_0_txd_2), + .qsfp_0_txc_2(qsfp_0_txc_2), + .qsfp_0_rx_clk_2(qsfp_0_rx_clk_2), + .qsfp_0_rx_rst_2(qsfp_0_rx_rst_2), + .qsfp_0_rxd_2(qsfp_0_rxd_2), + .qsfp_0_rxc_2(qsfp_0_rxc_2), + .qsfp_0_tx_clk_3(qsfp_0_tx_clk_3), + .qsfp_0_tx_rst_3(qsfp_0_tx_rst_3), + .qsfp_0_txd_3(qsfp_0_txd_3), + .qsfp_0_txc_3(qsfp_0_txc_3), + .qsfp_0_rx_clk_3(qsfp_0_rx_clk_3), + .qsfp_0_rx_rst_3(qsfp_0_rx_rst_3), + .qsfp_0_rxd_3(qsfp_0_rxd_3), + .qsfp_0_rxc_3(qsfp_0_rxc_3), + .qsfp_1_tx_clk_0(qsfp_1_tx_clk_0), + .qsfp_1_tx_rst_0(qsfp_1_tx_rst_0), + .qsfp_1_txd_0(qsfp_1_txd_0), + .qsfp_1_txc_0(qsfp_1_txc_0), + .qsfp_1_rx_clk_0(qsfp_1_rx_clk_0), + .qsfp_1_rx_rst_0(qsfp_1_rx_rst_0), + .qsfp_1_rxd_0(qsfp_1_rxd_0), + .qsfp_1_rxc_0(qsfp_1_rxc_0), + .qsfp_1_tx_clk_1(qsfp_1_tx_clk_1), + .qsfp_1_tx_rst_1(qsfp_1_tx_rst_1), + .qsfp_1_txd_1(qsfp_1_txd_1), + .qsfp_1_txc_1(qsfp_1_txc_1), + .qsfp_1_rx_clk_1(qsfp_1_rx_clk_1), + .qsfp_1_rx_rst_1(qsfp_1_rx_rst_1), + .qsfp_1_rxd_1(qsfp_1_rxd_1), + .qsfp_1_rxc_1(qsfp_1_rxc_1), + .qsfp_1_tx_clk_2(qsfp_1_tx_clk_2), + .qsfp_1_tx_rst_2(qsfp_1_tx_rst_2), + .qsfp_1_txd_2(qsfp_1_txd_2), + .qsfp_1_txc_2(qsfp_1_txc_2), + .qsfp_1_rx_clk_2(qsfp_1_rx_clk_2), + .qsfp_1_rx_rst_2(qsfp_1_rx_rst_2), + .qsfp_1_rxd_2(qsfp_1_rxd_2), + .qsfp_1_rxc_2(qsfp_1_rxc_2), + .qsfp_1_tx_clk_3(qsfp_1_tx_clk_3), + .qsfp_1_tx_rst_3(qsfp_1_tx_rst_3), + .qsfp_1_txd_3(qsfp_1_txd_3), + .qsfp_1_txc_3(qsfp_1_txc_3), + .qsfp_1_rx_clk_3(qsfp_1_rx_clk_3), + .qsfp_1_rx_rst_3(qsfp_1_rx_rst_3), + .qsfp_1_rxd_3(qsfp_1_rxd_3), + .qsfp_1_rxc_3(qsfp_1_rxc_3) +); + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py b/example/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py b/example/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file From 6d52a7c0e7efa897a032239311eb22b284397a9e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 8 Jan 2019 17:31:49 -0800 Subject: [PATCH 496/617] Remove unneeded links --- example/ADM_PCIE_9V3/fpga_10g/tb/gmii_ep.py | 1 - example/ExaNIC_X10/fpga/tb/gmii_ep.py | 1 - example/ExaNIC_X10/fpga/tb/test_fpga_core.py | 1 - 3 files changed, 3 deletions(-) delete mode 120000 example/ADM_PCIE_9V3/fpga_10g/tb/gmii_ep.py delete mode 120000 example/ExaNIC_X10/fpga/tb/gmii_ep.py diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/gmii_ep.py b/example/ADM_PCIE_9V3/fpga_10g/tb/gmii_ep.py deleted file mode 120000 index 754166f2f..000000000 --- a/example/ADM_PCIE_9V3/fpga_10g/tb/gmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga/tb/gmii_ep.py b/example/ExaNIC_X10/fpga/tb/gmii_ep.py deleted file mode 120000 index 754166f2f..000000000 --- a/example/ExaNIC_X10/fpga/tb/gmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga/tb/test_fpga_core.py b/example/ExaNIC_X10/fpga/tb/test_fpga_core.py index 773a2ff3b..4880532a0 100755 --- a/example/ExaNIC_X10/fpga/tb/test_fpga_core.py +++ b/example/ExaNIC_X10/fpga/tb/test_fpga_core.py @@ -29,7 +29,6 @@ import os import eth_ep import arp_ep import udp_ep -import gmii_ep import xgmii_ep module = 'fpga_core' From b8b504682a39f71b649ccc50cfcebceb2c85de03 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 15 Jan 2019 00:30:36 -0800 Subject: [PATCH 497/617] Fix transceiver clocking --- example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v index 58cc9ea4f..a4c3c2897 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v +++ b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v @@ -351,10 +351,10 @@ always @(posedge gt_txusrclk, posedge gt_tx_reset) begin end end -genvar n; - generate +genvar n; + for (n = 0; n < 8; n = n + 1) begin BUFG_GT bufg_gt_rx_usrclk_inst ( @@ -561,7 +561,7 @@ qsfp_0_pcs_pma_0 ( // GTY interface .tx_core_clk_0(clk_156mhz_int), .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[0]), + .rx_serdes_clk_0(gt_rxusrclk[4]), .rx_serdes_reset_0(qsfp_0_serdes_reset_0), .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_0), .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_0), @@ -624,7 +624,7 @@ qsfp_0_pcs_pma_1 ( // GTY interface .tx_core_clk_0(clk_156mhz_int), .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[1]), + .rx_serdes_clk_0(gt_rxusrclk[5]), .rx_serdes_reset_0(qsfp_0_serdes_reset_1), .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_1), .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_1), @@ -687,7 +687,7 @@ qsfp_0_pcs_pma_2 ( // GTY interface .tx_core_clk_0(clk_156mhz_int), .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[2]), + .rx_serdes_clk_0(gt_rxusrclk[6]), .rx_serdes_reset_0(qsfp_0_serdes_reset_2), .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_2), .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_2), @@ -750,7 +750,7 @@ qsfp_0_pcs_pma_3 ( // GTY interface .tx_core_clk_0(clk_156mhz_int), .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[3]), + .rx_serdes_clk_0(gt_rxusrclk[7]), .rx_serdes_reset_0(qsfp_0_serdes_reset_3), .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_3), .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_3), @@ -813,7 +813,7 @@ qsfp_1_pcs_pma_0 ( // GTY interface .tx_core_clk_0(clk_156mhz_int), .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[4]), + .rx_serdes_clk_0(gt_rxusrclk[0]), .rx_serdes_reset_0(qsfp_1_serdes_reset_0), .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_0), .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_0), @@ -876,7 +876,7 @@ qsfp_1_pcs_pma_1 ( // GTY interface .tx_core_clk_0(clk_156mhz_int), .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[5]), + .rx_serdes_clk_0(gt_rxusrclk[1]), .rx_serdes_reset_0(qsfp_1_serdes_reset_1), .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_1), .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_1), @@ -939,7 +939,7 @@ qsfp_1_pcs_pma_2 ( // GTY interface .tx_core_clk_0(clk_156mhz_int), .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[6]), + .rx_serdes_clk_0(gt_rxusrclk[2]), .rx_serdes_reset_0(qsfp_1_serdes_reset_2), .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_2), .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_2), @@ -1002,7 +1002,7 @@ qsfp_1_pcs_pma_3 ( // GTY interface .tx_core_clk_0(clk_156mhz_int), .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[7]), + .rx_serdes_clk_0(gt_rxusrclk[3]), .rx_serdes_reset_0(qsfp_1_serdes_reset_3), .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_3), .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_3), From bf94ef56b881f0da492d0d2eddeffbab4b8efee5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 16 Jan 2019 13:23:02 -0800 Subject: [PATCH 498/617] Move ifg parameter --- tb/xgmii_ep.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index b0f2b42f0..fa1bb83a7 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -121,9 +121,11 @@ class XGMIIFrame(object): class XGMIISource(object): - def __init__(self): + def __init__(self, ifg=12, enable_dic=True): self.has_logic = False self.queue = [] + self.ifg = ifg + self.enable_dic = enable_dic def send(self, frame): self.queue.append(XGMIIFrame(frame)) @@ -140,7 +142,6 @@ class XGMIISource(object): txd, txc, enable=True, - ifg=12, name=None ): @@ -173,7 +174,7 @@ class XGMIISource(object): ifg_cnt = 0 deficit_idle_cnt = 0 elif enable: - if ifg_cnt > bw-1: + if (ifg_cnt > bw-1 and self.enable_dic) or ifg_cnt > 0: ifg_cnt -= bw txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 txc.next = 0xff if bw == 8 else 0xf @@ -186,7 +187,7 @@ class XGMIISource(object): d |= dl.pop(0) << (8*i) c |= cl.pop(0) << i if not dl: - ifg_cnt = max(ifg, 12) - (bw-i) + deficit_idle_cnt + ifg_cnt = self.ifg - (bw-i) + deficit_idle_cnt else: d |= XGMII_IDLE << (8*i) c |= 1 << i @@ -222,7 +223,7 @@ class XGMIISource(object): d |= dl.pop(0) << (8*i) c |= cl.pop(0) << i if not dl: - ifg_cnt = max(ifg, 12) - (bw-i) + deficit_idle_cnt + ifg_cnt = self.ifg - (bw-i) + deficit_idle_cnt else: d |= XGMII_IDLE << (8*i) c |= 1 << i From 32d889b20dc4deec356a644167d0e867429b126c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 16 Jan 2019 13:26:14 -0800 Subject: [PATCH 499/617] Remove unreachable code --- rtl/axis_xgmii_rx_32.v | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index 5e6e2012e..f27730bba 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -353,12 +353,7 @@ always @* begin error_bad_fcs_next = 1'b1; end - if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == XGMII_START) begin - // start condition - state_next = STATE_PAYLOAD; - end else begin - state_next = STATE_IDLE; - end + state_next = STATE_IDLE; end endcase end From ea02b6c898073154079072d28a52226dc1064b50 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 16 Jan 2019 13:26:47 -0800 Subject: [PATCH 500/617] Properly handle short IFG --- rtl/axis_xgmii_rx_64.v | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index 3d50af09c..9bbe6d29a 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -85,6 +85,7 @@ reg [3:0] swap_rxc = 4'd0; reg [63:0] xgmii_rxd_d0 = 32'd0; reg [63:0] xgmii_rxd_d1 = 32'd0; +reg [63:0] xgmii_rxd_crc = 32'd0; reg [7:0] xgmii_rxc_d0 = 8'd0; reg [7:0] xgmii_rxc_d1 = 8'd0; @@ -136,7 +137,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_8 ( - .data_in(xgmii_rxd_d0[7:0]), + .data_in(xgmii_rxd_crc[7:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next0) @@ -152,7 +153,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_16 ( - .data_in(xgmii_rxd_d0[15:0]), + .data_in(xgmii_rxd_crc[15:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next1) @@ -168,7 +169,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_24 ( - .data_in(xgmii_rxd_d0[23:0]), + .data_in(xgmii_rxd_crc[23:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next2) @@ -184,7 +185,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_32 ( - .data_in(xgmii_rxd_d0[31:0]), + .data_in(xgmii_rxd_crc[31:0]), .state_in(last_cycle ? crc_state3 : crc_state), .data_out(), .state_out(crc_next3) @@ -391,7 +392,20 @@ always @* begin if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == XGMII_START) begin // start condition - state_next = STATE_PAYLOAD; + if (control_masked) begin + // control or error characters in first data word + m_axis_tdata_next = 64'd0; + m_axis_tkeep_next = 8'h01; + m_axis_tvalid_next = 1'b1; + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + state_next = STATE_IDLE; + end else begin + reset_crc = 1'b0; + update_crc = 1'b1; + state_next = STATE_PAYLOAD; + end end else begin state_next = STATE_IDLE; end @@ -436,10 +450,6 @@ always @(posedge clk) begin xgmii_rxc_d0 <= xgmii_rxc; end - if (state_next == STATE_LAST) begin - xgmii_rxc_d0[3:0] <= xgmii_rxc_d0[7:4]; - end - xgmii_rxc_d1 <= xgmii_rxc_d0; // datapath @@ -468,16 +478,20 @@ always @(posedge clk) begin if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin xgmii_rxd_d0 <= xgmii_rxd; + xgmii_rxd_crc <= xgmii_rxd; end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; + xgmii_rxd_crc <= {xgmii_rxd[31:0], swap_rxd}; end else if (lanes_swapped) begin xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; + xgmii_rxd_crc <= {xgmii_rxd[31:0], swap_rxd}; end else begin xgmii_rxd_d0 <= xgmii_rxd; + xgmii_rxd_crc <= xgmii_rxd; end if (state_next == STATE_LAST) begin - xgmii_rxd_d0[31:0] <= xgmii_rxd_d0[63:32]; + xgmii_rxd_crc[31:0] <= xgmii_rxd_crc[63:32]; end xgmii_rxd_d1 <= xgmii_rxd_d0; From 128dc292a1088900d84b09c6dccf5448830bcf39 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 16 Jan 2019 13:27:28 -0800 Subject: [PATCH 501/617] Add short IFG tests --- tb/test_axis_xgmii_rx_32.py | 33 +++++++++++++++++++++++++++++++++ tb/test_axis_xgmii_rx_64.py | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/tb/test_axis_xgmii_rx_32.py b/tb/test_axis_xgmii_rx_32.py index 0828b7131..291eab65a 100755 --- a/tb/test_axis_xgmii_rx_32.py +++ b/tb/test_axis_xgmii_rx_32.py @@ -351,6 +351,39 @@ def bench(): yield delay(100) + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 6: test stream with zero IFG, length %d" % payload_len) + current_test.next = 6 + + source.ifg = 0 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + source.ifg = 12 + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_xgmii_rx_64.py b/tb/test_axis_xgmii_rx_64.py index 59b2a2198..9cb96467f 100755 --- a/tb/test_axis_xgmii_rx_64.py +++ b/tb/test_axis_xgmii_rx_64.py @@ -351,9 +351,42 @@ def bench(): yield delay(100) + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 6: test stream with zero IFG, length %d" % payload_len) + current_test.next = 6 + + source.ifg = 0 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + source.ifg = 12 + + yield delay(100) + yield clk.posedge - print("test 6: Ensure 0xfb in FCS in lane 4 is not detected as start code in lane 0") - current_test.next = 6 + print("test 7: Ensure 0xfb in FCS in lane 4 is not detected as start code in lane 0") + current_test.next = 7 test_frame = eth_ep.EthFrame() test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 From 5fbd67501c50e31f1b98e40893df97685696036e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 16 Jan 2019 17:25:08 -0800 Subject: [PATCH 502/617] Clamp ifg_cnt at zero --- tb/xgmii_ep.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index fa1bb83a7..9778084e6 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -175,7 +175,7 @@ class XGMIISource(object): deficit_idle_cnt = 0 elif enable: if (ifg_cnt > bw-1 and self.enable_dic) or ifg_cnt > 0: - ifg_cnt -= bw + ifg_cnt = max(ifg_cnt - bw, 0) txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 txc.next = 0xff if bw == 8 else 0xf elif dl: From c9752f24ddb883c9f28a79408c415eef26f6caa7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 16 Jan 2019 17:26:19 -0800 Subject: [PATCH 503/617] Add BASE-R SERDES endpoint model --- tb/baser_serdes_ep.py | 664 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 664 insertions(+) create mode 100644 tb/baser_serdes_ep.py diff --git a/tb/baser_serdes_ep.py b/tb/baser_serdes_ep.py new file mode 100644 index 000000000..f975c9885 --- /dev/null +++ b/tb/baser_serdes_ep.py @@ -0,0 +1,664 @@ +""" + +Copyright (c) 2018 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 xgmii_ep + +ETH_PRE = 0x55 +ETH_SFD = 0xD5 + +XGMII_IDLE = 0x07 +XGMII_LPI = 0x06 +XGMII_START = 0xfb +XGMII_TERM = 0xfd +XGMII_ERROR = 0xfe +XGMII_SEQ_OS = 0x9c +XGMII_RES_0 = 0x1c +XGMII_RES_1 = 0x3c +XGMII_RES_2 = 0x7c +XGMII_RES_3 = 0xbc +XGMII_RES_4 = 0xdc +XGMII_RES_5 = 0xf7 +XGMII_SIG_OS = 0x5c + +CTRL_IDLE = 0x00 +CTRL_LPI = 0x06 +CTRL_ERROR = 0x1e +CTRL_RES_0 = 0x2d +CTRL_RES_1 = 0x33 +CTRL_RES_2 = 0x4b +CTRL_RES_3 = 0x55 +CTRL_RES_4 = 0x66 +CTRL_RES_5 = 0x78 + +O_SEQ_OS = 0x0 +O_SIG_OS = 0xf + +SYNC_DATA = 0b10 +SYNC_CTRL = 0b01 + +BLOCK_TYPE_CTRL = 0x1e # C7 C6 C5 C4 C3 C2 C1 C0 BT +BLOCK_TYPE_OS_4 = 0x2d # D7 D6 D5 O4 C3 C2 C1 C0 BT +BLOCK_TYPE_START_4 = 0x33 # D7 D6 D5 C3 C2 C1 C0 BT +BLOCK_TYPE_OS_START = 0x66 # D7 D6 D5 O0 D3 D2 D1 BT +BLOCK_TYPE_OS_04 = 0x55 # D7 D6 D5 O4 O0 D3 D2 D1 BT +BLOCK_TYPE_START_0 = 0x78 # D7 D6 D5 D4 D3 D2 D1 BT +BLOCK_TYPE_OS_0 = 0x4b # C7 C6 C5 C4 O0 D3 D2 D1 BT +BLOCK_TYPE_TERM_0 = 0x87 # C7 C6 C5 C4 C3 C2 C1 BT +BLOCK_TYPE_TERM_1 = 0x99 # C7 C6 C5 C4 C3 C2 D0 BT +BLOCK_TYPE_TERM_2 = 0xaa # C7 C6 C5 C4 C3 D1 D0 BT +BLOCK_TYPE_TERM_3 = 0xb4 # C7 C6 C5 C4 D2 D1 D0 BT +BLOCK_TYPE_TERM_4 = 0xcc # C7 C6 C5 D3 D2 D1 D0 BT +BLOCK_TYPE_TERM_5 = 0xd2 # C7 C6 D4 D3 D2 D1 D0 BT +BLOCK_TYPE_TERM_6 = 0xe1 # C7 D5 D4 D3 D2 D1 D0 BT +BLOCK_TYPE_TERM_7 = 0xff # D6 D5 D4 D3 D2 D1 D0 BT + +def block_type_term_lane(bt): + if bt == BLOCK_TYPE_TERM_0: + return 0 + elif bt == BLOCK_TYPE_TERM_1: + return 1 + elif bt == BLOCK_TYPE_TERM_2: + return 2 + elif bt == BLOCK_TYPE_TERM_3: + return 3 + elif bt == BLOCK_TYPE_TERM_4: + return 4 + elif bt == BLOCK_TYPE_TERM_5: + return 5 + elif bt == BLOCK_TYPE_TERM_6: + return 6 + elif bt == BLOCK_TYPE_TERM_7: + return 7 + else: + return None + +class BaseRSerdesSource(object): + def __init__(self, ifg=12, enable_dic=True): + self.has_logic = False + self.queue = [] + self.ifg = ifg + self.enable_dic = enable_dic + + def send(self, frame): + self.queue.append(xgmii_ep.XGMIIFrame(frame)) + + def count(self): + return len(self.queue) + + def empty(self): + return not self.queue + + def create_logic(self, + clk, + tx_data, + tx_header, + enable=True, + scramble=True, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + assert len(tx_data) in [64] + assert len(tx_data) == len(tx_header)*32 + + bw = int(len(tx_data)/8) + + @instance + def logic(): + frame = None + ccl = [] + ifg_cnt = 0 + deficit_idle_cnt = 0 + scrambler_state = 0 + + while True: + yield clk.posedge + + if enable: + data = 0x000000000000001e + header = 0b01 + + if (ifg_cnt > bw-1 and self.enable_dic) or ifg_cnt > 0: + ifg_cnt = max(ifg_cnt - bw, 0) + elif ccl: + header, data = ccl.pop(0) + if not ccl: + l = block_type_term_lane(data & 0xff) + if l is not None: + ifg_cnt = self.ifg - (bw-l) + deficit_idle_cnt + else: + ifg_cnt = self.ifg + deficit_idle_cnt + elif self.queue: + frame = self.queue.pop(0) + dl, cl = frame.build() + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + + assert len(dl) > 0 + assert dl[0] == ETH_PRE + dl[0] = XGMII_START + cl[0] = 1 + dl.append(XGMII_TERM) + cl.append(1) + + if bw == 8 and ifg_cnt >= 4: + ifg_cnt = max(ifg_cnt-4, 0) + dl = [XGMII_IDLE]*4+dl + cl = [1]*4+cl + + deficit_idle_cnt = ifg_cnt + ifg_cnt = 0 + + # pad length to multiple of 8 by adding idles + if len(dl)%8: + for k in range(8-(len(dl)%8)): + dl.append(XGMII_IDLE) + cl.append(1) + + # 10GBASE-R encoding + for k in range(0, len(dl), 8): + di = dl[k:k+8] + ci = cl[k:k+8] + + # remap control characters + ctrl = 0 + ctrl_decode_error = [0]*8 + for i in range(8): + if not ci[i]: + # data + ctrl |= CTRL_ERROR << i*7 + elif di[i] == XGMII_IDLE: + # idle + ctrl |= CTRL_IDLE << i*7 + elif di[i] == XGMII_LPI: + # LPI + ctrl |= CTRL_LPI << i*7 + elif di[i] == XGMII_ERROR: + # error + ctrl |= CTRL_ERROR << i*7 + elif di[i] == XGMII_RES_0: + # reserved0 + ctrl |= CTRL_RES_0 << i*7 + elif di[i] == XGMII_RES_1: + # reserved1 + ctrl |= CTRL_RES_1 << i*7 + elif di[i] == XGMII_RES_2: + # reserved2 + ctrl |= CTRL_RES_2 << i*7 + elif di[i] == XGMII_RES_3: + # reserved3 + ctrl |= CTRL_RES_3 << i*7 + elif di[i] == XGMII_RES_4: + # reserved4 + ctrl |= CTRL_RES_4 << i*7 + elif di[i] == XGMII_RES_5: + # reserved5 + ctrl |= CTRL_RES_5 << i*7 + else: + # invalid + ctrl |= CTRL_ERROR << i*7 + ctrl_decode_error[i] = ci[i] + + if not any(ci): + # data + h = SYNC_DATA + d = 0 + for i in range(8): + d |= di[i] << i*8 + else: + # control + h = SYNC_CTRL + if ci[0] and di[0] == XGMII_START and not any(ci[1:]): + # start in lane 0 + d = BLOCK_TYPE_START_0 + for i in range(1,8): + d |= di[i] << i*8 + elif ci[4] and di[4] == XGMII_START and not any(ci[5:]): + # start in lane 4 + if ci[0] and (di[0] == XGMII_SEQ_OS or di[0] == XGMII_SIG_OS) and not any(ci[1:4]): + # ordered set in lane 0 + d = BLOCK_TYPE_OS_START + for i in range(1,4): + d |= di[i] << i*8 + if di[0] == XGMII_SIG_OS: + # signal ordered set + d |= O_SIG_OS << 32 + else: + # other control + d = BLOCK_TYPE_START_4 | (ctrl & 0xfffffff) << 8 + + for i in range(5,8): + d |= di[i] << i*8 + elif ci[0] and (di[0] == XGMII_SEQ_OS or di[0] == XGMII_SIG_OS) and not any(ci[1:4]): + # ordered set in lane 0 + if ci[4] and (di[4] == XGMII_SEQ_OS or di[4] == XGMII_SIG_OS) and not any(ci[5:8]): + # ordered set in lane 4 + d = BLOCK_TYPE_OS_04 + for i in range(5,8): + d |= di[i] << i*8 + if di[4] == XGMII_SIG_OS: + # signal ordered set + d |= O_SIG_OS << 36 + else: + d = BLOCK_TYPE_OS_0 | (ctrl & 0xfffffff) << 40 + for i in range(1,4): + d |= di[i] << i*8 + if di[0] == XGMII_SIG_OS: + # signal ordered set + d |= O_SIG_OS << 32 + elif ci[4] and (di[4] == XGMII_SEQ_OS or di[4] == XGMII_SIG_OS) and not any(ci[5:8]): + # ordered set in lane 4 + d = BLOCK_TYPE_OS_4 | (ctrl & 0xfffffff) << 8 + for i in range(5,8): + d |= di[i] << i*8 + if di[4] == XGMII_SIG_OS: + # signal ordered set + d |= O_SIG_OS << 36 + elif ci[0] and di[0] == XGMII_TERM: + # terminate in lane 0 + d = BLOCK_TYPE_TERM_0 | (ctrl & 0xffffffffffff80) << 8 + elif ci[1] and di[1] == XGMII_TERM and not ci[0]: + # terminate in lane 1 + d = BLOCK_TYPE_TERM_1 | (ctrl & 0xffffffffffc000) << 8 | di[0] << 8 + elif ci[2] and di[2] == XGMII_TERM and not any(ci[0:1]): + # terminate in lane 2 + d = BLOCK_TYPE_TERM_2 | (ctrl & 0xffffffffe00000) << 8 + for i in range(2): + d |= di[i] << ((i+1)*8) + elif ci[3] and di[3] == XGMII_TERM and not any(ci[0:2]): + # terminate in lane 3 + d = BLOCK_TYPE_TERM_3 | (ctrl & 0xfffffff0000000) << 8 + for i in range(3): + d |= di[i] << ((i+1)*8) + elif ci[4] and di[4] == XGMII_TERM and not any(ci[0:3]): + # terminate in lane 4 + d = BLOCK_TYPE_TERM_4 | (ctrl & 0xfffff800000000) << 8 + for i in range(4): + d |= di[i] << ((i+1)*8) + elif ci[5] and di[5] == XGMII_TERM and not any(ci[0:4]): + # terminate in lane 5 + d = BLOCK_TYPE_TERM_5 | (ctrl & 0xfffc0000000000) << 8 + for i in range(5): + d |= di[i] << ((i+1)*8) + elif ci[6] and di[6] == XGMII_TERM and not any(ci[0:5]): + # terminate in lane 6 + d = BLOCK_TYPE_TERM_6 | (ctrl & 0xfe000000000000) << 8 + for i in range(6): + d |= di[i] << ((i+1)*8) + elif ci[7] and di[7] == XGMII_TERM and not any(ci[0:6]): + # terminate in lane 7 + d = BLOCK_TYPE_TERM_7 + for i in range(7): + d |= di[i] << ((i+1)*8) + else: + # all control + d = BLOCK_TYPE_CTRL | ctrl << 8 + + ccl.append((h, d)) + + header, data = ccl.pop(0) + if not ccl: + l = block_type_term_lane(data & 0xff) + if l is not None: + ifg_cnt = self.ifg - (bw-l) + deficit_idle_cnt + else: + ifg_cnt = self.ifg + deficit_idle_cnt + else: + ifg_cnt = 0 + deficit_idle_cnt = 0 + + if scramble: + # 64b66b scrambler + b = 0 + for i in range(len(tx_data)): + if bool(scrambler_state & (1<<38)) ^ bool(scrambler_state & (1<<57)) ^ bool(data & (1 << i)): + scrambler_state = ((scrambler_state & 0x1ffffffffffffff) << 1) | 1 + b = b | (1 << i) + else: + scrambler_state = (scrambler_state & 0x1ffffffffffffff) << 1 + data = b + + tx_data.next = data + tx_header.next = header + + return instances() + + +class BaseRSerdesSink(object): + def __init__(self): + self.has_logic = False + self.queue = [] + self.sync = Signal(intbv(0)) + + def recv(self): + if self.queue: + return self.queue.pop(0) + return None + + def count(self): + return len(self.queue) + + def empty(self): + return not self.queue + + def wait(self, timeout=0): + if self.queue: + return + if timeout: + yield self.sync, delay(timeout) + else: + yield self.sync + + def create_logic(self, + clk, + rx_data, + rx_header, + enable=True, + scramble=True, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + assert len(rx_data) in [64] + assert len(rx_data) == len(rx_header)*32 + + bw = int(len(rx_data)/8) + + @instance + def logic(): + frame = None + d = [] + c = [] + scrambler_state = 0 + + while True: + yield clk.posedge + + if enable: + data = int(rx_data) + header = int(rx_header) + + if scramble: + # 64b66b descrambler + b = 0 + for i in range(len(rx_data)): + if bool(scrambler_state & (1<<38)) ^ bool(scrambler_state & (1<<57)) ^ bool(data & (1 << i)): + b = b | (1 << i) + scrambler_state = (scrambler_state & 0x1ffffffffffffff) << 1 | bool(data & (1 << i)) + data = b + + # 10GBASE-R decoding + + # remap control characters + ctrl = [0]*8 + for i in range(8): + if (data >> i*7+8) & 0x7f == CTRL_IDLE: + # idle + ctrl[i] = XGMII_IDLE; + elif (data >> i*7+8) & 0x7f == CTRL_LPI: + # LPI + ctrl[i] = XGMII_LPI + elif (data >> i*7+8) & 0x7f == CTRL_ERROR: + # error + ctrl[i] = XGMII_ERROR + elif (data >> i*7+8) & 0x7f == CTRL_RES_0: + # reserved0 + ctrl[i] = XGMII_RES_0 + elif (data >> i*7+8) & 0x7f == CTRL_RES_1: + # reserved1 + ctrl[i] = XGMII_RES_1 + elif (data >> i*7+8) & 0x7f == CTRL_RES_2: + # reserved2 + ctrl[i] = XGMII_RES_2 + elif (data >> i*7+8) & 0x7f == CTRL_RES_3: + # reserved3 + ctrl[i] = XGMII_RES_3 + elif (data >> i*7+8) & 0x7f == CTRL_RES_4: + # reserved4 + ctrl[i] = XGMII_RES_4 + elif (data >> i*7+8) & 0x7f == CTRL_RES_5: + # reserved5 + ctrl[i] = XGMII_RES_5 + else: + # invalid + ctrl[i] = XGMII_ERROR + + dl = [] + cl = [] + if header == SYNC_DATA: + # data + for k in range(8): + dl.append((data >> k*8) & 0xff) + cl.append(0) + elif header == SYNC_CTRL: + if data & 0xff == BLOCK_TYPE_CTRL: + # C7 C6 C5 C4 C3 C2 C1 C0 BT + dl = ctrl + cl = [1]*8 + elif data & 0xff == BLOCK_TYPE_OS_4: + # D7 D6 D5 O4 C3 C2 C1 C0 BT + dl = ctrl[0:4] + cl = [1]*4 + if (data >> 36) & 0xf == O_SEQ_OS: + dl.append(XGMII_SEQ_OS) + elif (data >> 36) & 0xf == O_SIG_OS: + dl.append(XGMII_SIG_OS) + else: + dl.append(XGMII_ERROR) + cl.append(1) + for k in range(4,7): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + elif data & 0xff == BLOCK_TYPE_START_4: + # D7 D6 D5 C3 C2 C1 C0 BT + dl = ctrl[0:4] + cl = [1]*4 + dl.append(XGMII_START) + cl.append(1) + for k in range(4,7): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + elif data & 0xff == BLOCK_TYPE_OS_START: + # D7 D6 D5 O0 D3 D2 D1 BT + if (data >> 32) & 0xf == O_SEQ_OS: + dl.append(XGMII_SEQ_OS) + elif (data >> 32) & 0xf == O_SIG_OS: + dl.append(XGMII_SIG_OS) + else: + dl.append(XGMII_ERROR) + cl.append(1) + for k in range(0,3): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + dl.append(XGMII_START) + cl.append(1) + for k in range(4,7): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + elif data & 0xff == BLOCK_TYPE_OS_04: + # D7 D6 D5 O4 O0 D3 D2 D1 BT + if (data >> 32) & 0xf == O_SEQ_OS: + dl.append(XGMII_SEQ_OS) + elif (data >> 32) & 0xf == O_SIG_OS: + dl.append(XGMII_SIG_OS) + else: + dl.append(XGMII_ERROR) + cl.append(1) + for k in range(0,3): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + if (data >> 36) & 0xf == O_SEQ_OS: + dl.append(XGMII_SEQ_OS) + elif (data >> 36) & 0xf == O_SIG_OS: + dl.append(XGMII_SIG_OS) + else: + dl.append(XGMII_ERROR) + cl.append(1) + for k in range(4,7): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + elif data & 0xff == BLOCK_TYPE_START_0: + # D7 D6 D5 D4 D3 D2 D1 BT + dl.append(XGMII_START) + cl.append(1) + for k in range(7): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + elif data & 0xff == BLOCK_TYPE_OS_0: + # C7 C6 C5 C4 O0 D3 D2 D1 BT + if (data >> 32) & 0xf == O_SEQ_OS: + dl.append(XGMII_SEQ_OS) + elif (data >> 32) & 0xf == O_SIG_OS: + dl.append(XGMII_SEQ_OS) + else: + dl.append(XGMII_ERROR) + cl.append(1) + for k in range(0,3): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + dl.extend(ctrl[4:8]) + cl.extend([1]*4) + elif data & 0xff == BLOCK_TYPE_TERM_0: + # C7 C6 C5 C4 C3 C2 C1 BT + dl.append(XGMII_TERM) + cl.append(1) + dl.extend(ctrl[1:]) + cl.extend([1]*7) + elif data & 0xff == BLOCK_TYPE_TERM_1: + # C7 C6 C5 C4 C3 C2 D0 BT + dl.append((data >> 8) & 0xff) + cl.append(0) + dl.append(XGMII_TERM) + cl.append(1) + dl.extend(ctrl[2:]) + cl.extend([1]*6) + elif data & 0xff == BLOCK_TYPE_TERM_2: + # C7 C6 C5 C4 C3 D1 D0 BT + for k in range(2): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + dl.append(XGMII_TERM) + cl.append(1) + dl.extend(ctrl[3:]) + cl.extend([1]*5) + elif data & 0xff == BLOCK_TYPE_TERM_3: + # C7 C6 C5 C4 D2 D1 D0 BT + for k in range(3): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + dl.append(XGMII_TERM) + cl.append(1) + dl.extend(ctrl[4:]) + cl.extend([1]*4) + elif data & 0xff == BLOCK_TYPE_TERM_4: + # C7 C6 C5 D3 D2 D1 D0 BT + for k in range(4): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + dl.append(XGMII_TERM) + cl.append(1) + dl.extend(ctrl[5:]) + cl.extend([1]*3) + elif data & 0xff == BLOCK_TYPE_TERM_5: + # C7 C6 D4 D3 D2 D1 D0 BT + for k in range(5): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + dl.append(XGMII_TERM) + cl.append(1) + dl.extend(ctrl[6:]) + cl.extend([1]*2) + elif data & 0xff == BLOCK_TYPE_TERM_6: + # C7 D5 D4 D3 D2 D1 D0 BT + for k in range(6): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + dl.append(XGMII_TERM) + cl.append(1) + dl.extend(ctrl[7:]) + cl.extend([1]*1) + elif data & 0xff == BLOCK_TYPE_TERM_7: + # D6 D5 D4 D3 D2 D1 D0 BT + for k in range(7): + dl.append((data >> (k+1)*8) & 0xff) + cl.append(0) + dl.append(XGMII_TERM) + cl.append(1) + else: + # invalid block type + dl = [XGMII_ERROR]*8 + cl = [1]*8 + else: + # invalid sync header + dl = [XGMII_ERROR]*8 + cl = [1]*8 + + if frame is None: + if cl[0] and dl[0] == XGMII_START: + # start in lane 0 + frame = xgmii_ep.XGMIIFrame() + d = [ETH_PRE] + c = [0] + for i in range(1,bw): + d.append(dl[i]) + c.append(cl[i]) + elif bw == 8 and cl[4] and dl[4] == XGMII_START: + # start in lane 4 + frame = xgmii_ep.XGMIIFrame() + d = [ETH_PRE] + c = [0] + for i in range(5,bw): + d.append(dl[i]) + c.append(cl[i]) + else: + for i in range(bw): + if cl[i]: + # got a control character; terminate frame reception + if dl[i] != XGMII_TERM: + # store control character if it's not a termination + d.append(dl[i]) + c.append(cl[i]) + frame.parse(d, c) + self.queue.append(frame) + self.sync.next = not self.sync + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + frame = None + d = [] + c = [] + break + else: + d.append(dl[i]) + c.append(cl[i]) + + return instances() + From 91553e6edfbaf376de735afe0bb8effef62471fb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 16 Jan 2019 17:30:07 -0800 Subject: [PATCH 504/617] Add XGMII 10GBASE-R encoder and decoder modules and testbenches --- rtl/xgmii_baser_dec_64.v | 325 ++++++++++++++++++++++++++++++++++ rtl/xgmii_baser_enc_64.v | 253 ++++++++++++++++++++++++++ tb/test_xgmii_baser_dec_64.py | 206 +++++++++++++++++++++ tb/test_xgmii_baser_dec_64.v | 87 +++++++++ tb/test_xgmii_baser_enc_64.py | 204 +++++++++++++++++++++ tb/test_xgmii_baser_enc_64.v | 84 +++++++++ 6 files changed, 1159 insertions(+) create mode 100644 rtl/xgmii_baser_dec_64.v create mode 100644 rtl/xgmii_baser_enc_64.v create mode 100755 tb/test_xgmii_baser_dec_64.py create mode 100644 tb/test_xgmii_baser_dec_64.v create mode 100755 tb/test_xgmii_baser_enc_64.py create mode 100644 tb/test_xgmii_baser_enc_64.v diff --git a/rtl/xgmii_baser_dec_64.v b/rtl/xgmii_baser_dec_64.v new file mode 100644 index 000000000..f10c88b78 --- /dev/null +++ b/rtl/xgmii_baser_dec_64.v @@ -0,0 +1,325 @@ +/* + +Copyright (c) 2018 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 + +/* + * XGMII 10GBASE-R decoder + */ +module xgmii_baser_dec_64 # +( + parameter DATA_WIDTH = 64, + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = 2 +) +( + input wire clk, + input wire rst, + + /* + * 10GBASE-R encoded input + */ + input wire [DATA_WIDTH-1:0] encoded_rx_data, + input wire [HDR_WIDTH-1:0] encoded_rx_hdr, + + /* + * XGMII interface + */ + output wire [DATA_WIDTH-1:0] xgmii_rxd, + output wire [CTRL_WIDTH-1:0] xgmii_rxc, + + /* + * Status + */ + output wire rx_bad_block +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end + + if (HDR_WIDTH != 2) begin + $error("Error: HDR_WIDTH must be 2"); + $finish; + end +end + +localparam [7:0] + XGMII_IDLE = 8'h07, + XGMII_LPI = 8'h06, + XGMII_START = 8'hfb, + XGMII_TERM = 8'hfd, + XGMII_ERROR = 8'hfe, + XGMII_SEQ_OS = 8'h9c, + XGMII_RES_0 = 8'h1c, + XGMII_RES_1 = 8'h3c, + XGMII_RES_2 = 8'h7c, + XGMII_RES_3 = 8'hbc, + XGMII_RES_4 = 8'hdc, + XGMII_RES_5 = 8'hf7, + XGMII_SIG_OS = 8'h5c; + +localparam [6:0] + CTRL_IDLE = 7'h00, + CTRL_LPI = 7'h06, + CTRL_ERROR = 7'h1e, + CTRL_RES_0 = 7'h2d, + CTRL_RES_1 = 7'h33, + CTRL_RES_2 = 7'h4b, + CTRL_RES_3 = 7'h55, + CTRL_RES_4 = 7'h66, + CTRL_RES_5 = 7'h78; + +localparam [3:0] + O_SEQ_OS = 4'h0, + O_SIG_OS = 4'hf; + +localparam [1:0] + SYNC_DATA = 2'b10, + SYNC_CTRL = 2'b01; + +localparam [7:0] + BLOCK_TYPE_CTRL = 8'h1e, // C7 C6 C5 C4 C3 C2 C1 C0 BT + BLOCK_TYPE_OS_4 = 8'h2d, // D7 D6 D5 O4 C3 C2 C1 C0 BT + BLOCK_TYPE_START_4 = 8'h33, // D7 D6 D5 C3 C2 C1 C0 BT + BLOCK_TYPE_OS_START = 8'h66, // D7 D6 D5 O0 D3 D2 D1 BT + BLOCK_TYPE_OS_04 = 8'h55, // D7 D6 D5 O4 O0 D3 D2 D1 BT + BLOCK_TYPE_START_0 = 8'h78, // D7 D6 D5 D4 D3 D2 D1 BT + BLOCK_TYPE_OS_0 = 8'h4b, // C7 C6 C5 C4 O0 D3 D2 D1 BT + BLOCK_TYPE_TERM_0 = 8'h87, // C7 C6 C5 C4 C3 C2 C1 BT + BLOCK_TYPE_TERM_1 = 8'h99, // C7 C6 C5 C4 C3 C2 D0 BT + BLOCK_TYPE_TERM_2 = 8'haa, // C7 C6 C5 C4 C3 D1 D0 BT + BLOCK_TYPE_TERM_3 = 8'hb4, // C7 C6 C5 C4 D2 D1 D0 BT + BLOCK_TYPE_TERM_4 = 8'hcc, // C7 C6 C5 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_5 = 8'hd2, // C7 C6 D4 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_6 = 8'he1, // C7 D5 D4 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_7 = 8'hff; // D6 D5 D4 D3 D2 D1 D0 BT + +reg [DATA_WIDTH-1:0] decoded_ctrl; +reg [CTRL_WIDTH-1:0] decode_err; + +reg [DATA_WIDTH-1:0] xgmii_rxd_reg = {DATA_WIDTH{1'b0}}, xgmii_rxd_next; +reg [CTRL_WIDTH-1:0] xgmii_rxc_reg = {CTRL_WIDTH{1'b0}}, xgmii_rxc_next; + +reg rx_bad_block_reg = 1'b0, rx_bad_block_next; + +assign xgmii_rxd = xgmii_rxd_reg; +assign xgmii_rxc = xgmii_rxc_reg; + +assign rx_bad_block = rx_bad_block_reg; + +integer i; + +always @* begin + xgmii_rxd_next = {8{XGMII_ERROR}}; + xgmii_rxc_next = 8'hff; + rx_bad_block_next = 1'b0; + + for (i = 0; i < CTRL_WIDTH; i = i + 1) begin + case (encoded_rx_data[7*i+8 +: 7]) + CTRL_IDLE: begin + decoded_ctrl[8*i +: 8] = XGMII_IDLE; + decode_err[i] = 1'b0; + end + CTRL_ERROR: begin + decoded_ctrl[8*i +: 8] = XGMII_ERROR; + decode_err[i] = 1'b0; + end + CTRL_RES_0: begin + decoded_ctrl[8*i +: 8] = XGMII_RES_0; + decode_err[i] = 1'b0; + end + CTRL_RES_1: begin + decoded_ctrl[8*i +: 8] = XGMII_RES_1; + decode_err[i] = 1'b0; + end + CTRL_RES_2: begin + decoded_ctrl[8*i +: 8] = XGMII_RES_2; + decode_err[i] = 1'b0; + end + CTRL_RES_3: begin + decoded_ctrl[8*i +: 8] = XGMII_RES_3; + decode_err[i] = 1'b0; + end + CTRL_RES_4: begin + decoded_ctrl[8*i +: 8] = XGMII_RES_4; + decode_err[i] = 1'b0; + end + CTRL_RES_5: begin + decoded_ctrl[8*i +: 8] = XGMII_RES_5; + decode_err[i] = 1'b0; + end + default: begin + decoded_ctrl[8*i +: 8] = XGMII_ERROR; + decode_err[i] = 1'b1; + end + endcase + end + + if (encoded_rx_hdr == SYNC_DATA) begin + xgmii_rxd_next = encoded_rx_data; + xgmii_rxc_next = 8'h00; + end else if (encoded_rx_hdr == SYNC_CTRL) begin + case (encoded_rx_data[7:0]) + BLOCK_TYPE_CTRL: begin + // C7 C6 C5 C4 C3 C2 C1 C0 BT + xgmii_rxd_next = decoded_ctrl; + xgmii_rxc_next = 8'hff; + end + BLOCK_TYPE_OS_4: begin + // D7 D6 D5 O4 C3 C2 C1 C0 BT + xgmii_rxd_next[31:0] = decoded_ctrl[31:0]; + xgmii_rxc_next[3:0] = 4'hf; + if (encoded_rx_data[39:36] == O_SEQ_OS) begin + xgmii_rxd_next[63:32] = {encoded_rx_data[63:40], XGMII_SEQ_OS}; + xgmii_rxc_next[7:4] = 4'h1; + end else begin + xgmii_rxd_next[63:32] = {4{XGMII_ERROR}}; + xgmii_rxc_next[7:4] = 4'hf; + end + end + BLOCK_TYPE_START_4: begin + // D7 D6 D5 C3 C2 C1 C0 BT + xgmii_rxd_next = {encoded_rx_data[63:40], XGMII_START, decoded_ctrl[31:0]}; + xgmii_rxc_next = 8'h1f; + end + BLOCK_TYPE_OS_START: begin + // D7 D6 D5 O0 D3 D2 D1 BT + if (encoded_rx_data[35:32] == O_SEQ_OS) begin + xgmii_rxd_next[31:0] = {encoded_rx_data[31:8], XGMII_SEQ_OS}; + xgmii_rxc_next[3:0] = 4'h1; + end else begin + xgmii_rxd_next[31:0] = {4{XGMII_ERROR}}; + xgmii_rxc_next[3:0] = 4'hf; + end + xgmii_rxd_next[63:32] = {encoded_rx_data[63:40], XGMII_START}; + xgmii_rxc_next[7:4] = 4'h1; + end + BLOCK_TYPE_OS_04: begin + // D7 D6 D5 O4 O0 D3 D2 D1 BT + if (encoded_rx_data[35:32] == O_SEQ_OS) begin + xgmii_rxd_next[31:0] = {encoded_rx_data[31:8], XGMII_SEQ_OS}; + xgmii_rxc_next[3:0] = 4'h1; + end else begin + xgmii_rxd_next[31:0] = {4{XGMII_ERROR}}; + xgmii_rxc_next[3:0] = 4'hf; + end + if (encoded_rx_data[39:36] == O_SEQ_OS) begin + xgmii_rxd_next[63:32] = {encoded_rx_data[63:40], XGMII_SEQ_OS}; + xgmii_rxc_next[7:4] = 4'h1; + end else begin + xgmii_rxd_next[63:32] = {4{XGMII_ERROR}}; + xgmii_rxc_next[7:4] = 4'hf; + end + end + BLOCK_TYPE_START_0: begin + // D7 D6 D5 D4 D3 D2 D1 BT + xgmii_rxd_next = {encoded_rx_data[63:8], XGMII_START}; + xgmii_rxc_next = 8'h01; + end + BLOCK_TYPE_OS_0: begin + // C7 C6 C5 C4 O0 D3 D2 D1 BT + if (encoded_rx_data[35:32] == O_SEQ_OS) begin + xgmii_rxd_next[31:0] = {encoded_rx_data[31:8], XGMII_SEQ_OS}; + xgmii_rxc_next[3:0] = 4'h1; + end else begin + xgmii_rxd_next[31:0] = {4{XGMII_ERROR}}; + xgmii_rxc_next[3:0] = 4'hf; + end + xgmii_rxd_next[63:32] = decoded_ctrl[63:32]; + xgmii_rxc_next[7:4] = 4'hf; + end + BLOCK_TYPE_TERM_0: begin + // C7 C6 C5 C4 C3 C2 C1 BT + xgmii_rxd_next = {decoded_ctrl[63:8], XGMII_TERM}; + xgmii_rxc_next = 8'hff; + end + BLOCK_TYPE_TERM_1: begin + // C7 C6 C5 C4 C3 C2 D0 BT + xgmii_rxd_next = {decoded_ctrl[63:16], XGMII_TERM, encoded_rx_data[15:8]}; + xgmii_rxc_next = 8'hfe; + end + BLOCK_TYPE_TERM_2: begin + // C7 C6 C5 C4 C3 D1 D0 BT + xgmii_rxd_next = {decoded_ctrl[63:24], XGMII_TERM, encoded_rx_data[23:8]}; + xgmii_rxc_next = 8'hfc; + end + BLOCK_TYPE_TERM_3: begin + // C7 C6 C5 C4 D2 D1 D0 BT + xgmii_rxd_next = {decoded_ctrl[63:32], XGMII_TERM, encoded_rx_data[31:8]}; + xgmii_rxc_next = 8'hf8; + end + BLOCK_TYPE_TERM_4: begin + // C7 C6 C5 D3 D2 D1 D0 BT + xgmii_rxd_next = {decoded_ctrl[63:40], XGMII_TERM, encoded_rx_data[39:8]}; + xgmii_rxc_next = 8'hf0; + end + BLOCK_TYPE_TERM_5: begin + // C7 C6 D4 D3 D2 D1 D0 BT + xgmii_rxd_next = {decoded_ctrl[63:48], XGMII_TERM, encoded_rx_data[47:8]}; + xgmii_rxc_next = 8'he0; + end + BLOCK_TYPE_TERM_6: begin + // C7 D5 D4 D3 D2 D1 D0 BT + xgmii_rxd_next = {decoded_ctrl[63:56], XGMII_TERM, encoded_rx_data[55:8]}; + xgmii_rxc_next = 8'hc0; + end + BLOCK_TYPE_TERM_7: begin + // D6 D5 D4 D3 D2 D1 D0 BT + xgmii_rxd_next = {XGMII_TERM, encoded_rx_data[63:8]}; + xgmii_rxc_next = 8'h80; + end + default: begin + // invalid block type + xgmii_rxd_next = {8{XGMII_ERROR}}; + xgmii_rxc_next = 8'hff; + rx_bad_block_next = 1'b1; + end + endcase + end else begin + // invalid header + xgmii_rxd_next = {8{XGMII_ERROR}}; + xgmii_rxc_next = 8'hff; + rx_bad_block_next = 1'b1; + end +end + +always @(posedge clk) begin + xgmii_rxd_reg <= xgmii_rxd_next; + xgmii_rxc_reg <= xgmii_rxc_next; + + rx_bad_block_reg <= rx_bad_block_next; +end + +endmodule diff --git a/rtl/xgmii_baser_enc_64.v b/rtl/xgmii_baser_enc_64.v new file mode 100644 index 000000000..9cb38d7c0 --- /dev/null +++ b/rtl/xgmii_baser_enc_64.v @@ -0,0 +1,253 @@ +/* + +Copyright (c) 2018 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 + +/* + * XGMII 10GBASE-R encoder + */ +module xgmii_baser_enc_64 # +( + parameter DATA_WIDTH = 64, + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = 2 +) +( + input wire clk, + input wire rst, + + /* + * XGMII interface + */ + input wire [DATA_WIDTH-1:0] xgmii_txd, + input wire [CTRL_WIDTH-1:0] xgmii_txc, + + /* + * 10GBASE-R encoded interface + */ + output wire [DATA_WIDTH-1:0] encoded_tx_data, + output wire [HDR_WIDTH-1:0] encoded_tx_hdr +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end + + if (HDR_WIDTH != 2) begin + $error("Error: HDR_WIDTH must be 2"); + $finish; + end +end + +localparam [7:0] + XGMII_IDLE = 8'h07, + XGMII_LPI = 8'h06, + XGMII_START = 8'hfb, + XGMII_TERM = 8'hfd, + XGMII_ERROR = 8'hfe, + XGMII_SEQ_OS = 8'h9c, + XGMII_RES_0 = 8'h1c, + XGMII_RES_1 = 8'h3c, + XGMII_RES_2 = 8'h7c, + XGMII_RES_3 = 8'hbc, + XGMII_RES_4 = 8'hdc, + XGMII_RES_5 = 8'hf7, + XGMII_SIG_OS = 8'h5c; + +localparam [6:0] + CTRL_IDLE = 7'h00, + CTRL_LPI = 7'h06, + CTRL_ERROR = 7'h1e, + CTRL_RES_0 = 7'h2d, + CTRL_RES_1 = 7'h33, + CTRL_RES_2 = 7'h4b, + CTRL_RES_3 = 7'h55, + CTRL_RES_4 = 7'h66, + CTRL_RES_5 = 7'h78; + +localparam [3:0] + O_SEQ_OS = 4'h0, + O_SIG_OS = 4'hf; + +localparam [1:0] + SYNC_DATA = 2'b10, + SYNC_CTRL = 2'b01; + +localparam [7:0] + BLOCK_TYPE_CTRL = 8'h1e, // C7 C6 C5 C4 C3 C2 C1 C0 BT + BLOCK_TYPE_OS_4 = 8'h2d, // D7 D6 D5 O4 C3 C2 C1 C0 BT + BLOCK_TYPE_START_4 = 8'h33, // D7 D6 D5 C3 C2 C1 C0 BT + BLOCK_TYPE_OS_START = 8'h66, // D7 D6 D5 O0 D3 D2 D1 BT + BLOCK_TYPE_OS_04 = 8'h55, // D7 D6 D5 O4 O0 D3 D2 D1 BT + BLOCK_TYPE_START_0 = 8'h78, // D7 D6 D5 D4 D3 D2 D1 BT + BLOCK_TYPE_OS_0 = 8'h4b, // C7 C6 C5 C4 O0 D3 D2 D1 BT + BLOCK_TYPE_TERM_0 = 8'h87, // C7 C6 C5 C4 C3 C2 C1 BT + BLOCK_TYPE_TERM_1 = 8'h99, // C7 C6 C5 C4 C3 C2 D0 BT + BLOCK_TYPE_TERM_2 = 8'haa, // C7 C6 C5 C4 C3 D1 D0 BT + BLOCK_TYPE_TERM_3 = 8'hb4, // C7 C6 C5 C4 D2 D1 D0 BT + BLOCK_TYPE_TERM_4 = 8'hcc, // C7 C6 C5 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_5 = 8'hd2, // C7 C6 D4 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_6 = 8'he1, // C7 D5 D4 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_7 = 8'hff; // D6 D5 D4 D3 D2 D1 D0 BT + +reg [DATA_WIDTH*7/8-1:0] encoded_ctrl; +reg [CTRL_WIDTH-1:0] encode_err; + +reg [DATA_WIDTH-1:0] encoded_tx_data_reg = {DATA_WIDTH{1'b0}}, encoded_tx_data_next; +reg [HDR_WIDTH-1:0] encoded_tx_hdr_reg = {HDR_WIDTH{1'b0}}, encoded_tx_hdr_next; + +assign encoded_tx_data = encoded_tx_data_reg; +assign encoded_tx_hdr = encoded_tx_hdr_reg; + +integer i; + +always @* begin + + + for (i = 0; i < CTRL_WIDTH; i = i + 1) begin + if (xgmii_txc[i]) begin + // control + case (xgmii_txd[8*i +: 8]) + XGMII_IDLE: begin + encoded_ctrl[7*i +: 7] = CTRL_IDLE; + encode_err[i] = 1'b0; + end + XGMII_ERROR: begin + encoded_ctrl[7*i +: 7] = CTRL_ERROR; + encode_err[i] = 1'b0; + end + XGMII_RES_0: begin + encoded_ctrl[7*i +: 7] = CTRL_RES_0; + encode_err[i] = 1'b0; + end + XGMII_RES_1: begin + encoded_ctrl[7*i +: 7] = CTRL_RES_1; + encode_err[i] = 1'b0; + end + XGMII_RES_2: begin + encoded_ctrl[7*i +: 7] = CTRL_RES_2; + encode_err[i] = 1'b0; + end + XGMII_RES_3: begin + encoded_ctrl[7*i +: 7] = CTRL_RES_3; + encode_err[i] = 1'b0; + end + XGMII_RES_4: begin + encoded_ctrl[7*i +: 7] = CTRL_RES_4; + encode_err[i] = 1'b0; + end + XGMII_RES_5: begin + encoded_ctrl[7*i +: 7] = CTRL_RES_5; + encode_err[i] = 1'b0; + end + default: begin + encoded_ctrl[7*i +: 7] = CTRL_ERROR; + encode_err[i] = 1'b1; + end + endcase + end else begin + // data (always invalid as control) + encoded_ctrl[7*i +: 7] = CTRL_ERROR; + encode_err[i] = 1'b1; + end + end + + if (xgmii_txc == 8'h00) begin + encoded_tx_data_next = xgmii_txd; + encoded_tx_hdr_next = SYNC_DATA; + end else begin + if (xgmii_txc[0] && xgmii_txd[7:0] == XGMII_START && !xgmii_txc[7:1]) begin + // start in lane 0 + encoded_tx_data_next = {xgmii_txd[63:8], BLOCK_TYPE_START_0}; + end else if (xgmii_txc[4] && xgmii_txd[39:32] == XGMII_START && !xgmii_txc[7:5]) begin + // start in lane 4 + if (xgmii_txc[0] && xgmii_txd[7:0] == XGMII_SEQ_OS && !xgmii_txc[3:1]) begin + // ordered set in lane 0 + encoded_tx_data_next[35:0] = {O_SEQ_OS, xgmii_txd[31:8], BLOCK_TYPE_START_4}; + end else begin + encoded_tx_data_next[35:0] = {encoded_ctrl[27:0], BLOCK_TYPE_START_4}; + end + encoded_tx_data_next[63:36] = {xgmii_txd[63:40], 4'd0}; + end else if (xgmii_txc[0] && xgmii_txd[7:0] == XGMII_SEQ_OS && !xgmii_txc[3:1]) begin + // ordered set in lane 0 + encoded_tx_data_next[35:8] = {O_SEQ_OS, xgmii_txd[31:8]}; + if (xgmii_txc[4] && xgmii_txd[39:32] == XGMII_SEQ_OS && !xgmii_txc[7:5]) begin + // ordered set in lane 4 + encoded_tx_data_next[63:36] = {xgmii_txd[63:40], O_SEQ_OS}; + encoded_tx_data_next[7:0] = BLOCK_TYPE_OS_04; + end else begin + encoded_tx_data_next[63:36] = encoded_ctrl[55:28]; + encoded_tx_data_next[7:0] = BLOCK_TYPE_OS_0; + end + end else if (xgmii_txc[4] && xgmii_txd[39:32] == XGMII_SEQ_OS && !xgmii_txc[7:5]) begin + // ordered set in lane 4 + encoded_tx_data_next = {xgmii_txd[63:40], O_SEQ_OS, 4'd0, encoded_ctrl[27:0], BLOCK_TYPE_OS_4}; + end else if (xgmii_txc[0] && xgmii_txd[7:0] == XGMII_TERM) begin + // terminate in lane 0 + encoded_tx_data_next = {encoded_ctrl[55:7], 7'd0, BLOCK_TYPE_TERM_0}; + end else if (xgmii_txc[1] && xgmii_txd[15:8] == XGMII_TERM && !xgmii_txc[0]) begin + // terminate in lane 1 + encoded_tx_data_next = {encoded_ctrl[55:14], 6'd0, xgmii_txd[7:0], BLOCK_TYPE_TERM_1}; + end else if (xgmii_txc[2] && xgmii_txd[23:16] == XGMII_TERM && !xgmii_txc[1:0]) begin + // terminate in lane 2 + encoded_tx_data_next = {encoded_ctrl[55:21], 5'd0, xgmii_txd[15:0], BLOCK_TYPE_TERM_2}; + end else if (xgmii_txc[3] && xgmii_txd[31:24] == XGMII_TERM && !xgmii_txc[2:0]) begin + // terminate in lane 3 + encoded_tx_data_next = {encoded_ctrl[55:28], 4'd0, xgmii_txd[23:0], BLOCK_TYPE_TERM_3}; + end else if (xgmii_txc[4] && xgmii_txd[39:32] == XGMII_TERM && !xgmii_txc[3:0]) begin + // terminate in lane 4 + encoded_tx_data_next = {encoded_ctrl[55:35], 3'd0, xgmii_txd[31:0], BLOCK_TYPE_TERM_4}; + end else if (xgmii_txc[5] && xgmii_txd[47:40] == XGMII_TERM && !xgmii_txc[4:0]) begin + // terminate in lane 5 + encoded_tx_data_next = {encoded_ctrl[55:42], 2'd0, xgmii_txd[39:0], BLOCK_TYPE_TERM_5}; + end else if (xgmii_txc[6] && xgmii_txd[55:48] == XGMII_TERM && !xgmii_txc[5:0]) begin + // terminate in lane 6 + encoded_tx_data_next = {encoded_ctrl[55:49], 1'd0, xgmii_txd[47:0], BLOCK_TYPE_TERM_6}; + end else if (xgmii_txc[7] && xgmii_txd[63:56] == XGMII_TERM && !xgmii_txc[6:0]) begin + // terminate in lane 7 + encoded_tx_data_next = {xgmii_txd[55:0], BLOCK_TYPE_TERM_7}; + end else begin + // all control + encoded_tx_data_next = {encoded_ctrl, BLOCK_TYPE_CTRL}; + end + encoded_tx_hdr_next = SYNC_CTRL; + end +end + +always @(posedge clk) begin + encoded_tx_data_reg <= encoded_tx_data_next; + encoded_tx_hdr_reg <= encoded_tx_hdr_next; +end + +endmodule diff --git a/tb/test_xgmii_baser_dec_64.py b/tb/test_xgmii_baser_dec_64.py new file mode 100755 index 000000000..bf6a43e94 --- /dev/null +++ b/tb/test_xgmii_baser_dec_64.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2018 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 + +import axis_ep +import eth_ep +import xgmii_ep +import baser_serdes_ep + +module = 'xgmii_baser_dec_64' +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 bench(): + + # Parameters + DATA_WIDTH = 64 + CTRL_WIDTH = (DATA_WIDTH/8) + HDR_WIDTH = 2 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + encoded_rx_data = Signal(intbv(0)[DATA_WIDTH:]) + encoded_rx_hdr = Signal(intbv(0)[HDR_WIDTH:]) + + # Outputs + xgmii_rxd = Signal(intbv(0)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0)[CTRL_WIDTH:]) + rx_bad_block = Signal(bool(0)) + + # sources and sinks + source = baser_serdes_ep.BaseRSerdesSource() + + source_logic = source.create_logic( + clk, + tx_data=encoded_rx_data, + tx_header=encoded_rx_hdr, + scramble=False, + name='source' + ) + + sink = xgmii_ep.XGMIISink() + + sink_logic = sink.create_logic( + clk, + rst, + rxd=xgmii_rxd, + rxc=xgmii_rxc, + 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, + xgmii_rxd=xgmii_rxd, + xgmii_rxc=xgmii_rxc, + encoded_rx_data=encoded_rx_data, + encoded_rx_hdr=encoded_rx_hdr, + rx_bad_block=rx_bad_block + ) + + @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 + + # testbench stimulus + + for payload_len in list(range(16,34)): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = bytearray(range(payload_len)) + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame) + + source.send(xgmii_frame) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame.data + + 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 = bytearray(range(payload_len)) + test_frame2 = bytearray(range(payload_len)) + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame1) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame2) + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame1.data + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame2.data + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: errored frame, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = bytearray(range(payload_len)) + test_frame2 = bytearray(range(payload_len)) + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame1) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame2) + + xgmii_frame1.error = 1 + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + #assert rx_frame.data == xgmii_frame1.data + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame2.data + + 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() diff --git a/tb/test_xgmii_baser_dec_64.v b/tb/test_xgmii_baser_dec_64.v new file mode 100644 index 000000000..1ce426e12 --- /dev/null +++ b/tb/test_xgmii_baser_dec_64.v @@ -0,0 +1,87 @@ +/* + +Copyright (c) 2018 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 + +/* + * Testbench for xgmii_baser_dec_64 + */ +module test_xgmii_baser_dec_64; + +// Parameters +parameter DATA_WIDTH = 64; +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter HDR_WIDTH = 2; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] encoded_rx_data = 0; +reg [HDR_WIDTH-1:0] encoded_rx_hdr = 0; + +// Outputs +wire [DATA_WIDTH-1:0] xgmii_rxd; +wire [CTRL_WIDTH-1:0] xgmii_rxc; +wire rx_bad_block; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + encoded_rx_data, + encoded_rx_hdr + ); + $to_myhdl( + xgmii_rxd, + xgmii_rxc, + rx_bad_block + ); + + // dump file + $dumpfile("test_xgmii_baser_dec_64.lxt"); + $dumpvars(0, test_xgmii_baser_dec_64); +end + +xgmii_baser_dec_64 #( + .DATA_WIDTH(DATA_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + .encoded_rx_data(encoded_rx_data), + .encoded_rx_hdr(encoded_rx_hdr), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .rx_bad_block(rx_bad_block) +); + +endmodule diff --git a/tb/test_xgmii_baser_enc_64.py b/tb/test_xgmii_baser_enc_64.py new file mode 100755 index 000000000..a6c72c17d --- /dev/null +++ b/tb/test_xgmii_baser_enc_64.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2018 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 + +import axis_ep +import eth_ep +import xgmii_ep +import baser_serdes_ep + +module = 'xgmii_baser_enc_64' +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 bench(): + + # Parameters + DATA_WIDTH = 64 + CTRL_WIDTH = (DATA_WIDTH/8) + HDR_WIDTH = 2 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + xgmii_txd = Signal(intbv(0)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0)[CTRL_WIDTH:]) + + # Outputs + encoded_tx_data = Signal(intbv(0)[DATA_WIDTH:]) + encoded_tx_hdr = Signal(intbv(0)[HDR_WIDTH:]) + + # sources and sinks + source = xgmii_ep.XGMIISource() + + source_logic = source.create_logic( + clk, + rst, + txd=xgmii_txd, + txc=xgmii_txc, + name='source' + ) + + sink = baser_serdes_ep.BaseRSerdesSink() + + sink_logic = sink.create_logic( + clk, + rx_data=encoded_tx_data, + rx_header=encoded_tx_hdr, + scramble=False, + 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, + xgmii_txd=xgmii_txd, + xgmii_txc=xgmii_txc, + encoded_tx_data=encoded_tx_data, + encoded_tx_hdr=encoded_tx_hdr + ) + + @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 + + # testbench stimulus + + for payload_len in list(range(16,34)): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = bytearray(range(payload_len)) + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame) + + source.send(xgmii_frame) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame.data + + 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 = bytearray(range(payload_len)) + test_frame2 = bytearray(range(payload_len)) + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame1) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame2) + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame1.data + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame2.data + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: errored frame, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = bytearray(range(payload_len)) + test_frame2 = bytearray(range(payload_len)) + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame1) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame2) + + xgmii_frame1.error = 1 + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + #assert rx_frame.data == xgmii_frame1.data + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame2.data + + 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() diff --git a/tb/test_xgmii_baser_enc_64.v b/tb/test_xgmii_baser_enc_64.v new file mode 100644 index 000000000..dff67b5b1 --- /dev/null +++ b/tb/test_xgmii_baser_enc_64.v @@ -0,0 +1,84 @@ +/* + +Copyright (c) 2018 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 + +/* + * Testbench for xgmii_baser_enc_64 + */ +module test_xgmii_baser_enc_64; + +// Parameters +parameter DATA_WIDTH = 64; +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter HDR_WIDTH = 2; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] xgmii_txd = 0; +reg [CTRL_WIDTH-1:0] xgmii_txc = 0; + +// Outputs +wire [DATA_WIDTH-1:0] encoded_tx_data; +wire [HDR_WIDTH-1:0] encoded_tx_hdr; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + xgmii_txd, + xgmii_txc + ); + $to_myhdl( + encoded_tx_data, + encoded_tx_hdr + ); + + // dump file + $dumpfile("test_xgmii_baser_enc_64.lxt"); + $dumpvars(0, test_xgmii_baser_enc_64); +end + +xgmii_baser_enc_64 #( + .DATA_WIDTH(DATA_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .encoded_tx_data(encoded_tx_data), + .encoded_tx_hdr(encoded_tx_hdr) +); + +endmodule From dbbbc28059a19a052e659bccb00e6b076c5c8cfb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 16 Jan 2019 18:00:56 -0800 Subject: [PATCH 505/617] Add 10G Ethernet PHY modules and testbenches --- rtl/eth_phy_10g.v | 109 +++++++++++++ rtl/eth_phy_10g_rx.v | 173 ++++++++++++++++++++ rtl/eth_phy_10g_rx_ber_mon.v | 120 ++++++++++++++ rtl/eth_phy_10g_rx_frame_sync.v | 133 ++++++++++++++++ rtl/eth_phy_10g_tx.v | 139 +++++++++++++++++ tb/test_eth_phy_10g_64.py | 254 ++++++++++++++++++++++++++++++ tb/test_eth_phy_10g_64.v | 121 ++++++++++++++ tb/test_eth_phy_10g_rx_64.py | 269 ++++++++++++++++++++++++++++++++ tb/test_eth_phy_10g_rx_64.v | 99 ++++++++++++ tb/test_eth_phy_10g_tx_64.py | 207 ++++++++++++++++++++++++ tb/test_eth_phy_10g_tx_64.v | 88 +++++++++++ 11 files changed, 1712 insertions(+) create mode 100644 rtl/eth_phy_10g.v create mode 100644 rtl/eth_phy_10g_rx.v create mode 100644 rtl/eth_phy_10g_rx_ber_mon.v create mode 100644 rtl/eth_phy_10g_rx_frame_sync.v create mode 100644 rtl/eth_phy_10g_tx.v create mode 100755 tb/test_eth_phy_10g_64.py create mode 100644 tb/test_eth_phy_10g_64.v create mode 100755 tb/test_eth_phy_10g_rx_64.py create mode 100644 tb/test_eth_phy_10g_rx_64.v create mode 100755 tb/test_eth_phy_10g_tx_64.py create mode 100644 tb/test_eth_phy_10g_tx_64.v diff --git a/rtl/eth_phy_10g.v b/rtl/eth_phy_10g.v new file mode 100644 index 000000000..4d4e21751 --- /dev/null +++ b/rtl/eth_phy_10g.v @@ -0,0 +1,109 @@ +/* + +Copyright (c) 2018 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 + +/* + * 10G Ethernet PHY + */ +module eth_phy_10g # +( + parameter DATA_WIDTH = 64, + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = 2, + parameter BIT_REVERSE = 0, + parameter SCRAMBLER_DISABLE = 0, + parameter SLIP_COUNT_WIDTH = 3, + parameter COUNT_125US = 125000/6.4 +) +( + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, + + /* + * XGMII interface + */ + input wire [DATA_WIDTH-1:0] xgmii_txd, + input wire [CTRL_WIDTH-1:0] xgmii_txc, + output wire [DATA_WIDTH-1:0] xgmii_rxd, + output wire [CTRL_WIDTH-1:0] xgmii_rxc, + + /* + * SERDES interface + */ + output wire [DATA_WIDTH-1:0] serdes_tx_data, + output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + input wire [DATA_WIDTH-1:0] serdes_rx_data, + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * Status + */ + output wire rx_block_lock, + output wire rx_high_ber +); + +eth_phy_10g_rx #( + .DATA_WIDTH(DATA_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), + .COUNT_125US(COUNT_125US) +) +eth_phy_10g_rx_inst ( + .clk(rx_clk), + .rst(rx_rst), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber) +); + +eth_phy_10g_tx #( + .DATA_WIDTH(DATA_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE) +) +eth_phy_10g_tx_inst ( + .clk(tx_clk), + .rst(tx_rst), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .serdes_tx_data(serdes_tx_data), + .serdes_tx_hdr(serdes_tx_hdr) +); + +endmodule diff --git a/rtl/eth_phy_10g_rx.v b/rtl/eth_phy_10g_rx.v new file mode 100644 index 000000000..0348d0d1c --- /dev/null +++ b/rtl/eth_phy_10g_rx.v @@ -0,0 +1,173 @@ +/* + +Copyright (c) 2018 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 + +/* + * 10G Ethernet PHY + */ +module eth_phy_10g_rx # +( + parameter DATA_WIDTH = 64, + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = 2, + parameter BIT_REVERSE = 0, + parameter SCRAMBLER_DISABLE = 0, + parameter SLIP_COUNT_WIDTH = 3, + parameter COUNT_125US = 125000/6.4 +) +( + input wire clk, + input wire rst, + + /* + * XGMII interface + */ + output wire [DATA_WIDTH-1:0] xgmii_rxd, + output wire [CTRL_WIDTH-1:0] xgmii_rxc, + + /* + * SERDES interface + */ + input wire [DATA_WIDTH-1:0] serdes_rx_data, + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * Status + */ + output wire rx_block_lock, + output wire rx_high_ber +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end + + if (HDR_WIDTH != 2) begin + $error("Error: HDR_WIDTH must be 2"); + $finish; + end +end + +wire [DATA_WIDTH-1:0] serdes_rx_data_int; +wire [HDR_WIDTH-1:0] serdes_rx_hdr_int; + +generate + genvar n; + + if (BIT_REVERSE) begin + for (n = 0; n < DATA_WIDTH; n = n + 1) begin + assign serdes_rx_data_int[n] = serdes_rx_data[DATA_WIDTH-n-1]; + end + + for (n = 0; n < HDR_WIDTH; n = n + 1) begin + assign serdes_rx_hdr_int[n] = serdes_rx_hdr[HDR_WIDTH-n-1]; + end + end else begin + assign serdes_rx_data_int = serdes_rx_data; + assign serdes_rx_hdr_int = serdes_rx_hdr; + end +endgenerate + +wire [DATA_WIDTH-1:0] descrambled_rx_data; + +reg [DATA_WIDTH-1:0] encoded_rx_data_reg = {DATA_WIDTH{1'b0}}; +reg [HDR_WIDTH-1:0] encoded_rx_hdr_reg = {HDR_WIDTH{1'b0}}; + +reg [57:0] scrambler_state_reg = {58{1'b1}}; +wire [57:0] scrambler_state; + +lfsr #( + .LFSR_WIDTH(58), + .LFSR_POLY(58'h8000000001), + .LFSR_CONFIG("FIBONACCI"), + .LFSR_FEED_FORWARD(1), + .REVERSE(1), + .DATA_WIDTH(DATA_WIDTH), + .STYLE("AUTO") +) +descrambler_inst ( + .data_in(serdes_rx_data_int), + .state_in(scrambler_state_reg), + .data_out(descrambled_rx_data), + .state_out(scrambler_state) +); + +always @(posedge clk) begin + scrambler_state_reg <= scrambler_state; + + encoded_rx_data_reg <= descrambled_rx_data; + encoded_rx_hdr_reg <= serdes_rx_hdr_int; +end + +xgmii_baser_dec_64 #( + .DATA_WIDTH(DATA_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH) +) +xgmii_baser_dec_inst ( + .clk(clk), + .rst(rst), + .encoded_rx_data(SCRAMBLER_DISABLE ? serdes_rx_data_int : encoded_rx_data_reg), + .encoded_rx_hdr(SCRAMBLER_DISABLE ? serdes_rx_hdr_int : encoded_rx_hdr_reg), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .rx_bad_block() +); + +eth_phy_10g_rx_frame_sync #( + .HDR_WIDTH(HDR_WIDTH), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH) +) +eth_phy_10g_rx_frame_sync_inst ( + .clk(clk), + .rst(rst), + .serdes_rx_hdr(serdes_rx_hdr_int), + .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_block_lock(rx_block_lock) +); + +eth_phy_10g_rx_ber_mon #( + .HDR_WIDTH(HDR_WIDTH), + .COUNT_125US(COUNT_125US) +) +eth_phy_10g_rx_ber_mon_inst ( + .clk(clk), + .rst(rst), + .serdes_rx_hdr(serdes_rx_hdr_int), + .rx_high_ber(rx_high_ber) +); + +endmodule diff --git a/rtl/eth_phy_10g_rx_ber_mon.v b/rtl/eth_phy_10g_rx_ber_mon.v new file mode 100644 index 000000000..a1b5d0b37 --- /dev/null +++ b/rtl/eth_phy_10g_rx_ber_mon.v @@ -0,0 +1,120 @@ +/* + +Copyright (c) 2018 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 + +/* + * 10G Ethernet PHY BER monitor + */ +module eth_phy_10g_rx_ber_mon # +( + parameter HDR_WIDTH = 2, + parameter COUNT_125US = 125000/6.4 +) +( + input wire clk, + input wire rst, + + /* + * SERDES interface + */ + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + + /* + * Status + */ + output wire rx_high_ber +); + +// bus width assertions +initial begin + if (HDR_WIDTH != 2) begin + $error("Error: HDR_WIDTH must be 2"); + $finish; + end +end + +parameter COUNT_WIDTH = $clog2(COUNT_125US); + +localparam [1:0] + SYNC_DATA = 2'b10, + SYNC_CTRL = 2'b01; + +reg [COUNT_WIDTH-1:0] time_count_reg = 0, time_count_next; +reg [3:0] ber_count_reg = 4'd0, ber_count_next; + +reg rx_high_ber_reg = 1'b0, rx_high_ber_next; + +assign rx_high_ber = rx_high_ber_reg; + +always @* begin + if (time_count_reg > 0) begin + time_count_next = time_count_reg-1; + end else begin + time_count_next = time_count_reg; + end + ber_count_next = ber_count_reg; + + rx_high_ber_next = rx_high_ber_reg; + + if (serdes_rx_hdr == SYNC_CTRL || serdes_rx_hdr == SYNC_DATA) begin + // valid header + if (ber_count_reg != 4'd15) begin + if (time_count_reg == 0) begin + rx_high_ber_next = 1'b0; + end + end + end else begin + // invalid header + if (ber_count_reg == 4'd15) begin + rx_high_ber_next = 1'b1; + end else begin + ber_count_next = ber_count_reg + 1; + if (time_count_reg == 0) begin + rx_high_ber_next = 1'b0; + end + end + end + if (time_count_reg == 0) begin + // 125 us timer expired + ber_count_next = 4'd0; + time_count_next = COUNT_125US; + end +end + +always @(posedge clk) begin + if (rst) begin + time_count_reg <= COUNT_125US; + ber_count_reg <= 4'd0; + rx_high_ber_reg <= 1'b0; + end else begin + time_count_reg <= time_count_next; + ber_count_reg <= ber_count_next; + rx_high_ber_reg <= rx_high_ber_next; + end +end + +endmodule diff --git a/rtl/eth_phy_10g_rx_frame_sync.v b/rtl/eth_phy_10g_rx_frame_sync.v new file mode 100644 index 000000000..14fdf72b5 --- /dev/null +++ b/rtl/eth_phy_10g_rx_frame_sync.v @@ -0,0 +1,133 @@ +/* + +Copyright (c) 2018 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 + +/* + * 10G Ethernet PHY frame sync + */ +module eth_phy_10g_rx_frame_sync # +( + parameter HDR_WIDTH = 2, + parameter SLIP_COUNT_WIDTH = 3 +) +( + input wire clk, + input wire rst, + + /* + * SERDES interface + */ + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * Status + */ + output wire rx_block_lock +); + +// bus width assertions +initial begin + if (HDR_WIDTH != 2) begin + $error("Error: HDR_WIDTH must be 2"); + $finish; + end +end + +localparam [1:0] + SYNC_DATA = 2'b10, + SYNC_CTRL = 2'b01; + +reg [5:0] sh_count_reg = 6'd0, sh_count_next; +reg [3:0] sh_invalid_count_reg = 4'd0, sh_invalid_count_next; +reg [SLIP_COUNT_WIDTH-1:0] slip_count_reg = 0, slip_count_next; + +reg serdes_rx_bitslip_reg = 1'b0, serdes_rx_bitslip_next; + +reg rx_block_lock_reg = 1'b0, rx_block_lock_next; + +assign serdes_rx_bitslip = serdes_rx_bitslip_reg; +assign rx_block_lock = rx_block_lock_reg; + +always @* begin + sh_count_next = sh_count_reg; + sh_invalid_count_next = sh_invalid_count_reg; + slip_count_next = slip_count_reg; + + serdes_rx_bitslip_next = 1'b0; + + rx_block_lock_next = rx_block_lock_reg; + + if (slip_count_reg) begin + slip_count_next = slip_count_reg-1; + end else if (serdes_rx_hdr == SYNC_CTRL || serdes_rx_hdr == SYNC_DATA) begin + // valid header + sh_count_next = sh_count_reg + 1; + if (&sh_count_reg) begin + // valid count overflow, reset + sh_count_next = 0; + sh_invalid_count_next = 0; + if (!sh_invalid_count_reg) begin + rx_block_lock_next = 1'b1; + end + end + end else begin + // invalid header + sh_count_next = sh_count_reg + 1; + sh_invalid_count_next = sh_invalid_count_reg + 1; + if (!rx_block_lock_reg || &sh_invalid_count_reg) begin + // invalid count overflow, lost block lock + sh_count_next = 0; + sh_invalid_count_next = 0; + rx_block_lock_next = 1'b0; + serdes_rx_bitslip_next = 1'b1; + slip_count_next = {SLIP_COUNT_WIDTH{1'b1}}; + end else if (&sh_count_reg) begin + // valid count overflow, reset + sh_count_next = 0; + sh_invalid_count_next = 0; + end + end +end + +always @(posedge clk) begin + if (rst) begin + sh_count_reg <= 6'd0; + sh_invalid_count_reg <= 4'd0; + slip_count_reg <= 0; + rx_block_lock_reg <= 1'b0; + end else begin + sh_count_reg <= sh_count_next; + sh_invalid_count_reg <= sh_invalid_count_next; + slip_count_reg <= slip_count_next; + rx_block_lock_reg <= rx_block_lock_next; + end + + serdes_rx_bitslip_reg <= serdes_rx_bitslip_next; +end + +endmodule diff --git a/rtl/eth_phy_10g_tx.v b/rtl/eth_phy_10g_tx.v new file mode 100644 index 000000000..96de4a584 --- /dev/null +++ b/rtl/eth_phy_10g_tx.v @@ -0,0 +1,139 @@ +/* + +Copyright (c) 2018 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 + +/* + * 10G Ethernet PHY + */ +module eth_phy_10g_tx # +( + parameter DATA_WIDTH = 64, + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = 2, + parameter BIT_REVERSE = 0, + parameter SCRAMBLER_DISABLE = 0 +) +( + input wire clk, + input wire rst, + + /* + * XGMII interface + */ + input wire [DATA_WIDTH-1:0] xgmii_txd, + input wire [CTRL_WIDTH-1:0] xgmii_txc, + + /* + * SERDES interface + */ + output wire [DATA_WIDTH-1:0] serdes_tx_data, + output wire [HDR_WIDTH-1:0] serdes_tx_hdr +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end + + if (HDR_WIDTH != 2) begin + $error("Error: HDR_WIDTH must be 2"); + $finish; + end +end + +wire [DATA_WIDTH-1:0] encoded_tx_data; +wire [HDR_WIDTH-1:0] encoded_tx_hdr; + +xgmii_baser_enc_64 #( + .DATA_WIDTH(DATA_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH) +) +xgmii_baser_enc_inst ( + .clk(clk), + .rst(rst), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .encoded_tx_data(encoded_tx_data), + .encoded_tx_hdr(encoded_tx_hdr) +); + +reg [57:0] scrambler_state_reg = {58{1'b1}}; +wire [57:0] scrambler_state; +wire [DATA_WIDTH-1:0] scrambled_data; + +reg [DATA_WIDTH-1:0] serdes_tx_data_reg = {DATA_WIDTH{1'b0}}; +reg [HDR_WIDTH-1:0] serdes_tx_hdr_reg = {HDR_WIDTH{1'b0}}; + +generate + genvar n; + + if (BIT_REVERSE) begin + for (n = 0; n < DATA_WIDTH; n = n + 1) begin + assign serdes_tx_data[n] = serdes_tx_data_reg[DATA_WIDTH-n-1]; + end + + for (n = 0; n < HDR_WIDTH; n = n + 1) begin + assign serdes_tx_hdr[n] = serdes_tx_hdr_reg[HDR_WIDTH-n-1]; + end + end else begin + assign serdes_tx_data = serdes_tx_data_reg; + assign serdes_tx_hdr = serdes_tx_hdr_reg; + end +endgenerate + +lfsr #( + .LFSR_WIDTH(58), + .LFSR_POLY(58'h8000000001), + .LFSR_CONFIG("FIBONACCI"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(DATA_WIDTH), + .STYLE("AUTO") +) +scrambler_inst ( + .data_in(encoded_tx_data), + .state_in(scrambler_state_reg), + .data_out(scrambled_data), + .state_out(scrambler_state) +); + +always @(posedge clk) begin + scrambler_state_reg <= scrambler_state; + + serdes_tx_data_reg <= SCRAMBLER_DISABLE ? encoded_tx_data : scrambled_data; + serdes_tx_hdr_reg <= encoded_tx_hdr; +end + +endmodule diff --git a/tb/test_eth_phy_10g_64.py b/tb/test_eth_phy_10g_64.py new file mode 100755 index 000000000..e24ae570b --- /dev/null +++ b/tb/test_eth_phy_10g_64.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2018 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 + +import axis_ep +import eth_ep +import xgmii_ep +import baser_serdes_ep + +module = 'eth_phy_10g' +testbench = 'test_%s_64' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_phy_10g_rx.v") +srcs.append("../rtl/eth_phy_10g_rx_ber_mon.v") +srcs.append("../rtl/eth_phy_10g_rx_frame_sync.v") +srcs.append("../rtl/eth_phy_10g_tx.v") +srcs.append("../rtl/xgmii_baser_dec_64.v") +srcs.append("../rtl/xgmii_baser_enc_64.v") +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + DATA_WIDTH = 64 + CTRL_WIDTH = (DATA_WIDTH/8) + HDR_WIDTH = 2 + BIT_REVERSE = 0 + SCRAMBLER_DISABLE = 0 + COUNT_125US = 1250/6.4 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + xgmii_txd = Signal(intbv(0)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0)[CTRL_WIDTH:]) + serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) + serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + + serdes_rx_data_int = Signal(intbv(0)[DATA_WIDTH:]) + serdes_rx_hdr_int = Signal(intbv(1)[HDR_WIDTH:]) + + # Outputs + xgmii_rxd = Signal(intbv(0)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0)[CTRL_WIDTH:]) + serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) + serdes_tx_hdr = Signal(intbv(0)[HDR_WIDTH:]) + serdes_rx_bitslip = Signal(bool(0)) + rx_block_lock = Signal(bool(0)) + rx_high_ber = Signal(bool(0)) + + # sources and sinks + xgmii_source = xgmii_ep.XGMIISource() + + xgmii_source_logic = xgmii_source.create_logic( + tx_clk, + tx_rst, + txd=xgmii_txd, + txc=xgmii_txc, + name='xgmii_source' + ) + + xgmii_sink = xgmii_ep.XGMIISink() + + xgmii_sink_logic = xgmii_sink.create_logic( + rx_clk, + rx_rst, + rxd=xgmii_rxd, + rxc=xgmii_rxc, + name='xgmii_sink' + ) + + serdes_source = baser_serdes_ep.BaseRSerdesSource() + + serdes_source_logic = serdes_source.create_logic( + rx_clk, + tx_data=serdes_rx_data_int, + tx_header=serdes_rx_hdr_int, + name='serdes_source' + ) + + serdes_sink = baser_serdes_ep.BaseRSerdesSink() + + serdes_sink_logic = serdes_sink.create_logic( + tx_clk, + rx_data=serdes_tx_data, + rx_header=serdes_tx_hdr, + name='serdes_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, + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + xgmii_txd=xgmii_txd, + xgmii_txc=xgmii_txc, + xgmii_rxd=xgmii_rxd, + xgmii_rxc=xgmii_rxc, + serdes_tx_data=serdes_tx_data, + serdes_tx_hdr=serdes_tx_hdr, + serdes_rx_data=serdes_rx_data, + serdes_rx_hdr=serdes_rx_hdr, + serdes_rx_bitslip=serdes_rx_bitslip, + rx_block_lock=rx_block_lock, + rx_high_ber=rx_high_ber + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + rx_clk.next = not rx_clk + tx_clk.next = not tx_clk + + load_bit_offset = [] + + @instance + def shift_bits(): + bit_offset = 0 + last_data = 0 + + while True: + yield clk.posedge + + if load_bit_offset: + bit_offset = load_bit_offset.pop(0) + + if serdes_rx_bitslip: + bit_offset += 1 + + bit_offset = bit_offset % 66 + + data = int(serdes_rx_data_int) << 2 | int(serdes_rx_hdr_int) + + out_data = ((last_data | data << 66) >> 66-bit_offset) & 0x3ffffffffffffffff + + last_data = data + + serdes_rx_data.next = out_data >> 2 + serdes_rx_hdr.next = out_data & 3 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + tx_rst.next = 1 + rx_rst.next = 1 + yield clk.posedge + rst.next = 0 + tx_rst.next = 0 + rx_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test RX packet") + current_test.next = 1 + + test_frame = bytearray(range(128)) + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame) + + xgmii_source.send(xgmii_frame) + + yield serdes_sink.wait() + rx_frame = serdes_sink.recv() + + assert rx_frame.data == xgmii_frame.data + + assert xgmii_sink.empty() + assert serdes_sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test TX packet") + current_test.next = 2 + + test_frame = bytearray(range(128)) + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame) + + serdes_source.send(xgmii_frame) + + yield xgmii_sink.wait() + rx_frame = xgmii_sink.recv() + + assert rx_frame.data == xgmii_frame.data + + assert xgmii_sink.empty() + assert serdes_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() diff --git a/tb/test_eth_phy_10g_64.v b/tb/test_eth_phy_10g_64.v new file mode 100644 index 000000000..61a78d7af --- /dev/null +++ b/tb/test_eth_phy_10g_64.v @@ -0,0 +1,121 @@ +/* + +Copyright (c) 2018 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 + +/* + * Testbench for eth_phy_10g + */ +module test_eth_phy_10g_64; + +// Parameters +parameter DATA_WIDTH = 64; +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter HDR_WIDTH = 2; +parameter BIT_REVERSE = 0; +parameter SCRAMBLER_DISABLE = 0; +parameter COUNT_125US = 125000/6.4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg rx_clk = 0; +reg rx_rst = 0; +reg tx_clk = 0; +reg tx_rst = 0; +reg [DATA_WIDTH-1:0] xgmii_txd = 0; +reg [CTRL_WIDTH-1:0] xgmii_txc = 0; +reg [DATA_WIDTH-1:0] serdes_rx_data = 0; +reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; + +// Outputs +wire [DATA_WIDTH-1:0] xgmii_rxd; +wire [CTRL_WIDTH-1:0] xgmii_rxc; +wire [DATA_WIDTH-1:0] serdes_tx_data; +wire [HDR_WIDTH-1:0] serdes_tx_hdr; +wire serdes_rx_bitslip; +wire rx_block_lock; +wire rx_high_ber; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + rx_clk, + rx_rst, + tx_clk, + tx_rst, + xgmii_txd, + xgmii_txc, + serdes_rx_data, + serdes_rx_hdr + ); + $to_myhdl( + xgmii_rxd, + xgmii_rxc, + serdes_tx_data, + serdes_tx_hdr, + serdes_rx_bitslip, + rx_block_lock, + rx_high_ber + ); + + // dump file + $dumpfile("test_eth_phy_10g_64.lxt"); + $dumpvars(0, test_eth_phy_10g_64); +end + +eth_phy_10g #( + .DATA_WIDTH(DATA_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .COUNT_125US(COUNT_125US) +) +UUT ( + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .serdes_tx_data(serdes_tx_data), + .serdes_tx_hdr(serdes_tx_hdr), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber) +); + +endmodule diff --git a/tb/test_eth_phy_10g_rx_64.py b/tb/test_eth_phy_10g_rx_64.py new file mode 100755 index 000000000..1effa27e8 --- /dev/null +++ b/tb/test_eth_phy_10g_rx_64.py @@ -0,0 +1,269 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2018 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 + +import axis_ep +import eth_ep +import xgmii_ep +import baser_serdes_ep + +module = 'eth_phy_10g_rx' +testbench = 'test_%s_64' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_phy_10g_rx_ber_mon.v") +srcs.append("../rtl/eth_phy_10g_rx_frame_sync.v") +srcs.append("../rtl/xgmii_baser_dec_64.v") +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + DATA_WIDTH = 64 + CTRL_WIDTH = (DATA_WIDTH/8) + HDR_WIDTH = 2 + BIT_REVERSE = 0 + SCRAMBLER_DISABLE = 0 + COUNT_125US = 1250/6.4 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) + serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + + serdes_rx_data_int = Signal(intbv(0)[DATA_WIDTH:]) + serdes_rx_hdr_int = Signal(intbv(1)[HDR_WIDTH:]) + + # Outputs + xgmii_rxd = Signal(intbv(0)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0)[CTRL_WIDTH:]) + serdes_rx_bitslip = Signal(bool(0)) + rx_block_lock = Signal(bool(0)) + rx_high_ber = Signal(bool(0)) + + # sources and sinks + source = baser_serdes_ep.BaseRSerdesSource() + + source_logic = source.create_logic( + clk, + tx_data=serdes_rx_data_int, + tx_header=serdes_rx_hdr_int, + name='source' + ) + + sink = xgmii_ep.XGMIISink() + + sink_logic = sink.create_logic( + clk, + rst, + rxd=xgmii_rxd, + rxc=xgmii_rxc, + 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, + xgmii_rxd=xgmii_rxd, + xgmii_rxc=xgmii_rxc, + serdes_rx_data=serdes_rx_data, + serdes_rx_hdr=serdes_rx_hdr, + serdes_rx_bitslip=serdes_rx_bitslip, + rx_block_lock=rx_block_lock, + rx_high_ber=rx_high_ber + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + load_bit_offset = [] + + @instance + def shift_bits(): + bit_offset = 0 + last_data = 0 + + while True: + yield clk.posedge + + if load_bit_offset: + bit_offset = load_bit_offset.pop(0) + + if serdes_rx_bitslip: + bit_offset += 1 + + bit_offset = bit_offset % 66 + + data = int(serdes_rx_data_int) << 2 | int(serdes_rx_hdr_int) + + out_data = ((last_data | data << 66) >> 66-bit_offset) & 0x3ffffffffffffffff + + last_data = data + + serdes_rx_data.next = out_data >> 2 + serdes_rx_hdr.next = out_data & 3 + + @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(16,34)): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = bytearray(range(payload_len)) + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame) + + source.send(xgmii_frame) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame.data + + 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 = bytearray(range(payload_len)) + test_frame2 = bytearray(range(payload_len)) + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame1) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame2) + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame1.data + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame2.data + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: errored frame, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = bytearray(range(payload_len)) + test_frame2 = bytearray(range(payload_len)) + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame1) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame2) + + xgmii_frame1.error = 1 + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + #assert rx_frame.data == xgmii_frame1.data + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame2.data + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: test frame sync") + current_test.next = 4 + + assert rx_block_lock + + load_bit_offset.append(33) + + yield delay(600) + + assert not rx_block_lock + assert rx_high_ber + + yield delay(3000) + + assert rx_block_lock + + yield delay(2000) + + assert not rx_high_ber + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_phy_10g_rx_64.v b/tb/test_eth_phy_10g_rx_64.v new file mode 100644 index 000000000..221ea84ec --- /dev/null +++ b/tb/test_eth_phy_10g_rx_64.v @@ -0,0 +1,99 @@ +/* + +Copyright (c) 2018 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 + +/* + * Testbench for eth_phy_10g_rx + */ +module test_eth_phy_10g_rx_64; + +// Parameters +parameter DATA_WIDTH = 64; +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter HDR_WIDTH = 2; +parameter BIT_REVERSE = 0; +parameter SCRAMBLER_DISABLE = 0; +parameter COUNT_125US = 1250/6.4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] serdes_rx_data = 0; +reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; + +// Outputs +wire [DATA_WIDTH-1:0] xgmii_rxd; +wire [CTRL_WIDTH-1:0] xgmii_rxc; +wire serdes_rx_bitslip; +wire rx_block_lock; +wire rx_high_ber; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + serdes_rx_data, + serdes_rx_hdr + ); + $to_myhdl( + xgmii_rxd, + xgmii_rxc, + serdes_rx_bitslip, + rx_block_lock, + rx_high_ber + ); + + // dump file + $dumpfile("test_eth_phy_10g_rx_64.lxt"); + $dumpvars(0, test_eth_phy_10g_rx_64); +end + +eth_phy_10g_rx #( + .DATA_WIDTH(DATA_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .COUNT_125US(COUNT_125US) +) +UUT ( + .clk(clk), + .rst(rst), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber) +); + +endmodule diff --git a/tb/test_eth_phy_10g_tx_64.py b/tb/test_eth_phy_10g_tx_64.py new file mode 100755 index 000000000..dffd88854 --- /dev/null +++ b/tb/test_eth_phy_10g_tx_64.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2018 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 + +import axis_ep +import eth_ep +import xgmii_ep +import baser_serdes_ep + +module = 'eth_phy_10g_tx' +testbench = 'test_%s_64' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/xgmii_baser_enc_64.v") +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + DATA_WIDTH = 64 + CTRL_WIDTH = (DATA_WIDTH/8) + HDR_WIDTH = 2 + BIT_REVERSE = 0 + SCRAMBLER_DISABLE = 0 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + xgmii_txd = Signal(intbv(0)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0)[CTRL_WIDTH:]) + + # Outputs + serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) + serdes_tx_hdr = Signal(intbv(0)[HDR_WIDTH:]) + + # sources and sinks + source = xgmii_ep.XGMIISource() + + source_logic = source.create_logic( + clk, + rst, + txd=xgmii_txd, + txc=xgmii_txc, + name='source' + ) + + sink = baser_serdes_ep.BaseRSerdesSink() + + sink_logic = sink.create_logic( + clk, + rx_data=serdes_tx_data, + rx_header=serdes_tx_hdr, + 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, + xgmii_txd=xgmii_txd, + xgmii_txc=xgmii_txc, + serdes_tx_data=serdes_tx_data, + serdes_tx_hdr=serdes_tx_hdr + ) + + @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 + + # testbench stimulus + + for payload_len in list(range(16,34)): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = bytearray(range(payload_len)) + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame) + + source.send(xgmii_frame) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame.data + + 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 = bytearray(range(payload_len)) + test_frame2 = bytearray(range(payload_len)) + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame1) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame2) + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame1.data + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame2.data + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: errored frame, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = bytearray(range(payload_len)) + test_frame2 = bytearray(range(payload_len)) + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame1) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame2) + + xgmii_frame1.error = 1 + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + #assert rx_frame.data == xgmii_frame1.data + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data == xgmii_frame2.data + + 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() diff --git a/tb/test_eth_phy_10g_tx_64.v b/tb/test_eth_phy_10g_tx_64.v new file mode 100644 index 000000000..af5a5fd36 --- /dev/null +++ b/tb/test_eth_phy_10g_tx_64.v @@ -0,0 +1,88 @@ +/* + +Copyright (c) 2018 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 + +/* + * Testbench for eth_phy_10g_tx + */ +module test_eth_phy_10g_tx_64; + +// Parameters +parameter DATA_WIDTH = 64; +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter HDR_WIDTH = 2; +parameter BIT_REVERSE = 0; +parameter SCRAMBLER_DISABLE = 0; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] xgmii_txd = 0; +reg [CTRL_WIDTH-1:0] xgmii_txc = 0; + +// Outputs +wire [DATA_WIDTH-1:0] serdes_tx_data; +wire [HDR_WIDTH-1:0] serdes_tx_hdr; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + xgmii_txd, + xgmii_txc + ); + $to_myhdl( + serdes_tx_data, + serdes_tx_hdr + ); + + // dump file + $dumpfile("test_eth_phy_10g_tx_64.lxt"); + $dumpvars(0, test_eth_phy_10g_tx_64); +end + +eth_phy_10g_tx #( + .DATA_WIDTH(DATA_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE) +) +UUT ( + .clk(clk), + .rst(rst), + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .serdes_tx_data(serdes_tx_data), + .serdes_tx_hdr(serdes_tx_hdr) +); + +endmodule From 2e29aea8575b525cb41c14a867a158deae1eec9b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 17 Jan 2019 19:09:47 -0800 Subject: [PATCH 506/617] Fix input clock period settings --- example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v | 2 +- example/ExaNIC_X10/fpga/rtl/fpga.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v index a4c3c2897..5a104958b 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v +++ b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v @@ -153,7 +153,7 @@ MMCME3_BASE #( .CLKFBOUT_PHASE(0), .DIVCLK_DIVIDE(3), .REF_JITTER1(0.010), - .CLKIN1_PERIOD(8.0), + .CLKIN1_PERIOD(3.333), .STARTUP_WAIT("FALSE"), .CLKOUT4_CASCADE("FALSE") ) diff --git a/example/ExaNIC_X10/fpga/rtl/fpga.v b/example/ExaNIC_X10/fpga/rtl/fpga.v index 893e837dc..5eb9be2d6 100644 --- a/example/ExaNIC_X10/fpga/rtl/fpga.v +++ b/example/ExaNIC_X10/fpga/rtl/fpga.v @@ -126,7 +126,7 @@ MMCME3_BASE #( .CLKFBOUT_PHASE(0), .DIVCLK_DIVIDE(1), .REF_JITTER1(0.010), - .CLKIN1_PERIOD(8.0), + .CLKIN1_PERIOD(10.0), .STARTUP_WAIT("FALSE"), .CLKOUT4_CASCADE("FALSE") ) From 0bbe062c6617bda9c89f9fc5d633a96f49289f60 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 18 Jan 2019 13:32:58 -0800 Subject: [PATCH 507/617] Switch out Xilinx PHY core in ADM-PCIE-9V3 example design --- example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile | 8 +- .../fpga_10g/ip/gtwizard_ultrascale_0.xci | 20 +- .../fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci | 127 ---- example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v | 704 ++++++------------ 4 files changed, 262 insertions(+), 597 deletions(-) delete mode 100644 example/ADM_PCIE_9V3/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile index 87ab18cad..8e53e10e6 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -14,6 +14,13 @@ SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/eth_phy_10g.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v +SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v @@ -42,7 +49,6 @@ XDC_FILES = fpga.xdc # IP XCI_FILES += ip/gtwizard_ultrascale_0.xci -XCI_FILES += ip/ten_gig_eth_pcs_pma_0.xci include ../common/vivado.mk diff --git a/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci b/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci index 996e812b5..d7bc14aa1 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci +++ b/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci @@ -12,6 +12,7 @@ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111000000000000" 2 2578.125 + 0 0 125 67 @@ -103,6 +104,7 @@ X0Y19 X0Y18 X0Y17 X0Y16 X0Y15 X0Y14 X0Y13 X0Y12 gtwizard_ultrascale_0 0 + 0 125 BOTH @@ -649,10 +651,10 @@ 0 0 0 - 33 + 13 0 10GBASE-R - 3 + 5 156.2500000 8 2 @@ -1352,7 +1354,8 @@ false false virtexuplus - + + xcvu3p ffvc1517 VERILOG @@ -1363,12 +1366,12 @@ TRUE TRUE IP_Flow - 0 + 5 TRUE . . - 2017.2.1 + 2018.3 OUT_OF_CONTEXT @@ -1376,16 +1379,23 @@ + + + + + + + diff --git a/example/ADM_PCIE_9V3/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci b/example/ADM_PCIE_9V3/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci deleted file mode 100644 index 8014504dc..000000000 --- a/example/ADM_PCIE_9V3/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci +++ /dev/null @@ -1,127 +0,0 @@ - - - xilinx.com - xci - unknown - 1.0 - - - ten_gig_eth_pcs_pma_0 - - - 1 - 75 - 64 - 7 - BASE-R - Asynchronous - Ethernet PCS/PMA 64-bit - MII - 0 - 0 - 0 - 0 - 0 - virtexuplus - 0 - 100.00 - Quad X0Y0 - 0 - 156.25 - GTY - None - 0 - 0 - 0 - 0 - 0 - X0Y0 - NA - NA - NA - 10 - 1 - 0 - 2 - 0 - 0 - 4 - 1 - 0 - 1 - 100 - BASE-R - Asynchronous - Ethernet PCS/PMA 64-bit - ten_gig_eth_pcs_pma_0 - MII - Custom - 0 - 0 - 0 - 0 - 0 - Custom - 0 - 100.00 - Quad_X0Y0 - 0 - 156.25 - GTY - None - 0 - 0 - 0 - 0 - 0 - X0Y0 - NA - NA - NA - 10 - 1 - 0 - 2 - 0 - 0 - false - 1 - virtexuplus - - xcvu3p - ffvc1517 - VERILOG - - MIXED - -2 - I - TRUE - TRUE - IP_Flow - 0 - TRUE - . - - . - 2017.2.1 - OUT_OF_CONTEXT - - - - - - - - - - - - - - - - - - - - diff --git a/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v index 5a104958b..00e6ae2cd 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v +++ b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga.v @@ -211,71 +211,71 @@ debounce_switch_inst ( // XGMII 10G PHY assign qsfp_0_sel_l = 1'b0; -wire qsfp_0_tx_clk_0_int = clk_156mhz_int; -wire qsfp_0_tx_rst_0_int = rst_156mhz_int; +wire qsfp_0_tx_clk_0_int; +wire qsfp_0_tx_rst_0_int; wire [63:0] qsfp_0_txd_0_int; wire [7:0] qsfp_0_txc_0_int; -wire qsfp_0_rx_clk_0_int = clk_156mhz_int; -wire qsfp_0_rx_rst_0_int = rst_156mhz_int; +wire qsfp_0_rx_clk_0_int; +wire qsfp_0_rx_rst_0_int; wire [63:0] qsfp_0_rxd_0_int; wire [7:0] qsfp_0_rxc_0_int; -wire qsfp_0_tx_clk_1_int = clk_156mhz_int; -wire qsfp_0_tx_rst_1_int = rst_156mhz_int; +wire qsfp_0_tx_clk_1_int; +wire qsfp_0_tx_rst_1_int; wire [63:0] qsfp_0_txd_1_int; wire [7:0] qsfp_0_txc_1_int; -wire qsfp_0_rx_clk_1_int = clk_156mhz_int; -wire qsfp_0_rx_rst_1_int = rst_156mhz_int; +wire qsfp_0_rx_clk_1_int; +wire qsfp_0_rx_rst_1_int; wire [63:0] qsfp_0_rxd_1_int; wire [7:0] qsfp_0_rxc_1_int; -wire qsfp_0_tx_clk_2_int = clk_156mhz_int; -wire qsfp_0_tx_rst_2_int = rst_156mhz_int; +wire qsfp_0_tx_clk_2_int; +wire qsfp_0_tx_rst_2_int; wire [63:0] qsfp_0_txd_2_int; wire [7:0] qsfp_0_txc_2_int; -wire qsfp_0_rx_clk_2_int = clk_156mhz_int; -wire qsfp_0_rx_rst_2_int = rst_156mhz_int; +wire qsfp_0_rx_clk_2_int; +wire qsfp_0_rx_rst_2_int; wire [63:0] qsfp_0_rxd_2_int; wire [7:0] qsfp_0_rxc_2_int; -wire qsfp_0_tx_clk_3_int = clk_156mhz_int; -wire qsfp_0_tx_rst_3_int = rst_156mhz_int; +wire qsfp_0_tx_clk_3_int; +wire qsfp_0_tx_rst_3_int; wire [63:0] qsfp_0_txd_3_int; wire [7:0] qsfp_0_txc_3_int; -wire qsfp_0_rx_clk_3_int = clk_156mhz_int; -wire qsfp_0_rx_rst_3_int = rst_156mhz_int; +wire qsfp_0_rx_clk_3_int; +wire qsfp_0_rx_rst_3_int; wire [63:0] qsfp_0_rxd_3_int; wire [7:0] qsfp_0_rxc_3_int; assign qsfp_1_sel_l = 1'b0; -wire qsfp_1_tx_clk_0_int = clk_156mhz_int; -wire qsfp_1_tx_rst_0_int = rst_156mhz_int; +wire qsfp_1_tx_clk_0_int; +wire qsfp_1_tx_rst_0_int; wire [63:0] qsfp_1_txd_0_int; wire [7:0] qsfp_1_txc_0_int; -wire qsfp_1_rx_clk_0_int = clk_156mhz_int; -wire qsfp_1_rx_rst_0_int = rst_156mhz_int; +wire qsfp_1_rx_clk_0_int; +wire qsfp_1_rx_rst_0_int; wire [63:0] qsfp_1_rxd_0_int; wire [7:0] qsfp_1_rxc_0_int; -wire qsfp_1_tx_clk_1_int = clk_156mhz_int; -wire qsfp_1_tx_rst_1_int = rst_156mhz_int; +wire qsfp_1_tx_clk_1_int; +wire qsfp_1_tx_rst_1_int; wire [63:0] qsfp_1_txd_1_int; wire [7:0] qsfp_1_txc_1_int; -wire qsfp_1_rx_clk_1_int = clk_156mhz_int; -wire qsfp_1_rx_rst_1_int = rst_156mhz_int; +wire qsfp_1_rx_clk_1_int; +wire qsfp_1_rx_rst_1_int; wire [63:0] qsfp_1_rxd_1_int; wire [7:0] qsfp_1_rxc_1_int; -wire qsfp_1_tx_clk_2_int = clk_156mhz_int; -wire qsfp_1_tx_rst_2_int = rst_156mhz_int; +wire qsfp_1_tx_clk_2_int; +wire qsfp_1_tx_rst_2_int; wire [63:0] qsfp_1_txd_2_int; wire [7:0] qsfp_1_txc_2_int; -wire qsfp_1_rx_clk_2_int = clk_156mhz_int; -wire qsfp_1_rx_rst_2_int = rst_156mhz_int; +wire qsfp_1_rx_clk_2_int; +wire qsfp_1_rx_rst_2_int; wire [63:0] qsfp_1_rxd_2_int; wire [7:0] qsfp_1_rxc_2_int; -wire qsfp_1_tx_clk_3_int = clk_156mhz_int; -wire qsfp_1_tx_rst_3_int = rst_156mhz_int; +wire qsfp_1_tx_clk_3_int; +wire qsfp_1_tx_rst_3_int; wire [63:0] qsfp_1_txd_3_int; wire [7:0] qsfp_1_txc_3_int; -wire qsfp_1_rx_clk_3_int = clk_156mhz_int; -wire qsfp_1_rx_rst_3_int = rst_156mhz_int; +wire qsfp_1_rx_clk_3_int; +wire qsfp_1_rx_rst_3_int; wire [63:0] qsfp_1_rxd_3_int; wire [7:0] qsfp_1_rxc_3_int; @@ -509,508 +509,284 @@ qsfp_gty_inst ( .txprgdivresetdone_out(gt_txprgdivresetdone) ); -wire qsfp_0_serdes_reset_0; +assign qsfp_0_tx_clk_0_int = clk_156mhz_int; +assign qsfp_0_tx_rst_0_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_0_int = gt_rxusrclk[4]; sync_reset #( .N(4) ) -qsfp_0_pcs_pma_0_rx_serdes_reset_sync_inst ( - .clk(gt_rxusrclk[0]), +qsfp_0_rx_rst_0_reset_sync_inst ( + .clk(qsfp_0_rx_clk_0_int), .rst(~gt_reset_rx_done), - .sync_reset_out(qsfp_0_serdes_reset_0) + .sync_reset_out(qsfp_0_rx_rst_0_int) ); -ten_gig_eth_pcs_pma_0 -qsfp_0_pcs_pma_0 ( - .rx_reset_0(rst_156mhz_int), - .rx_mii_d_0(qsfp_0_rxd_0_int), - .rx_mii_c_0(qsfp_0_rxc_0_int), - - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), - - .stat_rx_block_lock_0(qsfp_0_rx_block_lock_0), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), - - .tx_reset_0(rst_156mhz_int), - .tx_mii_d_0(qsfp_0_txd_0_int), - .tx_mii_c_0(qsfp_0_txc_0_int), - - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - .stat_tx_local_fault_0(), - - // GTY interface - .tx_core_clk_0(clk_156mhz_int), - .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[4]), - .rx_serdes_reset_0(qsfp_0_serdes_reset_0), - .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_0), - .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_0), - .rxheader_out_0(qsfp_0_gt_rxheader_0), - .rxheadervalid_out_0(qsfp_0_gt_rxheadervalid_0), - .rx_serdes_data_out_0(qsfp_0_gt_rxdata_0), - .tx_serdes_data_in_0(qsfp_0_gt_txdata_0), - .txheader_in_0(qsfp_0_gt_txheader_0) +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_0_phy_0_inst ( + .tx_clk(qsfp_0_tx_clk_0_int), + .tx_rst(qsfp_0_tx_rst_0_int), + .rx_clk(qsfp_0_rx_clk_0_int), + .rx_rst(qsfp_0_rx_rst_0_int), + .xgmii_txd(qsfp_0_txd_0_int), + .xgmii_txc(qsfp_0_txc_0_int), + .xgmii_rxd(qsfp_0_rxd_0_int), + .xgmii_rxc(qsfp_0_rxc_0_int), + .serdes_tx_data(qsfp_0_gt_txdata_0), + .serdes_tx_hdr(qsfp_0_gt_txheader_0), + .serdes_rx_data(qsfp_0_gt_rxdata_0), + .serdes_rx_hdr(qsfp_0_gt_rxheader_0), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_0), + .rx_block_lock(qsfp_0_rx_block_lock_0), + .rx_high_ber() ); -wire qsfp_0_serdes_reset_1; +assign qsfp_0_tx_clk_1_int = clk_156mhz_int; +assign qsfp_0_tx_rst_1_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_1_int = gt_rxusrclk[5]; sync_reset #( .N(4) ) -qsfp_0_pcs_pma_1_rx_serdes_reset_sync_inst ( - .clk(gt_rxusrclk[1]), +qsfp_0_rx_rst_1_reset_sync_inst ( + .clk(qsfp_0_rx_clk_1_int), .rst(~gt_reset_rx_done), - .sync_reset_out(qsfp_0_serdes_reset_1) + .sync_reset_out(qsfp_0_rx_rst_1_int) ); -ten_gig_eth_pcs_pma_0 -qsfp_0_pcs_pma_1 ( - .rx_reset_0(rst_156mhz_int), - .rx_mii_d_0(qsfp_0_rxd_1_int), - .rx_mii_c_0(qsfp_0_rxc_1_int), - - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), - - .stat_rx_block_lock_0(qsfp_0_rx_block_lock_1), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), - - .tx_reset_0(rst_156mhz_int), - .tx_mii_d_0(qsfp_0_txd_1_int), - .tx_mii_c_0(qsfp_0_txc_1_int), - - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - .stat_tx_local_fault_0(), - - // GTY interface - .tx_core_clk_0(clk_156mhz_int), - .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[5]), - .rx_serdes_reset_0(qsfp_0_serdes_reset_1), - .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_1), - .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_1), - .rxheader_out_0(qsfp_0_gt_rxheader_1), - .rxheadervalid_out_0(qsfp_0_gt_rxheadervalid_1), - .rx_serdes_data_out_0(qsfp_0_gt_rxdata_1), - .tx_serdes_data_in_0(qsfp_0_gt_txdata_1), - .txheader_in_0(qsfp_0_gt_txheader_1) +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_0_phy_1_inst ( + .tx_clk(qsfp_0_tx_clk_1_int), + .tx_rst(qsfp_0_tx_rst_1_int), + .rx_clk(qsfp_0_rx_clk_1_int), + .rx_rst(qsfp_0_rx_rst_1_int), + .xgmii_txd(qsfp_0_txd_1_int), + .xgmii_txc(qsfp_0_txc_1_int), + .xgmii_rxd(qsfp_0_rxd_1_int), + .xgmii_rxc(qsfp_0_rxc_1_int), + .serdes_tx_data(qsfp_0_gt_txdata_1), + .serdes_tx_hdr(qsfp_0_gt_txheader_1), + .serdes_rx_data(qsfp_0_gt_rxdata_1), + .serdes_rx_hdr(qsfp_0_gt_rxheader_1), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_1), + .rx_block_lock(qsfp_0_rx_block_lock_1), + .rx_high_ber() ); -wire qsfp_0_serdes_reset_2; +assign qsfp_0_tx_clk_2_int = clk_156mhz_int; +assign qsfp_0_tx_rst_2_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_2_int = gt_rxusrclk[6]; sync_reset #( .N(4) ) -qsfp_0_pcs_pma_2_rx_serdes_reset_sync_inst ( - .clk(gt_rxusrclk[2]), +qsfp_0_rx_rst_2_reset_sync_inst ( + .clk(qsfp_0_rx_clk_2_int), .rst(~gt_reset_rx_done), - .sync_reset_out(qsfp_0_serdes_reset_2) + .sync_reset_out(qsfp_0_rx_rst_2_int) ); -ten_gig_eth_pcs_pma_0 -qsfp_0_pcs_pma_2 ( - .rx_reset_0(rst_156mhz_int), - .rx_mii_d_0(qsfp_0_rxd_2_int), - .rx_mii_c_0(qsfp_0_rxc_2_int), - - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), - - .stat_rx_block_lock_0(qsfp_0_rx_block_lock_2), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), - - .tx_reset_0(rst_156mhz_int), - .tx_mii_d_0(qsfp_0_txd_2_int), - .tx_mii_c_0(qsfp_0_txc_2_int), - - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - .stat_tx_local_fault_0(), - - // GTY interface - .tx_core_clk_0(clk_156mhz_int), - .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[6]), - .rx_serdes_reset_0(qsfp_0_serdes_reset_2), - .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_2), - .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_2), - .rxheader_out_0(qsfp_0_gt_rxheader_2), - .rxheadervalid_out_0(qsfp_0_gt_rxheadervalid_2), - .rx_serdes_data_out_0(qsfp_0_gt_rxdata_2), - .tx_serdes_data_in_0(qsfp_0_gt_txdata_2), - .txheader_in_0(qsfp_0_gt_txheader_2) +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_0_phy_2_inst ( + .tx_clk(qsfp_0_tx_clk_2_int), + .tx_rst(qsfp_0_tx_rst_2_int), + .rx_clk(qsfp_0_rx_clk_2_int), + .rx_rst(qsfp_0_rx_rst_2_int), + .xgmii_txd(qsfp_0_txd_2_int), + .xgmii_txc(qsfp_0_txc_2_int), + .xgmii_rxd(qsfp_0_rxd_2_int), + .xgmii_rxc(qsfp_0_rxc_2_int), + .serdes_tx_data(qsfp_0_gt_txdata_2), + .serdes_tx_hdr(qsfp_0_gt_txheader_2), + .serdes_rx_data(qsfp_0_gt_rxdata_2), + .serdes_rx_hdr(qsfp_0_gt_rxheader_2), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_2), + .rx_block_lock(qsfp_0_rx_block_lock_2), + .rx_high_ber() ); -wire qsfp_0_serdes_reset_3; +assign qsfp_0_tx_clk_3_int = clk_156mhz_int; +assign qsfp_0_tx_rst_3_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_3_int = gt_rxusrclk[7]; sync_reset #( .N(4) ) -qsfp_0_pcs_pma_3_rx_serdes_reset_sync_inst ( - .clk(gt_rxusrclk[3]), +qsfp_0_rx_rst_3_reset_sync_inst ( + .clk(qsfp_0_rx_clk_3_int), .rst(~gt_reset_rx_done), - .sync_reset_out(qsfp_0_serdes_reset_3) + .sync_reset_out(qsfp_0_rx_rst_3_int) ); -ten_gig_eth_pcs_pma_0 -qsfp_0_pcs_pma_3 ( - .rx_reset_0(rst_156mhz_int), - .rx_mii_d_0(qsfp_0_rxd_3_int), - .rx_mii_c_0(qsfp_0_rxc_3_int), - - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), - - .stat_rx_block_lock_0(qsfp_0_rx_block_lock_3), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), - - .tx_reset_0(rst_156mhz_int), - .tx_mii_d_0(qsfp_0_txd_3_int), - .tx_mii_c_0(qsfp_0_txc_3_int), - - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - .stat_tx_local_fault_0(), - - // GTY interface - .tx_core_clk_0(clk_156mhz_int), - .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[7]), - .rx_serdes_reset_0(qsfp_0_serdes_reset_3), - .rxgearboxslip_in_0(qsfp_0_gt_rxgearboxslip_3), - .rxdatavalid_out_0(qsfp_0_gt_rxdatavalid_3), - .rxheader_out_0(qsfp_0_gt_rxheader_3), - .rxheadervalid_out_0(qsfp_0_gt_rxheadervalid_3), - .rx_serdes_data_out_0(qsfp_0_gt_rxdata_3), - .tx_serdes_data_in_0(qsfp_0_gt_txdata_3), - .txheader_in_0(qsfp_0_gt_txheader_3) +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_0_phy_3_inst ( + .tx_clk(qsfp_0_tx_clk_3_int), + .tx_rst(qsfp_0_tx_rst_3_int), + .rx_clk(qsfp_0_rx_clk_3_int), + .rx_rst(qsfp_0_rx_rst_3_int), + .xgmii_txd(qsfp_0_txd_3_int), + .xgmii_txc(qsfp_0_txc_3_int), + .xgmii_rxd(qsfp_0_rxd_3_int), + .xgmii_rxc(qsfp_0_rxc_3_int), + .serdes_tx_data(qsfp_0_gt_txdata_3), + .serdes_tx_hdr(qsfp_0_gt_txheader_3), + .serdes_rx_data(qsfp_0_gt_rxdata_3), + .serdes_rx_hdr(qsfp_0_gt_rxheader_3), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_3), + .rx_block_lock(qsfp_0_rx_block_lock_3), + .rx_high_ber() ); -wire qsfp_1_serdes_reset_0; +assign qsfp_1_tx_clk_0_int = clk_156mhz_int; +assign qsfp_1_tx_rst_0_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_0_int = gt_rxusrclk[0]; sync_reset #( .N(4) ) -qsfp_1_pcs_pma_0_rx_serdes_reset_sync_inst ( - .clk(gt_rxusrclk[4]), +qsfp_1_rx_rst_0_reset_sync_inst ( + .clk(qsfp_1_rx_clk_0_int), .rst(~gt_reset_rx_done), - .sync_reset_out(qsfp_1_serdes_reset_0) + .sync_reset_out(qsfp_1_rx_rst_0_int) ); -ten_gig_eth_pcs_pma_0 -qsfp_1_pcs_pma_0 ( - .rx_reset_0(rst_156mhz_int), - .rx_mii_d_0(qsfp_1_rxd_0_int), - .rx_mii_c_0(qsfp_1_rxc_0_int), - - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), - - .stat_rx_block_lock_0(qsfp_1_rx_block_lock_0), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), - - .tx_reset_0(rst_156mhz_int), - .tx_mii_d_0(qsfp_1_txd_0_int), - .tx_mii_c_0(qsfp_1_txc_0_int), - - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - .stat_tx_local_fault_0(), - - // GTY interface - .tx_core_clk_0(clk_156mhz_int), - .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[0]), - .rx_serdes_reset_0(qsfp_1_serdes_reset_0), - .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_0), - .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_0), - .rxheader_out_0(qsfp_1_gt_rxheader_0), - .rxheadervalid_out_0(qsfp_1_gt_rxheadervalid_0), - .rx_serdes_data_out_0(qsfp_1_gt_rxdata_0), - .tx_serdes_data_in_0(qsfp_1_gt_txdata_0), - .txheader_in_0(qsfp_1_gt_txheader_0) +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_1_phy_0_inst ( + .tx_clk(qsfp_1_tx_clk_0_int), + .tx_rst(qsfp_1_tx_rst_0_int), + .rx_clk(qsfp_1_rx_clk_0_int), + .rx_rst(qsfp_1_rx_rst_0_int), + .xgmii_txd(qsfp_1_txd_0_int), + .xgmii_txc(qsfp_1_txc_0_int), + .xgmii_rxd(qsfp_1_rxd_0_int), + .xgmii_rxc(qsfp_1_rxc_0_int), + .serdes_tx_data(qsfp_1_gt_txdata_0), + .serdes_tx_hdr(qsfp_1_gt_txheader_0), + .serdes_rx_data(qsfp_1_gt_rxdata_0), + .serdes_rx_hdr(qsfp_1_gt_rxheader_0), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_0), + .rx_block_lock(qsfp_1_rx_block_lock_0), + .rx_high_ber() ); -wire qsfp_1_serdes_reset_1; +assign qsfp_1_tx_clk_1_int = clk_156mhz_int; +assign qsfp_1_tx_rst_1_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_1_int = gt_rxusrclk[1]; sync_reset #( .N(4) ) -qsfp_1_pcs_pma_1_rx_serdes_reset_sync_inst ( - .clk(gt_rxusrclk[5]), +qsfp_1_rx_rst_1_reset_sync_inst ( + .clk(qsfp_1_rx_clk_1_int), .rst(~gt_reset_rx_done), - .sync_reset_out(qsfp_1_serdes_reset_1) + .sync_reset_out(qsfp_1_rx_rst_1_int) ); -ten_gig_eth_pcs_pma_0 -qsfp_1_pcs_pma_1 ( - .rx_reset_0(rst_156mhz_int), - .rx_mii_d_0(qsfp_1_rxd_1_int), - .rx_mii_c_0(qsfp_1_rxc_1_int), - - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), - - .stat_rx_block_lock_0(qsfp_1_rx_block_lock_1), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), - - .tx_reset_0(rst_156mhz_int), - .tx_mii_d_0(qsfp_1_txd_1_int), - .tx_mii_c_0(qsfp_1_txc_1_int), - - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - .stat_tx_local_fault_0(), - - // GTY interface - .tx_core_clk_0(clk_156mhz_int), - .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[1]), - .rx_serdes_reset_0(qsfp_1_serdes_reset_1), - .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_1), - .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_1), - .rxheader_out_0(qsfp_1_gt_rxheader_1), - .rxheadervalid_out_0(qsfp_1_gt_rxheadervalid_1), - .rx_serdes_data_out_0(qsfp_1_gt_rxdata_1), - .tx_serdes_data_in_0(qsfp_1_gt_txdata_1), - .txheader_in_0(qsfp_1_gt_txheader_1) +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_1_phy_1_inst ( + .tx_clk(qsfp_1_tx_clk_1_int), + .tx_rst(qsfp_1_tx_rst_1_int), + .rx_clk(qsfp_1_rx_clk_1_int), + .rx_rst(qsfp_1_rx_rst_1_int), + .xgmii_txd(qsfp_1_txd_1_int), + .xgmii_txc(qsfp_1_txc_1_int), + .xgmii_rxd(qsfp_1_rxd_1_int), + .xgmii_rxc(qsfp_1_rxc_1_int), + .serdes_tx_data(qsfp_1_gt_txdata_1), + .serdes_tx_hdr(qsfp_1_gt_txheader_1), + .serdes_rx_data(qsfp_1_gt_rxdata_1), + .serdes_rx_hdr(qsfp_1_gt_rxheader_1), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_1), + .rx_block_lock(qsfp_1_rx_block_lock_1), + .rx_high_ber() ); -wire qsfp_1_serdes_reset_2; +assign qsfp_1_tx_clk_2_int = clk_156mhz_int; +assign qsfp_1_tx_rst_2_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_2_int = gt_rxusrclk[2]; sync_reset #( .N(4) ) -qsfp_1_pcs_pma_2_rx_serdes_reset_sync_inst ( - .clk(gt_rxusrclk[6]), +qsfp_1_rx_rst_2_reset_sync_inst ( + .clk(qsfp_1_rx_clk_2_int), .rst(~gt_reset_rx_done), - .sync_reset_out(qsfp_1_serdes_reset_2) + .sync_reset_out(qsfp_1_rx_rst_2_int) ); -ten_gig_eth_pcs_pma_0 -qsfp_1_pcs_pma_2 ( - .rx_reset_0(rst_156mhz_int), - .rx_mii_d_0(qsfp_1_rxd_2_int), - .rx_mii_c_0(qsfp_1_rxc_2_int), - - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), - - .stat_rx_block_lock_0(qsfp_1_rx_block_lock_2), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), - - .tx_reset_0(rst_156mhz_int), - .tx_mii_d_0(qsfp_1_txd_2_int), - .tx_mii_c_0(qsfp_1_txc_2_int), - - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - .stat_tx_local_fault_0(), - - // GTY interface - .tx_core_clk_0(clk_156mhz_int), - .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[2]), - .rx_serdes_reset_0(qsfp_1_serdes_reset_2), - .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_2), - .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_2), - .rxheader_out_0(qsfp_1_gt_rxheader_2), - .rxheadervalid_out_0(qsfp_1_gt_rxheadervalid_2), - .rx_serdes_data_out_0(qsfp_1_gt_rxdata_2), - .tx_serdes_data_in_0(qsfp_1_gt_txdata_2), - .txheader_in_0(qsfp_1_gt_txheader_2) +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_1_phy_2_inst ( + .tx_clk(qsfp_1_tx_clk_2_int), + .tx_rst(qsfp_1_tx_rst_2_int), + .rx_clk(qsfp_1_rx_clk_2_int), + .rx_rst(qsfp_1_rx_rst_2_int), + .xgmii_txd(qsfp_1_txd_2_int), + .xgmii_txc(qsfp_1_txc_2_int), + .xgmii_rxd(qsfp_1_rxd_2_int), + .xgmii_rxc(qsfp_1_rxc_2_int), + .serdes_tx_data(qsfp_1_gt_txdata_2), + .serdes_tx_hdr(qsfp_1_gt_txheader_2), + .serdes_rx_data(qsfp_1_gt_rxdata_2), + .serdes_rx_hdr(qsfp_1_gt_rxheader_2), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_2), + .rx_block_lock(qsfp_1_rx_block_lock_2), + .rx_high_ber() ); -wire qsfp_1_serdes_reset_3; +assign qsfp_1_tx_clk_3_int = clk_156mhz_int; +assign qsfp_1_tx_rst_3_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_3_int = gt_rxusrclk[3]; sync_reset #( .N(4) ) -qsfp_1_pcs_pma_3_rx_serdes_reset_sync_inst ( - .clk(gt_rxusrclk[7]), +qsfp_1_rx_rst_3_reset_sync_inst ( + .clk(qsfp_1_rx_clk_3_int), .rst(~gt_reset_rx_done), - .sync_reset_out(qsfp_1_serdes_reset_3) + .sync_reset_out(qsfp_1_rx_rst_3_int) ); -ten_gig_eth_pcs_pma_0 -qsfp_1_pcs_pma_3 ( - .rx_reset_0(rst_156mhz_int), - .rx_mii_d_0(qsfp_1_rxd_3_int), - .rx_mii_c_0(qsfp_1_rxc_3_int), - - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), - - .stat_rx_block_lock_0(qsfp_1_rx_block_lock_3), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), - - .tx_reset_0(rst_156mhz_int), - .tx_mii_d_0(qsfp_1_txd_3_int), - .tx_mii_c_0(qsfp_1_txc_3_int), - - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - .stat_tx_local_fault_0(), - - // GTY interface - .tx_core_clk_0(clk_156mhz_int), - .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk[3]), - .rx_serdes_reset_0(qsfp_1_serdes_reset_3), - .rxgearboxslip_in_0(qsfp_1_gt_rxgearboxslip_3), - .rxdatavalid_out_0(qsfp_1_gt_rxdatavalid_3), - .rxheader_out_0(qsfp_1_gt_rxheader_3), - .rxheadervalid_out_0(qsfp_1_gt_rxheadervalid_3), - .rx_serdes_data_out_0(qsfp_1_gt_rxdata_3), - .tx_serdes_data_in_0(qsfp_1_gt_txdata_3), - .txheader_in_0(qsfp_1_gt_txheader_3) +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_1_phy_3_inst ( + .tx_clk(qsfp_1_tx_clk_3_int), + .tx_rst(qsfp_1_tx_rst_3_int), + .rx_clk(qsfp_1_rx_clk_3_int), + .rx_rst(qsfp_1_rx_rst_3_int), + .xgmii_txd(qsfp_1_txd_3_int), + .xgmii_txc(qsfp_1_txc_3_int), + .xgmii_rxd(qsfp_1_rxd_3_int), + .xgmii_rxc(qsfp_1_rxc_3_int), + .serdes_tx_data(qsfp_1_gt_txdata_3), + .serdes_tx_hdr(qsfp_1_gt_txheader_3), + .serdes_rx_data(qsfp_1_gt_rxdata_3), + .serdes_rx_hdr(qsfp_1_gt_rxheader_3), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_3), + .rx_block_lock(qsfp_1_rx_block_lock_3), + .rx_high_ber() ); //assign led = sw[0] ? {qsfp_1_rx_block_lock_4, qsfp_1_rx_block_lock_3, qsfp_1_rx_block_lock_2, qsfp_1_rx_block_lock_1, qsfp_0_rx_block_lock_4, qsfp_0_rx_block_lock_3, qsfp_0_rx_block_lock_2, qsfp_0_rx_block_lock_1} : led_int; From 07b4efa9badf0edfc10dc3f3c76a9758583a1667 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 18 Jan 2019 13:49:46 -0800 Subject: [PATCH 508/617] Switch out Xilinx PHY core in ExaNIC X10 example design --- example/ExaNIC_X10/fpga/fpga/Makefile | 8 +- .../fpga/ip/gtwizard_ultrascale_0.xci | 14 +- .../fpga/ip/ten_gig_eth_pcs_pma_0.xci | 132 ------------- example/ExaNIC_X10/fpga/rtl/fpga.v | 176 ++++++------------ 4 files changed, 76 insertions(+), 254 deletions(-) delete mode 100644 example/ExaNIC_X10/fpga/ip/ten_gig_eth_pcs_pma_0.xci diff --git a/example/ExaNIC_X10/fpga/fpga/Makefile b/example/ExaNIC_X10/fpga/fpga/Makefile index fa241dffd..998b8557d 100644 --- a/example/ExaNIC_X10/fpga/fpga/Makefile +++ b/example/ExaNIC_X10/fpga/fpga/Makefile @@ -13,6 +13,13 @@ SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/eth_phy_10g.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v +SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v @@ -41,7 +48,6 @@ XDC_FILES = fpga.xdc # IP XCI_FILES = ip/gtwizard_ultrascale_0.xci -XCI_FILES += ip/ten_gig_eth_pcs_pma_0.xci include ../common/vivado.mk diff --git a/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci b/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci index 4de2bbe20..333cda6bc 100644 --- a/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci +++ b/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci @@ -12,6 +12,7 @@ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000000" 1 2578.125 + 0 0 125 17 @@ -71,7 +72,7 @@ 312.5000000 0 257.8125 - "0" + 0 2 1 0 @@ -103,6 +104,7 @@ X0Y13 X0Y12 gtwizard_ultrascale_0 0 + 0 rxpolarity_in txpolarity_in 125 BOTH @@ -652,7 +654,7 @@ 13 0 10GBASE-R - 3 + 4 312.5000000 2 1 @@ -1352,7 +1354,8 @@ false false kintexu - + + xcku035 fbva676 VERILOG @@ -1363,12 +1366,12 @@ TRUE TRUE IP_Flow - 0 + 5 TRUE . . - 2017.2.1 + 2018.3 OUT_OF_CONTEXT @@ -1387,6 +1390,7 @@ + diff --git a/example/ExaNIC_X10/fpga/ip/ten_gig_eth_pcs_pma_0.xci b/example/ExaNIC_X10/fpga/ip/ten_gig_eth_pcs_pma_0.xci deleted file mode 100644 index fc00bdafe..000000000 --- a/example/ExaNIC_X10/fpga/ip/ten_gig_eth_pcs_pma_0.xci +++ /dev/null @@ -1,132 +0,0 @@ - - - xilinx.com - xci - unknown - 1.0 - - - ten_gig_eth_pcs_pma_0 - - - 1 - 75 - 64 - 7 - BASE-R - Asynchronous - Ethernet PCS/PMA 64-bit - MII - 0 - 0 - 0 - 0 - 0 - kintexu - 0 - 125 - Quad X0Y0 - 0 - 161.1328125 - GTH - None - 0 - 0 - 0 - 0 - 0 - X0Y12 - NA - NA - NA - 10 - 1 - 0 - 2 - 0 - 0 - 4 - 1 - 0 - 1 - 100 - BASE-R - Asynchronous - Ethernet PCS/PMA 64-bit - ten_gig_eth_pcs_pma_0 - MII - Custom - 0 - 0 - 0 - 0 - 0 - Custom - 0 - 125 - Quad_X0Y3 - 0 - 161.1328125 - GTH - None - 0 - 0 - 0 - 0 - 0 - X0Y12 - NA - NA - NA - 10 - 1 - 0 - 2 - 0 - 0 - false - 1 - kintexu - - xcku035 - fbva676 - VERILOG - - MIXED - -2 - E - TRUE - TRUE - IP_Flow - 0 - TRUE - . - - . - 2017.2.1 - OUT_OF_CONTEXT - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/ExaNIC_X10/fpga/rtl/fpga.v b/example/ExaNIC_X10/fpga/rtl/fpga.v index 5eb9be2d6..8392a87d6 100644 --- a/example/ExaNIC_X10/fpga/rtl/fpga.v +++ b/example/ExaNIC_X10/fpga/rtl/fpga.v @@ -178,20 +178,20 @@ assign sfp_2_tx_disable = 1'b0; assign sfp_1_rs = 1'b1; assign sfp_2_rs = 1'b1; -wire sfp_1_tx_clk_int = clk_156mhz_int; -wire sfp_1_tx_rst_int = rst_156mhz_int; +wire sfp_1_tx_clk_int; +wire sfp_1_tx_rst_int; wire [63:0] sfp_1_txd_int; wire [7:0] sfp_1_txc_int; -wire sfp_1_rx_clk_int = clk_156mhz_int; -wire sfp_1_rx_rst_int = rst_156mhz_int; +wire sfp_1_rx_clk_int; +wire sfp_1_rx_rst_int; wire [63:0] sfp_1_rxd_int; wire [7:0] sfp_1_rxc_int; -wire sfp_2_tx_clk_int = clk_156mhz_int; -wire sfp_2_tx_rst_int = rst_156mhz_int; +wire sfp_2_tx_clk_int; +wire sfp_2_tx_rst_int; wire [63:0] sfp_2_txd_int; wire [7:0] sfp_2_txc_int; -wire sfp_2_rx_clk_int = clk_156mhz_int; -wire sfp_2_rx_rst_int = rst_156mhz_int; +wire sfp_2_rx_clk_int; +wire sfp_2_rx_rst_int; wire [63:0] sfp_2_rxd_int; wire [7:0] sfp_2_rxc_int; @@ -383,130 +383,74 @@ sfp_gth_inst ( .txprgdivresetdone_out(gt_txprgdivresetdone) ); -wire sfp_1_serdes_reset; +assign sfp_1_tx_clk_int = clk_156mhz_int; +assign sfp_1_tx_rst_int = rst_156mhz_int; + +assign sfp_1_rx_clk_int = gt_rxusrclk2[0]; sync_reset #( .N(4) ) -sfp_1_pcs_pma_rx_serdes_reset_sync_inst ( - .clk(gt_rxusrclk[0]), +sfp_1_rx_rst_reset_sync_inst ( + .clk(sfp_1_rx_clk_int), .rst(~gt_reset_rx_done), - .sync_reset_out(sfp_1_serdes_reset) + .sync_reset_out(sfp_1_rx_rst_int) ); -ten_gig_eth_pcs_pma_0 -sfp_pcs_pma_1 ( - .rx_reset_0(rst_156mhz_int), - .rx_mii_d_0(sfp_1_rxd_int), - .rx_mii_c_0(sfp_1_rxc_int), - - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), - - .stat_rx_block_lock_0(sfp_1_rx_block_lock), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), - - .tx_reset_0(rst_156mhz_int), - .tx_mii_d_0(sfp_1_txd_int), - .tx_mii_c_0(sfp_1_txc_int), - - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - .stat_tx_local_fault_0(), - - // GTH interface - .tx_core_clk_0(clk_156mhz_int), - .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk2[0]), - .rx_serdes_reset_0(sfp_1_serdes_reset), - .rxgearboxslip_in_0(sfp_1_gt_rxgearboxslip), - .rxdatavalid_out_0(sfp_1_gt_rxdatavalid), - .rxheader_out_0(sfp_1_gt_rxheader), - .rxheadervalid_out_0(sfp_1_gt_rxheadervalid), - .rx_serdes_data_out_0(sfp_1_gt_rxdata), - .tx_serdes_data_in_0(sfp_1_gt_txdata), - .txheader_in_0(sfp_1_gt_txheader) +eth_phy_10g #( + .BIT_REVERSE(1) +) +sfp_1_phy_inst ( + .tx_clk(sfp_1_tx_clk_int), + .tx_rst(sfp_1_tx_rst_int), + .rx_clk(sfp_1_rx_clk_int), + .rx_rst(sfp_1_rx_rst_int), + .xgmii_txd(sfp_1_txd_int), + .xgmii_txc(sfp_1_txc_int), + .xgmii_rxd(sfp_1_rxd_int), + .xgmii_rxc(sfp_1_rxc_int), + .serdes_tx_data(sfp_1_gt_txdata), + .serdes_tx_hdr(sfp_1_gt_txheader), + .serdes_rx_data(sfp_1_gt_rxdata), + .serdes_rx_hdr(sfp_1_gt_rxheader), + .serdes_rx_bitslip(sfp_1_gt_rxgearboxslip), + .rx_block_lock(sfp_1_rx_block_lock), + .rx_high_ber() ); -wire sfp_2_serdes_reset; +assign sfp_2_tx_clk_int = clk_156mhz_int; +assign sfp_2_tx_rst_int = rst_156mhz_int; + +assign sfp_2_rx_clk_int = gt_rxusrclk2[1]; sync_reset #( .N(4) ) -sfp_2_pcs_pma_rx_serdes_reset_sync_inst ( - .clk(gt_rxusrclk[1]), +sfp_2_rx_rst_reset_sync_inst ( + .clk(sfp_2_rx_clk_int), .rst(~gt_reset_rx_done), - .sync_reset_out(sfp_2_serdes_reset) + .sync_reset_out(sfp_2_rx_rst_int) ); -ten_gig_eth_pcs_pma_0 -sfp_pcs_pma_2 ( - .rx_reset_0(rst_156mhz_int), - .rx_mii_d_0(sfp_2_rxd_int), - .rx_mii_c_0(sfp_2_rxc_int), - - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), - - .stat_rx_block_lock_0(sfp_2_rx_block_lock), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), - - .tx_reset_0(rst_156mhz_int), - .tx_mii_d_0(sfp_2_txd_int), - .tx_mii_c_0(sfp_2_txc_int), - - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - .stat_tx_local_fault_0(), - - // GTH interface - .tx_core_clk_0(clk_156mhz_int), - .rx_core_clk_0(clk_156mhz_int), - .rx_serdes_clk_0(gt_rxusrclk2[1]), - .rx_serdes_reset_0(sfp_2_serdes_reset), - .rxgearboxslip_in_0(sfp_2_gt_rxgearboxslip), - .rxdatavalid_out_0(sfp_2_gt_rxdatavalid), - .rxheader_out_0(sfp_2_gt_rxheader), - .rxheadervalid_out_0(sfp_2_gt_rxheadervalid), - .rx_serdes_data_out_0(sfp_2_gt_rxdata), - .tx_serdes_data_in_0(sfp_2_gt_txdata), - .txheader_in_0(sfp_2_gt_txheader) +eth_phy_10g #( + .BIT_REVERSE(1) +) +sfp_2_phy_inst ( + .tx_clk(sfp_2_tx_clk_int), + .tx_rst(sfp_2_tx_rst_int), + .rx_clk(sfp_2_rx_clk_int), + .rx_rst(sfp_2_rx_rst_int), + .xgmii_txd(sfp_2_txd_int), + .xgmii_txc(sfp_2_txc_int), + .xgmii_rxd(sfp_2_rxd_int), + .xgmii_rxc(sfp_2_rxc_int), + .serdes_tx_data(sfp_2_gt_txdata), + .serdes_tx_hdr(sfp_2_gt_txheader), + .serdes_rx_data(sfp_2_gt_rxdata), + .serdes_rx_hdr(sfp_2_gt_rxheader), + .serdes_rx_bitslip(sfp_2_gt_rxgearboxslip), + .rx_block_lock(sfp_2_rx_block_lock), + .rx_high_ber() ); assign sfp_1_led[0] = sfp_1_rx_block_lock; From a060d2eed9df56f4f2d113deae3fdf9ba6bf3bd3 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 18 Jan 2019 16:22:24 -0800 Subject: [PATCH 509/617] Update readme --- README.md | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5d5c60404..ed9f6decc 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,17 @@ GitHub repository: https://github.com/alexforencich/verilog-ethernet Collection of Ethernet-related components for both gigabit and 10G packet processing (8 bit and 64 bit datapaths). Includes modules for handling Ethernet frames as well as IP, UDP, and ARP and the components for -constructing a complete UDP/IP stack. Includes full MyHDL testbench with +constructing a complete UDP/IP stack. Includes MAC modules for gigabit and +10G and a 10G PCS/PMA PHY module. Also includes full MyHDL testbench with intelligent bus cosimulation endpoints. For IP and ARP support only, use ip_complete (1G) or ip_complete_64 (10G). For UDP, IP, and ARP support, use udp_complete (1G) or udp_complete_64 (10G). +Top level gigabit and 10G MAC modules are eth_mac_*, with various interfaces +and with/without FIFOs. Top level 10G PCS/PMA PHY module is eth_phy_10g. + ## Documentation ### arp module @@ -156,7 +160,27 @@ bits. Ethernet frame muliplexer with parametrizable data width and port count. Supports priority and round-robin arbitration. -### gmii_phy_if +### eth_phy_10g module + +10G Ethernet PCS/PMA PHY. + +### eth_phy_10g_rx module + +10G Ethernet PCS/PMA PHY receive-side logic. + +### eth_phy_10g_rx_ber_mon module + +10G Ethernet PCS/PMA PHY BER monitor. + +### eth_phy_10g_rx_frame_sync module + +10G Ethernet PCS/PMA PHY frame synchronizer. + +### eth_phy_10g_tx module + +10G Ethernet PCS/PMA PHY transmit-side logic. + +### gmii_phy_if module GMII/MII PHY interface and clocking logic. @@ -217,7 +241,7 @@ Supports priority and round-robin arbitration. Fully parametrizable combinatorial parallel LFSR/CRC module. -### rgmii_phy_if +### rgmii_phy_if module RGMII PHY interface and clocking logic. @@ -285,12 +309,20 @@ UDP frame transmitter with 64 bit datapath for 10G Ethernet. UDP frame muliplexer with parametrizable data width and port count. Supports priority and round-robin arbitration. -### xgmii_deinterleave.v +### xgmii_baser_dec_64 module + +XGMII 10GBASE-R decoder for 10G PCS/PMA PHY. + +### xgmii_baser_enc_64 module + +XGMII 10GBASE-R encoder for 10G PCS/PMA PHY. + +### xgmii_deinterleave module XGMII de-interleaver for interfacing with PHY cores that interleave the control and data lines. -### xgmii_interleave.v +### xgmii_interleave module XGMII interleaver for interfacing with PHY cores that interleave the control and data lines. @@ -376,6 +408,10 @@ and data lines. rtl/udp_ip_tx.v : UDP frame transmitter rtl/udp_ip_tx_64.v : UDP frame transmitter (64 bit) rtl/udp_mux.v : UDP frame multiplexer + rtl/xgmii_baser_dec_64.v : XGMII 10GBASE-R decoder + rtl/xgmii_baser_enc_64.v : XGMII 10GBASE-R encoder + rtl/xgmii_deinterleave.v : XGMII data/control de-interleaver + rtl/xgmii_interleave.v : XGMII data/control interleaver ### AXI Stream Interface Example @@ -468,6 +504,7 @@ individual test scripts can be run with python directly. tb/arp_ep.py : MyHDL ARP frame endpoints tb/axis_ep.py : MyHDL AXI Stream endpoints + tb/baser_serdes.py : MyHDL 10GBASE-R SERDES endpoints tb/eth_ep.py : MyHDL Ethernet frame endpoints tb/gmii_ep.py : MyHDL GMII endpoints tb/ip_ep.py : MyHDL IP frame endpoints From e784900050b8ef427b0ff06eca2cb375bb3f3548 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 22 Jan 2019 14:18:27 -0800 Subject: [PATCH 510/617] Remove unused code --- rtl/axis_xgmii_tx_32.v | 11 ----------- rtl/axis_xgmii_tx_64.v | 15 --------------- 2 files changed, 26 deletions(-) diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index 3e9cc8762..cb5c5ae5d 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -203,17 +203,6 @@ function [2:0] keep2count; endcase endfunction -function [3:0] count2keep; - input [2:0] k; - case (k) - 3'd0: count2keep = 4'b0000; - 3'd1: count2keep = 4'b0001; - 3'd2: count2keep = 4'b0011; - 3'd3: count2keep = 4'b0111; - 3'd4: count2keep = 4'b1111; - endcase -endfunction - // Mask input data integer j; diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index 361e3900a..c78b5741f 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -280,21 +280,6 @@ function [3:0] keep2count; endcase endfunction -function [7:0] count2keep; - input [3:0] k; - case (k) - 4'd0: count2keep = 8'b00000000; - 4'd1: count2keep = 8'b00000001; - 4'd2: count2keep = 8'b00000011; - 4'd3: count2keep = 8'b00000111; - 4'd4: count2keep = 8'b00001111; - 4'd5: count2keep = 8'b00011111; - 4'd6: count2keep = 8'b00111111; - 4'd7: count2keep = 8'b01111111; - 4'd8: count2keep = 8'b11111111; - endcase -endfunction - // Mask input data integer j; From 6238ed5755fc87671156cd2c417866ab71b62a9a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 22 Jan 2019 14:19:43 -0800 Subject: [PATCH 511/617] Report error for invalid encoding --- rtl/axis_xgmii_tx_32.v | 8 ++++---- rtl/axis_xgmii_tx_64.v | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index cb5c5ae5d..9fa3e41ac 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -248,10 +248,10 @@ always @* begin extra_cycle = 1'b1; end default: begin - fcs_output_txd_0 = 32'd0; - fcs_output_txd_1 = 32'd0; - fcs_output_txc_0 = 4'd0; - fcs_output_txc_1 = 4'd0; + fcs_output_txd_0 = {4{XGMII_ERROR}}; + fcs_output_txd_1 = {4{XGMII_ERROR}}; + fcs_output_txc_0 = 4'b1111; + fcs_output_txc_1 = 4'b1111; ifg_offset = 8'd0; extra_cycle = 1'b0; end diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index c78b5741f..1b6f10630 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -357,10 +357,10 @@ always @* begin extra_cycle = 1'b1; end default: begin - fcs_output_txd_0 = 64'd0; - fcs_output_txd_1 = 64'd0; - fcs_output_txc_0 = 8'd0; - fcs_output_txc_1 = 8'd0; + fcs_output_txd_0 = {8{XGMII_ERROR}}; + fcs_output_txd_1 = {8{XGMII_ERROR}}; + fcs_output_txc_0 = 8'b11111111; + fcs_output_txc_1 = 8'b11111111; ifg_offset = 8'd0; extra_cycle = 1'b1; end From 54e31c51b7dd4f81cb380a36bf17a2b63645812f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 22 Jan 2019 14:21:14 -0800 Subject: [PATCH 512/617] Adjustment to scrambler bypass --- rtl/eth_phy_10g_rx.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtl/eth_phy_10g_rx.v b/rtl/eth_phy_10g_rx.v index 0348d0d1c..45a99e3aa 100644 --- a/rtl/eth_phy_10g_rx.v +++ b/rtl/eth_phy_10g_rx.v @@ -128,7 +128,7 @@ descrambler_inst ( always @(posedge clk) begin scrambler_state_reg <= scrambler_state; - encoded_rx_data_reg <= descrambled_rx_data; + encoded_rx_data_reg <= SCRAMBLER_DISABLE ? serdes_rx_data_int : descrambled_rx_data; encoded_rx_hdr_reg <= serdes_rx_hdr_int; end @@ -140,8 +140,8 @@ xgmii_baser_dec_64 #( xgmii_baser_dec_inst ( .clk(clk), .rst(rst), - .encoded_rx_data(SCRAMBLER_DISABLE ? serdes_rx_data_int : encoded_rx_data_reg), - .encoded_rx_hdr(SCRAMBLER_DISABLE ? serdes_rx_hdr_int : encoded_rx_hdr_reg), + .encoded_rx_data(encoded_rx_data_reg), + .encoded_rx_hdr(encoded_rx_hdr_reg), .xgmii_rxd(xgmii_rxd), .xgmii_rxc(xgmii_rxc), .rx_bad_block() From 9ae60dcd9a994c9ecb6f49c6199b645efeab18fd Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 22 Jan 2019 14:22:01 -0800 Subject: [PATCH 513/617] Simplify lane swapping code --- rtl/axis_xgmii_tx_64.v | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index 1b6f10630..b85baae29 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -648,24 +648,14 @@ always @(posedge clk) begin s_axis_tready_reg <= s_axis_tready_next; - if (lanes_swapped) begin - if (unswap_lanes) begin - lanes_swapped <= 1'b0; - xgmii_txd_reg <= xgmii_txd_next; - xgmii_txc_reg <= xgmii_txc_next; - end else begin - xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd}; - xgmii_txc_reg <= {xgmii_txc_next[3:0], swap_txc}; - end + if (swap_lanes || (lanes_swapped && !unswap_lanes)) begin + lanes_swapped <= 1'b1; + xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd}; + xgmii_txc_reg <= {xgmii_txc_next[3:0], swap_txc}; end else begin - if (swap_lanes) begin - lanes_swapped <= 1'b1; - xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd}; - xgmii_txc_reg <= {xgmii_txc_next[3:0], swap_txc}; - end else begin - xgmii_txd_reg <= xgmii_txd_next; - xgmii_txc_reg <= xgmii_txc_next; - end + lanes_swapped <= 1'b0; + xgmii_txd_reg <= xgmii_txd_next; + xgmii_txc_reg <= xgmii_txc_next; end // datapath From 92df3778ea3e8c3448b2de3bd60d1afa2035c4b5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 22 Jan 2019 14:23:29 -0800 Subject: [PATCH 514/617] Fix DIC implementation in testbench --- tb/baser_serdes_ep.py | 4 ++-- tb/xgmii_ep.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tb/baser_serdes_ep.py b/tb/baser_serdes_ep.py index f975c9885..3589c583d 100644 --- a/tb/baser_serdes_ep.py +++ b/tb/baser_serdes_ep.py @@ -144,7 +144,7 @@ class BaseRSerdesSource(object): data = 0x000000000000001e header = 0b01 - if (ifg_cnt > bw-1 and self.enable_dic) or ifg_cnt > 0: + if ifg_cnt > bw-1 or (not self.enable_dic and ifg_cnt > 0): ifg_cnt = max(ifg_cnt - bw, 0) elif ccl: header, data = ccl.pop(0) @@ -172,7 +172,7 @@ class BaseRSerdesSource(object): dl = [XGMII_IDLE]*4+dl cl = [1]*4+cl - deficit_idle_cnt = ifg_cnt + deficit_idle_cnt = max(ifg_cnt, 0) ifg_cnt = 0 # pad length to multiple of 8 by adding idles diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 9778084e6..74eb9a33d 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -174,7 +174,7 @@ class XGMIISource(object): ifg_cnt = 0 deficit_idle_cnt = 0 elif enable: - if (ifg_cnt > bw-1 and self.enable_dic) or ifg_cnt > 0: + if ifg_cnt > bw-1 or (not self.enable_dic and ifg_cnt > 0): ifg_cnt = max(ifg_cnt - bw, 0) txd.next = 0x0707070707070707 if bw == 8 else 0x07070707 txc.next = 0xff if bw == 8 else 0xf @@ -212,7 +212,7 @@ class XGMIISource(object): dl = [XGMII_IDLE]*4+dl cl = [1]*4+cl - deficit_idle_cnt = ifg_cnt + deficit_idle_cnt = max(ifg_cnt, 0) ifg_cnt = 0 d = 0 From 4d2090a1a5e581ab057588dba8e16c79c9706257 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 22 Jan 2019 14:24:35 -0800 Subject: [PATCH 515/617] Fix off-by-one error in control character checks --- tb/baser_serdes_ep.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tb/baser_serdes_ep.py b/tb/baser_serdes_ep.py index 3589c583d..8c410f5ce 100644 --- a/tb/baser_serdes_ep.py +++ b/tb/baser_serdes_ep.py @@ -286,32 +286,32 @@ class BaseRSerdesSource(object): elif ci[1] and di[1] == XGMII_TERM and not ci[0]: # terminate in lane 1 d = BLOCK_TYPE_TERM_1 | (ctrl & 0xffffffffffc000) << 8 | di[0] << 8 - elif ci[2] and di[2] == XGMII_TERM and not any(ci[0:1]): + elif ci[2] and di[2] == XGMII_TERM and not any(ci[0:2]): # terminate in lane 2 d = BLOCK_TYPE_TERM_2 | (ctrl & 0xffffffffe00000) << 8 for i in range(2): d |= di[i] << ((i+1)*8) - elif ci[3] and di[3] == XGMII_TERM and not any(ci[0:2]): + elif ci[3] and di[3] == XGMII_TERM and not any(ci[0:3]): # terminate in lane 3 d = BLOCK_TYPE_TERM_3 | (ctrl & 0xfffffff0000000) << 8 for i in range(3): d |= di[i] << ((i+1)*8) - elif ci[4] and di[4] == XGMII_TERM and not any(ci[0:3]): + elif ci[4] and di[4] == XGMII_TERM and not any(ci[0:4]): # terminate in lane 4 d = BLOCK_TYPE_TERM_4 | (ctrl & 0xfffff800000000) << 8 for i in range(4): d |= di[i] << ((i+1)*8) - elif ci[5] and di[5] == XGMII_TERM and not any(ci[0:4]): + elif ci[5] and di[5] == XGMII_TERM and not any(ci[0:5]): # terminate in lane 5 d = BLOCK_TYPE_TERM_5 | (ctrl & 0xfffc0000000000) << 8 for i in range(5): d |= di[i] << ((i+1)*8) - elif ci[6] and di[6] == XGMII_TERM and not any(ci[0:5]): + elif ci[6] and di[6] == XGMII_TERM and not any(ci[0:6]): # terminate in lane 6 d = BLOCK_TYPE_TERM_6 | (ctrl & 0xfe000000000000) << 8 for i in range(6): d |= di[i] << ((i+1)*8) - elif ci[7] and di[7] == XGMII_TERM and not any(ci[0:6]): + elif ci[7] and di[7] == XGMII_TERM and not any(ci[0:7]): # terminate in lane 7 d = BLOCK_TYPE_TERM_7 for i in range(7): From 5b2d4fd46564a86905c40904a1dbe7ed34a6e11f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 22 Jan 2019 18:46:34 -0800 Subject: [PATCH 516/617] Add force offset start parameter --- tb/baser_serdes_ep.py | 3 ++- tb/xgmii_ep.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tb/baser_serdes_ep.py b/tb/baser_serdes_ep.py index 8c410f5ce..2dbd16bbc 100644 --- a/tb/baser_serdes_ep.py +++ b/tb/baser_serdes_ep.py @@ -101,6 +101,7 @@ class BaseRSerdesSource(object): self.queue = [] self.ifg = ifg self.enable_dic = enable_dic + self.force_offset_start = False def send(self, frame): self.queue.append(xgmii_ep.XGMIIFrame(frame)) @@ -167,7 +168,7 @@ class BaseRSerdesSource(object): dl.append(XGMII_TERM) cl.append(1) - if bw == 8 and ifg_cnt >= 4: + if (bw == 8 and ifg_cnt >= 4) or self.force_offset_start: ifg_cnt = max(ifg_cnt-4, 0) dl = [XGMII_IDLE]*4+dl cl = [1]*4+cl diff --git a/tb/xgmii_ep.py b/tb/xgmii_ep.py index 74eb9a33d..6191cb32a 100644 --- a/tb/xgmii_ep.py +++ b/tb/xgmii_ep.py @@ -126,6 +126,7 @@ class XGMIISource(object): self.queue = [] self.ifg = ifg self.enable_dic = enable_dic + self.force_offset_start = False def send(self, frame): self.queue.append(XGMIIFrame(frame)) @@ -207,7 +208,7 @@ class XGMIISource(object): dl.append(XGMII_TERM) cl.append(1) - if bw == 8 and ifg_cnt >= 4: + if (bw == 8 and ifg_cnt >= 4) or self.force_offset_start: ifg_cnt = max(ifg_cnt-4, 0) dl = [XGMII_IDLE]*4+dl cl = [1]*4+cl From a743f6f789a095105bf0ea21e60dc149c9eca434 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 22 Jan 2019 18:47:32 -0800 Subject: [PATCH 517/617] Add zero IFG forced offset start test --- tb/test_axis_xgmii_rx_64.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tb/test_axis_xgmii_rx_64.py b/tb/test_axis_xgmii_rx_64.py index 9cb96467f..ba972ce0c 100755 --- a/tb/test_axis_xgmii_rx_64.py +++ b/tb/test_axis_xgmii_rx_64.py @@ -384,6 +384,41 @@ def bench(): yield delay(100) + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 6: test stream with zero IFG and offset start, length %d" % payload_len) + current_test.next = 6 + + source.ifg = 0 + source.force_offset_start = True + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + source.ifg = 12 + source.force_offset_start = False + + yield delay(100) + yield clk.posedge print("test 7: Ensure 0xfb in FCS in lane 4 is not detected as start code in lane 0") current_test.next = 7 From e644ce3895e1d1a3e8864b6777c6ef8768efd34d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 31 Jan 2019 17:00:23 -0800 Subject: [PATCH 518/617] Add start packet strobe timing outputs to MAC modules --- rtl/axis_gmii_rx.v | 7 +++++++ rtl/axis_gmii_tx.v | 18 +++++++++++++++++- rtl/axis_xgmii_rx_32.v | 7 +++++++ rtl/axis_xgmii_rx_64.v | 12 ++++++++++++ rtl/axis_xgmii_tx_32.v | 18 +++++++++++++++++- rtl/axis_xgmii_tx_64.v | 25 ++++++++++++++++++++++++- rtl/eth_mac_10g.v | 18 ++++++++++++++++-- rtl/eth_mac_1g.v | 6 +++++- tb/test_axis_gmii_rx.py | 2 ++ tb/test_axis_gmii_rx.v | 3 +++ tb/test_axis_gmii_tx.py | 5 ++++- tb/test_axis_gmii_tx.v | 7 +++++-- tb/test_axis_xgmii_rx_32.py | 2 ++ tb/test_axis_xgmii_rx_32.v | 3 +++ tb/test_axis_xgmii_rx_64.py | 4 ++++ tb/test_axis_xgmii_rx_64.v | 6 ++++++ tb/test_axis_xgmii_tx_32.py | 5 ++++- tb/test_axis_xgmii_tx_32.v | 7 +++++-- tb/test_axis_xgmii_tx_64.py | 7 ++++++- tb/test_axis_xgmii_tx_64.v | 10 ++++++++-- tb/test_eth_mac_10g_32.py | 8 ++++++++ tb/test_eth_mac_10g_32.v | 12 ++++++++++++ tb/test_eth_mac_10g_64.py | 8 ++++++++ tb/test_eth_mac_10g_64.v | 12 ++++++++++++ tb/test_eth_mac_1g.py | 4 ++++ tb/test_eth_mac_1g.v | 6 ++++++ 26 files changed, 207 insertions(+), 15 deletions(-) diff --git a/rtl/axis_gmii_rx.v b/rtl/axis_gmii_rx.v index 37c11be7e..c6a52f655 100644 --- a/rtl/axis_gmii_rx.v +++ b/rtl/axis_gmii_rx.v @@ -58,6 +58,7 @@ module axis_gmii_rx /* * Status */ + output wire start_packet, output wire error_bad_frame, output wire error_bad_fcs ); @@ -103,6 +104,7 @@ reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; +reg start_packet_reg = 1'b0, start_packet_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; @@ -114,6 +116,7 @@ assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; assign m_axis_tuser = m_axis_tuser_reg; +assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; @@ -144,6 +147,7 @@ always @* begin m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; + start_packet_next = 1'b0; error_bad_frame_next = 1'b0; error_bad_fcs_next = 1'b0; @@ -160,6 +164,7 @@ always @* begin reset_crc = 1'b1; if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == ETH_SFD) begin + start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end else begin state_next = STATE_IDLE; @@ -218,6 +223,7 @@ always @(posedge clk) begin m_axis_tvalid_reg <= 1'b0; + start_packet_reg <= 1'b0; error_bad_frame_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; @@ -236,6 +242,7 @@ always @(posedge clk) begin m_axis_tvalid_reg <= m_axis_tvalid_next; + start_packet_reg <= start_packet_next; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index 7fa2d7ed0..8f0316c69 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -63,7 +63,12 @@ module axis_gmii_tx # /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay, + + /* + * Status + */ + output wire start_packet ); localparam [7:0] @@ -99,6 +104,8 @@ reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +reg start_packet_reg = 1'b0, start_packet_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; @@ -108,6 +115,8 @@ assign gmii_txd = gmii_txd_reg; assign gmii_tx_en = gmii_tx_en_reg; assign gmii_tx_er = gmii_tx_er_reg; +assign start_packet = start_packet_reg; + lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), @@ -143,6 +152,8 @@ always @* begin gmii_tx_en_next = 1'b0; gmii_tx_er_next = 1'b0; + start_packet_next = 1'b0; + if (!clk_enable) begin // clock disabled - hold state and outputs gmii_txd_next = gmii_txd_reg; @@ -195,6 +206,7 @@ always @* begin s_tdata_next = s_axis_tdata; end gmii_txd_next = ETH_SFD; + start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end else begin state_next = STATE_PREAMBLE; @@ -351,6 +363,8 @@ always @(posedge clk) begin gmii_tx_en_reg <= 1'b0; gmii_tx_er_reg <= 1'b0; + start_packet_reg <= 1'b0; + crc_state <= 32'hFFFFFFFF; end else begin state_reg <= state_next; @@ -362,6 +376,8 @@ always @(posedge clk) begin gmii_tx_en_reg <= gmii_tx_en_next; gmii_tx_er_reg <= gmii_tx_er_next; + start_packet_reg <= start_packet_next; + // datapath if (reset_crc) begin crc_state <= 32'hFFFFFFFF; diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index f27730bba..5710b7d26 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -52,6 +52,7 @@ module axis_xgmii_rx_32 /* * Status */ + output wire start_packet, output wire error_bad_frame, output wire error_bad_fcs ); @@ -94,6 +95,7 @@ reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; +reg start_packet_reg = 1'b0, start_packet_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; @@ -120,6 +122,7 @@ assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; assign m_axis_tuser = m_axis_tuser_reg; +assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; @@ -260,6 +263,7 @@ always @* begin m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; + start_packet_next = 1'b0; error_bad_frame_next = 1'b0; error_bad_fcs_next = 1'b0; @@ -291,6 +295,7 @@ always @* begin STATE_PREAMBLE: begin // drop preamble update_crc = 1'b1; + start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end STATE_PAYLOAD: begin @@ -364,6 +369,7 @@ always @(posedge clk) begin m_axis_tvalid_reg <= 1'b0; + start_packet_reg <= 1'b0; error_bad_frame_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; @@ -380,6 +386,7 @@ always @(posedge clk) begin m_axis_tvalid_reg <= m_axis_tvalid_next; + start_packet_reg <= start_packet_next; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index 9bbe6d29a..f91ac9b39 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -52,6 +52,8 @@ module axis_xgmii_rx_64 /* * Status */ + output wire start_packet_0, + output wire start_packet_4, output wire error_bad_frame, output wire error_bad_fcs ); @@ -96,6 +98,8 @@ reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; +reg start_packet_0_reg = 1'b0; +reg start_packet_4_reg = 1'b0; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; @@ -122,6 +126,8 @@ assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; assign m_axis_tuser = m_axis_tuser_reg; +assign start_packet_0 = start_packet_0_reg; +assign start_packet_4 = start_packet_4_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; @@ -419,6 +425,8 @@ always @(posedge clk) begin m_axis_tvalid_reg <= 1'b0; + start_packet_0_reg <= 1'b0; + start_packet_4_reg <= 1'b0; error_bad_frame_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; @@ -435,14 +443,18 @@ always @(posedge clk) begin m_axis_tvalid_reg <= m_axis_tvalid_next; + start_packet_0_reg <= 1'b0; + start_packet_4_reg <= 1'b0; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin lanes_swapped <= 1'b0; + start_packet_0_reg <= 1'b1; xgmii_rxc_d0 <= xgmii_rxc; end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin lanes_swapped <= 1'b1; + start_packet_4_reg <= 1'b1; xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; end else if (lanes_swapped) begin xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index 9fa3e41ac..7c8ab7d9e 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -58,7 +58,12 @@ module axis_xgmii_tx_32 # /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay, + + /* + * Status + */ + output wire start_packet ); localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; @@ -123,11 +128,15 @@ wire [31:0] crc_next3; reg [31:0] xgmii_txd_reg = {4{XGMII_IDLE}}, xgmii_txd_next; reg [3:0] xgmii_txc_reg = 4'b1111, xgmii_txc_next; +reg start_packet_reg = 1'b0, start_packet_next; + assign s_axis_tready = s_axis_tready_reg; assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; +assign start_packet = start_packet_reg; + lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), @@ -278,6 +287,8 @@ always @* begin xgmii_txd_next = {4{XGMII_IDLE}}; xgmii_txc_next = 4'b1111; + start_packet_next = 1'b0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data @@ -312,6 +323,7 @@ always @* begin xgmii_txd_next = {ETH_SFD, {3{ETH_PRE}}}; xgmii_txc_next = 4'b0000; s_axis_tready_next = 1'b1; + start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end STATE_PAYLOAD: begin @@ -519,6 +531,8 @@ always @(posedge clk) begin xgmii_txd_reg <= {4{XGMII_IDLE}}; xgmii_txc_reg <= 4'b1111; + start_packet_reg <= 1'b0; + crc_state <= 32'hFFFFFFFF; end else begin state_reg <= state_next; @@ -533,6 +547,8 @@ always @(posedge clk) begin xgmii_txd_reg <= xgmii_txd_next; xgmii_txc_reg <= xgmii_txc_next; + start_packet_reg <= start_packet_next; + // datapath if (reset_crc) begin crc_state <= 32'hFFFFFFFF; diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index b85baae29..e6f8c2569 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -58,7 +58,13 @@ module axis_xgmii_tx_64 # /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay, + + /* + * Status + */ + output wire start_packet_0, + output wire start_packet_4 ); localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; @@ -132,11 +138,17 @@ wire [31:0] crc_next7; reg [63:0] xgmii_txd_reg = {8{XGMII_IDLE}}, xgmii_txd_next; reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; +reg start_packet_0_reg = 1'b0, start_packet_0_next; +reg start_packet_4_reg = 1'b0, start_packet_4_next; + assign s_axis_tready = s_axis_tready_reg; assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; +assign start_packet_0 = start_packet_0_reg; +assign start_packet_4 = start_packet_4_reg; + lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), @@ -390,6 +402,9 @@ always @* begin xgmii_txd_next = {8{XGMII_IDLE}}; xgmii_txc_next = 8'b11111111; + start_packet_0_next = 1'b0; + start_packet_4_next = 1'b0; + case (state_reg) STATE_IDLE: begin // idle state - wait for data @@ -409,9 +424,11 @@ always @* begin if (ifg_count_reg > 8'd0) begin // need to send more idles - swap lanes swap_lanes = 1'b1; + start_packet_4_next = 1'b1; end else begin // no more idles - unswap unswap_lanes = 1'b1; + start_packet_0_next = 1'b1; end xgmii_txd_next = {ETH_SFD, {6{ETH_PRE}}, XGMII_START}; xgmii_txc_next = 8'b00000001; @@ -635,6 +652,9 @@ always @(posedge clk) begin xgmii_txd_reg <= {8{XGMII_IDLE}}; xgmii_txc_reg <= 8'b11111111; + start_packet_0_reg <= 1'b0; + start_packet_4_reg <= 1'b0; + crc_state <= 32'hFFFFFFFF; lanes_swapped <= 1'b0; @@ -648,6 +668,9 @@ always @(posedge clk) begin s_axis_tready_reg <= s_axis_tready_next; + start_packet_0_reg <= start_packet_0_next; + start_packet_4_reg <= start_packet_4_next; + if (swap_lanes || (lanes_swapped && !unswap_lanes)) begin lanes_swapped <= 1'b1; xgmii_txd_reg <= {xgmii_txd_next[31:0], swap_txd}; diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index 1d0b78515..89f368744 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -74,6 +74,10 @@ module eth_mac_10g # /* * Status */ + output wire tx_start_packet_0, + output wire tx_start_packet_4, + output wire rx_start_packet_0, + output wire rx_start_packet_4, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, @@ -111,6 +115,8 @@ axis_xgmii_rx_inst ( .m_axis_tvalid(rx_axis_tvalid), .m_axis_tlast(rx_axis_tlast), .m_axis_tuser(rx_axis_tuser), + .start_packet_0(rx_start_packet_0), + .start_packet_4(rx_start_packet_4), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); @@ -131,7 +137,9 @@ axis_xgmii_tx_inst ( .s_axis_tuser(tx_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), - .ifg_delay(ifg_delay) + .ifg_delay(ifg_delay), + .start_packet_0(tx_start_packet_0), + .start_packet_4(tx_start_packet_4) ); end else begin @@ -147,10 +155,13 @@ axis_xgmii_rx_inst ( .m_axis_tvalid(rx_axis_tvalid), .m_axis_tlast(rx_axis_tlast), .m_axis_tuser(rx_axis_tuser), + .start_packet(rx_start_packet_0), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); +assign tx_start_packet_4 = 1'b0; + axis_xgmii_tx_32 #( .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), @@ -167,9 +178,12 @@ axis_xgmii_tx_inst ( .s_axis_tuser(tx_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), - .ifg_delay(ifg_delay) + .ifg_delay(ifg_delay), + .start_packet(tx_start_packet_0) ); +assign rx_start_packet_4 = 1'b0; + end endgenerate diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v index ceb134b66..727406cc3 100644 --- a/rtl/eth_mac_1g.v +++ b/rtl/eth_mac_1g.v @@ -78,6 +78,8 @@ module eth_mac_1g # /* * Status */ + output wire tx_start_packet, + output wire rx_start_packet, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, @@ -100,6 +102,7 @@ axis_gmii_rx_inst ( .m_axis_tuser(rx_axis_tuser), .clk_enable(rx_clk_enable), .mii_select(rx_mii_select), + .start_packet(rx_start_packet), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); @@ -121,7 +124,8 @@ axis_gmii_tx_inst ( .gmii_tx_er(gmii_tx_er), .clk_enable(tx_clk_enable), .mii_select(tx_mii_select), - .ifg_delay(ifg_delay) + .ifg_delay(ifg_delay), + .start_packet(tx_start_packet) ); endmodule diff --git a/tb/test_axis_gmii_rx.py b/tb/test_axis_gmii_rx.py index 4c2c52af4..dbf93f16b 100755 --- a/tb/test_axis_gmii_rx.py +++ b/tb/test_axis_gmii_rx.py @@ -64,6 +64,7 @@ def bench(): m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) m_axis_tuser = Signal(bool(0)) + start_packet = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -115,6 +116,7 @@ def bench(): clk_enable=clk_enable, mii_select=mii_select, + start_packet=start_packet, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs ) diff --git a/tb/test_axis_gmii_rx.v b/tb/test_axis_gmii_rx.v index 60ec7d29f..af28a9a77 100644 --- a/tb/test_axis_gmii_rx.v +++ b/tb/test_axis_gmii_rx.v @@ -50,6 +50,7 @@ wire [7:0] m_axis_tdata; wire m_axis_tvalid; wire m_axis_tlast; wire m_axis_tuser; +wire start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -70,6 +71,7 @@ initial begin m_axis_tvalid, m_axis_tlast, m_axis_tuser, + start_packet, error_bad_frame, error_bad_fcs ); @@ -92,6 +94,7 @@ UUT ( .m_axis_tuser(m_axis_tuser), .clk_enable(clk_enable), .mii_select(mii_select), + .start_packet(start_packet), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs) ); diff --git a/tb/test_axis_gmii_tx.py b/tb/test_axis_gmii_tx.py index ab0e62597..aa36f80f1 100755 --- a/tb/test_axis_gmii_tx.py +++ b/tb/test_axis_gmii_tx.py @@ -67,6 +67,7 @@ def bench(): gmii_txd = Signal(intbv(0)[8:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) + start_packet = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -121,7 +122,9 @@ def bench(): clk_enable=clk_enable, mii_select=mii_select, - ifg_delay=ifg_delay + ifg_delay=ifg_delay, + + start_packet=start_packet ) @always(delay(4)) diff --git a/tb/test_axis_gmii_tx.v b/tb/test_axis_gmii_tx.v index 8224d7971..e15d19467 100644 --- a/tb/test_axis_gmii_tx.v +++ b/tb/test_axis_gmii_tx.v @@ -53,6 +53,7 @@ wire s_axis_tready; wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; +wire start_packet; initial begin // myhdl integration @@ -72,7 +73,8 @@ initial begin s_axis_tready, gmii_txd, gmii_tx_en, - gmii_tx_er + gmii_tx_er, + start_packet ); // dump file @@ -97,7 +99,8 @@ UUT ( .gmii_tx_er(gmii_tx_er), .clk_enable(clk_enable), .mii_select(mii_select), - .ifg_delay(ifg_delay) + .ifg_delay(ifg_delay), + .start_packet(start_packet) ); endmodule diff --git a/tb/test_axis_xgmii_rx_32.py b/tb/test_axis_xgmii_rx_32.py index 291eab65a..0e12f2aae 100755 --- a/tb/test_axis_xgmii_rx_32.py +++ b/tb/test_axis_xgmii_rx_32.py @@ -62,6 +62,7 @@ def bench(): m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) m_axis_tuser = Signal(bool(0)) + start_packet = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -108,6 +109,7 @@ def bench(): m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, + start_packet=start_packet, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs ) diff --git a/tb/test_axis_xgmii_rx_32.v b/tb/test_axis_xgmii_rx_32.v index 12681e6ca..828f034d8 100644 --- a/tb/test_axis_xgmii_rx_32.v +++ b/tb/test_axis_xgmii_rx_32.v @@ -47,6 +47,7 @@ wire [3:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; wire m_axis_tuser; +wire start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -65,6 +66,7 @@ initial begin m_axis_tvalid, m_axis_tlast, m_axis_tuser, + start_packet, error_bad_frame, error_bad_fcs ); @@ -85,6 +87,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .start_packet(start_packet), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs) ); diff --git a/tb/test_axis_xgmii_rx_64.py b/tb/test_axis_xgmii_rx_64.py index ba972ce0c..16a7a2d7a 100755 --- a/tb/test_axis_xgmii_rx_64.py +++ b/tb/test_axis_xgmii_rx_64.py @@ -62,6 +62,8 @@ def bench(): m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) m_axis_tuser = Signal(bool(0)) + start_packet_0 = Signal(bool(0)) + start_packet_4 = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -108,6 +110,8 @@ def bench(): m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, + start_packet_0=start_packet_0, + start_packet_4=start_packet_4, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs ) diff --git a/tb/test_axis_xgmii_rx_64.v b/tb/test_axis_xgmii_rx_64.v index 700660a65..fdafb2431 100644 --- a/tb/test_axis_xgmii_rx_64.v +++ b/tb/test_axis_xgmii_rx_64.v @@ -47,6 +47,8 @@ wire [7:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; wire m_axis_tuser; +wire start_packet_0; +wire start_packet_4; wire error_bad_frame; wire error_bad_fcs; @@ -65,6 +67,8 @@ initial begin m_axis_tvalid, m_axis_tlast, m_axis_tuser, + start_packet_0, + start_packet_4, error_bad_frame, error_bad_fcs ); @@ -85,6 +89,8 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .start_packet_0(start_packet_0), + .start_packet_4(start_packet_4), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs) ); diff --git a/tb/test_axis_xgmii_tx_32.py b/tb/test_axis_xgmii_tx_32.py index f0f480148..86fa63b9e 100755 --- a/tb/test_axis_xgmii_tx_32.py +++ b/tb/test_axis_xgmii_tx_32.py @@ -65,6 +65,7 @@ def bench(): s_axis_tready = Signal(bool(0)) xgmii_txd = Signal(intbv(0x07070707)[32:]) xgmii_txc = Signal(intbv(0xf)[4:]) + start_packet = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -114,7 +115,9 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, - ifg_delay=ifg_delay + ifg_delay=ifg_delay, + + start_packet=start_packet ) @always(delay(4)) diff --git a/tb/test_axis_xgmii_tx_32.v b/tb/test_axis_xgmii_tx_32.v index c59c69425..aa783804d 100644 --- a/tb/test_axis_xgmii_tx_32.v +++ b/tb/test_axis_xgmii_tx_32.v @@ -51,6 +51,7 @@ reg [7:0] ifg_delay = 0; wire s_axis_tready; wire [31:0] xgmii_txd; wire [3:0] xgmii_txc; +wire start_packet; initial begin // myhdl integration @@ -68,7 +69,8 @@ initial begin $to_myhdl( s_axis_tready, xgmii_txd, - xgmii_txc + xgmii_txc, + start_packet ); // dump file @@ -91,7 +93,8 @@ UUT ( .s_axis_tuser(s_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), - .ifg_delay(ifg_delay) + .ifg_delay(ifg_delay), + .start_packet(start_packet) ); endmodule diff --git a/tb/test_axis_xgmii_tx_64.py b/tb/test_axis_xgmii_tx_64.py index 58918b240..e4b7ee3ed 100755 --- a/tb/test_axis_xgmii_tx_64.py +++ b/tb/test_axis_xgmii_tx_64.py @@ -65,6 +65,8 @@ def bench(): s_axis_tready = Signal(bool(0)) xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) xgmii_txc = Signal(intbv(0xff)[8:]) + start_packet_0 = Signal(bool(0)) + start_packet_4 = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -114,7 +116,10 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, - ifg_delay=ifg_delay + ifg_delay=ifg_delay, + + start_packet_0=start_packet_0, + start_packet_4=start_packet_4 ) @always(delay(4)) diff --git a/tb/test_axis_xgmii_tx_64.v b/tb/test_axis_xgmii_tx_64.v index 6a46d8cae..6ac8654c2 100644 --- a/tb/test_axis_xgmii_tx_64.v +++ b/tb/test_axis_xgmii_tx_64.v @@ -51,6 +51,8 @@ reg [7:0] ifg_delay = 0; wire s_axis_tready; wire [63:0] xgmii_txd; wire [7:0] xgmii_txc; +wire start_packet_0; +wire start_packet_4; initial begin // myhdl integration @@ -68,7 +70,9 @@ initial begin $to_myhdl( s_axis_tready, xgmii_txd, - xgmii_txc + xgmii_txc, + start_packet_0, + start_packet_4 ); // dump file @@ -91,7 +95,9 @@ UUT ( .s_axis_tuser(s_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), - .ifg_delay(ifg_delay) + .ifg_delay(ifg_delay), + .start_packet_0(start_packet_0), + .start_packet_4(start_packet_4) ); endmodule diff --git a/tb/test_eth_mac_10g_32.py b/tb/test_eth_mac_10g_32.py index 04112b47b..305db04a6 100755 --- a/tb/test_eth_mac_10g_32.py +++ b/tb/test_eth_mac_10g_32.py @@ -82,6 +82,10 @@ def bench(): rx_axis_tuser = Signal(bool(0)) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_start_packet_0 = Signal(bool(0)) + tx_start_packet_4 = Signal(bool(0)) + rx_start_packet_0 = Signal(bool(0)) + rx_start_packet_4 = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) @@ -170,6 +174,10 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + tx_start_packet_0=tx_start_packet_0, + tx_start_packet_4=tx_start_packet_4, + rx_start_packet_0=rx_start_packet_0, + rx_start_packet_4=rx_start_packet_4, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, diff --git a/tb/test_eth_mac_10g_32.v b/tb/test_eth_mac_10g_32.v index 62b55bfad..351cf9f44 100644 --- a/tb/test_eth_mac_10g_32.v +++ b/tb/test_eth_mac_10g_32.v @@ -66,6 +66,10 @@ wire rx_axis_tlast; wire rx_axis_tuser; wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; +wire tx_start_packet_0; +wire tx_start_packet_4; +wire rx_start_packet_0; +wire rx_start_packet_4; wire rx_error_bad_frame; wire rx_error_bad_fcs; @@ -97,6 +101,10 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, + tx_start_packet_0, + tx_start_packet_4, + rx_start_packet_0, + rx_start_packet_4, rx_error_bad_frame, rx_error_bad_fcs ); @@ -134,6 +142,10 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .tx_start_packet_0(tx_start_packet_0), + .tx_start_packet_4(tx_start_packet_4), + .rx_start_packet_0(rx_start_packet_0), + .rx_start_packet_4(rx_start_packet_4), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .ifg_delay(ifg_delay) diff --git a/tb/test_eth_mac_10g_64.py b/tb/test_eth_mac_10g_64.py index c21fe2a61..6dbd63b26 100755 --- a/tb/test_eth_mac_10g_64.py +++ b/tb/test_eth_mac_10g_64.py @@ -82,6 +82,10 @@ def bench(): rx_axis_tuser = Signal(bool(0)) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_start_packet_0 = Signal(bool(0)) + tx_start_packet_4 = Signal(bool(0)) + rx_start_packet_0 = Signal(bool(0)) + rx_start_packet_4 = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) @@ -170,6 +174,10 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + tx_start_packet_0=tx_start_packet_0, + tx_start_packet_4=tx_start_packet_4, + rx_start_packet_0=rx_start_packet_0, + rx_start_packet_4=rx_start_packet_4, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, diff --git a/tb/test_eth_mac_10g_64.v b/tb/test_eth_mac_10g_64.v index 608edfe45..6713d0564 100644 --- a/tb/test_eth_mac_10g_64.v +++ b/tb/test_eth_mac_10g_64.v @@ -66,6 +66,10 @@ wire rx_axis_tlast; wire rx_axis_tuser; wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; +wire tx_start_packet_0; +wire tx_start_packet_4; +wire rx_start_packet_0; +wire rx_start_packet_4; wire rx_error_bad_frame; wire rx_error_bad_fcs; @@ -97,6 +101,10 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, + tx_start_packet_0, + tx_start_packet_4, + rx_start_packet_0, + rx_start_packet_4, rx_error_bad_frame, rx_error_bad_fcs ); @@ -134,6 +142,10 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .tx_start_packet_0(tx_start_packet_0), + .tx_start_packet_4(tx_start_packet_4), + .rx_start_packet_0(rx_start_packet_0), + .rx_start_packet_4(rx_start_packet_4), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .ifg_delay(ifg_delay) diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index d0053099a..285c373df 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -82,6 +82,8 @@ def bench(): gmii_txd = Signal(intbv(0)[8:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) + tx_start_packet = Signal(bool(0)) + rx_start_packet = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) @@ -180,6 +182,8 @@ def bench(): rx_mii_select=rx_mii_select, tx_mii_select=tx_mii_select, + tx_start_packet=tx_start_packet, + rx_start_packet=rx_start_packet, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, diff --git a/tb/test_eth_mac_1g.v b/tb/test_eth_mac_1g.v index 387808879..12502af4e 100644 --- a/tb/test_eth_mac_1g.v +++ b/tb/test_eth_mac_1g.v @@ -66,6 +66,8 @@ wire rx_axis_tuser; wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; +wire tx_start_packet; +wire rx_start_packet; wire rx_error_bad_frame; wire rx_error_bad_fcs; @@ -101,6 +103,8 @@ initial begin gmii_txd, gmii_tx_en, gmii_tx_er, + tx_start_packet, + rx_start_packet, rx_error_bad_frame, rx_error_bad_fcs ); @@ -138,6 +142,8 @@ UUT ( .tx_clk_enable(tx_clk_enable), .rx_mii_select(rx_mii_select), .tx_mii_select(tx_mii_select), + .tx_start_packet(tx_start_packet), + .rx_start_packet(rx_start_packet), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .ifg_delay(ifg_delay) From 5f6e7f721cdf3d555ad595d6d3d47a3c937b7e1a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 31 Jan 2019 18:12:07 -0800 Subject: [PATCH 519/617] Update testbench --- example/ExaNIC_X10/fpga/rtl/fpga_core.v | 2 +- example/ExaNIC_X10/fpga/tb/test_fpga_core.py | 26 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/example/ExaNIC_X10/fpga/rtl/fpga_core.v b/example/ExaNIC_X10/fpga/rtl/fpga_core.v index b710b1de5..952c0f399 100644 --- a/example/ExaNIC_X10/fpga/rtl/fpga_core.v +++ b/example/ExaNIC_X10/fpga/rtl/fpga_core.v @@ -46,7 +46,7 @@ module fpga_core output wire [1:0] sma_led, /* - * Ethernet: QSFP28 + * Ethernet: SFP+ */ input wire sfp_1_tx_clk, input wire sfp_1_tx_rst, diff --git a/example/ExaNIC_X10/fpga/tb/test_fpga_core.py b/example/ExaNIC_X10/fpga/tb/test_fpga_core.py index 4880532a0..c4e47a956 100755 --- a/example/ExaNIC_X10/fpga/tb/test_fpga_core.py +++ b/example/ExaNIC_X10/fpga/tb/test_fpga_core.py @@ -81,15 +81,6 @@ def bench(): rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - sfp_1_txd = Signal(intbv(0)[64:]) - sfp_1_txc = Signal(intbv(0)[8:]) - sfp_2_txd = Signal(intbv(0)[64:]) - sfp_2_txc = Signal(intbv(0)[8:]) - - # Outputs - sfp_1_led = Signal(intbv(0)[2:]) - sfp_2_led = Signal(intbv(0)[2:]) - sma_led = Signal(intbv(0)[2:]) sfp_1_tx_clk = Signal(bool(0)) sfp_1_tx_rst = Signal(bool(0)) sfp_1_rx_clk = Signal(bool(0)) @@ -103,18 +94,27 @@ def bench(): sfp_2_rxd = Signal(intbv(0)[64:]) sfp_2_rxc = Signal(intbv(0)[8:]) + # Outputs + sfp_1_led = Signal(intbv(0)[2:]) + sfp_2_led = Signal(intbv(0)[2:]) + sma_led = Signal(intbv(0)[2:]) + sfp_1_txd = Signal(intbv(0)[64:]) + sfp_1_txc = Signal(intbv(0)[8:]) + sfp_2_txd = Signal(intbv(0)[64:]) + sfp_2_txc = Signal(intbv(0)[8:]) + # sources and sinks sfp_1_source = xgmii_ep.XGMIISource() - sfp_1_source_logic = sfp_1_source.create_logic(sfp_1_tx_clk, sfp_1_tx_rst, txd=sfp_1_rxd, txc=sfp_1_rxc, name='sfp_1_source') + sfp_1_source_logic = sfp_1_source.create_logic(sfp_1_rx_clk, sfp_1_rx_rst, txd=sfp_1_rxd, txc=sfp_1_rxc, name='sfp_1_source') sfp_1_sink = xgmii_ep.XGMIISink() - sfp_1_sink_logic = sfp_1_sink.create_logic(sfp_1_rx_clk, sfp_1_rx_rst, rxd=sfp_1_txd, rxc=sfp_1_txc, name='sfp_1_sink') + sfp_1_sink_logic = sfp_1_sink.create_logic(sfp_1_tx_clk, sfp_1_tx_rst, rxd=sfp_1_txd, rxc=sfp_1_txc, name='sfp_1_sink') sfp_2_source = xgmii_ep.XGMIISource() - sfp_2_source_logic = sfp_2_source.create_logic(sfp_2_tx_clk, sfp_2_tx_rst, txd=sfp_2_rxd, txc=sfp_2_rxc, name='sfp_2_source') + sfp_2_source_logic = sfp_2_source.create_logic(sfp_2_rx_clk, sfp_2_rx_rst, txd=sfp_2_rxd, txc=sfp_2_rxc, name='sfp_2_source') sfp_2_sink = xgmii_ep.XGMIISink() - sfp_2_sink_logic = sfp_2_sink.create_logic(sfp_2_rx_clk, sfp_2_rx_rst, rxd=sfp_2_txd, rxc=sfp_2_txc, name='sfp_2_sink') + sfp_2_sink_logic = sfp_2_sink.create_logic(sfp_2_tx_clk, sfp_2_tx_rst, rxd=sfp_2_txd, rxc=sfp_2_txc, name='sfp_2_sink') # DUT if os.system(build_cmd): From ec38440d89785c515b11d42b99ba7e1a866f2fcd Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 31 Jan 2019 18:13:07 -0800 Subject: [PATCH 520/617] Add 10G Ethernet MAC/PHY combination modules and testbenches --- rtl/axis_baser_rx_64.v | 574 +++++++++++++++++++++ rtl/axis_baser_tx_64.v | 848 ++++++++++++++++++++++++++++++++ rtl/eth_mac_phy_10g.v | 154 ++++++ rtl/eth_mac_phy_10g_fifo.v | 295 +++++++++++ rtl/eth_mac_phy_10g_rx.v | 187 +++++++ rtl/eth_mac_phy_10g_tx.v | 168 +++++++ tb/test_axis_baser_rx_64.py | 438 +++++++++++++++++ tb/test_axis_baser_rx_64.v | 105 ++++ tb/test_axis_baser_tx_64.py | 345 +++++++++++++ tb/test_axis_baser_tx_64.v | 111 +++++ tb/test_eth_mac_phy_10g.py | 320 ++++++++++++ tb/test_eth_mac_phy_10g.v | 173 +++++++ tb/test_eth_mac_phy_10g_fifo.py | 344 +++++++++++++ tb/test_eth_mac_phy_10g_fifo.v | 204 ++++++++ 14 files changed, 4266 insertions(+) create mode 100644 rtl/axis_baser_rx_64.v create mode 100644 rtl/axis_baser_tx_64.v create mode 100644 rtl/eth_mac_phy_10g.v create mode 100644 rtl/eth_mac_phy_10g_fifo.v create mode 100644 rtl/eth_mac_phy_10g_rx.v create mode 100644 rtl/eth_mac_phy_10g_tx.v create mode 100755 tb/test_axis_baser_rx_64.py create mode 100644 tb/test_axis_baser_rx_64.v create mode 100755 tb/test_axis_baser_tx_64.py create mode 100644 tb/test_axis_baser_tx_64.v create mode 100755 tb/test_eth_mac_phy_10g.py create mode 100644 tb/test_eth_mac_phy_10g.v create mode 100755 tb/test_eth_mac_phy_10g_fifo.py create mode 100644 tb/test_eth_mac_phy_10g_fifo.v diff --git a/rtl/axis_baser_rx_64.v b/rtl/axis_baser_rx_64.v new file mode 100644 index 000000000..8bc7072da --- /dev/null +++ b/rtl/axis_baser_rx_64.v @@ -0,0 +1,574 @@ +/* + +Copyright (c) 2019 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 10GBASE-R frame receiver (10GBASE-R in, AXI out) + */ +module axis_baser_rx_64 # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = 2 +) +( + input wire clk, + input wire rst, + + /* + * 10GBASE-R encoded input + */ + input wire [DATA_WIDTH-1:0] encoded_rx_data, + input wire [HDR_WIDTH-1:0] encoded_rx_hdr, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire m_axis_tuser, + + /* + * Status + */ + output wire start_packet_0, + output wire start_packet_4, + output wire error_bad_frame, + output wire error_bad_fcs +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end + + if (HDR_WIDTH != 2) begin + $error("Error: HDR_WIDTH must be 2"); + $finish; + end +end + +localparam [7:0] + ETH_PRE = 8'h55, + ETH_SFD = 8'hD5; + +localparam [7:0] + XGMII_IDLE = 8'h07, + XGMII_START = 8'hfb, + XGMII_TERM = 8'hfd, + XGMII_ERROR = 8'hfe; + +localparam [6:0] + CTRL_IDLE = 7'h00, + CTRL_LPI = 7'h06, + CTRL_ERROR = 7'h1e, + CTRL_RES_0 = 7'h2d, + CTRL_RES_1 = 7'h33, + CTRL_RES_2 = 7'h4b, + CTRL_RES_3 = 7'h55, + CTRL_RES_4 = 7'h66, + CTRL_RES_5 = 7'h78; + +localparam [3:0] + O_SEQ_OS = 4'h0, + O_SIG_OS = 4'hf; + +localparam [1:0] + SYNC_DATA = 2'b10, + SYNC_CTRL = 2'b01; + +localparam [7:0] + BLOCK_TYPE_CTRL = 8'h1e, // C7 C6 C5 C4 C3 C2 C1 C0 BT + BLOCK_TYPE_OS_4 = 8'h2d, // D7 D6 D5 O4 C3 C2 C1 C0 BT + BLOCK_TYPE_START_4 = 8'h33, // D7 D6 D5 C3 C2 C1 C0 BT + BLOCK_TYPE_OS_START = 8'h66, // D7 D6 D5 O0 D3 D2 D1 BT + BLOCK_TYPE_OS_04 = 8'h55, // D7 D6 D5 O4 O0 D3 D2 D1 BT + BLOCK_TYPE_START_0 = 8'h78, // D7 D6 D5 D4 D3 D2 D1 BT + BLOCK_TYPE_OS_0 = 8'h4b, // C7 C6 C5 C4 O0 D3 D2 D1 BT + BLOCK_TYPE_TERM_0 = 8'h87, // C7 C6 C5 C4 C3 C2 C1 BT + BLOCK_TYPE_TERM_1 = 8'h99, // C7 C6 C5 C4 C3 C2 D0 BT + BLOCK_TYPE_TERM_2 = 8'haa, // C7 C6 C5 C4 C3 D1 D0 BT + BLOCK_TYPE_TERM_3 = 8'hb4, // C7 C6 C5 C4 D2 D1 D0 BT + BLOCK_TYPE_TERM_4 = 8'hcc, // C7 C6 C5 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_5 = 8'hd2, // C7 C6 D4 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_6 = 8'he1, // C7 D5 D4 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_7 = 8'hff; // D6 D5 D4 D3 D2 D1 D0 BT + +localparam [3:0] + INPUT_TYPE_IDLE = 4'd0, + INPUT_TYPE_ERROR = 4'd1, + INPUT_TYPE_START_0 = 4'd2, + INPUT_TYPE_START_4 = 4'd3, + INPUT_TYPE_DATA = 4'd4, + INPUT_TYPE_TERM_0 = 4'd8, + INPUT_TYPE_TERM_1 = 4'd9, + INPUT_TYPE_TERM_2 = 4'd10, + INPUT_TYPE_TERM_3 = 4'd11, + INPUT_TYPE_TERM_4 = 4'd12, + INPUT_TYPE_TERM_5 = 4'd13, + INPUT_TYPE_TERM_6 = 4'd14, + INPUT_TYPE_TERM_7 = 4'd15; + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PAYLOAD = 3'd1, + STATE_LAST = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg lanes_swapped = 1'b0; +reg [31:0] swap_data = 32'd0; + +reg delay_type_valid = 1'b0; +reg [3:0] delay_type = INPUT_TYPE_IDLE; + +reg [DATA_WIDTH-1:0] input_data_d0 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] input_data_d1 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] input_data_crc = {DATA_WIDTH{1'b0}}; + +reg [3:0] input_type_d0 = INPUT_TYPE_IDLE; +reg [3:0] input_type_d1 = INPUT_TYPE_IDLE; + +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, m_axis_tkeep_next; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; +reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; + +reg start_packet_0_reg = 1'b0; +reg start_packet_4_reg = 1'b0; +reg error_bad_frame_reg = 1'b0, error_bad_frame_next; +reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; +reg [31:0] crc_state3 = 32'hFFFFFFFF; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; +wire [31:0] crc_next7; + +wire crc_valid0 = crc_next0 == ~32'h2144df1c; +wire crc_valid1 = crc_next1 == ~32'h2144df1c; +wire crc_valid2 = crc_next2 == ~32'h2144df1c; +wire crc_valid3 = crc_next3 == ~32'h2144df1c; +wire crc_valid7 = crc_next7 == ~32'h2144df1c; + +reg crc_valid7_save = 1'b0; + +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = m_axis_tkeep_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; + +assign start_packet_0 = start_packet_0_reg; +assign start_packet_4 = start_packet_4_reg; +assign error_bad_frame = error_bad_frame_reg; +assign error_bad_fcs = error_bad_fcs_reg; + +wire last_cycle = state_reg == STATE_LAST; + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(8), + .STYLE("AUTO") +) +eth_crc_8 ( + .data_in(input_data_crc[7:0]), + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next0) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(16), + .STYLE("AUTO") +) +eth_crc_16 ( + .data_in(input_data_crc[15:0]), + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next1) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(24), + .STYLE("AUTO") +) +eth_crc_24 ( + .data_in(input_data_crc[23:0]), + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next2) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( + .data_in(input_data_crc[31:0]), + .state_in(last_cycle ? crc_state3 : crc_state), + .data_out(), + .state_out(crc_next3) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(64), + .STYLE("AUTO") +) +eth_crc_64 ( + .data_in(input_data_d0[63:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next7) +); + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 1'b0; + update_crc = 1'b0; + + m_axis_tdata_next = input_data_d1; + m_axis_tkeep_next = 8'd0; + m_axis_tvalid_next = 1'b0; + m_axis_tlast_next = 1'b0; + m_axis_tuser_next = 1'b0; + + error_bad_frame_next = 1'b0; + error_bad_fcs_next = 1'b0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for packet + reset_crc = 1'b1; + + if (input_type_d1 == INPUT_TYPE_START_0) begin + // start condition + reset_crc = 1'b0; + update_crc = 1'b1; + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // read payload + update_crc = 1'b1; + + m_axis_tdata_next = input_data_d1; + m_axis_tkeep_next = 8'hff; + m_axis_tvalid_next = 1'b1; + m_axis_tlast_next = 1'b0; + m_axis_tuser_next = 1'b0; + + if (input_type_d0 == INPUT_TYPE_DATA) begin + state_next = STATE_PAYLOAD; + end else if (input_type_d0[3]) begin + // INPUT_TYPE_TERM_* + if (input_type_d0 <= INPUT_TYPE_TERM_4) begin + // end this cycle + reset_crc = 1'b1; + case (input_type_d0) + INPUT_TYPE_TERM_0: m_axis_tkeep_next = 8'b00001111; + INPUT_TYPE_TERM_1: m_axis_tkeep_next = 8'b00011111; + INPUT_TYPE_TERM_2: m_axis_tkeep_next = 8'b00111111; + INPUT_TYPE_TERM_3: m_axis_tkeep_next = 8'b01111111; + INPUT_TYPE_TERM_4: m_axis_tkeep_next = 8'b11111111; + endcase + m_axis_tlast_next = 1'b1; + if ((input_type_d0 == INPUT_TYPE_TERM_0 && crc_valid7_save) || + (input_type_d0 == INPUT_TYPE_TERM_1 && crc_valid0) || + (input_type_d0 == INPUT_TYPE_TERM_2 && crc_valid1) || + (input_type_d0 == INPUT_TYPE_TERM_3 && crc_valid2) || + (input_type_d0 == INPUT_TYPE_TERM_4 && crc_valid3)) begin + // CRC valid + end else begin + m_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; + end + state_next = STATE_IDLE; + end else begin + // need extra cycle + state_next = STATE_LAST; + end + end else begin + // control or error characters in packet + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + reset_crc = 1'b1; + state_next = STATE_IDLE; + end + end + STATE_LAST: begin + // last cycle of packet + m_axis_tdata_next = input_data_d1; + m_axis_tkeep_next = 8'hff; + m_axis_tvalid_next = 1'b1; + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b0; + + reset_crc = 1'b1; + + case (input_type_d1) + INPUT_TYPE_TERM_5: m_axis_tkeep_next = 8'b00000001; + INPUT_TYPE_TERM_6: m_axis_tkeep_next = 8'b00000011; + INPUT_TYPE_TERM_7: m_axis_tkeep_next = 8'b00000111; + endcase + + if ((input_type_d1 == INPUT_TYPE_TERM_5 && crc_valid0) || + (input_type_d1 == INPUT_TYPE_TERM_6 && crc_valid1) || + (input_type_d1 == INPUT_TYPE_TERM_7 && crc_valid2)) begin + // CRC valid + end else begin + m_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; + end + + state_next = STATE_IDLE; + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + m_axis_tvalid_reg <= 1'b0; + + start_packet_0_reg <= 1'b0; + start_packet_4_reg <= 1'b0; + error_bad_frame_reg <= 1'b0; + error_bad_fcs_reg <= 1'b0; + + crc_state <= 32'hFFFFFFFF; + crc_state3 <= 32'hFFFFFFFF; + crc_valid7_save <= 1'b0; + + input_type_d0 <= INPUT_TYPE_IDLE; + input_type_d1 <= INPUT_TYPE_IDLE; + + lanes_swapped <= 1'b0; + + delay_type_valid <= 1'b0; + delay_type <= INPUT_TYPE_IDLE; + end else begin + state_reg <= state_next; + + m_axis_tvalid_reg <= m_axis_tvalid_next; + + start_packet_0_reg <= 1'b0; + start_packet_4_reg <= 1'b0; + error_bad_frame_reg <= error_bad_frame_next; + error_bad_fcs_reg <= error_bad_fcs_next; + + delay_type_valid <= 1'b0; + + if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin + lanes_swapped <= 1'b0; + start_packet_0_reg <= 1'b1; + input_type_d0 <= INPUT_TYPE_START_0; + end else if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_4)begin + lanes_swapped <= 1'b1; + start_packet_4_reg <= 1'b1; + delay_type_valid <= 1'b1; + if (delay_type_valid) begin + input_type_d0 <= delay_type; + end else begin + input_type_d0 <= INPUT_TYPE_IDLE; + end + end else if (lanes_swapped) begin + if (delay_type_valid) begin + input_type_d0 <= delay_type; + end else if (encoded_rx_hdr == SYNC_DATA) begin + input_type_d0 <= INPUT_TYPE_DATA; + end else if (encoded_rx_hdr == SYNC_CTRL) begin + case (encoded_rx_data[7:0]) + BLOCK_TYPE_TERM_0: input_type_d0 <= INPUT_TYPE_TERM_4; + BLOCK_TYPE_TERM_1: input_type_d0 <= INPUT_TYPE_TERM_5; + BLOCK_TYPE_TERM_2: input_type_d0 <= INPUT_TYPE_TERM_6; + BLOCK_TYPE_TERM_3: input_type_d0 <= INPUT_TYPE_TERM_7; + BLOCK_TYPE_TERM_4: begin + delay_type_valid <= 1'b1; + input_type_d0 <= INPUT_TYPE_DATA; + end + BLOCK_TYPE_TERM_5: begin + delay_type_valid <= 1'b1; + input_type_d0 <= INPUT_TYPE_DATA; + end + BLOCK_TYPE_TERM_6: begin + delay_type_valid <= 1'b1; + input_type_d0 <= INPUT_TYPE_DATA; + end + BLOCK_TYPE_TERM_7: begin + delay_type_valid <= 1'b1; + input_type_d0 <= INPUT_TYPE_DATA; + end + default: input_type_d0 <= INPUT_TYPE_ERROR; + endcase + end else begin + input_type_d0 <= INPUT_TYPE_ERROR; + end + end else begin + if (encoded_rx_hdr == SYNC_DATA) begin + input_type_d0 <= INPUT_TYPE_DATA; + end else if (encoded_rx_hdr == SYNC_CTRL) begin + case (encoded_rx_data[7:0]) + BLOCK_TYPE_TERM_0: input_type_d0 <= INPUT_TYPE_TERM_0; + BLOCK_TYPE_TERM_1: input_type_d0 <= INPUT_TYPE_TERM_1; + BLOCK_TYPE_TERM_2: input_type_d0 <= INPUT_TYPE_TERM_2; + BLOCK_TYPE_TERM_3: input_type_d0 <= INPUT_TYPE_TERM_3; + BLOCK_TYPE_TERM_4: input_type_d0 <= INPUT_TYPE_TERM_4; + BLOCK_TYPE_TERM_5: input_type_d0 <= INPUT_TYPE_TERM_5; + BLOCK_TYPE_TERM_6: input_type_d0 <= INPUT_TYPE_TERM_6; + BLOCK_TYPE_TERM_7: input_type_d0 <= INPUT_TYPE_TERM_7; + default: input_type_d0 <= INPUT_TYPE_ERROR; + endcase + end else begin + input_type_d0 <= INPUT_TYPE_ERROR; + end + end + + input_type_d1 <= input_type_d0; + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + crc_state3 <= 32'hFFFFFFFF; + crc_valid7_save <= 1'b0; + end else if (update_crc) begin + crc_state <= crc_next7; + crc_state3 <= crc_next3; + crc_valid7_save <= crc_valid7; + end + end + + m_axis_tdata_reg <= m_axis_tdata_next; + m_axis_tkeep_reg <= m_axis_tkeep_next; + m_axis_tlast_reg <= m_axis_tlast_next; + m_axis_tuser_reg <= m_axis_tuser_next; + + if (encoded_rx_hdr == SYNC_DATA) begin + swap_data <= encoded_rx_data[63:32]; + end else begin + swap_data <= {8'd0, encoded_rx_data[63:40]}; + end + + if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin + input_data_d0 <= encoded_rx_data; + input_data_crc <= encoded_rx_data; + end else if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_4)begin + input_data_d0 <= {encoded_rx_data[31:0], swap_data}; + input_data_crc <= {encoded_rx_data[31:0], swap_data}; + end else if (lanes_swapped) begin + if (encoded_rx_hdr == SYNC_DATA) begin + input_data_d0 <= {encoded_rx_data[31:0], swap_data}; + input_data_crc <= {encoded_rx_data[31:0], swap_data}; + end else begin + input_data_d0 <= {encoded_rx_data[39:8], swap_data}; + input_data_crc <= {encoded_rx_data[39:8], swap_data}; + end + end else begin + if (encoded_rx_hdr == SYNC_DATA) begin + input_data_d0 <= encoded_rx_data; + input_data_crc <= encoded_rx_data; + end else begin + input_data_d0 <= {8'd0, encoded_rx_data[63:8]}; + input_data_crc <= {8'd0, encoded_rx_data[63:8]}; + end + end + + if (state_next == STATE_LAST) begin + input_data_crc[31:0] <= input_data_crc[63:32]; + end + + input_data_d1 <= input_data_d0; + + if (encoded_rx_hdr == SYNC_DATA) begin + delay_type <= INPUT_TYPE_DATA; + end else if (encoded_rx_hdr == SYNC_CTRL) begin + case (encoded_rx_data[7:0]) + BLOCK_TYPE_START_4: delay_type <= INPUT_TYPE_START_0; + BLOCK_TYPE_TERM_0: delay_type <= INPUT_TYPE_TERM_4; + BLOCK_TYPE_TERM_1: delay_type <= INPUT_TYPE_TERM_5; + BLOCK_TYPE_TERM_2: delay_type <= INPUT_TYPE_TERM_6; + BLOCK_TYPE_TERM_3: delay_type <= INPUT_TYPE_TERM_7; + BLOCK_TYPE_TERM_4: delay_type <= INPUT_TYPE_TERM_0; + BLOCK_TYPE_TERM_5: delay_type <= INPUT_TYPE_TERM_1; + BLOCK_TYPE_TERM_6: delay_type <= INPUT_TYPE_TERM_2; + BLOCK_TYPE_TERM_7: delay_type <= INPUT_TYPE_TERM_3; + default: delay_type <= INPUT_TYPE_ERROR; + endcase + end else begin + delay_type <= INPUT_TYPE_ERROR; + end +end + +endmodule diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v new file mode 100644 index 000000000..2a4d987cc --- /dev/null +++ b/rtl/axis_baser_tx_64.v @@ -0,0 +1,848 @@ +/* + +Copyright (c) 2019 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 10GBASE-R frame transmitter (AXI in, 10GBASE-R out) + */ +module axis_baser_tx_64 # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = 2, + parameter ENABLE_PADDING = 1, + parameter ENABLE_DIC = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + 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, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, + + /* + * 10GBASE-R encoded interface + */ + output wire [DATA_WIDTH-1:0] encoded_tx_data, + output wire [HDR_WIDTH-1:0] encoded_tx_hdr, + + /* + * Configuration + */ + input wire [7:0] ifg_delay, + + /* + * Status + */ + output wire start_packet_0, + output wire start_packet_4 +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end + + if (HDR_WIDTH != 2) begin + $error("Error: HDR_WIDTH must be 2"); + $finish; + end +end + +localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; +localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8; +localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007; + +localparam [7:0] + ETH_PRE = 8'h55, + ETH_SFD = 8'hD5; + +localparam [6:0] + CTRL_IDLE = 7'h00, + CTRL_LPI = 7'h06, + CTRL_ERROR = 7'h1e, + CTRL_RES_0 = 7'h2d, + CTRL_RES_1 = 7'h33, + CTRL_RES_2 = 7'h4b, + CTRL_RES_3 = 7'h55, + CTRL_RES_4 = 7'h66, + CTRL_RES_5 = 7'h78; + +localparam [3:0] + O_SEQ_OS = 4'h0, + O_SIG_OS = 4'hf; + +localparam [1:0] + SYNC_DATA = 2'b10, + SYNC_CTRL = 2'b01; + +localparam [7:0] + BLOCK_TYPE_CTRL = 8'h1e, // C7 C6 C5 C4 C3 C2 C1 C0 BT + BLOCK_TYPE_OS_4 = 8'h2d, // D7 D6 D5 O4 C3 C2 C1 C0 BT + BLOCK_TYPE_START_4 = 8'h33, // D7 D6 D5 C3 C2 C1 C0 BT + BLOCK_TYPE_OS_START = 8'h66, // D7 D6 D5 O0 D3 D2 D1 BT + BLOCK_TYPE_OS_04 = 8'h55, // D7 D6 D5 O4 O0 D3 D2 D1 BT + BLOCK_TYPE_START_0 = 8'h78, // D7 D6 D5 D4 D3 D2 D1 BT + BLOCK_TYPE_OS_0 = 8'h4b, // C7 C6 C5 C4 O0 D3 D2 D1 BT + BLOCK_TYPE_TERM_0 = 8'h87, // C7 C6 C5 C4 C3 C2 C1 BT + BLOCK_TYPE_TERM_1 = 8'h99, // C7 C6 C5 C4 C3 C2 D0 BT + BLOCK_TYPE_TERM_2 = 8'haa, // C7 C6 C5 C4 C3 D1 D0 BT + BLOCK_TYPE_TERM_3 = 8'hb4, // C7 C6 C5 C4 D2 D1 D0 BT + BLOCK_TYPE_TERM_4 = 8'hcc, // C7 C6 C5 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_5 = 8'hd2, // C7 C6 D4 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_6 = 8'he1, // C7 D5 D4 D3 D2 D1 D0 BT + BLOCK_TYPE_TERM_7 = 8'hff; // D6 D5 D4 D3 D2 D1 D0 BT + +localparam [3:0] + OUTPUT_TYPE_IDLE = 4'd0, + OUTPUT_TYPE_ERROR = 4'd1, + OUTPUT_TYPE_START_0 = 4'd2, + OUTPUT_TYPE_START_4 = 4'd3, + OUTPUT_TYPE_DATA = 4'd4, + OUTPUT_TYPE_TERM_0 = 4'd8, + OUTPUT_TYPE_TERM_1 = 4'd9, + OUTPUT_TYPE_TERM_2 = 4'd10, + OUTPUT_TYPE_TERM_3 = 4'd11, + OUTPUT_TYPE_TERM_4 = 4'd12, + OUTPUT_TYPE_TERM_5 = 4'd13, + OUTPUT_TYPE_TERM_6 = 4'd14, + OUTPUT_TYPE_TERM_7 = 4'd15; + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PAYLOAD = 3'd1, + STATE_PAD = 3'd2, + STATE_FCS_1 = 3'd3, + STATE_FCS_2 = 3'd4, + STATE_IFG = 3'd5, + STATE_WAIT_END = 3'd6; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg swap_lanes; +reg unswap_lanes; + +reg lanes_swapped = 1'b0; +reg [31:0] swap_data = 32'd0; + +reg delay_type_valid = 1'b0; +reg [3:0] delay_type = OUTPUT_TYPE_IDLE; + +reg [DATA_WIDTH-1:0] s_axis_tdata_masked; + +reg [DATA_WIDTH-1:0] s_tdata_reg = {DATA_WIDTH{1'b0}}, s_tdata_next; +reg [7:0] s_tkeep_reg = 8'd0, s_tkeep_next; + +reg [DATA_WIDTH-1:0] fcs_output_data_0; +reg [DATA_WIDTH-1:0] fcs_output_data_1; +reg [3:0] fcs_output_type_0; +reg [3:0] fcs_output_type_1; + +reg [7:0] ifg_offset; + +reg extra_cycle; + +reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; + +reg [7:0] ifg_count_reg = 8'd0, ifg_count_next; +reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; + +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; + +wire [31:0] crc_next0; +wire [31:0] crc_next1; +wire [31:0] crc_next2; +wire [31:0] crc_next3; +wire [31:0] crc_next4; +wire [31:0] crc_next5; +wire [31:0] crc_next6; +wire [31:0] crc_next7; + +reg [DATA_WIDTH-1:0] encoded_tx_data_reg = {{8{CTRL_IDLE}}, BLOCK_TYPE_CTRL}; +reg [HDR_WIDTH-1:0] encoded_tx_hdr_reg = SYNC_CTRL; + +reg [DATA_WIDTH-1:0] output_data_reg = {DATA_WIDTH{1'b0}}, output_data_next; +reg [3:0] output_type_reg = OUTPUT_TYPE_IDLE, output_type_next; + +reg start_packet_0_reg = 1'b0, start_packet_0_next; +reg start_packet_4_reg = 1'b0, start_packet_4_next; + +assign s_axis_tready = s_axis_tready_reg; + +assign encoded_tx_data = encoded_tx_data_reg; +assign encoded_tx_hdr = encoded_tx_hdr_reg; + +assign start_packet_0 = start_packet_0_reg; +assign start_packet_4 = start_packet_4_reg; + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(8), + .STYLE("AUTO") +) +eth_crc_8 ( + .data_in(s_tdata_reg[7:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next0) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(16), + .STYLE("AUTO") +) +eth_crc_16 ( + .data_in(s_tdata_reg[15:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next1) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(24), + .STYLE("AUTO") +) +eth_crc_24 ( + .data_in(s_tdata_reg[23:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next2) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(32), + .STYLE("AUTO") +) +eth_crc_32 ( + .data_in(s_tdata_reg[31:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next3) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(40), + .STYLE("AUTO") +) +eth_crc_40 ( + .data_in(s_tdata_reg[39:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next4) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(48), + .STYLE("AUTO") +) +eth_crc_48 ( + .data_in(s_tdata_reg[47:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next5) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(56), + .STYLE("AUTO") +) +eth_crc_56 ( + .data_in(s_tdata_reg[55:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next6) +); + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(64), + .STYLE("AUTO") +) +eth_crc_64 ( + .data_in(s_tdata_reg[63:0]), + .state_in(crc_state), + .data_out(), + .state_out(crc_next7) +); + +function [3:0] keep2count; + input [7:0] k; + casez (k) + 8'bzzzzzzz0: keep2count = 4'd0; + 8'bzzzzzz01: keep2count = 4'd1; + 8'bzzzzz011: keep2count = 4'd2; + 8'bzzzz0111: keep2count = 4'd3; + 8'bzzz01111: keep2count = 4'd4; + 8'bzz011111: keep2count = 4'd5; + 8'bz0111111: keep2count = 4'd6; + 8'b01111111: keep2count = 4'd7; + 8'b11111111: keep2count = 4'd8; + endcase +endfunction + +// Mask input data +integer j; + +always @* begin + for (j = 0; j < 8; j = j + 1) begin + s_axis_tdata_masked[j*8 +: 8] = s_axis_tkeep[j] ? s_axis_tdata[j*8 +: 8] : 8'd0; + end +end + +// FCS cycle calculation +always @* begin + casez (s_tkeep_reg) + 8'bzzzzzz01: begin + fcs_output_data_0 = {24'd0, ~crc_next0[31:0], s_tdata_reg[7:0]}; + fcs_output_data_1 = 64'd0; + fcs_output_type_0 = OUTPUT_TYPE_TERM_5; + fcs_output_type_1 = OUTPUT_TYPE_IDLE; + ifg_offset = 8'd3; + extra_cycle = 1'b0; + end + 8'bzzzzz011: begin + fcs_output_data_0 = {16'd0, ~crc_next1[31:0], s_tdata_reg[15:0]}; + fcs_output_data_1 = 64'd0; + fcs_output_type_0 = OUTPUT_TYPE_TERM_6; + fcs_output_type_1 = OUTPUT_TYPE_IDLE; + ifg_offset = 8'd2; + extra_cycle = 1'b0; + end + 8'bzzzz0111: begin + fcs_output_data_0 = {8'd0, ~crc_next2[31:0], s_tdata_reg[23:0]}; + fcs_output_data_1 = 64'd0; + fcs_output_type_0 = OUTPUT_TYPE_TERM_7; + fcs_output_type_1 = OUTPUT_TYPE_IDLE; + ifg_offset = 8'd1; + extra_cycle = 1'b0; + end + 8'bzzz01111: begin + fcs_output_data_0 = {~crc_next3[31:0], s_tdata_reg[31:0]}; + fcs_output_data_1 = 64'd0; + fcs_output_type_0 = OUTPUT_TYPE_DATA; + fcs_output_type_1 = OUTPUT_TYPE_TERM_0; + ifg_offset = 8'd8; + extra_cycle = 1'b1; + end + 8'bzz011111: begin + fcs_output_data_0 = {~crc_next4[23:0], s_tdata_reg[39:0]}; + fcs_output_data_1 = {56'd0, ~crc_next4[31:24]}; + fcs_output_type_0 = OUTPUT_TYPE_DATA; + fcs_output_type_1 = OUTPUT_TYPE_TERM_1; + ifg_offset = 8'd7; + extra_cycle = 1'b1; + end + 8'bz0111111: begin + fcs_output_data_0 = {~crc_next5[15:0], s_tdata_reg[47:0]}; + fcs_output_data_1 = {48'd0, ~crc_next5[31:16]}; + fcs_output_type_0 = OUTPUT_TYPE_DATA; + fcs_output_type_1 = OUTPUT_TYPE_TERM_2; + ifg_offset = 8'd6; + extra_cycle = 1'b1; + end + 8'b01111111: begin + fcs_output_data_0 = {~crc_next6[7:0], s_tdata_reg[55:0]}; + fcs_output_data_1 = {40'd0, ~crc_next6[31:8]}; + fcs_output_type_0 = OUTPUT_TYPE_DATA; + fcs_output_type_1 = OUTPUT_TYPE_TERM_3; + ifg_offset = 8'd5; + extra_cycle = 1'b1; + end + 8'b11111111: begin + fcs_output_data_0 = s_tdata_reg; + fcs_output_data_1 = {32'd0, ~crc_next7[31:0]}; + fcs_output_type_0 = OUTPUT_TYPE_DATA; + fcs_output_type_1 = OUTPUT_TYPE_TERM_4; + ifg_offset = 8'd4; + extra_cycle = 1'b1; + end + default: begin + fcs_output_data_0 = 64'd0; + fcs_output_data_1 = 64'd0; + fcs_output_type_0 = OUTPUT_TYPE_ERROR; + fcs_output_type_1 = OUTPUT_TYPE_ERROR; + ifg_offset = 8'd0; + extra_cycle = 1'b1; + end + endcase +end + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 1'b0; + update_crc = 1'b0; + + swap_lanes = 1'b0; + unswap_lanes = 1'b0; + + frame_ptr_next = frame_ptr_reg; + + ifg_count_next = ifg_count_reg; + deficit_idle_count_next = deficit_idle_count_reg; + + s_axis_tready_next = 1'b0; + + s_tdata_next = s_tdata_reg; + s_tkeep_next = s_tkeep_reg; + + output_data_next = s_tdata_reg; + output_type_next = OUTPUT_TYPE_IDLE; + + start_packet_0_next = 1'b0; + start_packet_4_next = 1'b0; + + case (state_reg) + STATE_IDLE: begin + // idle state - wait for data + frame_ptr_next = 16'd8; + reset_crc = 1'b1; + s_axis_tready_next = 1'b1; + + output_data_next = s_tdata_reg; + output_type_next = OUTPUT_TYPE_IDLE; + + s_tdata_next = s_axis_tdata_masked; + s_tkeep_next = s_axis_tkeep; + + if (s_axis_tvalid) begin + // XGMII start and preamble + if (ifg_count_reg > 8'd0) begin + // need to send more idles - swap lanes + swap_lanes = 1'b1; + start_packet_4_next = 1'b1; + end else begin + // no more idles - unswap + unswap_lanes = 1'b1; + start_packet_0_next = 1'b1; + end + output_data_next = {ETH_SFD, {7{ETH_PRE}}}; + output_type_next = OUTPUT_TYPE_START_0; + s_axis_tready_next = 1'b1; + state_next = STATE_PAYLOAD; + end else begin + ifg_count_next = 8'd0; + deficit_idle_count_next = 2'd0; + unswap_lanes = 1'b1; + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // transfer payload + update_crc = 1'b1; + s_axis_tready_next = 1'b1; + + frame_ptr_next = frame_ptr_reg + 16'd8; + + output_data_next = s_tdata_reg; + output_type_next = OUTPUT_TYPE_DATA; + + s_tdata_next = s_axis_tdata_masked; + s_tkeep_next = s_axis_tkeep; + + if (s_axis_tvalid) begin + if (s_axis_tlast) begin + frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); + s_axis_tready_next = 1'b0; + if (s_axis_tuser) begin + output_type_next = OUTPUT_TYPE_ERROR; + frame_ptr_next = 16'd0; + ifg_count_next = 8'd8; + state_next = STATE_IFG; + end else begin + s_axis_tready_next = 1'b0; + + if (ENABLE_PADDING && (frame_ptr_reg < MIN_FL_NOCRC_MS || (frame_ptr_reg == MIN_FL_NOCRC_MS && keep2count(s_axis_tkeep) < MIN_FL_NOCRC_LS))) begin + s_tkeep_next = 8'hff; + frame_ptr_next = frame_ptr_reg + 16'd8; + + if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-8)) begin + state_next = STATE_PAD; + end else begin + s_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8); + + state_next = STATE_FCS_1; + end + end else begin + state_next = STATE_FCS_1; + end + end + end else begin + state_next = STATE_PAYLOAD; + end + end else begin + // tvalid deassert, fail framec + output_type_next = OUTPUT_TYPE_ERROR; + frame_ptr_next = 16'd0; + ifg_count_next = 8'd8; + state_next = STATE_WAIT_END; + end + end + STATE_PAD: begin + // pad frame to MIN_FRAME_LENGTH + s_axis_tready_next = 1'b0; + + output_data_next = s_tdata_reg; + output_type_next = OUTPUT_TYPE_DATA; + + s_tdata_next = 64'd0; + s_tkeep_next = 8'hff; + + update_crc = 1'b1; + frame_ptr_next = frame_ptr_reg + 16'd8; + + if (frame_ptr_reg < (MIN_FL_NOCRC_LS > 0 ? MIN_FL_NOCRC_MS : MIN_FL_NOCRC_MS-8)) begin + state_next = STATE_PAD; + end else begin + s_tkeep_next = 8'hff >> ((8-MIN_FL_NOCRC_LS) % 8); + + state_next = STATE_FCS_1; + end + end + STATE_FCS_1: begin + // last cycle + s_axis_tready_next = 1'b0; + + output_data_next = fcs_output_data_0; + output_type_next = fcs_output_type_0; + + frame_ptr_next = 16'd0; + + ifg_count_next = (ifg_delay > 8'd12 ? ifg_delay : 8'd12) - ifg_offset + (lanes_swapped ? 8'd4 : 8'd0) + deficit_idle_count_reg; + if (extra_cycle) begin + state_next = STATE_FCS_2; + end else begin + state_next = STATE_IFG; + end + end + STATE_FCS_2: begin + // last cycle + s_axis_tready_next = 1'b0; + + output_data_next = fcs_output_data_1; + output_type_next = fcs_output_type_1; + + reset_crc = 1'b1; + frame_ptr_next = 16'd0; + + if (ENABLE_DIC) begin + if (ifg_count_next > 8'd7) begin + state_next = STATE_IFG; + end else begin + if (ifg_count_next >= 8'd4) begin + deficit_idle_count_next = ifg_count_next - 8'd4; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 8'd0; + end + s_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 8'd4) begin + state_next = STATE_IFG; + end else begin + s_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end + end + STATE_IFG: begin + // send IFG + if (ifg_count_reg > 8'd8) begin + ifg_count_next = ifg_count_reg - 8'd8; + end else begin + ifg_count_next = 8'd0; + end + + reset_crc = 1'b1; + + if (ENABLE_DIC) begin + if (ifg_count_next > 8'd7) begin + state_next = STATE_IFG; + end else begin + if (ifg_count_next >= 8'd4) begin + deficit_idle_count_next = ifg_count_next - 8'd4; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 8'd0; + end + s_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 8'd4) begin + state_next = STATE_IFG; + end else begin + s_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end + end + STATE_WAIT_END: begin + // wait for end of frame + if (ifg_count_reg > 8'd8) begin + ifg_count_next = ifg_count_reg - 8'd8; + end else begin + ifg_count_next = 8'd0; + end + + reset_crc = 1'b1; + + if (s_axis_tvalid) begin + if (s_axis_tlast) begin + if (ENABLE_DIC) begin + if (ifg_count_next > 8'd7) begin + state_next = STATE_IFG; + end else begin + if (ifg_count_next >= 8'd4) begin + deficit_idle_count_next = ifg_count_next - 8'd4; + end else begin + deficit_idle_count_next = ifg_count_next; + ifg_count_next = 8'd0; + end + s_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end else begin + if (ifg_count_next > 8'd4) begin + state_next = STATE_IFG; + end else begin + s_axis_tready_next = 1'b1; + state_next = STATE_IDLE; + end + end + end else begin + state_next = STATE_WAIT_END; + end + end else begin + state_next = STATE_WAIT_END; + end + end + endcase +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + frame_ptr_reg <= 16'd0; + + ifg_count_reg <= 8'd0; + deficit_idle_count_reg <= 2'd0; + + s_axis_tready_reg <= 1'b0; + + encoded_tx_data_reg <= {{8{CTRL_IDLE}}, BLOCK_TYPE_CTRL}; + encoded_tx_hdr_reg <= SYNC_CTRL; + + output_data_reg <= {DATA_WIDTH{1'b0}}; + output_type_reg <= OUTPUT_TYPE_IDLE; + + start_packet_0_reg <= 1'b0; + start_packet_4_reg <= 1'b0; + + crc_state <= 32'hFFFFFFFF; + + lanes_swapped <= 1'b0; + + delay_type_valid <= 1'b0; + delay_type <= OUTPUT_TYPE_IDLE; + end else begin + state_reg <= state_next; + + frame_ptr_reg <= frame_ptr_next; + + ifg_count_reg <= ifg_count_next; + deficit_idle_count_reg <= deficit_idle_count_next; + + s_axis_tready_reg <= s_axis_tready_next; + + start_packet_0_reg <= start_packet_0_next; + start_packet_4_reg <= start_packet_4_next; + + delay_type_valid <= 1'b0; + + if (swap_lanes || (lanes_swapped && !unswap_lanes)) begin + lanes_swapped <= 1'b1; + output_data_reg <= {output_data_next[31:0], swap_data}; + if (delay_type_valid) begin + output_type_reg <= delay_type; + end else if (output_type_next == OUTPUT_TYPE_START_0) begin + output_type_reg <= OUTPUT_TYPE_START_4; + end else if (output_type_next[3]) begin + // OUTPUT_TYPE_TERM_* + if (output_type_next[2]) begin + delay_type_valid <= 1'b1; + output_type_reg <= OUTPUT_TYPE_DATA; + end else begin + output_type_reg <= output_type_next ^ 4'd4; + end + end else begin + output_type_reg <= output_type_next; + end + end else begin + lanes_swapped <= 1'b0; + output_data_reg <= output_data_next; + output_type_reg <= output_type_next; + end + + case (output_type_reg) + OUTPUT_TYPE_IDLE: begin + encoded_tx_data_reg <= {{8{CTRL_IDLE}}, BLOCK_TYPE_CTRL}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_ERROR: begin + encoded_tx_data_reg <= {{8{CTRL_ERROR}}, BLOCK_TYPE_CTRL}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_START_0: begin + encoded_tx_data_reg <= {output_data_reg[63:8], BLOCK_TYPE_START_0}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_START_4: begin + encoded_tx_data_reg <= {output_data_reg[63:40], 4'd0, {4{CTRL_IDLE}}, BLOCK_TYPE_START_4}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_DATA: begin + encoded_tx_data_reg <= output_data_reg; + encoded_tx_hdr_reg <= SYNC_DATA; + end + OUTPUT_TYPE_TERM_0: begin + encoded_tx_data_reg <= {{7{CTRL_IDLE}}, 7'd0, BLOCK_TYPE_TERM_0}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_TERM_1: begin + encoded_tx_data_reg <= {{6{CTRL_IDLE}}, 6'd0, output_data_reg[7:0], BLOCK_TYPE_TERM_1}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_TERM_2: begin + encoded_tx_data_reg <= {{5{CTRL_IDLE}}, 5'd0, output_data_reg[15:0], BLOCK_TYPE_TERM_2}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_TERM_3: begin + encoded_tx_data_reg <= {{4{CTRL_IDLE}}, 4'd0, output_data_reg[23:0], BLOCK_TYPE_TERM_3}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_TERM_4: begin + encoded_tx_data_reg <= {{3{CTRL_IDLE}}, 3'd0, output_data_reg[31:0], BLOCK_TYPE_TERM_4}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_TERM_5: begin + encoded_tx_data_reg <= {{2{CTRL_IDLE}}, 2'd0, output_data_reg[39:0], BLOCK_TYPE_TERM_5}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_TERM_6: begin + encoded_tx_data_reg <= {{1{CTRL_IDLE}}, 1'd0, output_data_reg[47:0], BLOCK_TYPE_TERM_6}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + OUTPUT_TYPE_TERM_7: begin + encoded_tx_data_reg <= {output_data_reg[55:0], BLOCK_TYPE_TERM_7}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + default: begin + encoded_tx_data_reg <= {{8{CTRL_ERROR}}, BLOCK_TYPE_CTRL}; + encoded_tx_hdr_reg <= SYNC_CTRL; + end + endcase + + // datapath + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next7; + end + end + + s_tdata_reg <= s_tdata_next; + s_tkeep_reg <= s_tkeep_next; + + swap_data <= output_data_next[63:32]; + + delay_type <= output_type_next ^ 4'd4; +end + +endmodule diff --git a/rtl/eth_mac_phy_10g.v b/rtl/eth_mac_phy_10g.v new file mode 100644 index 000000000..672f09a9d --- /dev/null +++ b/rtl/eth_mac_phy_10g.v @@ -0,0 +1,154 @@ +/* + +Copyright (c) 2019 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 + +/* + * 10G Ethernet MAC/PHY combination + */ +module eth_mac_phy_10g # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = (DATA_WIDTH/32), + parameter ENABLE_PADDING = 1, + parameter ENABLE_DIC = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter BIT_REVERSE = 0, + parameter SCRAMBLER_DISABLE = 0, + parameter SLIP_COUNT_WIDTH = 3, + parameter COUNT_125US = 125000/6.4 +) +( + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * SERDES interface + */ + output wire [DATA_WIDTH-1:0] serdes_tx_data, + output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + input wire [DATA_WIDTH-1:0] serdes_rx_data, + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * Status + */ + output wire tx_start_packet_0, + output wire tx_start_packet_4, + output wire rx_start_packet_0, + output wire rx_start_packet_4, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_block_lock, + output wire rx_high_ber, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +eth_mac_phy_10g_rx #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), + .COUNT_125US(COUNT_125US) +) +eth_mac_phy_10g_rx_inst ( + .clk(rx_clk), + .rst(rx_rst), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(rx_axis_tkeep), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tuser(rx_axis_tuser), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_start_packet_0(rx_start_packet_0), + .rx_start_packet_4(rx_start_packet_4), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber) +); + +eth_mac_phy_10g_tx #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE) +) +eth_mac_phy_10g_tx_inst ( + .clk(tx_clk), + .rst(tx_rst), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(tx_axis_tkeep), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tuser(tx_axis_tuser), + .serdes_tx_data(serdes_tx_data), + .serdes_tx_hdr(serdes_tx_hdr), + .ifg_delay(ifg_delay), + .tx_start_packet_0(tx_start_packet_0), + .tx_start_packet_4(tx_start_packet_4) +); + +endmodule diff --git a/rtl/eth_mac_phy_10g_fifo.v b/rtl/eth_mac_phy_10g_fifo.v new file mode 100644 index 000000000..e19f89817 --- /dev/null +++ b/rtl/eth_mac_phy_10g_fifo.v @@ -0,0 +1,295 @@ +/* + +Copyright (c) 2019 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 + +/* + * 10G Ethernet MAC/PHY combination with TX and RX FIFOs + */ +module eth_mac_phy_10g_fifo # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = (DATA_WIDTH/32), + parameter ENABLE_PADDING = 1, + parameter ENABLE_DIC = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter BIT_REVERSE = 0, + parameter SCRAMBLER_DISABLE = 0, + parameter SLIP_COUNT_WIDTH = 3, + parameter COUNT_125US = 125000/6.4, + parameter TX_FIFO_ADDR_WIDTH = 12-$clog2(KEEP_WIDTH), + parameter TX_FRAME_FIFO = 1, + parameter TX_DROP_BAD_FRAME = TX_FRAME_FIFO, + parameter TX_DROP_WHEN_FULL = 0, + parameter RX_FIFO_ADDR_WIDTH = 12-$clog2(KEEP_WIDTH), + parameter RX_FRAME_FIFO = 1, + parameter RX_DROP_BAD_FRAME = RX_FRAME_FIFO, + parameter RX_DROP_WHEN_FULL = RX_FRAME_FIFO +) +( + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, + input wire logic_clk, + input wire logic_rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + input wire rx_axis_tready, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * SERDES interface + */ + output wire [DATA_WIDTH-1:0] serdes_tx_data, + output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + input wire [DATA_WIDTH-1:0] serdes_rx_data, + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * Status + */ + output wire tx_fifo_overflow, + output wire tx_fifo_bad_frame, + output wire tx_fifo_good_frame, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_block_lock, + output wire rx_high_ber, + output wire rx_fifo_overflow, + output wire rx_fifo_bad_frame, + output wire rx_fifo_good_frame, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +wire [DATA_WIDTH-1:0] tx_fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] tx_fifo_axis_tkeep; +wire tx_fifo_axis_tvalid; +wire tx_fifo_axis_tready; +wire tx_fifo_axis_tlast; +wire tx_fifo_axis_tuser; + +wire [DATA_WIDTH-1:0] rx_fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] rx_fifo_axis_tkeep; +wire rx_fifo_axis_tvalid; +wire rx_fifo_axis_tlast; +wire rx_fifo_axis_tuser; + +// synchronize MAC status signals into logic clock domain +wire rx_error_bad_frame_int; +wire rx_error_bad_fcs_int; + +reg [3:0] rx_sync_reg_1 = 4'd0; +reg [3:0] rx_sync_reg_2 = 4'd0; +reg [3:0] rx_sync_reg_3 = 4'd0; +reg [3:0] rx_sync_reg_4 = 4'd0; + +assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; +assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; +assign rx_block_lock = rx_sync_reg_3[2] ^ rx_sync_reg_4[2]; +assign rx_high_ber = rx_sync_reg_3[3] ^ rx_sync_reg_4[3]; + +always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + rx_sync_reg_1 <= 4'd0; + end else begin + rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_high_ber_int, rx_block_lock_int, rx_error_bad_frame_int, rx_error_bad_frame_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + rx_sync_reg_2 <= 4'd0; + rx_sync_reg_3 <= 4'd0; + rx_sync_reg_4 <= 4'd0; + end else begin + rx_sync_reg_2 <= rx_sync_reg_1; + rx_sync_reg_3 <= rx_sync_reg_2; + rx_sync_reg_4 <= rx_sync_reg_3; + end +end + +eth_mac_phy_10g #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), + .COUNT_125US(COUNT_125US) +) +eth_mac_phy_10g_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_fifo_axis_tdata), + .tx_axis_tkeep(tx_fifo_axis_tkeep), + .tx_axis_tvalid(tx_fifo_axis_tvalid), + .tx_axis_tready(tx_fifo_axis_tready), + .tx_axis_tlast(tx_fifo_axis_tlast), + .tx_axis_tuser(tx_fifo_axis_tuser), + .rx_axis_tdata(rx_fifo_axis_tdata), + .rx_axis_tkeep(rx_fifo_axis_tkeep), + .rx_axis_tvalid(rx_fifo_axis_tvalid), + .rx_axis_tlast(rx_fifo_axis_tlast), + .rx_axis_tuser(rx_fifo_axis_tuser), + .serdes_tx_data(serdes_tx_data), + .serdes_tx_hdr(serdes_tx_hdr), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_error_bad_frame(rx_error_bad_frame_int), + .rx_error_bad_fcs(rx_error_bad_fcs_int), + .rx_block_lock(rx_block_lock_int), + .rx_high_ber(rx_high_ber_int), + .ifg_delay(ifg_delay) +); + +axis_async_fifo #( + .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(1), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(1), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(TX_FRAME_FIFO), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) +) +tx_fifo ( + // Common reset + .async_rst(logic_rst | tx_rst), + // AXI input + .s_clk(logic_clk), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(tx_axis_tkeep), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(tx_axis_tuser), + // AXI output + .m_clk(tx_clk), + .m_axis_tdata(tx_fifo_axis_tdata), + .m_axis_tkeep(tx_fifo_axis_tkeep), + .m_axis_tvalid(tx_fifo_axis_tvalid), + .m_axis_tready(tx_fifo_axis_tready), + .m_axis_tlast(tx_fifo_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_axis_tuser), + // Status + .s_status_overflow(tx_fifo_overflow), + .s_status_bad_frame(tx_fifo_bad_frame), + .s_status_good_frame(tx_fifo_good_frame), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() +); + +axis_async_fifo #( + .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(1), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(1), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(RX_FRAME_FIFO), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(RX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(RX_DROP_WHEN_FULL) +) +rx_fifo ( + // Common reset + .async_rst(rx_rst | logic_rst), + // AXI input + .s_clk(rx_clk), + .s_axis_tdata(rx_fifo_axis_tdata), + .s_axis_tkeep(rx_fifo_axis_tkeep), + .s_axis_tvalid(rx_fifo_axis_tvalid), + .s_axis_tready(), + .s_axis_tlast(rx_fifo_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_axis_tuser), + // AXI output + .m_clk(logic_clk), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(rx_axis_tkeep), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tready(rx_axis_tready), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(rx_axis_tuser), + // Status + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(rx_fifo_overflow), + .m_status_bad_frame(rx_fifo_bad_frame), + .m_status_good_frame(rx_fifo_good_frame) +); + +endmodule diff --git a/rtl/eth_mac_phy_10g_rx.v b/rtl/eth_mac_phy_10g_rx.v new file mode 100644 index 000000000..d6f48cfb4 --- /dev/null +++ b/rtl/eth_mac_phy_10g_rx.v @@ -0,0 +1,187 @@ +/* + +Copyright (c) 2019 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 + +/* + * 10G Ethernet MAC/PHY combination + */ +module eth_mac_phy_10g_rx # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = (DATA_WIDTH/32), + parameter BIT_REVERSE = 0, + parameter SCRAMBLER_DISABLE = 0, + parameter SLIP_COUNT_WIDTH = 3, + parameter COUNT_125US = 125000/6.4 +) +( + input wire clk, + input wire rst, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire m_axis_tuser, + + /* + * SERDES interface + */ + input wire [DATA_WIDTH-1:0] serdes_rx_data, + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * Status + */ + output wire rx_start_packet_0, + output wire rx_start_packet_4, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_block_lock, + output wire rx_high_ber +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end + + if (HDR_WIDTH * 32 != DATA_WIDTH) begin + $error("Error: HDR_WIDTH must be equal to DATA_WIDTH/32"); + $finish; + end +end + +wire [DATA_WIDTH-1:0] serdes_rx_data_int; +wire [HDR_WIDTH-1:0] serdes_rx_hdr_int; + +generate + genvar n; + + if (BIT_REVERSE) begin + for (n = 0; n < DATA_WIDTH; n = n + 1) begin + assign serdes_rx_data_int[n] = serdes_rx_data[DATA_WIDTH-n-1]; + end + + for (n = 0; n < HDR_WIDTH; n = n + 1) begin + assign serdes_rx_hdr_int[n] = serdes_rx_hdr[HDR_WIDTH-n-1]; + end + end else begin + assign serdes_rx_data_int = serdes_rx_data; + assign serdes_rx_hdr_int = serdes_rx_hdr; + end +endgenerate + +wire [DATA_WIDTH-1:0] descrambled_rx_data; + +reg [DATA_WIDTH-1:0] encoded_rx_data_reg = {DATA_WIDTH{1'b0}}; +reg [HDR_WIDTH-1:0] encoded_rx_hdr_reg = {HDR_WIDTH{1'b0}}; + +reg [57:0] scrambler_state_reg = {58{1'b1}}; +wire [57:0] scrambler_state; + +lfsr #( + .LFSR_WIDTH(58), + .LFSR_POLY(58'h8000000001), + .LFSR_CONFIG("FIBONACCI"), + .LFSR_FEED_FORWARD(1), + .REVERSE(1), + .DATA_WIDTH(DATA_WIDTH), + .STYLE("AUTO") +) +descrambler_inst ( + .data_in(serdes_rx_data_int), + .state_in(scrambler_state_reg), + .data_out(descrambled_rx_data), + .state_out(scrambler_state) +); + +always @(posedge clk) begin + scrambler_state_reg <= scrambler_state; + + encoded_rx_data_reg <= SCRAMBLER_DISABLE ? serdes_rx_data_int : descrambled_rx_data; + encoded_rx_hdr_reg <= serdes_rx_hdr_int; +end + +axis_baser_rx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .HDR_WIDTH(HDR_WIDTH) +) +axis_baser_rx_inst ( + .clk(clk), + .rst(rst), + .encoded_rx_data(encoded_rx_data_reg), + .encoded_rx_hdr(encoded_rx_hdr_reg), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), + .start_packet_0(rx_start_packet_0), + .start_packet_4(rx_start_packet_4), + .error_bad_frame(rx_error_bad_frame), + .error_bad_fcs(rx_error_bad_fcs) +); + +eth_phy_10g_rx_frame_sync #( + .HDR_WIDTH(HDR_WIDTH), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH) +) +eth_phy_10g_rx_frame_sync_inst ( + .clk(clk), + .rst(rst), + .serdes_rx_hdr(serdes_rx_hdr_int), + .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_block_lock(rx_block_lock) +); + +eth_phy_10g_rx_ber_mon #( + .HDR_WIDTH(HDR_WIDTH), + .COUNT_125US(COUNT_125US) +) +eth_phy_10g_rx_ber_mon_inst ( + .clk(clk), + .rst(rst), + .serdes_rx_hdr(serdes_rx_hdr_int), + .rx_high_ber(rx_high_ber) +); + +endmodule diff --git a/rtl/eth_mac_phy_10g_tx.v b/rtl/eth_mac_phy_10g_tx.v new file mode 100644 index 000000000..7c4d2032e --- /dev/null +++ b/rtl/eth_mac_phy_10g_tx.v @@ -0,0 +1,168 @@ +/* + +Copyright (c) 2019 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 + +/* + * 10G Ethernet MAC/PHY combination + */ +module eth_mac_phy_10g_tx # +( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = (DATA_WIDTH/32), + parameter ENABLE_PADDING = 1, + parameter ENABLE_DIC = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter BIT_REVERSE = 0, + parameter SCRAMBLER_DISABLE = 0 +) +( + 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, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, + + /* + * SERDES interface + */ + output wire [DATA_WIDTH-1:0] serdes_tx_data, + output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + + /* + * Configuration + */ + input wire [7:0] ifg_delay, + + /* + * Status + */ + output wire tx_start_packet_0, + output wire tx_start_packet_4 +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end + + if (HDR_WIDTH * 32 != DATA_WIDTH) begin + $error("Error: HDR_WIDTH must be equal to DATA_WIDTH/32"); + $finish; + end +end + +wire [DATA_WIDTH-1:0] encoded_tx_data; +wire [HDR_WIDTH-1:0] encoded_tx_hdr; + +axis_baser_tx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +axis_baser_tx_inst ( + .clk(clk), + .rst(rst), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .encoded_tx_data(encoded_tx_data), + .encoded_tx_hdr(encoded_tx_hdr), + .ifg_delay(ifg_delay), + .start_packet_0(tx_start_packet_0), + .start_packet_4(tx_start_packet_4) +); + +reg [57:0] tx_scrambler_state_reg = {58{1'b1}}; +wire [57:0] tx_scrambler_state; +wire [DATA_WIDTH-1:0] scrambled_data; + +reg [DATA_WIDTH-1:0] serdes_tx_data_reg = {DATA_WIDTH{1'b0}}; +reg [HDR_WIDTH-1:0] serdes_tx_hdr_reg = {HDR_WIDTH{1'b0}}; + +generate + genvar n; + + if (BIT_REVERSE) begin + for (n = 0; n < DATA_WIDTH; n = n + 1) begin + assign serdes_tx_data[n] = serdes_tx_data_reg[DATA_WIDTH-n-1]; + end + + for (n = 0; n < HDR_WIDTH; n = n + 1) begin + assign serdes_tx_hdr[n] = serdes_tx_hdr_reg[HDR_WIDTH-n-1]; + end + end else begin + assign serdes_tx_data = serdes_tx_data_reg; + assign serdes_tx_hdr = serdes_tx_hdr_reg; + end +endgenerate + +lfsr #( + .LFSR_WIDTH(58), + .LFSR_POLY(58'h8000000001), + .LFSR_CONFIG("FIBONACCI"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(DATA_WIDTH), + .STYLE("AUTO") +) +scrambler_inst ( + .data_in(encoded_tx_data), + .state_in(tx_scrambler_state_reg), + .data_out(scrambled_data), + .state_out(tx_scrambler_state) +); + +always @(posedge clk) begin + tx_scrambler_state_reg <= tx_scrambler_state; + + serdes_tx_data_reg <= SCRAMBLER_DISABLE ? encoded_tx_data : scrambled_data; + serdes_tx_hdr_reg <= encoded_tx_hdr; +end + +endmodule diff --git a/tb/test_axis_baser_rx_64.py b/tb/test_axis_baser_rx_64.py new file mode 100755 index 000000000..c1a06fded --- /dev/null +++ b/tb/test_axis_baser_rx_64.py @@ -0,0 +1,438 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep +import eth_ep +import baser_serdes_ep +import xgmii_ep + +module = 'axis_baser_rx_64' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + HDR_WIDTH = 2 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + encoded_rx_data = Signal(intbv(0)[DATA_WIDTH:]) + encoded_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + + # Outputs + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tuser = Signal(bool(0)) + start_packet_0 = Signal(bool(0)) + start_packet_4 = Signal(bool(0)) + error_bad_frame = Signal(bool(0)) + error_bad_fcs = Signal(bool(0)) + + # sources and sinks + source = baser_serdes_ep.BaseRSerdesSource() + + source_logic = source.create_logic( + clk, + tx_data=encoded_rx_data, + tx_header=encoded_rx_hdr, + scramble=False, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tlast=m_axis_tlast, + tuser=m_axis_tuser, + 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, + encoded_rx_data=encoded_rx_data, + encoded_rx_hdr=encoded_rx_hdr, + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tlast=m_axis_tlast, + m_axis_tuser=m_axis_tuser, + start_packet_0=start_packet_0, + start_packet_4=start_packet_4, + error_bad_frame=error_bad_frame, + error_bad_fcs=error_bad_fcs + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + error_bad_frame_asserted = Signal(bool(0)) + error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (error_bad_frame): + error_bad_frame_asserted.next = 1 + if (error_bad_fcs): + error_bad_fcs_asserted.next = 1 + + @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,18))+list(range(64,82)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + xgmii_frame = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + source.send(xgmii_frame) + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: truncated frame, length %d" % payload_len) + current_test.next = 3 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + axis_frame1.data = axis_frame1.data[:-1] + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert error_bad_frame_asserted + assert error_bad_fcs_asserted + + assert rx_frame.user[-1] + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: errored frame, length %d" % payload_len) + current_test.next = 4 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis_fcs() + axis_frame2 = test_frame2.build_axis_fcs() + + error_bad_frame_asserted.next = 0 + error_bad_fcs_asserted.next = 0 + + xgmii_frame1 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame1)) + xgmii_frame2 = xgmii_ep.XGMIIFrame(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame2)) + + xgmii_frame1.error = 1 + + source.send(xgmii_frame1) + source.send(xgmii_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert error_bad_frame_asserted + assert not error_bad_fcs_asserted + + assert rx_frame.last_cycle_user + + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 5: test stream, length %d" % payload_len) + current_test.next = 5 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 6: test stream with zero IFG, length %d" % payload_len) + current_test.next = 6 + + source.ifg = 0 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + source.ifg = 12 + + yield delay(100) + + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 6: test stream with zero IFG and offset start, length %d" % payload_len) + current_test.next = 6 + + source.ifg = 0 + source.force_offset_start = True + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + source.ifg = 12 + source.force_offset_start = False + + yield delay(100) + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_baser_rx_64.v b/tb/test_axis_baser_rx_64.v new file mode 100644 index 000000000..cf644a276 --- /dev/null +++ b/tb/test_axis_baser_rx_64.v @@ -0,0 +1,105 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for axis_baser_rx_64 + */ +module test_axis_baser_rx_64; + +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter HDR_WIDTH = 2; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [DATA_WIDTH-1:0] encoded_rx_data = 0; +reg [HDR_WIDTH-1:0] encoded_rx_hdr = 1; + +// Outputs +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire m_axis_tuser; +wire start_packet_0; +wire start_packet_4; +wire error_bad_frame; +wire error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + encoded_rx_data, + encoded_rx_hdr + ); + $to_myhdl( + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tuser, + start_packet_0, + start_packet_4, + error_bad_frame, + error_bad_fcs + ); + + // dump file + $dumpfile("test_axis_baser_rx_64.lxt"); + $dumpvars(0, test_axis_baser_rx_64); +end + +axis_baser_rx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .HDR_WIDTH(HDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + .encoded_rx_data(encoded_rx_data), + .encoded_rx_hdr(encoded_rx_hdr), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tlast(m_axis_tlast), + .m_axis_tuser(m_axis_tuser), + .start_packet_0(start_packet_0), + .start_packet_4(start_packet_4), + .error_bad_frame(error_bad_frame), + .error_bad_fcs(error_bad_fcs) +); + +endmodule diff --git a/tb/test_axis_baser_tx_64.py b/tb/test_axis_baser_tx_64.py new file mode 100755 index 000000000..e64be4945 --- /dev/null +++ b/tb/test_axis_baser_tx_64.py @@ -0,0 +1,345 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep +import eth_ep +import baser_serdes_ep + +module = 'axis_baser_tx_64' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + HDR_WIDTH = 2 + ENABLE_PADDING = 1 + ENABLE_DIC = 1 + MIN_FRAME_LENGTH = 64 + + # 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)) + s_axis_tuser = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + s_axis_tready = Signal(bool(0)) + encoded_tx_data = Signal(intbv(0)[DATA_WIDTH:]) + encoded_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + start_packet_0 = Signal(bool(0)) + start_packet_4 = 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, + tready=s_axis_tready, + tlast=s_axis_tlast, + tuser=s_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = baser_serdes_ep.BaseRSerdesSink() + + sink_logic = sink.create_logic( + clk, + rx_data=encoded_tx_data, + rx_header=encoded_tx_hdr, + scramble=False, + 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_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tuser=s_axis_tuser, + encoded_tx_data=encoded_tx_data, + encoded_tx_hdr=encoded_tx_hdr, + ifg_delay=ifg_delay, + start_packet_0=start_packet_0, + start_packet_4=start_packet_4, + ) + + @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 + + ifg_delay.next = 12 + + # testbench stimulus + + for payload_len in list(range(1,18))+list(range(40,58)): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source.send(axis_frame) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + source.send(axis_frame1) + source.send(axis_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame1.eth_src_mac + assert eth_frame.eth_type == test_frame1.eth_type + assert eth_frame.payload.data.index(test_frame1.payload.data) == 0 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + 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(range(payload_len)) + test_frame1.update_fcs() + 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(range(payload_len)) + test_frame2.update_fcs() + + axis_frame1 = test_frame1.build_axis() + axis_frame2 = test_frame2.build_axis() + + axis_frame1.last_cycle_user = 1 + + source.send(axis_frame1) + source.send(axis_frame2) + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + assert rx_frame.error[-1] + + # bad packet + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame2.eth_src_mac + assert eth_frame.eth_type == test_frame2.eth_type + assert eth_frame.payload.data.index(test_frame2.payload.data) == 0 + + assert sink.empty() + + yield delay(100) + + for payload_len in list(range(46,54)): + yield clk.posedge + print("test 4: test stream, length %d" % payload_len) + current_test.next = 4 + + for i in range(10): + 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(range(payload_len)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + source.send(axis_frame) + + for i in range(10): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + assert len(eth_frame.payload.data) == max(payload_len, 46) + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_axis_baser_tx_64.v b/tb/test_axis_baser_tx_64.v new file mode 100644 index 000000000..efa195259 --- /dev/null +++ b/tb/test_axis_baser_tx_64.v @@ -0,0 +1,111 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for axis_baser_tx_64 + */ +module test_axis_baser_tx_64; + +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter HDR_WIDTH = 2; +parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; +parameter MIN_FRAME_LENGTH = 64; + +// 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; +reg s_axis_tuser = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire s_axis_tready; +wire [DATA_WIDTH-1:0] encoded_tx_data; +wire [HDR_WIDTH-1:0] encoded_tx_hdr; +wire start_packet_0; +wire start_packet_4; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tuser, + ifg_delay + ); + $to_myhdl( + s_axis_tready, + encoded_tx_data, + encoded_tx_hdr, + start_packet_0, + start_packet_4 + ); + + // dump file + $dumpfile("test_axis_baser_tx_64.lxt"); + $dumpvars(0, test_axis_baser_tx_64); +end + +axis_baser_tx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +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_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tuser(s_axis_tuser), + .encoded_tx_data(encoded_tx_data), + .encoded_tx_hdr(encoded_tx_hdr), + .ifg_delay(ifg_delay), + .start_packet_0(start_packet_0), + .start_packet_4(start_packet_4) +); + +endmodule diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py new file mode 100755 index 000000000..0eda4e24e --- /dev/null +++ b/tb/test_eth_mac_phy_10g.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep +import eth_ep +import xgmii_ep +import baser_serdes_ep + +module = 'eth_mac_phy_10g' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_baser_tx_64.v") +srcs.append("../rtl/axis_baser_rx_64.v") +srcs.append("../rtl/eth_mac_phy_10g_rx.v") +srcs.append("../rtl/eth_mac_phy_10g_tx.v") +srcs.append("../rtl/eth_phy_10g_rx_ber_mon.v") +srcs.append("../rtl/eth_phy_10g_rx_frame_sync.v") +srcs.append("../rtl/lfsr.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) + HDR_WIDTH = (DATA_WIDTH/32) + ENABLE_PADDING = 1 + ENABLE_DIC = 1 + MIN_FRAME_LENGTH = 64 + BIT_REVERSE = 0 + SCRAMBLER_DISABLE = 0 + SLIP_COUNT_WIDTH = 3 + COUNT_125US = 125000/6.4 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) + serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + ifg_delay = Signal(intbv(0)[8:]) + + serdes_rx_data_int = Signal(intbv(0)[DATA_WIDTH:]) + serdes_rx_hdr_int = Signal(intbv(1)[HDR_WIDTH:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) + serdes_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + serdes_rx_bitslip = Signal(bool(0)) + tx_start_packet_0 = Signal(bool(0)) + tx_start_packet_4 = Signal(bool(0)) + rx_start_packet_0 = Signal(bool(0)) + rx_start_packet_4 = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + rx_block_lock = Signal(bool(0)) + rx_high_ber = Signal(bool(0)) + + # sources and sinks + axis_source_pause = Signal(bool(0)) + + serdes_source = baser_serdes_ep.BaseRSerdesSource() + + serdes_source_logic = serdes_source.create_logic( + rx_clk, + tx_data=serdes_rx_data_int, + tx_header=serdes_rx_hdr_int, + name='serdes_source' + ) + + serdes_sink = baser_serdes_ep.BaseRSerdesSink() + + serdes_sink_logic = serdes_sink.create_logic( + tx_clk, + rx_data=serdes_tx_data, + rx_header=serdes_tx_hdr, + name='serdes_sink' + ) + + axis_source = axis_ep.AXIStreamSource() + + axis_source_logic = axis_source.create_logic( + tx_clk, + tx_rst, + tdata=tx_axis_tdata, + tkeep=tx_axis_tkeep, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + pause=axis_source_pause, + name='axis_source' + ) + + axis_sink = axis_ep.AXIStreamSink() + + axis_sink_logic = axis_sink.create_logic( + rx_clk, + rx_rst, + tdata=rx_axis_tdata, + tkeep=rx_axis_tkeep, + tvalid=rx_axis_tvalid, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + name='axis_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, + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + tx_axis_tdata=tx_axis_tdata, + tx_axis_tkeep=tx_axis_tkeep, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + rx_axis_tdata=rx_axis_tdata, + rx_axis_tkeep=rx_axis_tkeep, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + serdes_tx_data=serdes_tx_data, + serdes_tx_hdr=serdes_tx_hdr, + serdes_rx_data=serdes_rx_data, + serdes_rx_hdr=serdes_rx_hdr, + serdes_rx_bitslip=serdes_rx_bitslip, + tx_start_packet_0=tx_start_packet_0, + tx_start_packet_4=tx_start_packet_4, + rx_start_packet_0=rx_start_packet_0, + rx_start_packet_4=rx_start_packet_4, + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + rx_block_lock=rx_block_lock, + rx_high_ber=rx_high_ber, + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + tx_clk.next = not tx_clk + rx_clk.next = not rx_clk + + load_bit_offset = [] + + @instance + def shift_bits(): + bit_offset = 0 + last_data = 0 + + while True: + yield clk.posedge + + if load_bit_offset: + bit_offset = load_bit_offset.pop(0) + + if serdes_rx_bitslip: + bit_offset += 1 + + bit_offset = bit_offset % 66 + + data = int(serdes_rx_data_int) << 2 | int(serdes_rx_hdr_int) + + out_data = ((last_data | data << 66) >> 66-bit_offset) & 0x3ffffffffffffffff + + last_data = data + + serdes_rx_data.next = out_data >> 2 + serdes_rx_hdr.next = out_data & 3 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + tx_rst.next = 1 + rx_rst.next = 1 + yield clk.posedge + rst.next = 0 + tx_rst.next = 0 + rx_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + serdes_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + yield axis_sink.wait() + rx_frame = axis_sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + + yield serdes_sink.wait() + rx_frame = serdes_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_phy_10g.v b/tb/test_eth_mac_phy_10g.v new file mode 100644 index 000000000..2937762bc --- /dev/null +++ b/tb/test_eth_mac_phy_10g.v @@ -0,0 +1,173 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for eth_mac_phy_10g + */ +module test_eth_mac_phy_10g; + +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter HDR_WIDTH = (DATA_WIDTH/32); +parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; +parameter MIN_FRAME_LENGTH = 64; +parameter BIT_REVERSE = 0; +parameter SCRAMBLER_DISABLE = 0; +parameter SLIP_COUNT_WIDTH = 3; +parameter COUNT_125US = 125000/6.4; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg rx_clk = 0; +reg rx_rst = 0; +reg tx_clk = 0; +reg tx_rst = 0; +reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg [DATA_WIDTH-1:0] serdes_rx_data = 0; +reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [DATA_WIDTH-1:0] rx_axis_tdata; +wire [KEEP_WIDTH-1:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire [DATA_WIDTH-1:0] serdes_tx_data; +wire [HDR_WIDTH-1:0] serdes_tx_hdr; +wire serdes_rx_bitslip; +wire tx_start_packet_0; +wire tx_start_packet_4; +wire rx_start_packet_0; +wire rx_start_packet_4; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; +wire rx_block_lock; +wire rx_high_ber; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + rx_clk, + rx_rst, + tx_clk, + tx_rst, + tx_axis_tdata, + tx_axis_tkeep, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + serdes_rx_data, + serdes_rx_hdr, + ifg_delay + ); + $to_myhdl( + tx_axis_tready, + rx_axis_tdata, + rx_axis_tkeep, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + serdes_tx_data, + serdes_tx_hdr, + serdes_rx_bitslip, + tx_start_packet_0, + tx_start_packet_4, + rx_start_packet_0, + rx_start_packet_4, + rx_error_bad_frame, + rx_error_bad_fcs, + rx_block_lock, + rx_high_ber + ); + + // dump file + $dumpfile("test_eth_mac_phy_10g.lxt"); + $dumpvars(0, test_eth_mac_phy_10g); +end + +eth_mac_phy_10g #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), + .COUNT_125US(COUNT_125US) +) +UUT ( + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .serdes_tx_data(serdes_tx_data), + .serdes_tx_hdr(serdes_tx_hdr), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_bitslip(serdes_rx_bitslip), + .tx_start_packet_0(tx_start_packet_0), + .tx_start_packet_4(tx_start_packet_4), + .rx_start_packet_0(rx_start_packet_0), + .rx_start_packet_4(rx_start_packet_4), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/tb/test_eth_mac_phy_10g_fifo.py b/tb/test_eth_mac_phy_10g_fifo.py new file mode 100755 index 000000000..df34ef405 --- /dev/null +++ b/tb/test_eth_mac_phy_10g_fifo.py @@ -0,0 +1,344 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep +import eth_ep +import xgmii_ep +import baser_serdes_ep + +module = 'eth_mac_phy_10g_fifo' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_baser_tx_64.v") +srcs.append("../rtl/axis_baser_rx_64.v") +srcs.append("../rtl/eth_mac_phy_10g.v") +srcs.append("../rtl/eth_mac_phy_10g_rx.v") +srcs.append("../rtl/eth_mac_phy_10g_tx.v") +srcs.append("../rtl/eth_phy_10g_rx_ber_mon.v") +srcs.append("../rtl/eth_phy_10g_rx_frame_sync.v") +srcs.append("../rtl/lfsr.v") +srcs.append("../lib/axis/rtl/axis_async_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = int(DATA_WIDTH/8) + CTRL_WIDTH = int(DATA_WIDTH/8) + HDR_WIDTH = int(DATA_WIDTH/32) + ENABLE_PADDING = 1 + ENABLE_DIC = 1 + MIN_FRAME_LENGTH = 64 + BIT_REVERSE = 0 + SCRAMBLER_DISABLE = 0 + SLIP_COUNT_WIDTH = 3 + COUNT_125US = 125000/6.4 + TX_FIFO_ADDR_WIDTH = 12-(KEEP_WIDTH-1).bit_length() + TX_FRAME_FIFO = 1 + TX_DROP_BAD_FRAME = TX_FRAME_FIFO + TX_DROP_WHEN_FULL = 0 + RX_FIFO_ADDR_WIDTH = 12-(KEEP_WIDTH-1).bit_length() + RX_FRAME_FIFO = 1 + RX_DROP_BAD_FRAME = RX_FRAME_FIFO + RX_DROP_WHEN_FULL = RX_FRAME_FIFO + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + logic_clk = Signal(bool(0)) + logic_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + rx_axis_tready = Signal(bool(0)) + serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) + serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + ifg_delay = Signal(intbv(0)[8:]) + + serdes_rx_data_int = Signal(intbv(0)[DATA_WIDTH:]) + serdes_rx_hdr_int = Signal(intbv(1)[HDR_WIDTH:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) + serdes_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + serdes_rx_bitslip = Signal(bool(0)) + tx_fifo_overflow = Signal(bool(0)) + tx_fifo_bad_frame = Signal(bool(0)) + tx_fifo_good_frame = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + rx_block_lock = Signal(bool(0)) + rx_high_ber = Signal(bool(0)) + rx_fifo_overflow = Signal(bool(0)) + rx_fifo_bad_frame = Signal(bool(0)) + rx_fifo_good_frame = Signal(bool(0)) + + # sources and sinks + axis_source_pause = Signal(bool(0)) + + serdes_source = baser_serdes_ep.BaseRSerdesSource() + + serdes_source_logic = serdes_source.create_logic( + rx_clk, + tx_data=serdes_rx_data_int, + tx_header=serdes_rx_hdr_int, + name='serdes_source' + ) + + serdes_sink = baser_serdes_ep.BaseRSerdesSink() + + serdes_sink_logic = serdes_sink.create_logic( + tx_clk, + rx_data=serdes_tx_data, + rx_header=serdes_tx_hdr, + name='serdes_sink' + ) + + axis_source = axis_ep.AXIStreamSource() + + axis_source_logic = axis_source.create_logic( + logic_clk, + logic_rst, + tdata=tx_axis_tdata, + tkeep=tx_axis_tkeep, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + pause=axis_source_pause, + name='axis_source' + ) + + axis_sink = axis_ep.AXIStreamSink() + + axis_sink_logic = axis_sink.create_logic( + logic_clk, + logic_rst, + tdata=rx_axis_tdata, + tkeep=rx_axis_tkeep, + tvalid=rx_axis_tvalid, + tready=rx_axis_tready, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + name='axis_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, + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + logic_clk=logic_clk, + logic_rst=logic_rst, + tx_axis_tdata=tx_axis_tdata, + tx_axis_tkeep=tx_axis_tkeep, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + rx_axis_tdata=rx_axis_tdata, + rx_axis_tkeep=rx_axis_tkeep, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tready=rx_axis_tready, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + serdes_tx_data=serdes_tx_data, + serdes_tx_hdr=serdes_tx_hdr, + serdes_rx_data=serdes_rx_data, + serdes_rx_hdr=serdes_rx_hdr, + serdes_rx_bitslip=serdes_rx_bitslip, + tx_fifo_overflow=tx_fifo_overflow, + tx_fifo_bad_frame=tx_fifo_bad_frame, + tx_fifo_good_frame=tx_fifo_good_frame, + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + rx_block_lock=rx_block_lock, + rx_high_ber=rx_high_ber, + rx_fifo_overflow=rx_fifo_overflow, + rx_fifo_bad_frame=rx_fifo_bad_frame, + rx_fifo_good_frame=rx_fifo_good_frame, + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + tx_clk.next = not tx_clk + rx_clk.next = not rx_clk + logic_clk.next = not logic_clk + + load_bit_offset = [] + + @instance + def shift_bits(): + bit_offset = 0 + last_data = 0 + + while True: + yield clk.posedge + + if load_bit_offset: + bit_offset = load_bit_offset.pop(0) + + if serdes_rx_bitslip: + bit_offset += 1 + + bit_offset = bit_offset % 66 + + data = int(serdes_rx_data_int) << 2 | int(serdes_rx_hdr_int) + + out_data = ((last_data | data << 66) >> 66-bit_offset) & 0x3ffffffffffffffff + + last_data = data + + serdes_rx_data.next = out_data >> 2 + serdes_rx_hdr.next = out_data & 3 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + tx_rst.next = 1 + rx_rst.next = 1 + logic_rst.next = 1 + yield clk.posedge + rst.next = 0 + tx_rst.next = 0 + rx_rst.next = 0 + logic_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + serdes_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + yield axis_sink.wait() + rx_frame = axis_sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + + yield serdes_sink.wait() + rx_frame = serdes_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_phy_10g_fifo.v b/tb/test_eth_mac_phy_10g_fifo.v new file mode 100644 index 000000000..c838c79b4 --- /dev/null +++ b/tb/test_eth_mac_phy_10g_fifo.v @@ -0,0 +1,204 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for eth_mac_phy_10g_fifo + */ +module test_eth_mac_phy_10g_fifo; + +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter HDR_WIDTH = (DATA_WIDTH/32); +parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; +parameter MIN_FRAME_LENGTH = 64; +parameter BIT_REVERSE = 0; +parameter SCRAMBLER_DISABLE = 0; +parameter SLIP_COUNT_WIDTH = 3; +parameter COUNT_125US = 125000/6.4; +parameter TX_FIFO_ADDR_WIDTH = 12-$clog2(KEEP_WIDTH); +parameter TX_FRAME_FIFO = 1; +parameter TX_DROP_BAD_FRAME = TX_FRAME_FIFO; +parameter TX_DROP_WHEN_FULL = 0; +parameter RX_FIFO_ADDR_WIDTH = 12-$clog2(KEEP_WIDTH); +parameter RX_FRAME_FIFO = 1; +parameter RX_DROP_BAD_FRAME = RX_FRAME_FIFO; +parameter RX_DROP_WHEN_FULL = RX_FRAME_FIFO; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg rx_clk = 0; +reg rx_rst = 0; +reg tx_clk = 0; +reg tx_rst = 0; +reg logic_clk = 0; +reg logic_rst = 0; +reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg rx_axis_tready = 0; +reg [DATA_WIDTH-1:0] serdes_rx_data = 0; +reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [DATA_WIDTH-1:0] rx_axis_tdata; +wire [KEEP_WIDTH-1:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire [DATA_WIDTH-1:0] serdes_tx_data; +wire [HDR_WIDTH-1:0] serdes_tx_hdr; +wire serdes_rx_bitslip; +wire tx_fifo_overflow; +wire tx_fifo_bad_frame; +wire tx_fifo_good_frame; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; +wire rx_block_lock; +wire rx_high_ber; +wire rx_fifo_overflow; +wire rx_fifo_bad_frame; +wire rx_fifo_good_frame; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + rx_clk, + rx_rst, + tx_clk, + tx_rst, + logic_clk, + logic_rst, + tx_axis_tdata, + tx_axis_tkeep, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + rx_axis_tready, + serdes_rx_data, + serdes_rx_hdr, + ifg_delay + ); + $to_myhdl( + tx_axis_tready, + rx_axis_tdata, + rx_axis_tkeep, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + serdes_tx_data, + serdes_tx_hdr, + serdes_rx_bitslip, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, + rx_error_bad_frame, + rx_error_bad_fcs, + rx_block_lock, + rx_high_ber, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame + ); + + // dump file + $dumpfile("test_eth_mac_phy_10g_fifo.lxt"); + $dumpvars(0, test_eth_mac_phy_10g_fifo); +end + +eth_mac_phy_10g_fifo #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), + .COUNT_125US(COUNT_125US), + .TX_FIFO_ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .TX_FRAME_FIFO(TX_FRAME_FIFO), + .TX_DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .TX_DROP_WHEN_FULL(TX_DROP_WHEN_FULL), + .RX_FIFO_ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), + .RX_FRAME_FIFO(RX_FRAME_FIFO), + .RX_DROP_BAD_FRAME(RX_DROP_BAD_FRAME), + .RX_DROP_WHEN_FULL(RX_DROP_WHEN_FULL) +) +UUT ( + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .logic_clk(logic_clk), + .logic_rst(logic_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .serdes_tx_data(serdes_tx_data), + .serdes_tx_hdr(serdes_tx_hdr), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_bitslip(serdes_rx_bitslip), + .tx_fifo_overflow(tx_fifo_overflow), + .tx_fifo_bad_frame(tx_fifo_bad_frame), + .tx_fifo_good_frame(tx_fifo_good_frame), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber), + .rx_fifo_overflow(rx_fifo_overflow), + .rx_fifo_bad_frame(rx_fifo_bad_frame), + .rx_fifo_good_frame(rx_fifo_good_frame), + .ifg_delay(ifg_delay) +); + +endmodule From c1fe89db628c4af3ee8e71c35b409076a2e23168 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 31 Jan 2019 18:14:06 -0800 Subject: [PATCH 521/617] Add bit reverse support to serdes endpoint --- tb/baser_serdes_ep.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tb/baser_serdes_ep.py b/tb/baser_serdes_ep.py index 2dbd16bbc..0c085bb05 100644 --- a/tb/baser_serdes_ep.py +++ b/tb/baser_serdes_ep.py @@ -118,6 +118,7 @@ class BaseRSerdesSource(object): tx_header, enable=True, scramble=True, + reverse=False, name=None ): @@ -345,6 +346,11 @@ class BaseRSerdesSource(object): scrambler_state = (scrambler_state & 0x1ffffffffffffff) << 1 data = b + if reverse: + # bit reverse + data = sum(1 << (63-i) for i in range(64) if (data >> i) & 1) + header = sum(1 << (1-i) for i in range(2) if (header >> i) & 1) + tx_data.next = data tx_header.next = header @@ -382,6 +388,7 @@ class BaseRSerdesSink(object): rx_header, enable=True, scramble=True, + reverse=False, name=None ): @@ -408,6 +415,11 @@ class BaseRSerdesSink(object): data = int(rx_data) header = int(rx_header) + if reverse: + # bit reverse + data = sum(1 << (63-i) for i in range(64) if (data >> i) & 1) + header = sum(1 << (1-i) for i in range(2) if (header >> i) & 1) + if scramble: # 64b66b descrambler b = 0 From 22b3d05954a95daa8e91b3ceb877f1e7dba3e1b0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 31 Jan 2019 18:20:31 -0800 Subject: [PATCH 522/617] Update readme --- README.md | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ed9f6decc..4f9b7b7b9 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,16 @@ Collection of Ethernet-related components for both gigabit and 10G packet processing (8 bit and 64 bit datapaths). Includes modules for handling Ethernet frames as well as IP, UDP, and ARP and the components for constructing a complete UDP/IP stack. Includes MAC modules for gigabit and -10G and a 10G PCS/PMA PHY module. Also includes full MyHDL testbench with -intelligent bus cosimulation endpoints. +10G, a 10G PCS/PMA PHY module, and a 10G combination MAC/PCS/PMA module. Also +includes full MyHDL testbench with intelligent bus cosimulation endpoints. For IP and ARP support only, use ip_complete (1G) or ip_complete_64 (10G). For UDP, IP, and ARP support, use udp_complete (1G) or udp_complete_64 (10G). Top level gigabit and 10G MAC modules are eth_mac_*, with various interfaces -and with/without FIFOs. Top level 10G PCS/PMA PHY module is eth_phy_10g. +and with/without FIFOs. Top level 10G PCS/PMA PHY module is eth_phy_10g. Top +level 10G MAC/PCS/PMA combination module is eth_mac_phy_10g. ## Documentation @@ -155,6 +156,22 @@ bits. 10G Ethernet MAC with XGMII interface and FIFOs. Datapath selectable between 32 and 64 bits. +### eth_mac_phy_10g module + +10G Ethernet MAC/PHY combination module with SERDES interface. + +### eth_mac_phy_10g_fifo module + +10G Ethernet MAC/PHY combination module with SERDES interface and FIFOs. + +### eth_mac_phy_10g_rx module + +10G Ethernet MAC/PHY combination module with SERDES interface, RX path. + +### eth_mac_phy_10g_tx module + +10G Ethernet MAC/PHY combination module with SERDES interface, TX path. + ### eth_mux module Ethernet frame muliplexer with parametrizable data width and port count. @@ -370,6 +387,10 @@ and data lines. rtl/eth_mac_1g_rgmii_fifo.v : Tri-mode Ethernet RGMII MAC with FIFO rtl/eth_mac_10g.v : 10G Etherent XGMII MAC rtl/eth_mac_10g_fifo.v : 10G Etherent XGMII MAC with FIFO + rtl/eth_mac_phy_10g.v : 10G Etherent XGMII MAC/PHY + rtl/eth_mac_phy_10g_fifo.v : 10G Etherent XGMII MAC/PHY with FIFO + rtl/eth_mac_phy_10g_rx.v : 10G Etherent XGMII MAC/PHY RX with FIFO + rtl/eth_mac_phy_10g_tx.v : 10G Etherent XGMII MAC/PHY TX with FIFO rtl/eth_mux.v : Ethernet frame multiplexer rtl/gmii_phy_if.v : GMII PHY interface rtl/iddr.v : Generic DDR input register From 52058cb5de68b1192a0c7e7a33dc6a0650e4c84c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 5 Feb 2019 18:28:42 -0800 Subject: [PATCH 523/617] Swap out PHY in VCU118 example design --- example/VCU118/fpga_10g/fpga.xdc | 43 +- example/VCU118/fpga_10g/fpga/Makefile | 9 +- .../fpga_10g/ip/gig_ethernet_pcs_pma_0.xci | 230 ++- .../fpga_10g/ip/gtwizard_ultrascale_0.xci | 1408 +++++++++++++++++ .../fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci | 131 -- example/VCU118/fpga_10g/rtl/fpga.v | 940 +++++------ 6 files changed, 2103 insertions(+), 658 deletions(-) create mode 100644 example/VCU118/fpga_10g/ip/gtwizard_ultrascale_0.xci delete mode 100644 example/VCU118/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci diff --git a/example/VCU118/fpga_10g/fpga.xdc b/example/VCU118/fpga_10g/fpga.xdc index 5f67fd2b1..5dd36a0b6 100644 --- a/example/VCU118/fpga_10g/fpga.xdc +++ b/example/VCU118/fpga_10g/fpga.xdc @@ -4,6 +4,7 @@ # General configuration set_property CFGBVS GND [current_design] set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] # System clocks # 300 MHz @@ -84,23 +85,23 @@ set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generat # QSFP28 Interfaces set_property -dict {LOC V7 } [get_ports qsfp1_tx1_p] ;# MGTYTXN0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 -set_property -dict {LOC V6 } [get_ports qsfp1_tx1_n] ;# MGTYTXP0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC V6 } [get_ports qsfp1_tx1_n] ;# MGTYTXP0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 set_property -dict {LOC Y2 } [get_ports qsfp1_rx1_p] ;# MGTYTXN1_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 -set_property -dict {LOC Y1 } [get_ports qsfp1_rx1_n] ;# MGTYTXP1_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC Y1 } [get_ports qsfp1_rx1_n] ;# MGTYTXP1_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 set_property -dict {LOC T7 } [get_ports qsfp1_tx2_p] ;# MGTYTXN2_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 -set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXP2_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXP2_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 set_property -dict {LOC W4 } [get_ports qsfp1_rx2_p] ;# MGTYTXN3_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 -set_property -dict {LOC W3 } [get_ports qsfp1_rx2_n] ;# MGTYTXP3_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC W3 } [get_ports qsfp1_rx2_n] ;# MGTYTXP3_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 set_property -dict {LOC P7 } [get_ports qsfp1_tx3_p] ;# MGTYTXN0_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 -set_property -dict {LOC P6 } [get_ports qsfp1_tx3_n] ;# MGTYTXP0_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC P6 } [get_ports qsfp1_tx3_n] ;# MGTYTXP0_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 set_property -dict {LOC V2 } [get_ports qsfp1_rx3_p] ;# MGTYTXN1_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 -set_property -dict {LOC V1 } [get_ports qsfp1_rx3_n] ;# MGTYTXP1_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC V1 } [get_ports qsfp1_rx3_n] ;# MGTYTXP1_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 set_property -dict {LOC M7 } [get_ports qsfp1_tx4_p] ;# MGTYTXN2_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 -set_property -dict {LOC M6 } [get_ports qsfp1_tx4_n] ;# MGTYTXP2_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC M6 } [get_ports qsfp1_tx4_n] ;# MGTYTXP2_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 set_property -dict {LOC U4 } [get_ports qsfp1_rx4_p] ;# MGTYTXN3_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 -set_property -dict {LOC U3 } [get_ports qsfp1_rx4_n] ;# MGTYTXP3_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC U3 } [get_ports qsfp1_rx4_n] ;# MGTYTXP3_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 set_property -dict {LOC W9 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_231 from U38.4 -set_property -dict {LOC W8 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_231 from U38.5 +#set_property -dict {LOC W8 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_231 from U38.5 #set_property -dict {LOC U9 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_231 from U57.28 #set_property -dict {LOC U8 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U57.29 #set_property -dict {LOC AM23 IOSTANDARD LVDS} [get_ports qsfp1_recclk_p] ;# to U57.16 @@ -116,23 +117,23 @@ create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_ set_clock_groups -asynchronous -group [get_clocks qsfp1_mgt_refclk_0 -include_generated_clocks] set_property -dict {LOC L5 } [get_ports qsfp2_tx1_p] ;# MGTYTXN0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 -set_property -dict {LOC L4 } [get_ports qsfp2_tx1_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC L4 } [get_ports qsfp2_tx1_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 set_property -dict {LOC T2 } [get_ports qsfp2_rx1_p] ;# MGTYTXN1_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 -set_property -dict {LOC T1 } [get_ports qsfp2_rx1_n] ;# MGTYTXP1_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC T1 } [get_ports qsfp2_rx1_n] ;# MGTYTXP1_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 set_property -dict {LOC K7 } [get_ports qsfp2_tx2_p] ;# MGTYTXN2_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 -set_property -dict {LOC K6 } [get_ports qsfp2_tx2_n] ;# MGTYTXP2_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC K6 } [get_ports qsfp2_tx2_n] ;# MGTYTXP2_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 set_property -dict {LOC R4 } [get_ports qsfp2_rx2_p] ;# MGTYTXN3_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 -set_property -dict {LOC R3 } [get_ports qsfp2_rx2_n] ;# MGTYTXP3_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC R3 } [get_ports qsfp2_rx2_n] ;# MGTYTXP3_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 set_property -dict {LOC J5 } [get_ports qsfp2_tx3_p] ;# MGTYTXN0_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 -set_property -dict {LOC J4 } [get_ports qsfp2_tx3_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC J4 } [get_ports qsfp2_tx3_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 set_property -dict {LOC P2 } [get_ports qsfp2_rx3_p] ;# MGTYTXN1_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 -set_property -dict {LOC P1 } [get_ports qsfp2_rx3_n] ;# MGTYTXP1_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC P1 } [get_ports qsfp2_rx3_n] ;# MGTYTXP1_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 set_property -dict {LOC H7 } [get_ports qsfp2_tx4_p] ;# MGTYTXN2_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 -set_property -dict {LOC H6 } [get_ports qsfp2_tx4_n] ;# MGTYTXP2_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC H6 } [get_ports qsfp2_tx4_n] ;# MGTYTXP2_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 set_property -dict {LOC M2 } [get_ports qsfp2_rx4_p] ;# MGTYTXN3_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 -set_property -dict {LOC M1 } [get_ports qsfp2_rx4_n] ;# MGTYTXP3_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 -set_property -dict {LOC R9 } [get_ports qsfp2_mgt_refclk_0_p] ;# MGTREFCLK0P_232 from U104.13 -set_property -dict {LOC R8 } [get_ports qsfp2_mgt_refclk_0_n] ;# MGTREFCLK0N_232 from U104.14 +#set_property -dict {LOC M1 } [get_ports qsfp2_rx4_n] ;# MGTYTXP3_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC R9 } [get_ports qsfp2_mgt_refclk_0_p] ;# MGTREFCLK0P_232 from U104.13 +#set_property -dict {LOC R8 } [get_ports qsfp2_mgt_refclk_0_n] ;# MGTREFCLK0N_232 from U104.14 #set_property -dict {LOC N9 } [get_ports qsfp2_mgt_refclk_1_p] ;# MGTREFCLK1P_232 from U57.35 #set_property -dict {LOC N8 } [get_ports qsfp2_mgt_refclk_1_n] ;# MGTREFCLK1N_232 from U57.34 #set_property -dict {LOC AP23 IOSTANDARD LVDS} [get_ports qsfp2_recclk_p] ;# to U57.12 @@ -144,8 +145,8 @@ set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports qsfp2_intl] set_property -dict {LOC AT24 IOSTANDARD LVCMOS18} [get_ports qsfp2_lpmode] # 156.25 MHz MGT reference clock -create_clock -period 6.400 -name qsfp2_mgt_refclk_0 [get_ports qsfp2_mgt_refclk_0_p] -set_clock_groups -asynchronous -group [get_clocks qsfp2_mgt_refclk_0 -include_generated_clocks] +#create_clock -period 6.400 -name qsfp2_mgt_refclk_0 [get_ports qsfp2_mgt_refclk_0_p] +#set_clock_groups -asynchronous -group [get_clocks qsfp2_mgt_refclk_0 -include_generated_clocks] # I2C interface set_property -dict {LOC AM24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_scl] diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile index 82fc9d2b3..37f715b9a 100644 --- a/example/VCU118/fpga_10g/fpga/Makefile +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -19,6 +19,13 @@ SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/eth_phy_10g.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v +SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v @@ -51,7 +58,7 @@ XDC_FILES += clock.xdc # IP XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci -XCI_FILES += ip/ten_gig_eth_pcs_pma_0.xci +XCI_FILES += ip/gtwizard_ultrascale_0.xci include ../common/vivado.mk diff --git a/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci index c23253498..129b30ccd 100644 --- a/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci +++ b/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci @@ -9,6 +9,207 @@ gig_ethernet_pcs_pma_0 + 1 + 1 + 1 + 1 + + + + 0 + + + + 0 + + + 0 + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + false + false + false + false + 0 + + + + 0 + + + + 0 + false + 100000000 + + + + 0 + + + + 0 + + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + false + false + false + false + 0 + 0 + + + + 100000000 + 0 + 0.000 + + + + 100000000 + 0 + 0.000 + false + false + false + + + + 100000000 + 0 + 0.000 + 0 + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + ACTIVE_LOW + ACTIVE_LOW + ACTIVE_LOW + ACTIVE_LOW + 1 + 0 + 0 + 0 + + 1 + 100000000 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 0.000 + AXI4LITE + READ_WRITE + 0 + 0 + 0 + 0 + 0 + + + 100000000 + 0 + 0.000 + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 true 0 0 @@ -20,7 +221,7 @@ DIFF_PAIR_2 DIFF_PAIR_1 virtexuplus - Sync + 0 gig_ethernet_pcs_pma_0 50.0 false @@ -38,6 +239,7 @@ GTH false true + false false false false @@ -59,6 +261,7 @@ xcvu9p false 1 + false true Sync gig_ethernet_pcs_pma_0 @@ -98,7 +301,8 @@ 0 false virtexuplus - + + xcvu9p flga2104 VERILOG @@ -109,17 +313,35 @@ TRUE TRUE IP_Flow - 0 + 5 TRUE . . - 2017.2.1 + 2018.3 OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + diff --git a/example/VCU118/fpga_10g/ip/gtwizard_ultrascale_0.xci b/example/VCU118/fpga_10g/ip/gtwizard_ultrascale_0.xci new file mode 100644 index 000000000..a596a88d5 --- /dev/null +++ b/example/VCU118/fpga_10g/ip/gtwizard_ultrascale_0.xci @@ -0,0 +1,1408 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gtwizard_ultrascale_0 + + + "000000000000000000000000000000000000000011111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + 2 + 2578.125 + 0 + 0 + 125 + 67 + 3 + 2 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 1 + 250 + 0 + 0 + 0 + 0 + 0 + 1 + "00000000" + "00000000" + 1 + 4 + 0 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000" + 0 + "00000000" + 1 + 0 + 5000 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + 0 + "1010000011" + 0 + "0101111100" + 4 + 1 + 64 + 10.3125 + 144 + 1 + 156.2500000 + 4 + 0 + 0x000000000000000000000000000000000000000000000000 + 156.25 + 0 + 0 + 0 + 1 + 1 + 0 + 64 + 156.2500000 + 156.2500000 + 0 + 257.8125 + 0 + 8 + 2 + 0 + 0 + 0 + 156.25 + 0 + 0 + 1 + 4 + 1 + 64 + 10.3125 + 144 + 1 + 156.2500000 + 4 + 0 + 156.25 + 0 + 0 + 1 + 1 + 0 + 64 + 156.2500000 + 156.2500000 + 1 + X1Y55 X1Y54 X1Y53 X1Y52 X1Y51 X1Y50 X1Y49 X1Y48 + gtwizard_ultrascale_0 + 0 + 0 + + 125 + BOTH + 0 + GTY + 2 + 20 + 96 + 1 + gtye4 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + -1 + -1 + -1 + -1 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + 1 + 1 + 0 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + -1 + 0 + 0 + 0 + -1 + 0 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 14 + 0 + 10GBASE-R + 5 + 156.2500000 + 8 + 2 + 156.2500000 + false + CORE + NONE + CORE + CORE + EXAMPLE_DESIGN + CORE + EXAMPLE_DESIGN + EXAMPLE_DESIGN + false + NAME + false + 250 + false + false + 250 + GTY-10GBASE-R + 0 + MULTI + 1 + ENABLE + DISABLE + ENABLE + 00000000 + false + false + false + false + false + false + false + false + 00000000 + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 4 + 1 + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + false + false + false + false + false + false + false + false + 00000000 + DISABLE + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 0 + 5000 + ENABLE + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 1 + false + 0000000000 + false + 1010000011 + NONE + false + 0101111100 + true + 0 + AC + 64B66B_ASYNC + true + AUTO + 64 + 6.1862627 + -20 + 10.3125 + X1Y48 + RXPROGDIVCLK + QPLL0 + 200 + 0 + + 156.25 + X1Y55 clk0-1 X1Y54 clk0-1 X1Y53 clk0-1 X1Y52 clk0-1 + OFF + 0 + PROGRAMMABLE + 800 + 64 + 15 + false + 0 + 10.3125 + 257.8125 + 0 + false + QPLL0 + 156.25 + 1 + ENABLE + 64B66B_ASYNC + CUSTOM + true + 64 + 10.3125 + X1Y48 + TXPROGDIVCLK + QPLL0 + 0 + 156.25 + X1Y55 clk0-1 X1Y54 clk0-1 X1Y53 clk0-1 X1Y52 clk0-1 + 64 + false + 1 + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + true + true + false + true + true + true + false + true + true + true + false + false + false + false + false + true + false + false + false + false + false + false + false + true + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + virtexuplus + + + xcvu9p + flga2104 + VERILOG + + MIXED + -2L + E + TRUE + TRUE + IP_Flow + 5 + TRUE + . + + . + 2018.3 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/VCU118/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci b/example/VCU118/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci deleted file mode 100644 index 2d73f4a1c..000000000 --- a/example/VCU118/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci +++ /dev/null @@ -1,131 +0,0 @@ - - - xilinx.com - xci - unknown - 1.0 - - - ten_gig_eth_pcs_pma_0 - - - 0 - 75 - 64 - 7 - BASE-R - Asynchronous - Ethernet PCS/PMA 64-bit - MII - 0 - 0 - 0 - 0 - 0 - virtexuplus - 0 - 125 - Quad X0Y0 - 1 - 156.25 - GTY - None - 0 - 0 - 0 - 1 - 0 - X1Y48 - X1Y49 - X1Y50 - X1Y51 - 10 - 4 - 0 - 2 - 0 - 0 - 4 - 1 - 0 - 0 - 100 - BASE-R - Asynchronous - Ethernet PCS/PMA 64-bit - ten_gig_eth_pcs_pma_0 - MII - Custom - 0 - 0 - 0 - 0 - 0 - Custom - 0 - 125 - Quad_X1Y12 - 1 - 156.25 - GTY - None - 0 - 0 - 0 - 1 - 0 - X1Y48 - X1Y49 - X1Y50 - X1Y51 - 10 - 4 - 0 - 2 - 0 - 0 - false - 1 - virtexuplus - - xcvu9p - flga2104 - VERILOG - - MIXED - -2L - E - TRUE - TRUE - IP_Flow - 0 - TRUE - . - - . - 2017.2.1 - OUT_OF_CONTEXT - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/VCU118/fpga_10g/rtl/fpga.v b/example/VCU118/fpga_10g/rtl/fpga.v index 3d704efb3..7ffe4ac34 100644 --- a/example/VCU118/fpga_10g/rtl/fpga.v +++ b/example/VCU118/fpga_10g/rtl/fpga.v @@ -102,8 +102,8 @@ module fpga ( output wire qsfp2_tx4_n, input wire qsfp2_rx4_p, input wire qsfp2_rx4_n, - input wire qsfp2_mgt_refclk_0_p, - input wire qsfp2_mgt_refclk_0_n, + // input wire qsfp2_mgt_refclk_0_p, + // input wire qsfp2_mgt_refclk_0_n, // input wire qsfp2_mgt_refclk_1_p, // input wire qsfp2_mgt_refclk_1_n, // output wire qsfp2_recclk_p, @@ -282,11 +282,11 @@ sync_signal_inst ( // SI570 I2C wire i2c_scl_i; -wire i2c_scl_o = 1; -wire i2c_scl_t = 1; +wire i2c_scl_o = 1'b1; +wire i2c_scl_t = 1'b1; wire i2c_sda_i; -wire i2c_sda_o = 1; -wire i2c_sda_t = 1; +wire i2c_sda_o = 1'b1; +wire i2c_sda_t = 1'b1; assign i2c_scl_i = i2c_scl; assign i2c_scl = i2c_scl_t ? 1'bz : i2c_scl_o; @@ -302,7 +302,7 @@ wire qsfp1_tx_clk_1_int; wire qsfp1_tx_rst_1_int; wire [63:0] qsfp1_txd_1_int; wire [7:0] qsfp1_txc_1_int; -wire qsfp1_rx_clk_1_int = qsfp1_tx_clk_1_int; +wire qsfp1_rx_clk_1_int; wire qsfp1_rx_rst_1_int; wire [63:0] qsfp1_rxd_1_int; wire [7:0] qsfp1_rxc_1_int; @@ -310,7 +310,7 @@ wire qsfp1_tx_clk_2_int; wire qsfp1_tx_rst_2_int; wire [63:0] qsfp1_txd_2_int; wire [7:0] qsfp1_txc_2_int; -wire qsfp1_rx_clk_2_int = qsfp1_tx_clk_2_int; +wire qsfp1_rx_clk_2_int; wire qsfp1_rx_rst_2_int; wire [63:0] qsfp1_rxd_2_int; wire [7:0] qsfp1_rxc_2_int; @@ -318,7 +318,7 @@ wire qsfp1_tx_clk_3_int; wire qsfp1_tx_rst_3_int; wire [63:0] qsfp1_txd_3_int; wire [7:0] qsfp1_txc_3_int; -wire qsfp1_rx_clk_3_int = qsfp1_tx_clk_3_int; +wire qsfp1_rx_clk_3_int; wire qsfp1_rx_rst_3_int; wire [63:0] qsfp1_rxd_3_int; wire [7:0] qsfp1_rxc_3_int; @@ -326,7 +326,7 @@ wire qsfp1_tx_clk_4_int; wire qsfp1_tx_rst_4_int; wire [63:0] qsfp1_txd_4_int; wire [7:0] qsfp1_txc_4_int; -wire qsfp1_rx_clk_4_int = qsfp1_tx_clk_4_int; +wire qsfp1_rx_clk_4_int; wire qsfp1_rx_rst_4_int; wire [63:0] qsfp1_rxd_4_int; wire [7:0] qsfp1_rxc_4_int; @@ -339,7 +339,7 @@ wire qsfp2_tx_clk_1_int; wire qsfp2_tx_rst_1_int; wire [63:0] qsfp2_txd_1_int; wire [7:0] qsfp2_txc_1_int; -wire qsfp2_rx_clk_1_int = qsfp2_tx_clk_1_int; +wire qsfp2_rx_clk_1_int; wire qsfp2_rx_rst_1_int; wire [63:0] qsfp2_rxd_1_int; wire [7:0] qsfp2_rxc_1_int; @@ -347,7 +347,7 @@ wire qsfp2_tx_clk_2_int; wire qsfp2_tx_rst_2_int; wire [63:0] qsfp2_txd_2_int; wire [7:0] qsfp2_txc_2_int; -wire qsfp2_rx_clk_2_int = qsfp2_tx_clk_2_int; +wire qsfp2_rx_clk_2_int; wire qsfp2_rx_rst_2_int; wire [63:0] qsfp2_rxd_2_int; wire [7:0] qsfp2_rxc_2_int; @@ -355,7 +355,7 @@ wire qsfp2_tx_clk_3_int; wire qsfp2_tx_rst_3_int; wire [63:0] qsfp2_txd_3_int; wire [7:0] qsfp2_txc_3_int; -wire qsfp2_rx_clk_3_int = qsfp2_tx_clk_3_int; +wire qsfp2_rx_clk_3_int; wire qsfp2_rx_rst_3_int; wire [63:0] qsfp2_rxd_3_int; wire [7:0] qsfp2_rxc_3_int; @@ -363,7 +363,7 @@ wire qsfp2_tx_clk_4_int; wire qsfp2_tx_rst_4_int; wire [63:0] qsfp2_txd_4_int; wire [7:0] qsfp2_txc_4_int; -wire qsfp2_rx_clk_4_int = qsfp2_tx_clk_4_int; +wire qsfp2_rx_clk_4_int; wire qsfp2_rx_rst_4_int; wire [63:0] qsfp2_rxd_4_int; wire [7:0] qsfp2_rxc_4_int; @@ -378,555 +378,493 @@ wire qsfp2_rx_block_lock_2; wire qsfp2_rx_block_lock_3; wire qsfp2_rx_block_lock_4; -assign clk_156mhz_int = qsfp1_tx_clk_1_int; -assign rst_156mhz_int = qsfp1_tx_rst_1_int; +wire qsfp1_mgt_refclk_0; -ten_gig_eth_pcs_pma_0 -ten_gig_eth_pcs_pma_inst_qsfp1 ( - //// Channel 0 - .gt_rxp_in_0(qsfp1_rx1_p), - .gt_rxn_in_0(qsfp1_rx1_n), - .gt_txp_out_0(qsfp1_tx1_p), - .gt_txn_out_0(qsfp1_tx1_n), +wire [7:0] gt_txclkout; +wire gt_txusrclk; - .tx_mii_clk_0(qsfp1_tx_clk_1_int), - .rx_core_clk_0(qsfp1_rx_clk_1_int), - .rx_clk_out_0(), - .gt_loopback_in_0(3'd0), +wire [7:0] gt_rxclkout; +wire [7:0] gt_rxusrclk; - //// RX_0 Signals - .rx_reset_0(1'b0), - .user_rx_reset_0(qsfp1_rx_rst_1_int), - .rxrecclkout_0(), +wire gt_reset_tx_done; +wire gt_reset_rx_done; - //// RX_0 User Interface Signals - .rx_mii_d_0(qsfp1_rxd_1_int), - .rx_mii_c_0(qsfp1_rxc_1_int), +wire [7:0] gt_txprgdivresetdone; +wire [7:0] gt_txpmaresetdone; +wire [7:0] gt_rxprgdivresetdone; +wire [7:0] gt_rxpmaresetdone; - //// RX_0 Control Signals - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), +wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); +wire gt_rx_reset = ~>_rxpmaresetdone; - //// RX_0 Stats Signals - .stat_rx_block_lock_0(qsfp1_rx_block_lock_1), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), +reg gt_userclk_tx_active = 1'b0; +reg [7:0] gt_userclk_rx_active = 1'b0; - //// TX_0 Signals - .tx_reset_0(1'b0), - .user_tx_reset_0(qsfp1_tx_rst_1_int), - - //// TX_0 User Interface Signals - .tx_mii_d_0(qsfp1_txd_1_int), - .tx_mii_c_0(qsfp1_txc_1_int), - - //// TX_0 Control Signals - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), - - //// TX_0 Stats Signals - .stat_tx_local_fault_0(), - - .gtwiz_reset_tx_datapath_0(1'b0), - .gtwiz_reset_rx_datapath_0(1'b0), - - .gtpowergood_out_0(), - - - //// Channel 1 - .gt_rxp_in_1(qsfp1_rx2_p), - .gt_rxn_in_1(qsfp1_rx2_n), - .gt_txp_out_1(qsfp1_tx2_p), - .gt_txn_out_1(qsfp1_tx2_n), - - .tx_mii_clk_1(qsfp1_tx_clk_2_int), - .rx_core_clk_1(qsfp1_rx_clk_2_int), - .rx_clk_out_1(), - .gt_loopback_in_1(3'd0), - - //// RX_1 Signals - .rx_reset_1(1'b0), - .user_rx_reset_1(qsfp1_rx_rst_2_int), - .rxrecclkout_1(), - - //// RX_1 User Interface Signals - .rx_mii_d_1(qsfp1_rxd_2_int), - .rx_mii_c_1(qsfp1_rxc_2_int), - - //// RX_1 Control Signals - .ctl_rx_test_pattern_1(1'b0), - .ctl_rx_test_pattern_enable_1(1'b0), - .ctl_rx_data_pattern_select_1(1'b0), - .ctl_rx_prbs31_test_pattern_enable_1(1'b0), - - //// RX_1 Stats Signals - .stat_rx_block_lock_1(qsfp1_rx_block_lock_2), - .stat_rx_framing_err_valid_1(), - .stat_rx_framing_err_1(), - .stat_rx_hi_ber_1(), - .stat_rx_valid_ctrl_code_1(), - .stat_rx_bad_code_1(), - .stat_rx_bad_code_valid_1(), - .stat_rx_error_valid_1(), - .stat_rx_error_1(), - .stat_rx_fifo_error_1(), - .stat_rx_local_fault_1(), - .stat_rx_status_1(), - - //// TX_1 Signals - .tx_reset_1(1'b0), - .user_tx_reset_1(qsfp1_tx_rst_2_int), - - //// TX_1 User Interface Signals - .tx_mii_d_1(qsfp1_txd_2_int), - .tx_mii_c_1(qsfp1_txc_2_int), - - //// TX_1 Control Signals - .ctl_tx_test_pattern_1(1'b0), - .ctl_tx_test_pattern_enable_1(1'b0), - .ctl_tx_test_pattern_select_1(1'b0), - .ctl_tx_data_pattern_select_1(1'b0), - .ctl_tx_test_pattern_seed_a_1(58'd0), - .ctl_tx_test_pattern_seed_b_1(58'd0), - .ctl_tx_prbs31_test_pattern_enable_1(1'b0), - - //// TX_1 Stats Signals - .stat_tx_local_fault_1(), - - .gtwiz_reset_tx_datapath_1(1'b0), - .gtwiz_reset_rx_datapath_1(1'b0), - - .gtpowergood_out_1(), - - - //// Channel 2 - .gt_rxp_in_2(qsfp1_rx3_p), - .gt_rxn_in_2(qsfp1_rx3_n), - .gt_txp_out_2(qsfp1_tx3_p), - .gt_txn_out_2(qsfp1_tx3_n), - - .tx_mii_clk_2(qsfp1_tx_clk_3_int), - .rx_core_clk_2(qsfp1_rx_clk_3_int), - .rx_clk_out_2(), - .gt_loopback_in_2(3'd0), - - //// RX_2 Signals - .rx_reset_2(1'b0), - .user_rx_reset_2(qsfp1_rx_rst_3_int), - .rxrecclkout_2(), - - //// RX_2 User Interface Signals - .rx_mii_d_2(qsfp1_rxd_3_int), - .rx_mii_c_2(qsfp1_rxc_3_int), - - //// RX_2 Control Signals - .ctl_rx_test_pattern_2(1'b0), - .ctl_rx_test_pattern_enable_2(1'b0), - .ctl_rx_data_pattern_select_2(1'b0), - .ctl_rx_prbs31_test_pattern_enable_2(1'b0), - - //// RX_2 Stats Signals - .stat_rx_block_lock_2(qsfp1_rx_block_lock_3), - .stat_rx_framing_err_valid_2(), - .stat_rx_framing_err_2(), - .stat_rx_hi_ber_2(), - .stat_rx_valid_ctrl_code_2(), - .stat_rx_bad_code_2(), - .stat_rx_bad_code_valid_2(), - .stat_rx_error_valid_2(), - .stat_rx_error_2(), - .stat_rx_fifo_error_2(), - .stat_rx_local_fault_2(), - .stat_rx_status_2(), - - //// TX_2 Signals - .tx_reset_2(1'b0), - .user_tx_reset_2(qsfp1_tx_rst_3_int), - - //// TX_2 User Interface Signals - .tx_mii_d_2(qsfp1_txd_3_int), - .tx_mii_c_2(qsfp1_txc_3_int), - - //// TX_2 Control Signals - .ctl_tx_test_pattern_2(1'b0), - .ctl_tx_test_pattern_enable_2(1'b0), - .ctl_tx_test_pattern_select_2(1'b0), - .ctl_tx_data_pattern_select_2(1'b0), - .ctl_tx_test_pattern_seed_a_2(58'd0), - .ctl_tx_test_pattern_seed_b_2(58'd0), - .ctl_tx_prbs31_test_pattern_enable_2(1'b0), - - //// TX_2 Stats Signals - .stat_tx_local_fault_2(), - - .gtwiz_reset_tx_datapath_2(1'b0), - .gtwiz_reset_rx_datapath_2(1'b0), - - .gtpowergood_out_2(), - - - //// Channel 3 - .gt_rxp_in_3(qsfp1_rx4_p), - .gt_rxn_in_3(qsfp1_rx4_n), - .gt_txp_out_3(qsfp1_tx4_p), - .gt_txn_out_3(qsfp1_tx4_n), - - .tx_mii_clk_3(qsfp1_tx_clk_4_int), - .rx_core_clk_3(qsfp1_rx_clk_4_int), - .rx_clk_out_3(), - .gt_loopback_in_3(3'd0), - - //// RX_3 Signals - .rx_reset_3(1'b0), - .user_rx_reset_3(qsfp1_rx_rst_4_int), - .rxrecclkout_3(), - - //// RX_3 User Interface Signals - .rx_mii_d_3(qsfp1_rxd_4_int), - .rx_mii_c_3(qsfp1_rxc_4_int), - - //// RX_3 Control Signals - .ctl_rx_test_pattern_3(1'b0), - .ctl_rx_test_pattern_enable_3(1'b0), - .ctl_rx_data_pattern_select_3(1'b0), - .ctl_rx_prbs31_test_pattern_enable_3(1'b0), - - //// RX_3 Stats Signals - .stat_rx_block_lock_3(qsfp1_rx_block_lock_4), - .stat_rx_framing_err_valid_3(), - .stat_rx_framing_err_3(), - .stat_rx_hi_ber_3(), - .stat_rx_valid_ctrl_code_3(), - .stat_rx_bad_code_3(), - .stat_rx_bad_code_valid_3(), - .stat_rx_error_valid_3(), - .stat_rx_error_3(), - .stat_rx_fifo_error_3(), - .stat_rx_local_fault_3(), - .stat_rx_status_3(), - - //// TX_3 Signals - .tx_reset_3(1'b0), - .user_tx_reset_3(qsfp1_tx_rst_4_int), - - //// TX_3 User Interface Signals - .tx_mii_d_3(qsfp1_txd_4_int), - .tx_mii_c_3(qsfp1_txc_4_int), - - //// TX_3 Control Signals - .ctl_tx_test_pattern_3(1'b0), - .ctl_tx_test_pattern_enable_3(1'b0), - .ctl_tx_test_pattern_select_3(1'b0), - .ctl_tx_data_pattern_select_3(1'b0), - .ctl_tx_test_pattern_seed_a_3(58'd0), - .ctl_tx_test_pattern_seed_b_3(58'd0), - .ctl_tx_prbs31_test_pattern_enable_3(1'b0), - - //// TX_3 Stats Signals - .stat_tx_local_fault_3(), - - .gtwiz_reset_tx_datapath_3(1'b0), - .gtwiz_reset_rx_datapath_3(1'b0), - - .gtpowergood_out_3(), - - .gt_refclk_p(qsfp1_mgt_refclk_0_p), - .gt_refclk_n(qsfp1_mgt_refclk_0_n), - - .gt_refclk_out(), - - .sys_reset(rst_125mhz_int), - .dclk(clk_125mhz_int) +IBUFDS_GTE4 ibufds_gte4_qsfp1_mgt_refclk_0_inst ( + .I (qsfp1_mgt_refclk_0_p), + .IB (qsfp1_mgt_refclk_0_n), + .CEB (1'b0), + .O (qsfp1_mgt_refclk_0), + .ODIV2 () ); -ten_gig_eth_pcs_pma_0 -ten_gig_eth_pcs_pma_inst_qsfp2 ( - //// Channel 0 - .gt_rxp_in_0(qsfp2_rx1_p), - .gt_rxn_in_0(qsfp2_rx1_n), - .gt_txp_out_0(qsfp2_tx1_p), - .gt_txn_out_0(qsfp2_tx1_n), - .tx_mii_clk_0(qsfp2_tx_clk_1_int), - .rx_core_clk_0(qsfp2_rx_clk_1_int), - .rx_clk_out_0(), - .gt_loopback_in_0(3'd0), +BUFG_GT bufg_gt_tx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txclkout[0]), + .O (gt_txusrclk) +); - //// RX_0 Signals - .rx_reset_0(1'b0), - .user_rx_reset_0(qsfp2_rx_rst_1_int), - .rxrecclkout_0(), +assign clk_156mhz_int = gt_txusrclk; - //// RX_0 User Interface Signals - .rx_mii_d_0(qsfp2_rxd_1_int), - .rx_mii_c_0(qsfp2_rxc_1_int), +always @(posedge gt_txusrclk, posedge gt_tx_reset) begin + if (gt_tx_reset) begin + gt_userclk_tx_active <= 1'b0; + end else begin + gt_userclk_tx_active <= 1'b1; + end +end - //// RX_0 Control Signals - .ctl_rx_test_pattern_0(1'b0), - .ctl_rx_test_pattern_enable_0(1'b0), - .ctl_rx_data_pattern_select_0(1'b0), - .ctl_rx_prbs31_test_pattern_enable_0(1'b0), +genvar n; - //// RX_0 Stats Signals - .stat_rx_block_lock_0(qsfp2_rx_block_lock_1), - .stat_rx_framing_err_valid_0(), - .stat_rx_framing_err_0(), - .stat_rx_hi_ber_0(), - .stat_rx_valid_ctrl_code_0(), - .stat_rx_bad_code_0(), - .stat_rx_bad_code_valid_0(), - .stat_rx_error_valid_0(), - .stat_rx_error_0(), - .stat_rx_fifo_error_0(), - .stat_rx_local_fault_0(), - .stat_rx_status_0(), +generate - //// TX_0 Signals - .tx_reset_0(1'b0), - .user_tx_reset_0(qsfp2_tx_rst_1_int), +for (n = 0; n < 8; n = n + 1) begin - //// TX_0 User Interface Signals - .tx_mii_d_0(qsfp2_txd_1_int), - .tx_mii_c_0(qsfp2_txc_1_int), + BUFG_GT bufg_gt_rx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk[n]) + ); - //// TX_0 Control Signals - .ctl_tx_test_pattern_0(1'b0), - .ctl_tx_test_pattern_enable_0(1'b0), - .ctl_tx_test_pattern_select_0(1'b0), - .ctl_tx_data_pattern_select_0(1'b0), - .ctl_tx_test_pattern_seed_a_0(58'd0), - .ctl_tx_test_pattern_seed_b_0(58'd0), - .ctl_tx_prbs31_test_pattern_enable_0(1'b0), + always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin + if (gt_rx_reset) begin + gt_userclk_rx_active[n] <= 1'b0; + end else begin + gt_userclk_rx_active[n] <= 1'b1; + end + end - //// TX_0 Stats Signals - .stat_tx_local_fault_0(), +end - .gtwiz_reset_tx_datapath_0(1'b0), - .gtwiz_reset_rx_datapath_0(1'b0), +endgenerate - .gtpowergood_out_0(), +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz_int), + .rst(~gt_reset_tx_done), + .sync_reset_out(rst_156mhz_int) +); +wire [5:0] qsfp1_gt_txheader_1; +wire [127:0] qsfp1_gt_txdata_1; +wire qsfp1_gt_rxgearboxslip_1; +wire [5:0] qsfp1_gt_rxheader_1; +wire [1:0] qsfp1_gt_rxheadervalid_1; +wire [127:0] qsfp1_gt_rxdata_1; +wire [1:0] qsfp1_gt_rxdatavalid_1; - //// Channel 1 - .gt_rxp_in_1(qsfp2_rx2_p), - .gt_rxn_in_1(qsfp2_rx2_n), - .gt_txp_out_1(qsfp2_tx2_p), - .gt_txn_out_1(qsfp2_tx2_n), +wire [5:0] qsfp1_gt_txheader_2; +wire [127:0] qsfp1_gt_txdata_2; +wire qsfp1_gt_rxgearboxslip_2; +wire [5:0] qsfp1_gt_rxheader_2; +wire [1:0] qsfp1_gt_rxheadervalid_2; +wire [127:0] qsfp1_gt_rxdata_2; +wire [1:0] qsfp1_gt_rxdatavalid_2; - .tx_mii_clk_1(qsfp2_tx_clk_2_int), - .rx_core_clk_1(qsfp2_rx_clk_2_int), - .rx_clk_out_1(), - .gt_loopback_in_1(3'd0), +wire [5:0] qsfp1_gt_txheader_3; +wire [127:0] qsfp1_gt_txdata_3; +wire qsfp1_gt_rxgearboxslip_3; +wire [5:0] qsfp1_gt_rxheader_3; +wire [1:0] qsfp1_gt_rxheadervalid_3; +wire [127:0] qsfp1_gt_rxdata_3; +wire [1:0] qsfp1_gt_rxdatavalid_3; - //// RX_1 Signals - .rx_reset_1(1'b0), - .user_rx_reset_1(qsfp2_rx_rst_2_int), - .rxrecclkout_1(), +wire [5:0] qsfp1_gt_txheader_4; +wire [127:0] qsfp1_gt_txdata_4; +wire qsfp1_gt_rxgearboxslip_4; +wire [5:0] qsfp1_gt_rxheader_4; +wire [1:0] qsfp1_gt_rxheadervalid_4; +wire [127:0] qsfp1_gt_rxdata_4; +wire [1:0] qsfp1_gt_rxdatavalid_4; - //// RX_1 User Interface Signals - .rx_mii_d_1(qsfp2_rxd_2_int), - .rx_mii_c_1(qsfp2_rxc_2_int), +wire [5:0] qsfp2_gt_txheader_1; +wire [127:0] qsfp2_gt_txdata_1; +wire qsfp2_gt_rxgearboxslip_1; +wire [5:0] qsfp2_gt_rxheader_1; +wire [1:0] qsfp2_gt_rxheadervalid_1; +wire [127:0] qsfp2_gt_rxdata_1; +wire [1:0] qsfp2_gt_rxdatavalid_1; - //// RX_1 Control Signals - .ctl_rx_test_pattern_1(1'b0), - .ctl_rx_test_pattern_enable_1(1'b0), - .ctl_rx_data_pattern_select_1(1'b0), - .ctl_rx_prbs31_test_pattern_enable_1(1'b0), +wire [5:0] qsfp2_gt_txheader_2; +wire [127:0] qsfp2_gt_txdata_2; +wire qsfp2_gt_rxgearboxslip_2; +wire [5:0] qsfp2_gt_rxheader_2; +wire [1:0] qsfp2_gt_rxheadervalid_2; +wire [127:0] qsfp2_gt_rxdata_2; +wire [1:0] qsfp2_gt_rxdatavalid_2; - //// RX_1 Stats Signals - .stat_rx_block_lock_1(qsfp2_rx_block_lock_2), - .stat_rx_framing_err_valid_1(), - .stat_rx_framing_err_1(), - .stat_rx_hi_ber_1(), - .stat_rx_valid_ctrl_code_1(), - .stat_rx_bad_code_1(), - .stat_rx_bad_code_valid_1(), - .stat_rx_error_valid_1(), - .stat_rx_error_1(), - .stat_rx_fifo_error_1(), - .stat_rx_local_fault_1(), - .stat_rx_status_1(), +wire [5:0] qsfp2_gt_txheader_3; +wire [127:0] qsfp2_gt_txdata_3; +wire qsfp2_gt_rxgearboxslip_3; +wire [5:0] qsfp2_gt_rxheader_3; +wire [1:0] qsfp2_gt_rxheadervalid_3; +wire [127:0] qsfp2_gt_rxdata_3; +wire [1:0] qsfp2_gt_rxdatavalid_3; - //// TX_1 Signals - .tx_reset_1(1'b0), - .user_tx_reset_1(qsfp2_tx_rst_2_int), +wire [5:0] qsfp2_gt_txheader_4; +wire [127:0] qsfp2_gt_txdata_4; +wire qsfp2_gt_rxgearboxslip_4; +wire [5:0] qsfp2_gt_rxheader_4; +wire [1:0] qsfp2_gt_rxheadervalid_4; +wire [127:0] qsfp2_gt_rxdata_4; +wire [1:0] qsfp2_gt_rxdatavalid_4; - //// TX_1 User Interface Signals - .tx_mii_d_1(qsfp2_txd_2_int), - .tx_mii_c_1(qsfp2_txc_2_int), +gtwizard_ultrascale_0 +qsfp_gty_inst ( + .gtwiz_userclk_tx_active_in(>_userclk_tx_active), + .gtwiz_userclk_rx_active_in(>_userclk_rx_active), - //// TX_1 Control Signals - .ctl_tx_test_pattern_1(1'b0), - .ctl_tx_test_pattern_enable_1(1'b0), - .ctl_tx_test_pattern_select_1(1'b0), - .ctl_tx_data_pattern_select_1(1'b0), - .ctl_tx_test_pattern_seed_a_1(58'd0), - .ctl_tx_test_pattern_seed_b_1(58'd0), - .ctl_tx_prbs31_test_pattern_enable_1(1'b0), + .gtwiz_reset_clk_freerun_in(clk_125mhz_int), + .gtwiz_reset_all_in(rst_125mhz_int), - //// TX_1 Stats Signals - .stat_tx_local_fault_1(), + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(1'b0), - .gtwiz_reset_tx_datapath_1(1'b0), - .gtwiz_reset_rx_datapath_1(1'b0), + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(1'b0), - .gtpowergood_out_1(), + .gtwiz_reset_rx_cdr_stable_out(), + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), - //// Channel 2 - .gt_rxp_in_2(qsfp2_rx3_p), - .gt_rxn_in_2(qsfp2_rx3_n), - .gt_txp_out_2(qsfp2_tx3_p), - .gt_txn_out_2(qsfp2_tx3_n), + .gtrefclk00_in({2{qsfp1_mgt_refclk_0}}), - .tx_mii_clk_2(qsfp2_tx_clk_3_int), - .rx_core_clk_2(qsfp2_rx_clk_3_int), - .rx_clk_out_2(), - .gt_loopback_in_2(3'd0), + .qpll0outclk_out(), + .qpll0outrefclk_out(), - //// RX_2 Signals - .rx_reset_2(1'b0), - .user_rx_reset_2(qsfp2_rx_rst_3_int), - .rxrecclkout_2(), + .gtyrxn_in({qsfp2_rx4_n, qsfp2_rx3_n, qsfp2_rx2_n, qsfp2_rx1_n, qsfp1_rx4_n, qsfp1_rx3_n, qsfp1_rx2_n, qsfp1_rx1_n}), + .gtyrxp_in({qsfp2_rx4_p, qsfp2_rx3_p, qsfp2_rx2_p, qsfp2_rx1_p, qsfp1_rx4_p, qsfp1_rx3_p, qsfp1_rx2_p, qsfp1_rx1_p}), - //// RX_2 User Interface Signals - .rx_mii_d_2(qsfp2_rxd_3_int), - .rx_mii_c_2(qsfp2_rxc_3_int), + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk), - //// RX_2 Control Signals - .ctl_rx_test_pattern_2(1'b0), - .ctl_rx_test_pattern_enable_2(1'b0), - .ctl_rx_data_pattern_select_2(1'b0), - .ctl_rx_prbs31_test_pattern_enable_2(1'b0), + .txdata_in({qsfp2_gt_txdata_4, qsfp2_gt_txdata_3, qsfp2_gt_txdata_2, qsfp2_gt_txdata_1, qsfp1_gt_txdata_4, qsfp1_gt_txdata_3, qsfp1_gt_txdata_2, qsfp1_gt_txdata_1}), + .txheader_in({qsfp2_gt_txheader_4, qsfp2_gt_txheader_3, qsfp2_gt_txheader_2, qsfp2_gt_txheader_1, qsfp1_gt_txheader_4, qsfp1_gt_txheader_3, qsfp1_gt_txheader_2, qsfp1_gt_txheader_1}), + .txsequence_in({8{1'b0}}), - //// RX_2 Stats Signals - .stat_rx_block_lock_2(qsfp2_rx_block_lock_3), - .stat_rx_framing_err_valid_2(), - .stat_rx_framing_err_2(), - .stat_rx_hi_ber_2(), - .stat_rx_valid_ctrl_code_2(), - .stat_rx_bad_code_2(), - .stat_rx_bad_code_valid_2(), - .stat_rx_error_valid_2(), - .stat_rx_error_2(), - .stat_rx_fifo_error_2(), - .stat_rx_local_fault_2(), - .stat_rx_status_2(), + .txusrclk_in({8{gt_txusrclk}}), + .txusrclk2_in({8{gt_txusrclk}}), - //// TX_2 Signals - .tx_reset_2(1'b0), - .user_tx_reset_2(qsfp2_tx_rst_3_int), + .gtpowergood_out(), - //// TX_2 User Interface Signals - .tx_mii_d_2(qsfp2_txd_3_int), - .tx_mii_c_2(qsfp2_txc_3_int), + .gtytxn_out({qsfp2_tx4_n, qsfp2_tx3_n, qsfp2_tx2_n, qsfp2_tx1_n, qsfp1_tx4_n, qsfp1_tx3_n, qsfp1_tx2_n, qsfp1_tx1_n}), + .gtytxp_out({qsfp2_tx4_p, qsfp2_tx3_p, qsfp2_tx2_p, qsfp2_tx1_p, qsfp1_tx4_p, qsfp1_tx3_p, qsfp1_tx2_p, qsfp1_tx1_p}), - //// TX_2 Control Signals - .ctl_tx_test_pattern_2(1'b0), - .ctl_tx_test_pattern_enable_2(1'b0), - .ctl_tx_test_pattern_select_2(1'b0), - .ctl_tx_data_pattern_select_2(1'b0), - .ctl_tx_test_pattern_seed_a_2(58'd0), - .ctl_tx_test_pattern_seed_b_2(58'd0), - .ctl_tx_prbs31_test_pattern_enable_2(1'b0), + .rxgearboxslip_in({qsfp2_gt_rxgearboxslip_4, qsfp2_gt_rxgearboxslip_3, qsfp2_gt_rxgearboxslip_2, qsfp2_gt_rxgearboxslip_1, qsfp1_gt_rxgearboxslip_4, qsfp1_gt_rxgearboxslip_3, qsfp1_gt_rxgearboxslip_2, qsfp1_gt_rxgearboxslip_1}), + .rxdata_out({qsfp2_gt_rxdata_4, qsfp2_gt_rxdata_3, qsfp2_gt_rxdata_2, qsfp2_gt_rxdata_1, qsfp1_gt_rxdata_4, qsfp1_gt_rxdata_3, qsfp1_gt_rxdata_2, qsfp1_gt_rxdata_1}), + .rxdatavalid_out({qsfp2_gt_rxdatavalid_4, qsfp2_gt_rxdatavalid_3, qsfp2_gt_rxdatavalid_2, qsfp2_gt_rxdatavalid_1, qsfp1_gt_rxdatavalid_4, qsfp1_gt_rxdatavalid_3, qsfp1_gt_rxdatavalid_2, qsfp1_gt_rxdatavalid_1}), + .rxheader_out({qsfp2_gt_rxheader_4, qsfp2_gt_rxheader_3, qsfp2_gt_rxheader_2, qsfp2_gt_rxheader_1, qsfp1_gt_rxheader_4, qsfp1_gt_rxheader_3, qsfp1_gt_rxheader_2, qsfp1_gt_rxheader_1}), + .rxheadervalid_out({qsfp2_gt_rxheadervalid_4, qsfp2_gt_rxheadervalid_3, qsfp2_gt_rxheadervalid_2, qsfp2_gt_rxheadervalid_1, qsfp1_gt_rxheadervalid_4, qsfp1_gt_rxheadervalid_3, qsfp1_gt_rxheadervalid_2, qsfp1_gt_rxheadervalid_1}), + .rxoutclk_out(gt_rxclkout), + .rxpmaresetdone_out(gt_rxpmaresetdone), + .rxprgdivresetdone_out(gt_rxprgdivresetdone), + .rxstartofseq_out(), - //// TX_2 Stats Signals - .stat_tx_local_fault_2(), + .txoutclk_out(gt_txclkout), + .txpmaresetdone_out(gt_txpmaresetdone), + .txprgdivresetdone_out(gt_txprgdivresetdone) +); - .gtwiz_reset_tx_datapath_2(1'b0), - .gtwiz_reset_rx_datapath_2(1'b0), +assign qsfp1_tx_clk_1_int = clk_156mhz_int; +assign qsfp1_tx_rst_1_int = rst_156mhz_int; - .gtpowergood_out_2(), +assign qsfp1_rx_clk_1_int = gt_rxusrclk[0]; +sync_reset #( + .N(4) +) +qsfp1_rx_rst_1_reset_sync_inst ( + .clk(qsfp1_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp1_rx_rst_1_int) +); - //// Channel 3 - .gt_rxp_in_3(qsfp2_rx4_p), - .gt_rxn_in_3(qsfp2_rx4_n), - .gt_txp_out_3(qsfp2_tx4_p), - .gt_txn_out_3(qsfp2_tx4_n), +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_1_inst ( + .tx_clk(qsfp1_tx_clk_1_int), + .tx_rst(qsfp1_tx_rst_1_int), + .rx_clk(qsfp1_rx_clk_1_int), + .rx_rst(qsfp1_rx_rst_1_int), + .xgmii_txd(qsfp1_txd_1_int), + .xgmii_txc(qsfp1_txc_1_int), + .xgmii_rxd(qsfp1_rxd_1_int), + .xgmii_rxc(qsfp1_rxc_1_int), + .serdes_tx_data(qsfp1_gt_txdata_1), + .serdes_tx_hdr(qsfp1_gt_txheader_1), + .serdes_rx_data(qsfp1_gt_rxdata_1), + .serdes_rx_hdr(qsfp1_gt_rxheader_1), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_1), + .rx_block_lock(qsfp1_rx_block_lock_1), + .rx_high_ber() +); - .tx_mii_clk_3(qsfp2_tx_clk_4_int), - .rx_core_clk_3(qsfp2_rx_clk_4_int), - .rx_clk_out_3(), - .gt_loopback_in_3(3'd0), +assign qsfp1_tx_clk_2_int = clk_156mhz_int; +assign qsfp1_tx_rst_2_int = rst_156mhz_int; - //// RX_3 Signals - .rx_reset_3(1'b0), - .user_rx_reset_3(qsfp2_rx_rst_4_int), - .rxrecclkout_3(), +assign qsfp1_rx_clk_2_int = gt_rxusrclk[1]; - //// RX_3 User Interface Signals - .rx_mii_d_3(qsfp2_rxd_4_int), - .rx_mii_c_3(qsfp2_rxc_4_int), +sync_reset #( + .N(4) +) +qsfp1_rx_rst_2_reset_sync_inst ( + .clk(qsfp1_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp1_rx_rst_2_int) +); - //// RX_3 Control Signals - .ctl_rx_test_pattern_3(1'b0), - .ctl_rx_test_pattern_enable_3(1'b0), - .ctl_rx_data_pattern_select_3(1'b0), - .ctl_rx_prbs31_test_pattern_enable_3(1'b0), +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_2_inst ( + .tx_clk(qsfp1_tx_clk_2_int), + .tx_rst(qsfp1_tx_rst_2_int), + .rx_clk(qsfp1_rx_clk_2_int), + .rx_rst(qsfp1_rx_rst_2_int), + .xgmii_txd(qsfp1_txd_2_int), + .xgmii_txc(qsfp1_txc_2_int), + .xgmii_rxd(qsfp1_rxd_2_int), + .xgmii_rxc(qsfp1_rxc_2_int), + .serdes_tx_data(qsfp1_gt_txdata_2), + .serdes_tx_hdr(qsfp1_gt_txheader_2), + .serdes_rx_data(qsfp1_gt_rxdata_2), + .serdes_rx_hdr(qsfp1_gt_rxheader_2), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_2), + .rx_block_lock(qsfp1_rx_block_lock_2), + .rx_high_ber() +); - //// RX_3 Stats Signals - .stat_rx_block_lock_3(qsfp2_rx_block_lock_4), - .stat_rx_framing_err_valid_3(), - .stat_rx_framing_err_3(), - .stat_rx_hi_ber_3(), - .stat_rx_valid_ctrl_code_3(), - .stat_rx_bad_code_3(), - .stat_rx_bad_code_valid_3(), - .stat_rx_error_valid_3(), - .stat_rx_error_3(), - .stat_rx_fifo_error_3(), - .stat_rx_local_fault_3(), - .stat_rx_status_3(), +assign qsfp1_tx_clk_3_int = clk_156mhz_int; +assign qsfp1_tx_rst_3_int = rst_156mhz_int; - //// TX_3 Signals - .tx_reset_3(1'b0), - .user_tx_reset_3(qsfp2_tx_rst_4_int), +assign qsfp1_rx_clk_3_int = gt_rxusrclk[2]; - //// TX_3 User Interface Signals - .tx_mii_d_3(qsfp2_txd_4_int), - .tx_mii_c_3(qsfp2_txc_4_int), +sync_reset #( + .N(4) +) +qsfp1_rx_rst_3_reset_sync_inst ( + .clk(qsfp1_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp1_rx_rst_3_int) +); - //// TX_3 Control Signals - .ctl_tx_test_pattern_3(1'b0), - .ctl_tx_test_pattern_enable_3(1'b0), - .ctl_tx_test_pattern_select_3(1'b0), - .ctl_tx_data_pattern_select_3(1'b0), - .ctl_tx_test_pattern_seed_a_3(58'd0), - .ctl_tx_test_pattern_seed_b_3(58'd0), - .ctl_tx_prbs31_test_pattern_enable_3(1'b0), +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_3_inst ( + .tx_clk(qsfp1_tx_clk_3_int), + .tx_rst(qsfp1_tx_rst_3_int), + .rx_clk(qsfp1_rx_clk_3_int), + .rx_rst(qsfp1_rx_rst_3_int), + .xgmii_txd(qsfp1_txd_3_int), + .xgmii_txc(qsfp1_txc_3_int), + .xgmii_rxd(qsfp1_rxd_3_int), + .xgmii_rxc(qsfp1_rxc_3_int), + .serdes_tx_data(qsfp1_gt_txdata_3), + .serdes_tx_hdr(qsfp1_gt_txheader_3), + .serdes_rx_data(qsfp1_gt_rxdata_3), + .serdes_rx_hdr(qsfp1_gt_rxheader_3), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_3), + .rx_block_lock(qsfp1_rx_block_lock_3), + .rx_high_ber() +); - //// TX_3 Stats Signals - .stat_tx_local_fault_3(), +assign qsfp1_tx_clk_4_int = clk_156mhz_int; +assign qsfp1_tx_rst_4_int = rst_156mhz_int; - .gtwiz_reset_tx_datapath_3(1'b0), - .gtwiz_reset_rx_datapath_3(1'b0), +assign qsfp1_rx_clk_4_int = gt_rxusrclk[3]; - .gtpowergood_out_3(), +sync_reset #( + .N(4) +) +qsfp1_rx_rst_4_reset_sync_inst ( + .clk(qsfp1_rx_clk_4_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp1_rx_rst_4_int) +); - .gt_refclk_p(qsfp2_mgt_refclk_0_p), - .gt_refclk_n(qsfp2_mgt_refclk_0_n), +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_4_inst ( + .tx_clk(qsfp1_tx_clk_4_int), + .tx_rst(qsfp1_tx_rst_4_int), + .rx_clk(qsfp1_rx_clk_4_int), + .rx_rst(qsfp1_rx_rst_4_int), + .xgmii_txd(qsfp1_txd_4_int), + .xgmii_txc(qsfp1_txc_4_int), + .xgmii_rxd(qsfp1_rxd_4_int), + .xgmii_rxc(qsfp1_rxc_4_int), + .serdes_tx_data(qsfp1_gt_txdata_4), + .serdes_tx_hdr(qsfp1_gt_txheader_4), + .serdes_rx_data(qsfp1_gt_rxdata_4), + .serdes_rx_hdr(qsfp1_gt_rxheader_4), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_4), + .rx_block_lock(qsfp1_rx_block_lock_4), + .rx_high_ber() +); - .gt_refclk_out(), +assign qsfp2_tx_clk_1_int = clk_156mhz_int; +assign qsfp2_tx_rst_1_int = rst_156mhz_int; - .sys_reset(rst_125mhz_int), - .dclk(clk_125mhz_int) +assign qsfp2_rx_clk_1_int = gt_rxusrclk[4]; + +sync_reset #( + .N(4) +) +qsfp2_rx_rst_1_reset_sync_inst ( + .clk(qsfp2_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp2_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp2_phy_1_inst ( + .tx_clk(qsfp2_tx_clk_1_int), + .tx_rst(qsfp2_tx_rst_1_int), + .rx_clk(qsfp2_rx_clk_1_int), + .rx_rst(qsfp2_rx_rst_1_int), + .xgmii_txd(qsfp2_txd_1_int), + .xgmii_txc(qsfp2_txc_1_int), + .xgmii_rxd(qsfp2_rxd_1_int), + .xgmii_rxc(qsfp2_rxc_1_int), + .serdes_tx_data(qsfp2_gt_txdata_1), + .serdes_tx_hdr(qsfp2_gt_txheader_1), + .serdes_rx_data(qsfp2_gt_rxdata_1), + .serdes_rx_hdr(qsfp2_gt_rxheader_1), + .serdes_rx_bitslip(qsfp2_gt_rxgearboxslip_1), + .rx_block_lock(qsfp2_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp2_tx_clk_2_int = clk_156mhz_int; +assign qsfp2_tx_rst_2_int = rst_156mhz_int; + +assign qsfp2_rx_clk_2_int = gt_rxusrclk[5]; + +sync_reset #( + .N(4) +) +qsfp2_rx_rst_2_reset_sync_inst ( + .clk(qsfp2_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp2_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp2_phy_2_inst ( + .tx_clk(qsfp2_tx_clk_2_int), + .tx_rst(qsfp2_tx_rst_2_int), + .rx_clk(qsfp2_rx_clk_2_int), + .rx_rst(qsfp2_rx_rst_2_int), + .xgmii_txd(qsfp2_txd_2_int), + .xgmii_txc(qsfp2_txc_2_int), + .xgmii_rxd(qsfp2_rxd_2_int), + .xgmii_rxc(qsfp2_rxc_2_int), + .serdes_tx_data(qsfp2_gt_txdata_2), + .serdes_tx_hdr(qsfp2_gt_txheader_2), + .serdes_rx_data(qsfp2_gt_rxdata_2), + .serdes_rx_hdr(qsfp2_gt_rxheader_2), + .serdes_rx_bitslip(qsfp2_gt_rxgearboxslip_2), + .rx_block_lock(qsfp2_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp2_tx_clk_3_int = clk_156mhz_int; +assign qsfp2_tx_rst_3_int = rst_156mhz_int; + +assign qsfp2_rx_clk_3_int = gt_rxusrclk[6]; + +sync_reset #( + .N(4) +) +qsfp2_rx_rst_3_reset_sync_inst ( + .clk(qsfp2_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp2_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp2_phy_3_inst ( + .tx_clk(qsfp2_tx_clk_3_int), + .tx_rst(qsfp2_tx_rst_3_int), + .rx_clk(qsfp2_rx_clk_3_int), + .rx_rst(qsfp2_rx_rst_3_int), + .xgmii_txd(qsfp2_txd_3_int), + .xgmii_txc(qsfp2_txc_3_int), + .xgmii_rxd(qsfp2_rxd_3_int), + .xgmii_rxc(qsfp2_rxc_3_int), + .serdes_tx_data(qsfp2_gt_txdata_3), + .serdes_tx_hdr(qsfp2_gt_txheader_3), + .serdes_rx_data(qsfp2_gt_rxdata_3), + .serdes_rx_hdr(qsfp2_gt_rxheader_3), + .serdes_rx_bitslip(qsfp2_gt_rxgearboxslip_3), + .rx_block_lock(qsfp2_rx_block_lock_3), + .rx_high_ber() +); + +assign qsfp2_tx_clk_4_int = clk_156mhz_int; +assign qsfp2_tx_rst_4_int = rst_156mhz_int; + +assign qsfp2_rx_clk_4_int = gt_rxusrclk[7]; + +sync_reset #( + .N(4) +) +qsfp2_rx_rst_4_reset_sync_inst ( + .clk(qsfp2_rx_clk_4_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp2_rx_rst_4_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp2_phy_4_inst ( + .tx_clk(qsfp2_tx_clk_4_int), + .tx_rst(qsfp2_tx_rst_4_int), + .rx_clk(qsfp2_rx_clk_4_int), + .rx_rst(qsfp2_rx_rst_4_int), + .xgmii_txd(qsfp2_txd_4_int), + .xgmii_txc(qsfp2_txc_4_int), + .xgmii_rxd(qsfp2_rxd_4_int), + .xgmii_rxc(qsfp2_rxc_4_int), + .serdes_tx_data(qsfp2_gt_txdata_4), + .serdes_tx_hdr(qsfp2_gt_txheader_4), + .serdes_rx_data(qsfp2_gt_rxdata_4), + .serdes_rx_hdr(qsfp2_gt_rxheader_4), + .serdes_rx_bitslip(qsfp2_gt_rxgearboxslip_4), + .rx_block_lock(qsfp2_rx_block_lock_4), + .rx_high_ber() ); // SGMII interface to PHY From cd6b87e984ff7cbeaf11f9468124019f5e654bdb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 6 Feb 2019 21:25:30 -0800 Subject: [PATCH 524/617] Enable bitstream compression in example designs --- example/NexysVideo/fpga/fpga.xdc | 1 + example/VCU108/fpga_10g/fpga.xdc | 1 + example/VCU108/fpga_1g/fpga.xdc | 1 + example/VCU118/fpga_1g/fpga.xdc | 1 + 4 files changed, 4 insertions(+) diff --git a/example/NexysVideo/fpga/fpga.xdc b/example/NexysVideo/fpga/fpga.xdc index c6da45b8e..f66c951df 100644 --- a/example/NexysVideo/fpga/fpga.xdc +++ b/example/NexysVideo/fpga/fpga.xdc @@ -4,6 +4,7 @@ # General configuration set_property CFGBVS VCCO [current_design] set_property CONFIG_VOLTAGE 3.3 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] # 100 MHz clock set_property -dict {LOC R4 IOSTANDARD LVCMOS33} [get_ports clk] diff --git a/example/VCU108/fpga_10g/fpga.xdc b/example/VCU108/fpga_10g/fpga.xdc index a289f96fe..3412bfd56 100644 --- a/example/VCU108/fpga_10g/fpga.xdc +++ b/example/VCU108/fpga_10g/fpga.xdc @@ -4,6 +4,7 @@ # General configuration set_property CFGBVS GND [current_design] set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] # System clocks # 300 MHz diff --git a/example/VCU108/fpga_1g/fpga.xdc b/example/VCU108/fpga_1g/fpga.xdc index 48a01e1c3..c9ec17ff2 100644 --- a/example/VCU108/fpga_1g/fpga.xdc +++ b/example/VCU108/fpga_1g/fpga.xdc @@ -4,6 +4,7 @@ # General configuration set_property CFGBVS GND [current_design] set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] # System clocks # 300 MHz diff --git a/example/VCU118/fpga_1g/fpga.xdc b/example/VCU118/fpga_1g/fpga.xdc index d9297bb15..46e9e7d25 100644 --- a/example/VCU118/fpga_1g/fpga.xdc +++ b/example/VCU118/fpga_1g/fpga.xdc @@ -4,6 +4,7 @@ # General configuration set_property CFGBVS GND [current_design] set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] # System clocks # 300 MHz From b60886a0eca31198f9a79874f73e21963c51656e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 27 Feb 2019 19:46:30 -0800 Subject: [PATCH 525/617] Add AXI stream broadcast module and testbench --- README.md | 6 + rtl/axis_broadcast.v | 180 ++++++++++++ tb/test_axis_broadcast_4.py | 548 ++++++++++++++++++++++++++++++++++++ tb/test_axis_broadcast_4.v | 140 +++++++++ 4 files changed, 874 insertions(+) create mode 100644 rtl/axis_broadcast.v create mode 100755 tb/test_axis_broadcast_4.py create mode 100644 tb/test_axis_broadcast_4.v diff --git a/README.md b/README.md index a4de85a25..6ac5e504f 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,11 @@ Configurable word-based or frame-based asynchronous FIFO with parametrizable data width, depth, type, and bad frame detection. Supports power of two depths only. +### axis_broadcast module + +AXI stream broadcaster. Duplicates one input stream across multiple output +streams. + ### axis_cobs_decode Consistent Overhead Byte Stuffing (COBS) decoder. Fixed 8 bit width. @@ -186,6 +191,7 @@ Parametrizable priority encoder. axis_adapter.v : Parametrizable bus width adapter axis_arb_mux.v : Parametrizable arbitrated multiplexer axis_async_fifo.v : Parametrizable asynchronous FIFO + axis_broadcast.v : AXI stream broadcaster axis_cobs_decode.v : COBS decoder axis_cobs_encode.v : COBS encoder axis_crosspoint.v : Parametrizable crosspoint switch diff --git a/rtl/axis_broadcast.v b/rtl/axis_broadcast.v new file mode 100644 index 000000000..c285ff3e3 --- /dev/null +++ b/rtl/axis_broadcast.v @@ -0,0 +1,180 @@ +/* + +Copyright (c) 2019 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 broadcaster + */ +module axis_broadcast # +( + parameter M_COUNT = 4, + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LAST_ENABLE = 1, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1 +) +( + input wire clk, + 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, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI outputs + */ + output wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata, + output wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep, + output wire [M_COUNT-1:0] m_axis_tvalid, + input wire [M_COUNT-1:0] m_axis_tready, + output wire [M_COUNT-1:0] m_axis_tlast, + output wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid, + output wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest, + output wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser +); + +parameter CL_M_COUNT = $clog2(M_COUNT); + +// datapath registers +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; + +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg [M_COUNT-1:0] m_axis_tvalid_reg = {M_COUNT{1'b0}}, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// // datapath control +reg store_axis_input_to_output; +reg store_axis_input_to_temp; +reg store_axis_temp_to_output; + +assign s_axis_tready = s_axis_tready_reg; + +assign m_axis_tdata = {M_COUNT{m_axis_tdata_reg}}; +assign m_axis_tkeep = KEEP_ENABLE ? {M_COUNT{m_axis_tkeep_reg}} : {M_COUNT*KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = LAST_ENABLE ? {M_COUNT{m_axis_tlast_reg}} : {M_COUNT{1'b1}}; +assign m_axis_tid = ID_ENABLE ? {M_COUNT{m_axis_tid_reg}} : {M_COUNT*ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? {M_COUNT{m_axis_tdest_reg}} : {M_COUNT*DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? {M_COUNT{m_axis_tuser_reg}} : {M_COUNT*USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +wire s_axis_tready_early = ((m_axis_tready & m_axis_tvalid) == m_axis_tvalid) || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid || !s_axis_tvalid)); + +always @* begin + // transfer sink ready state to source + m_axis_tvalid_next = m_axis_tvalid_reg & ~m_axis_tready; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; + + store_axis_input_to_output = 1'b0; + store_axis_input_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (s_axis_tready_reg) begin + // input is ready + if (((m_axis_tready & m_axis_tvalid) == m_axis_tvalid) || !m_axis_tvalid) begin + // output is ready or currently not valid, transfer data to output + m_axis_tvalid_next = {M_COUNT{s_axis_tvalid}}; + store_axis_input_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_axis_tvalid_next = s_axis_tvalid; + store_axis_input_to_temp = 1'b1; + end + end else if ((m_axis_tready & m_axis_tvalid) == m_axis_tvalid) begin + // input is not ready, but output is ready + m_axis_tvalid_next = {M_COUNT{temp_m_axis_tvalid_reg}}; + temp_m_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + if (rst) begin + s_axis_tready_reg <= 1'b0; + m_axis_tvalid_reg <= {M_COUNT{1'b0}}; + temp_m_axis_tvalid_reg <= {M_COUNT{1'b0}}; + end else begin + s_axis_tready_reg <= s_axis_tready_early; + m_axis_tvalid_reg <= m_axis_tvalid_next; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; + end + + // datapath + if (store_axis_input_to_output) begin + m_axis_tdata_reg <= s_axis_tdata; + m_axis_tkeep_reg <= s_axis_tkeep; + m_axis_tlast_reg <= s_axis_tlast; + m_axis_tid_reg <= s_axis_tid; + m_axis_tdest_reg <= s_axis_tdest; + m_axis_tuser_reg <= s_axis_tuser; + end else if (store_axis_temp_to_output) begin + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; + end + + if (store_axis_input_to_temp) begin + temp_m_axis_tdata_reg <= s_axis_tdata; + temp_m_axis_tkeep_reg <= s_axis_tkeep; + temp_m_axis_tlast_reg <= s_axis_tlast; + temp_m_axis_tid_reg <= s_axis_tid; + temp_m_axis_tdest_reg <= s_axis_tdest; + temp_m_axis_tuser_reg <= s_axis_tuser; + end +end + +endmodule diff --git a/tb/test_axis_broadcast_4.py b/tb/test_axis_broadcast_4.py new file mode 100755 index 000000000..0cb828847 --- /dev/null +++ b/tb/test_axis_broadcast_4.py @@ -0,0 +1,548 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep +import math + +module = 'axis_broadcast' +testbench = 'test_%s_4' % 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 bench(): + + # Parameters + M_COUNT = 4 + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + LAST_ENABLE = 1 + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + + # 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(1)[KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + + m_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)] + + m_axis_tready = ConcatSignal(*reversed(m_axis_tready_list)) + + # Outputs + s_axis_tready = Signal(bool(0)) + + m_axis_tdata = Signal(intbv(0)[M_COUNT*DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0xf)[M_COUNT*KEEP_WIDTH:]) + m_axis_tvalid = Signal(intbv(0)[M_COUNT:]) + m_axis_tlast = Signal(intbv(0)[M_COUNT:]) + m_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:]) + + m_axis_tdata_list = [m_axis_tdata((i+1)*DATA_WIDTH, i*DATA_WIDTH) for i in range(M_COUNT)] + m_axis_tkeep_list = [m_axis_tkeep((i+1)*KEEP_WIDTH, i*KEEP_WIDTH) for i in range(M_COUNT)] + m_axis_tvalid_list = [m_axis_tvalid(i) for i in range(M_COUNT)] + m_axis_tlast_list = [m_axis_tlast(i) for i in range(M_COUNT)] + m_axis_tid_list = [m_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)] + m_axis_tdest_list = [m_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)] + m_axis_tuser_list = [m_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)] + + # sources and sinks + source_pause = Signal(bool(0)) + sink_pause_list = [] + sink_list = [] + sink_logic_list = [] + + source = axis_ep.AXIStreamSource() + + source_logic = source.create_logic( + clk, + rst, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, + pause=source_pause, + name='source' + ) + + for k in range(M_COUNT): + s = axis_ep.AXIStreamSink() + p = Signal(bool(0)) + + sink_list.append(s) + sink_pause_list.append(p) + + sink_logic_list.append(s.create_logic( + clk, + rst, + tdata=m_axis_tdata_list[k], + tkeep=m_axis_tkeep_list[k], + tvalid=m_axis_tvalid_list[k], + tready=m_axis_tready_list[k], + tlast=m_axis_tlast_list[k], + tid=m_axis_tid_list[k], + tdest=m_axis_tdest_list[k], + tuser=m_axis_tuser_list[k], + pause=p, + name='sink_%d' % k + )) + + # 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_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, + + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + yield clk.posedge + + yield clk.posedge + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=1 + ) + + source.send(test_frame) + + for sink in sink_list: + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: longer packet") + current_test.next = 2 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)), + id=1 + ) + + source.send(test_frame) + + for sink in sink_list: + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 3: test packet with pauses") + current_test.next = 3 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=3, + dest=1 + ) + + source.send(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_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True + yield delay(32) + yield clk.posedge + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False + + for sink in sink_list: + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 4: back-to-back packets") + current_test.next = 4 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=4, + dest=2 + ) + + source.send(test_frame1) + source.send(test_frame2) + + for sink in sink_list: + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 5: alternate pause source") + current_test.next = 5 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=5, + dest=2 + ) + + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + + while s_axis_tvalid or m_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 + + for sink in sink_list: + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 6: alternate pause sink") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=6, + dest=2 + ) + + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + + while s_axis_tvalid or m_axis_tvalid: + sink_pause_list[0].next = True + sink_pause_list[1].next = True + sink_pause_list[2].next = True + sink_pause_list[3].next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause_list[0].next = False + sink_pause_list[1].next = False + sink_pause_list[2].next = False + sink_pause_list[3].next = False + yield clk.posedge + + for sink in sink_list: + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 7: alternate pause individual sinks") + current_test.next = 7 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=7, + dest=2 + ) + + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + + while s_axis_tvalid or m_axis_tvalid: + for pause in sink_pause_list: + pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + pause.next = False + yield clk.posedge + + for sink in sink_list: + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 8: alternate un-pause individual sinks") + current_test.next = 8 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=8, + dest=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=8, + dest=2 + ) + + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + + for pause in sink_pause_list: + pause.next = True + + while s_axis_tvalid or m_axis_tvalid: + for pause in sink_pause_list: + yield clk.posedge + yield clk.posedge + yield clk.posedge + pause.next = False + yield clk.posedge + pause.next = True + + for pause in sink_pause_list: + pause.next = False + + for sink in sink_list: + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + yield delay(100) + + yield clk.posedge + print("test 9: tuser assert") + current_test.next = 9 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10', + id=9, + dest=1, + last_cycle_user=1 + ) + + source.send(test_frame) + + for sink in sink_list: + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + assert rx_frame.last_cycle_user + + yield delay(100) + + raise StopSimulation + + return instances() + +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() + diff --git a/tb/test_axis_broadcast_4.v b/tb/test_axis_broadcast_4.v new file mode 100644 index 000000000..e4f707697 --- /dev/null +++ b/tb/test_axis_broadcast_4.v @@ -0,0 +1,140 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for axis_broadcast + */ +module test_axis_broadcast_4; + +// Parameters +parameter M_COUNT = 4; +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LAST_ENABLE = 1; +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; + +// Inputs +reg clk = 0; +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; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; + +reg [M_COUNT-1:0] m_axis_tready = 0; + +// Outputs +wire s_axis_tready; + +wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata; +wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep; +wire [M_COUNT-1:0] m_axis_tvalid; +wire [M_COUNT-1:0] m_axis_tlast; +wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid; +wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest; +wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready + ); + $to_myhdl( + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser + ); + + // dump file + $dumpfile("test_axis_broadcast_4.lxt"); + $dumpvars(0, test_axis_broadcast_4); +end + +axis_broadcast #( + .M_COUNT(M_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(LAST_ENABLE), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI outputs + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) +); + +endmodule From e0f740457b94a3b0487bb8ca60c6b8426153686d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 7 Mar 2019 22:51:40 -0800 Subject: [PATCH 526/617] Testbench updates --- tb/test_axis_adapter_64_8.py | 6 ++++-- tb/test_axis_adapter_8_64.py | 6 ++++-- tb/test_axis_arb_mux_4.py | 13 ++++++++----- tb/test_axis_arb_mux_4_64.py | 13 ++++++++----- tb/test_axis_async_fifo.py | 6 ++++-- tb/test_axis_async_fifo_64.py | 6 ++++-- tb/test_axis_async_frame_fifo.py | 6 ++++-- tb/test_axis_async_frame_fifo_64.py | 6 ++++-- tb/test_axis_broadcast_4.py | 24 ++++++++--------------- tb/test_axis_cobs_decode.py | 7 ++++--- tb/test_axis_cobs_encode.py | 7 ++++--- tb/test_axis_cobs_encode_zero_frame.py | 7 ++++--- tb/test_axis_demux_4.py | 24 +++++++++++------------ tb/test_axis_demux_4_64.py | 24 +++++++++++------------ tb/test_axis_fifo.py | 6 ++++-- tb/test_axis_fifo_64.py | 6 ++++-- tb/test_axis_frame_fifo.py | 6 ++++-- tb/test_axis_frame_fifo_64.py | 6 ++++-- tb/test_axis_frame_join_4.py | 15 +++++++------- tb/test_axis_frame_length_adjust_64.py | 6 ++++-- tb/test_axis_frame_length_adjust_8.py | 6 ++++-- tb/test_axis_mux_4.py | 19 +++++++++--------- tb/test_axis_mux_4_64.py | 19 +++++++++--------- tb/test_axis_rate_limit.py | 6 ++++-- tb/test_axis_rate_limit_64.py | 6 ++++-- tb/test_axis_register.py | 6 ++++-- tb/test_axis_register_64.py | 6 ++++-- tb/test_axis_srl_fifo.py | 6 ++++-- tb/test_axis_srl_fifo_64.py | 6 ++++-- tb/test_axis_srl_register.py | 6 ++++-- tb/test_axis_srl_register_64.py | 6 ++++-- tb/test_axis_stat_counter.py | 12 ++++++++++++ tb/test_axis_switch_4x4.py | 27 +++++++++++--------------- tb/test_axis_switch_4x4_64.py | 27 +++++++++++--------------- tb/test_axis_tap.py | 6 ++++-- tb/test_axis_tap_64.py | 6 ++++-- 36 files changed, 205 insertions(+), 165 deletions(-) diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index 42f4a0003..bd51eca7e 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -157,12 +157,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_axis_tvalid: diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index 8307bf940..4acafae6a 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -157,12 +157,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_axis_tvalid: diff --git a/tb/test_axis_arb_mux_4.py b/tb/test_axis_arb_mux_4.py index cd5489475..d5d055d67 100755 --- a/tb/test_axis_arb_mux_4.py +++ b/tb/test_axis_arb_mux_4.py @@ -302,7 +302,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 5: alterate pause source") + print("test 5: alternate pause source") current_test.next = 5 test_frame1 = axis_ep.AXIStreamFrame( @@ -327,14 +327,17 @@ def bench(): yield clk.posedge while s_axis_tvalid: - for k in range(S_COUNT): - source_pause_list[k].next = True - yield clk.posedge yield clk.posedge yield clk.posedge for k in range(S_COUNT): source_pause_list[k].next = False yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = True + yield clk.posedge + + for k in range(S_COUNT): + source_pause_list[k].next = False yield sink.wait() rx_frame = sink.recv() @@ -349,7 +352,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 6: alterate pause sink") + print("test 6: alternate pause sink") current_test.next = 6 test_frame1 = axis_ep.AXIStreamFrame( diff --git a/tb/test_axis_arb_mux_4_64.py b/tb/test_axis_arb_mux_4_64.py index b462ce9f1..4d4889f0c 100755 --- a/tb/test_axis_arb_mux_4_64.py +++ b/tb/test_axis_arb_mux_4_64.py @@ -302,7 +302,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 5: alterate pause source") + print("test 5: alternate pause source") current_test.next = 5 test_frame1 = axis_ep.AXIStreamFrame( @@ -327,14 +327,17 @@ def bench(): yield clk.posedge while s_axis_tvalid: - for k in range(S_COUNT): - source_pause_list[k].next = True - yield clk.posedge yield clk.posedge yield clk.posedge for k in range(S_COUNT): source_pause_list[k].next = False yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = True + yield clk.posedge + + for k in range(S_COUNT): + source_pause_list[k].next = False yield sink.wait() rx_frame = sink.recv() @@ -349,7 +352,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 6: alterate pause sink") + print("test 6: alternate pause sink") current_test.next = 6 test_frame1 = axis_ep.AXIStreamFrame( diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index 50f836591..39cfdcde0 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -320,12 +320,14 @@ def bench(): yield s_clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield s_clk.posedge yield s_clk.posedge yield s_clk.posedge source_pause.next = False yield s_clk.posedge + source_pause.next = True + yield s_clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index 9af357fe2..5e1739096 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -320,12 +320,14 @@ def bench(): yield s_clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield s_clk.posedge yield s_clk.posedge yield s_clk.posedge source_pause.next = False yield s_clk.posedge + source_pause.next = True + yield s_clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index 96d0d6956..f6745b583 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -418,12 +418,14 @@ def bench(): yield s_clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield s_clk.posedge yield s_clk.posedge yield s_clk.posedge source_pause.next = False yield s_clk.posedge + source_pause.next = True + yield s_clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index 699833f26..a72d060e4 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -418,12 +418,14 @@ def bench(): yield s_clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield s_clk.posedge yield s_clk.posedge yield s_clk.posedge source_pause.next = False yield s_clk.posedge + source_pause.next = True + yield s_clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_broadcast_4.py b/tb/test_axis_broadcast_4.py index 0cb828847..1a29c1d05 100755 --- a/tb/test_axis_broadcast_4.py +++ b/tb/test_axis_broadcast_4.py @@ -252,16 +252,12 @@ def bench(): yield delay(64) yield clk.posedge - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = True yield delay(32) yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False for sink in sink_list: yield sink.wait() @@ -382,17 +378,13 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge for sink in sink_list: diff --git a/tb/test_axis_cobs_decode.py b/tb/test_axis_cobs_decode.py index 160a96bd9..889dba45d 100755 --- a/tb/test_axis_cobs_decode.py +++ b/tb/test_axis_cobs_decode.py @@ -77,7 +77,6 @@ def cobs_decode(block): block = bytearray(block) dec = bytearray() - it = iter(bytearray(block)) code = 0 i = 0 @@ -202,12 +201,14 @@ def bench(): i = max(0, i-1) if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 2 - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): i = 2 diff --git a/tb/test_axis_cobs_encode.py b/tb/test_axis_cobs_encode.py index 370407afe..05b6e0ac8 100755 --- a/tb/test_axis_cobs_encode.py +++ b/tb/test_axis_cobs_encode.py @@ -78,7 +78,6 @@ def cobs_decode(block): block = bytearray(block) dec = bytearray() - it = iter(bytearray(block)) code = 0 i = 0 @@ -203,12 +202,14 @@ def bench(): i = max(0, i-1) if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 2 - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): i = 2 diff --git a/tb/test_axis_cobs_encode_zero_frame.py b/tb/test_axis_cobs_encode_zero_frame.py index c957e51e4..5fc3b55cd 100755 --- a/tb/test_axis_cobs_encode_zero_frame.py +++ b/tb/test_axis_cobs_encode_zero_frame.py @@ -78,7 +78,6 @@ def cobs_decode(block): block = bytearray(block) dec = bytearray() - it = iter(bytearray(block)) code = 0 i = 0 @@ -204,12 +203,14 @@ def bench(): i = max(0, i-1) if s_axis_tvalid or m_axis_tvalid or not source.empty(): i = 2 - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): i = 2 diff --git a/tb/test_axis_demux_4.py b/tb/test_axis_demux_4.py index b6b780c7b..5e02ffce7 100755 --- a/tb/test_axis_demux_4.py +++ b/tb/test_axis_demux_4.py @@ -322,7 +322,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 5: alterate pause source") + print("test 5: alternate pause source") current_test.next = 5 select.next = 1 @@ -349,13 +349,15 @@ def bench(): yield clk.posedge while s_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge + select.next = 2 yield clk.posedge source_pause.next = False yield clk.posedge - select.next = 2 + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink_list[1].wait() rx_frame = sink_list[1].recv() @@ -370,7 +372,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 6: alterate pause sink") + print("test 6: alternate pause sink") current_test.next = 6 select.next = 1 @@ -397,17 +399,13 @@ def bench(): yield clk.posedge while s_axis_tvalid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge select.next = 2 diff --git a/tb/test_axis_demux_4_64.py b/tb/test_axis_demux_4_64.py index 5c91bc39d..5fd01de50 100755 --- a/tb/test_axis_demux_4_64.py +++ b/tb/test_axis_demux_4_64.py @@ -322,7 +322,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 5: alterate pause source") + print("test 5: alternate pause source") current_test.next = 5 select.next = 1 @@ -349,13 +349,15 @@ def bench(): yield clk.posedge while s_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge + select.next = 2 yield clk.posedge source_pause.next = False yield clk.posedge - select.next = 2 + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink_list[1].wait() rx_frame = sink_list[1].recv() @@ -370,7 +372,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 6: alterate pause sink") + print("test 6: alternate pause sink") current_test.next = 6 select.next = 1 @@ -397,17 +399,13 @@ def bench(): yield clk.posedge while s_axis_tvalid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge select.next = 2 diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index 0ffd1c001..f38f320d7 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -309,12 +309,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index d09739bfb..7b508b7c7 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -309,12 +309,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index 9280f2c5a..2c2636b6a 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -365,12 +365,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index 2987b275c..164e9718c 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -365,12 +365,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_frame_join_4.py b/tb/test_axis_frame_join_4.py index 1b0a1a03f..c89b9d9f6 100755 --- a/tb/test_axis_frame_join_4.py +++ b/tb/test_axis_frame_join_4.py @@ -292,19 +292,18 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_frame_length_adjust_64.py b/tb/test_axis_frame_length_adjust_64.py index c2dc03188..a92a926bf 100755 --- a/tb/test_axis_frame_length_adjust_64.py +++ b/tb/test_axis_frame_length_adjust_64.py @@ -185,12 +185,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_axis_tvalid: diff --git a/tb/test_axis_frame_length_adjust_8.py b/tb/test_axis_frame_length_adjust_8.py index cf7177225..a180c5349 100755 --- a/tb/test_axis_frame_length_adjust_8.py +++ b/tb/test_axis_frame_length_adjust_8.py @@ -185,12 +185,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_axis_tvalid: diff --git a/tb/test_axis_mux_4.py b/tb/test_axis_mux_4.py index 4d469375c..e4c7791ae 100755 --- a/tb/test_axis_mux_4.py +++ b/tb/test_axis_mux_4.py @@ -318,7 +318,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 5: alterate pause source") + print("test 5: alternate pause source") current_test.next = 5 select.next = 1 @@ -345,20 +345,19 @@ def bench(): yield clk.posedge while s_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge select.next = 2 + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() @@ -372,7 +371,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 6: alterate pause sink") + print("test 6: alternate pause sink") current_test.next = 6 select.next = 1 diff --git a/tb/test_axis_mux_4_64.py b/tb/test_axis_mux_4_64.py index 0b9d8a471..31d4a267a 100755 --- a/tb/test_axis_mux_4_64.py +++ b/tb/test_axis_mux_4_64.py @@ -318,7 +318,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 5: alterate pause source") + print("test 5: alternate pause source") current_test.next = 5 select.next = 1 @@ -345,20 +345,19 @@ def bench(): yield clk.posedge while s_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge select.next = 2 + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() @@ -372,7 +371,7 @@ def bench(): yield delay(100) yield clk.posedge - print("test 6: alterate pause sink") + print("test 6: alternate pause sink") current_test.next = 6 select.next = 1 diff --git a/tb/test_axis_rate_limit.py b/tb/test_axis_rate_limit.py index 7c3ef6e3a..522075091 100755 --- a/tb/test_axis_rate_limit.py +++ b/tb/test_axis_rate_limit.py @@ -349,12 +349,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_rate_limit_64.py b/tb/test_axis_rate_limit_64.py index a4ff8105c..2ef4ae9f4 100755 --- a/tb/test_axis_rate_limit_64.py +++ b/tb/test_axis_rate_limit_64.py @@ -349,12 +349,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_register.py b/tb/test_axis_register.py index 95527a97d..f9bcea205 100755 --- a/tb/test_axis_register.py +++ b/tb/test_axis_register.py @@ -304,12 +304,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_register_64.py b/tb/test_axis_register_64.py index 7021a22fd..9098131ae 100755 --- a/tb/test_axis_register_64.py +++ b/tb/test_axis_register_64.py @@ -304,12 +304,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_srl_fifo.py b/tb/test_axis_srl_fifo.py index 4178d8e8a..ea3df9959 100755 --- a/tb/test_axis_srl_fifo.py +++ b/tb/test_axis_srl_fifo.py @@ -306,12 +306,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_srl_fifo_64.py b/tb/test_axis_srl_fifo_64.py index f788c2103..9458d188e 100755 --- a/tb/test_axis_srl_fifo_64.py +++ b/tb/test_axis_srl_fifo_64.py @@ -306,12 +306,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_srl_register.py b/tb/test_axis_srl_register.py index 25b6c1aab..0528bd4ef 100755 --- a/tb/test_axis_srl_register.py +++ b/tb/test_axis_srl_register.py @@ -303,12 +303,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_srl_register_64.py b/tb/test_axis_srl_register_64.py index 6763ed335..abdd4f7a6 100755 --- a/tb/test_axis_srl_register_64.py +++ b/tb/test_axis_srl_register_64.py @@ -303,12 +303,14 @@ def bench(): yield clk.posedge while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_stat_counter.py b/tb/test_axis_stat_counter.py index 238d58604..907fca6ef 100755 --- a/tb/test_axis_stat_counter.py +++ b/tb/test_axis_stat_counter.py @@ -528,6 +528,13 @@ def bench(): while monitor_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 while m_axis_tvalid: yield clk.posedge @@ -589,6 +596,11 @@ def bench(): yield clk.posedge while monitor_axis_tvalid: + monitor_sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + monitor_sink_pause.next = False yield clk.posedge while m_axis_tvalid: diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py index 6a25eb49e..bf6c4613c 100755 --- a/tb/test_axis_switch_4x4.py +++ b/tb/test_axis_switch_4x4.py @@ -202,32 +202,27 @@ def bench(): def wait_pause_source(): while s_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False + def wait_pause_sink(): while s_axis_tvalid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge @instance diff --git a/tb/test_axis_switch_4x4_64.py b/tb/test_axis_switch_4x4_64.py index ce53db690..a679a33d8 100755 --- a/tb/test_axis_switch_4x4_64.py +++ b/tb/test_axis_switch_4x4_64.py @@ -202,32 +202,27 @@ def bench(): def wait_pause_source(): while s_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False + def wait_pause_sink(): while s_axis_tvalid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge @instance diff --git a/tb/test_axis_tap.py b/tb/test_axis_tap.py index 02bc578cf..ee89b457a 100755 --- a/tb/test_axis_tap.py +++ b/tb/test_axis_tap.py @@ -329,12 +329,14 @@ def bench(): yield clk.posedge while tap_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_tap_64.py b/tb/test_axis_tap_64.py index b35cc8f28..f1edf5e77 100755 --- a/tb/test_axis_tap_64.py +++ b/tb/test_axis_tap_64.py @@ -329,12 +329,14 @@ def bench(): yield clk.posedge while tap_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() From d2df971fc937885ce453b3473b33876549946d58 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 7 Mar 2019 22:57:46 -0800 Subject: [PATCH 527/617] Add AXI stream frame length measurement module and testbenches --- rtl/axis_frame_len.v | 110 +++++++++ tb/test_axis_frame_len_64.py | 418 ++++++++++++++++++++++++++++++++++ tb/test_axis_frame_len_64.v | 94 ++++++++ tb/test_axis_frame_len_8.py | 420 +++++++++++++++++++++++++++++++++++ tb/test_axis_frame_len_8.v | 94 ++++++++ 5 files changed, 1136 insertions(+) create mode 100644 rtl/axis_frame_len.v create mode 100755 tb/test_axis_frame_len_64.py create mode 100644 tb/test_axis_frame_len_64.v create mode 100755 tb/test_axis_frame_len_8.py create mode 100644 tb/test_axis_frame_len_8.v diff --git a/rtl/axis_frame_len.v b/rtl/axis_frame_len.v new file mode 100644 index 000000000..e4dfe6596 --- /dev/null +++ b/rtl/axis_frame_len.v @@ -0,0 +1,110 @@ +/* + +Copyright (c) 2019 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 frame length measurement + */ +module axis_frame_len # +( + parameter DATA_WIDTH = 64, + parameter KEEP_ENABLE = (DATA_WIDTH>8), + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter LEN_WIDTH = 16 +) +( + input wire clk, + input wire rst, + + /* + * AXI monitor + */ + input wire [KEEP_WIDTH-1:0] monitor_axis_tkeep, + input wire monitor_axis_tvalid, + input wire monitor_axis_tready, + input wire monitor_axis_tlast, + + /* + * Status + */ + output wire [LEN_WIDTH-1:0] frame_len, + output wire frame_len_valid +); + +reg [LEN_WIDTH-1:0] frame_len_reg = 0, frame_len_next; +reg frame_len_valid_reg = 1'b0, frame_len_valid_next; +reg frame_reg = 1'b0, frame_next; + +assign frame_len = frame_len_reg; +assign frame_len_valid = frame_len_valid_reg; + +integer offset, i, bit_cnt; + +always @* begin + frame_len_next = frame_len_reg; + frame_len_valid_next = 1'b0; + frame_next = frame_reg; + + if (monitor_axis_tready && monitor_axis_tvalid) begin + // valid transfer cycle + + if (monitor_axis_tlast) begin + // end of frame + frame_len_valid_next = 1'b1; + frame_next = 1'b0; + end else if (!frame_reg) begin + // first word after end of frame + frame_len_next = 0; + frame_next = 1'b1; + end + + // increment frame length by number of words transferred + if (KEEP_ENABLE) begin + bit_cnt = 0; + for (i = 0; i <= KEEP_WIDTH; i = i + 1) begin + if (monitor_axis_tkeep == ({KEEP_WIDTH{1'b1}}) >> (KEEP_WIDTH-i)) bit_cnt = i; + end + frame_len_next = frame_len_next + bit_cnt; + end else begin + frame_len_next = frame_len_next + 1; + end + end +end + +always @(posedge clk) begin + if (rst) begin + frame_len_reg <= 0; + frame_len_valid_reg <= 0; + frame_reg <= 1'b0; + end else begin + frame_len_reg <= frame_len_next; + frame_len_valid_reg <= frame_len_valid_next; + frame_reg <= frame_next; + end +end + +endmodule diff --git a/tb/test_axis_frame_len_64.py b/tb/test_axis_frame_len_64.py new file mode 100755 index 000000000..229004749 --- /dev/null +++ b/tb/test_axis_frame_len_64.py @@ -0,0 +1,418 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep + +module = 'axis_frame_len' +testbench = 'test_%s_64' % 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 bench(): + + # Parameters + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + LEN_WIDTH = 16 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + monitor_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + monitor_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + monitor_axis_tvalid = Signal(bool(0)) + monitor_axis_tready = Signal(bool(0)) + monitor_axis_tlast = Signal(bool(0)) + + # Outputs + frame_len = Signal(intbv(0)[LEN_WIDTH:]) + frame_len_valid = Signal(bool(0)) + + # sources and sinks + source_pause = Signal(bool(0)) + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource() + + source_logic = source.create_logic( + clk, + rst, + tdata=monitor_axis_tdata, + tkeep=monitor_axis_tkeep, + tvalid=monitor_axis_tvalid, + tready=monitor_axis_tready, + tlast=monitor_axis_tlast, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=monitor_axis_tdata, + tkeep=monitor_axis_tkeep, + tvalid=monitor_axis_tvalid, + tready=monitor_axis_tready, + tlast=monitor_axis_tlast, + pause=sink_pause, + name='sink' + ) + + frame_len_sink = axis_ep.AXIStreamSink() + + frame_len_sink_logic = frame_len_sink.create_logic( + clk, + rst, + tdata=frame_len, + tvalid=frame_len_valid, + name='frame_len_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, + + monitor_axis_tkeep=monitor_axis_tkeep, + monitor_axis_tvalid=monitor_axis_tvalid, + monitor_axis_tready=monitor_axis_tready, + monitor_axis_tlast=monitor_axis_tlast, + + frame_len=frame_len, + frame_len_valid=frame_len_valid + ) + + @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 + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + + source.send(test_frame) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 4: longer packet") + current_test.next = 4 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)) + ) + + source.send(test_frame) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 5: test packet with pauses") + current_test.next = 5 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)) + ) + + source.send(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + while monitor_axis_tvalid: + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 6: back-to-back packets") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 7: alternate pause source") + current_test.next = 7 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + source_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + source_pause.next = False + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 8: alternate pause sink") + current_test.next = 8 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 9: various length packets") + current_test.next = 9 + + lens = [32, 48, 96, 128, 256] + test_frame = [] + + for i in lens: + test_frame.append(axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(i))) + ) + + for f in test_frame: + source.send(f) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + for i in lens: + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + raise StopSimulation + + return instances() + +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() + diff --git a/tb/test_axis_frame_len_64.v b/tb/test_axis_frame_len_64.v new file mode 100644 index 000000000..ec4dadf01 --- /dev/null +++ b/tb/test_axis_frame_len_64.v @@ -0,0 +1,94 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for axis_frame_len + */ +module test_axis_frame_len_64; + +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LEN_WIDTH = 16; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [KEEP_WIDTH-1:0] monitor_axis_tkeep = 0; +reg monitor_axis_tvalid = 0; +reg monitor_axis_tready = 0; +reg monitor_axis_tlast = 0; + +// Outputs +wire [LEN_WIDTH-1:0] frame_len; +wire frame_len_valid; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + monitor_axis_tkeep, + monitor_axis_tvalid, + monitor_axis_tready, + monitor_axis_tlast + ); + $to_myhdl( + frame_len, + frame_len_valid + ); + + // dump file + $dumpfile("test_axis_frame_len_64.lxt"); + $dumpvars(0, test_axis_frame_len_64); +end + +axis_frame_len #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LEN_WIDTH(LEN_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI monitor + .monitor_axis_tkeep(monitor_axis_tkeep), + .monitor_axis_tvalid(monitor_axis_tvalid), + .monitor_axis_tready(monitor_axis_tready), + .monitor_axis_tlast(monitor_axis_tlast), + // Status + .frame_len(frame_len), + .frame_len_valid(frame_len_valid) +); + +endmodule diff --git a/tb/test_axis_frame_len_8.py b/tb/test_axis_frame_len_8.py new file mode 100755 index 000000000..9bca5f310 --- /dev/null +++ b/tb/test_axis_frame_len_8.py @@ -0,0 +1,420 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep + +module = 'axis_frame_len' +testbench = 'test_%s_8' % 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 bench(): + + # Parameters + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = (DATA_WIDTH/8) + LEN_WIDTH = 16 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + monitor_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + monitor_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) + monitor_axis_tvalid = Signal(bool(0)) + monitor_axis_tready = Signal(bool(0)) + monitor_axis_tlast = Signal(bool(0)) + + # Outputs + frame_len = Signal(intbv(0)[LEN_WIDTH:]) + frame_len_valid = Signal(bool(0)) + + # sources and sinks + source_pause = Signal(bool(0)) + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource() + + source_logic = source.create_logic( + clk, + rst, + tdata=monitor_axis_tdata, + tkeep=monitor_axis_tkeep, + tvalid=monitor_axis_tvalid, + tready=monitor_axis_tready, + tlast=monitor_axis_tlast, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=monitor_axis_tdata, + tkeep=monitor_axis_tkeep, + tvalid=monitor_axis_tvalid, + tready=monitor_axis_tready, + tlast=monitor_axis_tlast, + pause=sink_pause, + name='sink' + ) + + frame_len_sink = axis_ep.AXIStreamSink() + + frame_len_sink_logic = frame_len_sink.create_logic( + clk, + rst, + tdata=frame_len, + tvalid=frame_len_valid, + name='frame_len_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, + + monitor_axis_tkeep=monitor_axis_tkeep, + monitor_axis_tvalid=monitor_axis_tvalid, + monitor_axis_tready=monitor_axis_tready, + monitor_axis_tlast=monitor_axis_tlast, + + frame_len=frame_len, + frame_len_valid=frame_len_valid + ) + + @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 + print("test 1: test packet") + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + + source.send(test_frame) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 4: longer packet") + current_test.next = 4 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)) + ) + + source.send(test_frame) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 5: test packet with pauses") + current_test.next = 5 + + test_frame = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(256)) + ) + + source.send(test_frame) + yield clk.posedge + + yield delay(64) + yield clk.posedge + source_pause.next = True + yield delay(32) + yield clk.posedge + source_pause.next = False + + yield delay(64) + yield clk.posedge + sink_pause.next = True + yield delay(32) + yield clk.posedge + sink_pause.next = False + + while monitor_axis_tvalid: + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 6: back-to-back packets") + current_test.next = 6 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 7: alternate pause source") + current_test.next = 7 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + + while monitor_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 + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 8: alternate pause sink") + current_test.next = 8 + + test_frame1 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + test_frame2 = axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10' + ) + + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + + while monitor_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + yield clk.posedge + print("test 9: various length packets") + current_test.next = 9 + + lens = [32, 48, 96, 128, 256] + test_frame = [] + + for i in lens: + test_frame.append(axis_ep.AXIStreamFrame( + b'\xDA\xD1\xD2\xD3\xD4\xD5' + + b'\x5A\x51\x52\x53\x54\x55' + + b'\x80\x00' + + bytearray(range(i))) + ) + + for f in test_frame: + source.send(f) + yield clk.posedge + + while monitor_axis_tvalid: + yield clk.posedge + + for i in lens: + yield sink.wait() + f = sink.recv() + + yield frame_len_sink.wait() + l = frame_len_sink.recv() + + assert len(f.data) == l.data[0] + + yield delay(100) + + raise StopSimulation + + return instances() + +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() + diff --git a/tb/test_axis_frame_len_8.v b/tb/test_axis_frame_len_8.v new file mode 100644 index 000000000..0f40aa8e2 --- /dev/null +++ b/tb/test_axis_frame_len_8.v @@ -0,0 +1,94 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for axis_frame_len + */ +module test_axis_frame_len_8; + +// Parameters +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter LEN_WIDTH = 16; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [KEEP_WIDTH-1:0] monitor_axis_tkeep = 0; +reg monitor_axis_tvalid = 0; +reg monitor_axis_tready = 0; +reg monitor_axis_tlast = 0; + +// Outputs +wire [LEN_WIDTH-1:0] frame_len; +wire frame_len_valid; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + monitor_axis_tkeep, + monitor_axis_tvalid, + monitor_axis_tready, + monitor_axis_tlast + ); + $to_myhdl( + frame_len, + frame_len_valid + ); + + // dump file + $dumpfile("test_axis_frame_len_8.lxt"); + $dumpvars(0, test_axis_frame_len_8); +end + +axis_frame_len #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LEN_WIDTH(LEN_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI monitor + .monitor_axis_tkeep(monitor_axis_tkeep), + .monitor_axis_tvalid(monitor_axis_tvalid), + .monitor_axis_tready(monitor_axis_tready), + .monitor_axis_tlast(monitor_axis_tlast), + // Status + .frame_len(frame_len), + .frame_len_valid(frame_len_valid) +); + +endmodule From b1f3a74b86a9a80c203ace6bc814c8d94e088aa6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 7 Mar 2019 22:59:15 -0800 Subject: [PATCH 528/617] Remove unused code --- rtl/axis_demux.v | 2 -- 1 file changed, 2 deletions(-) diff --git a/rtl/axis_demux.v b/rtl/axis_demux.v index ed661e76e..546734ad1 100644 --- a/rtl/axis_demux.v +++ b/rtl/axis_demux.v @@ -99,8 +99,6 @@ wire m_axis_tready_int_early; assign s_axis_tready = s_axis_tready_reg && enable; -integer i; - always @* begin select_next = select_reg; select_ctl = select_reg; From 414f091c2c948ff8a55643bc1aabef657b8c1146 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 7 Mar 2019 22:59:49 -0800 Subject: [PATCH 529/617] Properly handle width of 1 --- rtl/priority_encoder.v | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rtl/priority_encoder.v b/rtl/priority_encoder.v index e40b27293..730306302 100644 --- a/rtl/priority_encoder.v +++ b/rtl/priority_encoder.v @@ -47,7 +47,11 @@ parameter W1 = 2**$clog2(WIDTH); parameter W2 = W1/2; generate - if (WIDTH == 2) begin + if (WIDTH == 1) begin + // one input + assign output_valid = input_unencoded; + assign output_encoded = 0; + end else if (WIDTH == 2) begin // two inputs - just an OR gate assign output_valid = |input_unencoded; if (LSB_PRIORITY == "LOW") begin From 013e88253e40f3e395aaa47529a9a06b6a26a8a0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 7 Mar 2019 23:44:43 -0800 Subject: [PATCH 530/617] Testbench updates --- tb/test_arp_eth_rx.py | 6 ++++-- tb/test_arp_eth_rx_64.py | 6 ++++-- tb/test_axis_eth_fcs_check.py | 6 ++++-- tb/test_axis_eth_fcs_check_64.py | 6 ++++-- tb/test_axis_eth_fcs_insert.py | 6 ++++-- tb/test_axis_eth_fcs_insert_64.py | 6 ++++-- tb/test_axis_eth_fcs_insert_64_pad.py | 6 ++++-- tb/test_axis_eth_fcs_insert_pad.py | 6 ++++-- tb/test_eth_arb_mux_4.py | 15 +++++++-------- tb/test_eth_arb_mux_64_4.py | 15 +++++++-------- tb/test_eth_axis_rx.py | 6 ++++-- tb/test_eth_axis_rx_64.py | 6 ++++-- tb/test_eth_axis_tx.py | 6 ++++-- tb/test_eth_axis_tx_64.py | 6 ++++-- tb/test_eth_demux_4.py | 18 ++++++++---------- tb/test_eth_demux_64_4.py | 12 ++++-------- tb/test_eth_mux_4.py | 15 +++++++-------- tb/test_eth_mux_64_4.py | 15 +++++++-------- tb/test_ip_arb_mux_4.py | 15 +++++++-------- tb/test_ip_arb_mux_64_4.py | 15 +++++++-------- tb/test_ip_demux_4.py | 12 ++++-------- tb/test_ip_demux_64_4.py | 12 ++++-------- tb/test_ip_eth_rx.py | 6 ++++-- tb/test_ip_eth_rx_64.py | 6 ++++-- tb/test_ip_eth_tx.py | 6 ++++-- tb/test_ip_eth_tx_64.py | 6 ++++-- tb/test_ip_mux_4.py | 15 +++++++-------- tb/test_ip_mux_64_4.py | 15 +++++++-------- tb/test_udp_arb_mux_4.py | 15 +++++++-------- tb/test_udp_arb_mux_64_4.py | 15 +++++++-------- tb/test_udp_demux_4.py | 12 ++++-------- tb/test_udp_demux_64_4.py | 12 ++++-------- tb/test_udp_ip_rx.py | 6 ++++-- tb/test_udp_ip_rx_64.py | 6 ++++-- tb/test_udp_ip_tx.py | 6 ++++-- tb/test_udp_ip_tx_64.py | 6 ++++-- tb/test_udp_mux_4.py | 15 +++++++-------- tb/test_udp_mux_64_4.py | 15 +++++++-------- 38 files changed, 192 insertions(+), 186 deletions(-) diff --git a/tb/test_arp_eth_rx.py b/tb/test_arp_eth_rx.py index e793ef506..19303fac3 100755 --- a/tb/test_arp_eth_rx.py +++ b/tb/test_arp_eth_rx.py @@ -358,12 +358,14 @@ def bench(): yield clk.posedge while s_eth_payload_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_arp_eth_rx_64.py b/tb/test_arp_eth_rx_64.py index 998a6f007..0191157b8 100755 --- a/tb/test_arp_eth_rx_64.py +++ b/tb/test_arp_eth_rx_64.py @@ -361,12 +361,14 @@ def bench(): yield clk.posedge while s_eth_payload_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_axis_eth_fcs_check.py b/tb/test_axis_eth_fcs_check.py index 55b2729e2..620ecdcae 100755 --- a/tb/test_axis_eth_fcs_check.py +++ b/tb/test_axis_eth_fcs_check.py @@ -144,12 +144,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_axis_tvalid: diff --git a/tb/test_axis_eth_fcs_check_64.py b/tb/test_axis_eth_fcs_check_64.py index 5c021ef67..67b3d92ef 100755 --- a/tb/test_axis_eth_fcs_check_64.py +++ b/tb/test_axis_eth_fcs_check_64.py @@ -150,12 +150,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_axis_tvalid: diff --git a/tb/test_axis_eth_fcs_insert.py b/tb/test_axis_eth_fcs_insert.py index 8a5ee2477..e41a7379a 100755 --- a/tb/test_axis_eth_fcs_insert.py +++ b/tb/test_axis_eth_fcs_insert.py @@ -136,12 +136,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_axis_tvalid: diff --git a/tb/test_axis_eth_fcs_insert_64.py b/tb/test_axis_eth_fcs_insert_64.py index d2bfb7583..6b276f353 100755 --- a/tb/test_axis_eth_fcs_insert_64.py +++ b/tb/test_axis_eth_fcs_insert_64.py @@ -142,12 +142,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_axis_tvalid: diff --git a/tb/test_axis_eth_fcs_insert_64_pad.py b/tb/test_axis_eth_fcs_insert_64_pad.py index af81dcade..ce36959be 100755 --- a/tb/test_axis_eth_fcs_insert_64_pad.py +++ b/tb/test_axis_eth_fcs_insert_64_pad.py @@ -142,12 +142,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_axis_tvalid: diff --git a/tb/test_axis_eth_fcs_insert_pad.py b/tb/test_axis_eth_fcs_insert_pad.py index e9133c3b8..b2d9393fa 100755 --- a/tb/test_axis_eth_fcs_insert_pad.py +++ b/tb/test_axis_eth_fcs_insert_pad.py @@ -136,12 +136,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_axis_tvalid: diff --git a/tb/test_eth_arb_mux_4.py b/tb/test_eth_arb_mux_4.py index bd4c62c4b..f96e9b710 100755 --- a/tb/test_eth_arb_mux_4.py +++ b/tb/test_eth_arb_mux_4.py @@ -335,19 +335,18 @@ def bench(): yield clk.posedge while s_eth_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_eth_arb_mux_64_4.py b/tb/test_eth_arb_mux_64_4.py index 86104b6d6..75d321252 100755 --- a/tb/test_eth_arb_mux_64_4.py +++ b/tb/test_eth_arb_mux_64_4.py @@ -335,19 +335,18 @@ def bench(): yield clk.posedge while s_eth_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index fe6467aaf..bb6ad1e32 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -153,12 +153,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_eth_payload_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_eth_payload_axis_tvalid: diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index f39d730b9..c7733a363 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -159,12 +159,14 @@ def bench(): def wait_pause_source(): while s_axis_tvalid or m_eth_payload_axis_tvalid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_axis_tvalid or m_eth_payload_axis_tvalid: diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py index a5031ae0a..229712fe7 100755 --- a/tb/test_eth_axis_tx.py +++ b/tb/test_eth_axis_tx.py @@ -144,12 +144,14 @@ def bench(): def wait_pause_source(): while s_eth_payload_axis_tvalid or m_axis_tvalid or s_eth_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_eth_payload_axis_tvalid or m_axis_tvalid or s_eth_hdr_valid: diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py index 105c24cba..f529c49f7 100755 --- a/tb/test_eth_axis_tx_64.py +++ b/tb/test_eth_axis_tx_64.py @@ -150,12 +150,14 @@ def bench(): def wait_pause_source(): while s_eth_payload_axis_tvalid or m_axis_tvalid or s_eth_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_eth_payload_axis_tvalid or m_axis_tvalid or s_eth_hdr_valid: diff --git a/tb/test_eth_demux_4.py b/tb/test_eth_demux_4.py index 16a1adb23..5b9e488ed 100755 --- a/tb/test_eth_demux_4.py +++ b/tb/test_eth_demux_4.py @@ -354,14 +354,16 @@ def bench(): yield clk.posedge while s_eth_payload_axis_tvalid or s_eth_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge select.next = 2 + source_pause.next = False + yield sink_list[1].wait() rx_frame = sink_list[1].recv() @@ -396,17 +398,13 @@ def bench(): yield clk.posedge while s_eth_payload_axis_tvalid or s_eth_hdr_valid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge select.next = 2 diff --git a/tb/test_eth_demux_64_4.py b/tb/test_eth_demux_64_4.py index 1071089d3..6b5afe2a1 100755 --- a/tb/test_eth_demux_64_4.py +++ b/tb/test_eth_demux_64_4.py @@ -396,17 +396,13 @@ def bench(): yield clk.posedge while s_eth_payload_axis_tvalid or s_eth_hdr_valid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = True yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge select.next = 2 diff --git a/tb/test_eth_mux_4.py b/tb/test_eth_mux_4.py index 7a7ef02f4..e96d41a38 100755 --- a/tb/test_eth_mux_4.py +++ b/tb/test_eth_mux_4.py @@ -354,20 +354,19 @@ def bench(): yield clk.posedge while s_eth_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge select.next = 2 + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_eth_mux_64_4.py b/tb/test_eth_mux_64_4.py index 8beb729eb..2b263523f 100755 --- a/tb/test_eth_mux_64_4.py +++ b/tb/test_eth_mux_64_4.py @@ -354,20 +354,19 @@ def bench(): yield clk.posedge while s_eth_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge select.next = 2 + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_ip_arb_mux_4.py b/tb/test_ip_arb_mux_4.py index ad3c3885a..2127c395c 100755 --- a/tb/test_ip_arb_mux_4.py +++ b/tb/test_ip_arb_mux_4.py @@ -538,19 +538,18 @@ def bench(): yield clk.posedge while s_ip_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_ip_arb_mux_64_4.py b/tb/test_ip_arb_mux_64_4.py index cf17d9654..ee633c952 100755 --- a/tb/test_ip_arb_mux_64_4.py +++ b/tb/test_ip_arb_mux_64_4.py @@ -538,19 +538,18 @@ def bench(): yield clk.posedge while s_ip_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_ip_demux_4.py b/tb/test_ip_demux_4.py index d4a51a1fd..a5d467d5d 100755 --- a/tb/test_ip_demux_4.py +++ b/tb/test_ip_demux_4.py @@ -627,17 +627,13 @@ def bench(): yield clk.posedge while s_ip_payload_axis_tvalid or s_ip_hdr_valid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge select.next = 2 diff --git a/tb/test_ip_demux_64_4.py b/tb/test_ip_demux_64_4.py index 166ad0fce..69f65356b 100755 --- a/tb/test_ip_demux_64_4.py +++ b/tb/test_ip_demux_64_4.py @@ -627,17 +627,13 @@ def bench(): yield clk.posedge while s_ip_payload_axis_tvalid or s_ip_hdr_valid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge select.next = 2 diff --git a/tb/test_ip_eth_rx.py b/tb/test_ip_eth_rx.py index 69fa513bf..2996f196d 100755 --- a/tb/test_ip_eth_rx.py +++ b/tb/test_ip_eth_rx.py @@ -222,12 +222,14 @@ def bench(): def wait_pause_source(): while s_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_eth_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_eth_hdr_valid: diff --git a/tb/test_ip_eth_rx_64.py b/tb/test_ip_eth_rx_64.py index 62b349566..e55cdbb3a 100755 --- a/tb/test_ip_eth_rx_64.py +++ b/tb/test_ip_eth_rx_64.py @@ -228,12 +228,14 @@ def bench(): def wait_pause_source(): while s_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_eth_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_eth_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_eth_hdr_valid: diff --git a/tb/test_ip_eth_tx.py b/tb/test_ip_eth_tx.py index 50cbaaba1..799de5202 100755 --- a/tb/test_ip_eth_tx.py +++ b/tb/test_ip_eth_tx.py @@ -198,12 +198,14 @@ def bench(): def wait_pause_source(): while s_ip_payload_axis_tvalid or m_eth_payload_axis_tvalid or s_ip_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_ip_payload_axis_tvalid or m_eth_payload_axis_tvalid or s_ip_hdr_valid: diff --git a/tb/test_ip_eth_tx_64.py b/tb/test_ip_eth_tx_64.py index d528db9a3..185fb140f 100755 --- a/tb/test_ip_eth_tx_64.py +++ b/tb/test_ip_eth_tx_64.py @@ -204,12 +204,14 @@ def bench(): def wait_pause_source(): while s_ip_payload_axis_tvalid or m_eth_payload_axis_tvalid or s_ip_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_ip_payload_axis_tvalid or m_eth_payload_axis_tvalid or s_ip_hdr_valid: diff --git a/tb/test_ip_mux_4.py b/tb/test_ip_mux_4.py index 178589b0e..c19349bec 100755 --- a/tb/test_ip_mux_4.py +++ b/tb/test_ip_mux_4.py @@ -557,20 +557,19 @@ def bench(): yield clk.posedge while s_ip_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge select.next = 2 + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_ip_mux_64_4.py b/tb/test_ip_mux_64_4.py index b1920fdfd..ea7ca2f19 100755 --- a/tb/test_ip_mux_64_4.py +++ b/tb/test_ip_mux_64_4.py @@ -557,20 +557,19 @@ def bench(): yield clk.posedge while s_ip_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge select.next = 2 + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_udp_arb_mux_4.py b/tb/test_udp_arb_mux_4.py index 6b98097e0..69c07767e 100755 --- a/tb/test_udp_arb_mux_4.py +++ b/tb/test_udp_arb_mux_4.py @@ -598,19 +598,18 @@ def bench(): yield clk.posedge while s_udp_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_udp_arb_mux_64_4.py b/tb/test_udp_arb_mux_64_4.py index c28ac25c4..a4d0b3de8 100755 --- a/tb/test_udp_arb_mux_64_4.py +++ b/tb/test_udp_arb_mux_64_4.py @@ -598,19 +598,18 @@ def bench(): yield clk.posedge while s_udp_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_udp_demux_4.py b/tb/test_udp_demux_4.py index 45a2c0b1b..16352cb08 100755 --- a/tb/test_udp_demux_4.py +++ b/tb/test_udp_demux_4.py @@ -695,17 +695,13 @@ def bench(): yield clk.posedge while s_udp_payload_axis_tvalid or s_udp_hdr_valid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge select.next = 2 diff --git a/tb/test_udp_demux_64_4.py b/tb/test_udp_demux_64_4.py index f99169b75..5b0e0935b 100755 --- a/tb/test_udp_demux_64_4.py +++ b/tb/test_udp_demux_64_4.py @@ -695,17 +695,13 @@ def bench(): yield clk.posedge while s_udp_payload_axis_tvalid or s_udp_hdr_valid: - sink_pause_list[0].next = True - sink_pause_list[1].next = True - sink_pause_list[2].next = True - sink_pause_list[3].next = True + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge yield clk.posedge yield clk.posedge - sink_pause_list[0].next = False - sink_pause_list[1].next = False - sink_pause_list[2].next = False - sink_pause_list[3].next = False + for k in range(M_COUNT): + sink_pause_list[k].next = False yield clk.posedge select.next = 2 diff --git a/tb/test_udp_ip_rx.py b/tb/test_udp_ip_rx.py index 69c43a3bc..c4b1e9c4e 100755 --- a/tb/test_udp_ip_rx.py +++ b/tb/test_udp_ip_rx.py @@ -264,12 +264,14 @@ def bench(): def wait_pause_source(): while s_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_ip_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_ip_hdr_valid: diff --git a/tb/test_udp_ip_rx_64.py b/tb/test_udp_ip_rx_64.py index 763fba805..6d4ea37a7 100755 --- a/tb/test_udp_ip_rx_64.py +++ b/tb/test_udp_ip_rx_64.py @@ -270,12 +270,14 @@ def bench(): def wait_pause_source(): while s_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_ip_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_ip_payload_axis_tvalid or m_udp_payload_axis_tvalid or s_ip_hdr_valid: diff --git a/tb/test_udp_ip_tx.py b/tb/test_udp_ip_tx.py index 2197ab41d..4a34589d7 100755 --- a/tb/test_udp_ip_tx.py +++ b/tb/test_udp_ip_tx.py @@ -256,12 +256,14 @@ def bench(): def wait_pause_source(): while s_udp_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_udp_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_udp_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_udp_hdr_valid: diff --git a/tb/test_udp_ip_tx_64.py b/tb/test_udp_ip_tx_64.py index ee6562acf..474adbaea 100755 --- a/tb/test_udp_ip_tx_64.py +++ b/tb/test_udp_ip_tx_64.py @@ -262,12 +262,14 @@ def bench(): def wait_pause_source(): while s_udp_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_udp_hdr_valid: - source_pause.next = True - yield clk.posedge yield clk.posedge yield clk.posedge source_pause.next = False yield clk.posedge + source_pause.next = True + yield clk.posedge + + source_pause.next = False def wait_pause_sink(): while s_udp_payload_axis_tvalid or m_ip_payload_axis_tvalid or s_udp_hdr_valid: diff --git a/tb/test_udp_mux_4.py b/tb/test_udp_mux_4.py index 1399c50af..e1355b0d6 100755 --- a/tb/test_udp_mux_4.py +++ b/tb/test_udp_mux_4.py @@ -617,20 +617,19 @@ def bench(): yield clk.posedge while s_udp_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge select.next = 2 + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_udp_mux_64_4.py b/tb/test_udp_mux_64_4.py index 162f658ce..64c5af4c9 100755 --- a/tb/test_udp_mux_64_4.py +++ b/tb/test_udp_mux_64_4.py @@ -617,20 +617,19 @@ def bench(): yield clk.posedge while s_udp_payload_axis_tvalid: - source_pause_list[0].next = True - source_pause_list[1].next = True - source_pause_list[2].next = True - source_pause_list[3].next = True yield clk.posedge yield clk.posedge + for k in range(S_COUNT): + source_pause_list[k].next = False yield clk.posedge - source_pause_list[0].next = False - source_pause_list[1].next = False - source_pause_list[2].next = False - source_pause_list[3].next = False + for k in range(S_COUNT): + source_pause_list[k].next = True yield clk.posedge select.next = 2 + for k in range(S_COUNT): + source_pause_list[k].next = False + yield sink.wait() rx_frame = sink.recv() From fb4abb6b39fe1536162dfdc41d3cf64beb8fa834 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 14 Mar 2019 14:44:00 -0700 Subject: [PATCH 531/617] Fix widths --- rtl/arp_eth_tx_64.v | 4 ++-- rtl/eth_axis_rx_64.v | 4 ++-- rtl/ip_eth_tx_64.v | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rtl/arp_eth_tx_64.v b/rtl/arp_eth_tx_64.v index 52a499492..0270cca1a 100644 --- a/rtl/arp_eth_tx_64.v +++ b/rtl/arp_eth_tx_64.v @@ -282,13 +282,13 @@ always @(posedge clk) begin end // output datapath logic -reg [64:0] m_eth_payload_axis_tdata_reg = 64'd0; +reg [63:0] m_eth_payload_axis_tdata_reg = 64'd0; reg [7:0] m_eth_payload_axis_tkeep_reg = 8'd0; reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; reg m_eth_payload_axis_tlast_reg = 1'b0; reg m_eth_payload_axis_tuser_reg = 1'b0; -reg [64:0] temp_m_eth_payload_axis_tdata_reg = 64'd0; +reg [63:0] temp_m_eth_payload_axis_tdata_reg = 64'd0; reg [7:0] temp_m_eth_payload_axis_tkeep_reg = 8'd0; reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; reg temp_m_eth_payload_axis_tlast_reg = 1'b0; diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index a9928c0f8..e060e9bde 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -326,13 +326,13 @@ always @(posedge clk) begin end // output datapath logic -reg [64:0] m_eth_payload_axis_tdata_reg = 64'd0; +reg [63:0] m_eth_payload_axis_tdata_reg = 64'd0; reg [7:0] m_eth_payload_axis_tkeep_reg = 8'd0; reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; reg m_eth_payload_axis_tlast_reg = 1'b0; reg m_eth_payload_axis_tuser_reg = 1'b0; -reg [64:0] temp_m_eth_payload_axis_tdata_reg = 64'd0; +reg [63:0] temp_m_eth_payload_axis_tdata_reg = 64'd0; reg [7:0] temp_m_eth_payload_axis_tkeep_reg = 8'd0; reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; reg temp_m_eth_payload_axis_tlast_reg = 1'b0; diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index c19a2f008..6c75e37d6 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -550,13 +550,13 @@ always @(posedge clk) begin end // output datapath logic -reg [64:0] m_eth_payload_axis_tdata_reg = 64'd0; +reg [63:0] m_eth_payload_axis_tdata_reg = 64'd0; reg [7:0] m_eth_payload_axis_tkeep_reg = 8'd0; reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; reg m_eth_payload_axis_tlast_reg = 1'b0; reg m_eth_payload_axis_tuser_reg = 1'b0; -reg [64:0] temp_m_eth_payload_axis_tdata_reg = 64'd0; +reg [63:0] temp_m_eth_payload_axis_tdata_reg = 64'd0; reg [7:0] temp_m_eth_payload_axis_tkeep_reg = 8'd0; reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; reg temp_m_eth_payload_axis_tlast_reg = 1'b0; From 0efb135b7a5feb228734b651647bf1ad5219b79a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 25 Mar 2019 15:06:45 -0700 Subject: [PATCH 532/617] Fix STATE_WAIT_END --- rtl/axis_xgmii_tx_32.v | 8 ++++++-- rtl/axis_xgmii_tx_64.v | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index 7c8ab7d9e..bdcda1cc0 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -482,8 +482,10 @@ always @* begin end STATE_WAIT_END: begin // wait for end of frame - if (ifg_count_reg > 8'd8) begin - ifg_count_next = ifg_count_reg - 8'd8; + s_axis_tready_next = 1'b1; + + if (ifg_count_reg > 8'd4) begin + ifg_count_next = ifg_count_reg - 8'd4; end else begin ifg_count_next = 8'd0; end @@ -492,6 +494,8 @@ always @* begin if (s_axis_tvalid) begin if (s_axis_tlast) begin + s_axis_tready_next = 1'b0; + if (ENABLE_DIC) begin if (ifg_count_next > 8'd3) begin state_next = STATE_IFG; diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index e6f8c2569..3f260133e 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -597,6 +597,8 @@ always @* begin end STATE_WAIT_END: begin // wait for end of frame + s_axis_tready_next = 1'b1; + if (ifg_count_reg > 8'd8) begin ifg_count_next = ifg_count_reg - 8'd8; end else begin @@ -607,6 +609,8 @@ always @* begin if (s_axis_tvalid) begin if (s_axis_tlast) begin + s_axis_tready_next = 1'b0; + if (ENABLE_DIC) begin if (ifg_count_next > 8'd7) begin state_next = STATE_IFG; From 9891d75c2f646bac2dc1bf700661647d34c31865 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 25 Mar 2019 23:24:01 -0700 Subject: [PATCH 533/617] Fix STATE_WAIT_END --- rtl/axis_baser_tx_64.v | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v index 2a4d987cc..7bf1d2202 100644 --- a/rtl/axis_baser_tx_64.v +++ b/rtl/axis_baser_tx_64.v @@ -664,8 +664,10 @@ always @* begin end STATE_WAIT_END: begin // wait for end of frame - if (ifg_count_reg > 8'd8) begin - ifg_count_next = ifg_count_reg - 8'd8; + s_axis_tready_next = 1'b1; + + if (ifg_count_reg > 8'd4) begin + ifg_count_next = ifg_count_reg - 8'd4; end else begin ifg_count_next = 8'd0; end @@ -674,6 +676,8 @@ always @* begin if (s_axis_tvalid) begin if (s_axis_tlast) begin + s_axis_tready_next = 1'b0; + if (ENABLE_DIC) begin if (ifg_count_next > 8'd7) begin state_next = STATE_IFG; From b691a30760ab224308d3ee0a559cc759da773f8d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 26 Mar 2019 12:06:58 -0700 Subject: [PATCH 534/617] Accept OS_START block type --- rtl/axis_baser_rx_64.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/axis_baser_rx_64.v b/rtl/axis_baser_rx_64.v index 8bc7072da..d52c2664a 100644 --- a/rtl/axis_baser_rx_64.v +++ b/rtl/axis_baser_rx_64.v @@ -435,7 +435,7 @@ always @(posedge clk) begin lanes_swapped <= 1'b0; start_packet_0_reg <= 1'b1; input_type_d0 <= INPUT_TYPE_START_0; - end else if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_4)begin + end else if (encoded_rx_hdr == SYNC_CTRL && (encoded_rx_data[7:0] == BLOCK_TYPE_START_4 || encoded_rx_data[7:0] == BLOCK_TYPE_OS_START)) begin lanes_swapped <= 1'b1; start_packet_4_reg <= 1'b1; delay_type_valid <= 1'b1; @@ -524,7 +524,7 @@ always @(posedge clk) begin if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin input_data_d0 <= encoded_rx_data; input_data_crc <= encoded_rx_data; - end else if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_4)begin + end else if (encoded_rx_hdr == SYNC_CTRL && (encoded_rx_data[7:0] == BLOCK_TYPE_START_4 || encoded_rx_data[7:0] == BLOCK_TYPE_OS_START)) begin input_data_d0 <= {encoded_rx_data[31:0], swap_data}; input_data_crc <= {encoded_rx_data[31:0], swap_data}; end else if (lanes_swapped) begin From 585ccefa1534cba00ee915f54baf491a0b49df82 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 26 Mar 2019 12:42:08 -0700 Subject: [PATCH 535/617] Add TX underflow error signal --- rtl/axis_baser_tx_64.v | 11 +++++++++-- rtl/axis_gmii_tx.v | 9 ++++++++- rtl/axis_xgmii_tx_32.v | 9 ++++++++- rtl/axis_xgmii_tx_64.v | 9 ++++++++- rtl/eth_mac_10g.v | 4 +++- rtl/eth_mac_10g_fifo.v | 31 +++++++++++++++++++++++++++++++ rtl/eth_mac_1g.v | 4 +++- rtl/eth_mac_1g_fifo.v | 30 ++++++++++++++++++++++++++++++ rtl/eth_mac_1g_gmii.v | 2 ++ rtl/eth_mac_1g_gmii_fifo.v | 30 ++++++++++++++++++++++++++++++ rtl/eth_mac_1g_rgmii.v | 2 ++ rtl/eth_mac_1g_rgmii_fifo.v | 30 ++++++++++++++++++++++++++++++ rtl/eth_mac_phy_10g.v | 4 +++- rtl/eth_mac_phy_10g_fifo.v | 30 ++++++++++++++++++++++++++++++ rtl/eth_mac_phy_10g_tx.v | 6 ++++-- tb/test_axis_baser_tx_64.py | 2 ++ tb/test_axis_baser_tx_64.v | 7 +++++-- tb/test_axis_gmii_tx.py | 4 +++- tb/test_axis_gmii_tx.v | 7 +++++-- tb/test_axis_xgmii_tx_32.py | 4 +++- tb/test_axis_xgmii_tx_32.v | 7 +++++-- tb/test_axis_xgmii_tx_64.py | 4 +++- tb/test_axis_xgmii_tx_64.v | 7 +++++-- tb/test_eth_mac_10g_32.py | 2 ++ tb/test_eth_mac_10g_32.v | 3 +++ tb/test_eth_mac_10g_64.py | 2 ++ tb/test_eth_mac_10g_64.v | 3 +++ tb/test_eth_mac_10g_fifo_32.py | 2 ++ tb/test_eth_mac_10g_fifo_32.v | 3 +++ tb/test_eth_mac_10g_fifo_64.py | 2 ++ tb/test_eth_mac_10g_fifo_64.v | 3 +++ tb/test_eth_mac_1g.py | 2 ++ tb/test_eth_mac_1g.v | 3 +++ tb/test_eth_mac_1g_fifo.py | 2 ++ tb/test_eth_mac_1g_fifo.v | 3 +++ tb/test_eth_mac_1g_gmii.py | 2 ++ tb/test_eth_mac_1g_gmii.v | 3 +++ tb/test_eth_mac_1g_gmii_fifo.py | 2 ++ tb/test_eth_mac_1g_gmii_fifo.v | 3 +++ tb/test_eth_mac_1g_rgmii.py | 2 ++ tb/test_eth_mac_1g_rgmii.v | 3 +++ tb/test_eth_mac_1g_rgmii_fifo.py | 2 ++ tb/test_eth_mac_1g_rgmii_fifo.v | 3 +++ tb/test_eth_mac_phy_10g.py | 2 ++ tb/test_eth_mac_phy_10g.v | 3 +++ tb/test_eth_mac_phy_10g_fifo.py | 2 ++ tb/test_eth_mac_phy_10g_fifo.v | 3 +++ 47 files changed, 292 insertions(+), 21 deletions(-) diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v index 7bf1d2202..cd11407a1 100644 --- a/rtl/axis_baser_tx_64.v +++ b/rtl/axis_baser_tx_64.v @@ -67,7 +67,8 @@ module axis_baser_tx_64 # * Status */ output wire start_packet_0, - output wire start_packet_4 + output wire start_packet_4, + output wire error_underflow ); // bus width assertions @@ -211,6 +212,7 @@ reg [3:0] output_type_reg = OUTPUT_TYPE_IDLE, output_type_next; reg start_packet_0_reg = 1'b0, start_packet_0_next; reg start_packet_4_reg = 1'b0, start_packet_4_next; +reg error_underflow_reg = 1'b0, error_underflow_next; assign s_axis_tready = s_axis_tready_reg; @@ -219,6 +221,7 @@ assign encoded_tx_hdr = encoded_tx_hdr_reg; assign start_packet_0 = start_packet_0_reg; assign start_packet_4 = start_packet_4_reg; +assign error_underflow = error_underflow_reg; lfsr #( .LFSR_WIDTH(32), @@ -474,6 +477,7 @@ always @* begin start_packet_0_next = 1'b0; start_packet_4_next = 1'b0; + error_underflow_next = 1'b0; case (state_reg) STATE_IDLE: begin @@ -554,10 +558,11 @@ always @* begin state_next = STATE_PAYLOAD; end end else begin - // tvalid deassert, fail framec + // tvalid deassert, fail frame output_type_next = OUTPUT_TYPE_ERROR; frame_ptr_next = 16'd0; ifg_count_next = 8'd8; + error_underflow_next = 1'b1; state_next = STATE_WAIT_END; end end @@ -728,6 +733,7 @@ always @(posedge clk) begin start_packet_0_reg <= 1'b0; start_packet_4_reg <= 1'b0; + error_underflow_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; @@ -747,6 +753,7 @@ always @(posedge clk) begin start_packet_0_reg <= start_packet_0_next; start_packet_4_reg <= start_packet_4_next; + error_underflow_reg <= error_underflow_next; delay_type_valid <= 1'b0; diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index 8f0316c69..0acdab337 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -68,7 +68,8 @@ module axis_gmii_tx # /* * Status */ - output wire start_packet + output wire start_packet, + output wire error_underflow ); localparam [7:0] @@ -105,6 +106,7 @@ reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg start_packet_reg = 1'b0, start_packet_next; +reg error_underflow_reg = 1'b0, error_underflow_next; reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; @@ -116,6 +118,7 @@ assign gmii_tx_en = gmii_tx_en_reg; assign gmii_tx_er = gmii_tx_er_reg; assign start_packet = start_packet_reg; +assign error_underflow = error_underflow_reg; lfsr #( .LFSR_WIDTH(32), @@ -153,6 +156,7 @@ always @* begin gmii_tx_er_next = 1'b0; start_packet_next = 1'b0; + error_underflow_next = 1'b0; if (!clk_enable) begin // clock disabled - hold state and outputs @@ -243,6 +247,7 @@ always @* begin // tvalid deassert, fail frame gmii_tx_er_next = 1'b1; frame_ptr_next = 16'd0; + error_underflow_next = 1'b1; state_next = STATE_WAIT_END; end end @@ -364,6 +369,7 @@ always @(posedge clk) begin gmii_tx_er_reg <= 1'b0; start_packet_reg <= 1'b0; + error_underflow_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; end else begin @@ -377,6 +383,7 @@ always @(posedge clk) begin gmii_tx_er_reg <= gmii_tx_er_next; start_packet_reg <= start_packet_next; + error_underflow_reg <= error_underflow_next; // datapath if (reset_crc) begin diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index bdcda1cc0..ea2ac38fc 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -63,7 +63,8 @@ module axis_xgmii_tx_32 # /* * Status */ - output wire start_packet + output wire start_packet, + output wire error_underflow ); localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; @@ -129,6 +130,7 @@ reg [31:0] xgmii_txd_reg = {4{XGMII_IDLE}}, xgmii_txd_next; reg [3:0] xgmii_txc_reg = 4'b1111, xgmii_txc_next; reg start_packet_reg = 1'b0, start_packet_next; +reg error_underflow_reg = 1'b0, error_underflow_next; assign s_axis_tready = s_axis_tready_reg; @@ -136,6 +138,7 @@ assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; assign start_packet = start_packet_reg; +assign error_underflow = error_underflow_reg; lfsr #( .LFSR_WIDTH(32), @@ -288,6 +291,7 @@ always @* begin xgmii_txc_next = 4'b1111; start_packet_next = 1'b0; + error_underflow_next = 1'b0; case (state_reg) STATE_IDLE: begin @@ -376,6 +380,7 @@ always @* begin xgmii_txc_next = 4'b1111; frame_ptr_next = 16'd0; ifg_count_next = 8'd10; + error_underflow_next = 1'b1; state_next = STATE_WAIT_END; end end @@ -536,6 +541,7 @@ always @(posedge clk) begin xgmii_txc_reg <= 4'b1111; start_packet_reg <= 1'b0; + error_underflow_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; end else begin @@ -552,6 +558,7 @@ always @(posedge clk) begin xgmii_txc_reg <= xgmii_txc_next; start_packet_reg <= start_packet_next; + error_underflow_reg <= error_underflow_next; // datapath if (reset_crc) begin diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index 3f260133e..2d5816b1a 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -64,7 +64,8 @@ module axis_xgmii_tx_64 # * Status */ output wire start_packet_0, - output wire start_packet_4 + output wire start_packet_4, + output wire error_underflow ); localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; @@ -140,6 +141,7 @@ reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; reg start_packet_0_reg = 1'b0, start_packet_0_next; reg start_packet_4_reg = 1'b0, start_packet_4_next; +reg error_underflow_reg = 1'b0, error_underflow_next; assign s_axis_tready = s_axis_tready_reg; @@ -148,6 +150,7 @@ assign xgmii_txc = xgmii_txc_reg; assign start_packet_0 = start_packet_0_reg; assign start_packet_4 = start_packet_4_reg; +assign error_underflow = error_underflow_reg; lfsr #( .LFSR_WIDTH(32), @@ -404,6 +407,7 @@ always @* begin start_packet_0_next = 1'b0; start_packet_4_next = 1'b0; + error_underflow_next = 1'b0; case (state_reg) STATE_IDLE: begin @@ -491,6 +495,7 @@ always @* begin xgmii_txc_next = 8'b11111111; frame_ptr_next = 16'd0; ifg_count_next = 8'd8; + error_underflow_next = 1'b1; state_next = STATE_WAIT_END; end end @@ -658,6 +663,7 @@ always @(posedge clk) begin start_packet_0_reg <= 1'b0; start_packet_4_reg <= 1'b0; + error_underflow_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; @@ -674,6 +680,7 @@ always @(posedge clk) begin start_packet_0_reg <= start_packet_0_next; start_packet_4_reg <= start_packet_4_next; + error_underflow_reg <= error_underflow_next; if (swap_lanes || (lanes_swapped && !unswap_lanes)) begin lanes_swapped <= 1'b1; diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index 89f368744..8d3099d8a 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -76,6 +76,7 @@ module eth_mac_10g # */ output wire tx_start_packet_0, output wire tx_start_packet_4, + output wire tx_error_underflow, output wire rx_start_packet_0, output wire rx_start_packet_4, output wire rx_error_bad_frame, @@ -139,7 +140,8 @@ axis_xgmii_tx_inst ( .xgmii_txc(xgmii_txc), .ifg_delay(ifg_delay), .start_packet_0(tx_start_packet_0), - .start_packet_4(tx_start_packet_4) + .start_packet_4(tx_start_packet_4), + .error_underflow(tx_error_underflow) ); end else begin diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 207aad38b..05f57b1d8 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -85,6 +85,7 @@ module eth_mac_10g_fifo # /* * Status */ + output wire tx_error_underflow, output wire tx_fifo_overflow, output wire tx_fifo_bad_frame, output wire tx_fifo_good_frame, @@ -114,6 +115,35 @@ wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain +wire tx_error_underflow_int; + +reg tx_sync_reg_1 = 1'b0; +reg tx_sync_reg_2 = 1'b0; +reg tx_sync_reg_3 = 1'b0; +reg tx_sync_reg_4 = 1'b0; + +assign tx_error_underflow = tx_sync_reg_3 ^ tx_sync_reg_4; + +always @(posedge tx_clk or posedge tx_rst) begin + if (tx_rst) begin + tx_sync_reg_1 <= 1'b0; + end else begin + tx_sync_reg_1 <= tx_sync_reg_1 ^ {tx_error_underflow_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + tx_sync_reg_2 <= 1'b0; + tx_sync_reg_3 <= 1'b0; + tx_sync_reg_4 <= 1'b0; + end else begin + tx_sync_reg_2 <= tx_sync_reg_1; + tx_sync_reg_3 <= tx_sync_reg_2; + tx_sync_reg_4 <= tx_sync_reg_3; + end +end + wire rx_error_bad_frame_int; wire rx_error_bad_fcs_int; @@ -173,6 +203,7 @@ eth_mac_10g_inst ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .tx_error_underflow(tx_error_underflow_int), .rx_error_bad_frame(rx_error_bad_frame_int), .rx_error_bad_fcs(rx_error_bad_fcs_int), .ifg_delay(ifg_delay) diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v index 727406cc3..1a37ff5c8 100644 --- a/rtl/eth_mac_1g.v +++ b/rtl/eth_mac_1g.v @@ -79,6 +79,7 @@ module eth_mac_1g # * Status */ output wire tx_start_packet, + output wire tx_error_underflow, output wire rx_start_packet, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, @@ -125,7 +126,8 @@ axis_gmii_tx_inst ( .clk_enable(tx_clk_enable), .mii_select(tx_mii_select), .ifg_delay(ifg_delay), - .start_packet(tx_start_packet) + .start_packet(tx_start_packet), + .error_underflow(tx_error_underflow) ); endmodule diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index b80fd95f1..bda92a892 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -89,6 +89,7 @@ module eth_mac_1g_fifo # /* * Status */ + output wire tx_error_underflow, output wire tx_fifo_overflow, output wire tx_fifo_bad_frame, output wire tx_fifo_good_frame, @@ -116,6 +117,35 @@ wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain +wire tx_error_underflow_int; + +reg tx_sync_reg_1 = 1'b0; +reg tx_sync_reg_2 = 1'b0; +reg tx_sync_reg_3 = 1'b0; +reg tx_sync_reg_4 = 1'b0; + +assign tx_error_underflow = tx_sync_reg_3 ^ tx_sync_reg_4; + +always @(posedge tx_clk or posedge tx_rst) begin + if (tx_rst) begin + tx_sync_reg_1 <= 1'b0; + end else begin + tx_sync_reg_1 <= tx_sync_reg_1 ^ {tx_error_underflow_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + tx_sync_reg_2 <= 1'b0; + tx_sync_reg_3 <= 1'b0; + tx_sync_reg_4 <= 1'b0; + end else begin + tx_sync_reg_2 <= tx_sync_reg_1; + tx_sync_reg_3 <= tx_sync_reg_2; + tx_sync_reg_4 <= tx_sync_reg_3; + end +end + wire rx_error_bad_frame_int; wire rx_error_bad_fcs_int; diff --git a/rtl/eth_mac_1g_gmii.v b/rtl/eth_mac_1g_gmii.v index c0f4ed4d7..8e5d7ff62 100644 --- a/rtl/eth_mac_1g_gmii.v +++ b/rtl/eth_mac_1g_gmii.v @@ -86,6 +86,7 @@ module eth_mac_1g_gmii # /* * Status */ + output wire tx_error_underflow, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, output wire [1:0] speed, @@ -244,6 +245,7 @@ eth_mac_1g_inst ( .tx_clk_enable(1'b1), .rx_mii_select(rx_mii_select_3), .tx_mii_select(tx_mii_select_3), + .tx_error_underflow(tx_error_underflow), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .ifg_delay(ifg_delay) diff --git a/rtl/eth_mac_1g_gmii_fifo.v b/rtl/eth_mac_1g_gmii_fifo.v index 17d4ae35b..a7c8387eb 100644 --- a/rtl/eth_mac_1g_gmii_fifo.v +++ b/rtl/eth_mac_1g_gmii_fifo.v @@ -93,6 +93,7 @@ module eth_mac_1g_gmii_fifo # /* * Status */ + output wire tx_error_underflow, output wire tx_fifo_overflow, output wire tx_fifo_bad_frame, output wire tx_fifo_good_frame, @@ -126,6 +127,35 @@ wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain +wire tx_error_underflow_int; + +reg tx_sync_reg_1 = 1'b0; +reg tx_sync_reg_2 = 1'b0; +reg tx_sync_reg_3 = 1'b0; +reg tx_sync_reg_4 = 1'b0; + +assign tx_error_underflow = tx_sync_reg_3 ^ tx_sync_reg_4; + +always @(posedge tx_clk or posedge tx_rst) begin + if (tx_rst) begin + tx_sync_reg_1 <= 1'b0; + end else begin + tx_sync_reg_1 <= tx_sync_reg_1 ^ {tx_error_underflow_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + tx_sync_reg_2 <= 1'b0; + tx_sync_reg_3 <= 1'b0; + tx_sync_reg_4 <= 1'b0; + end else begin + tx_sync_reg_2 <= tx_sync_reg_1; + tx_sync_reg_3 <= tx_sync_reg_2; + tx_sync_reg_4 <= tx_sync_reg_3; + end +end + wire rx_error_bad_frame_int; wire rx_error_bad_fcs_int; diff --git a/rtl/eth_mac_1g_rgmii.v b/rtl/eth_mac_1g_rgmii.v index e1b01902c..48facacef 100644 --- a/rtl/eth_mac_1g_rgmii.v +++ b/rtl/eth_mac_1g_rgmii.v @@ -86,6 +86,7 @@ module eth_mac_1g_rgmii # /* * Status */ + output wire tx_error_underflow, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, output wire [1:0] speed, @@ -245,6 +246,7 @@ eth_mac_1g_inst ( .tx_clk_enable(mac_gmii_tx_clk_en), .rx_mii_select(rx_mii_select_3), .tx_mii_select(tx_mii_select_3), + .tx_error_underflow(tx_error_underflow), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .ifg_delay(ifg_delay) diff --git a/rtl/eth_mac_1g_rgmii_fifo.v b/rtl/eth_mac_1g_rgmii_fifo.v index 2298d52d5..88041ae6c 100644 --- a/rtl/eth_mac_1g_rgmii_fifo.v +++ b/rtl/eth_mac_1g_rgmii_fifo.v @@ -93,6 +93,7 @@ module eth_mac_1g_rgmii_fifo # /* * Status */ + output wire tx_error_underflow, output wire tx_fifo_overflow, output wire tx_fifo_bad_frame, output wire tx_fifo_good_frame, @@ -126,6 +127,35 @@ wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain +wire tx_error_underflow_int; + +reg tx_sync_reg_1 = 1'b0; +reg tx_sync_reg_2 = 1'b0; +reg tx_sync_reg_3 = 1'b0; +reg tx_sync_reg_4 = 1'b0; + +assign tx_error_underflow = tx_sync_reg_3 ^ tx_sync_reg_4; + +always @(posedge tx_clk or posedge tx_rst) begin + if (tx_rst) begin + tx_sync_reg_1 <= 1'b0; + end else begin + tx_sync_reg_1 <= tx_sync_reg_1 ^ {tx_error_underflow_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + tx_sync_reg_2 <= 1'b0; + tx_sync_reg_3 <= 1'b0; + tx_sync_reg_4 <= 1'b0; + end else begin + tx_sync_reg_2 <= tx_sync_reg_1; + tx_sync_reg_3 <= tx_sync_reg_2; + tx_sync_reg_4 <= tx_sync_reg_3; + end +end + wire rx_error_bad_frame_int; wire rx_error_bad_fcs_int; diff --git a/rtl/eth_mac_phy_10g.v b/rtl/eth_mac_phy_10g.v index 672f09a9d..a06da75f8 100644 --- a/rtl/eth_mac_phy_10g.v +++ b/rtl/eth_mac_phy_10g.v @@ -82,6 +82,7 @@ module eth_mac_phy_10g # */ output wire tx_start_packet_0, output wire tx_start_packet_4, + output wire tx_error_underflow, output wire rx_start_packet_0, output wire rx_start_packet_4, output wire rx_error_bad_frame, @@ -148,7 +149,8 @@ eth_mac_phy_10g_tx_inst ( .serdes_tx_hdr(serdes_tx_hdr), .ifg_delay(ifg_delay), .tx_start_packet_0(tx_start_packet_0), - .tx_start_packet_4(tx_start_packet_4) + .tx_start_packet_4(tx_start_packet_4), + .tx_error_underflow(tx_error_underflow) ); endmodule diff --git a/rtl/eth_mac_phy_10g_fifo.v b/rtl/eth_mac_phy_10g_fifo.v index e19f89817..c8dc0b9c7 100644 --- a/rtl/eth_mac_phy_10g_fifo.v +++ b/rtl/eth_mac_phy_10g_fifo.v @@ -91,6 +91,7 @@ module eth_mac_phy_10g_fifo # /* * Status */ + output wire tx_error_underflow, output wire tx_fifo_overflow, output wire tx_fifo_bad_frame, output wire tx_fifo_good_frame, @@ -122,6 +123,35 @@ wire rx_fifo_axis_tlast; wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain +wire tx_error_underflow_int; + +reg tx_sync_reg_1 = 1'b0; +reg tx_sync_reg_2 = 1'b0; +reg tx_sync_reg_3 = 1'b0; +reg tx_sync_reg_4 = 1'b0; + +assign tx_error_underflow = tx_sync_reg_3 ^ tx_sync_reg_4; + +always @(posedge tx_clk or posedge tx_rst) begin + if (tx_rst) begin + tx_sync_reg_1 <= 1'b0; + end else begin + tx_sync_reg_1 <= tx_sync_reg_1 ^ {tx_error_underflow_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + tx_sync_reg_2 <= 1'b0; + tx_sync_reg_3 <= 1'b0; + tx_sync_reg_4 <= 1'b0; + end else begin + tx_sync_reg_2 <= tx_sync_reg_1; + tx_sync_reg_3 <= tx_sync_reg_2; + tx_sync_reg_4 <= tx_sync_reg_3; + end +end + wire rx_error_bad_frame_int; wire rx_error_bad_fcs_int; diff --git a/rtl/eth_mac_phy_10g_tx.v b/rtl/eth_mac_phy_10g_tx.v index 7c4d2032e..cc5b119dc 100644 --- a/rtl/eth_mac_phy_10g_tx.v +++ b/rtl/eth_mac_phy_10g_tx.v @@ -70,7 +70,8 @@ module eth_mac_phy_10g_tx # * Status */ output wire tx_start_packet_0, - output wire tx_start_packet_4 + output wire tx_start_packet_4, + output wire tx_error_underflow ); // bus width assertions @@ -115,7 +116,8 @@ axis_baser_tx_inst ( .encoded_tx_hdr(encoded_tx_hdr), .ifg_delay(ifg_delay), .start_packet_0(tx_start_packet_0), - .start_packet_4(tx_start_packet_4) + .start_packet_4(tx_start_packet_4), + .error_underflow(tx_error_underflow) ); reg [57:0] tx_scrambler_state_reg = {58{1'b1}}; diff --git a/tb/test_axis_baser_tx_64.py b/tb/test_axis_baser_tx_64.py index e64be4945..f1e7d762a 100755 --- a/tb/test_axis_baser_tx_64.py +++ b/tb/test_axis_baser_tx_64.py @@ -71,6 +71,7 @@ def bench(): encoded_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) start_packet_0 = Signal(bool(0)) start_packet_4 = Signal(bool(0)) + error_underflow = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -120,6 +121,7 @@ def bench(): ifg_delay=ifg_delay, start_packet_0=start_packet_0, start_packet_4=start_packet_4, + error_underflow=error_underflow ) @always(delay(4)) diff --git a/tb/test_axis_baser_tx_64.v b/tb/test_axis_baser_tx_64.v index efa195259..bd7477599 100644 --- a/tb/test_axis_baser_tx_64.v +++ b/tb/test_axis_baser_tx_64.v @@ -57,6 +57,7 @@ wire [DATA_WIDTH-1:0] encoded_tx_data; wire [HDR_WIDTH-1:0] encoded_tx_hdr; wire start_packet_0; wire start_packet_4; +wire error_underflow; initial begin // myhdl integration @@ -76,7 +77,8 @@ initial begin encoded_tx_data, encoded_tx_hdr, start_packet_0, - start_packet_4 + start_packet_4, + error_underflow ); // dump file @@ -105,7 +107,8 @@ UUT ( .encoded_tx_hdr(encoded_tx_hdr), .ifg_delay(ifg_delay), .start_packet_0(start_packet_0), - .start_packet_4(start_packet_4) + .start_packet_4(start_packet_4), + .error_underflow(error_underflow) ); endmodule diff --git a/tb/test_axis_gmii_tx.py b/tb/test_axis_gmii_tx.py index aa36f80f1..f0cd1b5b6 100755 --- a/tb/test_axis_gmii_tx.py +++ b/tb/test_axis_gmii_tx.py @@ -68,6 +68,7 @@ def bench(): gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) start_packet = Signal(bool(0)) + error_underflow = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -124,7 +125,8 @@ def bench(): ifg_delay=ifg_delay, - start_packet=start_packet + start_packet=start_packet, + error_underflow=error_underflow ) @always(delay(4)) diff --git a/tb/test_axis_gmii_tx.v b/tb/test_axis_gmii_tx.v index e15d19467..99d702451 100644 --- a/tb/test_axis_gmii_tx.v +++ b/tb/test_axis_gmii_tx.v @@ -54,6 +54,7 @@ wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; wire start_packet; +wire error_underflow; initial begin // myhdl integration @@ -74,7 +75,8 @@ initial begin gmii_txd, gmii_tx_en, gmii_tx_er, - start_packet + start_packet, + error_underflow ); // dump file @@ -100,7 +102,8 @@ UUT ( .clk_enable(clk_enable), .mii_select(mii_select), .ifg_delay(ifg_delay), - .start_packet(start_packet) + .start_packet(start_packet), + .error_underflow(error_underflow) ); endmodule diff --git a/tb/test_axis_xgmii_tx_32.py b/tb/test_axis_xgmii_tx_32.py index 86fa63b9e..9fca431b5 100755 --- a/tb/test_axis_xgmii_tx_32.py +++ b/tb/test_axis_xgmii_tx_32.py @@ -66,6 +66,7 @@ def bench(): xgmii_txd = Signal(intbv(0x07070707)[32:]) xgmii_txc = Signal(intbv(0xf)[4:]) start_packet = Signal(bool(0)) + error_underflow = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -117,7 +118,8 @@ def bench(): ifg_delay=ifg_delay, - start_packet=start_packet + start_packet=start_packet, + error_underflow=error_underflow ) @always(delay(4)) diff --git a/tb/test_axis_xgmii_tx_32.v b/tb/test_axis_xgmii_tx_32.v index aa783804d..244bc341d 100644 --- a/tb/test_axis_xgmii_tx_32.v +++ b/tb/test_axis_xgmii_tx_32.v @@ -52,6 +52,7 @@ wire s_axis_tready; wire [31:0] xgmii_txd; wire [3:0] xgmii_txc; wire start_packet; +wire error_underflow; initial begin // myhdl integration @@ -70,7 +71,8 @@ initial begin s_axis_tready, xgmii_txd, xgmii_txc, - start_packet + start_packet, + error_underflow ); // dump file @@ -94,7 +96,8 @@ UUT ( .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), .ifg_delay(ifg_delay), - .start_packet(start_packet) + .start_packet(start_packet), + .error_underflow(error_underflow) ); endmodule diff --git a/tb/test_axis_xgmii_tx_64.py b/tb/test_axis_xgmii_tx_64.py index e4b7ee3ed..ce183cdc8 100755 --- a/tb/test_axis_xgmii_tx_64.py +++ b/tb/test_axis_xgmii_tx_64.py @@ -67,6 +67,7 @@ def bench(): xgmii_txc = Signal(intbv(0xff)[8:]) start_packet_0 = Signal(bool(0)) start_packet_4 = Signal(bool(0)) + error_underflow = Signal(bool(0)) # sources and sinks source_pause = Signal(bool(0)) @@ -119,7 +120,8 @@ def bench(): ifg_delay=ifg_delay, start_packet_0=start_packet_0, - start_packet_4=start_packet_4 + start_packet_4=start_packet_4, + error_underflow=error_underflow ) @always(delay(4)) diff --git a/tb/test_axis_xgmii_tx_64.v b/tb/test_axis_xgmii_tx_64.v index 6ac8654c2..26597295c 100644 --- a/tb/test_axis_xgmii_tx_64.v +++ b/tb/test_axis_xgmii_tx_64.v @@ -53,6 +53,7 @@ wire [63:0] xgmii_txd; wire [7:0] xgmii_txc; wire start_packet_0; wire start_packet_4; +wire error_underflow; initial begin // myhdl integration @@ -72,7 +73,8 @@ initial begin xgmii_txd, xgmii_txc, start_packet_0, - start_packet_4 + start_packet_4, + error_underflow ); // dump file @@ -97,7 +99,8 @@ UUT ( .xgmii_txc(xgmii_txc), .ifg_delay(ifg_delay), .start_packet_0(start_packet_0), - .start_packet_4(start_packet_4) + .start_packet_4(start_packet_4), + .error_underflow(error_underflow) ); endmodule diff --git a/tb/test_eth_mac_10g_32.py b/tb/test_eth_mac_10g_32.py index 305db04a6..1866379d0 100755 --- a/tb/test_eth_mac_10g_32.py +++ b/tb/test_eth_mac_10g_32.py @@ -84,6 +84,7 @@ def bench(): xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) tx_start_packet_0 = Signal(bool(0)) tx_start_packet_4 = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) rx_start_packet_0 = Signal(bool(0)) rx_start_packet_4 = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) @@ -176,6 +177,7 @@ def bench(): tx_start_packet_0=tx_start_packet_0, tx_start_packet_4=tx_start_packet_4, + tx_error_underflow=tx_error_underflow, rx_start_packet_0=rx_start_packet_0, rx_start_packet_4=rx_start_packet_4, rx_error_bad_frame=rx_error_bad_frame, diff --git a/tb/test_eth_mac_10g_32.v b/tb/test_eth_mac_10g_32.v index 351cf9f44..608dc0243 100644 --- a/tb/test_eth_mac_10g_32.v +++ b/tb/test_eth_mac_10g_32.v @@ -68,6 +68,7 @@ wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; wire tx_start_packet_0; wire tx_start_packet_4; +wire tx_error_underflow; wire rx_start_packet_0; wire rx_start_packet_4; wire rx_error_bad_frame; @@ -103,6 +104,7 @@ initial begin xgmii_txc, tx_start_packet_0, tx_start_packet_4, + tx_error_underflow, rx_start_packet_0, rx_start_packet_4, rx_error_bad_frame, @@ -144,6 +146,7 @@ UUT ( .xgmii_txc(xgmii_txc), .tx_start_packet_0(tx_start_packet_0), .tx_start_packet_4(tx_start_packet_4), + .tx_error_underflow(tx_error_underflow), .rx_start_packet_0(rx_start_packet_0), .rx_start_packet_4(rx_start_packet_4), .rx_error_bad_frame(rx_error_bad_frame), diff --git a/tb/test_eth_mac_10g_64.py b/tb/test_eth_mac_10g_64.py index 6dbd63b26..aa0a731b4 100755 --- a/tb/test_eth_mac_10g_64.py +++ b/tb/test_eth_mac_10g_64.py @@ -84,6 +84,7 @@ def bench(): xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) tx_start_packet_0 = Signal(bool(0)) tx_start_packet_4 = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) rx_start_packet_0 = Signal(bool(0)) rx_start_packet_4 = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) @@ -176,6 +177,7 @@ def bench(): tx_start_packet_0=tx_start_packet_0, tx_start_packet_4=tx_start_packet_4, + tx_error_underflow=tx_error_underflow, rx_start_packet_0=rx_start_packet_0, rx_start_packet_4=rx_start_packet_4, rx_error_bad_frame=rx_error_bad_frame, diff --git a/tb/test_eth_mac_10g_64.v b/tb/test_eth_mac_10g_64.v index 6713d0564..50a164f5d 100644 --- a/tb/test_eth_mac_10g_64.v +++ b/tb/test_eth_mac_10g_64.v @@ -68,6 +68,7 @@ wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; wire tx_start_packet_0; wire tx_start_packet_4; +wire tx_error_underflow; wire rx_start_packet_0; wire rx_start_packet_4; wire rx_error_bad_frame; @@ -103,6 +104,7 @@ initial begin xgmii_txc, tx_start_packet_0, tx_start_packet_4, + tx_error_underflow, rx_start_packet_0, rx_start_packet_4, rx_error_bad_frame, @@ -144,6 +146,7 @@ UUT ( .xgmii_txc(xgmii_txc), .tx_start_packet_0(tx_start_packet_0), .tx_start_packet_4(tx_start_packet_4), + .tx_error_underflow(tx_error_underflow), .rx_start_packet_0(rx_start_packet_0), .rx_start_packet_4(rx_start_packet_4), .rx_error_bad_frame(rx_error_bad_frame), diff --git a/tb/test_eth_mac_10g_fifo_32.py b/tb/test_eth_mac_10g_fifo_32.py index c68537a69..0488c8a3b 100755 --- a/tb/test_eth_mac_10g_fifo_32.py +++ b/tb/test_eth_mac_10g_fifo_32.py @@ -89,6 +89,7 @@ def bench(): rx_axis_tuser = Signal(bool(0)) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_error_underflow = Signal(bool(0)) tx_fifo_overflow = Signal(bool(0)) tx_fifo_bad_frame = Signal(bool(0)) tx_fifo_good_frame = Signal(bool(0)) @@ -189,6 +190,7 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + tx_error_underflow=tx_error_underflow, tx_fifo_overflow=tx_fifo_overflow, tx_fifo_bad_frame=tx_fifo_bad_frame, tx_fifo_good_frame=tx_fifo_good_frame, diff --git a/tb/test_eth_mac_10g_fifo_32.v b/tb/test_eth_mac_10g_fifo_32.v index f83c68933..02592b069 100644 --- a/tb/test_eth_mac_10g_fifo_32.v +++ b/tb/test_eth_mac_10g_fifo_32.v @@ -71,6 +71,7 @@ wire rx_axis_tlast; wire rx_axis_tuser; wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; +wire tx_error_underflow; wire tx_fifo_overflow; wire tx_fifo_bad_frame; wire tx_fifo_good_frame; @@ -111,6 +112,7 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, + tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, @@ -159,6 +161,7 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .tx_error_underflow(tx_error_underflow), .tx_fifo_overflow(tx_fifo_overflow), .tx_fifo_bad_frame(tx_fifo_bad_frame), .tx_fifo_good_frame(tx_fifo_good_frame), diff --git a/tb/test_eth_mac_10g_fifo_64.py b/tb/test_eth_mac_10g_fifo_64.py index 6d954097e..714028664 100755 --- a/tb/test_eth_mac_10g_fifo_64.py +++ b/tb/test_eth_mac_10g_fifo_64.py @@ -89,6 +89,7 @@ def bench(): rx_axis_tuser = Signal(bool(0)) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_error_underflow = Signal(bool(0)) tx_fifo_overflow = Signal(bool(0)) tx_fifo_bad_frame = Signal(bool(0)) tx_fifo_good_frame = Signal(bool(0)) @@ -189,6 +190,7 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + tx_error_underflow=tx_error_underflow, tx_fifo_overflow=tx_fifo_overflow, tx_fifo_bad_frame=tx_fifo_bad_frame, tx_fifo_good_frame=tx_fifo_good_frame, diff --git a/tb/test_eth_mac_10g_fifo_64.v b/tb/test_eth_mac_10g_fifo_64.v index cf87b62c3..c035ceb07 100644 --- a/tb/test_eth_mac_10g_fifo_64.v +++ b/tb/test_eth_mac_10g_fifo_64.v @@ -71,6 +71,7 @@ wire rx_axis_tlast; wire rx_axis_tuser; wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; +wire tx_error_underflow; wire tx_fifo_overflow; wire tx_fifo_bad_frame; wire tx_fifo_good_frame; @@ -111,6 +112,7 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, + tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, @@ -159,6 +161,7 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .tx_error_underflow(tx_error_underflow), .tx_fifo_overflow(tx_fifo_overflow), .tx_fifo_bad_frame(tx_fifo_bad_frame), .tx_fifo_good_frame(tx_fifo_good_frame), diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index 285c373df..b1cd8816c 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -83,6 +83,7 @@ def bench(): gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) tx_start_packet = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) rx_start_packet = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) @@ -183,6 +184,7 @@ def bench(): tx_mii_select=tx_mii_select, tx_start_packet=tx_start_packet, + tx_error_underflow=tx_error_underflow, rx_start_packet=rx_start_packet, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, diff --git a/tb/test_eth_mac_1g.v b/tb/test_eth_mac_1g.v index 12502af4e..4f92c1e78 100644 --- a/tb/test_eth_mac_1g.v +++ b/tb/test_eth_mac_1g.v @@ -67,6 +67,7 @@ wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; wire tx_start_packet; +wire tx_error_underflow; wire rx_start_packet; wire rx_error_bad_frame; wire rx_error_bad_fcs; @@ -104,6 +105,7 @@ initial begin gmii_tx_en, gmii_tx_er, tx_start_packet, + tx_error_underflow, rx_start_packet, rx_error_bad_frame, rx_error_bad_fcs @@ -143,6 +145,7 @@ UUT ( .rx_mii_select(rx_mii_select), .tx_mii_select(tx_mii_select), .tx_start_packet(tx_start_packet), + .tx_error_underflow(tx_error_underflow), .rx_start_packet(rx_start_packet), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), diff --git a/tb/test_eth_mac_1g_fifo.py b/tb/test_eth_mac_1g_fifo.py index bd3f6da08..df1fecebb 100755 --- a/tb/test_eth_mac_1g_fifo.py +++ b/tb/test_eth_mac_1g_fifo.py @@ -89,6 +89,7 @@ def bench(): gmii_txd = Signal(intbv(0)[8:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) tx_fifo_overflow = Signal(bool(0)) tx_fifo_bad_frame = Signal(bool(0)) tx_fifo_good_frame = Signal(bool(0)) @@ -199,6 +200,7 @@ def bench(): rx_mii_select=rx_mii_select, tx_mii_select=tx_mii_select, + tx_error_underflow=tx_error_underflow, tx_fifo_overflow=tx_fifo_overflow, tx_fifo_bad_frame=tx_fifo_bad_frame, tx_fifo_good_frame=tx_fifo_good_frame, diff --git a/tb/test_eth_mac_1g_fifo.v b/tb/test_eth_mac_1g_fifo.v index 0b20f9235..ea7e9ccae 100644 --- a/tb/test_eth_mac_1g_fifo.v +++ b/tb/test_eth_mac_1g_fifo.v @@ -71,6 +71,7 @@ wire rx_axis_tuser; wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; +wire tx_error_underflow; wire tx_fifo_overflow; wire tx_fifo_bad_frame; wire tx_fifo_good_frame; @@ -115,6 +116,7 @@ initial begin gmii_txd, gmii_tx_en, gmii_tx_er, + tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, @@ -163,6 +165,7 @@ UUT ( .tx_clk_enable(tx_clk_enable), .rx_mii_select(rx_mii_select), .tx_mii_select(tx_mii_select), + .tx_error_underflow(tx_error_underflow), .tx_fifo_overflow(tx_fifo_overflow), .tx_fifo_bad_frame(tx_fifo_bad_frame), .tx_fifo_good_frame(tx_fifo_good_frame), diff --git a/tb/test_eth_mac_1g_gmii.py b/tb/test_eth_mac_1g_gmii.py index 0949654a2..d21f1335f 100755 --- a/tb/test_eth_mac_1g_gmii.py +++ b/tb/test_eth_mac_1g_gmii.py @@ -91,6 +91,7 @@ def bench(): gmii_txd = Signal(intbv(0)[8:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) speed = Signal(intbv(0)[2:]) @@ -190,6 +191,7 @@ def bench(): gmii_tx_en=gmii_tx_en, gmii_tx_er=gmii_tx_er, + tx_error_underflow=tx_error_underflow, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, speed=speed, diff --git a/tb/test_eth_mac_1g_gmii.v b/tb/test_eth_mac_1g_gmii.v index 1a14270fc..660bd6dba 100644 --- a/tb/test_eth_mac_1g_gmii.v +++ b/tb/test_eth_mac_1g_gmii.v @@ -70,6 +70,7 @@ wire gmii_tx_clk; wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; +wire tx_error_underflow; wire rx_error_bad_frame; wire rx_error_bad_fcs; wire [1:0] speed; @@ -107,6 +108,7 @@ initial begin gmii_txd, gmii_tx_en, gmii_tx_er, + tx_error_underflow, rx_error_bad_frame, rx_error_bad_fcs, speed @@ -149,6 +151,7 @@ UUT ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .tx_error_underflow(tx_error_underflow), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .speed(speed), diff --git a/tb/test_eth_mac_1g_gmii_fifo.py b/tb/test_eth_mac_1g_gmii_fifo.py index b62c5ed6f..fef5f1447 100755 --- a/tb/test_eth_mac_1g_gmii_fifo.py +++ b/tb/test_eth_mac_1g_gmii_fifo.py @@ -94,6 +94,7 @@ def bench(): gmii_txd = Signal(intbv(0)[8:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) tx_fifo_overflow = Signal(bool(0)) tx_fifo_bad_frame = Signal(bool(0)) tx_fifo_good_frame = Signal(bool(0)) @@ -200,6 +201,7 @@ def bench(): gmii_tx_en=gmii_tx_en, gmii_tx_er=gmii_tx_er, + tx_error_underflow=tx_error_underflow, tx_fifo_overflow=tx_fifo_overflow, tx_fifo_bad_frame=tx_fifo_bad_frame, tx_fifo_good_frame=tx_fifo_good_frame, diff --git a/tb/test_eth_mac_1g_gmii_fifo.v b/tb/test_eth_mac_1g_gmii_fifo.v index 04da01928..6c60bba76 100644 --- a/tb/test_eth_mac_1g_gmii_fifo.v +++ b/tb/test_eth_mac_1g_gmii_fifo.v @@ -71,6 +71,7 @@ wire gmii_tx_clk; wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; +wire tx_error_underflow; wire tx_fifo_overflow; wire tx_fifo_bad_frame; wire tx_fifo_good_frame; @@ -113,6 +114,7 @@ initial begin gmii_txd, gmii_tx_en, gmii_tx_er, + tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, @@ -162,6 +164,7 @@ UUT ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .tx_error_underflow(tx_error_underflow), .tx_fifo_overflow(tx_fifo_overflow), .tx_fifo_bad_frame(tx_fifo_bad_frame), .tx_fifo_good_frame(tx_fifo_good_frame), diff --git a/tb/test_eth_mac_1g_rgmii.py b/tb/test_eth_mac_1g_rgmii.py index ba777e133..e84460f64 100755 --- a/tb/test_eth_mac_1g_rgmii.py +++ b/tb/test_eth_mac_1g_rgmii.py @@ -91,6 +91,7 @@ def bench(): rgmii_tx_clk = Signal(bool(0)) rgmii_txd = Signal(intbv(0)[4:]) rgmii_tx_ctl = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) speed = Signal(intbv(0)[2:]) @@ -186,6 +187,7 @@ def bench(): rgmii_txd=rgmii_txd, rgmii_tx_ctl=rgmii_tx_ctl, + tx_error_underflow=tx_error_underflow, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, speed=speed, diff --git a/tb/test_eth_mac_1g_rgmii.v b/tb/test_eth_mac_1g_rgmii.v index 918acf721..0313fa09f 100644 --- a/tb/test_eth_mac_1g_rgmii.v +++ b/tb/test_eth_mac_1g_rgmii.v @@ -69,6 +69,7 @@ wire rx_axis_tuser; wire rgmii_tx_clk; wire [3:0] rgmii_txd; wire rgmii_tx_ctl; +wire tx_error_underflow; wire rx_error_bad_frame; wire rx_error_bad_fcs; wire [1:0] speed; @@ -104,6 +105,7 @@ initial begin rgmii_tx_clk, rgmii_txd, rgmii_tx_ctl, + tx_error_underflow, rx_error_bad_frame, rx_error_bad_fcs, speed @@ -145,6 +147,7 @@ UUT ( .rgmii_tx_clk(rgmii_tx_clk), .rgmii_txd(rgmii_txd), .rgmii_tx_ctl(rgmii_tx_ctl), + .tx_error_underflow(tx_error_underflow), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .speed(speed), diff --git a/tb/test_eth_mac_1g_rgmii_fifo.py b/tb/test_eth_mac_1g_rgmii_fifo.py index 764e49b95..2840402da 100755 --- a/tb/test_eth_mac_1g_rgmii_fifo.py +++ b/tb/test_eth_mac_1g_rgmii_fifo.py @@ -92,6 +92,7 @@ def bench(): rgmii_tx_clk = Signal(bool(0)) rgmii_txd = Signal(intbv(0)[4:]) rgmii_tx_ctl = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) tx_fifo_overflow = Signal(bool(0)) tx_fifo_bad_frame = Signal(bool(0)) tx_fifo_good_frame = Signal(bool(0)) @@ -194,6 +195,7 @@ def bench(): rgmii_txd=rgmii_txd, rgmii_tx_ctl=rgmii_tx_ctl, + tx_error_underflow=tx_error_underflow, tx_fifo_overflow=tx_fifo_overflow, tx_fifo_bad_frame=tx_fifo_bad_frame, tx_fifo_good_frame=tx_fifo_good_frame, diff --git a/tb/test_eth_mac_1g_rgmii_fifo.v b/tb/test_eth_mac_1g_rgmii_fifo.v index 7664454ca..e141b3c27 100644 --- a/tb/test_eth_mac_1g_rgmii_fifo.v +++ b/tb/test_eth_mac_1g_rgmii_fifo.v @@ -70,6 +70,7 @@ wire rx_axis_tuser; wire rgmii_tx_clk; wire [3:0] rgmii_txd; wire rgmii_tx_ctl; +wire tx_error_underflow; wire tx_fifo_overflow; wire tx_fifo_bad_frame; wire tx_fifo_good_frame; @@ -110,6 +111,7 @@ initial begin rgmii_tx_clk, rgmii_txd, rgmii_tx_ctl, + tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, @@ -158,6 +160,7 @@ UUT ( .rgmii_tx_clk(rgmii_tx_clk), .rgmii_txd(rgmii_txd), .rgmii_tx_ctl(rgmii_tx_ctl), + .tx_error_underflow(tx_error_underflow), .tx_fifo_overflow(tx_fifo_overflow), .tx_fifo_bad_frame(tx_fifo_bad_frame), .tx_fifo_good_frame(tx_fifo_good_frame), diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py index 0eda4e24e..f9650fbdb 100755 --- a/tb/test_eth_mac_phy_10g.py +++ b/tb/test_eth_mac_phy_10g.py @@ -98,6 +98,7 @@ def bench(): serdes_rx_bitslip = Signal(bool(0)) tx_start_packet_0 = Signal(bool(0)) tx_start_packet_4 = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) rx_start_packet_0 = Signal(bool(0)) rx_start_packet_4 = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) @@ -185,6 +186,7 @@ def bench(): serdes_rx_bitslip=serdes_rx_bitslip, tx_start_packet_0=tx_start_packet_0, tx_start_packet_4=tx_start_packet_4, + tx_error_underflow=tx_error_underflow, rx_start_packet_0=rx_start_packet_0, rx_start_packet_4=rx_start_packet_4, rx_error_bad_frame=rx_error_bad_frame, diff --git a/tb/test_eth_mac_phy_10g.v b/tb/test_eth_mac_phy_10g.v index 2937762bc..825302e1a 100644 --- a/tb/test_eth_mac_phy_10g.v +++ b/tb/test_eth_mac_phy_10g.v @@ -74,6 +74,7 @@ wire [HDR_WIDTH-1:0] serdes_tx_hdr; wire serdes_rx_bitslip; wire tx_start_packet_0; wire tx_start_packet_4; +wire tx_error_underflow; wire rx_start_packet_0; wire rx_start_packet_4; wire rx_error_bad_frame; @@ -112,6 +113,7 @@ initial begin serdes_rx_bitslip, tx_start_packet_0, tx_start_packet_4, + tx_error_underflow, rx_start_packet_0, rx_start_packet_4, rx_error_bad_frame, @@ -161,6 +163,7 @@ UUT ( .serdes_rx_bitslip(serdes_rx_bitslip), .tx_start_packet_0(tx_start_packet_0), .tx_start_packet_4(tx_start_packet_4), + .tx_error_underflow(tx_error_underflow), .rx_start_packet_0(rx_start_packet_0), .rx_start_packet_4(rx_start_packet_4), .rx_error_bad_frame(rx_error_bad_frame), diff --git a/tb/test_eth_mac_phy_10g_fifo.py b/tb/test_eth_mac_phy_10g_fifo.py index df34ef405..e87bd9a4a 100755 --- a/tb/test_eth_mac_phy_10g_fifo.py +++ b/tb/test_eth_mac_phy_10g_fifo.py @@ -109,6 +109,7 @@ def bench(): serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) serdes_rx_bitslip = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) tx_fifo_overflow = Signal(bool(0)) tx_fifo_bad_frame = Signal(bool(0)) tx_fifo_good_frame = Signal(bool(0)) @@ -202,6 +203,7 @@ def bench(): serdes_rx_data=serdes_rx_data, serdes_rx_hdr=serdes_rx_hdr, serdes_rx_bitslip=serdes_rx_bitslip, + tx_error_underflow=tx_error_underflow, tx_fifo_overflow=tx_fifo_overflow, tx_fifo_bad_frame=tx_fifo_bad_frame, tx_fifo_good_frame=tx_fifo_good_frame, diff --git a/tb/test_eth_mac_phy_10g_fifo.v b/tb/test_eth_mac_phy_10g_fifo.v index c838c79b4..7c09e923f 100644 --- a/tb/test_eth_mac_phy_10g_fifo.v +++ b/tb/test_eth_mac_phy_10g_fifo.v @@ -83,6 +83,7 @@ wire rx_axis_tuser; wire [DATA_WIDTH-1:0] serdes_tx_data; wire [HDR_WIDTH-1:0] serdes_tx_hdr; wire serdes_rx_bitslip; +wire tx_error_underflow; wire tx_fifo_overflow; wire tx_fifo_bad_frame; wire tx_fifo_good_frame; @@ -126,6 +127,7 @@ initial begin serdes_tx_data, serdes_tx_hdr, serdes_rx_bitslip, + tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, @@ -188,6 +190,7 @@ UUT ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .tx_error_underflow(tx_error_underflow), .tx_fifo_overflow(tx_fifo_overflow), .tx_fifo_bad_frame(tx_fifo_bad_frame), .tx_fifo_good_frame(tx_fifo_good_frame), From 88badf13f0f66187d8048636df1e905daf924994 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 26 Mar 2019 16:19:49 -0700 Subject: [PATCH 536/617] Reset all status synchronization stages --- rtl/axis_async_fifo.v | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 697223aa8..30c51edf6 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -367,10 +367,13 @@ always @(posedge m_clk) begin if (m_rst_sync3_reg) begin overflow_sync2_reg <= 1'b0; overflow_sync3_reg <= 1'b0; + overflow_sync4_reg <= 1'b0; bad_frame_sync2_reg <= 1'b0; bad_frame_sync3_reg <= 1'b0; + bad_frame_sync4_reg <= 1'b0; good_frame_sync2_reg <= 1'b0; good_frame_sync3_reg <= 1'b0; + good_frame_sync4_reg <= 1'b0; end else begin overflow_sync2_reg <= overflow_sync1_reg; overflow_sync3_reg <= overflow_sync2_reg; From 3920b2801e4509ec7c3d567ed47e179e0ce83710 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 26 Mar 2019 16:39:31 -0700 Subject: [PATCH 537/617] Add short packet tests --- tb/test_axis_async_fifo.py | 21 +++++++++++++++++++++ tb/test_axis_async_fifo_64.py | 21 +++++++++++++++++++++ tb/test_axis_async_frame_fifo.py | 21 +++++++++++++++++++++ tb/test_axis_async_frame_fifo_64.py | 21 +++++++++++++++++++++ tb/test_axis_fifo.py | 21 +++++++++++++++++++++ tb/test_axis_fifo_64.py | 21 +++++++++++++++++++++ tb/test_axis_frame_fifo.py | 21 +++++++++++++++++++++ tb/test_axis_frame_fifo_64.py | 21 +++++++++++++++++++++ 8 files changed, 168 insertions(+) diff --git a/tb/test_axis_async_fifo.py b/tb/test_axis_async_fifo.py index 39cfdcde0..67989257e 100755 --- a/tb/test_axis_async_fifo.py +++ b/tb/test_axis_async_fifo.py @@ -500,6 +500,27 @@ def bench(): yield delay(100) + yield s_clk.posedge + print("test 11: many small packets") + current_test.next = 11 + + test_frame = axis_ep.AXIStreamFrame( + b'\xAA', + id=11, + dest=1 + ) + + for k in range(64): + source.send(test_frame) + + for k in range(64): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_async_fifo_64.py b/tb/test_axis_async_fifo_64.py index 5e1739096..44925adf4 100755 --- a/tb/test_axis_async_fifo_64.py +++ b/tb/test_axis_async_fifo_64.py @@ -500,6 +500,27 @@ def bench(): yield delay(100) + yield s_clk.posedge + print("test 11: many small packets") + current_test.next = 11 + + test_frame = axis_ep.AXIStreamFrame( + b'\xAA', + id=11, + dest=1 + ) + + for k in range(64): + source.send(test_frame) + + for k in range(64): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_async_frame_fifo.py b/tb/test_axis_async_frame_fifo.py index f6745b583..367efd19d 100755 --- a/tb/test_axis_async_frame_fifo.py +++ b/tb/test_axis_async_frame_fifo.py @@ -668,6 +668,27 @@ def bench(): yield delay(100) + yield s_clk.posedge + print("test 12: many small packets") + current_test.next = 12 + + test_frame = axis_ep.AXIStreamFrame( + b'\xAA', + id=12, + dest=1 + ) + + for k in range(64): + source.send(test_frame) + + for k in range(64): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_async_frame_fifo_64.py b/tb/test_axis_async_frame_fifo_64.py index a72d060e4..fbd5a76d2 100755 --- a/tb/test_axis_async_frame_fifo_64.py +++ b/tb/test_axis_async_frame_fifo_64.py @@ -668,6 +668,27 @@ def bench(): yield delay(100) + yield s_clk.posedge + print("test 12: many small packets") + current_test.next = 12 + + test_frame = axis_ep.AXIStreamFrame( + b'\xAA', + id=12, + dest=1 + ) + + for k in range(64): + source.send(test_frame) + + for k in range(64): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_fifo.py b/tb/test_axis_fifo.py index f38f320d7..c28c90189 100755 --- a/tb/test_axis_fifo.py +++ b/tb/test_axis_fifo.py @@ -489,6 +489,27 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 11: many small packets") + current_test.next = 11 + + test_frame = axis_ep.AXIStreamFrame( + b'\xAA', + id=11, + dest=1 + ) + + for k in range(64): + source.send(test_frame) + + for k in range(64): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_fifo_64.py b/tb/test_axis_fifo_64.py index 7b508b7c7..eeb28ba4a 100755 --- a/tb/test_axis_fifo_64.py +++ b/tb/test_axis_fifo_64.py @@ -489,6 +489,27 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 11: many small packets") + current_test.next = 11 + + test_frame = axis_ep.AXIStreamFrame( + b'\xAA', + id=11, + dest=1 + ) + + for k in range(64): + source.send(test_frame) + + for k in range(64): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_frame_fifo.py b/tb/test_axis_frame_fifo.py index 2c2636b6a..b5ebab517 100755 --- a/tb/test_axis_frame_fifo.py +++ b/tb/test_axis_frame_fifo.py @@ -594,6 +594,27 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 12: many small packets") + current_test.next = 12 + + test_frame = axis_ep.AXIStreamFrame( + b'\xAA', + id=12, + dest=1 + ) + + for k in range(64): + source.send(test_frame) + + for k in range(64): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_axis_frame_fifo_64.py b/tb/test_axis_frame_fifo_64.py index 164e9718c..e0200d27a 100755 --- a/tb/test_axis_frame_fifo_64.py +++ b/tb/test_axis_frame_fifo_64.py @@ -594,6 +594,27 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 12: many small packets") + current_test.next = 12 + + test_frame = axis_ep.AXIStreamFrame( + b'\xAA', + id=12, + dest=1 + ) + + for k in range(64): + source.send(test_frame) + + for k in range(64): + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + yield delay(100) + raise StopSimulation return instances() From 932aa3545156b6c6006a10cd6a2f30b128aed37d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 26 Mar 2019 18:45:54 -0700 Subject: [PATCH 538/617] Fix AXI stream async frame FIFO write pointer synchronization --- rtl/axis_async_fifo.v | 60 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 30c51edf6..659b2698d 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -124,6 +124,7 @@ localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_next; reg [ADDR_WIDTH:0] wr_ptr_cur_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_next; reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_gray_next; +reg [ADDR_WIDTH:0] wr_ptr_sync_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_sync_gray_next; reg [ADDR_WIDTH:0] wr_ptr_cur_gray_reg = {ADDR_WIDTH+1{1'b0}}, wr_ptr_cur_gray_next; reg [ADDR_WIDTH:0] wr_addr_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}, rd_ptr_next; @@ -135,6 +136,14 @@ reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; +reg wr_ptr_update_valid_reg = 1'b0, wr_ptr_update_valid_next; +reg wr_ptr_update_reg = 1'b0, wr_ptr_update_next; +reg wr_ptr_update_sync1_reg = 1'b0; +reg wr_ptr_update_sync2_reg = 1'b0; +reg wr_ptr_update_sync3_reg = 1'b0; +reg wr_ptr_update_ack_sync1_reg = 1'b0; +reg wr_ptr_update_ack_sync2_reg = 1'b0; + reg s_rst_sync1_reg = 1'b1; reg s_rst_sync2_reg = 1'b1; reg s_rst_sync3_reg = 1'b1; @@ -160,7 +169,7 @@ wire full_cur = ((wr_ptr_cur_gray_reg[ADDR_WIDTH] != rd_ptr_gray_sync2_reg[ADDR_ (wr_ptr_cur_gray_reg[ADDR_WIDTH-1] != rd_ptr_gray_sync2_reg[ADDR_WIDTH-1]) && (wr_ptr_cur_gray_reg[ADDR_WIDTH-2:0] == rd_ptr_gray_sync2_reg[ADDR_WIDTH-2:0])); // empty when pointers match exactly -wire empty = rd_ptr_gray_reg == wr_ptr_gray_sync2_reg; +wire empty = rd_ptr_gray_reg == (FRAME_FIFO ? wr_ptr_gray_sync1_reg : wr_ptr_gray_sync2_reg); // overflow within packet wire full_wr = ((wr_ptr_reg[ADDR_WIDTH] != wr_ptr_cur_reg[ADDR_WIDTH]) && (wr_ptr_reg[ADDR_WIDTH-1:0] == wr_ptr_cur_reg[ADDR_WIDTH-1:0])); @@ -253,8 +262,22 @@ always @* begin wr_ptr_next = wr_ptr_reg; wr_ptr_cur_next = wr_ptr_cur_reg; wr_ptr_gray_next = wr_ptr_gray_reg; + wr_ptr_sync_gray_next = wr_ptr_sync_gray_reg; wr_ptr_cur_gray_next = wr_ptr_cur_gray_reg; + wr_ptr_update_valid_next = wr_ptr_update_valid_reg; + wr_ptr_update_next = wr_ptr_update_reg; + + if (FRAME_FIFO && wr_ptr_update_valid_reg) begin + // have updated pointer to sync + if (wr_ptr_update_next == wr_ptr_update_ack_sync2_reg) begin + // no sync in progress; sync update + wr_ptr_update_valid_next = 1'b0; + wr_ptr_sync_gray_next = wr_ptr_gray_reg; + wr_ptr_update_next = !wr_ptr_update_ack_sync2_reg; + end + end + if (s_axis_tready && s_axis_tvalid) begin // transfer in if (!FRAME_FIFO) begin @@ -288,6 +311,17 @@ always @* begin // good packet, update write pointer wr_ptr_next = wr_ptr_cur_reg + 1; wr_ptr_gray_next = wr_ptr_next ^ (wr_ptr_next >> 1); + + if (wr_ptr_update_next == wr_ptr_update_ack_sync2_reg) begin + // no sync in progress; sync update + wr_ptr_update_valid_next = 1'b0; + wr_ptr_sync_gray_next = wr_ptr_gray_next; + wr_ptr_update_next = !wr_ptr_update_ack_sync2_reg; + end else begin + // sync in progress; flag it for later + wr_ptr_update_valid_next = 1'b1; + end + good_frame_next = 1'b1; end end @@ -300,8 +334,12 @@ always @(posedge s_clk) begin wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_sync_gray_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_cur_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_update_valid_reg <= 1'b0; + wr_ptr_update_reg <= 1'b0; + drop_frame_reg <= 1'b0; overflow_reg <= 1'b0; bad_frame_reg <= 1'b0; @@ -310,8 +348,12 @@ always @(posedge s_clk) begin wr_ptr_reg <= wr_ptr_next; wr_ptr_cur_reg <= wr_ptr_cur_next; wr_ptr_gray_reg <= wr_ptr_gray_next; + wr_ptr_sync_gray_reg <= wr_ptr_sync_gray_next; wr_ptr_cur_gray_reg <= wr_ptr_cur_gray_next; + wr_ptr_update_valid_reg <= wr_ptr_update_valid_next; + wr_ptr_update_reg <= wr_ptr_update_next; + drop_frame_reg <= drop_frame_next; overflow_reg <= overflow_next; bad_frame_reg <= bad_frame_next; @@ -334,9 +376,13 @@ always @(posedge s_clk) begin if (s_rst_sync3_reg) begin rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_update_ack_sync1_reg <= 1'b0; + wr_ptr_update_ack_sync2_reg <= 1'b0; end else begin rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg; rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg; + wr_ptr_update_ack_sync1_reg <= wr_ptr_update_sync3_reg; + wr_ptr_update_ack_sync2_reg <= wr_ptr_update_ack_sync1_reg; end end @@ -344,9 +390,19 @@ always @(posedge m_clk) begin if (m_rst_sync3_reg) begin wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_update_sync1_reg <= 1'b0; + wr_ptr_update_sync2_reg <= 1'b0; + wr_ptr_update_sync3_reg <= 1'b0; end else begin - wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; + if (!FRAME_FIFO) begin + wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; + end else if (wr_ptr_update_sync2_reg ^ wr_ptr_update_sync3_reg) begin + wr_ptr_gray_sync1_reg <= wr_ptr_sync_gray_reg; + end wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg; + wr_ptr_update_sync1_reg <= wr_ptr_update_reg; + wr_ptr_update_sync2_reg <= wr_ptr_update_sync1_reg; + wr_ptr_update_sync3_reg <= wr_ptr_update_sync2_reg; end end From 48984013de6e098c7d0087604d0232c87a437444 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 26 Mar 2019 18:46:25 -0700 Subject: [PATCH 539/617] Add AXI stream async FIFO timing constraints --- syn/axis_async_fifo.tcl | 75 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 syn/axis_async_fifo.tcl diff --git a/syn/axis_async_fifo.tcl b/syn/axis_async_fifo.tcl new file mode 100644 index 000000000..097e92870 --- /dev/null +++ b/syn/axis_async_fifo.tcl @@ -0,0 +1,75 @@ +# Copyright (c) 2019 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. + +# AXI stream asynchronous FIFO timing constraints + +foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo || REF_NAME == axis_async_fifo)}] { + puts "Inserting timing constraints for axis_async_fifo instance $fifo_inst" + + # get clock periods + set read_clk [get_clocks -of_objects [get_pins $fifo_inst/rd_ptr_reg_reg[0]/C]] + set write_clk [get_clocks -of_objects [get_pins $fifo_inst/wr_ptr_reg_reg[0]/C]] + + set read_clk_period [get_property -min PERIOD $read_clk] + set write_clk_period [get_property -min PERIOD $write_clk] + + set min_clk_period [expr $read_clk_period < $write_clk_period ? $read_clk_period : $write_clk_period] + + # reset synchronization + set reset_ffs [get_cells -hier -regexp ".*/(s|m)_rst_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] + + set_property ASYNC_REG TRUE $reset_ffs + set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}] + + set_false_path -to [get_pins $fifo_inst/s_rst_sync2_reg_reg/D] + set_max_delay -from [get_cells $fifo_inst/s_rst_sync2_reg_reg] -to [get_cells $fifo_inst/s_rst_sync3_reg_reg] $min_clk_period + + set_false_path -to [get_pins $fifo_inst/m_rst_sync2_reg_reg/D] + set_max_delay -from [get_cells $fifo_inst/m_rst_sync2_reg_reg] -to [get_cells $fifo_inst/m_rst_sync3_reg_reg] $min_clk_period + + # pointer synchronization + set_property ASYNC_REG TRUE [get_cells -hier -regexp ".*/(wr|rd)_ptr_gray_sync\[12\]_reg_reg\\\[\\d+\\\]" -filter "PARENT == $fifo_inst"] + + set_max_delay -from [get_cells "$fifo_inst/rd_ptr_reg_reg[*] $fifo_inst/rd_ptr_gray_reg_reg[*]"] -to [get_cells $fifo_inst/rd_ptr_gray_sync1_reg_reg[*]] -datapath_only $read_clk_period + set_bus_skew -from [get_cells "$fifo_inst/rd_ptr_reg_reg[*] $fifo_inst/rd_ptr_gray_reg_reg[*]"] -to [get_cells $fifo_inst/rd_ptr_gray_sync1_reg_reg[*]] $write_clk_period + set_max_delay -from [get_cells "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] -datapath_only $write_clk_period + set_bus_skew -from [get_cells "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] $read_clk_period + + # frame FIFO pointer update synchronization + set update_ffs [get_cells -hier -regexp ".*/wr_ptr_update(_ack)?_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] + + if {[llength $update_ffs]} { + set_property ASYNC_REG TRUE $update_ffs + + set_max_delay -from [get_cells $fifo_inst/wr_ptr_update_reg_reg] -to [get_cells $fifo_inst/wr_ptr_update_sync1_reg_reg] -datapath_only $write_clk_period + set_max_delay -from [get_cells $fifo_inst/wr_ptr_update_sync3_reg_reg] -to [get_cells $fifo_inst/wr_ptr_update_ack_sync1_reg_reg] -datapath_only $read_clk_period + } + + # status synchronization + foreach i {overflow bad_frame good_frame} { + set status_sync_regs [get_cells -quiet -hier -regexp ".*/${i}_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] + + if {[llength $status_sync_regs]} { + set_property ASYNC_REG TRUE $status_sync_regs + + set_max_delay -from [get_cells $fifo_inst/${i}_sync1_reg_reg] -to [get_cells $fifo_inst/${i}_sync2_reg_reg] -datapath_only $read_clk_period + } + } +} From e9388447838167e046af076286a48a9f76f9b527 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 27 Mar 2019 23:54:48 -0700 Subject: [PATCH 540/617] Account for merged registers --- syn/axis_async_fifo.tcl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/syn/axis_async_fifo.tcl b/syn/axis_async_fifo.tcl index 097e92870..6565f9b50 100644 --- a/syn/axis_async_fifo.tcl +++ b/syn/axis_async_fifo.tcl @@ -38,11 +38,15 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo || set_property ASYNC_REG TRUE $reset_ffs set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}] - set_false_path -to [get_pins $fifo_inst/s_rst_sync2_reg_reg/D] - set_max_delay -from [get_cells $fifo_inst/s_rst_sync2_reg_reg] -to [get_cells $fifo_inst/s_rst_sync3_reg_reg] $min_clk_period + if {[llength [get_cells $fifo_inst/s_rst_sync2_reg_reg]]} { + set_false_path -to [get_pins $fifo_inst/s_rst_sync2_reg_reg/D] + set_max_delay -from [get_cells $fifo_inst/s_rst_sync2_reg_reg] -to [get_cells $fifo_inst/s_rst_sync3_reg_reg] $min_clk_period + } - set_false_path -to [get_pins $fifo_inst/m_rst_sync2_reg_reg/D] - set_max_delay -from [get_cells $fifo_inst/m_rst_sync2_reg_reg] -to [get_cells $fifo_inst/m_rst_sync3_reg_reg] $min_clk_period + if {[llength [get_cells $fifo_inst/m_rst_sync2_reg_reg]]} { + set_false_path -to [get_pins $fifo_inst/m_rst_sync2_reg_reg/D] + set_max_delay -from [get_cells $fifo_inst/m_rst_sync2_reg_reg] -to [get_cells $fifo_inst/m_rst_sync3_reg_reg] $min_clk_period + } # pointer synchronization set_property ASYNC_REG TRUE [get_cells -hier -regexp ".*/(wr|rd)_ptr_gray_sync\[12\]_reg_reg\\\[\\d+\\\]" -filter "PARENT == $fifo_inst"] From edcfd0dc40e48ddd927d8f1c8e611432a2600f43 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 12:36:32 -0700 Subject: [PATCH 541/617] Prevent SRL inference in synchronizers --- rtl/eth_mac_1g_gmii.v | 42 ++++++++++++++++++------------------------ rtl/eth_mac_1g_rgmii.v | 40 +++++++++++++++++----------------------- 2 files changed, 35 insertions(+), 47 deletions(-) diff --git a/rtl/eth_mac_1g_gmii.v b/rtl/eth_mac_1g_gmii.v index 8e5d7ff62..dc0927c83 100644 --- a/rtl/eth_mac_1g_gmii.v +++ b/rtl/eth_mac_1g_gmii.v @@ -105,26 +105,20 @@ wire mac_gmii_tx_en; wire mac_gmii_tx_er; reg [1:0] speed_reg = 2'b10; -wire mii_select; +reg mii_select_reg = 1'b0; -reg tx_mii_select_1 = 1'b0; -reg tx_mii_select_2 = 1'b0; -reg tx_mii_select_3 = 1'b0; +(* srl_style = "register" *) +reg [1:0] tx_mii_select_sync = 2'd0; always @(posedge tx_clk) begin - tx_mii_select_1 <= mii_select; - tx_mii_select_2 <= tx_mii_select_1; - tx_mii_select_3 <= tx_mii_select_2; + tx_mii_select_sync <= {tx_mii_select_sync[0], mii_select_reg}; end -reg rx_mii_select_1 = 1'b0; -reg rx_mii_select_2 = 1'b0; -reg rx_mii_select_3 = 1'b0; +(* srl_style = "register" *) +reg [1:0] rx_mii_select_sync = 2'd0; always @(posedge rx_clk) begin - rx_mii_select_1 <= mii_select; - rx_mii_select_2 <= rx_mii_select_1; - rx_mii_select_3 <= rx_mii_select_2; + rx_mii_select_sync <= {rx_mii_select_sync[0], mii_select_reg}; end // PHY speed detection @@ -134,14 +128,11 @@ always @(posedge rx_clk) begin rx_prescale <= rx_prescale + 3'd1; end -reg rx_prescale_sync_1 = 1'b0; -reg rx_prescale_sync_2 = 1'b0; -reg rx_prescale_sync_3 = 1'b0; +(* srl_style = "register" *) +reg [2:0] rx_prescale_sync = 3'd0; always @(posedge gtx_clk) begin - rx_prescale_sync_1 <= rx_prescale[2]; - rx_prescale_sync_2 <= rx_prescale_sync_1; - rx_prescale_sync_3 <= rx_prescale_sync_2; + rx_prescale_sync <= {rx_prescale_sync[1:0], rx_prescale[2]}; end reg [6:0] rx_speed_count_1 = 0; @@ -152,10 +143,11 @@ always @(posedge gtx_clk) begin rx_speed_count_1 <= 0; rx_speed_count_2 <= 0; speed_reg <= 2'b10; + mii_select_reg <= 1'b0; end else begin rx_speed_count_1 <= rx_speed_count_1 + 1; - if (rx_prescale_sync_2 ^ rx_prescale_sync_3) begin + if (rx_prescale_sync[1] ^ rx_prescale_sync[2]) begin rx_speed_count_2 <= rx_speed_count_2 + 1; end @@ -164,6 +156,7 @@ always @(posedge gtx_clk) begin rx_speed_count_1 <= 0; rx_speed_count_2 <= 0; speed_reg <= 2'b00; + mii_select_reg <= 1'b1; end if (&rx_speed_count_2) begin @@ -173,16 +166,17 @@ always @(posedge gtx_clk) begin if (rx_speed_count_1[6:5]) begin // large reference count - 100M speed_reg <= 2'b01; + mii_select_reg <= 1'b1; end else begin // small reference count - 1000M speed_reg <= 2'b10; + mii_select_reg <= 1'b0; end end end end assign speed = speed_reg; -assign mii_select = speed != 2'b10; gmii_phy_if #( .TARGET(TARGET), @@ -214,7 +208,7 @@ gmii_phy_if_inst ( .phy_gmii_tx_en(gmii_tx_en), .phy_gmii_tx_er(gmii_tx_er), - .mii_select(mii_select) + .mii_select(mii_select_reg) ); eth_mac_1g #( @@ -243,8 +237,8 @@ eth_mac_1g_inst ( .gmii_tx_er(mac_gmii_tx_er), .rx_clk_enable(1'b1), .tx_clk_enable(1'b1), - .rx_mii_select(rx_mii_select_3), - .tx_mii_select(tx_mii_select_3), + .rx_mii_select(rx_mii_select_sync[1]), + .tx_mii_select(tx_mii_select_sync[1]), .tx_error_underflow(tx_error_underflow), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), diff --git a/rtl/eth_mac_1g_rgmii.v b/rtl/eth_mac_1g_rgmii.v index 48facacef..a29d576ed 100644 --- a/rtl/eth_mac_1g_rgmii.v +++ b/rtl/eth_mac_1g_rgmii.v @@ -106,26 +106,20 @@ wire mac_gmii_tx_en; wire mac_gmii_tx_er; reg [1:0] speed_reg = 2'b10; -wire mii_select; +reg mii_select_reg = 1'b0; -reg tx_mii_select_1 = 1'b0; -reg tx_mii_select_2 = 1'b0; -reg tx_mii_select_3 = 1'b0; +(* srl_style = "register" *) +reg [1:0] tx_mii_select_sync = 2'd0; always @(posedge tx_clk) begin - tx_mii_select_1 <= mii_select; - tx_mii_select_2 <= tx_mii_select_1; - tx_mii_select_3 <= tx_mii_select_2; + tx_mii_select_sync <= {tx_mii_select_sync[0], mii_select_reg}; end -reg rx_mii_select_1 = 1'b0; -reg rx_mii_select_2 = 1'b0; -reg rx_mii_select_3 = 1'b0; +(* srl_style = "register" *) +reg [1:0] rx_mii_select_sync = 2'd0; always @(posedge rx_clk) begin - rx_mii_select_1 <= mii_select; - rx_mii_select_2 <= rx_mii_select_1; - rx_mii_select_3 <= rx_mii_select_2; + rx_mii_select_sync <= {rx_mii_select_sync[0], mii_select_reg}; end // PHY speed detection @@ -135,14 +129,11 @@ always @(posedge rx_clk) begin rx_prescale <= rx_prescale + 3'd1; end -reg rx_prescale_sync_1 = 1'b0; -reg rx_prescale_sync_2 = 1'b0; -reg rx_prescale_sync_3 = 1'b0; +(* srl_style = "register" *) +reg [2:0] rx_prescale_sync = 3'd0; always @(posedge gtx_clk) begin - rx_prescale_sync_1 <= rx_prescale[2]; - rx_prescale_sync_2 <= rx_prescale_sync_1; - rx_prescale_sync_3 <= rx_prescale_sync_2; + rx_prescale_sync <= {rx_prescale_sync[1:0], rx_prescale[2]}; end reg [6:0] rx_speed_count_1 = 0; @@ -153,10 +144,11 @@ always @(posedge gtx_clk) begin rx_speed_count_1 <= 0; rx_speed_count_2 <= 0; speed_reg <= 2'b10; + mii_select_reg <= 1'b0; end else begin rx_speed_count_1 <= rx_speed_count_1 + 1; - if (rx_prescale_sync_2 ^ rx_prescale_sync_3) begin + if (rx_prescale_sync[1] ^ rx_prescale_sync[2]) begin rx_speed_count_2 <= rx_speed_count_2 + 1; end @@ -165,6 +157,7 @@ always @(posedge gtx_clk) begin rx_speed_count_1 <= 0; rx_speed_count_2 <= 0; speed_reg <= 2'b00; + mii_select_reg <= 1'b1; end if (&rx_speed_count_2) begin @@ -174,16 +167,17 @@ always @(posedge gtx_clk) begin if (rx_speed_count_1[6:5]) begin // large reference count - 100M speed_reg <= 2'b01; + mii_select_reg <= 1'b1; end else begin // small reference count - 1000M speed_reg <= 2'b10; + mii_select_reg <= 1'b0; end end end end assign speed = speed_reg; -assign mii_select = speed != 2'b10; rgmii_phy_if #( .TARGET(TARGET), @@ -244,8 +238,8 @@ eth_mac_1g_inst ( .gmii_tx_er(mac_gmii_tx_er), .rx_clk_enable(1'b1), .tx_clk_enable(mac_gmii_tx_clk_en), - .rx_mii_select(rx_mii_select_3), - .tx_mii_select(tx_mii_select_3), + .rx_mii_select(rx_mii_select_sync[1]), + .tx_mii_select(tx_mii_select_sync[1]), .tx_error_underflow(tx_error_underflow), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), From 3eaed305f561f9ae1b5d50a13c6727c4b6582cdb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 16:27:15 -0700 Subject: [PATCH 542/617] Connect TX underflow status outputs --- rtl/eth_mac_1g_fifo.v | 1 + rtl/eth_mac_1g_gmii_fifo.v | 1 + rtl/eth_mac_1g_rgmii_fifo.v | 1 + rtl/eth_mac_phy_10g_fifo.v | 1 + 4 files changed, 4 insertions(+) diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index bda92a892..767f900cd 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -205,6 +205,7 @@ eth_mac_1g_inst ( .tx_clk_enable(tx_clk_enable), .rx_mii_select(rx_mii_select), .tx_mii_select(tx_mii_select), + .tx_error_underflow(tx_error_underflow_int), .rx_error_bad_frame(rx_error_bad_frame_int), .rx_error_bad_fcs(rx_error_bad_fcs_int), .ifg_delay(ifg_delay) diff --git a/rtl/eth_mac_1g_gmii_fifo.v b/rtl/eth_mac_1g_gmii_fifo.v index a7c8387eb..65d6c8ab6 100644 --- a/rtl/eth_mac_1g_gmii_fifo.v +++ b/rtl/eth_mac_1g_gmii_fifo.v @@ -231,6 +231,7 @@ eth_mac_1g_gmii_inst ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .tx_error_underflow(tx_error_underflow_int), .rx_error_bad_frame(rx_error_bad_frame_int), .rx_error_bad_fcs(rx_error_bad_fcs_int), .speed(speed_int), diff --git a/rtl/eth_mac_1g_rgmii_fifo.v b/rtl/eth_mac_1g_rgmii_fifo.v index 88041ae6c..06e535ab4 100644 --- a/rtl/eth_mac_1g_rgmii_fifo.v +++ b/rtl/eth_mac_1g_rgmii_fifo.v @@ -230,6 +230,7 @@ eth_mac_1g_rgmii_inst ( .rgmii_tx_clk(rgmii_tx_clk), .rgmii_txd(rgmii_txd), .rgmii_tx_ctl(rgmii_tx_ctl), + .tx_error_underflow(tx_error_underflow_int), .rx_error_bad_frame(rx_error_bad_frame_int), .rx_error_bad_fcs(rx_error_bad_fcs_int), .speed(speed_int), diff --git a/rtl/eth_mac_phy_10g_fifo.v b/rtl/eth_mac_phy_10g_fifo.v index c8dc0b9c7..41249e562 100644 --- a/rtl/eth_mac_phy_10g_fifo.v +++ b/rtl/eth_mac_phy_10g_fifo.v @@ -219,6 +219,7 @@ eth_mac_phy_10g_inst ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .tx_error_underflow(tx_error_underflow_int), .rx_error_bad_frame(rx_error_bad_frame_int), .rx_error_bad_fcs(rx_error_bad_fcs_int), .rx_block_lock(rx_block_lock_int), From 8285f94eaaef06155a28315e84489a744aded636 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 16:27:33 -0700 Subject: [PATCH 543/617] Rename tx_sync regs --- rtl/eth_mac_10g_fifo.v | 10 +++++----- rtl/eth_mac_1g_fifo.v | 10 +++++----- rtl/eth_mac_1g_gmii_fifo.v | 10 +++++----- rtl/eth_mac_1g_rgmii_fifo.v | 10 +++++----- rtl/eth_mac_phy_10g_fifo.v | 10 +++++----- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/rtl/eth_mac_10g_fifo.v b/rtl/eth_mac_10g_fifo.v index 05f57b1d8..b478dff58 100644 --- a/rtl/eth_mac_10g_fifo.v +++ b/rtl/eth_mac_10g_fifo.v @@ -117,12 +117,12 @@ wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain wire tx_error_underflow_int; -reg tx_sync_reg_1 = 1'b0; -reg tx_sync_reg_2 = 1'b0; -reg tx_sync_reg_3 = 1'b0; -reg tx_sync_reg_4 = 1'b0; +reg [0:0] tx_sync_reg_1 = 1'b0; +reg [0:0] tx_sync_reg_2 = 1'b0; +reg [0:0] tx_sync_reg_3 = 1'b0; +reg [0:0] tx_sync_reg_4 = 1'b0; -assign tx_error_underflow = tx_sync_reg_3 ^ tx_sync_reg_4; +assign tx_error_underflow = tx_sync_reg_3[0] ^ tx_sync_reg_4[0]; always @(posedge tx_clk or posedge tx_rst) begin if (tx_rst) begin diff --git a/rtl/eth_mac_1g_fifo.v b/rtl/eth_mac_1g_fifo.v index 767f900cd..b96c5a862 100644 --- a/rtl/eth_mac_1g_fifo.v +++ b/rtl/eth_mac_1g_fifo.v @@ -119,12 +119,12 @@ wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain wire tx_error_underflow_int; -reg tx_sync_reg_1 = 1'b0; -reg tx_sync_reg_2 = 1'b0; -reg tx_sync_reg_3 = 1'b0; -reg tx_sync_reg_4 = 1'b0; +reg [0:0] tx_sync_reg_1 = 1'b0; +reg [0:0] tx_sync_reg_2 = 1'b0; +reg [0:0] tx_sync_reg_3 = 1'b0; +reg [0:0] tx_sync_reg_4 = 1'b0; -assign tx_error_underflow = tx_sync_reg_3 ^ tx_sync_reg_4; +assign tx_error_underflow = tx_sync_reg_3[0] ^ tx_sync_reg_4[0]; always @(posedge tx_clk or posedge tx_rst) begin if (tx_rst) begin diff --git a/rtl/eth_mac_1g_gmii_fifo.v b/rtl/eth_mac_1g_gmii_fifo.v index 65d6c8ab6..dc853732c 100644 --- a/rtl/eth_mac_1g_gmii_fifo.v +++ b/rtl/eth_mac_1g_gmii_fifo.v @@ -129,12 +129,12 @@ wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain wire tx_error_underflow_int; -reg tx_sync_reg_1 = 1'b0; -reg tx_sync_reg_2 = 1'b0; -reg tx_sync_reg_3 = 1'b0; -reg tx_sync_reg_4 = 1'b0; +reg [0:0] tx_sync_reg_1 = 1'b0; +reg [0:0] tx_sync_reg_2 = 1'b0; +reg [0:0] tx_sync_reg_3 = 1'b0; +reg [0:0] tx_sync_reg_4 = 1'b0; -assign tx_error_underflow = tx_sync_reg_3 ^ tx_sync_reg_4; +assign tx_error_underflow = tx_sync_reg_3[0] ^ tx_sync_reg_4[0]; always @(posedge tx_clk or posedge tx_rst) begin if (tx_rst) begin diff --git a/rtl/eth_mac_1g_rgmii_fifo.v b/rtl/eth_mac_1g_rgmii_fifo.v index 06e535ab4..ce7b85746 100644 --- a/rtl/eth_mac_1g_rgmii_fifo.v +++ b/rtl/eth_mac_1g_rgmii_fifo.v @@ -129,12 +129,12 @@ wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain wire tx_error_underflow_int; -reg tx_sync_reg_1 = 1'b0; -reg tx_sync_reg_2 = 1'b0; -reg tx_sync_reg_3 = 1'b0; -reg tx_sync_reg_4 = 1'b0; +reg [0:0] tx_sync_reg_1 = 1'b0; +reg [0:0] tx_sync_reg_2 = 1'b0; +reg [0:0] tx_sync_reg_3 = 1'b0; +reg [0:0] tx_sync_reg_4 = 1'b0; -assign tx_error_underflow = tx_sync_reg_3 ^ tx_sync_reg_4; +assign tx_error_underflow = tx_sync_reg_3[0] ^ tx_sync_reg_4[0]; always @(posedge tx_clk or posedge tx_rst) begin if (tx_rst) begin diff --git a/rtl/eth_mac_phy_10g_fifo.v b/rtl/eth_mac_phy_10g_fifo.v index 41249e562..038194636 100644 --- a/rtl/eth_mac_phy_10g_fifo.v +++ b/rtl/eth_mac_phy_10g_fifo.v @@ -125,12 +125,12 @@ wire rx_fifo_axis_tuser; // synchronize MAC status signals into logic clock domain wire tx_error_underflow_int; -reg tx_sync_reg_1 = 1'b0; -reg tx_sync_reg_2 = 1'b0; -reg tx_sync_reg_3 = 1'b0; -reg tx_sync_reg_4 = 1'b0; +reg [0:0] tx_sync_reg_1 = 1'b0; +reg [0:0] tx_sync_reg_2 = 1'b0; +reg [0:0] tx_sync_reg_3 = 1'b0; +reg [0:0] tx_sync_reg_4 = 1'b0; -assign tx_error_underflow = tx_sync_reg_3 ^ tx_sync_reg_4; +assign tx_error_underflow = tx_sync_reg_3[0] ^ tx_sync_reg_4[0]; always @(posedge tx_clk or posedge tx_rst) begin if (tx_rst) begin From d16d291d5e5d997295abd86f83239a5a34e5195f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 16:30:34 -0700 Subject: [PATCH 544/617] Upgrade example design IP cores --- .../fpga_10g/ip/gig_ethernet_pcs_pma_0.xci | 230 +++++++++++++++++- .../fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci | 128 +++++++++- .../fpga_1g/ip/gig_ethernet_pcs_pma_0.xci | 230 +++++++++++++++++- .../fpga_1g/ip/gig_ethernet_pcs_pma_0.xci | 230 +++++++++++++++++- 4 files changed, 803 insertions(+), 15 deletions(-) diff --git a/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci index 908bb2e82..1db9474cb 100644 --- a/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci +++ b/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci @@ -7,8 +7,209 @@ gig_ethernet_pcs_pma_0 - + + 1 + 1 + 1 + 1 + + + + 0 + + + + 0 + + + 0 + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + false + false + false + false + 0 + + + + 0 + + + + 0 + false + 100000000 + + + + 0 + + + + 0 + + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + false + false + false + false + 0 + 0 + + + + 100000000 + 0 + 0.000 + + + + 100000000 + 0 + 0.000 + false + false + false + + + + 100000000 + 0 + 0.000 + 0 + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + ACTIVE_LOW + ACTIVE_LOW + ACTIVE_LOW + ACTIVE_LOW + 1 + 0 + 0 + 0 + + 1 + 100000000 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 0.000 + AXI4LITE + READ_WRITE + 0 + 0 + 0 + 0 + 0 + + + 100000000 + 0 + 0.000 + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 true 0 0 @@ -38,6 +239,7 @@ GTH false true + false false false false @@ -59,6 +261,7 @@ xcvu095 false 1 + false true Sync gig_ethernet_pcs_pma_0 @@ -98,7 +301,8 @@ 1 false virtexu - + + xcvu095 ffva2104 VERILOG @@ -109,17 +313,35 @@ TRUE TRUE IP_Flow - 2 + 5 TRUE . . - 2017.1 + 2018.3 OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + diff --git a/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci b/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci index aaf8ceecd..644821b10 100644 --- a/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci +++ b/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci @@ -9,6 +9,127 @@ ten_gig_eth_pcs_pma_0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0.000 + + + + 0 + 0.000 + + + 100000000 + 0 + 0.000 + 0 + 0 + 0 + 0 + 0 + + + + 100000000 + 0 + 0.000 + + + + 100000000 + 0 + 0.000 + 0 + false + 0 + 0 + + + + 100000000 + 0 + 0.000 + + + + 0 + 0.000 + + + + 100000000 + 0 + 0.000 + + + + 0 + 0.000 + + + + 100000000 + 0 + 0.000 + + + + 0 + 0.000 + + + + 100000000 + 0 + 0.000 + + + + 0 + 0.000 + false + 0 + 0 + + + 0 + 0.000 + 0 + + + + 0 + 0.000 + + + + 0 + 0.000 + 0 + + + + 0 + 0.000 + + + + 0 + 0.000 + + 0 + 0.000 + + + + 0 + 0.000 0 ten_gig_eth_pcs_pma_0 125.00 @@ -45,7 +166,8 @@ 10Gig GTY virtexu - + + xcvu095 ffva2104 VERILOG @@ -56,12 +178,12 @@ TRUE TRUE IP_Flow - 8 + 14 TRUE . . - 2017.1 + 2018.3 OUT_OF_CONTEXT diff --git a/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci index 908bb2e82..1db9474cb 100644 --- a/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci +++ b/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci @@ -7,8 +7,209 @@ gig_ethernet_pcs_pma_0 - + + 1 + 1 + 1 + 1 + + + + 0 + + + + 0 + + + 0 + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + false + false + false + false + 0 + + + + 0 + + + + 0 + false + 100000000 + + + + 0 + + + + 0 + + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + false + false + false + false + 0 + 0 + + + + 100000000 + 0 + 0.000 + + + + 100000000 + 0 + 0.000 + false + false + false + + + + 100000000 + 0 + 0.000 + 0 + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + ACTIVE_LOW + ACTIVE_LOW + ACTIVE_LOW + ACTIVE_LOW + 1 + 0 + 0 + 0 + + 1 + 100000000 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 0.000 + AXI4LITE + READ_WRITE + 0 + 0 + 0 + 0 + 0 + + + 100000000 + 0 + 0.000 + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 true 0 0 @@ -38,6 +239,7 @@ GTH false true + false false false false @@ -59,6 +261,7 @@ xcvu095 false 1 + false true Sync gig_ethernet_pcs_pma_0 @@ -98,7 +301,8 @@ 1 false virtexu - + + xcvu095 ffva2104 VERILOG @@ -109,17 +313,35 @@ TRUE TRUE IP_Flow - 2 + 5 TRUE . . - 2017.1 + 2018.3 OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + diff --git a/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci index c23253498..129b30ccd 100644 --- a/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci +++ b/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci @@ -9,6 +9,207 @@ gig_ethernet_pcs_pma_0 + 1 + 1 + 1 + 1 + + + + 0 + + + + 0 + + + 0 + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + false + false + false + false + 0 + + + + 0 + + + + 0 + false + 100000000 + + + + 0 + + + + 0 + + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + false + false + false + false + 0 + 0 + + + + 100000000 + 0 + 0.000 + + + + 100000000 + 0 + 0.000 + false + false + false + + + + 100000000 + 0 + 0.000 + 0 + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + ACTIVE_LOW + ACTIVE_LOW + ACTIVE_LOW + ACTIVE_LOW + 1 + 0 + 0 + 0 + + 1 + 100000000 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 0.000 + AXI4LITE + READ_WRITE + 0 + 0 + 0 + 0 + 0 + + + 100000000 + 0 + 0.000 + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 true 0 0 @@ -20,7 +221,7 @@ DIFF_PAIR_2 DIFF_PAIR_1 virtexuplus - Sync + 0 gig_ethernet_pcs_pma_0 50.0 false @@ -38,6 +239,7 @@ GTH false true + false false false false @@ -59,6 +261,7 @@ xcvu9p false 1 + false true Sync gig_ethernet_pcs_pma_0 @@ -98,7 +301,8 @@ 0 false virtexuplus - + + xcvu9p flga2104 VERILOG @@ -109,17 +313,35 @@ TRUE TRUE IP_Flow - 0 + 5 TRUE . . - 2017.2.1 + 2018.3 OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + From ad3905ac4db5e0e1db4725a31932a0290c3cd497 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 16:33:01 -0700 Subject: [PATCH 545/617] Account for more merged registers --- syn/axis_async_fifo.tcl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/syn/axis_async_fifo.tcl b/syn/axis_async_fifo.tcl index 6565f9b50..6b3fe44cf 100644 --- a/syn/axis_async_fifo.tcl +++ b/syn/axis_async_fifo.tcl @@ -35,8 +35,10 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo || # reset synchronization set reset_ffs [get_cells -hier -regexp ".*/(s|m)_rst_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] - set_property ASYNC_REG TRUE $reset_ffs - set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}] + if {[llength $reset_ffs]} { + set_property ASYNC_REG TRUE $reset_ffs + set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}] + } if {[llength [get_cells $fifo_inst/s_rst_sync2_reg_reg]]} { set_false_path -to [get_pins $fifo_inst/s_rst_sync2_reg_reg/D] From 58201866f3bab67f4916d55e1ebb12c9fe116abf Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 17:53:51 -0700 Subject: [PATCH 546/617] Add timing constraints --- syn/eth_mac_1g_gmii.tcl | 55 ++++++++++++++++++++++++++++++++++++++++ syn/eth_mac_1g_rgmii.tcl | 55 ++++++++++++++++++++++++++++++++++++++++ syn/eth_mac_fifo.tcl | 48 +++++++++++++++++++++++++++++++++++ syn/gmii_phy_if.tcl | 31 ++++++++++++++++++++++ syn/rgmii_phy_if.tcl | 39 ++++++++++++++++++++++++++++ 5 files changed, 228 insertions(+) create mode 100644 syn/eth_mac_1g_gmii.tcl create mode 100644 syn/eth_mac_1g_rgmii.tcl create mode 100644 syn/eth_mac_fifo.tcl create mode 100644 syn/gmii_phy_if.tcl create mode 100644 syn/rgmii_phy_if.tcl diff --git a/syn/eth_mac_1g_gmii.tcl b/syn/eth_mac_1g_gmii.tcl new file mode 100644 index 000000000..65c637c78 --- /dev/null +++ b/syn/eth_mac_1g_gmii.tcl @@ -0,0 +1,55 @@ +# Copyright (c) 2019 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. + +# GMII Gigabit Ethernet MAC timing constraints + +foreach mac_inst [get_cells -hier -filter {(ORIG_REF_NAME == eth_mac_1g_gmii || REF_NAME == eth_mac_1g_gmii)}] { + puts "Inserting timing constraints for eth_mac_1g_gmii instance $mac_inst" + + set select_ffs [get_cells -hier -regexp ".*/tx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"] + + if {[llength $select_ffs]} { + set_property ASYNC_REG TRUE $select_ffs + + set src_clk [get_clocks -of_objects [get_pins $mac_inst/mii_select_reg_reg/C]] + + set_max_delay -from [get_cells $mac_inst/mii_select_reg_reg] -to [get_cells $mac_inst/tx_mii_select_sync_reg[0]] -datapath_only [get_property -min PERIOD $src_clk] + } + + set select_ffs [get_cells -hier -regexp ".*/rx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"] + + if {[llength $select_ffs]} { + set_property ASYNC_REG TRUE $select_ffs + + set src_clk [get_clocks -of_objects [get_pins $mac_inst/mii_select_reg_reg/C]] + + set_max_delay -from [get_cells $mac_inst/mii_select_reg_reg] -to [get_cells $mac_inst/rx_mii_select_sync_reg[0]] -datapath_only [get_property -min PERIOD $src_clk] + } + + set prescale_ffs [get_cells -hier -regexp ".*/rx_prescale_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"] + + if {[llength $prescale_ffs]} { + set_property ASYNC_REG TRUE $prescale_ffs + + set src_clk [get_clocks -of_objects [get_pins $mac_inst/rx_prescale_reg[2]/C]] + + set_max_delay -from [get_cells $mac_inst/rx_prescale_reg[2]] -to [get_cells $mac_inst/rx_prescale_sync_reg[0]] -datapath_only [get_property -min PERIOD $src_clk] + } +} diff --git a/syn/eth_mac_1g_rgmii.tcl b/syn/eth_mac_1g_rgmii.tcl new file mode 100644 index 000000000..7f8d0e273 --- /dev/null +++ b/syn/eth_mac_1g_rgmii.tcl @@ -0,0 +1,55 @@ +# Copyright (c) 2019 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. + +# RGMII Gigabit Ethernet MAC timing constraints + +foreach mac_inst [get_cells -hier -filter {(ORIG_REF_NAME == eth_mac_1g_rgmii || REF_NAME == eth_mac_1g_rgmii)}] { + puts "Inserting timing constraints for eth_mac_1g_rgmii instance $mac_inst" + + set select_ffs [get_cells -hier -regexp ".*/tx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"] + + if {[llength $select_ffs]} { + set_property ASYNC_REG TRUE $select_ffs + + set src_clk [get_clocks -of_objects [get_pins $mac_inst/mii_select_reg_reg/C]] + + set_max_delay -from [get_cells $mac_inst/mii_select_reg_reg] -to [get_cells $mac_inst/tx_mii_select_sync_reg[0]] -datapath_only [get_property -min PERIOD $src_clk] + } + + set select_ffs [get_cells -hier -regexp ".*/rx_mii_select_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"] + + if {[llength $select_ffs]} { + set_property ASYNC_REG TRUE $select_ffs + + set src_clk [get_clocks -of_objects [get_pins $mac_inst/mii_select_reg_reg/C]] + + set_max_delay -from [get_cells $mac_inst/mii_select_reg_reg] -to [get_cells $mac_inst/rx_mii_select_sync_reg[0]] -datapath_only [get_property -min PERIOD $src_clk] + } + + set prescale_ffs [get_cells -hier -regexp ".*/rx_prescale_sync_reg\\\[\\d\\\]" -filter "PARENT == $mac_inst"] + + if {[llength $prescale_ffs]} { + set_property ASYNC_REG TRUE $prescale_ffs + + set src_clk [get_clocks -of_objects [get_pins $mac_inst/rx_prescale_reg[2]/C]] + + set_max_delay -from [get_cells $mac_inst/rx_prescale_reg[2]] -to [get_cells $mac_inst/rx_prescale_sync_reg[0]] -datapath_only [get_property -min PERIOD $src_clk] + } +} diff --git a/syn/eth_mac_fifo.tcl b/syn/eth_mac_fifo.tcl new file mode 100644 index 000000000..daa072456 --- /dev/null +++ b/syn/eth_mac_fifo.tcl @@ -0,0 +1,48 @@ +# Copyright (c) 2019 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. + +# Ethernet MAC with FIFO timing constraints + +foreach mac_inst [get_cells -hier -filter {(ORIG_REF_NAME == eth_mac_1g_fifo || REF_NAME == eth_mac_1g_fifo || \ + ORIG_REF_NAME == eth_mac_10g_fifo || REF_NAME == eth_mac_10g_fifo || \ + ORIG_REF_NAME == eth_mac_1g_gmii_fifo || REF_NAME == eth_mac_1g_gmii_fifo || \ + ORIG_REF_NAME == eth_mac_1g_rgmii_fifo || REF_NAME == eth_mac_1g_rgmii_fifo)}] { + puts "Inserting timing constraints for ethernet MAC with FIFO instance $mac_inst" + + set sync_ffs [get_cells -hier -regexp ".*/rx_sync_reg_\[1234\]_reg\\\[\\d+\\\]" -filter "PARENT == $mac_inst"] + + if {[llength $sync_ffs]} { + set_property ASYNC_REG TRUE $sync_ffs + + set src_clk [get_clocks -of_objects [get_pins $mac_inst/rx_sync_reg_1_reg[*]/C]] + + set_max_delay -from [get_cells $mac_inst/rx_sync_reg_1_reg[*]] -to [get_cells $mac_inst/rx_sync_reg_2_reg[*]] -datapath_only [get_property -min PERIOD $src_clk] + } + + set sync_ffs [get_cells -hier -regexp ".*/tx_sync_reg_\[1234\]_reg\\\[\\d+\\\]" -filter "PARENT == $mac_inst"] + + if {[llength $sync_ffs]} { + set_property ASYNC_REG TRUE $sync_ffs + + set src_clk [get_clocks -of_objects [get_pins $mac_inst/tx_sync_reg_1_reg[*]/C]] + + set_max_delay -from [get_cells $mac_inst/tx_sync_reg_1_reg[*]] -to [get_cells $mac_inst/tx_sync_reg_2_reg[*]] -datapath_only [get_property -min PERIOD $src_clk] + } +} diff --git a/syn/gmii_phy_if.tcl b/syn/gmii_phy_if.tcl new file mode 100644 index 000000000..f20ccc1fa --- /dev/null +++ b/syn/gmii_phy_if.tcl @@ -0,0 +1,31 @@ +# Copyright (c) 2019 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. + +# GMII PHY IF timing constraints + +foreach if_inst [get_cells -hier -filter {(ORIG_REF_NAME == gmii_phy_if || REF_NAME == gmii_phy_if)}] { + puts "Inserting timing constraints for gmii_phy_if instance $if_inst" + + # reset synchronization + set reset_ffs [get_cells -hier -regexp ".*/(rx|tx)_rst_reg_reg\\\[\\d\\\]" -filter "PARENT == $if_inst"] + + set_property ASYNC_REG TRUE $reset_ffs + set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}] +} diff --git a/syn/rgmii_phy_if.tcl b/syn/rgmii_phy_if.tcl new file mode 100644 index 000000000..57105081d --- /dev/null +++ b/syn/rgmii_phy_if.tcl @@ -0,0 +1,39 @@ +# Copyright (c) 2019 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. + +# RGMII PHY IF timing constraints + +foreach if_inst [get_cells -hier -filter {(ORIG_REF_NAME == rgmii_phy_if || REF_NAME == rgmii_phy_if)}] { + puts "Inserting timing constraints for rgmii_phy_if instance $if_inst" + + # reset synchronization + set reset_ffs [get_cells -hier -regexp ".*/(rx|tx)_rst_reg_reg\\\[\\d\\\]" -filter "PARENT == $if_inst"] + + set_property ASYNC_REG TRUE $reset_ffs + set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}] + + # clock output + set_property ASYNC_REG TRUE [get_cells $if_inst/clk_oddr_inst/oddr[0].oddr_inst] + + set src_clk [get_clocks -of_objects [get_pins $if_inst/rgmii_tx_clk_1_reg/C]] + + set_max_delay -from [get_cells $if_inst/rgmii_tx_clk_1_reg] -to [get_cells $if_inst/clk_oddr_inst/oddr[0].oddr_inst] -datapath_only [expr [get_property -min PERIOD $src_clk]/4] + set_max_delay -from [get_cells $if_inst/rgmii_tx_clk_2_reg] -to [get_cells $if_inst/clk_oddr_inst/oddr[0].oddr_inst] -datapath_only [expr [get_property -min PERIOD $src_clk]/4] +} From e120a8560748e56c05d39363edf240f4525a71ad Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 17:56:55 -0700 Subject: [PATCH 547/617] Use correct clock --- example/VCU108/fpga_10g/rtl/fpga.v | 8 ++++---- example/VCU118/fpga_10g/rtl/fpga.v | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/example/VCU108/fpga_10g/rtl/fpga.v b/example/VCU108/fpga_10g/rtl/fpga.v index 4aecc407b..99a9ee0e1 100644 --- a/example/VCU108/fpga_10g/rtl/fpga.v +++ b/example/VCU108/fpga_10g/rtl/fpga.v @@ -218,11 +218,11 @@ wire [3:0] sw_int; debounce_switch #( .WIDTH(9), .N(4), - .RATE(125000) + .RATE(156000) ) debounce_switch_inst ( - .clk(clk_125mhz_int), - .rst(rst_125mhz_int), + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), .in({btnu, btnl, btnd, @@ -245,7 +245,7 @@ sync_signal #( .N(2) ) sync_signal_inst ( - .clk(clk_125mhz_int), + .clk(clk_156mhz_int), .in({uart_rxd, uart_cts}), .out({uart_rxd_int, uart_cts_int}) ); diff --git a/example/VCU118/fpga_10g/rtl/fpga.v b/example/VCU118/fpga_10g/rtl/fpga.v index 7ffe4ac34..4009e488f 100644 --- a/example/VCU118/fpga_10g/rtl/fpga.v +++ b/example/VCU118/fpga_10g/rtl/fpga.v @@ -248,11 +248,11 @@ wire [3:0] sw_int; debounce_switch #( .WIDTH(9), .N(4), - .RATE(125000) + .RATE(156000) ) debounce_switch_inst ( - .clk(clk_125mhz_int), - .rst(rst_125mhz_int), + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), .in({btnu, btnl, btnd, @@ -275,7 +275,7 @@ sync_signal #( .N(2) ) sync_signal_inst ( - .clk(clk_125mhz_int), + .clk(clk_156mhz_int), .in({uart_rxd, uart_cts}), .out({uart_rxd_int, uart_cts_int}) ); From 0ca8c9a59b5b8b603f3664e7093da4221e061292 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 17:59:30 -0700 Subject: [PATCH 548/617] Update example design timing constraints --- example/ADM_PCIE_9V3/fpga_10g/fpga.xdc | 5 ----- example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile | 2 ++ example/ExaNIC_X10/fpga/fpga.xdc | 3 --- example/ExaNIC_X10/fpga/fpga/Makefile | 2 ++ example/NexysVideo/fpga/fpga.xdc | 2 -- example/NexysVideo/fpga/fpga/Makefile | 4 ++++ example/VCU108/fpga_10g/clock.xdc | 4 ---- example/VCU108/fpga_10g/fpga.xdc | 5 ----- example/VCU108/fpga_10g/fpga/Makefile | 3 ++- example/VCU108/fpga_1g/fpga.xdc | 5 ----- example/VCU108/fpga_1g/fpga/Makefile | 2 ++ example/VCU118/fpga_10g/clock.xdc | 4 ---- example/VCU118/fpga_10g/fpga.xdc | 10 +--------- example/VCU118/fpga_10g/fpga/Makefile | 3 ++- example/VCU118/fpga_1g/fpga.xdc | 10 +--------- example/VCU118/fpga_1g/fpga/Makefile | 2 ++ 16 files changed, 18 insertions(+), 48 deletions(-) delete mode 100644 example/VCU108/fpga_10g/clock.xdc delete mode 100644 example/VCU118/fpga_10g/clock.xdc diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga.xdc b/example/ADM_PCIE_9V3/fpga_10g/fpga.xdc index e5783955a..0ba473e92 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/fpga.xdc +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga.xdc @@ -16,7 +16,6 @@ set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design] set_property -dict {LOC AP26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_p] set_property -dict {LOC AP27 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_n] create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p] -set_clock_groups -asynchronous -group [get_clocks clk_300mhz -include_generated_clocks] # LEDs set_property -dict {LOC AT27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[0]}] @@ -59,7 +58,6 @@ set_property -dict {LOC D31 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports # 161.1328125 MHz MGT reference clock create_clock -period 6.206 -name qsfp_0_mgt_refclk [get_ports qsfp_0_mgt_refclk_p] -set_clock_groups -asynchronous -group [get_clocks qsfp_0_mgt_refclk -include_generated_clocks] set_property -dict {LOC R38 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 #set_property -dict {LOC R39 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 @@ -84,7 +82,6 @@ set_property -dict {LOC D30 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports # 161.1328125 MHz MGT reference clock create_clock -period 6.206 -name qsfp_1_mgt_refclk [get_ports qsfp_1_mgt_refclk_p] -set_clock_groups -asynchronous -group [get_clocks qsfp_1_mgt_refclk -include_generated_clocks] set_property -dict {LOC B29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_reset_l] set_property -dict {LOC C29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_int_l] @@ -165,9 +162,7 @@ set_property -dict {LOC C29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports # 100 MHz MGT reference clock #create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_1_p] -#set_clock_groups -asynchronous -group [get_clocks pcie_mgt_refclk_1 -include_generated_clocks] #create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p] -#set_clock_groups -asynchronous -group [get_clocks pcie_mgt_refclk_2 -include_generated_clocks] # QSPI flash #set_property -dict {LOC AB10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi_clk}] diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile index 8e53e10e6..440aef95e 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -46,6 +46,8 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl # IP XCI_FILES += ip/gtwizard_ultrascale_0.xci diff --git a/example/ExaNIC_X10/fpga/fpga.xdc b/example/ExaNIC_X10/fpga/fpga.xdc index 1f14f4575..b65411da0 100644 --- a/example/ExaNIC_X10/fpga/fpga.xdc +++ b/example/ExaNIC_X10/fpga/fpga.xdc @@ -14,7 +14,6 @@ set_property CONFIG_MODE BPI16 [current_design] set_property -dict {LOC D18 IOSTANDARD LVDS} [get_ports clk_100mhz_p] set_property -dict {LOC C18 IOSTANDARD LVDS} [get_ports clk_100mhz_n] create_clock -period 10 -name clk_100mhz [get_ports clk_100mhz_p] -set_clock_groups -asynchronous -group [get_clocks clk_100mhz -include_generated_clocks] # LEDs set_property -dict {LOC A25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_1_led[0]}] @@ -61,7 +60,6 @@ set_property -dict {LOC D25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports # 161.1328125 MHz MGT reference clock create_clock -period 6.206 -name sfp_mgt_refclk [get_ports sfp_mgt_refclk_p] -set_clock_groups -asynchronous -group [get_clocks sfp_mgt_refclk -include_generated_clocks] # I2C interface #set_property -dict {LOC B26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_scl] @@ -106,7 +104,6 @@ set_clock_groups -asynchronous -group [get_clocks sfp_mgt_refclk -include_genera # 100 MHz MGT reference clock #create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_mgt_refclk_p] -#set_clock_groups -asynchronous -group [get_clocks pcie_mgt_refclk -include_generated_clocks] # Flash #set_property -dict {LOC AE10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[0]}] diff --git a/example/ExaNIC_X10/fpga/fpga/Makefile b/example/ExaNIC_X10/fpga/fpga/Makefile index 998b8557d..4838540a3 100644 --- a/example/ExaNIC_X10/fpga/fpga/Makefile +++ b/example/ExaNIC_X10/fpga/fpga/Makefile @@ -45,6 +45,8 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl # IP XCI_FILES = ip/gtwizard_ultrascale_0.xci diff --git a/example/NexysVideo/fpga/fpga.xdc b/example/NexysVideo/fpga/fpga.xdc index f66c951df..2b5c9d3cd 100644 --- a/example/NexysVideo/fpga/fpga.xdc +++ b/example/NexysVideo/fpga/fpga.xdc @@ -9,7 +9,6 @@ set_property BITSTREAM.GENERAL.COMPRESS true [current_design] # 100 MHz clock set_property -dict {LOC R4 IOSTANDARD LVCMOS33} [get_ports clk] create_clock -period 10.000 -name clk [get_ports clk] -set_clock_groups -asynchronous -group [get_clocks clk -include_generated_clocks] # LEDs set_property -dict {LOC T14 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[0]}] @@ -65,5 +64,4 @@ set_property -dict {LOC W14 IOSTANDARD LVCMOS25} [get_ports phy_pme_n] #set_property -dict {LOC AA16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports phy_mdc] create_clock -period 8.000 -name phy_rx_clk [get_ports phy_rx_clk] -set_clock_groups -asynchronous -group [get_clocks phy_rx_clk -include_generated_clocks] diff --git a/example/NexysVideo/fpga/fpga/Makefile b/example/NexysVideo/fpga/fpga/Makefile index 744125aca..b54be3306 100644 --- a/example/NexysVideo/fpga/fpga/Makefile +++ b/example/NexysVideo/fpga/fpga/Makefile @@ -46,6 +46,10 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc XDC_FILES += eth.xdc +XDC_FILES += lib/eth/syn/rgmii_phy_if.tcl +XDC_FILES += lib/eth/syn/eth_mac_1g_rgmii.tcl +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl include ../common/vivado.mk diff --git a/example/VCU108/fpga_10g/clock.xdc b/example/VCU108/fpga_10g/clock.xdc deleted file mode 100644 index bf52c8f3b..000000000 --- a/example/VCU108/fpga_10g/clock.xdc +++ /dev/null @@ -1,4 +0,0 @@ -# Clock constraints - -# internal clock groups -set_clock_groups -asynchronous -group [get_clocks -of_objects [get_nets clk_156mhz_int]] diff --git a/example/VCU108/fpga_10g/fpga.xdc b/example/VCU108/fpga_10g/fpga.xdc index 3412bfd56..049fa76fa 100644 --- a/example/VCU108/fpga_10g/fpga.xdc +++ b/example/VCU108/fpga_10g/fpga.xdc @@ -11,23 +11,19 @@ set_property BITSTREAM.GENERAL.COMPRESS true [current_design] #set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p] #set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n] #create_clock -period 3.333 -name clk_300mhz_1 [get_ports clk_300mhz_1_p] -#set_clock_groups -asynchronous -group [get_clocks clk_300mhz_1 -include_generated_clocks] #set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p] #set_property -dict {LOC G21 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_n] #create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p] -#set_clock_groups -asynchronous -group [get_clocks clk_300mhz_2 -include_generated_clocks] # 125 MHz set_property -dict {LOC BC9 IOSTANDARD LVDS} [get_ports clk_125mhz_p] set_property -dict {LOC BC8 IOSTANDARD LVDS} [get_ports clk_125mhz_n] create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] -set_clock_groups -asynchronous -group [get_clocks clk_125mhz -include_generated_clocks] # 90 MHz #set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] #create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] -#set_clock_groups -asynchronous -group [get_clocks clk_90mhz -include_generated_clocks] # LEDs set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] @@ -75,7 +71,6 @@ set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports phy_int_n] # 625 MHz ref clock from SGMII PHY create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] -set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generated_clocks] # QSFP+ Interface set_property -dict {LOC AG45} [get_ports qsfp_rx1_p] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 189ef49bb..12d080c3e 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -48,8 +48,9 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc -XDC_FILES += clock.xdc XDC_FILES += eth.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl # IP XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci diff --git a/example/VCU108/fpga_1g/fpga.xdc b/example/VCU108/fpga_1g/fpga.xdc index c9ec17ff2..e3b15a5f9 100644 --- a/example/VCU108/fpga_1g/fpga.xdc +++ b/example/VCU108/fpga_1g/fpga.xdc @@ -11,23 +11,19 @@ set_property BITSTREAM.GENERAL.COMPRESS true [current_design] #set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p] #set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n] #create_clock -period 3.333 -name clk_300mhz_1 [get_ports clk_300mhz_1_p] -#set_clock_groups -asynchronous -group [get_clocks clk_300mhz_1 -include_generated_clocks] #set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p] #set_property -dict {LOC G21 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_n] #create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p] -#set_clock_groups -asynchronous -group [get_clocks clk_300mhz_2 -include_generated_clocks] # 125 MHz set_property -dict {LOC BC9 IOSTANDARD LVDS} [get_ports clk_125mhz_p] set_property -dict {LOC BC8 IOSTANDARD LVDS} [get_ports clk_125mhz_n] create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] -set_clock_groups -asynchronous -group [get_clocks clk_125mhz -include_generated_clocks] # 90 MHz #set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] #create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] -#set_clock_groups -asynchronous -group [get_clocks clk_90mhz -include_generated_clocks] # LEDs set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] @@ -75,5 +71,4 @@ set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports phy_int_n] # 625 MHz ref clock from SGMII PHY create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] -set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generated_clocks] diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index 299cf00d4..3a815ba1d 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -40,6 +40,8 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc XDC_FILES += eth.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl # IP XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci diff --git a/example/VCU118/fpga_10g/clock.xdc b/example/VCU118/fpga_10g/clock.xdc deleted file mode 100644 index bf52c8f3b..000000000 --- a/example/VCU118/fpga_10g/clock.xdc +++ /dev/null @@ -1,4 +0,0 @@ -# Clock constraints - -# internal clock groups -set_clock_groups -asynchronous -group [get_clocks -of_objects [get_nets clk_156mhz_int]] diff --git a/example/VCU118/fpga_10g/fpga.xdc b/example/VCU118/fpga_10g/fpga.xdc index 5dd36a0b6..6267607c6 100644 --- a/example/VCU118/fpga_10g/fpga.xdc +++ b/example/VCU118/fpga_10g/fpga.xdc @@ -11,29 +11,24 @@ set_property BITSTREAM.GENERAL.COMPRESS true [current_design] #set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_p] #set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_n] #create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p] -#set_clock_groups -asynchronous -group [get_clocks clk_300mhz -include_generated_clocks] # 250 MHz #set_property -dict {LOC E12 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_1_p] #set_property -dict {LOC D12 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_1_n] #create_clock -period 4 -name clk_250mhz_1 [get_ports clk_250mhz_1_p] -#set_clock_groups -asynchronous -group [get_clocks clk_250mhz_1 -include_generated_clocks] #set_property -dict {LOC AW26 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_2_p] #set_property -dict {LOC AW27 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_2_n] #create_clock -period 4 -name clk_250mhz_2 [get_ports clk_250mhz_2_p] -#set_clock_groups -asynchronous -group [get_clocks clk_250mhz_2 -include_generated_clocks] # 125 MHz set_property -dict {LOC AY24 IOSTANDARD LVDS} [get_ports clk_125mhz_p] set_property -dict {LOC AY23 IOSTANDARD LVDS} [get_ports clk_125mhz_n] create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] -set_clock_groups -asynchronous -group [get_clocks clk_125mhz -include_generated_clocks] # 90 MHz #set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] #create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] -#set_clock_groups -asynchronous -group [get_clocks clk_90mhz -include_generated_clocks] # LEDs set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] @@ -80,8 +75,7 @@ set_property -dict {LOC AR23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports p set_property -dict {LOC AV23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc] # 625 MHz ref clock from SGMII PHY -create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] -set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generated_clocks] +#create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] # QSFP28 Interfaces set_property -dict {LOC V7 } [get_ports qsfp1_tx1_p] ;# MGTYTXN0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 @@ -114,7 +108,6 @@ set_property -dict {LOC AN21 IOSTANDARD LVCMOS18} [get_ports qsfp1_lpmode] # 156.25 MHz MGT reference clock create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p] -set_clock_groups -asynchronous -group [get_clocks qsfp1_mgt_refclk_0 -include_generated_clocks] set_property -dict {LOC L5 } [get_ports qsfp2_tx1_p] ;# MGTYTXN0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 #set_property -dict {LOC L4 } [get_ports qsfp2_tx1_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 @@ -146,7 +139,6 @@ set_property -dict {LOC AT24 IOSTANDARD LVCMOS18} [get_ports qsfp2_lpmode] # 156.25 MHz MGT reference clock #create_clock -period 6.400 -name qsfp2_mgt_refclk_0 [get_ports qsfp2_mgt_refclk_0_p] -#set_clock_groups -asynchronous -group [get_clocks qsfp2_mgt_refclk_0 -include_generated_clocks] # I2C interface set_property -dict {LOC AM24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_scl] diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile index 37f715b9a..95d9c5219 100644 --- a/example/VCU118/fpga_10g/fpga/Makefile +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -54,7 +54,8 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc -XDC_FILES += clock.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl # IP XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci diff --git a/example/VCU118/fpga_1g/fpga.xdc b/example/VCU118/fpga_1g/fpga.xdc index 46e9e7d25..42e39f369 100644 --- a/example/VCU118/fpga_1g/fpga.xdc +++ b/example/VCU118/fpga_1g/fpga.xdc @@ -11,29 +11,24 @@ set_property BITSTREAM.GENERAL.COMPRESS true [current_design] #set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_p] #set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_n] #create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p] -#set_clock_groups -asynchronous -group [get_clocks clk_300mhz -include_generated_clocks] # 250 MHz #set_property -dict {LOC E12 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_1_p] #set_property -dict {LOC D12 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_1_n] #create_clock -period 4 -name clk_250mhz_1 [get_ports clk_250mhz_1_p] -#set_clock_groups -asynchronous -group [get_clocks clk_250mhz_1 -include_generated_clocks] #set_property -dict {LOC AW26 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_2_p] #set_property -dict {LOC AW27 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_2_n] #create_clock -period 4 -name clk_250mhz_2 [get_ports clk_250mhz_2_p] -#set_clock_groups -asynchronous -group [get_clocks clk_250mhz_2 -include_generated_clocks] # 125 MHz set_property -dict {LOC AY24 IOSTANDARD LVDS} [get_ports clk_125mhz_p] set_property -dict {LOC AY23 IOSTANDARD LVDS} [get_ports clk_125mhz_n] create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] -set_clock_groups -asynchronous -group [get_clocks clk_125mhz -include_generated_clocks] # 90 MHz #set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] #create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] -#set_clock_groups -asynchronous -group [get_clocks clk_90mhz -include_generated_clocks] # LEDs set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] @@ -80,8 +75,7 @@ set_property -dict {LOC AR23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports p set_property -dict {LOC AV23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc] # 625 MHz ref clock from SGMII PHY -create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] -set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generated_clocks] +#create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] # QSFP28 Interfaces #set_property -dict {LOC V7 } [get_ports qsfp1_tx1_p] ;# MGTYTXN0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 @@ -114,7 +108,6 @@ set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generat # 156.25 MHz MGT reference clock #create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p] -#set_clock_groups -asynchronous -group [get_clocks qsfp1_mgt_refclk_0 -include_generated_clocks] #set_property -dict {LOC L5 } [get_ports qsfp2_tx1_p] ;# MGTYTXN0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 #set_property -dict {LOC L4 } [get_ports qsfp2_tx1_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 @@ -146,7 +139,6 @@ set_clock_groups -asynchronous -group [get_clocks phy_sgmii_clk -include_generat # 156.25 MHz MGT reference clock #create_clock -period 6.400 -name qsfp2_mgt_refclk_0 [get_ports qsfp2_mgt_refclk_0_p] -#set_clock_groups -asynchronous -group [get_clocks qsfp2_mgt_refclk_0 -include_generated_clocks] # I2C interface #set_property -dict {LOC AM24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_scl] diff --git a/example/VCU118/fpga_1g/fpga/Makefile b/example/VCU118/fpga_1g/fpga/Makefile index 834f771ba..15000e344 100644 --- a/example/VCU118/fpga_1g/fpga/Makefile +++ b/example/VCU118/fpga_1g/fpga/Makefile @@ -40,6 +40,8 @@ SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v # XDC files XDC_FILES = fpga.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl # IP XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci From 8e2d93688448e35d89c371762bc5e65990d1fd50 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 19:18:03 -0700 Subject: [PATCH 549/617] Add MII PHY interface, MAC wrappers, and testbenches --- rtl/eth_mac_mii.v | 166 ++++++++++++++++++ rtl/eth_mac_mii_fifo.v | 312 ++++++++++++++++++++++++++++++++++ rtl/mii_phy_if.v | 137 +++++++++++++++ syn/eth_mac_fifo.tcl | 3 +- syn/mii_phy_if.tcl | 31 ++++ tb/mii_ep.py | 262 +++++++++++++++++++++++++++++ tb/test_eth_mac_mii.py | 301 +++++++++++++++++++++++++++++++++ tb/test_eth_mac_mii.v | 148 +++++++++++++++++ tb/test_eth_mac_mii_fifo.py | 323 ++++++++++++++++++++++++++++++++++++ tb/test_eth_mac_mii_fifo.v | 167 +++++++++++++++++++ 10 files changed, 1849 insertions(+), 1 deletion(-) create mode 100644 rtl/eth_mac_mii.v create mode 100644 rtl/eth_mac_mii_fifo.v create mode 100644 rtl/mii_phy_if.v create mode 100644 syn/mii_phy_if.tcl create mode 100644 tb/mii_ep.py create mode 100755 tb/test_eth_mac_mii.py create mode 100644 tb/test_eth_mac_mii.v create mode 100755 tb/test_eth_mac_mii_fifo.py create mode 100644 tb/test_eth_mac_mii_fifo.v diff --git a/rtl/eth_mac_mii.v b/rtl/eth_mac_mii.v new file mode 100644 index 000000000..75c1f86c9 --- /dev/null +++ b/rtl/eth_mac_mii.v @@ -0,0 +1,166 @@ +/* + +Copyright (c) 2019 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 + +/* + * 10M/100M Ethernet MAC with MII interface + */ +module eth_mac_mii # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire rst, + output wire rx_clk, + output wire rx_rst, + output wire tx_clk, + output wire tx_rst, + + /* + * AXI input + */ + input wire [7:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] rx_axis_tdata, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * MII interface + */ + input wire mii_rx_clk, + input wire [3:0] mii_rxd, + input wire mii_rx_dv, + input wire mii_rx_er, + input wire mii_tx_clk, + output wire [3:0] mii_txd, + output wire mii_tx_en, + output wire mii_tx_er, + + /* + * Status + */ + output wire tx_start_packet, + output wire tx_error_underflow, + output wire rx_start_packet, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +wire [3:0] mac_mii_rxd; +wire mac_mii_rx_dv; +wire mac_mii_rx_er; +wire [3:0] mac_mii_txd; +wire mac_mii_tx_en; +wire mac_mii_tx_er; + +mii_phy_if #( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE) +) +mii_phy_if_inst ( + .rst(rst), + + .mac_mii_rx_clk(rx_clk), + .mac_mii_rx_rst(rx_rst), + .mac_mii_rxd(mac_mii_rxd), + .mac_mii_rx_dv(mac_mii_rx_dv), + .mac_mii_rx_er(mac_mii_rx_er), + .mac_mii_tx_clk(tx_clk), + .mac_mii_tx_rst(tx_rst), + .mac_mii_txd(mac_mii_txd), + .mac_mii_tx_en(mac_mii_tx_en), + .mac_mii_tx_er(mac_mii_tx_er), + + .phy_mii_rx_clk(mii_rx_clk), + .phy_mii_rxd(mii_rxd), + .phy_mii_rx_dv(mii_rx_dv), + .phy_mii_rx_er(mii_rx_er), + .phy_mii_tx_clk(mii_tx_clk), + .phy_mii_txd(mii_txd), + .phy_mii_tx_en(mii_tx_en), + .phy_mii_tx_er(mii_tx_er) +); + +eth_mac_1g #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .gmii_rxd(mac_mii_rxd), + .gmii_rx_dv(mac_mii_rx_dv), + .gmii_rx_er(mac_mii_rx_er), + .gmii_txd(mac_mii_txd), + .gmii_tx_en(mac_mii_tx_en), + .gmii_tx_er(mac_mii_tx_er), + .rx_clk_enable(1'b1), + .tx_clk_enable(1'b1), + .rx_mii_select(1'b1), + .tx_mii_select(1'b1), + .tx_start_packet(tx_start_packet), + .tx_error_underflow(tx_error_underflow), + .rx_start_packet(rx_start_packet), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/rtl/eth_mac_mii_fifo.v b/rtl/eth_mac_mii_fifo.v new file mode 100644 index 000000000..56dd9ae99 --- /dev/null +++ b/rtl/eth_mac_mii_fifo.v @@ -0,0 +1,312 @@ +/* + +Copyright (c) 2019 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 + +/* + * 10M/100M Ethernet MAC with MII interface and TX and RX FIFOs + */ +module eth_mac_mii_fifo # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter TX_FIFO_ADDR_WIDTH = 12, + parameter TX_FRAME_FIFO = 1, + parameter TX_DROP_BAD_FRAME = TX_FRAME_FIFO, + parameter TX_DROP_WHEN_FULL = 0, + parameter RX_FIFO_ADDR_WIDTH = 12, + parameter RX_FRAME_FIFO = 1, + parameter RX_DROP_BAD_FRAME = RX_FRAME_FIFO, + parameter RX_DROP_WHEN_FULL = RX_FRAME_FIFO +) +( + input wire rst, + input wire logic_clk, + input wire logic_rst, + + /* + * AXI input + */ + input wire [7:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] rx_axis_tdata, + output wire rx_axis_tvalid, + input wire rx_axis_tready, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * MII interface + */ + input wire mii_rx_clk, + input wire [3:0] mii_rxd, + input wire mii_rx_dv, + input wire mii_rx_er, + input wire mii_tx_clk, + output wire [3:0] mii_txd, + output wire mii_tx_en, + output wire mii_tx_er, + + /* + * Status + */ + output wire tx_error_underflow, + output wire tx_fifo_overflow, + output wire tx_fifo_bad_frame, + output wire tx_fifo_good_frame, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_fifo_overflow, + output wire rx_fifo_bad_frame, + output wire rx_fifo_good_frame, + + /* + * Configuration + */ + input wire [7:0] ifg_delay +); + +wire tx_clk; +wire rx_clk; +wire tx_rst; +wire rx_rst; + +wire [7:0] tx_fifo_axis_tdata; +wire tx_fifo_axis_tvalid; +wire tx_fifo_axis_tready; +wire tx_fifo_axis_tlast; +wire tx_fifo_axis_tuser; + +wire [7:0] rx_fifo_axis_tdata; +wire rx_fifo_axis_tvalid; +wire rx_fifo_axis_tlast; +wire rx_fifo_axis_tuser; + +// synchronize MAC status signals into logic clock domain +wire tx_error_underflow_int; + +reg [0:0] tx_sync_reg_1 = 1'b0; +reg [0:0] tx_sync_reg_2 = 1'b0; +reg [0:0] tx_sync_reg_3 = 1'b0; +reg [0:0] tx_sync_reg_4 = 1'b0; + +assign tx_error_underflow = tx_sync_reg_3[0] ^ tx_sync_reg_4[0]; + +always @(posedge tx_clk or posedge tx_rst) begin + if (tx_rst) begin + tx_sync_reg_1 <= 1'b0; + end else begin + tx_sync_reg_1 <= tx_sync_reg_1 ^ {tx_error_underflow_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + tx_sync_reg_2 <= 1'b0; + tx_sync_reg_3 <= 1'b0; + tx_sync_reg_4 <= 1'b0; + end else begin + tx_sync_reg_2 <= tx_sync_reg_1; + tx_sync_reg_3 <= tx_sync_reg_2; + tx_sync_reg_4 <= tx_sync_reg_3; + end +end + +wire rx_error_bad_frame_int; +wire rx_error_bad_fcs_int; + +reg [1:0] rx_sync_reg_1 = 2'd0; +reg [1:0] rx_sync_reg_2 = 2'd0; +reg [1:0] rx_sync_reg_3 = 2'd0; +reg [1:0] rx_sync_reg_4 = 2'd0; + +assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; +assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; + +always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + rx_sync_reg_1 <= 2'd0; + end else begin + rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_error_bad_frame_int, rx_error_bad_frame_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + rx_sync_reg_2 <= 2'd0; + rx_sync_reg_3 <= 2'd0; + rx_sync_reg_4 <= 2'd0; + end else begin + rx_sync_reg_2 <= rx_sync_reg_1; + rx_sync_reg_3 <= rx_sync_reg_2; + rx_sync_reg_4 <= rx_sync_reg_3; + end +end + +eth_mac_mii #( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_mii_inst ( + .rst(rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_fifo_axis_tdata), + .tx_axis_tvalid(tx_fifo_axis_tvalid), + .tx_axis_tready(tx_fifo_axis_tready), + .tx_axis_tlast(tx_fifo_axis_tlast), + .tx_axis_tuser(tx_fifo_axis_tuser), + .rx_axis_tdata(rx_fifo_axis_tdata), + .rx_axis_tvalid(rx_fifo_axis_tvalid), + .rx_axis_tlast(rx_fifo_axis_tlast), + .rx_axis_tuser(rx_fifo_axis_tuser), + .mii_rx_clk(mii_rx_clk), + .mii_rxd(mii_rxd), + .mii_rx_dv(mii_rx_dv), + .mii_rx_er(mii_rx_er), + .mii_tx_clk(mii_tx_clk), + .mii_txd(mii_txd), + .mii_tx_en(mii_tx_en), + .mii_tx_er(mii_tx_er), + .tx_error_underflow(tx_error_underflow_int), + .rx_error_bad_frame(rx_error_bad_frame_int), + .rx_error_bad_fcs(rx_error_bad_fcs_int), + .ifg_delay(ifg_delay) +); + +axis_async_fifo #( + .ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .LAST_ENABLE(1), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(TX_FRAME_FIFO), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) +) +tx_fifo ( + // Common reset + .async_rst(logic_rst | tx_rst), + // AXI input + .s_clk(logic_clk), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(tx_axis_tuser), + // AXI output + .m_clk(tx_clk), + .m_axis_tdata(tx_fifo_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_axis_tvalid), + .m_axis_tready(tx_fifo_axis_tready), + .m_axis_tlast(tx_fifo_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_axis_tuser), + // Status + .s_status_overflow(tx_fifo_overflow), + .s_status_bad_frame(tx_fifo_bad_frame), + .s_status_good_frame(tx_fifo_good_frame), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() +); + +axis_async_fifo #( + .ADDR_WIDTH(RX_FIFO_ADDR_WIDTH), + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .LAST_ENABLE(1), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(TX_FRAME_FIFO), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) +) +rx_fifo ( + // Common reset + .async_rst(rx_rst | logic_rst), + // AXI input + .s_clk(rx_clk), + .s_axis_tdata(rx_fifo_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_axis_tvalid), + .s_axis_tready(), + .s_axis_tlast(rx_fifo_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_axis_tuser), + // AXI output + .m_clk(logic_clk), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tready(rx_axis_tready), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(rx_axis_tuser), + // Status + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(rx_fifo_overflow), + .m_status_bad_frame(rx_fifo_bad_frame), + .m_status_good_frame(rx_fifo_good_frame) +); + +endmodule diff --git a/rtl/mii_phy_if.v b/rtl/mii_phy_if.v new file mode 100644 index 000000000..0e8cb8ce2 --- /dev/null +++ b/rtl/mii_phy_if.v @@ -0,0 +1,137 @@ +/* + +Copyright (c) 2019 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 + +/* + * MII PHY interface + */ +module mii_phy_if # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2" +) +( + input wire rst, + + /* + * MII interface to MAC + */ + output wire mac_mii_rx_clk, + output wire mac_mii_rx_rst, + output wire [3:0] mac_mii_rxd, + output wire mac_mii_rx_dv, + output wire mac_mii_rx_er, + output wire mac_mii_tx_clk, + output wire mac_mii_tx_rst, + input wire [3:0] mac_mii_txd, + input wire mac_mii_tx_en, + input wire mac_mii_tx_er, + + /* + * MII interface to PHY + */ + input wire phy_mii_rx_clk, + input wire [3:0] phy_mii_rxd, + input wire phy_mii_rx_dv, + input wire phy_mii_rx_er, + input wire phy_mii_tx_clk, + output wire [3:0] phy_mii_txd, + output wire phy_mii_tx_en, + output wire phy_mii_tx_er +); + +ssio_sdr_in # +( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .WIDTH(6) +) +rx_ssio_sdr_inst ( + .input_clk(phy_mii_rx_clk), + .input_d({phy_mii_rxd, phy_mii_rx_dv, phy_mii_rx_er}), + .output_clk(mac_mii_rx_clk), + .output_q({mac_mii_rxd, mac_mii_rx_dv, mac_mii_rx_er}) +); + +(* IOB = "TRUE" *) +reg [3:0] phy_mii_txd_reg = 4'd0; +(* IOB = "TRUE" *) +reg phy_mii_tx_en_reg = 1'b0, phy_mii_tx_er_reg = 1'b0; + +assign phy_mii_txd = phy_mii_txd_reg; +assign phy_mii_tx_en = phy_mii_tx_en_reg; +assign phy_mii_tx_er = phy_mii_tx_er_reg; + +always @(posedge mac_mii_tx_clk) begin + phy_mii_txd_reg <= mac_mii_txd; + phy_mii_tx_en_reg <= mac_mii_tx_en; + phy_mii_tx_er_reg <= mac_mii_tx_er; +end + +generate + +if (TARGET == "XILINX") begin + BUFG + mii_bufg_inst ( + .I(phy_mii_tx_clk), + .O(mac_mii_tx_clk) + ); +end else begin + assign mac_mii_tx_clk = phy_mii_tx_clk; +end + +endgenerate + +// reset sync +reg [3:0] tx_rst_reg = 4'hf; +assign mac_mii_tx_rst = tx_rst_reg[0]; + +always @(posedge mac_mii_tx_clk or posedge rst) begin + if (rst) begin + tx_rst_reg <= 4'hf; + end else begin + tx_rst_reg <= {1'b0, tx_rst_reg[3:1]}; + end +end + +reg [3:0] rx_rst_reg = 4'hf; +assign mac_mii_rx_rst = rx_rst_reg[0]; + +always @(posedge mac_mii_rx_clk or posedge rst) begin + if (rst) begin + rx_rst_reg <= 4'hf; + end else begin + rx_rst_reg <= {1'b0, rx_rst_reg[3:1]}; + end +end + +endmodule diff --git a/syn/eth_mac_fifo.tcl b/syn/eth_mac_fifo.tcl index daa072456..69a06318e 100644 --- a/syn/eth_mac_fifo.tcl +++ b/syn/eth_mac_fifo.tcl @@ -23,7 +23,8 @@ foreach mac_inst [get_cells -hier -filter {(ORIG_REF_NAME == eth_mac_1g_fifo || REF_NAME == eth_mac_1g_fifo || \ ORIG_REF_NAME == eth_mac_10g_fifo || REF_NAME == eth_mac_10g_fifo || \ ORIG_REF_NAME == eth_mac_1g_gmii_fifo || REF_NAME == eth_mac_1g_gmii_fifo || \ - ORIG_REF_NAME == eth_mac_1g_rgmii_fifo || REF_NAME == eth_mac_1g_rgmii_fifo)}] { + ORIG_REF_NAME == eth_mac_1g_rgmii_fifo || REF_NAME == eth_mac_1g_rgmii_fifo || \ + ORIG_REF_NAME == eth_mac_mii_fifo || REF_NAME == eth_mac_mii_fifo)}] { puts "Inserting timing constraints for ethernet MAC with FIFO instance $mac_inst" set sync_ffs [get_cells -hier -regexp ".*/rx_sync_reg_\[1234\]_reg\\\[\\d+\\\]" -filter "PARENT == $mac_inst"] diff --git a/syn/mii_phy_if.tcl b/syn/mii_phy_if.tcl new file mode 100644 index 000000000..64f518200 --- /dev/null +++ b/syn/mii_phy_if.tcl @@ -0,0 +1,31 @@ +# Copyright (c) 2019 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. + +# MII PHY IF timing constraints + +foreach if_inst [get_cells -hier -filter {(ORIG_REF_NAME == mii_phy_if || REF_NAME == mii_phy_if)}] { + puts "Inserting timing constraints for mii_phy_if instance $if_inst" + + # reset synchronization + set reset_ffs [get_cells -hier -regexp ".*/(rx|tx)_rst_reg_reg\\\[\\d\\\]" -filter "PARENT == $if_inst"] + + set_property ASYNC_REG TRUE $reset_ffs + set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}] +} diff --git a/tb/mii_ep.py b/tb/mii_ep.py new file mode 100644 index 000000000..64c4a09b9 --- /dev/null +++ b/tb/mii_ep.py @@ -0,0 +1,262 @@ +""" + +Copyright (c) 2019 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 * + +class MIIFrame(object): + def __init__(self, data=b'', error=None): + self.data = b'' + self.error = None + + if type(data) is MIIFrame: + self.data = data.data + self.error = data.error + else: + self.data = bytearray(data) + + def build(self): + if self.data is None: + return + + f = list(self.data) + d = [] + er = [] + i = 0 + + assert_er = False + if (type(self.error) is int or type(self.error) is bool) and self.error: + assert_er = True + self.error = None + + while len(f) > 0: + db = f.pop(0) + d.append(db & 0x0f) + d.append(db >> 4) + if self.error is None: + er.append(0) + er.append(0) + else: + er.append(self.error[i]) + er.append(self.error[i]) + i += 1 + + if assert_er: + er[-1] = 1 + self.error = 1 + + return d, er + + def parse(self, d, er): + if d is None or er is None: + return + + # sync and repack data + odd = True + sync = False + b = 0 + be = 0 + d2 = [] + er2 = [] + for n, e in zip(d, er): + odd = not odd + b = (n & 0x0F) << 4 | b >> 4 + be |= e + if not sync and b == 0xD5: + odd = True + sync = True + if odd: + d2.append(b) + er2.append(be) + be = False + + self.data = bytearray(d2) + self.error = er2 + + def __eq__(self, other): + if type(other) is MIIFrame: + return self.data == other.data + return False + + def __repr__(self): + return 'MIIFrame(data=%s, error=%s)' % (repr(self.data), repr(self.error)) + + def __iter__(self): + return self.data.__iter__() + + +class MIISource(object): + def __init__(self): + self.has_logic = False + self.queue = [] + + def send(self, frame): + self.queue.append(MIIFrame(frame)) + + def count(self): + return len(self.queue) + + def empty(self): + return not self.queue + + def create_logic(self, + clk, + rst, + txd, + tx_en, + tx_er, + clk_enable=True, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + assert len(txd) == 4 + + @instance + def logic(): + frame = None + d = [] + er = [] + ifg_cnt = 0 + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame = None + txd.next = 0 + tx_en.next = 0 + tx_er.next = 0 + d = [] + er = [] + ifg_cnt = 0 + else: + if not clk_enable: + pass + elif ifg_cnt > 0: + ifg_cnt -= 1 + txd.next = 0 + tx_er.next = 0 + tx_en.next = 0 + elif len(d) > 0: + txd.next = d.pop(0) + tx_er.next = er.pop(0) + tx_en.next = 1 + if len(d) == 0: + ifg_cnt = 12*2 + elif self.queue: + frame = MIIFrame(self.queue.pop(0)) + d, er = frame.build() + if name is not None: + print("[%s] Sending frame %s" % (name, repr(frame))) + txd.next = d.pop(0) + tx_er.next = er.pop(0) + tx_en.next = 1 + else: + txd.next = 0 + tx_er.next = 0 + tx_en.next = 0 + + return logic + + +class MIISink(object): + def __init__(self): + self.has_logic = False + self.queue = [] + self.sync = Signal(intbv(0)) + + def recv(self): + if self.queue: + return self.queue.pop(0) + return None + + def count(self): + return len(self.queue) + + def empty(self): + return not self.queue + + def wait(self, timeout=0): + if self.queue: + return + if timeout: + yield self.sync, delay(timeout) + else: + yield self.sync + + def create_logic(self, + clk, + rst, + rxd, + rx_dv, + rx_er, + clk_enable=True, + name=None + ): + + assert not self.has_logic + + self.has_logic = True + + assert len(rxd) == 4 + + @instance + def logic(): + frame = None + d = [] + er = [] + + while True: + yield clk.posedge, rst.posedge + + if rst: + frame = None + d = [] + er = [] + else: + if not clk_enable: + pass + elif rx_dv: + if frame is None: + frame = MIIFrame() + d = [] + er = [] + d.append(int(rxd)) + er.append(int(rx_er)) + elif frame is not None: + if len(d) > 0: + frame.parse(d, er) + self.queue.append(frame) + self.sync.next = not self.sync + if name is not None: + print("[%s] Got frame %s" % (name, repr(frame))) + frame = None + d = [] + er = [] + + return logic + diff --git a/tb/test_eth_mac_mii.py b/tb/test_eth_mac_mii.py new file mode 100755 index 000000000..23946b983 --- /dev/null +++ b/tb/test_eth_mac_mii.py @@ -0,0 +1,301 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep +import eth_ep +import mii_ep + +module = 'eth_mac_mii' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("../rtl/axis_gmii_rx.v") +srcs.append("../rtl/axis_gmii_tx.v") +srcs.append("../rtl/eth_mac_1g.v") +srcs.append("../rtl/mii_phy_if.v") +srcs.append("../rtl/ssio_sdr_in.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + TARGET = "SIM" + CLOCK_INPUT_STYLE = "BUFIO2" + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + tx_axis_tdata = Signal(intbv(0)[8:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + mii_rx_clk = Signal(bool(0)) + mii_rxd = Signal(intbv(0)[4:]) + mii_rx_dv = Signal(bool(0)) + mii_rx_er = Signal(bool(0)) + mii_tx_clk = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + rx_clk = Signal(bool(0)) + rx_rst = Signal(bool(0)) + tx_clk = Signal(bool(0)) + tx_rst = Signal(bool(0)) + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[8:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + mii_txd = Signal(intbv(0)[4:]) + mii_tx_en = Signal(bool(0)) + mii_tx_er = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + + # sources and sinks + axis_source_pause = Signal(bool(0)) + + + mii_source = mii_ep.MIISource() + + mii_source_logic = mii_source.create_logic( + mii_rx_clk, + rst, + txd=mii_rxd, + tx_en=mii_rx_dv, + tx_er=mii_rx_er, + name='mii_source' + ) + + mii_sink = mii_ep.MIISink() + + mii_sink_logic = mii_sink.create_logic( + mii_tx_clk, + rst, + rxd=mii_txd, + rx_dv=mii_tx_en, + rx_er=mii_tx_er, + name='mii_sink' + ) + + axis_source = axis_ep.AXIStreamSource() + + axis_source_logic = axis_source.create_logic( + mii_rx_clk, #tx_clk, + tx_rst, + tdata=tx_axis_tdata, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + pause=axis_source_pause, + name='axis_source' + ) + + axis_sink = axis_ep.AXIStreamSink() + + axis_sink_logic = axis_sink.create_logic( + mii_rx_clk, + rx_rst, + tdata=rx_axis_tdata, + tvalid=rx_axis_tvalid, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + name='axis_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, + + rx_clk=rx_clk, + rx_rst=rx_rst, + tx_clk=tx_clk, + tx_rst=tx_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + mii_rx_clk=mii_rx_clk, + mii_rxd=mii_rxd, + mii_rx_dv=mii_rx_dv, + mii_rx_er=mii_rx_er, + + mii_tx_clk=mii_tx_clk, + mii_txd=mii_txd, + mii_tx_en=mii_tx_en, + mii_tx_er=mii_tx_er, + + tx_error_underflow=tx_error_underflow, + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + phy_clk_hp = Signal(int(20)) + + @instance + def phy_clk_gen(): + while True: + yield delay(int(phy_clk_hp)) + mii_rx_clk.next = not mii_rx_clk + mii_tx_clk.next = not mii_rx_clk + + rx_error_bad_frame_asserted = Signal(bool(0)) + rx_error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_bad_frame): + rx_error_bad_frame_asserted.next = 1 + if (rx_error_bad_fcs): + rx_error_bad_fcs_asserted.next = 1 + + @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 + + ifg_delay.next = 12 + + # testbench stimulus + + for rate in [20, 200]: + phy_clk_hp.next = rate + + yield delay(1000) + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + mii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + yield axis_sink.wait() + rx_frame = axis_sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + + yield mii_sink.wait() + rx_frame = mii_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_mii.v b/tb/test_eth_mac_mii.v new file mode 100644 index 000000000..a4c2d97f6 --- /dev/null +++ b/tb/test_eth_mac_mii.v @@ -0,0 +1,148 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for eth_mac_mii + */ +module test_eth_mac_mii; + +// Parameters +parameter TARGET = "SIM"; +parameter CLOCK_INPUT_STYLE = "BUFIO2"; +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [7:0] tx_axis_tdata = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg mii_rx_clk = 0; +reg [3:0] mii_rxd = 0; +reg mii_rx_dv = 0; +reg mii_rx_er = 0; +reg mii_tx_clk = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire rx_clk; +wire rx_rst; +wire tx_clk; +wire tx_rst; +wire tx_axis_tready; +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire [3:0] mii_txd; +wire mii_tx_en; +wire mii_tx_er; +wire tx_error_underflow; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + mii_rx_clk, + mii_rxd, + mii_rx_dv, + mii_rx_er, + mii_tx_clk, + ifg_delay + ); + $to_myhdl( + rx_clk, + rx_rst, + tx_clk, + tx_rst, + tx_axis_tready, + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + mii_txd, + mii_tx_en, + mii_tx_er, + tx_error_underflow, + rx_error_bad_frame, + rx_error_bad_fcs + ); + + // dump file + $dumpfile("test_eth_mac_mii.lxt"); + $dumpvars(0, test_eth_mac_mii); +end + +eth_mac_mii #( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +UUT ( + .rst(rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .mii_rx_clk(mii_rx_clk), + .mii_rxd(mii_rxd), + .mii_rx_dv(mii_rx_dv), + .mii_rx_er(mii_rx_er), + .mii_tx_clk(mii_tx_clk), + .mii_txd(mii_txd), + .mii_tx_en(mii_tx_en), + .mii_tx_er(mii_tx_er), + .tx_error_underflow(tx_error_underflow), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .ifg_delay(ifg_delay) +); + +endmodule diff --git a/tb/test_eth_mac_mii_fifo.py b/tb/test_eth_mac_mii_fifo.py new file mode 100755 index 000000000..1192112f0 --- /dev/null +++ b/tb/test_eth_mac_mii_fifo.py @@ -0,0 +1,323 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep +import eth_ep +import mii_ep + +module = 'eth_mac_mii_fifo' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/lfsr.v") +srcs.append("../rtl/axis_gmii_rx.v") +srcs.append("../rtl/axis_gmii_tx.v") +srcs.append("../rtl/eth_mac_1g.v") +srcs.append("../rtl/eth_mac_mii.v") +srcs.append("../rtl/mii_phy_if.v") +srcs.append("../rtl/ssio_sdr_in.v") +srcs.append("../lib/axis/rtl/axis_async_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + TARGET = "SIM" + CLOCK_INPUT_STYLE = "BUFIO2" + ENABLE_PADDING = 1 + MIN_FRAME_LENGTH = 64 + TX_FIFO_ADDR_WIDTH = 9 + RX_FIFO_ADDR_WIDTH = 9 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + logic_clk = Signal(bool(0)) + logic_rst = Signal(bool(0)) + tx_axis_tdata = Signal(intbv(0)[8:]) + tx_axis_tvalid = Signal(bool(0)) + tx_axis_tlast = Signal(bool(0)) + tx_axis_tuser = Signal(bool(0)) + rx_axis_tready = Signal(bool(0)) + mii_rx_clk = Signal(bool(0)) + mii_rxd = Signal(intbv(0)[4:]) + mii_rx_dv = Signal(bool(0)) + mii_rx_er = Signal(bool(0)) + mii_tx_clk = Signal(bool(0)) + ifg_delay = Signal(intbv(0)[8:]) + + # Outputs + tx_axis_tready = Signal(bool(0)) + rx_axis_tdata = Signal(intbv(0)[8:]) + rx_axis_tvalid = Signal(bool(0)) + rx_axis_tlast = Signal(bool(0)) + rx_axis_tuser = Signal(bool(0)) + mii_txd = Signal(intbv(0)[4:]) + mii_tx_en = Signal(bool(0)) + mii_tx_er = Signal(bool(0)) + tx_error_underflow = Signal(bool(0)) + tx_fifo_overflow = Signal(bool(0)) + tx_fifo_bad_frame = Signal(bool(0)) + tx_fifo_good_frame = Signal(bool(0)) + rx_error_bad_frame = Signal(bool(0)) + rx_error_bad_fcs = Signal(bool(0)) + rx_fifo_overflow = Signal(bool(0)) + rx_fifo_bad_frame = Signal(bool(0)) + rx_fifo_good_frame = Signal(bool(0)) + + # sources and sinks + axis_source_pause = Signal(bool(0)) + axis_sink_pause = Signal(bool(0)) + + mii_source = mii_ep.MIISource() + + mii_source_logic = mii_source.create_logic( + mii_rx_clk, + rst, + txd=mii_rxd, + tx_en=mii_rx_dv, + tx_er=mii_rx_er, + name='mii_source' + ) + + mii_sink = mii_ep.MIISink() + + mii_sink_logic = mii_sink.create_logic( + mii_tx_clk, + rst, + rxd=mii_txd, + rx_dv=mii_tx_en, + rx_er=mii_tx_er, + name='mii_sink' + ) + + axis_source = axis_ep.AXIStreamSource() + + axis_source_logic = axis_source.create_logic( + logic_clk, + logic_rst, + tdata=tx_axis_tdata, + tvalid=tx_axis_tvalid, + tready=tx_axis_tready, + tlast=tx_axis_tlast, + tuser=tx_axis_tuser, + pause=axis_source_pause, + name='axis_source' + ) + + axis_sink = axis_ep.AXIStreamSink() + + axis_sink_logic = axis_sink.create_logic( + logic_clk, + logic_rst, + tdata=rx_axis_tdata, + tvalid=rx_axis_tvalid, + tready=rx_axis_tready, + tlast=rx_axis_tlast, + tuser=rx_axis_tuser, + pause=axis_sink_pause, + name='axis_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, + + logic_clk=logic_clk, + logic_rst=logic_rst, + + tx_axis_tdata=tx_axis_tdata, + tx_axis_tvalid=tx_axis_tvalid, + tx_axis_tready=tx_axis_tready, + tx_axis_tlast=tx_axis_tlast, + tx_axis_tuser=tx_axis_tuser, + + rx_axis_tdata=rx_axis_tdata, + rx_axis_tready=rx_axis_tready, + rx_axis_tvalid=rx_axis_tvalid, + rx_axis_tlast=rx_axis_tlast, + rx_axis_tuser=rx_axis_tuser, + + mii_rx_clk=mii_rx_clk, + mii_rxd=mii_rxd, + mii_rx_dv=mii_rx_dv, + mii_rx_er=mii_rx_er, + + mii_tx_clk=mii_tx_clk, + mii_txd=mii_txd, + mii_tx_en=mii_tx_en, + mii_tx_er=mii_tx_er, + + tx_error_underflow=tx_error_underflow, + tx_fifo_overflow=tx_fifo_overflow, + tx_fifo_bad_frame=tx_fifo_bad_frame, + tx_fifo_good_frame=tx_fifo_good_frame, + rx_error_bad_frame=rx_error_bad_frame, + rx_error_bad_fcs=rx_error_bad_fcs, + rx_fifo_overflow=rx_fifo_overflow, + rx_fifo_bad_frame=rx_fifo_bad_frame, + rx_fifo_good_frame=rx_fifo_good_frame, + + ifg_delay=ifg_delay + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + logic_clk.next = not clk + + phy_clk_hp = Signal(int(20)) + + @instance + def phy_clk_gen(): + while True: + yield delay(int(phy_clk_hp)) + mii_rx_clk.next = not mii_rx_clk + mii_tx_clk.next = not mii_rx_clk + + rx_error_bad_frame_asserted = Signal(bool(0)) + rx_error_bad_fcs_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (rx_error_bad_frame): + rx_error_bad_frame_asserted.next = 1 + if (rx_error_bad_fcs): + rx_error_bad_fcs_asserted.next = 1 + + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + logic_rst.next = 1 + yield clk.posedge + rst.next = 0 + logic_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + ifg_delay.next = 12 + + # testbench stimulus + + for rate in [20, 200]: + phy_clk_hp.next = rate + + yield delay(1000) + + yield clk.posedge + print("test 1: test rx packet") + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis_fcs() + + mii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame)) + + yield axis_sink.wait() + rx_frame = axis_sink.recv() + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis(rx_frame) + eth_frame.update_fcs() + + assert eth_frame == test_frame + + yield delay(100) + + yield clk.posedge + print("test 2: test tx packet") + current_test.next = 2 + + 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(range(32)) + test_frame.update_fcs() + + axis_frame = test_frame.build_axis() + + axis_source.send(axis_frame) + + yield mii_sink.wait() + rx_frame = mii_sink.recv() + + assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5') + + eth_frame = eth_ep.EthFrame() + eth_frame.parse_axis_fcs(rx_frame.data[8:]) + + print(hex(eth_frame.eth_fcs)) + print(hex(eth_frame.calc_fcs())) + + assert len(eth_frame.payload.data) == 46 + assert eth_frame.eth_fcs == eth_frame.calc_fcs() + assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac + assert eth_frame.eth_src_mac == test_frame.eth_src_mac + assert eth_frame.eth_type == test_frame.eth_type + assert eth_frame.payload.data.index(test_frame.payload.data) == 0 + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_eth_mac_mii_fifo.v b/tb/test_eth_mac_mii_fifo.v new file mode 100644 index 000000000..5eb2eff45 --- /dev/null +++ b/tb/test_eth_mac_mii_fifo.v @@ -0,0 +1,167 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for eth_mac_mii_fifo + */ +module test_eth_mac_mii_fifo; + +// Parameters +parameter TARGET = "SIM"; +parameter CLOCK_INPUT_STYLE = "BUFIO2"; +parameter ENABLE_PADDING = 1; +parameter MIN_FRAME_LENGTH = 64; +parameter TX_FIFO_ADDR_WIDTH = 9; +parameter RX_FIFO_ADDR_WIDTH = 9; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg logic_clk = 0; +reg logic_rst = 0; +reg [7:0] tx_axis_tdata = 0; +reg tx_axis_tvalid = 0; +reg tx_axis_tlast = 0; +reg tx_axis_tuser = 0; +reg rx_axis_tready = 0; +reg mii_rx_clk = 0; +reg [3:0] mii_rxd = 0; +reg mii_rx_dv = 0; +reg mii_rx_er = 0; +reg mii_tx_clk = 0; +reg [7:0] ifg_delay = 0; + +// Outputs +wire tx_axis_tready; +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tlast; +wire rx_axis_tuser; +wire [3:0] mii_txd; +wire mii_tx_en; +wire mii_tx_er; +wire tx_error_underflow; +wire tx_fifo_overflow; +wire tx_fifo_bad_frame; +wire tx_fifo_good_frame; +wire rx_error_bad_frame; +wire rx_error_bad_fcs; +wire rx_fifo_overflow; +wire rx_fifo_bad_frame; +wire rx_fifo_good_frame; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + logic_clk, + logic_rst, + tx_axis_tdata, + tx_axis_tvalid, + tx_axis_tlast, + tx_axis_tuser, + rx_axis_tready, + mii_rx_clk, + mii_rxd, + mii_rx_dv, + mii_rx_er, + mii_tx_clk, + ifg_delay + ); + $to_myhdl( + tx_axis_tready, + rx_axis_tdata, + rx_axis_tvalid, + rx_axis_tlast, + rx_axis_tuser, + mii_txd, + mii_tx_en, + mii_tx_er, + tx_error_underflow, + tx_fifo_overflow, + tx_fifo_bad_frame, + tx_fifo_good_frame, + rx_error_bad_frame, + rx_error_bad_fcs, + rx_fifo_overflow, + rx_fifo_bad_frame, + rx_fifo_good_frame + ); + + // dump file + $dumpfile("test_eth_mac_mii_fifo.lxt"); + $dumpvars(0, test_eth_mac_mii_fifo); +end + +eth_mac_mii_fifo #( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .TX_FIFO_ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), + .RX_FIFO_ADDR_WIDTH(RX_FIFO_ADDR_WIDTH) +) +UUT ( + .rst(rst), + .logic_clk(logic_clk), + .logic_rst(logic_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .mii_rx_clk(mii_rx_clk), + .mii_rxd(mii_rxd), + .mii_rx_dv(mii_rx_dv), + .mii_rx_er(mii_rx_er), + .mii_tx_clk(mii_tx_clk), + .mii_txd(mii_txd), + .mii_tx_en(mii_tx_en), + .mii_tx_er(mii_tx_er), + .tx_error_underflow(tx_error_underflow), + .tx_fifo_overflow(tx_fifo_overflow), + .tx_fifo_bad_frame(tx_fifo_bad_frame), + .tx_fifo_good_frame(tx_fifo_good_frame), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_fifo_overflow(rx_fifo_overflow), + .rx_fifo_bad_frame(rx_fifo_bad_frame), + .rx_fifo_good_frame(rx_fifo_good_frame), + .ifg_delay(ifg_delay) +); + +endmodule From 000895682891ea341cbf2a8a6e1971b10f67a596 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 19:38:55 -0700 Subject: [PATCH 550/617] Add Arty example design --- example/Arty/fpga/Makefile | 25 + example/Arty/fpga/README.md | 25 + example/Arty/fpga/common/vivado.mk | 118 +++++ example/Arty/fpga/fpga.xdc | 73 +++ example/Arty/fpga/fpga/Makefile | 61 +++ example/Arty/fpga/lib/eth | 1 + example/Arty/fpga/rtl/debounce_switch.v | 89 ++++ example/Arty/fpga/rtl/fpga.v | 267 +++++++++++ example/Arty/fpga/rtl/fpga_core.v | 590 ++++++++++++++++++++++++ example/Arty/fpga/rtl/sync_reset.v | 52 +++ example/Arty/fpga/rtl/sync_signal.v | 58 +++ example/Arty/fpga/tb/arp_ep.py | 1 + example/Arty/fpga/tb/axis_ep.py | 1 + example/Arty/fpga/tb/eth_ep.py | 1 + example/Arty/fpga/tb/ip_ep.py | 1 + example/Arty/fpga/tb/mii_ep.py | 1 + example/Arty/fpga/tb/test_fpga_core.py | 325 +++++++++++++ example/Arty/fpga/tb/test_fpga_core.v | 158 +++++++ example/Arty/fpga/tb/udp_ep.py | 1 + 19 files changed, 1848 insertions(+) create mode 100644 example/Arty/fpga/Makefile create mode 100644 example/Arty/fpga/README.md create mode 100644 example/Arty/fpga/common/vivado.mk create mode 100644 example/Arty/fpga/fpga.xdc create mode 100644 example/Arty/fpga/fpga/Makefile create mode 120000 example/Arty/fpga/lib/eth create mode 100644 example/Arty/fpga/rtl/debounce_switch.v create mode 100644 example/Arty/fpga/rtl/fpga.v create mode 100644 example/Arty/fpga/rtl/fpga_core.v create mode 100644 example/Arty/fpga/rtl/sync_reset.v create mode 100644 example/Arty/fpga/rtl/sync_signal.v create mode 120000 example/Arty/fpga/tb/arp_ep.py create mode 120000 example/Arty/fpga/tb/axis_ep.py create mode 120000 example/Arty/fpga/tb/eth_ep.py create mode 120000 example/Arty/fpga/tb/ip_ep.py create mode 120000 example/Arty/fpga/tb/mii_ep.py create mode 100755 example/Arty/fpga/tb/test_fpga_core.py create mode 100644 example/Arty/fpga/tb/test_fpga_core.v create mode 120000 example/Arty/fpga/tb/udp_ep.py diff --git a/example/Arty/fpga/Makefile b/example/Arty/fpga/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/Arty/fpga/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/Arty/fpga/README.md b/example/Arty/fpga/README.md new file mode 100644 index 000000000..75c852333 --- /dev/null +++ b/example/Arty/fpga/README.md @@ -0,0 +1,25 @@ +# Verilog Ethernet Arty Example Design + +## Introduction + +This example design targets the Digilent Arty FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +FPGA: XC7A35TICSG324-1L +PHY: TI DP83848J + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the Arty board with Vivado. Then run netcat -u +192.168.1.128 1234 to open a UDP connection to port 1234. Any text entered +into netcat will be echoed back after pressing enter. + + diff --git a/example/Arty/fpga/common/vivado.mk b/example/Arty/fpga/common/vivado.mk new file mode 100644 index 000000000..a54b530f6 --- /dev/null +++ b/example/Arty/fpga/common/vivado.mk @@ -0,0 +1,118 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile $(XCI_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/Arty/fpga/fpga.xdc b/example/Arty/fpga/fpga.xdc new file mode 100644 index 000000000..87fc5b623 --- /dev/null +++ b/example/Arty/fpga/fpga.xdc @@ -0,0 +1,73 @@ +# XDC constraints for the Digilent Arty board +# part: xc7a35t-csg324-1 + +# General configuration +set_property CFGBVS VCCO [current_design] +set_property CONFIG_VOLTAGE 3.3 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] + +# 100 MHz clock +set_property -dict {LOC E3 IOSTANDARD LVCMOS33} [get_ports clk] +create_clock -period 10.000 -name clk [get_ports clk] + +# LEDs +set_property -dict {LOC G6 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led0_r] +set_property -dict {LOC F6 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led0_g] +set_property -dict {LOC E1 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led0_b] +set_property -dict {LOC G3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led1_r] +set_property -dict {LOC J4 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led1_g] +set_property -dict {LOC G4 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led1_b] +set_property -dict {LOC J3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led2_r] +set_property -dict {LOC J2 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led2_g] +set_property -dict {LOC H4 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led2_b] +set_property -dict {LOC K1 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led3_r] +set_property -dict {LOC H6 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led3_g] +set_property -dict {LOC K2 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led3_b] +set_property -dict {LOC H5 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led4] +set_property -dict {LOC J5 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led5] +set_property -dict {LOC T9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led6] +set_property -dict {LOC T10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led7] + +# Reset button +set_property -dict {LOC C2 IOSTANDARD LVCMOS33} [get_ports reset_n] + +# Push buttons +set_property -dict {LOC D9 IOSTANDARD LVCMOS33} [get_ports {btn[0]}] +set_property -dict {LOC C9 IOSTANDARD LVCMOS33} [get_ports {btn[1]}] +set_property -dict {LOC B9 IOSTANDARD LVCMOS33} [get_ports {btn[2]}] +set_property -dict {LOC B8 IOSTANDARD LVCMOS33} [get_ports {btn[3]}] + +# Toggle switches +set_property -dict {LOC A8 IOSTANDARD LVCMOS33} [get_ports {sw[0]}] +set_property -dict {LOC C11 IOSTANDARD LVCMOS33} [get_ports {sw[1]}] +set_property -dict {LOC C10 IOSTANDARD LVCMOS33} [get_ports {sw[2]}] +set_property -dict {LOC A10 IOSTANDARD LVCMOS33} [get_ports {sw[3]}] + +# UART +set_property -dict {LOC D10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports uart_txd] +set_property -dict {LOC A9 IOSTANDARD LVCMOS33} [get_ports uart_rxd] + +# Ethernet MII PHY +set_property -dict {LOC F15 IOSTANDARD LVCMOS33} [get_ports phy_rx_clk] +set_property -dict {LOC D18 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[0]}] +set_property -dict {LOC E17 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[1]}] +set_property -dict {LOC E18 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[2]}] +set_property -dict {LOC G17 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[3]}] +set_property -dict {LOC G16 IOSTANDARD LVCMOS33} [get_ports phy_rx_dv] +set_property -dict {LOC C17 IOSTANDARD LVCMOS33} [get_ports phy_rx_er] +set_property -dict {LOC H16 IOSTANDARD LVCMOS33} [get_ports phy_tx_clk] +set_property -dict {LOC H14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[0]}] +set_property -dict {LOC J14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[1]}] +set_property -dict {LOC J13 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[2]}] +set_property -dict {LOC H17 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[3]}] +set_property -dict {LOC H15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports phy_tx_en] +set_property -dict {LOC D17 IOSTANDARD LVCMOS33} [get_ports phy_col] +set_property -dict {LOC G14 IOSTANDARD LVCMOS33} [get_ports phy_crs] +set_property -dict {LOC G18 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_ref_clk] +set_property -dict {LOC C16 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_reset_n] +#set_property -dict {LOC K13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_mdio] +#set_property -dict {LOC F16 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_mdc] + +create_clock -period 40.000 -name phy_rx_clk [get_ports phy_rx_clk] +create_clock -period 40.000 -name phy_tx_clk [get_ports phy_tx_clk] + diff --git a/example/Arty/fpga/fpga/Makefile b/example/Arty/fpga/fpga/Makefile new file mode 100644 index 000000000..596b0e845 --- /dev/null +++ b/example/Arty/fpga/fpga/Makefile @@ -0,0 +1,61 @@ + +# FPGA settings +FPGA_PART = xc7a35t-csg324-1 +FPGA_TOP = fpga +FPGA_ARCH = artix7 + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/ssio_sdr_in.v +SYN_FILES += lib/eth/rtl/mii_phy_if.v +SYN_FILES += lib/eth/rtl/eth_mac_mii_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_mii.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += lib/eth/syn/mii_phy_if.tcl +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl + echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "exit" >> program.tcl + vivado -mode batch -source program.tcl + diff --git a/example/Arty/fpga/lib/eth b/example/Arty/fpga/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/Arty/fpga/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/Arty/fpga/rtl/debounce_switch.v b/example/Arty/fpga/rtl/debounce_switch.v new file mode 100644 index 000000000..bb631cc35 --- /dev/null +++ b/example/Arty/fpga/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/Arty/fpga/rtl/fpga.v b/example/Arty/fpga/rtl/fpga.v new file mode 100644 index 000000000..61c138ce6 --- /dev/null +++ b/example/Arty/fpga/rtl/fpga.v @@ -0,0 +1,267 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 100MHz + * Reset: Push button, active low + */ + input wire clk, + input wire reset_n, + + /* + * GPIO + */ + input wire [3:0] sw, + input wire [3:0] btn, + output wire led0_r, + output wire led0_g, + output wire led0_b, + output wire led1_r, + output wire led1_g, + output wire led1_b, + output wire led2_r, + output wire led2_g, + output wire led2_b, + output wire led3_r, + output wire led3_g, + output wire led3_b, + output wire led4, + output wire led5, + output wire led6, + output wire led7, + + /* + * Ethernet: 100BASE-T MII + */ + output wire phy_ref_clk, + input wire phy_rx_clk, + input wire [3:0] phy_rxd, + input wire phy_rx_dv, + input wire phy_rx_er, + input wire phy_tx_clk, + output wire [3:0] phy_txd, + output wire phy_tx_en, + input wire phy_col, + input wire phy_crs, + output wire phy_reset_n, + + /* + * UART: 500000 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd +); + +// Clock and reset + +wire clk_ibufg; +wire clk_bufg; +wire clk_mmcm_out; + +// Internal 125 MHz clock +wire clk_int; +wire rst_int; + +wire mmcm_rst = ~reset_n; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFG +clk_ibufg_inst( + .I(clk), + .O(clk_ibufg) +); + +wire clk_25mhz_mmcm_out; +wire clk_25mhz_int; + +// MMCM instance +// 100 MHz in, 125 MHz out +// PFD range: 10 MHz to 550 MHz +// VCO range: 600 MHz to 1200 MHz +// M = 10, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +// Divide by 40 to get output frequency of 25 MHz +// 1000 / 5 = 200 MHz +MMCME2_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(40), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(10), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(10.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(clk_25mhz_mmcm_out), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_bufg_inst ( + .I(clk_mmcm_out), + .O(clk_int) +); + +BUFG +clk_25mhz_bufg_inst ( + .I(clk_25mhz_mmcm_out), + .O(clk_25mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_inst ( + .clk(clk_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_int) +); + +// GPIO +wire [3:0] btn_int; +wire [3:0] sw_int; + +debounce_switch #( + .WIDTH(8), + .N(4), + .RATE(25000) +) +debounce_switch_inst ( + .clk(clk_int), + .rst(rst_int), + .in({btn, + sw}), + .out({btn_int, + sw_int}) +); + +sync_signal #( + .WIDTH(1), + .N(2) +) +sync_signal_inst ( + .clk(clk_int), + .in({uart_rxd}), + .out({uart_rxd_int}) +); + +assign phy_ref_clk = clk_25mhz_int; + +fpga_core +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk(clk_int), + .rst(rst_int), + /* + * GPIO + */ + .btn(btn_int), + .sw(sw_int), + .led0_r(led0_r), + .led0_g(led0_g), + .led0_b(led0_b), + .led1_r(led1_r), + .led1_g(led1_g), + .led1_b(led1_b), + .led2_r(led2_r), + .led2_g(led2_g), + .led2_b(led2_b), + .led3_r(led3_r), + .led3_g(led3_g), + .led3_b(led3_b), + .led4(led4), + .led5(led5), + .led6(led6), + .led7(led7), + /* + * Ethernet: 1000BASE-T RGMII + */ + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_dv(phy_rx_dv), + .phy_rx_er(phy_rx_er), + .phy_tx_clk(phy_tx_clk), + .phy_txd(phy_txd), + .phy_tx_en(phy_tx_en), + .phy_col(phy_col), + .phy_crs(phy_crs), + .phy_reset_n(phy_reset_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd) +); + +endmodule diff --git a/example/Arty/fpga/rtl/fpga_core.v b/example/Arty/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..f13193e96 --- /dev/null +++ b/example/Arty/fpga/rtl/fpga_core.v @@ -0,0 +1,590 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 125MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire [3:0] btn, + input wire [3:0] sw, + output wire led0_r, + output wire led0_g, + output wire led0_b, + output wire led1_r, + output wire led1_g, + output wire led1_b, + output wire led2_r, + output wire led2_g, + output wire led2_b, + output wire led3_r, + output wire led3_g, + output wire led3_b, + output wire led4, + output wire led5, + output wire led6, + output wire led7, + + /* + * Ethernet: 100BASE-T MII + */ + input wire phy_rx_clk, + input wire [3:0] phy_rxd, + input wire phy_rx_dv, + input wire phy_rx_er, + input wire phy_tx_clk, + output wire [3:0] phy_txd, + output wire phy_tx_en, + input wire phy_col, + input wire phy_crs, + output wire phy_reset_n, + + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd +); + +// AXI between MAC and Ethernet modules +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [7:0] tx_axis_tdata; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [7:0] rx_eth_payload_axis_tdata; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [7:0] tx_eth_payload_axis_tdata; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [7:0] rx_ip_payload_axis_tdata; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [7:0] tx_ip_payload_axis_tdata; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [7:0] rx_udp_payload_axis_tdata; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; + +wire [7:0] rx_fifo_udp_payload_axis_tdata; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; + +wire [7:0] tx_fifo_udp_payload_axis_tdata; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_axis_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = !match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; + +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; + +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_axis_tlast) begin + valid_last <= 1'b0; + end + end + end +end + +//assign led = sw; +assign {led0_g, led1_g, led2_g, led3_g, led4, led5, led6, led7} = led_reg; +assign phy_reset_n = !rst; + +assign uart_txd = 0; + +eth_mac_mii_fifo #( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE("BUFR"), + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) +) +eth_mac_inst ( + .rst(rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .mii_rx_clk(phy_rx_clk), + .mii_rxd(phy_rxd), + .mii_rx_dv(phy_rx_dv), + .mii_rx_er(phy_rx_er), + .mii_tx_clk(phy_tx_clk), + .mii_txd(phy_txd), + .mii_tx_en(phy_tx_en), + .mii_tx_er(), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + .ifg_delay(12) +); + +eth_axis_rx +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(rx_axis_tdata), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // AXI output + .m_axis_tdata(tx_axis_tdata), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // IP frame input + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), + // IP frame output + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), + // UDP frame input + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), + // UDP frame output + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(0) +); + +axis_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(0) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), + + // AXI output + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() +); + +endmodule diff --git a/example/Arty/fpga/rtl/sync_reset.v b/example/Arty/fpga/rtl/sync_reset.v new file mode 100644 index 000000000..acbcf1c6e --- /dev/null +++ b/example/Arty/fpga/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/Arty/fpga/rtl/sync_signal.v b/example/Arty/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/example/Arty/fpga/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/Arty/fpga/tb/arp_ep.py b/example/Arty/fpga/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/Arty/fpga/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/Arty/fpga/tb/axis_ep.py b/example/Arty/fpga/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/Arty/fpga/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/Arty/fpga/tb/eth_ep.py b/example/Arty/fpga/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/Arty/fpga/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/Arty/fpga/tb/ip_ep.py b/example/Arty/fpga/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/Arty/fpga/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/Arty/fpga/tb/mii_ep.py b/example/Arty/fpga/tb/mii_ep.py new file mode 120000 index 000000000..e1b3a9129 --- /dev/null +++ b/example/Arty/fpga/tb/mii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/mii_ep.py \ No newline at end of file diff --git a/example/Arty/fpga/tb/test_fpga_core.py b/example/Arty/fpga/tb/test_fpga_core.py new file mode 100755 index 000000000..07e9f84ca --- /dev/null +++ b/example/Arty/fpga/tb/test_fpga_core.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import eth_ep +import arp_ep +import udp_ep +import mii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/ssio_sdr_in.v") +srcs.append("../lib/eth/rtl/mii_phy_if.v") +srcs.append("../lib/eth/rtl/eth_mac_mii_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_mii.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen.v") +srcs.append("../lib/eth/rtl/udp.v") +srcs.append("../lib/eth/rtl/udp_ip_rx.v") +srcs.append("../lib/eth/rtl/udp_ip_tx.v") +srcs.append("../lib/eth/rtl/ip_complete.v") +srcs.append("../lib/eth/rtl/ip.v") +srcs.append("../lib/eth/rtl/ip_eth_rx.v") +srcs.append("../lib/eth/rtl/ip_eth_tx.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + TARGET = "SIM" + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btn = Signal(intbv(0)[4:]) + sw = Signal(intbv(0)[4:]) + phy_rx_clk = Signal(bool(0)) + phy_rxd = Signal(intbv(0)[4:]) + phy_rx_dv = Signal(bool(0)) + phy_rx_er = Signal(bool(0)) + phy_col = Signal(bool(0)) + phy_crs = Signal(bool(0)) + uart_rxd = Signal(bool(0)) + + # Outputs + led0_r = Signal(bool(0)) + led0_g = Signal(bool(0)) + led0_b = Signal(bool(0)) + led1_r = Signal(bool(0)) + led1_g = Signal(bool(0)) + led1_b = Signal(bool(0)) + led2_r = Signal(bool(0)) + led2_g = Signal(bool(0)) + led2_b = Signal(bool(0)) + led3_r = Signal(bool(0)) + led3_g = Signal(bool(0)) + led3_b = Signal(bool(0)) + led4 = Signal(bool(0)) + led5 = Signal(bool(0)) + led6 = Signal(bool(0)) + led7 = Signal(bool(0)) + phy_tx_clk = Signal(bool(0)) + phy_txd = Signal(intbv(0)[4:]) + phy_tx_en = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_txd = Signal(bool(0)) + + # sources and sinks + mii_source = mii_ep.MIISource() + + mii_source_logic = mii_source.create_logic( + phy_rx_clk, + rst, + txd=phy_rxd, + tx_en=phy_rx_dv, + tx_er=phy_rx_er, + name='mii_source' + ) + + mii_sink = mii_ep.MIISink() + + mii_sink_logic = mii_sink.create_logic( + phy_tx_clk, + rst, + rxd=phy_txd, + rx_dv=phy_tx_en, + rx_er=False, + name='mii_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, + + btn=btn, + sw=sw, + led0_r=led0_r, + led0_g=led0_g, + led0_b=led0_b, + led1_r=led1_r, + led1_g=led1_g, + led1_b=led1_b, + led2_r=led2_r, + led2_g=led2_g, + led2_b=led2_b, + led3_r=led3_r, + led3_g=led3_g, + led3_b=led3_b, + led4=led4, + led5=led5, + led6=led6, + led7=led7, + + phy_rx_clk=phy_rx_clk, + phy_rxd=phy_rxd, + phy_rx_dv=phy_rx_dv, + phy_rx_er=phy_rx_er, + phy_tx_clk=phy_tx_clk, + phy_txd=phy_txd, + phy_tx_en=phy_tx_en, + phy_col=phy_col, + phy_crs=phy_crs, + phy_reset_n=phy_reset_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + phy_clk_hp = Signal(int(20)) + + @instance + def phy_clk_gen(): + while True: + yield delay(int(phy_clk_hp)) + phy_rx_clk.next = not phy_rx_clk + phy_tx_clk.next = not phy_tx_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 + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + mii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while mii_sink.empty(): + yield clk.posedge + + rx_frame = mii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + mii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while mii_sink.empty(): + yield clk.posedge + + rx_frame = mii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert mii_source.empty() + assert mii_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() diff --git a/example/Arty/fpga/tb/test_fpga_core.v b/example/Arty/fpga/tb/test_fpga_core.v new file mode 100644 index 000000000..3ceea0953 --- /dev/null +++ b/example/Arty/fpga/tb/test_fpga_core.v @@ -0,0 +1,158 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters +parameter TARGET = "SIM"; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [3:0] btn = 0; +reg [3:0] sw = 0; +reg phy_rx_clk = 0; +reg [3:0] phy_rxd = 0; +reg phy_rx_dv = 0; +reg phy_rx_er = 0; +reg phy_col = 0; +reg phy_crs = 0; +reg phy_tx_clk = 0; +reg uart_rxd = 0; + +// Outputs +wire led0_r; +wire led0_g; +wire led0_b; +wire led1_r; +wire led1_g; +wire led1_b; +wire led2_r; +wire led2_g; +wire led2_b; +wire led3_r; +wire led3_g; +wire led3_b; +wire led4; +wire led5; +wire led6; +wire led7; +wire [3:0] phy_txd; +wire phy_tx_en; +wire phy_reset_n; +wire uart_txd; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + btn, + sw, + phy_rx_clk, + phy_rxd, + phy_rx_dv, + phy_rx_er, + phy_tx_clk, + phy_col, + phy_crs, + uart_rxd + ); + $to_myhdl( + led0_r, + led0_g, + led0_b, + led1_r, + led1_g, + led1_b, + led2_r, + led2_g, + led2_b, + led3_r, + led3_g, + led3_b, + led4, + led5, + led6, + led7, + phy_txd, + phy_tx_en, + phy_reset_n, + uart_txd + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core #( + .TARGET(TARGET) +) +UUT ( + .clk(clk), + .rst(rst), + .btn(btn), + .sw(sw), + .led0_r(led0_r), + .led0_g(led0_g), + .led0_b(led0_b), + .led1_r(led1_r), + .led1_g(led1_g), + .led1_b(led1_b), + .led2_r(led2_r), + .led2_g(led2_g), + .led2_b(led2_b), + .led3_r(led3_r), + .led3_g(led3_g), + .led3_b(led3_b), + .led4(led4), + .led5(led5), + .led6(led6), + .led7(led7), + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_dv(phy_rx_dv), + .phy_rx_er(phy_rx_er), + .phy_tx_clk(phy_tx_clk), + .phy_txd(phy_txd), + .phy_tx_en(phy_tx_en), + .phy_col(phy_col), + .phy_crs(phy_crs), + .phy_reset_n(phy_reset_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd) +); + +endmodule diff --git a/example/Arty/fpga/tb/udp_ep.py b/example/Arty/fpga/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/Arty/fpga/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file From a9c7946368b97e658c42fb7d2611fd0e59de72a5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 23:49:04 -0700 Subject: [PATCH 551/617] Change parameter concatenation to increments of DEST_WIDTH --- rtl/axis_switch.v | 16 ++++++++-------- tb/test_axis_switch_4x4.py | 3 +-- tb/test_axis_switch_4x4.v | 4 ++-- tb/test_axis_switch_4x4_64.py | 3 +-- tb/test_axis_switch_4x4_64.v | 4 ++-- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/rtl/axis_switch.v b/rtl/axis_switch.v index 6f58a2230..f8433b5e7 100644 --- a/rtl/axis_switch.v +++ b/rtl/axis_switch.v @@ -41,8 +41,8 @@ module axis_switch # parameter DEST_WIDTH = $clog2(S_COUNT), parameter USER_ENABLE = 1, parameter USER_WIDTH = 1, - parameter M_BASE = {32'd3, 32'd2, 32'd1, 32'd0}, - parameter M_TOP = {32'd3, 32'd2, 32'd1, 32'd0}, + parameter M_BASE = {2'd3, 2'd2, 2'd1, 2'd0}, + parameter M_TOP = {2'd3, 2'd2, 2'd1, 2'd0}, parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}}, parameter S_REG_TYPE = 0, parameter M_REG_TYPE = 2, @@ -93,14 +93,14 @@ initial begin end for (i = 0; i < M_COUNT; i = i + 1) begin - if (M_BASE[i*32 +: 32] < 0 || M_BASE[i*32 +: 32] > 2**DEST_WIDTH-1 || M_TOP[i*32 +: 32] < 0 || M_TOP[i*32 +: 32] > 2**DEST_WIDTH-1) begin + if (M_BASE[i*DEST_WIDTH +: DEST_WIDTH] < 0 || M_BASE[i*DEST_WIDTH +: DEST_WIDTH] > 2**DEST_WIDTH-1 || M_TOP[i*DEST_WIDTH +: DEST_WIDTH] < 0 || M_TOP[i*DEST_WIDTH +: DEST_WIDTH] > 2**DEST_WIDTH-1) begin $error("Error: value out of range"); $finish; end end for (i = 0; i < M_COUNT; i = i + 1) begin - if (M_BASE[i*32 +: 32] > M_TOP[i*32 +: 32]) begin + if (M_BASE[i*DEST_WIDTH +: DEST_WIDTH] > M_TOP[i*DEST_WIDTH +: DEST_WIDTH]) begin $error("Error: invalid range"); $finish; end @@ -108,9 +108,9 @@ initial begin for (i = 0; i < M_COUNT; i = i + 1) begin for (j = i+1; j < M_COUNT; j = j + 1) begin - if (M_BASE[i*32 +: 32] <= M_TOP[j*32 +: 32] && M_BASE[j*32 +: 32] <= M_TOP[i*32 +: 32]) begin - $display("%d: %08x-%08x", i, M_BASE[i*32 +: 32], M_TOP[i*32 +: 32]); - $display("%d: %08x-%08x", j, M_BASE[j*32 +: 32], M_TOP[j*32 +: 32]); + if (M_BASE[i*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[j*DEST_WIDTH +: DEST_WIDTH] && M_BASE[j*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[i*DEST_WIDTH +: DEST_WIDTH]) begin + $display("%d: %08x-%08x", i, M_BASE[i*DEST_WIDTH +: DEST_WIDTH], M_TOP[i*DEST_WIDTH +: DEST_WIDTH]); + $display("%d: %08x-%08x", j, M_BASE[j*DEST_WIDTH +: DEST_WIDTH], M_TOP[j*DEST_WIDTH +: DEST_WIDTH]); $error("Error: ranges overlap"); $finish; end @@ -153,7 +153,7 @@ generate select_valid_next = 1'b0; drop_next = 1'b1; for (k = 0; k < M_COUNT; k = k + 1) begin - if (int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] >= M_BASE[k*32 +: 32] && int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[k*32 +: 32] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin + if (int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] >= M_BASE[k*DEST_WIDTH +: DEST_WIDTH] && int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[k*DEST_WIDTH +: DEST_WIDTH] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin select_next = k; select_valid_next = 1'b1; drop_next = 1'b0; diff --git a/tb/test_axis_switch_4x4.py b/tb/test_axis_switch_4x4.py index bf6c4613c..0958f2ff8 100755 --- a/tb/test_axis_switch_4x4.py +++ b/tb/test_axis_switch_4x4.py @@ -27,7 +27,6 @@ from myhdl import * import os import axis_ep -import math module = 'axis_switch' testbench = 'test_%s_4x4' % module @@ -54,7 +53,7 @@ def bench(): KEEP_WIDTH = (DATA_WIDTH/8) ID_ENABLE = 1 ID_WIDTH = 8 - DEST_WIDTH = math.ceil(math.log(M_COUNT+1, 2)) + DEST_WIDTH = (M_COUNT+1).bit_length() USER_ENABLE = 1 USER_WIDTH = 1 M_BASE = [0, 1, 2, 3] diff --git a/tb/test_axis_switch_4x4.v b/tb/test_axis_switch_4x4.v index b30419a84..7999b4a30 100644 --- a/tb/test_axis_switch_4x4.v +++ b/tb/test_axis_switch_4x4.v @@ -42,8 +42,8 @@ parameter ID_WIDTH = 8; parameter DEST_WIDTH = $clog2(M_COUNT+1); parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; -parameter M_BASE = {32'd3, 32'd2, 32'd1, 32'd0}; -parameter M_TOP = {32'd3, 32'd2, 32'd1, 32'd0}; +parameter M_BASE = {3'd3, 3'd2, 3'd1, 3'd0}; +parameter M_TOP = {3'd3, 3'd2, 3'd1, 3'd0}; parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}}; parameter S_REG_TYPE = 0; parameter M_REG_TYPE = 2; diff --git a/tb/test_axis_switch_4x4_64.py b/tb/test_axis_switch_4x4_64.py index a679a33d8..4f2082e39 100755 --- a/tb/test_axis_switch_4x4_64.py +++ b/tb/test_axis_switch_4x4_64.py @@ -27,7 +27,6 @@ from myhdl import * import os import axis_ep -import math module = 'axis_switch' testbench = 'test_%s_4x4_64' % module @@ -54,7 +53,7 @@ def bench(): KEEP_WIDTH = (DATA_WIDTH/8) ID_ENABLE = 1 ID_WIDTH = 8 - DEST_WIDTH = math.ceil(math.log(M_COUNT+1, 2)) + DEST_WIDTH = (M_COUNT+1).bit_length() USER_ENABLE = 1 USER_WIDTH = 1 M_BASE = [0, 1, 2, 3] diff --git a/tb/test_axis_switch_4x4_64.v b/tb/test_axis_switch_4x4_64.v index b107ac7a2..2c677478f 100644 --- a/tb/test_axis_switch_4x4_64.v +++ b/tb/test_axis_switch_4x4_64.v @@ -42,8 +42,8 @@ parameter ID_WIDTH = 8; parameter DEST_WIDTH = $clog2(M_COUNT+1); parameter USER_ENABLE = 1; parameter USER_WIDTH = 1; -parameter M_BASE = {32'd3, 32'd2, 32'd1, 32'd0}; -parameter M_TOP = {32'd3, 32'd2, 32'd1, 32'd0}; +parameter M_BASE = {3'd3, 3'd2, 3'd1, 3'd0}; +parameter M_TOP = {3'd3, 3'd2, 3'd1, 3'd0}; parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}}; parameter S_REG_TYPE = 0; parameter M_REG_TYPE = 2; From 5428d81fd61a00fba61703cebde32319f6e01d50 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 28 Mar 2019 23:56:06 -0700 Subject: [PATCH 552/617] Update AXI stream switch instances --- example/VCU108/fpga_10g/rtl/fpga_core.v | 4 ++-- example/VCU118/fpga_10g/rtl/fpga_core.v | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index 29b444e70..20ad98210 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -583,8 +583,8 @@ axis_switch #( .DEST_WIDTH(2), .USER_ENABLE(1), .USER_WIDTH(1), - .M_BASE({32'd2, 32'd1, 32'd0}), - .M_TOP({32'd2, 32'd1, 32'd0}), + .M_BASE({2'd2, 2'd1, 2'd0}), + .M_TOP({2'd2, 2'd1, 2'd0}), .M_CONNECT({3{3'b111}}), .S_REG_TYPE(0), .M_REG_TYPE(1), diff --git a/example/VCU118/fpga_10g/rtl/fpga_core.v b/example/VCU118/fpga_10g/rtl/fpga_core.v index 9fa9a0707..a523e3afd 100644 --- a/example/VCU118/fpga_10g/rtl/fpga_core.v +++ b/example/VCU118/fpga_10g/rtl/fpga_core.v @@ -640,8 +640,8 @@ axis_switch #( .DEST_WIDTH(2), .USER_ENABLE(1), .USER_WIDTH(1), - .M_BASE({32'd2, 32'd1, 32'd0}), - .M_TOP({32'd2, 32'd1, 32'd0}), + .M_BASE({2'd2, 2'd1, 2'd0}), + .M_TOP({2'd2, 2'd1, 2'd0}), .M_CONNECT({3{3'b111}}), .S_REG_TYPE(0), .M_REG_TYPE(1), From 1bec4857660fd25745f00a82511b2e25cca778b9 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 3 Apr 2019 11:48:09 -0700 Subject: [PATCH 553/617] Fix constants --- rtl/arp.v | 2 +- rtl/arp_64.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/arp.v b/rtl/arp.v index 7ebe5c5cb..47a0f3e10 100644 --- a/rtl/arp.v +++ b/rtl/arp.v @@ -284,7 +284,7 @@ always @* begin outgoing_arp_tha_next = incoming_arp_sha; outgoing_arp_tpa_next = incoming_arp_spa; end - end else if (incoming_arp_oper == ARP_OPER_INARP_REPLY) begin + end else if (incoming_arp_oper == ARP_OPER_INARP_REQUEST) begin // INARP request if (incoming_arp_tha == local_mac) begin // send reply frame to valid incoming request diff --git a/rtl/arp_64.v b/rtl/arp_64.v index 086b579be..82f456b26 100644 --- a/rtl/arp_64.v +++ b/rtl/arp_64.v @@ -288,7 +288,7 @@ always @* begin outgoing_arp_tha_next = incoming_arp_sha; outgoing_arp_tpa_next = incoming_arp_spa; end - end else if (incoming_arp_oper == ARP_OPER_INARP_REPLY) begin + end else if (incoming_arp_oper == ARP_OPER_INARP_REQUEST) begin // INARP request if (incoming_arp_tha == local_mac) begin // send reply frame to valid incoming request From 978fdce95c2007ccf4c17a64927e57487eda11e2 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 3 Apr 2019 20:57:10 -0700 Subject: [PATCH 554/617] Minor fixes --- example/Arty/fpga/rtl/fpga.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/Arty/fpga/rtl/fpga.v b/example/Arty/fpga/rtl/fpga.v index 61c138ce6..c64b841c4 100644 --- a/example/Arty/fpga/rtl/fpga.v +++ b/example/Arty/fpga/rtl/fpga.v @@ -192,7 +192,7 @@ wire [3:0] sw_int; debounce_switch #( .WIDTH(8), .N(4), - .RATE(25000) + .RATE(125000) ) debounce_switch_inst ( .clk(clk_int), @@ -245,7 +245,7 @@ core_inst ( .led6(led6), .led7(led7), /* - * Ethernet: 1000BASE-T RGMII + * Ethernet: 100BASE-T MII */ .phy_rx_clk(phy_rx_clk), .phy_rxd(phy_rxd), From 18d6aab16de8950f98824232213841138c8a82e3 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 3 Apr 2019 22:32:06 -0700 Subject: [PATCH 555/617] Update readme --- README.md | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4f9b7b7b9..768085442 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,14 @@ bits. 10G Ethernet MAC with XGMII interface and FIFOs. Datapath selectable between 32 and 64 bits. +### eth_mac_mii module + +Ethernet MAC with MII interface. + +### eth_mac_mii_fifo module + +Ethernet MAC with MII interface and FIFOs. + ### eth_mac_phy_10g module 10G Ethernet MAC/PHY combination module with SERDES interface. @@ -258,6 +266,10 @@ Supports priority and round-robin arbitration. Fully parametrizable combinatorial parallel LFSR/CRC module. +### mii_phy_if module + +MII PHY interface and clocking logic. + ### rgmii_phy_if module RGMII PHY interface and clocking logic. @@ -379,18 +391,20 @@ and data lines. rtl/eth_axis_tx.v : Ethernet frame transmitter rtl/eth_axis_tx_64.v : Ethernet frame transmitter (64 bit) rtl/eth_demux.v : Ethernet frame demultiplexer - rtl/eth_mac_1g.v : Gigabit Etherent GMII MAC - rtl/eth_mac_1g_fifo.v : Gigabit Etherent GMII MAC with FIFO + rtl/eth_mac_1g.v : Gigabit Ethernet GMII MAC + rtl/eth_mac_1g_fifo.v : Gigabit Ethernet GMII MAC with FIFO rtl/eth_mac_1g_gmii.v : Tri-mode Ethernet GMII/MII MAC rtl/eth_mac_1g_gmii_fifo.v : Tri-mode Ethernet GMII/MII MAC with FIFO rtl/eth_mac_1g_rgmii.v : Tri-mode Ethernet RGMII MAC rtl/eth_mac_1g_rgmii_fifo.v : Tri-mode Ethernet RGMII MAC with FIFO - rtl/eth_mac_10g.v : 10G Etherent XGMII MAC - rtl/eth_mac_10g_fifo.v : 10G Etherent XGMII MAC with FIFO - rtl/eth_mac_phy_10g.v : 10G Etherent XGMII MAC/PHY - rtl/eth_mac_phy_10g_fifo.v : 10G Etherent XGMII MAC/PHY with FIFO - rtl/eth_mac_phy_10g_rx.v : 10G Etherent XGMII MAC/PHY RX with FIFO - rtl/eth_mac_phy_10g_tx.v : 10G Etherent XGMII MAC/PHY TX with FIFO + rtl/eth_mac_10g.v : 10G Ethernet XGMII MAC + rtl/eth_mac_10g_fifo.v : 10G Ethernet XGMII MAC with FIFO + rtl/eth_mac_mii.v : Ethernet MII MAC + rtl/eth_mac_mii_fifo.v : Ethernet MII MAC with FIFO + rtl/eth_mac_phy_10g.v : 10G Ethernet XGMII MAC/PHY + rtl/eth_mac_phy_10g_fifo.v : 10G Ethernet XGMII MAC/PHY with FIFO + rtl/eth_mac_phy_10g_rx.v : 10G Ethernet XGMII MAC/PHY RX with FIFO + rtl/eth_mac_phy_10g_tx.v : 10G Ethernet XGMII MAC/PHY TX with FIFO rtl/eth_mux.v : Ethernet frame multiplexer rtl/gmii_phy_if.v : GMII PHY interface rtl/iddr.v : Generic DDR input register @@ -407,6 +421,7 @@ and data lines. rtl/ip_mux.v : IP frame multiplexer rtl/lfsr.v : Generic LFSR/CRC module rtl/oddr.v : Generic DDR output register + rtl/mii_phy_if.v : MII PHY interface rtl/rgmii_phy_if.v : RGMII PHY interface rtl/ssio_ddr_in.v : Generic source synchronous IO DDR input module rtl/ssio_ddr_in_diff.v : Generic source synchronous IO DDR differential input module @@ -529,6 +544,7 @@ individual test scripts can be run with python directly. tb/eth_ep.py : MyHDL Ethernet frame endpoints tb/gmii_ep.py : MyHDL GMII endpoints tb/ip_ep.py : MyHDL IP frame endpoints + tb/mii_ep.py : MyHDL MII endpoints tb/rgmii_ep.py : MyHDL RGMII endpoints tb/udp_ep.py : MyHDL UDP frame endpoints tb/xgmii_ep.py : MyHDL XGMII endpoints From 696c634726da5d8a80393089417362823c065492 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 17 Apr 2019 00:16:45 -0700 Subject: [PATCH 556/617] Add rx_bad_block outputs --- rtl/axis_baser_rx_64.v | 19 ++++++++++++++++--- rtl/eth_mac_phy_10g.v | 2 ++ rtl/eth_mac_phy_10g_fifo.v | 25 ++++++++++++++----------- rtl/eth_mac_phy_10g_rx.v | 4 +++- rtl/eth_phy_10g.v | 2 ++ rtl/eth_phy_10g_rx.v | 3 ++- tb/test_axis_baser_rx_64.py | 4 +++- tb/test_axis_baser_rx_64.v | 7 +++++-- tb/test_eth_mac_phy_10g.py | 2 ++ tb/test_eth_mac_phy_10g.v | 3 +++ tb/test_eth_mac_phy_10g_fifo.py | 2 ++ tb/test_eth_mac_phy_10g_fifo.v | 3 +++ tb/test_eth_phy_10g_64.py | 2 ++ tb/test_eth_phy_10g_64.v | 3 +++ tb/test_eth_phy_10g_rx_64.py | 2 ++ tb/test_eth_phy_10g_rx_64.v | 3 +++ 16 files changed, 67 insertions(+), 19 deletions(-) diff --git a/rtl/axis_baser_rx_64.v b/rtl/axis_baser_rx_64.v index d52c2664a..89bd629f2 100644 --- a/rtl/axis_baser_rx_64.v +++ b/rtl/axis_baser_rx_64.v @@ -60,7 +60,8 @@ module axis_baser_rx_64 # output wire start_packet_0, output wire start_packet_4, output wire error_bad_frame, - output wire error_bad_fcs + output wire error_bad_fcs, + output wire rx_bad_block ); // bus width assertions @@ -176,6 +177,7 @@ reg start_packet_0_reg = 1'b0; reg start_packet_4_reg = 1'b0; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; +reg rx_bad_block_reg = 1'b0; reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state3 = 32'hFFFFFFFF; @@ -204,6 +206,7 @@ assign start_packet_0 = start_packet_0_reg; assign start_packet_4 = start_packet_4_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; +assign rx_bad_block = rx_bad_block_reg; wire last_cycle = state_reg == STATE_LAST; @@ -407,6 +410,7 @@ always @(posedge clk) begin start_packet_4_reg <= 1'b0; error_bad_frame_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; + rx_bad_block_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; crc_state3 <= 32'hFFFFFFFF; @@ -428,6 +432,7 @@ always @(posedge clk) begin start_packet_4_reg <= 1'b0; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; + rx_bad_block_reg <= 1'b0; delay_type_valid <= 1'b0; @@ -471,9 +476,13 @@ always @(posedge clk) begin delay_type_valid <= 1'b1; input_type_d0 <= INPUT_TYPE_DATA; end - default: input_type_d0 <= INPUT_TYPE_ERROR; + default: begin + rx_bad_block_reg <= 1'b1; + input_type_d0 <= INPUT_TYPE_ERROR; + end endcase end else begin + rx_bad_block_reg <= 1'b1; input_type_d0 <= INPUT_TYPE_ERROR; end end else begin @@ -489,9 +498,13 @@ always @(posedge clk) begin BLOCK_TYPE_TERM_5: input_type_d0 <= INPUT_TYPE_TERM_5; BLOCK_TYPE_TERM_6: input_type_d0 <= INPUT_TYPE_TERM_6; BLOCK_TYPE_TERM_7: input_type_d0 <= INPUT_TYPE_TERM_7; - default: input_type_d0 <= INPUT_TYPE_ERROR; + default: begin + rx_bad_block_reg <= 1'b1; + input_type_d0 <= INPUT_TYPE_ERROR; + end endcase end else begin + rx_bad_block_reg <= 1'b1; input_type_d0 <= INPUT_TYPE_ERROR; end end diff --git a/rtl/eth_mac_phy_10g.v b/rtl/eth_mac_phy_10g.v index a06da75f8..061c52942 100644 --- a/rtl/eth_mac_phy_10g.v +++ b/rtl/eth_mac_phy_10g.v @@ -87,6 +87,7 @@ module eth_mac_phy_10g # output wire rx_start_packet_4, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, + output wire rx_bad_block, output wire rx_block_lock, output wire rx_high_ber, @@ -121,6 +122,7 @@ eth_mac_phy_10g_rx_inst ( .rx_start_packet_4(rx_start_packet_4), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), .rx_high_ber(rx_high_ber) ); diff --git a/rtl/eth_mac_phy_10g_fifo.v b/rtl/eth_mac_phy_10g_fifo.v index 038194636..8c98f418d 100644 --- a/rtl/eth_mac_phy_10g_fifo.v +++ b/rtl/eth_mac_phy_10g_fifo.v @@ -97,6 +97,7 @@ module eth_mac_phy_10g_fifo # output wire tx_fifo_good_frame, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, + output wire rx_bad_block, output wire rx_block_lock, output wire rx_high_ber, output wire rx_fifo_overflow, @@ -155,29 +156,30 @@ end wire rx_error_bad_frame_int; wire rx_error_bad_fcs_int; -reg [3:0] rx_sync_reg_1 = 4'd0; -reg [3:0] rx_sync_reg_2 = 4'd0; -reg [3:0] rx_sync_reg_3 = 4'd0; -reg [3:0] rx_sync_reg_4 = 4'd0; +reg [4:0] rx_sync_reg_1 = 5'd0; +reg [4:0] rx_sync_reg_2 = 5'd0; +reg [4:0] rx_sync_reg_3 = 5'd0; +reg [4:0] rx_sync_reg_4 = 5'd0; assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; -assign rx_block_lock = rx_sync_reg_3[2] ^ rx_sync_reg_4[2]; -assign rx_high_ber = rx_sync_reg_3[3] ^ rx_sync_reg_4[3]; +assign rx_bad_block = rx_sync_reg_3[2] ^ rx_sync_reg_4[2]; +assign rx_block_lock = rx_sync_reg_3[3] ^ rx_sync_reg_4[3]; +assign rx_high_ber = rx_sync_reg_3[4] ^ rx_sync_reg_4[4]; always @(posedge rx_clk or posedge rx_rst) begin if (rx_rst) begin - rx_sync_reg_1 <= 4'd0; + rx_sync_reg_1 <= 5'd0; end else begin - rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_high_ber_int, rx_block_lock_int, rx_error_bad_frame_int, rx_error_bad_frame_int}; + rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_high_ber_int, rx_block_lock_int, rx_bad_block_int, rx_error_bad_frame_int, rx_error_bad_frame_int}; end end always @(posedge logic_clk or posedge logic_rst) begin if (logic_rst) begin - rx_sync_reg_2 <= 4'd0; - rx_sync_reg_3 <= 4'd0; - rx_sync_reg_4 <= 4'd0; + rx_sync_reg_2 <= 5'd0; + rx_sync_reg_3 <= 5'd0; + rx_sync_reg_4 <= 5'd0; end else begin rx_sync_reg_2 <= rx_sync_reg_1; rx_sync_reg_3 <= rx_sync_reg_2; @@ -222,6 +224,7 @@ eth_mac_phy_10g_inst ( .tx_error_underflow(tx_error_underflow_int), .rx_error_bad_frame(rx_error_bad_frame_int), .rx_error_bad_fcs(rx_error_bad_fcs_int), + .rx_bad_block(rx_bad_block_int), .rx_block_lock(rx_block_lock_int), .rx_high_ber(rx_high_ber_int), .ifg_delay(ifg_delay) diff --git a/rtl/eth_mac_phy_10g_rx.v b/rtl/eth_mac_phy_10g_rx.v index d6f48cfb4..52d7c1c64 100644 --- a/rtl/eth_mac_phy_10g_rx.v +++ b/rtl/eth_mac_phy_10g_rx.v @@ -67,6 +67,7 @@ module eth_mac_phy_10g_rx # output wire rx_start_packet_4, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, + output wire rx_bad_block, output wire rx_block_lock, output wire rx_high_ber ); @@ -158,7 +159,8 @@ axis_baser_rx_inst ( .start_packet_0(rx_start_packet_0), .start_packet_4(rx_start_packet_4), .error_bad_frame(rx_error_bad_frame), - .error_bad_fcs(rx_error_bad_fcs) + .error_bad_fcs(rx_error_bad_fcs), + .rx_bad_block(rx_bad_block) ); eth_phy_10g_rx_frame_sync #( diff --git a/rtl/eth_phy_10g.v b/rtl/eth_phy_10g.v index 4d4e21751..97be98925 100644 --- a/rtl/eth_phy_10g.v +++ b/rtl/eth_phy_10g.v @@ -65,6 +65,7 @@ module eth_phy_10g # /* * Status */ + output wire rx_bad_block, output wire rx_block_lock, output wire rx_high_ber ); @@ -86,6 +87,7 @@ eth_phy_10g_rx_inst ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), .rx_high_ber(rx_high_ber) ); diff --git a/rtl/eth_phy_10g_rx.v b/rtl/eth_phy_10g_rx.v index 45a99e3aa..911919b43 100644 --- a/rtl/eth_phy_10g_rx.v +++ b/rtl/eth_phy_10g_rx.v @@ -59,6 +59,7 @@ module eth_phy_10g_rx # /* * Status */ + output wire rx_bad_block, output wire rx_block_lock, output wire rx_high_ber ); @@ -144,7 +145,7 @@ xgmii_baser_dec_inst ( .encoded_rx_hdr(encoded_rx_hdr_reg), .xgmii_rxd(xgmii_rxd), .xgmii_rxc(xgmii_rxc), - .rx_bad_block() + .rx_bad_block(rx_bad_block) ); eth_phy_10g_rx_frame_sync #( diff --git a/tb/test_axis_baser_rx_64.py b/tb/test_axis_baser_rx_64.py index c1a06fded..053628b5f 100755 --- a/tb/test_axis_baser_rx_64.py +++ b/tb/test_axis_baser_rx_64.py @@ -69,6 +69,7 @@ def bench(): start_packet_4 = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) + rx_bad_block = Signal(bool(0)) # sources and sinks source = baser_serdes_ep.BaseRSerdesSource() @@ -113,7 +114,8 @@ def bench(): start_packet_0=start_packet_0, start_packet_4=start_packet_4, error_bad_frame=error_bad_frame, - error_bad_fcs=error_bad_fcs + error_bad_fcs=error_bad_fcs, + rx_bad_block=rx_bad_block ) @always(delay(4)) diff --git a/tb/test_axis_baser_rx_64.v b/tb/test_axis_baser_rx_64.v index cf644a276..202c217e2 100644 --- a/tb/test_axis_baser_rx_64.v +++ b/tb/test_axis_baser_rx_64.v @@ -54,6 +54,7 @@ wire start_packet_0; wire start_packet_4; wire error_bad_frame; wire error_bad_fcs; +wire rx_bad_block; initial begin // myhdl integration @@ -73,7 +74,8 @@ initial begin start_packet_0, start_packet_4, error_bad_frame, - error_bad_fcs + error_bad_fcs, + rx_bad_block ); // dump file @@ -99,7 +101,8 @@ UUT ( .start_packet_0(start_packet_0), .start_packet_4(start_packet_4), .error_bad_frame(error_bad_frame), - .error_bad_fcs(error_bad_fcs) + .error_bad_fcs(error_bad_fcs), + .rx_bad_block(rx_bad_block) ); endmodule diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py index f9650fbdb..777d0ae15 100755 --- a/tb/test_eth_mac_phy_10g.py +++ b/tb/test_eth_mac_phy_10g.py @@ -103,6 +103,7 @@ def bench(): rx_start_packet_4 = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) + rx_bad_block = Signal(bool(0)) rx_block_lock = Signal(bool(0)) rx_high_ber = Signal(bool(0)) @@ -191,6 +192,7 @@ def bench(): rx_start_packet_4=rx_start_packet_4, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, + rx_bad_block=rx_bad_block, rx_block_lock=rx_block_lock, rx_high_ber=rx_high_ber, ifg_delay=ifg_delay diff --git a/tb/test_eth_mac_phy_10g.v b/tb/test_eth_mac_phy_10g.v index 825302e1a..5f70fcc10 100644 --- a/tb/test_eth_mac_phy_10g.v +++ b/tb/test_eth_mac_phy_10g.v @@ -79,6 +79,7 @@ wire rx_start_packet_0; wire rx_start_packet_4; wire rx_error_bad_frame; wire rx_error_bad_fcs; +wire rx_bad_block; wire rx_block_lock; wire rx_high_ber; @@ -118,6 +119,7 @@ initial begin rx_start_packet_4, rx_error_bad_frame, rx_error_bad_fcs, + rx_bad_block, rx_block_lock, rx_high_ber ); @@ -168,6 +170,7 @@ UUT ( .rx_start_packet_4(rx_start_packet_4), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), .rx_high_ber(rx_high_ber), .ifg_delay(ifg_delay) diff --git a/tb/test_eth_mac_phy_10g_fifo.py b/tb/test_eth_mac_phy_10g_fifo.py index e87bd9a4a..8e084b8de 100755 --- a/tb/test_eth_mac_phy_10g_fifo.py +++ b/tb/test_eth_mac_phy_10g_fifo.py @@ -115,6 +115,7 @@ def bench(): tx_fifo_good_frame = Signal(bool(0)) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) + rx_bad_block = Signal(bool(0)) rx_block_lock = Signal(bool(0)) rx_high_ber = Signal(bool(0)) rx_fifo_overflow = Signal(bool(0)) @@ -209,6 +210,7 @@ def bench(): tx_fifo_good_frame=tx_fifo_good_frame, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, + rx_bad_block=rx_bad_block, rx_block_lock=rx_block_lock, rx_high_ber=rx_high_ber, rx_fifo_overflow=rx_fifo_overflow, diff --git a/tb/test_eth_mac_phy_10g_fifo.v b/tb/test_eth_mac_phy_10g_fifo.v index 7c09e923f..81b8ab1f2 100644 --- a/tb/test_eth_mac_phy_10g_fifo.v +++ b/tb/test_eth_mac_phy_10g_fifo.v @@ -89,6 +89,7 @@ wire tx_fifo_bad_frame; wire tx_fifo_good_frame; wire rx_error_bad_frame; wire rx_error_bad_fcs; +wire rx_bad_block; wire rx_block_lock; wire rx_high_ber; wire rx_fifo_overflow; @@ -133,6 +134,7 @@ initial begin tx_fifo_good_frame, rx_error_bad_frame, rx_error_bad_fcs, + rx_bad_block, rx_block_lock, rx_high_ber, rx_fifo_overflow, @@ -196,6 +198,7 @@ UUT ( .tx_fifo_good_frame(tx_fifo_good_frame), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), .rx_high_ber(rx_high_ber), .rx_fifo_overflow(rx_fifo_overflow), diff --git a/tb/test_eth_phy_10g_64.py b/tb/test_eth_phy_10g_64.py index e24ae570b..aa8cf8215 100755 --- a/tb/test_eth_phy_10g_64.py +++ b/tb/test_eth_phy_10g_64.py @@ -83,6 +83,7 @@ def bench(): serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_tx_hdr = Signal(intbv(0)[HDR_WIDTH:]) serdes_rx_bitslip = Signal(bool(0)) + rx_bad_block = Signal(bool(0)) rx_block_lock = Signal(bool(0)) rx_high_ber = Signal(bool(0)) @@ -147,6 +148,7 @@ def bench(): serdes_rx_data=serdes_rx_data, serdes_rx_hdr=serdes_rx_hdr, serdes_rx_bitslip=serdes_rx_bitslip, + rx_bad_block=rx_bad_block, rx_block_lock=rx_block_lock, rx_high_ber=rx_high_ber ) diff --git a/tb/test_eth_phy_10g_64.v b/tb/test_eth_phy_10g_64.v index 61a78d7af..2e565f000 100644 --- a/tb/test_eth_phy_10g_64.v +++ b/tb/test_eth_phy_10g_64.v @@ -59,6 +59,7 @@ wire [CTRL_WIDTH-1:0] xgmii_rxc; wire [DATA_WIDTH-1:0] serdes_tx_data; wire [HDR_WIDTH-1:0] serdes_tx_hdr; wire serdes_rx_bitslip; +wire rx_bad_block; wire rx_block_lock; wire rx_high_ber; @@ -83,6 +84,7 @@ initial begin serdes_tx_data, serdes_tx_hdr, serdes_rx_bitslip, + rx_bad_block, rx_block_lock, rx_high_ber ); @@ -114,6 +116,7 @@ UUT ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), .rx_high_ber(rx_high_ber) ); diff --git a/tb/test_eth_phy_10g_rx_64.py b/tb/test_eth_phy_10g_rx_64.py index 1effa27e8..29195afa7 100755 --- a/tb/test_eth_phy_10g_rx_64.py +++ b/tb/test_eth_phy_10g_rx_64.py @@ -72,6 +72,7 @@ def bench(): xgmii_rxd = Signal(intbv(0)[DATA_WIDTH:]) xgmii_rxc = Signal(intbv(0)[CTRL_WIDTH:]) serdes_rx_bitslip = Signal(bool(0)) + rx_bad_block = Signal(bool(0)) rx_block_lock = Signal(bool(0)) rx_high_ber = Signal(bool(0)) @@ -109,6 +110,7 @@ def bench(): serdes_rx_data=serdes_rx_data, serdes_rx_hdr=serdes_rx_hdr, serdes_rx_bitslip=serdes_rx_bitslip, + rx_bad_block=rx_bad_block, rx_block_lock=rx_block_lock, rx_high_ber=rx_high_ber ) diff --git a/tb/test_eth_phy_10g_rx_64.v b/tb/test_eth_phy_10g_rx_64.v index 221ea84ec..1a2d1bbab 100644 --- a/tb/test_eth_phy_10g_rx_64.v +++ b/tb/test_eth_phy_10g_rx_64.v @@ -51,6 +51,7 @@ reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; wire [DATA_WIDTH-1:0] xgmii_rxd; wire [CTRL_WIDTH-1:0] xgmii_rxc; wire serdes_rx_bitslip; +wire rx_bad_block; wire rx_block_lock; wire rx_high_ber; @@ -67,6 +68,7 @@ initial begin xgmii_rxd, xgmii_rxc, serdes_rx_bitslip, + rx_bad_block, rx_block_lock, rx_high_ber ); @@ -92,6 +94,7 @@ UUT ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), .rx_high_ber(rx_high_ber) ); From e3fcb0fa1de79daf7d2c81703b651d0e7cf9b06b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 26 Apr 2019 18:36:09 -0700 Subject: [PATCH 557/617] Test shorter frames --- tb/test_axis_adapter_64_8.py | 15 --------------- tb/test_axis_adapter_8_64.py | 15 --------------- 2 files changed, 30 deletions(-) diff --git a/tb/test_axis_adapter_64_8.py b/tb/test_axis_adapter_64_8.py index bd51eca7e..7c1b7b48d 100755 --- a/tb/test_axis_adapter_64_8.py +++ b/tb/test_axis_adapter_64_8.py @@ -192,9 +192,6 @@ def bench(): current_test.next = 1 test_frame = axis_ep.AXIStreamFrame( - b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + bytearray(range(payload_len)), id=1, dest=1, @@ -221,17 +218,11 @@ def bench(): current_test.next = 2 test_frame1 = axis_ep.AXIStreamFrame( - b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + bytearray(range(payload_len)), id=2, dest=1, ) test_frame2 = axis_ep.AXIStreamFrame( - b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + bytearray(range(payload_len)), id=2, dest=2, @@ -264,18 +255,12 @@ def bench(): current_test.next = 3 test_frame1 = axis_ep.AXIStreamFrame( - b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + bytearray(range(payload_len)), id=3, dest=1, last_cycle_user=1 ) test_frame2 = axis_ep.AXIStreamFrame( - b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + bytearray(range(payload_len)), id=3, dest=2, diff --git a/tb/test_axis_adapter_8_64.py b/tb/test_axis_adapter_8_64.py index 4acafae6a..43c2a46e0 100755 --- a/tb/test_axis_adapter_8_64.py +++ b/tb/test_axis_adapter_8_64.py @@ -192,9 +192,6 @@ def bench(): current_test.next = 1 test_frame = axis_ep.AXIStreamFrame( - b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + bytearray(range(payload_len)), id=1, dest=1, @@ -221,17 +218,11 @@ def bench(): current_test.next = 2 test_frame1 = axis_ep.AXIStreamFrame( - b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + bytearray(range(payload_len)), id=2, dest=1, ) test_frame2 = axis_ep.AXIStreamFrame( - b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + bytearray(range(payload_len)), id=2, dest=2, @@ -264,18 +255,12 @@ def bench(): current_test.next = 3 test_frame1 = axis_ep.AXIStreamFrame( - b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + bytearray(range(payload_len)), id=3, dest=1, last_cycle_user=1 ) test_frame2 = axis_ep.AXIStreamFrame( - b'\xDA\xD1\xD2\xD3\xD4\xD5' + - b'\x5A\x51\x52\x53\x54\x55' + - b'\x80\x00' + bytearray(range(payload_len)), id=3, dest=2, From 8e969aa14ce74b66e48099686fb9929ede637c87 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 26 Apr 2019 18:38:25 -0700 Subject: [PATCH 558/617] Add FIFO/width adapter wrapper modules --- rtl/axis_async_fifo_adapter.v | 321 +++++++++++++++++++++++ rtl/axis_fifo_adapter.v | 311 +++++++++++++++++++++++ tb/test_axis_async_fifo_adapter_64_8.py | 324 ++++++++++++++++++++++++ tb/test_axis_async_fifo_adapter_64_8.v | 165 ++++++++++++ tb/test_axis_async_fifo_adapter_8_64.py | 324 ++++++++++++++++++++++++ tb/test_axis_async_fifo_adapter_8_64.v | 165 ++++++++++++ tb/test_axis_fifo_adapter_64_8.py | 312 +++++++++++++++++++++++ tb/test_axis_fifo_adapter_64_8.v | 156 ++++++++++++ tb/test_axis_fifo_adapter_8_64.py | 312 +++++++++++++++++++++++ tb/test_axis_fifo_adapter_8_64.v | 156 ++++++++++++ 10 files changed, 2546 insertions(+) create mode 100644 rtl/axis_async_fifo_adapter.v create mode 100644 rtl/axis_fifo_adapter.v create mode 100755 tb/test_axis_async_fifo_adapter_64_8.py create mode 100644 tb/test_axis_async_fifo_adapter_64_8.v create mode 100755 tb/test_axis_async_fifo_adapter_8_64.py create mode 100644 tb/test_axis_async_fifo_adapter_8_64.v create mode 100755 tb/test_axis_fifo_adapter_64_8.py create mode 100644 tb/test_axis_fifo_adapter_64_8.v create mode 100755 tb/test_axis_fifo_adapter_8_64.py create mode 100644 tb/test_axis_fifo_adapter_8_64.v diff --git a/rtl/axis_async_fifo_adapter.v b/rtl/axis_async_fifo_adapter.v new file mode 100644 index 000000000..d8e626096 --- /dev/null +++ b/rtl/axis_async_fifo_adapter.v @@ -0,0 +1,321 @@ +/* + +Copyright (c) 2019 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 asynchronous FIFO with width converter + */ +module axis_async_fifo_adapter # +( + parameter ADDR_WIDTH = 12, + parameter S_DATA_WIDTH = 8, + parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8), + parameter S_KEEP_WIDTH = (S_DATA_WIDTH/8), + parameter M_DATA_WIDTH = 8, + parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8), + parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + parameter FRAME_FIFO = 0, + parameter USER_BAD_FRAME_VALUE = 1'b1, + parameter USER_BAD_FRAME_MASK = 1'b1, + parameter DROP_BAD_FRAME = 0, + parameter DROP_WHEN_FULL = 0 +) +( + /* + * AXI input + */ + input wire s_clk, + input wire s_rst, + input wire [S_DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI output + */ + input wire m_clk, + input wire m_rst, + output wire [M_DATA_WIDTH-1:0] m_axis_tdata, + output wire [M_KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * Status + */ + output wire s_status_overflow, + output wire s_status_bad_frame, + output wire s_status_good_frame, + output wire m_status_overflow, + output wire m_status_bad_frame, + output wire m_status_good_frame +); + +// force keep width to 1 when disabled +parameter S_KEEP_WIDTH_INT = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1; +parameter M_KEEP_WIDTH_INT = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1; + +// bus word sizes (must be identical) +parameter S_DATA_WORD_SIZE = S_DATA_WIDTH / S_KEEP_WIDTH_INT; +parameter M_DATA_WORD_SIZE = M_DATA_WIDTH / M_KEEP_WIDTH_INT; +// output bus is wider +parameter EXPAND_BUS = M_KEEP_WIDTH_INT > S_KEEP_WIDTH_INT; +// total data and keep widths +parameter DATA_WIDTH = EXPAND_BUS ? M_DATA_WIDTH : S_DATA_WIDTH; +parameter KEEP_WIDTH = EXPAND_BUS ? M_KEEP_WIDTH_INT : S_KEEP_WIDTH_INT; + +// bus width assertions +initial begin + if (S_DATA_WORD_SIZE * S_KEEP_WIDTH_INT != S_DATA_WIDTH) begin + $error("Error: input data width not evenly divisble"); + $finish; + end + + if (M_DATA_WORD_SIZE * M_KEEP_WIDTH_INT != M_DATA_WIDTH) begin + $error("Error: output data width not evenly divisble"); + $finish; + end + + if (S_DATA_WORD_SIZE != M_DATA_WORD_SIZE) begin + $error("Error: word size mismatch"); + $finish; + end +end + +wire [DATA_WIDTH-1:0] pre_fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] pre_fifo_axis_tkeep; +wire pre_fifo_axis_tvalid; +wire pre_fifo_axis_tready; +wire pre_fifo_axis_tlast; +wire [ID_WIDTH-1:0] pre_fifo_axis_tid; +wire [DEST_WIDTH-1:0] pre_fifo_axis_tdest; +wire [USER_WIDTH-1:0] pre_fifo_axis_tuser; + +wire [DATA_WIDTH-1:0] post_fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] post_fifo_axis_tkeep; +wire post_fifo_axis_tvalid; +wire post_fifo_axis_tready; +wire post_fifo_axis_tlast; +wire [ID_WIDTH-1:0] post_fifo_axis_tid; +wire [DEST_WIDTH-1:0] post_fifo_axis_tdest; +wire [USER_WIDTH-1:0] post_fifo_axis_tuser; + +generate + +if (M_KEEP_WIDTH == S_KEEP_WIDTH) begin + + // same width, no adapter needed + + assign pre_fifo_axis_tdata = s_axis_tdata; + assign pre_fifo_axis_tkeep = s_axis_tkeep; + assign pre_fifo_axis_tvalid = s_axis_tvalid; + assign s_axis_tready = pre_fifo_axis_tready; + assign pre_fifo_axis_tlast = s_axis_tlast; + assign pre_fifo_axis_tid = s_axis_tid; + assign pre_fifo_axis_tdest = s_axis_tdest; + assign pre_fifo_axis_tuser = s_axis_tuser; + + assign m_axis_tdata = post_fifo_axis_tdata; + assign m_axis_tkeep = post_fifo_axis_tkeep; + assign m_axis_tvalid = post_fifo_axis_tvalid; + assign post_fifo_axis_tready = m_axis_tready; + assign m_axis_tlast = post_fifo_axis_tlast; + assign m_axis_tid = post_fifo_axis_tid; + assign m_axis_tdest = post_fifo_axis_tdest; + assign m_axis_tuser = post_fifo_axis_tuser; + + +end else if (EXPAND_BUS) begin + + // output wider, adapt width before FIFO + + axis_adapter #( + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) + ) + adapter_inst ( + .clk(s_clk), + .rst(s_rst), + // AXI input + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_axis_tdata(pre_fifo_axis_tdata), + .m_axis_tkeep(pre_fifo_axis_tkeep), + .m_axis_tvalid(pre_fifo_axis_tvalid), + .m_axis_tready(pre_fifo_axis_tready), + .m_axis_tlast(pre_fifo_axis_tlast), + .m_axis_tid(pre_fifo_axis_tid), + .m_axis_tdest(pre_fifo_axis_tdest), + .m_axis_tuser(pre_fifo_axis_tuser) + ); + + assign m_axis_tdata = post_fifo_axis_tdata; + assign m_axis_tkeep = post_fifo_axis_tkeep; + assign m_axis_tvalid = post_fifo_axis_tvalid; + assign post_fifo_axis_tready = m_axis_tready; + assign m_axis_tlast = post_fifo_axis_tlast; + assign m_axis_tid = post_fifo_axis_tid; + assign m_axis_tdest = post_fifo_axis_tdest; + assign m_axis_tuser = post_fifo_axis_tuser; + +end else begin + + // input wider, adapt width after FIFO + + assign pre_fifo_axis_tdata = s_axis_tdata; + assign pre_fifo_axis_tkeep = s_axis_tkeep; + assign pre_fifo_axis_tvalid = s_axis_tvalid; + assign s_axis_tready = pre_fifo_axis_tready; + assign pre_fifo_axis_tlast = s_axis_tlast; + assign pre_fifo_axis_tid = s_axis_tid; + assign pre_fifo_axis_tdest = s_axis_tdest; + assign pre_fifo_axis_tuser = s_axis_tuser; + + axis_adapter #( + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) + ) + adapter_inst ( + .clk(m_clk), + .rst(m_rst), + // AXI input + .s_axis_tdata(post_fifo_axis_tdata), + .s_axis_tkeep(post_fifo_axis_tkeep), + .s_axis_tvalid(post_fifo_axis_tvalid), + .s_axis_tready(post_fifo_axis_tready), + .s_axis_tlast(post_fifo_axis_tlast), + .s_axis_tid(post_fifo_axis_tid), + .s_axis_tdest(post_fifo_axis_tdest), + .s_axis_tuser(post_fifo_axis_tuser), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) + ); + +end + +endgenerate + +axis_async_fifo #( + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(EXPAND_BUS ? M_KEEP_ENABLE : S_KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(1), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL) +) +fifo_inst ( + // Common reset + .async_rst(s_rst | m_rst), + // AXI input + .s_clk(s_clk), + .s_axis_tdata(pre_fifo_axis_tdata), + .s_axis_tkeep(pre_fifo_axis_tkeep), + .s_axis_tvalid(pre_fifo_axis_tvalid), + .s_axis_tready(pre_fifo_axis_tready), + .s_axis_tlast(pre_fifo_axis_tlast), + .s_axis_tid(pre_fifo_axis_tid), + .s_axis_tdest(pre_fifo_axis_tdest), + .s_axis_tuser(pre_fifo_axis_tuser), + // AXI output + .m_clk(m_clk), + .m_axis_tdata(post_fifo_axis_tdata), + .m_axis_tkeep(post_fifo_axis_tkeep), + .m_axis_tvalid(post_fifo_axis_tvalid), + .m_axis_tready(post_fifo_axis_tready), + .m_axis_tlast(post_fifo_axis_tlast), + .m_axis_tid(post_fifo_axis_tid), + .m_axis_tdest(post_fifo_axis_tdest), + .m_axis_tuser(post_fifo_axis_tuser), + // Status + .s_status_overflow(s_status_overflow), + .s_status_bad_frame(s_status_bad_frame), + .s_status_good_frame(s_status_good_frame), + .m_status_overflow(m_status_overflow), + .m_status_bad_frame(m_status_bad_frame), + .m_status_good_frame(m_status_good_frame) +); + +endmodule diff --git a/rtl/axis_fifo_adapter.v b/rtl/axis_fifo_adapter.v new file mode 100644 index 000000000..fac142c7d --- /dev/null +++ b/rtl/axis_fifo_adapter.v @@ -0,0 +1,311 @@ +/* + +Copyright (c) 2019 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4-Stream FIFO with width converter + */ +module axis_fifo_adapter # +( + parameter ADDR_WIDTH = 12, + parameter S_DATA_WIDTH = 8, + parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8), + parameter S_KEEP_WIDTH = (S_DATA_WIDTH/8), + parameter M_DATA_WIDTH = 8, + parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8), + parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8), + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + parameter FRAME_FIFO = 0, + parameter USER_BAD_FRAME_VALUE = 1'b1, + parameter USER_BAD_FRAME_MASK = 1'b1, + parameter DROP_BAD_FRAME = 0, + parameter DROP_WHEN_FULL = 0 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [S_DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI output + */ + output wire [M_DATA_WIDTH-1:0] m_axis_tdata, + output wire [M_KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * Status + */ + output wire status_overflow, + output wire status_bad_frame, + output wire status_good_frame +); + +// force keep width to 1 when disabled +parameter S_KEEP_WIDTH_INT = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1; +parameter M_KEEP_WIDTH_INT = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1; + +// bus word sizes (must be identical) +parameter S_DATA_WORD_SIZE = S_DATA_WIDTH / S_KEEP_WIDTH_INT; +parameter M_DATA_WORD_SIZE = M_DATA_WIDTH / M_KEEP_WIDTH_INT; +// output bus is wider +parameter EXPAND_BUS = M_KEEP_WIDTH_INT > S_KEEP_WIDTH_INT; +// total data and keep widths +parameter DATA_WIDTH = EXPAND_BUS ? M_DATA_WIDTH : S_DATA_WIDTH; +parameter KEEP_WIDTH = EXPAND_BUS ? M_KEEP_WIDTH_INT : S_KEEP_WIDTH_INT; + +// bus width assertions +initial begin + if (S_DATA_WORD_SIZE * S_KEEP_WIDTH_INT != S_DATA_WIDTH) begin + $error("Error: input data width not evenly divisble"); + $finish; + end + + if (M_DATA_WORD_SIZE * M_KEEP_WIDTH_INT != M_DATA_WIDTH) begin + $error("Error: output data width not evenly divisble"); + $finish; + end + + if (S_DATA_WORD_SIZE != M_DATA_WORD_SIZE) begin + $error("Error: word size mismatch"); + $finish; + end +end + +wire [DATA_WIDTH-1:0] pre_fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] pre_fifo_axis_tkeep; +wire pre_fifo_axis_tvalid; +wire pre_fifo_axis_tready; +wire pre_fifo_axis_tlast; +wire [ID_WIDTH-1:0] pre_fifo_axis_tid; +wire [DEST_WIDTH-1:0] pre_fifo_axis_tdest; +wire [USER_WIDTH-1:0] pre_fifo_axis_tuser; + +wire [DATA_WIDTH-1:0] post_fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] post_fifo_axis_tkeep; +wire post_fifo_axis_tvalid; +wire post_fifo_axis_tready; +wire post_fifo_axis_tlast; +wire [ID_WIDTH-1:0] post_fifo_axis_tid; +wire [DEST_WIDTH-1:0] post_fifo_axis_tdest; +wire [USER_WIDTH-1:0] post_fifo_axis_tuser; + +generate + +if (M_KEEP_WIDTH_INT == S_KEEP_WIDTH_INT) begin + + // same width, no adapter needed + + assign pre_fifo_axis_tdata = s_axis_tdata; + assign pre_fifo_axis_tkeep = s_axis_tkeep; + assign pre_fifo_axis_tvalid = s_axis_tvalid; + assign s_axis_tready = pre_fifo_axis_tready; + assign pre_fifo_axis_tlast = s_axis_tlast; + assign pre_fifo_axis_tid = s_axis_tid; + assign pre_fifo_axis_tdest = s_axis_tdest; + assign pre_fifo_axis_tuser = s_axis_tuser; + + assign m_axis_tdata = post_fifo_axis_tdata; + assign m_axis_tkeep = post_fifo_axis_tkeep; + assign m_axis_tvalid = post_fifo_axis_tvalid; + assign post_fifo_axis_tready = m_axis_tready; + assign m_axis_tlast = post_fifo_axis_tlast; + assign m_axis_tid = post_fifo_axis_tid; + assign m_axis_tdest = post_fifo_axis_tdest; + assign m_axis_tuser = post_fifo_axis_tuser; + +end else if (EXPAND_BUS) begin + + // output wider, adapt width before FIFO + + axis_adapter #( + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) + ) + adapter_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_axis_tdata(pre_fifo_axis_tdata), + .m_axis_tkeep(pre_fifo_axis_tkeep), + .m_axis_tvalid(pre_fifo_axis_tvalid), + .m_axis_tready(pre_fifo_axis_tready), + .m_axis_tlast(pre_fifo_axis_tlast), + .m_axis_tid(pre_fifo_axis_tid), + .m_axis_tdest(pre_fifo_axis_tdest), + .m_axis_tuser(pre_fifo_axis_tuser) + ); + + assign m_axis_tdata = post_fifo_axis_tdata; + assign m_axis_tkeep = post_fifo_axis_tkeep; + assign m_axis_tvalid = post_fifo_axis_tvalid; + assign post_fifo_axis_tready = m_axis_tready; + assign m_axis_tlast = post_fifo_axis_tlast; + assign m_axis_tid = post_fifo_axis_tid; + assign m_axis_tdest = post_fifo_axis_tdest; + assign m_axis_tuser = post_fifo_axis_tuser; + +end else begin + + // input wider, adapt width after FIFO + + assign pre_fifo_axis_tdata = s_axis_tdata; + assign pre_fifo_axis_tkeep = s_axis_tkeep; + assign pre_fifo_axis_tvalid = s_axis_tvalid; + assign s_axis_tready = pre_fifo_axis_tready; + assign pre_fifo_axis_tlast = s_axis_tlast; + assign pre_fifo_axis_tid = s_axis_tid; + assign pre_fifo_axis_tdest = s_axis_tdest; + assign pre_fifo_axis_tuser = s_axis_tuser; + + axis_adapter #( + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) + ) + adapter_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(post_fifo_axis_tdata), + .s_axis_tkeep(post_fifo_axis_tkeep), + .s_axis_tvalid(post_fifo_axis_tvalid), + .s_axis_tready(post_fifo_axis_tready), + .s_axis_tlast(post_fifo_axis_tlast), + .s_axis_tid(post_fifo_axis_tid), + .s_axis_tdest(post_fifo_axis_tdest), + .s_axis_tuser(post_fifo_axis_tuser), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) + ); + +end + +endgenerate + +axis_fifo #( + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(EXPAND_BUS ? M_KEEP_ENABLE : S_KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(1), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL) +) +fifo_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(pre_fifo_axis_tdata), + .s_axis_tkeep(pre_fifo_axis_tkeep), + .s_axis_tvalid(pre_fifo_axis_tvalid), + .s_axis_tready(pre_fifo_axis_tready), + .s_axis_tlast(pre_fifo_axis_tlast), + .s_axis_tid(pre_fifo_axis_tid), + .s_axis_tdest(pre_fifo_axis_tdest), + .s_axis_tuser(pre_fifo_axis_tuser), + // AXI output + .m_axis_tdata(post_fifo_axis_tdata), + .m_axis_tkeep(post_fifo_axis_tkeep), + .m_axis_tvalid(post_fifo_axis_tvalid), + .m_axis_tready(post_fifo_axis_tready), + .m_axis_tlast(post_fifo_axis_tlast), + .m_axis_tid(post_fifo_axis_tid), + .m_axis_tdest(post_fifo_axis_tdest), + .m_axis_tuser(post_fifo_axis_tuser), + // Status + .status_overflow(status_overflow), + .status_bad_frame(status_bad_frame), + .status_good_frame(status_good_frame) +); + +endmodule diff --git a/tb/test_axis_async_fifo_adapter_64_8.py b/tb/test_axis_async_fifo_adapter_64_8.py new file mode 100755 index 000000000..9f1cca6a7 --- /dev/null +++ b/tb/test_axis_async_fifo_adapter_64_8.py @@ -0,0 +1,324 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep + +module = 'axis_async_fifo_adapter' +testbench = 'test_%s_64_8' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_adapter.v") +srcs.append("../rtl/axis_async_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + ADDR_WIDTH = 2 + S_DATA_WIDTH = 64 + S_KEEP_ENABLE = (S_DATA_WIDTH>8) + S_KEEP_WIDTH = (S_DATA_WIDTH/8) + M_DATA_WIDTH = 8 + M_KEEP_ENABLE = (M_DATA_WIDTH>8) + M_KEEP_WIDTH = (M_DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + FRAME_FIFO = 0 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 0 + DROP_WHEN_FULL = 0 + + # Inputs + s_clk = Signal(bool(0)) + s_rst = Signal(bool(0)) + m_clk = Signal(bool(0)) + m_rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + s_axis_tdata = Signal(intbv(0)[S_DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[S_KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) + + # Outputs + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[M_DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[M_KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + + # sources and sinks + source_pause = Signal(bool(0)) + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource() + + source_logic = source.create_logic( + s_clk, + s_rst, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + m_clk, + m_rst, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, + pause=sink_pause, + name='sink' + ) + + # DUT + if os.system(build_cmd): + raise Exception("Error running build command") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + s_clk=s_clk, + s_rst=s_rst, + m_clk=m_clk, + m_rst=m_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_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, + + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser + ) + + @always(delay(4)) + def s_clkgen(): + s_clk.next = not s_clk + + @always(delay(5)) + def m_clkgen(): + m_clk.next = not m_clk + + def wait_normal(): + while s_axis_tvalid or m_axis_tvalid: + yield s_clk.posedge + + def wait_pause_source(): + while s_axis_tvalid or m_axis_tvalid: + yield s_clk.posedge + yield s_clk.posedge + source_pause.next = False + yield s_clk.posedge + source_pause.next = True + yield s_clk.posedge + + source_pause.next = False + + def wait_pause_sink(): + while s_axis_tvalid or m_axis_tvalid: + sink_pause.next = True + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + sink_pause.next = False + yield s_clk.posedge + + @instance + def check(): + yield delay(100) + yield s_clk.posedge + s_rst.next = 1 + m_rst.next = 1 + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + s_rst.next = 0 + m_rst.next = 0 + yield s_clk.posedge + yield delay(100) + yield s_clk.posedge + + for payload_len in range(1,18): + yield s_clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=1, + dest=1, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame) + yield s_clk.posedge + yield s_clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + assert sink.empty() + + yield delay(100) + + yield s_clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=2, + dest=1, + ) + test_frame2 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=2, + dest=2, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield s_clk.posedge + yield s_clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield s_clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=3, + dest=1, + last_cycle_user=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=3, + dest=2, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield s_clk.posedge + yield s_clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + assert rx_frame.last_cycle_user + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + raise StopSimulation + + return instances() + +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() + diff --git a/tb/test_axis_async_fifo_adapter_64_8.v b/tb/test_axis_async_fifo_adapter_64_8.v new file mode 100644 index 000000000..22e206694 --- /dev/null +++ b/tb/test_axis_async_fifo_adapter_64_8.v @@ -0,0 +1,165 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for axis_async_fifo_adapter + */ +module test_axis_async_fifo_adapter_64_8; + +// Parameters +parameter ADDR_WIDTH = 2; +parameter S_DATA_WIDTH = 64; +parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8); +parameter S_KEEP_WIDTH = (S_DATA_WIDTH/8); +parameter M_DATA_WIDTH = 8; +parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8); +parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 0; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 0; +parameter DROP_WHEN_FULL = 0; + +// Inputs +reg s_clk = 0; +reg s_rst = 0; +reg m_clk = 0; +reg m_rst = 0; +reg [7:0] current_test = 0; + +reg [S_DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; + +// Outputs +wire s_axis_tready; +wire [M_DATA_WIDTH-1:0] m_axis_tdata; +wire [M_KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl( + s_clk, + s_rst, + m_clk, + m_rst, + current_test, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready + ); + $to_myhdl( + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser + ); + + // dump file + $dumpfile("test_axis_async_fifo_adapter_64_8.lxt"); + $dumpvars(0, test_axis_async_fifo_adapter_64_8); +end + +axis_async_fifo_adapter #( + .ADDR_WIDTH(ADDR_WIDTH), + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL) +) +UUT ( + // AXI input + .s_clk(s_clk), + .s_rst(s_rst), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_clk(m_clk), + .m_rst(m_rst), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), + // Status + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() +); + +endmodule diff --git a/tb/test_axis_async_fifo_adapter_8_64.py b/tb/test_axis_async_fifo_adapter_8_64.py new file mode 100755 index 000000000..d04ab1312 --- /dev/null +++ b/tb/test_axis_async_fifo_adapter_8_64.py @@ -0,0 +1,324 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep + +module = 'axis_async_fifo_adapter' +testbench = 'test_%s_8_64' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_adapter.v") +srcs.append("../rtl/axis_async_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + ADDR_WIDTH = 2 + S_DATA_WIDTH = 8 + S_KEEP_ENABLE = (S_DATA_WIDTH>8) + S_KEEP_WIDTH = (S_DATA_WIDTH/8) + M_DATA_WIDTH = 64 + M_KEEP_ENABLE = (M_DATA_WIDTH>8) + M_KEEP_WIDTH = (M_DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + FRAME_FIFO = 0 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 0 + DROP_WHEN_FULL = 0 + + # Inputs + s_clk = Signal(bool(0)) + s_rst = Signal(bool(0)) + m_clk = Signal(bool(0)) + m_rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + s_axis_tdata = Signal(intbv(0)[S_DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[S_KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) + + # Outputs + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[M_DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[M_KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + + # sources and sinks + source_pause = Signal(bool(0)) + sink_pause = Signal(bool(0)) + + source = axis_ep.AXIStreamSource() + + source_logic = source.create_logic( + s_clk, + s_rst, + tdata=s_axis_tdata, + tkeep=s_axis_tkeep, + tvalid=s_axis_tvalid, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + m_clk, + m_rst, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, + pause=sink_pause, + name='sink' + ) + + # DUT + if os.system(build_cmd): + raise Exception("Error running build command") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + s_clk=s_clk, + s_rst=s_rst, + m_clk=m_clk, + m_rst=m_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_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, + + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser + ) + + @always(delay(4)) + def s_clkgen(): + s_clk.next = not s_clk + + @always(delay(5)) + def m_clkgen(): + m_clk.next = not m_clk + + def wait_normal(): + while s_axis_tvalid or m_axis_tvalid: + yield s_clk.posedge + + def wait_pause_source(): + while s_axis_tvalid or m_axis_tvalid: + yield s_clk.posedge + yield s_clk.posedge + source_pause.next = False + yield s_clk.posedge + source_pause.next = True + yield s_clk.posedge + + source_pause.next = False + + def wait_pause_sink(): + while s_axis_tvalid or m_axis_tvalid: + sink_pause.next = True + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + sink_pause.next = False + yield s_clk.posedge + + @instance + def check(): + yield delay(100) + yield s_clk.posedge + s_rst.next = 1 + m_rst.next = 1 + yield s_clk.posedge + yield s_clk.posedge + yield s_clk.posedge + s_rst.next = 0 + m_rst.next = 0 + yield s_clk.posedge + yield delay(100) + yield s_clk.posedge + + for payload_len in range(1,18): + yield s_clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=1, + dest=1, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame) + yield s_clk.posedge + yield s_clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + assert sink.empty() + + yield delay(100) + + yield s_clk.posedge + print("test 2: back-to-back packets, length %d" % payload_len) + current_test.next = 2 + + test_frame1 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=2, + dest=1, + ) + test_frame2 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=2, + dest=2, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield s_clk.posedge + yield s_clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield s_clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=3, + dest=1, + last_cycle_user=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=3, + dest=2, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield s_clk.posedge + yield s_clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + assert rx_frame.last_cycle_user + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + raise StopSimulation + + return instances() + +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() + diff --git a/tb/test_axis_async_fifo_adapter_8_64.v b/tb/test_axis_async_fifo_adapter_8_64.v new file mode 100644 index 000000000..ddb4a1f35 --- /dev/null +++ b/tb/test_axis_async_fifo_adapter_8_64.v @@ -0,0 +1,165 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for axis_async_fifo_adapter + */ +module test_axis_async_fifo_adapter_8_64; + +// Parameters +parameter ADDR_WIDTH = 2; +parameter S_DATA_WIDTH = 8; +parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8); +parameter S_KEEP_WIDTH = (S_DATA_WIDTH/8); +parameter M_DATA_WIDTH = 64; +parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8); +parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 0; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 0; +parameter DROP_WHEN_FULL = 0; + +// Inputs +reg s_clk = 0; +reg s_rst = 0; +reg m_clk = 0; +reg m_rst = 0; +reg [7:0] current_test = 0; + +reg [S_DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; + +// Outputs +wire s_axis_tready; +wire [M_DATA_WIDTH-1:0] m_axis_tdata; +wire [M_KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl( + s_clk, + s_rst, + m_clk, + m_rst, + current_test, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready + ); + $to_myhdl( + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser + ); + + // dump file + $dumpfile("test_axis_async_fifo_adapter_8_64.lxt"); + $dumpvars(0, test_axis_async_fifo_adapter_8_64); +end + +axis_async_fifo_adapter #( + .ADDR_WIDTH(ADDR_WIDTH), + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL) +) +UUT ( + // AXI input + .s_clk(s_clk), + .s_rst(s_rst), + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_clk(m_clk), + .m_rst(m_rst), + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), + // Status + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() +); + +endmodule diff --git a/tb/test_axis_fifo_adapter_64_8.py b/tb/test_axis_fifo_adapter_64_8.py new file mode 100755 index 000000000..2129221e1 --- /dev/null +++ b/tb/test_axis_fifo_adapter_64_8.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep + +module = 'axis_fifo_adapter' +testbench = 'test_%s_64_8' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_adapter.v") +srcs.append("../rtl/axis_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + ADDR_WIDTH = 2 + S_DATA_WIDTH = 64 + S_KEEP_ENABLE = (S_DATA_WIDTH>8) + S_KEEP_WIDTH = (S_DATA_WIDTH/8) + M_DATA_WIDTH = 8 + M_KEEP_ENABLE = (M_DATA_WIDTH>8) + M_KEEP_WIDTH = (M_DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + FRAME_FIFO = 0 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 0 + DROP_WHEN_FULL = 0 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + s_axis_tdata = Signal(intbv(0)[S_DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[S_KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) + + # Outputs + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[M_DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[M_KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + + # sources and sinks + source_pause = Signal(bool(0)) + sink_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, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, + pause=sink_pause, + 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_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, + + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while s_axis_tvalid or m_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while s_axis_tvalid or m_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 + + def wait_pause_sink(): + while s_axis_tvalid or m_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=1, + dest=1, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + 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 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=2, + dest=1, + ) + test_frame2 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=2, + dest=2, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=3, + dest=1, + last_cycle_user=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=3, + dest=2, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + assert rx_frame.last_cycle_user + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + raise StopSimulation + + return instances() + +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() + diff --git a/tb/test_axis_fifo_adapter_64_8.v b/tb/test_axis_fifo_adapter_64_8.v new file mode 100644 index 000000000..5afd8d8d2 --- /dev/null +++ b/tb/test_axis_fifo_adapter_64_8.v @@ -0,0 +1,156 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for axis_fifo_adapter + */ +module test_axis_fifo_adapter_64_8; + +// Parameters +parameter ADDR_WIDTH = 2; +parameter S_DATA_WIDTH = 64; +parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8); +parameter S_KEEP_WIDTH = (S_DATA_WIDTH/8); +parameter M_DATA_WIDTH = 8; +parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8); +parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 0; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 0; +parameter DROP_WHEN_FULL = 0; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [S_DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; + +// Outputs +wire s_axis_tready; +wire [M_DATA_WIDTH-1:0] m_axis_tdata; +wire [M_KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready + ); + $to_myhdl( + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser + ); + + // dump file + $dumpfile("test_axis_fifo_adapter_64_8.lxt"); + $dumpvars(0, test_axis_fifo_adapter_64_8); +end + +axis_fifo_adapter #( + .ADDR_WIDTH(ADDR_WIDTH), + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() +); + +endmodule diff --git a/tb/test_axis_fifo_adapter_8_64.py b/tb/test_axis_fifo_adapter_8_64.py new file mode 100755 index 000000000..f59dd451a --- /dev/null +++ b/tb/test_axis_fifo_adapter_8_64.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import axis_ep + +module = 'axis_fifo_adapter' +testbench = 'test_%s_8_64' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/axis_adapter.v") +srcs.append("../rtl/axis_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + ADDR_WIDTH = 2 + S_DATA_WIDTH = 8 + S_KEEP_ENABLE = (S_DATA_WIDTH>8) + S_KEEP_WIDTH = (S_DATA_WIDTH/8) + M_DATA_WIDTH = 64 + M_KEEP_ENABLE = (M_DATA_WIDTH>8) + M_KEEP_WIDTH = (M_DATA_WIDTH/8) + ID_ENABLE = 1 + ID_WIDTH = 8 + DEST_ENABLE = 1 + DEST_WIDTH = 8 + USER_ENABLE = 1 + USER_WIDTH = 1 + FRAME_FIFO = 0 + USER_BAD_FRAME_VALUE = 1 + USER_BAD_FRAME_MASK = 1 + DROP_BAD_FRAME = 0 + DROP_WHEN_FULL = 0 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + s_axis_tdata = Signal(intbv(0)[S_DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[S_KEEP_WIDTH:]) + s_axis_tvalid = Signal(bool(0)) + s_axis_tlast = Signal(bool(0)) + s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + m_axis_tready = Signal(bool(0)) + + # Outputs + s_axis_tready = Signal(bool(0)) + m_axis_tdata = Signal(intbv(0)[M_DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[M_KEEP_WIDTH:]) + m_axis_tvalid = Signal(bool(0)) + m_axis_tlast = Signal(bool(0)) + m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) + m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + + # sources and sinks + source_pause = Signal(bool(0)) + sink_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, + tready=s_axis_tready, + tlast=s_axis_tlast, + tid=s_axis_tid, + tdest=s_axis_tdest, + tuser=s_axis_tuser, + pause=source_pause, + name='source' + ) + + sink = axis_ep.AXIStreamSink() + + sink_logic = sink.create_logic( + clk, + rst, + tdata=m_axis_tdata, + tkeep=m_axis_tkeep, + tvalid=m_axis_tvalid, + tready=m_axis_tready, + tlast=m_axis_tlast, + tid=m_axis_tid, + tdest=m_axis_tdest, + tuser=m_axis_tuser, + pause=sink_pause, + 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_tready=s_axis_tready, + s_axis_tlast=s_axis_tlast, + s_axis_tid=s_axis_tid, + s_axis_tdest=s_axis_tdest, + s_axis_tuser=s_axis_tuser, + + m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, + m_axis_tvalid=m_axis_tvalid, + m_axis_tready=m_axis_tready, + m_axis_tlast=m_axis_tlast, + m_axis_tid=m_axis_tid, + m_axis_tdest=m_axis_tdest, + m_axis_tuser=m_axis_tuser + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + def wait_normal(): + while s_axis_tvalid or m_axis_tvalid: + yield clk.posedge + + def wait_pause_source(): + while s_axis_tvalid or m_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 + + def wait_pause_sink(): + while s_axis_tvalid or m_axis_tvalid: + sink_pause.next = True + yield clk.posedge + yield clk.posedge + yield clk.posedge + sink_pause.next = False + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + for payload_len in range(1,18): + yield clk.posedge + print("test 1: test packet, length %d" % payload_len) + current_test.next = 1 + + test_frame = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=1, + dest=1, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame + + 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 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=2, + dest=1, + ) + test_frame2 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=2, + dest=2, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: tuser assert, length %d" % payload_len) + current_test.next = 3 + + test_frame1 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=3, + dest=1, + last_cycle_user=1 + ) + test_frame2 = axis_ep.AXIStreamFrame( + bytearray(range(payload_len)), + id=3, + dest=2, + ) + + for wait in wait_normal, wait_pause_source, wait_pause_sink: + source.send(test_frame1) + source.send(test_frame2) + yield clk.posedge + yield clk.posedge + + yield wait() + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame1 + assert rx_frame.last_cycle_user + + yield sink.wait() + rx_frame = sink.recv() + + assert rx_frame == test_frame2 + + assert sink.empty() + + yield delay(100) + + raise StopSimulation + + return instances() + +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() + diff --git a/tb/test_axis_fifo_adapter_8_64.v b/tb/test_axis_fifo_adapter_8_64.v new file mode 100644 index 000000000..c97a3a422 --- /dev/null +++ b/tb/test_axis_fifo_adapter_8_64.v @@ -0,0 +1,156 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for axis_fifo_adapter + */ +module test_axis_fifo_adapter_8_64; + +// Parameters +parameter ADDR_WIDTH = 2; +parameter S_DATA_WIDTH = 8; +parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8); +parameter S_KEEP_WIDTH = (S_DATA_WIDTH/8); +parameter M_DATA_WIDTH = 64; +parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8); +parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8); +parameter ID_ENABLE = 1; +parameter ID_WIDTH = 8; +parameter DEST_ENABLE = 1; +parameter DEST_WIDTH = 8; +parameter USER_ENABLE = 1; +parameter USER_WIDTH = 1; +parameter FRAME_FIFO = 0; +parameter USER_BAD_FRAME_VALUE = 1'b1; +parameter USER_BAD_FRAME_MASK = 1'b1; +parameter DROP_BAD_FRAME = 0; +parameter DROP_WHEN_FULL = 0; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [S_DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [S_KEEP_WIDTH-1:0] s_axis_tkeep = 0; +reg s_axis_tvalid = 0; +reg s_axis_tlast = 0; +reg [ID_WIDTH-1:0] s_axis_tid = 0; +reg [DEST_WIDTH-1:0] s_axis_tdest = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg m_axis_tready = 0; + +// Outputs +wire s_axis_tready; +wire [M_DATA_WIDTH-1:0] m_axis_tdata; +wire [M_KEEP_WIDTH-1:0] m_axis_tkeep; +wire m_axis_tvalid; +wire m_axis_tlast; +wire [ID_WIDTH-1:0] m_axis_tid; +wire [DEST_WIDTH-1:0] m_axis_tdest; +wire [USER_WIDTH-1:0] m_axis_tuser; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + s_axis_tdata, + s_axis_tkeep, + s_axis_tvalid, + s_axis_tlast, + s_axis_tid, + s_axis_tdest, + s_axis_tuser, + m_axis_tready + ); + $to_myhdl( + s_axis_tready, + m_axis_tdata, + m_axis_tkeep, + m_axis_tvalid, + m_axis_tlast, + m_axis_tid, + m_axis_tdest, + m_axis_tuser + ); + + // dump file + $dumpfile("test_axis_fifo_adapter_8_64.lxt"); + $dumpvars(0, test_axis_fifo_adapter_8_64); +end + +axis_fifo_adapter #( + .ADDR_WIDTH(ADDR_WIDTH), + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL) +) +UUT ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser), + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() +); + +endmodule From 1d616267856f3dff1edc579a889cfe360160795e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 2 May 2019 19:29:47 -0700 Subject: [PATCH 559/617] Add KC705 GMII example design --- example/KC705/fpga_gmii/Makefile | 25 + example/KC705/fpga_gmii/README.md | 28 + example/KC705/fpga_gmii/clock.xdc | 4 + example/KC705/fpga_gmii/common/vivado.mk | 118 ++++ example/KC705/fpga_gmii/fpga.xdc | 78 +++ example/KC705/fpga_gmii/fpga/Makefile | 65 ++ example/KC705/fpga_gmii/lib/eth | 1 + example/KC705/fpga_gmii/rtl/debounce_switch.v | 89 +++ example/KC705/fpga_gmii/rtl/fpga.v | 254 ++++++++ example/KC705/fpga_gmii/rtl/fpga_core.v | 587 ++++++++++++++++++ example/KC705/fpga_gmii/rtl/sync_reset.v | 52 ++ example/KC705/fpga_gmii/rtl/sync_signal.v | 58 ++ example/KC705/fpga_gmii/tb/arp_ep.py | 1 + example/KC705/fpga_gmii/tb/axis_ep.py | 1 + example/KC705/fpga_gmii/tb/eth_ep.py | 1 + example/KC705/fpga_gmii/tb/gmii_ep.py | 1 + example/KC705/fpga_gmii/tb/ip_ep.py | 1 + example/KC705/fpga_gmii/tb/test_fpga_core.py | 315 ++++++++++ example/KC705/fpga_gmii/tb/test_fpga_core.v | 134 ++++ example/KC705/fpga_gmii/tb/udp_ep.py | 1 + 20 files changed, 1814 insertions(+) create mode 100644 example/KC705/fpga_gmii/Makefile create mode 100644 example/KC705/fpga_gmii/README.md create mode 100644 example/KC705/fpga_gmii/clock.xdc create mode 100644 example/KC705/fpga_gmii/common/vivado.mk create mode 100644 example/KC705/fpga_gmii/fpga.xdc create mode 100644 example/KC705/fpga_gmii/fpga/Makefile create mode 120000 example/KC705/fpga_gmii/lib/eth create mode 100644 example/KC705/fpga_gmii/rtl/debounce_switch.v create mode 100644 example/KC705/fpga_gmii/rtl/fpga.v create mode 100644 example/KC705/fpga_gmii/rtl/fpga_core.v create mode 100644 example/KC705/fpga_gmii/rtl/sync_reset.v create mode 100644 example/KC705/fpga_gmii/rtl/sync_signal.v create mode 120000 example/KC705/fpga_gmii/tb/arp_ep.py create mode 120000 example/KC705/fpga_gmii/tb/axis_ep.py create mode 120000 example/KC705/fpga_gmii/tb/eth_ep.py create mode 120000 example/KC705/fpga_gmii/tb/gmii_ep.py create mode 120000 example/KC705/fpga_gmii/tb/ip_ep.py create mode 100755 example/KC705/fpga_gmii/tb/test_fpga_core.py create mode 100644 example/KC705/fpga_gmii/tb/test_fpga_core.v create mode 120000 example/KC705/fpga_gmii/tb/udp_ep.py diff --git a/example/KC705/fpga_gmii/Makefile b/example/KC705/fpga_gmii/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/KC705/fpga_gmii/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/KC705/fpga_gmii/README.md b/example/KC705/fpga_gmii/README.md new file mode 100644 index 000000000..e524f6276 --- /dev/null +++ b/example/KC705/fpga_gmii/README.md @@ -0,0 +1,28 @@ +# Verilog Ethernet KC705 Example Design + +## Introduction + +This example design targets the Xilinx KC705 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +Configure the PHY for GMII by placing J29 and J30 across pins 1 and 2 and +opening J64. + +FPGA: XC7K325T-2FFG900C +PHY: Marvell 88E1111 + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the KC705 board with Vivado. Then run netcat -u +192.168.1.128 1234 to open a UDP connection to port 1234. Any text entered +into netcat will be echoed back after pressing enter. + + diff --git a/example/KC705/fpga_gmii/clock.xdc b/example/KC705/fpga_gmii/clock.xdc new file mode 100644 index 000000000..93d13048b --- /dev/null +++ b/example/KC705/fpga_gmii/clock.xdc @@ -0,0 +1,4 @@ +# Clock constraints + +# BUFGMUX outputs +set_clock_groups -physically_exclusive -group clk_mmcm_out -group phy_tx_clk diff --git a/example/KC705/fpga_gmii/common/vivado.mk b/example/KC705/fpga_gmii/common/vivado.mk new file mode 100644 index 000000000..a54b530f6 --- /dev/null +++ b/example/KC705/fpga_gmii/common/vivado.mk @@ -0,0 +1,118 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile $(XCI_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/KC705/fpga_gmii/fpga.xdc b/example/KC705/fpga_gmii/fpga.xdc new file mode 100644 index 000000000..e52f2e3b7 --- /dev/null +++ b/example/KC705/fpga_gmii/fpga.xdc @@ -0,0 +1,78 @@ +# XDC constraints for the Xilinx KC705 board +# part: xc7k325tffg900-2 + +# General configuration +set_property CFGBVS VCCO [current_design] +set_property CONFIG_VOLTAGE 2.5 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] + +# System clocks +# 200 MHz +set_property -dict {LOC AD12 IOSTANDARD LVDS} [get_ports clk_200mhz_p] +set_property -dict {LOC AD11 IOSTANDARD LVDS} [get_ports clk_200mhz_n] +create_clock -period 5.000 -name clk_200mhz [get_ports clk_200mhz_p] + +# LEDs +set_property -dict {LOC AB8 IOSTANDARD LVCMOS15 SLEW SLOW DRIVE 12} [get_ports {led[0]}] +set_property -dict {LOC AA8 IOSTANDARD LVCMOS15 SLEW SLOW DRIVE 12} [get_ports {led[1]}] +set_property -dict {LOC AC9 IOSTANDARD LVCMOS15 SLEW SLOW DRIVE 12} [get_ports {led[2]}] +set_property -dict {LOC AB9 IOSTANDARD LVCMOS15 SLEW SLOW DRIVE 12} [get_ports {led[3]}] +set_property -dict {LOC AE26 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[4]}] +set_property -dict {LOC G19 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[5]}] +set_property -dict {LOC E18 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[6]}] +set_property -dict {LOC F16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports {led[7]}] + +# Reset button +set_property -dict {LOC AB7 IOSTANDARD LVCMOS15} [get_ports reset] + +# Push buttons +set_property -dict {LOC AA12 IOSTANDARD LVCMOS15} [get_ports btnu] +set_property -dict {LOC AC6 IOSTANDARD LVCMOS15} [get_ports btnl] +set_property -dict {LOC AB12 IOSTANDARD LVCMOS15} [get_ports btnd] +set_property -dict {LOC AG5 IOSTANDARD LVCMOS15} [get_ports btnr] +set_property -dict {LOC G12 IOSTANDARD LVCMOS25} [get_ports btnc] + +# Toggle switches +set_property -dict {LOC Y29 IOSTANDARD LVCMOS25} [get_ports {sw[0]}] +set_property -dict {LOC W29 IOSTANDARD LVCMOS25} [get_ports {sw[1]}] +set_property -dict {LOC AA28 IOSTANDARD LVCMOS25} [get_ports {sw[2]}] +set_property -dict {LOC Y28 IOSTANDARD LVCMOS25} [get_ports {sw[3]}] + +# UART +set_property -dict {LOC K24 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports uart_txd] +set_property -dict {LOC M19 IOSTANDARD LVCMOS25} [get_ports uart_rxd] +set_property -dict {LOC L27 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports uart_rts] +set_property -dict {LOC K23 IOSTANDARD LVCMOS25} [get_ports uart_cts] + +# Gigabit Ethernet GMII PHY +set_property -dict {LOC U27 IOSTANDARD LVCMOS25} [get_ports phy_rx_clk] +set_property -dict {LOC U30 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[0]}] +set_property -dict {LOC U25 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[1]}] +set_property -dict {LOC T25 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[2]}] +set_property -dict {LOC U28 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[3]}] +set_property -dict {LOC R19 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[4]}] +set_property -dict {LOC T27 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[5]}] +set_property -dict {LOC T26 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[6]}] +set_property -dict {LOC T28 IOSTANDARD LVCMOS25} [get_ports {phy_rxd[7]}] +set_property -dict {LOC R28 IOSTANDARD LVCMOS25} [get_ports phy_rx_dv] +set_property -dict {LOC V26 IOSTANDARD LVCMOS25} [get_ports phy_rx_er] +set_property -dict {LOC K30 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports phy_gtx_clk] +set_property -dict {LOC M28 IOSTANDARD LVCMOS25} [get_ports phy_tx_clk] +set_property -dict {LOC N27 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[0]}] +set_property -dict {LOC N25 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[1]}] +set_property -dict {LOC M29 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[2]}] +set_property -dict {LOC L28 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[3]}] +set_property -dict {LOC J26 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[4]}] +set_property -dict {LOC K26 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[5]}] +set_property -dict {LOC L30 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[6]}] +set_property -dict {LOC J28 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports {phy_txd[7]}] +set_property -dict {LOC M27 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports phy_tx_en] +set_property -dict {LOC N29 IOSTANDARD LVCMOS25 SLEW FAST DRIVE 16} [get_ports phy_tx_er] +set_property -dict {LOC L20 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports phy_reset_n] +set_property -dict {LOC N30 IOSTANDARD LVCMOS25} [get_ports phy_int_n] +#set_property -dict {LOC J21 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports phy_mdio] +#set_property -dict {LOC R23 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports phy_mdc] + +create_clock -period 40.000 -name phy_tx_clk [get_ports phy_tx_clk] +create_clock -period 8.000 -name phy_rx_clk [get_ports phy_rx_clk] + diff --git a/example/KC705/fpga_gmii/fpga/Makefile b/example/KC705/fpga_gmii/fpga/Makefile new file mode 100644 index 000000000..53353ae47 --- /dev/null +++ b/example/KC705/fpga_gmii/fpga/Makefile @@ -0,0 +1,65 @@ + +# FPGA settings +FPGA_PART = xc7k325tffg900-2 +FPGA_TOP = fpga +FPGA_ARCH = kintex7 + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/oddr.v +SYN_FILES += lib/eth/rtl/ssio_sdr_in.v +SYN_FILES += lib/eth/rtl/ssio_sdr_out.v +SYN_FILES += lib/eth/rtl/gmii_phy_if.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_gmii_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_gmii.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += clock.xdc +XDC_FILES += lib/eth/syn/gmii_phy_if.tcl +XDC_FILES += lib/eth/syn/eth_mac_1g_gmii.tcl +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl + echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "exit" >> program.tcl + vivado -mode batch -source program.tcl + diff --git a/example/KC705/fpga_gmii/lib/eth b/example/KC705/fpga_gmii/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/KC705/fpga_gmii/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/KC705/fpga_gmii/rtl/debounce_switch.v b/example/KC705/fpga_gmii/rtl/debounce_switch.v new file mode 100644 index 000000000..bb631cc35 --- /dev/null +++ b/example/KC705/fpga_gmii/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/KC705/fpga_gmii/rtl/fpga.v b/example/KC705/fpga_gmii/rtl/fpga.v new file mode 100644 index 000000000..bf0dc4a0e --- /dev/null +++ b/example/KC705/fpga_gmii/rtl/fpga.v @@ -0,0 +1,254 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 200MHz + * Reset: Push button, active high + */ + input wire clk_200mhz_p, + input wire clk_200mhz_n, + input wire reset, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T GMII + */ + input wire phy_rx_clk, + input wire [7:0] phy_rxd, + input wire phy_rx_dv, + input wire phy_rx_er, + output wire phy_gtx_clk, + input wire phy_tx_clk, + output wire [7:0] phy_txd, + output wire phy_tx_en, + output wire phy_tx_er, + output wire phy_reset_n, + input wire phy_int_n, + + /* + * UART: 500000 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// Clock and reset + +wire clk_200mhz_ibufg; +wire clk_200mhz_bufg; +wire clk_200mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_200mhz_int; +wire rst_int; + +wire mmcm_rst = reset; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS +clk_200mhz_ibufgds_inst( + .I(clk_200mhz_p), + .IB(clk_200mhz_n), + .O(clk_200mhz_ibufg) +); + +// MMCM instance +// 200 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 600 MHz to 1440 MHz +// M = 5, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCME2_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(8), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(5), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(5.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_200mhz_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_bufg_inst ( + .I(clk_mmcm_out), + .O(clk_int) +); + +sync_reset #( + .N(4) +) +sync_reset_inst ( + .clk(clk_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_int) +); + +// GPIO +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [3:0] sw_int; + +debounce_switch #( + .WIDTH(9), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_int), + .rst(rst_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +wire uart_rxd_int; +wire uart_cts_int; + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(clk_int), + .in({uart_rxd, uart_cts}), + .out({uart_rxd_int, uart_cts_int}) +); + +fpga_core +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk(clk_int), + .rst(rst_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .led(led), + /* + * Ethernet: 1000BASE-T GMII + */ + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_dv(phy_rx_dv), + .phy_rx_er(phy_rx_er), + .phy_gtx_clk(phy_gtx_clk), + .phy_tx_clk(phy_tx_clk), + .phy_txd(phy_txd), + .phy_tx_en(phy_tx_en), + .phy_tx_er(phy_tx_er), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts_int) +); + +endmodule diff --git a/example/KC705/fpga_gmii/rtl/fpga_core.v b/example/KC705/fpga_gmii/rtl/fpga_core.v new file mode 100644 index 000000000..cd2002c81 --- /dev/null +++ b/example/KC705/fpga_gmii/rtl/fpga_core.v @@ -0,0 +1,587 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 125MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire [7:0] led, + + /* + * Ethernet: 1000BASE-T GMII + */ + input wire phy_rx_clk, + input wire [7:0] phy_rxd, + input wire phy_rx_dv, + input wire phy_rx_er, + output wire phy_gtx_clk, + input wire phy_tx_clk, + output wire [7:0] phy_txd, + output wire phy_tx_en, + output wire phy_tx_er, + output wire phy_reset_n, + input wire phy_int_n, + + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// AXI between MAC and Ethernet modules +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [7:0] tx_axis_tdata; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [7:0] rx_eth_payload_axis_tdata; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [7:0] tx_eth_payload_axis_tdata; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [7:0] rx_ip_payload_axis_tdata; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [7:0] tx_ip_payload_axis_tdata; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [7:0] rx_udp_payload_axis_tdata; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; + +wire [7:0] rx_fifo_udp_payload_axis_tdata; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; + +wire [7:0] tx_fifo_udp_payload_axis_tdata; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_axis_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = !match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; + +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; + +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_axis_tlast) begin + valid_last <= 1'b0; + end + end + end +end + +//assign led = sw; +assign led = led_reg; +assign phy_reset_n = !rst; + +assign uart_txd = 0; +assign uart_rts = 0; + +eth_mac_1g_gmii_fifo #( + .TARGET(TARGET), + .IODDR_STYLE("IODDR"), + .CLOCK_INPUT_STYLE("BUFR"), + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) +) +eth_mac_inst ( + .gtx_clk(clk), + .gtx_rst(rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .gmii_rx_clk(phy_rx_clk), + .gmii_rxd(phy_rxd), + .gmii_rx_dv(phy_rx_dv), + .gmii_rx_er(phy_rx_er), + .gmii_tx_clk(phy_gtx_clk), + .mii_tx_clk(phy_tx_clk), + .gmii_txd(phy_txd), + .gmii_tx_en(phy_tx_en), + .gmii_tx_er(phy_tx_er), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + .speed(), + + .ifg_delay(12) +); + +eth_axis_rx +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(rx_axis_tdata), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // AXI output + .m_axis_tdata(tx_axis_tdata), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // IP frame input + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), + // IP frame output + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), + // UDP frame input + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), + // UDP frame output + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(0) +); + +axis_fifo #( + .ADDR_WIDTH(12), + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(0) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), + + // AXI output + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() +); + +endmodule diff --git a/example/KC705/fpga_gmii/rtl/sync_reset.v b/example/KC705/fpga_gmii/rtl/sync_reset.v new file mode 100644 index 000000000..acbcf1c6e --- /dev/null +++ b/example/KC705/fpga_gmii/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/KC705/fpga_gmii/rtl/sync_signal.v b/example/KC705/fpga_gmii/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/example/KC705/fpga_gmii/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/KC705/fpga_gmii/tb/arp_ep.py b/example/KC705/fpga_gmii/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/KC705/fpga_gmii/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/KC705/fpga_gmii/tb/axis_ep.py b/example/KC705/fpga_gmii/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/KC705/fpga_gmii/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/KC705/fpga_gmii/tb/eth_ep.py b/example/KC705/fpga_gmii/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/KC705/fpga_gmii/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/KC705/fpga_gmii/tb/gmii_ep.py b/example/KC705/fpga_gmii/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/KC705/fpga_gmii/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/KC705/fpga_gmii/tb/ip_ep.py b/example/KC705/fpga_gmii/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/KC705/fpga_gmii/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/KC705/fpga_gmii/tb/test_fpga_core.py b/example/KC705/fpga_gmii/tb/test_fpga_core.py new file mode 100755 index 000000000..18864b43c --- /dev/null +++ b/example/KC705/fpga_gmii/tb/test_fpga_core.py @@ -0,0 +1,315 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2018 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 + +import eth_ep +import arp_ep +import udp_ep +import gmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/oddr.v") +srcs.append("../lib/eth/rtl/ssio_sdr_in.v") +srcs.append("../lib/eth/rtl/ssio_sdr_out.v") +srcs.append("../lib/eth/rtl/gmii_phy_if.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_gmii_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g_gmii.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen.v") +srcs.append("../lib/eth/rtl/udp.v") +srcs.append("../lib/eth/rtl/udp_ip_rx.v") +srcs.append("../lib/eth/rtl/udp_ip_tx.v") +srcs.append("../lib/eth/rtl/ip_complete.v") +srcs.append("../lib/eth/rtl/ip.v") +srcs.append("../lib/eth/rtl/ip_eth_rx.v") +srcs.append("../lib/eth/rtl/ip_eth_tx.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + TARGET = "SIM" + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[4:]) + phy_rx_clk = Signal(bool(0)) + phy_rxd = Signal(intbv(0)[8:]) + phy_rx_dv = Signal(bool(0)) + phy_rx_er = Signal(bool(0)) + phy_tx_clk = Signal(bool(0)) + phy_int_n = Signal(bool(1)) + uart_rxd = Signal(bool(0)) + uart_cts = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[8:]) + phy_gtx_clk = Signal(bool(0)) + phy_txd = Signal(intbv(0)[8:]) + phy_tx_en = Signal(bool(0)) + phy_tx_er = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + + # sources and sinks + mii_select = Signal(bool(0)) + + gmii_source = gmii_ep.GMIISource() + + gmii_source_logic = gmii_source.create_logic( + phy_rx_clk, + rst, + txd=phy_rxd, + tx_en=phy_rx_dv, + tx_er=phy_rx_er, + mii_select=mii_select, + name='gmii_source' + ) + + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + phy_tx_clk, + rst, + rxd=phy_txd, + rx_dv=phy_tx_en, + rx_er=phy_tx_er, + mii_select=mii_select, + name='gmii_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, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, + + phy_rx_clk=phy_rx_clk, + phy_rxd=phy_rxd, + phy_rx_dv=phy_rx_dv, + phy_rx_er=phy_rx_er, + phy_gtx_clk=phy_gtx_clk, + phy_tx_clk=phy_tx_clk, + phy_txd=phy_txd, + phy_tx_en=phy_tx_en, + phy_tx_er=phy_tx_er, + phy_reset_n=phy_reset_n, + phy_int_n=phy_int_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + rx_clk_hp = Signal(int(4)) + + @instance + def rx_clk_gen(): + while True: + yield delay(int(rx_clk_hp)) + phy_rx_clk.next = not phy_rx_clk + phy_tx_clk.next = not phy_tx_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 + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source.empty() + assert gmii_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() diff --git a/example/KC705/fpga_gmii/tb/test_fpga_core.v b/example/KC705/fpga_gmii/tb/test_fpga_core.v new file mode 100644 index 000000000..bbe377cba --- /dev/null +++ b/example/KC705/fpga_gmii/tb/test_fpga_core.v @@ -0,0 +1,134 @@ +/* + +Copyright (c) 2015-2018 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters +parameter TARGET = "SIM"; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [3:0] sw = 0; +reg phy_rx_clk = 0; +reg [7:0] phy_rxd = 0; +reg phy_rx_dv = 0; +reg phy_rx_er = 0; +reg phy_tx_clk = 0; +reg phy_int_n = 1; +reg uart_rxd = 0; +reg uart_cts = 0; + +// Outputs +wire [7:0] led; +wire phy_gtx_clk; +wire [7:0] phy_txd; +wire phy_tx_en; +wire phy_tx_er; +wire phy_reset_n; +wire uart_txd; +wire uart_rts; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + phy_rx_clk, + phy_rxd, + phy_rx_dv, + phy_rx_er, + phy_tx_clk, + phy_int_n, + uart_rxd, + uart_cts + ); + $to_myhdl( + led, + phy_gtx_clk, + phy_txd, + phy_tx_en, + phy_tx_er, + phy_reset_n, + uart_txd, + uart_rts + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core #( + .TARGET(TARGET) +) +UUT ( + .clk(clk), + .rst(rst), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .phy_rx_clk(phy_rx_clk), + .phy_rxd(phy_rxd), + .phy_rx_dv(phy_rx_dv), + .phy_rx_er(phy_rx_er), + .phy_gtx_clk(phy_gtx_clk), + .phy_tx_clk(phy_tx_clk), + .phy_txd(phy_txd), + .phy_tx_en(phy_tx_en), + .phy_tx_er(phy_tx_er), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts) +); + +endmodule diff --git a/example/KC705/fpga_gmii/tb/udp_ep.py b/example/KC705/fpga_gmii/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/KC705/fpga_gmii/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file From 2abb41385468e91f52f5ea5916390660ce03c009 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 2 May 2019 20:30:37 -0700 Subject: [PATCH 560/617] Fix signal name --- example/KC705/fpga_gmii/rtl/fpga.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/KC705/fpga_gmii/rtl/fpga.v b/example/KC705/fpga_gmii/rtl/fpga.v index bf0dc4a0e..8db1ad5c5 100644 --- a/example/KC705/fpga_gmii/rtl/fpga.v +++ b/example/KC705/fpga_gmii/rtl/fpga.v @@ -80,7 +80,7 @@ wire clk_200mhz_bufg; wire clk_200mhz_mmcm_out; // Internal 125 MHz clock -wire clk_200mhz_int; +wire clk_int; wire rst_int; wire mmcm_rst = reset; From b7d297850c9bace1adf29a89f14c57edb33db004 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 10 May 2019 14:56:18 -0700 Subject: [PATCH 561/617] Move 10G PHY interface logic into separate modules --- rtl/eth_mac_phy_10g_rx.v | 92 +++++-------------- rtl/eth_mac_phy_10g_tx.v | 54 +++-------- rtl/eth_phy_10g_rx.v | 94 +++++-------------- rtl/eth_phy_10g_rx_if.v | 156 ++++++++++++++++++++++++++++++++ rtl/eth_phy_10g_tx.v | 56 +++--------- rtl/eth_phy_10g_tx_if.v | 116 ++++++++++++++++++++++++ tb/test_eth_mac_phy_10g.py | 2 + tb/test_eth_mac_phy_10g_fifo.py | 2 + tb/test_eth_phy_10g_64.py | 2 + tb/test_eth_phy_10g_rx_64.py | 1 + tb/test_eth_phy_10g_tx_64.py | 1 + 11 files changed, 346 insertions(+), 230 deletions(-) create mode 100644 rtl/eth_phy_10g_rx_if.v create mode 100644 rtl/eth_phy_10g_tx_if.v diff --git a/rtl/eth_mac_phy_10g_rx.v b/rtl/eth_mac_phy_10g_rx.v index 52d7c1c64..8773bc21a 100644 --- a/rtl/eth_mac_phy_10g_rx.v +++ b/rtl/eth_mac_phy_10g_rx.v @@ -90,57 +90,30 @@ initial begin end end -wire [DATA_WIDTH-1:0] serdes_rx_data_int; -wire [HDR_WIDTH-1:0] serdes_rx_hdr_int; +wire [DATA_WIDTH-1:0] encoded_rx_data; +wire [HDR_WIDTH-1:0] encoded_rx_hdr; -generate - genvar n; - - if (BIT_REVERSE) begin - for (n = 0; n < DATA_WIDTH; n = n + 1) begin - assign serdes_rx_data_int[n] = serdes_rx_data[DATA_WIDTH-n-1]; - end - - for (n = 0; n < HDR_WIDTH; n = n + 1) begin - assign serdes_rx_hdr_int[n] = serdes_rx_hdr[HDR_WIDTH-n-1]; - end - end else begin - assign serdes_rx_data_int = serdes_rx_data; - assign serdes_rx_hdr_int = serdes_rx_hdr; - end -endgenerate - -wire [DATA_WIDTH-1:0] descrambled_rx_data; - -reg [DATA_WIDTH-1:0] encoded_rx_data_reg = {DATA_WIDTH{1'b0}}; -reg [HDR_WIDTH-1:0] encoded_rx_hdr_reg = {HDR_WIDTH{1'b0}}; - -reg [57:0] scrambler_state_reg = {58{1'b1}}; -wire [57:0] scrambler_state; - -lfsr #( - .LFSR_WIDTH(58), - .LFSR_POLY(58'h8000000001), - .LFSR_CONFIG("FIBONACCI"), - .LFSR_FEED_FORWARD(1), - .REVERSE(1), +eth_phy_10g_rx_if #( .DATA_WIDTH(DATA_WIDTH), - .STYLE("AUTO") + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), + .COUNT_125US(COUNT_125US) ) -descrambler_inst ( - .data_in(serdes_rx_data_int), - .state_in(scrambler_state_reg), - .data_out(descrambled_rx_data), - .state_out(scrambler_state) +eth_phy_10g_rx_if_inst ( + .clk(clk), + .rst(rst), + .encoded_rx_data(encoded_rx_data), + .encoded_rx_hdr(encoded_rx_hdr), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_bad_block(rx_bad_block), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber) ); -always @(posedge clk) begin - scrambler_state_reg <= scrambler_state; - - encoded_rx_data_reg <= SCRAMBLER_DISABLE ? serdes_rx_data_int : descrambled_rx_data; - encoded_rx_hdr_reg <= serdes_rx_hdr_int; -end - axis_baser_rx_64 #( .DATA_WIDTH(DATA_WIDTH), .KEEP_WIDTH(KEEP_WIDTH), @@ -149,8 +122,8 @@ axis_baser_rx_64 #( axis_baser_rx_inst ( .clk(clk), .rst(rst), - .encoded_rx_data(encoded_rx_data_reg), - .encoded_rx_hdr(encoded_rx_hdr_reg), + .encoded_rx_data(encoded_rx_data), + .encoded_rx_hdr(encoded_rx_hdr), .m_axis_tdata(m_axis_tdata), .m_axis_tkeep(m_axis_tkeep), .m_axis_tvalid(m_axis_tvalid), @@ -163,27 +136,4 @@ axis_baser_rx_inst ( .rx_bad_block(rx_bad_block) ); -eth_phy_10g_rx_frame_sync #( - .HDR_WIDTH(HDR_WIDTH), - .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH) -) -eth_phy_10g_rx_frame_sync_inst ( - .clk(clk), - .rst(rst), - .serdes_rx_hdr(serdes_rx_hdr_int), - .serdes_rx_bitslip(serdes_rx_bitslip), - .rx_block_lock(rx_block_lock) -); - -eth_phy_10g_rx_ber_mon #( - .HDR_WIDTH(HDR_WIDTH), - .COUNT_125US(COUNT_125US) -) -eth_phy_10g_rx_ber_mon_inst ( - .clk(clk), - .rst(rst), - .serdes_rx_hdr(serdes_rx_hdr_int), - .rx_high_ber(rx_high_ber) -); - endmodule diff --git a/rtl/eth_mac_phy_10g_tx.v b/rtl/eth_mac_phy_10g_tx.v index cc5b119dc..cdf1ef601 100644 --- a/rtl/eth_mac_phy_10g_tx.v +++ b/rtl/eth_mac_phy_10g_tx.v @@ -120,51 +120,19 @@ axis_baser_tx_inst ( .error_underflow(tx_error_underflow) ); -reg [57:0] tx_scrambler_state_reg = {58{1'b1}}; -wire [57:0] tx_scrambler_state; -wire [DATA_WIDTH-1:0] scrambled_data; - -reg [DATA_WIDTH-1:0] serdes_tx_data_reg = {DATA_WIDTH{1'b0}}; -reg [HDR_WIDTH-1:0] serdes_tx_hdr_reg = {HDR_WIDTH{1'b0}}; - -generate - genvar n; - - if (BIT_REVERSE) begin - for (n = 0; n < DATA_WIDTH; n = n + 1) begin - assign serdes_tx_data[n] = serdes_tx_data_reg[DATA_WIDTH-n-1]; - end - - for (n = 0; n < HDR_WIDTH; n = n + 1) begin - assign serdes_tx_hdr[n] = serdes_tx_hdr_reg[HDR_WIDTH-n-1]; - end - end else begin - assign serdes_tx_data = serdes_tx_data_reg; - assign serdes_tx_hdr = serdes_tx_hdr_reg; - end -endgenerate - -lfsr #( - .LFSR_WIDTH(58), - .LFSR_POLY(58'h8000000001), - .LFSR_CONFIG("FIBONACCI"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), +eth_phy_10g_tx_if #( .DATA_WIDTH(DATA_WIDTH), - .STYLE("AUTO") + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE) ) -scrambler_inst ( - .data_in(encoded_tx_data), - .state_in(tx_scrambler_state_reg), - .data_out(scrambled_data), - .state_out(tx_scrambler_state) +eth_phy_10g_tx_if_inst ( + .clk(clk), + .rst(rst), + .encoded_tx_data(encoded_tx_data), + .encoded_tx_hdr(encoded_tx_hdr), + .serdes_tx_data(serdes_tx_data), + .serdes_tx_hdr(serdes_tx_hdr) ); -always @(posedge clk) begin - tx_scrambler_state_reg <= tx_scrambler_state; - - serdes_tx_data_reg <= SCRAMBLER_DISABLE ? encoded_tx_data : scrambled_data; - serdes_tx_hdr_reg <= encoded_tx_hdr; -end - endmodule diff --git a/rtl/eth_phy_10g_rx.v b/rtl/eth_phy_10g_rx.v index 911919b43..f8d945ab1 100644 --- a/rtl/eth_phy_10g_rx.v +++ b/rtl/eth_phy_10g_rx.v @@ -27,7 +27,7 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * 10G Ethernet PHY + * 10G Ethernet PHY RX */ module eth_phy_10g_rx # ( @@ -82,57 +82,30 @@ initial begin end end -wire [DATA_WIDTH-1:0] serdes_rx_data_int; -wire [HDR_WIDTH-1:0] serdes_rx_hdr_int; +wire [DATA_WIDTH-1:0] encoded_rx_data; +wire [HDR_WIDTH-1:0] encoded_rx_hdr; -generate - genvar n; - - if (BIT_REVERSE) begin - for (n = 0; n < DATA_WIDTH; n = n + 1) begin - assign serdes_rx_data_int[n] = serdes_rx_data[DATA_WIDTH-n-1]; - end - - for (n = 0; n < HDR_WIDTH; n = n + 1) begin - assign serdes_rx_hdr_int[n] = serdes_rx_hdr[HDR_WIDTH-n-1]; - end - end else begin - assign serdes_rx_data_int = serdes_rx_data; - assign serdes_rx_hdr_int = serdes_rx_hdr; - end -endgenerate - -wire [DATA_WIDTH-1:0] descrambled_rx_data; - -reg [DATA_WIDTH-1:0] encoded_rx_data_reg = {DATA_WIDTH{1'b0}}; -reg [HDR_WIDTH-1:0] encoded_rx_hdr_reg = {HDR_WIDTH{1'b0}}; - -reg [57:0] scrambler_state_reg = {58{1'b1}}; -wire [57:0] scrambler_state; - -lfsr #( - .LFSR_WIDTH(58), - .LFSR_POLY(58'h8000000001), - .LFSR_CONFIG("FIBONACCI"), - .LFSR_FEED_FORWARD(1), - .REVERSE(1), +eth_phy_10g_rx_if #( .DATA_WIDTH(DATA_WIDTH), - .STYLE("AUTO") + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), + .COUNT_125US(COUNT_125US) ) -descrambler_inst ( - .data_in(serdes_rx_data_int), - .state_in(scrambler_state_reg), - .data_out(descrambled_rx_data), - .state_out(scrambler_state) +eth_phy_10g_rx_if_inst ( + .clk(clk), + .rst(rst), + .encoded_rx_data(encoded_rx_data), + .encoded_rx_hdr(encoded_rx_hdr), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_bad_block(rx_bad_block), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber) ); -always @(posedge clk) begin - scrambler_state_reg <= scrambler_state; - - encoded_rx_data_reg <= SCRAMBLER_DISABLE ? serdes_rx_data_int : descrambled_rx_data; - encoded_rx_hdr_reg <= serdes_rx_hdr_int; -end - xgmii_baser_dec_64 #( .DATA_WIDTH(DATA_WIDTH), .CTRL_WIDTH(CTRL_WIDTH), @@ -141,34 +114,11 @@ xgmii_baser_dec_64 #( xgmii_baser_dec_inst ( .clk(clk), .rst(rst), - .encoded_rx_data(encoded_rx_data_reg), - .encoded_rx_hdr(encoded_rx_hdr_reg), + .encoded_rx_data(encoded_rx_data), + .encoded_rx_hdr(encoded_rx_hdr), .xgmii_rxd(xgmii_rxd), .xgmii_rxc(xgmii_rxc), .rx_bad_block(rx_bad_block) ); -eth_phy_10g_rx_frame_sync #( - .HDR_WIDTH(HDR_WIDTH), - .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH) -) -eth_phy_10g_rx_frame_sync_inst ( - .clk(clk), - .rst(rst), - .serdes_rx_hdr(serdes_rx_hdr_int), - .serdes_rx_bitslip(serdes_rx_bitslip), - .rx_block_lock(rx_block_lock) -); - -eth_phy_10g_rx_ber_mon #( - .HDR_WIDTH(HDR_WIDTH), - .COUNT_125US(COUNT_125US) -) -eth_phy_10g_rx_ber_mon_inst ( - .clk(clk), - .rst(rst), - .serdes_rx_hdr(serdes_rx_hdr_int), - .rx_high_ber(rx_high_ber) -); - endmodule diff --git a/rtl/eth_phy_10g_rx_if.v b/rtl/eth_phy_10g_rx_if.v new file mode 100644 index 000000000..59db115f0 --- /dev/null +++ b/rtl/eth_phy_10g_rx_if.v @@ -0,0 +1,156 @@ +/* + +Copyright (c) 2018 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 + +/* + * 10G Ethernet PHY RX IF + */ +module eth_phy_10g_rx_if # +( + parameter DATA_WIDTH = 64, + parameter HDR_WIDTH = 2, + parameter BIT_REVERSE = 0, + parameter SCRAMBLER_DISABLE = 0, + parameter SLIP_COUNT_WIDTH = 3, + parameter COUNT_125US = 125000/6.4 +) +( + input wire clk, + input wire rst, + + /* + * 10GBASE-R encoded interface + */ + output wire [DATA_WIDTH-1:0] encoded_rx_data, + output wire [HDR_WIDTH-1:0] encoded_rx_hdr, + + /* + * SERDES interface + */ + input wire [DATA_WIDTH-1:0] serdes_rx_data, + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * Status + */ + output wire rx_bad_block, + output wire rx_block_lock, + output wire rx_high_ber +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (HDR_WIDTH != 2) begin + $error("Error: HDR_WIDTH must be 2"); + $finish; + end +end + +wire [DATA_WIDTH-1:0] serdes_rx_data_int; +wire [HDR_WIDTH-1:0] serdes_rx_hdr_int; + +generate + genvar n; + + if (BIT_REVERSE) begin + for (n = 0; n < DATA_WIDTH; n = n + 1) begin + assign serdes_rx_data_int[n] = serdes_rx_data[DATA_WIDTH-n-1]; + end + + for (n = 0; n < HDR_WIDTH; n = n + 1) begin + assign serdes_rx_hdr_int[n] = serdes_rx_hdr[HDR_WIDTH-n-1]; + end + end else begin + assign serdes_rx_data_int = serdes_rx_data; + assign serdes_rx_hdr_int = serdes_rx_hdr; + end +endgenerate + +wire [DATA_WIDTH-1:0] descrambled_rx_data; + +reg [DATA_WIDTH-1:0] encoded_rx_data_reg = {DATA_WIDTH{1'b0}}; +reg [HDR_WIDTH-1:0] encoded_rx_hdr_reg = {HDR_WIDTH{1'b0}}; + +reg [57:0] scrambler_state_reg = {58{1'b1}}; +wire [57:0] scrambler_state; + +lfsr #( + .LFSR_WIDTH(58), + .LFSR_POLY(58'h8000000001), + .LFSR_CONFIG("FIBONACCI"), + .LFSR_FEED_FORWARD(1), + .REVERSE(1), + .DATA_WIDTH(DATA_WIDTH), + .STYLE("AUTO") +) +descrambler_inst ( + .data_in(serdes_rx_data_int), + .state_in(scrambler_state_reg), + .data_out(descrambled_rx_data), + .state_out(scrambler_state) +); + +always @(posedge clk) begin + scrambler_state_reg <= scrambler_state; + + encoded_rx_data_reg <= SCRAMBLER_DISABLE ? serdes_rx_data_int : descrambled_rx_data; + encoded_rx_hdr_reg <= serdes_rx_hdr_int; +end + +assign encoded_rx_data = encoded_rx_data_reg; +assign encoded_rx_hdr = encoded_rx_hdr_reg; + +eth_phy_10g_rx_frame_sync #( + .HDR_WIDTH(HDR_WIDTH), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH) +) +eth_phy_10g_rx_frame_sync_inst ( + .clk(clk), + .rst(rst), + .serdes_rx_hdr(serdes_rx_hdr_int), + .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_block_lock(rx_block_lock) +); + +eth_phy_10g_rx_ber_mon #( + .HDR_WIDTH(HDR_WIDTH), + .COUNT_125US(COUNT_125US) +) +eth_phy_10g_rx_ber_mon_inst ( + .clk(clk), + .rst(rst), + .serdes_rx_hdr(serdes_rx_hdr_int), + .rx_high_ber(rx_high_ber) +); + +endmodule diff --git a/rtl/eth_phy_10g_tx.v b/rtl/eth_phy_10g_tx.v index 96de4a584..41801897a 100644 --- a/rtl/eth_phy_10g_tx.v +++ b/rtl/eth_phy_10g_tx.v @@ -27,7 +27,7 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * 10G Ethernet PHY + * 10G Ethernet PHY TX */ module eth_phy_10g_tx # ( @@ -89,51 +89,19 @@ xgmii_baser_enc_inst ( .encoded_tx_hdr(encoded_tx_hdr) ); -reg [57:0] scrambler_state_reg = {58{1'b1}}; -wire [57:0] scrambler_state; -wire [DATA_WIDTH-1:0] scrambled_data; - -reg [DATA_WIDTH-1:0] serdes_tx_data_reg = {DATA_WIDTH{1'b0}}; -reg [HDR_WIDTH-1:0] serdes_tx_hdr_reg = {HDR_WIDTH{1'b0}}; - -generate - genvar n; - - if (BIT_REVERSE) begin - for (n = 0; n < DATA_WIDTH; n = n + 1) begin - assign serdes_tx_data[n] = serdes_tx_data_reg[DATA_WIDTH-n-1]; - end - - for (n = 0; n < HDR_WIDTH; n = n + 1) begin - assign serdes_tx_hdr[n] = serdes_tx_hdr_reg[HDR_WIDTH-n-1]; - end - end else begin - assign serdes_tx_data = serdes_tx_data_reg; - assign serdes_tx_hdr = serdes_tx_hdr_reg; - end -endgenerate - -lfsr #( - .LFSR_WIDTH(58), - .LFSR_POLY(58'h8000000001), - .LFSR_CONFIG("FIBONACCI"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), +eth_phy_10g_tx_if #( .DATA_WIDTH(DATA_WIDTH), - .STYLE("AUTO") + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(BIT_REVERSE), + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE) ) -scrambler_inst ( - .data_in(encoded_tx_data), - .state_in(scrambler_state_reg), - .data_out(scrambled_data), - .state_out(scrambler_state) +eth_phy_10g_tx_if_inst ( + .clk(clk), + .rst(rst), + .encoded_tx_data(encoded_tx_data), + .encoded_tx_hdr(encoded_tx_hdr), + .serdes_tx_data(serdes_tx_data), + .serdes_tx_hdr(serdes_tx_hdr) ); -always @(posedge clk) begin - scrambler_state_reg <= scrambler_state; - - serdes_tx_data_reg <= SCRAMBLER_DISABLE ? encoded_tx_data : scrambled_data; - serdes_tx_hdr_reg <= encoded_tx_hdr; -end - endmodule diff --git a/rtl/eth_phy_10g_tx_if.v b/rtl/eth_phy_10g_tx_if.v new file mode 100644 index 000000000..d0119ac4e --- /dev/null +++ b/rtl/eth_phy_10g_tx_if.v @@ -0,0 +1,116 @@ +/* + +Copyright (c) 2018 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 + +/* + * 10G Ethernet PHY TX IF + */ +module eth_phy_10g_tx_if # +( + parameter DATA_WIDTH = 64, + parameter HDR_WIDTH = 2, + parameter BIT_REVERSE = 0, + parameter SCRAMBLER_DISABLE = 0 +) +( + input wire clk, + input wire rst, + + /* + * 10GBASE-R encoded interface + */ + input wire [DATA_WIDTH-1:0] encoded_tx_data, + input wire [HDR_WIDTH-1:0] encoded_tx_hdr, + + /* + * SERDES interface + */ + output wire [DATA_WIDTH-1:0] serdes_tx_data, + output wire [HDR_WIDTH-1:0] serdes_tx_hdr +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (HDR_WIDTH != 2) begin + $error("Error: HDR_WIDTH must be 2"); + $finish; + end +end + +reg [57:0] scrambler_state_reg = {58{1'b1}}; +wire [57:0] scrambler_state; +wire [DATA_WIDTH-1:0] scrambled_data; + +reg [DATA_WIDTH-1:0] serdes_tx_data_reg = {DATA_WIDTH{1'b0}}; +reg [HDR_WIDTH-1:0] serdes_tx_hdr_reg = {HDR_WIDTH{1'b0}}; + +generate + genvar n; + + if (BIT_REVERSE) begin + for (n = 0; n < DATA_WIDTH; n = n + 1) begin + assign serdes_tx_data[n] = serdes_tx_data_reg[DATA_WIDTH-n-1]; + end + + for (n = 0; n < HDR_WIDTH; n = n + 1) begin + assign serdes_tx_hdr[n] = serdes_tx_hdr_reg[HDR_WIDTH-n-1]; + end + end else begin + assign serdes_tx_data = serdes_tx_data_reg; + assign serdes_tx_hdr = serdes_tx_hdr_reg; + end +endgenerate + +lfsr #( + .LFSR_WIDTH(58), + .LFSR_POLY(58'h8000000001), + .LFSR_CONFIG("FIBONACCI"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(DATA_WIDTH), + .STYLE("AUTO") +) +scrambler_inst ( + .data_in(encoded_tx_data), + .state_in(scrambler_state_reg), + .data_out(scrambled_data), + .state_out(scrambler_state) +); + +always @(posedge clk) begin + scrambler_state_reg <= scrambler_state; + + serdes_tx_data_reg <= SCRAMBLER_DISABLE ? encoded_tx_data : scrambled_data; + serdes_tx_hdr_reg <= encoded_tx_hdr; +end + +endmodule diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py index 777d0ae15..949713cb6 100755 --- a/tb/test_eth_mac_phy_10g.py +++ b/tb/test_eth_mac_phy_10g.py @@ -41,6 +41,8 @@ srcs.append("../rtl/axis_baser_tx_64.v") srcs.append("../rtl/axis_baser_rx_64.v") srcs.append("../rtl/eth_mac_phy_10g_rx.v") srcs.append("../rtl/eth_mac_phy_10g_tx.v") +srcs.append("../rtl/eth_phy_10g_rx_if.v") +srcs.append("../rtl/eth_phy_10g_tx_if.v") srcs.append("../rtl/eth_phy_10g_rx_ber_mon.v") srcs.append("../rtl/eth_phy_10g_rx_frame_sync.v") srcs.append("../rtl/lfsr.v") diff --git a/tb/test_eth_mac_phy_10g_fifo.py b/tb/test_eth_mac_phy_10g_fifo.py index 8e084b8de..2004e9bcc 100755 --- a/tb/test_eth_mac_phy_10g_fifo.py +++ b/tb/test_eth_mac_phy_10g_fifo.py @@ -42,6 +42,8 @@ srcs.append("../rtl/axis_baser_rx_64.v") srcs.append("../rtl/eth_mac_phy_10g.v") srcs.append("../rtl/eth_mac_phy_10g_rx.v") srcs.append("../rtl/eth_mac_phy_10g_tx.v") +srcs.append("../rtl/eth_phy_10g_rx_if.v") +srcs.append("../rtl/eth_phy_10g_tx_if.v") srcs.append("../rtl/eth_phy_10g_rx_ber_mon.v") srcs.append("../rtl/eth_phy_10g_rx_frame_sync.v") srcs.append("../rtl/lfsr.v") diff --git a/tb/test_eth_phy_10g_64.py b/tb/test_eth_phy_10g_64.py index aa8cf8215..41684510b 100755 --- a/tb/test_eth_phy_10g_64.py +++ b/tb/test_eth_phy_10g_64.py @@ -38,9 +38,11 @@ srcs = [] srcs.append("../rtl/%s.v" % module) srcs.append("../rtl/eth_phy_10g_rx.v") +srcs.append("../rtl/eth_phy_10g_rx_if.v") srcs.append("../rtl/eth_phy_10g_rx_ber_mon.v") srcs.append("../rtl/eth_phy_10g_rx_frame_sync.v") srcs.append("../rtl/eth_phy_10g_tx.v") +srcs.append("../rtl/eth_phy_10g_tx_if.v") srcs.append("../rtl/xgmii_baser_dec_64.v") srcs.append("../rtl/xgmii_baser_enc_64.v") srcs.append("../rtl/lfsr.v") diff --git a/tb/test_eth_phy_10g_rx_64.py b/tb/test_eth_phy_10g_rx_64.py index 29195afa7..c55b33225 100755 --- a/tb/test_eth_phy_10g_rx_64.py +++ b/tb/test_eth_phy_10g_rx_64.py @@ -37,6 +37,7 @@ testbench = 'test_%s_64' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_phy_10g_rx_if.v") srcs.append("../rtl/eth_phy_10g_rx_ber_mon.v") srcs.append("../rtl/eth_phy_10g_rx_frame_sync.v") srcs.append("../rtl/xgmii_baser_dec_64.v") diff --git a/tb/test_eth_phy_10g_tx_64.py b/tb/test_eth_phy_10g_tx_64.py index dffd88854..e19caa431 100755 --- a/tb/test_eth_phy_10g_tx_64.py +++ b/tb/test_eth_phy_10g_tx_64.py @@ -37,6 +37,7 @@ testbench = 'test_%s_64' % module srcs = [] srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/eth_phy_10g_tx_if.v") srcs.append("../rtl/xgmii_baser_enc_64.v") srcs.append("../rtl/lfsr.v") srcs.append("%s.v" % testbench) From e34c72da1fe63e31b62ac5b69116a5a0f5d320aa Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 10 May 2019 17:23:55 -0700 Subject: [PATCH 562/617] Add missing parameter --- tb/test_eth_phy_10g_64.py | 1 + tb/test_eth_phy_10g_64.v | 2 ++ tb/test_eth_phy_10g_rx_64.py | 1 + tb/test_eth_phy_10g_rx_64.v | 2 ++ 4 files changed, 6 insertions(+) diff --git a/tb/test_eth_phy_10g_64.py b/tb/test_eth_phy_10g_64.py index 41684510b..26c432e1a 100755 --- a/tb/test_eth_phy_10g_64.py +++ b/tb/test_eth_phy_10g_64.py @@ -60,6 +60,7 @@ def bench(): HDR_WIDTH = 2 BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 + SLIP_COUNT_WIDTH = 3 COUNT_125US = 1250/6.4 # Inputs diff --git a/tb/test_eth_phy_10g_64.v b/tb/test_eth_phy_10g_64.v index 2e565f000..18c940d1d 100644 --- a/tb/test_eth_phy_10g_64.v +++ b/tb/test_eth_phy_10g_64.v @@ -37,6 +37,7 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter HDR_WIDTH = 2; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; +parameter SLIP_COUNT_WIDTH = 3; parameter COUNT_125US = 125000/6.4; // Inputs @@ -100,6 +101,7 @@ eth_phy_10g #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) UUT ( diff --git a/tb/test_eth_phy_10g_rx_64.py b/tb/test_eth_phy_10g_rx_64.py index c55b33225..6d11cefc5 100755 --- a/tb/test_eth_phy_10g_rx_64.py +++ b/tb/test_eth_phy_10g_rx_64.py @@ -56,6 +56,7 @@ def bench(): HDR_WIDTH = 2 BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 + SLIP_COUNT_WIDTH = 3 COUNT_125US = 1250/6.4 # Inputs diff --git a/tb/test_eth_phy_10g_rx_64.v b/tb/test_eth_phy_10g_rx_64.v index 1a2d1bbab..4fc6f2a67 100644 --- a/tb/test_eth_phy_10g_rx_64.v +++ b/tb/test_eth_phy_10g_rx_64.v @@ -37,6 +37,7 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter HDR_WIDTH = 2; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; +parameter SLIP_COUNT_WIDTH = 3; parameter COUNT_125US = 1250/6.4; // Inputs @@ -84,6 +85,7 @@ eth_phy_10g_rx #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) UUT ( From 79ec13724338b15c5cd8f4ef934001a440fc60b8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 10 May 2019 20:28:45 -0700 Subject: [PATCH 563/617] Add PRBS31 generation and checking to 10G PHY --- rtl/eth_mac_phy_10g.v | 19 ++++++++--- rtl/eth_mac_phy_10g_fifo.v | 10 ++++-- rtl/eth_mac_phy_10g_rx.v | 14 ++++++-- rtl/eth_mac_phy_10g_tx.v | 26 +++++++++------ rtl/eth_phy_10g.v | 21 +++++++++--- rtl/eth_phy_10g_rx.v | 14 ++++++-- rtl/eth_phy_10g_rx_if.v | 59 ++++++++++++++++++++++++++++++++- rtl/eth_phy_10g_tx.v | 16 ++++++--- rtl/eth_phy_10g_tx_if.v | 41 ++++++++++++++++++++--- tb/test_eth_mac_phy_10g.py | 9 ++++- tb/test_eth_mac_phy_10g.v | 15 +++++++-- tb/test_eth_mac_phy_10g_fifo.py | 7 +++- tb/test_eth_mac_phy_10g_fifo.v | 12 +++++-- tb/test_eth_phy_10g_64.py | 9 ++++- tb/test_eth_phy_10g_64.v | 15 +++++++-- tb/test_eth_phy_10g_rx_64.py | 50 +++++++++++++++++++++++++++- tb/test_eth_phy_10g_rx_64.v | 12 +++++-- tb/test_eth_phy_10g_tx_64.py | 36 +++++++++++++++++++- tb/test_eth_phy_10g_tx_64.v | 11 ++++-- 19 files changed, 345 insertions(+), 51 deletions(-) diff --git a/rtl/eth_mac_phy_10g.v b/rtl/eth_mac_phy_10g.v index 061c52942..b859ad22c 100644 --- a/rtl/eth_mac_phy_10g.v +++ b/rtl/eth_mac_phy_10g.v @@ -40,6 +40,7 @@ module eth_mac_phy_10g # parameter MIN_FRAME_LENGTH = 64, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, + parameter PRBS31_ENABLE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4 ) @@ -85,6 +86,7 @@ module eth_mac_phy_10g # output wire tx_error_underflow, output wire rx_start_packet_0, output wire rx_start_packet_4, + output wire [6:0] rx_error_count, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, output wire rx_bad_block, @@ -94,7 +96,9 @@ module eth_mac_phy_10g # /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay, + input wire tx_prbs31_enable, + input wire rx_prbs31_enable ); eth_mac_phy_10g_rx #( @@ -104,6 +108,7 @@ eth_mac_phy_10g_rx #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) @@ -120,11 +125,13 @@ eth_mac_phy_10g_rx_inst ( .serdes_rx_bitslip(serdes_rx_bitslip), .rx_start_packet_0(rx_start_packet_0), .rx_start_packet_4(rx_start_packet_4), + .rx_error_count(rx_error_count), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), - .rx_high_ber(rx_high_ber) + .rx_high_ber(rx_high_ber), + .rx_prbs31_enable(rx_prbs31_enable) ); eth_mac_phy_10g_tx #( @@ -136,7 +143,8 @@ eth_mac_phy_10g_tx #( .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), .BIT_REVERSE(BIT_REVERSE), - .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE) + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE) ) eth_mac_phy_10g_tx_inst ( .clk(tx_clk), @@ -149,10 +157,11 @@ eth_mac_phy_10g_tx_inst ( .s_axis_tuser(tx_axis_tuser), .serdes_tx_data(serdes_tx_data), .serdes_tx_hdr(serdes_tx_hdr), - .ifg_delay(ifg_delay), .tx_start_packet_0(tx_start_packet_0), .tx_start_packet_4(tx_start_packet_4), - .tx_error_underflow(tx_error_underflow) + .tx_error_underflow(tx_error_underflow), + .ifg_delay(ifg_delay), + .tx_prbs31_enable(tx_prbs31_enable) ); endmodule diff --git a/rtl/eth_mac_phy_10g_fifo.v b/rtl/eth_mac_phy_10g_fifo.v index 8c98f418d..a502d6731 100644 --- a/rtl/eth_mac_phy_10g_fifo.v +++ b/rtl/eth_mac_phy_10g_fifo.v @@ -40,6 +40,7 @@ module eth_mac_phy_10g_fifo # parameter MIN_FRAME_LENGTH = 64, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, + parameter PRBS31_ENABLE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4, parameter TX_FIFO_ADDR_WIDTH = 12-$clog2(KEEP_WIDTH), @@ -107,7 +108,9 @@ module eth_mac_phy_10g_fifo # /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay, + input wire tx_prbs31_enable, + input wire rx_prbs31_enable ); wire [DATA_WIDTH-1:0] tx_fifo_axis_tdata; @@ -197,6 +200,7 @@ eth_mac_phy_10g #( .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) @@ -227,7 +231,9 @@ eth_mac_phy_10g_inst ( .rx_bad_block(rx_bad_block_int), .rx_block_lock(rx_block_lock_int), .rx_high_ber(rx_high_ber_int), - .ifg_delay(ifg_delay) + .ifg_delay(ifg_delay), + .tx_prbs31_enable(tx_prbs31_enable), + .rx_prbs31_enable(rx_prbs31_enable) ); axis_async_fifo #( diff --git a/rtl/eth_mac_phy_10g_rx.v b/rtl/eth_mac_phy_10g_rx.v index 8773bc21a..119fb6155 100644 --- a/rtl/eth_mac_phy_10g_rx.v +++ b/rtl/eth_mac_phy_10g_rx.v @@ -37,6 +37,7 @@ module eth_mac_phy_10g_rx # parameter HDR_WIDTH = (DATA_WIDTH/32), parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, + parameter PRBS31_ENABLE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4 ) @@ -65,11 +66,17 @@ module eth_mac_phy_10g_rx # */ output wire rx_start_packet_0, output wire rx_start_packet_4, + output wire [6:0] rx_error_count, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, output wire rx_bad_block, output wire rx_block_lock, - output wire rx_high_ber + output wire rx_high_ber, + + /* + * Configuration + */ + input wire rx_prbs31_enable ); // bus width assertions @@ -98,6 +105,7 @@ eth_phy_10g_rx_if #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) @@ -109,9 +117,11 @@ eth_phy_10g_rx_if_inst ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_error_count(rx_error_count), .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), - .rx_high_ber(rx_high_ber) + .rx_high_ber(rx_high_ber), + .rx_prbs31_enable(rx_prbs31_enable) ); axis_baser_rx_64 #( diff --git a/rtl/eth_mac_phy_10g_tx.v b/rtl/eth_mac_phy_10g_tx.v index cdf1ef601..1399ae92c 100644 --- a/rtl/eth_mac_phy_10g_tx.v +++ b/rtl/eth_mac_phy_10g_tx.v @@ -39,7 +39,8 @@ module eth_mac_phy_10g_tx # parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, parameter BIT_REVERSE = 0, - parameter SCRAMBLER_DISABLE = 0 + parameter SCRAMBLER_DISABLE = 0, + parameter PRBS31_ENABLE = 0 ) ( input wire clk, @@ -61,17 +62,18 @@ module eth_mac_phy_10g_tx # output wire [DATA_WIDTH-1:0] serdes_tx_data, output wire [HDR_WIDTH-1:0] serdes_tx_hdr, - /* - * Configuration - */ - input wire [7:0] ifg_delay, - /* * Status */ output wire tx_start_packet_0, output wire tx_start_packet_4, - output wire tx_error_underflow + output wire tx_error_underflow, + + /* + * Configuration + */ + input wire [7:0] ifg_delay, + input wire tx_prbs31_enable ); // bus width assertions @@ -114,17 +116,18 @@ axis_baser_tx_inst ( .s_axis_tuser(s_axis_tuser), .encoded_tx_data(encoded_tx_data), .encoded_tx_hdr(encoded_tx_hdr), - .ifg_delay(ifg_delay), .start_packet_0(tx_start_packet_0), .start_packet_4(tx_start_packet_4), - .error_underflow(tx_error_underflow) + .error_underflow(tx_error_underflow), + .ifg_delay(ifg_delay) ); eth_phy_10g_tx_if #( .DATA_WIDTH(DATA_WIDTH), .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), - .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE) + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE) ) eth_phy_10g_tx_if_inst ( .clk(clk), @@ -132,7 +135,8 @@ eth_phy_10g_tx_if_inst ( .encoded_tx_data(encoded_tx_data), .encoded_tx_hdr(encoded_tx_hdr), .serdes_tx_data(serdes_tx_data), - .serdes_tx_hdr(serdes_tx_hdr) + .serdes_tx_hdr(serdes_tx_hdr), + .tx_prbs31_enable(tx_prbs31_enable) ); endmodule diff --git a/rtl/eth_phy_10g.v b/rtl/eth_phy_10g.v index 97be98925..341e86f5e 100644 --- a/rtl/eth_phy_10g.v +++ b/rtl/eth_phy_10g.v @@ -36,6 +36,7 @@ module eth_phy_10g # parameter HDR_WIDTH = 2, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, + parameter PRBS31_ENABLE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4 ) @@ -65,9 +66,16 @@ module eth_phy_10g # /* * Status */ + output wire [6:0] rx_error_count, output wire rx_bad_block, output wire rx_block_lock, - output wire rx_high_ber + output wire rx_high_ber, + + /* + * Configuration + */ + input wire tx_prbs31_enable, + input wire rx_prbs31_enable ); eth_phy_10g_rx #( @@ -76,6 +84,7 @@ eth_phy_10g_rx #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) @@ -87,9 +96,11 @@ eth_phy_10g_rx_inst ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_error_count(rx_error_count), .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), - .rx_high_ber(rx_high_ber) + .rx_high_ber(rx_high_ber), + .rx_prbs31_enable(rx_prbs31_enable) ); eth_phy_10g_tx #( @@ -97,7 +108,8 @@ eth_phy_10g_tx #( .CTRL_WIDTH(CTRL_WIDTH), .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), - .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE) + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE) ) eth_phy_10g_tx_inst ( .clk(tx_clk), @@ -105,7 +117,8 @@ eth_phy_10g_tx_inst ( .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), .serdes_tx_data(serdes_tx_data), - .serdes_tx_hdr(serdes_tx_hdr) + .serdes_tx_hdr(serdes_tx_hdr), + .tx_prbs31_enable(tx_prbs31_enable) ); endmodule diff --git a/rtl/eth_phy_10g_rx.v b/rtl/eth_phy_10g_rx.v index f8d945ab1..931e6bb34 100644 --- a/rtl/eth_phy_10g_rx.v +++ b/rtl/eth_phy_10g_rx.v @@ -36,6 +36,7 @@ module eth_phy_10g_rx # parameter HDR_WIDTH = 2, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, + parameter PRBS31_ENABLE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4 ) @@ -59,9 +60,15 @@ module eth_phy_10g_rx # /* * Status */ + output wire [6:0] rx_error_count, output wire rx_bad_block, output wire rx_block_lock, - output wire rx_high_ber + output wire rx_high_ber, + + /* + * Configuration + */ + input wire rx_prbs31_enable ); // bus width assertions @@ -90,6 +97,7 @@ eth_phy_10g_rx_if #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) @@ -101,9 +109,11 @@ eth_phy_10g_rx_if_inst ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_error_count(rx_error_count), .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), - .rx_high_ber(rx_high_ber) + .rx_high_ber(rx_high_ber), + .rx_prbs31_enable(rx_prbs31_enable) ); xgmii_baser_dec_64 #( diff --git a/rtl/eth_phy_10g_rx_if.v b/rtl/eth_phy_10g_rx_if.v index 59db115f0..deac5e452 100644 --- a/rtl/eth_phy_10g_rx_if.v +++ b/rtl/eth_phy_10g_rx_if.v @@ -35,6 +35,7 @@ module eth_phy_10g_rx_if # parameter HDR_WIDTH = 2, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, + parameter PRBS31_ENABLE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4 ) @@ -58,9 +59,15 @@ module eth_phy_10g_rx_if # /* * Status */ + output wire [6:0] rx_error_count, output wire rx_bad_block, output wire rx_block_lock, - output wire rx_high_ber + output wire rx_high_ber, + + /* + * Configuration + */ + input wire rx_prbs31_enable ); // bus width assertions @@ -104,6 +111,16 @@ reg [HDR_WIDTH-1:0] encoded_rx_hdr_reg = {HDR_WIDTH{1'b0}}; reg [57:0] scrambler_state_reg = {58{1'b1}}; wire [57:0] scrambler_state; +reg [30:0] prbs31_state_reg = 31'h7fffffff; +wire [30:0] prbs31_state; +wire [DATA_WIDTH+HDR_WIDTH-1:0] prbs31_data; + +reg [6:0] rx_error_count_reg = 0; +reg [5:0] rx_error_count_1_reg = 0; +reg [5:0] rx_error_count_2_reg = 0; +reg [5:0] rx_error_count_1_temp = 0; +reg [5:0] rx_error_count_2_temp = 0; + lfsr #( .LFSR_WIDTH(58), .LFSR_POLY(58'h8000000001), @@ -120,16 +137,56 @@ descrambler_inst ( .state_out(scrambler_state) ); +lfsr #( + .LFSR_WIDTH(31), + .LFSR_POLY(31'h10000001), + .LFSR_CONFIG("FIBONACCI"), + .LFSR_FEED_FORWARD(1), + .REVERSE(1), + .DATA_WIDTH(DATA_WIDTH+HDR_WIDTH), + .STYLE("AUTO") +) +prbs31_check_inst ( + .data_in(~{serdes_rx_data_int, serdes_rx_hdr_int}), + .state_in(prbs31_state_reg), + .data_out(prbs31_data), + .state_out(prbs31_state) +); + +integer i; + +always @* begin + rx_error_count_1_temp = 0; + rx_error_count_2_temp = 0; + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + if (i & 1) begin + rx_error_count_1_temp = rx_error_count_1_temp + prbs31_data[i]; + end else begin + rx_error_count_2_temp = rx_error_count_2_temp + prbs31_data[i]; + end + end +end + always @(posedge clk) begin scrambler_state_reg <= scrambler_state; encoded_rx_data_reg <= SCRAMBLER_DISABLE ? serdes_rx_data_int : descrambled_rx_data; encoded_rx_hdr_reg <= serdes_rx_hdr_int; + + if (PRBS31_ENABLE && rx_prbs31_enable) begin + prbs31_state_reg <= prbs31_state; + + rx_error_count_1_reg <= rx_error_count_1_temp; + rx_error_count_2_reg <= rx_error_count_2_temp; + rx_error_count_reg <= rx_error_count_1_reg + rx_error_count_2_reg; + end end assign encoded_rx_data = encoded_rx_data_reg; assign encoded_rx_hdr = encoded_rx_hdr_reg; +assign rx_error_count = rx_error_count_reg; + eth_phy_10g_rx_frame_sync #( .HDR_WIDTH(HDR_WIDTH), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH) diff --git a/rtl/eth_phy_10g_tx.v b/rtl/eth_phy_10g_tx.v index 41801897a..6fc6caf73 100644 --- a/rtl/eth_phy_10g_tx.v +++ b/rtl/eth_phy_10g_tx.v @@ -35,7 +35,8 @@ module eth_phy_10g_tx # parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter HDR_WIDTH = 2, parameter BIT_REVERSE = 0, - parameter SCRAMBLER_DISABLE = 0 + parameter SCRAMBLER_DISABLE = 0, + parameter PRBS31_ENABLE = 0 ) ( input wire clk, @@ -51,7 +52,12 @@ module eth_phy_10g_tx # * SERDES interface */ output wire [DATA_WIDTH-1:0] serdes_tx_data, - output wire [HDR_WIDTH-1:0] serdes_tx_hdr + output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + + /* + * Configuration + */ + input wire tx_prbs31_enable ); // bus width assertions @@ -93,7 +99,8 @@ eth_phy_10g_tx_if #( .DATA_WIDTH(DATA_WIDTH), .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), - .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE) + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE) ) eth_phy_10g_tx_if_inst ( .clk(clk), @@ -101,7 +108,8 @@ eth_phy_10g_tx_if_inst ( .encoded_tx_data(encoded_tx_data), .encoded_tx_hdr(encoded_tx_hdr), .serdes_tx_data(serdes_tx_data), - .serdes_tx_hdr(serdes_tx_hdr) + .serdes_tx_hdr(serdes_tx_hdr), + .tx_prbs31_enable(tx_prbs31_enable) ); endmodule diff --git a/rtl/eth_phy_10g_tx_if.v b/rtl/eth_phy_10g_tx_if.v index d0119ac4e..5f84c6ba2 100644 --- a/rtl/eth_phy_10g_tx_if.v +++ b/rtl/eth_phy_10g_tx_if.v @@ -34,7 +34,8 @@ module eth_phy_10g_tx_if # parameter DATA_WIDTH = 64, parameter HDR_WIDTH = 2, parameter BIT_REVERSE = 0, - parameter SCRAMBLER_DISABLE = 0 + parameter SCRAMBLER_DISABLE = 0, + parameter PRBS31_ENABLE = 0 ) ( input wire clk, @@ -50,7 +51,12 @@ module eth_phy_10g_tx_if # * SERDES interface */ output wire [DATA_WIDTH-1:0] serdes_tx_data, - output wire [HDR_WIDTH-1:0] serdes_tx_hdr + output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + + /* + * Configuration + */ + input wire tx_prbs31_enable ); // bus width assertions @@ -70,6 +76,10 @@ reg [57:0] scrambler_state_reg = {58{1'b1}}; wire [57:0] scrambler_state; wire [DATA_WIDTH-1:0] scrambled_data; +reg [30:0] prbs31_state_reg = 31'h7fffffff; +wire [30:0] prbs31_state; +wire [DATA_WIDTH+HDR_WIDTH-1:0] prbs31_data; + reg [DATA_WIDTH-1:0] serdes_tx_data_reg = {DATA_WIDTH{1'b0}}; reg [HDR_WIDTH-1:0] serdes_tx_hdr_reg = {HDR_WIDTH{1'b0}}; @@ -106,11 +116,34 @@ scrambler_inst ( .state_out(scrambler_state) ); +lfsr #( + .LFSR_WIDTH(31), + .LFSR_POLY(31'h10000001), + .LFSR_CONFIG("FIBONACCI"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(DATA_WIDTH+HDR_WIDTH), + .STYLE("AUTO") +) +prbs31_gen_inst ( + .data_in({DATA_WIDTH+HDR_WIDTH{1'b0}}), + .state_in(prbs31_state_reg), + .data_out(prbs31_data), + .state_out(prbs31_state) +); + always @(posedge clk) begin scrambler_state_reg <= scrambler_state; - serdes_tx_data_reg <= SCRAMBLER_DISABLE ? encoded_tx_data : scrambled_data; - serdes_tx_hdr_reg <= encoded_tx_hdr; + if (PRBS31_ENABLE && tx_prbs31_enable) begin + prbs31_state_reg <= prbs31_state; + + serdes_tx_data_reg <= ~prbs31_data[DATA_WIDTH+HDR_WIDTH-1:HDR_WIDTH]; + serdes_tx_hdr_reg <= ~prbs31_data[HDR_WIDTH-1:0]; + end else begin + serdes_tx_data_reg <= SCRAMBLER_DISABLE ? encoded_tx_data : scrambled_data; + serdes_tx_hdr_reg <= encoded_tx_hdr; + end end endmodule diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py index 949713cb6..23468c8a0 100755 --- a/tb/test_eth_mac_phy_10g.py +++ b/tb/test_eth_mac_phy_10g.py @@ -64,6 +64,7 @@ def bench(): MIN_FRAME_LENGTH = 64 BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 + PRBS31_ENABLE = 1 SLIP_COUNT_WIDTH = 3 COUNT_125US = 125000/6.4 @@ -84,6 +85,8 @@ def bench(): serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) + tx_prbs31_enable = Signal(bool(0)) + rx_prbs31_enable = Signal(bool(0)) serdes_rx_data_int = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_hdr_int = Signal(intbv(1)[HDR_WIDTH:]) @@ -103,6 +106,7 @@ def bench(): tx_error_underflow = Signal(bool(0)) rx_start_packet_0 = Signal(bool(0)) rx_start_packet_4 = Signal(bool(0)) + rx_error_count = Signal(intbv(0)[7:]) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) rx_bad_block = Signal(bool(0)) @@ -192,12 +196,15 @@ def bench(): tx_error_underflow=tx_error_underflow, rx_start_packet_0=rx_start_packet_0, rx_start_packet_4=rx_start_packet_4, + rx_error_count=rx_error_count, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, rx_bad_block=rx_bad_block, rx_block_lock=rx_block_lock, rx_high_ber=rx_high_ber, - ifg_delay=ifg_delay + ifg_delay=ifg_delay, + tx_prbs31_enable=tx_prbs31_enable, + rx_prbs31_enable=rx_prbs31_enable ) @always(delay(4)) diff --git a/tb/test_eth_mac_phy_10g.v b/tb/test_eth_mac_phy_10g.v index 5f70fcc10..cbc06970c 100644 --- a/tb/test_eth_mac_phy_10g.v +++ b/tb/test_eth_mac_phy_10g.v @@ -41,6 +41,7 @@ parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; +parameter PRBS31_ENABLE = 1; parameter SLIP_COUNT_WIDTH = 3; parameter COUNT_125US = 125000/6.4; @@ -61,6 +62,8 @@ reg tx_axis_tuser = 0; reg [DATA_WIDTH-1:0] serdes_rx_data = 0; reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; reg [7:0] ifg_delay = 0; +reg tx_prbs31_enable = 0; +reg rx_prbs31_enable = 0; // Outputs wire tx_axis_tready; @@ -77,6 +80,7 @@ wire tx_start_packet_4; wire tx_error_underflow; wire rx_start_packet_0; wire rx_start_packet_4; +wire [6:0] rx_error_count; wire rx_error_bad_frame; wire rx_error_bad_fcs; wire rx_bad_block; @@ -100,7 +104,9 @@ initial begin tx_axis_tuser, serdes_rx_data, serdes_rx_hdr, - ifg_delay + ifg_delay, + tx_prbs31_enable, + rx_prbs31_enable ); $to_myhdl( tx_axis_tready, @@ -115,6 +121,7 @@ initial begin tx_start_packet_0, tx_start_packet_4, tx_error_underflow, + rx_error_count, rx_start_packet_0, rx_start_packet_4, rx_error_bad_frame, @@ -139,6 +146,7 @@ eth_mac_phy_10g #( .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) @@ -168,12 +176,15 @@ UUT ( .tx_error_underflow(tx_error_underflow), .rx_start_packet_0(rx_start_packet_0), .rx_start_packet_4(rx_start_packet_4), + .rx_error_count(rx_error_count), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), .rx_high_ber(rx_high_ber), - .ifg_delay(ifg_delay) + .ifg_delay(ifg_delay), + .tx_prbs31_enable(tx_prbs31_enable), + .rx_prbs31_enable(rx_prbs31_enable) ); endmodule diff --git a/tb/test_eth_mac_phy_10g_fifo.py b/tb/test_eth_mac_phy_10g_fifo.py index 2004e9bcc..628fd946c 100755 --- a/tb/test_eth_mac_phy_10g_fifo.py +++ b/tb/test_eth_mac_phy_10g_fifo.py @@ -66,6 +66,7 @@ def bench(): MIN_FRAME_LENGTH = 64 BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 + PRBS31_ENABLE = 1 SLIP_COUNT_WIDTH = 3 COUNT_125US = 125000/6.4 TX_FIFO_ADDR_WIDTH = 12-(KEEP_WIDTH-1).bit_length() @@ -97,6 +98,8 @@ def bench(): serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) + tx_prbs31_enable = Signal(bool(0)) + rx_prbs31_enable = Signal(bool(0)) serdes_rx_data_int = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_hdr_int = Signal(intbv(1)[HDR_WIDTH:]) @@ -218,7 +221,9 @@ def bench(): rx_fifo_overflow=rx_fifo_overflow, rx_fifo_bad_frame=rx_fifo_bad_frame, rx_fifo_good_frame=rx_fifo_good_frame, - ifg_delay=ifg_delay + ifg_delay=ifg_delay, + tx_prbs31_enable=tx_prbs31_enable, + rx_prbs31_enable=rx_prbs31_enable ) @always(delay(4)) diff --git a/tb/test_eth_mac_phy_10g_fifo.v b/tb/test_eth_mac_phy_10g_fifo.v index 81b8ab1f2..a688e60c7 100644 --- a/tb/test_eth_mac_phy_10g_fifo.v +++ b/tb/test_eth_mac_phy_10g_fifo.v @@ -41,6 +41,7 @@ parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; +parameter PRBS31_ENABLE = 1; parameter SLIP_COUNT_WIDTH = 3; parameter COUNT_125US = 125000/6.4; parameter TX_FIFO_ADDR_WIDTH = 12-$clog2(KEEP_WIDTH); @@ -72,6 +73,8 @@ reg rx_axis_tready = 0; reg [DATA_WIDTH-1:0] serdes_rx_data = 0; reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; reg [7:0] ifg_delay = 0; +reg tx_prbs31_enable = 0; +reg rx_prbs31_enable = 0; // Outputs wire tx_axis_tready; @@ -116,7 +119,9 @@ initial begin rx_axis_tready, serdes_rx_data, serdes_rx_hdr, - ifg_delay + ifg_delay, + tx_prbs31_enable, + rx_prbs31_enable ); $to_myhdl( tx_axis_tready, @@ -157,6 +162,7 @@ eth_mac_phy_10g_fifo #( .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US), .TX_FIFO_ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), @@ -204,7 +210,9 @@ UUT ( .rx_fifo_overflow(rx_fifo_overflow), .rx_fifo_bad_frame(rx_fifo_bad_frame), .rx_fifo_good_frame(rx_fifo_good_frame), - .ifg_delay(ifg_delay) + .ifg_delay(ifg_delay), + .tx_prbs31_enable(tx_prbs31_enable), + .rx_prbs31_enable(rx_prbs31_enable) ); endmodule diff --git a/tb/test_eth_phy_10g_64.py b/tb/test_eth_phy_10g_64.py index 26c432e1a..55d216fc2 100755 --- a/tb/test_eth_phy_10g_64.py +++ b/tb/test_eth_phy_10g_64.py @@ -60,6 +60,7 @@ def bench(): HDR_WIDTH = 2 BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 + PRBS31_ENABLE = 1 SLIP_COUNT_WIDTH = 3 COUNT_125US = 1250/6.4 @@ -76,6 +77,8 @@ def bench(): xgmii_txc = Signal(intbv(0)[CTRL_WIDTH:]) serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + tx_prbs31_enable = Signal(bool(0)) + rx_prbs31_enable = Signal(bool(0)) serdes_rx_data_int = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_hdr_int = Signal(intbv(1)[HDR_WIDTH:]) @@ -86,6 +89,7 @@ def bench(): serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_tx_hdr = Signal(intbv(0)[HDR_WIDTH:]) serdes_rx_bitslip = Signal(bool(0)) + rx_error_count = Signal(intbv(0)[7:]) rx_bad_block = Signal(bool(0)) rx_block_lock = Signal(bool(0)) rx_high_ber = Signal(bool(0)) @@ -151,9 +155,12 @@ def bench(): serdes_rx_data=serdes_rx_data, serdes_rx_hdr=serdes_rx_hdr, serdes_rx_bitslip=serdes_rx_bitslip, + rx_error_count=rx_error_count, rx_bad_block=rx_bad_block, rx_block_lock=rx_block_lock, - rx_high_ber=rx_high_ber + rx_high_ber=rx_high_ber, + tx_prbs31_enable=tx_prbs31_enable, + rx_prbs31_enable=rx_prbs31_enable ) @always(delay(4)) diff --git a/tb/test_eth_phy_10g_64.v b/tb/test_eth_phy_10g_64.v index 18c940d1d..94c102caa 100644 --- a/tb/test_eth_phy_10g_64.v +++ b/tb/test_eth_phy_10g_64.v @@ -37,6 +37,7 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter HDR_WIDTH = 2; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; +parameter PRBS31_ENABLE = 1; parameter SLIP_COUNT_WIDTH = 3; parameter COUNT_125US = 125000/6.4; @@ -53,6 +54,8 @@ reg [DATA_WIDTH-1:0] xgmii_txd = 0; reg [CTRL_WIDTH-1:0] xgmii_txc = 0; reg [DATA_WIDTH-1:0] serdes_rx_data = 0; reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; +reg tx_prbs31_enable = 0; +reg rx_prbs31_enable = 0; // Outputs wire [DATA_WIDTH-1:0] xgmii_rxd; @@ -60,6 +63,7 @@ wire [CTRL_WIDTH-1:0] xgmii_rxc; wire [DATA_WIDTH-1:0] serdes_tx_data; wire [HDR_WIDTH-1:0] serdes_tx_hdr; wire serdes_rx_bitslip; +wire [6:0] rx_error_count; wire rx_bad_block; wire rx_block_lock; wire rx_high_ber; @@ -77,7 +81,9 @@ initial begin xgmii_txd, xgmii_txc, serdes_rx_data, - serdes_rx_hdr + serdes_rx_hdr, + tx_prbs31_enable, + rx_prbs31_enable ); $to_myhdl( xgmii_rxd, @@ -85,6 +91,7 @@ initial begin serdes_tx_data, serdes_tx_hdr, serdes_rx_bitslip, + rx_error_count, rx_bad_block, rx_block_lock, rx_high_ber @@ -101,6 +108,7 @@ eth_phy_10g #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) @@ -118,9 +126,12 @@ UUT ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_error_count(rx_error_count), .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), - .rx_high_ber(rx_high_ber) + .rx_high_ber(rx_high_ber), + .tx_prbs31_enable(tx_prbs31_enable), + .rx_prbs31_enable(rx_prbs31_enable) ); endmodule diff --git a/tb/test_eth_phy_10g_rx_64.py b/tb/test_eth_phy_10g_rx_64.py index 6d11cefc5..c7f0277cd 100755 --- a/tb/test_eth_phy_10g_rx_64.py +++ b/tb/test_eth_phy_10g_rx_64.py @@ -48,6 +48,17 @@ src = ' '.join(srcs) build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) +def prbs31(width=8, state=0x7fffffff): + while True: + out = 0 + for i in range(width): + if bool(state & 0x08000000) ^ bool(state & 0x40000000): + state = ((state & 0x3fffffff) << 1) | 1 + out = out | 2**i + else: + state = (state & 0x3fffffff) << 1 + yield ~out & (2**width-1) + def bench(): # Parameters @@ -56,6 +67,7 @@ def bench(): HDR_WIDTH = 2 BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 + PRBS31_ENABLE = 1 SLIP_COUNT_WIDTH = 3 COUNT_125US = 1250/6.4 @@ -66,6 +78,7 @@ def bench(): serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + rx_prbs31_enable = Signal(bool(0)) serdes_rx_data_int = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_hdr_int = Signal(intbv(1)[HDR_WIDTH:]) @@ -74,6 +87,7 @@ def bench(): xgmii_rxd = Signal(intbv(0)[DATA_WIDTH:]) xgmii_rxc = Signal(intbv(0)[CTRL_WIDTH:]) serdes_rx_bitslip = Signal(bool(0)) + rx_error_count = Signal(intbv(0)[7:]) rx_bad_block = Signal(bool(0)) rx_block_lock = Signal(bool(0)) rx_high_ber = Signal(bool(0)) @@ -112,9 +126,11 @@ def bench(): serdes_rx_data=serdes_rx_data, serdes_rx_hdr=serdes_rx_hdr, serdes_rx_bitslip=serdes_rx_bitslip, + rx_error_count=rx_error_count, rx_bad_block=rx_bad_block, rx_block_lock=rx_block_lock, - rx_high_ber=rx_high_ber + rx_high_ber=rx_high_ber, + rx_prbs31_enable=rx_prbs31_enable ) @always(delay(4)) @@ -122,12 +138,15 @@ def bench(): clk.next = not clk load_bit_offset = [] + prbs_en = Signal(bool(0)) @instance def shift_bits(): bit_offset = 0 last_data = 0 + prbs_gen = prbs31(66) + while True: yield clk.posedge @@ -145,6 +164,9 @@ def bench(): last_data = data + if prbs_en: + out_data = next(prbs_gen) + serdes_rx_data.next = out_data >> 2 serdes_rx_hdr.next = out_data & 3 @@ -260,6 +282,32 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 5: PRBS31 check") + current_test.next = 5 + + rx_prbs31_enable.next = True + + yield delay(100) + + for k in range(20): + yield clk.posedge + assert rx_error_count > 0 + + prbs_en.next = True + + yield delay(100) + + for k in range(20): + yield clk.posedge + assert rx_error_count == 0 + + prbs_en.next = False + + rx_prbs31_enable.next = False + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_eth_phy_10g_rx_64.v b/tb/test_eth_phy_10g_rx_64.v index 4fc6f2a67..96bb37e6b 100644 --- a/tb/test_eth_phy_10g_rx_64.v +++ b/tb/test_eth_phy_10g_rx_64.v @@ -37,6 +37,7 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter HDR_WIDTH = 2; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; +parameter PRBS31_ENABLE = 1; parameter SLIP_COUNT_WIDTH = 3; parameter COUNT_125US = 1250/6.4; @@ -47,11 +48,13 @@ reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] serdes_rx_data = 0; reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; +reg rx_prbs31_enable = 0; // Outputs wire [DATA_WIDTH-1:0] xgmii_rxd; wire [CTRL_WIDTH-1:0] xgmii_rxc; wire serdes_rx_bitslip; +wire [6:0] rx_error_count; wire rx_bad_block; wire rx_block_lock; wire rx_high_ber; @@ -63,12 +66,14 @@ initial begin rst, current_test, serdes_rx_data, - serdes_rx_hdr + serdes_rx_hdr, + rx_prbs31_enable ); $to_myhdl( xgmii_rxd, xgmii_rxc, serdes_rx_bitslip, + rx_error_count, rx_bad_block, rx_block_lock, rx_high_ber @@ -85,6 +90,7 @@ eth_phy_10g_rx #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) @@ -96,9 +102,11 @@ UUT ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .rx_error_count(rx_error_count), .rx_bad_block(rx_bad_block), .rx_block_lock(rx_block_lock), - .rx_high_ber(rx_high_ber) + .rx_high_ber(rx_high_ber), + .rx_prbs31_enable(rx_prbs31_enable) ); endmodule diff --git a/tb/test_eth_phy_10g_tx_64.py b/tb/test_eth_phy_10g_tx_64.py index e19caa431..79b9339f0 100755 --- a/tb/test_eth_phy_10g_tx_64.py +++ b/tb/test_eth_phy_10g_tx_64.py @@ -46,6 +46,17 @@ src = ' '.join(srcs) build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) +def prbs31(width=8, state=0x7fffffff): + while True: + out = 0 + for i in range(width): + if bool(state & 0x08000000) ^ bool(state & 0x40000000): + state = ((state & 0x3fffffff) << 1) | 1 + out = out | 2**i + else: + state = (state & 0x3fffffff) << 1 + yield ~out & (2**width-1) + def bench(): # Parameters @@ -54,6 +65,7 @@ def bench(): HDR_WIDTH = 2 BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 + PRBS31_ENABLE = 1 # Inputs clk = Signal(bool(0)) @@ -62,6 +74,7 @@ def bench(): xgmii_txd = Signal(intbv(0)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0)[CTRL_WIDTH:]) + tx_prbs31_enable = Signal(bool(0)) # Outputs serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) @@ -99,7 +112,8 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, serdes_tx_data=serdes_tx_data, - serdes_tx_hdr=serdes_tx_hdr + serdes_tx_hdr=serdes_tx_hdr, + tx_prbs31_enable=tx_prbs31_enable ) @always(delay(4)) @@ -195,6 +209,26 @@ def bench(): yield delay(100) + yield clk.posedge + print("test 4: PRBS31 generation") + current_test.next = 4 + + tx_prbs31_enable.next = True + + yield delay(100) + + prbs_gen = prbs31(66) + prbs_data = [next(prbs_gen) for x in range(100)] + + for k in range(20): + yield clk.posedge + data = int(serdes_tx_data) << 2 | int(serdes_tx_hdr) + assert data in prbs_data + + tx_prbs31_enable.next = False + + yield delay(100) + raise StopSimulation return instances() diff --git a/tb/test_eth_phy_10g_tx_64.v b/tb/test_eth_phy_10g_tx_64.v index af5a5fd36..374be71f5 100644 --- a/tb/test_eth_phy_10g_tx_64.v +++ b/tb/test_eth_phy_10g_tx_64.v @@ -37,6 +37,7 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter HDR_WIDTH = 2; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; +parameter PRBS31_ENABLE = 1; // Inputs reg clk = 0; @@ -45,6 +46,7 @@ reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] xgmii_txd = 0; reg [CTRL_WIDTH-1:0] xgmii_txc = 0; +reg tx_prbs31_enable = 0; // Outputs wire [DATA_WIDTH-1:0] serdes_tx_data; @@ -57,7 +59,8 @@ initial begin rst, current_test, xgmii_txd, - xgmii_txc + xgmii_txc, + tx_prbs31_enable ); $to_myhdl( serdes_tx_data, @@ -74,7 +77,8 @@ eth_phy_10g_tx #( .CTRL_WIDTH(CTRL_WIDTH), .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), - .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE) + .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), + .PRBS31_ENABLE(PRBS31_ENABLE) ) UUT ( .clk(clk), @@ -82,7 +86,8 @@ UUT ( .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), .serdes_tx_data(serdes_tx_data), - .serdes_tx_hdr(serdes_tx_hdr) + .serdes_tx_hdr(serdes_tx_hdr), + .tx_prbs31_enable(tx_prbs31_enable) ); endmodule From 249f9d9df4f091aaefc9de6bd734dd3b66037f90 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 10 May 2019 22:55:44 -0700 Subject: [PATCH 564/617] Update example designs --- example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile | 2 ++ example/ExaNIC_X10/fpga/fpga/Makefile | 2 ++ example/VCU118/fpga_10g/fpga/Makefile | 2 ++ 3 files changed, 6 insertions(+) diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile index 440aef95e..5c5aa8e84 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -16,9 +16,11 @@ SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v diff --git a/example/ExaNIC_X10/fpga/fpga/Makefile b/example/ExaNIC_X10/fpga/fpga/Makefile index 4838540a3..0c3fbbee6 100644 --- a/example/ExaNIC_X10/fpga/fpga/Makefile +++ b/example/ExaNIC_X10/fpga/fpga/Makefile @@ -15,9 +15,11 @@ SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile index 95d9c5219..7b00eb4ad 100644 --- a/example/VCU118/fpga_10g/fpga/Makefile +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -21,9 +21,11 @@ SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v From 3da3725429401ff9b8ac27ba3b3be62a726ee7bc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 16 May 2019 23:22:47 -0700 Subject: [PATCH 565/617] Disable bit slipping when RX PRBS check is enabled --- rtl/eth_phy_10g_rx_if.v | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rtl/eth_phy_10g_rx_if.v b/rtl/eth_phy_10g_rx_if.v index deac5e452..996afcfec 100644 --- a/rtl/eth_phy_10g_rx_if.v +++ b/rtl/eth_phy_10g_rx_if.v @@ -187,6 +187,9 @@ assign encoded_rx_hdr = encoded_rx_hdr_reg; assign rx_error_count = rx_error_count_reg; +wire serdes_rx_bitslip_int; +assign serdes_rx_bitslip = serdes_rx_bitslip_int && !(PRBS31_ENABLE && rx_prbs31_enable); + eth_phy_10g_rx_frame_sync #( .HDR_WIDTH(HDR_WIDTH), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH) @@ -195,7 +198,7 @@ eth_phy_10g_rx_frame_sync_inst ( .clk(clk), .rst(rst), .serdes_rx_hdr(serdes_rx_hdr_int), - .serdes_rx_bitslip(serdes_rx_bitslip), + .serdes_rx_bitslip(serdes_rx_bitslip_int), .rx_block_lock(rx_block_lock) ); From 352f52e15921689e5b6390a3a8d66f193172a133 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 27 May 2019 01:02:55 -0700 Subject: [PATCH 566/617] Add flash target to Arty example design --- example/Arty/fpga/fpga.xdc | 8 +++++--- example/Arty/fpga/fpga/Makefile | 32 +++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/example/Arty/fpga/fpga.xdc b/example/Arty/fpga/fpga.xdc index 87fc5b623..b21f79e90 100644 --- a/example/Arty/fpga/fpga.xdc +++ b/example/Arty/fpga/fpga.xdc @@ -2,9 +2,11 @@ # part: xc7a35t-csg324-1 # General configuration -set_property CFGBVS VCCO [current_design] -set_property CONFIG_VOLTAGE 3.3 [current_design] -set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property CFGBVS VCCO [current_design] +set_property CONFIG_VOLTAGE 3.3 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] # 100 MHz clock set_property -dict {LOC E3 IOSTANDARD LVCMOS33} [get_ports clk] diff --git a/example/Arty/fpga/fpga/Makefile b/example/Arty/fpga/fpga/Makefile index 596b0e845..865b11d68 100644 --- a/example/Arty/fpga/fpga/Makefile +++ b/example/Arty/fpga/fpga/Makefile @@ -53,9 +53,35 @@ program: $(FPGA_TOP).bit echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl - echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl - echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl - echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl vivado -mode batch -source program.tcl +%.mcs: %.bit + echo "write_cfgmem -force -format mcs -size 16 -interface SPIx4 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -mode batch -source generate_mcs.tcl + +flash: $(FPGA_TOP).mcs + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25ql128-spi-x1_x2_x4}] 0]" >> flash.tcl + echo "set_property PROGRAM.FILES [list "$(FPGA_TOP).mcs"] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices] 0]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -mode batch -source flash.tcl + From e181ea5abc824549140f50d676cef36d6bdab93c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 3 Jun 2019 19:00:28 -0700 Subject: [PATCH 567/617] Add PTP clock module and testbench --- rtl/ptp_clock.v | 246 +++++++++++++++++++++++++++ tb/test_ptp_clock.py | 394 +++++++++++++++++++++++++++++++++++++++++++ tb/test_ptp_clock.v | 146 ++++++++++++++++ 3 files changed, 786 insertions(+) create mode 100644 rtl/ptp_clock.v create mode 100755 tb/test_ptp_clock.py create mode 100644 tb/test_ptp_clock.v diff --git a/rtl/ptp_clock.v b/rtl/ptp_clock.v new file mode 100644 index 000000000..f1f27d646 --- /dev/null +++ b/rtl/ptp_clock.v @@ -0,0 +1,246 @@ +/* + +Copyright (c) 2015-2019 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 + +/* + * PTP clock module + */ +module ptp_clock # +( + parameter PERIOD_NS_WIDTH = 4, + parameter OFFSET_NS_WIDTH = 4, + parameter DRIFT_NS_WIDTH = 4, + parameter FNS_WIDTH = 16, + parameter PERIOD_NS = 4'h6, + parameter PERIOD_FNS = 16'h6666, + parameter DRIFT_ENABLE = 1, + parameter DRIFT_NS = 4'h0, + parameter DRIFT_FNS = 16'h0002, + parameter DRIFT_RATE = 16'h0005 +) +( + input wire clk, + input wire rst, + + /* + * Timestamp inputs for synchronization + */ + input wire [95:0] input_ts_96, + input wire input_ts_96_valid, + input wire [63:0] input_ts_64, + input wire input_ts_64_valid, + + /* + * Period adjustment + */ + input wire [PERIOD_NS_WIDTH-1:0] input_period_ns, + input wire [FNS_WIDTH-1:0] input_period_fns, + input wire input_period_valid, + + /* + * Offset adjustment + */ + input wire [OFFSET_NS_WIDTH-1:0] input_adj_ns, + input wire [FNS_WIDTH-1:0] input_adj_fns, + input wire [15:0] input_adj_count, + input wire input_adj_valid, + output wire input_adj_active, + + /* + * Drift adjustment + */ + input wire [DRIFT_NS_WIDTH-1:0] input_drift_ns, + input wire [FNS_WIDTH-1:0] input_drift_fns, + input wire [15:0] input_drift_rate, + input wire input_drift_valid, + + /* + * Timestamp outputs + */ + output wire [95:0] output_ts_96, + output wire [63:0] output_ts_64, + output wire output_ts_step, + + /* + * PPS output + */ + output wire output_pps +); + +parameter INC_NS_WIDTH = $clog2(2**PERIOD_NS_WIDTH + 2**OFFSET_NS_WIDTH + 2**DRIFT_NS_WIDTH); + +reg [PERIOD_NS_WIDTH-1:0] period_ns_reg = PERIOD_NS; +reg [FNS_WIDTH-1:0] period_fns_reg = PERIOD_FNS; + +reg [OFFSET_NS_WIDTH-1:0] adj_ns_reg = 0; +reg [FNS_WIDTH-1:0] adj_fns_reg = 0; +reg [15:0] adj_count_reg = 0; +reg adj_active_reg = 0; + +reg [DRIFT_NS_WIDTH-1:0] drift_ns_reg = DRIFT_NS; +reg [FNS_WIDTH-1:0] drift_fns_reg = DRIFT_FNS; +reg [15:0] drift_rate_reg = DRIFT_RATE; + +reg [INC_NS_WIDTH-1:0] ts_inc_ns_reg = 0; +reg [FNS_WIDTH-1:0] ts_inc_fns_reg = 0; + +reg [47:0] ts_96_s_reg = 0; +reg [29:0] ts_96_ns_reg = 0; +reg [FNS_WIDTH-1:0] ts_96_fns_reg = 0; +reg [29:0] ts_96_ns_inc_reg = 0; +reg [FNS_WIDTH-1:0] ts_96_fns_inc_reg = 0; +reg [30:0] ts_96_ns_ovf_reg = 31'h7fffffff; +reg [FNS_WIDTH-1:0] ts_96_fns_ovf_reg = 16'hffff; + +reg [47:0] ts_64_ns_reg = 0; +reg [FNS_WIDTH-1:0] ts_64_fns_reg = 0; + +reg ts_step_reg = 1'b0; + +reg [15:0] drift_cnt = 0; + +reg [47:0] temp; + +reg pps_reg = 0; + +assign input_adj_active = adj_active_reg; + +assign output_ts_96[95:48] = ts_96_s_reg; +assign output_ts_96[47:46] = 2'b00; +assign output_ts_96[45:16] = ts_96_ns_reg; +assign output_ts_96[15:0] = FNS_WIDTH > 16 ? ts_96_fns_reg >> (FNS_WIDTH-16) : ts_96_fns_reg << (16-FNS_WIDTH); +assign output_ts_64[63:16] = ts_64_ns_reg; +assign output_ts_64[15:0] = FNS_WIDTH > 16 ? ts_64_fns_reg >> (FNS_WIDTH-16) : ts_64_fns_reg << (16-FNS_WIDTH); +assign output_ts_step = ts_step_reg; + +assign output_pps = pps_reg; + +always @(posedge clk) begin + ts_step_reg <= 0; + + // latch parameters + if (input_period_valid) begin + period_ns_reg <= input_period_ns; + period_fns_reg <= input_period_fns; + end + + if (input_adj_valid) begin + adj_ns_reg <= input_adj_ns; + adj_fns_reg <= input_adj_fns; + adj_count_reg <= input_adj_count; + end + + if (DRIFT_ENABLE && input_drift_valid) begin + drift_ns_reg <= input_drift_ns; + drift_fns_reg <= input_drift_fns; + drift_rate_reg <= input_drift_rate; + end + + // timestamp increment calculation + {ts_inc_ns_reg, ts_inc_fns_reg} <= $signed({period_ns_reg, period_fns_reg}) + + (adj_active_reg ? $signed({adj_ns_reg, adj_fns_reg}) : 0) + + ((DRIFT_ENABLE && drift_cnt == 0) ? $signed({drift_ns_reg, drift_fns_reg}) : 0); + + // offset adjust counter + if (adj_count_reg > 0) begin + adj_count_reg <= adj_count_reg - 1; + adj_active_reg <= 1; + ts_step_reg <= 1; + end else begin + adj_active_reg <= 0; + end + + // drift counter + if (drift_cnt == 0) begin + drift_cnt <= drift_rate_reg-1; + end else begin + drift_cnt <= drift_cnt - 1; + end + + // 96 bit timestamp + if (input_ts_96_valid) begin + // load timestamp + {ts_96_ns_inc_reg, ts_96_fns_inc_reg} <= (FNS_WIDTH > 16 ? input_ts_96[45:0] << (FNS_WIDTH-16) : input_ts_96[45:0] >> (16-FNS_WIDTH)) + {ts_inc_ns_reg, ts_inc_fns_reg}; + {ts_96_ns_ovf_reg, ts_96_fns_ovf_reg} <= (FNS_WIDTH > 16 ? input_ts_96[45:0] << (FNS_WIDTH-16) : input_ts_96[45:0] >> (16-FNS_WIDTH)) + {ts_inc_ns_reg, ts_inc_fns_reg} - {31'd1_000_000_000, {FNS_WIDTH{1'b0}}}; + ts_96_s_reg <= input_ts_96[95:48]; + ts_96_ns_reg <= input_ts_96[45:16]; + ts_96_fns_reg <= FNS_WIDTH > 16 ? input_ts_96[15:0] << (FNS_WIDTH-16) : input_ts_96[15:0] >> (16-FNS_WIDTH); + ts_step_reg <= 1; + end else if (!ts_96_ns_ovf_reg[30]) begin + // if the overflow lookahead did not borrow, one second has elapsed + // increment seconds field, pre-compute both normal increment and overflow values + {ts_96_ns_inc_reg, ts_96_fns_inc_reg} <= {ts_96_ns_ovf_reg, ts_96_fns_ovf_reg} + {ts_inc_ns_reg, ts_inc_fns_reg}; + {ts_96_ns_ovf_reg, ts_96_fns_ovf_reg} <= {ts_96_ns_ovf_reg, ts_96_fns_ovf_reg} + {ts_inc_ns_reg, ts_inc_fns_reg} - {31'd1_000_000_000, {FNS_WIDTH{1'b0}}}; + {ts_96_ns_reg, ts_96_fns_reg} <= {ts_96_ns_ovf_reg, ts_96_fns_ovf_reg}; + ts_96_s_reg <= ts_96_s_reg + 1; + end else begin + // no increment seconds field, pre-compute both normal increment and overflow values + {ts_96_ns_inc_reg, ts_96_fns_inc_reg} <= {ts_96_ns_inc_reg, ts_96_fns_inc_reg} + {ts_inc_ns_reg, ts_inc_fns_reg}; + {ts_96_ns_ovf_reg, ts_96_fns_ovf_reg} <= {ts_96_ns_inc_reg, ts_96_fns_inc_reg} + {ts_inc_ns_reg, ts_inc_fns_reg} - {31'd1_000_000_000, {FNS_WIDTH{1'b0}}}; + {ts_96_ns_reg, ts_96_fns_reg} <= {ts_96_ns_inc_reg, ts_96_fns_inc_reg}; + ts_96_s_reg <= ts_96_s_reg; + end + + // 64 bit timestamp + if (input_ts_64_valid) begin + // load timestamp + {ts_64_ns_reg, ts_64_fns_reg} <= input_ts_64; + ts_step_reg <= 1; + end else begin + {ts_64_ns_reg, ts_64_fns_reg} <= {ts_64_ns_reg, ts_64_fns_reg} + {ts_inc_ns_reg, ts_inc_fns_reg}; + end + + pps_reg <= !ts_96_ns_ovf_reg[30]; + + if (rst) begin + period_ns_reg <= PERIOD_NS; + period_fns_reg <= PERIOD_FNS; + adj_ns_reg <= 0; + adj_fns_reg <= 0; + adj_count_reg <= 0; + adj_active_reg <= 0; + drift_ns_reg <= DRIFT_NS; + drift_fns_reg <= DRIFT_FNS; + drift_rate_reg <= DRIFT_RATE; + ts_inc_ns_reg <= 0; + ts_inc_fns_reg <= 0; + ts_96_s_reg <= 0; + ts_96_ns_reg <= 0; + ts_96_fns_reg <= 0; + ts_96_ns_inc_reg <= 0; + ts_96_fns_inc_reg <= 0; + ts_96_ns_ovf_reg <= 31'h7fffffff; + ts_96_fns_ovf_reg <= {FNS_WIDTH{1'b1}}; + ts_64_ns_reg <= 0; + ts_64_fns_reg <= 0; + ts_step_reg <= 0; + drift_cnt <= 0; + pps_reg <= 0; + end +end + +endmodule diff --git a/tb/test_ptp_clock.py b/tb/test_ptp_clock.py new file mode 100755 index 000000000..462c58305 --- /dev/null +++ b/tb/test_ptp_clock.py @@ -0,0 +1,394 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2015-2019 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 + +module = 'ptp_clock' +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 bench(): + + # Parameters + PERIOD_NS_WIDTH = 4 + OFFSET_NS_WIDTH = 4 + DRIFT_NS_WIDTH = 4 + FNS_WIDTH = 16 + PERIOD_NS = 0x6 + PERIOD_FNS = 0x6666 + DRIFT_ENABLE = 1 + DRIFT_NS = 0x0 + DRIFT_FNS = 0x0002 + DRIFT_RATE = 0x0005 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_ts_96 = Signal(intbv(0)[96:]) + input_ts_96_valid = Signal(bool(0)) + input_ts_64 = Signal(intbv(0)[64:]) + input_ts_64_valid = Signal(bool(0)) + input_period_ns = Signal(intbv(0)[PERIOD_NS_WIDTH:]) + input_period_fns = Signal(intbv(0)[FNS_WIDTH:]) + input_period_valid = Signal(bool(0)) + input_adj_ns = Signal(intbv(0)[OFFSET_NS_WIDTH:]) + input_adj_fns = Signal(intbv(0)[FNS_WIDTH:]) + input_adj_count = Signal(intbv(0)[16:]) + input_adj_valid = Signal(bool(0)) + input_drift_ns = Signal(intbv(0)[DRIFT_NS_WIDTH:]) + input_drift_fns = Signal(intbv(0)[FNS_WIDTH:]) + input_drift_rate = Signal(intbv(0)[16:]) + input_drift_valid = Signal(bool(0)) + + # Outputs + input_adj_active = Signal(bool(0)) + output_ts_96 = Signal(intbv(0)[96:]) + output_ts_64 = Signal(intbv(0)[64:]) + output_ts_step = Signal(bool(0)) + output_pps = Signal(bool(0)) + + # 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, + + input_ts_96=input_ts_96, + input_ts_96_valid=input_ts_96_valid, + input_ts_64=input_ts_64, + input_ts_64_valid=input_ts_64_valid, + + input_period_ns=input_period_ns, + input_period_fns=input_period_fns, + input_period_valid=input_period_valid, + + input_adj_ns=input_adj_ns, + input_adj_fns=input_adj_fns, + input_adj_count=input_adj_count, + input_adj_valid=input_adj_valid, + input_adj_active=input_adj_active, + + input_drift_ns=input_drift_ns, + input_drift_fns=input_drift_fns, + input_drift_rate=input_drift_rate, + input_drift_valid=input_drift_valid, + + output_ts_96=output_ts_96, + output_ts_64=output_ts_64, + output_ts_step=output_ts_step, + + output_pps=output_pps + ) + + @always(delay(3200)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100000) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100000) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: Default rate and drift") + current_test.next = 1 + + yield clk.posedge + start_time = now()*1e-12 + start_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + start_ts_64 = output_ts_64/2**16*1e-9 + + for i in range(10000): + yield clk.posedge + + stop_time = now()*1e-12 + stop_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + stop_ts_64 = output_ts_64/2**16*1e-9 + + print(stop_time-start_time) + print(stop_ts_96-start_ts_96) + print(stop_ts_64-start_ts_64) + + assert abs((stop_time-start_time) - (stop_ts_96-start_ts_96)) < 1e-12 + assert abs((stop_time-start_time) - (stop_ts_64-start_ts_64)) < 1e-12 + + yield delay(100000) + + yield clk.posedge + print("test 2: Load timestamps") + current_test.next = 2 + + input_ts_96.next = 12345678 + input_ts_96_valid.next = 1 + input_ts_64.next = 87654321 + input_ts_64_valid.next = 1 + + yield clk.posedge + + input_ts_96_valid.next = 0 + input_ts_64_valid.next = 0 + + yield clk.posedge + + assert output_ts_96 == 12345678 + assert output_ts_64 == 87654321 + + start_time = now()*1e-12 + start_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + start_ts_64 = output_ts_64/2**16*1e-9 + + for i in range(2000): + yield clk.posedge + + stop_time = now()*1e-12 + stop_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + stop_ts_64 = output_ts_64/2**16*1e-9 + + print(stop_time-start_time) + print(stop_ts_96-start_ts_96) + print(stop_ts_64-start_ts_64) + + assert abs((stop_time-start_time) - (stop_ts_96-start_ts_96)) < 1e-12 + assert abs((stop_time-start_time) - (stop_ts_64-start_ts_64)) < 1e-12 + + yield delay(100000) + + yield clk.posedge + print("test 3: Seconds increment") + current_test.next = 3 + + input_ts_96.next = 999990000*2**16 + input_ts_96_valid.next = 1 + input_ts_64.next = 999990000*2**16 + input_ts_64_valid.next = 1 + + yield clk.posedge + + input_ts_96_valid.next = 0 + input_ts_64_valid.next = 0 + + yield clk.posedge + + assert output_ts_96 == 999990000*2**16 + assert output_ts_64 == 999990000*2**16 + + start_time = now()*1e-12 + start_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + start_ts_64 = output_ts_64/2**16*1e-9 + + for i in range(3000): + yield clk.posedge + + if output_pps: + assert output_ts_96[96:48] == 1 + assert output_ts_96[48:0] < 10*2**16 + + stop_time = now()*1e-12 + stop_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + stop_ts_64 = output_ts_64/2**16*1e-9 + + print(stop_time-start_time) + print(stop_ts_96-start_ts_96) + print(stop_ts_64-start_ts_64) + + assert abs((stop_time-start_time) - (stop_ts_96-start_ts_96)) < 1e-12 + assert abs((stop_time-start_time) - (stop_ts_64-start_ts_64)) < 1e-12 + + yield delay(100000) + + yield clk.posedge + print("test 4: Offset adjust") + current_test.next = 4 + + input_ts_96.next = 0 + input_ts_96_valid.next = 1 + input_ts_64.next = 0 + input_ts_64_valid.next = 1 + + yield clk.posedge + + input_ts_96_valid.next = 0 + input_ts_64_valid.next = 0 + + yield clk.posedge + + start_time = now()*1e-12 + start_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + start_ts_64 = output_ts_64/2**16*1e-9 + + for i in range(2000): + yield clk.posedge + + # 1 ns offset - 1024*64/65536 = 1 + input_adj_ns.next = 0 + input_adj_fns.next = 64 + input_adj_count.next = 1024 + input_adj_valid.next = 1 + + for i in range(2000): + yield clk.posedge + input_adj_valid.next = 0 + + stop_time = now()*1e-12 + stop_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + stop_ts_64 = output_ts_64/2**16*1e-9 + + print(stop_time-start_time) + print(stop_ts_96-start_ts_96) + print(stop_ts_64-start_ts_64) + + assert abs((stop_time-start_time) - (stop_ts_96-start_ts_96) + 1e-9) < 1e-12 + assert abs((stop_time-start_time) - (stop_ts_64-start_ts_64) + 1e-9) < 1e-12 + + yield delay(100000) + + yield clk.posedge + print("test 5: Frequency adjust") + current_test.next = 5 + + input_ts_96.next = 0 + input_ts_96_valid.next = 1 + input_ts_64.next = 0 + input_ts_64_valid.next = 1 + + input_period_ns.next = 6 + input_period_fns.next = 0x6624 + input_period_valid.next = 1 + + # flush old period out of pipeline registers + yield clk.posedge + yield clk.posedge + yield clk.posedge + + input_ts_96_valid.next = 0 + input_ts_64_valid.next = 0 + input_period_valid.next = 0 + + yield clk.posedge + + start_time = now()*1e-12 + start_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + start_ts_64 = output_ts_64/2**16*1e-9 + + for i in range(10000): + yield clk.posedge + + stop_time = now()*1e-12 + stop_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + stop_ts_64 = output_ts_64/2**16*1e-9 + + print(stop_time-start_time) + print(stop_ts_96-start_ts_96) + print(stop_ts_64-start_ts_64) + + assert abs((stop_time-start_time) - (stop_ts_96-start_ts_96) * 6.4/(6+(0x6624+2/5)/2**16)) < 1e-12 + assert abs((stop_time-start_time) - (stop_ts_64-start_ts_64) * 6.4/(6+(0x6624+2/5)/2**16)) < 1e-12 + + yield delay(100000) + + yield clk.posedge + print("test 6: Drift adjust") + current_test.next = 6 + + input_ts_96.next = 0 + input_ts_96_valid.next = 1 + input_ts_64.next = 0 + input_ts_64_valid.next = 1 + + input_period_ns.next = 6 + input_period_fns.next = 0x6666 + input_period_valid.next = 1 + + input_drift_ns.next = 0 + input_drift_fns.next = 20 + input_drift_rate.next = 5 + input_drift_valid.next = 1 + + # flush old period out of pipeline registers + yield clk.posedge + yield clk.posedge + yield clk.posedge + + input_ts_96_valid.next = 0 + input_ts_64_valid.next = 0 + input_period_valid.next = 0 + input_drift_valid.next = 0 + + yield clk.posedge + + start_time = now()*1e-12 + start_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + start_ts_64 = output_ts_64/2**16*1e-9 + + for i in range(10000): + yield clk.posedge + + stop_time = now()*1e-12 + stop_ts_96 = output_ts_96[96:48] + (output_ts_96[48:0]/2**16*1e-9) + stop_ts_64 = output_ts_64/2**16*1e-9 + + print(stop_time-start_time) + print(stop_ts_96-start_ts_96) + print(stop_ts_64-start_ts_64) + + assert abs((stop_time-start_time) - (stop_ts_96-start_ts_96) * 6.4/(6+(0x6666+20/5)/2**16)) < 1e-12 + assert abs((stop_time-start_time) - (stop_ts_64-start_ts_64) * 6.4/(6+(0x6666+20/5)/2**16)) < 1e-12 + + yield delay(100000) + + raise StopSimulation + + return dut, clkgen, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_ptp_clock.v b/tb/test_ptp_clock.v new file mode 100644 index 000000000..a95da483d --- /dev/null +++ b/tb/test_ptp_clock.v @@ -0,0 +1,146 @@ +/* + +Copyright (c) 2015-2019 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 1ps / 1fs + +/* + * Testbench for ptp_clock + */ +module test_ptp_clock; + +// Parameters +parameter PERIOD_NS_WIDTH = 4; +parameter OFFSET_NS_WIDTH = 4; +parameter DRIFT_NS_WIDTH = 4; +parameter FNS_WIDTH = 16; +parameter PERIOD_NS = 4'h6; +parameter PERIOD_FNS = 16'h6666; +parameter DRIFT_ENABLE = 1; +parameter DRIFT_NS = 4'h0; +parameter DRIFT_FNS = 16'h0002; +parameter DRIFT_RATE = 16'h0005; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [95:0] input_ts_96 = 0; +reg input_ts_96_valid = 0; +reg [63:0] input_ts_64 = 0; +reg input_ts_64_valid = 0; +reg [PERIOD_NS_WIDTH-1:0] input_period_ns = 0; +reg [FNS_WIDTH-1:0] input_period_fns = 0; +reg input_period_valid = 0; +reg [OFFSET_NS_WIDTH-1:0] input_adj_ns = 0; +reg [FNS_WIDTH-1:0] input_adj_fns = 0; +reg [15:0] input_adj_count = 0; +reg input_adj_valid = 0; +reg [DRIFT_NS_WIDTH-1:0] input_drift_ns = 0; +reg [FNS_WIDTH-1:0] input_drift_fns = 0; +reg [15:0] input_drift_rate = 0; +reg input_drift_valid = 0; + +// Outputs +wire input_adj_active; +wire [95:0] output_ts_96; +wire [63:0] output_ts_64; +wire output_ts_step; +wire output_pps; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + input_ts_96, + input_ts_96_valid, + input_ts_64, + input_ts_64_valid, + input_period_ns, + input_period_fns, + input_period_valid, + input_adj_ns, + input_adj_fns, + input_adj_count, + input_adj_valid, + input_drift_ns, + input_drift_fns, + input_drift_rate, + input_drift_valid + ); + $to_myhdl( + input_adj_active, + output_ts_96, + output_ts_64, + output_ts_step, + output_pps + ); + + // dump file + $dumpfile("test_ptp_clock.lxt"); + $dumpvars(0, test_ptp_clock); +end + +ptp_clock #( + .PERIOD_NS_WIDTH(PERIOD_NS_WIDTH), + .OFFSET_NS_WIDTH(OFFSET_NS_WIDTH), + .DRIFT_NS_WIDTH (DRIFT_NS_WIDTH), + .FNS_WIDTH(FNS_WIDTH), + .PERIOD_NS(PERIOD_NS), + .PERIOD_FNS(PERIOD_FNS), + .DRIFT_ENABLE(DRIFT_ENABLE), + .DRIFT_NS(DRIFT_NS), + .DRIFT_FNS(DRIFT_FNS), + .DRIFT_RATE(DRIFT_RATE) +) +UUT ( + .clk(clk), + .rst(rst), + .input_ts_96(input_ts_96), + .input_ts_96_valid(input_ts_96_valid), + .input_ts_64(input_ts_64), + .input_ts_64_valid(input_ts_64_valid), + .input_period_ns(input_period_ns), + .input_period_fns(input_period_fns), + .input_period_valid(input_period_valid), + .input_adj_ns(input_adj_ns), + .input_adj_fns(input_adj_fns), + .input_adj_count(input_adj_count), + .input_adj_valid(input_adj_valid), + .input_adj_active(input_adj_active), + .input_drift_ns(input_drift_ns), + .input_drift_fns(input_drift_fns), + .input_drift_rate(input_drift_rate), + .input_drift_valid(input_drift_valid), + .output_ts_96(output_ts_96), + .output_ts_64(output_ts_64), + .output_ts_step(output_ts_step), + .output_pps(output_pps) +); + +endmodule From 2efcfdb0a08f3a942c071d553c63e3eeb2f1f1b6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 3 Jun 2019 19:08:16 -0700 Subject: [PATCH 568/617] Add PTP clock simulation model --- tb/ptp.py | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 tb/ptp.py diff --git a/tb/ptp.py b/tb/ptp.py new file mode 100644 index 000000000..5379e789e --- /dev/null +++ b/tb/ptp.py @@ -0,0 +1,127 @@ +""" + +Copyright (c) 2015-2019 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 * + +class PtpClock(object): + def __init__(self): + self.period_ns = 0x6 + self.period_fns = 0x6666 + self.drift_ns = 0x0 + self.drift_fns = 0x0002 + self.drift_rate = 5 + + self.set_96_l = [] + self.set_64_l = [] + + def set_96(self, ts): + self.set_96_l.append(ts) + + def set_64(self, ts): + self.set_64_l.append(ts) + + def create_logic(self, + clk, + rst, + ts_96=Signal(intbv(0)[96:]), + ts_64=Signal(intbv(0)[64:]), + ts_step=Signal(bool(0)) + ): + + @instance + def logic(): + + ts_96_s = 0 + ts_96_ns = 0 + ts_96_fns = 0 + + ts_64_ns = 0 + ts_64_fns = 0 + + drift_cnt = 0 + + while True: + yield clk.posedge, rst.posedge + + if rst: + ts_96_s = 0 + ts_96_ns = 0 + ts_96_fns = 0 + ts_64_ns = 0 + ts_64_fns = 0 + drift_cnt = 0 + ts_96.next = 0 + ts_64.next = 0 + else: + ts_step.next = 0 + + t = ((ts_96_ns << 16) + ts_96_fns) + ((self.period_ns << 16) + self.period_fns) + + if drift_cnt > 0: + t += (self.drift_ns << 16) + self.drift_fns + ts_step.next = 1 + + if t > (1000000000<<16): + ts_96_s += 1 + t -= (1000000000<<16) + + ts_96_fns = t & 0xffff + ts_96_ns = t >> 16 + + if self.set_96_l: + ts = self.set_96_l.pop(0) + + ts_96_s = ts >> 48 + ts_96_ns = (ts >> 16) & 0x3fffffff + ts_96_fns = ts & 0xffff + + ts_step.next = 1 + + ts_96.next = (ts_96_s << 48) | (ts_96_ns << 16) | (ts_96_fns) + + t = ((ts_64_ns << 16) + ts_64_fns) + ((self.period_ns << 16) + self.period_fns) + + if drift_cnt > 0: + t += ((self.drift_ns << 16) + self.drift_fns) + ts_step.next = 1 + + ts_64_fns = t & 0xffff + ts_64_ns = t >> 16 + + if self.set_64_l: + ts = self.set_64_l.pop(0) + + ts_64_ns = ts >> 16 + ts_64_fns = ts & 0xffff + + ts_step.next = 1 + + ts_64.next = (ts_64_ns << 16) | ts_64_fns + + if drift_cnt > 0: + drift_cnt -= 1 + else: + drift_cnt = self.drift_rate-1 + + return instances() From 659aa6748179959f832c18399f49336c61d0ea0d Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 6 Jun 2019 17:13:14 -0700 Subject: [PATCH 569/617] Pack start packet strobes into the same signal --- rtl/axis_baser_rx_64.v | 19 +++++++------------ rtl/axis_baser_tx_64.v | 22 ++++++++-------------- rtl/axis_xgmii_rx_64.v | 19 +++++++------------ rtl/axis_xgmii_tx_64.v | 22 ++++++++-------------- rtl/eth_mac_10g.v | 20 ++++++++------------ rtl/eth_mac_phy_10g.v | 12 ++++-------- rtl/eth_mac_phy_10g_rx.v | 6 ++---- rtl/eth_mac_phy_10g_tx.v | 6 ++---- tb/test_axis_baser_rx_64.py | 6 ++---- tb/test_axis_baser_rx_64.v | 9 +++------ tb/test_axis_baser_tx_64.py | 6 ++---- tb/test_axis_baser_tx_64.v | 9 +++------ tb/test_axis_xgmii_rx_64.py | 6 ++---- tb/test_axis_xgmii_rx_64.v | 9 +++------ tb/test_axis_xgmii_tx_64.py | 6 ++---- tb/test_axis_xgmii_tx_64.v | 9 +++------ tb/test_eth_mac_10g_32.py | 12 ++++-------- tb/test_eth_mac_10g_32.v | 18 ++++++------------ tb/test_eth_mac_10g_64.py | 12 ++++-------- tb/test_eth_mac_10g_64.v | 18 ++++++------------ tb/test_eth_mac_phy_10g.py | 12 ++++-------- tb/test_eth_mac_phy_10g.v | 18 ++++++------------ 22 files changed, 96 insertions(+), 180 deletions(-) diff --git a/rtl/axis_baser_rx_64.v b/rtl/axis_baser_rx_64.v index 89bd629f2..6916911b6 100644 --- a/rtl/axis_baser_rx_64.v +++ b/rtl/axis_baser_rx_64.v @@ -57,8 +57,7 @@ module axis_baser_rx_64 # /* * Status */ - output wire start_packet_0, - output wire start_packet_4, + output wire [1:0] start_packet, output wire error_bad_frame, output wire error_bad_fcs, output wire rx_bad_block @@ -173,8 +172,7 @@ reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; -reg start_packet_0_reg = 1'b0; -reg start_packet_4_reg = 1'b0; +reg [1:0] start_packet_reg = 2'b00; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg rx_bad_block_reg = 1'b0; @@ -202,8 +200,7 @@ assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; assign m_axis_tuser = m_axis_tuser_reg; -assign start_packet_0 = start_packet_0_reg; -assign start_packet_4 = start_packet_4_reg; +assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; assign rx_bad_block = rx_bad_block_reg; @@ -406,8 +403,7 @@ always @(posedge clk) begin m_axis_tvalid_reg <= 1'b0; - start_packet_0_reg <= 1'b0; - start_packet_4_reg <= 1'b0; + start_packet_reg <= 2'b00; error_bad_frame_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; rx_bad_block_reg <= 1'b0; @@ -428,8 +424,7 @@ always @(posedge clk) begin m_axis_tvalid_reg <= m_axis_tvalid_next; - start_packet_0_reg <= 1'b0; - start_packet_4_reg <= 1'b0; + start_packet_reg <= 2'b00; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; rx_bad_block_reg <= 1'b0; @@ -438,11 +433,11 @@ always @(posedge clk) begin if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin lanes_swapped <= 1'b0; - start_packet_0_reg <= 1'b1; + start_packet_reg <= 2'b01; input_type_d0 <= INPUT_TYPE_START_0; end else if (encoded_rx_hdr == SYNC_CTRL && (encoded_rx_data[7:0] == BLOCK_TYPE_START_4 || encoded_rx_data[7:0] == BLOCK_TYPE_OS_START)) begin lanes_swapped <= 1'b1; - start_packet_4_reg <= 1'b1; + start_packet_reg <= 2'b10; delay_type_valid <= 1'b1; if (delay_type_valid) begin input_type_d0 <= delay_type; diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v index cd11407a1..e7a62fa2b 100644 --- a/rtl/axis_baser_tx_64.v +++ b/rtl/axis_baser_tx_64.v @@ -66,8 +66,7 @@ module axis_baser_tx_64 # /* * Status */ - output wire start_packet_0, - output wire start_packet_4, + output wire [1:0] start_packet, output wire error_underflow ); @@ -210,8 +209,7 @@ reg [HDR_WIDTH-1:0] encoded_tx_hdr_reg = SYNC_CTRL; reg [DATA_WIDTH-1:0] output_data_reg = {DATA_WIDTH{1'b0}}, output_data_next; reg [3:0] output_type_reg = OUTPUT_TYPE_IDLE, output_type_next; -reg start_packet_0_reg = 1'b0, start_packet_0_next; -reg start_packet_4_reg = 1'b0, start_packet_4_next; +reg [1:0] start_packet_reg = 2'b00, start_packet_next; reg error_underflow_reg = 1'b0, error_underflow_next; assign s_axis_tready = s_axis_tready_reg; @@ -219,8 +217,7 @@ assign s_axis_tready = s_axis_tready_reg; assign encoded_tx_data = encoded_tx_data_reg; assign encoded_tx_hdr = encoded_tx_hdr_reg; -assign start_packet_0 = start_packet_0_reg; -assign start_packet_4 = start_packet_4_reg; +assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; lfsr #( @@ -475,8 +472,7 @@ always @* begin output_data_next = s_tdata_reg; output_type_next = OUTPUT_TYPE_IDLE; - start_packet_0_next = 1'b0; - start_packet_4_next = 1'b0; + start_packet_next = 2'b00; error_underflow_next = 1'b0; case (state_reg) @@ -497,11 +493,11 @@ always @* begin if (ifg_count_reg > 8'd0) begin // need to send more idles - swap lanes swap_lanes = 1'b1; - start_packet_4_next = 1'b1; + start_packet_next = 2'b10; end else begin // no more idles - unswap unswap_lanes = 1'b1; - start_packet_0_next = 1'b1; + start_packet_next = 2'b01; end output_data_next = {ETH_SFD, {7{ETH_PRE}}}; output_type_next = OUTPUT_TYPE_START_0; @@ -731,8 +727,7 @@ always @(posedge clk) begin output_data_reg <= {DATA_WIDTH{1'b0}}; output_type_reg <= OUTPUT_TYPE_IDLE; - start_packet_0_reg <= 1'b0; - start_packet_4_reg <= 1'b0; + start_packet_reg <= 2'b00; error_underflow_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; @@ -751,8 +746,7 @@ always @(posedge clk) begin s_axis_tready_reg <= s_axis_tready_next; - start_packet_0_reg <= start_packet_0_next; - start_packet_4_reg <= start_packet_4_next; + start_packet_reg <= start_packet_next; error_underflow_reg <= error_underflow_next; delay_type_valid <= 1'b0; diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index f91ac9b39..96e438998 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -52,8 +52,7 @@ module axis_xgmii_rx_64 /* * Status */ - output wire start_packet_0, - output wire start_packet_4, + output wire [1:0] start_packet, output wire error_bad_frame, output wire error_bad_fcs ); @@ -98,8 +97,7 @@ reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; -reg start_packet_0_reg = 1'b0; -reg start_packet_4_reg = 1'b0; +reg [1:0] start_packet_reg = 2'b00; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; @@ -126,8 +124,7 @@ assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; assign m_axis_tuser = m_axis_tuser_reg; -assign start_packet_0 = start_packet_0_reg; -assign start_packet_4 = start_packet_4_reg; +assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; @@ -425,8 +422,7 @@ always @(posedge clk) begin m_axis_tvalid_reg <= 1'b0; - start_packet_0_reg <= 1'b0; - start_packet_4_reg <= 1'b0; + start_packet_reg <= 2'b00; error_bad_frame_reg <= 1'b0; error_bad_fcs_reg <= 1'b0; @@ -443,18 +439,17 @@ always @(posedge clk) begin m_axis_tvalid_reg <= m_axis_tvalid_next; - start_packet_0_reg <= 1'b0; - start_packet_4_reg <= 1'b0; + start_packet_reg <= 2'b00; error_bad_frame_reg <= error_bad_frame_next; error_bad_fcs_reg <= error_bad_fcs_next; if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin lanes_swapped <= 1'b0; - start_packet_0_reg <= 1'b1; + start_packet_reg <= 2'b01; xgmii_rxc_d0 <= xgmii_rxc; end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin lanes_swapped <= 1'b1; - start_packet_4_reg <= 1'b1; + start_packet_reg <= 2'b10; xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; end else if (lanes_swapped) begin xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index 2d5816b1a..fd3001844 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -63,8 +63,7 @@ module axis_xgmii_tx_64 # /* * Status */ - output wire start_packet_0, - output wire start_packet_4, + output wire [1:0] start_packet, output wire error_underflow ); @@ -139,8 +138,7 @@ wire [31:0] crc_next7; reg [63:0] xgmii_txd_reg = {8{XGMII_IDLE}}, xgmii_txd_next; reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; -reg start_packet_0_reg = 1'b0, start_packet_0_next; -reg start_packet_4_reg = 1'b0, start_packet_4_next; +reg start_packet_reg = 2'b00, start_packet_next; reg error_underflow_reg = 1'b0, error_underflow_next; assign s_axis_tready = s_axis_tready_reg; @@ -148,8 +146,7 @@ assign s_axis_tready = s_axis_tready_reg; assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; -assign start_packet_0 = start_packet_0_reg; -assign start_packet_4 = start_packet_4_reg; +assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; lfsr #( @@ -405,8 +402,7 @@ always @* begin xgmii_txd_next = {8{XGMII_IDLE}}; xgmii_txc_next = 8'b11111111; - start_packet_0_next = 1'b0; - start_packet_4_next = 1'b0; + start_packet_next = 2'b00; error_underflow_next = 1'b0; case (state_reg) @@ -428,11 +424,11 @@ always @* begin if (ifg_count_reg > 8'd0) begin // need to send more idles - swap lanes swap_lanes = 1'b1; - start_packet_4_next = 1'b1; + start_packet_next = 2'b10; end else begin // no more idles - unswap unswap_lanes = 1'b1; - start_packet_0_next = 1'b1; + start_packet_next = 2'b01; end xgmii_txd_next = {ETH_SFD, {6{ETH_PRE}}, XGMII_START}; xgmii_txc_next = 8'b00000001; @@ -661,8 +657,7 @@ always @(posedge clk) begin xgmii_txd_reg <= {8{XGMII_IDLE}}; xgmii_txc_reg <= 8'b11111111; - start_packet_0_reg <= 1'b0; - start_packet_4_reg <= 1'b0; + start_packet_reg <= 2'b00; error_underflow_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; @@ -678,8 +673,7 @@ always @(posedge clk) begin s_axis_tready_reg <= s_axis_tready_next; - start_packet_0_reg <= start_packet_0_next; - start_packet_4_reg <= start_packet_4_next; + start_packet_reg <= start_packet_next; error_underflow_reg <= error_underflow_next; if (swap_lanes || (lanes_swapped && !unswap_lanes)) begin diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index 8d3099d8a..dceab9c73 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -74,11 +74,9 @@ module eth_mac_10g # /* * Status */ - output wire tx_start_packet_0, - output wire tx_start_packet_4, + output wire [1:0] tx_start_packet, output wire tx_error_underflow, - output wire rx_start_packet_0, - output wire rx_start_packet_4, + output wire [1:0] rx_start_packet, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, @@ -116,8 +114,7 @@ axis_xgmii_rx_inst ( .m_axis_tvalid(rx_axis_tvalid), .m_axis_tlast(rx_axis_tlast), .m_axis_tuser(rx_axis_tuser), - .start_packet_0(rx_start_packet_0), - .start_packet_4(rx_start_packet_4), + .start_packet(rx_start_packet), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); @@ -139,8 +136,7 @@ axis_xgmii_tx_inst ( .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), .ifg_delay(ifg_delay), - .start_packet_0(tx_start_packet_0), - .start_packet_4(tx_start_packet_4), + .start_packet(tx_start_packet), .error_underflow(tx_error_underflow) ); @@ -157,12 +153,12 @@ axis_xgmii_rx_inst ( .m_axis_tvalid(rx_axis_tvalid), .m_axis_tlast(rx_axis_tlast), .m_axis_tuser(rx_axis_tuser), - .start_packet(rx_start_packet_0), + .start_packet(rx_start_packet), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); -assign tx_start_packet_4 = 1'b0; +assign rx_start_packet[1] = 1'b0; axis_xgmii_tx_32 #( .ENABLE_PADDING(ENABLE_PADDING), @@ -181,10 +177,10 @@ axis_xgmii_tx_inst ( .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), .ifg_delay(ifg_delay), - .start_packet(tx_start_packet_0) + .start_packet(tx_start_packet) ); -assign rx_start_packet_4 = 1'b0; +assign tx_start_packet[1] = 1'b0; end diff --git a/rtl/eth_mac_phy_10g.v b/rtl/eth_mac_phy_10g.v index b859ad22c..d635f3254 100644 --- a/rtl/eth_mac_phy_10g.v +++ b/rtl/eth_mac_phy_10g.v @@ -81,11 +81,9 @@ module eth_mac_phy_10g # /* * Status */ - output wire tx_start_packet_0, - output wire tx_start_packet_4, + output wire [1:0] tx_start_packet, output wire tx_error_underflow, - output wire rx_start_packet_0, - output wire rx_start_packet_4, + output wire [1:0] rx_start_packet, output wire [6:0] rx_error_count, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, @@ -123,8 +121,7 @@ eth_mac_phy_10g_rx_inst ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), - .rx_start_packet_0(rx_start_packet_0), - .rx_start_packet_4(rx_start_packet_4), + .rx_start_packet(rx_start_packet), .rx_error_count(rx_error_count), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), @@ -157,8 +154,7 @@ eth_mac_phy_10g_tx_inst ( .s_axis_tuser(tx_axis_tuser), .serdes_tx_data(serdes_tx_data), .serdes_tx_hdr(serdes_tx_hdr), - .tx_start_packet_0(tx_start_packet_0), - .tx_start_packet_4(tx_start_packet_4), + .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), .ifg_delay(ifg_delay), .tx_prbs31_enable(tx_prbs31_enable) diff --git a/rtl/eth_mac_phy_10g_rx.v b/rtl/eth_mac_phy_10g_rx.v index 119fb6155..5c70391fd 100644 --- a/rtl/eth_mac_phy_10g_rx.v +++ b/rtl/eth_mac_phy_10g_rx.v @@ -64,8 +64,7 @@ module eth_mac_phy_10g_rx # /* * Status */ - output wire rx_start_packet_0, - output wire rx_start_packet_4, + output wire [1:0] rx_start_packet, output wire [6:0] rx_error_count, output wire rx_error_bad_frame, output wire rx_error_bad_fcs, @@ -139,8 +138,7 @@ axis_baser_rx_inst ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), - .start_packet_0(rx_start_packet_0), - .start_packet_4(rx_start_packet_4), + .start_packet(rx_start_packet), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs), .rx_bad_block(rx_bad_block) diff --git a/rtl/eth_mac_phy_10g_tx.v b/rtl/eth_mac_phy_10g_tx.v index 1399ae92c..9e795206f 100644 --- a/rtl/eth_mac_phy_10g_tx.v +++ b/rtl/eth_mac_phy_10g_tx.v @@ -65,8 +65,7 @@ module eth_mac_phy_10g_tx # /* * Status */ - output wire tx_start_packet_0, - output wire tx_start_packet_4, + output wire [1:0] tx_start_packet, output wire tx_error_underflow, /* @@ -116,8 +115,7 @@ axis_baser_tx_inst ( .s_axis_tuser(s_axis_tuser), .encoded_tx_data(encoded_tx_data), .encoded_tx_hdr(encoded_tx_hdr), - .start_packet_0(tx_start_packet_0), - .start_packet_4(tx_start_packet_4), + .start_packet(tx_start_packet), .error_underflow(tx_error_underflow), .ifg_delay(ifg_delay) ); diff --git a/tb/test_axis_baser_rx_64.py b/tb/test_axis_baser_rx_64.py index 053628b5f..f4313fc18 100755 --- a/tb/test_axis_baser_rx_64.py +++ b/tb/test_axis_baser_rx_64.py @@ -65,8 +65,7 @@ def bench(): m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) m_axis_tuser = Signal(bool(0)) - start_packet_0 = Signal(bool(0)) - start_packet_4 = Signal(bool(0)) + start_packet = Signal(intbv(0)[2:]) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) rx_bad_block = Signal(bool(0)) @@ -111,8 +110,7 @@ def bench(): m_axis_tvalid=m_axis_tvalid, m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, - start_packet_0=start_packet_0, - start_packet_4=start_packet_4, + start_packet=start_packet, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs, rx_bad_block=rx_bad_block diff --git a/tb/test_axis_baser_rx_64.v b/tb/test_axis_baser_rx_64.v index 202c217e2..cc0b669f8 100644 --- a/tb/test_axis_baser_rx_64.v +++ b/tb/test_axis_baser_rx_64.v @@ -50,8 +50,7 @@ wire [KEEP_WIDTH-1:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; wire m_axis_tuser; -wire start_packet_0; -wire start_packet_4; +wire [1:0] start_packet; wire error_bad_frame; wire error_bad_fcs; wire rx_bad_block; @@ -71,8 +70,7 @@ initial begin m_axis_tvalid, m_axis_tlast, m_axis_tuser, - start_packet_0, - start_packet_4, + start_packet, error_bad_frame, error_bad_fcs, rx_bad_block @@ -98,8 +96,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), - .start_packet_0(start_packet_0), - .start_packet_4(start_packet_4), + .start_packet(start_packet), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs), .rx_bad_block(rx_bad_block) diff --git a/tb/test_axis_baser_tx_64.py b/tb/test_axis_baser_tx_64.py index f1e7d762a..26afcefc5 100755 --- a/tb/test_axis_baser_tx_64.py +++ b/tb/test_axis_baser_tx_64.py @@ -69,8 +69,7 @@ def bench(): s_axis_tready = Signal(bool(0)) encoded_tx_data = Signal(intbv(0)[DATA_WIDTH:]) encoded_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) - start_packet_0 = Signal(bool(0)) - start_packet_4 = Signal(bool(0)) + start_packet = Signal(intbv(0)[2:]) error_underflow = Signal(bool(0)) # sources and sinks @@ -119,8 +118,7 @@ def bench(): encoded_tx_data=encoded_tx_data, encoded_tx_hdr=encoded_tx_hdr, ifg_delay=ifg_delay, - start_packet_0=start_packet_0, - start_packet_4=start_packet_4, + start_packet=start_packet, error_underflow=error_underflow ) diff --git a/tb/test_axis_baser_tx_64.v b/tb/test_axis_baser_tx_64.v index bd7477599..aa64db44a 100644 --- a/tb/test_axis_baser_tx_64.v +++ b/tb/test_axis_baser_tx_64.v @@ -55,8 +55,7 @@ reg [7:0] ifg_delay = 0; wire s_axis_tready; wire [DATA_WIDTH-1:0] encoded_tx_data; wire [HDR_WIDTH-1:0] encoded_tx_hdr; -wire start_packet_0; -wire start_packet_4; +wire [1:0] start_packet; wire error_underflow; initial begin @@ -76,8 +75,7 @@ initial begin s_axis_tready, encoded_tx_data, encoded_tx_hdr, - start_packet_0, - start_packet_4, + start_packet, error_underflow ); @@ -106,8 +104,7 @@ UUT ( .encoded_tx_data(encoded_tx_data), .encoded_tx_hdr(encoded_tx_hdr), .ifg_delay(ifg_delay), - .start_packet_0(start_packet_0), - .start_packet_4(start_packet_4), + .start_packet(start_packet), .error_underflow(error_underflow) ); diff --git a/tb/test_axis_xgmii_rx_64.py b/tb/test_axis_xgmii_rx_64.py index 16a7a2d7a..52bd854db 100755 --- a/tb/test_axis_xgmii_rx_64.py +++ b/tb/test_axis_xgmii_rx_64.py @@ -62,8 +62,7 @@ def bench(): m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) m_axis_tuser = Signal(bool(0)) - start_packet_0 = Signal(bool(0)) - start_packet_4 = Signal(bool(0)) + start_packet = Signal(intbv(0)[2:]) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -110,8 +109,7 @@ def bench(): m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, - start_packet_0=start_packet_0, - start_packet_4=start_packet_4, + start_packet=start_packet, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs ) diff --git a/tb/test_axis_xgmii_rx_64.v b/tb/test_axis_xgmii_rx_64.v index fdafb2431..cee56eb27 100644 --- a/tb/test_axis_xgmii_rx_64.v +++ b/tb/test_axis_xgmii_rx_64.v @@ -47,8 +47,7 @@ wire [7:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; wire m_axis_tuser; -wire start_packet_0; -wire start_packet_4; +wire [1:0] start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -67,8 +66,7 @@ initial begin m_axis_tvalid, m_axis_tlast, m_axis_tuser, - start_packet_0, - start_packet_4, + start_packet, error_bad_frame, error_bad_fcs ); @@ -89,8 +87,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), - .start_packet_0(start_packet_0), - .start_packet_4(start_packet_4), + .start_packet(start_packet), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs) ); diff --git a/tb/test_axis_xgmii_tx_64.py b/tb/test_axis_xgmii_tx_64.py index ce183cdc8..10d178544 100755 --- a/tb/test_axis_xgmii_tx_64.py +++ b/tb/test_axis_xgmii_tx_64.py @@ -65,8 +65,7 @@ def bench(): s_axis_tready = Signal(bool(0)) xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) xgmii_txc = Signal(intbv(0xff)[8:]) - start_packet_0 = Signal(bool(0)) - start_packet_4 = Signal(bool(0)) + start_packet = Signal(intbv(0)[2:]) error_underflow = Signal(bool(0)) # sources and sinks @@ -119,8 +118,7 @@ def bench(): ifg_delay=ifg_delay, - start_packet_0=start_packet_0, - start_packet_4=start_packet_4, + start_packet=start_packet, error_underflow=error_underflow ) diff --git a/tb/test_axis_xgmii_tx_64.v b/tb/test_axis_xgmii_tx_64.v index 26597295c..71ae92778 100644 --- a/tb/test_axis_xgmii_tx_64.v +++ b/tb/test_axis_xgmii_tx_64.v @@ -51,8 +51,7 @@ reg [7:0] ifg_delay = 0; wire s_axis_tready; wire [63:0] xgmii_txd; wire [7:0] xgmii_txc; -wire start_packet_0; -wire start_packet_4; +wire [1:0] start_packet; wire error_underflow; initial begin @@ -72,8 +71,7 @@ initial begin s_axis_tready, xgmii_txd, xgmii_txc, - start_packet_0, - start_packet_4, + start_packet, error_underflow ); @@ -98,8 +96,7 @@ UUT ( .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), .ifg_delay(ifg_delay), - .start_packet_0(start_packet_0), - .start_packet_4(start_packet_4), + .start_packet(start_packet), .error_underflow(error_underflow) ); diff --git a/tb/test_eth_mac_10g_32.py b/tb/test_eth_mac_10g_32.py index 1866379d0..43c5b9ba1 100755 --- a/tb/test_eth_mac_10g_32.py +++ b/tb/test_eth_mac_10g_32.py @@ -82,11 +82,9 @@ def bench(): rx_axis_tuser = Signal(bool(0)) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) - tx_start_packet_0 = Signal(bool(0)) - tx_start_packet_4 = Signal(bool(0)) + tx_start_packet = Signal(intbv(0)[2:]) tx_error_underflow = Signal(bool(0)) - rx_start_packet_0 = Signal(bool(0)) - rx_start_packet_4 = Signal(bool(0)) + rx_start_packet = Signal(intbv(0)[2:]) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) @@ -175,11 +173,9 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, - tx_start_packet_0=tx_start_packet_0, - tx_start_packet_4=tx_start_packet_4, + tx_start_packet=tx_start_packet, tx_error_underflow=tx_error_underflow, - rx_start_packet_0=rx_start_packet_0, - rx_start_packet_4=rx_start_packet_4, + rx_start_packet=rx_start_packet, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, diff --git a/tb/test_eth_mac_10g_32.v b/tb/test_eth_mac_10g_32.v index 608dc0243..e4efdf3e8 100644 --- a/tb/test_eth_mac_10g_32.v +++ b/tb/test_eth_mac_10g_32.v @@ -66,11 +66,9 @@ wire rx_axis_tlast; wire rx_axis_tuser; wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; -wire tx_start_packet_0; -wire tx_start_packet_4; +wire [1:0] tx_start_packet; wire tx_error_underflow; -wire rx_start_packet_0; -wire rx_start_packet_4; +wire [1:0] rx_start_packet; wire rx_error_bad_frame; wire rx_error_bad_fcs; @@ -102,11 +100,9 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, - tx_start_packet_0, - tx_start_packet_4, + tx_start_packet, tx_error_underflow, - rx_start_packet_0, - rx_start_packet_4, + rx_start_packet, rx_error_bad_frame, rx_error_bad_fcs ); @@ -144,11 +140,9 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), - .tx_start_packet_0(tx_start_packet_0), - .tx_start_packet_4(tx_start_packet_4), + .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), - .rx_start_packet_0(rx_start_packet_0), - .rx_start_packet_4(rx_start_packet_4), + .rx_start_packet(rx_start_packet), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .ifg_delay(ifg_delay) diff --git a/tb/test_eth_mac_10g_64.py b/tb/test_eth_mac_10g_64.py index aa0a731b4..ccbc7bed4 100755 --- a/tb/test_eth_mac_10g_64.py +++ b/tb/test_eth_mac_10g_64.py @@ -82,11 +82,9 @@ def bench(): rx_axis_tuser = Signal(bool(0)) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) - tx_start_packet_0 = Signal(bool(0)) - tx_start_packet_4 = Signal(bool(0)) + tx_start_packet = Signal(intbv(0)[2:]) tx_error_underflow = Signal(bool(0)) - rx_start_packet_0 = Signal(bool(0)) - rx_start_packet_4 = Signal(bool(0)) + rx_start_packet = Signal(intbv(0)[2:]) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) @@ -175,11 +173,9 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, - tx_start_packet_0=tx_start_packet_0, - tx_start_packet_4=tx_start_packet_4, + tx_start_packet=tx_start_packet, tx_error_underflow=tx_error_underflow, - rx_start_packet_0=rx_start_packet_0, - rx_start_packet_4=rx_start_packet_4, + rx_start_packet=rx_start_packet, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, diff --git a/tb/test_eth_mac_10g_64.v b/tb/test_eth_mac_10g_64.v index 50a164f5d..10ef31f8a 100644 --- a/tb/test_eth_mac_10g_64.v +++ b/tb/test_eth_mac_10g_64.v @@ -66,11 +66,9 @@ wire rx_axis_tlast; wire rx_axis_tuser; wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; -wire tx_start_packet_0; -wire tx_start_packet_4; +wire [1:0] tx_start_packet; wire tx_error_underflow; -wire rx_start_packet_0; -wire rx_start_packet_4; +wire [1:0] rx_start_packet; wire rx_error_bad_frame; wire rx_error_bad_fcs; @@ -102,11 +100,9 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, - tx_start_packet_0, - tx_start_packet_4, + tx_start_packet, tx_error_underflow, - rx_start_packet_0, - rx_start_packet_4, + rx_start_packet, rx_error_bad_frame, rx_error_bad_fcs ); @@ -144,11 +140,9 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), - .tx_start_packet_0(tx_start_packet_0), - .tx_start_packet_4(tx_start_packet_4), + .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), - .rx_start_packet_0(rx_start_packet_0), - .rx_start_packet_4(rx_start_packet_4), + .rx_start_packet(rx_start_packet), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), .ifg_delay(ifg_delay) diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py index 23468c8a0..e5156b0c9 100755 --- a/tb/test_eth_mac_phy_10g.py +++ b/tb/test_eth_mac_phy_10g.py @@ -101,11 +101,9 @@ def bench(): serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) serdes_rx_bitslip = Signal(bool(0)) - tx_start_packet_0 = Signal(bool(0)) - tx_start_packet_4 = Signal(bool(0)) + tx_start_packet = Signal(intbv(0)[2:]) tx_error_underflow = Signal(bool(0)) - rx_start_packet_0 = Signal(bool(0)) - rx_start_packet_4 = Signal(bool(0)) + rx_start_packet = Signal(intbv(0)[2:]) rx_error_count = Signal(intbv(0)[7:]) rx_error_bad_frame = Signal(bool(0)) rx_error_bad_fcs = Signal(bool(0)) @@ -191,11 +189,9 @@ def bench(): serdes_rx_data=serdes_rx_data, serdes_rx_hdr=serdes_rx_hdr, serdes_rx_bitslip=serdes_rx_bitslip, - tx_start_packet_0=tx_start_packet_0, - tx_start_packet_4=tx_start_packet_4, + tx_start_packet=tx_start_packet, tx_error_underflow=tx_error_underflow, - rx_start_packet_0=rx_start_packet_0, - rx_start_packet_4=rx_start_packet_4, + rx_start_packet=rx_start_packet, rx_error_count=rx_error_count, rx_error_bad_frame=rx_error_bad_frame, rx_error_bad_fcs=rx_error_bad_fcs, diff --git a/tb/test_eth_mac_phy_10g.v b/tb/test_eth_mac_phy_10g.v index cbc06970c..77f85468d 100644 --- a/tb/test_eth_mac_phy_10g.v +++ b/tb/test_eth_mac_phy_10g.v @@ -75,11 +75,9 @@ wire rx_axis_tuser; wire [DATA_WIDTH-1:0] serdes_tx_data; wire [HDR_WIDTH-1:0] serdes_tx_hdr; wire serdes_rx_bitslip; -wire tx_start_packet_0; -wire tx_start_packet_4; +wire [1:0] tx_start_packet; wire tx_error_underflow; -wire rx_start_packet_0; -wire rx_start_packet_4; +wire [1:0] rx_start_packet; wire [6:0] rx_error_count; wire rx_error_bad_frame; wire rx_error_bad_fcs; @@ -118,12 +116,10 @@ initial begin serdes_tx_data, serdes_tx_hdr, serdes_rx_bitslip, - tx_start_packet_0, - tx_start_packet_4, + tx_start_packet, tx_error_underflow, rx_error_count, - rx_start_packet_0, - rx_start_packet_4, + rx_start_packet, rx_error_bad_frame, rx_error_bad_fcs, rx_bad_block, @@ -171,11 +167,9 @@ UUT ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), - .tx_start_packet_0(tx_start_packet_0), - .tx_start_packet_4(tx_start_packet_4), + .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), - .rx_start_packet_0(rx_start_packet_0), - .rx_start_packet_4(rx_start_packet_4), + .rx_start_packet(rx_start_packet), .rx_error_count(rx_error_count), .rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_fcs(rx_error_bad_fcs), From 82fe5a6bdda2b5c1b1a097b451369e788fd8d636 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 7 Jun 2019 16:38:36 -0700 Subject: [PATCH 570/617] Add PTP timestamp capture logic to MACs --- rtl/axis_baser_rx_64.v | 64 ++++++++++++---- rtl/axis_baser_tx_64.v | 93 ++++++++++++++++++---- rtl/axis_gmii_rx.v | 72 +++++++++++------ rtl/axis_gmii_tx.v | 80 ++++++++++++++----- rtl/axis_xgmii_rx_32.v | 87 ++++++++++++++------- rtl/axis_xgmii_rx_64.v | 106 ++++++++++++++++++------- rtl/axis_xgmii_tx_32.v | 121 ++++++++++++++++++++--------- rtl/axis_xgmii_tx_64.v | 149 +++++++++++++++++++++++++++--------- rtl/eth_mac_10g.v | 127 ++++++++++++++++++++++-------- rtl/eth_mac_1g.v | 98 ++++++++++++++++-------- rtl/eth_mac_phy_10g.v | 100 ++++++++++++++++-------- rtl/eth_mac_phy_10g_rx.v | 54 ++++++++----- rtl/eth_mac_phy_10g_tx.v | 56 ++++++++++---- tb/test_axis_baser_rx_64.py | 9 ++- tb/test_axis_baser_rx_64.v | 19 ++++- tb/test_axis_baser_tx_64.py | 17 +++- tb/test_axis_baser_tx_64.v | 30 +++++++- tb/test_axis_gmii_rx.py | 14 +++- tb/test_axis_gmii_rx.v | 21 +++-- tb/test_axis_gmii_tx.py | 21 ++++- tb/test_axis_gmii_tx.v | 32 +++++++- tb/test_axis_xgmii_rx_32.py | 22 ++++-- tb/test_axis_xgmii_rx_32.v | 32 ++++++-- tb/test_axis_xgmii_rx_64.py | 22 ++++-- tb/test_axis_xgmii_rx_64.v | 34 ++++++-- tb/test_axis_xgmii_tx_32.py | 30 ++++++-- tb/test_axis_xgmii_tx_32.v | 44 +++++++++-- tb/test_axis_xgmii_tx_64.py | 30 ++++++-- tb/test_axis_xgmii_tx_64.v | 46 +++++++++-- tb/test_eth_mac_10g_32.py | 23 +++++- tb/test_eth_mac_10g_32.v | 37 ++++++++- tb/test_eth_mac_10g_64.py | 25 +++++- tb/test_eth_mac_10g_64.v | 41 +++++++++- tb/test_eth_mac_1g.py | 32 ++++++-- tb/test_eth_mac_1g.v | 47 ++++++++++-- tb/test_eth_mac_phy_10g.py | 24 +++++- tb/test_eth_mac_phy_10g.v | 39 +++++++++- 37 files changed, 1471 insertions(+), 427 deletions(-) diff --git a/rtl/axis_baser_rx_64.v b/rtl/axis_baser_rx_64.v index 6916911b6..e37b8294c 100644 --- a/rtl/axis_baser_rx_64.v +++ b/rtl/axis_baser_rx_64.v @@ -33,34 +33,44 @@ module axis_baser_rx_64 # ( parameter DATA_WIDTH = 64, parameter KEEP_WIDTH = (DATA_WIDTH/8), - parameter HDR_WIDTH = 2 + parameter HDR_WIDTH = 2, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * 10GBASE-R encoded input */ - input wire [DATA_WIDTH-1:0] encoded_rx_data, - input wire [HDR_WIDTH-1:0] encoded_rx_hdr, + input wire [DATA_WIDTH-1:0] encoded_rx_data, + input wire [HDR_WIDTH-1:0] encoded_rx_hdr, /* * AXI output */ - output wire [DATA_WIDTH-1:0] m_axis_tdata, - output wire [KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, /* * Status */ - output wire [1:0] start_packet, - output wire error_bad_frame, - output wire error_bad_fcs, - output wire rx_bad_block + output wire [1:0] start_packet, + output wire error_bad_frame, + output wire error_bad_fcs, + output wire rx_bad_block ); // bus width assertions @@ -177,6 +187,8 @@ reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg rx_bad_block_reg = 1'b0; +reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0; + reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state3 = 32'hFFFFFFFF; @@ -198,7 +210,7 @@ assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tkeep = m_axis_tkeep_reg; assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = m_axis_tuser_reg; +assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg; assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; @@ -518,6 +530,28 @@ always @(posedge clk) begin end end + if (PTP_TS_WIDTH == 96 && $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin + // ns field rollover + ptp_ts_reg[45:16] <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000); + ptp_ts_reg[95:48] <= ptp_ts_reg[95:48] + 1; + end + + if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin + if (PTP_TS_WIDTH == 96) begin + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + ptp_ts_reg[95:48] <= ptp_ts[95:48]; + end else begin + ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + end + end else if (encoded_rx_hdr == SYNC_CTRL && (encoded_rx_data[7:0] == BLOCK_TYPE_START_4 || encoded_rx_data[7:0] == BLOCK_TYPE_OS_START)) begin + if (PTP_TS_WIDTH == 96) begin + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + ptp_ts_reg[95:48] <= ptp_ts[95:48]; + end else begin + ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + end + end + m_axis_tdata_reg <= m_axis_tdata_next; m_axis_tkeep_reg <= m_axis_tkeep_next; m_axis_tlast_reg <= m_axis_tlast_next; diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v index e7a62fa2b..4487053a2 100644 --- a/rtl/axis_baser_tx_64.v +++ b/rtl/axis_baser_tx_64.v @@ -36,38 +36,53 @@ module axis_baser_tx_64 # parameter HDR_WIDTH = 2, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( - input wire clk, - input wire rst, + 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, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * 10GBASE-R encoded interface */ - output wire [DATA_WIDTH-1:0] encoded_tx_data, - output wire [HDR_WIDTH-1:0] encoded_tx_hdr, + output wire [DATA_WIDTH-1:0] encoded_tx_data, + output wire [HDR_WIDTH-1:0] encoded_tx_hdr, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, /* * Configuration */ - input wire [7:0] ifg_delay, + input wire [7:0] ifg_delay, /* * Status */ - output wire [1:0] start_packet, - output wire error_underflow + output wire [1:0] start_packet, + output wire error_underflow ); // bus width assertions @@ -192,6 +207,11 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next; +reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next; +reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next; +reg m_axis_ptp_ts_valid_int_reg = 1'b0, m_axis_ptp_ts_valid_int_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next0; @@ -217,6 +237,10 @@ assign s_axis_tready = s_axis_tready_reg; assign encoded_tx_data = encoded_tx_data_reg; assign encoded_tx_hdr = encoded_tx_hdr_reg; +assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; +assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; + assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; @@ -469,12 +493,26 @@ always @* begin s_tdata_next = s_tdata_reg; s_tkeep_next = s_tkeep_reg; + m_axis_ptp_ts_next = m_axis_ptp_ts_reg; + m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg; + m_axis_ptp_ts_valid_next = 1'b0; + m_axis_ptp_ts_valid_int_next = 1'b0; + output_data_next = s_tdata_reg; output_type_next = OUTPUT_TYPE_IDLE; start_packet_next = 2'b00; error_underflow_next = 1'b0; + if (m_axis_ptp_ts_valid_int_reg) begin + m_axis_ptp_ts_valid_next = 1'b1; + if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin + // ns field rollover + m_axis_ptp_ts_next[45:16] <= $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000); + m_axis_ptp_ts_next[95:48] <= m_axis_ptp_ts_reg[95:48] + 1; + end + end + case (state_reg) STATE_IDLE: begin // idle state - wait for data @@ -493,10 +531,26 @@ always @* begin if (ifg_count_reg > 8'd0) begin // need to send more idles - swap lanes swap_lanes = 1'b1; + if (PTP_TS_WIDTH == 96) begin + m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + end else begin + m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + end + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_int_next = 1'b1; start_packet_next = 2'b10; end else begin // no more idles - unswap unswap_lanes = 1'b1; + if (PTP_TS_WIDTH == 96) begin + m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + end else begin + m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + end + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_int_next = 1'b1; start_packet_next = 2'b01; end output_data_next = {ETH_SFD, {7{ETH_PRE}}}; @@ -527,7 +581,7 @@ always @* begin if (s_axis_tlast) begin frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); s_axis_tready_next = 1'b0; - if (s_axis_tuser) begin + if (s_axis_tuser[0]) begin output_type_next = OUTPUT_TYPE_ERROR; frame_ptr_next = 16'd0; ifg_count_next = 8'd8; @@ -721,6 +775,9 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; + m_axis_ptp_ts_valid_reg <= 1'b0; + m_axis_ptp_ts_valid_int_reg <= 1'b0; + encoded_tx_data_reg <= {{8{CTRL_IDLE}}, BLOCK_TYPE_CTRL}; encoded_tx_hdr_reg <= SYNC_CTRL; @@ -745,6 +802,9 @@ always @(posedge clk) begin deficit_idle_count_reg <= deficit_idle_count_next; s_axis_tready_reg <= s_axis_tready_next; + + m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next; + m_axis_ptp_ts_valid_int_reg <= m_axis_ptp_ts_valid_int_next; start_packet_reg <= start_packet_next; error_underflow_reg <= error_underflow_next; @@ -845,6 +905,9 @@ always @(posedge clk) begin s_tdata_reg <= s_tdata_next; s_tkeep_reg <= s_tkeep_next; + m_axis_ptp_ts_reg <= m_axis_ptp_ts_next; + m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next; + swap_data <= output_data_next[63:32]; delay_type <= output_type_next ^ 4'd4; diff --git a/rtl/axis_gmii_rx.v b/rtl/axis_gmii_rx.v index c6a52f655..b09240162 100644 --- a/rtl/axis_gmii_rx.v +++ b/rtl/axis_gmii_rx.v @@ -29,40 +29,59 @@ THE SOFTWARE. /* * AXI4-Stream GMII frame receiver (GMII in, AXI out) */ -module axis_gmii_rx +module axis_gmii_rx # ( - input wire clk, - input wire rst, + parameter DATA_WIDTH = 8, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 +) +( + input wire clk, + input wire rst, /* * GMII input */ - input wire [7:0] gmii_rxd, - input wire gmii_rx_dv, - input wire gmii_rx_er, + input wire [DATA_WIDTH-1:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, /* * AXI output */ - output wire [7:0] m_axis_tdata, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, /* * Control */ - input wire clk_enable, - input wire mii_select, + input wire clk_enable, + input wire mii_select, /* * Status */ - output wire start_packet, - output wire error_bad_frame, - output wire error_bad_fcs + output wire start_packet, + output wire error_bad_frame, + output wire error_bad_fcs ); +// bus width assertions +initial begin + if (DATA_WIDTH != 8) begin + $error("Error: Interface width must be 8"); + $finish; + end +end + localparam [7:0] ETH_PRE = 8'h55, ETH_SFD = 8'hD5; @@ -81,11 +100,11 @@ reg update_crc; reg mii_odd = 1'b0; reg mii_locked = 1'b0; -reg [7:0] gmii_rxd_d0 = 8'd0; -reg [7:0] gmii_rxd_d1 = 8'd0; -reg [7:0] gmii_rxd_d2 = 8'd0; -reg [7:0] gmii_rxd_d3 = 8'd0; -reg [7:0] gmii_rxd_d4 = 8'd0; +reg [DATA_WIDTH-1:0] gmii_rxd_d0 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d1 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d2 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d3 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d4 = {DATA_WIDTH{1'b0}}; reg gmii_rx_dv_d0 = 1'b0; reg gmii_rx_dv_d1 = 1'b0; @@ -99,7 +118,7 @@ reg gmii_rx_er_d2 = 1'b0; reg gmii_rx_er_d3 = 1'b0; reg gmii_rx_er_d4 = 1'b0; -reg [7:0] m_axis_tdata_reg = 8'd0, m_axis_tdata_next; +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; @@ -108,13 +127,15 @@ reg start_packet_reg = 1'b0, start_packet_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; +reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0, ptp_ts_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next; assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = m_axis_tuser_reg; +assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg; assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; @@ -142,7 +163,7 @@ always @* begin reset_crc = 1'b0; update_crc = 1'b0; - m_axis_tdata_next = 8'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; m_axis_tvalid_next = 1'b0; m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; @@ -151,6 +172,8 @@ always @* begin error_bad_frame_next = 1'b0; error_bad_fcs_next = 1'b0; + ptp_ts_next = ptp_ts_reg; + if (!clk_enable) begin // clock disabled - hold state state_next = state_reg; @@ -164,6 +187,7 @@ always @* begin reset_crc = 1'b1; if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == ETH_SFD) begin + ptp_ts_next = ptp_ts; start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end else begin @@ -283,6 +307,8 @@ always @(posedge clk) begin end end + ptp_ts_reg <= ptp_ts_next; + m_axis_tdata_reg <= m_axis_tdata_next; m_axis_tlast_reg <= m_axis_tlast_next; m_axis_tuser_reg <= m_axis_tuser_next; diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index 0acdab337..e16ef2ed8 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -31,47 +31,69 @@ THE SOFTWARE. */ module axis_gmii_tx # ( + parameter DATA_WIDTH = 8, parameter ENABLE_PADDING = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI input */ - input wire [7:0] s_axis_tdata, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * GMII output */ - output wire [7:0] gmii_txd, - output wire gmii_tx_en, - output wire gmii_tx_er, + output wire [DATA_WIDTH-1:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, /* * Control */ - input wire clk_enable, - input wire mii_select, + input wire clk_enable, + input wire mii_select, /* * Configuration */ - input wire [7:0] ifg_delay, + input wire [7:0] ifg_delay, /* * Status */ - output wire start_packet, - output wire error_underflow + output wire start_packet, + output wire error_underflow ); +// bus width assertions +initial begin + if (DATA_WIDTH != 8) begin + $error("Error: Interface width must be 8"); + $finish; + end +end + localparam [7:0] ETH_PRE = 8'h55, ETH_SFD = 8'hD5; @@ -105,6 +127,10 @@ reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next; +reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next; +reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next; + reg start_packet_reg = 1'b0, start_packet_next; reg error_underflow_reg = 1'b0, error_underflow_next; @@ -117,6 +143,10 @@ assign gmii_txd = gmii_txd_reg; assign gmii_tx_en = gmii_tx_en_reg; assign gmii_tx_er = gmii_tx_er_reg; +assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; +assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; + assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; @@ -151,7 +181,11 @@ always @* begin s_tdata_next = s_tdata_reg; - gmii_txd_next = 8'd0; + m_axis_ptp_ts_next = m_axis_ptp_ts_reg; + m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg; + m_axis_ptp_ts_valid_next = 1'b0; + + gmii_txd_next = {DATA_WIDTH{1'b0}}; gmii_tx_en_next = 1'b0; gmii_tx_er_next = 1'b0; @@ -210,6 +244,9 @@ always @* begin s_tdata_next = s_axis_tdata; end gmii_txd_next = ETH_SFD; + m_axis_ptp_ts_next = ptp_ts; + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_next = 1'b1; start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end else begin @@ -233,7 +270,7 @@ always @* begin if (s_axis_tvalid) begin if (s_axis_tlast) begin s_axis_tready_next = !s_axis_tready_reg; - if (s_axis_tuser) begin + if (s_axis_tuser[0]) begin gmii_tx_er_next = 1'b1; frame_ptr_next = 1'b0; state_next = STATE_IFG; @@ -365,6 +402,8 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; + m_axis_ptp_ts_valid_reg <= 1'b0; + gmii_tx_en_reg <= 1'b0; gmii_tx_er_reg <= 1'b0; @@ -378,6 +417,8 @@ always @(posedge clk) begin frame_ptr_reg <= frame_ptr_next; s_axis_tready_reg <= s_axis_tready_next; + + m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next; gmii_tx_en_reg <= gmii_tx_en_next; gmii_tx_er_reg <= gmii_tx_er_next; @@ -393,6 +434,9 @@ always @(posedge clk) begin end end + m_axis_ptp_ts_reg <= m_axis_ptp_ts_next; + m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next; + mii_odd_reg <= mii_odd_next; mii_msn_reg <= mii_msn_next; diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index 5710b7d26..65fafe901 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -29,34 +29,60 @@ THE SOFTWARE. /* * AXI4-Stream XGMII frame receiver (XGMII in, AXI out) */ -module axis_xgmii_rx_32 +module axis_xgmii_rx_32 # ( - input wire clk, - input wire rst, + parameter DATA_WIDTH = 32, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 +) +( + input wire clk, + input wire rst, /* * XGMII input */ - input wire [31:0] xgmii_rxd, - input wire [3:0] xgmii_rxc, + input wire [DATA_WIDTH-1:0] xgmii_rxd, + input wire [CTRL_WIDTH-1:0] xgmii_rxc, /* * AXI output */ - output wire [31:0] m_axis_tdata, - output wire [3:0] m_axis_tkeep, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, /* * Status */ - output wire start_packet, - output wire error_bad_frame, - output wire error_bad_fcs + output wire start_packet, + output wire error_bad_frame, + output wire error_bad_fcs ); +// bus width assertions +initial begin + if (DATA_WIDTH != 32) begin + $error("Error: Interface width must be 32"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end +end + localparam [7:0] ETH_PRE = 8'h55, ETH_SFD = 8'hD5; @@ -81,16 +107,16 @@ reg update_crc; reg [3:0] last_cycle_tkeep_reg = 4'd0, last_cycle_tkeep_next; -reg [31:0] xgmii_rxd_d0 = 32'd0; -reg [31:0] xgmii_rxd_d1 = 32'd0; -reg [31:0] xgmii_rxd_d2 = 32'd0; +reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] xgmii_rxd_d2 = {DATA_WIDTH{1'b0}}; -reg [3:0] xgmii_rxc_d0 = 4'd0; -reg [3:0] xgmii_rxc_d1 = 4'd0; -reg [3:0] xgmii_rxc_d2 = 4'd0; +reg [CTRL_WIDTH-1:0] xgmii_rxc_d0 = {CTRL_WIDTH{1'b0}}; +reg [CTRL_WIDTH-1:0] xgmii_rxc_d1 = {CTRL_WIDTH{1'b0}}; +reg [CTRL_WIDTH-1:0] xgmii_rxc_d2 = {CTRL_WIDTH{1'b0}}; -reg [31:0] m_axis_tdata_reg = 32'd0, m_axis_tdata_next; -reg [3:0] m_axis_tkeep_reg = 4'd0, m_axis_tkeep_next; +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, m_axis_tkeep_next; reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; @@ -99,6 +125,8 @@ reg start_packet_reg = 1'b0, start_packet_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; +reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0, ptp_ts_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next0; @@ -120,7 +148,7 @@ assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tkeep = m_axis_tkeep_reg; assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = m_axis_tuser_reg; +assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg; assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; @@ -257,8 +285,8 @@ always @* begin last_cycle_tkeep_next = last_cycle_tkeep_reg; - m_axis_tdata_next = 32'd0; - m_axis_tkeep_next = 4'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; + m_axis_tkeep_next = {KEEP_WIDTH{1'b0}}; m_axis_tvalid_next = 1'b0; m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; @@ -267,6 +295,8 @@ always @* begin error_bad_frame_next = 1'b0; error_bad_fcs_next = 1'b0; + ptp_ts_next = ptp_ts_reg; + case (state_reg) STATE_IDLE: begin // idle state - wait for packet @@ -276,7 +306,7 @@ always @* begin // start condition if (control_masked) begin // control or error characters in first data word - m_axis_tdata_next = 32'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; m_axis_tkeep_next = 4'h1; m_axis_tvalid_next = 1'b1; m_axis_tlast_next = 1'b1; @@ -295,6 +325,7 @@ always @* begin STATE_PREAMBLE: begin // drop preamble update_crc = 1'b1; + ptp_ts_next = ptp_ts; start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end @@ -379,8 +410,8 @@ always @(posedge clk) begin crc_valid2_save <= 1'b0; crc_valid3_save <= 1'b0; - xgmii_rxc_d0 <= 4'd0; - xgmii_rxc_d1 <= 4'd0; + xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}}; + xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}}; end else begin state_reg <= state_next; @@ -415,6 +446,8 @@ always @(posedge clk) begin m_axis_tlast_reg <= m_axis_tlast_next; m_axis_tuser_reg <= m_axis_tuser_next; + ptp_ts_reg <= ptp_ts_next; + last_cycle_tkeep_reg <= last_cycle_tkeep_next; detect_term_save <= detect_term; diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index 96e438998..45838e0ee 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -29,34 +29,62 @@ THE SOFTWARE. /* * AXI4-Stream XGMII frame receiver (XGMII in, AXI out) */ -module axis_xgmii_rx_64 +module axis_xgmii_rx_64 # ( - input wire clk, - input wire rst, + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 +) +( + input wire clk, + input wire rst, /* * XGMII input */ - input wire [63:0] xgmii_rxd, - input wire [7:0] xgmii_rxc, + input wire [DATA_WIDTH-1:0] xgmii_rxd, + input wire [CTRL_WIDTH-1:0] xgmii_rxc, /* * AXI output */ - output wire [63:0] m_axis_tdata, - output wire [7:0] m_axis_tkeep, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, /* * Status */ - output wire [1:0] start_packet, - output wire error_bad_frame, - output wire error_bad_fcs + output wire [1:0] start_packet, + output wire error_bad_frame, + output wire error_bad_fcs ); +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end +end + localparam [7:0] ETH_PRE = 8'h55, ETH_SFD = 8'hD5; @@ -84,15 +112,15 @@ reg lanes_swapped = 1'b0; reg [31:0] swap_rxd = 32'd0; reg [3:0] swap_rxc = 4'd0; -reg [63:0] xgmii_rxd_d0 = 32'd0; -reg [63:0] xgmii_rxd_d1 = 32'd0; -reg [63:0] xgmii_rxd_crc = 32'd0; +reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] xgmii_rxd_crc = {DATA_WIDTH{1'b0}}; -reg [7:0] xgmii_rxc_d0 = 8'd0; -reg [7:0] xgmii_rxc_d1 = 8'd0; +reg [CTRL_WIDTH-1:0] xgmii_rxc_d0 = {CTRL_WIDTH{1'b0}}; +reg [CTRL_WIDTH-1:0] xgmii_rxc_d1 = {CTRL_WIDTH{1'b0}}; -reg [63:0] m_axis_tdata_reg = 64'd0, m_axis_tdata_next; -reg [7:0] m_axis_tkeep_reg = 8'd0, m_axis_tkeep_next; +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, m_axis_tkeep_next; reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; @@ -101,6 +129,8 @@ reg [1:0] start_packet_reg = 2'b00; reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; +reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0; + reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state3 = 32'hFFFFFFFF; @@ -122,7 +152,7 @@ assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tkeep = m_axis_tkeep_reg; assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = m_axis_tuser_reg; +assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg; assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; @@ -295,8 +325,8 @@ always @* begin last_cycle_tkeep_next = last_cycle_tkeep_reg; - m_axis_tdata_next = 64'd0; - m_axis_tkeep_next = 8'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; + m_axis_tkeep_next = {KEEP_WIDTH{1'b0}}; m_axis_tvalid_next = 1'b0; m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; @@ -313,7 +343,7 @@ always @* begin // start condition if (control_masked) begin // control or error characters in first data word - m_axis_tdata_next = 64'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; m_axis_tkeep_next = 8'h01; m_axis_tvalid_next = 1'b1; m_axis_tlast_next = 1'b1; @@ -397,7 +427,7 @@ always @* begin // start condition if (control_masked) begin // control or error characters in first data word - m_axis_tdata_next = 64'd0; + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; m_axis_tkeep_next = 8'h01; m_axis_tvalid_next = 1'b1; m_axis_tlast_next = 1'b1; @@ -430,8 +460,8 @@ always @(posedge clk) begin crc_state3 <= 32'hFFFFFFFF; crc_valid7_save <= 1'b0; - xgmii_rxc_d0 <= 8'd0; - xgmii_rxc_d1 <= 8'd0; + xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}}; + xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}}; lanes_swapped <= 1'b0; end else begin @@ -471,6 +501,28 @@ always @(posedge clk) begin end end + if (PTP_TS_WIDTH == 96 && $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin + // ns field rollover + ptp_ts_reg[45:16] <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000); + ptp_ts_reg[95:48] <= ptp_ts_reg[95:48] + 1; + end + + if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin + if (PTP_TS_WIDTH == 96) begin + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + ptp_ts_reg[95:48] <= ptp_ts[95:48]; + end else begin + ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + end + end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin + if (PTP_TS_WIDTH == 96) begin + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + ptp_ts_reg[95:48] <= ptp_ts[95:48]; + end else begin + ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + end + end + m_axis_tdata_reg <= m_axis_tdata_next; m_axis_tkeep_reg <= m_axis_tkeep_next; m_axis_tlast_reg <= m_axis_tlast_next; diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index ea2ac38fc..0eae6d15e 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -31,42 +31,71 @@ THE SOFTWARE. */ module axis_xgmii_tx_32 # ( + parameter DATA_WIDTH = 32, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI input */ - input wire [31:0] s_axis_tdata, - input wire [3:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * XGMII output */ - output wire [31:0] xgmii_txd, - output wire [3:0] xgmii_txc, + output wire [DATA_WIDTH-1:0] xgmii_txd, + output wire [CTRL_WIDTH-1:0] xgmii_txc, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, /* * Configuration */ - input wire [7:0] ifg_delay, + input wire [7:0] ifg_delay, /* * Status */ - output wire start_packet, - output wire error_underflow + output wire start_packet, + output wire error_underflow ); +// bus width assertions +initial begin + if (DATA_WIDTH != 32) begin + $error("Error: Interface width must be 32"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end +end + localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfffc; localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0003; @@ -98,15 +127,15 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg reset_crc; reg update_crc; -reg [31:0] s_axis_tdata_masked; +reg [DATA_WIDTH-1:0] s_axis_tdata_masked; -reg [31:0] s_tdata_reg = 64'd0, s_tdata_next; -reg [3:0] s_tkeep_reg = 8'd0, s_tkeep_next; +reg [DATA_WIDTH-1:0] s_tdata_reg ={DATA_WIDTH{1'b0}}, s_tdata_next; +reg [KEEP_WIDTH-1:0] s_tkeep_reg = {KEEP_WIDTH{1'b0}}, s_tkeep_next; -reg [31:0] fcs_output_txd_0; -reg [31:0] fcs_output_txd_1; -reg [3:0] fcs_output_txc_0; -reg [3:0] fcs_output_txc_1; +reg [DATA_WIDTH-1:0] fcs_output_txd_0; +reg [DATA_WIDTH-1:0] fcs_output_txd_1; +reg [CTRL_WIDTH-1:0] fcs_output_txc_0; +reg [CTRL_WIDTH-1:0] fcs_output_txc_1; reg [7:0] ifg_offset; @@ -119,6 +148,10 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next; +reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next; +reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next0; @@ -126,8 +159,8 @@ wire [31:0] crc_next1; wire [31:0] crc_next2; wire [31:0] crc_next3; -reg [31:0] xgmii_txd_reg = {4{XGMII_IDLE}}, xgmii_txd_next; -reg [3:0] xgmii_txc_reg = 4'b1111, xgmii_txc_next; +reg [DATA_WIDTH-1:0] xgmii_txd_reg = {CTRL_WIDTH{XGMII_IDLE}}, xgmii_txd_next; +reg [CTRL_WIDTH-1:0] xgmii_txc_reg = {CTRL_WIDTH{1'b1}}, xgmii_txc_next; reg start_packet_reg = 1'b0, start_packet_next; reg error_underflow_reg = 1'b0, error_underflow_next; @@ -137,6 +170,10 @@ assign s_axis_tready = s_axis_tready_reg; assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; +assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; +assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; + assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; @@ -260,10 +297,10 @@ always @* begin extra_cycle = 1'b1; end default: begin - fcs_output_txd_0 = {4{XGMII_ERROR}}; - fcs_output_txd_1 = {4{XGMII_ERROR}}; - fcs_output_txc_0 = 4'b1111; - fcs_output_txc_1 = 4'b1111; + fcs_output_txd_0 = {CTRL_WIDTH{XGMII_ERROR}}; + fcs_output_txd_1 = {CTRL_WIDTH{XGMII_ERROR}}; + fcs_output_txc_0 = {CTRL_WIDTH{1'b1}}; + fcs_output_txc_1 = {CTRL_WIDTH{1'b1}}; ifg_offset = 8'd0; extra_cycle = 1'b0; end @@ -286,9 +323,13 @@ always @* begin s_tdata_next = s_tdata_reg; s_tkeep_next = s_tkeep_reg; + m_axis_ptp_ts_next = m_axis_ptp_ts_reg; + m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg; + m_axis_ptp_ts_valid_next = 1'b0; + // XGMII idle - xgmii_txd_next = {4{XGMII_IDLE}}; - xgmii_txc_next = 4'b1111; + xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_next = {CTRL_WIDTH{1'b1}}; start_packet_next = 1'b0; error_underflow_next = 1'b0; @@ -300,8 +341,8 @@ always @* begin reset_crc = 1'b1; // XGMII idle - xgmii_txd_next = {4{XGMII_IDLE}}; - xgmii_txc_next = 4'b1111; + xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_next = {CTRL_WIDTH{1'b1}}; s_tdata_next = s_axis_tdata_masked; s_tkeep_next = s_axis_tkeep; @@ -327,6 +368,9 @@ always @* begin xgmii_txd_next = {ETH_SFD, {3{ETH_PRE}}}; xgmii_txc_next = 4'b0000; s_axis_tready_next = 1'b1; + m_axis_ptp_ts_next = ptp_ts; + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_next = 1'b1; start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end @@ -347,7 +391,7 @@ always @* begin if (s_axis_tlast) begin frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); s_axis_tready_next = 1'b0; - if (s_axis_tuser) begin + if (s_axis_tuser[0]) begin xgmii_txd_next = {XGMII_TERM, {3{XGMII_ERROR}}}; xgmii_txc_next = 4'b1111; frame_ptr_next = 16'd0; @@ -389,7 +433,7 @@ always @* begin s_axis_tready_next = 1'b0; xgmii_txd_next = s_tdata_reg; - xgmii_txc_next = 4'b0000; + xgmii_txc_next = {CTRL_WIDTH{1'b0}}; s_tdata_next = 32'd0; s_tkeep_next = 4'hf; @@ -537,8 +581,10 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; - xgmii_txd_reg <= {4{XGMII_IDLE}}; - xgmii_txc_reg <= 4'b1111; + m_axis_ptp_ts_valid_reg <= 1'b0; + + xgmii_txd_reg <= {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_reg <= {CTRL_WIDTH{1'b1}}; start_packet_reg <= 1'b0; error_underflow_reg <= 1'b0; @@ -553,6 +599,8 @@ always @(posedge clk) begin deficit_idle_count_reg <= deficit_idle_count_next; s_axis_tready_reg <= s_axis_tready_next; + + m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next; xgmii_txd_reg <= xgmii_txd_next; xgmii_txc_reg <= xgmii_txc_next; @@ -570,6 +618,9 @@ always @(posedge clk) begin s_tdata_reg <= s_tdata_next; s_tkeep_reg <= s_tkeep_next; + + m_axis_ptp_ts_reg <= m_axis_ptp_ts_next; + m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next; end endmodule diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index fd3001844..67f30ce87 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -31,42 +31,73 @@ THE SOFTWARE. */ module axis_xgmii_tx_64 # ( + parameter DATA_WIDTH = 64, + parameter KEEP_WIDTH = (DATA_WIDTH/8), + parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI input */ - input wire [63:0] s_axis_tdata, - input wire [7:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * XGMII output */ - output wire [63:0] xgmii_txd, - output wire [7:0] xgmii_txc, + output wire [DATA_WIDTH-1:0] xgmii_txd, + output wire [CTRL_WIDTH-1:0] xgmii_txc, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, /* * Configuration */ - input wire [7:0] ifg_delay, + input wire [7:0] ifg_delay, /* * Status */ - output wire [1:0] start_packet, - output wire error_underflow + output wire [1:0] start_packet, + output wire error_underflow ); +// bus width assertions +initial begin + if (DATA_WIDTH != 64) begin + $error("Error: Interface width must be 64"); + $finish; + end + + if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: Interface requires byte (8-bit) granularity"); + $finish; + end +end + localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8; localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007; @@ -103,15 +134,15 @@ reg lanes_swapped = 1'b0; reg [31:0] swap_txd = 32'd0; reg [3:0] swap_txc = 4'd0; -reg [63:0] s_axis_tdata_masked; +reg [DATA_WIDTH-1:0] s_axis_tdata_masked; -reg [63:0] s_tdata_reg = 64'd0, s_tdata_next; -reg [7:0] s_tkeep_reg = 8'd0, s_tkeep_next; +reg [DATA_WIDTH-1:0] s_tdata_reg = {DATA_WIDTH{1'b0}}, s_tdata_next; +reg [KEEP_WIDTH-1:0] s_tkeep_reg = {KEEP_WIDTH{1'b0}}, s_tkeep_next; -reg [63:0] fcs_output_txd_0; -reg [63:0] fcs_output_txd_1; -reg [7:0] fcs_output_txc_0; -reg [7:0] fcs_output_txc_1; +reg [DATA_WIDTH-1:0] fcs_output_txd_0; +reg [DATA_WIDTH-1:0] fcs_output_txd_1; +reg [CTRL_WIDTH-1:0] fcs_output_txc_0; +reg [CTRL_WIDTH-1:0] fcs_output_txc_1; reg [7:0] ifg_offset; @@ -124,6 +155,11 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next; +reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next; +reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next; +reg m_axis_ptp_ts_valid_int_reg = 1'b0, m_axis_ptp_ts_valid_int_next; + reg [31:0] crc_state = 32'hFFFFFFFF; wire [31:0] crc_next0; @@ -135,8 +171,8 @@ wire [31:0] crc_next5; wire [31:0] crc_next6; wire [31:0] crc_next7; -reg [63:0] xgmii_txd_reg = {8{XGMII_IDLE}}, xgmii_txd_next; -reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; +reg [DATA_WIDTH-1:0] xgmii_txd_reg = {CTRL_WIDTH{XGMII_IDLE}}, xgmii_txd_next; +reg [CTRL_WIDTH-1:0] xgmii_txc_reg = {CTRL_WIDTH{1'b1}}, xgmii_txc_next; reg start_packet_reg = 2'b00, start_packet_next; reg error_underflow_reg = 1'b0, error_underflow_next; @@ -146,6 +182,10 @@ assign s_axis_tready = s_axis_tready_reg; assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; +assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; +assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; + assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; @@ -369,10 +409,10 @@ always @* begin extra_cycle = 1'b1; end default: begin - fcs_output_txd_0 = {8{XGMII_ERROR}}; - fcs_output_txd_1 = {8{XGMII_ERROR}}; - fcs_output_txc_0 = 8'b11111111; - fcs_output_txc_1 = 8'b11111111; + fcs_output_txd_0 = {CTRL_WIDTH{XGMII_ERROR}}; + fcs_output_txd_1 = {CTRL_WIDTH{XGMII_ERROR}}; + fcs_output_txc_0 = {CTRL_WIDTH{1'b1}}; + fcs_output_txc_1 = {CTRL_WIDTH{1'b1}}; ifg_offset = 8'd0; extra_cycle = 1'b1; end @@ -398,13 +438,27 @@ always @* begin s_tdata_next = s_tdata_reg; s_tkeep_next = s_tkeep_reg; + m_axis_ptp_ts_next = m_axis_ptp_ts_reg; + m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg; + m_axis_ptp_ts_valid_next = 1'b0; + m_axis_ptp_ts_valid_int_next = 1'b0; + // XGMII idle - xgmii_txd_next = {8{XGMII_IDLE}}; - xgmii_txc_next = 8'b11111111; + xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_next = {CTRL_WIDTH{1'b1}}; start_packet_next = 2'b00; error_underflow_next = 1'b0; + if (m_axis_ptp_ts_valid_int_reg) begin + m_axis_ptp_ts_valid_next = 1'b1; + if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin + // ns field rollover + m_axis_ptp_ts_next[45:16] <= $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000); + m_axis_ptp_ts_next[95:48] <= m_axis_ptp_ts_reg[95:48] + 1; + end + end + case (state_reg) STATE_IDLE: begin // idle state - wait for data @@ -413,8 +467,8 @@ always @* begin s_axis_tready_next = 1'b1; // XGMII idle - xgmii_txd_next = {8{XGMII_IDLE}}; - xgmii_txc_next = 8'b11111111; + xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_next = {CTRL_WIDTH{1'b1}}; s_tdata_next = s_axis_tdata_masked; s_tkeep_next = s_axis_tkeep; @@ -424,10 +478,26 @@ always @* begin if (ifg_count_reg > 8'd0) begin // need to send more idles - swap lanes swap_lanes = 1'b1; + if (PTP_TS_WIDTH == 96) begin + m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + end else begin + m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + end + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_int_next = 1'b1; start_packet_next = 2'b10; end else begin // no more idles - unswap unswap_lanes = 1'b1; + if (PTP_TS_WIDTH == 96) begin + m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + end else begin + m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + end + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_int_next = 1'b1; start_packet_next = 2'b01; end xgmii_txd_next = {ETH_SFD, {6{ETH_PRE}}, XGMII_START}; @@ -458,7 +528,7 @@ always @* begin if (s_axis_tlast) begin frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); s_axis_tready_next = 1'b0; - if (s_axis_tuser) begin + if (s_axis_tuser[0]) begin xgmii_txd_next = {{3{XGMII_IDLE}}, XGMII_TERM, {4{XGMII_ERROR}}}; xgmii_txc_next = 8'b11111111; frame_ptr_next = 16'd0; @@ -500,7 +570,7 @@ always @* begin s_axis_tready_next = 1'b0; xgmii_txd_next = s_tdata_reg; - xgmii_txc_next = 8'b00000000; + xgmii_txc_next = {CTRL_WIDTH{1'b0}}; s_tdata_next = 64'd0; s_tkeep_next = 8'hff; @@ -654,8 +724,11 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; - xgmii_txd_reg <= {8{XGMII_IDLE}}; - xgmii_txc_reg <= 8'b11111111; + m_axis_ptp_ts_valid_reg <= 1'b0; + m_axis_ptp_ts_valid_int_reg <= 1'b0; + + xgmii_txd_reg <= {CTRL_WIDTH{XGMII_IDLE}}; + xgmii_txc_reg <= {CTRL_WIDTH{1'b1}}; start_packet_reg <= 2'b00; error_underflow_reg <= 1'b0; @@ -672,6 +745,9 @@ always @(posedge clk) begin deficit_idle_count_reg <= deficit_idle_count_next; s_axis_tready_reg <= s_axis_tready_next; + + m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next; + m_axis_ptp_ts_valid_int_reg <= m_axis_ptp_ts_valid_int_next; start_packet_reg <= start_packet_next; error_underflow_reg <= error_underflow_next; @@ -697,6 +773,9 @@ always @(posedge clk) begin s_tdata_reg <= s_tdata_next; s_tkeep_reg <= s_tkeep_next; + m_axis_ptp_ts_reg <= m_axis_ptp_ts_next; + m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next; + swap_txd <= xgmii_txd_next[63:32]; swap_txc <= xgmii_txc_next[7:4]; end diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index dceab9c73..9601a2e13 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -36,54 +36,73 @@ module eth_mac_10g # parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter TX_PTP_TS_ENABLE = 0, + parameter TX_PTP_TS_WIDTH = 96, + parameter TX_PTP_TAG_ENABLE = 0, + parameter TX_PTP_TAG_WIDTH = 16, + parameter RX_PTP_TS_ENABLE = 0, + parameter RX_PTP_TS_WIDTH = 96, + parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, + parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1 ) ( - input wire rx_clk, - input wire rx_rst, - input wire tx_clk, - input wire tx_rst, + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, /* * AXI input */ - input wire [DATA_WIDTH-1:0] tx_axis_tdata, - input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire tx_axis_tuser, + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire [TX_USER_WIDTH-1:0] tx_axis_tuser, /* * AXI output */ - output wire [DATA_WIDTH-1:0] rx_axis_tdata, - output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, - output wire rx_axis_tvalid, - output wire rx_axis_tlast, - output wire rx_axis_tuser, + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire [RX_USER_WIDTH-1:0] rx_axis_tuser, /* * XGMII interface */ - input wire [DATA_WIDTH-1:0] xgmii_rxd, - input wire [CTRL_WIDTH-1:0] xgmii_rxc, - output wire [DATA_WIDTH-1:0] xgmii_txd, - output wire [CTRL_WIDTH-1:0] xgmii_txc, + input wire [DATA_WIDTH-1:0] xgmii_rxd, + input wire [CTRL_WIDTH-1:0] xgmii_rxc, + output wire [DATA_WIDTH-1:0] xgmii_txd, + output wire [CTRL_WIDTH-1:0] xgmii_txc, + + /* + * PTP + */ + input wire [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts, + input wire [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts, + output wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts, + output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag, + output wire tx_axis_ptp_ts_valid, /* * Status */ - output wire [1:0] tx_start_packet, - output wire tx_error_underflow, - output wire [1:0] rx_start_packet, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, + output wire [1:0] tx_start_packet, + output wire tx_error_underflow, + output wire [1:0] rx_start_packet, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay ); // bus width assertions @@ -103,7 +122,16 @@ generate if (DATA_WIDTH == 64) begin -axis_xgmii_rx_64 +axis_xgmii_rx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .USER_WIDTH(RX_USER_WIDTH) +) axis_xgmii_rx_inst ( .clk(rx_clk), .rst(rx_rst), @@ -114,15 +142,26 @@ axis_xgmii_rx_inst ( .m_axis_tvalid(rx_axis_tvalid), .m_axis_tlast(rx_axis_tlast), .m_axis_tuser(rx_axis_tuser), + .ptp_ts(rx_ptp_ts), .start_packet(rx_start_packet), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); axis_xgmii_tx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .USER_WIDTH(TX_USER_WIDTH) ) axis_xgmii_tx_inst ( .clk(tx_clk), @@ -135,6 +174,10 @@ axis_xgmii_tx_inst ( .s_axis_tuser(tx_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .ptp_ts(tx_ptp_ts), + .m_axis_ptp_ts(tx_axis_ptp_ts), + .m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .ifg_delay(ifg_delay), .start_packet(tx_start_packet), .error_underflow(tx_error_underflow) @@ -142,7 +185,14 @@ axis_xgmii_tx_inst ( end else begin -axis_xgmii_rx_32 +axis_xgmii_rx_32 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .USER_WIDTH(RX_USER_WIDTH) +) axis_xgmii_rx_inst ( .clk(rx_clk), .rst(rx_rst), @@ -153,7 +203,8 @@ axis_xgmii_rx_inst ( .m_axis_tvalid(rx_axis_tvalid), .m_axis_tlast(rx_axis_tlast), .m_axis_tuser(rx_axis_tuser), - .start_packet(rx_start_packet), + .ptp_ts(rx_ptp_ts), + .start_packet(rx_start_packet[0]), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs) ); @@ -161,9 +212,17 @@ axis_xgmii_rx_inst ( assign rx_start_packet[1] = 1'b0; axis_xgmii_tx_32 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .USER_WIDTH(TX_USER_WIDTH) ) axis_xgmii_tx_inst ( .clk(tx_clk), @@ -176,8 +235,12 @@ axis_xgmii_tx_inst ( .s_axis_tuser(tx_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .ptp_ts(tx_ptp_ts), + .m_axis_ptp_ts(tx_axis_ptp_ts), + .m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .ifg_delay(ifg_delay), - .start_packet(tx_start_packet) + .start_packet(tx_start_packet[0]) ); assign tx_start_packet[1] = 1'b0; diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v index 1a37ff5c8..7eefcdf3f 100644 --- a/rtl/eth_mac_1g.v +++ b/rtl/eth_mac_1g.v @@ -31,66 +31,89 @@ THE SOFTWARE. */ module eth_mac_1g # ( + parameter DATA_WIDTH = 8, parameter ENABLE_PADDING = 1, - parameter MIN_FRAME_LENGTH = 64 + parameter MIN_FRAME_LENGTH = 64, + parameter TX_PTP_TS_ENABLE = 0, + parameter TX_PTP_TS_WIDTH = 96, + parameter TX_PTP_TAG_ENABLE = 0, + parameter TX_PTP_TAG_WIDTH = 16, + parameter RX_PTP_TS_ENABLE = 0, + parameter RX_PTP_TS_WIDTH = 96, + parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, + parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1 ) ( - input wire rx_clk, - input wire rx_rst, - input wire tx_clk, - input wire tx_rst, + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, /* * AXI input */ - input wire [7:0] tx_axis_tdata, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire tx_axis_tuser, + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire [TX_USER_WIDTH-1:0] tx_axis_tuser, /* * AXI output */ - output wire [7:0] rx_axis_tdata, - output wire rx_axis_tvalid, - output wire rx_axis_tlast, - output wire rx_axis_tuser, + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire [RX_USER_WIDTH-1:0] rx_axis_tuser, /* * GMII interface */ - input wire [7:0] gmii_rxd, - input wire gmii_rx_dv, - input wire gmii_rx_er, - output wire [7:0] gmii_txd, - output wire gmii_tx_en, - output wire gmii_tx_er, + input wire [DATA_WIDTH-1:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, + output wire [DATA_WIDTH-1:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * PTP + */ + input wire [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts, + input wire [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts, + output wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts, + output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag, + output wire tx_axis_ptp_ts_valid, /* * Control */ - input wire rx_clk_enable, - input wire tx_clk_enable, - input wire rx_mii_select, - input wire tx_mii_select, + input wire rx_clk_enable, + input wire tx_clk_enable, + input wire rx_mii_select, + input wire tx_mii_select, /* * Status */ - output wire tx_start_packet, - output wire tx_error_underflow, - output wire rx_start_packet, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, + output wire tx_start_packet, + output wire tx_error_underflow, + output wire rx_start_packet, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, /* * Configuration */ - input wire [7:0] ifg_delay + input wire [7:0] ifg_delay ); -axis_gmii_rx +axis_gmii_rx #( + .DATA_WIDTH(DATA_WIDTH), + .PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .USER_WIDTH(RX_USER_WIDTH) +) axis_gmii_rx_inst ( .clk(rx_clk), .rst(rx_rst), @@ -101,6 +124,7 @@ axis_gmii_rx_inst ( .m_axis_tvalid(rx_axis_tvalid), .m_axis_tlast(rx_axis_tlast), .m_axis_tuser(rx_axis_tuser), + .ptp_ts(rx_ptp_ts), .clk_enable(rx_clk_enable), .mii_select(rx_mii_select), .start_packet(rx_start_packet), @@ -109,8 +133,14 @@ axis_gmii_rx_inst ( ); axis_gmii_tx #( + .DATA_WIDTH(DATA_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .USER_WIDTH(TX_USER_WIDTH) ) axis_gmii_tx_inst ( .clk(tx_clk), @@ -123,6 +153,10 @@ axis_gmii_tx_inst ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .ptp_ts(tx_ptp_ts), + .m_axis_ptp_ts(tx_axis_ptp_ts), + .m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .clk_enable(tx_clk_enable), .mii_select(tx_mii_select), .ifg_delay(ifg_delay), diff --git a/rtl/eth_mac_phy_10g.v b/rtl/eth_mac_phy_10g.v index d635f3254..a1b16ade1 100644 --- a/rtl/eth_mac_phy_10g.v +++ b/rtl/eth_mac_phy_10g.v @@ -38,6 +38,16 @@ module eth_mac_phy_10g # parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter TX_PTP_TS_ENABLE = 0, + parameter TX_PTP_TS_WIDTH = 96, + parameter TX_PTP_TAG_ENABLE = 0, + parameter TX_PTP_TAG_WIDTH = 16, + parameter RX_PTP_TS_ENABLE = 0, + parameter RX_PTP_TS_WIDTH = 96, + parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, + parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0, @@ -45,58 +55,67 @@ module eth_mac_phy_10g # parameter COUNT_125US = 125000/6.4 ) ( - input wire rx_clk, - input wire rx_rst, - input wire tx_clk, - input wire tx_rst, + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, /* * AXI input */ - input wire [DATA_WIDTH-1:0] tx_axis_tdata, - input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire tx_axis_tuser, + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire [TX_USER_WIDTH-1:0] tx_axis_tuser, /* * AXI output */ - output wire [DATA_WIDTH-1:0] rx_axis_tdata, - output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, - output wire rx_axis_tvalid, - output wire rx_axis_tlast, - output wire rx_axis_tuser, + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire [RX_USER_WIDTH-1:0] rx_axis_tuser, /* * SERDES interface */ - output wire [DATA_WIDTH-1:0] serdes_tx_data, - output wire [HDR_WIDTH-1:0] serdes_tx_hdr, - input wire [DATA_WIDTH-1:0] serdes_rx_data, - input wire [HDR_WIDTH-1:0] serdes_rx_hdr, - output wire serdes_rx_bitslip, + output wire [DATA_WIDTH-1:0] serdes_tx_data, + output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + input wire [DATA_WIDTH-1:0] serdes_rx_data, + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * PTP + */ + input wire [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts, + input wire [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts, + output wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts, + output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag, + output wire tx_axis_ptp_ts_valid, /* * Status */ - output wire [1:0] tx_start_packet, - output wire tx_error_underflow, - output wire [1:0] rx_start_packet, - output wire [6:0] rx_error_count, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, - output wire rx_bad_block, - output wire rx_block_lock, - output wire rx_high_ber, + output wire [1:0] tx_start_packet, + output wire tx_error_underflow, + output wire [1:0] rx_start_packet, + output wire [6:0] rx_error_count, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_bad_block, + output wire rx_block_lock, + output wire rx_high_ber, /* * Configuration */ - input wire [7:0] ifg_delay, - input wire tx_prbs31_enable, - input wire rx_prbs31_enable + input wire [7:0] ifg_delay, + input wire tx_prbs31_enable, + input wire rx_prbs31_enable ); eth_mac_phy_10g_rx #( @@ -104,6 +123,11 @@ eth_mac_phy_10g_rx #( .KEEP_WIDTH(KEEP_WIDTH), .CTRL_WIDTH(CTRL_WIDTH), .HDR_WIDTH(HDR_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .USER_WIDTH(RX_USER_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), @@ -121,6 +145,7 @@ eth_mac_phy_10g_rx_inst ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .ptp_ts(rx_ptp_ts), .rx_start_packet(rx_start_packet), .rx_error_count(rx_error_count), .rx_error_bad_frame(rx_error_bad_frame), @@ -139,6 +164,13 @@ eth_mac_phy_10g_tx #( .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .USER_WIDTH(TX_USER_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE) @@ -154,6 +186,10 @@ eth_mac_phy_10g_tx_inst ( .s_axis_tuser(tx_axis_tuser), .serdes_tx_data(serdes_tx_data), .serdes_tx_hdr(serdes_tx_hdr), + .ptp_ts(tx_ptp_ts), + .m_axis_ptp_ts(tx_axis_ptp_ts), + .m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), .ifg_delay(ifg_delay), diff --git a/rtl/eth_mac_phy_10g_rx.v b/rtl/eth_mac_phy_10g_rx.v index 5c70391fd..44476eef4 100644 --- a/rtl/eth_mac_phy_10g_rx.v +++ b/rtl/eth_mac_phy_10g_rx.v @@ -35,6 +35,11 @@ module eth_mac_phy_10g_rx # parameter KEEP_WIDTH = (DATA_WIDTH/8), parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter HDR_WIDTH = (DATA_WIDTH/32), + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0, @@ -42,40 +47,45 @@ module eth_mac_phy_10g_rx # parameter COUNT_125US = 125000/6.4 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI output */ - output wire [DATA_WIDTH-1:0] m_axis_tdata, - output wire [KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, /* * SERDES interface */ - input wire [DATA_WIDTH-1:0] serdes_rx_data, - input wire [HDR_WIDTH-1:0] serdes_rx_hdr, - output wire serdes_rx_bitslip, + input wire [DATA_WIDTH-1:0] serdes_rx_data, + input wire [HDR_WIDTH-1:0] serdes_rx_hdr, + output wire serdes_rx_bitslip, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, /* * Status */ - output wire [1:0] rx_start_packet, - output wire [6:0] rx_error_count, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, - output wire rx_bad_block, - output wire rx_block_lock, - output wire rx_high_ber, + output wire [1:0] rx_start_packet, + output wire [6:0] rx_error_count, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_bad_block, + output wire rx_block_lock, + output wire rx_high_ber, /* * Configuration */ - input wire rx_prbs31_enable + input wire rx_prbs31_enable ); // bus width assertions @@ -126,7 +136,12 @@ eth_phy_10g_rx_if_inst ( axis_baser_rx_64 #( .DATA_WIDTH(DATA_WIDTH), .KEEP_WIDTH(KEEP_WIDTH), - .HDR_WIDTH(HDR_WIDTH) + .HDR_WIDTH(HDR_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(USER_WIDTH) ) axis_baser_rx_inst ( .clk(clk), @@ -138,6 +153,7 @@ axis_baser_rx_inst ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .ptp_ts(ptp_ts), .start_packet(rx_start_packet), .error_bad_frame(rx_error_bad_frame), .error_bad_fcs(rx_error_bad_fcs), diff --git a/rtl/eth_mac_phy_10g_tx.v b/rtl/eth_mac_phy_10g_tx.v index 9e795206f..9a497e2d5 100644 --- a/rtl/eth_mac_phy_10g_tx.v +++ b/rtl/eth_mac_phy_10g_tx.v @@ -38,41 +38,56 @@ module eth_mac_phy_10g_tx # parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, + parameter PTP_PERIOD_NS = 4'h6, + parameter PTP_PERIOD_FNS = 16'h6666, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0 ) ( - input wire clk, - input wire rst, + 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, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * SERDES interface */ - output wire [DATA_WIDTH-1:0] serdes_tx_data, - output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + output wire [DATA_WIDTH-1:0] serdes_tx_data, + output wire [HDR_WIDTH-1:0] serdes_tx_hdr, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, /* * Status */ - output wire [1:0] tx_start_packet, - output wire tx_error_underflow, + output wire [1:0] tx_start_packet, + output wire tx_error_underflow, /* * Configuration */ - input wire [7:0] ifg_delay, - input wire tx_prbs31_enable + input wire [7:0] ifg_delay, + input wire tx_prbs31_enable ); // bus width assertions @@ -102,7 +117,14 @@ axis_baser_tx_64 #( .HDR_WIDTH(HDR_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_ENABLE(PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .USER_WIDTH(USER_WIDTH) ) axis_baser_tx_inst ( .clk(clk), @@ -115,6 +137,10 @@ axis_baser_tx_inst ( .s_axis_tuser(s_axis_tuser), .encoded_tx_data(encoded_tx_data), .encoded_tx_hdr(encoded_tx_hdr), + .ptp_ts(ptp_ts), + .m_axis_ptp_ts(m_axis_ptp_ts), + .m_axis_ptp_ts_tag(m_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(m_axis_ptp_ts_valid), .start_packet(tx_start_packet), .error_underflow(tx_error_underflow), .ifg_delay(ifg_delay) diff --git a/tb/test_axis_baser_rx_64.py b/tb/test_axis_baser_rx_64.py index f4313fc18..d13e4993f 100755 --- a/tb/test_axis_baser_rx_64.py +++ b/tb/test_axis_baser_rx_64.py @@ -50,6 +50,11 @@ def bench(): DATA_WIDTH = 64 KEEP_WIDTH = (DATA_WIDTH/8) HDR_WIDTH = 2 + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) @@ -58,13 +63,14 @@ def bench(): encoded_rx_data = Signal(intbv(0)[DATA_WIDTH:]) encoded_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) # Outputs m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) - m_axis_tuser = Signal(bool(0)) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) start_packet = Signal(intbv(0)[2:]) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -110,6 +116,7 @@ def bench(): m_axis_tvalid=m_axis_tvalid, m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, + ptp_ts=ptp_ts, start_packet=start_packet, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs, diff --git a/tb/test_axis_baser_rx_64.v b/tb/test_axis_baser_rx_64.v index cc0b669f8..95eb08067 100644 --- a/tb/test_axis_baser_rx_64.v +++ b/tb/test_axis_baser_rx_64.v @@ -35,6 +35,11 @@ module test_axis_baser_rx_64; parameter DATA_WIDTH = 64; parameter KEEP_WIDTH = (DATA_WIDTH/8); parameter HDR_WIDTH = 2; +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; @@ -43,13 +48,14 @@ reg [7:0] current_test = 0; reg [DATA_WIDTH-1:0] encoded_rx_data = 0; reg [HDR_WIDTH-1:0] encoded_rx_hdr = 1; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; // Outputs wire [DATA_WIDTH-1:0] m_axis_tdata; wire [KEEP_WIDTH-1:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; -wire m_axis_tuser; +wire [USER_WIDTH-1:0] m_axis_tuser; wire [1:0] start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -62,7 +68,8 @@ initial begin rst, current_test, encoded_rx_data, - encoded_rx_hdr + encoded_rx_hdr, + ptp_ts ); $to_myhdl( m_axis_tdata, @@ -84,7 +91,12 @@ end axis_baser_rx_64 #( .DATA_WIDTH(DATA_WIDTH), .KEEP_WIDTH(KEEP_WIDTH), - .HDR_WIDTH(HDR_WIDTH) + .HDR_WIDTH(HDR_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -96,6 +108,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .ptp_ts(ptp_ts), .start_packet(start_packet), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs), diff --git a/tb/test_axis_baser_tx_64.py b/tb/test_axis_baser_tx_64.py index 26afcefc5..f807214ef 100755 --- a/tb/test_axis_baser_tx_64.py +++ b/tb/test_axis_baser_tx_64.py @@ -52,6 +52,13 @@ def bench(): ENABLE_PADDING = 1 ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + PTP_TAG_ENABLE = 0 + PTP_TAG_WIDTH = 16 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) @@ -62,13 +69,17 @@ def bench(): s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) s_axis_tvalid = Signal(bool(0)) s_axis_tlast = Signal(bool(0)) - s_axis_tuser = Signal(bool(0)) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs s_axis_tready = Signal(bool(0)) encoded_tx_data = Signal(intbv(0)[DATA_WIDTH:]) encoded_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) + m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:]) + m_axis_ptp_ts_valid = Signal(bool(0)) start_packet = Signal(intbv(0)[2:]) error_underflow = Signal(bool(0)) @@ -117,6 +128,10 @@ def bench(): s_axis_tuser=s_axis_tuser, encoded_tx_data=encoded_tx_data, encoded_tx_hdr=encoded_tx_hdr, + ptp_ts=ptp_ts, + m_axis_ptp_ts=m_axis_ptp_ts, + m_axis_ptp_ts_tag=m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid=m_axis_ptp_ts_valid, ifg_delay=ifg_delay, start_packet=start_packet, error_underflow=error_underflow diff --git a/tb/test_axis_baser_tx_64.v b/tb/test_axis_baser_tx_64.v index aa64db44a..5aac11293 100644 --- a/tb/test_axis_baser_tx_64.v +++ b/tb/test_axis_baser_tx_64.v @@ -38,6 +38,13 @@ parameter HDR_WIDTH = 2; parameter ENABLE_PADDING = 1; parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_WIDTH = 16; +parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; @@ -48,13 +55,17 @@ 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; -reg s_axis_tuser = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; reg [7:0] ifg_delay = 0; // Outputs wire s_axis_tready; wire [DATA_WIDTH-1:0] encoded_tx_data; wire [HDR_WIDTH-1:0] encoded_tx_hdr; +wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts; +wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag; +wire m_axis_ptp_ts_valid; wire [1:0] start_packet; wire error_underflow; @@ -69,12 +80,16 @@ initial begin s_axis_tvalid, s_axis_tlast, s_axis_tuser, + ptp_ts, ifg_delay ); $to_myhdl( s_axis_tready, encoded_tx_data, encoded_tx_hdr, + m_axis_ptp_ts, + m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid, start_packet, error_underflow ); @@ -90,7 +105,14 @@ axis_baser_tx_64 #( .HDR_WIDTH(HDR_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_ENABLE(PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -103,6 +125,10 @@ UUT ( .s_axis_tuser(s_axis_tuser), .encoded_tx_data(encoded_tx_data), .encoded_tx_hdr(encoded_tx_hdr), + .ptp_ts(ptp_ts), + .m_axis_ptp_ts(m_axis_ptp_ts), + .m_axis_ptp_ts_tag(m_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(m_axis_ptp_ts_valid), .ifg_delay(ifg_delay), .start_packet(start_packet), .error_underflow(error_underflow) diff --git a/tb/test_axis_gmii_rx.py b/tb/test_axis_gmii_rx.py index dbf93f16b..237909385 100755 --- a/tb/test_axis_gmii_rx.py +++ b/tb/test_axis_gmii_rx.py @@ -46,24 +46,28 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters - + DATA_WIDTH = 8 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - gmii_rxd = Signal(intbv(0)[8:]) + gmii_rxd = Signal(intbv(0)[DATA_WIDTH:]) gmii_rx_dv = Signal(bool(0)) gmii_rx_er = Signal(bool(0)) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) clk_enable = Signal(bool(1)) mii_select = Signal(bool(0)) # Outputs - m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) - m_axis_tuser = Signal(bool(0)) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) start_packet = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -113,6 +117,8 @@ def bench(): m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, + ptp_ts=ptp_ts, + clk_enable=clk_enable, mii_select=mii_select, diff --git a/tb/test_axis_gmii_rx.v b/tb/test_axis_gmii_rx.v index af28a9a77..452fdcbe1 100644 --- a/tb/test_axis_gmii_rx.v +++ b/tb/test_axis_gmii_rx.v @@ -32,24 +32,28 @@ THE SOFTWARE. module test_axis_gmii_rx; // Parameters +parameter DATA_WIDTH = 8; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] gmii_rxd = 0; +reg [DATA_WIDTH-1:0] gmii_rxd = 0; reg gmii_rx_dv = 0; reg gmii_rx_er = 0; - +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; reg clk_enable = 1; reg mii_select = 0; // Outputs -wire [7:0] m_axis_tdata; +wire [DATA_WIDTH-1:0] m_axis_tdata; wire m_axis_tvalid; wire m_axis_tlast; -wire m_axis_tuser; +wire [USER_WIDTH-1:0] m_axis_tuser; wire start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -63,6 +67,7 @@ initial begin gmii_rxd, gmii_rx_dv, gmii_rx_er, + ptp_ts, clk_enable, mii_select ); @@ -81,7 +86,12 @@ initial begin $dumpvars(0, test_axis_gmii_rx); end -axis_gmii_rx +axis_gmii_rx #( + .DATA_WIDTH(DATA_WIDTH), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), @@ -92,6 +102,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .ptp_ts(ptp_ts), .clk_enable(clk_enable), .mii_select(mii_select), .start_packet(start_packet), diff --git a/tb/test_axis_gmii_tx.py b/tb/test_axis_gmii_tx.py index f0cd1b5b6..041fef7d0 100755 --- a/tb/test_axis_gmii_tx.py +++ b/tb/test_axis_gmii_tx.py @@ -46,27 +46,37 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + DATA_WIDTH = 8 ENABLE_PADDING = 1 MIN_FRAME_LENGTH = 64 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + PTP_TAG_ENABLE = 0 + PTP_TAG_WIDTH = 16 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) s_axis_tvalid = Signal(bool(0)) s_axis_tlast = Signal(bool(0)) - s_axis_tuser = Signal(bool(0)) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) clk_enable = Signal(bool(1)) mii_select = Signal(bool(0)) ifg_delay = Signal(intbv(0)[8:]) # Outputs s_axis_tready = Signal(bool(0)) - gmii_txd = Signal(intbv(0)[8:]) + gmii_txd = Signal(intbv(0)[DATA_WIDTH:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) + m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) + m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:]) + m_axis_ptp_ts_valid = Signal(bool(0)) start_packet = Signal(bool(0)) error_underflow = Signal(bool(0)) @@ -120,6 +130,11 @@ def bench(): gmii_tx_en=gmii_tx_en, gmii_tx_er=gmii_tx_er, + ptp_ts=ptp_ts, + m_axis_ptp_ts=m_axis_ptp_ts, + m_axis_ptp_ts_tag=m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid=m_axis_ptp_ts_valid, + clk_enable=clk_enable, mii_select=mii_select, diff --git a/tb/test_axis_gmii_tx.v b/tb/test_axis_gmii_tx.v index 99d702451..44ea2a234 100644 --- a/tb/test_axis_gmii_tx.v +++ b/tb/test_axis_gmii_tx.v @@ -32,27 +32,37 @@ THE SOFTWARE. module test_axis_gmii_tx; // Parameters +parameter DATA_WIDTH = 8; parameter ENABLE_PADDING = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_WIDTH = 16; +parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] s_axis_tdata = 0; +reg [DATA_WIDTH-1:0] s_axis_tdata = 0; reg s_axis_tvalid = 0; reg s_axis_tlast = 0; -reg s_axis_tuser = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; reg clk_enable = 1; reg mii_select = 0; reg [7:0] ifg_delay = 0; // Outputs wire s_axis_tready; -wire [7:0] gmii_txd; +wire [DATA_WIDTH-1:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; +wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts; +wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag; +wire m_axis_ptp_ts_valid; wire start_packet; wire error_underflow; @@ -66,6 +76,7 @@ initial begin s_axis_tvalid, s_axis_tlast, s_axis_tuser, + ptp_ts, clk_enable, mii_select, ifg_delay @@ -75,6 +86,9 @@ initial begin gmii_txd, gmii_tx_en, gmii_tx_er, + m_axis_ptp_ts, + m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid, start_packet, error_underflow ); @@ -85,8 +99,14 @@ initial begin end axis_gmii_tx #( + .DATA_WIDTH(DATA_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_ENABLE(PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -99,6 +119,10 @@ UUT ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .ptp_ts(ptp_ts), + .m_axis_ptp_ts(m_axis_ptp_ts), + .m_axis_ptp_ts_tag(m_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(m_axis_ptp_ts_valid), .clk_enable(clk_enable), .mii_select(mii_select), .ifg_delay(ifg_delay), diff --git a/tb/test_axis_xgmii_rx_32.py b/tb/test_axis_xgmii_rx_32.py index 0e12f2aae..7ec9c7e49 100755 --- a/tb/test_axis_xgmii_rx_32.py +++ b/tb/test_axis_xgmii_rx_32.py @@ -46,22 +46,28 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters - + DATA_WIDTH = 32 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) - current_test = Signal(intbv(0)[4:]) + current_test = Signal(intbv(0)[8:]) - xgmii_rxd = Signal(intbv(0x07070707)[32:]) - xgmii_rxc = Signal(intbv(0xf)[4:]) + xgmii_rxd = Signal(intbv(0x07070707)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0xf)[CTRL_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) # Outputs - m_axis_tdata = Signal(intbv(0)[32:]) - m_axis_tkeep = Signal(intbv(0)[4:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) - m_axis_tuser = Signal(bool(0)) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) start_packet = Signal(bool(0)) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -109,6 +115,8 @@ def bench(): m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, + ptp_ts=ptp_ts, + start_packet=start_packet, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs diff --git a/tb/test_axis_xgmii_rx_32.v b/tb/test_axis_xgmii_rx_32.v index 828f034d8..837519434 100644 --- a/tb/test_axis_xgmii_rx_32.v +++ b/tb/test_axis_xgmii_rx_32.v @@ -32,21 +32,28 @@ THE SOFTWARE. module test_axis_xgmii_rx_32; // Parameters +parameter DATA_WIDTH = 32; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; -reg [3:0] current_test = 0; +reg [7:0] current_test = 0; -reg [31:0] xgmii_rxd = 32'h07070707; -reg [3:0] xgmii_rxc = 4'hf; +reg [DATA_WIDTH-1:0] xgmii_rxd = 32'h07070707; +reg [CTRL_WIDTH-1:0] xgmii_rxc = 4'hf; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; // Outputs -wire [31:0] m_axis_tdata; -wire [3:0] m_axis_tkeep; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; -wire m_axis_tuser; +wire [USER_WIDTH-1:0] m_axis_tuser; wire start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -58,7 +65,8 @@ initial begin rst, current_test, xgmii_rxd, - xgmii_rxc + xgmii_rxc, + ptp_ts ); $to_myhdl( m_axis_tdata, @@ -76,7 +84,14 @@ initial begin $dumpvars(0, test_axis_xgmii_rx_32); end -axis_xgmii_rx_32 +axis_xgmii_rx_32 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), @@ -87,6 +102,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .ptp_ts(ptp_ts), .start_packet(start_packet), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs) diff --git a/tb/test_axis_xgmii_rx_64.py b/tb/test_axis_xgmii_rx_64.py index 52bd854db..14d0a9318 100755 --- a/tb/test_axis_xgmii_rx_64.py +++ b/tb/test_axis_xgmii_rx_64.py @@ -46,22 +46,30 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters - + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - xgmii_rxd = Signal(intbv(0x0707070707070707)[64:]) - xgmii_rxc = Signal(intbv(0xff)[8:]) + xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) # Outputs - m_axis_tdata = Signal(intbv(0)[64:]) - m_axis_tkeep = Signal(intbv(0)[8:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) - m_axis_tuser = Signal(bool(0)) + m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) start_packet = Signal(intbv(0)[2:]) error_bad_frame = Signal(bool(0)) error_bad_fcs = Signal(bool(0)) @@ -109,6 +117,8 @@ def bench(): m_axis_tlast=m_axis_tlast, m_axis_tuser=m_axis_tuser, + ptp_ts=ptp_ts, + start_packet=start_packet, error_bad_frame=error_bad_frame, error_bad_fcs=error_bad_fcs diff --git a/tb/test_axis_xgmii_rx_64.v b/tb/test_axis_xgmii_rx_64.v index cee56eb27..f8d7e8b06 100644 --- a/tb/test_axis_xgmii_rx_64.v +++ b/tb/test_axis_xgmii_rx_64.v @@ -32,21 +32,30 @@ THE SOFTWARE. module test_axis_xgmii_rx_64; // Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] xgmii_rxd = 64'h0707070707070707; -reg [7:0] xgmii_rxc = 8'hff; +reg [DATA_WIDTH-1:0] xgmii_rxd = 64'h0707070707070707; +reg [CTRL_WIDTH-1:0] xgmii_rxc = 8'hff; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; // Outputs -wire [63:0] m_axis_tdata; -wire [7:0] m_axis_tkeep; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; -wire m_axis_tuser; +wire [USER_WIDTH-1:0] m_axis_tuser; wire [1:0] start_packet; wire error_bad_frame; wire error_bad_fcs; @@ -58,7 +67,8 @@ initial begin rst, current_test, xgmii_rxd, - xgmii_rxc + xgmii_rxc, + ptp_ts ); $to_myhdl( m_axis_tdata, @@ -76,7 +86,16 @@ initial begin $dumpvars(0, test_axis_xgmii_rx_64); end -axis_xgmii_rx_64 +axis_xgmii_rx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(USER_WIDTH) +) UUT ( .clk(clk), .rst(rst), @@ -87,6 +106,7 @@ UUT ( .m_axis_tvalid(m_axis_tvalid), .m_axis_tlast(m_axis_tlast), .m_axis_tuser(m_axis_tuser), + .ptp_ts(ptp_ts), .start_packet(start_packet), .error_bad_frame(error_bad_frame), .error_bad_fcs(error_bad_fcs) diff --git a/tb/test_axis_xgmii_tx_32.py b/tb/test_axis_xgmii_tx_32.py index 9fca431b5..41dc13631 100755 --- a/tb/test_axis_xgmii_tx_32.py +++ b/tb/test_axis_xgmii_tx_32.py @@ -46,25 +46,38 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + DATA_WIDTH = 32 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) ENABLE_PADDING = 1 + ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + PTP_TAG_ENABLE = 0 + PTP_TAG_WIDTH = 16 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) - current_test = Signal(intbv(0)[4:]) + current_test = Signal(intbv(0)[8:]) - s_axis_tdata = Signal(intbv(0)[32:]) - s_axis_tkeep = Signal(intbv(0)[4:]) + 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)) - s_axis_tuser = Signal(bool(0)) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs s_axis_tready = Signal(bool(0)) - xgmii_txd = Signal(intbv(0x07070707)[32:]) - xgmii_txc = Signal(intbv(0xf)[4:]) + xgmii_txd = Signal(intbv(0x07070707)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0xf)[CTRL_WIDTH:]) + m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) + m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:]) + m_axis_ptp_ts_valid = Signal(bool(0)) start_packet = Signal(bool(0)) error_underflow = Signal(bool(0)) @@ -116,6 +129,11 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + ptp_ts=ptp_ts, + m_axis_ptp_ts=m_axis_ptp_ts, + m_axis_ptp_ts_tag=m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid=m_axis_ptp_ts_valid, + ifg_delay=ifg_delay, start_packet=start_packet, diff --git a/tb/test_axis_xgmii_tx_32.v b/tb/test_axis_xgmii_tx_32.v index 244bc341d..7af249a4e 100644 --- a/tb/test_axis_xgmii_tx_32.v +++ b/tb/test_axis_xgmii_tx_32.v @@ -32,25 +32,38 @@ THE SOFTWARE. module test_axis_xgmii_tx_32; // Parameters +parameter DATA_WIDTH = 32; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_WIDTH = 16; +parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; -reg [3:0] current_test = 0; +reg [7:0] current_test = 0; -reg [31:0] s_axis_tdata = 0; -reg [3:0] s_axis_tkeep = 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; -reg s_axis_tuser = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; reg [7:0] ifg_delay = 0; // Outputs wire s_axis_tready; -wire [31:0] xgmii_txd; -wire [3:0] xgmii_txc; +wire [DATA_WIDTH-1:0] xgmii_txd; +wire [CTRL_WIDTH-1:0] xgmii_txc; +wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts; +wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag; +wire m_axis_ptp_ts_valid; wire start_packet; wire error_underflow; @@ -65,12 +78,16 @@ initial begin s_axis_tvalid, s_axis_tlast, s_axis_tuser, + ptp_ts, ifg_delay ); $to_myhdl( s_axis_tready, xgmii_txd, xgmii_txc, + m_axis_ptp_ts, + m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid, start_packet, error_underflow ); @@ -81,8 +98,17 @@ initial begin end axis_xgmii_tx_32 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_ENABLE(PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -95,6 +121,10 @@ UUT ( .s_axis_tuser(s_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .ptp_ts(ptp_ts), + .m_axis_ptp_ts(m_axis_ptp_ts), + .m_axis_ptp_ts_tag(m_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(m_axis_ptp_ts_valid), .ifg_delay(ifg_delay), .start_packet(start_packet), .error_underflow(error_underflow) diff --git a/tb/test_axis_xgmii_tx_64.py b/tb/test_axis_xgmii_tx_64.py index 10d178544..0845a88a0 100755 --- a/tb/test_axis_xgmii_tx_64.py +++ b/tb/test_axis_xgmii_tx_64.py @@ -46,25 +46,40 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + DATA_WIDTH = 64 + KEEP_WIDTH = (DATA_WIDTH/8) + CTRL_WIDTH = (DATA_WIDTH/8) ENABLE_PADDING = 1 + ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + PTP_TS_ENABLE = 0 + PTP_TS_WIDTH = 96 + PTP_TAG_ENABLE = 0 + PTP_TAG_WIDTH = 16 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - s_axis_tdata = Signal(intbv(0)[64:]) - s_axis_tkeep = 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)) - s_axis_tuser = Signal(bool(0)) + s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) + ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs s_axis_tready = Signal(bool(0)) - xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) - xgmii_txc = Signal(intbv(0xff)[8:]) + xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) + xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:]) + m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:]) + m_axis_ptp_ts_valid = Signal(bool(0)) start_packet = Signal(intbv(0)[2:]) error_underflow = Signal(bool(0)) @@ -116,6 +131,11 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + ptp_ts=ptp_ts, + m_axis_ptp_ts=m_axis_ptp_ts, + m_axis_ptp_ts_tag=m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid=m_axis_ptp_ts_valid, + ifg_delay=ifg_delay, start_packet=start_packet, diff --git a/tb/test_axis_xgmii_tx_64.v b/tb/test_axis_xgmii_tx_64.v index 71ae92778..8fdc43426 100644 --- a/tb/test_axis_xgmii_tx_64.v +++ b/tb/test_axis_xgmii_tx_64.v @@ -32,25 +32,40 @@ THE SOFTWARE. module test_axis_xgmii_tx_64; // Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_WIDTH = (DATA_WIDTH/8); +parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter ENABLE_PADDING = 1; +parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter PTP_TS_ENABLE = 0; +parameter PTP_TS_WIDTH = 96; +parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_WIDTH = 16; +parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] s_axis_tdata = 0; -reg [7:0] s_axis_tkeep = 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; -reg s_axis_tuser = 0; +reg [USER_WIDTH-1:0] s_axis_tuser = 0; +reg [PTP_TS_WIDTH-1:0] ptp_ts = 0; reg [7:0] ifg_delay = 0; // Outputs wire s_axis_tready; -wire [63:0] xgmii_txd; -wire [7:0] xgmii_txc; +wire [DATA_WIDTH-1:0] xgmii_txd; +wire [CTRL_WIDTH-1:0] xgmii_txc; +wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts; +wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag; +wire m_axis_ptp_ts_valid; wire [1:0] start_packet; wire error_underflow; @@ -65,12 +80,16 @@ initial begin s_axis_tvalid, s_axis_tlast, s_axis_tuser, + ptp_ts, ifg_delay ); $to_myhdl( s_axis_tready, xgmii_txd, xgmii_txc, + m_axis_ptp_ts, + m_axis_ptp_ts_tag, + m_axis_ptp_ts_valid, start_packet, error_underflow ); @@ -81,8 +100,19 @@ initial begin end axis_xgmii_tx_64 #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_WIDTH(KEEP_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_ENABLE(PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .USER_WIDTH(USER_WIDTH) ) UUT ( .clk(clk), @@ -95,6 +125,10 @@ UUT ( .s_axis_tuser(s_axis_tuser), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .ptp_ts(ptp_ts), + .m_axis_ptp_ts(m_axis_ptp_ts), + .m_axis_ptp_ts_tag(m_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(m_axis_ptp_ts_valid), .ifg_delay(ifg_delay), .start_packet(start_packet), .error_underflow(error_underflow) diff --git a/tb/test_eth_mac_10g_32.py b/tb/test_eth_mac_10g_32.py index 43c5b9ba1..ee290e30c 100755 --- a/tb/test_eth_mac_10g_32.py +++ b/tb/test_eth_mac_10g_32.py @@ -54,6 +54,14 @@ def bench(): ENABLE_PADDING = 1 ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + TX_PTP_TS_ENABLE = 0 + TX_PTP_TS_WIDTH = 96 + TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_WIDTH = 16 + RX_PTP_TS_ENABLE = 0 + RX_PTP_TS_WIDTH = 96 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) @@ -68,9 +76,11 @@ def bench(): tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tvalid = Signal(bool(0)) tx_axis_tlast = Signal(bool(0)) - tx_axis_tuser = Signal(bool(0)) + tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:]) xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs @@ -79,9 +89,12 @@ def bench(): rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tvalid = Signal(bool(0)) rx_axis_tlast = Signal(bool(0)) - rx_axis_tuser = Signal(bool(0)) + rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:]) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:]) + tx_axis_ptp_ts_valid = Signal(bool(0)) tx_start_packet = Signal(intbv(0)[2:]) tx_error_underflow = Signal(bool(0)) rx_start_packet = Signal(intbv(0)[2:]) @@ -173,6 +186,12 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + tx_ptp_ts=tx_ptp_ts, + rx_ptp_ts=rx_ptp_ts, + tx_axis_ptp_ts=tx_axis_ptp_ts, + tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid, + tx_start_packet=tx_start_packet, tx_error_underflow=tx_error_underflow, rx_start_packet=rx_start_packet, diff --git a/tb/test_eth_mac_10g_32.v b/tb/test_eth_mac_10g_32.v index e4efdf3e8..0a98ef33e 100644 --- a/tb/test_eth_mac_10g_32.v +++ b/tb/test_eth_mac_10g_32.v @@ -38,6 +38,14 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter ENABLE_PADDING = 1; parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter TX_PTP_TS_ENABLE = 0; +parameter TX_PTP_TS_WIDTH = 96; +parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_WIDTH = 16; +parameter RX_PTP_TS_ENABLE = 0; +parameter RX_PTP_TS_WIDTH = 96; +parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; @@ -52,9 +60,11 @@ reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg tx_axis_tvalid = 0; reg tx_axis_tlast = 0; -reg tx_axis_tuser = 0; +reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0; reg [DATA_WIDTH-1:0] xgmii_rxd = 0; reg [CTRL_WIDTH-1:0] xgmii_rxc = 0; +reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0; +reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0; reg [7:0] ifg_delay = 0; // Outputs @@ -63,9 +73,12 @@ wire [DATA_WIDTH-1:0] rx_axis_tdata; wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire rx_axis_tvalid; wire rx_axis_tlast; -wire rx_axis_tuser; +wire [RX_USER_WIDTH-1:0] rx_axis_tuser; wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; +wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts; +wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag; +wire tx_axis_ptp_ts_valid; wire [1:0] tx_start_packet; wire tx_error_underflow; wire [1:0] rx_start_packet; @@ -89,6 +102,8 @@ initial begin tx_axis_tuser, xgmii_rxd, xgmii_rxc, + tx_ptp_ts, + rx_ptp_ts, ifg_delay ); $to_myhdl( @@ -100,6 +115,9 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, + tx_axis_ptp_ts, + tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid, tx_start_packet, tx_error_underflow, rx_start_packet, @@ -118,7 +136,15 @@ eth_mac_10g #( .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .TX_USER_WIDTH(TX_USER_WIDTH), + .RX_USER_WIDTH(RX_USER_WIDTH) ) UUT ( .rx_clk(rx_clk), @@ -140,6 +166,11 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), + .tx_axis_ptp_ts(tx_axis_ptp_ts), + .tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), .rx_start_packet(rx_start_packet), diff --git a/tb/test_eth_mac_10g_64.py b/tb/test_eth_mac_10g_64.py index ccbc7bed4..2662ed6c6 100755 --- a/tb/test_eth_mac_10g_64.py +++ b/tb/test_eth_mac_10g_64.py @@ -54,6 +54,16 @@ def bench(): ENABLE_PADDING = 1 ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + TX_PTP_TS_ENABLE = 0 + TX_PTP_TS_WIDTH = 96 + TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_WIDTH = 16 + RX_PTP_TS_ENABLE = 0 + RX_PTP_TS_WIDTH = 96 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) @@ -68,9 +78,11 @@ def bench(): tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tvalid = Signal(bool(0)) tx_axis_tlast = Signal(bool(0)) - tx_axis_tuser = Signal(bool(0)) + tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:]) xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) # Outputs @@ -79,9 +91,12 @@ def bench(): rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tvalid = Signal(bool(0)) rx_axis_tlast = Signal(bool(0)) - rx_axis_tuser = Signal(bool(0)) + rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:]) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) + tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:]) + tx_axis_ptp_ts_valid = Signal(bool(0)) tx_start_packet = Signal(intbv(0)[2:]) tx_error_underflow = Signal(bool(0)) rx_start_packet = Signal(intbv(0)[2:]) @@ -173,6 +188,12 @@ def bench(): xgmii_txd=xgmii_txd, xgmii_txc=xgmii_txc, + tx_ptp_ts=tx_ptp_ts, + rx_ptp_ts=rx_ptp_ts, + tx_axis_ptp_ts=tx_axis_ptp_ts, + tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid, + tx_start_packet=tx_start_packet, tx_error_underflow=tx_error_underflow, rx_start_packet=rx_start_packet, diff --git a/tb/test_eth_mac_10g_64.v b/tb/test_eth_mac_10g_64.v index 10ef31f8a..db0585b3b 100644 --- a/tb/test_eth_mac_10g_64.v +++ b/tb/test_eth_mac_10g_64.v @@ -38,6 +38,16 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8); parameter ENABLE_PADDING = 1; parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter TX_PTP_TS_ENABLE = 0; +parameter TX_PTP_TS_WIDTH = 96; +parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_WIDTH = 16; +parameter RX_PTP_TS_ENABLE = 0; +parameter RX_PTP_TS_WIDTH = 96; +parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; @@ -52,9 +62,11 @@ reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg tx_axis_tvalid = 0; reg tx_axis_tlast = 0; -reg tx_axis_tuser = 0; +reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0; reg [DATA_WIDTH-1:0] xgmii_rxd = 0; reg [CTRL_WIDTH-1:0] xgmii_rxc = 0; +reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0; +reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0; reg [7:0] ifg_delay = 0; // Outputs @@ -63,9 +75,12 @@ wire [DATA_WIDTH-1:0] rx_axis_tdata; wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire rx_axis_tvalid; wire rx_axis_tlast; -wire rx_axis_tuser; +wire [RX_USER_WIDTH-1:0] rx_axis_tuser; wire [DATA_WIDTH-1:0] xgmii_txd; wire [CTRL_WIDTH-1:0] xgmii_txc; +wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts; +wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag; +wire tx_axis_ptp_ts_valid; wire [1:0] tx_start_packet; wire tx_error_underflow; wire [1:0] rx_start_packet; @@ -89,6 +104,8 @@ initial begin tx_axis_tuser, xgmii_rxd, xgmii_rxc, + tx_ptp_ts, + rx_ptp_ts, ifg_delay ); $to_myhdl( @@ -100,6 +117,9 @@ initial begin rx_axis_tuser, xgmii_txd, xgmii_txc, + tx_axis_ptp_ts, + tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid, tx_start_packet, tx_error_underflow, rx_start_packet, @@ -118,7 +138,17 @@ eth_mac_10g #( .CTRL_WIDTH(CTRL_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .TX_USER_WIDTH(TX_USER_WIDTH), + .RX_USER_WIDTH(RX_USER_WIDTH) ) UUT ( .rx_clk(rx_clk), @@ -140,6 +170,11 @@ UUT ( .xgmii_rxc(xgmii_rxc), .xgmii_txd(xgmii_txd), .xgmii_txc(xgmii_txc), + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), + .tx_axis_ptp_ts(tx_axis_ptp_ts), + .tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), .rx_start_packet(rx_start_packet), diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index b1cd8816c..8a978e8d2 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -48,8 +48,17 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): # Parameters + DATA_WIDTH = 8 ENABLE_PADDING = 1 MIN_FRAME_LENGTH = 64 + TX_PTP_TS_ENABLE = 0 + TX_PTP_TS_WIDTH = 96 + TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_WIDTH = 16 + RX_PTP_TS_ENABLE = 0 + RX_PTP_TS_WIDTH = 96 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) @@ -60,13 +69,15 @@ def bench(): rx_rst = Signal(bool(0)) tx_clk = Signal(bool(0)) tx_rst = Signal(bool(0)) - tx_axis_tdata = Signal(intbv(0)[8:]) + tx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) tx_axis_tvalid = Signal(bool(0)) tx_axis_tlast = Signal(bool(0)) - tx_axis_tuser = Signal(bool(0)) - gmii_rxd = Signal(intbv(0)[8:]) + tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:]) + gmii_rxd = Signal(intbv(0)[DATA_WIDTH:]) gmii_rx_dv = Signal(bool(0)) gmii_rx_er = Signal(bool(0)) + tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:]) rx_clk_enable = Signal(bool(1)) tx_clk_enable = Signal(bool(1)) rx_mii_select = Signal(bool(0)) @@ -75,13 +86,16 @@ def bench(): # Outputs tx_axis_tready = Signal(bool(0)) - rx_axis_tdata = Signal(intbv(0)[8:]) + rx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) rx_axis_tvalid = Signal(bool(0)) rx_axis_tlast = Signal(bool(0)) - rx_axis_tuser = Signal(bool(0)) - gmii_txd = Signal(intbv(0)[8:]) + rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:]) + gmii_txd = Signal(intbv(0)[DATA_WIDTH:]) gmii_tx_en = Signal(bool(0)) gmii_tx_er = Signal(bool(0)) + tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:]) + tx_axis_ptp_ts_valid = Signal(bool(0)) tx_start_packet = Signal(bool(0)) tx_error_underflow = Signal(bool(0)) rx_start_packet = Signal(bool(0)) @@ -177,6 +191,12 @@ def bench(): gmii_tx_en=gmii_tx_en, gmii_tx_er=gmii_tx_er, + tx_ptp_ts=tx_ptp_ts, + rx_ptp_ts=rx_ptp_ts, + tx_axis_ptp_ts=tx_axis_ptp_ts, + tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid, + rx_clk_enable=rx_clk_enable, tx_clk_enable=tx_clk_enable, diff --git a/tb/test_eth_mac_1g.v b/tb/test_eth_mac_1g.v index 4f92c1e78..25b63dbb2 100644 --- a/tb/test_eth_mac_1g.v +++ b/tb/test_eth_mac_1g.v @@ -32,8 +32,17 @@ THE SOFTWARE. module test_eth_mac_1g; // Parameters +parameter DATA_WIDTH = 8; parameter ENABLE_PADDING = 1; parameter MIN_FRAME_LENGTH = 64; +parameter TX_PTP_TS_ENABLE = 0; +parameter TX_PTP_TS_WIDTH = 96; +parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_WIDTH = 16; +parameter RX_PTP_TS_ENABLE = 0; +parameter RX_PTP_TS_WIDTH = 96; +parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; // Inputs reg clk = 0; @@ -44,13 +53,15 @@ reg rx_clk = 0; reg rx_rst = 0; reg tx_clk = 0; reg tx_rst = 0; -reg [7:0] tx_axis_tdata = 0; +reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; reg tx_axis_tvalid = 0; reg tx_axis_tlast = 0; -reg tx_axis_tuser = 0; -reg [7:0] gmii_rxd = 0; +reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0; +reg [DATA_WIDTH-1:0] gmii_rxd = 0; reg gmii_rx_dv = 0; reg gmii_rx_er = 0; +reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0; +reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0; reg rx_clk_enable = 1; reg tx_clk_enable = 1; reg rx_mii_select = 0; @@ -59,13 +70,16 @@ reg [7:0] ifg_delay = 0; // Outputs wire tx_axis_tready; -wire [7:0] rx_axis_tdata; +wire [DATA_WIDTH-1:0] rx_axis_tdata; wire rx_axis_tvalid; wire rx_axis_tlast; -wire rx_axis_tuser; -wire [7:0] gmii_txd; +wire [RX_USER_WIDTH-1:0] rx_axis_tuser; +wire [DATA_WIDTH-1:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; +wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts; +wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag; +wire tx_axis_ptp_ts_valid; wire tx_start_packet; wire tx_error_underflow; wire rx_start_packet; @@ -89,6 +103,8 @@ initial begin gmii_rxd, gmii_rx_dv, gmii_rx_er, + tx_ptp_ts, + rx_ptp_ts, rx_clk_enable, tx_clk_enable, rx_mii_select, @@ -104,6 +120,9 @@ initial begin gmii_txd, gmii_tx_en, gmii_tx_er, + tx_axis_ptp_ts, + tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid, tx_start_packet, tx_error_underflow, rx_start_packet, @@ -117,8 +136,17 @@ initial begin end eth_mac_1g #( + .DATA_WIDTH(DATA_WIDTH), .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .TX_USER_WIDTH(TX_USER_WIDTH), + .RX_USER_WIDTH(RX_USER_WIDTH) ) UUT ( .rx_clk(rx_clk), @@ -140,6 +168,11 @@ UUT ( .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er), + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), + .tx_axis_ptp_ts(tx_axis_ptp_ts), + .tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .rx_clk_enable(rx_clk_enable), .tx_clk_enable(tx_clk_enable), .rx_mii_select(rx_mii_select), diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py index e5156b0c9..255aa6f0f 100755 --- a/tb/test_eth_mac_phy_10g.py +++ b/tb/test_eth_mac_phy_10g.py @@ -62,6 +62,16 @@ def bench(): ENABLE_PADDING = 1 ENABLE_DIC = 1 MIN_FRAME_LENGTH = 64 + PTP_PERIOD_NS = 0x6 + PTP_PERIOD_FNS = 0x6666 + TX_PTP_TS_ENABLE = 0 + TX_PTP_TS_WIDTH = 96 + TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_WIDTH = 16 + RX_PTP_TS_ENABLE = 0 + RX_PTP_TS_WIDTH = 96 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 PRBS31_ENABLE = 1 @@ -81,9 +91,11 @@ def bench(): tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tvalid = Signal(bool(0)) tx_axis_tlast = Signal(bool(0)) - tx_axis_tuser = Signal(bool(0)) + tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:]) serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) + tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:]) ifg_delay = Signal(intbv(0)[8:]) tx_prbs31_enable = Signal(bool(0)) rx_prbs31_enable = Signal(bool(0)) @@ -97,10 +109,13 @@ def bench(): rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tvalid = Signal(bool(0)) rx_axis_tlast = Signal(bool(0)) - rx_axis_tuser = Signal(bool(0)) + rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:]) serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) serdes_rx_bitslip = Signal(bool(0)) + tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:]) + tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:]) + tx_axis_ptp_ts_valid = Signal(bool(0)) tx_start_packet = Signal(intbv(0)[2:]) tx_error_underflow = Signal(bool(0)) rx_start_packet = Signal(intbv(0)[2:]) @@ -189,6 +204,11 @@ def bench(): serdes_rx_data=serdes_rx_data, serdes_rx_hdr=serdes_rx_hdr, serdes_rx_bitslip=serdes_rx_bitslip, + tx_ptp_ts=tx_ptp_ts, + rx_ptp_ts=rx_ptp_ts, + tx_axis_ptp_ts=tx_axis_ptp_ts, + tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid, tx_start_packet=tx_start_packet, tx_error_underflow=tx_error_underflow, rx_start_packet=rx_start_packet, diff --git a/tb/test_eth_mac_phy_10g.v b/tb/test_eth_mac_phy_10g.v index 77f85468d..6a73719e9 100644 --- a/tb/test_eth_mac_phy_10g.v +++ b/tb/test_eth_mac_phy_10g.v @@ -39,6 +39,16 @@ parameter HDR_WIDTH = (DATA_WIDTH/32); parameter ENABLE_PADDING = 1; parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; +parameter PTP_PERIOD_NS = 4'h6; +parameter PTP_PERIOD_FNS = 16'h6666; +parameter TX_PTP_TS_ENABLE = 0; +parameter TX_PTP_TS_WIDTH = 96; +parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_WIDTH = 16; +parameter RX_PTP_TS_ENABLE = 0; +parameter RX_PTP_TS_WIDTH = 96; +parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; parameter PRBS31_ENABLE = 1; @@ -58,9 +68,11 @@ reg [DATA_WIDTH-1:0] tx_axis_tdata = 0; reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg tx_axis_tvalid = 0; reg tx_axis_tlast = 0; -reg tx_axis_tuser = 0; +reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0; reg [DATA_WIDTH-1:0] serdes_rx_data = 0; reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; +reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0; +reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0; reg [7:0] ifg_delay = 0; reg tx_prbs31_enable = 0; reg rx_prbs31_enable = 0; @@ -71,10 +83,13 @@ wire [DATA_WIDTH-1:0] rx_axis_tdata; wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire rx_axis_tvalid; wire rx_axis_tlast; -wire rx_axis_tuser; +wire [RX_USER_WIDTH-1:0] rx_axis_tuser; wire [DATA_WIDTH-1:0] serdes_tx_data; wire [HDR_WIDTH-1:0] serdes_tx_hdr; wire serdes_rx_bitslip; +wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts; +wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag; +wire tx_axis_ptp_ts_valid; wire [1:0] tx_start_packet; wire tx_error_underflow; wire [1:0] rx_start_packet; @@ -102,6 +117,8 @@ initial begin tx_axis_tuser, serdes_rx_data, serdes_rx_hdr, + tx_ptp_ts, + rx_ptp_ts, ifg_delay, tx_prbs31_enable, rx_prbs31_enable @@ -116,6 +133,9 @@ initial begin serdes_tx_data, serdes_tx_hdr, serdes_rx_bitslip, + tx_axis_ptp_ts, + tx_axis_ptp_ts_tag, + tx_axis_ptp_ts_valid, tx_start_packet, tx_error_underflow, rx_error_count, @@ -140,6 +160,16 @@ eth_mac_phy_10g #( .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE), + .TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH), + .TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE), + .RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH), + .TX_USER_WIDTH(TX_USER_WIDTH), + .RX_USER_WIDTH(RX_USER_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), @@ -167,6 +197,11 @@ UUT ( .serdes_rx_data(serdes_rx_data), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_bitslip(serdes_rx_bitslip), + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), + .tx_axis_ptp_ts(tx_axis_ptp_ts), + .tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), .tx_start_packet(tx_start_packet), .tx_error_underflow(tx_error_underflow), .rx_start_packet(rx_start_packet), From 2794c315e840562a1facdb87b4bb34740928cfc5 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 8 Jun 2019 17:36:09 -0700 Subject: [PATCH 571/617] Fix synthesizer complaints --- rtl/axis_baser_rx_64.v | 4 ++-- rtl/axis_baser_tx_64.v | 4 ++-- rtl/axis_xgmii_rx_64.v | 4 ++-- rtl/axis_xgmii_tx_64.v | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rtl/axis_baser_rx_64.v b/rtl/axis_baser_rx_64.v index e37b8294c..93d17b397 100644 --- a/rtl/axis_baser_rx_64.v +++ b/rtl/axis_baser_rx_64.v @@ -545,10 +545,10 @@ always @(posedge clk) begin end end else if (encoded_rx_hdr == SYNC_CTRL && (encoded_rx_data[7:0] == BLOCK_TYPE_START_4 || encoded_rx_data[7:0] == BLOCK_TYPE_OS_START)) begin if (PTP_TS_WIDTH == 96) begin - ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); ptp_ts_reg[95:48] <= ptp_ts[95:48]; end else begin - ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + ptp_ts_reg <= ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); end end diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v index 4487053a2..f76704b99 100644 --- a/rtl/axis_baser_tx_64.v +++ b/rtl/axis_baser_tx_64.v @@ -532,10 +532,10 @@ always @* begin // need to send more idles - swap lanes swap_lanes = 1'b1; if (PTP_TS_WIDTH == 96) begin - m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; end else begin - m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + m_axis_ptp_ts_next = ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); end m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; m_axis_ptp_ts_valid_int_next = 1'b1; diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index 45838e0ee..f0790ce33 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -516,10 +516,10 @@ always @(posedge clk) begin end end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin if (PTP_TS_WIDTH == 96) begin - ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); ptp_ts_reg[95:48] <= ptp_ts[95:48]; end else begin - ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + ptp_ts_reg <= ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); end end diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index 67f30ce87..6bb73a1a6 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -479,10 +479,10 @@ always @* begin // need to send more idles - swap lanes swap_lanes = 1'b1; if (PTP_TS_WIDTH == 96) begin - m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; end else begin - m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5; + m_axis_ptp_ts_next = ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); end m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; m_axis_ptp_ts_valid_int_next = 1'b1; From ccc15324a6aea80d6790a0f4f4bc125e8d5bfa9c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 9 Jun 2019 18:46:49 -0700 Subject: [PATCH 572/617] Fix bad frame mask --- rtl/axis_async_fifo.v | 2 +- rtl/axis_fifo.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index 659b2698d..d1b9fb4a4 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -302,7 +302,7 @@ always @* begin wr_ptr_cur_gray_next = wr_ptr_cur_next ^ (wr_ptr_cur_next >> 1); if (s_axis_tlast) begin // end of frame - if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin + if (DROP_BAD_FRAME && USER_BAD_FRAME_MASK & ~(s_axis_tuser ^ USER_BAD_FRAME_VALUE)) begin // bad packet, reset write pointer wr_ptr_cur_next = wr_ptr_reg; wr_ptr_cur_gray_next = wr_ptr_cur_next ^ (wr_ptr_cur_next >> 1); diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index 83d89900d..d6329b1d9 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -207,7 +207,7 @@ always @* begin wr_ptr_cur_next = wr_ptr_cur_reg + 1; if (s_axis_tlast) begin // end of frame - if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin + if (DROP_BAD_FRAME && USER_BAD_FRAME_MASK & ~(s_axis_tuser ^ USER_BAD_FRAME_VALUE)) begin // bad packet, reset write pointer wr_ptr_cur_next = wr_ptr_reg; bad_frame_next = 1'b1; From 6eff2f003068320bb0243fb38864d28293be589e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 9 Jun 2019 22:03:24 -0700 Subject: [PATCH 573/617] Decouple transmit PTP tag enable and transmit PTP timestamp enable --- rtl/axis_baser_tx_64.v | 8 ++++---- rtl/axis_gmii_tx.v | 8 ++++---- rtl/axis_xgmii_tx_32.v | 8 ++++---- rtl/axis_xgmii_tx_64.v | 8 ++++---- rtl/eth_mac_10g.v | 4 ++-- rtl/eth_mac_1g.v | 4 ++-- rtl/eth_mac_phy_10g.v | 4 ++-- rtl/eth_mac_phy_10g_tx.v | 4 ++-- tb/test_axis_baser_tx_64.py | 4 ++-- tb/test_axis_baser_tx_64.v | 4 ++-- tb/test_axis_gmii_tx.py | 4 ++-- tb/test_axis_gmii_tx.v | 4 ++-- tb/test_axis_xgmii_tx_32.py | 4 ++-- tb/test_axis_xgmii_tx_32.v | 4 ++-- tb/test_axis_xgmii_tx_64.py | 4 ++-- tb/test_axis_xgmii_tx_64.v | 4 ++-- tb/test_eth_mac_10g_32.py | 4 ++-- tb/test_eth_mac_10g_32.v | 4 ++-- tb/test_eth_mac_10g_64.py | 4 ++-- tb/test_eth_mac_10g_64.v | 4 ++-- tb/test_eth_mac_1g.py | 4 ++-- tb/test_eth_mac_1g.v | 4 ++-- tb/test_eth_mac_phy_10g.py | 4 ++-- tb/test_eth_mac_phy_10g.v | 4 ++-- 24 files changed, 56 insertions(+), 56 deletions(-) diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v index f76704b99..fcaa8ea15 100644 --- a/rtl/axis_baser_tx_64.v +++ b/rtl/axis_baser_tx_64.v @@ -41,9 +41,9 @@ module axis_baser_tx_64 # parameter PTP_PERIOD_FNS = 16'h6666, parameter PTP_TS_ENABLE = 0, parameter PTP_TS_WIDTH = 96, - parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_ENABLE = PTP_TS_ENABLE, parameter PTP_TAG_WIDTH = 16, - parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 + parameter USER_WIDTH = (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( input wire clk, @@ -238,8 +238,8 @@ assign encoded_tx_data = encoded_tx_data_reg; assign encoded_tx_hdr = encoded_tx_hdr_reg; assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; -assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; -assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; +assign m_axis_ptp_ts_tag = PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE || PTP_TAG_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index e16ef2ed8..de4c43998 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -36,9 +36,9 @@ module axis_gmii_tx # parameter MIN_FRAME_LENGTH = 64, parameter PTP_TS_ENABLE = 0, parameter PTP_TS_WIDTH = 96, - parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_ENABLE = PTP_TS_ENABLE, parameter PTP_TAG_WIDTH = 16, - parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 + parameter USER_WIDTH = (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( input wire clk, @@ -144,8 +144,8 @@ assign gmii_tx_en = gmii_tx_en_reg; assign gmii_tx_er = gmii_tx_er_reg; assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; -assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; -assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; +assign m_axis_ptp_ts_tag = PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE || PTP_TAG_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index 0eae6d15e..ead5affff 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -39,9 +39,9 @@ module axis_xgmii_tx_32 # parameter MIN_FRAME_LENGTH = 64, parameter PTP_TS_ENABLE = 0, parameter PTP_TS_WIDTH = 96, - parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_ENABLE = PTP_TS_ENABLE, parameter PTP_TAG_WIDTH = 16, - parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 + parameter USER_WIDTH = (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( input wire clk, @@ -171,8 +171,8 @@ assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; -assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; -assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; +assign m_axis_ptp_ts_tag = PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE || PTP_TAG_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index 6bb73a1a6..fb1c9b394 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -41,9 +41,9 @@ module axis_xgmii_tx_64 # parameter PTP_PERIOD_FNS = 16'h6666, parameter PTP_TS_ENABLE = 0, parameter PTP_TS_WIDTH = 96, - parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_ENABLE = PTP_TS_ENABLE, parameter PTP_TAG_WIDTH = 16, - parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 + parameter USER_WIDTH = (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1 ) ( input wire clk, @@ -183,8 +183,8 @@ assign xgmii_txd = xgmii_txd_reg; assign xgmii_txc = xgmii_txc_reg; assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; -assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; -assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; +assign m_axis_ptp_ts_tag = PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE || PTP_TAG_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; assign start_packet = start_packet_reg; assign error_underflow = error_underflow_reg; diff --git a/rtl/eth_mac_10g.v b/rtl/eth_mac_10g.v index 9601a2e13..187389bce 100644 --- a/rtl/eth_mac_10g.v +++ b/rtl/eth_mac_10g.v @@ -41,11 +41,11 @@ module eth_mac_10g # parameter PTP_PERIOD_FNS = 16'h6666, parameter TX_PTP_TS_ENABLE = 0, parameter TX_PTP_TS_WIDTH = 96, - parameter TX_PTP_TAG_ENABLE = 0, + parameter TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE, parameter TX_PTP_TAG_WIDTH = 16, parameter RX_PTP_TS_ENABLE = 0, parameter RX_PTP_TS_WIDTH = 96, - parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, + parameter TX_USER_WIDTH = (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1 ) ( diff --git a/rtl/eth_mac_1g.v b/rtl/eth_mac_1g.v index 7eefcdf3f..4f1075c19 100644 --- a/rtl/eth_mac_1g.v +++ b/rtl/eth_mac_1g.v @@ -36,11 +36,11 @@ module eth_mac_1g # parameter MIN_FRAME_LENGTH = 64, parameter TX_PTP_TS_ENABLE = 0, parameter TX_PTP_TS_WIDTH = 96, - parameter TX_PTP_TAG_ENABLE = 0, + parameter TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE, parameter TX_PTP_TAG_WIDTH = 16, parameter RX_PTP_TS_ENABLE = 0, parameter RX_PTP_TS_WIDTH = 96, - parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, + parameter TX_USER_WIDTH = (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1 ) ( diff --git a/rtl/eth_mac_phy_10g.v b/rtl/eth_mac_phy_10g.v index a1b16ade1..1811e5f79 100644 --- a/rtl/eth_mac_phy_10g.v +++ b/rtl/eth_mac_phy_10g.v @@ -42,11 +42,11 @@ module eth_mac_phy_10g # parameter PTP_PERIOD_FNS = 16'h6666, parameter TX_PTP_TS_ENABLE = 0, parameter TX_PTP_TS_WIDTH = 96, - parameter TX_PTP_TAG_ENABLE = 0, + parameter TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE, parameter TX_PTP_TAG_WIDTH = 16, parameter RX_PTP_TS_ENABLE = 0, parameter RX_PTP_TS_WIDTH = 96, - parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, + parameter TX_USER_WIDTH = (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, diff --git a/rtl/eth_mac_phy_10g_tx.v b/rtl/eth_mac_phy_10g_tx.v index 9a497e2d5..4b80b8cc5 100644 --- a/rtl/eth_mac_phy_10g_tx.v +++ b/rtl/eth_mac_phy_10g_tx.v @@ -42,9 +42,9 @@ module eth_mac_phy_10g_tx # parameter PTP_PERIOD_FNS = 16'h6666, parameter PTP_TS_ENABLE = 0, parameter PTP_TS_WIDTH = 96, - parameter PTP_TAG_ENABLE = 0, + parameter PTP_TAG_ENABLE = PTP_TS_ENABLE, parameter PTP_TAG_WIDTH = 16, - parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1, + parameter USER_WIDTH = (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0 diff --git a/tb/test_axis_baser_tx_64.py b/tb/test_axis_baser_tx_64.py index f807214ef..62269ecb6 100755 --- a/tb/test_axis_baser_tx_64.py +++ b/tb/test_axis_baser_tx_64.py @@ -56,9 +56,9 @@ def bench(): PTP_PERIOD_FNS = 0x6666 PTP_TS_ENABLE = 0 PTP_TS_WIDTH = 96 - PTP_TAG_ENABLE = 0 + PTP_TAG_ENABLE = PTP_TS_ENABLE PTP_TAG_WIDTH = 16 - USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) diff --git a/tb/test_axis_baser_tx_64.v b/tb/test_axis_baser_tx_64.v index 5aac11293..1c62d6bdd 100644 --- a/tb/test_axis_baser_tx_64.v +++ b/tb/test_axis_baser_tx_64.v @@ -42,9 +42,9 @@ parameter PTP_PERIOD_NS = 4'h6; parameter PTP_PERIOD_FNS = 16'h6666; parameter PTP_TS_ENABLE = 0; parameter PTP_TS_WIDTH = 96; -parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_ENABLE = PTP_TS_ENABLE; parameter PTP_TAG_WIDTH = 16; -parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; +parameter USER_WIDTH = (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; diff --git a/tb/test_axis_gmii_tx.py b/tb/test_axis_gmii_tx.py index 041fef7d0..1c47c6a57 100755 --- a/tb/test_axis_gmii_tx.py +++ b/tb/test_axis_gmii_tx.py @@ -51,9 +51,9 @@ def bench(): MIN_FRAME_LENGTH = 64 PTP_TS_ENABLE = 0 PTP_TS_WIDTH = 96 - PTP_TAG_ENABLE = 0 + PTP_TAG_ENABLE = PTP_TS_ENABLE PTP_TAG_WIDTH = 16 - USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) diff --git a/tb/test_axis_gmii_tx.v b/tb/test_axis_gmii_tx.v index 44ea2a234..f24b03804 100644 --- a/tb/test_axis_gmii_tx.v +++ b/tb/test_axis_gmii_tx.v @@ -37,9 +37,9 @@ parameter ENABLE_PADDING = 1; parameter MIN_FRAME_LENGTH = 64; parameter PTP_TS_ENABLE = 0; parameter PTP_TS_WIDTH = 96; -parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_ENABLE = PTP_TS_ENABLE; parameter PTP_TAG_WIDTH = 16; -parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; +parameter USER_WIDTH = (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; diff --git a/tb/test_axis_xgmii_tx_32.py b/tb/test_axis_xgmii_tx_32.py index 41dc13631..6f3f48edd 100755 --- a/tb/test_axis_xgmii_tx_32.py +++ b/tb/test_axis_xgmii_tx_32.py @@ -54,9 +54,9 @@ def bench(): MIN_FRAME_LENGTH = 64 PTP_TS_ENABLE = 0 PTP_TS_WIDTH = 96 - PTP_TAG_ENABLE = 0 + PTP_TAG_ENABLE = PTP_TS_ENABLE PTP_TAG_WIDTH = 16 - USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) diff --git a/tb/test_axis_xgmii_tx_32.v b/tb/test_axis_xgmii_tx_32.v index 7af249a4e..9f2615378 100644 --- a/tb/test_axis_xgmii_tx_32.v +++ b/tb/test_axis_xgmii_tx_32.v @@ -40,9 +40,9 @@ parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; parameter PTP_TS_ENABLE = 0; parameter PTP_TS_WIDTH = 96; -parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_ENABLE = PTP_TS_ENABLE; parameter PTP_TAG_WIDTH = 16; -parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; +parameter USER_WIDTH = (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; diff --git a/tb/test_axis_xgmii_tx_64.py b/tb/test_axis_xgmii_tx_64.py index 0845a88a0..aa547938c 100755 --- a/tb/test_axis_xgmii_tx_64.py +++ b/tb/test_axis_xgmii_tx_64.py @@ -56,9 +56,9 @@ def bench(): PTP_PERIOD_FNS = 0x6666 PTP_TS_ENABLE = 0 PTP_TS_WIDTH = 96 - PTP_TAG_ENABLE = 0 + PTP_TAG_ENABLE = PTP_TS_ENABLE PTP_TAG_WIDTH = 16 - USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1 + USER_WIDTH = (PTP_TAG_WIDTH if PTP_TAG_ENABLE else 0) + 1 # Inputs clk = Signal(bool(0)) diff --git a/tb/test_axis_xgmii_tx_64.v b/tb/test_axis_xgmii_tx_64.v index 8fdc43426..e840edd11 100644 --- a/tb/test_axis_xgmii_tx_64.v +++ b/tb/test_axis_xgmii_tx_64.v @@ -42,9 +42,9 @@ parameter PTP_PERIOD_NS = 4'h6; parameter PTP_PERIOD_FNS = 16'h6666; parameter PTP_TS_ENABLE = 0; parameter PTP_TS_WIDTH = 96; -parameter PTP_TAG_ENABLE = 0; +parameter PTP_TAG_ENABLE = PTP_TS_ENABLE; parameter PTP_TAG_WIDTH = 16; -parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; +parameter USER_WIDTH = (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; // Inputs reg clk = 0; diff --git a/tb/test_eth_mac_10g_32.py b/tb/test_eth_mac_10g_32.py index ee290e30c..f63897201 100755 --- a/tb/test_eth_mac_10g_32.py +++ b/tb/test_eth_mac_10g_32.py @@ -56,11 +56,11 @@ def bench(): MIN_FRAME_LENGTH = 64 TX_PTP_TS_ENABLE = 0 TX_PTP_TS_WIDTH = 96 - TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE TX_PTP_TAG_WIDTH = 16 RX_PTP_TS_ENABLE = 0 RX_PTP_TS_WIDTH = 96 - TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TAG_ENABLE else 0) + 1 RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 # Inputs diff --git a/tb/test_eth_mac_10g_32.v b/tb/test_eth_mac_10g_32.v index 0a98ef33e..dd93fafc6 100644 --- a/tb/test_eth_mac_10g_32.v +++ b/tb/test_eth_mac_10g_32.v @@ -40,11 +40,11 @@ parameter ENABLE_DIC = 1; parameter MIN_FRAME_LENGTH = 64; parameter TX_PTP_TS_ENABLE = 0; parameter TX_PTP_TS_WIDTH = 96; -parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE; parameter TX_PTP_TAG_WIDTH = 16; parameter RX_PTP_TS_ENABLE = 0; parameter RX_PTP_TS_WIDTH = 96; -parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter TX_USER_WIDTH = (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; // Inputs diff --git a/tb/test_eth_mac_10g_64.py b/tb/test_eth_mac_10g_64.py index 2662ed6c6..6b7e960b4 100755 --- a/tb/test_eth_mac_10g_64.py +++ b/tb/test_eth_mac_10g_64.py @@ -58,11 +58,11 @@ def bench(): PTP_PERIOD_FNS = 0x6666 TX_PTP_TS_ENABLE = 0 TX_PTP_TS_WIDTH = 96 - TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE TX_PTP_TAG_WIDTH = 16 RX_PTP_TS_ENABLE = 0 RX_PTP_TS_WIDTH = 96 - TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TAG_ENABLE else 0) + 1 RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 # Inputs diff --git a/tb/test_eth_mac_10g_64.v b/tb/test_eth_mac_10g_64.v index db0585b3b..20ffa25e0 100644 --- a/tb/test_eth_mac_10g_64.v +++ b/tb/test_eth_mac_10g_64.v @@ -42,11 +42,11 @@ parameter PTP_PERIOD_NS = 4'h6; parameter PTP_PERIOD_FNS = 16'h6666; parameter TX_PTP_TS_ENABLE = 0; parameter TX_PTP_TS_WIDTH = 96; -parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE; parameter TX_PTP_TAG_WIDTH = 16; parameter RX_PTP_TS_ENABLE = 0; parameter RX_PTP_TS_WIDTH = 96; -parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter TX_USER_WIDTH = (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; // Inputs diff --git a/tb/test_eth_mac_1g.py b/tb/test_eth_mac_1g.py index 8a978e8d2..cf2ab16bf 100755 --- a/tb/test_eth_mac_1g.py +++ b/tb/test_eth_mac_1g.py @@ -53,11 +53,11 @@ def bench(): MIN_FRAME_LENGTH = 64 TX_PTP_TS_ENABLE = 0 TX_PTP_TS_WIDTH = 96 - TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE TX_PTP_TAG_WIDTH = 16 RX_PTP_TS_ENABLE = 0 RX_PTP_TS_WIDTH = 96 - TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TAG_ENABLE else 0) + 1 RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 # Inputs diff --git a/tb/test_eth_mac_1g.v b/tb/test_eth_mac_1g.v index 25b63dbb2..5790affca 100644 --- a/tb/test_eth_mac_1g.v +++ b/tb/test_eth_mac_1g.v @@ -37,11 +37,11 @@ parameter ENABLE_PADDING = 1; parameter MIN_FRAME_LENGTH = 64; parameter TX_PTP_TS_ENABLE = 0; parameter TX_PTP_TS_WIDTH = 96; -parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE; parameter TX_PTP_TAG_WIDTH = 16; parameter RX_PTP_TS_ENABLE = 0; parameter RX_PTP_TS_WIDTH = 96; -parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter TX_USER_WIDTH = (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; // Inputs diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py index 255aa6f0f..5f5f43e6c 100755 --- a/tb/test_eth_mac_phy_10g.py +++ b/tb/test_eth_mac_phy_10g.py @@ -66,11 +66,11 @@ def bench(): PTP_PERIOD_FNS = 0x6666 TX_PTP_TS_ENABLE = 0 TX_PTP_TS_WIDTH = 96 - TX_PTP_TAG_ENABLE = 0 + TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE TX_PTP_TAG_WIDTH = 16 RX_PTP_TS_ENABLE = 0 RX_PTP_TS_WIDTH = 96 - TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1 + TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TAG_ENABLE else 0) + 1 RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1 BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 diff --git a/tb/test_eth_mac_phy_10g.v b/tb/test_eth_mac_phy_10g.v index 6a73719e9..45911b60f 100644 --- a/tb/test_eth_mac_phy_10g.v +++ b/tb/test_eth_mac_phy_10g.v @@ -43,11 +43,11 @@ parameter PTP_PERIOD_NS = 4'h6; parameter PTP_PERIOD_FNS = 16'h6666; parameter TX_PTP_TS_ENABLE = 0; parameter TX_PTP_TS_WIDTH = 96; -parameter TX_PTP_TAG_ENABLE = 0; +parameter TX_PTP_TAG_ENABLE = TX_PTP_TS_ENABLE; parameter TX_PTP_TAG_WIDTH = 16; parameter RX_PTP_TS_ENABLE = 0; parameter RX_PTP_TS_WIDTH = 96; -parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; +parameter TX_USER_WIDTH = (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1; parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; From 75d9154d320a4a189b89aae6cc7e447edc578904 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 10 Jun 2019 17:39:18 -0700 Subject: [PATCH 574/617] Reduce extraneous warnings from get_cells --- syn/axis_async_fifo.tcl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/syn/axis_async_fifo.tcl b/syn/axis_async_fifo.tcl index 6b3fe44cf..b64564743 100644 --- a/syn/axis_async_fifo.tcl +++ b/syn/axis_async_fifo.tcl @@ -33,19 +33,19 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo || set min_clk_period [expr $read_clk_period < $write_clk_period ? $read_clk_period : $write_clk_period] # reset synchronization - set reset_ffs [get_cells -hier -regexp ".*/(s|m)_rst_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] + set reset_ffs [get_cells -quiet -hier -regexp ".*/(s|m)_rst_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] if {[llength $reset_ffs]} { set_property ASYNC_REG TRUE $reset_ffs set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}] } - if {[llength [get_cells $fifo_inst/s_rst_sync2_reg_reg]]} { + if {[llength [get_cells -quiet $fifo_inst/s_rst_sync2_reg_reg]]} { set_false_path -to [get_pins $fifo_inst/s_rst_sync2_reg_reg/D] set_max_delay -from [get_cells $fifo_inst/s_rst_sync2_reg_reg] -to [get_cells $fifo_inst/s_rst_sync3_reg_reg] $min_clk_period } - if {[llength [get_cells $fifo_inst/m_rst_sync2_reg_reg]]} { + if {[llength [get_cells -quiet $fifo_inst/m_rst_sync2_reg_reg]]} { set_false_path -to [get_pins $fifo_inst/m_rst_sync2_reg_reg/D] set_max_delay -from [get_cells $fifo_inst/m_rst_sync2_reg_reg] -to [get_cells $fifo_inst/m_rst_sync3_reg_reg] $min_clk_period } @@ -55,11 +55,11 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo || set_max_delay -from [get_cells "$fifo_inst/rd_ptr_reg_reg[*] $fifo_inst/rd_ptr_gray_reg_reg[*]"] -to [get_cells $fifo_inst/rd_ptr_gray_sync1_reg_reg[*]] -datapath_only $read_clk_period set_bus_skew -from [get_cells "$fifo_inst/rd_ptr_reg_reg[*] $fifo_inst/rd_ptr_gray_reg_reg[*]"] -to [get_cells $fifo_inst/rd_ptr_gray_sync1_reg_reg[*]] $write_clk_period - set_max_delay -from [get_cells "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] -datapath_only $write_clk_period - set_bus_skew -from [get_cells "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] $read_clk_period + set_max_delay -from [get_cells -quiet "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] -datapath_only $write_clk_period + set_bus_skew -from [get_cells -quiet "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] $read_clk_period # frame FIFO pointer update synchronization - set update_ffs [get_cells -hier -regexp ".*/wr_ptr_update(_ack)?_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] + set update_ffs [get_cells -quiet -hier -regexp ".*/wr_ptr_update(_ack)?_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] if {[llength $update_ffs]} { set_property ASYNC_REG TRUE $update_ffs From ced2df141c936901434b419b364a865f69237638 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 10 Jun 2019 17:40:30 -0700 Subject: [PATCH 575/617] Add false path for async FIFO implementation in distributed RAM --- syn/axis_async_fifo.tcl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/syn/axis_async_fifo.tcl b/syn/axis_async_fifo.tcl index b64564743..bc7bd5e4c 100644 --- a/syn/axis_async_fifo.tcl +++ b/syn/axis_async_fifo.tcl @@ -58,6 +58,13 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo || set_max_delay -from [get_cells -quiet "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] -datapath_only $write_clk_period set_bus_skew -from [get_cells -quiet "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_sync_gray_reg_reg[*]"] -to [get_cells $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] $read_clk_period + # output register (needed for distributed RAM sync write/async read) + set output_reg_ffs [get_cells -quiet "$fifo_inst/mem_read_data_reg_reg[*]"] + + if {[llength $output_reg_ffs]} { + set_false_path -from $write_clk -to $output_reg_ffs + } + # frame FIFO pointer update synchronization set update_ffs [get_cells -quiet -hier -regexp ".*/wr_ptr_update(_ack)?_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] From 296744b37ec88d08ed960159ea20b3cac06d3c4b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 12 Jun 2019 23:31:03 -0700 Subject: [PATCH 576/617] Make use of blocking statements consistent --- rtl/axis_baser_tx_64.v | 4 ++-- rtl/axis_xgmii_tx_64.v | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v index fcaa8ea15..c5e12a94a 100644 --- a/rtl/axis_baser_tx_64.v +++ b/rtl/axis_baser_tx_64.v @@ -508,8 +508,8 @@ always @* begin m_axis_ptp_ts_valid_next = 1'b1; if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin // ns field rollover - m_axis_ptp_ts_next[45:16] <= $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000); - m_axis_ptp_ts_next[95:48] <= m_axis_ptp_ts_reg[95:48] + 1; + m_axis_ptp_ts_next[45:16] = $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000); + m_axis_ptp_ts_next[95:48] = m_axis_ptp_ts_reg[95:48] + 1; end end diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index fb1c9b394..b9c21c2aa 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -454,8 +454,8 @@ always @* begin m_axis_ptp_ts_valid_next = 1'b1; if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin // ns field rollover - m_axis_ptp_ts_next[45:16] <= $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000); - m_axis_ptp_ts_next[95:48] <= m_axis_ptp_ts_reg[95:48] + 1; + m_axis_ptp_ts_next[45:16] = $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000); + m_axis_ptp_ts_next[95:48] = m_axis_ptp_ts_reg[95:48] + 1; end end From b41ab00381cd56073898654c21c81b38285449af Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 13 Jun 2019 23:45:17 -0700 Subject: [PATCH 577/617] Initialize ARP cache --- rtl/arp_cache.v | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rtl/arp_cache.v b/rtl/arp_cache.v index fd695f3b6..91af3163e 100644 --- a/rtl/arp_cache.v +++ b/rtl/arp_cache.v @@ -130,6 +130,16 @@ wr_hash ( .state_out(write_request_hash) ); +integer i; + +initial begin + for (i = 0; i < 2**CACHE_ADDR_WIDTH; i = i + 1) begin + valid_mem[i] = 1'b0; + ip_addr_mem[i] = 32'd0; + mac_addr_mem[i] = 48'd0; + end +end + always @* begin mem_write = 1'b0; store_query = 1'b0; From ce135220854a6fab555bc5a184238e3963e2ead4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 14 Jun 2019 00:01:13 -0700 Subject: [PATCH 578/617] Implement ARP cache clear --- rtl/arp_cache.v | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/rtl/arp_cache.v b/rtl/arp_cache.v index 91af3163e..e0c4c0662 100644 --- a/rtl/arp_cache.v +++ b/rtl/arp_cache.v @@ -71,6 +71,7 @@ reg [31:0] query_ip_reg = 0; reg write_ip_valid_reg = 0, write_ip_valid_next; reg [31:0] write_ip_reg = 0; reg [47:0] write_mac_reg = 0; +reg clear_cache_reg = 0, clear_cache_next; reg [CACHE_ADDR_WIDTH-1:0] wr_ptr_reg = {CACHE_ADDR_WIDTH{1'b0}}, wr_ptr_next; reg [CACHE_ADDR_WIDTH-1:0] rd_ptr_reg = {CACHE_ADDR_WIDTH{1'b0}}, rd_ptr_next; @@ -148,9 +149,11 @@ always @* begin wr_ptr_next = wr_ptr_reg; rd_ptr_next = rd_ptr_reg; + clear_cache_next = clear_cache_reg | clear_cache; + query_ip_valid_next = query_ip_valid_reg; - query_request_ready_next = ~query_ip_valid_reg || ~query_request_valid || query_response_ready; + query_request_ready_next = (~query_ip_valid_reg || ~query_request_valid || query_response_ready) && !clear_cache_next; query_response_valid_next = query_response_valid_reg & ~query_response_ready; query_response_error_next = query_response_error_reg; @@ -173,7 +176,7 @@ always @* begin write_ip_valid_next = write_ip_valid_reg; - write_request_ready_next = 1'b1; + write_request_ready_next = !clear_cache_next; if (write_ip_valid_reg) begin write_ip_valid_next = 0; @@ -185,6 +188,15 @@ always @* begin write_ip_valid_next = 1; wr_ptr_next = write_request_hash[CACHE_ADDR_WIDTH-1:0]; end + + if (clear_cache) begin + clear_cache_next = 1'b1; + wr_ptr_next = 0; + end else if (clear_cache_reg) begin + wr_ptr_next = wr_ptr_reg + 1; + clear_cache_next = wr_ptr_next != 0; + mem_write = 1; + end end always @(posedge clk) begin @@ -194,12 +206,16 @@ always @(posedge clk) begin query_response_valid_reg <= 1'b0; write_ip_valid_reg <= 1'b0; write_request_ready_reg <= 1'b0; + clear_cache_reg <= 1'b1; + wr_ptr_reg <= 0; end else begin query_ip_valid_reg <= query_ip_valid_next; query_request_ready_reg <= query_request_ready_next; query_response_valid_reg <= query_response_valid_next; write_ip_valid_reg <= write_ip_valid_next; write_request_ready_reg <= write_request_ready_next; + clear_cache_reg <= clear_cache_next; + wr_ptr_reg <= wr_ptr_next; end query_response_error_reg <= query_response_error_next; @@ -213,13 +229,12 @@ always @(posedge clk) begin write_mac_reg <= write_request_mac; end - wr_ptr_reg <= wr_ptr_next; rd_ptr_reg <= rd_ptr_next; query_response_mac_reg <= mac_addr_mem[rd_ptr_reg]; if (mem_write) begin - valid_mem[wr_ptr_reg] <= 1'b1; + valid_mem[wr_ptr_reg] <= !clear_cache_reg; ip_addr_mem[wr_ptr_reg] <= write_ip_reg; mac_addr_mem[wr_ptr_reg] <= write_mac_reg; end From d96a5a449a288fe6e6e23709e7f2660aadf04c4b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 14 Jun 2019 00:01:51 -0700 Subject: [PATCH 579/617] Update ARP cache testbench --- tb/test_arp_cache.py | 263 ++++++++----------------------------------- tb/test_arp_cache.v | 5 +- 2 files changed, 49 insertions(+), 219 deletions(-) diff --git a/tb/test_arp_cache.py b/tb/test_arp_cache.py index a576facda..9237b47de 100755 --- a/tb/test_arp_cache.py +++ b/tb/test_arp_cache.py @@ -43,6 +43,9 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + CACHE_ADDR_WIDTH = 2 + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) @@ -193,8 +196,6 @@ def bench(): yield delay(100) - raise StopSimulation - yield clk.posedge print("test 3: write more") current_test.next = 3 @@ -202,7 +203,7 @@ def bench(): yield clk.posedge write_request_source.send([(0xc0a80121, 0x0000c0a80121)]) write_request_source.send([(0xc0a80122, 0x0000c0a80122)]) - # overwrites 0xc0a80121 due to LRU + # overwrites 0xc0a80112 write_request_source.send([(0xc0a80123, 0x0000c0a80123)]) while not write_request_source.empty(): @@ -222,21 +223,21 @@ def bench(): assert resp.data[0][0] == 0x0000c0a80111 assert not resp.user[0] + # not in cache; was overwritten yield clk.posedge query_request_source.send([(0xc0a80112, )]) yield query_response_sink.wait() resp = query_response_sink.recv() - assert resp.data[0][0] == 0x0000c0a80112 - assert not resp.user[0] + assert resp.user[0] - # not in cache; was overwritten yield clk.posedge query_request_source.send([(0xc0a80121, )]) yield query_response_sink.wait() resp = query_response_sink.recv() - assert resp.user[0] + assert resp.data[0][0] == 0x0000c0a80121 + assert not resp.user[0] yield clk.posedge query_request_source.send([(0xc0a80122, )]) @@ -254,237 +255,65 @@ def bench(): assert resp.data[0][0] == 0x0000c0a80123 assert not resp.user[0] - # LRU reset by previous operation - yield delay(100) - raise StopSimulation - yield clk.posedge - print("test 5: LRU test") + print("test 5: Test overwrite") current_test.next = 5 - # read to set LRU bit yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80111 - yield clk.posedge - query_request_valid.next = False + write_request_source.send([(0xc0a80123, 0x0000c0a80164)]) - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80111 - - yield clk.posedge - write_request_valid.next = True - write_request_ip.next = 0xc0a80131 - write_request_mac.next = 0x0000c0a80131 - yield clk.posedge - write_request_valid.next = False - - yield write_complete.posedge - yield clk.posedge - - yield clk.posedge - write_request_valid.next = True - write_request_ip.next = 0xc0a80132 - write_request_mac.next = 0x0000c0a80132 - yield clk.posedge - write_request_valid.next = False - - yield write_complete.posedge - yield clk.posedge - - yield clk.posedge - write_request_valid.next = True - write_request_ip.next = 0xc0a80133 - write_request_mac.next = 0x0000c0a80133 - yield clk.posedge - write_request_valid.next = False - - yield write_complete.posedge - yield clk.posedge + while not write_request_source.empty(): + yield clk.posedge # read values yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80111 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80111, )]) - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80111 + yield query_response_sink.wait() + resp = query_response_sink.recv() + assert resp.data[0][0] == 0x0000c0a80111 + assert not resp.user[0] + + # not in cache; was overwritten + yield clk.posedge + query_request_source.send([(0xc0a80112, )]) + + yield query_response_sink.wait() + resp = query_response_sink.recv() + assert resp.user[0] yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80112 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80121, )]) - yield query_response_valid.posedge - assert bool(query_response_error) + yield query_response_sink.wait() + resp = query_response_sink.recv() + assert resp.data[0][0] == 0x0000c0a80121 + assert not resp.user[0] yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80121 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80122, )]) - yield query_response_valid.posedge - assert bool(query_response_error) + yield query_response_sink.wait() + resp = query_response_sink.recv() + assert resp.data[0][0] == 0x0000c0a80122 + assert not resp.user[0] yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80122 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80123, )]) - yield query_response_valid.posedge - assert bool(query_response_error) - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80123 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert bool(query_response_error) - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80131 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80131 - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80132 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80132 - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80133 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80133 - - # LRU reset by previous operation + yield query_response_sink.wait() + resp = query_response_sink.recv() + assert resp.data[0][0] == 0x0000c0a80164 + assert not resp.user[0] yield delay(100) yield clk.posedge - print("test 6: Test overwrite") + print("test 6: clear cache") current_test.next = 6 - yield clk.posedge - write_request_valid.next = True - write_request_ip.next = 0xc0a80133 - write_request_mac.next = 0x0000c0a80164 - yield clk.posedge - write_request_valid.next = False - - yield write_complete.posedge - yield clk.posedge - - # read values - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80111 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80111 - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80112 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert bool(query_response_error) - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80121 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert bool(query_response_error) - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80122 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert bool(query_response_error) - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80123 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert bool(query_response_error) - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80131 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80131 - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80132 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80132 - - yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80133 - yield clk.posedge - query_request_valid.next = False - - yield query_response_valid.posedge - assert not bool(query_response_error) - assert int(query_response_mac) == 0x0000c0a80164 - - # LRU reset by previous operation - - yield delay(100) - - yield clk.posedge - print("test 7: clear cache") - current_test.next = 7 - yield clk.posedge clear_cache.next = True yield clk.posedge @@ -493,13 +322,11 @@ def bench(): yield delay(100) yield clk.posedge - query_request_valid.next = True - query_request_ip.next = 0xc0a80111 - yield clk.posedge - query_request_valid.next = False + query_request_source.send([(0xc0a80111, )]) - yield query_response_valid.posedge - assert bool(query_response_error) + yield query_response_sink.wait() + resp = query_response_sink.recv() + assert resp.user[0] yield delay(100) diff --git a/tb/test_arp_cache.v b/tb/test_arp_cache.v index ad0e8129c..d91625d97 100755 --- a/tb/test_arp_cache.v +++ b/tb/test_arp_cache.v @@ -31,6 +31,9 @@ THE SOFTWARE. */ module test_arp_cache; +// Parameters +parameter CACHE_ADDR_WIDTH = 2; + // Inputs reg clk = 0; reg rst = 0; @@ -84,7 +87,7 @@ initial begin end arp_cache #( - .CACHE_ADDR_WIDTH(2) + .CACHE_ADDR_WIDTH(CACHE_ADDR_WIDTH) ) UUT ( .clk(clk), From b2cacc4e9460f6f6c5d993fc81741a5a982b4a0f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 14 Jun 2019 00:26:07 -0700 Subject: [PATCH 580/617] Update readme --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 768085442..10613cc8a 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,12 @@ Fully parametrizable combinatorial parallel LFSR/CRC module. MII PHY interface and clocking logic. +### ptp_clock module + +PTP clock module with PPS output. Generates both 64 bit and 96 bit timestamp +formats. Fine frequeny adjustment supported with configurable fractional +nanoseconds field. + ### rgmii_phy_if module RGMII PHY interface and clocking logic. @@ -420,8 +426,9 @@ and data lines. rtl/ip_eth_tx_64.v : IPv4 frame transmitter (64 bit) rtl/ip_mux.v : IP frame multiplexer rtl/lfsr.v : Generic LFSR/CRC module - rtl/oddr.v : Generic DDR output register rtl/mii_phy_if.v : MII PHY interface + rtl/oddr.v : Generic DDR output register + rtl/ptp_clock.v : PTP clock rtl/rgmii_phy_if.v : RGMII PHY interface rtl/ssio_ddr_in.v : Generic source synchronous IO DDR input module rtl/ssio_ddr_in_diff.v : Generic source synchronous IO DDR differential input module @@ -545,6 +552,7 @@ individual test scripts can be run with python directly. tb/gmii_ep.py : MyHDL GMII endpoints tb/ip_ep.py : MyHDL IP frame endpoints tb/mii_ep.py : MyHDL MII endpoints + tb/ptp.py : MyHDL PTP clock model tb/rgmii_ep.py : MyHDL RGMII endpoints tb/udp_ep.py : MyHDL UDP frame endpoints tb/xgmii_ep.py : MyHDL XGMII endpoints From 3684ccafb202a6fe7cb97e65e746263b6da8e3cf Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 15 Jun 2019 16:56:45 -0700 Subject: [PATCH 581/617] Make use of blocking statements consistent --- rtl/axis_baser_tx_64.v | 8 ++++---- rtl/axis_xgmii_tx_64.v | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v index c5e12a94a..35b86809f 100644 --- a/rtl/axis_baser_tx_64.v +++ b/rtl/axis_baser_tx_64.v @@ -532,8 +532,8 @@ always @* begin // need to send more idles - swap lanes swap_lanes = 1'b1; if (PTP_TS_WIDTH == 96) begin - m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); - m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + m_axis_ptp_ts_next[45:0] = ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); + m_axis_ptp_ts_next[95:48] = ptp_ts[95:48]; end else begin m_axis_ptp_ts_next = ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); end @@ -544,8 +544,8 @@ always @* begin // no more idles - unswap unswap_lanes = 1'b1; if (PTP_TS_WIDTH == 96) begin - m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); - m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + m_axis_ptp_ts_next[45:0] = ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + m_axis_ptp_ts_next[95:48] = ptp_ts[95:48]; end else begin m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); end diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index b9c21c2aa..4e527c64a 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -479,8 +479,8 @@ always @* begin // need to send more idles - swap lanes swap_lanes = 1'b1; if (PTP_TS_WIDTH == 96) begin - m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); - m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + m_axis_ptp_ts_next[45:0] = ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); + m_axis_ptp_ts_next[95:48] = ptp_ts[95:48]; end else begin m_axis_ptp_ts_next = ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); end @@ -491,8 +491,8 @@ always @* begin // no more idles - unswap unswap_lanes = 1'b1; if (PTP_TS_WIDTH == 96) begin - m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); - m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48]; + m_axis_ptp_ts_next[45:0] = ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); + m_axis_ptp_ts_next[95:48] = ptp_ts[95:48]; end else begin m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); end From 27999924a04b8152e2b25111b57cec9be546cc9c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 15 Jun 2019 17:35:49 -0700 Subject: [PATCH 582/617] Update VCU108 example designs --- example/VCU108/fpga_10g/fpga.xdc | 37 +- example/VCU108/fpga_10g/fpga/Makefile | 13 +- .../fpga_10g/ip/gig_ethernet_pcs_pma_0.xci | 5 +- .../fpga_10g/ip/gtwizard_ultrascale_0.xci | 1402 +++++++++++++++++ .../fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci | 203 --- example/VCU108/fpga_10g/rtl/fpga.v | 682 +++++--- example/VCU108/fpga_10g/rtl/fpga_core.v | 24 +- example/VCU108/fpga_10g/rtl/i2c_master.v | 895 ----------- example/VCU108/fpga_10g/rtl/si570_i2c_init.v | 486 ------ example/VCU108/fpga_10g/tb/test_fpga_core.py | 72 +- example/VCU108/fpga_10g/tb/test_fpga_core.v | 48 + .../fpga_1g/ip/gig_ethernet_pcs_pma_0.xci | 5 +- 12 files changed, 2058 insertions(+), 1814 deletions(-) create mode 100644 example/VCU108/fpga_10g/ip/gtwizard_ultrascale_0.xci delete mode 100644 example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci delete mode 100644 example/VCU108/fpga_10g/rtl/i2c_master.v delete mode 100644 example/VCU108/fpga_10g/rtl/si570_i2c_init.v diff --git a/example/VCU108/fpga_10g/fpga.xdc b/example/VCU108/fpga_10g/fpga.xdc index 049fa76fa..314bb5d00 100644 --- a/example/VCU108/fpga_10g/fpga.xdc +++ b/example/VCU108/fpga_10g/fpga.xdc @@ -73,24 +73,24 @@ set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports phy_int_n] create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] # QSFP+ Interface -set_property -dict {LOC AG45} [get_ports qsfp_rx1_p] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AG46} [get_ports qsfp_rx1_n] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AF43} [get_ports qsfp_rx2_p] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AF44} [get_ports qsfp_rx2_n] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AE45} [get_ports qsfp_rx3_p] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AE46} [get_ports qsfp_rx3_n] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AD43} [get_ports qsfp_rx4_p] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AD44} [get_ports qsfp_rx4_n] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 -set_property -dict {LOC AK42} [get_ports qsfp_tx1_p] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AK43} [get_ports qsfp_tx1_n] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AJ40} [get_ports qsfp_tx2_p] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AJ41} [get_ports qsfp_tx2_n] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AG41} [get_ports qsfp_tx3_p] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AG40} [get_ports qsfp_tx3_n] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AE40} [get_ports qsfp_tx4_p] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 -#set_property -dict {LOC AE41} [get_ports qsfp_tx4_n] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC AG45} [get_ports qsfp_rx1_p] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AG46} [get_ports qsfp_rx1_n] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC AF43} [get_ports qsfp_rx2_p] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AF44} [get_ports qsfp_rx2_n] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC AE45} [get_ports qsfp_rx3_p] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AE46} [get_ports qsfp_rx3_n] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC AD43} [get_ports qsfp_rx4_p] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AD44} [get_ports qsfp_rx4_n] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC AK42} [get_ports qsfp_tx1_p] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AK43} [get_ports qsfp_tx1_n] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC AJ40} [get_ports qsfp_tx2_p] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AJ41} [get_ports qsfp_tx2_n] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC AG40} [get_ports qsfp_tx3_p] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AG41} [get_ports qsfp_tx3_n] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC AE40} [get_ports qsfp_tx4_p] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC AE41} [get_ports qsfp_tx4_n] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 set_property -dict {LOC AF38} [get_ports qsfp_mgt_refclk_0_p] ;# MGTREFCLK0P_127 from U32 SI570 via U102 SI53340 -set_property -dict {LOC AF39} [get_ports qsfp_mgt_refclk_0_n] ;# MGTREFCLK0N_127 from U32 SI570 via U102 SI53340 +#set_property -dict {LOC AF39} [get_ports qsfp_mgt_refclk_0_n] ;# MGTREFCLK0N_127 from U32 SI570 via U102 SI53340 #set_property -dict {LOC AD38} [get_ports qsfp_mgt_refclk_1_p] ;# MGTREFCLK1P_127 from U57 CKOUT2 SI5328 #set_property -dict {LOC AD39} [get_ports qsfp_mgt_refclk_1_n] ;# MGTREFCLK1N_127 from U57 CKOUT2 SI5328 #set_property -dict {LOC AG34 IOSTANDARD LVDS} [get_ports qsfp_recclk_p] ;# to U57 CKIN1 SI5328 @@ -101,6 +101,9 @@ set_property -dict {LOC AL25 IOSTANDARD LVCMOS18} [get_ports qsfp_modprsl] set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp_intl] set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp_lpmode] +# 156.25 MHz MGT reference clock +create_clock -period 6.400 -name qsfp_mgt_refclk_0 [get_ports qsfp_mgt_refclk_0_p] + # I2C interface set_property -dict {LOC AN21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_scl] set_property -dict {LOC AP21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_sda] diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 12d080c3e..ef2fae0eb 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -10,8 +10,6 @@ SYN_FILES += rtl/fpga_core.v SYN_FILES += rtl/debounce_switch.v SYN_FILES += rtl/sync_reset.v SYN_FILES += rtl/sync_signal.v -SYN_FILES += rtl/i2c_master.v -SYN_FILES += rtl/si570_i2c_init.v SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_1g.v SYN_FILES += lib/eth/rtl/axis_gmii_rx.v @@ -20,6 +18,15 @@ SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/eth_phy_10g.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v +SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v +SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v @@ -54,7 +61,7 @@ XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl # IP XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci -XCI_FILES += ip/ten_gig_eth_pcs_pma_0.xci +XCI_FILES += ip/gtwizard_ultrascale_0.xci include ../common/vivado.mk diff --git a/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci index 1db9474cb..91b324db6 100644 --- a/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci +++ b/example/VCU108/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci @@ -309,16 +309,17 @@ MIXED -2 + E TRUE TRUE IP_Flow - 5 + 6 TRUE . . - 2018.3 + 2019.1 OUT_OF_CONTEXT diff --git a/example/VCU108/fpga_10g/ip/gtwizard_ultrascale_0.xci b/example/VCU108/fpga_10g/ip/gtwizard_ultrascale_0.xci new file mode 100644 index 000000000..a38021fba --- /dev/null +++ b/example/VCU108/fpga_10g/ip/gtwizard_ultrascale_0.xci @@ -0,0 +1,1402 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gtwizard_ultrascale_0 + + + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000000" + 1 + 2578.125 + 0 + 0 + 125 + 27 + 1 + 2 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 1 + 250 + 0 + 0 + 0 + 0 + 0 + 1 + "00000000" + "00000000" + 1 + 2 + 0 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000" + 0 + "00000000" + 1 + 0 + 5000 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + 0 + "1010000011" + 0 + "0101111100" + 4 + 1 + 64 + 10.3125 + 12 + 1 + 156.2500000 + 4 + 0 + 0x000000000000000000000000000000000000000000000000 + 156.25 + 0 + 0 + 0 + 1 + 1 + 0 + 64 + 156.2500000 + 156.2500000 + 0 + 257.8125 + 1 + 4 + 1 + 0 + 0 + 0 + 156.25 + 0 + 0 + 1 + 4 + 1 + 64 + 10.3125 + 12 + 1 + 156.2500000 + 4 + 0 + 156.25 + 0 + 0 + 1 + 1 + 0 + 64 + 156.2500000 + 156.2500000 + 0 + X0Y15 X0Y14 X0Y13 X0Y12 + gtwizard_ultrascale_0 + 0 + 0 + + 125 + BOTH + 0 + GTY + 2 + 20 + 96 + 2 + gtye3 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + -1 + -1 + -1 + -1 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + 1 + 1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + -1 + -1 + 0 + -1 + -1 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + -1 + -1 + 0 + -1 + -1 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + -1 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + 1 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + -1 + -1 + -1 + 0 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + -1 + 0 + 0 + 0 + -1 + 0 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 13 + 0 + 10GBASE-R + 6 + 156.2500000 + 4 + 1 + 156.2500000 + false + CORE + NONE + CORE + CORE + EXAMPLE_DESIGN + CORE + EXAMPLE_DESIGN + EXAMPLE_DESIGN + false + NAME + false + 250 + false + false + 250 + GTY-10GBASE-R + 0 + MULTI + 1 + ENABLE + DISABLE + ENABLE + 00000000 + false + false + false + false + false + false + false + false + 00000000 + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 2 + 1 + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + false + false + false + false + false + false + false + false + 00000000 + DISABLE + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 0 + 5000 + ENABLE + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 1 + false + 0000000000 + false + 1010000011 + NONE + false + 0101111100 + true + 0 + AC + 64B66B_ASYNC + true + AUTO + 64 + 6.1862627 + -20 + 10.3125 + X0Y12 + RXPROGDIVCLK + QPLL0 + 200 + 0 + + 156.25 + + OFF + 0 + PROGRAMMABLE + 800 + 64 + 15 + false + 0 + 10.3125 + 257.8125 + 1 + false + QPLL0 + 156.25 + 1 + ENABLE + 64B66B_ASYNC + CUSTOM + true + 64 + 10.3125 + X0Y12 + TXPROGDIVCLK + QPLL0 + 0 + 156.25 + + 64 + false + 1 + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + true + true + false + true + true + true + false + true + true + true + false + false + false + false + false + true + false + false + false + false + false + false + false + true + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + virtexu + + + xcvu095 + ffva2104 + VERILOG + + MIXED + -2 + + E + TRUE + TRUE + IP_Flow + 6 + TRUE + . + + . + 2019.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci b/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci deleted file mode 100644 index 644821b10..000000000 --- a/example/VCU108/fpga_10g/ip/ten_gig_eth_pcs_pma_0.xci +++ /dev/null @@ -1,203 +0,0 @@ - - - xilinx.com - xci - unknown - 1.0 - - - ten_gig_eth_pcs_pma_0 - - - 0 - 0 - 0 - 0 - 0 - - - 0 - 0.000 - - - - 0 - 0.000 - - - 100000000 - 0 - 0.000 - 0 - 0 - 0 - 0 - 0 - - - - 100000000 - 0 - 0.000 - - - - 100000000 - 0 - 0.000 - 0 - false - 0 - 0 - - - - 100000000 - 0 - 0.000 - - - - 0 - 0.000 - - - - 100000000 - 0 - 0.000 - - - - 0 - 0.000 - - - - 100000000 - 0 - 0.000 - - - - 0 - 0.000 - - - - 100000000 - 0 - 0.000 - - - - 0 - 0.000 - false - 0 - 0 - - - 0 - 0.000 - 0 - - - - 0 - 0.000 - - - - 0 - 0.000 - 0 - - - - 0 - 0.000 - - - - 0 - 0.000 - - 0 - 0.000 - - - - 0 - 0.000 - 0 - ten_gig_eth_pcs_pma_0 - 125.00 - virtexu - X0Y12 - 64 - 3 - false - false - false - false - false - false - clk0 - 156 - 10 - ten_gig_eth_pcs_pma_0_gt - ten_gig_eth_pcs_pma_0 - 125.00 - None - X0Y12 - false - clk0 - 156.25 - 1 - Time_of_day - false - false - false - BASE-R - 64bit - false - false - 10Gig - GTY - virtexu - - - xcvu095 - ffva2104 - VERILOG - - MIXED - -2 - E - TRUE - TRUE - IP_Flow - 14 - TRUE - . - - . - 2018.3 - OUT_OF_CONTEXT - - - - - - - - - - - - - - - - diff --git a/example/VCU108/fpga_10g/rtl/fpga.v b/example/VCU108/fpga_10g/rtl/fpga.v index 99a9ee0e1..9792b14d3 100644 --- a/example/VCU108/fpga_10g/rtl/fpga.v +++ b/example/VCU108/fpga_10g/rtl/fpga.v @@ -60,20 +60,20 @@ module fpga ( */ input wire qsfp_rx1_p, input wire qsfp_rx1_n, - // input wire qsfp_rx2_p, - // input wire qsfp_rx2_n, - // input wire qsfp_rx3_p, - // input wire qsfp_rx3_n, - // input wire qsfp_rx4_p, - // input wire qsfp_rx4_n, + input wire qsfp_rx2_p, + input wire qsfp_rx2_n, + input wire qsfp_rx3_p, + input wire qsfp_rx3_n, + input wire qsfp_rx4_p, + input wire qsfp_rx4_n, output wire qsfp_tx1_p, output wire qsfp_tx1_n, - // output wire qsfp_tx2_p, - // output wire qsfp_tx2_n, - // output wire qsfp_tx3_p, - // output wire qsfp_tx3_n, - // output wire qsfp_tx4_p, - // output wire qsfp_tx4_n, + output wire qsfp_tx2_p, + output wire qsfp_tx2_n, + output wire qsfp_tx3_p, + output wire qsfp_tx3_n, + output wire qsfp_tx4_p, + output wire qsfp_tx4_n, input wire qsfp_mgt_refclk_0_p, input wire qsfp_mgt_refclk_0_n, // input wire qsfp_mgt_refclk_1_p, @@ -252,232 +252,510 @@ sync_signal_inst ( // SI570 I2C wire i2c_scl_i; -wire i2c_scl_o; -wire i2c_scl_t; +wire i2c_scl_o = 1'b1; +wire i2c_scl_t = 1'b1; wire i2c_sda_i; -wire i2c_sda_o; -wire i2c_sda_t; +wire i2c_sda_o = 1'b1; +wire i2c_sda_t = 1'b1; assign i2c_scl_i = i2c_scl; assign i2c_scl = i2c_scl_t ? 1'bz : i2c_scl_o; assign i2c_sda_i = i2c_sda; assign i2c_sda = i2c_sda_t ? 1'bz : i2c_sda_o; -wire [6:0] si570_i2c_cmd_address; -wire si570_i2c_cmd_start; -wire si570_i2c_cmd_read; -wire si570_i2c_cmd_write; -wire si570_i2c_cmd_write_multiple; -wire si570_i2c_cmd_stop; -wire si570_i2c_cmd_valid; -wire si570_i2c_cmd_ready; - -wire [7:0] si570_i2c_data; -wire si570_i2c_data_valid; -wire si570_i2c_data_ready; -wire si570_i2c_data_last; - -wire si570_i2c_init_busy; - -// delay start by ~10 ms -reg [20:0] si570_i2c_init_start_delay = 21'd0; - -always @(posedge clk_125mhz_int) begin - if (rst_125mhz_int) begin - si570_i2c_init_start_delay <= 21'd0; - end else begin - if (!si570_i2c_init_start_delay[20]) begin - si570_i2c_init_start_delay <= si570_i2c_init_start_delay + 21'd1; - end - end -end - -si570_i2c_init -si570_i2c_init_inst ( - .clk(clk_125mhz_int), - .rst(rst_125mhz_int), - .cmd_address(si570_i2c_cmd_address), - .cmd_start(si570_i2c_cmd_start), - .cmd_read(si570_i2c_cmd_read), - .cmd_write(si570_i2c_cmd_write), - .cmd_write_multiple(si570_i2c_cmd_write_multiple), - .cmd_stop(si570_i2c_cmd_stop), - .cmd_valid(si570_i2c_cmd_valid), - .cmd_ready(si570_i2c_cmd_ready), - .data_out(si570_i2c_data), - .data_out_valid(si570_i2c_data_valid), - .data_out_ready(si570_i2c_data_ready), - .data_out_last(si570_i2c_data_last), - .busy(si570_i2c_init_busy), - .start(si570_i2c_init_start_delay[20]) -); - -i2c_master -si570_i2c_master ( - .clk(clk_125mhz_int), - .rst(rst_125mhz_int), - .cmd_address(si570_i2c_cmd_address), - .cmd_start(si570_i2c_cmd_start), - .cmd_read(si570_i2c_cmd_read), - .cmd_write(si570_i2c_cmd_write), - .cmd_write_multiple(si570_i2c_cmd_write_multiple), - .cmd_stop(si570_i2c_cmd_stop), - .cmd_valid(si570_i2c_cmd_valid), - .cmd_ready(si570_i2c_cmd_ready), - .data_in(si570_i2c_data), - .data_in_valid(si570_i2c_data_valid), - .data_in_ready(si570_i2c_data_ready), - .data_in_last(si570_i2c_data_last), - .data_out(), - .data_out_valid(), - .data_out_ready(1), - .data_out_last(), - .scl_i(i2c_scl_i), - .scl_o(i2c_scl_o), - .scl_t(i2c_scl_t), - .sda_i(i2c_sda_i), - .sda_o(i2c_sda_o), - .sda_t(i2c_sda_t), - .busy(), - .bus_control(), - .bus_active(), - .missed_ack(), - .prescale(800), - .stop_on_idle(1) -); - // XGMII 10G PHY assign qsfp_modsell = 1'b0; assign qsfp_resetl = 1'b1; assign qsfp_lpmode = 1'b0; +wire qsfp_tx_clk_1_int; +wire qsfp_tx_rst_1_int; wire [63:0] qsfp_txd_1_int; wire [7:0] qsfp_txc_1_int; +wire qsfp_rx_clk_1_int; +wire qsfp_rx_rst_1_int; wire [63:0] qsfp_rxd_1_int; wire [7:0] qsfp_rxc_1_int; +wire qsfp_tx_clk_2_int; +wire qsfp_tx_rst_2_int; wire [63:0] qsfp_txd_2_int; wire [7:0] qsfp_txc_2_int; -wire [63:0] qsfp_rxd_2_int = 64'h0707070707070707; -wire [7:0] qsfp_rxc_2_int = 8'hff; +wire qsfp_rx_clk_2_int; +wire qsfp_rx_rst_2_int; +wire [63:0] qsfp_rxd_2_int; +wire [7:0] qsfp_rxc_2_int; +wire qsfp_tx_clk_3_int; +wire qsfp_tx_rst_3_int; wire [63:0] qsfp_txd_3_int; wire [7:0] qsfp_txc_3_int; -wire [63:0] qsfp_rxd_3_int = 64'h0707070707070707; -wire [7:0] qsfp_rxc_3_int = 8'hff; +wire qsfp_rx_clk_3_int; +wire qsfp_rx_rst_3_int; +wire [63:0] qsfp_rxd_3_int; +wire [7:0] qsfp_rxc_3_int; +wire qsfp_tx_clk_4_int; +wire qsfp_tx_rst_4_int; wire [63:0] qsfp_txd_4_int; wire [7:0] qsfp_txc_4_int; -wire [63:0] qsfp_rxd_4_int = 64'h0707070707070707; -wire [7:0] qsfp_rxc_4_int = 8'hff; +wire qsfp_rx_clk_4_int; +wire qsfp_rx_rst_4_int; +wire [63:0] qsfp_rxd_4_int; +wire [7:0] qsfp_rxc_4_int; -wire [535:0] configuration_vector; -wire [447:0] status_vector; -wire [7:0] core_status; +wire qsfp_rx_block_lock_1; +wire qsfp_rx_block_lock_2; +wire qsfp_rx_block_lock_3; +wire qsfp_rx_block_lock_4; -assign configuration_vector[0] = 1'b0; // PMA Loopback Enable -assign configuration_vector[14:1] = 0; -assign configuration_vector[15] = 1'b0; // PMA Reset -assign configuration_vector[16] = 1'b0; // Global PMD TX Disable -assign configuration_vector[109:17] = 0; -assign configuration_vector[110] = 1'b0; // PCS Loopback Enable -assign configuration_vector[111] = 1'b0; // PCS Reset -assign configuration_vector[169:112] = 58'd0; // 10GBASE-R Test Pattern Seed A0-3 -assign configuration_vector[175:170] = 0; -assign configuration_vector[233:176] = 58'd0; // 10GBASE-R Test Pattern Seed B0-3 -assign configuration_vector[239:234] = 0; -assign configuration_vector[240] = 1'b0; // Data Pattern Select -assign configuration_vector[241] = 1'b0; // Test Pattern Select -assign configuration_vector[242] = 1'b0; // RX Test Pattern Checking Enable -assign configuration_vector[243] = 1'b0; // TX Test Pattern Enable -assign configuration_vector[244] = 1'b0; // PRBS31 TX Test Pattern Enable -assign configuration_vector[245] = 1'b0; // PRBS31 RX Test Pattern Checking Enable -assign configuration_vector[383:246] = 0; -assign configuration_vector[399:384] = 16'h4C4B; // 125 us timer control -assign configuration_vector[511:400] = 0; -assign configuration_vector[512] = 1'b0; // Set PMA Link Status -assign configuration_vector[513] = 1'b0; // Clear PMA/PMD Link Faults -assign configuration_vector[515:514] = 0; -assign configuration_vector[516] = 1'b0; // Set PCS Link Status -assign configuration_vector[517] = 1'b0; // Clear PCS Link Faults -assign configuration_vector[518] = 1'b0; // Clear 10GBASE-R Status 2 -assign configuration_vector[519] = 1'b0; // Clear 10GBASE-R Test Pattern Error Counter -assign configuration_vector[535:520] = 0; +wire qsfp_mgt_refclk_0; -wire drp_gnt; -wire gt_drprdy; -wire [15:0] gt_drpdo; -wire gt_drpen; -wire gt_drpwe; -wire [15:0] gt_drpaddr; -wire [15:0] gt_drpdi; +wire [3:0] gt_txclkout; +wire gt_txusrclk; -ten_gig_eth_pcs_pma_0 -ten_gig_eth_pcs_pma_inst ( - .refclk_p(qsfp_mgt_refclk_0_p), - .refclk_n(qsfp_mgt_refclk_0_n), +wire [3:0] gt_rxclkout; +wire [3:0] gt_rxusrclk; - .dclk(clk_125mhz_int), +wire gt_reset_tx_done; +wire gt_reset_rx_done; - .coreclk_out(), +wire [3:0] gt_txprgdivresetdone; +wire [3:0] gt_txpmaresetdone; +wire [3:0] gt_rxprgdivresetdone; +wire [3:0] gt_rxpmaresetdone; - .reset(rst_125mhz_int | si570_i2c_init_busy), +wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); +wire gt_rx_reset = ~>_rxpmaresetdone; - .sim_speedup_control(1'b0), +reg gt_userclk_tx_active = 1'b0; +reg [3:0] gt_userclk_rx_active = 1'b0; + +IBUFDS_GTE3 ibufds_gte3_qsfp_mgt_refclk_0_inst ( + .I (qsfp_mgt_refclk_0_p), + .IB (qsfp_mgt_refclk_0_n), + .CEB (1'b0), + .O (qsfp_mgt_refclk_0), + .ODIV2 () +); + + +BUFG_GT bufg_gt_tx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txclkout[0]), + .O (gt_txusrclk) +); + +assign clk_156mhz_int = gt_txusrclk; + +always @(posedge gt_txusrclk, posedge gt_tx_reset) begin + if (gt_tx_reset) begin + gt_userclk_tx_active <= 1'b0; + end else begin + gt_userclk_tx_active <= 1'b1; + end +end + +genvar n; + +generate + +for (n = 0; n < 4; n = n + 1) begin + + BUFG_GT bufg_gt_rx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk[n]) + ); + + always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin + if (gt_rx_reset) begin + gt_userclk_rx_active[n] <= 1'b0; + end else begin + gt_userclk_rx_active[n] <= 1'b1; + end + end + +end + +endgenerate + +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz_int), + .rst(~gt_reset_tx_done), + .sync_reset_out(rst_156mhz_int) +); + +wire [5:0] qsfp_gt_txheader_1; +wire [127:0] qsfp_gt_txdata_1; +wire qsfp_gt_rxgearboxslip_1; +wire [5:0] qsfp_gt_rxheader_1; +wire [1:0] qsfp_gt_rxheadervalid_1; +wire [127:0] qsfp_gt_rxdata_1; +wire [1:0] qsfp_gt_rxdatavalid_1; + +wire [5:0] qsfp_gt_txheader_2; +wire [127:0] qsfp_gt_txdata_2; +wire qsfp_gt_rxgearboxslip_2; +wire [5:0] qsfp_gt_rxheader_2; +wire [1:0] qsfp_gt_rxheadervalid_2; +wire [127:0] qsfp_gt_rxdata_2; +wire [1:0] qsfp_gt_rxdatavalid_2; + +wire [5:0] qsfp_gt_txheader_3; +wire [127:0] qsfp_gt_txdata_3; +wire qsfp_gt_rxgearboxslip_3; +wire [5:0] qsfp_gt_rxheader_3; +wire [1:0] qsfp_gt_rxheadervalid_3; +wire [127:0] qsfp_gt_rxdata_3; +wire [1:0] qsfp_gt_rxdatavalid_3; + +wire [5:0] qsfp_gt_txheader_4; +wire [127:0] qsfp_gt_txdata_4; +wire qsfp_gt_rxgearboxslip_4; +wire [5:0] qsfp_gt_rxheader_4; +wire [1:0] qsfp_gt_rxheadervalid_4; +wire [127:0] qsfp_gt_rxdata_4; +wire [1:0] qsfp_gt_rxdatavalid_4; + +gtwizard_ultrascale_0 +qsfp_gty_inst ( + .gtwiz_userclk_tx_active_in(>_userclk_tx_active), + .gtwiz_userclk_rx_active_in(>_userclk_rx_active), + + .gtwiz_reset_clk_freerun_in(clk_125mhz_int), + .gtwiz_reset_all_in(rst_125mhz_int), + + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(1'b0), + + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(1'b0), + + .gtwiz_reset_rx_cdr_stable_out(), + + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + + .gtrefclk00_in({1{qsfp_mgt_refclk_0}}), .qpll0outclk_out(), .qpll0outrefclk_out(), - .qpll0lock_out(), - .rxrecclk_out(), + .gtyrxn_in({qsfp_rx4_n, qsfp_rx3_n, qsfp_rx2_n, qsfp_rx1_n}), + .gtyrxp_in({qsfp_rx4_p, qsfp_rx3_p, qsfp_rx2_p, qsfp_rx1_p}), - .txusrclk_out(), - .txusrclk2_out(clk_156mhz_int), + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk), - .gttxreset_out(), - .gtrxreset_out(), + .txdata_in({qsfp_gt_txdata_4, qsfp_gt_txdata_3, qsfp_gt_txdata_2, qsfp_gt_txdata_1}), + .txheader_in({qsfp_gt_txheader_4, qsfp_gt_txheader_3, qsfp_gt_txheader_2, qsfp_gt_txheader_1}), + .txsequence_in({4{1'b0}}), - .txuserrdy_out(), + .txusrclk_in({4{gt_txusrclk}}), + .txusrclk2_in({4{gt_txusrclk}}), - .areset_datapathclk_out(rst_156mhz_int), - .areset_coreclk_out(), - .reset_counter_done_out(), + .gtpowergood_out(), + .gtytxn_out({qsfp_tx4_n, qsfp_tx3_n, qsfp_tx2_n, qsfp_tx1_n}), + .gtytxp_out({qsfp_tx4_p, qsfp_tx3_p, qsfp_tx2_p, qsfp_tx1_p}), + + .rxgearboxslip_in({qsfp_gt_rxgearboxslip_4, qsfp_gt_rxgearboxslip_3, qsfp_gt_rxgearboxslip_2, qsfp_gt_rxgearboxslip_1}), + .rxdata_out({qsfp_gt_rxdata_4, qsfp_gt_rxdata_3, qsfp_gt_rxdata_2, qsfp_gt_rxdata_1}), + .rxdatavalid_out({qsfp_gt_rxdatavalid_4, qsfp_gt_rxdatavalid_3, qsfp_gt_rxdatavalid_2, qsfp_gt_rxdatavalid_1}), + .rxheader_out({qsfp_gt_rxheader_4, qsfp_gt_rxheader_3, qsfp_gt_rxheader_2, qsfp_gt_rxheader_1}), + .rxheadervalid_out({qsfp_gt_rxheadervalid_4, qsfp_gt_rxheadervalid_3, qsfp_gt_rxheadervalid_2, qsfp_gt_rxheadervalid_1}), + .rxoutclk_out(gt_rxclkout), + .rxpmaresetdone_out(gt_rxpmaresetdone), + .rxprgdivresetdone_out(gt_rxprgdivresetdone), + .rxstartofseq_out(), + + .txoutclk_out(gt_txclkout), + .txpmaresetdone_out(gt_txpmaresetdone), + .txprgdivresetdone_out(gt_txprgdivresetdone) +); + +assign qsfp_tx_clk_1_int = clk_156mhz_int; +assign qsfp_tx_rst_1_int = rst_156mhz_int; + +assign qsfp_rx_clk_1_int = gt_rxusrclk[0]; + +sync_reset #( + .N(4) +) +qsfp_rx_rst_1_reset_sync_inst ( + .clk(qsfp_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_phy_1_inst ( + .tx_clk(qsfp_tx_clk_1_int), + .tx_rst(qsfp_tx_rst_1_int), + .rx_clk(qsfp_rx_clk_1_int), + .rx_rst(qsfp_rx_rst_1_int), .xgmii_txd(qsfp_txd_1_int), .xgmii_txc(qsfp_txc_1_int), .xgmii_rxd(qsfp_rxd_1_int), .xgmii_rxc(qsfp_rxc_1_int), - - .txp(qsfp_tx1_p), - .txn(qsfp_tx1_n), - .rxp(qsfp_rx1_p), - .rxn(qsfp_rx1_n), - - .resetdone_out(), - .signal_detect(1'b1), - .tx_fault(1'b0), - - .drp_req(drp_gnt), - .drp_gnt(drp_gnt), - - .core_to_gt_drprdy(gt_drprdy), - .core_to_gt_drpdo(gt_drpdo), - .core_to_gt_drpen(gt_drpen), - .core_to_gt_drpwe(gt_drpwe), - .core_to_gt_drpaddr(gt_drpaddr), - .core_to_gt_drpdi(gt_drpdi), - - .gt_drprdy(gt_drprdy), - .gt_drpdo(gt_drpdo), - .gt_drpen(gt_drpen), - .gt_drpwe(gt_drpwe), - .gt_drpaddr(gt_drpaddr), - .gt_drpdi(gt_drpdi), - - .tx_disable(), - .configuration_vector(configuration_vector), - .status_vector(status_vector), - .pma_pmd_type(3'b101), - .core_status(core_status) + .serdes_tx_data(qsfp_gt_txdata_1), + .serdes_tx_hdr(qsfp_gt_txheader_1), + .serdes_rx_data(qsfp_gt_rxdata_1), + .serdes_rx_hdr(qsfp_gt_rxheader_1), + .serdes_rx_bitslip(qsfp_gt_rxgearboxslip_1), + .rx_block_lock(qsfp_rx_block_lock_1), + .rx_high_ber() ); +assign qsfp_tx_clk_2_int = clk_156mhz_int; +assign qsfp_tx_rst_2_int = rst_156mhz_int; + +assign qsfp_rx_clk_2_int = gt_rxusrclk[1]; + +sync_reset #( + .N(4) +) +qsfp_rx_rst_2_reset_sync_inst ( + .clk(qsfp_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_phy_2_inst ( + .tx_clk(qsfp_tx_clk_2_int), + .tx_rst(qsfp_tx_rst_2_int), + .rx_clk(qsfp_rx_clk_2_int), + .rx_rst(qsfp_rx_rst_2_int), + .xgmii_txd(qsfp_txd_2_int), + .xgmii_txc(qsfp_txc_2_int), + .xgmii_rxd(qsfp_rxd_2_int), + .xgmii_rxc(qsfp_rxc_2_int), + .serdes_tx_data(qsfp_gt_txdata_2), + .serdes_tx_hdr(qsfp_gt_txheader_2), + .serdes_rx_data(qsfp_gt_rxdata_2), + .serdes_rx_hdr(qsfp_gt_rxheader_2), + .serdes_rx_bitslip(qsfp_gt_rxgearboxslip_2), + .rx_block_lock(qsfp_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp_tx_clk_3_int = clk_156mhz_int; +assign qsfp_tx_rst_3_int = rst_156mhz_int; + +assign qsfp_rx_clk_3_int = gt_rxusrclk[2]; + +sync_reset #( + .N(4) +) +qsfp_rx_rst_3_reset_sync_inst ( + .clk(qsfp_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_phy_3_inst ( + .tx_clk(qsfp_tx_clk_3_int), + .tx_rst(qsfp_tx_rst_3_int), + .rx_clk(qsfp_rx_clk_3_int), + .rx_rst(qsfp_rx_rst_3_int), + .xgmii_txd(qsfp_txd_3_int), + .xgmii_txc(qsfp_txc_3_int), + .xgmii_rxd(qsfp_rxd_3_int), + .xgmii_rxc(qsfp_rxc_3_int), + .serdes_tx_data(qsfp_gt_txdata_3), + .serdes_tx_hdr(qsfp_gt_txheader_3), + .serdes_rx_data(qsfp_gt_rxdata_3), + .serdes_rx_hdr(qsfp_gt_rxheader_3), + .serdes_rx_bitslip(qsfp_gt_rxgearboxslip_3), + .rx_block_lock(qsfp_rx_block_lock_3), + .rx_high_ber() +); + +assign qsfp_tx_clk_4_int = clk_156mhz_int; +assign qsfp_tx_rst_4_int = rst_156mhz_int; + +assign qsfp_rx_clk_4_int = gt_rxusrclk[3]; + +sync_reset #( + .N(4) +) +qsfp_rx_rst_4_reset_sync_inst ( + .clk(qsfp_rx_clk_4_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_rx_rst_4_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_phy_4_inst ( + .tx_clk(qsfp_tx_clk_4_int), + .tx_rst(qsfp_tx_rst_4_int), + .rx_clk(qsfp_rx_clk_4_int), + .rx_rst(qsfp_rx_rst_4_int), + .xgmii_txd(qsfp_txd_4_int), + .xgmii_txc(qsfp_txc_4_int), + .xgmii_rxd(qsfp_rxd_4_int), + .xgmii_rxc(qsfp_rxc_4_int), + .serdes_tx_data(qsfp_gt_txdata_4), + .serdes_tx_hdr(qsfp_gt_txheader_4), + .serdes_rx_data(qsfp_gt_rxdata_4), + .serdes_rx_hdr(qsfp_gt_rxheader_4), + .serdes_rx_bitslip(qsfp_gt_rxgearboxslip_4), + .rx_block_lock(qsfp_rx_block_lock_4), + .rx_high_ber() +); + +// // XGMII 10G PHY +// assign qsfp_modsell = 1'b0; +// assign qsfp_resetl = 1'b1; +// assign qsfp_lpmode = 1'b0; + +// wire [63:0] qsfp_txd_1_int; +// wire [7:0] qsfp_txc_1_int; +// wire [63:0] qsfp_rxd_1_int; +// wire [7:0] qsfp_rxc_1_int; +// wire [63:0] qsfp_txd_2_int; +// wire [7:0] qsfp_txc_2_int; +// wire [63:0] qsfp_rxd_2_int = 64'h0707070707070707; +// wire [7:0] qsfp_rxc_2_int = 8'hff; +// wire [63:0] qsfp_txd_3_int; +// wire [7:0] qsfp_txc_3_int; +// wire [63:0] qsfp_rxd_3_int = 64'h0707070707070707; +// wire [7:0] qsfp_rxc_3_int = 8'hff; +// wire [63:0] qsfp_txd_4_int; +// wire [7:0] qsfp_txc_4_int; +// wire [63:0] qsfp_rxd_4_int = 64'h0707070707070707; +// wire [7:0] qsfp_rxc_4_int = 8'hff; + +// wire [535:0] configuration_vector; +// wire [447:0] status_vector; +// wire [7:0] core_status; + +// assign configuration_vector[0] = 1'b0; // PMA Loopback Enable +// assign configuration_vector[14:1] = 0; +// assign configuration_vector[15] = 1'b0; // PMA Reset +// assign configuration_vector[16] = 1'b0; // Global PMD TX Disable +// assign configuration_vector[109:17] = 0; +// assign configuration_vector[110] = 1'b0; // PCS Loopback Enable +// assign configuration_vector[111] = 1'b0; // PCS Reset +// assign configuration_vector[169:112] = 58'd0; // 10GBASE-R Test Pattern Seed A0-3 +// assign configuration_vector[175:170] = 0; +// assign configuration_vector[233:176] = 58'd0; // 10GBASE-R Test Pattern Seed B0-3 +// assign configuration_vector[239:234] = 0; +// assign configuration_vector[240] = 1'b0; // Data Pattern Select +// assign configuration_vector[241] = 1'b0; // Test Pattern Select +// assign configuration_vector[242] = 1'b0; // RX Test Pattern Checking Enable +// assign configuration_vector[243] = 1'b0; // TX Test Pattern Enable +// assign configuration_vector[244] = 1'b0; // PRBS31 TX Test Pattern Enable +// assign configuration_vector[245] = 1'b0; // PRBS31 RX Test Pattern Checking Enable +// assign configuration_vector[383:246] = 0; +// assign configuration_vector[399:384] = 16'h4C4B; // 125 us timer control +// assign configuration_vector[511:400] = 0; +// assign configuration_vector[512] = 1'b0; // Set PMA Link Status +// assign configuration_vector[513] = 1'b0; // Clear PMA/PMD Link Faults +// assign configuration_vector[515:514] = 0; +// assign configuration_vector[516] = 1'b0; // Set PCS Link Status +// assign configuration_vector[517] = 1'b0; // Clear PCS Link Faults +// assign configuration_vector[518] = 1'b0; // Clear 10GBASE-R Status 2 +// assign configuration_vector[519] = 1'b0; // Clear 10GBASE-R Test Pattern Error Counter +// assign configuration_vector[535:520] = 0; + +// wire drp_gnt; +// wire gt_drprdy; +// wire [15:0] gt_drpdo; +// wire gt_drpen; +// wire gt_drpwe; +// wire [15:0] gt_drpaddr; +// wire [15:0] gt_drpdi; + +// ten_gig_eth_pcs_pma_0 +// ten_gig_eth_pcs_pma_inst ( +// .refclk_p(qsfp_mgt_refclk_0_p), +// .refclk_n(qsfp_mgt_refclk_0_n), + +// .dclk(clk_125mhz_int), + +// .coreclk_out(), + +// //.reset(rst_125mhz_int | si570_i2c_init_busy), +// .reset(rst_125mhz_int), + +// .sim_speedup_control(1'b0), + +// .qpll0outclk_out(), +// .qpll0outrefclk_out(), +// .qpll0lock_out(), + +// .rxrecclk_out(), + +// .txusrclk_out(), +// .txusrclk2_out(clk_156mhz_int), + +// .gttxreset_out(), +// .gtrxreset_out(), + +// .txuserrdy_out(), + +// .areset_datapathclk_out(rst_156mhz_int), +// .areset_coreclk_out(), +// .reset_counter_done_out(), + +// .xgmii_txd(qsfp_txd_1_int), +// .xgmii_txc(qsfp_txc_1_int), +// .xgmii_rxd(qsfp_rxd_1_int), +// .xgmii_rxc(qsfp_rxc_1_int), + +// .txp(qsfp_tx1_p), +// .txn(qsfp_tx1_n), +// .rxp(qsfp_rx1_p), +// .rxn(qsfp_rx1_n), + +// .resetdone_out(), +// .signal_detect(1'b1), +// .tx_fault(1'b0), + +// .drp_req(drp_gnt), +// .drp_gnt(drp_gnt), + +// .core_to_gt_drprdy(gt_drprdy), +// .core_to_gt_drpdo(gt_drpdo), +// .core_to_gt_drpen(gt_drpen), +// .core_to_gt_drpwe(gt_drpwe), +// .core_to_gt_drpaddr(gt_drpaddr), +// .core_to_gt_drpdi(gt_drpdi), + +// .gt_drprdy(gt_drprdy), +// .gt_drpdo(gt_drpdo), +// .gt_drpen(gt_drpen), +// .gt_drpwe(gt_drpwe), +// .gt_drpaddr(gt_drpaddr), +// .gt_drpdi(gt_drpdi), + +// .tx_disable(), +// .configuration_vector(configuration_vector), +// .status_vector(status_vector), +// .pma_pmd_type(3'b101), +// .core_status(core_status) +// ); + // SGMII interface to PHY wire phy_gmii_clk_int; wire phy_gmii_rst_int; @@ -581,7 +859,7 @@ gig_eth_pcspma ( wire [7:0] led_int; -assign led = sw[0] ? {7'd0, core_status[0]} : led_int; +assign led = sw[0] ? {4'd0, qsfp_rx_block_lock_4, qsfp_rx_block_lock_3, qsfp_rx_block_lock_2, qsfp_rx_block_lock_1} : led_int; fpga_core core_inst ( @@ -604,20 +882,36 @@ core_inst ( /* * Ethernet: QSFP28 */ + .qsfp_tx_clk_1(qsfp_tx_clk_1_int), + .qsfp_tx_rst_1(qsfp_tx_rst_1_int), .qsfp_txd_1(qsfp_txd_1_int), .qsfp_txc_1(qsfp_txc_1_int), + .qsfp_rx_clk_1(qsfp_rx_clk_1_int), + .qsfp_rx_rst_1(qsfp_rx_rst_1_int), .qsfp_rxd_1(qsfp_rxd_1_int), .qsfp_rxc_1(qsfp_rxc_1_int), + .qsfp_tx_clk_2(qsfp_tx_clk_2_int), + .qsfp_tx_rst_2(qsfp_tx_rst_2_int), .qsfp_txd_2(qsfp_txd_2_int), .qsfp_txc_2(qsfp_txc_2_int), + .qsfp_rx_clk_2(qsfp_rx_clk_2_int), + .qsfp_rx_rst_2(qsfp_rx_rst_2_int), .qsfp_rxd_2(qsfp_rxd_2_int), .qsfp_rxc_2(qsfp_rxc_2_int), + .qsfp_tx_clk_3(qsfp_tx_clk_3_int), + .qsfp_tx_rst_3(qsfp_tx_rst_3_int), .qsfp_txd_3(qsfp_txd_3_int), .qsfp_txc_3(qsfp_txc_3_int), + .qsfp_rx_clk_3(qsfp_rx_clk_3_int), + .qsfp_rx_rst_3(qsfp_rx_rst_3_int), .qsfp_rxd_3(qsfp_rxd_3_int), .qsfp_rxc_3(qsfp_rxc_3_int), + .qsfp_tx_clk_4(qsfp_tx_clk_4_int), + .qsfp_tx_rst_4(qsfp_tx_rst_4_int), .qsfp_txd_4(qsfp_txd_4_int), .qsfp_txc_4(qsfp_txc_4_int), + .qsfp_rx_clk_4(qsfp_rx_clk_4_int), + .qsfp_rx_rst_4(qsfp_rx_rst_4_int), .qsfp_rxd_4(qsfp_rxd_4_int), .qsfp_rxc_4(qsfp_rxc_4_int), /* diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index 20ad98210..16284a70f 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -55,20 +55,36 @@ module fpga_core # /* * Ethernet: QSFP28 */ + input wire qsfp_tx_clk_1, + input wire qsfp_tx_rst_1, output wire [63:0] qsfp_txd_1, output wire [7:0] qsfp_txc_1, + input wire qsfp_rx_clk_1, + input wire qsfp_rx_rst_1, input wire [63:0] qsfp_rxd_1, input wire [7:0] qsfp_rxc_1, + input wire qsfp_tx_clk_2, + input wire qsfp_tx_rst_2, output wire [63:0] qsfp_txd_2, output wire [7:0] qsfp_txc_2, + input wire qsfp_rx_clk_2, + input wire qsfp_rx_rst_2, input wire [63:0] qsfp_rxd_2, input wire [7:0] qsfp_rxc_2, + input wire qsfp_tx_clk_3, + input wire qsfp_tx_rst_3, output wire [63:0] qsfp_txd_3, output wire [7:0] qsfp_txc_3, + input wire qsfp_rx_clk_3, + input wire qsfp_rx_rst_3, input wire [63:0] qsfp_rxd_3, input wire [7:0] qsfp_rxc_3, + input wire qsfp_tx_clk_4, + input wire qsfp_tx_rst_4, output wire [63:0] qsfp_txd_4, output wire [7:0] qsfp_txc_4, + input wire qsfp_rx_clk_4, + input wire qsfp_rx_rst_4, input wire [63:0] qsfp_rxd_4, input wire [7:0] qsfp_rxc_4, @@ -365,10 +381,10 @@ eth_mac_10g_fifo #( .RX_FRAME_FIFO(1) ) eth_mac_10g_fifo_inst ( - .rx_clk(clk), - .rx_rst(rst), - .tx_clk(clk), - .tx_rst(rst), + .rx_clk(qsfp_rx_clk_1), + .rx_rst(qsfp_rx_rst_1), + .tx_clk(qsfp_tx_clk_1), + .tx_rst(qsfp_tx_rst_1), .logic_clk(clk), .logic_rst(rst), diff --git a/example/VCU108/fpga_10g/rtl/i2c_master.v b/example/VCU108/fpga_10g/rtl/i2c_master.v deleted file mode 100644 index 95d3a5212..000000000 --- a/example/VCU108/fpga_10g/rtl/i2c_master.v +++ /dev/null @@ -1,895 +0,0 @@ -/* - -Copyright (c) 2015-2018 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 - -/* - * I2C master - */ -module i2c_master ( - input wire clk, - input wire rst, - - /* - * Host interface - */ - input wire [6:0] cmd_address, - input wire cmd_start, - input wire cmd_read, - input wire cmd_write, - input wire cmd_write_multiple, - input wire cmd_stop, - input wire cmd_valid, - output wire cmd_ready, - - input wire [7:0] data_in, - input wire data_in_valid, - output wire data_in_ready, - input wire data_in_last, - - output wire [7:0] data_out, - output wire data_out_valid, - input wire data_out_ready, - output wire data_out_last, - - /* - * I2C interface - */ - input wire scl_i, - output wire scl_o, - output wire scl_t, - input wire sda_i, - output wire sda_o, - output wire sda_t, - - /* - * Status - */ - output wire busy, - output wire bus_control, - output wire bus_active, - output wire missed_ack, - - /* - * Configuration - */ - input wire [15:0] prescale, - input wire stop_on_idle -); - -/* - -I2C - -Read - __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ -sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_\_R___A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A____/ - ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ -scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP - -Write - __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ -sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_/_W_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_/_N_\__/ - ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ -scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP - -Commands: - -read - read data byte - set start to force generation of a start condition - start is implied when bus is inactive or active with write or different address - set stop to issue a stop condition after reading current byte - if stop is set with read command, then data_out_last will be set - -write - write data byte - set start to force generation of a start condition - start is implied when bus is inactive or active with read or different address - set stop to issue a stop condition after writing current byte - -write multiple - write multiple data bytes (until data_in_last) - set start to force generation of a start condition - start is implied when bus is inactive or active with read or different address - set stop to issue a stop condition after writing block - -stop - issue stop condition if bus is active - -Status: - -busy - module is communicating over the bus - -bus_control - module has control of bus in active state - -bus_active - bus is active, not necessarily controlled by this module - -missed_ack - strobed when a slave ack is missed - -Parameters: - -prescale - set prescale to 1/4 of the minimum clock period in units - of input clk cycles (prescale = Fclk / (FI2Cclk * 4)) - -stop_on_idle - automatically issue stop when command input is not valid - -Example of interfacing with tristate pins: -(this will work for any tristate bus) - -assign scl_i = scl_pin; -assign scl_pin = scl_t ? 1'bz : scl_o; -assign sda_i = sda_pin; -assign sda_pin = sda_t ? 1'bz : sda_o; - -Equivalent code that does not use *_t connections: -(we can get away with this because I2C is open-drain) - -assign scl_i = scl_pin; -assign scl_pin = scl_o ? 1'bz : 1'b0; -assign sda_i = sda_pin; -assign sda_pin = sda_o ? 1'bz : 1'b0; - -Example of two interconnected I2C devices: - -assign scl_1_i = scl_1_o & scl_2_o; -assign scl_2_i = scl_1_o & scl_2_o; -assign sda_1_i = sda_1_o & sda_2_o; -assign sda_2_i = sda_1_o & sda_2_o; - -Example of two I2C devices sharing the same pins: - -assign scl_1_i = scl_pin; -assign scl_2_i = scl_pin; -assign scl_pin = (scl_1_o & scl_2_o) ? 1'bz : 1'b0; -assign sda_1_i = sda_pin; -assign sda_2_i = sda_pin; -assign sda_pin = (sda_1_o & sda_2_o) ? 1'bz : 1'b0; - -Notes: - -scl_o should not be connected directly to scl_i, only via AND logic or a tristate -I/O pin. This would prevent devices from stretching the clock period. - -*/ - -localparam [4:0] - STATE_IDLE = 4'd0, - STATE_ACTIVE_WRITE = 4'd1, - STATE_ACTIVE_READ = 4'd2, - STATE_START_WAIT = 4'd3, - STATE_START = 4'd4, - STATE_ADDRESS_1 = 4'd5, - STATE_ADDRESS_2 = 4'd6, - STATE_WRITE_1 = 4'd7, - STATE_WRITE_2 = 4'd8, - STATE_WRITE_3 = 4'd9, - STATE_READ = 4'd10, - STATE_STOP = 4'd11; - -reg [4:0] state_reg = STATE_IDLE, state_next; - -localparam [4:0] - PHY_STATE_IDLE = 5'd0, - PHY_STATE_ACTIVE = 5'd1, - PHY_STATE_REPEATED_START_1 = 5'd2, - PHY_STATE_REPEATED_START_2 = 5'd3, - PHY_STATE_START_1 = 5'd4, - PHY_STATE_START_2 = 5'd5, - PHY_STATE_WRITE_BIT_1 = 5'd6, - PHY_STATE_WRITE_BIT_2 = 5'd7, - PHY_STATE_WRITE_BIT_3 = 5'd8, - PHY_STATE_READ_BIT_1 = 5'd9, - PHY_STATE_READ_BIT_2 = 5'd10, - PHY_STATE_READ_BIT_3 = 5'd11, - PHY_STATE_READ_BIT_4 = 5'd12, - PHY_STATE_STOP_1 = 5'd13, - PHY_STATE_STOP_2 = 5'd14, - PHY_STATE_STOP_3 = 5'd15; - -reg [4:0] phy_state_reg = STATE_IDLE, phy_state_next; - -reg phy_start_bit; -reg phy_stop_bit; -reg phy_write_bit; -reg phy_read_bit; -reg phy_release_bus; - -reg phy_tx_data; - -reg phy_rx_data_reg = 1'b0, phy_rx_data_next; - -reg [6:0] addr_reg = 7'd0, addr_next; -reg [7:0] data_reg = 8'd0, data_next; -reg last_reg = 1'b0, last_next; - -reg mode_read_reg = 1'b0, mode_read_next; -reg mode_write_multiple_reg = 1'b0, mode_write_multiple_next; -reg mode_stop_reg = 1'b0, mode_stop_next; - -reg [16:0] delay_reg = 16'd0, delay_next; -reg delay_scl_reg = 1'b0, delay_scl_next; -reg delay_sda_reg = 1'b0, delay_sda_next; - -reg [3:0] bit_count_reg = 4'd0, bit_count_next; - -reg cmd_ready_reg = 1'b0, cmd_ready_next; - -reg data_in_ready_reg = 1'b0, data_in_ready_next; - -reg [7:0] data_out_reg = 8'd0, data_out_next; -reg data_out_valid_reg = 1'b0, data_out_valid_next; -reg data_out_last_reg = 1'b0, data_out_last_next; - -reg scl_i_reg = 1'b1; -reg sda_i_reg = 1'b1; - -reg scl_o_reg = 1'b1, scl_o_next; -reg sda_o_reg = 1'b1, sda_o_next; - -reg last_scl_i_reg = 1'b1; -reg last_sda_i_reg = 1'b1; - -reg busy_reg = 1'b0; -reg bus_active_reg = 1'b0; -reg bus_control_reg = 1'b0, bus_control_next; -reg missed_ack_reg = 1'b0, missed_ack_next; - -assign cmd_ready = cmd_ready_reg; - -assign data_in_ready = data_in_ready_reg; - -assign data_out = data_out_reg; -assign data_out_valid = data_out_valid_reg; -assign data_out_last = data_out_last_reg; - -assign scl_o = scl_o_reg; -assign scl_t = scl_o_reg; -assign sda_o = sda_o_reg; -assign sda_t = sda_o_reg; - -assign busy = busy_reg; -assign bus_active = bus_active_reg; -assign bus_control = bus_control_reg; -assign missed_ack = missed_ack_reg; - -wire scl_posedge = scl_i_reg & ~last_scl_i_reg; -wire scl_negedge = ~scl_i_reg & last_scl_i_reg; -wire sda_posedge = sda_i_reg & ~last_sda_i_reg; -wire sda_negedge = ~sda_i_reg & last_sda_i_reg; - -wire start_bit = sda_negedge & scl_i_reg; -wire stop_bit = sda_posedge & scl_i_reg; - -always @* begin - state_next = STATE_IDLE; - - phy_start_bit = 1'b0; - phy_stop_bit = 1'b0; - phy_write_bit = 1'b0; - phy_read_bit = 1'b0; - phy_tx_data = 1'b0; - phy_release_bus = 1'b0; - - addr_next = addr_reg; - data_next = data_reg; - last_next = last_reg; - - mode_read_next = mode_read_reg; - mode_write_multiple_next = mode_write_multiple_reg; - mode_stop_next = mode_stop_reg; - - bit_count_next = bit_count_reg; - - cmd_ready_next = 1'b0; - - data_in_ready_next = 1'b0; - - data_out_next = data_out_reg; - data_out_valid_next = data_out_valid_reg & ~data_out_ready; - data_out_last_next = data_out_last_reg; - - missed_ack_next = 1'b0; - - // generate delays - if (phy_state_reg != PHY_STATE_IDLE && phy_state_reg != PHY_STATE_ACTIVE) begin - // wait for phy operation - state_next = state_reg; - end else begin - // process states - case (state_reg) - STATE_IDLE: begin - // line idle - cmd_ready_next = 1'b1; - - if (cmd_ready & cmd_valid) begin - // command valid - if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin - // read or write command - addr_next = cmd_address; - mode_read_next = cmd_read; - mode_write_multiple_next = cmd_write_multiple; - mode_stop_next = cmd_stop; - - cmd_ready_next = 1'b0; - - // start bit - if (bus_active) begin - state_next = STATE_START_WAIT; - end else begin - phy_start_bit = 1'b1; - bit_count_next = 4'd8; - state_next = STATE_ADDRESS_1; - end - end else begin - // invalid or unspecified - ignore - state_next = STATE_IDLE; - end - end else begin - state_next = STATE_IDLE; - end - end - STATE_ACTIVE_WRITE: begin - // line active with current address and read/write mode - cmd_ready_next = 1'b1; - - if (cmd_ready & cmd_valid) begin - // command valid - if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin - // read or write command - addr_next = cmd_address; - mode_read_next = cmd_read; - mode_write_multiple_next = cmd_write_multiple; - mode_stop_next = cmd_stop; - - cmd_ready_next = 1'b0; - - if (cmd_start || cmd_address != addr_reg || cmd_read) begin - // address or mode mismatch or forced start - repeated start - - // repeated start bit - phy_start_bit = 1'b1; - bit_count_next = 4'd8; - state_next = STATE_ADDRESS_1; - end else begin - // address and mode match - - // start write - data_in_ready_next = 1'b1; - state_next = STATE_WRITE_1; - end - end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin - // stop command - phy_stop_bit = 1'b1; - state_next = STATE_IDLE; - end else begin - // invalid or unspecified - ignore - state_next = STATE_ACTIVE_WRITE; - end - end else begin - if (stop_on_idle & cmd_ready & ~cmd_valid) begin - // no waiting command and stop_on_idle selected, issue stop condition - phy_stop_bit = 1'b1; - state_next = STATE_IDLE; - end else begin - state_next = STATE_ACTIVE_WRITE; - end - end - end - STATE_ACTIVE_READ: begin - // line active to current address - cmd_ready_next = ~data_out_valid; - - if (cmd_ready & cmd_valid) begin - // command valid - if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin - // read or write command - addr_next = cmd_address; - mode_read_next = cmd_read; - mode_write_multiple_next = cmd_write_multiple; - mode_stop_next = cmd_stop; - - cmd_ready_next = 1'b0; - - if (cmd_start || cmd_address != addr_reg || cmd_write) begin - // address or mode mismatch or forced start - repeated start - - // write nack for previous read - phy_write_bit = 1'b1; - phy_tx_data = 1'b1; - // repeated start bit - state_next = STATE_START; - end else begin - // address and mode match - - // write ack for previous read - phy_write_bit = 1'b1; - phy_tx_data = 1'b0; - // start next read - bit_count_next = 4'd8; - data_next = 8'd0; - state_next = STATE_READ; - end - end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin - // stop command - // write nack for previous read - phy_write_bit = 1'b1; - phy_tx_data = 1'b1; - // send stop bit - state_next = STATE_STOP; - end else begin - // invalid or unspecified - ignore - state_next = STATE_ACTIVE_READ; - end - end else begin - if (stop_on_idle & cmd_ready & ~cmd_valid) begin - // no waiting command and stop_on_idle selected, issue stop condition - // write ack for previous read - phy_write_bit = 1'b1; - phy_tx_data = 1'b1; - // send stop bit - state_next = STATE_STOP; - end else begin - state_next = STATE_ACTIVE_READ; - end - end - end - STATE_START_WAIT: begin - // wait for bus idle - - if (bus_active) begin - state_next = STATE_START_WAIT; - end else begin - // bus is idle, take control - phy_start_bit = 1'b1; - bit_count_next = 4'd8; - state_next = STATE_ADDRESS_1; - end - end - STATE_START: begin - // send start bit - - phy_start_bit = 1'b1; - bit_count_next = 4'd8; - state_next = STATE_ADDRESS_1; - end - STATE_ADDRESS_1: begin - // send address - bit_count_next = bit_count_reg - 1; - if (bit_count_reg > 1) begin - // send address - phy_write_bit = 1'b1; - phy_tx_data = addr_reg[bit_count_reg-2]; - state_next = STATE_ADDRESS_1; - end else if (bit_count_reg > 0) begin - // send read/write bit - phy_write_bit = 1'b1; - phy_tx_data = mode_read_reg; - state_next = STATE_ADDRESS_1; - end else begin - // read ack bit - phy_read_bit = 1'b1; - state_next = STATE_ADDRESS_2; - end - end - STATE_ADDRESS_2: begin - // read ack bit - missed_ack_next = phy_rx_data_reg; - - if (mode_read_reg) begin - // start read - bit_count_next = 4'd8; - data_next = 1'b0; - state_next = STATE_READ; - end else begin - // start write - data_in_ready_next = 1'b1; - state_next = STATE_WRITE_1; - end - end - STATE_WRITE_1: begin - data_in_ready_next = 1'b1; - - if (data_in_ready & data_in_valid) begin - // got data, start write - data_next = data_in; - last_next = data_in_last; - bit_count_next = 4'd8; - data_in_ready_next = 1'b0; - state_next = STATE_WRITE_2; - end else begin - // wait for data - state_next = STATE_WRITE_1; - end - end - STATE_WRITE_2: begin - // send data - bit_count_next = bit_count_reg - 1; - if (bit_count_reg > 0) begin - // write data bit - phy_write_bit = 1'b1; - phy_tx_data = data_reg[bit_count_reg-1]; - state_next = STATE_WRITE_2; - end else begin - // read ack bit - phy_read_bit = 1'b1; - state_next = STATE_WRITE_3; - end - end - STATE_WRITE_3: begin - // read ack bit - missed_ack_next = phy_rx_data_reg; - - if (mode_write_multiple_reg && !last_reg) begin - // more to write - state_next = STATE_WRITE_1; - end else if (mode_stop_reg) begin - // last cycle and stop selected - phy_stop_bit = 1'b1; - state_next = STATE_IDLE; - end else begin - // otherwise, return to bus active state - state_next = STATE_ACTIVE_WRITE; - end - end - STATE_READ: begin - // read data - - bit_count_next = bit_count_reg - 1; - data_next = {data_reg[6:0], phy_rx_data_reg}; - if (bit_count_reg > 0) begin - // read next bit - phy_read_bit = 1'b1; - state_next = STATE_READ; - end else begin - // output data word - data_out_next = data_next; - data_out_valid_next = 1'b1; - data_out_last_next = 1'b0; - if (mode_stop_reg) begin - // send nack and stop - data_out_last_next = 1'b1; - phy_write_bit = 1'b1; - phy_tx_data = 1'b1; - state_next = STATE_STOP; - end else begin - // return to bus active state - state_next = STATE_ACTIVE_READ; - end - end - end - STATE_STOP: begin - // send stop bit - phy_stop_bit = 1'b1; - state_next = STATE_IDLE; - end - endcase - end -end - -always @* begin - phy_state_next = PHY_STATE_IDLE; - - phy_rx_data_next = phy_rx_data_reg; - - delay_next = delay_reg; - delay_scl_next = delay_scl_reg; - delay_sda_next = delay_sda_reg; - - scl_o_next = scl_o_reg; - sda_o_next = sda_o_reg; - - bus_control_next = bus_control_reg; - - if (phy_release_bus) begin - // release bus and return to idle state - sda_o_next = 1'b1; - scl_o_next = 1'b1; - delay_scl_next = 1'b0; - delay_sda_next = 1'b0; - delay_next = 1'b0; - phy_state_next = PHY_STATE_IDLE; - end else if (delay_scl_reg) begin - // wait for SCL to match command - delay_scl_next = scl_o_reg & ~scl_i_reg; - phy_state_next = phy_state_reg; - end else if (delay_sda_reg) begin - // wait for SDA to match command - delay_sda_next = sda_o_reg & ~sda_i_reg; - phy_state_next = phy_state_reg; - end else if (delay_reg > 0) begin - // time delay - delay_next = delay_reg - 1; - phy_state_next = phy_state_reg; - end else begin - case (phy_state_reg) - PHY_STATE_IDLE: begin - // bus idle - wait for start command - sda_o_next = 1'b1; - scl_o_next = 1'b1; - if (phy_start_bit) begin - sda_o_next = 1'b0; - delay_next = prescale; - phy_state_next = PHY_STATE_START_1; - end else begin - phy_state_next = PHY_STATE_IDLE; - end - end - PHY_STATE_ACTIVE: begin - // bus active - if (phy_start_bit) begin - sda_o_next = 1'b1; - delay_next = prescale; - phy_state_next = PHY_STATE_REPEATED_START_1; - end else if (phy_write_bit) begin - sda_o_next = phy_tx_data; - delay_next = prescale; - phy_state_next = PHY_STATE_WRITE_BIT_1; - end else if (phy_read_bit) begin - sda_o_next = 1'b1; - delay_next = prescale; - phy_state_next = PHY_STATE_READ_BIT_1; - end else if (phy_stop_bit) begin - sda_o_next = 1'b0; - delay_next = prescale; - phy_state_next = PHY_STATE_STOP_1; - end else begin - phy_state_next = PHY_STATE_ACTIVE; - end - end - PHY_STATE_REPEATED_START_1: begin - // generate repeated start bit - // ______ - // sda XXX/ \_______ - // _______ - // scl ______/ \___ - // - - scl_o_next = 1'b1; - delay_scl_next = 1'b1; - delay_next = prescale; - phy_state_next = PHY_STATE_REPEATED_START_2; - end - PHY_STATE_REPEATED_START_2: begin - // generate repeated start bit - // ______ - // sda XXX/ \_______ - // _______ - // scl ______/ \___ - // - - sda_o_next = 1'b0; - delay_next = prescale; - phy_state_next = PHY_STATE_START_1; - end - PHY_STATE_START_1: begin - // generate start bit - // ___ - // sda \_______ - // _______ - // scl \___ - // - - scl_o_next = 1'b0; - delay_next = prescale; - phy_state_next = PHY_STATE_START_2; - end - PHY_STATE_START_2: begin - // generate start bit - // ___ - // sda \_______ - // _______ - // scl \___ - // - - bus_control_next = 1'b1; - phy_state_next = PHY_STATE_ACTIVE; - end - PHY_STATE_WRITE_BIT_1: begin - // write bit - // ________ - // sda X________X - // ____ - // scl __/ \__ - - scl_o_next = 1'b1; - delay_scl_next = 1'b1; - delay_next = prescale << 1; - phy_state_next = PHY_STATE_WRITE_BIT_2; - end - PHY_STATE_WRITE_BIT_2: begin - // write bit - // ________ - // sda X________X - // ____ - // scl __/ \__ - - scl_o_next = 1'b0; - delay_next = prescale; - phy_state_next = PHY_STATE_WRITE_BIT_3; - end - PHY_STATE_WRITE_BIT_3: begin - // write bit - // ________ - // sda X________X - // ____ - // scl __/ \__ - - phy_state_next = PHY_STATE_ACTIVE; - end - PHY_STATE_READ_BIT_1: begin - // read bit - // ________ - // sda X________X - // ____ - // scl __/ \__ - - scl_o_next = 1'b1; - delay_scl_next = 1'b1; - delay_next = prescale; - phy_state_next = PHY_STATE_READ_BIT_2; - end - PHY_STATE_READ_BIT_2: begin - // read bit - // ________ - // sda X________X - // ____ - // scl __/ \__ - - phy_rx_data_next = sda_i_reg; - delay_next = prescale; - phy_state_next = PHY_STATE_READ_BIT_3; - end - PHY_STATE_READ_BIT_3: begin - // read bit - // ________ - // sda X________X - // ____ - // scl __/ \__ - - scl_o_next = 1'b0; - delay_next = prescale; - phy_state_next = PHY_STATE_READ_BIT_4; - end - PHY_STATE_READ_BIT_4: begin - // read bit - // ________ - // sda X________X - // ____ - // scl __/ \__ - - phy_state_next = PHY_STATE_ACTIVE; - end - PHY_STATE_STOP_1: begin - // stop bit - // ___ - // sda XXX\_______/ - // _______ - // scl _______/ - - scl_o_next = 1'b1; - delay_scl_next = 1'b1; - delay_next = prescale; - phy_state_next = PHY_STATE_STOP_2; - end - PHY_STATE_STOP_2: begin - // stop bit - // ___ - // sda XXX\_______/ - // _______ - // scl _______/ - - sda_o_next = 1'b1; - delay_next = prescale; - phy_state_next = PHY_STATE_STOP_3; - end - PHY_STATE_STOP_3: begin - // stop bit - // ___ - // sda XXX\_______/ - // _______ - // scl _______/ - - bus_control_next = 1'b0; - phy_state_next = PHY_STATE_IDLE; - end - endcase - end -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - phy_state_reg <= PHY_STATE_IDLE; - delay_reg <= 16'd0; - delay_scl_reg <= 1'b0; - delay_sda_reg <= 1'b0; - cmd_ready_reg <= 1'b0; - data_in_ready_reg <= 1'b0; - data_out_valid_reg <= 1'b0; - scl_o_reg <= 1'b1; - sda_o_reg <= 1'b1; - busy_reg <= 1'b0; - bus_active_reg <= 1'b0; - bus_control_reg <= 1'b0; - missed_ack_reg <= 1'b0; - end else begin - state_reg <= state_next; - phy_state_reg <= phy_state_next; - - delay_reg <= delay_next; - delay_scl_reg <= delay_scl_next; - delay_sda_reg <= delay_sda_next; - - cmd_ready_reg <= cmd_ready_next; - data_in_ready_reg <= data_in_ready_next; - data_out_valid_reg <= data_out_valid_next; - - scl_o_reg <= scl_o_next; - sda_o_reg <= sda_o_next; - - busy_reg <= !(state_reg == STATE_IDLE || state_reg == STATE_ACTIVE_WRITE || state_reg == STATE_ACTIVE_READ); - - if (start_bit) begin - bus_active_reg <= 1'b1; - end else if (stop_bit) begin - bus_active_reg <= 1'b0; - end else begin - bus_active_reg <= bus_active_reg; - end - - bus_control_reg <= bus_control_next; - missed_ack_reg <= missed_ack_next; - end - - phy_rx_data_reg <= phy_rx_data_next; - - addr_reg <= addr_next; - data_reg <= data_next; - last_reg <= last_next; - - mode_read_reg <= mode_read_next; - mode_write_multiple_reg <= mode_write_multiple_next; - mode_stop_reg <= mode_stop_next; - - bit_count_reg <= bit_count_next; - - data_out_reg <= data_out_next; - data_out_last_reg <= data_out_last_next; - - scl_i_reg <= scl_i; - sda_i_reg <= sda_i; - last_scl_i_reg <= scl_i_reg; - last_sda_i_reg <= sda_i_reg; -end - -endmodule diff --git a/example/VCU108/fpga_10g/rtl/si570_i2c_init.v b/example/VCU108/fpga_10g/rtl/si570_i2c_init.v deleted file mode 100644 index cea21ed6e..000000000 --- a/example/VCU108/fpga_10g/rtl/si570_i2c_init.v +++ /dev/null @@ -1,486 +0,0 @@ -/* - -Copyright (c) 2015-2018 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 - -/* - * si570_i2c_init - */ -module si570_i2c_init ( - input wire clk, - input wire rst, - - /* - * I2C master interface - */ - output wire [6:0] cmd_address, - output wire cmd_start, - output wire cmd_read, - output wire cmd_write, - output wire cmd_write_multiple, - output wire cmd_stop, - output wire cmd_valid, - input wire cmd_ready, - - output wire [7:0] data_out, - output wire data_out_valid, - input wire data_out_ready, - output wire data_out_last, - - /* - * Status - */ - output wire busy, - - /* - * Configuration - */ - input wire start -); - -/* - -Generic module for I2C bus initialization. Good for use when multiple devices -on an I2C bus must be initialized on system start without intervention of a -general-purpose processor. - -Copy this file and change init_data and INIT_DATA_LEN as needed. - -This module can be used in two modes: simple device initalization, or multiple -device initialization. In multiple device mode, the same initialization sequence -can be performed on multiple different device addresses. - -To use single device mode, only use the start write to address and write data commands. -The module will generate the I2C commands in sequential order. Terminate the list -with a 0 entry. - -To use the multiple device mode, use the start data and start address block commands -to set up lists of initialization data and device addresses. The module enters -multiple device mode upon seeing a start data block command. The module stores the -offset of the start of the data block and then skips ahead until it reaches a start -address block command. The module will store the offset to the address block and -read the first address in the block. Then it will jump back to the data block -and execute it, substituting the stored address for each current address write -command. Upon reaching the start address block command, the module will read out the -next address and start again at the top of the data block. If the module encounters -a start data block command while looking for an address, then it will store a new data -offset and then look for a start address block command. Terminate the list with a 0 -entry. Normal address commands will operate normally inside a data block. - -Commands: - -00 0000000 : stop -00 0000001 : exit multiple device mode -00 0000011 : start write to current address -00 0001000 : start address block -00 0001001 : start data block -00 1000001 : send I2C stop -01 aaaaaaa : start write to address -1 dddddddd : write 8-bit data - -Examples - -write 0x11223344 to register 0x0004 on device at 0x50 - -01 1010000 start write to 0x50 -1 00000000 write address 0x0004 -1 00000100 -1 00010001 write data 0x11223344 -1 00100010 -1 00110011 -1 01000100 -0 00000000 stop - -write 0x11223344 to register 0x0004 on devices at 0x50, 0x51, 0x52, and 0x53 - -00 0001001 start data block -00 0000011 start write to current address -1 00000100 -1 00010001 write data 0x11223344 -1 00100010 -1 00110011 -1 01000100 -00 0001000 start address block -01 1010000 address 0x50 -01 1010000 address 0x51 -01 1010000 address 0x52 -01 1010000 address 0x53 -00 0000000 stop - -*/ - -// init_data ROM -localparam INIT_DATA_LEN = 24; - -reg [8:0] init_data [INIT_DATA_LEN-1:0]; - -initial begin - // set up I2C muxes to select U32 - init_data[0] = {2'b01, 7'b1110101}; // select U80 (0x75) - init_data[1] = {1'b1, 8'b00000000}; // disconnect all outputs - init_data[2] = {2'b00, 7'b1000001}; // I2C stop - init_data[3] = {2'b01, 7'b1110100}; // select U28 (0x74) - init_data[4] = {1'b1, 8'b00000001}; // connect only output 0 to SI570 - init_data[5] = {2'b00, 7'b1000001}; // I2C stop - // set SI570 output frequency (U32) - // freeze DCO - init_data[6] = {2'b01, 7'b1011101}; - init_data[7] = {1'b1, 8'd137}; - init_data[8] = {1'b1, 8'h10}; // 137: 0x10 - // set output to 156.25 MHz (HS_DIV=4 N1=8 DCO=5000.0 RFREQ=0x02BC035168) - init_data[9] = {2'b01, 7'b1011101}; - init_data[10] = {1'b1, 8'd7}; - init_data[11] = {1'b1, 8'h01}; // 7: HS_DIV[2:0], N1[6:2] - init_data[12] = {1'b1, 8'hC2}; // 8: N1[1:0], RFREQ[37:32] - init_data[13] = {1'b1, 8'hBC}; // 9: RFREQ[31:24] - init_data[14] = {1'b1, 8'h03}; // 10: RFREQ[23:16] - init_data[15] = {1'b1, 8'h51}; // 11: RFREQ[15:8] - init_data[16] = {1'b1, 8'h68}; // 12: RFREQ[7:0] - // un-freeze DCO - init_data[17] = {2'b01, 7'b1011101}; - init_data[18] = {1'b1, 8'd137}; - init_data[19] = {1'b1, 8'h00}; // 137: 0x00 - // new frequency - init_data[20] = {2'b01, 7'b1011101}; - init_data[21] = {1'b1, 8'd135}; - init_data[22] = {1'b1, 8'h40}; // 135: 0x40 - init_data[23] = 9'd0; // stop -end - -localparam [3:0] - STATE_IDLE = 3'd0, - STATE_RUN = 3'd1, - STATE_TABLE_1 = 3'd2, - STATE_TABLE_2 = 3'd3, - STATE_TABLE_3 = 3'd4; - -reg [4:0] state_reg = STATE_IDLE, state_next; - -parameter AW = $clog2(INIT_DATA_LEN); - -reg [8:0] init_data_reg = 9'd0; - -reg [AW-1:0] address_reg = {AW{1'b0}}, address_next; -reg [AW-1:0] address_ptr_reg = {AW{1'b0}}, address_ptr_next; -reg [AW-1:0] data_ptr_reg = {AW{1'b0}}, data_ptr_next; - -reg [6:0] cur_address_reg = 7'd0, cur_address_next; - -reg [6:0] cmd_address_reg = 7'd0, cmd_address_next; -reg cmd_start_reg = 1'b0, cmd_start_next; -reg cmd_write_reg = 1'b0, cmd_write_next; -reg cmd_stop_reg = 1'b0, cmd_stop_next; -reg cmd_valid_reg = 1'b0, cmd_valid_next; - -reg [7:0] data_out_reg = 8'd0, data_out_next; -reg data_out_valid_reg = 1'b0, data_out_valid_next; - -reg start_flag_reg = 1'b0, start_flag_next; - -reg busy_reg = 1'b0; - -assign cmd_address = cmd_address_reg; -assign cmd_start = cmd_start_reg; -assign cmd_read = 1'b0; -assign cmd_write = cmd_write_reg; -assign cmd_write_multiple = 1'b0; -assign cmd_stop = cmd_stop_reg; -assign cmd_valid = cmd_valid_reg; - -assign data_out = data_out_reg; -assign data_out_valid = data_out_valid_reg; -assign data_out_last = 1'b1; - -assign busy = busy_reg; - -always @* begin - state_next = STATE_IDLE; - - address_next = address_reg; - address_ptr_next = address_ptr_reg; - data_ptr_next = data_ptr_reg; - - cur_address_next = cur_address_reg; - - cmd_address_next = cmd_address_reg; - cmd_start_next = cmd_start_reg & ~(cmd_valid & cmd_ready); - cmd_write_next = cmd_write_reg & ~(cmd_valid & cmd_ready); - cmd_stop_next = cmd_stop_reg & ~(cmd_valid & cmd_ready); - cmd_valid_next = cmd_valid_reg & ~cmd_ready; - - data_out_next = data_out_reg; - data_out_valid_next = data_out_valid_reg & ~data_out_ready; - - start_flag_next = start_flag_reg; - - if (cmd_valid | data_out_valid) begin - // wait for output registers to clear - state_next = state_reg; - end else begin - case (state_reg) - STATE_IDLE: begin - // wait for start signal - if (~start_flag_reg & start) begin - address_next = {AW{1'b0}}; - start_flag_next = 1'b1; - state_next = STATE_RUN; - end else begin - state_next = STATE_IDLE; - end - end - STATE_RUN: begin - // process commands - if (init_data_reg[8] == 1'b1) begin - // write data - cmd_write_next = 1'b1; - cmd_stop_next = 1'b0; - cmd_valid_next = 1'b1; - - data_out_next = init_data_reg[7:0]; - data_out_valid_next = 1'b1; - - address_next = address_reg + 1; - - state_next = STATE_RUN; - end else if (init_data_reg[8:7] == 2'b01) begin - // write address - cmd_address_next = init_data_reg[6:0]; - cmd_start_next = 1'b1; - - address_next = address_reg + 1; - - state_next = STATE_RUN; - end else if (init_data_reg == 9'b001000001) begin - // send stop - cmd_write_next = 1'b0; - cmd_start_next = 1'b0; - cmd_stop_next = 1'b1; - cmd_valid_next = 1'b1; - - address_next = address_reg + 1; - - state_next = STATE_RUN; - end else if (init_data_reg == 9'b000001001) begin - // data table start - data_ptr_next = address_reg + 1; - address_next = address_reg + 1; - state_next = STATE_TABLE_1; - end else if (init_data_reg == 9'd0) begin - // stop - cmd_start_next = 1'b0; - cmd_write_next = 1'b0; - cmd_stop_next = 1'b1; - cmd_valid_next = 1'b1; - - state_next = STATE_IDLE; - end else begin - // invalid command, skip - address_next = address_reg + 1; - state_next = STATE_RUN; - end - end - STATE_TABLE_1: begin - // find address table start - if (init_data_reg == 9'b000001000) begin - // address table start - address_ptr_next = address_reg + 1; - address_next = address_reg + 1; - state_next = STATE_TABLE_2; - end else if (init_data_reg == 9'b000001001) begin - // data table start - data_ptr_next = address_reg + 1; - address_next = address_reg + 1; - state_next = STATE_TABLE_1; - end else if (init_data_reg == 1) begin - // exit mode - address_next = address_reg + 1; - state_next = STATE_RUN; - end else if (init_data_reg == 9'd0) begin - // stop - cmd_start_next = 1'b0; - cmd_write_next = 1'b0; - cmd_stop_next = 1'b1; - cmd_valid_next = 1'b1; - - state_next = STATE_IDLE; - end else begin - // invalid command, skip - address_next = address_reg + 1; - state_next = STATE_TABLE_1; - end - end - STATE_TABLE_2: begin - // find next address - if (init_data_reg[8:7] == 2'b01) begin - // write address command - // store address and move to data table - cur_address_next = init_data_reg[6:0]; - address_ptr_next = address_reg + 1; - address_next = data_ptr_reg; - state_next = STATE_TABLE_3; - end else if (init_data_reg == 9'b000001001) begin - // data table start - data_ptr_next = address_reg + 1; - address_next = address_reg + 1; - state_next = STATE_TABLE_1; - end else if (init_data_reg == 9'd1) begin - // exit mode - address_next = address_reg + 1; - state_next = STATE_RUN; - end else if (init_data_reg == 9'd0) begin - // stop - cmd_start_next = 1'b0; - cmd_write_next = 1'b0; - cmd_stop_next = 1'b1; - cmd_valid_next = 1'b1; - - state_next = STATE_IDLE; - end else begin - // invalid command, skip - address_next = address_reg + 1; - state_next = STATE_TABLE_2; - end - end - STATE_TABLE_3: begin - // process data table with selected address - if (init_data_reg[8] == 1'b1) begin - // write data - cmd_write_next = 1'b1; - cmd_stop_next = 1'b0; - cmd_valid_next = 1'b1; - - data_out_next = init_data_reg[7:0]; - data_out_valid_next = 1'b1; - - address_next = address_reg + 1; - - state_next = STATE_TABLE_3; - end else if (init_data_reg[8:7] == 2'b01) begin - // write address - cmd_address_next = init_data_reg[6:0]; - cmd_start_next = 1'b1; - - address_next = address_reg + 1; - - state_next = STATE_TABLE_3; - end else if (init_data_reg == 9'b000000011) begin - // write current address - cmd_address_next = cur_address_reg; - cmd_start_next = 1'b1; - - address_next = address_reg + 1; - - state_next = STATE_TABLE_3; - end else if (init_data_reg == 9'b001000001) begin - // send stop - cmd_write_next = 1'b0; - cmd_start_next = 1'b0; - cmd_stop_next = 1'b1; - cmd_valid_next = 1'b1; - - address_next = address_reg + 1; - - state_next = STATE_TABLE_3; - end else if (init_data_reg == 9'b000001001) begin - // data table start - data_ptr_next = address_reg + 1; - address_next = address_reg + 1; - state_next = STATE_TABLE_1; - end else if (init_data_reg == 9'b000001000) begin - // address table start - address_next = address_ptr_reg; - state_next = STATE_TABLE_2; - end else if (init_data_reg == 9'd1) begin - // exit mode - address_next = address_reg + 1; - state_next = STATE_RUN; - end else if (init_data_reg == 9'd0) begin - // stop - cmd_start_next = 1'b0; - cmd_write_next = 1'b0; - cmd_stop_next = 1'b1; - cmd_valid_next = 1'b1; - - state_next = STATE_IDLE; - end else begin - // invalid command, skip - address_next = address_reg + 1; - state_next = STATE_TABLE_3; - end - end - endcase - end -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - - init_data_reg <= 9'd0; - - address_reg <= {AW{1'b0}}; - address_ptr_reg <= {AW{1'b0}}; - data_ptr_reg <= {AW{1'b0}}; - - cur_address_reg <= 7'd0; - - cmd_valid_reg <= 1'b0; - - data_out_valid_reg <= 1'b0; - - start_flag_reg <= 1'b0; - - busy_reg <= 1'b0; - end else begin - state_reg <= state_next; - - // read init_data ROM - init_data_reg <= init_data[address_next]; - - address_reg <= address_next; - address_ptr_reg <= address_ptr_next; - data_ptr_reg <= data_ptr_next; - - cur_address_reg <= cur_address_next; - - cmd_valid_reg <= cmd_valid_next; - - data_out_valid_reg <= data_out_valid_next; - - start_flag_reg <= start & start_flag_next; - - busy_reg <= (state_reg != STATE_IDLE); - end - - cmd_address_reg <= cmd_address_next; - cmd_start_reg <= cmd_start_next; - cmd_write_reg <= cmd_write_next; - cmd_stop_reg <= cmd_stop_next; - - data_out_reg <= data_out_next; -end - -endmodule diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index ada6a5e36..92c8db291 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -95,12 +95,28 @@ def bench(): btnr = Signal(bool(0)) btnc = Signal(bool(0)) sw = Signal(intbv(0)[4:]) + qsfp_tx_clk_1 = Signal(bool(0)) + qsfp_tx_rst_1 = Signal(bool(0)) + qsfp_rx_clk_1 = Signal(bool(0)) + qsfp_rx_rst_1 = Signal(bool(0)) qsfp_rxd_1 = Signal(intbv(0)[64:]) qsfp_rxc_1 = Signal(intbv(0)[8:]) + qsfp_tx_clk_2 = Signal(bool(0)) + qsfp_tx_rst_2 = Signal(bool(0)) + qsfp_rx_clk_2 = Signal(bool(0)) + qsfp_rx_rst_2 = Signal(bool(0)) qsfp_rxd_2 = Signal(intbv(0)[64:]) qsfp_rxc_2 = Signal(intbv(0)[8:]) + qsfp_tx_clk_3 = Signal(bool(0)) + qsfp_tx_rst_3 = Signal(bool(0)) + qsfp_rx_clk_3 = Signal(bool(0)) + qsfp_rx_rst_3 = Signal(bool(0)) qsfp_rxd_3 = Signal(intbv(0)[64:]) qsfp_rxc_3 = Signal(intbv(0)[8:]) + qsfp_tx_clk_4 = Signal(bool(0)) + qsfp_tx_rst_4 = Signal(bool(0)) + qsfp_rx_clk_4 = Signal(bool(0)) + qsfp_rx_rst_4 = Signal(bool(0)) qsfp_rxd_4 = Signal(intbv(0)[64:]) qsfp_rxc_4 = Signal(intbv(0)[8:]) phy_gmii_clk = Signal(bool(0)) @@ -132,28 +148,28 @@ def bench(): # sources and sinks qsfp_1_source = xgmii_ep.XGMIISource() - qsfp_1_source_logic = qsfp_1_source.create_logic(clk, rst, txd=qsfp_rxd_1, txc=qsfp_rxc_1, name='qsfp_1_source') + qsfp_1_source_logic = qsfp_1_source.create_logic(qsfp_rx_clk_1, qsfp_rx_rst_1, txd=qsfp_rxd_1, txc=qsfp_rxc_1, name='qsfp_1_source') qsfp_1_sink = xgmii_ep.XGMIISink() - qsfp_1_sink_logic = qsfp_1_sink.create_logic(clk, rst, rxd=qsfp_txd_1, rxc=qsfp_txc_1, name='qsfp_1_sink') + qsfp_1_sink_logic = qsfp_1_sink.create_logic(qsfp_tx_clk_1, qsfp_tx_rst_1, rxd=qsfp_txd_1, rxc=qsfp_txc_1, name='qsfp_1_sink') qsfp_2_source = xgmii_ep.XGMIISource() - qsfp_2_source_logic = qsfp_2_source.create_logic(clk, rst, txd=qsfp_rxd_2, txc=qsfp_rxc_2, name='qsfp_2_source') + qsfp_2_source_logic = qsfp_2_source.create_logic(qsfp_rx_clk_2, qsfp_rx_rst_2, txd=qsfp_rxd_2, txc=qsfp_rxc_2, name='qsfp_2_source') qsfp_2_sink = xgmii_ep.XGMIISink() - qsfp_2_sink_logic = qsfp_2_sink.create_logic(clk, rst, rxd=qsfp_txd_2, rxc=qsfp_txc_2, name='qsfp_2_sink') + qsfp_2_sink_logic = qsfp_2_sink.create_logic(qsfp_tx_clk_2, qsfp_tx_rst_2, rxd=qsfp_txd_2, rxc=qsfp_txc_2, name='qsfp_2_sink') qsfp_3_source = xgmii_ep.XGMIISource() - qsfp_3_source_logic = qsfp_3_source.create_logic(clk, rst, txd=qsfp_rxd_3, txc=qsfp_rxc_3, name='qsfp_3_source') + qsfp_3_source_logic = qsfp_3_source.create_logic(qsfp_rx_clk_3, qsfp_rx_rst_3, txd=qsfp_rxd_3, txc=qsfp_rxc_3, name='qsfp_3_source') qsfp_3_sink = xgmii_ep.XGMIISink() - qsfp_3_sink_logic = qsfp_3_sink.create_logic(clk, rst, rxd=qsfp_txd_3, rxc=qsfp_txc_3, name='qsfp_3_sink') + qsfp_3_sink_logic = qsfp_3_sink.create_logic(qsfp_tx_clk_3, qsfp_tx_rst_3, rxd=qsfp_txd_3, rxc=qsfp_txc_3, name='qsfp_3_sink') qsfp_4_source = xgmii_ep.XGMIISource() - qsfp_4_source_logic = qsfp_4_source.create_logic(clk, rst, txd=qsfp_rxd_4, txc=qsfp_rxc_4, name='qsfp_4_source') + qsfp_4_source_logic = qsfp_4_source.create_logic(qsfp_rx_clk_4, qsfp_rx_rst_4, txd=qsfp_rxd_4, txc=qsfp_rxc_4, name='qsfp_4_source') qsfp_4_sink = xgmii_ep.XGMIISink() - qsfp_4_sink_logic = qsfp_4_sink.create_logic(clk, rst, rxd=qsfp_txd_4, rxc=qsfp_txc_4, name='qsfp_4_sink') + qsfp_4_sink_logic = qsfp_4_sink.create_logic(qsfp_tx_clk_4, qsfp_tx_rst_4, rxd=qsfp_txd_4, rxc=qsfp_txc_4, name='qsfp_4_sink') gmii_source = gmii_ep.GMIISource() @@ -197,20 +213,36 @@ def bench(): sw=sw, led=led, + qsfp_tx_clk_1=qsfp_tx_clk_1, + qsfp_tx_rst_1=qsfp_tx_rst_1, qsfp_txd_1=qsfp_txd_1, qsfp_txc_1=qsfp_txc_1, + qsfp_rx_clk_1=qsfp_rx_clk_1, + qsfp_rx_rst_1=qsfp_rx_rst_1, qsfp_rxd_1=qsfp_rxd_1, qsfp_rxc_1=qsfp_rxc_1, + qsfp_tx_clk_2=qsfp_tx_clk_2, + qsfp_tx_rst_2=qsfp_tx_rst_2, qsfp_txd_2=qsfp_txd_2, qsfp_txc_2=qsfp_txc_2, + qsfp_rx_clk_2=qsfp_rx_clk_2, + qsfp_rx_rst_2=qsfp_rx_rst_2, qsfp_rxd_2=qsfp_rxd_2, qsfp_rxc_2=qsfp_rxc_2, + qsfp_tx_clk_3=qsfp_tx_clk_3, + qsfp_tx_rst_3=qsfp_tx_rst_3, qsfp_txd_3=qsfp_txd_3, qsfp_txc_3=qsfp_txc_3, + qsfp_rx_clk_3=qsfp_rx_clk_3, + qsfp_rx_rst_3=qsfp_rx_rst_3, qsfp_rxd_3=qsfp_rxd_3, qsfp_rxc_3=qsfp_rxc_3, + qsfp_tx_clk_4=qsfp_tx_clk_4, + qsfp_tx_rst_4=qsfp_tx_rst_4, qsfp_txd_4=qsfp_txd_4, qsfp_txc_4=qsfp_txc_4, + qsfp_rx_clk_4=qsfp_rx_clk_4, + qsfp_rx_rst_4=qsfp_rx_rst_4, qsfp_rxd_4=qsfp_rxd_4, qsfp_rxc_4=qsfp_rxc_4, @@ -235,6 +267,14 @@ def bench(): @always(delay(4)) def clkgen(): clk.next = not clk + qsfp_tx_clk_1.next = not qsfp_tx_clk_1 + qsfp_rx_clk_1.next = not qsfp_rx_clk_1 + qsfp_tx_clk_2.next = not qsfp_tx_clk_2 + qsfp_rx_clk_2.next = not qsfp_rx_clk_2 + qsfp_tx_clk_3.next = not qsfp_tx_clk_3 + qsfp_rx_clk_3.next = not qsfp_rx_clk_3 + qsfp_tx_clk_4.next = not qsfp_tx_clk_4 + qsfp_rx_clk_4.next = not qsfp_rx_clk_4 phy_gmii_clk.next = not phy_gmii_clk clk_enable_rate = Signal(int(0)) @@ -254,9 +294,25 @@ def bench(): yield delay(100) yield clk.posedge rst.next = 1 + qsfp_tx_rst_1.next = 1 + qsfp_rx_rst_1.next = 1 + qsfp_tx_rst_2.next = 1 + qsfp_rx_rst_2.next = 1 + qsfp_tx_rst_3.next = 1 + qsfp_rx_rst_3.next = 1 + qsfp_tx_rst_4.next = 1 + qsfp_rx_rst_4.next = 1 phy_gmii_rst.next = 1 yield clk.posedge rst.next = 0 + qsfp_tx_rst_1.next = 0 + qsfp_rx_rst_1.next = 0 + qsfp_tx_rst_2.next = 0 + qsfp_rx_rst_2.next = 0 + qsfp_tx_rst_3.next = 0 + qsfp_rx_rst_3.next = 0 + qsfp_tx_rst_4.next = 0 + qsfp_rx_rst_4.next = 0 phy_gmii_rst.next = 0 yield clk.posedge yield delay(100) diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.v b/example/VCU108/fpga_10g/tb/test_fpga_core.v index 6093a0a61..04b913f58 100644 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.v +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.v @@ -44,12 +44,28 @@ reg btnd = 0; reg btnr = 0; reg btnc = 0; reg [3:0] sw = 0; +reg qsfp_tx_clk_1 = 0; +reg qsfp_tx_rst_1 = 0; +reg qsfp_rx_clk_1 = 0; +reg qsfp_rx_rst_1 = 0; reg [63:0] qsfp_rxd_1 = 0; reg [7:0] qsfp_rxc_1 = 0; +reg qsfp_tx_clk_2 = 0; +reg qsfp_tx_rst_2 = 0; +reg qsfp_rx_clk_2 = 0; +reg qsfp_rx_rst_2 = 0; reg [63:0] qsfp_rxd_2 = 0; reg [7:0] qsfp_rxc_2 = 0; +reg qsfp_tx_clk_3 = 0; +reg qsfp_tx_rst_3 = 0; +reg qsfp_rx_clk_3 = 0; +reg qsfp_rx_rst_3 = 0; reg [63:0] qsfp_rxd_3 = 0; reg [7:0] qsfp_rxc_3 = 0; +reg qsfp_tx_clk_4 = 0; +reg qsfp_tx_rst_4 = 0; +reg qsfp_rx_clk_4 = 0; +reg qsfp_rx_rst_4 = 0; reg [63:0] qsfp_rxd_4 = 0; reg [7:0] qsfp_rxc_4 = 0; reg phy_gmii_clk = 0; @@ -92,12 +108,28 @@ initial begin btnr, btnc, sw, + qsfp_tx_clk_1, + qsfp_tx_rst_1, + qsfp_rx_clk_1, + qsfp_rx_rst_1, qsfp_rxd_1, qsfp_rxc_1, + qsfp_tx_clk_2, + qsfp_tx_rst_2, + qsfp_rx_clk_2, + qsfp_rx_rst_2, qsfp_rxd_2, qsfp_rxc_2, + qsfp_tx_clk_3, + qsfp_tx_rst_3, + qsfp_rx_clk_3, + qsfp_rx_rst_3, qsfp_rxd_3, qsfp_rxc_3, + qsfp_tx_clk_4, + qsfp_tx_rst_4, + qsfp_rx_clk_4, + qsfp_rx_rst_4, qsfp_rxd_4, qsfp_rxc_4, phy_gmii_clk, @@ -144,20 +176,36 @@ UUT ( .btnc(btnc), .sw(sw), .led(led), + .qsfp_tx_clk_1(qsfp_tx_clk_1), + .qsfp_tx_rst_1(qsfp_tx_rst_1), .qsfp_txd_1(qsfp_txd_1), .qsfp_txc_1(qsfp_txc_1), + .qsfp_rx_clk_1(qsfp_rx_clk_1), + .qsfp_rx_rst_1(qsfp_rx_rst_1), .qsfp_rxd_1(qsfp_rxd_1), .qsfp_rxc_1(qsfp_rxc_1), + .qsfp_tx_clk_2(qsfp_tx_clk_2), + .qsfp_tx_rst_2(qsfp_tx_rst_2), .qsfp_txd_2(qsfp_txd_2), .qsfp_txc_2(qsfp_txc_2), + .qsfp_rx_clk_2(qsfp_rx_clk_2), + .qsfp_rx_rst_2(qsfp_rx_rst_2), .qsfp_rxd_2(qsfp_rxd_2), .qsfp_rxc_2(qsfp_rxc_2), + .qsfp_tx_clk_3(qsfp_tx_clk_3), + .qsfp_tx_rst_3(qsfp_tx_rst_3), .qsfp_txd_3(qsfp_txd_3), .qsfp_txc_3(qsfp_txc_3), + .qsfp_rx_clk_3(qsfp_rx_clk_3), + .qsfp_rx_rst_3(qsfp_rx_rst_3), .qsfp_rxd_3(qsfp_rxd_3), .qsfp_rxc_3(qsfp_rxc_3), + .qsfp_tx_clk_4(qsfp_tx_clk_4), + .qsfp_tx_rst_4(qsfp_tx_rst_4), .qsfp_txd_4(qsfp_txd_4), .qsfp_txc_4(qsfp_txc_4), + .qsfp_rx_clk_4(qsfp_rx_clk_4), + .qsfp_rx_rst_4(qsfp_rx_rst_4), .qsfp_rxd_4(qsfp_rxd_4), .qsfp_rxc_4(qsfp_rxc_4), .phy_gmii_clk(phy_gmii_clk), diff --git a/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci index 1db9474cb..91b324db6 100644 --- a/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci +++ b/example/VCU108/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci @@ -309,16 +309,17 @@ MIXED -2 + E TRUE TRUE IP_Flow - 5 + 6 TRUE . . - 2018.3 + 2019.1 OUT_OF_CONTEXT From 938479c246cce663f07160baf415d4c1d97f2e1c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Jun 2019 00:36:50 -0700 Subject: [PATCH 583/617] MAC RX timing optimizations --- rtl/axis_xgmii_rx_32.v | 7 ++++--- rtl/axis_xgmii_rx_64.v | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index 65fafe901..7980bd5ad 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -286,7 +286,7 @@ always @* begin last_cycle_tkeep_next = last_cycle_tkeep_reg; m_axis_tdata_next = {DATA_WIDTH{1'b0}}; - m_axis_tkeep_next = {KEEP_WIDTH{1'b0}}; + m_axis_tkeep_next = {KEEP_WIDTH{1'b1}}; m_axis_tvalid_next = 1'b0; m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; @@ -334,11 +334,13 @@ always @* begin update_crc = 1'b1; m_axis_tdata_next = xgmii_rxd_d2; - m_axis_tkeep_next = ~xgmii_rxc_d2; + m_axis_tkeep_next = {KEEP_WIDTH{1'b1}}; m_axis_tvalid_next = 1'b1; m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; + last_cycle_tkeep_next = tkeep_mask; + if (control_masked) begin // control or error characters in packet m_axis_tlast_next = 1'b1; @@ -362,7 +364,6 @@ always @* begin state_next = STATE_IDLE; end else begin // need extra cycle - last_cycle_tkeep_next = tkeep_mask; state_next = STATE_LAST; end end else begin diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index f0790ce33..d8021bc33 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -326,7 +326,7 @@ always @* begin last_cycle_tkeep_next = last_cycle_tkeep_reg; m_axis_tdata_next = {DATA_WIDTH{1'b0}}; - m_axis_tkeep_next = {KEEP_WIDTH{1'b0}}; + m_axis_tkeep_next = {KEEP_WIDTH{1'b1}}; m_axis_tvalid_next = 1'b0; m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; @@ -364,11 +364,13 @@ always @* begin update_crc = 1'b1; m_axis_tdata_next = xgmii_rxd_d1; - m_axis_tkeep_next = ~xgmii_rxc_d1; + m_axis_tkeep_next = {KEEP_WIDTH{1'b1}}; m_axis_tvalid_next = 1'b1; m_axis_tlast_next = 1'b0; m_axis_tuser_next = 1'b0; + last_cycle_tkeep_next = {4'b0000, tkeep_mask[7:4]}; + if (control_masked) begin // control or error characters in packet m_axis_tlast_next = 1'b1; @@ -396,7 +398,6 @@ always @* begin state_next = STATE_IDLE; end else begin // need extra cycle - last_cycle_tkeep_next = {4'b0000, tkeep_mask[7:4]}; state_next = STATE_LAST; end end else begin From 4f97303e4443647022c78c2454840e2c28caa221 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Jun 2019 15:38:35 -0700 Subject: [PATCH 584/617] Remove unused code --- rtl/axis_xgmii_rx_32.v | 11 ----------- rtl/axis_xgmii_rx_64.v | 15 --------------- 2 files changed, 26 deletions(-) diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index 7980bd5ad..62a109ec2 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -221,9 +221,7 @@ eth_crc_32 ( ); // detect control characters -reg [3:0] detect_start; reg [3:0] detect_term; -reg [3:0] detect_error; reg [3:0] detect_term_save; @@ -231,46 +229,37 @@ integer i; always @* begin for (i = 0; i < 4; i = i + 1) begin - detect_start[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_START); detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_TERM); - detect_error[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_ERROR); end end // mask errors to within packet -reg [3:0] detect_error_masked; reg [3:0] control_masked; reg [3:0] tkeep_mask; always @* begin casez (detect_term) 4'b0000: begin - detect_error_masked = detect_error; control_masked = xgmii_rxc_d0; tkeep_mask = 4'b1111; end 4'bzzz1: begin - detect_error_masked = 0; control_masked = 0; tkeep_mask = 4'b0000; end 4'bzz10: begin - detect_error_masked = detect_error[0]; control_masked = xgmii_rxc_d0[0]; tkeep_mask = 4'b0001; end 4'bz100: begin - detect_error_masked = detect_error[1:0]; control_masked = xgmii_rxc_d0[1:0]; tkeep_mask = 4'b0011; end 4'b1000: begin - detect_error_masked = detect_error[2:0]; control_masked = xgmii_rxc_d0[2:0]; tkeep_mask = 4'b0111; end default: begin - detect_error_masked = detect_error; control_masked = xgmii_rxc_d0; tkeep_mask = 4'b1111; end diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index d8021bc33..889ccd375 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -241,9 +241,7 @@ eth_crc_64 ( ); // detect control characters -reg [7:0] detect_start; reg [7:0] detect_term; -reg [7:0] detect_error; reg [7:0] detect_term_save = 8'd0; @@ -251,66 +249,53 @@ integer i; always @* begin for (i = 0; i < 8; i = i + 1) begin - detect_start[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_START); detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_TERM); - detect_error[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_ERROR); end end // mask errors to within packet -reg [7:0] detect_error_masked; reg [7:0] control_masked; reg [7:0] tkeep_mask; always @* begin casez (detect_term) 8'b00000000: begin - detect_error_masked = detect_error; control_masked = xgmii_rxc_d0; tkeep_mask = 8'b11111111; end 8'bzzzzzzz1: begin - detect_error_masked = 0; control_masked = 0; tkeep_mask = 8'b00000000; end 8'bzzzzzz10: begin - detect_error_masked = detect_error[0]; control_masked = xgmii_rxc_d0[0]; tkeep_mask = 8'b00000001; end 8'bzzzzz100: begin - detect_error_masked = detect_error[1:0]; control_masked = xgmii_rxc_d0[1:0]; tkeep_mask = 8'b00000011; end 8'bzzzz1000: begin - detect_error_masked = detect_error[2:0]; control_masked = xgmii_rxc_d0[2:0]; tkeep_mask = 8'b00000111; end 8'bzzz10000: begin - detect_error_masked = detect_error[3:0]; control_masked = xgmii_rxc_d0[3:0]; tkeep_mask = 8'b00001111; end 8'bzz100000: begin - detect_error_masked = detect_error[4:0]; control_masked = xgmii_rxc_d0[4:0]; tkeep_mask = 8'b00011111; end 8'bz1000000: begin - detect_error_masked = detect_error[5:0]; control_masked = xgmii_rxc_d0[5:0]; tkeep_mask = 8'b00111111; end 8'b10000000: begin - detect_error_masked = detect_error[6:0]; control_masked = xgmii_rxc_d0[6:0]; tkeep_mask = 8'b01111111; end default: begin - detect_error_masked = detect_error; control_masked = xgmii_rxc_d0; tkeep_mask = 8'b11111111; end From 8bb243cd35729740ea47f865b2f08b1486b8f7aa Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Jun 2019 15:44:41 -0700 Subject: [PATCH 585/617] MAC termination detect timing optimizations --- rtl/axis_xgmii_rx_32.v | 12 +++++------- rtl/axis_xgmii_rx_64.v | 26 +++++++++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index 62a109ec2..b30e19686 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -221,18 +221,12 @@ eth_crc_32 ( ); // detect control characters -reg [3:0] detect_term; +reg [3:0] detect_term = 4'd0; reg [3:0] detect_term_save; integer i; -always @* begin - for (i = 0; i < 4; i = i + 1) begin - detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_TERM); - end -end - // mask errors to within packet reg [3:0] control_masked; reg [3:0] tkeep_mask; @@ -440,6 +434,10 @@ always @(posedge clk) begin last_cycle_tkeep_reg <= last_cycle_tkeep_next; + for (i = 0; i < 4; i = i + 1) begin + detect_term[i] <= xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM); + end + detect_term_save <= detect_term; xgmii_rxd_d0 <= xgmii_rxd; diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index 889ccd375..88d3db227 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -241,18 +241,12 @@ eth_crc_64 ( ); // detect control characters -reg [7:0] detect_term; +reg [7:0] detect_term = 8'd0; reg [7:0] detect_term_save = 8'd0; integer i; -always @* begin - for (i = 0; i < 8; i = i + 1) begin - detect_term[i] = xgmii_rxc_d0[i] && (xgmii_rxd_d0[i*8 +: 8] == XGMII_TERM); - end -end - // mask errors to within packet reg [7:0] control_masked; reg [7:0] tkeep_mask; @@ -524,15 +518,33 @@ always @(posedge clk) begin if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin xgmii_rxd_d0 <= xgmii_rxd; xgmii_rxd_crc <= xgmii_rxd; + + for (i = 0; i < 8; i = i + 1) begin + detect_term[i] <= xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM); + end end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; xgmii_rxd_crc <= {xgmii_rxd[31:0], swap_rxd}; + + for (i = 0; i < 4; i = i + 1) begin + detect_term[i] <= swap_rxc[i] && (swap_rxd[i*8 +: 8] == XGMII_TERM); + detect_term[i+4] <= xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM); + end end else if (lanes_swapped) begin xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; xgmii_rxd_crc <= {xgmii_rxd[31:0], swap_rxd}; + + for (i = 0; i < 4; i = i + 1) begin + detect_term[i] <= swap_rxc[i] && (swap_rxd[i*8 +: 8] == XGMII_TERM); + detect_term[i+4] <= xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM); + end end else begin xgmii_rxd_d0 <= xgmii_rxd; xgmii_rxd_crc <= xgmii_rxd; + + for (i = 0; i < 8; i = i + 1) begin + detect_term[i] <= xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM); + end end if (state_next == STATE_LAST) begin From 320a45c4ab65d92632fb467b69cfb02eb9bd85b0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Jun 2019 17:33:14 -0700 Subject: [PATCH 586/617] Remove unused state bit --- rtl/axis_xgmii_rx_32.v | 12 ++++++------ rtl/axis_xgmii_rx_64.v | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index b30e19686..2b26140c3 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -93,13 +93,13 @@ localparam [7:0] XGMII_TERM = 8'hfd, XGMII_ERROR = 8'hfe; -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_PREAMBLE = 3'd1, - STATE_PAYLOAD = 3'd2, - STATE_LAST = 3'd3; +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PREAMBLE = 2'd1, + STATE_PAYLOAD = 2'd2, + STATE_LAST = 2'd3; -reg [2:0] state_reg = STATE_IDLE, state_next; +reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg reset_crc; diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index 88d3db227..a7eeccc2c 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -95,12 +95,12 @@ localparam [7:0] XGMII_TERM = 8'hfd, XGMII_ERROR = 8'hfe; -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_PAYLOAD = 3'd1, - STATE_LAST = 3'd2; +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PAYLOAD = 2'd1, + STATE_LAST = 2'd2; -reg [2:0] state_reg = STATE_IDLE, state_next; +reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg reset_crc; From 3b959b2765200855cbee19274e4f536c15766e47 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Jun 2019 17:39:28 -0700 Subject: [PATCH 587/617] CRC handling logic optimizations --- rtl/axis_xgmii_rx_32.v | 25 ++++++------------------- rtl/axis_xgmii_rx_64.v | 34 ++++++++++++++++------------------ 2 files changed, 22 insertions(+), 37 deletions(-) diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index 2b26140c3..a295b020c 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -103,7 +103,6 @@ reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg reset_crc; -reg update_crc; reg [3:0] last_cycle_tkeep_reg = 4'd0, last_cycle_tkeep_next; @@ -264,7 +263,6 @@ always @* begin state_next = STATE_IDLE; reset_crc = 1'b0; - update_crc = 1'b0; last_cycle_tkeep_next = last_cycle_tkeep_reg; @@ -298,7 +296,6 @@ always @* begin state_next = STATE_IDLE; end else begin reset_crc = 1'b0; - update_crc = 1'b1; state_next = STATE_PREAMBLE; end end else begin @@ -307,15 +304,12 @@ always @* begin end STATE_PREAMBLE: begin // drop preamble - update_crc = 1'b1; ptp_ts_next = ptp_ts; start_packet_next = 1'b1; state_next = STATE_PAYLOAD; end STATE_PAYLOAD: begin // read payload - update_crc = 1'b1; - m_axis_tdata_next = xgmii_rxd_d2; m_axis_tkeep_next = {KEEP_WIDTH{1'b1}}; m_axis_tvalid_next = 1'b1; @@ -389,10 +383,6 @@ always @(posedge clk) begin error_bad_fcs_reg <= 1'b0; crc_state <= 32'hFFFFFFFF; - crc_valid0_save <= 1'b0; - crc_valid1_save <= 1'b0; - crc_valid2_save <= 1'b0; - crc_valid3_save <= 1'b0; xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}}; xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}}; @@ -412,16 +402,8 @@ always @(posedge clk) begin // datapath if (reset_crc) begin crc_state <= 32'hFFFFFFFF; - crc_valid0_save <= 1'b0; - crc_valid1_save <= 1'b0; - crc_valid2_save <= 1'b0; - crc_valid3_save <= 1'b0; - end else if (update_crc) begin + end else begin crc_state <= crc_next3; - crc_valid0_save <= crc_valid0; - crc_valid1_save <= crc_valid1; - crc_valid2_save <= crc_valid2; - crc_valid3_save <= crc_valid3; end end @@ -440,6 +422,11 @@ always @(posedge clk) begin detect_term_save <= detect_term; + crc_valid0_save <= crc_valid0; + crc_valid1_save <= crc_valid1; + crc_valid2_save <= crc_valid2; + crc_valid3_save <= crc_valid3; + xgmii_rxd_d0 <= xgmii_rxd; xgmii_rxd_d1 <= xgmii_rxd_d0; xgmii_rxd_d2 <= xgmii_rxd_d1; diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index a7eeccc2c..8ef42e16b 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -104,7 +104,7 @@ reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg reset_crc; -reg update_crc; +reg update_crc_last; reg [7:0] last_cycle_tkeep_reg = 8'd0, last_cycle_tkeep_next; @@ -158,8 +158,6 @@ assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; -wire last_cycle = state_reg == STATE_LAST; - lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), @@ -171,7 +169,7 @@ lfsr #( ) eth_crc_8 ( .data_in(xgmii_rxd_crc[7:0]), - .state_in(last_cycle ? crc_state3 : crc_state), + .state_in(crc_state3), .data_out(), .state_out(crc_next0) ); @@ -187,7 +185,7 @@ lfsr #( ) eth_crc_16 ( .data_in(xgmii_rxd_crc[15:0]), - .state_in(last_cycle ? crc_state3 : crc_state), + .state_in(crc_state3), .data_out(), .state_out(crc_next1) ); @@ -203,7 +201,7 @@ lfsr #( ) eth_crc_24 ( .data_in(xgmii_rxd_crc[23:0]), - .state_in(last_cycle ? crc_state3 : crc_state), + .state_in(crc_state3), .data_out(), .state_out(crc_next2) ); @@ -219,7 +217,7 @@ lfsr #( ) eth_crc_32 ( .data_in(xgmii_rxd_crc[31:0]), - .state_in(last_cycle ? crc_state3 : crc_state), + .state_in(crc_state3), .data_out(), .state_out(crc_next3) ); @@ -234,7 +232,7 @@ lfsr #( .STYLE("AUTO") ) eth_crc_64 ( - .data_in(xgmii_rxd_d0[63:0]), + .data_in(xgmii_rxd_crc[63:0]), .state_in(crc_state), .data_out(), .state_out(crc_next7) @@ -300,7 +298,7 @@ always @* begin state_next = STATE_IDLE; reset_crc = 1'b0; - update_crc = 1'b0; + update_crc_last = 1'b0; last_cycle_tkeep_next = last_cycle_tkeep_reg; @@ -331,7 +329,6 @@ always @* begin state_next = STATE_IDLE; end else begin reset_crc = 1'b0; - update_crc = 1'b1; state_next = STATE_PAYLOAD; end end else begin @@ -340,8 +337,6 @@ always @* begin end STATE_PAYLOAD: begin // read payload - update_crc = 1'b1; - m_axis_tdata_next = xgmii_rxd_d1; m_axis_tkeep_next = {KEEP_WIDTH{1'b1}}; m_axis_tvalid_next = 1'b1; @@ -377,6 +372,7 @@ always @* begin state_next = STATE_IDLE; end else begin // need extra cycle + update_crc_last = 1'b1; state_next = STATE_LAST; end end else begin @@ -416,7 +412,6 @@ always @* begin state_next = STATE_IDLE; end else begin reset_crc = 1'b0; - update_crc = 1'b1; state_next = STATE_PAYLOAD; end end else begin @@ -438,7 +433,6 @@ always @(posedge clk) begin crc_state <= 32'hFFFFFFFF; crc_state3 <= 32'hFFFFFFFF; - crc_valid7_save <= 1'b0; xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}}; xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}}; @@ -472,12 +466,14 @@ always @(posedge clk) begin // datapath if (reset_crc) begin crc_state <= 32'hFFFFFFFF; - crc_state3 <= 32'hFFFFFFFF; - crc_valid7_save <= 1'b0; - end else if (update_crc) begin + end else begin crc_state <= crc_next7; + end + + if (update_crc_last) begin crc_state3 <= crc_next3; - crc_valid7_save <= crc_valid7; + end else begin + crc_state3 <= crc_next7; end end @@ -547,6 +543,8 @@ always @(posedge clk) begin end end + crc_valid7_save <= crc_valid7; + if (state_next == STATE_LAST) begin xgmii_rxd_crc[31:0] <= xgmii_rxd_crc[63:32]; end From 55bf44117b3f8f5bd7a578f22fe32cb182325b2a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Jun 2019 19:57:52 -0700 Subject: [PATCH 588/617] shift_axis_extra_cycle timing optimization --- rtl/eth_axis_rx_64.v | 8 +++++--- rtl/eth_axis_tx_64.v | 8 +++++--- rtl/ip_eth_rx_64.v | 8 +++++--- rtl/ip_eth_tx_64.v | 8 +++++--- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v index e060e9bde..2f815cccf 100644 --- a/rtl/eth_axis_rx_64.v +++ b/rtl/eth_axis_rx_64.v @@ -118,7 +118,7 @@ reg shift_axis_tvalid; reg shift_axis_tlast; reg shift_axis_tuser; reg shift_axis_s_tready; -reg shift_axis_extra_cycle; +reg shift_axis_extra_cycle_reg = 1'b0; // internal datapath reg [63:0] m_eth_payload_axis_tdata_int; @@ -142,9 +142,8 @@ assign error_header_early_termination = error_header_early_termination_reg; always @* begin shift_axis_tdata[15:0] = save_axis_tdata_reg[63:48]; shift_axis_tkeep[1:0] = save_axis_tkeep_reg[7:6]; - shift_axis_extra_cycle = save_axis_tlast_reg && (save_axis_tkeep_reg[7:6] != 0); - if (shift_axis_extra_cycle) begin + if (shift_axis_extra_cycle_reg) begin shift_axis_tdata[63:16] = 48'd0; shift_axis_tkeep[7:2] = 6'd0; shift_axis_tvalid = 1'b1; @@ -276,6 +275,7 @@ always @(posedge clk) begin s_axis_tready_reg <= 1'b0; m_eth_hdr_valid_reg <= 1'b0; save_axis_tlast_reg <= 1'b0; + shift_axis_extra_cycle_reg <= 1'b0; busy_reg <= 1'b0; error_header_early_termination_reg <= 1'b0; end else begin @@ -293,8 +293,10 @@ always @(posedge clk) begin if (flush_save) begin save_axis_tlast_reg <= 1'b0; + shift_axis_extra_cycle_reg <= 1'b0; end else if (transfer_in_save) begin save_axis_tlast_reg <= s_axis_tlast; + shift_axis_extra_cycle_reg <= s_axis_tlast && (s_axis_tkeep[7:6] != 0); end end diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v index cae7dd473..e414d2cd2 100644 --- a/rtl/eth_axis_tx_64.v +++ b/rtl/eth_axis_tx_64.v @@ -116,7 +116,7 @@ reg shift_eth_payload_axis_tvalid; reg shift_eth_payload_axis_tlast; reg shift_eth_payload_axis_tuser; reg shift_eth_payload_s_tready; -reg shift_eth_payload_extra_cycle; +reg shift_eth_payload_extra_cycle_reg = 1'b0; // internal datapath reg [63:0] m_axis_tdata_int; @@ -135,9 +135,8 @@ assign busy = busy_reg; always @* begin shift_eth_payload_axis_tdata[47:0] = save_eth_payload_axis_tdata_reg[63:16]; shift_eth_payload_axis_tkeep[5:0] = save_eth_payload_axis_tkeep_reg[7:2]; - shift_eth_payload_extra_cycle = save_eth_payload_axis_tlast_reg && (save_eth_payload_axis_tkeep_reg[7:2] != 0); - if (shift_eth_payload_extra_cycle) begin + if (shift_eth_payload_extra_cycle_reg) begin shift_eth_payload_axis_tdata[63:48] = 16'd0; shift_eth_payload_axis_tkeep[7:6] = 2'd0; shift_eth_payload_axis_tvalid = 1'b1; @@ -296,6 +295,7 @@ always @(posedge clk) begin s_eth_hdr_ready_reg <= 1'b0; s_eth_payload_axis_tready_reg <= 1'b0; save_eth_payload_axis_tlast_reg <= 1'b0; + shift_eth_payload_extra_cycle_reg <= 1'b0; busy_reg <= 1'b0; end else begin state_reg <= state_next; @@ -317,8 +317,10 @@ always @(posedge clk) begin if (flush_save) begin save_eth_payload_axis_tlast_reg <= 1'b0; + shift_eth_payload_extra_cycle_reg <= 1'b0; end else if (transfer_in_save) begin save_eth_payload_axis_tlast_reg <= s_eth_payload_axis_tlast; + shift_eth_payload_extra_cycle_reg <= s_eth_payload_axis_tlast && (s_eth_payload_axis_tkeep[7:2] != 0); end end diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index e798a0d58..781c21462 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -184,7 +184,7 @@ reg shift_eth_payload_axis_tvalid; reg shift_eth_payload_axis_tlast; reg shift_eth_payload_axis_tuser; reg shift_eth_payload_s_tready; -reg shift_eth_payload_extra_cycle; +reg shift_eth_payload_extra_cycle_reg = 1'b0; // internal datapath reg [63:0] m_ip_payload_axis_tdata_int; @@ -255,9 +255,8 @@ endfunction always @* begin shift_eth_payload_axis_tdata[31:0] = save_eth_payload_axis_tdata_reg[63:32]; shift_eth_payload_axis_tkeep[3:0] = save_eth_payload_axis_tkeep_reg[7:4]; - shift_eth_payload_extra_cycle = save_eth_payload_axis_tlast_reg && (save_eth_payload_axis_tkeep_reg[7:4] != 0); - if (shift_eth_payload_extra_cycle) begin + if (shift_eth_payload_extra_cycle_reg) begin shift_eth_payload_axis_tdata[63:32] = 32'd0; shift_eth_payload_axis_tkeep[7:4] = 4'd0; shift_eth_payload_axis_tvalid = 1'b1; @@ -512,6 +511,7 @@ always @(posedge clk) begin s_eth_payload_axis_tready_reg <= 1'b0; m_ip_hdr_valid_reg <= 1'b0; save_eth_payload_axis_tlast_reg <= 1'b0; + shift_eth_payload_extra_cycle_reg <= 1'b0; busy_reg <= 1'b0; error_header_early_termination_reg <= 1'b0; error_payload_early_termination_reg <= 1'b0; @@ -540,8 +540,10 @@ always @(posedge clk) begin // datapath if (flush_save) begin save_eth_payload_axis_tlast_reg <= 1'b0; + shift_eth_payload_extra_cycle_reg <= 1'b0; end else if (transfer_in_save) begin save_eth_payload_axis_tlast_reg <= s_eth_payload_axis_tlast; + shift_eth_payload_extra_cycle_reg <= s_eth_payload_axis_tlast && (s_eth_payload_axis_tkeep[7:4] != 0); end end diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 6c75e37d6..74276c023 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -170,7 +170,7 @@ reg shift_ip_payload_axis_tvalid; reg shift_ip_payload_axis_tlast; reg shift_ip_payload_axis_tuser; reg shift_ip_payload_s_tready; -reg shift_ip_payload_extra_cycle; +reg shift_ip_payload_extra_cycle_reg = 1'b0; // internal datapath reg [63:0] m_eth_payload_axis_tdata_int; @@ -225,9 +225,8 @@ endfunction always @* begin shift_ip_payload_axis_tdata[31:0] = save_ip_payload_axis_tdata_reg[63:32]; shift_ip_payload_axis_tkeep[3:0] = save_ip_payload_axis_tkeep_reg[7:4]; - shift_ip_payload_extra_cycle = save_ip_payload_axis_tlast_reg && (save_ip_payload_axis_tkeep_reg[7:4] != 0); - if (shift_ip_payload_extra_cycle) begin + if (shift_ip_payload_extra_cycle_reg) begin shift_ip_payload_axis_tdata[63:32] = 32'd0; shift_ip_payload_axis_tkeep[7:4] = 4'd0; shift_ip_payload_axis_tvalid = 1'b1; @@ -495,6 +494,7 @@ always @(posedge clk) begin s_ip_payload_axis_tready_reg <= 1'b0; m_eth_hdr_valid_reg <= 1'b0; save_ip_payload_axis_tlast_reg <= 1'b0; + shift_ip_payload_extra_cycle_reg <= 1'b0; busy_reg <= 1'b0; error_payload_early_termination_reg <= 1'b0; end else begin @@ -515,8 +515,10 @@ always @(posedge clk) begin if (flush_save) begin save_ip_payload_axis_tlast_reg <= 1'b0; + shift_ip_payload_extra_cycle_reg <= 1'b0; end else if (transfer_in_save) begin save_ip_payload_axis_tlast_reg <= s_ip_payload_axis_tlast; + shift_ip_payload_extra_cycle_reg <= s_ip_payload_axis_tlast && (s_ip_payload_axis_tkeep[7:4] != 0); end end From b17966f73deedfad2f4562acfb96e6f42f52a40c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Jun 2019 20:01:08 -0700 Subject: [PATCH 589/617] store_last_word timing optimization --- rtl/ip_eth_rx_64.v | 3 ++- rtl/ip_eth_tx_64.v | 3 ++- rtl/udp_ip_rx_64.v | 3 ++- rtl/udp_ip_tx_64.v | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 781c21462..11bc89c21 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -396,6 +396,8 @@ always @* begin m_ip_payload_axis_tlast_int = shift_eth_payload_axis_tlast; m_ip_payload_axis_tuser_int = shift_eth_payload_axis_tuser; + store_last_word = 1'b1; + if (m_ip_payload_axis_tready_int_reg && shift_eth_payload_axis_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_axis_tkeep); @@ -410,7 +412,6 @@ always @* begin s_eth_hdr_ready_next = !m_ip_hdr_valid_reg && !check_hdr_reg; state_next = STATE_IDLE; end else begin - store_last_word = 1'b1; m_ip_payload_axis_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; end diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 74276c023..40c3c670a 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -407,6 +407,8 @@ always @* begin m_eth_payload_axis_tlast_int = shift_ip_payload_axis_tlast; m_eth_payload_axis_tuser_int = shift_ip_payload_axis_tuser; + store_last_word = 1'b1; + if (m_eth_payload_axis_tready_int_reg && shift_ip_payload_axis_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_axis_tkeep); @@ -421,7 +423,6 @@ always @* begin s_ip_hdr_ready_next = !m_eth_hdr_valid_next; state_next = STATE_IDLE; end else begin - store_last_word = 1'b1; m_eth_payload_axis_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index b51b64cf9..a9279ce2f 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -334,6 +334,8 @@ always @* begin m_udp_payload_axis_tlast_int = s_ip_payload_axis_tlast; m_udp_payload_axis_tuser_int = s_ip_payload_axis_tuser; + store_last_word = 1'b1; + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(s_ip_payload_axis_tkeep); @@ -346,7 +348,6 @@ always @* begin s_ip_hdr_ready_next = !m_udp_hdr_valid_next; state_next = STATE_IDLE; end else begin - store_last_word = 1'b1; m_udp_payload_axis_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; end diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index 967f0a506..bd7f56384 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -334,6 +334,8 @@ always @* begin m_ip_payload_axis_tlast_int = s_udp_payload_axis_tlast; m_ip_payload_axis_tuser_int = s_udp_payload_axis_tuser; + store_last_word = 1'b1; + if (m_ip_payload_axis_tready_int_reg && s_udp_payload_axis_tvalid) begin // word transfer through frame_ptr_next = frame_ptr_reg+keep2count(s_udp_payload_axis_tkeep); @@ -346,7 +348,6 @@ always @* begin s_udp_hdr_ready_next = !m_ip_hdr_valid_next; state_next = STATE_IDLE; end else begin - store_last_word = 1'b1; m_ip_payload_axis_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; end From 7ec836baf6235f2b48a317d26f485fbd23ae0133 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Jun 2019 22:01:11 -0700 Subject: [PATCH 590/617] IP header checksum optimizations --- rtl/ip_eth_rx_64.v | 30 +++++++++++++----------------- rtl/ip_eth_tx_64.v | 8 ++++---- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 11bc89c21..30760dd50 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -139,8 +139,10 @@ reg transfer_in_save; reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; -reg [31:0] hdr_sum_temp; -reg [31:0] hdr_sum_reg = 32'd0, hdr_sum_next; +reg [16:0] hdr_sum_high_reg = 17'd0; +reg [16:0] hdr_sum_low_reg = 17'd0; +reg [19:0] hdr_sum_temp; +reg [19:0] hdr_sum_reg = 20'd0, hdr_sum_next; reg check_hdr_reg = 1'b0, check_hdr_next; reg [63:0] last_word_data_reg = 64'd0; @@ -338,24 +340,14 @@ always @* begin case (frame_ptr_reg) 8'h00: begin store_hdr_word_0 = 1'b1; - hdr_sum_next = s_eth_payload_axis_tdata[15:0] + - s_eth_payload_axis_tdata[31:16] + - s_eth_payload_axis_tdata[47:32] + - s_eth_payload_axis_tdata[63:48]; end 8'h08: begin store_hdr_word_1 = 1'b1; - hdr_sum_next = hdr_sum_reg + - s_eth_payload_axis_tdata[15:0] + - s_eth_payload_axis_tdata[31:16] + - s_eth_payload_axis_tdata[47:32] + - s_eth_payload_axis_tdata[63:48]; + hdr_sum_next = hdr_sum_high_reg + hdr_sum_low_reg; end 8'h10: begin store_hdr_word_2 = 1'b1; - hdr_sum_next = hdr_sum_reg + - s_eth_payload_axis_tdata[15:0] + - s_eth_payload_axis_tdata[31:16]; + hdr_sum_next = hdr_sum_reg + hdr_sum_high_reg + hdr_sum_low_reg; frame_ptr_next = frame_ptr_reg + 16'd4; // check header checksum on next cycle for improved timing @@ -435,10 +427,9 @@ always @* begin if (check_hdr_reg) begin check_hdr_next = 1'b0; - hdr_sum_temp = hdr_sum_reg[15:0] + hdr_sum_reg[31:16]; - hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[16]; + hdr_sum_temp = hdr_sum_reg[15:0] + hdr_sum_reg[19:16] + hdr_sum_low_reg; - if (hdr_sum_temp != 16'hffff) begin + if (hdr_sum_temp != 19'h0ffff && hdr_sum_temp != 19'h1fffe) begin // bad checksum error_invalid_checksum_next = 1'b1; m_ip_payload_axis_tvalid_int = 1'b0; @@ -548,6 +539,11 @@ always @(posedge clk) begin end end + if (s_eth_payload_axis_tvalid) begin + hdr_sum_low_reg <= s_eth_payload_axis_tdata[15:0] + s_eth_payload_axis_tdata[31:16]; + hdr_sum_high_reg <= s_eth_payload_axis_tdata[47:32] + s_eth_payload_axis_tdata[63:48]; + end + // datapath if (store_eth_hdr) begin m_eth_dest_mac_reg <= s_eth_dest_mac; diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 40c3c670a..7adc52828 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -131,8 +131,8 @@ reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; reg flush_save; reg transfer_in_save; -reg [31:0] hdr_sum_temp; -reg [31:0] hdr_sum_reg = 32'd0, hdr_sum_next; +reg [19:0] hdr_sum_temp; +reg [19:0] hdr_sum_reg = 20'd0, hdr_sum_next; reg [63:0] last_word_data_reg = 64'd0; reg [7:0] last_word_keep_reg = 8'd0; @@ -258,7 +258,7 @@ always @* begin frame_ptr_next = frame_ptr_reg; - hdr_sum_temp = 16'd0; + hdr_sum_temp = 20'd0; hdr_sum_next = hdr_sum_reg; m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; @@ -328,7 +328,7 @@ always @* begin m_eth_payload_axis_tkeep_int = 8'hff; end 8'h08: begin - hdr_sum_temp = hdr_sum_reg[15:0] + hdr_sum_reg[31:16]; + hdr_sum_temp = hdr_sum_reg[15:0] + hdr_sum_reg[19:16]; hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[16]; m_eth_payload_axis_tdata_int[ 7: 0] = ip_ttl_reg; m_eth_payload_axis_tdata_int[15: 8] = ip_protocol_reg; From 1d3554c37e0397ea6fabe201c0529194aaa76215 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 16 Jun 2019 23:53:26 -0700 Subject: [PATCH 591/617] Rework pointer handling to improve timing --- rtl/ip_eth_rx.v | 72 +++++++++++++++++++++++---------------------- rtl/ip_eth_rx_64.v | 41 +++++++++++++------------- rtl/ip_eth_tx.v | 73 ++++++++++++++++++++++++---------------------- rtl/ip_eth_tx_64.v | 45 ++++++++++++++-------------- rtl/udp_ip_rx.v | 40 +++++++++++++------------ rtl/udp_ip_rx_64.v | 32 +++++++++----------- rtl/udp_ip_tx.v | 44 +++++++++++++++------------- rtl/udp_ip_tx_64.v | 46 ++++++++++++----------------- 8 files changed, 196 insertions(+), 197 deletions(-) diff --git a/rtl/ip_eth_rx.v b/rtl/ip_eth_rx.v index 93fce01a2..5d0579148 100644 --- a/rtl/ip_eth_rx.v +++ b/rtl/ip_eth_rx.v @@ -149,7 +149,8 @@ reg store_ip_dest_ip_2; reg store_ip_dest_ip_3; reg store_last_word; -reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; +reg [5:0] hdr_ptr_reg = 6'd0, hdr_ptr_next; +reg [15:0] word_count_reg = 16'd0, word_count_next; reg [15:0] hdr_sum_reg = 16'd0, hdr_sum_next; @@ -256,7 +257,8 @@ always @* begin store_last_word = 1'b0; - frame_ptr_next = frame_ptr_reg; + hdr_ptr_next = hdr_ptr_reg; + word_count_next = word_count_reg; hdr_sum_next = hdr_sum_reg; @@ -275,7 +277,7 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for header - frame_ptr_next = 16'd0; + hdr_ptr_next = 16'd0; hdr_sum_next = 16'd0; s_eth_hdr_ready_next = !m_ip_hdr_valid_next; @@ -291,39 +293,40 @@ always @* begin STATE_READ_HEADER: begin // read header s_eth_payload_axis_tready_next = 1'b1; + word_count_next = m_ip_length_reg - 5*4; if (s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg + 16'd1; + hdr_ptr_next = hdr_ptr_reg + 6'd1; state_next = STATE_READ_HEADER; - if (frame_ptr_reg[0]) begin + if (hdr_ptr_reg[0]) begin hdr_sum_next = add1c16b(hdr_sum_reg, {8'd0, s_eth_payload_axis_tdata}); end else begin hdr_sum_next = add1c16b(hdr_sum_reg, {s_eth_payload_axis_tdata, 8'd0}); end - case (frame_ptr_reg) - 8'h00: store_ip_version_ihl = 1'b1; - 8'h01: store_ip_dscp_ecn = 1'b1; - 8'h02: store_ip_length_1 = 1'b1; - 8'h03: store_ip_length_0 = 1'b1; - 8'h04: store_ip_identification_1 = 1'b1; - 8'h05: store_ip_identification_0 = 1'b1; - 8'h06: store_ip_flags_fragment_offset_1 = 1'b1; - 8'h07: store_ip_flags_fragment_offset_0 = 1'b1; - 8'h08: store_ip_ttl = 1'b1; - 8'h09: store_ip_protocol = 1'b1; - 8'h0A: store_ip_header_checksum_1 = 1'b1; - 8'h0B: store_ip_header_checksum_0 = 1'b1; - 8'h0C: store_ip_source_ip_3 = 1'b1; - 8'h0D: store_ip_source_ip_2 = 1'b1; - 8'h0E: store_ip_source_ip_1 = 1'b1; - 8'h0F: store_ip_source_ip_0 = 1'b1; - 8'h10: store_ip_dest_ip_3 = 1'b1; - 8'h11: store_ip_dest_ip_2 = 1'b1; - 8'h12: store_ip_dest_ip_1 = 1'b1; - 8'h13: begin + case (hdr_ptr_reg) + 6'h00: store_ip_version_ihl = 1'b1; + 6'h01: store_ip_dscp_ecn = 1'b1; + 6'h02: store_ip_length_1 = 1'b1; + 6'h03: store_ip_length_0 = 1'b1; + 6'h04: store_ip_identification_1 = 1'b1; + 6'h05: store_ip_identification_0 = 1'b1; + 6'h06: store_ip_flags_fragment_offset_1 = 1'b1; + 6'h07: store_ip_flags_fragment_offset_0 = 1'b1; + 6'h08: store_ip_ttl = 1'b1; + 6'h09: store_ip_protocol = 1'b1; + 6'h0A: store_ip_header_checksum_1 = 1'b1; + 6'h0B: store_ip_header_checksum_0 = 1'b1; + 6'h0C: store_ip_source_ip_3 = 1'b1; + 6'h0D: store_ip_source_ip_2 = 1'b1; + 6'h0E: store_ip_source_ip_1 = 1'b1; + 6'h0F: store_ip_source_ip_0 = 1'b1; + 6'h10: store_ip_dest_ip_3 = 1'b1; + 6'h11: store_ip_dest_ip_2 = 1'b1; + 6'h12: store_ip_dest_ip_1 = 1'b1; + 6'h13: begin store_ip_dest_ip_0 = 1'b1; if (m_ip_version_reg != 4'd4 || m_ip_ihl_reg != 4'd5) begin error_invalid_header_next = 1'b1; @@ -362,9 +365,9 @@ always @* begin if (s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg + 16'd1; + word_count_next = word_count_reg - 16'd1; if (s_eth_payload_axis_tlast) begin - if (frame_ptr_next != m_ip_length_reg) begin + if (word_count_reg > 16'd1) begin // end of frame, but length does not match m_ip_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; @@ -373,7 +376,7 @@ always @* begin s_eth_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin - if (frame_ptr_next == m_ip_length_reg) begin + if (word_count_reg == 16'd1) begin store_last_word = 1'b1; m_ip_payload_axis_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; @@ -428,8 +431,6 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 16'd0; - hdr_sum_reg <= 16'd0; s_eth_hdr_ready_reg <= 1'b0; s_eth_payload_axis_tready_reg <= 1'b0; m_ip_hdr_valid_reg <= 1'b0; @@ -441,10 +442,6 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; - - hdr_sum_reg <= hdr_sum_next; - s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; @@ -458,6 +455,11 @@ always @(posedge clk) begin busy_reg <= state_next != STATE_IDLE; end + hdr_ptr_reg <= hdr_ptr_next; + word_count_reg <= word_count_next; + + hdr_sum_reg <= hdr_sum_next; + // datapath if (store_eth_hdr) begin m_eth_dest_mac_reg <= s_eth_dest_mac; diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 30760dd50..188675e2a 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -137,7 +137,8 @@ reg store_last_word; reg flush_save; reg transfer_in_save; -reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; +reg [5:0] hdr_ptr_reg = 6'd0, hdr_ptr_next; +reg [15:0] word_count_reg = 16'd0, word_count_next; reg [16:0] hdr_sum_high_reg = 17'd0; reg [16:0] hdr_sum_low_reg = 17'd0; @@ -291,7 +292,8 @@ always @* begin store_last_word = 1'b0; - frame_ptr_next = frame_ptr_reg; + hdr_ptr_next = hdr_ptr_reg; + word_count_next = word_count_reg; hdr_sum_temp = 32'd0; hdr_sum_next = hdr_sum_reg; @@ -313,7 +315,7 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for header - frame_ptr_next = 16'd0; + hdr_ptr_next = 6'd0; hdr_sum_next = 32'd0; flush_save = 1'b1; s_eth_hdr_ready_next = !m_ip_hdr_valid_next; @@ -330,25 +332,25 @@ always @* begin STATE_READ_HEADER: begin // read header s_eth_payload_axis_tready_next = shift_eth_payload_s_tready; + word_count_next = m_ip_length_reg - 5*4; if (s_eth_payload_axis_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg + 16'd8; + hdr_ptr_next = hdr_ptr_reg + 6'd8; transfer_in_save = 1'b1; state_next = STATE_READ_HEADER; - case (frame_ptr_reg) - 8'h00: begin + case (hdr_ptr_reg) + 6'h00: begin store_hdr_word_0 = 1'b1; end - 8'h08: begin + 6'h08: begin store_hdr_word_1 = 1'b1; hdr_sum_next = hdr_sum_high_reg + hdr_sum_low_reg; end - 8'h10: begin + 6'h10: begin store_hdr_word_2 = 1'b1; hdr_sum_next = hdr_sum_reg + hdr_sum_high_reg + hdr_sum_low_reg; - frame_ptr_next = frame_ptr_reg + 16'd4; // check header checksum on next cycle for improved timing check_hdr_next = 1'b1; @@ -392,12 +394,11 @@ always @* begin if (m_ip_payload_axis_tready_int_reg && shift_eth_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+keep2count(shift_eth_payload_axis_tkeep); + word_count_next = word_count_reg - 16'd8; transfer_in_save = 1'b1; - if (frame_ptr_next >= m_ip_length_reg) begin + if (word_count_reg <= keep2count(shift_eth_payload_axis_tkeep)) begin // have entire payload - frame_ptr_next = m_ip_length_reg; - m_ip_payload_axis_tkeep_int = shift_eth_payload_axis_tkeep & count2keep(m_ip_length_reg - frame_ptr_reg); + m_ip_payload_axis_tkeep_int = shift_eth_payload_axis_tkeep & count2keep(word_count_reg); if (shift_eth_payload_axis_tlast) begin s_eth_payload_axis_tready_next = 1'b0; flush_save = 1'b1; @@ -496,9 +497,6 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 16'd0; - hdr_sum_reg <= 16'd0; - check_hdr_reg <= 1'b0; s_eth_hdr_ready_reg <= 1'b0; s_eth_payload_axis_tready_reg <= 1'b0; m_ip_hdr_valid_reg <= 1'b0; @@ -512,11 +510,6 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; - - hdr_sum_reg <= hdr_sum_next; - check_hdr_reg <= check_hdr_next; - s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; @@ -539,6 +532,12 @@ always @(posedge clk) begin end end + hdr_ptr_reg <= hdr_ptr_next; + word_count_reg <= word_count_next; + + hdr_sum_reg <= hdr_sum_next; + check_hdr_reg <= check_hdr_next; + if (s_eth_payload_axis_tvalid) begin hdr_sum_low_reg <= s_eth_payload_axis_tdata[15:0] + s_eth_payload_axis_tdata[31:16]; hdr_sum_high_reg <= s_eth_payload_axis_tdata[47:32] + s_eth_payload_axis_tdata[63:48]; diff --git a/rtl/ip_eth_tx.v b/rtl/ip_eth_tx.v index 010eed35c..14619f88f 100644 --- a/rtl/ip_eth_tx.v +++ b/rtl/ip_eth_tx.v @@ -123,7 +123,8 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_ip_hdr; reg store_last_word; -reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; +reg [5:0] hdr_ptr_reg = 6'd0, hdr_ptr_next; +reg [15:0] word_count_reg = 16'd0, word_count_next; reg [15:0] hdr_sum_reg = 16'd0, hdr_sum_next; @@ -189,7 +190,8 @@ always @* begin store_last_word = 1'b0; - frame_ptr_next = frame_ptr_reg; + hdr_ptr_next = hdr_ptr_reg; + word_count_next = word_count_reg; hdr_sum_next = hdr_sum_reg; @@ -205,7 +207,7 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 16'd0; + hdr_ptr_next = 6'd0; s_ip_hdr_ready_next = !m_eth_hdr_valid_next; if (s_ip_hdr_ready && s_ip_hdr_valid) begin @@ -215,7 +217,7 @@ always @* begin if (m_eth_payload_axis_tready_int_reg) begin m_eth_payload_axis_tvalid_int = 1'b1; m_eth_payload_axis_tdata_int = {4'd4, 4'd5}; // ip_version, ip_ihl - frame_ptr_next = 16'd1; + hdr_ptr_next = 6'd1; end state_next = STATE_WRITE_HEADER; end else begin @@ -224,60 +226,62 @@ always @* begin end STATE_WRITE_HEADER: begin // write header + word_count_next = ip_length_reg - 5*4; + if (m_eth_payload_axis_tready_int_reg) begin - frame_ptr_next = frame_ptr_reg + 16'd1; + hdr_ptr_next = hdr_ptr_reg + 6'd1; m_eth_payload_axis_tvalid_int = 1; state_next = STATE_WRITE_HEADER; - case (frame_ptr_reg) - 8'h00: begin + case (hdr_ptr_reg) + 6'h00: begin m_eth_payload_axis_tdata_int = {4'd4, 4'd5}; // ip_version, ip_ihl end - 8'h01: begin + 6'h01: begin m_eth_payload_axis_tdata_int = {ip_dscp_reg, ip_ecn_reg}; hdr_sum_next = {4'd4, 4'd5, ip_dscp_reg, ip_ecn_reg}; end - 8'h02: begin + 6'h02: begin m_eth_payload_axis_tdata_int = ip_length_reg[15: 8]; hdr_sum_next = add1c16b(hdr_sum_reg, ip_length_reg); end - 8'h03: begin + 6'h03: begin m_eth_payload_axis_tdata_int = ip_length_reg[ 7: 0]; hdr_sum_next = add1c16b(hdr_sum_reg, ip_identification_reg); end - 8'h04: begin + 6'h04: begin m_eth_payload_axis_tdata_int = ip_identification_reg[15: 8]; hdr_sum_next = add1c16b(hdr_sum_reg, {ip_flags_reg, ip_fragment_offset_reg}); end - 8'h05: begin + 6'h05: begin m_eth_payload_axis_tdata_int = ip_identification_reg[ 7: 0]; hdr_sum_next = add1c16b(hdr_sum_reg, {ip_ttl_reg, ip_protocol_reg}); end - 8'h06: begin + 6'h06: begin m_eth_payload_axis_tdata_int = {ip_flags_reg, ip_fragment_offset_reg[12:8]}; hdr_sum_next = add1c16b(hdr_sum_reg, ip_source_ip_reg[31:16]); end - 8'h07: begin + 6'h07: begin m_eth_payload_axis_tdata_int = ip_fragment_offset_reg[ 7: 0]; hdr_sum_next = add1c16b(hdr_sum_reg, ip_source_ip_reg[15:0]); end - 8'h08: begin + 6'h08: begin m_eth_payload_axis_tdata_int = ip_ttl_reg; hdr_sum_next = add1c16b(hdr_sum_reg, ip_dest_ip_reg[31:16]); end - 8'h09: begin + 6'h09: begin m_eth_payload_axis_tdata_int = ip_protocol_reg; hdr_sum_next = add1c16b(hdr_sum_reg, ip_dest_ip_reg[15:0]); end - 8'h0A: m_eth_payload_axis_tdata_int = ~hdr_sum_reg[15: 8]; - 8'h0B: m_eth_payload_axis_tdata_int = ~hdr_sum_reg[ 7: 0]; - 8'h0C: m_eth_payload_axis_tdata_int = ip_source_ip_reg[31:24]; - 8'h0D: m_eth_payload_axis_tdata_int = ip_source_ip_reg[23:16]; - 8'h0E: m_eth_payload_axis_tdata_int = ip_source_ip_reg[15: 8]; - 8'h0F: m_eth_payload_axis_tdata_int = ip_source_ip_reg[ 7: 0]; - 8'h10: m_eth_payload_axis_tdata_int = ip_dest_ip_reg[31:24]; - 8'h11: m_eth_payload_axis_tdata_int = ip_dest_ip_reg[23:16]; - 8'h12: m_eth_payload_axis_tdata_int = ip_dest_ip_reg[15: 8]; - 8'h13: begin + 6'h0A: m_eth_payload_axis_tdata_int = ~hdr_sum_reg[15: 8]; + 6'h0B: m_eth_payload_axis_tdata_int = ~hdr_sum_reg[ 7: 0]; + 6'h0C: m_eth_payload_axis_tdata_int = ip_source_ip_reg[31:24]; + 6'h0D: m_eth_payload_axis_tdata_int = ip_source_ip_reg[23:16]; + 6'h0E: m_eth_payload_axis_tdata_int = ip_source_ip_reg[15: 8]; + 6'h0F: m_eth_payload_axis_tdata_int = ip_source_ip_reg[ 7: 0]; + 6'h10: m_eth_payload_axis_tdata_int = ip_dest_ip_reg[31:24]; + 6'h11: m_eth_payload_axis_tdata_int = ip_dest_ip_reg[23:16]; + 6'h12: m_eth_payload_axis_tdata_int = ip_dest_ip_reg[15: 8]; + 6'h13: begin m_eth_payload_axis_tdata_int = ip_dest_ip_reg[ 7: 0]; s_ip_payload_axis_tready_next = m_eth_payload_axis_tready_int_early; state_next = STATE_WRITE_PAYLOAD; @@ -298,9 +302,9 @@ always @* begin if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg + 16'd1; + word_count_next = word_count_reg - 6'd1; if (s_ip_payload_axis_tlast) begin - if (frame_ptr_next != ip_length_reg) begin + if (word_count_reg != 16'd1) begin // end of frame, but length does not match m_eth_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; @@ -309,7 +313,7 @@ always @* begin s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin - if (frame_ptr_next == ip_length_reg) begin + if (word_count_reg == 16'd1) begin store_last_word = 1'b1; m_eth_payload_axis_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; @@ -364,8 +368,6 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 16'd0; - hdr_sum_reg <= 16'd0; s_ip_hdr_ready_reg <= 1'b0; s_ip_payload_axis_tready_reg <= 1'b0; m_eth_hdr_valid_reg <= 1'b0; @@ -374,10 +376,6 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; - - hdr_sum_reg <= hdr_sum_next; - s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; s_ip_payload_axis_tready_reg <= s_ip_payload_axis_tready_next; @@ -388,6 +386,11 @@ always @(posedge clk) begin error_payload_early_termination_reg <= error_payload_early_termination_next; end + hdr_ptr_reg <= hdr_ptr_next; + word_count_reg <= word_count_next; + + hdr_sum_reg <= hdr_sum_next; + // datapath if (store_ip_hdr) begin m_eth_dest_mac_reg <= s_eth_dest_mac; diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 7adc52828..8bf8473c0 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -126,7 +126,8 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_ip_hdr; reg store_last_word; -reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; +reg [5:0] hdr_ptr_reg = 6'd0, hdr_ptr_next; +reg [15:0] word_count_reg = 16'd0, word_count_next; reg flush_save; reg transfer_in_save; @@ -256,7 +257,8 @@ always @* begin flush_save = 1'b0; transfer_in_save = 1'b0; - frame_ptr_next = frame_ptr_reg; + hdr_ptr_next = hdr_ptr_reg; + word_count_next = word_count_reg; hdr_sum_temp = 20'd0; hdr_sum_next = hdr_sum_reg; @@ -274,7 +276,7 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 16'd0; + hdr_ptr_next = 6'd0; flush_save = 1'b1; s_ip_hdr_ready_next = !m_eth_hdr_valid_next; @@ -302,7 +304,7 @@ always @* begin m_eth_payload_axis_tdata_int[55:48] = {s_ip_flags, s_ip_fragment_offset[12: 8]}; m_eth_payload_axis_tdata_int[63:56] = s_ip_fragment_offset[ 7: 0]; m_eth_payload_axis_tkeep_int = 8'hff; - frame_ptr_next = 16'd8; + hdr_ptr_next = 6'd8; end state_next = STATE_WRITE_HEADER; end else begin @@ -311,12 +313,14 @@ always @* begin end STATE_WRITE_HEADER: begin // write header + word_count_next = ip_length_reg - 5*4 + 4; + if (m_eth_payload_axis_tready_int_reg) begin - frame_ptr_next = frame_ptr_reg + 16'd8; + hdr_ptr_next = hdr_ptr_reg + 6'd8; m_eth_payload_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; - case (frame_ptr_reg) - 8'h00: begin + case (hdr_ptr_reg) + 6'h00: begin m_eth_payload_axis_tdata_int[ 7: 0] = {4'd4, 4'd5}; // ip_version, ip_ihl m_eth_payload_axis_tdata_int[15: 8] = {ip_dscp_reg, ip_ecn_reg}; m_eth_payload_axis_tdata_int[23:16] = ip_length_reg[15: 8]; @@ -327,7 +331,7 @@ always @* begin m_eth_payload_axis_tdata_int[63:56] = ip_fragment_offset_reg[ 7: 0]; m_eth_payload_axis_tkeep_int = 8'hff; end - 8'h08: begin + 6'h08: begin hdr_sum_temp = hdr_sum_reg[15:0] + hdr_sum_reg[19:16]; hdr_sum_temp = hdr_sum_temp[15:0] + hdr_sum_temp[16]; m_eth_payload_axis_tdata_int[ 7: 0] = ip_ttl_reg; @@ -366,12 +370,11 @@ always @* begin m_eth_payload_axis_tkeep_int = {shift_ip_payload_axis_tkeep[7:4], 4'hF}; m_eth_payload_axis_tlast_int = shift_ip_payload_axis_tlast; m_eth_payload_axis_tuser_int = shift_ip_payload_axis_tuser; - frame_ptr_next = frame_ptr_reg+keep2count(m_eth_payload_axis_tkeep_int); + word_count_next = word_count_reg - 16'd8; - if (frame_ptr_next >= ip_length_reg) begin + if (keep2count(m_eth_payload_axis_tkeep_int) >= word_count_reg) begin // have entire payload - frame_ptr_next = ip_length_reg; - m_eth_payload_axis_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); + m_eth_payload_axis_tkeep_int = count2keep(word_count_reg); if (shift_ip_payload_axis_tlast) begin s_ip_hdr_ready_next = !m_eth_hdr_valid_next; s_ip_payload_axis_tready_next = 1'b0; @@ -411,12 +414,11 @@ always @* begin if (m_eth_payload_axis_tready_int_reg && shift_ip_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+keep2count(shift_ip_payload_axis_tkeep); + word_count_next = word_count_reg - 16'd8; transfer_in_save = 1'b1; - if (frame_ptr_next >= ip_length_reg) begin + if (keep2count(shift_ip_payload_axis_tkeep) >= word_count_reg) begin // have entire payload - frame_ptr_next = ip_length_reg; - m_eth_payload_axis_tkeep_int = count2keep(ip_length_reg - frame_ptr_reg); + m_eth_payload_axis_tkeep_int = count2keep(word_count_reg); if (shift_ip_payload_axis_tlast) begin s_ip_payload_axis_tready_next = 1'b0; flush_save = 1'b1; @@ -489,8 +491,6 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 16'd0; - hdr_sum_reg <= 16'd0; s_ip_hdr_ready_reg <= 1'b0; s_ip_payload_axis_tready_reg <= 1'b0; m_eth_hdr_valid_reg <= 1'b0; @@ -501,10 +501,6 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; - - hdr_sum_reg <= hdr_sum_next; - s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; s_ip_payload_axis_tready_reg <= s_ip_payload_axis_tready_next; @@ -523,6 +519,11 @@ always @(posedge clk) begin end end + hdr_ptr_reg <= hdr_ptr_next; + word_count_reg <= word_count_next; + + hdr_sum_reg <= hdr_sum_next; + // datapath if (store_ip_hdr) begin m_eth_dest_mac_reg <= s_eth_dest_mac; diff --git a/rtl/udp_ip_rx.v b/rtl/udp_ip_rx.v index c143d4d8b..609ff09a2 100644 --- a/rtl/udp_ip_rx.v +++ b/rtl/udp_ip_rx.v @@ -158,7 +158,8 @@ reg store_udp_checksum_0; reg store_udp_checksum_1; reg store_last_word; -reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; +reg [2:0] hdr_ptr_reg = 3'd0, hdr_ptr_next; +reg [15:0] word_count_reg = 16'd0, word_count_next; reg [7:0] last_word_data_reg = 8'd0; @@ -246,7 +247,8 @@ always @* begin store_last_word = 1'b0; - frame_ptr_next = frame_ptr_reg; + hdr_ptr_next = hdr_ptr_reg; + word_count_next = word_count_reg; m_udp_hdr_valid_next = m_udp_hdr_valid_reg && !m_udp_hdr_ready; @@ -261,7 +263,7 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for header - frame_ptr_next = 16'd0; + hdr_ptr_next = 3'd0; s_ip_hdr_ready_next = !m_udp_hdr_valid_next; if (s_ip_hdr_ready && s_ip_hdr_valid) begin @@ -276,21 +278,22 @@ always @* begin STATE_READ_HEADER: begin // read header state s_ip_payload_axis_tready_next = 1'b1; + word_count_next = m_udp_length_reg - 16'd8; if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg + 16'd1; + hdr_ptr_next = hdr_ptr_reg + 3'd1; state_next = STATE_READ_HEADER; - case (frame_ptr_reg) - 8'h00: store_udp_source_port_1 = 1'b1; - 8'h01: store_udp_source_port_0 = 1'b1; - 8'h02: store_udp_dest_port_1 = 1'b1; - 8'h03: store_udp_dest_port_0 = 1'b1; - 8'h04: store_udp_length_1 = 1'b1; - 8'h05: store_udp_length_0 = 1'b1; - 8'h06: store_udp_checksum_1 = 1'b1; - 8'h07: begin + case (hdr_ptr_reg) + 3'h0: store_udp_source_port_1 = 1'b1; + 3'h1: store_udp_source_port_0 = 1'b1; + 3'h2: store_udp_dest_port_1 = 1'b1; + 3'h3: store_udp_dest_port_0 = 1'b1; + 3'h4: store_udp_length_1 = 1'b1; + 3'h5: store_udp_length_0 = 1'b1; + 3'h6: store_udp_checksum_1 = 1'b1; + 3'h7: begin store_udp_checksum_0 = 1'b1; m_udp_hdr_valid_next = 1'b1; s_ip_payload_axis_tready_next = m_udp_payload_axis_tready_int_early; @@ -321,9 +324,9 @@ always @* begin if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg + 16'd1; + word_count_next = word_count_reg - 16'd1; if (s_ip_payload_axis_tlast) begin - if (frame_ptr_next != m_udp_length_reg) begin + if (word_count_reg != 16'd1) begin // end of frame, but length does not match m_udp_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; @@ -332,7 +335,7 @@ always @* begin s_ip_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin - if (frame_ptr_next == m_udp_length_reg) begin + if (word_count_reg == 16'd1) begin store_last_word = 1'b1; m_udp_payload_axis_tvalid_int = 1'b0; state_next = STATE_READ_PAYLOAD_LAST; @@ -387,7 +390,6 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 16'd0; s_ip_hdr_ready_reg <= 1'b0; s_ip_payload_axis_tready_reg <= 1'b0; m_udp_hdr_valid_reg <= 1'b0; @@ -397,7 +399,6 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; s_ip_payload_axis_tready_reg <= s_ip_payload_axis_tready_next; @@ -410,6 +411,9 @@ always @(posedge clk) begin busy_reg <= state_next != STATE_IDLE; end + hdr_ptr_reg <= hdr_ptr_next; + word_count_reg <= word_count_next; + // datapath if (store_ip_hdr) begin m_eth_dest_mac_reg <= s_eth_dest_mac; diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index a9279ce2f..1780f1375 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -153,7 +153,7 @@ reg store_ip_hdr; reg store_hdr_word_0; reg store_last_word; -reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; +reg [15:0] word_count_reg = 16'd0, word_count_next; reg [63:0] last_word_data_reg = 64'd0; reg [7:0] last_word_keep_reg = 8'd0; @@ -266,7 +266,7 @@ always @* begin store_last_word = 1'b0; - frame_ptr_next = frame_ptr_reg; + word_count_next = word_count_reg; m_udp_hdr_valid_next = m_udp_hdr_valid_reg && !m_udp_hdr_ready; @@ -282,7 +282,6 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for header - frame_ptr_next = 16'd0; s_ip_hdr_ready_next = !m_udp_hdr_valid_next; if (s_ip_hdr_ready && s_ip_hdr_valid) begin @@ -298,19 +297,16 @@ always @* begin // read header state s_ip_payload_axis_tready_next = 1'b1; + word_count_next = {s_ip_payload_axis_tdata[39:32], s_ip_payload_axis_tdata[47:40]} - 16'd8; + if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer in - store it - frame_ptr_next = frame_ptr_reg + 16'd8; state_next = STATE_READ_HEADER; - case (frame_ptr_reg) - 8'h00: begin - store_hdr_word_0 = 1'b1; - m_udp_hdr_valid_next = 1'b1; - s_ip_payload_axis_tready_next = m_udp_payload_axis_tready_int_early; - state_next = STATE_READ_PAYLOAD; - end - endcase + store_hdr_word_0 = 1'b1; + m_udp_hdr_valid_next = 1'b1; + s_ip_payload_axis_tready_next = m_udp_payload_axis_tready_int_early; + state_next = STATE_READ_PAYLOAD; if (s_ip_payload_axis_tlast) begin error_header_early_termination_next = 1'b1; @@ -338,11 +334,10 @@ always @* begin if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+keep2count(s_ip_payload_axis_tkeep); - if (frame_ptr_next >= m_udp_length_reg) begin + word_count_next = word_count_reg - 16'd8; + if (keep2count(s_ip_payload_axis_tkeep) >= word_count_reg) begin // have entire payload - frame_ptr_next = m_udp_length_reg; - m_udp_payload_axis_tkeep_int = s_ip_payload_axis_tkeep & count2keep(m_udp_length_reg - frame_ptr_reg); + m_udp_payload_axis_tkeep_int = s_ip_payload_axis_tkeep & count2keep(word_count_reg); if (s_ip_payload_axis_tlast) begin s_ip_payload_axis_tready_next = 1'b0; s_ip_hdr_ready_next = !m_udp_hdr_valid_next; @@ -411,7 +406,6 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 16'd0; s_ip_hdr_ready_reg <= 1'b0; s_ip_payload_axis_tready_reg <= 1'b0; m_udp_hdr_valid_reg <= 1'b0; @@ -421,8 +415,6 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; - s_ip_hdr_ready_reg <= s_ip_hdr_ready_next; s_ip_payload_axis_tready_reg <= s_ip_payload_axis_tready_next; @@ -434,6 +426,8 @@ always @(posedge clk) begin busy_reg <= state_next != STATE_IDLE; end + word_count_reg <= word_count_next; + // datapath if (store_ip_hdr) begin m_eth_dest_mac_reg <= s_eth_dest_mac; diff --git a/rtl/udp_ip_tx.v b/rtl/udp_ip_tx.v index 096e9444c..23ae0ee47 100644 --- a/rtl/udp_ip_tx.v +++ b/rtl/udp_ip_tx.v @@ -147,7 +147,8 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_udp_hdr; reg store_last_word; -reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; +reg [2:0] hdr_ptr_reg = 3'd0, hdr_ptr_next; +reg [15:0] word_count_reg = 16'd0, word_count_next; reg [7:0] last_word_data_reg = 8'd0; @@ -222,7 +223,8 @@ always @* begin store_last_word = 1'b0; - frame_ptr_next = frame_ptr_reg; + hdr_ptr_next = hdr_ptr_reg; + word_count_next = word_count_reg; m_ip_hdr_valid_next = m_ip_hdr_valid_reg && !m_ip_hdr_ready; @@ -236,7 +238,7 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 16'd0; + hdr_ptr_next = 3'd0; s_udp_hdr_ready_next = !m_ip_hdr_valid_next; if (s_udp_hdr_ready && s_udp_hdr_valid) begin @@ -246,7 +248,7 @@ always @* begin if (m_ip_payload_axis_tready_int_reg) begin m_ip_payload_axis_tvalid_int = 1'b1; m_ip_payload_axis_tdata_int = s_udp_source_port[15: 8]; - frame_ptr_next = 1'b1; + hdr_ptr_next = 3'd1; end state_next = STATE_WRITE_HEADER; end else begin @@ -255,20 +257,22 @@ always @* begin end STATE_WRITE_HEADER: begin // write header state + word_count_next = udp_length_reg - 16'd8; + if (m_ip_payload_axis_tready_int_reg) begin // word transfer out - frame_ptr_next = frame_ptr_reg + 16'd1; + hdr_ptr_next = hdr_ptr_reg + 3'd1; m_ip_payload_axis_tvalid_int = 1'b1; state_next = STATE_WRITE_HEADER; - case (frame_ptr_reg) - 8'h00: m_ip_payload_axis_tdata_int = udp_source_port_reg[15: 8]; - 8'h01: m_ip_payload_axis_tdata_int = udp_source_port_reg[ 7: 0]; - 8'h02: m_ip_payload_axis_tdata_int = udp_dest_port_reg[15: 8]; - 8'h03: m_ip_payload_axis_tdata_int = udp_dest_port_reg[ 7: 0]; - 8'h04: m_ip_payload_axis_tdata_int = udp_length_reg[15: 8]; - 8'h05: m_ip_payload_axis_tdata_int = udp_length_reg[ 7: 0]; - 8'h06: m_ip_payload_axis_tdata_int = udp_checksum_reg[15: 8]; - 8'h07: begin + case (hdr_ptr_reg) + 3'h0: m_ip_payload_axis_tdata_int = udp_source_port_reg[15: 8]; + 3'h1: m_ip_payload_axis_tdata_int = udp_source_port_reg[ 7: 0]; + 3'h2: m_ip_payload_axis_tdata_int = udp_dest_port_reg[15: 8]; + 3'h3: m_ip_payload_axis_tdata_int = udp_dest_port_reg[ 7: 0]; + 3'h4: m_ip_payload_axis_tdata_int = udp_length_reg[15: 8]; + 3'h5: m_ip_payload_axis_tdata_int = udp_length_reg[ 7: 0]; + 3'h6: m_ip_payload_axis_tdata_int = udp_checksum_reg[15: 8]; + 3'h7: begin m_ip_payload_axis_tdata_int = udp_checksum_reg[ 7: 0]; s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; state_next = STATE_WRITE_PAYLOAD; @@ -289,9 +293,9 @@ always @* begin if (s_udp_payload_axis_tready && s_udp_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg + 16'd1; + word_count_next = word_count_reg - 16'd1; if (s_udp_payload_axis_tlast) begin - if (frame_ptr_next != udp_length_reg) begin + if (word_count_reg != 16'd1) begin // end of frame, but length does not match m_ip_payload_axis_tuser_int = 1'b1; error_payload_early_termination_next = 1'b1; @@ -300,7 +304,7 @@ always @* begin s_udp_payload_axis_tready_next = 1'b0; state_next = STATE_IDLE; end else begin - if (frame_ptr_next == udp_length_reg) begin + if (word_count_reg == 16'd1) begin store_last_word = 1'b1; m_ip_payload_axis_tvalid_int = 1'b0; state_next = STATE_WRITE_PAYLOAD_LAST; @@ -355,7 +359,6 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 16'd0; s_udp_hdr_ready_reg <= 1'b0; s_udp_payload_axis_tready_reg <= 1'b0; m_ip_hdr_valid_reg <= 1'b0; @@ -364,8 +367,6 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; - s_udp_hdr_ready_reg <= s_udp_hdr_ready_next; s_udp_payload_axis_tready_reg <= s_udp_payload_axis_tready_next; @@ -376,6 +377,9 @@ always @(posedge clk) begin error_payload_early_termination_reg <= error_payload_early_termination_next; end + hdr_ptr_reg <= hdr_ptr_next; + word_count_reg <= word_count_next; + // datapath if (store_udp_hdr) begin m_eth_dest_mac_reg <= s_eth_dest_mac; diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index bd7f56384..b74421db7 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -149,7 +149,7 @@ reg [2:0] state_reg = STATE_IDLE, state_next; reg store_udp_hdr; reg store_last_word; -reg [15:0] frame_ptr_reg = 16'd0, frame_ptr_next; +reg [15:0] word_count_reg = 16'd0, word_count_next; reg [63:0] last_word_data_reg = 64'd0; reg [7:0] last_word_keep_reg = 8'd0; @@ -256,7 +256,7 @@ always @* begin store_last_word = 1'b0; - frame_ptr_next = frame_ptr_reg; + word_count_next = word_count_reg; m_ip_hdr_valid_next = m_ip_hdr_valid_reg && !m_ip_hdr_ready; @@ -271,8 +271,8 @@ always @* begin case (state_reg) STATE_IDLE: begin // idle state - wait for data - frame_ptr_next = 16'd0; s_udp_hdr_ready_next = !m_ip_hdr_valid_next; + word_count_next = s_udp_length - 16'd8; if (s_udp_hdr_ready && s_udp_hdr_valid) begin store_udp_hdr = 1'b1; @@ -290,7 +290,6 @@ always @* begin m_ip_payload_axis_tdata_int[55:48] = s_udp_checksum[15: 8]; m_ip_payload_axis_tdata_int[63:56] = s_udp_checksum[ 7: 0]; m_ip_payload_axis_tkeep_int = 8'hff; - frame_ptr_next = 16'd8; s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; state_next = STATE_WRITE_PAYLOAD; end @@ -302,24 +301,18 @@ always @* begin // write header state if (m_ip_payload_axis_tready_int_reg) begin // word transfer out - frame_ptr_next = frame_ptr_reg + 16'd8; m_ip_payload_axis_tvalid_int = 1'b1; - state_next = STATE_WRITE_HEADER; - case (frame_ptr_reg) - 8'h00: begin - m_ip_payload_axis_tdata_int[ 7: 0] = udp_source_port_reg[15: 8]; - m_ip_payload_axis_tdata_int[15: 8] = udp_source_port_reg[ 7: 0]; - m_ip_payload_axis_tdata_int[23:16] = udp_dest_port_reg[15: 8]; - m_ip_payload_axis_tdata_int[31:24] = udp_dest_port_reg[ 7: 0]; - m_ip_payload_axis_tdata_int[39:32] = udp_length_reg[15: 8]; - m_ip_payload_axis_tdata_int[47:40] = udp_length_reg[ 7: 0]; - m_ip_payload_axis_tdata_int[55:48] = udp_checksum_reg[15: 8]; - m_ip_payload_axis_tdata_int[63:56] = udp_checksum_reg[ 7: 0]; - m_ip_payload_axis_tkeep_int = 8'hff; - s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; - state_next = STATE_WRITE_PAYLOAD; - end - endcase + m_ip_payload_axis_tdata_int[ 7: 0] = udp_source_port_reg[15: 8]; + m_ip_payload_axis_tdata_int[15: 8] = udp_source_port_reg[ 7: 0]; + m_ip_payload_axis_tdata_int[23:16] = udp_dest_port_reg[15: 8]; + m_ip_payload_axis_tdata_int[31:24] = udp_dest_port_reg[ 7: 0]; + m_ip_payload_axis_tdata_int[39:32] = udp_length_reg[15: 8]; + m_ip_payload_axis_tdata_int[47:40] = udp_length_reg[ 7: 0]; + m_ip_payload_axis_tdata_int[55:48] = udp_checksum_reg[15: 8]; + m_ip_payload_axis_tdata_int[63:56] = udp_checksum_reg[ 7: 0]; + m_ip_payload_axis_tkeep_int = 8'hff; + s_udp_payload_axis_tready_next = m_ip_payload_axis_tready_int_early; + state_next = STATE_WRITE_PAYLOAD; end else begin state_next = STATE_WRITE_HEADER; end @@ -338,11 +331,10 @@ always @* begin if (m_ip_payload_axis_tready_int_reg && s_udp_payload_axis_tvalid) begin // word transfer through - frame_ptr_next = frame_ptr_reg+keep2count(s_udp_payload_axis_tkeep); - if (frame_ptr_next >= udp_length_reg) begin + word_count_next = word_count_reg - 16'd8; + if (keep2count(s_udp_payload_axis_tkeep) >= word_count_reg) begin // have entire payload - frame_ptr_next = udp_length_reg; - m_ip_payload_axis_tkeep_int = count2keep(udp_length_reg - frame_ptr_reg); + m_ip_payload_axis_tkeep_int = count2keep(word_count_reg); if (s_udp_payload_axis_tlast) begin s_udp_payload_axis_tready_next = 1'b0; s_udp_hdr_ready_next = !m_ip_hdr_valid_next; @@ -411,7 +403,6 @@ end always @(posedge clk) begin if (rst) begin state_reg <= STATE_IDLE; - frame_ptr_reg <= 16'd0; s_udp_hdr_ready_reg <= 1'b0; s_udp_payload_axis_tready_reg <= 1'b0; m_ip_hdr_valid_reg <= 1'b0; @@ -420,7 +411,6 @@ always @(posedge clk) begin end else begin state_reg <= state_next; - frame_ptr_reg <= frame_ptr_next; s_udp_hdr_ready_reg <= s_udp_hdr_ready_next; s_udp_payload_axis_tready_reg <= s_udp_payload_axis_tready_next; @@ -432,6 +422,8 @@ always @(posedge clk) begin error_payload_early_termination_reg <= error_payload_early_termination_next; end + word_count_reg <= word_count_next; + // datapath if (store_udp_hdr) begin m_eth_dest_mac_reg <= s_eth_dest_mac; From 303dec816548404af956fec51ee513e85d922831 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Jun 2019 00:25:41 -0700 Subject: [PATCH 592/617] Sum errors across data and header --- rtl/eth_phy_10g_rx_if.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/eth_phy_10g_rx_if.v b/rtl/eth_phy_10g_rx_if.v index 996afcfec..cbd0d2a7c 100644 --- a/rtl/eth_phy_10g_rx_if.v +++ b/rtl/eth_phy_10g_rx_if.v @@ -158,7 +158,7 @@ integer i; always @* begin rx_error_count_1_temp = 0; rx_error_count_2_temp = 0; - for (i = 0; i < DATA_WIDTH; i = i + 1) begin + for (i = 0; i < DATA_WIDTH+HDR_WIDTH; i = i + 1) begin if (i & 1) begin rx_error_count_1_temp = rx_error_count_1_temp + prbs31_data[i]; end else begin From 3ba91ce091a438131afc12e61614f41a0edc412a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Jun 2019 00:53:41 -0700 Subject: [PATCH 593/617] Wait for block lock --- tb/test_eth_mac_phy_10g.py | 8 ++++++++ tb/test_eth_mac_phy_10g_fifo.py | 8 ++++++++ tb/test_eth_phy_10g_64.py | 8 ++++++++ tb/test_eth_phy_10g_rx_64.py | 8 ++++++++ 4 files changed, 32 insertions(+) diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py index 5f5f43e6c..bff32f2bc 100755 --- a/tb/test_eth_mac_phy_10g.py +++ b/tb/test_eth_mac_phy_10g.py @@ -275,6 +275,14 @@ def bench(): # testbench stimulus + # wait for block lock + while not rx_block_lock: + yield clk.posedge + + # dump garbage + while not axis_sink.empty(): + axis_sink.recv() + yield clk.posedge print("test 1: test rx packet") current_test.next = 1 diff --git a/tb/test_eth_mac_phy_10g_fifo.py b/tb/test_eth_mac_phy_10g_fifo.py index 628fd946c..f3347df87 100755 --- a/tb/test_eth_mac_phy_10g_fifo.py +++ b/tb/test_eth_mac_phy_10g_fifo.py @@ -281,6 +281,14 @@ def bench(): # testbench stimulus + # wait for block lock + while not rx_block_lock: + yield clk.posedge + + # dump garbage + while not axis_sink.empty(): + axis_sink.recv() + yield clk.posedge print("test 1: test rx packet") current_test.next = 1 diff --git a/tb/test_eth_phy_10g_64.py b/tb/test_eth_phy_10g_64.py index 55d216fc2..47f9cb47a 100755 --- a/tb/test_eth_phy_10g_64.py +++ b/tb/test_eth_phy_10g_64.py @@ -213,6 +213,14 @@ def bench(): # testbench stimulus + # wait for block lock + while not rx_block_lock: + yield clk.posedge + + # dump garbage + while not xgmii_sink.empty(): + xgmii_sink.recv() + yield clk.posedge print("test 1: test RX packet") current_test.next = 1 diff --git a/tb/test_eth_phy_10g_rx_64.py b/tb/test_eth_phy_10g_rx_64.py index c7f0277cd..030523eea 100755 --- a/tb/test_eth_phy_10g_rx_64.py +++ b/tb/test_eth_phy_10g_rx_64.py @@ -183,6 +183,14 @@ def bench(): # testbench stimulus + # wait for block lock + while not rx_block_lock: + yield clk.posedge + + # dump garbage + while not sink.empty(): + sink.recv() + for payload_len in list(range(16,34)): yield clk.posedge print("test 1: test packet, length %d" % payload_len) From 134ce047778fa1f964435bc78436f2a2ee5b4ae1 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Jun 2019 00:57:28 -0700 Subject: [PATCH 594/617] Add configurable serdes pipeline register chain --- rtl/eth_mac_phy_10g.v | 6 ++++- rtl/eth_mac_phy_10g_fifo.v | 4 ++++ rtl/eth_mac_phy_10g_rx.v | 2 ++ rtl/eth_mac_phy_10g_tx.v | 6 +++-- rtl/eth_phy_10g.v | 6 ++++- rtl/eth_phy_10g_rx.v | 2 ++ rtl/eth_phy_10g_rx_if.v | 39 +++++++++++++++++++++++++++----- rtl/eth_phy_10g_tx.v | 6 +++-- rtl/eth_phy_10g_tx_if.v | 40 ++++++++++++++++++++++++++++----- tb/test_eth_mac_phy_10g.py | 2 ++ tb/test_eth_mac_phy_10g.v | 4 ++++ tb/test_eth_mac_phy_10g_fifo.py | 2 ++ tb/test_eth_mac_phy_10g_fifo.v | 4 ++++ tb/test_eth_phy_10g_64.py | 2 ++ tb/test_eth_phy_10g_64.v | 4 ++++ tb/test_eth_phy_10g_rx_64.py | 1 + tb/test_eth_phy_10g_rx_64.v | 2 ++ tb/test_eth_phy_10g_tx_64.py | 1 + tb/test_eth_phy_10g_tx_64.v | 4 +++- 19 files changed, 119 insertions(+), 18 deletions(-) diff --git a/rtl/eth_mac_phy_10g.v b/rtl/eth_mac_phy_10g.v index 1811e5f79..31390eb07 100644 --- a/rtl/eth_mac_phy_10g.v +++ b/rtl/eth_mac_phy_10g.v @@ -51,6 +51,8 @@ module eth_mac_phy_10g # parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0, + parameter TX_SERDES_PIPELINE = 0, + parameter RX_SERDES_PIPELINE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4 ) @@ -131,6 +133,7 @@ eth_mac_phy_10g_rx #( .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), + .SERDES_PIPELINE(RX_SERDES_PIPELINE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) @@ -173,7 +176,8 @@ eth_mac_phy_10g_tx #( .USER_WIDTH(TX_USER_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), - .PRBS31_ENABLE(PRBS31_ENABLE) + .PRBS31_ENABLE(PRBS31_ENABLE), + .SERDES_PIPELINE(TX_SERDES_PIPELINE) ) eth_mac_phy_10g_tx_inst ( .clk(tx_clk), diff --git a/rtl/eth_mac_phy_10g_fifo.v b/rtl/eth_mac_phy_10g_fifo.v index a502d6731..405ae374d 100644 --- a/rtl/eth_mac_phy_10g_fifo.v +++ b/rtl/eth_mac_phy_10g_fifo.v @@ -41,6 +41,8 @@ module eth_mac_phy_10g_fifo # parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0, + parameter TX_SERDES_PIPELINE = 0, + parameter RX_SERDES_PIPELINE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4, parameter TX_FIFO_ADDR_WIDTH = 12-$clog2(KEEP_WIDTH), @@ -201,6 +203,8 @@ eth_mac_phy_10g #( .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), + .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), + .RX_SERDES_PIPELINE(RX_SERDES_PIPELINE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) diff --git a/rtl/eth_mac_phy_10g_rx.v b/rtl/eth_mac_phy_10g_rx.v index 44476eef4..f46dd3832 100644 --- a/rtl/eth_mac_phy_10g_rx.v +++ b/rtl/eth_mac_phy_10g_rx.v @@ -43,6 +43,7 @@ module eth_mac_phy_10g_rx # parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0, + parameter SERDES_PIPELINE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4 ) @@ -115,6 +116,7 @@ eth_phy_10g_rx_if #( .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), + .SERDES_PIPELINE(SERDES_PIPELINE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) diff --git a/rtl/eth_mac_phy_10g_tx.v b/rtl/eth_mac_phy_10g_tx.v index 4b80b8cc5..56a3713f9 100644 --- a/rtl/eth_mac_phy_10g_tx.v +++ b/rtl/eth_mac_phy_10g_tx.v @@ -47,7 +47,8 @@ module eth_mac_phy_10g_tx # parameter USER_WIDTH = (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, - parameter PRBS31_ENABLE = 0 + parameter PRBS31_ENABLE = 0, + parameter SERDES_PIPELINE = 0 ) ( input wire clk, @@ -151,7 +152,8 @@ eth_phy_10g_tx_if #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), - .PRBS31_ENABLE(PRBS31_ENABLE) + .PRBS31_ENABLE(PRBS31_ENABLE), + .SERDES_PIPELINE(SERDES_PIPELINE) ) eth_phy_10g_tx_if_inst ( .clk(clk), diff --git a/rtl/eth_phy_10g.v b/rtl/eth_phy_10g.v index 341e86f5e..3db237317 100644 --- a/rtl/eth_phy_10g.v +++ b/rtl/eth_phy_10g.v @@ -37,6 +37,8 @@ module eth_phy_10g # parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0, + parameter TX_SERDES_PIPELINE = 0, + parameter RX_SERDES_PIPELINE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4 ) @@ -85,6 +87,7 @@ eth_phy_10g_rx #( .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), + .SERDES_PIPELINE(RX_SERDES_PIPELINE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) @@ -109,7 +112,8 @@ eth_phy_10g_tx #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), - .PRBS31_ENABLE(PRBS31_ENABLE) + .PRBS31_ENABLE(PRBS31_ENABLE), + .SERDES_PIPELINE(TX_SERDES_PIPELINE) ) eth_phy_10g_tx_inst ( .clk(tx_clk), diff --git a/rtl/eth_phy_10g_rx.v b/rtl/eth_phy_10g_rx.v index 931e6bb34..05bd6619e 100644 --- a/rtl/eth_phy_10g_rx.v +++ b/rtl/eth_phy_10g_rx.v @@ -37,6 +37,7 @@ module eth_phy_10g_rx # parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0, + parameter SERDES_PIPELINE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4 ) @@ -98,6 +99,7 @@ eth_phy_10g_rx_if #( .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), + .SERDES_PIPELINE(SERDES_PIPELINE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) diff --git a/rtl/eth_phy_10g_rx_if.v b/rtl/eth_phy_10g_rx_if.v index cbd0d2a7c..a7edf5adb 100644 --- a/rtl/eth_phy_10g_rx_if.v +++ b/rtl/eth_phy_10g_rx_if.v @@ -36,6 +36,7 @@ module eth_phy_10g_rx_if # parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, parameter PRBS31_ENABLE = 0, + parameter SERDES_PIPELINE = 0, parameter SLIP_COUNT_WIDTH = 3, parameter COUNT_125US = 125000/6.4 ) @@ -83,24 +84,50 @@ initial begin end end -wire [DATA_WIDTH-1:0] serdes_rx_data_int; -wire [HDR_WIDTH-1:0] serdes_rx_hdr_int; +wire [DATA_WIDTH-1:0] serdes_rx_data_rev, serdes_rx_data_int; +wire [HDR_WIDTH-1:0] serdes_rx_hdr_rev, serdes_rx_hdr_int; generate genvar n; if (BIT_REVERSE) begin for (n = 0; n < DATA_WIDTH; n = n + 1) begin - assign serdes_rx_data_int[n] = serdes_rx_data[DATA_WIDTH-n-1]; + assign serdes_rx_data_rev[n] = serdes_rx_data[DATA_WIDTH-n-1]; end for (n = 0; n < HDR_WIDTH; n = n + 1) begin - assign serdes_rx_hdr_int[n] = serdes_rx_hdr[HDR_WIDTH-n-1]; + assign serdes_rx_hdr_rev[n] = serdes_rx_hdr[HDR_WIDTH-n-1]; end end else begin - assign serdes_rx_data_int = serdes_rx_data; - assign serdes_rx_hdr_int = serdes_rx_hdr; + assign serdes_rx_data_rev = serdes_rx_data; + assign serdes_rx_hdr_rev = serdes_rx_hdr; end + + if (SERDES_PIPELINE > 0) begin + (* srl_style = "register" *) + reg [DATA_WIDTH-1:0] serdes_rx_data_pipe_reg[SERDES_PIPELINE-1:0]; + (* srl_style = "register" *) + reg [HDR_WIDTH-1:0] serdes_rx_hdr_pipe_reg[SERDES_PIPELINE-1:0]; + + for (n = 0; n < SERDES_PIPELINE; n = n + 1) begin + initial begin + serdes_rx_data_pipe_reg[n] <= {DATA_WIDTH{1'b0}}; + serdes_rx_hdr_pipe_reg[n] <= {HDR_WIDTH{1'b0}}; + end + + always @(posedge clk) begin + serdes_rx_data_pipe_reg[n] <= n == 0 ? serdes_rx_data_rev : serdes_rx_data_pipe_reg[n-1]; + serdes_rx_hdr_pipe_reg[n] <= n == 0 ? serdes_rx_hdr_rev : serdes_rx_hdr_pipe_reg[n-1]; + end + end + + assign serdes_rx_data_int = serdes_rx_data_pipe_reg[SERDES_PIPELINE-1]; + assign serdes_rx_hdr_int = serdes_rx_hdr_pipe_reg[SERDES_PIPELINE-1]; + end else begin + assign serdes_rx_data_int = serdes_rx_data_rev; + assign serdes_rx_hdr_int = serdes_rx_hdr_rev; + end + endgenerate wire [DATA_WIDTH-1:0] descrambled_rx_data; diff --git a/rtl/eth_phy_10g_tx.v b/rtl/eth_phy_10g_tx.v index 6fc6caf73..86488353e 100644 --- a/rtl/eth_phy_10g_tx.v +++ b/rtl/eth_phy_10g_tx.v @@ -36,7 +36,8 @@ module eth_phy_10g_tx # parameter HDR_WIDTH = 2, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, - parameter PRBS31_ENABLE = 0 + parameter PRBS31_ENABLE = 0, + parameter SERDES_PIPELINE = 0 ) ( input wire clk, @@ -100,7 +101,8 @@ eth_phy_10g_tx_if #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), - .PRBS31_ENABLE(PRBS31_ENABLE) + .PRBS31_ENABLE(PRBS31_ENABLE), + .SERDES_PIPELINE(SERDES_PIPELINE) ) eth_phy_10g_tx_if_inst ( .clk(clk), diff --git a/rtl/eth_phy_10g_tx_if.v b/rtl/eth_phy_10g_tx_if.v index 5f84c6ba2..70ea70b7b 100644 --- a/rtl/eth_phy_10g_tx_if.v +++ b/rtl/eth_phy_10g_tx_if.v @@ -35,7 +35,8 @@ module eth_phy_10g_tx_if # parameter HDR_WIDTH = 2, parameter BIT_REVERSE = 0, parameter SCRAMBLER_DISABLE = 0, - parameter PRBS31_ENABLE = 0 + parameter PRBS31_ENABLE = 0, + parameter SERDES_PIPELINE = 0 ) ( input wire clk, @@ -83,21 +84,50 @@ wire [DATA_WIDTH+HDR_WIDTH-1:0] prbs31_data; reg [DATA_WIDTH-1:0] serdes_tx_data_reg = {DATA_WIDTH{1'b0}}; reg [HDR_WIDTH-1:0] serdes_tx_hdr_reg = {HDR_WIDTH{1'b0}}; +wire [DATA_WIDTH-1:0] serdes_tx_data_int; +wire [HDR_WIDTH-1:0] serdes_tx_hdr_int; + generate genvar n; if (BIT_REVERSE) begin for (n = 0; n < DATA_WIDTH; n = n + 1) begin - assign serdes_tx_data[n] = serdes_tx_data_reg[DATA_WIDTH-n-1]; + assign serdes_tx_data_int[n] = serdes_tx_data_reg[DATA_WIDTH-n-1]; end for (n = 0; n < HDR_WIDTH; n = n + 1) begin - assign serdes_tx_hdr[n] = serdes_tx_hdr_reg[HDR_WIDTH-n-1]; + assign serdes_tx_hdr_int[n] = serdes_tx_hdr_reg[HDR_WIDTH-n-1]; end end else begin - assign serdes_tx_data = serdes_tx_data_reg; - assign serdes_tx_hdr = serdes_tx_hdr_reg; + assign serdes_tx_data_int = serdes_tx_data_reg; + assign serdes_tx_hdr_int = serdes_tx_hdr_reg; end + + if (SERDES_PIPELINE > 0) begin + (* srl_style = "register" *) + reg [DATA_WIDTH-1:0] serdes_tx_data_pipe_reg[SERDES_PIPELINE-1:0]; + (* srl_style = "register" *) + reg [HDR_WIDTH-1:0] serdes_tx_hdr_pipe_reg[SERDES_PIPELINE-1:0]; + + for (n = 0; n < SERDES_PIPELINE; n = n + 1) begin + initial begin + serdes_tx_data_pipe_reg[n] <= {DATA_WIDTH{1'b0}}; + serdes_tx_hdr_pipe_reg[n] <= {HDR_WIDTH{1'b0}}; + end + + always @(posedge clk) begin + serdes_tx_data_pipe_reg[n] <= n == 0 ? serdes_tx_data_int : serdes_tx_data_pipe_reg[n-1]; + serdes_tx_hdr_pipe_reg[n] <= n == 0 ? serdes_tx_hdr_int : serdes_tx_hdr_pipe_reg[n-1]; + end + end + + assign serdes_tx_data = serdes_tx_data_pipe_reg[SERDES_PIPELINE-1]; + assign serdes_tx_hdr = serdes_tx_hdr_pipe_reg[SERDES_PIPELINE-1]; + end else begin + assign serdes_tx_data = serdes_tx_data_int; + assign serdes_tx_hdr = serdes_tx_hdr_int; + end + endgenerate lfsr #( diff --git a/tb/test_eth_mac_phy_10g.py b/tb/test_eth_mac_phy_10g.py index bff32f2bc..e1f885308 100755 --- a/tb/test_eth_mac_phy_10g.py +++ b/tb/test_eth_mac_phy_10g.py @@ -75,6 +75,8 @@ def bench(): BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 PRBS31_ENABLE = 1 + TX_SERDES_PIPELINE = 2 + RX_SERDES_PIPELINE = 2 SLIP_COUNT_WIDTH = 3 COUNT_125US = 125000/6.4 diff --git a/tb/test_eth_mac_phy_10g.v b/tb/test_eth_mac_phy_10g.v index 45911b60f..06033637e 100644 --- a/tb/test_eth_mac_phy_10g.v +++ b/tb/test_eth_mac_phy_10g.v @@ -52,6 +52,8 @@ parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; parameter PRBS31_ENABLE = 1; +parameter TX_SERDES_PIPELINE = 2; +parameter RX_SERDES_PIPELINE = 2; parameter SLIP_COUNT_WIDTH = 3; parameter COUNT_125US = 125000/6.4; @@ -173,6 +175,8 @@ eth_mac_phy_10g #( .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), + .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), + .RX_SERDES_PIPELINE(RX_SERDES_PIPELINE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) diff --git a/tb/test_eth_mac_phy_10g_fifo.py b/tb/test_eth_mac_phy_10g_fifo.py index f3347df87..c2f13fc85 100755 --- a/tb/test_eth_mac_phy_10g_fifo.py +++ b/tb/test_eth_mac_phy_10g_fifo.py @@ -67,6 +67,8 @@ def bench(): BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 PRBS31_ENABLE = 1 + TX_SERDES_PIPELINE = 2 + RX_SERDES_PIPELINE = 2 SLIP_COUNT_WIDTH = 3 COUNT_125US = 125000/6.4 TX_FIFO_ADDR_WIDTH = 12-(KEEP_WIDTH-1).bit_length() diff --git a/tb/test_eth_mac_phy_10g_fifo.v b/tb/test_eth_mac_phy_10g_fifo.v index a688e60c7..00276002a 100644 --- a/tb/test_eth_mac_phy_10g_fifo.v +++ b/tb/test_eth_mac_phy_10g_fifo.v @@ -42,6 +42,8 @@ parameter MIN_FRAME_LENGTH = 64; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; parameter PRBS31_ENABLE = 1; +parameter TX_SERDES_PIPELINE = 2; +parameter RX_SERDES_PIPELINE = 2; parameter SLIP_COUNT_WIDTH = 3; parameter COUNT_125US = 125000/6.4; parameter TX_FIFO_ADDR_WIDTH = 12-$clog2(KEEP_WIDTH); @@ -163,6 +165,8 @@ eth_mac_phy_10g_fifo #( .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), + .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), + .RX_SERDES_PIPELINE(RX_SERDES_PIPELINE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US), .TX_FIFO_ADDR_WIDTH(TX_FIFO_ADDR_WIDTH), diff --git a/tb/test_eth_phy_10g_64.py b/tb/test_eth_phy_10g_64.py index 47f9cb47a..174877801 100755 --- a/tb/test_eth_phy_10g_64.py +++ b/tb/test_eth_phy_10g_64.py @@ -61,6 +61,8 @@ def bench(): BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 PRBS31_ENABLE = 1 + TX_SERDES_PIPELINE = 2 + RX_SERDES_PIPELINE = 2 SLIP_COUNT_WIDTH = 3 COUNT_125US = 1250/6.4 diff --git a/tb/test_eth_phy_10g_64.v b/tb/test_eth_phy_10g_64.v index 94c102caa..51939ce3b 100644 --- a/tb/test_eth_phy_10g_64.v +++ b/tb/test_eth_phy_10g_64.v @@ -38,6 +38,8 @@ parameter HDR_WIDTH = 2; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; parameter PRBS31_ENABLE = 1; +parameter TX_SERDES_PIPELINE = 2; +parameter RX_SERDES_PIPELINE = 2; parameter SLIP_COUNT_WIDTH = 3; parameter COUNT_125US = 125000/6.4; @@ -109,6 +111,8 @@ eth_phy_10g #( .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), + .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), + .RX_SERDES_PIPELINE(RX_SERDES_PIPELINE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) diff --git a/tb/test_eth_phy_10g_rx_64.py b/tb/test_eth_phy_10g_rx_64.py index 030523eea..22be35f79 100755 --- a/tb/test_eth_phy_10g_rx_64.py +++ b/tb/test_eth_phy_10g_rx_64.py @@ -68,6 +68,7 @@ def bench(): BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 PRBS31_ENABLE = 1 + SERDES_PIPELINE = 2 SLIP_COUNT_WIDTH = 3 COUNT_125US = 1250/6.4 diff --git a/tb/test_eth_phy_10g_rx_64.v b/tb/test_eth_phy_10g_rx_64.v index 96bb37e6b..846088af6 100644 --- a/tb/test_eth_phy_10g_rx_64.v +++ b/tb/test_eth_phy_10g_rx_64.v @@ -38,6 +38,7 @@ parameter HDR_WIDTH = 2; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; parameter PRBS31_ENABLE = 1; +parameter SERDES_PIPELINE = 2; parameter SLIP_COUNT_WIDTH = 3; parameter COUNT_125US = 1250/6.4; @@ -91,6 +92,7 @@ eth_phy_10g_rx #( .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_ENABLE(PRBS31_ENABLE), + .SERDES_PIPELINE(SERDES_PIPELINE), .SLIP_COUNT_WIDTH(SLIP_COUNT_WIDTH), .COUNT_125US(COUNT_125US) ) diff --git a/tb/test_eth_phy_10g_tx_64.py b/tb/test_eth_phy_10g_tx_64.py index 79b9339f0..1bed6c7a9 100755 --- a/tb/test_eth_phy_10g_tx_64.py +++ b/tb/test_eth_phy_10g_tx_64.py @@ -66,6 +66,7 @@ def bench(): BIT_REVERSE = 0 SCRAMBLER_DISABLE = 0 PRBS31_ENABLE = 1 + SERDES_PIPELINE = 2 # Inputs clk = Signal(bool(0)) diff --git a/tb/test_eth_phy_10g_tx_64.v b/tb/test_eth_phy_10g_tx_64.v index 374be71f5..eb45ce9a1 100644 --- a/tb/test_eth_phy_10g_tx_64.v +++ b/tb/test_eth_phy_10g_tx_64.v @@ -38,6 +38,7 @@ parameter HDR_WIDTH = 2; parameter BIT_REVERSE = 0; parameter SCRAMBLER_DISABLE = 0; parameter PRBS31_ENABLE = 1; +parameter SERDES_PIPELINE = 2; // Inputs reg clk = 0; @@ -78,7 +79,8 @@ eth_phy_10g_tx #( .HDR_WIDTH(HDR_WIDTH), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), - .PRBS31_ENABLE(PRBS31_ENABLE) + .PRBS31_ENABLE(PRBS31_ENABLE), + .SERDES_PIPELINE(SERDES_PIPELINE) ) UUT ( .clk(clk), From eb1f38a749fe655b492eb7e0166c6e1ab6dd0a52 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Jun 2019 15:06:55 -0700 Subject: [PATCH 595/617] More critical path optimizations --- rtl/ip_eth_rx_64.v | 7 ++++++- rtl/ip_eth_tx_64.v | 7 ++++++- rtl/udp_ip_rx_64.v | 7 ++++++- rtl/udp_ip_tx_64.v | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/rtl/ip_eth_rx_64.v b/rtl/ip_eth_rx_64.v index 188675e2a..47554645c 100644 --- a/rtl/ip_eth_rx_64.v +++ b/rtl/ip_eth_rx_64.v @@ -396,10 +396,15 @@ always @* begin // word transfer through word_count_next = word_count_reg - 16'd8; transfer_in_save = 1'b1; - if (word_count_reg <= keep2count(shift_eth_payload_axis_tkeep)) begin + if (word_count_reg <= 8) begin // have entire payload m_ip_payload_axis_tkeep_int = shift_eth_payload_axis_tkeep & count2keep(word_count_reg); if (shift_eth_payload_axis_tlast) begin + if (keep2count(shift_eth_payload_axis_tkeep) < word_count_reg[4:0]) begin + // end of frame, but length does not match + error_payload_early_termination_next = 1'b1; + m_ip_payload_axis_tuser_int = 1'b1; + end s_eth_payload_axis_tready_next = 1'b0; flush_save = 1'b1; s_eth_hdr_ready_next = !m_ip_hdr_valid_reg && !check_hdr_reg; diff --git a/rtl/ip_eth_tx_64.v b/rtl/ip_eth_tx_64.v index 8bf8473c0..471cf239f 100644 --- a/rtl/ip_eth_tx_64.v +++ b/rtl/ip_eth_tx_64.v @@ -416,10 +416,15 @@ always @* begin // word transfer through word_count_next = word_count_reg - 16'd8; transfer_in_save = 1'b1; - if (keep2count(shift_ip_payload_axis_tkeep) >= word_count_reg) begin + if (word_count_reg <= 8) begin // have entire payload m_eth_payload_axis_tkeep_int = count2keep(word_count_reg); if (shift_ip_payload_axis_tlast) begin + if (keep2count(shift_ip_payload_axis_tkeep) < word_count_reg[4:0]) begin + // end of frame, but length does not match + error_payload_early_termination_next = 1'b1; + m_eth_payload_axis_tuser_int = 1'b1; + end s_ip_payload_axis_tready_next = 1'b0; flush_save = 1'b1; s_ip_hdr_ready_next = !m_eth_hdr_valid_next; diff --git a/rtl/udp_ip_rx_64.v b/rtl/udp_ip_rx_64.v index 1780f1375..e3244ce28 100644 --- a/rtl/udp_ip_rx_64.v +++ b/rtl/udp_ip_rx_64.v @@ -335,10 +335,15 @@ always @* begin if (s_ip_payload_axis_tready && s_ip_payload_axis_tvalid) begin // word transfer through word_count_next = word_count_reg - 16'd8; - if (keep2count(s_ip_payload_axis_tkeep) >= word_count_reg) begin + if (word_count_reg <= 8) begin // have entire payload m_udp_payload_axis_tkeep_int = s_ip_payload_axis_tkeep & count2keep(word_count_reg); if (s_ip_payload_axis_tlast) begin + if (keep2count(s_ip_payload_axis_tkeep) < word_count_reg[4:0]) begin + // end of frame, but length does not match + error_payload_early_termination_next = 1'b1; + m_udp_payload_axis_tuser_int = 1'b1; + end s_ip_payload_axis_tready_next = 1'b0; s_ip_hdr_ready_next = !m_udp_hdr_valid_next; state_next = STATE_IDLE; diff --git a/rtl/udp_ip_tx_64.v b/rtl/udp_ip_tx_64.v index b74421db7..fe899b900 100644 --- a/rtl/udp_ip_tx_64.v +++ b/rtl/udp_ip_tx_64.v @@ -332,10 +332,15 @@ always @* begin if (m_ip_payload_axis_tready_int_reg && s_udp_payload_axis_tvalid) begin // word transfer through word_count_next = word_count_reg - 16'd8; - if (keep2count(s_udp_payload_axis_tkeep) >= word_count_reg) begin + if (word_count_reg <= 8) begin // have entire payload m_ip_payload_axis_tkeep_int = count2keep(word_count_reg); if (s_udp_payload_axis_tlast) begin + if (keep2count(s_udp_payload_axis_tkeep) < word_count_reg[4:0]) begin + // end of frame, but length does not match + error_payload_early_termination_next = 1'b1; + m_ip_payload_axis_tuser_int = 1'b1; + end s_udp_payload_axis_tready_next = 1'b0; s_udp_hdr_ready_next = !m_ip_hdr_valid_next; state_next = STATE_IDLE; From a031993b268b24c6f8adae32d229445e2387bf65 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Jun 2019 23:16:57 -0700 Subject: [PATCH 596/617] Update example designs --- example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci | 5 +++-- example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci | 5 +++-- example/VCU118/fpga_10g/ip/gtwizard_ultrascale_0.xci | 5 +++-- example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci b/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci index d7bc14aa1..ef03a5467 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci +++ b/example/ADM_PCIE_9V3/fpga_10g/ip/gtwizard_ultrascale_0.xci @@ -1362,16 +1362,17 @@ MIXED -2 + I TRUE TRUE IP_Flow - 5 + 6 TRUE . . - 2018.3 + 2019.1 OUT_OF_CONTEXT diff --git a/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci index 129b30ccd..1e578e860 100644 --- a/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci +++ b/example/VCU118/fpga_10g/ip/gig_ethernet_pcs_pma_0.xci @@ -309,16 +309,17 @@ MIXED -2L + E TRUE TRUE IP_Flow - 5 + 6 TRUE . . - 2018.3 + 2019.1 OUT_OF_CONTEXT diff --git a/example/VCU118/fpga_10g/ip/gtwizard_ultrascale_0.xci b/example/VCU118/fpga_10g/ip/gtwizard_ultrascale_0.xci index a596a88d5..31eeac690 100644 --- a/example/VCU118/fpga_10g/ip/gtwizard_ultrascale_0.xci +++ b/example/VCU118/fpga_10g/ip/gtwizard_ultrascale_0.xci @@ -1362,16 +1362,17 @@ MIXED -2L + E TRUE TRUE IP_Flow - 5 + 6 TRUE . . - 2018.3 + 2019.1 OUT_OF_CONTEXT diff --git a/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci index 129b30ccd..1e578e860 100644 --- a/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci +++ b/example/VCU118/fpga_1g/ip/gig_ethernet_pcs_pma_0.xci @@ -309,16 +309,17 @@ MIXED -2L + E TRUE TRUE IP_Flow - 5 + 6 TRUE . . - 2018.3 + 2019.1 OUT_OF_CONTEXT From 1a28b0bf6707c4666778f364c8d0939e8b15c324 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Jun 2019 23:22:56 -0700 Subject: [PATCH 597/617] Add ADM-PCIE-9V3 25G example design --- example/ADM_PCIE_9V3/fpga_25g/Makefile | 25 + example/ADM_PCIE_9V3/fpga_25g/README.md | 24 + .../ADM_PCIE_9V3/fpga_25g/common/vivado.mk | 118 ++ example/ADM_PCIE_9V3/fpga_25g/fpga.xdc | 176 ++ example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile | 69 + .../fpga_25g/ip/gtwizard_ultrascale_0.xci | 1411 +++++++++++++++++ example/ADM_PCIE_9V3/fpga_25g/lib/eth | 1 + .../fpga_25g/rtl/debounce_switch.v | 89 ++ example/ADM_PCIE_9V3/fpga_25g/rtl/fpga.v | 904 +++++++++++ example/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v | 659 ++++++++ .../ADM_PCIE_9V3/fpga_25g/rtl/sync_reset.v | 52 + .../ADM_PCIE_9V3/fpga_25g/rtl/sync_signal.v | 58 + example/ADM_PCIE_9V3/fpga_25g/tb/arp_ep.py | 1 + example/ADM_PCIE_9V3/fpga_25g/tb/axis_ep.py | 1 + example/ADM_PCIE_9V3/fpga_25g/tb/eth_ep.py | 1 + example/ADM_PCIE_9V3/fpga_25g/tb/ip_ep.py | 1 + .../fpga_25g/tb/test_fpga_core.py | 462 ++++++ .../ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.v | 269 ++++ example/ADM_PCIE_9V3/fpga_25g/tb/udp_ep.py | 1 + example/ADM_PCIE_9V3/fpga_25g/tb/xgmii_ep.py | 1 + 20 files changed, 4323 insertions(+) create mode 100644 example/ADM_PCIE_9V3/fpga_25g/Makefile create mode 100644 example/ADM_PCIE_9V3/fpga_25g/README.md create mode 100644 example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk create mode 100644 example/ADM_PCIE_9V3/fpga_25g/fpga.xdc create mode 100644 example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile create mode 100644 example/ADM_PCIE_9V3/fpga_25g/ip/gtwizard_ultrascale_0.xci create mode 120000 example/ADM_PCIE_9V3/fpga_25g/lib/eth create mode 100644 example/ADM_PCIE_9V3/fpga_25g/rtl/debounce_switch.v create mode 100644 example/ADM_PCIE_9V3/fpga_25g/rtl/fpga.v create mode 100644 example/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v create mode 100644 example/ADM_PCIE_9V3/fpga_25g/rtl/sync_reset.v create mode 100644 example/ADM_PCIE_9V3/fpga_25g/rtl/sync_signal.v create mode 120000 example/ADM_PCIE_9V3/fpga_25g/tb/arp_ep.py create mode 120000 example/ADM_PCIE_9V3/fpga_25g/tb/axis_ep.py create mode 120000 example/ADM_PCIE_9V3/fpga_25g/tb/eth_ep.py create mode 120000 example/ADM_PCIE_9V3/fpga_25g/tb/ip_ep.py create mode 100755 example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py create mode 100644 example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.v create mode 120000 example/ADM_PCIE_9V3/fpga_25g/tb/udp_ep.py create mode 120000 example/ADM_PCIE_9V3/fpga_25g/tb/xgmii_ep.py diff --git a/example/ADM_PCIE_9V3/fpga_25g/Makefile b/example/ADM_PCIE_9V3/fpga_25g/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/ADM_PCIE_9V3/fpga_25g/README.md b/example/ADM_PCIE_9V3/fpga_25g/README.md new file mode 100644 index 000000000..691f825b8 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/README.md @@ -0,0 +1,24 @@ +# Verilog Ethernet ADM-PCIE-9V3 Example Design + +## Introduction + +This example design targets the Alpha Data ADM-PCIE-9V3 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +FPGA: xcvu3p-ffvc1517-2-i +PHY: 25G BASE-R PHY IP core and internal GTY transceiver + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the ADM-PCIE-9V3 board with Vivado. Then run +netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any text +entered into netcat will be echoed back after pressing enter. + diff --git a/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk b/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk new file mode 100644 index 000000000..a54b530f6 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk @@ -0,0 +1,118 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile $(XCI_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/ADM_PCIE_9V3/fpga_25g/fpga.xdc b/example/ADM_PCIE_9V3/fpga_25g/fpga.xdc new file mode 100644 index 000000000..0ba473e92 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/fpga.xdc @@ -0,0 +1,176 @@ +# XDC constraints for the ADM-PCIE-9V3 +# part: xcvu3p-ffvc1517-2-i + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN {DIV-1} [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 8 [current_design] +set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] +set_property BITSTREAM.CONFIG.UNUSEDPIN {Pullnone} [current_design] +set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design] + +# 300 MHz system clock +set_property -dict {LOC AP26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_p] +set_property -dict {LOC AP27 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_n] +create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p] + +# LEDs +set_property -dict {LOC AT27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[0]}] +set_property -dict {LOC AU27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[1]}] +set_property -dict {LOC AU23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_r}] +set_property -dict {LOC AH24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[0]}] +set_property -dict {LOC AJ23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[1]}] + +# Switches +set_property -dict {LOC AV27 IOSTANDARD LVCMOS18} [get_ports {user_sw[0]}] +set_property -dict {LOC AW27 IOSTANDARD LVCMOS18} [get_ports {user_sw[1]}] + +# GPIO +#set_property -dict {LOC G30 IOSTANDARD LVCMOS18} [get_ports gpio_p[0]] +#set_property -dict {LOC F30 IOSTANDARD LVCMOS18} [get_ports gpio_n[0]] +#set_property -dict {LOC J31 IOSTANDARD LVCMOS18} [get_ports gpio_p[1]] +#set_property -dict {LOC H31 IOSTANDARD LVCMOS18} [get_ports gpio_n[1]] + +# QSFP28 Interfaces +set_property -dict {LOC G38 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXN0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC G39 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXP0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC E38 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXN1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC E39 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXP1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC C38 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXN2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC C39 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXP2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC B36 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXN3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC B37 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXP3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC F35 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXN0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC F36 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXP0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC D35 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXN1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC D36 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXP1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC C33 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXN2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC C34 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXP2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC A33 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXN3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4 +#set_property -dict {LOC A34 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXP3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4 +set_property -dict {LOC N33 } [get_ports qsfp_0_mgt_refclk_p] ;# MGTREFCLK0P_128 from ? +#set_property -dict {LOC N34 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_128 from ? +set_property -dict {LOC F29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_0_modprs_l] +set_property -dict {LOC D31 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_0_sel_l] + +# 161.1328125 MHz MGT reference clock +create_clock -period 6.206 -name qsfp_0_mgt_refclk [get_ports qsfp_0_mgt_refclk_p] + +set_property -dict {LOC R38 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC R39 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC N38 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC N39 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC L38 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC L39 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC J38 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC J39 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC P35 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC P36 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC M35 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC M36 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC K35 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC K36 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC H35 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +#set_property -dict {LOC H36 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3 +set_property -dict {LOC U33 } [get_ports qsfp_1_mgt_refclk_p] ;# MGTREFCLK0P_127 from ? +#set_property -dict {LOC U34 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_127 from ? +set_property -dict {LOC F33 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_1_modprs_l] +set_property -dict {LOC D30 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_1_sel_l] + +# 161.1328125 MHz MGT reference clock +create_clock -period 6.206 -name qsfp_1_mgt_refclk [get_ports qsfp_1_mgt_refclk_p] + +set_property -dict {LOC B29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_reset_l] +set_property -dict {LOC C29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_int_l] +#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_i2c_scl] +#set_property -dict {LOC A29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_i2c_sda] + +# PCIe Interface +#set_property -dict {LOC J2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC J1 } [get_ports {pcie_rx_n[0]}] ;# MGTYTXP3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC H5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXN3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC H4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXP3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC L2 } [get_ports {pcie_rx_p[1]}] ;# MGTYTXN2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC L1 } [get_ports {pcie_rx_n[1]}] ;# MGTYTXP2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC K5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXN2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC K4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXP2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC N2 } [get_ports {pcie_rx_p[2]}] ;# MGTYTXN1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC N1 } [get_ports {pcie_rx_n[2]}] ;# MGTYTXP1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC M5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXN1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC M4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXP1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC R2 } [get_ports {pcie_rx_p[3]}] ;# MGTYTXN0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC R1 } [get_ports {pcie_rx_n[3]}] ;# MGTYTXP0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC P5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXN0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC P4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXP0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1 +#set_property -dict {LOC U2 } [get_ports {pcie_rx_p[4]}] ;# MGTYTXN3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC U1 } [get_ports {pcie_rx_n[4]}] ;# MGTYTXP3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC T5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXN3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC T4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXP3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC W2 } [get_ports {pcie_rx_p[5]}] ;# MGTYTXN2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC W1 } [get_ports {pcie_rx_n[5]}] ;# MGTYTXP2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC V5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXN2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC V4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXP2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AA2 } [get_ports {pcie_rx_p[6]}] ;# MGTYTXN1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AA1 } [get_ports {pcie_rx_n[6]}] ;# MGTYTXP1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXN1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXP1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AC2 } [get_ports {pcie_rx_p[7]}] ;# MGTYTXN0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AC1 } [get_ports {pcie_rx_n[7]}] ;# MGTYTXP0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXN0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXP0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AE2 } [get_ports {pcie_rx_p[8]}] ;# MGTYTXN3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AE1 } [get_ports {pcie_rx_n[8]}] ;# MGTYTXP3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXN3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXP3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[9]}] ;# MGTYTXN2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[9]}] ;# MGTYTXP2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXN2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXP2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[10]}] ;# MGTYTXN1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[10]}] ;# MGTYTXP1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AK5 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXN1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AK4 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXP1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[11]}] ;# MGTYTXN0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[11]}] ;# MGTYTXP0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AM5 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXN0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AM4 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXP0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[12]}] ;# MGTYTXN3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[12]}] ;# MGTYTXP3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AP5 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXN3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AP4 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXP3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[13]}] ;# MGTYTXN2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[13]}] ;# MGTYTXP2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AT5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXN2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AT4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXP2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[14]}] ;# MGTYTXN1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[14]}] ;# MGTYTXP1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXN1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXP1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[15]}] ;# MGTYTXN0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[15]}] ;# MGTYTXP0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AW7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXN0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AW6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXP0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0 +#set_property -dict {LOC AA7 } [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_226 +#set_property -dict {LOC AA6 } [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_226 +#set_property -dict {LOC AJ7 } [get_ports pcie_refclk_2_p] ;# MGTREFCLK0P_224 +#set_property -dict {LOC AJ6 } [get_ports pcie_refclk_2_n] ;# MGTREFCLK0N_224 +#set_property -dict {LOC AJ31 IOSTANDARD LVCMOS18 PULLUP true} [get_ports perst_0] +#set_property -dict {LOC AH29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports perst_1] + +# 100 MHz MGT reference clock +#create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_1_p] +#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p] + +# QSPI flash +#set_property -dict {LOC AB10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi_clk}] +#set_property -dict {LOC AB8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[0]}] +#set_property -dict {LOC AD8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[1]}] +#set_property -dict {LOC Y8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[2]}] +#set_property -dict {LOC AC8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[3]}] +#set_property -dict {LOC AF30 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[0]}] +#set_property -dict {LOC AG30 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[1]}] +#set_property -dict {LOC AF28 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[2]}] +#set_property -dict {LOC AG28 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[3]}] diff --git a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile new file mode 100644 index 000000000..5c5aa8e84 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile @@ -0,0 +1,69 @@ + +# FPGA settings +FPGA_PART = xcvu3p-ffvc1517-2-i +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/eth_phy_10g.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v +SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v +SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp_64.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v +SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl + +# IP +XCI_FILES += ip/gtwizard_ultrascale_0.xci + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl + echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "exit" >> program.tcl + vivado -mode batch -source program.tcl + diff --git a/example/ADM_PCIE_9V3/fpga_25g/ip/gtwizard_ultrascale_0.xci b/example/ADM_PCIE_9V3/fpga_25g/ip/gtwizard_ultrascale_0.xci new file mode 100644 index 000000000..9862aadf8 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/ip/gtwizard_ultrascale_0.xci @@ -0,0 +1,1411 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gtwizard_ultrascale_0 + + + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111000000000000" + 2 + 2578.125 + 0 + 0 + 125 + 67 + 3 + 2 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 0 + 250 + 0 + 0 + 0 + 0 + 0 + 1 + "00000000" + "00000000" + 1 + 4 + 0 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000" + 0 + "00000000" + 1 + 0 + 5000 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + 0 + "1010000011" + 0 + "0101111100" + 4 + 1 + 64 + 25.78125 + 15 + 1 + 390.6250000 + 4 + 0 + 0x000000000000000000000000000000000000000000000000 + 161.1328125 + 0 + 0 + 0 + 1 + 1 + 0 + 64 + 390.6250000 + 390.6250000 + 0 + 257.8125 + 0 + 8 + 2 + 0 + 0 + 0 + 390.625 + 0 + 0 + 1 + 4 + 1 + 64 + 25.78125 + 15 + 1 + 390.6250000 + 4 + 0 + 161.1328125 + 0 + 0 + 1 + 1 + 0 + 64 + 390.6250000 + 390.6250000 + 1 + X0Y19 X0Y18 X0Y17 X0Y16 X0Y15 X0Y14 X0Y13 X0Y12 + gtwizard_ultrascale_0 + 0 + 0 + + 125 + BOTH + 0 + GTY + 2 + 30 + 96 + 3 + gtye4 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + -1 + -1 + -1 + -1 + 1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + -1 + 0 + 0 + 0 + -1 + 0 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 27 + 0 + 10GBASE-R + 9 + 390.6250000 + 8 + 2 + 390.6250000 + false + CORE + NONE + CORE + CORE + EXAMPLE_DESIGN + CORE + EXAMPLE_DESIGN + CORE + false + NAME + false + 250 + false + false + 250 + GTY-10GBASE-R + 0 + MULTI + 1 + ENABLE + DISABLE + ENABLE + 00000000 + false + false + false + false + false + false + false + false + 00000000 + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 4 + 1 + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + false + false + false + false + false + false + false + false + 00000000 + DISABLE + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 0 + 5000 + ENABLE + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 1 + false + 0000000000 + false + 1010000011 + NONE + false + 0101111100 + true + 0 + AC + 64B66B_ASYNC + true + AUTO + 64 + 10 + -20 + 25.78125 + X0Y15 + RXPROGDIVCLK + QPLL0 + 200 + 0 + + 161.1328125 + + OFF + 0 + PROGRAMMABLE + 800 + 64 + 15 + false + 0 + 10.3125 + 257.8125 + 0 + false + QPLL0 + 390.625 + 1 + ENABLE + 64B66B_ASYNC + CUSTOM + true + 64 + 25.78125 + X0Y15 + TXPROGDIVCLK + QPLL0 + 0 + 161.1328125 + + 64 + false + 1 + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + true + true + false + true + true + true + false + true + true + true + false + false + false + false + false + true + false + false + false + false + false + true + true + true + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + virtexuplus + + + xcvu3p + ffvc1517 + VERILOG + + MIXED + -2 + + I + TRUE + TRUE + IP_Flow + 6 + TRUE + . + + . + 2019.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ADM_PCIE_9V3/fpga_25g/lib/eth b/example/ADM_PCIE_9V3/fpga_25g/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_25g/rtl/debounce_switch.v b/example/ADM_PCIE_9V3/fpga_25g/rtl/debounce_switch.v new file mode 100644 index 000000000..bb631cc35 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_25g/rtl/fpga.v b/example/ADM_PCIE_9V3/fpga_25g/rtl/fpga.v new file mode 100644 index 000000000..82be12252 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/rtl/fpga.v @@ -0,0 +1,904 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 300MHz LVDS + */ + input wire clk_300mhz_p, + input wire clk_300mhz_n, + + /* + * GPIO + */ + output wire [1:0] user_led_g, + output wire user_led_r, + output wire [1:0] front_led, + input wire [1:0] user_sw, + + /* + * Ethernet: QSFP28 + */ + output wire qsfp_0_tx_0_p, + output wire qsfp_0_tx_0_n, + input wire qsfp_0_rx_0_p, + input wire qsfp_0_rx_0_n, + output wire qsfp_0_tx_1_p, + output wire qsfp_0_tx_1_n, + input wire qsfp_0_rx_1_p, + input wire qsfp_0_rx_1_n, + output wire qsfp_0_tx_2_p, + output wire qsfp_0_tx_2_n, + input wire qsfp_0_rx_2_p, + input wire qsfp_0_rx_2_n, + output wire qsfp_0_tx_3_p, + output wire qsfp_0_tx_3_n, + input wire qsfp_0_rx_3_p, + input wire qsfp_0_rx_3_n, + input wire qsfp_0_mgt_refclk_p, + input wire qsfp_0_mgt_refclk_n, + input wire qsfp_0_modprs_l, + output wire qsfp_0_sel_l, + + output wire qsfp_1_tx_0_p, + output wire qsfp_1_tx_0_n, + input wire qsfp_1_rx_0_p, + input wire qsfp_1_rx_0_n, + output wire qsfp_1_tx_1_p, + output wire qsfp_1_tx_1_n, + input wire qsfp_1_rx_1_p, + input wire qsfp_1_rx_1_n, + output wire qsfp_1_tx_2_p, + output wire qsfp_1_tx_2_n, + input wire qsfp_1_rx_2_p, + input wire qsfp_1_rx_2_n, + output wire qsfp_1_tx_3_p, + output wire qsfp_1_tx_3_n, + input wire qsfp_1_rx_3_p, + input wire qsfp_1_rx_3_n, + input wire qsfp_1_mgt_refclk_p, + input wire qsfp_1_mgt_refclk_n, + input wire qsfp_1_modprs_l, + output wire qsfp_1_sel_l, + + output wire qsfp_reset_l, + input wire qsfp_int_l +); + +// Clock and reset + +wire clk_300mhz_ibufg; +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +// Internal 156.25 MHz clock +wire clk_156mhz_int; +wire rst_156mhz_int; + +wire mmcm_rst = 1'b0; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS #( + .DIFF_TERM("FALSE"), + .IBUF_LOW_PWR("FALSE") +) +clk_300mhz_ibufg_inst ( + .O (clk_300mhz_ibufg), + .I (clk_300mhz_p), + .IB (clk_300mhz_n) +); + +// MMCM instance +// 300 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 10, D = 3 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCME3_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(10), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(3), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(3.333), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_300mhz_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire [1:0] user_sw_int; + +debounce_switch #( + .WIDTH(2), + .N(4), + .RATE(125000) +) +debounce_switch_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + .in({user_sw}), + .out({user_sw_int}) +); + +// XGMII 10G PHY +assign qsfp_0_sel_l = 1'b0; + +wire qsfp_0_tx_clk_0_int; +wire qsfp_0_tx_rst_0_int; +wire [63:0] qsfp_0_txd_0_int; +wire [7:0] qsfp_0_txc_0_int; +wire qsfp_0_rx_clk_0_int; +wire qsfp_0_rx_rst_0_int; +wire [63:0] qsfp_0_rxd_0_int; +wire [7:0] qsfp_0_rxc_0_int; +wire qsfp_0_tx_clk_1_int; +wire qsfp_0_tx_rst_1_int; +wire [63:0] qsfp_0_txd_1_int; +wire [7:0] qsfp_0_txc_1_int; +wire qsfp_0_rx_clk_1_int; +wire qsfp_0_rx_rst_1_int; +wire [63:0] qsfp_0_rxd_1_int; +wire [7:0] qsfp_0_rxc_1_int; +wire qsfp_0_tx_clk_2_int; +wire qsfp_0_tx_rst_2_int; +wire [63:0] qsfp_0_txd_2_int; +wire [7:0] qsfp_0_txc_2_int; +wire qsfp_0_rx_clk_2_int; +wire qsfp_0_rx_rst_2_int; +wire [63:0] qsfp_0_rxd_2_int; +wire [7:0] qsfp_0_rxc_2_int; +wire qsfp_0_tx_clk_3_int; +wire qsfp_0_tx_rst_3_int; +wire [63:0] qsfp_0_txd_3_int; +wire [7:0] qsfp_0_txc_3_int; +wire qsfp_0_rx_clk_3_int; +wire qsfp_0_rx_rst_3_int; +wire [63:0] qsfp_0_rxd_3_int; +wire [7:0] qsfp_0_rxc_3_int; + +assign qsfp_1_sel_l = 1'b0; + +wire qsfp_1_tx_clk_0_int; +wire qsfp_1_tx_rst_0_int; +wire [63:0] qsfp_1_txd_0_int; +wire [7:0] qsfp_1_txc_0_int; +wire qsfp_1_rx_clk_0_int; +wire qsfp_1_rx_rst_0_int; +wire [63:0] qsfp_1_rxd_0_int; +wire [7:0] qsfp_1_rxc_0_int; +wire qsfp_1_tx_clk_1_int; +wire qsfp_1_tx_rst_1_int; +wire [63:0] qsfp_1_txd_1_int; +wire [7:0] qsfp_1_txc_1_int; +wire qsfp_1_rx_clk_1_int; +wire qsfp_1_rx_rst_1_int; +wire [63:0] qsfp_1_rxd_1_int; +wire [7:0] qsfp_1_rxc_1_int; +wire qsfp_1_tx_clk_2_int; +wire qsfp_1_tx_rst_2_int; +wire [63:0] qsfp_1_txd_2_int; +wire [7:0] qsfp_1_txc_2_int; +wire qsfp_1_rx_clk_2_int; +wire qsfp_1_rx_rst_2_int; +wire [63:0] qsfp_1_rxd_2_int; +wire [7:0] qsfp_1_rxc_2_int; +wire qsfp_1_tx_clk_3_int; +wire qsfp_1_tx_rst_3_int; +wire [63:0] qsfp_1_txd_3_int; +wire [7:0] qsfp_1_txc_3_int; +wire qsfp_1_rx_clk_3_int; +wire qsfp_1_rx_rst_3_int; +wire [63:0] qsfp_1_rxd_3_int; +wire [7:0] qsfp_1_rxc_3_int; + +assign qsfp_reset_l = 1'b1; + +wire qsfp_0_rx_block_lock_0; +wire qsfp_0_rx_block_lock_1; +wire qsfp_0_rx_block_lock_2; +wire qsfp_0_rx_block_lock_3; + +wire qsfp_1_rx_block_lock_0; +wire qsfp_1_rx_block_lock_1; +wire qsfp_1_rx_block_lock_2; +wire qsfp_1_rx_block_lock_3; + +wire qsfp_0_mgt_refclk; +wire qsfp_1_mgt_refclk; + +wire [7:0] gt_txclkout; +wire gt_txusrclk; + +wire [7:0] gt_rxclkout; +wire [7:0] gt_rxusrclk; + +wire gt_reset_tx_done; +wire gt_reset_rx_done; + +wire [7:0] gt_txprgdivresetdone; +wire [7:0] gt_txpmaresetdone; +wire [7:0] gt_rxprgdivresetdone; +wire [7:0] gt_rxpmaresetdone; + +wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); +wire gt_rx_reset = ~>_rxpmaresetdone; + +reg gt_userclk_tx_active = 1'b0; +reg [7:0] gt_userclk_rx_active = 1'b0; + +IBUFDS_GTE4 ibufds_gte4_qsfp_0_mgt_refclk_inst ( + .I (qsfp_0_mgt_refclk_p), + .IB (qsfp_0_mgt_refclk_n), + .CEB (1'b0), + .O (qsfp_0_mgt_refclk), + .ODIV2 () +); + +IBUFDS_GTE4 ibufds_gte4_qsfp_1_mgt_refclk_inst ( + .I (qsfp_1_mgt_refclk_p), + .IB (qsfp_1_mgt_refclk_n), + .CEB (1'b0), + .O (qsfp_1_mgt_refclk), + .ODIV2 () +); + + +BUFG_GT bufg_gt_tx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txclkout[0]), + .O (gt_txusrclk) +); + +assign clk_156mhz_int = gt_txusrclk; + +always @(posedge gt_txusrclk, posedge gt_tx_reset) begin + if (gt_tx_reset) begin + gt_userclk_tx_active <= 1'b0; + end else begin + gt_userclk_tx_active <= 1'b1; + end +end + +generate + +genvar n; + +for (n = 0; n < 8; n = n + 1) begin + + BUFG_GT bufg_gt_rx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk[n]) + ); + + always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin + if (gt_rx_reset) begin + gt_userclk_rx_active[n] <= 1'b0; + end else begin + gt_userclk_rx_active[n] <= 1'b1; + end + end + +end + +endgenerate + +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz_int), + .rst(~gt_reset_tx_done), + .sync_reset_out(rst_156mhz_int) +); + +wire [5:0] qsfp_0_gt_txheader_0; +wire [63:0] qsfp_0_gt_txdata_0; +wire qsfp_0_gt_rxgearboxslip_0; +wire [5:0] qsfp_0_gt_rxheader_0; +wire [1:0] qsfp_0_gt_rxheadervalid_0; +wire [63:0] qsfp_0_gt_rxdata_0; +wire [1:0] qsfp_0_gt_rxdatavalid_0; + +wire [5:0] qsfp_0_gt_txheader_1; +wire [63:0] qsfp_0_gt_txdata_1; +wire qsfp_0_gt_rxgearboxslip_1; +wire [5:0] qsfp_0_gt_rxheader_1; +wire [1:0] qsfp_0_gt_rxheadervalid_1; +wire [63:0] qsfp_0_gt_rxdata_1; +wire [1:0] qsfp_0_gt_rxdatavalid_1; + +wire [5:0] qsfp_0_gt_txheader_2; +wire [63:0] qsfp_0_gt_txdata_2; +wire qsfp_0_gt_rxgearboxslip_2; +wire [5:0] qsfp_0_gt_rxheader_2; +wire [1:0] qsfp_0_gt_rxheadervalid_2; +wire [63:0] qsfp_0_gt_rxdata_2; +wire [1:0] qsfp_0_gt_rxdatavalid_2; + +wire [5:0] qsfp_0_gt_txheader_3; +wire [63:0] qsfp_0_gt_txdata_3; +wire qsfp_0_gt_rxgearboxslip_3; +wire [5:0] qsfp_0_gt_rxheader_3; +wire [1:0] qsfp_0_gt_rxheadervalid_3; +wire [63:0] qsfp_0_gt_rxdata_3; +wire [1:0] qsfp_0_gt_rxdatavalid_3; + +wire [5:0] qsfp_1_gt_txheader_0; +wire [63:0] qsfp_1_gt_txdata_0; +wire qsfp_1_gt_rxgearboxslip_0; +wire [5:0] qsfp_1_gt_rxheader_0; +wire [1:0] qsfp_1_gt_rxheadervalid_0; +wire [63:0] qsfp_1_gt_rxdata_0; +wire [1:0] qsfp_1_gt_rxdatavalid_0; + +wire [5:0] qsfp_1_gt_txheader_1; +wire [63:0] qsfp_1_gt_txdata_1; +wire qsfp_1_gt_rxgearboxslip_1; +wire [5:0] qsfp_1_gt_rxheader_1; +wire [1:0] qsfp_1_gt_rxheadervalid_1; +wire [63:0] qsfp_1_gt_rxdata_1; +wire [1:0] qsfp_1_gt_rxdatavalid_1; + +wire [5:0] qsfp_1_gt_txheader_2; +wire [63:0] qsfp_1_gt_txdata_2; +wire qsfp_1_gt_rxgearboxslip_2; +wire [5:0] qsfp_1_gt_rxheader_2; +wire [1:0] qsfp_1_gt_rxheadervalid_2; +wire [63:0] qsfp_1_gt_rxdata_2; +wire [1:0] qsfp_1_gt_rxdatavalid_2; + +wire [5:0] qsfp_1_gt_txheader_3; +wire [63:0] qsfp_1_gt_txdata_3; +wire qsfp_1_gt_rxgearboxslip_3; +wire [5:0] qsfp_1_gt_rxheader_3; +wire [1:0] qsfp_1_gt_rxheadervalid_3; +wire [63:0] qsfp_1_gt_rxdata_3; +wire [1:0] qsfp_1_gt_rxdatavalid_3; + +gtwizard_ultrascale_0 +qsfp_gty_inst ( + .gtwiz_userclk_tx_active_in(>_userclk_tx_active), + .gtwiz_userclk_rx_active_in(>_userclk_rx_active), + + .gtwiz_reset_clk_freerun_in(clk_125mhz_int), + .gtwiz_reset_all_in(rst_125mhz_int), + + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(1'b0), + + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(1'b0), + + .gtwiz_reset_rx_cdr_stable_out(), + + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + + .gtrefclk00_in({qsfp_0_mgt_refclk, qsfp_1_mgt_refclk}), + + .qpll0outclk_out(), + .qpll0outrefclk_out(), + + .gtyrxn_in({qsfp_0_rx_3_n, qsfp_0_rx_2_n, qsfp_0_rx_1_n, qsfp_0_rx_0_n, qsfp_1_rx_3_n, qsfp_1_rx_2_n, qsfp_1_rx_1_n, qsfp_1_rx_0_n}), + .gtyrxp_in({qsfp_0_rx_3_p, qsfp_0_rx_2_p, qsfp_0_rx_1_p, qsfp_0_rx_0_p, qsfp_1_rx_3_p, qsfp_1_rx_2_p, qsfp_1_rx_1_p, qsfp_1_rx_0_p}), + + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk), + + .gtwiz_userdata_tx_in({qsfp_0_gt_txdata_3, qsfp_0_gt_txdata_2, qsfp_0_gt_txdata_1, qsfp_0_gt_txdata_0, qsfp_1_gt_txdata_3, qsfp_1_gt_txdata_2, qsfp_1_gt_txdata_1, qsfp_1_gt_txdata_0}), + .txheader_in({qsfp_0_gt_txheader_3, qsfp_0_gt_txheader_2, qsfp_0_gt_txheader_1, qsfp_0_gt_txheader_0, qsfp_1_gt_txheader_3, qsfp_1_gt_txheader_2, qsfp_1_gt_txheader_1, qsfp_1_gt_txheader_0}), + .txsequence_in({8{1'b0}}), + + .txusrclk_in({8{gt_txusrclk}}), + .txusrclk2_in({8{gt_txusrclk}}), + + .gtpowergood_out(), + + .gtytxn_out({qsfp_0_tx_3_n, qsfp_0_tx_2_n, qsfp_0_tx_1_n, qsfp_0_tx_0_n, qsfp_1_tx_3_n, qsfp_1_tx_2_n, qsfp_1_tx_1_n, qsfp_1_tx_0_n}), + .gtytxp_out({qsfp_0_tx_3_p, qsfp_0_tx_2_p, qsfp_0_tx_1_p, qsfp_0_tx_0_p, qsfp_1_tx_3_p, qsfp_1_tx_2_p, qsfp_1_tx_1_p, qsfp_1_tx_0_p}), + + .rxgearboxslip_in({qsfp_0_gt_rxgearboxslip_3, qsfp_0_gt_rxgearboxslip_2, qsfp_0_gt_rxgearboxslip_1, qsfp_0_gt_rxgearboxslip_0, qsfp_1_gt_rxgearboxslip_3, qsfp_1_gt_rxgearboxslip_2, qsfp_1_gt_rxgearboxslip_1, qsfp_1_gt_rxgearboxslip_0}), + .gtwiz_userdata_rx_out({qsfp_0_gt_rxdata_3, qsfp_0_gt_rxdata_2, qsfp_0_gt_rxdata_1, qsfp_0_gt_rxdata_0, qsfp_1_gt_rxdata_3, qsfp_1_gt_rxdata_2, qsfp_1_gt_rxdata_1, qsfp_1_gt_rxdata_0}), + .rxdatavalid_out({qsfp_0_gt_rxdatavalid_3, qsfp_0_gt_rxdatavalid_2, qsfp_0_gt_rxdatavalid_1, qsfp_0_gt_rxdatavalid_0, qsfp_1_gt_rxdatavalid_3, qsfp_1_gt_rxdatavalid_2, qsfp_1_gt_rxdatavalid_1, qsfp_1_gt_rxdatavalid_0}), + .rxheader_out({qsfp_0_gt_rxheader_3, qsfp_0_gt_rxheader_2, qsfp_0_gt_rxheader_1, qsfp_0_gt_rxheader_0, qsfp_1_gt_rxheader_3, qsfp_1_gt_rxheader_2, qsfp_1_gt_rxheader_1, qsfp_1_gt_rxheader_0}), + .rxheadervalid_out({qsfp_0_gt_rxheadervalid_3, qsfp_0_gt_rxheadervalid_2, qsfp_0_gt_rxheadervalid_1, qsfp_0_gt_rxheadervalid_0, qsfp_1_gt_rxheadervalid_3, qsfp_1_gt_rxheadervalid_2, qsfp_1_gt_rxheadervalid_1, qsfp_1_gt_rxheadervalid_0}), + .rxoutclk_out(gt_rxclkout), + .rxpmaresetdone_out(gt_rxpmaresetdone), + .rxprgdivresetdone_out(gt_rxprgdivresetdone), + .rxstartofseq_out(), + + .txoutclk_out(gt_txclkout), + .txpmaresetdone_out(gt_txpmaresetdone), + .txprgdivresetdone_out(gt_txprgdivresetdone) +); + +assign qsfp_0_tx_clk_0_int = clk_156mhz_int; +assign qsfp_0_tx_rst_0_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_0_int = gt_rxusrclk[4]; + +sync_reset #( + .N(4) +) +qsfp_0_rx_rst_0_reset_sync_inst ( + .clk(qsfp_0_rx_clk_0_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_0_rx_rst_0_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp_0_phy_0_inst ( + .tx_clk(qsfp_0_tx_clk_0_int), + .tx_rst(qsfp_0_tx_rst_0_int), + .rx_clk(qsfp_0_rx_clk_0_int), + .rx_rst(qsfp_0_rx_rst_0_int), + .xgmii_txd(qsfp_0_txd_0_int), + .xgmii_txc(qsfp_0_txc_0_int), + .xgmii_rxd(qsfp_0_rxd_0_int), + .xgmii_rxc(qsfp_0_rxc_0_int), + .serdes_tx_data(qsfp_0_gt_txdata_0), + .serdes_tx_hdr(qsfp_0_gt_txheader_0), + .serdes_rx_data(qsfp_0_gt_rxdata_0), + .serdes_rx_hdr(qsfp_0_gt_rxheader_0), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_0), + .rx_block_lock(qsfp_0_rx_block_lock_0), + .rx_high_ber() +); + +assign qsfp_0_tx_clk_1_int = clk_156mhz_int; +assign qsfp_0_tx_rst_1_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_1_int = gt_rxusrclk[5]; + +sync_reset #( + .N(4) +) +qsfp_0_rx_rst_1_reset_sync_inst ( + .clk(qsfp_0_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_0_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp_0_phy_1_inst ( + .tx_clk(qsfp_0_tx_clk_1_int), + .tx_rst(qsfp_0_tx_rst_1_int), + .rx_clk(qsfp_0_rx_clk_1_int), + .rx_rst(qsfp_0_rx_rst_1_int), + .xgmii_txd(qsfp_0_txd_1_int), + .xgmii_txc(qsfp_0_txc_1_int), + .xgmii_rxd(qsfp_0_rxd_1_int), + .xgmii_rxc(qsfp_0_rxc_1_int), + .serdes_tx_data(qsfp_0_gt_txdata_1), + .serdes_tx_hdr(qsfp_0_gt_txheader_1), + .serdes_rx_data(qsfp_0_gt_rxdata_1), + .serdes_rx_hdr(qsfp_0_gt_rxheader_1), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_1), + .rx_block_lock(qsfp_0_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp_0_tx_clk_2_int = clk_156mhz_int; +assign qsfp_0_tx_rst_2_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_2_int = gt_rxusrclk[6]; + +sync_reset #( + .N(4) +) +qsfp_0_rx_rst_2_reset_sync_inst ( + .clk(qsfp_0_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_0_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp_0_phy_2_inst ( + .tx_clk(qsfp_0_tx_clk_2_int), + .tx_rst(qsfp_0_tx_rst_2_int), + .rx_clk(qsfp_0_rx_clk_2_int), + .rx_rst(qsfp_0_rx_rst_2_int), + .xgmii_txd(qsfp_0_txd_2_int), + .xgmii_txc(qsfp_0_txc_2_int), + .xgmii_rxd(qsfp_0_rxd_2_int), + .xgmii_rxc(qsfp_0_rxc_2_int), + .serdes_tx_data(qsfp_0_gt_txdata_2), + .serdes_tx_hdr(qsfp_0_gt_txheader_2), + .serdes_rx_data(qsfp_0_gt_rxdata_2), + .serdes_rx_hdr(qsfp_0_gt_rxheader_2), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_2), + .rx_block_lock(qsfp_0_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp_0_tx_clk_3_int = clk_156mhz_int; +assign qsfp_0_tx_rst_3_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_3_int = gt_rxusrclk[7]; + +sync_reset #( + .N(4) +) +qsfp_0_rx_rst_3_reset_sync_inst ( + .clk(qsfp_0_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_0_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp_0_phy_3_inst ( + .tx_clk(qsfp_0_tx_clk_3_int), + .tx_rst(qsfp_0_tx_rst_3_int), + .rx_clk(qsfp_0_rx_clk_3_int), + .rx_rst(qsfp_0_rx_rst_3_int), + .xgmii_txd(qsfp_0_txd_3_int), + .xgmii_txc(qsfp_0_txc_3_int), + .xgmii_rxd(qsfp_0_rxd_3_int), + .xgmii_rxc(qsfp_0_rxc_3_int), + .serdes_tx_data(qsfp_0_gt_txdata_3), + .serdes_tx_hdr(qsfp_0_gt_txheader_3), + .serdes_rx_data(qsfp_0_gt_rxdata_3), + .serdes_rx_hdr(qsfp_0_gt_rxheader_3), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_3), + .rx_block_lock(qsfp_0_rx_block_lock_3), + .rx_high_ber() +); + +assign qsfp_1_tx_clk_0_int = clk_156mhz_int; +assign qsfp_1_tx_rst_0_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_0_int = gt_rxusrclk[0]; + +sync_reset #( + .N(4) +) +qsfp_1_rx_rst_0_reset_sync_inst ( + .clk(qsfp_1_rx_clk_0_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_1_rx_rst_0_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp_1_phy_0_inst ( + .tx_clk(qsfp_1_tx_clk_0_int), + .tx_rst(qsfp_1_tx_rst_0_int), + .rx_clk(qsfp_1_rx_clk_0_int), + .rx_rst(qsfp_1_rx_rst_0_int), + .xgmii_txd(qsfp_1_txd_0_int), + .xgmii_txc(qsfp_1_txc_0_int), + .xgmii_rxd(qsfp_1_rxd_0_int), + .xgmii_rxc(qsfp_1_rxc_0_int), + .serdes_tx_data(qsfp_1_gt_txdata_0), + .serdes_tx_hdr(qsfp_1_gt_txheader_0), + .serdes_rx_data(qsfp_1_gt_rxdata_0), + .serdes_rx_hdr(qsfp_1_gt_rxheader_0), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_0), + .rx_block_lock(qsfp_1_rx_block_lock_0), + .rx_high_ber() +); + +assign qsfp_1_tx_clk_1_int = clk_156mhz_int; +assign qsfp_1_tx_rst_1_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_1_int = gt_rxusrclk[1]; + +sync_reset #( + .N(4) +) +qsfp_1_rx_rst_1_reset_sync_inst ( + .clk(qsfp_1_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_1_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp_1_phy_1_inst ( + .tx_clk(qsfp_1_tx_clk_1_int), + .tx_rst(qsfp_1_tx_rst_1_int), + .rx_clk(qsfp_1_rx_clk_1_int), + .rx_rst(qsfp_1_rx_rst_1_int), + .xgmii_txd(qsfp_1_txd_1_int), + .xgmii_txc(qsfp_1_txc_1_int), + .xgmii_rxd(qsfp_1_rxd_1_int), + .xgmii_rxc(qsfp_1_rxc_1_int), + .serdes_tx_data(qsfp_1_gt_txdata_1), + .serdes_tx_hdr(qsfp_1_gt_txheader_1), + .serdes_rx_data(qsfp_1_gt_rxdata_1), + .serdes_rx_hdr(qsfp_1_gt_rxheader_1), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_1), + .rx_block_lock(qsfp_1_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp_1_tx_clk_2_int = clk_156mhz_int; +assign qsfp_1_tx_rst_2_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_2_int = gt_rxusrclk[2]; + +sync_reset #( + .N(4) +) +qsfp_1_rx_rst_2_reset_sync_inst ( + .clk(qsfp_1_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_1_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp_1_phy_2_inst ( + .tx_clk(qsfp_1_tx_clk_2_int), + .tx_rst(qsfp_1_tx_rst_2_int), + .rx_clk(qsfp_1_rx_clk_2_int), + .rx_rst(qsfp_1_rx_rst_2_int), + .xgmii_txd(qsfp_1_txd_2_int), + .xgmii_txc(qsfp_1_txc_2_int), + .xgmii_rxd(qsfp_1_rxd_2_int), + .xgmii_rxc(qsfp_1_rxc_2_int), + .serdes_tx_data(qsfp_1_gt_txdata_2), + .serdes_tx_hdr(qsfp_1_gt_txheader_2), + .serdes_rx_data(qsfp_1_gt_rxdata_2), + .serdes_rx_hdr(qsfp_1_gt_rxheader_2), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_2), + .rx_block_lock(qsfp_1_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp_1_tx_clk_3_int = clk_156mhz_int; +assign qsfp_1_tx_rst_3_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_3_int = gt_rxusrclk[3]; + +sync_reset #( + .N(4) +) +qsfp_1_rx_rst_3_reset_sync_inst ( + .clk(qsfp_1_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp_1_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp_1_phy_3_inst ( + .tx_clk(qsfp_1_tx_clk_3_int), + .tx_rst(qsfp_1_tx_rst_3_int), + .rx_clk(qsfp_1_rx_clk_3_int), + .rx_rst(qsfp_1_rx_rst_3_int), + .xgmii_txd(qsfp_1_txd_3_int), + .xgmii_txc(qsfp_1_txc_3_int), + .xgmii_rxd(qsfp_1_rxd_3_int), + .xgmii_rxc(qsfp_1_rxc_3_int), + .serdes_tx_data(qsfp_1_gt_txdata_3), + .serdes_tx_hdr(qsfp_1_gt_txheader_3), + .serdes_rx_data(qsfp_1_gt_rxdata_3), + .serdes_rx_hdr(qsfp_1_gt_rxheader_3), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_3), + .rx_block_lock(qsfp_1_rx_block_lock_3), + .rx_high_ber() +); + +//assign led = sw[0] ? {qsfp_1_rx_block_lock_4, qsfp_1_rx_block_lock_3, qsfp_1_rx_block_lock_2, qsfp_1_rx_block_lock_1, qsfp_0_rx_block_lock_4, qsfp_0_rx_block_lock_3, qsfp_0_rx_block_lock_2, qsfp_0_rx_block_lock_1} : led_int; +assign front_led = {1'b0, qsfp_0_rx_block_lock_0}; + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + /* + * GPIO + */ + .user_led_g(user_led_g), + .user_led_r(user_led_r), + //.front_led(front_led), + .user_sw(user_sw_int), + + /* + * Ethernet: QSFP28 + */ + .qsfp_0_tx_clk_0(qsfp_0_tx_clk_0_int), + .qsfp_0_tx_rst_0(qsfp_0_tx_rst_0_int), + .qsfp_0_txd_0(qsfp_0_txd_0_int), + .qsfp_0_txc_0(qsfp_0_txc_0_int), + .qsfp_0_rx_clk_0(qsfp_0_rx_clk_0_int), + .qsfp_0_rx_rst_0(qsfp_0_rx_rst_0_int), + .qsfp_0_rxd_0(qsfp_0_rxd_0_int), + .qsfp_0_rxc_0(qsfp_0_rxc_0_int), + .qsfp_0_tx_clk_1(qsfp_0_tx_clk_1_int), + .qsfp_0_tx_rst_1(qsfp_0_tx_rst_1_int), + .qsfp_0_txd_1(qsfp_0_txd_1_int), + .qsfp_0_txc_1(qsfp_0_txc_1_int), + .qsfp_0_rx_clk_1(qsfp_0_rx_clk_1_int), + .qsfp_0_rx_rst_1(qsfp_0_rx_rst_1_int), + .qsfp_0_rxd_1(qsfp_0_rxd_1_int), + .qsfp_0_rxc_1(qsfp_0_rxc_1_int), + .qsfp_0_tx_clk_2(qsfp_0_tx_clk_2_int), + .qsfp_0_tx_rst_2(qsfp_0_tx_rst_2_int), + .qsfp_0_txd_2(qsfp_0_txd_2_int), + .qsfp_0_txc_2(qsfp_0_txc_2_int), + .qsfp_0_rx_clk_2(qsfp_0_rx_clk_2_int), + .qsfp_0_rx_rst_2(qsfp_0_rx_rst_2_int), + .qsfp_0_rxd_2(qsfp_0_rxd_2_int), + .qsfp_0_rxc_2(qsfp_0_rxc_2_int), + .qsfp_0_tx_clk_3(qsfp_0_tx_clk_3_int), + .qsfp_0_tx_rst_3(qsfp_0_tx_rst_3_int), + .qsfp_0_txd_3(qsfp_0_txd_3_int), + .qsfp_0_txc_3(qsfp_0_txc_3_int), + .qsfp_0_rx_clk_3(qsfp_0_rx_clk_3_int), + .qsfp_0_rx_rst_3(qsfp_0_rx_rst_3_int), + .qsfp_0_rxd_3(qsfp_0_rxd_3_int), + .qsfp_0_rxc_3(qsfp_0_rxc_3_int), + .qsfp_1_tx_clk_0(qsfp_1_tx_clk_0_int), + .qsfp_1_tx_rst_0(qsfp_1_tx_rst_0_int), + .qsfp_1_txd_0(qsfp_1_txd_0_int), + .qsfp_1_txc_0(qsfp_1_txc_0_int), + .qsfp_1_rx_clk_0(qsfp_1_rx_clk_0_int), + .qsfp_1_rx_rst_0(qsfp_1_rx_rst_0_int), + .qsfp_1_rxd_0(qsfp_1_rxd_0_int), + .qsfp_1_rxc_0(qsfp_1_rxc_0_int), + .qsfp_1_tx_clk_1(qsfp_1_tx_clk_1_int), + .qsfp_1_tx_rst_1(qsfp_1_tx_rst_1_int), + .qsfp_1_txd_1(qsfp_1_txd_1_int), + .qsfp_1_txc_1(qsfp_1_txc_1_int), + .qsfp_1_rx_clk_1(qsfp_1_rx_clk_1_int), + .qsfp_1_rx_rst_1(qsfp_1_rx_rst_1_int), + .qsfp_1_rxd_1(qsfp_1_rxd_1_int), + .qsfp_1_rxc_1(qsfp_1_rxc_1_int), + .qsfp_1_tx_clk_2(qsfp_1_tx_clk_2_int), + .qsfp_1_tx_rst_2(qsfp_1_tx_rst_2_int), + .qsfp_1_txd_2(qsfp_1_txd_2_int), + .qsfp_1_txc_2(qsfp_1_txc_2_int), + .qsfp_1_rx_clk_2(qsfp_1_rx_clk_2_int), + .qsfp_1_rx_rst_2(qsfp_1_rx_rst_2_int), + .qsfp_1_rxd_2(qsfp_1_rxd_2_int), + .qsfp_1_rxc_2(qsfp_1_rxc_2_int), + .qsfp_1_tx_clk_3(qsfp_1_tx_clk_3_int), + .qsfp_1_tx_rst_3(qsfp_1_tx_rst_3_int), + .qsfp_1_txd_3(qsfp_1_txd_3_int), + .qsfp_1_txc_3(qsfp_1_txc_3_int), + .qsfp_1_rx_clk_3(qsfp_1_rx_clk_3_int), + .qsfp_1_rx_rst_3(qsfp_1_rx_rst_3_int), + .qsfp_1_rxd_3(qsfp_1_rxd_3_int), + .qsfp_1_rxc_3(qsfp_1_rxc_3_int) +); + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v b/example/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v new file mode 100644 index 000000000..93f5ddc41 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v @@ -0,0 +1,659 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + output wire [1:0] user_led_g, + output wire user_led_r, + output wire [1:0] front_led, + input wire [1:0] user_sw, + + /* + * Ethernet: QSFP28 + */ + input wire qsfp_0_tx_clk_0, + input wire qsfp_0_tx_rst_0, + output wire [63:0] qsfp_0_txd_0, + output wire [7:0] qsfp_0_txc_0, + input wire qsfp_0_rx_clk_0, + input wire qsfp_0_rx_rst_0, + input wire [63:0] qsfp_0_rxd_0, + input wire [7:0] qsfp_0_rxc_0, + input wire qsfp_0_tx_clk_1, + input wire qsfp_0_tx_rst_1, + output wire [63:0] qsfp_0_txd_1, + output wire [7:0] qsfp_0_txc_1, + input wire qsfp_0_rx_clk_1, + input wire qsfp_0_rx_rst_1, + input wire [63:0] qsfp_0_rxd_1, + input wire [7:0] qsfp_0_rxc_1, + input wire qsfp_0_tx_clk_2, + input wire qsfp_0_tx_rst_2, + output wire [63:0] qsfp_0_txd_2, + output wire [7:0] qsfp_0_txc_2, + input wire qsfp_0_rx_clk_2, + input wire qsfp_0_rx_rst_2, + input wire [63:0] qsfp_0_rxd_2, + input wire [7:0] qsfp_0_rxc_2, + input wire qsfp_0_tx_clk_3, + input wire qsfp_0_tx_rst_3, + output wire [63:0] qsfp_0_txd_3, + output wire [7:0] qsfp_0_txc_3, + input wire qsfp_0_rx_clk_3, + input wire qsfp_0_rx_rst_3, + input wire [63:0] qsfp_0_rxd_3, + input wire [7:0] qsfp_0_rxc_3, + input wire qsfp_1_tx_clk_0, + input wire qsfp_1_tx_rst_0, + output wire [63:0] qsfp_1_txd_0, + output wire [7:0] qsfp_1_txc_0, + input wire qsfp_1_rx_clk_0, + input wire qsfp_1_rx_rst_0, + input wire [63:0] qsfp_1_rxd_0, + input wire [7:0] qsfp_1_rxc_0, + input wire qsfp_1_tx_clk_1, + input wire qsfp_1_tx_rst_1, + output wire [63:0] qsfp_1_txd_1, + output wire [7:0] qsfp_1_txc_1, + input wire qsfp_1_rx_clk_1, + input wire qsfp_1_rx_rst_1, + input wire [63:0] qsfp_1_rxd_1, + input wire [7:0] qsfp_1_rxc_1, + input wire qsfp_1_tx_clk_2, + input wire qsfp_1_tx_rst_2, + output wire [63:0] qsfp_1_txd_2, + output wire [7:0] qsfp_1_txc_2, + input wire qsfp_1_rx_clk_2, + input wire qsfp_1_rx_rst_2, + input wire [63:0] qsfp_1_rxd_2, + input wire [7:0] qsfp_1_rxc_2, + input wire qsfp_1_tx_clk_3, + input wire qsfp_1_tx_rst_3, + output wire [63:0] qsfp_1_txd_3, + output wire [7:0] qsfp_1_txc_3, + input wire qsfp_1_rx_clk_3, + input wire qsfp_1_rx_rst_3, + input wire [63:0] qsfp_1_rxd_3, + input wire [7:0] qsfp_1_rxc_3 +); + +// AXI between MAC and Ethernet modules +wire [63:0] rx_axis_tdata; +wire [7:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [63:0] tx_axis_tdata; +wire [7:0] tx_axis_tkeep; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [63:0] rx_eth_payload_axis_tdata; +wire [7:0] rx_eth_payload_axis_tkeep; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [63:0] tx_eth_payload_axis_tdata; +wire [7:0] tx_eth_payload_axis_tkeep; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [63:0] rx_ip_payload_axis_tdata; +wire [7:0] rx_ip_payload_axis_tkeep; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [63:0] tx_ip_payload_axis_tdata; +wire [7:0] tx_ip_payload_axis_tkeep; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [63:0] rx_udp_payload_axis_tdata; +wire [7:0] rx_udp_payload_axis_tkeep; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [63:0] tx_udp_payload_axis_tdata; +wire [7:0] tx_udp_payload_axis_tkeep; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; + +wire [63:0] rx_fifo_udp_payload_axis_tdata; +wire [7:0] rx_fifo_udp_payload_axis_tkeep; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; + +wire [63:0] tx_fifo_udp_payload_axis_tdata; +wire [7:0] tx_fifo_udp_payload_axis_tkeep; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_axis_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tkeep = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = !match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; + +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; + +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_axis_tvalid; + if (tx_udp_payload_axis_tvalid && !valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; + end + end +end + +assign user_led_g = ~led_reg[1:0]; +assign user_led_r = 1'b1; +assign front_led = 2'b00; + +assign phy_reset_n = !rst; + +assign qsfp_0_txd_1 = 64'h0707070707070707; +assign qsfp_0_txc_1 = 8'hff; +assign qsfp_0_txd_2 = 64'h0707070707070707; +assign qsfp_0_txc_2 = 8'hff; +assign qsfp_0_txd_3 = 64'h0707070707070707; +assign qsfp_0_txc_3 = 8'hff; + +assign qsfp_1_txd_0 = 64'h0707070707070707; +assign qsfp_1_txc_0 = 8'hff; +assign qsfp_1_txd_1 = 64'h0707070707070707; +assign qsfp_1_txc_1 = 8'hff; +assign qsfp_1_txd_2 = 64'h0707070707070707; +assign qsfp_1_txc_2 = 8'hff; +assign qsfp_1_txd_3 = 64'h0707070707070707; +assign qsfp_1_txc_3 = 8'hff; + +eth_mac_10g_fifo #( + .ENABLE_PADDING(1), + .ENABLE_DIC(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(9), + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(9), + .RX_FRAME_FIFO(1) +) +eth_mac_10g_fifo_inst ( + .rx_clk(qsfp_0_rx_clk_0), + .rx_rst(qsfp_0_rx_rst_0), + .tx_clk(qsfp_0_tx_clk_0), + .tx_rst(qsfp_0_tx_rst_0), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tkeep(tx_axis_tkeep), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tkeep(rx_axis_tkeep), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .xgmii_rxd(qsfp_0_rxd_0), + .xgmii_rxc(qsfp_0_rxc_0), + .xgmii_txd(qsfp_0_txd_0), + .xgmii_txc(qsfp_0_txc_0), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + .ifg_delay(8'd12) +); + +eth_axis_rx_64 +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(rx_axis_tdata), + .s_axis_tkeep(rx_axis_tkeep), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx_64 +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // AXI output + .m_axis_tdata(tx_axis_tdata), + .m_axis_tkeep(tx_axis_tkeep), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete_64 +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // IP frame input + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), + // IP frame output + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), + // UDP frame input + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), + // UDP frame output + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(1'b0) +); + +axis_fifo #( + .ADDR_WIDTH(10), + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(8), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(0) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), + + // AXI output + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() +); + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_25g/rtl/sync_reset.v b/example/ADM_PCIE_9V3/fpga_25g/rtl/sync_reset.v new file mode 100644 index 000000000..acbcf1c6e --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_25g/rtl/sync_signal.v b/example/ADM_PCIE_9V3/fpga_25g/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_25g/tb/arp_ep.py b/example/ADM_PCIE_9V3/fpga_25g/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_25g/tb/axis_ep.py b/example/ADM_PCIE_9V3/fpga_25g/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_25g/tb/eth_ep.py b/example/ADM_PCIE_9V3/fpga_25g/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_25g/tb/ip_ep.py b/example/ADM_PCIE_9V3/fpga_25g/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py b/example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py new file mode 100755 index 000000000..35b21e22b --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py @@ -0,0 +1,462 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016-2018 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 + +import eth_ep +import arp_ep +import udp_ep +import xgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") +srcs.append("../lib/eth/rtl/arp_64.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") +srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + user_sw = Signal(intbv(0)[2:]) + qsfp_0_tx_clk_0 = Signal(bool(0)) + qsfp_0_tx_rst_0 = Signal(bool(0)) + qsfp_0_rx_clk_0 = Signal(bool(0)) + qsfp_0_rx_rst_0 = Signal(bool(0)) + qsfp_0_rxd_0 = Signal(intbv(0)[64:]) + qsfp_0_rxc_0 = Signal(intbv(0)[8:]) + qsfp_0_tx_clk_1 = Signal(bool(0)) + qsfp_0_tx_rst_1 = Signal(bool(0)) + qsfp_0_rx_clk_1 = Signal(bool(0)) + qsfp_0_rx_rst_1 = Signal(bool(0)) + qsfp_0_rxd_1 = Signal(intbv(0)[64:]) + qsfp_0_rxc_1 = Signal(intbv(0)[8:]) + qsfp_0_tx_clk_2 = Signal(bool(0)) + qsfp_0_tx_rst_2 = Signal(bool(0)) + qsfp_0_rx_clk_2 = Signal(bool(0)) + qsfp_0_rx_rst_2 = Signal(bool(0)) + qsfp_0_rxd_2 = Signal(intbv(0)[64:]) + qsfp_0_rxc_2 = Signal(intbv(0)[8:]) + qsfp_0_tx_clk_3 = Signal(bool(0)) + qsfp_0_tx_rst_3 = Signal(bool(0)) + qsfp_0_rx_clk_3 = Signal(bool(0)) + qsfp_0_rx_rst_3 = Signal(bool(0)) + qsfp_0_rxd_3 = Signal(intbv(0)[64:]) + qsfp_0_rxc_3 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_0 = Signal(bool(0)) + qsfp_1_tx_rst_0 = Signal(bool(0)) + qsfp_1_rx_clk_0 = Signal(bool(0)) + qsfp_1_rx_rst_0 = Signal(bool(0)) + qsfp_1_rxd_0 = Signal(intbv(0)[64:]) + qsfp_1_rxc_0 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_1 = Signal(bool(0)) + qsfp_1_tx_rst_1 = Signal(bool(0)) + qsfp_1_rx_clk_1 = Signal(bool(0)) + qsfp_1_rx_rst_1 = Signal(bool(0)) + qsfp_1_rxd_1 = Signal(intbv(0)[64:]) + qsfp_1_rxc_1 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_2 = Signal(bool(0)) + qsfp_1_tx_rst_2 = Signal(bool(0)) + qsfp_1_rx_clk_2 = Signal(bool(0)) + qsfp_1_rx_rst_2 = Signal(bool(0)) + qsfp_1_rxd_2 = Signal(intbv(0)[64:]) + qsfp_1_rxc_2 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_3 = Signal(bool(0)) + qsfp_1_tx_rst_3 = Signal(bool(0)) + qsfp_1_rx_clk_3 = Signal(bool(0)) + qsfp_1_rx_rst_3 = Signal(bool(0)) + qsfp_1_rxd_3 = Signal(intbv(0)[64:]) + qsfp_1_rxc_3 = Signal(intbv(0)[8:]) + + # Outputs + user_led_g = Signal(intbv(0)[2:]) + user_led_r = Signal(bool(0)) + front_led = Signal(intbv(0)[2:]) + qsfp_0_txd_0 = Signal(intbv(0)[64:]) + qsfp_0_txc_0 = Signal(intbv(0)[8:]) + qsfp_0_txd_1 = Signal(intbv(0)[64:]) + qsfp_0_txc_1 = Signal(intbv(0)[8:]) + qsfp_0_txd_2 = Signal(intbv(0)[64:]) + qsfp_0_txc_2 = Signal(intbv(0)[8:]) + qsfp_0_txd_3 = Signal(intbv(0)[64:]) + qsfp_0_txc_3 = Signal(intbv(0)[8:]) + qsfp_1_txd_0 = Signal(intbv(0)[64:]) + qsfp_1_txc_0 = Signal(intbv(0)[8:]) + qsfp_1_txd_1 = Signal(intbv(0)[64:]) + qsfp_1_txc_1 = Signal(intbv(0)[8:]) + qsfp_1_txd_2 = Signal(intbv(0)[64:]) + qsfp_1_txc_2 = Signal(intbv(0)[8:]) + qsfp_1_txd_3 = Signal(intbv(0)[64:]) + qsfp_1_txc_3 = Signal(intbv(0)[8:]) + + # sources and sinks + qsfp_0_0_source = xgmii_ep.XGMIISource() + qsfp_0_0_source_logic = qsfp_0_0_source.create_logic(qsfp_0_rx_clk_0, qsfp_0_rx_rst_0, txd=qsfp_0_rxd_0, txc=qsfp_0_rxc_0, name='qsfp_0_0_source') + + qsfp_0_0_sink = xgmii_ep.XGMIISink() + qsfp_0_0_sink_logic = qsfp_0_0_sink.create_logic(qsfp_0_tx_clk_0, qsfp_0_tx_rst_0, rxd=qsfp_0_txd_0, rxc=qsfp_0_txc_0, name='qsfp_0_0_sink') + + qsfp_0_1_source = xgmii_ep.XGMIISource() + qsfp_0_1_source_logic = qsfp_0_1_source.create_logic(qsfp_0_rx_clk_1, qsfp_0_rx_rst_1, txd=qsfp_0_rxd_1, txc=qsfp_0_rxc_1, name='qsfp_0_1_source') + + qsfp_0_1_sink = xgmii_ep.XGMIISink() + qsfp_0_1_sink_logic = qsfp_0_1_sink.create_logic(qsfp_0_tx_clk_1, qsfp_0_tx_rst_1, rxd=qsfp_0_txd_1, rxc=qsfp_0_txc_1, name='qsfp_0_1_sink') + + qsfp_0_2_source = xgmii_ep.XGMIISource() + qsfp_0_2_source_logic = qsfp_0_2_source.create_logic(qsfp_0_rx_clk_2, qsfp_0_rx_rst_2, txd=qsfp_0_rxd_2, txc=qsfp_0_rxc_2, name='qsfp_0_2_source') + + qsfp_0_2_sink = xgmii_ep.XGMIISink() + qsfp_0_2_sink_logic = qsfp_0_2_sink.create_logic(qsfp_0_tx_clk_2, qsfp_0_tx_rst_2, rxd=qsfp_0_txd_2, rxc=qsfp_0_txc_2, name='qsfp_0_2_sink') + + qsfp_0_3_source = xgmii_ep.XGMIISource() + qsfp_0_3_source_logic = qsfp_0_3_source.create_logic(qsfp_0_rx_clk_3, qsfp_0_rx_rst_3, txd=qsfp_0_rxd_3, txc=qsfp_0_rxc_3, name='qsfp_0_3_source') + + qsfp_0_3_sink = xgmii_ep.XGMIISink() + qsfp_0_3_sink_logic = qsfp_0_3_sink.create_logic(qsfp_0_tx_clk_3, qsfp_0_tx_rst_3, rxd=qsfp_0_txd_3, rxc=qsfp_0_txc_3, name='qsfp_0_3_sink') + + qsfp_1_0_source = xgmii_ep.XGMIISource() + qsfp_1_0_source_logic = qsfp_1_0_source.create_logic(qsfp_1_rx_clk_0, qsfp_1_rx_rst_0, txd=qsfp_1_rxd_0, txc=qsfp_1_rxc_0, name='qsfp_1_0_source') + + qsfp_1_0_sink = xgmii_ep.XGMIISink() + qsfp_1_0_sink_logic = qsfp_1_0_sink.create_logic(qsfp_1_tx_clk_0, qsfp_1_tx_rst_0, rxd=qsfp_1_txd_0, rxc=qsfp_1_txc_0, name='qsfp_1_0_sink') + + qsfp_1_1_source = xgmii_ep.XGMIISource() + qsfp_1_1_source_logic = qsfp_1_1_source.create_logic(qsfp_1_rx_clk_1, qsfp_1_rx_rst_1, txd=qsfp_1_rxd_1, txc=qsfp_1_rxc_1, name='qsfp_1_1_source') + + qsfp_1_1_sink = xgmii_ep.XGMIISink() + qsfp_1_1_sink_logic = qsfp_1_1_sink.create_logic(qsfp_1_tx_clk_1, qsfp_1_tx_rst_1, rxd=qsfp_1_txd_1, rxc=qsfp_1_txc_1, name='qsfp_1_1_sink') + + qsfp_1_2_source = xgmii_ep.XGMIISource() + qsfp_1_2_source_logic = qsfp_1_2_source.create_logic(qsfp_1_rx_clk_2, qsfp_1_rx_rst_2, txd=qsfp_1_rxd_2, txc=qsfp_1_rxc_2, name='qsfp_1_2_source') + + qsfp_1_2_sink = xgmii_ep.XGMIISink() + qsfp_1_2_sink_logic = qsfp_1_2_sink.create_logic(qsfp_1_tx_clk_2, qsfp_1_tx_rst_2, rxd=qsfp_1_txd_2, rxc=qsfp_1_txc_2, name='qsfp_1_2_sink') + + qsfp_1_3_source = xgmii_ep.XGMIISource() + qsfp_1_3_source_logic = qsfp_1_3_source.create_logic(qsfp_1_rx_clk_3, qsfp_1_rx_rst_3, txd=qsfp_1_rxd_3, txc=qsfp_1_rxc_3, name='qsfp_1_3_source') + + qsfp_1_3_sink = xgmii_ep.XGMIISink() + qsfp_1_3_sink_logic = qsfp_1_3_sink.create_logic(qsfp_1_tx_clk_3, qsfp_1_tx_rst_3, rxd=qsfp_1_txd_3, rxc=qsfp_1_txc_3, name='qsfp_1_3_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, + + user_led_g=user_led_g, + user_led_r=user_led_r, + front_led=front_led, + user_sw=user_sw, + + qsfp_0_tx_clk_0=qsfp_0_tx_clk_0, + qsfp_0_tx_rst_0=qsfp_0_tx_rst_0, + qsfp_0_txd_0=qsfp_0_txd_0, + qsfp_0_txc_0=qsfp_0_txc_0, + qsfp_0_rx_clk_0=qsfp_0_rx_clk_0, + qsfp_0_rx_rst_0=qsfp_0_rx_rst_0, + qsfp_0_rxd_0=qsfp_0_rxd_0, + qsfp_0_rxc_0=qsfp_0_rxc_0, + qsfp_0_tx_clk_1=qsfp_0_tx_clk_1, + qsfp_0_tx_rst_1=qsfp_0_tx_rst_1, + qsfp_0_txd_1=qsfp_0_txd_1, + qsfp_0_txc_1=qsfp_0_txc_1, + qsfp_0_rx_clk_1=qsfp_0_rx_clk_1, + qsfp_0_rx_rst_1=qsfp_0_rx_rst_1, + qsfp_0_rxd_1=qsfp_0_rxd_1, + qsfp_0_rxc_1=qsfp_0_rxc_1, + qsfp_0_tx_clk_2=qsfp_0_tx_clk_2, + qsfp_0_tx_rst_2=qsfp_0_tx_rst_2, + qsfp_0_txd_2=qsfp_0_txd_2, + qsfp_0_txc_2=qsfp_0_txc_2, + qsfp_0_rx_clk_2=qsfp_0_rx_clk_2, + qsfp_0_rx_rst_2=qsfp_0_rx_rst_2, + qsfp_0_rxd_2=qsfp_0_rxd_2, + qsfp_0_rxc_2=qsfp_0_rxc_2, + qsfp_0_tx_clk_3=qsfp_0_tx_clk_3, + qsfp_0_tx_rst_3=qsfp_0_tx_rst_3, + qsfp_0_txd_3=qsfp_0_txd_3, + qsfp_0_txc_3=qsfp_0_txc_3, + qsfp_0_rx_clk_3=qsfp_0_rx_clk_3, + qsfp_0_rx_rst_3=qsfp_0_rx_rst_3, + qsfp_0_rxd_3=qsfp_0_rxd_3, + qsfp_0_rxc_3=qsfp_0_rxc_3, + qsfp_1_tx_clk_0=qsfp_1_tx_clk_0, + qsfp_1_tx_rst_0=qsfp_1_tx_rst_0, + qsfp_1_txd_0=qsfp_1_txd_0, + qsfp_1_txc_0=qsfp_1_txc_0, + qsfp_1_rx_clk_0=qsfp_1_rx_clk_0, + qsfp_1_rx_rst_0=qsfp_1_rx_rst_0, + qsfp_1_rxd_0=qsfp_1_rxd_0, + qsfp_1_rxc_0=qsfp_1_rxc_0, + qsfp_1_tx_clk_1=qsfp_1_tx_clk_1, + qsfp_1_tx_rst_1=qsfp_1_tx_rst_1, + qsfp_1_txd_1=qsfp_1_txd_1, + qsfp_1_txc_1=qsfp_1_txc_1, + qsfp_1_rx_clk_1=qsfp_1_rx_clk_1, + qsfp_1_rx_rst_1=qsfp_1_rx_rst_1, + qsfp_1_rxd_1=qsfp_1_rxd_1, + qsfp_1_rxc_1=qsfp_1_rxc_1, + qsfp_1_tx_clk_2=qsfp_1_tx_clk_2, + qsfp_1_tx_rst_2=qsfp_1_tx_rst_2, + qsfp_1_txd_2=qsfp_1_txd_2, + qsfp_1_txc_2=qsfp_1_txc_2, + qsfp_1_rx_clk_2=qsfp_1_rx_clk_2, + qsfp_1_rx_rst_2=qsfp_1_rx_rst_2, + qsfp_1_rxd_2=qsfp_1_rxd_2, + qsfp_1_rxc_2=qsfp_1_rxc_2, + qsfp_1_tx_clk_3=qsfp_1_tx_clk_3, + qsfp_1_tx_rst_3=qsfp_1_tx_rst_3, + qsfp_1_txd_3=qsfp_1_txd_3, + qsfp_1_txc_3=qsfp_1_txc_3, + qsfp_1_rx_clk_3=qsfp_1_rx_clk_3, + qsfp_1_rx_rst_3=qsfp_1_rx_rst_3, + qsfp_1_rxd_3=qsfp_1_rxd_3, + qsfp_1_rxc_3=qsfp_1_rxc_3 + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + qsfp_0_tx_clk_0.next = not qsfp_0_tx_clk_0 + qsfp_0_rx_clk_0.next = not qsfp_0_rx_clk_0 + qsfp_0_tx_clk_1.next = not qsfp_0_tx_clk_1 + qsfp_0_rx_clk_1.next = not qsfp_0_rx_clk_1 + qsfp_0_tx_clk_2.next = not qsfp_0_tx_clk_2 + qsfp_0_rx_clk_2.next = not qsfp_0_rx_clk_2 + qsfp_0_tx_clk_3.next = not qsfp_0_tx_clk_3 + qsfp_0_rx_clk_3.next = not qsfp_0_rx_clk_3 + qsfp_1_tx_clk_0.next = not qsfp_1_tx_clk_0 + qsfp_1_rx_clk_0.next = not qsfp_1_rx_clk_0 + qsfp_1_tx_clk_1.next = not qsfp_1_tx_clk_1 + qsfp_1_rx_clk_1.next = not qsfp_1_rx_clk_1 + qsfp_1_tx_clk_2.next = not qsfp_1_tx_clk_2 + qsfp_1_rx_clk_2.next = not qsfp_1_rx_clk_2 + qsfp_1_tx_clk_3.next = not qsfp_1_tx_clk_3 + qsfp_1_rx_clk_3.next = not qsfp_1_rx_clk_3 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + qsfp_0_tx_rst_1.next = 1 + qsfp_0_rx_rst_1.next = 1 + qsfp_0_tx_rst_2.next = 1 + qsfp_0_rx_rst_2.next = 1 + qsfp_0_tx_rst_3.next = 1 + qsfp_0_rx_rst_3.next = 1 + qsfp_0_tx_rst_0.next = 1 + qsfp_0_rx_rst_0.next = 1 + qsfp_1_tx_rst_1.next = 1 + qsfp_1_rx_rst_1.next = 1 + qsfp_1_tx_rst_2.next = 1 + qsfp_1_rx_rst_2.next = 1 + qsfp_1_tx_rst_3.next = 1 + qsfp_1_rx_rst_3.next = 1 + qsfp_1_tx_rst_0.next = 1 + qsfp_1_rx_rst_0.next = 1 + yield clk.posedge + rst.next = 0 + qsfp_0_tx_rst_1.next = 0 + qsfp_0_rx_rst_1.next = 0 + qsfp_0_tx_rst_2.next = 0 + qsfp_0_rx_rst_2.next = 0 + qsfp_0_tx_rst_3.next = 0 + qsfp_0_rx_rst_3.next = 0 + qsfp_0_tx_rst_0.next = 0 + qsfp_0_rx_rst_0.next = 0 + qsfp_1_tx_rst_1.next = 0 + qsfp_1_rx_rst_1.next = 0 + qsfp_1_tx_rst_2.next = 0 + qsfp_1_rx_rst_2.next = 0 + qsfp_1_tx_rst_3.next = 0 + qsfp_1_rx_rst_3.next = 0 + qsfp_1_tx_rst_0.next = 0 + qsfp_1_rx_rst_0.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while qsfp_0_0_sink.empty(): + yield clk.posedge + + rx_frame = qsfp_0_0_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while qsfp_0_0_sink.empty(): + yield clk.posedge + + rx_frame = qsfp_0_0_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert qsfp_0_0_source.empty() + assert qsfp_0_0_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() diff --git a/example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.v b/example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.v new file mode 100644 index 000000000..003072a91 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.v @@ -0,0 +1,269 @@ +/* + +Copyright (c) 2016-2018 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [1:0] user_sw = 0; +reg qsfp_0_tx_clk_0 = 0; +reg qsfp_0_tx_rst_0 = 0; +reg qsfp_0_rx_clk_0 = 0; +reg qsfp_0_rx_rst_0 = 0; +reg [63:0] qsfp_0_rxd_0 = 0; +reg [7:0] qsfp_0_rxc_0 = 0; +reg qsfp_0_tx_clk_1 = 0; +reg qsfp_0_tx_rst_1 = 0; +reg qsfp_0_rx_clk_1 = 0; +reg qsfp_0_rx_rst_1 = 0; +reg [63:0] qsfp_0_rxd_1 = 0; +reg [7:0] qsfp_0_rxc_1 = 0; +reg qsfp_0_tx_clk_2 = 0; +reg qsfp_0_tx_rst_2 = 0; +reg qsfp_0_rx_clk_2 = 0; +reg qsfp_0_rx_rst_2 = 0; +reg [63:0] qsfp_0_rxd_2 = 0; +reg [7:0] qsfp_0_rxc_2 = 0; +reg qsfp_0_tx_clk_3 = 0; +reg qsfp_0_tx_rst_3 = 0; +reg qsfp_0_rx_clk_3 = 0; +reg qsfp_0_rx_rst_3 = 0; +reg [63:0] qsfp_0_rxd_3 = 0; +reg [7:0] qsfp_0_rxc_3 = 0; +reg qsfp_1_tx_clk_0 = 0; +reg qsfp_1_tx_rst_0 = 0; +reg qsfp_1_rx_clk_0 = 0; +reg qsfp_1_rx_rst_0 = 0; +reg [63:0] qsfp_1_rxd_0 = 0; +reg [7:0] qsfp_1_rxc_0 = 0; +reg qsfp_1_tx_clk_1 = 0; +reg qsfp_1_tx_rst_1 = 0; +reg qsfp_1_rx_clk_1 = 0; +reg qsfp_1_rx_rst_1 = 0; +reg [63:0] qsfp_1_rxd_1 = 0; +reg [7:0] qsfp_1_rxc_1 = 0; +reg qsfp_1_tx_clk_2 = 0; +reg qsfp_1_tx_rst_2 = 0; +reg qsfp_1_rx_clk_2 = 0; +reg qsfp_1_rx_rst_2 = 0; +reg [63:0] qsfp_1_rxd_2 = 0; +reg [7:0] qsfp_1_rxc_2 = 0; +reg qsfp_1_tx_clk_3 = 0; +reg qsfp_1_tx_rst_3 = 0; +reg qsfp_1_rx_clk_3 = 0; +reg qsfp_1_rx_rst_3 = 0; +reg [63:0] qsfp_1_rxd_3 = 0; +reg [7:0] qsfp_1_rxc_3 = 0; + +// Outputs +wire [1:0] user_led_g; +wire user_led_r; +wire [1:0] front_led; +wire [63:0] qsfp_0_txd_0; +wire [7:0] qsfp_0_txc_0; +wire [63:0] qsfp_0_txd_1; +wire [7:0] qsfp_0_txc_1; +wire [63:0] qsfp_0_txd_2; +wire [7:0] qsfp_0_txc_2; +wire [63:0] qsfp_0_txd_3; +wire [7:0] qsfp_0_txc_3; +wire [63:0] qsfp_1_txd_0; +wire [7:0] qsfp_1_txc_0; +wire [63:0] qsfp_1_txd_1; +wire [7:0] qsfp_1_txc_1; +wire [63:0] qsfp_1_txd_2; +wire [7:0] qsfp_1_txc_2; +wire [63:0] qsfp_1_txd_3; +wire [7:0] qsfp_1_txc_3; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + user_sw, + qsfp_0_tx_clk_0, + qsfp_0_tx_rst_0, + qsfp_0_rx_clk_0, + qsfp_0_rx_rst_0, + qsfp_0_rxd_0, + qsfp_0_rxc_0, + qsfp_0_tx_clk_1, + qsfp_0_tx_rst_1, + qsfp_0_rx_clk_1, + qsfp_0_rx_rst_1, + qsfp_0_rxd_1, + qsfp_0_rxc_1, + qsfp_0_tx_clk_2, + qsfp_0_tx_rst_2, + qsfp_0_rx_clk_2, + qsfp_0_rx_rst_2, + qsfp_0_rxd_2, + qsfp_0_rxc_2, + qsfp_0_tx_clk_3, + qsfp_0_tx_rst_3, + qsfp_0_rx_clk_3, + qsfp_0_rx_rst_3, + qsfp_0_rxd_3, + qsfp_0_rxc_3, + qsfp_1_tx_clk_0, + qsfp_1_tx_rst_0, + qsfp_1_rx_clk_0, + qsfp_1_rx_rst_0, + qsfp_1_rxd_0, + qsfp_1_rxc_0, + qsfp_1_tx_clk_1, + qsfp_1_tx_rst_1, + qsfp_1_rx_clk_1, + qsfp_1_rx_rst_1, + qsfp_1_rxd_1, + qsfp_1_rxc_1, + qsfp_1_tx_clk_2, + qsfp_1_tx_rst_2, + qsfp_1_rx_clk_2, + qsfp_1_rx_rst_2, + qsfp_1_rxd_2, + qsfp_1_rxc_2, + qsfp_1_tx_clk_3, + qsfp_1_tx_rst_3, + qsfp_1_rx_clk_3, + qsfp_1_rx_rst_3, + qsfp_1_rxd_3, + qsfp_1_rxc_3 + ); + $to_myhdl( + user_led_g, + user_led_r, + front_led, + qsfp_0_txd_0, + qsfp_0_txc_0, + qsfp_0_txd_1, + qsfp_0_txc_1, + qsfp_0_txd_2, + qsfp_0_txc_2, + qsfp_0_txd_3, + qsfp_0_txc_3, + qsfp_1_txd_0, + qsfp_1_txc_0, + qsfp_1_txd_1, + qsfp_1_txc_1, + qsfp_1_txd_2, + qsfp_1_txc_2, + qsfp_1_txd_3, + qsfp_1_txc_3 + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .user_led_g(user_led_g), + .user_led_r(user_led_r), + .front_led(front_led), + .user_sw(user_sw), + .qsfp_0_tx_clk_0(qsfp_0_tx_clk_0), + .qsfp_0_tx_rst_0(qsfp_0_tx_rst_0), + .qsfp_0_txd_0(qsfp_0_txd_0), + .qsfp_0_txc_0(qsfp_0_txc_0), + .qsfp_0_rx_clk_0(qsfp_0_rx_clk_0), + .qsfp_0_rx_rst_0(qsfp_0_rx_rst_0), + .qsfp_0_rxd_0(qsfp_0_rxd_0), + .qsfp_0_rxc_0(qsfp_0_rxc_0), + .qsfp_0_tx_clk_1(qsfp_0_tx_clk_1), + .qsfp_0_tx_rst_1(qsfp_0_tx_rst_1), + .qsfp_0_txd_1(qsfp_0_txd_1), + .qsfp_0_txc_1(qsfp_0_txc_1), + .qsfp_0_rx_clk_1(qsfp_0_rx_clk_1), + .qsfp_0_rx_rst_1(qsfp_0_rx_rst_1), + .qsfp_0_rxd_1(qsfp_0_rxd_1), + .qsfp_0_rxc_1(qsfp_0_rxc_1), + .qsfp_0_tx_clk_2(qsfp_0_tx_clk_2), + .qsfp_0_tx_rst_2(qsfp_0_tx_rst_2), + .qsfp_0_txd_2(qsfp_0_txd_2), + .qsfp_0_txc_2(qsfp_0_txc_2), + .qsfp_0_rx_clk_2(qsfp_0_rx_clk_2), + .qsfp_0_rx_rst_2(qsfp_0_rx_rst_2), + .qsfp_0_rxd_2(qsfp_0_rxd_2), + .qsfp_0_rxc_2(qsfp_0_rxc_2), + .qsfp_0_tx_clk_3(qsfp_0_tx_clk_3), + .qsfp_0_tx_rst_3(qsfp_0_tx_rst_3), + .qsfp_0_txd_3(qsfp_0_txd_3), + .qsfp_0_txc_3(qsfp_0_txc_3), + .qsfp_0_rx_clk_3(qsfp_0_rx_clk_3), + .qsfp_0_rx_rst_3(qsfp_0_rx_rst_3), + .qsfp_0_rxd_3(qsfp_0_rxd_3), + .qsfp_0_rxc_3(qsfp_0_rxc_3), + .qsfp_1_tx_clk_0(qsfp_1_tx_clk_0), + .qsfp_1_tx_rst_0(qsfp_1_tx_rst_0), + .qsfp_1_txd_0(qsfp_1_txd_0), + .qsfp_1_txc_0(qsfp_1_txc_0), + .qsfp_1_rx_clk_0(qsfp_1_rx_clk_0), + .qsfp_1_rx_rst_0(qsfp_1_rx_rst_0), + .qsfp_1_rxd_0(qsfp_1_rxd_0), + .qsfp_1_rxc_0(qsfp_1_rxc_0), + .qsfp_1_tx_clk_1(qsfp_1_tx_clk_1), + .qsfp_1_tx_rst_1(qsfp_1_tx_rst_1), + .qsfp_1_txd_1(qsfp_1_txd_1), + .qsfp_1_txc_1(qsfp_1_txc_1), + .qsfp_1_rx_clk_1(qsfp_1_rx_clk_1), + .qsfp_1_rx_rst_1(qsfp_1_rx_rst_1), + .qsfp_1_rxd_1(qsfp_1_rxd_1), + .qsfp_1_rxc_1(qsfp_1_rxc_1), + .qsfp_1_tx_clk_2(qsfp_1_tx_clk_2), + .qsfp_1_tx_rst_2(qsfp_1_tx_rst_2), + .qsfp_1_txd_2(qsfp_1_txd_2), + .qsfp_1_txc_2(qsfp_1_txc_2), + .qsfp_1_rx_clk_2(qsfp_1_rx_clk_2), + .qsfp_1_rx_rst_2(qsfp_1_rx_rst_2), + .qsfp_1_rxd_2(qsfp_1_rxd_2), + .qsfp_1_rxc_2(qsfp_1_rxc_2), + .qsfp_1_tx_clk_3(qsfp_1_tx_clk_3), + .qsfp_1_tx_rst_3(qsfp_1_tx_rst_3), + .qsfp_1_txd_3(qsfp_1_txd_3), + .qsfp_1_txc_3(qsfp_1_txc_3), + .qsfp_1_rx_clk_3(qsfp_1_rx_clk_3), + .qsfp_1_rx_rst_3(qsfp_1_rx_rst_3), + .qsfp_1_rxd_3(qsfp_1_rxd_3), + .qsfp_1_rxc_3(qsfp_1_rxc_3) +); + +endmodule diff --git a/example/ADM_PCIE_9V3/fpga_25g/tb/udp_ep.py b/example/ADM_PCIE_9V3/fpga_25g/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_25g/tb/xgmii_ep.py b/example/ADM_PCIE_9V3/fpga_25g/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_25g/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file From 1eb9c39ed3bf9c448d399685afe7ce059ee6ea4c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Jun 2019 23:25:06 -0700 Subject: [PATCH 598/617] Add VCU118 25G example design --- example/VCU118/fpga_25g/Makefile | 25 + example/VCU118/fpga_25g/README.md | 33 + example/VCU118/fpga_25g/common/vivado.mk | 118 ++ example/VCU118/fpga_25g/fpga.xdc | 147 ++ example/VCU118/fpga_25g/fpga/Makefile | 78 + .../fpga_25g/ip/gig_ethernet_pcs_pma_0.xci | 365 +++++ .../fpga_25g/ip/gtwizard_ultrascale_0.xci | 1415 +++++++++++++++++ example/VCU118/fpga_25g/lib/eth | 1 + example/VCU118/fpga_25g/rtl/debounce_switch.v | 89 ++ example/VCU118/fpga_25g/rtl/fpga.v | 1314 +++++++++++++++ example/VCU118/fpga_25g/rtl/fpga_core.v | 908 +++++++++++ example/VCU118/fpga_25g/rtl/mdio_master.v | 225 +++ example/VCU118/fpga_25g/rtl/sync_reset.v | 52 + example/VCU118/fpga_25g/rtl/sync_signal.v | 58 + example/VCU118/fpga_25g/tb/arp_ep.py | 1 + example/VCU118/fpga_25g/tb/axis_ep.py | 1 + example/VCU118/fpga_25g/tb/eth_ep.py | 1 + example/VCU118/fpga_25g/tb/gmii_ep.py | 1 + example/VCU118/fpga_25g/tb/ip_ep.py | 1 + example/VCU118/fpga_25g/tb/test_fpga_core.py | 689 ++++++++ example/VCU118/fpga_25g/tb/test_fpga_core.v | 324 ++++ example/VCU118/fpga_25g/tb/udp_ep.py | 1 + example/VCU118/fpga_25g/tb/xgmii_ep.py | 1 + 23 files changed, 5848 insertions(+) create mode 100644 example/VCU118/fpga_25g/Makefile create mode 100644 example/VCU118/fpga_25g/README.md create mode 100644 example/VCU118/fpga_25g/common/vivado.mk create mode 100644 example/VCU118/fpga_25g/fpga.xdc create mode 100644 example/VCU118/fpga_25g/fpga/Makefile create mode 100644 example/VCU118/fpga_25g/ip/gig_ethernet_pcs_pma_0.xci create mode 100644 example/VCU118/fpga_25g/ip/gtwizard_ultrascale_0.xci create mode 120000 example/VCU118/fpga_25g/lib/eth create mode 100644 example/VCU118/fpga_25g/rtl/debounce_switch.v create mode 100644 example/VCU118/fpga_25g/rtl/fpga.v create mode 100644 example/VCU118/fpga_25g/rtl/fpga_core.v create mode 100644 example/VCU118/fpga_25g/rtl/mdio_master.v create mode 100644 example/VCU118/fpga_25g/rtl/sync_reset.v create mode 100644 example/VCU118/fpga_25g/rtl/sync_signal.v create mode 120000 example/VCU118/fpga_25g/tb/arp_ep.py create mode 120000 example/VCU118/fpga_25g/tb/axis_ep.py create mode 120000 example/VCU118/fpga_25g/tb/eth_ep.py create mode 120000 example/VCU118/fpga_25g/tb/gmii_ep.py create mode 120000 example/VCU118/fpga_25g/tb/ip_ep.py create mode 100755 example/VCU118/fpga_25g/tb/test_fpga_core.py create mode 100644 example/VCU118/fpga_25g/tb/test_fpga_core.v create mode 120000 example/VCU118/fpga_25g/tb/udp_ep.py create mode 120000 example/VCU118/fpga_25g/tb/xgmii_ep.py diff --git a/example/VCU118/fpga_25g/Makefile b/example/VCU118/fpga_25g/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/example/VCU118/fpga_25g/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = fpga +SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) + +# Rules +.PHONY: all +all: $(SUBDIRS) $(TARGETS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + cd $@ && $(MAKE) + +.PHONY: $(SUBDIRS_CLEAN) +$(SUBDIRS_CLEAN): + cd $(@:.clean=) && $(MAKE) clean + +.PHONY: clean +clean: $(SUBDIRS_CLEAN) + -rm -rf $(TARGETS) + +program: + #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit diff --git a/example/VCU118/fpga_25g/README.md b/example/VCU118/fpga_25g/README.md new file mode 100644 index 000000000..4e2fb8698 --- /dev/null +++ b/example/VCU118/fpga_25g/README.md @@ -0,0 +1,33 @@ +# Verilog Ethernet VCU118 Example Design + +## Introduction + +This example design targets the Xilinx VCU118 FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. The design also enables the gigabit Ethernet interface for +testing with a QSFP loopback adapter. + +FPGA: xcvu9p-flga2104-2L-e +PHY: 25G BASE-R PHY IP core and internal GTY transceiver + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the VCU118 board with Vivado. Then run +netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any text +entered into netcat will be echoed back after pressing enter. + +Note that the gigabit PHY is also enabled for debugging. The gigabit port can +be inserted into the 10G data path between the 10G MAC and 10G PHY so that the +10G interface can be tested with a QSFP loopback adapter. Turn on SW12.1 to +insert the gigabit port into the 10G data path, or off to bypass the gigabit +port. Turn on SW12.2 to place the port in the TX path or off to place the +port in the RX path. + + diff --git a/example/VCU118/fpga_25g/common/vivado.mk b/example/VCU118/fpga_25g/common/vivado.mk new file mode 100644 index 000000000..a54b530f6 --- /dev/null +++ b/example/VCU118/fpga_25g/common/vivado.mk @@ -0,0 +1,118 @@ +################################################################### +# +# Xilinx Vivado FPGA Makefile +# +# Copyright (c) 2016 Alex Forencich +# +################################################################### +# +# Parameters: +# FPGA_TOP - Top module name +# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) +# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) +# SYN_FILES - space-separated list of source files +# INC_FILES - space-separated list of include files +# XDC_FILES - space-separated list of timing constraint files +# XCI_FILES - space-separated list of IP XCI files +# +# Example: +# +# FPGA_TOP = fpga +# FPGA_FAMILY = VirtexUltrascale +# FPGA_DEVICE = xcvu095-ffva2104-2-e +# SYN_FILES = rtl/fpga.v +# XDC_FILES = fpga.xdc +# XCI_FILES = ip/pcspma.xci +# include ../common/vivado.mk +# +################################################################### + +# phony targets +.PHONY: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +tmpclean: + -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: Makefile $(XCI_FILES_REL) + rm -rf defines.v + touch defines.v + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/VCU118/fpga_25g/fpga.xdc b/example/VCU118/fpga_25g/fpga.xdc new file mode 100644 index 000000000..6267607c6 --- /dev/null +++ b/example/VCU118/fpga_25g/fpga.xdc @@ -0,0 +1,147 @@ +# XDC constraints for the Xilinx VCU118 board +# part: xcvu9p-flga2104-2L-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] + +# System clocks +# 300 MHz +#set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_p] +#set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_n] +#create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p] + +# 250 MHz +#set_property -dict {LOC E12 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_1_p] +#set_property -dict {LOC D12 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_1_n] +#create_clock -period 4 -name clk_250mhz_1 [get_ports clk_250mhz_1_p] + +#set_property -dict {LOC AW26 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_2_p] +#set_property -dict {LOC AW27 IOSTANDARD DIFF_SSTL12} [get_ports clk_250mhz_2_n] +#create_clock -period 4 -name clk_250mhz_2 [get_ports clk_250mhz_2_p] + +# 125 MHz +set_property -dict {LOC AY24 IOSTANDARD LVDS} [get_ports clk_125mhz_p] +set_property -dict {LOC AY23 IOSTANDARD LVDS} [get_ports clk_125mhz_n] +create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] + +# 90 MHz +#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] +#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] + +# LEDs +set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] +set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}] +set_property -dict {LOC AY30 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}] +set_property -dict {LOC BB32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[3]}] +set_property -dict {LOC BF32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[4]}] +set_property -dict {LOC AU37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[5]}] +set_property -dict {LOC AV36 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[6]}] +set_property -dict {LOC BA37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[7]}] + +# Reset button +set_property -dict {LOC L19 IOSTANDARD LVCMOS12} [get_ports reset] + +# Push buttons +set_property -dict {LOC BB24 IOSTANDARD LVCMOS18} [get_ports btnu] +set_property -dict {LOC BF22 IOSTANDARD LVCMOS18} [get_ports btnl] +set_property -dict {LOC BE22 IOSTANDARD LVCMOS18} [get_ports btnd] +set_property -dict {LOC BE23 IOSTANDARD LVCMOS18} [get_ports btnr] +set_property -dict {LOC BD23 IOSTANDARD LVCMOS18} [get_ports btnc] + +# DIP switches +set_property -dict {LOC B17 IOSTANDARD LVCMOS12} [get_ports {sw[0]}] +set_property -dict {LOC G16 IOSTANDARD LVCMOS12} [get_ports {sw[1]}] +set_property -dict {LOC J16 IOSTANDARD LVCMOS12} [get_ports {sw[2]}] +set_property -dict {LOC D21 IOSTANDARD LVCMOS12} [get_ports {sw[3]}] + +# UART +set_property -dict {LOC BB21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] +set_property -dict {LOC AW25 IOSTANDARD LVCMOS18} [get_ports uart_rxd] +set_property -dict {LOC BB22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_rts] +set_property -dict {LOC AY25 IOSTANDARD LVCMOS18} [get_ports uart_cts] + +# Gigabit Ethernet SGMII PHY +set_property -dict {LOC AU24 IOSTANDARD LVDS} [get_ports phy_sgmii_rx_p] +set_property -dict {LOC AV24 IOSTANDARD LVDS} [get_ports phy_sgmii_rx_n] +set_property -dict {LOC AU21 IOSTANDARD LVDS} [get_ports phy_sgmii_tx_p] +set_property -dict {LOC AV21 IOSTANDARD LVDS} [get_ports phy_sgmii_tx_n] +set_property -dict {LOC AT22 IOSTANDARD LVDS} [get_ports phy_sgmii_clk_p] +set_property -dict {LOC AU22 IOSTANDARD LVDS} [get_ports phy_sgmii_clk_n] +set_property -dict {LOC BA21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_reset_n] +set_property -dict {LOC AR24 IOSTANDARD LVCMOS18} [get_ports phy_int_n] +set_property -dict {LOC AR23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdio] +set_property -dict {LOC AV23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc] + +# 625 MHz ref clock from SGMII PHY +#create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p] + +# QSFP28 Interfaces +set_property -dict {LOC V7 } [get_ports qsfp1_tx1_p] ;# MGTYTXN0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC V6 } [get_ports qsfp1_tx1_n] ;# MGTYTXP0_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC Y2 } [get_ports qsfp1_rx1_p] ;# MGTYTXN1_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC Y1 } [get_ports qsfp1_rx1_n] ;# MGTYTXP1_231 GTYE3_CHANNEL_X1Y48 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC T7 } [get_ports qsfp1_tx2_p] ;# MGTYTXN2_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXP2_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC W4 } [get_ports qsfp1_rx2_p] ;# MGTYTXN3_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC W3 } [get_ports qsfp1_rx2_n] ;# MGTYTXP3_231 GTYE3_CHANNEL_X1Y49 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC P7 } [get_ports qsfp1_tx3_p] ;# MGTYTXN0_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC P6 } [get_ports qsfp1_tx3_n] ;# MGTYTXP0_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC V2 } [get_ports qsfp1_rx3_p] ;# MGTYTXN1_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC V1 } [get_ports qsfp1_rx3_n] ;# MGTYTXP1_231 GTYE3_CHANNEL_X1Y50 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC M7 } [get_ports qsfp1_tx4_p] ;# MGTYTXN2_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC M6 } [get_ports qsfp1_tx4_n] ;# MGTYTXP2_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC U4 } [get_ports qsfp1_rx4_p] ;# MGTYTXN3_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +#set_property -dict {LOC U3 } [get_ports qsfp1_rx4_n] ;# MGTYTXP3_231 GTYE3_CHANNEL_X1Y51 / GTYE3_COMMON_X1Y12 +set_property -dict {LOC W9 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_231 from U38.4 +#set_property -dict {LOC W8 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_231 from U38.5 +#set_property -dict {LOC U9 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_231 from U57.28 +#set_property -dict {LOC U8 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U57.29 +#set_property -dict {LOC AM23 IOSTANDARD LVDS} [get_ports qsfp1_recclk_p] ;# to U57.16 +#set_property -dict {LOC AM22 IOSTANDARD LVDS} [get_ports qsfp1_recclk_n] ;# to U57.17 +set_property -dict {LOC AM21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modsell] +set_property -dict {LOC BA22 IOSTANDARD LVCMOS18} [get_ports qsfp1_resetl] +set_property -dict {LOC AL21 IOSTANDARD LVCMOS18} [get_ports qsfp1_modprsl] +set_property -dict {LOC AP21 IOSTANDARD LVCMOS18} [get_ports qsfp1_intl] +set_property -dict {LOC AN21 IOSTANDARD LVCMOS18} [get_ports qsfp1_lpmode] + +# 156.25 MHz MGT reference clock +create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p] + +set_property -dict {LOC L5 } [get_ports qsfp2_tx1_p] ;# MGTYTXN0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC L4 } [get_ports qsfp2_tx1_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC T2 } [get_ports qsfp2_rx1_p] ;# MGTYTXN1_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC T1 } [get_ports qsfp2_rx1_n] ;# MGTYTXP1_232 GTYE3_CHANNEL_X1Y52 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC K7 } [get_ports qsfp2_tx2_p] ;# MGTYTXN2_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC K6 } [get_ports qsfp2_tx2_n] ;# MGTYTXP2_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC R4 } [get_ports qsfp2_rx2_p] ;# MGTYTXN3_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC R3 } [get_ports qsfp2_rx2_n] ;# MGTYTXP3_232 GTYE3_CHANNEL_X1Y53 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC J5 } [get_ports qsfp2_tx3_p] ;# MGTYTXN0_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC J4 } [get_ports qsfp2_tx3_n] ;# MGTYTXP0_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC P2 } [get_ports qsfp2_rx3_p] ;# MGTYTXN1_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC P1 } [get_ports qsfp2_rx3_n] ;# MGTYTXP1_232 GTYE3_CHANNEL_X1Y54 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC H7 } [get_ports qsfp2_tx4_p] ;# MGTYTXN2_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC H6 } [get_ports qsfp2_tx4_n] ;# MGTYTXP2_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +set_property -dict {LOC M2 } [get_ports qsfp2_rx4_p] ;# MGTYTXN3_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC M1 } [get_ports qsfp2_rx4_n] ;# MGTYTXP3_232 GTYE3_CHANNEL_X1Y55 / GTYE3_COMMON_X1Y13 +#set_property -dict {LOC R9 } [get_ports qsfp2_mgt_refclk_0_p] ;# MGTREFCLK0P_232 from U104.13 +#set_property -dict {LOC R8 } [get_ports qsfp2_mgt_refclk_0_n] ;# MGTREFCLK0N_232 from U104.14 +#set_property -dict {LOC N9 } [get_ports qsfp2_mgt_refclk_1_p] ;# MGTREFCLK1P_232 from U57.35 +#set_property -dict {LOC N8 } [get_ports qsfp2_mgt_refclk_1_n] ;# MGTREFCLK1N_232 from U57.34 +#set_property -dict {LOC AP23 IOSTANDARD LVDS} [get_ports qsfp2_recclk_p] ;# to U57.12 +#set_property -dict {LOC AP22 IOSTANDARD LVDS} [get_ports qsfp2_recclk_n] ;# to U57.13 +set_property -dict {LOC AN23 IOSTANDARD LVCMOS18} [get_ports qsfp2_modsell] +set_property -dict {LOC AY22 IOSTANDARD LVCMOS18} [get_ports qsfp2_resetl] +set_property -dict {LOC AN24 IOSTANDARD LVCMOS18} [get_ports qsfp2_modprsl] +set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports qsfp2_intl] +set_property -dict {LOC AT24 IOSTANDARD LVCMOS18} [get_ports qsfp2_lpmode] + +# 156.25 MHz MGT reference clock +#create_clock -period 6.400 -name qsfp2_mgt_refclk_0 [get_ports qsfp2_mgt_refclk_0_p] + +# I2C interface +set_property -dict {LOC AM24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_scl] +set_property -dict {LOC AL24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_sda] + + diff --git a/example/VCU118/fpga_25g/fpga/Makefile b/example/VCU118/fpga_25g/fpga/Makefile new file mode 100644 index 000000000..7b00eb4ad --- /dev/null +++ b/example/VCU118/fpga_25g/fpga/Makefile @@ -0,0 +1,78 @@ + +# FPGA settings +FPGA_PART = xcvu9p-flga2104-2L-e +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/mdio_master.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/eth_phy_10g.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v +SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v +SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp_64.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v +SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_adapter.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_switch.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_register.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl + +# IP +XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci +XCI_FILES += ip/gtwizard_ultrascale_0.xci + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl + echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "exit" >> program.tcl + vivado -mode batch -source program.tcl + diff --git a/example/VCU118/fpga_25g/ip/gig_ethernet_pcs_pma_0.xci b/example/VCU118/fpga_25g/ip/gig_ethernet_pcs_pma_0.xci new file mode 100644 index 000000000..1e578e860 --- /dev/null +++ b/example/VCU118/fpga_25g/ip/gig_ethernet_pcs_pma_0.xci @@ -0,0 +1,365 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gig_ethernet_pcs_pma_0 + + + 1 + 1 + 1 + 1 + + + + 0 + + + + 0 + + + 0 + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + false + false + false + false + 0 + + + + 0 + + + + 0 + false + 100000000 + + + + 0 + + + + 0 + + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + + + 100000000 + 0 + 0.000 + false + false + false + false + 0 + 0 + + + + 100000000 + 0 + 0.000 + + + + 100000000 + 0 + 0.000 + false + false + false + + + + 100000000 + 0 + 0.000 + 0 + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + ACTIVE_LOW + ACTIVE_LOW + ACTIVE_LOW + ACTIVE_LOW + 1 + 0 + 0 + 0 + + 1 + 100000000 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 0.000 + AXI4LITE + READ_WRITE + 0 + 0 + 0 + 0 + 0 + + + 100000000 + 0 + 0.000 + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + true + 0 + 0 + true + false + DIFF_PAIR_0 + DIFF_PAIR_1 + false + DIFF_PAIR_2 + DIFF_PAIR_1 + virtexuplus + 0 + gig_ethernet_pcs_pma_0 + 50.0 + false + . + true + false + false + true + virtexuplus + 16 + 10 + X0Y4 + 8 + 5 + GTH + false + true + false + false + false + false + true + 1 + clk0 + 125 + TXOUTCLK + true + false + gig_ethernet_pcs_pma_0_gt + true + GTHE4 + false + 0 + true + false + false + xcvu9p + false + 1 + false + true + Sync + gig_ethernet_pcs_pma_0 + Custom + 50.0 + TEMAC + Custom + 0 + false + false + false + false + X0Y4 + GTH + false + false + 625 + Custom + false + 1G + 1 + LVDS + 125 + clk0 + TXOUTCLK + DIFF_PAIR_0 + DIFF_PAIR_1 + false + 10_100_1000 + false + SGMII + Include_Shared_Logic_in_Core + Time_of_day + false + DIFF_PAIR_2 + DIFF_PAIR_1 + 0 + false + virtexuplus + + + xcvu9p + flga2104 + VERILOG + + MIXED + -2L + + E + TRUE + TRUE + IP_Flow + 6 + TRUE + . + + . + 2019.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/VCU118/fpga_25g/ip/gtwizard_ultrascale_0.xci b/example/VCU118/fpga_25g/ip/gtwizard_ultrascale_0.xci new file mode 100644 index 000000000..cbac1c8b2 --- /dev/null +++ b/example/VCU118/fpga_25g/ip/gtwizard_ultrascale_0.xci @@ -0,0 +1,1415 @@ + + + xilinx.com + xci + unknown + 1.0 + + + gtwizard_ultrascale_0 + + + "000000000000000000000000000000000000000011111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + 2 + 2578.125 + 0 + 0 + 125 + 67 + 3 + 2 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 1 + 250 + 0 + 0 + 0 + 0 + 0 + 1 + "00000000" + "00000000" + 1 + 4 + 0 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000" + 0 + "00000000" + 1 + 0 + 5000 + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + 0 + "1010000011" + 0 + "0101111100" + 4 + 1 + 64 + 25.78125 + 144 + 1 + 390.6250000 + 4 + 0 + 0x000000000000000000000000000000000000000000000000 + 156.25 + 0 + 0 + 0 + 1 + 1 + 0 + 64 + 390.6250000 + 390.6250000 + 0 + 257.8125 + 0 + 8 + 2 + 0 + 0 + 0 + 390.625 + 0 + 0 + 1 + 4 + 1 + 64 + 25.78125 + 144 + 1 + 390.6250000 + 4 + 0 + 156.25 + 0 + 0 + 1 + 1 + 0 + 64 + 390.6250000 + 390.6250000 + 1 + X1Y55 X1Y54 X1Y53 X1Y52 X1Y51 X1Y50 X1Y49 X1Y48 + gtwizard_ultrascale_0 + 0 + 0 + + 125 + BOTH + 0 + GTY + 2 + 30 + 96 + 4 + gtye4 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + -1 + -1 + -1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + 1 + 1 + 1 + -1 + -1 + -1 + -1 + -1 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + 1 + 1 + 1 + 1 + 0 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + -1 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + -1 + -1 + -1 + 0 + 0 + 0 + -1 + -1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + -1 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + -1 + 0 + 0 + 0 + -1 + 0 + 1 + -1 + -1 + -1 + -1 + -1 + -1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 27 + 0 + 10GBASE-R + 9 + 390.6250000 + 8 + 2 + 390.6250000 + false + CORE + NONE + CORE + CORE + EXAMPLE_DESIGN + CORE + EXAMPLE_DESIGN + EXAMPLE_DESIGN + false + NAME + false + 250 + false + false + 250 + GTY-10GBASE-R + 0 + MULTI + 1 + ENABLE + DISABLE + ENABLE + 00000000 + false + false + false + false + false + false + false + false + 00000000 + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 4 + 1 + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + false + false + false + false + false + false + false + false + 00000000 + DISABLE + false + false + false + false + false + false + false + false + 1 + 00000000 + false + false + false + false + false + false + false + false + 0 + 5000 + ENABLE + 0 + 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 00000000 + 1 + false + 0000000000 + false + 1010000011 + NONE + false + 0101111100 + true + 0 + AC + 64B66B_ASYNC + true + AUTO + 64 + 10 + -20 + 25.78125 + X1Y48 + RXPROGDIVCLK + QPLL0 + 200 + 8388608 + + 156.25 + X1Y55 clk0+1 X1Y54 clk0+1 X1Y53 clk0+1 X1Y52 clk0+1 X1Y51 clk0+1 X1Y50 clk0+1 X1Y49 clk0+1 X1Y48 clk0+1 + OFF + 0 + PROGRAMMABLE + 800 + 64 + 15 + false + 0 + 10.3125 + 257.8125 + 0 + false + QPLL0 + 390.625 + 1 + ENABLE + 64B66B_ASYNC + CUSTOM + true + 64 + 25.78125 + X1Y48 + TXPROGDIVCLK + QPLL0 + 8388608 + 156.25 + X1Y55 clk0+1 X1Y54 clk0+1 X1Y53 clk0+1 X1Y52 clk0+1 X1Y51 clk0+1 X1Y50 clk0+1 X1Y49 clk0+1 X1Y48 clk0+1 + 64 + false + 1 + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + true + true + false + true + true + true + false + true + true + true + false + false + false + false + false + true + false + false + false + false + false + false + false + true + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + false + false + true + false + false + false + false + false + false + false + false + true + true + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + false + virtexuplus + + + xcvu9p + flga2104 + VERILOG + + MIXED + -2L + + E + TRUE + TRUE + IP_Flow + 6 + TRUE + . + + . + 2019.1 + OUT_OF_CONTEXT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/VCU118/fpga_25g/lib/eth b/example/VCU118/fpga_25g/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/VCU118/fpga_25g/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/VCU118/fpga_25g/rtl/debounce_switch.v b/example/VCU118/fpga_25g/rtl/debounce_switch.v new file mode 100644 index 000000000..bb631cc35 --- /dev/null +++ b/example/VCU118/fpga_25g/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module debounce_switch #( + parameter WIDTH=1, // width of the input and output signals + parameter N=3, // length of shift register + parameter RATE=125000 // clock division factor +)( + input wire clk, + input wire rst, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [23:0] cnt_reg = 24'd0; + +reg [N-1:0] debounce_reg[WIDTH-1:0]; + +reg [WIDTH-1:0] state; + +/* + * The synchronized output is the state register + */ +assign out = state; + +integer k; + +always @(posedge clk or posedge rst) begin + if (rst) begin + cnt_reg <= 0; + state <= 0; + + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= 0; + end + end else begin + if (cnt_reg < RATE) begin + cnt_reg <= cnt_reg + 24'd1; + end else begin + cnt_reg <= 24'd0; + end + + if (cnt_reg == 24'd0) begin + for (k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state[k] <= 0; + end else if (&debounce_reg[k] == 1) begin + state[k] <= 1; + end else begin + state[k] <= state[k]; + end + end + end +end + +endmodule diff --git a/example/VCU118/fpga_25g/rtl/fpga.v b/example/VCU118/fpga_25g/rtl/fpga.v new file mode 100644 index 000000000..823ffbf96 --- /dev/null +++ b/example/VCU118/fpga_25g/rtl/fpga.v @@ -0,0 +1,1314 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 125MHz LVDS + * Reset: Push button, active low + */ + input wire clk_125mhz_p, + input wire clk_125mhz_n, + input wire reset, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * I2C for board management + */ + inout wire i2c_scl, + inout wire i2c_sda, + + /* + * Ethernet: QSFP28 + */ + output wire qsfp1_tx1_p, + output wire qsfp1_tx1_n, + input wire qsfp1_rx1_p, + input wire qsfp1_rx1_n, + output wire qsfp1_tx2_p, + output wire qsfp1_tx2_n, + input wire qsfp1_rx2_p, + input wire qsfp1_rx2_n, + output wire qsfp1_tx3_p, + output wire qsfp1_tx3_n, + input wire qsfp1_rx3_p, + input wire qsfp1_rx3_n, + output wire qsfp1_tx4_p, + output wire qsfp1_tx4_n, + input wire qsfp1_rx4_p, + input wire qsfp1_rx4_n, + input wire qsfp1_mgt_refclk_0_p, + input wire qsfp1_mgt_refclk_0_n, + // input wire qsfp1_mgt_refclk_1_p, + // input wire qsfp1_mgt_refclk_1_n, + // output wire qsfp1_recclk_p, + // output wire qsfp1_recclk_n, + output wire qsfp1_modsell, + output wire qsfp1_resetl, + input wire qsfp1_modprsl, + input wire qsfp1_intl, + output wire qsfp1_lpmode, + + output wire qsfp2_tx1_p, + output wire qsfp2_tx1_n, + input wire qsfp2_rx1_p, + input wire qsfp2_rx1_n, + output wire qsfp2_tx2_p, + output wire qsfp2_tx2_n, + input wire qsfp2_rx2_p, + input wire qsfp2_rx2_n, + output wire qsfp2_tx3_p, + output wire qsfp2_tx3_n, + input wire qsfp2_rx3_p, + input wire qsfp2_rx3_n, + output wire qsfp2_tx4_p, + output wire qsfp2_tx4_n, + input wire qsfp2_rx4_p, + input wire qsfp2_rx4_n, + // input wire qsfp2_mgt_refclk_0_p, + // input wire qsfp2_mgt_refclk_0_n, + // input wire qsfp2_mgt_refclk_1_p, + // input wire qsfp2_mgt_refclk_1_n, + // output wire qsfp2_recclk_p, + // output wire qsfp2_recclk_n, + output wire qsfp2_modsell, + output wire qsfp2_resetl, + input wire qsfp2_modprsl, + input wire qsfp2_intl, + output wire qsfp2_lpmode, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_sgmii_rx_p, + input wire phy_sgmii_rx_n, + output wire phy_sgmii_tx_p, + output wire phy_sgmii_tx_n, + input wire phy_sgmii_clk_p, + input wire phy_sgmii_clk_n, + output wire phy_reset_n, + input wire phy_int_n, + inout wire phy_mdio, + output wire phy_mdc, + + /* + * UART: 500000 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// Clock and reset + +wire clk_125mhz_ibufg; +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +// Internal 156.25 MHz clock +wire clk_156mhz_int; +wire rst_156mhz_int; + +wire mmcm_rst = reset; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS #( + .DIFF_TERM("FALSE"), + .IBUF_LOW_PWR("FALSE") +) +clk_125mhz_ibufg_inst ( + .O (clk_125mhz_ibufg), + .I (clk_125mhz_p), + .IB (clk_125mhz_n) +); + +// MMCM instance +// 125 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 8, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCME3_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(8), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(8), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(8.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_125mhz_ibufg), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .sync_reset_out(rst_125mhz_int) +); + +// GPIO +wire btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [3:0] sw_int; + +debounce_switch #( + .WIDTH(9), + .N(4), + .RATE(156000) +) +debounce_switch_inst ( + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +wire uart_rxd_int; +wire uart_cts_int; + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(clk_156mhz_int), + .in({uart_rxd, uart_cts}), + .out({uart_rxd_int, uart_cts_int}) +); + +// SI570 I2C +wire i2c_scl_i; +wire i2c_scl_o = 1'b1; +wire i2c_scl_t = 1'b1; +wire i2c_sda_i; +wire i2c_sda_o = 1'b1; +wire i2c_sda_t = 1'b1; + +assign i2c_scl_i = i2c_scl; +assign i2c_scl = i2c_scl_t ? 1'bz : i2c_scl_o; +assign i2c_sda_i = i2c_sda; +assign i2c_sda = i2c_sda_t ? 1'bz : i2c_sda_o; + +// XGMII 10G PHY +assign qsfp1_modsell = 1'b0; +assign qsfp1_resetl = 1'b1; +assign qsfp1_lpmode = 1'b0; + +wire qsfp1_tx_clk_1_int; +wire qsfp1_tx_rst_1_int; +wire [63:0] qsfp1_txd_1_int; +wire [7:0] qsfp1_txc_1_int; +wire qsfp1_rx_clk_1_int; +wire qsfp1_rx_rst_1_int; +wire [63:0] qsfp1_rxd_1_int; +wire [7:0] qsfp1_rxc_1_int; +wire qsfp1_tx_clk_2_int; +wire qsfp1_tx_rst_2_int; +wire [63:0] qsfp1_txd_2_int; +wire [7:0] qsfp1_txc_2_int; +wire qsfp1_rx_clk_2_int; +wire qsfp1_rx_rst_2_int; +wire [63:0] qsfp1_rxd_2_int; +wire [7:0] qsfp1_rxc_2_int; +wire qsfp1_tx_clk_3_int; +wire qsfp1_tx_rst_3_int; +wire [63:0] qsfp1_txd_3_int; +wire [7:0] qsfp1_txc_3_int; +wire qsfp1_rx_clk_3_int; +wire qsfp1_rx_rst_3_int; +wire [63:0] qsfp1_rxd_3_int; +wire [7:0] qsfp1_rxc_3_int; +wire qsfp1_tx_clk_4_int; +wire qsfp1_tx_rst_4_int; +wire [63:0] qsfp1_txd_4_int; +wire [7:0] qsfp1_txc_4_int; +wire qsfp1_rx_clk_4_int; +wire qsfp1_rx_rst_4_int; +wire [63:0] qsfp1_rxd_4_int; +wire [7:0] qsfp1_rxc_4_int; + +assign qsfp2_modsell = 1'b0; +assign qsfp2_resetl = 1'b1; +assign qsfp2_lpmode = 1'b0; + +wire qsfp2_tx_clk_1_int; +wire qsfp2_tx_rst_1_int; +wire [63:0] qsfp2_txd_1_int; +wire [7:0] qsfp2_txc_1_int; +wire qsfp2_rx_clk_1_int; +wire qsfp2_rx_rst_1_int; +wire [63:0] qsfp2_rxd_1_int; +wire [7:0] qsfp2_rxc_1_int; +wire qsfp2_tx_clk_2_int; +wire qsfp2_tx_rst_2_int; +wire [63:0] qsfp2_txd_2_int; +wire [7:0] qsfp2_txc_2_int; +wire qsfp2_rx_clk_2_int; +wire qsfp2_rx_rst_2_int; +wire [63:0] qsfp2_rxd_2_int; +wire [7:0] qsfp2_rxc_2_int; +wire qsfp2_tx_clk_3_int; +wire qsfp2_tx_rst_3_int; +wire [63:0] qsfp2_txd_3_int; +wire [7:0] qsfp2_txc_3_int; +wire qsfp2_rx_clk_3_int; +wire qsfp2_rx_rst_3_int; +wire [63:0] qsfp2_rxd_3_int; +wire [7:0] qsfp2_rxc_3_int; +wire qsfp2_tx_clk_4_int; +wire qsfp2_tx_rst_4_int; +wire [63:0] qsfp2_txd_4_int; +wire [7:0] qsfp2_txc_4_int; +wire qsfp2_rx_clk_4_int; +wire qsfp2_rx_rst_4_int; +wire [63:0] qsfp2_rxd_4_int; +wire [7:0] qsfp2_rxc_4_int; + +wire qsfp1_rx_block_lock_1; +wire qsfp1_rx_block_lock_2; +wire qsfp1_rx_block_lock_3; +wire qsfp1_rx_block_lock_4; + +wire qsfp2_rx_block_lock_1; +wire qsfp2_rx_block_lock_2; +wire qsfp2_rx_block_lock_3; +wire qsfp2_rx_block_lock_4; + +wire qsfp1_mgt_refclk_0; + +wire [7:0] gt_txclkout; +wire gt_txusrclk; + +wire [7:0] gt_rxclkout; +wire [7:0] gt_rxusrclk; + +wire gt_reset_tx_done; +wire gt_reset_rx_done; + +wire [7:0] gt_txprgdivresetdone; +wire [7:0] gt_txpmaresetdone; +wire [7:0] gt_rxprgdivresetdone; +wire [7:0] gt_rxpmaresetdone; + +wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); +wire gt_rx_reset = ~>_rxpmaresetdone; + +reg gt_userclk_tx_active = 1'b0; +reg [7:0] gt_userclk_rx_active = 1'b0; + +IBUFDS_GTE4 ibufds_gte4_qsfp1_mgt_refclk_0_inst ( + .I (qsfp1_mgt_refclk_0_p), + .IB (qsfp1_mgt_refclk_0_n), + .CEB (1'b0), + .O (qsfp1_mgt_refclk_0), + .ODIV2 () +); + + +BUFG_GT bufg_gt_tx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txclkout[0]), + .O (gt_txusrclk) +); + +assign clk_156mhz_int = gt_txusrclk; + +always @(posedge gt_txusrclk, posedge gt_tx_reset) begin + if (gt_tx_reset) begin + gt_userclk_tx_active <= 1'b0; + end else begin + gt_userclk_tx_active <= 1'b1; + end +end + +genvar n; + +generate + +for (n = 0; n < 8; n = n + 1) begin + + BUFG_GT bufg_gt_rx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk[n]) + ); + + always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin + if (gt_rx_reset) begin + gt_userclk_rx_active[n] <= 1'b0; + end else begin + gt_userclk_rx_active[n] <= 1'b1; + end + end + +end + +endgenerate + +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz_int), + .rst(~gt_reset_tx_done), + .sync_reset_out(rst_156mhz_int) +); + +wire [5:0] qsfp1_gt_txheader_1; +wire [127:0] qsfp1_gt_txdata_1; +wire qsfp1_gt_rxgearboxslip_1; +wire [5:0] qsfp1_gt_rxheader_1; +wire [1:0] qsfp1_gt_rxheadervalid_1; +wire [127:0] qsfp1_gt_rxdata_1; +wire [1:0] qsfp1_gt_rxdatavalid_1; + +wire [5:0] qsfp1_gt_txheader_2; +wire [127:0] qsfp1_gt_txdata_2; +wire qsfp1_gt_rxgearboxslip_2; +wire [5:0] qsfp1_gt_rxheader_2; +wire [1:0] qsfp1_gt_rxheadervalid_2; +wire [127:0] qsfp1_gt_rxdata_2; +wire [1:0] qsfp1_gt_rxdatavalid_2; + +wire [5:0] qsfp1_gt_txheader_3; +wire [127:0] qsfp1_gt_txdata_3; +wire qsfp1_gt_rxgearboxslip_3; +wire [5:0] qsfp1_gt_rxheader_3; +wire [1:0] qsfp1_gt_rxheadervalid_3; +wire [127:0] qsfp1_gt_rxdata_3; +wire [1:0] qsfp1_gt_rxdatavalid_3; + +wire [5:0] qsfp1_gt_txheader_4; +wire [127:0] qsfp1_gt_txdata_4; +wire qsfp1_gt_rxgearboxslip_4; +wire [5:0] qsfp1_gt_rxheader_4; +wire [1:0] qsfp1_gt_rxheadervalid_4; +wire [127:0] qsfp1_gt_rxdata_4; +wire [1:0] qsfp1_gt_rxdatavalid_4; + +wire [5:0] qsfp2_gt_txheader_1; +wire [127:0] qsfp2_gt_txdata_1; +wire qsfp2_gt_rxgearboxslip_1; +wire [5:0] qsfp2_gt_rxheader_1; +wire [1:0] qsfp2_gt_rxheadervalid_1; +wire [127:0] qsfp2_gt_rxdata_1; +wire [1:0] qsfp2_gt_rxdatavalid_1; + +wire [5:0] qsfp2_gt_txheader_2; +wire [127:0] qsfp2_gt_txdata_2; +wire qsfp2_gt_rxgearboxslip_2; +wire [5:0] qsfp2_gt_rxheader_2; +wire [1:0] qsfp2_gt_rxheadervalid_2; +wire [127:0] qsfp2_gt_rxdata_2; +wire [1:0] qsfp2_gt_rxdatavalid_2; + +wire [5:0] qsfp2_gt_txheader_3; +wire [127:0] qsfp2_gt_txdata_3; +wire qsfp2_gt_rxgearboxslip_3; +wire [5:0] qsfp2_gt_rxheader_3; +wire [1:0] qsfp2_gt_rxheadervalid_3; +wire [127:0] qsfp2_gt_rxdata_3; +wire [1:0] qsfp2_gt_rxdatavalid_3; + +wire [5:0] qsfp2_gt_txheader_4; +wire [127:0] qsfp2_gt_txdata_4; +wire qsfp2_gt_rxgearboxslip_4; +wire [5:0] qsfp2_gt_rxheader_4; +wire [1:0] qsfp2_gt_rxheadervalid_4; +wire [127:0] qsfp2_gt_rxdata_4; +wire [1:0] qsfp2_gt_rxdatavalid_4; + +gtwizard_ultrascale_0 +qsfp_gty_inst ( + .gtwiz_userclk_tx_active_in(>_userclk_tx_active), + .gtwiz_userclk_rx_active_in(>_userclk_rx_active), + + .gtwiz_reset_clk_freerun_in(clk_125mhz_int), + .gtwiz_reset_all_in(rst_125mhz_int), + + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(1'b0), + + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(1'b0), + + .gtwiz_reset_rx_cdr_stable_out(), + + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + + .gtrefclk00_in({2{qsfp1_mgt_refclk_0}}), + + .qpll0outclk_out(), + .qpll0outrefclk_out(), + + .gtyrxn_in({qsfp2_rx4_n, qsfp2_rx3_n, qsfp2_rx2_n, qsfp2_rx1_n, qsfp1_rx4_n, qsfp1_rx3_n, qsfp1_rx2_n, qsfp1_rx1_n}), + .gtyrxp_in({qsfp2_rx4_p, qsfp2_rx3_p, qsfp2_rx2_p, qsfp2_rx1_p, qsfp1_rx4_p, qsfp1_rx3_p, qsfp1_rx2_p, qsfp1_rx1_p}), + + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk), + + .txdata_in({qsfp2_gt_txdata_4, qsfp2_gt_txdata_3, qsfp2_gt_txdata_2, qsfp2_gt_txdata_1, qsfp1_gt_txdata_4, qsfp1_gt_txdata_3, qsfp1_gt_txdata_2, qsfp1_gt_txdata_1}), + .txheader_in({qsfp2_gt_txheader_4, qsfp2_gt_txheader_3, qsfp2_gt_txheader_2, qsfp2_gt_txheader_1, qsfp1_gt_txheader_4, qsfp1_gt_txheader_3, qsfp1_gt_txheader_2, qsfp1_gt_txheader_1}), + .txsequence_in({8{1'b0}}), + + .txusrclk_in({8{gt_txusrclk}}), + .txusrclk2_in({8{gt_txusrclk}}), + + .gtpowergood_out(), + + .gtytxn_out({qsfp2_tx4_n, qsfp2_tx3_n, qsfp2_tx2_n, qsfp2_tx1_n, qsfp1_tx4_n, qsfp1_tx3_n, qsfp1_tx2_n, qsfp1_tx1_n}), + .gtytxp_out({qsfp2_tx4_p, qsfp2_tx3_p, qsfp2_tx2_p, qsfp2_tx1_p, qsfp1_tx4_p, qsfp1_tx3_p, qsfp1_tx2_p, qsfp1_tx1_p}), + + .rxgearboxslip_in({qsfp2_gt_rxgearboxslip_4, qsfp2_gt_rxgearboxslip_3, qsfp2_gt_rxgearboxslip_2, qsfp2_gt_rxgearboxslip_1, qsfp1_gt_rxgearboxslip_4, qsfp1_gt_rxgearboxslip_3, qsfp1_gt_rxgearboxslip_2, qsfp1_gt_rxgearboxslip_1}), + .rxdata_out({qsfp2_gt_rxdata_4, qsfp2_gt_rxdata_3, qsfp2_gt_rxdata_2, qsfp2_gt_rxdata_1, qsfp1_gt_rxdata_4, qsfp1_gt_rxdata_3, qsfp1_gt_rxdata_2, qsfp1_gt_rxdata_1}), + .rxdatavalid_out({qsfp2_gt_rxdatavalid_4, qsfp2_gt_rxdatavalid_3, qsfp2_gt_rxdatavalid_2, qsfp2_gt_rxdatavalid_1, qsfp1_gt_rxdatavalid_4, qsfp1_gt_rxdatavalid_3, qsfp1_gt_rxdatavalid_2, qsfp1_gt_rxdatavalid_1}), + .rxheader_out({qsfp2_gt_rxheader_4, qsfp2_gt_rxheader_3, qsfp2_gt_rxheader_2, qsfp2_gt_rxheader_1, qsfp1_gt_rxheader_4, qsfp1_gt_rxheader_3, qsfp1_gt_rxheader_2, qsfp1_gt_rxheader_1}), + .rxheadervalid_out({qsfp2_gt_rxheadervalid_4, qsfp2_gt_rxheadervalid_3, qsfp2_gt_rxheadervalid_2, qsfp2_gt_rxheadervalid_1, qsfp1_gt_rxheadervalid_4, qsfp1_gt_rxheadervalid_3, qsfp1_gt_rxheadervalid_2, qsfp1_gt_rxheadervalid_1}), + .rxoutclk_out(gt_rxclkout), + .rxpmaresetdone_out(gt_rxpmaresetdone), + .rxprgdivresetdone_out(gt_rxprgdivresetdone), + .rxstartofseq_out(), + + .txoutclk_out(gt_txclkout), + .txpmaresetdone_out(gt_txpmaresetdone), + .txprgdivresetdone_out(gt_txprgdivresetdone) +); + +assign qsfp1_tx_clk_1_int = clk_156mhz_int; +assign qsfp1_tx_rst_1_int = rst_156mhz_int; + +assign qsfp1_rx_clk_1_int = gt_rxusrclk[0]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_1_reset_sync_inst ( + .clk(qsfp1_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp1_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp1_phy_1_inst ( + .tx_clk(qsfp1_tx_clk_1_int), + .tx_rst(qsfp1_tx_rst_1_int), + .rx_clk(qsfp1_rx_clk_1_int), + .rx_rst(qsfp1_rx_rst_1_int), + .xgmii_txd(qsfp1_txd_1_int), + .xgmii_txc(qsfp1_txc_1_int), + .xgmii_rxd(qsfp1_rxd_1_int), + .xgmii_rxc(qsfp1_rxc_1_int), + .serdes_tx_data(qsfp1_gt_txdata_1), + .serdes_tx_hdr(qsfp1_gt_txheader_1), + .serdes_rx_data(qsfp1_gt_rxdata_1), + .serdes_rx_hdr(qsfp1_gt_rxheader_1), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_1), + .rx_block_lock(qsfp1_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp1_tx_clk_2_int = clk_156mhz_int; +assign qsfp1_tx_rst_2_int = rst_156mhz_int; + +assign qsfp1_rx_clk_2_int = gt_rxusrclk[1]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_2_reset_sync_inst ( + .clk(qsfp1_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp1_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp1_phy_2_inst ( + .tx_clk(qsfp1_tx_clk_2_int), + .tx_rst(qsfp1_tx_rst_2_int), + .rx_clk(qsfp1_rx_clk_2_int), + .rx_rst(qsfp1_rx_rst_2_int), + .xgmii_txd(qsfp1_txd_2_int), + .xgmii_txc(qsfp1_txc_2_int), + .xgmii_rxd(qsfp1_rxd_2_int), + .xgmii_rxc(qsfp1_rxc_2_int), + .serdes_tx_data(qsfp1_gt_txdata_2), + .serdes_tx_hdr(qsfp1_gt_txheader_2), + .serdes_rx_data(qsfp1_gt_rxdata_2), + .serdes_rx_hdr(qsfp1_gt_rxheader_2), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_2), + .rx_block_lock(qsfp1_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp1_tx_clk_3_int = clk_156mhz_int; +assign qsfp1_tx_rst_3_int = rst_156mhz_int; + +assign qsfp1_rx_clk_3_int = gt_rxusrclk[2]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_3_reset_sync_inst ( + .clk(qsfp1_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp1_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp1_phy_3_inst ( + .tx_clk(qsfp1_tx_clk_3_int), + .tx_rst(qsfp1_tx_rst_3_int), + .rx_clk(qsfp1_rx_clk_3_int), + .rx_rst(qsfp1_rx_rst_3_int), + .xgmii_txd(qsfp1_txd_3_int), + .xgmii_txc(qsfp1_txc_3_int), + .xgmii_rxd(qsfp1_rxd_3_int), + .xgmii_rxc(qsfp1_rxc_3_int), + .serdes_tx_data(qsfp1_gt_txdata_3), + .serdes_tx_hdr(qsfp1_gt_txheader_3), + .serdes_rx_data(qsfp1_gt_rxdata_3), + .serdes_rx_hdr(qsfp1_gt_rxheader_3), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_3), + .rx_block_lock(qsfp1_rx_block_lock_3), + .rx_high_ber() +); + +assign qsfp1_tx_clk_4_int = clk_156mhz_int; +assign qsfp1_tx_rst_4_int = rst_156mhz_int; + +assign qsfp1_rx_clk_4_int = gt_rxusrclk[3]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_4_reset_sync_inst ( + .clk(qsfp1_rx_clk_4_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp1_rx_rst_4_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp1_phy_4_inst ( + .tx_clk(qsfp1_tx_clk_4_int), + .tx_rst(qsfp1_tx_rst_4_int), + .rx_clk(qsfp1_rx_clk_4_int), + .rx_rst(qsfp1_rx_rst_4_int), + .xgmii_txd(qsfp1_txd_4_int), + .xgmii_txc(qsfp1_txc_4_int), + .xgmii_rxd(qsfp1_rxd_4_int), + .xgmii_rxc(qsfp1_rxc_4_int), + .serdes_tx_data(qsfp1_gt_txdata_4), + .serdes_tx_hdr(qsfp1_gt_txheader_4), + .serdes_rx_data(qsfp1_gt_rxdata_4), + .serdes_rx_hdr(qsfp1_gt_rxheader_4), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_4), + .rx_block_lock(qsfp1_rx_block_lock_4), + .rx_high_ber() +); + +assign qsfp2_tx_clk_1_int = clk_156mhz_int; +assign qsfp2_tx_rst_1_int = rst_156mhz_int; + +assign qsfp2_rx_clk_1_int = gt_rxusrclk[4]; + +sync_reset #( + .N(4) +) +qsfp2_rx_rst_1_reset_sync_inst ( + .clk(qsfp2_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp2_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp2_phy_1_inst ( + .tx_clk(qsfp2_tx_clk_1_int), + .tx_rst(qsfp2_tx_rst_1_int), + .rx_clk(qsfp2_rx_clk_1_int), + .rx_rst(qsfp2_rx_rst_1_int), + .xgmii_txd(qsfp2_txd_1_int), + .xgmii_txc(qsfp2_txc_1_int), + .xgmii_rxd(qsfp2_rxd_1_int), + .xgmii_rxc(qsfp2_rxc_1_int), + .serdes_tx_data(qsfp2_gt_txdata_1), + .serdes_tx_hdr(qsfp2_gt_txheader_1), + .serdes_rx_data(qsfp2_gt_rxdata_1), + .serdes_rx_hdr(qsfp2_gt_rxheader_1), + .serdes_rx_bitslip(qsfp2_gt_rxgearboxslip_1), + .rx_block_lock(qsfp2_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp2_tx_clk_2_int = clk_156mhz_int; +assign qsfp2_tx_rst_2_int = rst_156mhz_int; + +assign qsfp2_rx_clk_2_int = gt_rxusrclk[5]; + +sync_reset #( + .N(4) +) +qsfp2_rx_rst_2_reset_sync_inst ( + .clk(qsfp2_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp2_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp2_phy_2_inst ( + .tx_clk(qsfp2_tx_clk_2_int), + .tx_rst(qsfp2_tx_rst_2_int), + .rx_clk(qsfp2_rx_clk_2_int), + .rx_rst(qsfp2_rx_rst_2_int), + .xgmii_txd(qsfp2_txd_2_int), + .xgmii_txc(qsfp2_txc_2_int), + .xgmii_rxd(qsfp2_rxd_2_int), + .xgmii_rxc(qsfp2_rxc_2_int), + .serdes_tx_data(qsfp2_gt_txdata_2), + .serdes_tx_hdr(qsfp2_gt_txheader_2), + .serdes_rx_data(qsfp2_gt_rxdata_2), + .serdes_rx_hdr(qsfp2_gt_rxheader_2), + .serdes_rx_bitslip(qsfp2_gt_rxgearboxslip_2), + .rx_block_lock(qsfp2_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp2_tx_clk_3_int = clk_156mhz_int; +assign qsfp2_tx_rst_3_int = rst_156mhz_int; + +assign qsfp2_rx_clk_3_int = gt_rxusrclk[6]; + +sync_reset #( + .N(4) +) +qsfp2_rx_rst_3_reset_sync_inst ( + .clk(qsfp2_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp2_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp2_phy_3_inst ( + .tx_clk(qsfp2_tx_clk_3_int), + .tx_rst(qsfp2_tx_rst_3_int), + .rx_clk(qsfp2_rx_clk_3_int), + .rx_rst(qsfp2_rx_rst_3_int), + .xgmii_txd(qsfp2_txd_3_int), + .xgmii_txc(qsfp2_txc_3_int), + .xgmii_rxd(qsfp2_rxd_3_int), + .xgmii_rxc(qsfp2_rxc_3_int), + .serdes_tx_data(qsfp2_gt_txdata_3), + .serdes_tx_hdr(qsfp2_gt_txheader_3), + .serdes_rx_data(qsfp2_gt_rxdata_3), + .serdes_rx_hdr(qsfp2_gt_rxheader_3), + .serdes_rx_bitslip(qsfp2_gt_rxgearboxslip_3), + .rx_block_lock(qsfp2_rx_block_lock_3), + .rx_high_ber() +); + +assign qsfp2_tx_clk_4_int = clk_156mhz_int; +assign qsfp2_tx_rst_4_int = rst_156mhz_int; + +assign qsfp2_rx_clk_4_int = gt_rxusrclk[7]; + +sync_reset #( + .N(4) +) +qsfp2_rx_rst_4_reset_sync_inst ( + .clk(qsfp2_rx_clk_4_int), + .rst(~gt_reset_rx_done), + .sync_reset_out(qsfp2_rx_rst_4_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1), + .TX_SERDES_PIPELINE(2), + .RX_SERDES_PIPELINE(2), + .COUNT_125US(125000/2.56) +) +qsfp2_phy_4_inst ( + .tx_clk(qsfp2_tx_clk_4_int), + .tx_rst(qsfp2_tx_rst_4_int), + .rx_clk(qsfp2_rx_clk_4_int), + .rx_rst(qsfp2_rx_rst_4_int), + .xgmii_txd(qsfp2_txd_4_int), + .xgmii_txc(qsfp2_txc_4_int), + .xgmii_rxd(qsfp2_rxd_4_int), + .xgmii_rxc(qsfp2_rxc_4_int), + .serdes_tx_data(qsfp2_gt_txdata_4), + .serdes_tx_hdr(qsfp2_gt_txheader_4), + .serdes_rx_data(qsfp2_gt_rxdata_4), + .serdes_rx_hdr(qsfp2_gt_rxheader_4), + .serdes_rx_bitslip(qsfp2_gt_rxgearboxslip_4), + .rx_block_lock(qsfp2_rx_block_lock_4), + .rx_high_ber() +); + +// SGMII interface to PHY +wire phy_gmii_clk_int; +wire phy_gmii_rst_int; +wire phy_gmii_clk_en_int; +wire [7:0] phy_gmii_txd_int; +wire phy_gmii_tx_en_int; +wire phy_gmii_tx_er_int; +wire [7:0] phy_gmii_rxd_int; +wire phy_gmii_rx_dv_int; +wire phy_gmii_rx_er_int; + +wire [15:0] gig_eth_pcspma_status_vector; + +wire gig_eth_pcspma_status_link_status = gig_eth_pcspma_status_vector[0]; +wire gig_eth_pcspma_status_link_synchronization = gig_eth_pcspma_status_vector[1]; +wire gig_eth_pcspma_status_rudi_c = gig_eth_pcspma_status_vector[2]; +wire gig_eth_pcspma_status_rudi_i = gig_eth_pcspma_status_vector[3]; +wire gig_eth_pcspma_status_rudi_invalid = gig_eth_pcspma_status_vector[4]; +wire gig_eth_pcspma_status_rxdisperr = gig_eth_pcspma_status_vector[5]; +wire gig_eth_pcspma_status_rxnotintable = gig_eth_pcspma_status_vector[6]; +wire gig_eth_pcspma_status_phy_link_status = gig_eth_pcspma_status_vector[7]; +wire [1:0] gig_eth_pcspma_status_remote_fault_encdg = gig_eth_pcspma_status_vector[9:8]; +wire [1:0] gig_eth_pcspma_status_speed = gig_eth_pcspma_status_vector[11:10]; +wire gig_eth_pcspma_status_duplex = gig_eth_pcspma_status_vector[12]; +wire gig_eth_pcspma_status_remote_fault = gig_eth_pcspma_status_vector[13]; +wire [1:0] gig_eth_pcspma_status_pause = gig_eth_pcspma_status_vector[15:14]; + +wire [4:0] gig_eth_pcspma_config_vector; + +assign gig_eth_pcspma_config_vector[4] = 1'b1; // autonegotiation enable +assign gig_eth_pcspma_config_vector[3] = 1'b0; // isolate +assign gig_eth_pcspma_config_vector[2] = 1'b0; // power down +assign gig_eth_pcspma_config_vector[1] = 1'b0; // loopback enable +assign gig_eth_pcspma_config_vector[0] = 1'b0; // unidirectional enable + +wire [15:0] gig_eth_pcspma_an_config_vector; + +assign gig_eth_pcspma_an_config_vector[15] = 1'b1; // SGMII link status +assign gig_eth_pcspma_an_config_vector[14] = 1'b1; // SGMII Acknowledge +assign gig_eth_pcspma_an_config_vector[13:12] = 2'b01; // full duplex +assign gig_eth_pcspma_an_config_vector[11:10] = 2'b10; // SGMII speed +assign gig_eth_pcspma_an_config_vector[9] = 1'b0; // reserved +assign gig_eth_pcspma_an_config_vector[8:7] = 2'b00; // pause frames - SGMII reserved +assign gig_eth_pcspma_an_config_vector[6] = 1'b0; // reserved +assign gig_eth_pcspma_an_config_vector[5] = 1'b0; // full duplex - SGMII reserved +assign gig_eth_pcspma_an_config_vector[4:1] = 4'b0000; // reserved +assign gig_eth_pcspma_an_config_vector[0] = 1'b1; // SGMII + +gig_ethernet_pcs_pma_0 +eth_pcspma ( + // SGMII + .txp_0 (phy_sgmii_tx_p), + .txn_0 (phy_sgmii_tx_n), + .rxp_0 (phy_sgmii_rx_p), + .rxn_0 (phy_sgmii_rx_n), + + // Ref clock from PHY + .refclk625_p (phy_sgmii_clk_p), + .refclk625_n (phy_sgmii_clk_n), + + // async reset + .reset (rst_125mhz_int), + + // clock and reset outputs + .clk125_out (phy_gmii_clk_int), + .clk312_out (), + .rst_125_out (phy_gmii_rst_int), + .tx_logic_reset (), + .rx_logic_reset (), + .tx_locked (), + .rx_locked (), + .tx_pll_clk_out (), + .rx_pll_clk_out (), + + // MAC clocking + .sgmii_clk_r_0 (), + .sgmii_clk_f_0 (), + .sgmii_clk_en_0 (phy_gmii_clk_en_int), + + // Speed control + .speed_is_10_100_0 (gig_eth_pcspma_status_speed != 2'b10), + .speed_is_100_0 (gig_eth_pcspma_status_speed == 2'b01), + + // Internal GMII + .gmii_txd_0 (phy_gmii_txd_int), + .gmii_tx_en_0 (phy_gmii_tx_en_int), + .gmii_tx_er_0 (phy_gmii_tx_er_int), + .gmii_rxd_0 (phy_gmii_rxd_int), + .gmii_rx_dv_0 (phy_gmii_rx_dv_int), + .gmii_rx_er_0 (phy_gmii_rx_er_int), + .gmii_isolate_0 (), + + // Configuration + .configuration_vector_0 (gig_eth_pcspma_config_vector), + + .an_interrupt_0 (), + .an_adv_config_vector_0 (gig_eth_pcspma_an_config_vector), + .an_restart_config_0 (1'b0), + + // Status + .status_vector_0 (gig_eth_pcspma_status_vector), + .signal_detect_0 (1'b1), + + // Cascade + .tx_bsc_rst_out (), + .rx_bsc_rst_out (), + .tx_bs_rst_out (), + .rx_bs_rst_out (), + .tx_rst_dly_out (), + .rx_rst_dly_out (), + .tx_bsc_en_vtc_out (), + .rx_bsc_en_vtc_out (), + .tx_bs_en_vtc_out (), + .rx_bs_en_vtc_out (), + .riu_clk_out (), + .riu_addr_out (), + .riu_wr_data_out (), + .riu_wr_en_out (), + .riu_nibble_sel_out (), + .riu_rddata_1 (16'b0), + .riu_valid_1 (1'b0), + .riu_prsnt_1 (1'b0), + .riu_rddata_2 (16'b0), + .riu_valid_2 (1'b0), + .riu_prsnt_2 (1'b0), + .riu_rddata_3 (16'b0), + .riu_valid_3 (1'b0), + .riu_prsnt_3 (1'b0), + .rx_btval_1 (), + .rx_btval_2 (), + .rx_btval_3 (), + .tx_dly_rdy_1 (1'b1), + .rx_dly_rdy_1 (1'b1), + .rx_vtc_rdy_1 (1'b1), + .tx_vtc_rdy_1 (1'b1), + .tx_dly_rdy_2 (1'b1), + .rx_dly_rdy_2 (1'b1), + .rx_vtc_rdy_2 (1'b1), + .tx_vtc_rdy_2 (1'b1), + .tx_dly_rdy_3 (1'b1), + .rx_dly_rdy_3 (1'b1), + .rx_vtc_rdy_3 (1'b1), + .tx_vtc_rdy_3 (1'b1), + .tx_rdclk_out () +); + +reg [19:0] delay_reg = 20'hfffff; + +reg [4:0] mdio_cmd_phy_addr = 5'h03; +reg [4:0] mdio_cmd_reg_addr = 5'h00; +reg [15:0] mdio_cmd_data = 16'd0; +reg [1:0] mdio_cmd_opcode = 2'b01; +reg mdio_cmd_valid = 1'b0; +wire mdio_cmd_ready; + +reg [3:0] state_reg = 0; + +always @(posedge clk_125mhz_int) begin + if (rst_125mhz_int) begin + state_reg <= 0; + delay_reg <= 20'hfffff; + mdio_cmd_reg_addr <= 5'h00; + mdio_cmd_data <= 16'd0; + mdio_cmd_valid <= 1'b0; + end else begin + mdio_cmd_valid <= mdio_cmd_valid & !mdio_cmd_ready; + if (delay_reg > 0) begin + delay_reg <= delay_reg - 1; + end else if (!mdio_cmd_ready) begin + // wait for ready + state_reg <= state_reg; + end else begin + mdio_cmd_valid <= 1'b0; + case (state_reg) + // set SGMII autonegotiation timer to 11 ms + // write 0x0070 to CFG4 (0x0031) + 4'd0: begin + // write to REGCR to load address + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h001F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd1; + end + 4'd1: begin + // write address of CFG4 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h0031; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd2; + end + 4'd2: begin + // write to REGCR to load data + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h401F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd3; + end + 4'd3: begin + // write data for CFG4 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h0070; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd4; + end + // enable SGMII clock output + // write 0x4000 to SGMIICTL1 (0x00D3) + 4'd4: begin + // write to REGCR to load address + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h001F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd5; + end + 4'd5: begin + // write address of SGMIICTL1 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h00D3; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd6; + end + 4'd6: begin + // write to REGCR to load data + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h401F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd7; + end + 4'd7: begin + // write data for SGMIICTL1 to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h4000; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd8; + end + // enable 10Mbps operation + // write 0x0015 to 10M_SGMII_CFG (0x016F) + 4'd8: begin + // write to REGCR to load address + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h001F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd9; + end + 4'd9: begin + // write address of 10M_SGMII_CFG to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h016F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd10; + end + 4'd10: begin + // write to REGCR to load data + mdio_cmd_reg_addr <= 5'h0D; + mdio_cmd_data <= 16'h401F; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd11; + end + 4'd11: begin + // write data for 10M_SGMII_CFG to ADDAR + mdio_cmd_reg_addr <= 5'h0E; + mdio_cmd_data <= 16'h0015; + mdio_cmd_valid <= 1'b1; + state_reg <= 4'd12; + end + 4'd12: begin + // done + state_reg <= 4'd12; + end + endcase + end + end +end + +wire mdc; +wire mdio_i; +wire mdio_o; +wire mdio_t; + +mdio_master +mdio_master_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + + .cmd_phy_addr(mdio_cmd_phy_addr), + .cmd_reg_addr(mdio_cmd_reg_addr), + .cmd_data(mdio_cmd_data), + .cmd_opcode(mdio_cmd_opcode), + .cmd_valid(mdio_cmd_valid), + .cmd_ready(mdio_cmd_ready), + + .data_out(), + .data_out_valid(), + .data_out_ready(1'b1), + + .mdc_o(mdc), + .mdio_i(mdio_i), + .mdio_o(mdio_o), + .mdio_t(mdio_t), + + .busy(), + + .prescale(8'd3) +); + +assign phy_mdc = mdc; +assign mdio_i = phy_mdio; +assign phy_mdio = mdio_t ? 1'bz : mdio_o; + +wire [7:0] led_int; + +assign led = sw[0] ? {qsfp2_rx_block_lock_4, qsfp2_rx_block_lock_3, qsfp2_rx_block_lock_2, qsfp2_rx_block_lock_1, qsfp1_rx_block_lock_4, qsfp1_rx_block_lock_3, qsfp1_rx_block_lock_2, qsfp1_rx_block_lock_1} : led_int; + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .led(led_int), + /* + * Ethernet: QSFP28 + */ + .qsfp1_tx_clk_1(qsfp1_tx_clk_1_int), + .qsfp1_tx_rst_1(qsfp1_tx_rst_1_int), + .qsfp1_txd_1(qsfp1_txd_1_int), + .qsfp1_txc_1(qsfp1_txc_1_int), + .qsfp1_rx_clk_1(qsfp1_rx_clk_1_int), + .qsfp1_rx_rst_1(qsfp1_rx_rst_1_int), + .qsfp1_rxd_1(qsfp1_rxd_1_int), + .qsfp1_rxc_1(qsfp1_rxc_1_int), + .qsfp1_tx_clk_2(qsfp1_tx_clk_2_int), + .qsfp1_tx_rst_2(qsfp1_tx_rst_2_int), + .qsfp1_txd_2(qsfp1_txd_2_int), + .qsfp1_txc_2(qsfp1_txc_2_int), + .qsfp1_rx_clk_2(qsfp1_rx_clk_2_int), + .qsfp1_rx_rst_2(qsfp1_rx_rst_2_int), + .qsfp1_rxd_2(qsfp1_rxd_2_int), + .qsfp1_rxc_2(qsfp1_rxc_2_int), + .qsfp1_tx_clk_3(qsfp1_tx_clk_3_int), + .qsfp1_tx_rst_3(qsfp1_tx_rst_3_int), + .qsfp1_txd_3(qsfp1_txd_3_int), + .qsfp1_txc_3(qsfp1_txc_3_int), + .qsfp1_rx_clk_3(qsfp1_rx_clk_3_int), + .qsfp1_rx_rst_3(qsfp1_rx_rst_3_int), + .qsfp1_rxd_3(qsfp1_rxd_3_int), + .qsfp1_rxc_3(qsfp1_rxc_3_int), + .qsfp1_tx_clk_4(qsfp1_tx_clk_4_int), + .qsfp1_tx_rst_4(qsfp1_tx_rst_4_int), + .qsfp1_txd_4(qsfp1_txd_4_int), + .qsfp1_txc_4(qsfp1_txc_4_int), + .qsfp1_rx_clk_4(qsfp1_rx_clk_4_int), + .qsfp1_rx_rst_4(qsfp1_rx_rst_4_int), + .qsfp1_rxd_4(qsfp1_rxd_4_int), + .qsfp1_rxc_4(qsfp1_rxc_4_int), + .qsfp2_tx_clk_1(qsfp2_tx_clk_1_int), + .qsfp2_tx_rst_1(qsfp2_tx_rst_1_int), + .qsfp2_txd_1(qsfp2_txd_1_int), + .qsfp2_txc_1(qsfp2_txc_1_int), + .qsfp2_rx_clk_1(qsfp2_rx_clk_1_int), + .qsfp2_rx_rst_1(qsfp2_rx_rst_1_int), + .qsfp2_rxd_1(qsfp2_rxd_1_int), + .qsfp2_rxc_1(qsfp2_rxc_1_int), + .qsfp2_tx_clk_2(qsfp2_tx_clk_2_int), + .qsfp2_tx_rst_2(qsfp2_tx_rst_2_int), + .qsfp2_txd_2(qsfp2_txd_2_int), + .qsfp2_txc_2(qsfp2_txc_2_int), + .qsfp2_rx_clk_2(qsfp2_rx_clk_2_int), + .qsfp2_rx_rst_2(qsfp2_rx_rst_2_int), + .qsfp2_rxd_2(qsfp2_rxd_2_int), + .qsfp2_rxc_2(qsfp2_rxc_2_int), + .qsfp2_tx_clk_3(qsfp2_tx_clk_3_int), + .qsfp2_tx_rst_3(qsfp2_tx_rst_3_int), + .qsfp2_txd_3(qsfp2_txd_3_int), + .qsfp2_txc_3(qsfp2_txc_3_int), + .qsfp2_rx_clk_3(qsfp2_rx_clk_3_int), + .qsfp2_rx_rst_3(qsfp2_rx_rst_3_int), + .qsfp2_rxd_3(qsfp2_rxd_3_int), + .qsfp2_rxc_3(qsfp2_rxc_3_int), + .qsfp2_tx_clk_4(qsfp2_tx_clk_4_int), + .qsfp2_tx_rst_4(qsfp2_tx_rst_4_int), + .qsfp2_txd_4(qsfp2_txd_4_int), + .qsfp2_txc_4(qsfp2_txc_4_int), + .qsfp2_rx_clk_4(qsfp2_rx_clk_4_int), + .qsfp2_rx_rst_4(qsfp2_rx_rst_4_int), + .qsfp2_rxd_4(qsfp2_rxd_4_int), + .qsfp2_rxc_4(qsfp2_rxc_4_int), + /* + * Ethernet: 1000BASE-T SGMII + */ + .phy_gmii_clk(phy_gmii_clk_int), + .phy_gmii_rst(phy_gmii_rst_int), + .phy_gmii_clk_en(phy_gmii_clk_en_int), + .phy_gmii_rxd(phy_gmii_rxd_int), + .phy_gmii_rx_dv(phy_gmii_rx_dv_int), + .phy_gmii_rx_er(phy_gmii_rx_er_int), + .phy_gmii_txd(phy_gmii_txd_int), + .phy_gmii_tx_en(phy_gmii_tx_en_int), + .phy_gmii_tx_er(phy_gmii_tx_er_int), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts_int) +); + +endmodule diff --git a/example/VCU118/fpga_25g/rtl/fpga_core.v b/example/VCU118/fpga_25g/rtl/fpga_core.v new file mode 100644 index 000000000..a523e3afd --- /dev/null +++ b/example/VCU118/fpga_25g/rtl/fpga_core.v @@ -0,0 +1,908 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [3:0] sw, + output wire [7:0] led, + + /* + * Ethernet: QSFP28 + */ + input wire qsfp1_tx_clk_1, + input wire qsfp1_tx_rst_1, + output wire [63:0] qsfp1_txd_1, + output wire [7:0] qsfp1_txc_1, + input wire qsfp1_rx_clk_1, + input wire qsfp1_rx_rst_1, + input wire [63:0] qsfp1_rxd_1, + input wire [7:0] qsfp1_rxc_1, + input wire qsfp1_tx_clk_2, + input wire qsfp1_tx_rst_2, + output wire [63:0] qsfp1_txd_2, + output wire [7:0] qsfp1_txc_2, + input wire qsfp1_rx_clk_2, + input wire qsfp1_rx_rst_2, + input wire [63:0] qsfp1_rxd_2, + input wire [7:0] qsfp1_rxc_2, + input wire qsfp1_tx_clk_3, + input wire qsfp1_tx_rst_3, + output wire [63:0] qsfp1_txd_3, + output wire [7:0] qsfp1_txc_3, + input wire qsfp1_rx_clk_3, + input wire qsfp1_rx_rst_3, + input wire [63:0] qsfp1_rxd_3, + input wire [7:0] qsfp1_rxc_3, + input wire qsfp1_tx_clk_4, + input wire qsfp1_tx_rst_4, + output wire [63:0] qsfp1_txd_4, + output wire [7:0] qsfp1_txc_4, + input wire qsfp1_rx_clk_4, + input wire qsfp1_rx_rst_4, + input wire [63:0] qsfp1_rxd_4, + input wire [7:0] qsfp1_rxc_4, + input wire qsfp2_tx_clk_1, + input wire qsfp2_tx_rst_1, + output wire [63:0] qsfp2_txd_1, + output wire [7:0] qsfp2_txc_1, + input wire qsfp2_rx_clk_1, + input wire qsfp2_rx_rst_1, + input wire [63:0] qsfp2_rxd_1, + input wire [7:0] qsfp2_rxc_1, + input wire qsfp2_tx_clk_2, + input wire qsfp2_tx_rst_2, + output wire [63:0] qsfp2_txd_2, + output wire [7:0] qsfp2_txc_2, + input wire qsfp2_rx_clk_2, + input wire qsfp2_rx_rst_2, + input wire [63:0] qsfp2_rxd_2, + input wire [7:0] qsfp2_rxc_2, + input wire qsfp2_tx_clk_3, + input wire qsfp2_tx_rst_3, + output wire [63:0] qsfp2_txd_3, + output wire [7:0] qsfp2_txc_3, + input wire qsfp2_rx_clk_3, + input wire qsfp2_rx_rst_3, + input wire [63:0] qsfp2_rxd_3, + input wire [7:0] qsfp2_rxc_3, + input wire qsfp2_tx_clk_4, + input wire qsfp2_tx_rst_4, + output wire [63:0] qsfp2_txd_4, + output wire [7:0] qsfp2_txc_4, + input wire qsfp2_rx_clk_4, + input wire qsfp2_rx_rst_4, + input wire [63:0] qsfp2_rxd_4, + input wire [7:0] qsfp2_rxc_4, + + /* + * Ethernet: 1000BASE-T SGMII + */ + input wire phy_gmii_clk, + input wire phy_gmii_rst, + input wire phy_gmii_clk_en, + input wire [7:0] phy_gmii_rxd, + input wire phy_gmii_rx_dv, + input wire phy_gmii_rx_er, + output wire [7:0] phy_gmii_txd, + output wire phy_gmii_tx_en, + output wire phy_gmii_tx_er, + output wire phy_reset_n, + input wire phy_int_n, + + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + output wire uart_rts, + input wire uart_cts +); + +// AXI between MAC and Ethernet modules +wire [63:0] mac_rx_axis_tdata; +wire [7:0] mac_rx_axis_tkeep; +wire mac_rx_axis_tvalid; +wire mac_rx_axis_tready; +wire mac_rx_axis_tlast; +wire mac_rx_axis_tuser; + +wire [63:0] mac_tx_axis_tdata; +wire [7:0] mac_tx_axis_tkeep; +wire mac_tx_axis_tvalid; +wire mac_tx_axis_tready; +wire mac_tx_axis_tlast; +wire mac_tx_axis_tuser; + +wire [63:0] rx_axis_tdata; +wire [7:0] rx_axis_tkeep; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [63:0] tx_axis_tdata; +wire [7:0] tx_axis_tkeep; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [63:0] rx_eth_payload_axis_tdata; +wire [7:0] rx_eth_payload_axis_tkeep; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [63:0] tx_eth_payload_axis_tdata; +wire [7:0] tx_eth_payload_axis_tkeep; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [63:0] rx_ip_payload_axis_tdata; +wire [7:0] rx_ip_payload_axis_tkeep; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [63:0] tx_ip_payload_axis_tdata; +wire [7:0] tx_ip_payload_axis_tkeep; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [63:0] rx_udp_payload_axis_tdata; +wire [7:0] rx_udp_payload_axis_tkeep; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [63:0] tx_udp_payload_axis_tdata; +wire [7:0] tx_udp_payload_axis_tkeep; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; + +wire [63:0] rx_fifo_udp_payload_axis_tdata; +wire [7:0] rx_fifo_udp_payload_axis_tkeep; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; + +wire [63:0] tx_fifo_udp_payload_axis_tdata; +wire [7:0] tx_fifo_udp_payload_axis_tkeep; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_axis_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tkeep = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = !match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk) begin + if (rst) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; + +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; + +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg [7:0] led_reg = 0; + +always @(posedge clk) begin + if (rst) begin + led_reg <= 0; + end else begin + valid_last <= tx_udp_payload_axis_tvalid; + if (tx_udp_payload_axis_tvalid && !valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; + end + end +end + +//assign led = sw; +assign led = led_reg; +assign phy_reset_n = !rst; + +assign qsfp1_txd_2 = 64'h0707070707070707; +assign qsfp1_txc_2 = 8'hff; +assign qsfp1_txd_3 = 64'h0707070707070707; +assign qsfp1_txc_3 = 8'hff; +assign qsfp1_txd_4 = 64'h0707070707070707; +assign qsfp1_txc_4 = 8'hff; + +assign qsfp2_txd_1 = 64'h0707070707070707; +assign qsfp2_txc_1 = 8'hff; +assign qsfp2_txd_2 = 64'h0707070707070707; +assign qsfp2_txc_2 = 8'hff; +assign qsfp2_txd_3 = 64'h0707070707070707; +assign qsfp2_txc_3 = 8'hff; +assign qsfp2_txd_4 = 64'h0707070707070707; +assign qsfp2_txc_4 = 8'hff; + +eth_mac_10g_fifo #( + .ENABLE_PADDING(1), + .ENABLE_DIC(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(9), + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(9), + .RX_FRAME_FIFO(1) +) +eth_mac_10g_fifo_inst ( + .rx_clk(qsfp1_rx_clk_1), + .rx_rst(qsfp1_rx_rst_1), + .tx_clk(qsfp1_tx_clk_1), + .tx_rst(qsfp1_tx_rst_1), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(mac_tx_axis_tdata), + .tx_axis_tkeep(mac_tx_axis_tkeep), + .tx_axis_tvalid(mac_tx_axis_tvalid), + .tx_axis_tready(mac_tx_axis_tready), + .tx_axis_tlast(mac_tx_axis_tlast), + .tx_axis_tuser(mac_tx_axis_tuser), + + .rx_axis_tdata(mac_rx_axis_tdata), + .rx_axis_tkeep(mac_rx_axis_tkeep), + .rx_axis_tvalid(mac_rx_axis_tvalid), + .rx_axis_tready(mac_rx_axis_tready), + .rx_axis_tlast(mac_rx_axis_tlast), + .rx_axis_tuser(mac_rx_axis_tuser), + + .xgmii_rxd(qsfp1_rxd_1), + .xgmii_rxc(qsfp1_rxc_1), + .xgmii_txd(qsfp1_txd_1), + .xgmii_txc(qsfp1_txc_1), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + .ifg_delay(8'd12) +); + +// 1G interface for debugging +wire [7:0] gig_rx_axis_tdata; +wire gig_rx_axis_tvalid; +wire gig_rx_axis_tready; +wire gig_rx_axis_tlast; +wire gig_rx_axis_tuser; + +wire [7:0] gig_tx_axis_tdata; +wire gig_tx_axis_tvalid; +wire gig_tx_axis_tready; +wire gig_tx_axis_tlast; +wire gig_tx_axis_tuser; + +wire [63:0] gig_rx_axis_tdata_64; +wire [7:0] gig_rx_axis_tkeep_64; +wire gig_rx_axis_tvalid_64; +wire gig_rx_axis_tready_64; +wire gig_rx_axis_tlast_64; +wire gig_rx_axis_tuser_64; + +wire [63:0] gig_tx_axis_tdata_64; +wire [7:0] gig_tx_axis_tkeep_64; +wire gig_tx_axis_tvalid_64; +wire gig_tx_axis_tready_64; +wire gig_tx_axis_tlast_64; +wire gig_tx_axis_tuser_64; + +eth_mac_1g_fifo #( + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(12), + .TX_FRAME_FIFO(1), + .RX_FIFO_ADDR_WIDTH(12), + .RX_FRAME_FIFO(1) +) +eth_mac_1g_inst ( + .rx_clk(phy_gmii_clk), + .rx_rst(phy_gmii_rst), + .tx_clk(phy_gmii_clk), + .tx_rst(phy_gmii_rst), + .logic_clk(clk), + .logic_rst(rst), + + .tx_axis_tdata(gig_tx_axis_tdata), + .tx_axis_tvalid(gig_tx_axis_tvalid), + .tx_axis_tready(gig_tx_axis_tready), + .tx_axis_tlast(gig_tx_axis_tlast), + .tx_axis_tuser(gig_tx_axis_tuser), + + .rx_axis_tdata(gig_rx_axis_tdata), + .rx_axis_tvalid(gig_rx_axis_tvalid), + .rx_axis_tready(gig_rx_axis_tready), + .rx_axis_tlast(gig_rx_axis_tlast), + .rx_axis_tuser(gig_rx_axis_tuser), + + .gmii_rxd(phy_gmii_rxd), + .gmii_rx_dv(phy_gmii_rx_dv), + .gmii_rx_er(phy_gmii_rx_er), + .gmii_txd(phy_gmii_txd), + .gmii_tx_en(phy_gmii_tx_en), + .gmii_tx_er(phy_gmii_tx_er), + + .rx_clk_enable(phy_gmii_clk_en), + .tx_clk_enable(phy_gmii_clk_en), + .rx_mii_select(1'b0), + .tx_mii_select(1'b0), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + .ifg_delay(12) +); + +axis_adapter #( + .S_DATA_WIDTH(8), + .M_DATA_WIDTH(64), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) +) +gig_rx_axis_adapter_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(gig_rx_axis_tdata), + .s_axis_tkeep(1'b1), + .s_axis_tvalid(gig_rx_axis_tvalid), + .s_axis_tready(gig_rx_axis_tready), + .s_axis_tlast(gig_rx_axis_tlast), + .s_axis_tuser(gig_rx_axis_tuser), + // AXI output + .m_axis_tdata(gig_rx_axis_tdata_64), + .m_axis_tkeep(gig_rx_axis_tkeep_64), + .m_axis_tvalid(gig_rx_axis_tvalid_64), + .m_axis_tready(gig_rx_axis_tready_64), + .m_axis_tlast(gig_rx_axis_tlast_64), + .m_axis_tuser(gig_rx_axis_tuser_64) +); + +axis_adapter #( + .S_DATA_WIDTH(64), + .M_DATA_WIDTH(8), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1) +) +gig_tx_axis_adapter_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(gig_tx_axis_tdata_64), + .s_axis_tkeep(gig_tx_axis_tkeep_64), + .s_axis_tvalid(gig_tx_axis_tvalid_64), + .s_axis_tready(gig_tx_axis_tready_64), + .s_axis_tlast(gig_tx_axis_tlast_64), + .s_axis_tuser(gig_tx_axis_tuser_64), + // AXI output + .m_axis_tdata(gig_tx_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(gig_tx_axis_tvalid), + .m_axis_tready(gig_tx_axis_tready), + .m_axis_tlast(gig_tx_axis_tlast), + .m_axis_tuser(gig_tx_axis_tuser) +); + +// tap port mux logic +// sw[3] enable +// sw[2] select 0 rx, 1 tx + +reg [1:0] mac_rx_tdest; +reg [1:0] tx_tdest; +reg [1:0] gig_rx_tdest; + +always @* begin + if (sw[3]) begin + if (sw[2]) begin + // Tap on TX path + // MAC RX out -> stack RX in + // stack TX out -> gig TX in + // gig RX out -> MAC TX in + mac_rx_tdest = 2'd1; + tx_tdest = 2'd2; + gig_rx_tdest = 2'd0; + end else begin + // Tap on RX path + // MAC RX out -> gig TX in + // stack TX out -> MAC TX in + // gig RX out -> stack RX in + mac_rx_tdest = 2'd2; + tx_tdest = 2'd0; + gig_rx_tdest = 2'd1; + end + end else begin + // Tap disabled + // MAC RX out -> stack RX in + // stack TX out -> MAC TX in + // gig RX out -> blackhole + mac_rx_tdest = 2'd1; + tx_tdest = 2'd0; + gig_rx_tdest = 2'd3; + end +end + +axis_switch #( + .S_COUNT(3), + .M_COUNT(3), + .DATA_WIDTH(64), + .KEEP_WIDTH(8), + .ID_ENABLE(0), + .DEST_WIDTH(2), + .USER_ENABLE(1), + .USER_WIDTH(1), + .M_BASE({2'd2, 2'd1, 2'd0}), + .M_TOP({2'd2, 2'd1, 2'd0}), + .M_CONNECT({3{3'b111}}), + .S_REG_TYPE(0), + .M_REG_TYPE(1), + .ARB_TYPE("PRIORITY"), + .LSB_PRIORITY("HIGH") +) +axis_switch_inst ( + .clk(clk), + .rst(rst), + // AXI inputs + .s_axis_tdata({ gig_rx_axis_tdata_64, tx_axis_tdata, mac_rx_axis_tdata}), + .s_axis_tkeep({ gig_rx_axis_tkeep_64, tx_axis_tkeep, mac_rx_axis_tkeep}), + .s_axis_tvalid({gig_rx_axis_tvalid_64, tx_axis_tvalid, mac_rx_axis_tvalid}), + .s_axis_tready({gig_rx_axis_tready_64, tx_axis_tready, mac_rx_axis_tready}), + .s_axis_tlast({ gig_rx_axis_tlast_64, tx_axis_tlast, mac_rx_axis_tlast}), + .s_axis_tid(0), + .s_axis_tdest({ gig_rx_tdest, tx_tdest, mac_rx_tdest}), + .s_axis_tuser({ gig_rx_axis_tuser_64, tx_axis_tuser, mac_rx_axis_tuser}), + // AXI outputs + .m_axis_tdata({ gig_tx_axis_tdata_64, rx_axis_tdata, mac_tx_axis_tdata}), + .m_axis_tkeep({ gig_tx_axis_tkeep_64, rx_axis_tkeep, mac_tx_axis_tkeep}), + .m_axis_tvalid({gig_tx_axis_tvalid_64, rx_axis_tvalid, mac_tx_axis_tvalid}), + .m_axis_tready({gig_tx_axis_tready_64, rx_axis_tready, mac_tx_axis_tready}), + .m_axis_tlast({ gig_tx_axis_tlast_64, rx_axis_tlast, mac_tx_axis_tlast}), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser({ gig_tx_axis_tuser_64, rx_axis_tuser, mac_tx_axis_tuser}) +); + +eth_axis_rx_64 +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .s_axis_tdata(rx_axis_tdata), + .s_axis_tkeep(rx_axis_tkeep), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx_64 +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // AXI output + .m_axis_tdata(tx_axis_tdata), + .m_axis_tkeep(tx_axis_tkeep), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete_64 +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // IP frame input + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), + // IP frame output + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), + // UDP frame input + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), + // UDP frame output + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(1'b0) +); + +axis_fifo #( + .ADDR_WIDTH(10), + .DATA_WIDTH(64), + .KEEP_ENABLE(1), + .KEEP_WIDTH(8), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(0) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), + + // AXI output + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() +); + +endmodule diff --git a/example/VCU118/fpga_25g/rtl/mdio_master.v b/example/VCU118/fpga_25g/rtl/mdio_master.v new file mode 100644 index 000000000..1dc56a8cf --- /dev/null +++ b/example/VCU118/fpga_25g/rtl/mdio_master.v @@ -0,0 +1,225 @@ +/* + +Copyright (c) 2015-2018 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 + +/* + * MDIO master + */ +module mdio_master ( + input wire clk, + input wire rst, + + /* + * Host interface + */ + input wire [4:0] cmd_phy_addr, + input wire [4:0] cmd_reg_addr, + input wire [15:0] cmd_data, + input wire [1:0] cmd_opcode, + input wire cmd_valid, + output wire cmd_ready, + + output wire [15:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + + /* + * MDIO to PHY + */ + output wire mdc_o, + input wire mdio_i, + output wire mdio_o, + output wire mdio_t, + + /* + * Status + */ + output wire busy, + + /* + * Configuration + */ + input wire [7:0] prescale +); + +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PREAMBLE = 2'd1, + STATE_TRANSFER = 2'd2; + +reg [1:0] state_reg = STATE_IDLE, state_next; + +reg [16:0] count_reg = 16'd0, count_next; +reg [6:0] bit_count_reg = 6'd0, bit_count_next; +reg cycle_reg = 1'b0, cycle_next; + +reg [31:0] data_reg = 32'd0, data_next; + +reg [1:0] op_reg = 2'b00, op_next; + +reg cmd_ready_reg = 1'b0, cmd_ready_next; + +reg [15:0] data_out_reg = 15'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; + +reg mdio_i_reg = 1'b1; + +reg mdc_o_reg = 1'b0, mdc_o_next; +reg mdio_o_reg = 1'b0, mdio_o_next; +reg mdio_t_reg = 1'b1, mdio_t_next; + +reg busy_reg = 1'b0; + +assign cmd_ready = cmd_ready_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; + +assign mdc_o = mdc_o_reg; +assign mdio_o = mdio_o_reg; +assign mdio_t = mdio_t_reg; + +assign busy = busy_reg; + +always @* begin + state_next = STATE_IDLE; + + count_next = count_reg; + bit_count_next = bit_count_reg; + cycle_next = cycle_reg; + + data_next = data_reg; + + op_next = op_reg; + + cmd_ready_next = 1'b0; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + + mdc_o_next = mdc_o_reg; + mdio_o_next = mdio_o_reg; + mdio_t_next = mdio_t_reg; + + if (count_reg > 16'd0) begin + count_next = count_reg - 16'd1; + state_next = state_reg; + end else if (cycle_reg) begin + cycle_next = 1'b0; + mdc_o_next = 1'b1; + count_next = prescale; + state_next = state_reg; + end else begin + mdc_o_next = 1'b0; + case (state_reg) + STATE_IDLE: begin + // idle - accept new command + cmd_ready_next = ~data_out_valid; + + if (cmd_ready & cmd_valid) begin + cmd_ready_next = 1'b0; + data_next = {2'b01, cmd_opcode, cmd_phy_addr, cmd_reg_addr, 2'b10, cmd_data}; + op_next = cmd_opcode; + mdio_t_next = 1'b0; + mdio_o_next = 1'b1; + bit_count_next = 6'd32; + cycle_next = 1'b1; + count_next = prescale; + state_next = STATE_PREAMBLE; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PREAMBLE: begin + cycle_next = 1'b1; + count_next = prescale; + if (bit_count_reg > 6'd1) begin + bit_count_next = bit_count_reg - 6'd1; + state_next = STATE_PREAMBLE; + end else begin + bit_count_next = 6'd32; + {mdio_o_next, data_next} = {data_reg, mdio_i_reg}; + state_next = STATE_TRANSFER; + end + end + STATE_TRANSFER: begin + cycle_next = 1'b1; + count_next = prescale; + if ((op_reg == 2'b10 || op_reg == 2'b11) && bit_count_reg == 6'd19) begin + mdio_t_next = 1'b1; + end + if (bit_count_reg > 6'd1) begin + bit_count_next = bit_count_reg - 6'd1; + {mdio_o_next, data_next} = {data_reg, mdio_i_reg}; + state_next = STATE_TRANSFER; + end else begin + if (op_reg == 2'b10 || op_reg == 2'b11) begin + data_out_next = data_reg[15:0]; + data_out_valid_next = 1'b1; + end + mdio_t_next = 1'b1; + state_next = STATE_IDLE; + end + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + count_reg <= 16'd0; + bit_count_reg <= 6'd0; + cycle_reg <= 1'b0; + cmd_ready_reg <= 1'b0; + data_out_valid_reg <= 1'b0; + mdc_o_reg <= 1'b0; + mdio_o_reg <= 1'b0; + mdio_t_reg <= 1'b1; + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + count_reg <= count_next; + bit_count_reg <= bit_count_next; + cycle_reg <= cycle_next; + cmd_ready_reg <= cmd_ready_next; + data_out_valid_reg <= data_out_valid_next; + mdc_o_reg <= mdc_o_next; + mdio_o_reg <= mdio_o_next; + mdio_t_reg <= mdio_t_next; + busy_reg <= (state_next != STATE_IDLE || count_reg != 0 || cycle_reg || mdc_o); + end + + data_reg <= data_next; + op_reg <= op_next; + + data_out_reg <= data_out_next; + + mdio_i_reg <= mdio_i; +end + +endmodule diff --git a/example/VCU118/fpga_25g/rtl/sync_reset.v b/example/VCU118/fpga_25g/rtl/sync_reset.v new file mode 100644 index 000000000..acbcf1c6e --- /dev/null +++ b/example/VCU118/fpga_25g/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk or posedge rst) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/VCU118/fpga_25g/rtl/sync_signal.v b/example/VCU118/fpga_25g/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/example/VCU118/fpga_25g/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2018 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 + +/* + * Synchronizes an asyncronous signal to a given clock by using a pipeline of + * two registers. + */ +module sync_signal #( + parameter WIDTH=1, // width of the input and output signals + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire [WIDTH-1:0] in, + output wire [WIDTH-1:0] out +); + +reg [WIDTH-1:0] sync_reg[N-1:0]; + +/* + * The synchronized output is the last register in the pipeline. + */ +assign out = sync_reg[N-1]; + +integer k; + +always @(posedge clk) begin + sync_reg[0] <= in; + for (k = 1; k < N; k = k + 1) begin + sync_reg[k] <= sync_reg[k-1]; + end +end + +endmodule diff --git a/example/VCU118/fpga_25g/tb/arp_ep.py b/example/VCU118/fpga_25g/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/example/VCU118/fpga_25g/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_25g/tb/axis_ep.py b/example/VCU118/fpga_25g/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/example/VCU118/fpga_25g/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_25g/tb/eth_ep.py b/example/VCU118/fpga_25g/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/example/VCU118/fpga_25g/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_25g/tb/gmii_ep.py b/example/VCU118/fpga_25g/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/example/VCU118/fpga_25g/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_25g/tb/ip_ep.py b/example/VCU118/fpga_25g/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/example/VCU118/fpga_25g/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_25g/tb/test_fpga_core.py b/example/VCU118/fpga_25g/tb/test_fpga_core.py new file mode 100755 index 000000000..00ed0dd0c --- /dev/null +++ b/example/VCU118/fpga_25g/tb/test_fpga_core.py @@ -0,0 +1,689 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016-2018 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 + +import eth_ep +import arp_ep +import udp_ep +import gmii_ep +import xgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") +srcs.append("../lib/eth/rtl/arp_64.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") +srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_adapter.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_switch.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_register.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[4:]) + qsfp1_tx_clk_1 = Signal(bool(0)) + qsfp1_tx_rst_1 = Signal(bool(0)) + qsfp1_rx_clk_1 = Signal(bool(0)) + qsfp1_rx_rst_1 = Signal(bool(0)) + qsfp1_rxd_1 = Signal(intbv(0)[64:]) + qsfp1_rxc_1 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_2 = Signal(bool(0)) + qsfp1_tx_rst_2 = Signal(bool(0)) + qsfp1_rx_clk_2 = Signal(bool(0)) + qsfp1_rx_rst_2 = Signal(bool(0)) + qsfp1_rxd_2 = Signal(intbv(0)[64:]) + qsfp1_rxc_2 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_3 = Signal(bool(0)) + qsfp1_tx_rst_3 = Signal(bool(0)) + qsfp1_rx_clk_3 = Signal(bool(0)) + qsfp1_rx_rst_3 = Signal(bool(0)) + qsfp1_rxd_3 = Signal(intbv(0)[64:]) + qsfp1_rxc_3 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_4 = Signal(bool(0)) + qsfp1_tx_rst_4 = Signal(bool(0)) + qsfp1_rx_clk_4 = Signal(bool(0)) + qsfp1_rx_rst_4 = Signal(bool(0)) + qsfp1_rxd_4 = Signal(intbv(0)[64:]) + qsfp1_rxc_4 = Signal(intbv(0)[8:]) + qsfp2_tx_clk_1 = Signal(bool(0)) + qsfp2_tx_rst_1 = Signal(bool(0)) + qsfp2_rx_clk_1 = Signal(bool(0)) + qsfp2_rx_rst_1 = Signal(bool(0)) + qsfp2_rxd_1 = Signal(intbv(0)[64:]) + qsfp2_rxc_1 = Signal(intbv(0)[8:]) + qsfp2_tx_clk_2 = Signal(bool(0)) + qsfp2_tx_rst_2 = Signal(bool(0)) + qsfp2_rx_clk_2 = Signal(bool(0)) + qsfp2_rx_rst_2 = Signal(bool(0)) + qsfp2_rxd_2 = Signal(intbv(0)[64:]) + qsfp2_rxc_2 = Signal(intbv(0)[8:]) + qsfp2_tx_clk_3 = Signal(bool(0)) + qsfp2_tx_rst_3 = Signal(bool(0)) + qsfp2_rx_clk_3 = Signal(bool(0)) + qsfp2_rx_rst_3 = Signal(bool(0)) + qsfp2_rxd_3 = Signal(intbv(0)[64:]) + qsfp2_rxc_3 = Signal(intbv(0)[8:]) + qsfp2_tx_clk_4 = Signal(bool(0)) + qsfp2_tx_rst_4 = Signal(bool(0)) + qsfp2_rx_clk_4 = Signal(bool(0)) + qsfp2_rx_rst_4 = Signal(bool(0)) + qsfp2_rxd_4 = Signal(intbv(0)[64:]) + qsfp2_rxc_4 = Signal(intbv(0)[8:]) + phy_gmii_clk = Signal(bool(0)) + phy_gmii_rst = Signal(bool(0)) + phy_gmii_clk_en = Signal(bool(0)) + phy_gmii_rxd = Signal(intbv(0)[8:]) + phy_gmii_rx_dv = Signal(bool(0)) + phy_gmii_rx_er = Signal(bool(0)) + phy_int_n = Signal(bool(1)) + uart_rxd = Signal(bool(0)) + uart_cts = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[8:]) + qsfp1_txd_1 = Signal(intbv(0)[64:]) + qsfp1_txc_1 = Signal(intbv(0)[8:]) + qsfp1_txd_2 = Signal(intbv(0)[64:]) + qsfp1_txc_2 = Signal(intbv(0)[8:]) + qsfp1_txd_3 = Signal(intbv(0)[64:]) + qsfp1_txc_3 = Signal(intbv(0)[8:]) + qsfp1_txd_4 = Signal(intbv(0)[64:]) + qsfp1_txc_4 = Signal(intbv(0)[8:]) + qsfp2_txd_1 = Signal(intbv(0)[64:]) + qsfp2_txc_1 = Signal(intbv(0)[8:]) + qsfp2_txd_2 = Signal(intbv(0)[64:]) + qsfp2_txc_2 = Signal(intbv(0)[8:]) + qsfp2_txd_3 = Signal(intbv(0)[64:]) + qsfp2_txc_3 = Signal(intbv(0)[8:]) + qsfp2_txd_4 = Signal(intbv(0)[64:]) + qsfp2_txc_4 = Signal(intbv(0)[8:]) + phy_gmii_txd = Signal(intbv(0)[8:]) + phy_gmii_tx_en = Signal(bool(0)) + phy_gmii_tx_er = Signal(bool(0)) + phy_reset_n = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + + # sources and sinks + qsfp1_1_source = xgmii_ep.XGMIISource() + qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') + + qsfp1_1_sink = xgmii_ep.XGMIISink() + qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') + + qsfp1_2_source = xgmii_ep.XGMIISource() + qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') + + qsfp1_2_sink = xgmii_ep.XGMIISink() + qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') + + qsfp1_3_source = xgmii_ep.XGMIISource() + qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') + + qsfp1_3_sink = xgmii_ep.XGMIISink() + qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') + + qsfp1_4_source = xgmii_ep.XGMIISource() + qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') + + qsfp1_4_sink = xgmii_ep.XGMIISink() + qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') + + qsfp2_1_source = xgmii_ep.XGMIISource() + qsfp2_1_source_logic = qsfp2_1_source.create_logic(qsfp2_rx_clk_1, qsfp2_rx_rst_1, txd=qsfp2_rxd_1, txc=qsfp2_rxc_1, name='qsfp2_1_source') + + qsfp2_1_sink = xgmii_ep.XGMIISink() + qsfp2_1_sink_logic = qsfp2_1_sink.create_logic(qsfp2_tx_clk_1, qsfp2_tx_rst_1, rxd=qsfp2_txd_1, rxc=qsfp2_txc_1, name='qsfp2_1_sink') + + qsfp2_2_source = xgmii_ep.XGMIISource() + qsfp2_2_source_logic = qsfp2_2_source.create_logic(qsfp2_rx_clk_2, qsfp2_rx_rst_2, txd=qsfp2_rxd_2, txc=qsfp2_rxc_2, name='qsfp2_2_source') + + qsfp2_2_sink = xgmii_ep.XGMIISink() + qsfp2_2_sink_logic = qsfp2_2_sink.create_logic(qsfp2_tx_clk_2, qsfp2_tx_rst_2, rxd=qsfp2_txd_2, rxc=qsfp2_txc_2, name='qsfp2_2_sink') + + qsfp2_3_source = xgmii_ep.XGMIISource() + qsfp2_3_source_logic = qsfp2_3_source.create_logic(qsfp2_rx_clk_3, qsfp2_rx_rst_3, txd=qsfp2_rxd_3, txc=qsfp2_rxc_3, name='qsfp2_3_source') + + qsfp2_3_sink = xgmii_ep.XGMIISink() + qsfp2_3_sink_logic = qsfp2_3_sink.create_logic(qsfp2_tx_clk_3, qsfp2_tx_rst_3, rxd=qsfp2_txd_3, rxc=qsfp2_txc_3, name='qsfp2_3_sink') + + qsfp2_4_source = xgmii_ep.XGMIISource() + qsfp2_4_source_logic = qsfp2_4_source.create_logic(qsfp2_rx_clk_4, qsfp2_rx_rst_4, txd=qsfp2_rxd_4, txc=qsfp2_rxc_4, name='qsfp2_4_source') + + qsfp2_4_sink = xgmii_ep.XGMIISink() + qsfp2_4_sink_logic = qsfp2_4_sink.create_logic(qsfp2_tx_clk_4, qsfp2_tx_rst_4, rxd=qsfp2_txd_4, rxc=qsfp2_txc_4, name='qsfp2_4_sink') + + gmii_source = gmii_ep.GMIISource() + + gmii_source_logic = gmii_source.create_logic( + phy_gmii_clk, + phy_gmii_rst, + txd=phy_gmii_rxd, + tx_en=phy_gmii_rx_dv, + tx_er=phy_gmii_rx_er, + clk_enable=phy_gmii_clk_en, + name='gmii_source' + ) + + gmii_sink = gmii_ep.GMIISink() + + gmii_sink_logic = gmii_sink.create_logic( + phy_gmii_clk, + phy_gmii_rst, + rxd=phy_gmii_txd, + rx_dv=phy_gmii_tx_en, + rx_er=phy_gmii_tx_er, + clk_enable=phy_gmii_clk_en, + name='gmii_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, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, + + qsfp1_tx_clk_1=qsfp1_tx_clk_1, + qsfp1_tx_rst_1=qsfp1_tx_rst_1, + qsfp1_txd_1=qsfp1_txd_1, + qsfp1_txc_1=qsfp1_txc_1, + qsfp1_rx_clk_1=qsfp1_rx_clk_1, + qsfp1_rx_rst_1=qsfp1_rx_rst_1, + qsfp1_rxd_1=qsfp1_rxd_1, + qsfp1_rxc_1=qsfp1_rxc_1, + qsfp1_tx_clk_2=qsfp1_tx_clk_2, + qsfp1_tx_rst_2=qsfp1_tx_rst_2, + qsfp1_txd_2=qsfp1_txd_2, + qsfp1_txc_2=qsfp1_txc_2, + qsfp1_rx_clk_2=qsfp1_rx_clk_2, + qsfp1_rx_rst_2=qsfp1_rx_rst_2, + qsfp1_rxd_2=qsfp1_rxd_2, + qsfp1_rxc_2=qsfp1_rxc_2, + qsfp1_tx_clk_3=qsfp1_tx_clk_3, + qsfp1_tx_rst_3=qsfp1_tx_rst_3, + qsfp1_txd_3=qsfp1_txd_3, + qsfp1_txc_3=qsfp1_txc_3, + qsfp1_rx_clk_3=qsfp1_rx_clk_3, + qsfp1_rx_rst_3=qsfp1_rx_rst_3, + qsfp1_rxd_3=qsfp1_rxd_3, + qsfp1_rxc_3=qsfp1_rxc_3, + qsfp1_tx_clk_4=qsfp1_tx_clk_4, + qsfp1_tx_rst_4=qsfp1_tx_rst_4, + qsfp1_txd_4=qsfp1_txd_4, + qsfp1_txc_4=qsfp1_txc_4, + qsfp1_rx_clk_4=qsfp1_rx_clk_4, + qsfp1_rx_rst_4=qsfp1_rx_rst_4, + qsfp1_rxd_4=qsfp1_rxd_4, + qsfp1_rxc_4=qsfp1_rxc_4, + qsfp2_tx_clk_1=qsfp2_tx_clk_1, + qsfp2_tx_rst_1=qsfp2_tx_rst_1, + qsfp2_txd_1=qsfp2_txd_1, + qsfp2_txc_1=qsfp2_txc_1, + qsfp2_rx_clk_1=qsfp2_rx_clk_1, + qsfp2_rx_rst_1=qsfp2_rx_rst_1, + qsfp2_rxd_1=qsfp2_rxd_1, + qsfp2_rxc_1=qsfp2_rxc_1, + qsfp2_tx_clk_2=qsfp2_tx_clk_2, + qsfp2_tx_rst_2=qsfp2_tx_rst_2, + qsfp2_txd_2=qsfp2_txd_2, + qsfp2_txc_2=qsfp2_txc_2, + qsfp2_rx_clk_2=qsfp2_rx_clk_2, + qsfp2_rx_rst_2=qsfp2_rx_rst_2, + qsfp2_rxd_2=qsfp2_rxd_2, + qsfp2_rxc_2=qsfp2_rxc_2, + qsfp2_tx_clk_3=qsfp2_tx_clk_3, + qsfp2_tx_rst_3=qsfp2_tx_rst_3, + qsfp2_txd_3=qsfp2_txd_3, + qsfp2_txc_3=qsfp2_txc_3, + qsfp2_rx_clk_3=qsfp2_rx_clk_3, + qsfp2_rx_rst_3=qsfp2_rx_rst_3, + qsfp2_rxd_3=qsfp2_rxd_3, + qsfp2_rxc_3=qsfp2_rxc_3, + qsfp2_tx_clk_4=qsfp2_tx_clk_4, + qsfp2_tx_rst_4=qsfp2_tx_rst_4, + qsfp2_txd_4=qsfp2_txd_4, + qsfp2_txc_4=qsfp2_txc_4, + qsfp2_rx_clk_4=qsfp2_rx_clk_4, + qsfp2_rx_rst_4=qsfp2_rx_rst_4, + qsfp2_rxd_4=qsfp2_rxd_4, + qsfp2_rxc_4=qsfp2_rxc_4, + + phy_gmii_clk=phy_gmii_clk, + phy_gmii_rst=phy_gmii_rst, + phy_gmii_clk_en=phy_gmii_clk_en, + phy_gmii_rxd=phy_gmii_rxd, + phy_gmii_rx_dv=phy_gmii_rx_dv, + phy_gmii_rx_er=phy_gmii_rx_er, + phy_gmii_txd=phy_gmii_txd, + phy_gmii_tx_en=phy_gmii_tx_en, + phy_gmii_tx_er=phy_gmii_tx_er, + phy_reset_n=phy_reset_n, + phy_int_n=phy_int_n, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + qsfp1_tx_clk_1.next = not qsfp1_tx_clk_1 + qsfp1_rx_clk_1.next = not qsfp1_rx_clk_1 + qsfp1_tx_clk_2.next = not qsfp1_tx_clk_2 + qsfp1_rx_clk_2.next = not qsfp1_rx_clk_2 + qsfp1_tx_clk_3.next = not qsfp1_tx_clk_3 + qsfp1_rx_clk_3.next = not qsfp1_rx_clk_3 + qsfp1_tx_clk_4.next = not qsfp1_tx_clk_4 + qsfp1_rx_clk_4.next = not qsfp1_rx_clk_4 + qsfp2_tx_clk_1.next = not qsfp2_tx_clk_1 + qsfp2_rx_clk_1.next = not qsfp2_rx_clk_1 + qsfp2_tx_clk_2.next = not qsfp2_tx_clk_2 + qsfp2_rx_clk_2.next = not qsfp2_rx_clk_2 + qsfp2_tx_clk_3.next = not qsfp2_tx_clk_3 + qsfp2_rx_clk_3.next = not qsfp2_rx_clk_3 + qsfp2_tx_clk_4.next = not qsfp2_tx_clk_4 + qsfp2_rx_clk_4.next = not qsfp2_rx_clk_4 + phy_gmii_clk.next = not phy_gmii_clk + + clk_enable_rate = Signal(int(0)) + clk_enable_div = Signal(int(0)) + + @always(clk.posedge) + def clk_enable_gen(): + if clk_enable_div.next > 0: + phy_gmii_clk_en.next = 0 + clk_enable_div.next = clk_enable_div - 1 + else: + phy_gmii_clk_en.next = 1 + clk_enable_div.next = clk_enable_rate - 1 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + qsfp1_tx_rst_1.next = 1 + qsfp1_rx_rst_1.next = 1 + qsfp1_tx_rst_2.next = 1 + qsfp1_rx_rst_2.next = 1 + qsfp1_tx_rst_3.next = 1 + qsfp1_rx_rst_3.next = 1 + qsfp1_tx_rst_4.next = 1 + qsfp1_rx_rst_4.next = 1 + qsfp2_tx_rst_1.next = 1 + qsfp2_rx_rst_1.next = 1 + qsfp2_tx_rst_2.next = 1 + qsfp2_rx_rst_2.next = 1 + qsfp2_tx_rst_3.next = 1 + qsfp2_rx_rst_3.next = 1 + qsfp2_tx_rst_4.next = 1 + qsfp2_rx_rst_4.next = 1 + phy_gmii_rst.next = 1 + yield clk.posedge + rst.next = 0 + qsfp1_tx_rst_1.next = 0 + qsfp1_rx_rst_1.next = 0 + qsfp1_tx_rst_2.next = 0 + qsfp1_rx_rst_2.next = 0 + qsfp1_tx_rst_3.next = 0 + qsfp1_rx_rst_3.next = 0 + qsfp1_tx_rst_4.next = 0 + qsfp1_rx_rst_4.next = 0 + qsfp2_tx_rst_1.next = 0 + qsfp2_rx_rst_1.next = 0 + qsfp2_tx_rst_2.next = 0 + qsfp2_rx_rst_2.next = 0 + qsfp2_tx_rst_3.next = 0 + qsfp2_rx_rst_3.next = 0 + qsfp2_tx_rst_4.next = 0 + qsfp2_rx_rst_4.next = 0 + phy_gmii_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + qsfp1_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while qsfp1_1_sink.empty(): + yield clk.posedge + + rx_frame = qsfp1_1_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + qsfp1_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while qsfp1_1_sink.empty(): + yield clk.posedge + + rx_frame = qsfp1_1_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert qsfp1_1_source.empty() + assert qsfp1_1_sink.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test gigabit tap") + current_test.next = 2 + + sw.next = 0x8 # enable tap on RX + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # loop packet back through on XGMII interface + while qsfp1_1_sink.empty(): + yield clk.posedge + + qsfp1_1_source.send(qsfp1_1_sink.recv()) + + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source.empty() + assert gmii_sink.empty() + assert qsfp1_1_source.empty() + assert qsfp1_1_sink.empty() + + yield delay(100) + + sw.next = 0xc # enable tap on TX + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # loop packet back through on XGMII interface + while qsfp1_1_sink.empty(): + yield clk.posedge + + qsfp1_1_source.send(qsfp1_1_sink.recv()) + + while gmii_sink.empty(): + yield clk.posedge + + rx_frame = gmii_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert gmii_source.empty() + assert gmii_sink.empty() + assert qsfp1_1_source.empty() + assert qsfp1_1_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() diff --git a/example/VCU118/fpga_25g/tb/test_fpga_core.v b/example/VCU118/fpga_25g/tb/test_fpga_core.v new file mode 100644 index 000000000..24db5dc0c --- /dev/null +++ b/example/VCU118/fpga_25g/tb/test_fpga_core.v @@ -0,0 +1,324 @@ +/* + +Copyright (c) 2016-2018 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 + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [3:0] sw = 0; +reg qsfp1_tx_clk_1 = 0; +reg qsfp1_tx_rst_1 = 0; +reg qsfp1_rx_clk_1 = 0; +reg qsfp1_rx_rst_1 = 0; +reg [63:0] qsfp1_rxd_1 = 0; +reg [7:0] qsfp1_rxc_1 = 0; +reg qsfp1_tx_clk_2 = 0; +reg qsfp1_tx_rst_2 = 0; +reg qsfp1_rx_clk_2 = 0; +reg qsfp1_rx_rst_2 = 0; +reg [63:0] qsfp1_rxd_2 = 0; +reg [7:0] qsfp1_rxc_2 = 0; +reg qsfp1_tx_clk_3 = 0; +reg qsfp1_tx_rst_3 = 0; +reg qsfp1_rx_clk_3 = 0; +reg qsfp1_rx_rst_3 = 0; +reg [63:0] qsfp1_rxd_3 = 0; +reg [7:0] qsfp1_rxc_3 = 0; +reg qsfp1_tx_clk_4 = 0; +reg qsfp1_tx_rst_4 = 0; +reg qsfp1_rx_clk_4 = 0; +reg qsfp1_rx_rst_4 = 0; +reg [63:0] qsfp1_rxd_4 = 0; +reg [7:0] qsfp1_rxc_4 = 0; +reg qsfp2_tx_clk_1 = 0; +reg qsfp2_tx_rst_1 = 0; +reg qsfp2_rx_clk_1 = 0; +reg qsfp2_rx_rst_1 = 0; +reg [63:0] qsfp2_rxd_1 = 0; +reg [7:0] qsfp2_rxc_1 = 0; +reg qsfp2_tx_clk_2 = 0; +reg qsfp2_tx_rst_2 = 0; +reg qsfp2_rx_clk_2 = 0; +reg qsfp2_rx_rst_2 = 0; +reg [63:0] qsfp2_rxd_2 = 0; +reg [7:0] qsfp2_rxc_2 = 0; +reg qsfp2_tx_clk_3 = 0; +reg qsfp2_tx_rst_3 = 0; +reg qsfp2_rx_clk_3 = 0; +reg qsfp2_rx_rst_3 = 0; +reg [63:0] qsfp2_rxd_3 = 0; +reg [7:0] qsfp2_rxc_3 = 0; +reg qsfp2_tx_clk_4 = 0; +reg qsfp2_tx_rst_4 = 0; +reg qsfp2_rx_clk_4 = 0; +reg qsfp2_rx_rst_4 = 0; +reg [63:0] qsfp2_rxd_4 = 0; +reg [7:0] qsfp2_rxc_4 = 0; +reg phy_gmii_clk = 0; +reg phy_gmii_rst = 0; +reg phy_gmii_clk_en = 0; +reg [7:0] phy_gmii_rxd = 0; +reg phy_gmii_rx_dv = 0; +reg phy_gmii_rx_er = 0; +reg phy_int_n = 1; +reg uart_rxd = 0; +reg uart_cts = 0; + +// Outputs +wire [7:0] led; +wire [63:0] qsfp1_txd_1; +wire [7:0] qsfp1_txc_1; +wire [63:0] qsfp1_txd_2; +wire [7:0] qsfp1_txc_2; +wire [63:0] qsfp1_txd_3; +wire [7:0] qsfp1_txc_3; +wire [63:0] qsfp1_txd_4; +wire [7:0] qsfp1_txc_4; +wire [63:0] qsfp2_txd_1; +wire [7:0] qsfp2_txc_1; +wire [63:0] qsfp2_txd_2; +wire [7:0] qsfp2_txc_2; +wire [63:0] qsfp2_txd_3; +wire [7:0] qsfp2_txc_3; +wire [63:0] qsfp2_txd_4; +wire [7:0] qsfp2_txc_4; +wire phy_tx_clk; +wire [7:0] phy_gmii_txd; +wire phy_gmii_tx_en; +wire phy_gmii_tx_er; +wire phy_reset_n; +wire uart_txd; +wire uart_rts; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + qsfp1_tx_clk_1, + qsfp1_tx_rst_1, + qsfp1_rx_clk_1, + qsfp1_rx_rst_1, + qsfp1_rxd_1, + qsfp1_rxc_1, + qsfp1_tx_clk_2, + qsfp1_tx_rst_2, + qsfp1_rx_clk_2, + qsfp1_rx_rst_2, + qsfp1_rxd_2, + qsfp1_rxc_2, + qsfp1_tx_clk_3, + qsfp1_tx_rst_3, + qsfp1_rx_clk_3, + qsfp1_rx_rst_3, + qsfp1_rxd_3, + qsfp1_rxc_3, + qsfp1_tx_clk_4, + qsfp1_tx_rst_4, + qsfp1_rx_clk_4, + qsfp1_rx_rst_4, + qsfp1_rxd_4, + qsfp1_rxc_4, + qsfp2_tx_clk_1, + qsfp2_tx_rst_1, + qsfp2_rx_clk_1, + qsfp2_rx_rst_1, + qsfp2_rxd_1, + qsfp2_rxc_1, + qsfp2_tx_clk_2, + qsfp2_tx_rst_2, + qsfp2_rx_clk_2, + qsfp2_rx_rst_2, + qsfp2_rxd_2, + qsfp2_rxc_2, + qsfp2_tx_clk_3, + qsfp2_tx_rst_3, + qsfp2_rx_clk_3, + qsfp2_rx_rst_3, + qsfp2_rxd_3, + qsfp2_rxc_3, + qsfp2_tx_clk_4, + qsfp2_tx_rst_4, + qsfp2_rx_clk_4, + qsfp2_rx_rst_4, + qsfp2_rxd_4, + qsfp2_rxc_4, + phy_gmii_clk, + phy_gmii_rst, + phy_gmii_clk_en, + phy_gmii_rxd, + phy_gmii_rx_dv, + phy_gmii_rx_er, + phy_int_n, + uart_rxd, + uart_cts + ); + $to_myhdl( + led, + qsfp1_txd_1, + qsfp1_txc_1, + qsfp1_txd_2, + qsfp1_txc_2, + qsfp1_txd_3, + qsfp1_txc_3, + qsfp1_txd_4, + qsfp1_txc_4, + qsfp2_txd_1, + qsfp2_txc_1, + qsfp2_txd_2, + qsfp2_txc_2, + qsfp2_txd_3, + qsfp2_txc_3, + qsfp2_txd_4, + qsfp2_txc_4, + phy_gmii_txd, + phy_gmii_tx_en, + phy_gmii_tx_er, + phy_reset_n, + uart_txd, + uart_rts + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .qsfp1_tx_clk_1(qsfp1_tx_clk_1), + .qsfp1_tx_rst_1(qsfp1_tx_rst_1), + .qsfp1_txd_1(qsfp1_txd_1), + .qsfp1_txc_1(qsfp1_txc_1), + .qsfp1_rx_clk_1(qsfp1_rx_clk_1), + .qsfp1_rx_rst_1(qsfp1_rx_rst_1), + .qsfp1_rxd_1(qsfp1_rxd_1), + .qsfp1_rxc_1(qsfp1_rxc_1), + .qsfp1_tx_clk_2(qsfp1_tx_clk_2), + .qsfp1_tx_rst_2(qsfp1_tx_rst_2), + .qsfp1_txd_2(qsfp1_txd_2), + .qsfp1_txc_2(qsfp1_txc_2), + .qsfp1_rx_clk_2(qsfp1_rx_clk_2), + .qsfp1_rx_rst_2(qsfp1_rx_rst_2), + .qsfp1_rxd_2(qsfp1_rxd_2), + .qsfp1_rxc_2(qsfp1_rxc_2), + .qsfp1_tx_clk_3(qsfp1_tx_clk_3), + .qsfp1_tx_rst_3(qsfp1_tx_rst_3), + .qsfp1_txd_3(qsfp1_txd_3), + .qsfp1_txc_3(qsfp1_txc_3), + .qsfp1_rx_clk_3(qsfp1_rx_clk_3), + .qsfp1_rx_rst_3(qsfp1_rx_rst_3), + .qsfp1_rxd_3(qsfp1_rxd_3), + .qsfp1_rxc_3(qsfp1_rxc_3), + .qsfp1_tx_clk_4(qsfp1_tx_clk_4), + .qsfp1_tx_rst_4(qsfp1_tx_rst_4), + .qsfp1_txd_4(qsfp1_txd_4), + .qsfp1_txc_4(qsfp1_txc_4), + .qsfp1_rx_clk_4(qsfp1_rx_clk_4), + .qsfp1_rx_rst_4(qsfp1_rx_rst_4), + .qsfp1_rxd_4(qsfp1_rxd_4), + .qsfp1_rxc_4(qsfp1_rxc_4), + .qsfp2_tx_clk_1(qsfp2_tx_clk_1), + .qsfp2_tx_rst_1(qsfp2_tx_rst_1), + .qsfp2_txd_1(qsfp2_txd_1), + .qsfp2_txc_1(qsfp2_txc_1), + .qsfp2_rx_clk_1(qsfp2_rx_clk_1), + .qsfp2_rx_rst_1(qsfp2_rx_rst_1), + .qsfp2_rxd_1(qsfp2_rxd_1), + .qsfp2_rxc_1(qsfp2_rxc_1), + .qsfp2_tx_clk_2(qsfp2_tx_clk_2), + .qsfp2_tx_rst_2(qsfp2_tx_rst_2), + .qsfp2_txd_2(qsfp2_txd_2), + .qsfp2_txc_2(qsfp2_txc_2), + .qsfp2_rx_clk_2(qsfp2_rx_clk_2), + .qsfp2_rx_rst_2(qsfp2_rx_rst_2), + .qsfp2_rxd_2(qsfp2_rxd_2), + .qsfp2_rxc_2(qsfp2_rxc_2), + .qsfp2_tx_clk_3(qsfp2_tx_clk_3), + .qsfp2_tx_rst_3(qsfp2_tx_rst_3), + .qsfp2_txd_3(qsfp2_txd_3), + .qsfp2_txc_3(qsfp2_txc_3), + .qsfp2_rx_clk_3(qsfp2_rx_clk_3), + .qsfp2_rx_rst_3(qsfp2_rx_rst_3), + .qsfp2_rxd_3(qsfp2_rxd_3), + .qsfp2_rxc_3(qsfp2_rxc_3), + .qsfp2_tx_clk_4(qsfp2_tx_clk_4), + .qsfp2_tx_rst_4(qsfp2_tx_rst_4), + .qsfp2_txd_4(qsfp2_txd_4), + .qsfp2_txc_4(qsfp2_txc_4), + .qsfp2_rx_clk_4(qsfp2_rx_clk_4), + .qsfp2_rx_rst_4(qsfp2_rx_rst_4), + .qsfp2_rxd_4(qsfp2_rxd_4), + .qsfp2_rxc_4(qsfp2_rxc_4), + .phy_gmii_clk(phy_gmii_clk), + .phy_gmii_rst(phy_gmii_rst), + .phy_gmii_clk_en(phy_gmii_clk_en), + .phy_gmii_rxd(phy_gmii_rxd), + .phy_gmii_rx_dv(phy_gmii_rx_dv), + .phy_gmii_rx_er(phy_gmii_rx_er), + .phy_gmii_txd(phy_gmii_txd), + .phy_gmii_tx_en(phy_gmii_tx_en), + .phy_gmii_tx_er(phy_gmii_tx_er), + .phy_reset_n(phy_reset_n), + .phy_int_n(phy_int_n), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts) +); + +endmodule diff --git a/example/VCU118/fpga_25g/tb/udp_ep.py b/example/VCU118/fpga_25g/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/example/VCU118/fpga_25g/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/example/VCU118/fpga_25g/tb/xgmii_ep.py b/example/VCU118/fpga_25g/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/example/VCU118/fpga_25g/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file From 4410d7484833a8d128089ac483301b20ba8f814b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Jun 2019 23:28:15 -0700 Subject: [PATCH 599/617] Update readme --- README.md | 88 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 10613cc8a..612296390 100644 --- a/README.md +++ b/README.md @@ -6,20 +6,23 @@ GitHub repository: https://github.com/alexforencich/verilog-ethernet ## Introduction -Collection of Ethernet-related components for both gigabit and 10G packet +Collection of Ethernet-related components for gigabit, 10G, and 25G packet processing (8 bit and 64 bit datapaths). Includes modules for handling Ethernet frames as well as IP, UDP, and ARP and the components for constructing a complete UDP/IP stack. Includes MAC modules for gigabit and -10G, a 10G PCS/PMA PHY module, and a 10G combination MAC/PCS/PMA module. Also -includes full MyHDL testbench with intelligent bus cosimulation endpoints. +10G/25G, a 10G/25G PCS/PMA PHY module, and a 10G/25G combination MAC/PCS/PMA +module. Also includes full MyHDL testbench with intelligent bus cosimulation +endpoints. -For IP and ARP support only, use ip_complete (1G) or ip_complete_64 (10G). +For IP and ARP support only, use ip_complete (1G) or ip_complete_64 (10G/25G). -For UDP, IP, and ARP support, use udp_complete (1G) or udp_complete_64 (10G). +For UDP, IP, and ARP support, use udp_complete (1G) or udp_complete_64 +(10G/25G). -Top level gigabit and 10G MAC modules are eth_mac_*, with various interfaces -and with/without FIFOs. Top level 10G PCS/PMA PHY module is eth_phy_10g. Top -level 10G MAC/PCS/PMA combination module is eth_mac_phy_10g. +Top level gigabit and 10G/25G MAC modules are eth_mac_*, with various +interfaces and with/without FIFOs. Top level 10G/25G PCS/PMA PHY module is +eth_phy_10g. Top level 10G/25G MAC/PCS/PMA combination module is +eth_mac_phy_10g. ## Documentation @@ -30,7 +33,7 @@ ARP handling logic with parametrizable retry timeout parameters. ### arp_64 module ARP handling logic with parametrizable retry timeout parameters and 64 bit -datapath for 10G Ethernet. +datapath for 10G/25G Ethernet. ### arp_cache module @@ -42,7 +45,7 @@ ARP frame receiver. ### arp_eth_rx_64 module -ARP frame receiver with 64 bit datapath for 10G Ethernet. +ARP frame receiver with 64 bit datapath for 10G/25G Ethernet. ### arp_eth_tx module @@ -50,7 +53,7 @@ ARP frame transmitter. ### arp_eth_tx_64 module -ARP frame transmitter with 64 bit datapath for 10G Ethernet. +ARP frame transmitter with 64 bit datapath for 10G/25G Ethernet. ### axis_eth_fcs module @@ -58,7 +61,8 @@ Ethernet frame check sequence calculator. ### axis_eth_fcs_64 module -Ethernet frame check sequence calculator with 64 bit datapath for 10G Ethernet. +Ethernet frame check sequence calculator with 64 bit datapath for 10G/25G +Ethernet. ### axis_eth_fcs_check module @@ -103,7 +107,7 @@ Ethernet frame receiver. ### eth_axis_rx_64 module -Ethernet frame receiver with 64 bit datapath for 10G Ethernet. +Ethernet frame receiver with 64 bit datapath for 10G/25G Ethernet. ### eth_axis_tx module @@ -111,7 +115,7 @@ Ethernet frame transmitter. ### eth_axis_tx_64 module -Ethernet frame transmitter with 64 bit datapath for 10G Ethernet. +Ethernet frame transmitter with 64 bit datapath for 10G/25G Ethernet. ### eth_demux module @@ -148,13 +152,13 @@ adaptation logic. ### eth_mac_10g module -10G Ethernet MAC with XGMII interface. Datapath selectable between 32 and 64 -bits. +10G/25G Ethernet MAC with XGMII interface. Datapath selectable between 32 and +64 bits. ### eth_mac_10g_fifo module -10G Ethernet MAC with XGMII interface and FIFOs. Datapath selectable between -32 and 64 bits. +10G/25G Ethernet MAC with XGMII interface and FIFOs. Datapath selectable +between 32 and 64 bits. ### eth_mac_mii module @@ -166,19 +170,19 @@ Ethernet MAC with MII interface and FIFOs. ### eth_mac_phy_10g module -10G Ethernet MAC/PHY combination module with SERDES interface. +10G/25G Ethernet MAC/PHY combination module with SERDES interface. ### eth_mac_phy_10g_fifo module -10G Ethernet MAC/PHY combination module with SERDES interface and FIFOs. +10G/25G Ethernet MAC/PHY combination module with SERDES interface and FIFOs. ### eth_mac_phy_10g_rx module -10G Ethernet MAC/PHY combination module with SERDES interface, RX path. +10G/25G Ethernet MAC/PHY combination module with SERDES interface, RX path. ### eth_mac_phy_10g_tx module -10G Ethernet MAC/PHY combination module with SERDES interface, TX path. +10G/25G Ethernet MAC/PHY combination module with SERDES interface, TX path. ### eth_mux module @@ -187,23 +191,23 @@ Supports priority and round-robin arbitration. ### eth_phy_10g module -10G Ethernet PCS/PMA PHY. +10G/25G Ethernet PCS/PMA PHY. ### eth_phy_10g_rx module -10G Ethernet PCS/PMA PHY receive-side logic. +10G/25G Ethernet PCS/PMA PHY receive-side logic. ### eth_phy_10g_rx_ber_mon module -10G Ethernet PCS/PMA PHY BER monitor. +10G/25G Ethernet PCS/PMA PHY BER monitor. ### eth_phy_10g_rx_frame_sync module -10G Ethernet PCS/PMA PHY frame synchronizer. +10G/25G Ethernet PCS/PMA PHY frame synchronizer. ### eth_phy_10g_tx module -10G Ethernet PCS/PMA PHY transmit-side logic. +10G/25G Ethernet PCS/PMA PHY transmit-side logic. ### gmii_phy_if module @@ -216,7 +220,7 @@ transmssion and reception. Interfaces with ARP module for MAC address lookup. ### ip_64 module -IPv4 block with 64 bit data width for 10G Ethernet. Manages IPv4 packet +IPv4 block with 64 bit data width for 10G/25G Ethernet. Manages IPv4 packet transmssion and reception. Interfaces with ARP module for MAC address lookup. ### ip_arb_mux module @@ -232,9 +236,9 @@ Top level for gigabit IP stack. ### ip_complete_64 module -IPv4 module with ARP integration and 64 bit data width for 10G Ethernet. +IPv4 module with ARP integration and 64 bit data width for 10G/25G Ethernet. -Top level for 10G IP stack. +Top level for 10G/25G IP stack. ### ip_demux module @@ -247,7 +251,7 @@ IP frame receiver. ### ip_eth_rx_64 module -IP frame receiver with 64 bit datapath for 10G Ethernet. +IP frame receiver with 64 bit datapath for 10G/25G Ethernet. ### ip_eth_tx module @@ -255,7 +259,7 @@ IP frame transmitter. ### ip_eth_tx_64 module -IP frame transmitter with 64 bit datapath for 10G Ethernet. +IP frame transmitter with 64 bit datapath for 10G/25G Ethernet. ### ip_mux module @@ -287,7 +291,7 @@ transmssion and reception. ### udp_64 module -UDP block with 64 bit data width for 10G Ethernet. Manages UDP packet +UDP block with 64 bit data width for 10G/25G Ethernet. Manages UDP packet transmssion and reception. ### udp_arb_mux module @@ -316,7 +320,7 @@ Top level for gigabit UDP stack. UDP module with IPv4 and ARP integration and 64 bit data width for 10G Ethernet. -Top level for 10G UDP stack. +Top level for 10G/25G UDP stack. ### udp_demux module @@ -329,7 +333,7 @@ UDP frame receiver. ### udp_ip_rx_64 module -UDP frame receiver with 64 bit datapath for 10G Ethernet. +UDP frame receiver with 64 bit datapath for 10G/25G Ethernet. ### udp_ip_tx module @@ -337,7 +341,7 @@ UDP frame transmitter. ### udp_ip_tx_64 module -UDP frame transmitter with 64 bit datapath for 10G Ethernet. +UDP frame transmitter with 64 bit datapath for 10G/25G Ethernet. ### udp_mux module @@ -403,14 +407,14 @@ and data lines. rtl/eth_mac_1g_gmii_fifo.v : Tri-mode Ethernet GMII/MII MAC with FIFO rtl/eth_mac_1g_rgmii.v : Tri-mode Ethernet RGMII MAC rtl/eth_mac_1g_rgmii_fifo.v : Tri-mode Ethernet RGMII MAC with FIFO - rtl/eth_mac_10g.v : 10G Ethernet XGMII MAC - rtl/eth_mac_10g_fifo.v : 10G Ethernet XGMII MAC with FIFO + rtl/eth_mac_10g.v : 10G/25G Ethernet XGMII MAC + rtl/eth_mac_10g_fifo.v : 10G/25G Ethernet XGMII MAC with FIFO rtl/eth_mac_mii.v : Ethernet MII MAC rtl/eth_mac_mii_fifo.v : Ethernet MII MAC with FIFO - rtl/eth_mac_phy_10g.v : 10G Ethernet XGMII MAC/PHY - rtl/eth_mac_phy_10g_fifo.v : 10G Ethernet XGMII MAC/PHY with FIFO - rtl/eth_mac_phy_10g_rx.v : 10G Ethernet XGMII MAC/PHY RX with FIFO - rtl/eth_mac_phy_10g_tx.v : 10G Ethernet XGMII MAC/PHY TX with FIFO + rtl/eth_mac_phy_10g.v : 10G/25G Ethernet XGMII MAC/PHY + rtl/eth_mac_phy_10g_fifo.v : 10G/25G Ethernet XGMII MAC/PHY with FIFO + rtl/eth_mac_phy_10g_rx.v : 10G/25G Ethernet XGMII MAC/PHY RX with FIFO + rtl/eth_mac_phy_10g_tx.v : 10G/25G Ethernet XGMII MAC/PHY TX with FIFO rtl/eth_mux.v : Ethernet frame multiplexer rtl/gmii_phy_if.v : GMII PHY interface rtl/iddr.v : Generic DDR input register From 0927f4c326f611bfa34f83c3bb7ae4b01bb202f8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 19 Jun 2019 23:51:04 -0700 Subject: [PATCH 600/617] Fix readme --- example/VCU118/fpga_25g/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example/VCU118/fpga_25g/README.md b/example/VCU118/fpga_25g/README.md index 4e2fb8698..4d9729984 100644 --- a/example/VCU118/fpga_25g/README.md +++ b/example/VCU118/fpga_25g/README.md @@ -24,9 +24,9 @@ netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any text entered into netcat will be echoed back after pressing enter. Note that the gigabit PHY is also enabled for debugging. The gigabit port can -be inserted into the 10G data path between the 10G MAC and 10G PHY so that the -10G interface can be tested with a QSFP loopback adapter. Turn on SW12.1 to -insert the gigabit port into the 10G data path, or off to bypass the gigabit +be inserted into the 25G data path between the 25G MAC and 25G PHY so that the +25G interface can be tested with a QSFP loopback adapter. Turn on SW12.1 to +insert the gigabit port into the 25G data path, or off to bypass the gigabit port. Turn on SW12.2 to place the port in the TX path or off to place the port in the RX path. From 9e7f4a9836ef77ba814f22b5385011232a347d6b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 20 Jun 2019 18:02:15 -0700 Subject: [PATCH 601/617] Remove unused state bit --- rtl/axis_baser_rx_64.v | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rtl/axis_baser_rx_64.v b/rtl/axis_baser_rx_64.v index 93d17b397..e77fab59a 100644 --- a/rtl/axis_baser_rx_64.v +++ b/rtl/axis_baser_rx_64.v @@ -152,12 +152,12 @@ localparam [3:0] INPUT_TYPE_TERM_6 = 4'd14, INPUT_TYPE_TERM_7 = 4'd15; -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_PAYLOAD = 3'd1, - STATE_LAST = 3'd2; +localparam [1:0] + STATE_IDLE = 2'd0, + STATE_PAYLOAD = 2'd1, + STATE_LAST = 2'd2; -reg [2:0] state_reg = STATE_IDLE, state_next; +reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg reset_crc; From df04d7e68d6148389563295251242523181eb631 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 20 Jun 2019 18:10:53 -0700 Subject: [PATCH 602/617] CRC handling logic optimizations --- rtl/axis_baser_rx_64.v | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/rtl/axis_baser_rx_64.v b/rtl/axis_baser_rx_64.v index e77fab59a..533fdcfb2 100644 --- a/rtl/axis_baser_rx_64.v +++ b/rtl/axis_baser_rx_64.v @@ -161,7 +161,7 @@ reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg reset_crc; -reg update_crc; +reg update_crc_last; reg lanes_swapped = 1'b0; reg [31:0] swap_data = 32'd0; @@ -217,8 +217,6 @@ assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; assign rx_bad_block = rx_bad_block_reg; -wire last_cycle = state_reg == STATE_LAST; - lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), @@ -230,7 +228,7 @@ lfsr #( ) eth_crc_8 ( .data_in(input_data_crc[7:0]), - .state_in(last_cycle ? crc_state3 : crc_state), + .state_in(crc_state3), .data_out(), .state_out(crc_next0) ); @@ -246,7 +244,7 @@ lfsr #( ) eth_crc_16 ( .data_in(input_data_crc[15:0]), - .state_in(last_cycle ? crc_state3 : crc_state), + .state_in(crc_state3), .data_out(), .state_out(crc_next1) ); @@ -262,7 +260,7 @@ lfsr #( ) eth_crc_24 ( .data_in(input_data_crc[23:0]), - .state_in(last_cycle ? crc_state3 : crc_state), + .state_in(crc_state3), .data_out(), .state_out(crc_next2) ); @@ -278,7 +276,7 @@ lfsr #( ) eth_crc_32 ( .data_in(input_data_crc[31:0]), - .state_in(last_cycle ? crc_state3 : crc_state), + .state_in(crc_state3), .data_out(), .state_out(crc_next3) ); @@ -303,7 +301,7 @@ always @* begin state_next = STATE_IDLE; reset_crc = 1'b0; - update_crc = 1'b0; + update_crc_last = 1'b0; m_axis_tdata_next = input_data_d1; m_axis_tkeep_next = 8'd0; @@ -322,7 +320,6 @@ always @* begin if (input_type_d1 == INPUT_TYPE_START_0) begin // start condition reset_crc = 1'b0; - update_crc = 1'b1; state_next = STATE_PAYLOAD; end else begin state_next = STATE_IDLE; @@ -330,8 +327,6 @@ always @* begin end STATE_PAYLOAD: begin // read payload - update_crc = 1'b1; - m_axis_tdata_next = input_data_d1; m_axis_tkeep_next = 8'hff; m_axis_tvalid_next = 1'b1; @@ -367,6 +362,7 @@ always @* begin state_next = STATE_IDLE; end else begin // need extra cycle + update_crc_last = 1'b1; state_next = STATE_LAST; end end else begin @@ -422,7 +418,6 @@ always @(posedge clk) begin crc_state <= 32'hFFFFFFFF; crc_state3 <= 32'hFFFFFFFF; - crc_valid7_save <= 1'b0; input_type_d0 <= INPUT_TYPE_IDLE; input_type_d1 <= INPUT_TYPE_IDLE; @@ -521,12 +516,14 @@ always @(posedge clk) begin // datapath if (reset_crc) begin crc_state <= 32'hFFFFFFFF; - crc_state3 <= 32'hFFFFFFFF; - crc_valid7_save <= 1'b0; - end else if (update_crc) begin + end else begin crc_state <= crc_next7; + end + + if (update_crc_last) begin crc_state3 <= crc_next3; - crc_valid7_save <= crc_valid7; + end else begin + crc_state3 <= crc_next7; end end @@ -587,6 +584,8 @@ always @(posedge clk) begin end end + crc_valid7_save <= crc_valid7; + if (state_next == STATE_LAST) begin input_data_crc[31:0] <= input_data_crc[63:32]; end From 7cce7896b5d5d492d7537b54a4943640cbee724f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 25 Jun 2019 23:46:44 -0700 Subject: [PATCH 603/617] Update programming commands --- example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile | 6 +++--- example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile | 6 +++--- example/VCU108/fpga_10g/fpga/Makefile | 6 +++--- example/VCU108/fpga_1g/fpga/Makefile | 6 +++--- example/VCU118/fpga_10g/fpga/Makefile | 6 +++--- example/VCU118/fpga_1g/fpga/Makefile | 6 +++--- example/VCU118/fpga_25g/fpga/Makefile | 6 +++--- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile index 5c5aa8e84..5ba42c6cc 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -61,9 +61,9 @@ program: $(FPGA_TOP).bit echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl - echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl - echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl - echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl vivado -mode batch -source program.tcl diff --git a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile index 5c5aa8e84..5ba42c6cc 100644 --- a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile @@ -61,9 +61,9 @@ program: $(FPGA_TOP).bit echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl - echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl - echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl - echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl vivado -mode batch -source program.tcl diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index ef2fae0eb..6ac12d04a 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -70,9 +70,9 @@ program: $(FPGA_TOP).bit echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl - echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl - echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl - echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl vivado -mode batch -source program.tcl diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index 3a815ba1d..e897df5dd 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -53,9 +53,9 @@ program: $(FPGA_TOP).bit echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl - echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl - echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl - echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl vivado -mode batch -source program.tcl diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile index 7b00eb4ad..6489c0c84 100644 --- a/example/VCU118/fpga_10g/fpga/Makefile +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -70,9 +70,9 @@ program: $(FPGA_TOP).bit echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl - echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl - echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl - echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl vivado -mode batch -source program.tcl diff --git a/example/VCU118/fpga_1g/fpga/Makefile b/example/VCU118/fpga_1g/fpga/Makefile index 15000e344..74bda492f 100644 --- a/example/VCU118/fpga_1g/fpga/Makefile +++ b/example/VCU118/fpga_1g/fpga/Makefile @@ -53,9 +53,9 @@ program: $(FPGA_TOP).bit echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl - echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl - echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl - echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl vivado -mode batch -source program.tcl diff --git a/example/VCU118/fpga_25g/fpga/Makefile b/example/VCU118/fpga_25g/fpga/Makefile index 7b00eb4ad..6489c0c84 100644 --- a/example/VCU118/fpga_25g/fpga/Makefile +++ b/example/VCU118/fpga_25g/fpga/Makefile @@ -70,9 +70,9 @@ program: $(FPGA_TOP).bit echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl - echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl - echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl - echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl vivado -mode batch -source program.tcl From daf1d3106fbd53f72b7da403aebda252e50c2fa0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 26 Jun 2019 01:28:54 -0700 Subject: [PATCH 604/617] Enable flash programming on VCU108 --- example/VCU108/fpga_10g/fpga.xdc | 9 ++++--- example/VCU108/fpga_10g/fpga/Makefile | 35 +++++++++++++++++++++++++++ example/VCU108/fpga_1g/fpga.xdc | 9 ++++--- example/VCU108/fpga_1g/fpga/Makefile | 35 +++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 6 deletions(-) diff --git a/example/VCU108/fpga_10g/fpga.xdc b/example/VCU108/fpga_10g/fpga.xdc index 314bb5d00..976f8bea2 100644 --- a/example/VCU108/fpga_10g/fpga.xdc +++ b/example/VCU108/fpga_10g/fpga.xdc @@ -2,9 +2,12 @@ # part: xcvu095-ffva2104-2-e # General configuration -set_property CFGBVS GND [current_design] -set_property CONFIG_VOLTAGE 1.8 [current_design] -set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN {DIV-1} [current_design] +set_property BITSTREAM.CONFIG.BPI_SYNC_MODE Type1 [current_design] +set_property CONFIG_MODE BPI16 [current_design] # System clocks # 300 MHz diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 6ac12d04a..cae30623a 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -76,3 +76,38 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -mode batch -source program.tcl +%.mcs: %.bit + echo "write_cfgmem -force -format mcs -size 128 -interface BPIx16 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -mode batch -source generate_mcs.tcl + mkdir -p rev + EXT=mcs; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + +flash: $(FPGA_TOP).mcs + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt28gu01gaax1e-bpi-x16}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list "$(FPGA_TOP).mcs"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.BPI_RS_PINS {none} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -mode batch -source flash.tcl + diff --git a/example/VCU108/fpga_1g/fpga.xdc b/example/VCU108/fpga_1g/fpga.xdc index e3b15a5f9..652b31be7 100644 --- a/example/VCU108/fpga_1g/fpga.xdc +++ b/example/VCU108/fpga_1g/fpga.xdc @@ -2,9 +2,12 @@ # part: xcvu095-ffva2104-2-e # General configuration -set_property CFGBVS GND [current_design] -set_property CONFIG_VOLTAGE 1.8 [current_design] -set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN {DIV-1} [current_design] +set_property BITSTREAM.CONFIG.BPI_SYNC_MODE Type1 [current_design] +set_property CONFIG_MODE BPI16 [current_design] # System clocks # 300 MHz diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index e897df5dd..164ee53fe 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -59,3 +59,38 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -mode batch -source program.tcl +%.mcs: %.bit + echo "write_cfgmem -force -format mcs -size 128 -interface BPIx16 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -mode batch -source generate_mcs.tcl + mkdir -p rev + EXT=mcs; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + +flash: $(FPGA_TOP).mcs + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt28gu01gaax1e-bpi-x16}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list "$(FPGA_TOP).mcs"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.BPI_RS_PINS {none} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -mode batch -source flash.tcl + From d166350d776f0e653e9be482aa15c4c3d21bd1f6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 26 Jun 2019 18:59:41 -0700 Subject: [PATCH 605/617] Update Arty XDC --- example/Arty/fpga/fpga.xdc | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/example/Arty/fpga/fpga.xdc b/example/Arty/fpga/fpga.xdc index b21f79e90..c00c158cc 100644 --- a/example/Arty/fpga/fpga.xdc +++ b/example/Arty/fpga/fpga.xdc @@ -45,6 +45,44 @@ set_property -dict {LOC C11 IOSTANDARD LVCMOS33} [get_ports {sw[1]}] set_property -dict {LOC C10 IOSTANDARD LVCMOS33} [get_ports {sw[2]}] set_property -dict {LOC A10 IOSTANDARD LVCMOS33} [get_ports {sw[3]}] +# GPIO +# PMOD JA +#set_property -dict {LOC G13 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_ja1}] ;# PMOD JA pin 1 +#set_property -dict {LOC B11 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_ja2}] ;# PMOD JA pin 2 +#set_property -dict {LOC A11 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_ja3}] ;# PMOD JA pin 3 +#set_property -dict {LOC D12 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_ja4}] ;# PMOD JA pin 4 +#set_property -dict {LOC D13 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_ja7}] ;# PMOD JA pin 7 +#set_property -dict {LOC B18 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_ja8}] ;# PMOD JA pin 8 +#set_property -dict {LOC A18 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_ja9}] ;# PMOD JA pin 9 +#set_property -dict {LOC K16 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_ja10}] ;# PMOD JA pin 10 +# PMOD JB +#set_property -dict {LOC E15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jb1}] ;# PMOD JB pin 1 +#set_property -dict {LOC E16 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jb2}] ;# PMOD JB pin 2 +#set_property -dict {LOC D15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jb3}] ;# PMOD JB pin 3 +#set_property -dict {LOC C15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jb4}] ;# PMOD JB pin 4 +#set_property -dict {LOC J17 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jb7}] ;# PMOD JB pin 7 +#set_property -dict {LOC J18 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jb8}] ;# PMOD JB pin 8 +#set_property -dict {LOC K15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jb9}] ;# PMOD JB pin 9 +#set_property -dict {LOC J15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jb10}] ;# PMOD JB pin 10 +# PMOD JC +#set_property -dict {LOC U12 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jc1}] ;# PMOD JC pin 1 +#set_property -dict {LOC V12 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jc2}] ;# PMOD JC pin 2 +#set_property -dict {LOC V10 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jc3}] ;# PMOD JC pin 3 +#set_property -dict {LOC V11 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jc4}] ;# PMOD JC pin 4 +#set_property -dict {LOC U14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jc7}] ;# PMOD JC pin 7 +#set_property -dict {LOC V14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jc8}] ;# PMOD JC pin 8 +#set_property -dict {LOC T13 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jc9}] ;# PMOD JC pin 9 +#set_property -dict {LOC U13 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jc10}] ;# PMOD JC pin 10 +# PMOD JD +#set_property -dict {LOC D4 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jd1}] ;# PMOD JD pin 1 +#set_property -dict {LOC D3 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jd2}] ;# PMOD JD pin 2 +#set_property -dict {LOC F4 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jd3}] ;# PMOD JD pin 3 +#set_property -dict {LOC F3 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jd4}] ;# PMOD JD pin 4 +#set_property -dict {LOC E2 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jd7}] ;# PMOD JD pin 7 +#set_property -dict {LOC D2 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jd8}] ;# PMOD JD pin 8 +#set_property -dict {LOC H2 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jd9}] ;# PMOD JD pin 9 +#set_property -dict {LOC G2 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_jd10}] ;# PMOD JD pin 10 + # UART set_property -dict {LOC D10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports uart_txd] set_property -dict {LOC A9 IOSTANDARD LVCMOS33} [get_ports uart_rxd] From dc4416a2610d3cabe24aa20daa72fd80d998b2d6 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 26 Jun 2019 19:00:20 -0700 Subject: [PATCH 606/617] Update Arty flash programming commands --- example/Arty/fpga/fpga/Makefile | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/example/Arty/fpga/fpga/Makefile b/example/Arty/fpga/fpga/Makefile index 865b11d68..7dfa7069c 100644 --- a/example/Arty/fpga/fpga/Makefile +++ b/example/Arty/fpga/fpga/Makefile @@ -59,28 +59,39 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -mode batch -source program.tcl -%.mcs: %.bit +%.mcs %.prm: %.bit echo "write_cfgmem -force -format mcs -size 16 -interface SPIx4 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl echo "exit" >> generate_mcs.tcl vivado -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do let COUNT=COUNT+1; done; \ + let COUNT=COUNT-1; \ + for x in .mcs .prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; -flash: $(FPGA_TOP).mcs +flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm echo "open_hw" > flash.tcl echo "connect_hw_server" >> flash.tcl echo "open_hw_target" >> flash.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25ql128-spi-x1_x2_x4}] 0]" >> flash.tcl - echo "set_property PROGRAM.FILES [list "$(FPGA_TOP).mcs"] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "set_property PROGRAM.ERASE 1 [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "set_property PROGRAM.CFG_PROGRAM 1 [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "set_property PROGRAM.VERIFY 1 [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "set_property PROGRAM.CHECKSUM 0 [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices] 0]]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list "$(FPGA_TOP).mcs"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list "$(FPGA_TOP).prm"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl echo "program_hw_devices [current_hw_device]" >> flash.tcl echo "refresh_hw_device [current_hw_device]" >> flash.tcl - echo "program_hw_cfgmem -hw_cfgmem [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl echo "boot_hw_device [current_hw_device]" >> flash.tcl echo "exit" >> flash.tcl vivado -mode batch -source flash.tcl From 88cc4e6e24bcd5d405e25e845050adf44138e730 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 26 Jun 2019 19:50:28 -0700 Subject: [PATCH 607/617] Update VCU108 flash programming commands --- example/VCU108/fpga_10g/fpga/Makefile | 15 +++++++++------ example/VCU108/fpga_1g/fpga/Makefile | 15 +++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index cae30623a..68a465771 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -76,18 +76,20 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -mode batch -source program.tcl -%.mcs: %.bit +%.mcs %.prm: %.bit echo "write_cfgmem -force -format mcs -size 128 -interface BPIx16 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl echo "exit" >> generate_mcs.tcl vivado -mode batch -source generate_mcs.tcl mkdir -p rev - EXT=mcs; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ do let COUNT=COUNT+1; done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + let COUNT=COUNT-1; \ + for x in .mcs .prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; -flash: $(FPGA_TOP).mcs +flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm echo "open_hw" > flash.tcl echo "connect_hw_server" >> flash.tcl echo "open_hw_target" >> flash.tcl @@ -96,6 +98,7 @@ flash: $(FPGA_TOP).mcs echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt28gu01gaax1e-bpi-x16}] 0]" >> flash.tcl echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl echo "set_property PROGRAM.FILES [list "$(FPGA_TOP).mcs"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list "$(FPGA_TOP).prm"] [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index 164ee53fe..a4be6bab1 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -59,18 +59,20 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -mode batch -source program.tcl -%.mcs: %.bit +%.mcs %.prm: %.bit echo "write_cfgmem -force -format mcs -size 128 -interface BPIx16 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl echo "exit" >> generate_mcs.tcl vivado -mode batch -source generate_mcs.tcl mkdir -p rev - EXT=mcs; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ do let COUNT=COUNT+1; done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + let COUNT=COUNT-1; \ + for x in .mcs .prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; -flash: $(FPGA_TOP).mcs +flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm echo "open_hw" > flash.tcl echo "connect_hw_server" >> flash.tcl echo "open_hw_target" >> flash.tcl @@ -79,6 +81,7 @@ flash: $(FPGA_TOP).mcs echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt28gu01gaax1e-bpi-x16}] 0]" >> flash.tcl echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl echo "set_property PROGRAM.FILES [list "$(FPGA_TOP).mcs"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list "$(FPGA_TOP).prm"] [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl From 963a8f7459a83d8f788b6e5006e9a6c3302e5736 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 26 Jun 2019 20:06:22 -0700 Subject: [PATCH 608/617] Add flash ADM-PCIE-9V3 flash programming commands --- example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile | 37 +++++++++++++++++++++ example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile | 37 +++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile index 5ba42c6cc..8abdf19a8 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -67,3 +67,40 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -mode batch -source program.tcl +%_primary.mcs %_secondary.mcs %_primary.prm %_secondary.prm: %.bit + echo "write_cfgmem -force -format mcs -size 64 -interface SPIx8 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do let COUNT=COUNT+1; done; \ + let COUNT=COUNT-1; \ + for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu256-spi-x1_x2_x4_x8}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list "$(FPGA_TOP)_primary.mcs" "$(FPGA_TOP)_secondary.mcs"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list "$(FPGA_TOP)_primary.prm" "$(FPGA_TOP)_secondary.prm"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -mode batch -source flash.tcl + diff --git a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile index 5ba42c6cc..8abdf19a8 100644 --- a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile @@ -67,3 +67,40 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -mode batch -source program.tcl +%_primary.mcs %_secondary.mcs %_primary.prm %_secondary.prm: %.bit + echo "write_cfgmem -force -format mcs -size 64 -interface SPIx8 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do let COUNT=COUNT+1; done; \ + let COUNT=COUNT-1; \ + for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu256-spi-x1_x2_x4_x8}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list "$(FPGA_TOP)_primary.mcs" "$(FPGA_TOP)_secondary.mcs"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list "$(FPGA_TOP)_primary.prm" "$(FPGA_TOP)_secondary.prm"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -mode batch -source flash.tcl + From 15b3aaf2e795ec1d9bf2b09607b65f295750ca6a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 26 Jun 2019 20:17:45 -0700 Subject: [PATCH 609/617] Update programming commands --- example/ExaNIC_X10/fpga/fpga/Makefile | 6 +++--- example/KC705/fpga_gmii/fpga/Makefile | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/example/ExaNIC_X10/fpga/fpga/Makefile b/example/ExaNIC_X10/fpga/fpga/Makefile index 0c3fbbee6..c9dbc1c54 100644 --- a/example/ExaNIC_X10/fpga/fpga/Makefile +++ b/example/ExaNIC_X10/fpga/fpga/Makefile @@ -60,9 +60,9 @@ program: $(FPGA_TOP).bit echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl - echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl - echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl - echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl vivado -mode batch -source program.tcl diff --git a/example/KC705/fpga_gmii/fpga/Makefile b/example/KC705/fpga_gmii/fpga/Makefile index 53353ae47..d003e017a 100644 --- a/example/KC705/fpga_gmii/fpga/Makefile +++ b/example/KC705/fpga_gmii/fpga/Makefile @@ -57,9 +57,9 @@ program: $(FPGA_TOP).bit echo "connect_hw_server" >> program.tcl echo "open_hw_target" >> program.tcl echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl - echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl - echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl - echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl vivado -mode batch -source program.tcl From cfcd9da375f9a8f7ae5d23e896c6e492b2721484 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 26 Jun 2019 20:50:05 -0700 Subject: [PATCH 610/617] Update IP --- example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci b/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci index 333cda6bc..3380b154b 100644 --- a/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci +++ b/example/ExaNIC_X10/fpga/ip/gtwizard_ultrascale_0.xci @@ -1362,16 +1362,17 @@ MIXED -2 + E TRUE TRUE IP_Flow - 5 + 6 TRUE . . - 2018.3 + 2019.1 OUT_OF_CONTEXT From af4f675840a40f53730ecc85770e7b7643a978a8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 27 Jun 2019 00:15:36 -0700 Subject: [PATCH 611/617] Fix for dash --- example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile | 4 ++-- example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile | 4 ++-- example/Arty/fpga/fpga/Makefile | 4 ++-- example/VCU108/fpga_10g/fpga/Makefile | 4 ++-- example/VCU108/fpga_1g/fpga/Makefile | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile index 8abdf19a8..97b4a55c8 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -74,8 +74,8 @@ program: $(FPGA_TOP).bit mkdir -p rev COUNT=100; \ while [ -e rev/$*_rev$$COUNT.bit ]; \ - do let COUNT=COUNT+1; done; \ - let COUNT=COUNT-1; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \ do cp $*$$x rev/$*_rev$$COUNT$$x; \ echo "Output: rev/$*_rev$$COUNT$$x"; done; diff --git a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile index 8abdf19a8..97b4a55c8 100644 --- a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile @@ -74,8 +74,8 @@ program: $(FPGA_TOP).bit mkdir -p rev COUNT=100; \ while [ -e rev/$*_rev$$COUNT.bit ]; \ - do let COUNT=COUNT+1; done; \ - let COUNT=COUNT-1; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \ do cp $*$$x rev/$*_rev$$COUNT$$x; \ echo "Output: rev/$*_rev$$COUNT$$x"; done; diff --git a/example/Arty/fpga/fpga/Makefile b/example/Arty/fpga/fpga/Makefile index 7dfa7069c..099e683e4 100644 --- a/example/Arty/fpga/fpga/Makefile +++ b/example/Arty/fpga/fpga/Makefile @@ -66,8 +66,8 @@ program: $(FPGA_TOP).bit mkdir -p rev COUNT=100; \ while [ -e rev/$*_rev$$COUNT.bit ]; \ - do let COUNT=COUNT+1; done; \ - let COUNT=COUNT-1; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ for x in .mcs .prm; \ do cp $*$$x rev/$*_rev$$COUNT$$x; \ echo "Output: rev/$*_rev$$COUNT$$x"; done; diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 68a465771..88618c262 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -83,8 +83,8 @@ program: $(FPGA_TOP).bit mkdir -p rev COUNT=100; \ while [ -e rev/$*_rev$$COUNT.bit ]; \ - do let COUNT=COUNT+1; done; \ - let COUNT=COUNT-1; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ for x in .mcs .prm; \ do cp $*$$x rev/$*_rev$$COUNT$$x; \ echo "Output: rev/$*_rev$$COUNT$$x"; done; diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index a4be6bab1..01b5f17c5 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -66,8 +66,8 @@ program: $(FPGA_TOP).bit mkdir -p rev COUNT=100; \ while [ -e rev/$*_rev$$COUNT.bit ]; \ - do let COUNT=COUNT+1; done; \ - let COUNT=COUNT-1; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ for x in .mcs .prm; \ do cp $*$$x rev/$*_rev$$COUNT$$x; \ echo "Output: rev/$*_rev$$COUNT$$x"; done; From 025f05e6678b61733c6e1852e2085070e7c1bb57 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 27 Jun 2019 00:48:20 -0700 Subject: [PATCH 612/617] Add nojournal and nolog --- example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile | 6 +++--- example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile | 6 +++--- example/Arty/fpga/fpga/Makefile | 6 +++--- example/ExaNIC_X10/fpga/fpga/Makefile | 2 +- example/KC705/fpga_gmii/fpga/Makefile | 2 +- example/VCU108/fpga_10g/fpga/Makefile | 6 +++--- example/VCU108/fpga_1g/fpga/Makefile | 6 +++--- example/VCU118/fpga_10g/fpga/Makefile | 2 +- example/VCU118/fpga_1g/fpga/Makefile | 2 +- example/VCU118/fpga_25g/fpga/Makefile | 2 +- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile index 97b4a55c8..75c240387 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -65,12 +65,12 @@ program: $(FPGA_TOP).bit echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl - vivado -mode batch -source program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl %_primary.mcs %_secondary.mcs %_primary.prm %_secondary.prm: %.bit echo "write_cfgmem -force -format mcs -size 64 -interface SPIx8 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl echo "exit" >> generate_mcs.tcl - vivado -mode batch -source generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl mkdir -p rev COUNT=100; \ while [ -e rev/$*_rev$$COUNT.bit ]; \ @@ -102,5 +102,5 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl echo "boot_hw_device [current_hw_device]" >> flash.tcl echo "exit" >> flash.tcl - vivado -mode batch -source flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl diff --git a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile index 97b4a55c8..75c240387 100644 --- a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile @@ -65,12 +65,12 @@ program: $(FPGA_TOP).bit echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl - vivado -mode batch -source program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl %_primary.mcs %_secondary.mcs %_primary.prm %_secondary.prm: %.bit echo "write_cfgmem -force -format mcs -size 64 -interface SPIx8 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl echo "exit" >> generate_mcs.tcl - vivado -mode batch -source generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl mkdir -p rev COUNT=100; \ while [ -e rev/$*_rev$$COUNT.bit ]; \ @@ -102,5 +102,5 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl echo "boot_hw_device [current_hw_device]" >> flash.tcl echo "exit" >> flash.tcl - vivado -mode batch -source flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl diff --git a/example/Arty/fpga/fpga/Makefile b/example/Arty/fpga/fpga/Makefile index 099e683e4..492c57e8d 100644 --- a/example/Arty/fpga/fpga/Makefile +++ b/example/Arty/fpga/fpga/Makefile @@ -57,12 +57,12 @@ program: $(FPGA_TOP).bit echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl - vivado -mode batch -source program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl %.mcs %.prm: %.bit echo "write_cfgmem -force -format mcs -size 16 -interface SPIx4 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl echo "exit" >> generate_mcs.tcl - vivado -mode batch -source generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl mkdir -p rev COUNT=100; \ while [ -e rev/$*_rev$$COUNT.bit ]; \ @@ -94,5 +94,5 @@ flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl echo "boot_hw_device [current_hw_device]" >> flash.tcl echo "exit" >> flash.tcl - vivado -mode batch -source flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl diff --git a/example/ExaNIC_X10/fpga/fpga/Makefile b/example/ExaNIC_X10/fpga/fpga/Makefile index c9dbc1c54..48fec2986 100644 --- a/example/ExaNIC_X10/fpga/fpga/Makefile +++ b/example/ExaNIC_X10/fpga/fpga/Makefile @@ -64,5 +64,5 @@ program: $(FPGA_TOP).bit echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl - vivado -mode batch -source program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl diff --git a/example/KC705/fpga_gmii/fpga/Makefile b/example/KC705/fpga_gmii/fpga/Makefile index d003e017a..7231fad40 100644 --- a/example/KC705/fpga_gmii/fpga/Makefile +++ b/example/KC705/fpga_gmii/fpga/Makefile @@ -61,5 +61,5 @@ program: $(FPGA_TOP).bit echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl - vivado -mode batch -source program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 88618c262..e0d21a10b 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -74,12 +74,12 @@ program: $(FPGA_TOP).bit echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl - vivado -mode batch -source program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl %.mcs %.prm: %.bit echo "write_cfgmem -force -format mcs -size 128 -interface BPIx16 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl echo "exit" >> generate_mcs.tcl - vivado -mode batch -source generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl mkdir -p rev COUNT=100; \ while [ -e rev/$*_rev$$COUNT.bit ]; \ @@ -112,5 +112,5 @@ flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl echo "boot_hw_device [current_hw_device]" >> flash.tcl echo "exit" >> flash.tcl - vivado -mode batch -source flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index 01b5f17c5..f4ab11cc3 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -57,12 +57,12 @@ program: $(FPGA_TOP).bit echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl - vivado -mode batch -source program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl %.mcs %.prm: %.bit echo "write_cfgmem -force -format mcs -size 128 -interface BPIx16 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl echo "exit" >> generate_mcs.tcl - vivado -mode batch -source generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl mkdir -p rev COUNT=100; \ while [ -e rev/$*_rev$$COUNT.bit ]; \ @@ -95,5 +95,5 @@ flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl echo "boot_hw_device [current_hw_device]" >> flash.tcl echo "exit" >> flash.tcl - vivado -mode batch -source flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile index 6489c0c84..b87c3c9f0 100644 --- a/example/VCU118/fpga_10g/fpga/Makefile +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -74,5 +74,5 @@ program: $(FPGA_TOP).bit echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl - vivado -mode batch -source program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl diff --git a/example/VCU118/fpga_1g/fpga/Makefile b/example/VCU118/fpga_1g/fpga/Makefile index 74bda492f..f92425064 100644 --- a/example/VCU118/fpga_1g/fpga/Makefile +++ b/example/VCU118/fpga_1g/fpga/Makefile @@ -57,5 +57,5 @@ program: $(FPGA_TOP).bit echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl - vivado -mode batch -source program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl diff --git a/example/VCU118/fpga_25g/fpga/Makefile b/example/VCU118/fpga_25g/fpga/Makefile index 6489c0c84..b87c3c9f0 100644 --- a/example/VCU118/fpga_25g/fpga/Makefile +++ b/example/VCU118/fpga_25g/fpga/Makefile @@ -74,5 +74,5 @@ program: $(FPGA_TOP).bit echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl echo "program_hw_devices [current_hw_device]" >> program.tcl echo "exit" >> program.tcl - vivado -mode batch -source program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl From dfafa9c83d37b999475e66c484bd20a2563513ef Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 27 Jun 2019 00:59:36 -0700 Subject: [PATCH 613/617] Update vivado.mk --- example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk | 14 +++++++------- example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk | 14 +++++++------- example/Arty/fpga/common/vivado.mk | 14 +++++++------- example/ExaNIC_X10/fpga/common/vivado.mk | 14 +++++++------- example/KC705/fpga_gmii/common/vivado.mk | 14 +++++++------- example/NexysVideo/fpga/common/vivado.mk | 14 +++++++------- example/VCU108/fpga_10g/common/vivado.mk | 14 +++++++------- example/VCU108/fpga_1g/common/vivado.mk | 14 +++++++------- example/VCU118/fpga_10g/common/vivado.mk | 14 +++++++------- example/VCU118/fpga_1g/common/vivado.mk | 14 +++++++------- example/VCU118/fpga_25g/common/vivado.mk | 14 +++++++------- 11 files changed, 77 insertions(+), 77 deletions(-) diff --git a/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk b/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk +++ b/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk b/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk +++ b/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/Arty/fpga/common/vivado.mk b/example/Arty/fpga/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/Arty/fpga/common/vivado.mk +++ b/example/Arty/fpga/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/ExaNIC_X10/fpga/common/vivado.mk b/example/ExaNIC_X10/fpga/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/ExaNIC_X10/fpga/common/vivado.mk +++ b/example/ExaNIC_X10/fpga/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/KC705/fpga_gmii/common/vivado.mk b/example/KC705/fpga_gmii/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/KC705/fpga_gmii/common/vivado.mk +++ b/example/KC705/fpga_gmii/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/NexysVideo/fpga/common/vivado.mk b/example/NexysVideo/fpga/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/NexysVideo/fpga/common/vivado.mk +++ b/example/NexysVideo/fpga/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/VCU108/fpga_10g/common/vivado.mk b/example/VCU108/fpga_10g/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/VCU108/fpga_10g/common/vivado.mk +++ b/example/VCU108/fpga_10g/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/VCU108/fpga_1g/common/vivado.mk b/example/VCU108/fpga_1g/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/VCU108/fpga_1g/common/vivado.mk +++ b/example/VCU108/fpga_1g/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/VCU118/fpga_10g/common/vivado.mk b/example/VCU118/fpga_10g/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/VCU118/fpga_10g/common/vivado.mk +++ b/example/VCU118/fpga_10g/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/VCU118/fpga_1g/common/vivado.mk b/example/VCU118/fpga_1g/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/VCU118/fpga_1g/common/vivado.mk +++ b/example/VCU118/fpga_1g/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/example/VCU118/fpga_25g/common/vivado.mk b/example/VCU118/fpga_25g/common/vivado.mk index a54b530f6..964ed04eb 100644 --- a/example/VCU118/fpga_25g/common/vivado.mk +++ b/example/VCU118/fpga_25g/common/vivado.mk @@ -31,7 +31,7 @@ .PHONY: clean fpga # prevent make from deleting intermediate files and reports -.PRECIOUS: %.xpr %.bit +.PRECIOUS: %.xpr %.bit %.mcs %.prm .SECONDARY: CONFIG ?= config.mk @@ -63,7 +63,7 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl distclean: clean -rm -rf rev @@ -83,7 +83,7 @@ distclean: clean for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done echo "exit" >> create_project.tcl - vivado -mode batch -source create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl # synthesis run %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) @@ -92,7 +92,7 @@ distclean: clean echo "launch_runs synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl echo "exit" >> run_synth.tcl - vivado -mode batch -source run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp @@ -101,7 +101,7 @@ distclean: clean echo "launch_runs impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl echo "exit" >> run_impl.tcl - vivado -mode batch -source run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file %.bit: %.runs/impl_1/%_routed.dcp @@ -109,10 +109,10 @@ distclean: clean echo "open_run impl_1" >> generate_bit.tcl echo "write_bitstream -force $*.bit" >> generate_bit.tcl echo "exit" >> generate_bit.tcl - vivado -mode batch -source generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl mkdir -p rev EXT=bit; COUNT=100; \ while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ - do let COUNT=COUNT+1; done; \ + do COUNT=$$((COUNT+1)); done; \ cp $@ rev/$*_rev$$COUNT.$$EXT; \ echo "Output: rev/$*_rev$$COUNT.$$EXT"; From d62a5ad050a3af4c10f85447fc37f38be832ecb8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 27 Jun 2019 01:26:58 -0700 Subject: [PATCH 614/617] Fix quotes --- example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile | 4 ++-- example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile | 4 ++-- example/Arty/fpga/fpga/Makefile | 4 ++-- example/VCU108/fpga_10g/fpga/Makefile | 4 ++-- example/VCU108/fpga_1g/fpga/Makefile | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile index 75c240387..1a17dbdac 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -88,8 +88,8 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu256-spi-x1_x2_x4_x8}] 0]" >> flash.tcl echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "set_property PROGRAM.FILES [list "$(FPGA_TOP)_primary.mcs" "$(FPGA_TOP)_secondary.mcs"] [current_hw_cfgmem]" >> flash.tcl - echo "set_property PROGRAM.PRM_FILES [list "$(FPGA_TOP)_primary.prm" "$(FPGA_TOP)_secondary.prm"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl diff --git a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile index 75c240387..1a17dbdac 100644 --- a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile @@ -88,8 +88,8 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu256-spi-x1_x2_x4_x8}] 0]" >> flash.tcl echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "set_property PROGRAM.FILES [list "$(FPGA_TOP)_primary.mcs" "$(FPGA_TOP)_secondary.mcs"] [current_hw_cfgmem]" >> flash.tcl - echo "set_property PROGRAM.PRM_FILES [list "$(FPGA_TOP)_primary.prm" "$(FPGA_TOP)_secondary.prm"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl diff --git a/example/Arty/fpga/fpga/Makefile b/example/Arty/fpga/fpga/Makefile index 492c57e8d..36d5be2e6 100644 --- a/example/Arty/fpga/fpga/Makefile +++ b/example/Arty/fpga/fpga/Makefile @@ -80,8 +80,8 @@ flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25ql128-spi-x1_x2_x4}] 0]" >> flash.tcl echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "set_property PROGRAM.FILES [list "$(FPGA_TOP).mcs"] [current_hw_cfgmem]" >> flash.tcl - echo "set_property PROGRAM.PRM_FILES [list "$(FPGA_TOP).prm"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index e0d21a10b..de36e54d7 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -97,8 +97,8 @@ flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt28gu01gaax1e-bpi-x16}] 0]" >> flash.tcl echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "set_property PROGRAM.FILES [list "$(FPGA_TOP).mcs"] [current_hw_cfgmem]" >> flash.tcl - echo "set_property PROGRAM.PRM_FILES [list "$(FPGA_TOP).prm"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl diff --git a/example/VCU108/fpga_1g/fpga/Makefile b/example/VCU108/fpga_1g/fpga/Makefile index f4ab11cc3..ba7eadc08 100644 --- a/example/VCU108/fpga_1g/fpga/Makefile +++ b/example/VCU108/fpga_1g/fpga/Makefile @@ -80,8 +80,8 @@ flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt28gu01gaax1e-bpi-x16}] 0]" >> flash.tcl echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl - echo "set_property PROGRAM.FILES [list "$(FPGA_TOP).mcs"] [current_hw_cfgmem]" >> flash.tcl - echo "set_property PROGRAM.PRM_FILES [list "$(FPGA_TOP).prm"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl From 386ff91210d923311bbabda6b29f231b5877099b Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 27 Jun 2019 01:27:32 -0700 Subject: [PATCH 615/617] Add ExaNIC X10 flash programming commands --- example/ExaNIC_X10/fpga/fpga/Makefile | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/example/ExaNIC_X10/fpga/fpga/Makefile b/example/ExaNIC_X10/fpga/fpga/Makefile index 48fec2986..5533ee52a 100644 --- a/example/ExaNIC_X10/fpga/fpga/Makefile +++ b/example/ExaNIC_X10/fpga/fpga/Makefile @@ -66,3 +66,41 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -nojournal -nolog -mode batch -source program.tcl +%.mcs %.prm: %.bit + echo "write_cfgmem -force -format mcs -size 32 -interface BPIx16 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in .mcs .prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {28f256p30t-bpi-x16}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.BPI_RS_PINS {none} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl + From fdfb5177615eb2a72bdf093f65284196007bbd39 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 27 Jun 2019 01:30:18 -0700 Subject: [PATCH 616/617] Add PTP perout module and testbench --- rtl/ptp_perout.v | 329 ++++++++++++++++++++++++++++++++++++++++++ tb/test_ptp_perout.py | 182 +++++++++++++++++++++++ tb/test_ptp_perout.v | 122 ++++++++++++++++ 3 files changed, 633 insertions(+) create mode 100644 rtl/ptp_perout.v create mode 100755 tb/test_ptp_perout.py create mode 100644 tb/test_ptp_perout.v diff --git a/rtl/ptp_perout.v b/rtl/ptp_perout.v new file mode 100644 index 000000000..54ba07a65 --- /dev/null +++ b/rtl/ptp_perout.v @@ -0,0 +1,329 @@ +/* + +Copyright (c) 2019 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 + +/* + * PTP period out module + */ +module ptp_perout # +( + parameter FNS_ENABLE = 1, + parameter OUT_START_S = 48'h0, + parameter OUT_START_NS = 30'h0, + parameter OUT_START_FNS = 16'h0000, + parameter OUT_PERIOD_S = 48'd1, + parameter OUT_PERIOD_NS = 30'd0, + parameter OUT_PERIOD_FNS = 16'h0000, + parameter OUT_WIDTH_S = 48'h0, + parameter OUT_WIDTH_NS = 30'd1000, + parameter OUT_WIDTH_FNS = 16'h0000 +) +( + input wire clk, + input wire rst, + + /* + * Timestamp input from PTP clock + */ + input wire [95:0] input_ts_96, + input wire input_ts_step, + + /* + * Control + */ + input wire enable, + input wire [95:0] input_start, + input wire input_start_valid, + input wire [95:0] input_period, + input wire input_period_valid, + input wire [95:0] input_width, + input wire input_width_valid, + + /* + * Status + */ + output wire locked, + output wire error, + + /* + * Pulse output + */ + output wire output_pulse +); + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_UPDATE_RISE_1 = 3'd1, + STATE_UPDATE_RISE_2 = 3'd2, + STATE_UPDATE_FALL_1 = 3'd3, + STATE_UPDATE_FALL_2 = 3'd4, + STATE_WAIT_EDGE = 3'd5; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +reg [47:0] time_s_reg = 0; +reg [30:0] time_ns_reg = 0; +reg [15:0] time_fns_reg = 0; + +reg [47:0] next_rise_s_reg = 0, next_rise_s_next; +reg [30:0] next_rise_ns_reg = 0, next_rise_ns_next; +reg [15:0] next_rise_fns_reg = 0, next_rise_fns_next; + +reg [47:0] next_fall_s_reg = 0, next_fall_s_next; +reg [30:0] next_fall_ns_reg = 0, next_fall_ns_next; +reg [15:0] next_fall_fns_reg = 0, next_fall_fns_next; + +reg [47:0] start_s_reg = OUT_START_S; +reg [30:0] start_ns_reg = OUT_START_NS; +reg [15:0] start_fns_reg = OUT_START_FNS; + +reg [47:0] period_s_reg = OUT_PERIOD_S; +reg [30:0] period_ns_reg = OUT_PERIOD_NS; +reg [15:0] period_fns_reg = OUT_PERIOD_FNS; + +reg [47:0] width_s_reg = OUT_WIDTH_S; +reg [30:0] width_ns_reg = OUT_WIDTH_NS; +reg [15:0] width_fns_reg = OUT_WIDTH_FNS; + +reg [29:0] ts_96_ns_inc_reg = 0, ts_96_ns_inc_next; +reg [15:0] ts_96_fns_inc_reg = 0, ts_96_fns_inc_next; +reg [30:0] ts_96_ns_ovf_reg = 0, ts_96_ns_ovf_next; +reg [15:0] ts_96_fns_ovf_reg = 0, ts_96_fns_ovf_next; + +reg locked_reg = 1'b0, locked_next; +reg error_reg = 1'b0; +reg level_reg = 1'b0, level_next; +reg output_reg = 1'b0, output_next; + +assign locked = locked_reg; +assign error = error_reg; +assign output_pulse = output_reg; + +always @* begin + state_next = STATE_IDLE; + + next_rise_s_next = next_rise_s_reg; + next_rise_ns_next = next_rise_ns_reg; + next_rise_fns_next = next_rise_fns_reg; + + next_fall_s_next = next_fall_s_reg; + next_fall_ns_next = next_fall_ns_reg; + next_fall_fns_next = next_fall_fns_reg; + + ts_96_ns_inc_next = ts_96_ns_inc_reg; + ts_96_fns_inc_next = ts_96_fns_inc_reg; + + ts_96_ns_ovf_next = ts_96_ns_ovf_reg; + ts_96_fns_ovf_next = ts_96_fns_ovf_reg; + + locked_next = locked_reg; + level_next = level_reg; + output_next = output_reg; + + case (state_reg) + STATE_IDLE: begin + // set next rise to start time + next_rise_s_next = start_s_reg; + next_rise_ns_next = start_ns_reg; + if (FNS_ENABLE) begin + next_rise_fns_next = start_fns_reg; + end + locked_next = 1'b0; + level_next = 1'b0; + output_next = 1'b0; + if (input_start_valid || input_period_valid) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_UPDATE_FALL_1; + end + end + STATE_UPDATE_RISE_1: begin + // set next rise time to next rise time plus period + {ts_96_ns_inc_next, ts_96_fns_inc_next} = {next_rise_ns_reg, next_rise_fns_reg} + {period_ns_reg, period_fns_reg}; + {ts_96_ns_ovf_next, ts_96_fns_ovf_next} = {next_rise_ns_reg, next_rise_fns_reg} + {period_ns_reg, period_fns_reg} - {31'd1_000_000_000, 16'd0}; + if (input_start_valid || input_period_valid) begin + level_next = 1'b0; + output_next = 1'b0; + state_next = STATE_IDLE; + end else begin + state_next = STATE_UPDATE_RISE_2; + end + end + STATE_UPDATE_RISE_2: begin + if (!ts_96_ns_ovf_reg[30]) begin + // if the overflow lookahead did not borrow, one second has elapsed + next_rise_s_next = next_rise_s_reg + period_s_reg + 1; + next_rise_ns_next = ts_96_ns_ovf_reg; + next_rise_fns_next = ts_96_fns_ovf_reg; + end else begin + // no increment seconds field + next_rise_s_next = next_rise_s_reg + period_s_reg; + next_rise_ns_next = ts_96_ns_inc_reg; + next_rise_fns_next = ts_96_fns_inc_reg; + end + if (input_start_valid || input_period_valid) begin + level_next = 1'b0; + output_next = 1'b0; + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_EDGE; + end + end + STATE_UPDATE_FALL_1: begin + // set next fall time to next rise time plus width + {ts_96_ns_inc_next, ts_96_fns_inc_next} = {next_rise_ns_reg, next_rise_fns_reg} + {width_ns_reg, width_fns_reg}; + {ts_96_ns_ovf_next, ts_96_fns_ovf_next} = {next_rise_ns_reg, next_rise_fns_reg} + {width_ns_reg, width_fns_reg} - {31'd1_000_000_000, 16'd0}; + if (input_start_valid || input_period_valid) begin + level_next = 1'b0; + output_next = 1'b0; + state_next = STATE_IDLE; + end else begin + state_next = STATE_UPDATE_FALL_2; + end + end + STATE_UPDATE_FALL_2: begin + if (!ts_96_ns_ovf_reg[30]) begin + // if the overflow lookahead did not borrow, one second has elapsed + next_fall_s_next = next_rise_s_reg + width_s_reg + 1; + next_fall_ns_next = ts_96_ns_ovf_reg; + next_fall_fns_next = ts_96_fns_ovf_reg; + end else begin + // no increment seconds field + next_fall_s_next = next_rise_s_reg + width_s_reg; + next_fall_ns_next = ts_96_ns_inc_reg; + next_fall_fns_next = ts_96_fns_inc_reg; + end + if (input_start_valid || input_period_valid) begin + level_next = 1'b0; + output_next = 1'b0; + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_EDGE; + end + end + STATE_WAIT_EDGE: begin + if (input_start_valid || input_period_valid) begin + state_next = STATE_IDLE; + end else if ((time_s_reg > next_rise_s_reg) || (time_s_reg == next_rise_s_reg && {time_ns_reg, time_fns_reg} > {next_rise_ns_reg, next_rise_fns_reg})) begin + // rising edge + level_next = 1'b1; + output_next = enable && locked_reg; + state_next = STATE_UPDATE_RISE_1; + end else if ((time_s_reg > next_fall_s_reg) || (time_s_reg == next_fall_s_reg && {time_ns_reg, time_fns_reg} > {next_fall_ns_reg, next_fall_fns_reg})) begin + // falling edge + level_next = 1'b0; + output_next = 1'b0; + state_next = STATE_UPDATE_FALL_1; + end else begin + locked_next = locked_reg || level_reg; + state_next = STATE_WAIT_EDGE; + end + end + endcase +end + +always @(posedge clk) begin + state_reg <= state_next; + + time_s_reg <= input_ts_96[95:48]; + time_ns_reg <= input_ts_96[45:16]; + if (FNS_ENABLE) begin + time_fns_reg <= input_ts_96[15:0]; + end + + if (input_start_valid) begin + start_s_reg <= input_start[95:48]; + start_ns_reg <= input_start[45:16]; + if (FNS_ENABLE) begin + start_fns_reg <= input_start[15:0]; + end + end + + if (input_period_valid) begin + period_s_reg <= input_period[95:48]; + period_ns_reg <= input_period[45:16]; + if (FNS_ENABLE) begin + period_fns_reg <= input_period[15:0]; + end + end + + if (input_width_valid) begin + width_s_reg <= input_width[95:48]; + width_ns_reg <= input_width[45:16]; + if (FNS_ENABLE) begin + width_fns_reg <= input_width[15:0]; + end + end + + next_rise_s_reg <= next_rise_s_next; + next_rise_ns_reg <= next_rise_ns_next; + if (FNS_ENABLE) begin + next_rise_fns_reg <= next_rise_fns_next; + end + + next_fall_s_reg <= next_fall_s_next; + next_fall_ns_reg <= next_fall_ns_next; + if (FNS_ENABLE) begin + next_fall_fns_reg <= next_fall_fns_next; + end + + ts_96_ns_inc_reg <= ts_96_ns_inc_next; + if (FNS_ENABLE) begin + ts_96_fns_inc_reg <= ts_96_fns_inc_next; + end + + ts_96_ns_ovf_reg <= ts_96_ns_ovf_next; + if (FNS_ENABLE) begin + ts_96_fns_ovf_reg <= ts_96_fns_ovf_next; + end + + locked_reg <= locked_next; + level_reg <= level_next; + output_reg <= output_next; + + if (rst) begin + state_reg <= STATE_IDLE; + + start_s_reg <= OUT_START_S; + start_ns_reg <= OUT_START_NS; + start_fns_reg <= OUT_START_FNS; + + period_s_reg <= OUT_PERIOD_S; + period_ns_reg <= OUT_PERIOD_NS; + period_fns_reg <= OUT_PERIOD_FNS; + + width_s_reg <= OUT_WIDTH_S; + width_ns_reg <= OUT_WIDTH_NS; + width_fns_reg <= OUT_WIDTH_FNS; + + locked_reg <= 1'b0; + error_reg <= 1'b0; + output_reg <= 1'b0; + end +end + +endmodule diff --git a/tb/test_ptp_perout.py b/tb/test_ptp_perout.py new file mode 100755 index 000000000..b908368ae --- /dev/null +++ b/tb/test_ptp_perout.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2019 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 + +import ptp + +module = 'ptp_perout' +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 bench(): + + # Parameters + FNS_ENABLE = 1 + OUT_START_S = 0x0 + OUT_START_NS = 0x0 + OUT_START_FNS = 0x0000 + OUT_PERIOD_S = 1 + OUT_PERIOD_NS = 0 + OUT_PERIOD_FNS = 0x0000 + OUT_WIDTH_S = 0x0 + OUT_WIDTH_NS = 1000 + OUT_WIDTH_FNS = 0x0000 + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_ts_96 = Signal(intbv(0)[96:]) + input_ts_step = Signal(bool(0)) + enable = Signal(bool(0)) + input_start = Signal(intbv(0)[96:]) + input_start_valid = Signal(bool(0)) + input_period = Signal(intbv(0)[96:]) + input_period_valid = Signal(bool(0)) + input_width = Signal(intbv(0)[96:]) + input_width_valid = Signal(bool(0)) + + # Outputs + locked = Signal(bool(0)) + error = Signal(bool(0)) + output_pulse = Signal(bool(0)) + + # PTP clock + ptp_clock = ptp.PtpClock() + + ptp_logic = ptp_clock.create_logic( + clk, + rst, + ts_96=input_ts_96 + ) + + # 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, + input_ts_96=input_ts_96, + input_ts_step=input_ts_step, + enable=enable, + input_start=input_start, + input_start_valid=input_start_valid, + input_period=input_period, + input_period_valid=input_period_valid, + input_width=input_width, + input_width_valid=input_width_valid, + locked=locked, + error=error, + output_pulse=output_pulse + ) + + @always(delay(32)) + 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 + + # testbench stimulus + + enable.next = 1 + + yield clk.posedge + print("test 1: Test pulse out") + current_test.next = 1 + + input_start.next = 100 << 16 + input_start_valid.next = 1 + input_period.next = 100 << 16 + input_period_valid.next = 1 + input_width.next = 50 << 16 + input_width_valid.next = 1 + + yield clk.posedge + + input_start_valid.next = 0 + input_period_valid.next = 0 + input_width_valid.next = 0 + + + yield delay(10000) + + yield delay(100) + + yield clk.posedge + print("test 2: Test pulse out") + current_test.next = 2 + + input_start.next = 0 << 16 + input_start_valid.next = 1 + input_period.next = 100 << 16 + input_period_valid.next = 1 + input_width.next = 50 << 16 + input_width_valid.next = 1 + + yield clk.posedge + + input_start_valid.next = 0 + input_period_valid.next = 0 + input_width_valid.next = 0 + + + yield delay(10000) + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/tb/test_ptp_perout.v b/tb/test_ptp_perout.v new file mode 100644 index 000000000..160a44dd0 --- /dev/null +++ b/tb/test_ptp_perout.v @@ -0,0 +1,122 @@ +/* + +Copyright (c) 2019 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 + +/* + * Testbench for ptp_perout + */ +module test_ptp_perout; + +// Parameters +parameter FNS_ENABLE = 1; +parameter OUT_START_S = 48'h0; +parameter OUT_START_NS = 30'h0; +parameter OUT_START_FNS = 16'h0000; +parameter OUT_PERIOD_S = 48'd1; +parameter OUT_PERIOD_NS = 30'd0; +parameter OUT_PERIOD_FNS = 16'h0000; +parameter OUT_WIDTH_S = 48'h0; +parameter OUT_WIDTH_NS = 30'd1000; +parameter OUT_WIDTH_FNS = 16'h0000; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [95:0] input_ts_96 = 0; +reg input_ts_step = 0; +reg enable = 0; +reg [95:0] input_start = 0; +reg input_start_valid = 0; +reg [95:0] input_period = 0; +reg input_period_valid = 0; +reg [95:0] input_width = 0; +reg input_width_valid = 0; + +// Outputs +wire locked; +wire error; +wire output_pulse; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + input_ts_96, + input_ts_step, + enable, + input_start, + input_start_valid, + input_period, + input_period_valid, + input_width, + input_width_valid + ); + $to_myhdl( + locked, + error, + output_pulse + ); + + // dump file + $dumpfile("test_ptp_perout.lxt"); + $dumpvars(0, test_ptp_perout); +end + +ptp_perout #( + .FNS_ENABLE(FNS_ENABLE), + .OUT_START_S(OUT_START_S), + .OUT_START_NS(OUT_START_NS), + .OUT_START_FNS(OUT_START_FNS), + .OUT_PERIOD_S(OUT_PERIOD_S), + .OUT_PERIOD_NS(OUT_PERIOD_NS), + .OUT_PERIOD_FNS(OUT_PERIOD_FNS), + .OUT_WIDTH_S(OUT_WIDTH_S), + .OUT_WIDTH_NS(OUT_WIDTH_NS), + .OUT_WIDTH_FNS(OUT_WIDTH_FNS) +) +UUT ( + .clk(clk), + .rst(rst), + .input_ts_96(input_ts_96), + .input_ts_step(input_ts_step), + .enable(enable), + .input_start(input_start), + .input_start_valid(input_start_valid), + .input_period(input_period), + .input_period_valid(input_period_valid), + .input_width(input_width), + .input_width_valid(input_width_valid), + .locked(locked), + .error(error), + .output_pulse(output_pulse) +); + +endmodule From e5171d874916b3e23a02d5621e91dd9ff02b7fcb Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 1 Jul 2019 17:51:31 -0700 Subject: [PATCH 617/617] Enable flash programming in VCU118 example designs --- example/VCU118/fpga_10g/fpga.xdc | 10 +++++--- example/VCU118/fpga_10g/fpga/Makefile | 37 +++++++++++++++++++++++++++ example/VCU118/fpga_1g/fpga.xdc | 10 +++++--- example/VCU118/fpga_1g/fpga/Makefile | 37 +++++++++++++++++++++++++++ example/VCU118/fpga_25g/fpga.xdc | 10 +++++--- example/VCU118/fpga_25g/fpga/Makefile | 37 +++++++++++++++++++++++++++ 6 files changed, 132 insertions(+), 9 deletions(-) diff --git a/example/VCU118/fpga_10g/fpga.xdc b/example/VCU118/fpga_10g/fpga.xdc index 6267607c6..efbf0cc00 100644 --- a/example/VCU118/fpga_10g/fpga.xdc +++ b/example/VCU118/fpga_10g/fpga.xdc @@ -2,9 +2,13 @@ # part: xcvu9p-flga2104-2L-e # General configuration -set_property CFGBVS GND [current_design] -set_property CONFIG_VOLTAGE 1.8 [current_design] -set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN {DIV-1} [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 8 [current_design] +set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] # System clocks # 300 MHz diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile index b87c3c9f0..807cc1ed1 100644 --- a/example/VCU118/fpga_10g/fpga/Makefile +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -76,3 +76,40 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -nojournal -nolog -mode batch -source program.tcl +%_primary.mcs %_secondary.mcs %_primary.prm %_secondary.prm: %.bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx8 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4_x8}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl + diff --git a/example/VCU118/fpga_1g/fpga.xdc b/example/VCU118/fpga_1g/fpga.xdc index 42e39f369..65c32a917 100644 --- a/example/VCU118/fpga_1g/fpga.xdc +++ b/example/VCU118/fpga_1g/fpga.xdc @@ -2,9 +2,13 @@ # part: xcvu9p-flga2104-2L-e # General configuration -set_property CFGBVS GND [current_design] -set_property CONFIG_VOLTAGE 1.8 [current_design] -set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN {DIV-1} [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 8 [current_design] +set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] # System clocks # 300 MHz diff --git a/example/VCU118/fpga_1g/fpga/Makefile b/example/VCU118/fpga_1g/fpga/Makefile index f92425064..f5849ac8f 100644 --- a/example/VCU118/fpga_1g/fpga/Makefile +++ b/example/VCU118/fpga_1g/fpga/Makefile @@ -59,3 +59,40 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -nojournal -nolog -mode batch -source program.tcl +%_primary.mcs %_secondary.mcs %_primary.prm %_secondary.prm: %.bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx8 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4_x8}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl + diff --git a/example/VCU118/fpga_25g/fpga.xdc b/example/VCU118/fpga_25g/fpga.xdc index 6267607c6..efbf0cc00 100644 --- a/example/VCU118/fpga_25g/fpga.xdc +++ b/example/VCU118/fpga_25g/fpga.xdc @@ -2,9 +2,13 @@ # part: xcvu9p-flga2104-2L-e # General configuration -set_property CFGBVS GND [current_design] -set_property CONFIG_VOLTAGE 1.8 [current_design] -set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN {DIV-1} [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 8 [current_design] +set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] # System clocks # 300 MHz diff --git a/example/VCU118/fpga_25g/fpga/Makefile b/example/VCU118/fpga_25g/fpga/Makefile index b87c3c9f0..807cc1ed1 100644 --- a/example/VCU118/fpga_25g/fpga/Makefile +++ b/example/VCU118/fpga_25g/fpga/Makefile @@ -76,3 +76,40 @@ program: $(FPGA_TOP).bit echo "exit" >> program.tcl vivado -nojournal -nolog -mode batch -source program.tcl +%_primary.mcs %_secondary.mcs %_primary.prm %_secondary.prm: %.bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx8 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4_x8}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl +